From 21ef47c552a1b48ee32c72cb586ca006a0f35c50 Mon Sep 17 00:00:00 2001 From: iSergio Date: Fri, 2 Feb 2018 08:43:44 +0300 Subject: [PATCH] Cesium version up to 1.42 --- .../org/cesiumjs/public/cs/Cesium/Cesium.js | 182 +- .../Widgets/Images/NavigationHelp/Mouse.svg | 1 + .../Images/NavigationHelp/MouseLeft.svg | 1 + .../Images/NavigationHelp/MouseMiddle.svg | 1 + .../Images/NavigationHelp/MouseRight.svg | 1 + .../Widgets/Images/NavigationHelp/Touch.svg | 1 + .../Images/NavigationHelp/TouchDrag.svg | 1 + .../Images/NavigationHelp/TouchRotate.svg | 1 + .../Images/NavigationHelp/TouchTilt.svg | 1 + .../Images/NavigationHelp/TouchZoom.svg | 1 + .../Widgets/InfoBox/InfoBoxDescription.css | 2 +- .../public/cs/Cesium/Widgets/shared.css | 2 +- .../public/cs/Cesium/Widgets/widgets.css | 2 +- .../cs/Cesium/Workers/combineGeometry.js | 10 +- .../cs/Cesium/Workers/createBoxGeometry.js | 6 +- .../Workers/createBoxOutlineGeometry.js | 6 +- .../cs/Cesium/Workers/createCircleGeometry.js | 14 +- .../Workers/createCircleOutlineGeometry.js | 8 +- .../Cesium/Workers/createCorridorGeometry.js | 13 +- .../Workers/createCorridorOutlineGeometry.js | 13 +- .../Cesium/Workers/createCylinderGeometry.js | 6 +- .../Workers/createCylinderOutlineGeometry.js | 6 +- .../Cesium/Workers/createEllipseGeometry.js | 13 +- .../Workers/createEllipseOutlineGeometry.js | 8 +- .../Cesium/Workers/createEllipsoidGeometry.js | 6 +- .../Workers/createEllipsoidOutlineGeometry.js | 6 +- .../Cesium/Workers/createFrustumGeometry.js | 8 +- .../Workers/createFrustumOutlineGeometry.js | 8 +- .../cs/Cesium/Workers/createGeometry.js | 10 +- .../cs/Cesium/Workers/createPlaneGeometry.js | 6 +- .../Workers/createPlaneOutlineGeometry.js | 6 +- .../Cesium/Workers/createPolygonGeometry.js | 14 +- .../Workers/createPolygonOutlineGeometry.js | 14 +- .../Cesium/Workers/createPolylineGeometry.js | 8 +- .../Workers/createPolylineVolumeGeometry.js | 14 +- .../createPolylineVolumeOutlineGeometry.js | 12 +- .../Cesium/Workers/createRectangleGeometry.js | 11 +- .../Workers/createRectangleOutlineGeometry.js | 8 +- .../Workers/createSimplePolylineGeometry.js | 8 +- .../cs/Cesium/Workers/createSphereGeometry.js | 6 +- .../Workers/createSphereOutlineGeometry.js | 6 +- ...VerticesFromGoogleEarthEnterpriseBuffer.js | 12 +- .../Workers/createVerticesFromHeightmap.js | 12 +- .../createVerticesFromQuantizedTerrainMesh.js | 12 +- .../cs/Cesium/Workers/createWallGeometry.js | 12 +- .../Workers/createWallOutlineGeometry.js | 12 +- .../Workers/upsampleQuantizedTerrainMesh.js | 12 +- .../public/cs/CesiumUnminified/Cesium.js | 352455 ++++++++------- .../Widgets/Images/NavigationHelp/Mouse.svg | 1 + .../Images/NavigationHelp/MouseLeft.svg | 1 + .../Images/NavigationHelp/MouseMiddle.svg | 1 + .../Images/NavigationHelp/MouseRight.svg | 1 + .../Widgets/Images/NavigationHelp/Touch.svg | 1 + .../Images/NavigationHelp/TouchDrag.svg | 1 + .../Images/NavigationHelp/TouchRotate.svg | 1 + .../Images/NavigationHelp/TouchTilt.svg | 1 + .../Images/NavigationHelp/TouchZoom.svg | 1 + .../cs/CesiumUnminified/Widgets/shared.css | 4 + .../Workers/combineGeometry.js | 110 +- .../Workers/createBoxGeometry.js | 65 +- .../Workers/createBoxOutlineGeometry.js | 45 +- .../Workers/createCircleGeometry.js | 4488 +- .../Workers/createCircleOutlineGeometry.js | 45 +- .../Workers/createCorridorGeometry.js | 4844 +- .../Workers/createCorridorOutlineGeometry.js | 4842 +- .../Workers/createCylinderGeometry.js | 65 +- .../Workers/createCylinderOutlineGeometry.js | 45 +- .../Workers/createEllipseGeometry.js | 4488 +- .../Workers/createEllipseOutlineGeometry.js | 45 +- .../Workers/createEllipsoidGeometry.js | 63 +- .../Workers/createEllipsoidOutlineGeometry.js | 45 +- .../Workers/createFrustumGeometry.js | 67 +- .../Workers/createFrustumOutlineGeometry.js | 67 +- .../Workers/createGeometry.js | 110 +- .../Workers/createPlaneGeometry.js | 45 +- .../Workers/createPlaneOutlineGeometry.js | 45 +- .../Workers/createPolygonGeometry.js | 4906 +- .../Workers/createPolygonOutlineGeometry.js | 4904 +- .../Workers/createPolylineGeometry.js | 69 +- .../Workers/createPolylineVolumeGeometry.js | 4891 +- .../createPolylineVolumeOutlineGeometry.js | 4884 +- .../Workers/createRectangleGeometry.js | 112 +- .../Workers/createRectangleOutlineGeometry.js | 45 +- .../Workers/createSimplePolylineGeometry.js | 67 +- .../Workers/createSphereGeometry.js | 63 +- .../Workers/createSphereOutlineGeometry.js | 45 +- ...VerticesFromGoogleEarthEnterpriseBuffer.js | 5077 +- .../Workers/createVerticesFromHeightmap.js | 5077 +- .../createVerticesFromQuantizedTerrainMesh.js | 4637 +- .../Workers/createWallGeometry.js | 4886 +- .../Workers/createWallOutlineGeometry.js | 4884 +- .../Workers/upsampleQuantizedTerrainMesh.js | 4645 +- 92 files changed, 229833 insertions(+), 191874 deletions(-) diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Cesium.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Cesium.js index e82efe85..d91aa75f 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Cesium.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Cesium.js @@ -467,92 +467,96 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /*! NoSleep.js v0.7.0 - git.io/vfn01 - Rich Tibbett - MIT license */ -!function(){var requirejs,require,define;!function(e){function t(e,t){return v.call(e,t)}function r(e,t){var r,i,n,o,a,s,l,u,c,d,h,p,f=t&&t.split("/"),m=g.map,_=m&&m["*"]||{};if(e){for(e=e.split("/"),a=e.length-1,g.nodeIdCompat&&C.test(e[a])&&(e[a]=e[a].replace(C,"")),"."===e[0].charAt(0)&&f&&(p=f.slice(0,f.length-1),e=p.concat(e)),c=0;c0&&(e.splice(c-1,2),c-=2)}e=e.join("/")}if((f||_)&&m){for(r=e.split("/"),c=r.length;c>0;c-=1){if(i=r.slice(0,c).join("/"),f)for(d=f.length;d>0;d-=1)if((n=m[f.slice(0,d).join("/")])&&(n=n[i])){o=n,s=c;break}if(o)break;!l&&_&&_[i]&&(l=_[i],u=c)}!o&&l&&(o=l,s=u),o&&(r.splice(0,s,o),e=r.join("/"))}return e}function i(t,r){return function(){var i=y.call(arguments,0);return"string"!=typeof i[0]&&1===i.length&&i.push(null),d.apply(e,i.concat([t,r]))}}function n(e){return function(t){return r(t,e)}}function o(e){return function(t){f[e]=t}}function a(r){if(t(m,r)){var i=m[r];delete m[r],_[r]=!0,c.apply(e,i)}if(!t(f,r)&&!t(_,r))throw new Error("No "+r);return f[r]}function s(e){var t,r=e?e.indexOf("!"):-1;return r>-1&&(t=e.substring(0,r),e=e.substring(r+1,e.length)),[t,e]}function l(e){return e?s(e):[]}function u(e){return function(){return g&&g.config&&g.config[e]||{}}}var c,d,h,p,f={},m={},g={},_={},v=Object.prototype.hasOwnProperty,y=[].slice,C=/\.js$/;h=function(e,t){var i,o=s(e),l=o[0],u=t[1];return e=o[1],l&&(l=r(l,u),i=a(l)),l?e=i&&i.normalize?i.normalize(e,n(u)):r(e,u):(e=r(e,u),o=s(e),l=o[0],e=o[1],l&&(i=a(l))),{f:l?l+"!"+e:e,n:e,pr:l,p:i}},p={require:function(e){return i(e)},exports:function(e){var t=f[e];return void 0!==t?t:f[e]={}},module:function(e){return{id:e,uri:"",exports:f[e],config:u(e)}}},c=function(r,n,s,u){var c,d,g,v,y,C,b,S=[],w=typeof s;if(u=u||r,C=l(u),"undefined"===w||"function"===w){for(n=!n.length&&s.length?["require","exports","module"]:n,y=0;y=i)throw new t("Expected "+e+" to be less than "+i+", actual value was "+r)},n.typeOf.number.lessThanOrEquals=function(e,r,i){if(n.typeOf.number(e,r),r>i)throw new t("Expected "+e+" to be less than or equal to "+i+", actual value was "+r)},n.typeOf.number.greaterThan=function(e,r,i){if(n.typeOf.number(e,r),r<=i)throw new t("Expected "+e+" to be greater than "+i+", actual value was "+r)},n.typeOf.number.greaterThanOrEquals=function(e,r,i){if(n.typeOf.number(e,r),r>>0,a=t(i,0),s=a<0?Math.max(o+a,0):Math.min(a,o),l=t(n,o),u=l<0?Math.max(o+l,0):Math.min(l,o);s>>0,this.mti=1;this.mti>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r>>1^t[1&e];for(;r>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,i){"use strict";var n={};n.EPSILON1=.1,n.EPSILON2=.01,n.EPSILON3=.001,n.EPSILON4=1e-4,n.EPSILON5=1e-5,n.EPSILON6=1e-6,n.EPSILON7=1e-7,n.EPSILON8=1e-8,n.EPSILON9=1e-9,n.EPSILON10=1e-10,n.EPSILON11=1e-11,n.EPSILON12=1e-12,n.EPSILON13=1e-13,n.EPSILON14=1e-14,n.EPSILON15=1e-15,n.EPSILON16=1e-16,n.EPSILON17=1e-17,n.EPSILON18=1e-18,n.EPSILON19=1e-19,n.EPSILON20=1e-20,n.GRAVITATIONALPARAMETER=3986004418e5,n.SOLAR_RADIUS=6955e5,n.LUNAR_RADIUS=1737400,n.SIXTY_FOUR_KILOBYTES=65536,n.sign=function(e){return e>0?1:e<0?-1:0},n.signNotZero=function(e){return e<0?-1:1},n.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*n.clamp(e,-1,1)+.5)*r)},n.fromSNorm=function(e,r){return r=t(r,255),n.clamp(e,0,r)/r*2-1},n.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},n.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},n.lerp=function(e,t,r){return(1-r)*e+r*t},n.PI=Math.PI,n.ONE_OVER_PI=1/Math.PI,n.PI_OVER_TWO=.5*Math.PI,n.PI_OVER_THREE=Math.PI/3,n.PI_OVER_FOUR=Math.PI/4,n.PI_OVER_SIX=Math.PI/6,n.THREE_PI_OVER_TWO=3*Math.PI*.5,n.TWO_PI=2*Math.PI,n.ONE_OVER_TWO_PI=1/(2*Math.PI),n.RADIANS_PER_DEGREE=Math.PI/180,n.DEGREES_PER_RADIAN=180/Math.PI,n.RADIANS_PER_ARCSECOND=n.RADIANS_PER_DEGREE/3600,n.toRadians=function(e){return e*n.RADIANS_PER_DEGREE},n.toDegrees=function(e){return e*n.DEGREES_PER_RADIAN},n.convertLongitudeRange=function(e){var t=n.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},n.clampToLatitudeRange=function(e){return n.clamp(e,-1*n.PI_OVER_TWO,n.PI_OVER_TWO)},n.negativePiToPi=function(e){return n.zeroToTwoPi(e+n.PI)-n.PI},n.zeroToTwoPi=function(e){var t=n.mod(e,n.TWO_PI);return Math.abs(t)n.EPSILON14?n.TWO_PI:t},n.mod=function(e,t){return(e%t+t)%t},n.equalsEpsilon=function(e,r,i,n){n=t(n,i);var o=Math.abs(e-r);return o<=n||o<=i*Math.max(Math.abs(e),Math.abs(r))};var o=[1];n.factorial=function(e){var t=o.length;if(e>=t)for(var r=o[t-1],i=t;i<=e;i++)o.push(r*i);return o[e]},n.incrementWrap=function(e,r,i){return i=t(i,0),++e,e>r&&(e=i),e},n.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},n.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},n.clamp=function(e,t,r){return er?r:e};var a=new e;return n.setRandomNumberSeed=function(t){a=new e(t)},n.nextRandomNumber=function(){return a.random()},n.randomBetween=function(e,t){return n.nextRandomNumber()*(t-e)+e},n.acosClamped=function(e){return Math.acos(n.clamp(e,-1,1))},n.asinClamped=function(e){return Math.asin(n.clamp(e,-1,1))},n.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},n.logBase=function(e,t){return Math.log(e)/Math.log(t)},n.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},n}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,r,i){"use strict";function n(e,i,n){if(r(e)){n=t(n,!1);var a=e.length;if(a<2)return e;var s,l,u;for(s=1;s1&&i(c[0],c[c.length-1],o)&&c.shift(),c}}var o=i.EPSILON10;return n}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/AssociativeArray",["./defined","./defineProperties","./DeveloperError"],function(e,t,r){"use strict";function i(){this._array=[],this._hash={}}return t(i.prototype,{length:{get:function(){return this._array.length}},values:{get:function(){return this._array}}}),i.prototype.contains=function(t){return e(this._hash[t])},i.prototype.set=function(e,t){t!==this._hash[e]&&(this.remove(e),this._hash[e]=t,this._array.push(t))},i.prototype.get=function(e){return this._hash[e]},i.prototype.remove=function(t){var r=this._hash[t],i=e(r);if(i){var n=this._array;n.splice(n.indexOf(r),1),delete this._hash[t]}return i},i.prototype.removeAll=function(){var e=this._array;e.length>0&&(this._hash={},e.length=0)},i}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,r){this.x=t(e,0),this.y=t(r,0)}a.fromElements=function(e,t,i){return r(i)?(i.x=e,i.y=t,i):new a(e,t)},a.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new a(e.x,e.y)},a.fromCartesian3=a.clone,a.fromCartesian4=a.clone,a.packedLength=2,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.x,r[i]=e.y,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.x=e[i++],n.y=e[i],n},a.packArray=function(e,t){var i=e.length;r(t)?t.length=2*i:t=new Array(2*i);for(var n=0;n0?n.INSIDE:l+s<0?n.OUTSIDE:n.INTERSECTING},o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.intersectPlane=function(e){return o.intersectPlane(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,i){"use strict";function n(r,n,l,u,c){i(c)||(c=new t);var d,h,p,f,m,g,_,v;i(n.z)?(d=t.subtract(l,n,o),h=t.subtract(u,n,a),p=t.subtract(r,n,s),f=t.dot(d,d),m=t.dot(d,h),g=t.dot(d,p),_=t.dot(h,h),v=t.dot(h,p)):(d=e.subtract(l,n,o),h=e.subtract(u,n,a),p=e.subtract(r,n,s),f=e.dot(d,d),m=e.dot(d,h),g=e.dot(d,p),_=e.dot(h,h),v=e.dot(h,p));var y=1/(f*_-m*m);return c.y=(_*g-m*v)*y,c.z=(f*v-m*g)*y,c.x=1-c.y-c.z,c}var o=new t,a=new t,s=new t;return n}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var i,n,o=0,a=e.length-1;o<=a;)if(i=~~((o+a)/2),(n=r(e[i],t))<0)o=i+1;else{if(!(n>0))return i;a=i-1}return~(a+1)}return t}),define("Core/Credit",["./defaultValue","./defined","./defineProperties","./DeveloperError"],function(e,t,r,i){"use strict";function n(r){r=e(r,e.EMPTY_OBJECT);var i=r.text,n=r.imageUrl,s=r.link,l=e(r.showOnScreen,!1),u=t(s),c=t(n);t(i)||c||(i=s),this._text=i,this._imageUrl=n,this._link=s,this._hasLink=u,this._hasImage=c,this._showOnScreen=l;var d,h=JSON.stringify([i,n,s]);t(a[h])?d=a[h]:(d=o++,a[h]=d),this._id=d}var o=0,a={};return r(n.prototype,{text:{get:function(){return this._text}},imageUrl:{get:function(){return this._imageUrl}},link:{get:function(){return this._link}},id:{get:function(){return this._id}},showOnScreen:{get:function(){return this._showOnScreen}}}),n.prototype.hasImage=function(){return this._hasImage},n.prototype.hasLink=function(){return this._hasLink},n.equals=function(e,r){return e===r||t(e)&&t(r)&&e._id===r._id},n.prototype.equals=function(e){return n.equals(this,e)},n}),define("Core/BingMapsApi",["./Credit","./defined"],function(e,t){"use strict";var r={};r.defaultKey=void 0;var i,n=!1,o="This application is using Cesium's default Bing Maps key. Please create a new key for the application as soon as possible and prior to deployment by visiting https://www.bingmapsportal.com/, and provide your key to Cesium by setting the Cesium.BingMapsApi.defaultKey property before constructing the CesiumWidget or any other object that uses the Bing Maps API.";return r.getKey=function(e){return t(e)?e:t(r.defaultKey)?r.defaultKey:(n||(console.log(o),n=!0),"Aig5SkZ4pNMN8b4rX-RUH2c_95mK-wjb4WL9k50K51faErEGnNsxgpWHXiqS3Rhe")},r.getErrorCredit=function(n){if(!t(n)&&!t(r.defaultKey))return t(i)||(i=new e({text:o,showOnScreen:!0})),i},r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=i.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return o.test(t)?t:e.toUpperCase()}function r(e,t,r,i){return(t||"")+r.toLowerCase()+(i||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var i=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(a,r).replace(n,t)),this.path&&(this.path=this.path.replace(n,t)),this.query&&(this.query=this.query.replace(n,t)),this.fragment&&(this.fragment=this.fragment.replace(n,t))};var n=/%[0-9a-z]{2}/gi,o=/[a-zA-Z0-9\-\._~]/,a=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],i=""==t[0];i&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),i&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,i,n){return t(e).then(r,i,n)}function t(e){var t,r;return e instanceof i?t=e:s(e)?(r=a(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=n(e),t}function r(t){return e(t,o)}function i(e){this.then=e}function n(e){return new i(function(r){try{return t(r?r(e):e)}catch(e){return o(e)}})}function o(e){return new i(function(r,i){try{return i?t(i(e)):o(e)}catch(e){return o(e)}})}function a(){function e(e,t,r){return h(e,t,r)}function r(e){return f(e)}function n(e){return f(o(e))}function s(e){return p(e)}var l,u,c,d,h,p,f;return u=new i(e),l={then:e,resolve:r,reject:n,progress:s,promise:u,resolver:{resolve:r,reject:n,progress:s}},c=[],d=[],h=function(e,t,r){var i,n;return i=a(),n="function"==typeof r?function(e){try{i.progress(r(e))}catch(e){i.progress(e)}}:function(e){i.progress(e)},c.push(function(r){r.then(e,t).then(i.resolve,i.reject,n)}),d.push(n),i.promise},p=function(e){return m(d,e),e},f=function(e){return e=t(e),h=e.then,f=t,p=_,m(c,e),d=c=b,e},l}function s(e){return e&&"function"==typeof e.then}function l(t,r,i,n,o){return g(2,arguments),e(t,function(t){function s(e){m(e)}function l(e){f(e)}var u,c,d,h,p,f,m,g,v,y;if(v=t.length>>>0,u=Math.max(0,Math.min(r,v)),d=[],c=v-u+1,h=[],p=a(),u)for(g=p.progress,m=function(e){h.push(e),--c||(f=m=_,p.reject(h))},f=function(e){d.push(e),--u||(f=m=_,p.resolve(d))},y=0;y>>0,i=[],u=a(),o)for(s=function(t,n){e(t,r).then(function(e){i[n]=e,--o||u.resolve(i)},u.reject)},l=0;l2;return e(t,function(e){return e=n?i:e,r.resolve(e),e},function(e){return r.reject(e),o(e)},r.progress)}function m(e,t){for(var r,i=0;r=e[i++];)r(t)}function g(e,t){for(var r,i=t.length;i>e;)if(null!=(r=t[--i])&&"function"!=typeof r)throw new Error("arg "+i+" must be a function")}function _(){}function v(e){return e}var y,C,b;return e.defer=a,e.resolve=t,e.reject=r,e.join=d,e.all=c,e.map=h,e.reduce=p,e.any=u,e.some=l,e.chain=f,e.isPromise=s,i.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(b,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return c(t,function(t){return e.apply(b,t)})})}},C=[].slice,y=[].reduce||function(e){var t,r,i,n,o;if(o=0,t=Object(this),n=t.length>>>0,r=arguments,r.length<=1)for(;;){if(o in t){i=t[o++];break}if(++o>=n)throw new TypeError}else i=r[1];for(;oe&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),n.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},n.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,i=this._comparator,n=this._array,a=-1,s=!0;s;){var l=2*(e+1),u=l-1;a=u=0;--t)this.heapify(t)},n.prototype.insert=function(e){var t=this._array,i=this._comparator,n=this._maximumLength,a=this._length++;for(an&&(l=t[n],this._length=n),l},n.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,i=r[e];return o(r,e,--this._length),this.heapify(e),i}},n}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e,t){return e.priority-t.priority}function c(){}function d(e){i(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return T[e]0&&console.log("Number of attempted requests: "+C.numberOfAttemptedRequests),C.numberOfActiveRequests>0&&console.log("Number of active requests: "+C.numberOfActiveRequests),C.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+C.numberOfCancelledRequests),C.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+C.numberOfCancelledActiveRequests),C.numberOfFailedRequests>0&&console.log("Number of failed requests: "+C.numberOfFailedRequests),v())}var C={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},b=20,S=new o({comparator:u});S.maximumLength=b,S.reserve(b);var w=[],T={},A="undefined"!=typeof document?new e(document.location.href):new e;return c.maximumRequests=50,c.maximumRequestsPerServer=6,c.throttleRequests=!0,c.debugShowStatistics=!1,n(c,{statistics:{get:function(){return C}},priorityHeapLength:{get:function(){return b},set:function(e){if(ee;){var t=S.pop();_(t)}b=e,S.maximumLength=e,S.reserve(e)}}}),c.update=function(){var e,t,r=0,i=w.length;for(e=0;e0&&(w[e-r]=t):++r;w.length-=r;var n=S.internalArray,o=S.length;for(e=0;e0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||h(t.serverKey)?(g(t),++s):_(t);y()},c.getServerKey=function(t){var r=new e(t).resolve(A);r.normalize();var n=r.authority;/:/.test(n)||(n=n+":"+("https"===r.scheme?"443":"80"));var o=T[n];return i(o)||(T[n]=0),n},c.request=function(e){if(s(e.url)||a(e.url))return e.state=l.RECEIVED,e.requestFunction();if(++C.numberOfAttemptedRequests,i(e.serverKey)||(e.serverKey=c.getServerKey(e.url)),!c.throttleRequests||!e.throttle)return g(e);if(!(w.length>=c.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){d(e);var t=S.insert(e);if(i(t)){if(t===e)return;_(t)}return p(e)}},c.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=w.length,t=0;ti.EPSILON12);return t(u)?(u.x=c*P,u.y=d*D,u.z=h*I,u):new e(c*P,d*D,h*I)}var o=new e,a=new e;return n}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,i,n,o,a){"use strict";function s(e,t,i){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(i,0)}s.fromRadians=function(e,t,n,o){return n=r(n,0),i(o)?(o.longitude=e,o.latitude=t,o.height=n,o):new s(e,t,n)},s.fromDegrees=function(e,t,r,i){return e=o.toRadians(e),t=o.toRadians(t),s.fromRadians(e,t,r,i)};var l=new e,u=new e,c=new e,d=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),p=o.EPSILON1;return s.fromCartesian=function(t,r,n){var f=i(r)?r.oneOverRadii:d,m=i(r)?r.oneOverRadiiSquared:h,g=i(r)?r._centerToleranceSquared:p,_=a(t,f,m,g,u);if(i(_)){var v=e.multiplyComponents(_,m,l);v=e.normalize(v,v);var y=e.subtract(t,_,c),C=Math.atan2(v.y,v.x),b=Math.asin(v.z),S=o.sign(e.dot(y,t))*e.magnitude(y);return i(n)?(n.longitude=C,n.latitude=b,n.height=S,n):new s(C,b,S)}},s.clone=function(e,t){if(i(e))return i(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new s(e.longitude,e.latitude,e.height)},s.equals=function(e,t){return e===t||i(e)&&i(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},s.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},s.ZERO=n(new s(0,0,0)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},s}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r,n,o){r=i(r,0),n=i(n,0),o=i(o,0),t._radii=new e(r,n,o),t._radiiSquared=new e(r*r,n*n,o*o),t._radiiToTheFourth=new e(r*r*r*r,n*n*n*n,o*o*o*o),t._oneOverRadii=new e(0===r?0:1/r,0===n?0:1/n,0===o?0:1/o),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===n?0:1/(n*n),0===o?0:1/(o*o)),t._minimumRadius=Math.min(r,n,o),t._maximumRadius=Math.max(r,n,o),t._centerToleranceSquared=l.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function d(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,r)}o(d.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),d.clone=function(t,r){if(n(t)){var i=t._radii;return n(r)?(e.clone(i,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new d(i.x,i.y,i.z)}},d.fromCartesian3=function(e,t){return n(t)||(t=new d),n(e)?(c(t,e.x,e.y,e.z),t):t},d.WGS84=s(new d(6378137,6378137,6356752.314245179)),d.UNIT_SPHERE=s(new d(1,1,1)),d.MOON=s(new d(l.LUNAR_RADIUS,l.LUNAR_RADIUS,l.LUNAR_RADIUS)),d.prototype.clone=function(e){return d.clone(this,e)},d.packedLength=e.packedLength,d.pack=function(t,r,n){return n=i(n,0),e.pack(t._radii,r,n),r},d.unpack=function(t,r,n){r=i(r,0);var o=e.unpack(t,r);return d.fromCartesian3(o,n)},d.prototype.geocentricSurfaceNormal=e.normalize,d.prototype.geodeticSurfaceNormalCartographic=function(t,r){var i=t.longitude,o=t.latitude,a=Math.cos(o),s=a*Math.cos(i),l=a*Math.sin(i),u=Math.sin(o);return n(r)||(r=new e),r.x=s,r.y=l,r.z=u,e.normalize(r,r)},d.prototype.geodeticSurfaceNormal=function(t,r){return n(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,p=new e;d.prototype.cartographicToCartesian=function(t,r){var i=h,o=p;this.geodeticSurfaceNormalCartographic(t,i),e.multiplyComponents(this._radiiSquared,i,o);var a=Math.sqrt(e.dot(i,o));return e.divideByScalar(o,a,o),e.multiplyByScalar(i,t.height,i),n(r)||(r=new e),e.add(o,i,r)},d.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;n(t)?t.length=r:t=new Array(r);for(var i=0;i=this._radii.z-r))return o},d}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,i,n){this.west=r(e,0),this.south=r(t,0),this.east=r(i,0),this.north=r(n,0)}n(l.prototype,{width:{get:function(){return l.computeWidth(this)}},height:{get:function(){return l.computeHeight(this)}}}),l.packedLength=4,l.pack=function(e,t,i){return i=r(i,0),t[i++]=e.west,t[i++]=e.south,t[i++]=e.east,t[i]=e.north,t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n.west=e[t++],n.south=e[t++],n.east=e[t++],n.north=e[t],n},l.computeWidth=function(e){var t=e.east,r=e.west;return t=0?p.longitude:p.longitude+s.TWO_PI;o=Math.min(o,f),a=Math.max(a,f)}return n-r>a-o&&(r=o,n=a,n>s.PI&&(n-=s.TWO_PI),r>s.PI&&(r-=s.TWO_PI)),i(t)?(t.west=r,t.south=u,t.east=n,t.north=c,t):new l(r,u,n,c)},l.fromCartesianArray=function(e,t,n){t=r(t,o.WGS84);for(var a=Number.MAX_VALUE,u=-Number.MAX_VALUE,c=Number.MAX_VALUE,d=-Number.MAX_VALUE,h=Number.MAX_VALUE,p=-Number.MAX_VALUE,f=0,m=e.length;f=0?g.longitude:g.longitude+s.TWO_PI;c=Math.min(c,_),d=Math.max(d,_)}return u-a>d-c&&(a=c,u=d,u>s.PI&&(u-=s.TWO_PI),a>s.PI&&(a-=s.TWO_PI)),i(n)?(n.west=a,n.south=h,n.east=u,n.north=p,n):new l(a,h,u,p)},l.clone=function(e,t){if(i(e))return i(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new l(e.west,e.south,e.east,e.north)},l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},l.prototype.equalsEpsilon=function(e,t){return i(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},l.validate=function(e){},l.southwest=function(t,r){return i(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},l.northwest=function(t,r){return i(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},l.northeast=function(t,r){return i(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},l.southeast=function(t,r){return i(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},l.center=function(t,r){var n=t.east,o=t.west;n0?n+=s.TWO_PI:a0&&(a+=s.TWO_PI),n=p))return i(r)?(r.west=c,r.south=h,r.east=d,r.north=p,r):new l(c,h,d,p)}},l.simpleIntersection=function(e,t,r){var n=Math.max(e.west,t.west),o=Math.max(e.south,t.south),a=Math.min(e.east,t.east),s=Math.min(e.north,t.north);if(!(o>=s||n>=a))return i(r)?(r.west=n,r.south=o,r.east=a,r.north=s,r):new l(n,o,a,s)},l.union=function(e,t,r){i(r)||(r=new l);var n=e.east,o=e.west,a=t.east,u=t.west;n0?n+=s.TWO_PI:a0&&(a+=s.TWO_PI),nn||s.equalsEpsilon(r,n,s.EPSILON14))&&(r=e.south&&i<=e.north};var u=new e;return l.subsample=function(e,t,n,a){t=r(t,o.WGS84),n=r(n,0),i(a)||(a=[]);var c=0,d=e.north,h=e.south,p=e.east,f=e.west,m=u;m.height=n,m.longitude=f,m.latitude=d,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.longitude=p,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.latitude=h,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.longitude=f,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.latitude=d<0?d:h>0?h:0;for(var g=1;g<8;++g)m.longitude=-Math.PI+g*s.PI_OVER_TWO,l.contains(e,m)&&(a[c]=t.cartographicToCartesian(m,a[c]),c++);return 0===m.latitude&&(m.longitude=f,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.longitude=p,a[c]=t.cartographicToCartesian(m,a[c]),c++),a.length=c,a},l.MAX_VALUE=a(new l(-Math.PI,-s.PI_OVER_TWO,Math.PI,s.PI_OVER_TWO)),l}),define("Core/BingMapsGeocoderService",["./BingMapsApi","./Check","./defaultValue","./defined","./defineProperties","./loadJsonp","./Rectangle"],function(e,t,r,i,n,o,a){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT);var n=t.key;if(this._key=e.getKey(n),i(n)){var o=e.getErrorCredit(n);i(o)&&t.scene._frameState.creditDisplay.addDefaultCredit(o)}}var l="https://dev.virtualearth.net/REST/v1/Locations";return n(s.prototype,{url:{get:function(){return l}},key:{get:function(){return this._key}}}),s.prototype.geocode=function(e){var t=this.key;return o(l,{parameters:{query:e,key:t},callbackParameterName:"jsonp"}).then(function(e){return 0===e.resourceSets.length?[]:e.resourceSets[0].resources.map(function(e){var t=e.bbox,r=t[0],i=t[1],n=t[2],o=t[3];return{displayName:e.name,destination:a.fromDegrees(i,r,o,n)}})})},s}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,i,n,o,a){"use strict";function s(e){this._ellipsoid=r(e,a.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return n(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.prototype.project=function(t,r){var n=this._semimajorAxis,o=t.longitude*n,a=t.latitude*n,s=t.height;return i(r)?(r.x=o,r.y=a,r.z=s,r):new e(o,a,s)},s.prototype.unproject=function(e,r){var n=this._oneOverSemimajorAxis,o=e.x*n,a=e.y*n,s=e.z;return i(r)?(r.longitude=o,r.latitude=a,r.height=s,r):new t(o,a,s)},s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r,n){this.x=i(e,0),this.y=i(t,0),this.width=i(r,0),this.height=i(n,0)}l.packedLength=4,l.pack=function(e,t,r){return r=i(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.width,t[r]=e.height,t},l.unpack=function(e,t,r){return t=i(t,0),n(r)||(r=new l),r.x=e[t++],r.y=e[t++],r.width=e[t++],r.height=e[t],r},l.fromPoints=function(e,t){if(n(t)||(t=new l),!n(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var r=e.length,i=e[0].x,o=e[0].y,a=e[0].x,s=e[0].y,u=1;ur.width?r.width=i:i<0&&(r.width-=i,r.x=t.x),n>r.height?r.height=n:n<0&&(r.height-=n,r.y=t.y),r},l.intersect=function(e,t){var r=e.x,i=e.y,n=t.x,o=t.y;return r>n+t.width||r+e.widtho+t.height?a.OUTSIDE:a.INTERSECTING},l.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.intersect=function(e){return l.intersect(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,i,n,o,a,s,l,u){this[0]=r(e,0),this[1]=r(n,0),this[2]=r(s,0),this[3]=r(t,0),this[4]=r(o,0),this[5]=r(l,0),this[6]=r(i,0),this[7]=r(a,0),this[8]=r(u,0)}function u(e){for(var t=0,r=0;r<9;++r){var i=e[r];t+=i*i}return Math.sqrt(t)}function c(e){for(var t=0,r=0;r<3;++r){var i=e[l.getElementIndex(m[r],f[r])];t+=2*i*i}return Math.sqrt(t)}function d(e,t){for(var r=s.EPSILON15,i=0,n=1,o=0;o<3;++o){var a=Math.abs(e[l.getElementIndex(m[o],f[o])]);a>i&&(n=o,i=a)}var u=1,c=0,d=f[n],h=m[n];if(Math.abs(e[l.getElementIndex(h,d)])>r){var p,g=e[l.getElementIndex(h,h)],_=e[l.getElementIndex(d,d)],v=e[l.getElementIndex(h,d)],y=(g-_)/2/v;p=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),u=1/Math.sqrt(1+p*p),c=p*u}return t=l.clone(l.IDENTITY,t),t[l.getElementIndex(d,d)]=t[l.getElementIndex(h,h)]=u,t[l.getElementIndex(h,d)]=c,t[l.getElementIndex(d,h)]=-c,t}l.packedLength=9,l.pack=function(e,t,i){return i=r(i,0),t[i++]=e[0],t[i++]=e[1],t[i++]=e[2],t[i++]=e[3],t[i++]=e[4],t[i++]=e[5],t[i++]=e[6],t[i++]=e[7],t[i++]=e[8],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new l(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},l.fromArray=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t],n[1]=e[t+1],n[2]=e[t+2],n[3]=e[t+3],n[4]=e[t+4],n[5]=e[t+5],n[6]=e[t+6],n[7]=e[t+7],n[8]=e[t+8],n},l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},l.fromQuaternion=function(e,t){var r=e.x*e.x,n=e.x*e.y,o=e.x*e.z,a=e.x*e.w,s=e.y*e.y,u=e.y*e.z,c=e.y*e.w,d=e.z*e.z,h=e.z*e.w,p=e.w*e.w,f=r-s-d+p,m=2*(n-h),g=2*(o+c),_=2*(n+h),v=-r+s-d+p,y=2*(u-a),C=2*(o-c),b=2*(u+a),S=-r-s+d+p;return i(t)?(t[0]=f,t[1]=_,t[2]=C,t[3]=m,t[4]=v,t[5]=b,t[6]=g,t[7]=y,t[8]=S,t):new l(f,m,g,_,v,y,C,b,S)},l.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),n=Math.cos(-e.heading),o=Math.cos(e.roll),a=Math.sin(-e.pitch),s=Math.sin(-e.heading),u=Math.sin(e.roll),c=r*n,d=-o*s+u*a*n,h=u*s+o*a*n,p=r*s,f=o*n+u*a*s,m=-u*n+o*a*s,g=-a,_=u*r,v=o*r;return i(t)?(t[0]=c,t[1]=p,t[2]=g,t[3]=d,t[4]=f,t[5]=_,t[6]=h,t[7]=m,t[8]=v,t):new l(c,d,h,p,f,m,g,_,v)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new l(e.x,0,0,0,e.y,0,0,0,e.z)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new l(e,0,0,0,e,0,0,0,e)},l.fromCrossProduct=function(e,t){return i(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new l(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},l.fromRotationX=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=n,t[6]=0,t[7]=-n,t[8]=r,t):new l(1,0,0,0,r,-n,0,n,r)},l.fromRotationY=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=r,t[1]=0,t[2]=-n,t[3]=0,t[4]=1,t[5]=0,t[6]=n,t[7]=0,t[8]=r,t):new l(r,0,n,0,1,0,-n,0,r)},l.fromRotationZ=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=r,t[1]=n,t[2]=0,t[3]=-n,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new l(r,-n,0,n,r,0,0,0,1)},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},l.getElementIndex=function(e,t){return 3*e+t},l.getColumn=function(e,t,r){var i=3*t,n=e[i],o=e[i+1],a=e[i+2];return r.x=n,r.y=o,r.z=a,r},l.setColumn=function(e,t,r,i){i=l.clone(e,i);var n=3*t;return i[n]=r.x,i[n+1]=r.y,i[n+2]=r.z,i},l.getRow=function(e,t,r){var i=e[t],n=e[t+3],o=e[t+6];return r.x=i,r.y=n,r.z=o,r},l.setRow=function(e,t,r,i){return i=l.clone(e,i),i[t]=r.x,i[t+3]=r.y,i[t+6]=r.z,i};var h=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,r){var i=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],n=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],o=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],a=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],s=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],l=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],u=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],d=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=i,r[1]=n,r[2]=o,r[3]=a,r[4]=s,r[5]=l,r[6]=u,r[7]=c,r[8]=d,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},l.multiplyByVector=function(e,t,r){var i=t.x,n=t.y,o=t.z,a=e[0]*i+e[3]*n+e[6]*o,s=e[1]*i+e[4]*n+e[7]*o,l=e[2]*i+e[5]*n+e[8]*o;return r.x=a,r.y=s,r.z=l,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},l.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},l.transpose=function(e,t){var r=e[0],i=e[3],n=e[6],o=e[1],a=e[4],s=e[7],l=e[2],u=e[5],c=e[8];return t[0]=r,t[1]=i,t[2]=n,t[3]=o,t[4]=a,t[5]=s,t[6]=l,t[7]=u,t[8]=c,t};var f=[1,0,0],m=[2,2,1],g=new l,_=new l;return l.computeEigenDecomposition=function(e,t){var r=s.EPSILON20,n=0,o=0;i(t)||(t={});for(var a=t.unitary=l.clone(l.IDENTITY,t.unitary),h=t.diagonal=l.clone(e,t.diagonal),p=r*u(h);o<10&&c(h)>p;)d(h,g),l.transpose(g,_),l.multiply(h,g,h),l.multiply(_,h,h),l.multiply(a,g,a),++n>2&&(++o,n=0);return t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},l.determinant=function(e){var t=e[0],r=e[3],i=e[6],n=e[1],o=e[4],a=e[7],s=e[2],l=e[5],u=e[8];return t*(o*u-l*a)+n*(l*i-r*u)+s*(r*a-o*i)},l.inverse=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[3],a=e[4],s=e[5],u=e[6],c=e[7],d=e[8],h=l.determinant(e);t[0]=a*d-c*s,t[1]=c*n-i*d,t[2]=i*s-a*n,t[3]=u*s-o*d,t[4]=r*d-u*n,t[5]=o*n-r*s,t[6]=o*c-u*a,t[7]=u*i-r*c,t[8]=r*a-o*i;var p=1/h;return l.multiplyByScalar(t,p,t)},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},l.IDENTITY=a(new l(1,0,0,0,1,0,0,0,1)),l.ZERO=a(new l(0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN1ROW0=3,l.COLUMN1ROW1=4,l.COLUMN1ROW2=5,l.COLUMN2ROW0=6,l.COLUMN2ROW1=7,l.COLUMN2ROW2=8,n(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},l}), -define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,r,i,n){this.x=t(e,0),this.y=t(r,0),this.z=t(i,0),this.w=t(n,0)}a.fromElements=function(e,t,i,n,o){return r(o)?(o.x=e,o.y=t,o.z=i,o.w=n,o):new a(e,t,i,n)},a.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new a(e.red,e.green,e.blue,e.alpha)},a.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new a(e.x,e.y,e.z,e.w)},a.packedLength=4,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.x,r[i++]=e.y,r[i++]=e.z,r[i]=e.w,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.x=e[i++],n.y=e[i++],n.z=e[i++],n.w=e[i],n},a.packArray=function(e,t){var i=e.length;r(t)?t.length=4*i:t=new Array(4*i);for(var n=0;nu.x&&e.clone(o,u),xc.y&&e.clone(o,c),Pd.z&&e.clone(o,d)}var D=e.magnitudeSquared(e.subtract(u,a,C)),I=e.magnitudeSquared(e.subtract(c,s,C)),O=e.magnitudeSquared(e.subtract(d,l,C)),M=a,R=u,N=D;I>N&&(N=I,M=s,R=c),O>N&&(N=O,M=l,R=d);var L=b;L.x=.5*(M.x+R.x),L.y=.5*(M.y+R.y),L.z=.5*(M.z+R.z);var k=e.magnitudeSquared(e.subtract(R,L,C)),F=Math.sqrt(k),B=S;B.x=a.x,B.y=s.y,B.z=l.z;var U=w;U.x=u.x,U.y=c.y,U.z=d.z;var V=e.multiplyByScalar(e.add(B,U,C),.5,T),z=0;for(i=0;iz&&(z=G);var H=e.magnitudeSquared(e.subtract(o,L,C));if(H>k){var W=Math.sqrt(H);F=.5*(F+W),k=F*F;var j=W-F;L.x=(F*L.x+j*o.x)/W,L.y=(F*L.y+j*o.y)/W,L.z=(F*L.z+j*o.z)/W}}return FA.x&&e.clone(s,A),IE.y&&e.clone(s,E),Ox.z&&e.clone(s,x)}var M=e.magnitudeSquared(e.subtract(A,u,C)),R=e.magnitudeSquared(e.subtract(E,c,C)),N=e.magnitudeSquared(e.subtract(x,d,C)),L=u,k=A,F=M;R>F&&(F=R,L=c,k=E),N>F&&(F=N,L=d,k=x);var B=b;B.x=.5*(L.x+k.x),B.y=.5*(L.y+k.y),B.z=.5*(L.z+k.z);var U=e.magnitudeSquared(e.subtract(k,B,C)),V=Math.sqrt(U),z=S;z.x=u.x,z.y=c.y,z.z=d.z;var G=w;G.x=A.x,G.y=E.y,G.z=x.z;var H=e.multiplyByScalar(e.add(z,G,C),.5,T),W=0;for(l=0;lW&&(W=j);var q=e.magnitudeSquared(e.subtract(s,B,C));if(q>U){var Y=Math.sqrt(q);V=.5*(V+Y),U=V*V;var X=Y-V;B.x=(V*B.x+X*s.x)/Y,B.y=(V*B.y+X*s.y)/Y,B.z=(V*B.z+X*s.z)/Y}}return Vc.x&&e.clone(o,c),Pd.y&&e.clone(o,d),DA.z&&e.clone(o,A)}var I=e.magnitudeSquared(e.subtract(c,s,C)),O=e.magnitudeSquared(e.subtract(d,l,C)),M=e.magnitudeSquared(e.subtract(A,u,C)),R=s,N=c,L=I;O>L&&(L=O,R=l,N=d),M>L&&(L=M,R=u,N=A);var k=b;k.x=.5*(R.x+N.x),k.y=.5*(R.y+N.y),k.z=.5*(R.z+N.z);var F=e.magnitudeSquared(e.subtract(N,k,C)),B=Math.sqrt(F),U=S;U.x=s.x,U.y=l.y,U.z=u.z;var V=w;V.x=c.x,V.y=d.y,V.z=A.z;var z=e.multiplyByScalar(e.add(U,V,C),.5,T),G=0;for(a=0;aG&&(G=H);var W=e.magnitudeSquared(e.subtract(o,k,C));if(W>F){var j=Math.sqrt(W);B=.5*(B+j),F=B*B;var q=j-B;k.x=(B*k.x+q*o.x)/j,k.y=(B*k.y+q*o.y)/j,k.z=(B*k.z+q*o.z)/j}}return B=c+l)return t.clone(i),i;if(l>=c+a)return r.clone(i),i;var d=.5*(a+c+l),p=e.multiplyByScalar(u,(-a+d)/c,k);return e.add(p,o,p),e.clone(p,i.center),i.radius=d,i};var F=new e;h.expand=function(t,r,i){i=h.clone(t,i);var n=e.magnitude(e.subtract(r,i.center,F));return n>i.radius&&(i.radius=n),i},h.intersectPlane=function(t,r){var i=t.center,n=t.radius,o=r.normal,a=e.dot(o,i)+r.distance;return a<-n?s.OUTSIDE:a=i[r]){if(r+1=0&&e>=i[r-1])return r-1;var o;if(e>i[r])for(o=r;o=i[o]&&e=0&&!(e>=i[o]&&ei&&(t=Math.floor((e-i)/o)+1,e-=t*o),e},o.prototype.clampTime=function(e){var t=this.times;return n.clamp(e,t[0],t[t.length-1])},o}),define("Core/LinearSpline",["./Cartesian3","./defaultValue","./defined","./defineProperties","./DeveloperError","./Spline"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT);var r=e.points,i=e.times;this._times=i,this._points=r,this._lastTimeIndex=0}return i(a.prototype,{times:{get:function(){return this._times}},points:{get:function(){return this._points}}}),a.prototype.findTimeInterval=o.prototype.findTimeInterval,a.prototype.wrapTime=o.prototype.wrapTime,a.prototype.clampTime=o.prototype.clampTime,a.prototype.evaluate=function(t,i){var n=this.points,o=this.times,a=this._lastTimeIndex=this.findTimeInterval(t,this._lastTimeIndex),s=(t-o[a])/(o[a+1]-o[a]);return r(i)||(i=new e),e.lerp(n[a],n[a+1],s,i)},a}),define("Core/TridiagonalSystemSolver",["./Cartesian3","./defined","./DeveloperError"],function(e,t,r){"use strict";var i={};return i.solve=function(t,r,i,n){var o,a=new Array(i.length),s=new Array(n.length),l=new Array(n.length);for(o=0;o=0;--o)l[o]=e.subtract(s[o],e.multiplyByScalar(l[o+1],a[o],l[o]),l[o]);return l},i}), -define("Core/HermiteSpline",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./LinearSpline","./Matrix4","./Spline","./TridiagonalSystemSolver"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r,n){var o=p,a=m,s=f,l=g;o.length=a.length=t.length-1,s.length=l.length=t.length;var c;o[0]=s[0]=1,a[0]=0;var d=l[0];for(i(d)||(d=l[0]=new e),e.clone(r,d),c=1;c2&&(n(a)||(a=f,e.multiplyByScalar(r[1],2,a),e.subtract(a,r[2],a),e.subtract(a,r[0],a),e.multiplyByScalar(a,.5,a)),!n(s))){var l=r.length-1;s=m,e.multiplyByScalar(r[l-1],2,s),e.subtract(r[l],s,s),e.add(s,r[l-2],s),e.multiplyByScalar(s,.5,s)}this._times=o,this._points=r,this._firstTangent=e.clone(a),this._lastTangent=e.clone(s),this._evaluateFunction=u(this),this._lastTimeIndex=0}var d=new t,h=new e,p=new e,f=new e,m=new e;return o(c.prototype,{times:{get:function(){return this._times}},points:{get:function(){return this._points}},firstTangent:{get:function(){return this._firstTangent}},lastTangent:{get:function(){return this._lastTangent}}}),c.catmullRomCoefficientMatrix=new s(-.5,1,-.5,0,1.5,-2.5,0,1,-1.5,2,.5,0,.5,-.5,0,0),c.prototype.findTimeInterval=l.prototype.findTimeInterval,c.prototype.wrapTime=l.prototype.wrapTime,c.prototype.clampTime=l.prototype.clampTime,c.prototype.evaluate=function(e,t){return this._evaluateFunction(e,t)},c}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function i(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function n(e,t){return t-e}return r(i.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),i.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},i.prototype.removeEventListener=function(e,t){for(var r=this._listeners,i=this._scopes,n=-1,o=0;o0){for(s.sort(n),e=0;e=a&&(p=a-1);var f=(o.north-t.latitude)/d|0;return f>=u&&(f=u-1),i(n)?(n.x=p,n.y=f,n):new e(p,f)}},u}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,r,i,n,o,a){"use strict";function s(e,r){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,n(r)&&(this.cameraPosition=r)}function l(e,r,i){var n=e.transformPositionToScaledSpace(r,f),o=t.magnitudeSquared(n),a=Math.sqrt(o),s=t.divideByScalar(n,a,m);o=Math.max(1,o),a=Math.max(1,a);var l=t.dot(s,i),u=t.magnitude(t.cross(s,i,s)),c=1/a;return 1/(l*c-u*(Math.sqrt(o-1)*c))}function u(e,r,i){if(!(r<=0||r===1/0||r!==r))return t.multiplyByScalar(e,r,i)}function c(e,r){return t.equals(r,t.ZERO)?r:(e.transformPositionToScaledSpace(r,g),t.normalize(g,g))}o(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var r=this._ellipsoid,i=r.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),n=t.magnitudeSquared(i)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=i,this._distanceToLimbInScaledSpaceSquared=n}}});var d=new t;s.prototype.isPointVisible=function(e){var t=this._ellipsoid,r=t.transformPositionToScaledSpace(e,d);return this.isScaledSpacePointVisible(r)},s.prototype.isScaledSpacePointVisible=function(e){var r=this._cameraPositionInScaledSpace,i=this._distanceToLimbInScaledSpaceSquared,n=t.subtract(e,r,d),o=-t.dot(n,r);return!(i<0?o>0:o>i&&o*o/t.magnitudeSquared(n)>i)},s.prototype.computeHorizonCullingPoint=function(e,r,i){n(i)||(i=new t);for(var o=this._ellipsoid,a=c(o,e),s=0,d=0,h=r.length;ds&&s/a0?[h/e,n/h]:[n/h,h/e]},i}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,i){var n,o,a=e,s=t/3,l=r/3,u=i,c=a*l,d=s*u,h=s*s,p=l*l,f=a*l-h,m=a*u-s*l,g=s*u-p,_=4*f*g-m*m;if(_<0){var v,y,C;h*d>=c*p?(v=a,y=f,C=-2*s*f+a*m):(v=u,y=g,C=-u*m+2*l*g);var b=C<0?-1:1,S=-b*Math.abs(v)*Math.sqrt(-_);o=-C+S;var w=o/2,T=w<0?-Math.pow(-w,1/3):Math.pow(w,1/3),A=o===S?-T:-y/T;return n=y<=0?T+A:-C/(T*T+A*A+y),h*d>=c*p?[(n-s)/a]:[-u/(n+l)]}var E=f,x=-2*s*f+a*m,P=g,D=-u*m+2*l*g,I=Math.sqrt(_),O=Math.sqrt(3)/2,M=Math.abs(Math.atan2(a*I,-x)/3);n=2*Math.sqrt(-E);var R=Math.cos(M);o=n*R;var N=n*(-R/2-O*Math.sin(M)),L=o+N>2*s?o-s:N-s,k=a,F=L/k;M=Math.abs(Math.atan2(u*I,-D)/3),n=2*Math.sqrt(-P),R=Math.cos(M),o=n*R,N=n*(-R/2-O*Math.sin(M));var B=-u,U=o+N<2*l?o+l:N+l,V=B/U,z=k*U,G=-L*U-k*B,H=L*B,W=(l*G-s*H)/(-s*G+l*z);return F<=W?F<=V?W<=V?[F,W,V]:[F,V,W]:[V,F,W]:F<=V?[W,F,V]:W<=V?[W,V,F]:[V,W,F]}var i={};return i.computeDiscriminant=function(e,t,r,i){var n=e*e,o=t*t,a=r*r;return 18*e*t*r*i+o*a-27*n*(i*i)-4*(e*a*r+o*t*i)},i.computeRealRoots=function(e,i,n,o){var a,s;if(0===e)return t.computeRealRoots(i,n,o);if(0===i){if(0===n){if(0===o)return[0,0,0];s=-o/e;var l=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3);return[l,l,l]}return 0===o?(a=t.computeRealRoots(e,0,n),0===a.Length?[0]:[a[0],0,a[1]]):r(e,0,n,o)}return 0===n?0===o?(s=-i/e,s<0?[s,0,0]:[0,0,s]):r(e,i,0,o):0===o?(a=t.computeRealRoots(e,i,n),0===a.length?[0]:a[1]<=0?[a[0],a[1],0]:a[0]>=0?[0,a[0],a[1]]:[a[0],0,a[1]]):r(e,i,n,o)},i}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,i){"use strict";function n(t,n,o,a){var s=t*t,l=n-3*s/8,u=o-n*t/2+s*t/8,c=a-o*t/4+n*s/16-3*s*s/256,d=e.computeRealRoots(1,2*l,l*l-4*c,-u*u);if(d.length>0){var h=-t/4,p=d[d.length-1];if(Math.abs(p)=0&&_>=0){var v=Math.sqrt(g),y=Math.sqrt(_);return[h-y,h-v,h+v,h+y]}if(g>=0&&_<0)return m=Math.sqrt(g),[h-m,h+m];if(g<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(p>0){var C=Math.sqrt(p),b=(l+p-u/C)/2,S=(l+p+u/C)/2,w=i.computeRealRoots(1,C,b),T=i.computeRealRoots(1,-C,S);return 0!==w.length?(w[0]+=h,w[1]+=h,0!==T.length?(T[0]+=h,T[1]+=h,w[1]<=T[0]?[w[0],w[1],T[0],T[1]]:T[1]<=w[0]?[T[0],T[1],w[0],w[1]]:w[0]>=T[0]&&w[1]<=T[1]?[T[0],w[0],w[1],T[1]]:T[0]>=w[0]&&T[1]<=w[1]?[w[0],T[0],T[1],w[1]]:w[0]>T[0]&&w[0]0){var f,m,g=p[0],_=n-g,v=_*_,y=t/2,C=_/2,b=v-4*a,S=v+4*Math.abs(a),w=u-4*g,T=u+4*Math.abs(g);if(g<0||b*T=M[0]&&O[1]<=M[1]?[M[0],O[0],O[1],M[1]]:M[0]>=O[0]&&M[1]<=O[1]?[O[0],M[0],M[1],O[1]]:O[0]>M[0]&&O[0]0){var o=1/(2*e),a=Math.sqrt(n),s=(-t+a)*o,l=(-t-a)*o;return s0?y.push(new e(n,o*k,o*-U)):0!==U?(y.push(new e(n,o*k,o*-U)),y.push(new e(n,o*k,o*U)),++N):y.push(new e(n,o*k,o*U))}return y}var m={};m.rayPlane=function(t,r,n){i(n)||(n=new e);var o=t.origin,s=t.direction,l=r.normal,u=e.dot(l,s);if(!(Math.abs(u)w)return;if(u=e.cross(l,m,C),(d=e.dot(f,u))<0||c+d>w)return;h=e.dot(b,u)/w}else{if(Math.abs(w)1)return;if(u=e.cross(l,m,C),(d=e.dot(f,u)*T)<0||c+d>1)return;h=e.dot(b,u)*T}return h},m.rayTriangle=function(t,r,n,o,a,s){var l=m.rayTriangleParametric(t,r,n,o,a);if(i(l)&&!(l<0))return i(s)||(s=new e),e.multiplyByScalar(t.direction,l,s),e.add(t.origin,s,s)};var b=new c;m.lineSegmentTriangle=function(t,r,n,o,a,s,l){var u=b;e.clone(t,u.origin),e.subtract(r,t,u.direction),e.normalize(u.direction,u.direction);var c=m.rayTriangleParametric(u,n,o,a,s);if(!(!i(c)||c<0||c>e.distance(t,r)))return i(l)||(l=new e),e.multiplyByScalar(u.direction,c,l),e.add(u.origin,l,l)};var S={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=h(e,t,r),i(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var w=new c;m.lineSegmentSphere=function(t,r,n,o){var a=w;e.clone(t,a.origin);var s=e.subtract(r,t,a.direction),l=e.magnitude(s);if(e.normalize(s,s),o=h(a,n,o),!(!i(o)||o.stop<0||o.start>l))return o.start=Math.max(o.start,0),o.stop=Math.min(o.stop,l),o};var T=new e,A=new e;m.rayEllipsoid=function(t,r){var i,n,a,s,l,u=r.oneOverRadii,c=e.multiplyComponents(u,t.origin,T),d=e.multiplyComponents(u,t.direction,A),h=e.magnitudeSquared(c),p=e.dot(c,d);if(h>1){if(p>=0)return;var f=p*p;if(i=h-1,n=e.magnitudeSquared(d),a=n*i,fa){s=p*p-a,l=-p+Math.sqrt(s);var m=l/n,g=i/l;return m=0)return n}var u=i(this.rayEllipsoid(t,r)),c=r.transformPositionToScaledSpace(o,E),d=e.normalize(c,c),h=e.mostOrthogonalAxis(c,D),p=e.normalize(e.cross(h,d,x),x),m=e.normalize(e.cross(d,p,P),P),g=O;g[0]=d.x,g[1]=d.y,g[2]=d.z,g[3]=p.x,g[4]=p.y,g[5]=p.z,g[6]=m.x,g[7]=m.y,g[8]=m.z;var _=s.transpose(g,M),v=s.fromScale(r.radii,R),y=s.fromScale(r.oneOverRadii,N),C=L;C[0]=0,C[1]=-o.z,C[2]=o.y,C[3]=o.z,C[4]=0,C[5]=-o.x,C[6]=-o.y,C[7]=o.x,C[8]=0;var b,S,w=s.multiply(s.multiply(_,y,k),C,k),T=s.multiply(s.multiply(w,v,F),g,F),A=s.multiplyByVector(w,n,I),z=f(T,e.negate(A,E),0,0,1),G=z.length;if(G>0){for(var H=e.clone(e.ZERO,U),W=Number.NEGATIVE_INFINITY,j=0;jW&&(W=Y,H=e.clone(b,H))}var X=r.cartesianToCartographic(H,V);return W=a.clamp(W,0,1),S=e.magnitude(e.subtract(H,n,D))*Math.sqrt(1-W*W),S=u?-S:S,X.height=S,r.cartographicToCartesian(X,new e)}};var z=new e;return m.lineSegmentPlane=function(t,r,n,o){i(o)||(o=new e);var s=e.subtract(r,t,z),l=n.normal,u=e.dot(l,s);if(!(Math.abs(u)1))return e.multiplyByScalar(s,d,o),e.add(t,o,o),o}},m.trianglePlaneIntersection=function(t,r,i,n){var o=n.normal,a=n.distance,s=e.dot(o,t)+a<0,l=e.dot(o,r)+a<0,u=e.dot(o,i)+a<0,c=0;c+=s?1:0,c+=l?1:0,c+=u?1:0;var d,h;if(1!==c&&2!==c||(d=new e,h=new e),1===c){if(s)return m.lineSegmentPlane(t,r,n,d),m.lineSegmentPlane(t,i,n,h),{positions:[t,r,i,d,h],indices:[0,3,4,1,2,4,1,4,3]};if(l)return m.lineSegmentPlane(r,i,n,d),m.lineSegmentPlane(r,t,n,h),{positions:[t,r,i,d,h],indices:[1,3,4,2,0,4,2,4,3]};if(u)return m.lineSegmentPlane(i,t,n,d),m.lineSegmentPlane(i,r,n,h),{positions:[t,r,i,d,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===c){if(!s)return m.lineSegmentPlane(r,t,n,d),m.lineSegmentPlane(i,t,n,h),{positions:[t,r,i,d,h],indices:[1,2,4,1,4,3,0,3,4]};if(!l)return m.lineSegmentPlane(i,r,n,d),m.lineSegmentPlane(t,r,n,h),{positions:[t,r,i,d,h],indices:[2,0,4,2,4,3,1,3,4]};if(!u)return m.lineSegmentPlane(t,i,n,d),m.lineSegmentPlane(r,i,n,h),{positions:[t,r,i,d,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,i,n,o,a){"use strict";function s(t,r){this.normal=e.clone(t),this.distance=r}s.fromPointNormal=function(t,i,n){var o=-e.dot(i,t);return r(n)?(e.clone(i,n.normal),n.distance=o,n):new s(i,o)};var l=new e;s.fromCartesian4=function(t,i){var n=e.fromCartesian4(t,l),o=t.w;return r(i)?(e.clone(n,i.normal),i.distance=o,i):new s(n,o)},s.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var u=new e;return s.transform=function(t,r,i){return a.multiplyByPointAsVector(r,t.normal,l),e.normalize(l,l),e.multiplyByScalar(t.normal,-t.distance,u),a.multiplyByPoint(r,u,u),s.fromPointNormal(u,l,i)},s.clone=function(t,i){return r(i)?(e.clone(t.normal,i.normal),i.distance=t.distance,i):new s(t.normal,t.distance)},s.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},s.ORIGIN_XY_PLANE=n(new s(e.UNIT_Z,0)),s.ORIGIN_YZ_PLANE=n(new s(e.UNIT_X,0)),s.ORIGIN_ZX_PLANE=n(new s(e.UNIT_Y,0)),s}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,i,n){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=i,this.ut1MinusUtc=n}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,i=t[r++],n=function(e,t,r,i){r||(r=" ");var n=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return i?e+n:n+e},o=function(e,t,r,i,o,a){var s=i-e.length;return s>0&&(e=r||!o?n(e,i,a,r):e.slice(0,t.length)+n("",s,"0",!0)+e.slice(t.length)),e},a=function(e,t,r,i,a,s,l){var u=e>>>0;return r=r&&u&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+n(u.toString(t),s||0,"0",!1),o(e,r,i,a,l)},s=function(e,t,r,i,n,a){return null!=i&&(e=e.slice(0,i)),o(e,"",t,r,n,a)},l=function(e,i,l,u,c,d,h){var p,f,m,g,_;if("%%"==e)return"%";for(var v=!1,y="",C=!1,b=!1,S=" ",w=l.length,T=0;l&&T-1?6:"d"==h?0:void 0,_=i?t[i.slice(0,-1)]:t[r++],h){case"s":return s(String(_),v,u,d,C,S);case"c":return s(String.fromCharCode(+_),v,u,d,C);case"b":return a(_,2,b,v,u,d,C);case"o":return a(_,8,b,v,u,d,C);case"x":return a(_,16,b,v,u,d,C);case"X":return a(_,16,b,v,u,d,C).toUpperCase();case"u":return a(_,10,b,v,u,d,C);case"i":case"d":return p=+_||0,p=Math.round(p-p%1),f=p<0?"-":y,_=f+n(String(Math.abs(p)),d,"0",!1),o(_,f,v,u,C);case"e":case"E":case"f":case"F":case"g":case"G":return p=+_,f=p<0?"-":y,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],g=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=f+Math.abs(p)[m](d),o(_,f,v,u,C)[g]();default:return e}};return i.replace(e,l)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,i,n,o,a,s){this.year=e,this.month=t,this.day=r,this.hour=i,this.minute=n,this.second=o,this.millisecond=a,this.isLeapSecond=s}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t){return m.compare(e.julianDate,t.julianDate)}function d(e){v.julianDate=e;var r=m.leapSeconds,i=t(r,v,c);i<0&&(i=~i),i>=r.length&&(i=r.length-1);var n=r[i].offset;if(i>0){m.secondsDifference(r[i].julianDate,e)>n&&(i--,n=r[i].offset)}m.addSeconds(e,n,e)}function h(e,r){v.julianDate=e;var i=m.leapSeconds,n=t(i,v,c);if(n<0&&(n=~n),0===n)return m.addSeconds(e,-i[0].offset,r);if(n>=i.length)return m.addSeconds(e,-i[n-1].offset,r);var o=m.secondsDifference(i[n].julianDate,e);return 0===o?m.addSeconds(e,-i[n].offset,r):o<=1?void 0:m.addSeconds(e,-i[--n].offset,r)}function p(e,t,r){var i=t/l.SECONDS_PER_DAY|0;return e+=i,t-=l.SECONDS_PER_DAY*i,t<0&&(e--,t+=l.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function f(e,t,r,i,n,o,a){var s=(t-14)/12|0,u=e+4800+s,c=(1461*u/4|0)+(367*(t-2-12*s)/12|0)-(3*((u+100)/100|0)/4|0)+r-32075;(i-=12)<0&&(i+=24);var d=o+(i*l.SECONDS_PER_HOUR+n*l.SECONDS_PER_MINUTE+a*l.SECONDS_PER_MILLISECOND);return d>=43200&&(c-=1),[c,d]}function m(e,t,i){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),i=r(i,u.UTC);var n=0|e;t+=(e-n)*l.SECONDS_PER_DAY,p(n,t,this),i===u.UTC&&d(this)}var g=new o,_=[31,28,31,30,31,30,31,31,30,31,30,31],v=new s,y=/^(\d{4})$/,C=/^(\d{4})-(\d{2})$/,b=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,w=/^(\d{4})-?(\d{2})-?(\d{2})$/,T=/([Z+\-])?(\d{2})?:?(\d{2})?$/,A=/^(\d{2})(\.\d+)?/.source+T.source,E=/^(\d{2}):?(\d{2})(\.\d+)?/.source+T.source,x=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+T.source;m.fromGregorianDate=function(e,t){var r=f(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return i(t)?(p(r[0],r[1],t),d(t),t):new m(r[0],r[1],u.UTC)},m.fromDate=function(e,t){var r=f(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return i(t)?(p(r[0],r[1],t),d(t),t):new m(r[0],r[1],u.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,n,o,s=e.split("T"),l=1,c=1,h=0,g=0,v=0,T=0,P=s[0],D=s[1];if(null!==(s=P.match(w)))r=+s[1],l=+s[2],c=+s[3];else if(null!==(s=P.match(C)))r=+s[1],l=+s[2];else if(null!==(s=P.match(y)))r=+s[1];else{var I;if(null!==(s=P.match(b)))r=+s[1],I=+s[2],o=a(r);else if(null!==(s=P.match(S))){r=+s[1];var O=+s[2],M=+s[3]||0,R=new Date(Date.UTC(r,0,4));I=7*O+M-R.getUTCDay()-3}n=new Date(Date.UTC(r,0,1)),n.setUTCDate(I),l=n.getUTCMonth()+1,c=n.getUTCDate()}o=a(r);var N;if(i(D)){s=D.match(x),null!==s?(h=+s[1],g=+s[2],v=+s[3],T=1e3*+(s[4]||0),N=5):(s=D.match(E),null!==s?(h=+s[1],g=+s[2],v=60*+(s[3]||0),N=4):null!==(s=D.match(A))&&(h=+s[1],g=60*+(s[2]||0),N=3));var L=s[N],k=+s[N+1],F=+(s[N+2]||0);switch(L){case"+":h-=k,g-=F;break;case"-":h+=k,g+=F;break;case"Z":break;default:g+=new Date(Date.UTC(r,l-1,c,h,g)).getTimezoneOffset()}}var B=60===v;for(B&&v--;g>=60;)g-=60,h++;for(;h>=24;)h-=24,c++;for(n=o&&2===l?29:_[l-1];c>n;)c-=n,l++,l>12&&(l-=12,r++),n=o&&2===l?29:_[l-1];for(;g<0;)g+=60,h--;for(;h<0;)h+=24,c--;for(;c<1;)l--,l<1&&(l+=12,r--),n=o&&2===l?29:_[l-1],c+=n;var U=f(r,l,c,h,g,v,T);return i(t)?(p(U[0],U[1],t),d(t)):t=new m(U[0],U[1],u.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var P=new m(0,0,u.TAI);return m.toGregorianDate=function(e,t){var r=!1,n=h(e,P);i(n)||(m.addSeconds(e,-1,P),n=h(P,P),r=!0);var a=n.dayNumber,s=n.secondsOfDay;s>=43200&&(a+=1);var u=a+68569|0,c=4*u/146097|0;u=u-((146097*c+3)/4|0)|0;var d=4e3*(u+1)/1461001|0;u=u-(1461*d/4|0)+31|0;var p=80*u/2447|0,f=u-(2447*p/80|0)|0;u=p/11|0;var g=p+2-12*u|0,_=100*(c-49)+d+u|0,v=s/l.SECONDS_PER_HOUR|0,y=s-v*l.SECONDS_PER_HOUR,C=y/l.SECONDS_PER_MINUTE|0;y-=C*l.SECONDS_PER_MINUTE;var b=0|y,S=(y-b)/l.SECONDS_PER_MILLISECOND;return v+=12,v>23&&(v-=24),r&&(b+=1),i(t)?(t.year=_,t.month=g,t.day=f,t.hour=v,t.minute=C,t.second=b,t.millisecond=S,t.isLeapSecond=r,t):new o(_,g,f,v,C,b,S,r)},m.toDate=function(e){var t=m.toGregorianDate(e,g),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var n,o=m.toGregorianDate(t,g);return i(r)||0===o.millisecond?i(r)&&0!==r?(n=(.01*o.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",o.year,o.month,o.day,o.hour,o.minute,o.second,n)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",o.year,o.month,o.day,o.hour,o.minute,o.second):(n=(.01*o.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",o.year,o.month,o.day,o.hour,o.minute,o.second,n))},m.clone=function(e,t){if(i(e))return i(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,u.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||i(e)&&i(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/l.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*l.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/l.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){v.julianDate=e;var r=m.leapSeconds,i=t(r,v,c);return i<0&&(i=~i,--i<0&&(i=0)),r[i].offset},m.addSeconds=function(e,t,r){return p(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var i=e.secondsOfDay+t*l.SECONDS_PER_MINUTE;return p(e.dayNumber,i,r)},m.addHours=function(e,t,r){var i=e.secondsOfDay+t*l.SECONDS_PER_HOUR;return p(e.dayNumber,i,r)},m.addDays=function(e,t,r){ -return p(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new s(new m(2441317,43210,u.TAI),10),new s(new m(2441499,43211,u.TAI),11),new s(new m(2441683,43212,u.TAI),12),new s(new m(2442048,43213,u.TAI),13),new s(new m(2442413,43214,u.TAI),14),new s(new m(2442778,43215,u.TAI),15),new s(new m(2443144,43216,u.TAI),16),new s(new m(2443509,43217,u.TAI),17),new s(new m(2443874,43218,u.TAI),18),new s(new m(2444239,43219,u.TAI),19),new s(new m(2444786,43220,u.TAI),20),new s(new m(2445151,43221,u.TAI),21),new s(new m(2445516,43222,u.TAI),22),new s(new m(2446247,43223,u.TAI),23),new s(new m(2447161,43224,u.TAI),24),new s(new m(2447892,43225,u.TAI),25),new s(new m(2448257,43226,u.TAI),26),new s(new m(2448804,43227,u.TAI),27),new s(new m(2449169,43228,u.TAI),28),new s(new m(2449534,43229,u.TAI),29),new s(new m(2450083,43230,u.TAI),30),new s(new m(2450630,43231,u.TAI),31),new s(new m(2451179,43232,u.TAI),32),new s(new m(2453736,43233,u.TAI),33),new s(new m(2454832,43234,u.TAI),34),new s(new m(2456109,43235,u.TAI),35),new s(new m(2457204,43236,u.TAI),36),new s(new m(2457754,43237,u.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,i){if(null===r||"object"!=typeof r)return r;i=e(i,!1);var n=new r.constructor;for(var o in r)if(r.hasOwnProperty(o)){var a=r[o];i&&(a=t(a,i)),n[o]=a}return n}return t}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),i=0;i0){var a=n.substring(0,o),s=n.substring(o+2);t[a]=s}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,i){this.statusCode=e,this.response=r,this.responseHeaders=i,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(r){var i=new e(r);i.normalize();var n=i.getAuthority();if(t(n)){if(-1!==n.indexOf("@")){n=n.split("@")[1]}if(-1===n.indexOf(":")){var o=i.getScheme();if(t(o)||(o=window.location.protocol,o=o.substring(0,o.length-1)),"http"===o)n+=":80";else{if("https"!==o)return;n+=":443"}}return n}}var n={},o={};return n.add=function(e,r){var i=e.toLowerCase()+":"+r;t(o[i])||(o[i]=!0)},n.remove=function(e,r){var i=e.toLowerCase()+":"+r;t(o[i])&&delete o[i]},n.contains=function(e){var r=i(e);return!(!t(r)||!t(o[r]))},n.clear=function(){o={}},n}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t){t=r(t,r.EMPTY_OBJECT);var n=t.url,a=t.responseType,l=r(t.method,"GET"),u=t.data,d=t.headers,h=t.overrideMimeType;n=r(n,t.url);var p=i(t.request)?t.request:new o;return p.url=n,p.requestFunction=function(){var t=e.defer(),r=c.load(n,a,l,u,d,t,h);return i(r)&&i(r.abort)&&(p.cancelFunction=function(){r.abort()}),t.promise},s.request(p)}function d(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function h(e,t){for(var r=d(e,t),i=new ArrayBuffer(r.length),n=new Uint8Array(i),o=0;o=300)&&(!g||0!==h.status))return void s.reject(new a(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,r=h.responseType;if(204===h.status)s.resolve();else if(!i(e)||i(t)&&r!==t)if("json"===t&&"string"==typeof e)try{s.resolve(JSON.parse(e))}catch(e){s.reject(e)}else(""===r||"document"===r)&&i(h.responseXML)&&h.responseXML.hasChildNodes()?s.resolve(h.responseXML):""!==r&&"text"!==r||!i(h.responseText)?s.reject(new l("Invalid XMLHttpRequest response type.")):s.resolve(h.responseText);else s.resolve(e)},h.onerror=function(e){s.reject(new a)},h.send(n),h},c.defaultLoad=c.load,c}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,r,i){return e({url:t,headers:r,request:i})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,r,i){"use strict";function n(r,n,a){t(n)?t(n.Accept)||(n=e(n),n.Accept=o.Accept):n=o;var s=i(r,n,a);if(t(s))return s.then(function(e){if(t(e))return JSON.parse(e)})}var o={Accept:"application/json,*/*;q=0.01"};return n}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),i(t.data))f(this,t.data);else if(i(t.url)){var n=this;this._downloadPromise=e(l(t.url),function(e){f(n,e)},function(){n._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else f(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function p(e,t){return a.compare(e.julianDate,t)}function f(e,r){if(!i(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!i(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var n=r.columnNames.indexOf("modifiedJulianDateUtc"),o=r.columnNames.indexOf("xPoleWanderRadians"),l=r.columnNames.indexOf("yPoleWanderRadians"),u=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),f=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(n<0||o<0||l<0||u<0||h<0||f<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var g=e._samples=r.samples,_=e._dates=[];e._dateColumn=n,e._xPoleWanderRadiansColumn=o,e._yPoleWanderRadiansColumn=l,e._ut1MinusUtcSecondsColumn=u,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=f,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var v,y=e._addNewLeapSeconds,C=0,b=g.length;Ct.length-1)return s.xPoleWander=0,s.yPoleWander=0,s.xPoleOffset=0,s.yPoleOffset=0,s.ut1MinusUtc=0,s;var u=t[n],c=t[o];if(u.equals(c)||i.equals(u))return m(e,r,n,l,s),s;if(i.equals(c))return m(e,r,o,l,s),s;var d=a.secondsDifference(i,u)/a.secondsDifference(c,u),h=n*l,p=o*l,f=r[h+e._ut1MinusUtcSecondsColumn],_=r[p+e._ut1MinusUtcSecondsColumn],v=_-f;if(v>.5||v<-.5){var y=r[h+e._taiMinusUtcSecondsColumn],C=r[p+e._taiMinusUtcSecondsColumn];y!==C&&(c.equals(i)?f=_:_-=C-y)}return s.xPoleWander=g(d,r[h+e._xPoleWanderRadiansColumn],r[p+e._xPoleWanderRadiansColumn]),s.yPoleWander=g(d,r[h+e._yPoleWanderRadiansColumn],r[p+e._yPoleWanderRadiansColumn]),s.xPoleOffset=g(d,r[h+e._xCelestialPoleOffsetRadiansColumn],r[p+e._xCelestialPoleOffsetRadiansColumn]),s.yPoleOffset=g(d,r[h+e._yCelestialPoleOffsetRadiansColumn],r[p+e._yCelestialPoleOffsetRadiansColumn]),s.ut1MinusUtc=g(d,f,_),s}return h.NONE=o({getPromiseToLoad:function(){return e()},compute:function(e,t){return i(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new n(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(i(this._samples)){if(i(r)||(r=new n(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var o=this._dates,s=this._lastIndex,l=0,c=0;if(i(s)){var d=o[s],h=o[s+1],p=a.lessThanOrEquals(d,e),f=!i(h),m=f||a.greaterThanOrEquals(h,e);if(p&&m)return l=s,!f&&h.equals(e)&&++l,c=l+1,_(this,o,this._samples,e,l,c,r),r}var g=t(o,e,a.compare,this._dateColumn);return g>=0?(g=this._totalSamples&&(l=this._totalSamples-1);for(var d=s/this._samplesPerXysFile|0,h=l/this._samplesPerXysFile|0,p=[],f=d;f<=h;++f)p.push(c(this,f));return e.all(p)},l.prototype.computeXysRadians=function(e,t,r){var o=u(this,e,t);if(!(o<0)){var a=o/this._stepSizeDays|0;if(!(a>=this._totalSamples)){var s=this._interpolationOrder,l=a-(s/2|0);l<0&&(l=0);var d=l+s;d>=this._totalSamples&&(d=this._totalSamples-1,(l=d-s)<0&&(l=0));var h=!1,p=this._samples;if(i(p[3*l])||(c(this,l/this._samplesPerXysFile|0),h=!0),i(p[3*d])||(c(this,d/this._samplesPerXysFile|0),h=!0),!h){i(r)?(r.x=0,r.y=0,r.s=0):r=new n(0,0,0);var f,m,g=o-l*this._stepSizeDays,_=this._work,v=this._denominators,y=this._coef,C=this._xTable;for(f=0;f<=s;++f)_[f]=g-C[f];for(f=0;f<=s;++f){for(y[f]=1,m=0;m<=s;++m)m!==f&&(y[f]*=_[m]);y[f]*=v[f];var b=3*(l+f);r.x+=y[f]*p[b++],r.y+=y[f]*p[b++],r.s+=y[f]*p[b]}return r}}}},l}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,i,n){this.x=r(e,0),this.y=r(t,0),this.z=r(i,0),this.w=r(n,0)}var u=new e;l.fromAxisAngle=function(t,r,n){var o=r/2,a=Math.sin(o);u=e.normalize(t,u);var s=u.x*a,c=u.y*a,d=u.z*a,h=Math.cos(o);return i(n)?(n.x=s,n.y=c,n.z=d,n.w=h,n):new l(s,c,d,h)};var c=[1,2,0],d=new Array(3);l.fromRotationMatrix=function(e,t){var r,n,o,a,u,h=e[s.COLUMN0ROW0],p=e[s.COLUMN1ROW1],f=e[s.COLUMN2ROW2],m=h+p+f;if(m>0)r=Math.sqrt(m+1),u=.5*r,r=.5/r,n=(e[s.COLUMN1ROW2]-e[s.COLUMN2ROW1])*r,o=(e[s.COLUMN2ROW0]-e[s.COLUMN0ROW2])*r,a=(e[s.COLUMN0ROW1]-e[s.COLUMN1ROW0])*r;else{var g=c,_=0;p>h&&(_=1),f>h&&f>p&&(_=2);var v=g[_],y=g[v];r=Math.sqrt(e[s.getElementIndex(_,_)]-e[s.getElementIndex(v,v)]-e[s.getElementIndex(y,y)]+1);var C=d;C[_]=.5*r,r=.5/r,u=(e[s.getElementIndex(y,v)]-e[s.getElementIndex(v,y)])*r,C[v]=(e[s.getElementIndex(v,_)]+e[s.getElementIndex(_,v)])*r,C[y]=(e[s.getElementIndex(y,_)]+e[s.getElementIndex(_,y)])*r,n=-C[0],o=-C[1],a=-C[2]}return i(t)?(t.x=n,t.y=o,t.z=a,t.w=u,t):new l(n,o,a,u)};var h=new l,p=new l,f=new l,m=new l;l.fromHeadingPitchRoll=function(t,r){return m=l.fromAxisAngle(e.UNIT_X,t.roll,h),f=l.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=l.multiply(f,m,f),p=l.fromAxisAngle(e.UNIT_Z,-t.heading,h),l.multiply(p,r,r)};var g=new e,_=new e,v=new l,y=new l,C=new l;l.packedLength=4,l.pack=function(e,t,i){return i=r(i,0),t[i++]=e.x,t[i++]=e.y,t[i++]=e.z,t[i]=e.w,t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n.x=e[t],n.y=e[t+1],n.z=e[t+2],n.w=e[t+3],n},l.packedInterpolationLength=3,l.convertPackedArrayForInterpolation=function(e,t,r,i){l.unpack(e,4*r,C),l.conjugate(C,C);for(var n=0,o=r-t+1;n=0?n=1:(n=-1,o=-o);for(var a=o-1,s=1-r,u=r*r,c=s*s,d=7;d>=0;--d)R[d]=(O[d]*u-M[d])*a,N[d]=(O[d]*c-M[d])*a;var h=n*r*(1+R[0]*(1+R[1]*(1+R[2]*(1+R[3]*(1+R[4]*(1+R[5]*(1+R[6]*(1+R[7])))))))),p=s*(1+N[0]*(1+N[1]*(1+N[2]*(1+N[3]*(1+N[4]*(1+N[5]*(1+N[6]*(1+N[7])))))))),f=l.multiplyByScalar(e,p,D);return l.multiplyByScalar(t,h,i),l.add(f,i,i)},l.fastSquad=function(e,t,r,i,n,o){var a=l.fastSlerp(e,t,n,x),s=l.fastSlerp(r,i,n,P);return l.fastSlerp(a,s,2*n*(1-n),o)},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},l.ZERO=o(new l(0,0,0,0)),l.IDENTITY=o(new l(0,0,0,1)),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},l}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";var C={},b={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},w={},T={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},A=new r,E=new r,x=new r;C.localFrameToFixedFrameGenerator=function(e,t){if(!b.hasOwnProperty(e)||!b[e].hasOwnProperty(t))throw new l("firstAxis and secondAxis must be east, north, up, west, south or down.");var i,n=b[e][t],o=e+t;return s(w[o])?i=w[o]:(i=function(i,o,l){if(s(l)||(l=new _),m.equalsEpsilon(i.x,0,m.EPSILON14)&&m.equalsEpsilon(i.y,0,m.EPSILON14)){var u=m.sign(i.z);r.unpack(S[e],0,A),"east"!==e&&"west"!==e&&r.multiplyByScalar(A,u,A),r.unpack(S[t],0,E),"east"!==t&&"west"!==t&&r.multiplyByScalar(E,u,E),r.unpack(S[n],0,x),"east"!==n&&"west"!==n&&r.multiplyByScalar(x,u,x)}else{o=a(o,d.WGS84),o.geodeticSurfaceNormal(i,T.up);var c=T.up,h=T.east;h.x=-i.y,h.y=i.x,h.z=0,r.normalize(h,T.east),r.cross(c,h,T.north),r.multiplyByScalar(T.up,-1,T.down),r.multiplyByScalar(T.east,-1,T.west),r.multiplyByScalar(T.north,-1,T.south),A=T[e],E=T[t],x=T[n]}return l[0]=A.x,l[1]=A.y,l[2]=A.z,l[3]=0,l[4]=E.x,l[5]=E.y,l[6]=E.z,l[7]=0,l[8]=x.x,l[9]=x.y,l[10]=x.z,l[11]=0,l[12]=i.x,l[13]=i.y,l[14]=i.z,l[15]=1,l},w[o]=i),i},C.eastNorthUpToFixedFrame=C.localFrameToFixedFrameGenerator("east","north"),C.northEastDownToFixedFrame=C.localFrameToFixedFrameGenerator("north","east"),C.northUpEastToFixedFrame=C.localFrameToFixedFrameGenerator("north","up"),C.northWestUpToFixedFrame=C.localFrameToFixedFrameGenerator("north","west");var P=new v,D=new r(1,1,1),I=new _;C.headingPitchRollToFixedFrame=function(e,t,i,n,o){n=a(n,C.eastNorthUpToFixedFrame);var s=v.fromHeadingPitchRoll(t,P),l=_.fromTranslationQuaternionRotationScale(r.ZERO,s,D,I);return o=n(e,i,o),_.multiply(o,l,o)};var O=new _,M=new g;C.headingPitchRollQuaternion=function(e,t,r,i,n){var o=C.headingPitchRollToFixedFrame(e,t,r,i,O),a=_.getRotation(o,M);return v.fromRotationMatrix(a,n)};var R=m.TWO_PI/86400,N=new f;C.computeTemeToPseudoFixedMatrix=function(e,t){N=f.addSeconds(e,-f.computeTaiMinusUtc(e),N);var r,i=N.dayNumber,n=N.secondsOfDay,o=i-2451545;r=n>=43200?(o+.5)/y.DAYS_PER_JULIAN_CENTURY:(o-.5)/y.DAYS_PER_JULIAN_CENTURY;var a=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),l=a*R%m.TWO_PI,u=72921158553e-15+1.1772758384668e-19*(i-2451545.5),c=(n+.5*y.SECONDS_PER_DAY)%y.SECONDS_PER_DAY,d=l+u*c,h=Math.cos(d),p=Math.sin(d);return s(t)?(t[0]=h,t[1]=-p,t[2]=0,t[3]=p,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new g(h,p,0,-p,h,0,0,0,1)},C.iau2006XysData=new h,C.earthOrientationParameters=u.NONE;C.preloadIcrfFixed=function(t){var r=t.start.dayNumber,i=t.start.secondsOfDay+32.184,n=t.stop.dayNumber,o=t.stop.secondsOfDay+32.184,a=C.iau2006XysData.preload(r,i,n,o),s=C.earthOrientationParameters.getPromiseToLoad();return e.all([a,s])},C.computeIcrfToFixedMatrix=function(e,t){s(t)||(t=new g);var r=C.computeFixedToIcrfMatrix(e,t);if(s(r))return g.transpose(r,t)};var L=new p(0,0,0),k=new c(0,0,0,0,0,0),F=new g,B=new g;C.computeFixedToIcrfMatrix=function(e,t){s(t)||(t=new g);var r=C.earthOrientationParameters.compute(e,k);if(s(r)){var i=e.dayNumber,n=e.secondsOfDay+32.184,o=C.iau2006XysData.computeXysRadians(i,n,L);if(s(o)){var a=o.x+r.xPoleOffset,l=o.y+r.yPoleOffset,u=1/(1+Math.sqrt(1-a*a-l*l)),c=F;c[0]=1-u*a*a,c[3]=-u*a*l,c[6]=a,c[1]=-u*a*l,c[4]=1-u*l*l,c[7]=l,c[2]=-a,c[5]=-l,c[8]=1-u*(a*a+l*l);var d=g.fromRotationZ(-o.s,B),h=g.multiply(c,d,F),p=e.dayNumber,_=e.secondsOfDay-f.computeTaiMinusUtc(e)+r.ut1MinusUtc,v=p-2451545,b=_/y.SECONDS_PER_DAY,S=.779057273264+b+.00273781191135448*(v+b);S=S%1*m.TWO_PI;var w=g.fromRotationZ(S,B),T=g.multiply(h,w,F),A=Math.cos(r.xPoleWander),E=Math.cos(r.yPoleWander),x=Math.sin(r.xPoleWander),P=Math.sin(r.yPoleWander),D=i-2451545+n/y.SECONDS_PER_DAY;D/=36525;var I=-47e-6*D*m.RADIANS_PER_DEGREE/3600,O=Math.cos(I),M=Math.sin(I),R=B;return R[0]=A*O,R[1]=A*M,R[2]=x,R[3]=-E*M+P*x*O,R[4]=E*O+P*x*M,R[5]=-P*A,R[6]=-P*M-E*x*O,R[7]=P*O-E*x*M,R[8]=E*A,g.multiply(T,R,t)}}};var U=new i;C.pointToWindowCoordinates=function(e,t,r,i){return i=C.pointToGLWindowCoordinates(e,t,r,i),i.y=2*t[5]-i.y,i},C.pointToGLWindowCoordinates=function(e,r,n,o){s(o)||(o=new t);var a=U;return _.multiplyByVector(e,i.fromElements(n.x,n.y,n.z,1,a),a),i.multiplyByScalar(a,1/a.w,a),_.multiplyByVector(r,a,a),t.fromCartesian4(a,o)};var V=new r,z=new r,G=new r;C.rotationMatrixFromPositionVelocity=function(e,t,i,n){var o=a(i,d.WGS84).geodeticSurfaceNormal(e,V),l=r.cross(t,o,z);r.equalsEpsilon(l,r.ZERO,m.EPSILON6)&&(l=r.clone(r.UNIT_X,l));var u=r.cross(l,t,G);return r.cross(t,u,l),r.negate(l,l),s(n)||(n=new g),n[0]=t.x,n[1]=t.y,n[2]=t.z,n[3]=l.x,n[4]=l.y,n[5]=l.z,n[6]=u.x,n[7]=u.y,n[8]=u.z,n};var H=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),W=new n,j=new r,q=new r,Y=new g,X=new _,Q=new _;return C.basisTo2D=function(e,t,i){var n=_.getTranslation(t,q),o=e.ellipsoid,a=o.cartesianToCartographic(n,W),s=e.project(a,j);r.fromElements(s.z,s.x,s.y,s);var l=C.eastNorthUpToFixedFrame(n,o,X),u=_.inverseTransformation(l,Q),c=_.getRotation(t,Y),d=_.multiplyByMatrix3(u,c,i);return _.multiply(H,d,i),_.setTranslation(i,s,i),i},C.wgs84To2DModelMatrix=function(e,t,i){var n=e.ellipsoid,o=C.eastNorthUpToFixedFrame(t,n,X),a=_.inverseTransformation(o,Q),s=n.cartesianToCartographic(t,W),l=e.project(s,j);r.fromElements(l.z,l.x,l.y,l);var u=_.fromTranslation(l,X);return _.multiply(H,a,i),_.multiply(u,i,i),i},C}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,t){t=n(t,l.WGS84),e=t.scaleToGeodeticSurface(e);var i=p.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=r.fromCartesian4(c.getColumn(i,0,m)),this._yAxis=r.fromCartesian4(c.getColumn(i,1,m));var o=r.fromCartesian4(c.getColumn(i,2,m));this._plane=d.fromPointNormal(e,o)}var m=new i;a(f.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var g=new e;f.fromPoints=function(t,r){return new f(e.fromPoints(t,g).center,r)};var _=new h,v=new r;f.prototype.projectPointOntoPlane=function(e,i){var n=_;n.origin=e,r.normalize(e,n.direction);var a=u.rayPlane(n,this._plane,v);if(o(a)||(r.negate(n.direction,n.direction),a=u.rayPlane(n,this._plane,v)),o(a)){var s=r.subtract(a,this._origin,a),l=r.dot(this._xAxis,s),c=r.dot(this._yAxis,s);return o(i)?(i.x=l,i.y=c,i):new t(l,c)}},f.prototype.projectPointsOntoPlane=function(e,t){o(t)||(t=[]);for(var r=0,i=e.length,n=0;n0?0:a.latitude;b.latitude=C.latitude=y.latitude=e.south,S.latitude=v.latitude=T,h.latitude=m.latitude=_.latitude=e.north,b.longitude=S.longitude=h.longitude=e.west,C.longitude=m.longitude=w,y.longitude=v.longitude=_.longitude=e.east,_.height=m.height=h.height=S.height=b.height=C.height=y.height=v.height=r,i.cartographicArrayToCartesianArray(D,I),c.projectPointsToNearestOnPlane(I,O);var A=Math.min(O[6].x,O[7].x,O[0].x),E=Math.max(O[2].x,O[3].x,O[4].x),M=Math.min(O[4].y,O[5].y,O[6].y),R=Math.max(O[0].y,O[1].y,O[2].y);return _.height=h.height=y.height=b.height=t,i.cartographicArrayToCartesianArray(D,I),g(c,A,E,M,R,Math.min(p.getPointDistance(d,I[0]),p.getPointDistance(d,I[2]),p.getPointDistance(d,I[4]),p.getPointDistance(d,I[6])),r,o)},m.clone=function(e,t){if(o(e))return o(t)?(r.clone(e.center,t.center),h.clone(e.halfAxes,t.halfAxes),t):new m(e.center,e.halfAxes)},m.intersectPlane=function(e,t){var i=e.center,n=t.normal,o=e.halfAxes,a=n.x,s=n.y,l=n.z,c=Math.abs(a*o[h.COLUMN0ROW0]+s*o[h.COLUMN0ROW1]+l*o[h.COLUMN0ROW2])+Math.abs(a*o[h.COLUMN1ROW0]+s*o[h.COLUMN1ROW1]+l*o[h.COLUMN1ROW2])+Math.abs(a*o[h.COLUMN2ROW0]+s*o[h.COLUMN2ROW1]+l*o[h.COLUMN2ROW2]),d=r.dot(n,i)+t.distance;return d<=-c?u.OUTSIDE:d>=c?u.INSIDE:u.INTERSECTING};var M=new r,R=new r,N=new r,L=new r;m.distanceSquaredTo=function(e,t){var i=r.subtract(t,e.center,A),n=e.halfAxes,o=h.getColumn(n,0,M),a=h.getColumn(n,1,R),s=h.getColumn(n,2,N),l=r.magnitude(o),u=r.magnitude(a),c=r.magnitude(s);r.normalize(o,o),r.normalize(a,a),r.normalize(s,s);var d=L;d.x=r.dot(i,o),d.y=r.dot(i,a),d.z=r.dot(i,s);var p,f=0;return d.x<-l?(p=d.x+l,f+=p*p):d.x>l&&(p=d.x-l,f+=p*p),d.y<-u?(p=d.y+u,f+=p*p):d.y>u&&(p=d.y-u,f+=p*p),d.z<-c?(p=d.z+c, -f+=p*p):d.z>c&&(p=d.z-c,f+=p*p),f};var k=new r,F=new r;m.computePlaneDistances=function(e,t,i,n){o(n)||(n=new c);var a=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,l=e.center,u=e.halfAxes,d=h.getColumn(u,0,M),p=h.getColumn(u,1,R),f=h.getColumn(u,2,N),m=r.add(d,p,k);r.add(m,f,m),r.add(m,l,m);var g=r.subtract(m,t,F),_=r.dot(i,g);return a=Math.min(_,a),s=Math.max(_,s),r.add(l,d,m),r.add(m,p,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),r.add(l,d,m),r.subtract(m,p,m),r.add(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),r.add(l,d,m),r.subtract(m,p,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),r.subtract(l,d,m),r.add(m,p,m),r.add(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),r.subtract(l,d,m),r.add(m,p,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),r.subtract(l,d,m),r.subtract(m,p,m),r.add(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),r.subtract(l,d,m),r.subtract(m,p,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),a=Math.min(_,a),s=Math.max(_,s),n.start=a,n.stop=s,n};var B=new e;return m.isOccluded=function(t,r){var i=e.fromOrientedBoundingBox(t,B);return!r.isBoundingSphereVisible(i)},m.prototype.intersectPlane=function(e){return m.intersectPlane(this,e)},m.prototype.distanceSquaredTo=function(e){return m.distanceSquaredTo(this,e)},m.prototype.computePlaneDistances=function(e,t,r){return m.computePlaneDistances(this,e,t,r)},m.prototype.isOccluded=function(e){return m.isOccluded(this,e)},m.equals=function(e,t){return e===t||o(e)&&o(t)&&r.equals(e.center,t.center)&&h.equals(e.halfAxes,t.halfAxes)},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e,t,i,a,u,h){var g,_,v,y;if(o(e)&&o(t)&&o(i)&&o(a)){var C=e.minimum,b=e.maximum,S=r.subtract(b,C,d),w=i-t;g=Math.max(r.maximumComponent(S),w)l.MaximumLatitude?e=l.MaximumLatitude:e<-l.MaximumLatitude&&(e=-l.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},l.MaximumLatitude=l.mercatorAngleToGeodeticLatitude(Math.PI),l.prototype.project=function(t,r){var n=this._semimajorAxis,o=t.longitude*n,a=l.geodeticLatitudeToMercatorAngle(t.latitude)*n,s=t.height;return i(r)?(r.x=o,r.y=a,r.z=s,r):new e(o,a,s)},l.prototype.unproject=function(e,r){var n=this._oneOverSemimajorAxis,o=e.x*n,a=l.mercatorAngleToGeodeticLatitude(e.y*n),s=e.z;return i(r)?(r.longitude=o,r.latitude=a,r.height=s,r):new t(o,a,s)},l}),define("Core/HeightmapTessellator",["./AxisAlignedBoundingBox","./BoundingSphere","./Cartesian2","./Cartesian3","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidalOccluder","./freezeObject","./Math","./Matrix4","./OrientedBoundingBox","./Rectangle","./TerrainEncoding","./Transforms","./WebMercatorProjection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";var _={};_.DEFAULT_STRUCTURE=u({heightScale:1,heightOffset:0,elementsPerHeight:1,stride:1,elementMultiplier:256,isBigEndian:!1});var v=new i,y=new d,C=new i,b=new i;return _.computeVertices=function(a){var u,S,w,T,A=Math.cos,E=Math.sin,x=Math.sqrt,P=Math.atan,D=Math.exp,I=c.PI_OVER_TWO,O=c.toRadians,M=a.heightmap,R=a.width,N=a.height,L=a.skirtHeight,k=n(a.isGeographic,!0),F=n(a.ellipsoid,s.WGS84),B=1/F.maximumRadius,U=a.nativeRectangle,V=a.rectangle;o(V)?(u=V.west,S=V.south,w=V.east,T=V.north):k?(u=O(U.west),S=O(U.south),w=O(U.east),T=O(U.north)):(u=U.west*B,S=I-2*P(D(-U.south*B)),w=U.east*B,T=I-2*P(D(-U.north*B)));var z=a.relativeToCenter,G=o(z);z=G?z:i.ZERO;var H=n(a.exaggeration,1),W=n(a.includeWebMercatorT,!1),j=n(a.structure,_.DEFAULT_STRUCTURE),q=n(j.heightScale,_.DEFAULT_STRUCTURE.heightScale),Y=n(j.heightOffset,_.DEFAULT_STRUCTURE.heightOffset),X=n(j.elementsPerHeight,_.DEFAULT_STRUCTURE.elementsPerHeight),Q=n(j.stride,_.DEFAULT_STRUCTURE.stride),Z=n(j.elementMultiplier,_.DEFAULT_STRUCTURE.elementMultiplier),K=n(j.isBigEndian,_.DEFAULT_STRUCTURE.isBigEndian),J=p.computeWidth(U),$=p.computeHeight(U),ee=J/(R-1),te=$/(N-1);k||(J*=B,$*=B);var re,ie,ne=F.radiiSquared,oe=ne.x,ae=ne.y,se=ne.z,le=65536,ue=-65536,ce=m.eastNorthUpToFixedFrame(z,F),de=d.inverseTransformation(ce,y);W&&(re=g.geodeticLatitudeToMercatorAngle(S),ie=1/(g.geodeticLatitudeToMercatorAngle(T)-re));var he=C;he.x=Number.POSITIVE_INFINITY,he.y=Number.POSITIVE_INFINITY,he.z=Number.POSITIVE_INFINITY;var pe=b;pe.x=Number.NEGATIVE_INFINITY,pe.y=Number.NEGATIVE_INFINITY,pe.z=Number.NEGATIVE_INFINITY;var fe=Number.POSITIVE_INFINITY,me=R+(L>0?2:0),ge=N+(L>0?2:0),_e=me*ge,ve=new Array(_e),ye=new Array(_e),Ce=new Array(_e),be=W?new Array(_e):[],Se=0,we=N,Te=0,Ae=R;L>0&&(--Se,++we,--Te,++Ae);for(var Ee=0,xe=Se;xe=N&&(Pe=N-1);var De=U.north-te*Pe;De=k?O(De):I-2*P(D(-De*B));var Ie=A(De),Oe=E(De),Me=se*Oe,Re=(De-S)/(T-S);Re=c.clamp(Re,0,1);var Ne;W&&(Ne=(g.geodeticLatitudeToMercatorAngle(De)-re)*ie);for(var Le=Te;Le=R&&(ke=R-1);var Fe=U.west+ee*ke;k?Fe=O(Fe):Fe*=B;var Be,Ue=Pe*(R*Q)+ke*Q;if(1===X)Be=M[Ue];else{Be=0;var Ve;if(K)for(Ve=0;Ve=0;--Ve)Be=Be*Z+M[Ue+Ve]}Be=(Be*q+Y)*H;var ze=(Fe-u)/(w-u);if(ze=c.clamp(ze,0,1),Ce[Ee]=new r(ze,Re),ue=Math.max(ue,Be),le=Math.min(le,Be),Le!==ke||xe!==Pe){Le<0?Fe-=1e-5*J:Fe+=1e-5*J,xe<0?De+=1e-5*$:De-=1e-5*$,Ie=A(De),Oe=E(De),Me=se*Oe,Be-=L}var Ge=Ie*A(Fe),He=Ie*E(Fe),We=oe*Ge,je=ae*He,qe=x(We*Ge+je*He+Me*Oe),Ye=1/qe,Xe=We*Ye,Qe=je*Ye,Ze=Me*Ye,Ke=new i;Ke.x=Xe+Ge*Be,Ke.y=Qe+He*Be,Ke.z=Ze+Oe*Be,ve[Ee]=Ke,ye[Ee]=Be,W&&(be[Ee]=Ne),Ee++,d.multiplyByPoint(de,Ke,v),i.minimumByComponent(v,he,he),i.maximumByComponent(v,pe,pe),fe=Math.min(fe,Be)}}var Je,$e=t.fromPoints(ve);o(V)&&V.width=this._maximumActiveTasks)){++this._activeTasks;var n=this;return e(c(),function(o){i(r)?o||(r.length=0):r=_;var a=n._nextID++,s=e.defer();return n._deferreds[a]=s,n._worker.postMessage({id:a,parameters:t,canTransferArrayBuffer:o},r),s.promise})}},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){return i(this._worker)&&this._worker.terminate(),n(this)},m._defaultWorkerModulePrefix="Workers/",m._workerModulePrefix=m._defaultWorkerModulePrefix,m._loaderConfig=void 0,m._canTransferArrayBuffer=void 0,m}),define("Core/TerrainMesh",["./defaultValue"],function(e){"use strict";function t(t,r,i,n,o,a,s,l,u,c,d){this.center=t,this.vertices=r,this.stride=e(l,6),this.indices=i,this.minimumHeight=n,this.maximumHeight=o,this.boundingSphere3D=a,this.occludeePointInScaledSpace=s,this.orientedBoundingBox=u,this.encoding=c,this.exaggeration=d}return t}),define("Core/TerrainProvider",["./defined","./defineProperties","./DeveloperError","./Math"],function(e,t,r,i){"use strict";function n(){r.throwInstantiationError()}t(n.prototype,{errorEvent:{get:r.throwInstantiationError},credit:{get:r.throwInstantiationError},tilingScheme:{get:r.throwInstantiationError},ready:{get:r.throwInstantiationError},readyPromise:{get:r.throwInstantiationError},hasWaterMask:{get:r.throwInstantiationError},hasVertexNormals:{get:r.throwInstantiationError},availability:{get:r.throwInstantiationError}});var o=[];return n.getRegularGridIndices=function(t,r){var i=o[t];e(i)||(o[t]=i=[]);var n=i[r];if(!e(n)){n=i[r]=new Uint16Array((t-1)*(r-1)*6);for(var a=0,s=0,l=0;l=a&&(p=a-1,h=a-2);var f=0|d,m=f+1;m>=s&&(m=s-1,f=s-2);var v=c-h,y=d-f;return f=s-1-f,m=s-1-m,g(v,y,_(e,t,r,i,n,f*a+h),_(e,t,r,i,n,f*a+p),_(e,t,r,i,n,m*a+h),_(e,t,r,i,n,m*a+p))}function m(e,t,r,i,n,o,a,s,l,u,c){var d=(l-o.west)*(a-1)/(o.east-o.west),h=(u-o.south)*(s-1)/(o.north-o.south);n>0&&(d+=1,h+=1,a+=2,s+=2);var p=n>0?a-1:a,f=0|d,m=f+1;m>=p&&(m=a-1,f=a-2);var _=n>0?s-1:s,v=0|h,y=v+1;y>=_&&(y=s-1,v=s-2);var C=d-f,b=h-v;return v=s-1-v,y=s-1-y,g(C,b,(t.decodeHeight(e,v*a+f)/c-r)/i,(t.decodeHeight(e,v*a+m)/c-r)/i,(t.decodeHeight(e,y*a+f)/c-r)/i,(t.decodeHeight(e,y*a+m)/c-r)/i)}function g(e,t,r,i,n,o){return t=0;--a)s=s*r+e[o+a];return s}function v(e,t,r,i,n,o,a,s){a*=n;var l;if(o)for(l=0;l0;--l)e[a+l]=s/i|0,s-=e[a+l]*i,i/=r;e[a+l]=s}i(p.prototype,{credits:{get:function(){}},waterMask:{get:function(){return this._waterMask}}});var y=new u("createVerticesFromHeightmap");return p.prototype.createMesh=function(i,n,a,s,u){var p=i.ellipsoid,f=i.tileXYToNativeRectangle(n,a,s),m=i.tileXYToRectangle(n,a,s);u=t(u,1);var g=p.cartographicToCartesian(l.center(m)),_=this._structure,v=h.getEstimatedLevelZeroGeometricErrorForAHeightmap(p,this._width,i.getNumberOfXTilesAtLevel(0)),C=v/(1<d.highestEncodedHeight?d.highestEncodedHeight:N,v(g,E,x,D,f,P,I*u+M,N)}return new p({buffer:g,width:u,height:c,childTileMask:0,structure:this._structure,createdByUpsampling:!0})}},p.prototype.isChildAvailable=function(e,t,r,i){var n=2;return r!==2*e&&++n,i!==2*t&&(n-=2),0!=(this._childTileMask&1<=i.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},o.createTypedArrayFromArrayBuffer=function(e,t,r,n){return e>=i.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,n):new Uint16Array(t,r,n)},r(o)}),define("Core/loadArrayBuffer",["./loadWithXhr"],function(e){"use strict";function t(t,r,i){return e({url:t,responseType:"arraybuffer",headers:r,request:i})}return t}),define("Core/Intersections2D",["./Cartesian3","./defined","./DeveloperError"],function(e,t,r){"use strict";var i={};return i.clipTriangleAtAxisAlignedThreshold=function(e,r,i,n,o,a){t(a)?a.length=0:a=[];var s,l,u;r?(s=ie,l=n>e,u=o>e);var c,d,h,p,f,m,g=s+l+u;return 1===g?s?(c=(e-i)/(n-i),d=(e-i)/(o-i),a.push(1),a.push(2),1!==d&&(a.push(-1),a.push(0),a.push(2),a.push(d)),1!==c&&(a.push(-1),a.push(0),a.push(1),a.push(c))):l?(h=(e-n)/(o-n),p=(e-n)/(i-n),a.push(2),a.push(0),1!==p&&(a.push(-1),a.push(1),a.push(0),a.push(p)),1!==h&&(a.push(-1),a.push(1),a.push(2),a.push(h))):u&&(f=(e-o)/(i-o),m=(e-o)/(n-o),a.push(0),a.push(1),1!==m&&(a.push(-1),a.push(2),a.push(1),a.push(m)),1!==f&&(a.push(-1),a.push(2),a.push(0),a.push(f))):2===g?s||i===e?l||n===e?u||o===e||(d=(e-i)/(o-i),h=(e-n)/(o-n),a.push(2),a.push(-1),a.push(0),a.push(2),a.push(d),a.push(-1),a.push(1),a.push(2),a.push(h)):(m=(e-o)/(n-o),c=(e-i)/(n-i),a.push(1),a.push(-1),a.push(2),a.push(1),a.push(m),a.push(-1),a.push(0),a.push(1),a.push(c)):(p=(e-n)/(i-n),f=(e-o)/(i-o),a.push(0),a.push(-1),a.push(1),a.push(0),a.push(p),a.push(-1),a.push(2),a.push(0),a.push(f)):3!==g&&(a.push(0),a.push(1),a.push(2)),a},i.computeBarycentricCoordinates=function(r,i,n,o,a,s,l,u,c){var d=n-l,h=l-a,p=s-u,f=o-u,m=1/(p*d+h*f),g=i-u,_=r-l,v=(p*_+h*g)*m,y=(-f*_+d*g)*m,C=1-v-y;return t(c)?(c.x=v,c.y=y,c.z=C,c):new e(v,y,C)},i}),define("Core/QuantizedMeshTerrainData",["../ThirdParty/when","./BoundingSphere","./Cartesian2","./Cartesian3","./defaultValue","./defined","./defineProperties","./DeveloperError","./IndexDatatype","./Intersections2D","./Math","./OrientedBoundingBox","./TaskProcessor","./TerrainEncoding","./TerrainMesh"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){function t(e,t){return a[e]-a[t]}function r(e,t){return o[e]-o[t]}this._quantizedVertices=e.quantizedVertices,this._encodedNormals=e.encodedNormals,this._indices=e.indices,this._minimumHeight=e.minimumHeight,this._maximumHeight=e.maximumHeight,this._boundingSphere=e.boundingSphere,this._orientedBoundingBox=e.orientedBoundingBox,this._horizonOcclusionPoint=e.horizonOcclusionPoint,this._credits=e.credits;var i=this._quantizedVertices.length/3,o=this._uValues=this._quantizedVertices.subarray(0,i),a=this._vValues=this._quantizedVertices.subarray(i,2*i);this._heightValues=this._quantizedVertices.subarray(2*i,3*i),this._westIndices=g(e.westIndices,t,i),this._southIndices=g(e.southIndices,r,i),this._eastIndices=g(e.eastIndices,t,i),this._northIndices=g(e.northIndices,r,i),this._westSkirtHeight=e.westSkirtHeight,this._southSkirtHeight=e.southSkirtHeight,this._eastSkirtHeight=e.eastSkirtHeight,this._northSkirtHeight=e.northSkirtHeight,this._childTileMask=n(e.childTileMask,15),this._createdByUpsampling=n(e.createdByUpsampling,!1),this._waterMask=e.waterMask,this._mesh=void 0}function g(e,t,r){y.length=e.length;for(var i=!1,n=0,o=e.length;n0&&t(e[n-1],e[n])>0;return i?(y.sort(t),l.createTypedArray(r,y)):e}function _(e,t,r){for(var i=e._mesh,n=i.vertices,o=i.encoding,a=i.indices,s=0,l=a.length;s=-1e-15&&g.y>=-1e-15&&g.z>=-1e-15){var _=o.decodeHeight(n,c),v=o.decodeHeight(n,d),y=o.decodeHeight(n,h);return g.x*_+g.y*v+g.z*y}}}function v(e,t,r){for(var i=e._uValues,n=e._vValues,o=e._heightValues,a=e._indices,s=0,l=a.length;s=-1e-15&&C.y>=-1e-15&&C.z>=-1e-15){var b=C.x*o[d]+C.y*o[h]+C.z*o[p];return c.lerp(e._minimumHeight,e._maximumHeight,b/S)}}}a(m.prototype,{credits:{get:function(){return this._credits}},waterMask:{get:function(){return this._waterMask}}});var y=[],C=new h("createVerticesFromQuantizedTerrainMesh");m.prototype.createMesh=function(t,r,i,a,s){var u=t.ellipsoid,c=t.tileXYToRectangle(r,i,a);s=n(s,1);var d=C.scheduleTask({minimumHeight:this._minimumHeight,maximumHeight:this._maximumHeight,quantizedVertices:this._quantizedVertices,octEncodedNormals:this._encodedNormals,includeWebMercatorT:!0,indices:this._indices,westIndices:this._westIndices,southIndices:this._southIndices,eastIndices:this._eastIndices,northIndices:this._northIndices,westSkirtHeight:this._westSkirtHeight,southSkirtHeight:this._southSkirtHeight,eastSkirtHeight:this._eastSkirtHeight,northSkirtHeight:this._northSkirtHeight,rectangle:c,relativeToCenter:this._boundingSphere.center,ellipsoid:u,exaggeration:s});if(o(d)){var h=this;return e(d,function(e){var t=h._quantizedVertices.length/3;t+=h._westIndices.length+h._southIndices.length+h._eastIndices.length+h._northIndices.length;var r=l.createTypedArray(t,e.indices),i=new Float32Array(e.vertices),o=e.center,a=e.minimumHeight,u=e.maximumHeight,c=n(e.boundingSphere,h._boundingSphere),d=n(e.orientedBoundingBox,h._orientedBoundingBox),m=h._horizonOcclusionPoint,g=e.vertexStride,_=p.clone(e.encoding);return h._skirtIndex=e.skirtIndex,h._vertexCountWithoutSkirts=h._quantizedVertices.length/3,h._mesh=new f(o,i,r,a,u,c,m,g,d,_,s),h._quantizedVertices=void 0,h._encodedNormals=void 0,h._indices=void 0,h._uValues=void 0,h._vValues=void 0,h._heightValues=void 0,h._westIndices=void 0,h._southIndices=void 0,h._eastIndices=void 0,h._northIndices=void 0,h._mesh})}};var b=new h("upsampleQuantizedTerrainMesh");m.prototype.upsample=function(r,n,a,s,u,c,h){var p=this._mesh;if(o(this._mesh)){var f=2*n!==u,g=2*a===c,_=r.ellipsoid,v=r.tileXYToRectangle(u,c,h),y=b.scheduleTask({vertices:p.vertices,vertexCountWithoutSkirts:this._vertexCountWithoutSkirts,indices:p.indices,skirtIndex:this._skirtIndex,encoding:p.encoding,minimumHeight:this._minimumHeight,maximumHeight:this._maximumHeight,isEastChild:f,isNorthChild:g,childRectangle:v,ellipsoid:_,exaggeration:p.exaggeration});if(o(y)){var C=Math.min(this._westSkirtHeight,this._eastSkirtHeight);C=Math.min(C,this._southSkirtHeight),C=Math.min(C,this._northSkirtHeight);var S=f?.5*C:this._westSkirtHeight,w=g?.5*C:this._southSkirtHeight,T=f?this._eastSkirtHeight:.5*C,A=g?this._northSkirtHeight:.5*C;return e(y,function(e){var r,n=new Uint16Array(e.vertices),a=l.createTypedArray(n.length/3,e.indices);return o(e.encodedNormals)&&(r=new Uint8Array(e.encodedNormals)),new m({quantizedVertices:n,indices:a,encodedNormals:r,minimumHeight:e.minimumHeight,maximumHeight:e.maximumHeight,boundingSphere:t.clone(e.boundingSphere),orientedBoundingBox:d.clone(e.orientedBoundingBox),horizonOcclusionPoint:i.clone(e.horizonOcclusionPoint),westIndices:e.westIndices,southIndices:e.southIndices,eastIndices:e.eastIndices,northIndices:e.northIndices,westSkirtHeight:S,southSkirtHeight:w,eastSkirtHeight:T,northSkirtHeight:A,childTileMask:0,createdByUpsampling:!0})})}}};var S=32767,w=new i;m.prototype.interpolateHeight=function(e,t,r){var i=c.clamp((t-e.west)/e.width,0,1);i*=S;var n=c.clamp((r-e.south)/e.height,0,1);return n*=S,o(this._mesh)?_(this,i,n):v(this,i,n)};var T=new r,A=new r,E=new r;return m.prototype.isChildAvailable=function(e,t,r,i){var n=2;return r!==2*e&&++n,i!==2*t&&(n-=2),0!=(this._childTileMask&1<=e.west&&t.east<=e.east&&t.south>=e.south&&t.north<=e.north}function p(e,t){return t.longitude>=e.west&&t.longitude<=e.east&&t.latitude>=e.south&&t.latitude<=e.north}function f(e,t,r){for(var i=0,n=!1;!n;){var o=t._nw&&p(t._nw.extent,r),a=t._ne&&p(t._ne.extent,r),s=t._sw&&p(t._sw.extent,r),l=t._se&&p(t._se.extent,r);if(o+a+s+l>1){o&&(i=Math.max(i,f(t,t._nw,r))),a&&(i=Math.max(i,f(t,t._ne,r))),s&&(i=Math.max(i,f(t,t._sw,r))),l&&(i=Math.max(i,f(t,t._se,r)));break}o?t=t._nw:a?t=t._ne:s?t=t._sw:l?t=t._se:n=!0}for(;t!==e;){for(var u=t.rectangles,c=u.length-1;c>=0&&u[c].level>i;--c){var d=u[c];p(d,r)&&(i=d.level)}t=t.parent}return i}function m(e,t,r){if(t){var i,n=!1;for(i=0;it.east&&r.push(new o(t.east,n.south,n.east,n.north)),n.southt.north&&r.push(new o(Math.max(t.west,n.west),t.north,Math.min(t.east,n.east),n.north))):r.push(n)}return r}var _=new o;a.prototype.addAvailableTileRange=function(e,t,r,i,n){var o=this._tilingScheme;o.tileXYToRectangle(t,r,e,_);var a=_.west,s=_.north;o.tileXYToRectangle(i,n,e,_);for(var d=_.east,h=_.south,p=new l(e,a,h,d,s),f=0;f=0;--n)if(r(i[n])&&0===i[n].length)return n;return 0};var S=new t;return a.prototype.isTileAvailable=function(e,t,r){var i=this._tilingScheme.tileXYToRectangle(t,r,e,_) -;return o.center(i,S),this.computeMaximumLevelAtPosition(S)>=e},a.prototype.computeChildMaskForTile=function(e,t,r){var i=e+1;if(i>=this._maximumLevel)return 0;var n=0;return n|=this.isTileAvailable(i,2*t,2*r+1)?1:0,n|=this.isTileAvailable(i,2*t+1,2*r+1)?2:0,n|=this.isTileAvailable(i,2*t,2*r)?4:0,n|=this.isTileAvailable(i,2*t+1,2*r)?8:0},i(s.prototype,{nw:{get:function(){return this._nw||(this._nw=new s(this.tilingScheme,this,this.level+1,2*this.x,2*this.y)),this._nw}},ne:{get:function(){return this._ne||(this._ne=new s(this.tilingScheme,this,this.level+1,2*this.x+1,2*this.y)),this._ne}},sw:{get:function(){return this._sw||(this._sw=new s(this.tilingScheme,this,this.level+1,2*this.x,2*this.y+1)),this._sw}},se:{get:function(){return this._se||(this._se=new s(this.tilingScheme,this,this.level+1,2*this.x+1,2*this.y+1)),this._se}}}),a}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var r,i=t.name,n=t.message;r=e(i)&&e(n)?i+": "+n:t.toString();var o=t.stack;return e(o)&&(r+="\n"+o),r}return t}),define("Core/TileProviderError",["./defaultValue","./defined","./formatError"],function(e,t,r){"use strict";function i(t,r,i,n,o,a,s){this.provider=t,this.message=r,this.x=i,this.y=n,this.level=o,this.timesRetried=e(a,0),this.retry=!1,this.error=s}return i.handleError=function(e,n,o,a,s,l,u,c,d){var h=e;return t(e)?(h.provider=n,h.message=a,h.x=s,h.y=l,h.level=u,h.retry=!1,h.error=d,++h.timesRetried):h=new i(n,a,s,l,u,0,d),o.numberOfListeners>0?o.raiseEvent(h):console.log('An error occurred in "'+n.constructor.name+'": '+r(a)),h.retry&&t(c)&&c(),h},i.handleSuccess=function(e){t(e)&&(e.timesRetried=-1)},i}),define("Core/CesiumTerrainProvider",["../ThirdParty/Uri","../ThirdParty/when","./BoundingSphere","./Cartesian3","./Credit","./defaultValue","./defined","./defineProperties","./DeveloperError","./Event","./GeographicTilingScheme","./HeightmapTerrainData","./IndexDatatype","./joinUrls","./loadArrayBuffer","./loadJson","./Math","./OrientedBoundingBox","./QuantizedMeshTerrainData","./RuntimeError","./TerrainProvider","./TileAvailability","./TileProviderError"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S){"use strict";function w(e){this.isHeightmap=e.isHeightmap,this.tileUrlTemplates=e.tileUrlTemplates,this.availability=e.availability,this.hasVertexNormals=e.hasVertexNormals,this.hasWaterMask=e.hasWaterMask,this.littleEndianExtensionSize=e.littleEndianExtensionSize}function T(r){function i(r){var n;if(!r.format)return n="The tile format is not specified in the layer.json file.",void(v=S.handleError(v,y,y._errorEvent,n,void 0,void 0,void 0,h));if(!r.tiles||0===r.tiles.length)return n="The layer.json file does not specify any tile URL templates.",void(v=S.handleError(v,y,y._errorEvent,n,void 0,void 0,void 0,h));var o=!1,l=!1,u=!0,c=!1;if("heightmap-1.0"===r.format)c=!0,a(y._heightmapStructure)||(y._heightmapStructure={heightScale:.2,heightOffset:-1e3,elementsPerHeight:1,stride:1,elementMultiplier:256,isBigEndian:!1,lowestEncodedHeight:0,highestEncodedHeight:65535}),l=!0,y._requestWaterMask=!0;else if(0!==r.format.indexOf("quantized-mesh-1."))return n='The tile format "'+r.format+'" is invalid or not supported.',void(v=S.handleError(v,y,y._errorEvent,n,void 0,void 0,void 0,h));for(var d=r.tiles,f=0;f0&&(A+=" "),A+=r.attribution),T.push(new w({isHeightmap:c,tileUrlTemplates:d,availability:P,hasVertexNormals:o,hasWaterMask:l,littleEndianExtensionSize:u}));var F=r.parentUrl;if(a(F)){if(!a(P))return console.log("A layer.json can't have a parentUrl if it does't have an available array."),t.resolve();g=p(g,F),_=p(g,"layer.json"),a(y._proxy)&&(_=y._proxy.getURL(_));var B=m(_);return t(B,i,s)}return t.resolve()}function s(e){var t="An error occurred while accessing "+_+".";v=S.handleError(v,y,y._errorEvent,t,void 0,void 0,void 0,h)}function l(e){i(e).then(function(){if(!a(v)){var e=E.length;if(e>0)for(var t=y._availability=new b(y._tilingScheme,e),r=0;r0&&(y._credit=new n({text:A})),y._ready=!0,y._readyPromise.resolve(!0)}})}function d(e){if(a(e)&&404===e.statusCode)return void l({tilejson:"2.1.0",format:"heightmap-1.0",version:"1.0.0",scheme:"tms",tiles:["{z}/{x}/{y}.terrain?v={version}"]});s(e)}function h(){var e=m(_);t(e,l,d)}this._url=r.url,this._proxy=r.proxy,this._tilingScheme=new c({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:1,ellipsoid:r.ellipsoid}),this._heightmapWidth=65,this._levelZeroMaximumGeometricError=C.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid,this._heightmapWidth,this._tilingScheme.getNumberOfXTilesAtLevel(0)),this._heightmapStructure=void 0,this._hasWaterMask=!1,this._hasVertexNormals=!1,this._requestVertexNormals=o(r.requestVertexNormals,!1),this._requestWaterMask=o(r.requestWaterMask,!1),this._errorEvent=new u;var f=r.credit;"string"==typeof f&&(f=new n({text:f})),this._credit=f,this._availability=void 0,this._ready=!1,this._readyPromise=t.defer();var g=this._url,_=p(this._url,"layer.json");a(this._proxy)&&(_=this._proxy.getURL(_));var v,y=this,T=this._layers=[],A="",E=[];h()}function A(e){return a(e)&&0!==e.length?{Accept:"application/vnd.quantized-mesh;extensions="+e.join("-")+",application/octet-stream;q=0.9,*/*;q=0.01"}:{Accept:"application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01"}}function E(e,t,r,i,n,o){var a=new Uint16Array(t,0,e._heightmapWidth*e._heightmapWidth);return new d({buffer:a,childTileMask:new Uint8Array(t,a.byteLength,1)[0],waterMask:new Uint8Array(t,a.byteLength+1,t.byteLength-a.byteLength-1),width:e._heightmapWidth,height:e._heightmapWidth,structure:e._heightmapStructure})}function x(e,t,n,o,a,s,l){function u(e){return e>>1^-(1&e)}var c=0,d=3*Float64Array.BYTES_PER_ELEMENT,p=4*Float64Array.BYTES_PER_ELEMENT,f=3*Uint16Array.BYTES_PER_ELEMENT,m=Uint16Array.BYTES_PER_ELEMENT,y=3*m,C=new DataView(t),b=new i(C.getFloat64(c,!0),C.getFloat64(c+8,!0),C.getFloat64(c+16,!0));c+=d;var S=C.getFloat32(c,!0);c+=Float32Array.BYTES_PER_ELEMENT;var w=C.getFloat32(c,!0);c+=Float32Array.BYTES_PER_ELEMENT;var T=new r(new i(C.getFloat64(c,!0),C.getFloat64(c+8,!0),C.getFloat64(c+16,!0)),C.getFloat64(c+d,!0));c+=p;var A=new i(C.getFloat64(c,!0),C.getFloat64(c+8,!0),C.getFloat64(c+16,!0));c+=d;var E=C.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var x=new Uint16Array(t,c,3*E);c+=E*f,E>65536&&(m=Uint32Array.BYTES_PER_ELEMENT,y=3*m);var D,I=x.subarray(0,E),O=x.subarray(E,2*E),M=x.subarray(2*E,3*E),R=0,N=0,L=0;for(D=0;D1;--x){if(E=t.PI_OVER_TWO-(x-1)*A,L=n(-E,l,w,S,_,y,v,C,b,L),k=n(E+Math.PI,l,w,S,_,y,v,C,b,k),i){for(R[N++]=L.x,R[N++]=L.y,R[N++]=L.z,D=2*(x-1)+2,P=1;P=0?(i=65536*Math.floor(e/65536),t.high=i,t.low=e-i):(i=65536*Math.floor(-e/65536),t.high=-i,t.low=e+i),t};var n={high:0,low:0};i.fromCartesian=function(e,t){r(t)||(t=new i);var o=t.high,a=t.low;return i.encode(e.x,n),o.x=n.high,a.x=n.low,i.encode(e.y,n),o.y=n.high,a.y=n.low,i.encode(e.z,n),o.z=n.high,a.z=n.low,t};var o=new i;return i.writeElements=function(e,t,r){i.fromCartesian(e,o);var n=o.high,a=o.low;t[r]=n.x,t[r+1]=n.y,t[r+2]=n.z,t[r+3]=a.x,t[r+4]=a.y,t[r+5]=a.z},i}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var i={};return i.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var i=r.indices,n=r.maximumIndex,o=e(r.cacheSize,24),a=i.length;if(!t(n)){n=0;for(var s=0,l=i[s];sn&&(n=l),++s,l=i[s]}for(var u=[],c=0;co&&(u[i[h]]=d,++d);return(d-o+1)/(a/3)},i.tipsify=function(r){function i(e,t,r,i){for(;t.length>=1;){var o=t[t.length-1];if(t.splice(t.length-1,1),e[o].numLiveTriangles>0)return o}for(;n0)return++n-1;++n}return-1}r=e(r,e.EMPTY_OBJECT);var n,o=r.indices,a=r.maximumIndex,s=e(r.cacheSize,24),l=o.length,u=0,c=0,d=o[c],h=l;if(t(a))u=a+1;else{for(;cu&&(u=d),++c,d=o[c];if(-1===u)return 0;++u}var p,f=[];for(p=0;ps&&(v.timeStamp=_,++_),++c}g=function(e,t,r,n,o,a,s){for(var l,u=-1,c=-1,d=0;dc||-1===c)&&(c=l,u=h)),++d}return-1===u?i(n,a,e,s):u}(o,s,C,f,_,b,u)}return w},i}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T){"use strict";function A(e,t,r,i,n){e[t++]=r,e[t++]=i,e[t++]=i,e[t++]=n,e[t++]=n,e[t]=r}function E(e){for(var t=e.length,r=t/3*6,i=g.createTypedArray(t,r),n=0,o=0;o=3){var r=6*(t-2),i=g.createTypedArray(t,r);A(i,0,e[0],e[1],e[2]);for(var n=6,o=3;o0){for(var t=e.length-1,r=6*(t-1),i=g.createTypedArray(t,r),n=e[0],o=0,a=1;aD&&(D=I)}return new p({attributes:_,indices:v,primitiveType:m,boundingSphere:u(P)?new r(P,D):void 0})}function L(e){if(u(e.indices))return e;for(var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,t),i=0;i3&&(r[3]=0,r[4]=2,r[5]=3);for(var i=6,n=3;no?n>a?y.sign(e.y):y.sign(r.y):o>a?y.sign(t.y):y.sign(r.y);var s=i<0;G(e,s),G(t,s),G(r,s)}function W(e,t,r,i){n.add(e,n.multiplyByScalar(n.subtract(t,e,be),e.y/(e.y-t.y),be),r),n.clone(r,i),G(r,!0),G(i,!1)}function j(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){H(e,t,r);var i=e.y<0,n=t.y<0,o=r.y<0,a=0;a+=i?1:0,a+=n?1:0,a+=o?1:0;var s=Ee.indices;1===a?(s[1]=3,s[2]=4,s[5]=6,s[7]=6,s[8]=5,i?(W(e,t,Se,Te),W(e,r,we,Ae),s[0]=0,s[3]=1,s[4]=2,s[6]=1):n?(W(t,r,Se,Te),W(t,e,we,Ae),s[0]=1,s[3]=2,s[4]=0,s[6]=2):o&&(W(r,e,Se,Te),W(r,t,we,Ae),s[0]=2,s[3]=0,s[4]=1,s[6]=0)):2===a&&(s[2]=4,s[4]=4,s[5]=3,s[7]=5,s[8]=6,i?n?o||(W(r,e,Se,Te),W(r,t,we,Ae),s[0]=0,s[1]=1,s[3]=0,s[6]=2):(W(t,r,Se,Te),W(t,e,we,Ae),s[0]=2,s[1]=0,s[3]=2,s[6]=1):(W(e,t,Se,Te),W(e,r,we,Ae),s[0]=1,s[1]=2,s[3]=1,s[6]=0));var l=Ee.positions;return l[0]=e,l[1]=t,l[2]=r,l.length=3,1!==a&&2!==a||(l[3]=Se,l[4]=we,l[5]=Te,l[6]=Ae,l.length=7),Ee}}function q(e,t){var i=e.attributes;if(0!==i.position.values.length){for(var n in i)if(i.hasOwnProperty(n)&&u(i[n])&&u(i[n].values)){var o=i[n];o.values=s.createTypedArray(o.componentDatatype,o.values)}var a=p.computeNumberOfVertices(e);return e.indices=g.createTypedArray(a,e.indices),t&&(e.boundingSphere=r.fromVertices(i.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var i in t)if(t.hasOwnProperty(i)&&u(t[i])&&u(t[i].values)){var n=t[i];r[i]=new f({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return new p({attributes:r,indices:[],primitiveType:e.primitiveType})}function X(e,t,r){var i=u(e.geometry.boundingSphere);t=q(t,i),r=q(r,i),u(r)&&!u(t)?e.geometry=r:!u(r)&&u(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Q(e,r,o,a,s,l,c,d,h,p,f,m){if(u(l)||u(c)||u(d)||u(h)||u(p)){var g=n.fromArray(s,3*e,xe),_=n.fromArray(s,3*r,Pe),v=n.fromArray(s,3*o,De),y=t(a,g,_,v,Ie);if(u(l)){var C=n.fromArray(l,3*e,xe),b=n.fromArray(l,3*r,Pe),S=n.fromArray(l,3*o,De);n.multiplyByScalar(C,y.x,C),n.multiplyByScalar(b,y.y,b),n.multiplyByScalar(S,y.z,S);var w=n.add(C,b,C);n.add(w,S,w),n.normalize(w,w),n.pack(w,f.normal.values,3*m)}if(u(p)){var T=n.fromArray(p,3*e,xe),A=n.fromArray(p,3*r,Pe),E=n.fromArray(p,3*o,De);n.multiplyByScalar(T,y.x,T),n.multiplyByScalar(A,y.y,A),n.multiplyByScalar(E,y.z,E);var x;n.equals(T,n.ZERO)&&n.equals(A,n.ZERO)&&n.equals(E,n.ZERO)?(x=xe,x.x=0,x.y=0,x.z=0):(x=n.add(T,A,T),n.add(x,E,x),n.normalize(x,x)),n.pack(x,f.extrudeDirection.values,3*m)}if(u(c)){var P=n.fromArray(c,3*e,xe),D=n.fromArray(c,3*r,Pe),I=n.fromArray(c,3*o,De);n.multiplyByScalar(P,y.x,P),n.multiplyByScalar(D,y.y,D),n.multiplyByScalar(I,y.z,I);var O=n.add(P,D,P);n.add(O,I,O),n.normalize(O,O),n.pack(O,f.tangent.values,3*m)}if(u(d)){var M=n.fromArray(d,3*e,xe),R=n.fromArray(d,3*r,Pe),N=n.fromArray(d,3*o,De);n.multiplyByScalar(M,y.x,M),n.multiplyByScalar(R,y.y,R),n.multiplyByScalar(N,y.z,N);var L=n.add(M,R,M);n.add(L,N,L),n.normalize(L,L),n.pack(L,f.bitangent.values,3*m)}if(u(h)){var k=i.fromArray(h,2*e,Oe),F=i.fromArray(h,2*r,Me),B=i.fromArray(h,2*o,Re);i.multiplyByScalar(k,y.x,k),i.multiplyByScalar(F,y.y,F),i.multiplyByScalar(B,y.z,B);var U=i.add(k,F,k);i.add(U,B,U),i.pack(U,f.st.values,2*m)}}}function Z(e,t,r,i,n,o){var a=e.position.values.length/3;if(-1!==n){var s=i[n],l=r[s];return-1===l?(r[s]=a,e.position.values.push(o.x,o.y,o.z),t.push(a),a):(t.push(l),l)}return e.position.values.push(o.x,o.y,o.z),t.push(a),a}function K(e){var t,r,i,o,a,s=e.geometry,l=s.attributes,c=l.position.values,d=u(l.normal)?l.normal.values:void 0,h=u(l.bitangent)?l.bitangent.values:void 0,p=u(l.tangent)?l.tangent.values:void 0,f=u(l.st)?l.st.values:void 0,m=u(l.extrudeDirection)?l.extrudeDirection.values:void 0,g=s.indices,_=Y(s),v=Y(s),y=[];y.length=c.length/3;var C=[];for(C.length=c.length/3,a=0;a3)for(var D=P.positions,I=P.indices,O=I.length,M=0;M0)){var u=n.unpack(i,s,Ve);(l.y<0&&u.y>0||l.y>0&&u.y<0)&&(s-3>0?(i[s]=r[s-3],i[s+1]=r[s-2],i[s+2]=r[s-1]):n.pack(l,i,s));var c=n.unpack(o,s,ze);(l.y<0&&c.y>0||l.y>0&&c.y<0)&&(s+3n&&(n=r[o]);e.indices=T.tipsify({indices:r,maximumIndex:n,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=p.computeNumberOfVertices(e);if(u(e.indices)&&r>=y.SIXTY_FOUR_KILOBYTES){var i,n=[],o=[],a=0,s=D(e.attributes),l=e.indices,c=l.length -;e.primitiveType===w.TRIANGLES?i=3:e.primitiveType===w.LINES?i=2:e.primitiveType===w.POINTS&&(i=1);for(var d=0;d=y.SIXTY_FOUR_KILOBYTES&&(t.push(new p({attributes:s,indices:o,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),n=[],o=[],a=0,s=D(e.attributes))}0!==o.length&&t.push(new p({attributes:s,indices:o,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new n,ie=new a;te.projectTo2D=function(e,t,r,i,o){var a=e.attributes[t];o=u(o)?o:new h;for(var l=o.ellipsoid,c=a.values,d=new Float64Array(c.length),p=0,m=0;m0&&a.push(N(t,"geometry")),r.length>0&&(a.push(N(r,"westHemisphereGeometry")),a.push(N(r,"eastHemisphereGeometry"))),a};var ue=new n,ce=new n,de=new n,he=new n;te.computeNormal=function(e){var t,r=e.indices,i=e.attributes,o=i.position.values,a=i.position.values.length/3,l=r.length,u=new Array(a),c=new Array(l/3),d=new Array(l);for(t=0;t0){for(h=0;h0||r.intersectPlane(i,S.ORIGIN_ZX_PLANE)!==_.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:K(e);break;case m.LINES:J(e)}else z(t),t.primitiveType===w.TRIANGLES?K(e):t.primitiveType===w.LINES&&J(e);return e},te}),define("Core/EllipseGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./Matrix4","./PrimitiveType","./Quaternion","./Rectangle","./Transforms","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A){"use strict";function E(e,i,o){var a=i.vertexFormat,s=i.center,l=i.semiMajorAxis,c=i.semiMinorAxis,h=i.ellipsoid,m=i.stRotation,g=o?e.length/3*2:e.length/3,_=i.shadowVolume,v=a.st?new Float32Array(2*g):void 0,C=a.normal?new Float32Array(3*g):void 0,b=a.tangent?new Float32Array(3*g):void 0,w=a.bitangent?new Float32Array(3*g):void 0,T=_?new Float32Array(3*g):void 0,A=0,E=z,x=G,P=H,D=new d(h),I=D.project(h.cartesianToCartographic(s,W),j),O=h.scaleToGeodeticSurface(s,N);h.geodeticSurfaceNormal(O,O);for(var M=S.fromAxisAngle(O,m,V),R=y.fromQuaternion(M,U),F=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,q),X=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Y),Q=e.length,Z=o?Q:0,K=Z/3*2,J=0;J1;--n){for(a[s++]=t++,a[s++]=t,a[s++]=i,r=2*n,o=0;o1,p=o(e.vertexFormat,A.DEFAULT);this._center=r.clone(t),this._semiMajorAxis=n,this._semiMinorAxis=s,this._ellipsoid=c.clone(i),this._rotation=o(e.rotation,0),this._stRotation=o(e.stRotation,0),this._height=u,this._granularity=l,this._vertexFormat=A.clone(p),this._extrudedHeight=o(d,u),this._extrude=h,this._shadowVolume=o(e.shadowVolume,!1),this._workerName="createEllipseGeometry",this._rectangle=M(this._center,this._ellipsoid,n,s,this._rotation)}var N=new r,L=new r,k=new r,F=new r,B=new t,U=new y,V=new S,z=new r,G=new r,H=new r,W=new i,j=new r,q=new t,Y=new t,X=new r,Q=new e,Z=new e,K=new C,J=new C,$=new y,ee=[new r,new r,new r,new r],te=[new i,new i,new i,new i];R.packedLength=r.packedLength+c.packedLength+A.packedLength+w.packedLength+9,R.pack=function(e,t,i){return i=o(i,0),r.pack(e._center,t,i),i+=r.packedLength,c.pack(e._ellipsoid,t,i),i+=c.packedLength,A.pack(e._vertexFormat,t,i),i+=A.packedLength,w.pack(e._rectangle,t,i),i+=w.packedLength,t[i++]=e._semiMajorAxis,t[i++]=e._semiMinorAxis,t[i++]=e._rotation,t[i++]=e._stRotation,t[i++]=e._height,t[i++]=e._granularity,t[i++]=e._extrudedHeight,t[i++]=e._extrude?1:0,t[i]=e._shadowVolume?1:0,t};var re=new r,ie=new c,ne=new A,oe=new w,ae={center:re,ellipsoid:ie,vertexFormat:ne,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,stRotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,shadowVolume:void 0};return R.unpack=function(e,t,i){t=o(t,0);var n=r.unpack(e,t,re);t+=r.packedLength;var s=c.unpack(e,t,ie);t+=c.packedLength;var l=A.unpack(e,t,ne);t+=A.packedLength;var u=w.unpack(e,t,oe);t+=w.packedLength;var d=e[t++],h=e[t++],p=e[t++],f=e[t++],m=e[t++],g=e[t++],_=e[t++],v=1===e[t++],y=1===e[t];return a(i)?(i._center=r.clone(n,i._center),i._ellipsoid=c.clone(s,i._ellipsoid),i._vertexFormat=A.clone(l,i._vertexFormat),i._semiMajorAxis=d,i._semiMinorAxis=h,i._rotation=p,i._stRotation=f,i._height=m,i._granularity=g,i._extrudedHeight=_,i._extrude=v,i._shadowVolume=y,i._rectangle=w.clone(u),i):(ae.height=m,ae.extrudedHeight=_,ae.granularity=g,ae.stRotation=f,ae.rotation=p,ae.semiMajorAxis=d,ae.semiMinorAxis=h,ae.shadowVolume=y,new R(ae))},R.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,vertexFormat:e._vertexFormat,stRotation:e._stRotation};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),r.shadowVolume=e._shadowVolume,t=O(r)):t=P(r),new h({attributes:t.attributes,indices:t.indices,primitiveType:b.TRIANGLES,boundingSphere:t.boundingSphere})}},R.createShadowVolume=function(e,t,r){var i=e._granularity,n=e._ellipsoid,o=t(i,n),a=r(i,n);return new R({center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:n,rotation:e._rotation,stRotation:e._stRotation,granularity:i,extrudedHeight:o,height:a,vertexFormat:A.POSITION_ONLY,shadowVolume:!0})},s(R.prototype,{rectangle:{get:function(){return this._rectangle}}}),R}),define("Core/CircleGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./EllipseGeometry","./Ellipsoid","./VertexFormat"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT);var t=e.radius,i={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,vertexFormat:e.vertexFormat,stRotation:e.stRotation,shadowVolume:e.shadowVolume};this._ellipseGeometry=new o(i),this._workerName="createCircleGeometry"}l.packedLength=o.packedLength,l.pack=function(e,t,r){return o.pack(e._ellipseGeometry,t,r)};var u=new o({center:new e,semiMajorAxis:1,semiMinorAxis:1}),c={center:new e,radius:void 0,ellipsoid:a.clone(a.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,vertexFormat:new s,stRotation:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0,shadowVolume:void 0};return l.unpack=function(t,r,n){var d=o.unpack(t,r,u);return c.center=e.clone(d._center,c.center),c.ellipsoid=a.clone(d._ellipsoid,c.ellipsoid),c.height=d._height,c.extrudedHeight=d._extrudedHeight,c.granularity=d._granularity,c.vertexFormat=s.clone(d._vertexFormat,c.vertexFormat),c.stRotation=d._stRotation,c.shadowVolume=d._shadowVolume,i(n)?(c.semiMajorAxis=d._semiMajorAxis,c.semiMinorAxis=d._semiMinorAxis,n._ellipseGeometry=new o(c),n):(c.radius=d._semiMajorAxis,new l(c))},l.createGeometry=function(e){return o.createGeometry(e._ellipseGeometry)},l.createShadowVolume=function(e,t,r){var i=e._ellipseGeometry._granularity,n=e._ellipseGeometry._ellipsoid,o=t(i,n),a=r(i,n);return new l({center:e._ellipseGeometry._center,radius:e._ellipseGeometry._semiMajorAxis,ellipsoid:n,stRotation:e._ellipseGeometry._stRotation,granularity:i,extrudedHeight:o,height:a,vertexFormat:s.POSITION_ONLY,shadowVolume:!0})},n(l.prototype,{rectangle:{get:function(){return this._ellipseGeometry.rectangle}}}),l}),define("Core/EllipseOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(i){var n=i.center;v=t.multiplyByScalar(i.ellipsoid.geodeticSurfaceNormal(n,v),i.height,v),v=t.add(n,v,v);for(var o=new e(v,i.semiMajorAxis),s=a.computeEllipsePositions(i,!1,!0).outerPositions,l=new c({position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:a.raisePositionsToHeight(s,i,!1)})}),h=s.length/3,p=d.createTypedArray(h,2*h),f=0,m=0;m0){var E=Math.min(b,v);A=Math.round(v/E);var x=Math.min(A*b,v);for(w=0;w1;this._center=t.clone(r),this._semiMajorAxis=a,this._semiMinorAxis=l,this._ellipsoid=s.clone(o),this._rotation=i(e.rotation,0),this._height=c,this._granularity=u,this._extrudedHeight=d,this._extrude=p,this._numberOfVerticalLines=Math.max(i(e.numberOfVerticalLines,16),0),this._workerName="createEllipseOutlineGeometry"}var _=new t,v=new t,y=new e,C=new e;g.packedLength=t.packedLength+s.packedLength+9,g.pack=function(e,r,o){return o=i(o,0),t.pack(e._center,r,o),o+=t.packedLength,s.pack(e._ellipsoid,r,o),o+=s.packedLength,r[o++]=e._semiMajorAxis,r[o++]=e._semiMinorAxis,r[o++]=e._rotation,r[o++]=e._height,r[o++]=e._granularity,r[o++]=n(e._extrudedHeight)?1:0,r[o++]=i(e._extrudedHeight,0),r[o++]=e._extrude?1:0,r[o]=e._numberOfVerticalLines,r};var b=new t,S=new s,w={center:b,ellipsoid:S,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,numberOfVerticalLines:void 0};return g.unpack=function(e,r,o){r=i(r,0);var a=t.unpack(e,r,b);r+=t.packedLength;var l=s.unpack(e,r,S);r+=s.packedLength;var u=e[r++],c=e[r++],d=e[r++],h=e[r++],p=e[r++],f=e[r++],m=e[r++],_=1===e[r++],v=e[r];return n(o)?(o._center=t.clone(a,o._center),o._ellipsoid=s.clone(l,o._ellipsoid),o._semiMajorAxis=u,o._semiMinorAxis=c,o._rotation=d,o._height=h,o._granularity=p,o._extrudedHeight=f?m:void 0,o._extrude=_,o._numberOfVerticalLines=v,o):(w.height=h,w.extrudedHeight=f?m:void 0,w.granularity=p,w.rotation=d,w.semiMajorAxis=u,w.semiMinorAxis=c,w.numberOfVerticalLines=v,new g(w))},g.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,numberOfVerticalLines:e._numberOfVerticalLines};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),t=m(r)):t=f(r),new l({attributes:t.attributes,indices:t.indices,primitiveType:p.LINES,boundingSphere:t.boundingSphere})}},g}),define("Core/CircleOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipseOutlineGeometry","./Ellipsoid"],function(e,t,r,i,n,o){"use strict";function a(e){e=r(e,r.EMPTY_OBJECT);var t=e.radius,i={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,numberOfVerticalLines:e.numberOfVerticalLines};this._ellipseGeometry=new n(i),this._workerName="createCircleOutlineGeometry"}a.packedLength=n.packedLength,a.pack=function(e,t,r){return n.pack(e._ellipseGeometry,t,r)};var s=new n({center:new e,semiMajorAxis:1,semiMinorAxis:1}),l={center:new e,radius:void 0,ellipsoid:o.clone(o.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,numberOfVerticalLines:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0};return a.unpack=function(t,r,u){var c=n.unpack(t,r,s);return l.center=e.clone(c._center,l.center),l.ellipsoid=o.clone(c._ellipsoid,l.ellipsoid),l.height=c._height,l.extrudedHeight=c._extrudedHeight,l.granularity=c._granularity,l.numberOfVerticalLines=c._numberOfVerticalLines,i(u)?(l.semiMajorAxis=c._semiMajorAxis,l.semiMinorAxis=c._semiMinorAxis,u._ellipseGeometry=new n(l),u):(l.radius=c._semiMajorAxis,new a(l))},a.createGeometry=function(e){return n.createGeometry(e._ellipseGeometry)},a}),define("Core/Color",["./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,t,r){return r<0&&(r+=1),r>1&&(r-=1),6*r<1?e+6*(t-e)*r:2*r<1?t:3*r<2?e+(t-e)*(2/3-r)*6:e}function s(e,r,i,n){this.red=t(e,1),this.green=t(r,1),this.blue=t(i,1),this.alpha=t(n,1)}s.fromCartesian4=function(e,t){return r(t)?(t.red=e.x,t.green=e.y,t.blue=e.z,t.alpha=e.w,t):new s(e.x,e.y,e.z,e.w)},s.fromBytes=function(e,i,n,o,a){return e=s.byteToFloat(t(e,255)),i=s.byteToFloat(t(i,255)),n=s.byteToFloat(t(n,255)),o=s.byteToFloat(t(o,255)),r(a)?(a.red=e,a.green=i,a.blue=n,a.alpha=o,a):new s(e,i,n,o)},s.fromAlpha=function(e,t,i){return r(i)?(i.red=e.red,i.green=e.green,i.blue=e.blue,i.alpha=t,i):new s(e.red,e.green,e.blue,t)};var l,u,c;i.supportsTypedArrays()&&(l=new ArrayBuffer(4),u=new Uint32Array(l),c=new Uint8Array(l)),s.fromRgba=function(e,t){return u[0]=e,s.fromBytes(c[0],c[1],c[2],c[3],t)},s.fromHsl=function(e,i,n,o,l){e=t(e,0)%1,i=t(i,0),n=t(n,0),o=t(o,1);var u=n,c=n,d=n;if(0!==i){var h;h=n<.5?n*(1+i):n+i-n*i;var p=2*n-h;u=a(p,h,e+1/3),c=a(p,h,e),d=a(p,h,e-1/3)}return r(l)?(l.red=u,l.green=c,l.blue=d,l.alpha=o,l):new s(u,c,d,o)},s.fromRandom=function(e,i){e=t(e,t.EMPTY_OBJECT);var n=e.red;if(!r(n)){var a=t(e.minimumRed,0),l=t(e.maximumRed,1);n=a+o.nextRandomNumber()*(l-a)}var u=e.green;if(!r(u)){var c=t(e.minimumGreen,0),d=t(e.maximumGreen,1);u=c+o.nextRandomNumber()*(d-c)}var h=e.blue;if(!r(h)){var p=t(e.minimumBlue,0),f=t(e.maximumBlue,1);h=p+o.nextRandomNumber()*(f-p)}var m=e.alpha;if(!r(m)){var g=t(e.minimumAlpha,0),_=t(e.maximumAlpha,1);m=g+o.nextRandomNumber()*(_-g)}return r(i)?(i.red=n,i.green=u,i.blue=h,i.alpha=m,i):new s(n,u,h,m)};var d=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,h=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,p=/^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i,f=/^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i;return s.fromCssColorString=function(e,i){r(i)||(i=new s);var n=s[e.toUpperCase()];if(r(n))return s.clone(n,i),i;var o=d.exec(e);return null!==o?(i.red=parseInt(o[1],16)/15,i.green=parseInt(o[2],16)/15,i.blue=parseInt(o[3],16)/15,i.alpha=1,i):null!==(o=h.exec(e))?(i.red=parseInt(o[1],16)/255,i.green=parseInt(o[2],16)/255,i.blue=parseInt(o[3],16)/255,i.alpha=1,i):null!==(o=p.exec(e))?(i.red=parseFloat(o[1])/("%"===o[1].substr(-1)?100:255),i.green=parseFloat(o[2])/("%"===o[2].substr(-1)?100:255),i.blue=parseFloat(o[3])/("%"===o[3].substr(-1)?100:255),i.alpha=parseFloat(t(o[4],"1.0")),i):null!==(o=f.exec(e))?s.fromHsl(parseFloat(o[1])/360,parseFloat(o[2])/100,parseFloat(o[3])/100,parseFloat(t(o[4],"1.0")),i):i=void 0},s.packedLength=4,s.pack=function(e,r,i){return i=t(i,0),r[i++]=e.red,r[i++]=e.green,r[i++]=e.blue,r[i]=e.alpha,r},s.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new s),n.red=e[i++],n.green=e[i++],n.blue=e[i++],n.alpha=e[i],n},s.byteToFloat=function(e){return e/255},s.floatToByte=function(e){return 1===e?255:256*e|0},s.clone=function(e,t){if(r(e))return r(t)?(t.red=e.red,t.green=e.green,t.blue=e.blue,t.alpha=e.alpha,t):new s(e.red,e.green,e.blue,e.alpha)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.red===t.red&&e.green===t.green&&e.blue===t.blue&&e.alpha===t.alpha},s.equalsArray=function(e,t,r){return e.red===t[r]&&e.green===t[r+1]&&e.blue===t[r+2]&&e.alpha===t[r+3]},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return this===e||r(e)&&Math.abs(this.red-e.red)<=t&&Math.abs(this.green-e.green)<=t&&Math.abs(this.blue-e.blue)<=t&&Math.abs(this.alpha-e.alpha)<=t},s.prototype.toString=function(){return"("+this.red+", "+this.green+", "+this.blue+", "+this.alpha+")"},s.prototype.toCssColorString=function(){var e=s.floatToByte(this.red),t=s.floatToByte(this.green),r=s.floatToByte(this.blue);return 1===this.alpha?"rgb("+e+","+t+","+r+")":"rgba("+e+","+t+","+r+","+this.alpha+")"},s.prototype.toBytes=function(e){var t=s.floatToByte(this.red),i=s.floatToByte(this.green),n=s.floatToByte(this.blue),o=s.floatToByte(this.alpha);return r(e)?(e[0]=t,e[1]=i,e[2]=n,e[3]=o,e):[t,i,n,o]},s.prototype.toRgba=function(){return c[0]=s.floatToByte(this.red),c[1]=s.floatToByte(this.green),c[2]=s.floatToByte(this.blue),c[3]=s.floatToByte(this.alpha),u[0]},s.prototype.brighten=function(e,t){return e=1-e,t.red=1-(1-this.red)*e,t.green=1-(1-this.green)*e,t.blue=1-(1-this.blue)*e,t.alpha=this.alpha,t},s.prototype.darken=function(e,t){return e=1-e,t.red=this.red*e,t.green=this.green*e,t.blue=this.blue*e,t.alpha=this.alpha,t},s.prototype.withAlpha=function(e,t){return s.fromAlpha(this,e,t)},s.add=function(e,t,r){return r.red=e.red+t.red,r.green=e.green+t.green,r.blue=e.blue+t.blue,r.alpha=e.alpha+t.alpha,r},s.subtract=function(e,t,r){return r.red=e.red-t.red,r.green=e.green-t.green,r.blue=e.blue-t.blue,r.alpha=e.alpha-t.alpha,r},s.multiply=function(e,t,r){return r.red=e.red*t.red,r.green=e.green*t.green,r.blue=e.blue*t.blue,r.alpha=e.alpha*t.alpha,r},s.divide=function(e,t,r){return r.red=e.red/t.red,r.green=e.green/t.green,r.blue=e.blue/t.blue,r.alpha=e.alpha/t.alpha,r},s.mod=function(e,t,r){return r.red=e.red%t.red,r.green=e.green%t.green,r.blue=e.blue%t.blue,r.alpha=e.alpha%t.alpha,r},s.multiplyByScalar=function(e,t,r){return r.red=e.red*t,r.green=e.green*t,r.blue=e.blue*t,r.alpha=e.alpha*t,r},s.divideByScalar=function(e,t,r){return r.red=e.red/t,r.green=e.green/t,r.blue=e.blue/t,r.alpha=e.alpha/t,r},s.ALICEBLUE=n(s.fromCssColorString("#F0F8FF")),s.ANTIQUEWHITE=n(s.fromCssColorString("#FAEBD7")),s.AQUA=n(s.fromCssColorString("#00FFFF")),s.AQUAMARINE=n(s.fromCssColorString("#7FFFD4")),s.AZURE=n(s.fromCssColorString("#F0FFFF")),s.BEIGE=n(s.fromCssColorString("#F5F5DC")),s.BISQUE=n(s.fromCssColorString("#FFE4C4")),s.BLACK=n(s.fromCssColorString("#000000")),s.BLANCHEDALMOND=n(s.fromCssColorString("#FFEBCD")),s.BLUE=n(s.fromCssColorString("#0000FF")),s.BLUEVIOLET=n(s.fromCssColorString("#8A2BE2")),s.BROWN=n(s.fromCssColorString("#A52A2A")),s.BURLYWOOD=n(s.fromCssColorString("#DEB887")),s.CADETBLUE=n(s.fromCssColorString("#5F9EA0")),s.CHARTREUSE=n(s.fromCssColorString("#7FFF00")),s.CHOCOLATE=n(s.fromCssColorString("#D2691E")),s.CORAL=n(s.fromCssColorString("#FF7F50")),s.CORNFLOWERBLUE=n(s.fromCssColorString("#6495ED")),s.CORNSILK=n(s.fromCssColorString("#FFF8DC")),s.CRIMSON=n(s.fromCssColorString("#DC143C")),s.CYAN=n(s.fromCssColorString("#00FFFF")),s.DARKBLUE=n(s.fromCssColorString("#00008B")),s.DARKCYAN=n(s.fromCssColorString("#008B8B")),s.DARKGOLDENROD=n(s.fromCssColorString("#B8860B")),s.DARKGRAY=n(s.fromCssColorString("#A9A9A9")),s.DARKGREEN=n(s.fromCssColorString("#006400")),s.DARKGREY=s.DARKGRAY, -s.DARKKHAKI=n(s.fromCssColorString("#BDB76B")),s.DARKMAGENTA=n(s.fromCssColorString("#8B008B")),s.DARKOLIVEGREEN=n(s.fromCssColorString("#556B2F")),s.DARKORANGE=n(s.fromCssColorString("#FF8C00")),s.DARKORCHID=n(s.fromCssColorString("#9932CC")),s.DARKRED=n(s.fromCssColorString("#8B0000")),s.DARKSALMON=n(s.fromCssColorString("#E9967A")),s.DARKSEAGREEN=n(s.fromCssColorString("#8FBC8F")),s.DARKSLATEBLUE=n(s.fromCssColorString("#483D8B")),s.DARKSLATEGRAY=n(s.fromCssColorString("#2F4F4F")),s.DARKSLATEGREY=s.DARKSLATEGRAY,s.DARKTURQUOISE=n(s.fromCssColorString("#00CED1")),s.DARKVIOLET=n(s.fromCssColorString("#9400D3")),s.DEEPPINK=n(s.fromCssColorString("#FF1493")),s.DEEPSKYBLUE=n(s.fromCssColorString("#00BFFF")),s.DIMGRAY=n(s.fromCssColorString("#696969")),s.DIMGREY=s.DIMGRAY,s.DODGERBLUE=n(s.fromCssColorString("#1E90FF")),s.FIREBRICK=n(s.fromCssColorString("#B22222")),s.FLORALWHITE=n(s.fromCssColorString("#FFFAF0")),s.FORESTGREEN=n(s.fromCssColorString("#228B22")),s.FUCHSIA=n(s.fromCssColorString("#FF00FF")),s.GAINSBORO=n(s.fromCssColorString("#DCDCDC")),s.GHOSTWHITE=n(s.fromCssColorString("#F8F8FF")),s.GOLD=n(s.fromCssColorString("#FFD700")),s.GOLDENROD=n(s.fromCssColorString("#DAA520")),s.GRAY=n(s.fromCssColorString("#808080")),s.GREEN=n(s.fromCssColorString("#008000")),s.GREENYELLOW=n(s.fromCssColorString("#ADFF2F")),s.GREY=s.GRAY,s.HONEYDEW=n(s.fromCssColorString("#F0FFF0")),s.HOTPINK=n(s.fromCssColorString("#FF69B4")),s.INDIANRED=n(s.fromCssColorString("#CD5C5C")),s.INDIGO=n(s.fromCssColorString("#4B0082")),s.IVORY=n(s.fromCssColorString("#FFFFF0")),s.KHAKI=n(s.fromCssColorString("#F0E68C")),s.LAVENDER=n(s.fromCssColorString("#E6E6FA")),s.LAVENDAR_BLUSH=n(s.fromCssColorString("#FFF0F5")),s.LAWNGREEN=n(s.fromCssColorString("#7CFC00")),s.LEMONCHIFFON=n(s.fromCssColorString("#FFFACD")),s.LIGHTBLUE=n(s.fromCssColorString("#ADD8E6")),s.LIGHTCORAL=n(s.fromCssColorString("#F08080")),s.LIGHTCYAN=n(s.fromCssColorString("#E0FFFF")),s.LIGHTGOLDENRODYELLOW=n(s.fromCssColorString("#FAFAD2")),s.LIGHTGRAY=n(s.fromCssColorString("#D3D3D3")),s.LIGHTGREEN=n(s.fromCssColorString("#90EE90")),s.LIGHTGREY=s.LIGHTGRAY,s.LIGHTPINK=n(s.fromCssColorString("#FFB6C1")),s.LIGHTSEAGREEN=n(s.fromCssColorString("#20B2AA")),s.LIGHTSKYBLUE=n(s.fromCssColorString("#87CEFA")),s.LIGHTSLATEGRAY=n(s.fromCssColorString("#778899")),s.LIGHTSLATEGREY=s.LIGHTSLATEGRAY,s.LIGHTSTEELBLUE=n(s.fromCssColorString("#B0C4DE")),s.LIGHTYELLOW=n(s.fromCssColorString("#FFFFE0")),s.LIME=n(s.fromCssColorString("#00FF00")),s.LIMEGREEN=n(s.fromCssColorString("#32CD32")),s.LINEN=n(s.fromCssColorString("#FAF0E6")),s.MAGENTA=n(s.fromCssColorString("#FF00FF")),s.MAROON=n(s.fromCssColorString("#800000")),s.MEDIUMAQUAMARINE=n(s.fromCssColorString("#66CDAA")),s.MEDIUMBLUE=n(s.fromCssColorString("#0000CD")),s.MEDIUMORCHID=n(s.fromCssColorString("#BA55D3")),s.MEDIUMPURPLE=n(s.fromCssColorString("#9370DB")),s.MEDIUMSEAGREEN=n(s.fromCssColorString("#3CB371")),s.MEDIUMSLATEBLUE=n(s.fromCssColorString("#7B68EE")),s.MEDIUMSPRINGGREEN=n(s.fromCssColorString("#00FA9A")),s.MEDIUMTURQUOISE=n(s.fromCssColorString("#48D1CC")),s.MEDIUMVIOLETRED=n(s.fromCssColorString("#C71585")),s.MIDNIGHTBLUE=n(s.fromCssColorString("#191970")),s.MINTCREAM=n(s.fromCssColorString("#F5FFFA")),s.MISTYROSE=n(s.fromCssColorString("#FFE4E1")),s.MOCCASIN=n(s.fromCssColorString("#FFE4B5")),s.NAVAJOWHITE=n(s.fromCssColorString("#FFDEAD")),s.NAVY=n(s.fromCssColorString("#000080")),s.OLDLACE=n(s.fromCssColorString("#FDF5E6")),s.OLIVE=n(s.fromCssColorString("#808000")),s.OLIVEDRAB=n(s.fromCssColorString("#6B8E23")),s.ORANGE=n(s.fromCssColorString("#FFA500")),s.ORANGERED=n(s.fromCssColorString("#FF4500")),s.ORCHID=n(s.fromCssColorString("#DA70D6")),s.PALEGOLDENROD=n(s.fromCssColorString("#EEE8AA")),s.PALEGREEN=n(s.fromCssColorString("#98FB98")),s.PALETURQUOISE=n(s.fromCssColorString("#AFEEEE")),s.PALEVIOLETRED=n(s.fromCssColorString("#DB7093")),s.PAPAYAWHIP=n(s.fromCssColorString("#FFEFD5")),s.PEACHPUFF=n(s.fromCssColorString("#FFDAB9")),s.PERU=n(s.fromCssColorString("#CD853F")),s.PINK=n(s.fromCssColorString("#FFC0CB")),s.PLUM=n(s.fromCssColorString("#DDA0DD")),s.POWDERBLUE=n(s.fromCssColorString("#B0E0E6")),s.PURPLE=n(s.fromCssColorString("#800080")),s.RED=n(s.fromCssColorString("#FF0000")),s.ROSYBROWN=n(s.fromCssColorString("#BC8F8F")),s.ROYALBLUE=n(s.fromCssColorString("#4169E1")),s.SADDLEBROWN=n(s.fromCssColorString("#8B4513")),s.SALMON=n(s.fromCssColorString("#FA8072")),s.SANDYBROWN=n(s.fromCssColorString("#F4A460")),s.SEAGREEN=n(s.fromCssColorString("#2E8B57")),s.SEASHELL=n(s.fromCssColorString("#FFF5EE")),s.SIENNA=n(s.fromCssColorString("#A0522D")),s.SILVER=n(s.fromCssColorString("#C0C0C0")),s.SKYBLUE=n(s.fromCssColorString("#87CEEB")),s.SLATEBLUE=n(s.fromCssColorString("#6A5ACD")),s.SLATEGRAY=n(s.fromCssColorString("#708090")),s.SLATEGREY=s.SLATEGRAY,s.SNOW=n(s.fromCssColorString("#FFFAFA")),s.SPRINGGREEN=n(s.fromCssColorString("#00FF7F")),s.STEELBLUE=n(s.fromCssColorString("#4682B4")),s.TAN=n(s.fromCssColorString("#D2B48C")),s.TEAL=n(s.fromCssColorString("#008080")),s.THISTLE=n(s.fromCssColorString("#D8BFD8")),s.TOMATO=n(s.fromCssColorString("#FF6347")),s.TURQUOISE=n(s.fromCssColorString("#40E0D0")),s.VIOLET=n(s.fromCssColorString("#EE82EE")),s.WHEAT=n(s.fromCssColorString("#F5DEB3")),s.WHITE=n(s.fromCssColorString("#FFFFFF")),s.WHITESMOKE=n(s.fromCssColorString("#F5F5F5")),s.YELLOW=n(s.fromCssColorString("#FFFF00")),s.YELLOWGREEN=n(s.fromCssColorString("#9ACD32")),s.TRANSPARENT=n(new s(0,0,0,0)),s}),define("Core/ClippingPlaneCollection",["./Cartesian3","./Cartesian4","./Check","./Color","./defaultValue","./defined","./defineProperties","./DeveloperError","./Intersect","./Matrix4","./Plane"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e){e=n(e,n.EMPTY_OBJECT);var t=e.planes;o(t)?this._planes=t.slice(0):this._planes=[],this.enabled=n(e.enabled,!0),this.modelMatrix=u.clone(n(e.modelMatrix,u.IDENTITY)),this.edgeColor=i.clone(n(e.edgeColor,i.WHITE)),this.edgeWidth=n(e.edgeWidth,0),this._testIntersection=void 0,this._unionClippingRegions=void 0,this.unionClippingRegions=n(e.unionClippingRegions,!1)}function h(e){return e===l.OUTSIDE}function p(e){return e===l.INSIDE}function f(e,t){for(var r=e.length,i=0;i0&&(a=l.OUTSIDE);for(var s=0;ss.EPSILON12);var M=h*(t*t-r*r)/(r*r),R=1+M*(4096+M*(M*(320-175*M)-768))/16384,N=M*(256+M*(M*(74-47*M)-128))/1024,L=p*p,k=N*d*(p+N*(u*(2*L-1)-N*p*(4*d*d-3)*(4*L-3)/6)/4),F=r*R*(l-k),B=Math.atan2(C*D,w-A*P),U=Math.atan2(v*D,w*P-A);e._distance=F,e._startHeading=B,e._endHeading=U,e._uSquared=M}function h(r,i,n,o){e.normalize(o.cartographicToCartesian(i,m),f),e.normalize(o.cartographicToCartesian(n,m),m);d(r,o.maximumRadius,o.minimumRadius,i.longitude,i.latitude,n.longitude,n.latitude),r._start=t.clone(i,r._start),r._end=t.clone(n,r._end),r._start.height=0,r._end.height=0,l(r)}function p(e,r,o){var s=i(o,a.WGS84);this._ellipsoid=s,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,n(e)&&n(r)&&h(this,e,r,s)}var f=new e,m=new e;return o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),p.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},p.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},p.prototype.interpolateUsingSurfaceDistance=function(e,r){var i=this._constants,o=i.distanceRatio+e/i.b,a=Math.cos(2*o),s=Math.cos(4*o),l=Math.cos(6*o),u=Math.sin(2*o),d=Math.sin(4*o),h=Math.sin(6*o),p=Math.sin(8*o),f=o*o,m=o*f,g=i.u8Over256,_=i.u2Over4,v=i.u6Over64,y=i.u4Over16,C=2*m*g*a/3+o*(1-_+7*y/4-15*v/4+579*g/64-(y-15*v/4+187*g/16)*a-(5*v/4-115*g/16)*s-29*g*l/16)+(_/2-y+71*v/32-85*g/16)*u+(5*y/16-5*v/4+383*g/96)*d-f*((v-11*g/2)*u+5*g*d/2)+(29*v/96-29*g/16)*h+539*g*p/1536,b=Math.asin(Math.sin(C)*i.cosineAlpha),S=Math.atan(i.a/i.b*Math.tan(b));C-=i.sigma;var w=Math.cos(2*i.sigma+C),T=Math.sin(C),A=Math.cos(C),E=i.cosineU*A,x=i.sineU*T,P=Math.atan2(T*i.sineHeading,E-x*i.cosineHeading),D=P-c(i.f,i.sineAlpha,i.cosineSquaredAlpha,C,T,A,w);return n(r)?(r.longitude=this._start.longitude+D,r.latitude=S,r.height=0,r):new t(this._start.longitude+D,S,0)},p}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e,t,r){var i=T;i.length=e;var n;if(t===r){for(n=0;n0){n=r(n,c.IDENTITY);var l=c.inverseTransformation(n,g),u=c.multiplyByPoint(l,e.ZERO,_),h=e.normalize(c.multiplyByPointAsVector(l,e.UNIT_Y,v),v),p=d.fromPointNormal(u,h,y),f=e.normalize(c.multiplyByPointAsVector(l,e.UNIT_X,C),C),m=d.fromPointNormal(u,f,b),T=1;o.push(e.clone(t[0]));for(var A=o[0],E=t.length,x=1;x=0?-c:c}function m(e,r,i,n,o,a,u,c){var h=z,p=G;F=d.eastNorthUpToFixedFrame(e,o,F),h=l.multiplyByPointAsVector(F,k,h),h=t.normalize(h,h);var m=f(h,r,e,o);U=s.fromRotationZ(m,U),H.z=a,F=l.multiplyTransformation(F,l.fromRotationTranslation(U,H,B),F);var g=V;g[0]=u;for(var _=0;_0)for(var b=f?2:1,S=0;S=0};var X=new t,Q=new t;return M.computePositions=function(e,r,i,o,s){var l=o._ellipsoid,c=h(e,l),d=o._granularity,f=o._cornerType,O=s?_(r,i):v(r,i),R=s?v(r,i):void 0,N=i.height/2,L=i.width/2,k=e.length,F=[],B=s?[]:void 0,U=b,V=S,z=w,G=T,H=A,W=E,j=x,q=P,Y=D,Z=e[0],K=e[1];G=l.geodeticSurfaceNormal(Z,G),U=t.subtract(K,Z,U),U=t.normalize(U,U),q=t.cross(G,U,q),q=t.normalize(q,q);var J=c[0],$=c[1];s&&(B=m(Z,q,R,B,l,J+N,1,1)),Y=t.clone(Z,Y),Z=K,V=t.negate(U,V);for(var ee,te,re=1;re80*n){c=h=e[0],d=p=e[1];for(var _=n;_h&&(h=f),m>p&&(p=m);g=Math.max(h-c,p-d)}return i(s,u,n,c,d,g),u}function t(e,t,r,i,n){var o,a;if(n===P(e,t,r,i)>0)for(o=t;o=t;o-=i)a=A(o,e[o],e[o+1],a);return a&&y(a,a.next)&&(E(a),a=a.next),a}function r(e,t){if(!e)return e;t||(t=e);var r,i=e;do{if(r=!1,i.steiner||!y(i,i.next)&&0!==v(i.prev,i,i.next))i=i.next;else{if(E(i),(i=t=i.prev)===i.next)return null;r=!0}}while(r||i!==t);return t}function i(e,t,l,u,c,d,p){if(e){!p&&d&&h(e,u,c,d);for(var f,m,g=e;e.prev!==e.next;)if(f=e.prev,m=e.next,d?o(e,u,c,d):n(e))t.push(f.i/l),t.push(e.i/l),t.push(m.i/l),E(e),e=m.next,g=m.next;else if((e=m)===g){p?1===p?(e=a(e,t,l),i(e,t,l,u,c,d,2)):2===p&&s(e,t,l,u,c,d):i(r(e),t,l,u,c,d,1);break}}}function n(e){var t=e.prev,r=e,i=e.next;if(v(t,r,i)>=0)return!1;for(var n=e.next.next;n!==e.prev;){if(g(t.x,t.y,r.x,r.y,i.x,i.y,n.x,n.y)&&v(n.prev,n,n.next)>=0)return!1;n=n.next}return!0}function o(e,t,r,i){var n=e.prev,o=e,a=e.next;if(v(n,o,a)>=0)return!1;for(var s=n.xo.x?n.x>a.x?n.x:a.x:o.x>a.x?o.x:a.x,c=n.y>o.y?n.y>a.y?n.y:a.y:o.y>a.y?o.y:a.y,d=f(s,l,t,r,i),h=f(u,c,t,r,i),p=e.nextZ;p&&p.z<=h;){if(p!==e.prev&&p!==e.next&&g(n.x,n.y,o.x,o.y,a.x,a.y,p.x,p.y)&&v(p.prev,p,p.next)>=0)return!1;p=p.nextZ}for(p=e.prevZ;p&&p.z>=d;){if(p!==e.prev&&p!==e.next&&g(n.x,n.y,o.x,o.y,a.x,a.y,p.x,p.y)&&v(p.prev,p,p.next)>=0)return!1;p=p.prevZ}return!0}function a(e,t,r){var i=e;do{var n=i.prev,o=i.next.next;!y(n,o)&&C(n,i,i.next,o)&&S(n,o)&&S(o,n)&&(t.push(n.i/r),t.push(i.i/r),t.push(o.i/r),E(i),E(i.next),i=e=o),i=i.next}while(i!==e);return i}function s(e,t,n,o,a,s){var l=e;do{for(var u=l.next.next;u!==l.prev;){if(l.i!==u.i&&_(l,u)){var c=T(l,u);return l=r(l,l.next),c=r(c,c.next),i(l,t,n,o,a,s),void i(c,t,n,o,a,s)}u=u.next}l=l.next}while(l!==e)}function l(e,i,n,o){var a,s,l,d,h,p=[];for(a=0,s=i.length;a=i.next.y){var s=i.x+(o-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(s<=n&&s>a){if(a=s,s===n){if(o===i.y)return i;if(o===i.next.y)return i.next}r=i.x=i.x&&i.x>=c&&g(or.x)&&S(i,e)&&(r=i,h=l),i=i.next;return r}function h(e,t,r,i){var n=e;do{null===n.z&&(n.z=f(n.x,n.y,t,r,i)),n.prevZ=n.prev,n.nextZ=n.next,n=n.next}while(n!==e);n.prevZ.nextZ=null,n.prevZ=null,p(n)}function p(e){var t,r,i,n,o,a,s,l,u=1;do{for(r=e,e=null,o=null,a=0;r;){for(a++,i=r,s=0,t=0;t0||l>0&&i;)0===s?(n=i,i=i.nextZ,l--):0!==l&&i?r.z<=i.z?(n=r,r=r.nextZ,s--):(n=i,i=i.nextZ,l--):(n=r,r=r.nextZ,s--),o?o.nextZ=n:e=n,n.prevZ=o,o=n;r=i}o.nextZ=null,u*=2}while(a>1);return e}function f(e,t,r,i,n){return e=32767*(e-r)/n,t=32767*(t-i)/n,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,r=e;do{t.x=0&&(e-a)*(i-s)-(r-a)*(t-s)>=0&&(r-a)*(o-s)-(n-a)*(i-s)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!b(e,t)&&S(e,t)&&S(t,e)&&w(e,t)}function v(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function y(e,t){return e.x===t.x&&e.y===t.y}function C(e,t,r,i){return!!(y(e,t)&&y(r,i)||y(e,i)&&y(r,t))||v(e,t,r)>0!=v(e,t,i)>0&&v(r,i,e)>0!=v(r,i,t)>0}function b(e,t){var r=e;do{ -if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&C(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function S(e,t){return v(e.prev,e,e.next)<0?v(e,t,e.next)>=0&&v(e,e.prev,t)>=0:v(e,t,e.prev)<0||v(e,e.next,t)<0}function w(e,t){var r=e,i=!1,n=(e.x+t.x)/2,o=(e.y+t.y)/2;do{r.y>o!=r.next.y>o&&n<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(i=!i),r=r.next}while(r!==e);return i}function T(e,t){var r=new x(e.i,e.x,e.y),i=new x(t.i,t.x,t.y),n=e.next,o=t.prev;return e.next=t,t.prev=e,r.next=n,n.prev=r,i.next=r,r.prev=i,o.next=i,i.prev=o,i}function A(e,t,r,i){var n=new x(e,t,r);return i?(n.next=i.next,n.prev=i,i.next.prev=n,i.next=n):(n.prev=n,n.next=n),n}function E(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function x(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function P(e,t,r,i){for(var n=0,o=t,a=r-i;o0&&(i+=e[n-1].length,r.holes.push(i))}return r},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===r.CLOCKWISE||e===r.COUNTER_CLOCKWISE}};return e(r)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";var p=new r,f=new r,m={};m.computeArea2D=function(e){for(var t=e.length,r=0,i=t-1,n=0;n0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(r,i){var n=t.packArray(r);return e(n,i,2)};var g=new r,_=new r,v=new r,y=new r,C=new r,b=new r,S=new r;return m.computeSubdivision=function(e,t,i,s){s=o(s,c.RADIANS_PER_DEGREE);var h,p=i.slice(0),f=t.length,m=new Array(3*f),w=0;for(h=0;h0;){var I,O,M=p.pop(),R=p.pop(),N=p.pop(),L=r.fromArray(m,3*N,g),k=r.fromArray(m,3*R,_),F=r.fromArray(m,3*M,v),B=r.multiplyByScalar(r.normalize(L,y),x,y),U=r.multiplyByScalar(r.normalize(k,C),x,C),V=r.multiplyByScalar(r.normalize(F,b),x,b),z=r.magnitudeSquared(r.subtract(B,U,S)),G=r.magnitudeSquared(r.subtract(U,V,S)),H=r.magnitudeSquared(r.subtract(V,B,S)),W=Math.max(z,G,H);W>D?z===W?(I=Math.min(N,R)+" "+Math.max(N,R),h=E[I],a(h)||(O=r.add(L,k,S),r.multiplyByScalar(O,.5,O),m.push(O.x,O.y,O.z),h=m.length/3-1,E[I]=h),p.push(N,h,M),p.push(h,R,M)):G===W?(I=Math.min(R,M)+" "+Math.max(R,M),h=E[I],a(h)||(O=r.add(k,F,S),r.multiplyByScalar(O,.5,O),m.push(O.x,O.y,O.z),h=m.length/3-1,E[I]=h),p.push(R,h,N),p.push(h,M,N)):H===W&&(I=Math.min(M,N)+" "+Math.max(M,N),h=E[I],a(h)||(O=r.add(F,L,S),r.multiplyByScalar(O,.5,O),m.push(O.x,O.y,O.z),h=m.length/3-1,E[I]=h),p.push(M,h,R),p.push(h,N,R)):(A.push(N),A.push(R),A.push(M))}return new l({attributes:{position:new u({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:m})},indices:A,primitiveType:d.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,i,n){i=o(i,s.WGS84);var l=p,u=f;if(t=o(t,0),n=o(n,!0),a(e))for(var c=e.length,d=0;dbe;s--)Ce=g.PI_OVER_TWO-s*ye,_e[ve++]=1-me*(1+Math.cos(Ce)),_e[ve++]=.5*(1+Math.sin(Ce));for(s=be;s>0;s--)Ce=g.PI_OVER_TWO-ye*s,_e[ve++]=1-ge*(1+Math.cos(Ce)),_e[ve++]=.5*(1+Math.sin(Ce));for(s=C-A;s>0;s--)_e[ve++]=s*ge,_e[ve++]=1;for(s=1;s0;s--)_e[ve++]=(s-1)*ge,_e[ve++]=1}y.st=new p({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:_e})}return t.normal&&(y.normal=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:j.normals})),t.tangent&&(y.tangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:j.tangents})),t.bitangent&&(y.bitangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:j.bitangents})),{attributes:y,indices:K}}function T(e,t){if(!(t.normal||t.tangent||t.bitangent||t.st))return e;var i,n,o=e.position.values;(t.normal||t.bitangent)&&(i=e.normal.values,n=e.bitangent.values);var s,l=e.position.values.length/18,u=3*l,c=2*l,d=2*u;if(t.normal||t.bitangent||t.tangent){var h=t.normal?new Float32Array(6*u):void 0,p=t.tangent?new Float32Array(6*u):void 0,f=t.bitangent?new Float32Array(6*u):void 0,m=I,g=O,_=M,v=R,y=N,C=L,b=d;for(s=0;s0){var b=Math.min(g,m);_=Math.round(m/b),C+=b}var S,w=d.createTypedArray(v,2*C),T=0;for(S=0;S0)for(S=0;S=f&&(m=(m+8)%24,u=m);d1?1:u;var C=p(u);for(t in n){var b=i[t]||0,S=n[t];S instanceof Array?r[t]=f(S,C):("string"==typeof S&&(S=b+parseFloat(S,10)),"number"==typeof S&&(r[t]=b+(S-b)*C))}if(null!==v&&v.call(r,C),1==u){if(s>0){isFinite(s)&&s--;for(t in o){if("string"==typeof n[t]&&(o[t]=o[t]+parseFloat(n[t],10)),l){var w=o[t];o[t]=n[t],n[t]=w}i[t]=o[t]}return l&&(c=!c),h=e+d,!0}null!==y&&y.call(r);for(var T=0,A=m.length;T1?a(t[i],t[i-1],i-n):a(t[o],t[o+1>i?i:o+1],n-o)},Bezier:function(t,r){var i,n=0,o=t.length-1,a=Math.pow,s=e.Interpolation.Utils.Bernstein;for(i=0;i<=o;i++)n+=a(1-r,o-i)*a(r,i)*t[i]*s(o,i);return n},CatmullRom:function(t,r){var i=t.length-1,n=i*r,o=Math.floor(n),a=e.Interpolation.Utils.CatmullRom;return t[0]===t[i]?(r<0&&(o=Math.floor(n=i*(1+r))),a(t[(o-1+i)%i],t[o],t[(o+1)%i],t[(o+2)%i],n-o)):r<0?t[0]-(a(t[0],t[0],t[1],t[1],-n)-t[0]):r>1?t[i]-(a(t[i],t[i],t[i-1],t[i-1],n-i)-t[i]):a(t[o?o-1:0],t[o],t[i1;r--)i*=r;return e[t]=i}}(),CatmullRom:function(e,t,r,i,n){var o=.5*(r-e),a=.5*(i-t),s=n*n;return(2*t-2*r+o+a)*(n*s)+(-3*t+3*r-2*o-a)*s+o*n+t}}},e}),define("Core/EasingFunction",["../ThirdParty/Tween","./freezeObject"],function(e,t){"use strict";return t({LINEAR_NONE:e.Easing.Linear.None,QUADRACTIC_IN:e.Easing.Quadratic.In,QUADRACTIC_OUT:e.Easing.Quadratic.Out,QUADRACTIC_IN_OUT:e.Easing.Quadratic.InOut,CUBIC_IN:e.Easing.Cubic.In,CUBIC_OUT:e.Easing.Cubic.Out,CUBIC_IN_OUT:e.Easing.Cubic.InOut,QUARTIC_IN:e.Easing.Quartic.In,QUARTIC_OUT:e.Easing.Quartic.Out,QUARTIC_IN_OUT:e.Easing.Quartic.InOut,QUINTIC_IN:e.Easing.Quintic.In,QUINTIC_OUT:e.Easing.Quintic.Out,QUINTIC_IN_OUT:e.Easing.Quintic.InOut,SINUSOIDAL_IN:e.Easing.Sinusoidal.In,SINUSOIDAL_OUT:e.Easing.Sinusoidal.Out,SINUSOIDAL_IN_OUT:e.Easing.Sinusoidal.InOut,EXPONENTIAL_IN:e.Easing.Exponential.In,EXPONENTIAL_OUT:e.Easing.Exponential.Out,EXPONENTIAL_IN_OUT:e.Easing.Exponential.InOut,CIRCULAR_IN:e.Easing.Circular.In,CIRCULAR_OUT:e.Easing.Circular.Out,CIRCULAR_IN_OUT:e.Easing.Circular.InOut,ELASTIC_IN:e.Easing.Elastic.In,ELASTIC_OUT:e.Easing.Elastic.Out,ELASTIC_IN_OUT:e.Easing.Elastic.InOut,BACK_IN:e.Easing.Back.In,BACK_OUT:e.Easing.Back.Out,BACK_IN_OUT:e.Easing.Back.InOut,BOUNCE_IN:e.Easing.Bounce.In,BOUNCE_OUT:e.Easing.Bounce.Out,BOUNCE_IN_OUT:e.Easing.Bounce.InOut})}),define("Core/EllipsoidGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=n(e,n.EMPTY_OBJECT);var t=n(e.radii,b),i=Math.round(n(e.stackPartitions,64)),o=Math.round(n(e.slicePartitions,64)),a=n(e.vertexFormat,f.DEFAULT);this._radii=r.clone(t),this._stackPartitions=i,this._slicePartitions=o,this._vertexFormat=f.clone(a),this._workerName="createEllipsoidGeometry"}var g=new r,_=new r,v=new r,y=new r,C=new r,b=new r(1,1,1),S=Math.cos,w=Math.sin;m.packedLength=r.packedLength+f.packedLength+2,m.pack=function(e,t,i){return i=n(i,0),r.pack(e._radii,t,i),i+=r.packedLength,f.pack(e._vertexFormat,t,i),i+=f.packedLength,t[i++]=e._stackPartitions,t[i]=e._slicePartitions,t};var T=new r,A=new f,E={radii:T,vertexFormat:A,stackPartitions:void 0,slicePartitions:void 0};return m.unpack=function(e,t,i){t=n(t,0);var a=r.unpack(e,t,T);t+=r.packedLength;var s=f.unpack(e,t,A);t+=f.packedLength;var l=e[t++],u=e[t];return o(i)?(i._radii=r.clone(a,i._radii),i._vertexFormat=f.clone(s,i._vertexFormat),i._stackPartitions=l,i._slicePartitions=u,i):(E.stackPartitions=l,E.slicePartitions=u,new m(E))},m.createGeometry=function(n){var o=n._radii;if(!(o.x<=0||o.y<=0||o.z<=0)){var a,f,m=s.fromCartesian3(o),b=n._vertexFormat,T=n._slicePartitions+1,A=n._stackPartitions+1,E=A*T,x=new Float64Array(3*E),P=6*(T-1)*(A-2),D=d.createTypedArray(E,P),I=b.normal?new Float32Array(3*E):void 0,O=b.tangent?new Float32Array(3*E):void 0,M=b.bitangent?new Float32Array(3*E):void 0,R=b.st?new Float32Array(2*E):void 0,N=new Array(T),L=new Array(T),k=0;for(a=0;ax.length&&(k=3*(a-T*Math.floor(.5*A))),r.fromArray(x,k,Z),m.geodeticSurfaceNormal(Z,Z),t.negate(Z,Z)),R[W++]=Math.atan2(Z.y,Z.x)/h.TWO_PI+.5,R[W++]=Math.asin(Q.z)/Math.PI+.5}if(b.normal&&(I[j++]=Q.x,I[j++]=Q.y,I[j++]=Q.z),b.tangent||b.bitangent){var K=v;if(aE-T-1?(r.cross(r.UNIT_X,Q,K),r.normalize(K,K)):(r.cross(r.UNIT_Z,Q,K),r.normalize(K,K)),b.tangent&&(O[q++]=K.x,O[q++]=K.y,O[q++]=K.z),b.bitangent){var J=r.cross(Q,K,y);r.normalize(J,J),M[Y++]=J.x,M[Y++]=J.y,M[Y++]=J.z}}}b.st&&(H.st=new u({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:R})),b.normal&&(H.normal=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),b.tangent&&(H.tangent=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:O})),b.bitangent&&(H.bitangent=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:M}))}for(k=0,f=0;fN-b-1;--o)E[x++]=N,E[x++]=o;var L=new u({position:new l({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:A})});return new s({attributes:L,indices:E,primitiveType:h.LINES,boundingSphere:e.fromEllipsoid(y)})}},p}),define("Core/EllipsoidTerrainProvider",["../ThirdParty/when","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Event","./GeographicTilingScheme","./HeightmapTerrainData","./TerrainProvider"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(i){i=t(i,{}),this._tilingScheme=i.tilingScheme,r(this._tilingScheme)||(this._tilingScheme=new a({ellipsoid:t(i.ellipsoid,n.WGS84)})),this._levelZeroMaximumGeometricError=l.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid,64,this._tilingScheme.getNumberOfXTilesAtLevel(0)),this._errorEvent=new o,this._readyPromise=e.resolve(!0)}return i(u.prototype,{errorEvent:{get:function(){return this._errorEvent}},credit:{get:function(){}},tilingScheme:{get:function(){return this._tilingScheme}},ready:{get:function(){return!0}},readyPromise:{get:function(){return this._readyPromise}},hasWaterMask:{get:function(){return!1}},hasVertexNormals:{get:function(){return!1}}}),u.prototype.requestTileGeometry=function(e,t,r,i){return new s({buffer:new Uint8Array(256),width:16,height:16})},u.prototype.getLevelMaximumGeometricError=function(e){return this._levelZeroMaximumGeometricError/(1<>10),56320+(1023&o)))}return t},"undefined"!=typeof TextDecoder?n.decode=n.decodeWithTextDecoder:n.decode=n.decodeWithFromCharCode,n}),define("Core/getMagic",["./defaultValue","./getStringFromTypedArray"],function(e,t){"use strict";function r(r,i){return i=e(i,0),t(r,i,Math.min(4,r.length))}return r}),function(global,undefined){"use strict";!function(e,t,r){function i(r){var n=t[r];return n||e[r][0].call(n=t[r]={exports:{}},i,n,n.exports),n.exports}var n=global.protobuf=i(r[0]);"function"==typeof define&&define.amd&&define("ThirdParty/protobuf-minimal",[],function(){return n.configure(),n}),"object"==typeof module&&module&&module.exports&&(module.exports=n)}({1:[function(e,t,r){function i(e,t){for(var r=[],i=2;i1&&"="===e.charAt(t);)++r;return Math.ceil(3*e.length)/4-r};for(var n=new Array(64),o=new Array(123),a=0;a<64;)o[n[a]=a<26?a+65:a<52?a+71:a<62?a-4:a-59|43]=a++;i.encode=function(e,t,r){for(var i,o=[],a=0,s=0;t>2],i=(3&l)<<4,s=1;break;case 1:o[a++]=n[i|l>>4],i=(15&l)<<2,s=2;break;case 2:o[a++]=n[i|l>>6],o[a++]=n[63&l],s=0}}return s&&(o[a++]=n[i],o[a]=61,1===s&&(o[a+1]=61)),String.fromCharCode.apply(String,o)};i.decode=function(e,t,r){for(var i,n=r,a=0,s=0;s1)break;if((l=o[l])===undefined)throw Error("invalid encoding");switch(a){case 0:i=l,a=1;break;case 1:t[r++]=i<<2|(48&l)>>4,i=l,a=2;break;case 2:t[r++]=(15&i)<<4|(60&l)>>2,i=l,a=3;break;case 3:t[r++]=(3&i)<<6|l,a=0}}if(1===a)throw Error("invalid encoding");return r-n},i.test=function(e){return/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(e)}},{}],3:[function(e,t,r){function i(){this._listeners={}}t.exports=i,i.prototype.on=function(e,t,r){return(this._listeners[e]||(this._listeners[e]=[])).push({fn:t,ctx:r||this}),this},i.prototype.off=function(e,t){if(e===undefined)this._listeners={};else if(t===undefined)this._listeners[e]=[];else for(var r=this._listeners[e],i=0;i>>1,o=null,a=i;return function(r){if(r<1||r>n)return e(r);a+r>i&&(o=e(i),a=0);var s=t.call(o,a,a+=r);return 7&a&&(a=1+(7|a)),s}}t.exports=i},{}],6:[function(e,t,r){var i=r;i.length=function(e){for(var t=0,r=0,i=0;i191&&i<224?o[a++]=(31&i)<<6|63&e[t++]:i>239&&i<365?(i=((7&i)<<18|(63&e[t++])<<12|(63&e[t++])<<6|63&e[t++])-65536,o[a++]=55296+(i>>10),o[a++]=56320+(1023&i)):o[a++]=(15&i)<<12|(63&e[t++])<<6|63&e[t++],a>8191&&((n||(n=[])).push(String.fromCharCode.apply(String,o)),a=0);return n?(a&&n.push(String.fromCharCode.apply(String,o.slice(0,a))),n.join("")):String.fromCharCode.apply(String,o.slice(0,a))},i.write=function(e,t,r){for(var i,n,o=r,a=0;a>6|192,t[r++]=63&i|128):55296==(64512&i)&&56320==(64512&(n=e.charCodeAt(a+1)))?(i=65536+((1023&i)<<10)+(1023&n),++a,t[r++]=i>>18|240,t[r++]=i>>12&63|128,t[r++]=i>>6&63|128,t[r++]=63&i|128):(t[r++]=i>>12|224,t[r++]=i>>6&63|128,t[r++]=63&i|128);return r-o}},{}],7:[function(e,t,r){function i(){n.Reader._configure(n.BufferReader),n.util._configure()}var n=r;n.build="minimal",n.roots={},n.Writer=e(14),n.BufferWriter=e(15),n.Reader=e(8),n.BufferReader=e(9),n.util=e(13),n.rpc=e(10),n.configure=i,n.Writer._configure(n.BufferWriter),i()},{10:10,13:13,14:14,15:15,8:8,9:9}],8:[function(e,t,r){function i(e,t){return RangeError("index out of range: "+e.pos+" + "+(t||1)+" > "+e.len)}function n(e){this.buf=e,this.pos=0,this.len=e.length}function o(){var e=new c(0,0),t=0;if(!(this.len-this.pos>4)){for(;t<3;++t){if(this.pos>=this.len)throw i(this);if(e.lo=(e.lo|(127&this.buf[this.pos])<<7*t)>>>0,this.buf[this.pos++]<128)return e}return e.lo=(e.lo|(127&this.buf[this.pos++])<<7*t)>>>0,e}for(;t<4;++t)if(e.lo=(e.lo|(127&this.buf[this.pos])<<7*t)>>>0,this.buf[this.pos++]<128)return e;if(e.lo=(e.lo|(127&this.buf[this.pos])<<28)>>>0,e.hi=(e.hi|(127&this.buf[this.pos])>>4)>>>0,this.buf[this.pos++]<128)return e;if(t=0,this.len-this.pos>4){for(;t<5;++t)if(e.hi=(e.hi|(127&this.buf[this.pos])<<7*t+3)>>>0,this.buf[this.pos++]<128)return e}else for(;t<5;++t){if(this.pos>=this.len)throw i(this);if(e.hi=(e.hi|(127&this.buf[this.pos])<<7*t+3)>>>0,this.buf[this.pos++]<128)return e}throw Error("invalid varint encoding")}function a(e,t){return(e[t-4]|e[t-3]<<8|e[t-2]<<16|e[t-1]<<24)>>>0}function s(){if(this.pos+8>this.len)throw i(this,8);return new c(a(this.buf,this.pos+=4),a(this.buf,this.pos+=4))}t.exports=n;var l,u=e(13),c=u.LongBits,d=u.utf8,h="undefined"!=typeof Uint8Array?function(e){if(e instanceof Uint8Array||Array.isArray(e))return new n(e);throw Error("illegal buffer")}:function(e){if(Array.isArray(e))return new n(e);throw Error("illegal buffer")};n.create=u.Buffer?function(e){return(n.create=function(e){return u.Buffer.isBuffer(e)?new l(e):h(e)})(e)}:h,n.prototype._slice=u.Array.prototype.subarray||u.Array.prototype.slice,n.prototype.uint32=function(){var e=4294967295;return function(){if(e=(127&this.buf[this.pos])>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(127&this.buf[this.pos])<<7)>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(127&this.buf[this.pos])<<14)>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(127&this.buf[this.pos])<<21)>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(15&this.buf[this.pos])<<28)>>>0,this.buf[this.pos++]<128)return e;if((this.pos+=5)>this.len)throw this.pos=this.len,i(this,10);return e}}(),n.prototype.int32=function(){return 0|this.uint32()},n.prototype.sint32=function(){var e=this.uint32();return e>>>1^-(1&e)|0},n.prototype.bool=function(){return 0!==this.uint32()},n.prototype.fixed32=function(){if(this.pos+4>this.len)throw i(this,4);return a(this.buf,this.pos+=4)},n.prototype.sfixed32=function(){if(this.pos+4>this.len)throw i(this,4);return 0|a(this.buf,this.pos+=4)};var p="undefined"!=typeof Float32Array?function(){var e=new Float32Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[3]?function(r,i){return t[0]=r[i],t[1]=r[i+1],t[2]=r[i+2],t[3]=r[i+3],e[0]}:function(r,i){return t[0]=r[i+3],t[1]=r[i+2],t[2]=r[i+1],t[3]=r[i],e[0]}}():function(e,t){var r=a(e,t+4),i=2*(r>>31)+1,n=r>>>23&255,o=8388607&r;return 255===n?o?NaN:i*(1/0):0===n?1.401298464324817e-45*i*o:i*Math.pow(2,n-150)*(o+8388608)};n.prototype.float=function(){if(this.pos+4>this.len)throw i(this,4);var e=p(this.buf,this.pos);return this.pos+=4,e};var f="undefined"!=typeof Float64Array?function(){var e=new Float64Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[7]?function(r,i){return t[0]=r[i],t[1]=r[i+1],t[2]=r[i+2],t[3]=r[i+3],t[4]=r[i+4],t[5]=r[i+5],t[6]=r[i+6],t[7]=r[i+7],e[0]}:function(r,i){return t[0]=r[i+7],t[1]=r[i+6],t[2]=r[i+5],t[3]=r[i+4],t[4]=r[i+3],t[5]=r[i+2],t[6]=r[i+1],t[7]=r[i],e[0]}}():function(e,t){var r=a(e,t+4),i=a(e,t+8),n=2*(i>>31)+1,o=i>>>20&2047,s=4294967296*(1048575&i)+r;return 2047===o?s?NaN:n*(1/0):0===o?5e-324*n*s:n*Math.pow(2,o-1075)*(s+4503599627370496)};n.prototype.double=function(){if(this.pos+8>this.len)throw i(this,4);var e=f(this.buf,this.pos);return this.pos+=8,e},n.prototype.bytes=function(){var e=this.uint32(),t=this.pos,r=this.pos+e;if(r>this.len)throw i(this,e);return this.pos+=e,t===r?new this.buf.constructor(0):this._slice.call(this.buf,t,r)},n.prototype.string=function(){var e=this.bytes();return d.read(e,0,e.length)},n.prototype.skip=function(e){if("number"==typeof e){if(this.pos+e>this.len)throw i(this,e);this.pos+=e}else do{if(this.pos>=this.len)throw i(this)}while(128&this.buf[this.pos++]);return this},n.prototype.skipType=function(e){switch(e){case 0:this.skip();break;case 1:this.skip(8);break;case 2:this.skip(this.uint32());break;case 3:for(;;){if(4==(e=7&this.uint32()))break;this.skipType(e)}break;case 5:this.skip(4);break;default:throw Error("invalid wire type "+e+" at offset "+this.pos)}return this},n._configure=function(e){l=e;var t=u.Long?"toLong":"toNumber";u.merge(n.prototype,{int64:function(){return o.call(this)[t](!1)},uint64:function(){return o.call(this)[t](!0)},sint64:function(){return o.call(this).zzDecode()[t](!1)},fixed64:function(){return s.call(this)[t](!0)},sfixed64:function(){return s.call(this)[t](!1)}})}},{13:13}],9:[function(e,t,r){function i(e){n.call(this,e)}t.exports=i;var n=e(8);(i.prototype=Object.create(n.prototype)).constructor=i;var o=e(13);o.Buffer&&(i.prototype._slice=o.Buffer.prototype.slice),i.prototype.string=function(){var e=this.uint32();return this.buf.utf8Slice(this.pos,this.pos=Math.min(this.pos+e,this.len))}},{13:13,8:8}],10:[function(e,t,r){r.Service=e(11)},{11:11}],11:[function(e,t,r){function i(e,t,r){if("function"!=typeof e)throw TypeError("rpcImpl must be a function");n.EventEmitter.call(this),this.rpcImpl=e,this.requestDelimited=Boolean(t),this.responseDelimited=Boolean(r)}t.exports=i;var n=e(13);(i.prototype=Object.create(n.EventEmitter.prototype)).constructor=i,i.prototype.rpcCall=function e(t,r,i,o,a){if(!o)throw TypeError("request must be specified");var s=this;if(!a)return n.asPromise(e,s,t,r,i,o);if(!s.rpcImpl)return setTimeout(function(){a(Error("already ended"))},0),undefined;try{return s.rpcImpl(t,r[s.requestDelimited?"encodeDelimited":"encode"](o).finish(),function(e,r){if(e)return s.emit("error",e,t),a(e);if(null===r)return s.end(!0),undefined;if(!(r instanceof i))try{r=i[s.responseDelimited?"decodeDelimited":"decode"](r)}catch(e){return s.emit("error",e,t),a(e)}return s.emit("data",r,t),a(null,r)})}catch(e){return s.emit("error",e,t),setTimeout(function(){a(e)},0),undefined}},i.prototype.end=function(e){return this.rpcImpl&&(e||this.rpcImpl(null,null,null),this.rpcImpl=null,this.emit("end").off()),this}},{13:13}],12:[function(e,t,r){function i(e,t){this.lo=e>>>0,this.hi=t>>>0}t.exports=i;var n=e(13),o=i.zero=new i(0,0);o.toNumber=function(){return 0},o.zzEncode=o.zzDecode=function(){return this},o.length=function(){return 1};var a=i.zeroHash="\0\0\0\0\0\0\0\0";i.fromNumber=function(e){if(0===e)return o;var t=e<0;t&&(e=-e);var r=e>>>0,n=(e-r)/4294967296>>>0;return t&&(n=~n>>>0,r=~r>>>0,++r>4294967295&&(r=0,++n>4294967295&&(n=0))),new i(r,n)},i.from=function(e){if("number"==typeof e)return i.fromNumber(e);if(n.isString(e)){if(!n.Long)return i.fromNumber(parseInt(e,10));e=n.Long.fromString(e)}return e.low||e.high?new i(e.low>>>0,e.high>>>0):o},i.prototype.toNumber=function(e){if(!e&&this.hi>>>31){var t=1+~this.lo>>>0,r=~this.hi>>>0;return t||(r=r+1>>>0),-(t+4294967296*r)}return this.lo+4294967296*this.hi},i.prototype.toLong=function(e){return n.Long?new n.Long(0|this.lo,0|this.hi,Boolean(e)):{low:0|this.lo,high:0|this.hi,unsigned:Boolean(e)}};var s=String.prototype.charCodeAt;i.fromHash=function(e){return e===a?o:new i((s.call(e,0)|s.call(e,1)<<8|s.call(e,2)<<16|s.call(e,3)<<24)>>>0,(s.call(e,4)|s.call(e,5)<<8|s.call(e,6)<<16|s.call(e,7)<<24)>>>0)},i.prototype.toHash=function(){return String.fromCharCode(255&this.lo,this.lo>>>8&255,this.lo>>>16&255,this.lo>>>24,255&this.hi,this.hi>>>8&255,this.hi>>>16&255,this.hi>>>24)},i.prototype.zzEncode=function(){var e=this.hi>>31;return this.hi=((this.hi<<1|this.lo>>>31)^e)>>>0,this.lo=(this.lo<<1^e)>>>0,this},i.prototype.zzDecode=function(){var e=-(1&this.lo);return this.lo=((this.lo>>>1|this.hi<<31)^e)>>>0,this.hi=(this.hi>>>1^e)>>>0,this},i.prototype.length=function(){var e=this.lo,t=(this.lo>>>28|this.hi<<4)>>>0,r=this.hi>>>24;return 0===r?0===t?e<16384?e<128?1:2:e<2097152?3:4:t<16384?t<128?5:6:t<2097152?7:8:r<128?9:10}},{13:13}],13:[function(e,t,r){function i(e,t,r){for(var i=Object.keys(t),n=0;n-1;--r)if(1===t[e[r]]&&this[e[r]]!==undefined&&null!==this[e[r]])return e[r]}},o.oneOfSetter=function(e){return function(t){for(var r=0;r127;)t[r++]=127&e|128,e>>>=7;t[r]=e}function u(e,t){this.len=e,this.next=undefined,this.val=t}function c(e,t,r){for(;e.hi;)t[r++]=127&e.lo|128,e.lo=(e.lo>>>7|e.hi<<25)>>>0,e.hi>>>=7;for(;e.lo>127;)t[r++]=127&e.lo|128,e.lo=e.lo>>>7;t[r++]=e.lo}function d(e,t,r){t[r++]=255&e,t[r++]=e>>>8&255,t[r++]=e>>>16&255,t[r]=e>>>24}t.exports=a;var h,p=e(13),f=p.LongBits,m=p.base64,g=p.utf8;a.create=p.Buffer?function(){return(a.create=function(){return new h})()}:function(){return new a},a.alloc=function(e){return new p.Array(e)},p.Array!==Array&&(a.alloc=p.pool(a.alloc,p.Array.prototype.subarray)),a.prototype.push=function(e,t,r){return this.tail=this.tail.next=new i(e,t,r),this.len+=t,this},u.prototype=Object.create(i.prototype),u.prototype.fn=l,a.prototype.uint32=function(e){return this.len+=(this.tail=this.tail.next=new u((e>>>=0)<128?1:e<16384?2:e<2097152?3:e<268435456?4:5,e)).len,this},a.prototype.int32=function(e){return e<0?this.push(c,10,f.fromNumber(e)):this.uint32(e)},a.prototype.sint32=function(e){return this.uint32((e<<1^e>>31)>>>0)},a.prototype.uint64=function(e){var t=f.from(e);return this.push(c,t.length(),t)},a.prototype.int64=a.prototype.uint64,a.prototype.sint64=function(e){var t=f.from(e).zzEncode();return this.push(c,t.length(),t)},a.prototype.bool=function(e){return this.push(s,1,e?1:0)},a.prototype.fixed32=function(e){return this.push(d,4,e>>>0)},a.prototype.sfixed32=a.prototype.fixed32,a.prototype.fixed64=function(e){var t=f.from(e);return this.push(d,4,t.lo).push(d,4,t.hi)},a.prototype.sfixed64=a.prototype.fixed64;var _="undefined"!=typeof Float32Array?function(){var e=new Float32Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[3]?function(r,i,n){e[0]=r,i[n++]=t[0],i[n++]=t[1],i[n++]=t[2],i[n]=t[3]}:function(r,i,n){e[0]=r,i[n++]=t[3],i[n++]=t[2],i[n++]=t[1],i[n]=t[0]}}():function(e,t,r){var i=e<0?1:0;if(i&&(e=-e),0===e)d(1/e>0?0:2147483648,t,r);else if(isNaN(e))d(2147483647,t,r);else if(e>3.4028234663852886e38)d((i<<31|2139095040)>>>0,t,r);else if(e<1.1754943508222875e-38)d((i<<31|Math.round(e/1.401298464324817e-45))>>>0,t,r);else{var n=Math.floor(Math.log(e)/Math.LN2),o=8388607&Math.round(e*Math.pow(2,-n)*8388608);d((i<<31|n+127<<23|o)>>>0,t,r)}};a.prototype.float=function(e){return this.push(_,4,e)};var v="undefined"!=typeof Float64Array?function(){var e=new Float64Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[7]?function(r,i,n){e[0]=r,i[n++]=t[0],i[n++]=t[1],i[n++]=t[2],i[n++]=t[3],i[n++]=t[4],i[n++]=t[5],i[n++]=t[6],i[n]=t[7]}:function(r,i,n){e[0]=r,i[n++]=t[7],i[n++]=t[6],i[n++]=t[5],i[n++]=t[4],i[n++]=t[3],i[n++]=t[2],i[n++]=t[1],i[n]=t[0]}}():function(e,t,r){var i=e<0?1:0;if(i&&(e=-e),0===e)d(0,t,r),d(1/e>0?0:2147483648,t,r+4);else if(isNaN(e))d(4294967295,t,r),d(2147483647,t,r+4);else if(e>1.7976931348623157e308)d(0,t,r),d((i<<31|2146435072)>>>0,t,r+4);else{var n;if(e<2.2250738585072014e-308)n=e/5e-324,d(n>>>0,t,r),d((i<<31|n/4294967296)>>>0,t,r+4);else{var o=Math.floor(Math.log(e)/Math.LN2);1024===o&&(o=1023),n=e*Math.pow(2,-o),d(4503599627370496*n>>>0,t,r),d((i<<31|o+1023<<20|1048576*n&1048575)>>>0,t,r+4)}}};a.prototype.double=function(e){return this.push(v,8,e)};var y=p.Array.prototype.set?function(e,t,r){t.set(e,r)}:function(e,t,r){for(var i=0;i>>0;if(!t)return this.push(s,1,0);if(p.isString(e)){var r=a.alloc(t=m.length(e));m.decode(e,r,0),e=r}return this.uint32(t).push(y,t,e)},a.prototype.string=function(e){var t=g.length(e);return t?this.uint32(t).push(g.write,t,e):this.push(s,1,0)},a.prototype.fork=function(){return this.states=new o(this),this.head=this.tail=new i(n,0,0),this.len=0,this},a.prototype.reset=function(){return this.states?(this.head=this.states.head,this.tail=this.states.tail,this.len=this.states.len,this.states=this.states.next):(this.head=this.tail=new i(n,0,0),this.len=0),this},a.prototype.ldelim=function(){var e=this.head,t=this.tail,r=this.len;return this.reset().uint32(r),r&&(this.tail.next=e.next,this.tail=t,this.len+=r),this},a.prototype.finish=function(){for(var e=this.head.next,t=this.constructor.alloc(this.len),r=0;e;)e.fn(e.val,t,r),r+=e.len,e=e.next;return t},a._configure=function(e){h=e}},{13:13}],15:[function(e,t,r){function i(){o.call(this)}function n(e,t,r){e.length<40?a.utf8.write(e,t,r):t.utf8Write(e,r)}t.exports=i;var o=e(14);(i.prototype=Object.create(o.prototype)).constructor=i;var a=e(13),s=a.Buffer;i.alloc=function(e){return(i.alloc=a._Buffer_allocUnsafe)(e)};var l=s&&s.prototype instanceof Uint8Array&&"set"===s.prototype.set.name?function(e,t,r){t.set(e,r)}:function(e,t,r){if(e.copy)e.copy(t,r,0,e.length);else for(var i=0;i>>0;return this.uint32(t),t&&this.push(l,t,e),this},i.prototype.string=function(e){var t=s.byteLength(e);return this.uint32(t),t&&this.push(n,t,e),this}},{13:13,14:14}]},{},[7])}("object"==typeof window&&window||"object"==typeof self&&self||this),define("ThirdParty/google-earth-dbroot-parser",["./protobuf-minimal"],function(e){"use strict";var t=e.Reader,r=(e.Writer,e.util),i=[],n=e.roots.default||(e.roots.default={});return n.keyhole=function(){var o={};return o.dbroot=function(){var o={};return o.StringEntryProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.stringId=e.fixed32();break;case 2:o.stringValue=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isInteger(e.stringId)?r.isString(e.stringValue)?null:"stringValue: string expected":"stringId: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.StringEntryProto)return e;var t=new n.keyhole.dbroot.StringEntryProto;return void 0!==e.stringId&&null!==e.stringId&&(t.stringId=e.stringId>>>0),void 0!==e.stringValue&&null!==e.stringValue&&(t.stringValue=String(e.stringValue)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.stringId=0,r.stringValue=""),void 0!==e.stringId&&null!==e.stringId&&e.hasOwnProperty("stringId")&&(r.stringId=e.stringId),void 0!==e.stringValue&&null!==e.stringValue&&e.hasOwnProperty("stringValue")&&(r.stringValue=e.stringValue),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.StringIdOrValueProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.stringId=e.fixed32();break;case 2:o.value=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.stringId||r.isInteger(e.stringId)?void 0===e.value||r.isString(e.value)?null:"value: string expected":"stringId: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.StringIdOrValueProto)return e;var t=new n.keyhole.dbroot.StringIdOrValueProto;return void 0!==e.stringId&&null!==e.stringId&&(t.stringId=e.stringId>>>0),void 0!==e.value&&null!==e.value&&(t.value=String(e.value)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.stringId=0,r.value=""),void 0!==e.stringId&&null!==e.stringId&&e.hasOwnProperty("stringId")&&(r.stringId=e.stringId),void 0!==e.value&&null!==e.value&&e.hasOwnProperty("value")&&(r.value=e.value),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.PlanetModelProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.radius=e.double();break;case 2:o.flattening=e.double();break;case 4:o.elevationBias=e.double();break;case 5:o.negativeAltitudeExponentBias=e.int32();break;case 6:o.compressedNegativeAltitudeThreshold=e.double();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.radius&&"number"!=typeof e.radius?"radius: number expected":void 0!==e.flattening&&"number"!=typeof e.flattening?"flattening: number expected":void 0!==e.elevationBias&&"number"!=typeof e.elevationBias?"elevationBias: number expected":void 0===e.negativeAltitudeExponentBias||r.isInteger(e.negativeAltitudeExponentBias)?void 0!==e.compressedNegativeAltitudeThreshold&&"number"!=typeof e.compressedNegativeAltitudeThreshold?"compressedNegativeAltitudeThreshold: number expected":null:"negativeAltitudeExponentBias: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PlanetModelProto)return e;var t=new n.keyhole.dbroot.PlanetModelProto;return void 0!==e.radius&&null!==e.radius&&(t.radius=Number(e.radius)),void 0!==e.flattening&&null!==e.flattening&&(t.flattening=Number(e.flattening)),void 0!==e.elevationBias&&null!==e.elevationBias&&(t.elevationBias=Number(e.elevationBias)),void 0!==e.negativeAltitudeExponentBias&&null!==e.negativeAltitudeExponentBias&&(t.negativeAltitudeExponentBias=0|e.negativeAltitudeExponentBias),void 0!==e.compressedNegativeAltitudeThreshold&&null!==e.compressedNegativeAltitudeThreshold&&(t.compressedNegativeAltitudeThreshold=Number(e.compressedNegativeAltitudeThreshold)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.radius=6378.137,r.flattening=.00335281066474748,r.elevationBias=0,r.negativeAltitudeExponentBias=0,r.compressedNegativeAltitudeThreshold=0),void 0!==e.radius&&null!==e.radius&&e.hasOwnProperty("radius")&&(r.radius=e.radius),void 0!==e.flattening&&null!==e.flattening&&e.hasOwnProperty("flattening")&&(r.flattening=e.flattening),void 0!==e.elevationBias&&null!==e.elevationBias&&e.hasOwnProperty("elevationBias")&&(r.elevationBias=e.elevationBias),void 0!==e.negativeAltitudeExponentBias&&null!==e.negativeAltitudeExponentBias&&e.hasOwnProperty("negativeAltitudeExponentBias")&&(r.negativeAltitudeExponentBias=e.negativeAltitudeExponentBias),void 0!==e.compressedNegativeAltitudeThreshold&&null!==e.compressedNegativeAltitudeThreshold&&e.hasOwnProperty("compressedNegativeAltitudeThreshold")&&(r.compressedNegativeAltitudeThreshold=e.compressedNegativeAltitudeThreshold),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.ProviderInfoProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.providerId=e.int32();break;case 2:o.copyrightString=a[1].decode(e,e.uint32());break;case 3:o.verticalPixelOffset=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isInteger(e.providerId))return"providerId: integer expected";if(void 0!==e.copyrightString&&null!==e.copyrightString){var t=a[1].verify(e.copyrightString);if(t)return"copyrightString."+t}return void 0===e.verticalPixelOffset||r.isInteger(e.verticalPixelOffset)?null:"verticalPixelOffset: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ProviderInfoProto)return e;var t=new n.keyhole.dbroot.ProviderInfoProto;if(void 0!==e.providerId&&null!==e.providerId&&(t.providerId=0|e.providerId),void 0!==e.copyrightString&&null!==e.copyrightString){if("object"!=typeof e.copyrightString)throw TypeError(".keyhole.dbroot.ProviderInfoProto.copyrightString: object expected");t.copyrightString=a[1].fromObject(e.copyrightString)}return void 0!==e.verticalPixelOffset&&null!==e.verticalPixelOffset&&(t.verticalPixelOffset=0|e.verticalPixelOffset),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.providerId=0,r.copyrightString=null,r.verticalPixelOffset=-1),void 0!==e.providerId&&null!==e.providerId&&e.hasOwnProperty("providerId")&&(r.providerId=e.providerId), -void 0!==e.copyrightString&&null!==e.copyrightString&&e.hasOwnProperty("copyrightString")&&(r.copyrightString=a[1].toObject(e.copyrightString,t)),void 0!==e.verticalPixelOffset&&null!==e.verticalPixelOffset&&e.hasOwnProperty("verticalPixelOffset")&&(r.verticalPixelOffset=e.verticalPixelOffset),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.PopUpProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.isBalloonStyle=e.bool();break;case 2:o.text=a[1].decode(e,e.uint32());break;case 3:o.backgroundColorAbgr=e.fixed32();break;case 4:o.textColorAbgr=e.fixed32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.isBalloonStyle&&"boolean"!=typeof e.isBalloonStyle)return"isBalloonStyle: boolean expected";if(void 0!==e.text&&null!==e.text){var t=a[1].verify(e.text);if(t)return"text."+t}return void 0===e.backgroundColorAbgr||r.isInteger(e.backgroundColorAbgr)?void 0===e.textColorAbgr||r.isInteger(e.textColorAbgr)?null:"textColorAbgr: integer expected":"backgroundColorAbgr: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PopUpProto)return e;var t=new n.keyhole.dbroot.PopUpProto;if(void 0!==e.isBalloonStyle&&null!==e.isBalloonStyle&&(t.isBalloonStyle=Boolean(e.isBalloonStyle)),void 0!==e.text&&null!==e.text){if("object"!=typeof e.text)throw TypeError(".keyhole.dbroot.PopUpProto.text: object expected");t.text=a[1].fromObject(e.text)}return void 0!==e.backgroundColorAbgr&&null!==e.backgroundColorAbgr&&(t.backgroundColorAbgr=e.backgroundColorAbgr>>>0),void 0!==e.textColorAbgr&&null!==e.textColorAbgr&&(t.textColorAbgr=e.textColorAbgr>>>0),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.isBalloonStyle=!1,r.text=null,r.backgroundColorAbgr=4294967295,r.textColorAbgr=4278190080),void 0!==e.isBalloonStyle&&null!==e.isBalloonStyle&&e.hasOwnProperty("isBalloonStyle")&&(r.isBalloonStyle=e.isBalloonStyle),void 0!==e.text&&null!==e.text&&e.hasOwnProperty("text")&&(r.text=a[1].toObject(e.text,t)),void 0!==e.backgroundColorAbgr&&null!==e.backgroundColorAbgr&&e.hasOwnProperty("backgroundColorAbgr")&&(r.backgroundColorAbgr=e.backgroundColorAbgr),void 0!==e.textColorAbgr&&null!==e.textColorAbgr&&e.hasOwnProperty("textColorAbgr")&&(r.textColorAbgr=e.textColorAbgr),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.StyleAttributeProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.styleId=e.string();break;case 3:o.providerId=e.int32();break;case 4:o.polyColorAbgr=e.fixed32();break;case 5:o.lineColorAbgr=e.fixed32();break;case 6:o.lineWidth=e.float();break;case 7:o.labelColorAbgr=e.fixed32();break;case 8:o.labelScale=e.float();break;case 9:o.placemarkIconColorAbgr=e.fixed32();break;case 10:o.placemarkIconScale=e.float();break;case 11:o.placemarkIconPath=a[9].decode(e,e.uint32());break;case 12:o.placemarkIconX=e.int32();break;case 13:o.placemarkIconY=e.int32();break;case 14:o.placemarkIconWidth=e.int32();break;case 15:o.placemarkIconHeight=e.int32();break;case 16:o.popUp=a[14].decode(e,e.uint32());break;case 17:o.drawFlag&&o.drawFlag.length||(o.drawFlag=[]),o.drawFlag.push(a[15].decode(e,e.uint32()));break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.styleId))return"styleId: string expected";if(void 0!==e.providerId&&!r.isInteger(e.providerId))return"providerId: integer expected";if(void 0!==e.polyColorAbgr&&!r.isInteger(e.polyColorAbgr))return"polyColorAbgr: integer expected";if(void 0!==e.lineColorAbgr&&!r.isInteger(e.lineColorAbgr))return"lineColorAbgr: integer expected";if(void 0!==e.lineWidth&&"number"!=typeof e.lineWidth)return"lineWidth: number expected";if(void 0!==e.labelColorAbgr&&!r.isInteger(e.labelColorAbgr))return"labelColorAbgr: integer expected";if(void 0!==e.labelScale&&"number"!=typeof e.labelScale)return"labelScale: number expected";if(void 0!==e.placemarkIconColorAbgr&&!r.isInteger(e.placemarkIconColorAbgr))return"placemarkIconColorAbgr: integer expected";if(void 0!==e.placemarkIconScale&&"number"!=typeof e.placemarkIconScale)return"placemarkIconScale: number expected";if(void 0!==e.placemarkIconPath&&null!==e.placemarkIconPath){var t=a[9].verify(e.placemarkIconPath);if(t)return"placemarkIconPath."+t}if(void 0!==e.placemarkIconX&&!r.isInteger(e.placemarkIconX))return"placemarkIconX: integer expected";if(void 0!==e.placemarkIconY&&!r.isInteger(e.placemarkIconY))return"placemarkIconY: integer expected";if(void 0!==e.placemarkIconWidth&&!r.isInteger(e.placemarkIconWidth))return"placemarkIconWidth: integer expected";if(void 0!==e.placemarkIconHeight&&!r.isInteger(e.placemarkIconHeight))return"placemarkIconHeight: integer expected";if(void 0!==e.popUp&&null!==e.popUp){var t=a[14].verify(e.popUp);if(t)return"popUp."+t}if(void 0!==e.drawFlag){if(!Array.isArray(e.drawFlag))return"drawFlag: array expected";for(var i=0;i>>0),void 0!==e.lineColorAbgr&&null!==e.lineColorAbgr&&(t.lineColorAbgr=e.lineColorAbgr>>>0),void 0!==e.lineWidth&&null!==e.lineWidth&&(t.lineWidth=Number(e.lineWidth)),void 0!==e.labelColorAbgr&&null!==e.labelColorAbgr&&(t.labelColorAbgr=e.labelColorAbgr>>>0),void 0!==e.labelScale&&null!==e.labelScale&&(t.labelScale=Number(e.labelScale)),void 0!==e.placemarkIconColorAbgr&&null!==e.placemarkIconColorAbgr&&(t.placemarkIconColorAbgr=e.placemarkIconColorAbgr>>>0),void 0!==e.placemarkIconScale&&null!==e.placemarkIconScale&&(t.placemarkIconScale=Number(e.placemarkIconScale)),void 0!==e.placemarkIconPath&&null!==e.placemarkIconPath){if("object"!=typeof e.placemarkIconPath)throw TypeError(".keyhole.dbroot.StyleAttributeProto.placemarkIconPath: object expected");t.placemarkIconPath=a[9].fromObject(e.placemarkIconPath)}if(void 0!==e.placemarkIconX&&null!==e.placemarkIconX&&(t.placemarkIconX=0|e.placemarkIconX),void 0!==e.placemarkIconY&&null!==e.placemarkIconY&&(t.placemarkIconY=0|e.placemarkIconY),void 0!==e.placemarkIconWidth&&null!==e.placemarkIconWidth&&(t.placemarkIconWidth=0|e.placemarkIconWidth),void 0!==e.placemarkIconHeight&&null!==e.placemarkIconHeight&&(t.placemarkIconHeight=0|e.placemarkIconHeight),void 0!==e.popUp&&null!==e.popUp){if("object"!=typeof e.popUp)throw TypeError(".keyhole.dbroot.StyleAttributeProto.popUp: object expected");t.popUp=a[14].fromObject(e.popUp)}if(e.drawFlag){if(!Array.isArray(e.drawFlag))throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: array expected");t.drawFlag=[];for(var r=0;r>>3){case 1:o.styleMapId=e.int32();break;case 2:if(o.channelId&&o.channelId.length||(o.channelId=[]),2==(7&a))for(var s=e.uint32()+e.pos;e.pos>>3){case 1:o.minZoom=e.int32();break;case 2:o.maxZoom=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isInteger(e.minZoom)?r.isInteger(e.maxZoom)?null:"maxZoom: integer expected":"minZoom: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ZoomRangeProto)return e;var t=new n.keyhole.dbroot.ZoomRangeProto;return void 0!==e.minZoom&&null!==e.minZoom&&(t.minZoom=0|e.minZoom),void 0!==e.maxZoom&&null!==e.maxZoom&&(t.maxZoom=0|e.maxZoom),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.minZoom=0,r.maxZoom=0),void 0!==e.minZoom&&null!==e.minZoom&&e.hasOwnProperty("minZoom")&&(r.minZoom=e.minZoom),void 0!==e.maxZoom&&null!==e.maxZoom&&e.hasOwnProperty("maxZoom")&&(r.maxZoom=e.maxZoom),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.DrawFlagProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.drawFlagType=e.uint32();break;default:e.skipType(7&a)}}return o},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";switch(e.drawFlagType){default:return"drawFlagType: enum value expected";case 1:case 2:case 3:case 4:case 5:}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DrawFlagProto)return e;var t=new n.keyhole.dbroot.DrawFlagProto;switch(e.drawFlagType){case"TYPE_FILL_ONLY":case 1:t.drawFlagType=1;break;case"TYPE_OUTLINE_ONLY":case 2:t.drawFlagType=2;break;case"TYPE_FILL_AND_OUTLINE":case 3:t.drawFlagType=3;break;case"TYPE_ANTIALIASING":case 4:t.drawFlagType=4;break;case"TYPE_CENTER_LABEL":case 5:t.drawFlagType=5}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.drawFlagType=t.enums===String?"TYPE_FILL_ONLY":1),void 0!==e.drawFlagType&&null!==e.drawFlagType&&e.hasOwnProperty("drawFlagType")&&(r.drawFlagType=t.enums===String?o[0][e.drawFlagType]:e.drawFlagType),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r.DrawFlagType=function(){var e={},t=Object.create(e);return t.TYPE_FILL_ONLY=1,t.TYPE_OUTLINE_ONLY=2,t.TYPE_FILL_AND_OUTLINE=3,t.TYPE_ANTIALIASING=4,t.TYPE_CENTER_LABEL=5,t}(),r}(),o.LayerProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.zoomRange&&o.zoomRange.length||(o.zoomRange=[]),o.zoomRange.push(a[0].decode(e,e.uint32()));break;case 2:o.preserveTextLevel=e.int32();break;case 4:o.lodBeginTransition=e.bool();break;case 5:o.lodEndTransition=e.bool();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.zoomRange){if(!Array.isArray(e.zoomRange))return"zoomRange: array expected";for(var t=0;t>>3){case 1:o.isExpandable=e.bool();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.isExpandable&&"boolean"!=typeof e.isExpandable?"isExpandable: boolean expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.FolderProto)return e;var t=new n.keyhole.dbroot.FolderProto;return void 0!==e.isExpandable&&null!==e.isExpandable&&(t.isExpandable=Boolean(e.isExpandable)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.isExpandable=!0),void 0!==e.isExpandable&&null!==e.isExpandable&&e.hasOwnProperty("isExpandable")&&(r.isExpandable=e.isExpandable),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.RequirementProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 3:o.requiredVram=e.string();break;case 4:o.requiredClientVer=e.string();break;case 5:o.probability=e.string();break;case 6:o.requiredUserAgent=e.string();break;case 7:o.requiredClientCapabilities=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.requiredVram||r.isString(e.requiredVram)?void 0===e.requiredClientVer||r.isString(e.requiredClientVer)?void 0===e.probability||r.isString(e.probability)?void 0===e.requiredUserAgent||r.isString(e.requiredUserAgent)?void 0===e.requiredClientCapabilities||r.isString(e.requiredClientCapabilities)?null:"requiredClientCapabilities: string expected":"requiredUserAgent: string expected":"probability: string expected":"requiredClientVer: string expected":"requiredVram: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.RequirementProto)return e;var t=new n.keyhole.dbroot.RequirementProto;return void 0!==e.requiredVram&&null!==e.requiredVram&&(t.requiredVram=String(e.requiredVram)),void 0!==e.requiredClientVer&&null!==e.requiredClientVer&&(t.requiredClientVer=String(e.requiredClientVer)),void 0!==e.probability&&null!==e.probability&&(t.probability=String(e.probability)),void 0!==e.requiredUserAgent&&null!==e.requiredUserAgent&&(t.requiredUserAgent=String(e.requiredUserAgent)),void 0!==e.requiredClientCapabilities&&null!==e.requiredClientCapabilities&&(t.requiredClientCapabilities=String(e.requiredClientCapabilities)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.requiredVram="",r.requiredClientVer="",r.probability="",r.requiredUserAgent="",r.requiredClientCapabilities=""),void 0!==e.requiredVram&&null!==e.requiredVram&&e.hasOwnProperty("requiredVram")&&(r.requiredVram=e.requiredVram),void 0!==e.requiredClientVer&&null!==e.requiredClientVer&&e.hasOwnProperty("requiredClientVer")&&(r.requiredClientVer=e.requiredClientVer),void 0!==e.probability&&null!==e.probability&&e.hasOwnProperty("probability")&&(r.probability=e.probability),void 0!==e.requiredUserAgent&&null!==e.requiredUserAgent&&e.hasOwnProperty("requiredUserAgent")&&(r.requiredUserAgent=e.requiredUserAgent),void 0!==e.requiredClientCapabilities&&null!==e.requiredClientCapabilities&&e.hasOwnProperty("requiredClientCapabilities")&&(r.requiredClientCapabilities=e.requiredClientCapabilities),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.LookAtProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.longitude=e.float();break;case 2:o.latitude=e.float();break;case 3:o.range=e.float();break;case 4:o.tilt=e.float();break;case 5:o.heading=e.float();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":"number"!=typeof e.longitude?"longitude: number expected":"number"!=typeof e.latitude?"latitude: number expected":void 0!==e.range&&"number"!=typeof e.range?"range: number expected":void 0!==e.tilt&&"number"!=typeof e.tilt?"tilt: number expected":void 0!==e.heading&&"number"!=typeof e.heading?"heading: number expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.LookAtProto)return e;var t=new n.keyhole.dbroot.LookAtProto;return void 0!==e.longitude&&null!==e.longitude&&(t.longitude=Number(e.longitude)),void 0!==e.latitude&&null!==e.latitude&&(t.latitude=Number(e.latitude)),void 0!==e.range&&null!==e.range&&(t.range=Number(e.range)),void 0!==e.tilt&&null!==e.tilt&&(t.tilt=Number(e.tilt)),void 0!==e.heading&&null!==e.heading&&(t.heading=Number(e.heading)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.longitude=0,r.latitude=0,r.range=0,r.tilt=0,r.heading=0),void 0!==e.longitude&&null!==e.longitude&&e.hasOwnProperty("longitude")&&(r.longitude=e.longitude),void 0!==e.latitude&&null!==e.latitude&&e.hasOwnProperty("latitude")&&(r.latitude=e.latitude),void 0!==e.range&&null!==e.range&&e.hasOwnProperty("range")&&(r.range=e.range),void 0!==e.tilt&&null!==e.tilt&&e.hasOwnProperty("tilt")&&(r.tilt=e.tilt),void 0!==e.heading&&null!==e.heading&&e.hasOwnProperty("heading")&&(r.heading=e.heading),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.NestedFeatureProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.featureType=e.uint32();break;case 2:o.kmlUrl=a[1].decode(e,e.uint32());break;case 21:o.databaseUrl=e.string();break;case 3:o.layer=a[3].decode(e,e.uint32());break;case 4:o.folder=a[4].decode(e,e.uint32());break;case 5:o.requirement=a[5].decode(e,e.uint32());break;case 6:o.channelId=e.int32();break;case 7:o.displayName=a[7].decode(e,e.uint32());break;case 8:o.isVisible=e.bool();break;case 9:o.isEnabled=e.bool();break;case 10:o.isChecked=e.bool();break;case 11:o.layerMenuIconPath=e.string();break;case 12:o.description=a[12].decode(e,e.uint32());break;case 13:o.lookAt=a[13].decode(e,e.uint32());break;case 15:o.assetUuid=e.string();break;case 16:o.isSaveLocked=e.bool();break;case 17:o.children&&o.children.length||(o.children=[]),o.children.push(a[16].decode(e,e.uint32()));break;case 18:o.clientConfigScriptName=e.string();break;case 19:o.dioramaDataChannelBase=e.int32();break;case 20:o.replicaDataChannelBase=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.featureType)switch(e.featureType){default:return"featureType: enum value expected";case 1:case 2:case 3:case 4:}if(void 0!==e.kmlUrl&&null!==e.kmlUrl){var t=a[1].verify(e.kmlUrl);if(t)return"kmlUrl."+t}if(void 0!==e.databaseUrl&&!r.isString(e.databaseUrl))return"databaseUrl: string expected";if(void 0!==e.layer&&null!==e.layer){var t=a[3].verify(e.layer);if(t)return"layer."+t}if(void 0!==e.folder&&null!==e.folder){var t=a[4].verify(e.folder);if(t)return"folder."+t}if(void 0!==e.requirement&&null!==e.requirement){var t=a[5].verify(e.requirement);if(t)return"requirement."+t}if(!r.isInteger(e.channelId))return"channelId: integer expected";if(void 0!==e.displayName&&null!==e.displayName){var t=a[7].verify(e.displayName);if(t)return"displayName."+t}if(void 0!==e.isVisible&&"boolean"!=typeof e.isVisible)return"isVisible: boolean expected";if(void 0!==e.isEnabled&&"boolean"!=typeof e.isEnabled)return"isEnabled: boolean expected";if(void 0!==e.isChecked&&"boolean"!=typeof e.isChecked)return"isChecked: boolean expected";if(void 0!==e.layerMenuIconPath&&!r.isString(e.layerMenuIconPath))return"layerMenuIconPath: string expected";if(void 0!==e.description&&null!==e.description){var t=a[12].verify(e.description);if(t)return"description."+t}if(void 0!==e.lookAt&&null!==e.lookAt){var t=a[13].verify(e.lookAt);if(t)return"lookAt."+t}if(void 0!==e.assetUuid&&!r.isString(e.assetUuid))return"assetUuid: string expected";if(void 0!==e.isSaveLocked&&"boolean"!=typeof e.isSaveLocked)return"isSaveLocked: boolean expected";if(void 0!==e.children){if(!Array.isArray(e.children))return"children: array expected";for(var i=0;i>>3){case 1:o.countryCode=e.string();break;case 2:o.domainName=e.string();break;case 3:if(o.supportedFeatures&&o.supportedFeatures.length||(o.supportedFeatures=[]),2==(7&a))for(var s=e.uint32()+e.pos;e.pos>>3){case 1:o.disableDiskCache=e.bool();break;case 2:o.disableEmbeddedBrowserVista=e.bool();break;case 3:o.drawAtmosphere=e.bool();break;case 4:o.drawStars=e.bool();break;case 5:o.shaderFilePrefix=e.string();break;case 6:o.useProtobufQuadtreePackets=e.bool();break;case 7:o.useExtendedCopyrightIds=e.bool();break;case 8:o.precipitationsOptions=a[7].decode(e,e.uint32());break;case 9:o.captureOptions=a[8].decode(e,e.uint32());break;case 10:o.show_2dMapsIcon=e.bool();break;case 11:o.disableInternalBrowser=e.bool();break;case 12:o.internalBrowserBlacklist=e.string();break;case 13:o.internalBrowserOriginWhitelist=e.string();break;case 14:o.polarTileMergingLevel=e.int32();break;case 15:o.jsBridgeRequestWhitelist=e.string();break;case 16:o.mapsOptions=a[15].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.disableDiskCache&&"boolean"!=typeof e.disableDiskCache)return"disableDiskCache: boolean expected";if(void 0!==e.disableEmbeddedBrowserVista&&"boolean"!=typeof e.disableEmbeddedBrowserVista)return"disableEmbeddedBrowserVista: boolean expected";if(void 0!==e.drawAtmosphere&&"boolean"!=typeof e.drawAtmosphere)return"drawAtmosphere: boolean expected";if(void 0!==e.drawStars&&"boolean"!=typeof e.drawStars)return"drawStars: boolean expected";if(void 0!==e.shaderFilePrefix&&!r.isString(e.shaderFilePrefix))return"shaderFilePrefix: string expected";if(void 0!==e.useProtobufQuadtreePackets&&"boolean"!=typeof e.useProtobufQuadtreePackets)return"useProtobufQuadtreePackets: boolean expected";if(void 0!==e.useExtendedCopyrightIds&&"boolean"!=typeof e.useExtendedCopyrightIds)return"useExtendedCopyrightIds: boolean expected";if(void 0!==e.precipitationsOptions&&null!==e.precipitationsOptions){var t=a[7].verify(e.precipitationsOptions);if(t)return"precipitationsOptions."+t}if(void 0!==e.captureOptions&&null!==e.captureOptions){var t=a[8].verify(e.captureOptions);if(t)return"captureOptions."+t}if(void 0!==e.show_2dMapsIcon&&"boolean"!=typeof e.show_2dMapsIcon)return"show_2dMapsIcon: boolean expected";if(void 0!==e.disableInternalBrowser&&"boolean"!=typeof e.disableInternalBrowser)return"disableInternalBrowser: boolean expected";if(void 0!==e.internalBrowserBlacklist&&!r.isString(e.internalBrowserBlacklist))return"internalBrowserBlacklist: string expected";if(void 0!==e.internalBrowserOriginWhitelist&&!r.isString(e.internalBrowserOriginWhitelist))return"internalBrowserOriginWhitelist: string expected";if(void 0!==e.polarTileMergingLevel&&!r.isInteger(e.polarTileMergingLevel))return"polarTileMergingLevel: integer expected";if(void 0!==e.jsBridgeRequestWhitelist&&!r.isString(e.jsBridgeRequestWhitelist))return"jsBridgeRequestWhitelist: string expected";if(void 0!==e.mapsOptions&&null!==e.mapsOptions){var t=a[15].verify(e.mapsOptions);if(t)return"mapsOptions."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto)return e;var t=new n.keyhole.dbroot.ClientOptionsProto;if(void 0!==e.disableDiskCache&&null!==e.disableDiskCache&&(t.disableDiskCache=Boolean(e.disableDiskCache)),void 0!==e.disableEmbeddedBrowserVista&&null!==e.disableEmbeddedBrowserVista&&(t.disableEmbeddedBrowserVista=Boolean(e.disableEmbeddedBrowserVista)),void 0!==e.drawAtmosphere&&null!==e.drawAtmosphere&&(t.drawAtmosphere=Boolean(e.drawAtmosphere)),void 0!==e.drawStars&&null!==e.drawStars&&(t.drawStars=Boolean(e.drawStars)),void 0!==e.shaderFilePrefix&&null!==e.shaderFilePrefix&&(t.shaderFilePrefix=String(e.shaderFilePrefix)),void 0!==e.useProtobufQuadtreePackets&&null!==e.useProtobufQuadtreePackets&&(t.useProtobufQuadtreePackets=Boolean(e.useProtobufQuadtreePackets)),void 0!==e.useExtendedCopyrightIds&&null!==e.useExtendedCopyrightIds&&(t.useExtendedCopyrightIds=Boolean(e.useExtendedCopyrightIds)),void 0!==e.precipitationsOptions&&null!==e.precipitationsOptions){if("object"!=typeof e.precipitationsOptions)throw TypeError(".keyhole.dbroot.ClientOptionsProto.precipitationsOptions: object expected");t.precipitationsOptions=a[7].fromObject(e.precipitationsOptions)}if(void 0!==e.captureOptions&&null!==e.captureOptions){if("object"!=typeof e.captureOptions)throw TypeError(".keyhole.dbroot.ClientOptionsProto.captureOptions: object expected");t.captureOptions=a[8].fromObject(e.captureOptions)}if(void 0!==e.show_2dMapsIcon&&null!==e.show_2dMapsIcon&&(t.show_2dMapsIcon=Boolean(e.show_2dMapsIcon)),void 0!==e.disableInternalBrowser&&null!==e.disableInternalBrowser&&(t.disableInternalBrowser=Boolean(e.disableInternalBrowser)),void 0!==e.internalBrowserBlacklist&&null!==e.internalBrowserBlacklist&&(t.internalBrowserBlacklist=String(e.internalBrowserBlacklist)),void 0!==e.internalBrowserOriginWhitelist&&null!==e.internalBrowserOriginWhitelist&&(t.internalBrowserOriginWhitelist=String(e.internalBrowserOriginWhitelist)),void 0!==e.polarTileMergingLevel&&null!==e.polarTileMergingLevel&&(t.polarTileMergingLevel=0|e.polarTileMergingLevel),void 0!==e.jsBridgeRequestWhitelist&&null!==e.jsBridgeRequestWhitelist&&(t.jsBridgeRequestWhitelist=String(e.jsBridgeRequestWhitelist)),void 0!==e.mapsOptions&&null!==e.mapsOptions){if("object"!=typeof e.mapsOptions)throw TypeError(".keyhole.dbroot.ClientOptionsProto.mapsOptions: object expected");t.mapsOptions=a[15].fromObject(e.mapsOptions)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.disableDiskCache=!1,r.disableEmbeddedBrowserVista=!1,r.drawAtmosphere=!0,r.drawStars=!0,r.shaderFilePrefix="",r.useProtobufQuadtreePackets=!1,r.useExtendedCopyrightIds=!0,r.precipitationsOptions=null,r.captureOptions=null,r.show_2dMapsIcon=!0,r.disableInternalBrowser=!1,r.internalBrowserBlacklist="",r.internalBrowserOriginWhitelist="*",r.polarTileMergingLevel=0,r.jsBridgeRequestWhitelist="http://*.google.com/*",r.mapsOptions=null),void 0!==e.disableDiskCache&&null!==e.disableDiskCache&&e.hasOwnProperty("disableDiskCache")&&(r.disableDiskCache=e.disableDiskCache),void 0!==e.disableEmbeddedBrowserVista&&null!==e.disableEmbeddedBrowserVista&&e.hasOwnProperty("disableEmbeddedBrowserVista")&&(r.disableEmbeddedBrowserVista=e.disableEmbeddedBrowserVista),void 0!==e.drawAtmosphere&&null!==e.drawAtmosphere&&e.hasOwnProperty("drawAtmosphere")&&(r.drawAtmosphere=e.drawAtmosphere),void 0!==e.drawStars&&null!==e.drawStars&&e.hasOwnProperty("drawStars")&&(r.drawStars=e.drawStars),void 0!==e.shaderFilePrefix&&null!==e.shaderFilePrefix&&e.hasOwnProperty("shaderFilePrefix")&&(r.shaderFilePrefix=e.shaderFilePrefix),void 0!==e.useProtobufQuadtreePackets&&null!==e.useProtobufQuadtreePackets&&e.hasOwnProperty("useProtobufQuadtreePackets")&&(r.useProtobufQuadtreePackets=e.useProtobufQuadtreePackets),void 0!==e.useExtendedCopyrightIds&&null!==e.useExtendedCopyrightIds&&e.hasOwnProperty("useExtendedCopyrightIds")&&(r.useExtendedCopyrightIds=e.useExtendedCopyrightIds),void 0!==e.precipitationsOptions&&null!==e.precipitationsOptions&&e.hasOwnProperty("precipitationsOptions")&&(r.precipitationsOptions=a[7].toObject(e.precipitationsOptions,t)),void 0!==e.captureOptions&&null!==e.captureOptions&&e.hasOwnProperty("captureOptions")&&(r.captureOptions=a[8].toObject(e.captureOptions,t)),void 0!==e.show_2dMapsIcon&&null!==e.show_2dMapsIcon&&e.hasOwnProperty("show_2dMapsIcon")&&(r.show_2dMapsIcon=e.show_2dMapsIcon),void 0!==e.disableInternalBrowser&&null!==e.disableInternalBrowser&&e.hasOwnProperty("disableInternalBrowser")&&(r.disableInternalBrowser=e.disableInternalBrowser),void 0!==e.internalBrowserBlacklist&&null!==e.internalBrowserBlacklist&&e.hasOwnProperty("internalBrowserBlacklist")&&(r.internalBrowserBlacklist=e.internalBrowserBlacklist),void 0!==e.internalBrowserOriginWhitelist&&null!==e.internalBrowserOriginWhitelist&&e.hasOwnProperty("internalBrowserOriginWhitelist")&&(r.internalBrowserOriginWhitelist=e.internalBrowserOriginWhitelist),void 0!==e.polarTileMergingLevel&&null!==e.polarTileMergingLevel&&e.hasOwnProperty("polarTileMergingLevel")&&(r.polarTileMergingLevel=e.polarTileMergingLevel),void 0!==e.jsBridgeRequestWhitelist&&null!==e.jsBridgeRequestWhitelist&&e.hasOwnProperty("jsBridgeRequestWhitelist")&&(r.jsBridgeRequestWhitelist=e.jsBridgeRequestWhitelist),void 0!==e.mapsOptions&&null!==e.mapsOptions&&e.hasOwnProperty("mapsOptions")&&(r.mapsOptions=a[15].toObject(e.mapsOptions,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.PrecipitationsOptions=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.imageUrl=e.string();break;case 2:o.imageExpireTime=e.int32();break;case 3:o.maxColorDistance=e.int32();break;case 4:o.imageLevel=e.int32();break;case 5:o.weatherMapping&&o.weatherMapping.length||(o.weatherMapping=[]),o.weatherMapping.push(a[4].decode(e,e.uint32()));break;case 6:o.cloudsLayerUrl=e.string();break;case 7:o.animationDecelerationDelay=e.float();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.imageUrl&&!r.isString(e.imageUrl))return"imageUrl: string expected";if(void 0!==e.imageExpireTime&&!r.isInteger(e.imageExpireTime))return"imageExpireTime: integer expected";if(void 0!==e.maxColorDistance&&!r.isInteger(e.maxColorDistance))return"maxColorDistance: integer expected";if(void 0!==e.imageLevel&&!r.isInteger(e.imageLevel))return"imageLevel: integer expected";if(void 0!==e.weatherMapping){if(!Array.isArray(e.weatherMapping))return"weatherMapping: array expected";for(var t=0;t>>3){case 1:o.colorAbgr=e.uint32();break;case 2:o.weatherType=e.uint32();break;case 3:o.elongation=e.float();break;case 4:o.opacity=e.float();break;case 5:o.fogDensity=e.float();break;case 6:o.speed0=e.float();break;case 7:o.speed1=e.float();break;case 8:o.speed2=e.float();break;case 9:o.speed3=e.float();break;default:e.skipType(7&a)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isInteger(e.colorAbgr))return"colorAbgr: integer expected";switch(e.weatherType){default:return"weatherType: enum value expected";case 0:case 1:case 2:}return void 0!==e.elongation&&"number"!=typeof e.elongation?"elongation: number expected":void 0!==e.opacity&&"number"!=typeof e.opacity?"opacity: number expected":void 0!==e.fogDensity&&"number"!=typeof e.fogDensity?"fogDensity: number expected":void 0!==e.speed0&&"number"!=typeof e.speed0?"speed0: number expected":void 0!==e.speed1&&"number"!=typeof e.speed1?"speed1: number expected":void 0!==e.speed2&&"number"!=typeof e.speed2?"speed2: number expected":void 0!==e.speed3&&"number"!=typeof e.speed3?"speed3: number expected":null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping;switch(void 0!==e.colorAbgr&&null!==e.colorAbgr&&(t.colorAbgr=e.colorAbgr>>>0),e.weatherType){case"NO_PRECIPITATION":case 0:t.weatherType=0;break;case"RAIN":case 1:t.weatherType=1;break;case"SNOW":case 2:t.weatherType=2}return void 0!==e.elongation&&null!==e.elongation&&(t.elongation=Number(e.elongation)),void 0!==e.opacity&&null!==e.opacity&&(t.opacity=Number(e.opacity)),void 0!==e.fogDensity&&null!==e.fogDensity&&(t.fogDensity=Number(e.fogDensity)),void 0!==e.speed0&&null!==e.speed0&&(t.speed0=Number(e.speed0)),void 0!==e.speed1&&null!==e.speed1&&(t.speed1=Number(e.speed1)),void 0!==e.speed2&&null!==e.speed2&&(t.speed2=Number(e.speed2)),void 0!==e.speed3&&null!==e.speed3&&(t.speed3=Number(e.speed3)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.colorAbgr=0,r.weatherType=t.enums===String?"NO_PRECIPITATION":0,r.elongation=1,r.opacity=0,r.fogDensity=0,r.speed0=0,r.speed1=0,r.speed2=0,r.speed3=0),void 0!==e.colorAbgr&&null!==e.colorAbgr&&e.hasOwnProperty("colorAbgr")&&(r.colorAbgr=e.colorAbgr),void 0!==e.weatherType&&null!==e.weatherType&&e.hasOwnProperty("weatherType")&&(r.weatherType=t.enums===String?a[1][e.weatherType]:e.weatherType),void 0!==e.elongation&&null!==e.elongation&&e.hasOwnProperty("elongation")&&(r.elongation=e.elongation),void 0!==e.opacity&&null!==e.opacity&&e.hasOwnProperty("opacity")&&(r.opacity=e.opacity),void 0!==e.fogDensity&&null!==e.fogDensity&&e.hasOwnProperty("fogDensity")&&(r.fogDensity=e.fogDensity),void 0!==e.speed0&&null!==e.speed0&&e.hasOwnProperty("speed0")&&(r.speed0=e.speed0),void 0!==e.speed1&&null!==e.speed1&&e.hasOwnProperty("speed1")&&(r.speed1=e.speed1),void 0!==e.speed2&&null!==e.speed2&&e.hasOwnProperty("speed2")&&(r.speed2=e.speed2),void 0!==e.speed3&&null!==e.speed3&&e.hasOwnProperty("speed3")&&(r.speed3=e.speed3),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.WeatherType=function(){var e={},t=Object.create(e);return t.NO_PRECIPITATION=0,t.RAIN=1,t.SNOW=2,t}(),o}(),o}(),o.CaptureOptions=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.allowSaveAsImage=e.bool();break;case 2:o.maxFreeCaptureRes=e.int32();break;case 3:o.maxPremiumCaptureRes=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.allowSaveAsImage&&"boolean"!=typeof e.allowSaveAsImage?"allowSaveAsImage: boolean expected":void 0===e.maxFreeCaptureRes||r.isInteger(e.maxFreeCaptureRes)?void 0===e.maxPremiumCaptureRes||r.isInteger(e.maxPremiumCaptureRes)?null:"maxPremiumCaptureRes: integer expected":"maxFreeCaptureRes: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.CaptureOptions)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.CaptureOptions;return void 0!==e.allowSaveAsImage&&null!==e.allowSaveAsImage&&(t.allowSaveAsImage=Boolean(e.allowSaveAsImage)),void 0!==e.maxFreeCaptureRes&&null!==e.maxFreeCaptureRes&&(t.maxFreeCaptureRes=0|e.maxFreeCaptureRes),void 0!==e.maxPremiumCaptureRes&&null!==e.maxPremiumCaptureRes&&(t.maxPremiumCaptureRes=0|e.maxPremiumCaptureRes),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.allowSaveAsImage=!0,r.maxFreeCaptureRes=2400,r.maxPremiumCaptureRes=4800),void 0!==e.allowSaveAsImage&&null!==e.allowSaveAsImage&&e.hasOwnProperty("allowSaveAsImage")&&(r.allowSaveAsImage=e.allowSaveAsImage),void 0!==e.maxFreeCaptureRes&&null!==e.maxFreeCaptureRes&&e.hasOwnProperty("maxFreeCaptureRes")&&(r.maxFreeCaptureRes=e.maxFreeCaptureRes),void 0!==e.maxPremiumCaptureRes&&null!==e.maxPremiumCaptureRes&&e.hasOwnProperty("maxPremiumCaptureRes")&&(r.maxPremiumCaptureRes=e.maxPremiumCaptureRes),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.MapsOptions=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.enableMaps=e.bool();break;case 2:o.docsAutoDownloadEnabled=e.bool();break;case 3:o.docsAutoDownloadInterval=e.int32();break;case 4:o.docsAutoUploadEnabled=e.bool();break;case 5:o.docsAutoUploadDelay=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.enableMaps&&"boolean"!=typeof e.enableMaps?"enableMaps: boolean expected":void 0!==e.docsAutoDownloadEnabled&&"boolean"!=typeof e.docsAutoDownloadEnabled?"docsAutoDownloadEnabled: boolean expected":void 0===e.docsAutoDownloadInterval||r.isInteger(e.docsAutoDownloadInterval)?void 0!==e.docsAutoUploadEnabled&&"boolean"!=typeof e.docsAutoUploadEnabled?"docsAutoUploadEnabled: boolean expected":void 0===e.docsAutoUploadDelay||r.isInteger(e.docsAutoUploadDelay)?null:"docsAutoUploadDelay: integer expected":"docsAutoDownloadInterval: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.MapsOptions)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.MapsOptions;return void 0!==e.enableMaps&&null!==e.enableMaps&&(t.enableMaps=Boolean(e.enableMaps)),void 0!==e.docsAutoDownloadEnabled&&null!==e.docsAutoDownloadEnabled&&(t.docsAutoDownloadEnabled=Boolean(e.docsAutoDownloadEnabled)),void 0!==e.docsAutoDownloadInterval&&null!==e.docsAutoDownloadInterval&&(t.docsAutoDownloadInterval=0|e.docsAutoDownloadInterval),void 0!==e.docsAutoUploadEnabled&&null!==e.docsAutoUploadEnabled&&(t.docsAutoUploadEnabled=Boolean(e.docsAutoUploadEnabled)),void 0!==e.docsAutoUploadDelay&&null!==e.docsAutoUploadDelay&&(t.docsAutoUploadDelay=0|e.docsAutoUploadDelay),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.enableMaps=!1,r.docsAutoDownloadEnabled=!1,r.docsAutoDownloadInterval=0,r.docsAutoUploadEnabled=!1,r.docsAutoUploadDelay=0),void 0!==e.enableMaps&&null!==e.enableMaps&&e.hasOwnProperty("enableMaps")&&(r.enableMaps=e.enableMaps),void 0!==e.docsAutoDownloadEnabled&&null!==e.docsAutoDownloadEnabled&&e.hasOwnProperty("docsAutoDownloadEnabled")&&(r.docsAutoDownloadEnabled=e.docsAutoDownloadEnabled),void 0!==e.docsAutoDownloadInterval&&null!==e.docsAutoDownloadInterval&&e.hasOwnProperty("docsAutoDownloadInterval")&&(r.docsAutoDownloadInterval=e.docsAutoDownloadInterval),void 0!==e.docsAutoUploadEnabled&&null!==e.docsAutoUploadEnabled&&e.hasOwnProperty("docsAutoUploadEnabled")&&(r.docsAutoUploadEnabled=e.docsAutoUploadEnabled),void 0!==e.docsAutoUploadDelay&&null!==e.docsAutoUploadDelay&&e.hasOwnProperty("docsAutoUploadDelay")&&(r.docsAutoUploadDelay=e.docsAutoUploadDelay),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)}, -i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o}(),o.FetchingOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.maxRequestsPerQuery=e.int32();break;case 12:o.forceMaxRequestsPerQuery=e.bool();break;case 13:o.sortBatches=e.bool();break;case 2:o.maxDrawable=e.int32();break;case 3:o.maxImagery=e.int32();break;case 4:o.maxTerrain=e.int32();break;case 5:o.maxQuadtree=e.int32();break;case 6:o.maxDioramaMetadata=e.int32();break;case 7:o.maxDioramaData=e.int32();break;case 8:o.maxConsumerFetchRatio=e.float();break;case 9:o.maxProEcFetchRatio=e.float();break;case 10:o.safeOverallQps=e.float();break;case 11:o.safeImageryQps=e.float();break;case 14:o.domainsForHttps=e.string();break;case 15:o.hostsForHttp=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.maxRequestsPerQuery||r.isInteger(e.maxRequestsPerQuery)?void 0!==e.forceMaxRequestsPerQuery&&"boolean"!=typeof e.forceMaxRequestsPerQuery?"forceMaxRequestsPerQuery: boolean expected":void 0!==e.sortBatches&&"boolean"!=typeof e.sortBatches?"sortBatches: boolean expected":void 0===e.maxDrawable||r.isInteger(e.maxDrawable)?void 0===e.maxImagery||r.isInteger(e.maxImagery)?void 0===e.maxTerrain||r.isInteger(e.maxTerrain)?void 0===e.maxQuadtree||r.isInteger(e.maxQuadtree)?void 0===e.maxDioramaMetadata||r.isInteger(e.maxDioramaMetadata)?void 0===e.maxDioramaData||r.isInteger(e.maxDioramaData)?void 0!==e.maxConsumerFetchRatio&&"number"!=typeof e.maxConsumerFetchRatio?"maxConsumerFetchRatio: number expected":void 0!==e.maxProEcFetchRatio&&"number"!=typeof e.maxProEcFetchRatio?"maxProEcFetchRatio: number expected":void 0!==e.safeOverallQps&&"number"!=typeof e.safeOverallQps?"safeOverallQps: number expected":void 0!==e.safeImageryQps&&"number"!=typeof e.safeImageryQps?"safeImageryQps: number expected":void 0===e.domainsForHttps||r.isString(e.domainsForHttps)?void 0===e.hostsForHttp||r.isString(e.hostsForHttp)?null:"hostsForHttp: string expected":"domainsForHttps: string expected":"maxDioramaData: integer expected":"maxDioramaMetadata: integer expected":"maxQuadtree: integer expected":"maxTerrain: integer expected":"maxImagery: integer expected":"maxDrawable: integer expected":"maxRequestsPerQuery: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.FetchingOptionsProto)return e;var t=new n.keyhole.dbroot.FetchingOptionsProto;return void 0!==e.maxRequestsPerQuery&&null!==e.maxRequestsPerQuery&&(t.maxRequestsPerQuery=0|e.maxRequestsPerQuery),void 0!==e.forceMaxRequestsPerQuery&&null!==e.forceMaxRequestsPerQuery&&(t.forceMaxRequestsPerQuery=Boolean(e.forceMaxRequestsPerQuery)),void 0!==e.sortBatches&&null!==e.sortBatches&&(t.sortBatches=Boolean(e.sortBatches)),void 0!==e.maxDrawable&&null!==e.maxDrawable&&(t.maxDrawable=0|e.maxDrawable),void 0!==e.maxImagery&&null!==e.maxImagery&&(t.maxImagery=0|e.maxImagery),void 0!==e.maxTerrain&&null!==e.maxTerrain&&(t.maxTerrain=0|e.maxTerrain),void 0!==e.maxQuadtree&&null!==e.maxQuadtree&&(t.maxQuadtree=0|e.maxQuadtree),void 0!==e.maxDioramaMetadata&&null!==e.maxDioramaMetadata&&(t.maxDioramaMetadata=0|e.maxDioramaMetadata),void 0!==e.maxDioramaData&&null!==e.maxDioramaData&&(t.maxDioramaData=0|e.maxDioramaData),void 0!==e.maxConsumerFetchRatio&&null!==e.maxConsumerFetchRatio&&(t.maxConsumerFetchRatio=Number(e.maxConsumerFetchRatio)),void 0!==e.maxProEcFetchRatio&&null!==e.maxProEcFetchRatio&&(t.maxProEcFetchRatio=Number(e.maxProEcFetchRatio)),void 0!==e.safeOverallQps&&null!==e.safeOverallQps&&(t.safeOverallQps=Number(e.safeOverallQps)),void 0!==e.safeImageryQps&&null!==e.safeImageryQps&&(t.safeImageryQps=Number(e.safeImageryQps)),void 0!==e.domainsForHttps&&null!==e.domainsForHttps&&(t.domainsForHttps=String(e.domainsForHttps)),void 0!==e.hostsForHttp&&null!==e.hostsForHttp&&(t.hostsForHttp=String(e.hostsForHttp)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.maxRequestsPerQuery=1,r.forceMaxRequestsPerQuery=!1,r.sortBatches=!1,r.maxDrawable=2,r.maxImagery=2,r.maxTerrain=5,r.maxQuadtree=5,r.maxDioramaMetadata=1,r.maxDioramaData=0,r.maxConsumerFetchRatio=1,r.maxProEcFetchRatio=0,r.safeOverallQps=0,r.safeImageryQps=0,r.domainsForHttps="google.com gstatic.com",r.hostsForHttp=""),void 0!==e.maxRequestsPerQuery&&null!==e.maxRequestsPerQuery&&e.hasOwnProperty("maxRequestsPerQuery")&&(r.maxRequestsPerQuery=e.maxRequestsPerQuery),void 0!==e.forceMaxRequestsPerQuery&&null!==e.forceMaxRequestsPerQuery&&e.hasOwnProperty("forceMaxRequestsPerQuery")&&(r.forceMaxRequestsPerQuery=e.forceMaxRequestsPerQuery),void 0!==e.sortBatches&&null!==e.sortBatches&&e.hasOwnProperty("sortBatches")&&(r.sortBatches=e.sortBatches),void 0!==e.maxDrawable&&null!==e.maxDrawable&&e.hasOwnProperty("maxDrawable")&&(r.maxDrawable=e.maxDrawable),void 0!==e.maxImagery&&null!==e.maxImagery&&e.hasOwnProperty("maxImagery")&&(r.maxImagery=e.maxImagery),void 0!==e.maxTerrain&&null!==e.maxTerrain&&e.hasOwnProperty("maxTerrain")&&(r.maxTerrain=e.maxTerrain),void 0!==e.maxQuadtree&&null!==e.maxQuadtree&&e.hasOwnProperty("maxQuadtree")&&(r.maxQuadtree=e.maxQuadtree),void 0!==e.maxDioramaMetadata&&null!==e.maxDioramaMetadata&&e.hasOwnProperty("maxDioramaMetadata")&&(r.maxDioramaMetadata=e.maxDioramaMetadata),void 0!==e.maxDioramaData&&null!==e.maxDioramaData&&e.hasOwnProperty("maxDioramaData")&&(r.maxDioramaData=e.maxDioramaData),void 0!==e.maxConsumerFetchRatio&&null!==e.maxConsumerFetchRatio&&e.hasOwnProperty("maxConsumerFetchRatio")&&(r.maxConsumerFetchRatio=e.maxConsumerFetchRatio),void 0!==e.maxProEcFetchRatio&&null!==e.maxProEcFetchRatio&&e.hasOwnProperty("maxProEcFetchRatio")&&(r.maxProEcFetchRatio=e.maxProEcFetchRatio),void 0!==e.safeOverallQps&&null!==e.safeOverallQps&&e.hasOwnProperty("safeOverallQps")&&(r.safeOverallQps=e.safeOverallQps),void 0!==e.safeImageryQps&&null!==e.safeImageryQps&&e.hasOwnProperty("safeImageryQps")&&(r.safeImageryQps=e.safeImageryQps),void 0!==e.domainsForHttps&&null!==e.domainsForHttps&&e.hasOwnProperty("domainsForHttps")&&(r.domainsForHttps=e.domainsForHttps),void 0!==e.hostsForHttp&&null!==e.hostsForHttp&&e.hasOwnProperty("hostsForHttp")&&(r.hostsForHttp=e.hostsForHttp),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.TimeMachineOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.serverUrl=e.string();break;case 2:o.isTimemachine=e.bool();break;case 3:o.dwellTimeMs=e.int32();break;case 4:o.discoverabilityAltitudeMeters=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.serverUrl||r.isString(e.serverUrl)?void 0!==e.isTimemachine&&"boolean"!=typeof e.isTimemachine?"isTimemachine: boolean expected":void 0===e.dwellTimeMs||r.isInteger(e.dwellTimeMs)?void 0===e.discoverabilityAltitudeMeters||r.isInteger(e.discoverabilityAltitudeMeters)?null:"discoverabilityAltitudeMeters: integer expected":"dwellTimeMs: integer expected":"serverUrl: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.TimeMachineOptionsProto)return e;var t=new n.keyhole.dbroot.TimeMachineOptionsProto;return void 0!==e.serverUrl&&null!==e.serverUrl&&(t.serverUrl=String(e.serverUrl)),void 0!==e.isTimemachine&&null!==e.isTimemachine&&(t.isTimemachine=Boolean(e.isTimemachine)),void 0!==e.dwellTimeMs&&null!==e.dwellTimeMs&&(t.dwellTimeMs=0|e.dwellTimeMs),void 0!==e.discoverabilityAltitudeMeters&&null!==e.discoverabilityAltitudeMeters&&(t.discoverabilityAltitudeMeters=0|e.discoverabilityAltitudeMeters),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.serverUrl="",r.isTimemachine=!1,r.dwellTimeMs=500,r.discoverabilityAltitudeMeters=15e3),void 0!==e.serverUrl&&null!==e.serverUrl&&e.hasOwnProperty("serverUrl")&&(r.serverUrl=e.serverUrl),void 0!==e.isTimemachine&&null!==e.isTimemachine&&e.hasOwnProperty("isTimemachine")&&(r.isTimemachine=e.isTimemachine),void 0!==e.dwellTimeMs&&null!==e.dwellTimeMs&&e.hasOwnProperty("dwellTimeMs")&&(r.dwellTimeMs=e.dwellTimeMs),void 0!==e.discoverabilityAltitudeMeters&&null!==e.discoverabilityAltitudeMeters&&e.hasOwnProperty("discoverabilityAltitudeMeters")&&(r.discoverabilityAltitudeMeters=e.discoverabilityAltitudeMeters),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.AutopiaOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.metadataServerUrl=e.string();break;case 2:o.depthmapServerUrl=e.string();break;case 3:o.coverageOverlayUrl=e.string();break;case 4:o.maxImageryQps=e.float();break;case 5:o.maxMetadataDepthmapQps=e.float();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.metadataServerUrl||r.isString(e.metadataServerUrl)?void 0===e.depthmapServerUrl||r.isString(e.depthmapServerUrl)?void 0===e.coverageOverlayUrl||r.isString(e.coverageOverlayUrl)?void 0!==e.maxImageryQps&&"number"!=typeof e.maxImageryQps?"maxImageryQps: number expected":void 0!==e.maxMetadataDepthmapQps&&"number"!=typeof e.maxMetadataDepthmapQps?"maxMetadataDepthmapQps: number expected":null:"coverageOverlayUrl: string expected":"depthmapServerUrl: string expected":"metadataServerUrl: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.AutopiaOptionsProto)return e;var t=new n.keyhole.dbroot.AutopiaOptionsProto;return void 0!==e.metadataServerUrl&&null!==e.metadataServerUrl&&(t.metadataServerUrl=String(e.metadataServerUrl)),void 0!==e.depthmapServerUrl&&null!==e.depthmapServerUrl&&(t.depthmapServerUrl=String(e.depthmapServerUrl)),void 0!==e.coverageOverlayUrl&&null!==e.coverageOverlayUrl&&(t.coverageOverlayUrl=String(e.coverageOverlayUrl)),void 0!==e.maxImageryQps&&null!==e.maxImageryQps&&(t.maxImageryQps=Number(e.maxImageryQps)),void 0!==e.maxMetadataDepthmapQps&&null!==e.maxMetadataDepthmapQps&&(t.maxMetadataDepthmapQps=Number(e.maxMetadataDepthmapQps)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.metadataServerUrl="http://cbk0.google.com/cbk",r.depthmapServerUrl="http://cbk0.google.com/cbk",r.coverageOverlayUrl="",r.maxImageryQps=0,r.maxMetadataDepthmapQps=0),void 0!==e.metadataServerUrl&&null!==e.metadataServerUrl&&e.hasOwnProperty("metadataServerUrl")&&(r.metadataServerUrl=e.metadataServerUrl),void 0!==e.depthmapServerUrl&&null!==e.depthmapServerUrl&&e.hasOwnProperty("depthmapServerUrl")&&(r.depthmapServerUrl=e.depthmapServerUrl),void 0!==e.coverageOverlayUrl&&null!==e.coverageOverlayUrl&&e.hasOwnProperty("coverageOverlayUrl")&&(r.coverageOverlayUrl=e.coverageOverlayUrl),void 0!==e.maxImageryQps&&null!==e.maxImageryQps&&e.hasOwnProperty("maxImageryQps")&&(r.maxImageryQps=e.maxImageryQps),void 0!==e.maxMetadataDepthmapQps&&null!==e.maxMetadataDepthmapQps&&e.hasOwnProperty("maxMetadataDepthmapQps")&&(r.maxMetadataDepthmapQps=e.maxMetadataDepthmapQps),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.CSIOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.samplingPercentage=e.int32();break;case 2:o.experimentId=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.samplingPercentage||r.isInteger(e.samplingPercentage)?void 0===e.experimentId||r.isString(e.experimentId)?null:"experimentId: string expected":"samplingPercentage: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.CSIOptionsProto)return e;var t=new n.keyhole.dbroot.CSIOptionsProto;return void 0!==e.samplingPercentage&&null!==e.samplingPercentage&&(t.samplingPercentage=0|e.samplingPercentage),void 0!==e.experimentId&&null!==e.experimentId&&(t.experimentId=String(e.experimentId)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.samplingPercentage=0,r.experimentId=""),void 0!==e.samplingPercentage&&null!==e.samplingPercentage&&e.hasOwnProperty("samplingPercentage")&&(r.samplingPercentage=e.samplingPercentage),void 0!==e.experimentId&&null!==e.experimentId&&e.hasOwnProperty("experimentId")&&(r.experimentId=e.experimentId),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.SearchTabProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.isVisible=e.bool();break;case 2:o.tabLabel=a[1].decode(e,e.uint32());break;case 3:o.baseUrl=e.string();break;case 4:o.viewportPrefix=e.string();break;case 5:o.inputBox&&o.inputBox.length||(o.inputBox=[]),o.inputBox.push(a[4].decode(e,e.uint32()));break;case 6:o.requirement=a[5].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if("boolean"!=typeof e.isVisible)return"isVisible: boolean expected";if(void 0!==e.tabLabel&&null!==e.tabLabel){var t=a[1].verify(e.tabLabel);if(t)return"tabLabel."+t}if(void 0!==e.baseUrl&&!r.isString(e.baseUrl))return"baseUrl: string expected";if(void 0!==e.viewportPrefix&&!r.isString(e.viewportPrefix))return"viewportPrefix: string expected";if(void 0!==e.inputBox){if(!Array.isArray(e.inputBox))return"inputBox: array expected";for(var i=0;i>>3){case 1:o.label=a[0].decode(e,e.uint32());break;case 2:o.queryVerb=e.string();break;case 3:o.queryPrepend=e.string();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";var t=a[0].verify(e.label);return t?"label."+t:r.isString(e.queryVerb)?void 0===e.queryPrepend||r.isString(e.queryPrepend)?null:"queryPrepend: string expected":"queryVerb: string expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.SearchTabProto.InputBoxInfo)return e;var t=new n.keyhole.dbroot.SearchTabProto.InputBoxInfo;if(void 0!==e.label&&null!==e.label){if("object"!=typeof e.label)throw TypeError(".keyhole.dbroot.SearchTabProto.InputBoxInfo.label: object expected");t.label=a[0].fromObject(e.label)}return void 0!==e.queryVerb&&null!==e.queryVerb&&(t.queryVerb=String(e.queryVerb)),void 0!==e.queryPrepend&&null!==e.queryPrepend&&(t.queryPrepend=String(e.queryPrepend)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.label=null,r.queryVerb="",r.queryPrepend=""),void 0!==e.label&&null!==e.label&&e.hasOwnProperty("label")&&(r.label=a[0].toObject(e.label,t)),void 0!==e.queryVerb&&null!==e.queryVerb&&e.hasOwnProperty("queryVerb")&&(r.queryVerb=e.queryVerb),void 0!==e.queryPrepend&&null!==e.queryPrepend&&e.hasOwnProperty("queryPrepend")&&(r.queryPrepend=e.queryPrepend),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o}(),o.CobrandProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.logoUrl=e.string();break;case 2:o.xCoord=a[1].decode(e,e.uint32());break;case 3:o.yCoord=a[2].decode(e,e.uint32());break;case 4:o.tiePoint=e.uint32();break;case 5:o.screenSize=e.double();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.logoUrl))return"logoUrl: string expected";if(void 0!==e.xCoord&&null!==e.xCoord){var t=a[1].verify(e.xCoord);if(t)return"xCoord."+t}if(void 0!==e.yCoord&&null!==e.yCoord){var t=a[2].verify(e.yCoord);if(t)return"yCoord."+t}if(void 0!==e.tiePoint)switch(e.tiePoint){default:return"tiePoint: enum value expected";case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:}return void 0!==e.screenSize&&"number"!=typeof e.screenSize?"screenSize: number expected":null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.CobrandProto)return e;var t=new n.keyhole.dbroot.CobrandProto;if(void 0!==e.logoUrl&&null!==e.logoUrl&&(t.logoUrl=String(e.logoUrl)),void 0!==e.xCoord&&null!==e.xCoord){if("object"!=typeof e.xCoord)throw TypeError(".keyhole.dbroot.CobrandProto.xCoord: object expected");t.xCoord=a[1].fromObject(e.xCoord)}if(void 0!==e.yCoord&&null!==e.yCoord){if("object"!=typeof e.yCoord)throw TypeError(".keyhole.dbroot.CobrandProto.yCoord: object expected");t.yCoord=a[2].fromObject(e.yCoord)}switch(e.tiePoint){case"TOP_LEFT":case 0:t.tiePoint=0;break;case"TOP_CENTER":case 1:t.tiePoint=1;break;case"TOP_RIGHT":case 2:t.tiePoint=2;break;case"MID_LEFT":case 3:t.tiePoint=3;break;case"MID_CENTER":case 4:t.tiePoint=4;break;case"MID_RIGHT":case 5:t.tiePoint=5;break;case"BOTTOM_LEFT":case 6:t.tiePoint=6;break;case"BOTTOM_CENTER":case 7:t.tiePoint=7;break;case"BOTTOM_RIGHT":case 8:t.tiePoint=8}return void 0!==e.screenSize&&null!==e.screenSize&&(t.screenSize=Number(e.screenSize)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.logoUrl="",r.xCoord=null,r.yCoord=null,r.tiePoint=t.enums===String?"BOTTOM_LEFT":6,r.screenSize=0),void 0!==e.logoUrl&&null!==e.logoUrl&&e.hasOwnProperty("logoUrl")&&(r.logoUrl=e.logoUrl),void 0!==e.xCoord&&null!==e.xCoord&&e.hasOwnProperty("xCoord")&&(r.xCoord=a[1].toObject(e.xCoord,t)),void 0!==e.yCoord&&null!==e.yCoord&&e.hasOwnProperty("yCoord")&&(r.yCoord=a[2].toObject(e.yCoord,t)),void 0!==e.tiePoint&&null!==e.tiePoint&&e.hasOwnProperty("tiePoint")&&(r.tiePoint=t.enums===String?a[3][e.tiePoint]:e.tiePoint),void 0!==e.screenSize&&null!==e.screenSize&&e.hasOwnProperty("screenSize")&&(r.screenSize=e.screenSize),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.Coord=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.value=e.double();break;case 2:o.isRelative=e.bool();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":"number"!=typeof e.value?"value: number expected":void 0!==e.isRelative&&"boolean"!=typeof e.isRelative?"isRelative: boolean expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.CobrandProto.Coord)return e;var t=new n.keyhole.dbroot.CobrandProto.Coord;return void 0!==e.value&&null!==e.value&&(t.value=Number(e.value)),void 0!==e.isRelative&&null!==e.isRelative&&(t.isRelative=Boolean(e.isRelative)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.value=0,r.isRelative=!1),void 0!==e.value&&null!==e.value&&e.hasOwnProperty("value")&&(r.value=e.value),void 0!==e.isRelative&&null!==e.isRelative&&e.hasOwnProperty("isRelative")&&(r.isRelative=e.isRelative),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.TiePoint=function(){var e={},t=Object.create(e);return t.TOP_LEFT=0,t.TOP_CENTER=1,t.TOP_RIGHT=2,t.MID_LEFT=3,t.MID_CENTER=4,t.MID_RIGHT=5,t.BOTTOM_LEFT=6,t.BOTTOM_CENTER=7,t.BOTTOM_RIGHT=8,t}(),o}(),o.DatabaseDescriptionProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.databaseName=a[0].decode(e,e.uint32());break;case 2:o.databaseUrl=e.string();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.databaseName&&null!==e.databaseName){var t=a[0].verify(e.databaseName);if(t)return"databaseName."+t}return r.isString(e.databaseUrl)?null:"databaseUrl: string expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DatabaseDescriptionProto)return e;var t=new n.keyhole.dbroot.DatabaseDescriptionProto;if(void 0!==e.databaseName&&null!==e.databaseName){if("object"!=typeof e.databaseName)throw TypeError(".keyhole.dbroot.DatabaseDescriptionProto.databaseName: object expected");t.databaseName=a[0].fromObject(e.databaseName)}return void 0!==e.databaseUrl&&null!==e.databaseUrl&&(t.databaseUrl=String(e.databaseUrl)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.databaseName=null,r.databaseUrl=""),void 0!==e.databaseName&&null!==e.databaseName&&e.hasOwnProperty("databaseName")&&(r.databaseName=a[0].toObject(e.databaseName,t)),void 0!==e.databaseUrl&&null!==e.databaseUrl&&e.hasOwnProperty("databaseUrl")&&(r.databaseUrl=e.databaseUrl),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.ConfigScriptProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.scriptName=e.string();break;case 2:o.scriptData=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isString(e.scriptName)?r.isString(e.scriptData)?null:"scriptData: string expected":"scriptName: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ConfigScriptProto)return e;var t=new n.keyhole.dbroot.ConfigScriptProto;return void 0!==e.scriptName&&null!==e.scriptName&&(t.scriptName=String(e.scriptName)),void 0!==e.scriptData&&null!==e.scriptData&&(t.scriptData=String(e.scriptData)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.scriptName="",r.scriptData=""),void 0!==e.scriptName&&null!==e.scriptName&&e.hasOwnProperty("scriptName")&&(r.scriptName=e.scriptName),void 0!==e.scriptData&&null!==e.scriptData&&e.hasOwnProperty("scriptData")&&(r.scriptData=e.scriptData),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.SwoopParamsProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.startDistInMeters=e.double();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.startDistInMeters&&"number"!=typeof e.startDistInMeters?"startDistInMeters: number expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.SwoopParamsProto)return e;var t=new n.keyhole.dbroot.SwoopParamsProto;return void 0!==e.startDistInMeters&&null!==e.startDistInMeters&&(t.startDistInMeters=Number(e.startDistInMeters)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.startDistInMeters=0),void 0!==e.startDistInMeters&&null!==e.startDistInMeters&&e.hasOwnProperty("startDistInMeters")&&(r.startDistInMeters=e.startDistInMeters),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.PostingServerProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:a.name=o[0].decode(e,e.uint32());break;case 2:a.baseUrl=o[1].decode(e,e.uint32());break;case 3:a.postWizardPath=o[2].decode(e,e.uint32());break;case 4:a.fileSubmitPath=o[3].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.name&&null!==e.name){var t=o[0].verify(e.name);if(t)return"name."+t}if(void 0!==e.baseUrl&&null!==e.baseUrl){var t=o[1].verify(e.baseUrl);if(t)return"baseUrl."+t}if(void 0!==e.postWizardPath&&null!==e.postWizardPath){var t=o[2].verify(e.postWizardPath);if(t)return"postWizardPath."+t}if(void 0!==e.fileSubmitPath&&null!==e.fileSubmitPath){var t=o[3].verify(e.fileSubmitPath);if(t)return"fileSubmitPath."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PostingServerProto)return e;var t=new n.keyhole.dbroot.PostingServerProto;if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.PostingServerProto.name: object expected");t.name=o[0].fromObject(e.name)}if(void 0!==e.baseUrl&&null!==e.baseUrl){if("object"!=typeof e.baseUrl)throw TypeError(".keyhole.dbroot.PostingServerProto.baseUrl: object expected");t.baseUrl=o[1].fromObject(e.baseUrl)}if(void 0!==e.postWizardPath&&null!==e.postWizardPath){if("object"!=typeof e.postWizardPath)throw TypeError(".keyhole.dbroot.PostingServerProto.postWizardPath: object expected");t.postWizardPath=o[2].fromObject(e.postWizardPath)}if(void 0!==e.fileSubmitPath&&null!==e.fileSubmitPath){if("object"!=typeof e.fileSubmitPath)throw TypeError(".keyhole.dbroot.PostingServerProto.fileSubmitPath: object expected");t.fileSubmitPath=o[3].fromObject(e.fileSubmitPath)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={}) -;var r={};return t.defaults&&(r.name=null,r.baseUrl=null,r.postWizardPath=null,r.fileSubmitPath=null),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=o[0].toObject(e.name,t)),void 0!==e.baseUrl&&null!==e.baseUrl&&e.hasOwnProperty("baseUrl")&&(r.baseUrl=o[1].toObject(e.baseUrl,t)),void 0!==e.postWizardPath&&null!==e.postWizardPath&&e.hasOwnProperty("postWizardPath")&&(r.postWizardPath=o[2].toObject(e.postWizardPath,t)),void 0!==e.fileSubmitPath&&null!==e.fileSubmitPath&&e.hasOwnProperty("fileSubmitPath")&&(r.fileSubmitPath=o[3].toObject(e.fileSubmitPath,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.PlanetaryDatabaseProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:a.url=o[0].decode(e,e.uint32());break;case 2:a.name=o[1].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";var t=o[0].verify(e.url);if(t)return"url."+t;var t=o[1].verify(e.name);return t?"name."+t:null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PlanetaryDatabaseProto)return e;var t=new n.keyhole.dbroot.PlanetaryDatabaseProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.url: object expected");t.url=o[0].fromObject(e.url)}if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.name: object expected");t.name=o[1].fromObject(e.name)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.name=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=o[1].toObject(e.name,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.LogServerProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.url=a[0].decode(e,e.uint32());break;case 2:o.enable=e.bool();break;case 3:o.throttlingFactor=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=a[0].verify(e.url);if(t)return"url."+t}return void 0!==e.enable&&"boolean"!=typeof e.enable?"enable: boolean expected":void 0===e.throttlingFactor||r.isInteger(e.throttlingFactor)?null:"throttlingFactor: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.LogServerProto)return e;var t=new n.keyhole.dbroot.LogServerProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.LogServerProto.url: object expected");t.url=a[0].fromObject(e.url)}return void 0!==e.enable&&null!==e.enable&&(t.enable=Boolean(e.enable)),void 0!==e.throttlingFactor&&null!==e.throttlingFactor&&(t.throttlingFactor=0|e.throttlingFactor),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.enable=!1,r.throttlingFactor=1),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=a[0].toObject(e.url,t)),void 0!==e.enable&&null!==e.enable&&e.hasOwnProperty("enable")&&(r.enable=e.enable),void 0!==e.throttlingFactor&&null!==e.throttlingFactor&&e.hasOwnProperty("throttlingFactor")&&(r.throttlingFactor=e.throttlingFactor),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.EndSnippetProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.model=a[0].decode(e,e.uint32());break;case 2:o.authServerUrl=a[1].decode(e,e.uint32());break;case 3:o.disableAuthentication=e.bool();break;case 4:o.mfeDomains&&o.mfeDomains.length||(o.mfeDomains=[]),o.mfeDomains.push(a[3].decode(e,e.uint32()));break;case 5:o.mfeLangParam=e.string();break;case 6:o.adsUrlPatterns=e.string();break;case 7:o.reverseGeocoderUrl=a[6].decode(e,e.uint32());break;case 8:o.reverseGeocoderProtocolVersion=e.int32();break;case 9:o.skyDatabaseIsAvailable=e.bool();break;case 10:o.skyDatabaseUrl=a[9].decode(e,e.uint32());break;case 11:o.defaultWebPageIntlUrl=a[10].decode(e,e.uint32());break;case 12:o.numStartUpTips=e.int32();break;case 13:o.startUpTipsUrl=a[12].decode(e,e.uint32());break;case 51:o.numProStartUpTips=e.int32();break;case 52:o.proStartUpTipsUrl=a[14].decode(e,e.uint32());break;case 64:o.startupTipsIntlUrl=a[15].decode(e,e.uint32());break;case 14:o.userGuideIntlUrl=a[16].decode(e,e.uint32());break;case 15:o.supportCenterIntlUrl=a[17].decode(e,e.uint32());break;case 16:o.businessListingIntlUrl=a[18].decode(e,e.uint32());break;case 17:o.supportAnswerIntlUrl=a[19].decode(e,e.uint32());break;case 18:o.supportTopicIntlUrl=a[20].decode(e,e.uint32());break;case 19:o.supportRequestIntlUrl=a[21].decode(e,e.uint32());break;case 20:o.earthIntlUrl=a[22].decode(e,e.uint32());break;case 21:o.addContentUrl=a[23].decode(e,e.uint32());break;case 22:o.sketchupNotInstalledUrl=a[24].decode(e,e.uint32());break;case 23:o.sketchupErrorUrl=a[25].decode(e,e.uint32());break;case 24:o.freeLicenseUrl=a[26].decode(e,e.uint32());break;case 25:o.proLicenseUrl=a[27].decode(e,e.uint32());break;case 48:o.tutorialUrl=a[28].decode(e,e.uint32());break;case 49:o.keyboardShortcutsUrl=a[29].decode(e,e.uint32());break;case 50:o.releaseNotesUrl=a[30].decode(e,e.uint32());break;case 26:o.hideUserData=e.bool();break;case 27:o.useGeLogo=e.bool();break;case 28:o.dioramaDescriptionUrlBase=a[33].decode(e,e.uint32());break;case 29:o.dioramaDefaultColor=e.uint32();break;case 53:o.dioramaBlacklistUrl=a[35].decode(e,e.uint32());break;case 30:o.clientOptions=a[36].decode(e,e.uint32());break;case 31:o.fetchingOptions=a[37].decode(e,e.uint32());break;case 32:o.timeMachineOptions=a[38].decode(e,e.uint32());break;case 33:o.csiOptions=a[39].decode(e,e.uint32());break;case 34:o.searchTab&&o.searchTab.length||(o.searchTab=[]),o.searchTab.push(a[40].decode(e,e.uint32()));break;case 35:o.cobrandInfo&&o.cobrandInfo.length||(o.cobrandInfo=[]),o.cobrandInfo.push(a[41].decode(e,e.uint32()));break;case 36:o.validDatabase&&o.validDatabase.length||(o.validDatabase=[]),o.validDatabase.push(a[42].decode(e,e.uint32()));break;case 37:o.configScript&&o.configScript.length||(o.configScript=[]),o.configScript.push(a[43].decode(e,e.uint32()));break;case 38:o.deauthServerUrl=a[44].decode(e,e.uint32());break;case 39:o.swoopParameters=a[45].decode(e,e.uint32());break;case 40:o.bbsServerInfo=a[46].decode(e,e.uint32());break;case 41:o.dataErrorServerInfo=a[47].decode(e,e.uint32());break;case 42:o.planetaryDatabase&&o.planetaryDatabase.length||(o.planetaryDatabase=[]),o.planetaryDatabase.push(a[48].decode(e,e.uint32()));break;case 43:o.logServer=a[49].decode(e,e.uint32());break;case 44:o.autopiaOptions=a[50].decode(e,e.uint32());break;case 54:o.searchConfig=a[51].decode(e,e.uint32());break;case 45:o.searchInfo=a[52].decode(e,e.uint32());break;case 46:o.elevationServiceBaseUrl=e.string();break;case 47:o.elevationProfileQueryDelay=e.int32();break;case 55:o.proUpgradeUrl=a[55].decode(e,e.uint32());break;case 56:o.earthCommunityUrl=a[56].decode(e,e.uint32());break;case 57:o.googleMapsUrl=a[57].decode(e,e.uint32());break;case 58:o.sharingUrl=a[58].decode(e,e.uint32());break;case 59:o.privacyPolicyUrl=a[59].decode(e,e.uint32());break;case 60:o.doGplusUserCheck=e.bool();break;case 61:o.rocktreeDataProto=a[61].decode(e,e.uint32());break;case 62:o.filmstripConfig&&o.filmstripConfig.length||(o.filmstripConfig=[]),o.filmstripConfig.push(a[62].decode(e,e.uint32()));break;case 63:o.showSigninButton=e.bool();break;case 65:o.proMeasureUpsellUrl=a[64].decode(e,e.uint32());break;case 66:o.proPrintUpsellUrl=a[65].decode(e,e.uint32());break;case 67:o.starDataProto=a[66].decode(e,e.uint32());break;case 68:o.feedbackUrl=a[67].decode(e,e.uint32());break;case 69:o.oauth2LoginUrl=a[68].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.model&&null!==e.model){var t=a[0].verify(e.model);if(t)return"model."+t}if(void 0!==e.authServerUrl&&null!==e.authServerUrl){var t=a[1].verify(e.authServerUrl);if(t)return"authServerUrl."+t}if(void 0!==e.disableAuthentication&&"boolean"!=typeof e.disableAuthentication)return"disableAuthentication: boolean expected";if(void 0!==e.mfeDomains){if(!Array.isArray(e.mfeDomains))return"mfeDomains: array expected";for(var i=0;i>>0),void 0!==e.dioramaBlacklistUrl&&null!==e.dioramaBlacklistUrl){if("object"!=typeof e.dioramaBlacklistUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaBlacklistUrl: object expected");t.dioramaBlacklistUrl=a[35].fromObject(e.dioramaBlacklistUrl)}if(void 0!==e.clientOptions&&null!==e.clientOptions){if("object"!=typeof e.clientOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.clientOptions: object expected");t.clientOptions=a[36].fromObject(e.clientOptions)}if(void 0!==e.fetchingOptions&&null!==e.fetchingOptions){if("object"!=typeof e.fetchingOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.fetchingOptions: object expected");t.fetchingOptions=a[37].fromObject(e.fetchingOptions)}if(void 0!==e.timeMachineOptions&&null!==e.timeMachineOptions){if("object"!=typeof e.timeMachineOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.timeMachineOptions: object expected");t.timeMachineOptions=a[38].fromObject(e.timeMachineOptions)}if(void 0!==e.csiOptions&&null!==e.csiOptions){if("object"!=typeof e.csiOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.csiOptions: object expected");t.csiOptions=a[39].fromObject(e.csiOptions)}if(e.searchTab){if(!Array.isArray(e.searchTab))throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: array expected");t.searchTab=[];for(var r=0;r>>3){case 1:o.searchServer&&o.searchServer.length||(o.searchServer=[]),o.searchServer.push(a[0].decode(e,e.uint32()));break;case 2:o.oneboxService&&o.oneboxService.length||(o.oneboxService=[]),o.oneboxService.push(a[1].decode(e,e.uint32()));break;case 3:o.kmlSearchUrl=a[2].decode(e,e.uint32());break;case 4:o.kmlRenderUrl=a[3].decode(e,e.uint32());break;case 6:o.searchHistoryUrl=a[4].decode(e,e.uint32());break;case 5:o.errorPageUrl=a[5].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.searchServer){if(!Array.isArray(e.searchServer))return"searchServer: array expected";for(var t=0;t>>3){case 1:o.name=a[0].decode(e,e.uint32());break;case 2:o.url=a[1].decode(e,e.uint32());break;case 3:o.type=e.uint32();break;case 4:o.htmlTransformUrl=a[3].decode(e,e.uint32());break;case 5:o.kmlTransformUrl=a[4].decode(e,e.uint32());break;case 6:o.supplementalUi=a[5].decode(e,e.uint32());break;case 9:o.suggestion&&o.suggestion.length||(o.suggestion=[]),o.suggestion.push(a[6].decode(e,e.uint32()));break;case 7:o.searchlet&&o.searchlet.length||(o.searchlet=[]),o.searchlet.push(a[7].decode(e,e.uint32()));break;case 8:o.requirements=a[8].decode(e,e.uint32());break;case 10:o.suggestServer=a[9].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.name&&null!==e.name){var t=a[0].verify(e.name);if(t)return"name."+t}if(void 0!==e.url&&null!==e.url){var t=a[1].verify(e.url);if(t)return"url."+t}if(void 0!==e.type)switch(e.type){default:return"type: enum value expected";case 0:case 1:}if(void 0!==e.htmlTransformUrl&&null!==e.htmlTransformUrl){var t=a[3].verify(e.htmlTransformUrl);if(t)return"htmlTransformUrl."+t}if(void 0!==e.kmlTransformUrl&&null!==e.kmlTransformUrl){var t=a[4].verify(e.kmlTransformUrl);if(t)return"kmlTransformUrl."+t}if(void 0!==e.supplementalUi&&null!==e.supplementalUi){var t=a[5].verify(e.supplementalUi);if(t)return"supplementalUi."+t}if(void 0!==e.suggestion){if(!Array.isArray(e.suggestion))return"suggestion: array expected";for(var r=0;r>>3){case 1:o.url=a[0].decode(e,e.uint32());break;case 2:o.label=a[1].decode(e,e.uint32());break;case 3:o.height=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=a[0].verify(e.url);if(t)return"url."+t}if(void 0!==e.label&&null!==e.label){var t=a[1].verify(e.label);if(t)return"label."+t}return void 0===e.height||r.isInteger(e.height)?null:"height: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.url: object expected");t.url=a[0].fromObject(e.url)}if(void 0!==e.label&&null!==e.label){if("object"!=typeof e.label)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.label: object expected");t.label=a[1].fromObject(e.label)}return void 0!==e.height&&null!==e.height&&(t.height=0|e.height),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.label=null,r.height=160),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=a[0].toObject(e.url,t)),void 0!==e.label&&null!==e.label&&e.hasOwnProperty("label")&&(r.label=a[1].toObject(e.label,t)),void 0!==e.height&&null!==e.height&&e.hasOwnProperty("height")&&(r.height=e.height),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.SearchletProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:a.url=o[0].decode(e,e.uint32());break;case 2:a.name=o[1].decode(e,e.uint32());break;case 3:a.requirements=o[2].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=o[0].verify(e.url);if(t)return"url."+t}if(void 0!==e.name&&null!==e.name){var t=o[1].verify(e.name);if(t)return"name."+t}if(void 0!==e.requirements&&null!==e.requirements){var t=o[2].verify(e.requirements);if(t)return"requirements."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.url: object expected");t.url=o[0].fromObject(e.url)}if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.name: object expected");t.name=o[1].fromObject(e.name)}if(void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.requirements: object expected");t.requirements=o[2].fromObject(e.requirements)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.name=null,r.requirements=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=o[1].toObject(e.name,t)),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=o[2].toObject(e.requirements,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o}(),o.OneboxServiceProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:a.serviceUrl=o[0].decode(e,e.uint32());break;case 2:a.requirements=o[1].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.serviceUrl&&null!==e.serviceUrl){var t=o[0].verify(e.serviceUrl);if(t)return"serviceUrl."+t}if(void 0!==e.requirements&&null!==e.requirements){var t=o[1].verify(e.requirements);if(t)return"requirements."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto;if(void 0!==e.serviceUrl&&null!==e.serviceUrl){if("object"!=typeof e.serviceUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.serviceUrl: object expected");t.serviceUrl=o[0].fromObject(e.serviceUrl)}if(void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.requirements: object expected");t.requirements=o[1].fromObject(e.requirements)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.serviceUrl=null,r.requirements=null),void 0!==e.serviceUrl&&null!==e.serviceUrl&&e.hasOwnProperty("serviceUrl")&&(r.serviceUrl=o[0].toObject(e.serviceUrl,t)),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=o[1].toObject(e.requirements,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o}(),o.SearchInfoProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.defaultUrl=e.string();break;case 2:o.geocodeParam=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.defaultUrl||r.isString(e.defaultUrl)?void 0===e.geocodeParam||r.isString(e.geocodeParam)?null:"geocodeParam: string expected":"defaultUrl: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchInfoProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchInfoProto;return void 0!==e.defaultUrl&&null!==e.defaultUrl&&(t.defaultUrl=String(e.defaultUrl)),void 0!==e.geocodeParam&&null!==e.geocodeParam&&(t.geocodeParam=String(e.geocodeParam)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.defaultUrl="http://maps.google.com/maps",r.geocodeParam="q"),void 0!==e.defaultUrl&&null!==e.defaultUrl&&e.hasOwnProperty("defaultUrl")&&(r.defaultUrl=e.defaultUrl),void 0!==e.geocodeParam&&null!==e.geocodeParam&&e.hasOwnProperty("geocodeParam")&&(r.geocodeParam=e.geocodeParam),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.RockTreeDataProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:a.url=o[0].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=o[0].verify(e.url);if(t)return"url."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.RockTreeDataProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.RockTreeDataProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.RockTreeDataProto.url: object expected");t.url=o[0].fromObject(e.url)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.FilmstripConfigProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.requirements=a[0].decode(e,e.uint32());break;case 2:o.alleycatUrlTemplate=a[1].decode(e,e.uint32());break;case 9:o.fallbackAlleycatUrlTemplate=a[2].decode(e,e.uint32());break;case 3:o.metadataUrlTemplate=a[3].decode(e,e.uint32());break;case 4:o.thumbnailUrlTemplate=a[4].decode(e,e.uint32());break;case 5:o.kmlUrlTemplate=a[5].decode(e,e.uint32());break;case 6:o.featuredToursUrl=a[6].decode(e,e.uint32());break;case 7:o.enableViewportFallback=e.bool();break;case 8:o.viewportFallbackDistance=e.uint32();break;case 10:o.imageryType&&o.imageryType.length||(o.imageryType=[]),o.imageryType.push(a[9].decode(e,e.uint32()));break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.requirements&&null!==e.requirements){var t=a[0].verify(e.requirements);if(t)return"requirements."+t}if(void 0!==e.alleycatUrlTemplate&&null!==e.alleycatUrlTemplate){var t=a[1].verify(e.alleycatUrlTemplate);if(t)return"alleycatUrlTemplate."+t}if(void 0!==e.fallbackAlleycatUrlTemplate&&null!==e.fallbackAlleycatUrlTemplate){var t=a[2].verify(e.fallbackAlleycatUrlTemplate);if(t)return"fallbackAlleycatUrlTemplate."+t}if(void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){var t=a[3].verify(e.metadataUrlTemplate);if(t)return"metadataUrlTemplate."+t}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){var t=a[4].verify(e.thumbnailUrlTemplate);if(t)return"thumbnailUrlTemplate."+t}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){var t=a[5].verify(e.kmlUrlTemplate);if(t)return"kmlUrlTemplate."+t}if(void 0!==e.featuredToursUrl&&null!==e.featuredToursUrl){var t=a[6].verify(e.featuredToursUrl);if(t)return"featuredToursUrl."+t}if(void 0!==e.enableViewportFallback&&"boolean"!=typeof e.enableViewportFallback)return"enableViewportFallback: boolean expected";if(void 0!==e.viewportFallbackDistance&&!r.isInteger(e.viewportFallbackDistance))return"viewportFallbackDistance: integer expected";if(void 0!==e.imageryType){if(!Array.isArray(e.imageryType))return"imageryType: array expected";for(var i=0;i>>0),e.imageryType){if(!Array.isArray(e.imageryType))throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: array expected");t.imageryType=[];for(var r=0;r>>3){case 1:o.imageryTypeId=e.int32();break;case 2:o.imageryTypeLabel=e.string();break;case 3:o.metadataUrlTemplate=a[2].decode(e,e.uint32());break;case 4:o.thumbnailUrlTemplate=a[3].decode(e,e.uint32());break;case 5:o.kmlUrlTemplate=a[4].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.imageryTypeId&&!r.isInteger(e.imageryTypeId))return"imageryTypeId: integer expected";if(void 0!==e.imageryTypeLabel&&!r.isString(e.imageryTypeLabel))return"imageryTypeLabel: string expected";if(void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){var t=a[2].verify(e.metadataUrlTemplate);if(t)return"metadataUrlTemplate."+t}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){var t=a[3].verify(e.thumbnailUrlTemplate);if(t)return"thumbnailUrlTemplate."+t}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){var t=a[4].verify(e.kmlUrlTemplate);if(t)return"kmlUrlTemplate."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto;if(void 0!==e.imageryTypeId&&null!==e.imageryTypeId&&(t.imageryTypeId=0|e.imageryTypeId),void 0!==e.imageryTypeLabel&&null!==e.imageryTypeLabel&&(t.imageryTypeLabel=String(e.imageryTypeLabel)),void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){if("object"!=typeof e.metadataUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.metadataUrlTemplate: object expected");t.metadataUrlTemplate=a[2].fromObject(e.metadataUrlTemplate)}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){if("object"!=typeof e.thumbnailUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.thumbnailUrlTemplate: object expected");t.thumbnailUrlTemplate=a[3].fromObject(e.thumbnailUrlTemplate)}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){if("object"!=typeof e.kmlUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.kmlUrlTemplate: object expected");t.kmlUrlTemplate=a[4].fromObject(e.kmlUrlTemplate)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.imageryTypeId=0,r.imageryTypeLabel="",r.metadataUrlTemplate=null,r.thumbnailUrlTemplate=null,r.kmlUrlTemplate=null),void 0!==e.imageryTypeId&&null!==e.imageryTypeId&&e.hasOwnProperty("imageryTypeId")&&(r.imageryTypeId=e.imageryTypeId),void 0!==e.imageryTypeLabel&&null!==e.imageryTypeLabel&&e.hasOwnProperty("imageryTypeLabel")&&(r.imageryTypeLabel=e.imageryTypeLabel),void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate&&e.hasOwnProperty("metadataUrlTemplate")&&(r.metadataUrlTemplate=a[2].toObject(e.metadataUrlTemplate,t)),void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate&&e.hasOwnProperty("thumbnailUrlTemplate")&&(r.thumbnailUrlTemplate=a[3].toObject(e.thumbnailUrlTemplate,t)),void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate&&e.hasOwnProperty("kmlUrlTemplate")&&(r.kmlUrlTemplate=a[4].toObject(e.kmlUrlTemplate,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o}(),o.StarDataProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:a.url=o[0].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=o[0].verify(e.url);if(t)return"url."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.StarDataProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.StarDataProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.StarDataProto.url: object expected");t.url=o[0].fromObject(e.url)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o}(),o.DbRootRefProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 2:o.url=e.string();break;case 1:o.isCritical=e.bool();break;case 3:o.requirements=a[2].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.url))return"url: string expected";if(void 0!==e.isCritical&&"boolean"!=typeof e.isCritical)return"isCritical: boolean expected";if(void 0!==e.requirements&&null!==e.requirements){var t=a[2].verify(e.requirements);if(t)return"requirements."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DbRootRefProto)return e;var t=new n.keyhole.dbroot.DbRootRefProto;if(void 0!==e.url&&null!==e.url&&(t.url=String(e.url)),void 0!==e.isCritical&&null!==e.isCritical&&(t.isCritical=Boolean(e.isCritical)),void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.DbRootRefProto.requirements: object expected");t.requirements=a[2].fromObject(e.requirements)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url="",r.isCritical=!1,r.requirements=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=e.url),void 0!==e.isCritical&&null!==e.isCritical&&e.hasOwnProperty("isCritical")&&(r.isCritical=e.isCritical),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=a[2].toObject(e.requirements,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.DatabaseVersionProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 1:o.quadtreeVersion=e.uint32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isInteger(e.quadtreeVersion)?null:"quadtreeVersion: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DatabaseVersionProto)return e;var t=new n.keyhole.dbroot.DatabaseVersionProto;return void 0!==e.quadtreeVersion&&null!==e.quadtreeVersion&&(t.quadtreeVersion=e.quadtreeVersion>>>0),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.quadtreeVersion=0),void 0!==e.quadtreeVersion&&null!==e.quadtreeVersion&&e.hasOwnProperty("quadtreeVersion")&&(r.quadtreeVersion=e.quadtreeVersion),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.DbRootProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r>>3){case 15:o.databaseName=a[0].decode(e,e.uint32());break;case 1:o.imageryPresent=e.bool();break;case 14:o.protoImagery=e.bool();break;case 2:o.terrainPresent=e.bool();break;case 3:o.providerInfo&&o.providerInfo.length||(o.providerInfo=[]),o.providerInfo.push(a[4].decode(e,e.uint32()));break;case 4:o.nestedFeature&&o.nestedFeature.length||(o.nestedFeature=[]),o.nestedFeature.push(a[5].decode(e,e.uint32()));break;case 5:o.styleAttribute&&o.styleAttribute.length||(o.styleAttribute=[]),o.styleAttribute.push(a[6].decode(e,e.uint32()));break;case 6:o.styleMap&&o.styleMap.length||(o.styleMap=[]),o.styleMap.push(a[7].decode(e,e.uint32()));break;case 7:o.endSnippet=a[8].decode(e,e.uint32());break;case 8:o.translationEntry&&o.translationEntry.length||(o.translationEntry=[]),o.translationEntry.push(a[9].decode(e,e.uint32()));break;case 9:o.language=e.string();break;case 10:o.version=e.int32();break;case 11:o.dbrootReference&&o.dbrootReference.length||(o.dbrootReference=[]),o.dbrootReference.push(a[12].decode(e,e.uint32()));break;case 13:o.databaseVersion=a[13].decode(e,e.uint32());break;case 16:o.refreshTimeout=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.databaseName&&null!==e.databaseName){var t=a[0].verify(e.databaseName);if(t)return"databaseName."+t}if(void 0!==e.imageryPresent&&"boolean"!=typeof e.imageryPresent)return"imageryPresent: boolean expected";if(void 0!==e.protoImagery&&"boolean"!=typeof e.protoImagery)return"protoImagery: boolean expected";if(void 0!==e.terrainPresent&&"boolean"!=typeof e.terrainPresent)return"terrainPresent: boolean expected";if(void 0!==e.providerInfo){if(!Array.isArray(e.providerInfo))return"providerInfo: array expected";for(var i=0;i>>3){case 1:o.encryptionType=e.uint32();break;case 2:o.encryptionData=e.bytes();break;case 3:o.dbrootData=e.bytes();break;default:e.skipType(7&a)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.encryptionType)switch(e.encryptionType){default:return"encryptionType: enum value expected";case 0:}return void 0===e.encryptionData||e.encryptionData&&"number"==typeof e.encryptionData.length||r.isString(e.encryptionData)?void 0===e.dbrootData||e.dbrootData&&"number"==typeof e.dbrootData.length||r.isString(e.dbrootData)?null:"dbrootData: buffer expected":"encryptionData: buffer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EncryptedDbRootProto)return e;var t=new n.keyhole.dbroot.EncryptedDbRootProto;switch(e.encryptionType){case"ENCRYPTION_XOR":case 0:t.encryptionType=0}return void 0!==e.encryptionData&&null!==e.encryptionData&&("string"==typeof e.encryptionData?r.base64.decode(e.encryptionData,t.encryptionData=r.newBuffer(r.base64.length(e.encryptionData)),0):e.encryptionData.length&&(t.encryptionData=e.encryptionData)),void 0!==e.dbrootData&&null!==e.dbrootData&&("string"==typeof e.dbrootData?r.base64.decode(e.dbrootData,t.dbrootData=r.newBuffer(r.base64.length(e.dbrootData)),0):e.dbrootData.length&&(t.dbrootData=e.dbrootData)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var i={};return t.defaults&&(i.encryptionType=t.enums===String?"ENCRYPTION_XOR":0,i.encryptionData=t.bytes===String?"":[],i.dbrootData=t.bytes===String?"":[]),void 0!==e.encryptionType&&null!==e.encryptionType&&e.hasOwnProperty("encryptionType")&&(i.encryptionType=t.enums===String?a[0][e.encryptionType]:e.encryptionType),void 0!==e.encryptionData&&null!==e.encryptionData&&e.hasOwnProperty("encryptionData")&&(i.encryptionData=t.bytes===String?r.base64.encode(e.encryptionData,0,e.encryptionData.length):t.bytes===Array?Array.prototype.slice.call(e.encryptionData):e.encryptionData),void 0!==e.dbrootData&&null!==e.dbrootData&&e.hasOwnProperty("dbrootData")&&(i.dbrootData=t.bytes===String?r.base64.encode(e.dbrootData,0,e.dbrootData.length):t.bytes===Array?Array.prototype.slice.call(e.dbrootData):e.dbrootData),i},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.EncryptionType=function(){var e={},t=Object.create(e);return t.ENCRYPTION_XOR=0,t}(),o}(),o}(),o}(),r.lazyResolve(n,i),n.keyhole.dbroot}),define("Core/isBitSet",[],function(){"use strict";function e(e,t){return 0!=(e&t)}return e}),define("Core/GoogleEarthEnterpriseTileInformation",["./defined","./isBitSet"],function(e,t){"use strict";function r(e,t,r,i,n,o){this._bits=e,this.cnodeVersion=t,this.imageryVersion=r,this.terrainVersion=i,this.imageryProvider=n,this.terrainProvider=o,this.ancestorHasTerrain=!1,this.terrainState=void 0}var i=[1,2,4,8];return r.clone=function(t,i){return e(i)?(i._bits=t._bits,i.cnodeVersion=t.cnodeVersion,i.imageryVersion=t.imageryVersion,i.terrainVersion=t.terrainVersion,i.imageryProvider=t.imageryProvider,i.terrainProvider=t.terrainProvider):i=new r(t._bits,t.cnodeVersion,t.imageryVersion,t.terrainVersion,t.imageryProvider,t.terrainProvider),i.ancestorHasTerrain=t.ancestorHasTerrain,i.terrainState=t.terrainState,i},r.prototype.setParent=function(e){this.ancestorHasTerrain=e.ancestorHasTerrain||this.hasTerrain()},r.prototype.hasSubtree=function(){return t(this._bits,16)},r.prototype.hasImagery=function(){return t(this._bits,64)},r.prototype.hasTerrain=function(){return t(this._bits,128)},r.prototype.hasChildren=function(){return t(this._bits,15)},r.prototype.hasChild=function(e){return t(this._bits,i[e])},r.prototype.getChildBitmask=function(){return 15&this._bits},r}),define("Core/GoogleEarthEnterpriseMetadata",["../ThirdParty/google-earth-dbroot-parser","../ThirdParty/when","./appendForwardSlash","./Check","./Credit","./defaultValue","./defined","./defineProperties","./GoogleEarthEnterpriseTileInformation","./isBitSet","./joinUrls","./loadArrayBuffer","./Math","./Request","./RuntimeError","./TaskProcessor"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e){e=o(e,o.EMPTY_OBJECT),this.imageryPresent=!0,this.protoImagery=void 0,this.terrainPresent=!0,this.negativeAltitudeExponentBias=32,this.negativeAltitudeThreshold=h.EPSILON12,this.providers={},this.key=void 0,this._quadPacketVersion=1,this._url=r(e.url),this._proxy=e.proxy,this._tileInfo={},this._subtreePromises={};var i=this;this._readyPromise=y(this).then(function(){return i.getQuadTreePacket("",i._quadPacketVersion)}).then(function(){return!0}).otherwise(function(e){var r="An error occurred while accessing "+v(i,"",1)+".";return t.reject(new f(r))})}function _(e,r,i){var n=e._tileInfo,o=r,s=n[o];if(a(s)&&(!s.hasSubtree()||s.hasChildren()))return s;for(;void 0===s&&o.length>1;)o=o.substring(0,o.length-1),s=n[o];var l,u=e._subtreePromises,c=u[o];return a(c)?c.then(function(){return l=new p({throttle:i.throttle,throttleByServer:i.throttleByServer,type:i.type,priorityFunction:i.priorityFunction}),_(e,r,l)}):a(s)&&s.hasSubtree()?(c=e.getQuadTreePacket(o,s.cnodeVersion,i),a(c)?(u[o]=c,c.then(function(){return l=new p({throttle:i.throttle,throttleByServer:i.throttleByServer,type:i.type,priorityFunction:i.priorityFunction}),_(e,r,l)}).always(function(){delete u[o]})):void 0):t.reject(new f("Couldn't load metadata for tile "+r))}function v(e,t,r){return c(e._url,"flatfile?q2-0"+t+"-q."+r.toString())}function y(t){var r=c(t._url,"dbRoot.v5?output=proto"),i=t._proxy;return a(i)&&(r=i.getURL(r)),d(r).then(function(r){var i=e.EncryptedDbRootProto.decode(new Uint8Array(r)),n=i.encryptionData,o=n.byteOffset,a=o+n.byteLength,s=t.key=n.buffer.slice(o,a);n=i.dbrootData,o=n.byteOffset,a=o+n.byteLength;var l=n.buffer.slice(o,a);return b.scheduleTask({buffer:l,type:"DbRoot",key:s},[l])}).then(function(r){var i=e.DbRootProto.decode(new Uint8Array(r.buffer));if(t.imageryPresent=o(i.imageryPresent,t.imageryPresent),t.protoImagery=i.protoImagery,t.terrainPresent=o(i.terrainPresent,t.terrainPresent),a(i.endSnippet)&&a(i.endSnippet.model)){var s=i.endSnippet.model;t.negativeAltitudeExponentBias=o(s.negativeAltitudeExponentBias,t.negativeAltitudeExponentBias),t.negativeAltitudeThreshold=o(s.compressedNegativeAltitudeThreshold,t.negativeAltitudeThreshold)}a(i.databaseVersion)&&(t._quadPacketVersion=o(i.databaseVersion.quadtreeVersion,t._quadPacketVersion));for(var l=t.providers,u=o(i.providerInfo,[]),c=u.length,d=0;dmF8J´Ýð.ÝuڌDt"úa"\f3"So¯9D\vŒ9Ù9L¹¿«\\ŒP_Ÿ"uxéq‘h;ÁěðMª>}æÎI‰Ææx\fa1-¤O¥~q ˆì\r1èN\v\0nPh}=\b\r•¦n£h—$[kó#ó¶s³\r\v@ÀŸØQ]ú".jßI\0¹ wUÆïj¿{GLƒîÜÜF…©­S+S4ÿ”Yä8è1ƒN¹XFkË-#†’p\x005ˆ"Ï1²&/çÃu-6,rt°#G·ÓÑ&…7râ\0ŒDÏÚ3-Þ`†i#i*|ÍKQ\r•T9w.)ê¦P¢joP™\\>TûïP[\vE‰m(w7ێJfJo™ åpâ¹q~\fmI-zþrÇòY0»]såÉ êxì ðŠB|G`°½&·q¶ÇŸÑ3‚=Ó«îc™È+S D\\qÆÌD2O<ÊÀ)=RÓaX©}e´ÜÏ\rô=ñ\b©BÚ#\tØ¿^PIøMÀËGLO÷{+ØÅ1’;µoÜl\r’ˆўÛ?âéÚ_ԄâFaZÞUϤ\0¾ýÎgñJi—æ HØ]~®q N®ÀV©‘<‚rçvì)IÖ]-ƒãÛ6©;f—‡jÕ¶=P^R¹KÇsWxÉô.Y•“oÐKW>\'\'Ç`Û;íšSD>?’mw¢\në?R¨ÆU^1I7…ôÅ&-©¿‹\'TÚÃj å*x°Öprª‹h½ˆ÷_H±~ÀXL?fù>áeÀp§Ï8i¯ðVldIœ\'­xtO‡ÞV9\0Úw\vË-‰û5Oõ\bQ`Á\nZGM&30xÚÀœFGâ[y`In7gS\n>éìF9²ñ4\rƄSuná\fYÙÞ)…{II¥wy¾IV.6ç\v:»Ob{ÒM1•/½8{¨O!áìFpv•})"xˆ\nÝ\\ÚÞQÏðüYRe|3ßóHÚ»*uÛ`²Ôüíì5¨ÿ(1-È܈F|Š["');s(g.prototype,{url:{get:function(){return this._url}},proxy:{get:function(){return this._proxy}},readyPromise:{get:function(){return this._readyPromise}}}),g.tileXYToQuadKey=function(e,t,r){for(var i="",n=r;n>=0;--n){var o=1<=0;--n){var o=1<1;){if(r=n.substring(n.length-1),n=n.substring(0,n.length-1),t=this.getTileInformationFromQuadKey(n),a(t)){t.hasSubtree()||t.hasChild(parseInt(r))||(i=!1);break}if(null===t){i=!1;break}}return i};var b=new m("decodeGoogleEarthEnterprisePacket",Number.POSITIVE_INFINITY);return g.prototype.getQuadTreePacket=function(e,t,r){t=o(t,1),e=o(e,"");var i=v(this,e,t),n=this._proxy;a(n)&&(i=n.getURL(i));var s=d(i,void 0,r);if(a(s)){var u=this._tileInfo,c=this.key;return s.then(function(t){return b.scheduleTask({buffer:t,quadKey:e,type:"Metadata",key:c},[t]).then(function(t){var r,i=-1;if(""!==e){i=e.length+1;var n=t[e];r=u[e],r._bits|=n._bits,delete t[e]}var o=Object.keys(t);o.sort(function(e,t){return e.length-t.length});for(var a=o.length,s=0;s1){var p=u[c.substring(0,c.length-1)];d.setParent(p)}u[c]=d}else u[c]=null}})})}},g.prototype.populateSubtree=function(e,t,r,i){return _(this,g.tileXYToQuadKey(e,t,r),i)},g.prototype.getTileInformation=function(e,t,r){var i=g.tileXYToQuadKey(e,t,r);return this._tileInfo[i]},g.prototype.getTileInformationFromQuadKey=function(e){return this._tileInfo[e]},g}),define("Core/GoogleEarthEnterpriseTerrainData",["./BoundingSphere","./Cartesian2","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./IndexDatatype","./Intersections2D","./Math","./OrientedBoundingBox","./QuantizedMeshTerrainData","./Rectangle","./TaskProcessor","./TerrainEncoding","./TerrainMesh"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){e=n(e,n.EMPTY_OBJECT),this._buffer=e.buffer,this._credits=e.credits,this._negativeAltitudeExponentBias=e.negativeAltitudeExponentBias,this._negativeElevationThreshold=e.negativeElevationThreshold;var t=n(e.childTileMask,15),r=3&t;r|=4&t?8:0,r|=8&t?4:0,this._childTileMask=r,this._createdByUpsampling=n(e.createdByUpsampling,!1),this._skirtHeight=void 0,this._bufferType=this._buffer.constructor,this._mesh=void 0,this._minimumHeight=void 0,this._maximumHeight=void 0,this._vertexCountWithoutSkirts=void 0,this._skirtIndex=void 0}function v(e,t,r){for(var i=e._mesh,n=i.vertices,o=i.encoding,a=i.indices,s=0,l=a.length;s=-1e-15&&g.y>=-1e-15&&g.z>=-1e-15){var _=o.decodeHeight(n,c),v=o.decodeHeight(n,d),y=o.decodeHeight(n,h);return g.x*_+g.y*v+g.z*y}}}function y(e,t,r,i){var n=e._buffer,o=0,a=0,s=0;r>.5?(t>.5?(o=2,a=.5):o=3,s=.5):t>.5&&(o=1,a=.5);for(var l=new DataView(n),d=0,h=0;h=-1e-15&&U.y>=-1e-15&&U.z>=-1e-15)return U.x*S[T]+U.y*S[A]+U.z*S[E]}}a(_.prototype,{credits:{get:function(){return this._credits}},waterMask:{get:function(){}}});var C=new f("createVerticesFromGoogleEarthEnterpriseBuffer"),b=new p,S=new p;_.prototype.createMesh=function(e,t,r,i,a){var s=e.ellipsoid;e.tileXYToNativeRectangle(t,r,i,b),e.tileXYToRectangle(t,r,i,S),a=n(a,1);var l=s.cartographicToCartesian(p.center(S)),u=40075.16/(1<0?r:1;var n=e.url+"flatfile?f1c-0"+t+"-t."+r.toString(),o=e._proxy;return i(o)&&(n=o.getURL(n)),n}var A={UNKNOWN:0,NONE:1,SELF:2,PARENT:3},E=new d;b.prototype.add=function(e,t){this._terrainCache[e]={buffer:t,timestamp:d.now()}},b.prototype.get=function(e){var t=this._terrainCache,r=t[e];if(i(r))return delete this._terrainCache[e],r.buffer},b.prototype.tidy=function(){if(d.now(E),d.secondsDifference(E,this._lastTidy)>10){for(var e=this._terrainCache,t=Object.keys(e),r=t.length,i=0;i10&&delete e[n]}d.clone(E,this._lastTidy)}},n(S.prototype,{url:{get:function(){return this._metadata.url}},proxy:{get:function(){return this._proxy}},tilingScheme:{get:function(){return this._tilingScheme}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasWaterMask:{get:function(){return!1}},hasVertexNormals:{get:function(){return!1}},availability:{get:function(){}}});var x=new y("decodeGoogleEarthEnterprisePacket",Number.POSITIVE_INFINITY);return S.prototype.requestTileGeometry=function(t,r,n,o){var a=l.tileXYToQuadKey(t,r,n),s=this._terrainCache,d=this._metadata,p=d.getTileInformationFromQuadKey(a);if(!i(p))return e.reject(new v("Terrain tile doesn't exist"));var f=p.terrainState;i(f)||(f=p.terrainState=A.UNKNOWN);var m=s.get(a);if(i(m)){var _=d.providers[p.terrainProvider];return new u({buffer:m,childTileMask:w(a,p,d),credits:i(_)?[_]:void 0,negativeAltitudeExponentBias:d.negativeAltitudeExponentBias,negativeElevationThreshold:d.negativeAltitudeThreshold})}if(s.tidy(),!p.ancestorHasTerrain)return new c({buffer:new Uint8Array(256),width:16,height:16});if(f===A.NONE)return e.reject(new v("Terrain tile doesn't exist"));var y,C=a,b=-1;switch(f){case A.SELF:b=p.terrainVersion;break;case A.PARENT:C=C.substring(0,C.length-1),y=d.getTileInformationFromQuadKey(C),b=y.terrainVersion;break;case A.UNKNOWN:p.hasTerrain()?b=p.terrainVersion:(C=C.substring(0,C.length-1),y=d.getTileInformationFromQuadKey(C),i(y)&&y.hasTerrain()&&(b=y.terrainVersion))}if(b<0)return e.reject(new v("Terrain tile doesn't exist"));var S,E,P=this._terrainPromises,D=this._terrainRequests,I=T(this,C,b);if(i(P[C]))S=P[C],E=D[C];else{E=o;var O=h(I,void 0,E);if(!i(O))return;S=O.then(function(t){return i(t)?x.scheduleTask({buffer:t,type:"Terrain",key:d.key},[t]).then(function(e){var t=d.getTileInformationFromQuadKey(C);t.terrainState=A.SELF,s.add(C,e[0]);for(var r=t.terrainProvider,n=e.length-1,o=0;o0){for(l=0;l1){var P=o.isCompressedFormat(_)?o.compressedTextureSizeInBytes(_,y,C):o.textureSizeInBytes(_,y,C);x=new Uint8Array(x.buffer,x.byteOffset,P)}return new r(_,y,C,x)}var u=[171,75,84,88,32,49,49,187,13,10,26,10],c=67305985,d=4;return s}),define("Core/loadXML",["./loadWithXhr"],function(e){"use strict";function t(t,r,i){return e({url:t,responseType:"document",headers:r,overrideMimeType:"text/xml",request:i})}return t}),define("Core/ManagedArray",["./Check","./defaultValue","./defineProperties"],function(e,t,r){"use strict";function i(e){e=t(e,0),this._array=new Array(e),this._length=e}return r(i.prototype,{length:{get:function(){return this._length},set:function(e){this._length=e,e>this._array.length&&(this._array.length=e)}},values:{get:function(){return this._array}}}),i.prototype.get=function(e){return this._array[e]},i.prototype.set=function(e,t){e>=this.length&&(this.length=e+1),this._array[e]=t},i.prototype.push=function(e){var t=this.length++;this._array[t]=e},i.prototype.pop=function(){return this._array[--this.length]},i.prototype.reserve=function(e){e>this._array.length&&(this._array.length=e)},i.prototype.resize=function(e){this.length=e},i.prototype.trim=function(e){e=t(e,this.length),this._array.length=e},i}),define("Core/MapboxApi",["./Credit","./defined"],function(e,t){"use strict";var r={};r.defaultAccessToken=void 0;var i,n=!1,o="This application is using Cesium's default Mapbox access token. Please create a new access token for the application as soon as possible and prior to deployment by visiting https://www.mapbox.com/account/apps/, and provide your token to Cesium by setting the Cesium.MapboxApi.defaultAccessToken property before constructing the CesiumWidget or any other object that uses the Mapbox API.";return r.getAccessToken=function(e){return t(e)?e:t(r.defaultAccessToken)?r.defaultAccessToken:(n||(console.log(o),n=!0),"pk.eyJ1IjoiYW5hbHl0aWNhbGdyYXBoaWNzIiwiYSI6ImNpd204Zm4wejAwNzYyeW5uNjYyZmFwdWEifQ.7i-VIZZWX8pd1bTfxIVj9g")},r.getErrorCredit=function(n){if(!t(n)&&!t(r.defaultAccessToken))return t(i)||(i=new e({text:o,showOnScreen:!0})),i},r}),define("Core/MapProjection",["./defineProperties","./DeveloperError"],function(e,t){"use strict";function r(){t.throwInstantiationError()}return e(r.prototype,{ellipsoid:{get:t.throwInstantiationError}}),r.prototype.project=t.throwInstantiationError,r.prototype.unproject=t.throwInstantiationError,r}),define("Core/Matrix2",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./freezeObject"],function(e,t,r,i,n,o){"use strict";function a(e,t,i,n){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(t,0),this[3]=r(n,0)}a.packedLength=4,a.pack=function(e,t,i){return i=r(i,0),t[i++]=e[0],t[i++]=e[1],t[i++]=e[2],t[i++]=e[3],t},a.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new a),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n},a.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):new a(e[0],e[2],e[1],e[3])},a.fromArray=function(e,t,n){return t=r(t,0),i(n)||(n=new a),n[0]=e[t],n[1]=e[t+1],n[2]=e[t+2],n[3]=e[t+3],n},a.fromColumnMajorArray=function(e,t){return a.clone(e,t)},a.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[2],t[2]=e[1],t[3]=e[3],t):new a(e[0],e[1],e[2],e[3])},a.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=e.y,t):new a(e.x,0,0,e.y)},a.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=e,t):new a(e,0,0,e)},a.fromRotation=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t):new a(r,-n,n,r)},a.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):[e[0],e[1],e[2],e[3]]},a.getElementIndex=function(e,t){return 2*e+t},a.getColumn=function(e,t,r){var i=2*t,n=e[i],o=e[i+1];return r.x=n,r.y=o,r},a.setColumn=function(e,t,r,i){i=a.clone(e,i);var n=2*t;return i[n]=r.x,i[n+1]=r.y,i},a.getRow=function(e,t,r){var i=e[t],n=e[t+2];return r.x=i,r.y=n,r},a.setRow=function(e,t,r,i){return i=a.clone(e,i),i[t]=r.x,i[t+2]=r.y,i};var s=new e;a.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],s)),r.y=e.magnitude(e.fromElements(t[2],t[3],s)),r};var l=new e;return a.getMaximumScale=function(t){return a.getScale(t,l),e.maximumComponent(l)},a.multiply=function(e,t,r){var i=e[0]*t[0]+e[2]*t[1],n=e[0]*t[2]+e[2]*t[3],o=e[1]*t[0]+e[3]*t[1],a=e[1]*t[2]+e[3]*t[3];return r[0]=i,r[1]=o,r[2]=n,r[3]=a,r},a.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r},a.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r},a.multiplyByVector=function(e,t,r){var i=e[0]*t.x+e[2]*t.y,n=e[1]*t.x+e[3]*t.y;return r.x=i,r.y=n,r},a.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r},a.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.y,r[3]=e[3]*t.y,r},a.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},a.transpose=function(e,t){var r=e[0],i=e[2],n=e[1],o=e[3];return t[0]=r,t[1]=i,t[2]=n,t[3]=o,t},a.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t},a.equals=function(e,t){return e===t||i(e)&&i(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},a.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]},a.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r},a.IDENTITY=o(new a(1,0,0,1)),a.ZERO=o(new a(0,0,0,0)),a.COLUMN0ROW0=0,a.COLUMN0ROW1=1,a.COLUMN1ROW0=2,a.COLUMN1ROW1=3,n(a.prototype,{length:{get:function(){return a.packedLength}}}),a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a.prototype.equalsEpsilon=function(e,t){return a.equalsEpsilon(this,e,t)},a.prototype.toString=function(){return"("+this[0]+", "+this[2]+")\n("+this[1]+", "+this[3]+")"},a}),define("Core/mergeSort",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e,t,r,i,n,s){var l,u,c=n-i+1,d=s-n,h=o,p=a;for(l=0;l=d||t(m,g,r)<=0)?(e[f]=m,++l):u=a)){var s=Math.floor(.5*(o+a));i(e,t,n,o,s),i(e,t,n,s+1,a),r(e,t,n,o,s,a)}}function n(e,t,r){var n=e.length,s=Math.ceil(.5*n);o.length=s,a.length=s,i(e,t,r,0,n-1),o.length=0,a.length=0}var o=[],a=[];return n}),define("Core/NearFarScalar",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(t,r,i,n){this.near=e(t,0),this.nearValue=e(r,0),this.far=e(i,1),this.farValue=e(n,0)}return i.clone=function(e,r){if(t(e))return t(r)?(r.near=e.near,r.nearValue=e.nearValue,r.far=e.far,r.farValue=e.farValue,r):new i(e.near,e.nearValue,e.far,e.farValue)},i.packedLength=4,i.pack=function(t,r,i){return i=e(i,0),r[i++]=t.near,r[i++]=t.nearValue,r[i++]=t.far,r[i]=t.farValue,r},i.unpack=function(r,n,o){return n=e(n,0),t(o)||(o=new i),o.near=r[n++],o.nearValue=r[n++],o.far=r[n++],o.farValue=r[n],o},i.equals=function(e,r){return e===r||t(e)&&t(r)&&e.near===r.near&&e.nearValue===r.nearValue&&e.far===r.far&&e.farValue===r.farValue},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/Visibility",["./freezeObject"],function(e){"use strict";return e({NONE:-1,PARTIAL:0,FULL:1})}),define("Core/Occluder",["./BoundingSphere","./Cartesian3","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math","./Rectangle","./Visibility"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){this._occluderPosition=t.clone(e.center),this._occluderRadius=e.radius,this._horizonDistance=0,this._horizonPlaneNormal=void 0,this._horizonPlanePosition=void 0,this._cameraPosition=void 0,this.cameraPosition=r}var d=new t;n(c.prototype,{position:{get:function(){return this._occluderPosition}},radius:{get:function(){return this._occluderRadius}},cameraPosition:{set:function(e){e=t.clone(e,this._cameraPosition);var r,i,n,o=t.subtract(this._occluderPosition,e,d),a=t.magnitudeSquared(o),s=this._occluderRadius*this._occluderRadius;if(a>s){r=Math.sqrt(a-s),a=1/Math.sqrt(a),i=t.multiplyByScalar(o,a,d);var l=r*r*a;n=t.add(e,t.multiplyByScalar(i,l,d),d)}else r=Number.MAX_VALUE;this._horizonDistance=r,this._horizonPlaneNormal=i,this._horizonPlanePosition=n,this._cameraPosition=e}}}),c.fromBoundingSphere=function(e,r,n){return i(n)?(t.clone(e.center,n._occluderPosition),n._occluderRadius=e.radius,n.cameraPosition=r,n):new c(e,r)};var h=new t;c.prototype.isPointVisible=function(e){if(this._horizonDistance!==Number.MAX_VALUE){var r=t.subtract(e,this._occluderPosition,h),i=this._occluderRadius;if((i=t.magnitudeSquared(r)-i*i)>0)return i=Math.sqrt(i)+this._horizonDistance,r=t.subtract(e,this._cameraPosition,r),i*i>t.magnitudeSquared(r)}return!1};var p=new t;c.prototype.isBoundingSphereVisible=function(e){var r=t.clone(e.center,p),i=e.radius;if(this._horizonDistance!==Number.MAX_VALUE){var n=t.subtract(r,this._occluderPosition,h),o=this._occluderRadius-i;if(o=t.magnitudeSquared(n)-o*o,i0&&(o=Math.sqrt(o)+this._horizonDistance,n=t.subtract(r,this._cameraPosition,n),o*o+i*i>t.magnitudeSquared(n));if(o>0){n=t.subtract(r,this._cameraPosition,n);var a=t.magnitudeSquared(n),s=this._occluderRadius*this._occluderRadius,l=i*i;return(this._horizonDistance*this._horizonDistance+s)*l>a*s||(o=Math.sqrt(o)+this._horizonDistance)*o+l>a}return!0}return!1};var f=new t;c.prototype.computeVisibility=function(e){var r=t.clone(e.center),i=e.radius;if(i>this._occluderRadius)return u.FULL;if(this._horizonDistance!==Number.MAX_VALUE){var n=t.subtract(r,this._occluderPosition,f),o=this._occluderRadius-i,a=t.magnitudeSquared(n);if((o=a-o*o)>0){o=Math.sqrt(o)+this._horizonDistance,n=t.subtract(r,this._cameraPosition,n);var s=t.magnitudeSquared(n);return o*o+i*i0?(o=Math.sqrt(o)+this._horizonDistance,s-i?u.PARTIAL:u.FULL))}}return u.NONE};var m=new t;c.computeOccludeePoint=function(e,r,i){var n=t.clone(r),o=t.clone(e.center),a=e.radius,s=i.length,l=t.normalize(t.subtract(n,o,m),m),u=-t.dot(l,o),d=c._anyRotationVector(o,l,u),h=c._horizonToPlaneNormalDotProduct(e,l,u,d,i[0]);if(h){for(var p,f=1;fn.y?0:1;(0===o&&n.z>n.x||1===o&&n.z>n.y)&&(o=2);var a,s=new t;0===o?(n.x=e.x,n.y=e.y+1,n.z=e.z+1,a=t.UNIT_X):1===o?(n.x=e.x+1,n.y=e.y,n.z=e.z+1,a=t.UNIT_Y):(n.x=e.x+1,n.y=e.y+1,n.z=e.z,a=t.UNIT_Z);var l=(t.dot(r,n)+i)/-t.dot(r,a);return t.normalize(t.subtract(t.add(n,t.multiplyByScalar(a,l,s),n),e,n),n)};var v=new t;c._rotationVector=function(e,r,i,n,o){var a=t.subtract(n,e,v);if(a=t.normalize(a,a),t.dot(r,a)<.9999999847691291){var l=t.cross(r,a,a);if(t.magnitude(l)>s.EPSILON13)return t.normalize(l,new t)}return o};var y=new t,C=new t,b=new t,S=new t;return c._horizonToPlaneNormalDotProduct=function(e,r,i,n,o){var a=t.clone(o,y),s=t.clone(e.center,C),l=e.radius,u=t.subtract(s,a,b),c=t.magnitudeSquared(u),d=l*l;if(c"+r,document.body.appendChild(d),o.leading=1.2*s;var h=e(d,"height");if(h=h.replace("px",""),h>=2*s&&(o.leading=h/2|0),document.body.removeChild(d),c)o.ascent=0,o.descent=0,o.bounds={minx:0,maxx:o.width,miny:0,maxy:0},o.height=0;else{var p=document.createElement("canvas");p.width=o.width+100,p.height=3*s,p.style.opacity=1,p.style.fontFamily=a,p.style.fontSize=s,p.style.fontStyle=l,p.style.fontWeight=u;var f=p.getContext("2d");f.font=l+" "+u+" "+s+"px "+a;var m=p.width,g=p.height,_=g/2;f.fillStyle="white",f.fillRect(-1,-1,m+2,g+2),i&&(f.strokeStyle="black",f.lineWidth=t.lineWidth,f.strokeText(r,50,_)),n&&(f.fillStyle="black",f.fillText(r,50,_));for(var v=f.getImageData(0,0,m,g).data,y=0,C=4*m,b=v.length;++y0&&255===v[y];);var w=y/C|0;for(y=0;y=b&&(y=y-b+4);var T=y%C/4|0,A=1;for(y=b-3;y>=0&&255===v[y];)(y-=C)<0&&(y=b-3-4*A++);var E=y%C/4+1|0;o.ascent=_-S,o.descent=w-_,o.bounds={minx:T-50,maxx:E-50,miny:0,maxy:w-S},o.height=w-S+1}return o}}),define("Core/writeTextToCanvas",["../ThirdParty/measureText","./Color","./defaultValue","./defined","./DeveloperError"],function(e,t,r,i,n){"use strict";function o(n,o){if(""!==n){o=r(o,r.EMPTY_OBJECT);var s=r(o.font,"10px sans-serif"),l=r(o.stroke,!1),u=r(o.fill,!0),c=r(o.strokeWidth,1),d=r(o.backgroundColor,t.TRANSPARENT),h=r(o.padding,0),p=2*h,f=document.createElement("canvas");f.width=1,f.height=1,f.style.font=s;var m=f.getContext("2d");i(a)||(i(m.imageSmoothingEnabled)?a="imageSmoothingEnabled":i(m.mozImageSmoothingEnabled)?a="mozImageSmoothingEnabled":i(m.webkitImageSmoothingEnabled)?a="webkitImageSmoothingEnabled":i(m.msImageSmoothingEnabled)&&(a="msImageSmoothingEnabled")),m.font=s,m.lineJoin="round",m.lineWidth=c,m[a]=!1,m.textBaseline=r(o.textBaseline,"bottom"),f.style.visibility="hidden",document.body.appendChild(f);var g=e(m,n,l,u);f.dimensions=g,document.body.removeChild(f),f.style.visibility="";var _=-g.bounds.minx,v=Math.ceil(g.width)+_+p,y=g.height+p,C=y-g.ascent+p,b=y-C+p;if(f.width=v,f.height=y,m.font=s,m.lineJoin="round",m.lineWidth=c,m[a]=!1,d!==t.TRANSPARENT&&(m.fillStyle=d.toCssColorString(),m.fillRect(0,0,f.width,f.height)),l){var S=r(o.strokeColor,t.BLACK);m.strokeStyle=S.toCssColorString(),m.strokeText(n,_+h,b)}if(u){var w=r(o.fillColor,t.WHITE);m.fillStyle=w.toCssColorString(),m.fillText(n,_+h,b)}return f}}var a;return o}),define("Core/PinBuilder",["./buildModuleUrl","./Color","./defined","./DeveloperError","./loadImage","./writeTextToCanvas"],function(e,t,r,i,n,o){"use strict";function a(){this._cache={}}function s(e,t,r){e.save(),e.scale(r/24,r/24),e.fillStyle=t.toCssColorString(),e.strokeStyle=t.brighten(.6,c).toCssColorString(),e.lineWidth=.846,e.beginPath(),e.moveTo(6.72,.422),e.lineTo(17.28,.422),e.bezierCurveTo(18.553,.422,19.577,1.758,19.577,3.415),e.lineTo(19.577,10.973),e.bezierCurveTo(19.577,12.63,18.553,13.966,17.282,13.966),e.lineTo(14.386,14.008),e.lineTo(11.826,23.578),e.lineTo(9.614,14.008),e.lineTo(6.719,13.965),e.bezierCurveTo(5.446,13.983,4.422,12.629,4.422,10.972),e.lineTo(4.422,3.416),e.bezierCurveTo(4.423,1.76,5.447,.423,6.718,.423),e.closePath(),e.fill(),e.stroke(),e.restore()}function l(e,r,i){var n=i/2.5,o=n,a=n;r.width>r.height?a=n*(r.height/r.width):r.width0&&i.y>0&&i.z>0}var i=new t;return r}),define("Core/Queue",["./defineProperties"],function(e){"use strict";function t(){this._array=[],this._offset=0,this._length=0}return e(t.prototype,{length:{get:function(){return this._length}}}),t.prototype.enqueue=function(e){this._array.push(e),this._length++},t.prototype.dequeue=function(){if(0!==this._length){var e=this._array,t=this._offset,r=e[t];return e[t]=void 0,t++,t>10&&2*t>e.length&&(this._array=e.slice(t),t=0),this._offset=t,this._length--,r}},t.prototype.peek=function(){if(0!==this._length)return this._array[this._offset]},t.prototype.contains=function(e){return-1!==this._array.indexOf(e)},t.prototype.clear=function(){this._array.length=this._offset=this._length=0},t.prototype.sort=function(e){this._offset>0&&(this._array=this._array.slice(this._offset),this._offset=0),this._array.sort(e)},t}),define("Core/PolygonGeometryLibrary",["./arrayRemoveDuplicates","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e,r,i,n){return t.subtract(r,e,v),t.multiplyByScalar(v,i/n,v),t.add(e,v,v),[v.x,v.y,v.z]}var _={};_.computeHierarchyPackedLength=function(e){for(var r=0,i=[e];i.length>0;){var o=i.pop();if(n(o)){r+=2;var a=o.positions,s=o.holes;if(n(a)&&(r+=a.length*t.packedLength),n(s))for(var l=s.length,u=0;u0;){var a=o.pop();if(n(a)){var s=a.positions,l=a.holes;if(r[i++]=n(s)?s.length:0,r[i++]=n(l)?l.length:0,n(s))for(var u=s.length,c=0;c0?new Array(n):void 0,s=0;s0?new Array(u):void 0;for(s=0;sb?(d=o.TWO_PI-S+b,n=Math.ceil(d/h)+1,a=Math.ceil(A/h)+1,u=d/(n-1),c=A/(a-1)):(d=b-S,n=Math.ceil(d/h)+1,a=Math.ceil(A/h)+1,u=d/(n-1),c=A/(a-1)),r=s.northwest(t,r);var E=s.center(t,m);0===v&&0===y||(E.longitude1||v>1))for(var b=0;b0;t-=d)q=3*t,Q=D(Q,J,q,C,A),J+=6,n.st&&(K=I(K,$,2*t,E),$+=4),i&&(ee+=3,Z[ee++]=O[q],Z[ee++]=O[q+1],Z[ee++]=O[q+2]);for(t=d-1;t>=0;t--)q=3*t,Q=D(Q,J,q,C,A),J+=6,n.st&&(K=I(K,$,2*t,E),$+=4),i&&(ee+=3,Z[ee++]=O[q],Z[ee++]=O[q+1],Z[ee++]=O[q+2]);var re=x(Q,n,p);n.st&&(re.attributes.st=new h({componentDatatype:o.FLOAT,componentsPerAttribute:2,values:K})),i&&(re.attributes.extrudeDirection=new h({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:Z}));var ie,ne,oe,ae,se=g.createTypedArray(X,6*Y);b=Q.length/3;var le=0;for(t=0;t=0;t--)g.computePosition(e,h,t,p),a[s++]=p.x,a[s++]=p.y,a[s++]=p.z;for(t=0,h=n-2;h>0;h--)g.computePosition(e,h,t,p),a[s++]=p.x,a[s++]=p.y,a[s++]=p.z;for(var m=a.length/3*2,_=d.createTypedArray(a.length/3,m),v=0,y=0;yO.mouseEmulationIgnoreMilliseconds}function v(e,r){if(_(e)){var n=r.button;e._buttonDown=n;var o;if(n===M.LEFT)o=u.LEFT_DOWN;else if(n===M.MIDDLE)o=u.MIDDLE_DOWN;else{if(n!==M.RIGHT)return;o=u.RIGHT_DOWN}var a=c(e,r,e._primaryPosition);t.clone(a,e._primaryStartPosition),t.clone(a,e._primaryPreviousPosition);var s=h(r),l=e.getInputAction(o,s);i(l)&&(t.clone(a,R.position),l(R),r.preventDefault())}}function y(e,r){if(_(e)){var n=r.button;e._buttonDown=void 0;var o,a;if(n===M.LEFT)o=u.LEFT_UP,a=u.LEFT_CLICK;else if(n===M.MIDDLE)o=u.MIDDLE_UP,a=u.MIDDLE_CLICK;else{if(n!==M.RIGHT)return;o=u.RIGHT_UP,a=u.RIGHT_CLICK}var s=h(r),l=e.getInputAction(o,s),d=e.getInputAction(a,s);if(i(l)||i(d)){var p=c(e,r,e._primaryPosition);if(i(l)&&(t.clone(p,N.position),l(N)),i(d)){var f=e._primaryStartPosition,m=f.x-p.x,g=f.y-p.y;Math.sqrt(m*m+g*g)0?-120*t.detail:t.wheelDelta;if(i(r)){var o=h(t),a=e.getInputAction(u.WHEEL,o);i(a)&&(a(r),t.preventDefault())}}function w(e,r){g(e);var i,n,o,a=r.changedTouches,s=a.length,l=e._positions;for(i=0;iP;++i){a=o;o=a-(a-t*Math.sin(a)-e)/(1-t*Math.cos(a))}return a=o+r*n.TWO_PI}function f(e,t){var r=Math.floor(e/n.TWO_PI);e-=r*n.TWO_PI;var i=Math.cos(e)-t,o=Math.sin(e)*Math.sqrt(1-t*t),a=Math.atan2(o,i);return a=n.zeroToTwoPi(a),e<0&&(a-=n.TWO_PI),a+=r*n.TWO_PI}function m(e,r,i,n){var a=Math.cos(e),s=Math.sin(e),l=Math.cos(r),u=Math.sin(r),c=Math.cos(i),d=Math.sin(i);return t(n)?(n[0]=c*a-d*s*l,n[1]=d*a+c*s*l,n[2]=s*u,n[3]=-c*s-d*a*l,n[4]=-d*s+c*a*l,n[5]=a*u,n[6]=d*u,n[7]=-c*u,n[8]=l):n=new o(c*a-d*s*l,-c*s-d*a*l,d*u,d*a+c*s*l,-d*s+c*a*l,-c*u,s*u,a*u,l),n}function g(e,t){u(e,Ee) -;var r=Ee.dayNumber-S.dayNumber+(Ee.secondsOfDay-S.secondsOfDay)/a.SECONDS_PER_DAY,i=r/(10*a.DAYS_PER_JULIAN_CENTURY),n=.3595362*i,o=D+V*Math.cos(M*n)+X*Math.sin(M*n)+z*Math.cos(R*n)+Q*Math.sin(R*n)+G*Math.cos(N*n)+Z*Math.sin(N*n)+H*Math.cos(L*n)+K*Math.sin(L*n)+W*Math.cos(k*n)+J*Math.sin(k*n)+j*Math.cos(F*n)+$*Math.sin(F*n)+q*Math.cos(B*n)+ee*Math.sin(B*n)+Y*Math.cos(U*n)+te*Math.sin(U*n),s=I+O*i+ce*Math.cos(re*n)+ve*Math.sin(re*n)+de*Math.cos(ie*n)+ye*Math.sin(ie*n)+he*Math.cos(ne*n)+Ce*Math.sin(ne*n)+pe*Math.cos(oe*n)+be*Math.sin(oe*n)+fe*Math.cos(ae*n)+Se*Math.sin(ae*n)+me*Math.cos(se*n)+we*Math.sin(se*n)+ge*Math.cos(le*n)+Te*Math.sin(le*n)+_e*Math.cos(ue*n)+Ae*Math.sin(ue*n);return c(o,.0167086342-.0004203654*i,469.97289*A*i,102.93734808*T+11612.3529*A*i,174.87317577*T-8679.27034*A*i,s,t)}function _(e,t){u(e,Ee);var r=Ee.dayNumber-S.dayNumber+(Ee.secondsOfDay-S.secondsOfDay)/a.SECONDS_PER_DAY,i=r/a.DAYS_PER_JULIAN_CENTURY,n=i*i,o=n*i,s=o*i,l=383397.7725+.004*i,d=.055545526-1.6e-8*i,h=5.15668983*T,p=-8e-5*i+.02966*n-42e-6*o-1.3e-7*s,f=83.35324312*T,m=14643420.2669*i-38.2702*n-.045047*o+21301e-8*s,g=125.04455501*T,_=-6967919.3631*i+6.3602*n+.007625*o-3586e-8*s,v=218.31664563*T,y=1732559343.4847*i-6.391*n+.006588*o-3169e-8*s,C=297.85019547*T+A*(1602961601.209*i-6.3706*n+.006593*o-3169e-8*s),b=93.27209062*T+A*(1739527262.8478*i-12.7512*n-.001037*o+417e-8*s),E=134.96340251*T+A*(1717915923.2178*i+31.8792*n+.051635*o-2447e-7*s),x=357.52910918*T+A*(129596581.0481*i-.5532*n+136e-6*o-1149e-8*s),P=310.17137918*T-A*(6967051.436*i+6.2068*n+.007618*o-3219e-8*s),D=2*C,I=4*C,O=6*C,M=2*E,R=3*E,N=4*E,L=2*b;l+=3400.4*Math.cos(D)-635.6*Math.cos(D-E)-235.6*Math.cos(E)+218.1*Math.cos(D-x)+181*Math.cos(D+E),d+=.014216*Math.cos(D-E)+.008551*Math.cos(D-M)-.001383*Math.cos(E)+.001356*Math.cos(D+E)-.001147*Math.cos(I-R)-914e-6*Math.cos(I-M)+869e-6*Math.cos(D-x-E)-627e-6*Math.cos(D)-394e-6*Math.cos(I-N)+282e-6*Math.cos(D-x-M)-279e-6*Math.cos(C-E)-236e-6*Math.cos(M)+231e-6*Math.cos(I)+229e-6*Math.cos(O-N)-201e-6*Math.cos(M-L),p+=486.26*Math.cos(D-L)-40.13*Math.cos(D)+37.51*Math.cos(L)+25.73*Math.cos(M-L)+19.97*Math.cos(D-x-L),m+=-55609*Math.sin(D-E)-34711*Math.sin(D-M)-9792*Math.sin(E)+9385*Math.sin(I-R)+7505*Math.sin(I-M)+5318*Math.sin(D+E)+3484*Math.sin(I-N)-3417*Math.sin(D-x-E)-2530*Math.sin(O-N)-2376*Math.sin(D)-2075*Math.sin(D-R)-1883*Math.sin(M)-1736*Math.sin(O-5*E)+1626*Math.sin(x)-1370*Math.sin(O-R),_+=-5392*Math.sin(D-L)-540*Math.sin(x)-441*Math.sin(D)+423*Math.sin(L)-288*Math.sin(M-L),y+=-3332.9*Math.sin(D)+1197.4*Math.sin(D-E)-662.5*Math.sin(x)+396.3*Math.sin(E)-218*Math.sin(D-x);var k=2*P,F=3*P;p+=46.997*Math.cos(P)*i-.614*Math.cos(D-L+P)*i+.614*Math.cos(D-L-P)*i-.0297*Math.cos(k)*n-.0335*Math.cos(P)*n+.0012*Math.cos(D-L+k)*n-16e-5*Math.cos(P)*o+4e-5*Math.cos(F)*o+4e-5*Math.cos(k)*o;var B=2.116*Math.sin(P)*i-.111*Math.sin(D-L-P)*i-.0015*Math.sin(P)*n;return m+=B,y+=B,_+=-520.77*Math.sin(P)*i+13.66*Math.sin(D-L+P)*i+1.12*Math.sin(D-P)*i-1.06*Math.sin(L-P)*i+.66*Math.sin(k)*n+.371*Math.sin(P)*n-.035*Math.sin(D-L+k)*n-.015*Math.sin(D-L+P)*n+.0014*Math.sin(P)*o-.0011*Math.sin(F)*o-9e-4*Math.sin(k)*o,l*=w,c(l,d,h+p*A,f+m*A,g+_*A,v+y*A,t)}function v(t,r){return r=_(t,r),e.multiplyByScalar(r,xe,r)}var y={},C=32.184,b=2451545,S=new i(2451545,0,s.TAI),w=1e3,T=n.RADIANS_PER_DEGREE,A=n.RADIANS_PER_ARCSECOND,E=new o,x=50,P=n.EPSILON8,D=149598022260.7121,I=100.46645683*T,O=1295977422.83429*A,M=16002,R=21863,N=32004,L=10931,k=14529,F=16368,B=15318,U=32794,V=64e-7*14959787e4,z=-2273887.624,G=927506.794,H=14959787e4*-8e-7,W=32e-7*14959787e4,j=-613351.267,q=284235.953,Y=-164557.657,X=-2243968.05,Q=-688150.202,Z=1017265.516,K=807828.498,J=14e-7*14959787e4,$=359034.888,ee=14959787e4*-28e-7,te=329115.314,re=10,ie=16002,ne=21863,oe=10931,ae=1473,se=32004,le=4387,ue=73,ce=-325e-7,de=-322e-7,he=1e-7*-79,pe=232*1e-7,fe=1e-7*-52,me=97e-7,ge=55e-7,_e=-41e-7,ve=-105e-7,ye=-137e-7,Ce=258e-7,be=35e-7,Se=1e-7*-116,we=-88e-7,Te=-112e-7,Ae=-8e-6,Ee=new i(0,0,s.TAI),xe=-.01215058143522694,Pe=new o(1.0000000000000002,5.619723173785822e-16,4.690511510146299e-19,-5.154129427414611e-16,.9174820620691819,-.39777715593191376,-2.23970096136568e-16,.39777715593191376,.9174820620691819),De=new e;return y.computeSunPositionInEarthInertialFrame=function(r,n){return t(r)||(r=i.now()),t(n)||(n=new e),De=g(r,De),n=e.negate(De,n),v(r,De),e.subtract(n,De,n),o.multiplyByVector(Pe,n,n),n},y.computeMoonPositionInEarthInertialFrame=function(e,r){return t(e)||(e=i.now()),r=_(e,r),o.multiplyByVector(Pe,r,r),r},y}),define("Core/SimplePolylineGeometry",["./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e,t,i,n,o,a,s){var l,u=p.numberOfPoints(e,t,o),c=i.red,d=i.green,h=i.blue,f=i.alpha,m=n.red,g=n.green,_=n.blue,v=n.alpha;if(r.equals(i,n)){for(l=0;l0?new Array(u):void 0;for(l=0;l0&&(t.pack(q,s,W),W+=3,b=w[a-1],C[j++]=r.floatToByte(b.red),C[j++]=r.floatToByte(b.green),C[j++]=r.floatToByte(b.blue),C[j++]=r.floatToByte(b.alpha)),D&&a===I-1)break;t.pack(q,s,W),W+=3,o(w)&&(b=w[a],C[j++]=r.floatToByte(b.red),C[j++]=r.floatToByte(b.green),C[j++]=r.floatToByte(b.blue),C[j++]=r.floatToByte(b.alpha))}}var Y=new c;Y.position=new u({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:s}),o(w)&&(Y.color=new u({componentDatatype:i.UNSIGNED_BYTE,componentsPerAttribute:4,values:C,normalize:!0})),g=s.length/3;var X=2*(g-1),Q=d.createTypedArray(g,X),Z=0;for(a=0;a=1e3&&(o+=Math.floor(n/1e3),n%=1e3),o>=60&&(a+=Math.floor(o/60),o%=60),a>=60&&(l+=Math.floor(a/60),a%=60),l>=24&&(c+=Math.floor(l/24),l%=24),_[2]=s(h)?29:28;c>_[d]||d>=13;)c>_[d]&&(c-=_[d],++d),d>=13&&(--d,h+=Math.floor(d/12),d%=12,++d),_[2]=s(h)?29:28;return g.millisecond=n,g.second=o,g.minute=a,g.hour=l,g.day=c,g.month=d,g.year=h,u.fromGregorianDate(g,i)}function f(e,t){if(!r(e)||0===e.length)return!1;if(t.year=0,t.month=0,t.day=0,t.hour=0,t.minute=0,t.second=0,t.millisecond=0,"P"===e[0]){var i=e.match(y);if(!r(i))return!1;if(r(i[1])&&(t.year=Number(i[1].replace(",","."))),r(i[2])&&(t.month=Number(i[2].replace(",","."))),r(i[3])&&(t.day=7*Number(i[3].replace(",","."))),r(i[4])&&(t.day+=Number(i[4].replace(",","."))),r(i[5])&&(t.hour=Number(i[5].replace(",","."))),r(i[6])&&(t.minute=Number(i[6].replace(",","."))),r(i[7])){var n=Number(i[7].replace(",","."));t.second=Math.floor(n),t.millisecond=n%1*1e3}}else"Z"!==e[e.length-1]&&(e+="Z"),u.toGregorianDate(u.fromIso8601(e,v),t);return t.year||t.month||t.day||t.hour||t.minute||t.second||t.millisecond}i(h.prototype,{changedEvent:{get:function(){return this._changedEvent}},start:{get:function(){var e=this._intervals;return 0===e.length?void 0:e[0].start}},isStartIncluded:{get:function(){var e=this._intervals;return 0!==e.length&&e[0].isStartIncluded}},stop:{get:function(){var e=this._intervals,t=e.length;return 0===t?void 0:e[t-1].stop}},isStopIncluded:{get:function(){var e=this._intervals,t=e.length;return 0!==t&&e[t-1].isStopIncluded}},length:{get:function(){return this._intervals.length}},isEmpty:{get:function(){return 0===this._intervals.length}}}),h.prototype.equals=function(e,t){if(this===e)return!0;if(!(e instanceof h))return!1;var r=this._intervals,i=e._intervals,n=r.length;if(n!==i.length)return!1;for(var o=0;o0&&(this._intervals.length=0,this._changedEvent.raiseEvent(this))},h.prototype.findIntervalContainingDate=function(e){var t=this.indexOf(e);return t>=0?this._intervals[t]:void 0},h.prototype.findDataForIntervalContainingDate=function(e){var t=this.indexOf(e);return t>=0?this._intervals[t].data:void 0},h.prototype.contains=function(e){return this.indexOf(e)>=0};var m=new c;h.prototype.indexOf=function(t){var r=this._intervals;m.start=t,m.stop=t;var i=e(r,m,d);return i>=0?r[i].isStartIncluded?i:i>0&&r[i-1].stop.equals(t)&&r[i-1].isStopIncluded?i-1:~i:(i=~i,i>0&&i-10&&t.isStartIncluded&&a[o-1].isStartIncluded&&a[o-1].start.equals(t.start)?--o:o0&&((n=u.compare(a[o-1].stop,t.start))>0||0===n&&(a[o-1].isStopIncluded||t.isStartIncluded))&&((r(i)?i(a[o-1].data,t.data):a[o-1].data===t.data)?(t=new c(u.greaterThan(t.stop,a[o-1].stop)?{start:a[o-1].start,stop:t.stop,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:t.isStopIncluded,data:t.data}:{start:a[o-1].start,stop:a[o-1].stop,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:a[o-1].isStopIncluded||t.stop.equals(a[o-1].stop)&&t.isStopIncluded,data:t.data}),a.splice(o-1,1),--o):(n=u.compare(a[o-1].stop,t.stop),n>0||0===n&&a[o-1].isStopIncluded&&!t.isStopIncluded?a.splice(o-1,1,new c({start:a[o-1].start,stop:t.start,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:!t.isStartIncluded,data:a[o-1].data}),new c({start:t.stop,stop:a[o-1].stop,isStartIncluded:!t.isStopIncluded,isStopIncluded:a[o-1].isStopIncluded,data:a[o-1].data})):a[o-1]=new c({start:a[o-1].start,stop:t.start,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:!t.isStartIncluded,data:a[o-1].data})));o0||0===n&&(t.isStopIncluded||a[o].isStartIncluded));)if(r(i)?i(a[o].data,t.data):a[o].data===t.data)t=new c({start:t.start,stop:u.greaterThan(a[o].stop,t.stop)?a[o].stop:t.stop,isStartIncluded:t.isStartIncluded,isStopIncluded:u.greaterThan(a[o].stop,t.stop)?a[o].isStopIncluded:t.isStopIncluded,data:t.data}),a.splice(o,1);else{if(a[o]=new c({start:t.stop,stop:a[o].stop,isStartIncluded:!t.isStopIncluded,isStopIncluded:a[o].isStopIncluded,data:a[o].data}),!a[o].isEmpty)break;a.splice(o,1)}a.splice(o,0,t),this._changedEvent.raiseEvent(this)}},h.prototype.removeInterval=function(t){if(t.isEmpty)return!1;var r=!1,i=this._intervals,n=e(i,t,d);n<0&&(n=~n);var o=t.start,a=t.stop,s=t.isStartIncluded,l=t.isStopIncluded;if(n>0){var h=i[n-1],p=h.stop;(u.greaterThan(p,o)||c.equals(p,o)&&h.isStopIncluded&&s)&&(r=!0,(u.greaterThan(p,a)||h.isStopIncluded&&!l&&c.equals(p,a))&&i.splice(n,0,new c({start:a,stop:p,isStartIncluded:!l,isStopIncluded:h.isStopIncluded,data:h.data})),i[n-1]=new c({start:h.start,stop:o,isStartIncluded:h.isStartIncluded,isStopIncluded:!s,data:h.data}))}var f=i[n];for(nh?h:d<0?0:d;var f=s?e(this.tolerance,1):.001;Math.abs(l-p)>f&&(this._seeking=!0,i.currentTime=l)}},a}),define("Core/VRTheWorldTerrainProvider",["../ThirdParty/when","./Credit","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Event","./GeographicTilingScheme","./getImagePixels","./HeightmapTerrainData","./loadImage","./loadXML","./Math","./Rectangle","./TerrainProvider","./TileProviderError"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e,t){this.rectangle=e,this.maxLevel=t}function v(i){function n(e){var t=e.getElementsByTagName("SRS")[0].textContent;if("EPSG:4326"!==t)return void o("SRS "+t+" is not supported.");v._tilingScheme=new l({ellipsoid:y});var r=e.getElementsByTagName("TileFormat")[0];v._heightmapWidth=parseInt(r.getAttribute("width"),10),v._heightmapHeight=parseInt(r.getAttribute("height"),10),v._levelZeroMaximumGeometricError=m.getEstimatedLevelZeroGeometricErrorForAHeightmap(y,Math.min(v._heightmapWidth,v._heightmapHeight),v._tilingScheme.getNumberOfXTilesAtLevel(0));for(var i=e.getElementsByTagName("DataExtent"),n=0;n0&&"/"!==this._url[this._url.length-1]&&(this._url+="/"),this._errorEvent=new s,this._ready=!1,this._readyPromise=e.defer(),this._proxy=i.proxy,this._terrainDataStructure={heightScale:.001,heightOffset:-1e3,elementsPerHeight:3,stride:4,elementMultiplier:256,isBigEndian:!0,lowestEncodedHeight:0,highestEncodedHeight:16777215};var c=i.credit;"string"==typeof c&&(c=new t({text:c})),this._credit=c,this._tilingScheme=void 0,this._rectangles=[];var d,v=this,y=r(i.ellipsoid,a.WGS84);u()}function y(e,t,r,n){for(var o=e._tilingScheme,a=e._rectangles,s=o.tileXYToRectangle(t,r,n),l=0,u=0;u=3){var _=r.fromPoints(s,e),v=_.projectPointsOntoPlane(s);n.computeWindingOrder2D(v)===a.CLOCKWISE&&(s.reverse(),u.reverse(),c.reverse())}var y,C,b=s.length,S=b-2,w=i.chordLength(d,e.maximumRadius),T=f;if(T.minDistance=w,T.ellipsoid=e,m){var A,E=0;for(A=0;A0)for(c=new Array(l),s=0;s0)for(d=new Array(l),s=0;s0)for(c=new Array(l),s=0;s0)for(d=new Array(l),s=0;s=s&&(_=s-1);var v=g/h|0;return v>=l&&(v=l-1),r(n)?(n.x=_,n.y=v,n):new e(_,v)}},s}),define("Core/WeightSpline",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./Spline"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT);var r=e.weights,i=e.times;this._times=i,this._weights=r,this._count=r.length/i.length,this._lastTimeIndex=0}return i(a.prototype,{times:{get:function(){return this._times}},weights:{get:function(){return this._weights}}}),a.prototype.findTimeInterval=o.prototype.findTimeInterval,a.prototype.wrapTime=o.prototype.wrapTime,a.prototype.clampTime=o.prototype.clampTime,a.prototype.evaluate=function(e,t){var i=this.weights,n=this.times,o=this._lastTimeIndex=this.findTimeInterval(e,this._lastTimeIndex),a=(e-n[o])/(n[o+1]-n[o]);r(t)||(t=new Array(this._count));for(var s=0;s-1;n--)a=t[n],o(a._billboard)&&o(a._position)&&s.set(a.id,new m(a));for(n=i.length-1;n>-1;n--)a=i[n],o(a._billboard)&&o(a._position)?s.contains(a.id)||s.set(a.id,new m(a)):(_(s.get(a.id),a,l),s.remove(a.id));for(n=r.length-1;n>-1;n--)a=r[n],_(s.get(a.id),a,l),s.remove(a.id)},g}),define("Shaders/Appearances/AllMaterialAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec3 v_tangentEC;\nvarying vec3 v_bitangentEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nmat3 tangentToEyeMatrix = czm_tangentToEyeSpaceMatrix(v_normalEC, v_tangentEC, v_bitangentEC);\nvec3 normalEC = normalize(v_normalEC);\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.tangentToEyeMatrix = tangentToEyeMatrix;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nmaterialInput.st = v_st;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/AllMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute vec3 tangent;\nattribute vec3 bitangent;\nattribute vec2 st;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec3 v_tangentEC;\nvarying vec3 v_bitangentEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\nv_tangentEC = czm_normal * tangent;\nv_bitangentEC = czm_normal * bitangent;\nv_st = st;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Shaders/Appearances/BasicMaterialAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nvec3 normalEC = normalize(v_normalEC);\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/BasicMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Shaders/Appearances/TexturedMaterialAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nvec3 normalEC = normalize(v_normalEC);;\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nmaterialInput.st = v_st;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/TexturedMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute vec2 st;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\nv_st = st;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Scene/BlendEquation",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({ADD:t.FUNC_ADD,SUBTRACT:t.FUNC_SUBTRACT,REVERSE_SUBTRACT:t.FUNC_REVERSE_SUBTRACT,MIN:t.MIN,MAX:t.MAX})}),define("Scene/BlendFunction",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({ZERO:t.ZERO,ONE:t.ONE,SOURCE_COLOR:t.SRC_COLOR,ONE_MINUS_SOURCE_COLOR:t.ONE_MINUS_SRC_COLOR,DESTINATION_COLOR:t.DST_COLOR,ONE_MINUS_DESTINATION_COLOR:t.ONE_MINUS_DST_COLOR,SOURCE_ALPHA:t.SRC_ALPHA,ONE_MINUS_SOURCE_ALPHA:t.ONE_MINUS_SRC_ALPHA,DESTINATION_ALPHA:t.DST_ALPHA,ONE_MINUS_DESTINATION_ALPHA:t.ONE_MINUS_DST_ALPHA,CONSTANT_COLOR:t.CONSTANT_COLOR,ONE_MINUS_CONSTANT_COLOR:t.ONE_MINUS_CONSTANT_ALPHA,CONSTANT_ALPHA:t.CONSTANT_ALPHA,ONE_MINUS_CONSTANT_ALPHA:t.ONE_MINUS_CONSTANT_ALPHA,SOURCE_ALPHA_SATURATE:t.SRC_ALPHA_SATURATE})}),define("Scene/BlendingState",["../Core/freezeObject","./BlendEquation","./BlendFunction"],function(e,t,r){"use strict";return e({DISABLED:e({enabled:!1}),ALPHA_BLEND:e({enabled:!0,equationRgb:t.ADD,equationAlpha:t.ADD,functionSourceRgb:r.SOURCE_ALPHA,functionSourceAlpha:r.SOURCE_ALPHA,functionDestinationRgb:r.ONE_MINUS_SOURCE_ALPHA,functionDestinationAlpha:r.ONE_MINUS_SOURCE_ALPHA}),PRE_MULTIPLIED_ALPHA_BLEND:e({enabled:!0,equationRgb:t.ADD,equationAlpha:t.ADD,functionSourceRgb:r.ONE,functionSourceAlpha:r.ONE,functionDestinationRgb:r.ONE_MINUS_SOURCE_ALPHA,functionDestinationAlpha:r.ONE_MINUS_SOURCE_ALPHA}),ADDITIVE_BLEND:e({enabled:!0,equationRgb:t.ADD,equationAlpha:t.ADD,functionSourceRgb:r.SOURCE_ALPHA,functionSourceAlpha:r.SOURCE_ALPHA,functionDestinationRgb:r.ONE,functionDestinationAlpha:r.ONE})})}),define("Scene/CullFace",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({FRONT:t.FRONT,BACK:t.BACK,FRONT_AND_BACK:t.FRONT_AND_BACK})}),define("Scene/Appearance",["../Core/clone","../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","./BlendingState","./CullFace"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this.material=e.material,this.translucent=r(e.translucent,!0),this._vertexShaderSource=e.vertexShaderSource,this._fragmentShaderSource=e.fragmentShaderSource,this._renderState=e.renderState,this._closed=r(e.closed,!1)}return n(s.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}}}),s.prototype.getFragmentShaderSource=function(){var e=[];return this.flat&&e.push("#define FLAT"),this.faceForward&&e.push("#define FACE_FORWARD"),i(this.material)&&e.push(this.material.shaderSource),e.push(this.fragmentShaderSource),e.join("\n")},s.prototype.isTranslucent=function(){return i(this.material)&&this.material.isTranslucent()||!i(this.material)&&this.translucent},s.prototype.getRenderState=function(){var t=this.isTranslucent(),r=e(this.renderState,!1);return t?(r.depthMask=!1,r.blending=o.ALPHA_BLEND):r.depthMask=!0,r},s.getDefaultRenderState=function(e,r,n){var s={depthTest:{enabled:!0}};return e&&(s.depthMask=!1,s.blending=o.ALPHA_BLEND),r&&(s.cull={enabled:!0,face:a.BACK}),i(n)&&(s=t(n,s,!0)),s},s}),define("Renderer/ContextLimits",["../Core/defineProperties"],function(e){"use strict";var t={_maximumCombinedTextureImageUnits:0,_maximumCubeMapSize:0,_maximumFragmentUniformVectors:0,_maximumTextureImageUnits:0,_maximumRenderbufferSize:0,_maximumTextureSize:0,_maximumVaryingVectors:0,_maximumVertexAttributes:0,_maximumVertexTextureImageUnits:0,_maximumVertexUniformVectors:0,_minimumAliasedLineWidth:0,_maximumAliasedLineWidth:0,_minimumAliasedPointSize:0,_maximumAliasedPointSize:0,_maximumViewportWidth:0,_maximumViewportHeight:0,_maximumTextureFilterAnisotropy:0,_maximumDrawBuffers:0,_maximumColorAttachments:0,_highpFloatSupported:!1,_highpIntSupported:!1};return e(t,{maximumCombinedTextureImageUnits:{get:function(){return t._maximumCombinedTextureImageUnits}},maximumCubeMapSize:{get:function(){return t._maximumCubeMapSize}},maximumFragmentUniformVectors:{get:function(){return t._maximumFragmentUniformVectors}},maximumTextureImageUnits:{get:function(){return t._maximumTextureImageUnits}},maximumRenderbufferSize:{get:function(){return t._maximumRenderbufferSize}},maximumTextureSize:{get:function(){return t._maximumTextureSize}},maximumVaryingVectors:{get:function(){return t._maximumVaryingVectors}},maximumVertexAttributes:{get:function(){return t._maximumVertexAttributes}},maximumVertexTextureImageUnits:{get:function(){return t._maximumVertexTextureImageUnits}},maximumVertexUniformVectors:{get:function(){return t._maximumVertexUniformVectors}},minimumAliasedLineWidth:{get:function(){return t._minimumAliasedLineWidth}},maximumAliasedLineWidth:{get:function(){return t._maximumAliasedLineWidth}},minimumAliasedPointSize:{get:function(){return t._minimumAliasedPointSize}},maximumAliasedPointSize:{get:function(){return t._maximumAliasedPointSize}},maximumViewportWidth:{get:function(){return t._maximumViewportWidth}},maximumViewportHeight:{get:function(){return t._maximumViewportHeight}},maximumTextureFilterAnisotropy:{get:function(){return t._maximumTextureFilterAnisotropy}},maximumDrawBuffers:{get:function(){return t._maximumDrawBuffers}},maximumColorAttachments:{get:function(){return t._maximumColorAttachments}},highpFloatSupported:{get:function(){return t._highpFloatSupported}},highpIntSupported:{get:function(){return t._highpIntSupported}}}),t}),define("Renderer/CubeMapFace",["../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/DeveloperError","./PixelDatatype"],function(e,t,r,i,n){"use strict";function o(e,t,r,i,n,o,a,s,l){this._gl=e,this._texture=t,this._textureTarget=r,this._targetFace=i,this._pixelFormat=n,this._pixelDatatype=o,this._size=a,this._preMultiplyAlpha=s,this._flipY=l}return r(o.prototype,{pixelFormat:{get:function(){return this._pixelFormat}},pixelDatatype:{get:function(){return this._pixelDatatype}},_target:{get:function(){return this._targetFace}}}),o.prototype.copyFrom=function(e,r,i){r=t(r,0),i=t(i,0);var n=this._gl,o=this._textureTarget;n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this._preMultiplyAlpha),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,this._flipY),n.activeTexture(n.TEXTURE0),n.bindTexture(o,this._texture),e.arrayBufferView?n.texSubImage2D(this._targetFace,0,r,i,e.width,e.height,this._pixelFormat,this._pixelDatatype,e.arrayBufferView):n.texSubImage2D(this._targetFace,0,r,i,this._pixelFormat,this._pixelDatatype,e),n.bindTexture(o,null)},o.prototype.copyFromFramebuffer=function(e,r,i,n,o,a){e=t(e,0),r=t(r,0),i=t(i,0),n=t(n,0),o=t(o,this._size),a=t(a,this._size);var s=this._gl,l=this._textureTarget;s.activeTexture(s.TEXTURE0),s.bindTexture(l,this._texture),s.copyTexSubImage2D(this._targetFace,0,e,r,i,n,o,a),s.bindTexture(l,null)},o}),define("Renderer/MipmapHint",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={DONT_CARE:t.DONT_CARE,FASTEST:t.FASTEST,NICEST:t.NICEST,validate:function(e){return e===r.DONT_CARE||e===r.FASTEST||e===r.NICEST}};return e(r)}),define("Renderer/TextureMagnificationFilter",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={NEAREST:t.NEAREST,LINEAR:t.LINEAR,validate:function(e){return e===r.NEAREST||e===r.LINEAR}};return e(r)}),define("Renderer/TextureMinificationFilter",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={NEAREST:t.NEAREST,LINEAR:t.LINEAR,NEAREST_MIPMAP_NEAREST:t.NEAREST_MIPMAP_NEAREST,LINEAR_MIPMAP_NEAREST:t.LINEAR_MIPMAP_NEAREST, -NEAREST_MIPMAP_LINEAR:t.NEAREST_MIPMAP_LINEAR,LINEAR_MIPMAP_LINEAR:t.LINEAR_MIPMAP_LINEAR,validate:function(e){return e===r.NEAREST||e===r.LINEAR||e===r.NEAREST_MIPMAP_NEAREST||e===r.LINEAR_MIPMAP_NEAREST||e===r.NEAREST_MIPMAP_LINEAR||e===r.LINEAR_MIPMAP_LINEAR}};return e(r)}),define("Renderer/TextureWrap",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={CLAMP_TO_EDGE:t.CLAMP_TO_EDGE,REPEAT:t.REPEAT,MIRRORED_REPEAT:t.MIRRORED_REPEAT,validate:function(e){return e===r.CLAMP_TO_EDGE||e===r.REPEAT||e===r.MIRRORED_REPEAT}};return e(r)}),define("Renderer/Sampler",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","./TextureMagnificationFilter","./TextureMinificationFilter","./TextureWrap"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT);var i=t(e.wrapS,s.CLAMP_TO_EDGE),n=t(e.wrapT,s.CLAMP_TO_EDGE),l=t(e.minificationFilter,a.LINEAR),u=t(e.magnificationFilter,o.LINEAR),c=r(e.maximumAnisotropy)?e.maximumAnisotropy:1;this._wrapS=i,this._wrapT=n,this._minificationFilter=l,this._magnificationFilter=u,this._maximumAnisotropy=c}return i(l.prototype,{wrapS:{get:function(){return this._wrapS}},wrapT:{get:function(){return this._wrapT}},minificationFilter:{get:function(){return this._minificationFilter}},magnificationFilter:{get:function(){return this._magnificationFilter}},maximumAnisotropy:{get:function(){return this._maximumAnisotropy}}}),l}),define("Renderer/CubeMap",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Math","../Core/PixelFormat","./ContextLimits","./CubeMapFace","./MipmapHint","./PixelDatatype","./Sampler","./TextureMagnificationFilter","./TextureMinificationFilter"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){function i(e,t){t.arrayBufferView?v.texImage2D(e,0,p,c,c,0,p,f,t.arrayBufferView):v.texImage2D(e,0,p,p,f,t)}e=t(e,t.EMPTY_OBJECT);var n,o=e.context,a=e.source;if(r(a)){var l=[a.positiveX,a.negativeX,a.positiveY,a.negativeY,a.positiveZ,a.negativeZ];n=l[0].width,l[0].height}else n=e.width,e.height;var c=n,p=t(e.pixelFormat,s.RGBA),f=t(e.pixelDatatype,d.UNSIGNED_BYTE),m=6*s.textureSizeInBytes(p,f,c,c),g=e.preMultiplyAlpha||p===s.RGB||p===s.LUMINANCE,_=t(e.flipY,!0),v=o._gl,y=v.TEXTURE_CUBE_MAP,C=v.createTexture();v.activeTexture(v.TEXTURE0),v.bindTexture(y,C),r(a)?(v.pixelStorei(v.UNPACK_PREMULTIPLY_ALPHA_WEBGL,g),v.pixelStorei(v.UNPACK_FLIP_Y_WEBGL,_),i(v.TEXTURE_CUBE_MAP_POSITIVE_X,a.positiveX),i(v.TEXTURE_CUBE_MAP_NEGATIVE_X,a.negativeX),i(v.TEXTURE_CUBE_MAP_POSITIVE_Y,a.positiveY),i(v.TEXTURE_CUBE_MAP_NEGATIVE_Y,a.negativeY),i(v.TEXTURE_CUBE_MAP_POSITIVE_Z,a.positiveZ),i(v.TEXTURE_CUBE_MAP_NEGATIVE_Z,a.negativeZ)):(v.texImage2D(v.TEXTURE_CUBE_MAP_POSITIVE_X,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_NEGATIVE_X,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_POSITIVE_Y,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_NEGATIVE_Y,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_POSITIVE_Z,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_NEGATIVE_Z,0,p,c,c,0,p,f,null)),v.bindTexture(y,null),this._gl=v,this._textureFilterAnisotropic=o._textureFilterAnisotropic,this._textureTarget=y,this._texture=C,this._pixelFormat=p,this._pixelDatatype=f,this._size=c,this._hasMipmap=!1,this._sizeInBytes=m,this._preMultiplyAlpha=g,this._flipY=_,this._sampler=void 0,this._positiveX=new u(v,C,y,v.TEXTURE_CUBE_MAP_POSITIVE_X,p,f,c,g,_),this._negativeX=new u(v,C,y,v.TEXTURE_CUBE_MAP_NEGATIVE_X,p,f,c,g,_),this._positiveY=new u(v,C,y,v.TEXTURE_CUBE_MAP_POSITIVE_Y,p,f,c,g,_),this._negativeY=new u(v,C,y,v.TEXTURE_CUBE_MAP_NEGATIVE_Y,p,f,c,g,_),this._positiveZ=new u(v,C,y,v.TEXTURE_CUBE_MAP_POSITIVE_Z,p,f,c,g,_),this._negativeZ=new u(v,C,y,v.TEXTURE_CUBE_MAP_NEGATIVE_Z,p,f,c,g,_),this.sampler=r(e.sampler)?e.sampler:new h}return i(m.prototype,{positiveX:{get:function(){return this._positiveX}},negativeX:{get:function(){return this._negativeX}},positiveY:{get:function(){return this._positiveY}},negativeY:{get:function(){return this._negativeY}},positiveZ:{get:function(){return this._positiveZ}},negativeZ:{get:function(){return this._negativeZ}},sampler:{get:function(){return this._sampler},set:function(e){var t=e.minificationFilter,i=e.magnificationFilter,n=t===f.NEAREST_MIPMAP_NEAREST||t===f.NEAREST_MIPMAP_LINEAR||t===f.LINEAR_MIPMAP_NEAREST||t===f.LINEAR_MIPMAP_LINEAR;this._pixelDatatype===d.FLOAT&&(t=n?f.NEAREST_MIPMAP_NEAREST:f.NEAREST,i=p.NEAREST);var o=this._gl,a=this._textureTarget;o.activeTexture(o.TEXTURE0),o.bindTexture(a,this._texture),o.texParameteri(a,o.TEXTURE_MIN_FILTER,t),o.texParameteri(a,o.TEXTURE_MAG_FILTER,i),o.texParameteri(a,o.TEXTURE_WRAP_S,e.wrapS),o.texParameteri(a,o.TEXTURE_WRAP_T,e.wrapT),r(this._textureFilterAnisotropic)&&o.texParameteri(a,this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,e.maximumAnisotropy),o.bindTexture(a,null),this._sampler=e}},pixelFormat:{get:function(){return this._pixelFormat}},pixelDatatype:{get:function(){return this._pixelDatatype}},width:{get:function(){return this._size}},height:{get:function(){return this._size}},sizeInBytes:{get:function(){return this._hasMipmap?Math.floor(4*this._sizeInBytes/3):this._sizeInBytes}},preMultiplyAlpha:{get:function(){return this._preMultiplyAlpha}},flipY:{get:function(){return this._flipY}},_target:{get:function(){return this._textureTarget}}}),m.prototype.generateMipmap=function(e){e=t(e,c.DONT_CARE),this._hasMipmap=!0;var r=this._gl,i=this._textureTarget;r.hint(r.GENERATE_MIPMAP_HINT,e),r.activeTexture(r.TEXTURE0),r.bindTexture(i,this._texture),r.generateMipmap(i),r.bindTexture(i,null)},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){return this._gl.deleteTexture(this._texture),this._positiveX=n(this._positiveX),this._negativeX=n(this._negativeX),this._positiveY=n(this._positiveY),this._negativeY=n(this._negativeY),this._positiveZ=n(this._positiveZ),this._negativeZ=n(this._negativeZ),n(this)},m}),define("Renderer/Texture",["../Core/Cartesian2","../Core/Check","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Math","../Core/PixelFormat","../Core/WebGLConstants","./ContextLimits","./MipmapHint","./PixelDatatype","./Sampler","./TextureMagnificationFilter","./TextureMinificationFilter"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(t){t=i(t,i.EMPTY_OBJECT);var o=t.context,a=t.width,s=t.height,l=t.source;n(l)&&(n(a)||(a=i(l.videoWidth,l.width)),n(s)||(s=i(l.videoHeight,l.height)));var d=i(t.pixelFormat,u.RGBA),h=i(t.pixelDatatype,p.UNSIGNED_BYTE),m=d,g=u.isCompressedFormat(m);if(o.webgl2&&(d===u.DEPTH_STENCIL?m=c.DEPTH24_STENCIL8:d===u.DEPTH_COMPONENT&&(h===p.UNSIGNED_SHORT?m=c.DEPTH_COMPONENT16:h===p.UNSIGNED_INT&&(m=c.DEPTH_COMPONENT24)),h===p.FLOAT))switch(d){case u.RGBA:m=c.RGBA32F;break;case u.RGB:m=c.RGB32F;break;case u.RG:m=c.RG32F;break;case u.R:m=c.R32F}var _=t.preMultiplyAlpha||d===u.RGB||d===u.LUMINANCE,v=i(t.flipY,!0),y=o._gl,C=y.TEXTURE_2D,b=y.createTexture();y.activeTexture(y.TEXTURE0),y.bindTexture(C,b),n(l)?(y.pixelStorei(y.UNPACK_PREMULTIPLY_ALPHA_WEBGL,_),y.pixelStorei(y.UNPACK_FLIP_Y_WEBGL,v),n(l.arrayBufferView)?g?y.compressedTexImage2D(C,0,m,a,s,0,l.arrayBufferView):y.texImage2D(C,0,m,a,s,0,d,h,l.arrayBufferView):n(l.framebuffer)?(l.framebuffer!==o.defaultFramebuffer&&l.framebuffer._bind(),y.copyTexImage2D(C,0,m,l.xOffset,l.yOffset,a,s,0),l.framebuffer!==o.defaultFramebuffer&&l.framebuffer._unBind()):y.texImage2D(C,0,m,d,h,l)):y.texImage2D(C,0,m,a,s,0,d,h,null),y.bindTexture(C,null);var S;S=g?u.compressedTextureSizeInBytes(d,a,s):u.textureSizeInBytes(d,h,a,s),this._id=r(),this._context=o,this._textureFilterAnisotropic=o._textureFilterAnisotropic,this._textureTarget=C,this._texture=b,this._pixelFormat=d,this._pixelDatatype=h,this._width=a,this._height=s,this._dimensions=new e(a,s),this._hasMipmap=!1,this._sizeInBytes=S,this._preMultiplyAlpha=_,this._flipY=v,this._sampler=void 0,this.sampler=n(t.sampler)?t.sampler:new f}return _.fromFramebuffer=function(e){e=i(e,i.EMPTY_OBJECT);var t=e.context,r=t._gl,o=i(e.pixelFormat,u.RGB),a=i(e.framebufferXOffset,0),s=i(e.framebufferYOffset,0),l=i(e.width,r.drawingBufferWidth),c=i(e.height,r.drawingBufferHeight),d=e.framebuffer;return new _({context:t,width:l,height:c,pixelFormat:o,source:{framebuffer:n(d)?d:t.defaultFramebuffer,xOffset:a,yOffset:s,width:l,height:c}})},o(_.prototype,{id:{get:function(){return this._id}},sampler:{get:function(){return this._sampler},set:function(e){var t=e.minificationFilter,r=e.magnificationFilter,i=t===g.NEAREST_MIPMAP_NEAREST||t===g.NEAREST_MIPMAP_LINEAR||t===g.LINEAR_MIPMAP_NEAREST||t===g.LINEAR_MIPMAP_LINEAR;this._pixelDatatype===p.FLOAT&&(t=i?g.NEAREST_MIPMAP_NEAREST:g.NEAREST,r=m.NEAREST);var o=this._context._gl,a=this._textureTarget;o.activeTexture(o.TEXTURE0),o.bindTexture(a,this._texture),o.texParameteri(a,o.TEXTURE_MIN_FILTER,t),o.texParameteri(a,o.TEXTURE_MAG_FILTER,r),o.texParameteri(a,o.TEXTURE_WRAP_S,e.wrapS),o.texParameteri(a,o.TEXTURE_WRAP_T,e.wrapT),n(this._textureFilterAnisotropic)&&o.texParameteri(a,this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,e.maximumAnisotropy),o.bindTexture(a,null),this._sampler=e}},pixelFormat:{get:function(){return this._pixelFormat}},pixelDatatype:{get:function(){return this._pixelDatatype}},dimensions:{get:function(){return this._dimensions}},preMultiplyAlpha:{get:function(){return this._preMultiplyAlpha}},flipY:{get:function(){return this._flipY}},width:{get:function(){return this._width}},height:{get:function(){return this._height}},sizeInBytes:{get:function(){return this._hasMipmap?Math.floor(4*this._sizeInBytes/3):this._sizeInBytes}},_target:{get:function(){return this._textureTarget}}}),_.prototype.copyFrom=function(e,t,r){t=i(t,0),r=i(r,0);var n=this._context._gl,o=this._textureTarget;n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this._preMultiplyAlpha),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,this._flipY),n.activeTexture(n.TEXTURE0),n.bindTexture(o,this._texture),e.arrayBufferView?n.texSubImage2D(o,0,t,r,e.width,e.height,this._pixelFormat,this._pixelDatatype,e.arrayBufferView):n.texSubImage2D(o,0,t,r,this._pixelFormat,this._pixelDatatype,e),n.bindTexture(o,null)},_.prototype.copyFromFramebuffer=function(e,t,r,n,o,a){e=i(e,0),t=i(t,0),r=i(r,0),n=i(n,0),o=i(o,this._width),a=i(a,this._height);var s=this._context._gl,l=this._textureTarget;s.activeTexture(s.TEXTURE0),s.bindTexture(l,this._texture),s.copyTexSubImage2D(l,0,e,t,r,n,o,a),s.bindTexture(l,null)},_.prototype.generateMipmap=function(e){e=i(e,h.DONT_CARE),this._hasMipmap=!0;var t=this._context._gl,r=this._textureTarget;t.hint(t.GENERATE_MIPMAP_HINT,e),t.activeTexture(t.TEXTURE0),t.bindTexture(r,this._texture),t.generateMipmap(r),t.bindTexture(r,null)},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return this._context._gl.deleteTexture(this._texture),a(this)},_}),define("Shaders/Materials/BumpMapMaterial",[],function(){"use strict";return"uniform sampler2D image;\nuniform float strength;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nvec2 centerPixel = fract(repeat * st);\nfloat centerBump = texture2D(image, centerPixel).channel;\nfloat imageWidth = float(imageDimensions.x);\nvec2 rightPixel = fract(repeat * (st + vec2(1.0 / imageWidth, 0.0)));\nfloat rightBump = texture2D(image, rightPixel).channel;\nfloat imageHeight = float(imageDimensions.y);\nvec2 leftPixel = fract(repeat * (st + vec2(0.0, 1.0 / imageHeight)));\nfloat topBump = texture2D(image, leftPixel).channel;\nvec3 normalTangentSpace = normalize(vec3(centerBump - rightBump, centerBump - topBump, clamp(1.0 - strength, 0.1, 1.0)));\nvec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\nmaterial.normal = normalEC;\nmaterial.diffuse = vec3(0.01);\nreturn material;\n}\n"}),define("Shaders/Materials/CheckerboardMaterial",[],function(){"use strict";return"uniform vec4 lightColor;\nuniform vec4 darkColor;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat b = mod(floor(repeat.s * st.s) + floor(repeat.t * st.t), 2.0);\nfloat scaledWidth = fract(repeat.s * st.s);\nscaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\nfloat scaledHeight = fract(repeat.t * st.t);\nscaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\nfloat value = min(scaledWidth, scaledHeight);\nvec4 currentColor = mix(lightColor, darkColor, b);\nvec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03);\nmaterial.diffuse = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/DotMaterial",[],function(){"use strict";return"uniform vec4 lightColor;\nuniform vec4 darkColor;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat b = smoothstep(0.3, 0.32, length(fract(repeat * materialInput.st) - 0.5));\nvec4 color = mix(lightColor, darkColor, b);\nmaterial.diffuse = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/ElevationContourMaterial",[],function(){"use strict";return"#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\nuniform vec4 color;\nuniform float spacing;\nuniform float width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat distanceToContour = mod(materialInput.height, spacing);\n#ifdef GL_OES_standard_derivatives\nfloat dxc = abs(dFdx(materialInput.height));\nfloat dyc = abs(dFdy(materialInput.height));\nfloat dF = max(dxc, dyc) * width;\nmaterial.alpha = (distanceToContour < dF) ? 1.0 : 0.0;\n#else\nmaterial.alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0;\n#endif\nmaterial.diffuse = color.rgb;\nreturn material;\n}\n"}),define("Shaders/Materials/ElevationRampMaterial",[],function(){"use strict";return"uniform sampler2D image;\nuniform float minimumHeight;\nuniform float maximumHeight;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat scaledHeight = clamp((materialInput.height - minimumHeight) / (maximumHeight - minimumHeight), 0.0, 1.0);\nvec4 rampColor = texture2D(image, vec2(scaledHeight, 0.5));\nmaterial.diffuse = rampColor.rgb;\nmaterial.alpha = rampColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/FadeMaterial",[],function(){"use strict";return"uniform vec4 fadeInColor;\nuniform vec4 fadeOutColor;\nuniform float maximumDistance;\nuniform bool repeat;\nuniform vec2 fadeDirection;\nuniform vec2 time;\nfloat getTime(float t, float coord)\n{\nfloat scalar = 1.0 / maximumDistance;\nfloat q = distance(t, coord) * scalar;\nif (repeat)\n{\nfloat r = distance(t, coord + 1.0) * scalar;\nfloat s = distance(t, coord - 1.0) * scalar;\nq = min(min(r, s), q);\n}\nreturn clamp(q, 0.0, 1.0);\n}\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat s = getTime(time.x, st.s) * fadeDirection.s;\nfloat t = getTime(time.y, st.t) * fadeDirection.t;\nfloat u = length(vec2(s, t));\nvec4 color = mix(fadeInColor, fadeOutColor, u);\nmaterial.emission = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/GridMaterial",[],function(){"use strict";return"#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\nuniform vec4 color;\nuniform float cellAlpha;\nuniform vec2 lineCount;\nuniform vec2 lineThickness;\nuniform vec2 lineOffset;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat scaledWidth = fract(lineCount.s * st.s - lineOffset.s);\nscaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\nfloat scaledHeight = fract(lineCount.t * st.t - lineOffset.t);\nscaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\nfloat value;\n#ifdef GL_OES_standard_derivatives\nconst float fuzz = 1.2;\nvec2 thickness = (lineThickness * czm_resolutionScale) - 1.0;\nvec2 dx = abs(dFdx(st));\nvec2 dy = abs(dFdy(st));\nvec2 dF = vec2(max(dx.s, dy.s), max(dx.t, dy.t)) * lineCount;\nvalue = min(\nsmoothstep(dF.s * thickness.s, dF.s * (fuzz + thickness.s), scaledWidth),\nsmoothstep(dF.t * thickness.t, dF.t * (fuzz + thickness.t), scaledHeight));\n#else\nconst float fuzz = 0.05;\nvec2 range = 0.5 - (lineThickness * 0.05);\nvalue = min(\n1.0 - smoothstep(range.s, range.s + fuzz, scaledWidth),\n1.0 - smoothstep(range.t, range.t + fuzz, scaledHeight));\n#endif\nfloat dRim = 1.0 - abs(dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC)));\nfloat sRim = smoothstep(0.8, 1.0, dRim);\nvalue *= (1.0 - sRim);\nvec3 halfColor = color.rgb * 0.5;\nmaterial.diffuse = halfColor;\nmaterial.emission = halfColor;\nmaterial.alpha = color.a * (1.0 - ((1.0 - cellAlpha) * value));\nreturn material;\n}\n"}),define("Shaders/Materials/NormalMapMaterial",[],function(){"use strict";return"uniform sampler2D image;\nuniform float strength;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec4 textureValue = texture2D(image, fract(repeat * materialInput.st));\nvec3 normalTangentSpace = textureValue.channels;\nnormalTangentSpace.xy = normalTangentSpace.xy * 2.0 - 1.0;\nnormalTangentSpace.z = clamp(1.0 - strength, 0.1, 1.0);\nnormalTangentSpace = normalize(normalTangentSpace);\nvec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\nmaterial.normal = normalEC;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineArrowMaterial",[],function(){"use strict";return"#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\nuniform vec4 color;\nvarying float v_width;\nfloat getPointOnLine(vec2 p0, vec2 p1, float x)\n{\nfloat slope = (p0.y - p1.y) / (p0.x - p1.x);\nreturn slope * (x - p0.x) + p0.y;\n}\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\n#ifdef GL_OES_standard_derivatives\nfloat base = 1.0 - abs(fwidth(st.s)) * 10.0;\n#else\nfloat base = 0.99;\n#endif\nvec2 center = vec2(1.0, 0.5);\nfloat ptOnUpperLine = getPointOnLine(vec2(base, 1.0), center, st.s);\nfloat ptOnLowerLine = getPointOnLine(vec2(base, 0.0), center, st.s);\nfloat halfWidth = 0.15;\nfloat s = step(0.5 - halfWidth, st.t);\ns *= 1.0 - step(0.5 + halfWidth, st.t);\ns *= 1.0 - step(base, st.s);\nfloat t = step(base, materialInput.st.s);\nt *= 1.0 - step(ptOnUpperLine, st.t);\nt *= step(ptOnLowerLine, st.t);\nfloat dist;\nif (st.s < base)\n{\nfloat d1 = abs(st.t - (0.5 - halfWidth));\nfloat d2 = abs(st.t - (0.5 + halfWidth));\ndist = min(d1, d2);\n}\nelse\n{\nfloat d1 = czm_infinity;\nif (st.t < 0.5 - halfWidth && st.t > 0.5 + halfWidth)\n{\nd1 = abs(st.s - base);\n}\nfloat d2 = abs(st.t - ptOnUpperLine);\nfloat d3 = abs(st.t - ptOnLowerLine);\ndist = min(min(d1, d2), d3);\n}\nvec4 outsideColor = vec4(0.0);\nvec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0));\nvec4 outColor = czm_antialias(outsideColor, color, currentColor, dist);\nmaterial.diffuse = outColor.rgb;\nmaterial.alpha = outColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineDashMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform vec4 gapColor;\nuniform float dashLength;\nuniform float dashPattern;\nvarying float v_polylineAngle;\nconst float maskLength = 16.0;\nmat2 rotate(float rad) {\nfloat c = cos(rad);\nfloat s = sin(rad);\nreturn mat2(\nc, s,\n-s, c\n);\n}\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 pos = rotate(v_polylineAngle) * gl_FragCoord.xy;\nfloat dashPosition = fract(pos.x / dashLength);\nfloat maskIndex = floor(dashPosition * maskLength);\nfloat maskTest = floor(dashPattern / pow(2.0, maskIndex));\nvec4 fragColor = (mod(maskTest, 2.0) < 1.0) ? gapColor : color;\nif (fragColor.a < 0.005) {\ndiscard;\n}\nmaterial.emission = fragColor.rgb;\nmaterial.alpha = fragColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineGlowMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform float glowPower;\nvarying float v_width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5);\nmaterial.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb);\nmaterial.alpha = clamp(0.0, 1.0, glow) * color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineOutlineMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform vec4 outlineColor;\nuniform float outlineWidth;\nvarying float v_width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width;\nfloat b = step(0.5 - halfInteriorWidth, st.t);\nb *= 1.0 - step(0.5 + halfInteriorWidth, st.t);\nfloat d1 = abs(st.t - (0.5 - halfInteriorWidth));\nfloat d2 = abs(st.t - (0.5 + halfInteriorWidth));\nfloat dist = min(d1, d2);\nvec4 currentColor = mix(outlineColor, color, b);\nvec4 outColor = czm_antialias(outlineColor, color, currentColor, dist);\nmaterial.diffuse = outColor.rgb;\nmaterial.alpha = outColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/RimLightingMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform vec4 rimColor;\nuniform float width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat d = 1.0 - dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC));\nfloat s = smoothstep(1.0 - width, 1.0, d);\nmaterial.diffuse = color.rgb;\nmaterial.emission = rimColor.rgb * s;\nmaterial.alpha = mix(color.a, rimColor.a, s);\nreturn material;\n}\n"}),define("Shaders/Materials/SlopeRampMaterial",[],function(){"use strict";return"uniform sampler2D image;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec4 rampColor = texture2D(image, vec2(materialInput.slope, 0.5));\nmaterial.diffuse = rampColor.rgb;\nmaterial.alpha = rampColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/StripeMaterial",[],function(){"use strict";return"uniform vec4 evenColor;\nuniform vec4 oddColor;\nuniform float offset;\nuniform float repeat;\nuniform bool horizontal;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat coord = mix(materialInput.st.s, materialInput.st.t, float(horizontal));\nfloat value = fract((coord - offset) * (repeat * 0.5));\nfloat dist = min(value, min(abs(value - 0.5), 1.0 - value));\nvec4 currentColor = mix(evenColor, oddColor, step(0.5, value));\nvec4 color = czm_antialias(evenColor, oddColor, currentColor, dist);\nmaterial.diffuse = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/Water",[],function(){"use strict";return"uniform sampler2D specularMap;\nuniform sampler2D normalMap;\nuniform vec4 baseWaterColor;\nuniform vec4 blendColor;\nuniform float frequency;\nuniform float animationSpeed;\nuniform float amplitude;\nuniform float specularIntensity;\nuniform float fadeFactor;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat time = czm_frameNumber * animationSpeed;\nfloat fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);\nfloat specularMapValue = texture2D(specularMap, materialInput.st).r;\nvec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);\nvec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));\nnormalTangentSpace.xy /= fade;\nnormalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);\nnormalTangentSpace = normalize(normalTangentSpace);\nfloat tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);\nmaterial.alpha = specularMapValue;\nmaterial.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);\nmaterial.diffuse += (0.1 * tsPerturbationRatio);\nmaterial.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);\nmaterial.specular = specularIntensity;\nmaterial.shininess = 10.0;\nreturn material;\n}\n"}),define("Scene/Material",["../Core/Cartesian2","../Core/clone","../Core/Color","../Core/combine","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/isArray","../Core/loadCRN","../Core/loadImage","../Core/loadKTX","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4","../Renderer/CubeMap","../Renderer/Texture","../Shaders/Materials/BumpMapMaterial","../Shaders/Materials/CheckerboardMaterial","../Shaders/Materials/DotMaterial","../Shaders/Materials/ElevationContourMaterial","../Shaders/Materials/ElevationRampMaterial","../Shaders/Materials/FadeMaterial","../Shaders/Materials/GridMaterial","../Shaders/Materials/NormalMapMaterial","../Shaders/Materials/PolylineArrowMaterial","../Shaders/Materials/PolylineDashMaterial","../Shaders/Materials/PolylineGlowMaterial","../Shaders/Materials/PolylineOutlineMaterial","../Shaders/Materials/RimLightingMaterial","../Shaders/Materials/SlopeRampMaterial","../Shaders/Materials/StripeMaterial","../Shaders/Materials/Water","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L){"use strict";function k(e){this.type=void 0,this.shaderSource=void 0,this.materials=void 0,this.uniforms=void 0,this._uniforms=void 0,this.translucent=void 0,this._strict=void 0,this._template=void 0,this._count=void 0,this._texturePaths={},this._loadedImages=[],this._loadedCubeMaps=[],this._textures={},this._updateFunctions=[],this._defaultTexture=void 0,F(e,this),s(this,{type:{value:this.type,writable:!1}}),a(k._uniformList[this.type])||(k._uniformList[this.type]=Object.keys(this._uniforms))}function F(e,r){e=o(e,o.EMPTY_OBJECT),r._strict=o(e.strict,!1),r._count=o(e.count,0),r._template=t(o(e.fabric,o.EMPTY_OBJECT)),r._template.uniforms=t(o(r._template.uniforms,o.EMPTY_OBJECT)),r._template.materials=t(o(r._template.materials,o.EMPTY_OBJECT)),r.type=a(r._template.type)?r._template.type:n(),r.shaderSource="",r.materials={},r.uniforms={},r._uniforms={},r._translucentFunctions=[];var s,l=k._materialCache.getMaterial(r.type);if(a(l)){var u=t(l.fabric,!0);r._template=i(r._template,u,!0),s=l.translucent}z(r),a(l)||k._materialCache.addMaterial(r.type,r),G(r),j(r),X(r);var c=0===r._translucentFunctions.length||void 0;if(s=o(s,c),s=o(e.translucent,s),a(s))if("function"==typeof s){var d=function(){return s(r)};r._translucentFunctions.push(d)}else r._translucentFunctions.push(s)}function B(e,t,r,i){if(a(e))for(var n in e)if(e.hasOwnProperty(n)){var o=-1!==t.indexOf(n);(i&&!o||!i&&o)&&r(n,t)}}function U(e,t){}function V(e,t){}function z(e){var t=e._template,r=t.uniforms,i=t.materials,n=t.components;B(t,K,U,!0),B(n,J,U,!0);var o=[];for(var a in i)i.hasOwnProperty(a)&&o.push(a);B(r,o,V,!1)}function G(e){var t=e._template.components,r=e._template.source;if(a(r))e.shaderSource+=r+"\n";else{if(e.shaderSource+="czm_material czm_getMaterial(czm_materialInput materialInput)\n{\n",e.shaderSource+="czm_material material = czm_getDefaultMaterial(materialInput);\n",a(t))for(var i in t)t.hasOwnProperty(i)&&(e.shaderSource+="material."+i+" = "+t[i]+";\n");e.shaderSource+="return material;\n}\n"}}function H(e){var t;return function(r,i){var n=r.uniforms,o=n[e],s=t!==o;t=o;var l,u,c=r._textures[e];if(o instanceof HTMLVideoElement)if(o.readyState>=2){if(s&&a(c)&&(c!==i.defaultTexture&&c.destroy(),c=void 0),!a(c)||c===i.defaultTexture)return c=new v({context:i,source:o}),void(r._textures[e]=c);c.copyFrom(o)}else a(c)||(r._textures[e]=i.defaultTexture);else{if(o instanceof v&&o!==c){r._texturePaths[e]=void 0;var f=r._textures[e];return f!==r._defaultTexture&&f.destroy(),r._textures[e]=o,l=e+"Dimensions",void(n.hasOwnProperty(l)&&(u=n[l],u.x=o._width,u.y=o._height))}if(a(c)||(r._texturePaths[e]=void 0,a(r._defaultTexture)||(r._defaultTexture=i.defaultTexture),c=r._textures[e]=r._defaultTexture,l=e+"Dimensions",n.hasOwnProperty(l)&&(u=n[l],u.x=c._width,u.y=c._height)),o!==k.DefaultImageId&&o!==r._texturePaths[e]){if("string"==typeof o){var m;m=ee.test(o)?p(o):te.test(o)?d(o):h(o),L(m,function(t){r._loadedImages.push({id:e,image:t})})}else o instanceof HTMLCanvasElement&&r._loadedImages.push({id:e,image:o});r._texturePaths[e]=o}}}}function W(e){return function(t,r){var i=t.uniforms[e];if(i instanceof _){var n=t._textures[e];return n!==t._defaultTexture&&n.destroy(),t._texturePaths[e]=void 0,void(t._textures[e]=i)}if(a(t._textures[e])||(t._texturePaths[e]=void 0,t._textures[e]=r.defaultCubeMap),i!==k.DefaultCubeMapId){var o=i.positiveX+i.negativeX+i.positiveY+i.negativeY+i.positiveZ+i.negativeZ;if(o!==t._texturePaths[e]){var s=[h(i.positiveX),h(i.negativeX),h(i.positiveY),h(i.negativeY),h(i.positiveZ),h(i.negativeZ)];L.all(s).then(function(r){t._loadedCubeMaps.push({id:e,images:r})}),t._texturePaths[e]=o}}}}function j(e){var t=e._template.uniforms;for(var r in t)t.hasOwnProperty(r)&&q(e,r)}function q(e,t){var r=(e._strict,e._template.uniforms),i=r[t],n=Y(i);if("channels"===n)Q(e,t,i,!1);else{if("sampler2D"===n){var o=t+"Dimensions";Z(e,o)>0&&(r[o]={type:"ivec3",x:1,y:1},q(e,o))}if(!new RegExp("uniform\\s+"+n+"\\s+"+t+"\\s*;").test(e.shaderSource)){var a="uniform "+n+" "+t+";";e.shaderSource=a+e.shaderSource}var s=t+"_"+e._count++;if(Q(e,t,s),e.uniforms[t]=i,"sampler2D"===n)e._uniforms[s]=function(){return e._textures[t]},e._updateFunctions.push(H(t));else if("samplerCube"===n)e._uniforms[s]=function(){return e._textures[t]},e._updateFunctions.push(W(t));else if(-1!==n.indexOf("mat")){var l=new $[n];e._uniforms[s]=function(){return $[n].fromColumnMajorArray(e.uniforms[t],l)}}else e._uniforms[s]=function(){return e.uniforms[t]}}}function Y(e){var t=e.type;if(!a(t)){var r=typeof e;if("number"===r)t="float";else if("boolean"===r)t="bool";else if("string"===r||e instanceof HTMLCanvasElement)t=/^([rgba]){1,4}$/i.test(e)?"channels":e===k.DefaultCubeMapId?"samplerCube":"sampler2D";else if("object"===r)if(c(e))4!==e.length&&9!==e.length&&16!==e.length||(t="mat"+Math.sqrt(e.length));else{var i=0;for(var n in e)e.hasOwnProperty(n)&&(i+=1);i>=2&&i<=4?t="vec"+i:6===i&&(t="samplerCube")}}return t}function X(e){var t=e._strict,r=e._template.materials;for(var n in r)if(r.hasOwnProperty(n)){var o=new k({strict:t,fabric:r[n],count:e._count});e._count=o._count,e._uniforms=i(e._uniforms,o._uniforms,!0),e.materials[n]=o,e._translucentFunctions=e._translucentFunctions.concat(o._translucentFunctions);var a="czm_getMaterial_"+e._count++;Q(o,"czm_getMaterial",a),e.shaderSource=o.shaderSource+e.shaderSource;var s=a+"(materialInput)";Q(e,n,s)}}function Q(e,t,r,i){i=o(i,!0);var n=0,a="([\\w"+(i?".":"")+"])?",s=new RegExp(a+t+"([\\w])?","g");return e.shaderSource=e.shaderSource.replace(s,function(e,t,i){return t||i?e:(n+=1,r)}),n} -function Z(e,t,r){return Q(e,t,t,r)}k._uniformList={},k.fromType=function(e,t){var r=new k({fabric:{type:e}});if(a(t))for(var i in t)t.hasOwnProperty(i)&&(r.uniforms[i]=t[i]);return r},k.prototype.isTranslucent=function(){if(a(this.translucent))return"function"==typeof this.translucent?this.translucent():this.translucent;for(var e=!0,t=this._translucentFunctions,r=t.length,i=0;i0&&console.log(b+"Vertex shader compile log: "+d)),m&&(d=e.getShaderInfoLog(s),r(d)&&d.length>0&&console.log(b+"Fragment shader compile log: "+d)),m&&(d=e.getProgramInfoLog(l),r(d)&&d.length>0&&console.log(b+"Shader program link log: "+d)),l}function m(e,t,r){for(var i={},n=0;n=0){if(f=i[d.slice(0,v)],!r(f))continue;m=f._locations,m.length<=1&&(g=f.value,null!==(_=e.getUniformLocation(t,d))&&(m.push(_),g.push(e.getUniform(t,_))))}else{m=[];for(var y=0;y=0;S--)c.splice(T,0,"#endif //"+A[S])}var x=!1;for(d=0;d=0}):i[f]=o.slice())}}return i}function u(e,t){var r="#extension\\s+GL_"+e+"\\s+:\\s+[a-zA-Z0-9]+\\s*$";n(new RegExp(r,"g"),"",t)}return r}),define("Shaders/Builtin/Constants/degreesPerRadian",[],function(){"use strict";return"const float czm_degreesPerRadian = 57.29577951308232;\n"}),define("Shaders/Builtin/Constants/depthRange",[],function(){"use strict";return"const czm_depthRangeStruct czm_depthRange = czm_depthRangeStruct(0.0, 1.0);\n"}),define("Shaders/Builtin/Constants/epsilon1",[],function(){"use strict";return"const float czm_epsilon1 = 0.1;\n"}),define("Shaders/Builtin/Constants/epsilon2",[],function(){"use strict";return"const float czm_epsilon2 = 0.01;\n"}),define("Shaders/Builtin/Constants/epsilon3",[],function(){"use strict";return"const float czm_epsilon3 = 0.001;\n"}),define("Shaders/Builtin/Constants/epsilon4",[],function(){"use strict";return"const float czm_epsilon4 = 0.0001;\n"}),define("Shaders/Builtin/Constants/epsilon5",[],function(){"use strict";return"const float czm_epsilon5 = 0.00001;\n"}),define("Shaders/Builtin/Constants/epsilon6",[],function(){"use strict";return"const float czm_epsilon6 = 0.000001;\n"}),define("Shaders/Builtin/Constants/epsilon7",[],function(){"use strict";return"const float czm_epsilon7 = 0.0000001;\n"}),define("Shaders/Builtin/Constants/infinity",[],function(){"use strict";return"const float czm_infinity = 5906376272000.0;\n"}),define("Shaders/Builtin/Constants/maxClippingPlanes",[],function(){"use strict";return"const int czm_maxClippingPlanes = 6;\n"}),define("Shaders/Builtin/Constants/oneOverPi",[],function(){"use strict";return"const float czm_oneOverPi = 0.3183098861837907;\n"}),define("Shaders/Builtin/Constants/oneOverTwoPi",[],function(){"use strict";return"const float czm_oneOverTwoPi = 0.15915494309189535;\n"}),define("Shaders/Builtin/Constants/passCesium3DTile",[],function(){"use strict";return"const float czm_passCesium3DTile = 4.0;\n"}),define("Shaders/Builtin/Constants/passCesium3DTileClassification",[],function(){"use strict";return"const float czm_passCesium3DTileClassification = 5.0;\n"}),define("Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow",[],function(){"use strict";return"const float czm_passCesium3DTileClassificationIgnoreShow = 6.0;\n"}),define("Shaders/Builtin/Constants/passCompute",[],function(){"use strict";return"const float czm_passCompute = 1.0;\n"}),define("Shaders/Builtin/Constants/passEnvironment",[],function(){"use strict";return"const float czm_passEnvironment = 0.0;\n"}),define("Shaders/Builtin/Constants/passGlobe",[],function(){"use strict";return"const float czm_passGlobe = 2.0;\n"}),define("Shaders/Builtin/Constants/passOpaque",[],function(){"use strict";return"const float czm_passOpaque = 7.0;\n"}),define("Shaders/Builtin/Constants/passOverlay",[],function(){"use strict";return"const float czm_passOverlay = 9.0;\n"}),define("Shaders/Builtin/Constants/passTerrainClassification",[],function(){"use strict";return"const float czm_passTerrainClassification = 3.0;\n"}),define("Shaders/Builtin/Constants/passTranslucent",[],function(){"use strict";return"const float czm_passTranslucent = 8.0;\n"}),define("Shaders/Builtin/Constants/pi",[],function(){"use strict";return"const float czm_pi = 3.141592653589793;\n"}),define("Shaders/Builtin/Constants/piOverFour",[],function(){"use strict";return"const float czm_piOverFour = 0.7853981633974483;\n"}),define("Shaders/Builtin/Constants/piOverSix",[],function(){"use strict";return"const float czm_piOverSix = 0.5235987755982988;\n"}),define("Shaders/Builtin/Constants/piOverThree",[],function(){"use strict";return"const float czm_piOverThree = 1.0471975511965976;\n"}),define("Shaders/Builtin/Constants/piOverTwo",[],function(){"use strict";return"const float czm_piOverTwo = 1.5707963267948966;\n"}),define("Shaders/Builtin/Constants/radiansPerDegree",[],function(){"use strict";return"const float czm_radiansPerDegree = 0.017453292519943295;\n"}),define("Shaders/Builtin/Constants/sceneMode2D",[],function(){"use strict";return"const float czm_sceneMode2D = 2.0;\n"}),define("Shaders/Builtin/Constants/sceneMode3D",[],function(){"use strict";return"const float czm_sceneMode3D = 3.0;\n"}),define("Shaders/Builtin/Constants/sceneModeColumbusView",[],function(){"use strict";return"const float czm_sceneModeColumbusView = 1.0;\n"}),define("Shaders/Builtin/Constants/sceneModeMorphing",[],function(){"use strict";return"const float czm_sceneModeMorphing = 0.0;\n"}),define("Shaders/Builtin/Constants/solarRadius",[],function(){"use strict";return"const float czm_solarRadius = 695500000.0;\n"}),define("Shaders/Builtin/Constants/threePiOver2",[],function(){"use strict";return"const float czm_threePiOver2 = 4.71238898038469;\n"}),define("Shaders/Builtin/Constants/twoPi",[],function(){"use strict";return"const float czm_twoPi = 6.283185307179586;\n"}),define("Shaders/Builtin/Constants/webMercatorMaxLatitude",[],function(){"use strict";return"const float czm_webMercatorMaxLatitude = 1.4844222297453324;\n"}),define("Shaders/Builtin/Structs/depthRangeStruct",[],function(){"use strict";return"struct czm_depthRangeStruct\n{\nfloat near;\nfloat far;\n};\n"}),define("Shaders/Builtin/Structs/ellipsoid",[],function(){"use strict";return"struct czm_ellipsoid\n{\nvec3 center;\nvec3 radii;\nvec3 inverseRadii;\nvec3 inverseRadiiSquared;\n};\n"}),define("Shaders/Builtin/Structs/material",[],function(){"use strict";return"struct czm_material\n{\nvec3 diffuse;\nfloat specular;\nfloat shininess;\nvec3 normal;\nvec3 emission;\nfloat alpha;\n};\n"}),define("Shaders/Builtin/Structs/materialInput",[],function(){"use strict";return"struct czm_materialInput\n{\nfloat s;\nvec2 st;\nvec3 str;\nvec3 normalEC;\nmat3 tangentToEyeMatrix;\nvec3 positionToEyeEC;\nfloat height;\nfloat slope;\n};\n"}),define("Shaders/Builtin/Structs/ray",[],function(){"use strict";return"struct czm_ray\n{\nvec3 origin;\nvec3 direction;\n};\n"}),define("Shaders/Builtin/Structs/raySegment",[],function(){"use strict";return"struct czm_raySegment\n{\nfloat start;\nfloat stop;\n};\nconst czm_raySegment czm_emptyRaySegment = czm_raySegment(-czm_infinity, -czm_infinity);\nconst czm_raySegment czm_fullRaySegment = czm_raySegment(0.0, czm_infinity);\n"}),define("Shaders/Builtin/Structs/shadowParameters",[],function(){"use strict";return"struct czm_shadowParameters\n{\n#ifdef USE_CUBE_MAP_SHADOW\nvec3 texCoords;\n#else\nvec2 texCoords;\n#endif\nfloat depthBias;\nfloat depth;\nfloat nDotL;\nvec2 texelStepSize;\nfloat normalShadingSmooth;\nfloat darkness;\n};\n"}),define("Shaders/Builtin/Functions/alphaWeight",[],function(){"use strict";return"float czm_alphaWeight(float a)\n{\nfloat x = 2.0 * (gl_FragCoord.x - czm_viewport.x) / czm_viewport.z - 1.0;\nfloat y = 2.0 * (gl_FragCoord.y - czm_viewport.y) / czm_viewport.w - 1.0;\nfloat z = (gl_FragCoord.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\nvec4 q = vec4(x, y, z, 0.0);\nq /= gl_FragCoord.w;\nif (czm_inverseProjection != mat4(0.0)) {\nq = czm_inverseProjection * q;\n} else {\nfloat top = czm_frustumPlanes.x;\nfloat bottom = czm_frustumPlanes.y;\nfloat left = czm_frustumPlanes.z;\nfloat right = czm_frustumPlanes.w;\nfloat near = czm_currentFrustum.x;\nfloat far = czm_currentFrustum.y;\nq.x = (q.x * (right - left) + left + right) * 0.5;\nq.y = (q.y * (top - bottom) + bottom + top) * 0.5;\nq.z = (q.z * (near - far) - near - far) * 0.5;\nq.w = 1.0;\n}\nreturn pow(a + 0.01, 4.0) + max(1e-2, min(3.0 * 1e3, 100.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0))));\n}\n"}),define("Shaders/Builtin/Functions/antialias",[],function(){"use strict";return"vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist, float fuzzFactor)\n{\nfloat val1 = clamp(dist / fuzzFactor, 0.0, 1.0);\nfloat val2 = clamp((dist - 0.5) / fuzzFactor, 0.0, 1.0);\nval1 = val1 * (1.0 - val2);\nval1 = val1 * val1 * (3.0 - (2.0 * val1));\nval1 = pow(val1, 0.5);\nvec4 midColor = (color1 + color2) * 0.5;\nreturn mix(midColor, currentColor, val1);\n}\nvec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist)\n{\nreturn czm_antialias(color1, color2, currentColor, dist, 0.1);\n}\n"}),define("Shaders/Builtin/Functions/cascadeColor",[],function(){"use strict";return"vec4 czm_cascadeColor(vec4 weights)\n{\nreturn vec4(1.0, 0.0, 0.0, 1.0) * weights.x +\nvec4(0.0, 1.0, 0.0, 1.0) * weights.y +\nvec4(0.0, 0.0, 1.0, 1.0) * weights.z +\nvec4(1.0, 0.0, 1.0, 1.0) * weights.w;\n}\n"}),define("Shaders/Builtin/Functions/cascadeDistance",[],function(){"use strict";return"uniform vec4 shadowMap_cascadeDistances;\nfloat czm_cascadeDistance(vec4 weights)\n{\nreturn dot(shadowMap_cascadeDistances, weights);\n}\n"}),define("Shaders/Builtin/Functions/cascadeMatrix",[],function(){"use strict";return"uniform mat4 shadowMap_cascadeMatrices[4];\nmat4 czm_cascadeMatrix(vec4 weights)\n{\nreturn shadowMap_cascadeMatrices[0] * weights.x +\nshadowMap_cascadeMatrices[1] * weights.y +\nshadowMap_cascadeMatrices[2] * weights.z +\nshadowMap_cascadeMatrices[3] * weights.w;\n}\n"}),define("Shaders/Builtin/Functions/cascadeWeights",[],function(){"use strict";return"uniform vec4 shadowMap_cascadeSplits[2];\nvec4 czm_cascadeWeights(float depthEye)\n{\nvec4 near = step(shadowMap_cascadeSplits[0], vec4(depthEye));\nvec4 far = step(depthEye, shadowMap_cascadeSplits[1]);\nreturn near * far;\n}\n"}),define("Shaders/Builtin/Functions/columbusViewMorph",[],function(){"use strict";return"vec4 czm_columbusViewMorph(vec4 position2D, vec4 position3D, float time)\n{\nvec3 p = mix(position2D.xyz, position3D.xyz, time);\nreturn vec4(p, 1.0);\n}\n"}),define("Shaders/Builtin/Functions/computePosition",[],function(){"use strict";return"vec4 czm_computePosition();\n"}),define("Shaders/Builtin/Functions/cosineAndSine",[],function(){"use strict" -;return"vec2 cordic(float angle)\n{\nvec2 vector = vec2(6.0725293500888267e-1, 0.0);\nfloat sense = (angle < 0.0) ? -1.0 : 1.0;\nmat2 rotation = mat2(1.0, sense, -sense, 1.0);\nvector = rotation * vector;\nangle -= sense * 7.8539816339744828e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfloat factor = sense * 5.0e-1;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 4.6364760900080609e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 2.5e-1;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 2.4497866312686414e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.25e-1;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.2435499454676144e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 6.25e-2;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 6.2418809995957350e-2;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.125e-2;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.1239833430268277e-2;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.5625e-2;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.5623728620476831e-2;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 7.8125e-3;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 7.8123410601011111e-3;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.90625e-3;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.9062301319669718e-3;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.953125e-3;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.9531225164788188e-3;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 9.765625e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 9.7656218955931946e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 4.8828125e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 4.8828121119489829e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 2.44140625e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 2.4414062014936177e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.220703125e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.2207031189367021e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 6.103515625e-5;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 6.1035156174208773e-5;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.0517578125e-5;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.0517578115526096e-5;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.52587890625e-5;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.5258789061315762e-5;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 7.62939453125e-6;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 7.6293945311019700e-6;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.814697265625e-6;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.8146972656064961e-6;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.9073486328125e-6;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.9073486328101870e-6;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 9.5367431640625e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 9.5367431640596084e-7;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 4.76837158203125e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 4.7683715820308884e-7;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 2.384185791015625e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 2.3841857910155797e-7;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.1920928955078125e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nreturn vector;\n}\nvec2 czm_cosineAndSine(float angle)\n{\nif (angle < -czm_piOverTwo || angle > czm_piOverTwo)\n{\nif (angle < 0.0)\n{\nreturn -cordic(angle + czm_pi);\n}\nelse\n{\nreturn -cordic(angle - czm_pi);\n}\n}\nelse\n{\nreturn cordic(angle);\n}\n}\n"}),define("Shaders/Builtin/Functions/decompressTextureCoordinates",[],function(){"use strict";return"vec2 czm_decompressTextureCoordinates(float encoded)\n{\nfloat temp = encoded / 4096.0;\nfloat xZeroTo4095 = floor(temp);\nfloat stx = xZeroTo4095 / 4095.0;\nfloat sty = (encoded - xZeroTo4095 * 4096.0) / 4095.0;\nreturn vec2(stx, sty);\n}\n"}),define("Shaders/Builtin/Functions/discardIfClippedWithIntersect",[],function(){"use strict";return"float czm_discardIfClippedWithIntersect(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n{\nif (clippingPlanesLength > 0)\n{\nbool clipped = true;\nvec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\nvec3 clipNormal = vec3(0.0);\nvec3 clipPosition = vec3(0.0);\nfloat clipAmount = 0.0;\nfloat pixelWidth = czm_metersPerPixel(position);\nfor (int i = 0; i < czm_maxClippingPlanes; ++i)\n{\nif (i == clippingPlanesLength)\n{\nbreak;\n}\nclipNormal = clippingPlanes[i].xyz;\nclipPosition = -clippingPlanes[i].w * clipNormal;\nfloat amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\nclipAmount = max(amount, clipAmount);\nclipped = clipped && (amount <= 0.0);\n}\nif (clipped)\n{\ndiscard;\n}\nreturn clipAmount;\n}\nreturn 0.0;\n}\n"}),define("Shaders/Builtin/Functions/discardIfClippedWithUnion",[],function(){"use strict";return"float czm_discardIfClippedWithUnion(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n{\nif (clippingPlanesLength > 0)\n{\nvec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\nvec3 clipNormal = vec3(0.0);\nvec3 clipPosition = vec3(0.0);\nfloat clipAmount = 0.0;\nfloat pixelWidth = czm_metersPerPixel(position);\nfor (int i = 0; i < czm_maxClippingPlanes; ++i)\n{\nif (i == clippingPlanesLength)\n{\nbreak;\n}\nclipNormal = clippingPlanes[i].xyz;\nclipPosition = -clippingPlanes[i].w * clipNormal;\nfloat amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\nclipAmount = max(amount, clipAmount);\nif (amount <= 0.0)\n{\ndiscard;\n}\n}\nreturn clipAmount;\n}\nreturn 0.0;\n}\n"}),define("Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates",[],function(){"use strict";return"mat3 czm_eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)\n{\nvec3 tangentMC = normalize(vec3(-positionMC.y, positionMC.x, 0.0));\nvec3 tangentEC = normalize(czm_normal3D * tangentMC);\nvec3 bitangentEC = normalize(cross(normalEC, tangentEC));\nreturn mat3(\ntangentEC.x, tangentEC.y, tangentEC.z,\nbitangentEC.x, bitangentEC.y, bitangentEC.z,\nnormalEC.x, normalEC.y, normalEC.z);\n}\n"}),define("Shaders/Builtin/Functions/ellipsoidContainsPoint",[],function(){"use strict";return"bool czm_ellipsoidContainsPoint(czm_ellipsoid ellipsoid, vec3 point)\n{\nvec3 scaled = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(point, 1.0)).xyz;\nreturn (dot(scaled, scaled) <= 1.0);\n}\n"}),define("Shaders/Builtin/Functions/ellipsoidNew",[],function(){"use strict";return"czm_ellipsoid czm_ellipsoidNew(vec3 center, vec3 radii)\n{\nvec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\nvec3 inverseRadiiSquared = inverseRadii * inverseRadii;\nczm_ellipsoid temp = czm_ellipsoid(center, radii, inverseRadii, inverseRadiiSquared);\nreturn temp;\n}\n"}),define("Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates",[],function(){"use strict";return"vec2 czm_ellipsoidWgs84TextureCoordinates(vec3 normal)\n{\nreturn vec2(atan(normal.y, normal.x) * czm_oneOverTwoPi + 0.5, asin(normal.z) * czm_oneOverPi + 0.5);\n}\n"}),define("Shaders/Builtin/Functions/equalsEpsilon",[],function(){"use strict";return"bool czm_equalsEpsilon(vec4 left, vec4 right, float epsilon) {\nreturn all(lessThanEqual(abs(left - right), vec4(epsilon)));\n}\nbool czm_equalsEpsilon(vec3 left, vec3 right, float epsilon) {\nreturn all(lessThanEqual(abs(left - right), vec3(epsilon)));\n}\nbool czm_equalsEpsilon(vec2 left, vec2 right, float epsilon) {\nreturn all(lessThanEqual(abs(left - right), vec2(epsilon)));\n}\nbool czm_equalsEpsilon(float left, float right, float epsilon) {\nreturn (abs(left - right) <= epsilon);\n}\n"}),define("Shaders/Builtin/Functions/eyeOffset",[],function(){"use strict";return"vec4 czm_eyeOffset(vec4 positionEC, vec3 eyeOffset)\n{\nvec4 p = positionEC;\nvec4 zEyeOffset = normalize(p) * eyeOffset.z;\np.xy += eyeOffset.xy + zEyeOffset.xy;\np.z += zEyeOffset.z;\nreturn p;\n}\n"}),define("Shaders/Builtin/Functions/eyeToWindowCoordinates",[],function(){"use strict";return"vec4 czm_eyeToWindowCoordinates(vec4 positionEC)\n{\nvec4 q = czm_projection * positionEC;\nq.xyz /= q.w;\nq.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\nreturn q;\n}\n"}),define("Shaders/Builtin/Functions/fog",[],function(){"use strict";return"vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor)\n{\nfloat scalar = distanceToCamera * czm_fogDensity;\nfloat fog = 1.0 - exp(-(scalar * scalar));\nreturn mix(color, fogColor, fog);\n}\n"}),define("Shaders/Builtin/Functions/geodeticSurfaceNormal",[],function(){"use strict";return"vec3 czm_geodeticSurfaceNormal(vec3 positionOnEllipsoid, vec3 ellipsoidCenter, vec3 oneOverEllipsoidRadiiSquared)\n{\nreturn normalize((positionOnEllipsoid - ellipsoidCenter) * oneOverEllipsoidRadiiSquared);\n}\n"}),define("Shaders/Builtin/Functions/getDefaultMaterial",[],function(){"use strict";return"czm_material czm_getDefaultMaterial(czm_materialInput materialInput)\n{\nczm_material material;\nmaterial.diffuse = vec3(0.0);\nmaterial.specular = 0.0;\nmaterial.shininess = 1.0;\nmaterial.normal = materialInput.normalEC;\nmaterial.emission = vec3(0.0);\nmaterial.alpha = 1.0;\nreturn material;\n}\n"}),define("Shaders/Builtin/Functions/getLambertDiffuse",[],function(){"use strict";return"float czm_getLambertDiffuse(vec3 lightDirectionEC, vec3 normalEC)\n{\nreturn max(dot(lightDirectionEC, normalEC), 0.0);\n}\n"}),define("Shaders/Builtin/Functions/getSpecular",[],function(){"use strict";return"float czm_getSpecular(vec3 lightDirectionEC, vec3 toEyeEC, vec3 normalEC, float shininess)\n{\nvec3 toReflectedLight = reflect(-lightDirectionEC, normalEC);\nfloat specular = max(dot(toReflectedLight, toEyeEC), 0.0);\nreturn pow(specular, max(shininess, czm_epsilon2));\n}\n"}),define("Shaders/Builtin/Functions/getWaterNoise",[],function(){"use strict";return"vec4 czm_getWaterNoise(sampler2D normalMap, vec2 uv, float time, float angleInRadians)\n{\nfloat cosAngle = cos(angleInRadians);\nfloat sinAngle = sin(angleInRadians);\nvec2 s0 = vec2(1.0/17.0, 0.0);\nvec2 s1 = vec2(-1.0/29.0, 0.0);\nvec2 s2 = vec2(1.0/101.0, 1.0/59.0);\nvec2 s3 = vec2(-1.0/109.0, -1.0/57.0);\ns0 = vec2((cosAngle * s0.x) - (sinAngle * s0.y), (sinAngle * s0.x) + (cosAngle * s0.y));\ns1 = vec2((cosAngle * s1.x) - (sinAngle * s1.y), (sinAngle * s1.x) + (cosAngle * s1.y));\ns2 = vec2((cosAngle * s2.x) - (sinAngle * s2.y), (sinAngle * s2.x) + (cosAngle * s2.y));\ns3 = vec2((cosAngle * s3.x) - (sinAngle * s3.y), (sinAngle * s3.x) + (cosAngle * s3.y));\nvec2 uv0 = (uv/103.0) + (time * s0);\nvec2 uv1 = uv/107.0 + (time * s1) + vec2(0.23);\nvec2 uv2 = uv/vec2(897.0, 983.0) + (time * s2) + vec2(0.51);\nvec2 uv3 = uv/vec2(991.0, 877.0) + (time * s3) + vec2(0.71);\nuv0 = fract(uv0);\nuv1 = fract(uv1);\nuv2 = fract(uv2);\nuv3 = fract(uv3);\nvec4 noise = (texture2D(normalMap, uv0)) +\n(texture2D(normalMap, uv1)) +\n(texture2D(normalMap, uv2)) +\n(texture2D(normalMap, uv3));\nreturn ((noise / 4.0) - 0.5) * 2.0;\n}\n"}),define("Shaders/Builtin/Functions/getWgs84EllipsoidEC",[],function(){"use strict";return"czm_ellipsoid czm_getWgs84EllipsoidEC()\n{\nvec3 radii = vec3(6378137.0, 6378137.0, 6356752.314245);\nvec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\nvec3 inverseRadiiSquared = inverseRadii * inverseRadii;\nczm_ellipsoid temp = czm_ellipsoid(czm_view[3].xyz, radii, inverseRadii, inverseRadiiSquared);\nreturn temp;\n}\n"}),define("Shaders/Builtin/Functions/HSBToRGB",[],function(){"use strict";return"const vec4 K_HSB2RGB = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\nvec3 czm_HSBToRGB(vec3 hsb)\n{\nvec3 p = abs(fract(hsb.xxx + K_HSB2RGB.xyz) * 6.0 - K_HSB2RGB.www);\nreturn hsb.z * mix(K_HSB2RGB.xxx, clamp(p - K_HSB2RGB.xxx, 0.0, 1.0), hsb.y);\n}\n"}),define("Shaders/Builtin/Functions/HSLToRGB",[],function(){"use strict";return"vec3 hueToRGB(float hue)\n{\nfloat r = abs(hue * 6.0 - 3.0) - 1.0;\nfloat g = 2.0 - abs(hue * 6.0 - 2.0);\nfloat b = 2.0 - abs(hue * 6.0 - 4.0);\nreturn clamp(vec3(r, g, b), 0.0, 1.0);\n}\nvec3 czm_HSLToRGB(vec3 hsl)\n{\nvec3 rgb = hueToRGB(hsl.x);\nfloat c = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;\nreturn (rgb - 0.5) * c + hsl.z;\n}\n"}),define("Shaders/Builtin/Functions/hue",[],function(){"use strict";return"vec3 czm_hue(vec3 rgb, float adjustment)\n{\nconst mat3 toYIQ = mat3(0.299, 0.587, 0.114,\n0.595716, -0.274453, -0.321263,\n0.211456, -0.522591, 0.311135);\nconst mat3 toRGB = mat3(1.0, 0.9563, 0.6210,\n1.0, -0.2721, -0.6474,\n1.0, -1.107, 1.7046);\nvec3 yiq = toYIQ * rgb;\nfloat hue = atan(yiq.z, yiq.y) + adjustment;\nfloat chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);\nvec3 color = vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));\nreturn toRGB * color;\n}\n"}),define("Shaders/Builtin/Functions/isEmpty",[],function(){"use strict";return"bool czm_isEmpty(czm_raySegment interval)\n{\nreturn (interval.stop < 0.0);\n}\n"}),define("Shaders/Builtin/Functions/isFull",[],function(){"use strict";return"bool czm_isFull(czm_raySegment interval)\n{\nreturn (interval.start == 0.0 && interval.stop == czm_infinity);\n}\n"}),define("Shaders/Builtin/Functions/latitudeToWebMercatorFraction",[],function(){"use strict";return"float czm_latitudeToWebMercatorFraction(float latitude, float southMercatorY, float oneOverMercatorHeight)\n{\nfloat sinLatitude = sin(latitude);\nfloat mercatorY = 0.5 * log((1.0 + sinLatitude) / (1.0 - sinLatitude));\nreturn (mercatorY - southMercatorY) * oneOverMercatorHeight;\n}\n"}),define("Shaders/Builtin/Functions/luminance",[],function(){"use strict";return"float czm_luminance(vec3 rgb)\n{\nconst vec3 W = vec3(0.2125, 0.7154, 0.0721);\nreturn dot(rgb, W);\n}\n"});define("Shaders/Builtin/Functions/metersPerPixel",[],function(){"use strict";return"float czm_metersPerPixel(vec4 positionEC)\n{\nfloat width = czm_viewport.z;\nfloat height = czm_viewport.w;\nfloat pixelWidth;\nfloat pixelHeight;\nfloat top = czm_frustumPlanes.x;\nfloat bottom = czm_frustumPlanes.y;\nfloat left = czm_frustumPlanes.z;\nfloat right = czm_frustumPlanes.w;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nfloat frustumWidth = right - left;\nfloat frustumHeight = top - bottom;\npixelWidth = frustumWidth / width;\npixelHeight = frustumHeight / height;\n}\nelse\n{\nfloat distanceToPixel = -positionEC.z;\nfloat inverseNear = 1.0 / czm_currentFrustum.x;\nfloat tanTheta = top * inverseNear;\npixelHeight = 2.0 * distanceToPixel * tanTheta / height;\ntanTheta = right * inverseNear;\npixelWidth = 2.0 * distanceToPixel * tanTheta / width;\n}\nreturn max(pixelWidth, pixelHeight);\n}\n"}),define("Shaders/Builtin/Functions/modelToWindowCoordinates",[],function(){"use strict";return"vec4 czm_modelToWindowCoordinates(vec4 position)\n{\nvec4 q = czm_modelViewProjection * position;\nq.xyz /= q.w;\nq.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\nreturn q;\n}\n"}),define("Shaders/Builtin/Functions/multiplyWithColorBalance",[],function(){"use strict";return"vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right)\n{\nconst vec3 W = vec3(0.2125, 0.7154, 0.0721);\nvec3 target = left * right;\nfloat leftLuminance = dot(left, W);\nfloat rightLuminance = dot(right, W);\nfloat targetLuminance = dot(target, W);\nreturn ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target;\n}\n"}),define("Shaders/Builtin/Functions/nearFarScalar",[],function(){"use strict";return"float czm_nearFarScalar(vec4 nearFarScalar, float cameraDistSq)\n{\nfloat valueAtMin = nearFarScalar.y;\nfloat valueAtMax = nearFarScalar.w;\nfloat nearDistanceSq = nearFarScalar.x * nearFarScalar.x;\nfloat farDistanceSq = nearFarScalar.z * nearFarScalar.z;\nfloat t = (cameraDistSq - nearDistanceSq) / (farDistanceSq - nearDistanceSq);\nt = pow(clamp(t, 0.0, 1.0), 0.2);\nreturn mix(valueAtMin, valueAtMax, t);\n}\n"}),define("Shaders/Builtin/Functions/octDecode",[],function(){"use strict";return"vec3 czm_octDecode(vec2 encoded, float range)\n{\nif (encoded.x == 0.0 && encoded.y == 0.0) {\nreturn vec3(0.0, 0.0, 0.0);\n}\nencoded = encoded / range * 2.0 - 1.0;\nvec3 v = vec3(encoded.x, encoded.y, 1.0 - abs(encoded.x) - abs(encoded.y));\nif (v.z < 0.0)\n{\nv.xy = (1.0 - abs(v.yx)) * czm_signNotZero(v.xy);\n}\nreturn normalize(v);\n}\nvec3 czm_octDecode(vec2 encoded)\n{\nreturn czm_octDecode(encoded, 255.0);\n}\nvec3 czm_octDecode(float encoded)\n{\nfloat temp = encoded / 256.0;\nfloat x = floor(temp);\nfloat y = (temp - x) * 256.0;\nreturn czm_octDecode(vec2(x, y));\n}\nvoid czm_octDecode(vec2 encoded, out vec3 vector1, out vec3 vector2, out vec3 vector3)\n{\nfloat temp = encoded.x / 65536.0;\nfloat x = floor(temp);\nfloat encodedFloat1 = (temp - x) * 65536.0;\ntemp = encoded.y / 65536.0;\nfloat y = floor(temp);\nfloat encodedFloat2 = (temp - y) * 65536.0;\nvector1 = czm_octDecode(encodedFloat1);\nvector2 = czm_octDecode(encodedFloat2);\nvector3 = czm_octDecode(vec2(x, y));\n}\n"}),define("Shaders/Builtin/Functions/packDepth",[],function(){"use strict";return"vec4 czm_packDepth(float depth)\n{\nvec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nenc = fract(enc);\nenc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\nreturn enc;\n}\n"}),define("Shaders/Builtin/Functions/phong",[],function(){"use strict";return"float czm_private_getLambertDiffuseOfMaterial(vec3 lightDirectionEC, czm_material material)\n{\nreturn czm_getLambertDiffuse(lightDirectionEC, material.normal);\n}\nfloat czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm_material material)\n{\nreturn czm_getSpecular(lightDirectionEC, toEyeEC, material.normal, material.shininess);\n}\nvec4 czm_phong(vec3 toEye, czm_material material)\n{\nfloat diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material);\nif (czm_sceneMode == czm_sceneMode3D) {\ndiffuse += czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 1.0, 0.0), material);\n}\nfloat specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material) + czm_private_getSpecularOfMaterial(czm_moonDirectionEC, toEye, material);\nvec3 materialDiffuse = material.diffuse * 0.5;\nvec3 ambient = materialDiffuse;\nvec3 color = ambient + material.emission;\ncolor += materialDiffuse * diffuse;\ncolor += material.specular * specular;\nreturn vec4(color, material.alpha);\n}\nvec4 czm_private_phong(vec3 toEye, czm_material material)\n{\nfloat diffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material);\nfloat specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material);\nvec3 ambient = vec3(0.0);\nvec3 color = ambient + material.emission;\ncolor += material.diffuse * diffuse;\ncolor += material.specular * specular;\nreturn vec4(color, material.alpha);\n}\n"}),define("Shaders/Builtin/Functions/pointAlongRay",[],function(){"use strict";return"vec3 czm_pointAlongRay(czm_ray ray, float time)\n{\nreturn ray.origin + (time * ray.direction);\n}\n"}),define("Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval",[],function(){"use strict";return"czm_raySegment czm_rayEllipsoidIntersectionInterval(czm_ray ray, czm_ellipsoid ellipsoid)\n{\nvec3 q = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.origin, 1.0)).xyz;\nvec3 w = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.direction, 0.0)).xyz;\nq = q - ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ellipsoid.center, 1.0)).xyz;\nfloat q2 = dot(q, q);\nfloat qw = dot(q, w);\nif (q2 > 1.0)\n{\nif (qw >= 0.0)\n{\nreturn czm_emptyRaySegment;\n}\nelse\n{\nfloat qw2 = qw * qw;\nfloat difference = q2 - 1.0;\nfloat w2 = dot(w, w);\nfloat product = w2 * difference;\nif (qw2 < product)\n{\nreturn czm_emptyRaySegment;\n}\nelse if (qw2 > product)\n{\nfloat discriminant = qw * qw - product;\nfloat temp = -qw + sqrt(discriminant);\nfloat root0 = temp / w2;\nfloat root1 = difference / temp;\nif (root0 < root1)\n{\nczm_raySegment i = czm_raySegment(root0, root1);\nreturn i;\n}\nelse\n{\nczm_raySegment i = czm_raySegment(root1, root0);\nreturn i;\n}\n}\nelse\n{\nfloat root = sqrt(difference / w2);\nczm_raySegment i = czm_raySegment(root, root);\nreturn i;\n}\n}\n}\nelse if (q2 < 1.0)\n{\nfloat difference = q2 - 1.0;\nfloat w2 = dot(w, w);\nfloat product = w2 * difference;\nfloat discriminant = qw * qw - product;\nfloat temp = -qw + sqrt(discriminant);\nczm_raySegment i = czm_raySegment(0.0, temp / w2);\nreturn i;\n}\nelse\n{\nif (qw < 0.0)\n{\nfloat w2 = dot(w, w);\nczm_raySegment i = czm_raySegment(0.0, -qw / w2);\nreturn i;\n}\nelse\n{\nreturn czm_emptyRaySegment;\n}\n}\n}\n"}),define("Shaders/Builtin/Functions/RGBToHSB",[],function(){"use strict";return"const vec4 K_RGB2HSB = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\nvec3 czm_RGBToHSB(vec3 rgb)\n{\nvec4 p = mix(vec4(rgb.bg, K_RGB2HSB.wz), vec4(rgb.gb, K_RGB2HSB.xy), step(rgb.b, rgb.g));\nvec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r));\nfloat d = q.x - min(q.w, q.y);\nreturn vec3(abs(q.z + (q.w - q.y) / (6.0 * d + czm_epsilon7)), d / (q.x + czm_epsilon7), q.x);\n}\n"}),define("Shaders/Builtin/Functions/RGBToHSL",[],function(){"use strict";return"vec3 RGBtoHCV(vec3 rgb)\n{\nvec4 p = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0 / 3.0) : vec4(rgb.gb, 0.0, -1.0 / 3.0);\nvec4 q = (rgb.r < p.x) ? vec4(p.xyw, rgb.r) : vec4(rgb.r, p.yzx);\nfloat c = q.x - min(q.w, q.y);\nfloat h = abs((q.w - q.y) / (6.0 * c + czm_epsilon7) + q.z);\nreturn vec3(h, c, q.x);\n}\nvec3 czm_RGBToHSL(vec3 rgb)\n{\nvec3 hcv = RGBtoHCV(rgb);\nfloat l = hcv.z - hcv.y * 0.5;\nfloat s = hcv.y / (1.0 - abs(l * 2.0 - 1.0) + czm_epsilon7);\nreturn vec3(hcv.x, s, l);\n}\n"}),define("Shaders/Builtin/Functions/RGBToXYZ",[],function(){"use strict";return"vec3 czm_RGBToXYZ(vec3 rgb)\n{\nconst mat3 RGB2XYZ = mat3(0.4124, 0.2126, 0.0193,\n0.3576, 0.7152, 0.1192,\n0.1805, 0.0722, 0.9505);\nvec3 xyz = RGB2XYZ * rgb;\nvec3 Yxy;\nYxy.r = xyz.g;\nfloat temp = dot(vec3(1.0), xyz);\nYxy.gb = xyz.rg / temp;\nreturn Yxy;\n}\n"}),define("Shaders/Builtin/Functions/saturation",[],function(){"use strict";return"vec3 czm_saturation(vec3 rgb, float adjustment)\n{\nconst vec3 W = vec3(0.2125, 0.7154, 0.0721);\nvec3 intensity = vec3(dot(rgb, W));\nreturn mix(intensity, rgb, adjustment);\n}\n"}),define("Shaders/Builtin/Functions/shadowDepthCompare",[],function(){"use strict";return"float czm_sampleShadowMap(samplerCube shadowMap, vec3 d)\n{\nreturn czm_unpackDepth(textureCube(shadowMap, d));\n}\nfloat czm_sampleShadowMap(sampler2D shadowMap, vec2 uv)\n{\n#ifdef USE_SHADOW_DEPTH_TEXTURE\nreturn texture2D(shadowMap, uv).r;\n#else\nreturn czm_unpackDepth(texture2D(shadowMap, uv));\n#endif\n}\nfloat czm_shadowDepthCompare(samplerCube shadowMap, vec3 uv, float depth)\n{\nreturn step(depth, czm_sampleShadowMap(shadowMap, uv));\n}\nfloat czm_shadowDepthCompare(sampler2D shadowMap, vec2 uv, float depth)\n{\nreturn step(depth, czm_sampleShadowMap(shadowMap, uv));\n}\n"}),define("Shaders/Builtin/Functions/shadowVisibility",[],function(){"use strict";return"float czm_private_shadowVisibility(float visibility, float nDotL, float normalShadingSmooth, float darkness)\n{\n#ifdef USE_NORMAL_SHADING\n#ifdef USE_NORMAL_SHADING_SMOOTH\nfloat strength = clamp(nDotL / normalShadingSmooth, 0.0, 1.0);\n#else\nfloat strength = step(0.0, nDotL);\n#endif\nvisibility *= strength;\n#endif\nvisibility = max(visibility, darkness);\nreturn visibility;\n}\n#ifdef USE_CUBE_MAP_SHADOW\nfloat czm_shadowVisibility(samplerCube shadowMap, czm_shadowParameters shadowParameters)\n{\nfloat depthBias = shadowParameters.depthBias;\nfloat depth = shadowParameters.depth;\nfloat nDotL = shadowParameters.nDotL;\nfloat normalShadingSmooth = shadowParameters.normalShadingSmooth;\nfloat darkness = shadowParameters.darkness;\nvec3 uvw = shadowParameters.texCoords;\ndepth -= depthBias;\nfloat visibility = czm_shadowDepthCompare(shadowMap, uvw, depth);\nreturn czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n}\n#else\nfloat czm_shadowVisibility(sampler2D shadowMap, czm_shadowParameters shadowParameters)\n{\nfloat depthBias = shadowParameters.depthBias;\nfloat depth = shadowParameters.depth;\nfloat nDotL = shadowParameters.nDotL;\nfloat normalShadingSmooth = shadowParameters.normalShadingSmooth;\nfloat darkness = shadowParameters.darkness;\nvec2 uv = shadowParameters.texCoords;\ndepth -= depthBias;\n#ifdef USE_SOFT_SHADOWS\nvec2 texelStepSize = shadowParameters.texelStepSize;\nfloat radius = 1.0;\nfloat dx0 = -texelStepSize.x * radius;\nfloat dy0 = -texelStepSize.y * radius;\nfloat dx1 = texelStepSize.x * radius;\nfloat dy1 = texelStepSize.y * radius;\nfloat visibility = (\nczm_shadowDepthCompare(shadowMap, uv, depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx0, 0.0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx1, 0.0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy1), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy1), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy1), depth)\n) * (1.0 / 9.0);\n#else\nfloat visibility = czm_shadowDepthCompare(shadowMap, uv, depth);\n#endif\nreturn czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n}\n#endif\n"}),define("Shaders/Builtin/Functions/signNotZero",[],function(){"use strict";return"float czm_signNotZero(float value)\n{\nreturn value >= 0.0 ? 1.0 : -1.0;\n}\nvec2 czm_signNotZero(vec2 value)\n{\nreturn vec2(czm_signNotZero(value.x), czm_signNotZero(value.y));\n}\nvec3 czm_signNotZero(vec3 value)\n{\nreturn vec3(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z));\n}\nvec4 czm_signNotZero(vec4 value)\n{\nreturn vec4(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z), czm_signNotZero(value.w));\n}\n"}),define("Shaders/Builtin/Functions/tangentToEyeSpaceMatrix",[],function(){"use strict";return"mat3 czm_tangentToEyeSpaceMatrix(vec3 normalEC, vec3 tangentEC, vec3 bitangentEC)\n{\nvec3 normal = normalize(normalEC);\nvec3 tangent = normalize(tangentEC);\nvec3 bitangent = normalize(bitangentEC);\nreturn mat3(tangent.x , tangent.y , tangent.z,\nbitangent.x, bitangent.y, bitangent.z,\nnormal.x , normal.y , normal.z);\n}\n"}),define("Shaders/Builtin/Functions/translateRelativeToEye",[],function(){"use strict";return"vec4 czm_translateRelativeToEye(vec3 high, vec3 low)\n{\nvec3 highDifference = high - czm_encodedCameraPositionMCHigh;\nvec3 lowDifference = low - czm_encodedCameraPositionMCLow;\nreturn vec4(highDifference + lowDifference, 1.0);\n}\n"}),define("Shaders/Builtin/Functions/translucentPhong",[],function(){"use strict";return"vec4 czm_translucentPhong(vec3 toEye, czm_material material)\n{\nfloat diffuse = czm_getLambertDiffuse(vec3(0.0, 0.0, 1.0), material.normal);\nif (czm_sceneMode == czm_sceneMode3D) {\ndiffuse += czm_getLambertDiffuse(vec3(0.0, 1.0, 0.0), material.normal);\n}\ndiffuse = clamp(diffuse, 0.0, 1.0);\nfloat specular = czm_getSpecular(czm_sunDirectionEC, toEye, material.normal, material.shininess);\nspecular += czm_getSpecular(czm_moonDirectionEC, toEye, material.normal, material.shininess);\nvec3 materialDiffuse = material.diffuse * 0.5;\nvec3 ambient = materialDiffuse;\nvec3 color = ambient + material.emission;\ncolor += materialDiffuse * diffuse;\ncolor += material.specular * specular;\nreturn vec4(color, material.alpha);\n}\n"}),define("Shaders/Builtin/Functions/transpose",[],function(){"use strict";return"mat2 czm_transpose(mat2 matrix)\n{\nreturn mat2(\nmatrix[0][0], matrix[1][0],\nmatrix[0][1], matrix[1][1]);\n}\nmat3 czm_transpose(mat3 matrix)\n{\nreturn mat3(\nmatrix[0][0], matrix[1][0], matrix[2][0],\nmatrix[0][1], matrix[1][1], matrix[2][1],\nmatrix[0][2], matrix[1][2], matrix[2][2]);\n}\nmat4 czm_transpose(mat4 matrix)\n{\nreturn mat4(\nmatrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],\nmatrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],\nmatrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],\nmatrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);\n}\n"}),define("Shaders/Builtin/Functions/unpackDepth",[],function(){"use strict";return"float czm_unpackDepth(vec4 packedDepth)\n{\nreturn dot(packedDepth, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n}\n"}),define("Shaders/Builtin/Functions/windowToEyeCoordinates",[],function(){"use strict";return"vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate)\n{\nfloat x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0;\nfloat y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0;\nfloat z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\nvec4 q = vec4(x, y, z, 1.0);\nq /= fragmentCoordinate.w;\nif (czm_inverseProjection != mat4(0.0)) {\nq = czm_inverseProjection * q;\n} else {\nfloat top = czm_frustumPlanes.x;\nfloat bottom = czm_frustumPlanes.y;\nfloat left = czm_frustumPlanes.z;\nfloat right = czm_frustumPlanes.w;\nfloat near = czm_currentFrustum.x;\nfloat far = czm_currentFrustum.y;\nq.x = (q.x * (right - left) + left + right) * 0.5;\nq.y = (q.y * (top - bottom) + bottom + top) * 0.5;\nq.z = (q.z * (near - far) - near - far) * 0.5;\nq.w = 1.0;\n}\nreturn q;\n}\n"}),define("Shaders/Builtin/Functions/XYZToRGB",[],function(){"use strict";return"vec3 czm_XYZToRGB(vec3 Yxy)\n{\nconst mat3 XYZ2RGB = mat3( 3.2405, -0.9693, 0.0556,\n-1.5371, 1.8760, -0.2040,\n-0.4985, 0.0416, 1.0572);\nvec3 xyz;\nxyz.r = Yxy.r * Yxy.g / Yxy.b;\nxyz.g = Yxy.r;\nxyz.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b;\nreturn XYZ2RGB * xyz;\n}\n"}), -define("Shaders/Builtin/CzmBuiltins",["./Constants/degreesPerRadian","./Constants/depthRange","./Constants/epsilon1","./Constants/epsilon2","./Constants/epsilon3","./Constants/epsilon4","./Constants/epsilon5","./Constants/epsilon6","./Constants/epsilon7","./Constants/infinity","./Constants/maxClippingPlanes","./Constants/oneOverPi","./Constants/oneOverTwoPi","./Constants/passCesium3DTile","./Constants/passCesium3DTileClassification","./Constants/passCesium3DTileClassificationIgnoreShow","./Constants/passCompute","./Constants/passEnvironment","./Constants/passGlobe","./Constants/passOpaque","./Constants/passOverlay","./Constants/passTerrainClassification","./Constants/passTranslucent","./Constants/pi","./Constants/piOverFour","./Constants/piOverSix","./Constants/piOverThree","./Constants/piOverTwo","./Constants/radiansPerDegree","./Constants/sceneMode2D","./Constants/sceneMode3D","./Constants/sceneModeColumbusView","./Constants/sceneModeMorphing","./Constants/solarRadius","./Constants/threePiOver2","./Constants/twoPi","./Constants/webMercatorMaxLatitude","./Structs/depthRangeStruct","./Structs/ellipsoid","./Structs/material","./Structs/materialInput","./Structs/ray","./Structs/raySegment","./Structs/shadowParameters","./Functions/alphaWeight","./Functions/antialias","./Functions/cascadeColor","./Functions/cascadeDistance","./Functions/cascadeMatrix","./Functions/cascadeWeights","./Functions/columbusViewMorph","./Functions/computePosition","./Functions/cosineAndSine","./Functions/decompressTextureCoordinates","./Functions/discardIfClippedWithIntersect","./Functions/discardIfClippedWithUnion","./Functions/eastNorthUpToEyeCoordinates","./Functions/ellipsoidContainsPoint","./Functions/ellipsoidNew","./Functions/ellipsoidWgs84TextureCoordinates","./Functions/equalsEpsilon","./Functions/eyeOffset","./Functions/eyeToWindowCoordinates","./Functions/fog","./Functions/geodeticSurfaceNormal","./Functions/getDefaultMaterial","./Functions/getLambertDiffuse","./Functions/getSpecular","./Functions/getWaterNoise","./Functions/getWgs84EllipsoidEC","./Functions/HSBToRGB","./Functions/HSLToRGB","./Functions/hue","./Functions/isEmpty","./Functions/isFull","./Functions/latitudeToWebMercatorFraction","./Functions/luminance","./Functions/metersPerPixel","./Functions/modelToWindowCoordinates","./Functions/multiplyWithColorBalance","./Functions/nearFarScalar","./Functions/octDecode","./Functions/packDepth","./Functions/phong","./Functions/pointAlongRay","./Functions/rayEllipsoidIntersectionInterval","./Functions/RGBToHSB","./Functions/RGBToHSL","./Functions/RGBToXYZ","./Functions/saturation","./Functions/shadowDepthCompare","./Functions/shadowVisibility","./Functions/signNotZero","./Functions/tangentToEyeSpaceMatrix","./Functions/translateRelativeToEye","./Functions/translucentPhong","./Functions/transpose","./Functions/unpackDepth","./Functions/windowToEyeCoordinates","./Functions/XYZToRGB"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H,W,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,Ce,be,Se,we,Te,Ae,Ee,xe,Pe,De,Ie,Oe,Me,Re,Ne,Le,ke,Fe,Be,Ue,Ve,ze,Ge,He,We,je){"use strict";return{czm_degreesPerRadian:e,czm_depthRange:t,czm_epsilon1:r,czm_epsilon2:i,czm_epsilon3:n,czm_epsilon4:o,czm_epsilon5:a,czm_epsilon6:s,czm_epsilon7:l,czm_infinity:u,czm_maxClippingPlanes:c,czm_oneOverPi:d,czm_oneOverTwoPi:h,czm_passCesium3DTile:p,czm_passCesium3DTileClassification:f,czm_passCesium3DTileClassificationIgnoreShow:m,czm_passCompute:g,czm_passEnvironment:_,czm_passGlobe:v,czm_passOpaque:y,czm_passOverlay:C,czm_passTerrainClassification:b,czm_passTranslucent:S,czm_pi:w,czm_piOverFour:T,czm_piOverSix:A,czm_piOverThree:E,czm_piOverTwo:x,czm_radiansPerDegree:P,czm_sceneMode2D:D,czm_sceneMode3D:I,czm_sceneModeColumbusView:O,czm_sceneModeMorphing:M,czm_solarRadius:R,czm_threePiOver2:N,czm_twoPi:L,czm_webMercatorMaxLatitude:k,czm_depthRangeStruct:F,czm_ellipsoid:B,czm_material:U,czm_materialInput:V,czm_ray:z,czm_raySegment:G,czm_shadowParameters:H,czm_alphaWeight:W,czm_antialias:j,czm_cascadeColor:q,czm_cascadeDistance:Y,czm_cascadeMatrix:X,czm_cascadeWeights:Q,czm_columbusViewMorph:Z,czm_computePosition:K,czm_cosineAndSine:J,czm_decompressTextureCoordinates:$,czm_discardIfClippedWithIntersect:ee,czm_discardIfClippedWithUnion:te,czm_eastNorthUpToEyeCoordinates:re,czm_ellipsoidContainsPoint:ie,czm_ellipsoidNew:ne,czm_ellipsoidWgs84TextureCoordinates:oe,czm_equalsEpsilon:ae,czm_eyeOffset:se,czm_eyeToWindowCoordinates:le,czm_fog:ue,czm_geodeticSurfaceNormal:ce,czm_getDefaultMaterial:de,czm_getLambertDiffuse:he,czm_getSpecular:pe,czm_getWaterNoise:fe,czm_getWgs84EllipsoidEC:me,czm_HSBToRGB:ge,czm_HSLToRGB:_e,czm_hue:ve,czm_isEmpty:ye,czm_isFull:Ce,czm_latitudeToWebMercatorFraction:be,czm_luminance:Se,czm_metersPerPixel:we,czm_modelToWindowCoordinates:Te,czm_multiplyWithColorBalance:Ae,czm_nearFarScalar:Ee,czm_octDecode:xe,czm_packDepth:Pe,czm_phong:De,czm_pointAlongRay:Ie,czm_rayEllipsoidIntersectionInterval:Oe,czm_RGBToHSB:Me,czm_RGBToHSL:Re,czm_RGBToXYZ:Ne,czm_saturation:Le,czm_shadowDepthCompare:ke,czm_shadowVisibility:Fe,czm_signNotZero:Be,czm_tangentToEyeSpaceMatrix:Ue,czm_translateRelativeToEye:Ve,czm_translucentPhong:ze,czm_transpose:Ge,czm_unpackDepth:He,czm_windowToEyeCoordinates:We,czm_XYZToRGB:je}}),define("Renderer/ShaderSource",["../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Renderer/modernizeShader","../Shaders/Builtin/CzmBuiltins","./AutomaticUniforms"],function(e,t,r,i,n,o){"use strict";function a(e){return e=e.replace(/\/\/.*/g,""),e.replace(/\/\*\*[\s\S]*?\*\//gm,function(e){for(var t=e.match(/\n/gm).length,r="",i=0;i0;){var i=e.pop();r.push(i),0===i.requiredBy.length&&t.push(i)}for(;t.length>0;){var n=t.shift();e.push(n);for(var o=0;o=0;--n)i=i+t[n].glslSource+"\n";return i.replace(r.glslSource,"")}function d(e,r,n){var o,s,l="",u=e.sources;if(t(u))for(o=0,s=u.length;o0&&(a.glVertexAttribDivisor(t,this.instanceDivisor),a._vertexAttribDivisors[t]=this.instanceDivisor,a._previousDrawInstanced=!0)},c.disableVertexAttribArray=function(e){e.disableVertexAttribArray(this.index),this.instanceDivisor>0&&a.glVertexAttribDivisor(o,0)};else{switch(c.componentsPerAttribute){case 1:c.vertexAttrib=function(e){e.vertexAttrib1fv(this.index,this.value)};break;case 2:c.vertexAttrib=function(e){e.vertexAttrib2fv(this.index,this.value)};break;case 3:c.vertexAttrib=function(e){e.vertexAttrib3fv(this.index,this.value)};break;case 4:c.vertexAttrib=function(e){e.vertexAttrib4fv(this.index,this.value)}}c.disableVertexAttribArray=function(e){}}e.push(c)}function m(e,t,r){for(var n=0;n0&&(d=!0),i(u[n].value)&&(h=!0);var v;o.vertexArrayObject&&(v=o.glCreateVertexArray(),o.glBindVertexArray(v),m(a,u,l),o.glBindVertexArray(null)),this._numberOfVertices=c,this._hasInstancedAttributes=d,this._hasConstantAttributes=h,this._context=o,this._gl=a,this._vao=v,this._attributes=u,this._indexBuffer=l}function _(e){return e.values.length/e.componentsPerAttribute}function v(e){return t.getSizeInBytes(e.componentDatatype)*e.componentsPerAttribute}function y(e){var r,n,o,a=[];for(n in e)e.hasOwnProperty(n)&&i(e[n])&&i(e[n].values)&&(a.push(n),e[n].componentDatatype===t.DOUBLE&&(e[n].componentDatatype=t.FLOAT,e[n].values=t.createTypedArray(t.FLOAT,e[n].values)));var s,l=a.length;if(l>0)for(s=_(e[a[0]]),r=1;r0){var p=t.getSizeInBytes(e[a[0]].componentDatatype),f=d%p;0!==f&&(d+=p-f);var m=s*d,g=new ArrayBuffer(m),y={};for(r=0;r0&&(t.glVertexAttribDivisor(i,0),n[i]=0)}}function b(e,t){for(var r=e._attributes,n=r.length,o=0;o=u.SIXTY_FOUR_KILOBYTES&&c.elementIndexUint?d.createIndexBuffer({context:c,typedArray:new Uint32Array(x),usage:f,indexDatatype:l.UNSIGNED_INT}):d.createIndexBuffer({context:c,typedArray:new Uint16Array(x),usage:f,indexDatatype:l.UNSIGNED_SHORT})),new g({context:c,attributes:C,indexBuffer:E})},n(g.prototype,{numberOfAttributes:{get:function(){return this._attributes.length}},numberOfVertices:{get:function(){return this._numberOfVertices}},indexBuffer:{get:function(){return this._indexBuffer}}}),g.prototype.getAttribute=function(e){return this._attributes[e]},g.prototype._bind=function(){i(this._vao)?(this._context.glBindVertexArray(this._vao),this._context.instancedArrays&&C(this),this._hasConstantAttributes&&b(this,this._gl)):m(this._gl,this._attributes,this._indexBuffer)},g.prototype._unBind=function(){if(i(this._vao))this._context.glBindVertexArray(null);else{for(var e=this._attributes,t=this._gl,r=0;r=U)return i<0?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY;var n=i*e.x*k;return n+=i*e.y*F,(n+=i*e.z*B)*Math.pow(10,r)}function T(e,t,i){var n=r.unpack(e,t,N),o=w(n);n=r.unpack(e,t+4,N);var a=w(n);n=r.unpack(e,t+8,N);var s=w(n);n=r.unpack(e,t+12,N);var l=w(n);return r.fromElements(o,a,s,l,i)}function A(e,t){if(V[0]=e,0===(e=V[0]))return r.clone(r.ZERO,t);var i,n=e<0?1:0;isFinite(e)?(e=Math.abs(e),i=Math.floor(c.logBase(e,10))+1,e/=Math.pow(10,i)):(e=.1,i=U);var o=e*L;return t.x=Math.floor(o),o=(o-t.x)*L,t.y=Math.floor(o),o=(o-t.y)*L,t.z=Math.floor(o),t.w=2*(i+U)+n,t}function E(e,t,i){var n=A(e.x,N);r.pack(n,t,i),n=A(e.y,n),r.pack(n,t,i+4),n=A(e.z,n),r.pack(n,t,i+8),n=A(e.w,n),r.pack(n,t,i+12)}function x(e,t){var r=e._textureDimensions;e._texture=new m({context:t,pixelFormat:d.RGBA,pixelDatatype:e._pixelDatatype,width:r.x,height:r.y,sampler:new f({minificationFilter:_.NEAREST,magnificationFilter:g.NEAREST})})}function P(e){var t=e._textureDimensions;e._texture.copyFrom({width:t.x,height:t.y,arrayBufferView:e._batchValues})}function D(e){var t=e._stride;return 1===e._textureDimensions.y?"uniform vec4 batchTextureStep; \nvec2 computeSt(float batchId) \n{ \n float stepX = batchTextureStep.x; \n float centerX = batchTextureStep.y; \n float numberOfAttributes = float("+t+"); \n return vec2(centerX + (batchId * numberOfAttributes * stepX), 0.5); \n} \n":"uniform vec4 batchTextureStep; \nuniform vec2 batchTextureDimensions; \nvec2 computeSt(float batchId) \n{ \n float stepX = batchTextureStep.x; \n float centerX = batchTextureStep.y; \n float stepY = batchTextureStep.z; \n float centerY = batchTextureStep.w; \n float numberOfAttributes = float("+t+"); \n float xId = mod(batchId * numberOfAttributes, batchTextureDimensions.x); \n float yId = floor(batchId * numberOfAttributes / batchTextureDimensions.x); \n return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n} \n"}function I(e){return e._packFloats?"float unpackFloat(vec4 value) \n{ \n value *= 255.0; \n float temp = value.w / 2.0; \n float exponent = floor(temp); \n float sign = (temp - exponent) * 2.0; \n exponent = exponent - float("+U+"); \n sign = sign * 2.0 - 1.0; \n sign = -sign; \n float unpacked = sign * value.x * float("+k+"); \n unpacked += sign * value.y * float("+F+"); \n unpacked += sign * value.z * float("+B+"); \n return unpacked * pow(10.0, exponent); \n} \n":""}function O(e){return 1===e?"float":"vec"+e}function M(e){return 1===e?".x":2===e?".xy":3===e?".xyz":""}function R(e,t){var r=e._attributes,i=r[t],o=i.componentsPerAttribute,a=i.functionName,s=O(o),l=M(o),u=e._offsets[t],c=s+" "+a+"(float batchId) \n{ \n vec2 st = computeSt(batchId); \n st.x += batchTextureStep.x * float("+u+"); \n";return e._packFloats&&i.componentDatatype!==p.UNSIGNED_BYTE?c+="vec4 textureValue; \ntextureValue.x = unpackFloat(texture2D(batchTexture, st)); \ntextureValue.y = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x, 0.0))); \ntextureValue.z = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 2.0, 0.0))); \ntextureValue.w = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 3.0, 0.0))); \n":c+=" vec4 textureValue = texture2D(batchTexture, st); \n",c+=" "+s+" value = textureValue"+l+"; \n",e._pixelDatatype!==p.UNSIGNED_BYTE||i.componentDatatype!==n.UNSIGNED_BYTE||i.normalize?e._pixelDatatype===p.FLOAT&&i.componentDatatype===n.UNSIGNED_BYTE&&i.normalize&&(c+="value /= 255.0; \n"):c+="value *= 255.0; \n",c+=" return value; \n} \n"}a(v.prototype,{attributes:{get:function(){return this._attributes}},numberOfInstances:{get:function(){return this._numberOfInstances}}});var N=new r,L=256,k=1/L,F=1/65536,B=1/16777216,U=38;if(u.supportsTypedArrays()){var V=new Float32Array(1),z=new r;v.prototype.getBatchedAttribute=function(e,t,i){var n,a=this._attributes,s=this._offsets[t],l=this._stride,u=4*l*e+4*s;n=this._packFloats&&a[t].componentDatatype!==p.UNSIGNED_BYTE?T(this._batchValues,u,z):r.unpack(this._batchValues,u,z);var c=C(a,t);return o(c.fromCartesian4)?c.fromCartesian4(n,i):o(c.clone)?c.clone(n,i):n.x};var G=[void 0,void 0,new e,new t,new r],H=new r;return v.prototype.setBatchedAttribute=function(e,t,i){var n=this._attributes,a=G[n[t].componentsPerAttribute],s=this.getBatchedAttribute(e,t,a),l=C(this._attributes,t);if(!(o(l.equals)?l.equals(s,i):s===i)){var u=H;u.x=o(i.x)?i.x:i,u.y=o(i.y)?i.y:0,u.z=o(i.z)?i.z:0,u.w=o(i.w)?i.w:0;var c=this._offsets[t],d=this._stride,h=4*d*e+4*c;this._packFloats&&n[t].componentDatatype!==p.UNSIGNED_BYTE?E(u,this._batchValues,h):r.pack(u,this._batchValues,h),this._batchValuesDirty=!0}},v.prototype.update=function(e){o(this._texture)&&!this._batchValuesDirty||0===this._attributes.length||(this._batchValuesDirty=!1,o(this._texture)||x(this,e.context),P(this))},v.prototype.getUniformMapCallback=function(){var e=this;return function(t){return 0===e._attributes.length?t:i(t,{batchTexture:function(){return e._texture},batchTextureDimensions:function(){return e._textureDimensions},batchTextureStep:function(){return e._textureStep}})}},v.prototype.getVertexShaderCallback=function(){var e=this._attributes;if(0===e.length)return function(e){return e};var t="uniform sampler2D batchTexture; \n";t+=D(this)+"\n",t+=I(this)+"\n";for(var r=e.length,i=0;i1){var s=e[0].modelMatrix;for(n=1;n=0){var u=n[l];o=u.offset+u.count,s=u.index,a=i[s].indices.length}else o=0,s=0,a=i[s].indices.length;for(var c=e.length,d=0;da&&(o=0,a=i[++s].indices.length),n.push({index:s,offset:o,count:f}),o+=f}}}function y(e,t){var r=[];return v(e,"geometry",t,r),v(e,"westHemisphereGeometry",t,r),v(e,"eastHemisphereGeometry",t,r),r}function C(e,t){var i=e.attributes;for(var n in i)if(i.hasOwnProperty(n)){var o=i[n];r(o)&&r(o.values)&&t.push(o.values.buffer)}r(e.indices)&&t.push(e.indices.buffer)}function b(e,t){for(var r=e.length,i=0;i0&&(i=_(t),i.length>0&&(n=c.createAttributeLocations(i[0]),t.createPickOffsets&&(o=y(a,i))));for(var l=new Array(s),u=new Array(s),d=0;d0&&(n.set(c.indices,l),l+=C)}}return i.push(n.buffer),{stringTable:o,packedData:n}},x.unpackCreateGeometryResults=function(r){for(var i,n=r.stringTable,o=r.packedData,a=new Array(o[0]),c=0,h=1;h0){var x=v.length/y;for(E=d.createTypedArray(x,_),i=0;i<_;i++)E[i]=o[h++]}a[c++]=new s({primitiveType:m,geometryType:g,boundingSphere:p,boundingSphereCV:f,indices:E,attributes:C})}else a[c++]=void 0}return a},x.packCombineGeometryParameters=function(e,t){for(var r=e.createGeometryResults,i=r.length,n=0;n1?"vec"+a:"float",l="compressedAttributes",u="attribute "+s+" "+l+";",c="",d="";if(i){c+="vec2 st;\n";d+=" st = czm_decompressTextureCoordinates("+(a>1?l+".x":l)+");\n"}r&&n&&o?(c+="vec3 normal;\nvec3 tangent;\nvec3 bitangent;\n",d+=" czm_octDecode("+l+"."+(i?"yz":"xy")+", normal, tangent, bitangent);\n"):(r&&(c+="vec3 normal;\n",d+=" normal = czm_octDecode("+l+(a>1?"."+(i?"y":"x"):"")+");\n"),n&&(c+="vec3 tangent;\n",d+=" tangent = czm_octDecode("+l+"."+(i&&r?"z":"y")+");\n"),o&&(c+="vec3 bitangent;\n",d+=" bitangent = czm_octDecode("+l+"."+(i&&r?"z":"y")+");\n"));var h=t;return h=h.replace(/attribute\s+vec3\s+normal;/g,""),h=h.replace(/attribute\s+vec2\s+st;/g,""),h=h.replace(/attribute\s+vec3\s+tangent;/g,""),h=h.replace(/attribute\s+vec3\s+bitangent;/g,""),h=I.replaceMain(h,"czm_non_compressed_main"),[u,c,h,"void main() \n{ \n"+d+" czm_non_compressed_main(); \n}"].join("\n")}function X(e){var t=I.replaceMain(e,"czm_non_depth_clamp_main");return t+="varying float v_WindowZ;\nvoid main() {\n czm_non_depth_clamp_main();\n vec4 position = gl_Position;\n v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n position.z = min(position.z, position.w);\n gl_Position = position;}\n"}function Q(e){var t=I.replaceMain(e,"czm_non_depth_clamp_main");return t+="varying float v_WindowZ;\nvoid main() {\n czm_non_depth_clamp_main();\n#ifdef GL_EXT_frag_depth\n gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n#endif\n}\n",t="#ifdef GL_EXT_frag_depth\n#extension GL_EXT_frag_depth : enable\n#endif\n"+t}function Z(e,t){e.vertexAttributes}function K(e,t){return function(){return e[t]}}function J(e,t){var r,i,n,o,a=e._instanceIds;if(e._state===F.READY){r=y(e.geometryInstances)?e.geometryInstances:[e.geometryInstances];var s=e._numberOfInstances=r.length,l=[],d=[];for(n=0;n0){var _=new Float64Array(p);for(g=[_.buffer],o=0;o0?e._state=F.COMBINED:ce(e,t,F.FAILED,void 0)}).otherwise(function(r){ce(e,t,F.FAILED,r)})}}function $(e,t){var r,i,n=y(e.geometryInstances)?e.geometryInstances:[e.geometryInstances],o=e._numberOfInstances=n.length,a=new Array(o),s=e._instanceIds,l=0;for(i=0;i0?e._state=F.COMBINED:ce(e,t,F.FAILED,void 0)}function ee(t,r){if(c(t._batchTableAttributeIndices.distanceDisplayCondition)&&!t._batchTableBoundingSpheresUpdated){for(var i=t._batchTableBoundingSphereAttributeIndices,n=i.center3DHigh,o=i.center3DLow,a=i.center2DHigh,s=i.center2DLow,l=i.radius,u=r.mapProjection,d=u.ellipsoid,h=t._batchTable,p=t._instanceBoundingSpheres,m=p.length,g=0;g0){if(0===A.maximumVertexTextureImageUnits)throw new b("Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero.");this._batchTable.update(e)}if(this._state!==F.COMPLETE&&this._state!==F.COMBINED&&(this.asynchronous?J(this,e):$(this,e)),this._state===F.COMBINED&&(ee(this,e),te(this,e)),this.show&&this._state===F.COMPLETE){var r=this.appearance,i=r.material,n=!1,o=!1;this._appearance!==r?(this._appearance=r,this._material=i,n=!0,o=!0):this._material!==i&&(this._material=i,o=!0);var a=this.depthFailAppearance,s=c(a)?a.material:void 0;this._depthFailAppearance!==a?(this._depthFailAppearance=a,this._depthFailMaterial=s,n=!0,o=!0):this._depthFailMaterial!==s&&(this._depthFailMaterial=s,o=!0);var l=this._appearance.isTranslucent();this._translucent!==l&&(this._translucent=l,n=!0),c(this._material)&&this._material.update(t);var d=r.closed&&l;if(n){u(this._createRenderStatesFunction,re)(this,t,r,d)}if(o){u(this._createShaderProgramFunction,ie)(this,e,r)}if(n||o){u(this._createCommandsFunction,oe)(this,r,i,l,d,this._colorCommands,this._pickCommands,e)}u(this._updateAndQueueCommandsFunction,ae)(this,e,this._colorCommands,this._pickCommands,this.modelMatrix,this.cull,this.debugShowBoundingVolume,d)}}}},V.prototype.getGeometryInstanceAttributes=function(e){for(var t=-1,r=this._lastPerInstanceAttributeIndex,i=this._instanceIds,n=i.length,o=0;o-1;c--)i=n[c],u(e,b,p,i);for(r=g-1;r>=0;r--)for(h=m[r],h.collectionChanged.addEventListener(d.prototype._onCollectionChanged,e),n=h.values,p=h.id,c=n.length-1;c>-1;c--){i=n[c],l(e,b,p,i);var S=C.getById(i.id);t(S)||(S=y.getById(i.id),t(S)?s(S):(f.id=i.id,S=new o(f)),C.add(S)),S.merge(i)}e._collectionsCopy=m.slice(0),y.suspendEvents(),y.removeAll();var w=C.values;for(r=0;r=0;h--)p=n[h].getById(C),t(p)&&(t(m)||(m=c.getById(C),s(m)),m.merge(p));t(m)||c.removeById(C),m=void 0}var b=r.length;for(d=0;d=0;h--)p=n[h].getById(w),t(p)&&(t(m)||(m=c.getById(w),t(m)?s(m):(f.id=w,m=new o(f),c.add(m))),m.merge(p));m=void 0}c.resumeEvents()},d.prototype._onDefinitionChanged=function(e,r,i,n){for(var o=this._collections,a=this._composite,s=o.length,l=e.id,u=a.getById(l),c=u[r],d=!t(c),h=!0,p=s-1;p>=0;p--){var f=o[p].getById(e.id);if(t(f)){var m=f[r];if(t(m)){if(h){if(h=!1,!t(m.merge)||!t(m.clone)){c=m;break}c=m.clone(c)}c.merge(m)}}}d&&-1===u.propertyNames.indexOf(r)&&u.addProperty(r),u[r]=c},d}),define("DataSources/CompositeProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/EventHelper","../Core/TimeIntervalCollection","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(t,r,i,n){function o(){i.raiseEvent(t)}var a=[];r.removeAll();for(var s=n.length,l=0;l1&&(i=F),this._createBoundingVolumeFunction=e._createBoundingVolumeFunction,this._updateAndQueueCommandsFunction=e._updateAndQueueCommandsFunction,this._primitiveOptions={geometryInstances:void 0,appearance:n,vertexCacheOptimize:t(e.vertexCacheOptimize,!1),interleave:t(e.interleave,!1),releaseGeometryInstances:t(e.releaseGeometryInstances,!0),allowPicking:t(e.allowPicking,!0),asynchronous:t(e.asynchronous,!0),compressVertices:t(e.compressVertices,!0),_readOnlyInstanceAttributes:i,_createBoundingVolumeFunction:void 0,_createRenderStatesFunction:void 0,_createShaderProgramFunction:void 0,_createCommandsFunction:void 0,_updateAndQueueCommandsFunction:void 0,_createPickOffsets:!0}}function A(e){return{colorMask:{red:!1,green:!1,blue:!1,alpha:!1},stencilTest:{enabled:e,frontFunction:S.ALWAYS,frontOperation:{fail:w.KEEP,zFail:w.DECREMENT_WRAP,zPass:w.DECREMENT_WRAP},backFunction:S.ALWAYS,backOperation:{fail:w.KEEP,zFail:w.INCREMENT_WRAP,zPass:w.INCREMENT_WRAP},reference:U,mask:B},depthTest:{enabled:!1},depthMask:!1}}function E(e){return{colorMask:{red:!1,green:!1,blue:!1,alpha:!1},stencilTest:{enabled:e,frontFunction:S.ALWAYS,frontOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.INCREMENT_WRAP},backFunction:S.ALWAYS,backOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},reference:U,mask:B},depthTest:{enabled:!0,func:v.LESS_OR_EQUAL},depthMask:!1}}function x(e){return{stencilTest:{enabled:e,frontFunction:S.NOT_EQUAL,frontOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},backFunction:S.NOT_EQUAL,backOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},reference:U,mask:B},depthTest:{enabled:!1},depthMask:!1,blending:g.ALPHA_BLEND}}function P(e,t,i,n){if(!r(e._rsStencilPreloadPass)){var o=!e.debugShowShadowVolume;e._rsStencilPreloadPass=c.fromCache(A(o)),e._rsStencilDepthPass=c.fromCache(E(o)),e._rsColorPass=c.fromCache(x(o)),e._rsPickPass=c.fromCache(V)}}function D(e,t){if(!e.compressVertices)return t;if(-1!==t.search(/attribute\s+vec3\s+extrudeDirection;/g)){var r=t;r=r.replace(/attribute\s+vec3\s+extrudeDirection;/g,""),r=h.replaceMain(r,"czm_non_compressed_main");return["attribute vec2 compressedAttributes;","vec3 extrudeDirection;\n",r,"void main() \n{ \n extrudeDirection = czm_octDecode(compressedAttributes, 65535.0);\n czm_non_compressed_main(); \n}"].join("\n")}}function I(e,t,i){if(!r(e._sp)){var n=t.context,o=e._primitive,a=f;a=e._primitive._batchTable.getVertexShaderCallback()(a),a=C._appendDistanceDisplayConditionToShader(o,a),a=C._modifyShaderPosition(e,a,t.scene3DOnly),a=C._updateColorAttribute(o,a),e._extruded&&(a=D(o,a));var s=e._extruded?"EXTRUDED_GEOMETRY":"",l=new h({defines:[s],sources:[a]}),u=new h({sources:[p]}),c=e._primitive._attributeLocations;if(e._spStencil=d.replaceCache({context:n,shaderProgram:e._spStencil,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:c}),e._primitive.allowPicking){var m=h.createPickVertexShaderSource(a);m=C._appendShowToShader(o,m),m=C._updatePickColorAttribute(m);var g=new h({defines:[s],sources:[m]}),_=new h({sources:[p],pickColorQualifier:"varying"});e._spPick=d.replaceCache({context:n,shaderProgram:e._spPick,vertexShaderSource:g,fragmentShaderSource:_,attributeLocations:c})}else e._spPick=d.fromCache({context:n,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:c});a=C._appendShowToShader(o,a),l=new h({defines:[s],sources:[a]}),e._sp=d.replaceCache({context:n,shaderProgram:e._sp,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:c})}}function O(e,t){var i=e._primitive,n=3*i._va.length;t.length=2*n;var o,a,s=0,c=i._batchTable.getUniformMapCallback()(e._uniformMap);for(o=0;os?s:t-1}}function E(e,t,r){var n=A(t),o=b._defaultMinTerrainHeight,s=b._defaultMaxTerrainHeight;if(a(n)){var l=n.level+"-"+n.x+"-"+n.y,u=b._terrainHeights[l];a(u)&&(o=u[0],s=u[1]),r.cartographicToCartesian(g.northeast(t,H),z),r.cartographicToCartesian(g.southwest(t,H),G),i.subtract(G,z,W),i.add(z,i.multiplyByScalar(W,.5,W),W);var c=r.scaleToGeodeticSurface(W,j);if(a(c)){var d=i.distance(W,c);o=Math.min(o,-d)}else o=b._defaultMinTerrainHeight}e._minTerrainHeight=Math.max(b._defaultMinTerrainHeight,o),e._maxTerrainHeight=s}function x(t,r){var i=A(t),n=b._defaultMaxTerrainHeight;if(a(i)){var o=i.level+"-"+i.x+"-"+i.y,s=b._terrainHeights[o];a(s)&&(n=s[1])}var l=e.fromRectangle3D(t,r,0);return e.fromRectangle3D(t,r,n,q),e.union(l,q,l)}function P(t,r,n){var o=r.mapProjection.ellipsoid,a=T(r,n);if(a.width=A.clientWidth)P=!0;else{if(B.x>.5*A.clientWidth){E.width=B.x,x.frustum.right=O.x-k,g=p(b,n,x,g),f.clipToGLWindowCoordinates(E,g,v),E.x+=B.x,x.position.x=-x.position.x;var U=x.frustum.right;x.frustum.right=-x.frustum.left,x.frustum.left=-U,g=p(b,n,x,g),f.clipToGLWindowCoordinates(E,g,y)}else{E.x+=B.x,E.width-=B.x,x.frustum.left=-O.x-k,g=p(b,n,x,g),f.clipToGLWindowCoordinates(E,g,v),E.x=E.x-E.width,x.position.x=-x.position.x;var V=x.frustum.left;x.frustum.left=-x.frustum.right,x.frustum.right=-V,g=p(b,n,x,g),f.clipToGLWindowCoordinates(E,g,y)}r.clone(M,x.position),x.frustum=R.clone(),a=t.clone(v,a),(a.x<0||a.x>A.clientWidth)&&(a.x=y.x)}}if(C.mode!==h.SCENE2D||P){if(g=p(b,n,x,g),g.z<0&&!(x.frustum instanceof u)&&!(x.frustum instanceof c))return;a=f.clipToGLWindowCoordinates(E,g,a)}return a.y=A.clientHeight-a.y,a}},f.wgs84ToDrawingBufferCoordinates=function(e,t,r){if(r=f.wgs84ToWindowCoordinates(e,t,r),o(r))return f.transformWindowToDrawingBuffer(e,r,r)};var A=new r,E=new n;f.computeActualWgs84Position=function(e,t,i){var n=e.mode;if(n===h.SCENE3D)return r.clone(t,i);var a=e.mapProjection,l=a.ellipsoid.cartesianToCartographic(t,E);if(o(l)){if(a.project(l,A),n===h.COLUMBUS_VIEW)return r.fromElements(A.z,A.x,A.y,i);if(n===h.SCENE2D)return r.fromElements(0,A.x,A.y,i);var u=e.morphTime;return r.fromElements(s.lerp(A.z,t.x,u),s.lerp(A.x,t.y,u),s.lerp(A.y,t.z,u),i)}};var x=new r,P=new r,D=new l;f.clipToGLWindowCoordinates=function(e,i,n){return r.divideByScalar(i,i.w,x),l.computeViewportTransformation(e,0,1,D),l.multiplyByPoint(D,x,P),t.fromCartesian3(P,n)},f.transformWindowToDrawingBuffer=function(e,r,i){var n=e.canvas,o=e.drawingBufferWidth/n.clientWidth,a=e.drawingBufferHeight/n.clientHeight;return t.fromElements(r.x*o,r.y*a,i)};var I=new i,O=new i;return f.drawingBufferToWgs84Coordinates=function(e,t,n,a){var s=e.context,u=s.uniformState,c=e._passState.viewport,d=i.clone(i.UNIT_W,I);d.x=(t.x-c.x)/c.width*2-1,d.y=(t.y-c.y)/c.height*2-1,d.z=2*n-1,d.w=1;var h,p=e.camera.frustum;if(o(p.fovy)){h=l.multiplyByVector(u.inverseViewProjection,d,O);var f=1/h.w;r.multiplyByScalar(h,f,h)}else{o(p._offCenterFrustum)&&(p=p._offCenterFrustum);var m=u.currentFrustum;h=O,h.x=.5*(d.x*(p.right-p.left)+p.left+p.right),h.y=.5*(d.y*(p.top-p.bottom)+p.bottom+p.top),h.z=.5*(d.z*(m.x-m.y)-m.x-m.y),h.w=1,h=l.multiplyByVector(u.inverseView,h,h)}return r.fromCartesian4(h,a)},f}),define("Scene/Billboard",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Matrix4","../Core/NearFarScalar","./HeightReference","./HorizontalOrigin","./SceneMode","./SceneTransforms","./VerticalOrigin"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(e,i){e=s(e,s.EMPTY_OBJECT);var n=e.translucencyByDistance,u=e.pixelOffsetScaleByDistance,c=e.scaleByDistance,h=e.distanceDisplayCondition;l(n)&&(n=p.clone(n)),l(u)&&(u=p.clone(u)),l(c)&&(c=p.clone(c)),l(h)&&(h=d.clone(h)),this._show=s(e.show,!0),this._position=r.clone(s(e.position,r.ZERO)),this._actualPosition=r.clone(this._position),this._pixelOffset=t.clone(s(e.pixelOffset,t.ZERO)),this._translate=new t(0,0),this._eyeOffset=r.clone(s(e.eyeOffset,r.ZERO)),this._heightReference=s(e.heightReference,f.NONE),this._verticalOrigin=s(e.verticalOrigin,v.CENTER),this._horizontalOrigin=s(e.horizontalOrigin,m.CENTER),this._scale=s(e.scale,1),this._color=o.clone(s(e.color,o.WHITE)),this._rotation=s(e.rotation,0),this._alignedAxis=r.clone(s(e.alignedAxis,r.ZERO)),this._width=e.width,this._height=e.height,this._scaleByDistance=c,this._translucencyByDistance=n,this._pixelOffsetScaleByDistance=u,this._sizeInMeters=s(e.sizeInMeters,!1),this._distanceDisplayCondition=h,this._disableDepthTestDistance=s(e.disableDepthTestDistance,0),this._id=e.id,this._collection=s(e.collection,i),this._pickId=void 0,this._pickPrimitive=s(e._pickPrimitive,this),this._billboardCollection=i,this._dirty=!1,this._index=-1,this._imageIndex=-1,this._imageIndexPromise=void 0,this._imageId=void 0,this._image=void 0,this._imageSubRegion=void 0,this._imageWidth=void 0,this._imageHeight=void 0;var _=e.image,y=e.imageId;l(_)&&(l(y)||(y="string"==typeof _?_:l(_.src)?_.src:a()),this._imageId=y,this._image=_),l(e.imageSubRegion)&&(this._imageId=y,this._imageSubRegion=e.imageSubRegion),l(this._billboardCollection._textureAtlas)&&this._loadImage(),this._actualClampedPosition=void 0,this._removeCallbackFunc=void 0,this._mode=g.SCENE3D,this._clusterShow=!0,this._updateClamping()}function C(e,t){var r=e._billboardCollection;l(r)&&(r._updateBillboard(e,t),e._dirty=!0)}var b=y.SHOW_INDEX=0,S=y.POSITION_INDEX=1,w=y.PIXEL_OFFSET_INDEX=2,T=y.EYE_OFFSET_INDEX=3,A=y.HORIZONTAL_ORIGIN_INDEX=4,E=y.VERTICAL_ORIGIN_INDEX=5,x=y.SCALE_INDEX=6,P=y.IMAGE_INDEX_INDEX=7,D=y.COLOR_INDEX=8,I=y.ROTATION_INDEX=9,O=y.ALIGNED_AXIS_INDEX=10,M=y.SCALE_BY_DISTANCE_INDEX=11,R=y.TRANSLUCENCY_BY_DISTANCE_INDEX=12,N=y.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX=13,L=y.DISTANCE_DISPLAY_CONDITION=14,k=y.DISABLE_DEPTH_DISTANCE=15;y.NUMBER_OF_PROPERTIES=16,u(y.prototype,{show:{get:function(){return this._show},set:function(e){this._show!==e&&(this._show=e,C(this,b))}},position:{get:function(){return this._position},set:function(e){var t=this._position;r.equals(t,e)||(r.clone(e,t),r.clone(e,this._actualPosition),this._updateClamping(),C(this,S))}},heightReference:{get:function(){return this._heightReference},set:function(e){e!==this._heightReference&&(this._heightReference=e,this._updateClamping(),C(this,S))}},pixelOffset:{get:function(){return this._pixelOffset},set:function(e){var r=this._pixelOffset;t.equals(r,e)||(t.clone(e,r),C(this,w))}},scaleByDistance:{get:function(){return this._scaleByDistance},set:function(e){var t=this._scaleByDistance;p.equals(t,e)||(this._scaleByDistance=p.clone(e,t),C(this,M))}},translucencyByDistance:{get:function(){return this._translucencyByDistance},set:function(e){var t=this._translucencyByDistance;p.equals(t,e)||(this._translucencyByDistance=p.clone(e,t),C(this,R))}},pixelOffsetScaleByDistance:{get:function(){return this._pixelOffsetScaleByDistance},set:function(e){var t=this._pixelOffsetScaleByDistance;p.equals(t,e)||(this._pixelOffsetScaleByDistance=p.clone(e,t),C(this,N))}},eyeOffset:{get:function(){return this._eyeOffset},set:function(e){var t=this._eyeOffset;r.equals(t,e)||(r.clone(e,t),C(this,T))}},horizontalOrigin:{get:function(){return this._horizontalOrigin},set:function(e){this._horizontalOrigin!==e&&(this._horizontalOrigin=e,C(this,A))}},verticalOrigin:{get:function(){return this._verticalOrigin},set:function(e){this._verticalOrigin!==e&&(this._verticalOrigin=e,C(this,E))}},scale:{get:function(){return this._scale},set:function(e){this._scale!==e&&(this._scale=e,C(this,x))}},color:{get:function(){return this._color},set:function(e){var t=this._color;o.equals(t,e)||(o.clone(e,t),C(this,D))}},rotation:{get:function(){return this._rotation},set:function(e){this._rotation!==e&&(this._rotation=e,C(this,I))}},alignedAxis:{get:function(){return this._alignedAxis},set:function(e){var t=this._alignedAxis;r.equals(t,e)||(r.clone(e,t),C(this,O))}},width:{get:function(){return s(this._width,this._imageWidth)},set:function(e){this._width!==e&&(this._width=e,C(this,P))}},height:{get:function(){return s(this._height,this._imageHeight)},set:function(e){this._height!==e&&(this._height=e,C(this,P))}},sizeInMeters:{get:function(){return this._sizeInMeters},set:function(e){this._sizeInMeters!==e&&(this._sizeInMeters=e,C(this,D))}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){d.equals(e,this._distanceDisplayCondition)||(this._distanceDisplayCondition=d.clone(e,this._distanceDisplayCondition),C(this,L))}},disableDepthTestDistance:{get:function(){return this._disableDepthTestDistance},set:function(e){this._disableDepthTestDistance!==e&&(this._disableDepthTestDistance=e,C(this,k))}},id:{get:function(){return this._id},set:function(e){this._id=e,l(this._pickId)&&(this._pickId.object.id=e)}},pickPrimitive:{get:function(){return this._pickPrimitive},set:function(e){this._pickPrimitive=e,l(this._pickId)&&(this._pickId.object.primitive=e)}},image:{get:function(){return this._imageId},set:function(e){l(e)?"string"==typeof e?this.setImage(e,e):l(e.src)?this.setImage(e.src,e):this.setImage(a(),e):(this._imageIndex=-1,this._imageSubRegion=void 0,this._imageId=void 0,this._image=void 0,this._imageIndexPromise=void 0,C(this,P))}},ready:{get:function(){return-1!==this._imageIndex}},_clampedPosition:{get:function(){return this._actualClampedPosition},set:function(e){this._actualClampedPosition=r.clone(e,this._actualClampedPosition),C(this,S)}},clusterShow:{get:function(){return this._clusterShow},set:function(e){this._clusterShow!==e&&(this._clusterShow=e,C(this,b))}}}),y.prototype.getPickId=function(e){return l(this._pickId)||(this._pickId=e.createPickId({primitive:this._pickPrimitive,collection:this._collection,id:this._id})),this._pickId},y.prototype._updateClamping=function(){y._updateClamping(this._billboardCollection,this)};var F=new n,B=new r;y._updateClamping=function(e,t){function i(e){if(t._heightReference===f.RELATIVE_TO_GROUND)if(t._mode===g.SCENE3D){var i=s.cartesianToCartographic(e,F);i.height+=h.height,s.cartographicToCartesian(i,e)}else e.x+=h.height;t._clampedPosition=r.clone(e,t._clampedPosition)}var o=e._scene;if(l(o)){var a=o.globe,s=a.ellipsoid,u=a._surface,c=o.frameState.mode,d=c!==t._mode;if(t._mode=c,(t._heightReference===f.NONE||d)&&l(t._removeCallbackFunc)&&(t._removeCallbackFunc(),t._removeCallbackFunc=void 0,t._clampedPosition=void 0),t._heightReference!==f.NONE&&l(t._position)){var h=s.cartesianToCartographic(t._position);if(!l(h))return void(t._actualClampedPosition=void 0);l(t._removeCallbackFunc)&&t._removeCallbackFunc(),t._removeCallbackFunc=u.updateHeight(h,i),n.clone(h,F);var p=a.getHeight(h);l(p)&&(F.height=p),s.cartographicToCartesian(F,B),i(B)}}},y.prototype._loadImage=function(){var t,r=this._billboardCollection._textureAtlas,i=this._imageId,n=this._image,o=this._imageSubRegion;if(l(n)&&(t=r.addImage(i,n)),l(o)&&(t=r.addSubRegion(i,o)),this._imageIndexPromise=t,l(t)){var a=this;t.then(function(t){if(a._imageId===i&&a._image===n&&e.equals(a._imageSubRegion,o)){var s=r.textureCoordinates[t];a._imageWidth=r.texture.width*s.width,a._imageHeight=r.texture.height*s.height,a._imageIndex=t,a._ready=!0,a._image=void 0,a._imageIndexPromise=void 0,C(a,P)}}).otherwise(function(e){console.error("Error loading image for billboard: "+e),a._imageIndexPromise=void 0})}},y.prototype.setImage=function(e,t){this._imageId!==e&&(this._imageIndex=-1,this._imageSubRegion=void 0,this._imageId=e,this._image=t,l(this._billboardCollection._textureAtlas)&&this._loadImage())},y.prototype.setImageSubRegion=function(t,r){this._imageId===t&&e.equals(this._imageSubRegion,r)||(this._imageIndex=-1,this._imageId=t,this._imageSubRegion=e.clone(r),l(this._billboardCollection._textureAtlas)&&this._loadImage())},y.prototype._setTranslate=function(e){var r=this._translate;t.equals(r,e)||(t.clone(e,r),C(this,w))},y.prototype._getActualPosition=function(){return l(this._clampedPosition)?this._clampedPosition:this._actualPosition},y.prototype._setActualPosition=function(e){l(this._clampedPosition)||r.clone(e,this._actualPosition),C(this,S)};var U=new i;y._computeActualPosition=function(e,t,r,i){return l(e._clampedPosition)?(r.mode!==e._mode&&e._updateClamping(),e._clampedPosition):r.mode===g.SCENE3D?t:(h.multiplyByPoint(i,t,U),_.computeActualWgs84Position(r,U))};var V=new r;y._computeScreenSpacePosition=function(e,r,i,n,o,a){var s=h.multiplyByPoint(e,r,V),u=_.wgs84WithEyeOffsetToWindowCoordinates(o,s,i,a);if(l(u))return t.add(u,n,u),u};var z=new t(0,0);return y.prototype.computeScreenSpacePosition=function(e,r){var i=this._billboardCollection;l(r)||(r=new t),t.clone(this._pixelOffset,z),t.add(z,this._translate,z);var n=i.modelMatrix,o=this._position;if(l(this._clampedPosition)&&(o=this._clampedPosition,e.mode!==g.SCENE3D)){var a=e.mapProjection,s=a.ellipsoid,u=a.unproject(o,F);o=s.cartographicToCartesian(u,V),n=h.IDENTITY}return y._computeScreenSpacePosition(n,o,this._eyeOffset,z,e,r)},y.getScreenSpaceBoundingBox=function(t,r,i){var n=t.width,o=t.height,a=t.scale;n*=a,o*=a;var s=r.x;t.horizontalOrigin===m.RIGHT?s-=n:t.horizontalOrigin===m.CENTER&&(s-=.5*n);var u=r.y;return t.verticalOrigin===v.BOTTOM||t.verticalOrigin===v.BASELINE?u-=o:t.verticalOrigin===v.CENTER&&(u-=.5*o),l(i)||(i=new e),i.x=s,i.y=u,i.width=n,i.height=o,i},y.prototype.equals=function(i){return this===i||l(i)&&this._id===i._id&&r.equals(this._position,i._position)&&this._imageId===i._imageId&&this._show===i._show&&this._scale===i._scale&&this._verticalOrigin===i._verticalOrigin&&this._horizontalOrigin===i._horizontalOrigin&&this._heightReference===i._heightReference&&e.equals(this._imageSubRegion,i._imageSubRegion)&&o.equals(this._color,i._color)&&t.equals(this._pixelOffset,i._pixelOffset)&&t.equals(this._translate,i._translate)&&r.equals(this._eyeOffset,i._eyeOffset)&&p.equals(this._scaleByDistance,i._scaleByDistance)&&p.equals(this._translucencyByDistance,i._translucencyByDistance)&&p.equals(this._pixelOffsetScaleByDistance,i._pixelOffsetScaleByDistance)&&d.equals(this._distanceDisplayCondition,i._distanceDisplayCondition)&&this._disableDepthTestDistance===i._disableDepthTestDistance},y.prototype._destroy=function(){l(this._customData)&&(this._billboardCollection._scene.globe._surface.removeTileCustomData(this._customData),this._customData=void 0),l(this._removeCallbackFunc)&&(this._removeCallbackFunc(),this._removeCallbackFunc=void 0),this.image=void 0,this._pickId=this._pickId&&this._pickId.destroy(),this._billboardCollection=void 0},y}),define("Renderer/VertexArrayFacade",["../Core/Check","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Math","./Buffer","./BufferUsage","./VertexArray"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,n,o,a){function s(e,r){return t.getSizeInBytes(r.componentDatatype)-t.getSizeInBytes(e.componentDatatype)}var l=c._verifyAttributes(n);o=r(o,0);for(var u,d,h=[],p={},f=l.length,m=0;m0){t.needsCommit=!1;var r=t.vertexBuffer,n=e._size*t.vertexSizeInBytes,o=i(r);if(!o||r.sizeInBytes0){var i=e.vertexSizeInBytes*t,n=e.vertexSizeInBytes*r;e.vertexBuffer.copyFromArrayView(new Uint8Array(e.arrayBuffer,i,n),i)}}function p(e){var t=e.va;if(i(t)){for(var r=t.length,n=0;n0?t.getSizeInBytes(e[0].componentDatatype):0,s=a>0?r%a:0;return r+=0===s?0:a-s},c._createArrayViews=function(e,r){for(var i=[],n=0,o=e.length,a=0;a0){var n=new ArrayBuffer(r*e.vertexSizeInBytes);if(i(e.arrayBuffer))for(var o=new Uint8Array(n),a=new Uint8Array(e.arrayBuffer),s=a.length,l=0;l= 0.995)\n{\ndiscard;\n}\n#endif\n#endif\n#ifdef RENDER_FOR_PICK\ngl_FragColor = v_pickColor;\n#else\ngl_FragColor = color;\n#endif\n}\n"}),define("Shaders/BillboardCollectionVS",[],function(){"use strict" -;return"#ifdef INSTANCED\nattribute vec2 direction;\n#endif\nattribute vec4 positionHighAndScale;\nattribute vec4 positionLowAndRotation;\nattribute vec4 compressedAttribute0;\nattribute vec4 compressedAttribute1;\nattribute vec4 compressedAttribute2;\nattribute vec4 eyeOffset;\nattribute vec4 scaleByDistance;\nattribute vec4 pixelOffsetScaleByDistance;\nattribute vec3 distanceDisplayConditionAndDisableDepth;\nvarying vec2 v_textureCoordinates;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#else\nvarying vec4 v_color;\n#endif\nconst float UPPER_BOUND = 32768.0;\nconst float SHIFT_LEFT16 = 65536.0;\nconst float SHIFT_LEFT8 = 256.0;\nconst float SHIFT_LEFT7 = 128.0;\nconst float SHIFT_LEFT5 = 32.0;\nconst float SHIFT_LEFT3 = 8.0;\nconst float SHIFT_LEFT2 = 4.0;\nconst float SHIFT_LEFT1 = 2.0;\nconst float SHIFT_RIGHT8 = 1.0 / 256.0;\nconst float SHIFT_RIGHT7 = 1.0 / 128.0;\nconst float SHIFT_RIGHT5 = 1.0 / 32.0;\nconst float SHIFT_RIGHT3 = 1.0 / 8.0;\nconst float SHIFT_RIGHT2 = 1.0 / 4.0;\nconst float SHIFT_RIGHT1 = 1.0 / 2.0;\nvec4 computePositionWindowCoordinates(vec4 positionEC, vec2 imageSize, float scale, vec2 direction, vec2 origin, vec2 translate, vec2 pixelOffset, vec3 alignedAxis, bool validAlignedAxis, float rotation, bool sizeInMeters)\n{\nvec2 halfSize = imageSize * scale * czm_resolutionScale * 0.5;\nhalfSize *= ((direction * 2.0) - 1.0);\nvec2 originTranslate = origin * abs(halfSize);\n#if defined(ROTATION) || defined(ALIGNED_AXIS)\nif (validAlignedAxis || rotation != 0.0)\n{\nfloat angle = rotation;\nif (validAlignedAxis)\n{\nvec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0);\nangle += sign(-projectedAlignedAxis.x) * acos( sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) /\n(projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y) );\n}\nfloat cosTheta = cos(angle);\nfloat sinTheta = sin(angle);\nmat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta);\nhalfSize = rotationMatrix * halfSize;\n}\n#endif\nif (sizeInMeters)\n{\npositionEC.xy += halfSize;\n}\nvec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\nif (sizeInMeters)\n{\noriginTranslate /= czm_metersPerPixel(positionEC);\n}\npositionWC.xy += originTranslate;\nif (!sizeInMeters)\n{\npositionWC.xy += halfSize;\n}\npositionWC.xy += translate;\npositionWC.xy += (pixelOffset * czm_resolutionScale);\nreturn positionWC;\n}\nvoid main()\n{\nvec3 positionHigh = positionHighAndScale.xyz;\nvec3 positionLow = positionLowAndRotation.xyz;\nfloat scale = positionHighAndScale.w;\n#if defined(ROTATION) || defined(ALIGNED_AXIS)\nfloat rotation = positionLowAndRotation.w;\n#else\nfloat rotation = 0.0;\n#endif\nfloat compressed = compressedAttribute0.x;\nvec2 pixelOffset;\npixelOffset.x = floor(compressed * SHIFT_RIGHT7);\ncompressed -= pixelOffset.x * SHIFT_LEFT7;\npixelOffset.x -= UPPER_BOUND;\nvec2 origin;\norigin.x = floor(compressed * SHIFT_RIGHT5);\ncompressed -= origin.x * SHIFT_LEFT5;\norigin.y = floor(compressed * SHIFT_RIGHT3);\ncompressed -= origin.y * SHIFT_LEFT3;\norigin -= vec2(1.0);\nfloat show = floor(compressed * SHIFT_RIGHT2);\ncompressed -= show * SHIFT_LEFT2;\n#ifdef INSTANCED\nvec2 textureCoordinatesBottomLeft = czm_decompressTextureCoordinates(compressedAttribute0.w);\nvec2 textureCoordinatesRange = czm_decompressTextureCoordinates(eyeOffset.w);\nvec2 textureCoordinates = textureCoordinatesBottomLeft + direction * textureCoordinatesRange;\n#else\nvec2 direction;\ndirection.x = floor(compressed * SHIFT_RIGHT1);\ndirection.y = compressed - direction.x * SHIFT_LEFT1;\nvec2 textureCoordinates = czm_decompressTextureCoordinates(compressedAttribute0.w);\n#endif\nfloat temp = compressedAttribute0.y * SHIFT_RIGHT8;\npixelOffset.y = -(floor(temp) - UPPER_BOUND);\nvec2 translate;\ntranslate.y = (temp - floor(temp)) * SHIFT_LEFT16;\ntemp = compressedAttribute0.z * SHIFT_RIGHT8;\ntranslate.x = floor(temp) - UPPER_BOUND;\ntranslate.y += (temp - floor(temp)) * SHIFT_LEFT8;\ntranslate.y -= UPPER_BOUND;\ntemp = compressedAttribute1.x * SHIFT_RIGHT8;\nvec2 imageSize = vec2(floor(temp), compressedAttribute2.w);\n#ifdef EYE_DISTANCE_TRANSLUCENCY\nvec4 translucencyByDistance;\ntranslucencyByDistance.x = compressedAttribute1.z;\ntranslucencyByDistance.z = compressedAttribute1.w;\ntranslucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\ntemp = compressedAttribute1.y * SHIFT_RIGHT8;\ntranslucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n#endif\n#ifdef ALIGNED_AXIS\nvec3 alignedAxis = czm_octDecode(floor(compressedAttribute1.y * SHIFT_RIGHT8));\ntemp = compressedAttribute2.z * SHIFT_RIGHT5;\nbool validAlignedAxis = (temp - floor(temp)) * SHIFT_LEFT1 > 0.0;\n#else\nvec3 alignedAxis = vec3(0.0);\nbool validAlignedAxis = false;\n#endif\n#ifdef RENDER_FOR_PICK\ntemp = compressedAttribute2.y;\n#else\ntemp = compressedAttribute2.x;\n#endif\nvec4 color;\ntemp = temp * SHIFT_RIGHT8;\ncolor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\ncolor.g = (temp - floor(temp)) * SHIFT_LEFT8;\ncolor.r = floor(temp);\ntemp = compressedAttribute2.z * SHIFT_RIGHT8;\nbool sizeInMeters = floor((temp - floor(temp)) * SHIFT_LEFT7) > 0.0;\ntemp = floor(temp) * SHIFT_RIGHT8;\n#ifdef RENDER_FOR_PICK\ncolor.a = (temp - floor(temp)) * SHIFT_LEFT8;\nvec4 pickColor = color / 255.0;\n#else\ncolor.a = floor(temp);\ncolor /= 255.0;\n#endif\nvec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\nvec4 positionEC = czm_modelViewRelativeToEye * p;\npositionEC = czm_eyeOffset(positionEC, eyeOffset.xyz);\npositionEC.xyz *= show;\n#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(EYE_DISTANCE_PIXEL_OFFSET) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\nfloat lengthSq;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nlengthSq = czm_eyeHeight2D.y;\n}\nelse\n{\nlengthSq = dot(positionEC.xyz, positionEC.xyz);\n}\n#endif\n#ifdef EYE_DISTANCE_SCALING\nfloat distanceScale = czm_nearFarScalar(scaleByDistance, lengthSq);\nscale *= distanceScale;\ntranslate *= distanceScale;\nif (scale == 0.0)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\nfloat translucency = 1.0;\n#ifdef EYE_DISTANCE_TRANSLUCENCY\ntranslucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\nif (translucency == 0.0)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\n#ifdef EYE_DISTANCE_PIXEL_OFFSET\nfloat pixelOffsetScale = czm_nearFarScalar(pixelOffsetScaleByDistance, lengthSq);\npixelOffset *= pixelOffsetScale;\n#endif\n#ifdef DISTANCE_DISPLAY_CONDITION\nfloat nearSq = distanceDisplayConditionAndDisableDepth.x;\nfloat farSq = distanceDisplayConditionAndDisableDepth.y;\nif (lengthSq < nearSq || lengthSq > farSq)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\nvec4 positionWC = computePositionWindowCoordinates(positionEC, imageSize, scale, direction, origin, translate, pixelOffset, alignedAxis, validAlignedAxis, rotation, sizeInMeters);\ngl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\nv_textureCoordinates = textureCoordinates;\n#ifdef DISABLE_DEPTH_DISTANCE\nfloat disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\nif (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n{\ndisableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n}\nif (disableDepthTestDistance != 0.0)\n{\nfloat zclip = gl_Position.z / gl_Position.w;\nbool clipped = (zclip < -1.0 || zclip > 1.0);\nif (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n{\ngl_Position.z = -gl_Position.w;\n}\n}\n#endif\n#ifdef RENDER_FOR_PICK\nv_pickColor = pickColor;\n#else\nv_color = color;\nv_color.a *= translucency;\n#endif\n}\n"}),define("Scene/BlendOption",["../Core/freezeObject"],function(e){"use strict";return e({OPAQUE:0,TRANSLUCENT:1,OPAQUE_AND_TRANSLUCENT:2})}),define("Renderer/Framebuffer",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/PixelFormat","./ContextLimits"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r){var i=e._gl;i.framebufferTexture2D(i.FRAMEBUFFER,t,r._target,r._texture,0)}function u(e,t,r){var i=e._gl;i.framebufferRenderbuffer(i.FRAMEBUFFER,t,i.RENDERBUFFER,r._getRenderbuffer())}function c(e){e=t(e,t.EMPTY_OBJECT);var i=e.context._gl;s.maximumColorAttachments;this._gl=i,this._framebuffer=i.createFramebuffer(),this._colorTextures=[],this._colorRenderbuffers=[],this._activeColorAttachments=[],this._depthTexture=void 0,this._depthRenderbuffer=void 0,this._stencilRenderbuffer=void 0,this._depthStencilTexture=void 0,this._depthStencilRenderbuffer=void 0,this.destroyAttachments=t(e.destroyAttachments,!0);r(e.depthTexture)||r(e.depthRenderbuffer),r(e.depthStencilTexture)||r(e.depthStencilRenderbuffer);this._bind();var n,o,a,c,d;if(r(e.colorTextures)){var h=e.colorTextures;for(c=this._colorTextures.length=this._activeColorAttachments.length=h.length,a=0;a0){for(var s=e._texture.width,l=e._texture.height,u=2*(s+r.width+a),c=2*(l+r.height+a),p=s/u,m=l/c,g=new f(new t(s+a,a),new t(u,l)),_=new f(new t,new t(u,l),e._root,g),v=new f(new t(a,l+a),new t(u,c)),y=new f(new t,new t(u,c),_,v),C=0;Cl){r.childNode1=new f(new t(r.bottomLeft.x,r.bottomLeft.y),new t(r.bottomLeft.x+i.width,r.topRight.y));var u=r.bottomLeft.x+i.width+e._borderWidthInPixels;u0&&(e._shaderDisableDepthDistance=!0,d===Number.POSITIVE_INFINITY&&(d=-1)),e._instanced?(o=n._index,a(o,l,u,d)):(o=4*n._index,a(o+0,l,u,d),a(o+1,l,u,d),a(o+2,l,u,d),a(o+3,l,u,d))}function Q(e,t,r,i,n){z(e,t,r,i,n),G(e,t,r,i,n),H(e,t,r,i,n),W(e,t,r,i,n),j(e,t,r,i,n),q(e,t,r,i,n),Y(e,t,r,i,n),X(e,t,r,i,n)}function Z(e,r,i,n,o,a){var l;n.mode===O.SCENE3D?(l=e._baseVolume,e._boundingVolumeDirty=!0):l=e._baseVolume2D;for(var u=[],c=0;c0){this._vaf=V(n,i,this._buffersUsage,this._instanced),g=this._vaf.writers;for(var D=0;D0){var R=Ne;R.length=0,(d[te]||d[ue]||d[ae])&&R.push(z),(d[se]||d[re]||d[ne]||d[oe]||d[ee])&&(R.push(G),this._instanced&&R.push(j)),(d[se]||d[ce]||d[he])&&(R.push(H),R.push(W)),(d[se]||d[le])&&R.push(W),d[ie]&&R.push(j),d[de]&&R.push(q),d[pe]&&R.push(Y),(d[fe]||d[me])&&R.push(X);var N=R.length;if(g=this._vaf.writers,c/i>.1){for(var L=0;L1.5*i&&(u.length=i),s(this._vaf)&&s(this._vaf.va)){this._boundingVolumeDirty&&(this._boundingVolumeDirty=!1,t.transform(this._baseVolume,this.modelMatrix,this._baseVolumeWC));var we,Te=f.IDENTITY;e.mode===O.SCENE3D?(Te=this.modelMatrix,we=t.clone(this._baseVolumeWC,this._boundingVolume)):we=t.clone(this._baseVolume2D,this._boundingVolume),J(this,e,we);var Ae=this._blendOption!==this.blendOption;if(this._blendOption=this.blendOption,Ae){ -this._blendOption===P.OPAQUE||this._blendOption===P.OPAQUE_AND_TRANSLUCENT?this._rsOpaque=C.fromCache({depthTest:{enabled:!0,func:m.LESS},depthMask:!0}):this._rsOpaque=void 0;var Ee=this._blendOption===P.TRANSLUCENT;this._blendOption===P.TRANSLUCENT||this._blendOption===P.OPAQUE_AND_TRANSLUCENT?this._rsTranslucent=C.fromCache({depthTest:{enabled:!0,func:Ee?m.LEQUAL:m.LESS},depthMask:Ee,blending:x.ALPHA_BLEND}):this._rsTranslucent=void 0}this._shaderDisableDepthDistance=this._shaderDisableDepthDistance||0!==e.minimumDisableDepthTestDistance;var xe,Pe;(Ae||this._shaderRotation!==this._compiledShaderRotation||this._shaderAlignedAxis!==this._compiledShaderAlignedAxis||this._shaderScaleByDistance!==this._compiledShaderScaleByDistance||this._shaderTranslucencyByDistance!==this._compiledShaderTranslucencyByDistance||this._shaderPixelOffsetScaleByDistance!==this._compiledShaderPixelOffsetScaleByDistance||this._shaderDistanceDisplayCondition!==this._compiledShaderDistanceDisplayCondition||this._shaderDisableDepthDistance!==this._compiledShaderDisableDepthDistance)&&(xe=new S({sources:[A]}),this._instanced&&xe.defines.push("INSTANCED"),this._shaderRotation&&xe.defines.push("ROTATION"),this._shaderAlignedAxis&&xe.defines.push("ALIGNED_AXIS"),this._shaderScaleByDistance&&xe.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&xe.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderPixelOffsetScaleByDistance&&xe.defines.push("EYE_DISTANCE_PIXEL_OFFSET"),this._shaderDistanceDisplayCondition&&xe.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&xe.defines.push("DISABLE_DEPTH_DISTANCE"),this._blendOption===P.OPAQUE_AND_TRANSLUCENT&&(Pe=new S({defines:["OPAQUE"],sources:[T]}),this._sp=b.replaceCache({context:n,shaderProgram:this._sp,vertexShaderSource:xe,fragmentShaderSource:Pe,attributeLocations:$}),Pe=new S({defines:["TRANSLUCENT"],sources:[T]}),this._spTranslucent=b.replaceCache({context:n,shaderProgram:this._spTranslucent,vertexShaderSource:xe,fragmentShaderSource:Pe,attributeLocations:$})),this._blendOption===P.OPAQUE&&(Pe=new S({sources:[T]}),this._sp=b.replaceCache({context:n,shaderProgram:this._sp,vertexShaderSource:xe,fragmentShaderSource:Pe,attributeLocations:$})),this._blendOption===P.TRANSLUCENT&&(Pe=new S({sources:[T]}),this._spTranslucent=b.replaceCache({context:n,shaderProgram:this._spTranslucent,vertexShaderSource:xe,fragmentShaderSource:Pe,attributeLocations:$})),this._compiledShaderRotation=this._shaderRotation,this._compiledShaderAlignedAxis=this._shaderAlignedAxis,this._compiledShaderScaleByDistance=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistance=this._shaderTranslucencyByDistance,this._compiledShaderPixelOffsetScaleByDistance=this._shaderPixelOffsetScaleByDistance,this._compiledShaderDistanceDisplayCondition=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistance=this._shaderDisableDepthDistance),s(this._spPick)&&this._shaderRotation===this._compiledShaderRotationPick&&this._shaderAlignedAxis===this._compiledShaderAlignedAxisPick&&this._shaderScaleByDistance===this._compiledShaderScaleByDistancePick&&this._shaderTranslucencyByDistance===this._compiledShaderTranslucencyByDistancePick&&this._shaderPixelOffsetScaleByDistance===this._compiledShaderPixelOffsetScaleByDistancePick&&this._shaderDistanceDisplayCondition===this._compiledShaderDistanceDisplayConditionPick&&this._shaderDisableDepthDistance===this._compiledShaderDisableDepthDistancePick||(xe=new S({defines:["RENDER_FOR_PICK"],sources:[A]}),this._instanced&&xe.defines.push("INSTANCED"),this._shaderRotation&&xe.defines.push("ROTATION"),this._shaderAlignedAxis&&xe.defines.push("ALIGNED_AXIS"),this._shaderScaleByDistance&&xe.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&xe.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderPixelOffsetScaleByDistance&&xe.defines.push("EYE_DISTANCE_PIXEL_OFFSET"),this._shaderDistanceDisplayCondition&&xe.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&xe.defines.push("DISABLE_DEPTH_DISTANCE"),Pe=new S({defines:["RENDER_FOR_PICK"],sources:[T]}),this._spPick=b.replaceCache({context:n,shaderProgram:this._spPick,vertexShaderSource:xe,fragmentShaderSource:Pe,attributeLocations:$}),this._compiledShaderRotationPick=this._shaderRotation,this._compiledShaderAlignedAxisPick=this._shaderAlignedAxis,this._compiledShaderScaleByDistancePick=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistancePick=this._shaderTranslucencyByDistance,this._compiledShaderPixelOffsetScaleByDistancePick=this._shaderPixelOffsetScaleByDistance,this._compiledShaderDistanceDisplayConditionPick=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistancePick=this._shaderDisableDepthDistance);var De,Ie,Oe,Me,Re=e.commandList;if(_.render){var Le=this._colorCommands,ke=this._blendOption===P.OPAQUE,Fe=this._blendOption===P.OPAQUE_AND_TRANSLUCENT;De=this._vaf.va,Ie=De.length,Le.length=Ie;var Be=Fe?2*Ie:Ie;for(Me=0;Me]/,n=[],o="",a=T.LTR,s="",l=e.length,u=0;u";case">":return"<"}}function w(e){for(var t=e.split("\n"),r="",i=0;iu+1?a[u+1].Type===T.RTL?(l=d+l,s=0):(l=b(l,s,c.Word),s+=c.Word.length):l=b(l,0,d)):c.Type===T.RTL?l=b(l,s,C(c.Word)):c.Type===T.LTR?(l+=c.Word,s=l.length):c.Type!==T.WEAK&&c.Type!==T.BRACKETS||(u>0&&a[u-1].Type===T.RTL?a.length>u+1?a[u+1].Type===T.RTL?l=b(l,s,d):(l+=c.Word,s=l.length):l+=c.Word:(l+=c.Word,s=l.length))}r+=l,i0,h=t._backgroundBillboard,p=e._backgroundBillboardCollection;c?(i(h)||(h=p.add({collection:e,image:P,imageSubRegion:I}),t._backgroundBillboard=h),h.color=t._backgroundColor,h.show=t._show,h.position=t._position,h.eyeOffset=t._eyeOffset,h.pixelOffset=t._pixelOffset,h.horizontalOrigin=d.LEFT,h.verticalOrigin=t._verticalOrigin,h.heightReference=t._heightReference,h.scale=t._scale,h.pickPrimitive=t,h.id=t._id,h.translucencyByDistance=t._translucencyByDistance,h.pixelOffsetScaleByDistance=t._pixelOffsetScaleByDistance,h.scaleByDistance=t._scaleByDistance,h.distanceDisplayCondition=t._distanceDisplayCondition,h.disableDepthTestDistance=t._disableDepthTestDistance):i(h)&&(p.remove(h),t._backgroundBillboard=h=void 0);var f=e._glyphTextureCache;for(o=0;o0&&O.height>0&&b(e._textureAtlas,x,O,D)}if(r=l[o],i(r)?-1===D.index?C(e,r):i(r.textureInfo)&&(r.textureInfo=void 0):(r=new g,l[o]=r),r.textureInfo=D,r.dimensions=D.dimensions,-1!==D.index){var M=r.billboard,R=e._spareBillboards;i(M)||(M=R.length>0?R.pop():e._billboardCollection.add({collection:e}),r.billboard=M),M.show=t._show,M.position=t._position,M.eyeOffset=t._eyeOffset,M.pixelOffset=t._pixelOffset,M.horizontalOrigin=d.LEFT,M.verticalOrigin=t._verticalOrigin,M.heightReference=t._heightReference,M.scale=t._scale,M.pickPrimitive=t,M.id=t._id,M.image=x,M.translucencyByDistance=t._translucencyByDistance,M.pixelOffsetScaleByDistance=t._pixelOffsetScaleByDistance,M.scaleByDistance=t._scaleByDistance,M.distanceDisplayCondition=t._distanceDisplayCondition,M.disableDepthTestDistance=t._disableDepthTestDistance}}t._repositionAllGlyphs=!0}function w(e,t,r){return t===d.CENTER?-e/2:t===d.RIGHT?-(e+r.x):r.x}function T(e,r){var n,o,a=e._glyphs,s=e._renderedText,l=0,u=0,c=[],h=Number.NEGATIVE_INFINITY,p=0,f=1,g=0,_=a.length,v=e._backgroundBillboard,y=R;for(t.clone(i(v)?e._backgroundPadding:t.ZERO,y),g=0;g<_;++g)"\n"===s.charAt(g)?(c.push(l),++f,l=0):(n=a[g],o=n.dimensions,p=Math.max(p,o.height-o.descent),h=Math.max(h,o.descent),l+=o.width-o.bounds.minx,g<_-1&&(l+=a[g+1].dimensions.bounds.minx),u=Math.max(u,l));c.push(l);var C=p+h,b=e._scale,S=e._horizontalOrigin,T=e._verticalOrigin,A=0,E=c[A],P=w(E,S,y),D=x*C,I=D*(f-1);M.x=P*b*r,M.y=0;var O=0;for(g=0;g<_;++g)if("\n"===s.charAt(g))++A,O+=D,E=c[A],P=w(E,S,y),M.x=P*b*r;else if(n=a[g],o=n.dimensions,T===m.TOP?M.y=o.height-p-y.y:T===m.CENTER?M.y=(I+o.height-p)/2:T===m.BASELINE?M.y=I:M.y=I+h+y.y,M.y=(M.y-o.descent-O)*b*r,i(n.billboard)&&n.billboard._setTranslate(M),g<_-1){var N=a[g+1];M.x+=(o.width-o.bounds.minx+N.dimensions.bounds.minx)*b*r}i(v)&&s.split("\n").join("").length>0&&(P=S===d.CENTER?-u/2-y.x:S===d.RIGHT?-(u+2*y.x):0,M.x=P*b*r,T===m.TOP?M.y=C-p-h:T===m.CENTER?M.y=(C-p)/2-h:T===m.BASELINE?M.y=-y.y-h:M.y=0,M.y=M.y*b*r,v.width=u+2*y.x,v.height=C+I+2*y.y,v._setTranslate(M))}function A(e,t){for(var r=t._glyphs,n=0,a=r.length;n0?c.TRANSLUCENT:this.blendOption;t.blendOption=g,r.blendOption=g,this._labelsToUpdate.length=0,r.update(e),t.update(e)},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){return this.removeAll(),this._billboardCollection=this._billboardCollection.destroy(),this._textureAtlas=this._textureAtlas&&this._textureAtlas.destroy(),this._backgroundBillboardCollection=this._backgroundBillboardCollection.destroy(),this._backgroundTextureAtlas=this._backgroundTextureAtlas&&this._backgroundTextureAtlas.destroy(),o(this)},E}),define("Scene/PointPrimitive",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Matrix4","../Core/NearFarScalar","./SceneMode","./SceneTransforms"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,t){e=o(e,o.EMPTY_OBJECT);var i=e.translucencyByDistance,s=e.scaleByDistance,l=e.distanceDisplayCondition;a(i)&&(i=d.clone(i)),a(s)&&(s=d.clone(s)),a(l)&&(l=u.clone(l)),this._show=o(e.show,!0),this._position=r.clone(o(e.position,r.ZERO)),this._actualPosition=r.clone(this._position),this._color=n.clone(o(e.color,n.WHITE)),this._outlineColor=n.clone(o(e.outlineColor,n.TRANSPARENT)),this._outlineWidth=o(e.outlineWidth,0),this._pixelSize=o(e.pixelSize,10),this._scaleByDistance=s,this._translucencyByDistance=i,this._distanceDisplayCondition=l,this._disableDepthTestDistance=o(e.disableDepthTestDistance,0),this._id=e.id,this._collection=o(e.collection,t),this._clusterShow=!0,this._pickId=void 0,this._pointPrimitiveCollection=t,this._dirty=!1,this._index=-1}function m(e,t){var r=e._pointPrimitiveCollection;a(r)&&(r._updatePointPrimitive(e,t),e._dirty=!0)}var g=f.SHOW_INDEX=0,_=f.POSITION_INDEX=1,v=f.COLOR_INDEX=2,y=f.OUTLINE_COLOR_INDEX=3,C=f.OUTLINE_WIDTH_INDEX=4,b=f.PIXEL_SIZE_INDEX=5,S=f.SCALE_BY_DISTANCE_INDEX=6,w=f.TRANSLUCENCY_BY_DISTANCE_INDEX=7,T=f.DISTANCE_DISPLAY_CONDITION_INDEX=8,A=f.DISABLE_DEPTH_DISTANCE_INDEX=9;f.NUMBER_OF_PROPERTIES=10,s(f.prototype,{show:{get:function(){return this._show},set:function(e){this._show!==e&&(this._show=e,m(this,g))}},position:{get:function(){return this._position},set:function(e){var t=this._position;r.equals(t,e)||(r.clone(e,t),r.clone(e,this._actualPosition),m(this,_))}},scaleByDistance:{get:function(){return this._scaleByDistance},set:function(e){var t=this._scaleByDistance;d.equals(t,e)||(this._scaleByDistance=d.clone(e,t),m(this,S))}},translucencyByDistance:{get:function(){return this._translucencyByDistance},set:function(e){var t=this._translucencyByDistance;d.equals(t,e)||(this._translucencyByDistance=d.clone(e,t),m(this,w))}},pixelSize:{get:function(){return this._pixelSize},set:function(e){this._pixelSize!==e&&(this._pixelSize=e,m(this,b))}},color:{get:function(){return this._color},set:function(e){var t=this._color;n.equals(t,e)||(n.clone(e,t),m(this,v))}},outlineColor:{get:function(){return this._outlineColor},set:function(e){var t=this._outlineColor;n.equals(t,e)||(n.clone(e,t),m(this,y))}},outlineWidth:{get:function(){return this._outlineWidth},set:function(e){this._outlineWidth!==e&&(this._outlineWidth=e,m(this,C))}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){u.equals(this._distanceDisplayCondition,e)||(this._distanceDisplayCondition=u.clone(e,this._distanceDisplayCondition),m(this,T))}},disableDepthTestDistance:{get:function(){return this._disableDepthTestDistance},set:function(e){this._disableDepthTestDistance!==e&&(this._disableDepthTestDistance=e,m(this,A))}},id:{get:function(){return this._id},set:function(e){this._id=e,a(this._pickId)&&(this._pickId.object.id=e)}},clusterShow:{get:function(){return this._clusterShow},set:function(e){this._clusterShow!==e&&(this._clusterShow=e,m(this,g))}}}),f.prototype.getPickId=function(e){return a(this._pickId)||(this._pickId=e.createPickId({primitive:this,collection:this._collection,id:this._id})),this._pickId},f.prototype._getActualPosition=function(){return this._actualPosition},f.prototype._setActualPosition=function(e){r.clone(e,this._actualPosition),m(this,_)};var E=new i;f._computeActualPosition=function(e,t,r){return t.mode===h.SCENE3D?e:(c.multiplyByPoint(r,e,E),p.computeActualWgs84Position(t,E))};var x=new i;return f._computeScreenSpacePosition=function(e,t,r,n){var o=c.multiplyByVector(e,i.fromElements(t.x,t.y,t.z,1,x),x);return p.wgs84ToWindowCoordinates(r,o,n)},f.prototype.computeScreenSpacePosition=function(e,r){var i=this._pointPrimitiveCollection;a(r)||(r=new t);var n=i.modelMatrix,o=f._computeScreenSpacePosition(n,this._actualPosition,e,r);if(a(o))return o.y=e.canvas.clientHeight-o.y,o},f.getScreenSpaceBoundingBox=function(t,r,i){var n=t.pixelSize,o=.5*n,s=r.x-o,l=r.y-o,u=n,c=n;return a(i)||(i=new e),i.x=s,i.y=l,i.width=u,i.height=c,i},f.prototype.equals=function(e){return this===e||a(e)&&this._id===e._id&&r.equals(this._position,e._position)&&n.equals(this._color,e._color)&&this._pixelSize===e._pixelSize&&this._outlineWidth===e._outlineWidth&&this._show===e._show&&n.equals(this._outlineColor,e._outlineColor)&&d.equals(this._scaleByDistance,e._scaleByDistance)&&d.equals(this._translucencyByDistance,e._translucencyByDistance)&&u.equals(this._distanceDisplayCondition,e._distanceDisplayCondition)&&this._disableDepthTestDistance===e._disableDepthTestDistance},f.prototype._destroy=function(){this._pickId=this._pickId&&this._pickId.destroy(),this._pointPrimitiveCollection=void 0},f}),define("Shaders/PointPrimitiveCollectionFS",[],function(){"use strict" -;return"varying vec4 v_color;\nvarying vec4 v_outlineColor;\nvarying float v_innerPercent;\nvarying float v_pixelDistance;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#endif\nvoid main()\n{\nfloat distanceToCenter = length(gl_PointCoord - vec2(0.5));\nfloat maxDistance = max(0.0, 0.5 - v_pixelDistance);\nfloat wholeAlpha = 1.0 - smoothstep(maxDistance, 0.5, distanceToCenter);\nfloat innerAlpha = 1.0 - smoothstep(maxDistance * v_innerPercent, 0.5 * v_innerPercent, distanceToCenter);\nvec4 color = mix(v_outlineColor, v_color, innerAlpha);\ncolor.a *= wholeAlpha;\n#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\nif (color.a < 0.005)\n{\ndiscard;\n}\n#else\n#ifdef OPAQUE\nif (color.a < 0.995)\n{\ndiscard;\n}\n#else\nif (color.a >= 0.995)\n{\ndiscard;\n}\n#endif\n#endif\n#ifdef RENDER_FOR_PICK\ngl_FragColor = v_pickColor;\n#else\ngl_FragColor = color;\n#endif\n}\n"}),define("Shaders/PointPrimitiveCollectionVS",[],function(){"use strict";return"uniform float u_maxTotalPointSize;\nattribute vec4 positionHighAndSize;\nattribute vec4 positionLowAndOutline;\nattribute vec4 compressedAttribute0;\nattribute vec4 compressedAttribute1;\nattribute vec4 scaleByDistance;\nattribute vec3 distanceDisplayConditionAndDisableDepth;\nvarying vec4 v_color;\nvarying vec4 v_outlineColor;\nvarying float v_innerPercent;\nvarying float v_pixelDistance;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#endif\nconst float SHIFT_LEFT8 = 256.0;\nconst float SHIFT_RIGHT8 = 1.0 / 256.0;\nvoid main()\n{\nvec3 positionHigh = positionHighAndSize.xyz;\nvec3 positionLow = positionLowAndOutline.xyz;\nfloat outlineWidthBothSides = 2.0 * positionLowAndOutline.w;\nfloat totalSize = positionHighAndSize.w + outlineWidthBothSides;\nfloat outlinePercent = outlineWidthBothSides / totalSize;\ntotalSize *= czm_resolutionScale;\ntotalSize += 3.0;\nfloat temp = compressedAttribute1.x * SHIFT_RIGHT8;\nfloat show = floor(temp);\n#ifdef EYE_DISTANCE_TRANSLUCENCY\nvec4 translucencyByDistance;\ntranslucencyByDistance.x = compressedAttribute1.z;\ntranslucencyByDistance.z = compressedAttribute1.w;\ntranslucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\ntemp = compressedAttribute1.y * SHIFT_RIGHT8;\ntranslucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n#endif\nvec4 color;\nvec4 outlineColor;\n#ifdef RENDER_FOR_PICK\ncolor = vec4(0.0);\noutlineColor = vec4(0.0);\nvec4 pickColor;\ntemp = compressedAttribute0.z * SHIFT_RIGHT8;\npickColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\npickColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\npickColor.r = floor(temp);\n#else\ntemp = compressedAttribute0.x * SHIFT_RIGHT8;\ncolor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\ncolor.g = (temp - floor(temp)) * SHIFT_LEFT8;\ncolor.r = floor(temp);\ntemp = compressedAttribute0.y * SHIFT_RIGHT8;\noutlineColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\noutlineColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\noutlineColor.r = floor(temp);\n#endif\ntemp = compressedAttribute0.w * SHIFT_RIGHT8;\n#ifdef RENDER_FOR_PICK\npickColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\npickColor = pickColor / 255.0;\n#endif\ntemp = floor(temp) * SHIFT_RIGHT8;\noutlineColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\noutlineColor /= 255.0;\ncolor.a = floor(temp);\ncolor /= 255.0;\nvec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\nvec4 positionEC = czm_modelViewRelativeToEye * p;\npositionEC.xyz *= show;\n#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\nfloat lengthSq;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nlengthSq = czm_eyeHeight2D.y;\n}\nelse\n{\nlengthSq = dot(positionEC.xyz, positionEC.xyz);\n}\n#endif\n#ifdef EYE_DISTANCE_SCALING\ntotalSize *= czm_nearFarScalar(scaleByDistance, lengthSq);\n#endif\ntotalSize = min(totalSize, u_maxTotalPointSize);\nif (totalSize < 1.0)\n{\npositionEC.xyz = vec3(0.0);\ntotalSize = 1.0;\n}\nfloat translucency = 1.0;\n#ifdef EYE_DISTANCE_TRANSLUCENCY\ntranslucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\nif (translucency < 0.004)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\n#ifdef DISTANCE_DISPLAY_CONDITION\nfloat nearSq = distanceDisplayConditionAndDisableDepth.x;\nfloat farSq = distanceDisplayConditionAndDisableDepth.y;\nif (lengthSq < nearSq || lengthSq > farSq) {\npositionEC.xyz = vec3(0.0);\n}\n#endif\nvec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\ngl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\n#ifdef DISABLE_DEPTH_DISTANCE\nfloat disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\nif (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n{\ndisableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n}\nif (disableDepthTestDistance != 0.0)\n{\nfloat zclip = gl_Position.z / gl_Position.w;\nbool clipped = (zclip < -1.0 || zclip > 1.0);\nif (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n{\ngl_Position.z = -gl_Position.w;\n}\n}\n#endif\nv_color = color;\nv_color.a *= translucency;\nv_outlineColor = outlineColor;\nv_outlineColor.a *= translucency;\nv_innerPercent = 1.0 - outlinePercent;\nv_pixelDistance = 2.0 / totalSize;\ngl_PointSize = totalSize;\n#ifdef RENDER_FOR_PICK\nv_pickColor = pickColor;\n#endif\n}\n"}),define("Scene/PointPrimitiveCollection",["../Core/BoundingSphere","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EncodedCartesian3","../Core/Math","../Core/Matrix4","../Core/PrimitiveType","../Core/WebGLConstants","../Renderer/BufferUsage","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArrayFacade","../Shaders/PointPrimitiveCollectionFS","../Shaders/PointPrimitiveCollectionVS","./BlendingState","./BlendOption","./PointPrimitive","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E){"use strict";function x(t){t=i(t,i.EMPTY_OBJECT),this._sp=void 0,this._spTranslucent=void 0,this._spPick=void 0,this._rsOpaque=void 0,this._rsTranslucent=void 0,this._vaf=void 0,this._pointPrimitives=[],this._pointPrimitivesToUpdate=[],this._pointPrimitivesToUpdateIndex=0,this._pointPrimitivesRemoved=!1,this._createVertexArray=!1,this._shaderScaleByDistance=!1,this._compiledShaderScaleByDistance=!1,this._compiledShaderScaleByDistancePick=!1,this._shaderTranslucencyByDistance=!1,this._compiledShaderTranslucencyByDistance=!1,this._compiledShaderTranslucencyByDistancePick=!1,this._shaderDistanceDisplayCondition=!1,this._compiledShaderDistanceDisplayCondition=!1,this._compiledShaderDistanceDisplayConditionPick=!1,this._shaderDisableDepthDistance=!1,this._compiledShaderDisableDepthDistance=!1,this._compiledShaderDisableDepthDistancePick=!1,this._propertiesChanged=new Uint32Array(Z),this._maxPixelSize=1,this._baseVolume=new e,this._baseVolumeWC=new e,this._baseVolume2D=new e,this._boundingVolume=new e,this._boundingVolumeDirty=!1,this._colorCommands=[],this._pickCommands=[],this.modelMatrix=c.clone(i(t.modelMatrix,c.IDENTITY)),this._modelMatrix=c.clone(c.IDENTITY),this.debugShowBoundingVolume=i(t.debugShowBoundingVolume,!1),this.blendOption=i(t.blendOption,T.OPAQUE_AND_TRANSLUCENT),this._blendOption=void 0,this._mode=E.SCENE3D,this._maxTotalPointSize=1,this._buffersUsage=[p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW];var r=this;this._uniforms={u_maxTotalPointSize:function(){return r._maxTotalPointSize}}}function P(e){for(var t=e.length,r=0;r0&&(e._shaderDisableDepthDistance=!0,c===Number.POSITIVE_INFINITY&&(c=-1)),a(o,s,l,c)}function k(e,t,r,i){O(e,t,r,i),M(e,t,r,i),R(e,t,r,i),N(e,t,r,i),L(e,t,r,i)}function F(t,r,i,o,a,s){var l;o.mode===E.SCENE3D?(l=t._baseVolume,t._boundingVolumeDirty=!0):l=t._baseVolume2D;for(var u=[],c=0;c0){this._vaf=I(p,o,this._buffersUsage),r=this._vaf.writers;for(var P=0;P0){var J=te;J.length=0,(l[z]||l[W]||l[j])&&J.push(O),(l[G]||l[H])&&J.push(M),(l[V]||l[Y])&&J.push(R),l[q]&&J.push(N),(l[X]||l[Q])&&J.push(L);var $=J.length;if(r=this._vaf.writers,s/o>.1){for(var ee=0;ee1.5*o&&(a.length=o),n(this._vaf)&&n(this._vaf.va)){this._boundingVolumeDirty&&(this._boundingVolumeDirty=!1,e.transform(this._baseVolume,this.modelMatrix,this._baseVolumeWC));var se,le=c.IDENTITY;t.mode===E.SCENE3D?(le=this.modelMatrix,se=e.clone(this._baseVolumeWC,this._boundingVolume)):se=e.clone(this._baseVolume2D,this._boundingVolume),U(this,t,se);var ue=this._blendOption!==this.blendOption;this._blendOption=this.blendOption,ue&&(this._blendOption===T.OPAQUE||this._blendOption===T.OPAQUE_AND_TRANSLUCENT?this._rsOpaque=_.fromCache({depthTest:{enabled:!0,func:h.LEQUAL},depthMask:!0}):this._rsOpaque=void 0,this._blendOption===T.TRANSLUCENT||this._blendOption===T.OPAQUE_AND_TRANSLUCENT?this._rsTranslucent=_.fromCache({depthTest:{enabled:!0,func:h.LEQUAL},depthMask:!1,blending:w.ALPHA_BLEND}):this._rsTranslucent=void 0),this._shaderDisableDepthDistance=this._shaderDisableDepthDistance||0!==t.minimumDisableDepthTestDistance;var ce,de;(ue||this._shaderScaleByDistance&&!this._compiledShaderScaleByDistance||this._shaderTranslucencyByDistance&&!this._compiledShaderTranslucencyByDistance||this._shaderDistanceDisplayCondition&&!this._compiledShaderDistanceDisplayCondition||this._shaderDisableDepthDistance!==this._compiledShaderDisableDepthDistance)&&(ce=new y({sources:[S]}),this._shaderScaleByDistance&&ce.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&ce.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderDistanceDisplayCondition&&ce.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&ce.defines.push("DISABLE_DEPTH_DISTANCE"),this._blendOption===T.OPAQUE_AND_TRANSLUCENT&&(de=new y({defines:["OPAQUE"],sources:[b]}),this._sp=v.replaceCache({context:p,shaderProgram:this._sp,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K}),de=new y({defines:["TRANSLUCENT"],sources:[b]}),this._spTranslucent=v.replaceCache({context:p,shaderProgram:this._spTranslucent,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K})),this._blendOption===T.OPAQUE&&(de=new y({sources:[b]}),this._sp=v.replaceCache({context:p,shaderProgram:this._sp,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K})),this._blendOption===T.TRANSLUCENT&&(de=new y({sources:[b]}),this._spTranslucent=v.replaceCache({context:p,shaderProgram:this._spTranslucent,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K})),this._compiledShaderScaleByDistance=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistance=this._shaderTranslucencyByDistance,this._compiledShaderDistanceDisplayCondition=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistance=this._shaderDisableDepthDistance),(!n(this._spPick)||this._shaderScaleByDistance&&!this._compiledShaderScaleByDistancePick||this._shaderTranslucencyByDistance&&!this._compiledShaderTranslucencyByDistancePick||this._shaderDistanceDisplayCondition&&!this._compiledShaderDistanceDisplayConditionPick||this._shaderDisableDepthDistance!==this._compiledShaderDisableDepthDistancePick)&&(ce=new y({defines:["RENDER_FOR_PICK"],sources:[S]}),this._shaderScaleByDistance&&ce.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&ce.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderDistanceDisplayCondition&&ce.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&ce.defines.push("DISABLE_DEPTH_DISTANCE"),de=new y({defines:["RENDER_FOR_PICK"],sources:[b]}),this._spPick=v.replaceCache({context:p,shaderProgram:this._spPick,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K}),this._compiledShaderScaleByDistancePick=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistancePick=this._shaderTranslucencyByDistance,this._compiledShaderDistanceDisplayConditionPick=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistancePick=this._shaderDisableDepthDistance);var he,pe,fe,me,ge=t.commandList;if(C.render){var _e=this._colorCommands,ve=this._blendOption===T.OPAQUE,ye=this._blendOption===T.OPAQUE_AND_TRANSLUCENT;he=this._vaf.va,pe=he.length,_e.length=pe;var Ce=ye?2*pe:pe;for(me=0;me=r&&s<=n&&l>=i&&l<=o&&c.push(e[f]);else{var m=Math.floor((p+h)/2);s=t[2*m],l=t[2*m+1],s>=r&&s<=n&&l>=i&&l<=o&&c.push(e[m]);var g=(d+1)%2;(0===d?r<=s:i<=l)&&(u.push(p),u.push(m-1),u.push(g)),(0===d?n>=s:o>=l)&&(u.push(m+1),u.push(h),u.push(g))}}return c}function o(e,t,r,i,n,s){if(!(n-i<=r)){var l=Math.floor((i+n)/2);a(e,t,l,i,n,s%2),o(e,t,r,i,l-1,s+1),o(e,t,r,l+1,n,s+1)}}function a(e,t,r,i,n,o){for(;n>i;){if(n-i>600){var l=n-i+1,u=r-i+1,c=Math.log(l),d=.5*Math.exp(2*c/3),h=.5*Math.sqrt(c*d*(l-d)/l)*(u-l/2<0?-1:1);a(e,t,r,Math.max(i,Math.floor(r-u*d/l+h)),Math.min(n,Math.floor(r+(l-u)*d/l+h)),o)}var p=t[2*r+o],f=i,m=n;for(s(e,t,i,r),t[2*n+o]>p&&s(e,t,i,n);fp;)m--}t[2*i+o]===p?s(e,t,i,m):(m++,s(e,t,m,n)),m<=r&&(i=m+1),r<=m&&(n=m-1)}}function s(e,t,r,i){l(e,r,i),l(t,2*r,2*i),l(t,2*r+1,2*i+1)}function l(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}function u(e,t,r,i,n,o){for(var a=[0,e.length-1,0],s=[],l=n*n;a.length;){var u=a.pop(),d=a.pop(),h=a.pop();if(d-h<=o)for(var p=h;p<=d;p++)c(t[2*p],t[2*p+1],r,i)<=l&&s.push(e[p]);else{var f=Math.floor((h+d)/2),m=t[2*f],g=t[2*f+1];c(m,g,r,i)<=l&&s.push(e[f]);var _=(u+1)%2;(0===u?r-n<=m:i-n<=g)&&(a.push(h),a.push(f-1),a.push(_)),(0===u?r+n>=m:i+n>=g)&&(a.push(f+1),a.push(d),a.push(_))}}return s}function c(e,t,r,i){var n=e-r,o=t-i;return n*n+o*o}return t.prototype={range:function(e,t,r,i){return n(this.ids,this.coords,e,t,r,i,this.nodeSize)},within:function(e,t,r){return u(this.ids,this.coords,e,t,r,this.nodeSize)}},e}),define("DataSources/EntityCluster",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/EllipsoidalOccluder","../Core/Event","../Core/Matrix4","../Scene/Billboard","../Scene/BillboardCollection","../Scene/Label","../Scene/LabelCollection","../Scene/PointPrimitive","../Scene/PointPrimitiveCollection","../Scene/SceneMode","../ThirdParty/kdbush"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){e=i(e,i.EMPTY_OBJECT),this._enabled=i(e.enabled,!1),this._pixelRange=i(e.pixelRange,80),this._minimumClusterSize=i(e.minimumClusterSize,2),this._clusterBillboards=i(e.clusterBillboards,!0),this._clusterLabels=i(e.clusterLabels,!0),this._clusterPoints=i(e.clusterPoints,!0),this._labelCollection=void 0,this._billboardCollection=void 0,this._pointCollection=void 0,this._clusterBillboardCollection=void 0,this._clusterLabelCollection=void 0,this._clusterPointCollection=void 0,this._collectionIndicesByEntity={},this._unusedLabelIndices=[],this._unusedBillboardIndices=[],this._unusedPointIndices=[],this._previousClusters=[],this._previousHeight=void 0,this._enabledDirty=!1,this._clusterDirty=!1,this._cluster=void 0,this._removeEventListener=void 0,this._clusterEvent=new s}function v(e){return e.coord.x}function y(e){return e.coord.y}function C(e,t){e.x-=t,e.y-=t,e.width+=2*t,e.height+=2*t}function b(t,r,i,o,a){if(n(t._labelCollection)&&o._clusterLabels?a=d.getScreenSpaceBoundingBox(t,r,a):n(t._billboardCollection)&&o._clusterBillboards?a=u.getScreenSpaceBoundingBox(t,r,a):n(t._pointPrimitiveCollection)&&o._clusterPoints&&(a=p.getScreenSpaceBoundingBox(t,r,a)),C(a,i),o._clusterLabels&&!n(t._labelCollection)&&n(t.id)&&T(o,t.id)&&n(t.id._label)){var s=o._collectionIndicesByEntity[t.id],l=o._labelCollection.get(s),c=d.getScreenSpaceBoundingBox(l,r,O);C(c,i),a=e.union(a,c,a)}return a}function S(e,t){if(e.clusterShow=!0,!n(e._labelCollection)&&n(e.id)&&T(t,e.id)&&n(e.id._label)){var r=t._collectionIndicesByEntity[e.id];t._labelCollection.get(r).clusterShow=!0}}function w(e,t,r,i){var n={billboard:i._clusterBillboardCollection.add(),label:i._clusterLabelCollection.add(),point:i._clusterPointCollection.add()};n.billboard.show=!1,n.point.show=!1,n.label.show=!0,n.label.text=t.toLocaleString(),n.label.id=r,n.billboard.position=n.label.position=n.point.position=e,i._clusterEvent.raiseEvent(r,n)}function T(e,t){return n(e)&&n(e._collectionIndicesByEntity[t])&&n(e._collectionIndicesByEntity[t].labelIndex)}function A(e,t,r,i,o){if(n(e))for(var a=e.length,s=0;s=x)for(w(J.position,X,Y,i),D.push(J),V=0;V=x){var pe=r.multiplyByScalar(ce,1/X,ce);for(w(pe,X,Y,i),D.push({position:pe,width:ue.width,height:ue.height,minimumWidth:G.width,minimumHeight:G.height}),V=0;V0?(l=c.pop(),u=a.get(l)):(u=a.add(),l=a.length-1),s[i]=l,this._clusterDirty=!0,u}}function P(e,t){var r=e._collectionIndicesByEntity[t];n(r.billboardIndex)||n(r.labelIndex)||n(r.pointIndex)||delete e._collectionIndicesByEntity[t]}function D(e){if(n(e))for(var t=e.length,r=0;r0&&0===this._labelCollection.get(0)._glyphs.length&&(t=e.commandList,e.commandList=[],this._labelCollection.update(e),e.commandList=t),n(this._billboardCollection)&&this._billboardCollection.length>0&&!n(this._billboardCollection.get(0).width)&&(t=e.commandList,e.commandList=[],this._billboardCollection.update(e),e.commandList=t),this._enabledDirty&&(this._enabledDirty=!1,I(this),this._clusterDirty=!0),this._clusterDirty&&(this._clusterDirty=!1,this._cluster()),n(this._clusterLabelCollection)&&this._clusterLabelCollection.update(e),n(this._clusterBillboardCollection)&&this._clusterBillboardCollection.update(e),n(this._clusterPointCollection)&&this._clusterPointCollection.update(e),n(this._labelCollection)&&this._labelCollection.update(e),n(this._billboardCollection)&&this._billboardCollection.update(e),n(this._pointCollection)&&this._pointCollection.update(e)},_.prototype.destroy=function(){this._labelCollection=this._labelCollection&&this._labelCollection.destroy(),this._billboardCollection=this._billboardCollection&&this._billboardCollection.destroy(),this._pointCollection=this._pointCollection&&this._pointCollection.destroy(),this._clusterLabelCollection=this._clusterLabelCollection&&this._clusterLabelCollection.destroy(),this._clusterBillboardCollection=this._clusterBillboardCollection&&this._clusterBillboardCollection.destroy(),this._clusterPointCollection=this._clusterPointCollection&&this._clusterPointCollection.destroy(),n(this._removeEventListener)&&(this._removeEventListener(),this._removeEventListener=void 0), -this._labelCollection=void 0,this._billboardCollection=void 0,this._pointCollection=void 0,this._clusterBillboardCollection=void 0,this._clusterLabelCollection=void 0,this._clusterPointCollection=void 0,this._collectionIndicesByEntity=void 0,this._unusedLabelIndices=[],this._unusedBillboardIndices=[],this._unusedPointIndices=[],this._previousClusters=[],this._previousHeight=void 0,this._enabledDirty=!1,this._pixelRangeDirty=!1,this._minimumClusterSizeDirty=!1},_}),define("DataSources/CustomDataSource",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./DataSource","./EntityCluster","./EntityCollection"],function(e,t,r,i,n,o,a){"use strict";function s(e){this._name=e,this._clock=void 0,this._changed=new i,this._error=new i,this._isLoading=!1,this._loading=new i,this._entityCollection=new a(this),this._entityCluster=new o}return t(s.prototype,{name:{get:function(){return this._name},set:function(e){this._name!==e&&(this._name=e,this._changed.raiseEvent(this))}},clock:{get:function(){return this._clock},set:function(e){this._clock!==e&&(this._clock=e,this._changed.raiseEvent(this))}},entities:{get:function(){return this._entityCollection}},isLoading:{get:function(){return this._isLoading},set:function(e){n.setLoading(this,e)}},changedEvent:{get:function(){return this._changed}},errorEvent:{get:function(){return this._error}},loadingEvent:{get:function(){return this._loading}},show:{get:function(){return this._entityCollection.show},set:function(e){this._entityCollection.show=e}},clustering:{get:function(){return this._entityCluster},set:function(e){this._entityCluster=e}}}),s}),define("DataSources/CylinderGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/CylinderGeometry","../Core/CylinderOutlineGeometry","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/ShowGeometryInstanceAttribute","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.length=void 0,this.topRadius=void 0,this.bottomRadius=void 0,this.slices=void 0,this.numberOfVerticalLines=void 0}function A(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(A.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new d,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"cylinder",e.cylinder,void 0)}function E(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(e.WHITE),P=new C(!0),D=new C(!0),I=new C(!1),O=new C(e.BLACK),M=new C(v.DISABLED),R=new C(new u),N=new e;return a(A,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),a(A.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!o(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!o(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!0},geometryChanged:{get:function(){return this._geometryChanged}}}),A.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},A.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},A.prototype.createFillGeometryInstance=function(i){var n,a,s=this._entity,l=s.isAvailable(i),u=new f(l&&s.isShowing&&this._showProperty.getValue(i)&&this._fillProperty.getValue(i)),d=this._distanceDisplayConditionProperty.getValue(i),m=c.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var g=e.WHITE;o(this._materialProperty.color)&&(this._materialProperty.color.isConstant||l)&&(g=this._materialProperty.color.getValue(i)),a=t.fromColor(g),n={show:u,distanceDisplayCondition:m,color:a}}else n={show:u,distanceDisplayCondition:m};return new h({id:s,geometry:new r(this._options),modelMatrix:s.computeModelMatrix(p.MINIMUM_VALUE),attributes:n})},A.prototype.createOutlineGeometryInstance=function(r){var n=this._entity,o=n.isAvailable(r),a=w.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),s=this._distanceDisplayConditionProperty.getValue(r);return new h({id:n,geometry:new i(this._options),modelMatrix:n.computeModelMatrix(p.MINIMUM_VALUE),attributes:{show:new f(o&&n.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(a),distanceDisplayCondition:c.fromDistanceDisplayCondition(s)}})},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){this._entitySubscription(),s(this)},A.prototype._onEntityPropertyChanged=function(e,t,r,i){if("availability"===t||"position"===t||"orientation"===t||"cylinder"===t){var a=e.cylinder;if(!o(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!o(s)||!s.isConstant||s.getValue(p.MINIMUM_VALUE),u=a.outline,c=o(u);if(c&&u.isConstant&&(c=u.getValue(p.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=e.position,h=a.length,f=a.topRadius,_=a.bottomRadius,v=a.show;if(o(v)&&v.isConstant&&!v.getValue(p.MINIMUM_VALUE)||!o(d)||!o(h)||!o(f)||!o(_))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var C=n(a.material,x),b=C instanceof y;this._materialProperty=C,this._fillProperty=n(s,D),this._showProperty=n(v,P),this._showOutlineProperty=n(a.outline,I),this._outlineColorProperty=c?n(a.outlineColor,O):void 0,this._shadowsProperty=n(a.shadows,M),this._distanceDisplayConditionProperty=n(a.distanceDisplayCondition,R);var S=a.slices,T=a.outlineWidth,A=a.numberOfVerticalLines;if(this._fillEnabled=l,this._outlineEnabled=c,d.isConstant&&w.isConstant(e.orientation)&&h.isConstant&&f.isConstant&&_.isConstant&&w.isConstant(S)&&w.isConstant(T)&&w.isConstant(A)){var E=this._options;E.vertexFormat=b?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,E.length=h.getValue(p.MINIMUM_VALUE),E.topRadius=f.getValue(p.MINIMUM_VALUE),E.bottomRadius=_.getValue(p.MINIMUM_VALUE),E.slices=o(S)?S.getValue(p.MINIMUM_VALUE):void 0,E.numberOfVerticalLines=o(A)?A.getValue(p.MINIMUM_VALUE):void 0,this._outlineWidth=o(T)?T.getValue(p.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},A.prototype.createDynamicUpdater=function(e){return new E(e,this)},E.prototype.update=function(n){var a=this._primitives;a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var s=this._geometryUpdater,l=s._entity,u=l.cylinder;if(l.isShowing&&l.isAvailable(n)&&w.getValueOrDefault(u.show,n,!0)){var d=this._options,p=l.computeModelMatrix(n),f=w.getValueOrUndefined(u.length,n),v=w.getValueOrUndefined(u.topRadius,n),y=w.getValueOrUndefined(u.bottomRadius,n);if(o(p)&&o(f)&&o(v)&&o(y)){d.length=f,d.topRadius=v,d.bottomRadius=y,d.slices=w.getValueOrUndefined(u.slices,n),d.numberOfVerticalLines=w.getValueOrUndefined(u.numberOfVerticalLines,n);var C=this._geometryUpdater.shadowsProperty.getValue(n),b=this._geometryUpdater.distanceDisplayConditionProperty,T=b.getValue(n),A=c.fromDistanceDisplayCondition(T);if(w.getValueOrDefault(u.fill,n,!0)){var E=S.getValue(n,s.fillMaterialProperty,this._material);this._material=E;var x=new m({material:E,translucent:E.isTranslucent(),closed:!0});d.vertexFormat=x.vertexFormat,this._primitive=a.add(new _({geometryInstances:new h({id:l,geometry:new r(d),modelMatrix:p,attributes:{distanceDisplayCondition:A}}),appearance:x,asynchronous:!1,shadows:C}))}if(w.getValueOrDefault(u.outline,n,!1)){d.vertexFormat=g.VERTEX_FORMAT;var P=w.getValueOrClonedDefault(u.outlineColor,n,e.BLACK,N),D=w.getValueOrDefault(u.outlineWidth,n,1),I=1!==P.alpha;this._outlinePrimitive=a.add(new _({geometryInstances:new h({id:l,geometry:new i(d),modelMatrix:p,attributes:{color:t.fromColor(P),distanceDisplayCondition:A}}),appearance:new g({flat:!0,translucent:I,renderState:{lineWidth:s._scene.clampLineWidth(D)}}),asynchronous:!1,shadows:C}))}}}},E.prototype.getBoundingSphere=function(e,t){return b(e,this._primitive,this._outlinePrimitive,t)},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),s(this)},A}),define("Scene/ColorBlendMode",["../Core/freezeObject","../Core/Math"],function(e,t){"use strict";var r={HIGHLIGHT:0,REPLACE:1,MIX:2};return r.getColorBlend=function(e,i){return e===r.HIGHLIGHT?0:e===r.REPLACE?1:e===r.MIX?t.clamp(i,t.EPSILON4,1):void 0},e(r)}),define("DataSources/DataSourceClock",["../Core/Clock","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/JulianDate","./createRawPropertyDescriptor"],function(e,t,r,i,n,o,a,s){"use strict";function l(){this._startTime=void 0,this._stopTime=void 0,this._currentTime=void 0,this._clockRange=void 0,this._clockStep=void 0,this._multiplier=void 0,this._definitionChanged=new o}return i(l.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},startTime:s("startTime"),stopTime:s("stopTime"),currentTime:s("currentTime"),clockRange:s("clockRange"),clockStep:s("clockStep"),multiplier:s("multiplier")}),l.prototype.clone=function(e){return r(e)||(e=new l),e.startTime=this.startTime,e.stopTime=this.stopTime,e.currentTime=this.currentTime,e.clockRange=this.clockRange,e.clockStep=this.clockStep,e.multiplier=this.multiplier,e},l.prototype.equals=function(e){return this===e||r(e)&&a.equals(this.startTime,e.startTime)&&a.equals(this.stopTime,e.stopTime)&&a.equals(this.currentTime,e.currentTime)&&this.clockRange===e.clockRange&&this.clockStep===e.clockStep&&this.multiplier===e.multiplier},l.prototype.merge=function(e){this.startTime=t(this.startTime,e.startTime),this.stopTime=t(this.stopTime,e.stopTime),this.currentTime=t(this.currentTime,e.currentTime),this.clockRange=t(this.clockRange,e.clockRange),this.clockStep=t(this.clockStep,e.clockStep),this.multiplier=t(this.multiplier,e.multiplier)},l.prototype.getValue=function(i){return r(i)||(i=new e),i.startTime=t(this.startTime,i.startTime),i.stopTime=t(this.stopTime,i.stopTime),i.currentTime=t(this.currentTime,i.currentTime),i.clockRange=t(this.clockRange,i.clockRange),i.multiplier=t(this.multiplier,i.multiplier),i.clockStep=t(this.clockStep,i.clockStep),i},l}),define("DataSources/GridMaterialProperty",["../Core/Cartesian2","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT),this._definitionChanged=new o,this._color=void 0,this._colorSubscription=void 0,this._cellAlpha=void 0,this._cellAlphaSubscription=void 0,this._lineCount=void 0,this._lineCountSubscription=void 0,this._lineThickness=void 0,this._lineThicknessSubscription=void 0,this._lineOffset=void 0,this._lineOffsetSubscription=void 0,this.color=e.color,this.cellAlpha=e.cellAlpha,this.lineCount=e.lineCount,this.lineThickness=e.lineThickness,this.lineOffset=e.lineOffset}var u=t.WHITE,c=new e(8,8),d=new e(0,0),h=new e(1,1);return n(l.prototype,{isConstant:{get:function(){return s.isConstant(this._color)&&s.isConstant(this._cellAlpha)&&s.isConstant(this._lineCount)&&s.isConstant(this._lineThickness)&&s.isConstant(this._lineOffset)}},definitionChanged:{get:function(){return this._definitionChanged}},color:a("color"),cellAlpha:a("cellAlpha"),lineCount:a("lineCount"),lineThickness:a("lineThickness"),lineOffset:a("lineOffset")}),l.prototype.getType=function(e){return"Grid"},l.prototype.getValue=function(e,t){return i(t)||(t={}),t.color=s.getValueOrClonedDefault(this._color,e,u,t.color),t.cellAlpha=s.getValueOrDefault(this._cellAlpha,e,.1),t.lineCount=s.getValueOrClonedDefault(this._lineCount,e,c,t.lineCount),t.lineThickness=s.getValueOrClonedDefault(this._lineThickness,e,h,t.lineThickness),t.lineOffset=s.getValueOrClonedDefault(this._lineOffset,e,d,t.lineOffset),t},l.prototype.equals=function(e){return this===e||e instanceof l&&s.equals(this._color,e._color)&&s.equals(this._cellAlpha,e._cellAlpha)&&s.equals(this._lineCount,e._lineCount)&&s.equals(this._lineThickness,e._lineThickness)&&s.equals(this._lineOffset,e._lineOffset)},l}),define("DataSources/PolylineArrowMaterialProperty",["../Core/Color","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o){"use strict";function a(e){this._definitionChanged=new i,this._color=void 0,this._colorSubscription=void 0,this.color=e}return r(a.prototype,{isConstant:{get:function(){return o.isConstant(this._color)}},definitionChanged:{get:function(){return this._definitionChanged}},color:n("color")}),a.prototype.getType=function(e){return"PolylineArrow"},a.prototype.getValue=function(r,i){return t(i)||(i={}),i.color=o.getValueOrClonedDefault(this._color,r,e.WHITE,i.color),i},a.prototype.equals=function(e){return this===e||e instanceof a&&o.equals(this._color,e._color)},a}),define("DataSources/PolylineDashMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._color=void 0,this._colorSubscription=void 0,this._gapColor=void 0,this._gapColorSubscription=void 0,this._dashLength=void 0,this._dashLengthSubscription=void 0,this._dashPattern=void 0,this._dashPatternSubscription=void 0,this.color=e.color,this.gapColor=e.gapColor,this.dashLength=e.dashLength,this.dashPattern=e.dashPattern}var l=e.WHITE,u=e.TRANSPARENT;return i(s.prototype,{isConstant:{get:function(){return a.isConstant(this._color)&&a.isConstant(this._gapColor)&&a.isConstant(this._dashLength)&&a.isConstant(this._dashPattern)}},definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),gapColor:o("gapColor"),dashLength:o("dashLength"),dashPattern:o("dashPattern")}),s.prototype.getType=function(e){return"PolylineDash"},s.prototype.getValue=function(e,t){return r(t)||(t={}),t.color=a.getValueOrClonedDefault(this._color,e,l,t.color),t.gapColor=a.getValueOrClonedDefault(this._gapColor,e,u,t.gapColor),t.dashLength=a.getValueOrDefault(this._dashLength,e,16,t.dashLength),t.dashPattern=a.getValueOrDefault(this._dashPattern,e,255,t.dashPattern),t},s.prototype.equals=function(e){return this===e||e instanceof s&&a.equals(this._color,e._color)&&a.equals(this._gapColor,e._gapColor)&&a.equals(this._dashLength,e._dashLength)&&a.equals(this._dashPattern,e._dashPattern)},s}),define("DataSources/PolylineGlowMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._color=void 0,this._colorSubscription=void 0,this._glowPower=void 0,this._glowPowerSubscription=void 0,this.color=e.color,this.glowPower=e.glowPower}var l=e.WHITE;return i(s.prototype,{isConstant:{get:function(){return a.isConstant(this._color)&&a.isConstant(this._glow)}},definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),glowPower:o("glowPower")}),s.prototype.getType=function(e){return"PolylineGlow"},s.prototype.getValue=function(e,t){return r(t)||(t={}),t.color=a.getValueOrClonedDefault(this._color,e,l,t.color),t.glowPower=a.getValueOrDefault(this._glowPower,e,.25,t.glowPower),t},s.prototype.equals=function(e){return this===e||e instanceof s&&a.equals(this._color,e._color)&&a.equals(this._glowPower,e._glowPower)},s}),define("DataSources/PolylineOutlineMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._color=void 0,this._colorSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this.color=e.color,this.outlineColor=e.outlineColor,this.outlineWidth=e.outlineWidth}var l=e.WHITE,u=e.BLACK;return i(s.prototype,{isConstant:{get:function(){return a.isConstant(this._color)&&a.isConstant(this._outlineColor)&&a.isConstant(this._outlineWidth)}},definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),outlineColor:o("outlineColor"),outlineWidth:o("outlineWidth")}),s.prototype.getType=function(e){return"PolylineOutline"},s.prototype.getValue=function(e,t){return r(t)||(t={}),t.color=a.getValueOrClonedDefault(this._color,e,l,t.color),t.outlineColor=a.getValueOrClonedDefault(this._outlineColor,e,u,t.outlineColor),t.outlineWidth=a.getValueOrDefault(this._outlineWidth,e,1),t},s.prototype.equals=function(e){return this===e||e instanceof s&&a.equals(this._color,e._color)&&a.equals(this._outlineColor,e._outlineColor)&&a.equals(this._outlineWidth,e._outlineWidth)},s}),define("DataSources/PositionPropertyArray",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/EventHelper","../Core/ReferenceFrame","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(t,r){this._value=void 0,this._definitionChanged=new n,this._eventHelper=new o,this._referenceFrame=e(r,a.FIXED),this.setValue(t)}return r(l.prototype,{isConstant:{get:function(){var e=this._value;if(!t(e))return!0;for(var r=e.length,i=0;i=t;i--)e[i]=e[s--]}for(i=0;i=0||r(_)&&s.compare(g,_)>=0));){for(f[y++]=g,v+=1,l=0;l0&&(m.length=C,u(n,p,m),f.length=y,u(i,h,f))}else{for(l=0;ll)return;if(this._backwardExtrapolationType===a.HOLD)return u.unpack(c,0,i)}if(d>=o){d=o-1;var p=n[d];if(l=this._forwardExtrapolationDuration,this._forwardExtrapolationType===a.NONE||0!==l&&s.secondsDifference(t,p)>l)return;if(this._forwardExtrapolationType===a.HOLD)return d=o-1,u.unpack(c,d*u.packedLength,i)}var f=this._xTable,m=this._yTable,g=this._interpolationAlgorithm,_=this._packedInterpolationLength,v=this._inputOrder;if(this._updateTableLength){this._updateTableLength=!1;var y=Math.min(g.getRequiredDataPoints(this._interpolationDegree,v),o);y!==this._numberOfPoints&&(this._numberOfPoints=y,f.length=y,m.length=y*_)}var C=this._numberOfPoints-1;if(C<1)return;var b=0,S=o-1;if(S-b+1>=C+1){var w=d-(C/2|0)-1;wS&&(T=S,(w=T-C)0){n=new Array(i);for(var s=0;sh&&e!==Object);var v="function"==typeof e.unpack&&e!==Ae;if(!p&&!_)return void(t[r]=g?new J(v?e.unpack(f,0):f):Fe(e,a,i));var y,C=t[r],S=i.epoch;if(c(S)&&(y=w.fromIso8601(S)),p&&!_)return C instanceof xe||(C=new xe(e),t[r]=C),C.addSamplesPackedArray(f,y),void Je(i,C);var T;if(!p&&_)return l=l.clone(),l.data=g?v?e.unpack(f,0):f:Fe(e,a,i),c(C)||(C=g?new Oe:new Z,t[r]=C),void(g&&C instanceof Oe?C.intervals.addInterval(l):C instanceof Z?(g&&(l.data=new J(l.data)),C.intervals.addInterval(l)):(T=b.MAXIMUM_INTERVAL.clone(),T.data=C,C=new Z,t[r]=C,C.intervals.addInterval(T),g&&(l.data=new J(l.data)),C.intervals.addInterval(l)));c(C)||(C=new Z,t[r]=C),C instanceof Z||(T=b.MAXIMUM_INTERVAL.clone(),T.data=C,C=new Z,t[r]=C,C.intervals.addInterval(T));var A=C.intervals;T=A.findInterval(l),c(T)&&T.data instanceof xe||(T=l.clone(),T.data=new xe(e),A.addInterval(T)),T.data.addSamplesPackedArray(f,y),Je(i,T.data)}function et(e,t,r,i,n,o,a,s){if(c(i))if(C(i))for(var l=0,u=i.length;l_),!m&&!y)return void(e[t]=v?new K(r.unpack(p),h):ke(a,i.reference));var C,S=e[t],T=i.epoch;if(c(T)&&(C=w.fromIso8601(T)),m&&!y)return S instanceof Ee&&(!c(h)||S.referenceFrame===h)||(S=new Ee(h,g),e[t]=S),S.addSamplesPackedArray(p,C),void Je(i,S);var A;if(!m&&y)return l=l.clone(),l.data=v?r.unpack(p):ke(a,i.reference),c(S)||(S=v?new Ie(h):new Q(h),e[t]=S),void(v&&S instanceof Ie&&c(h)&&S.referenceFrame===h?S.intervals.addInterval(l):S instanceof Q?(v&&(l.data=new K(l.data,h)),S.intervals.addInterval(l)):(A=b.MAXIMUM_INTERVAL.clone(),A.data=S,S=new Q(S.referenceFrame),e[t]=S,S.intervals.addInterval(A),v&&(l.data=new K(l.data,h)),S.intervals.addInterval(l)));c(S)?S instanceof Q||(A=b.MAXIMUM_INTERVAL.clone(),A.data=S,S=new Q(S.referenceFrame),e[t]=S,S.intervals.addInterval(A)):(S=new Q(h),e[t]=S);var E=S.intervals;A=E.findInterval(l),c(A)&&A.data instanceof Ee&&(!c(h)||A.data.referenceFrame===h)||(A=l.clone(),A.data=new Ee(h,g),E.addInterval(A)),A.data.addSamplesPackedArray(p,C),Je(i,A.data)}function rt(e,t,r,i,n,o,a){if(c(r))if(C(r))for(var s=0,l=r.length;s. version format.");var n=t._documentPacket;c(e.name)&&(n.name=e.name);var o=e.clock;if(c(o)){var a=n.clock;c(a)?(a.interval=u(o.interval,a.interval),a.currentTime=u(o.currentTime,a.currentTime),a.range=u(o.range,a.range),a.step=u(o.step,a.step),a.multiplier=u(o.multiplier,a.multiplier)):n.clock={interval:o.interval,currentTime:o.currentTime,range:o.range,step:o.step,multiplier:o.multiplier}}}function St(e,t,r,i,n){var o=t.ellipse;if(c(o)){var s,l=o.interval;c(l)&&(qt.iso8601=l,s=L.fromIso8601(qt));var u=e.ellipse;c(u)||(e.ellipse=u=new ie),et(Boolean,u,"show",o.show,s,i,r,n),et(Number,u,"semiMajorAxis",o.semiMajorAxis,s,i,r,n),et(Number,u,"semiMinorAxis",o.semiMinorAxis,s,i,r,n),et(Number,u,"height",o.height,s,i,r,n),et(Number,u,"extrudedHeight",o.extrudedHeight,s,i,r,n),et(Ae,u,"rotation",o.rotation,s,i,r,n),et(Ae,u,"stRotation",o.stRotation,s,i,r,n),et(Number,u,"granularity",o.granularity,s,i,r,n),et(Boolean,u,"fill",o.fill,s,i,r,n),nt(u,"material",o.material,s,i,r,n),et(Boolean,u,"outline",o.outline,s,i,r,n),et(a,u,"outlineColor",o.outlineColor,s,i,r,n),et(Number,u,"outlineWidth",o.outlineWidth,s,i,r,n),et(Number,u,"numberOfVerticalLines",o.numberOfVerticalLines,s,i,r,n),et(z,u,"shadows",o.shadows,s,i,r,n),et(p,u,"distanceDisplayCondition",o.distanceDisplayCondition,s,i,r,n)}}function wt(e,t,i,n,o){var s=t.ellipsoid;if(c(s)){var l,u=s.interval;c(u)&&(qt.iso8601=u,l=L.fromIso8601(qt));var d=e.ellipsoid;c(d)||(e.ellipsoid=d=new ne),et(Boolean,d,"show",s.show,l,n,i,o),et(r,d,"radii",s.radii,l,n,i,o),et(Boolean,d,"fill",s.fill,l,n,i,o),nt(d,"material",s.material,l,n,i,o),et(Boolean,d,"outline",s.outline,l,n,i,o),et(a,d,"outlineColor",s.outlineColor,l,n,i,o),et(Number,d,"outlineWidth",s.outlineWidth,l,n,i,o),et(Number,d,"stackPartitions",s.stackPartitions,l,n,i,o),et(Number,d,"slicePartitions",s.slicePartitions,l,n,i,o),et(Number,d,"subdivisions",s.subdivisions,l,n,i,o),et(z,d,"shadows",s.shadows,l,n,i,o),et(p,d,"distanceDisplayCondition",s.distanceDisplayCondition,l,n,i,o)}}function Tt(e,i,n,o,s){var l=i.label;if(c(l)){var u,d=l.interval;c(d)&&(qt.iso8601=d,u=L.fromIso8601(qt));var h=e.label;c(h)||(e.label=h=new ue),et(Boolean,h,"show",l.show,u,o,n,s),et(String,h,"text",l.text,u,o,n,s),et(String,h,"font",l.font,u,o,n,s),et(V,h,"style",l.style,u,o,n,s),et(Number,h,"scale",l.scale,u,o,n,s),et(Boolean,h,"showBackground",l.showBackground,u,o,n,s),et(a,h,"backgroundColor",l.backgroundColor,u,o,n,s),et(t,h,"backgroundPadding",l.backgroundPadding,u,o,n,s),et(t,h,"pixelOffset",l.pixelOffset,u,o,n,s),et(r,h,"eyeOffset",l.eyeOffset,u,o,n,s),et(U,h,"horizontalOrigin",l.horizontalOrigin,u,o,n,s),et(G,h,"verticalOrigin",l.verticalOrigin,u,o,n,s),et(B,h,"heightReference",l.heightReference,u,o,n,s),et(a,h,"fillColor",l.fillColor,u,o,n,s),et(a,h,"outlineColor",l.outlineColor,u,o,n,s),et(Number,h,"outlineWidth",l.outlineWidth,u,o,n,s),et(P,h,"translucencyByDistance",l.translucencyByDistance,u,o,n,s),et(P,h,"pixelOffsetScaleByDistance",l.pixelOffsetScaleByDistance,u,o,n,s),et(P,h,"scaleByDistance",l.scaleByDistance,u,o,n,s),et(p,h,"distanceDisplayCondition",l.distanceDisplayCondition,u,o,n,s),et(Number,h,"disableDepthTestDistance",l.disableDepthTestDistance,u,o,n,s)}}function At(e,t,r,i,n){var o=t.model;if(c(o)){var s,l=o.interval;c(l)&&(qt.iso8601=l,s=L.fromIso8601(qt));var u=e.model;c(u)||(e.model=u=new ce),et(Boolean,u,"show",o.show,s,i,r,n),et(H,u,"uri",o.gltf,s,i,r,n),et(Number,u,"scale",o.scale,s,i,r,n),et(Number,u,"minimumPixelSize",o.minimumPixelSize,s,i,r,n),et(Number,u,"maximumScale",o.maximumScale,s,i,r,n),et(Boolean,u,"incrementallyLoadTextures",o.incrementallyLoadTextures,s,i,r,n),et(Boolean,u,"runAnimations",o.runAnimations,s,i,r,n),et(Boolean,u,"clampAnimations",o.clampAnimations,s,i,r,n),et(z,u,"shadows",o.shadows,s,i,r,n),et(B,u,"heightReference",o.heightReference,s,i,r,n),et(a,u,"silhouetteColor",o.silhouetteColor,s,i,r,n),et(Number,u,"silhouetteSize",o.silhouetteSize,s,i,r,n),et(a,u,"color",o.color,s,i,r,n),et(F,u,"colorBlendMode",o.colorBlendMode,s,i,r,n),et(Number,u,"colorBlendAmount",o.colorBlendAmount,s,i,r,n),et(p,u,"distanceDisplayCondition",o.distanceDisplayCondition,s,i,r,n);var d=o.nodeTransformations -;if(c(d))if(C(d))for(var h=0,f=d.length;h-1;d--)r[d](s,e,t,i,o)}Ut=void 0}function Nt(e){var t,r=e._documentPacket.clock;if(!c(r)){if(!c(e._clock)){var i=e._entityCollection.computeAvailability();if(!i.start.equals(b.MINIMUM_VALUE)){var a=i.start,s=i.stop,l=w.secondsDifference(s,a),d=Math.round(l/120);return t=new re,t.startTime=w.clone(a),t.stopTime=w.clone(s),t.clockRange=n.LOOP_STOP,t.multiplier=d,t.currentTime=w.clone(a),t.clockStep=o.SYSTEM_CLOCK_MULTIPLIER,e._clock=t,!0}}return!1}if(c(e._clock)?t=e._clock.clone():(t=new re,t.startTime=b.MINIMUM_VALUE.clone(),t.stopTime=b.MAXIMUM_VALUE.clone(),t.currentTime=b.MINIMUM_VALUE.clone(),t.clockRange=n.LOOP_STOP,t.clockStep=o.SYSTEM_CLOCK_MULTIPLIER,t.multiplier=1),c(r.interval)){qt.iso8601=r.interval;var h=L.fromIso8601(qt);t.startTime=h.start,t.stopTime=h.stop}return c(r.currentTime)&&(t.currentTime=w.fromIso8601(r.currentTime)),c(r.range)&&(t.clockRange=u(n[r.range],n.LOOP_STOP)),c(r.step)&&(t.clockStep=u(o[r.step],o.SYSTEM_CLOCK_MULTIPLIER)),c(r.multiplier)&&(t.multiplier=r.multiplier),!t.equals(e._clock)&&(e._clock=t.clone(e._clock),!0)}function Lt(e,t,r,i){r=u(r,u.EMPTY_OBJECT);var n=t,o=r.sourceUri,a=c(r.query)?D(r.query):void 0;return"string"==typeof t&&(c(a)&&(t=S(t,"?"+a,!1)),n=E(t),o=u(o,t)),te.setLoading(e,!0),W(n,function(t){return kt(e,t,o,i,a)}).otherwise(function(t){return te.setLoading(e,!1),e._error.raiseEvent(e,t),console.log(t),W.reject(t)})}function kt(e,t,r,i,n){te.setLoading(e,!0);var o=e._entityCollection;i&&(e._version=void 0,e._documentPacket=new Ft,o.removeAll()),Bt._processCzml(t,o,r,void 0,e,n);var a=Nt(e),s=e._documentPacket;return c(s.name)&&e._name!==s.name?(e._name=s.name,a=!0):!c(e._name)&&c(r)&&(e._name=v(r),a=!0),te.setLoading(e,!1),a&&e._changed.raiseEvent(e),e}function Ft(){this.name=void 0,this.clock=void 0}function Bt(e){this._name=e,this._changed=new m,this._error=new m,this._isLoading=!1,this._loading=new m,this._clock=void 0,this._documentPacket=new Ft,this._version=void 0,this._entityCollection=new ae(this),this._entityCluster=new oe}Le.packedLength=r.packedLength,Le.unpack=r.unpack,Le.pack=r.pack;var Ut,Vt=new r,zt=new N,Gt=new i,Ht=new L,Wt=new I,jt={HERMITE:y,LAGRANGE:T,LINEAR:A},qt={iso8601:void 0};return Bt.load=function(e,t){return(new Bt).load(e,t)},d(Bt.prototype,{name:{get:function(){return this._name}},clock:{get:function(){return this._clock}},entities:{get:function(){return this._entityCollection}},isLoading:{get:function(){return this._isLoading}},changedEvent:{get:function(){return this._changed}},errorEvent:{get:function(){return this._error}},loadingEvent:{get:function(){return this._loading}},show:{get:function(){return this._entityCollection.show},set:function(e){this._entityCollection.show=e}},clustering:{get:function(){return this._entityCluster},set:function(e){this._entityCluster=e}}}),Bt.updaters=[_t,vt,yt,Ct,St,wt,Tt,At,ot,at,xt,Pt,Dt,It,ct,Ot,st,lt,Mt,ut,mt],Bt.prototype.process=function(e,t){return Lt(this,e,t,!1)},Bt.prototype.load=function(e,t){return Lt(this,e,t,!0)},Bt.processPacketData=et,Bt.processPositionPacketData=rt,Bt.processMaterialPacketData=nt,Bt._processCzml=function(e,t,r,i,n,o){if(i=c(i)?i:Bt.updaters,C(e))for(var a=0,s=e.length;a=0;i--){var n=e[i];if(n.remove(t)&&0===n.updaters.length)return e.splice(i,1),n.destroy(),!0}return!1}function m(e,t,r){for(var i=!1,n=t.length,o=0;o0)for(o=0;o=0;n--){var a=t[n];if(a.invalidated){t.splice(n,1);for(var s=a.updaters.values,l=s.length,u=0;u0){for(i(m)&&(i(this.oldPrimitive)?g.remove(m):this.oldPrimitive=m),h=0;h0){for(i(g)&&(i(this.oldPrimitive)?_.remove(g):this.oldPrimitive=g),h=0;h=0;i--){var n=t[i];if(n.remove(e)){0===n.updaters.length&&(t.splice(i,1),n.destroy());break}}},p.prototype.update=function(e){var t,r=this._items,i=r.length;for(t=i-1;t>=0;t--){var n=r[t];if(n.invalidated){r.splice(t,1);for(var o=n.updaters.values,a=o.length,s=0;s0){for(r(m)&&(r(this.oldPrimitive)?g.remove(m):this.oldPrimitive=m),u=0;u0){for(i(g)&&(i(this.oldPrimitive)?_.remove(g):this.oldPrimitive=g),d=0;d0)for(d=!0,t=0;t0)for(d=!0,t=0;t-1;t--)r=c[t],i=r.id,n=this._updaters.get(i),n.entity===r?(p(this,n),f(this,e,n)):(l.push(r),a.push(r));for(t=l.length-1;t>-1;t--)r=l[t],i=r.id,n=this._updaters.get(i),p(this,n),n.destroy(),this._updaters.remove(i),this._subscriptions.get(i)(),this._subscriptions.remove(i);for(t=a.length-1;t>-1;t--)r=a[t],i=r.id,n=new this._type(r,this._scene),this._updaters.set(i,n),f(this,e,n),this._subscriptions.set(i,n.geometryChanged.addEventListener(m._onGeometryChanged,this));o.removeAll(),s.removeAll(),u.removeAll();var d=!0,h=this._batches,g=h.length;for(t=0;t-1;i--)o=r[i],n=o.id,a.remove(n)||(s.set(n,o),l.remove(n));for(i=t.length-1;i>-1;i--)o=t[i],n=o.id,s.remove(n)?l.set(n,o):a.set(n,o)},m}),define("DataSources/LabelVisualizer",["../Core/AssociativeArray","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/NearFarScalar","../Scene/HeightReference","../Scene/HorizontalOrigin","../Scene/LabelStyle","../Scene/VerticalOrigin","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e){this.entity=e,this.label=void 0,this.index=void 0}function _(t,r){r.collectionChanged.addEventListener(_.prototype._onCollectionChanged,this),this._cluster=t,this._entityCollection=r,this._items=new e,this._onCollectionChanged(r,r.values,[],[])}function v(e,t,r){o(e)&&(e.label=void 0,r.removeLabel(t))}var y=h.FILL,C=i.WHITE,b=i.BLACK,S=new i(.165,.165,.165,.8),w=new t(7,5),T=t.ZERO,A=r.ZERO,E=c.NONE,x=d.CENTER,P=p.CENTER,D=new r,I=new i,O=new i,M=new i,R=new t,N=new r,L=new t,k=new u,F=new u,B=new u,U=new l;return _.prototype.update=function(e){for(var t=this._items.values,r=this._cluster,i=0,n=t.length;i-1;n--)a=t[n],o(a._label)&&o(a._position)&&s.set(a.id,new g(a));for(n=i.length-1;n>-1;n--)a=i[n],o(a._label)&&o(a._position)?s.contains(a.id)||s.set(a.id,new g(a)):(v(s.get(a.id),a,l),s.remove(a.id));for(n=r.length-1;n>-1;n--)a=r[n],v(s.get(a.id),a,l),s.remove(a.id)},_}),define("ThirdParty/GltfPipeline/addToArray",[],function(){"use strict";function e(e,t){return e.push(t),e.length-1}return e}),define("ThirdParty/GltfPipeline/ForEach",["../../Core/defined"],function(e){"use strict";var t={};return t.object=function(t,r){if(e(t))for(var i=0;i0){var l=o[0];if("object"==typeof l)for(var u=s.length,c=0;c0){var a=e.accessors,s=e.bufferViews;t.mesh(e,function(e){if(t.meshPrimitive(e,function(e){var l=e.indices;if(n(l)){var u=a[l],c=u.bufferView;if(r[c]){var d=s[c];n(d)&&(d.target=o.ELEMENT_ARRAY_BUFFER,r[c]=!1,i--)}}t.meshPrimitiveAttribute(e,function(e){var t=a[e],l=t.bufferView;if(r[l]){var u=s[l];n(u)&&(u.target=o.ARRAY_BUFFER,r[l]=!1,i--)}}),t.meshPrimitiveTargetAttribute(e,function(e){var t=a[e].bufferView;if(r[t]){var l=s[t];n(l)&&(l.target=o.ARRAY_BUFFER,r[t]=!1,i--)}})}),0===i)return!0})}}function p(e,t){return t=i(t,{}),a(e,f),s(e),l(e),u(e),c(e),h(e),t.optimizeForCesium&&d(e),e}var f={accessors:[],animations:[{channels:[],samplers:[{interpolation:"LINEAR"}]}],asset:{},buffers:[{byteLength:0,type:"arraybuffer"}],bufferViews:[{byteLength:0}],cameras:[],images:[],materials:[{values:function(e){var t=i(e.extensions,{}),r=t.KHR_materials_common;if(!n(r))return{}},extensions:function(e){var t=i(e.extensions,{}),r=t.KHR_materials_common;if(n(r)){var o=r.technique,a={ambient:[0,0,0,1],emission:[0,0,0,1],transparency:1};return"CONSTANT"!==o&&(a.diffuse=[0,0,0,1],"LAMBERT"!==o&&(a.specular=[0,0,0,1],a.shininess=0)),{KHR_materials_common:{doubleSided:!1,transparent:!1,values:a}}}}}],meshes:[{primitives:[{attributes:{},mode:o.TRIANGLES}]}],nodes:[{children:[],matrix:function(e){if(!n(e.translation)&&!n(e.rotation)&&!n(e.scale))return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},rotation:function(e){if(n(e.translation)||n(e.scale))return[0,0,0,1]},scale:function(e){if(n(e.translation)||n(e.rotation))return[1,1,1]},translation:function(e){if(n(e.rotation)||n(e.scale))return[0,0,0]}}],programs:[{attributes:[]}],samplers:[{magFilter:o.LINEAR,minFilter:o.NEAREST_MIPMAP_LINEAR,wrapS:o.REPEAT,wrapT:o.REPEAT}],scenes:[{nodes:[]}],shaders:[],skins:[{bindShapeMatrix:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}],techniques:[{parameters:{},attributes:{},uniforms:{},states:{enable:[]}}],textures:[{format:o.RGBA,internalFormat:o.RGBA,target:o.TEXTURE_2D,type:o.UNSIGNED_BYTE}],extensionsUsed:[],extensionsRequired:[]},m={values:{emission:[.5,.5,.5,1]},extras:{_pipeline:{}}},g={attributes:{a_position:"position"},parameters:{modelViewMatrix:{semantic:"MODELVIEW",type:o.FLOAT_MAT4},projectionMatrix:{semantic:"PROJECTION",type:o.FLOAT_MAT4},emission:{type:o.FLOAT_VEC4,value:[.5,.5,.5,1]},position:{semantic:"POSITION",type:o.FLOAT_VEC3}},states:{enable:[o.CULL_FACE,o.DEPTH_TEST]},uniforms:{u_modelViewMatrix:"modelViewMatrix",u_projectionMatrix:"projectionMatrix",u_emission:"emission"}},_={attributes:["a_position"]},v={type:o.VERTEX_SHADER,extras:{_pipeline:{extension:".vert",source:"precision highp float;\n\nuniform mat4 u_modelViewMatrix;\nuniform mat4 u_projectionMatrix;\n\nattribute vec3 a_position;\n\nvoid main (void)\n{\n gl_Position = u_projectionMatrix * u_modelViewMatrix * vec4(a_position, 1.0);\n}\n"}}},y={type:o.FRAGMENT_SHADER,extras:{_pipeline:{extension:".frag",source:"precision highp float;\n\nuniform vec4 u_emission;\n\nvoid main(void)\n{\n gl_FragColor = u_emission;\n}\n"}}};return p}),define("ThirdParty/GltfPipeline/addPipelineExtras",["../../Core/defaultValue","../../Core/defined"],function(e,t){"use strict";function r(r){var n=[];for(var o in r)if(r.hasOwnProperty(o))for(var a=r[o],s=a.length,l=0;l0;){var c=n.pop();for(var d in c)if(c.hasOwnProperty(d)){var h=c[d];t(h)&&"object"==typeof h&&"extras"!==d&&(n.push(h),i[d]||Array.isArray(h)||(h.extras=e(h.extras,{}),h.extras._pipeline=e(h.extras._pipeline,{})))}}return r.extras=e(r.extras,{}),r.extras._pipeline=e(r.extras._pipeline,{}),r.asset=e(r.asset,{}),r.asset.extras=e(r.asset.extras,{}),t(r.asset.extras)&&"object"!=typeof r.asset.extras&&(r.asset.extras={extras:r.asset.extras}),r.asset.extras._pipeline=e(r.asset.extras._pipeline,{}),r}var i={attributes:!0,uniforms:!0,extensions:!0,values:!0,samplers:!0};return r}),define("ThirdParty/GltfPipeline/byteLengthForComponentType",["../../Core/WebGLConstants"],function(e){"use strict";function t(t){switch(t){case e.BYTE:case e.UNSIGNED_BYTE:return 1;case e.SHORT:case e.UNSIGNED_SHORT:return 2;case e.FLOAT:case e.UNSIGNED_INT:return 4}}return t}),define("ThirdParty/GltfPipeline/numberOfComponentsForType",[],function(){"use strict";function e(e){switch(e){case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":case"MAT2":return 4;case"MAT3":return 9;case"MAT4":return 16}}return e}),define("ThirdParty/GltfPipeline/getAccessorByteStride",["./byteLengthForComponentType","./numberOfComponentsForType","../../Core/defined"],function(e,t,r){"use strict";function i(i,n){var o=i.bufferViews[n.bufferView];return r(o.byteStride)&&o.byteStride>0?o.byteStride:e(n.componentType)*t(n.type)}return i}),define("ThirdParty/GltfPipeline/removeExtensionsRequired",["../../Core/defined"],function(e){"use strict";function t(t,r){var i=t.extensionsRequired;if(e(i)){var n=i.indexOf(r);n>=0&&i.splice(n,1),0===i.length&&delete t.extensionsRequired}}return t}),define("ThirdParty/GltfPipeline/removeExtensionsUsed",["./removeExtensionsRequired","../../Core/defined"],function(e,t){"use strict";function r(r,i){var n=r.extensionsUsed;if(t(n)){var o=n.indexOf(i);o>=0&&n.splice(o,1),e(r,i),0===n.length&&delete r.extensionsUsed}}return r}),define("ThirdParty/GltfPipeline/addExtensionsUsed",["../../Core/defined"],function(e){"use strict";function t(t,r){var i=t.extensionsUsed;e(i)||(i=[],t.extensionsUsed=i),i.indexOf(r)<0&&i.push(r)}return t}),define("ThirdParty/GltfPipeline/addExtensionsRequired",["./addExtensionsUsed","../../Core/defined"],function(e,t){"use strict";function r(r,i){var n=r.extensionsRequired;t(n)||(n=[],r.extensionsRequired=n),n.indexOf(i)<0&&n.push(i),e(r,i)}return r}),define("ThirdParty/GltfPipeline/updateVersion",["./addExtensionsRequired","./addToArray","./ForEach","./getAccessorByteStride","./numberOfComponentsForType","../../Core/Cartesian3","../../Core/Math","../../Core/clone","../../Core/ComponentDatatype","../../Core/defaultValue","../../Core/defined","../../Core/Quaternion","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e,t){t=u(t,{});var r=t.targetVersion,i=e.version;e.asset=u(e.asset,{version:"1.0"}),i=u(i,e.asset.version),F.hasOwnProperty(i)||(c(i)&&(i=(""+i).substring(0,3)),F.hasOwnProperty(i)||(i="1.0"));for(var n=F[i];c(n)&&i!==r;)n(e),i=e.asset.version,n=F[i];return e}function f(e){var t=e.materials;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r],n=i.instanceTechnique;c(n)&&(i.technique=n.technique,i.values=n.values,delete i.instanceTechnique)}}function m(e){var t=e.meshes;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r],n=i.primitives;if(c(n))for(var o=n.length,a=0;a0)for(r.mesh=o.meshes[s[0]],i=1;i0&&c(r.skin)){e.skins[o.skins[r.skin]].skeleton=o.nodes[h[0]]}delete r.skeletons}c(r.skin)&&(r.skin=o.skins[r.skin]),c(r.jointName)&&delete r.jointName}),r.skin(e,function(e){c(e.inverseBindMatrices)&&(e.inverseBindMatrices=o.accessors[e.inverseBindMatrices]);var t=[],r=e.jointNames;if(c(r)){for(i=0;i=0&&(n=r.substring(0,i)),!c(U[n])){var o="_"+r;t[r]=o}}});for(var i in t)if(t.hasOwnProperty(i)){var n=t[i],o=e.attributes[i];c(o)&&(delete e.attributes[i],e.attributes[n]=o)}})}),r.technique(e,function(e){r.techniqueParameter(e,function(e){var r=t[e.semantic];c(r)&&(e.semantic=r)})})}function P(e){r.technique(e,function(e){var t=e.states;if(c(t)){var r=t.functions;c(r)&&delete r.scissor;var i=t.enable;if(c(i)){var n=i.indexOf(h.SCISSOR_TEST);n>=0&&i.splice(n,1)}}})}function D(e){r.technique(e,function(e){var t=e.states;if(c(t)){var r=t.functions;if(c(r)){var i=r.blendColor;if(c(i))for(var n=0;n<4;n++)i[n]=a.clamp(i[n],0,1);var o=r.depthRange;c(o)&&(o[1]=a.clamp(o[1],0,1),o[0]=a.clamp(o[0],0,o[1]))}}})}function I(e){r.camera(e,function(e){var t=e.perspective;if(c(t)){var r=t.aspectRatio;c(r)&&0===r&&delete t.aspectRatio;var i=t.yfov;c(i)&&0===i&&(t.yfov=1)}})}function O(e){r.buffer(e,function(e){c(e.byteLength)||(e.byteLength=e.extras._pipeline.source.length)}),r.bufferView(e,function(t){if(!c(t.byteLength)){var r=t.buffer,i=e.buffers[r];t.byteLength=i.byteLength}})}function M(e){var n=e.bufferViews,o={};r.accessor(e,function(r){var a=r.bufferView;if(c(a)){c(o[a])||(o[a]=!0);var l=s(n[a]),u=c(r.byteStride)&&0!==r.byteStride?r.byteStride:i(e,r);c(u)&&(l.byteStride=u,0!==l.byteStride&&(l.byteLength=r.count*u),l.byteOffset+=r.byteOffset,r.byteOffset=0,delete r.byteStride),r.bufferView=t(n,l)}});var a={},l=0;r.bufferView(e,function(e,t){c(o[t])?l++:a[t]=t-l});var u=0;for(var d in o)if(c(d)){var h=parseInt(d)-u;n.splice(h,1),u++}r.accessor(e,function(e){var t=e.bufferView;c(t)&&(e.bufferView=a[t])}),r.shader(e,function(e){var t=e.bufferView;c(t)&&(e.bufferView=a[t])}),r.image(e,function(e){var t=e.bufferView;if(c(t)&&(e.bufferView=a[t]),c(e.extras)){var r=e.extras.compressedImage3DTiles;for(var i in r)if(r.hasOwnProperty(i)){var n=r[i],o=n.bufferView;c(o)&&(n.bufferView=a[o])}}})}function R(e){r.technique(e,function(e){r.techniqueAttribute(e,function(t){var r=e.parameters[t];c(r.value)&&delete r.value})})}function N(e){r.technique(e,function(e){r.techniqueParameter(e,function(e){if(c(e.count)){var t=e.semantic;(!c(t)||"JOINTMATRIX"!==t&&0!==t.indexOf("_"))&&delete e.count}})})}function L(t){var r=t.techniques;c(r)&&r.length>0&&e(t,"KHR_technique_webgl")}function k(e){c(e.asset)||(e.asset={}),e.asset.version="2.0",f(e),C(e),S(e),w(e),T(e),O(e),M(e),A(e),E(e),x(e),P(e),D(e),I(e),R(e),N(e),L(e)}var F={.8:y,"1.0":k,"2.0":void 0},B={CESIUM_RTC:!0,KHR_materials_common:!0,WEB3D_quantized_attributes:!0},U={POSITION:!0,NORMAL:!0,TEXCOORD:!0,COLOR:!0,JOINT:!0,WEIGHT:!0};return p}),define("ThirdParty/GltfPipeline/parseBinaryGltf",["./addPipelineExtras","./removeExtensionsUsed","./updateVersion","../../Core/ComponentDatatype","../../Core/defined","../../Core/DeveloperError","../../Core/getMagic","../../Core/getStringFromTypedArray","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(u){var c=i.createArrayBufferView(l.INT,u.buffer,u.byteOffset,5);if("glTF"!==a(u))throw new o("File is not valid binary glTF");var d=c[1];if(1!==d&&2!==d)throw new o("Binary glTF version is not 1 or 2");var h,p,f;if(1===d){f=c[2];var m=c[3];if(0!==c[4])throw new o("Binary glTF scene format is not JSON");var g=20+m,_=s(u,20,m);h=JSON.parse(_);var v=u.subarray(g,f);if(p=h.buffers,n(p)&&Object.keys(p).length>0){var y=p.binary_glTF;n(y)||(y=p.KHR_binary_glTF),n(y)&&(y.extras={_pipeline:{source:v}})}r(h),t(h,"KHR_binary_glTF"),e(h)}if(2===d){f=c[2];for(var C,b=12;b0)){p[0].extras._pipeline.source=C}}return h}return u}),define("ThirdParty/GltfPipeline/techniqueParameterForSemantic",["../../Core/defined"],function(e){"use strict";function t(t,r){var i=t.parameters;for(var n in i)if(i.hasOwnProperty(n)){var o=i[n],a=o.semantic;if(e(a)&&a===r)return n}}return t}),define("ThirdParty/GltfPipeline/webGLConstantToGlslType",["../../Core/WebGLConstants"],function(e){"use strict";function t(t){switch(t){case e.FLOAT:return"float";case e.FLOAT_VEC2:return"vec2";case e.FLOAT_VEC3:return"vec3";case e.FLOAT_VEC4:return"vec4";case e.FLOAT_MAT2:return"mat2";case e.FLOAT_MAT3:return"mat3";case e.FLOAT_MAT4:return"mat4";case e.SAMPLER_2D:return"sampler2D";case e.BOOL:return"bool"}}return t}),define("ThirdParty/GltfPipeline/glslTypeToWebGLConstant",["../../Core/WebGLConstants"],function(e){"use strict";function t(t){switch(t){case"float":return e.FLOAT;case"vec2":return e.FLOAT_VEC2;case"vec3":return e.FLOAT_VEC3;case"vec4":return e.FLOAT_VEC4;case"mat2":return e.FLOAT_MAT2;case"mat3":return e.FLOAT_MAT3;case"mat4":return e.FLOAT_MAT4;case"sampler2D":return e.SAMPLER_2D}}return t}),define("ThirdParty/GltfPipeline/processModelMaterialsCommon",["./addToArray","./ForEach","./numberOfComponentsForType","./techniqueParameterForSemantic","./webGLConstantToGlslType","./glslTypeToWebGLConstant","../../Core/clone","../../Core/defined","../../Core/defaultValue","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){if(r=l(r,{}),s(e)){var i=!1,n=e.extensionsRequired,o=e.extensionsUsed;if(s(o)){var a=o.indexOf("KHR_materials_common");a>=0&&(o.splice(a,1),i=!0),s(n)&&(a=n.indexOf("KHR_materials_common"))>=0&&n.splice(a,1)}if(i){s(e.programs)||(e.programs=[]),s(e.shaders)||(e.shaders=[]),s(e.techniques)||(e.techniques=[]),m(e);var u=d(e);y(e);var c={};t.material(e,function(t){if(s(t.extensions)&&s(t.extensions.KHR_materials_common)){var i=t.extensions.KHR_materials_common,n=f(i),o=c[n];s(o)||(o=h(e,i,u,r),c[n]=o),t.values={};var a=i.values;for(var l in a)if(a.hasOwnProperty(l)){var d=a[l];t.values[l]=d}t.technique=o,delete t.extensions.KHR_materials_common,0===Object.keys(t.extensions).length&&delete t.extensions}}),s(e.extensions)&&(delete e.extensions.KHR_materials_common,0===Object.keys(e.extensions).length&&delete e.extensions),v(e)}return e}}function d(e){var t,r={};if(s(e.extensions)&&s(e.extensions.KHR_materials_common)&&(t=e.extensions.KHR_materials_common.lights),s(t)){var i=e.nodes;for(var n in i)if(i.hasOwnProperty(n)){var o=i[n];if(s(o.extensions)&&s(o.extensions.KHR_materials_common)){var a=o.extensions.KHR_materials_common.light;s(a)&&s(t[a])&&(t[a].node=n),delete o.extensions.KHR_materials_common}}var l=0;for(var c in t)if(t.hasOwnProperty(c)){var d=t[c],h=d.type;if("ambient"!==h&&!s(d.node)){delete t[c];continue}var p="light"+l.toString();switch(d.baseName=p,h){case"ambient":var f=d.ambient;r[p+"Color"]={type:u.FLOAT_VEC3,value:f.color};break;case"directional":var m=d.directional;r[p+"Color"]={type:u.FLOAT_VEC3,value:m.color},s(d.node)&&(r[p+"Transform"]={node:d.node,semantic:"MODELVIEW",type:u.FLOAT_MAT4});break;case"point":var g=d.point;r[p+"Color"]={type:u.FLOAT_VEC3,value:g.color},s(d.node)&&(r[p+"Transform"]={node:d.node,semantic:"MODELVIEW",type:u.FLOAT_MAT4}),r[p+"Attenuation"]={type:u.FLOAT_VEC3,value:[g.constantAttenuation,g.linearAttenuation,g.quadraticAttenuation]};break;case"spot":var _=d.spot;r[p+"Color"]={type:u.FLOAT_VEC3,value:_.color},s(d.node)&&(r[p+"Transform"]={node:d.node,semantic:"MODELVIEW",type:u.FLOAT_MAT4},r[p+"InverseTransform"]={node:d.node,semantic:"MODELVIEWINVERSE",type:u.FLOAT_MAT4,useInFragment:!0}),r[p+"Attenuation"]={type:u.FLOAT_VEC3,value:[_.constantAttenuation,_.linearAttenuation,_.quadraticAttenuation]},r[p+"FallOff"]={type:u.FLOAT_VEC2,value:[_.fallOffAngle,_.fallOffExponent]}}++l}}return r}function h(t,i,a,c){var d,h=l(c.optimizeForCesium,!1),f=s(t.extensions)&&s(t.extensions.CESIUM_RTC),m=l(c.addBatchIdToGeneratedShaders,!1),_=t.techniques,v=t.shaders,y=t.programs,C=i.technique.toUpperCase();s(t.extensions)&&s(t.extensions.KHR_materials_common)&&(d=t.extensions.KHR_materials_common.lights);var b=i.values;s(i.transparent)&&(b.transparent=i.transparent),s(i.doubleSided)&&(b.doubleSided=i.doubleSided);var S=l(i.jointCount,0),w=S>0,T={};w&&(T=i.extras._pipeline.skinning);var A="precision highp float;\n",E="precision highp float;\n",x="CONSTANT"!==C,P={modelViewMatrix:{semantic:f?"CESIUM_RTC_MODELVIEW":"MODELVIEW",type:u.FLOAT_MAT4},projectionMatrix:{semantic:"PROJECTION",type:u.FLOAT_MAT4}};x&&(P.normalMatrix={semantic:"MODELVIEWINVERSETRANSPOSE",type:u.FLOAT_MAT3}),w&&(P.jointMatrix={count:S,semantic:"JOINTMATRIX",type:u.FLOAT_MAT4});var D,I=!1;for(var O in b)if(b.hasOwnProperty(O)&&"transparent"!==O&&"doubleSided"!==O){var M=p(O,b[O]);D=O.toLowerCase(),I||M!==u.SAMPLER_2D||(I=!0),P[D]={type:M}}if(s(P.diffuse)&&h&&(P.diffuse.semantic="_3DTILESDIFFUSE"),s(a))for(var R in a)a.hasOwnProperty(R)&&(P[R]=a[R]);var N={};for(var L in P)if(P.hasOwnProperty(L)&&"extras"!==L){var k=P[L];N["u_"+L]=L;var F=s(k.count)?"["+k.count+"]":"";k.type!==u.FLOAT_MAT3&&k.type!==u.FLOAT_MAT4||k.useInFragment?(E+="uniform "+n(k.type)+" u_"+L+F+";\n",delete k.useInFragment):A+="uniform "+n(k.type)+" u_"+L+F+";\n"}var B="";if(w){var U,V,z=r(T.type),G=!1;if(0===T.type.indexOf("MAT")&&(G=!0,z=Math.sqrt(z)),G)for(U=0;U0,X=!1,Q=!1,Z="";for(var K in d)if(d.hasOwnProperty(K)){var J=d[K],$=J.type.toLowerCase(),ee=J.baseName;Z+=" {\n";var te,re,ie="u_"+ee+"Color";"ambient"===$?(Q=!0,Z+=" ambientLight += "+ie+";\n"):x&&(X=!0,te="v_"+ee+"Direction",re="v_"+ee+"Position","point"!==$&&(A+="varying vec3 "+te+";\n",E+="varying vec3 "+te+";\n",B+=" "+te+" = mat3(u_"+ee+"Transform) * vec3(0.,0.,1.);\n","directional"===$&&(Z+=" vec3 l = normalize("+te+");\n")),"directional"!==$?(A+="varying vec3 "+re+";\n",E+="varying vec3 "+re+";\n",B+=" "+re+" = u_"+ee+"Transform[3].xyz;\n",Z+=" vec3 VP = "+re+" - v_positionEC;\n",Z+=" vec3 l = normalize(VP);\n",Z+=" float range = length(VP);\n",Z+=" float attenuation = 1.0 / (u_"+ee+"Attenuation.x + ",Z+="(u_"+ee+"Attenuation.y * range) + ",Z+="(u_"+ee+"Attenuation.z * range * range));\n"):Z+=" float attenuation = 1.0;\n","spot"===$&&(Z+=" float spotDot = dot(l, normalize("+te+"));\n",Z+=" if (spotDot < cos(u_"+ee+"FallOff.x * 0.5))\n",Z+=" {\n",Z+=" attenuation = 0.0;\n",Z+=" }\n",Z+=" else\n",Z+=" {\n",Z+=" attenuation *= max(0.0, pow(spotDot, u_"+ee+"FallOff.y));\n",Z+=" }\n"),Z+=" diffuseLight += "+ie+"* max(dot(normal,l), 0.) * attenuation;\n",Y&&("BLINN"===C?(Z+=" vec3 h = normalize(l + viewDir);\n",Z+=" float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n"):(Z+=" vec3 reflectDir = reflect(-l, normal);\n",Z+=" float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n"),Z+=" specularLight += "+ie+" * specularIntensity;\n")),Z+=" }\n"}if(Q||(Z+=" ambientLight += vec3(0.2, 0.2, 0.2);\n"),!X&&"CONSTANT"!==C){Z+=h?" vec3 l = normalize(czm_sunDirectionEC);\n":" vec3 l = vec3(0.0, 0.0, 1.0);\n";Z+=" diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal,l), "+(h?"0.2":"0.0")+");\n",Y&&("BLINN"===C?(Z+=" vec3 h = normalize(l + viewDir);\n",Z+=" float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n"):(Z+=" vec3 reflectDir = reflect(-l, normal);\n",Z+=" float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n"),Z+=" specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity;\n")}A+="void main(void) {\n",A+=B,A+="}\n",E+="void main(void) {\n";var ne=" vec3 color = vec3(0.0, 0.0, 0.0);\n";x&&(E+=" vec3 normal = normalize(v_normal);\n",i.doubleSided&&(E+=" if (gl_FrontFacing == false)\n",E+=" {\n",E+=" normal = -normal;\n",E+=" }\n"));var oe;"CONSTANT"!==C?(s(P.diffuse)&&(P.diffuse.type===u.SAMPLER_2D?E+=" vec4 diffuse = texture2D(u_diffuse, "+W+");\n":E+=" vec4 diffuse = u_diffuse;\n", -E+=" vec3 diffuseLight = vec3(0.0, 0.0, 0.0);\n",ne+=" color += diffuse.rgb * diffuseLight;\n"),Y&&(P.specular.type===u.SAMPLER_2D?E+=" vec3 specular = texture2D(u_specular, "+W+").rgb;\n":E+=" vec3 specular = u_specular.rgb;\n",E+=" vec3 specularLight = vec3(0.0, 0.0, 0.0);\n",ne+=" color += specular * specularLight;\n"),oe=s(P.transparency)?" gl_FragColor = vec4(color * diffuse.a * u_transparency, diffuse.a * u_transparency);\n":" gl_FragColor = vec4(color * diffuse.a, diffuse.a);\n"):oe=s(P.transparency)?" gl_FragColor = vec4(color * u_transparency, u_transparency);\n":" gl_FragColor = vec4(color, 1.0);\n",s(P.emission)&&(P.emission.type===u.SAMPLER_2D?E+=" vec3 emission = texture2D(u_emission, "+W+").rgb;\n":E+=" vec3 emission = u_emission.rgb;\n",ne+=" color += emission;\n"),(s(P.ambient)||"CONSTANT"!==C)&&(s(P.ambient)?P.ambient.type===u.SAMPLER_2D?E+=" vec3 ambient = texture2D(u_ambient, "+W+").rgb;\n":E+=" vec3 ambient = u_ambient.rgb;\n":E+=" vec3 ambient = diffuse.rgb;\n",ne+=" color += ambient * ambientLight;\n"),E+=" vec3 viewDir = -normalize(v_positionEC);\n",E+=" vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n",E+=Z,E+=ne,E+=oe,E+="}\n";var ae;ae=b.transparent?{enable:[u.DEPTH_TEST,u.BLEND],functions:{depthMask:[!1],blendEquationSeparate:[u.FUNC_ADD,u.FUNC_ADD],blendFuncSeparate:[u.ONE,u.ONE_MINUS_SRC_ALPHA,u.ONE,u.ONE_MINUS_SRC_ALPHA]}}:i.doubleSided?{enable:[u.DEPTH_TEST]}:{enable:[u.CULL_FACE,u.DEPTH_TEST]};var se=e(v,{type:u.VERTEX_SHADER,extras:{_pipeline:{source:A,extension:".glsl"}}}),le=e(v,{type:u.FRAGMENT_SHADER,extras:{_pipeline:{source:E,extension:".glsl"}}}),ue=Object.keys(H),ce=e(y,{attributes:ue,fragmentShader:le,vertexShader:se});return e(_,{attributes:H,parameters:P,program:ce,states:ae,uniforms:N})}function p(e,t){var r;switch(r=s(t.value)?t.value:s(t.index)?[t.index]:t,e){case"ambient":case"diffuse":case"emission":case"specular":return 1===r.length?u.SAMPLER_2D:u.FLOAT_VEC4;case"shininess":case"transparency":return u.FLOAT;case"transparent":case"doubleSided":return u.BOOL}}function f(e){var t="";t+="technique:"+e.technique+";";for(var r=e.values,i=Object.keys(r).sort(),n=i.length,o=0;o0){t+=e.extras._pipeline.skinning.type+";"}return t}function m(e){s(e.extensions)||(e.extensions={});var t=e.extensions;s(t.KHR_materials_common)||(t.KHR_materials_common={});var r=t.KHR_materials_common;s(r.lights)||(r.lights={});for(var i=r.lights,n=i.length,o=0;o=0||C.indexOf("Factor")>=0)||"doubleSided"===C)&&(y[C]=a[C]);var b,S="precision highp float;\n",w="precision highp float;\n";s(i.skins)&&(b=i.skins[0]);var T,A=s(b)?b.joints:[],E=A.length,x=a.extras._pipeline.skinning,P=s(x.type),D=!1,I=!1;t.mesh(i,function(e){t.meshPrimitive(e,function(e){var t=e.targets;!I&&s(t)&&(I=!0,T=t);var r=e.attributes;for(var i in r)i.indexOf("TANGENT")>=0&&(D=!0)})});var O={modelViewMatrix:{semantic:f?"CESIUM_RTC_MODELVIEW":"MODELVIEW",type:u.FLOAT_MAT4},projectionMatrix:{semantic:"PROJECTION",type:u.FLOAT_MAT4}};O.normalMatrix={semantic:"MODELVIEWINVERSETRANSPOSE",type:u.FLOAT_MAT3},P&&(O.jointMatrix={count:E,semantic:"JOINTMATRIX",type:u.FLOAT_MAT4}),I&&(O.morphWeights={count:T.length,semantic:"MORPHWEIGHTS",type:u.FLOAT});var M=!1;for(var R in y)if(y.hasOwnProperty(R)){var N=h(R);M||N!==u.SAMPLER_2D||(M=!0),O[R]={type:N}}var L={};for(var k in O)if(O.hasOwnProperty(k)&&"extras"!==k){var F=O[k];L["u_"+k]=k;var B=s(F.count)?"["+F.count+"]":"";F.type!==u.FLOAT_MAT3&&F.type!==u.FLOAT_MAT4&&"morphWeights"!==k||F.useInFragment?(w+="uniform "+n(F.type)+" u_"+k+B+";\n",delete F.useInFragment):S+="uniform "+n(F.type)+" u_"+k+B+";\n"}var U="";if(P){var V,z,G=r(x.type),H=!1;if(0===x.type.indexOf("MAT")&&(H=!0,G=Math.sqrt(G)),H)for(V=0;V= "+$+"));\n":w+=" gl_FragColor = vec4(color, 1.0);\n"}else w+="BLEND"===J?" gl_FragColor = vec4(color, baseColorWithAlpha.a);\n":" gl_FragColor = vec4(color, 1.0);\n";else w+=" gl_FragColor = vec4(color, 1.0);\n";w+="}\n";var ee;ee=s(J)&&"OPAQUE"!==J?{enable:[u.DEPTH_TEST,u.BLEND],functions:{depthMask:[!1],blendEquationSeparate:[u.FUNC_ADD,u.FUNC_ADD],blendFuncSeparate:[u.ONE,u.ONE_MINUS_SRC_ALPHA,u.ONE,u.ONE_MINUS_SRC_ALPHA]}}:y.doubleSided?{enable:[u.DEPTH_TEST]}:{enable:[u.CULL_FACE,u.DEPTH_TEST]};var te=e(_,{type:u.VERTEX_SHADER,extras:{_pipeline:{source:S,extension:".glsl"}}}),re=e(_,{type:u.FRAGMENT_SHADER,extras:{_pipeline:{source:w,extension:".glsl"}}}),ie=Object.keys(W),ne=e(v,{attributes:ie,fragmentShader:re,vertexShader:te});return e(g,{attributes:W,parameters:O,program:ne,states:ee,uniforms:L})}function h(e){switch(e){case"baseColorFactor":return u.FLOAT_VEC4;case"metallicFactor":case"roughnessFactor":return u.FLOAT;case"baseColorTexture":case"metallicRoughnessTexture":case"normalTexture":case"occlusionTexture":case"emissiveTexture":return u.SAMPLER_2D;case"emissiveFactor":return u.FLOAT_VEC3;case"doubleSided":return u.BOOL}}function p(e){return"SCALAR"===e?"float":e.toLowerCase()}function f(e,t){var r=e.accessors,n=e.materials,o=e.techniques,a=e.programs,l=e.shaders,u=t.targets,c=t.attributes;for(var d in u)if(s(d)){var h=u[d];for(var f in h)"extras"!==f&&(c[f+"_"+d]=h[f])}var m=n[t.material],g=o[m.technique],_=a[g.program],v=l[_.vertexShader];for(var y in c)if(c.hasOwnProperty(y)&&!s(i(g,y))){var C=c[y],b=r[C],S=y.toLowerCase();"_"===S.charAt(0)&&(S=S.slice(1));var w="a_"+S;g.parameters[S]={semantic:y,type:b.componentType},g.attributes[w]=S,_.attributes.push(w);var T=v.extras._pipeline,A=T.source;A="attribute "+p(b.type)+" "+w+";\n"+A,T.source=A}}function m(e){t.mesh(e,function(r){t.meshPrimitive(r,function(t){f(e,t)})})}function g(r){var i=r.accessors,n=r.materials;t.mesh(r,function(r){t.meshPrimitive(r,function(t){var r,o,l=t.material,u=n[l],c=t.attributes.JOINTS_0;if(s(c)){var d=i[c];r=d.componentType,o=d.type}var h=s(c),p=u.extras._pipeline.skinning;if(s(p)){if(p.skinned!==h||p.type!==o){var f=a(u,!0);f.material.extras._pipeline.skinning={skinned:h,componentType:r,type:o},l=e(n,f),t.material=l}}else u.extras._pipeline.skinning={skinned:h,componentType:r,type:o}})})}return c}),define("Scene/AttributeType",["../Core/freezeObject"],function(e){"use strict";return e({SCALAR:"SCALAR",VEC2:"VEC2",VEC3:"VEC3",VEC4:"VEC4",MAT2:"MAT2",MAT3:"MAT3",MAT4:"MAT4"})}),define("Scene/Axis",["../Core/Check","../Core/freezeObject","../Core/Math","../Core/Matrix3","../Core/Matrix4"],function(e,t,r,i,n){"use strict";var o={X:0,Y:1,Z:2,Y_UP_TO_Z_UP:n.fromRotationTranslation(i.fromRotationX(r.PI_OVER_TWO)),Z_UP_TO_Y_UP:n.fromRotationTranslation(i.fromRotationX(-r.PI_OVER_TWO)),X_UP_TO_Z_UP:n.fromRotationTranslation(i.fromRotationY(-r.PI_OVER_TWO)),Z_UP_TO_X_UP:n.fromRotationTranslation(i.fromRotationY(r.PI_OVER_TWO)),X_UP_TO_Y_UP:n.fromRotationTranslation(i.fromRotationZ(r.PI_OVER_TWO)),Y_UP_TO_X_UP:n.fromRotationTranslation(i.fromRotationZ(-r.PI_OVER_TWO)),fromName:function(e){return o[e]}};return t(o)}),define("Scene/getAttributeOrUniformBySemantic",["../Core/defined"],function(e){"use strict";function t(t,r){var i,n=t.techniques;for(var o in n)if(n.hasOwnProperty(o)){var a=n[o],s=a.parameters,l=a.attributes,u=a.uniforms;for(var c in l)if(l.hasOwnProperty(c)&&(i=s[l[c]],e(i)&&i.semantic===r))return c;for(var d in u)if(u.hasOwnProperty(d)&&(i=s[u[d]],e(i)&&i.semantic===r))return d}}return t}),define("Scene/JobType",["../Core/freezeObject"],function(e){"use strict";return e({TEXTURE:0,PROGRAM:1,BUFFER:2,NUMBER_OF_JOB_TYPES:3})}),define("Scene/ModelAnimationCache",["./AttributeType","../Core/Cartesian3","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/LinearSpline","../Core/Matrix4","../Core/Quaternion","../Core/QuaternionSpline","../Core/WebGLConstants","../Core/WeightSpline","../ThirdParty/GltfPipeline/getAccessorByteStride","../ThirdParty/GltfPipeline/numberOfComponentsForType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(){}function f(e,t){var r=e.gltf,i=r.buffers,n=r.bufferViews,o=n[t.bufferView],a=i[o.buffer],s=o.byteOffset+t.byteOffset,l=t.count*h(t.type),u=_.test(a.uri)?"":a.uri;return e.cacheKey+"//"+u+"/"+s+"/"+l}function m(e,t,r){return e.cacheKey+"//"+t+"/"+r}function g(e){this._value=e}var _=/^data\:/i,v={};p.getAnimationParameterValues=function(e,o){var a=f(e,o),l=v[a];if(!n(l)){var u=e.gltf,c=u.buffers,p=u.bufferViews,m=p[o.bufferView],g=m.buffer,_=c[g],y=_.extras._pipeline.source,C=o.componentType,b=o.type,S=h(b),w=o.count,T=d(u,o);l=new Array(w);for(var A=i(o.byteOffset,0),E=m.byteOffset+A,x=0;x=0,w=g.loop===l.REPEAT||g.loop===l.MIRRORED_REPEAT;if((S||w&&!t(g.startTime))&&(b<=1||w)&&(!t(C)||o.lessThanOrEquals(c,C))){if(g._state===u.STOPPED&&(g._state=u.ANIMATING,g.start.numberOfListeners>0&&r.afterRender.push(g._raiseStartEvent)),g.loop===l.REPEAT)b-=Math.floor(b);else if(g.loop===l.MIRRORED_REPEAT){var T=Math.floor(b),A=b-T;b=T%2==1?1-A:A}g.reverse&&(b=1-b);var E=b*y*g.speedup;E=a.clamp(E,_.startTime,_.stopTime),h(_,E),g.update.numberOfListeners>0&&(g._updateEventTime=E,r.afterRender.push(g._raiseUpdateEvent)),s=!0}else S&&g._state===u.ANIMATING&&(g._state=u.STOPPED,g.stop.numberOfListeners>0&&r.afterRender.push(g._raiseStopEvent),g.removeOnStop&&f.push(g))}n=f.length;for(var x=0;x0;){p=l.pop();var f=p._transformToRoot,m=p.mesh;if(u(m))for(var g=o[m],_=g.primitives,v=_.length,y=0;y0&&(jr.set(o.peek(),e,n),t.jobScheduler.execute(jr,fe.BUFFER));)o.dequeue();for(;a.length>0&&(i=a.peek(),qr.set(i.id,i.componentType,e,n),t.jobScheduler.execute(qr,fe.BUFFER));)a.dequeue()}else{for(;o.length>0;)Xe(o.dequeue(),e,n);for(;a.length>0;)i=a.dequeue(),Qe(i.id,i.componentType,e,n)}}}function Ke(e,t){var r,i={},n=t.length;for(r=1;r2?"vec"+(y-1):"float",e=C+" "+v+";\n"+e;var b="";5===y?(e="uniform mat4 "+p+";\n"+e,e="uniform vec4 "+f+";\n"+e,b="\nvoid main() {\n "+v+" = "+p+" * "+c+" + "+f+";\n "+_+"();\n}\n",n[p]={mat:4},n[f]={vec:4}):(e="uniform mat"+y+" "+h+";\n"+e,b="\nvoid main() {\n "+v+" = "+C+"("+h+" * vec"+y+"("+c+",1.0));\n "+_+"();\n}\n",n[h]={mat:y}),e=q.replaceMain(e,_),e+=b}}}}return r._programPrimitives[t]=void 0,e}function it(e){var t=e.gltf;return!!u(t.asset)&&l(t.asset.premultipliedAlpha,!1)}function nt(e,t){return e=q.replaceMain(e,"gltf_blend_main"),e+="uniform vec4 gltf_color; \nuniform float gltf_colorBlend; \nvoid main() \n{ \n gltf_blend_main(); \n",t&&(e+=" float alpha = 1.0 - ceil(gl_FragColor.a) + gl_FragColor.a; \n gl_FragColor.rgb /= alpha; \n"),e+=" gl_FragColor.rgb = mix(gl_FragColor.rgb, gltf_color.rgb, gltf_colorBlend); \n float highlight = ceil(gltf_colorBlend); \n gl_FragColor.rgb *= mix(gltf_color.rgb, vec3(1.0), highlight); \n gl_FragColor.a *= gltf_color.a; \n} \n"}function ot(e,t,r){return u(r)&&(e=r(e,t)),e}function at(e,t,r){var i=t.gltf.programs,n=t.gltf.shaders,o=i[e],a=Ke(t,o.attributes),s=n[o.vertexShader].extras._pipeline.source,l=n[o.fragmentShader].extras._pipeline.source,c=o.attributes.length,d=t._precreatedAttributes;if(u(d))for(var h in d)d.hasOwnProperty(h)&&(a[h]=c++);t.extensionsUsed.WEB3D_quantized_attributes&&(s=rt(s,e,t,r));var p=it(t),m=nt(l,p);f.isInternetExplorer()||(m=yr(m));var g=ot(s,e,t._vertexShaderLoaded),_=ot(m,e,t._fragmentShaderLoaded);if(t._rendererResources.programs[e]=j.fromCache({context:r,vertexShaderSource:g,fragmentShaderSource:_,attributeLocations:a}),t.allowPicking){var v=ot(s,e,t._pickVertexShaderLoaded),y=ot(l,e,t._pickFragmentShaderLoaded);t._pickFragmentShaderLoaded||(y=q.createPickFragmentShaderSource(l,"uniform")),t._rendererResources.pickPrograms[e]=j.fromCache({context:r,vertexShaderSource:v,fragmentShaderSource:y,attributeLocations:a})}}function st(e,t){var r=e._loadResources,i=r.programsToCreate;if(0===r.pendingShaderLoads&&0===r.pendingBufferLoads){var n=t.context;if(e.asynchronous)for(;i.length>0&&(Xr.set(i.peek(),e,n),t.jobScheduler.execute(Xr,fe.PROGRAM));)i.dequeue();else for(;i.length>0;)at(i.dequeue(),e,n)}}function lt(e,t){return function(r){e.texturesToCreate.enqueue({id:t.id,image:r,bufferView:void 0}),--e.pendingBufferViewToImage}}function ut(e){var t=e._loadResources;if(0===t.pendingBufferLoads)for(;t.texturesToCreateFromBufferView.length>0;){var r=t.texturesToCreateFromBufferView.dequeue(),i=e.gltf,n=i.bufferViews[r.bufferView],o=i.textures[r.id].source,a=Me(e,"image","id: "+r.id+", bufferView: "+r.bufferView);if("image/ktx"===r.mimeType)A(t.getBuffer(n)).then(Ve(e,r.id,o)).otherwise(a),++e._loadResources.pendingTextureLoads;else if("image/crn"===r.mimeType)S(t.getBuffer(n)).then(Ve(e,r.id,o)).otherwise(a),++e._loadResources.pendingTextureLoads;else{var s=lt(t,r);T(t.getBuffer(n),r.mimeType).then(s).otherwise(a),++t.pendingBufferViewToImage}}}function ct(e,t){var r=e._loadResources;if(r.createSamplers){r.createSamplers=!1;var i=e._rendererResources.samplers,n=e.gltf.samplers;for(var o in n)if(n.hasOwnProperty(o)){var a=n[o];i[o]=new W({wrapS:a.wrapS,wrapT:a.wrapT,minificationFilter:a.minFilter,magnificationFilter:a.magFilter})}}}function dt(e,t,r){var i=t.gltf.textures,n=i[e.id],o=t._rendererResources.samplers,a=o[n.sampler];a=l(a,new W({wrapS:Q.REPEAT,wrapT:Q.REPEAT}));var s,c=e.internalFormat,d=!(u(c)&&O.isCompressedFormat(c)||a.minificationFilter!==X.NEAREST_MIPMAP_NEAREST&&a.minificationFilter!==X.NEAREST_MIPMAP_LINEAR&&a.minificationFilter!==X.LINEAR_MIPMAP_NEAREST&&a.minificationFilter!==X.LINEAR_MIPMAP_LINEAR),h=d||a.wrapS===Q.REPEAT||a.wrapS===Q.MIRRORED_REPEAT||a.wrapT===Q.REPEAT||a.wrapT===Q.MIRRORED_REPEAT,p=e.image;if(u(c)&&n.target===B.TEXTURE_2D)s=new Y({context:r,source:{arrayBufferView:e.bufferView},width:e.width,height:e.height,pixelFormat:c,sampler:a});else if(u(p)){var f=!x.isPowerOfTwo(p.width)||!x.isPowerOfTwo(p.height);if(h&&f){var m=document.createElement("canvas");m.width=x.nextPowerOfTwo(p.width),m.height=x.nextPowerOfTwo(p.height);var g=m.getContext("2d");g.drawImage(p,0,0,p.width,p.height,0,0,m.width,m.height),p=m}n.target===B.TEXTURE_2D&&(s=new Y({context:r,source:p,pixelFormat:n.internalFormat,pixelDatatype:n.type,sampler:a,flipY:!1}),d&&s.generateMipmap())}u(s)&&(t._rendererResources.textures[e.id]=s,t._texturesByteLength+=s.sizeInBytes)}function ht(e,t){var r=t.context,i=e._loadResources.texturesToCreate;if(e.asynchronous)for(;i.length>0&&(Zr.set(i.peek(),e,r),t.jobScheduler.execute(Zr,fe.TEXTURE));)i.dequeue();else for(;i.length>0;)dt(i.dequeue(),e,r)}function pt(e,t){var r,i,n=e.gltf,o=n.techniques,a=n.materials,s={},l=o[a[t.material].technique],c=l.parameters,d=l.attributes,h=e._rendererResources.programs[l.program],p=h.vertexAttributes,f=h._attributeLocations;for(r in p)if(p.hasOwnProperty(r)){var m=d[r];if(i=p[r].index,u(m)){var g=c[m];s[g.semantic]=i}}var _=e._precreatedAttributes;if(u(_))for(r in _)_.hasOwnProperty(r)&&(i=f[r],s[r]=i);return s}function ft(e,t){for(var r=e.length,i={},n=0;n0;){var a=o.pop(),s=t[a];u(s)&&(i[a]=a);for(var l=s.children,c=l.length,d=0;d0;){var v=f.pop();m[v.id]=!0;var y=v.parentRuntimeNode,C=v.gltfNode,b=a[v.id];if(0===b.parents.length)if(u(C.matrix))b.matrix=I.fromColumnMajorArray(C.matrix);else{var S=C.rotation;b.translation=r.fromArray(C.translation),b.rotation=N.unpack(S),b.scale=r.fromArray(C.scale)}u(y)?(y.children.push(b),b.parents.push(y)):o.push(b),u(C.mesh)&&Qt(e,C,b,t,i);for(var w=C.children,T=w.length,A=0;A0;){v=h.pop();var y=v.transformToRoot,C=v.commands;if(v.dirtyNumber===s||n||o){var b=I.multiplyTransformation(p,y,v.computedMatrix),S=C.length;if(S>0)for(var w=0;w0;){o=i.pop();for(var a=o.computedShow,s=o.commands,l=s.length,u=0;u0&&i<1){var n=e._nodeCommands,o=n.length;if(!u(n[0].translucentCommand))for(var a=0;a0&&e.silhouetteColor.alpha>0&&u(e._normalAttributeName)}function fr(e){for(var t=e._nodeCommands,r=t.length,i=0;i0&&e.color.alpha<1}function gr(e){return 0===e.color.alpha}function _r(e,t){return Math.floor(e)!==Math.floor(t)||Math.ceil(e)!==Math.ceil(t)}function vr(e,t){for(var r=++oi%255,i=fr(e)||mr(e)||e.silhouetteColor.alpha<1,n=e._rendererResources.silhouettePrograms,a=t.scene3DOnly,l=e._nodeCommands,c=l.length,d=0;d 0) \n { \n float clipDistance; \n if (gltf_clippingPlanesUnionRegions) \n { \n clipDistance = czm_discardIfClippedWithUnion(gltf_clippingPlanes, gltf_clippingPlanesLength); \n } \n else \n { \n clipDistance = czm_discardIfClippedWithIntersect(gltf_clippingPlanes, gltf_clippingPlanesLength); \n } \n \n vec4 clippingPlanesEdgeColor = vec4(1.0); \n clippingPlanesEdgeColor.rgb = gltf_clippingPlanesEdgeStyle.rgb; \n float clippingPlanesEdgeWidth = gltf_clippingPlanesEdgeStyle.a; \n if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n { \n gl_FragColor = clippingPlanesEdgeColor; \n } \n } \n} \n"}function Cr(e,t){if(pr(e,t)){var r=e._nodeCommands,i=_r(e.color.alpha,e._colorPreviousAlpha)||_r(e.silhouetteColor.alpha,e._silhouetteColorPreviousAlpha)||!u(r[0].silhouetteModelCommand);e._colorPreviousAlpha=e.color.alpha,e._silhouetteColorPreviousAlpha=e.silhouetteColor.alpha,i&&vr(e,t)}}function br(e){var t=e.clippingPlanes,r=0;u(t)&&t.enabled&&(r=t.length);var n=e._packedClippingPlanes,o=n.length;if(o!==r){n.length=r;for(var a=o;a=o&&i<=a}if(!f.supportsTypedArrays())return{};var Rr=new r,Nr={NEEDS_LOAD:0,LOADING:1,LOADED:2,FAILED:3};Se.prototype.getBuffer=function(e){return xe(this.buffers[e.buffer],e.byteOffset,e.byteLength)},Se.prototype.finishedPendingBufferLoads=function(){return 0===this.pendingBufferLoads},Se.prototype.finishedBuffersCreation=function(){return 0===this.pendingBufferLoads&&0===this.vertexBuffersToCreate.length&&0===this.indexBuffersToCreate.length},Se.prototype.finishedProgramCreation=function(){return 0===this.pendingShaderLoads&&0===this.programsToCreate.length},Se.prototype.finishedTextureCreation=function(){var e=0===this.pendingTextureLoads,t=0===this.texturesToCreate.length&&0===this.texturesToCreateFromBufferView.length;return e&&t},Se.prototype.finishedEverythingButTextureCreation=function(){var e=0===this.pendingBufferLoads&&0===this.pendingShaderLoads,t=0===this.vertexBuffersToCreate.length&&0===this.indexBuffersToCreate.length&&0===this.programsToCreate.length&&0===this.pendingBufferViewToImage;return e&&t},Se.prototype.finished=function(){return this.finishedTextureCreation()&&this.finishedEverythingButTextureCreation()},c(Te.prototype,{gltf:{set:function(e){this._gltf=e},get:function(){return this._gltf}}}),Te.prototype.makeReady=function(e){this.gltf=e;for(var t=this.modelsToLoad,r=t.length,i=0;iG||F.center.y-F.radiusG||F.center.y-F.radiusG||F.center.y-F.radius-1;i--)m(this,e[i],t,r);return n(this)},f.prototype.getBoundingSphere=function(e,r){var n=this._modelHash[e.id];if(!i(n))return h.FAILED;var o=n.modelPrimitive;if(!i(o)||!o.show)return h.FAILED;if(!o.ready)return h.PENDING;if(o.heightReference===l.NONE)t.transform(o.boundingSphere,o.modelMatrix,r);else{if(!i(o._clampedModelMatrix))return h.PENDING;t.transform(o.boundingSphere,o._clampedModelMatrix,r)}return h.DONE},f.prototype._onCollectionChanged=function(e,t,r,n){var o,a,s=this._entitiesToVisualize,l=this._modelHash,u=this._primitives;for(o=t.length-1;o>-1;o--)a=t[o],i(a._model)&&i(a._position)&&s.set(a.id,a);for(o=n.length-1;o>-1;o--)a=n[o],i(a._model)&&i(a._position)?(g(a,l),s.set(a.id,a)):(m(this,a,l,u),s.remove(a.id));for(o=r.length-1;o>-1;o--)a=r[o],m(this,a,l,u),s.remove(a.id)},f}),define("Shaders/PolylineCommon",[],function(){"use strict";return"void clipLineSegmentToNearPlane(\nvec3 p0,\nvec3 p1,\nout vec4 positionWC,\nout bool clipped,\nout bool culledByNearPlane)\n{\nculledByNearPlane = false;\nclipped = false;\nvec3 p1ToP0 = p1 - p0;\nfloat magnitude = length(p1ToP0);\nvec3 direction = normalize(p1ToP0);\nfloat endPoint0Distance = -(czm_currentFrustum.x + p0.z);\nfloat denominator = -direction.z;\nif (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7)\n{\nculledByNearPlane = true;\n}\nelse if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7)\n{\nfloat t = (czm_currentFrustum.x + p0.z) / denominator;\nif (t < 0.0 || t > magnitude)\n{\nculledByNearPlane = true;\n}\nelse\n{\np0 = p0 + t * direction;\nclipped = true;\n}\n}\npositionWC = czm_eyeToWindowCoordinates(vec4(p0, 1.0));\n}\nvec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle) {\nvec4 endPointWC, p0, p1;\nbool culledByNearPlane, clipped;\nvec4 positionEC = czm_modelViewRelativeToEye * position;\nvec4 prevEC = czm_modelViewRelativeToEye * previous;\nvec4 nextEC = czm_modelViewRelativeToEye * next;\nvec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);\nvec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);\nvec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);\n#ifdef POLYLINE_DASH\nvec2 lineDir;\nif (usePrevious) {\nlineDir = normalize(positionWindow.xy - previousWindow.xy);\n}\nelse {\nlineDir = normalize(nextWindow.xy - positionWindow.xy);\n}\nangle = atan(lineDir.x, lineDir.y) - 1.570796327;\nangle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;\n#endif\nclipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane);\nclipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane);\nclipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane);\nif (culledByNearPlane)\n{\nreturn vec4(0.0, 0.0, 0.0, 1.0);\n}\nvec2 prevWC = normalize(p0.xy - endPointWC.xy);\nvec2 nextWC = normalize(p1.xy - endPointWC.xy);\nfloat expandWidth = width * 0.5;\nvec2 direction;\nif (czm_equalsEpsilon(previous.xyz - position.xyz, vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))\n{\ndirection = vec2(-nextWC.y, nextWC.x);\n}\nelse if (czm_equalsEpsilon(next.xyz - position.xyz, vec3(0.0), czm_epsilon1) || clipped)\n{\ndirection = vec2(prevWC.y, -prevWC.x);\n}\nelse\n{\nvec2 normal = vec2(-nextWC.y, nextWC.x);\ndirection = normalize((nextWC + prevWC) * 0.5);\nif (dot(direction, normal) < 0.0)\n{\ndirection = -direction;\n}\nfloat sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);\nexpandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);\n}\nvec2 offset = direction * expandDirection * expandWidth * czm_resolutionScale;\nreturn vec4(endPointWC.xy + offset, -endPointWC.z, 1.0);\n}\n"}),define("Shaders/PolylineFS",[],function(){"use strict";return"varying vec2 v_st;\nvoid main()\n{\nczm_materialInput materialInput;\nmaterialInput.s = v_st.s;\nmaterialInput.st = v_st;\nmaterialInput.str = vec3(v_st, 0.0);\nczm_material material = czm_getMaterial(materialInput);\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n}\n"}),define("Shaders/PolylineVS",[],function(){"use strict" -;return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 position2DHigh;\nattribute vec3 position2DLow;\nattribute vec3 prevPosition3DHigh;\nattribute vec3 prevPosition3DLow;\nattribute vec3 prevPosition2DHigh;\nattribute vec3 prevPosition2DLow;\nattribute vec3 nextPosition3DHigh;\nattribute vec3 nextPosition3DLow;\nattribute vec3 nextPosition2DHigh;\nattribute vec3 nextPosition2DLow;\nattribute vec4 texCoordExpandAndBatchIndex;\nvarying vec2 v_st;\nvarying float v_width;\nvarying vec4 czm_pickColor;\nvarying float v_polylineAngle;\nvoid main()\n{\nfloat texCoord = texCoordExpandAndBatchIndex.x;\nfloat expandDir = texCoordExpandAndBatchIndex.y;\nbool usePrev = texCoordExpandAndBatchIndex.z < 0.0;\nfloat batchTableIndex = texCoordExpandAndBatchIndex.w;\nvec2 widthAndShow = batchTable_getWidthAndShow(batchTableIndex);\nfloat width = widthAndShow.x + 0.5;\nfloat show = widthAndShow.y;\nif (width < 1.0)\n{\nshow = 0.0;\n}\nvec4 pickColor = batchTable_getPickColor(batchTableIndex);\nvec4 p, prev, next;\nif (czm_morphTime == 1.0)\n{\np = czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz);\nprev = czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz);\nnext = czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz);\n}\nelse if (czm_morphTime == 0.0)\n{\np = czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy);\nprev = czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy);\nnext = czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy);\n}\nelse\n{\np = czm_columbusViewMorph(\nczm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy),\nczm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz),\nczm_morphTime);\nprev = czm_columbusViewMorph(\nczm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy),\nczm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz),\nczm_morphTime);\nnext = czm_columbusViewMorph(\nczm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy),\nczm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz),\nczm_morphTime);\n}\n#ifdef DISTANCE_DISPLAY_CONDITION\nvec3 centerHigh = batchTable_getCenterHigh(batchTableIndex);\nvec4 centerLowAndRadius = batchTable_getCenterLowAndRadius(batchTableIndex);\nvec3 centerLow = centerLowAndRadius.xyz;\nfloat radius = centerLowAndRadius.w;\nvec2 distanceDisplayCondition = batchTable_getDistanceDisplayCondition(batchTableIndex);\nfloat lengthSq;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nlengthSq = czm_eyeHeight2D.y;\n}\nelse\n{\nvec4 center = czm_translateRelativeToEye(centerHigh.xyz, centerLow.xyz);\nlengthSq = max(0.0, dot(center.xyz, center.xyz) - radius * radius);\n}\nfloat nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x;\nfloat farSq = distanceDisplayCondition.y * distanceDisplayCondition.y;\nif (lengthSq < nearSq || lengthSq > farSq)\n{\nshow = 0.0;\n}\n#endif\nvec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\ngl_Position = czm_viewportOrthographic * positionWC * show;\nv_st = vec2(texCoord, clamp(expandDir, 0.0, 1.0));\nv_width = width;\nczm_pickColor = pickColor;\n}\n"}),define("Scene/Polyline",["../Core/arrayRemoveDuplicates","../Core/BoundingSphere","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Matrix4","../Core/PolylinePipeline","./Material"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(a,s){a=n(a,n.EMPTY_OBJECT),this._show=n(a.show,!0),this._width=n(a.width,1),this._loop=n(a.loop,!1),this._distanceDisplayCondition=a.distanceDisplayCondition,this._material=a.material,o(this._material)||(this._material=d.fromType(d.ColorType,{color:new i(1,1,1,1)}));var l=a.positions;o(l)||(l=[]),this._positions=l,this._actualPositions=e(l,r.equalsEpsilon),this._loop&&this._actualPositions.length>2&&(this._actualPositions===this._positions&&(this._actualPositions=l.slice()),this._actualPositions.push(r.clone(this._actualPositions[0]))),this._length=this._actualPositions.length,this._id=a.id;var h;o(s)&&(h=u.clone(s.modelMatrix)),this._modelMatrix=h,this._segments=c.wrapLongitude(this._actualPositions,h),this._actualLength=void 0,this._propertiesChanged=new Uint32Array(C),this._polylineCollection=s,this._dirty=!1,this._pickId=void 0,this._boundingVolume=t.fromPoints(this._actualPositions),this._boundingVolumeWC=t.transform(this._boundingVolume,this._modelMatrix),this._boundingVolume2D=new t}function p(e,t){++e._propertiesChanged[t];var r=e._polylineCollection;o(r)&&(r._updatePolyline(e,t),e._dirty=!0)}var f=h.POSITION_INDEX=0,m=h.SHOW_INDEX=1,g=h.WIDTH_INDEX=2,_=h.MATERIAL_INDEX=3,v=h.POSITION_SIZE_INDEX=4,y=h.DISTANCE_DISPLAY_CONDITION=5,C=h.NUMBER_OF_PROPERTIES=6;return a(h.prototype,{show:{get:function(){return this._show},set:function(e){e!==this._show&&(this._show=e,p(this,m))}},positions:{get:function(){return this._positions},set:function(i){var n=e(i,r.equalsEpsilon);this._loop&&n.length>2&&(n===i&&(n=i.slice()),n.push(r.clone(n[0]))),this._actualPositions.length===n.length&&this._actualPositions.length===this._length||p(this,v),this._positions=i,this._actualPositions=n,this._length=n.length,this._boundingVolume=t.fromPoints(this._actualPositions,this._boundingVolume),this._boundingVolumeWC=t.transform(this._boundingVolume,this._modelMatrix,this._boundingVolumeWC),p(this,f),this.update()}},material:{get:function(){return this._material},set:function(e){this._material!==e&&(this._material=e,p(this,_))}},width:{get:function(){return this._width},set:function(e){e!==this._width&&(this._width=e,p(this,g))}},loop:{get:function(){return this._loop},set:function(e){if(e!==this._loop){var t=this._actualPositions;e?t.length>2&&!r.equals(t[0],t[t.length-1])&&(t.length===this._positions.length&&(this._actualPositions=t=this._positions.slice()),t.push(r.clone(t[0]))):t.length>2&&r.equals(t[0],t[t.length-1])&&(t.length-1===this._positions.length?this._actualPositions=this._positions:t.pop()),this._loop=e,p(this,v)}}},id:{get:function(){return this._id},set:function(e){this._id=e,o(this._pickId)&&(this._pickId.object.id=e)}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){l.equals(e,this._distanceDisplayCondition)||(this._distanceDisplayCondition=l.clone(e,this._distanceDisplayCondition),p(this,y))}}}),h.prototype.update=function(){var e=u.IDENTITY;o(this._polylineCollection)&&(e=this._polylineCollection.modelMatrix);var r=this._segments.positions.length,i=this._segments.lengths,n=this._propertiesChanged[f]>0||this._propertiesChanged[v]>0;if(u.equals(e,this._modelMatrix)&&!n||(this._segments=c.wrapLongitude(this._actualPositions,e),this._boundingVolumeWC=t.transform(this._boundingVolume,e,this._boundingVolumeWC)),this._modelMatrix=u.clone(e,this._modelMatrix),this._segments.positions.length!==r)p(this,v);else for(var a=i.length,s=0;s0){var F=A.isTranslucent();c>=u?(E=new S({owner:t}),i.push(E)):E=i[c],++c,E.boundingVolume=e.clone(ce,E.boundingVolume),E.modelMatrix=n,E.shaderProgram=D,E.vertexArray=v.va,E.renderState=F?t._translucentRS:t._opaqueRS,E.pass=F?w.TRANSLUCENT:w.OPAQUE,E.debugShowBoundingVolume=!!o&&p,E.uniformMap=m(A._uniforms),E.count=M,E.offset=P,P+=M,M=0,d=!0,s.push(E)}A=N._material,A.update(a),T=L}for(var B=N._locatorBuckets,U=B.length,V=0;V0&&(c>=u?(E=new S({owner:t}),i.push(E)):E=i[c],++c,E.boundingVolume=e.clone(ce,E.boundingVolume),E.modelMatrix=n,E.shaderProgram=D,E.vertexArray=v.va,E.renderState=A.isTranslucent()?t._translucentRS:t._opaqueRS,E.pass=A.isTranslucent()?w.TRANSLUCENT:w.OPAQUE,E.debugShowBoundingVolume=!!o&&p,E.uniformMap=m(A._uniforms),E.count=M,E.offset=P,d=!0,s.push(E)),T=void 0}i.length=c}function V(e){var t=!1,r=e._propertiesChanged,i=e._positionBufferUsage;return r[te]?i.bufferUsage!==C.STREAM_DRAW?(t=!0,i.bufferUsage=C.STREAM_DRAW,i.frameCount=100):i.frameCount=100:i.bufferUsage!==C.STATIC_DRAW&&(0===i.frameCount?(t=!0,i.bufferUsage=C.STATIC_DRAW):i.frameCount--),t}function z(e,t,r){e._createVertexArray=!1,Y(e),X(e),W(e);var i,n,o=[[]],s=o[0],u=e._batchTable,c=[0],d=0,h=[[]],f=0,g=e._polylineBuckets;for(i in g)g.hasOwnProperty(i)&&(n=g[i],n.updateShader(t,u),f+=n.lengthOfPositions);if(f>0){var _,v=e._mode,b=new Float32Array(6*f*3),S=new Float32Array(4*f),w=0,T=0,A=0;for(i in g)if(g.hasOwnProperty(i)){n=g[i],n.write(b,S,w,T,A,u,t,r),v===k.MORPHING&&(l(_)||(_=new Float32Array(6*f*3)),n.writeForMorph(_,w));var E=n.lengthOfPositions;w+=6*E*3,T+=4*E,A+=4*E,d=n.updateIndices(o,c,h,d)}var x=e._positionBufferUsage.bufferUsage,D=C.STATIC_DRAW;e._positionBuffer=y.createVertexBuffer({context:t,typedArray:b,usage:x});var I;l(_)&&(I=y.createVertexBuffer({context:t,typedArray:_,usage:x})),e._texCoordExpandAndBatchIndexBuffer=y.createVertexBuffer({context:t,typedArray:S,usage:D});for(var O=3*Float32Array.BYTES_PER_ELEMENT,M=4*Float32Array.BYTES_PER_ELEMENT,R=0,N=o.length,L=0;L0){var F=new Uint16Array(s),B=y.createIndexBuffer({context:t,typedArray:F,usage:C.STATIC_DRAW,indexDatatype:p.UNSIGNED_SHORT});R+=c[L];var U,V,z,G,H=6*(L*(O*m.SIXTY_FOUR_KILOBYTES)-R*O),j=O+H,q=O+j,Q=O+q,Z=O+Q,K=O+Z,J=L*(M*m.SIXTY_FOUR_KILOBYTES)-R*M,$=[{index:ae.position3DHigh,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:H,strideInBytes:6*O},{index:ae.position3DLow,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:j,strideInBytes:6*O},{index:ae.position2DHigh,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:H,strideInBytes:6*O},{index:ae.position2DLow,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:j,strideInBytes:6*O},{index:ae.prevPosition3DHigh,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:q,strideInBytes:6*O},{index:ae.prevPosition3DLow,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:Q,strideInBytes:6*O},{index:ae.prevPosition2DHigh,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:q,strideInBytes:6*O},{index:ae.prevPosition2DLow,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:Q,strideInBytes:6*O},{index:ae.nextPosition3DHigh,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:Z,strideInBytes:6*O},{index:ae.nextPosition3DLow,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:K,strideInBytes:6*O},{index:ae.nextPosition2DHigh,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:Z,strideInBytes:6*O},{index:ae.nextPosition2DLow,componentsPerAttribute:3,componentDatatype:a.FLOAT,offsetInBytes:K,strideInBytes:6*O},{index:ae.texCoordExpandAndBatchIndex,componentsPerAttribute:4,componentDatatype:a.FLOAT,vertexBuffer:e._texCoordExpandAndBatchIndexBuffer,offsetInBytes:J}];v===k.SCENE3D?(U=e._positionBuffer,V="vertexBuffer",z=he,G="value"):v===k.SCENE2D||v===k.COLUMBUS_VIEW?(U=he,V="value",z=e._positionBuffer,G="vertexBuffer"):(U=I,V="vertexBuffer",z=e._positionBuffer,G="vertexBuffer"),$[0][V]=U,$[1][V]=U,$[2][G]=z,$[3][G]=z,$[4][V]=U,$[5][V]=U,$[6][G]=z,$[7][G]=z,$[8][V]=U,$[9][V]=U,$[10][G]=z,$[11][G]=z;var ee=new P({context:t,attributes:$,indexBuffer:B});e._vertexArrays.push({va:ee,buckets:h[L]})}}}function G(e,t){return t instanceof x?t.id:t}function H(e){var t=N._uniformList[e.type],r=t.length;pe.length=2*r;for(var i=0,n=0;n1){s.update();var u=s.material,c=i[u.type];l(c)||(c=i[u.type]=new K(u,t,r)),c.addPolyline(s)}}}function j(e,t){var r=t.mode;e._mode===r&&g.equals(e._modelMatrix,e.modelMatrix)||(e._mode=r,e._modelMatrix=g.clone(e.modelMatrix),e._createVertexArray=!0)}function q(e){if(e._polylinesRemoved){e._polylinesRemoved=!1;for(var t=[],r=e._polylines.length,i=0,n=0;i2){if(a[te]||a[ie]){var C=e.mode===k.SCENE2D?r._boundingVolume2D:r._boundingVolumeWC,S=h.fromCartesian(C.center,se),w=i.fromElements(S.low.x,S.low.y,S.low.z,C.radius,le);this._batchTable.setBatchedAttribute(r._index,2,S.high),this._batchTable.setBatchedAttribute(r._index,3,w)}if(a[ne]){var A=ue;A.x=0,A.y=Number.MAX_VALUE;var E=r.distanceDisplayCondition;l(E)&&(A.x=E.near,A.y=E.far),this._batchTable.setBatchedAttribute(r._index,4,A)}}r._clean()}s.length=0,this._polylinesUpdated=!1}a=this._propertiesChanged;for(var x=0;x0,w=C._index,T=this.getSegments(C,d),A=T.positions,E=T.lengths,x=A.length,P=C.getPickId(c).color,D=0,I=0,O=0;O0||fe.x>0&&me.x<0)&&r.clone(fe,me),(fe.x<0&&ge.x>0||fe.x>0&&ge.x<0)&&r.clone(fe,ge));for(var L=R?2:0,F=N?2:4,B=L;B2&&(u.setBatchedAttribute(w,2,W),u.setBatchedAttribute(w,3,j),u.setBatchedAttribute(w,4,q))}};var Ce=new r,be=new r,Se=new r,we=new r;K.prototype.writeForMorph=function(e,t){for(var i=this.modelMatrix,n=this.polylines,o=n.length,a=0;a0&&(l=s[s.length-1]+1);for(var u=this.polylines,c=u.length,d=0;d0))continue;p[0]=f}else p=h._segments.lengths;var g=p.length;if(g>0){for(var _=0,v=0;vm.SIXTY_FOUR_KILOBYTES&&(h._locatorBuckets.push({locator:o,count:_}),_=0,t.push(4),s=[],e.push(s),l=0,o.count=a,a=0,i=0,o=new Z(0,0,this),r[++n]=[o]),s.push(l,l+2,l+1),s.push(l+1,l+2,l+3),_+=6,a+=6,i+=6,l+=4;h._locatorBuckets.push({locator:o,count:_}),l+4>m.SIXTY_FOUR_KILOBYTES&&(t.push(0),s=[],e.push(s),l=0,o.count=a,i=0,a=0,o=new Z(0,0,this),r[++n]=[o])}h._clean()}return o.count=a,i},K.prototype.getPolylineStartIndex=function(e){for(var t=this.polylines,r=0,i=t.length,n=0;n0){t._boundingVolume2D=e.fromPoints(s,t._boundingVolume2D);var h=t._boundingVolume2D.center;t._boundingVolume2D.center=new r(h.z,h.x,h.y)}return Ae.positions=s,Ae.lengths=t._segments.lengths,Ae};var De;return K.prototype.writeUpdate=function(e,t,i,n){var o=this.mode,a=n.ellipsoid.maximumRadius*m.PI,s=t._actualLength;if(s){e+=this.getPolylineStartIndex(t);var u=De,c=6*s*3;!l(u)||u.lengthc&&(u=new Float32Array(u.buffer,0,c));var d,p=this.getSegments(t,n),f=p.positions,g=p.lengths,_=0,v=0,y=0;s=f.length;for(var C=0;C0||fe.x>0&&me.x<0)&&r.clone(fe,me),(fe.x<0&&ge.x>0||fe.x>0&&ge.x<0)&&r.clone(fe,ge));for(var T=S?2:0,A=w?2:4,E=T;E0&&!b){var S=n[_+1],w=o.secondsDifference(S,y);b=w>l,b&&(p=Math.ceil(w/l),f=0,m=w/Math.max(p,2),p=Math.max(p-1,1))}if(b&&f0){var w=S.pop();c=this._polylineCollection.get(w),t.index=w}else t.index=this._polylineCollection.length,c=this._polylineCollection.add();c.id=a,t.polyline=c}var T=g.getValueOrDefault(s._resolution,e,60);c.show=!0,c.positions=P(l,i,n,e,this._referenceFrame,T,c.positions.slice()),c.material=m.getValue(e,s._material,c.material),c.width=g.getValueOrDefault(s._width,e,1),c.distanceDisplayCondition=g.getValueOrUndefined(s._distanceDisplayCondition,e,c.distanceDisplayCondition)},D.prototype.removeObject=function(e){ -var t=e.polyline;r(t)&&(this._unusedIndexes.push(e.index),e.polyline=void 0,t.show=!1,t.id=void 0,e.index=void 0)},D.prototype.destroy=function(){return this._scene.primitives.remove(this._polylineCollection),i(this)},I.prototype.update=function(e){var t=this._updaters;for(var i in t)t.hasOwnProperty(i)&&t[i].update(e);for(var n=this._items.values,o=0,a=n.length;o-1;o--)a=t[o],r(a._path)&&r(a._position)&&l.set(a.id,new b(a));for(o=n.length-1;o>-1;o--)a=n[o],r(a._path)&&r(a._position)?l.contains(a.id)||l.set(a.id,new b(a)):(s=l.get(a.id),r(s)&&(s.updater.removeObject(s),l.remove(a.id)));for(o=i.length-1;o>-1;o--)a=i[o],s=l.get(a.id),r(s)&&(r(s.updater)&&s.updater.removeObject(s),l.remove(a.id))},I._subSample=P,I}),define("DataSources/PlaneGeometryUpdater",["../Core/PlaneGeometry","../Core/PlaneOutlineGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/Matrix4","../Core/ShowGeometryInstanceAttribute","../Core/Quaternion","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x){"use strict";function P(e){this.id=e,this.vertexFormat=void 0,this.plane=void 0,this.dimensions=void 0}function D(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(D.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new p,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new P(e),this._onEntityPropertyChanged(e,"plane",e.plane,void 0)}function I(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new P(t._entity)}function O(e,t,n,o){var a,l;s(e)?(a=e.normal,l=e.distance):(a=i.clone(i.UNIT_X,G),l=0),s(t)||(t=new r(1,1));var u=i.multiplyByScalar(a,-l,z);u=g.multiplyByPoint(n,u,u);var c=g.multiplyByPointAsVector(n,a,G);i.normalize(c,c);var d=M(c,i.UNIT_Z),h=r.clone(t,H);return h.z=1,g.fromTranslationQuaternionRotationScale(u,d,h,o)}function M(e,t){var r=i.angleBetween(e,t);if(0===r)return v.clone(v.IDENTITY,j);var n=i.cross(t,e,W);return v.fromAxisAngle(n,r,j)}var R=new w(n.WHITE),N=new T(!0),L=new T(!0),k=new T(!1),F=new T(n.BLACK),B=new T(S.DISABLED),U=new T(new d),V=new n;l(D,{perInstanceColorAppearanceType:{value:C},materialAppearanceType:{value:y}}),l(D.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!s(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!s(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!1},geometryChanged:{get:function(){return this._geometryChanged}}}),D.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},D.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},D.prototype.createFillGeometryInstance=function(t){var r,i,a=this._entity,l=a.isAvailable(t),u=new _(l&&a.isShowing&&this._showProperty.getValue(t)&&this._fillProperty.getValue(t)),c=this._distanceDisplayConditionProperty.getValue(t),d=h.fromDistanceDisplayCondition(c);if(this._materialProperty instanceof w){var p=n.WHITE;s(this._materialProperty.color)&&(this._materialProperty.color.isConstant||l)&&(p=this._materialProperty.color.getValue(t)),i=o.fromColor(p),r={show:u,distanceDisplayCondition:d,color:i}}else r={show:u,distanceDisplayCondition:d};var m=a.plane,g=this._options,v=a.computeModelMatrix(t),y=x.getValueOrDefault(m.plane,t,g.plane),C=x.getValueOrUndefined(m.dimensions,t,g.dimensions);if(s(v)&&s(y)&&s(C))return g.plane=y,g.dimensions=C,v=O(y,C,v,v),new f({id:a,geometry:new e(this._options),modelMatrix:v,attributes:r})},D.prototype.createOutlineGeometryInstance=function(e){var r=this._entity,i=r.isAvailable(e),a=x.getValueOrDefault(this._outlineColorProperty,e,n.BLACK),l=this._distanceDisplayConditionProperty.getValue(e),u=r.plane,c=this._options,d=r.computeModelMatrix(e),p=x.getValueOrDefault(u.plane,e,c.plane),m=x.getValueOrUndefined(u.dimensions,e,c.dimensions);if(s(d)&&s(p)&&s(m))return c.plane=p,c.dimensions=m,d=O(p,m,d,d),new f({id:r,geometry:new t,modelMatrix:d,attributes:{show:new _(i&&r.isShowing&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)),color:o.fromColor(a),distanceDisplayCondition:h.fromDistanceDisplayCondition(l)}})},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){this._entitySubscription(),u(this)},D.prototype._onEntityPropertyChanged=function(e,t,r,i){if("availability"===t||"position"===t||"orientation"===t||"plane"===t){var n=this._entity.plane;if(!s(n))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var o=n.fill,l=!s(o)||!o.isConstant||o.getValue(m.MINIMUM_VALUE),u=n.outline,c=s(u);if(c&&u.isConstant&&(c=u.getValue(m.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=n.plane,h=n.dimensions,p=e.position,f=n.show;if(!s(d)||!s(h)||!s(p)||s(f)&&f.isConstant&&!f.getValue(m.MINIMUM_VALUE))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var g=a(n.material,R),_=g instanceof w;this._materialProperty=g,this._fillProperty=a(o,L),this._showProperty=a(f,N),this._showOutlineProperty=a(n.outline,k),this._outlineColorProperty=c?a(n.outlineColor,F):void 0,this._shadowsProperty=a(n.shadows,B),this._distanceDisplayConditionProperty=a(n.distanceDisplayCondition,U);var v=n.outlineWidth;if(this._fillEnabled=l,this._outlineEnabled=c,p.isConstant&&x.isConstant(e.orientation)&&d.isConstant&&h.isConstant&&x.isConstant(v)){var b=this._options;b.vertexFormat=_?C.VERTEX_FORMAT:y.MaterialSupport.TEXTURED.vertexFormat,b.plane=d.getValue(m.MINIMUM_VALUE,b.plane),b.dimensions=h.getValue(m.MINIMUM_VALUE,b.dimensions),this._outlineWidth=s(v)?v.getValue(m.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},D.prototype.createDynamicUpdater=function(e){return new I(e,this)},I.prototype.update=function(r){var i=this._primitives;i.removeAndDestroy(this._primitive),i.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var a=this._geometryUpdater,l=a._entity,u=l.plane;if(l.isShowing&&l.isAvailable(r)&&x.getValueOrDefault(u.show,r,!0)){var c=this._options,d=l.computeModelMatrix(r),p=x.getValueOrDefault(u.plane,r,c.plane),m=x.getValueOrUndefined(u.dimensions,r,c.dimensions);if(s(d)&&s(p)&&s(m)){c.plane=p,c.dimensions=m,d=O(p,m,d,d);var g=this._geometryUpdater.shadowsProperty.getValue(r),_=this._geometryUpdater.distanceDisplayConditionProperty,v=_.getValue(r),S=h.fromDistanceDisplayCondition(v);if(x.getValueOrDefault(u.fill,r,!0)){var w=E.getValue(r,a.fillMaterialProperty,this._material);this._material=w;var T=new y({material:w,translucent:w.isTranslucent(),closed:!0});c.vertexFormat=T.vertexFormat,this._primitive=i.add(new b({geometryInstances:new f({id:l,geometry:new e,modelMatrix:d,attributes:{distanceDisplayCondition:S}}),appearance:T,asynchronous:!1,shadows:g}))}if(x.getValueOrDefault(u.outline,r,!1)){c.vertexFormat=C.VERTEX_FORMAT;var A=x.getValueOrClonedDefault(u.outlineColor,r,n.BLACK,V),P=x.getValueOrDefault(u.outlineWidth,r,1),D=1!==A.alpha;this._outlinePrimitive=i.add(new b({geometryInstances:new f({id:l,geometry:new t,modelMatrix:d,attributes:{color:o.fromColor(A),distanceDisplayCondition:S}}),appearance:new C({flat:!0,translucent:D,renderState:{lineWidth:a._scene.clampLineWidth(P)}}),asynchronous:!1,shadows:g}))}}}};var z=new i,G=new i,H=new i,W=new i,j=new v;return I.prototype.getBoundingSphere=function(e,t){return A(e,this._primitive,this._outlinePrimitive,t)},I.prototype.isDestroyed=function(){return!1},I.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),u(this)},D}),define("DataSources/PointVisualizer",["../Core/AssociativeArray","../Core/Cartesian3","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/NearFarScalar","../Scene/HeightReference","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e){this.entity=e,this.pointPrimitive=void 0,this.billboard=void 0,this.color=void 0,this.outlineColor=void 0,this.pixelSize=void 0,this.outlineWidth=void 0}function h(t,r){r.collectionChanged.addEventListener(h.prototype._onCollectionChanged,this),this._cluster=t,this._entityCollection=r,this._items=new e,this._onCollectionChanged(r,r.values,[],[])}function p(e,t,r){if(i(e)){var n=e.pointPrimitive;if(i(n))return e.pointPrimitive=void 0,void r.removePoint(t);var o=e.billboard;i(o)&&(e.billboard=void 0,r.removeBillboard(t))}}function f(e,t,r,i,n){return function(o){var a=document.createElement("canvas"),s=n+2*i;a.height=a.width=s;var l=a.getContext("2d");return l.clearRect(0,0,s,s),0!==i&&(l.beginPath(),l.arc(s/2,s/2,s/2,0,2*Math.PI,!0),l.closePath(),l.fillStyle=r,l.fill(),e<1&&(l.save(),l.globalCompositeOperation="destination-out",l.beginPath(),l.arc(s/2,s/2,n/2,0,2*Math.PI,!0),l.closePath(),l.fillStyle="black",l.fill(),l.restore())),l.beginPath(),l.arc(s/2,s/2,n/2,0,2*Math.PI,!0),l.closePath(),l.fillStyle=t,l.fill(),a}}var m=r.WHITE,g=r.BLACK,_=new r,v=new t,y=new r,C=new s,b=new s,S=new a;return h.prototype.update=function(e){for(var t=this._items.values,n=this._cluster,o=0,a=t.length;o0?(w.scale=1,E=E||D!==s.outlineWidth||I!==s.pixelSize||!r.equals(x,s.color)||!r.equals(P,s.outlineColor)):(w.scale=I/50,I=50,E=E||D!==s.outlineWidth||!r.equals(x,s.color)||!r.equals(P,s.outlineColor)),E){s.color=r.clone(x,s.color),s.outlineColor=r.clone(P,s.outlineColor),s.pixelSize=I,s.outlineWidth=D;var O=x.alpha,M=x.toCssColorString(),R=P.toCssColorString(),N=JSON.stringify([M,I,R,D]);w.setImage(N,f(O,M,R,D,I))}}}else p(s,u,n)}return!0},h.prototype.getBoundingSphere=function(e,r){var n=this._items.get(e.id);if(!i(n)||!i(n.pointPrimitive)&&!i(n.billboard))return u.FAILED;if(i(n.pointPrimitive))r.center=t.clone(n.pointPrimitive.position,r.center);else{var o=n.billboard;if(!i(o._clampedPosition))return u.PENDING;r.center=t.clone(o._clampedPosition,r.center)}return r.radius=0,u.DONE},h.prototype.isDestroyed=function(){return!1},h.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(h.prototype._onCollectionChanged,this);for(var e=this._entityCollection.values,t=0;t-1;o--)a=t[o],i(a._point)&&i(a._position)&&s.set(a.id,new d(a));for(o=n.length-1;o>-1;o--)a=n[o],i(a._point)&&i(a._position)?s.contains(a.id)||s.set(a.id,new d(a)):(p(s.get(a.id),a,l),s.remove(a.id));for(o=r.length-1;o>-1;o--)a=r[o],p(s.get(a.id),a,l),s.remove(a.id)},h}),define("DataSources/PolygonGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/isArray","../Core/Iso8601","../Core/oneTimeWarning","../Core/PolygonGeometry","../Core/PolygonHierarchy","../Core/PolygonOutlineGeometry","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x){"use strict";function P(e){this.id=e,this.vertexFormat=void 0,this.polygonHierarchy=void 0,this.perPositionHeight=void 0,this.closeTop=void 0,this.closeBottom=void 0,this.height=void 0,this.extrudedHeight=void 0,this.granularity=void 0,this.stRotation=void 0}function D(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(D.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._isClosed=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._onTerrain=!1,this._options=new P(e),this._onEntityPropertyChanged(e,"polygon",e.polygon,void 0)}function I(e,t,r){this._primitives=e,this._groundPrimitives=t,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=r,this._options=new P(r._entity)}var O=new w(e.WHITE),M=new T(!0),R=new T(!0),N=new T(!1),L=new T(e.BLACK),k=new T(S.DISABLED),F=new T(new s),B=new e;return n(D,{perInstanceColorAppearanceType:{value:C},materialAppearanceType:{value:y}}),n(D.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return this._isClosed}},onTerrain:{get:function(){return this._onTerrain}},geometryChanged:{get:function(){return this._geometryChanged}}}),D.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},D.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},D.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new _(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),h=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof w){var p=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(p=this._materialProperty.color.getValue(r)),o=t.fromColor(p),n={show:u,distanceDisplayCondition:h,color:o}}else n={show:u,distanceDisplayCondition:h};return new c({id:a,geometry:new f(this._options),attributes:n})},D.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=x.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new g(this._options),attributes:{show:new _(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){this._entitySubscription(),o(this)},D.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"polygon"===t){var a=this._entity.polygon;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(h.MINIMUM_VALUE),u=a.perPositionHeight,c=i(u)&&(!u.isConstant||u.getValue(h.MINIMUM_VALUE)),f=a.outline,g=i(f);if(g&&f.isConstant&&(g=f.getValue(h.MINIMUM_VALUE)),!l&&!g)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var _=a.hierarchy,b=a.show;if(i(b)&&b.isConstant&&!b.getValue(h.MINIMUM_VALUE)||!i(_))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var S=r(a.material,O),T=S instanceof w;this._materialProperty=S,this._fillProperty=r(s,R),this._showProperty=r(b,M),this._showOutlineProperty=r(a.outline,N),this._outlineColorProperty=g?r(a.outlineColor,L):void 0,this._shadowsProperty=r(a.shadows,k),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,F);var A=a.height,E=a.extrudedHeight,P=a.granularity,D=a.stRotation,I=a.outlineWidth,B=l&&!i(A)&&!i(E)&&T&&!c&&v.isSupported(this._scene);g&&B&&(p(p.geometryOutlines),g=!1);var U=a.perPositionHeight,V=a.closeTop,z=a.closeBottom;if(this._fillEnabled=l,this._onTerrain=B,this._outlineEnabled=g,_.isConstant&&x.isConstant(A)&&x.isConstant(E)&&x.isConstant(P)&&x.isConstant(D)&&x.isConstant(I)&&x.isConstant(u)&&x.isConstant(U)&&x.isConstant(V)&&x.isConstant(z)&&(!B||x.isConstant(S))){var G=this._options;G.vertexFormat=T?C.VERTEX_FORMAT:y.MaterialSupport.TEXTURED.vertexFormat;var H=_.getValue(h.MINIMUM_VALUE);d(H)&&(H=new m(H));var W=x.getValueOrUndefined(A,h.MINIMUM_VALUE),j=x.getValueOrDefault(V,h.MINIMUM_VALUE,!0),q=x.getValueOrDefault(z,h.MINIMUM_VALUE,!0),Y=x.getValueOrUndefined(E,h.MINIMUM_VALUE);G.polygonHierarchy=H,G.height=W,G.extrudedHeight=Y,G.granularity=x.getValueOrUndefined(P,h.MINIMUM_VALUE),G.stRotation=x.getValueOrUndefined(D,h.MINIMUM_VALUE),G.perPositionHeight=x.getValueOrUndefined(U,h.MINIMUM_VALUE),G.closeTop=j,G.closeBottom=q,this._outlineWidth=x.getValueOrDefault(I,h.MINIMUM_VALUE,1),this._isClosed=i(Y)&&Y!==W&&j&&q,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},D.prototype.createDynamicUpdater=function(e,t){return new I(e,t,this)},I.prototype.update=function(r){var n=this._geometryUpdater,o=n._onTerrain,a=this._primitives,s=this._groundPrimitives;o?s.removeAndDestroy(this._primitive):(a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._outlinePrimitive=void 0),this._primitive=void 0;var l=n._entity,u=l.polygon;if(l.isShowing&&l.isAvailable(r)&&x.getValueOrDefault(u.show,r,!0)){var h=this._options,p=x.getValueOrUndefined(u.hierarchy,r);if(i(p)){d(p)?h.polygonHierarchy=new m(p):h.polygonHierarchy=p;var _=x.getValueOrDefault(u.closeTop,r,!0),S=x.getValueOrDefault(u.closeBottom,r,!0);h.height=x.getValueOrUndefined(u.height,r),h.extrudedHeight=x.getValueOrUndefined(u.extrudedHeight,r),h.granularity=x.getValueOrUndefined(u.granularity,r),h.stRotation=x.getValueOrUndefined(u.stRotation,r),h.perPositionHeight=x.getValueOrUndefined(u.perPositionHeight,r),h.closeTop=_,h.closeBottom=S;var w=this._geometryUpdater.shadowsProperty.getValue(r);if(x.getValueOrDefault(u.fill,r,!0)){var T=n.fillMaterialProperty,A=E.getValue(r,T,this._material);if(this._material=A,o){var P=e.WHITE;i(T.color)&&(P=T.color.getValue(r)),this._primitive=s.add(new v({geometryInstances:new c({id:l,geometry:new f(h),attributes:{color:t.fromColor(P)}}),asynchronous:!1,shadows:w}))}else{var D=new y({material:A,translucent:A.isTranslucent(),closed:i(h.extrudedHeight)&&h.extrudedHeight!==h.height&&_&&S});h.vertexFormat=D.vertexFormat,this._primitive=a.add(new b({geometryInstances:new c({id:l,geometry:new f(h)}),appearance:D,asynchronous:!1,shadows:w}))}}if(!o&&x.getValueOrDefault(u.outline,r,!1)){h.vertexFormat=C.VERTEX_FORMAT;var I=x.getValueOrClonedDefault(u.outlineColor,r,e.BLACK,B),O=x.getValueOrDefault(u.outlineWidth,r,1),M=1!==I.alpha;this._outlinePrimitive=a.add(new b({geometryInstances:new c({id:l,geometry:new g(h),attributes:{color:t.fromColor(I)}}),appearance:new C({flat:!0,translucent:M,renderState:{lineWidth:n._scene.clampLineWidth(O)}}),asynchronous:!1,shadows:w}))}}}},I.prototype.getBoundingSphere=function(e,t){return A(e,this._primitive,this._outlinePrimitive,t)},I.prototype.isDestroyed=function(){return!1},I.prototype.destroy=function(){var e=this._primitives,t=this._groundPrimitives;this._geometryUpdater._onTerrain?t.removeAndDestroy(this._primitive):e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},D}),define("Shaders/Appearances/PolylineColorAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 prevPosition3DHigh;\nattribute vec3 prevPosition3DLow;\nattribute vec3 nextPosition3DHigh;\nattribute vec3 nextPosition3DLow;\nattribute vec2 expandAndWidth;\nattribute vec4 color;\nattribute float batchId;\nvarying vec4 v_color;\nvoid main()\n{\nfloat expandDir = expandAndWidth.x;\nfloat width = abs(expandAndWidth.y) + 0.5;\nbool usePrev = expandAndWidth.y < 0.0;\nvec4 p = czm_computePosition();\nvec4 prev = czm_computePrevPosition();\nvec4 next = czm_computeNextPosition();\nv_color = color;\nfloat angle;\nvec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);\ngl_Position = czm_viewportOrthographic * positionWC;\n}\n"}),define("Scene/PolylineColorAppearance",["../Core/defaultValue","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/PerInstanceFlatColorAppearanceFS","../Shaders/Appearances/PolylineColorAppearanceVS","../Shaders/PolylineCommon","./Appearance"],function(e,t,r,i,n,o,a){"use strict";function s(t){t=e(t,e.EMPTY_OBJECT);var r=e(t.translucent,!0),i=s.VERTEX_FORMAT;this.material=void 0,this.translucent=r,this._vertexShaderSource=e(t.vertexShaderSource,l),this._fragmentShaderSource=e(t.fragmentShaderSource,u),this._renderState=a.getDefaultRenderState(r,!1,t.renderState),this._closed=!1,this._vertexFormat=i}var l=o+"\n"+n,u=i;return t(s.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return this._vertexFormat}}}),s.VERTEX_FORMAT=r.POSITION_ONLY,s.prototype.getFragmentShaderSource=a.prototype.getFragmentShaderSource,s.prototype.isTranslucent=a.prototype.isTranslucent,s.prototype.getRenderState=a.prototype.getRenderState,s}),define("Shaders/Appearances/PolylineMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 prevPosition3DHigh;\nattribute vec3 prevPosition3DLow;\nattribute vec3 nextPosition3DHigh;\nattribute vec3 nextPosition3DLow;\nattribute vec2 expandAndWidth;\nattribute vec2 st;\nattribute float batchId;\nvarying float v_width;\nvarying vec2 v_st;\nvarying float v_polylineAngle;\nvoid main()\n{\nfloat expandDir = expandAndWidth.x;\nfloat width = abs(expandAndWidth.y) + 0.5;\nbool usePrev = expandAndWidth.y < 0.0;\nvec4 p = czm_computePosition();\nvec4 prev = czm_computePrevPosition();\nvec4 next = czm_computeNextPosition();\nv_width = width;\nv_st = st;\nvec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\ngl_Position = czm_viewportOrthographic * positionWC;\n}\n"}),define("Scene/PolylineMaterialAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/PolylineMaterialAppearanceVS","../Shaders/PolylineCommon","../Shaders/PolylineFS","./Appearance","./Material"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.translucent,!0),n=u.VERTEX_FORMAT;this.material=t(r.material)?r.material:l.fromType(l.ColorType),this.translucent=i,this._vertexShaderSource=e(r.vertexShaderSource,c),this._fragmentShaderSource=e(r.fragmentShaderSource,d),this._renderState=s.getDefaultRenderState(i,!1,r.renderState),this._closed=!1,this._vertexFormat=n}var c=o+"\n"+n,d=a;return r(u.prototype,{vertexShaderSource:{get:function(){var e=this._vertexShaderSource;return-1!==this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g)&&(e="#define POLYLINE_DASH\n"+e),e}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return this._vertexFormat}}}),u.VERTEX_FORMAT=i.POSITION_AND_ST,u.prototype.getFragmentShaderSource=s.prototype.getFragmentShaderSource,u.prototype.isTranslucent=s.prototype.isTranslucent,u.prototype.getRenderState=s.prototype.getRenderState,u}),define("DataSources/PolylineGeometryUpdater",["../Core/BoundingSphere","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/PolylineGeometry","../Core/PolylinePipeline","../Core/ShowGeometryInstanceAttribute","../Scene/PolylineCollection","../Scene/PolylineColorAppearance","../Scene/PolylineMaterialAppearance","../Scene/ShadowMode","./BoundingSphereState","./ColorMaterialProperty","./ConstantProperty","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T){"use strict";function A(e){this.id=e,this.vertexFormat=void 0,this.positions=void 0,this.width=void 0,this.followSurface=void 0,this.granularity=void 0}function E(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(E.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._geometryChanged=new c,this._showProperty=void 0,this._materialProperty=void 0,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._depthFailMaterialProperty=void 0,this._options=new A(e),this._onEntityPropertyChanged(e,"polyline",e.polyline,void 0)}function x(e,t){var r=t._scene.id,i=P[r];!n(i)||i.isDestroyed()?(i=new g,P[r]=i,e.add(i)):e.contains(i)||e.add(i);var o=i.add();o.id=t._entity,this._line=o,this._primitives=e,this._geometryUpdater=t,this._positions=[]}var P={},D=new b(t.WHITE),I=new S(!0),O=new S(y.DISABLED),M=new S(new l);o(E,{perInstanceColorAppearanceType:{value:_},materialAppearanceType:{value:v}}),o(E.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!n(this._entity.availability)&&T.isConstant(this._showProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},depthFailMaterialProperty:{get:function(){return this._depthFailMaterialProperty}},outlineEnabled:{value:!1},hasConstantOutline:{value:!0},outlineColorProperty:{value:void 0},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!1},geometryChanged:{get:function(){return this._geometryChanged}}}),E.prototype.isOutlineVisible=function(e){return!1},E.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)},E.prototype.createFillGeometryInstance=function(e){var i,o=this._entity,a=o.isAvailable(e),s=new m(a&&o.isShowing&&this._showProperty.getValue(e)),l=this._distanceDisplayConditionProperty.getValue(e),c=u.fromDistanceDisplayCondition(l),h={show:s,distanceDisplayCondition:c};return this._materialProperty instanceof b&&(i=t.WHITE,n(this._materialProperty.color)&&(this._materialProperty.color.isConstant||a)&&(i=this._materialProperty.color.getValue(e)),h.color=r.fromColor(i)), -n(this._depthFailMaterialProperty)&&this._depthFailMaterialProperty instanceof b&&(i=t.WHITE,n(this._depthFailMaterialProperty.color)&&(this._depthFailMaterialProperty.color.isConstant||a)&&(i=this._depthFailMaterialProperty.color.getValue(e)),h.depthFailColor=r.fromColor(i)),new d({id:o,geometry:new p(this._options),attributes:h})},E.prototype.createOutlineGeometryInstance=function(e){},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){this._entitySubscription(),a(this)},E.prototype._onEntityPropertyChanged=function(e,t,r,o){if("availability"===t||"polyline"===t){var a=this._entity.polyline;if(!n(a))return void(this._fillEnabled&&(this._fillEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.positions,l=a.show;if(n(l)&&l.isConstant&&!l.getValue(h.MINIMUM_VALUE)||!n(s))return void(this._fillEnabled&&(this._fillEnabled=!1,this._geometryChanged.raiseEvent(this)));var u=i(a.material,D),c=u instanceof b;this._materialProperty=u,this._depthFailMaterialProperty=a.depthFailMaterial,this._showProperty=i(l,I),this._shadowsProperty=i(a.shadows,O),this._distanceDisplayConditionProperty=i(a.distanceDisplayCondition,M),this._fillEnabled=!0;var d=a.width,p=a.followSurface,f=a.granularity;if(s.isConstant&&T.isConstant(d)&&T.isConstant(p)&&T.isConstant(f)){var m=this._options,g=s.getValue(h.MINIMUM_VALUE,m.positions);if(!n(g)||g.length<2)return void(this._fillEnabled&&(this._fillEnabled=!1,this._geometryChanged.raiseEvent(this)));var y;y=c&&(!n(this._depthFailMaterialProperty)||this._depthFailMaterialProperty instanceof b)?_.VERTEX_FORMAT:v.VERTEX_FORMAT,m.vertexFormat=y,m.positions=g,m.width=n(d)?d.getValue(h.MINIMUM_VALUE):void 0,m.followSurface=n(p)?p.getValue(h.MINIMUM_VALUE):void 0,m.granularity=n(f)?f.getValue(h.MINIMUM_VALUE):void 0,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},E.prototype.createDynamicUpdater=function(e){return new x(e,this)};var R={positions:void 0,granularity:void 0,height:void 0,ellipsoid:void 0};return x.prototype.update=function(e){var t=this._geometryUpdater,r=t._entity,i=r.polyline,o=this._line;if(!r.isShowing||!r.isAvailable(e)||!T.getValueOrDefault(i._show,e,!0))return void(o.show=!1);var a=i.positions,s=T.getValueOrUndefined(a,e,this._positions);if(!n(s)||s.length<2)return void(o.show=!1);var l=T.getValueOrDefault(i._followSurface,e,!0),u=t._scene.globe;l&&n(u)&&(R.ellipsoid=u.ellipsoid,R.positions=s,R.granularity=T.getValueOrUndefined(i._granularity,e),R.height=f.extractHeights(s,u.ellipsoid),s=f.generateCartesianArc(R)),o.show=!0,o.positions=s.slice(),o.material=w.getValue(e,t.fillMaterialProperty,o.material),o.width=T.getValueOrDefault(i._width,e,1),o.distanceDisplayCondition=T.getValueOrUndefined(i._distanceDisplayCondition,e,o.distanceDisplayCondition)},x.prototype.getBoundingSphere=function(t,r){var i=this._line;return i.show&&i.positions.length>0?(e.fromPoints(i.positions,r),C.DONE):C.FAILED},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){var e=this._geometryUpdater,t=e._scene.id,r=P[t];r.remove(this._line),0===r.length&&(this._primitives.removeAndDestroy(r),delete P[t]),a(this)},E}),define("DataSources/PolylineVolumeGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/PolylineVolumeGeometry","../Core/PolylineVolumeOutlineGeometry","../Core/ShowGeometryInstanceAttribute","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.polylinePositions=void 0,this.shapePositions=void 0,this.cornerType=void 0,this.granularity=void 0}function A(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(A.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"polylineVolume",e.polylineVolume,void 0)}function E(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(e.WHITE),P=new C(!0),D=new C(!0),I=new C(!1),O=new C(e.BLACK),M=new C(v.DISABLED),R=new C(new s),N=new e;return n(A,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),n(A.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!0},geometryChanged:{get:function(){return this._geometryChanged}}}),A.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},A.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},A.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new f(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),p=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var m=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(m=this._materialProperty.color.getValue(r)),o=t.fromColor(m),n={show:u,distanceDisplayCondition:p,color:o}}else n={show:u,distanceDisplayCondition:p};return new c({id:a,geometry:new h(this._options),attributes:n})},A.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=w.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new p(this._options),attributes:{show:new f(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){this._entitySubscription(),o(this)},A.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"polylineVolume"===t){var a=this._entity.polylineVolume;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(d.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(d.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var h=a.positions,p=a.shape,f=a.show;if(!i(h)||!i(p)||i(f)&&f.isConstant&&!f.getValue(d.MINIMUM_VALUE))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var _=r(a.material,x),v=_ instanceof y;this._materialProperty=_,this._fillProperty=r(s,D),this._showProperty=r(f,P),this._showOutlineProperty=r(a.outline,I),this._outlineColorProperty=c?r(a.outlineColor,O):void 0,this._shadowsProperty=r(a.shadows,M),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,R);var C=a.granularity,b=a.outlineWidth,S=a.cornerType;if(this._fillEnabled=l,this._outlineEnabled=c,h.isConstant&&p.isConstant&&w.isConstant(C)&&w.isConstant(b)&&w.isConstant(S)){var T=this._options;T.vertexFormat=v?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,T.polylinePositions=h.getValue(d.MINIMUM_VALUE,T.polylinePositions),T.shapePositions=p.getValue(d.MINIMUM_VALUE,T.shape),T.granularity=i(C)?C.getValue(d.MINIMUM_VALUE):void 0,T.cornerType=i(S)?S.getValue(d.MINIMUM_VALUE):void 0,this._outlineWidth=i(b)?b.getValue(d.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},A.prototype.createDynamicUpdater=function(e){return new E(e,this)},E.prototype.update=function(r){var n=this._primitives;n.removeAndDestroy(this._primitive),n.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var o=this._geometryUpdater,a=o._entity,s=a.polylineVolume;if(a.isShowing&&a.isAvailable(r)&&w.getValueOrDefault(s.show,r,!0)){var l=this._options,u=w.getValueOrUndefined(s.positions,r,l.polylinePositions),d=w.getValueOrUndefined(s.shape,r);if(i(u)&&i(d)){l.polylinePositions=u,l.shapePositions=d,l.granularity=w.getValueOrUndefined(s.granularity,r),l.cornerType=w.getValueOrUndefined(s.cornerType,r);var f=this._geometryUpdater.shadowsProperty.getValue(r);if(!i(s.fill)||s.fill.getValue(r)){var v=S.getValue(r,o.fillMaterialProperty,this._material);this._material=v;var y=new m({material:v,translucent:v.isTranslucent(),closed:!0});l.vertexFormat=y.vertexFormat,this._primitive=n.add(new _({geometryInstances:new c({id:a,geometry:new h(l)}),appearance:y,asynchronous:!1,shadows:f}))}if(i(s.outline)&&s.outline.getValue(r)){l.vertexFormat=g.VERTEX_FORMAT;var C=w.getValueOrClonedDefault(s.outlineColor,r,e.BLACK,N),b=w.getValueOrDefault(s.outlineWidth,r,1),T=1!==C.alpha;this._outlinePrimitive=n.add(new _({geometryInstances:new c({id:a,geometry:new p(l),attributes:{color:t.fromColor(C)}}),appearance:new g({flat:!0,translucent:T,renderState:{lineWidth:o._scene.clampLineWidth(b)}}),asynchronous:!1,shadows:f}))}}}},E.prototype.getBoundingSphere=function(e,t){return b(e,this._primitive,this._outlinePrimitive,t)},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},A}),define("DataSources/RectangleGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/oneTimeWarning","../Core/RectangleGeometry","../Core/RectangleOutlineGeometry","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A){"use strict";function E(e){this.id=e,this.vertexFormat=void 0,this.rectangle=void 0,this.closeBottom=void 0,this.closeTop=void 0,this.height=void 0,this.extrudedHeight=void 0,this.granularity=void 0,this.stRotation=void 0,this.rotation=void 0}function x(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(x.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._isClosed=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._onTerrain=!1,this._options=new E(e),this._onEntityPropertyChanged(e,"rectangle",e.rectangle,void 0)}function P(e,t,r){this._primitives=e,this._groundPrimitives=t,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=r,this._options=new E(r._entity)}var D=new b(e.WHITE),I=new S(!0),O=new S(!0),M=new S(!1),R=new S(e.BLACK),N=new S(C.DISABLED),L=new S(new s),k=new e;return n(x,{perInstanceColorAppearanceType:{value:v},materialAppearanceType:{value:_}}),n(x.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&A.isConstant(this._showProperty)&&A.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&A.isConstant(this._showProperty)&&A.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return this._isClosed}},onTerrain:{get:function(){return this._onTerrain}},geometryChanged:{get:function(){return this._geometryChanged}}}),x.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},x.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},x.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new m(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),h=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof b){var f=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(f=this._materialProperty.color.getValue(r)),o=t.fromColor(f),n={show:u,distanceDisplayCondition:h,color:o}}else n={show:u,distanceDisplayCondition:h};return new c({id:a,geometry:new p(this._options),attributes:n})},x.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=A.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new f(this._options),attributes:{show:new m(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){this._entitySubscription(),o(this)},x.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"rectangle"===t){var a=this._entity.rectangle;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(d.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(d.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var p=a.coordinates,f=a.show;if(i(f)&&f.isConstant&&!f.getValue(d.MINIMUM_VALUE)||!i(p))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var m=r(a.material,D),y=m instanceof b;this._materialProperty=m,this._fillProperty=r(s,O),this._showProperty=r(f,I),this._showOutlineProperty=r(a.outline,M),this._outlineColorProperty=c?r(a.outlineColor,R):void 0,this._shadowsProperty=r(a.shadows,N),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,L);var C=a.height,S=a.extrudedHeight,w=a.granularity,T=a.stRotation,E=a.rotation,x=a.outlineWidth,P=a.closeBottom,k=a.closeTop,F=l&&!i(C)&&!i(S)&&y&&g.isSupported(this._scene);if(c&&F&&(h(h.geometryOutlines),c=!1),this._fillEnabled=l,this._onTerrain=F,this._outlineEnabled=c,p.isConstant&&A.isConstant(C)&&A.isConstant(S)&&A.isConstant(w)&&A.isConstant(T)&&A.isConstant(E)&&A.isConstant(x)&&A.isConstant(P)&&A.isConstant(k)&&(!F||A.isConstant(m))){var B=this._options;B.vertexFormat=y?v.VERTEX_FORMAT:_.MaterialSupport.TEXTURED.vertexFormat,B.rectangle=p.getValue(d.MINIMUM_VALUE,B.rectangle),B.height=i(C)?C.getValue(d.MINIMUM_VALUE):void 0,B.extrudedHeight=i(S)?S.getValue(d.MINIMUM_VALUE):void 0,B.granularity=i(w)?w.getValue(d.MINIMUM_VALUE):void 0,B.stRotation=i(T)?T.getValue(d.MINIMUM_VALUE):void 0,B.rotation=i(E)?E.getValue(d.MINIMUM_VALUE):void 0,B.closeBottom=i(P)?P.getValue(d.MINIMUM_VALUE):void 0,B.closeTop=i(k)?k.getValue(d.MINIMUM_VALUE):void 0,this._isClosed=i(S)&&i(B.closeTop)&&i(B.closeBottom)&&B.closeTop&&B.closeBottom,this._outlineWidth=i(x)?x.getValue(d.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},x.prototype.createDynamicUpdater=function(e,t){return new P(e,t,this)},P.prototype.update=function(r){var n=this._geometryUpdater,o=n._onTerrain,a=this._primitives,s=this._groundPrimitives;o?s.removeAndDestroy(this._primitive):(a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._outlinePrimitive=void 0),this._primitive=void 0;var l=n._entity,u=l.rectangle;if(l.isShowing&&l.isAvailable(r)&&A.getValueOrDefault(u.show,r,!0)){var d=this._options,h=A.getValueOrUndefined(u.coordinates,r,d.rectangle);if(i(h)){d.rectangle=h,d.height=A.getValueOrUndefined(u.height,r),d.extrudedHeight=A.getValueOrUndefined(u.extrudedHeight,r),d.granularity=A.getValueOrUndefined(u.granularity,r),d.stRotation=A.getValueOrUndefined(u.stRotation,r),d.rotation=A.getValueOrUndefined(u.rotation,r),d.closeBottom=A.getValueOrUndefined(u.closeBottom,r),d.closeTop=A.getValueOrUndefined(u.closeTop,r);var m=this._geometryUpdater.shadowsProperty.getValue(r);if(A.getValueOrDefault(u.fill,r,!0)){var C=n.fillMaterialProperty,b=T.getValue(r,C,this._material);if(this._material=b,o){var S=e.WHITE;i(C.color)&&(S=C.color.getValue(r)),this._primitive=s.add(new g({geometryInstances:new c({id:l,geometry:new p(d),attributes:{color:t.fromColor(S)}}),asynchronous:!1,shadows:m}))}else{var w=new _({material:b,translucent:b.isTranslucent(),closed:i(d.extrudedHeight)});d.vertexFormat=w.vertexFormat,this._primitive=a.add(new y({geometryInstances:new c({id:l,geometry:new p(d)}),appearance:w,asynchronous:!1,shadows:m}))}}if(!o&&A.getValueOrDefault(u.outline,r,!1)){d.vertexFormat=v.VERTEX_FORMAT;var E=A.getValueOrClonedDefault(u.outlineColor,r,e.BLACK,k),x=A.getValueOrDefault(u.outlineWidth,r,1),P=1!==E.alpha;this._outlinePrimitive=a.add(new y({geometryInstances:new c({id:l,geometry:new f(d),attributes:{color:t.fromColor(E)}}),appearance:new v({flat:!0,translucent:P,renderState:{lineWidth:n._scene.clampLineWidth(x)}}),asynchronous:!1,shadows:m}))}}}},P.prototype.getBoundingSphere=function(e,t){return w(e,this._primitive,this._outlinePrimitive,t)},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){var e=this._primitives,t=this._groundPrimitives;this._geometryUpdater._onTerrain?t.removeAndDestroy(this._primitive):e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},x}),define("DataSources/WallGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/ShowGeometryInstanceAttribute","../Core/WallGeometry","../Core/WallOutlineGeometry","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.positions=void 0,this.minimumHeights=void 0,this.maximumHeights=void 0,this.granularity=void 0}function A(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(A.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"wall",e.wall,void 0)}function E(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(e.WHITE),P=new C(!0),D=new C(!0),I=new C(!1),O=new C(e.BLACK),M=new C(v.DISABLED),R=new C(new s),N=new e;return n(A,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),n(A.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return!1}},geometryChanged:{get:function(){return this._geometryChanged}}}),A.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},A.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},A.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new h(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),f=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var m=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(m=this._materialProperty.color.getValue(r)),o=t.fromColor(m),n={show:u,distanceDisplayCondition:f,color:o}}else n={show:u,distanceDisplayCondition:f};return new c({id:a,geometry:new p(this._options),attributes:n})},A.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=w.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new f(this._options),attributes:{show:new h(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){this._entitySubscription(),o(this)},A.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"wall"===t){var a=this._entity.wall;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(d.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(d.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var h=a.positions,p=a.show;if(i(p)&&p.isConstant&&!p.getValue(d.MINIMUM_VALUE)||!i(h))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var f=r(a.material,x),_=f instanceof y;this._materialProperty=f,this._fillProperty=r(s,D),this._showProperty=r(p,P),this._showOutlineProperty=r(a.outline,I),this._outlineColorProperty=c?r(a.outlineColor,O):void 0,this._shadowsProperty=r(a.shadows,M),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,R);var v=a.minimumHeights,C=a.maximumHeights,b=a.outlineWidth,S=a.granularity;if(this._fillEnabled=l,this._outlineEnabled=c,h.isConstant&&w.isConstant(v)&&w.isConstant(C)&&w.isConstant(b)&&w.isConstant(S)){var T=this._options;T.vertexFormat=_?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,T.positions=h.getValue(d.MINIMUM_VALUE,T.positions),T.minimumHeights=i(v)?v.getValue(d.MINIMUM_VALUE,T.minimumHeights):void 0,T.maximumHeights=i(C)?C.getValue(d.MINIMUM_VALUE,T.maximumHeights):void 0,T.granularity=i(S)?S.getValue(d.MINIMUM_VALUE):void 0,this._outlineWidth=i(b)?b.getValue(d.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},A.prototype.createDynamicUpdater=function(e){return new E(e,this)},E.prototype.update=function(r){var n=this._primitives;n.removeAndDestroy(this._primitive),n.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var o=this._geometryUpdater,a=o._entity,s=a.wall;if(a.isShowing&&a.isAvailable(r)&&w.getValueOrDefault(s.show,r,!0)){var l=this._options,u=w.getValueOrUndefined(s.positions,r,l.positions);if(i(u)){l.positions=u,l.minimumHeights=w.getValueOrUndefined(s.minimumHeights,r,l.minimumHeights),l.maximumHeights=w.getValueOrUndefined(s.maximumHeights,r,l.maximumHeights),l.granularity=w.getValueOrUndefined(s.granularity,r);var d=this._geometryUpdater.shadowsProperty.getValue(r);if(w.getValueOrDefault(s.fill,r,!0)){var h=S.getValue(r,o.fillMaterialProperty,this._material);this._material=h;var v=new m({material:h,translucent:h.isTranslucent(),closed:i(l.extrudedHeight)});l.vertexFormat=v.vertexFormat,this._primitive=n.add(new _({geometryInstances:new c({id:a,geometry:new p(l)}),appearance:v,asynchronous:!1,shadows:d}))}if(w.getValueOrDefault(s.outline,r,!1)){l.vertexFormat=g.VERTEX_FORMAT;var y=w.getValueOrClonedDefault(s.outlineColor,r,e.BLACK,N),C=w.getValueOrDefault(s.outlineWidth,r,1),b=1!==y.alpha;this._outlinePrimitive=n.add(new _({geometryInstances:new c({id:a,geometry:new f(l),attributes:{color:t.fromColor(y)}}),appearance:new g({flat:!0,translucent:b,renderState:{lineWidth:o._scene.clampLineWidth(C)}}),asynchronous:!1,shadows:d}))}}}},E.prototype.getBoundingSphere=function(e,t){return b(e,this._primitive,this._outlinePrimitive,t)},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},A}),define("DataSources/DataSourceDisplay",["../Core/BoundingSphere","../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EventHelper","../Scene/GroundPrimitive","./BillboardVisualizer","./BoundingSphereState","./BoxGeometryUpdater","./CorridorGeometryUpdater","./CustomDataSource","./CylinderGeometryUpdater","./EllipseGeometryUpdater","./EllipsoidGeometryUpdater","./GeometryVisualizer","./LabelVisualizer","./ModelVisualizer","./PathVisualizer","./PlaneGeometryUpdater","./PointVisualizer","./PolygonGeometryUpdater","./PolylineGeometryUpdater","./PolylineVolumeGeometryUpdater","./RectangleGeometryUpdater","./WallGeometryUpdater"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x){"use strict";function P(e){l.initializeTerrainHeights();var t=e.scene,i=e.dataSourceCollection;this._eventHelper=new s,this._eventHelper.add(i.dataSourceAdded,this._onDataSourceAdded,this),this._eventHelper.add(i.dataSourceRemoved,this._onDataSourceRemoved,this),this._dataSourceCollection=i,this._scene=t,this._visualizersCallback=r(e.visualizersCallback,P.defaultVisualizersCallback);for(var n=0,o=i.length;nE*p.maximumRadius?(P=C,e.normalize(x,P),e.negate(P,P),I=e.clone(e.UNIT_Z,b),D=e.cross(I,P,y),e.magnitude(D)>l.EPSILON7&&(e.normalize(P,P),e.normalize(D,D),I=e.cross(P,D,b),e.normalize(I,I),O=!0)):e.equalsEpsilon(x,R,l.EPSILON7)||(I=C,e.normalize(F,I),e.normalize(B,B),D=e.cross(I,B,b),M&&(D=e.multiplyByScalar(D,-1,D)),e.equalsEpsilon(D,e.ZERO,l.EPSILON7)||(P=e.cross(D,I,y),u.multiplyByVector(N,P,P),u.multiplyByVector(N,D,D),u.multiplyByVector(N,I,I),e.normalize(P,P),e.normalize(D,D),e.normalize(I,I),O=!0))}}r(t.boundingSphere)&&(x=t.boundingSphere.center);var G,H,W;o&&(G=e.clone(i.position,S),H=e.clone(i.direction,w),W=e.clone(i.up,T));var j=v;O?(j[0]=P.x,j[1]=P.y,j[2]=P.z,j[3]=0,j[4]=D.x,j[5]=D.y,j[6]=D.z,j[7]=0,j[8]=I.x,j[9]=I.y,j[10]=I.z,j[11]=0,j[12]=x.x,j[13]=x.y,j[14]=x.z,j[15]=0):d.eastNorthUpToFixedFrame(x,p,j),i._setTransform(j),o&&(e.clone(G,i.position),e.clone(H,i.direction),e.clone(W,i.up),e.cross(H,W,i.right))}if(n){var q=f===h.SCENE2D||e.equals(t._offset3D,e.ZERO)?void 0:t._offset3D;i.lookAtTransform(i.transform,q)}}function f(r,i,n){this.entity=r,this.scene=i,this.ellipsoid=t(n,o.WGS84),this.boundingSphere=void 0,this._lastEntity=void 0,this._mode=void 0,this._lastCartesian=new e,this._defaultOffset3D=void 0,this._offset3D=new e}var m=new u,g=new u,_=new u,v=new c,y=new e,C=new e,b=new e,S=new e,w=new e,T=new e,A=new s,E=1.25;i(f,{defaultOffset3D:{get:function(){return this._defaultOffset3D},set:function(t){this._defaultOffset3D=e.clone(t,new e)}}}),f.defaultOffset3D=new e(-14e3,3500,3500);var x=new a,P=new e;return f.prototype.update=function(t,i){var n=this.scene,o=this.entity,a=this.ellipsoid,s=n.mode;if(s!==h.MORPHING){var u=o.position,c=o!==this._lastEntity,d=s!==this._mode,m=this._offset3D,g=n.camera,_=c||d,v=!0;if(c){var y=o.viewFrom,C=r(y);if(!C&&r(i)){x.pitch=-l.PI_OVER_FOUR,x.range=0;var b=u.getValue(t,P);if(r(b)){var S=2-1/Math.max(1,e.magnitude(b)/a.maximumRadius);x.pitch*=S}g.viewBoundingSphere(i,x),this.boundingSphere=i,_=!1,v=!1}else C&&r(y.getValue(t,m))||e.clone(f._defaultOffset3D,m)}else d||n.mode===h.MORPHING||this._mode===h.SCENE2D||e.clone(g.position,m);this._lastEntity=o,this._mode=n.mode!==h.MORPHING?n.mode:this._mode,n.mode!==h.MORPHING&&p(this,g,_,v,u,t,a)}},f}),function(){function e(e,t){function r(t){var r,i=e.arcs[t<0?~t:t],n=i[0];return e.transform?(r=[0,0],i.forEach(function(e){r[0]+=e[0],r[1]+=e[1]})):r=i[i.length-1],t<0?[r,n]:[n,r]}function i(e,t){for(var r in e){var i=e[r];delete t[i.start],delete i.start,delete i.end,i.forEach(function(e){n[e<0?~e:e]=1}),s.push(i)}}var n={},o={},a={},s=[],l=-1;return t.forEach(function(r,i){var n,o=e.arcs[r<0?~r:r];o.length<3&&!o[1][0]&&!o[1][1]&&(n=t[++l],t[l]=r,t[i]=n)}),t.forEach(function(e){var t,i,n=r(e),s=n[0],l=n[1];if(t=a[s])if(delete a[t.end],t.push(e),t.end=l,i=o[l]){delete o[i.start];var u=i===t?t:t.concat(i);o[u.start=t.start]=a[u.end=i.end]=u}else o[t.start]=a[t.end]=t;else if(t=o[l])if(delete o[t.start],t.unshift(e),t.start=s,i=a[s]){delete a[i.end];var c=i===t?t:i.concat(t);o[c.start=i.start]=a[c.end=t.end]=c}else o[t.start]=a[t.end]=t;else t=[e],o[t.start=s]=a[t.end=l]=t}),i(a,o),i(o,a),t.forEach(function(e){n[e<0?~e:e]||s.push([e])}),s}function t(t,r,i){function n(e){var t=e<0?~e:e;(c[t]||(c[t]=[])).push({i:e,g:u})}function o(e){e.forEach(n)}function a(e){e.forEach(o)}function s(e){"GeometryCollection"===e.type?e.geometries.forEach(s):e.type in d&&(u=e,d[e.type](e.arcs))}var l=[];if(arguments.length>1){var u,c=[],d={LineString:o,MultiLineString:a,Polygon:a,MultiPolygon:function(e){e.forEach(a)}};s(r),c.forEach(arguments.length<3?function(e){l.push(e[0].i)}:function(e){i(e[0].g,e[e.length-1].g)&&l.push(e[0].i)})}else for(var h=0,p=t.arcs.length;h0}var s={},l=[],u=[];return r.forEach(function(e){"Polygon"===e.type?i(e.arcs):"MultiPolygon"===e.type&&e.arcs.forEach(i)}),l.forEach(function(e){if(!e._){var t=[],r=[e];for(e._=1,u.push(t);e=r.pop();)t.push(e),e.forEach(function(e){e.forEach(function(e){s[e<0?~e:e].forEach(function(e){e._||(e._=1,r.push(e))})})})}}),l.forEach(function(e){delete e._}),{type:"MultiPolygon",arcs:u.map(function(r){var i=[];if(r.forEach(function(e){e.forEach(function(e){e.forEach(function(e){s[e<0?~e:e].length<2&&i.push(e)})})}),i=e(t,i),(n=i.length)>1)for(var a,l=o(r[0][0]),u=0;u>>1;e[n]0;){var r=(t+1>>1)-1,n=i[r];if(p(e,n)>=0)break;i[n._=t]=n,i[e._=t=r]=e}}function t(e,t){for(;;){var r=t+1<<1,o=r-1,a=t,s=i[a];if(o0&&(e=i[n],t(i[e._=0]=e,0)),r}},r.remove=function(r){var o,a=r._;if(i[a]===r)return a!==--n&&(o=i[n],(p(o,r)<0?e:t)(i[o._=a]=o,a)),a},r}function m(e){if(!e)return _;var t,r,i=e.scale[0],n=e.scale[1],o=e.translate[0],a=e.translate[1];return function(e,s){s||(t=r=0),e[0]=(t+=e[0])*i+o,e[1]=(r+=e[1])*n+a}}function g(e){if(!e)return _;var t,r,i=e.scale[0],n=e.scale[1],o=e.translate[0],a=e.translate[1];return function(e,s){s||(t=r=0);var l=(e[0]-o)/i|0,u=(e[1]-a)/n|0;e[0]=l-t,e[1]=u-r,t=l,r=u}}function _(){}var v={version:"1.6.18",mesh:function(e){return a(e,t.apply(this,arguments))},meshArcs:t,merge:function(e){return a(e,r.apply(this,arguments))},mergeArcs:r,feature:i,neighbors:u,presimplify:c};"function"==typeof define&&define.amd?define("ThirdParty/topojson",v):"object"==typeof module&&module.exports?module.exports=v:this.topojson=v}(),define("DataSources/GeoJsonDataSource",["../Core/Cartesian3","../Core/Color","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/getFilenameFromUri","../Core/loadJson","../Core/PinBuilder","../Core/PolygonHierarchy","../Core/RuntimeError","../Scene/HeightReference","../Scene/VerticalOrigin","../ThirdParty/topojson","../ThirdParty/when","./BillboardGraphics","./CallbackProperty","./ColorMaterialProperty","./ConstantPositionProperty","./ConstantProperty","./CorridorGraphics","./DataSource","./EntityCluster","./EntityCollection","./PolygonGraphics","./PolylineGraphics"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x){"use strict";function P(t){return e.fromDegrees(t[0],t[1],t[2])}function D(e,t){var r="";for(var i in e)if(e.hasOwnProperty(i)){if(i===t||-1!==ae.indexOf(i))continue;var o=e[i];n(o)&&(r+="object"==typeof o?""+i+""+D(o)+"":""+i+""+o+"")}return r.length>0&&(r=''+r+"
"),r}function I(e,t,r){var i;return function(o,a){return n(i)||(i=e(t,r)),i}}function O(e,t){return new v(I(D,e,t),!0)}function M(e,t,i){var o=e.id;if(n(o)&&"Feature"===e.type){for(var a=2,s=o;n(t.getById(s));)s=o+"_"+a,a++;o=s}else o=r();var l=t.getOrCreateEntity(o),u=e.properties;if(n(u)){l.properties=u;var c,d=u.title;if(n(d))l.name=d,c="title";else{var h=Number.MAX_VALUE;for(var p in u)if(u.hasOwnProperty(p)&&u[p]){var f=p.toLowerCase();if(h>1&&"title"===f){h=1,c=p;break}h>2&&"name"===f?(h=2,c=p):h>3&&/title/i.test(p)?(h=3,c=p):h>4&&/name/i.test(p)&&(h=4,c=p)}n(c)&&(l.name=u[c])}var m=u.description;null!==m&&(l.description=n(m)?new b(m):i(u,c))}return l}function R(e,t){for(var r=new Array(e.length),i=0;i2?v.perPositionHeight=new b(!0):a.clampToGround||(v.height=0);M(r,e._entityCollection,a.describe).polygon=v}}function W(e,t,r,i,n){H(e,t,i,r.coordinates,n)}function j(e,t,r,i,n){for(var o=r.coordinates,a=0;at&&(r=null==r?"..":r,e=e.substring(0,t-r.length)+r),e},indexOf:function(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,i=e.length;r",this.getInnerHtml(),""].join("")},buildAttrsStr:function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'="'+e[r]+'"');return t.join(" ")}}),e.AnchorTagBuilder=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},build:function(t){return new e.HtmlTag({tagName:"a",attrs:this.createAttrs(t.getType(),t.getAnchorHref()),innerHtml:this.processAnchorText(t.getAnchorText())})},createAttrs:function(e,t){var r={href:t},i=this.createCssClass(e);return i&&(r.class=i),this.newWindow&&(r.target="_blank"),r},createCssClass:function(e){var t=this.className;return t?t+" "+t+"-"+e:""},processAnchorText:function(e){return e=this.doTruncate(e)},doTruncate:function(t){return e.Util.ellipsis(t,this.truncate||Number.POSITIVE_INFINITY)}}),e.htmlParser.HtmlParser=e.Util.extend(Object,{htmlRegex:function(){var e=/!--([\s\S]+?)--/,t=/[0-9a-zA-Z][0-9a-zA-Z:]*/,r=/[^\s\0"'>\/=\x01-\x1F\x7F]+/,i=/(?:"[^"]*?"|'[^']*?'|[^'"=<>`\s]+)/,n=r.source+"(?:\\s*=\\s*"+i.source+")?";return new RegExp(["(?:","<(!DOCTYPE)","(?:","\\s+","(?:",n,"|",i.source+")",")*",">",")","|","(?:","<(/)?","(?:",e.source,"|","(?:","("+t.source+")","(?:","\\s+",n,")*","\\s*/?",")",")",">",")"].join(""),"gi")}(),htmlCharacterEntitiesRegex:/( | |<|<|>|>|"|"|')/gi,parse:function(e){for(var t,r,i=this.htmlRegex,n=0,o=[];null!==(t=i.exec(e));){var a=t[0],s=t[3],l=t[1]||t[4],u=!!t[2],c=e.substring(n,t.index);c&&(r=this.parseTextAndEntityNodes(c),o.push.apply(o,r)),s?o.push(this.createCommentNode(a,s)):o.push(this.createElementNode(a,l,u)),n=t.index+a.length}if(n>>8^n[255&(e^r[i])]},t.get=function(){return~e}}function n(e,t,r){return e.slice?e.slice(t,t+r):e.webkitSlice?e.webkitSlice(t,t+r):e.mozSlice?e.mozSlice(t,t+r):e.msSlice?e.msSlice(t,t+r):void 0}function o(e,t){var r,i;return r=new ArrayBuffer(e),i=new Uint8Array(r),t&&i.set(t,0),{buffer:r,array:i,view:new DataView(r)}}function a(){}function s(e){function t(t,r){var o=new Blob([e],{type:V});i=new u(o),i.init(function(){n.size=i.size,t()},r)}function r(e,t,r,n){i.readUint8Array(e,t,r,n)}var i,n=this;n.size=0,n.init=t,n.readUint8Array=r}function l(e){function t(t){for(var r=e.length;"="==e.charAt(r-1);)r--;i=e.indexOf(",")+1,n.size=Math.floor(.75*(r-i)),t()}function r(t,r,n){var a,s=o(r),l=4*Math.floor(t/3),u=4*Math.ceil((t+r)/3),c=window.atob(e.substring(l+i,u+i)),d=t-3*Math.floor(l/4);for(a=d;a2?o+=window.btoa(n):a=n,t()}function i(e){e(o+window.btoa(a))}var n=this,o="",a="";n.init=t,n.writeUint8Array=r,n.getData=i}function p(e){function t(t){n=new Blob([],{type:e}),t()}function r(t,r){n=new Blob([n,P?t:t.buffer],{type:e}),r()}function i(e){e(n)}var n,o=this;o.init=t,o.writeUint8Array=r,o.getData=i}function f(e,t,r,i,n,o,a,s,l,u){function c(){e.removeEventListener(z,d,!1),s(f)}function d(e){var t=e.data,i=t.data;t.onappend&&(f+=i.length,r.writeUint8Array(i,function(){o(!1,i),h()},u)),t.onflush&&(i?(f+=i.length,r.writeUint8Array(i,function(){o(!1,i),c()},u)):c()),t.progress&&a&&a(p+t.current,n)}function h(){p=m*F,p127?n[r-128]:String.fromCharCode(r);return i}function C(e){return decodeURIComponent(escape(e))}function b(e){var t,r="";for(t=0;t>16,r=65535&e;try{return new Date(1980+((65024&t)>>9),((480&t)>>5)-1,31&t,(63488&r)>>11,(2016&r)>>5,2*(31&r),0)}catch(e){}}function w(e,t,r,i,n){return e.version=t.view.getUint16(r,!0),e.bitFlag=t.view.getUint16(r+2,!0),e.compressionMethod=t.view.getUint16(r+4,!0),e.lastModDateRaw=t.view.getUint32(r+6,!0),e.lastModDate=S(e.lastModDateRaw),1==(1&e.bitFlag)?void n(I):((i||8!=(8&e.bitFlag))&&(e.crc32=t.view.getUint32(r+10,!0),e.compressedSize=t.view.getUint32(r+14,!0),e.uncompressedSize=t.view.getUint32(r+18,!0)),4294967295===e.compressedSize||4294967295===e.uncompressedSize?void n(O):(e.filenameLength=t.view.getUint16(r+22,!0),void(e.extraFieldLength=t.view.getUint16(r+24,!0))))}function T(e,t){function r(){}function i(r,n){e.readUint8Array(e.size-r,r,function(e){var t=o(e.length,e).view;1347093766!=t.getUint32(0)?i(r+1,n):n(t)},function(){t(M)})}return r.prototype.getData=function(r,i,n,a){function s(e,t){h&&h.terminate(),h=null,e&&e(t)}function l(e){var t=o(4);return t.view.setUint32(0,e),p.crc32==t.view.getUint32(0)}function u(e,t){a&&!l(t)?c():r.getData(function(e){s(i,e)})}function c(){s(t,L)}function d(){s(t,N)}var h,p=this;e.readUint8Array(p.offset,30,function(i){var s,l=o(i.length,i);if(1347093252!=l.view.getUint32(0))return void t(D);w(p,l,4,!1,t),s=p.offset+30+p.filenameLength+p.extraFieldLength,r.init(function(){0===p.compressionMethod?v(e,r,s,p.compressedSize,a,u,n,c,d):h=g(e,r,s,p.compressedSize,a,u,n,c,d)},d)},c)},{getEntries:function(n){if(e.size<22)return void t(D);i(22,function(i){var a,s;a=i.getUint32(16,!0),s=i.getUint16(8,!0),e.readUint8Array(a,e.size-a,function(e){var i,a,l,u,c=0,d=[],h=o(e.length,e);for(i=0;i>>1^3988292384:r>>>=1;i[e]=r}return i}(),s.prototype=new a,s.prototype.constructor=s,l.prototype=new a,l.prototype.constructor=l,u.prototype=new a,u.prototype.constructor=u,c.prototype.getData=function(e){e(this.data)},d.prototype=new c,d.prototype.constructor=d,h.prototype=new c,h.prototype.constructor=h,p.prototype=new c,p.prototype.constructor=p,r.zip={Reader:a,Writer:c,BlobReader:u,Data64URIReader:l,TextReader:s,BlobWriter:p,Data64URIWriter:h,TextWriter:d,createReader:function(e,t,r){e.init(function(){t(T(e,r))},r)},createWriter:function(e,t,r,i){e.init(function(){t(x(e,r,i))},r)},useWebWorkers:!0};var G;t(r.zip,{workerScriptsPath:{get:function(){return void 0===G&&(G=e("ThirdParty/Workers/")),G}}})}(r),r.zip}),define("DataSources/KmlLookAt",[],function(){"use strict";function e(e,t){this.position=e,this.headingPitchRange=t}return e}),define("DataSources/KmlTour",["../Core/Event","../Core/defined"],function(e,t){"use strict";function r(t,r){this.id=r,this.name=t,this.playlistIndex=0,this.playlist=[],this.tourStart=new e,this.tourEnd=new e,this.entryStart=new e,this.entryEnd=new e,this._activeEntries=[]}function i(e){for(var t=e.pop();void 0!==t;t=e.pop())t.stop()}function n(e,r,i){var n=this.playlist[this.playlistIndex];if(n){var a=o.bind(this,e,r,i);if(this._activeEntries.push(n),this.entryStart.raiseEvent(n),n.blocking)n.play(a,e.scene.camera,r);else{var s=this;n.play(function(){s.entryEnd.raiseEvent(n);var e=s._activeEntries.indexOf(n);e>=0&&s._activeEntries.splice(e,1)}),a(e,r,i)}}else t(i)&&i(!1)}function o(e,t,r,i){var o=this.playlist[this.playlistIndex];if(this.entryEnd.raiseEvent(o,i),i)r(i);else{var a=this._activeEntries.indexOf(o);a>=0&&this._activeEntries.splice(a,1),this.playlistIndex++,n.call(this,e,t,r)}}return r.prototype.addPlaylistEntry=function(e){this.playlist.push(e)},r.prototype.play=function(e,t){this.tourStart.raiseEvent();var r=this;n.call(this,e,t,function(e){r.playlistIndex=0,e||i(r._activeEntries),r.tourEnd.raiseEvent(e)})},r.prototype.stop=function(){i(this._activeEntries)},r}),define("DataSources/KmlTourFlyTo",["../Core/defined","../Core/combine","../Core/BoundingSphere","../Core/EasingFunction"],function(e,t,r,i){"use strict";function n(e,t,r){this.type="KmlTourFlyTo",this.blocking=!0,this.activeCamera=null,this.activeCallback=null,this.duration=e,this.view=r,this.flyToMode=t}return n.prototype.play=function(t,i,n){if(this.activeCamera=i,e(t)&&null!==t){var o=this;this.activeCallback=function(r){delete o.activeCallback,delete o.activeCamera,t(!e(r)&&r)}}var a=this.getCameraOptions(n);if(this.view.headingPitchRoll)i.flyTo(a);else if(this.view.headingPitchRange){var s=new r(this.view.position);i.flyToBoundingSphere(s,a)}},n.prototype.stop=function(){e(this.activeCamera)&&this.activeCamera.cancelFlight(),e(this.activeCallback)&&this.activeCallback(!0)},n.prototype.getCameraOptions=function(r){var n={duration:this.duration};return e(this.activeCallback)&&(n.complete=this.activeCallback),"smooth"===this.flyToMode&&(n.easingFunction=i.LINEAR_NONE),this.view.headingPitchRoll?(n.destination=this.view.position,n.orientation=this.view.headingPitchRoll):this.view.headingPitchRange&&(n.offset=this.view.headingPitchRange),e(r)&&(n=t(n,r)),n},n}),define("DataSources/KmlTourWait",["../Core/defined"],function(e){"use strict";function t(e){this.type="KmlTourWait",this.blocking=!0,this.duration=e,this.timeout=null}return t.prototype.play=function(e){var t=this;this.activeCallback=e,this.timeout=setTimeout(function(){delete t.activeCallback,e(!1)},1e3*this.duration)},t.prototype.stop=function(){clearTimeout(this.timeout),e(this.activeCallback)&&this.activeCallback(!0)},t}),define("DataSources/KmlDataSource",["../Core/AssociativeArray","../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/ClockRange","../Core/ClockStep","../Core/Color","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Ellipsoid","../Core/Event","../Core/getAbsoluteUri","../Core/getExtensionFromUri","../Core/getFilenameFromUri","../Core/Iso8601","../Core/joinUrls","../Core/JulianDate","../Core/loadBlob","../Core/loadXML","../Core/Math","../Core/NearFarScalar","../Core/objectToQuery","../Core/oneTimeWarning","../Core/PinBuilder","../Core/PolygonHierarchy","../Core/Rectangle","../Core/RuntimeError","../Core/TimeInterval","../Core/TimeIntervalCollection","../Core/HeadingPitchRoll","../Core/HeadingPitchRange","../Scene/HeightReference","../Scene/HorizontalOrigin","../Scene/LabelStyle","../Scene/SceneMode","../ThirdParty/Autolinker","../ThirdParty/Uri","../ThirdParty/when","../ThirdParty/zip","./BillboardGraphics","./CompositePositionProperty","./CorridorGraphics","./DataSource","./DataSourceClock","./Entity","./EntityCluster","./EntityCollection","./LabelGraphics","./PathGraphics","./PolygonGraphics","./PolylineGraphics","./PositionPropertyArray","./RectangleGraphics","./ReferenceProperty","./SampledPositionProperty","./ScaledPositionProperty","./TimeIntervalCollectionProperty","./WallGraphics","./KmlLookAt","./KmlCamera","./KmlTour","./KmlTourFlyTo","./KmlTourWait"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H,W,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he){"use strict";function pe(e){var t=e.slice(0,Math.min(4,e.size)),r=z.defer(),i=new FileReader;return i.addEventListener("load",function(){r.resolve(1347093252===new DataView(i.result).getUint32(0,!1))}),i.addEventListener("error",function(){r.reject(i.error)}),i.readAsArrayBuffer(t),r.promise}function fe(e){var t=z.defer(),r=new FileReader;return r.addEventListener("load",function(){t.resolve(r.result)}),r.addEventListener("error",function(){t.reject(r.error)}),r.readAsText(e),t.promise}function me(e){var t,r,i,n,o={xsi:"http://www.w3.org/2001/XMLSchema-instance"};for(var a in o)o.hasOwnProperty(a)&&(i=RegExp("[< ]"+a+":"),n="xmlns:"+a+"=",i.test(e)&&-1===e.indexOf(n)&&(c(t)||(t=e.substr(0,e.indexOf("",n);-1!==n&&n0?qt.maximumRed=o:qt.red=0,n>0?qt.maximumGreen=n:qt.green=0,i>0?qt.maximumBlue=i:qt.blue=0,qt.alpha=r,s.fromRandom(qt)):new s(o,n,i,r)}}function ke(e,t,r){var i=Me(e,t,r);if(c(i))return Le(i,"random"===Me(e,"colorMode",r))}function Fe(e){var t=Pe(e,"TimeStamp",jt.kmlgx),r=Me(t,"when",jt.kmlgx);if(c(t)&&c(r)&&0!==r.length){var i=C.fromIso8601(r),n=new M;return n.addInterval(new O({start:i,stop:v.MAXIMUM_VALUE})),n}}function Be(e){var t=Pe(e,"TimeSpan",jt.kmlgx);if(c(t)){var r,i=Pe(t,"begin",jt.kmlgx),n=c(i)?C.fromIso8601(i.textContent):void 0,o=Pe(t,"end",jt.kmlgx),a=c(o)?C.fromIso8601(o.textContent):void 0;if(c(n)&&c(a)){if(C.lessThan(a,n)){var s=n;n=a,a=s}r=new M,r.addInterval(new O({start:n,stop:a}))}else c(n)?(r=new M,r.addInterval(new O({start:n,stop:v.MAXIMUM_VALUE}))):c(a)&&(r=new M,r.addInterval(new O({start:v.MINIMUM_VALUE,stop:a})));return r}}function Ue(){var e=new H;return e.width=Ft,e.height=Ft,e.scaleByDistance=new T(Bt,Ut,Vt,zt),e.pixelOffsetScaleByDistance=new T(Bt,Ut,Vt,zt),e}function Ve(){var e=new $;return e.outline=!0,e.outlineColor=s.WHITE,e}function ze(){var e=new K;return e.translucencyByDistance=new T(3e6,1,5e6,0),e.pixelOffset=new r(17,0),e.horizontalOrigin=k.LEFT,e.font="16px sans-serif",e.style=F.FILL_AND_OUTLINE,e}function Ge(e,t,r,i,n,o){var a=Me(e,"href",jt.kml);if(c(a)&&0!==a.length){if(0===a.indexOf("root://icons/palette-")){var s=a.charAt(21),l=u(Oe(e,"x",jt.gx),0),d=u(Oe(e,"y",jt.gx),0);l=Math.min(l/32,7),d=7-Math.min(d/32,7);a="https://maps.google.com/mapfiles/kml/pal"+s+"/icon"+(8*d+l)+".png"}if(a=Ne(a,t._proxy,r,i,o),n){var h=Me(e,"refreshMode",jt.kml),p=Me(e,"viewRefreshMode",jt.kml);"onInterval"===h||"onExpire"===h?E("kml-refreshMode-"+h,"KML - Unsupported Icon refreshMode: "+h):"onStop"!==p&&"onRegion"!==p||E("kml-refreshMode-"+p,"KML - Unsupported Icon viewRefreshMode: "+p);var f=u(Me(e,"viewBoundScale",jt.kml),1),m="onStop"===p?"BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]":"",g=u(Me(e,"viewFormat",jt.kml),m),_=Me(e,"httpQuery",jt.kml),v=wt(g,_),C=y(a,v,!1);return Tt(t._camera,t._canvas,C,f,t._lastCameraView.bbox)}return a}}function He(e,n,o,a,s,l){var d=Oe(n,"scale",jt.kml),h=Oe(n,"heading",jt.kml),p=ke(n,"color",jt.kml),f=Pe(n,"Icon",jt.kml),m=Ge(f,e,a,s,!1,l);c(f)&&!c(m)&&(m=!1);var g=Oe(f,"x",jt.gx),_=Oe(f,"y",jt.gx),v=Oe(f,"w",jt.gx),y=Oe(f,"h",jt.gx),C=Pe(n,"hotSpot",jt.kml),b=Ee(C,"x"),S=Ee(C,"y"),T=xe(C,"xunits"),A=xe(C,"yunits"),E=o.billboard;c(E)||(E=Ue(),o.billboard=E),E.image=m,E.scale=d,E.color=p,(c(g)||c(_)||c(v)||c(y))&&(E.imageSubRegion=new t(g,_,v,y)),c(h)&&0!==h&&(E.rotation=w.toRadians(-h),E.alignedAxis=i.UNIT_Z),d=u(d,1);var x,P;c(b)&&("pixels"===T?x=-b*d:"insetPixels"===T?x=(b-Ft)*d:"fraction"===T&&(x=-b*Ft*d),x+=.5*Ft*d),c(S)&&("pixels"===A?P=S*d:"insetPixels"===A?P=(-S+Ft)*d:"fraction"===A&&(P=S*Ft*d),P-=.5*Ft*d),(c(x)||c(P))&&(E.pixelOffset=new r(x,P))}function We(e,t,r,i,n,o){for(var a=0,l=t.childNodes.length;a:clampToSeaFloor is currently not supported, using :clampToGround."),L.CLAMP_TO_GROUND):"relativeToSeaFloor"===t?(E("kml-gx:altitudeMode-relativeToSeaFloor","KML - :relativeToSeaFloor is currently not supported, using :relativeToGround."),L.RELATIVE_TO_GROUND):(c(e)?E("kml-altitudeMode-unknown","KML - Unknown :"+e+", using :CLAMP_TO_GROUND."):E("kml-gx:altitudeMode-unknown","KML - Unknown :"+t+", using :CLAMP_TO_GROUND."),L.CLAMP_TO_GROUND)}function Ze(e,t,r){return"relativeToSeaFloor"===r||"absolute"===t||"relativeToGround"===t?e:((c(t)&&"clampToGround"!==t||c(r)&&"clampToSeaFloor"!==r)&&E("kml-altitudeMode-unknown","KML - Unknown altitudeMode: "+u(t,r)),new oe(e))}function Ke(e,t,r){if(c(e)){if("relativeToSeaFloor"===r||"absolute"===t||"relativeToGround"===t)return e;(c(t)&&"clampToGround"!==t||c(r)&&"clampToSeaFloor"!==r)&&E("kml-altitudeMode-unknown","KML - Unknown altitudeMode: "+u(t,r));for(var i=e.length,n=0;n0&&E("kml-gx:angles","KML - gx:angles are not supported in gx:Tracks");for(var h=Math.min(s.length,u.length),p=[],f=[],m=0;m0&&i.availability.addInterval(new O({start:f[0],stop:f[f.length-1]})),d&&c&&Xe(t,i,n),!0}function nt(e,t,r,i,n,o,a,s,l){var u=e[0],c=e[e.length-1],d=new ne;d.addSamples(e,t),r.intervals.addInterval(new O({start:u,stop:c,isStartIncluded:l,isStopIncluded:l,data:Ze(d,a,s)})),i.addInterval(new O({start:u,stop:c,isStartIncluded:l,isStopIncluded:l})),n.intervals.addInterval(new O({start:u,stop:c,isStartIncluded:l,isStopIncluded:l,data:o}))}function ot(e,t,r,i,n){for(var o,a,s,l=Re(r,"interpolate",jt.gx),u=Ie(r,"Track",jt.gx),d=!1,h=new ae,p=new M,f=new W,m=0,g=u.length;m0)){for(v='',a=0;a";v+="
"+u(y.displayName,l)+""+u(y.value,"")+"
"}if(c(v)){v=kt.link(v),Xt.innerHTML=v;var T=Xt.querySelectorAll("a");for(a=0;a1&&(ye(Xt,"a","href",i),ye(Xt,"img","src",i)),Ce(Xt,"a","href",n,o),Ce(Xt,"img","src",n,o);var A='
",Xt.innerHTML="",t.description=A}}function ct(e,t,r,i,n,o,a,s,l,d){function h(e){return!e||e.show&&h(e.parent)}var p=Se(r,i,l),f=p.kml,m=je(p,e,r,n,o,a,d),g=Me(r,"name",jt.kml);p.name=g,p.parent=t;var _=Be(r);c(_)||(_=Fe(r)),p.availability=_,Ot(p);var v=Re(r,"visibility",jt.kml);p.show=h(t)&&u(v,!0);var y=Pe(r,"author",jt.atom),C=f.author;C.name=Me(y,"name",jt.atom),C.uri=Me(y,"uri",jt.atom),C.email=Me(y,"email",jt.atom);var b=Pe(r,"link",jt.atom),S=f.link;return S.href=xe(b,"href"),S.hreflang=xe(b,"hreflang"),S.rel=xe(b,"rel"),S.type=xe(b,"type"),S.title=xe(b,"title"),S.length=xe(b,"length"),f.address=Me(r,"address",jt.kml),f.phoneNumber=Me(r,"phoneNumber",jt.kml),f.snippet=Me(r,"Snippet",jt.kml),lt(r,p),ut(r,p,m,a,e._proxy,o),yt(r,p),vt(r,p),c(Pe(r,"Region",jt.kml))&&E("kml-region","KML - Placemark Regions are unsupported"),{entity:p,styleEntity:m}}function dt(e,t,r,i,n,o,a,s,l,u){for(var c=Object.keys(Qt),d=c.length,h=0;h0||c(t)&&t.length>0)&&(r+=y(St(e),St(t),!1)),r}function Tt(e,t,r,n,o){function a(e){return e<-w.PI_OVER_TWO?-w.PI_OVER_TWO:e>w.PI_OVER_TWO?w.PI_OVER_TWO:e}function s(e){return e>w.PI?e-w.TWO_PI:e<-w.PI?e+w.TWO_PI:e}if(c(e)&&e._mode!==B.MORPHING){var l,d,h=p.WGS84;if(o=u(o,Jt),c(t)&&(er.x=.5*t.clientWidth,er.y=.5*t.clientHeight,l=e.pickEllipsoid(er,h,tr)),c(l)?d=h.cartesianToCartographic(l,$t):(d=D.center(o,$t),l=h.cartographicToCartesian(d)),c(n)&&!w.equalsEpsilon(n,1,w.EPSILON9)){var f=o.width*n*.5,m=o.height*n*.5;o=new D(s(d.longitude-f),a(d.latitude-m),s(d.longitude+f),a(d.latitude+m))}r=r.replace("[bboxWest]",w.toDegrees(o.west).toString()),r=r.replace("[bboxSouth]",w.toDegrees(o.south).toString()),r=r.replace("[bboxEast]",w.toDegrees(o.east).toString()),r=r.replace("[bboxNorth]",w.toDegrees(o.north).toString());var g=w.toDegrees(d.longitude).toString(),_=w.toDegrees(d.latitude).toString();r=r.replace("[lookatLon]",g),r=r.replace("[lookatLat]",_),r=r.replace("[lookatTilt]",w.toDegrees(e.pitch).toString()),r=r.replace("[lookatHeading]",w.toDegrees(e.heading).toString()),r=r.replace("[lookatRange]",i.distance(e.positionWC,l)),r=r.replace("[lookatTerrainLon]",g),r=r.replace("[lookatTerrainLat]",_),r=r.replace("[lookatTerrainAlt]",d.height.toString()),h.cartesianToCartographic(e.positionWC,$t),r=r.replace("[cameraLon]",w.toDegrees($t.longitude).toString()),r=r.replace("[cameraLat]",w.toDegrees($t.latitude).toString()),r=r.replace("[cameraAlt]",w.toDegrees($t.height).toString());var v=e.frustum,y=v.aspectRatio,C="",b="";if(c(y)){var S=w.toDegrees(v.fov);y>1?(C=S,b=S/y):(b=S,C=S*y)}r=r.replace("[horizFov]",C.toString()),r=r.replace("[vertFov]",b.toString())}else r=r.replace("[bboxWest]","-180"),r=r.replace("[bboxSouth]","-90"),r=r.replace("[bboxEast]","180"),r=r.replace("[bboxNorth]","90"),r=r.replace("[lookatLon]",""),r=r.replace("[lookatLat]",""),r=r.replace("[lookatRange]",""),r=r.replace("[lookatTilt]",""),r=r.replace("[lookatHeading]",""),r=r.replace("[lookatTerrainLon]",""),r=r.replace("[lookatTerrainLat]",""),r=r.replace("[lookatTerrainAlt]",""),r=r.replace("[cameraLon]",""),r=r.replace("[cameraLat]",""),r=r.replace("[cameraAlt]",""),r=r.replace("[horizFov]",""),r=r.replace("[vertFov]","");return c(t)?(r=r.replace("[horizPixels]",t.clientWidth),r=r.replace("[vertPixels]",t.clientHeight)):(r=r.replace("[horizPixels]",""),r=r.replace("[vertPixels]","")),r=r.replace("[terrainEnabled]","1"),r=r.replace("[clientVersion]","1"),r=r.replace("[kmlVersion]","2.2"),r=r.replace("[clientName]","Cesium"),r=r.replace("[language]","English")}function At(e,t,r,i,n,o,a,s,d,h){var p=ct(e,t,r,i,n,o,a,s,d,h),f=p.entity,g=Pe(r,"Link",jt.kml);if(c(g)||(g=Pe(r,"Url",jt.kml)),c(g)){var _,v,b,S=Me(g,"href",jt.kml);if(c(S)){var w=S;S=Ne(S,void 0,o,a,h);var T;if(/^data:/.test(S))T=S,/\.kmz/i.test(o)||(w=m(w,o));else{w=S,_=Me(g,"viewRefreshMode",jt.kml),v=u(Me(g,"viewBoundScale",jt.kml),1);var A="onStop"===_?"BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]":"",x=u(Me(g,"viewFormat",jt.kml),A),P=Me(g,"httpQuery",jt.kml);b=wt(x,P),T=Tt(e._camera,e._canvas,y(S,b,!1),v,e._lastCameraView.bbox)}var D={sourceUri:w,uriResolver:a,context:f.id},I=new Z,O=Dt(e,I,T,D).then(function(t){var r=e._entityCollection,i=I.values;r.suspendEvents();for(var n=0;n0||"onExpire"===a||"onStop"===_){var d=Pe(t,"NetworkLinkControl",jt.kml),h=c(d),p=C.now(),m={id:l(),href:S,cookie:"",queryString:b,lastUpdated:p,updating:!1,entity:f,viewBoundScale:v,needsUpdate:!1,cameraUpdateTime:p},y=0;if(h&&(m.cookie=u(Me(d,"cookie",jt.kml),""),y=u(Oe(d,"minRefreshPeriod",jt.kml),0)),"onInterval"===a)h&&(s=Math.max(y,s)),m.refreshMode=Kt.INTERVAL,m.time=s;else if("onExpire"===a){var w;if(h&&(w=Me(d,"expires",jt.kml)),c(w))try{var T=C.fromIso8601(w),A=C.secondsDifference(T,p);A>0&&A0&&_e.time&&(i=!0):e.refreshMode===Kt.EXPIRE?C.greaterThan(o,e.time)&&(i=!0):e.refreshMode===Kt.STOP&&(s&&(e.needsUpdate=!0,e.cameraUpdateTime=o),e.needsUpdate&&C.secondsDifference(o,e.cameraUpdateTime)>=e.time&&(i=!0)),i){r(t),e.updating=!0;var n=new Z,u=y(e.href,wt(e.cookie,e.queryString),!1);u=Tt(a._camera,a._canvas,u,e.viewBoundScale,l.bbox),Dt(a,n,u,{context:t.id}).then(Mt(a,e,n,d,u)).otherwise(function(t){var r="NetworkLink "+e.href+" refresh failed: "+t;console.log(r),a._error.raiseEvent(a,r)}),h=!0}}d.set(e.id,e)}}),h&&(this._networkLinks=d,this._changed.raiseEvent(this)),!0},It}),define("DataSources/Visualizer",["../Core/DeveloperError"],function(e){"use strict";function t(){e.throwInstantiationError()}return t.prototype.update=e.throwInstantiationError,t.prototype.getBoundingSphere=e.throwInstantiationError,t.prototype.isDestroyed=e.throwInstantiationError,t.prototype.destroy=e.throwInstantiationError,t}),define("Renderer/ClearCommand",["../Core/Color","../Core/defaultValue","../Core/freezeObject"],function(e,t,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.color=e.color,this.depth=e.depth,this.stencil=e.stencil,this.renderState=e.renderState,this.framebuffer=e.framebuffer,this.owner=e.owner,this.pass=e.pass}return i.ALL=r(new i({color:new e(0,0,0,0),depth:1,stencil:0})),i.prototype.execute=function(e,t){e.clear(this,t)},i}),define("Renderer/ComputeCommand",["../Core/defaultValue","./Pass"],function(e,t){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT),this.vertexArray=r.vertexArray,this.fragmentShaderSource=r.fragmentShaderSource,this.shaderProgram=r.shaderProgram,this.uniformMap=r.uniformMap,this.outputTexture=r.outputTexture,this.preExecute=r.preExecute,this.postExecute=r.postExecute,this.persists=e(r.persists,!1),this.pass=t.COMPUTE,this.owner=r.owner}return r.prototype.execute=function(e){e.execute(this)},r}),define("Shaders/ViewportQuadVS",[],function(){"use strict";return"attribute vec4 position;\nattribute vec2 textureCoordinates;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_Position = position;\nv_textureCoordinates = textureCoordinates;\n}\n"}),define("Renderer/ComputeEngine",["../Core/BoundingRectangle","../Core/Check","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/PrimitiveType","../Shaders/ViewportQuadVS","./ClearCommand","./DrawCommand","./Framebuffer","./RenderState","./ShaderProgram"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){this._context=e}function f(e,t){return new c({context:e,colorTextures:[t],destroyAttachments:!1})}function m(e,t){return h.fromCache({context:e,vertexShaderSource:s,fragmentShaderSource:t,attributeLocations:{position:0,textureCoordinates:1}})}function g(t,r){return i(_)&&_.viewport.width===t&&_.viewport.height===r||(_=d.fromCache({viewport:new e(0,0,t,r)})),_}var _,v=new u({primitiveType:a.TRIANGLES}),y=new l({color:new r(0,0,0,0)});return p.prototype.execute=function(e){i(e.preExecute)&&e.preExecute(e);var t=e.outputTexture,r=t.width,n=t.height,o=this._context,a=i(e.vertexArray)?e.vertexArray:o.getViewportQuadVertexArray(),s=i(e.shaderProgram)?e.shaderProgram:m(o,e.fragmentShaderSource),l=f(o,t),u=g(r,n),c=e.uniformMap,d=y;d.framebuffer=l,d.renderState=u,d.execute(o);var h=v;h.vertexArray=a,h.renderState=u,h.shaderProgram=s,h.uniformMap=c,h.framebuffer=l,h.execute(o),l.destroy(),e.persists||(s.destroy(),i(e.vertexArray)&&a.destroy()),i(e.postExecute)&&e.postExecute(t)},p.prototype.isDestroyed=function(){return!1},p.prototype.destroy=function(){return n(this)},p}),define("Renderer/PassState",[],function(){"use strict";function e(e){this.context=e,this.framebuffer=void 0,this.blendingEnabled=void 0,this.scissorTest=void 0,this.viewport=void 0}return e}),define("Renderer/RenderbufferFormat",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={RGBA4:t.RGBA4,RGB5_A1:t.RGB5_A1,RGB565:t.RGB565,DEPTH_COMPONENT16:t.DEPTH_COMPONENT16,STENCIL_INDEX8:t.STENCIL_INDEX8,DEPTH_STENCIL:t.DEPTH_STENCIL,validate:function(e){return e===r.RGBA4||e===r.RGB5_A1||e===r.RGB565||e===r.DEPTH_COMPONENT16||e===r.STENCIL_INDEX8||e===r.DEPTH_STENCIL}};return e(r)}),define("Renderer/Renderbuffer",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","./ContextLimits","./RenderbufferFormat"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT);var i=e.context,n=i._gl,o=(a.maximumRenderbufferSize,t(e.format,s.RGBA4)),l=r(e.width)?e.width:n.drawingBufferWidth,u=r(e.height)?e.height:n.drawingBufferHeight;this._gl=n,this._format=o,this._width=l,this._height=u,this._renderbuffer=this._gl.createRenderbuffer(),n.bindRenderbuffer(n.RENDERBUFFER,this._renderbuffer),n.renderbufferStorage(n.RENDERBUFFER,o,l,u),n.bindRenderbuffer(n.RENDERBUFFER,null)}return i(l.prototype,{format:{get:function(){return this._format}},width:{get:function(){return this._width}},height:{get:function(){return this._height}}}),l.prototype._getRenderbuffer=function(){return this._renderbuffer},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._gl.deleteRenderbuffer(this._renderbuffer),n(this)},l}),define("Renderer/PickFramebuffer",["../Core/BoundingRectangle","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","./Framebuffer","./PassState","./Renderbuffer","./RenderbufferFormat","./Texture"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t){var r=new a(t);r.blendingEnabled=!1,r.scissorTest={enabled:!0,rectangle:new e},r.viewport=new e,this._context=t,this._fb=void 0,this._passState=r,this._width=0,this._height=0}c.prototype.begin=function(t){var r=this._context,n=r.drawingBufferWidth,a=r.drawingBufferHeight;return e.clone(t,this._passState.scissorTest.rectangle),i(this._fb)&&this._width===n&&this._height===a||(this._width=n,this._height=a,this._fb=this._fb&&this._fb.destroy(),this._fb=new o({context:r,colorTextures:[new u({context:r,width:n,height:a})],depthStencilRenderbuffer:new s({context:r,format:l.DEPTH_STENCIL})}),this._passState.framebuffer=this._fb),this._passState.viewport.width=n,this._passState.viewport.height=a,this._passState};var d=new t;return c.prototype.end=function(e){for(var n=r(e.width,1),o=r(e.height,1),a=this._context,s=a.readPixels({x:e.x,y:e.y,width:n,height:o,framebuffer:this._fb}),l=Math.max(n,o),u=l*l,c=Math.floor(.5*n),h=Math.floor(.5*o),p=0,f=0,m=0,g=-1,_=0;_0&&p===1-f){var C=m;m=-g,g=C}p+=m,f+=g}},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return this._fb=this._fb&&this._fb.destroy(),n(this)},c}),define("Renderer/ShaderCache",["../Core/defined","../Core/defineProperties","../Core/destroyObject","./ShaderProgram","./ShaderSource"],function(e,t,r,i,n){"use strict";function o(e){this._context=e,this._shaders={},this._numberOfShaders=0,this._shadersToRelease={}}function a(e,t){for(var r=t.derivedKeywords,i=r.length,n=0;nc.width?2*Math.tan(.5*u)/c.height:2*Math.tan(.5*u)/c.width,this._geometricToleranceOverMeter=o*e.maximumScreenSpaceError,a.clone(e.backgroundColor,this._backgroundColor),this._minimumDisableDepthTestDistance=e.minimumDisableDepthTestDistance,this._minimumDisableDepthTestDistance*=this._minimumDisableDepthTestDistance,this._minimumDisableDepthTestDistance===Number.POSITIVE_INFINITY&&(this._minimumDisableDepthTestDistance=-1)};var X=new i,Q=new i,Z=new i,K=new i,J=new i,$=new o,ee=new i,te=new p;return v}),define("Renderer/Context",["../Core/Check","../Core/clone","../Core/Color","../Core/ComponentDatatype","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Geometry","../Core/GeometryAttribute","../Core/Matrix4","../Core/PrimitiveType","../Core/RuntimeError","../Core/WebGLConstants","../Shaders/ViewportQuadVS","./BufferUsage","./ClearCommand","./ContextLimits","./CubeMap","./DrawCommand","./PassState","./PickFramebuffer","./RenderState","./ShaderCache","./ShaderProgram","./Texture","./UniformState","./VertexArray"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D){"use strict";function I(e,t){var r="WebGL Error: ";switch(t){case e.INVALID_ENUM:r+="INVALID_ENUM";break;case e.INVALID_VALUE:r+="INVALID_VALUE";break;case e.INVALID_OPERATION:r+="INVALID_OPERATION";break;case e.OUT_OF_MEMORY:r+="OUT_OF_MEMORY";break;case e.CONTEXT_LOST_WEBGL:r+="CONTEXT_LOST_WEBGL lost";break;default:r+="Unknown ("+t+")"}return r}function O(e,t,r,i){for(var n=I(e,i)+": "+t.name+"(",o=0;o=8}},antialias:{get:function(){return this._antialias}},standardDerivatives:{get:function(){return this._standardDerivatives||this._webgl2}},blendMinmax:{get:function(){return this._blendMinmax||this._webgl2}},elementIndexUint:{get:function(){return this._elementIndexUint||this._webgl2}},depthTexture:{get:function(){return this._depthTexture||this._webgl2}},floatingPointTexture:{get:function(){return this._textureFloat||this._colorBufferFloat}},textureFilterAnisotropic:{get:function(){return!!this._textureFilterAnisotropic}},s3tc:{get:function(){return this._s3tc}},pvrtc:{get:function(){return this._pvrtc}},etc1:{get:function(){return this._etc1}},vertexArrayObject:{get:function(){return this._vertexArrayObject||this._webgl2}},fragmentDepth:{get:function(){return this._fragDepth||this._webgl2}},instancedArrays:{get:function(){return this._instancedArrays||this._webgl2}},colorBufferFloat:{get:function(){return this._colorBufferFloat}},drawBuffers:{get:function(){return this._drawBuffers||this._webgl2}},debugShaders:{get:function(){return this._debugShaders}},throwOnWebGLError:{get:function(){return this._throwOnWebGLError},set:function(e){this._throwOnWebGLError=e,this._gl=N(this._originalGLContext,e?M:void 0)}},defaultTexture:{get:function(){return void 0===this._defaultTexture&&(this._defaultTexture=new x({context:this,source:{width:1,height:1,arrayBufferView:new Uint8Array([255,255,255,255])}})),this._defaultTexture}},defaultCubeMap:{get:function(){if(void 0===this._defaultCubeMap){var e={width:1,height:1,arrayBufferView:new Uint8Array([255,255,255,255])};this._defaultCubeMap=new C({context:this,source:{positiveX:e,negativeX:e,positiveY:e,negativeY:e,positiveZ:e,negativeZ:e}})}return this._defaultCubeMap}},drawingBufferHeight:{get:function(){return this._gl.drawingBufferHeight}},drawingBufferWidth:{get:function(){return this._gl.drawingBufferWidth}},defaultFramebuffer:{get:function(){return H}}});var W;"undefined"!=typeof WebGLRenderingContext&&(W=[m.BACK]);var j=new v;k.prototype.clear=function(e,t){e=o(e,j),t=o(t,this._defaultPassState);var i=this._gl,n=0,s=e.color,l=e.depth,u=e.stencil;a(s)&&(r.equals(this._clearColor,s)||(r.clone(s,this._clearColor),i.clearColor(s.red,s.green,s.blue,s.alpha)),n|=i.COLOR_BUFFER_BIT),a(l)&&(l!==this._clearDepth&&(this._clearDepth=l,i.clearDepth(l)),n|=i.DEPTH_BUFFER_BIT),a(u)&&(u!==this._clearStencil&&(this._clearStencil=u,i.clearStencil(u)),n|=i.STENCIL_BUFFER_BIT),B(this,o(e.renderState,this._defaultRenderState),t,!0),U(this,o(e.framebuffer,t.framebuffer)),i.clear(n)},k.prototype.draw=function(e,t){t=o(t,this._defaultPassState),V(this,o(e._framebuffer,t.framebuffer),e,t),z(this,e)},k.prototype.endFrame=function(){var e=this._gl;e.useProgram(null),this._currentFramebuffer=void 0,e.bindFramebuffer(e.FRAMEBUFFER,null);var t=W;this.drawBuffers&&this.glDrawBuffers(t);var r=this._maxFrameTextureUnitIndex;this._maxFrameTextureUnitIndex=0;for(var i=0;i0&&(o=!1)}o&&(n=void 0)}l._missingImagePixels=n,l._isReady=!0}function s(){l._missingImagePixels=void 0,l._isReady=!0}r=e(r,e.EMPTY_OBJECT),this._pixelsToCheck=r.pixelsToCheck,this._missingImagePixels=void 0,this._missingImageByteLength=void 0,this._isReady=!1;var l=this;o(n(r.missingImageUrl),a,s)}return a.prototype.isReady=function(){return this._isReady},a.prototype.shouldDiscardImage=function(e){var r=this._pixelsToCheck,n=this._missingImagePixels;if(!t(n))return!1;if(t(e.blob)&&e.blob.size!==this._missingImageByteLength)return!1;for(var o=i(e),a=e.width,s=0,l=r.length;s1&&"name"===o?(i=1,r=n):i>2&&"title"===o?(i=2,r=n):i>3&&/name/i.test(n)?(i=3,r=n):i>4&&/title/i.test(n)&&(i=4,r=n)}e(r)&&(this.name=t[r])},t.prototype.configureDescriptionFromProperties=function(t){function r(t){var i='';for(var n in t)if(t.hasOwnProperty(n)){var o=t[n];e(o)&&(i+="object"==typeof o?"":"")}return i+="
"+n+""+r(o)+"
"+n+""+o+"
"}this.description=r(t)},t}),define("Scene/ImageryProvider",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/loadCRN","../Core/loadImage","../Core/loadImageViaBlob","../Core/loadKTX"],function(e,t,r,i,n,o,a){"use strict";function s(){this.defaultAlpha=void 0,this.defaultBrightness=void 0,this.defaultContrast=void 0,this.defaultHue=void 0,this.defaultSaturation=void 0,this.defaultGamma=void 0,this.defaultMinificationFilter=void 0,this.defaultMagnificationFilter=void 0,r.throwInstantiationError()}t(s.prototype,{ready:{get:r.throwInstantiationError},readyPromise:{get:r.throwInstantiationError},rectangle:{get:r.throwInstantiationError},tileWidth:{get:r.throwInstantiationError},tileHeight:{get:r.throwInstantiationError},maximumLevel:{get:r.throwInstantiationError},minimumLevel:{get:r.throwInstantiationError},tilingScheme:{get:r.throwInstantiationError},tileDiscardPolicy:{get:r.throwInstantiationError},errorEvent:{get:r.throwInstantiationError},credit:{get:r.throwInstantiationError},proxy:{get:r.throwInstantiationError},hasAlphaChannel:{get:r.throwInstantiationError}}),s.prototype.getTileCredits=r.throwInstantiationError,s.prototype.requestImage=r.throwInstantiationError,s.prototype.pickFeatures=r.throwInstantiationError;var l=/\.ktx$/i,u=/\.crn$/i;return s.loadImage=function(t,r,s){return l.test(r)?a(r,void 0,s):u.test(r)?i(r,void 0,s):e(t.tileDiscardPolicy)?o(r,s):n(r,void 0,s)},s}), -define("Scene/ArcGisMapServerImageryProvider",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/loadJson","../Core/loadJsonp","../Core/Math","../Core/Rectangle","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorProjection","../Core/WebMercatorTilingScheme","../ThirdParty/when","./DiscardMissingTileImagePolicy","./ImageryLayerFeatureInfo","./ImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b){"use strict";function S(r){function a(n){var a=n.tileInfo;if(o(a)){if(C._tileWidth=a.rows,C._tileHeight=a.cols,102100===a.spatialReference.wkid||102113===a.spatialReference.wkid)C._tilingScheme=new _({ellipsoid:r.ellipsoid});else{if(4326!==n.tileInfo.spatialReference.wkid){var s="Tile spatial reference WKID "+n.tileInfo.spatialReference.wkid+" is not supported.";return void(h=m.handleError(h,C,C._errorEvent,s,void 0,void 0,void 0,c))}C._tilingScheme=new u({ellipsoid:r.ellipsoid})}if(C._maximumLevel=n.tileInfo.lods.length-1,o(n.fullExtent)){if(o(n.fullExtent.spatialReference)&&o(n.fullExtent.spatialReference.wkid))if(102100===n.fullExtent.spatialReference.wkid||102113===n.fullExtent.spatialReference.wkid){var l=new g,d=n.fullExtent,f=l.unproject(new t(Math.max(d.xmin,-C._tilingScheme.ellipsoid.maximumRadius*Math.PI),Math.max(d.ymin,-C._tilingScheme.ellipsoid.maximumRadius*Math.PI),0)),v=l.unproject(new t(Math.min(d.xmax,C._tilingScheme.ellipsoid.maximumRadius*Math.PI),Math.min(d.ymax,C._tilingScheme.ellipsoid.maximumRadius*Math.PI),0));C._rectangle=new p(f.longitude,f.latitude,v.longitude,v.latitude)}else{if(4326!==n.fullExtent.spatialReference.wkid){var b="fullExtent.spatialReference WKID "+n.fullExtent.spatialReference.wkid+" is not supported.";return void(h=m.handleError(h,C,C._errorEvent,b,void 0,void 0,void 0,c))}C._rectangle=p.fromDegrees(n.fullExtent.xmin,n.fullExtent.ymin,n.fullExtent.xmax,n.fullExtent.ymax)}}else C._rectangle=C._tilingScheme.rectangle;o(C._tileDiscardPolicy)||(C._tileDiscardPolicy=new y({missingImageUrl:w(C,0,0,C._maximumLevel),pixelsToCheck:[new e(0,0),new e(200,20),new e(20,200),new e(80,110),new e(160,130)],disableCheckIfAllPixelsAreTransparent:!0})),C._useTiles=!0}else C._useTiles=!1;o(n.copyrightText)&&n.copyrightText.length>0&&(C._credit=new i({text:n.copyrightText})),C._ready=!0,C._readyPromise.resolve(!0),m.handleSuccess(h)}function s(e){var t="An error occurred while accessing "+C._url+".";h=m.handleError(h,C,C._errorEvent,t,void 0,void 0,void 0,c),C._readyPromise.reject(new f(t))}function c(){var e={f:"json"};o(C._token)&&(e.token=C._token);var t=d(C._url,{parameters:e,proxy:C._proxy});v(t,a,s)}r=n(r,{}),this._url=r.url,this._token=r.token,this._tileDiscardPolicy=r.tileDiscardPolicy,this._proxy=r.proxy,this._tileWidth=n(r.tileWidth,256),this._tileHeight=n(r.tileHeight,256),this._maximumLevel=r.maximumLevel,this._tilingScheme=n(r.tilingScheme,new u({ellipsoid:r.ellipsoid})),this._credit=void 0,this._useTiles=n(r.usePreCachedTilesIfAvailable,!0),this._rectangle=n(r.rectangle,this._tilingScheme.rectangle),this._layers=r.layers,this.enablePickFeatures=n(r.enablePickFeatures,!0),this._errorEvent=new l,this._ready=!1,this._readyPromise=v.defer();var h,C=this;this._useTiles?c():(this._ready=!0,this._readyPromise.resolve(!0))}function w(e,t,r,i){var n;if(e._useTiles)n=e._url+"/tile/"+i+"/"+r+"/"+t;else{var a=e._tilingScheme.tileXYToNativeRectangle(t,r,i),s=a.west+"%2C"+a.south+"%2C"+a.east+"%2C"+a.north;n=e._url+"/export?",n+="bbox="+s,e._tilingScheme instanceof u?n+="&bboxSR=4326&imageSR=4326":n+="&bboxSR=3857&imageSR=3857",n+="&size="+e._tileWidth+"%2C"+e._tileHeight,n+="&format=png&transparent=true&f=image",e.layers&&(n+="&layers=show:"+e.layers)}var l=e._token;o(l)&&(-1===n.indexOf("?")&&(n+="?"),"?"!==n[n.length-1]&&(n+="&"),n+="token="+l);var c=e._proxy;return o(c)&&(n=c.getURL(n)),n}return a(S.prototype,{url:{get:function(){return this._url}},token:{get:function(){return this._token}},proxy:{get:function(){return this._proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},usingPrecachedTiles:{get:function(){return this._useTiles}},hasAlphaChannel:{get:function(){return!0}},layers:{get:function(){return this._layers}}}),S.prototype.getTileCredits=function(e,t,r){},S.prototype.requestImage=function(e,t,r,i){var n=w(this,e,t,r);return b.loadImage(this,n,i)},S.prototype.pickFeatures=function(e,i,n,a,s){if(this.enablePickFeatures){var l,d,p,f=this._tilingScheme.tileXYToNativeRectangle(e,i,n);if(this._tilingScheme instanceof u)l=h.toDegrees(a),d=h.toDegrees(s),p="4326";else{var m=this._tilingScheme.projection.project(new r(a,s,0));l=m.x,d=m.y,p="3857"}var _=this._url+"/identify?f=json&tolerance=2&geometryType=esriGeometryPoint";return _+="&geometry="+l+","+d,_+="&mapExtent="+f.west+","+f.south+","+f.east+","+f.north,_+="&imageDisplay="+this._tileWidth+","+this._tileHeight+",96",_+="&sr="+p,_+="&layers=visible",o(this._layers)&&(_+=":"+this._layers),o(this._token)&&(_+="&token="+this._token),o(this._proxy)&&(_=this._proxy.getURL(_)),c(_).then(function(e){var i=[],n=e.results;if(!o(n))return i;for(var a=0;a0){var d=Math.min(i,g.maximumTextureSize),h=Math.ceil(i/g.maximumTextureSize),p=1/d,f=.5*p,m=1/h,_=.5*m;l=new t(d,h),c=new r(p,f,m,_)}this._textureDimensions=l,this._textureStep=c}function N(t,r){var i,n,o,c=t.instancesLength,d=t.classes,h=t.classIds,p=t.parentCounts,f=t.parentIds,m=c;u(h.byteOffset)&&(h.componentType=l(h.componentType,s.UNSIGNED_SHORT),h.type=E.SCALAR,o=I(h),h=o.createArrayBufferView(r.buffer,r.byteOffset+h.byteOffset,c));var g;if(u(p))for(u(p.byteOffset)&&(p.componentType=l(p.componentType,s.UNSIGNED_SHORT),p.type=E.SCALAR,o=I(p),p=o.createArrayBufferView(r.buffer,r.byteOffset+p.byteOffset,c)),g=new Uint16Array(c),m=0,i=0;i0;)if(t=d.pop(),l[t]!==c){l[t]=c;var h=r(e,t);if(u(h))return h;for(var p=n[t],f=a[t],m=0;m0){for(var i=e._pickIds,n=L(e),a=new Uint8Array(n),s=e._content,l=0;l0?(n="",e&&(n+="uniform bool tile_translucentCommand; \n"),n+="uniform sampler2D tile_batchTexture; \nvarying vec4 tile_featureColor; \nvoid main() \n{ \n tile_main(); \n vec2 st = computeSt("+t+"); \n vec4 featureProperties = texture2D(tile_batchTexture, st); \n float show = ceil(featureProperties.a); \n gl_Position *= show; \n",e&&(n+=" bool isStyleTranslucent = (featureProperties.a != 1.0); \n if (czm_pass == czm_passTranslucent) \n { \n if (!isStyleTranslucent && !tile_translucentCommand) \n { \n gl_Position *= 0.0; \n } \n } \n else \n { \n if (isStyleTranslucent) \n { \n gl_Position *= 0.0; \n } \n } \n"),n+=" tile_featureColor = featureProperties; \n}"):n="varying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n tile_featureSt = computeSt("+t+"); \n}",o+"\n"+Y(r)+n}}},R.prototype.getFragmentShaderCallback=function(e,t){if(0!==this.featuresLength)return function(r){return r=Q(r,t),g.maximumVertexTextureImageUnits>0?r+="varying vec4 tile_featureColor; \nvoid main() \n{ \n tile_color(tile_featureColor); \n}":(e&&(r+="uniform bool tile_translucentCommand; \n"),r+="uniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n if (featureProperties.a == 0.0) { \n discard; \n } \n",e&&(r+=" bool isStyleTranslucent = (featureProperties.a != 1.0); \n if (czm_pass == czm_passTranslucent) \n { \n if (!isStyleTranslucent && !tile_translucentCommand) \n { \n discard; \n } \n } \n else \n { \n if (isStyleTranslucent) \n { \n discard; \n } \n } \n"),r+=" tile_color(featureProperties); \n} \n"),r}},R.prototype.getUniformMapCallback=function(){if(0!==this.featuresLength){var e=this;return function(t){return a(t,{tile_batchTexture:function(){return l(e._batchTexture,e._defaultTexture)},tile_textureDimensions:function(){return e._textureDimensions},tile_textureStep:function(){return e._textureStep},tile_colorBlend:function(){return Z(e)}})}}},R.prototype.getPickVertexShaderCallback=function(e){if(0!==this.featuresLength){var t=this;return function(r){var i,n=S.replaceMain(r,"tile_main");return i=g.maximumVertexTextureImageUnits>0?"uniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n vec2 st = computeSt("+e+"); \n vec4 featureProperties = texture2D(tile_batchTexture, st); \n float show = ceil(featureProperties.a); \n gl_Position *= show; \n tile_featureSt = st; \n}":"varying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n tile_featureSt = computeSt("+e+"); \n}",n+"\n"+Y(t)+i}}},R.prototype.getPickFragmentShaderCallback=function(){if(0!==this.featuresLength)return function(e){var t,r=S.replaceMain(e,"tile_main");return t=g.maximumVertexTextureImageUnits>0?"uniform sampler2D tile_pickTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n if (gl_FragColor.a == 0.0) { \n discard; \n } \n gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n}":"uniform sampler2D tile_pickTexture; \nuniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n if (featureProperties.a == 0.0) { \n discard; \n } \n tile_main(); \n if (gl_FragColor.a == 0.0) { \n discard; \n } \n gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n}",r+"\n"+t}},R.prototype.getPickUniformMapCallback=function(){if(0!==this.featuresLength){var e=this;return function(t){return a({tile_batchTexture:function(){return l(e._batchTexture,e._defaultTexture)},tile_textureDimensions:function(){return e._textureDimensions},tile_textureStep:function(){return e._textureStep},tile_pickTexture:function(){return e._pickTexture}},t)}}};var pe={ALL_OPAQUE:0,ALL_TRANSLUCENT:1,OPAQUE_AND_TRANSLUCENT:2};return R.prototype.addDerivedCommands=function(e,t,r){for(var i=e.commandList,n=i.length,o=this._content._tile,a=o._tileset,s=a.skipLevelOfDetail&&a._hasMixedContent&&e.context.stencilBuffer,l=J(this),c=t;c=570425344?(o-=2*x,M=P,I=D,O=0,P=0,D=0,C._deprecationWarning("b3dm-legacy-header","This b3dm header is using the legacy format [batchLength] [batchTableByteLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.")):O>=570425344&&(o-=x,M=I,I=P,O=D,P=0,D=0,C._deprecationWarning("b3dm-legacy-header","This b3dm header is using the legacy format [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md."));var R;if(0===P)R={BATCH_LENGTH:r(M,0)};else{var N=d(v,o,P);R=JSON.parse(N),o+=P}var L=new Uint8Array(n,o,D);o+=D;var k=new _(R,L);M=k.getGlobalProperty("BATCH_LENGTH"),k.featuresLength=M;var F,B;if(I>0){var U=d(v,o,I);F=JSON.parse(U),o+=I,O>0&&(B=new Uint8Array(n,o,O),B=new Uint8Array(B),o+=O)}var V=new m(t,M,F,B);t._batchTable=V;var z=g+E-o;if(0===z)throw new p("glTF byte length must be greater than 0.");var G;o%4==0?G=new Uint8Array(n,o,z):(C._deprecationWarning("b3dm-glb-unaligned","The embedded glb is not aligned to a 4-byte boundary."),G=new Uint8Array(v.subarray(o,o+z)));var H={content:t,primitive:a};t._model=new y({gltf:G,cull:!1,releaseGltfJson:!0,opaquePass:f.CESIUM_3D_TILE,basePath:l,requestType:h.TILES3D,modelMatrix:s.computedTransform,upAxis:a._gltfUpAxis,shadows:a.shadows,debugWireframe:a.debugWireframe,incrementallyLoadTextures:!1,vertexShaderLoaded:S(t),fragmentShaderLoaded:T(t),uniformMapLoaded:V.getUniformMapCallback(),pickVertexShaderLoaded:w(t),pickFragmentShaderLoaded:V.getPickFragmentShaderCallback(),pickUniformMapLoaded:V.getPickUniformMapCallback(),addBatchIdToGeneratedShaders:M>0,pickObject:H,clippingPlanes:new e({enabled:!1})}),i(a.clippingPlanes)&&(t._model.clippingPlanes=a.clippingPlanes.clone())}function E(e){var t=e._tileset,r=e.featuresLength;if(!i(e._features)&&r>0){for(var n=new Array(r),o=0;o=p.zoomMin&&t<=p.zoomMax){var f=c.intersection(r,p.bbox,S);n(f)&&(u=!0)}}u&&i.push(s.credit)}return i}o(v.prototype,{url:{get:function(){return this._url}},proxy:{get:function(){return this._proxy}},key:{get:function(){return this._key}},mapStyle:{get:function(){return this._mapStyle}},culture:{get:function(){return this._culture}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!1}}});var b=new c;v.prototype.getTileCredits=function(e,t,r){var i=this._tilingScheme.tileXYToRectangle(e,t,r,b),o=C(this._attributionList,r,i);return n(this._keyErrorCredit)&&o.push(this._keyErrorCredit),o},v.prototype.requestImage=function(e,t,r,i){var n=y(this,e,t,r);return _.loadImage(this,n,i)},v.prototype.pickFeatures=function(e,t,r,i,n){},v._logoData="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAAaCAYAAAAEy1RnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3gIDEgcPTMnXOQAAClZJREFUWMPdWGtsFNcV/u689uH1+sXaONhlWQzBENtxiUFBpBSLd60IpXHSNig4URtSYQUkRJNSi0igViVVVBJBaBsiAgKRQJSG8AgEHCCWU4iBCprY2MSgXfOI16y9D3s9Mzsztz9yB12WNU2i9Ecy0tHOzN4793zn3POdcy7BnRfJ8I7iB3SRDPeEExswLz8Y0DZIAYDIRGAgLQAm+7Xle31J3L3Anp1MZPY+BUBjorN332vgYhpgV1FRUd6TTz45ubq6OtDV1SXpuu5g//Oept9wNwlMyAi8IXDjyF245TsDTdivDMATCATGNDU1/WbhwoWPTZs2bWx1dXWhx+Oxrl+/PqTrus5t9W8KWEzjinTAYhro/xuBStwiIgBnJBLxKIoy1u/3V/r9/krDMMz3339/Z3t7e38ikUgCMDLEt8W+Q0cAI3McYTDDmZxh7DESG5Ni43jg9Gsa+X+OsxWxPSJTSj3JZFK5ZRVJErOzs8e6XC4fgGwALhbzDgAKU1hK28KEA6PMmTMn56233qpevnz5PQDcbJ7EzVUAuMrLy3MBeABkcWOEDELSyFe4y7iMoHkriZZlKYZh8ASHZDKpJJPJHAC5APIA5APIAeBlCjo5TwlpXnbOmTPHP3fu3KZVq1atZKBcDJQ9x7V48WJfc3Pzhp6enj+tXLnyR8w4MjdG4gyVDk7KICMClzKlLUrpbQMNw5AkScppbGz8cWdn57WjR4/2caw+DEBlYjO8wX1foZQWuN3uKZIklQD4G+fhlG0Yl8uVm5WVVW6app6dne0D0G8vnxbjJntHubCUOK/badZICyWanrJuAaeUknTQpmlKkUhEWbx48U8LCwtHhUKha+fPn+85fPhwV0tLyzUACSZx9jvMFhIByNFoVDEMw/qKB5HPvJfkUqBr9+7deklJyZ/j8bi5ffv2OAslieMLsG+m2DybT2QuzEQOsF5SUqJfvXo1yc2l6Xn6rgSRSCSEc+fOhVeuXLmwoqJixvTp0wcWLFgQ7unpudHR0dF97ty5z/fu3XseQJh5adjeerquy5ZlCalUivh8Pt8HH3ywzOPxyD09PZ81NjZ+2NnZaQEQx40b54vFYqaqquEVK1b4a2tr/WvWrDn18ssv144fP36SqqoD69ev371nz57rDLwAwHHkyJGfjRs3rtowDOv06dOnu7q6rs6bN2/s7Nmz9zIjDKenWoFZKg/AlMLCwl82Nzf/m3LX22+/fXb06NF/ALC8u7u7m6ZdkUhksL29/UpLS0vzunXrVgAoBzAaQBGAiY2NjUui0ei1RCLRFwwG/9PX19cVi8WCqqoOdHd3HysrK6sDMCccDl8IBoOtiqIsOnbs2D+i0eiV3t7ez8Ph8GeRSKRT07TB/v7+i1OnTp0HYBqABzs7O/+paVo0Fot1RyKRi/F4/Gp/f39XIpHoZnoUMn6wU+ZtRDaymwmxZFk2AWjvvvvuJ/F4PMn/n5+fn1VeXu6fOXNmbU1NzUOM4Bz8QqIoyg6HwxuLxfq3bdu2a+vWrW/09/dfKy0tffDVV199BEC20+n0ud3uQgBup9Pp83g8JYqieE+ePPnxxo0bt33xxRen8/Ly7n3hhRcWASh47bXX5pWVldWFw+GuXbt27XjzzTd3BoPBDq/XG1AUZRRHmAKPVfqaoKkgCCkA+oYNG84Eg0FHTU1N5ezZs8eWlJQ4CSF8/LvZYhJPQoQQpFKpwcrKyo1su9HBwUF99erVv588eXINgOOmacIwDEopdaZSKUIpxYkTJz6sr68/BMBav379RcMwZk2aNOl+AP+qq6t7xDTNVEVFxR+j0WgSAJk4ceKlTz/9tNzpdHpZvIvpjVW6pykhhBJCbkvwgiAQQogEQL558ybdtGlTsLm5OWJZdxZmlmWll5OUEEJN0zSGhob6GcOrALSzZ8/2apqWcLlc2axGACNRkRAimqaph0Kh68xIwwB0y7IMSZKcABz5+fkl8Xj8y2g0apOb5na7rYGBgS/JV54Q0qpAAoBKaS0jBWClg1ZVFeFw2AlgVF1dXeDpp5+eWVFRUVpcXOzgvQwAbrcbDJhdudlGpKZpGtx6JCcnRxIEQbQsS2PjbjM+AMvlchnMSBaXkr7ymCCIhmEYfMoVRVESBEHI0CaTTNubssUsQRBuubCtra33pZdeCk6YMCGwZs2aipqaGn9paWmuJEl3JP0bN258eeTIkRMABrm0YomiaImiKGVlZeWxLecAgBkzZvgdDkfWjRs3ggA0bpfpoiiahBCqKEqKAy2yULMA6MlkMp6Xl3cP1x2SWCwmFhQU+CmlFhfHNFOevpX4LcvSJUkyAeDQoUOh119//fpTTz01Zf78+UWBQCBHUZQ7yE/TNGPfvn0n33vvvSP79+//BECMeZsCMGRZNgRBgNPpHHXx4sVVDQ0Nf1+wYMGYJ554YikAevDgwUMA4oIgQJZlSggZdDqdBiGEZGdn6ww0tQlJURTT4/EMHz9+/MCjjz7622AwuHbZsmVbiouLvWvXrm1wOp3ZqVRqaKQTIInf1gAMl8ulU0q1CxcuBGOxmL5u3bryQCDgycrKEjORXGtra8eOHTsOHz169OyVK1cuA+hlRYrGlNRkWR7UNO2mYRiaz+cb3dLS8gYhhOi6Hj116tSOVatWHQNALcsaME0zLghClBDSZ9+zQsZ2SoJS2udwOKLPPffcvsrKyrJAIPDQ/v37txiGofX19V3r7e29UlBQMHqEVpjwnrYA6PF4PK6q6s2qqqqpZWVlitvtljOB7enpiWzbtu3wgQMHTre1tV0E0MeKkkGuIhMAqHv37u30er3Px+NxlyiKygMPPOAnhFiXLl0Kbd68uYPNsXbu3Lk6mUwaqqr2btmyZUdtbe3hd955pwvAEFNcO3jw4K/b2tqiqqpGIpGI4/HHH/9rQ0PDCa/XOyoSidDLly8PNTU1PcZ4QuNK1ju6NYHFRAGASXPnzv1Fa2vrxzTDpapqateuXR/Nnz+/SVGUhwFMBzCBFSLZLF75DsrJGpXRAH4EIABgPIBxAEoBFAPwARjFif1sNzZ25+VlOhaxufcCqAFQC+BhAPVLliz5XSqVUkOhUAuAKWnFyR3dlsw+fg+A+8eMGfPzTZs2bY9GozEb8JkzZ9qXLl36l+Li4l8B+AmAyQDGsGrOzfXNPGPawG2l85jksmcPm+vihH+2W1iF3bvZPN+sWbPuGx4eDrW3t+85fvz41o6OjmZN04Y0TYvV19cvYIbN5QqUjG2mwj5YAqDK4XDMe+aZZ55vbW09+sorr2yuqqpqYFatAuBn3uB7XzJCY297XeaUd2RoGzOJmHb6IjFj5D777LP3DQwMfDw8PBxSVbUvkUj0hEKhj1588cXH2O7zMSPdplumoxveMx5Zlj3jx4/39vb26gMDA4MsvgYZo+p8Pr7LqQX5Ds/U7d0jFxUVZS1atKg4Nzc317Isp67rZldXV6y5ufkmI78hFtcmrx8ZweMit6XsUs4+6kmlgbW+peLf9gyMZNCR374G0y/FxEzX8b/8+bkXEBxKFwAAAABJRU5ErkJggg==",v.tileXYToQuadKey=function(e,t,r){for(var i="",n=r;n>=0;--n){var o=1<=0;--n){var o=1< 0.0)\n{\nfloat G = G_Smith(roughness, NdotV, NdotL);\nfloat G_Vis = G * VdotH / (NdotH * NdotV);\nfloat Fc = pow(1.0 - VdotH, 5.0);\nA += (1.0 - Fc) * G_Vis;\nB += Fc * G_Vis;\n}\n}\nreturn vec2(A, B) / float(NumSamples);\n}\nvoid main()\n{\ngl_FragColor = vec4(integrateBrdf(1.0 - v_textureCoordinates.y, v_textureCoordinates.x), 0.0, 1.0);\n}\n"}),define("Scene/BrdfLutGenerator",["../Core/BoundingRectangle","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/PixelFormat","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Shaders/BrdfLutGeneratorFS"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(){this._framebuffer=void 0,this._colorTexture=void 0,this._drawCommand=void 0}function m(t,r){var i=t._framebuffer,n=r.createViewportQuadCommand(p,{framebuffer:i,renderState:s.fromCache({viewport:new e(0,0,256,256)})});t._drawCommand=n}function g(e,t){var r=new u({context:t,width:256,height:256,pixelFormat:n.RGBA,pixelDatatype:a.UNSIGNED_BYTE,sampler:new l({wrapS:h.CLAMP_TO_EDGE,wrapT:h.CLAMP_TO_EDGE,minificationFilter:d.NEAREST,magnificationFilter:c.NEAREST})});e._colorTexture=r;var i=new o({context:t,colorTextures:[r],destroyAttachments:!1});e._framebuffer=i}return r(f.prototype,{colorTexture:{get:function(){return this._colorTexture}}}),f.prototype.update=function(e){if(!t(this._colorTexture)){var r=e.context;g(this,r),m(this,r),this._drawCommand.execute(r),this._framebuffer=this._framebuffer&&this._framebuffer.destroy(),this._drawCommand.shaderProgram=this._drawCommand.shaderProgram&&this._drawCommand.shaderProgram.destroy()}},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._colorTexture=this._colorTexture&&this._colorTexture.destroy(),i(this)},f}),define("Scene/CameraFlightPath",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/EasingFunction","../Core/Math","../Core/PerspectiveFrustum","../Core/PerspectiveOffCenterFrustum","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,t,r){var i,n,o;if(e instanceof l){var a=Math.tan(.5*e.fovy);return i=e.near,n=e.near*a,o=e.aspectRatio*n,Math.max(t*i/o,r*i/n)}return e instanceof u?(i=e.near,n=e.top,o=e.right,Math.max(t*i/o,r*i/n)):Math.max(t,r)}function h(e,t,r,i){if(n(i)&&r(.5)>i){var o=r(0),a=r(1),l=r(.5),u=l-o,c=l-a;return function(i){var n=r(i);if(i<=.5){var l=(n-o)/u;return s.lerp(e,-s.PI_OVER_TWO,l)}var d=(n-a)/c;return s.lerp(-s.PI_OVER_TWO,t,1-d)}}return function(r){return s.lerp(e,t,r)}}function p(e,r,i,o,a){var l=a,u=Math.max(i,o);if(!n(l)){var c=e.position,h=r,p=e.up,f=e.right,m=e.frustum,g=t.subtract(c,h,w),_=t.magnitude(t.multiplyByScalar(p,t.dot(g,p),T)),v=t.magnitude(t.multiplyByScalar(f,t.dot(g,f),T));l=Math.min(.2*d(m,_,v),1e9)}if(ue+Math.PI?e+=s.TWO_PI:ts.PI&&(t.longitude+=s.TWO_PI)}function v(e,i,o,a,l,u,c,d,m,v){var y=e.camera,C=e.mapProjection,b=C.ellipsoid,S=r.clone(y.positionCartographic,E),w=y.pitch,T=f(y.heading,a),A=f(y.roll,u),P=b.cartesianToCartographic(o,x);S.longitude=s.zeroToTwoPi(S.longitude),P.longitude=s.zeroToTwoPi(P.longitude);var D=!1;if(n(d)){var I=s.zeroToTwoPi(d),O=Math.min(S.longitude,P.longitude),M=Math.max(S.longitude,P.longitude),R=I>=O&&I<=M;if(n(m)){var N=Math.abs(S.longitude-P.longitude),L=s.TWO_PI-N;(R?N:L)<(R?L:N)*m&&!R&&(D=!0)}else R||(D=!0)}D?g(S,P):_(S,P);var k=p(y,o,S.height,P.height,c),F=h(w,l,k,v);return function(){var e=S.longitude,r=P.longitude,n=S.latitude,o=P.latitude;return function(l){var c=l.time/i,d=t.fromRadians(s.lerp(e,r,c),s.lerp(n,o,c),k(c));y.setView({destination:d,orientation:{heading:s.lerp(T,a,c),pitch:F(c),roll:s.lerp(A,u,c)}})}}()}function y(r,i,n,o,a,l,u){function c(t){var r=t.time/i;d.setView({orientation:{heading:s.lerp(m,o,r)}}),e.lerp(h,n,r,d.position);var a=_(r),l=d.frustum,u=l.top/l.right,c=.5*(a-(l.right-l.left));l.right+=c,l.left-=c,l.top=u*l.right,l.bottom=-l.top}var d=r.camera,h=t.clone(d.position,A),m=f(d.heading,o),g=d.frustum.right-d.frustum.left,_=p(d,n,g,n.z,u);return c}function C(e,t){return{startObject:{},stopObject:{},duration:0,complete:e,cancel:t}}function b(e,t){function r(){"function"==typeof t&&t(),e.enableInputs=!0}return r}var S={},w=new t,T=new t,A=new t,E=new r,x=new r,P=new r,D=new t;return S.createTween=function(r,o){o=i(o,i.EMPTY_OBJECT);var l=o.destination,u=r.mode;if(u===c.MORPHING)return C();var d=i(o.convert,!0),h=r.mapProjection,p=h.ellipsoid,f=o.maximumHeight,g=o.flyOverLongitude,_=o.flyOverLongitudeWeight,S=o.pitchAdjustHeight,w=o.easingFunction;d&&u!==c.SCENE3D&&(p.cartesianToCartographic(l,P),l=h.project(P,D));var T=r.camera,A=o.endTransform;n(A)&&T._setTransform(A);var E=o.duration;n(E)||(E=Math.ceil(t.distance(T.position,l)/1e6)+2,E=Math.min(E,3));var x=i(o.heading,0),I=i(o.pitch,-s.PI_OVER_TWO),O=i(o.roll,0),M=r.screenSpaceCameraController;M.enableInputs=!1;var R=b(M,o.complete),N=b(M,o.cancel),L=T.frustum,k=r.mode===c.SCENE2D;if(k=k&&e.equalsEpsilon(T.position,l,s.EPSILON6),k=k&&s.equalsEpsilon(Math.max(L.right-L.left,L.top-L.bottom),l.z,s.EPSILON6),k=k||r.mode!==c.SCENE2D&&t.equalsEpsilon(l,T.position,s.EPSILON10),k=k&&s.equalsEpsilon(s.negativePiToPi(x),s.negativePiToPi(T.heading),s.EPSILON10)&&s.equalsEpsilon(s.negativePiToPi(I),s.negativePiToPi(T.pitch),s.EPSILON10)&&s.equalsEpsilon(s.negativePiToPi(O),s.negativePiToPi(T.roll),s.EPSILON10))return C(R,N);var F=new Array(4);if(F[c.SCENE2D]=y,F[c.SCENE3D]=v,F[c.COLUMBUS_VIEW]=m,E<=0){return C(function(){F[u](r,1,l,x,I,O,f,g,_,S)({time:1}),"function"==typeof R&&R()},N)}var B=F[u](r,E,l,x,I,O,f,g,_,S);if(!n(w)){var U=T.positionCartographic.height;w=U>(u===c.SCENE3D?p.cartesianToCartographic(l).height:l.z)&&U>11500?a.CUBIC_OUT:a.QUINTIC_IN_OUT}return{duration:E,easingFunction:w,startObject:{time:0},stopObject:{time:E},update:B,complete:R,cancel:N}},S}),define("Scene/MapMode2D",["../Core/freezeObject"],function(e){"use strict";return e({ROTATE:0,INFINITE_SCROLL:1})}),define("Scene/Camera",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/EasingFunction","../Core/Ellipsoid","../Core/EllipsoidGeodesic","../Core/Event","../Core/HeadingPitchRange","../Core/HeadingPitchRoll","../Core/Intersect","../Core/IntersectionTests","../Core/Math","../Core/Matrix3","../Core/Matrix4","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/Quaternion","../Core/Ray","../Core/Rectangle","../Core/Transforms","./CameraFlightPath","./MapMode2D","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D){"use strict";function I(e){this._scene=e,this._transform=y.clone(y.IDENTITY),this._invTransform=y.clone(y.IDENTITY),this._actualTransform=y.clone(y.IDENTITY),this._actualInvTransform=y.clone(y.IDENTITY),this._transformChanged=!1,this.position=new r,this._position=new r,this._positionWC=new r,this._positionCartographic=new n,this.direction=new r,this._direction=new r,this._directionWC=new r,this.up=new r,this._up=new r,this._upWC=new r,this.right=new r,this._right=new r,this._rightWC=new r,this.frustum=new S,this.frustum.aspectRatio=e.drawingBufferWidth/e.drawingBufferHeight,this.frustum.fov=_.toRadians(60),this.defaultMoveAmount=1e5,this.defaultLookAmount=Math.PI/60,this.defaultRotateAmount=Math.PI/3600,this.defaultZoomAmount=1e5,this.constrainedAxis=void 0,this.maximumZoomFactor=1.5,this._moveStart=new h,this._moveEnd=new h,this._changed=new h,this._changedPosition=void 0,this._changedDirection=void 0,this._changedFrustum=void 0,this.percentageChanged=.5,this._viewMatrix=new y,this._invViewMatrix=new y,O(this),this._mode=D.SCENE3D,this._modeChanged=!0;var t=e.mapProjection;this._projection=t,this._maxCoord=t.project(new n(Math.PI,_.PI_OVER_TWO)),this._max2Dfrustum=void 0,this._suspendTerrainAdjustment=!1,Q(this,I.DEFAULT_VIEW_RECTANGLE,this.position,!0);var i=r.magnitude(this.position);i+=i*I.DEFAULT_VIEW_FACTOR,r.normalize(this.position,this.position),r.multiplyByScalar(this.position,i,this.position)}function O(e){y.computeView(e._position,e._direction,e._up,e._right,e._viewMatrix),y.multiply(e._viewMatrix,e._actualInvTransform,e._viewMatrix),y.inverseTransformation(e._viewMatrix,e._invViewMatrix)}function M(e){E.basisTo2D(e._projection,e._transform,e._actualTransform)}function R(e){var t=e._projection,n=t.ellipsoid,o=y.getColumn(e._transform,3,me),a=n.cartesianToCartographic(o,he),s=t.project(a,pe),l=ge;l.x=s.z,l.y=s.x,l.z=s.y,l.w=1;var u=i.clone(i.UNIT_X,ye),c=i.add(y.getColumn(e._transform,0,fe),o,fe);n.cartesianToCartographic(c,a),t.project(a,s);var d=_e;d.x=s.z,d.y=s.x,d.z=s.y,d.w=0,r.subtract(d,l,d),d.x=0;var h=ve;if(r.magnitudeSquared(d)>_.EPSILON10)r.cross(u,d,h);else{var p=i.add(y.getColumn(e._transform,1,fe),o,fe);n.cartesianToCartographic(p,a),t.project(a,s),h.x=s.z,h.y=s.x,h.z=s.y,h.w=0,r.subtract(h,l,h),h.x=0,r.magnitudeSquared(h)<_.EPSILON10&&(i.clone(i.UNIT_Y,d),i.clone(i.UNIT_Z,h))}r.cross(h,u,d),r.normalize(d,d),r.cross(u,d,h),r.normalize(h,h),y.setColumn(e._actualTransform,0,d,e._actualTransform),y.setColumn(e._actualTransform,1,h,e._actualTransform),y.setColumn(e._actualTransform,2,u,e._actualTransform),y.setColumn(e._actualTransform,3,l,e._actualTransform)}function N(e){var t=e._mode,i=!1,n=0;t===D.SCENE2D&&(n=e.frustum.right-e.frustum.left,i=n!==e._positionCartographic.height);var o=e._position,a=!r.equals(o,e.position)||i;a&&(o=r.clone(e.position,e._position));var s=e._direction,l=!r.equals(s,e.direction);l&&(r.normalize(e.direction,e.direction),s=r.clone(e.direction,e._direction));var u=e._up,c=!r.equals(u,e.up);c&&(r.normalize(e.up,e.up),u=r.clone(e.up,e._up));var d=e._right,h=!r.equals(d,e.right);h&&(r.normalize(e.right,e.right),d=r.clone(e.right,e._right));var p=e._transformChanged||e._modeChanged;e._transformChanged=!1,p&&(y.inverseTransformation(e._transform,e._invTransform),e._mode===D.COLUMBUS_VIEW||e._mode===D.SCENE2D?y.equals(y.IDENTITY,e._transform)?y.clone(I.TRANSFORM_2D,e._actualTransform):e._mode===D.COLUMBUS_VIEW?M(e):R(e):y.clone(e._transform,e._actualTransform),y.inverseTransformation(e._actualTransform,e._actualInvTransform),e._modeChanged=!1);var f=e._actualTransform;if(a||p)if(e._positionWC=y.multiplyByPoint(f,o,e._positionWC),t===D.SCENE3D||t===D.MORPHING)e._positionCartographic=e._projection.ellipsoid.cartesianToCartographic(e._positionWC,e._positionCartographic);else{var m=Ce;m.x=e._positionWC.y,m.y=e._positionWC.z,m.z=e._positionWC.x,t===D.SCENE2D&&(m.z=n),e._projection.unproject(m,e._positionCartographic)}if(l||c||h){var g=r.dot(s,r.cross(u,d,Ce));if(Math.abs(1-g)>_.EPSILON2){var v=1/r.magnitudeSquared(u),C=r.dot(u,s)*v,b=r.multiplyByScalar(s,C,Ce);u=r.normalize(r.subtract(u,b,e._up),e._up),r.clone(u,e.up),d=r.cross(s,u,e._right),r.clone(d,e.right)}}(l||p)&&(e._directionWC=y.multiplyByPointAsVector(f,s,e._directionWC),r.normalize(e._directionWC,e._directionWC)),(c||p)&&(e._upWC=y.multiplyByPointAsVector(f,u,e._upWC),r.normalize(e._upWC,e._upWC)),(h||p)&&(e._rightWC=y.multiplyByPointAsVector(f,d,e._rightWC),r.normalize(e._rightWC,e._rightWC)),(a||l||c||h||p)&&O(e)}function L(e,t){var r;return r=_.equalsEpsilon(Math.abs(e.z),1,_.EPSILON3)?Math.atan2(t.y,t.x)-_.PI_OVER_TWO:Math.atan2(e.y,e.x)-_.PI_OVER_TWO,_.TWO_PI-_.zeroToTwoPi(r)}function k(e){return _.PI_OVER_TWO-_.acosClamped(e.z)}function F(e,t,r){var i=0;return _.equalsEpsilon(Math.abs(e.z),1,_.EPSILON3)||(i=Math.atan2(-r.z,t.z),i=_.zeroToTwoPi(i+_.TWO_PI)),i}function B(e,t,i){var n=y.clone(e.transform,Oe),o=E.eastNorthUpToFixedFrame(t,e._projection.ellipsoid,Me);e._setTransform(o),r.clone(r.ZERO,e.position),i.heading=i.heading-_.PI_OVER_TWO;var a=w.fromHeadingPitchRoll(i,Re),s=v.fromQuaternion(a,Ne);v.getColumn(s,0,e.direction),v.getColumn(s,2,e.up),r.cross(e.direction,e.up,e.right),e._setTransform(n),e._adjustOrthographicFrustum(!0)}function U(e,t,i,n){var o=y.clone(e.transform,Oe);if(e._setTransform(y.IDENTITY),!r.equals(t,e.positionWC)){if(n){var a=e._projection,s=a.ellipsoid.cartesianToCartographic(t,Le);t=a.project(s,Ie)}r.clone(t,e.position)}i.heading=i.heading-_.PI_OVER_TWO;var l=w.fromHeadingPitchRoll(i,Re),u=v.fromQuaternion(l,Ne);v.getColumn(u,0,e.direction),v.getColumn(u,2,e.up),r.cross(e.direction,e.up,e.right),e._setTransform(o),e._adjustOrthographicFrustum(!0)}function V(e,i,n,o){var a=y.clone(e.transform,Oe);if(e._setTransform(y.IDENTITY),!r.equals(i,e.positionWC)){if(o){var s=e._projection,l=s.ellipsoid.cartesianToCartographic(i,Le);i=s.project(l,Ie)}t.clone(i,e.position);var u=.5*-i.z,c=-u,d=e.frustum;if(c>u){var h=d.top/d.right;d.right=c,d.left=u,d.top=d.right*h,d.bottom=-d.top}}if(e._scene.mapMode2D===P.ROTATE){n.heading=n.heading-_.PI_OVER_TWO,n.pitch=-_.PI_OVER_TWO,n.roll=0;var p=w.fromHeadingPitchRoll(n,Re),f=v.fromQuaternion(p,Ne);v.getColumn(f,2,e.up),r.cross(e.direction,e.up,e.right)}e._setTransform(a)}function z(e,t,i,n){var o=r.clone(i.direction,ke),a=r.clone(i.up,Fe);if(e._scene.mode===D.SCENE3D){var s=e._projection.ellipsoid,l=E.eastNorthUpToFixedFrame(t,s,be),u=y.inverseTransformation(l,Se);y.multiplyByPointAsVector(u,o,o),y.multiplyByPointAsVector(u,a,a)}var c=r.cross(o,a,Be);return n.heading=L(o,a),n.pitch=k(o),n.roll=F(o,a,c),n}function G(e,t){var r,i,n=e._scene.mapMode2D===P.ROTATE,o=e._maxCoord.x,a=e._maxCoord.y;n?(i=o,r=-i):(i=t.x-2*o,r=t.x+2*o),t.x>o&&(t.x=i),t.x<-o&&(t.x=r),t.y>a&&(t.y=a),t.y<-a&&(t.y=-a)}function H(e,t){var i=e.position,n=r.normalize(i,Ye);if(a(e.constrainedAxis)){var o=r.equalsEpsilon(n,e.constrainedAxis,_.EPSILON2),s=r.equalsEpsilon(n,r.negate(e.constrainedAxis,Ze),_.EPSILON2);if(o||s)(o&&t<0||s&&t>0)&&e.rotate(e.right,t);else{var l=r.normalize(e.constrainedAxis,Xe),u=r.dot(n,l),c=_.acosClamped(u);t>0&&t>c&&(t=c-_.EPSILON4),u=r.dot(n,r.negate(l,Ze)),c=_.acosClamped(u),t<0&&-t>c&&(t=-c+_.EPSILON4);var d=r.cross(l,n,Qe);e.rotate(d,t)}}else e.rotate(e.right,t)}function W(e,t){a(e.constrainedAxis)?e.rotate(e.constrainedAxis,t):e.rotate(e.up,t)}function j(e,t){var r,i=e.frustum;if(t*=.5,Math.abs(i.top)+Math.abs(i.bottom)>Math.abs(i.left)+Math.abs(i.right)){var n=i.top-t,o=i.bottom+t,a=e._maxCoord.y;e._scene.mapMode2D===P.ROTATE&&(a*=e.maximumZoomFactor),o>a&&(o=a,n=-a),n<=o&&(n=1,o=-1),r=i.right/i.top,i.top=n,i.bottom=o,i.right=i.top*r,i.left=-i.right}else{var s=i.right-t,l=i.left+t,u=e._maxCoord.x;e._scene.mapMode2D===P.ROTATE&&(u*=e.maximumZoomFactor),s>u&&(s=u,l=-u),s<=l&&(s=1,l=-1),r=i.top/i.right,i.right=s,i.left=l,i.top=i.right*r,i.bottom=-i.top}}function q(e,t){e.move(e.direction,t)}function Y(e,t,i){t=_.clamp(t,-_.PI_OVER_TWO,_.PI_OVER_TWO),e=_.zeroToTwoPi(e)-_.PI_OVER_TWO;var n=w.fromAxisAngle(r.UNIT_Y,-t,$e),o=w.fromAxisAngle(r.UNIT_Z,-e,et),a=w.multiply(o,n,o),s=v.fromQuaternion(a,tt),l=r.clone(r.UNIT_X,Je);return v.multiplyByVector(s,l,l),r.negate(l,l),r.multiplyByScalar(l,i,l),l}function X(e,t,i,n){return Math.abs(r.dot(t,i))/n-r.dot(e,i)}function Q(e,t,i,n){var o=e._projection.ellipsoid,s=n?e:pt,l=t.north,u=t.south,c=t.east,h=t.west;h>c&&(c+=_.TWO_PI);var p,f=.5*(h+c);if(u<-_.PI_OVER_TWO+_.RADIANS_PER_DEGREE&&l>_.PI_OVER_TWO-_.RADIANS_PER_DEGREE)p=0;else{var m=it;m.longitude=f,m.latitude=l,m.height=0;var g=nt;g.longitude=f,g.latitude=u,g.height=0;var v=rt;a(v)&&v.ellipsoid===o||(rt=v=new d(void 0,void 0,o)),v.setEndPoints(m,g),p=v.interpolateUsingFraction(.5,it).latitude}var y=it;y.longitude=f,y.latitude=p,y.height=0;var b=o.cartographicToCartesian(y,dt),S=it;S.longitude=c,S.latitude=l;var w=o.cartographicToCartesian(S,ot);S.longitude=h;var T=o.cartographicToCartesian(S,st);S.longitude=f;var A=o.cartographicToCartesian(S,ut);S.latitude=u;var E=o.cartographicToCartesian(S,ct);S.longitude=c;var x=o.cartographicToCartesian(S,lt);S.longitude=h;var P=o.cartographicToCartesian(S,at);r.subtract(T,b,T),r.subtract(x,b,x),r.subtract(w,b,w),r.subtract(P,b,P),r.subtract(A,b,A),r.subtract(E,b,E);var D=o.geodeticSurfaceNormal(b,s.direction);r.negate(D,D);var I=r.cross(D,r.UNIT_Z,s.right);r.normalize(I,I);var O,M=r.cross(I,D,s.up);if(e.frustum instanceof C){var R,N,L=Math.max(r.distance(w,T),r.distance(x,P)),k=Math.max(r.distance(w,x),r.distance(T,P)),F=e.frustum._offCenterFrustum.right/e.frustum._offCenterFrustum.top,B=k*F;L>B?(R=L,N=R/F):(N=k,R=B),O=Math.max(R,N)}else{var U=Math.tan(.5*e.frustum.fovy),V=e.frustum.aspectRatio*U;if(O=Math.max(X(D,M,T,U),X(D,M,x,U),X(D,M,w,U),X(D,M,P,U),X(D,M,A,U),X(D,M,E,U),X(D,I,T,V),X(D,I,x,V),X(D,I,w,V),X(D,I,P,V),X(D,I,A,V),X(D,I,E,V)),u<0&&l>0){var z=it;z.longitude=h,z.latitude=0,z.height=0;var G=o.cartographicToCartesian(z,ht);r.subtract(G,b,G),O=Math.max(O,X(D,M,G,U),X(D,I,G,V)),z.longitude=c,G=o.cartographicToCartesian(z,ht),r.subtract(G,b,G),O=Math.max(O,X(D,M,G,U),X(D,I,G,V))}}return r.add(b,r.multiplyByScalar(D,-O,ht),i)}function Z(e,t,r){var i=e._projection;t.west>t.east&&(t=A.MAX_VALUE);var n=e._actualTransform,o=e._actualInvTransform,s=ft;s.longitude=t.east,s.latitude=t.north;var l=i.project(s,mt);y.multiplyByPoint(n,l,l),y.multiplyByPoint(o,l,l),s.longitude=t.west,s.latitude=t.south;var u=i.project(s,gt);if(y.multiplyByPoint(n,u,u),y.multiplyByPoint(o,u,u),r.x=.5*(l.x-u.x)+u.x,r.y=.5*(l.y-u.y)+u.y,a(e.frustum.fovy)){var c=Math.tan(.5*e.frustum.fovy),d=e.frustum.aspectRatio*c;r.z=.5*Math.max((l.x-u.x)/d,(l.y-u.y)/c)}else{var h=l.x-u.x,p=l.y-u.y;r.z=Math.max(h,p)}return r}function K(e,t,r){var i=e._projection;t.west>t.east&&(t=A.MAX_VALUE);var n=_t;n.longitude=t.east,n.latitude=t.north;var o=i.project(n,vt);n.longitude=t.west,n.latitude=t.south;var a,s,l=i.project(n,yt),u=.5*Math.abs(o.x-l.x),c=.5*Math.abs(o.y-l.y),d=e.frustum.right/e.frustum.top,h=c*d;return u>h?(a=u,s=a/d):(s=c,a=h),c=Math.max(2*a,2*s),r.x=.5*(o.x-l.x)+l.x,r.y=.5*(o.y-l.y)+l.y,n=i.unproject(r,n),n.height=c,r=i.project(n,r)}function J(e,t,r,i){r=o(r,c.WGS84);var n=e.getPickRay(t,Ct),a=g.rayEllipsoid(n,r);if(a){var s=a.start>0?a.start:a.stop;return T.getPoint(n,s,i)}}function $(e,t,r,i){var n=e.getPickRay(t,bt),o=n.origin;o.z=0;var a=r.unproject(o);if(!(a.latitude<-_.PI_OVER_TWO||a.latitude>_.PI_OVER_TWO))return r.ellipsoid.cartographicToCartesian(a,i)}function ee(e,t,i,n){var o=e.getPickRay(t,St),a=-o.origin.x/o.direction.x;T.getPoint(o,a,n);var s=i.unproject(new r(n.y,n.z,0));if(!(s.latitude<-_.PI_OVER_TWO||s.latitude>_.PI_OVER_TWO||s.longitude<-Math.PI||s.longitude>Math.PI))return i.ellipsoid.cartographicToCartesian(s,n)}function te(e,t,i){var n=e._scene.canvas,o=n.clientWidth,a=n.clientHeight,s=Math.tan(.5*e.frustum.fovy),l=e.frustum.aspectRatio*s,u=e.frustum.near,c=2/o*t.x-1,d=2/a*(a-t.y)-1,h=e.positionWC;r.clone(h,i.origin);var p=r.multiplyByScalar(e.directionWC,u,wt);r.add(h,p,p) -;var f=r.multiplyByScalar(e.rightWC,c*u*l,Tt),m=r.multiplyByScalar(e.upWC,d*u*s,At),g=r.add(p,f,i.direction);return r.add(g,m,g),r.subtract(g,h,g),r.normalize(g,g),i}function re(e,t,i){var n=e._scene.canvas,o=n.clientWidth,s=n.clientHeight,l=e.frustum;a(l._offCenterFrustum)&&(l=l._offCenterFrustum);var u=2/o*t.x-1;u*=.5*(l.right-l.left);var c=2/s*(s-t.y)-1;c*=.5*(l.top-l.bottom);var d=i.origin;return r.clone(e.position,d),r.multiplyByScalar(e.right,u,Et),r.add(Et,d,d),r.multiplyByScalar(e.up,c,Et),r.add(Et,d,d),r.clone(e.directionWC,i.direction),e._mode===D.COLUMBUS_VIEW&&r.fromElements(i.origin.z,i.origin.x,i.origin.y,i.origin),i}function ie(e,t,i,n,o,a){function s(i){var n=r.lerp(t,l,i.time,new r);e.worldToCameraCoordinatesPoint(n,e.position)}var l=r.clone(t);return i.y>n?l.y-=i.y-n:i.y<-n&&(l.y+=-n-i.y),i.z>o?l.z-=i.z-o:i.z<-o&&(l.z+=-o-i.z),{easingFunction:u.EXPONENTIAL_OUT,startObject:{time:0},stopObject:{time:1},duration:a,update:s}}function ne(e,t){var i=e.position,n=e.direction,o=e.worldToCameraCoordinatesVector(r.UNIT_X,It),a=-r.dot(o,i)/r.dot(o,n),s=r.add(i,r.multiplyByScalar(n,a,Ot),Ot);e.cameraToWorldCoordinatesPoint(s,s),i=e.cameraToWorldCoordinatesPoint(e.position,Mt);var l=Math.tan(.5*e.frustum.fovy),u=e.frustum.aspectRatio*l,c=r.magnitude(r.subtract(i,s,Rt)),d=u*c,h=l*c,p=e._maxCoord.x,f=e._maxCoord.y,m=Math.max(d-p,p),g=Math.max(h-f,f);if(i.z<-m||i.z>m||i.y<-g||i.y>g){var _=s.y<-m||s.y>m,v=s.z<-g||s.z>g;if(_||v)return ie(e,i,s,m,g,t)}}function oe(e,t){var r=e.frustum,i=Math.tan(.5*r.fovy),n=r.aspectRatio*i;return Math.max(t/n,t/i)}function ae(e,t){var r=e.frustum;a(r._offCenterFrustum)&&(r=r._offCenterFrustum);var i,n,o=r.right/r.top,s=t*o;return t>s?(i=t,n=i/o):(n=t,i=s),1.5*Math.max(i,n)}function se(e,t,r){a(r)||(r=p.clone(I.DEFAULT_OFFSET));var i=e._scene.screenSpaceCameraController.minimumZoomDistance,n=e._scene.screenSpaceCameraController.maximumZoomDistance,o=r.range;if(!a(o)||0===o){var s=t.radius;0===s?r.range=kt:e.frustum instanceof C||e._mode===D.SCENE2D?r.range=ae(e,s):r.range=oe(e,s),r.range=_.clamp(r.range,i,n)}return r}function le(e,t){var i,n,o=t.radii,a=e.positionWC,s=r.multiplyComponents(t.oneOverRadii,a,jt),l=r.magnitude(s),u=r.normalize(s,qt);r.equalsEpsilon(u,r.UNIT_Z,_.EPSILON10)?(i=new r(0,1,0),n=new r(0,0,1)):(i=r.normalize(r.cross(r.UNIT_Z,u,Yt),Yt),n=r.normalize(r.cross(u,i,Xt),Xt));var c=Math.sqrt(r.magnitudeSquared(s)-1),d=r.multiplyByScalar(u,1/l,jt),h=c/l,p=r.multiplyByScalar(i,h,qt),f=r.multiplyByScalar(n,h,Yt),m=r.add(d,f,Qt[0]);r.subtract(m,p,m),r.multiplyComponents(o,m,m);var g=r.subtract(d,f,Qt[1]);r.subtract(g,p,g),r.multiplyComponents(o,g,g);var v=r.subtract(d,f,Qt[2]);r.add(v,p,v),r.multiplyComponents(o,v,v);var y=r.add(d,f,Qt[3]);return r.add(y,p,y),r.multiplyComponents(o,y,y),Qt}function ue(e,t,r,i,n,o){Zt.x=e,Zt.y=t;var s=i.pickEllipsoid(Zt,n,Kt);return a(s)?(Jt[r]=n.cartesianToCartographic(s,Jt[r]),1):(Jt[r]=n.cartesianToCartographic(o[r],Jt[r]),0)}I.TRANSFORM_2D=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),I.TRANSFORM_2D_INVERSE=y.inverseTransformation(I.TRANSFORM_2D,new y),I.DEFAULT_VIEW_RECTANGLE=A.fromDegrees(-95,-20,-70,90),I.DEFAULT_VIEW_FACTOR=.5,I.DEFAULT_OFFSET=new p(0,-_.PI_OVER_FOUR,0),I.prototype._updateCameraChanged=function(){var e=this;if(0!==e._changed.numberOfListeners){var t=e.percentageChanged;if(e._mode===D.SCENE2D){if(!a(e._changedFrustum))return e._changedPosition=r.clone(e.position,e._changedPosition),void(e._changedFrustum=e.frustum.clone());var i,n=e.position,o=e._changedPosition,s=e.frustum,l=e._changedFrustum,u=n.x+s.left,c=n.x+s.right,d=o.x+l.left,h=o.x+l.right,p=n.y+s.bottom,f=n.y+s.top,m=o.y+l.bottom,g=o.y+l.top,v=Math.max(u,d),y=Math.min(c,h),C=Math.max(p,m),b=Math.min(f,g);if(v>=y||C>=f)i=1;else{var S=l;uh&&pg&&(S=s),i=1-(y-v)*(b-C)/((S.right-S.left)*(S.top-S.bottom))}return void(i>t&&(e._changed.raiseEvent(i),e._changedPosition=r.clone(e.position,e._changedPosition),e._changedFrustum=e.frustum.clone(e._changedFrustum)))}if(!a(e._changedDirection))return e._changedPosition=r.clone(e.positionWC,e._changedPosition),void(e._changedDirection=r.clone(e.directionWC,e._changedDirection));var w,T=_.acosClamped(r.dot(e.directionWC,e._changedDirection));w=a(e.frustum.fovy)?T/(.5*e.frustum.fovy):T;var A=r.distance(e.positionWC,e._changedPosition),E=A/e.positionCartographic.height;(w>t||E>t)&&(e._changed.raiseEvent(Math.max(w,E)),e._changedPosition=r.clone(e.positionWC,e._changedPosition),e._changedDirection=r.clone(e.directionWC,e._changedDirection))}};var ce=new y,de=new n;I.prototype._adjustHeightForTerrain=function(){var e=this._scene,t=e.screenSpaceCameraController,i=t.enableCollisionDetection,n=t.minimumCollisionTerrainHeight,o=t.minimumZoomDistance;if(!this._suspendTerrainAdjustment&&i){var s=this._mode,l=e.globe;if(a(l)&&s!==D.SCENE2D&&s!==D.MORPHING){var u,c,d=l.ellipsoid,h=e.mapProjection;y.equals(this.transform,y.IDENTITY)||(u=y.clone(this.transform,ce),c=r.magnitude(this.position),this._setTransform(y.IDENTITY));var p=de;s===D.SCENE3D?d.cartesianToCartographic(this.position,p):h.unproject(this.position,p);var f=!1;if(p.height_.PI?p+=_.TWO_PI-y:p+=y,f=v}return _.equalsEpsilon(Math.abs(p),_.TWO_PI,_.EPSILON9)&&(i.west=-_.PI,i.east=_.PI,Jt[0].latitude>=0?i.north=_.PI_OVER_TWO:i.south=-_.PI_OVER_TWO),i}},I.prototype.switchToPerspectiveFrustum=function(){if(!(this._mode===D.SCENE2D||this.frustum instanceof S)){var e=this._scene;this.frustum=new S,this.frustum.aspectRatio=e.drawingBufferWidth/e.drawingBufferHeight,this.frustum.fov=_.toRadians(60)}},I.prototype.switchToOrthographicFrustum=function(){if(!(this._mode===D.SCENE2D||this.frustum instanceof C)){var e=this._scene;this.frustum=new C,this.frustum.aspectRatio=e.drawingBufferWidth/e.drawingBufferHeight,this.frustum.width=r.magnitude(this.position);var t=this.frustum.projectionMatrix;a(t)&&this._adjustOrthographicFrustum(!0)}},I.clone=function(e,t){return a(t)||(t=new I(e._scene)),r.clone(e.position,t.position),r.clone(e.direction,t.direction),r.clone(e.up,t.up),r.clone(e.right,t.right),y.clone(e._transform,t.transform),t._transformChanged=!0,t},I}),define("Scene/CameraEventType",["../Core/freezeObject"],function(e){"use strict";return e({LEFT_DRAG:0,RIGHT_DRAG:1,MIDDLE_DRAG:2,WHEEL:3,PINCH:4})}),define("Scene/CameraEventAggregator",["../Core/Cartesian2","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/KeyboardEventModifier","../Core/Math","../Core/ScreenSpaceEventHandler","../Core/ScreenSpaceEventType","./CameraEventType"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){var i=e;return t(r)&&(i+="+"+r),i}function d(t,r){e.clone(t.distance.startPosition,r.distance.startPosition),e.clone(t.distance.endPosition,r.distance.endPosition),e.clone(t.angleAndHeight.startPosition,r.angleAndHeight.startPosition),e.clone(t.angleAndHeight.endPosition,r.angleAndHeight.endPosition)}function h(r,i,n){var o=c(u.PINCH,i),a=r._update,s=r._isDown,h=r._eventStartPosition,p=r._pressTime,f=r._releaseTime;a[o]=!0,s[o]=!1,h[o]=new e;var m=r._movement[o];t(m)||(m=r._movement[o]={}),m.distance={startPosition:new e,endPosition:new e},m.angleAndHeight={startPosition:new e,endPosition:new e},m.prevAngle=0,r._eventHandler.setInputAction(function(t){r._buttonsDown++,s[o]=!0,p[o]=new Date,e.lerp(t.position1,t.position2,.5,h[o])},l.PINCH_START,i),r._eventHandler.setInputAction(function(){r._buttonsDown=Math.max(r._buttonsDown-1,0),s[o]=!1,f[o]=new Date},l.PINCH_END,i),r._eventHandler.setInputAction(function(t){if(s[o]){a[o]?(d(t,m),a[o]=!1,m.prevAngle=m.angleAndHeight.startPosition.x):(e.clone(t.distance.endPosition,m.distance.endPosition),e.clone(t.angleAndHeight.endPosition,m.angleAndHeight.endPosition));for(var r=m.angleAndHeight.endPosition.x,i=m.prevAngle,l=2*Math.PI;r>=i+Math.PI;)r-=l;for(;r0||e}}}),_.prototype.isMoving=function(e,t){var r=c(e,t);return!this._update[r]},_.prototype.getMovement=function(e,t){var r=c(e,t);return this._movement[r]},_.prototype.getLastMovement=function(e,t){var r=c(e,t),i=this._lastMovement[r];if(i.valid)return i},_.prototype.isButtonDown=function(e,t){var r=c(e,t);return this._isDown[r]},_.prototype.getStartMousePosition=function(e,t){if(e===u.WHEEL)return this._currentMousePosition;var r=c(e,t);return this._eventStartPosition[r]},_.prototype.getButtonPressTime=function(e,t){var r=c(e,t);return this._pressTime[r]},_.prototype.getButtonReleaseTime=function(e,t){var r=c(e,t);return this._releaseTime[r]},_.prototype.reset=function(){for(var e in this._update)this._update.hasOwnProperty(e)&&(this._update[e]=!0)},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return this._eventHandler=this._eventHandler&&this._eventHandler.destroy(),i(this)},_}),define("Scene/Cesium3DTileChildrenVisibility",["../Core/freezeObject"],function(e){"use strict";return e({NONE:0,VISIBLE:1,IN_REQUEST_VOLUME:2,VISIBLE_IN_REQUEST_VOLUME:4,VISIBLE_NOT_IN_REQUEST_VOLUME:8})}),define("Scene/Composite3DTileContent",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/FeatureDetection","../Core/getMagic","../Core/RuntimeError","../ThirdParty/when"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r,i,n,o){this._tileset=e,this._tile=t,this._url=r,this._contents=[],this._readyPromise=s.defer(),u(this,i,n,o)}function u(r,i,n,l){n=e(n,0);var u=new Uint8Array(i),d=new DataView(i);n+=c;var h=d.getUint32(n,!0);if(1!==h)throw new a("Only Composite Tile version 1 is supported. Version "+h+" is not.");n+=c,n+=c;var p=d.getUint32(n,!0);n+=c;for(var f=[],m=0;m-1){if(!(n.indexOf(v)>-1))throw new h('Shader program cannot be optimized for instancing. Parameter "'+_+'" in program "'+t+'" uses unsupported semantic "'+v+'"');f[m]=v}}}}return r[t]}function D(e){return function(t,r){var i=P(e,r),n=a(e._batchTable),o=v.replaceMain(t,"czm_instancing_main"),s="",l="";for(var u in i)if(i.hasOwnProperty(u)){var c,d=i[u];"MODELVIEW"===d||"CESIUM_RTC_MODELVIEW"===d?c="czm_instanced_modelView":"MODELVIEWPROJECTION"===d?(c="czm_instanced_modelViewProjection",s+="mat4 czm_instanced_modelViewProjection;\n",l+="czm_instanced_modelViewProjection = czm_projection * czm_instanced_modelView;\n"):"MODELVIEWINVERSETRANSPOSE"===d&&(c="czm_instanced_modelViewInverseTranspose",s+="mat3 czm_instanced_modelViewInverseTranspose;\n",l+="czm_instanced_modelViewInverseTranspose = mat3(czm_instanced_modelView);\n");var h=new RegExp("uniform.*"+u+".*");o=o.replace(h,""),h=new RegExp(u+"\\b","g"),o=o.replace(h,c)}var p=n?"attribute float a_batchId;\n":"",f="uniform mat4 czm_instanced_modifiedModelView;\nuniform mat4 czm_instanced_nodeTransform;\n"+s+"mat4 czm_instanced_modelView;\nattribute vec4 czm_modelMatrixRow0;\nattribute vec4 czm_modelMatrixRow1;\nattribute vec4 czm_modelMatrixRow2;\n"+p+o+"void main()\n{\n mat4 czm_instanced_model = mat4(czm_modelMatrixRow0.x, czm_modelMatrixRow1.x, czm_modelMatrixRow2.x, 0.0, czm_modelMatrixRow0.y, czm_modelMatrixRow1.y, czm_modelMatrixRow2.y, 0.0, czm_modelMatrixRow0.z, czm_modelMatrixRow1.z, czm_modelMatrixRow2.z, 0.0, czm_modelMatrixRow0.w, czm_modelMatrixRow1.w, czm_modelMatrixRow2.w, 1.0);\n czm_instanced_modelView = czm_instanced_modifiedModelView * czm_instanced_model * czm_instanced_nodeTransform;\n"+l+" czm_instancing_main();\n}";return ne=f,n&&(f=e._batchTable.getVertexShaderCallback(!0,"a_batchId")(f)),f}}function I(e){return function(t){var r=e._batchTable;if(a(r)){var i=e._model.gltf,n=C(i,"_3DTILESDIFFUSE");t=r.getFragmentShaderCallback(!0,n)(t)}return t}}function O(e){return function(t){t=ne;var r=a(e._batchTable),i=e._allowPicking;return r?t=e._batchTable.getPickVertexShaderCallback("a_batchId")(t):i&&(t=v.createPickVertexShaderSource(t)),t}}function M(e){return function(t){var r=a(e._batchTable),i=e._allowPicking;return r?t=e._batchTable.getPickFragmentShaderCallback()(t):i&&(t=v.createPickFragmentShaderSource(t,"varying")),t}}function R(e,t){return function(){return c.multiply(t.uniformState.view,e._rtcTransform,e._rtcModelView)}}function N(e){return function(){return e.computedMatrix}}function L(e,t){return function(i,n,o){i=r(i),i.czm_instanced_modifiedModelView=R(e,t),i.czm_instanced_nodeTransform=N(o);var s=P(e,n);for(var l in s)s.hasOwnProperty(l)&&delete i[l];return a(e._batchTable)&&(i=e._batchTable.getUniformMapCallback()(i)),i}}function k(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getPickUniformMapCallback()(t)),t}}function F(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getVertexShaderCallback(!0,"a_batchId")(t),t="uniform float a_batchId\n;"+t),t}}function B(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getPickVertexShaderCallback("a_batchId")(t),t="uniform float a_batchId\n;"+t),t}}function U(e){return function(t){var r=a(e._batchTable),i=e._allowPicking;return r?t=e._batchTable.getPickFragmentShaderCallback()(t):i&&(t=v.createPickFragmentShaderSource(t,"uniform")),t}}function V(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getUniformMapCallback()(t)),t}}function z(e){var t=e._instances,r=e.length,i=e._center,n=e._vertexBufferTypedArray;a(n)||(n=new Float32Array(12*r)),e._dynamic&&(e._vertexBufferTypedArray=n);for(var o=0;o0){var j=m(u,s,L);H=JSON.parse(j),s+=L,k>0&&(W=new Uint8Array(i,s,k),W=new Uint8Array(W),s+=k)}r._batchTable=new A(r,G,H,W);var q=l+E-s;if(0===q)throw new b("glTF byte length is zero, i3dm must have a glTF to instance.");var Y;s%4==0?Y=new Uint8Array(i,s,q):(D._deprecationWarning("i3dm-glb-unaligned","The embedded glb is not aligned to a 4-byte boundary."),Y=new Uint8Array(u.subarray(s,s+q)));var X={instances:new Array(G),batchTable:r._batchTable,cull:!1,url:void 0,requestType:C.TILES3D,gltf:void 0,basePath:void 0,incrementallyLoadTextures:!1,upAxis:r._tileset._gltfUpAxis,opaquePass:T.CESIUM_3D_TILE};if(0===F){var Q=m(Y);Q=Q.replace(/[\s\0]+$/,""),X.url=p(g(f(r._url,!0),Q))}else X.gltf=Y,X.basePath=p(f(r._url,!0));var Z,K=z.getGlobalProperty("EAST_NORTH_UP"),J=z.getGlobalProperty("RTC_CENTER",n.FLOAT,3);a(J)&&(Z=t.unpack(J));for(var $=X.instances,ee=new t,te=new Array(3),re=new t,ie=new t,ne=new t,oe=new _,ae=new y,se=new t,le=new w,ue=new v,ce=0;ce0){for(var i=new Array(r),n=0;n0){var w=h(l,n,f);b=JSON.parse(w),n+=f,g>0&&(S=new Uint8Array(r,n,g),n+=g)}var T=new M(y,C),A=T.getGlobalProperty("POINTS_LENGTH");if(T.featuresLength=A,!s(A))throw new v("Feature table global property: POINTS_LENGTH must be defined");var E,x=!1;if(s(y.POSITION)){E=T.getPropertyArray("POSITION",o.FLOAT,3);var P=T.getGlobalProperty("RTC_CENTER",o.FLOAT,3);s(P)&&(e._rtcCenter=t.unpack(P))}else if(s(y.POSITION_QUANTIZED)){E=T.getPropertyArray("POSITION_QUANTIZED",o.UNSIGNED_SHORT,3),x=!0;var D=T.getGlobalProperty("QUANTIZED_VOLUME_SCALE",o.FLOAT,3);if(!s(D))throw new v("Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.");e._quantizedVolumeScale=t.unpack(D);var O=T.getGlobalProperty("QUANTIZED_VOLUME_OFFSET",o.FLOAT,3);if(!s(O))throw new v("Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.");e._quantizedVolumeOffset=t.unpack(O)}if(!s(E))throw new v("Either POSITION or POSITION_QUANTIZED must be defined.");var R,N=!1,L=!1;if(s(y.RGBA))R=T.getPropertyArray("RGBA",o.UNSIGNED_BYTE,4),N=!0;else if(s(y.RGB))R=T.getPropertyArray("RGB",o.UNSIGNED_BYTE,3);else if(s(y.RGB565))R=T.getPropertyArray("RGB565",o.UNSIGNED_SHORT,1),L=!0;else if(s(y.CONSTANT_RGBA)){var k=T.getGlobalProperty("CONSTANT_RGBA",o.UNSIGNED_BYTE,4);e._constantColor=i.fromBytes(k[0],k[1],k[2],k[3],e._constantColor)}else e._constantColor=i.clone(i.DARKGRAY,e._constantColor);e._isTranslucent=N;var F,B=!1;s(y.NORMAL)?F=T.getPropertyArray("NORMAL",o.FLOAT,3):s(y.NORMAL_OCT16P)&&(F=T.getPropertyArray("NORMAL_OCT16P",o.UNSIGNED_BYTE,2),B=!0);var U;if(s(y.BATCH_ID)){U=T.getPropertyArray("BATCH_ID",o.UNSIGNED_SHORT,1);var V=T.getGlobalProperty("BATCH_LENGTH");if(!s(V))throw new v("Global property: BATCH_LENGTH must be defined when BATCH_ID is defined.");s(S)&&(S=new Uint8Array(S)),e._batchTable=new I(e,V,b,S)}var z;if(!s(U)&&s(S)){z=I.getBinaryProperties(A,b,S);for(var G in z)if(z.hasOwnProperty(G)){var W=z[G],j=W.typedArray,q=o.fromTypedArray(j);q!==o.INT&&q!==o.UNSIGNED_INT&&q!==o.DOUBLE||(m("Cast pnts property to floats",'Point cloud property "'+G+'" will be casted to a float array because INT, UNSIGNED_INT, and DOUBLE are not valid WebGL vertex attribute types. Some precision may be lost.'),W.typedArray=new Float32Array(j))}}e._parsedContent={positions:E,colors:R,normals:F,batchIds:U,styleableProperties:z},e._pointsLength=A,e._isQuantized=x,e._isOctEncoded16P=B,e._isRGB565=L,e._hasColors=s(R),e._hasNormals=s(F),e._hasBatchIds=s(U)}function F(e,t){var r=t.context,a=e._parsedContent,l=e._pointsLength,u=a.positions,c=a.colors,d=a.normals,h=a.batchIds,p=a.styleableProperties,m=s(p),g=e._isQuantized,v=e._isOctEncoded16P,y=e._isRGB565,A=e._isTranslucent,E=e._hasColors,P=e._hasNormals,I=e._hasBatchIds,O=e._batchTable,M=s(O),R=[],N={};if(e._styleableShaderAttributes=N,m){var L=Q;for(var k in p)if(p.hasOwnProperty(k)){var F=p[k],B=F.typedArray,U=F.componentCount,V=o.fromTypedArray(B),z=C.createVertexBuffer({context:r,typedArray:F.typedArray,usage:b.STATIC_DRAW});e._geometryByteLength+=z.sizeInBytes;var G={index:L,vertexBuffer:z,componentsPerAttribute:U,componentDatatype:V,normalize:!1,offsetInBytes:0,strideInBytes:0};R.push(G),N[k]={location:L,componentCount:U},++L}}var H={u_pointSizeAndTilesetTime:function(){return W.x=e._pointSize,W.y=e._tileset.timeSinceLoad,W},u_highlightColor:function(){return e._highlightColor},u_constantColor:function(){return e._constantColor},u_clippingPlanesLength:function(){return e._packedClippingPlanes.length},u_clippingPlanes:function(){return e._packedClippingPlanes},u_clippingPlanesEdgeStyle:function(){var t=e._tileset.clippingPlanes;if(!s(t))return i.WHITE.withAlpha(0);var r=i.clone(t.edgeColor);return r.alpha=t.edgeWidth,r}};g&&(H=n(H,{u_quantizedVolumeScale:function(){return e._quantizedVolumeScale}}));var Z=C.createVertexBuffer({context:r,typedArray:u,usage:b.STATIC_DRAW});e._geometryByteLength+=Z.sizeInBytes;var K;E&&(K=C.createVertexBuffer({context:r,typedArray:c,usage:b.STATIC_DRAW}),e._geometryByteLength+=K.sizeInBytes);var J;P&&(J=C.createVertexBuffer({context:r,typedArray:d,usage:b.STATIC_DRAW}),e._geometryByteLength+=J.sizeInBytes);var $;I&&($=C.createVertexBuffer({context:r,typedArray:h,usage:b.STATIC_DRAW}),e._geometryByteLength+=$.sizeInBytes);var ee=[];if(g?ee.push({index:j,vertexBuffer:Z,componentsPerAttribute:3,componentDatatype:o.UNSIGNED_SHORT,normalize:!0,offsetInBytes:0,strideInBytes:0}):ee.push({index:j,vertexBuffer:Z,componentsPerAttribute:3,componentDatatype:o.FLOAT,normalize:!1,offsetInBytes:0,strideInBytes:0}),E)if(y)ee.push({index:q,vertexBuffer:K,componentsPerAttribute:1,componentDatatype:o.UNSIGNED_SHORT,normalize:!1,offsetInBytes:0,strideInBytes:0});else{var te=A?4:3;ee.push({index:q,vertexBuffer:K,componentsPerAttribute:te,componentDatatype:o.UNSIGNED_BYTE,normalize:!0,offsetInBytes:0,strideInBytes:0})}P&&(v?ee.push({index:Y,vertexBuffer:J,componentsPerAttribute:2,componentDatatype:o.UNSIGNED_BYTE,normalize:!1,offsetInBytes:0,strideInBytes:0}):ee.push({index:Y,vertexBuffer:J,componentsPerAttribute:3,componentDatatype:o.FLOAT,normalize:!1,offsetInBytes:0,strideInBytes:0})),I&&ee.push({index:X,vertexBuffer:$,componentsPerAttribute:1,componentDatatype:o.fromTypedArray(h),normalize:!1,offsetInBytes:0,strideInBytes:0}),m&&(ee=ee.concat(R));var re=new x({context:r,attributes:ee}),ie=H;M&&(ie=O.getUniformMapCallback()(H));var ne;M?ne=O.getPickUniformMapCallback()(H):(e._pickId=r.createPickId({primitive:e._tileset,content:e}),ne=n(H,{czm_pickColor:function(){return e._pickId.color}})),e._opaqueRenderState=T.fromCache({depthTest:{enabled:!0}}),e._translucentRenderState=T.fromCache({depthTest:{enabled:!0},depthMask:!1,blending:D.ALPHA_BLEND}),e._drawCommand=new S({boundingVolume:void 0,cull:!1,modelMatrix:new f,primitiveType:_.POINTS,vertexArray:re,count:l,shaderProgram:void 0,uniformMap:ie,renderState:A?e._translucentRenderState:e._opaqueRenderState,pass:A?w.TRANSLUCENT:w.CESIUM_3D_TILE,owner:e,castShadows:!1,receiveShadows:!1}),e._pickCommand=new S({boundingVolume:void 0,cull:!1,modelMatrix:new f,primitiveType:_.POINTS,vertexArray:re,count:l,shaderProgram:void 0,uniformMap:ne,renderState:A?e._translucentRenderState:e._opaqueRenderState,pass:A?w.TRANSLUCENT:w.CESIUM_3D_TILE,owner:e})}function B(e,t){for(var r=/czm_tiles3d_style_(\w+)/g,i=r.exec(e);null!==i;){var n=i[1];-1===t.indexOf(n)&&t.push(n),i=r.exec(e)}}function U(e,t){for(var r=e.numberOfAttributes,i=0;i=0,k=N.indexOf("NORMAL")>=0,F=N.filter(function(e){return-1===Z.indexOf(e)});if(k&&!b)throw new v("Style references the NORMAL semantic but the point cloud does not have normals");var z=e._styleableShaderAttributes;for(n in z)if(z.hasOwnProperty(n)){o=z[n];var G=F.indexOf(n)>=0,H=U(T,o.location);H.enabled=G}var W=C&&(!I||L);if(C){U(T,q).enabled=W}var Q={a_position:j};W&&(Q.a_color=q),b&&(Q.a_normal=Y),S&&(Q.a_batchId=X);var K="",J=F.length;for(i=0;i 0.0 && clipDistance < clippingPlanesEdgeWidth) \n { \n gl_FragColor = clippingPlanesEdgeColor; \n } \n"}ie+="} \n";var ne=re,oe=ie;p&&(ne=h.getVertexShaderCallback(!1,"a_batchId")(ne),oe=h.getFragmentShaderCallback(!1,void 0)(oe));var ae=re,se=ie;p?(ae=h.getPickVertexShaderCallback("a_batchId")(ae),se=h.getPickFragmentShaderCallback()(se)):se=E.createPickFragmentShaderSource(se,"uniform");var le=e._drawCommand;s(le.shaderProgram)&&le.shaderProgram.destroy(),le.shaderProgram=A.fromCache({context:c,vertexShaderSource:ne,fragmentShaderSource:oe,attributeLocations:Q});var ue=e._pickCommand;s(ue.shaderProgram)&&ue.shaderProgram.destroy(),ue.shaderProgram=A.fromCache({context:c,vertexShaderSource:ae,fragmentShaderSource:se,attributeLocations:Q});try{le.shaderProgram._bind()}catch(e){throw new v("Error generating style shader: this may be caused by a type mismatch, index out-of-bounds, or other syntax error.")}}function G(e){var t=e._tileset,r=e.featuresLength;if(!s(e._features)&&r>0){for(var i=new Array(r),n=0;n0){x.longitude=.5*(r.west+r.east),x.latitude=p;var m=i.cartographicToCartesian(x,D.origin);t.clone(d,D.direction);var g=h.fromPointNormal(e.southwestCornerCartesian,e.westNormal,P);u.rayPlane(D,g,e.southwestCornerCartesian),l=i.geodeticSurfaceNormal(m,S)}else l=i.geodeticSurfaceNormalCartographic(f.southeast(r),S);var _=t.cross(l,c,w);t.normalize(_,e.southNormal);var v,y=r.north;if(y<0){x.longitude=.5*(r.west+r.east),x.latitude=y;var C=i.cartographicToCartesian(x,D.origin);t.negate(d,D.direction);var I=h.fromPointNormal(e.northeastCornerCartesian,e.eastNormal,P);u.rayPlane(D,I,e.northeastCornerCartesian),v=i.geodeticSurfaceNormal(C,S)}else v=i.geodeticSurfaceNormalCartographic(f.northwest(r),S);var O=t.cross(c,v,w);t.normalize(O,e.northNormal)}a(y.prototype,{boundingVolume:{get:function(){return this._orientedBoundingBox}},boundingSphere:{get:function(){return this._boundingSphere}}});var b=new t,S=new t,w=new t,T=new t,A=new t,E=new t,x=new r,P=new h(t.UNIT_X,0),D=new p,I=new t,O=new t,M=new t(0,-1,0),R=new t(0,0,-1),N=new t;return y.prototype.distanceToCamera=function(e){var r=e.camera,i=r.positionWC,n=r.positionCartographic,o=0;if(!f.contains(this.rectangle,n)){var a=this.southwestCornerCartesian,s=this.northeastCornerCartesian,l=this.westNormal,u=this.southNormal,c=this.eastNormal,d=this.northNormal;e.mode!==v.SCENE3D&&(a=e.mapProjection.project(f.southwest(this.rectangle),I),a.z=a.y,a.y=a.x,a.x=0,s=e.mapProjection.project(f.northeast(this.rectangle),O),s.z=s.y,s.y=s.x,s.x=0,l=M,c=t.UNIT_Y,u=R,d=t.UNIT_Z);var h=t.subtract(i,a,N),p=t.dot(h,l),m=t.dot(h,u),g=t.subtract(i,s,N),_=t.dot(g,c),y=t.dot(g,d);p>0?o+=p*p:_>0&&(o+=_*_),m>0?o+=m*m:y>0&&(o+=y*y)}var C;C=e.mode===v.SCENE3D?n.height:i.x;var b=e.mode===v.SCENE3D?this.maximumHeight:0,S=C-b;return S>0&&(o+=S*S),Math.sqrt(o)},y.prototype.intersectPlane=function(e){return this._orientedBoundingBox.intersectPlane(e)},y.prototype.createDebugVolume=function(e){var t=new c.clone(c.IDENTITY),r=new m({rectangle:this.rectangle,height:this.minimumHeight,extrudedHeight:this.maximumHeight}),i=new l({geometry:r,modelMatrix:t,attributes:{color:n.fromColor(e)}});return new _({geometryInstances:i,appearance:new g({translucent:!1,flat:!0}),asynchronous:!1})},y}),define("Scene/TileBoundingSphere",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Check","../Core/ColorGeometryInstanceAttribute","../Core/defineProperties","../Core/GeometryInstance","../Core/Matrix4","../Core/SphereOutlineGeometry","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r){this._boundingSphere=new e(t,r)}return n(c.prototype,{center:{get:function(){return this._boundingSphere.center}},radius:{get:function(){return this._boundingSphere.radius}},boundingVolume:{get:function(){return this._boundingSphere}},boundingSphere:{get:function(){return this._boundingSphere}}}),c.prototype.distanceToCamera=function(e){var r=this._boundingSphere;return Math.max(0,t.distance(r.center,e.camera.positionWC)-r.radius)},c.prototype.intersectPlane=function(t){return e.intersectPlane(this._boundingSphere,t)},c.prototype.update=function(e,r){t.clone(e,this._boundingSphere.center),this._boundingSphere.radius=r},c.prototype.createDebugVolume=function(e){var t=new s({radius:this.radius}),r=a.fromTranslation(this.center,new a.clone(a.IDENTITY)),n=new o({geometry:t,modelMatrix:r,attributes:{color:i.fromColor(e)}});return new u({geometryInstances:n,appearance:new l({translucent:!1,flat:!0}),asynchronous:!1})},c}),define("Scene/TileOrientedBoundingBox",["../Core/BoundingSphere","../Core/BoxOutlineGeometry","../Core/Cartesian3","../Core/Check","../Core/ColorGeometryInstanceAttribute","../Core/defineProperties","../Core/GeometryInstance","../Core/Matrix3","../Core/Matrix4","../Core/OrientedBoundingBox","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t,r){this._orientedBoundingBox=new u(t,r),this._boundingSphere=e.fromOrientedBoundingBox(this._orientedBoundingBox)}return o(h.prototype,{boundingVolume:{get:function(){return this._orientedBoundingBox}},boundingSphere:{get:function(){return this._boundingSphere}}}),h.prototype.distanceToCamera=function(e){return Math.sqrt(this._orientedBoundingBox.distanceSquaredTo(e.camera.positionWC))},h.prototype.intersectPlane=function(e){return this._orientedBoundingBox.intersectPlane(e)},h.prototype.update=function(t,i){r.clone(t,this._orientedBoundingBox.center),s.clone(i,this._orientedBoundingBox.halfAxes),e.fromOrientedBoundingBox(this._orientedBoundingBox,this._boundingSphere)},h.prototype.createDebugVolume=function(e){var i=new t({minimum:new r(-1,-1,-1),maximum:new r(1,1,1)}),o=l.fromRotationTranslation(this.boundingVolume.halfAxes,this.boundingVolume.center),s=new a({geometry:i,modelMatrix:o,attributes:{color:n.fromColor(e)}});return new d({geometryInstances:s,appearance:new c({translucent:!1,flat:!0}),asynchronous:!1})},h}),define("Scene/Cesium3DTile",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Color","../Core/CullingVolume","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/getMagic","../Core/Intersect","../Core/joinUrls","../Core/JulianDate","../Core/loadArrayBuffer","../Core/Matrix3","../Core/Matrix4","../Core/Plane","../Core/Rectangle","../Core/Request","../Core/RequestScheduler","../Core/RequestState","../Core/RequestType","../Core/RuntimeError","../ThirdParty/when","./Cesium3DTileChildrenVisibility","./Cesium3DTileContentFactory","./Cesium3DTileContentState","./Cesium3DTileOptimizationHint","./Cesium3DTileRefine","./Empty3DTileContent","./SceneMode","./TileBoundingRegion","./TileBoundingSphere","./TileOrientedBoundingBox"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R){"use strict";function N(e,t,i,n){this._tileset=e,this._header=i;var a=i.content;this.transform=o(i.transform)?m.unpack(i.transform):m.clone(m.IDENTITY);var s=o(n)?n.computedTransform:e.modelMatrix,l=m.multiply(s,this.transform,new m);this.computedTransform=l,this._boundingVolume=this.createBoundingVolume(i.boundingVolume,l),this._boundingVolume2D=void 0;var u;o(a)&&o(a.boundingVolume)&&(u=this.createBoundingVolume(a.boundingVolume,l)),this._contentBoundingVolume=u,this._contentBoundingVolume2D=void 0;var c;o(i.viewerRequestVolume)&&(c=this.createBoundingVolume(i.viewerRequestVolume,l)),this._viewerRequestVolume=c,this.geometricError=i.geometricError,o(this.geometricError)||(this.geometricError=o(n)?n.geometricError:e._geometricError,N._deprecationWarning("geometricErrorUndefined","Required property geometricError is undefined for this tile. Using parent's geometric error instead."));var p;o(i.refine)?("replace"!==i.refine&&"add"!==i.refine||N._deprecationWarning("lowercase-refine",'This tile uses a lowercase refine "'+i.refine+'". Instead use "'+i.refine.toUpperCase()+'".'),p="REPLACE"===i.refine.toUpperCase()?P.REPLACE:P.ADD):p=o(n)?n.refine:P.REPLACE,this.refine=p,this.children=[],this.parent=n;var f,g,_,v,C;o(a)?(g=!1,_=E.UNLOADED,v=d(t,a.url),C=y.getServerKey(v)):(f=new D(e,this),g=!0,_=E.READY),this._content=f,this._contentUrl=v,this._contentState=_,this._contentReadyToProcessPromise=void 0,this._contentReadyPromise=void 0,this._expiredContent=void 0,this._serverKey=C,this.hasEmptyContent=g,this.hasRenderableContent=!1,this.hasTilesetContent=!1,this.replacementNode=void 0;var b,S,w=i.expire;o(w)&&(b=w.duration,o(w.date)&&(S=h.fromIso8601(w.date))),this.expireDuration=b,this.expireDate=S,this.selected=!1,this.lastStyleTime=0,this._optimChildrenWithinParent=x.NOT_COMPUTED,this._distanceToCamera=0,this._visibilityPlaneMask=0,this._childrenVisibility=T.VISIBLE,this._lastSelectedFrameNumber=-1,this._screenSpaceError=0,this._screenSpaceErrorComputedFrame=-1,this._finalResolution=!0,this._depth=0,this._centerZDepth=0,this._stackLength=0,this._selectedFrame=-1,this._selectionDepth=0,this._lastSelectionDepth=void 0,this._requestedFrame=void 0,this._lastVisitedFrame=void 0,this._ancestorWithContent=void 0,this._ancestorWithLoadedContent=void 0,this._isClipped=!0,this._debugBoundingVolume=void 0,this._debugContentBoundingVolume=void 0,this._debugViewerRequestVolume=void 0,this._debugColor=r.fromRandom({alpha:1}),this._debugColorizeTiles=!1,this._commandsLength=0,this._color=void 0,this._colorDirty=!1}function L(e){if(o(e.expireDuration)){var t=h.now(j);h.addSeconds(t,e.expireDuration,t),o(e.expireDate)?h.lessThan(e.expireDate,t)&&h.clone(t,e.expireDate):e.expireDate=h.clone(t)}}function k(e){return function(t){e._contentState=E.FAILED,e._contentReadyPromise.reject(t),e._contentReadyToProcessPromise.reject(t)}}function F(e){return function(){return e._distanceToCamera}}function B(t,r){if(r.mode!==I.SCENE3D&&!o(t._boundingVolume2D)){var i=t._boundingVolume.boundingSphere,n=e.projectTo2D(i,r.mapProjection,q);t._boundingVolume2D=new M(n.center,n.radius)}return r.mode!==I.SCENE3D?t._boundingVolume2D:t._boundingVolume}function U(t,r){if(r.mode!==I.SCENE3D&&!o(t._contentBoundingVolume2D)){var i=t._contentBoundingVolume.boundingSphere,n=e.projectTo2D(i,r.mapProjection,q);t._contentBoundingVolume2D=new M(n.center,n.radius)}return r.mode!==I.SCENE3D?t._contentBoundingVolume2D:t._contentBoundingVolume}function V(e,r,i){var n=t.fromElements(e[0],e[1],e[2],K),a=f.fromArray(e,3,Z);n=m.multiplyByPoint(r,n,n);var s=m.getRotation(r,X);return a=f.multiply(s,a,a),o(i)?(i.update(n,a),i):new R(n,a)}function z(e,t){var r=_.unpack(e,0,J);return o(t)?t:new O({rectangle:r,minimumHeight:e[4],maximumHeight:e[5]})}function G(e,r,i){var n=t.fromElements(e[0],e[1],e[2],K),a=e[3];n=m.multiplyByPoint(r,n,n);var s=m.getScale(r,Q);return a*=t.maximumComponent(s),o(i)?(i.update(n,a),i):new M(n,a)}function H(e,t,i){var n=o(e._header.content)&&o(e._header.content.boundingVolume),a=t.debugShowBoundingVolume||t.debugShowContentBoundingVolume&&!n;if(a){if(!o(e._debugBoundingVolume)){var s=e._finalResolution?n?r.WHITE:r.RED:r.YELLOW;e._debugBoundingVolume=e._boundingVolume.createDebugVolume(s)}e._debugBoundingVolume.update(i)}else!a&&o(e._debugBoundingVolume)&&(e._debugBoundingVolume=e._debugBoundingVolume.destroy());t.debugShowContentBoundingVolume&&n?(o(e._debugContentBoundingVolume)||(e._debugContentBoundingVolume=e._contentBoundingVolume.createDebugVolume(r.BLUE)),e._debugContentBoundingVolume.update(i)):!t.debugShowContentBoundingVolume&&o(e._debugContentBoundingVolume)&&(e._debugContentBoundingVolume=e._debugContentBoundingVolume.destroy()),t.debugShowViewerRequestVolume&&o(e._viewerRequestVolume)?(o(e._debugViewerRequestVolume)||(e._debugViewerRequestVolume=e._viewerRequestVolume.createDebugVolume(r.YELLOW)),e._debugViewerRequestVolume.update(i)):!t.debugShowViewerRequestVolume&&o(e._debugViewerRequestVolume)&&(e._debugViewerRequestVolume=e._debugViewerRequestVolume.destroy());var l=t.debugColorizeTiles&&!e._debugColorizeTiles,u=!t.debugColorizeTiles&&e._debugColorizeTiles;l?(e._debugColorizeTiles=!0,e.color=e._debugColor):u&&(e._debugColorizeTiles=!1,e.color=r.WHITE),e._colorDirty&&(e._colorDirty=!1,e._content.applyDebugSettings(!0,e._color)),u&&t.makeStyleDirty()}function W(e,t,r){var i=e._content,n=e._expiredContent;if(o(n)){if(!e.contentReady)return void n.update(t,r);e._expiredContent.destroy(),e._expiredContent=void 0}i.update(t,r)}N._deprecationWarning=s,a(N.prototype,{tileset:{get:function(){return this._tileset}},content:{get:function(){return this._content}},contentBoundingVolume:{get:function(){return n(this._contentBoundingVolume,this._boundingVolume)}},boundingSphere:{get:function(){return this._boundingVolume.boundingSphere}},color:{get:function(){return o(this._color)||(this._color=new r),r.clone(this._color)},set:function(e){this._color=r.clone(e,this._color),this._colorDirty=!0}},contentAvailable:{get:function(){return this.contentReady||o(this._expiredContent)&&this._contentState!==E.FAILED}},contentReady:{get:function(){return this._contentState===E.READY}},contentUnloaded:{get:function(){return this._contentState===E.UNLOADED}},contentExpired:{get:function(){return this._contentState===E.EXPIRED}},contentReadyToProcessPromise:{get:function(){if(o(this._contentReadyToProcessPromise))return this._contentReadyToProcessPromise.promise}},contentReadyPromise:{get:function(){if(o(this._contentReadyPromise))return this._contentReadyPromise.promise}},commandsLength:{get:function(){return this._commandsLength}}});var j=new h;N.prototype.updateExpiration=function(){if(o(this.expireDate)&&this.contentReady&&!this.hasEmptyContent){var e=h.now(j);h.lessThan(this.expireDate,e)&&(this._contentState=E.EXPIRED,this._expiredContent=this._content)}},N.prototype.requestContent=function(){var e=this,t=this._tileset;if(this.hasEmptyContent)return!1;var r=this._contentUrl,i=this.contentExpired;if(i){var n="?expired="+this.expireDate.toString();r=d(r,n,!1)}var a=new v({throttle:!0,throttleByServer:!0,type:b.TILES3D,priorityFunction:F(this),serverKey:this._serverKey}),s=p(r,void 0,a);if(!o(s))return!1;var l=this._contentState;this._contentState=E.LOADING,this._contentReadyToProcessPromise=w.defer(),this._contentReadyPromise=w.defer(),i&&(this.expireDate=void 0);var c=k(this);return s.then(function(r){if(e.isDestroyed())return void c();var i,n=new Uint8Array(r),a=u(n),s=A[a];return o(s)?(i=s(t,e,e._contentUrl,r,0),e.hasRenderableContent=!0):(i=A.json(t,e,e._contentUrl,r,0),e.hasTilesetContent=!0),e._content=i,e._contentState=E.PROCESSING,e._contentReadyToProcessPromise.resolve(i),i.readyPromise.then(function(t){if(e.isDestroyed())return void c();L(e),e.lastStyleTime=0,e._contentState=E.READY,e._contentReadyPromise.resolve(t)})}).otherwise(function(r){if(a.state===C.CANCELLED)return e._contentState=l,--t.statistics.numberOfPendingRequests,void++t.statistics.numberOfAttemptedRequests;c(r)}),!0},N.prototype.unloadContent=function(){this.hasRenderableContent&&(this._content=this._content&&this._content.destroy(),this._contentState=E.UNLOADED,this._contentReadyToProcessPromise=void 0,this._contentReadyPromise=void 0,this.replacementNode=void 0,this.lastStyleTime=0,this._debugColorizeTiles=!1,this._debugBoundingVolume=this._debugBoundingVolume&&this._debugBoundingVolume.destroy(),this._debugContentBoundingVolume=this._debugContentBoundingVolume&&this._debugContentBoundingVolume.destroy(),this._debugViewerRequestVolume=this._debugViewerRequestVolume&&this._debugViewerRequestVolume.destroy())};var q=new e;N.prototype.visibility=function(e,t){var r=e.cullingVolume,n=B(this,e),a=this._tileset,s=a.clippingPlanes;if(o(s)&&s.enabled){var l=a._root.computedTransform,u=s.computeIntersectionWithBoundingVolume(n,l);if(this._isClipped=u!==c.INSIDE,u===c.OUTSIDE)return i.MASK_OUTSIDE}return r.computeVisibilityWithPlaneMask(n,t)},N.prototype.contentVisibility=function(e){if(!o(this._contentBoundingVolume))return c.INSIDE;var t=e.cullingVolume,r=U(this,e),i=this._tileset,n=i.clippingPlanes;if(o(n)&&n.enabled){var a=i._root.computedTransform,s=n.computeIntersectionWithBoundingVolume(r,a);if(this._isClipped=s!==c.INSIDE,s===c.OUTSIDE)return c.OUTSIDE}return t.computeVisibility(r)},N.prototype.distanceToTile=function(e){return B(this,e).distanceToCamera(e)};var Y=new t;N.prototype.distanceToTileCenter=function(e){var r=B(this,e),i=r.boundingVolume,n=t.subtract(i.center,e.camera.positionWC,Y),o=t.magnitude(n);return t.divideByScalar(n,o,n),o*t.dot(e.camera.directionWC,n)},N.prototype.insideViewerRequestVolume=function(e){var t=this._viewerRequestVolume;return!o(t)||0===t.distanceToCamera(e)};var X=new f,Q=new t,Z=new f,K=new t,J=new _;N.prototype.createBoundingVolume=function(e,t,r){if(!o(e))throw new S("boundingVolume must be defined");if(o(e.box))return V(e.box,t,r);if(o(e.region))return z(e.region,r);if(o(e.sphere))return G(e.sphere,t,r);throw new S("boundingVolume must contain a sphere, region, or box")};var $=new m;N.prototype.updateTransform=function(e){e=n(e,m.IDENTITY);var t=m.multiply(e,this.transform,$);if(!m.equals(t,this.computedTransform)){m.clone(t,this.computedTransform);var r=this._header,i=this._header.content;this._boundingVolume=this.createBoundingVolume(r.boundingVolume,t,this._boundingVolume),o(this._contentBoundingVolume)&&(this._contentBoundingVolume=this.createBoundingVolume(i.boundingVolume,t,this._contentBoundingVolume)),o(this._viewerRequestVolume)&&(this._viewerRequestVolume=this.createBoundingVolume(r.viewerRequestVolume,t,this._viewerRequestVolume)),this._debugBoundingVolume=this._debugBoundingVolume&&this._debugBoundingVolume.destroy(),this._debugContentBoundingVolume=this._debugContentBoundingVolume&&this._debugContentBoundingVolume.destroy(),this._debugViewerRequestVolume=this._debugViewerRequestVolume&&this._debugViewerRequestVolume.destroy()}},N.prototype.update=function(e,t){var r=t.commandList.length;H(this,e,t),W(this,e,t),this._commandsLength=t.commandList.length-r};var ee=[];return N.prototype.process=function(e,t){var r=t.commandList;t.commandList=ee,this._content.update(e,t),ee.length=0,t.commandList=r},N.prototype.isDestroyed=function(){return!1},N.prototype.destroy=function(){return this._content=this._content&&this._content.destroy(),this._expiredContent=this._expiredContent&&!this._expiredContent.isDestroyed()&&this._expiredContent.destroy(),this._debugBoundingVolume=this._debugBoundingVolume&&this._debugBoundingVolume.destroy(),this._debugContentBoundingVolume=this._debugContentBoundingVolume&&this._debugContentBoundingVolume.destroy(),this._debugViewerRequestVolume=this._debugViewerRequestVolume&&this._debugViewerRequestVolume.destroy(),l(this)},N}),define("Scene/Cesium3DTileContent",["../Core/defineProperties","../Core/DeveloperError"],function(e,t){"use strict";function r(e,t,r,i,n){this.featurePropertiesDirty=!1}return e(r.prototype,{featuresLength:{get:function(){t.throwInstantiationError()}},pointsLength:{get:function(){t.throwInstantiationError()}},trianglesLength:{get:function(){t.throwInstantiationError()}},geometryByteLength:{get:function(){t.throwInstantiationError()}},texturesByteLength:{get:function(){t.throwInstantiationError()}},batchTableByteLength:{get:function(){t.throwInstantiationError()}},innerContents:{get:function(){t.throwInstantiationError()}},readyPromise:{get:function(){t.throwInstantiationError()}},tileset:{get:function(){t.throwInstantiationError()}},tile:{get:function(){t.throwInstantiationError()}},url:{get:function(){t.throwInstantiationError()}},batchTable:{get:function(){t.throwInstantiationError()}}}),r.prototype.hasProperty=function(e,r){t.throwInstantiationError()},r.prototype.getFeature=function(e){t.throwInstantiationError()},r.prototype.applyDebugSettings=function(e,r){t.throwInstantiationError()},r.prototype.applyStyle=function(e,r){t.throwInstantiationError()},r.prototype.update=function(e,r){t.throwInstantiationError()},r.prototype.isDestroyed=function(){t.throwInstantiationError()},r.prototype.destroy=function(){t.throwInstantiationError()},r}),define("Scene/Cesium3DTileOptimizations",["../Core/Cartesian3","../Core/Check","./Cesium3DTileOptimizationHint","./TileBoundingRegion","./TileOrientedBoundingBox"],function(e,t,r,i,n){"use strict";var o={},a=new e;return o.checkChildrenWithinParent=function(t){var o=t.children,s=o.length,l=t._boundingVolume;if(l instanceof n||l instanceof i){var u=l._orientedBoundingBox;t._optimChildrenWithinParent=r.USE_OPTIMIZATION;for(var c=0;c0;)for(var c=B.pop(),d=c.children,h=d.length,p=0;p0||a.length>0;){if(a.length>0){var s=a[a.length-1];if(s._stackLength===o.length){a.pop(),s===n&&(s._finalResolution=!0),p(e,s,i);continue}}var u=o.pop();if(t(u)&&b(u,i)){var c=u.selected&&u._selectedFrame===i.frameNumber&&u.hasRenderableContent,d=u.children,h=d.length;if(d.sort(f),c)if(u.refine===l.ADD)u._finalResolution=!0,p(e,u,i);else{if(u._selectionDepth=a.length,u._selectionDepth>0&&(e._hasMixedContent=!0),n=u,0===h){u._finalResolution=!0,p(e,u,i);continue}a.push(u),u._stackLength=o.length}for(var m=0;mn;return O(r._visibilityPlaneMask)&&(!a||P(e,o.geometricError,r,i)>n)}function R(e){return e.refine===l.ADD||0===e.children.length||e._childrenVisibility&0!==s.VISIBLE}function N(e){return e.refine===l.ADD&&e.hasRenderableContent}function L(e,r){var i=r.stack;!t(e)||t(r.shouldVisit)&&!r.shouldVisit(e)||i.push(e);for(var n=0;i.length>0;){n=Math.max(n,i.length);var o=i.pop();r.visitStart(o);for(var a=r.getChildren(o),s=!t(a.get),l=a.length,u=0;u0;){var a=i.length;o=Math.max(o,a);for(var s=0;si,a=e.refine===l.REPLACE&&0!=(n&s.VISIBLE_IN_REQUEST_VOLUME);if(n&s.VISIBLE_NOT_IN_REQUEST_VOLUME&&e.refine===l.REPLACE&&this.tileset._desiredTiles.push(e),o||a||e.hasTilesetContent){for(var u=e.children,c=u.length,d=0;dp.minimumRadius){var g=r.fromCartesian(m,p,te);n=t.normalize(u.positionWC,ee),o=u.directionWC,a=u.positionCartographic.height,s=0,l=2*g.height}else{var _=y.multiplyByPoint(h,u.positionWC,ne);if(n=t.UNIT_Z,o=y.multiplyByPointAsVector(h,u.directionWC,oe),o=t.normalize(o,o),a=_.z,d instanceof k){var C=c._header.boundingVolume.box[11];s=m.z-C,l=m.z+C}else if(d instanceof L){var b=f.radius;s=m.z-b,l=m.z+b}}}var S=e.dynamicScreenSpaceErrorHeightFalloff,w=s+(l-s)*S,T=l,A=v.clamp((a-w)/(T-w),0,1),E=Math.abs(t.dot(o,n)),x=1-E;x*=1-A;var P=e.dynamicScreenSpaceErrorDensity;P*=x,e._dynamicScreenSpaceErrorComputedDensity=P}function U(e,t,r){var i=e.skipLevelOfDetail?e.skipLevels:0,n=e.skipLevelOfDetail?e.skipScreenSpaceErrorFactor:1;return t!==r&&!r.hasEmptyContent&&!e.immediatelyLoadDesiredLevelOfDetail&&r._screenSpaceErrort._depth+i}function V(e,t){if(!t.hasEmptyContent){var r=e._statistics,i=t.contentExpired;if(!t.requestContent())return void++r.numberOfAttemptedRequests;i&&(t.hasRenderableContent?(r.decrementLoadCounts(t.content),--e._statistics.numberOfTilesWithContentReady):t.hasTilesetContent&&Z(e,t)),++r.numberOfPendingRequests;var n=H(e,t);t.contentReadyToProcessPromise.then(G(e,t)),t.contentReadyPromise.then(function(){n(),e.tileLoad.raiseEvent(t)}).otherwise(n)}}function z(e,t){if(t)for(var r=e._requestedTiles,i=r.length,n=0;n=0;--n)r[n].process(e,t)}function j(e){var t=e/1048576;return t<1?t.toLocaleString(void 0,se):Math.round(t).toLocaleString()}function q(e){var r=e._boundingVolume.boundingVolume,i=r.halfAxes,n=r.radius,a=t.clone(r.center,ae);if(o(i))a.x+=.75*(i[0]+i[3]+i[6]),a.y+=.75*(i[1]+i[4]+i[7]),a.z+=.75*(i[2]+i[5]+i[8]);else if(o(n)){var s=t.normalize(r.center,ae);s=t.multiplyByScalar(s,.75*n,ae),a=t.add(s,r.center,ae)}return a}function Y(e,t,r){var i="",n=0;if(t.debugShowGeometricError&&(i+="\nGeometric error: "+e.geometricError,n++),t.debugShowRenderingStatistics){i+="\nCommands: "+e.commandsLength,n++;e.content.pointsLength>0&&(i+="\nPoints: "+e.content.pointsLength,n++);e.content.trianglesLength>0&&(i+="\nTriangles: "+e.content.trianglesLength,n++),i+="\nFeatures: "+e.content.featuresLength,n++}t.debugShowMemoryUsage&&(i+="\nTexture Memory: "+j(e.content.texturesByteLength),i+="\nGeometry Memory: "+j(e.content.geometryByteLength),n+=2),t.debugShowUrl&&(i+="\nUrl: "+e._header.content.url,n++);var o={text:i.substring(1),position:r,font:19-n+"px sans-serif",showBackground:!0,disableDepthTestDistance:Number.POSITIVE_INFINITY};return t._tileDebugLabels.add(o)}function X(t,r){var i=t._selectedTiles,n=i.length;if(t._tileDebugLabels.removeAll(),t.debugPickedTileLabelOnly){if(o(t.debugPickedTile)){var a=o(t.debugPickPosition)?t.debugPickPosition:q(t.debugPickedTile),s=Y(t.debugPickedTile,t,a);s.pixelOffset=new e(15,-15)}}else for(var l=0;l0;e._backfaceCommands.length=0,c&&n.push(le);var d=n.length;for(r=0;r=0;--r)n[d+g+r]=n[d+r];for(r=0;r0;){t=n.pop();for(var o=t.children,a=o.length,s=0;sn||t);){var s=a.item;a=a.next,K(e,s),s.unloadContent(),i=e.totalMemoryUsageInBytes}}function $(e,t){var r=e._statistics,i=e._statisticsLastColor,n=r.numberOfPendingRequests,o=r.numberOfTilesProcessing,a=i.numberOfPendingRequests,s=i.numberOfTilesProcessing,l=n!==a||o!==s;l&&t.afterRender.push(function(){e.loadProgress.raiseEvent(n,o)}),e._tilesLoaded=0===r.numberOfPendingRequests&&0===r.numberOfTilesProcessing&&0===r.numberOfAttemptedRequests,l&&e._tilesLoaded&&t.afterRender.push(function(){e.allTilesLoaded.raiseEvent()})}a(F.prototype,{asset:{get:function(){return this._asset}},properties:{get:function(){return this._properties}},ready:{get:function(){return o(this._root)}},readyPromise:{get:function(){return this._readyPromise.promise}},tilesLoaded:{get:function(){return this._tilesLoaded}},url:{get:function(){return this._url}},basePath:{get:function(){return this._basePath}},style:{get:function(){return this._styleEngine.style},set:function(e){this._styleEngine.style=e}},maximumScreenSpaceError:{get:function(){return this._maximumScreenSpaceError},set:function(e){this._maximumScreenSpaceError=e}},maximumMemoryUsage:{get:function(){return this._maximumMemoryUsage},set:function(e){this._maximumMemoryUsage=e}},boundingSphere:{get:function(){return this._root.boundingSphere}},modelMatrix:{get:function(){return this._modelMatrix},set:function(e){this._modelMatrix=y.clone(e,this._modelMatrix),o(this._root)&&this._root.updateTransform(this._modelMatrix)}},timeSinceLoad:{get:function(){return this._timeSinceLoad}},totalMemoryUsageInBytes:{get:function(){var e=this._statistics;return e.texturesByteLength+e.geometryByteLength+e.batchTableByteLength}},styleEngine:{get:function(){return this._styleEngine}},statistics:{get:function(){return this._statistics}}}),F.loadJson=function(e){return g(e)},F.prototype.makeStyleDirty=function(){this._styleEngine.makeDirty()},F.prototype.loadTileset=function(e,t,r){var i=t.asset;if(!o(i))throw new C("Tileset must have an asset property.");if("0.0"!==i.version&&"1.0"!==i.version)throw new C("The tileset must be 3D Tiles version 0.0 or 1.0. See https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status");var a=this._statistics;if(!/[?&]v=/.test(e)){var s="?v="+n(i.tilesetVersion,"0.0");this._basePath=f(this._basePath,s),e=f(e,s,!1)}var l=d(e,!0),u=new A(this,l,t.root,r);o(r)&&(r.children.push(u),u._depth=r._depth+1),++a.numberOfTilesTotal;var c=[];for(c.push({header:t.root,tile3D:u});c.length>0;){var h=c.pop(),p=h.tile3D,m=h.header.children;if(o(m))for(var g=m.length,_=0;_0;){var t=e.pop();t.destroy();for(var r=t.children,i=r.length,n=0;n":7,"<=":7,">=":7,"<<":8,">>":8,">>>":8,"+":9,"-":9,"*":10,"/":10,"%":10},n=function(e){var t,r=0;for(var i in e)(t=i.length)>r&&e.hasOwnProperty(i)&&(r=t);return r},o=n(r),a=n(i),s={true:!0,false:!1,null:null},l=function(e){return i[e]||0},u=function(e,t,r){return{type:"||"===e||"&&"===e?"LogicalExpression":"BinaryExpression",operator:e,left:t,right:r}},c=function(e){return e>=48&&e<=57},d=function(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||e>=128&&!i[String.fromCharCode(e)]},h=function(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||e>=128&&!i[String.fromCharCode(e)]},p=function(e){for(var n,p,f=0,m=e.charAt,g=e.charCodeAt,_=function(t){return m.call(e,t)},v=function(t){return g.call(e,t)},y=e.length,C=function(){for(var e=v(f);32===e||9===e;)e=v(++f)},b=function(){var e,r,i=w();return C(),63!==v(f)?i:(f++,e=b(),e||t("Expected expression",f),C(),58===v(f)?(f++,r=b(),r||t("Expected expression",f),{type:"ConditionalExpression",test:i,consequent:e,alternate:r}):void t("Expected :",f))},S=function(){C();for(var t=e.substr(f,a),r=t.length;r>0;){if(i.hasOwnProperty(t))return f+=r,t;t=t.substr(0,--r)}return!1},w=function(){var e,r,i,n,o,a,s,c;if(a=T(),!(r=S()))return a;for(o={value:r,prec:l(r)},s=T(),s||t("Expected expression after "+r,f),n=[a,o,s];(r=S())&&0!==(i=l(r));){for(o={value:r,prec:i};n.length>2&&i<=n[n.length-2].prec;)s=n.pop(),r=n.pop().value,a=n.pop(),e=u(r,a,s),n.push(e);e=T(),e||t("Expected expression after "+r,f),n.push(o,e)}for(c=n.length-1,e=n[c];c>1;)e=u(n[c-1].value,n[c-2],e),c-=2;return e},T=function(){var t,i,n;if(C(),t=v(f),c(t)||46===t)return A();if(39===t||34===t)return E();if(d(t)||40===t)return D();if(91===t)return O();for(i=e.substr(f,o),n=i.length;n>0;){if(r.hasOwnProperty(i))return f+=n,{type:"UnaryExpression",operator:i,argument:T(),prefix:!0};i=i.substr(0,--n)}return!1},A=function(){for(var e,r,i="";c(v(f));)i+=_(f++);if(46===v(f))for(i+=_(f++);c(v(f));)i+=_(f++);if("e"===(e=_(f))||"E"===e){for(i+=_(f++),e=_(f),"+"!==e&&"-"!==e||(i+=_(f++));c(v(f));)i+=_(f++);c(v(f-1))||t("Expected exponent ("+i+_(f)+")",f)}return r=v(f),d(r)?t("Variable names cannot start with a number ("+i+_(f)+")",f):46===r&&t("Unexpected period",f),{type:"Literal",value:parseFloat(i),raw:i}},E=function(){for(var e,r="",i=_(f++),n=!1;f=0;){var n,o=t.indexOf("'"),a=t.indexOf('"');if(o>=0&&o=0&&a=0?new A(h.VARIABLE_IN_STRING,e.value):new A(h.LITERAL_STRING,P(e.value)):void 0}function O(e,t){var r,i,n,a,s=t.arguments,l=s.length;if("MemberExpression"===t.callee.type){r=t.callee.property.name;var u=t.callee.object;if("test"===r||"exec"===r){if("regExp"!==u.callee.name)throw new c(r+" is not a function.");return 0===l?"test"===r?new A(h.LITERAL_BOOLEAN,!1):new A(h.LITERAL_NULL,null):(n=U(e,u),a=U(e,s[0]),new A(h.FUNCTION_CALL,r,n,a))}if("toString"===r)return i=U(e,u),new A(h.FUNCTION_CALL,r,i);throw new c('Unexpected function call "'+r+'".')}if("color"===(r=t.callee.name)){if(0===l)return new A(h.LITERAL_COLOR,r);if(i=U(e,s[0]),o(s[1])){var d=U(e,s[1]);return new A(h.LITERAL_COLOR,r,[i,d])}return new A(h.LITERAL_COLOR,r,[i])}if("rgb"===r||"hsl"===r){if(l<3)throw new c(r+" requires three arguments.");return i=[U(e,s[0]),U(e,s[1]),U(e,s[2])],new A(h.LITERAL_COLOR,r,i)}if("rgba"===r||"hsla"===r){if(l<4)throw new c(r+" requires four arguments.");return i=[U(e,s[0]),U(e,s[1]),U(e,s[2]),U(e,s[3])],new A(h.LITERAL_COLOR,r,i)}if("vec2"===r||"vec3"===r||"vec4"===r){i=new Array(l);for(var p=0;p1)throw new c(r+" requires exactly one argument.");return i=U(e,s[0]),new A(h.UNARY,r,i)}if("getExactClassName"===r){if(l>0)throw new c(r+" does not take any argument.");return new A(h.UNARY,r)}if(o(ae[r])){if(1!==l)throw new c(r+" requires exactly one argument.");return i=U(e,s[0]),new A(h.UNARY,r,i)}if(o(se[r])){if(2!==l)throw new c(r+" requires exactly two arguments.");return n=U(e,s[0]),a=U(e,s[1]),new A(h.BINARY,r,n,a)}if(o(le[r])){if(3!==l)throw new c(r+" requires exactly three arguments.");n=U(e,s[0]),a=U(e,s[1]);var f=U(e,s[2]);return new A(h.TERNARY,r,n,a,f)}if("Boolean"===r)return 0===l?new A(h.LITERAL_BOOLEAN,!1):(i=U(e,s[0]),new A(h.UNARY,r,i));if("Number"===r)return 0===l?new A(h.LITERAL_NUMBER,0):(i=U(e,s[0]),new A(h.UNARY,r,i));if("String"===r)return 0===l?new A(h.LITERAL_STRING,""):(i=U(e,s[0]),new A(h.UNARY,r,i));if("regExp"===r)return M(e,t);throw new c('Unexpected function call "'+r+'".')}function M(e,t){var r=t.arguments;if(0===r.length)return new A(h.LITERAL_REGEX,new RegExp);var i,n=U(e,r[0]);if(r.length>1){var o=U(e,r[1]);if(k(n)&&k(o)){try{i=new RegExp(P(String(n._value)),o._value)}catch(e){throw new c(e)}return new A(h.LITERAL_REGEX,i)}return new A(h.REGEX,n,o)}if(k(n)){try{i=new RegExp(P(String(n._value)))}catch(e){throw new c(e)}return new A(h.LITERAL_REGEX,i)}return new A(h.REGEX,n)}function R(e){if(F(e.name)){var t=B(e.name);return"tiles3d_"===t.substr(0,8)?new A(h.BUILTIN_VARIABLE,t):new A(h.VARIABLE,t)}if("NaN"===e.name)return new A(h.LITERAL_NUMBER,NaN);if("Infinity"===e.name)return new A(h.LITERAL_NUMBER,1/0);if("undefined"===e.name)return new A(h.LITERAL_UNDEFINED,void 0);throw new c(e.name+" is not defined.")}function N(e){var t=e.property.name;return"PI"===t?new A(h.LITERAL_NUMBER,Math.PI):"E"===t?new A(h.LITERAL_NUMBER,Math.E):void 0}function L(e,t){if("Math"===t.object.name)return N(t);var r,i=U(e,t.object);return t.computed?(r=U(e,t.property),new A(h.MEMBER,"brackets",i,r)):(r=new A(h.LITERAL_STRING,t.property.name),new A(h.MEMBER,"dot",i,r))}function k(e){return e._type>=h.LITERAL_NULL}function F(e){return"czm_"===e.substr(0,4)}function B(e){return e.substr(4)}function U(e,t){var r,i,n,o;if("Literal"===t.type)r=I(t);else if("CallExpression"===t.type)r=O(e,t);else if("Identifier"===t.type)r=R(t);else if("UnaryExpression"===t.type){i=t.operator;var a=U(e,t.argument);if(!($.indexOf(i)>-1))throw new c('Unexpected operator "'+i+'".');r=new A(h.UNARY,i,a)}else if("BinaryExpression"===t.type){if(i=t.operator,n=U(e,t.left),o=U(e,t.right),!(ee.indexOf(i)>-1))throw new c('Unexpected operator "'+i+'".');r=new A(h.BINARY,i,n,o)}else if("LogicalExpression"===t.type)i=t.operator,n=U(e,t.left),o=U(e,t.right),ee.indexOf(i)>-1&&(r=new A(h.BINARY,i,n,o));else if("ConditionalExpression"===t.type){var s=U(e,t.test);n=U(e,t.consequent),o=U(e,t.alternate),r=new A(h.CONDITIONAL,"?",n,o,s)}else if("MemberExpression"===t.type)r=L(e,t);else{if("ArrayExpression"!==t.type)throw new c("Compound"===t.type?"Provide exactly one expression.":"Cannot parse expression.");for(var l=[],u=0;u"===e._value?e.evaluate=e._evaluateGreaterThan:">="===e._value?e.evaluate=e._evaluateGreaterThanOrEquals:"&&"===e._value?e.evaluate=e._evaluateAnd:"||"===e._value?e.evaluate=e._evaluateOr:"=~"===e._value?e.evaluate=e._evaluateRegExpMatch:"!~"===e._value?e.evaluate=e._evaluateRegExpNotMatch:o(se[e._value])&&(e.evaluate=H(e._value)):e._type===h.TERNARY?e.evaluate=W(e._value):e._type===h.MEMBER?"brackets"===e._value?e.evaluate=e._evaluateMemberBrackets:e.evaluate=e._evaluateMemberDot:e._type===h.ARRAY?e.evaluate=e._evaluateArray:e._type===h.VARIABLE?e.evaluate=e._evaluateVariable:e._type===h.VARIABLE_IN_STRING?e.evaluate=e._evaluateVariableString:e._type===h.LITERAL_COLOR?e.evaluate=e._evaluateLiteralColor:e._type===h.LITERAL_VECTOR?e.evaluate=e._evaluateLiteralVector:e._type===h.LITERAL_STRING?e.evaluate=e._evaluateLiteralString:e._type===h.REGEX?e.evaluate=e._evaluateRegExp:e._type===h.BUILTIN_VARIABLE?"tiles3d_tileset_time"===e._value&&(e.evaluate=z):e.evaluate=e._evaluateLiteral}function z(e,t){return t.content.tileset.timeSinceLoad}function G(e){var t=ae[e];return function(r,i){var n=this._left.evaluate(r,i);return t(e,n)}}function H(e){var t=se[e];return function(r,i){var n=this._left.evaluate(r,i),o=this._right.evaluate(r,i);return t(e,n,o)}}function W(e){var t=le[e];return function(r,i){var n=this._left.evaluate(r,i),o=this._right.evaluate(r,i),a=this._test.evaluate(r,i);return t(e,n,o,a)}}function j(e){return"feature"===e._value}function q(e){for(var t=e._left,r=t.length,i=0;i=this.arrayArray.length&&this.arrayArray.push([]);var e=this.arrayArray[this.arrayIndex++];return e.length=0,e},getCartesian2:function(){return this.cartesian2Index>=this.cartesian2Array.length&&this.cartesian2Array.push(new e),this.cartesian2Array[this.cartesian2Index++]},getCartesian3:function(){return this.cartesian3Index>=this.cartesian3Array.length&&this.cartesian3Array.push(new t),this.cartesian3Array[this.cartesian3Index++]},getCartesian4:function(){return this.cartesian4Index>=this.cartesian4Array.length&&this.cartesian4Array.push(new r),this.cartesian4Array[this.cartesian4Index++]}};p.prototype.evaluate=function(i,o,a){J.reset();var s=this._runtimeAst.evaluate(i,o);return a instanceof n&&s instanceof r?n.fromCartesian4(s,a):s instanceof e||s instanceof t||s instanceof r?s.clone(a):s},p.prototype.evaluateColor=function(e,t,r){J.reset();var i=this._runtimeAst.evaluate(e,t);return n.fromCartesian4(i,r)},p.prototype.getShaderFunction=function(e,t,r,i){var n=this.getShaderExpression(t,r);return n=i+" "+e+"() \n{ \n return "+n+"; \n} \n"},p.prototype.getShaderExpression=function(e,t){return this._runtimeAst.getShaderExpression(e,t)};var $=["!","-","+"],ee=["+","-","*","/","%","===","!==",">",">=","<","<=","&&","||","!~","=~"],te=/\${(.*?)}/g,re=/\\/g,ie="@#%",ne=/@#%/g,oe=new n,ae={abs:_(Math.abs),sqrt:_(Math.sqrt),cos:_(Math.cos),sin:_(Math.sin),tan:_(Math.tan),acos:_(Math.acos),asin:_(Math.asin),atan:_(Math.atan),radians:_(u.toRadians),degrees:_(u.toDegrees),sign:_(u.sign),floor:_(Math.floor),ceil:_(Math.ceil),round:_(Math.round),exp:_(Math.exp),exp2:_(m),log:_(Math.log),log2:_(g),fract:_(f),length:C,normalize:b},se={atan2:v(Math.atan2,!1),pow:v(Math.pow,!1),min:v(Math.min,!0),max:v(Math.max,!0),distance:S,dot:w,cross:T},le={clamp:y(u.clamp,!0),mix:y(u.lerp,!0)};return A.prototype._evaluateLiteral=function(e,t){return this._value},A.prototype._evaluateLiteralColor=function(e,t){var i=oe,a=this._left;if("color"===this._value)o(a)?a.length>1?(n.fromCssColorString(a[0].evaluate(e,t),i),i.alpha=a[1].evaluate(e,t)):n.fromCssColorString(a[0].evaluate(e,t),i):n.fromBytes(255,255,255,255,i);else if("rgb"===this._value)n.fromBytes(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),255,i);else if("rgba"===this._value){var s=255*a[3].evaluate(e,t);n.fromBytes(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),s,i)}else"hsl"===this._value?n.fromHsl(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),1,i):"hsla"===this._value&&n.fromHsl(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),a[3].evaluate(e,t),i);return r.fromColor(i,J.getCartesian4())},A.prototype._evaluateLiteralVector=function(i,n){for(var o=J.getArray(),a=this._value,s=this._left,l=s.length,u=0;u1)throw new c("Invalid "+a+" constructor. Not enough arguments.");if(h>p&&l>1)throw new c("Invalid "+a+" constructor. Too many arguments.");if(1===h){var f=o[0];o.push(f,f,f)}return"vec2"===a?e.fromArray(o,0,J.getCartesian2()):"vec3"===a?t.fromArray(o,0,J.getCartesian3()):"vec4"===a?r.fromArray(o,0,J.getCartesian4()):void 0},A.prototype._evaluateLiteralString=function(e,t){return this._value},A.prototype._evaluateVariableString=function(e,t){for(var r=this._value,i=te.exec(r);null!==i;){var n=i[0],a=i[1],s=t.getProperty(a);o(s)||(s=""),r=r.replace(n,s),i=te.exec(r)}return r},A.prototype._evaluateVariable=function(e,t){return t.getProperty(this._value)},A.prototype._evaluateMemberDot=function(i,n){if(j(this._left))return n.getProperty(this._right.evaluate(i,n));var a=this._left.evaluate(i,n);if(o(a)){var s=this._right.evaluate(i,n);if(a instanceof e||a instanceof t||a instanceof r){if("r"===s)return a.x;if("g"===s)return a.y;if("b"===s)return a.z;if("a"===s)return a.w}return a[s]}},A.prototype._evaluateMemberBrackets=function(i,n){if(j(this._left))return n.getProperty(this._right.evaluate(i,n));var a=this._left.evaluate(i,n);if(o(a)){var s=this._right.evaluate(i,n);if(a instanceof e||a instanceof t||a instanceof r){if(0===s||"r"===s)return a.x;if(1===s||"g"===s)return a.y;if(2===s||"b"===s)return a.z;if(3===s||"a"===s)return a.w}return a[s]}},A.prototype._evaluateArray=function(e,t){for(var r=[],i=0;i" requires number arguments. Arguments are '+r+" and "+i+".");return r>i},A.prototype._evaluateGreaterThanOrEquals=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if("number"!=typeof r||"number"!=typeof i)throw new c('Operator ">=" requires number arguments. Arguments are '+r+" and "+i+".");return r>=i},A.prototype._evaluateOr=function(e,t){var r=this._left.evaluate(e,t);if("boolean"!=typeof r)throw new c('Operator "||" requires boolean arguments. First argument is '+r+".");if(r)return!0;var i=this._right.evaluate(e,t);if("boolean"!=typeof i)throw new c('Operator "||" requires boolean arguments. Second argument is '+i+".");return r||i},A.prototype._evaluateAnd=function(e,t){var r=this._left.evaluate(e,t);if("boolean"!=typeof r)throw new c('Operator "&&" requires boolean arguments. First argument is '+r+".");if(!r)return!1;var i=this._right.evaluate(e,t);if("boolean"!=typeof i)throw new c('Operator "&&" requires boolean arguments. Second argument is '+i+".");return r&&i},A.prototype._evaluatePlus=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.add(o,a,J.getCartesian2());if(a instanceof t&&o instanceof t)return t.add(o,a,J.getCartesian3());if(a instanceof r&&o instanceof r)return r.add(o,a,J.getCartesian4());if("string"==typeof o||"string"==typeof a)return o+a;if("number"==typeof o&&"number"==typeof a)return o+a;throw new c('Operator "+" requires vector or number arguments of matching types, or at least one string argument. Arguments are '+o+" and "+a+".")},A.prototype._evaluateMinus=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.subtract(o,a,J.getCartesian2());if(a instanceof t&&o instanceof t)return t.subtract(o,a,J.getCartesian3());if(a instanceof r&&o instanceof r)return r.subtract(o,a,J.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o-a;throw new c('Operator "-" requires vector or number arguments of matching types. Arguments are '+o+" and "+a+".")},A.prototype._evaluateTimes=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.multiplyComponents(o,a,J.getCartesian2());if(a instanceof e&&"number"==typeof o)return e.multiplyByScalar(a,o,J.getCartesian2());if(o instanceof e&&"number"==typeof a)return e.multiplyByScalar(o,a,J.getCartesian2());if(a instanceof t&&o instanceof t)return t.multiplyComponents(o,a,J.getCartesian3());if(a instanceof t&&"number"==typeof o)return t.multiplyByScalar(a,o,J.getCartesian3());if(o instanceof t&&"number"==typeof a)return t.multiplyByScalar(o,a,J.getCartesian3());if(a instanceof r&&o instanceof r)return r.multiplyComponents(o,a,J.getCartesian4());if(a instanceof r&&"number"==typeof o)return r.multiplyByScalar(a,o,J.getCartesian4());if(o instanceof r&&"number"==typeof a)return r.multiplyByScalar(o,a,J.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o*a;throw new c('Operator "*" requires vector or number arguments. If both arguments are vectors they must be matching types. Arguments are '+o+" and "+a+".")},A.prototype._evaluateDivide=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.divideComponents(o,a,J.getCartesian2());if(o instanceof e&&"number"==typeof a)return e.divideByScalar(o,a,J.getCartesian2());if(a instanceof t&&o instanceof t)return t.divideComponents(o,a,J.getCartesian3());if(o instanceof t&&"number"==typeof a)return t.divideByScalar(o,a,J.getCartesian3());if(a instanceof r&&o instanceof r)return r.divideComponents(o,a,J.getCartesian4());if(o instanceof r&&"number"==typeof a)return r.divideByScalar(o,a,J.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o/a;throw new c('Operator "/" requires vector or number arguments of matching types, or a number as the second argument. Arguments are '+o+" and "+a+".")},A.prototype._evaluateMod=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.fromElements(o.x%a.x,o.y%a.y,J.getCartesian2());if(a instanceof t&&o instanceof t)return t.fromElements(o.x%a.x,o.y%a.y,o.z%a.z,J.getCartesian3());if(a instanceof r&&o instanceof r)return r.fromElements(o.x%a.x,o.y%a.y,o.z%a.z,o.w%a.w,J.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o%a;throw new c('Operator "%" requires vector or number arguments of matching types. Arguments are '+o+" and "+a+".")},A.prototype._evaluateEqualsStrict=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);return a instanceof e&&o instanceof e||a instanceof t&&o instanceof t||a instanceof r&&o instanceof r?o.equals(a):o===a},A.prototype._evaluateNotEqualsStrict=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);return a instanceof e&&o instanceof e||a instanceof t&&o instanceof t||a instanceof r&&o instanceof r?!o.equals(a):o!==a},A.prototype._evaluateConditional=function(e,t){var r=this._test.evaluate(e,t);if("boolean"!=typeof r)throw new c("Conditional argument of conditional expression must be a boolean. Argument is "+r+".");return r?this._left.evaluate(e,t):this._right.evaluate(e,t)},A.prototype._evaluateNaN=function(e,t){return isNaN(this._left.evaluate(e,t))},A.prototype._evaluateIsFinite=function(e,t){return isFinite(this._left.evaluate(e,t))},A.prototype._evaluateIsExactClass=function(e,t){return t.isExactClass(this._left.evaluate(e,t))},A.prototype._evaluateIsClass=function(e,t){return t.isClass(this._left.evaluate(e,t))},A.prototype._evaluategetExactClassName=function(e,t){return t.getExactClassName()},A.prototype._evaluateBooleanConversion=function(e,t){return Boolean(this._left.evaluate(e,t))},A.prototype._evaluateNumberConversion=function(e,t){return Number(this._left.evaluate(e,t))},A.prototype._evaluateStringConversion=function(e,t){return String(this._left.evaluate(e,t))},A.prototype._evaluateRegExp=function(e,t){var r=this._value.evaluate(e,t),i="";o(this._left)&&(i=this._left.evaluate(e,t));var n;try{n=new RegExp(r,i)}catch(e){throw new c(e)}return n},A.prototype._evaluateRegExpTest=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(!(r instanceof RegExp&&"string"==typeof i))throw new c("RegExp.test requires the first argument to be a RegExp and the second argument to be a string. Arguments are "+r+" and "+i+".");return r.test(i)},A.prototype._evaluateRegExpMatch=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(r instanceof RegExp&&"string"==typeof i)return r.test(i);if(i instanceof RegExp&&"string"==typeof r)return i.test(r);throw new c('Operator "=~" requires one RegExp argument and one string argument. Arguments are '+r+" and "+i+".")},A.prototype._evaluateRegExpNotMatch=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(r instanceof RegExp&&"string"==typeof i)return!r.test(i);if(i instanceof RegExp&&"string"==typeof r)return!i.test(r);throw new c('Operator "!~" requires one RegExp argument and one string argument. Arguments are '+r+" and "+i+".")},A.prototype._evaluateRegExpExec=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(!(r instanceof RegExp&&"string"==typeof i))throw new c("RegExp.exec requires the first argument to be a RegExp and the second argument to be a string. Arguments are "+r+" and "+i+".");var n=r.exec(i);return o(n)?n[1]:null},A.prototype._evaluateToString=function(i,n){var o=this._left.evaluate(i,n);if(o instanceof RegExp||o instanceof e||o instanceof t||o instanceof r)return String(o);throw new c('Unexpected function call "'+this._value+'".')},A.prototype.getShaderExpression=function(e,t,r){var i,a,s,u,d=this._type,p=this._value;switch(o(this._left)&&(a=l(this._left)?K(this._left,e,t,this):this._left.getShaderExpression(e,t,this)),o(this._right)&&(s=this._right.getShaderExpression(e,t,this)),o(this._test)&&(u=this._test.getShaderExpression(e,t,this)),l(this._value)&&(p=K(this._value,e,t,this)),d){case h.VARIABLE:return e+p;case h.UNARY:if("Boolean"===p)return"bool("+a+")";if("Number"===p)return"float("+a+")";if("round"===p)return"floor("+a+" + 0.5)";if(o(ae[p]))return p+"("+a+")";if("isNaN"===p||"isFinite"===p||"String"===p||"isExactClass"===p||"isClass"===p||"getExactClassName"===p)throw new c('Error generating style shader: "'+p+'" is not supported.');return o(ae[p])?p+"("+a+")":p+a;case h.BINARY:return"%"===p?"mod("+a+", "+s+")":"==="===p?"("+a+" == "+s+")":"!=="===p?"("+a+" != "+s+")":"atan2"===p?"atan("+a+", "+s+")":o(se[p])?p+"("+a+", "+s+")":"("+a+" "+p+" "+s+")";case h.TERNARY:if(o(le[p]))return p+"("+a+", "+s+", "+u+")";break;case h.CONDITIONAL:return"("+u+" ? "+a+" : "+s+")";case h.MEMBER:return"r"===s||"x"===s||"0.0"===s?a+"[0]":"g"===s||"y"===s||"1.0"===s?a+"[1]":"b"===s||"z"===s||"2.0"===s?a+"[2]":"a"===s||"w"===s||"3.0"===s?a+"[3]":a+"[int("+s+")]";case h.FUNCTION_CALL:throw new c('Error generating style shader: "'+p+'" is not supported.');case h.ARRAY:if(4===p.length)return"vec4("+p[0]+", "+p[1]+", "+p[2]+", "+p[3]+")";if(3===p.length)return"vec3("+p[0]+", "+p[1]+", "+p[2]+")";if(2===p.length)return"vec2("+p[0]+", "+p[1]+")";throw new c("Error generating style shader: Invalid array length. Array length should be 2, 3, or 4.");case h.REGEX:throw new c("Error generating style shader: Regular expressions are not supported.");case h.VARIABLE_IN_STRING:throw new c("Error generating style shader: Converting a variable to a string is not supported.");case h.LITERAL_NULL:throw new c("Error generating style shader: null is not supported.");case h.LITERAL_BOOLEAN:return p?"true":"false";case h.LITERAL_NUMBER:return X(p);case h.LITERAL_STRING:if(o(r)&&r._type===h.MEMBER&&("r"===p||"g"===p||"b"===p||"a"===p||"x"===p||"y"===p||"z"===p||"w"===p))return p;if(i=n.fromCssColorString(p,oe),o(i))return Q(i);throw new c("Error generating style shader: String literals are not supported.");case h.LITERAL_COLOR:var f=a;if("color"===p){if(!o(f))return"vec4(1.0)";if(f.length>1){var m=f[0],g=f[1];return"1.0"!==g&&(t.translucent=!0),"vec4("+m+", "+g+")"}return"vec4("+f[0]+", 1.0)"}if("rgb"===p)return i=Y(this),o(i)?Z(i):"vec4("+f[0]+" / 255.0, "+f[1]+" / 255.0, "+f[2]+" / 255.0, 1.0)";if("rgba"===p)return"1.0"!==f[3]&&(t.translucent=!0),i=Y(this),o(i)?Z(i):"vec4("+f[0]+" / 255.0, "+f[1]+" / 255.0, "+f[2]+" / 255.0, "+f[3]+")";if("hsl"===p)return i=q(this),o(i)?Z(i):"vec4(czm_HSLToRGB(vec3("+f[0]+", "+f[1]+", "+f[2]+")), 1.0)";if("hsla"===p)return i=q(this),o(i)?(1!==i.alpha&&(t.translucent=!0),Z(i)):("1.0"!==f[3]&&(t.translucent=!0),"vec4(czm_HSLToRGB(vec3("+f[0]+", "+f[1]+", "+f[2]+")), "+f[3]+")");break;case h.LITERAL_VECTOR:for(var _=a.length,v=p+"(",y=0;y<_;++y)v+=a[y],y<_-1&&(v+=", ");return v+=")";case h.LITERAL_REGEX:throw new c("Error generating style shader: Regular expressions are not supported.");case h.LITERAL_UNDEFINED:throw new c("Error generating style shader: undefined is not supported.");case h.BUILTIN_VARIABLE:if("tiles3d_tileset_time"===p)return"u_tilesetTime"}},p}),define("Scene/ConditionsExpression",["../Core/clone","../Core/defined","../Core/defineProperties","./Expression"],function(e,t,r,i){"use strict";function n(t,r){this._conditionsExpression=e(t,!0),this._conditions=t.conditions,this._runtimeConditions=void 0,a(this,r)}function o(e,t){this.condition=e,this.expression=t}function a(e,r){var n=[],a=e._conditions;if(t(a)){for(var s=a.length,l=0;l=0&&u1&&(r=r.length>=n?r:new Array(n-r.toString().length+1).join("0")+r)}}return r}function x(e,t,r,i){return E(e,"{x}",t)}function P(e,t,r,i){return E(e,"{reverseX}",e.tilingScheme.getNumberOfXTilesAtLevel(i)-t-1)}function D(e,t,r,i){return E(e,"{y}",r)}function I(e,t,r,i){return E(e,"{reverseY}",e.tilingScheme.getNumberOfYTilesAtLevel(i)-r-1)}function O(e,t,r,i){var n=e.maximumLevel;return E(e,"{reverseZ}",a(n)&&i0?t._subdomains=t._subdomains.split(""):t._subdomains=["a","b","c"],t._tileWidth=o(e.tileWidth,256),t._tileHeight=o(e.tileHeight,256),t._minimumLevel=o(e.minimumLevel,0),t._maximumLevel=e.maximumLevel,t._tilingScheme=o(e.tilingScheme,new v({ellipsoid:e.ellipsoid})),t._rectangle=o(e.rectangle,t._tilingScheme.rectangle),t._rectangle=_.intersection(t._rectangle,t._tilingScheme.rectangle),t._hasAlphaChannel=o(e.hasAlphaChannel,!0);var r=e.credit;"string"==typeof r&&(r=new n({text:r})),t._credit=r;var i,s={},l={};for(i in ie)ie.hasOwnProperty(i)&&(s[i]=ie[i]);for(i in ne)ne.hasOwnProperty(i)&&(l[i]=ne[i]);var u=e.customTags;if(a(u))for(i in u)if(u.hasOwnProperty(i)){var c="{"+i+"}";s[c]=u[i],l[c]=u[i]}return t._urlParts=A(t._url,s),t._pickFeaturesUrlParts=A(t._pickFeaturesUrl,l),!0})},b.prototype.getTileCredits=function(e,t,r){},b.prototype.requestImage=function(e,t,r,i){var n=S(this,e,t,r);return C.loadImage(this,n,i)},b.prototype.pickFeatures=function(e,t,r,i,n){function o(e,t){return e.callback(t)}function s(){if(l>=u._getFeatureInfoFormats.length)return y([]);var a=u._getFeatureInfoFormats[l],c=w(u,e,t,r,i,n,a.format);return++l,"json"===a.type?h(c).then(a.callback).otherwise(s):"xml"===a.type?m(c).then(a.callback).otherwise(s):"text"===a.type||"html"===a.type?p(c).then(a.callback).otherwise(s):f({url:c,responseType:a.format}).then(o.bind(void 0,a)).otherwise(s)}if(this.enablePickFeatures&&a(this._pickFeaturesUrl)&&0!==this._getFeatureInfoFormats.length){var l=0,u=this;return s()}};var oe=!1,ae=new _,se=!1,le=new _,ue=!1,ce=new e,de=!1,he=new _,pe=new t,fe=new r;return b}),define("Scene/createOpenStreetMapImageryProvider",["../Core/Credit","../Core/defaultValue","../Core/DeveloperError","../Core/Rectangle","../Core/WebMercatorTilingScheme","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o){"use strict";function a(r){r=t(r,{});var a=t(r.url,"https://a.tile.openstreetmap.org/");s.test(a)||(a+="/");var u=t(r.fileExtension,"png"),c=new n({ellipsoid:r.ellipsoid}),d=t(r.minimumLevel,0),h=r.maximumLevel,p=t(r.rectangle,c.rectangle),f=c.positionToTileXY(i.southwest(p),d),m=c.positionToTileXY(i.northeast(p),d),g=(Math.abs(m.x-f.x),Math.abs(m.y-f.y),t(r.credit,l));return"string"==typeof g&&(g=new e({text:g})),new o({url:a+"{z}/{x}/{y}."+u,proxy:r.proxy,credit:g,tilingScheme:c,tileWidth:256,tileHeight:256,minimumLevel:d,maximumLevel:h,rectangle:p})}var s=/\/$/,l=new e({text:"MapQuest, Open Street Map and contributors, CC-BY-SA"});return a}),define("Scene/createTangentSpaceDebugPrimitive",["../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/GeometryInstance","../Core/GeometryPipeline","../Core/Matrix4","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(i){i=t(i,t.EMPTY_OBJECT);var u=[],c=i.geometry;r(c.attributes)&&r(c.primitiveType)||(c=c.constructor.createGeometry(c));var d=c.attributes,h=a.clone(t(i.modelMatrix,a.IDENTITY)),p=t(i.length,1e4);if(r(d.normal)&&u.push(new n({geometry:o.createLineSegmentsForVectors(c,"normal",p),attributes:{color:new e(1,0,0,1)},modelMatrix:h})),r(d.tangent)&&u.push(new n({geometry:o.createLineSegmentsForVectors(c,"tangent",p),attributes:{color:new e(0,1,0,1)},modelMatrix:h})),r(d.bitangent)&&u.push(new n({geometry:o.createLineSegmentsForVectors(c,"bitangent",p),attributes:{color:new e(0,0,1,1)},modelMatrix:h})),u.length>0)return new l({asynchronous:!1,geometryInstances:u,appearance:new s({flat:!0,translucent:!1})})}return u}),define("Scene/createTileMapServiceImageryProvider",["../Core/Cartesian2","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/GeographicTilingScheme","../Core/joinUrls","../Core/loadXML","../Core/Rectangle","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorTilingScheme","../ThirdParty/when","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(n){function f(s){for(var h,p,f,m=/tileformat/i,b=/tileset/i,S=/tilesets/i,w=/boundingbox/i,T=[],A=s.childNodes[0].childNodes,E=0;Ek.rectangle.east&&(F.east=k.rectangle.east),F.southk.rectangle.north&&(F.north=k.rectangle.north);var W=k.positionToTileXY(l.southwest(F),R),j=k.positionToTileXY(l.northeast(F),R);(Math.abs(j.x-W.x)+1)*(Math.abs(j.y-W.y)+1)>4&&(R=0);var q=a(v,"{z}/{x}/{reverseY}."+I);y.resolve({url:q,tilingScheme:k,rectangle:F,tileWidth:O,tileHeight:M,minimumLevel:R,maximumLevel:N,proxy:n.proxy,tileDiscardPolicy:n.tileDiscardPolicy,credit:n.credit})}function m(e){var t=r(n.fileExtension,"png"),o=r(n.tileWidth,256),s=r(n.tileHeight,256),l=r(n.minimumLevel,0),u=n.maximumLevel,c=i(n.tilingScheme)?n.tilingScheme:new d({ellipsoid:n.ellipsoid}),h=r(n.rectangle,c.rectangle),p=a(v,"{z}/{x}/{reverseY}."+t);y.resolve({url:p,tilingScheme:c,rectangle:h,tileWidth:o,tileHeight:s,minimumLevel:l,maximumLevel:u,proxy:n.proxy,tileDiscardPolicy:n.tileDiscardPolicy,credit:n.credit})}function g(){var e=a(v,"tilemapresource.xml"),t=n.proxy;i(t)&&(e=t.getURL(e)),s(e).then(f).otherwise(m)}n=r(n,{});var _,v=n.url,y=h.defer(),C=new p(y.promise);return g(),C}return f}),define("Scene/CreditDisplay",["../Core/Check","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/destroyObject"],function(e,t,r,i,n){"use strict";function o(e,t){if(!i(e.element)){var r=e.text,n=e.link;if(e.hasLink()){var o=document.createElement("a");o.textContent=r,o.href=n,o.target="_blank",t.appendChild(o)}else t.textContent=r;return t.className="cesium-credit-text",e.element=t,t}return e.element}function a(e,t,r){if(!i(e.element)){var n=e.text,o=e.link,a=document.createElement("img");if(a.src=e.imageUrl,a.style["vertical-align"]=r?"middle":"bottom",i(n)&&(a.alt=n,a.title=n),e.hasLink()){var s=document.createElement("a");s.appendChild(a),s.href=o,s.target="_blank",t.appendChild(s)}else t.appendChild(a);t.className="cesium-credit-image",e.element=t}return e.element}function s(e,r){for(var i=e.length,n=0;n=_&&i!==e._lastViewportHeight&&(t.style.marginTop=Math.floor(.5*(i-t.clientHeight))+"px",e._lastViewportHeight=i)}function f(e,t){var r=e+" {";for(var i in t)t.hasOwnProperty(i)&&(r+=i+": "+t[i]+"; ");return r+=" }\n"}function m(){var e=document.head,t=document.createElement("style"),r="";r+=f(".cesium-credit-lightbox-overlay",{display:"none","z-index":"1",position:"absolute",top:"0",left:"0",width:"100%",height:"100%","background-color":"rgba(80, 80, 80, 0.8)"}),r+=f(".cesium-credit-lightbox",{"background-color":"#303336",color:y,position:"relative","min-height":v+"px",margin:"auto"}),r+=f(".cesium-credit-lightbox > ul > li > a, .cesium-credit-lightbox > ul > li > a:visited",{color:y}),r+=f(".cesium-credit-lightbox > ul > li > a:hover",{color:C}),r+=f(".cesium-credit-lightbox.cesium-credit-lightbox-expanded",{border:"1px solid #444","border-radius":"5px","max-width":"370px"}),r+=f(".cesium-credit-lightbox.cesium-credit-lightbox-mobile",{height:"100%",width:"100%"}),r+=f(".cesium-credit-lightbox-title",{padding:"20px 20px 0 20px"}),r+=f(".cesium-credit-lightbox-close",{"font-size":"18pt",cursor:"pointer",position:"absolute",top:"0",right:"6px",color:y}),r+=f(".cesium-credit-lightbox-close:hover",{color:C}),r+=f(".cesium-credit-lightbox > ul",{margin:"0",padding:"12px 20px 12px 40px","font-size":"13px"}),r+=f(".cesium-credit-lightbox > ul > li",{"padding-bottom":"6px"}),r+=f(".cesium-credit-expand-link",{"padding-left":"5px",cursor:"pointer","text-decoration":"underline",color:y}),r+=f(".cesium-credit-expand-link:hover",{color:C}),r+=f(".cesium-credit-text",{color:y}),t.innerHTML=r,e.insertBefore(t,e.firstChild)}function g(e,t,i){var n=this;i=r(i,document.body);var o=document.createElement("div");o.className="cesium-credit-lightbox-overlay",i.appendChild(o);var a=document.createElement("div");a.className="cesium-credit-lightbox",o.appendChild(a),o.onclick=function(e){e.target!==a&&n.hideLightbox()};var s=document.createElement("div");s.className="cesium-credit-lightbox-title",s.textContent="Data provided by:",a.appendChild(s);var l=document.createElement("a");l.onclick=this.hideLightbox.bind(this),l.innerHTML="×",l.className="cesium-credit-lightbox-close",a.appendChild(l);var u=document.createElement("ul");a.appendChild(u);var c=document.createElement("span");c.className="cesium-credit-imageContainer",e.appendChild(c);var d=document.createElement("span");d.className="cesium-credit-textContainer",e.appendChild(d);var h=document.createElement("a");h.className="cesium-credit-expand-link",h.onclick=this.showLightbox.bind(this),h.textContent="Data attribution",e.appendChild(h),m(),this._delimiter=r(t," • "),this._textContainer=d,this._imageContainer=c,this._lastViewportHeight=void 0,this._lastViewportWidth=void 0,this._lightboxCredits=a,this._creditList=u,this._lightbox=o,this._expandLink=h,this._expanded=!1,this._defaultImageCredits=[],this._defaultTextCredits=[],this._displayedCredits={imageCredits:[],textCredits:[],lightboxCredits:[]},this._currentFrameCredits={imageCredits:[],textCredits:[],lightboxCredits:[]},this.viewport=i,this.container=e}var _=576,v=100,y="#ffffff",C="#48b";return g.prototype.addCredit=function(e){e.showOnScreen?e.hasImage()?this._currentFrameCredits.imageCredits[e.id]=e:this._currentFrameCredits.textCredits[e.id]=e:this._currentFrameCredits.lightboxCredits[e.id]=e},g.prototype.addDefaultCredit=function(e){if(e.hasImage()){var t=this._defaultImageCredits;s(t,e)||t.push(e)}else{var r=this._defaultTextCredits;s(r,e)||r.push(e)}},g.prototype.removeDefaultCredit=function(e){var t;e.hasImage()?-1!==(t=this._defaultImageCredits.indexOf(e))&&this._defaultImageCredits.splice(t,1):-1!==(t=this._defaultTextCredits.indexOf(e))&&this._defaultTextCredits.splice(t,1)},g.prototype.showLightbox=function(){this._lightbox.style.display="block",this._expanded=!0},g.prototype.hideLightbox=function(){this._lightbox.style.display="none",this._expanded=!1},g.prototype.beginFrame=function(){this._currentFrameCredits.imageCredits.length=0,this._currentFrameCredits.textCredits.length=0,this._currentFrameCredits.lightboxCredits.length=0},g.prototype.endFrame=function(){u(this,this._defaultImageCredits),l(this,this._defaultTextCredits),u(this,this._currentFrameCredits.imageCredits),l(this,this._currentFrameCredits.textCredits);var e=this._defaultTextCredits.concat(this._currentFrameCredits.textCredits),t=this._defaultImageCredits.concat(this._currentFrameCredits.imageCredits),r=[],i=this._currentFrameCredits.lightboxCredits.length>0;this._expandLink.style.display=i?"inline":"none",this._expanded&&(p(this),c(this,this._currentFrameCredits.lightboxCredits),r=this._currentFrameCredits.lightboxCredits.slice()),h(this),this._displayedCredits.textCredits=e,this._displayedCredits.imageCredits=t,this._displayedCredits.lightboxCredits=r},g.prototype.destroy=function(){return this.container.removeChild(this._textContainer),this.container.removeChild(this._imageContainer),this.container.removeChild(this._expandLink),this.viewport.removeChild(this._lightbox),n(this)},g.prototype.isDestroyed=function(){return!1},g}),define("Scene/DebugAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","./Appearance"],function(e,t,r,i,n){"use strict";function o(r){r=e(r,e.EMPTY_OBJECT);var i=r.attributeName,o=r.perInstanceAttribute;t(o)||(o=!1);var a,s=e(r.glslDatatype,"vec3"),l="v_"+i;if("normal"===i||"tangent"===i||"bitangent"===i)a="vec4 getColor() { return vec4(("+l+" + vec3(1.0)) * 0.5, 1.0); }\n";else switch("st"===i&&(s="vec2"),s){case"float":a="vec4 getColor() { return vec4(vec3("+l+"), 1.0); }\n";break;case"vec2":a="vec4 getColor() { return vec4("+l+", 0.0, 1.0); }\n";break;case"vec3":a="vec4 getColor() { return vec4("+l+", 1.0); }\n";break;case"vec4":a="vec4 getColor() { return "+l+"; }\n"}var u="attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute float batchId;\n"+(o?"":"attribute "+s+" "+i+";\n")+"varying "+s+" "+l+";\nvoid main()\n{\nvec4 p = czm_translateRelativeToEye(position3DHigh, position3DLow);\n"+(o?l+" = czm_batchTable_"+i+"(batchId);\n":l+" = "+i+";\n")+"gl_Position = czm_modelViewProjectionRelativeToEye * p;\n}",c="varying "+s+" "+l+";\n"+a+"\nvoid main()\n{\ngl_FragColor = getColor();\n}";this.material=void 0,this.translucent=e(r.translucent,!1),this._vertexShaderSource=e(r.vertexShaderSource,u),this._fragmentShaderSource=e(r.fragmentShaderSource,c),this._renderState=n.getDefaultRenderState(!1,!1,r.renderState),this._closed=e(r.closed,!1),this._attributeName=i,this._glslDatatype=s}return r(o.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},attributeName:{get:function(){return this._attributeName}},glslDatatype:{get:function(){return this._glslDatatype}}}),o.prototype.getFragmentShaderSource=n.prototype.getFragmentShaderSource,o.prototype.isTranslucent=n.prototype.isTranslucent,o.prototype.getRenderState=n.prototype.getRenderState,o}),define("Scene/DebugCameraPrimitive",["../Core/Cartesian3","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/FrustumGeometry","../Core/FrustumOutlineGeometry","../Core/GeometryInstance","../Core/Matrix3","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/PerspectiveOffCenterFrustum","../Core/Quaternion","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(e){e=i(e,i.EMPTY_OBJECT),this._camera=e.camera,this._color=i(e.color,t.CYAN),this._updateOnChange=i(e.updateOnChange,!0),this.show=i(e.show,!0),this.id=e.id,this._id=void 0,this._outlinePrimitives=[],this._planesPrimitives=[]}var y=new e,C=new c,b=new m,S=new p,w=new f,T=new d,A=new h,E=new t,x=[1,1e5];return v.prototype.update=function(i){if(this.show){var n,o,a=this._planesPrimitives,h=this._outlinePrimitives;if(this._updateOnChange){for(o=a.length,n=0;n= 0.0) {\nt1 = (-b - sqrt(discriminant)) * 0.5;\nt2 = (-b + sqrt(discriminant)) * 0.5;\n}\nif (t1 < 0.0 && t2 < 0.0) {\ndiscard;\n}\nfloat t = min(t1, t2);\nif (t < 0.0) {\nt = 0.0;\n}\nczm_ellipsoid ellipsoid = czm_ellipsoidNew(ellipsoidCenter, u_radii);\nczm_ray ray = czm_ray(t * direction, direction);\nczm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);\nif (czm_isEmpty(intersection))\n{\ndiscard;\n}\nvec4 outsideFaceColor = (intersection.start != 0.0) ? computeEllipsoidColor(ray, intersection.start, 1.0) : vec4(0.0);\nvec4 insideFaceColor = (outsideFaceColor.a < 1.0) ? computeEllipsoidColor(ray, intersection.stop, -1.0) : vec4(0.0);\ngl_FragColor = mix(insideFaceColor, outsideFaceColor, outsideFaceColor.a);\ngl_FragColor.a = 1.0 - (1.0 - insideFaceColor.a) * (1.0 - outsideFaceColor.a);\n#ifdef WRITE_DEPTH\n#ifdef GL_EXT_frag_depth\nt = (intersection.start != 0.0) ? intersection.start : intersection.stop;\nvec3 positionEC = czm_pointAlongRay(ray, t);\nvec4 positionCC = czm_projection * vec4(positionEC, 1.0);\nfloat z = positionCC.z / positionCC.w;\nfloat n = czm_depthRange.near;\nfloat f = czm_depthRange.far;\ngl_FragDepthEXT = (z * (f - n) + f + n) * 0.5;\n#endif\n#endif\n}\n"}),define("Shaders/EllipsoidVS",[],function(){"use strict";return"attribute vec3 position;\nuniform vec3 u_radii;\nvarying vec3 v_positionEC;\nvoid main()\n{\nvec4 p = vec4(u_radii * position, 1.0);\nv_positionEC = (czm_modelView * p).xyz;\ngl_Position = czm_modelViewProjection * p;\ngl_Position.z = clamp(gl_Position.z, czm_depthRange.near, czm_depthRange.far);\n}\n"}),define("Scene/EllipsoidPrimitive",["../Core/BoundingSphere","../Core/BoxGeometry","../Core/Cartesian3","../Core/combine","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Matrix4","../Core/VertexFormat","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../Shaders/EllipsoidFS","../Shaders/EllipsoidVS","./BlendingState","./CullFace","./Material","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S){"use strict";function w(t){t=n(t,n.EMPTY_OBJECT),this.center=r.clone(n(t.center,r.ZERO)),this._center=new r,this.radii=r.clone(t.radii),this._radii=new r,this._oneOverEllipsoidRadiiSquared=new r,this._boundingSphere=new e,this.modelMatrix=l.clone(n(t.modelMatrix,l.IDENTITY)),this._modelMatrix=new l,this._computedModelMatrix=new l,this.show=n(t.show,!0),this.material=n(t.material,b.fromType(b.ColorType)),this._material=void 0,this._translucent=void 0,this.id=t.id,this._id=void 0,this.debugShowBoundingVolume=n(t.debugShowBoundingVolume,!1),this.onlySunLighting=n(t.onlySunLighting,!1),this._onlySunLighting=!1,this._depthTestEnabled=n(t.depthTestEnabled,!0),this._sp=void 0,this._rs=void 0,this._va=void 0,this._pickSP=void 0,this._pickId=void 0,this._colorCommand=new d({owner:n(t._owner,this)}),this._pickCommand=new d({owner:n(t._owner,this)});var i=this;this._uniforms={u_radii:function(){return i.radii},u_oneOverEllipsoidRadiiSquared:function(){return i._oneOverEllipsoidRadiiSquared}},this._pickUniforms={czm_pickColor:function(){return i._pickId.color}}}function T(e){var i=e.cache.ellipsoidPrimitive_vertexArray;if(o(i))return i;var n=t.createGeometry(t.fromDimensions({dimensions:new r(2,2,2),vertexFormat:u.POSITION_ONLY}));return i=g.fromGeometry({context:e,geometry:n,attributeLocations:A,bufferUsage:c.STATIC_DRAW,interleave:!0}),e.cache.ellipsoidPrimitive_vertexArray=i,i}var A={position:0};return w.prototype.update=function(t){if(this.show&&t.mode===S.SCENE3D&&o(this.center)&&o(this.radii)){var n=t.context,a=this.material.isTranslucent(),s=this._translucent!==a;o(this._rs)&&!s||(this._translucent=a,this._rs=p.fromCache({cull:{enabled:!0,face:C.FRONT},depthTest:{enabled:this._depthTestEnabled},depthMask:!a&&n.fragmentDepth,blending:a?y.ALPHA_BLEND:void 0})),o(this._va)||(this._va=T(n));var u=!1,c=this.radii;if(!r.equals(this._radii,c)){r.clone(c,this._radii);var d=this._oneOverEllipsoidRadiiSquared;d.x=1/(c.x*c.x),d.y=1/(c.y*c.y),d.z=1/(c.z*c.z),u=!0}l.equals(this.modelMatrix,this._modelMatrix)&&r.equals(this.center,this._center)||(l.clone(this.modelMatrix,this._modelMatrix),r.clone(this.center,this._center),l.multiplyByTranslation(this.modelMatrix,this.center,this._computedModelMatrix),u=!0),u&&(r.clone(r.ZERO,this._boundingSphere.center),this._boundingSphere.radius=r.maximumComponent(c),e.transform(this._boundingSphere,this._computedModelMatrix,this._boundingSphere));var g=this._material!==this.material;this._material=this.material,this._material.update(n);var b=this.onlySunLighting!==this._onlySunLighting;this._onlySunLighting=this.onlySunLighting;var w,E=this._colorCommand;(g||b||s)&&(w=new m({sources:[this.material.shaderSource,_]}),this.onlySunLighting&&w.defines.push("ONLY_SUN_LIGHTING"),!a&&n.fragmentDepth&&w.defines.push("WRITE_DEPTH"),this._sp=f.replaceCache({context:n,shaderProgram:this._sp,vertexShaderSource:v,fragmentShaderSource:w,attributeLocations:A}),E.vertexArray=this._va,E.renderState=this._rs,E.shaderProgram=this._sp,E.uniformMap=i(this._uniforms,this.material._uniforms),E.executeInClosestFrustum=a);var x=t.commandList,P=t.passes;if(P.render&&(E.boundingVolume=this._boundingSphere,E.debugShowBoundingVolume=this.debugShowBoundingVolume,E.modelMatrix=this._computedModelMatrix,E.pass=a?h.TRANSLUCENT:h.OPAQUE,x.push(E)),P.pick){var D=this._pickCommand;o(this._pickId)&&this._id===this.id||(this._id=this.id,this._pickId=this._pickId&&this._pickId.destroy(),this._pickId=n.createPickId({primitive:this,id:this.id})),(g||b||!o(this._pickSP))&&(w=new m({sources:[this.material.shaderSource,_],pickColorQualifier:"uniform"}),this.onlySunLighting&&w.defines.push("ONLY_SUN_LIGHTING"),!a&&n.fragmentDepth&&w.defines.push("WRITE_DEPTH"),this._pickSP=f.replaceCache({context:n,shaderProgram:this._pickSP,vertexShaderSource:v,fragmentShaderSource:w,attributeLocations:A}),D.vertexArray=this._va,D.renderState=this._rs,D.shaderProgram=this._pickSP,D.uniformMap=i(i(this._uniforms,this._pickUniforms),this.material._uniforms),D.executeInClosestFrustum=a),D.boundingVolume=this._boundingSphere,D.modelMatrix=this._computedModelMatrix,D.pass=a?h.TRANSLUCENT:h.OPAQUE,x.push(D)}}},w.prototype.isDestroyed=function(){return!1},w.prototype.destroy=function(){return this._sp=this._sp&&this._sp.destroy(),this._pickSP=this._pickSP&&this._pickSP.destroy(),this._pickId=this._pickId&&this._pickId.destroy(),a(this)},w}),define("Shaders/Appearances/EllipsoidSurfaceAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec2 v_st;\nvoid main()\n{\nczm_materialInput materialInput;\nvec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nmaterialInput.s = v_st.s;\nmaterialInput.st = v_st;\nmaterialInput.str = vec3(v_st, 0.0);\nmaterialInput.normalEC = normalEC;\nmaterialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\nvec3 positionToEyeEC = -v_positionEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/EllipsoidSurfaceAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec2 st;\nattribute float batchId;\nvarying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionMC = position3DHigh + position3DLow;\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_st = st;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Scene/EllipsoidSurfaceAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/EllipsoidSurfaceAppearanceFS","../Shaders/Appearances/EllipsoidSurfaceAppearanceVS","./Appearance","./Material"],function(e,t,r,i,n,o,a,s){"use strict";function l(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.translucent,!0),l=e(r.aboveGround,!1);this.material=t(r.material)?r.material:s.fromType(s.ColorType),this.translucent=e(r.translucent,!0),this._vertexShaderSource=e(r.vertexShaderSource,o),this._fragmentShaderSource=e(r.fragmentShaderSource,n),this._renderState=a.getDefaultRenderState(i,!l,r.renderState),this._closed=!1,this._flat=e(r.flat,!1),this._faceForward=e(r.faceForward,l),this._aboveGround=l}return r(l.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return l.VERTEX_FORMAT}},flat:{get:function(){return this._flat}},faceForward:{get:function(){return this._faceForward}},aboveGround:{get:function(){return this._aboveGround}}}),l.VERTEX_FORMAT=i.POSITION_AND_ST,l.prototype.getFragmentShaderSource=a.prototype.getFragmentShaderSource,l.prototype.isTranslucent=a.prototype.isTranslucent,l.prototype.getRenderState=a.prototype.getRenderState,l}),define("Scene/Fog",["../Core/Cartesian3","../Core/defined","../Core/Math","./SceneMode"],function(e,t,r,i){"use strict";function n(){this.enabled=!0,this.density=2e-4,this.screenSpaceErrorFactor=2,this.minimumBrightness=.1}function o(e){var t=a,r=t.length;if(et[r-1])return h=r-2;if(e>=t[h]){if(h+1=0&&e>=t[h-1])return--h;var i;for(i=0;i=t[i]&&e8e5||n.mode!==i.SCENE3D)return void(n.fog.enabled=!1);var h=d.height,f=o(h),m=r.clamp((h-a[f])/(a[f+1]-a[f]),0,1),g=r.lerp(s[f],s[f+1],m),_=1e6*this.density;g=g*(_-_/u*c)*1e-6;var v=e.normalize(l.positionWC,p);g*=1-Math.abs(e.dot(l.directionWC,v)),n.fog.density=g,n.fog.sse=this.screenSpaceErrorFactor,n.fog.minimumBrightness=this.minimumBrightness}},n}),define("Scene/FrameRateMonitor",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../Core/getTimestamp","../Core/TimeConstants"],function(e,t,r,i,n,o,a,s){"use strict";function l(r){function i(){c(n)}this._scene=r.scene,this.samplingWindow=e(r.samplingWindow,l.defaultSettings.samplingWindow),this.quietPeriod=e(r.quietPeriod,l.defaultSettings.quietPeriod),this.warmupPeriod=e(r.warmupPeriod,l.defaultSettings.warmupPeriod),this.minimumFrameRateDuringWarmup=e(r.minimumFrameRateDuringWarmup,l.defaultSettings.minimumFrameRateDuringWarmup),this.minimumFrameRateAfterWarmup=e(r.minimumFrameRateAfterWarmup,l.defaultSettings.minimumFrameRateAfterWarmup),this._lowFrameRate=new o,this._nominalFrameRate=new o,this._frameTimes=[],this._needsQuietPeriod=!0,this._quietPeriodEndTime=0,this._warmupPeriodEndTime=0,this._frameRateIsLow=!1,this._lastFramesPerSecond=void 0,this._pauseCount=0;var n=this;this._preRenderRemoveListener=this._scene.preRender.addEventListener(function(e,t){u(n,t)}),this._hiddenPropertyName=void 0!==document.hidden?"hidden":void 0!==document.mozHidden?"mozHidden":void 0!==document.msHidden?"msHidden":void 0!==document.webkitHidden?"webkitHidden":void 0;var a=void 0!==document.hidden?"visibilitychange":void 0!==document.mozHidden?"mozvisibilitychange":void 0!==document.msHidden?"msvisibilitychange":void 0!==document.webkitHidden?"webkitvisibilitychange":void 0;this._visibilityChangeRemoveListener=void 0,t(a)&&(document.addEventListener(a,i,!1),this._visibilityChangeRemoveListener=function(){document.removeEventListener(a,i,!1)})}function u(e,t){if(!(e._pauseCount>0)){var r=a();if(e._needsQuietPeriod)e._needsQuietPeriod=!1,e._frameTimes.length=0,e._quietPeriodEndTime=r+e.quietPeriod/s.SECONDS_PER_MILLISECOND,e._warmupPeriodEndTime=e._quietPeriodEndTime+(e.warmupPeriod+e.samplingWindow)/s.SECONDS_PER_MILLISECOND;else if(r>=e._quietPeriodEndTime){e._frameTimes.push(r);var i=r-e.samplingWindow/s.SECONDS_PER_MILLISECOND;if(e._frameTimes.length>=2&&e._frameTimes[0]<=i){for(;e._frameTimes.length>=2&&e._frameTimes[1]e._warmupPeriodEndTime?e.minimumFrameRateAfterWarmup:e.minimumFrameRateDuringWarmup);n>o?e._frameRateIsLow||(e._frameRateIsLow=!0,e._needsQuietPeriod=!0,e.lowFrameRate.raiseEvent(e.scene,e._lastFramesPerSecond)):e._frameRateIsLow&&(e._frameRateIsLow=!1,e._needsQuietPeriod=!0,e.nominalFrameRate.raiseEvent(e.scene,e._lastFramesPerSecond))}}}}function c(e){document[e._hiddenPropertyName]?e.pause():e.unpause()}return l.defaultSettings={samplingWindow:5,quietPeriod:2,warmupPeriod:5,minimumFrameRateDuringWarmup:4,minimumFrameRateAfterWarmup:8},l.fromScene=function(e){return t(e._frameRateMonitor)&&!e._frameRateMonitor.isDestroyed()||(e._frameRateMonitor=new l({scene:e})),e._frameRateMonitor},r(l.prototype,{scene:{get:function(){return this._scene}},lowFrameRate:{get:function(){return this._lowFrameRate}},nominalFrameRate:{get:function(){return this._nominalFrameRate}},lastFramesPerSecond:{get:function(){return this._lastFramesPerSecond}}}),l.prototype.pause=function(){1===++this._pauseCount&&(this._frameTimes.length=0,this._lastFramesPerSecond=void 0)},l.prototype.unpause=function(){--this._pauseCount<=0&&(this._pauseCount=0,this._needsQuietPeriod=!0)},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._preRenderRemoveListener(),t(this._visibilityChangeRemoveListener)&&this._visibilityChangeRemoveListener(),i(this)},l}),define("Scene/FrameState",["./SceneMode"],function(e){"use strict";function t(t,r,i){this.context=t,this.commandList=[],this.shadowMaps=[],this.brdfLutGenerator=void 0,this.environmentMap=void 0,this.mode=e.SCENE3D,this.morphTime=e.getMorphTime(e.SCENE3D),this.frameNumber=0,this.time=void 0,this.jobScheduler=i,this.mapProjection=void 0,this.camera=void 0,this.cullingVolume=void 0,this.occluder=void 0,this.maximumScreenSpaceError=void 0,this.passes={render:!1,pick:!1,depth:!1},this.creditDisplay=r,this.afterRender=[],this.scene3DOnly=!1,this.fog={enabled:!1,density:void 0,sse:void 0,minimumBrightness:void 0},this.terrainExaggeration=1,this.shadowHints={shadowsEnabled:!0,shadowMaps:[],lightShadowMaps:[],nearPlane:1,farPlane:5e3,closestObjectSize:1e3,lastDirtyTime:0,outOfView:!0},this.imagerySplitPosition=0,this.frustumSplits=[],this.backgroundColor=void 0,this.minimumDisableDepthTestDistance=void 0,this.invertClassification=!1,this.invertClassificationColor=void 0}return t}),define("Scene/FrustumCommands",["../Core/defaultValue","../Renderer/Pass"],function(e,t){"use strict";function r(r,i){this.near=e(r,0),this.far=e(i,0);for(var n=t.NUMBER_OF_PASSES,o=new Array(n),a=new Array(n),s=0;s= edgeVert;\nFxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;\nif(!horzSpan) lumaN = lumaW;\nif(!horzSpan) lumaS = lumaE;\nif(horzSpan) lengthSign = fxaaQualityRcpFrame.y;\nFxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;\nFxaaFloat gradientN = lumaN - lumaM;\nFxaaFloat gradientS = lumaS - lumaM;\nFxaaFloat lumaNN = lumaN + lumaM;\nFxaaFloat lumaSS = lumaS + lumaM;\nFxaaBool pairN = abs(gradientN) >= abs(gradientS);\nFxaaFloat gradient = max(abs(gradientN), abs(gradientS));\nif(pairN) lengthSign = -lengthSign;\nFxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);\nFxaaFloat2 posB;\nposB.x = posM.x;\nposB.y = posM.y;\nFxaaFloat2 offNP;\noffNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;\noffNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;\nif(!horzSpan) posB.x += lengthSign * 0.5;\nif( horzSpan) posB.y += lengthSign * 0.5;\nFxaaFloat2 posN;\nposN.x = posB.x - offNP.x * FXAA_QUALITY_P0;\nposN.y = posB.y - offNP.y * FXAA_QUALITY_P0;\nFxaaFloat2 posP;\nposP.x = posB.x + offNP.x * FXAA_QUALITY_P0;\nposP.y = posB.y + offNP.y * FXAA_QUALITY_P0;\nFxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;\nFxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));\nFxaaFloat subpixE = subpixC * subpixC;\nFxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));\nif(!pairN) lumaNN = lumaSS;\nFxaaFloat gradientScaled = gradient * 1.0/4.0;\nFxaaFloat lumaMM = lumaM - lumaNN * 0.5;\nFxaaFloat subpixF = subpixD * subpixE;\nFxaaBool lumaMLTZero = lumaMM < 0.0;\nlumaEndN -= lumaNN * 0.5;\nlumaEndP -= lumaNN * 0.5;\nFxaaBool doneN = abs(lumaEndN) >= gradientScaled;\nFxaaBool doneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;\nFxaaBool doneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;\n#if (FXAA_QUALITY_PS > 3)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;\n#if (FXAA_QUALITY_PS > 4)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;\n#if (FXAA_QUALITY_PS > 5)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;\n#if (FXAA_QUALITY_PS > 6)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;\n#if (FXAA_QUALITY_PS > 7)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;\n#if (FXAA_QUALITY_PS > 8)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;\n#if (FXAA_QUALITY_PS > 9)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;\n#if (FXAA_QUALITY_PS > 10)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;\n#if (FXAA_QUALITY_PS > 11)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;\n#if (FXAA_QUALITY_PS > 12)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\nFxaaFloat dstN = posM.x - posN.x;\nFxaaFloat dstP = posP.x - posM.x;\nif(!horzSpan) dstN = posM.y - posN.y;\nif(!horzSpan) dstP = posP.y - posM.y;\nFxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;\nFxaaFloat spanLength = (dstP + dstN);\nFxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;\nFxaaFloat spanLengthRcp = 1.0/spanLength;\nFxaaBool directionN = dstN < dstP;\nFxaaFloat dst = min(dstN, dstP);\nFxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;\nFxaaFloat subpixG = subpixF * subpixF;\nFxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;\nFxaaFloat subpixH = subpixG * fxaaQualitySubpix;\nFxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;\nFxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);\nif(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;\nif( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;\nreturn FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);\n}\n"}),define("Scene/FXAA",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Color","../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/Renderbuffer","../Renderer/RenderbufferFormat","../Renderer/RenderState","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Shaders/PostProcessFilters/FXAA","../ThirdParty/Shaders/FXAA3_11"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(){this._texture=void 0,this._depthStencilTexture=void 0,this._depthStencilRenderbuffer=void 0,this._fbo=void 0,this._command=void 0,this._viewport=new e,this._rs=void 0,this._useScissorTest=!1,this._scissorRectangle=void 0;var t=new a({color:new r(0,0,0,0),depth:1,owner:this});this._clearCommand=t,this._qualityPreset=39}function C(e){e._fbo=e._fbo&&e._fbo.destroy(),e._texture=e._texture&&e._texture.destroy(),e._depthStencilTexture=e._depthStencilTexture&&e._depthStencilTexture.destroy(),e._depthStencilRenderbuffer=e._depthStencilRenderbuffer&&e._depthStencilRenderbuffer.destroy(),e._fbo=void 0,e._texture=void 0,e._depthStencilTexture=void 0,e._depthStencilRenderbuffer=void 0,i(e._command)&&(e._command.shaderProgram=e._command.shaderProgram&&e._command.shaderProgram.destroy(),e._command=void 0)}return y.prototype.update=function(r,n){var a=r.drawingBufferWidth,y=r.drawingBufferHeight,C=this._texture,b=!i(C)||C.width!==a||C.height!==y;if(b&&(this._texture=this._texture&&this._texture.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),this._depthStencilRenderbuffer=this._depthStencilRenderbuffer&&this._depthStencilRenderbuffer.destroy(),this._texture=new p({context:r,width:a,height:y,pixelFormat:o.RGBA,pixelDatatype:l.UNSIGNED_BYTE,sampler:new h({wrapS:g.CLAMP_TO_EDGE,wrapT:g.CLAMP_TO_EDGE,minificationFilter:m.LINEAR,magnificationFilter:f.LINEAR})}),r.depthTexture?this._depthStencilTexture=new p({context:r,width:a,height:y,pixelFormat:o.DEPTH_STENCIL,pixelDatatype:l.UNSIGNED_INT_24_8}):this._depthStencilRenderbuffer=new u({context:r,width:a,height:y,format:c.DEPTH_STENCIL})),i(this._fbo)&&!b||(this._fbo=this._fbo&&this._fbo.destroy(),this._fbo=new s({context:r,colorTextures:[this._texture],depthStencilTexture:this._depthStencilTexture,depthStencilRenderbuffer:this._depthStencilRenderbuffer,destroyAttachments:!1})),!i(this._command)){var S="#define FXAA_QUALITY_PRESET "+this._qualityPreset+"\n"+v+"\n"+_;this._command=r.createViewportQuadCommand(S,{owner:this})}this._viewport.width=a,this._viewport.height=y;var w=!e.equals(this._viewport,n.viewport),T=w!==this._useScissorTest;if(this._useScissorTest=w,e.equals(this._scissorRectangle,n.viewport)||(this._scissorRectangle=e.clone(n.viewport,this._scissorRectangle),T=!0),i(this._rs)&&e.equals(this._rs.viewport,this._viewport)&&!T||(this._rs=d.fromCache({viewport:this._viewport,scissorTest:{enabled:this._useScissorTest,rectangle:this._scissorRectangle}})),this._command.renderState=this._rs,b){var A=this,E=new t(1/this._texture.width,1/this._texture.height);this._command.uniformMap={u_texture:function(){return A._texture},u_fxaaQualityRcpFrame:function(){return E}}}},y.prototype.execute=function(e,t){this._command.execute(e,t)},y.prototype.clear=function(e,t,i){var n=t.framebuffer;t.framebuffer=this._fbo,r.clone(i,this._clearCommand.color),this._clearCommand.execute(e,t),t.framebuffer=n},y.prototype.getColorFramebuffer=function(){return this._fbo},y.prototype.isDestroyed=function(){return!1},y.prototype.destroy=function(){return C(this),n(this)},y}),define("Scene/GetFeatureInfoFormat",["../Core/Cartographic","../Core/defined","../Core/DeveloperError","../Core/RuntimeError","./ImageryLayerFeatureInfo"],function(e,t,r,i,n){"use strict";function o(e,r,i){this.type=e,t(r)||("json"===e?r="application/json":"xml"===e?r="text/xml":"html"===e?r="text/html":"text"===e&&(r="text/plain")),this.format=r,t(i)||("json"===e?i=a:"xml"===e?i=s:"html"===e?i=m:"text"===e&&(i=m)),this.callback=i}function a(r){for(var i=[],o=r.features,a=0;a0)for(var o=0;o1&&(t=r[1]);var i=new n;return i.name=t,i.description=e,i.data=e,[i]}}var g="http://www.mapinfo.com/mxp",_="http://www.esri.com/wms",v="http://www.opengis.net/wfs",y="http://www.opengis.net/gml",C=/\s*<\/body>/im,b=//im,S=/([\s\S]*)<\/title>/im;return o}),define("Shaders/GlobeFS",[],function(){"use strict" -;return"uniform vec4 u_initialColor;\n#if TEXTURE_UNITS > 0\nuniform sampler2D u_dayTextures[TEXTURE_UNITS];\nuniform vec4 u_dayTextureTranslationAndScale[TEXTURE_UNITS];\nuniform bool u_dayTextureUseWebMercatorT[TEXTURE_UNITS];\n#ifdef APPLY_ALPHA\nuniform float u_dayTextureAlpha[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_SPLIT\nuniform float u_dayTextureSplit[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_BRIGHTNESS\nuniform float u_dayTextureBrightness[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_CONTRAST\nuniform float u_dayTextureContrast[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_HUE\nuniform float u_dayTextureHue[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_SATURATION\nuniform float u_dayTextureSaturation[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_GAMMA\nuniform float u_dayTextureOneOverGamma[TEXTURE_UNITS];\n#endif\nuniform vec4 u_dayTextureTexCoordsRectangle[TEXTURE_UNITS];\n#endif\n#ifdef SHOW_REFLECTIVE_OCEAN\nuniform sampler2D u_waterMask;\nuniform vec4 u_waterMaskTranslationAndScale;\nuniform float u_zoomedOutOceanSpecularIntensity;\n#endif\n#ifdef SHOW_OCEAN_WAVES\nuniform sampler2D u_oceanNormalMap;\n#endif\n#ifdef ENABLE_DAYNIGHT_SHADING\nuniform vec2 u_lightingFadeDistance;\n#endif\n#ifdef ENABLE_CLIPPING_PLANES\nuniform int u_clippingPlanesLength;\nuniform vec4 u_clippingPlanes[czm_maxClippingPlanes];\nuniform vec4 u_clippingPlanesEdgeStyle;\n#endif\n#if defined(FOG) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))\nuniform float u_minimumBrightness;\n#endif\nvarying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec3 v_textureCoordinates;\nvarying vec3 v_normalMC;\nvarying vec3 v_normalEC;\n#ifdef APPLY_MATERIAL\nvarying float v_height;\nvarying float v_slope;\n#endif\n#ifdef FOG\nvarying float v_distance;\nvarying vec3 v_rayleighColor;\nvarying vec3 v_mieColor;\n#endif\nvec4 sampleAndBlend(\nvec4 previousColor,\nsampler2D textureToSample,\nvec2 tileTextureCoordinates,\nvec4 textureCoordinateRectangle,\nvec4 textureCoordinateTranslationAndScale,\nfloat textureAlpha,\nfloat textureBrightness,\nfloat textureContrast,\nfloat textureHue,\nfloat textureSaturation,\nfloat textureOneOverGamma,\nfloat split)\n{\nvec2 alphaMultiplier = step(textureCoordinateRectangle.st, tileTextureCoordinates);\ntextureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;\nalphaMultiplier = step(vec2(0.0), textureCoordinateRectangle.pq - tileTextureCoordinates);\ntextureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;\nvec2 translation = textureCoordinateTranslationAndScale.xy;\nvec2 scale = textureCoordinateTranslationAndScale.zw;\nvec2 textureCoordinates = tileTextureCoordinates * scale + translation;\nvec4 value = texture2D(textureToSample, textureCoordinates);\nvec3 color = value.rgb;\nfloat alpha = value.a;\n#ifdef APPLY_SPLIT\nfloat splitPosition = czm_imagerySplitPosition;\nif (split < 0.0 && gl_FragCoord.x > splitPosition) {\nalpha = 0.0;\n}\nelse if (split > 0.0 && gl_FragCoord.x < splitPosition) {\nalpha = 0.0;\n}\n#endif\n#ifdef APPLY_BRIGHTNESS\ncolor = mix(vec3(0.0), color, textureBrightness);\n#endif\n#ifdef APPLY_CONTRAST\ncolor = mix(vec3(0.5), color, textureContrast);\n#endif\n#ifdef APPLY_HUE\ncolor = czm_hue(color, textureHue);\n#endif\n#ifdef APPLY_SATURATION\ncolor = czm_saturation(color, textureSaturation);\n#endif\n#ifdef APPLY_GAMMA\ncolor = pow(color, vec3(textureOneOverGamma));\n#endif\nfloat sourceAlpha = alpha * textureAlpha;\nfloat outAlpha = mix(previousColor.a, 1.0, sourceAlpha);\nvec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha;\nreturn vec4(outColor, outAlpha);\n}\nvec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates);\nvec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue);\nvoid main()\n{\n#ifdef ENABLE_CLIPPING_PLANES\n#ifdef UNION_CLIPPING_REGIONS\nfloat clipDistance = czm_discardIfClippedWithUnion(u_clippingPlanes, u_clippingPlanesLength);\n#else\nfloat clipDistance = czm_discardIfClippedWithIntersect(u_clippingPlanes, u_clippingPlanesLength);\n#endif\n#endif\nvec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0));\n#ifdef SHOW_TILE_BOUNDARIES\nif (v_textureCoordinates.x < (1.0/256.0) || v_textureCoordinates.x > (255.0/256.0) ||\nv_textureCoordinates.y < (1.0/256.0) || v_textureCoordinates.y > (255.0/256.0))\n{\ncolor = vec4(1.0, 0.0, 0.0, 1.0);\n}\n#endif\n#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING)\nvec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0));\nvec3 normalEC = czm_normal3D * normalMC;\n#endif\n#ifdef SHOW_REFLECTIVE_OCEAN\nvec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy;\nvec2 waterMaskScale = u_waterMaskTranslationAndScale.zw;\nvec2 waterMaskTextureCoordinates = v_textureCoordinates.xy * waterMaskScale + waterMaskTranslation;\nfloat mask = texture2D(u_waterMask, waterMaskTextureCoordinates).r;\nif (mask > 0.0)\n{\nmat3 enuToEye = czm_eastNorthUpToEyeCoordinates(v_positionMC, normalEC);\nvec2 ellipsoidTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC);\nvec2 ellipsoidFlippedTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC.zyx);\nvec2 textureCoordinates = mix(ellipsoidTextureCoordinates, ellipsoidFlippedTextureCoordinates, czm_morphTime * smoothstep(0.9, 0.95, normalMC.z));\ncolor = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, color, mask);\n}\n#endif\n#ifdef APPLY_MATERIAL\nczm_materialInput materialInput;\nmaterialInput.st = v_textureCoordinates.st;\nmaterialInput.normalEC = normalize(v_normalEC);\nmaterialInput.slope = v_slope;\nmaterialInput.height = v_height;\nczm_material material = czm_getMaterial(materialInput);\ncolor.xyz = mix(color.xyz, material.diffuse, material.alpha);\n#endif\n#ifdef ENABLE_VERTEX_LIGHTING\nfloat diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalize(v_normalEC)) * 0.9 + 0.3, 0.0, 1.0);\nvec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a);\n#elif defined(ENABLE_DAYNIGHT_SHADING)\nfloat diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0);\nfloat cameraDist = length(czm_view[3]);\nfloat fadeOutDist = u_lightingFadeDistance.x;\nfloat fadeInDist = u_lightingFadeDistance.y;\nfloat t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);\ndiffuseIntensity = mix(1.0, diffuseIntensity, t);\nvec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a);\n#else\nvec4 finalColor = color;\n#endif\n#ifdef ENABLE_CLIPPING_PLANES\nvec4 clippingPlanesEdgeColor = vec4(1.0);\nclippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb;\nfloat clippingPlanesEdgeWidth = u_clippingPlanesEdgeStyle.a;\nif (clipDistance < clippingPlanesEdgeWidth)\n{\nfinalColor = clippingPlanesEdgeColor;\n}\n#endif\n#ifdef FOG\nconst float fExposure = 2.0;\nvec3 fogColor = v_mieColor + finalColor.rgb * v_rayleighColor;\nfogColor = vec3(1.0) - exp(-fExposure * fogColor);\n#if defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING)\nfloat darken = clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), u_minimumBrightness, 1.0);\nfogColor *= darken;\n#endif\ngl_FragColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor), finalColor.a);\n#else\ngl_FragColor = finalColor;\n#endif\n}\n#ifdef SHOW_REFLECTIVE_OCEAN\nfloat waveFade(float edge0, float edge1, float x)\n{\nfloat y = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\nreturn pow(1.0 - y, 5.0);\n}\nfloat linearFade(float edge0, float edge1, float x)\n{\nreturn clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n}\nconst float oceanFrequencyLowAltitude = 825000.0;\nconst float oceanAnimationSpeedLowAltitude = 0.004;\nconst float oceanOneOverAmplitudeLowAltitude = 1.0 / 2.0;\nconst float oceanSpecularIntensity = 0.5;\nconst float oceanFrequencyHighAltitude = 125000.0;\nconst float oceanAnimationSpeedHighAltitude = 0.008;\nconst float oceanOneOverAmplitudeHighAltitude = 1.0 / 2.0;\nvec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float maskValue)\n{\nvec3 positionToEyeEC = -positionEyeCoordinates;\nfloat positionToEyeECLength = length(positionToEyeEC);\nvec3 normalizedpositionToEyeEC = normalize(normalize(positionToEyeEC));\nfloat waveIntensity = waveFade(70000.0, 1000000.0, positionToEyeECLength);\n#ifdef SHOW_OCEAN_WAVES\nfloat time = czm_frameNumber * oceanAnimationSpeedHighAltitude;\nvec4 noise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyHighAltitude, time, 0.0);\nvec3 normalTangentSpaceHighAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeHighAltitude);\ntime = czm_frameNumber * oceanAnimationSpeedLowAltitude;\nnoise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyLowAltitude, time, 0.0);\nvec3 normalTangentSpaceLowAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeLowAltitude);\nfloat highAltitudeFade = linearFade(0.0, 60000.0, positionToEyeECLength);\nfloat lowAltitudeFade = 1.0 - linearFade(20000.0, 60000.0, positionToEyeECLength);\nvec3 normalTangentSpace =\n(highAltitudeFade * normalTangentSpaceHighAltitude) +\n(lowAltitudeFade * normalTangentSpaceLowAltitude);\nnormalTangentSpace = normalize(normalTangentSpace);\nnormalTangentSpace.xy *= waveIntensity;\nnormalTangentSpace = normalize(normalTangentSpace);\n#else\nvec3 normalTangentSpace = vec3(0.0, 0.0, 1.0);\n#endif\nvec3 normalEC = enuToEye * normalTangentSpace;\nconst vec3 waveHighlightColor = vec3(0.3, 0.45, 0.6);\nfloat diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * maskValue;\nvec3 diffuseHighlight = waveHighlightColor * diffuseIntensity;\n#ifdef SHOW_OCEAN_WAVES\nfloat tsPerturbationRatio = normalTangentSpace.z;\nvec3 nonDiffuseHighlight = mix(waveHighlightColor * 5.0 * (1.0 - tsPerturbationRatio), vec3(0.0), diffuseIntensity);\n#else\nvec3 nonDiffuseHighlight = vec3(0.0);\n#endif\nfloat specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0) + 0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0);\nfloat surfaceReflectance = mix(0.0, mix(u_zoomedOutOceanSpecularIntensity, oceanSpecularIntensity, waveIntensity), maskValue);\nfloat specular = specularIntensity * surfaceReflectance;\nreturn vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a);\n}\n#endif // #ifdef SHOW_REFLECTIVE_OCEAN\n"}),define("Shaders/GlobeVS",[],function(){"use strict";return"#ifdef QUANTIZATION_BITS12\nattribute vec4 compressed0;\nattribute float compressed1;\n#else\nattribute vec4 position3DAndHeight;\nattribute vec4 textureCoordAndEncodedNormals;\n#endif\nuniform vec3 u_center3D;\nuniform mat4 u_modifiedModelView;\nuniform mat4 u_modifiedModelViewProjection;\nuniform vec4 u_tileRectangle;\nuniform vec2 u_southAndNorthLatitude;\nuniform vec2 u_southMercatorYAndOneOverHeight;\nvarying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec3 v_textureCoordinates;\nvarying vec3 v_normalMC;\nvarying vec3 v_normalEC;\n#ifdef APPLY_MATERIAL\nvarying float v_slope;\nvarying float v_height;\n#endif\n#ifdef FOG\nvarying float v_distance;\nvarying vec3 v_mieColor;\nvarying vec3 v_rayleighColor;\n#endif\nvec4 getPosition(vec3 position, float height, vec2 textureCoordinates);\nfloat get2DYPositionFraction(vec2 textureCoordinates);\nvec4 getPosition3DMode(vec3 position, float height, vec2 textureCoordinates)\n{\nreturn u_modifiedModelViewProjection * vec4(position, 1.0);\n}\nfloat get2DMercatorYPositionFraction(vec2 textureCoordinates)\n{\nconst float maxTileWidth = 0.003068;\nfloat positionFraction = textureCoordinates.y;\nfloat southLatitude = u_southAndNorthLatitude.x;\nfloat northLatitude = u_southAndNorthLatitude.y;\nif (northLatitude - southLatitude > maxTileWidth)\n{\nfloat southMercatorY = u_southMercatorYAndOneOverHeight.x;\nfloat oneOverMercatorHeight = u_southMercatorYAndOneOverHeight.y;\nfloat currentLatitude = mix(southLatitude, northLatitude, textureCoordinates.y);\ncurrentLatitude = clamp(currentLatitude, -czm_webMercatorMaxLatitude, czm_webMercatorMaxLatitude);\npositionFraction = czm_latitudeToWebMercatorFraction(currentLatitude, southMercatorY, oneOverMercatorHeight);\n}\nreturn positionFraction;\n}\nfloat get2DGeographicYPositionFraction(vec2 textureCoordinates)\n{\nreturn textureCoordinates.y;\n}\nvec4 getPositionPlanarEarth(vec3 position, float height, vec2 textureCoordinates)\n{\nfloat yPositionFraction = get2DYPositionFraction(textureCoordinates);\nvec4 rtcPosition2D = vec4(height, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordinates.x, yPositionFraction)), 1.0);\nreturn u_modifiedModelViewProjection * rtcPosition2D;\n}\nvec4 getPosition2DMode(vec3 position, float height, vec2 textureCoordinates)\n{\nreturn getPositionPlanarEarth(position, 0.0, textureCoordinates);\n}\nvec4 getPositionColumbusViewMode(vec3 position, float height, vec2 textureCoordinates)\n{\nreturn getPositionPlanarEarth(position, height, textureCoordinates);\n}\nvec4 getPositionMorphingMode(vec3 position, float height, vec2 textureCoordinates)\n{\nvec3 position3DWC = position + u_center3D;\nfloat yPositionFraction = get2DYPositionFraction(textureCoordinates);\nvec4 position2DWC = vec4(height, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordinates.x, yPositionFraction)), 1.0);\nvec4 morphPosition = czm_columbusViewMorph(position2DWC, vec4(position3DWC, 1.0), czm_morphTime);\nreturn czm_modelViewProjection * morphPosition;\n}\n#ifdef QUANTIZATION_BITS12\nuniform vec2 u_minMaxHeight;\nuniform mat4 u_scaleAndBias;\n#endif\nvoid main()\n{\n#ifdef QUANTIZATION_BITS12\nvec2 xy = czm_decompressTextureCoordinates(compressed0.x);\nvec2 zh = czm_decompressTextureCoordinates(compressed0.y);\nvec3 position = vec3(xy, zh.x);\nfloat height = zh.y;\nvec2 textureCoordinates = czm_decompressTextureCoordinates(compressed0.z);\nheight = height * (u_minMaxHeight.y - u_minMaxHeight.x) + u_minMaxHeight.x;\nposition = (u_scaleAndBias * vec4(position, 1.0)).xyz;\n#if (defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL)) && defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = czm_decompressTextureCoordinates(compressed0.w).x;\nfloat encodedNormal = compressed1;\n#elif defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = czm_decompressTextureCoordinates(compressed0.w).x;\nfloat encodedNormal = 0.0;\n#elif defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL)\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = compressed0.w;\n#else\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = 0.0;\n#endif\n#else\nvec3 position = position3DAndHeight.xyz;\nfloat height = position3DAndHeight.w;\nvec2 textureCoordinates = textureCoordAndEncodedNormals.xy;\n#if (defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)) && defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = textureCoordAndEncodedNormals.z;\nfloat encodedNormal = textureCoordAndEncodedNormals.w;\n#elif defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = textureCoordAndEncodedNormals.z;\n#elif defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = textureCoordAndEncodedNormals.z;\nfloat encodedNormal = 0.0;\n#else\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = 0.0;\n#endif\n#endif\nvec3 position3DWC = position + u_center3D;\ngl_Position = getPosition(position, height, textureCoordinates);\nv_textureCoordinates = vec3(textureCoordinates, webMercatorT);\n#if defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)\nv_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz;\nv_positionMC = position3DWC;\nvec3 normalMC = czm_octDecode(encodedNormal);\nv_normalMC = normalMC;\nv_normalEC = czm_normal3D * v_normalMC;\n#elif defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(GENERATE_POSITION)\nv_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz;\nv_positionMC = position3DWC;\n#endif\n#ifdef FOG\nAtmosphereColor atmosColor = computeGroundAtmosphereFromSpace(position3DWC);\nv_mieColor = atmosColor.mie;\nv_rayleighColor = atmosColor.rayleigh;\nv_distance = length((czm_modelView3D * vec4(position3DWC, 1.0)).xyz);\n#endif\n#ifdef APPLY_MATERIAL\nvec3 finalNormal = normalMC;\nvec3 ellipsoidNormal = normalize(position3DWC.xyz);\nv_slope = abs(dot(ellipsoidNormal, finalNormal));\nv_height = height;\n#endif\n}\n"}),define("Shaders/GroundAtmosphere",[],function(){"use strict";return"const float fInnerRadius = 6378137.0;\nconst float fOuterRadius = 6378137.0 * 1.025;\nconst float fOuterRadius2 = fOuterRadius * fOuterRadius;\nconst float Kr = 0.0025;\nconst float Km = 0.0015;\nconst float ESun = 15.0;\nconst float fKrESun = Kr * ESun;\nconst float fKmESun = Km * ESun;\nconst float fKr4PI = Kr * 4.0 * czm_pi;\nconst float fKm4PI = Km * 4.0 * czm_pi;\nconst float fScale = 1.0 / (fOuterRadius - fInnerRadius);\nconst float fScaleDepth = 0.25;\nconst float fScaleOverScaleDepth = fScale / fScaleDepth;\nstruct AtmosphereColor\n{\nvec3 mie;\nvec3 rayleigh;\n};\nconst int nSamples = 2;\nconst float fSamples = 2.0;\nfloat scale(float fCos)\n{\nfloat x = 1.0 - fCos;\nreturn fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\n}\nAtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos)\n{\nvec3 v3InvWavelength = vec3(1.0 / pow(0.650, 4.0), 1.0 / pow(0.570, 4.0), 1.0 / pow(0.475, 4.0));\nvec3 v3Ray = v3Pos - czm_viewerPositionWC;\nfloat fFar = length(v3Ray);\nv3Ray /= fFar;\nfloat fCameraHeight = length(czm_viewerPositionWC);\nfloat fCameraHeight2 = fCameraHeight * fCameraHeight;\nfloat B = 2.0 * length(czm_viewerPositionWC) * dot(normalize(czm_viewerPositionWC), v3Ray);\nfloat C = fCameraHeight2 - fOuterRadius2;\nfloat fDet = max(0.0, B*B - 4.0 * C);\nfloat fNear = 0.5 * (-B - sqrt(fDet));\nvec3 v3Start = czm_viewerPositionWC + v3Ray * fNear;\nfFar -= fNear;\nfloat fDepth = exp((fInnerRadius - fOuterRadius) / fScaleDepth);\nfloat fLightAngle = 1.0;\nfloat fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);\nfloat fCameraScale = scale(fCameraAngle);\nfloat fLightScale = scale(fLightAngle);\nfloat fCameraOffset = fDepth*fCameraScale;\nfloat fTemp = (fLightScale + fCameraScale);\nfloat fSampleLength = fFar / fSamples;\nfloat fScaledLength = fSampleLength * fScale;\nvec3 v3SampleRay = v3Ray * fSampleLength;\nvec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;\nvec3 v3FrontColor = vec3(0.0);\nvec3 v3Attenuate = vec3(0.0);\nfor(int i=0; i<nSamples; i++)\n{\nfloat fHeight = length(v3SamplePoint);\nfloat fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));\nfloat fScatter = fDepth*fTemp - fCameraOffset;\nv3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));\nv3FrontColor += v3Attenuate * (fDepth * fScaledLength);\nv3SamplePoint += v3SampleRay;\n}\nAtmosphereColor color;\ncolor.mie = v3FrontColor * (v3InvWavelength * fKrESun + fKmESun);\ncolor.rayleigh = v3Attenuate;\nreturn color;\n}\n"}),define("Scene/GlobeSurfaceShaderSet",["../Core/defined","../Core/destroyObject","../Core/TerrainQuantization","../Renderer/ShaderProgram","../Scene/SceneMode"],function(e,t,r,i,n){"use strict";function o(e,t,r,i){this.numberOfDayTextures=e,this.flags=t,this.material=r,this.shaderProgram=i}function a(){this.baseVertexShaderSource=void 0,this.baseFragmentShaderSource=void 0,this._shadersByTexturesFlags=[],this._pickShaderPrograms=[],this.material=void 0}function s(e){var t;switch(e){case n.SCENE3D:t="vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPosition3DMode(position, height, textureCoordinates); }";break;case n.SCENE2D:case n.COLUMBUS_VIEW:t="vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionColumbusViewMode(position, height, textureCoordinates); }";break;case n.MORPHING:t="vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionMorphingMode(position, height, textureCoordinates); }"}return t}function l(e){return e?"float get2DYPositionFraction(vec2 textureCoordinates) { return get2DMercatorYPositionFraction(textureCoordinates); }":"float get2DYPositionFraction(vec2 textureCoordinates) { return get2DGeographicYPositionFraction(textureCoordinates); }"}return a.prototype.getShaderProgram=function(t,n,a,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w){var T=0,A="",E=n.pickTerrain.mesh.encoding;E.quantization===r.BITS12&&(T=1,A="QUANTIZATION_BITS12");var x=t.mode,P=x|u<<2|c<<3|d<<4|h<<5|p<<6|f<<7|g<<8|_<<9|v<<10|y<<11|C<<12|b<<13|T<<14|m<<15|S<<16,D=n.surfaceShader;if(e(D)&&D.numberOfDayTextures===a&&D.flags===P&&D.material===this.material)return D.shaderProgram;var I=this._shadersByTexturesFlags[a];if(e(I)||(I=this._shadersByTexturesFlags[a]=[]),D=I[P],!e(D)||D.material!==this.material){var O=this.baseVertexShaderSource.clone(),M=this.baseFragmentShaderSource.clone();O.defines.push(A),M.defines.push("TEXTURE_UNITS "+a),u&&M.defines.push("APPLY_BRIGHTNESS"),c&&M.defines.push("APPLY_CONTRAST"),d&&M.defines.push("APPLY_HUE"),h&&M.defines.push("APPLY_SATURATION"),p&&M.defines.push("APPLY_GAMMA"),f&&M.defines.push("APPLY_ALPHA"),g&&(M.defines.push("SHOW_REFLECTIVE_OCEAN"),O.defines.push("SHOW_REFLECTIVE_OCEAN")),_&&M.defines.push("SHOW_OCEAN_WAVES"),v&&(y?(O.defines.push("ENABLE_VERTEX_LIGHTING"),M.defines.push("ENABLE_VERTEX_LIGHTING")):(O.defines.push("ENABLE_DAYNIGHT_SHADING"),M.defines.push("ENABLE_DAYNIGHT_SHADING"))),O.defines.push("INCLUDE_WEB_MERCATOR_Y"),M.defines.push("INCLUDE_WEB_MERCATOR_Y"),b&&(O.defines.push("FOG"),M.defines.push("FOG")),m&&M.defines.push("APPLY_SPLIT"),S&&(M.defines.push("ENABLE_CLIPPING_PLANES"),w&&M.defines.push("UNION_CLIPPING_REGIONS"));for(var R=" vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates)\n {\n vec4 color = initialColor;\n",N=0;N<a;++N)R+=" color = sampleAndBlend(\n color,\n u_dayTextures["+N+"],\n u_dayTextureUseWebMercatorT["+N+"] ? textureCoordinates.xz : textureCoordinates.xy,\n u_dayTextureTexCoordsRectangle["+N+"],\n u_dayTextureTranslationAndScale["+N+"],\n "+(f?"u_dayTextureAlpha["+N+"]":"1.0")+",\n "+(u?"u_dayTextureBrightness["+N+"]":"0.0")+",\n "+(c?"u_dayTextureContrast["+N+"]":"0.0")+",\n "+(d?"u_dayTextureHue["+N+"]":"0.0")+",\n "+(h?"u_dayTextureSaturation["+N+"]":"0.0")+",\n "+(p?"u_dayTextureOneOverGamma["+N+"]":"0.0")+",\n "+(m?"u_dayTextureSplit["+N+"]":"0.0")+"\n );\n";R+=" return color;\n }",M.sources.push(R),O.sources.push(s(x)),O.sources.push(l(C));var L=i.fromCache({context:t.context,vertexShaderSource:O,fragmentShaderSource:M,attributeLocations:E.getAttributeLocations()});D=I[P]=new o(a,P,this.material,L)}return n.surfaceShader=D,D.shaderProgram},a.prototype.getPickShaderProgram=function(t,n,o){var a=0,u="",c=n.pickTerrain.mesh.encoding;c.quantization===r.BITS12&&(a=1,u="QUANTIZATION_BITS12");var d=t.mode,h=d|o<<2|a<<3,p=this._pickShaderPrograms[h];if(!e(p)){var f=this.baseVertexShaderSource.clone();f.defines.push(u),f.sources.push(s(d)),f.sources.push(l(o));p=this._pickShaderPrograms[h]=i.fromCache({context:t.context,vertexShaderSource:f,fragmentShaderSource:"void main()\n{\n gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n}\n",attributeLocations:c.getAttributeLocations()})}return p},a.prototype.destroy=function(){var r,i,n=this._shadersByTexturesFlags;for(var o in n)if(n.hasOwnProperty(o)){var a=n[o];if(!e(a))continue;for(r in a)a.hasOwnProperty(r)&&(i=a[r],e(i)&&i.shaderProgram.destroy())}var s=this._pickShaderPrograms;for(r in s)s.hasOwnProperty(r)&&(i=s[r],i.destroy());return t(this)},a}),define("Scene/ImageryState",["../Core/freezeObject"],function(e){"use strict";return e({UNLOADED:0,TRANSITIONING:1,RECEIVED:2,TEXTURE_LOADED:3,READY:4,FAILED:5,INVALID:6,PLACEHOLDER:7})}),define("Scene/QuadtreeTileLoadState",["../Core/freezeObject"],function(e){"use strict";return e({START:0,LOADING:1,DONE:2,FAILED:3})}),define("Scene/TerrainState",["../Core/freezeObject"],function(e){"use strict";return e({FAILED:0,UNLOADED:1,RECEIVING:2,RECEIVED:3,TRANSFORMING:4,TRANSFORMED:5,READY:6})}),define("Scene/TileTerrain",["../Core/BoundingSphere","../Core/Cartesian3","../Core/defined","../Core/DeveloperError","../Core/IndexDatatype","../Core/OrientedBoundingBox","../Core/Request","../Core/RequestState","../Core/RequestType","../Core/TileProviderError","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/VertexArray","../ThirdParty/when","./TerrainState"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){this.state=f.UNLOADED,this.data=void 0,this.mesh=void 0,this.vertexArray=void 0,this.upsampleDetails=e,this.request=void 0}function g(e,t,i,n,o,c){function d(t){e.data=t,e.state=f.RECEIVED,e.request=void 0}function h(){if(e.request.state===s.CANCELLED)return e.data=void 0,e.state=f.UNLOADED,void(e.request=void 0);e.state=f.FAILED,e.request=void 0;var r="Failed to obtain terrain tile X: "+i+" Y: "+n+" Level: "+o+".";t._requestError=u.handleError(t._requestError,t,t.errorEvent,r,i,n,o,m)}function m(){var s=new a({throttle:!0,throttleByServer:!0,type:l.TERRAIN,priorityFunction:c});e.request=s,e.data=t.requestTileGeometry(i,n,o,s),r(e.data)?(e.state=f.RECEIVING,p(e.data,d,h)):(e.state=f.UNLOADED,e.request=void 0)}m()}function _(e,t,i,n,o,a){var s=i.tilingScheme,l=e.data,u=l.createMesh(s,n,o,a,t.terrainExaggeration);r(u)&&(e.state=f.TRANSFORMING,p(u,function(t){e.mesh=t,e.state=f.TRANSFORMED},function(){e.state=f.FAILED}))}function v(e,t,i,o,a,s){var l=e.mesh.vertices,u=c.createVertexBuffer({context:t,typedArray:l,usage:d.STATIC_DRAW}),p=e.mesh.encoding.getAttributes(u),m=e.mesh.indices.indexBuffers||{},g=m[t.id];if(!r(g)||g.isDestroyed()){var _=e.mesh.indices,v=2===_.BYTES_PER_ELEMENT?n.UNSIGNED_SHORT:n.UNSIGNED_INT;g=c.createIndexBuffer({context:t,typedArray:_,usage:d.STATIC_DRAW,indexDatatype:v}),g.vertexArrayDestroyable=!1,g.referenceCount=1,m[t.id]=g,e.mesh.indices.indexBuffers=m}else++g.referenceCount;e.vertexArray=new h({context:t,attributes:p,indexBuffer:g}),e.state=f.READY}return m.prototype.freeResources=function(){if(this.state=f.UNLOADED,this.data=void 0,this.mesh=void 0,r(this.vertexArray)){var e=this.vertexArray.indexBuffer;this.vertexArray.destroy(),this.vertexArray=void 0,!e.isDestroyed()&&r(e.referenceCount)&&0===--e.referenceCount&&e.destroy()}},m.prototype.publishToTile=function(r){var i=r.data,n=this.mesh;t.clone(n.center,i.center),i.minimumHeight=n.minimumHeight,i.maximumHeight=n.maximumHeight,i.boundingSphere3D=e.clone(n.boundingSphere3D,i.boundingSphere3D),i.orientedBoundingBox=o.clone(n.orientedBoundingBox,i.orientedBoundingBox),i.tileBoundingRegion.minimumHeight=n.minimumHeight,i.tileBoundingRegion.maximumHeight=n.maximumHeight,r.data.occludeePointInScaledSpace=t.clone(n.occludeePointInScaledSpace,i.occludeePointInScaledSpace)},m.prototype.processLoadStateMachine=function(e,t,r,i,n,o){this.state===f.UNLOADED&&g(this,t,r,i,n,o),this.state===f.RECEIVED&&_(this,e,t,r,i,n),this.state===f.TRANSFORMED&&v(this,e.context,t,r,i,n)},m.prototype.processUpsampleStateMachine=function(e,t,i,n,o){if(this.state===f.UNLOADED){var a=this.upsampleDetails,s=a.data,l=a.x,u=a.y,c=a.level;if(this.data=s.upsample(t.tilingScheme,l,u,c,i,n,o),!r(this.data))return;this.state=f.RECEIVING;var d=this;p(this.data,function(e){d.data=e,d.state=f.RECEIVED},function(){d.state=f.FAILED})}this.state===f.RECEIVED&&_(this,e,t,i,n,o),this.state===f.TRANSFORMED&&v(this,e.context,t,i,n,o)},m}),define("Scene/GlobeSurfaceTile",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Cartesian4","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/IntersectionTests","../Core/PixelFormat","../Renderer/PixelDatatype","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","./ImageryState","./QuadtreeTileLoadState","./SceneMode","./TerrainState","./TileBoundingRegion","./TileTerrain"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function C(){this.imagery=[],this.waterMaskTexture=void 0,this.waterMaskTranslationAndScale=new r(0,0,1,1),this.terrainData=void 0,this.center=new t,this.vertexArray=void 0,this.minimumHeight=0,this.maximumHeight=0,this.boundingSphere3D=new e,this.boundingSphere2D=new e,this.orientedBoundingBox=void 0,this.tileBoundingRegion=void 0,this.occludeePointInScaledSpace=new t,this.loadedTerrain=void 0,this.upsampledTerrain=void 0,this.pickBoundingSphere=new e,this.pickTerrain=void 0,this.surfaceShader=void 0,this.isClipped=!0}function b(e,r,i,o,a,s){if(e.decodePosition(o,a,s),n(r)&&r!==g.SCENE3D){var l=i.ellipsoid,u=l.cartesianToCartographic(s);i.project(u,s),t.fromElements(s.z,s.x,s.y,s)}return s}function S(e){var t,r;return n(e.parent)&&n(e.parent.data)&&(t=e.parent.data.minimumHeight,r=e.parent.data.maximumHeight),new v({rectangle:e.rectangle,ellipsoid:e.tilingScheme.ellipsoid,minimumHeight:t,maximumHeight:r})}function w(e,t){return function(){return e.tileBoundingRegion.distanceToCamera(t)}}function T(e,t,r){var i=e.data,o=E(e);n(o)&&(i.upsampledTerrain=new y(o)),O(e,t)&&(i.loadedTerrain=new y);for(var a=0,s=r.length;a<s;++a){var l=r.get(a);l.show&&l._createTileImagerySkeletons(e,t)}}function A(e,t,r,o){var a=e.data,s=a.loadedTerrain,l=a.upsampledTerrain,u=!1;n(s)&&(s.processLoadStateMachine(t,r,e.x,e.y,e.level,e._priorityFunction),s.state>=_.RECEIVED&&(a.terrainData!==s.data&&(a.terrainData=s.data,R(t.context,a),D(e)),u=!0),s.state===_.READY?(s.publishToTile(e),n(e.data.vertexArray)&&o.push(e.data.vertexArray),e.data.vertexArray=s.vertexArray,s.vertexArray=void 0,a.pickTerrain=i(a.loadedTerrain,a.upsampledTerrain),a.loadedTerrain=void 0,a.upsampledTerrain=void 0):s.state===_.FAILED&&(a.loadedTerrain=void 0)),!u&&n(l)&&(l.processUpsampleStateMachine(t,r,e.x,e.y,e.level),l.state>=_.RECEIVED&&a.terrainData!==l.data&&(a.terrainData=l.data,r.hasWaterMask&&N(e),x(e)),l.state===_.READY?(l.publishToTile(e),n(e.data.vertexArray)&&o.push(e.data.vertexArray),e.data.vertexArray=l.vertexArray,l.vertexArray=void 0,a.pickTerrain=a.upsampledTerrain,a.upsampledTerrain=void 0):l.state===_.FAILED&&(a.upsampledTerrain=void 0))}function E(e){for(var t=e.parent;n(t)&&n(t.data)&&!n(t.data.terrainData);)t=t.parent;if(n(t)&&n(t.data))return{data:t.data.terrainData,x:t.x,y:t.y,level:t.level}}function x(e){P(e,e._southwestChild),P(e,e._southeastChild),P(e,e._northwestChild),P(e,e._northeastChild)}function P(e,t){if(n(t)&&t.state!==m.START){var r=t.data;if(n(r.terrainData)&&!r.terrainData.wasCreatedByUpsampling())return;n(r.upsampledTerrain)&&r.upsampledTerrain.freeResources(),r.upsampledTerrain=new y({data:e.data.terrainData,x:e.x,y:e.y,level:e.level}),t.state=m.LOADING}}function D(e){var t=e.data;I(e,t,e.southwestChild),I(e,t,e.southeastChild),I(e,t,e.northwestChild),I(e,t,e.northeastChild)}function I(e,t,r){if(r.state!==m.START){var i=r.data;if(n(i.terrainData)&&!i.terrainData.wasCreatedByUpsampling())return;n(i.upsampledTerrain)&&i.upsampledTerrain.freeResources(),i.upsampledTerrain=new y({data:t.terrainData,x:e.x,y:e.y,level:e.level}),t.terrainData.isChildAvailable(e.x,e.y,r.x,r.y)&&(n(i.loadedTerrain)||(i.loadedTerrain=new y)),r.state=m.LOADING}}function O(e,t){var r=t.getTileDataAvailable(e.x,e.y,e.level);if(n(r))return r;var i=e.parent;return!n(i)||!(!n(i.data)||!n(i.data.terrainData))&&i.data.terrainData.isChildAvailable(i.x,i.y,e.x,e.y)}function M(e){var t=e.cache.tile_waterMaskData;if(!n(t)){var r=new c({context:e,pixelFormat:s.LUMINANCE,pixelDatatype:l.UNSIGNED_BYTE,source:{arrayBufferView:new Uint8Array([255]),width:1,height:1}});r.referenceCount=1;t={allWaterTexture:r,sampler:new u({wrapS:p.CLAMP_TO_EDGE,wrapT:p.CLAMP_TO_EDGE, -minificationFilter:h.LINEAR,magnificationFilter:d.LINEAR}),destroy:function(){this.allWaterTexture.destroy()}},e.cache.tile_waterMaskData=t}return t}function R(e,t){var i=t.waterMaskTexture;n(i)&&(--i.referenceCount,0===i.referenceCount&&i.destroy(),t.waterMaskTexture=void 0);var o=t.terrainData.waterMask;if(n(o)){var a,u=M(e),d=o.length;if(1===d){if(0===o[0])return;a=u.allWaterTexture}else{var h=Math.sqrt(d);a=new c({context:e,pixelFormat:s.LUMINANCE,pixelDatatype:l.UNSIGNED_BYTE,source:{width:h,height:h,arrayBufferView:o},sampler:u.sampler}),a.referenceCount=0}++a.referenceCount,t.waterMaskTexture=a,r.fromElements(0,0,1,1,t.waterMaskTranslationAndScale)}}function N(e){for(var t=e.data,r=e.parent;n(r)&&!n(r.data.terrainData)||r.data.terrainData.wasCreatedByUpsampling();)r=r.parent;if(n(r)&&n(r.data.waterMaskTexture)){t.waterMaskTexture=r.data.waterMaskTexture,++t.waterMaskTexture.referenceCount;var i=r.rectangle,o=e.rectangle,a=o.width,s=o.height,l=a/i.width,u=s/i.height;t.waterMaskTranslationAndScale.x=l*(o.west-i.west)/a,t.waterMaskTranslationAndScale.y=u*(o.south-i.south)/s,t.waterMaskTranslationAndScale.z=l,t.waterMaskTranslationAndScale.w=u}}o(C.prototype,{eligibleForUnloading:{get:function(){for(var e=this.loadedTerrain,t=n(e)&&(e.state===_.RECEIVING||e.state===_.TRANSFORMING),r=this.upsampledTerrain,i=n(r)&&(r.state===_.RECEIVING||r.state===_.TRANSFORMING),o=!t&&!i,a=this.imagery,s=0,l=a.length;o&&s<l;++s){var u=a[s];o=!n(u.loadingImagery)||u.loadingImagery.state!==f.TRANSITIONING}return o}}});var L=new t,k=new t,F=new t,B=new t;return C.prototype.pick=function(e,r,i,o,s){var l=this.pickTerrain;if(n(l)){var u=l.mesh;if(n(u))for(var c=u.vertices,d=u.indices,h=u.encoding,p=d.length,f=0;f<p;f+=3){var m=d[f],g=d[f+1],_=d[f+2],v=b(h,r,i,c,m,L),y=b(h,r,i,c,g,k),C=b(h,r,i,c,_,F),S=a.rayTriangle(e,v,y,C,o,B);if(n(S))return t.clone(S,s)}}},C.prototype.freeResources=function(){n(this.waterMaskTexture)&&(--this.waterMaskTexture.referenceCount,0===this.waterMaskTexture.referenceCount&&this.waterMaskTexture.destroy(),this.waterMaskTexture=void 0),this.terrainData=void 0,n(this.loadedTerrain)&&(this.loadedTerrain.freeResources(),this.loadedTerrain=void 0),n(this.upsampledTerrain)&&(this.upsampledTerrain.freeResources(),this.upsampledTerrain=void 0),n(this.pickTerrain)&&(this.pickTerrain.freeResources(),this.pickTerrain=void 0);var e,t,r=this.imagery;for(e=0,t=r.length;e<t;++e)r[e].freeResources();this.imagery.length=0,this.freeVertexArray()},C.prototype.freeVertexArray=function(){var e;n(this.vertexArray)&&(e=this.vertexArray.indexBuffer,this.vertexArray=this.vertexArray.destroy(),!e.isDestroyed()&&n(e.referenceCount)&&0===--e.referenceCount&&e.destroy()),n(this.wireframeVertexArray)&&(e=this.wireframeVertexArray.indexBuffer,this.wireframeVertexArray=this.wireframeVertexArray.destroy(),!e.isDestroyed()&&n(e.referenceCount)&&0===--e.referenceCount&&e.destroy())},C.processStateMachine=function(e,t,r,i,o){var a=e.data;n(a)||(a=e.data=new C,a.tileBoundingRegion=S(e)),n(e._priorityFunction)||(e._priorityFunction=w(a,t)),e.state===m.START&&(T(e,r,i),e.state=m.LOADING),e.state===m.LOADING&&A(e,t,r,o);var s,l,u=n(a.vertexArray),c=!n(a.loadedTerrain)&&!n(a.upsampledTerrain),d=n(a.terrainData)&&a.terrainData.wasCreatedByUpsampling(),h=a.imagery;for(s=0,l=h.length;s<l;++s){var p=h[s];if(n(p.loadingImagery)){if(p.loadingImagery.state===f.PLACEHOLDER){var g=p.loadingImagery.imageryLayer;if(g.imageryProvider.ready){p.freeResources(),h.splice(s,1),g._createTileImagerySkeletons(e,r,s),--s,l=h.length;continue}d=!1}var _=p.processStateMachine(e,t);c=c&&_,u=u&&(_||n(p.readyImagery)),d=d&&n(p.loadingImagery)&&(p.loadingImagery.state===f.FAILED||p.loadingImagery.state===f.INVALID)}else d=!1}if(e.upsampledFromParent=d,s===l&&(u&&(e.renderable=!0),c)){var v=[];e._loadedCallbacks.forEach(function(t){t(e)||v.push(t)}),e._loadedCallbacks=v,e.state=m.DONE,e._priorityFunction=void 0}},C}),define("Shaders/ReprojectWebMercatorFS",[],function(){"use strict";return"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_FragColor = texture2D(u_texture, v_textureCoordinates);\n}\n"}),define("Shaders/ReprojectWebMercatorVS",[],function(){"use strict";return"attribute vec4 position;\nattribute float webMercatorT;\nuniform vec2 u_textureDimensions;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nv_textureCoordinates = vec2(position.x, webMercatorT);\ngl_Position = czm_viewportOrthographic * (position * vec4(u_textureDimensions, 1.0, 1.0));\n}\n"}),define("Scene/Imagery",["../Core/defined","../Core/destroyObject","./ImageryState"],function(e,t,r){"use strict";function i(t,i,n,o,a){if(this.imageryLayer=t,this.x=i,this.y=n,this.level=o,this.request=void 0,0!==o){var s=i/2|0,l=n/2|0,u=o-1;this.parent=t.getImageryFromCache(s,l,u)}if(this.state=r.UNLOADED,this.imageUrl=void 0,this.image=void 0,this.texture=void 0,this.textureWebMercator=void 0,this.credits=void 0,this.referenceCount=0,!e(a)&&t.imageryProvider.ready){a=t.imageryProvider.tilingScheme.tileXYToRectangle(i,n,o)}this.rectangle=a}return i.createPlaceholder=function(e){var t=new i(e,0,0,0);return t.addReference(),t.state=r.PLACEHOLDER,t},i.prototype.addReference=function(){++this.referenceCount},i.prototype.releaseReference=function(){return--this.referenceCount,0===this.referenceCount?(this.imageryLayer.removeImageryFromCache(this),e(this.parent)&&this.parent.releaseReference(),e(this.image)&&e(this.image.destroy)&&this.image.destroy(),e(this.texture)&&this.texture.destroy(),e(this.textureWebMercator)&&this.texture!==this.textureWebMercator&&this.textureWebMercator.destroy(),t(this),0):this.referenceCount},i.prototype.processStateMachine=function(e,t,i){this.state===r.UNLOADED&&(this.state=r.TRANSITIONING,this.imageryLayer._requestImagery(this,i)),this.state===r.RECEIVED&&(this.state=r.TRANSITIONING,this.imageryLayer._createTexture(e.context,this));var n=this.state===r.READY&&t&&!this.texture;(this.state===r.TEXTURE_LOADED||n)&&(this.state=r.TRANSITIONING,this.imageryLayer._reprojectTexture(e,this,t))},i}),define("Scene/ImagerySplitDirection",["../Core/freezeObject"],function(e){"use strict";return e({LEFT:-1,NONE:0,RIGHT:1})}),define("Scene/TileImagery",["../Core/defined","./ImageryState"],function(e,t){"use strict";function r(e,t,r){this.readyImagery=void 0,this.loadingImagery=e,this.textureCoordinateRectangle=t,this.textureTranslationAndScale=void 0,this.useWebMercatorT=r}return r.prototype.freeResources=function(){e(this.readyImagery)&&this.readyImagery.releaseReference(),e(this.loadingImagery)&&this.loadingImagery.releaseReference()},r.prototype.processStateMachine=function(r,i){var n=this.loadingImagery,o=n.imageryLayer;if(n.processStateMachine(i,!this.useWebMercatorT,r._priorityFunction),n.state===t.READY)return e(this.readyImagery)&&this.readyImagery.releaseReference(),this.readyImagery=this.loadingImagery,this.loadingImagery=void 0,this.textureTranslationAndScale=o._calculateTextureTranslationAndScale(r,this),!0;for(var a,s=n.parent;e(s)&&(s.state!==t.READY||!this.useWebMercatorT&&!e(s.texture));)s.state!==t.FAILED&&s.state!==t.INVALID&&(a=a||s),s=s.parent;return this.readyImagery!==s&&(e(this.readyImagery)&&this.readyImagery.releaseReference(),this.readyImagery=s,e(s)&&(s.addReference(),this.textureTranslationAndScale=o._calculateTextureTranslationAndScale(r,this))),(n.state===t.FAILED||n.state===t.INVALID)&&(!e(a)||(a.processStateMachine(i,!this.useWebMercatorT,r._priorityFunction),!1))},r}),define("Scene/ImageryLayer",["../Core/Cartesian2","../Core/Cartesian4","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/GeographicTilingScheme","../Core/IndexDatatype","../Core/Math","../Core/PixelFormat","../Core/Rectangle","../Core/Request","../Core/RequestState","../Core/RequestType","../Core/TerrainProvider","../Core/TileProviderError","../Core/WebMercatorProjection","../Core/WebMercatorTilingScheme","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ComputeCommand","../Renderer/ContextLimits","../Renderer/MipmapHint","../Renderer/Sampler","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Renderer/VertexArray","../Shaders/ReprojectWebMercatorFS","../Shaders/ReprojectWebMercatorVS","../ThirdParty/when","./Imagery","./ImagerySplitDirection","./ImageryState","./TileImagery"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U){"use strict";function V(e,t){this._imageryProvider=e,t=r(t,{}),this.alpha=r(t.alpha,r(e.defaultAlpha,1)),this.brightness=r(t.brightness,r(e.defaultBrightness,V.DEFAULT_BRIGHTNESS)),this.contrast=r(t.contrast,r(e.defaultContrast,V.DEFAULT_CONTRAST)),this.hue=r(t.hue,r(e.defaultHue,V.DEFAULT_HUE)),this.saturation=r(t.saturation,r(e.defaultSaturation,V.DEFAULT_SATURATION)),this.gamma=r(t.gamma,r(e.defaultGamma,V.DEFAULT_GAMMA)),this.splitDirection=r(t.splitDirection,r(e.defaultSplit,V.DEFAULT_SPLIT)),this.minificationFilter=r(t.minificationFilter,r(e.defaultMinificationFilter,V.DEFAULT_MINIFICATION_FILTER)),this.magnificationFilter=r(t.magnificationFilter,r(e.defaultMagnificationFilter,V.DEFAULT_MAGNIFICATION_FILTER)),this.show=r(t.show,!0),this._minimumTerrainLevel=t.minimumTerrainLevel,this._maximumTerrainLevel=t.maximumTerrainLevel,this._rectangle=r(t.rectangle,h.MAX_VALUE),this._maximumAnisotropy=t.maximumAnisotropy,this._imageryCache={},this._skeletonPlaceholder=new U(k.createPlaceholder(this)),this._show=!0,this._layerIndex=-1,this._isBaseLayer=!1,this._requestImageError=void 0,this._reprojectComputeCommands=[]}function z(e,t,r){return e+":"+t+":"+r}function G(e,t,n,o){var a=e.minificationFilter,s=e.magnificationFilter;if(a===I.LINEAR&&s===D.LINEAR&&!d.isCompressedFormat(o.pixelFormat)&&c.isPowerOfTwo(o.width)&&c.isPowerOfTwo(o.height)){a=I.LINEAR_MIPMAP_LINEAR;var l=w.maximumTextureFilterAnisotropy,u=Math.min(l,r(e._maximumAnisotropy,l)),h=z(a,s,u),p=t.cache.imageryLayerMipmapSamplers;i(p)||(p={},t.cache.imageryLayerMipmapSamplers=p);var f=p[h];i(f)||(f=p[h]=new A({wrapS:O.CLAMP_TO_EDGE,wrapT:O.CLAMP_TO_EDGE,minificationFilter:a,magnificationFilter:s,maximumAnisotropy:u})),o.generateMipmap(T.NICEST),o.sampler=f}else{var m=z(a,s,0),g=t.cache.imageryLayerNonMipmapSamplers;i(g)||(g={},t.cache.imageryLayerNonMipmapSamplers=g);var _=g[m];i(_)||(_=g[m]=new A({wrapS:O.CLAMP_TO_EDGE,wrapT:O.CLAMP_TO_EDGE,minificationFilter:a,magnificationFilter:s})),o.sampler=_}n.state=B.READY}function H(e,t,r){return JSON.stringify([e,t,r])}function W(e,t,r,n){var o=t.cache.imageryLayer_reproject;if(!i(o)){o=t.cache.imageryLayer_reproject={vertexArray:void 0,shaderProgram:void 0,sampler:void 0,destroy:function(){i(this.framebuffer)&&this.framebuffer.destroy(),i(this.vertexArray)&&this.vertexArray.destroy(),i(this.shaderProgram)&&this.shaderProgram.destroy()}};for(var a=new Float32Array(256),s=0,l=0;l<64;++l){var d=l/63;a[s++]=0,a[s++]=d,a[s++]=1,a[s++]=d}var h={position:0,webMercatorT:1},p=g.getRegularGridIndices(2,64),f=C.createIndexBuffer({context:t,typedArray:p,usage:b.STATIC_DRAW,indexDatatype:u.UNSIGNED_SHORT});o.vertexArray=new M({context:t,attributes:[{index:h.position,vertexBuffer:C.createVertexBuffer({context:t,typedArray:a,usage:b.STATIC_DRAW}),componentsPerAttribute:2},{index:h.webMercatorT,vertexBuffer:C.createVertexBuffer({context:t,sizeInBytes:512,usage:b.STREAM_DRAW}),componentsPerAttribute:1}],indexBuffer:f});var m=new x({sources:[N]});o.shaderProgram=E.fromCache({context:t,vertexShaderSource:m,fragmentShaderSource:R,attributeLocations:h}),o.sampler=new A({wrapS:O.CLAMP_TO_EDGE,wrapT:O.CLAMP_TO_EDGE,minificationFilter:I.LINEAR,magnificationFilter:D.LINEAR})}r.sampler=o.sampler;var _=r.width,v=r.height;Z.textureDimensions.x=_,Z.textureDimensions.y=v,Z.texture=r;var y=Math.sin(n.south),S=.5*Math.log((1+y)/(1-y));y=Math.sin(n.north);var w=.5*Math.log((1+y)/(1-y)),L=1/(w-S),k=new P({context:t,width:_,height:v,pixelFormat:r.pixelFormat,pixelDatatype:r.pixelDatatype,preMultiplyAlpha:r.preMultiplyAlpha});c.isPowerOfTwo(_)&&c.isPowerOfTwo(v)&&k.generateMipmap(T.NICEST);for(var F=n.south,B=n.north,U=K,V=0,z=0;z<64;++z){var G=z/63,H=c.lerp(F,B,G);y=Math.sin(H);var W=.5*Math.log((1+y)/(1-y)),j=(W-S)*L;U[V++]=j,U[V++]=j}o.vertexArray.getAttribute(1).vertexBuffer.copyFromArrayView(U),e.shaderProgram=o.shaderProgram,e.outputTexture=k,e.uniformMap=Z,e.vertexArray=o.vertexArray}function j(e,t,r){var i=e._imageryProvider,n=i.tilingScheme,o=n.ellipsoid,a=e._imageryProvider.tilingScheme instanceof l?1:Math.cos(r),s=n.rectangle,u=o.maximumRadius*s.width*a/(i.tileWidth*n.getNumberOfXTilesAtLevel(0)),c=u/t,d=Math.log(c)/Math.log(2);return 0|Math.round(d)}n(V.prototype,{imageryProvider:{get:function(){return this._imageryProvider}},rectangle:{get:function(){return this._rectangle}}}),V.DEFAULT_BRIGHTNESS=1,V.DEFAULT_CONTRAST=1,V.DEFAULT_HUE=0,V.DEFAULT_SATURATION=1,V.DEFAULT_GAMMA=1,V.DEFAULT_SPLIT=F.NONE,V.DEFAULT_MINIFICATION_FILTER=I.LINEAR,V.DEFAULT_MAGNIFICATION_FILTER=D.LINEAR,V.prototype.isBaseLayer=function(){return this._isBaseLayer},V.prototype.isDestroyed=function(){return!1},V.prototype.destroy=function(){return o(this)};var q=new h,Y=new h,X=new h,Q=new h;V.prototype.getViewableRectangle=function(){var e=this._imageryProvider,t=this._rectangle;return e.readyPromise.then(function(){return h.intersection(e.rectangle,t)})},V.prototype._createTileImagerySkeletons=function(e,r,n){var o=e.data;if(i(this._minimumTerrainLevel)&&e.level<this._minimumTerrainLevel)return!1;if(i(this._maximumTerrainLevel)&&e.level>this._maximumTerrainLevel)return!1;var a=this._imageryProvider;if(i(n)||(n=o.imagery.length),!a.ready)return this._skeletonPlaceholder.loadingImagery.addReference(),o.imagery.splice(n,0,this._skeletonPlaceholder),!0;var s=a.tilingScheme instanceof y&&e.rectangle.north<v.MaximumLatitude&&e.rectangle.south>-v.MaximumLatitude,l=h.intersection(a.rectangle,this._rectangle,q),u=h.intersection(e.rectangle,l,Y);if(!i(u)){if(!this.isBaseLayer())return!1;var c=l,d=e.rectangle;u=Y,d.south>=c.north?u.north=u.south=c.north:d.north<=c.south?u.north=u.south=c.south:(u.south=Math.max(d.south,c.south),u.north=Math.min(d.north,c.north)),d.west>=c.east?u.west=u.east=c.east:d.east<=c.west?u.west=u.east=c.west:(u.west=Math.max(d.west,c.west),u.east=Math.min(d.east,c.east))}var p=0;u.south>0?p=u.south:u.north<0&&(p=u.north);var f=1*r.getLevelMaximumGeometricError(e.level),m=j(this,f,p);m=Math.max(0,m);var g=a.maximumLevel;if(m>g&&(m=g),i(a.minimumLevel)){var _=a.minimumLevel;m<_&&(m=_)}var C=a.tilingScheme,b=C.positionToTileXY(h.northwest(u),m),S=C.positionToTileXY(h.southeast(u),m),w=e.rectangle.width/512,T=e.rectangle.height/512,A=C.tileXYToRectangle(b.x,b.y,m);Math.abs(A.south-e.rectangle.north)<T&&b.y<S.y&&++b.y,Math.abs(A.east-e.rectangle.west)<w&&b.x<S.x&&++b.x;var E=C.tileXYToRectangle(S.x,S.y,m);Math.abs(E.north-e.rectangle.south)<T&&S.y>b.y&&--S.y,Math.abs(E.west-e.rectangle.east)<w&&S.x>b.x&&--S.x;var x,P=h.clone(e.rectangle,Q),D=C.tileXYToRectangle(b.x,b.y,m),I=h.intersection(D,l,X);s?(C.rectangleToNativeRectangle(P,P),C.rectangleToNativeRectangle(D,D),C.rectangleToNativeRectangle(I,I),C.rectangleToNativeRectangle(l,l),x=C.tileXYToNativeRectangle.bind(C),w=P.width/512,T=P.height/512):x=C.tileXYToRectangle.bind(C);var O,M,R=0,N=1;!this.isBaseLayer()&&Math.abs(I.west-P.west)>=w&&(R=Math.min(1,(I.west-P.west)/P.width)),!this.isBaseLayer()&&Math.abs(I.north-P.north)>=T&&(N=Math.max(0,(I.north-P.south)/P.height));for(var L=N,k=b.x;k<=S.x;k++)if(O=R,D=x(k,b.y,m),I=h.simpleIntersection(D,l,X),i(I)){R=Math.min(1,(I.east-P.west)/P.width),k===S.x&&(this.isBaseLayer()||Math.abs(I.east-P.east)<w)&&(R=1),N=L;for(var F=b.y;F<=S.y;F++)if(M=N,D=x(k,F,m),I=h.simpleIntersection(D,l,X),i(I)){N=Math.max(0,(I.south-P.south)/P.height),F===S.y&&(this.isBaseLayer()||Math.abs(I.south-P.south)<T)&&(N=0);var B=new t(O,N,R,M),V=this.getImageryFromCache(k,F,m);o.imagery.splice(n,0,new U(V,B,s)),++n}}return!0},V.prototype._calculateTextureTranslationAndScale=function(e,r){var i=r.readyImagery.rectangle,n=e.rectangle;if(r.useWebMercatorT){var o=r.readyImagery.imageryLayer.imageryProvider.tilingScheme;i=o.rectangleToNativeRectangle(i,q),n=o.rectangleToNativeRectangle(n,Q)}var a=n.width,s=n.height,l=a/i.width,u=s/i.height;return new t(l*(n.west-i.west)/a,u*(n.south-i.south)/s,l,u)},V.prototype._requestImagery=function(e,t){function r(t){if(!i(t))return n();e.image=t,e.state=B.RECEIVED,e.request=void 0,_.handleSuccess(s._requestImageError)}function n(t){if(e.request.state===f.CANCELLED)return e.state=B.UNLOADED,void(e.request=void 0);e.state=B.FAILED,e.request=void 0;var r="Failed to obtain image tile X: "+e.x+" Y: "+e.y+" Level: "+e.level+".";s._requestImageError=_.handleError(s._requestImageError,a,a.errorEvent,r,e.x,e.y,e.level,o,t)}function o(){var o=new p({throttle:!0,throttleByServer:!0,type:m.IMAGERY,priorityFunction:t});e.request=o,e.state=B.TRANSITIONING;var s=a.requestImage(e.x,e.y,e.level,o);if(!i(s))return e.state=B.UNLOADED,void(e.request=void 0);i(a.getTileCredits)&&(e.credits=a.getTileCredits(e.x,e.y,e.level)),L(s,r,n)}var a=this._imageryProvider,s=this;o()},V.prototype._createTexture=function(e,t){var r=this._imageryProvider,n=t.image;if(i(r.tileDiscardPolicy)){var o=r.tileDiscardPolicy;if(i(o)){if(!o.isReady())return void(t.state=B.RECEIVED);if(o.shouldDiscardImage(n))return void(t.state=B.INVALID)}}var a,s=new A({minificationFilter:this.minificationFilter,magnificationFilter:this.magnificationFilter});a=new P(i(n.internalFormat)?{context:e,pixelFormat:n.internalFormat,width:n.width,height:n.height,source:{arrayBufferView:n.bufferView},sampler:s}:{context:e,source:n,pixelFormat:r.hasAlphaChannel?d.RGBA:d.RGB,sampler:s}),r.tilingScheme instanceof y?t.textureWebMercator=a:t.texture=a,t.image=void 0,t.state=B.TEXTURE_LOADED},V.prototype._reprojectTexture=function(e,t,i){var n=t.textureWebMercator||t.texture,o=t.rectangle,a=e.context;if((i=r(i,!0))&&!(this._imageryProvider.tilingScheme instanceof l)&&o.width/n.width>1e-5){var s=this;t.addReference();var u=new S({persists:!0,owner:this,preExecute:function(e){W(e,a,n,t.rectangle)},postExecute:function(e){t.texture=e,G(s,a,t,e),t.releaseReference()}});this._reprojectComputeCommands.push(u)}else i&&(t.texture=n),G(this,a,t,n)},V.prototype.queueReprojectionCommands=function(e){for(var t=this._reprojectComputeCommands,r=t.length,i=0;i<r;++i)e.commandList.push(t[i]);t.length=0},V.prototype.cancelReprojections=function(){this._reprojectComputeCommands.length=0},V.prototype.getImageryFromCache=function(e,t,r,n){var o=H(e,t,r),a=this._imageryCache[o];return i(a)||(a=new k(this,e,t,r,n),this._imageryCache[o]=a),a.addReference(),a},V.prototype.removeImageryFromCache=function(e){var t=H(e.x,e.y,e.level);delete this._imageryCache[t]};var Z={u_textureDimensions:function(){return this.textureDimensions},u_texture:function(){return this.texture},textureDimensions:new e,texture:void 0},K=s.supportsTypedArrays()?new Float32Array(128):void 0;return V}),define("Scene/GlobeSurfaceTileProvider",["../Core/BoundingSphere","../Core/BoxOutlineGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../Core/FeatureDetection","../Core/GeometryInstance","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Intersect","../Core/Math","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/OrthographicFrustum","../Core/Plane","../Core/PrimitiveType","../Core/Rectangle","../Core/SphereOutlineGeometry","../Core/TerrainQuantization","../Core/Visibility","../Core/WebMercatorProjection","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/VertexArray","../Scene/BlendingState","../Scene/DepthFunction","../Scene/PerInstanceColorAppearance","../Scene/Primitive","./GlobeSurfaceTile","./ImageryLayer","./QuadtreeTileLoadState","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H,W,j){"use strict";function q(e){this.lightingFadeOutDistance=65e5,this.lightingFadeInDistance=9e6,this.hasWaterMask=!1,this.oceanNormalMap=void 0,this.zoomedOutOceanSpecularIntensity=.5,this.enableLighting=!1,this.shadows=j.RECEIVE_ONLY,this._quadtree=void 0,this._terrainProvider=e.terrainProvider,this._imageryLayers=e.imageryLayers,this._surfaceShaderSet=e.surfaceShaderSet,this._renderState=void 0,this._blendRenderState=void 0,this._pickRenderState=void 0,this._errorEvent=new p,this._imageryLayers.layerAdded.addEventListener(q.prototype._onLayerAdded,this),this._imageryLayers.layerRemoved.addEventListener(q.prototype._onLayerRemoved,this),this._imageryLayers.layerMoved.addEventListener(q.prototype._onLayerMoved,this),this._imageryLayers.layerShownOrHidden.addEventListener(q.prototype._onLayerShownOrHidden,this),this._layerOrderChanged=!1,this._tilesToRenderByTextureCount=[],this._drawCommands=[],this._uniformMaps=[],this._pickCommands=[],this._usedDrawCommands=0,this._usedPickCommands=0,this._vertexArraysToDestroy=[],this._debug={wireframe:!1,boundingSphereTile:void 0},this._baseColor=void 0,this._firstPassInitialColor=void 0,this.baseColor=new o(0,0,.5,1),this.clippingPlanes=void 0}function Y(e,t){var r=e.loadingImagery;u(r)||(r=e.readyImagery);var i=t.loadingImagery;return u(i)||(i=t.readyImagery),r.imageryLayer._layerIndex-i.imageryLayer._layerIndex}function X(e){var t=e.indexBuffer;e.destroy(),!t.isDestroyed()&&u(t.referenceCount)&&0===--t.referenceCount&&t.destroy()}function Q(e,t,r){return function(i){var n,o,a,s=-1,c=i.data.imagery,d=c.length;for(a=0;a<d;++a)if(n=c[a],o=l(n.readyImagery,n.loadingImagery),o.imageryLayer===t){s=a;break}if(-1!==s){var h=s+e;if(n=c[h],o=u(n)?l(n.readyImagery,n.loadingImagery):void 0,!u(o)||o.imageryLayer!==t)return!t._createTileImagerySkeletons(i,r,h);for(a=s;a<h;++a)c[a].freeResources();c.splice(s,e)}return!0}}function Z(e){return{u_initialColor:function(){return this.properties.initialColor},u_zoomedOutOceanSpecularIntensity:function(){return this.properties.zoomedOutOceanSpecularIntensity},u_oceanNormalMap:function(){return this.properties.oceanNormalMap},u_lightingFadeDistance:function(){return this.properties.lightingFadeDistance},u_center3D:function(){return this.properties.center3D},u_tileRectangle:function(){return this.properties.tileRectangle},u_modifiedModelView:function(){var t=e.context.uniformState.view,r=C.multiplyByPoint(t,this.properties.rtc,ae);return C.setTranslation(t,r,re),re},u_modifiedModelViewProjection:function(){var t=e.context.uniformState.view,r=e.context.uniformState.projection,i=C.multiplyByPoint(t,this.properties.rtc,ae);return C.setTranslation(t,i,ie),C.multiply(r,ie,ie),ie},u_dayTextures:function(){return this.properties.dayTextures},u_dayTextureTranslationAndScale:function(){return this.properties.dayTextureTranslationAndScale},u_dayTextureTexCoordsRectangle:function(){return this.properties.dayTextureTexCoordsRectangle},u_dayTextureUseWebMercatorT:function(){return this.properties.dayTextureUseWebMercatorT},u_dayTextureAlpha:function(){return this.properties.dayTextureAlpha},u_dayTextureBrightness:function(){return this.properties.dayTextureBrightness},u_dayTextureContrast:function(){return this.properties.dayTextureContrast},u_dayTextureHue:function(){return this.properties.dayTextureHue},u_dayTextureSaturation:function(){return this.properties.dayTextureSaturation},u_dayTextureOneOverGamma:function(){return this.properties.dayTextureOneOverGamma},u_dayIntensity:function(){return this.properties.dayIntensity},u_southAndNorthLatitude:function(){return this.properties.southAndNorthLatitude},u_southMercatorYAndOneOverHeight:function(){return this.properties.southMercatorYAndOneOverHeight},u_waterMask:function(){return this.properties.waterMask},u_waterMaskTranslationAndScale:function(){return this.properties.waterMaskTranslationAndScale},u_minMaxHeight:function(){return this.properties.minMaxHeight},u_scaleAndBias:function(){return this.properties.scaleAndBias},u_dayTextureSplit:function(){return this.properties.dayTextureSplit},u_clippingPlanesLength:function(){return this.properties.clippingPlanes.length},u_clippingPlanes:function(){return this.properties.clippingPlanes},u_clippingPlanesEdgeStyle:function(){var e=this.properties.clippingPlanesEdgeColor;return e.alpha=this.properties.clippingPlanesEdgeWidth,e},u_minimumBrightness:function(){return e.fog.minimumBrightness},properties:{initialColor:new n(0,0,.5,1),zoomedOutOceanSpecularIntensity:.5,oceanNormalMap:void 0,lightingFadeDistance:new r(65e5,9e6),center3D:void 0,rtc:new i,modifiedModelView:new C,tileRectangle:new n,dayTextures:[],dayTextureTranslationAndScale:[],dayTextureTexCoordsRectangle:[],dayTextureUseWebMercatorT:[],dayTextureAlpha:[],dayTextureBrightness:[],dayTextureContrast:[],dayTextureHue:[],dayTextureSaturation:[],dayTextureOneOverGamma:[],dayTextureSplit:[],dayIntensity:0,southAndNorthLatitude:new r,southMercatorYAndOneOverHeight:new r,waterMask:void 0,waterMaskTranslationAndScale:new n,minMaxHeight:new r,scaleAndBias:new C,clippingPlanes:[],clippingPlanesEdgeColor:o.clone(o.WHITE),clippingPlanesEdgeWidth:0}}}function K(e,t,r){var i=r.data;u(i.wireframeVertexArray)||u(i.terrainData)&&u(i.terrainData._mesh)&&(i.wireframeVertexArray=J(e,i.vertexArray,i.terrainData._mesh))}function J(e,t,r){var i={indices:r.indices,primitiveType:T.TRIANGLES};g.toWireframe(i);var n=i.indices,o=I.createIndexBuffer({context:e,typedArray:n,usage:O.STATIC_DRAW,indexDatatype:_.UNSIGNED_SHORT});return new k({context:e,attributes:t._attributes,indexBuffer:o})}function $(t,r,a){var l=r.data,c=a.creditDisplay,d=l.terrainData;if(u(d)&&u(d.credits))for(var h=d.credits,p=0,m=h.length;p<m;++p)c.addCredit(h[p]);var g=M.maximumTextureImageUnits,_=l.waterMaskTexture,v=t.hasWaterMask&&u(_),S=t.oceanNormalMap,w=v&&u(S),E=t.terrainProvider.ready&&t.terrainProvider.hasVertexNormals,P=a.fog.enabled,I=j.castShadows(t.shadows),O=j.receiveShadows(t.shadows);v&&--g,w&&--g;var L=l.center,k=l.pickTerrain.mesh.encoding,F=ne,B=0,U=0,V=0,z=0,H=!1;if(a.mode!==W.SCENE3D){var q=a.mapProjection,Y=q.project(A.southwest(r.rectangle),se),X=q.project(A.northeast(r.rectangle),le);if(F.x=Y.x,F.y=Y.y,F.z=X.x,F.w=X.y,a.mode!==W.MORPHING&&(L=oe,L.x=0,L.y=.5*(F.z+F.x),L.z=.5*(F.w+F.y),F.x-=L.y,F.y-=L.z,F.z-=L.y,F.w-=L.z),a.mode===W.SCENE2D&&k.quantization===x.BITS12){var Q=1/(Math.pow(2,12)-1)*.5,J=(F.z-F.x)*Q,$=(F.w-F.y)*Q;F.x-=J,F.y-=$,F.z+=J,F.w+=$}q instanceof D&&(B=r.rectangle.south,U=r.rectangle.north,V=D.geodeticLatitudeToMercatorAngle(B),z=1/(D.geodeticLatitudeToMercatorAngle(U)-V),H=!0)}var ee=l.imagery,te=0,re=ee.length,ie=t._renderState,ae=t._blendRenderState,pe=ie,fe=t._firstPassInitialColor,me=a.context;u(t._debug.boundingSphereTile)||de();do{var ge,_e,ve=0;t._drawCommands.length<=t._usedDrawCommands?(ge=new R,ge.owner=r,ge.cull=!1,ge.boundingVolume=new e,ge.orientedBoundingBox=void 0,_e=Z(a),t._drawCommands.push(ge),t._uniformMaps.push(_e)):(ge=t._drawCommands[t._usedDrawCommands],_e=t._uniformMaps[t._usedDrawCommands]),ge.owner=r,++t._usedDrawCommands,r===t._debug.boundingSphereTile&&(u(l.orientedBoundingBox)?ue(l.orientedBoundingBox,o.RED).update(a):u(l.boundingSphere3D)&&ce(l.boundingSphere3D,o.RED).update(a));var ye=_e.properties;n.clone(fe,ye.initialColor),ye.oceanNormalMap=S,ye.lightingFadeDistance.x=t.lightingFadeOutDistance,ye.lightingFadeDistance.y=t.lightingFadeInDistance,ye.zoomedOutOceanSpecularIntensity=t.zoomedOutOceanSpecularIntensity,ye.center3D=l.center,i.clone(L,ye.rtc),n.clone(F,ye.tileRectangle),ye.southAndNorthLatitude.x=B,ye.southAndNorthLatitude.y=U,ye.southMercatorYAndOneOverHeight.x=V,ye.southMercatorYAndOneOverHeight.y=z;for(var Ce=P&&y.fog(r._distance,a.fog.density)>y.EPSILON3,be=!1,Se=!1,we=!1,Te=!1,Ae=!1,Ee=!1,xe=!1;ve<g&&te<re;){var Pe=ee[te],De=Pe.readyImagery;if(++te,u(De)&&0!==De.imageryLayer.alpha){var Ie=Pe.useWebMercatorT?De.textureWebMercator:De.texture,Oe=De.imageryLayer;if(u(Pe.textureTranslationAndScale)||(Pe.textureTranslationAndScale=Oe._calculateTextureTranslationAndScale(r,Pe)),ye.dayTextures[ve]=Ie,ye.dayTextureTranslationAndScale[ve]=Pe.textureTranslationAndScale,ye.dayTextureTexCoordsRectangle[ve]=Pe.textureCoordinateRectangle,ye.dayTextureUseWebMercatorT[ve]=Pe.useWebMercatorT,ye.dayTextureAlpha[ve]=Oe.alpha,Ee=Ee||1!==ye.dayTextureAlpha[ve],ye.dayTextureBrightness[ve]=Oe.brightness,be=be||ye.dayTextureBrightness[ve]!==G.DEFAULT_BRIGHTNESS,ye.dayTextureContrast[ve]=Oe.contrast,Se=Se||ye.dayTextureContrast[ve]!==G.DEFAULT_CONTRAST,ye.dayTextureHue[ve]=Oe.hue,we=we||ye.dayTextureHue[ve]!==G.DEFAULT_HUE,ye.dayTextureSaturation[ve]=Oe.saturation,Te=Te||ye.dayTextureSaturation[ve]!==G.DEFAULT_SATURATION,ye.dayTextureOneOverGamma[ve]=1/Oe.gamma,Ae=Ae||ye.dayTextureOneOverGamma[ve]!==1/G.DEFAULT_GAMMA,ye.dayTextureSplit[ve]=Oe.splitDirection,xe=xe||0!==ye.dayTextureSplit[ve],u(De.credits))for(var Me=De.credits,Re=0,Ne=Me.length;Re<Ne;++Re)c.addCredit(Me[Re]);++ve}}ye.dayTextures.length=ve,ye.waterMask=_,n.clone(l.waterMaskTranslationAndScale,ye.waterMaskTranslationAndScale),ye.minMaxHeight.x=k.minimumHeight,ye.minMaxHeight.y=k.maximumHeight,C.clone(k.matrix,ye.scaleAndBias);var Le=t.clippingPlanes,ke=0;u(Le)&&r.isClipped&&(ke=Le.length);var Fe=ye.clippingPlanes,Be=Fe.length;if(Be!==ke){Fe.length=ke;for(var Ue=Be;Ue<ke;++Ue)Fe[Ue]=new n}u(Le)&&Le.enabled&&r.isClipped&&(Le.transformAndPackPlanes(me.uniformState.view,Fe),ye.clippingPlanesEdgeColor=o.clone(Le.edgeColor,ye.clippingPlanesEdgeColor),ye.clippingPlanesEdgeWidth=Le.edgeWidth);var Ve=u(Le)&&Le.enabled&&ye.clippingPlanes.length>0&&!f.isInternetExplorer(),ze=!!Ve&&Le.unionClippingRegions;u(t.uniformMap)&&(_e=s(_e,t.uniformMap)),ge.shaderProgram=t._surfaceShaderSet.getShaderProgram(a,l,ve,be,Se,we,Te,Ae,Ee,xe,v,w,t.enableLighting,E,H,Ce,Ve,ze),ge.castShadows=I,ge.receiveShadows=O,ge.renderState=pe,ge.primitiveType=T.TRIANGLES,ge.vertexArray=l.vertexArray,ge.uniformMap=_e,ge.pass=N.GLOBE,t._debug.wireframe&&(K(me,t,r),u(l.wireframeVertexArray)&&(ge.vertexArray=l.wireframeVertexArray,ge.primitiveType=T.LINES));var Ge=ge.boundingVolume,He=ge.orientedBoundingBox;a.mode!==W.SCENE3D?(e.fromRectangleWithHeights2D(r.rectangle,a.mapProjection,l.minimumHeight,l.maximumHeight,Ge),i.fromElements(Ge.center.z,Ge.center.x,Ge.center.y,Ge.center),a.mode===W.MORPHING&&(Ge=e.union(l.boundingSphere3D,Ge,Ge))):(ge.boundingVolume=e.clone(l.boundingSphere3D,Ge),ge.orientedBoundingBox=b.clone(l.orientedBoundingBox,He)),a.commandList.push(ge),pe=ae,fe=he}while(te<re)}function ee(e,t,r){var i;e._pickCommands.length<=e._usedPickCommands?(i=new R,i.cull=!1,e._pickCommands.push(i)):i=e._pickCommands[e._usedPickCommands],++e._usedPickCommands;var n=t.owner.data,o=r.projection instanceof D;i.shaderProgram=e._surfaceShaderSet.getPickShaderProgram(r,n,o),i.renderState=e._pickRenderState,i.owner=t.owner,i.primitiveType=t.primitiveType,i.vertexArray=t.vertexArray,i.uniformMap=t.uniformMap,i.boundingVolume=t.boundingVolume,i.orientedBoundingBox=t.orientedBoundingBox,i.pass=t.pass,r.commandList.push(i)}c(q.prototype,{baseColor:{get:function(){return this._baseColor},set:function(e){this._baseColor=e,this._firstPassInitialColor=n.fromColor(e,this._firstPassInitialColor)}},quadtree:{get:function(){return this._quadtree},set:function(e){this._quadtree=e}},ready:{get:function(){return this._terrainProvider.ready&&(0===this._imageryLayers.length||this._imageryLayers.get(0).imageryProvider.ready)}},tilingScheme:{get:function(){return this._terrainProvider.tilingScheme}},errorEvent:{get:function(){return this._errorEvent}},terrainProvider:{ -get:function(){return this._terrainProvider},set:function(e){this._terrainProvider!==e&&(this._terrainProvider=e,u(this._quadtree)&&this._quadtree.invalidateAllTiles())}}}),q.prototype.initialize=function(e){var t=this._imageryLayers;t._update(),t.queueReprojectionCommands(e),this._layerOrderChanged&&(this._layerOrderChanged=!1,this._quadtree.forEachLoadedTile(function(e){e.data.imagery.sort(Y)}));var r=e.creditDisplay;this._terrainProvider.ready&&u(this._terrainProvider.credit)&&r.addCredit(this._terrainProvider.credit);for(var i=0,n=t.length;i<n;++i){var o=t.get(i).imageryProvider;o.ready&&u(o.credit)&&r.addCredit(o.credit)}for(var a=this._vertexArraysToDestroy,s=a.length,l=0;l<s;++l)X(a[l]);a.length=0},q.prototype.beginUpdate=function(e){for(var t=this._tilesToRenderByTextureCount,r=0,i=t.length;r<i;++r){var n=t[r];u(n)&&(n.length=0)}this._usedDrawCommands=0},q.prototype.endUpdate=function(e){u(this._renderState)||(this._renderState=L.fromCache({cull:{enabled:!0},depthTest:{enabled:!0,func:B.LESS}}),this._blendRenderState=L.fromCache({cull:{enabled:!0},depthTest:{enabled:!0,func:B.LESS_OR_EQUAL},blending:F.ALPHA_BLEND}));for(var t=this._tilesToRenderByTextureCount,r=0,i=t.length;r<i;++r){var n=t[r];if(u(n))for(var o=0,a=n.length;o<a;++o)$(this,n[o],e)}},q.prototype.updateForPick=function(e){u(this._pickRenderState)||(this._pickRenderState=L.fromCache({colorMask:{red:!1,green:!1,blue:!1,alpha:!1},depthTest:{enabled:!0}})),this._usedPickCommands=0;for(var t=this._drawCommands,r=0,i=this._usedDrawCommands;r<i;++r)ee(this,t[r],e)},q.prototype.cancelReprojections=function(){this._imageryLayers.cancelReprojections()},q.prototype.getLevelMaximumGeometricError=function(e){return this._terrainProvider.getLevelMaximumGeometricError(e)},q.prototype.loadTile=function(e,t){z.processStateMachine(t,e,this._terrainProvider,this._imageryLayers,this._vertexArraysToDestroy)};var te=new e;q.prototype.computeTileVisibility=function(t,r,n){var o=this.computeDistanceToTile(t,r);if(t._distance=o,r.fog.enabled&&y.fog(o,r.fog.density)>=1)return P.NONE;var a=t.data,s=r.cullingVolume,c=l(a.orientedBoundingBox,a.boundingSphere3D);r.mode!==W.SCENE3D&&(c=te,e.fromRectangleWithHeights2D(t.rectangle,r.mapProjection,a.minimumHeight,a.maximumHeight,c),i.fromElements(c.center.z,c.center.x,c.center.y,c.center),r.mode===W.MORPHING&&(c=e.union(a.boundingSphere3D,c,c)));var d=this.clippingPlanes;if(u(d)&&d.enabled){var h=d.computeIntersectionWithBoundingVolume(c);if(t.isClipped=h!==v.INSIDE,h===v.OUTSIDE)return P.NONE}var p=s.computeVisibility(c);if(p===v.OUTSIDE)return P.NONE;var f=r.mode===W.SCENE3D&&r.camera.frustum instanceof S;if(r.mode===W.SCENE3D&&!f&&u(n)){var m=a.occludeePointInScaledSpace;return u(m)?n.ellipsoid.isScaledSpacePointVisible(m)?p:P.NONE:p}return p};var re=new C,ie=new C,ne=new n,oe=new i,ae=new i,se=new i,le=new i;q.prototype.showTileThisFrame=function(e,t){for(var r=0,i=e.data.imagery,n=0,o=i.length;n<o;++n){var a=i[n];u(a.readyImagery)&&0!==a.readyImagery.imageryLayer.alpha&&++r}var s=this._tilesToRenderByTextureCount[r];u(s)||(s=[],this._tilesToRenderByTextureCount[r]=s),s.push(e);var l=this._debug;++l.tilesRendered,l.texturesRendered+=r},q.prototype.computeDistanceToTile=function(e,t){return e.data.tileBoundingRegion.distanceToCamera(t)},q.prototype.isDestroyed=function(){return!1},q.prototype.destroy=function(){return this._tileProvider=this._tileProvider&&this._tileProvider.destroy(),d(this)},q.prototype._onLayerAdded=function(e,t){if(e.show){var r=this._terrainProvider,i=this;e.imageryProvider._reload=function(){e._imageryCache={},i._quadtree.forEachLoadedTile(function(t){if(t.state===H.DONE){var i,n=t.data.imagery,o=n.length,a=-1,s=0;for(i=0;i<o;++i){var u=n[i];if(l(u.readyImagery,u.loadingImagery).imageryLayer===e)-1===a&&(a=i),++s;else if(-1!==a)break}if(-1!==a){var c=a+s;e._createTileImagerySkeletons(t,r,c)&&(t._loadedCallbacks.push(Q(s,e,r)),t.state=H.LOADING)}}})},this._quadtree.forEachLoadedTile(function(t){e._createTileImagerySkeletons(t,r)&&(t.state=H.LOADING)}),this._layerOrderChanged=!0}},q.prototype._onLayerRemoved=function(e,t){this._quadtree.forEachLoadedTile(function(t){for(var r=t.data.imagery,i=-1,n=0,o=0,a=r.length;o<a;++o){var s=r[o],l=s.loadingImagery;if(u(l)||(l=s.readyImagery),l.imageryLayer===e)-1===i&&(i=o),s.freeResources(),++n;else if(-1!==i)break}-1!==i&&r.splice(i,n)}),u(e.imageryProvider)&&(e.imageryProvider._reload=void 0)},q.prototype._onLayerMoved=function(e,t,r){this._layerOrderChanged=!0},q.prototype._onLayerShownOrHidden=function(e,t,r){r?this._onLayerAdded(e,t):this._onLayerRemoved(e,t)};var ue,ce,de;!function(){function e(e){return new V({geometryInstances:e,appearance:new U({translucent:!1,flat:!0}),asynchronous:!1})}var r,n,o=new m({geometry:t.fromDimensions({dimensions:new i(2,2,2)})}),s=new m({geometry:new E({radius:1})}),l=new C;ue=function(t,i){return t===r?n:(de(),r=t,l=C.fromRotationTranslation(t.halfAxes,t.center,l),o.modelMatrix=l,o.attributes.color=a.fromColor(i),n=e(o))},ce=function(t,i){return t===r?n:(de(),r=t,l=C.fromTranslation(t.center,l),l=C.multiplyByUniformScale(l,t.radius,l),s.modelMatrix=l,s.attributes.color=a.fromColor(i),n=e(s))},de=function(){u(n)&&(n.destroy(),n=void 0,r=void 0)}}();var he=new n(0,0,0,0);return q}),define("Scene/ImageryLayerCollection",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../Core/Math","../Core/Rectangle","../ThirdParty/when","./ImageryLayer"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(){this._layers=[],this.layerAdded=new o,this.layerRemoved=new o,this.layerMoved=new o,this.layerShownOrHidden=new o}function d(e,t){return e.indexOf(t)}function h(e,t,r){var i=e._layers;if(t=a.clamp(t,0,i.length-1),r=a.clamp(r,0,i.length-1),t!==r){var n=i[t];i[t]=i[r],i[r]=n,e._update(),e.layerMoved.raiseEvent(n,r,t)}}r(c.prototype,{length:{get:function(){return this._layers.length}}}),c.prototype.add=function(e,r){t(r)?this._layers.splice(r,0,e):(r=this._layers.length,this._layers.push(e)),this._update(),this.layerAdded.raiseEvent(e,r)},c.prototype.addImageryProvider=function(e,t){var r=new u(e);return this.add(r,t),r},c.prototype.remove=function(t,r){r=e(r,!0);var i=this._layers.indexOf(t);return-1!==i&&(this._layers.splice(i,1),this._update(),this.layerRemoved.raiseEvent(t,i),r&&t.destroy(),!0)},c.prototype.removeAll=function(t){t=e(t,!0);for(var r=this._layers,i=0,n=r.length;i<n;i++){var o=r[i];this.layerRemoved.raiseEvent(o,i),t&&o.destroy()}this._layers=[]},c.prototype.contains=function(e){return-1!==this.indexOf(e)},c.prototype.indexOf=function(e){return this._layers.indexOf(e)},c.prototype.get=function(e){return this._layers[e]},c.prototype.raise=function(e){var t=d(this._layers,e);h(this,t,t+1)},c.prototype.lower=function(e){var t=d(this._layers,e);h(this,t,t-1)},c.prototype.raiseToTop=function(e){var t=d(this._layers,e);t!==this._layers.length-1&&(this._layers.splice(t,1),this._layers.push(e),this._update(),this.layerMoved.raiseEvent(e,this._layers.length-1,t))},c.prototype.lowerToBottom=function(e){var t=d(this._layers,e);0!==t&&(this._layers.splice(t,1),this._layers.splice(0,0,e),this._update(),this.layerMoved.raiseEvent(e,0,t))};var p=new s;return c.prototype.pickImageryLayerFeatures=function(e,r){var i=r.globe.pick(e,r);if(t(i)){for(var n,o=r.globe.ellipsoid.cartesianToCartographic(i),u=r.globe._surface._tilesToRender,c=0;!t(n)&&c<u.length;++c){var d=u[c];s.contains(d.rectangle,o)&&(n=d)}if(t(n)){for(var h=n.data.imagery,f=[],m=[],g=h.length-1;g>=0;--g){var _=h[g],v=_.readyImagery;if(t(v)){var y=v.imageryLayer.imageryProvider;if(t(y.pickFeatures)&&s.contains(v.rectangle,o)){var C=p;if(C.west=a.lerp(n.rectangle.west,n.rectangle.east,_.textureCoordinateRectangle.x-1/1024),C.east=a.lerp(n.rectangle.west,n.rectangle.east,_.textureCoordinateRectangle.z+1/1024),C.south=a.lerp(n.rectangle.south,n.rectangle.north,_.textureCoordinateRectangle.y-1/1024),C.north=a.lerp(n.rectangle.south,n.rectangle.north,_.textureCoordinateRectangle.w+1/1024),s.contains(C,o)){var b=y.pickFeatures(v.x,v.y,v.level,o.longitude,o.latitude);t(b)&&(f.push(b),m.push(v.imageryLayer))}}}}if(0!==f.length)return l.all(f,function(e){for(var r=[],i=0;i<e.length;++i){var n=e[i],a=m[i];if(t(n)&&n.length>0)for(var s=0;s<n.length;++s){var l=n[s];l.imageryLayer=a,t(l.position)||(l.position=o),r.push(l)}}return r})}}},c.prototype.queueReprojectionCommands=function(e){for(var t=this._layers,r=0,i=t.length;r<i;++r)t[r].queueReprojectionCommands(e)},c.prototype.cancelReprojections=function(){for(var e=this._layers,t=0,r=e.length;t<r;++t)e[t].cancelReprojections()},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return this.removeAll(!0),i(this)},c.prototype._update=function(){var e,r,i,n,o=!0,a=this._layers;for(i=0,n=a.length;i<n;++i)r=a[i],r._layerIndex=i,r.show?(r._isBaseLayer=o,o=!1):r._isBaseLayer=!1,r.show!==r._show&&(t(r._show)&&(t(e)||(e=[]),e.push(r)),r._show=r.show);if(t(e))for(i=0,n=e.length;i<n;++i)r=e[i],this.layerShownOrHidden.raiseEvent(r,r._layerIndex,r.show)},c}),define("Scene/QuadtreeOccluders",["../Core/Cartesian3","../Core/defineProperties","../Core/EllipsoidalOccluder"],function(e,t,r){"use strict";function i(t){this._ellipsoid=new r(t.ellipsoid,e.ZERO)}return t(i.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),i}),define("Scene/QuadtreeTile",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Rectangle","./QuadtreeTileLoadState"],function(e,t,r,i,n){"use strict";function o(e){this._tilingScheme=e.tilingScheme,this._x=e.x,this._y=e.y,this._level=e.level,this._parent=e.parent,this._rectangle=this._tilingScheme.tileXYToRectangle(this._x,this._y,this._level),this._southwestChild=void 0,this._southeastChild=void 0,this._northwestChild=void 0,this._northeastChild=void 0,this._replacementPrevious=void 0,this._replacementNext=void 0,this._distance=0,this._priorityFunction=void 0,this._customData=[],this._frameUpdated=void 0,this._frameRendered=void 0,this._loadedCallbacks=[],this.state=n.START,this.renderable=!1,this.upsampledFromParent=!1,this.data=void 0}function a(t){e(t)&&t.freeResources()}return o.createLevelZeroTiles=function(e){for(var t=e.getNumberOfXTilesAtLevel(0),r=e.getNumberOfYTilesAtLevel(0),i=new Array(t*r),n=0,a=0;a<r;++a)for(var s=0;s<t;++s)i[n++]=new o({tilingScheme:e,x:s,y:a,level:0});return i},o.prototype._updateCustomData=function(t,r,n){var o,a,s,l=this.customData;if(e(r)&&e(n)){for(l=l.filter(function(e){return-1===n.indexOf(e)}),this._customData=l,s=this._rectangle,o=0;o<r.length;++o)a=r[o],i.contains(s,a.positionCartographic)&&l.push(a);this._frameUpdated=t}else{var u=this._parent;if(e(u)&&this._frameUpdated!==u._frameUpdated){l.length=0,s=this._rectangle;var c=u.customData;for(o=0;o<c.length;++o)a=c[o],i.contains(s,a.positionCartographic)&&l.push(a);this._frameUpdated=u._frameUpdated}}},t(o.prototype,{tilingScheme:{get:function(){return this._tilingScheme}},x:{get:function(){return this._x}},y:{get:function(){return this._y}},level:{get:function(){return this._level}},parent:{get:function(){return this._parent}},rectangle:{get:function(){return this._rectangle}},children:{get:function(){return[this.northwestChild,this.northeastChild,this.southwestChild,this.southeastChild]}},southwestChild:{get:function(){return e(this._southwestChild)||(this._southwestChild=new o({tilingScheme:this.tilingScheme,x:2*this.x,y:2*this.y+1,level:this.level+1,parent:this})),this._southwestChild}},southeastChild:{get:function(){return e(this._southeastChild)||(this._southeastChild=new o({tilingScheme:this.tilingScheme,x:2*this.x+1,y:2*this.y+1,level:this.level+1,parent:this})),this._southeastChild}},northwestChild:{get:function(){return e(this._northwestChild)||(this._northwestChild=new o({tilingScheme:this.tilingScheme,x:2*this.x,y:2*this.y,level:this.level+1,parent:this})),this._northwestChild}},northeastChild:{get:function(){return e(this._northeastChild)||(this._northeastChild=new o({tilingScheme:this.tilingScheme,x:2*this.x+1,y:2*this.y,level:this.level+1,parent:this})),this._northeastChild}},customData:{get:function(){return this._customData}},needsLoading:{get:function(){return this.state<n.DONE}},eligibleForUnloading:{get:function(){var t=!0;return e(this.data)&&(t=this.data.eligibleForUnloading,e(t)||(t=!0)),t}}}),o.prototype.freeResources=function(){this.state=n.START,this.renderable=!1,this.upsampledFromParent=!1,e(this.data)&&e(this.data.freeResources)&&this.data.freeResources(),a(this._southwestChild),this._southwestChild=void 0,a(this._southeastChild),this._southeastChild=void 0,a(this._northwestChild),this._northwestChild=void 0,a(this._northeastChild),this._northeastChild=void 0},o}),define("Scene/TileReplacementQueue",["../Core/defined"],function(e){"use strict";function t(){this.head=void 0,this.tail=void 0,this.count=0,this._lastBeforeStartOfFrame=void 0}function r(e,t){var r=t.replacementPrevious,i=t.replacementNext;t===e._lastBeforeStartOfFrame&&(e._lastBeforeStartOfFrame=i),t===e.head?e.head=i:r.replacementNext=i,t===e.tail?e.tail=r:i.replacementPrevious=r,t.replacementPrevious=void 0,t.replacementNext=void 0,--e.count}return t.prototype.markStartOfRenderFrame=function(){this._lastBeforeStartOfFrame=this.head},t.prototype.trimTiles=function(t){for(var i=this.tail,n=!0;n&&e(this._lastBeforeStartOfFrame)&&this.count>t&&e(i);){n=i!==this._lastBeforeStartOfFrame;var o=i.replacementPrevious;i.eligibleForUnloading&&(i.freeResources(),r(this,i)),i=o}},t.prototype.markTileRendered=function(t){var i=this.head;return i===t?void(t===this._lastBeforeStartOfFrame&&(this._lastBeforeStartOfFrame=t.replacementNext)):(++this.count,e(i)?((e(t.replacementPrevious)||e(t.replacementNext))&&r(this,t),t.replacementPrevious=void 0,t.replacementNext=i,i.replacementPrevious=t,void(this.head=t)):(t.replacementPrevious=void 0,t.replacementNext=void 0,this.head=t,void(this.tail=t)))},t}),define("Scene/QuadtreePrimitive",["../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/getTimestamp","../Core/Math","../Core/OrthographicFrustum","../Core/Ray","../Core/Rectangle","../Core/Visibility","./QuadtreeOccluders","./QuadtreeTile","./QuadtreeTileLoadState","./SceneMode","./TileReplacementQueue"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(e){this._tileProvider=e.tileProvider,this._tileProvider.quadtree=this,this._debug={enableDebugOutput:!1,maxDepth:0,tilesVisited:0,tilesCulled:0,tilesRendered:0,tilesWaitingForChildren:0,lastMaxDepth:-1,lastTilesVisited:-1,lastTilesCulled:-1,lastTilesRendered:-1,lastTilesWaitingForChildren:-1,suspendLodUpdate:!1};var t=this._tileProvider.tilingScheme,i=t.ellipsoid;this._tilesToRender=[],this._tileLoadQueueHigh=[],this._tileLoadQueueMedium=[],this._tileLoadQueueLow=[],this._tileReplacementQueue=new _,this._levelZeroTiles=void 0,this._loadQueueTimeSlice=5,this._addHeightCallbacks=[],this._removeHeightCallbacks=[],this._tileToUpdateHeights=[],this._lastTileIndex=0,this._updateHeightsTimeSlice=2,this.maximumScreenSpaceError=r(e.maximumScreenSpaceError,2),this.tileCacheSize=r(e.tileCacheSize,100),this._occluders=new p({ellipsoid:i}),this._tileLoadProgressEvent=new a,this._lastTileLoadQueueLength=0}function y(e,t){var r=d.center(e.rectangle,k),i=r.longitude-L.longitude,n=r.latitude-L.latitude;r=d.center(t.rectangle,k);var o=r.longitude-L.longitude,a=r.latitude-L.latitude;return i*i+n*n-(o*o+a*a)}function C(e,t){var r=e._debug;if(!r.suspendLodUpdate){var n,o;if(e._tilesToRender.length=0,!i(e._levelZeroTiles)){if(!e._tileProvider.ready)return;var a=e._tileProvider.tilingScheme;e._levelZeroTiles=f.createLevelZeroTiles(a)}e._occluders.ellipsoid.cameraPosition=t.camera.positionWC;var s,l=e._levelZeroTiles,u=e._tileProvider,c=l.length>1?e._occluders:void 0;L=t.camera.positionCartographic,l.sort(y);var d=e._addHeightCallbacks,p=e._removeHeightCallbacks,m=t.frameNumber;if(d.length>0||p.length>0){for(n=0,o=l.length;n<o;++n)s=l[n],s._updateCustomData(m,d,p);d.length=0,p.length=0}for(n=0,o=l.length;n<o;++n)s=l[n],e._tileReplacementQueue.markTileRendered(s),s.renderable?u.computeTileVisibility(s,t,c)!==h.NONE?S(e,t,s):(s.needsLoading&&e._tileLoadQueueLow.push(s),++r.tilesCulled):(s.needsLoading&&e._tileLoadQueueHigh.push(s),++r.tilesWaitingForChildren);t.afterRender.push(b(e))}}function b(e){return function(){x(e)}}function S(e,t,r){var i=e._debug;if(++i.tilesVisited,e._tileReplacementQueue.markTileRendered(r),r._updateCustomData(t.frameNumber),r.level>i.maxDepth&&(i.maxDepth=r.level),P(e,t,r)<e.maximumScreenSpaceError)return r.needsLoading&&e._tileLoadQueueMedium.push(r),void I(e,r);var n=r.southwestChild,o=r.southeastChild,a=r.northwestChild,s=r.northeastChild,l=n.renderable&&o.renderable&&a.renderable&&s.renderable,u=n.upsampledFromParent&&o.upsampledFromParent&&a.upsampledFromParent&&s.upsampledFromParent;l?u?(I(e,r),w(e,t.camera.positionCartographic,n,o,a,s),r.needsLoading&&e._tileLoadQueueMedium.push(r)):(A(e,n,o,a,s,t),r.needsLoading&&e._tileLoadQueueLow.push(r)):(w(e,t.camera.positionCartographic,n,o,a,s),I(e,r),r.needsLoading&&e._tileLoadQueueLow.push(r))}function w(e,t,r,i,n,o){t.longitude<r.east?t.latitude<r.north?(T(e,r),T(e,i),T(e,n),T(e,o)):(T(e,n),T(e,r),T(e,o),T(e,i)):t.latitude<r.north?(T(e,i),T(e,r),T(e,o),T(e,n)):(T(e,o),T(e,n),T(e,i),T(e,r))}function T(e,t){e._tileReplacementQueue.markTileRendered(t),t.needsLoading&&(t.renderable?e._tileLoadQueueLow.push(t):e._tileLoadQueueHigh.push(t))}function A(e,t,r,i,n,o){var a=o.camera.positionCartographic,s=e._tileProvider,l=e._occluders;a.longitude<t.rectangle.east?a.latitude<t.rectangle.north?(E(e,t,s,o,l),E(e,r,s,o,l),E(e,i,s,o,l),E(e,n,s,o,l)):(E(e,i,s,o,l),E(e,t,s,o,l),E(e,n,s,o,l),E(e,r,s,o,l)):a.latitude<t.rectangle.north?(E(e,r,s,o,l),E(e,t,s,o,l),E(e,n,s,o,l),E(e,i,s,o,l)):(E(e,n,s,o,l),E(e,i,s,o,l),E(e,r,s,o,l),E(e,t,s,o,l))}function E(e,t,r,i,n){r.computeTileVisibility(t,i,n)!==h.NONE?S(e,i,t):(++e._debug.tilesCulled,e._tileReplacementQueue.markTileRendered(t))}function x(e){var t=e._tileLoadQueueHigh.length+e._tileLoadQueueMedium.length+e._tileLoadQueueLow.length;t!==e._lastTileLoadQueueLength&&(e._tileLoadProgressEvent.raiseEvent(t),e._lastTileLoadQueueLength=t)}function P(e,t,r){if(t.mode===g.SCENE2D||t.camera.frustum instanceof u)return D(e,t,r);var i=e._tileProvider.getLevelMaximumGeometricError(r.level),n=r._distance,o=t.context.drawingBufferHeight,a=t.camera.frustum.sseDenominator,s=i*o/(n*a);return t.fog.enabled&&(s-=l.fog(n,t.fog.density)*t.fog.sse),s}function D(e,t,r){var n=t.camera,o=n.frustum;i(o._offCenterFrustum)&&(o=o._offCenterFrustum);var a=t.context,s=a.drawingBufferWidth,u=a.drawingBufferHeight,c=e._tileProvider.getLevelMaximumGeometricError(r.level),d=Math.max(o.top-o.bottom,o.right-o.left)/Math.max(s,u),h=c/d;return t.fog.enabled&&t.mode!==g.SCENE2D&&(h-=l.fog(r._distance,t.fog.density)*t.fog.sse),h}function I(e,t){e._tilesToRender.push(t),++e._debug.tilesRendered}function O(e,t){var r=e._tileLoadQueueHigh,i=e._tileLoadQueueMedium,n=e._tileLoadQueueLow,o=e._tileProvider;if(0!==r.length||0!==i.length||0!==n.length){e._tileReplacementQueue.trimTiles(e.tileCacheSize);var a=s()+e._loadQueueTimeSlice;M(e,t,o,a,r),M(e,t,o,a,i),M(e,t,o,a,n)}}function M(e,t,r,i,n){for(var o=0,a=n.length;o<a&&s()<i;++o){var l=n[o];e._tileReplacementQueue.markTileRendered(l),r.loadTile(t,l)}}function R(n,o){for(var a=n._tileToUpdateHeights,l=n._tileProvider.terrainProvider,u=s(),c=n._updateHeightsTimeSlice,h=u+c,p=o.mode,f=o.mapProjection,m=f.ellipsoid;a.length>0;){var _,v=a[0],y=v.customData,C=y.length,b=!1;for(_=n._lastTileIndex;_<C;++_){var S=y[_];if(v.level>S.level){if(i(S.positionOnEllipsoidSurface)||(S.positionOnEllipsoidSurface=e.fromRadians(S.positionCartographic.longitude,S.positionCartographic.latitude,0,m)),p===g.SCENE3D){var w=m.geodeticSurfaceNormal(S.positionOnEllipsoidSurface,F.direction),T=m.getSurfaceNormalIntersectionWithZAxis(S.positionOnEllipsoidSurface,11500,F.origin);if(!i(T)){var A=Math.min(r(v.data.minimumHeight,0),-11500),E=e.multiplyByScalar(w,Math.abs(A)+1,U);e.subtract(S.positionOnEllipsoidSurface,E,F.origin)}}else t.clone(S.positionCartographic,B),B.height=-11500,f.project(B,U),e.fromElements(U.z,U.x,U.y,U),e.clone(U,F.origin),e.clone(e.UNIT_X,F.direction);var x=v.data.pick(F,p,f,!1,U);i(x)&&S.callback(x),S.level=v.level}else if(v.level===S.level){for(var P,D=v.children,I=D.length,O=0;O<I&&(P=D[O],!d.contains(P.rectangle,S.positionCartographic));++O);var M=l.getTileDataAvailable(P.x,P.y,P.level),R=v.parent;(i(M)&&!M||i(R)&&i(R.data)&&i(R.data.terrainData)&&!R.data.terrainData.isChildAvailable(R.x,R.y,P.x,P.y))&&S.removeFunc()}if(s()>=h){b=!0;break}}if(b){n._lastTileIndex=_;break}n._lastTileIndex=0,a.shift()}}function N(e,t){for(var r=e._tileProvider,i=e._tilesToRender,n=e._tileToUpdateHeights,o=0,a=i.length;o<a;++o){var s=i[o];r.showTileThisFrame(s,t),s._frameRendered!==t.frameNumber-1&&n.push(s),s._frameRendered=t.frameNumber}}n(v.prototype,{tileProvider:{get:function(){return this._tileProvider}},tileLoadProgressEvent:{get:function(){return this._tileLoadProgressEvent}}}),v.prototype.invalidateAllTiles=function(){var e=this._tileReplacementQueue;e.head=void 0,e.tail=void 0,e.count=0;var t=this._levelZeroTiles;if(i(t))for(var r=0;r<t.length;++r){for(var n=t[r],o=n.customData,a=o.length,s=0;s<a;++s){var l=o[s];l.level=0,this._addHeightCallbacks.push(l)}t[r].freeResources()}this._levelZeroTiles=void 0,this._tileProvider.cancelReprojections()},v.prototype.forEachLoadedTile=function(e){for(var t=this._tileReplacementQueue.head;i(t);)t.state!==m.START&&e(t),t=t.replacementNext},v.prototype.forEachRenderedTile=function(e){for(var t=this._tilesToRender,r=0,i=t.length;r<i;++r)e(t[r])},v.prototype.updateHeight=function(e,t){var r=this,i={positionOnEllipsoidSurface:void 0,positionCartographic:e,level:-1,callback:t};return i.removeFunc=function(){for(var e=r._addHeightCallbacks,t=e.length,n=0;n<t;++n)if(e[n]===i){e.splice(n,1);break}r._removeHeightCallbacks.push(i)},r._addHeightCallbacks.push(i),i.removeFunc},v.prototype.beginFrame=function(e){if(e.passes.render){this._tileProvider.initialize(e);var t=this._debug;t.suspendLodUpdate||(t.maxDepth=0,t.tilesVisited=0,t.tilesCulled=0,t.tilesRendered=0,t.tilesWaitingForChildren=0,this._tileLoadQueueHigh.length=0,this._tileLoadQueueMedium.length=0,this._tileLoadQueueLow.length=0,this._tileReplacementQueue.markStartOfRenderFrame())}},v.prototype.update=function(e){var t=e.passes;t.render&&(this._tileProvider.beginUpdate(e),C(this,e),N(this,e),this._tileProvider.endUpdate(e)),t.pick&&this._tilesToRender.length>0&&this._tileProvider.updateForPick(e)},v.prototype.endFrame=function(e){if(e.passes.render&&e.mode!==g.MORPHING){O(this,e),R(this,e);var t=this._debug;t.suspendLodUpdate||t.enableDebugOutput&&(t.tilesVisited===t.lastTilesVisited&&t.tilesRendered===t.lastTilesRendered&&t.tilesCulled===t.lastTilesCulled&&t.maxDepth===t.lastMaxDepth&&t.tilesWaitingForChildren===t.lastTilesWaitingForChildren||(console.log("Visited "+t.tilesVisited+", Rendered: "+t.tilesRendered+", Culled: "+t.tilesCulled+", Max Depth: "+t.maxDepth+", Waiting for children: "+t.tilesWaitingForChildren),t.lastTilesVisited=t.tilesVisited,t.lastTilesRendered=t.tilesRendered,t.lastTilesCulled=t.tilesCulled,t.lastMaxDepth=t.maxDepth,t.lastTilesWaitingForChildren=t.tilesWaitingForChildren))}},v.prototype.isDestroyed=function(){return!1},v.prototype.destroy=function(){this._tileProvider=this._tileProvider&&this._tileProvider.destroy()};var L,k=new t,F=new c,B=new t,U=new e;return v}),define("Scene/Globe",["../Core/BoundingSphere","../Core/buildModuleUrl","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/EllipsoidTerrainProvider","../Core/Event","../Core/IntersectionTests","../Core/loadImage","../Core/Ray","../Core/Rectangle","../Renderer/ShaderSource","../Renderer/Texture","../Shaders/GlobeFS","../Shaders/GlobeVS","../Shaders/GroundAtmosphere","../ThirdParty/when","./GlobeSurfaceShaderSet","./GlobeSurfaceTileProvider","./ImageryLayerCollection","./Material","./QuadtreePrimitive","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P){"use strict";function D(e){e=n(e,u.WGS84);var r=new c({ellipsoid:e}),i=new T;this._ellipsoid=e,this._imageryLayerCollection=i,this._surfaceShaderSet=new S,this._material=void 0,this._surface=new E({tileProvider:new w({terrainProvider:r,imageryLayers:i,surfaceShaderSet:this._surfaceShaderSet})}),this._terrainProvider=r,this._terrainProviderChanged=new d,I(this),this.show=!0,this.oceanNormalMapUrl=t("Assets/Textures/waterNormalsSmall.jpg"),this._oceanNormalMapUrl=void 0,this.maximumScreenSpaceError=2,this.tileCacheSize=100,this.enableLighting=!1,this.lightingFadeOutDistance=65e5,this.lightingFadeInDistance=9e6,this.showWaterEffect=!0,this.depthTestAgainstTerrain=!1,this.shadows=P.RECEIVE_ONLY,this._oceanNormalMap=void 0,this._zoomedOutOceanSpecularIntensity=.5}function I(e){var t=[],r=o(e._material)&&(e._material.shaderSource.match(/slope/)||e._material.shaderSource.match("normalEC")),i=[];!o(e._material)||r&&!e._terrainProvider.requestVertexNormals?e._surface._tileProvider.uniformMap=void 0:(i.push(e._material.shaderSource),t.push("APPLY_MATERIAL"),e._surface._tileProvider.uniformMap=e._material._uniforms),i.push(v),e._surfaceShaderSet.baseVertexShaderSource=new g({sources:[C,y],defines:t}),e._surfaceShaderSet.baseFragmentShaderSource=new g({sources:i,defines:t}),e._surfaceShaderSet.material=e._material}function O(t){return function(r,i){return e.distanceSquaredTo(r.pickBoundingSphere,t)-e.distanceSquaredTo(i.pickBoundingSphere,t)}}function M(e,t){return m.contains(e.rectangle,t)?e:void 0}a(D.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},imageryLayers:{get:function(){return this._imageryLayerCollection}},baseColor:{get:function(){return this._surface.tileProvider.baseColor},set:function(e){this._surface.tileProvider.baseColor=e}},clippingPlanes:{get:function(){return this._surface.tileProvider.clippingPlanes},set:function(e){this._surface.tileProvider.clippingPlanes=e}},terrainProvider:{get:function(){return this._terrainProvider},set:function(e){e!==this._terrainProvider&&(this._terrainProvider=e,this._terrainProviderChanged.raiseEvent(e),o(this._material)&&I(this))}},terrainProviderChanged:{get:function(){return this._terrainProviderChanged}},tileLoadProgressEvent:{get:function(){return this._surface.tileLoadProgressEvent}},material:{get:function(){return this._material},set:function(e){this._material!==e&&(this._material=e,I(this))}}});var R=[],N={start:0,stop:0};D.prototype.pick=function(t,i,n){var a=i.mode,s=i.mapProjection,l=R;l.length=0;var u,c,d=this._surface._tilesToRender,p=d.length;for(c=0;c<p;++c){u=d[c];var f=u.data;if(o(f)){var m=f.pickBoundingSphere;a!==x.SCENE3D?(e.fromRectangleWithHeights2D(u.rectangle,s,f.minimumHeight,f.maximumHeight,m),r.fromElements(m.center.z,m.center.x,m.center.y,m.center)):e.clone(f.boundingSphere3D,m);var g=h.raySphere(t,m,N);o(g)&&l.push(f)}}l.sort(O(t.origin));var _;for(p=l.length,c=0;c<p&&(_=l[c].pick(t,i.mode,i.mapProjection,!0,n),!o(_));++c);return _};var L=new r,k=new r,F=new i,B=new f;return D.prototype.getHeight=function(e){var t=this._surface._levelZeroTiles;if(o(t)){var i,a,s=t.length;for(a=0;a<s&&(i=t[a],!m.contains(i.rectangle,e));++a);if(o(i)&&m.contains(i.rectangle,e)){for(;i.renderable;)i=M(i.southwestChild,e)||M(i.southeastChild,e)||M(i.northwestChild,e)||i.northeastChild;for(;o(i)&&(!o(i.data)||!o(i.data.pickTerrain));)i=i.parent;if(o(i)){var l=this._surface._tileProvider.tilingScheme.ellipsoid,u=r.fromRadians(e.longitude,e.latitude,0,l,L),c=B,d=l.geodeticSurfaceNormal(u,c.direction),h=l.getSurfaceNormalIntersectionWithZAxis(u,11500,c.origin);if(!o(h)){var p=Math.min(n(i.data.minimumHeight,0),-11500),f=r.multiplyByScalar(d,Math.abs(p)+1,k);r.subtract(u,f,c.origin)}var g=i.data.pick(c,void 0,void 0,!1,k);if(o(g))return l.cartesianToCartographic(g,F).height}}}},D.prototype.beginFrame=function(e){if(this.show){var t=this._surface,r=t.tileProvider,i=this.terrainProvider,n=this.showWaterEffect&&i.ready&&i.hasWaterMask;if(n&&this.oceanNormalMapUrl!==this._oceanNormalMapUrl){var a=this.oceanNormalMapUrl;if(this._oceanNormalMapUrl=a,o(a)){var s=this;b(p(a),function(t){a===s.oceanNormalMapUrl&&(s._oceanNormalMap=s._oceanNormalMap&&s._oceanNormalMap.destroy(),s._oceanNormalMap=new _({context:e.context,source:t}))})}else this._oceanNormalMap=this._oceanNormalMap&&this._oceanNormalMap.destroy()}var l=e.mode;e.passes.render&&(l===x.SCENE3D?this._zoomedOutOceanSpecularIntensity=.5:this._zoomedOutOceanSpecularIntensity=0,t.maximumScreenSpaceError=this.maximumScreenSpaceError,t.tileCacheSize=this.tileCacheSize,r.terrainProvider=this.terrainProvider,r.lightingFadeOutDistance=this.lightingFadeOutDistance,r.lightingFadeInDistance=this.lightingFadeInDistance,r.zoomedOutOceanSpecularIntensity=this._zoomedOutOceanSpecularIntensity,r.hasWaterMask=n,r.oceanNormalMap=this._oceanNormalMap,r.enableLighting=this.enableLighting,r.shadows=this.shadows,t.beginFrame(e))}},D.prototype.update=function(e){if(this.show){o(this._material)&&this._material.update(e.context);var t=this._surface,r=e.passes;r.render&&t.update(e),r.pick&&t.update(e)}},D.prototype.endFrame=function(e){this.show&&e.passes.render&&this._surface.endFrame(e)},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){return this._surfaceShaderSet=this._surfaceShaderSet&&this._surfaceShaderSet.destroy(),this._surface=this._surface&&this._surface.destroy(),this._oceanNormalMap=this._oceanNormalMap&&this._oceanNormalMap.destroy(),s(this)},D}),define("Shaders/PostProcessFilters/PassThrough",[],function(){"use strict";return"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_FragColor = texture2D(u_texture, v_textureCoordinates);\n}\n"}),define("Scene/GlobeDepth",["../Core/BoundingRectangle","../Core/Color","../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Texture","../Shaders/PostProcessFilters/PassThrough"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(){this._colorTexture=void 0,this._depthStencilTexture=void 0,this._globeDepthTexture=void 0,this.framebuffer=void 0,this._copyDepthFramebuffer=void 0,this._clearColorCommand=void 0,this._copyColorCommand=void 0,this._copyDepthCommand=void 0,this._viewport=new e,this._rs=void 0,this._useScissorTest=!1,this._scissorRectangle=void 0,this._debugGlobeDepthViewportCommand=void 0}function h(e,t,i){if(!r(e._debugGlobeDepthViewportCommand)){e._debugGlobeDepthViewportCommand=t.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n float n_range = czm_depthRange.near;\n float f_range = czm_depthRange.far;\n float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n}\n",{uniformMap:{u_texture:function(){return e._globeDepthTexture}},owner:e})}e._debugGlobeDepthViewportCommand.execute(t,i)}function p(e){e._colorTexture=e._colorTexture&&!e._colorTexture.isDestroyed()&&e._colorTexture.destroy(),e._depthStencilTexture=e._depthStencilTexture&&!e._depthStencilTexture.isDestroyed()&&e._depthStencilTexture.destroy(),e._globeDepthTexture=e._globeDepthTexture&&!e._globeDepthTexture.isDestroyed()&&e._globeDepthTexture.destroy()}function f(e){e.framebuffer=e.framebuffer&&!e.framebuffer.isDestroyed()&&e.framebuffer.destroy(), -e._copyDepthFramebuffer=e._copyDepthFramebuffer&&!e._copyDepthFramebuffer.isDestroyed()&&e._copyDepthFramebuffer.destroy()}function m(e,t,r,i){e._colorTexture=new u({context:t,width:r,height:i,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE}),e._depthStencilTexture=new u({context:t,width:r,height:i,pixelFormat:n.DEPTH_STENCIL,pixelDatatype:s.UNSIGNED_INT_24_8}),e._globeDepthTexture=new u({context:t,width:r,height:i,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE})}function g(e,t){e.framebuffer=new a({context:t,colorTextures:[e._colorTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._copyDepthFramebuffer=new a({context:t,colorTextures:[e._globeDepthTexture],destroyAttachments:!1})}function _(e,t,i,n){var o=e._colorTexture,a=!r(o)||o.width!==i||o.height!==n;r(e.framebuffer)&&!a||(p(e),f(e),m(e,t,i,n),g(e,t))}function v(i,n,a,s,u){i._viewport.width=a,i._viewport.height=s;var d=!e.equals(i._viewport,u.viewport),h=d!==i._useScissorTest;if(i._useScissorTest=d,e.equals(i._scissorRectangle,u.viewport)||(i._scissorRectangle=e.clone(u.viewport,i._scissorRectangle),h=!0),r(i._rs)&&e.equals(i._viewport,i._rs.viewport)&&!h||(i._rs=l.fromCache({viewport:i._viewport,scissorTest:{enabled:i._useScissorTest,rectangle:i._scissorRectangle}})),!r(i._copyDepthCommand)){i._copyDepthCommand=n.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n}\n",{uniformMap:{u_texture:function(){return i._depthStencilTexture}},owner:i})}i._copyDepthCommand.framebuffer=i._copyDepthFramebuffer,r(i._copyColorCommand)||(i._copyColorCommand=n.createViewportQuadCommand(c,{uniformMap:{u_texture:function(){return i._colorTexture}},owner:i})),i._copyDepthCommand.renderState=i._rs,i._copyColorCommand.renderState=i._rs,r(i._clearColorCommand)||(i._clearColorCommand=new o({color:new t(0,0,0,0),stencil:0,owner:i})),i._clearColorCommand.framebuffer=i.framebuffer}return d.prototype.executeDebugGlobeDepth=function(e,t){h(this,e,t)},d.prototype.update=function(e,t){var r=e.drawingBufferWidth,i=e.drawingBufferHeight;_(this,e,r,i),v(this,e,r,i,t),e.uniformState.globeDepthTexture=void 0},d.prototype.executeCopyDepth=function(e,t){r(this._copyDepthCommand)&&(this._copyDepthCommand.execute(e,t),e.uniformState.globeDepthTexture=this._globeDepthTexture)},d.prototype.executeCopyColor=function(e,t){r(this._copyColorCommand)&&this._copyColorCommand.execute(e,t)},d.prototype.clear=function(e,i,n){var o=this._clearColorCommand;r(o)&&(t.clone(n,o.color),o.execute(e,i))},d.prototype.isDestroyed=function(){return!1},d.prototype.destroy=function(){p(this),f(this),r(this._copyColorCommand)&&(this._copyColorCommand.shaderProgram=this._copyColorCommand.shaderProgram.destroy()),r(this._copyDepthCommand)&&(this._copyDepthCommand.shaderProgram=this._copyDepthCommand.shaderProgram.destroy());var e=this._debugGlobeDepthViewportCommand;return r(e)&&(e.shaderProgram=e.shaderProgram.destroy()),i(this)},d}),define("Scene/GoogleEarthEnterpriseImageryProvider",["../Core/Credit","../Core/decodeGoogleEarthEnterpriseData","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/GoogleEarthEnterpriseMetadata","../Core/loadArrayBuffer","../Core/loadImageFromTypedArray","../Core/Math","../Core/Rectangle","../Core/Request","../Core/RuntimeError","../Core/TileProviderError","../ThirdParty/protobuf-minimal","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(){this._image=new Image}function y(t){t=r(t,r.EMPTY_OBJECT);var n;n=i(t.metadata)?this._metadata=t.metadata:this._metadata=new l({url:t.url,proxy:t.proxy}),this._tileDiscardPolicy=t.tileDiscardPolicy,this._proxy=r(t.proxy,this._metadata.proxy),this._tilingScheme=new s({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,rectangle:new h(-d.PI,-d.PI,d.PI,d.PI),ellipsoid:t.ellipsoid});var o=t.credit;"string"==typeof o&&(o=new e({text:o})),this._credit=o,this._tileWidth=256,this._tileHeight=256,this._maximumLevel=23,i(this._tileDiscardPolicy)||(this._tileDiscardPolicy=new v),this._errorEvent=new a,this._ready=!1;var u,c=this;this._readyPromise=n.readyPromise.then(function(e){if(!n.imageryPresent){var t=new f("The server "+n.url+" doesn't have imagery");return u=m.handleError(u,c,c._errorEvent,t.message,void 0,void 0,void 0,t),_.reject(t)}return m.handleSuccess(u),c._ready=e,e}).otherwise(function(e){return u=m.handleError(u,c,c._errorEvent,e.message,void 0,void 0,void 0,e),_.reject(e)})}function C(e,t,r,n,o){var a=l.tileXYToQuadKey(r,n,o),s=t.imageryVersion;s=i(s)&&s>0?s:1;var u=e.url+"flatfile?f1-0"+a+"-i."+s.toString(),c=e._proxy;return i(c)&&(u=c.getURL(u)),u}function b(e){var t="JFIF";if(e[6]===t.charCodeAt(0)&&e[7]===t.charCodeAt(1)&&e[8]===t.charCodeAt(2)&&e[9]===t.charCodeAt(3))return"image/jpeg";var r="PNG";return e[1]===r.charCodeAt(0)&&e[2]===r.charCodeAt(1)&&e[3]===r.charCodeAt(2)?"image/png":void 0}function S(e){for(var t=g.Reader.create(e),r=t.len,n={};t.pos<r;){var o=t.uint32();switch(o>>>3){case 1:n.imageType=t.uint32();break;case 2:n.imageData=t.bytes();break;case 3:n.alphaType=t.uint32();break;case 4:n.imageAlpha=t.bytes();break;case 5:var a=n.copyrightIds;if(i(a)||(a=n.copyrightIds=[]),2==(7&o))for(var s=t.uint32()+t.pos;t.pos<s;)a.push(t.uint32());else a.push(t.uint32());break;default:t.skipType(7&o)}}var l=n.imageType;if(i(l))switch(l){case 0:n.imageType="image/jpeg";break;case 4:n.imageType="image/png";break;default:throw new f("GoogleEarthEnterpriseImageryProvider: Unsupported image type.")}var u=n.alphaType;return i(u)&&0!==u&&(console.log("GoogleEarthEnterpriseImageryProvider: External alpha not supported."),delete n.alphaType,delete n.imageAlpha),n}return v.prototype.isReady=function(){return!0},v.prototype.shouldDiscardImage=function(e){return e===this._image},n(y.prototype,{url:{get:function(){return this._metadata.url}},proxy:{get:function(){return this._proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!1}}}),y.prototype.getTileCredits=function(e,t,r){var n=this._metadata,o=n.getTileInformation(e,t,r);if(i(o)){var a=n.providers[o.imageryProvider];if(i(a))return[a]}},y.prototype.requestImage=function(e,r,n,o){var a=this._tileDiscardPolicy._image,s=this._metadata,d=l.tileXYToQuadKey(e,r,n),h=s.getTileInformation(e,r,n);if(!i(h)){if(s.isValid(d)){var f=new p({throttle:o.throttle,throttleByServer:o.throttleByServer,type:o.type,priorityFunction:o.priorityFunction});return void s.populateSubtree(e,r,n,f)}return a}if(!h.hasImagery())return a;var m=C(this,h,e,r,n),g=u(m,void 0,o);return i(g)?g.then(function(e){t(s.key,e);var r,n=new Uint8Array(e),o=s.protoImagery;if(i(o)&&o||(r=b(n)),!i(r)&&(!i(o)||o)){var l=S(n);r=l.imageType,n=l.imageData}return i(r)&&i(n)?c(n,r):a}):void 0},y.prototype.pickFeatures=function(e,t,r,i,n){},y}),define("Scene/GoogleEarthEnterpriseMapsProvider",["../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/loadText","../Core/Rectangle","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorTilingScheme","../ThirdParty/when","./ImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(i){function n(e){var t;try{t=JSON.parse(e)}catch(r){t=JSON.parse(e.replace(/([\[\{,])[\n\r ]*([A-Za-z0-9]+)[\n\r ]*:/g,'$1"$2":'))}for(var n,o=0;o<t.layers.length;o++)if(t.layers[o].id===v._channel){n=t.layers[o];break}var s;if(!r(n))throw s="Could not find layer with channel (id) of "+v._channel+".",g=c.handleError(g,v,v._errorEvent,s,void 0,void 0,void 0,m),new u(s);if(!r(n.version))throw s="Could not find a version in channel (id) "+v._channel+".",g=c.handleError(g,v,v._errorEvent,s,void 0,void 0,void 0,m),new u(s);if(v._version=n.version,r(t.projection)&&"flat"===t.projection)v._tilingScheme=new a({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,rectangle:new l(-Math.PI,-Math.PI,Math.PI,Math.PI),ellipsoid:i.ellipsoid});else{if(r(t.projection)&&"mercator"!==t.projection)throw s="Unsupported projection "+t.projection+".",g=c.handleError(g,v,v._errorEvent,s,void 0,void 0,void 0,m),new u(s);v._tilingScheme=new d({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,ellipsoid:i.ellipsoid})}v._imageUrlTemplate=v._imageUrlTemplate.replace("{request}",v._requestType).replace("{channel}",v._channel).replace("{version}",v._version),v._ready=!0,v._readyPromise.resolve(!0),c.handleSuccess(g)}function p(e){var t="An error occurred while accessing "+_+".";g=c.handleError(g,v,v._errorEvent,t,void 0,void 0,void 0,m),v._readyPromise.reject(new u(t))}function m(){var e=r(v._proxy)?v._proxy.getURL(_):_,t=s(e);h(t,n,p)}i=t(i,{}),this._url=i.url,this._path=t(i.path,"/default_map"),this._tileDiscardPolicy=i.tileDiscardPolicy,this._proxy=i.proxy,this._channel=i.channel,this._requestType="ImageryMaps",this._credit=new e({text:"Google Imagery",imageUrl:f._logoData,link:"http://www.google.com/enterprise/mapsearth/products/earthenterprise.html"}),this.defaultGamma=1.9,this._tilingScheme=void 0,this._version=void 0,this._tileWidth=256,this._tileHeight=256,this._maximumLevel=i.maximumLevel,this._imageUrlTemplate=this._url+this._path+"/query?request={request}&channel={channel}&version={version}&x={x}&y={y}&z={zoom}",this._errorEvent=new o,this._ready=!1,this._readyPromise=h.defer();var g,_=this._url+this._path+"/query?request=Json&vars=geeServerDefs&is2d=t",v=this;m()}function m(e,t,i,n){var o=e._imageUrlTemplate;o=o.replace("{x}",t),o=o.replace("{y}",i),o=o.replace("{zoom}",n+1);var a=e._proxy;return r(a)&&(o=a.getURL(o)),o}return i(f.prototype,{url:{get:function(){return this._url}},path:{get:function(){return this._path}},proxy:{get:function(){return this._proxy}},channel:{get:function(){return this._channel}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},version:{get:function(){return this._version}},requestType:{get:function(){return this._requestType}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!0}}}),f.prototype.getTileCredits=function(e,t,r){},f.prototype.requestImage=function(e,t,r,i){var n=m(this,e,t,r);return p.loadImage(this,n,i)},f.prototype.pickFeatures=function(e,t,r,i,n){},f._logoData="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAAnCAYAAACmP2LfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAHdElNRQfcDB4TJDr1mp5kAAAAGnRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAB1zSURBVHhe7ZwHeFTFFsf/u+l9N70npOxuSAKEFFIhCSH0qhEQUHkgKCgWUFGBB6IoCAoo0ntooaRvEkIIBBBpoYSa3nvvfd+5u4sQUigPfMX8v2/Y3Tkzs3fv/d0z58zcgF69Ql1SY+MM1wQJem44ZeiJk8beEOqPwG6uC7ZqyElb9eo/JZEIkH2nRQkBIlNMauuPCS3uGN/kjkmNDghoskBAgzrZ2NLmf1+JwIKQpYsoxdmIV9+N07onCegzBPM9bOdmYKnazF6g/1N6UySPqSJzvCaaiLHtP8G/Phq+FRfgU5ogKWUXMLT6Mvzqr2BE40mMadqO8c3zMabBC6PqDDC8SlY60t9HByCLVTKu+ERmHr5TWI9wjVxEaOZivWo1pil8D1tZeWnLXv1l8iZ3PF2kjymiWRgvCoJv5U243IyAXcQq8A9Mg9W+4bDe6wv+kVGwCZkL+4Sf4ZR+BZ5VGQR3EkbWn8Hopm3wq54Lz2JD6ah/P21XGopQ9Qoc16jGSqVyTJWbQbUsibFXf42mihTwZpsvAtp3k0dOhFOSEH1+ngaDefrgjFCgFkxY8fCisCBvKgODzxRh9qslBFGfYmDGLbiV5mBwRRo8KtPhVBgPu8teMP7u73chD6kMRYRGBY5xqrFKqQwz5SdTbS/Qf5mmUYw8rf01CjHC4VP7AHZxO6E3qy9ZZCQNnio2rE/4o9/tkxiQUYp+KRXgx8XC5FsXcLz/hkCrDUU4pxLHuDVYpdwL9F+qqSJZKlPwenskfOoI5tN7YPCJGVme7wKYr5EBXzgYfW+mwTI0Gjrznaj2WW+I/y8dVPdDGLcKRzXrsEqlHO8oTKHaXqAZWe9hQXCi63NhHWYI3ilfWIW/YLjqL2JRiOFBJRz+LffhcPs09D+0J8vzn3zXdBnYnp8Mi6NboTWzH9X8fVc+DhDQodxqAroe36lU9AJNWr4cEAjNwI8OAC9cT1rbUfzwGeCfKiL7dGnNc+q1NiO80b4BY1oT4V6WDcsdc6j2xbyq4wMWrA9rQmeWFn36ey/jBaoPQ4hmLYI0G/AtAf22fC/QDols8ITrIYi/Bl6knbS2o3gRbxHQxQQ0k0S/gCa2v4OJovPwacqAQ1ICjL40klr+UrWoQbFBETo18jCpZsOoFODkvuCNJYoHW3QKXFEM7ETRcKfiQe8d6NVIFImXvg4skhY40mxnQYVRIIeA1qrHEc1GrFSpxFtP99AiFbDbNKDZpAzzGkVYVcvBuBJQEo/9/6C+dyjPitwLwak74D8V6Bfw0P5VShjXFoTR7TfhUZkL29M/wfATJan1lauWC3aDOgyaVDCuTgbf1bFkfmtkye1ogsK2asivLYfCglIoD8qCknI2NHuG4QSVGMgQyMbt0fioRYh9VYcRU7QX55uDcaHtFOJEsThMtmWtQgxsDodsWaC0c3ea3MzGBJEqxrfbYmzr6xjfPAeTmt5HQPO7eK1xDibUz8eY+k8xtHYJPCtXwvHOu7AXMrMTsF/TH8HajTis1YwVqpWY0TXQDKy1OpBr5EJA52Fukxx+bmKxtjWx2DuaWawNlZD5qhzyo9KhpHAbKpJO/6t65UCPbPHA2PYrGNacgkElabCJJDev/MpDhUKKnuq44LRoYEK1IiswkS1zYCfk5y+F0qjvoTwqBOof34dGeAnUL1ZCLboEnJ9zoe0QD/Nuj00UBVXRabzVLETM3S0ICfwA8yc7Y6C3ANYbZsA7aQ1W1xzEfZEQ6dT2BkG9pP4ouo7jGE1u42JS20QMrzkCr4xwuN4+AM+cYII3EaNar2J86zmMrP8DHulCON4NhU3YWuhOYy6SZENpH9cfx7WacFC7BSvUqjBDsRPQIiugURvazeqYVaqAw6dYrJ9WQy7gayj4nYDy3HtQOVQGpYRqKEWXQf2HdGha/AFdae9Xr4czz0ubISRA75ECbSut7agegO75OLxpahze8j5GtifBpzEDLiV30Dd2mNT6StWiCbVmLt5rUkBQCEt2zWzIMSA8HgrIBkLD+Sp0jhHISYXQ/KMYukfvQ3fQxq68XCTBHId/tMTg7LV1CFs4BszJ6hBarBgHlcRv8H7tbuSKQpFPYGe0BmND+nZ0npECaPKf0r4UIxsuoF/IMpitsAVnrA4s15uh3x8fwLXkLobUZGJIXTqcUzbDaJE5FAVq0t4S7dEcjqMEc6B2K5arVWN6Z6AbdOmm5mJelQKOHWSxF44Cy4CqxW0s6RwchCovFRohdGNfLgX3WiZ0N4aD++y7jfwYJUrAPCle/ZjKV+BFTSegrGAZIm3QjXhBytTWB3zhByzryMUU986jz16wD+96ijCNUIAgmkc3tS6G7GERjCbgR82B4OTbEESqIiCIcqsIYzoGGyrBEMSmgh8xBoIIAR2fAHZhj8Z9DOhl9FHeKkSDvn809fuc+iyCddRYaiOZBTvIt1YJfs0b4N+WDO+GHPLQN2Ab7S61vjJV60C9SRPvNSqzTpxlyQfS1dGUmjppK7gW16B/LhN6abnQu5cDwzO3YNhhqqK4WJY887sEdGzWFpxfOxmDpKZOOvgWFB8sx9L6nShvP4FyUQjKGg5gScpGKEqbUE7RxiGYv6QQ4zIG/r4D2m88sjEy/EIW/a6+TQ4gHe5VhXCvy4JL7gLYnesI2i6t4Tii04r92u1YKt767gB0ozrkGzmY26zEOh7Hkt+kAKhLTX9qOVVdg9aoNOjcToR+wUVKLYKgN0Zq7l7884wn9CKgr4AfWw/B6SwqKQRKOdXVghe9CpbherASSjtIpGpxRIHFjwygNreoXy0lb+lU7lHJBP9kPcGXQnBNghUB/Lh44fbUp5JA+5Hs71LbPPLCVRDEJZDNGIJgeQI6mG6KegKzldq1U7tGKjQmHR8vwl86kgRoAQN0xBw6ztn0nQ/ocxEdQ7L4d/BjG6g+m8aZTL/xsXPuW82Fb8t+DG1Ox5D6XAwqvQ67OA+p9ZWoUQPsei78mjSwNU9GLmEzVGZJTd3qFPTn3YZhXgYMMjNhlHsDxms/hNWfoUdrNPgEc2h7BG5d/Bo7Blt0BuNxXf4MVmXrkdRyEHWiY6hr2oc7mevRX2wc18gioEeI1+N9a+/CNnImVAZ0mhEoNOPAJT8MHjUF8KTiWhqHgbfMpVaJdhLQh3XasU9bJAZ6ekeg6zQwgEKuLSWysmd3QGmatLqD8qDNug3dCX/AIPk4jGr2wDB/JXTmkan70IvmZTY/rB9BdZlKLkG0lG0d5klAObKsw1+jzyFiWPnRawiaDrMYwTyMwMwh220WP2IWFVfqN4CKO8E3n0C6R/ZUej9Y2kUiMdDRFTRePH3nA3q/m7xpAEtAXl0QrkTwscnmS/3eptdzNEYevZLnZ5booqk8tuYs9tAny+n1LL1mghezlcULH0VtHamOZhvhIvoNOXQsd2EZIbluYnlWaMO75TCFG9kYXJ8H14o76H/10Z3yClSrCm6jGtbWK7LC7kIlYRfUmY2XHnUa+mbXYRSfCuNCptyE6b1jMBD/EPKwchQPLxGdxOWWI8iKXYBPqLozgI8pfA5YBWvxbfMeNLUfRmPTLjRnr8YKsdGvRQ5j2zZTSSRQ78H+7GhxfScFAINypsG9ukDspZ0LKKE+O0pqlGi71ggcIqD3dga6RhFKjSqYT+VEFkvu/E9Q+HNWKaE2VVDgVkPFqwAaay5CN3En9M59BM2vfKDs7AvljjPGE5LlharQdL+LoCmhOHU0rIUyD+NgVTOa+q2iVQiIcAKpHtbhXuJOjPqeVCRYThNE6VTvKNs3hM3cHGIxntxKyCbP7Erj1lHZJbVIJAG6iiCroZCAPGukvOyASJbvCgoaAoKoAQ1kHcGC7nmZDkmhBR2PfSQLtkcl4zCSAE2eO6qExYuYxrE4KqdvelBiM4+ncYQy1IY8d0wbhUSLJAZGbsUceNYdwJCGPAyuy4NbZToG3JoO1Qk9AvHvqF4ejo0KCKlisyl04Jw+AE1ma71HRUJP+QqM1t2HcVEyTEoSYVYQCuN3HenCt4XDhGA+KorAnYZ9KIj5ELOl3XpU/k/wrt+OmraDaG7cjpacbxFvYAAZDG5Vw/DWCxjRdp+ATsWAS6+D69H1+XDNsoVb1T06b0VwzCmBIOYdqUWibTojcFBH1CXQctBtUcA6Oh/RmVC4sBmKA5j6erC1qqE4sRpqG25A43QIOHuXgvOmP5R4ZH6m5UY2L9SSLjZ5sKjjsI/o8olH8ngjCZoSgmw9DMIl3t42Up0g+pq89/sEjLK47knZhSkSuDepJP4JOyNJyEFAR8VQKMOR1nbWM69yxNJYwh+VLE90ffPyxLE3EwL9Jq0huWQqwL1iA7zq8+FVl0+epgBO6T+gb2TH+OglqgastxtZrNNlkLt8E5oJx6HZdab7mFZBk3UZRjMewCT7HkzLfodZxREYr5sBjiIBPYiAPt8ehvSGPSg5vwjzpd16VNkmmDTswp22QDTXbkJrxhJkzHGDFoUQmvBpvo2hrZl0TnLhlLIYfUO7nt7dSg3hURcP1/JiDEgphuXBqVKLRFsfA3oJAf3mI6Cr2OjTwGYdqWGzzmZD6WoYVCfehdqsZKjuuwS1oB1Q+5piHac3oaxBzZ9vLZ4nHEeesoXg6niDPSYWP9yUgD5PHu48eKE64krHcErchHIEuRysTpAXjObQWIYEHiV4EQYEojp5aEoyY+IIpOQugKYYOnIdJXrdJ63PtWwXMQM6m6SVT4gfZkbHV0XHsVtaQ3K8yoJr0YfwoHDDq5ZiQSqDik/B4Q9taYtn18gyNia1qGJsmTrGlUjK2FJ1jCjRwOASDnkxDvN95ZD/og5yl0qgfCMJ2leDoeksHaFHXYOJVyrMkm/DrPwMzGr2wmjnLGipthyHL0W7t9pDkduwF2U3lmGFtvbTdyirt0OreT+iWwPRUrUBbSkLkT/fCUZwKVYikBMwpDlPXNzLwuAQ2rWX8KzUh2dDDJyLSmB7/S5Mf3WRWiR6CPSezkCXQs6qBnLCKsheyoXqnTCoL9oOFd9/Qtl9KJT6UJMX3/zhCz8iuCjhiviSYtMx3ZTJBN8lCE7eIRgF0p6krRRaRBDskTTGySBKws5SuUjJHYUiMQdpzCUE0Q3y5MnSDhJJQg5JUvjSgO5hHZofaioGmvc40IycMgbRtJktjgOZ5Ma9irzSg46xYHcaVEZevkgBHqUWGFK+FENKQ+BdGAq/wiMYWbwHI6h4FwTDOes0BMKFMHxPNg9qn1dANakYanfuQSs5FJoTpaP1qBswsSGgb9+EeUU0Af0LDH4dBhXlmv3wajuOpPYQFDcEojxtNQ6sn9ZzUsiofjfUWg/iYOt+tJatRtvN95DqZgxNuKTKwLV4Jdyqc8Wz1uCGTLjmDIVDQqewQ8anwpJi6GsYkF4Ey2O/QvsfXKlJIgboAwT07s5AZ0G1TylUIsuhdKMI6vcuQ3PVAqg+9UZ8JvGEywiuNoIwD4IzaV2X+HSa1otgE3+NwJImVkycG0kx8snfyUZJW+QFApeSu+hN9BpIn6n+ZBp9bqDv+C8Fum+8IpzzJNOmR3UhTaGFcC07iAHXmamuZw28C/S/aIt+CcthF7+ToN0EQdhqOFzcBu/Sm/ApvAGX3DzYXIiF9jtWTJf74L6ZC83UfGg8SId2xnloSZKxp+gWjC0J6KSrMK8KhmnlSugtInpkCzaBV78Hl5oPoaLpECrLt+Bi4jfgS7t1q+YDUGsPwj5KDFsLlqD97JuIpmpZmP+TftM1ezjlxsOllM4H3eReDWHwKrOBW84jqMeK5OBTv4Bu6HxxgqU1s/N3MkAHSoH+ioCe+gjoJHB0s8ENLID6/UJo3E+GVlwoNEwY278tXhR50RhmeexzgmM8JXjdF36MHwEoiXn70Csv6gxBm8PiRc6gJFD1HDzFpq1cP0omo5QJZAfqQzH0f6uHZjQgeR4cC/IJZCnUtSkYVPAWBiX2/CdU/S7Ql+9TgtFCTaiP0qAEXA2yRsqwuzECziWZcM4tgv2DSljF7ID+l+JNh9+hY38HuvcYmLOhk5EEnVPfQOmpW+33YGaXhj53E2BWuxvGebOh5cPUX/sWSgXrsa9mB2qaDqCK4C7I2IA3jn8u7tat2g6D034MIbWb0fZgHlr2DscXUhNNuYdkYRPrg/7JiXDMLYBrZS6GNEZgVJM/JjWY4I16G4xr/BCDq2nKjjoAvY+Zpwo7eXBskQK9Swr0lEdAn4a2wk3o/DMNWmn54KYUQIuZsebGQuXFQ42H4kfNk4QckSOkNZ1lGkGAUoInOKkAm2jJsVtH+om9Nj9ytZxNcNdhljXByo+JJXj/i4G2u2xM02YInPJLxFB7VudTPH0ZHkWu0hbPpwHpfnAszoFDVgVsb1fDMmoL9L8S7wTFQE/1AvR33oB+QSp0czKgl34B2iO9uwJCKib5SGaZjbqLPlkhMG1YDr1gQyioSs24vQTDitagsnIL6loCUVu9C2EJK9FjYtsWBNP2Q7hb9A155zdwY5mTeGexo0w32hEcy2F7JQaOqZfgk38KY6rDMKFBiGHNt+iGPgCNYd0/s/sbAb2fgN5JQC9Wq8bkR0AzioOOx3Xo30mGbnY+tNMKoJOQCm03qfnFxRf6E1yUFAqZJcyuZRWuQmB+TWHJcgJfkjPxImcSSIUsXviMx/O9DvqfALrPDjb6nhuBAWkZ5JFKKTYuIqhz4FUdAo9CGwzO7Ra2LjUg0w9OxdlwyKxAXzHQm8lDi4HeAT1WMPSHnYXR7aswKE6Gfl4K9PdfgZ6+uG8XSmMbKyXD/LsEmFduglH2NHA7rA3Hvg+Ve1/gYO4KNFRvQUPLQVRU7MG4yn1dJ4eiULAo3JhW9xsa77+Hml8GY8FQ425uAM5wRRivNoPlTjs4XhoH35oLGFZ/S/wglyDkbWmrrsUAvY+A3kHlSwJ6ihKzCvLnuQyElmIs9LdfhmHxA+jn5kI3jcrRFOjxU6DTbTx9DybsOBh0f034EeYEVyaFD0IYhnQ9y1pTIsiPvU5AnKYkUBL78yKmQhDLgDRPSWtPp/HFkFtHqFCfRBr73wX67qsD+qFsEubCnqKBAZllcCkkT12RjSHVMfApH0bJXfcH+aQGZg6FU1EWeeoK2NwgoMM3Q++zP/fq/Smf2g392ZEwzk2Acfl9GBHURmuSYPyn132oHBizH8B8wjX0SadQI2cWtOZZQbHTdEgRn8XN93EiczFayn5GU3Mg7lJMPab5SEeoCWZZ0TF4Ne/A/ZSPUbXdDz9Qdddrrk/KtcwR7jX34VXDzGCFGFT0GzyLu922x069kdiv145tOu34jlOHBWoz4arUAZQt0LYOhmFcHJ2H6zAsYnZDc2FwKhv60+m9UQrLUJ4hSYQAVhpM1O6jj30EDD33Q6frZyoY8cMVaWZZR560kuB5V9H6iVUas+Py5L1/IHsT2ZldR4nEkMdkUd8Y8tYd43mLIMhYhenDWvgjQSQiGFOkiEv0rEAzK2u8yG10M2WwBWFdb6q9NKDNd6rCOuYD9L2VI/57QMfcEniU5cCnJgG+lR9haAnz4MzT5ZjmA4e8HBqnGtYXamF+nK7bpx0uwHxoqGyE3sKD5HHjYVJ1C6Z5qTD5Ph2G1hnQEV/0LBhxU2E+4yYsbgTCJGsuNBfYQrnjA0CPxDo2CRYJ0xGesgD1ZWvQ3LQbKeSJ54uC0UcUDVVRGExFR/FB2y7cSf4C+Zv9sXSUeQ9P2z2pQdnmBHQsPKqKqFCyWJsM75o1GMw8O/iEhFZs/KK9CD9wRfhCTYTP1dqwnBOHrQYz8IuuH5ZxxI/MLQZH5kfoeu6D4cVQGNecgXHFbRgXZsD4Xg5MjqfDeE0KTBbRDLXsLiwOR8HkxCJoOs+Eavdr08ZBBGdYP7rYzAZILsH3LYUYtgSsAXlYRwLqW0r8Ksl2id4/Onaz47IE+kayUfwddYhsgwkqXRrLgOpHEuyhVF9B7ytoTAL//qNjeFagGfGEi5nvYPEifqOx/ek4p1J/8aKBWC8N6Icy2+oL6zOhECTmw46SuoHZpXBn/pK7/DK8K1bCp3Q0vAv7wqfIBD55OuS9teFVYASPfAFccseThw+E4Ho5LOMqYB6ZCeOdK6H1bleJH2sOOPZradqlC3otDqY5F2GafQmmCZdgFnMBZteEML2yCnprh0CZWVp66gbDuD5Q2uSLUacm43jSB0gq+h55JeuRX7wRqUUbkJL8DS4GTcPqCdZgduZ6XiZjgvcp9fIY3aAH/yY+3KvcMDBjLSXQBXDML4VbaQG8a9PgUxcOzyIneKY/Or6FHDO8q7INY+RiMFJaJijE4i2VeEylej/FDs99TAPH8Dvofv8bDK/vhVHxMRhX0W+vOgXTijiY5UXANGkNnYeRUGN2VrsPNx6XVaQNgRNM03sBgUjeOKJJ/Cr+LNzFsg61YB5/elyKtic0qM031CaZAG0gqJnVEuYBIoI49gy9D6DXrQR3GoU2j3YE+WE2FI9TGBG1FLywnhNbPt1Y/OhY+o5iGqsGNmdLaVxfqZUB+g0Iztwi2AOkNZ3FCzOm30bHeHK9tKYHKfPZMFhlAtM9c2EpjALv93zY3qlE/8xyOOUVUTiSBrfy83CvDIdbRZC4uJSGwzHzd0qgkmEVfRnGW/dC79vPobtkFLRmm0HDpVt43MnrzoOm/dfQeeOf0P3wB+guJogXrIDuhHfAsdOFbKdQ5GkaYQbNNYNht2c8/AOnYNKB6Ri//Q14zRwIuohdPC76pCbWKGFCkx9GNC7B0NZD8CiJh8Odi7A59zud7EuwvU4hVUYZBhUXwqsqA56V0RiUM1Dam36UoiyFuprQhc6fRZuKKhV5+rcLKD2hrPQ+NPsvgNb0j6C9eCG0v/kU2l9/BK0ZM8EdRJQ833noG8Qib6lDkA0lYD6i8GIJlffZ/IhhbJtQjW4TP164EiWWztTnH9T+a4L/MxpjAn02hWWYDAQnefSZzm7Io7zDOpiSzGh3grwPwd3zDccPZdH4phBEkXcWBrD4wlE07qObw5pmBUGsK43T/YPfgmAFWEe5U2EeCXhGcV5nQ3u2KrTf6w+jdTNhtud7mB/ZC4vg43QAwbAMDYLF0e3os+8HGP80D7oLx0F9dD+oj9AGZ4Y85K0Yj/Vs3kQiFgeybFPIySiDzdwAz9O3JzHjPNtYk8gjv948FOOatlGodR0Dk07Bau9n0F8wFBp+luBO1CXeuDD51Q3830PRP7UIzgUlcC0vhHPRSdic6eI53ecT3W0sKyjI2EFRxhzyz3sOO8voBkEUTclYhAyshCwr642PR79diwlbBOEs8vLMFjgbbuelhpeoz5rEDxsNNl/+9ON5RWJOLsXCysQdh5IhWWbzhUmoel6v/l/RxGpZTKgbh3EtEZQMp5AX2ASd2f3AVu7695ky/7nOuc2U/BZSCFIGp+I82F/rfprsVa/+Mk0sZ2F0tTvGNZ+gRO8B7C/HQ92beWine+/IDWDBbJUmbBN/hUNOGRyyStH34vfQeP3ZV4R61atXIu9Kefg1rIB/XRJciwso9nymLXmxbP+wxcCsVAxIKwfv1AZoDH96jN6rXr1SuVeowKsuFINrs+BSXATbc59JLU/XwCwdDMw7B/vUEpgHfQYZ7v9HCNar/2E55ynDpSwYrhXF4uKUeQiY0/Oy3kM555nCITcJgmvp0F30Yo8L9KpXL1X9E2XhkPoVBuYWwbmolKDOhmv+WHiXyGNkgbTRE1pOublXkRycCz+AfUoRzPdsgKJN1w/19KpXf7n6xlnCPikE/SkWdswrozDkNoZUfIWhFTYYWaPy4a6NkgSR2XAZXSOLIWUWcCv7FP1T7sH8wFZwp7ycxz971auXIm4AG+b77MFLEKLv7ULJMy0FefCsPAOv0t0YUrIMg0s+gVfxYrgVbIJLUSzsrl2F2ZZl4L7J/Pdp/956ca969UrEna0O41/HwSJ4F3in42Fz5Trsbt5Bv3u30e9uImyvnoV15GGY/LIA6kOZP1966pZ8r3r1n5eqhwZ0F/aB4ToHGK9zh/FPHjD60RE6H1tDaaA2cdy7mvFfI+BffksPNrEksu0AAAAASUVORK5CYII=",f}),define("Scene/GridImageryProvider",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","../Core/GeographicTilingScheme","../ThirdParty/when"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._tilingScheme=r(e.tilingScheme)?e.tilingScheme:new o({ellipsoid:e.ellipsoid}),this._cells=t(e.cells,8),this._color=t(e.color,l),this._glowColor=t(e.glowColor,u),this._glowWidth=t(e.glowWidth,6),this._backgroundColor=t(e.backgroundColor,c),this._errorEvent=new n,this._tileWidth=t(e.tileWidth,256),this._tileHeight=t(e.tileHeight,256),this._canvasSize=t(e.canvasSize,256),this._canvas=this._createGridCanvas(),this._readyPromise=a.resolve(!0)}var l=new e(1,1,1,.4),u=new e(0,1,0,.05),c=new e(0,.5,0,.2);return i(s.prototype,{proxy:{get:function(){}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){}},minimumLevel:{get:function(){}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return!0}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){}},hasAlphaChannel:{get:function(){return!0}}}),s.prototype._drawGrid=function(e){for(var t=this._canvasSize,r=0;r<=this._cells;++r){var i=r/this._cells,n=1+i*(t-1);e.moveTo(n,0),e.lineTo(n,t),e.moveTo(0,n),e.lineTo(t,n)}e.stroke()},s.prototype._createGridCanvas=function(){var e=document.createElement("canvas");e.width=this._canvasSize,e.height=this._canvasSize;var t=this._canvasSize,r=e.getContext("2d"),i=this._backgroundColor.toCssColorString();r.fillStyle=i,r.fillRect(0,0,t,t);var n=this._glowColor.toCssColorString();r.strokeStyle=n,r.lineWidth=this._glowWidth,r.strokeRect(0,0,t,t),this._drawGrid(r),r.lineWidth=.5*this._glowWidth,r.strokeRect(0,0,t,t),this._drawGrid(r);var o=this._color.toCssColorString();return r.strokeStyle=o,r.lineWidth=2,r.strokeRect(0,0,t,t),r.lineWidth=1,this._drawGrid(r),e},s.prototype.getTileCredits=function(e,t,r){},s.prototype.requestImage=function(e,t,r,i){return this._canvas},s.prototype.pickFeatures=function(e,t,r,i,n){},s}),define("Scene/InvertClassification",["../Core/Color","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/PixelFormat","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Sampler","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Shaders/PostProcessFilters/PassThrough","./BlendingState","./StencilFunction","./StencilOperation"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(){this.previousFramebuffer=void 0,this._previousFramebuffer=void 0,this._texture=void 0,this._classifiedTexture=void 0,this._depthStencilTexture=void 0,this._fbo=void 0,this._fboClassified=void 0,this._rsUnclassified=void 0,this._rsClassified=void 0,this._unclassifiedCommand=void 0,this._classifiedCommand=void 0,this._translucentCommand=void 0,this._clearColorCommand=new o({color:new e(0,0,0,0),owner:this}),this._clearCommand=new o({color:new e(0,0,0,0),depth:1,stencil:0});var t=this;this._uniformMap={u_texture:function(){return t._texture},u_depth:function(){return t._depthStencilTexture},u_classified:function(){return t._classifiedTexture}}}r(y.prototype,{unclassifiedCommand:{get:function(){return this._unclassifiedCommand}}}),y.isTranslucencySupported=function(e){return e.depthTexture&&e.fragmentDepth};var C={depthMask:!1,stencilTest:{enabled:!0,frontFunction:_.EQUAL,frontOperation:{fail:v.KEEP,zFail:v.KEEP,zPass:v.KEEP},backFunction:_.NEVER,reference:0,mask:15},blending:g.ALPHA_BLEND},b={depthMask:!1,stencilTest:{enabled:!0,frontFunction:_.NOT_EQUAL,frontOperation:{fail:v.KEEP,zFail:v.KEEP,zPass:v.KEEP},backFunction:_.NEVER,reference:0,mask:15},blending:g.ALPHA_BLEND},S={depthMask:!0,depthTest:{enabled:!0},blending:g.ALPHA_BLEND};return y.prototype.update=function(e){var r=this._texture,i=!t(r)||this.previousFramebuffer!==this._previousFramebuffer;this._previousFramebuffer=this.previousFramebuffer;var o=e.drawingBufferWidth,g=e.drawingBufferHeight,_=!t(r)||r.width!==o||r.height!==g;if((_||i)&&(this._texture=this._texture&&this._texture.destroy(),this._classifiedTexture=this._classifiedTexture&&this._classifiedTexture.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),this._texture=new d({context:e,width:o,height:g,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE,sampler:new u({wrapS:f.CLAMP_TO_EDGE,wrapT:f.CLAMP_TO_EDGE,minificationFilter:p.LINEAR,magnificationFilter:h.LINEAR})}),t(this._previousFramebuffer)||(this._classifiedTexture=new d({context:e,width:o,height:g,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE,sampler:new u({wrapS:f.CLAMP_TO_EDGE,wrapT:f.CLAMP_TO_EDGE,minificationFilter:p.LINEAR,magnificationFilter:h.LINEAR})}),this._depthStencilTexture=new d({context:e,width:o,height:g,pixelFormat:n.DEPTH_STENCIL,pixelDatatype:s.UNSIGNED_INT_24_8}))),!t(this._fbo)||_||i){this._fbo=this._fbo&&this._fbo.destroy(),this._fboClassified=this._fboClassified&&this._fboClassified.destroy();var v,y;t(this._previousFramebuffer)?(v=this._previousFramebuffer.depthStencilTexture,y=this._previousFramebuffer.depthStencilRenderbuffer):v=this._depthStencilTexture,this._fbo=new a({context:e,colorTextures:[this._texture],depthStencilTexture:v,depthStencilRenderbuffer:y,destroyAttachments:!1}),t(this._previousFramebuffer)||(this._fboClassified=new a({context:e,colorTextures:[this._classifiedTexture],depthStencilTexture:v,destroyAttachments:!1}))}if(t(this._rsUnclassified)||(this._rsUnclassified=l.fromCache(C),this._rsClassified=l.fromCache(b),this._rsDefault=l.fromCache(S)),!t(this._unclassifiedCommand)||i){t(this._unclassifiedCommand)&&(this._unclassifiedCommand.shaderProgram=this._unclassifiedCommand.shaderProgram&&this._unclassifiedCommand.shaderProgram.destroy(),this._classifiedCommand.shaderProgram=this._classifiedCommand.shaderProgram&&this._classifiedCommand.shaderProgram.destroy());var w=t(this._previousFramebuffer)?"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n vec4 color = texture2D(u_texture, v_textureCoordinates);\n if (color.a == 0.0)\n {\n discard;\n }\n#ifdef UNCLASSIFIED\n gl_FragColor = color * czm_invertClassificationColor;\n#else\n gl_FragColor = color;\n#endif\n}\n":"#extension GL_EXT_frag_depth : enable\nuniform sampler2D u_texture;\nuniform sampler2D u_depth;\nuniform sampler2D u_classified;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n vec4 color = texture2D(u_texture, v_textureCoordinates);\n if (color.a == 0.0)\n {\n discard;\n }\n bool isClassified = all(equal(texture2D(u_classified, v_textureCoordinates), vec4(0.0)));\n#ifdef UNCLASSIFIED\n vec4 highlightColor = czm_invertClassificationColor;\n if (isClassified)\n {\n discard;\n }\n#else\n vec4 highlightColor = vec4(1.0);\n if (!isClassified)\n {\n discard;\n }\n#endif\n gl_FragColor = color * highlightColor;\n gl_FragDepthEXT = texture2D(u_depth, v_textureCoordinates).r;\n}\n",T=new c({defines:["UNCLASSIFIED"],sources:[w]}),A=new c({sources:[w]});this._unclassifiedCommand=e.createViewportQuadCommand(T,{renderState:t(this._previousFramebuffer)?this._rsUnclassified:this._rsDefault,uniformMap:this._uniformMap,owner:this}),this._classifiedCommand=e.createViewportQuadCommand(A,{renderState:t(this._previousFramebuffer)?this._rsClassified:this._rsDefault,uniformMap:this._uniformMap,owner:this}),t(this._translucentCommand)&&(this._translucentCommand.shaderProgram=this._translucentCommand.shaderProgram&&this._translucentCommand.shaderProgram.destroy()),t(this._previousFramebuffer)||(this._translucentCommand=e.createViewportQuadCommand(m,{renderState:this._rsUnclassified,uniformMap:this._uniformMap,owner:this}))}},y.prototype.clear=function(e,r){var i=r.framebuffer;t(this._previousFramebuffer)?(r.framebuffer=this._fbo,this._clearColorCommand.execute(e,r)):(r.framebuffer=this._fbo,this._clearCommand.execute(e,r),r.framebuffer=this._fboClassified,this._clearCommand.execute(e,r)),r.framebuffer=i},y.prototype.executeClassified=function(e,r){if(!t(this._previousFramebuffer)){var i=r.framebuffer;r.framebuffer=this._fboClassified,this._translucentCommand.execute(e,r),r.framebuffer=i}this._classifiedCommand.execute(e,r)},y.prototype.executeUnclassified=function(e,t){this._unclassifiedCommand.execute(e,t)},y.prototype.isDestroyed=function(){return!1},y.prototype.destroy=function(){return this._fbo=this._fbo&&this._fbo.destroy(),this._texture=this._texture&&this._texture.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),t(this._unclassifiedCommand)&&(this._unclassifiedCommand.shaderProgram=this._unclassifiedCommand.shaderProgram&&this._unclassifiedCommand.shaderProgram.destroy(),this._classifiedCommand.shaderProgram=this._classifiedCommand.shaderProgram&&this._classifiedCommand.shaderProgram.destroy()),i(this)},y}),define("Scene/JobScheduler",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/getTimestamp","./JobType"],function(e,t,r,i,n){"use strict";function o(e){this._total=e,this.usedThisFrame=0,this.stolenFromMeThisFrame=0,this.starvedThisFrame=!1,this.starvedLastFrame=!1}function a(t){var r=new Array(n.NUMBER_OF_JOB_TYPES);r[n.TEXTURE]=new o(e(t)?t[n.TEXTURE]:10),r[n.PROGRAM]=new o(e(t)?t[n.PROGRAM]:10),r[n.BUFFER]=new o(e(t)?t[n.BUFFER]:30);var i,a=r.length,s=0;for(i=0;i<a;++i)s+=r[i].total;var l=new Array(a);for(i=0;i<a;++i)l[i]=!1;this._totalBudget=s,this._totalUsedThisFrame=0,this._budgets=r,this._executedThisFrame=l}return t(o.prototype,{total:{get:function(){return this._total}}}),a.getTimestamp=i,t(a.prototype,{totalBudget:{get:function(){return this._totalBudget}}}),a.prototype.disableThisFrame=function(){this._totalUsedThisFrame=this._totalBudget},a.prototype.resetBudgets=function(){ -for(var e=this._budgets,t=e.length,r=0;r<t;++r){var i=e[r];i.starvedLastFrame=i.starvedThisFrame,i.starvedThisFrame=!1,i.usedThisFrame=0,i.stolenFromMeThisFrame=0}this._totalUsedThisFrame=0},a.prototype.execute=function(e,t){var r=this._budgets,i=r[t],n=this._executedThisFrame[t];if(this._totalUsedThisFrame>=this._totalBudget&&n)return i.starvedThisFrame=!0,!1;var o;if(i.usedThisFrame+i.stolenFromMeThisFrame>=i.total){var s,l=r.length;for(s=0;s<l&&(o=r[s],!(o.usedThisFrame+o.stolenFromMeThisFrame<o.total)||o.starvedLastFrame);++s);if(s===l&&n)return!1;n&&(i.starvedThisFrame=!0)}var u=a.getTimestamp();e.execute();var c=a.getTimestamp()-u;return this._totalUsedThisFrame+=c,o?o.stolenFromMeThisFrame+=c:i.usedThisFrame+=c,this._executedThisFrame[t]=!0,!0},a}),define("Scene/MapboxImageryProvider",["../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/MapboxApi","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a){"use strict";function s(i){i=t(i,t.EMPTY_OBJECT);var n=i.mapId,s=t(i.url,"https://api.mapbox.com/v4/");this._url=s,this._mapId=n,this._accessToken=o.getAccessToken(i.accessToken),this._accessTokenErrorCredit=o.getErrorCredit(i.accessToken);var d=t(i.format,"png");/\./.test(d)||(d="."+d),this._format=d;var h=s;if(l.test(s)||(h+="/"),h+=n+"/{z}/{x}/{y}"+this._format,r(this._accessToken)&&(h+="?access_token="+this._accessToken),r(i.credit)){var p=i.credit;"string"==typeof p&&(p=new e({text:p})),u=p,c.length=0}this._imageryProvider=new a({url:h,proxy:i.proxy,credit:u,ellipsoid:i.ellipsoid,minimumLevel:i.minimumLevel,maximumLevel:i.maximumLevel,rectangle:i.rectangle})}var l=/\/$/,u=new e({text:"© Mapbox © OpenStreetMap",link:"https://www.mapbox.com/about/maps/"}),c=[new e({text:"Improve this map",link:"https://www.mapbox.com/map-feedback/"})];return i(s.prototype,{url:{get:function(){return this._url}},ready:{get:function(){return this._imageryProvider.ready}},readyPromise:{get:function(){return this._imageryProvider.readyPromise}},rectangle:{get:function(){return this._imageryProvider.rectangle}},tileWidth:{get:function(){return this._imageryProvider.tileWidth}},tileHeight:{get:function(){return this._imageryProvider.tileHeight}},maximumLevel:{get:function(){return this._imageryProvider.maximumLevel}},minimumLevel:{get:function(){return this._imageryProvider.minimumLevel}},tilingScheme:{get:function(){return this._imageryProvider.tilingScheme}},tileDiscardPolicy:{get:function(){return this._imageryProvider.tileDiscardPolicy}},errorEvent:{get:function(){return this._imageryProvider.errorEvent}},credit:{get:function(){return this._imageryProvider.credit}},proxy:{get:function(){return this._imageryProvider.proxy}},hasAlphaChannel:{get:function(){return this._imageryProvider.hasAlphaChannel}}}),s.prototype.getTileCredits=function(e,t,i){var n=c.slice();return r(this._accessTokenErrorCredit)&&n.push(this._accessTokenErrorCredit),n},s.prototype.requestImage=function(e,t,r,i){return this._imageryProvider.requestImage(e,t,r,i)},s.prototype.pickFeatures=function(e,t,r,i,n){return this._imageryProvider.pickFeatures(e,t,r,i,n)},s}),define("Scene/Moon",["../Core/buildModuleUrl","../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Ellipsoid","../Core/IauOrientationAxes","../Core/Matrix3","../Core/Matrix4","../Core/Simon1994PlanetaryPositions","../Core/Transforms","./EllipsoidPrimitive","./Material"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(t){t=r(t,r.EMPTY_OBJECT);var n=t.textureUrl;i(n)||(n=e("Assets/Textures/moonSmall.jpg")),this.show=r(t.show,!0),this.textureUrl=n,this._ellipsoid=r(t.ellipsoid,a.MOON),this.onlySunLighting=r(t.onlySunLighting,!0),this._ellipsoidPrimitive=new h({radii:this.ellipsoid.radii,material:p.fromType(p.ImageType),depthTestEnabled:!1,_owner:this}),this._ellipsoidPrimitive.material.translucent=!1,this._axes=new s}n(f.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}});var m=new l,g=new l,_=new t,v=[];return f.prototype.update=function(e){if(this.show){var t=this._ellipsoidPrimitive;t.material.uniforms.image=this.textureUrl,t.onlySunLighting=this.onlySunLighting;var r=e.time;i(d.computeIcrfToFixedMatrix(r,m))||d.computeTemeToPseudoFixedMatrix(r,m);var n=this._axes.evaluate(r,g);l.transpose(n,n),l.multiply(m,n,n);var o=c.computeMoonPositionInEarthInertialFrame(r,_);l.multiplyByVector(m,o,o),u.fromRotationTranslation(n,o,t.modelMatrix);var a=e.commandList;return e.commandList=v,v.length=0,t.update(e),e.commandList=a,1===v.length?v[0]:void 0}},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._ellipsoidPrimitive=this._ellipsoidPrimitive&&this._ellipsoidPrimitive.destroy(),o(this)},f}),define("Scene/NeverTileDiscardPolicy",[],function(){"use strict";function e(e){}return e.prototype.isReady=function(){return!0},e.prototype.shouldDiscardImage=function(e){return!1},e}),define("Shaders/AdjustTranslucentFS",[],function(){"use strict";return"#ifdef MRT\n#extension GL_EXT_draw_buffers : enable\n#endif\nuniform vec4 u_bgColor;\nuniform sampler2D u_depthTexture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nif (texture2D(u_depthTexture, v_textureCoordinates).r < 1.0)\n{\n#ifdef MRT\ngl_FragData[0] = u_bgColor;\ngl_FragData[1] = vec4(u_bgColor.a);\n#else\ngl_FragColor = u_bgColor;\n#endif\nreturn;\n}\ndiscard;\n}\n"}),define("Shaders/CompositeOITFS",[],function(){"use strict";return"uniform sampler2D u_opaque;\nuniform sampler2D u_accumulation;\nuniform sampler2D u_revealage;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec4 opaque = texture2D(u_opaque, v_textureCoordinates);\nvec4 accum = texture2D(u_accumulation, v_textureCoordinates);\nfloat r = texture2D(u_revealage, v_textureCoordinates).r;\n#ifdef MRT\nvec4 transparent = vec4(accum.rgb / clamp(r, 1e-4, 5e4), accum.a);\n#else\nvec4 transparent = vec4(accum.rgb / clamp(accum.a, 1e-4, 5e4), r);\n#endif\ngl_FragColor = (1.0 - transparent.a) * transparent + transparent.a * opaque;\nif (opaque != czm_backgroundColor)\n{\ngl_FragColor.a = 1.0;\n}\n}\n"}),define("Scene/OIT",["../Core/BoundingRectangle","../Core/Color","../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Core/WebGLConstants","../Renderer/ClearCommand","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/ShaderSource","../Renderer/Texture","../Shaders/AdjustTranslucentFS","../Shaders/CompositeOITFS","./BlendEquation","./BlendFunction"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(r){this._translucentMultipassSupport=!1,this._translucentMRTSupport=!1;var i=r.floatingPointTexture&&r.depthTexture;this._translucentMRTSupport=r.drawBuffers&&i,this._translucentMultipassSupport=!this._translucentMRTSupport&&i,this._opaqueFBO=void 0,this._opaqueTexture=void 0,this._depthStencilTexture=void 0,this._accumulationTexture=void 0,this._translucentFBO=void 0,this._alphaFBO=void 0,this._adjustTranslucentFBO=void 0,this._adjustAlphaFBO=void 0,this._opaqueClearCommand=new a({color:new t(0,0,0,0),owner:this}),this._translucentMRTClearCommand=new a({color:new t(0,0,0,1),owner:this}),this._translucentMultipassClearCommand=new a({color:new t(0,0,0,0),owner:this}),this._alphaClearCommand=new a({color:new t(1,1,1,1),owner:this}),this._translucentRenderStateCache={},this._alphaRenderStateCache={},this._compositeCommand=void 0,this._adjustTranslucentCommand=void 0,this._adjustAlphaCommand=void 0,this._viewport=new e,this._rs=void 0,this._useScissorTest=!1,this._scissorRectangle=void 0}function v(e){e._accumulationTexture=e._accumulationTexture&&!e._accumulationTexture.isDestroyed()&&e._accumulationTexture.destroy(),e._revealageTexture=e._revealageTexture&&!e._revealageTexture.isDestroyed()&&e._revealageTexture.destroy()}function y(e){e._translucentFBO=e._translucentFBO&&!e._translucentFBO.isDestroyed()&&e._translucentFBO.destroy(),e._alphaFBO=e._alphaFBO&&!e._alphaFBO.isDestroyed()&&e._alphaFBO.destroy(),e._adjustTranslucentFBO=e._adjustTranslucentFBO&&!e._adjustTranslucentFBO.isDestroyed()&&e._adjustTranslucentFBO.destroy(),e._adjustAlphaFBO=e._adjustAlphaFBO&&!e._adjustAlphaFBO.isDestroyed()&&e._adjustAlphaFBO.destroy()}function C(e){v(e),y(e)}function b(e,t,r,i){v(e);var o=new Float32Array(r*i*4);e._accumulationTexture=new h({context:t,pixelFormat:n.RGBA,pixelDatatype:u.FLOAT,source:{arrayBufferView:o,width:r,height:i}}),e._revealageTexture=new h({context:t,pixelFormat:n.RGBA,pixelDatatype:u.FLOAT,source:{arrayBufferView:o,width:r,height:i}})}function S(e,t){y(e);var r=o.FRAMEBUFFER_COMPLETE,i=!0;if(e._translucentMRTSupport&&(e._translucentFBO=new l({context:t,colorTextures:[e._accumulationTexture,e._revealageTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._adjustTranslucentFBO=new l({context:t,colorTextures:[e._accumulationTexture,e._revealageTexture],destroyAttachments:!1}),e._translucentFBO.status===r&&e._adjustTranslucentFBO.status===r||(y(e),e._translucentMRTSupport=!1)),!e._translucentMRTSupport){e._translucentFBO=new l({context:t,colorTextures:[e._accumulationTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._alphaFBO=new l({context:t,colorTextures:[e._revealageTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._adjustTranslucentFBO=new l({context:t,colorTextures:[e._accumulationTexture],destroyAttachments:!1}),e._adjustAlphaFBO=new l({context:t,colorTextures:[e._revealageTexture],destroyAttachments:!1});var n=e._translucentFBO.status===r,a=e._alphaFBO.status===r,s=e._adjustTranslucentFBO.status===r,u=e._adjustAlphaFBO.status===r;n&&a&&s&&u||(C(e),e._translucentMultipassSupport=!1,i=!1)}return i}function w(e,t,i,n){var o=i[n.id];if(!r(o)){var a=c.getState(n);a.depthMask=!1,a.blending=t,o=c.fromCache(a),i[n.id]=o}return o}function T(e,t,r){return w(t,R,e._translucentRenderStateCache,r)}function A(e,t,r){return w(t,N,e._translucentRenderStateCache,r)}function E(e,t,r){return w(t,L,e._alphaRenderStateCache,r)}function x(e,t,i,n){var o=e.shaderCache.getDerivedShaderProgram(t,i);if(!r(o)){var a=t._attributeLocations,s=t.fragmentShaderSource.clone();s.sources=s.sources.map(function(e){return e=d.replaceMain(e,"czm_translucent_main"),e=e.replace(/gl_FragColor/g,"czm_gl_FragColor"),e=e.replace(/\bdiscard\b/g,"czm_discard = true"),e=e.replace(/czm_phong/g,"czm_translucentPhong")}),s.sources.splice(0,0,(-1!==n.indexOf("gl_FragData")?"#extension GL_EXT_draw_buffers : enable \n":"")+"vec4 czm_gl_FragColor;\nbool czm_discard = false;\n"),s.sources.push("void main()\n{\n czm_translucent_main();\n if (czm_discard)\n {\n discard;\n }\n"+n+"}\n"),o=e.shaderCache.createDerivedShaderProgram(t,i,{vertexShaderSource:t.vertexShaderSource,fragmentShaderSource:s,attributeLocations:a})}return o}function P(e,t){return x(e,t,"translucentMRT",k)}function D(e,t){return x(e,t,"translucentMultipass",F)}function I(e,t){return x(e,t,"alphaMultipass",B)}function O(e,t,i,n,o,a){var s,l,u,c=t.context,d=n.framebuffer,h=o.length,p=t.frameState.shadowHints.shadowsEnabled;n.framebuffer=e._adjustTranslucentFBO,e._adjustTranslucentCommand.execute(c,n),n.framebuffer=e._adjustAlphaFBO,e._adjustAlphaCommand.execute(c,n);var f=e._opaqueFBO;for(n.framebuffer=e._translucentFBO,u=0;u<h;++u)s=o[u],l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.translucentCommand:s.derivedCommands.oit.translucentCommand,i(l,t,c,n,f);for(r(a)&&(s=a.unclassifiedCommand,l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.translucentCommand:s.derivedCommands.oit.translucentCommand,i(l,t,c,n,f)),n.framebuffer=e._alphaFBO,u=0;u<h;++u)s=o[u],l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.alphaCommand:s.derivedCommands.oit.alphaCommand,i(l,t,c,n,f);r(a)&&(s=a.unclassifiedCommand,l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.alphaCommand:s.derivedCommands.oit.alphaCommand,i(l,t,c,n,f)),n.framebuffer=d}function M(e,t,i,n,o,a){var s=t.context,l=n.framebuffer,u=o.length,c=t.frameState.shadowHints.shadowsEnabled;n.framebuffer=e._adjustTranslucentFBO,e._adjustTranslucentCommand.execute(s,n);var d=e._opaqueFBO;n.framebuffer=e._translucentFBO;for(var h,p,f=0;f<u;++f)h=o[f],p=c&&h.receiveShadows?h.derivedCommands.oit.shadows.translucentCommand:h.derivedCommands.oit.translucentCommand,i(p,t,s,n,d);r(a)&&(h=a.unclassifiedCommand,p=c&&h.receiveShadows?h.derivedCommands.oit.shadows.translucentCommand:h.derivedCommands.oit.translucentCommand,i(p,t,s,n,d)),n.framebuffer=l}_.prototype.update=function(t,i,n){if(this.isSupported()){this._opaqueFBO=n,this._opaqueTexture=n.getColorTexture(0),this._depthStencilTexture=n.depthStencilTexture;var o=this._opaqueTexture.width,a=this._opaqueTexture.height,s=this._accumulationTexture,l=!r(s)||s.width!==o||s.height!==a;if(l&&b(this,t,o,a),r(this._translucentFBO)&&!l||S(this,t)){var u,h,m=this;r(this._compositeCommand)||(u=new d({sources:[f]}),this._translucentMRTSupport&&u.defines.push("MRT"),h={u_opaque:function(){return m._opaqueTexture},u_accumulation:function(){return m._accumulationTexture},u_revealage:function(){return m._revealageTexture}},this._compositeCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this})),r(this._adjustTranslucentCommand)||(this._translucentMRTSupport?(u=new d({defines:["MRT"],sources:[p]}),h={u_bgColor:function(){return m._translucentMRTClearCommand.color},u_depthTexture:function(){return m._depthStencilTexture}},this._adjustTranslucentCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this})):this._translucentMultipassSupport&&(u=new d({sources:[p]}),h={u_bgColor:function(){return m._translucentMultipassClearCommand.color},u_depthTexture:function(){return m._depthStencilTexture}},this._adjustTranslucentCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this}),h={u_bgColor:function(){return m._alphaClearCommand.color},u_depthTexture:function(){return m._depthStencilTexture}},this._adjustAlphaCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this}))),this._viewport.width=o,this._viewport.height=a;var g=!e.equals(this._viewport,i.viewport),_=g!==this._useScissorTest;this._useScissorTest=g,e.equals(this._scissorRectangle,i.viewport)||(this._scissorRectangle=e.clone(i.viewport,this._scissorRectangle),_=!0),r(this._rs)&&e.equals(this._viewport,this._rs.viewport)&&!_||(this._rs=c.fromCache({viewport:this._viewport,scissorTest:{enabled:this._useScissorTest,rectangle:this._scissorRectangle}})),r(this._compositeCommand)&&(this._compositeCommand.renderState=this._rs),this._adjustTranslucentCommand&&(this._adjustTranslucentCommand.renderState=this._rs),r(this._adjustAlphaCommand)&&(this._adjustAlphaCommand.renderState=this._rs)}}};var R={enabled:!0,color:new t(0,0,0,0),equationRgb:m.ADD,equationAlpha:m.ADD,functionSourceRgb:g.ONE,functionDestinationRgb:g.ONE,functionSourceAlpha:g.ZERO,functionDestinationAlpha:g.ONE_MINUS_SOURCE_ALPHA},N={enabled:!0,color:new t(0,0,0,0),equationRgb:m.ADD,equationAlpha:m.ADD,functionSourceRgb:g.ONE,functionDestinationRgb:g.ONE,functionSourceAlpha:g.ONE,functionDestinationAlpha:g.ONE},L={enabled:!0,color:new t(0,0,0,0),equationRgb:m.ADD,equationAlpha:m.ADD,functionSourceRgb:g.ZERO,functionDestinationRgb:g.ONE_MINUS_SOURCE_ALPHA,functionSourceAlpha:g.ZERO,functionDestinationAlpha:g.ONE_MINUS_SOURCE_ALPHA},k=" vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n float ai = czm_gl_FragColor.a;\n float wzi = czm_alphaWeight(ai);\n gl_FragData[0] = vec4(Ci * wzi, ai);\n gl_FragData[1] = vec4(ai * wzi);\n",F=" vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n float ai = czm_gl_FragColor.a;\n float wzi = czm_alphaWeight(ai);\n gl_FragColor = vec4(Ci, ai) * wzi;\n",B=" float ai = czm_gl_FragColor.a;\n gl_FragColor = vec4(ai);\n";return _.prototype.createDerivedCommands=function(e,t,i){if(r(i)||(i={}),this._translucentMRTSupport){var n,o;r(i.translucentCommand)&&(n=i.translucentCommand.shaderProgram,o=i.translucentCommand.renderState),i.translucentCommand=s.shallowClone(e,i.translucentCommand),r(n)&&i.shaderProgramId===e.shaderProgram.id?(i.translucentCommand.shaderProgram=n,i.translucentCommand.renderState=o):(i.translucentCommand.shaderProgram=P(t,e.shaderProgram),i.translucentCommand.renderState=T(this,t,e.renderState),i.shaderProgramId=e.shaderProgram.id)}else{var a,l,u,c;r(i.translucentCommand)&&(a=i.translucentCommand.shaderProgram,l=i.translucentCommand.renderState,u=i.alphaCommand.shaderProgram,c=i.alphaCommand.renderState),i.translucentCommand=s.shallowClone(e,i.translucentCommand),i.alphaCommand=s.shallowClone(e,i.alphaCommand),r(a)&&i.shaderProgramId===e.shaderProgram.id?(i.translucentCommand.shaderProgram=a,i.translucentCommand.renderState=l,i.alphaCommand.shaderProgram=u,i.alphaCommand.renderState=c):(i.translucentCommand.shaderProgram=D(t,e.shaderProgram),i.translucentCommand.renderState=A(this,t,e.renderState),i.alphaCommand.shaderProgram=I(t,e.shaderProgram),i.alphaCommand.renderState=E(this,t,e.renderState),i.shaderProgramId=e.shaderProgram.id)}return i},_.prototype.executeCommands=function(e,t,r,i,n){if(this._translucentMRTSupport)return void M(this,e,t,r,i,n);O(this,e,t,r,i,n)},_.prototype.execute=function(e,t){this._compositeCommand.execute(e,t)},_.prototype.clear=function(e,r,i){var n=r.framebuffer;r.framebuffer=this._opaqueFBO,t.clone(i,this._opaqueClearCommand.color),this._opaqueClearCommand.execute(e,r),r.framebuffer=this._translucentFBO,(this._translucentMRTSupport?this._translucentMRTClearCommand:this._translucentMultipassClearCommand).execute(e,r),this._translucentMultipassSupport&&(r.framebuffer=this._alphaFBO,this._alphaClearCommand.execute(e,r)),r.framebuffer=n},_.prototype.isSupported=function(){return this._translucentMRTSupport||this._translucentMultipassSupport},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return C(this),r(this._compositeCommand)&&(this._compositeCommand.shaderProgram=this._compositeCommand.shaderProgram&&this._compositeCommand.shaderProgram.destroy()),r(this._adjustTranslucentCommand)&&(this._adjustTranslucentCommand.shaderProgram=this._adjustTranslucentCommand.shaderProgram&&this._adjustTranslucentCommand.shaderProgram.destroy()),r(this._adjustAlphaCommand)&&(this._adjustAlphaCommand.shaderProgram=this._adjustAlphaCommand.shaderProgram&&this._adjustAlphaCommand.shaderProgram.destroy()),i(this)},_}),define("Scene/Particle",["../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties"],function(e,t,r,i,n,o){"use strict";function a(n){n=i(n,i.EMPTY_OBJECT),this.mass=i(n.mass,1),this.position=t.clone(i(n.position,t.ZERO)),this.velocity=t.clone(i(n.velocity,t.ZERO)),this.life=i(n.life,Number.MAX_VALUE),this.image=n.image,this.startColor=r.clone(i(n.startColor,r.WHITE)),this.endColor=r.clone(i(n.endColor,r.WHITE)),this.startScale=i(n.startScale,1),this.endScale=i(n.endScale,1),this.size=e.clone(i(n.size,s)),this._age=0,this._normalizedAge=0,this._billboard=void 0}var s=new e(1,1);o(a.prototype,{age:{get:function(){return this._age}},normalizedAge:{get:function(){return this._normalizedAge}}});var l=new t;return a.prototype.update=function(e,r){if(t.multiplyByScalar(this.velocity,e,l),t.add(this.position,l,this.position),n(r))for(var i=r.length,o=0;o<i;++o){var a=r[o];"function"==typeof a&&a(this,e)}return this._age+=e,this.life===Number.MAX_VALUE?this._normalizedAge=0:this._normalizedAge=this._age/this.life,this._age<=this.life},a}),define("Scene/ParticleBurst",["../Core/defaultValue","../Core/defineProperties"],function(e,t){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.time=e(t.time,0),this.minimum=e(t.minimum,0),this.maximum=e(t.maximum,50),this._complete=!1}return t(r.prototype,{complete:{get:function(){return this._complete}}}),r}),define("Scene/ParticleEmitter",["../Core/DeveloperError"],function(e){"use strict";function t(e){}return t.prototype.emit=function(t){e.throwInstantiationError()},t}),define("Scene/ParticleSystem",["../Core/Cartesian2","../Core/Cartesian3","../Core/Check","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Event","../Core/JulianDate","../Core/Math","../Core/Matrix4","./BillboardCollection","./CircleEmitter","./Particle"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=n(e,n.EMPTY_OBJECT),this.show=n(e.show,!0),this.forces=e.forces,this.loop=n(e.loop,!0),this.image=n(e.image,void 0);var t=e.emitter;o(t)||(t=new p(.5)),this._emitter=t,this._bursts=e.bursts,this._modelMatrix=d.clone(n(e.modelMatrix,d.IDENTITY)),this._emitterModelMatrix=d.clone(n(e.emitterModelMatrix,d.IDENTITY)),this._matrixDirty=!0,this._combinedMatrix=new d,this._startColor=i.clone(n(e.startColor,i.WHITE)),this._endColor=i.clone(n(e.endColor,i.WHITE)),this._startScale=n(e.startScale,1),this._endScale=n(e.endScale,1),this._rate=n(e.rate,5),this._minimumSpeed=n(e.speed,n(e.minimumSpeed,1)),this._maximumSpeed=n(e.speed,n(e.maximumSpeed,1)),this._minimumLife=n(e.life,n(e.minimumLife,5)),this._maximumLife=n(e.life,n(e.maximumLife,5)),this._minimumMass=n(e.mass,n(e.minimumMass,1)),this._maximumMass=n(e.mass,n(e.maximumMass,1)),this._minimumWidth=n(e.width,n(e.minimumWidth,1)),this._maximumWidth=n(e.width,n(e.maximumWidth,1)),this._minimumHeight=n(e.height,n(e.minimumHeight,1)),this._maximumHeight=n(e.height,n(e.maximumHeight,1)),this._lifeTime=n(e.lifeTime,Number.MAX_VALUE),this._billboardCollection=void 0,this._particles=[],this._particlePool=[],this._previousTime=void 0,this._currentTime=0,this._carryOver=0,this._complete=new l,this._isComplete=!1,this._updateParticlePool=!0,this._particleEstimate=0}function g(e){var t=e._rate,r=e._maximumLife,i=0,n=e._bursts;if(o(n))for(var a=n.length,s=0;s<a;++s)i+=n[s].maximum;for(var l=e._billboardCollection,u=e.image,c=Math.ceil(t*r+i),d=e._particles,h=e._particlePool,p=Math.max(c-d.length-h.length,0),m=0;m<p;++m){var g=new f;g._billboard=l.add({image:u}),h.push(g)}e._particleEstimate=c}function _(e){var t=e._particlePool.pop();return o(t)||(t=new f),t}function v(e,t){e._particlePool.push(t)}function y(e){for(var t=e._particles,r=e._particlePool,i=e._billboardCollection,n=t.length,o=r.length,a=e._particleEstimate,s=o-Math.max(a-n-o,0),l=s;l<o;++l){var u=r[l];i.remove(u._billboard)}r.length=s}function C(e){o(e._billboard)&&(e._billboard.show=!1)}function b(e,t){var r=t._billboard;o(r)||(r=t._billboard=e._billboardCollection.add({image:t.image})),r.width=t.size.x,r.height=t.size.y,r.position=t.position,r.show=!0;var n=c.lerp(t.startColor.red,t.endColor.red,t.normalizedAge),a=c.lerp(t.startColor.green,t.endColor.green,t.normalizedAge),s=c.lerp(t.startColor.blue,t.endColor.blue,t.normalizedAge),l=c.lerp(t.startColor.alpha,t.endColor.alpha,t.normalizedAge);r.color=new i(n,a,s,l);var u=c.lerp(t.startScale,t.endScale,t.normalizedAge);r.scale=u}function S(r,n){n.startColor=i.clone(r._startColor,n.startColor),n.endColor=i.clone(r._endColor,n.endColor),n.startScale=r._startScale,n.endScale=r._endScale,n.image=r.image,n.life=c.randomBetween(r._minimumLife,r._maximumLife),n.mass=c.randomBetween(r._minimumMass,r._maximumMass);var o=c.randomBetween(r._minimumWidth,r._maximumWidth),a=c.randomBetween(r._minimumHeight,r._maximumHeight);n.size=e.fromElements(o,a,n.size),n._normalizedAge=0,n._age=0;var s=c.randomBetween(r._minimumSpeed,r._maximumSpeed);t.multiplyByScalar(n.velocity,s,n.velocity),r._particles.push(n)}function w(e,t){if(e._isComplete)return 0;t=c.mod(t,e._lifeTime);var r=t*e._rate,i=Math.floor(r);if(e._carryOver+=r-i,e._carryOver>1&&(i++,e._carryOver-=1),o(e.bursts))for(var n=e.bursts.length,a=0;a<n;a++){var s=e.bursts[a],l=e._currentTime;o(s)&&!s._complete&&l>s.time&&(i+=c.randomBetween(s.minimum,s.maximum),s._complete=!0)}return i}a(m.prototype,{emitter:{get:function(){return this._emitter},set:function(e){this._emitter=e}},bursts:{get:function(){return this._bursts},set:function(e){this._bursts=e,this._updateParticlePool=!0}},modelMatrix:{get:function(){return this._modelMatrix},set:function(e){this._matrixDirty=this._matrixDirty||!d.equals(this._modelMatrix,e),d.clone(e,this._modelMatrix)}},emitterModelMatrix:{get:function(){return this._emitterModelMatrix},set:function(e){this._matrixDirty=this._matrixDirty||!d.equals(this._emitterModelMatrix,e),d.clone(e,this._emitterModelMatrix)}},startColor:{get:function(){return this._startColor},set:function(e){i.clone(e,this._startColor)}},endColor:{get:function(){return this._endColor},set:function(e){i.clone(e,this._endColor)}},startScale:{get:function(){return this._startScale},set:function(e){this._startScale=e}},endScale:{get:function(){return this._endScale},set:function(e){this._endScale=e}},rate:{get:function(){return this._rate},set:function(e){this._rate=e,this._updateParticlePool=!0}},minimumSpeed:{get:function(){return this._minimumSpeed},set:function(e){this._minimumSpeed=e}},maximumSpeed:{get:function(){return this._maximumSpeed},set:function(e){this._maximumSpeed=e}},minimumLife:{get:function(){return this._minimumLife},set:function(e){this._minimumLife=e}},maximumLife:{get:function(){return this._maximumLife},set:function(e){this._maximumLife=e,this._updateParticlePool=!0}},minimumMass:{get:function(){return this._minimumMass},set:function(e){this._minimumMass=e}},maximumMass:{get:function(){return this._maximumMass},set:function(e){this._maximumMass=e}},minimumWidth:{get:function(){return this._minimumWidth},set:function(e){this._minimumWidth=e}},maximumWidth:{get:function(){return this._maximumWidth},set:function(e){this._maximumWidth=e}},minimumHeight:{get:function(){return this._minimumHeight},set:function(e){this._minimumHeight=e}},maximumHeight:{get:function(){return this._maximumHeight},set:function(e){this._maximumHeight=e}},lifeTime:{get:function(){return this._lifeTime},set:function(e){this._lifeTime=e}},complete:{get:function(){return this._complete}},isComplete:{get:function(){return this._isComplete}}});var T=new t;return m.prototype.update=function(e){if(this.show){o(this._billboardCollection)||(this._billboardCollection=new h),this._updateParticlePool&&(g(this),this._updateParticlePool=!1);var r=0;this._previousTime&&(r=u.secondsDifference(e.time,this._previousTime)),r<0&&(r=0);var i,n,a=this._particles,s=this._emitter,l=this.forces,p=a.length;for(i=0;i<p;++i)n=a[i],n.update(r,l)?b(this,n):(C(n),v(this,n),a[i]=a[p-1],--i,--p);a.length=p;var f=w(this,r);if(f>0&&o(s)){this._matrixDirty&&(this._combinedMatrix=d.multiply(this.modelMatrix,this.emitterModelMatrix,this._combinedMatrix),this._matrixDirty=!1);var m=this._combinedMatrix;for(i=0;i<f;i++)n=_(this),this._emitter.emit(n),t.add(n.position,n.velocity,T),d.multiplyByPoint(m,T,T),n.position=d.multiplyByPoint(m,n.position,n.position),t.subtract(T,n.position,n.velocity),t.normalize(n.velocity,n.velocity),S(this,n),b(this,n)}if(this._billboardCollection.update(e),this._previousTime=u.clone(e.time,this._previousTime),this._currentTime+=r,this._lifeTime!==Number.MAX_VALUE&&this._currentTime>this._lifeTime)if(this.loop){if(this._currentTime=c.mod(this._currentTime,this._lifeTime),this.bursts){var A=this.bursts.length;for(i=0;i<A;i++)this.bursts[i]._complete=!1}}else this._isComplete=!0,this._complete.raiseEvent(this);e.frameNumber%120==0&&y(this)}},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){return this._billboardCollection=this._billboardCollection&&this._billboardCollection.destroy(),s(this)},m}),define("Widgets/getElement",["../Core/DeveloperError"],function(e){"use strict";function t(e){if("string"==typeof e){e=document.getElementById(e)}return e}return t}),define("Scene/PerformanceDisplay",["../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/getTimestamp","../Widgets/getElement"],function(e,t,r,i,n,o){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT);var r=o(t.container);this._container=r;var i=document.createElement("div");i.className="cesium-performanceDisplay";var a=document.createElement("div");a.className="cesium-performanceDisplay-fps",this._fpsText=document.createTextNode(""),a.appendChild(this._fpsText);var s=document.createElement("div");s.className="cesium-performanceDisplay-ms",this._msText=document.createTextNode(""),s.appendChild(this._msText),i.appendChild(s),i.appendChild(a),this._container.appendChild(i),this._lastFpsSampleTime=n(),this._lastMsSampleTime=n(),this._fpsFrameCount=0,this._msFrameCount=0}return a.prototype.update=function(){var e=n();this._fpsFrameCount++;var t=e-this._lastFpsSampleTime;if(t>1e3){var r=1e3*this._fpsFrameCount/t|0;this._fpsText.nodeValue=r+" FPS",this._lastFpsSampleTime=e,this._fpsFrameCount=0}this._msFrameCount++;var i=e-this._lastMsSampleTime;i>200&&(this._msText.nodeValue=(i/this._msFrameCount).toFixed(2)+" MS",this._lastMsSampleTime=e,this._msFrameCount=0)},a.prototype.destroy=function(){return r(this)},a}),define("Scene/PickDepth",["../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Texture"],function(e,t,r,i,n,o,a){"use strict";function s(){this.framebuffer=void 0,this._depthTexture=void 0,this._textureToCopy=void 0,this._copyDepthCommand=void 0,this._debugPickDepthViewportCommand=void 0}function l(t,r,i){if(!e(t._debugPickDepthViewportCommand)){t._debugPickDepthViewportCommand=r.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n float n_range = czm_depthRange.near;\n float f_range = czm_depthRange.far;\n float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n}\n",{uniformMap:{u_texture:function(){return t._depthTexture}},owner:t})}t._debugPickDepthViewportCommand.execute(r,i)}function u(e){e._depthTexture=e._depthTexture&&!e._depthTexture.isDestroyed()&&e._depthTexture.destroy()}function c(e){e.framebuffer=e.framebuffer&&!e.framebuffer.isDestroyed()&&e.framebuffer.destroy()}function d(e,t,i,o){e._depthTexture=new a({context:t,width:i,height:o,pixelFormat:r.RGBA,pixelDatatype:n.UNSIGNED_BYTE})}function h(e,t,r,n){u(e),c(e),d(e,t,r,n),e.framebuffer=new i({context:t,colorTextures:[e._depthTexture],destroyAttachments:!1})}function p(t,r,i){var n=i.width,o=i.height,a=t._depthTexture,s=!e(a)||a.width!==n||a.height!==o;e(t.framebuffer)&&!s||h(t,r,n,o)}function f(t,r,i){if(!e(t._copyDepthCommand)){t._copyDepthCommand=r.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n}\n",{renderState:o.fromCache(),uniformMap:{u_texture:function(){return t._textureToCopy}},owner:t})}t._textureToCopy=i,t._copyDepthCommand.framebuffer=t.framebuffer}return s.prototype.executeDebugPickDepth=function(e,t){l(this,e,t)},s.prototype.update=function(e,t){p(this,e,t),f(this,e,t)},s.prototype.executeCopyDepth=function(e,t){this._copyDepthCommand.execute(e,t)},s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return u(this),c(this),this._copyDepthCommand.shaderProgram=e(this._copyDepthCommand.shaderProgram)&&this._copyDepthCommand.shaderProgram.destroy(),t(this)},s}),define("Scene/PrimitiveCollection",["../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError"],function(e,t,r,i,n,o){"use strict";function a(r){r=t(r,t.EMPTY_OBJECT),this._primitives=[],this._guid=e(),this.show=t(r.show,!0),this.destroyPrimitives=t(r.destroyPrimitives,!0)}function s(e,t){return e._primitives.indexOf(t)}return i(a.prototype,{length:{get:function(){return this._primitives.length}}}),a.prototype.add=function(e){ -var t=e._external=e._external||{};return(t._composites=t._composites||{})[this._guid]={collection:this},this._primitives.push(e),e},a.prototype.remove=function(e){if(this.contains(e)){var t=this._primitives.indexOf(e);if(-1!==t)return this._primitives.splice(t,1),delete e._external._composites[this._guid],this.destroyPrimitives&&e.destroy(),!0}return!1},a.prototype.removeAndDestroy=function(e){var t=this.remove(e);return t&&!this.destroyPrimitives&&e.destroy(),t},a.prototype.removeAll=function(){if(this.destroyPrimitives)for(var e=this._primitives,t=e.length,r=0;r<t;++r)e[r].destroy();this._primitives=[]},a.prototype.contains=function(e){return!!(r(e)&&e._external&&e._external._composites&&e._external._composites[this._guid])},a.prototype.raise=function(e){if(r(e)){var t=s(this,e),i=this._primitives;if(t!==i.length-1){var n=i[t];i[t]=i[t+1],i[t+1]=n}}},a.prototype.raiseToTop=function(e){if(r(e)){var t=s(this,e),i=this._primitives;t!==i.length-1&&(i.splice(t,1),i.push(e))}},a.prototype.lower=function(e){if(r(e)){var t=s(this,e),i=this._primitives;if(0!==t){var n=i[t];i[t]=i[t-1],i[t-1]=n}}},a.prototype.lowerToBottom=function(e){if(r(e)){var t=s(this,e),i=this._primitives;0!==t&&(i.splice(t,1),i.unshift(e))}},a.prototype.get=function(e){return this._primitives[e]},a.prototype.update=function(e){if(this.show)for(var t=this._primitives,r=0;r<t.length;++r)t[r].update(e)},a.prototype.isDestroyed=function(){return!1},a.prototype.destroy=function(){return this.removeAll(),n(this)},a}),define("Scene/QuadtreeTileProvider",["../Core/defineProperties","../Core/DeveloperError"],function(e,t){"use strict";function r(){t.throwInstantiationError()}return r.computeDefaultLevelZeroMaximumGeometricError=function(e){return 2*e.ellipsoid.maximumRadius*Math.PI*.25/(65*e.getNumberOfXTilesAtLevel(0))},e(r.prototype,{quadtree:{get:t.throwInstantiationError,set:t.throwInstantiationError},ready:{get:t.throwInstantiationError},tilingScheme:{get:t.throwInstantiationError},errorEvent:{get:t.throwInstantiationError}}),r.prototype.beginUpdate=t.throwInstantiationError,r.prototype.endUpdate=t.throwInstantiationError,r.prototype.getLevelMaximumGeometricError=t.throwInstantiationError,r.prototype.loadTile=t.throwInstantiationError,r.prototype.computeTileVisibility=t.throwInstantiationError,r.prototype.showTileThisFrame=t.throwInstantiationError,r.prototype.computeDistanceToTile=t.throwInstantiationError,r.prototype.isDestroyed=t.throwInstantiationError,r.prototype.destroy=t.throwInstantiationError,r}),define("Scene/SceneTransitioner",["../Core/Cartesian3","../Core/Cartographic","../Core/Check","../Core/defined","../Core/destroyObject","../Core/EasingFunction","../Core/Math","../Core/Matrix4","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/Ray","../Core/ScreenSpaceEventHandler","../Core/ScreenSpaceEventType","../Core/Transforms","./Camera","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){this._scene=e,this._currentTweens=[],this._morphHandler=void 0,this._morphCancelled=!1,this._completeMorph=void 0,this._morphToOrthographic=!1}function v(e,t){if(e._scene.completeMorphOnUserInput){e._morphHandler=new h(e._scene.canvas,!1);var r=function(){e._morphCancelled=!0,t(e)};e._completeMorph=r,e._morphHandler.setInputAction(r,p.LEFT_DOWN),e._morphHandler.setInputAction(r,p.MIDDLE_DOWN),e._morphHandler.setInputAction(r,p.RIGHT_DOWN),e._morphHandler.setInputAction(r,p.WHEEL)}}function y(e){for(var t=e._currentTweens,r=0;r<t.length;++r)t[r].cancelTween();e._currentTweens.length=0,e._morphHandler=e._morphHandler&&e._morphHandler.destroy()}function C(e,t){var r=e._scene,i=r.camera,n=q,o=n.position,a=n.direction,l=n.up,u=r.mapProjection.unproject(i.position,X);t.cartographicToCartesian(u,o);var c=t.scaleToGeodeticSurface(o,Q),d=f.eastNorthUpToFixedFrame(c,t,Z);return s.multiplyByPointAsVector(d,i.direction,a),s.multiplyByPointAsVector(d,i.up,l),n}function b(t,r,i,n){function a(t){w(c,p,t.time,u.position),w(d,f,t.time,u.direction),w(h,g,t.time,u.up),e.cross(u.direction,u.up,u.right),e.normalize(u.right,u.right)}r*=.5;var l=t._scene,u=l.camera,c=e.clone(u.position,K),d=e.clone(u.direction,J),h=e.clone(u.up,$),p=s.multiplyByPoint(m.TRANSFORM_2D_INVERSE,i.position,ee),f=s.multiplyByPointAsVector(m.TRANSFORM_2D_INVERSE,i.direction,te),g=s.multiplyByPointAsVector(m.TRANSFORM_2D_INVERSE,i.up,re),_=l.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:a,complete:function(){I(t,l,0,1,r,n)}});t._currentTweens.push(_)}function S(t,r,i){function n(t){w(p,_,t.time,u.position),w(f,y,t.time,u.direction),w(m,S,t.time,u.up),e.cross(u.direction,u.up,u.right),e.normalize(u.right,u.right);var r=u.frustum;r.right=a.lerp(T,A,t.time),r.left=-r.right,r.top=r.right*(l.drawingBufferHeight/l.drawingBufferWidth),r.bottom=-r.top,u.position.z=2*l.mapProjection.ellipsoid.maximumRadius}r/=3;var s,l=t._scene,u=l.camera;r>0?(s=q,e.fromDegrees(0,0,5*i.maximumRadius,i,s.position),e.negate(s.position,s.direction),e.normalize(s.direction,s.direction),e.clone(e.UNIT_Z,s.up)):(u.position.z=u.frustum.right-u.frustum.left,s=C(t,i));var c;t._morphToOrthographic?(c=ie,c.aspectRatio=l.drawingBufferWidth/l.drawingBufferHeight,c.width=u.frustum.right-u.frustum.left):(c=Y,c.aspectRatio=l.drawingBufferWidth/l.drawingBufferHeight,c.fov=a.toRadians(60)),s.frustum=c;var d=O(s);v(t,d);var h,p=e.clone(u.position,ne),f=e.clone(u.direction,oe),m=e.clone(u.up,ae),_=e.fromElements(0,0,5*i.maximumRadius,se),y=e.negate(e.UNIT_Z,le),S=e.clone(e.UNIT_Y,ue),T=u.frustum.right,A=.5*_.z;if(h=t._morphToOrthographic?function(){b(t,r,s,d)}:function(){x(t,r,s,function(){b(t,r,s,d)})},r>0){var E=l.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:n,complete:function(){l._mode=g.MORPHING,h()}});t._currentTweens.push(E)}else h()}function w(t,r,i,n){return e.lerp(t,r,i,n)}function T(e,t,r,i,n){function s(e){c.frustum.fov=a.lerp(d,h,e.time);var t=p/Math.tan(.5*c.frustum.fov);i(c,t)}var u=e._scene,c=u.camera;if(!(c.frustum instanceof l)){var d=c.frustum.fov,h=.5*a.RADIANS_PER_DEGREE,p=r.position.z*Math.tan(.5*d);c.frustum.far=p/Math.tan(.5*h)+1e7;var f=u.tweens.add({duration:t,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:s,complete:function(){c.frustum=r.frustum.clone(),n(e)}});e._currentTweens.push(f)}}function A(t,r){function n(t){w(c,g,t.time,u.position),w(d,p,t.time,u.direction),w(h,f,t.time,u.up),e.cross(u.direction,u.up,u.right),e.normalize(u.right,u.right),u._adjustOrthographicFrustum(!0)}function a(e,t){e.position.z=t}r*=.5;var l=t._scene,u=l.camera,c=e.clone(u.position,ce),d=e.clone(u.direction,de),h=e.clone(u.up,he),p=e.negate(e.UNIT_Z,fe),f=e.clone(e.UNIT_Y,me),g=pe;if(r>0)e.clone(e.ZERO,pe),g.z=5*l.mapProjection.ellipsoid.maximumRadius;else{e.clone(c,pe);var _=_e;s.multiplyByPoint(m.TRANSFORM_2D,c,_.origin),s.multiplyByPointAsVector(m.TRANSFORM_2D,d,_.direction);var y=l.globe;if(i(y)){var C=y.pick(_,l,ve);i(C)&&(s.multiplyByPoint(m.TRANSFORM_2D_INVERSE,C,g),g.z+=e.distance(c,g))}}var b=ge;b.right=.5*g.z,b.left=-b.right,b.top=b.right*(l.drawingBufferHeight/l.drawingBufferWidth),b.bottom=-b.top;var S=ye;S.position=g,S.direction=p,S.up=f,S.frustum=b;var A=M(S);v(t,A);var E=l.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:n,complete:function(){T(t,r,S,a,A)}});t._currentTweens.push(E)}function E(t,r,n){function o(e,t){e.position.x=t}function a(){T(t,r,c,o,w)}r*=.5;var l=t._scene,u=l.camera,c=be;if(r>0)e.clone(e.ZERO,c.position),c.position.z=5*n.maximumRadius,e.negate(e.UNIT_Z,c.direction),e.clone(e.UNIT_Y,c.up);else{n.cartesianToCartographic(u.positionWC,Ce),l.mapProjection.project(Ce,c.position),e.negate(e.UNIT_Z,c.direction),e.clone(e.UNIT_Y,c.up);var d=Te;e.clone(c.position2D,d.origin);var h=e.clone(u.directionWC,d.direction),p=n.scaleToGeodeticSurface(u.positionWC,Ee),g=f.eastNorthUpToFixedFrame(p,n,Ae);s.inverseTransformation(g,g),s.multiplyByPointAsVector(g,h,h),s.multiplyByPointAsVector(m.TRANSFORM_2D,h,h);var _=l.globe;if(i(_)){var y=_.pick(d,l,we);if(i(y)){var C=e.distance(c.position2D,y);y.x+=C,e.clone(y,c.position2D)}}}s.multiplyByPoint(m.TRANSFORM_2D,c.position,c.position2D),s.multiplyByPointAsVector(m.TRANSFORM_2D,c.direction,c.direction2D),s.multiplyByPointAsVector(m.TRANSFORM_2D,c.up,c.up2D);var b=c.frustum;b.right=.5*c.position.z,b.left=-b.right,b.top=b.right*(l.drawingBufferHeight/l.drawingBufferWidth),b.bottom=-b.top;var S=Se;s.multiplyByPoint(m.TRANSFORM_2D_INVERSE,c.position2D,S.position),e.clone(c.direction,S.direction),e.clone(c.up,S.up),S.frustum=b;var w=M(S);v(t,w),D(t,r,c,a)}function x(e,t,r,i){function n(e){l.frustum.fov=a.lerp(d,c,e.time),l.position.z=h/Math.tan(.5*l.frustum.fov)}var s=e._scene,l=s.camera,u=l.frustum.right-l.frustum.left;l.frustum=r.frustum.clone();var c=l.frustum.fov,d=.5*a.RADIANS_PER_DEGREE,h=u*Math.tan(.5*c);l.frustum.far=h/Math.tan(.5*d)+1e7,l.frustum.fov=d;var p=s.tweens.add({duration:t,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:n,complete:function(){i(e)}});e._currentTweens.push(p)}function P(t,r,i,n){function a(){function a(t){w(h,u,t.time,l.position),w(p,c,t.time,l.direction),w(f,d,t.time,l.up),e.cross(l.direction,l.up,l.right),e.normalize(l.right,l.right)}l.frustum=i.frustum.clone();var h=e.clone(l.position,ne),p=e.clone(l.direction,oe),f=e.clone(l.up,ae);h.z=u.z;var m=s.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:a,complete:function(){n(t)}});t._currentTweens.push(m)}r*=.5;var s=t._scene,l=s.camera,u=e.clone(i.position,se),c=e.clone(i.direction,le),d=e.clone(i.up,ue);s._mode=g.MORPHING,t._morphToOrthographic?a():x(t,0,i,a)}function D(t,r,i,n){function a(t){w(u,h,t.time,l.position),w(c,p,t.time,l.direction),w(d,f,t.time,l.up),e.cross(l.direction,l.up,l.right),e.normalize(l.right,l.right),l._adjustOrthographicFrustum(!0)}var s=t._scene,l=s.camera,u=e.clone(l.position,ne),c=e.clone(l.direction,oe),d=e.clone(l.up,ae),h=e.clone(i.position2D,se),p=e.clone(i.direction2D,le),f=e.clone(i.up2D,ue),m=s.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:a,complete:function(){I(t,s,1,0,r,n)}});t._currentTweens.push(m)}function I(e,t,r,n,a,s){var l={object:t,property:"morphTime",startValue:r,stopValue:n,duration:a,easingFunction:o.QUARTIC_OUT};i(s)&&(l.complete=function(){s(e)});var u=t.tweens.addProperty(l);e._currentTweens.push(u)}function O(t){return function(r){var n=r._scene;if(n._mode=g.SCENE3D,n.morphTime=g.getMorphTime(g.SCENE3D),y(r),r._previousMode!==g.MORPHING||r._morphCancelled){r._morphCancelled=!1;var o=n.camera;e.clone(t.position,o.position),e.clone(t.direction,o.direction),e.clone(t.up,o.up),e.cross(o.direction,o.up,o.right),e.normalize(o.right,o.right),o.frustum=t.frustum.clone()}var a=i(r._completeMorph);r._completeMorph=void 0,n.camera.update(n.mode),r._scene.morphComplete.raiseEvent(r,r._previousMode,g.SCENE3D,a)}}function M(t){return function(r){var n=r._scene;n._mode=g.SCENE2D,n.morphTime=g.getMorphTime(g.SCENE2D),y(r);var o=n.camera;e.clone(t.position,o.position),o.position.z=2*n.mapProjection.ellipsoid.maximumRadius,e.clone(t.direction,o.direction),e.clone(t.up,o.up),e.cross(o.direction,o.up,o.right),e.normalize(o.right,o.right),o.frustum=t.frustum.clone();var a=i(r._completeMorph);r._completeMorph=void 0,n.camera.update(n.mode),r._scene.morphComplete.raiseEvent(r,r._previousMode,g.SCENE2D,a)}}function R(t){return function(r){var n=r._scene;if(n._mode=g.COLUMBUS_VIEW,n.morphTime=g.getMorphTime(g.COLUMBUS_VIEW),y(r),r._previousModeMode!==g.MORPHING||r._morphCancelled){r._morphCancelled=!1;var o=n.camera;e.clone(t.position,o.position),e.clone(t.direction,o.direction),e.clone(t.up,o.up),e.cross(o.direction,o.up,o.right),e.normalize(o.right,o.right)}var a=i(r._completeMorph);r._completeMorph=void 0,n.camera.update(n.mode),r._scene.morphComplete.raiseEvent(r,r._previousMode,g.COLUMBUS_VIEW,a)}}_.prototype.completeMorph=function(){i(this._completeMorph)&&this._completeMorph()},_.prototype.morphTo2D=function(e,t){i(this._completeMorph)&&this._completeMorph();var r=this._scene;this._previousMode=r.mode,this._morphToOrthographic=r.camera.frustum instanceof l,this._previousMode!==g.SCENE2D&&this._previousMode!==g.MORPHING&&(this._scene.morphStart.raiseEvent(this,this._previousMode,g.SCENE2D,!0),r._mode=g.MORPHING,r.camera._setTransform(s.IDENTITY),this._previousMode===g.COLUMBUS_VIEW?A(this,e):E(this,e,t),0===e&&i(this._completeMorph)&&this._completeMorph())};var N=new e,L=new e,k=new e,F=new e,B=new e,U=new e,V=new e,z=new t,G=new s,H=new c,W=new l,j={position:void 0,direction:void 0,up:void 0,position2D:void 0,direction2D:void 0,up2D:void 0,frustum:void 0};_.prototype.morphToColumbusView=function(t,r){i(this._completeMorph)&&this._completeMorph();var n=this._scene;if(this._previousMode=n.mode,this._previousMode!==g.COLUMBUS_VIEW&&this._previousMode!==g.MORPHING){this._scene.morphStart.raiseEvent(this,this._previousMode,g.COLUMBUS_VIEW,!0),n.camera._setTransform(s.IDENTITY);var o=N,l=L,u=k;if(t>0)o.x=0,o.y=-1,o.z=1,o=e.multiplyByScalar(e.normalize(o,o),5*r.maximumRadius,o),e.negate(e.normalize(o,l),l),e.cross(e.UNIT_X,l,u);else{var c=n.camera;if(this._previousMode===g.SCENE2D)e.clone(c.position,o),o.z=c.frustum.right-c.frustum.left,e.negate(e.UNIT_Z,l),e.clone(e.UNIT_Y,u);else{e.clone(c.positionWC,o),e.clone(c.directionWC,l),e.clone(c.upWC,u);var d=r.scaleToGeodeticSurface(o,V),h=f.eastNorthUpToFixedFrame(d,r,G);s.inverseTransformation(h,h),n.mapProjection.project(r.cartesianToCartographic(o,z),o),s.multiplyByPointAsVector(h,l,l),s.multiplyByPointAsVector(h,u,u)}}var p;this._morphToOrthographic?(p=W,p.width=n.camera.frustum.right-n.camera.frustum.left,p.aspectRatio=n.drawingBufferWidth/n.drawingBufferHeight):(p=H,p.aspectRatio=n.drawingBufferWidth/n.drawingBufferHeight,p.fov=a.toRadians(60));var _=j;_.position=o,_.direction=l,_.up=u,_.frustum=p;var y=R(_);v(this,y),this._previousMode===g.SCENE2D?P(this,t,_,y):(_.position2D=s.multiplyByPoint(m.TRANSFORM_2D,o,F),_.direction2D=s.multiplyByPointAsVector(m.TRANSFORM_2D,l,B),_.up2D=s.multiplyByPointAsVector(m.TRANSFORM_2D,u,U),n._mode=g.MORPHING,D(this,t,_,y)),0===t&&i(this._completeMorph)&&this._completeMorph()}};var q={position:new e,direction:new e,up:new e,frustum:void 0},Y=new c;_.prototype.morphTo3D=function(t,r){i(this._completeMorph)&&this._completeMorph();var n=this._scene;if(this._previousMode=n.mode,this._previousMode!==g.SCENE3D&&this._previousMode!==g.MORPHING){if(this._scene.morphStart.raiseEvent(this,this._previousMode,g.SCENE3D,!0),n._mode=g.MORPHING,n.camera._setTransform(s.IDENTITY),this._previousMode===g.SCENE2D)S(this,t,r);else{var o;t>0?(o=q,e.fromDegrees(0,0,5*r.maximumRadius,r,o.position),e.negate(o.position,o.direction),e.normalize(o.direction,o.direction),e.clone(e.UNIT_Z,o.up)):o=C(this,r);var u,c=n.camera;c.frustum instanceof l?u=c.frustum.clone():(u=Y,u.aspectRatio=n.drawingBufferWidth/n.drawingBufferHeight,u.fov=a.toRadians(60)),o.frustum=u;var d=O(o);v(this,d),b(this,t,o,d)}0===t&&i(this._completeMorph)&&this._completeMorph()}},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return y(this),n(this)};var X=new t,Q=new e,Z=new s,K=new e,J=new e,$=new e,ee=new e,te=new e,re=new e,ie=new l,ne=new e,oe=new e,ae=new e,se=new e,le=new e,ue=new e,ce=new e,de=new e,he=new e,pe=new e,fe=new e,me=new e,ge=new u,_e=new d,ve=new e,ye={position:void 0,direction:void 0,up:void 0,frustum:void 0},Ce=new t,be={position:new e,direction:new e,up:new e,position2D:new e,direction2D:new e,up2D:new e,frustum:new u},Se={position:new e,direction:new e,up:new e,frustum:void 0},we=new e,Te=new d,Ae=new s,Ee=new e;return _}),define("Scene/TweenCollection",["../Core/clone","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/EasingFunction","../Core/getTimestamp","../Core/TimeConstants","../ThirdParty/Tween"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t,r,i,n,o,a,s,l,u,c){this._tweens=t,this._tweenjs=r,this._startObject=e(i),this._stopObject=e(n),this._duration=o,this._delay=a,this._easingFunction=s,this._update=l,this._complete=u,this.cancel=c,this.needsStart=!0}function c(){this._tweens=[]}return i(u.prototype,{startObject:{get:function(){return this._startObject}},stopObject:{get:function(){return this._stopObject}},duration:{get:function(){return this._duration}},delay:{get:function(){return this._delay}},easingFunction:{get:function(){return this._easingFunction}},update:{get:function(){return this._update}},complete:{get:function(){return this._complete}},tweenjs:{get:function(){return this._tweenjs}}}),u.prototype.cancelTween=function(){this._tweens.remove(this)},i(c.prototype,{length:{get:function(){return this._tweens.length}}}),c.prototype.add=function(i){if(i=t(i,t.EMPTY_OBJECT),0===i.duration)return r(i.complete)&&i.complete(),new u(this);var n=i.duration/s.SECONDS_PER_MILLISECOND,a=t(i.delay,0),c=a/s.SECONDS_PER_MILLISECOND,d=t(i.easingFunction,o.LINEAR_NONE),h=i.startObject,p=new l.Tween(h);p.to(e(i.stopObject),n),p.delay(c),p.easing(d),r(i.update)&&p.onUpdate(function(){i.update(h)}),p.onComplete(t(i.complete,null)),p.repeat(t(i._repeat,0));var f=new u(this,p,i.startObject,i.stopObject,i.duration,a,d,i.update,i.complete,i.cancel);return this._tweens.push(f),f},c.prototype.addProperty=function(e){function r(e){i[n]=e.value}e=t(e,t.EMPTY_OBJECT);var i=e.object,n=e.property,o=e.startValue,a=e.stopValue;return this.add({startObject:{value:o},stopObject:{value:a},duration:t(e.duration,3),delay:e.delay,easingFunction:e.easingFunction,update:r,complete:e.complete,cancel:e.cancel,_repeat:e._repeat})},c.prototype.addAlpha=function(e){function i(e){for(var t=o.length,r=0;r<t;++r)n.uniforms[o[r]].alpha=e.alpha}e=t(e,t.EMPTY_OBJECT);var n=e.material,o=[];for(var a in n.uniforms)n.uniforms.hasOwnProperty(a)&&r(n.uniforms[a])&&r(n.uniforms[a].alpha)&&o.push(a);return this.add({startObject:{alpha:t(e.startValue,0)},stopObject:{alpha:t(e.stopValue,1)},duration:t(e.duration,3),delay:e.delay,easingFunction:e.easingFunction,update:i,complete:e.complete,cancel:e.cancel})},c.prototype.addOffsetIncrement=function(e){e=t(e,t.EMPTY_OBJECT);var r=e.material,i=r.uniforms;return this.addProperty({object:i,property:"offset",startValue:i.offset,stopValue:i.offset+1,duration:e.duration,delay:e.delay,easingFunction:e.easingFunction,update:e.update,cancel:e.cancel,_repeat:1/0})},c.prototype.remove=function(e){if(!r(e))return!1;var t=this._tweens.indexOf(e);return-1!==t&&(e.tweenjs.stop(),r(e.cancel)&&e.cancel(),this._tweens.splice(t,1),!0)},c.prototype.removeAll=function(){for(var e=this._tweens,t=0;t<e.length;++t){var i=e[t];i.tweenjs.stop(),r(i.cancel)&&i.cancel()}e.length=0},c.prototype.contains=function(e){return r(e)&&-1!==this._tweens.indexOf(e)},c.prototype.get=function(e){return this._tweens[e]},c.prototype.update=function(e){var t=this._tweens,i=0;for(e=r(e)?e/s.SECONDS_PER_MILLISECOND:a();i<t.length;){var n=t[i],o=n.tweenjs;n.needsStart?(n.needsStart=!1,o.start(e)):o.update(e)?i++:(o.stop(),t.splice(i,1))}},c}),define("Scene/ScreenSpaceCameraController",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/HeadingPitchRoll","../Core/IntersectionTests","../Core/isArray","../Core/KeyboardEventModifier","../Core/Math","../Core/Matrix3","../Core/Matrix4","../Core/OrthographicFrustum","../Core/Plane","../Core/Quaternion","../Core/Ray","../Core/Transforms","./CameraEventAggregator","./CameraEventType","./MapMode2D","./SceneMode","./SceneTransforms","./TweenCollection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E){"use strict";function x(r){this.enableInputs=!0,this.enableTranslate=!0,this.enableZoom=!0,this.enableRotate=!0,this.enableTilt=!0,this.enableLook=!0,this.inertiaSpin=.9,this.inertiaTranslate=.9,this.inertiaZoom=.8,this.maximumMovementRatio=.1,this.bounceAnimationTime=3,this.minimumZoomDistance=1,this.maximumZoomDistance=Number.POSITIVE_INFINITY,this.translateEventTypes=S.LEFT_DRAG,this.zoomEventTypes=[S.RIGHT_DRAG,S.WHEEL,S.PINCH],this.rotateEventTypes=S.LEFT_DRAG,this.tiltEventTypes=[S.MIDDLE_DRAG,S.PINCH,{eventType:S.LEFT_DRAG,modifier:h.CTRL},{eventType:S.RIGHT_DRAG,modifier:h.CTRL}],this.lookEventTypes={eventType:S.LEFT_DRAG,modifier:h.SHIFT},this.minimumPickingTerrainHeight=15e4,this._minimumPickingTerrainHeight=this.minimumPickingTerrainHeight,this.minimumCollisionTerrainHeight=15e3,this._minimumCollisionTerrainHeight=this.minimumCollisionTerrainHeight,this.minimumTrackBallHeight=75e5,this._minimumTrackBallHeight=this.minimumTrackBallHeight,this.enableCollisionDetection=!0,this._scene=r,this._globe=void 0,this._ellipsoid=void 0,this._aggregator=new b(r.canvas),this._lastInertiaSpinMovement=void 0,this._lastInertiaZoomMovement=void 0,this._lastInertiaTranslateMovement=void 0,this._lastInertiaTiltMovement=void 0,this._tweens=new E,this._tween=void 0,this._horizontalRotationAxis=void 0,this._tiltCenterMousePosition=new e(-1,-1),this._tiltCenter=new t,this._rotateMousePosition=new e(-1,-1),this._rotateStartPosition=new t,this._strafeStartPosition=new t,this._zoomMouseStart=new e(-1,-1),this._zoomWorldPosition=new t,this._useZoomWorldPosition=!1,this._tiltCVOffMap=!1,this._looking=!1,this._rotating=!1,this._strafing=!1,this._zoomingOnVector=!1,this._rotatingZoom=!1;var n=r.mapProjection;this._maxCoord=n.project(new i(Math.PI,p.PI_OVER_TWO)),this._zoomFactor=5,this._rotateFactor=void 0,this._rotateRateRangeAdjustment=void 0,this._maximumRotateRate=1.77,this._minimumRotateRate=2e-4,this._minimumZoomRate=20,this._maximumZoomRate=5906376272e3}function P(e,t){if(e<0)return 0;var r=25*(1-t);return Math.exp(-r*e)}function D(t){return e.equalsEpsilon(t.startPosition,t.endPosition,p.EPSILON14)}function I(t,r,i,n,a,s,l){var u=s[l];o(u)||(u=s[l]={startPosition:new e,endPosition:new e,motion:new e,active:!1});var c=t.getButtonPressTime(r,i),d=t.getButtonReleaseTime(r,i),h=c&&d&&(d.getTime()-c.getTime())/1e3,p=new Date,f=d&&(p.getTime()-d.getTime())/1e3;if(c&&d&&h<te){var m=P(f,n);if(u.active)u.startPosition=e.clone(u.endPosition,u.startPosition),u.endPosition=e.multiplyByScalar(u.motion,m,u.endPosition),u.endPosition=e.add(u.startPosition,u.endPosition,u.endPosition),u.motion=e.clone(e.ZERO,u.motion);else{var g=t.getLastMovement(r,i);if(!o(g)||D(g))return;u.motion.x=.5*(g.endPosition.x-g.startPosition.x),u.motion.y=.5*(g.endPosition.y-g.startPosition.y),u.startPosition=e.clone(g.startPosition,u.startPosition),u.endPosition=e.multiplyByScalar(u.motion,m,u.endPosition),u.endPosition=e.add(u.startPosition,u.endPosition,u.endPosition),u.active=!0}if(isNaN(u.endPosition.x)||isNaN(u.endPosition.y)||e.distance(u.startPosition,u.endPosition)<.5)return void(u.active=!1);if(!t.isButtonDown(r,i)){a(s,t.getStartMousePosition(r,i),u)}}else u.active=!1}function O(e,t,r,i,n,a){if(o(r)){var s=e._aggregator;d(r)||(re[0]=r,r=re);for(var l=r.length,u=0;u<l;++u){var c=r[u],h=o(c.eventType)?c.eventType:c,p=c.modifier,f=s.isMoving(h,p)&&s.getMovement(h,p),m=s.getStartMousePosition(h,p);e.enableInputs&&t&&(f?i(e,m,f):n<1&&I(s,h,p,n,i,e,a))}}}function M(r,i,n,a,s,l){var u=1;o(l)&&(u=p.clamp(Math.abs(l),.25,1));var c=r.minimumZoomDistance*u,d=r.maximumZoomDistance,h=s-c,f=a*h;f=p.clamp(f,r._minimumZoomRate,r._maximumZoomRate);var m=n.endPosition.y-n.startPosition.y,_=m/r._scene.canvas.clientHeight;_=Math.min(_,r.maximumMovementRatio);var v=f*_;if(!(v>0&&Math.abs(s-c)<1||v<0&&Math.abs(s-d)<1)){s-v<c?v=s-c-1:s-v>d&&(v=s-d);var y=r._scene,C=y.camera,b=y.mode,S=Ee.orientation;if(S.heading=C.heading,S.pitch=C.pitch,S.roll=C.roll,C.frustum instanceof g)return void(Math.abs(v)>0&&(C.zoomIn(v),C._adjustOrthographicFrustum()));var w,E=e.equals(i,r._zoomMouseStart),x=r._zoomingOnVector,P=r._rotatingZoom;if(E||(r._zoomMouseStart=e.clone(i,r._zoomMouseStart),o(r._globe)&&(w=b!==T.SCENE2D?B(r,i,ne):C.getPickRay(i,ie).origin),o(w)?(r._useZoomWorldPosition=!0,r._zoomWorldPosition=t.clone(w,r._zoomWorldPosition)):r._useZoomWorldPosition=!1,x=r._zoomingOnVector=!1,P=r._rotatingZoom=!1),!r._useZoomWorldPosition)return void C.zoomIn(v);var D=b===T.COLUMBUS_VIEW;if(C.positionCartographic.height<2e6&&(P=!0),!E||P){if(b===T.SCENE2D){var I=r._zoomWorldPosition,O=C.position;if(!t.equals(I,O)&&C.positionCartographic.height<2*r._maxCoord.x){var M=C.position.x,R=t.subtract(I,O,ae);t.normalize(R,R);var N=t.distance(I,O)*v/(.5*C.getMagnitude());C.move(R,.5*N),(C.position.x<0&&M>0||C.position.x>0&&M<0)&&(w=C.getPickRay(i,ie).origin,r._zoomWorldPosition=t.clone(w,r._zoomWorldPosition))}}else if(b===T.SCENE3D){var L=t.normalize(C.position,he);if(C.positionCartographic.height<3e3&&Math.abs(t.dot(C.direction,L))<.6)D=!0;else{var k=y.canvas,F=se;F.x=k.clientWidth/2,F.y=k.clientHeight/2;var U=B(r,F,le);if(o(U)&&C.positionCartographic.height<1e6){var V=fe;t.clone(C.position,V);var z=r._zoomWorldPosition,G=pe;if(G=t.normalize(z,G),t.dot(G,L)<0)return;var H=Se,W=_e;t.clone(C.direction,W),t.add(V,t.multiplyByScalar(W,1e3,we),H);var j=ve,q=ye;t.subtract(z,V,j),t.normalize(j,q);var Y=t.dot(L,q);if(Y>=0)return void(r._zoomMouseStart.x=-1);var X=Math.acos(-Y),Q=t.magnitude(V),Z=t.magnitude(z),K=Q-v,J=t.magnitude(j),$=Math.asin(p.clamp(J/Z*Math.sin(X),-1,1)),ee=Math.asin(p.clamp(K/Z*Math.sin(X),-1,1)),te=$-ee+X,re=me;t.normalize(V,re);var xe=ge;xe=t.cross(q,re,xe),xe=t.normalize(xe,xe),t.normalize(t.cross(re,xe,we),W),t.multiplyByScalar(t.normalize(H,we),t.magnitude(H)-v,H),t.normalize(V,V),t.multiplyByScalar(V,K,V);var Pe=Ce;t.multiplyByScalar(t.add(t.multiplyByScalar(re,Math.cos(te)-1,Te),t.multiplyByScalar(W,Math.sin(te),Ae),we),K,Pe),t.add(V,Pe,V),t.normalize(H,re),t.normalize(t.cross(re,xe,we),W);var De=be;return t.multiplyByScalar(t.add(t.multiplyByScalar(re,Math.cos(te)-1,Te),t.multiplyByScalar(W,Math.sin(te),Ae),we),t.magnitude(H),De),t.add(H,De,H),t.clone(V,C.position),t.normalize(t.subtract(H,V,we),C.direction),t.clone(C.direction,C.direction),t.cross(C.direction,C.up,C.right),t.cross(C.right,C.direction,C.up),void C.setView(Ee)}if(o(U)){var Ie=t.normalize(U,ue),Oe=t.normalize(r._zoomWorldPosition,ce),Me=t.dot(Oe,Ie);if(Me>0&&Me<1){var Re=p.acosClamped(Me),Ne=t.cross(Oe,Ie,de),Le=Math.abs(Re)>p.toRadians(20)?.75*C.positionCartographic.height:C.positionCartographic.height-v,ke=v/Le;C.rotate(Ne,Re*ke)}}else D=!0}}r._rotatingZoom=!D}if(!E&&D||x){var Fe,Be=A.wgs84ToWindowCoordinates(y,r._zoomWorldPosition,oe);Fe=b!==T.COLUMBUS_VIEW&&e.equals(i,r._zoomMouseStart)&&o(Be)?C.getPickRay(Be,ie):C.getPickRay(i,ie);var Ue=Fe.direction;b===T.COLUMBUS_VIEW&&t.fromElements(Ue.y,Ue.z,Ue.x,Ue),C.move(Ue,v),r._zoomingOnVector=!0}else C.zoomIn(v);C.setView(Ee)}}function R(e,r,i){var n=e._scene,o=n.camera,a=o.getPickRay(i.startPosition,xe).origin,s=o.getPickRay(i.endPosition,Pe).origin,l=t.subtract(a,s,De),u=t.magnitude(l);u>0&&(t.normalize(l,l),o.move(l,u))}function N(e,t,r){o(r.distance)&&(r=r.distance);var i=e._scene,n=i.camera;M(e,t,r,e._zoomFactor,n.getMagnitude())}function L(t,r,i){if(o(i.angleAndHeight))return void k(t,r,i.angleAndHeight);var n=t._scene,a=n.camera,s=n.canvas,l=s.clientWidth,u=s.clientHeight,c=Ie;c.x=2/l*i.startPosition.x-1,c.y=2/u*(u-i.startPosition.y)-1,c=e.normalize(c,c);var d=Oe;d.x=2/l*i.endPosition.x-1,d.y=2/u*(u-i.endPosition.y)-1,d=e.normalize(d,d);var h=p.acosClamped(c.x);c.y<0&&(h=p.TWO_PI-h);var f=p.acosClamped(d.x);d.y<0&&(f=p.TWO_PI-f);var m=f-h;a.twistRight(m)}function k(e,t,r){var i=e._rotateFactor*e._rotateRateRangeAdjustment;i>e._maximumRotateRate&&(i=e._maximumRotateRate),i<e._minimumRotateRate&&(i=e._minimumRotateRate);var n=e._scene,o=n.camera,a=n.canvas,s=(r.endPosition.x-r.startPosition.x)/a.clientWidth;s=Math.min(s,e.maximumMovementRatio);var l=i*s*Math.PI*4;o.twistRight(l)}function F(e){var t=e._scene.mapMode2D===w.ROTATE;m.equals(m.IDENTITY,e._scene.camera.transform)?(O(e,e.enableTranslate,e.translateEventTypes,R,e.inertiaTranslate,"_lastInertiaTranslateMovement"),O(e,e.enableZoom,e.zoomEventTypes,N,e.inertiaZoom,"_lastInertiaZoomMovement"),t&&O(e,e.enableRotate,e.tiltEventTypes,L,e.inertiaSpin,"_lastInertiaTiltMovement")):(O(e,e.enableZoom,e.zoomEventTypes,N,e.inertiaZoom,"_lastInertiaZoomMovement"),t&&O(e,e.enableRotate,e.translateEventTypes,L,e.inertiaSpin,"_lastInertiaSpinMovement"))}function B(e,r,i){var n=e._scene,a=e._globe,s=n.camera;if(o(a)){var l;n.pickPositionSupported&&(l=n.pickPositionWorldCoordinates(r,Re));var u=s.getPickRay(r,Me),c=a.pick(u,n,Ne);return(o(l)?t.distance(l,s.positionWC):Number.POSITIVE_INFINITY)<(o(c)?t.distance(c,s.positionWC):Number.POSITIVE_INFINITY)?t.clone(l,i):t.clone(c,i)}}function U(r,i,n){if(t.equals(i,r._translateMousePosition)||(r._looking=!1),t.equals(i,r._strafeMousePosition)||(r._strafing=!1),r._looking)return void $(r,i,n);if(r._strafing)return void j(r,i,n);var a,s=r._scene,l=s.camera,u=e.clone(n.startPosition,Ge),d=e.clone(n.endPosition,He),h=l.getPickRay(u,Le),f=t.clone(t.ZERO,Ve),m=t.UNIT_X;if(l.position.z<r._minimumPickingTerrainHeight&&(a=B(r,u,Fe),o(a)&&(f.x=a.x)),f.x>l.position.z&&o(a))return t.clone(a,r._strafeStartPosition),r._strafing=!0,j(r,i,n),void(r._strafeMousePosition=e.clone(i,r._strafeMousePosition));var g=_.fromPointNormal(f,m,ze);h=l.getPickRay(u,Le);var v=c.rayPlane(h,g,Fe),y=l.getPickRay(d,ke),C=c.rayPlane(y,g,Be);if(!o(v)||!o(C))return r._looking=!0,$(r,i,n),void e.clone(i,r._translateMousePosition);var b=t.subtract(v,C,Ue),S=b.x;b.x=b.y,b.y=b.z,b.z=S;var w=t.magnitude(b);w>p.EPSILON6&&(t.normalize(b,b),l.move(b,w))}function V(t,r,i){if(o(i.angleAndHeight)&&(i=i.angleAndHeight),e.equals(r,t._tiltCenterMousePosition)||(t._tiltCVOffMap=!1,t._looking=!1),t._looking)return void $(t,r,i);var n=t._scene,a=n.camera,s=t._maxCoord,l=Math.abs(a.position.x)-s.x<0&&Math.abs(a.position.y)-s.y<0;t._tiltCVOffMap||!l||a.position.z>t._minimumPickingTerrainHeight?(t._tiltCVOffMap=!0,z(t,r,i)):G(t,r,i)}function z(r,i,n){var a=r._scene,s=a.camera,u=a.canvas,c=We;c.x=u.clientWidth/2,c.y=u.clientHeight/2;var d,h=s.getPickRay(c,je),f=t.UNIT_X,g=h.origin,_=h.direction,v=t.dot(f,_);if(Math.abs(v)>p.EPSILON6&&(d=-t.dot(f,g)/v),!o(d)||d<=0)return r._looking=!0,$(r,i,n),void e.clone(i,r._tiltCenterMousePosition);var y=t.multiplyByScalar(_,d,qe);t.add(g,y,y);var b=a.mapProjection,S=b.ellipsoid;t.fromElements(y.y,y.z,y.x,y);var w=b.unproject(y,$e);S.cartographicToCartesian(w,y);var T=C.eastNorthUpToFixedFrame(y,S,Xe),A=r._globe,E=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var x=m.clone(s.transform,et);s._setTransform(T),Y(r,i,n,t.UNIT_Z),s._setTransform(x),r._globe=A,r._ellipsoid=E;var P=E.maximumRadius;r._rotateFactor=1/P,r._rotateRateRangeAdjustment=P}function G(r,i,n){var a,s,u=r._scene,d=u.camera,h=t.UNIT_X;if(e.equals(i,r._tiltCenterMousePosition))a=t.clone(r._tiltCenter,qe);else{if(d.position.z<r._minimumPickingTerrainHeight&&(a=B(r,i,qe)),!o(a)){s=d.getPickRay(i,je);var g,y=s.origin,b=s.direction,S=t.dot(h,b);if(Math.abs(S)>p.EPSILON6&&(g=-t.dot(h,y)/S),!o(g)||g<=0)return r._looking=!0,$(r,i,n),void e.clone(i,r._tiltCenterMousePosition);a=t.multiplyByScalar(b,g,qe),t.add(y,a,a)}e.clone(i,r._tiltCenterMousePosition),t.clone(a,r._tiltCenter)}var w=u.canvas,T=We;T.x=w.clientWidth/2,T.y=r._tiltCenterMousePosition.y,s=d.getPickRay(T,je);var A=t.clone(t.ZERO,Ze);A.x=a.x;var E=_.fromPointNormal(A,h,Ke),x=c.rayPlane(s,E,Ye),P=d._projection,D=P.ellipsoid;t.fromElements(a.y,a.z,a.x,a);var I=P.unproject(a,$e);D.cartographicToCartesian(I,a);var O,M=C.eastNorthUpToFixedFrame(a,D,Xe);o(x)?(t.fromElements(x.y,x.z,x.x,x),I=P.unproject(x,$e),D.cartographicToCartesian(I,x),O=C.eastNorthUpToFixedFrame(x,D,Qe)):O=M;var R=r._globe,N=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE, -r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var L=t.UNIT_Z,k=m.clone(d.transform,et);d._setTransform(M);var F=t.cross(t.UNIT_Z,t.normalize(d.position,Je),Je),U=t.dot(d.right,F);if(Y(r,i,n,L,!1,!0),d._setTransform(O),U<0){n.startPosition.y>n.endPosition.y&&(L=void 0);var V=d.constrainedAxis;d.constrainedAxis=void 0,Y(r,i,n,L,!0,!1),d.constrainedAxis=V}else Y(r,i,n,L,!0,!1);if(o(d.constrainedAxis)){var z=t.cross(d.direction,d.constrainedAxis,it);t.equalsEpsilon(z,t.ZERO,p.EPSILON6)||(t.dot(z,d.right)<0&&t.negate(z,z),t.cross(z,d.direction,d.up),t.cross(d.direction,d.up,d.right),t.normalize(d.up,d.up),t.normalize(d.right,d.right))}d._setTransform(k),r._globe=R,r._ellipsoid=N;var G=N.maximumRadius;r._rotateFactor=1/G,r._rotateRateRangeAdjustment=G;var H=t.clone(d.positionWC,Je);if(d._adjustHeightForTerrain(),!t.equals(d.positionWC,H)){d._setTransform(O),d.worldToCameraCoordinatesPoint(H,H);var W=t.magnitudeSquared(H);t.magnitudeSquared(d.position)>W&&(t.normalize(d.position,d.position),t.multiplyByScalar(d.position,Math.sqrt(W),d.position));var j=t.angleBetween(H,d.position),q=t.cross(H,d.position,H);t.normalize(q,q);var X=v.fromAxisAngle(q,j,tt),Q=f.fromQuaternion(X,rt);f.multiplyByVector(Q,d.direction,d.direction),f.multiplyByVector(Q,d.up,d.up),t.cross(d.direction,d.up,d.right),t.cross(d.right,d.direction,d.up),d._setTransform(k)}}function H(e,r,i){o(i.distance)&&(i=i.distance);var n=e._scene,a=n.camera,s=n.canvas,l=nt;l.x=s.clientWidth/2,l.y=s.clientHeight/2;var u,c=a.getPickRay(l,ot);a.position.z<e._minimumPickingTerrainHeight&&(u=B(e,l,at));var d;if(o(u))d=t.distance(c.origin,u);else{var h=t.UNIT_X,p=c.origin,f=c.direction;d=-t.dot(h,p)/t.dot(h,f)}M(e,r,i,e._zoomFactor,d)}function W(e){var t=e._scene,r=t.camera;if(m.equals(m.IDENTITY,r.transform)){var i=e._tweens;if(e._aggregator.anyButtonDown&&i.removeAll(),O(e,e.enableTilt,e.tiltEventTypes,V,e.inertiaSpin,"_lastInertiaTiltMovement"),O(e,e.enableTranslate,e.translateEventTypes,U,e.inertiaTranslate,"_lastInertiaTranslateMovement"),O(e,e.enableZoom,e.zoomEventTypes,H,e.inertiaZoom,"_lastInertiaZoomMovement"),O(e,e.enableLook,e.lookEventTypes,$),!(e._aggregator.anyButtonDown||o(e._lastInertiaZoomMovement)&&e._lastInertiaZoomMovement.active||o(e._lastInertiaTranslateMovement)&&e._lastInertiaTranslateMovement.active||i.contains(e._tween))){var n=r.createCorrectPositionTween(e.bounceAnimationTime);o(n)&&(e._tween=i.add(n))}i.update()}else O(e,e.enableRotate,e.rotateEventTypes,Y,e.inertiaSpin,"_lastInertiaSpinMovement"),O(e,e.enableZoom,e.zoomEventTypes,Q,e.inertiaZoom,"_lastInertiaZoomMovement")}function j(e,r,i){var n=e._scene,a=n.camera,s=B(e,i.startPosition,dt);if(o(s)){var l=i.endPosition,u=a.getPickRay(l,st),d=t.clone(a.direction,ct);n.mode===T.COLUMBUS_VIEW&&t.fromElements(d.z,d.x,d.y,d);var h=_.fromPointNormal(s,d,lt),p=c.rayPlane(u,h,ut);o(p)&&(d=t.subtract(s,p,d),n.mode===T.COLUMBUS_VIEW&&t.fromElements(d.y,d.z,d.x,d),t.add(a.position,d,a.position))}}function q(r,i,n){var a=r._scene,s=a.camera;if(!m.equals(s.transform,m.IDENTITY))return void Y(r,i,n);var u,c,d,h,p=r._ellipsoid.geodeticSurfaceNormal(s.position,gt),f=r._ellipsoid.cartesianToCartographic(s.positionWC,pt).height,g=r._globe,_=!1;if(o(g)&&f<r._minimumPickingTerrainHeight&&(h=B(r,n.startPosition,dt),o(h))){var v=s.getPickRay(n.startPosition,Me),y=r._ellipsoid.geodeticSurfaceNormal(h);_=Math.abs(t.dot(v.direction,y))<.05,_&&!r._looking&&(r._rotating=!1,r._strafing=!0)}if(e.equals(i,r._rotateMousePosition))return void(r._looking?$(r,i,n,p):r._rotating?Y(r,i,n):r._strafing?(t.clone(h,r._strafeStartPosition),j(r,i,n)):(u=t.magnitude(r._rotateStartPosition),c=ft,c.x=c.y=c.z=u,d=l.fromCartesian3(c,mt),X(r,i,n,d)));r._looking=!1,r._rotating=!1,r._strafing=!1,o(g)&&f<r._minimumPickingTerrainHeight?o(h)?t.magnitude(s.position)<t.magnitude(h)?(t.clone(h,r._strafeStartPosition),r._strafing=!0,j(r,i,n)):(u=t.magnitude(h),c=ft,c.x=c.y=c.z=u,d=l.fromCartesian3(c,mt),X(r,i,n,d),t.clone(h,r._rotateStartPosition)):(r._looking=!0,$(r,i,n,p)):o(s.pickEllipsoid(n.startPosition,r._ellipsoid,ht))?(X(r,i,n,r._ellipsoid),t.clone(ht,r._rotateStartPosition)):f>r._minimumTrackBallHeight?(r._rotating=!0,Y(r,i,n)):(r._looking=!0,$(r,i,n,p)),e.clone(i,r._rotateMousePosition)}function Y(e,r,i,a,s,l){s=n(s,!1),l=n(l,!1);var u=e._scene,c=u.camera,d=u.canvas,h=c.constrainedAxis;o(a)&&(c.constrainedAxis=a);var p=t.magnitude(c.position),f=e._rotateFactor*(p-e._rotateRateRangeAdjustment);f>e._maximumRotateRate&&(f=e._maximumRotateRate),f<e._minimumRotateRate&&(f=e._minimumRotateRate);var m=(i.startPosition.x-i.endPosition.x)/d.clientWidth,g=(i.startPosition.y-i.endPosition.y)/d.clientHeight;m=Math.min(m,e.maximumMovementRatio),g=Math.min(g,e.maximumMovementRatio);var _=f*m*Math.PI*2,v=f*g*Math.PI;s||c.rotateRight(_),l||c.rotateUp(v),c.constrainedAxis=h}function X(r,i,n,a){var s=r._scene,l=s.camera,u=e.clone(n.startPosition,wt),c=e.clone(n.endPosition,Tt),d=l.pickEllipsoid(u,a,_t),h=l.pickEllipsoid(c,a,vt);if(!o(d)||!o(h))return r._rotating=!0,void Y(r,i,n);if(d=l.worldToCameraCoordinates(d,d),h=l.worldToCameraCoordinates(h,h),o(l.constrainedAxis)){var f=l.constrainedAxis,m=t.mostOrthogonalAxis(f,yt);t.cross(m,f,m),t.normalize(m,m);var g=t.cross(f,m,Ct),_=t.magnitude(d),v=t.dot(f,d),y=Math.acos(v/_),C=t.multiplyByScalar(f,v,bt);t.subtract(d,C,C),t.normalize(C,C);var b=t.magnitude(h),S=t.dot(f,h),w=Math.acos(S/b),T=t.multiplyByScalar(f,S,St);t.subtract(h,T,T),t.normalize(T,T);var A=Math.acos(t.dot(C,m));t.dot(C,g)<0&&(A=p.TWO_PI-A);var E=Math.acos(t.dot(T,m));t.dot(T,g)<0&&(E=p.TWO_PI-E);var x,P=A-E;x=t.equalsEpsilon(f,l.position,p.EPSILON2)?l.right:t.cross(f,l.position,yt);var D,I=t.cross(f,x,yt),O=t.dot(I,t.subtract(d,f,Ct)),M=t.dot(I,t.subtract(h,f,Ct));D=O>0&&M>0?w-y:O>0&&M<=0?t.dot(l.position,f)>0?-y-w:y+w:y-w,l.rotateRight(P),l.rotateUp(D)}else{t.normalize(d,d),t.normalize(h,h);var R=t.dot(d,h),N=t.cross(d,h,yt);if(R<1&&!t.equalsEpsilon(N,t.ZERO,p.EPSILON14)){var L=Math.acos(R);l.rotate(N,L)}}}function Q(e,r,i){o(i.distance)&&(i=i.distance);var n=e._ellipsoid,a=e._scene,s=a.camera,l=a.canvas,u=nt;u.x=l.clientWidth/2,u.y=l.clientHeight/2;var c,d=s.getPickRay(u,ot),h=n.cartesianToCartographic(s.position,Et).height;h<e._minimumPickingTerrainHeight&&(c=B(e,u,at));var p;p=o(c)?t.distance(d.origin,c):h;var f=t.normalize(s.position,At);M(e,r,i,e._zoomFactor,p,t.dot(f,s.direction))}function Z(t,r,i){var n=t._scene,a=n.camera;if(m.equals(a.transform,m.IDENTITY)){if(o(i.angleAndHeight)&&(i=i.angleAndHeight),e.equals(r,t._tiltCenterMousePosition)||(t._tiltOnEllipsoid=!1,t._looking=!1),t._looking){return void $(t,r,i,t._ellipsoid.geodeticSurfaceNormal(a.position,Ft))}var s=t._ellipsoid,l=s.cartesianToCartographic(a.position,kt);t._tiltOnEllipsoid||l.height>t._minimumCollisionTerrainHeight?(t._tiltOnEllipsoid=!0,K(t,r,i)):J(t,r,i)}}function K(r,i,n){var a=r._ellipsoid,s=r._scene,u=s.camera,d=.25*r.minimumZoomDistance,h=a.cartesianToCartographic(u.positionWC,Bt).height;if(!(h-d-1<p.EPSILON3&&n.endPosition.y-n.startPosition.y<0)){var f=s.canvas,g=xt;g.x=f.clientWidth/2,g.y=f.clientHeight/2;var _,v=u.getPickRay(g,Pt),b=c.rayEllipsoid(v,a);if(o(b))_=y.getPoint(v,b.start,Dt);else{if(!(h>r._minimumTrackBallHeight)){r._looking=!0;return $(r,i,n,r._ellipsoid.geodeticSurfaceNormal(u.position,Ft)),void e.clone(i,r._tiltCenterMousePosition)}var S=c.grazingAltitudeLocation(v,a);if(!o(S))return;var w=a.cartesianToCartographic(S,kt);w.height=0,_=a.cartographicToCartesian(w,Dt)}var T=C.eastNorthUpToFixedFrame(_,a,Ot),A=r._globe,E=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var x=m.clone(u.transform,Rt);u._setTransform(T),Y(r,i,n,t.UNIT_Z),u._setTransform(x),r._globe=A,r._ellipsoid=E;var P=E.maximumRadius;r._rotateFactor=1/P,r._rotateRateRangeAdjustment=P}}function J(r,i,n){var a,s,u,d=r._ellipsoid,h=r._scene,g=h.camera;if(e.equals(i,r._tiltCenterMousePosition))a=t.clone(r._tiltCenter,Dt);else{if(a=B(r,i,Dt),!o(a)){if(s=g.getPickRay(i,Pt),u=c.rayEllipsoid(s,d),!o(u)){if(d.cartesianToCartographic(g.position,kt).height<=r._minimumTrackBallHeight){r._looking=!0;$(r,i,n,r._ellipsoid.geodeticSurfaceNormal(g.position,Ft)),e.clone(i,r._tiltCenterMousePosition)}return}a=y.getPoint(s,u.start,Dt)}e.clone(i,r._tiltCenterMousePosition),t.clone(a,r._tiltCenter)}var _=h.canvas,b=xt;b.x=_.clientWidth/2,b.y=r._tiltCenterMousePosition.y,s=g.getPickRay(b,Pt);var S=t.magnitude(a),w=t.fromElements(S,S,S,ft),T=l.fromCartesian3(w,mt);if(u=c.rayEllipsoid(s,T),o(u)){var A=t.magnitude(s.origin)>S?u.start:u.stop,E=y.getPoint(s,A,It),x=C.eastNorthUpToFixedFrame(a,d,Ot),P=C.eastNorthUpToFixedFrame(E,T,Mt),D=r._globe,I=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var O=t.UNIT_Z,M=m.clone(g.transform,Rt);g._setTransform(x);var R=t.cross(E,g.positionWC,it),N=t.dot(g.rightWC,R);if(Y(r,i,n,O,!1,!0),g._setTransform(P),N<0){n.startPosition.y>n.endPosition.y&&(O=void 0);var L=g.constrainedAxis;g.constrainedAxis=void 0,Y(r,i,n,O,!0,!1),g.constrainedAxis=L}else Y(r,i,n,O,!0,!1);if(o(g.constrainedAxis)){var k=t.cross(g.direction,g.constrainedAxis,it);t.equalsEpsilon(k,t.ZERO,p.EPSILON6)||(t.dot(k,g.right)<0&&t.negate(k,k),t.cross(k,g.direction,g.up),t.cross(g.direction,g.up,g.right),t.normalize(g.up,g.up),t.normalize(g.right,g.right))}g._setTransform(M),r._globe=D,r._ellipsoid=I;var F=I.maximumRadius;r._rotateFactor=1/F,r._rotateRateRangeAdjustment=F;var U=t.clone(g.positionWC,it);if(g._adjustHeightForTerrain(),!t.equals(g.positionWC,U)){g._setTransform(P),g.worldToCameraCoordinatesPoint(U,U);var V=t.magnitudeSquared(U);t.magnitudeSquared(g.position)>V&&(t.normalize(g.position,g.position),t.multiplyByScalar(g.position,Math.sqrt(V),g.position));var z=t.angleBetween(U,g.position),G=t.cross(U,g.position,U);t.normalize(G,G);var H=v.fromAxisAngle(G,z,Nt),W=f.fromQuaternion(H,Lt);f.multiplyByVector(W,g.direction,g.direction),f.multiplyByVector(W,g.up,g.up),t.cross(g.direction,g.up,g.right),t.cross(g.right,g.direction,g.up),g._setTransform(M)}}}function $(e,r,i,a){var s=e._scene,l=s.camera,u=Ut;u.x=i.startPosition.x,u.y=0;var c=Vt;c.x=i.endPosition.x,c.y=0;var d,h,f=l.getPickRay(u,zt),m=l.getPickRay(c,Gt),_=0;l.frustum instanceof g?(d=f.origin,h=m.origin,t.add(l.direction,d,d),t.add(l.direction,h,h),t.subtract(d,l.position,d),t.subtract(h,l.position,h),t.normalize(d,d),t.normalize(h,h)):(d=f.direction,h=m.direction);var v=t.dot(d,h);v<1&&(_=Math.acos(v)),_=i.startPosition.x>i.endPosition.x?-_:_;var y=e._horizontalRotationAxis;if(o(a)?l.look(a,-_):o(y)?l.look(y,-_):l.lookLeft(_),u.x=0,u.y=i.startPosition.y,c.x=0,c.y=i.endPosition.y,f=l.getPickRay(u,zt),m=l.getPickRay(c,Gt),_=0,l.frustum instanceof g?(d=f.origin,h=m.origin,t.add(l.direction,d,d),t.add(l.direction,h,h),t.subtract(d,l.position,d),t.subtract(h,l.position,h),t.normalize(d,d),t.normalize(h,h)):(d=f.direction,h=m.direction),v=t.dot(d,h),v<1&&(_=Math.acos(v)),_=i.startPosition.y>i.endPosition.y?-_:_,a=n(a,y),o(a)){var C=l.direction,b=t.negate(a,Ht),S=t.equalsEpsilon(C,a,p.EPSILON2),w=t.equalsEpsilon(C,b,p.EPSILON2);if(S||w)(S&&_<0||w&&_>0)&&l.look(l.right,-_);else{v=t.dot(C,a);var T=p.acosClamped(v);_>0&&_>T&&(_=T-p.EPSILON4),v=t.dot(C,b),T=p.acosClamped(v),_<0&&-_>T&&(_=-T+p.EPSILON4);var A=t.cross(a,C,Wt);l.look(A,_)}}else l.lookUp(_)}function ee(e){O(e,e.enableRotate,e.rotateEventTypes,q,e.inertiaSpin,"_lastInertiaSpinMovement"),O(e,e.enableZoom,e.zoomEventTypes,Q,e.inertiaZoom,"_lastInertiaZoomMovement"),O(e,e.enableTilt,e.tiltEventTypes,Z,e.inertiaSpin,"_lastInertiaTiltMovement"),O(e,e.enableLook,e.lookEventTypes,$)}var te=.4,re=[],ie=new y,ne=new t,oe=new e,ae=new t,se=new e,le=new t,ue=new t,ce=new t,de=new t,he=new t,pe=new t,fe=new t,me=new t,ge=new t,_e=new t,ve=new t,ye=new t,Ce=new t,be=new t,Se=new t,we=new t,Te=new t,Ae=new t,Ee={orientation:new u},xe=new y,Pe=new y,De=new t,Ie=new e,Oe=new e,Me=new y,Re=new t,Ne=new t,Le=new y,ke=new y,Fe=new t,Be=new t,Ue=new t,Ve=new t,ze=new _(t.UNIT_X,0),Ge=new e,He=new e,We=new e,je=new y,qe=new t,Ye=new t,Xe=new m,Qe=new m,Ze=new t,Ke=new _(t.UNIT_X,0),Je=new t,$e=new i,et=new m,tt=new v,rt=new f,it=new t,nt=new e,ot=new y,at=new t,st=new y,lt=new _(t.UNIT_X,0),ut=new t,ct=new t,dt=new t,ht=new t,pt=new i,ft=new t,mt=new l,gt=new t,_t=r.clone(r.UNIT_W),vt=r.clone(r.UNIT_W),yt=new t,Ct=new t,bt=new t,St=new t,wt=new e,Tt=new e,At=new t,Et=new i,xt=new e,Pt=new y,Dt=new t,It=new t,Ot=new m,Mt=new m,Rt=new m,Nt=new v,Lt=new f,kt=new i,Ft=new t,Bt=new i,Ut=new e,Vt=new e,zt=new y,Gt=new y,Ht=new t,Wt=new t;return x.prototype.update=function(){m.equals(this._scene.camera.transform,m.IDENTITY)?(this._globe=this._scene.globe,this._ellipsoid=o(this._globe)?this._globe.ellipsoid:this._scene.mapProjection.ellipsoid):(this._globe=void 0,this._ellipsoid=l.UNIT_SPHERE),this._minimumCollisionTerrainHeight=this.minimumCollisionTerrainHeight*this._scene.terrainExaggeration,this._minimumPickingTerrainHeight=this.minimumPickingTerrainHeight*this._scene.terrainExaggeration,this._minimumTrackBallHeight=this.minimumTrackBallHeight*this._scene.terrainExaggeration;var e=this._ellipsoid.maximumRadius;this._rotateFactor=1/e,this._rotateRateRangeAdjustment=e;var r=this._scene,i=r.mode;i===T.SCENE2D?F(this):i===T.COLUMBUS_VIEW?(this._horizontalRotationAxis=t.UNIT_Z,W(this)):i===T.SCENE3D&&(this._horizontalRotationAxis=void 0,ee(this)),this._aggregator.reset()},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){return this._tweens.removeAll(),this._aggregator=this._aggregator&&this._aggregator.destroy(),a(this)},x}),define("Scene/ShadowMapShader",["../Core/defined","../Renderer/ShaderSource"],function(e,t){"use strict";function r(){}return r.getShadowCastShaderKeyword=function(e,t,r,i){return"castShadow "+e+" "+t+" "+r+" "+i},r.createShadowCastVertexShader=function(r,i,n){var o=r.defines.slice(0),a=r.sources.slice(0);n&&o.push("GENERATE_POSITION");var s=t.findPositionVarying(r),l=e(s);if(i&&!l){for(var u=a.length,c=0;c<u;++c)a[c]=t.replaceMain(a[c],"czm_shadow_cast_main");a.push("varying vec3 v_positionEC; \nvoid main() \n{ \n czm_shadow_cast_main(); \n v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n}")}return new t({defines:o,sources:a})},r.createShadowCastFragmentShader=function(r,i,n,o){var a=r.defines.slice(0),s=r.sources.slice(0),l=t.findPositionVarying(r),u=e(l);u||(l="v_positionEC");for(var c=s.length,d=0;d<c;++d)s[d]=t.replaceMain(s[d],"czm_shadow_cast_main");var h="";return i&&(u||(h+="varying vec3 v_positionEC; \n"),h+="uniform vec4 shadowMap_lightPositionEC; \n"),h+=o?"void main() \n{ \n":"void main() \n{ \n czm_shadow_cast_main(); \n if (gl_FragColor.a == 0.0) \n { \n discard; \n } \n",h+=i?"float distance = length("+l+"); \ndistance /= shadowMap_lightPositionEC.w; // radius \ngl_FragColor = czm_packDepth(distance); \n":n?"gl_FragColor = vec4(1.0); \n":"gl_FragColor = czm_packDepth(gl_FragCoord.z); \n",h+="} \n",s.push(h),new t({defines:a,sources:s})},r.getShadowReceiveShaderKeyword=function(e,t,r,i){return"receiveShadow "+e._usesDepthTexture+e._polygonOffsetSupported+e._isPointLight+e._isSpotLight+(e._numberOfCascades>1)+e.debugCascadeColors+e.softShadows+t+r+i},r.createShadowReceiveVertexShader=function(e,r,i){var n=e.defines.slice(0),o=e.sources.slice(0);return r&&(i?n.push("GENERATE_POSITION_AND_NORMAL"):n.push("GENERATE_POSITION")),new t({defines:n,sources:o})},r.createShadowReceiveFragmentShader=function(r,i,n,o,a){for(var s=t.findNormalVarying(r),l=!o&&e(s)||o&&a,u=t.findPositionVarying(r),c=e(u),d=i._usesDepthTexture,h=i._polygonOffsetSupported,p=i._isPointLight,f=i._isSpotLight,m=i._numberOfCascades>1,g=i.debugCascadeColors,_=i.softShadows,v=p?i._pointBias:o?i._terrainBias:i._primitiveBias,y=r.defines.slice(0),C=r.sources.slice(0),b=C.length,S=0;S<b;++S)C[S]=t.replaceMain(C[S],"czm_shadow_receive_main");p?y.push("USE_CUBE_MAP_SHADOW"):d&&y.push("USE_SHADOW_DEPTH_TEXTURE"),_&&!p&&y.push("USE_SOFT_SHADOWS"),m&&n&&o&&(l?y.push("ENABLE_VERTEX_LIGHTING"):y.push("ENABLE_DAYNIGHT_SHADING")),n&&v.normalShading&&l&&(y.push("USE_NORMAL_SHADING"),v.normalShadingSmooth>0&&y.push("USE_NORMAL_SHADING_SMOOTH"));var w="";return w+=p?"uniform samplerCube shadowMap_textureCube; \n":"uniform sampler2D shadowMap_texture; \n",w+="uniform mat4 shadowMap_matrix; \nuniform vec3 shadowMap_lightDirectionEC; \nuniform vec4 shadowMap_lightPositionEC; \nuniform vec4 shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness; \nuniform vec4 shadowMap_texelSizeDepthBiasAndNormalShadingSmooth; \nvec4 getPositionEC() \n{ \n"+(c?" return vec4("+u+", 1.0); \n":" return czm_windowToEyeCoordinates(gl_FragCoord); \n")+"} \nvec3 getNormalEC() \n{ \n"+(l?" return normalize("+s+"); \n":" return vec3(1.0); \n")+"} \nvoid applyNormalOffset(inout vec4 positionEC, vec3 normalEC, float nDotL) \n{ \n"+(v.normalOffset&&l?" float normalOffset = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.x; \n float normalOffsetScale = 1.0 - nDotL; \n vec3 offset = normalOffset * normalOffsetScale * normalEC; \n positionEC.xyz += offset; \n":"")+"} \n",w+="void main() \n{ \n czm_shadow_receive_main(); \n vec4 positionEC = getPositionEC(); \n vec3 normalEC = getNormalEC(); \n float depth = -positionEC.z; \n",w+=" czm_shadowParameters shadowParameters; \n shadowParameters.texelStepSize = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.xy; \n shadowParameters.depthBias = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.z; \n shadowParameters.normalShadingSmooth = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.w; \n shadowParameters.darkness = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.w; \n",o?w+=" shadowParameters.depthBias *= max(depth * 0.01, 1.0); \n":h||(w+=" shadowParameters.depthBias *= mix(1.0, 100.0, depth * 0.0015); \n"),w+=p?" vec3 directionEC = positionEC.xyz - shadowMap_lightPositionEC.xyz; \n float distance = length(directionEC); \n directionEC = normalize(directionEC); \n float radius = shadowMap_lightPositionEC.w; \n // Stop early if the fragment is beyond the point light radius \n if (distance > radius) \n { \n return; \n } \n vec3 directionWC = czm_inverseViewRotation * directionEC; \n shadowParameters.depth = distance / radius; \n shadowParameters.nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n shadowParameters.texCoords = directionWC; \n float visibility = czm_shadowVisibility(shadowMap_textureCube, shadowParameters); \n":f?" vec3 directionEC = normalize(positionEC.xyz - shadowMap_lightPositionEC.xyz); \n float nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n applyNormalOffset(positionEC, normalEC, nDotL); \n vec4 shadowPosition = shadowMap_matrix * positionEC; \n // Spot light uses a perspective projection, so perform the perspective divide \n shadowPosition /= shadowPosition.w; \n // Stop early if the fragment is not in the shadow bounds \n if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n { \n return; \n } \n shadowParameters.texCoords = shadowPosition.xy; \n shadowParameters.depth = shadowPosition.z; \n shadowParameters.nDotL = nDotL; \n float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n":m?" float maxDepth = shadowMap_cascadeSplits[1].w; \n // Stop early if the eye depth exceeds the last cascade \n if (depth > maxDepth) \n { \n return; \n } \n // Get the cascade based on the eye-space depth \n vec4 weights = czm_cascadeWeights(depth); \n // Apply normal offset \n float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n applyNormalOffset(positionEC, normalEC, nDotL); \n // Transform position into the cascade \n vec4 shadowPosition = czm_cascadeMatrix(weights) * positionEC; \n // Get visibility \n shadowParameters.texCoords = shadowPosition.xy; \n shadowParameters.depth = shadowPosition.z; \n shadowParameters.nDotL = nDotL; \n float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n // Fade out shadows that are far away \n float shadowMapMaximumDistance = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.z; \n float fade = max((depth - shadowMapMaximumDistance * 0.8) / (shadowMapMaximumDistance * 0.2), 0.0); \n visibility = mix(visibility, 1.0, fade); \n"+(g?" // Draw cascade colors for debugging \n gl_FragColor *= czm_cascadeColor(weights); \n":""):" float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n applyNormalOffset(positionEC, normalEC, nDotL); \n vec4 shadowPosition = shadowMap_matrix * positionEC; \n // Stop early if the fragment is not in the shadow bounds \n if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n { \n return; \n } \n shadowParameters.texCoords = shadowPosition.xy; \n shadowParameters.depth = shadowPosition.z; \n shadowParameters.nDotL = nDotL; \n float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n",w+=" gl_FragColor.rgb *= visibility; \n} \n",C.push(w),new t({defines:y,sources:C})},r}),define("Scene/ShadowMap",["../Core/BoundingRectangle","../Core/BoundingSphere","../Core/BoxOutlineGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/clone","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/combine","../Core/CullingVolume","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/GeometryInstance","../Core/Intersect","../Core/Math","../Core/Matrix4","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/PixelFormat","../Core/Quaternion","../Core/SphereOutlineGeometry","../Core/WebGLConstants","../Renderer/ClearCommand","../Renderer/ContextLimits","../Renderer/CubeMap","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/Pass","../Renderer/PassState","../Renderer/PixelDatatype","../Renderer/Renderbuffer","../Renderer/RenderbufferFormat","../Renderer/RenderState","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","./Camera","./CullFace","./DebugCameraPrimitive","./PerInstanceColorAppearance","./Primitive","./ShadowMapShader"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H,W,j,q,Y,X,Q){"use strict";function Z(e){e=h(e,h.EMPTY_OBJECT);var r=e.context;this._enabled=h(e.enabled,!0),this._softShadows=h(e.softShadows,!1),this._normalOffset=h(e.normalOffset,!0),this.dirty=!0,this.fromLightSource=h(e.fromLightSource,!0),this.darkness=h(e.darkness,.3),this._darkness=this.darkness,this.maximumDistance=h(e.maximumDistance,5e3),this._outOfView=!1,this._outOfViewPrevious=!1,this._needsUpdate=!0;var a=!0;(_.isInternetExplorer()||_.isEdge()||(_.isChrome()||_.isFirefox())&&_.isWindows()&&!r.depthTexture)&&(a=!1),this._polygonOffsetSupported=a,this._terrainBias={polygonOffset:a,polygonOffsetFactor:1.1,polygonOffsetUnits:4,normalOffset:this._normalOffset,normalOffsetScale:.5,normalShading:!0,normalShadingSmooth:.3,depthBias:1e-4},this._primitiveBias={polygonOffset:a,polygonOffsetFactor:1.1,polygonOffsetUnits:4,normalOffset:this._normalOffset,normalOffsetScale:.1,normalShading:!0,normalShadingSmooth:.05,depthBias:2e-5},this._pointBias={polygonOffset:!1,polygonOffsetFactor:1.1,polygonOffsetUnits:4,normalOffset:this._normalOffset,normalOffsetScale:0,normalShading:!0,normalShadingSmooth:.1,depthBias:5e-4},this._depthAttachment=void 0,this._colorAttachment=void 0,this._shadowMapMatrix=new b,this._shadowMapTexture=void 0,this._lightDirectionEC=new n,this._lightPositionEC=new o,this._distance=0,this._lightCamera=e.lightCamera,this._shadowMapCamera=new fe,this._shadowMapCullingVolume=void 0,this._sceneCamera=void 0,this._boundingSphere=new t,this._isPointLight=h(e.isPointLight,!1),this._pointLightRadius=h(e.pointLightRadius,100),this._cascadesEnabled=!this._isPointLight&&h(e.cascadesEnabled,!0),this._numberOfCascades=this._cascadesEnabled?h(e.numberOfCascades,4):0,this._fitNearFar=!0,this._maximumCascadeDistances=[25,150,700,Number.MAX_VALUE],this._textureSize=new i,this._isSpotLight=!1,this._cascadesEnabled?this._shadowMapCamera.frustum=new S:p(this._lightCamera.frustum.fov)&&(this._isSpotLight=!0),this._cascadeSplits=[new o,new o],this._cascadeMatrices=[new b,new b,new b,new b],this._cascadeDistances=new o;var s;s=this._isPointLight?6:this._cascadesEnabled?this._numberOfCascades:1,this._passes=new Array(s);for(var u=0;u<s;++u)this._passes[u]=new K(r);this.debugShow=!1,this.debugFreezeFrame=!1,this._debugFreezeFrame=!1,this._debugCascadeColors=!1,this._debugLightFrustum=void 0,this._debugCameraFrustum=void 0,this._debugCascadeFrustums=new Array(this._numberOfCascades),this._debugShadowViewCommand=void 0,this._usesDepthTexture=r.depthTexture,this._isPointLight&&(this._usesDepthTexture=!1),this._primitiveRenderState=void 0,this._terrainRenderState=void 0,this._pointRenderState=void 0,$(this),this._clearCommand=new P({depth:1,color:new l}),this._clearPassState=new N(r),this._size=h(e.size,2048),this.size=this._size}function K(e){this.camera=new fe,this.passState=new N(e),this.framebuffer=void 0,this.textureOffsets=void 0,this.commandList=[],this.cullingVolume=void 0}function J(e,t){return B.fromCache({cull:{enabled:!0,face:j.BACK},depthTest:{enabled:!0},colorMask:{red:e,green:e,blue:e,alpha:e},depthMask:!0,polygonOffset:{enabled:t.polygonOffset,factor:t.polygonOffsetFactor,units:t.polygonOffsetUnits}})}function $(e){var t=!e._usesDepthTexture;e._primitiveRenderState=J(t,e._primitiveBias),e._terrainRenderState=J(t,e._terrainBias),e._pointRenderState=J(t,e._pointBias)}function ee(e){for(var t=e._passes.length,r=0;r<t;++r){var i=e._passes[r],n=i.framebuffer;p(n)&&!n.isDestroyed()&&n.destroy(),i.framebuffer=void 0}e._depthAttachment=e._depthAttachment&&e._depthAttachment.destroy(),e._colorAttachment=e._colorAttachment&&e._colorAttachment.destroy()}function te(){return new U({wrapS:H.CLAMP_TO_EDGE,wrapT:H.CLAMP_TO_EDGE,minificationFilter:G.NEAREST,magnificationFilter:z.NEAREST})}function re(e,t){for(var r=new k({context:t,width:e._textureSize.x,height:e._textureSize.y,format:F.DEPTH_COMPONENT16}),i=new V({context:t,width:e._textureSize.x,height:e._textureSize.y,pixelFormat:T.RGBA,pixelDatatype:L.UNSIGNED_BYTE,sampler:te()}),n=new M({context:t,depthRenderbuffer:r,colorTextures:[i],destroyAttachments:!1}),o=e._passes.length,a=0;a<o;++a){var s=e._passes[a];s.framebuffer=n,s.passState.framebuffer=n}e._shadowMapTexture=i,e._depthAttachment=r,e._colorAttachment=i}function ie(e,t){for(var r=new V({context:t,width:e._textureSize.x,height:e._textureSize.y,pixelFormat:T.DEPTH_STENCIL,pixelDatatype:L.UNSIGNED_INT_24_8,sampler:te()}),i=new M({context:t,depthStencilTexture:r,destroyAttachments:!1}),n=e._passes.length,o=0;o<n;++o){var a=e._passes[o];a.framebuffer=i,a.passState.framebuffer=i}e._shadowMapTexture=r,e._depthAttachment=r}function ne(e,t){for(var r=new k({context:t,width:e._textureSize.x,height:e._textureSize.y,format:F.DEPTH_COMPONENT16}),i=new I({context:t,width:e._textureSize.x,height:e._textureSize.y,pixelFormat:T.RGBA,pixelDatatype:L.UNSIGNED_BYTE,sampler:te()}),n=[i.negativeX,i.negativeY,i.negativeZ,i.positiveX,i.positiveY,i.positiveZ],o=0;o<6;++o){var a=new M({context:t,depthRenderbuffer:r,colorTextures:[n[o]],destroyAttachments:!1}),s=e._passes[o];s.framebuffer=a,s.passState.framebuffer=a}e._shadowMapTexture=i,e._depthAttachment=r,e._colorAttachment=i}function oe(e,t){e._isPointLight?ne(e,t):e._usesDepthTexture?ie(e,t):re(e,t)}function ae(e,t){e._usesDepthTexture&&e._passes[0].framebuffer.status!==x.FRAMEBUFFER_COMPLETE&&(e._usesDepthTexture=!1,$(e),ee(e),oe(e,t))}function se(e,t){p(e._passes[0].framebuffer)&&e._shadowMapTexture.width===e._textureSize.x||(ee(e),oe(e,t),ae(e,t),le(e,t))}function le(e,t,r){r=h(r,0),(e._isPointLight||0===r)&&(e._clearCommand.framebuffer=e._passes[r].framebuffer,e._clearCommand.execute(t,e._clearPassState))}function ue(t,r){t._size=r;var i=t._passes,n=i.length,o=t._textureSize;if(t._isPointLight){r=D.maximumCubeMapSize>=r?r:D.maximumCubeMapSize,o.x=r,o.y=r;var a=new e(0,0,r,r);i[0].passState.viewport=a,i[1].passState.viewport=a,i[2].passState.viewport=a,i[3].passState.viewport=a,i[4].passState.viewport=a,i[5].passState.viewport=a}else 1===n?(r=D.maximumTextureSize>=r?r:D.maximumTextureSize,o.x=r,o.y=r,i[0].passState.viewport=new e(0,0,r,r)):4===n&&(r=D.maximumTextureSize>=2*r?r:D.maximumTextureSize/2,o.x=2*r,o.y=2*r,i[0].passState.viewport=new e(0,0,r,r),i[1].passState.viewport=new e(r,0,r,r),i[2].passState.viewport=new e(0,r,r,r),i[3].passState.viewport=new e(r,r,r,r));t._clearPassState.viewport=new e(0,0,o.x,o.y);for(var s=0;s<n;++s){var l=i[s],u=l.passState.viewport,c=u.x/o.x,d=u.y/o.y,h=u.width/o.x,p=u.height/o.y;l.textureOffsets=new b(h,0,0,c,0,p,0,d,0,0,1,0,0,0,0,1)}}function ce(e,t){var r;r=e._isPointLight?"uniform samplerCube shadowMap_textureCube; \nvarying vec2 v_textureCoordinates; \nvoid main() \n{ \n vec2 uv = v_textureCoordinates; \n vec3 dir; \n \n if (uv.y < 0.5) \n { \n if (uv.x < 0.333) \n { \n dir.x = -1.0; \n dir.y = uv.x * 6.0 - 1.0; \n dir.z = uv.y * 4.0 - 1.0; \n } \n else if (uv.x < 0.666) \n { \n dir.y = -1.0; \n dir.x = uv.x * 6.0 - 3.0; \n dir.z = uv.y * 4.0 - 1.0; \n } \n else \n { \n dir.z = -1.0; \n dir.x = uv.x * 6.0 - 5.0; \n dir.y = uv.y * 4.0 - 1.0; \n } \n } \n else \n { \n if (uv.x < 0.333) \n { \n dir.x = 1.0; \n dir.y = uv.x * 6.0 - 1.0; \n dir.z = uv.y * 4.0 - 3.0; \n } \n else if (uv.x < 0.666) \n { \n dir.y = 1.0; \n dir.x = uv.x * 6.0 - 3.0; \n dir.z = uv.y * 4.0 - 3.0; \n } \n else \n { \n dir.z = 1.0; \n dir.x = uv.x * 6.0 - 5.0; \n dir.y = uv.y * 4.0 - 3.0; \n } \n } \n \n float shadow = czm_unpackDepth(textureCube(shadowMap_textureCube, dir)); \n gl_FragColor = vec4(vec3(shadow), 1.0); \n} \n":"uniform sampler2D shadowMap_texture; \nvarying vec2 v_textureCoordinates; \nvoid main() \n{ \n"+(e._usesDepthTexture?" float shadow = texture2D(shadowMap_texture, v_textureCoordinates).r; \n":" float shadow = czm_unpackDepth(texture2D(shadowMap_texture, v_textureCoordinates)); \n")+" gl_FragColor = vec4(vec3(shadow), 1.0); \n} \n";var i=t.createViewportQuadCommand(r,{uniformMap:{shadowMap_texture:function(){return e._shadowMapTexture},shadowMap_textureCube:function(){return e._shadowMapTexture}}});return i.pass=R.OVERLAY,i}function de(t,r){var i=r.context,n=r.context.drawingBufferWidth,o=r.context.drawingBufferHeight,a=.3*Math.min(n,o),s=Se;s.x=n-a,s.y=0,s.width=a,s.height=a;var l=t._debugShadowViewCommand;p(l)||(l=ce(t,i),t._debugShadowViewCommand=l),p(l.renderState)&&e.equals(l.renderState.viewport,s)||(l.renderState=B.fromCache({viewport:e.clone(s)})),r.commandList.push(t._debugShadowViewCommand)}function he(e,t){var i=new v({geometry:new r({minimum:new n(-.5,-.5,-.5),maximum:new n(.5,.5,.5)}),attributes:{color:u.fromColor(t)}}),o=new v({geometry:new E({radius:.5}),attributes:{color:u.fromColor(t)}});return new X({geometryInstances:[i,o],appearance:new Y({translucent:!1,flat:!0}),asynchronous:!1,modelMatrix:e})}function pe(e,t){de(e,t);var r=e.debugFreezeFrame&&!e._debugFreezeFrame;if(e._debugFreezeFrame=e.debugFreezeFrame, -e.debugFreezeFrame&&(r&&(e._debugCameraFrustum=e._debugCameraFrustum&&e._debugCameraFrustum.destroy(),e._debugCameraFrustum=new q({camera:e._sceneCamera,color:l.CYAN,updateOnChange:!1})),e._debugCameraFrustum.update(t)),e._cascadesEnabled){if(e.debugFreezeFrame){r&&(e._debugLightFrustum=e._debugLightFrustum&&e._debugLightFrustum.destroy(),e._debugLightFrustum=new q({camera:e._shadowMapCamera,color:l.YELLOW,updateOnChange:!1})),e._debugLightFrustum.update(t);for(var i=0;i<e._numberOfCascades;++i)r&&(e._debugCascadeFrustums[i]=e._debugCascadeFrustums[i]&&e._debugCascadeFrustums[i].destroy(),e._debugCascadeFrustums[i]=new q({camera:e._passes[i].camera,color:xe[i],updateOnChange:!1})),e._debugCascadeFrustums[i].update(t)}}else if(e._isPointLight){if(!p(e._debugLightFrustum)||e._needsUpdate){var o=e._shadowMapCamera.positionWC,a=A.IDENTITY,s=2*e._pointLightRadius,u=n.fromElements(s,s,s,Pe),c=b.fromTranslationQuaternionRotationScale(o,a,u,Te);e._debugLightFrustum=e._debugLightFrustum&&e._debugLightFrustum.destroy(),e._debugLightFrustum=he(c,l.YELLOW)}e._debugLightFrustum.update(t)}else p(e._debugLightFrustum)&&!e._needsUpdate||(e._debugLightFrustum=new q({camera:e._shadowMapCamera,color:l.YELLOW,updateOnChange:!1})),e._debugLightFrustum.update(t)}function fe(){this.viewMatrix=new b,this.inverseViewMatrix=new b,this.frustum=void 0,this.positionCartographic=new a,this.positionWC=new n,this.directionWC=n.clone(n.UNIT_Z),this.upWC=n.clone(n.UNIT_Y),this.rightWC=n.clone(n.UNIT_X),this.viewProjectionMatrix=new b}function me(e,t){var r,i=e._shadowMapCamera,a=e._sceneCamera,s=a.frustum.near,l=a.frustum.far,u=e._numberOfCascades,c=l-s,d=l/s,h=.9,p=!1;t.shadowHints.closestObjectSize<200&&(p=!0,h=.9);var f=Me,m=Ie;for(m[0]=s,m[u]=l,r=0;r<u;++r){var g=(r+1)/u,_=s*Math.pow(d,g),v=s+c*g,y=C.lerp(v,_,h);m[r+1]=y,f[r]=y-m[r]}if(p){for(r=0;r<u;++r)f[r]=Math.min(f[r],e._maximumCascadeDistances[r]);var S=m[0];for(r=0;r<u-1;++r)S+=f[r],m[r+1]=S}o.unpack(m,0,e._cascadeSplits[0]),o.unpack(m,1,e._cascadeSplits[1]),o.unpack(f,0,e._cascadeDistances);var w=i.frustum,T=w.left,A=w.right,E=w.bottom,x=w.top,P=w.near,D=w.far,I=i.positionWC,O=i.directionWC,M=i.upWC,R=a.frustum.clone(Oe),N=i.getViewProjection();for(r=0;r<u;++r){R.near=m[r],R.far=m[r+1];for(var L=b.multiply(R.projectionMatrix,a.viewMatrix,Te),k=b.inverse(L,Te),F=b.multiply(N,k,Te),B=n.fromElements(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE,Re),U=n.fromElements(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE,Ne),V=0;V<8;++V){var z=o.clone(we[V],Ae[V]);b.multiplyByVector(F,z,z),n.divideByScalar(z,z.w,z),n.minimumByComponent(z,B,B),n.maximumByComponent(z,U,U)}B.x=Math.max(B.x,0),B.y=Math.max(B.y,0),B.z=0,U.x=Math.min(U.x,1),U.y=Math.min(U.y,1),U.z=Math.min(U.z,1);var G=e._passes[r],H=G.camera;H.clone(i);var W=H.frustum;W.left=T+B.x*(A-T),W.right=T+U.x*(A-T),W.bottom=E+B.y*(x-E),W.top=E+U.y*(x-E),W.near=P+B.z*(D-P),W.far=P+U.z*(D-P),G.cullingVolume=H.frustum.computeCullingVolume(I,O,M);var j=e._cascadeMatrices[r];b.multiply(H.getViewProjection(),a.inverseViewMatrix,j),b.multiply(G.textureOffsets,j,j)}}function ge(e,t){var r=e._shadowMapCamera,i=e._sceneCamera,a=b.multiply(i.frustum.projectionMatrix,i.viewMatrix,Te),s=b.inverse(a,Te),l=r.directionWC,u=i.directionWC,c=n.cross(l,u,ke);u=n.cross(c,l,Fe),n.normalize(u,u),n.normalize(c,c);for(var d=n.fromElements(0,0,0,Be),h=b.computeView(d,l,u,c,Le),p=b.multiply(h,s,Te),f=n.fromElements(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE,Re),m=n.fromElements(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE,Ne),g=0;g<8;++g){var _=o.clone(we[g],Ae[g]);b.multiplyByVector(p,_,_),n.divideByScalar(_,_.w,_),n.minimumByComponent(_,f,f),n.maximumByComponent(_,m,m)}m.z+=1e3,f.z-=10;var v=Be;v.x=-.5*(f.x+m.x),v.y=-.5*(f.y+m.y),v.z=-m.z;var y=b.fromTranslation(v,Te);h=b.multiply(y,h,h);var C=.5*(m.x-f.x),S=.5*(m.y-f.y),w=m.z-f.z,T=r.frustum;T.left=-C,T.right=C,T.bottom=-S,T.top=S,T.near=.01,T.far=w,b.clone(h,r.viewMatrix),b.inverse(h,r.inverseViewMatrix),b.getTranslation(r.inverseViewMatrix,r.positionWC),t.mapProjection.ellipsoid.cartesianToCartographic(r.positionWC,r.positionCartographic),n.clone(l,r.directionWC),n.clone(u,r.upWC),n.clone(c,r.rightWC)}function _e(e,t){var r=new w;r.fov=C.PI_OVER_TWO,r.near=1,r.far=e._pointLightRadius,r.aspectRatio=1;for(var i=0;i<6;++i){var n=e._passes[i].camera;n.positionWC=e._shadowMapCamera.positionWC,n.positionCartographic=t.mapProjection.ellipsoid.cartesianToCartographic(n.positionWC,n.positionCartographic),n.directionWC=Ue[i],n.upWC=Ve[i],n.rightWC=ze[i],b.computeView(n.positionWC,n.directionWC,n.upWC,n.rightWC,n.viewMatrix),b.inverse(n.viewMatrix,n.inverseViewMatrix),n.frustum=r}}function ve(e,r){var i=e._sceneCamera,o=e._shadowMapCamera,a=We;if(e._cascadesEnabled){if(i.frustum.near>=e.maximumDistance)return e._outOfView=!0,void(e._needsUpdate=!1);var s=r.mapProjection.ellipsoid.geodeticSurfaceNormal(i.positionWC,Ge),l=n.negate(o.directionWC,He),u=n.dot(s,l),c=C.clamp(u/.1,0,1);if(e._darkness=C.lerp(1,e.darkness,c),u<0)return e._outOfView=!0,void(e._needsUpdate=!1);e._needsUpdate=!0,e._outOfView=!1}else if(e._isPointLight)a.center=o.positionWC,a.radius=e._pointLightRadius,e._outOfView=r.cullingVolume.computeVisibility(a)===y.OUTSIDE,e._needsUpdate=!e._outOfView&&!e._boundingSphere.equals(a),t.clone(a,e._boundingSphere);else{var d=o.frustum.far/2,h=n.add(o.positionWC,n.multiplyByScalar(o.directionWC,d,je),je);a.center=h,a.radius=d,e._outOfView=r.cullingVolume.computeVisibility(a)===y.OUTSIDE,e._needsUpdate=!e._outOfView&&!e._boundingSphere.equals(a),t.clone(a,e._boundingSphere)}}function ye(e,t){var r=t.camera,i=e._lightCamera,o=e._sceneCamera,a=e._shadowMapCamera;e._cascadesEnabled?n.clone(i.directionWC,a.directionWC):e._isPointLight?n.clone(i.positionWC,a.positionWC):a.clone(i);var s=e._lightDirectionEC;b.multiplyByPointAsVector(r.viewMatrix,a.directionWC,s),n.normalize(s,s),n.negate(s,s),b.multiplyByPoint(r.viewMatrix,a.positionWC,e._lightPositionEC),e._lightPositionEC.w=e._pointLightRadius;var l,u;e._fitNearFar?(l=Math.min(t.shadowHints.nearPlane,e.maximumDistance),u=Math.min(t.shadowHints.farPlane,e.maximumDistance+1)):(l=r.frustum.near,u=e.maximumDistance),e._sceneCamera=W.clone(r,o),r.frustum.clone(e._sceneCamera.frustum),e._sceneCamera.frustum.near=l,e._sceneCamera.frustum.far=u,e._distance=u-l,ve(e,t),!e._outOfViewPrevious&&e._outOfView&&(e._needsUpdate=!0),e._outOfViewPrevious=e._outOfView}function Ce(e,t,r){var i=e._isPointLight?e._pointBias:r?e._terrainBias:e._primitiveBias,n={shadowMap_texture:function(){return e._shadowMapTexture},shadowMap_textureCube:function(){return e._shadowMapTexture},shadowMap_matrix:function(){return e._shadowMapMatrix},shadowMap_cascadeSplits:function(){return e._cascadeSplits},shadowMap_cascadeMatrices:function(){return e._cascadeMatrices},shadowMap_lightDirectionEC:function(){return e._lightDirectionEC},shadowMap_lightPositionEC:function(){return e._lightPositionEC},shadowMap_cascadeDistances:function(){return e._cascadeDistances},shadowMap_texelSizeDepthBiasAndNormalShadingSmooth:function(){var t=qe;return t.x=1/e._textureSize.x,t.y=1/e._textureSize.y,o.fromElements(t.x,t.y,i.depthBias,i.normalShadingSmooth,this.combinedUniforms1)},shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness:function(){return o.fromElements(i.normalOffsetScale,e._distance,e.maximumDistance,e._darkness,this.combinedUniforms2)},combinedUniforms1:new o,combinedUniforms2:new o};return c(t,n,!1)}function be(e,t,r,i,n,o){var a,l,u;if(p(o)&&(a=o.shaderProgram,l=o.renderState,u=o.uniformMap),o=O.shallowClone(r,o),o.castShadows=!0,o.receiveShadows=!1,!p(a)||n!==r.shaderProgram.id||t){var c=r.shaderProgram,d=r.pass===R.GLOBE,h=r.pass!==R.TRANSLUCENT,f=e._isPointLight,m=e._usesDepthTexture,g=Q.getShadowCastShaderKeyword(f,d,m,h);if(a=i.shaderCache.getDerivedShaderProgram(c,g),!p(a)){var _=c.vertexShaderSource,v=c.fragmentShaderSource,y=Q.createShadowCastVertexShader(_,f,d),C=Q.createShadowCastFragmentShader(v,f,m,h);a=i.shaderCache.createDerivedShaderProgram(c,g,{vertexShaderSource:y,fragmentShaderSource:C,attributeLocations:c._attributeLocations})}l=e._primitiveRenderState,f?l=e._pointRenderState:d&&(l=e._terrainRenderState);r.renderState.cull.enabled||(l=s(l,!1),l.cull=s(l.cull,!1),l.cull.enabled=!1,l=B.fromCache(l)),u=Ce(e,r.uniformMap,d)}return o.shaderProgram=a,o.renderState=l,o.uniformMap=u,o}Z.MAXIMUM_DISTANCE=2e4,Z.prototype.debugCreateRenderStates=function(){$(this)},f(Z.prototype,{enabled:{get:function(){return this._enabled},set:function(e){this.dirty=this._enabled!==e,this._enabled=e}},normalOffset:{get:function(){return this._normalOffset},set:function(e){this.dirty=this._normalOffset!==e,this._normalOffset=e,this._terrainBias.normalOffset=e,this._primitiveBias.normalOffset=e,this._pointBias.normalOffset=e}},softShadows:{get:function(){return this._softShadows},set:function(e){this.dirty=this._softShadows!==e,this._softShadows=e}},size:{get:function(){return this._size},set:function(e){ue(this,e)}},outOfView:{get:function(){return this._outOfView}},shadowMapCullingVolume:{get:function(){return this._shadowMapCullingVolume}},passes:{get:function(){return this._passes}},isPointLight:{get:function(){return this._isPointLight}},debugCascadeColors:{get:function(){return this._debugCascadeColors},set:function(e){this.dirty=this._debugCascadeColors!==e,this._debugCascadeColors=e}}});var Se=new e,we=new Array(8);we[0]=new o(-1,-1,-1,1),we[1]=new o(1,-1,-1,1),we[2]=new o(1,1,-1,1),we[3]=new o(-1,1,-1,1),we[4]=new o(-1,-1,1,1),we[5]=new o(1,-1,1,1),we[6]=new o(1,1,1,1),we[7]=new o(-1,1,1,1);for(var Te=new b,Ae=new Array(8),Ee=0;Ee<8;++Ee)Ae[Ee]=new o;var xe=[l.RED,l.GREEN,l.BLUE,l.MAGENTA],Pe=new n;fe.prototype.clone=function(e){b.clone(e.viewMatrix,this.viewMatrix),b.clone(e.inverseViewMatrix,this.inverseViewMatrix),this.frustum=e.frustum.clone(this.frustum),a.clone(e.positionCartographic,this.positionCartographic),n.clone(e.positionWC,this.positionWC),n.clone(e.directionWC,this.directionWC),n.clone(e.upWC,this.upWC),n.clone(e.rightWC,this.rightWC)};var De=new b(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);fe.prototype.getViewProjection=function(){var e=this.viewMatrix,t=this.frustum.projectionMatrix;return b.multiply(t,e,this.viewProjectionMatrix),b.multiply(De,this.viewProjectionMatrix,this.viewProjectionMatrix),this.viewProjectionMatrix};var Ie=new Array(5),Oe=new w,Me=new Array(4),Re=new n,Ne=new n,Le=new b,ke=new n,Fe=new n,Be=new n,Ue=[new n(-1,0,0),new n(0,-1,0),new n(0,0,-1),new n(1,0,0),new n(0,1,0),new n(0,0,1)],Ve=[new n(0,-1,0),new n(0,0,-1),new n(0,-1,0),new n(0,-1,0),new n(0,0,1),new n(0,-1,0)],ze=[new n(0,0,1),new n(1,0,0),new n(-1,0,0),new n(0,0,-1),new n(1,0,0),new n(1,0,0)],Ge=new n,He=new n,We=new t,je=We.center;Z.prototype.update=function(e){if(ye(this,e),this._needsUpdate)if(se(this,e.context),this._isPointLight&&_e(this,e),this._cascadesEnabled&&(ge(this,e),this._numberOfCascades>1&&me(this,e)),this._isPointLight)this._shadowMapCullingVolume=d.fromBoundingSphere(this._boundingSphere);else{var t=this._shadowMapCamera,r=t.positionWC,i=t.directionWC,n=t.upWC;this._shadowMapCullingVolume=t.frustum.computeCullingVolume(r,i,n),1===this._passes.length&&this._passes[0].camera.clone(t)}if(1===this._passes.length){var o=this._sceneCamera.inverseViewMatrix;b.multiply(this._shadowMapCamera.getViewProjection(),o,this._shadowMapMatrix)}this.debugShow&&pe(this,e)},Z.prototype.updatePass=function(e,t){le(this,e,t)};var qe=new i;return Z.createDerivedCommands=function(e,t,r,i,n,o){p(o)||(o={});var a=t.length>0,s=r.shaderProgram,l=s.vertexShaderSource,u=s.fragmentShaderSource,c=r.pass===R.GLOBE,d=!1;if(c&&(d=r.owner.data.pickTerrain.mesh.encoding.hasVertexNormals),r.castShadows){var h=o.castCommands;p(h)||(h=o.castCommands=[]);var f=o.castShaderProgramId,m=e.length;h.length=m;for(var g=0;g<m;++g)h[g]=be(e[g],i,r,n,f,h[g]);o.castShaderProgramId=r.shaderProgram.id}if(r.receiveShadows&&a){var _,v;p(o.receiveCommand)&&(_=o.receiveCommand.shaderProgram,v=o.receiveCommand.uniformMap),o.receiveCommand=O.shallowClone(r,o.receiveCommand),o.castShadows=!1,o.receiveShadows=!0;var y=o.receiveShaderCastShadows!==r.castShadows,C=o.receiveShaderProgramId!==r.shaderProgram.id;if(!p(_)||C||i||y){var b=Q.getShadowReceiveShaderKeyword(t[0],r.castShadows,c,d);if(_=n.shaderCache.getDerivedShaderProgram(s,b),!p(_)){var S=Q.createShadowReceiveVertexShader(l,c,d),w=Q.createShadowReceiveFragmentShader(u,t[0],r.castShadows,c,d);_=n.shaderCache.createDerivedShaderProgram(s,b,{vertexShaderSource:S,fragmentShaderSource:w,attributeLocations:s._attributeLocations})}v=Ce(t[0],r.uniformMap,c)}o.receiveCommand.shaderProgram=_,o.receiveCommand.uniformMap=v,o.receiveShaderProgramId=r.shaderProgram.id,o.receiveShaderCastShadows=r.castShadows}return o},Z.prototype.isDestroyed=function(){return!1},Z.prototype.destroy=function(){ee(this),this._debugLightFrustum=this._debugLightFrustum&&this._debugLightFrustum.destroy(),this._debugCameraFrustum=this._debugCameraFrustum&&this._debugCameraFrustum.destroy(),this._debugShadowViewCommand=this._debugShadowViewCommand&&this._debugShadowViewCommand.shaderProgram&&this._debugShadowViewCommand.shaderProgram.destroy();for(var e=0;e<this._numberOfCascades;++e)this._debugCascadeFrustums[e]=this._debugCascadeFrustums[e]&&this._debugCascadeFrustums[e].destroy();return m(this)},Z}),define("Shaders/PostProcessFilters/AdditiveBlend",[],function(){"use strict";return"uniform sampler2D u_texture0;\nuniform sampler2D u_texture1;\nuniform vec2 u_center;\nuniform float u_radius;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec4 color0 = texture2D(u_texture0, v_textureCoordinates);\nvec4 color1 = texture2D(u_texture1, v_textureCoordinates);\nfloat x = length(gl_FragCoord.xy - u_center) / u_radius;\nfloat t = smoothstep(0.5, 0.8, x);\ngl_FragColor = mix(color0 + color1, color0, t);\n}\n"}),define("Shaders/PostProcessFilters/BrightPass",[],function(){"use strict";return"uniform sampler2D u_texture;\nuniform float u_avgLuminance;\nuniform float u_threshold;\nuniform float u_offset;\nvarying vec2 v_textureCoordinates;\nfloat key(float avg)\n{\nfloat guess = 1.5 - (1.5 / (avg * 0.1 + 1.0));\nreturn max(0.0, guess) + 0.1;\n}\nvoid main()\n{\nvec4 color = texture2D(u_texture, v_textureCoordinates);\nvec3 xyz = czm_RGBToXYZ(color.rgb);\nfloat luminance = xyz.r;\nfloat scaledLum = key(u_avgLuminance) * luminance / u_avgLuminance;\nfloat brightLum = max(scaledLum - u_threshold, 0.0);\nfloat brightness = brightLum / (u_offset + brightLum);\nxyz.r = brightness;\ngl_FragColor = vec4(czm_XYZToRGB(xyz), 1.0);\n}\n"}),define("Shaders/PostProcessFilters/GaussianBlur1D",[],function(){"use strict";return"#define SAMPLES 8\nuniform float delta;\nuniform float sigma;\nuniform float direction;\nuniform sampler2D u_texture;\nuniform vec2 u_step;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec2 st = v_textureCoordinates;\nvec2 dir = vec2(1.0 - direction, direction);\nvec3 g;\ng.x = 1.0 / (sqrt(czm_twoPi) * sigma);\ng.y = exp((-0.5 * delta * delta) / (sigma * sigma));\ng.z = g.y * g.y;\nvec4 result = texture2D(u_texture, st) * g.x;\nfor (int i = 1; i < SAMPLES; ++i)\n{\ng.xy *= g.yz;\nvec2 offset = float(i) * dir * u_step;\nresult += texture2D(u_texture, st - offset) * g.x;\nresult += texture2D(u_texture, st + offset) * g.x;\n}\ngl_FragColor = result;\n}\n"}),define("Scene/SunPostProcess",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian4","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/Math","../Core/Matrix4","../Core/PixelFormat","../Core/Transforms","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PassState","../Renderer/PixelDatatype","../Renderer/Renderbuffer","../Renderer/RenderbufferFormat","../Renderer/RenderState","../Renderer/Texture","../Shaders/PostProcessFilters/AdditiveBlend","../Shaders/PostProcessFilters/BrightPass","../Shaders/PostProcessFilters/GaussianBlur1D","../Shaders/PostProcessFilters/PassThrough"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S){"use strict";function w(){this._fbo=void 0,this._downSampleFBO1=void 0,this._downSampleFBO2=void 0,this._clearFBO1Command=void 0,this._clearFBO2Command=void 0,this._downSampleCommand=void 0,this._brightPassCommand=void 0,this._blurXCommand=void 0,this._blurYCommand=void 0,this._blendCommand=void 0,this._fullScreenCommand=void 0,this._downSamplePassState=new p,this._downSamplePassState.scissorTest={enable:!0,rectangle:new e},this._upSamplePassState=new p,this._upSamplePassState.scissorTest={enabled:!0,rectangle:new e},this._uCenter=new t,this._uRadius=void 0,this._blurStep=new t}w.prototype.clear=function(e,t){var r=this._clearFBO1Command;i.clone(n(t,i.BLACK),r.color),r.execute(e),r=this._clearFBO2Command,i.clone(n(t,i.BLACK),r.color),r.execute(e)},w.prototype.execute=function(e,t){this._downSampleCommand.execute(e,this._downSamplePassState),this._brightPassCommand.execute(e,this._downSamplePassState),this._blurXCommand.execute(e,this._downSamplePassState),this._blurYCommand.execute(e,this._downSamplePassState),this._fullScreenCommand.framebuffer=t,this._blendCommand.framebuffer=t,this._fullScreenCommand.execute(e),this._blendCommand.execute(e,this._upSamplePassState)};var T=new e,A=new e,E=new r,x=new t,P=new t,D=new l;return w.prototype.update=function(e){var r=e.context,n=e.viewport,a=r.drawingBufferWidth,p=r.drawingBufferHeight,w=this;if(!o(this._downSampleCommand)){this._clearFBO1Command=new d({color:new i}),this._clearFBO2Command=new d({color:new i});var I={};this._downSampleCommand=r.createViewportQuadCommand(S,{uniformMap:I,owner:this}),I={u_avgLuminance:function(){return.5},u_threshold:function(){return.25},u_offset:function(){return.1}},this._brightPassCommand=r.createViewportQuadCommand(C,{uniformMap:I,owner:this});I={delta:function(){return 1},sigma:function(){return 2},direction:function(){return 0}},this._blurXCommand=r.createViewportQuadCommand(b,{uniformMap:I,owner:this}),I={delta:function(){return 1},sigma:function(){return 2},direction:function(){return 1}},this._blurYCommand=r.createViewportQuadCommand(b,{uniformMap:I,owner:this}),I={u_center:function(){return w._uCenter},u_radius:function(){return w._uRadius}},this._blendCommand=r.createViewportQuadCommand(y,{uniformMap:I,owner:this}),I={},this._fullScreenCommand=r.createViewportQuadCommand(S,{uniformMap:I,owner:this})}var O=Math.pow(2,Math.ceil(Math.log(a)/Math.log(2))-2),M=Math.pow(2,Math.ceil(Math.log(p)/Math.log(2))-2),R=Math.max(1,O,M),N=A;N.width=R,N.height=R;var L=this._fbo,k=o(L)&&L.getColorTexture(0)||void 0;if(!o(k)||k.width!==a||k.height!==p){L=L&&L.destroy(),this._downSampleFBO1=this._downSampleFBO1&&this._downSampleFBO1.destroy(),this._downSampleFBO2=this._downSampleFBO2&&this._downSampleFBO2.destroy(),this._blurStep.x=this._blurStep.y=1/R;var F=[new v({context:r,width:a,height:p})];L=r.depthTexture?this._fbo=new h({context:r,colorTextures:F,depthTexture:new v({context:r,width:a,height:p,pixelFormat:u.DEPTH_COMPONENT,pixelDatatype:f.UNSIGNED_SHORT})}):this._fbo=new h({context:r,colorTextures:F,depthRenderbuffer:new m({context:r,format:g.DEPTH_COMPONENT16})}),this._downSampleFBO1=new h({context:r,colorTextures:[new v({context:r,width:R,height:R})]}),this._downSampleFBO2=new h({context:r,colorTextures:[new v({context:r,width:R,height:R})]}),this._clearFBO1Command.framebuffer=this._downSampleFBO1,this._clearFBO2Command.framebuffer=this._downSampleFBO2,this._downSampleCommand.framebuffer=this._downSampleFBO1,this._brightPassCommand.framebuffer=this._downSampleFBO2,this._blurXCommand.framebuffer=this._downSampleFBO1,this._blurYCommand.framebuffer=this._downSampleFBO2;var B=_.fromCache({viewport:N});this._downSampleCommand.uniformMap.u_texture=function(){return L.getColorTexture(0)},this._downSampleCommand.renderState=B,this._brightPassCommand.uniformMap.u_texture=function(){return w._downSampleFBO1.getColorTexture(0)},this._brightPassCommand.renderState=B,this._blurXCommand.uniformMap.u_texture=function(){return w._downSampleFBO2.getColorTexture(0)},this._blurXCommand.uniformMap.u_step=function(){return w._blurStep},this._blurXCommand.renderState=B,this._blurYCommand.uniformMap.u_texture=function(){return w._downSampleFBO1.getColorTexture(0)},this._blurYCommand.uniformMap.u_step=function(){return w._blurStep},this._blurYCommand.renderState=B;var U=T;U.width=a,U.height=p;var V=_.fromCache({viewport:U});this._blendCommand.uniformMap.u_texture0=function(){return L.getColorTexture(0)},this._blendCommand.uniformMap.u_texture1=function(){return w._downSampleFBO2.getColorTexture(0)},this._blendCommand.renderState=V,this._fullScreenCommand.uniformMap.u_texture=function(){return L.getColorTexture(0)},this._fullScreenCommand.renderState=V}var z=r.uniformState,G=z.sunPositionWC,H=z.view,W=z.viewProjection,j=z.projection,q=l.computeViewportTransformation(n,0,1,D),Y=l.multiplyByPoint(H,G,E),X=c.pointToGLWindowCoordinates(W,q,G,x);Y.x+=s.SOLAR_RADIUS;var Q=c.pointToGLWindowCoordinates(j,q,Y,Y),Z=30*t.magnitude(t.subtract(Q,X,Q))*2,K=P;K.x=Z,K.y=Z;var J=this._upSamplePassState.scissorTest.rectangle;return J.x=Math.max(X.x-.5*K.x,0),J.y=Math.max(X.y-.5*K.y,0),J.width=Math.min(K.x,a),J.height=Math.min(K.y,p),this._uCenter=t.clone(X,this._uCenter),this._uRadius=.15*Math.max(K.x,K.y),q=l.computeViewportTransformation(N,0,1,D),X=c.pointToGLWindowCoordinates(W,q,G,x),K.x*=O/a,K.y*=M/p,J=this._downSamplePassState.scissorTest.rectangle,J.x=Math.max(X.x-.5*K.x,0),J.y=Math.max(X.y-.5*K.y,0),J.width=Math.min(K.x,a),J.height=Math.min(K.y,p),this._downSamplePassState.context=r,this._upSamplePassState.context=r,this._fbo},w.prototype.isDestroyed=function(){return!1},w.prototype.destroy=function(){return this._fbo=this._fbo&&this._fbo.destroy(),this._downSampleFBO1=this._downSampleFBO1&&this._downSampleFBO1.destroy(),this._downSampleFBO2=this._downSampleFBO2&&this._downSampleFBO2.destroy(),this._downSampleCommand=this._downSampleCommand&&this._downSampleCommand.shaderProgram&&this._downSampleCommand.shaderProgram.destroy(),this._brightPassCommand=this._brightPassCommand&&this._brightPassCommand.shaderProgram&&this._brightPassCommand.shaderProgram.destroy(),this._blurXCommand=this._blurXCommand&&this._blurXCommand.shaderProgram&&this._blurXCommand.shaderProgram.destroy(),this._blurYCommand=this._blurYCommand&&this._blurYCommand.shaderProgram&&this._blurYCommand.shaderProgram.destroy(),this._blendCommand=this._blendCommand&&this._blendCommand.shaderProgram&&this._blendCommand.shaderProgram.destroy(),this._fullScreenCommand=this._fullScreenCommand&&this._fullScreenCommand.shaderProgram&&this._fullScreenCommand.shaderProgram.destroy(),a(this)},w}),define("Scene/Scene",["../Core/BoundingRectangle","../Core/BoundingSphere","../Core/BoxGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/createGuid","../Core/CullingVolume","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EllipsoidGeometry","../Core/Event","../Core/GeographicProjection","../Core/GeometryInstance","../Core/GeometryPipeline","../Core/getTimestamp","../Core/Intersect","../Core/Interval","../Core/JulianDate","../Core/Math","../Core/Matrix4","../Core/mergeSort","../Core/Occluder","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/PerspectiveOffCenterFrustum","../Core/PixelFormat","../Core/RequestScheduler","../Core/ShowGeometryInstanceAttribute","../Core/Transforms","../Renderer/ClearCommand","../Renderer/ComputeEngine","../Renderer/Context","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/Pass","../Renderer/PassState","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/Texture","./BrdfLutGenerator","./Camera","./CreditDisplay","./DebugCameraPrimitive","./DepthPlane","./DeviceOrientationCameraController","./Fog","./FrameState","./FrustumCommands","./FXAA","./GlobeDepth","./InvertClassification","./JobScheduler","./MapMode2D","./OIT","./PerformanceDisplay","./PerInstanceColorAppearance","./PickDepth","./Primitive","./PrimitiveCollection","./SceneMode","./SceneTransforms","./SceneTransitioner","./ScreenSpaceCameraController","./ShadowMap","./SunPostProcess","./TweenCollection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H,W,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,Ce,be,Se){"use strict";function we(t){t=d(t,d.EMPTY_OBJECT);var r=t.canvas,i=t.contextOptions,n=t.creditContainer,o=t.creditViewport,a=h(n),l=new U(r,i);a||(n=document.createElement("div"),n.style.position="absolute",n.style.bottom="0",n.style["text-shadow"]="0 0 2px #000000",n.style.color="#ffffff",n.style["font-size"]="10px",n.style["padding-right"]="5px",r.parentNode.appendChild(n)),h(o)||(o=r.parentNode),this._id=u(),this._jobScheduler=new le,this._frameState=new ie(l,new J(n," • ",o),this._jobScheduler),this._frameState.scene3DOnly=d(t.scene3DOnly,!1),this._removeCreditContainer=!a,this._creditContainer=n;var c=new W(l);c.viewport=new e,c.viewport.x=0,c.viewport.y=0,c.viewport.width=l.drawingBufferWidth,c.viewport.height=l.drawingBufferHeight,this._passState=c,this._canvas=r,this._context=l,this._computeEngine=new B(l),this._globe=void 0,this._primitives=new me,this._groundPrimitives=new me,this._tweens=new Se,this._shaderFrameCount=0,this._sunPostProcess=void 0,this._computeCommandList=[],this._frustumCommandsList=[],this._overlayCommandList=[],this._pickFramebuffer=void 0,this._useOIT=d(t.orderIndependentTranslucency,!0),this._executeOITFunction=void 0;var p;l.depthTexture&&(p=new ae);var f;this._useOIT&&h(p)&&(f=new ce(l)),this._globeDepth=p,this._depthPlane=new ee,this._oit=f,this._fxaa=new oe,this._clearColorCommand=new F({color:new s,stencil:0,owner:this}),this._depthClearCommand=new F({depth:1,owner:this}),this._stencilClearCommand=new F({stencil:0}),this._pickDepths=[],this._debugGlobeDepths=[],this._pickDepthPassState=void 0,this._pickDepthFramebuffer=void 0,this._pickDepthFramebufferWidth=void 0,this._pickDepthFramebufferHeight=void 0,this._depthOnlyRenderStateCache={},this._transitioner=new ve(this),this._renderError=new _,this._preRender=new _,this._postRender=new _,this._cameraStartFired=!1,this._cameraMovedTime=void 0,this._pickPositionCache={},this._pickPositionCacheDirty=!1,this._minimumDisableDepthTestDistance=0,this.rethrowRenderErrors=!1,this.completeMorphOnUserInput=!0,this.morphStart=new _,this.morphComplete=new _,this.skyBox=void 0,this.skyAtmosphere=void 0,this.sun=void 0,this.sunBloom=!0,this._sunBloom=void 0,this.moon=void 0,this.backgroundColor=s.clone(s.BLACK),this._mode=ge.SCENE3D,this._mapProjection=h(t.mapProjection)?t.mapProjection:new v,this.morphTime=1,this.farToNearRatio=1e3,this.nearToFarDistance2D=175e4,this.debugCommandFilter=void 0,this.debugShowCommands=!1,this.debugShowFrustums=!1,this._debugFrustumStatistics=void 0,this.debugShowFramesPerSecond=!1,this.debugShowGlobeDepth=!1,this.debugShowDepthFrustum=1,this.debugShowFrustumPlanes=!1,this._debugShowFrustumPlanes=!1,this._debugFrustumPlanes=void 0,this.fxaa=!0,this.useDepthPicking=!0,this.pickTranslucentDepth=!1,this.cameraEventWaitTime=500,this.copyGlobeDepth=!1,this.fog=new re,this._sunCamera=new K(this),this.shadowMap=new Ce({context:l,lightCamera:this._sunCamera,enabled:d(t.shadows,!1)}),this.invertClassification=!1,this.invertClassificationColor=s.clone(s.WHITE),this._actualInvertClassificationColor=s.clone(this._invertClassificationColor),this._invertClassification=new se,this.focalLength=void 0,this.eyeSeparation=void 0,this._brdfLutGenerator=new Z,this._terrainExaggeration=d(t.terrainExaggeration,1),this._performanceDisplay=void 0,this._debugVolume=void 0;var m=new K(this);this._camera=m,this._cameraClone=K.clone(m),this._screenSpaceCameraController=new ye(this),this._mapMode2D=d(t.mapMode2D,ue.INFINITE_SCROLL),this._environmentState={skyBoxCommand:void 0,skyAtmosphereCommand:void 0,sunDrawCommand:void 0,sunComputeCommand:void 0,moonCommand:void 0,isSunVisible:!1,isMoonVisible:!1,isReadyForAtmosphere:!1,isSkyAtmosphereVisible:!1,clearGlobeDepth:!1,useDepthPlane:!1,originalFramebuffer:void 0,useGlobeDepthFramebuffer:!1,useOIT:!1,useFXAA:!1,useInvertClassification:!1},this._useWebVR=!1,this._cameraVR=void 0,this._aspectRatioVR=void 0;var g=m.frustum.near,y=m.frustum.far,C=Math.ceil(Math.log(y/g)/Math.log(this.farToNearRatio));Ie(g,y,this.farToNearRatio,C,this._frustumCommandsList,!1,void 0),De(this,0,T.now()),this.initializeFrame()}function Te(e,t){var r=Math.max(Math.abs(e.x),Math.abs(t.x)),i=Math.max(Math.abs(e.y),Math.abs(t.y)),n=Math.max(Math.abs(e.z),Math.abs(t.z));return Math.max(Math.max(r,i),n)}function Ae(e,t,r){var i=1/Math.max(1,Te(e.position,t.position));return n.multiplyByScalar(e.position,i,pt),n.multiplyByScalar(t.position,i,ft),n.equalsEpsilon(pt,ft,r)&&n.equalsEpsilon(e.direction,t.direction,r)&&n.equalsEpsilon(e.up,t.up,r)&&n.equalsEpsilon(e.right,t.right,r)&&E.equalsEpsilon(e.transform,t.transform,r)}function Ee(e,t){var r=e.frameState,i=e._context,n=r.shadowHints.shadowsEnabled,o=r.shadowHints.shadowMaps,a=r.shadowHints.lightShadowMaps,s=n&&a.length>0,l=!1,u=r.shadowHints.lastDirtyTime;t.lastDirtyTime!==u&&(t.lastDirtyTime=u,t.dirty=!0,l=!0);var c=t.derivedCommands;if(t.dirty&&h(c)){t.dirty=!1,n&&(t.receiveShadows||t.castShadows)&&(c.shadows=Ce.createDerivedCommands(o,a,t,l,i,c.shadows));var d=e._oit;t.pass===H.TRANSLUCENT&&h(d)&&d.isSupported()&&(s&&t.receiveShadows?(c.oit=h(c.oit)?c.oit:{},c.oit.shadows=d.createDerivedCommands(t.derivedCommands.shadows.receiveCommand,i,c.oit.shadows)):c.oit=d.createDerivedCommands(t,i,c.oit)),c.depth=ut(e,t,i,c.depth)}}function xe(e){var t=e.globe;if(e._mode===ge.SCENE3D&&h(t)){var r=t.ellipsoid;return mt.radius=r.minimumRadius,ht=P.fromBoundingSphere(mt,e._camera.positionWC,ht)}}function Pe(e){e.render=!1,e.pick=!1,e.depth=!1}function De(e,t,r){var i=e._camera,n=e._frameState;n.commandList.length=0,n.shadowMaps.length=0,n.brdfLutGenerator=e._brdfLutGenerator,n.environmentMap=e.skyBox&&e.skyBox._cubeMap,n.mode=e._mode,n.morphTime=e.morphTime,n.mapProjection=e.mapProjection,n.frameNumber=t,n.time=T.clone(r,n.time),n.camera=i,n.cullingVolume=i.frustum.computeCullingVolume(i.positionWC,i.directionWC,i.upWC),n.occluder=xe(e),n.terrainExaggeration=e._terrainExaggeration,n.minimumDisableDepthTestDistance=e._minimumDisableDepthTestDistance,n.invertClassification=e.invertClassification,e._actualInvertClassificationColor=s.clone(e.invertClassificationColor,e._actualInvertClassificationColor),se.isTranslucencySupported(e._context)||(e._actualInvertClassificationColor.alpha=1),n.invertClassificationColor=e._actualInvertClassificationColor,h(e.globe)?n.maximumScreenSpaceError=e.globe.maximumScreenSpaceError:n.maximumScreenSpaceError=2,Pe(n.passes)}function Ie(e,t,r,i,n,o,a){n.length=i;for(var s=0;s<i;++s){var l,u;o?(l=Math.min(t-a,e+s*a),u=Math.min(t,l+a)):(l=Math.max(e,Math.pow(r,s)*e),u=Math.min(t,r*l));var c=n[s];h(c)?(c.near=l,c.far=u):c=n[s]=new ne(l,u)}}function Oe(e,t,r){e.debugShowFrustums&&(t.debugOverlappingFrustums=0),e.frameState.passes.pick||Ee(e,t);for(var i=e._frustumCommandsList,n=i.length,o=0;o<n;++o){var a=i[o],s=a.near,l=a.far;if(!(r.start>l)){if(r.stop<s)break;var u=t.pass,c=a.indices[u]++;if(a.commands[u][c]=t,e.debugShowFrustums&&(t.debugOverlappingFrustums|=1<<o),t.executeInClosestFrustum)break}}if(e.debugShowFrustums){var d=e._debugFrustumStatistics.commandsInFrustums;d[t.debugOverlappingFrustums]=h(d[t.debugOverlappingFrustums])?d[t.debugOverlappingFrustums]+1:1,++e._debugFrustumStatistics.totalCommands}}function Me(e,t,r){return h(e)&&(!h(e.boundingVolume)||!e.cull||t.computeVisibility(e.boundingVolume)!==S.OUTSIDE&&(!h(r)||!e.boundingVolume.isOccluded(r)))} -function Re(e){var t=e._frameState,r=t.camera,i=r.directionWC,n=r.positionWC,o=e._computeCommandList,a=e._overlayCommandList,s=t.commandList;e.debugShowFrustums&&(e._debugFrustumStatistics={totalCommands:0,commandsInFrustums:{}});for(var l=e._frustumCommandsList,u=l.length,c=H.NUMBER_OF_PASSES,d=0;d<u;++d)for(var p=0;p<c;++p)l[d].indices[p]=0;o.length=0,a.length=0;for(var f=Number.MAX_VALUE,m=-Number.MAX_VALUE,g=!1,_=t.shadowHints.shadowsEnabled,v=Number.MAX_VALUE,y=-Number.MAX_VALUE,C=Number.MAX_VALUE,b=t.mode===ge.SCENE3D?t.occluder:void 0,S=t.cullingVolume,w=gt.planes,T=0;T<5;++T)w[T]=S.planes[T];S=gt;for(var E=s.length,x=0;x<E;++x){var P=s[x],D=P.pass;if(D===H.COMPUTE)o.push(P);else if(D===H.OVERLAY)a.push(P);else{var I=P.boundingVolume;if(h(I)){if(!Me(P,S,b))continue;if(_t=I.computePlaneDistances(n,i,_t),f=Math.min(f,_t.start),m=Math.max(m,_t.stop),_&&P.receiveShadows&&_t.start<Ce.MAXIMUM_DISTANCE&&!(D===H.GLOBE&&_t.start<-100&&_t.stop>100)){var O=_t.stop-_t.start;D!==H.GLOBE&&_t.start<100&&(C=Math.min(C,O)),v=Math.min(v,_t.start),y=Math.max(y,_t.stop)}}else _t.start=r.frustum.near,_t.stop=r.frustum.far,g=!(P instanceof F);Oe(e,P,_t)}}g?(f=r.frustum.near,m=r.frustum.far):(f=Math.min(Math.max(f,r.frustum.near),r.frustum.far),m=Math.max(Math.min(m,r.frustum.far),f),_&&(v=Math.min(Math.max(v,r.frustum.near),r.frustum.far),y=Math.max(Math.min(y,r.frustum.far),v))),_&&(t.shadowHints.nearPlane=v,t.shadowHints.farPlane=y,t.shadowHints.closestObjectSize=C);var M,R=e.mode===ge.SCENE2D,N=e.farToNearRatio;R?(m=Math.min(m,r.position.z+e.nearToFarDistance2D),f=Math.min(f,m),M=Math.ceil(Math.max(1,m-f)/e.nearToFarDistance2D)):M=Math.ceil(Math.log(m/f)/Math.log(N)),f!==Number.MAX_VALUE&&(M!==u||0!==l.length&&(f<l[0].near||m>l[u-1].far&&!A.equalsEpsilon(m,l[u-1].far,A.EPSILON8)))&&(Ie(f,m,N,M,l,R,e.nearToFarDistance2D),Re(e));var L=t.frustumSplits;L.length=M+1;for(var k=0;k<M;++k)L[k]=l[k].near,k===M-1&&(L[k+1]=l[k].far)}function Ne(e){var t={},r=e.vertexAttributes;for(var i in r)r.hasOwnProperty(i)&&(t[i]=r[i].index);return t}function Le(e,t,r){var i=t.context,n=d(r,e.shaderProgram),o=n.fragmentShaderSource.clone(),a=[];o.sources=o.sources.map(function(e){e=X.replaceMain(e,"czm_Debug_main");for(var t,r=/gl_FragData\[(\d+)\]/g;null!==(t=r.exec(e));)-1===a.indexOf(t[1])&&a.push(t[1]);return e});var l,u=a.length,c="void main() \n{ \n czm_Debug_main(); \n";if(t.debugShowCommands){h(e._debugColor)||(e._debugColor=s.fromRandom());var p=e._debugColor;if(u>0)for(l=0;l<u;++l)c+=" gl_FragData["+a[l]+"].rgb *= vec3("+p.red+", "+p.green+", "+p.blue+"); \n";else c+=" gl_FragColor.rgb *= vec3("+p.red+", "+p.green+", "+p.blue+"); \n"}if(t.debugShowFrustums){var f=1&e.debugOverlappingFrustums?"1.0":"0.0",m=2&e.debugOverlappingFrustums?"1.0":"0.0",g=4&e.debugOverlappingFrustums?"1.0":"0.0";if(u>0)for(l=0;l<u;++l)c+=" gl_FragData["+a[l]+"].rgb *= vec3("+f+", "+m+", "+g+"); \n";else c+=" gl_FragColor.rgb *= vec3("+f+", "+m+", "+g+"); \n"}c+="}",o.sources.push(c);var _=Ne(n);return Y.fromCache({context:i,vertexShaderSource:n.vertexShaderSource,fragmentShaderSource:o,attributeLocations:_})}function ke(e,t,r){var i=z.shallowClone(e);i.shaderProgram=Le(e,t),i.execute(t.context,r),i.shaderProgram.destroy()}function Fe(e,t,i,o,a){if(!h(t.debugCommandFilter)||t.debugCommandFilter(e)){if(e instanceof F)return void e.execute(i,o);var s=t.frameState.shadowHints.shadowsEnabled,u=s&&t.frameState.shadowHints.lightShadowMaps.length>0;if(t.debugShowCommands||t.debugShowFrustums?ke(e,t,o):u&&e.receiveShadows&&h(e.derivedCommands.shadows)?e.derivedCommands.shadows.receiveCommand.execute(i,o):t.frameState.passes.depth&&h(e.derivedCommands.depth)?e.derivedCommands.depth.depthOnlyCommand.execute(i,o):e.execute(i,o),e.debugShowBoundingVolume&&h(e.boundingVolume)){var c=t._frameState,d=e.boundingVolume;h(t._debugVolume)&&t._debugVolume.destroy();var p,f=n.clone(d.center);if(c.mode!==ge.SCENE3D){f=E.multiplyByPoint(vt,f,f);var m=c.mapProjection,_=m.unproject(f);f=m.ellipsoid.cartographicToCartesian(_)}if(h(d.radius)){var v=d.radius;p=C.toWireframe(g.createGeometry(new g({radii:new n(v,v,v),vertexFormat:he.FLAT_VERTEX_FORMAT}))),t._debugVolume=new fe({geometryInstances:new y({geometry:p,modelMatrix:E.fromTranslation(f),attributes:{color:new l(1,0,0,1)}}),appearance:new he({flat:!0,translucent:!1}),asynchronous:!1})}else{var b=d.halfAxes;p=C.toWireframe(r.createGeometry(r.fromDimensions({dimensions:new n(2,2,2),vertexFormat:he.FLAT_VERTEX_FORMAT}))),t._debugVolume=new fe({geometryInstances:new y({geometry:p,modelMatrix:E.fromRotationTranslation(b,f,new E),attributes:{color:new l(1,0,0,1)}}),appearance:new he({flat:!0,translucent:!1}),asynchronous:!1})}var S=c.commandList,w=c.commandList=[];t._debugVolume.update(c);var T;h(a)&&(T=o.framebuffer,o.framebuffer=a),w[0].execute(i,o),h(T)&&(o.framebuffer=T),c.commandList=S}}}function Be(e,t,r){return t.boundingVolume.distanceSquaredTo(r)-e.boundingVolume.distanceSquaredTo(r)}function Ue(e,t,r,i,n){var o=e.context;x(i,Be,e._camera.positionWC),h(n)&&t(n.unclassifiedCommand,e,o,r);for(var a=i.length,s=0;s<a;++s)t(i[s],e,o,r)}function Ve(e,t){var r=e._debugGlobeDepths[t];return!h(r)&&e.context.depthTexture&&(r=new ae,e._debugGlobeDepths[t]=r),r}function ze(e,t){var r=e._pickDepths[t];return h(r)||(r=new pe,e._pickDepths[t]=r),r}function Ge(e,t){var r=e._camera,i=e.context,n=i.uniformState;n.updateCamera(r);var o;o=h(r.frustum.fov)?r.frustum.clone(yt):h(r.frustum.infiniteProjectionMatrix)?r.frustum.clone(Ct):h(r.frustum.width)?r.frustum.clone(bt):r.frustum.clone(St),o.near=r.frustum.near,o.far=r.frustum.far,n.updateFrustum(o),n.updatePass(H.ENVIRONMENT);var a=e._useWebVR&&e.mode!==ge.SCENE2D,s=e._frameState.passes,l=s.pick,u=s.depth,c=e._environmentState;if(!l){var d=c.skyBoxCommand;if(h(d)&&Fe(d,e,i,t),c.isSkyAtmosphereVisible&&Fe(c.skyAtmosphereCommand,e,i,t),c.isSunVisible&&(c.sunDrawCommand.execute(i,t),e.sunBloom&&!a)){var p;p=c.useGlobeDepthFramebuffer?e._globeDepth.framebuffer:c.useFXAA?e._fxaa.getColorFramebuffer():c.originalFramebuffer,e._sunPostProcess.execute(i,p),t.framebuffer=p}c.isMoonVisible&&c.moonCommand.execute(i,t)}var f;c.useOIT?(h(e._executeOITFunction)||(e._executeOITFunction=function(e,t,r,i,n){e._oit.executeCommands(e,t,r,i,n)}),f=e._executeOITFunction):f=Ue;for(var m,g=c.clearGlobeDepth,_=c.useDepthPlane,v=e._depthClearCommand,y=e._depthPlane,C=r.position.z,b=e._frustumCommandsList,S=b.length,w=0;w<S;++w){var T=S-w-1,A=b[T];e.mode===ge.SCENE2D?(r.position.z=C-A.near+1,o.far=Math.max(1,A.far-A.near),o.near=1,n.update(e.frameState),n.updateFrustum(o)):(o.near=0!==T?A.near*dt:A.near,o.far=A.far,n.updateFrustum(o));var E,x=e.debugShowGlobeDepth?Ve(e,T):e._globeDepth;e.debugShowGlobeDepth&&h(x)&&c.useGlobeDepthFramebuffer&&(E=t.framebuffer,t.framebuffer=x.framebuffer),v.execute(i,t),e._stencilClearCommand.execute(i,t),n.updatePass(H.GLOBE);var P=A.commands[H.GLOBE],D=A.indices[H.GLOBE];for(m=0;m<D;++m)Fe(P[m],e,i,t);for(h(x)&&c.useGlobeDepthFramebuffer&&(e.copyGlobeDepth||e.debugShowGlobeDepth)&&(x.update(i,t),x.executeCopyDepth(i,t)),e.debugShowGlobeDepth&&h(x)&&c.useGlobeDepthFramebuffer&&(t.framebuffer=E),n.updatePass(H.TERRAIN_CLASSIFICATION),P=A.commands[H.TERRAIN_CLASSIFICATION],D=A.indices[H.TERRAIN_CLASSIFICATION],m=0;m<D;++m)Fe(P[m],e,i,t);if(g&&v.execute(i,t),!c.useInvertClassification||l){for(n.updatePass(H.CESIUM_3D_TILE),P=A.commands[H.CESIUM_3D_TILE],D=A.indices[H.CESIUM_3D_TILE],m=0;m<D;++m)Fe(P[m],e,i,t);for(n.updatePass(H.CESIUM_3D_TILE_CLASSIFICATION),P=A.commands[H.CESIUM_3D_TILE_CLASSIFICATION],D=A.indices[H.CESIUM_3D_TILE_CLASSIFICATION],m=0;m<D;++m)Fe(P[m],e,i,t)}else{e._invertClassification.clear(i,t);var I=t.framebuffer;for(t.framebuffer=e._invertClassification._fbo,n.updatePass(H.CESIUM_3D_TILE),P=A.commands[H.CESIUM_3D_TILE],D=A.indices[H.CESIUM_3D_TILE],m=0;m<D;++m)Fe(P[m],e,i,t);for(n.updatePass(H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW),P=A.commands[H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW],D=A.indices[H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW],m=0;m<D;++m)Fe(P[m],e,i,t);for(t.framebuffer=I,e._invertClassification.executeClassified(i,t),1===e.frameState.invertClassificationColor.alpha&&e._invertClassification.executeUnclassified(i,t),D>0&&i.stencilBuffer&&e._stencilClearCommand.execute(i,t),n.updatePass(H.CESIUM_3D_TILE_CLASSIFICATION),P=A.commands[H.CESIUM_3D_TILE_CLASSIFICATION],D=A.indices[H.CESIUM_3D_TILE_CLASSIFICATION],m=0;m<D;++m)Fe(P[m],e,i,t)}D>0&&i.stencilBuffer&&e._stencilClearCommand.execute(i,t),g&&_&&y.execute(i,t);for(var O=H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW+1,M=H.TRANSLUCENT,R=O;R<M;++R)for(n.updatePass(R),P=A.commands[R],D=A.indices[R],m=0;m<D;++m)Fe(P[m],e,i,t);0!==T&&e.mode!==ge.SCENE2D&&(o.near=A.near,n.updateFrustum(o));var N;if(!l&&c.useInvertClassification&&e.frameState.invertClassificationColor.alpha<1&&(N=e._invertClassification),n.updatePass(H.TRANSLUCENT),P=A.commands[H.TRANSLUCENT],P.length=A.indices[H.TRANSLUCENT],f(e,Fe,t,P,N),h(x)&&(c.useGlobeDepthFramebuffer||u)&&e.useDepthPicking){var L=u?t.framebuffer.depthStencilTexture:x.framebuffer.depthStencilTexture,k=ze(e,T);k.update(i,L),k.executeCopyDepth(i,t)}}}function He(e){e.context.uniformState.updatePass(H.COMPUTE);var t=e._environmentState.sunComputeCommand;h(t)&&t.execute(e._computeEngine);for(var r=e._computeCommandList,i=r.length,n=0;n<i;++n)r[n].execute(e._computeEngine)}function We(e,t){e.context.uniformState.updatePass(H.OVERLAY);for(var r=e.context,i=e._overlayCommandList,n=i.length,o=0;o<n;++o)i[o].execute(r,t)}function je(e,t,r){for(var i=r.shadowMapCullingVolume,n=r.isPointLight,o=r.passes,a=o.length,s=t.length,l=0;l<s;++l){var u=t[l];if(Ee(e,u),u.castShadows&&(u.pass===H.GLOBE||u.pass===H.CESIUM_3D_TILE||u.pass===H.OPAQUE||u.pass===H.TRANSLUCENT)&&Me(u,i))if(n)for(var c=0;c<a;++c)o[c].commandList.push(u);else if(1===a)o[0].commandList.push(u);else for(var d=!1,h=a-1;h>=0;--h){var p=o[h].cullingVolume;if(Me(u,p))o[h].commandList.push(u),d=!0;else if(d)break}}}function qe(e){var t=e.frameState,r=t.shadowHints.shadowMaps,i=r.length;if(t.shadowHints.shadowsEnabled)for(var n=e.context,o=n.uniformState,a=0;a<i;++a){var s=r[a];if(!s.outOfView){var l,u=s.passes,c=u.length;for(l=0;l<c;++l)u[l].commandList.length=0;var d=e.frameState.commandList;for(je(e,d,s),l=0;l<c;++l){var h=s.passes[l];o.updateCamera(h.camera),s.updatePass(n,l);for(var p=h.commandList.length,f=0;f<p;++f){var m=h.commandList[f];o.updatePass(m.pass),Fe(m.derivedCommands.shadows.castCommands[a],e,n,h.passState)}}}}}function Ye(e,t,r){var i=e._context,o=t.viewport;o.x=0,o.y=0,o.width=i.drawingBufferWidth,o.height=i.drawingBufferHeight;var a=e._frameState,s=a.camera,l=a.mode,u=a.passes.depth;if(e._useWebVR&&l!==ge.SCENE2D){et(e,t,r),u||$e(e),Re(e),u||(He(e),qe(e)),o.x=0,o.y=0,o.width=.5*i.drawingBufferWidth,o.height=i.drawingBufferHeight;var c=K.clone(s,e._cameraVR),h=s.frustum.near,p=h*d(e.focalLength,5),f=d(e.eyeSeparation,p/30),m=n.multiplyByScalar(c.right,.5*f,wt);s.frustum.aspectRatio=o.width/o.height;var g=.5*f*h/p;n.add(c.position,m,s.position),s.frustum.xOffset=g,Ge(e,t),o.x=t.viewport.width,n.subtract(c.position,m,s.position),s.frustum.xOffset=-g,Ge(e,t),K.clone(c,s)}else l!==ge.SCENE2D||e._mapMode2D===ue.ROTATE?Qe(!0,e,t,r):(et(e,t,r),Xe(e,t))}function Xe(t,r){var i=t.context,o=t.frameState,a=t.camera,s=r.viewport,l=e.clone(s,Ot);r.viewport=l;var u=Tt,c=At;t.mapProjection.project(u,c);var d=n.clone(a.position,Et),h=E.clone(a.transform,Pt),p=a.frustum.clone();a._setTransform(E.IDENTITY);var f=E.computeViewportTransformation(l,0,1,xt),m=a.frustum.projectionMatrix,g=a.positionWC.y,_=n.fromElements(A.sign(g)*c.x-g,0,-a.positionWC.x,Dt),v=k.pointToGLWindowCoordinates(m,f,_,It);v.x=Math.floor(v.x);var y=l.x,C=l.width;if(0===g||v.x<=y||v.x>=y+C)Qe(!0,t,r);else if(Math.abs(y+.5*C-v.x)<1)l.width=v.x-l.x,a.position.x*=A.sign(a.position.x),a.frustum.right=0,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Qe(!0,t,r),l.x=v.x,a.position.x=-a.position.x,a.frustum.right=-a.frustum.left,a.frustum.left=0,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Qe(!1,t,r);else if(v.x>y+.5*C){l.width=v.x-y;var b=a.frustum.right;a.frustum.right=c.x-g,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Qe(!0,t,r),l.x=v.x,l.width=y+C-v.x,a.position.x=-a.position.x,a.frustum.left=-a.frustum.right,a.frustum.right=b-2*a.frustum.right,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Qe(!1,t,r)}else{l.x=v.x,l.width=y+C-v.x;var S=a.frustum.left;a.frustum.left=-c.x-g,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Qe(!0,t,r),l.x=y,l.width=v.x-y,a.position.x=-a.position.x,a.frustum.right=-a.frustum.left,a.frustum.left=S-2*a.frustum.left,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Qe(!1,t,r)}a._setTransform(h),n.clone(d,a.position),a.frustum=p.clone(),r.viewport=s}function Qe(e,t,r,i){var n=t.frameState.passes.depth;e||n||(t.frameState.commandList.length=0),n||$e(t),Re(t),e&&(h(i)&&et(t,r,i),n||(He(t),qe(t))),Ge(t,r)}function Ze(e,t){var r=e._frameState,i=e._environmentState,n=r.passes.render,o=e.skyAtmosphere,a=e.globe;if(!n||e._mode!==ge.SCENE2D&&r.camera.frustum instanceof D)i.skyAtmosphereCommand=void 0,i.skyBoxCommand=void 0,i.sunDrawCommand=void 0,i.sunComputeCommand=void 0,i.moonCommand=void 0;else{h(o)&&h(a)&&(o.setDynamicAtmosphereColor(a.enableLighting),i.isReadyForAtmosphere=i.isReadyForAtmosphere||a._surface._tilesToRender.length>0),i.skyAtmosphereCommand=h(o)?o.update(r):void 0,i.skyBoxCommand=h(e.skyBox)?e.skyBox.update(r):void 0;var s=h(e.sun)?e.sun.update(r,t):void 0;i.sunDrawCommand=h(s)?s.drawCommand:void 0,i.sunComputeCommand=h(s)?s.computeCommand:void 0,i.moonCommand=h(e.moon)?e.moon.update(r):void 0}var l=i.clearGlobeDepth=h(a)&&(!a.depthTestAgainstTerrain||e.mode===ge.SCENE2D);(i.useDepthPlane=l&&e.mode===ge.SCENE3D)&&e._depthPlane.update(r);for(var u=r.mode===ge.SCENE3D?r.occluder:void 0,c=r.cullingVolume,d=gt.planes,p=0;p<5;++p)d[p]=c.planes[p];c=gt,i.isSkyAtmosphereVisible=h(i.skyAtmosphereCommand)&&i.isReadyForAtmosphere,i.isSunVisible=Me(i.sunDrawCommand,c,u),i.isMoonVisible=Me(i.moonCommand,c,u)}function Ke(e){var t=e._frameState;e.debugShowFrustumPlanes!==e._debugShowFrustumPlanes&&(e.debugShowFrustumPlanes?e._debugFrustumPlanes=new $({camera:e.camera,updateOnChange:!1}):e._debugFrustumPlanes=e._debugFrustumPlanes&&e._debugFrustumPlanes.destroy(),e._debugShowFrustumPlanes=e.debugShowFrustumPlanes),h(e._debugFrustumPlanes)&&e._debugFrustumPlanes.update(t)}function Je(e){var t=e._frameState,r=t.shadowMaps,i=r.length,n=i>0&&!t.passes.pick&&e.mode===ge.SCENE3D;if(n!==t.shadowHints.shadowsEnabled&&(++t.shadowHints.lastDirtyTime,t.shadowHints.shadowsEnabled=n),n){for(var o=0;o<i;++o)if(r[o]!==t.shadowHints.shadowMaps[o]){++t.shadowHints.lastDirtyTime;break}t.shadowHints.shadowMaps.length=0,t.shadowHints.lightShadowMaps.length=0;for(var a=0;a<i;++a){var s=r[a];s.update(t),t.shadowHints.shadowMaps.push(s),s.fromLightSource&&t.shadowHints.lightShadowMaps.push(s),s.dirty&&(++t.shadowHints.lastDirtyTime,s.dirty=!1)}}}function $e(e){var t=e._frameState;e._groundPrimitives.update(t),e._primitives.update(t),Ke(e),Je(e),e._globe&&e._globe.update(t)}function et(e,t,r){var i=e._context,n=e._environmentState,o=e._frameState.passes,a=o.pick,l=e._useWebVR&&e.mode!==ge.SCENE2D;n.originalFramebuffer=t.framebuffer,h(e.sun)&&e.sunBloom!==e._sunBloom?(e.sunBloom&&!l?e._sunPostProcess=new be:h(e._sunPostProcess)&&(e._sunPostProcess=e._sunPostProcess.destroy()),e._sunBloom=e.sunBloom):!h(e.sun)&&h(e._sunPostProcess)&&(e._sunPostProcess=e._sunPostProcess.destroy(),e._sunBloom=!1);var u=e._clearColorCommand;s.clone(r,u.color),u.execute(i,t);var c=n.useGlobeDepthFramebuffer=!a&&h(e._globeDepth);c&&(e._globeDepth.update(i,t),e._globeDepth.clear(i,t,r));var d=n.useOIT=!a&&h(e._oit)&&e._oit.isSupported();d&&(e._oit.update(i,t,e._globeDepth.framebuffer),e._oit.clear(i,t,r),n.useOIT=e._oit.isSupported());var p=n.useFXAA=!a&&e.fxaa;if(p&&(e._fxaa.update(i,t),e._fxaa.clear(i,t,r)),n.isSunVisible&&e.sunBloom&&!l?t.framebuffer=e._sunPostProcess.update(t):c?t.framebuffer=e._globeDepth.framebuffer:p&&(t.framebuffer=e._fxaa.getColorFramebuffer()),h(t.framebuffer)&&u.execute(i,t),n.useInvertClassification=!a&&h(t.framebuffer)&&e.invertClassification){var f;if(1===e.frameState.invertClassificationColor.alpha&&(n.useGlobeDepthFramebuffer?f=e._globeDepth.framebuffer:n.useFXAA&&(f=e._fxaa.getColorFramebuffer())),e._invertClassification.previousFramebuffer=f,e._invertClassification.update(i),e._invertClassification.clear(i,t),e.frameState.invertClassificationColor.alpha<1&&d){var m=e._invertClassification.unclassifiedCommand,g=m.derivedCommands;g.oit=e._oit.createDerivedCommands(m,i,g.oit)}}}function tt(e,t){var r=e._context,i=e._environmentState,n=i.useGlobeDepthFramebuffer;if(e.debugShowGlobeDepth&&n){Ve(e,e.debugShowDepthFrustum-1).executeDebugGlobeDepth(r,t)}if(e.debugShowPickDepth&&n){ze(e,e.debugShowDepthFrustum-1).executeDebugPickDepth(r,t)}var o=i.useOIT,a=i.useFXAA;o&&(t.framebuffer=a?e._fxaa.getColorFramebuffer():void 0,e._oit.execute(r,t)),a&&(!o&&n&&(t.framebuffer=e._fxaa.getColorFramebuffer(),e._globeDepth.executeCopyColor(r,t)),t.framebuffer=i.originalFramebuffer,e._fxaa.execute(r,t)),o||a||!n||(t.framebuffer=i.originalFramebuffer,e._globeDepth.executeCopyColor(r,t))}function rt(e){for(var t=e.afterRender,r=0,i=t.length;r<i;++r)t[r]();t.length=0}function it(e,t){e._pickPositionCacheDirty=!0,h(t)||(t=T.now());var r=e._camera;Ae(r,e._cameraClone,A.EPSILON6)?e._cameraStartFired&&b()-e._cameraMovedTime>e.cameraEventWaitTime&&(r.moveEnd.raiseEvent(),e._cameraStartFired=!1):(e._cameraStartFired||(r.moveStart.raiseEvent(),e._cameraStartFired=!0),e._cameraMovedTime=b(),K.clone(r,e._cameraClone)),e._preRender.raiseEvent(e,t),e._jobScheduler.resetBudgets();var i=e.context,o=i.uniformState,a=e._frameState;De(e,A.incrementWrap(a.frameNumber,15e6,1),t),a.passes.render=!0;var l=d(e.backgroundColor,s.BLACK);a.backgroundColor=l,a.creditDisplay.beginFrame(),e.fog.update(a),o.update(a);var u=e.shadowMap;h(u)&&u.enabled&&(n.negate(o.sunDirectionWC,e._sunCamera.direction),a.shadowMaps.push(u)),e._computeCommandList.length=0,e._overlayCommandList.length=0;var c=e._passState;if(c.framebuffer=void 0,c.blendingEnabled=void 0,c.scissorTest=void 0,h(e.globe)&&e.globe.beginFrame(a),Ze(e,c),Ye(e,c,l),tt(e,c),We(e,c),h(e.globe)&&e.globe.endFrame(a),a.creditDisplay.endFrame(),e.debugShowFramesPerSecond){if(!h(e._performanceDisplay)){var p=document.createElement("div");p.className="cesium-performanceDisplay-defaultContainer";e._canvas.parentNode.appendChild(p);var f=new de({container:p});e._performanceDisplay=f,e._performanceContainer=p}e._performanceDisplay.update()}else h(e._performanceDisplay)&&(e._performanceDisplay=e._performanceDisplay&&e._performanceDisplay.destroy(),e._performanceContainer.parentNode.removeChild(e._performanceContainer));i.endFrame(),N.update(),rt(a),e._postRender.raiseEvent(e,t)}function nt(e,t,r,i){var o=e._camera,a=o.frustum;h(a._offCenterFrustum)&&(a=a._offCenterFrustum);var s=e._passState.viewport,l=2*(t.x-s.x)/s.width-1;l*=.5*(a.right-a.left);var u=2*(s.height-t.y-s.y)/s.height-1;u*=.5*(a.top-a.bottom);var c=E.clone(o.transform,kt);o._setTransform(E.IDENTITY);var d=n.clone(o.position,Rt);n.multiplyByScalar(o.right,l,Nt),n.add(Nt,d,d),n.multiplyByScalar(o.up,u,Nt),n.add(Nt,d,d),o._setTransform(c),e.mode===ge.SCENE2D&&n.fromElements(d.z,d.x,d.y,d);var p=a.getPixelDimensions(s.width,s.height,1,Lt),f=Mt;return f.right=.5*p.x,f.left=-f.right,f.top=.5*p.y,f.bottom=-f.top,f.near=a.near,f.far=a.far,f.computeCullingVolume(d,o.directionWC,o.upWC)}function ot(e,t,r,i){var n=e._camera,o=n.frustum,a=o.near,s=Math.tan(.5*o.fovy),l=o.aspectRatio*s,u=e._passState.viewport,c=2*(t.x-u.x)/u.width-1,d=2*(u.height-t.y-u.y)/u.height-1,h=c*a*l,p=d*a*s,f=o.getPixelDimensions(u.width,u.height,1,Lt),m=f.x*r*.5,g=f.y*i*.5,_=Ft;return _.top=p+g,_.bottom=p-g,_.right=h+m,_.left=h-m,_.near=a,_.far=o.far,_.computeCullingVolume(n.positionWC,n.directionWC,n.upWC)}function at(e,t,r,i){var n=e.camera.frustum;return n instanceof D||n instanceof I?nt(e,t,r,i):ot(e,t,r,i)}function st(e,t){var r=e.shaderCache.getDerivedShaderProgram(t,"depthOnly");if(!h(r)){for(var i=t._attributeLocations,n=t.fragmentShaderSource,o=!1,a=n.sources,s=a.length,l=0;l<s;++l)if(Ht.test(a[l])||Wt.test(a[l])){o=!0;break}o||(n=new X({sources:["void main() { gl_FragColor = vec4(1.0); }"]})),r=e.shaderCache.createDerivedShaderProgram(t,"depthOnly",{vertexShaderSource:t.vertexShaderSource,fragmentShaderSource:n,attributeLocations:i})}return r}function lt(e,t){var r=e._depthOnlyRenderStateCache,i=r[t.id];if(!h(i)){var n=q.getState(t);n.depthMask=!0,n.colorMask={red:!1,green:!1,blue:!1,alpha:!1},i=q.fromCache(n),r[t.id]=i}return i}function ut(e,t,r,i){h(i)||(i={});var n,o;return h(i.depthOnlyCommand)&&(n=i.depthOnlyCommand.shaderProgram,o=i.depthOnlyCommand.renderState),i.depthOnlyCommand=z.shallowClone(t,i.depthOnlyCommand),h(n)&&i.shaderProgramId===t.shaderProgram.id?(i.depthOnlyCommand.shaderProgram=n,i.depthOnlyCommand.renderState=o):(i.depthOnlyCommand.shaderProgram=st(r,t.shaderProgram),i.depthOnlyCommand.renderState=lt(e,t.renderState),i.shaderProgramId=t.shaderProgram.id),i}function ct(t,r){var i=t._context,n=t._frameState;Pe(n.passes),n.passes.pick=!0,n.passes.depth=!0,n.cullingVolume=at(t,r,1,1);var o=t._pickDepthPassState;h(o)||(o=t._pickDepthPassState=new W(i),o.scissorTest={enabled:!0,rectangle:new e},o.viewport=new e);var a=i.drawingBufferWidth,s=i.drawingBufferHeight,l=t._pickDepthFramebuffer,u=t._pickDepthFramebufferWidth,c=t._pickDepthFramebufferHeight;h(l)&&u===a&&c===s||(t._pickDepthFramebuffer=t._pickDepthFramebuffer&&t._pickDepthFramebuffer.destroy(),l=t._pickDepthFramebuffer=new G({context:i,depthStencilTexture:new Q({context:i,width:a,height:s,pixelFormat:R.DEPTH_STENCIL,pixelDatatype:j.UNSIGNED_INT_24_8})}),t._pickDepthFramebufferWidth=a,t._pickDepthFramebufferHeight=s),o.framebuffer=l,o.viewport.width=a,o.viewport.height=s,o.scissorTest.rectangle.x=r.x,o.scissorTest.rectangle.y=s-r.y,o.scissorTest.rectangle.width=1,o.scissorTest.rectangle.height=1,Ze(t,o),Ye(t,o,zt),tt(t,o),i.endFrame()}var dt=.9999;p(we.prototype,{canvas:{get:function(){return this._canvas}},drawingBufferHeight:{get:function(){return this._context.drawingBufferHeight}},drawingBufferWidth:{get:function(){return this._context.drawingBufferWidth}},maximumAliasedLineWidth:{get:function(){return V.maximumAliasedLineWidth}},maximumCubeMapSize:{get:function(){return V.maximumCubeMapSize}},pickPositionSupported:{get:function(){return this._context.depthTexture}},globe:{get:function(){return this._globe},set:function(e){this._globe=this._globe&&this._globe.destroy(),this._globe=e}},primitives:{get:function(){return this._primitives}},groundPrimitives:{get:function(){return this._groundPrimitives}},camera:{get:function(){return this._camera}},screenSpaceCameraController:{get:function(){return this._screenSpaceCameraController}},mapProjection:{get:function(){return this._mapProjection}},frameState:{get:function(){return this._frameState}},tweens:{get:function(){return this._tweens}},imageryLayers:{get:function(){if(h(this.globe))return this.globe.imageryLayers}},terrainProvider:{get:function(){if(h(this.globe))return this.globe.terrainProvider},set:function(e){h(this.globe)&&(this.globe.terrainProvider=e)}},terrainProviderChanged:{get:function(){if(h(this.globe))return this.globe.terrainProviderChanged}},renderError:{get:function(){return this._renderError}},preRender:{get:function(){return this._preRender}},postRender:{get:function(){return this._postRender}},context:{get:function(){return this._context}},debugFrustumStatistics:{get:function(){return this._debugFrustumStatistics}},scene3DOnly:{get:function(){return this._frameState.scene3DOnly}},orderIndependentTranslucency:{get:function(){return h(this._oit)}},id:{get:function(){return this._id}},mode:{get:function(){return this._mode},set:function(e){e===ge.SCENE2D?this.morphTo2D(0):e===ge.SCENE3D?this.morphTo3D(0):e===ge.COLUMBUS_VIEW&&this.morphToColumbusView(0),this._mode=e}},numberOfFrustums:{get:function(){return this._frustumCommandsList.length}},terrainExaggeration:{get:function(){return this._terrainExaggeration}},useWebVR:{get:function(){return this._useWebVR},set:function(e){this._useWebVR=e,this._useWebVR?(this._frameState.creditDisplay.container.style.visibility="hidden",this._cameraVR=new K(this),h(this._deviceOrientationCameraController)||(this._deviceOrientationCameraController=new te(this)),this._aspectRatioVR=this._camera.frustum.aspectRatio):(this._frameState.creditDisplay.container.style.visibility="visible",this._cameraVR=void 0,this._deviceOrientationCameraController=this._deviceOrientationCameraController&&!this._deviceOrientationCameraController.isDestroyed()&&this._deviceOrientationCameraController.destroy(),this._camera.frustum.aspectRatio=this._aspectRatioVR,this._camera.frustum.xOffset=0)}},mapMode2D:{get:function(){return this._mapMode2D}},imagerySplitPosition:{get:function(){return this._frameState.imagerySplitPosition},set:function(e){this._frameState.imagerySplitPosition=e}},minimumDisableDepthTestDistance:{get:function(){return this._minimumDisableDepthTestDistance},set:function(e){this._minimumDisableDepthTestDistance=e}}}),we.prototype.getCompressedTextureFormatSupported=function(e){var t=this.context;return("WEBGL_compressed_texture_s3tc"===e||"s3tc"===e)&&t.s3tc||("WEBGL_compressed_texture_pvrtc"===e||"pvrtc"===e)&&t.pvrtc||("WEBGL_compressed_texture_etc1"===e||"etc1"===e)&&t.etc1};var ht,pt=new n,ft=new n,mt=new t,gt=new c,_t=new w,vt=new E(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1);vt=E.inverseTransformation(vt,vt);var yt=new O,Ct=new M,bt=new D,St=new I,wt=new n,Tt=new a(Math.PI,A.PI_OVER_TWO),At=new n,Et=new n,xt=new E,Pt=new E,Dt=new n,It=new n,Ot=new e;we.prototype.initializeFrame=function(){120==this._shaderFrameCount++&&(this._shaderFrameCount=0,this._context.shaderCache.destroyReleasedShaderPrograms()),this._tweens.update(),this._screenSpaceCameraController.update(),h(this._deviceOrientationCameraController)&&this._deviceOrientationCameraController.update(),this._camera.update(this._mode),this._camera._updateCameraChanged()},we.prototype.render=function(e){try{it(this,e)}catch(e){if(this._renderError.raiseEvent(this,e),this.rethrowRenderErrors)throw e}},we.prototype.clampLineWidth=function(e){return Math.max(V.minimumAliasedLineWidth,Math.min(e,V.maximumAliasedLineWidth))};var Mt=new I,Rt=new n,Nt=new n,Lt=new i,kt=new E,Ft=new M,Bt=3,Ut=3,Vt=new e(0,0,Bt,Ut),zt=new s(0,0,0,0),Gt=new i;we.prototype.pick=function(e,t,r){Bt=d(t,3),Ut=d(r,Bt);var i=this._context,n=i.uniformState,o=this._frameState,a=_e.transformWindowToDrawingBuffer(this,e,Gt);h(this._pickFramebuffer)||(this._pickFramebuffer=i.createPickFramebuffer()),this._jobScheduler.disableThisFrame(),De(this,o.frameNumber,o.time),o.cullingVolume=at(this,a,Bt,Ut),o.invertClassification=!1,o.passes.pick=!0,n.update(o),Vt.x=a.x-.5*(Bt-1),Vt.y=this.drawingBufferHeight-a.y-.5*(Ut-1),Vt.width=Bt,Vt.height=Ut;var s=this._pickFramebuffer.begin(Vt);Ze(this,s),Ye(this,s,zt),tt(this,s);var l=this._pickFramebuffer.end(Vt);return i.endFrame(),rt(o),l};var Ht=/\bgl_FragDepthEXT\b/,Wt=/\bdiscard\b/,jt=new o,qt=new o(1,1/255,1/65025,1/16581375);we.prototype.pickPositionWorldCoordinates=function(e,t){if(this.useDepthPicking){var r=e.toString();if(this._pickPositionCacheDirty)this._pickPositionCache={},this._pickPositionCacheDirty=!1;else if(this._pickPositionCache.hasOwnProperty(r))return n.clone(this._pickPositionCache[r],t);var i=this._context,a=i.uniformState,s=_e.transformWindowToDrawingBuffer(this,e,Gt);this.pickTranslucentDepth&&ct(this,s),s.y=this.drawingBufferHeight-s.y;var l,u=this._camera;l=h(u.frustum.fov)?u.frustum.clone(yt):h(u.frustum.infiniteProjectionMatrix)?u.frustum.clone(Ct):h(u.frustum.width)?u.frustum.clone(bt):u.frustum.clone(St);for(var c=this.numberOfFrustums,d=0;d<c;++d){var p=ze(this,d),f=i.readPixels({x:s.x,y:s.y,width:1,height:1,framebuffer:p.framebuffer}),m=o.unpack(f,0,jt);o.divideByScalar(m,255,m);var g=o.dot(m,qt);if(g>0&&g<1){var _,v=this._frustumCommandsList[d];return this.mode===ge.SCENE2D?(_=u.position.z,u.position.z=_-v.near+1,l.far=Math.max(1,v.far-v.near),l.near=1,a.update(this.frameState),a.updateFrustum(l)):(l.near=v.near*(0!==d?dt:1),l.far=v.far,a.updateFrustum(l)),t=_e.drawingBufferToWgs84Coordinates(this,s,g,t),this.mode===ge.SCENE2D&&(u.position.z=_,a.update(this.frameState)),this._pickPositionCache[r]=n.clone(t),t}}this._pickPositionCache[r]=void 0}};var Yt=new a;return we.prototype.pickPosition=function(e,t){if(t=this.pickPositionWorldCoordinates(e,t),h(t)&&this.mode!==ge.SCENE3D){n.fromElements(t.y,t.z,t.x,t);var r=this.mapProjection,i=r.ellipsoid,o=r.unproject(t,Yt);i.cartographicToCartesian(o,t)}return t},we.prototype.drillPick=function(e,t){var r,i,n=[],o=[],a=[];h(t)||(t=Number.MAX_VALUE);for(var s=this.pick(e);h(s)&&h(s.primitive)&&(n.push(s),!(0>=--t));){var l=s.primitive,u=!1;"function"==typeof l.getGeometryInstanceAttributes&&h(s.id)&&(i=l.getGeometryInstanceAttributes(s.id),h(i)&&h(i.show)&&(u=!0,i.show=L.toValue(!1,i.show),a.push(i))),u||(l.show=!1,o.push(l)),s=this.pick(e)}for(r=0;r<o.length;++r)o[r].show=!0;for(r=0;r<a.length;++r)i=a[r],i.show=L.toValue(!0,i.show);return n},we.prototype.completeMorph=function(){this._transitioner.completeMorph()},we.prototype.morphTo2D=function(e){var t,r=this.globe;t=h(r)?r.ellipsoid:this.mapProjection.ellipsoid,e=d(e,2),this._transitioner.morphTo2D(e,t)},we.prototype.morphToColumbusView=function(e){var t,r=this.globe;t=h(r)?r.ellipsoid:this.mapProjection.ellipsoid,e=d(e,2),this._transitioner.morphToColumbusView(e,t)},we.prototype.morphTo3D=function(e){var t,r=this.globe;t=h(r)?r.ellipsoid:this.mapProjection.ellipsoid,e=d(e,2),this._transitioner.morphTo3D(e,t)},we.prototype.isDestroyed=function(){return!1},we.prototype.destroy=function(){return this._tweens.removeAll(),this._computeEngine=this._computeEngine&&this._computeEngine.destroy(),this._screenSpaceCameraController=this._screenSpaceCameraController&&this._screenSpaceCameraController.destroy(),this._deviceOrientationCameraController=this._deviceOrientationCameraController&&!this._deviceOrientationCameraController.isDestroyed()&&this._deviceOrientationCameraController.destroy(),this._pickFramebuffer=this._pickFramebuffer&&this._pickFramebuffer.destroy(),this._pickDepthFramebuffer=this._pickDepthFramebuffer&&this._pickDepthFramebuffer.destroy(),this._primitives=this._primitives&&this._primitives.destroy(),this._groundPrimitives=this._groundPrimitives&&this._groundPrimitives.destroy(),this._globe=this._globe&&this._globe.destroy(),this.skyBox=this.skyBox&&this.skyBox.destroy(),this.skyAtmosphere=this.skyAtmosphere&&this.skyAtmosphere.destroy(),this._debugSphere=this._debugSphere&&this._debugSphere.destroy(),this.sun=this.sun&&this.sun.destroy(),this._sunPostProcess=this._sunPostProcess&&this._sunPostProcess.destroy(),this._depthPlane=this._depthPlane&&this._depthPlane.destroy(),this._transitioner.destroy(),this._debugFrustumPlanes=this._debugFrustumPlanes&&this._debugFrustumPlanes.destroy(),this._brdfLutGenerator=this._brdfLutGenerator&&this._brdfLutGenerator.destroy(),h(this._globeDepth)&&this._globeDepth.destroy(),this._removeCreditContainer&&this._canvas.parentNode.removeChild(this._creditContainer),h(this._oit)&&this._oit.destroy(),this._fxaa.destroy(),this._context=this._context&&this._context.destroy(),this._frameState.creditDisplay.destroy(),h(this._performanceDisplay)&&(this._performanceDisplay=this._performanceDisplay&&this._performanceDisplay.destroy(), -this._performanceContainer.parentNode.removeChild(this._performanceContainer)),f(this)},we.prototype.cartesianToCanvasCoordinates=function(e,t){return _e.wgs84ToWindowCoordinates(this,e,t)},we}),define("Scene/SingleTileImageryProvider",["../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/loadImage","../Core/Rectangle","../Core/RuntimeError","../Core/TileProviderError","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(i){function n(e){b._image=e,b._tileWidth=e.width,b._tileHeight=e.height,b._ready=!0,b._readyPromise.resolve(!0),c.handleSuccess(b._errorEvent)}function h(e){var t="Failed to load image "+v+".";C=c.handleError(C,b,b._errorEvent,t,0,0,0,p,e),b._readyPromise.reject(new u(t))}function p(){d(s(v),n,h)}i=t(i,{});var f=i.url;this._url=f;var m=i.proxy;this._proxy=m;var g=t(i.rectangle,l.MAX_VALUE),_=new a({rectangle:g,numberOfLevelZeroTilesX:1,numberOfLevelZeroTilesY:1,ellipsoid:i.ellipsoid});this._tilingScheme=_,this._image=void 0,this._texture=void 0,this._tileWidth=0,this._tileHeight=0,this._errorEvent=new o,this._ready=!1,this._readyPromise=d.defer();var v=f;r(m)&&(v=m.getURL(v));var y=i.credit;"string"==typeof y&&(y=new e({text:y})),this._credit=y;var C,b=this;p()}return i(h.prototype,{url:{get:function(){return this._url}},proxy:{get:function(){return this._proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return 0}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!0}}}),h.prototype.getTileCredits=function(e,t,r){},h.prototype.requestImage=function(e,t,r,i){return this._image},h.prototype.pickFeatures=function(e,t,r,i,n){},h}),define("Shaders/SkyAtmosphereFS",[],function(){"use strict";return"#ifdef COLOR_CORRECT\nuniform vec3 u_hsbShift;\n#endif\nuniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\nconst float g = -0.95;\nconst float g2 = g * g;\nvarying vec3 v_rayleighColor;\nvarying vec3 v_mieColor;\nvarying vec3 v_toCamera;\nvarying vec3 v_positionEC;\nvoid main (void)\n{\nfloat cosAngle = dot(czm_sunDirectionWC, normalize(v_toCamera)) / length(v_toCamera);\nfloat rayleighPhase = 0.75 * (1.0 + cosAngle * cosAngle);\nfloat miePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cosAngle * cosAngle) / pow(1.0 + g2 - 2.0 * g * cosAngle, 1.5);\nconst float exposure = 2.0;\nvec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor;\nrgb = vec3(1.0) - exp(-exposure * rgb);\nfloat l = czm_luminance(rgb);\n#ifdef COLOR_CORRECT\nvec3 hsb = czm_RGBToHSB(rgb);\nhsb.x += u_hsbShift.x;\nhsb.y = clamp(hsb.y + u_hsbShift.y, 0.0, 1.0);\nhsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0;\nrgb = czm_HSBToRGB(hsb);\nl = min(l, czm_luminance(rgb));\n#endif\nfloat atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0);\nfloat nightAlpha = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), 0.0, 1.0) : 1.0;\natmosphereAlpha *= pow(nightAlpha, 0.5);\ngl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime));\n}\n"}),define("Shaders/SkyAtmosphereVS",[],function(){"use strict";return"attribute vec4 position;\nuniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\nconst float Kr = 0.0025;\nconst float Kr4PI = Kr * 4.0 * czm_pi;\nconst float Km = 0.0015;\nconst float Km4PI = Km * 4.0 * czm_pi;\nconst float ESun = 15.0;\nconst float KmESun = Km * ESun;\nconst float KrESun = Kr * ESun;\nconst vec3 InvWavelength = vec3(\n5.60204474633241,\n9.473284437923038,\n19.643802610477206);\nconst float rayleighScaleDepth = 0.25;\nconst int nSamples = 2;\nconst float fSamples = 2.0;\nvarying vec3 v_rayleighColor;\nvarying vec3 v_mieColor;\nvarying vec3 v_toCamera;\nfloat scale(float cosAngle)\n{\nfloat x = 1.0 - cosAngle;\nreturn rayleighScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\n}\nvoid main(void)\n{\nfloat cameraHeight = u_cameraAndRadiiAndDynamicAtmosphereColor.x;\nfloat outerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.y;\nfloat innerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.z;\nvec3 positionV3 = position.xyz;\nvec3 ray = positionV3 - czm_viewerPositionWC;\nfloat far = length(ray);\nray /= far;\nfloat atmosphereScale = 1.0 / (outerRadius - innerRadius);\n#ifdef SKY_FROM_SPACE\nfloat B = 2.0 * dot(czm_viewerPositionWC, ray);\nfloat C = cameraHeight * cameraHeight - outerRadius * outerRadius;\nfloat det = max(0.0, B*B - 4.0 * C);\nfloat near = 0.5 * (-B - sqrt(det));\nvec3 start = czm_viewerPositionWC + ray * near;\nfar -= near;\nfloat startAngle = dot(ray, start) / outerRadius;\nfloat startDepth = exp(-1.0 / rayleighScaleDepth );\nfloat startOffset = startDepth*scale(startAngle);\n#else // SKY_FROM_ATMOSPHERE\nvec3 start = czm_viewerPositionWC;\nfloat height = length(start);\nfloat depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - cameraHeight));\nfloat startAngle = dot(ray, start) / height;\nfloat startOffset = depth*scale(startAngle);\n#endif\nfloat sampleLength = far / fSamples;\nfloat scaledLength = sampleLength * atmosphereScale;\nvec3 sampleRay = ray * sampleLength;\nvec3 samplePoint = start + sampleRay * 0.5;\nvec3 frontColor = vec3(0.0, 0.0, 0.0);\nvec3 lightDir = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? czm_sunPositionWC - czm_viewerPositionWC : czm_viewerPositionWC;\nlightDir = normalize(lightDir);\nfor(int i=0; i<nSamples; i++)\n{\nfloat height = length(samplePoint);\nfloat depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - height));\nfloat fLightAngle = dot(lightDir, samplePoint) / height;\nfloat fCameraAngle = dot(ray, samplePoint) / height;\nfloat fScatter = (startOffset + depth*(scale(fLightAngle) - scale(fCameraAngle)));\nvec3 attenuate = exp(-fScatter * (InvWavelength * Kr4PI + Km4PI));\nfrontColor += attenuate * (depth * scaledLength);\nsamplePoint += sampleRay;\n}\nv_mieColor = frontColor * KmESun;\nv_rayleighColor = frontColor * (InvWavelength * KrESun);\nv_toCamera = czm_viewerPositionWC - positionV3;\ngl_Position = czm_modelViewProjection * position;\n}\n"}),define("Scene/SkyAtmosphere",["../Core/Cartesian3","../Core/Cartesian4","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Ellipsoid","../Core/EllipsoidGeometry","../Core/GeometryPipeline","../Core/Math","../Core/VertexFormat","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../Shaders/SkyAtmosphereFS","../Shaders/SkyAtmosphereVS","./BlendingState","./CullFace","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b){"use strict";function S(i){i=r(i,a.WGS84),this.show=!0,this._ellipsoid=i,this._command=new h({owner:this}),this._spSkyFromSpace=void 0,this._spSkyFromAtmosphere=void 0,this._spSkyFromSpaceColorCorrect=void 0,this._spSkyFromAtmosphereColorCorrect=void 0,this.hueShift=0,this.saturationShift=0,this.brightnessShift=0,this._hueSaturationBrightness=new e;var n=new t;n.w=0,n.y=e.maximumComponent(e.multiplyByScalar(i.radii,1.025,new e)),n.z=i.maximumRadius,this._cameraAndRadiiAndDynamicAtmosphereColor=n;var o=this;this._command.uniformMap={u_cameraAndRadiiAndDynamicAtmosphereColor:function(){return o._cameraAndRadiiAndDynamicAtmosphereColor},u_hsbShift:function(){return o._hueSaturationBrightness.x=o.hueShift,o._hueSaturationBrightness.y=o.saturationShift,o._hueSaturationBrightness.z=o.brightnessShift,o._hueSaturationBrightness}}}function w(e){return!(u.equalsEpsilon(e.hueShift,0,u.EPSILON7)&&u.equalsEpsilon(e.saturationShift,0,u.EPSILON7)&&u.equalsEpsilon(e.brightnessShift,0,u.EPSILON7))}return n(S.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),S.prototype.setDynamicAtmosphereColor=function(e){this._cameraAndRadiiAndDynamicAtmosphereColor.w=e?1:0},S.prototype.update=function(t){if(this.show){var r=t.mode;if((r===b.SCENE3D||r===b.MORPHING)&&t.passes.render){var n=this._command;if(!i(n.vertexArray)){var o=t.context,a=s.createGeometry(new s({radii:e.multiplyByScalar(this._ellipsoid.radii,1.025,new e),slicePartitions:256,stackPartitions:256,vertexFormat:c.POSITION_ONLY}));n.vertexArray=g.fromGeometry({context:o,geometry:a,attributeLocations:l.createAttributeLocations(a),bufferUsage:d.STATIC_DRAW}),n.renderState=p.fromCache({cull:{enabled:!0,face:C.FRONT},blending:y.ALPHA_BLEND});var u=new m({defines:["SKY_FROM_SPACE"],sources:[v]});this._spSkyFromSpace=f.fromCache({context:o,vertexShaderSource:u,fragmentShaderSource:_}),u=new m({defines:["SKY_FROM_ATMOSPHERE"],sources:[v]}),this._spSkyFromAtmosphere=f.fromCache({context:o,vertexShaderSource:u,fragmentShaderSource:_})}var h=w(this);if(h&&(!i(this._spSkyFromSpaceColorCorrect)||!i(this._spSkyFromAtmosphereColorCorrect))){var S=t.context,T=new m({defines:["SKY_FROM_SPACE"],sources:[v]}),A=new m({defines:["COLOR_CORRECT"],sources:[_]});this._spSkyFromSpaceColorCorrect=f.fromCache({context:S,vertexShaderSource:T,fragmentShaderSource:A}),T=new m({defines:["SKY_FROM_ATMOSPHERE"],sources:[v]}),this._spSkyFromAtmosphereColorCorrect=f.fromCache({context:S,vertexShaderSource:T,fragmentShaderSource:A})}var E=t.camera.positionWC,x=e.magnitude(E);return this._cameraAndRadiiAndDynamicAtmosphereColor.x=x,x>this._cameraAndRadiiAndDynamicAtmosphereColor.y?n.shaderProgram=h?this._spSkyFromSpaceColorCorrect:this._spSkyFromSpace:n.shaderProgram=h?this._spSkyFromAtmosphereColorCorrect:this._spSkyFromAtmosphere,n}}},S.prototype.isDestroyed=function(){return!1},S.prototype.destroy=function(){var e=this._command;return e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),this._spSkyFromSpace=this._spSkyFromSpace&&this._spSkyFromSpace.destroy(),this._spSkyFromAtmosphere=this._spSkyFromAtmosphere&&this._spSkyFromAtmosphere.destroy(),this._spSkyFromSpaceColorCorrect=this._spSkyFromSpaceColorCorrect&&this._spSkyFromSpaceColorCorrect.destroy(),this._spSkyFromAtmosphereColorCorrect=this._spSkyFromAtmosphereColorCorrect&&this._spSkyFromAtmosphereColorCorrect.destroy(),o(this)},S}),define("Shaders/SkyBoxFS",[],function(){"use strict";return"uniform samplerCube u_cubeMap;\nvarying vec3 v_texCoord;\nvoid main()\n{\nvec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb;\ngl_FragColor = vec4(rgb, czm_morphTime);\n}\n"}),define("Shaders/SkyBoxVS",[],function(){"use strict";return"attribute vec3 position;\nvarying vec3 v_texCoord;\nvoid main()\n{\nvec3 p = czm_viewRotation * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\ngl_Position = czm_projection * vec4(p, 1.0);\nv_texCoord = position.xyz;\n}\n"}),define("Scene/SkyBox",["../Core/BoxGeometry","../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/GeometryPipeline","../Core/Matrix4","../Core/VertexFormat","../Renderer/BufferUsage","../Renderer/CubeMap","../Renderer/DrawCommand","../Renderer/loadCubeMap","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/VertexArray","../Shaders/SkyBoxFS","../Shaders/SkyBoxVS","./BlendingState","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function C(e){this.sources=e.sources,this._sources=void 0,this.show=r(e.show,!0),this._command=new d({modelMatrix:s.clone(s.IDENTITY),owner:this}),this._cubeMap=void 0}return C.prototype.update=function(r){var n=this;if(this.show&&(r.mode===y.SCENE3D||r.mode===y.MORPHING)&&r.passes.render){var o=r.context;if(this._sources!==this.sources){this._sources=this.sources;var s=this.sources;"string"==typeof s.positiveX?h(o,this._sources).then(function(e){n._cubeMap=n._cubeMap&&n._cubeMap.destroy(),n._cubeMap=e}):(this._cubeMap=this._cubeMap&&this._cubeMap.destroy(),this._cubeMap=new c({context:o,source:s}))}var d=this._command;if(!i(d.vertexArray)){d.uniformMap={u_cubeMap:function(){return n._cubeMap}};var C=e.createGeometry(e.fromDimensions({dimensions:new t(2,2,2),vertexFormat:l.POSITION_ONLY})),b=a.createAttributeLocations(C);d.vertexArray=m.fromGeometry({context:o,geometry:C,attributeLocations:b,bufferUsage:u.STATIC_DRAW}),d.shaderProgram=f.fromCache({context:o,vertexShaderSource:_,fragmentShaderSource:g,attributeLocations:b}),d.renderState=p.fromCache({blending:v.ALPHA_BLEND})}if(i(this._cubeMap))return d}},C.prototype.isDestroyed=function(){return!1},C.prototype.destroy=function(){var e=this._command;return e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),e.shaderProgram=e.shaderProgram&&e.shaderProgram.destroy(),this._cubeMap=this._cubeMap&&this._cubeMap.destroy(),n(this)},C}),define("Scene/SphereEmitter",["../Core/Cartesian3","../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/Math"],function(e,t,r,i,n){"use strict";function o(e){e=r(e,1),this._radius=r(e,1)}return i(o.prototype,{radius:{get:function(){return this._radius},set:function(e){this._radius=e}}}),o.prototype.emit=function(t){var r=n.randomBetween(0,n.TWO_PI),i=n.randomBetween(0,n.PI),o=n.randomBetween(0,this._radius),a=o*Math.cos(r)*Math.sin(i),s=o*Math.sin(r)*Math.sin(i),l=o*Math.cos(i);t.position=e.fromElements(a,s,l,t.position),t.velocity=e.normalize(t.position,t.velocity)},o}),define("Scene/StyleExpression",["../Core/DeveloperError"],function(e){"use strict";function t(){}return t.prototype.evaluate=function(t,r,i){e.throwInstantiationError()},t.prototype.evaluateColor=function(t,r,i){e.throwInstantiationError()},t.prototype.getShaderFunction=function(t,r,i,n){e.throwInstantiationError()},t}),define("Shaders/SunFS",[],function(){"use strict";return"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_FragColor = texture2D(u_texture, v_textureCoordinates);\n}\n"}),define("Shaders/SunTextureFS",[],function(){"use strict";return"uniform float u_glowLengthTS;\nuniform float u_radiusTS;\nvarying vec2 v_textureCoordinates;\nvec2 rotate(vec2 p, vec2 direction)\n{\nreturn vec2(p.x * direction.x - p.y * direction.y, p.x * direction.y + p.y * direction.x);\n}\nvec4 addBurst(vec2 position, vec2 direction)\n{\nvec2 rotatedPosition = rotate(position, direction) * vec2(25.0, 0.75);\nfloat radius = length(rotatedPosition);\nfloat burst = 1.0 - smoothstep(0.0, 0.55, radius);\nreturn vec4(burst);\n}\nvoid main()\n{\nvec2 position = v_textureCoordinates - vec2(0.5);\nfloat radius = length(position);\nfloat surface = step(radius, u_radiusTS);\nvec4 color = vec4(1.0, 1.0, surface + 0.2, surface);\nfloat glow = 1.0 - smoothstep(0.0, 0.55, radius);\ncolor.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75;\nvec4 burst = vec4(0.0);\nburst += 0.4 * addBurst(position, vec2(0.38942, 0.92106));\nburst += 0.4 * addBurst(position, vec2(0.99235, 0.12348));\nburst += 0.4 * addBurst(position, vec2(0.60327, -0.79754));\nburst += 0.3 * addBurst(position, vec2(0.31457, 0.94924));\nburst += 0.3 * addBurst(position, vec2(0.97931, 0.20239));\nburst += 0.3 * addBurst(position, vec2(0.66507, -0.74678));\ncolor += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15;\ngl_FragColor = clamp(color, vec4(0.0), vec4(1.0));\n}\n"}),define("Shaders/SunVS",[],function(){"use strict";return"attribute vec2 direction;\nuniform float u_size;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec4 position;\nif (czm_morphTime == 1.0)\n{\nposition = vec4(czm_sunPositionWC, 1.0);\n}\nelse\n{\nposition = vec4(czm_sunPositionColumbusView.zxy, 1.0);\n}\nvec4 positionEC = czm_view * position;\nvec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\nvec2 halfSize = vec2(u_size * 0.5);\nhalfSize *= ((direction * 2.0) - 1.0);\ngl_Position = czm_viewportOrthographic * vec4(positionWC.xy + halfSize, -positionWC.z, 1.0);\nv_textureCoordinates = direction;\n}\n"}),define("Scene/Sun",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/ComponentDatatype","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/IndexDatatype","../Core/Math","../Core/Matrix4","../Core/PixelFormat","../Core/PrimitiveType","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ComputeCommand","../Renderer/DrawCommand","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/Texture","../Renderer/VertexArray","../Shaders/SunFS","../Shaders/SunTextureFS","../Shaders/SunVS","./BlendingState","./SceneMode","./SceneTransforms"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E){"use strict";function x(){this.show=!0,this._drawCommand=new g({primitiveType:h.TRIANGLES,boundingVolume:new e,owner:this}),this._commands={drawCommand:this._drawCommand,computeCommand:void 0},this._boundingVolume=new e,this._boundingVolume2D=new e,this._texture=void 0,this._drawingBufferWidth=void 0,this._drawingBufferHeight=void 0,this._radiusTS=void 0,this._size=void 0,this.glowFactor=1,this._glowFactorDirty=!1;var t=this;this._uniformMap={u_texture:function(){return t._texture},u_size:function(){return t._size}}}a(x.prototype,{glowFactor:{get:function(){return this._glowFactor},set:function(e){e=Math.max(e,0),this._glowFactor=e,this._glowFactorDirty=!0}}});var P=new t,D=new t,I=new i,O=new i;return x.prototype.update=function(i,a){if(this.show){var s=i.mode;if(s!==A.SCENE2D&&s!==A.MORPHING&&i.passes.render){var h=i.context,g=a.viewport.width,x=a.viewport.height;if(!o(this._texture)||g!==this._drawingBufferWidth||x!==this._drawingBufferHeight||this._glowFactorDirty){this._texture=this._texture&&this._texture.destroy(),this._drawingBufferWidth=g,this._drawingBufferHeight=x,this._glowFactorDirty=!1;var M=Math.max(g,x);M=Math.pow(2,Math.ceil(Math.log(M)/Math.log(2))-2),M=Math.max(1,M),this._texture=new y({context:h,width:M,height:M,pixelFormat:d.RGBA}),this._glowLengthTS=5*this._glowFactor,this._radiusTS=1/(1+2*this._glowLengthTS)*.5;var R=this,N={u_glowLengthTS:function(){return R._glowLengthTS},u_radiusTS:function(){return R._radiusTS}};this._commands.computeCommand=new m({fragmentShaderSource:S,outputTexture:this._texture,uniformMap:N,persists:!1,owner:this,postExecute:function(){R._commands.computeCommand=void 0}})}var L=this._drawCommand;if(!o(L.vertexArray)){var k={direction:0},F=new Uint8Array(8);F[0]=0,F[1]=0,F[2]=255,F[3]=0,F[4]=255,F[5]=255,F[6]=0,F[7]=255;var B=p.createVertexBuffer({context:h,typedArray:F,usage:f.STATIC_DRAW}),U=[{index:k.direction,vertexBuffer:B,componentsPerAttribute:2,normalize:!0,componentDatatype:n.UNSIGNED_BYTE}],V=p.createIndexBuffer({context:h,typedArray:new Uint16Array([0,1,2,0,2,3]),usage:f.STATIC_DRAW,indexDatatype:l.UNSIGNED_SHORT});L.vertexArray=new C({context:h,attributes:U,indexBuffer:V}),L.shaderProgram=v.fromCache({context:h,vertexShaderSource:w,fragmentShaderSource:b,attributeLocations:k}),L.renderState=_.fromCache({blending:T.ALPHA_BLEND}),L.uniformMap=this._uniformMap}var z=h.uniformState.sunPositionWC,G=h.uniformState.sunPositionColumbusView,H=this._boundingVolume,W=this._boundingVolume2D;r.clone(z,H.center),W.center.x=G.z,W.center.y=G.x,W.center.z=G.y,H.radius=u.SOLAR_RADIUS+u.SOLAR_RADIUS*this._glowLengthTS,W.radius=H.radius,s===A.SCENE3D?e.clone(H,L.boundingVolume):s===A.COLUMBUS_VIEW&&e.clone(W,L.boundingVolume);var j=E.computeActualWgs84Position(i,z,O),q=r.magnitude(r.subtract(j,i.camera.position,O)),Y=h.uniformState.projection,X=I;X.x=0,X.y=0,X.z=-q,X.w=1;var Q=c.multiplyByVector(Y,X,O),Z=E.clipToGLWindowCoordinates(a.viewport,Q,P);X.x=u.SOLAR_RADIUS;var K=c.multiplyByVector(Y,X,O),J=E.clipToGLWindowCoordinates(a.viewport,K,D);return this._size=Math.ceil(t.magnitude(t.subtract(J,Z,O))),this._size=2*this._size*(1+2*this._glowLengthTS),this._commands}}},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){var e=this._drawCommand;return e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),e.shaderProgram=e.shaderProgram&&e.shaderProgram.destroy(),this._texture=this._texture&&this._texture.destroy(),s(this)},x}),define("Scene/TileBoundingVolume",["../Core/DeveloperError"],function(e){"use strict";function t(){}return t.prototype.boundingVolume=void 0,t.prototype.boundingSphere=void 0,t.prototype.distanceToCamera=function(t){e.throwInstantiationError()},t.prototype.intersectPlane=function(t){e.throwInstantiationError()},t.prototype.createDebugVolume=function(t){e.throwInstantiationError()},t}),define("Scene/TileCoordinatesImageryProvider",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","../Core/GeographicTilingScheme","../ThirdParty/when"],function(e,t,r,i,n,o,a){"use strict";function s(i){i=t(i,t.EMPTY_OBJECT),this._tilingScheme=r(i.tilingScheme)?i.tilingScheme:new o({ellipsoid:i.ellipsoid}),this._color=t(i.color,e.YELLOW),this._errorEvent=new n,this._tileWidth=t(i.tileWidth,256),this._tileHeight=t(i.tileHeight,256),this._readyPromise=a.resolve(!0)}return i(s.prototype,{proxy:{get:function(){}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){}},minimumLevel:{get:function(){}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return!0}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){}},hasAlphaChannel:{get:function(){return!0}}}),s.prototype.getTileCredits=function(e,t,r){},s.prototype.requestImage=function(e,t,r,i){var n=document.createElement("canvas");n.width=256,n.height=256;var o=n.getContext("2d"),a=this._color.toCssColorString();o.strokeStyle=a,o.lineWidth=2,o.strokeRect(1,1,255,255);var s="L"+r+"X"+e+"Y"+t;return o.font="bold 25px Arial",o.textAlign="center",o.fillStyle="black",o.fillText(s,127,127),o.fillStyle=a,o.fillText(s,124,124),n},s.prototype.pickFeatures=function(e,t,r,i,n){},s}),define("Scene/TileDiscardPolicy",["../Core/DeveloperError"],function(e){"use strict";function t(t){e.throwInstantiationError()}return t.prototype.isReady=e.throwInstantiationError,t.prototype.shouldDiscardImage=e.throwInstantiationError,t}),define("Scene/TileState",["../Core/freezeObject"],function(e){"use strict";return e({START:0,LOADING:1,READY:2,UPSAMPLED_ONLY:3})}),define("Scene/TimeDynamicImagery",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/JulianDate","../Core/Request","../Core/RequestType"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT),this._tileCache={},this._tilesRequestedForInterval=[];var r=this._clock=e.clock;this._times=e.times,this._requestImageFunction=e.requestImageFunction,this._reloadFunction=e.reloadFunction,this._currentIntervalIndex=-1,r.onTick.addEventListener(this._clockOnTick,this),this._clockOnTick(r)}function u(e,t,r){return e+"-"+t+"-"+r}function c(e){var t=e.split("-");if(3===t.length)return{x:Number(t[0]),y:Number(t[1]),level:Number(t[2])}}function d(e){var t=e._times;if(r(t)){var i=e._clock,n=i.currentTime,a=i.canAnimate&&i.shouldAnimate,s=i.multiplier;if(a||0===s){var l,u=t.indexOf(n);if(-1!==u){var c=t.get(u);return s>0?(l=o.secondsDifference(c.stop,n),++u):(l=o.secondsDifference(c.start,n),--u),l/=s,u>=0&&l<=5?t.get(u):void 0}}}}function h(e,t,i){var n=e._times.indexOf(i.start),o=e._tileCache,l=o[n];r(l)||(l=o[n]={});var u=t.key;if(r(l[u]))return!0;var d=c(u),h=new a({throttle:!0,throttleByServer:!0,type:s.IMAGERY,priorityFunction:t.priorityFunction}),p=e._requestImageFunction(d.x,d.y,d.level,h,i);return!!r(p)&&(l[u]={promise:p,request:h},!0)}return i(l.prototype,{clock:{get:function(){return this._clock},set:function(e){this._clock!==e&&(this._clock=e,this._clockOnTick(e),this._reloadFunction())}},times:{get:function(){return this._times},set:function(e){this._times!==e&&(this._times=e,this._clockOnTick(this._clock),this._reloadFunction())}},currentInterval:{get:function(){return this._times.get(this._currentIntervalIndex)}}}),l.prototype.getFromCache=function(e,t,i,n){var o,a=u(e,t,i),s=this._tileCache[this._currentIntervalIndex];if(r(s)&&r(s[a])){var l=s[a];o=l.promise.otherwise(function(e){throw n.state=l.request.state,e}),delete s[a]}return o},l.prototype.checkApproachingInterval=function(e,t,i,n){var o=u(e,t,i),a=this._tilesRequestedForInterval,s=d(this),l={key:o,priorityFunction:n.priorityFunction};r(s)&&h(this,l,s)||a.push(l),a.length>=512&&a.splice(0,256)},l.prototype._clockOnTick=function(e){var t=e.currentTime,i=this._times,n=i.indexOf(t),o=this._currentIntervalIndex;if(n!==o){var a=this._tileCache[o];for(var s in a)a.hasOwnProperty(s)&&a[s].request.cancel();return delete this._tileCache[o],this._tilesRequestedForInterval=[],this._currentIntervalIndex=n,void this._reloadFunction()}var l=d(this);if(r(l))for(var u=this._tilesRequestedForInterval,c=!0;c&&0!==u.length;){var p=u.pop();(c=h(this,p,l))||u.push(p)}},l}),define("Shaders/ViewportQuadFS",[],function(){"use strict";return"varying vec2 v_textureCoordinates;\nvoid main()\n{\nczm_materialInput materialInput;\nmaterialInput.s = v_textureCoordinates.s;\nmaterialInput.st = v_textureCoordinates;\nmaterialInput.str = vec3(v_textureCoordinates, 0.0);\nmaterialInput.normalEC = vec3(0.0, 0.0, -1.0);\nczm_material material = czm_getMaterial(materialInput);\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n}\n"}),define("Scene/ViewportQuad",["../Core/BoundingRectangle","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderSource","../Shaders/ViewportQuadFS","./BlendingState","./Material"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(i,n){this.show=!0,r(i)||(i=new e),this.rectangle=e.clone(i),r(n)||(n=c.fromType(c.ColorType,{color:new t(1,1,1,1)})),this.material=n,this._material=void 0,this._overlayCommand=void 0,this._rs=void 0}return d.prototype.update=function(t){if(this.show){var i=this._rs;r(i)&&e.equals(i.viewport,this.rectangle)||(this._rs=a.fromCache({blending:u.ALPHA_BLEND,viewport:this.rectangle}));if(t.passes.render){var n=t.context;if(this._material!==this.material||!r(this._overlayCommand)){this._material=this.material,r(this._overlayCommand)&&this._overlayCommand.shaderProgram.destroy();var c=new s({sources:[this._material.shaderSource,l]});this._overlayCommand=n.createViewportQuadCommand(c,{renderState:this._rs,uniformMap:this._material._uniforms,owner:this}),this._overlayCommand.pass=o.OVERLAY}this._material.update(n),this._overlayCommand.uniformMap=this._material._uniforms,t.commandList.push(this._overlayCommand)}}},d.prototype.isDestroyed=function(){return!1},d.prototype.destroy=function(){return r(this._overlayCommand)&&(this._overlayCommand.shaderProgram=this._overlayCommand.shaderProgram&&this._overlayCommand.shaderProgram.destroy()),i(this)},d}),define("Scene/WebMapServiceImageryProvider",["../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/freezeObject","../Core/GeographicTilingScheme","../Core/objectToQuery","../Core/queryToObject","../Core/WebMercatorTilingScheme","../ThirdParty/Uri","./GetFeatureInfoFormat","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(i){function n(e,t){r(m[e])||(m[e]=t),r(v)&&!r(v[e])&&(v[e]=t)}i=t(i,t.EMPTY_OBJECT),this._url=i.url,this._layers=i.layers;var o=t(i.getFeatureInfoFormats,p.DefaultGetFeatureInfoFormats),d=new c(i.url),m=l(t(d.query,"")),g=e(f(t(i.parameters,t.EMPTY_OBJECT)),p.DefaultParameters);m=e(g,m);var _,v;_=new c(i.url),v=l(t(_.query,""));var y=e(f(t(i.getFeatureInfoParameters,t.EMPTY_OBJECT)),p.GetFeatureInfoDefaultParameters);v=e(y,v),n("layers",i.layers),parseFloat(g.version)>=1.3?n("crs",i.tilingScheme instanceof u?"EPSG:3857":"CRS:84"):n("srs",i.tilingScheme instanceof u?"EPSG:3857":"EPSG:4326"),n("bbox","{westProjected},{southProjected},{eastProjected},{northProjected}"),n("width","{width}"),n("height","{height}"),d.query=s(m);var C,b=d.toString().replace(/%7B/g,"{").replace(/%7D/g,"}");r(v)&&(r(v.query_layers)||(v.query_layers=i.layers),r(v.x)||(v.x="{i}"),r(v.y)||(v.y="{j}"),r(v.info_format)||(v.info_format="{format}"),_.query=s(v),C=_.toString().replace(/%7B/g,"{").replace(/%7D/g,"}")),this._tileProvider=new h({url:b,pickFeaturesUrl:C,tilingScheme:t(i.tilingScheme,new a({ellipsoid:i.ellipsoid})),rectangle:i.rectangle,tileWidth:i.tileWidth,tileHeight:i.tileHeight,minimumLevel:i.minimumLevel,maximumLevel:i.maximumLevel,proxy:i.proxy,subdomains:i.subdomains,tileDiscardPolicy:i.tileDiscardPolicy,credit:i.credit,getFeatureInfoFormats:o,enablePickFeatures:i.enablePickFeatures})}function f(e){var t={};for(var r in e)e.hasOwnProperty(r)&&(t[r.toLowerCase()]=e[r]);return t}return i(p.prototype,{url:{get:function(){return this._url}},proxy:{get:function(){return this._tileProvider.proxy}},layers:{get:function(){return this._layers}},tileWidth:{get:function(){return this._tileProvider.tileWidth}},tileHeight:{get:function(){return this._tileProvider.tileHeight}},maximumLevel:{get:function(){return this._tileProvider.maximumLevel}},minimumLevel:{get:function(){return this._tileProvider.minimumLevel}},tilingScheme:{get:function(){return this._tileProvider.tilingScheme}},rectangle:{get:function(){return this._tileProvider.rectangle}},tileDiscardPolicy:{get:function(){return this._tileProvider.tileDiscardPolicy}},errorEvent:{get:function(){return this._tileProvider.errorEvent}},ready:{get:function(){return this._tileProvider.ready}},readyPromise:{get:function(){return this._tileProvider.readyPromise}},credit:{get:function(){return this._tileProvider.credit}},hasAlphaChannel:{get:function(){return this._tileProvider.hasAlphaChannel}},enablePickFeatures:{get:function(){return this._tileProvider.enablePickFeatures},set:function(e){this._tileProvider.enablePickFeatures=e}}}),p.prototype.getTileCredits=function(e,t,r){return this._tileProvider.getTileCredits(e,t,r)},p.prototype.requestImage=function(e,t,r,i){return this._tileProvider.requestImage(e,t,r,i)},p.prototype.pickFeatures=function(e,t,r,i,n){return this._tileProvider.pickFeatures(e,t,r,i,n)},p.DefaultParameters=o({service:"WMS",version:"1.1.1",request:"GetMap",styles:"",format:"image/jpeg"}),p.GetFeatureInfoDefaultParameters=o({service:"WMS",version:"1.1.1",request:"GetFeatureInfo"}),p.DefaultGetFeatureInfoFormats=o([o(new d("json","application/json")),o(new d("xml","text/xml")),o(new d("text","text/html"))]),p}),define("Scene/WebMapTileServiceImageryProvider",["../Core/combine","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/freezeObject","../Core/isArray","../Core/objectToQuery","../Core/queryToObject","../Core/Rectangle","../Core/WebMercatorTilingScheme","../ThirdParty/Uri","../ThirdParty/when","./ImageryProvider","./TimeDynamicImagery"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){e=r(e,r.EMPTY_OBJECT),this._url=e.url,this._layer=e.layer,this._style=e.style,this._tileMatrixSetID=e.tileMatrixSetID,this._tileMatrixLabels=e.tileMatrixLabels,this._format=r(e.format,"image/jpeg"),this._proxy=e.proxy,this._tileDiscardPolicy=e.tileDiscardPolicy,this._tilingScheme=i(e.tilingScheme)?e.tilingScheme:new h({ellipsoid:e.ellipsoid}),this._tileWidth=r(e.tileWidth,256),this._tileHeight=r(e.tileHeight,256), -this._minimumLevel=r(e.minimumLevel,0),this._maximumLevel=e.maximumLevel,this._rectangle=r(e.rectangle,this._tilingScheme.rectangle),this._dimensions=e.dimensions;var n=this;this._reload=void 0,i(e.times)&&(this._timeDynamicImagery=new g({clock:e.clock,times:e.times,requestImageFunction:function(e,t,r,i,o){return v(n,e,t,r,i,o)},reloadFunction:function(){i(n._reload)&&n._reload()}})),this._readyPromise=f.resolve(!0);var o=this._tilingScheme.positionToTileXY(d.southwest(this._rectangle),this._minimumLevel),s=this._tilingScheme.positionToTileXY(d.northeast(this._rectangle),this._minimumLevel);Math.abs(s.x-o.x),Math.abs(s.y-o.y);this._errorEvent=new a;var u=e.credit;this._credit="string"==typeof u?new t({text:u}):u,this._subdomains=e.subdomains,l(this._subdomains)?this._subdomains=this._subdomains.slice():i(this._subdomains)&&this._subdomains.length>0?this._subdomains=this._subdomains.split(""):this._subdomains=["a","b","c"]}function v(t,n,o,a,s,l){var d,h,f=t._tileMatrixLabels,g=i(f)?f[a]:a.toString(),_=t._subdomains,v=t._dimensions,C=i(l)?l.data:void 0;if(t._url.indexOf("{")>=0){if(d=t._url.replace("{style}",t._style).replace("{Style}",t._style).replace("{TileMatrixSet}",t._tileMatrixSetID).replace("{TileMatrix}",g).replace("{TileRow}",o.toString()).replace("{TileCol}",n.toString()).replace("{s}",_[(n+o+a)%_.length]),i(v))for(h in v)v.hasOwnProperty(h)&&(d=d.replace("{"+h+"}",v[h]));if(i(C))for(h in C)C.hasOwnProperty(h)&&(d=d.replace("{"+h+"}",C[h]))}else{var b=new p(t._url),S=c(r(b.query,""));if(S=e(y,S),S.tilematrix=g,S.layer=t._layer,S.style=t._style,S.tilerow=o,S.tilecol=n,S.tilematrixset=t._tileMatrixSetID,S.format=t._format,i(v))for(h in v)v.hasOwnProperty(h)&&(S[h]=v[h]);if(i(C))for(h in C)C.hasOwnProperty(h)&&(S[h]=C[h]);b.query=u(S),d=b.toString()}var w=t._proxy;return i(w)&&(d=w.getURL(d)),m.loadImage(t,d,s)}var y=s({service:"WMTS",version:"1.0.0",request:"GetTile"});return n(_.prototype,{url:{get:function(){return this._url}},proxy:{get:function(){return this._proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return this._minimumLevel}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},format:{get:function(){return this._format}},ready:{value:!0},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!0}},clock:{get:function(){return this._timeDynamicImagery.clock},set:function(e){this._timeDynamicImagery.clock=e}},times:{get:function(){return this._timeDynamicImagery.times},set:function(e){this._timeDynamicImagery.times=e}},dimensions:{get:function(){return this._dimensions},set:function(e){this._dimensions!==e&&(this._dimensions=e,i(this._reload)&&this._reload())}}}),_.prototype.getTileCredits=function(e,t,r){},_.prototype.requestImage=function(e,t,r,n){var o,a,s=this._timeDynamicImagery;return i(s)&&(a=s.currentInterval,o=s.getFromCache(e,t,r,n)),i(o)||(o=v(this,e,t,r,n,a)),i(o)&&i(s)&&s.checkApproachingInterval(e,t,r,n),o},_.prototype.pickFeatures=function(e,t,r,i,n){},_}),define("ThirdParty/crunch",[],function(){function globalEval(e){eval.call(null,e)}function assert(e,t){e||abort("Assertion failed: "+t)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(e){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}function setValue(e,t,r,i){switch(r=r||"i8","*"===r.charAt(r.length-1)&&(r="i32"),r){case"i1":case"i8":HEAP8[e>>0]=t;break;case"i16":HEAP16[e>>1]=t;break;case"i32":HEAP32[e>>2]=t;break;case"i64":tempI64=[t>>>0,(tempDouble=t,+Math_abs(tempDouble)>=1?tempDouble>0?(0|Math_min(+Math_floor(tempDouble/4294967296),4294967295))>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[e>>2]=tempI64[0],HEAP32[e+4>>2]=tempI64[1];break;case"float":HEAPF32[e>>2]=t;break;case"double":HEAPF64[e>>3]=t;break;default:abort("invalid type for setValue: "+r)}}function getValue(e,t,r){switch(t=t||"i8","*"===t.charAt(t.length-1)&&(t="i32"),t){case"i1":case"i8":return HEAP8[e>>0];case"i16":return HEAP16[e>>1];case"i32":case"i64":return HEAP32[e>>2];case"float":return HEAPF32[e>>2];case"double":return HEAPF64[e>>3];default:abort("invalid type for setValue: "+t)}return null}function allocate(e,t,r,i){var n,o;"number"==typeof e?(n=!0,o=e):(n=!1,o=e.length);var a,s="string"==typeof t?t:null;if(a=r==ALLOC_NONE?i:["function"==typeof _malloc?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][void 0===r?ALLOC_STATIC:r](Math.max(o,s?1:t.length)),n){var l,i=a;for(assert(0==(3&a)),l=a+(-4&o);i<l;i+=4)HEAP32[i>>2]=0;for(l=a+o;i<l;)HEAP8[i++>>0]=0;return a}if("i8"===s)return e.subarray||e.slice?HEAPU8.set(e,a):HEAPU8.set(new Uint8Array(e),a),a;for(var u,c,d,h=0;h<o;){var p=e[h];"function"==typeof p&&(p=Runtime.getFunctionIndex(p)),u=s||t[h],0!==u?("i64"==u&&(u="i32"),setValue(a+h,p,u),d!==u&&(c=Runtime.getNativeTypeSize(u),d=u),h+=c):h++}return a}function getMemory(e){return staticSealed?runtimeInitialized?_malloc(e):Runtime.dynamicAlloc(e):Runtime.staticAlloc(e)}function Pointer_stringify(e,t){if(0===t||!e)return"";for(var r,i=0,n=0;;){if(r=HEAPU8[e+n>>0],i|=r,0==r&&!t)break;if(n++,t&&n==t)break}t||(t=n);var o="";if(i<128){for(var a;t>0;)a=String.fromCharCode.apply(String,HEAPU8.subarray(e,e+Math.min(t,1024))),o=o?o+a:a,e+=1024,t-=1024;return o}return Module.UTF8ToString(e)}function AsciiToString(e){for(var t="";;){var r=HEAP8[e++>>0];if(!r)return t;t+=String.fromCharCode(r)}}function stringToAscii(e,t){return writeAsciiToMemory(e,t,!1)}function UTF8ArrayToString(e,t){for(var r=t;e[r];)++r;if(r-t>16&&e.subarray&&UTF8Decoder)return UTF8Decoder.decode(e.subarray(t,r));for(var i,n,o,a,s,l,u="";;){if(!(i=e[t++]))return u;if(128&i)if(n=63&e[t++],192!=(224&i))if(o=63&e[t++],224==(240&i)?i=(15&i)<<12|n<<6|o:(a=63&e[t++],240==(248&i)?i=(7&i)<<18|n<<12|o<<6|a:(s=63&e[t++],248==(252&i)?i=(3&i)<<24|n<<18|o<<12|a<<6|s:(l=63&e[t++],i=(1&i)<<30|n<<24|o<<18|a<<12|s<<6|l))),i<65536)u+=String.fromCharCode(i);else{var c=i-65536;u+=String.fromCharCode(55296|c>>10,56320|1023&c)}else u+=String.fromCharCode((31&i)<<6|n);else u+=String.fromCharCode(i)}}function UTF8ToString(e){return UTF8ArrayToString(HEAPU8,e)}function stringToUTF8Array(e,t,r,i){if(!(i>0))return 0;for(var n=r,o=r+i-1,a=0;a<e.length;++a){var s=e.charCodeAt(a);if(s>=55296&&s<=57343&&(s=65536+((1023&s)<<10)|1023&e.charCodeAt(++a)),s<=127){if(r>=o)break;t[r++]=s}else if(s<=2047){if(r+1>=o)break;t[r++]=192|s>>6,t[r++]=128|63&s}else if(s<=65535){if(r+2>=o)break;t[r++]=224|s>>12,t[r++]=128|s>>6&63,t[r++]=128|63&s}else if(s<=2097151){if(r+3>=o)break;t[r++]=240|s>>18,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}else if(s<=67108863){if(r+4>=o)break;t[r++]=248|s>>24,t[r++]=128|s>>18&63,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}else{if(r+5>=o)break;t[r++]=252|s>>30,t[r++]=128|s>>24&63,t[r++]=128|s>>18&63,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}}return t[r]=0,r-n}function stringToUTF8(e,t,r){return stringToUTF8Array(e,HEAPU8,t,r)}function lengthBytesUTF8(e){for(var t=0,r=0;r<e.length;++r){var i=e.charCodeAt(r);i>=55296&&i<=57343&&(i=65536+((1023&i)<<10)|1023&e.charCodeAt(++r)),i<=127?++t:t+=i<=2047?2:i<=65535?3:i<=2097151?4:i<=67108863?5:6}return t}function demangle(e){var t=Module.___cxa_demangle||Module.__cxa_demangle;if(t){try{var r=e.substr(1),i=lengthBytesUTF8(r)+1,n=_malloc(i);stringToUTF8(r,n,i);var o=_malloc(4),a=t(n,0,0,o);if(0===getValue(o,"i32")&&a)return Pointer_stringify(a)}catch(e){}finally{n&&_free(n),o&&_free(o),a&&_free(a)}return e}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),e}function demangleAll(e){var t=/__Z[\w\d_]+/g;return e.replace(t,function(e){var t=demangle(e);return e===t?e:e+" ["+t+"]"})}function jsStackTrace(){var e=new Error;if(!e.stack){try{throw new Error(0)}catch(t){e=t}if(!e.stack)return"(no stack trace available)"}return e.stack.toString()}function stackTrace(){var e=jsStackTrace();return Module.extraStackTrace&&(e+="\n"+Module.extraStackTrace()),demangleAll(e)}function alignUp(e,t){return e%t>0&&(e+=t-e%t),e}function updateGlobalBuffer(e){Module.buffer=buffer=e}function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){var e=Module.usingWasm?WASM_PAGE_SIZE:ASMJS_PAGE_SIZE,t=2147483648-e;if(HEAP32[DYNAMICTOP_PTR>>2]>t)return!1;var r=TOTAL_MEMORY;for(TOTAL_MEMORY=Math.max(TOTAL_MEMORY,MIN_TOTAL_MEMORY);TOTAL_MEMORY<HEAP32[DYNAMICTOP_PTR>>2];)TOTAL_MEMORY=TOTAL_MEMORY<=536870912?alignUp(2*TOTAL_MEMORY,e):Math.min(alignUp((3*TOTAL_MEMORY+2147483648)/4,e),t);var i=Module.reallocBuffer(TOTAL_MEMORY);return i&&i.byteLength==TOTAL_MEMORY?(updateGlobalBuffer(i),updateGlobalBufferViews(),!0):(TOTAL_MEMORY=r,!1)}function getTotalMemory(){return TOTAL_MEMORY}function callRuntimeCallbacks(e){for(;e.length>0;){var t=e.shift();if("function"!=typeof t){var r=t.func;"number"==typeof r?void 0===t.arg?Module.dynCall_v(r):Module.dynCall_vi(r,t.arg):r(void 0===t.arg?null:t.arg)}else t()}}function preRun(){if(Module.preRun)for("function"==typeof Module.preRun&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for("function"==typeof Module.postRun&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(e){__ATPRERUN__.unshift(e)}function addOnInit(e){__ATINIT__.unshift(e)}function addOnPreMain(e){__ATMAIN__.unshift(e)}function addOnExit(e){__ATEXIT__.unshift(e)}function addOnPostRun(e){__ATPOSTRUN__.unshift(e)}function intArrayFromString(e,t,r){var i=r>0?r:lengthBytesUTF8(e)+1,n=new Array(i),o=stringToUTF8Array(e,n,0,n.length);return t&&(n.length=o),n}function intArrayToString(e){for(var t=[],r=0;r<e.length;r++){var i=e[r];i>255&&(i&=255),t.push(String.fromCharCode(i))}return t.join("")}function writeStringToMemory(e,t,r){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var i,n;r&&(n=t+lengthBytesUTF8(e),i=HEAP8[n]),stringToUTF8(e,t,1/0),r&&(HEAP8[n]=i)}function writeArrayToMemory(e,t){HEAP8.set(e,t)}function writeAsciiToMemory(e,t,r){for(var i=0;i<e.length;++i)HEAP8[t++>>0]=e.charCodeAt(i);r||(HEAP8[t>>0]=0)}function addRunDependency(e){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}function removeRunDependency(e){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),0==runDependencies&&(null!==runDependencyWatcher&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var t=dependenciesFulfilled;dependenciesFulfilled=null,t()}}function _abort(){Module.abort()}function __ZSt18uncaught_exceptionv(){return!!__ZSt18uncaught_exceptionv.uncaught_exception}function ___cxa_begin_catch(e){var t=EXCEPTIONS.infos[e];return t&&!t.caught&&(t.caught=!0,__ZSt18uncaught_exceptionv.uncaught_exception--),t&&(t.rethrown=!1),EXCEPTIONS.caught.push(e),EXCEPTIONS.addRef(EXCEPTIONS.deAdjust(e)),e}function _pthread_once(e,t){_pthread_once.seen||(_pthread_once.seen={}),e in _pthread_once.seen||(Module.dynCall_v(t),_pthread_once.seen[e]=1)}function _emscripten_memcpy_big(e,t,r){return HEAPU8.set(HEAPU8.subarray(t,t+r),e),e}function ___syscall6(e,t){SYSCALLS.varargs=t;try{var r=SYSCALLS.getStreamFromFD();return FS.close(r),0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function _pthread_getspecific(e){return PTHREAD_SPECIFIC[e]||0}function ___setErrNo(e){return Module.___errno_location&&(HEAP32[Module.___errno_location()>>2]=e),e}function _pthread_key_create(e,t){return 0==e?ERRNO_CODES.EINVAL:(HEAP32[e>>2]=PTHREAD_SPECIFIC_NEXT_KEY,PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY]=0,PTHREAD_SPECIFIC_NEXT_KEY++,0)}function ___resumeException(e){throw EXCEPTIONS.last||(EXCEPTIONS.last=e),e+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."}function ___cxa_find_matching_catch(){var e=EXCEPTIONS.last;if(!e)return 0|(Runtime.setTempRet0(0),0);var t=EXCEPTIONS.infos[e],r=t.type;if(!r)return 0|(Runtime.setTempRet0(0),e);var i=Array.prototype.slice.call(arguments);Module.___cxa_is_pointer_type(r);___cxa_find_matching_catch.buffer||(___cxa_find_matching_catch.buffer=_malloc(4)),HEAP32[___cxa_find_matching_catch.buffer>>2]=e,e=___cxa_find_matching_catch.buffer;for(var n=0;n<i.length;n++)if(i[n]&&Module.___cxa_can_catch(i[n],r,e))return e=HEAP32[e>>2],t.adjusted=e,0|(Runtime.setTempRet0(i[n]),e);return e=HEAP32[e>>2],0|(Runtime.setTempRet0(r),e)}function ___gxx_personality_v0(){}function _pthread_setspecific(e,t){return e in PTHREAD_SPECIFIC?(PTHREAD_SPECIFIC[e]=t,0):ERRNO_CODES.EINVAL}function ___syscall140(e,t){SYSCALLS.varargs=t;try{var r=SYSCALLS.getStreamFromFD(),i=(SYSCALLS.get(),SYSCALLS.get()),n=SYSCALLS.get(),o=SYSCALLS.get(),a=i;return FS.llseek(r,a,o),HEAP32[n>>2]=r.position,r.getdents&&0===a&&0===o&&(r.getdents=null),0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function ___syscall146(e,t){SYSCALLS.varargs=t;try{var r=SYSCALLS.get(),i=SYSCALLS.get(),n=SYSCALLS.get(),o=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(e,t){var r=___syscall146.buffers[e];assert(r),0===t||10===t?((1===e?Module.print:Module.printErr)(UTF8ArrayToString(r,0)),r.length=0):r.push(t)});for(var a=0;a<n;a++){for(var s=HEAP32[i+8*a>>2],l=HEAP32[i+(8*a+4)>>2],u=0;u<l;u++)___syscall146.printChar(r,HEAPU8[s+u]);o+=l}return o}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function ___syscall54(e,t){SYSCALLS.varargs=t;try{return 0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function invoke_iiii(e,t,r,i){try{return Module.dynCall_iiii(e,t,r,i)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viiiii(e,t,r,i,n,o){try{Module.dynCall_viiiii(e,t,r,i,n,o)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_vi(e,t){try{Module.dynCall_vi(e,t)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_ii(e,t){try{return Module.dynCall_ii(e,t)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viii(e,t,r,i){try{Module.dynCall_viii(e,t,r,i)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_v(e){try{Module.dynCall_v(e)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viiiiii(e,t,r,i,n,o,a){try{Module.dynCall_viiiiii(e,t,r,i,n,o,a)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viiii(e,t,r,i,n){try{Module.dynCall_viiii(e,t,r,i,n)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function ExitStatus(e){this.name="ExitStatus",this.message="Program terminated with exit("+e+")",this.status=e}function run(e){function t(){Module.calledRun||(Module.calledRun=!0,ABORT||(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(e),postRun()))}e=e||Module.arguments,null===preloadStartTime&&(preloadStartTime=Date.now()),runDependencies>0||(preRun(),runDependencies>0||Module.calledRun||(Module.setStatus?(Module.setStatus("Running..."),setTimeout(function(){setTimeout(function(){Module.setStatus("")},1),t()},1)):t()))}function exit(e,t){t&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=e,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(e)),ENVIRONMENT_IS_NODE&&process.exit(e),Module.quit(e,new ExitStatus(e)))}function abort(e){Module.onAbort&&Module.onAbort(e),void 0!==e?(Module.print(e),Module.printErr(e),e=JSON.stringify(e)):e="",ABORT=!0,EXITSTATUS=1;var t="abort("+e+") at "+stackTrace()+"\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";throw abortDecorators&&abortDecorators.forEach(function(r){t=r(t,e)}),t}var Module;Module||(Module=(void 0!==Module?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1;if(Module.ENVIRONMENT)if("WEB"===Module.ENVIRONMENT)ENVIRONMENT_IS_WEB=!0;else if("WORKER"===Module.ENVIRONMENT)ENVIRONMENT_IS_WORKER=!0;else if("NODE"===Module.ENVIRONMENT)ENVIRONMENT_IS_NODE=!0;else{if("SHELL"!==Module.ENVIRONMENT)throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");ENVIRONMENT_IS_SHELL=!0}else ENVIRONMENT_IS_WEB="object"==typeof window,ENVIRONMENT_IS_WORKER="function"==typeof importScripts,ENVIRONMENT_IS_NODE="object"==typeof process&&"function"==typeof require&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn);var nodeFS,nodePath;Module.read=function(e,t){nodeFS||(nodeFS=require("fs")),nodePath||(nodePath=require("path")),e=nodePath.normalize(e);var r=nodeFS.readFileSync(e);return t?r:r.toString()},Module.readBinary=function(e){var t=Module.read(e,!0);return t.buffer||(t=new Uint8Array(t)),assert(t.buffer),t},Module.load=function(e){globalEval(read(e))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),"undefined"!=typeof module&&(module.exports=Module),process.on("uncaughtException",function(e){if(!(e instanceof ExitStatus))throw e}),Module.inspect=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),"undefined"!=typeof printErr&&(Module.printErr=printErr),"undefined"!=typeof read?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(e){if("function"==typeof readbuffer)return new Uint8Array(readbuffer(e));var t=read(e,"binary");return assert("object"==typeof t),t},"undefined"!=typeof scriptArgs?Module.arguments=scriptArgs:void 0!==arguments&&(Module.arguments=arguments),"function"==typeof quit&&(Module.quit=function(e,t){quit(e)});else{if(!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER)throw"Unknown runtime environment. Where are we?";if(Module.read=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.send(null),t.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null),new Uint8Array(t.response)}),Module.readAsync=function(e,t,r){var i=new XMLHttpRequest;i.open("GET",e,!0),i.responseType="arraybuffer",i.onload=function(){200==i.status||0==i.status&&i.response?t(i.response):r()},i.onerror=r,i.send(null)},void 0!==arguments&&(Module.arguments=arguments),"undefined"!=typeof console)Module.print||(Module.print=function(e){console.log(e)}),Module.printErr||(Module.printErr=function(e){console.warn(e)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&"undefined"!=typeof dump?function(e){dump(e)}:function(e){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),void 0===Module.setWindowTitle&&(Module.setWindowTitle=function(e){document.title=e})}!Module.load&&Module.read&&(Module.load=function(e){globalEval(Module.read(e))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(e,t){throw t}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[];for(var key in moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(e){return tempRet0=e,e},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(e){STACKTOP=e},getNativeTypeSize:function(e){switch(e){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:if("*"===e[e.length-1])return Runtime.QUANTUM_SIZE;if("i"===e[0]){var t=parseInt(e.substr(1));return assert(t%8==0),t/8}return 0}},getNativeFieldSize:function(e){return Math.max(Runtime.getNativeTypeSize(e),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(e,t){return"double"===t||"i64"===t?7&e&&(assert(4==(7&e)),e+=4):assert(0==(3&e)),e},getAlignSize:function(e,t,r){return r||"i64"!=e&&"double"!=e?e?Math.min(t||(e?Runtime.getNativeFieldSize(e):0),Runtime.QUANTUM_SIZE):Math.min(t,8):8},dynCall:function(e,t,r){return r&&r.length?Module["dynCall_"+e].apply(null,[t].concat(r)):Module["dynCall_"+e].call(null,t)},functionPointers:[],addFunction:function(e){for(var t=0;t<Runtime.functionPointers.length;t++)if(!Runtime.functionPointers[t])return Runtime.functionPointers[t]=e,2*(1+t);throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."},removeFunction:function(e){Runtime.functionPointers[(e-2)/2]=null},warnOnce:function(e){Runtime.warnOnce.shown||(Runtime.warnOnce.shown={}),Runtime.warnOnce.shown[e]||(Runtime.warnOnce.shown[e]=1,Module.printErr(e))},funcWrappers:{},getFuncWrapper:function(e,t){assert(t),Runtime.funcWrappers[t]||(Runtime.funcWrappers[t]={});var r=Runtime.funcWrappers[t];return r[e]||(1===t.length?r[e]=function(){return Runtime.dynCall(t,e)}:2===t.length?r[e]=function(r){return Runtime.dynCall(t,e,[r])}:r[e]=function(){return Runtime.dynCall(t,e,Array.prototype.slice.call(arguments))}),r[e]},getCompilerSetting:function(e){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"},stackAlloc:function(e){var t=STACKTOP;return STACKTOP=STACKTOP+e|0,STACKTOP=STACKTOP+15&-16,t},staticAlloc:function(e){var t=STATICTOP;return STATICTOP=STATICTOP+e|0,STATICTOP=STATICTOP+15&-16,t},dynamicAlloc:function(e){var t=HEAP32[DYNAMICTOP_PTR>>2],r=-16&(t+e+15|0);if(HEAP32[DYNAMICTOP_PTR>>2]=r,r>=TOTAL_MEMORY){if(!enlargeMemory())return HEAP32[DYNAMICTOP_PTR>>2]=t,0}return t},alignMemory:function(e,t){return e=Math.ceil(e/(t||16))*(t||16)},makeBigInt:function(e,t,r){return r?+(e>>>0)+4294967296*+(t>>>0):+(e>>>0)+4294967296*+(0|t)},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0,cwrap,ccall;!function(){function parseJSFunc(e){var t=e.toString().match(sourceRegex).slice(1);return{arguments:t[0],body:t[1],returnValue:t[2]}}function ensureJSsource(){if(!JSsource){JSsource={};for(var e in JSfuncs)JSfuncs.hasOwnProperty(e)&&(JSsource[e]=parseJSFunc(JSfuncs[e]))}}var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(e){var t=Runtime.stackAlloc(e.length);return writeArrayToMemory(e,t),t},stringToC:function(e){var t=0;if(null!==e&&void 0!==e&&0!==e){var r=1+(e.length<<2);t=Runtime.stackAlloc(r),stringToUTF8(e,t,r)}return t}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(e,t,r,i,n){var o=getCFunc(e),a=[],s=0;if(i)for(var l=0;l<i.length;l++){var u=toC[r[l]];u?(0===s&&(s=Runtime.stackSave()),a[l]=u(i[l])):a[l]=i[l]}var c=o.apply(null,a);if("string"===t&&(c=Pointer_stringify(c)),0!==s){if(n&&n.async)return void EmterpreterAsync.asyncFinalizers.push(function(){Runtime.stackRestore(s)});Runtime.stackRestore(s)}return c};var sourceRegex=/^function\s*[a-zA-Z$_0-9]*\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/,JSsource=null;cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident),numericArgs=argTypes.every(function(e){return"number"===e}),numericRet="string"!==returnType;if(numericRet&&numericArgs)return cfunc;var argNames=argTypes.map(function(e,t){return"$"+t}),funcstr="(function("+argNames.join(",")+") {",nargs=argTypes.length;if(!numericArgs){ensureJSsource(),funcstr+="var stack = "+JSsource.stackSave.body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if("number"!==type){var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";",funcstr+=convertCode.body+";",funcstr+=arg+"=("+convertCode.returnValue+");"}}}var cfuncname=parseJSFunc(function(){return cfunc}).returnValue;if(funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");",!numericRet){var strgfy=parseJSFunc(function(){return Pointer_stringify}).returnValue;funcstr+="ret = "+strgfy+"(ret);"}return numericArgs||(ensureJSsource(),funcstr+=JSsource.stackRestore.body.replace("()","(stack)")+";"),funcstr+="return ret})",eval(funcstr)}}(),Module.ccall=ccall,Module.cwrap=cwrap,Module.setValue=setValue,Module.getValue=getValue;var ALLOC_NORMAL=0,ALLOC_STACK=1,ALLOC_STATIC=2,ALLOC_DYNAMIC=3,ALLOC_NONE=4;Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE,Module.allocate=allocate,Module.getMemory=getMemory,Module.Pointer_stringify=Pointer_stringify,Module.AsciiToString=AsciiToString,Module.stringToAscii=stringToAscii;var UTF8Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;Module.UTF8ArrayToString=UTF8ArrayToString,Module.UTF8ToString=UTF8ToString,Module.stringToUTF8Array=stringToUTF8Array,Module.stringToUTF8=stringToUTF8,Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0;Module.stackTrace=stackTrace;var WASM_PAGE_SIZE=65536,ASMJS_PAGE_SIZE=16777216,MIN_TOTAL_MEMORY=16777216,HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64,STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1,Module.reallocBuffer||(Module.reallocBuffer=function(e){var t;try{if(ArrayBuffer.transfer)t=ArrayBuffer.transfer(buffer,e);else{var r=HEAP8;t=new ArrayBuffer(e);new Int8Array(t).set(r)}}catch(e){return!1}return!!_emscripten_replace_memory(t)&&t});var byteLength;try{byteLength=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,"byteLength").get),byteLength(new ArrayBuffer(4))}catch(e){byteLength=function(e){return e.byteLength}}var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||16777216;if(TOTAL_MEMORY<TOTAL_STACK&&Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was "+TOTAL_MEMORY+"! (TOTAL_STACK="+TOTAL_STACK+")"),buffer=Module.buffer?Module.buffer:new ArrayBuffer(TOTAL_MEMORY),updateGlobalBufferViews(),HEAP32[0]=1668509029,HEAP16[1]=25459,115!==HEAPU8[2]||99!==HEAPU8[3])throw"Runtime error: expected the system to be little-endian!";Module.HEAP=HEAP,Module.buffer=buffer,Module.HEAP8=HEAP8,Module.HEAP16=HEAP16,Module.HEAP32=HEAP32,Module.HEAPU8=HEAPU8,Module.HEAPU16=HEAPU16,Module.HEAPU32=HEAPU32,Module.HEAPF32=HEAPF32,Module.HEAPF64=HEAPF64;var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;Module.addOnPreRun=addOnPreRun,Module.addOnInit=addOnInit,Module.addOnPreMain=addOnPreMain,Module.addOnExit=addOnExit,Module.addOnPostRun=addOnPostRun,Module.intArrayFromString=intArrayFromString,Module.intArrayToString=intArrayToString,Module.writeStringToMemory=writeStringToMemory,Module.writeArrayToMemory=writeArrayToMemory,Module.writeAsciiToMemory=writeAsciiToMemory,Math.imul&&-5===Math.imul(4294967295,5)||(Math.imul=function(e,t){var r=e>>>16,i=65535&e,n=t>>>16,o=65535&t;return i*o+(r*o+i*n<<16)|0}),Math.imul=Math.imul,Math.clz32||(Math.clz32=function(e){e>>>=0;for(var t=0;t<32;t++)if(e&1<<31-t)return t;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(e){return e<0?Math.ceil(e):Math.floor(e)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;Module.addRunDependency=addRunDependency,Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[];STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+6192,__ATINIT__.push(), -allocate([228,2,0,0,81,16,0,0,12,3,0,0,177,16,0,0,32,0,0,0,0,0,0,0,12,3,0,0,94,16,0,0,48,0,0,0,0,0,0,0,228,2,0,0,127,16,0,0,12,3,0,0,140,16,0,0,16,0,0,0,0,0,0,0,12,3,0,0,183,17,0,0,32,0,0,0,0,0,0,0,12,3,0,0,147,17,0,0,72,0,0,0,0,0,0,0,108,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,32,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,1,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,40,20,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,56,0,0,0,1,0,0,0,5,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,37,115,40,37,117,41,58,32,65,115,115,101,114,116,105,111,110,32,102,97,105,108,117,114,101,58,32,34,37,115,34,10,0,109,95,115,105,122,101,32,60,61,32,109,95,99,97,112,97,99,105,116,121,0,46,47,105,110,99,92,99,114,110,95,100,101,99,111,109,112,46,104,0,109,105,110,95,110,101,119,95,99,97,112,97,99,105,116,121,32,60,32,40,48,120,55,70,70,70,48,48,48,48,85,32,47,32,101,108,101,109,101,110,116,95,115,105,122,101,41,0,110,101,119,95,99,97,112,97,99,105,116,121,32,38,38,32,40,110,101,119,95,99,97,112,97,99,105,116,121,32,62,32,109,95,99,97,112,97,99,105,116,121,41,0,110,117,109,95,99,111,100,101,115,91,99,93,0,115,111,114,116,101,100,95,112,111,115,32,60,32,116,111,116,97,108,95,117,115,101,100,95,115,121,109,115,0,112,67,111,100,101,115,105,122,101,115,91,115,121,109,95,105,110,100,101,120,93,32,61,61,32,99,111,100,101,115,105,122,101,0,116,32,60,32,40,49,85,32,60,60,32,116,97,98,108,101,95,98,105,116,115,41,0,109,95,108,111,111,107,117,112,91,116,93,32,61,61,32,99,85,73,78,84,51,50,95,77,65,88,0,99,114,110,100,95,109,97,108,108,111,99,58,32,115,105,122,101,32,116,111,111,32,98,105,103,0,99,114,110,100,95,109,97,108,108,111,99,58,32,111,117,116,32,111,102,32,109,101,109,111,114,121,0,40,40,117,105,110,116,51,50,41,112,95,110,101,119,32,38,32,40,67,82,78,68,95,77,73,78,95,65,76,76,79,67,95,65,76,73,71,78,77,69,78,84,32,45,32,49,41,41,32,61,61,32,48,0,99,114,110,100,95,114,101,97,108,108,111,99,58,32,98,97,100,32,112,116,114,0,99,114,110,100,95,102,114,101,101,58,32,98,97,100,32,112,116,114,0,102,97,108,115,101,0,40,116,111,116,97,108,95,115,121,109,115,32,62,61,32,49,41,32,38,38,32,40,116,111,116,97,108,95,115,121,109,115,32,60,61,32,112,114,101,102,105,120,95,99,111,100,105,110,103,58,58,99,77,97,120,83,117,112,112,111,114,116,101,100,83,121,109,115,41,0,17,18,19,20,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,16,48,0,110,117,109,95,98,105,116,115,32,60,61,32,51,50,85,0,109,95,98,105,116,95,99,111,117,110,116,32,60,61,32,99,66,105,116,66,117,102,83,105,122,101,0,116,32,33,61,32,99,85,73,78,84,51,50,95,77,65,88,0,109,111,100,101,108,46,109,95,99,111,100,101,95,115,105,122,101,115,91,115,121,109,93,32,61,61,32,108,101,110,0,0,2,3,1,0,2,3,4,5,6,7,1,40,108,101,110,32,62,61,32,49,41,32,38,38,32,40,108,101,110,32,60,61,32,99,77,97,120,69,120,112,101,99,116,101,100,67,111,100,101,83,105,122,101,41,0,105,32,60,32,109,95,115,105,122,101,0,110,101,120,116,95,108,101,118,101,108,95,111,102,115,32,62,32,99,117,114,95,108,101,118,101,108,95,111,102,115,0,1,2,2,3,3,3,3,4,0,0,0,0,0,0,1,1,0,1,0,1,0,0,1,2,1,2,0,0,0,1,0,2,1,0,2,0,0,1,2,3,110,117,109,32,38,38,32,40,110,117,109,32,61,61,32,126,110,117,109,95,99,104,101,99,107,41,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,101,120,99,101,112,116,105,111,110,32,111,102,32,116,121,112,101,32,37,115,58,32,37,115,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,101,120,99,101,112,116,105,111,110,32,111,102,32,116,121,112,101,32,37,115,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,102,111,114,101,105,103,110,32,101,120,99,101,112,116,105,111,110,0,116,101,114,109,105,110,97,116,105,110,103,0,117,110,99,97,117,103,104,116,0,83,116,57,101,120,99,101,112,116,105,111,110,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,54,95,95,115,104,105,109,95,116,121,112,101,95,105,110,102,111,69,0,83,116,57,116,121,112,101,95,105,110,102,111,0,78,49,48,95,95,99,120,120,97,98,105,118,49,50,48,95,95,115,105,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,112,116,104,114,101,97,100,95,111,110,99,101,32,102,97,105,108,117,114,101,32,105,110,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,95,102,97,115,116,40,41,0,99,97,110,110,111,116,32,99,114,101,97,116,101,32,112,116,104,114,101,97,100,32,107,101,121,32,102,111,114,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,40,41,0,99,97,110,110,111,116,32,122,101,114,111,32,111,117,116,32,116,104,114,101,97,100,32,118,97,108,117,101,32,102,111,114,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,40,41,0,116,101,114,109,105,110,97,116,101,95,104,97,110,100,108,101,114,32,117,110,101,120,112,101,99,116,101,100,108,121,32,114,101,116,117,114,110,101,100,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,57,95,95,112,111,105,110,116,101,114,95,116,121,112,101,95,105,110,102,111,69,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,112,98,97,115,101,95,116,121,112,101,95,105,110,102,111,69,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:function(e){if(!e||EXCEPTIONS.infos[e])return e;for(var t in EXCEPTIONS.infos){if(EXCEPTIONS.infos[t].adjusted===e)return t}return e},addRef:function(e){if(e){EXCEPTIONS.infos[e].refcount++}},decRef:function(e){if(e){var t=EXCEPTIONS.infos[e];assert(t.refcount>0),t.refcount--,0!==t.refcount||t.rethrown||(t.destructor&&Module.dynCall_vi(t.destructor,e),delete EXCEPTIONS.infos[e],___cxa_free_exception(e))}},clearRef:function(e){if(e){EXCEPTIONS.infos[e].refcount=0}}},SYSCALLS={varargs:0,get:function(e){return SYSCALLS.varargs+=4,HEAP32[SYSCALLS.varargs-4>>2]},getStr:function(){return Pointer_stringify(SYSCALLS.get())},get64:function(){var e=SYSCALLS.get(),t=SYSCALLS.get();return assert(e>=0?0===t:-1===t),e},getZero:function(){assert(0===SYSCALLS.get())}},cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_STATIC),PTHREAD_SPECIFIC={},PTHREAD_SPECIFIC_NEXT_KEY=1,ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};__ATEXIT__.push(function(){var e=Module._fflush;e&&e(0);var t=___syscall146.printChar;if(t){var r=___syscall146.buffers;r[1].length&&t(1,10),r[2].length&&t(2,10)}}),DYNAMICTOP_PTR=allocate(1,"i32",ALLOC_STATIC),STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP),STACK_MAX=STACK_BASE+TOTAL_STACK,DYNAMIC_BASE=Runtime.alignMemory(STACK_MAX),HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE,staticSealed=!0,Module.asmGlobalArg={Math:Math,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:1/0,byteLength:byteLength},Module.asmLibraryArg={abort:abort,assert:assert,enlargeMemory:enlargeMemory,getTotalMemory:getTotalMemory,abortOnCannotGrowMemory:abortOnCannotGrowMemory,invoke_iiii:invoke_iiii,invoke_viiiii:invoke_viiiii,invoke_vi:invoke_vi,invoke_ii:invoke_ii,invoke_viii:invoke_viii,invoke_v:invoke_v,invoke_viiiiii:invoke_viiiiii,invoke_viiii:invoke_viiii,_pthread_getspecific:_pthread_getspecific,___syscall54:___syscall54,_pthread_setspecific:_pthread_setspecific,___gxx_personality_v0:___gxx_personality_v0,___syscall6:___syscall6,___setErrNo:___setErrNo,_abort:_abort,___cxa_begin_catch:___cxa_begin_catch,_pthread_once:_pthread_once,_emscripten_memcpy_big:_emscripten_memcpy_big,_pthread_key_create:_pthread_key_create,___syscall140:___syscall140,___resumeException:___resumeException,___cxa_find_matching_catch:___cxa_find_matching_catch,___syscall146:___syscall146,__ZSt18uncaught_exceptionv:__ZSt18uncaught_exceptionv,DYNAMICTOP_PTR:DYNAMICTOP_PTR,tempDoublePtr:tempDoublePtr,ABORT:ABORT,STACKTOP:STACKTOP,STACK_MAX:STACK_MAX,cttz_i8:cttz_i8};var asm=function(e,t,r){"almost asm";function i(e){return!(16777215&rr(e)||rr(e)<=16777215||rr(e)>2147483648)&&(zt=new Vt(e),Ht=new Gt(e),jt=new Wt(e),Yt=new qt(e),Qt=new Xt(e),Kt=new Zt(e),$t=new Jt(e),tr=new er(e),r=e,!0)}function n(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,b=0;b=or,or=or+16|0,h=b;do{if(e>>>0<245){if(u=e>>>0<11?16:e+11&-8,e=u>>>3,d=0|jt[1144],3&(r=d>>>e)|0)return t=(1&r^1)+e|0,e=4616+(t<<1<<2)|0,r=e+8|0,i=0|jt[r>>2],n=i+8|0,o=0|jt[n>>2],(0|e)==(0|o)?jt[1144]=d&~(1<<t):(jt[o+12>>2]=e,jt[r>>2]=o),C=t<<3,jt[i+4>>2]=3|C,C=i+C+4|0,jt[C>>2]=1|jt[C>>2],C=n,or=b,0|C;if(c=0|jt[1146],u>>>0>c>>>0){if(0|r)return t=2<<e,t=r<<e&(t|0-t),t=(t&0-t)-1|0,a=t>>>12&16,t>>>=a,r=t>>>5&8,t>>>=r,n=t>>>2&4,t>>>=n,e=t>>>1&2,t>>>=e,i=t>>>1&1,i=(r|a|n|e|i)+(t>>>i)|0,t=4616+(i<<1<<2)|0,e=t+8|0,n=0|jt[e>>2],a=n+8|0,r=0|jt[a>>2],(0|t)==(0|r)?(e=d&~(1<<i),jt[1144]=e):(jt[r+12>>2]=t,jt[e>>2]=r,e=d),o=(i<<3)-u|0,jt[n+4>>2]=3|u,i=n+u|0,jt[i+4>>2]=1|o,jt[i+o>>2]=o,0|c&&(n=0|jt[1149],t=c>>>3,r=4616+(t<<1<<2)|0,t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=n,jt[t+12>>2]=n,jt[n+8>>2]=t,jt[n+12>>2]=r),jt[1146]=o,jt[1149]=i,C=a,or=b,0|C;if(s=0|jt[1145]){if(r=(s&0-s)-1|0,a=r>>>12&16,r>>>=a,o=r>>>5&8,r>>>=o,l=r>>>2&4,r>>>=l,i=r>>>1&2,r>>>=i,e=r>>>1&1,e=0|jt[4880+((o|a|l|i|e)+(r>>>e)<<2)>>2],r=(-8&jt[e+4>>2])-u|0,i=0|jt[e+16+((0==(0|jt[e+16>>2])&1)<<2)>>2]){do{a=(-8&jt[i+4>>2])-u|0,l=a>>>0<r>>>0,r=l?a:r,e=l?i:e,i=0|jt[i+16+((0==(0|jt[i+16>>2])&1)<<2)>>2]}while(0!=(0|i));l=e,o=r}else l=e,o=r;if(a=l+u|0,l>>>0<a>>>0){n=0|jt[l+24>>2],t=0|jt[l+12>>2];do{if((0|t)==(0|l)){if(e=l+20|0,!((t=0|jt[e>>2])||(e=l+16|0,t=0|jt[e>>2]))){r=0;break}for(;;)if(r=t+20|0,0|(i=0|jt[r>>2]))t=i,e=r;else{if(r=t+16|0,!(i=0|jt[r>>2]))break;t=i,e=r}jt[e>>2]=0,r=t}else r=0|jt[l+8>>2],jt[r+12>>2]=t,jt[t+8>>2]=r,r=t}while(0);do{if(0|n){if(t=0|jt[l+28>>2],e=4880+(t<<2)|0,(0|l)==(0|jt[e>>2])){if(jt[e>>2]=r,!r){jt[1145]=s&~(1<<t);break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|l)&1)<<2)>>2]=r,!r)break;jt[r+24>>2]=n,t=0|jt[l+16>>2],0|t&&(jt[r+16>>2]=t,jt[t+24>>2]=r),t=0|jt[l+20>>2],0|t&&(jt[r+20>>2]=t,jt[t+24>>2]=r)}}while(0);return o>>>0<16?(C=o+u|0,jt[l+4>>2]=3|C,C=l+C+4|0,jt[C>>2]=1|jt[C>>2]):(jt[l+4>>2]=3|u,jt[a+4>>2]=1|o,jt[a+o>>2]=o,0|c&&(i=0|jt[1149],t=c>>>3,r=4616+(t<<1<<2)|0,t=1<<t,d&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=d|t,t=r,e=r+8|0),jt[e>>2]=i,jt[t+12>>2]=i,jt[i+8>>2]=t,jt[i+12>>2]=r),jt[1146]=o,jt[1149]=a),C=l+8|0,or=b,0|C}d=u}else d=u}else d=u}else if(e>>>0<=4294967231)if(e=e+11|0,u=-8&e,l=0|jt[1145]){i=0-u|0,e>>>=8,e?u>>>0>16777215?s=31:(d=(e+1048320|0)>>>16&8,y=e<<d,c=(y+520192|0)>>>16&4,y<<=c,s=(y+245760|0)>>>16&2,s=14-(c|d|s)+(y<<s>>>15)|0,s=u>>>(s+7|0)&1|s<<1):s=0,r=0|jt[4880+(s<<2)>>2];e:do{if(r)for(e=0,a=u<<(31==(0|s)?0:25-(s>>>1)|0),o=0;;){if((n=(-8&jt[r+4>>2])-u|0)>>>0<i>>>0){if(!n){e=r,i=0,n=r,y=61;break e}e=r,i=n}if(n=0|jt[r+20>>2],r=0|jt[r+16+(a>>>31<<2)>>2],o=0==(0|n)|(0|n)==(0|r)?o:n,n=0==(0|r)){r=o,y=57;break}a<<=1&(1^n)}else r=0,e=0,y=57}while(0);if(57==(0|y)){if(0==(0|r)&0==(0|e)){if(e=2<<s,!(e=l&(e|0-e))){d=u;break}d=(e&0-e)-1|0,a=d>>>12&16,d>>>=a,o=d>>>5&8,d>>>=o,s=d>>>2&4,d>>>=s,c=d>>>1&2,d>>>=c,r=d>>>1&1,e=0,r=0|jt[4880+((o|a|s|c|r)+(d>>>r)<<2)>>2]}r?(n=r,y=61):(s=e,a=i)}if(61==(0|y))for(;;){if(y=0,r=(-8&jt[n+4>>2])-u|0,d=r>>>0<i>>>0,r=d?r:i,e=d?n:e,!(n=0|jt[n+16+((0==(0|jt[n+16>>2])&1)<<2)>>2])){s=e,a=r;break}i=r,y=61}if(0!=(0|s)?a>>>0<((0|jt[1146])-u|0)>>>0:0){if(o=s+u|0,s>>>0>=o>>>0)return C=0,or=b,0|C;n=0|jt[s+24>>2],t=0|jt[s+12>>2];do{if((0|t)==(0|s)){if(e=s+20|0,!((t=0|jt[e>>2])||(e=s+16|0,t=0|jt[e>>2]))){t=0;break}for(;;)if(r=t+20|0,0|(i=0|jt[r>>2]))t=i,e=r;else{if(r=t+16|0,!(i=0|jt[r>>2]))break;t=i,e=r}jt[e>>2]=0}else C=0|jt[s+8>>2],jt[C+12>>2]=t,jt[t+8>>2]=C}while(0);do{if(n){if(e=0|jt[s+28>>2],r=4880+(e<<2)|0,(0|s)==(0|jt[r>>2])){if(jt[r>>2]=t,!t){i=l&~(1<<e),jt[1145]=i;break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|s)&1)<<2)>>2]=t,!t){i=l;break}jt[t+24>>2]=n,e=0|jt[s+16>>2],0|e&&(jt[t+16>>2]=e,jt[e+24>>2]=t),e=0|jt[s+20>>2],e?(jt[t+20>>2]=e,jt[e+24>>2]=t,i=l):i=l}else i=l}while(0);do{if(a>>>0>=16){if(jt[s+4>>2]=3|u,jt[o+4>>2]=1|a,jt[o+a>>2]=a,t=a>>>3,a>>>0<256){r=4616+(t<<1<<2)|0,e=0|jt[1144],t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=o,jt[t+12>>2]=o,jt[o+8>>2]=t,jt[o+12>>2]=r;break}if(t=a>>>8,t?a>>>0>16777215?t=31:(y=(t+1048320|0)>>>16&8,C=t<<y,v=(C+520192|0)>>>16&4,C<<=v,t=(C+245760|0)>>>16&2,t=14-(v|y|t)+(C<<t>>>15)|0,t=a>>>(t+7|0)&1|t<<1):t=0,r=4880+(t<<2)|0,jt[o+28>>2]=t,e=o+16|0,jt[e+4>>2]=0,jt[e>>2]=0,e=1<<t,!(i&e)){jt[1145]=i|e,jt[r>>2]=o,jt[o+24>>2]=r,jt[o+12>>2]=o,jt[o+8>>2]=o;break}for(e=a<<(31==(0|t)?0:25-(t>>>1)|0),r=0|jt[r>>2];;){if((-8&jt[r+4>>2]|0)==(0|a)){y=97;break}if(i=r+16+(e>>>31<<2)|0,!(t=0|jt[i>>2])){y=96;break}e<<=1,r=t}if(96==(0|y)){jt[i>>2]=o,jt[o+24>>2]=r,jt[o+12>>2]=o,jt[o+8>>2]=o;break}if(97==(0|y)){y=r+8|0,C=0|jt[y>>2],jt[C+12>>2]=o,jt[y>>2]=o,jt[o+8>>2]=C,jt[o+12>>2]=r,jt[o+24>>2]=0;break}}else C=a+u|0,jt[s+4>>2]=3|C,C=s+C+4|0,jt[C>>2]=1|jt[C>>2]}while(0);return C=s+8|0,or=b,0|C}d=u}else d=u;else d=-1}while(0);if((r=0|jt[1146])>>>0>=d>>>0)return t=r-d|0,e=0|jt[1149],t>>>0>15?(C=e+d|0,jt[1149]=C,jt[1146]=t,jt[C+4>>2]=1|t,jt[C+t>>2]=t,jt[e+4>>2]=3|d):(jt[1146]=0,jt[1149]=0,jt[e+4>>2]=3|r,C=e+r+4|0,jt[C>>2]=1|jt[C>>2]),C=e+8|0,or=b,0|C;if((a=0|jt[1147])>>>0>d>>>0)return v=a-d|0,jt[1147]=v,C=0|jt[1150],y=C+d|0,jt[1150]=y,jt[y+4>>2]=1|v,jt[C+4>>2]=3|d,C=C+8|0,or=b,0|C;if(0|jt[1262]?e=0|jt[1264]:(jt[1264]=4096,jt[1263]=4096,jt[1265]=-1,jt[1266]=-1,jt[1267]=0,jt[1255]=0,e=-16&h^1431655768,jt[h>>2]=e,jt[1262]=e,e=4096),s=d+48|0,l=d+47|0,o=e+l|0,n=0-e|0,(u=o&n)>>>0<=d>>>0)return C=0,or=b,0|C;if(e=0|jt[1254],0|e?(c=0|jt[1252],(h=c+u|0)>>>0<=c>>>0|h>>>0>e>>>0):0)return C=0,or=b,0|C;e:do{if(4&jt[1255])t=0,y=133;else{r=0|jt[1150];t:do{if(r){for(i=5024;;){if(e=0|jt[i>>2],e>>>0<=r>>>0?(m=i+4|0,(e+(0|jt[m>>2])|0)>>>0>r>>>0):0)break;if(!(e=0|jt[i+8>>2])){y=118;break t}i=e}if((t=o-a&n)>>>0<2147483647)if((0|(e=0|Ce(0|t)))==((0|jt[i>>2])+(0|jt[m>>2])|0)){if(-1!=(0|e)){a=t,o=e,y=135;break e}}else i=e,y=126;else t=0}else y=118}while(0);do{if(118==(0|y))if(r=0|Ce(0),-1!=(0|r)?(t=r,p=0|jt[1263],f=p+-1|0,t=(0==(f&t|0)?0:(f+t&0-p)-t|0)+u|0,p=0|jt[1252],f=t+p|0,t>>>0>d>>>0&t>>>0<2147483647):0){if(m=0|jt[1254],0|m?f>>>0<=p>>>0|f>>>0>m>>>0:0){t=0;break}if((0|(e=0|Ce(0|t)))==(0|r)){a=t,o=r,y=135;break e}i=e,y=126}else t=0}while(0);do{if(126==(0|y)){if(r=0-t|0,!(s>>>0>t>>>0&t>>>0<2147483647&-1!=(0|i))){if(-1==(0|i)){t=0;break}a=t,o=i,y=135;break e}if(e=0|jt[1264],(e=l-t+e&0-e)>>>0>=2147483647){a=t,o=i,y=135;break e}if(-1==(0|Ce(0|e))){Ce(0|r),t=0;break}a=e+t|0,o=i,y=135;break e}}while(0);jt[1255]=4|jt[1255],y=133}}while(0);if(!(133==(0|y)?u>>>0<2147483647:0)||(v=0|Ce(0|u),m=0|Ce(0),g=m-v|0,_=g>>>0>(d+40|0)>>>0,-1==(0|v)|1^_|v>>>0<m>>>0&-1!=(0|v)&-1!=(0|m)^1)||(a=_?g:t,o=v,y=135),135==(0|y)){t=(0|jt[1252])+a|0,jt[1252]=t,t>>>0>(0|jt[1253])>>>0&&(jt[1253]=t),l=0|jt[1150];do{if(l){for(t=5024;;){if(e=0|jt[t>>2],r=t+4|0,i=0|jt[r>>2],(0|o)==(e+i|0)){y=145;break}if(!(n=0|jt[t+8>>2]))break;t=n}if((145==(0|y)?0==(8&jt[t+12>>2]|0):0)?l>>>0<o>>>0&l>>>0>=e>>>0:0){jt[r>>2]=i+a,C=l+8|0,C=0==(7&C|0)?0:0-C&7,y=l+C|0,C=(0|jt[1147])+(a-C)|0,jt[1150]=y,jt[1147]=C,jt[y+4>>2]=1|C,jt[y+C+4>>2]=40,jt[1151]=jt[1266];break}for(o>>>0<(0|jt[1148])>>>0&&(jt[1148]=o),r=o+a|0,t=5024;;){if((0|jt[t>>2])==(0|r)){y=153;break}if(!(e=0|jt[t+8>>2]))break;t=e}if(153==(0|y)?0==(8&jt[t+12>>2]|0):0){jt[t>>2]=o,c=t+4|0,jt[c>>2]=(0|jt[c>>2])+a,c=o+8|0,c=o+(0==(7&c|0)?0:0-c&7)|0,t=r+8|0,t=r+(0==(7&t|0)?0:0-t&7)|0,u=c+d|0,s=t-c-d|0,jt[c+4>>2]=3|d;do{if((0|t)!=(0|l)){if((0|t)==(0|jt[1149])){C=(0|jt[1146])+s|0,jt[1146]=C,jt[1149]=u,jt[u+4>>2]=1|C,jt[u+C>>2]=C;break}if(1==(3&(e=0|jt[t+4>>2])|0)){a=-8&e,i=e>>>3;e:do{if(e>>>0<256){if(e=0|jt[t+8>>2],(0|(r=0|jt[t+12>>2]))==(0|e)){jt[1144]=jt[1144]&~(1<<i);break}jt[e+12>>2]=r,jt[r+8>>2]=e;break}o=0|jt[t+24>>2],e=0|jt[t+12>>2];do{if((0|e)==(0|t)){if(i=t+16|0,r=i+4|0,!(e=0|jt[r>>2])){if(!(e=0|jt[i>>2])){e=0;break}r=i}for(;;)if(i=e+20|0,0|(n=0|jt[i>>2]))e=n,r=i;else{if(i=e+16|0,!(n=0|jt[i>>2]))break;e=n,r=i}jt[r>>2]=0}else C=0|jt[t+8>>2],jt[C+12>>2]=e,jt[e+8>>2]=C}while(0);if(!o)break;r=0|jt[t+28>>2],i=4880+(r<<2)|0;do{if((0|t)==(0|jt[i>>2])){if(jt[i>>2]=e,0|e)break;jt[1145]=jt[1145]&~(1<<r);break e}if(jt[o+16+(((0|jt[o+16>>2])!=(0|t)&1)<<2)>>2]=e,!e)break e}while(0);if(jt[e+24>>2]=o,r=t+16|0,i=0|jt[r>>2],0|i&&(jt[e+16>>2]=i,jt[i+24>>2]=e),!(r=0|jt[r+4>>2]))break;jt[e+20>>2]=r,jt[r+24>>2]=e}while(0);t=t+a|0,n=a+s|0}else n=s;if(t=t+4|0,jt[t>>2]=-2&jt[t>>2],jt[u+4>>2]=1|n,jt[u+n>>2]=n,t=n>>>3,n>>>0<256){r=4616+(t<<1<<2)|0,e=0|jt[1144],t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=u,jt[t+12>>2]=u,jt[u+8>>2]=t,jt[u+12>>2]=r;break}t=n>>>8;do{if(t){if(n>>>0>16777215){t=31;break}y=(t+1048320|0)>>>16&8,C=t<<y,v=(C+520192|0)>>>16&4,C<<=v,t=(C+245760|0)>>>16&2,t=14-(v|y|t)+(C<<t>>>15)|0,t=n>>>(t+7|0)&1|t<<1}else t=0}while(0);if(i=4880+(t<<2)|0,jt[u+28>>2]=t,e=u+16|0,jt[e+4>>2]=0,jt[e>>2]=0,e=0|jt[1145],r=1<<t,!(e&r)){jt[1145]=e|r,jt[i>>2]=u,jt[u+24>>2]=i,jt[u+12>>2]=u,jt[u+8>>2]=u;break}for(e=n<<(31==(0|t)?0:25-(t>>>1)|0),r=0|jt[i>>2];;){if((-8&jt[r+4>>2]|0)==(0|n)){y=194;break}if(i=r+16+(e>>>31<<2)|0,!(t=0|jt[i>>2])){y=193;break}e<<=1,r=t}if(193==(0|y)){jt[i>>2]=u,jt[u+24>>2]=r,jt[u+12>>2]=u,jt[u+8>>2]=u;break}if(194==(0|y)){y=r+8|0,C=0|jt[y>>2],jt[C+12>>2]=u,jt[y>>2]=u,jt[u+8>>2]=C,jt[u+12>>2]=r,jt[u+24>>2]=0;break}}else C=(0|jt[1147])+s|0,jt[1147]=C,jt[1150]=u,jt[u+4>>2]=1|C}while(0);return C=c+8|0,or=b,0|C}for(t=5024;;){if(e=0|jt[t>>2],e>>>0<=l>>>0?(C=e+(0|jt[t+4>>2])|0)>>>0>l>>>0:0)break;t=0|jt[t+8>>2]}n=C+-47|0,e=n+8|0,e=n+(0==(7&e|0)?0:0-e&7)|0,n=l+16|0,e=e>>>0<n>>>0?l:e,t=e+8|0,r=o+8|0,r=0==(7&r|0)?0:0-r&7,y=o+r|0,r=a+-40-r|0,jt[1150]=y,jt[1147]=r,jt[y+4>>2]=1|r,jt[y+r+4>>2]=40,jt[1151]=jt[1266],r=e+4|0,jt[r>>2]=27,jt[t>>2]=jt[1256],jt[t+4>>2]=jt[1257],jt[t+8>>2]=jt[1258],jt[t+12>>2]=jt[1259],jt[1256]=o,jt[1257]=a,jt[1259]=0,jt[1258]=t,t=e+24|0;do{y=t,t=t+4|0,jt[t>>2]=7}while((y+8|0)>>>0<C>>>0);if((0|e)!=(0|l)){if(o=e-l|0,jt[r>>2]=-2&jt[r>>2],jt[l+4>>2]=1|o,jt[e>>2]=o,t=o>>>3,o>>>0<256){r=4616+(t<<1<<2)|0,e=0|jt[1144],t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=l,jt[t+12>>2]=l,jt[l+8>>2]=t,jt[l+12>>2]=r;break}if(t=o>>>8,t?o>>>0>16777215?r=31:(y=(t+1048320|0)>>>16&8,C=t<<y,v=(C+520192|0)>>>16&4,C<<=v,r=(C+245760|0)>>>16&2,r=14-(v|y|r)+(C<<r>>>15)|0,r=o>>>(r+7|0)&1|r<<1):r=0,i=4880+(r<<2)|0,jt[l+28>>2]=r,jt[l+20>>2]=0,jt[n>>2]=0,t=0|jt[1145],e=1<<r,!(t&e)){jt[1145]=t|e,jt[i>>2]=l,jt[l+24>>2]=i,jt[l+12>>2]=l,jt[l+8>>2]=l;break}for(e=o<<(31==(0|r)?0:25-(r>>>1)|0),r=0|jt[i>>2];;){if((-8&jt[r+4>>2]|0)==(0|o)){y=216;break}if(i=r+16+(e>>>31<<2)|0,!(t=0|jt[i>>2])){y=215;break}e<<=1,r=t}if(215==(0|y)){jt[i>>2]=l,jt[l+24>>2]=r,jt[l+12>>2]=l,jt[l+8>>2]=l;break}if(216==(0|y)){y=r+8|0,C=0|jt[y>>2],jt[C+12>>2]=l,jt[y>>2]=l,jt[l+8>>2]=C,jt[l+12>>2]=r,jt[l+24>>2]=0;break}}}else{C=0|jt[1148],0==(0|C)|o>>>0<C>>>0&&(jt[1148]=o),jt[1256]=o,jt[1257]=a,jt[1259]=0,jt[1153]=jt[1262],jt[1152]=-1,t=0;do{C=4616+(t<<1<<2)|0,jt[C+12>>2]=C,jt[C+8>>2]=C,t=t+1|0}while(32!=(0|t));C=o+8|0,C=0==(7&C|0)?0:0-C&7,y=o+C|0,C=a+-40-C|0,jt[1150]=y,jt[1147]=C,jt[y+4>>2]=1|C,jt[y+C+4>>2]=40,jt[1151]=jt[1266]}}while(0);if((t=0|jt[1147])>>>0>d>>>0)return v=t-d|0,jt[1147]=v,C=0|jt[1150],y=C+d|0,jt[1150]=y,jt[y+4>>2]=1|v,jt[C+4>>2]=3|d,C=C+8|0,or=b,0|C}return C=0|At(),jt[C>>2]=12,C=0,or=b,0|C}function o(e,t,r,i,n,o){e|=0,t=+t,r|=0,i|=0,n|=0,o|=0;var a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,b=0,S=0,w=0,T=0,A=0,E=0,x=0,P=0;P=or,or=or+560|0,l=P+8|0,g=P,x=P+524|0,E=x,u=P+512|0,jt[g>>2]=0,A=u+12|0,Ze(t),(0|cr)<0?(t=-t,w=1,S=2087):(w=0!=(2049&n|0)&1,S=0==(2048&n|0)?0==(1&n|0)?2088:2093:2090),Ze(t),T=2146435072&cr;do{if(T>>>0<2146435072|2146435072==(0|T)&!1){if(p=2*+wt(t,g),a=0!=p,a&&(jt[g>>2]=(0|jt[g>>2])-1),97==(0|(v=32|o))){f=32&o,h=0==(0|f)?S:S+9|0,d=2|w,a=12-i|0;do{if(!(i>>>0>11|0==(0|a))){t=8;do{a=a+-1|0,t*=16}while(0!=(0|a));if(45==(0|zt[h>>0])){t=-(t+(-p-t));break}t=p+t-t;break}t=p}while(0);s=0|jt[g>>2],a=(0|s)<0?0-s|0:s,a=0|ue(a,((0|a)<0)<<31>>31,A),(0|a)==(0|A)&&(a=u+11|0,zt[a>>0]=48),zt[a+-1>>0]=43+(s>>31&2),c=a+-2|0,zt[c>>0]=o+15,u=(0|i)<1,l=0==(8&n|0),a=x;do{T=~~t,s=a+1|0,zt[a>>0]=Yt[2122+T>>0]|f,t=16*(t-+(0|T)),1!=(s-E|0)||l&u&0==t?a=s:(zt[s>>0]=46,a=a+2|0)}while(0!=t);T=a-E|0,E=A-c|0,A=0!=(0|i)&(T+-2|0)<(0|i)?i+2|0:T,a=E+d+A|0,fe(e,32,r,a,n),it(e,h,d),fe(e,48,r,a,65536^n),it(e,x,T),fe(e,48,A-T|0,0,0),it(e,c,E),fe(e,32,r,a,8192^n);break}s=(0|i)<0?6:i,a?(a=(0|jt[g>>2])-28|0,jt[g>>2]=a,t=268435456*p):(t=p,a=0|jt[g>>2]),T=(0|a)<0?l:l+288|0,l=T;do{C=~~t>>>0,jt[l>>2]=C,l=l+4|0,t=1e9*(t-+(C>>>0))}while(0!=t);if((0|a)>0)for(u=T,d=l;;){if(c=(0|a)<29?a:29,(a=d+-4|0)>>>0>=u>>>0){l=0;do{y=0|He(0|jt[a>>2],0,0|c),y=0|Ke(0|y,0|cr,0|l,0),C=cr,_=0|Oe(0|y,0|C,1e9,0),jt[a>>2]=_,l=0|ct(0|y,0|C,1e9,0),a=a+-4|0}while(a>>>0>=u>>>0);l&&(u=u+-4|0,jt[u>>2]=l)}for(l=d;;){if(l>>>0<=u>>>0)break;if(a=l+-4|0,0|jt[a>>2])break;l=a}if(a=(0|jt[g>>2])-c|0, -jt[g>>2]=a,!((0|a)>0))break;d=l}else u=T;if((0|a)<0){i=1+((s+25|0)/9|0)|0,m=102==(0|v);do{if(f=0-a|0,f=(0|f)<9?f:9,u>>>0<l>>>0){c=(1<<f)-1|0,d=1e9>>>f,h=0,a=u;do{C=0|jt[a>>2],jt[a>>2]=(C>>>f)+h,h=0|dr(C&c,d),a=a+4|0}while(a>>>0<l>>>0);a=0==(0|jt[u>>2])?u+4|0:u,h?(jt[l>>2]=h,u=a,a=l+4|0):(u=a,a=l)}else u=0==(0|jt[u>>2])?u+4|0:u,a=l;l=m?T:u,l=(a-l>>2|0)>(0|i)?l+(i<<2)|0:a,a=(0|jt[g>>2])+f|0,jt[g>>2]=a}while((0|a)<0);a=u,i=l}else a=u,i=l;if(C=T,a>>>0<i>>>0){if(l=9*(C-a>>2)|0,(c=0|jt[a>>2])>>>0>=10){u=10;do{u=10*u|0,l=l+1|0}while(c>>>0>=u>>>0)}}else l=0;if(m=103==(0|v),_=0!=(0|s),(0|(u=s-(102!=(0|v)?l:0)+((_&m)<<31>>31)|0))<((9*(i-C>>2)|0)-9|0)){if(u=u+9216|0,f=T+4+(((0|u)/9|0)-1024<<2)|0,(0|(u=1+((0|u)%9|0)|0))<9){c=10;do{c=10*c|0,u=u+1|0}while(9!=(0|u))}else c=10;if(d=0|jt[f>>2],h=(d>>>0)%(c>>>0)|0,(u=(f+4|0)==(0|i))&0==(0|h))u=f;else if(p=0==(1&((d>>>0)/(c>>>0)|0)|0)?9007199254740992:9007199254740994,y=(0|c)/2|0,t=h>>>0<y>>>0?.5:u&(0|h)==(0|y)?1:1.5,w&&(y=45==(0|zt[S>>0]),t=y?-t:t,p=y?-p:p),u=d-h|0,jt[f>>2]=u,p+t!=p){if(y=u+c|0,jt[f>>2]=y,y>>>0>999999999)for(l=f;;){if(u=l+-4|0,jt[l>>2]=0,u>>>0<a>>>0&&(a=a+-4|0,jt[a>>2]=0),y=1+(0|jt[u>>2])|0,jt[u>>2]=y,!(y>>>0>999999999))break;l=u}else u=f;if(l=9*(C-a>>2)|0,(d=0|jt[a>>2])>>>0>=10){c=10;do{c=10*c|0,l=l+1|0}while(d>>>0>=c>>>0)}}else u=f;u=u+4|0,u=i>>>0>u>>>0?u:i,y=a}else u=i,y=a;for(v=u;;){if(v>>>0<=y>>>0){g=0;break}if(a=v+-4|0,0|jt[a>>2]){g=1;break}v=a}i=0-l|0;do{if(m){if(a=(1&(1^_))+s|0,(0|a)>(0|l)&(0|l)>-5?(c=o+-1|0,s=a+-1-l|0):(c=o+-2|0,s=a+-1|0),!(a=8&n)){if(g?0!=(0|(b=0|jt[v+-4>>2])):0)if((b>>>0)%10|0)u=0;else{u=0,a=10;do{a=10*a|0,u=u+1|0}while(!(0|(b>>>0)%(a>>>0)))}else u=9;if(a=(9*(v-C>>2)|0)-9|0,102==(32|c)){f=a-u|0,f=(0|f)>0?f:0,s=(0|s)<(0|f)?s:f,f=0;break}f=a+l-u|0,f=(0|f)>0?f:0,s=(0|s)<(0|f)?s:f,f=0;break}f=a}else c=o,f=8&n}while(0);if(m=s|f,d=0!=(0|m)&1,h=102==(32|c))_=0,a=(0|l)>0?l:0;else{if(a=(0|l)<0?i:l,a=0|ue(a,((0|a)<0)<<31>>31,A),((u=A)-a|0)<2)do{a=a+-1|0,zt[a>>0]=48}while((u-a|0)<2);zt[a+-1>>0]=43+(l>>31&2),a=a+-2|0,zt[a>>0]=c,_=a,a=u-a|0}if(a=w+1+s+d+a|0,fe(e,32,r,a,n),it(e,S,w),fe(e,48,r,a,65536^n),h){c=y>>>0>T>>>0?T:y,f=x+9|0,d=f,h=x+8|0,u=c;do{if(l=0|ue(0|jt[u>>2],0,f),(0|u)==(0|c))(0|l)==(0|f)&&(zt[h>>0]=48,l=h);else if(l>>>0>x>>>0){ee(0|x,48,l-E|0);do{l=l+-1|0}while(l>>>0>x>>>0)}it(e,l,d-l|0),u=u+4|0}while(u>>>0<=T>>>0);if(0|m&&it(e,2138,1),u>>>0<v>>>0&(0|s)>0)for(;;){if((l=0|ue(0|jt[u>>2],0,f))>>>0>x>>>0){ee(0|x,48,l-E|0);do{l=l+-1|0}while(l>>>0>x>>>0)}if(it(e,l,(0|s)<9?s:9),u=u+4|0,l=s+-9|0,!(u>>>0<v>>>0&(0|s)>9)){s=l;break}s=l}fe(e,48,s+9|0,9,0)}else{if(m=g?v:y+4|0,(0|s)>-1){g=x+9|0,f=0==(0|f),i=g,d=0-E|0,h=x+8|0,c=y;do{l=0|ue(0|jt[c>>2],0,g),(0|l)==(0|g)&&(zt[h>>0]=48,l=h);do{if((0|c)==(0|y)){if(u=l+1|0,it(e,l,1),f&(0|s)<1){l=u;break}it(e,2138,1),l=u}else{if(l>>>0<=x>>>0)break;ee(0|x,48,l+d|0);do{l=l+-1|0}while(l>>>0>x>>>0)}}while(0);E=i-l|0,it(e,l,(0|s)>(0|E)?E:s),s=s-E|0,c=c+4|0}while(c>>>0<m>>>0&(0|s)>-1)}fe(e,48,s+18|0,18,0),it(e,_,A-_|0)}fe(e,32,r,a,8192^n)}else x=0!=(32&o|0),a=w+3|0,fe(e,32,r,a,-65537&n),it(e,S,w),it(e,t!=t|!1?x?2114:2118:x?2106:2110,3),fe(e,32,r,a,8192^n)}while(0);return or=P,0|((0|a)<(0|r)?r:a)}function a(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,b=0,S=0,T=0,A=0,E=0,x=0,P=0,D=0;D=or,or=or+64|0,A=D+16|0,E=D,S=D+24|0,x=D+8|0,P=D+20|0,jt[A>>2]=t,y=0!=(0|e),C=S+40|0,b=C,S=S+39|0,T=x+4|0,s=0,a=0,d=0;e:for(;;){do{if((0|a)>-1){if((0|s)>(2147483647-a|0)){a=0|At(),jt[a>>2]=75,a=-1;break}a=s+a|0;break}}while(0);if(!((s=0|zt[t>>0])<<24>>24)){v=87;break}l=t;t:for(;;){switch(s<<24>>24){case 37:s=l,v=9;break t;case 0:s=l;break t}_=l+1|0,jt[A>>2]=_,s=0|zt[_>>0],l=_}t:do{if(9==(0|v))for(;;){if(v=0,37!=(0|zt[l+1>>0]))break t;if(s=s+1|0,l=l+2|0,jt[A>>2]=l,37!=(0|zt[l>>0]))break;v=9}}while(0);if(s=s-t|0,y&&it(e,t,s),0|s)t=l;else{u=l+1|0,s=(0|zt[u>>0])-48|0,s>>>0<10?(_=36==(0|zt[l+2>>0]),g=_?s:-1,d=_?1:d,u=_?l+3|0:u):g=-1,jt[A>>2]=u,s=0|zt[u>>0],l=(s<<24>>24)-32|0;t:do{if(l>>>0<32)for(c=0,h=s;;){if(!(75913&(s=1<<l))){s=h;break t}if(c|=s,u=u+1|0,jt[A>>2]=u,s=0|zt[u>>0],(l=(s<<24>>24)-32|0)>>>0>=32)break;h=s}else c=0}while(0);if(s<<24>>24==42){if(l=u+1|0,s=(0|zt[l>>0])-48|0,s>>>0<10?36==(0|zt[u+2>>0]):0)jt[n+(s<<2)>>2]=10,s=0|jt[i+((0|zt[l>>0])-48<<3)>>2],d=1,u=u+3|0;else{if(0|d){a=-1;break}y?(d=3+(0|jt[r>>2])&-4,s=0|jt[d>>2],jt[r>>2]=d+4,d=0,u=l):(s=0,d=0,u=l)}jt[A>>2]=u,_=(0|s)<0,s=_?0-s|0:s,c=_?8192|c:c}else{if((0|(s=0|Te(A)))<0){a=-1;break}u=0|jt[A>>2]}do{if(46==(0|zt[u>>0])){if(42!=(0|zt[u+1>>0])){jt[A>>2]=u+1,l=0|Te(A),u=0|jt[A>>2];break}if(h=u+2|0,l=(0|zt[h>>0])-48|0,l>>>0<10?36==(0|zt[u+3>>0]):0){jt[n+(l<<2)>>2]=10,l=0|jt[i+((0|zt[h>>0])-48<<3)>>2],u=u+4|0,jt[A>>2]=u;break}if(0|d){a=-1;break e}y?(_=3+(0|jt[r>>2])&-4,l=0|jt[_>>2],jt[r>>2]=_+4):l=0,jt[A>>2]=h,u=h}else l=-1}while(0);for(m=0;;){if(((0|zt[u>>0])-65|0)>>>0>57){a=-1;break e}if(_=u+1|0,jt[A>>2]=_,h=0|zt[(0|zt[u>>0])-65+(1606+(58*m|0))>>0],!(((p=255&h)+-1|0)>>>0<8))break;m=p,u=_}if(!(h<<24>>24)){a=-1;break}f=(0|g)>-1;do{if(h<<24>>24==19){if(f){a=-1;break e}v=49}else{if(f){jt[n+(g<<2)>>2]=p,f=i+(g<<3)|0,g=0|jt[f+4>>2],v=E,jt[v>>2]=jt[f>>2],jt[v+4>>2]=g,v=49;break}if(!y){a=0;break e}w(E,p,r)}}while(0);if(49!=(0|v)||(v=0,y)){u=0|zt[u>>0],u=0!=(0|m)&3==(15&u|0)?-33&u:u,f=-65537&c,g=0==(8192&c|0)?c:f;t:do{switch(0|u){case 110:switch((255&m)<<24>>24){case 0:case 1:jt[jt[E>>2]>>2]=a,s=0,t=_;continue e;case 2:s=0|jt[E>>2],jt[s>>2]=a,jt[s+4>>2]=((0|a)<0)<<31>>31,s=0,t=_;continue e;case 3:Ht[jt[E>>2]>>1]=a,s=0,t=_;continue e;case 4:zt[jt[E>>2]>>0]=a,s=0,t=_;continue e;case 6:jt[jt[E>>2]>>2]=a,s=0,t=_;continue e;case 7:s=0|jt[E>>2],jt[s>>2]=a,jt[s+4>>2]=((0|a)<0)<<31>>31,s=0,t=_;continue e;default:s=0,t=_;continue e}case 112:u=120,l=l>>>0>8?l:8,t=8|g,v=61;break;case 88:case 120:t=g,v=61;break;case 111:u=E,t=0|jt[u>>2],u=0|jt[u+4>>2],p=0|De(t,u,C),f=b-p|0,c=0,h=2070,l=0==(8&g|0)|(0|l)>(0|f)?l:f+1|0,f=g,v=67;break;case 105:case 100:if(u=E,t=0|jt[u>>2],(0|(u=0|jt[u+4>>2]))<0){t=0|Ye(0,0,0|t,0|u),u=cr,c=E,jt[c>>2]=t,jt[c+4>>2]=u,c=1,h=2070,v=66;break t}c=0!=(2049&g|0)&1,h=0==(2048&g|0)?0==(1&g|0)?2070:2072:2071,v=66;break t;case 117:u=E,c=0,h=2070,t=0|jt[u>>2],u=0|jt[u+4>>2],v=66;break;case 99:zt[S>>0]=jt[E>>2],t=S,c=0,h=2070,p=C,u=1,l=f;break;case 109:u=0|At(),u=0|at(0|jt[u>>2]),v=71;break;case 115:u=0|jt[E>>2],u=0|u?u:2080,v=71;break;case 67:jt[x>>2]=jt[E>>2],jt[T>>2]=0,jt[E>>2]=x,p=-1,u=x,v=75;break;case 83:t=0|jt[E>>2],l?(p=l,u=t,v=75):(fe(e,32,s,0,g),t=0,v=84);break;case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:s=0|o(e,+tr[E>>3],s,l,g,u),t=_;continue e;default:c=0,h=2070,p=C,u=l,l=g}}while(0);t:do{if(61==(0|v))g=E,m=0|jt[g>>2],g=0|jt[g+4>>2],p=0|Ae(m,g,C,32&u),h=0==(8&t|0)|0==(0|m)&0==(0|g),c=h?0:2,h=h?2070:2070+(u>>4)|0,f=t,t=m,u=g,v=67;else if(66==(0|v))p=0|ue(t,u,C),f=g,v=67;else if(71==(0|v))v=0,g=0|z(u,0,l),m=0==(0|g),t=u,c=0,h=2070,p=m?u+l|0:g,u=m?l:g-u|0,l=f;else if(75==(0|v)){for(v=0,h=u,t=0,l=0;;){if(!(c=0|jt[h>>2]))break;if((0|(l=0|st(P,c)))<0|l>>>0>(p-t|0)>>>0)break;if(t=l+t|0,!(p>>>0>t>>>0))break;h=h+4|0}if((0|l)<0){a=-1;break e}if(fe(e,32,s,t,g),t)for(c=0;;){if(!(l=0|jt[u>>2])){v=84;break t}if(l=0|st(P,l),(0|(c=l+c|0))>(0|t)){v=84;break t}if(it(e,P,l),c>>>0>=t>>>0){v=84;break}u=u+4|0}else t=0,v=84}}while(0);if(67==(0|v))v=0,u=0!=(0|t)|0!=(0|u),g=0!=(0|l)|u,u=b-p+(1&(1^u))|0,t=g?p:C,p=C,u=g?(0|l)>(0|u)?l:u:l,l=(0|l)>-1?-65537&f:f;else if(84==(0|v)){v=0,fe(e,32,s,t,8192^g),s=(0|s)>(0|t)?s:t,t=_;continue}m=p-t|0,f=(0|u)<(0|m)?m:u,g=f+c|0,s=(0|s)<(0|g)?g:s,fe(e,32,s,g,l),it(e,h,c),fe(e,48,s,g,65536^l),fe(e,48,f,m,0),it(e,t,m),fe(e,32,s,g,8192^l),t=_}else s=0,t=_}}e:do{if(87==(0|v)&&!e)if(d){for(a=1;;){if(!(t=0|jt[n+(a<<2)>>2]))break;if(w(i+(a<<3)|0,t,r),(0|(a=a+1|0))>=10){a=1;break e}}for(;;){if(0|jt[n+(a<<2)>>2]){a=-1;break e}if((0|(a=a+1|0))>=10){a=1;break}}}else a=0}while(0);return or=D,0|a}function s(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,E=0,x=0,P=0;if(P=or,or=or+704|0,w=P+144|0,S=P+128|0,C=P+112|0,y=P+96|0,v=P+80|0,_=P+64|0,g=P+48|0,T=P+32|0,c=P+16|0,s=P,h=P+184|0,x=P+160|0,!(p=0|W(e,14)))return Z(t),x=1,or=P,0|x;if(f=t+4|0,m=t+8|0,(0|(r=0|jt[m>>2]))!=(0|p)){if(r>>>0<=p>>>0){do{if((0|jt[t+12>>2])>>>0<p>>>0){if(0|A(f,p,(r+1|0)==(0|p),1,0)){r=0|jt[m>>2];break}return zt[t+16>>0]=1,x=0,or=P,0|x}}while(0);ee((0|jt[f>>2])+r|0,0,p-r|0)}jt[m>>2]=p}if(ee(0|jt[f>>2],0,0|p),d=e+20|0,(0|(r=0|jt[d>>2]))<5){o=e+4|0,a=e+8|0,n=e+16|0;do{i=0|jt[o>>2],(0|i)==(0|jt[a>>2])?i=0:(jt[o>>2]=i+1,i=0|Yt[i>>0]),r=r+8|0,jt[d>>2]=r,(0|r)>=33&&(jt[s>>2]=866,jt[s+4>>2]=3208,jt[s+8>>2]=1366,Ve(h,812,s),he(h),r=0|jt[d>>2]),i=i<<32-r|jt[n>>2],jt[n>>2]=i}while((0|r)<5)}else i=e+16|0,n=i,i=0|jt[i>>2];if(u=i>>>27,jt[n>>2]=i<<5,jt[d>>2]=r+-5,(u+-1|0)>>>0>20)return x=0,or=P,0|x;jt[x+20>>2]=0,jt[x>>2]=0,jt[x+4>>2]=0,jt[x+8>>2]=0,jt[x+12>>2]=0,zt[x+16>>0]=0,r=x+4|0,i=x+8|0;e:do{if(0|A(r,21,0,1,0)){o=0|jt[i>>2],l=0|jt[r>>2],ee(l+o|0,0,21-o|0),jt[i>>2]=21,o=e+4|0,a=e+8|0,s=e+16|0,n=0;do{if((0|(r=0|jt[d>>2]))<3)do{i=0|jt[o>>2],(0|i)==(0|jt[a>>2])?i=0:(jt[o>>2]=i+1,i=0|Yt[i>>0]),r=r+8|0,jt[d>>2]=r,(0|r)>=33&&(jt[c>>2]=866,jt[c+4>>2]=3208,jt[c+8>>2]=1366,Ve(h,812,c),he(h),r=0|jt[d>>2]),i=i<<32-r|jt[s>>2],jt[s>>2]=i}while((0|r)<3);else i=0|jt[s>>2];jt[s>>2]=i<<3,jt[d>>2]=r+-3,zt[l+(0|Yt[1327+n>>0])>>0]=i>>>29,n=n+1|0}while((0|n)!=(0|u));if(0|k(x)){s=e+4|0,l=e+8|0,u=e+16|0,r=0;t:do{a=p-r|0,n=0|b(e,x);r:do{if(n>>>0<17)(0|jt[m>>2])>>>0<=r>>>0&&(jt[T>>2]=866,jt[T+4>>2]=910,jt[T+8>>2]=1497,Ve(h,812,T),he(h)),zt[(0|jt[f>>2])+r>>0]=n,r=r+1|0;else switch(0|n){case 17:if((0|(i=0|jt[d>>2]))<3)do{n=0|jt[s>>2],(0|n)==(0|jt[l>>2])?n=0:(jt[s>>2]=n+1,n=0|Yt[n>>0]),i=i+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[g>>2]=866,jt[g+4>>2]=3208,jt[g+8>>2]=1366,Ve(h,812,g),he(h),i=0|jt[d>>2]),n=n<<32-i|jt[u>>2],jt[u>>2]=n}while((0|i)<3);else n=0|jt[u>>2];if(jt[u>>2]=n<<3,jt[d>>2]=i+-3,n=3+(n>>>29)|0,i=n>>>0>a>>>0){r=0;break e}r=(i?0:n)+r|0;break r;case 18:if((0|(i=0|jt[d>>2]))<7)do{n=0|jt[s>>2],(0|n)==(0|jt[l>>2])?n=0:(jt[s>>2]=n+1,n=0|Yt[n>>0]),i=i+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[_>>2]=866,jt[_+4>>2]=3208,jt[_+8>>2]=1366,Ve(h,812,_),he(h),i=0|jt[d>>2]),n=n<<32-i|jt[u>>2],jt[u>>2]=n}while((0|i)<7);else n=0|jt[u>>2];if(jt[u>>2]=n<<7,jt[d>>2]=i+-7,n=11+(n>>>25)|0,i=n>>>0>a>>>0){r=0;break e}r=(i?0:n)+r|0;break r;default:if((n+-19|0)>>>0>=2){E=81;break t}if(i=0|jt[d>>2],19==(0|n)){if((0|i)<2)for(n=i;;){if(i=0|jt[s>>2],(0|i)==(0|jt[l>>2])?o=0:(jt[s>>2]=i+1,o=0|Yt[i>>0]),i=n+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[v>>2]=866,jt[v+4>>2]=3208,jt[v+8>>2]=1366,Ve(h,812,v),he(h),i=0|jt[d>>2]),n=o<<32-i|jt[u>>2],jt[u>>2]=n,!((0|i)<2))break;n=i}else n=0|jt[u>>2];jt[u>>2]=n<<2,n>>>=30,o=3,i=i+-2|0}else{if((0|i)<6)do{n=0|jt[s>>2],(0|n)==(0|jt[l>>2])?n=0:(jt[s>>2]=n+1,n=0|Yt[n>>0]),i=i+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[y>>2]=866,jt[y+4>>2]=3208,jt[y+8>>2]=1366,Ve(h,812,y),he(h),i=0|jt[d>>2]),n=n<<32-i|jt[u>>2],jt[u>>2]=n}while((0|i)<6);else n=0|jt[u>>2];jt[u>>2]=n<<6,n>>>=26,o=7,i=i+-6|0}if(jt[d>>2]=i,n=n+o|0,0==(0|r)|n>>>0>a>>>0){r=0;break e}if(i=r+-1|0,(0|jt[m>>2])>>>0<=i>>>0&&(jt[C>>2]=866,jt[C+4>>2]=910,jt[C+8>>2]=1497,Ve(h,812,C),he(h)),!((o=0|zt[(0|jt[f>>2])+i>>0])<<24>>24)){r=0;break e}if(i=n+r|0,r>>>0>=i>>>0)break r;do{(0|jt[m>>2])>>>0<=r>>>0&&(jt[S>>2]=866,jt[S+4>>2]=910,jt[S+8>>2]=1497,Ve(h,812,S),he(h)),zt[(0|jt[f>>2])+r>>0]=o,r=r+1|0}while((0|r)!=(0|i));r=i}}while(0)}while(p>>>0>r>>>0);if(81==(0|E)){jt[w>>2]=866,jt[w+4>>2]=3149,jt[w+8>>2]=1348,Ve(h,812,w),he(h),r=0;break}r=(0|p)==(0|r)?0|k(t):0}else r=0}else zt[x+16>>0]=1,r=0}while(0);return X(x),x=r,or=P,0|x}function l(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,b=0,S=0,w=0,T=0,A=0,E=0,x=0,P=0,D=0,I=0,O=0;if(O=or,or=or+880|0,D=O+144|0,P=O+128|0,x=O+112|0,E=O+96|0,S=O+80|0,_=O+64|0,m=O+48|0,g=O+32|0,d=O+16|0,c=O,T=O+360|0,A=O+296|0,I=O+224|0,f=O+156|0,0==(0|t)|i>>>0>11)return I=0,or=O,0|I;jt[e>>2]=t,n=I,o=n+68|0;do{jt[n>>2]=0,n=n+4|0}while((0|n)<(0|o));n=0;do{w=0|zt[r+n>>0],o=I+((255&w)<<2)|0,w<<24>>24&&(jt[o>>2]=1+(0|jt[o>>2])),n=n+1|0}while((0|n)!=(0|t));for(o=0,a=0,s=0,l=-1,u=1;;){if(n=0|jt[I+(u<<2)>>2],n?(h=u+-1|0,jt[A+(h<<2)>>2]=o,o=n+o|0,w=16-u|0,jt[e+28+(h<<2)>>2]=1+(o+-1<<w|(1<<w)-1),jt[e+96+(h<<2)>>2]=a,jt[f+(u<<2)>>2]=a,h=n+a|0,s=s>>>0>u>>>0?s:u,l=l>>>0<u>>>0?l:u):(jt[e+28+(u+-1<<2)>>2]=0,h=a),17==(0|(u=u+1|0)))break;o<<=1,a=h}jt[e+4>>2]=h,o=e+172|0;do{if(h>>>0>(0|jt[o>>2])>>>0){n=h+-1|0,n&h?(n|=n>>>16,n|=n>>>8,n|=n>>>4,n|=n>>>2,n=1+(n>>>1|n)|0,n=n>>>0>t>>>0?t:n):n=h,jt[o>>2]=n,a=e+176|0,n=0|jt[a>>2];do{if(0|n){if(w=0|jt[n+-4>>2],n=n+-8|0,(0!=(0|w)?(0|w)==(0|~jt[n>>2]):0)||(jt[c>>2]=866,jt[c+4>>2]=651,jt[c+8>>2]=1579,Ve(T,812,c),he(T)),7&n){jt[d>>2]=866,jt[d+4>>2]=2506,jt[d+8>>2]=1232,Ve(T,812,d),he(T);break}oe(n,0,0,1,0);break}}while(0);if(n=0|jt[o>>2],n=0|n?n:1,o=0|Q(8+(n<<1)|0,0)){jt[o+4>>2]=n,jt[o>>2]=~n,jt[a>>2]=o+8,p=24;break}jt[a>>2]=0,i=0;break}p=24}while(0);e:do{if(24==(0|p)){w=e+24|0,zt[w>>0]=l,zt[e+25>>0]=s,a=e+176|0,o=0;do{b=0|zt[r+o>>0],n=255&b,b<<24>>24&&(0|jt[I+(n<<2)>>2]||(jt[g>>2]=866,jt[g+4>>2]=2276,jt[g+8>>2]=977,Ve(T,812,g),he(T)),b=f+(n<<2)|0,n=0|jt[b>>2],jt[b>>2]=n+1,n>>>0>=h>>>0&&(jt[m>>2]=866,jt[m+4>>2]=2280,jt[m+8>>2]=990,Ve(T,812,m),he(T)),Ht[(0|jt[a>>2])+(n<<1)>>1]=o),o=o+1|0}while((0|o)!=(0|t));if(C=(0|Yt[w>>0])>>>0<i>>>0?i:0,b=e+8|0,jt[b>>2]=C,y=0!=(0|C)){v=1<<C,n=e+164|0;do{if(v>>>0>(0|jt[n>>2])>>>0){jt[n>>2]=v,a=e+168|0,n=0|jt[a>>2];do{if(0|n){if(g=0|jt[n+-4>>2],n=n+-8|0,(0!=(0|g)?(0|g)==(0|~jt[n>>2]):0)||(jt[_>>2]=866,jt[_+4>>2]=651,jt[_+8>>2]=1579,Ve(T,812,_),he(T)),7&n){jt[S>>2]=866,jt[S+4>>2]=2506,jt[S+8>>2]=1232,Ve(T,812,S),he(T);break}oe(n,0,0,1,0);break}}while(0);if(n=v<<2,o=0|Q(n+8|0,0)){S=o+8|0,jt[o+4>>2]=v,jt[o>>2]=~v,jt[a>>2]=S,o=S;break}jt[a>>2]=0,i=0;break e}o=e+168|0,n=v<<2,a=o,o=0|jt[o>>2]}while(0);ee(0|o,-1,0|n),m=e+176|0,f=1;do{if(0|jt[I+(f<<2)>>2]&&(g=C-f|0,_=1<<g,n=f+-1|0,o=0|jt[A+(n<<2)>>2],n>>>0>=16&&(jt[E>>2]=866,jt[E+4>>2]=1960,jt[E+8>>2]=1453,Ve(T,812,E),he(T)),t=0|jt[e+28+(n<<2)>>2],t=0==(0|t)?-1:(t+-1|0)>>>(16-f|0),o>>>0<=t>>>0)){h=(0|jt[e+96+(n<<2)>>2])-o|0,p=f<<16;do{n=0|Qt[(0|jt[m>>2])+(h+o<<1)>>1],(0|Yt[r+n>>0])!=(0|f)&&(jt[x>>2]=866,jt[x+4>>2]=2322,jt[x+8>>2]=1019,Ve(T,812,x),he(T)),d=o<<g,u=n|p,l=0;do{c=l+d|0,c>>>0>=v>>>0&&(jt[P>>2]=866,jt[P+4>>2]=2328,jt[P+8>>2]=1053,Ve(T,812,P),he(T)),n=0|jt[a>>2],-1!=(0|jt[n+(c<<2)>>2])&&(jt[D>>2]=866,jt[D+4>>2]=2330,jt[D+8>>2]=1076,Ve(T,812,D),he(T),n=0|jt[a>>2]),jt[n+(c<<2)>>2]=u,l=l+1|0}while(l>>>0<_>>>0);o=o+1|0}while(o>>>0<=t>>>0)}f=f+1|0}while(C>>>0>=f>>>0)}n=e+96|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A>>2]),n=e+100|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+4>>2]),n=e+104|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+8>>2]),n=e+108|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+12>>2]),n=e+112|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+16>>2]),n=e+116|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+20>>2]),n=e+120|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+24>>2]),n=e+124|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+28>>2]),n=e+128|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+32>>2]),n=e+132|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+36>>2]),n=e+136|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+40>>2]),n=e+140|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+44>>2]),n=e+144|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+48>>2]),n=e+148|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+52>>2]),n=e+152|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+56>>2]),n=e+156|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[A+60>>2]),n=e+16|0,jt[n>>2]=0,o=e+20|0,jt[o>>2]=Yt[w>>0];t:do{if(y){do{if(!i)break t;D=i,i=i+-1|0}while(!(0|jt[I+(D<<2)>>2]));if(jt[n>>2]=jt[e+28+(i<<2)>>2],i=C+1|0,jt[o>>2]=i,i>>>0<=s>>>0){for(;;){if(0|jt[I+(i<<2)>>2])break;if((i=i+1|0)>>>0>s>>>0)break t}jt[o>>2]=i}}}while(0);jt[e+92>>2]=-1,jt[e+160>>2]=1048575,jt[e+12>>2]=32-(0|jt[b>>2]),i=1}}while(0);return I=i,or=O,0|I}function u(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,A=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,N=0,L=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,H=0,W=0,j=0,q=0,Y=0,X=0,Q=0,Z=0,K=0,J=0,$=0,ee=0,te=0,re=0,ie=0,ne=0;if(re=or,or=or+656|0,ee=re+112|0,J=re+96|0,K=re+80|0,Z=re+64|0,Q=re+48|0,te=re+32|0,$=re+16|0,X=re,q=re+144|0,Y=re+128|0,k=e+240|0,F=0|jt[k>>2],B=e+256|0,U=0|jt[B>>2],j=0|zt[17+(0|jt[e+88>>2])>>0],V=255&j,z=i>>>2,!(j<<24>>24))return or=re,1;G=0==(0|s),H=a+-1|0,W=H<<4,j=s+-1|0,I=0!=(1&o|0),O=i<<1,M=e+92|0,R=e+116|0,N=e+140|0,L=e+236|0,D=0!=(1&n|0),P=e+188|0,T=e+252|0,A=z+1|0,E=z+2|0,x=z+3|0,w=0,o=0,r=0,n=1;do{if(!G)for(C=0|jt[t+(w<<2)>>2],S=0;;){if(v=1&S,u=0==(0|v),_=(v<<5^32)-16|0,v=(v<<1^2)-1|0,g=u?a:-1,l=u?0:H,e=(0|S)==(0|j),y=I&e,(0|l)!=(0|g))for(m=I&e^1,f=u?C:C+W|0;;){1==(0|n)&&(n=512|b(M,R)),p=7&n,n>>>=3,u=0|Yt[1539+p>>0],e=0;do{c=(0|b(M,N))+r|0,d=c-F|0,h=d>>31,r=h&c|d&~h,(0|jt[k>>2])>>>0<=r>>>0&&(jt[X>>2]=866,jt[X+4>>2]=910,jt[X+8>>2]=1497,Ve(q,812,X),he(q)),jt[Y+(e<<2)>>2]=jt[(0|jt[L>>2])+(r<<2)>>2],e=e+1|0}while(e>>>0<u>>>0);if(h=D&(0|l)==(0|H),y|h){d=0;do{e=f+(0|dr(d,i))|0,c=0==(0|d)|m,u=d<<1,ne=(0|b(M,P))+o|0,ie=ne-U|0,o=ie>>31,o=o&ne|ie&~o;do{if(h){if(!c){ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o;break}jt[e>>2]=jt[Y+((0|Yt[1547+(p<<2)+u>>0])<<2)>>2],(0|jt[B>>2])>>>0<=o>>>0&&(jt[J>>2]=866,jt[J+4>>2]=910,jt[J+8>>2]=1497,Ve(q,812,J),he(q)),jt[e+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o}else c&&(jt[e>>2]=jt[Y+((0|Yt[1547+(p<<2)+u>>0])<<2)>>2],(0|jt[B>>2])>>>0<=o>>>0&&(jt[K>>2]=866,jt[K+4>>2]=910,jt[K+8>>2]=1497,Ve(q,812,K),he(q)),jt[e+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2]),e=e+8|0,ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,c&&(jt[e>>2]=jt[Y+((0|Yt[1547+(p<<2)+(1|u)>>0])<<2)>>2],(0|jt[B>>2])>>>0<=o>>>0&&(jt[ee>>2]=866,jt[ee+4>>2]=910,jt[ee+8>>2]=1497,Ve(q,812,ee),he(q)),jt[e+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2])}while(0);d=d+1|0}while(2!=(0|d))}else jt[f>>2]=jt[Y+((0|Yt[1547+(p<<2)>>0])<<2)>>2],ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[$>>2]=866,jt[$+4>>2]=910,jt[$+8>>2]=1497,Ve(q,812,$),he(q)),jt[f+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],jt[f+8>>2]=jt[Y+((0|Yt[1547+(p<<2)+1>>0])<<2)>>2],ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[te>>2]=866,jt[te+4>>2]=910,jt[te+8>>2]=1497,Ve(q,812,te),he(q)),jt[f+12>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],jt[f+(z<<2)>>2]=jt[Y+((0|Yt[1547+(p<<2)+2>>0])<<2)>>2],ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[Q>>2]=866,jt[Q+4>>2]=910,jt[Q+8>>2]=1497,Ve(q,812,Q),he(q)),jt[f+(A<<2)>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],jt[f+(E<<2)>>2]=jt[Y+((0|Yt[1547+(p<<2)+3>>0])<<2)>>2],ie=(0|b(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[Z>>2]=866,jt[Z+4>>2]=910,jt[Z+8>>2]=1497,Ve(q,812,Z),he(q)),jt[f+(x<<2)>>2]=jt[(0|jt[T>>2])+(o<<2)>>2];if((0|(l=v+l|0))==(0|g))break;f=f+_|0}if((0|(S=S+1|0))==(0|s))break;C=C+O|0}w=w+1|0}while((0|w)!=(0|V));return or=re,1}function c(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,A=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,N=0,L=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,H=0,W=0,j=0,q=0,Y=0,X=0,Q=0,Z=0,K=0,J=0,$=0,ee=0,te=0,re=0,ie=0,ne=0,oe=0,ae=0;if(ae=or,or=or+640|0,ie=ae+80|0,re=ae+64|0,te=ae+48|0,oe=ae+32|0,ne=ae+16|0,ee=ae,J=ae+128|0,$=ae+112|0,F=ae+96|0,B=e+272|0,U=0|jt[B>>2],K=0|jt[e+88>>2],V=(0|Yt[K+63>>0])<<8|0|Yt[K+64>>0],K=0|zt[K+17>>0],z=255&K,!(K<<24>>24))return or=ae,1;G=0==(0|s),H=a+-1|0,W=H<<5,j=s+-1|0,q=i<<1,Y=e+92|0,X=e+116|0,Q=e+164|0,Z=e+268|0,K=e+212|0,k=0==(1&n|0),L=0==(1&o|0),N=e+288|0,R=e+284|0,M=0,e=0,o=0,n=0,r=0,l=1;do{if(!G)for(I=0|jt[t+(M<<2)>>2],O=0;;){if(D=1&O,c=0==(0|D),P=(D<<6^64)-32|0,D=(D<<1^2)-1|0,E=c?a:-1,(0|(u=c?0:H))!=(0|E))for(x=L|(0|O)!=(0|j),A=c?I:I+W|0;;){1==(0|l)&&(l=512|b(Y,X)),T=7&l,l>>>=3,d=0|Yt[1539+T>>0],c=0;do{C=(0|b(Y,Q))+r|0,S=C-U|0,w=S>>31,r=w&C|S&~w,(0|jt[B>>2])>>>0<=r>>>0&&(jt[ee>>2]=866,jt[ee+4>>2]=910,jt[ee+8>>2]=1497,Ve(J,812,ee),he(J)),jt[$+(c<<2)>>2]=Qt[(0|jt[Z>>2])+(r<<1)>>1],c=c+1|0}while(c>>>0<d>>>0);c=0;do{C=(0|b(Y,Q))+o|0,S=C-U|0,w=S>>31,o=w&C|S&~w,(0|jt[B>>2])>>>0<=o>>>0&&(jt[ne>>2]=866,jt[ne+4>>2]=910,jt[ne+8>>2]=1497,Ve(J,812,ne),he(J)),jt[F+(c<<2)>>2]=Qt[(0|jt[Z>>2])+(o<<1)>>1],c=c+1|0}while(c>>>0<d>>>0);for(w=k|(0|u)!=(0|H),C=0,S=A;;){if(_=x|0==(0|C),v=C<<1,w)for(m=0,g=S;;){if(y=(0|b(Y,K))+n|0,f=y-V|0,n=f>>31,n=n&y|f&~n,f=(0|b(Y,K))+e|0,y=f-V|0,e=y>>31,e=e&f|y&~e,_&&(f=0|Yt[m+v+(1547+(T<<2))>>0],d=3*n|0,c=0|jt[N>>2],c>>>0<=d>>>0&&(jt[oe>>2]=866,jt[oe+4>>2]=910,jt[oe+8>>2]=1497,Ve(J,812,oe),he(J),c=0|jt[N>>2]),h=0|jt[R>>2],d=h+(d<<1)|0,p=3*e|0,c>>>0>p>>>0?c=h:(jt[te>>2]=866,jt[te+4>>2]=910,jt[te+8>>2]=1497,Ve(J,812,te),he(J),c=0|jt[R>>2]),y=c+(p<<1)|0,jt[g>>2]=(0|Qt[d>>1])<<16|jt[$+(f<<2)>>2],jt[g+4>>2]=(0|Qt[d+4>>1])<<16|0|Qt[d+2>>1],jt[g+8>>2]=(0|Qt[y>>1])<<16|jt[F+(f<<2)>>2],jt[g+12>>2]=(0|Qt[y+4>>1])<<16|0|Qt[y+2>>1]),2==(0|(m=m+1|0)))break;g=g+16|0}else for(y=1^_,_=1547+(T<<2)+v|0,m=0,g=S;;){if(v=(0|b(Y,K))+n|0,f=v-V|0,n=f>>31,n=n&v|f&~n,f=(0|b(Y,K))+e|0,v=f-V|0,e=v>>31,e=e&f|v&~e,0!=(0|m)|y||(f=0|Yt[_>>0],d=3*n|0,c=0|jt[N>>2],c>>>0<=d>>>0&&(jt[re>>2]=866,jt[re+4>>2]=910,jt[re+8>>2]=1497,Ve(J,812,re),he(J),c=0|jt[N>>2]),h=0|jt[R>>2],d=h+(d<<1)|0,p=3*e|0,c>>>0>p>>>0?c=h:(jt[ie>>2]=866,jt[ie+4>>2]=910,jt[ie+8>>2]=1497,Ve(J,812,ie),he(J),c=0|jt[R>>2]),v=c+(p<<1)|0,jt[g>>2]=(0|Qt[d>>1])<<16|jt[$+(f<<2)>>2],jt[g+4>>2]=(0|Qt[d+4>>1])<<16|0|Qt[d+2>>1],jt[g+8>>2]=(0|Qt[v>>1])<<16|jt[F+(f<<2)>>2],jt[g+12>>2]=(0|Qt[v+4>>1])<<16|0|Qt[v+2>>1]),2==(0|(m=m+1|0)))break;g=g+16|0}if(2==(0|(C=C+1|0)))break;S=S+i|0}if((0|(u=D+u|0))==(0|E))break;A=A+P|0}if((0|(O=O+1|0))==(0|s))break;I=I+q|0}M=M+1|0}while((0|M)!=(0|z));return or=ae,1}function d(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0;if(e){r=e+-8|0,n=0|jt[1148],e=0|jt[e+-4>>2],t=-8&e,l=r+t|0;do{if(1&e)s=r,a=r;else{if(i=0|jt[r>>2],!(3&e))return;if(a=r+(0-i)|0,o=i+t|0,a>>>0<n>>>0)return;if((0|a)==(0|jt[1149])){if(e=l+4|0,3!=(3&(t=0|jt[e>>2])|0)){s=a,t=o;break}return jt[1146]=o,jt[e>>2]=-2&t,jt[a+4>>2]=1|o,void(jt[a+o>>2]=o)}if(r=i>>>3,i>>>0<256){if(e=0|jt[a+8>>2],(0|(t=0|jt[a+12>>2]))==(0|e)){jt[1144]=jt[1144]&~(1<<r),s=a,t=o;break}jt[e+12>>2]=t,jt[t+8>>2]=e,s=a,t=o;break}n=0|jt[a+24>>2],e=0|jt[a+12>>2];do{if((0|e)==(0|a)){if(r=a+16|0,t=r+4|0,!(e=0|jt[t>>2])){if(!(e=0|jt[r>>2])){e=0;break}t=r}for(;;)if(r=e+20|0,0|(i=0|jt[r>>2]))e=i,t=r;else{if(r=e+16|0,!(i=0|jt[r>>2]))break;e=i,t=r}jt[t>>2]=0}else s=0|jt[a+8>>2],jt[s+12>>2]=e,jt[e+8>>2]=s}while(0);if(n){if(t=0|jt[a+28>>2],r=4880+(t<<2)|0,(0|a)==(0|jt[r>>2])){if(jt[r>>2]=e,!e){jt[1145]=jt[1145]&~(1<<t),s=a,t=o;break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|a)&1)<<2)>>2]=e,!e){s=a,t=o;break}jt[e+24>>2]=n,t=a+16|0,r=0|jt[t>>2],0|r&&(jt[e+16>>2]=r,jt[r+24>>2]=e),t=0|jt[t+4>>2],t?(jt[e+20>>2]=t,jt[t+24>>2]=e,s=a,t=o):(s=a,t=o)}else s=a,t=o}}while(0);if(!(a>>>0>=l>>>0)&&(e=l+4|0,1&(i=0|jt[e>>2]))){if(2&i)jt[e>>2]=-2&i,jt[s+4>>2]=1|t,jt[a+t>>2]=t,n=t;else{if(e=0|jt[1149],(0|l)==(0|jt[1150])){if(l=(0|jt[1147])+t|0,jt[1147]=l,jt[1150]=s,jt[s+4>>2]=1|l,(0|s)!=(0|e))return;return jt[1149]=0,void(jt[1146]=0)}if((0|l)==(0|e))return l=(0|jt[1146])+t|0,jt[1146]=l,jt[1149]=a,jt[s+4>>2]=1|l,void(jt[a+l>>2]=l);n=(-8&i)+t|0,r=i>>>3;do{if(i>>>0<256){if(t=0|jt[l+8>>2],(0|(e=0|jt[l+12>>2]))==(0|t)){jt[1144]=jt[1144]&~(1<<r);break}jt[t+12>>2]=e,jt[e+8>>2]=t;break}o=0|jt[l+24>>2],e=0|jt[l+12>>2];do{if((0|e)==(0|l)){if(r=l+16|0,t=r+4|0,!(e=0|jt[t>>2])){if(!(e=0|jt[r>>2])){r=0;break}t=r}for(;;)if(r=e+20|0,0|(i=0|jt[r>>2]))e=i,t=r;else{if(r=e+16|0,!(i=0|jt[r>>2]))break;e=i,t=r}jt[t>>2]=0,r=e}else r=0|jt[l+8>>2],jt[r+12>>2]=e,jt[e+8>>2]=r,r=e}while(0);if(0|o){if(e=0|jt[l+28>>2],t=4880+(e<<2)|0,(0|l)==(0|jt[t>>2])){if(jt[t>>2]=r,!r){jt[1145]=jt[1145]&~(1<<e);break}}else if(jt[o+16+(((0|jt[o+16>>2])!=(0|l)&1)<<2)>>2]=r,!r)break;jt[r+24>>2]=o,e=l+16|0,t=0|jt[e>>2],0|t&&(jt[r+16>>2]=t,jt[t+24>>2]=r),e=0|jt[e+4>>2],0|e&&(jt[r+20>>2]=e,jt[e+24>>2]=r)}}while(0);if(jt[s+4>>2]=1|n,jt[a+n>>2]=n,(0|s)==(0|jt[1149]))return void(jt[1146]=n)}if(e=n>>>3,n>>>0<256)return r=4616+(e<<1<<2)|0,t=0|jt[1144],e=1<<e,t&e?(t=r+8|0,e=0|jt[t>>2]):(jt[1144]=t|e,e=r,t=r+8|0),jt[t>>2]=s,jt[e+12>>2]=s,jt[s+8>>2]=e,void(jt[s+12>>2]=r);e=n>>>8,e?n>>>0>16777215?e=31:(a=(e+1048320|0)>>>16&8,l=e<<a,o=(l+520192|0)>>>16&4,l<<=o,e=(l+245760|0)>>>16&2,e=14-(o|a|e)+(l<<e>>>15)|0,e=n>>>(e+7|0)&1|e<<1):e=0,i=4880+(e<<2)|0,jt[s+28>>2]=e,jt[s+20>>2]=0,jt[s+16>>2]=0,t=0|jt[1145],r=1<<e;do{if(t&r){for(t=n<<(31==(0|e)?0:25-(e>>>1)|0),r=0|jt[i>>2];;){if((-8&jt[r+4>>2]|0)==(0|n)){e=73;break}if(i=r+16+(t>>>31<<2)|0,!(e=0|jt[i>>2])){e=72;break}t<<=1,r=e}if(72==(0|e)){jt[i>>2]=s,jt[s+24>>2]=r,jt[s+12>>2]=s,jt[s+8>>2]=s;break}if(73==(0|e)){a=r+8|0,l=0|jt[a>>2],jt[l+12>>2]=s,jt[a>>2]=s,jt[s+8>>2]=l,jt[s+12>>2]=r,jt[s+24>>2]=0;break}}else jt[1145]=t|r,jt[i>>2]=s,jt[s+24>>2]=i,jt[s+12>>2]=s,jt[s+8>>2]=s}while(0);if(l=(0|jt[1152])-1|0,jt[1152]=l,!l){for(e=5032;;){if(!(e=0|jt[e>>2]))break;e=e+8|0}jt[1152]=-1}}}}function h(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,A=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,N=0,L=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,H=0,W=0,j=0,q=0,Y=0,X=0,Q=0,Z=0,K=0,J=0,$=0,ee=0,te=0,re=0,ie=0,ne=0,oe=0,ae=0,se=0,le=0,ue=0,ce=0,de=0;if(de=or,or=or+640|0,le=de+80|0,se=de+64|0,ae=de+48|0,ce=de+32|0,ue=de+16|0,oe=de,ie=de+128|0,ne=de+112|0,L=de+96|0,k=e+240|0,F=0|jt[k>>2],B=e+256|0,U=0|jt[B>>2],V=e+272|0,z=0|jt[V>>2],re=0|jt[e+88>>2],G=(0|Yt[re+63>>0])<<8|0|Yt[re+64>>0],re=0|zt[re+17>>0],H=255&re,!(re<<24>>24))return or=de,1;W=0==(0|s),j=a+-1|0,q=j<<5,Y=s+-1|0,X=i<<1,Q=e+92|0,Z=e+116|0,K=e+164|0,J=e+268|0,$=e+140|0,ee=e+236|0,te=e+212|0,re=e+188|0,N=0==(1&n|0),R=0==(1&o|0),O=e+288|0,M=e+284|0,I=e+252|0,D=0,e=0,o=0,n=0,r=0,l=1;do{if(!W)for(x=0|jt[t+(D<<2)>>2],P=0;;){if(E=1&P,c=0==(0|E),A=(E<<6^64)-32|0,E=(E<<1^2)-1|0,w=c?a:-1,(0|(u=c?0:j))!=(0|w))for(T=R|(0|P)!=(0|Y),S=c?x:x+q|0;;){1==(0|l)&&(l=512|b(Q,Z)),C=7&l,l>>>=3,d=0|Yt[1539+C>>0],c=0;do{_=(0|b(Q,K))+o|0,v=_-z|0,y=v>>31,o=y&_|v&~y,(0|jt[V>>2])>>>0<=o>>>0&&(jt[oe>>2]=866,jt[oe+4>>2]=910,jt[oe+8>>2]=1497,Ve(ie,812,oe),he(ie)),jt[L+(c<<2)>>2]=Qt[(0|jt[J>>2])+(o<<1)>>1],c=c+1|0}while(c>>>0<d>>>0);c=0;do{_=(0|b(Q,$))+r|0,v=_-F|0,y=v>>31,r=y&_|v&~y,(0|jt[k>>2])>>>0<=r>>>0&&(jt[ue>>2]=866,jt[ue+4>>2]=910,jt[ue+8>>2]=1497,Ve(ie,812,ue),he(ie)),jt[ne+(c<<2)>>2]=jt[(0|jt[ee>>2])+(r<<2)>>2],c=c+1|0}while(c>>>0<d>>>0);for(y=N|(0|u)!=(0|j),_=0,v=S;;){if(f=T|0==(0|_),m=_<<1,y)for(h=0,p=v;;){if(g=(0|b(Q,te))+e|0,d=g-G|0,e=d>>31,e=e&g|d&~e,d=(0|b(Q,re))+n|0,g=d-U|0,n=g>>31,n=n&d|g&~n,f&&(c=0|Yt[h+m+(1547+(C<<2))>>0],d=3*e|0,(0|jt[O>>2])>>>0<=d>>>0&&(jt[ce>>2]=866,jt[ce+4>>2]=910,jt[ce+8>>2]=1497,Ve(ie,812,ce),he(ie)),g=(0|jt[M>>2])+(d<<1)|0,jt[p>>2]=(0|Qt[g>>1])<<16|jt[L+(c<<2)>>2],jt[p+4>>2]=(0|Qt[g+4>>1])<<16|0|Qt[g+2>>1],jt[p+8>>2]=jt[ne+(c<<2)>>2],(0|jt[B>>2])>>>0<=n>>>0&&(jt[ae>>2]=866,jt[ae+4>>2]=910,jt[ae+8>>2]=1497,Ve(ie,812,ae),he(ie)),jt[p+12>>2]=jt[(0|jt[I>>2])+(n<<2)>>2]),2==(0|(h=h+1|0)))break;p=p+16|0}else for(g=1^f,f=1547+(C<<2)+m|0,h=0,p=v;;){if(m=(0|b(Q,te))+e|0,d=m-G|0,e=d>>31,e=e&m|d&~e,d=(0|b(Q,re))+n|0,m=d-U|0,n=m>>31,n=n&d|m&~n,0!=(0|h)|g||(c=0|Yt[f>>0],d=3*e|0,(0|jt[O>>2])>>>0<=d>>>0&&(jt[se>>2]=866,jt[se+4>>2]=910,jt[se+8>>2]=1497,Ve(ie,812,se),he(ie)),m=(0|jt[M>>2])+(d<<1)|0,jt[p>>2]=(0|Qt[m>>1])<<16|jt[L+(c<<2)>>2],jt[p+4>>2]=(0|Qt[m+4>>1])<<16|0|Qt[m+2>>1],jt[p+8>>2]=jt[ne+(c<<2)>>2],(0|jt[B>>2])>>>0<=n>>>0&&(jt[le>>2]=866,jt[le+4>>2]=910,jt[le+8>>2]=1497,Ve(ie,812,le),he(ie)),jt[p+12>>2]=jt[(0|jt[I>>2])+(n<<2)>>2]),2==(0|(h=h+1|0)))break;p=p+16|0}if(2==(0|(_=_+1|0)))break;v=v+i|0}if((0|(u=E+u|0))==(0|w))break;S=S+A|0}if((0|(P=P+1|0))==(0|s))break;x=x+X|0}D=D+1|0}while((0|D)!=(0|H));return or=de,1}function p(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;l=e+t|0,r=0|jt[e+4>>2];do{if(1&r)s=e,r=t;else{if(i=0|jt[e>>2],!(3&r))return;if(o=e+(0-i)|0,a=i+t|0,(0|o)==(0|jt[1149])){if(e=l+4|0,3!=(3&(r=0|jt[e>>2])|0)){s=o,r=a;break}return jt[1146]=a,jt[e>>2]=-2&r,jt[o+4>>2]=1|a,void(jt[o+a>>2]=a)}if(t=i>>>3,i>>>0<256){if(e=0|jt[o+8>>2],(0|(r=0|jt[o+12>>2]))==(0|e)){jt[1144]=jt[1144]&~(1<<t),s=o,r=a;break}jt[e+12>>2]=r,jt[r+8>>2]=e,s=o,r=a;break}n=0|jt[o+24>>2],e=0|jt[o+12>>2];do{if((0|e)==(0|o)){if(t=o+16|0,r=t+4|0,!(e=0|jt[r>>2])){if(!(e=0|jt[t>>2])){e=0;break}r=t}for(;;)if(t=e+20|0,0|(i=0|jt[t>>2]))e=i,r=t;else{if(t=e+16|0,!(i=0|jt[t>>2]))break;e=i,r=t}jt[r>>2]=0}else s=0|jt[o+8>>2],jt[s+12>>2]=e,jt[e+8>>2]=s}while(0);if(n){if(r=0|jt[o+28>>2],t=4880+(r<<2)|0,(0|o)==(0|jt[t>>2])){if(jt[t>>2]=e,!e){jt[1145]=jt[1145]&~(1<<r),s=o,r=a;break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|o)&1)<<2)>>2]=e,!e){s=o,r=a;break}jt[e+24>>2]=n,r=o+16|0,t=0|jt[r>>2],0|t&&(jt[e+16>>2]=t,jt[t+24>>2]=e),r=0|jt[r+4>>2],r?(jt[e+20>>2]=r,jt[r+24>>2]=e,s=o,r=a):(s=o,r=a)}else s=o,r=a}}while(0);if(e=l+4|0,2&(i=0|jt[e>>2]))jt[e>>2]=-2&i,jt[s+4>>2]=1|r,jt[s+r>>2]=r;else{if(e=0|jt[1149],(0|l)==(0|jt[1150])){if(l=(0|jt[1147])+r|0,jt[1147]=l,jt[1150]=s,jt[s+4>>2]=1|l,(0|s)!=(0|e))return;return jt[1149]=0,void(jt[1146]=0)}if((0|l)==(0|e))return l=(0|jt[1146])+r|0,jt[1146]=l,jt[1149]=s,jt[s+4>>2]=1|l,void(jt[s+l>>2]=l);o=(-8&i)+r|0,t=i>>>3;do{if(i>>>0<256){if(r=0|jt[l+8>>2],(0|(e=0|jt[l+12>>2]))==(0|r)){jt[1144]=jt[1144]&~(1<<t);break}jt[r+12>>2]=e,jt[e+8>>2]=r;break}n=0|jt[l+24>>2],e=0|jt[l+12>>2];do{if((0|e)==(0|l)){if(t=l+16|0,r=t+4|0,!(e=0|jt[r>>2])){if(!(e=0|jt[t>>2])){t=0;break}r=t}for(;;)if(t=e+20|0,0|(i=0|jt[t>>2]))e=i,r=t;else{if(t=e+16|0,!(i=0|jt[t>>2]))break;e=i,r=t}jt[r>>2]=0,t=e}else t=0|jt[l+8>>2],jt[t+12>>2]=e,jt[e+8>>2]=t,t=e}while(0);if(0|n){if(e=0|jt[l+28>>2],r=4880+(e<<2)|0,(0|l)==(0|jt[r>>2])){if(jt[r>>2]=t,!t){jt[1145]=jt[1145]&~(1<<e);break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|l)&1)<<2)>>2]=t,!t)break;jt[t+24>>2]=n,e=l+16|0,r=0|jt[e>>2],0|r&&(jt[t+16>>2]=r,jt[r+24>>2]=t),e=0|jt[e+4>>2],0|e&&(jt[t+20>>2]=e,jt[e+24>>2]=t)}}while(0);if(jt[s+4>>2]=1|o,jt[s+o>>2]=o,(0|s)==(0|jt[1149]))return void(jt[1146]=o);r=o}if(e=r>>>3,r>>>0<256)return t=4616+(e<<1<<2)|0,r=0|jt[1144],e=1<<e,r&e?(r=t+8|0,e=0|jt[r>>2]):(jt[1144]=r|e,e=t,r=t+8|0),jt[r>>2]=s,jt[e+12>>2]=s,jt[s+8>>2]=e,void(jt[s+12>>2]=t);if(e=r>>>8,e?r>>>0>16777215?e=31:(a=(e+1048320|0)>>>16&8,l=e<<a,o=(l+520192|0)>>>16&4,l<<=o,e=(l+245760|0)>>>16&2,e=14-(o|a|e)+(l<<e>>>15)|0,e=r>>>(e+7|0)&1|e<<1):e=0,n=4880+(e<<2)|0,jt[s+28>>2]=e,jt[s+20>>2]=0,jt[s+16>>2]=0,t=0|jt[1145],i=1<<e,!(t&i))return jt[1145]=t|i,jt[n>>2]=s,jt[s+24>>2]=n,jt[s+12>>2]=s,void(jt[s+8>>2]=s);for(t=r<<(31==(0|e)?0:25-(e>>>1)|0),i=0|jt[n>>2];;){if((-8&jt[i+4>>2]|0)==(0|r)){e=69;break}if(n=i+16+(t>>>31<<2)|0,!(e=0|jt[n>>2])){e=68;break}t<<=1,i=e}return 68==(0|e)?(jt[n>>2]=s,jt[s+24>>2]=i,jt[s+12>>2]=s,void(jt[s+8>>2]=s)):69==(0|e)?(a=i+8|0,l=0|jt[a>>2],jt[l+12>>2]=s,jt[a>>2]=s,jt[s+8>>2]=l,jt[s+12>>2]=i,void(jt[s+24>>2]=0)):void 0}function f(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,N=0,L=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,H=0,W=0;if(G=or,or=or+2416|0,a=G,o=G+1904|0,z=G+1880|0,B=G+980|0,U=G+80|0,V=G+16|0,r=0|jt[e+88>>2],k=(0|Yt[r+63>>0])<<8|0|Yt[r+64>>0],F=e+92|0,t=(0|jt[e+4>>2])+((0|Yt[r+58>>0])<<8|(0|Yt[r+57>>0])<<16|0|Yt[r+59>>0])|0,!(r=(0|Yt[r+61>>0])<<8|(0|Yt[r+60>>0])<<16|0|Yt[r+62>>0]))return z=0,or=G,0|z;if(jt[F>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,jt[z+20>>2]=0,jt[z>>2]=0,jt[z+4>>2]=0,jt[z+8>>2]=0,jt[z+12>>2]=0,zt[z+16>>0]=0,0|s(F,z)){for(t=0,r=-7,i=-7;;){if(jt[B+(t<<2)>>2]=i,jt[U+(t<<2)>>2]=r,n=(0|i)>6,225==(0|(t=t+1|0)))break;r=(1&n)+r|0,i=n?-7:i+1|0}t=V,r=t+64|0;do{jt[t>>2]=0,t=t+4|0}while((0|t)<(0|r));n=e+284|0,r=3*k|0,i=e+288|0,t=0|jt[i>>2];e:do{if((0|t)==(0|r))l=13;else{if(t>>>0<=r>>>0){do{if((0|jt[e+292>>2])>>>0<r>>>0){if(0|A(n,r,(t+1|0)==(0|r),2,0)){t=0|jt[i>>2];break}zt[e+296>>0]=1,t=0;break e}}while(0);ee((0|jt[n>>2])+(t<<1)|0,0,r-t<<1|0)}jt[i>>2]=r,l=13}}while(0);do{if(13==(0|l)){if(!k){jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(o,812,a),he(o),t=1;break}for(y=V+4|0,C=V+8|0,S=V+12|0,w=V+16|0,T=V+20|0,E=V+24|0,x=V+28|0,P=V+32|0,D=V+36|0,I=V+40|0,O=V+44|0,M=V+48|0,R=V+52|0,N=V+56|0,L=V+60|0,v=0,t=0|jt[n>>2],r=0|jt[V>>2], -i=0|jt[y>>2],n=0|jt[C>>2],e=0|jt[S>>2],o=0|jt[w>>2],a=0|jt[T>>2],l=0|jt[E>>2],u=0|jt[x>>2],c=0|jt[P>>2],d=0|jt[D>>2],h=0|jt[I>>2],p=0|jt[O>>2],f=0,m=0,g=0,_=0;;){if(W=0|b(F,z),r=r+(0|jt[B+(W<<2)>>2])&7,i=i+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),n=n+(0|jt[B+(W<<2)>>2])&7,e=e+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),o=o+(0|jt[B+(W<<2)>>2])&7,a=a+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),l=l+(0|jt[B+(W<<2)>>2])&7,u=u+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),c=c+(0|jt[B+(W<<2)>>2])&7,d=d+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),h=h+(0|jt[B+(W<<2)>>2])&7,p=p+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),f=f+(0|jt[B+(W<<2)>>2])&7,m=m+(0|jt[U+(W<<2)>>2])&7,W=0|b(F,z),g=g+(0|jt[B+(W<<2)>>2])&7,_=_+(0|jt[U+(W<<2)>>2])&7,W=0|Yt[1445+a>>0],Ht[t>>1]=(0|Yt[1445+i>>0])<<3|0|Yt[1445+r>>0]|(0|Yt[1445+n>>0])<<6|(0|Yt[1445+e>>0])<<9|(0|Yt[1445+o>>0])<<12|W<<15,H=0|Yt[1445+h>>0],Ht[t+2>>1]=(0|Yt[1445+l>>0])<<2|W>>>1|(0|Yt[1445+u>>0])<<5|(0|Yt[1445+c>>0])<<8|(0|Yt[1445+d>>0])<<11|H<<14,Ht[t+4>>1]=(0|Yt[1445+p>>0])<<1|H>>>2|(0|Yt[1445+f>>0])<<4|(0|Yt[1445+m>>0])<<7|(0|Yt[1445+g>>0])<<10|(0|Yt[1445+_>>0])<<13,(v=v+1|0)>>>0>=k>>>0)break;t=t+6|0}jt[V>>2]=r,jt[y>>2]=i,jt[C>>2]=n,jt[S>>2]=e,jt[w>>2]=o,jt[T>>2]=a,jt[E>>2]=l,jt[x>>2]=u,jt[P>>2]=c,jt[D>>2]=d,jt[I>>2]=h,jt[O>>2]=p,jt[M>>2]=f,jt[R>>2]=m,jt[N>>2]=g,jt[L>>2]=_,t=1}}while(0)}else t=0;return X(z),W=t,or=G,0|W}function m(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,N=0,L=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0;if(P=or,or=or+1008|0,a=P,o=P+496|0,x=P+472|0,w=P+276|0,T=P+80|0,E=P+16|0,r=0|jt[e+88>>2],C=(0|Yt[r+47>>0])<<8|0|Yt[r+48>>0],S=e+92|0,t=(0|jt[e+4>>2])+((0|Yt[r+42>>0])<<8|(0|Yt[r+41>>0])<<16|0|Yt[r+43>>0])|0,!(r=(0|Yt[r+45>>0])<<8|(0|Yt[r+44>>0])<<16|0|Yt[r+46>>0]))return x=0,or=P,0|x;if(jt[S>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,jt[x+20>>2]=0,jt[x>>2]=0,jt[x+4>>2]=0,jt[x+8>>2]=0,jt[x+12>>2]=0,zt[x+16>>0]=0,0|s(S,x)){for(t=0,r=-3,i=-3;;){if(jt[w+(t<<2)>>2]=i,jt[T+(t<<2)>>2]=r,n=(0|i)>2,49==(0|(t=t+1|0)))break;r=(1&n)+r|0,i=n?-3:i+1|0}t=E,r=t+64|0;do{jt[t>>2]=0,t=t+4|0}while((0|t)<(0|r));i=e+252|0,r=e+256|0,t=0|jt[r>>2];e:do{if((0|t)==(0|C))l=13;else{if(t>>>0<=C>>>0){do{if((0|jt[e+260>>2])>>>0<C>>>0){if(0|A(i,C,(t+1|0)==(0|C),4,0)){t=0|jt[r>>2];break}zt[e+264>>0]=1,t=0;break e}}while(0);ee((0|jt[i>>2])+(t<<2)|0,0,C-t<<2|0)}jt[r>>2]=C,l=13}}while(0);do{if(13==(0|l)){if(!C){jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(o,812,a),he(o),t=1;break}for(e=E+4|0,o=E+8|0,a=E+12|0,l=E+16|0,u=E+20|0,c=E+24|0,d=E+28|0,h=E+32|0,p=E+36|0,f=E+40|0,m=E+44|0,g=E+48|0,_=E+52|0,v=E+56|0,y=E+60|0,n=0,t=0|jt[i>>2],r=0|jt[e>>2],i=0|jt[E>>2];;){if(z=0|b(S,x),i=i+(0|jt[w+(z<<2)>>2])&3,r=r+(0|jt[T+(z<<2)>>2])&3,z=0|b(S,x),G=(0|jt[o>>2])+(0|jt[w+(z<<2)>>2])&3,jt[o>>2]=G,z=(0|jt[a>>2])+(0|jt[T+(z<<2)>>2])&3,jt[a>>2]=z,U=0|b(S,x),V=(0|jt[l>>2])+(0|jt[w+(U<<2)>>2])&3,jt[l>>2]=V,U=(0|jt[u>>2])+(0|jt[T+(U<<2)>>2])&3,jt[u>>2]=U,F=0|b(S,x),B=(0|jt[c>>2])+(0|jt[w+(F<<2)>>2])&3,jt[c>>2]=B,F=(0|jt[d>>2])+(0|jt[T+(F<<2)>>2])&3,jt[d>>2]=F,L=0|b(S,x),k=(0|jt[h>>2])+(0|jt[w+(L<<2)>>2])&3,jt[h>>2]=k,L=(0|jt[p>>2])+(0|jt[T+(L<<2)>>2])&3,jt[p>>2]=L,R=0|b(S,x),N=(0|jt[f>>2])+(0|jt[w+(R<<2)>>2])&3,jt[f>>2]=N,R=(0|jt[m>>2])+(0|jt[T+(R<<2)>>2])&3,jt[m>>2]=R,O=0|b(S,x),M=(0|jt[g>>2])+(0|jt[w+(O<<2)>>2])&3,jt[g>>2]=M,O=(0|jt[_>>2])+(0|jt[T+(O<<2)>>2])&3,jt[_>>2]=O,D=0|b(S,x),I=(0|jt[v>>2])+(0|jt[w+(D<<2)>>2])&3,jt[v>>2]=I,D=(0|jt[y>>2])+(0|jt[T+(D<<2)>>2])&3,jt[y>>2]=D,jt[t>>2]=(0|Yt[1441+r>>0])<<2|0|Yt[1441+i>>0]|(0|Yt[1441+G>>0])<<4|(0|Yt[1441+z>>0])<<6|(0|Yt[1441+V>>0])<<8|(0|Yt[1441+U>>0])<<10|(0|Yt[1441+B>>0])<<12|(0|Yt[1441+F>>0])<<14|(0|Yt[1441+k>>0])<<16|(0|Yt[1441+L>>0])<<18|(0|Yt[1441+N>>0])<<20|(0|Yt[1441+R>>0])<<22|(0|Yt[1441+M>>0])<<24|(0|Yt[1441+O>>0])<<26|(0|Yt[1441+I>>0])<<28|(0|Yt[1441+D>>0])<<30,(n=n+1|0)>>>0>=C>>>0)break;t=t+4|0}jt[E>>2]=i,jt[e>>2]=r,t=1}}while(0)}else t=0;return X(x),G=t,or=P,0|G}function g(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,C=0,S=0,w=0,T=0,A=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,N=0,L=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,H=0,W=0,j=0,q=0,Y=0,X=0,Q=0,Z=0;if(Z=or,or=or+592|0,Y=Z+48|0,Q=Z+32|0,X=Z+16|0,q=Z,W=Z+80|0,j=Z+64|0,I=e+272|0,O=0|jt[I>>2],H=0|jt[e+88>>2],M=(0|Yt[H+63>>0])<<8|0|Yt[H+64>>0],H=0|zt[H+17>>0],R=255&H,!(H<<24>>24))return or=Z,1;N=0==(0|s),L=a+-1|0,k=L<<4,F=s+-1|0,B=i<<1,U=e+92|0,V=e+116|0,z=e+164|0,G=e+268|0,H=e+212|0,D=0==(1&n|0),P=0==(1&o|0),x=e+288|0,E=e+284|0,A=0,n=0,r=0,o=1;do{if(!N)for(w=0|jt[t+(A<<2)>>2],T=0;;){if(S=1&T,l=0==(0|S),C=(S<<5^32)-16|0,S=(S<<1^2)-1|0,v=l?a:-1,(0|(e=l?0:L))!=(0|v))for(y=P|(0|T)!=(0|F),_=l?w:w+k|0;;){1==(0|o)&&(o=512|b(U,V)),g=7&o,o>>>=3,u=0|Yt[1539+g>>0],l=0;do{p=(0|b(U,z))+r|0,f=p-O|0,m=f>>31,r=m&p|f&~m,(0|jt[I>>2])>>>0<=r>>>0&&(jt[q>>2]=866,jt[q+4>>2]=910,jt[q+8>>2]=1497,Ve(W,812,q),he(W)),jt[j+(l<<2)>>2]=Qt[(0|jt[G>>2])+(r<<1)>>1],l=l+1|0}while(l>>>0<u>>>0);for(m=D|(0|e)!=(0|L),p=0,f=_;;){if(h=y|0==(0|p),u=p<<1,l=(0|b(U,H))+n|0,c=l-M|0,d=c>>31,d=d&l|c&~d,m?(h&&(n=0|Yt[1547+(g<<2)+u>>0],l=3*d|0,(0|jt[x>>2])>>>0<=l>>>0&&(jt[X>>2]=866,jt[X+4>>2]=910,jt[X+8>>2]=1497,Ve(W,812,X),he(W)),c=(0|jt[E>>2])+(l<<1)|0,jt[f>>2]=(0|Qt[c>>1])<<16|jt[j+(n<<2)>>2],jt[f+4>>2]=(0|Qt[c+4>>1])<<16|0|Qt[c+2>>1]),c=f+8|0,l=(0|b(U,H))+d|0,d=l-M|0,n=d>>31,n=n&l|d&~n,h&&(l=0|Yt[1547+(g<<2)+(1|u)>>0],u=3*n|0,(0|jt[x>>2])>>>0<=u>>>0&&(jt[Y>>2]=866,jt[Y+4>>2]=910,jt[Y+8>>2]=1497,Ve(W,812,Y),he(W)),h=(0|jt[E>>2])+(u<<1)|0,jt[c>>2]=(0|Qt[h>>1])<<16|jt[j+(l<<2)>>2],jt[f+12>>2]=(0|Qt[h+4>>1])<<16|0|Qt[h+2>>1])):(h&&(n=0|Yt[1547+(g<<2)+u>>0],l=3*d|0,(0|jt[x>>2])>>>0<=l>>>0&&(jt[Q>>2]=866,jt[Q+4>>2]=910,jt[Q+8>>2]=1497,Ve(W,812,Q),he(W)),h=(0|jt[E>>2])+(l<<1)|0,jt[f>>2]=(0|Qt[h>>1])<<16|jt[j+(n<<2)>>2],jt[f+4>>2]=(0|Qt[h+4>>1])<<16|0|Qt[h+2>>1]),d=(0|b(U,H))+d|0,h=d-M|0,n=h>>31,n=n&d|h&~n),2==(0|(p=p+1|0)))break;f=f+i|0}if((0|(e=S+e|0))==(0|v))break;_=_+C|0}if((0|(T=T+1|0))==(0|s))break;w=w+B|0}A=A+1|0}while((0|A)!=(0|R));return or=Z,1}function _(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;if(c=e,l=t,u=l,a=r,h=i,s=h,!u)return o=0!=(0|n),s?o?(jt[n>>2]=0|e,jt[n+4>>2]=0&t,h=0,n=0,0|(cr=h,n)):(h=0,n=0,0|(cr=h,n)):(o&&(jt[n>>2]=(c>>>0)%(a>>>0),jt[n+4>>2]=0),h=0,n=(c>>>0)/(a>>>0)>>>0,0|(cr=h,n));o=0==(0|s);do{if(a){if(!o){if((o=(0|hr(0|s))-(0|hr(0|u))|0)>>>0<=31){d=o+1|0,s=31-o|0,t=o-31>>31,a=d,e=c>>>(d>>>0)&t|u<<s,t&=u>>>(d>>>0),o=0,s=c<<s;break}return n?(jt[n>>2]=0|e,jt[n+4>>2]=l|0&t,h=0,n=0,0|(cr=h,n)):(h=0,n=0,0|(cr=h,n))}if((o=a-1|0)&a|0){s=33+(0|hr(0|a))-(0|hr(0|u))|0,f=64-s|0,d=32-s|0,l=d>>31,p=s-32|0,t=p>>31,a=s,e=d-1>>31&u>>>(p>>>0)|(u<<d|c>>>(s>>>0))&t,t&=u>>>(s>>>0),o=c<<f&l,s=(u<<f|c>>>(p>>>0))&l|c<<d&s-33>>31;break}return 0|n&&(jt[n>>2]=o&c,jt[n+4>>2]=0),1==(0|a)?(p=l|0&t,f=0|e,0|(cr=p,f)):(f=0|xe(0|a),p=u>>>(f>>>0)|0,f=u<<32-f|c>>>(f>>>0)|0,0|(cr=p,f))}if(o)return 0|n&&(jt[n>>2]=(u>>>0)%(a>>>0),jt[n+4>>2]=0),p=0,f=(u>>>0)/(a>>>0)>>>0,0|(cr=p,f);if(!c)return 0|n&&(jt[n>>2]=0,jt[n+4>>2]=(u>>>0)%(s>>>0)),p=0,f=(u>>>0)/(s>>>0)>>>0,0|(cr=p,f);if(!((o=s-1|0)&s))return 0|n&&(jt[n>>2]=0|e,jt[n+4>>2]=o&u|0&t),p=0,f=u>>>((0|xe(0|s))>>>0),0|(cr=p,f);if((o=(0|hr(0|s))-(0|hr(0|u))|0)>>>0<=30){t=o+1|0,s=31-o|0,a=t,e=u<<s|c>>>(t>>>0),t=u>>>(t>>>0),o=0,s=c<<s;break}return n?(jt[n>>2]=0|e,jt[n+4>>2]=l|0&t,p=0,f=0,0|(cr=p,f)):(p=0,f=0,0|(cr=p,f))}while(0);if(a){d=0|r,c=h|0&i,u=0|Ke(0|d,0|c,-1,-1),r=cr,l=s,s=0;do{i=l,l=o>>>31|l<<1,o=s|o<<1,i=e<<1|i>>>31|0,h=e>>>31|t<<1|0,Ye(0|u,0|r,0|i,0|h),f=cr,p=f>>31|((0|f)<0?-1:0)<<1,s=1&p,e=0|Ye(0|i,0|h,p&d|0,(((0|f)<0?-1:0)>>31|((0|f)<0?-1:0)<<1)&c|0),t=cr,a=a-1|0}while(0!=(0|a));u=l,l=0}else u=s,l=0,s=0;return a=0,0|n&&(jt[n>>2]=e,jt[n+4>>2]=t),p=(0|o)>>>31|(u|a)<<1|0&(a<<1|o>>>31)|l,f=-2&(o<<1|0)|s,0|(cr=p,f)}function v(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0;if(d=e+4|0,c=0|jt[d>>2],r=-8&c,s=e+r|0,!(3&c))return t>>>0<256?0|(e=0):(r>>>0>=(t+4|0)>>>0?(r-t|0)>>>0<=jt[1264]<<1>>>0:0)?0|e:0|(e=0);if(r>>>0>=t>>>0)return(r=r-t|0)>>>0<=15?0|e:(u=e+t|0,jt[d>>2]=1&c|t|2,jt[u+4>>2]=3|r,d=u+r+4|0,jt[d>>2]=1|jt[d>>2],p(u,r),0|e);if((0|s)==(0|jt[1150]))return u=(0|jt[1147])+r|0,r=u-t|0,i=e+t|0,u>>>0<=t>>>0?0|(e=0):(jt[d>>2]=1&c|t|2,jt[i+4>>2]=1|r,jt[1150]=i,jt[1147]=r,0|e);if((0|s)==(0|jt[1149]))return(n=(0|jt[1146])+r|0)>>>0<t>>>0?0|(e=0):(r=n-t|0,i=1&c,r>>>0>15?(c=e+t|0,u=c+r|0,jt[d>>2]=i|t|2,jt[c+4>>2]=1|r,jt[u>>2]=r,i=u+4|0,jt[i>>2]=-2&jt[i>>2],i=c):(jt[d>>2]=i|n|2,i=e+n+4|0,jt[i>>2]=1|jt[i>>2],i=0,r=0),jt[1146]=r,jt[1149]=i,0|e);if(2&(i=0|jt[s+4>>2])|0)return 0|(e=0);if((l=(-8&i)+r|0)>>>0<t>>>0)return 0|(e=0);u=l-t|0,n=i>>>3;do{if(i>>>0<256){if(i=0|jt[s+8>>2],(0|(r=0|jt[s+12>>2]))==(0|i)){jt[1144]=jt[1144]&~(1<<n);break}jt[i+12>>2]=r,jt[r+8>>2]=i;break}a=0|jt[s+24>>2],r=0|jt[s+12>>2];do{if((0|r)==(0|s)){if(n=s+16|0,i=n+4|0,r=0|jt[i>>2])o=i;else{if(!(r=0|jt[n>>2])){n=0;break}o=n}for(;;)if(n=r+20|0,0|(i=0|jt[n>>2]))r=i,o=n;else{if(i=r+16|0,!(n=0|jt[i>>2]))break;r=n,o=i}jt[o>>2]=0,n=r}else n=0|jt[s+8>>2],jt[n+12>>2]=r,jt[r+8>>2]=n,n=r}while(0);if(0|a){if(r=0|jt[s+28>>2],i=4880+(r<<2)|0,(0|s)==(0|jt[i>>2])){if(jt[i>>2]=n,!n){jt[1145]=jt[1145]&~(1<<r);break}}else if(jt[a+16+(((0|jt[a+16>>2])!=(0|s)&1)<<2)>>2]=n,!n)break;jt[n+24>>2]=a,r=s+16|0,i=0|jt[r>>2],0|i&&(jt[n+16>>2]=i,jt[i+24>>2]=n),r=0|jt[r+4>>2],0|r&&(jt[n+20>>2]=r,jt[r+24>>2]=n)}}while(0);return r=1&c,u>>>0<16?(jt[d>>2]=l|r|2,d=e+l+4|0,jt[d>>2]=1|jt[d>>2],0|e):(c=e+t|0,jt[d>>2]=r|t|2,jt[c+4>>2]=3|u,d=c+u+4|0,jt[d>>2]=1|jt[d>>2],p(c,u),0|e)}function y(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0;var a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;switch(f=or,or=or+592|0,p=f+56|0,l=f+40|0,d=f+72|0,c=f,h=f+68|0,jt[c>>2]=40,U(e,t,c),a=(0|jt[c+4>>2])>>>n,s=(0|jt[c+8>>2])>>>n,c=c+32|0,i=0|jt[c+4>>2],0|jt[c>>2]){case 0:i?u=14:c=8;break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:u=i?14:13;break;case 9:case 10:i?u=14:c=8;break;default:u=14}13==(0|u)?c=16:14==(0|u)&&(jt[l>>2]=866,jt[l+4>>2]=2672,jt[l+8>>2]=1251,Ve(d,812,l),he(d),c=0),jt[h>>2]=r,u=0|E(e,t),t=o+n|0;do{if(t>>>0>n>>>0){if(!u){for(i=r;;){if(i=i+(0|dr(0|dr((a+3|0)>>>2,c),(s+3|0)>>>2))|0,(0|(n=n+1|0))==(0|t))break;s>>>=1,a>>>=1}jt[h>>2]=i;break}for(e=s,i=r;;){if(s=0|dr((a+3|0)>>>2,c),l=0|dr(s,(e+3|0)>>>2),(n>>>0>15|l>>>0<8?0:519686845==(0|jt[u>>2]))&&(G(u,h,l,s,n),i=0|jt[h>>2]),i=i+l|0,jt[h>>2]=i,(0|(n=n+1|0))==(0|t))break;e>>>=1,a>>>=1}}}while(0);return u?519686845!=(0|jt[u>>2])?void(or=f):(S(u),7&u?(jt[p>>2]=866,jt[p+4>>2]=2506,jt[p+8>>2]=1232,Ve(d,812,p),he(d),void(or=f)):(oe(u,0,0,1,0),void(or=f))):void(or=f)}function C(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;if(f=or,or=or+576|0,a=f,n=f+64|0,p=f+16|0,i=e+88|0,t=0|jt[i>>2],h=(0|Yt[t+39>>0])<<8|0|Yt[t+40>>0],c=e+236|0,o=e+240|0,(0|(r=0|jt[o>>2]))!=(0|h)){if(r>>>0<=h>>>0){do{if((0|jt[e+244>>2])>>>0<h>>>0){if(0|A(c,h,(r+1|0)==(0|h),4,0)){t=0|jt[o>>2];break}return zt[e+248>>0]=1,p=0,or=f,0|p}t=r}while(0);ee((0|jt[c>>2])+(t<<2)|0,0,h-t<<2|0),t=0|jt[i>>2]}jt[o>>2]=h}if(d=e+92|0,r=(0|jt[e+4>>2])+((0|Yt[t+34>>0])<<8|(0|Yt[t+33>>0])<<16|0|Yt[t+35>>0])|0,!(t=(0|Yt[t+37>>0])<<8|(0|Yt[t+36>>0])<<16|0|Yt[t+38>>0]))return p=0,or=f,0|p;if(jt[d>>2]=r,jt[e+96>>2]=r,jt[e+104>>2]=t,jt[e+100>>2]=r+t,jt[e+108>>2]=0,jt[e+112>>2]=0,l=p+20|0,jt[p>>2]=0,jt[p+4>>2]=0,jt[p+8>>2]=0,jt[p+12>>2]=0,zt[p+16>>0]=0,u=p+24|0,jt[p+44>>2]=0,jt[l>>2]=0,jt[l+4>>2]=0,jt[l+8>>2]=0,jt[l+12>>2]=0,jt[l+16>>2]=0,zt[l+20>>0]=0,0|s(d,p)?0|s(d,u):0)if(0|jt[o>>2]||(jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(n,812,a),he(n)),h)for(a=0,l=0,r=0|jt[c>>2],i=0,e=0,t=0,n=0,o=0;;){if(a=(0|b(d,p))+a&31,o=(0|b(d,u))+o&63,n=(0|b(d,p))+n&31,t=(0|b(d,p))+t|0,e=(0|b(d,u))+e&63,i=(0|b(d,p))+i&31,jt[r>>2]=o<<5|a<<11|n|t<<27|e<<21|i<<16,(l=l+1|0)>>>0>=h>>>0){t=1;break}r=r+4|0,t&=31}else t=1;else t=0;return X(p+24|0),X(p),p=t,or=f,0|p}function b(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0;m=or,or=or+576|0,u=m+48|0,d=m+32|0,c=m+16|0,l=m,p=m+64|0,h=0|jt[t+20>>2],f=e+20|0,s=0|jt[f>>2],(0|s)<24?(a=e+4|0,r=0|jt[a>>2],n=0|jt[e+8>>2],i=r>>>0<n>>>0,(0|s)<16?(i?(o=(0|Yt[r>>0])<<8,r=r+1|0):o=0,r>>>0<n>>>0?(n=0|Yt[r>>0],r=r+1|0):n=0,jt[a>>2]=r,jt[f>>2]=s+16,i=16,r=n|o):(i?(jt[a>>2]=r+1,r=0|Yt[r>>0]):r=0,jt[f>>2]=s+8,i=24),a=e+16|0,n=jt[a>>2]|r<<i-s,jt[a>>2]=n):(n=e+16|0,a=n,n=0|jt[n>>2]),o=1+(n>>>16)|0;do{if(!(o>>>0<=(0|jt[h+16>>2])>>>0)){for(i=0|jt[h+20>>2];;){if(r=i+-1|0,!(o>>>0>(0|jt[h+28+(r<<2)>>2])>>>0))break;i=i+1|0}if((r=(n>>>(32-i|0))+(0|jt[h+96+(r<<2)>>2])|0)>>>0<(0|jt[t>>2])>>>0){r=0|Qt[(0|jt[h+176>>2])+(r<<1)>>1];break}return jt[u>>2]=866,jt[u+4>>2]=3275,jt[u+8>>2]=1348,Ve(p,812,u),he(p),f=0,or=m,0|f}i=0|jt[(0|jt[h+168>>2])+(n>>>(32-(0|jt[h+8>>2])|0)<<2)>>2],-1==(0|i)&&(jt[l>>2]=866,jt[l+4>>2]=3253,jt[l+8>>2]=1393,Ve(p,812,l),he(p)),r=65535&i,i>>>=16,(0|jt[t+8>>2])>>>0<=r>>>0&&(jt[c>>2]=866,jt[c+4>>2]=909,jt[c+8>>2]=1497,Ve(p,812,c),he(p)),(0|Yt[(0|jt[t+4>>2])+r>>0])!=(0|i)&&(jt[d>>2]=866,jt[d+4>>2]=3257,jt[d+8>>2]=1410,Ve(p,812,d),he(p))}while(0);return jt[a>>2]=jt[a>>2]<<i,jt[f>>2]=(0|jt[f>>2])-i,f=r,or=m,0|f}function S(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0;if(l=or,or=or+576|0,s=l+48|0,o=l+32|0,n=l+16|0,i=l,a=l+64|0,jt[e>>2]=0,t=e+284|0,r=0|jt[t>>2],0|r&&(7&r?(jt[i>>2]=866,jt[i+4>>2]=2506,jt[i+8>>2]=1232,Ve(a,812,i),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+288>>2]=0,jt[e+292>>2]=0),zt[e+296>>0]=0,t=e+268|0,r=0|jt[t>>2],0|r&&(7&r?(jt[n>>2]=866,jt[n+4>>2]=2506,jt[n+8>>2]=1232,Ve(a,812,n),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+272>>2]=0,jt[e+276>>2]=0),zt[e+280>>0]=0,t=e+252|0,r=0|jt[t>>2],0|r&&(7&r?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1232,Ve(a,812,o),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+256>>2]=0,jt[e+260>>2]=0),zt[e+264>>0]=0,t=e+236|0,!(r=0|jt[t>>2]))return s=e+248|0,zt[s>>0]=0,s=e+212|0,X(s),s=e+188|0,X(s),s=e+164|0,X(s),s=e+140|0,X(s),s=e+116|0,X(s),void(or=l);7&r?(jt[s>>2]=866,jt[s+4>>2]=2506,jt[s+8>>2]=1232,Ve(a,812,s),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+240>>2]=0,jt[e+244>>2]=0,s=e+248|0,zt[s>>0]=0,s=e+212|0,X(s),s=e+188|0,X(s),s=e+164|0,X(s),s=e+140|0,X(s),s=e+116|0,X(s),or=l}function w(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0;e:do{if(t>>>0<=20)switch(0|t){case 9:i=3+(0|jt[r>>2])&-4,t=0|jt[i>>2],jt[r>>2]=i+4,jt[e>>2]=t;break e;case 10:i=3+(0|jt[r>>2])&-4,t=0|jt[i>>2],jt[r>>2]=i+4,i=e,jt[i>>2]=t,jt[i+4>>2]=((0|t)<0)<<31>>31;break e;case 11:i=3+(0|jt[r>>2])&-4,t=0|jt[i>>2],jt[r>>2]=i+4,i=e,jt[i>>2]=t,jt[i+4>>2]=0;break e;case 12:i=7+(0|jt[r>>2])&-8,t=i,n=0|jt[t>>2],t=0|jt[t+4>>2],jt[r>>2]=i+8,i=e,jt[i>>2]=n,jt[i+4>>2]=t;break e;case 13:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,i=(65535&i)<<16>>16,n=e,jt[n>>2]=i,jt[n+4>>2]=((0|i)<0)<<31>>31;break e;case 14:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,n=e,jt[n>>2]=65535&i,jt[n+4>>2]=0;break e;case 15:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,i=(255&i)<<24>>24,n=e,jt[n>>2]=i,jt[n+4>>2]=((0|i)<0)<<31>>31;break e;case 16:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,n=e,jt[n>>2]=255&i,jt[n+4>>2]=0;break e;case 17:case 18:n=7+(0|jt[r>>2])&-8,o=+tr[n>>3],jt[r>>2]=n+8,tr[e>>3]=o;break e;default:break e}}while(0)}function T(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0;if(c=or,or=or+560|0,n=c,i=c+40|0,u=c+16|0,r=0|jt[e+88>>2],a=(0|Yt[r+55>>0])<<8|0|Yt[r+56>>0],l=e+92|0,t=(0|jt[e+4>>2])+((0|Yt[r+50>>0])<<8|(0|Yt[r+49>>0])<<16|0|Yt[r+51>>0])|0,!(r=(0|Yt[r+53>>0])<<8|(0|Yt[r+52>>0])<<16|0|Yt[r+54>>0]))return u=0,or=c,0|u;jt[l>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,jt[u+20>>2]=0,jt[u>>2]=0,jt[u+4>>2]=0,jt[u+8>>2]=0,jt[u+12>>2]=0,zt[u+16>>0]=0;e:do{if(0|s(l,u)){if(o=e+268|0,r=e+272|0,(0|(t=0|jt[r>>2]))!=(0|a)){if(t>>>0<=a>>>0){do{if((0|jt[e+276>>2])>>>0<a>>>0){if(0|A(o,a,(t+1|0)==(0|a),2,0)){t=0|jt[r>>2];break}zt[e+280>>0]=1,t=0;break e}}while(0);ee((0|jt[o>>2])+(t<<1)|0,0,a-t<<1|0)}jt[r>>2]=a}if(!a){jt[n>>2]=866,jt[n+4>>2]=910,jt[n+8>>2]=1497,Ve(i,812,n),he(i),t=1;break}for(r=0,e=0,i=0,t=0|jt[o>>2];;){if(o=0|b(l,u),i=o+i&255,e=(0|b(l,u))+e&255,Ht[t>>1]=e<<8|i,(r=r+1|0)>>>0>=a>>>0){t=1;break}t=t+2|0}}else t=0}while(0);return X(u),u=t,or=c,0|u}function A(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;if(f=or,or=or+576|0,d=f+48|0,l=f+32|0,a=f+16|0,o=f,c=f+64|0,h=f+60|0,u=e+4|0,p=e+8|0,(0|jt[u>>2])>>>0>(0|jt[p>>2])>>>0&&(jt[o>>2]=866,jt[o+4>>2]=2123,jt[o+8>>2]=845,Ve(c,812,o),he(c)),(2147418112/(i>>>0)|0)>>>0<=t>>>0&&(jt[a>>2]=866,jt[a+4>>2]=2124,jt[a+8>>2]=885,Ve(c,812,a),he(c)),(o=0|jt[p>>2])>>>0>=t>>>0)return p=1,or=f,0|p;if((r?0!=((s=t+-1|0)&t|0):0)?(t=s>>>16|s,t|=t>>>8,t|=t>>>4,t|=t>>>2,t=1+(t>>>1|t)|0,t?r=9:(t=0,r=10)):r=9,9==(0|r)&&t>>>0<=o>>>0&&(r=10),10==(0|r)&&(jt[l>>2]=866,jt[l+4>>2]=2133,jt[l+8>>2]=933,Ve(c,812,l),he(c)),s=0|dr(t,i),n)if(a=0|Q(s,h)){Mr[0&n](a,0|jt[e>>2],0|jt[u>>2]),o=0|jt[e>>2];do{if(0|o){if(7&o){jt[d>>2]=866,jt[d+4>>2]=2506,jt[d+8>>2]=1232,Ve(c,812,d),he(c);break}oe(o,0,0,1,0);break}}while(0);jt[e>>2]=a,r=20}else t=0;else o=0|J(0|jt[e>>2],s,h,1),o?(jt[e>>2]=o,r=20):t=0;return 20==(0|r)&&(o=0|jt[h>>2],o>>>0>s>>>0&&(t=(o>>>0)/(i>>>0)|0),jt[p>>2]=t,t=1),p=t,or=f,0|p}function E(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0;if(h=or,or=or+528|0,c=h,s=h+16|0,0==(0|e)|t>>>0<62)return p=0,or=h,0|p;if(!(l=0|Q(300,0)))return p=0,or=h,0|p;jt[l>>2]=519686845,jt[l+4>>2]=0,jt[l+8>>2]=0,u=l+88|0,r=l+136|0,i=l+160|0,n=l+184|0,o=l+208|0,a=l+232|0,d=l+252|0,jt[d>>2]=0,jt[d+4>>2]=0,jt[d+8>>2]=0,zt[d+12>>0]=0,d=l+268|0,jt[d>>2]=0,jt[d+4>>2]=0,jt[d+8>>2]=0,zt[d+12>>0]=0,d=l+284|0,jt[d>>2]=0,jt[d+4>>2]=0,jt[d+8>>2]=0,zt[d+12>>0]=0,d=u,p=d+44|0;do{jt[d>>2]=0,d=d+4|0}while((0|d)<(0|p));return zt[u+44>>0]=0,jt[r>>2]=0,jt[r+4>>2]=0,jt[r+8>>2]=0,jt[r+12>>2]=0,jt[r+16>>2]=0,zt[r+20>>0]=0,jt[i>>2]=0,jt[i+4>>2]=0,jt[i+8>>2]=0,jt[i+12>>2]=0,jt[i+16>>2]=0,zt[i+20>>0]=0,jt[n>>2]=0,jt[n+4>>2]=0,jt[n+8>>2]=0,jt[n+12>>2]=0,jt[n+16>>2]=0,zt[n+20>>0]=0,jt[o>>2]=0,jt[o+4>>2]=0,jt[o+8>>2]=0,jt[o+12>>2]=0,jt[o+16>>2]=0,zt[o+20>>0]=0,jt[a>>2]=0,jt[a+4>>2]=0,jt[a+8>>2]=0,jt[a+12>>2]=0,zt[a+16>>0]=0,0|H(l,e,t)?(p=l,or=h,0|p):(S(l),7&l?(jt[c>>2]=866,jt[c+4>>2]=2506,jt[c+8>>2]=1232,Ve(s,812,c),he(s),p=0,or=h,0|p):(oe(l,0,0,1,0),p=0,or=h,0|p))}function x(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0,l=0;switch(s=or,or=or+576|0,o=s+40|0,n=s+56|0,l=s,jt[l>>2]=40,U(e,t,l),i=(3+((0|jt[l+4>>2])>>>r)|0)>>>2,t=(3+((0|jt[l+8>>2])>>>r)|0)>>>2,r=l+32|0,e=0|jt[r+4>>2],0|jt[r>>2]){case 0:e?a=14:e=8;break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:a=e?14:13;break;case 9:case 10:e?a=14:e=8;break;default:a=14}return 13==(0|a)?e=16:14==(0|a)&&(jt[o>>2]=866,jt[o+4>>2]=2672,jt[o+8>>2]=1251,Ve(n,812,o),he(n),e=0),l=0|dr(0|dr(t,i),e),or=s,0|l}function P(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0;switch(n=or,or=or+576|0,i=n+40|0,r=n+56|0,o=n,jt[o>>2]=40,U(e,t,o),t=o+32|0,e=0|jt[t+4>>2],0|jt[t>>2]){case 0:if(!e)return o=8,or=n,0|o;e=14;break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:e=e?14:13;break;case 9:case 10:if(!e)return o=8,or=n,0|o;e=14;break;default:e=14}return 13==(0|e)?(o=16,or=n,0|o):14==(0|e)?(jt[i>>2]=866,jt[i+4>>2]=2672,jt[i+8>>2]=1251,Ve(r,812,i),he(r),o=0,or=n,0|o):0}function D(e,t,r,i,n,o,a){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0;var s=0,l=0,d=0,p=0;if(p=0|jt[e+88>>2],l=(Yt[p+12>>0]<<8|Yt[p+13>>0])>>>a,d=(Yt[p+14>>0]<<8|Yt[p+15>>0])>>>a,l=((l>>>0>1?l:1)+3|0)>>>2,d=((d>>>0>1?d:1)+3|0)>>>2,p=p+18|0,a=0|zt[p>>0],a=0|dr(l,a<<24>>24==0|a<<24>>24==9?8:16),o){if(!(0==(3&o|0)&a>>>0<=o>>>0))return 0|(n=0);a=o}if((0|dr(a,d))>>>0>n>>>0)return 0|(n=0);if(o=(l+1|0)>>>1,s=(d+1|0)>>>1,!r)return 0|(n=0);switch(jt[e+92>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,0|zt[p>>0]){case 0:if(!(0|u(e,i,n,a,l,d,o,s)))return 0|(n=0);break;case 4:case 6:case 5:case 3:case 2:if(!(0|h(e,i,n,a,l,d,o,s)))return 0|(n=0);break;case 9:if(!(0|g(e,i,n,a,l,d,o,s)))return 0|(n=0);break;case 8:case 7:if(!(0|c(e,i,n,a,l,d,o,s)))return 0|(n=0);break;default:return 0|(n=0)}return 0|(n=1)}function I(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0;if((0|r)>=8192)return 0|Tr(0|e,0|t,0|r);if(o=0|e,n=e+r|0,(3&e)==(3&t)){for(;3&e;){if(!r)return 0|o;zt[e>>0]=0|zt[t>>0],e=e+1|0,t=t+1|0,r=r-1|0}for(r=-4&n|0,i=r-64|0;(0|e)<=(0|i);)jt[e>>2]=jt[t>>2],jt[e+4>>2]=jt[t+4>>2],jt[e+8>>2]=jt[t+8>>2],jt[e+12>>2]=jt[t+12>>2],jt[e+16>>2]=jt[t+16>>2],jt[e+20>>2]=jt[t+20>>2],jt[e+24>>2]=jt[t+24>>2],jt[e+28>>2]=jt[t+28>>2],jt[e+32>>2]=jt[t+32>>2],jt[e+36>>2]=jt[t+36>>2],jt[e+40>>2]=jt[t+40>>2],jt[e+44>>2]=jt[t+44>>2],jt[e+48>>2]=jt[t+48>>2],jt[e+52>>2]=jt[t+52>>2],jt[e+56>>2]=jt[t+56>>2],jt[e+60>>2]=jt[t+60>>2],e=e+64|0,t=t+64|0;for(;(0|e)<(0|r);)jt[e>>2]=jt[t>>2],e=e+4|0,t=t+4|0}else for(r=n-4|0;(0|e)<(0|r);)zt[e>>0]=0|zt[t>>0],zt[e+1>>0]=0|zt[t+1>>0],zt[e+2>>0]=0|zt[t+2>>0],zt[e+3>>0]=0|zt[t+3>>0],e=e+4|0,t=t+4|0;for(;(0|e)<(0|n);)zt[e>>0]=0|zt[t>>0],e=e+1|0,t=t+1|0;return 0|o}function O(e){e|=0;var t=0,r=0,i=0,n=0;if(n=e+92|0,i=e+88|0,r=0|jt[i>>2],t=(0|jt[e+4>>2])+((0|Yt[r+68>>0])<<8|(0|Yt[r+67>>0])<<16|0|Yt[r+69>>0])|0,!(r=(0|Yt[r+65>>0])<<8|0|Yt[r+66>>0]))return 0|(n=0);if(jt[n>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,!(0|s(n,e+116|0)))return 0|(n=0);t=0|jt[i>>2];do{if((0|Yt[t+39>>0])<<8|0|Yt[t+40>>0]){if(!(0|s(n,e+140|0)))return 0|(n=0);if(0|s(n,e+188|0)){t=0|jt[i>>2];break}return 0|(n=0)}if(!((0|Yt[t+55>>0])<<8|0|Yt[t+56>>0]))return 0|(n=0)}while(0);if((0|Yt[t+55>>0])<<8|0|Yt[t+56>>0]|0){if(!(0|s(n,e+164|0)))return 0|(n=0);if(!(0|s(n,e+212|0)))return 0|(n=0)}return 0|(n=1)}function M(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0;d=or,or=or+48|0,u=d+16|0,o=d,n=d+32|0,s=e+28|0,i=0|jt[s>>2],jt[n>>2]=i,l=e+20|0,i=(0|jt[l>>2])-i|0,jt[n+4>>2]=i,jt[n+8>>2]=t,jt[n+12>>2]=r,i=i+r|0,a=e+60|0,jt[o>>2]=jt[a>>2],jt[o+4>>2]=n,jt[o+8>>2]=2,o=0|$e(0|xr(146,0|o));e:do{if((0|i)!=(0|o)){for(t=2;;){if((0|o)<0)break;if(i=i-o|0,p=0|jt[n+4>>2],h=o>>>0>p>>>0,n=h?n+8|0:n,t=(h<<31>>31)+t|0,p=o-(h?p:0)|0,jt[n>>2]=(0|jt[n>>2])+p,h=n+4|0,jt[h>>2]=(0|jt[h>>2])-p,jt[u>>2]=jt[a>>2],jt[u+4>>2]=n,jt[u+8>>2]=t,o=0|$e(0|xr(146,0|u)),(0|i)==(0|o)){c=3;break e}}jt[e+16>>2]=0,jt[s>>2]=0,jt[l>>2]=0,jt[e>>2]=32|jt[e>>2],r=2==(0|t)?0:r-(0|jt[n+4>>2])|0}else c=3}while(0);return 3==(0|c)&&(p=0|jt[e+44>>2],jt[e+16>>2]=p+(0|jt[e+48>>2]),jt[s>>2]=p,jt[l>>2]=p),or=d,0|r}function R(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0;do{if(0|lt(e,0|jt[t+8>>2],n))Pe(0,t,r,i);else{if(o=e+8|0,!(0|lt(e,0|jt[t>>2],n))){s=0|jt[o>>2],Dr[3&jt[24+(0|jt[s>>2])>>2]](s,t,r,i,n);break}if(e=t+32|0,(0|jt[t+16>>2])!=(0|r)?(a=t+20|0,(0|jt[a>>2])!=(0|r)):0){if(jt[e>>2]=i,i=t+44|0,4==(0|jt[i>>2]))break;e=t+52|0,zt[e>>0]=0,l=t+53|0,zt[l>>0]=0,o=0|jt[o>>2],Nr[3&jt[20+(0|jt[o>>2])>>2]](o,t,r,r,1,n),0|zt[l>>0]?0|zt[e>>0]?e=3:(e=3,s=11):(e=4,s=11),11==(0|s)&&(jt[a>>2]=r,l=t+40|0,jt[l>>2]=1+(0|jt[l>>2]),(1==(0|jt[t+36>>2])?2==(0|jt[t+24>>2]):0)&&(zt[t+54>>0]=1)),jt[i>>2]=e;break}1==(0|i)&&(jt[e>>2]=1)}}while(0)}function N(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0;g=or,or=or+224|0,d=g+120|0,h=g+80|0,f=g,m=g+136|0,i=h,n=i+40|0;do{jt[i>>2]=0,i=i+4|0}while((0|i)<(0|n));return jt[d>>2]=jt[r>>2],(0|a(0,t,d,f,h))<0?r=-1:(p=(0|jt[e+76>>2])>-1?0|Lt(e):0,r=0|jt[e>>2],c=32&r,(0|zt[e+74>>0])<1&&(jt[e>>2]=-33&r),i=e+48|0,0|jt[i>>2]?r=0|a(e,t,d,f,h):(n=e+44|0,o=0|jt[n>>2],jt[n>>2]=m,s=e+28|0,jt[s>>2]=m,l=e+20|0,jt[l>>2]=m,jt[i>>2]=80,u=e+16|0,jt[u>>2]=m+80,r=0|a(e,t,d,f,h),o&&(Pr[7&jt[e+36>>2]](e,0,0),r=0==(0|jt[l>>2])?-1:r,jt[n>>2]=o,jt[i>>2]=0,jt[u>>2]=0,jt[s>>2]=0,jt[l>>2]=0)),i=0|jt[e>>2],jt[e>>2]=i|c,0|p&&Nt(e),r=0==(32&i|0)?r:-1),or=g,0|r}function L(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0;h=or,or=or+64|0,c=h,u=0|jt[e>>2],d=e+(0|jt[u+-8>>2])|0,u=0|jt[u+-4>>2],jt[c>>2]=r,jt[c+4>>2]=e,jt[c+8>>2]=t,jt[c+12>>2]=i,e=c+16|0,t=c+20|0,i=c+24|0,n=c+28|0,o=c+32|0,a=c+40|0,s=e,l=s+36|0;do{jt[s>>2]=0,s=s+4|0}while((0|s)<(0|l));Ht[e+36>>1]=0,zt[e+38>>0]=0;e:do{if(0|lt(u,r,0))jt[c+48>>2]=1,Nr[3&jt[20+(0|jt[u>>2])>>2]](u,c,d,d,1,0),e=1==(0|jt[i>>2])?d:0;else{switch(Dr[3&jt[24+(0|jt[u>>2])>>2]](u,c,d,1,0),0|jt[c+36>>2]){case 0:e=1==(0|jt[a>>2])&1==(0|jt[n>>2])&1==(0|jt[o>>2])?0|jt[t>>2]:0;break e;case 1:break;default:e=0;break e}if(1!=(0|jt[i>>2])?!(0==(0|jt[a>>2])&1==(0|jt[n>>2])&1==(0|jt[o>>2])):0){e=0;break}e=0|jt[e>>2]}}while(0);return or=h,0|e}function k(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,u=0;if(u=or,or=or+544|0,a=u+16|0,t=u,n=u+32|0,o=e+8|0,r=0|jt[o>>2],(r+-1|0)>>>0>=8192&&(jt[t>>2]=866,jt[t+4>>2]=3006,jt[t+8>>2]=1257,Ve(n,812,t),he(n)),jt[e>>2]=r,i=e+20|0,t=0|jt[i>>2],t?s=r:(t=0|Q(180,0),t?(s=t+164|0,jt[s>>2]=0,jt[s+4>>2]=0,jt[s+8>>2]=0,jt[s+12>>2]=0):t=0,jt[i>>2]=t,s=0|jt[e>>2]),0|jt[o>>2]?a=s:(jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(n,812,a),he(n),a=0|jt[e>>2]),n=0|jt[e+4>>2],!(a>>>0>16))return e=0,e=0|l(t,s,n,e),or=u,0|e;for(r=a,i=0;;){if(o=i+1|0,!(r>>>0>3))break;r>>>=1,i=o}return e=i+2+(32!=(0|o)&1<<o>>>0<a>>>0&1)|0,e=255&(e>>>0<11?e:11),e=0|l(t,s,n,e),or=u,0|e}function F(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0;h=1794895138+(0|jt[e>>2])|0,o=0|ut(0|jt[e+8>>2],h),i=0|ut(0|jt[e+12>>2],h),n=0|ut(0|jt[e+16>>2],h);e:do{if((o>>>0<t>>>2>>>0?(d=t-(o<<2)|0,i>>>0<d>>>0&n>>>0<d>>>0):0)?0==(3&(n|i)|0):0){for(d=i>>>2,c=n>>>2,u=0;;){if(s=o>>>1,l=u+s|0,a=l<<1,n=a+d|0,i=0|ut(0|jt[e+(n<<2)>>2],h),!((n=0|ut(0|jt[e+(n+1<<2)>>2],h))>>>0<t>>>0&i>>>0<(t-n|0)>>>0)){i=0;break e}if(0|zt[e+(n+i)>>0]){i=0;break e}if(!(i=0|ve(r,e+n|0)))break;if(i=(0|i)<0,1==(0|o)){i=0;break e}u=i?u:l,o=i?s:o-s|0}i=a+c|0,n=0|ut(0|jt[e+(i<<2)>>2],h),i=0|ut(0|jt[e+(i+1<<2)>>2],h),i=i>>>0<t>>>0&n>>>0<(t-i|0)>>>0&&0==(0|zt[e+(i+n)>>0])?e+i|0:0}else i=0}while(0);return 0|i}function B(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0;s=or,or=or+576|0,o=s+48|0,a=s+32|0,i=s+16|0,r=s,n=s+64|0,t=0|jt[e+168>>2];do{if(0|t){if(l=0|jt[t+-4>>2],t=t+-8|0,(0!=(0|l)?(0|l)==(0|~jt[t>>2]):0)||(jt[r>>2]=866,jt[r+4>>2]=651,jt[r+8>>2]=1579,Ve(n,812,r),he(n)),7&t){jt[i>>2]=866,jt[i+4>>2]=2506,jt[i+8>>2]=1232,Ve(n,812,i),he(n);break}oe(t,0,0,1,0);break}}while(0);return(t=0|jt[e+176>>2])?(l=0|jt[t+-4>>2],t=t+-8|0,(0!=(0|l)?(0|l)==(0|~jt[t>>2]):0)||(jt[a>>2]=866,jt[a+4>>2]=651,jt[a+8>>2]=1579,Ve(n,812,a),he(n)),7&t?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1232,Ve(n,812,o),he(n),void(or=s)):(oe(t,0,0,1,0),void(or=s))):void(or=s)}function U(e,t,r){e|=0,t|=0,r|=0;var i=0;return 0!=(0|e)&t>>>0>73&0!=(0|r)?40!=(0|jt[r>>2])?0|(r=0):18552!=((0|Yt[e>>0])<<8|0|Yt[e+1>>0]|0)?0|(r=0):((0|Yt[e+2>>0])<<8|0|Yt[e+3>>0])>>>0<74?0|(r=0):((0|Yt[e+7>>0])<<16|(0|Yt[e+6>>0])<<24|(0|Yt[e+8>>0])<<8|0|Yt[e+9>>0])>>>0>t>>>0?0|(r=0):(jt[r+4>>2]=(0|Yt[e+12>>0])<<8|0|Yt[e+13>>0],jt[r+8>>2]=(0|Yt[e+14>>0])<<8|0|Yt[e+15>>0],jt[r+12>>2]=Yt[e+16>>0],jt[r+16>>2]=Yt[e+17>>0],t=e+18|0,i=r+32|0,jt[i>>2]=Yt[t>>0],jt[i+4>>2]=0,t=0|zt[t>>0],jt[r+20>>2]=t<<24>>24==0|t<<24>>24==9?8:16,jt[r+24>>2]=(0|Yt[e+26>>0])<<16|(0|Yt[e+25>>0])<<24|(0|Yt[e+27>>0])<<8|0|Yt[e+28>>0],jt[r+28>>2]=(0|Yt[e+30>>0])<<16|(0|Yt[e+29>>0])<<24|(0|Yt[e+31>>0])<<8|0|Yt[e+32>>0],0|(r=1)):0|(r=0)}function V(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0;if(u=or,or=or+544|0,s=u+16|0,r=u,a=u+32|0,t>>>0>=33&&(jt[r>>2]=866,jt[r+4>>2]=3199,jt[r+8>>2]=1350,Ve(a,812,r),he(a)),l=e+20|0,(0|(r=0|jt[l>>2]))>=(0|t))return n=e+16|0,o=n,n=0|jt[n>>2],a=r,s=32-t|0,s=n>>>s,n<<=t,jt[o>>2]=n,t=a-t|0,jt[l>>2]=t,or=u,0|s;n=e+4|0,o=e+8|0,i=e+16|0;do{e=0|jt[n>>2],(0|e)==(0|jt[o>>2])?e=0:(jt[n>>2]=e+1,e=0|Yt[e>>0]),r=r+8|0,jt[l>>2]=r,(0|r)>=33&&(jt[s>>2]=866,jt[s+4>>2]=3208,jt[s+8>>2]=1366,Ve(a,812,s),he(a),r=0|jt[l>>2]),e=e<<32-r|jt[i>>2],jt[i>>2]=e}while((0|r)<(0|t));return s=32-t|0,s=e>>>s,a=e<<t,jt[i>>2]=a,t=r-t|0,jt[l>>2]=t,or=u,0|s}function z(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0;o=255&t,i=0!=(0|r);e:do{if(i&0!=(3&e|0))for(n=255&t;;){if((0|zt[e>>0])==n<<24>>24){a=6;break e}if(e=e+1|0,r=r+-1|0,!((i=0!=(0|r))&0!=(3&e|0))){a=5;break}}else a=5}while(0);5==(0|a)&&(i?a=6:r=0);e:do{if(6==(0|a)&&(n=255&t,(0|zt[e>>0])!=n<<24>>24)){i=0|dr(o,16843009);t:do{if(r>>>0>3)for(;;){if((-2139062144&(o=jt[e>>2]^i)^-2139062144)&o+-16843009|0)break;if(e=e+4|0,(r=r+-4|0)>>>0<=3){a=11;break t}}else a=11}while(0);if(11==(0|a)&&!r){r=0;break}for(;;){if((0|zt[e>>0])==n<<24>>24)break e;if(e=e+1|0,!(r=r+-1|0)){r=0;break}}}}while(0);return 0|(0|r?e:0)}function G(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0,u=0,c=0;return c=or,or=or+528|0,u=c,l=c+16|0,a=0|jt[e+88>>2],s=(0|Yt[a+70+(n<<2)+1>>0])<<16|(0|Yt[a+70+(n<<2)>>0])<<24|(0|Yt[a+70+(n<<2)+2>>0])<<8|0|Yt[a+70+(n<<2)+3>>0],o=n+1|0,(o=o>>>0<(0|Yt[a+16>>0])>>>0?(0|Yt[a+70+(o<<2)+1>>0])<<16|(0|Yt[a+70+(o<<2)>>0])<<24|(0|Yt[a+70+(o<<2)+2>>0])<<8|0|Yt[a+70+(o<<2)+3>>0]:0|jt[e+8>>2])>>>0>s>>>0?(l=e+4|0,l=0|jt[l>>2],l=l+s|0,u=o-s|0,u=0|D(e,l,u,t,r,i,n),or=c,0|u):(jt[u>>2]=866,jt[u+4>>2]=3694,jt[u+8>>2]=1508,Ve(l,812,u),he(l),l=e+4|0,l=0|jt[l>>2],l=l+s|0,u=o-s|0,u=0|D(e,l,u,t,r,i,n),or=c,0|u)}function H(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;if(((0==(0|t)|r>>>0<74?0:18552==((0|Yt[t>>0])<<8|0|Yt[t+1>>0]|0))?((0|Yt[t+2>>0])<<8|0|Yt[t+3>>0])>>>0>=74:0)?((0|Yt[t+7>>0])<<16|(0|Yt[t+6>>0])<<24|(0|Yt[t+8>>0])<<8|0|Yt[t+9>>0])>>>0<=r>>>0:0){if(i=e+88|0,jt[i>>2]=t,jt[e+4>>2]=t,jt[e+8>>2]=r,!(0|O(e)))return 0|(n=0);if(t=0|jt[i>>2],(0|Yt[t+39>>0])<<8|0|Yt[t+40>>0]?(0|C(e)?0|m(e):0)&&(t=0|jt[i>>2],n=11):n=11,11==(0|n)){if(!((0|Yt[t+55>>0])<<8|0|Yt[t+56>>0]))return 0|(n=1);if(0|T(e)?0|f(e):0)return 0|(n=1)}return 0|(n=0)}return jt[e+88>>2]=0,0|(n=0)}function W(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0;if(u=or,or=or+528|0,a=u,o=u+16|0,!t)return l=0,or=u,0|l;if(t>>>0<=16)return l=0|V(e,t),or=u,0|l;if(s=0|V(e,t+-16|0),l=e+20|0,(0|(t=0|jt[l>>2]))<16){i=e+4|0,n=e+8|0,r=e+16|0;do{e=0|jt[i>>2],(0|e)==(0|jt[n>>2])?e=0:(jt[i>>2]=e+1,e=0|Yt[e>>0]),t=t+8|0,jt[l>>2]=t,(0|t)>=33&&(jt[a>>2]=866,jt[a+4>>2]=3208,jt[a+8>>2]=1366,Ve(o,812,a),he(o),t=0|jt[l>>2]),e=e<<32-t|jt[r>>2],jt[r>>2]=e}while((0|t)<16)}else e=e+16|0,r=e,e=0|jt[e>>2];return jt[r>>2]=e<<16,jt[l>>2]=t+-16,l=e>>>16|s<<16,or=u,0|l}function j(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0;i=r+16|0,n=0|jt[i>>2],n?o=5:0|_e(r)?i=0:(n=0|jt[i>>2],o=5);e:do{if(5==(0|o)){if(s=r+20|0,a=0|jt[s>>2],i=a,(n-a|0)>>>0<t>>>0){i=0|Pr[7&jt[r+36>>2]](r,e,t);break}t:do{if((0|zt[r+75>>0])>-1){for(a=t;;){if(!a){o=0,n=e;break t}if(n=a+-1|0,10==(0|zt[e+n>>0]))break;a=n}if((i=0|Pr[7&jt[r+36>>2]](r,e,a))>>>0<a>>>0)break e;o=a,n=e+a|0,t=t-a|0,i=0|jt[s>>2]}else o=0,n=e}while(0);I(0|i,0|n,0|t),jt[s>>2]=(0|jt[s>>2])+t,i=o+t|0}}while(0);return 0|i}function q(e,t,r){e|=0,t|=0,r|=0;do{if(e){if(t>>>0<128){zt[e>>0]=t,e=1;break}if(r=188+(0|xt())|0,!(0|jt[jt[r>>2]>>2])){if(57216==(-128&t|0)){zt[e>>0]=t,e=1;break}e=0|At(),jt[e>>2]=84,e=-1;break}if(t>>>0<2048){zt[e>>0]=t>>>6|192,zt[e+1>>0]=63&t|128,e=2;break}if(t>>>0<55296|57344==(-8192&t|0)){zt[e>>0]=t>>>12|224,zt[e+1>>0]=t>>>6&63|128,zt[e+2>>0]=63&t|128,e=3;break}if((t+-65536|0)>>>0<1048576){zt[e>>0]=t>>>18|240,zt[e+1>>0]=t>>>12&63|128,zt[e+2>>0]=t>>>6&63|128,zt[e+3>>0]=63&t|128,e=4;break}e=0|At(),jt[e>>2]=84,e=-1;break}e=1}while(0);return 0|e}function Y(){var e=0,t=0,r=0,i=0,n=0,o=0,a=0,s=0;n=or,or=or+48|0,a=n+32|0,r=n+24|0,s=n+16|0,o=n,n=n+36|0,e=0|ke(),(0|e?0|(i=0|jt[e>>2]):0)&&(e=i+48|0,t=0|jt[e>>2],e=0|jt[e+4>>2],1126902528==(-256&t|0)&1129074247==(0|e)||(jt[r>>2]=4168,je(4118,r)),e=1126902529==(0|t)&1129074247==(0|e)?0|jt[i+44>>2]:i+80|0,jt[n>>2]=e,i=0|jt[i>>2],e=0|jt[i+4>>2],0|Pr[7&jt[16+(0|jt[2])>>2]](8,i,n)?(s=0|jt[n>>2],s=0|Or[1&jt[8+(0|jt[s>>2])>>2]](s),jt[o>>2]=4168,jt[o+4>>2]=e,jt[o+8>>2]=s,je(4032,o)):(jt[s>>2]=4168,jt[s+4>>2]=e,je(4077,s))),je(4156,a)}function X(e){e|=0;var t=0,r=0,i=0,n=0,o=0;o=or,or=or+544|0,n=o+16|0,r=o,i=o+32|0,t=0|jt[e+20>>2];do{if(0|t){if(B(t),7&t){jt[r>>2]=866,jt[r+4>>2]=2506,jt[r+8>>2]=1232,Ve(i,812,r),he(i);break}oe(t,0,0,1,0);break}}while(0);if(t=e+4|0,!(r=0|jt[t>>2]))return n=e+16|0,zt[n>>0]=0,void(or=o);7&r?(jt[n>>2]=866,jt[n+4>>2]=2506,jt[n+8>>2]=1232,Ve(i,812,n),he(i)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+8>>2]=0,jt[e+12>>2]=0,n=e+16|0,zt[n>>0]=0,or=o}function Q(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;return l=or,or=or+560|0, -s=l+32|0,a=l+16|0,r=l,o=l+48|0,n=l+44|0,i=e+3&-4,(i=0|i?i:4)>>>0>2147418112?(jt[r>>2]=866,jt[r+4>>2]=2506,jt[r+8>>2]=1103,Ve(o,812,r),he(o),s=0,or=l,0|s):(jt[n>>2]=i,e=0|oe(0,i,n,1,0),r=0|jt[n>>2],0|t&&(jt[t>>2]=r),0==(0|e)|r>>>0<i>>>0?(jt[a>>2]=866,jt[a+4>>2]=2506,jt[a+8>>2]=1129,Ve(o,812,a),he(o),e=0):7&e&&(jt[s>>2]=866,jt[s+4>>2]=2533,jt[s+8>>2]=1156,Ve(o,812,s),he(o)),s=e,or=l,0|s)}function Z(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0;if(a=or,or=or+544|0,o=a+16|0,i=a,n=a+32|0,jt[e>>2]=0,t=e+4|0,r=0|jt[t>>2],0|r&&(7&r?(jt[i>>2]=866,jt[i+4>>2]=2506,jt[i+8>>2]=1232,Ve(n,812,i),he(n)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+8>>2]=0,jt[e+12>>2]=0),zt[e+16>>0]=0,e=e+20|0,!(t=0|jt[e>>2]))return void(or=a);B(t),7&t?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1232,Ve(n,812,o),he(n)):oe(t,0,0,1,0),jt[e>>2]=0,or=a}function K(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0,c=0;c=or,or=or+128|0,n=c+124|0,u=c,o=u,a=604,s=o+124|0;do{jt[o>>2]=jt[a>>2],o=o+4|0,a=a+4|0}while((0|o)<(0|s));return(t+-1|0)>>>0>2147483646?t?(t=0|At(),jt[t>>2]=75,t=-1):(e=n,t=1,l=4):l=4,4==(0|l)&&(l=-2-e|0,l=t>>>0>l>>>0?l:t,jt[u+48>>2]=l,n=u+20|0,jt[n>>2]=e,jt[u+44>>2]=e,t=e+l|0,e=u+16|0,jt[e>>2]=t,jt[u+28>>2]=t,t=0|N(u,r,i),l&&(u=0|jt[n>>2],zt[u+(((0|u)==(0|jt[e>>2]))<<31>>31)>>0]=0)),or=c,0|t}function J(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0;return u=or,or=or+560|0,l=u+32|0,o=u+16|0,n=u,a=u+48|0,s=u+44|0,7&e|0?(jt[n>>2]=866,jt[n+4>>2]=2506,jt[n+8>>2]=1210,Ve(a,812,n),he(a),l=0,or=u,0|l):t>>>0>2147418112?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1103,Ve(a,812,o),he(a),l=0,or=u,0|l):(jt[s>>2]=t,e=0|oe(e,t,s,i,0),0|r&&(jt[r>>2]=jt[s>>2]),7&e|0&&(jt[l>>2]=866,jt[l+4>>2]=2558,jt[l+8>>2]=1156,Ve(a,812,l),he(a)),l=e,or=u,0|l)}function $(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0;do{if(0|lt(e,0|jt[t+8>>2],n))Pe(0,t,r,i);else if(0|lt(e,0|jt[t>>2],n)){if(e=t+32|0,(0|jt[t+16>>2])!=(0|r)?(o=t+20|0,(0|jt[o>>2])!=(0|r)):0){jt[e>>2]=i,jt[o>>2]=r,i=t+40|0,jt[i>>2]=1+(0|jt[i>>2]),(1==(0|jt[t+36>>2])?2==(0|jt[t+24>>2]):0)&&(zt[t+54>>0]=1),jt[t+44>>2]=4;break}1==(0|i)&&(jt[e>>2]=1)}}while(0)}function ee(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0;if(o=e+r|0,t&=255,(0|r)>=67){for(;3&e;)zt[e>>0]=t,e=e+1|0;for(i=-4&o|0,n=i-64|0,a=t|t<<8|t<<16|t<<24;(0|e)<=(0|n);)jt[e>>2]=a,jt[e+4>>2]=a,jt[e+8>>2]=a,jt[e+12>>2]=a,jt[e+16>>2]=a,jt[e+20>>2]=a,jt[e+24>>2]=a,jt[e+28>>2]=a,jt[e+32>>2]=a,jt[e+36>>2]=a,jt[e+40>>2]=a,jt[e+44>>2]=a,jt[e+48>>2]=a,jt[e+52>>2]=a,jt[e+56>>2]=a,jt[e+60>>2]=a,e=e+64|0;for(;(0|e)<(0|i);)jt[e>>2]=a,e=e+4|0}for(;(0|e)<(0|o);)zt[e>>0]=t,e=e+1|0;return o-r|0}function te(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0;zt[t+53>>0]=1;do{if((0|jt[t+4>>2])==(0|i)){if(zt[t+52>>0]=1,i=t+16|0,o=0|jt[i>>2],s=t+54|0,l=t+48|0,a=t+24|0,e=t+36|0,!o){if(jt[i>>2]=r,jt[a>>2]=n,jt[e>>2]=1,!(1==(0|jt[l>>2])&1==(0|n)))break;zt[s>>0]=1;break}if((0|o)!=(0|r)){jt[e>>2]=1+(0|jt[e>>2]),zt[s>>0]=1;break}e=0|jt[a>>2],2==(0|e)&&(jt[a>>2]=n,e=n),1==(0|jt[l>>2])&1==(0|e)&&(zt[s>>0]=1)}}while(0)}function re(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0;if(a=or,or=or+64|0,n=a,0|lt(e,t,0))t=1;else if(0!=(0|t)?0!=(0|(o=0|L(t,32,16,0))):0){t=n+4|0,i=t+52|0;do{jt[t>>2]=0,t=t+4|0}while((0|t)<(0|i));jt[n>>2]=o,jt[n+8>>2]=e,jt[n+12>>2]=-1,jt[n+48>>2]=1,Lr[3&jt[28+(0|jt[o>>2])>>2]](o,n,0|jt[r>>2],1),1==(0|jt[n+24>>2])?(jt[r>>2]=jt[n+16>>2],t=1):t=0}else t=0;return or=a,0|t}function ie(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;l=or,or=or+16|0,a=l,s=255&t,zt[a>>0]=s,i=e+16|0,n=0|jt[i>>2],n?o=4:0|_e(e)?r=-1:(n=0|jt[i>>2],o=4);do{if(4==(0|o)){if(o=e+20|0,i=0|jt[o>>2],i>>>0<n>>>0?(0|(r=255&t))!=(0|zt[e+75>>0]):0){jt[o>>2]=i+1,zt[i>>0]=s;break}r=1==(0|Pr[7&jt[e+36>>2]](e,a,1))?0|Yt[a>>0]:-1}}while(0);return or=l,0|r}function ne(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;s=255&e,r=255&e,((0|jt[t+76>>2])>=0?0!=(0|Lt(t)):0)?(((0|r)!=(0|zt[t+75>>0])?(o=t+20|0,(a=0|jt[o>>2])>>>0<(0|jt[t+16>>2])>>>0):0)?(jt[o>>2]=a+1,zt[a>>0]=s):r=0|ie(t,e),Nt(t)):l=3;do{if(3==(0|l)){if((0|r)!=(0|zt[t+75>>0])?(i=t+20|0,(n=0|jt[i>>2])>>>0<(0|jt[t+16>>2])>>>0):0){jt[i>>2]=n+1,zt[n>>0]=s;break}r=0|ie(t,e)}}while(0);return 0|r}function oe(e,t,r,i,o){e|=0,t|=0,r|=0,i|=0,o|=0;do{if(e){if(!t){if(d(e),!r){t=0;break}jt[r>>2]=0,t=0;break}i?(t=0|ce(e,t),e=0==(0|t)?e:t):t=0,r&&(o=0|Ue(e),jt[r>>2]=o)}else t=0|n(t),r&&(e=t?0|Ue(t):0,jt[r>>2]=e)}while(0);return 0|t}function ae(e){e|=0;var t=0,r=0,i=0;i=e;e:do{if(3&i)for(t=i;;){if(!(0|zt[e>>0])){e=t;break e}if(e=e+1|0,!(3&(t=e))){r=4;break}}else r=4}while(0);if(4==(0|r)){for(;;){if((-2139062144&(t=0|jt[e>>2])^-2139062144)&t+-16843009)break;e=e+4|0}if((255&t)<<24>>24)do{e=e+1|0}while(0!=(0|zt[e>>0]))}return e-i|0}function se(e,t){e=+e,t|=0;var r=0,i=0,n=0;switch(tr[nr>>3]=e,r=0|jt[nr>>2],i=0|jt[nr+4>>2],2047&(n=0|We(0|r,0|i,52))){case 0:0!=e?(e=+se(0x10000000000000000*e,t),r=(0|jt[t>>2])-64|0):r=0,jt[t>>2]=r;break;case 2047:break;default:jt[t>>2]=(2047&n)-1022,jt[nr>>2]=r,jt[nr+4>>2]=-2146435073&i|1071644672,e=+tr[nr>>3]}return+e}function le(e,t){e|=0,t|=0;var r=0,i=0;for(i=0;;){if((0|Yt[2140+i>>0])==(0|e)){e=2;break}if(87==(0|(r=i+1|0))){r=2228,i=87,e=5;break}i=r}if(2==(0|e)&&(i?(r=2228,e=5):r=2228),5==(0|e))for(;;){do{e=r,r=r+1|0}while(0!=(0|zt[e>>0]));if(!(i=i+-1|0))break;e=5}return 0|Ct(r,0|jt[t+20>>2])}function ue(e,t,r){e|=0,t|=0,r|=0;var i=0;if(t>>>0>0|0==(0|t)&e>>>0>4294967295){for(;;){if(i=0|Oe(0|e,0|t,10,0),r=r+-1|0,zt[r>>0]=255&i|48,i=e,e=0|ct(0|e,0|t,10,0),!(t>>>0>9|9==(0|t)&i>>>0>4294967295))break;t=cr}t=e}else t=e;if(t)for(;;){if(r=r+-1|0,zt[r>>0]=48|(t>>>0)%10,t>>>0<10)break;t=(t>>>0)/10|0}return 0|r}function ce(e,t){e|=0,t|=0;var r=0,i=0;return e?t>>>0>4294967231?(t=0|At(),jt[t>>2]=12,0|(t=0)):0|(r=0|v(e+-8|0,t>>>0<11?16:t+11&-8))?0|(t=r+8|0):(r=0|n(t))?(i=0|jt[e+-4>>2],i=(-8&i)-(0==(3&i|0)?8:4)|0,I(0|r,0|e,0|(i>>>0<t>>>0?i:t)),d(e),0|(t=r)):0|(t=0):0|(t=0|n(t))}function de(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0;e=t+16|0,n=0|jt[e>>2],o=t+36|0,a=t+24|0;do{if(n){if((0|n)!=(0|r)){jt[o>>2]=1+(0|jt[o>>2]),jt[a>>2]=2,zt[t+54>>0]=1;break}2==(0|jt[a>>2])&&(jt[a>>2]=i)}else jt[e>>2]=r,jt[a>>2]=i,jt[o>>2]=1}while(0)}function he(e){e|=0;var t=0,r=0,i=0,n=0;i=0|jt[119],n=(0|jt[i+76>>2])>-1?0|Lt(i):0;do{if((0|rt(e,i))<0)e=1;else{if(10!=(0|zt[i+75>>0])?(t=i+20|0,(r=0|jt[t>>2])>>>0<(0|jt[i+16>>2])>>>0):0){jt[t>>2]=r+1,zt[r>>0]=10,e=0;break}e=(0|ie(i,10))<0}}while(0);return 0|n&&Nt(i),e<<31>>31|0}function pe(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,0|lt(e,0|jt[t+8>>2],o)?te(0,t,r,i,n):(e=0|jt[e+8>>2],Nr[3&jt[20+(0|jt[e>>2])>>2]](e,t,r,i,n,o))}function fe(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0;if(a=or,or=or+256|0,o=a,(0|r)>(0|i)&0==(73728&n|0)){if(n=r-i|0,ee(0|o,0|t,0|(n>>>0<256?n:256)),n>>>0>255){t=r-i|0;do{it(e,o,256),n=n+-256|0}while(n>>>0>255);n=255&t}it(e,o,n)}or=a}function me(e,t,r,i){e|=0,t|=0,r|=0,i|=0,0|lt(e,0|jt[t+8>>2],0)?de(0,t,r,i):(e=0|jt[e+8>>2],Lr[3&jt[28+(0|jt[e>>2])>>2]](e,t,r,i))}function ge(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0;return n=or,or=or+32|0,o=n,i=n+20|0,jt[o>>2]=jt[e+60>>2],jt[o+4>>2]=0,jt[o+8>>2]=t,jt[o+12>>2]=i,jt[o+16>>2]=r,(0|$e(0|Er(140,0|o)))<0?(jt[i>>2]=-1,e=-1):e=0|jt[i>>2],or=n,0|e}function _e(e){e|=0;var t=0,r=0;return t=e+74|0,r=0|zt[t>>0],zt[t>>0]=r+255|r,t=0|jt[e>>2],8&t?(jt[e>>2]=32|t,e=-1):(jt[e+8>>2]=0,jt[e+4>>2]=0,r=0|jt[e+44>>2],jt[e+28>>2]=r,jt[e+20>>2]=r,jt[e+16>>2]=r+(0|jt[e+48>>2]),e=0),0|e}function ve(e,t){e|=0,t|=0;var r=0,i=0;if(r=0|zt[e>>0],i=0|zt[t>>0],r<<24>>24==0?1:r<<24>>24!=i<<24>>24)e=i;else{do{e=e+1|0,t=t+1|0,r=0|zt[e>>0],i=0|zt[t>>0]}while(!(r<<24>>24==0?1:r<<24>>24!=i<<24>>24));e=i}return(255&r)-(255&e)|0}function ye(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return n=or,or=or+32|0,i=n,jt[e+36>>2]=1,(0==(64&jt[e>>2]|0)?(jt[i>>2]=jt[e+60>>2],jt[i+4>>2]=21523,jt[i+8>>2]=n+16,0|vr(54,0|i)):0)&&(zt[e+75>>0]=-1),i=0|M(e,t,r),or=n,0|i}function Ce(e){e|=0;var t=0,r=0;return r=e+15&-16|0,t=0|jt[ir>>2],e=t+r|0,(0|r)>0&(0|e)<(0|t)|(0|e)<0?(gr(),br(12),-1):(jt[ir>>2]=e,((0|e)>(0|mr())?0==(0|fr()):0)?(jt[ir>>2]=t,br(12),-1):0|t)}function be(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0;return n=0|dr(r,t),r=0==(0|t)?0:r,(0|jt[i+76>>2])>-1?(o=0==(0|Lt(i)),e=0|j(e,n,i),o||Nt(i)):e=0|j(e,n,i),(0|e)!=(0|n)&&(r=(e>>>0)/(t>>>0)|0),0|r}function Se(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,0|lt(e,0|jt[t+8>>2],o)&&te(0,t,r,i,n)}function we(e,t,r,i){e|=0,t|=0,r|=0,i|=0,0|lt(e,0|jt[t+8>>2],0)&&de(0,t,r,i)}function Te(e){e|=0;var t=0,r=0,i=0;if(r=0|jt[e>>2],(i=(0|zt[r>>0])-48|0)>>>0<10){t=0;do{t=i+(10*t|0)|0,r=r+1|0,jt[e>>2]=r,i=(0|zt[r>>0])-48|0}while(i>>>0<10)}else t=0;return 0|t}function Ae(e,t,r,i){if(e|=0,t|=0,r|=0,i|=0,!(0==(0|e)&0==(0|t)))do{r=r+-1|0,zt[r>>0]=0|Yt[2122+(15&e)>>0]|i,e=0|We(0|e,0|t,4),t=cr}while(!(0==(0|e)&0==(0|t)));return 0|r}function Ee(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return n=or,or=or+16|0,i=n,jt[i>>2]=jt[r>>2],e=0|Pr[7&jt[16+(0|jt[e>>2])>>2]](e,t,i),e&&(jt[r>>2]=jt[i>>2]),or=n,1&e|0}function xe(e){e|=0;var t=0;return(0|(t=0|zt[sr+(255&e)>>0]))<8?0|t:(0|(t=0|zt[sr+(e>>8&255)>>0]))<8?t+8|0:(t=0|zt[sr+(e>>16&255)>>0],(0|t)<8?t+16|0:24+(0|zt[sr+(e>>>24)>>0])|0)}function Pe(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0;((0|jt[t+4>>2])==(0|r)?(n=t+28|0,1!=(0|jt[n>>2])):0)&&(jt[n>>2]=i)}function De(e,t,r){if(e|=0,t|=0,r|=0,!(0==(0|e)&0==(0|t)))do{r=r+-1|0,zt[r>>0]=7&e|48,e=0|We(0|e,0|t,3),t=cr}while(!(0==(0|e)&0==(0|t)));return 0|r}function Ie(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return i=e+20|0,n=0|jt[i>>2],e=(0|jt[e+16>>2])-n|0,e=e>>>0>r>>>0?r:e,I(0|n,0|t,0|e),jt[i>>2]=(0|jt[i>>2])+e,0|r}function Oe(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0;return o=or,or=or+16|0,n=0|o,_(e,t,r,i,n),or=o,0|(cr=0|jt[n+4>>2],0|jt[n>>2])}function Me(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+32>>2]}function Re(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+12>>2]}function Ne(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+8>>2]}function Le(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+4>>2]}function ke(){var e=0,t=0;return e=or,or=or+16|0,0|wr(5136,2)?(je(4307,e),0):(t=0|_r(0|jt[1285]),or=e,0|t)}function Fe(e){e|=0;var t=0,r=0;return t=or,or=or+16|0,r=t,e=0|Ot(0|jt[e+60>>2]),jt[r>>2]=e,e=0|$e(0|Cr(6,0|r)),or=t,0|e}function Be(e){e|=0;var t=0;if(t=or,or=or+16|0,d(e),!(0|yr(0|jt[1285],0)))return void(or=t);je(4406,t)}function Ue(e){e|=0;var t=0;return e?(t=0|jt[e+-4>>2],e=3&t,0|(1==(0|e)?0:(-8&t)-(0==(0|e)?8:4)|0)):0}function Ve(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return i=or,or=or+16|0,n=i,jt[n>>2]=r,r=0|ft(e,t,n),or=i,0|r}function ze(e,t,r,i,n,o,a){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,Nr[3&e](0|t,0|r,0|i,0|n,0|o,0|a)}function Ge(){var e=0;if(e=or,or=or+16|0,!(0|Ar(5140,6)))return void(or=e);je(4356,e)}function He(e,t,r){return e|=0,t|=0,(0|(r|=0))<32?(cr=t<<r|(e&(1<<r)-1<<32-r)>>>32-r,e<<r):(cr=e<<r-32,0)}function We(e,t,r){return e|=0,t|=0,(0|(r|=0))<32?(cr=t>>>r,e>>>r|(t&(1<<r)-1)<<32-r):(cr=0,t>>>r-32|0)}function je(e,t){e|=0,t|=0;var r=0;r=or,or=or+16|0,jt[r>>2]=t,t=0|jt[26],N(t,e,r),ne(10,t),Sr()}function qe(){}function Ye(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,i=t-i-(r>>>0>e>>>0|0)>>>0,0|(cr=i,e-r>>>0|0)}function Xe(e,t){return e|=0,t|=0,t=t?0|F(0|jt[t>>2],0|jt[t+4>>2],e):0,0|(0|t?t:e)}function Qe(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,Dr[3&e](0|t,0|r,0|i,0|n,0|o)}function Ze(e){e=+e;var t=0;return tr[nr>>3]=e,t=0|jt[nr>>2],cr=0|jt[nr+4>>2],0|t}function Ke(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,r=e+r>>>0,0|(cr=t+i+(r>>>0<e>>>0|0)>>>0,0|r)}function Je(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0,Lr[3&e](0|t,0|r,0|i,0|n)}function $e(e){e|=0;var t=0;return e>>>0>4294963200&&(t=0|At(),jt[t>>2]=0-e,e=-1),0|e}function et(e){return e|=0,1&(e=e?0!=(0|L(e,32,88,0)):0)|0}function tt(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,0|Pr[7&e](0|t,0|r,0|i)}function rt(e,t){e|=0,t|=0;var r=0;return r=0|ae(e),((0|be(e,1,r,t))!=(0|r))<<31>>31|0}function it(e,t,r){e|=0,t|=0,r|=0,32&jt[e>>2]||j(t,r,e)}function nt(e,t,r,i){e|=0,t|=0,r|=0,i|=0,Mr[0&e](0|t,0|r,0|i)}function ot(e){e|=0;var t=0;return t=or,or=or+e|0,or=or+15&-16,0|t}function at(e){e|=0;var t=0;return t=188+(0|xt())|0,0|le(e,0|jt[t>>2])}function st(e,t){return e|=0,t|=0,0|(e=e?0|q(e,t,0):0)}function lt(e,t,r){return e|=0,t|=0,r|=0,(0|e)==(0|t)|0}function ut(e,t){e|=0,t|=0;var r=0;return r=0|dt(0|e),0|(0==(0|t)?e:r)}function ct(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,0|_(e,t,r,i,0)}function dt(e){return(255&(e|=0))<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>>24|0}function ht(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,pr(6)}function pt(e,t){e|=0,t|=0,lr||(lr=e,ur=t)}function ft(e,t,r){return e|=0,t|=0,r|=0,0|K(e,2147483647,t,r)}function mt(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0,pr(1)}function gt(e){e|=0,Nt(e),Dt(e)}function _t(e,t){return e|=0,t|=0,0|Or[1&e](0|t)}function vt(e,t){e|=0,t|=0,or=e,ar=t}function yt(e,t,r,i){e|=0,t|=0,r|=0,i|=0,pr(7)}function Ct(e,t){return e|=0,t|=0,0|Xe(e,t)}function bt(e,t){e|=0,t|=0,Ir[7&e](0|t)}function St(e,t,r){return e|=0,t|=0,r|=0,pr(0),0}function wt(e,t){return e=+e,t|=0,+ +se(e,t)}function Tt(e,t,r){e|=0,t|=0,r|=0,pr(4)}function At(){return 64+(0|xt())|0}function Et(e){e|=0,Rr[3&e]()}function xt(){return 232}function Pt(e){e|=0,or=e}function Dt(e){e|=0,d(e)}function It(e){e|=0,cr=e}function Ot(e){return 0|(e|=0)}function Mt(){return 5072}function Rt(e){return e|=0,pr(3),0}function Nt(e){e|=0}function Lt(e){return e|=0,0}function kt(){return 0|cr}function Ft(){return 0|or}function Bt(e){e|=0,pr(2)}function Ut(){pr(5)}var Vt=e.Int8Array,zt=new Vt(r),Gt=e.Int16Array,Ht=new Gt(r),Wt=e.Int32Array,jt=new Wt(r),qt=e.Uint8Array,Yt=new qt(r),Xt=e.Uint16Array,Qt=new Xt(r),Zt=e.Uint32Array,Kt=new Zt(r),Jt=e.Float32Array,$t=new Jt(r),er=e.Float64Array,tr=new er(r),rr=e.byteLength,ir=0|t.DYNAMICTOP_PTR,nr=0|t.tempDoublePtr,or=(t.ABORT,0|t.STACKTOP),ar=0|t.STACK_MAX,sr=0|t.cttz_i8,lr=0,ur=0,cr=(e.NaN,e.Infinity,0),dr=(e.Math.floor,e.Math.abs,e.Math.sqrt,e.Math.pow,e.Math.cos,e.Math.sin,e.Math.tan,e.Math.acos,e.Math.asin,e.Math.atan,e.Math.atan2,e.Math.exp,e.Math.log,e.Math.ceil,e.Math.imul),hr=(e.Math.min,e.Math.max,e.Math.clz32),pr=t.abort,fr=(t.assert,t.enlargeMemory),mr=t.getTotalMemory,gr=t.abortOnCannotGrowMemory,_r=(t.invoke_iiii,t.invoke_viiiii,t.invoke_vi,t.invoke_ii,t.invoke_viii,t.invoke_v,t.invoke_viiiiii,t.invoke_viiii,t._pthread_getspecific),vr=t.___syscall54,yr=t._pthread_setspecific,Cr=(t.___gxx_personality_v0,t.___syscall6),br=t.___setErrNo,Sr=t._abort,wr=(t.___cxa_begin_catch,t._pthread_once),Tr=t._emscripten_memcpy_big,Ar=t._pthread_key_create,Er=t.___syscall140,xr=(t.___resumeException,t.___cxa_find_matching_catch,t.___syscall146),Pr=(t.__ZSt18uncaught_exceptionv,[St,M,ge,ye,Ie,re,St,St]),Dr=[mt,$,R,mt],Ir=[Bt,Nt,gt,Nt,Nt,gt,Be,Bt],Or=[Rt,Fe],Mr=[Tt],Rr=[Ut,Y,Ge,Ut],Nr=[ht,Se,pe,ht],Lr=[yt,we,me,yt];return{stackSave:Ft,_i64Subtract:Ye,_crn_get_bytes_per_block:P,setThrew:pt,dynCall_viii:nt,_bitshift64Lshr:We,_bitshift64Shl:He,dynCall_viiii:Je,setTempRet0:It,_crn_decompress:y,_memset:ee,_sbrk:Ce,_memcpy:I,stackAlloc:ot,_crn_get_height:Ne,dynCall_vi:bt,getTempRet0:kt,_crn_get_levels:Re,_crn_get_uncompressed_size:x,_i64Add:Ke,dynCall_iiii:tt,_emscripten_get_global_libc:Mt,dynCall_ii:_t,___udivdi3:ct,_llvm_bswap_i32:dt,dynCall_viiiii:Qe,___cxa_can_catch:Ee,_free:d,runPostSets:qe,dynCall_viiiiii:ze,establishStackSpace:vt,___uremdi3:Oe,___cxa_is_pointer_type:et,stackRestore:Pt,_malloc:n,_emscripten_replace_memory:i,dynCall_v:Et,_crn_get_width:Le,_crn_get_dxt_format:Me}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),stackSave=Module.stackSave=asm.stackSave,getTempRet0=Module.getTempRet0=asm.getTempRet0,_memset=Module._memset=asm._memset,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,setTempRet0=Module.setTempRet0=asm.setTempRet0,_crn_decompress=Module._crn_decompress=asm._crn_decompress,_crn_get_bytes_per_block=Module._crn_get_bytes_per_block=asm._crn_get_bytes_per_block,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,_crn_get_height=Module._crn_get_height=asm._crn_get_height,_i64Subtract=Module._i64Subtract=asm._i64Subtract,_crn_get_levels=Module._crn_get_levels=asm._crn_get_levels,_crn_get_uncompressed_size=Module._crn_get_uncompressed_size=asm._crn_get_uncompressed_size,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,___udivdi3=Module.___udivdi3=asm.___udivdi3,_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,___cxa_can_catch=Module.___cxa_can_catch=asm.___cxa_can_catch,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,___uremdi3=Module.___uremdi3=asm.___uremdi3,___cxa_is_pointer_type=Module.___cxa_is_pointer_type=asm.___cxa_is_pointer_type,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,_emscripten_replace_memory=Module._emscripten_replace_memory=asm._emscripten_replace_memory,_crn_get_width=Module._crn_get_width=asm._crn_get_width,_crn_get_dxt_format=Module._crn_get_dxt_format=asm._crn_get_dxt_format,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii;Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm,ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var initialStackTop,preloadStartTime=null,calledMain=!1;dependenciesFulfilled=function e(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=e)},Module.callMain=Module.callMain=function(e){function t(){for(var e=0;e<3;e++)i.push(0)}e=e||[],ensureInitRuntime();var r=e.length+1,i=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];t();for(var n=0;n<r-1;n+=1)i.push(allocate(intArrayFromString(e[n]),"i8",ALLOC_NORMAL)),t();i.push(0),i=allocate(i,"i32",ALLOC_NORMAL);try{exit(Module._main(r,i,0),!0)}catch(e){if(e instanceof ExitStatus)return;if("SimulateInfiniteLoop"==e)return void(Module.noExitRuntime=!0);var o=e;e&&"object"==typeof e&&e.stack&&(o=[e,e.stack]),Module.printErr("exception thrown: "+o),Module.quit(1,e)}finally{calledMain=!0}},Module.run=Module.run=run,Module.exit=Module.exit=exit;var abortDecorators=[];if(Module.abort=Module.abort=abort,Module.preInit)for("function"==typeof Module.preInit&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;return Module.noInitialRun&&(shouldRunNow=!1),Module.noExitRuntime=!0,run(),Module}),define("ThirdParty/GltfPipeline/findAccessorMinMax",["./getAccessorByteStride","./numberOfComponentsForType","../../Core/arrayFill","../../Core/ComponentDatatype","../../Core/defined"],function(e,t,r,i,n){"use strict";function o(o,a){var s=o.bufferViews,l=o.buffers,u=a.bufferView,c=t(a.type),d=r(new Array(c),Number.POSITIVE_INFINITY),h=r(new Array(c),Number.NEGATIVE_INFINITY);if(n(u)&&n(s)&&s.hasOwnProperty(u)){var p=s[u],f=p.buffer;if(n(f)&&n(l)&&l.hasOwnProperty(f))for(var m=l[f],g=m.extras._pipeline.source,_=a.count,v=e(o,a),y=a.byteOffset+p.byteOffset,C=a.componentType,b=0;b<_;b++){for(var S=i.createArrayBufferView(C,g.buffer,y+g.byteOffset,c),w=0;w<c;w++){var T=S[w];d[w]=Math.min(d[w],T),h[w]=Math.max(h[w],T)}y+=v}}return{min:d,max:h}}return o}),define("ThirdParty/GltfPipeline/getJointCountForMaterials",["./ForEach","../../Core/defined"],function(e,t){"use strict";function r(r){var i=r.meshes,n={},o={};return e.node(r,function(e){t(e.skin)&&(t(o[e.skin])||(o[e.skin]=[]),o[e.skin].push(e))}),e.skin(r,function(r,a){for(var s=r.joints.length,l=function(e){n[e.material]=s},u=o[a],c=u.length,d=0;d<c;d++){var h=u[d],p=h.mesh;if(t(p)){var f=i[p];e.meshPrimitive(f,l)}}}),n}return r}),define("ThirdParty/GltfPipeline/removePipelineExtras",["../../Core/defined"],function(e){"use strict";function t(r){if(e(r)&&"object"==typeof r){e(r.extras)&&e(r.extras._pipeline)&&(delete r.extras._pipeline,0===Object.keys(r.extras).length&&delete r.extras);for(var i in r)r.hasOwnProperty(i)&&t(r[i])}return r}return t}),function(){!function(e){var t=this||(0,eval)("this"),r=t.document,i=t.navigator,n=t.jQuery,o=t.JSON;!function(e){"function"==typeof define&&define.amd?define("ThirdParty/knockout-3.4.2",["exports","require"],e):e("object"==typeof exports&&"object"==typeof module?module.exports||exports:t.ko={})}(function(a,s){function l(e,t){return(null===e||typeof e in g)&&e===t}function u(t,r){var i;return function(){i||(i=m.a.setTimeout(function(){i=e,t()},r))}}function c(e,t){var r;return function(){clearTimeout(r),r=m.a.setTimeout(e,t)}}function d(e,t){t&&t!==_?"beforeChange"===t?this.Ob(e):this.Ja(e,t):this.Pb(e)}function h(e,t){null!==t&&t.k&&t.k()}function p(e,t){var r=this.Mc,i=r[S];i.T||(this.ob&&this.Oa[t]?(r.Sb(t,e,this.Oa[t]),this.Oa[t]=null,--this.ob):i.s[t]||r.Sb(t,e,i.t?{$:e}:r.yc(e)),e.Ha&&e.Hc())}function f(e,t,r,i){m.d[e]={init:function(e,n,o,a,s){var l,u;return m.m(function(){var o=n(),a=m.a.c(o),a=!r!=!a,c=!u;(c||t||a!==l)&&(c&&m.xa.Ca()&&(u=m.a.wa(m.f.childNodes(e),!0)),a?(c||m.f.fa(e,m.a.wa(u)),m.hb(i?i(s,o):s,e)):m.f.za(e),l=a)},null,{i:e}),{controlsDescendantBindings:!0}}},m.h.va[e]=!1,m.f.aa[e]=!0}var m=void 0!==a?a:{};m.b=function(e,t){for(var r=e.split("."),i=m,n=0;n<r.length-1;n++)i=i[r[n]];i[r[r.length-1]]=t},m.H=function(e,t,r){e[t]=r},m.version="3.4.2",m.b("version",m.version),m.options={deferUpdates:!1,useOnlyNativeEvents:!1},m.a=function(){function a(e,t){for(var r in e)e.hasOwnProperty(r)&&t(r,e[r])}function s(e,t){if(t)for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function l(e,t){return e.__proto__=t,e}function u(e,t,r,i){var n=e[t].match(_)||[];m.a.r(r.match(_),function(e){m.a.ra(n,e,i)}),e[t]=n.join(" ")}var c={__proto__:[]}instanceof Array,d="function"==typeof Symbol,h={},p={};h[i&&/Firefox\/2/i.test(i.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"],h.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" "),a(h,function(e,t){if(t.length)for(var r=0,i=t.length;r<i;r++)p[t[r]]=e});var f={propertychange:!0},g=r&&function(){for(var t=3,i=r.createElement("div"),n=i.getElementsByTagName("i");i.innerHTML="\x3c!--[if gt IE "+ ++t+"]><i></i><![endif]--\x3e",n[0];);return 4<t?t:e}(),_=/\S+/g;return{gc:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],r:function(e,t){for(var r=0,i=e.length;r<i;r++)t(e[r],r)},o:function(e,t){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(e,t);for(var r=0,i=e.length;r<i;r++)if(e[r]===t)return r;return-1},Vb:function(e,t,r){for(var i=0,n=e.length;i<n;i++)if(t.call(r,e[i],i))return e[i];return null},Na:function(e,t){var r=m.a.o(e,t);0<r?e.splice(r,1):0===r&&e.shift()},Wb:function(e){e=e||[];for(var t=[],r=0,i=e.length;r<i;r++)0>m.a.o(t,e[r])&&t.push(e[r]);return t},ib:function(e,t){e=e||[];for(var r=[],i=0,n=e.length;i<n;i++)r.push(t(e[i],i));return r},Ma:function(e,t){e=e||[];for(var r=[],i=0,n=e.length;i<n;i++)t(e[i],i)&&r.push(e[i]);return r},ta:function(e,t){if(t instanceof Array)e.push.apply(e,t);else for(var r=0,i=t.length;r<i;r++)e.push(t[r]);return e},ra:function(e,t,r){var i=m.a.o(m.a.Bb(e),t);0>i?r&&e.push(t):r||e.splice(i,1)},la:c,extend:s,$a:l,ab:c?l:s,D:a,Ea:function(e,t){if(!e)return e;var r,i={};for(r in e)e.hasOwnProperty(r)&&(i[r]=t(e[r],r,e));return i},rb:function(e){for(;e.firstChild;)m.removeNode(e.firstChild)},nc:function(e){e=m.a.W(e);for(var t=(e[0]&&e[0].ownerDocument||r).createElement("div"),i=0,n=e.length;i<n;i++)t.appendChild(m.ba(e[i]));return t},wa:function(e,t){for(var r=0,i=e.length,n=[];r<i;r++){var o=e[r].cloneNode(!0);n.push(t?m.ba(o):o)}return n},fa:function(e,t){if(m.a.rb(e),t)for(var r=0,i=t.length;r<i;r++)e.appendChild(t[r])},uc:function(e,t){var r=e.nodeType?[e]:e;if(0<r.length){for(var i=r[0],n=i.parentNode,o=0,a=t.length;o<a;o++)n.insertBefore(t[o],i);for(o=0,a=r.length;o<a;o++)m.removeNode(r[o])}},Ba:function(e,t){if(e.length){for(t=8===t.nodeType&&t.parentNode||t;e.length&&e[0].parentNode!==t;)e.splice(0,1);for(;1<e.length&&e[e.length-1].parentNode!==t;)e.length--;if(1<e.length){var r=e[0],i=e[e.length-1];for(e.length=0;r!==i;)e.push(r),r=r.nextSibling;e.push(i)}}return e},wc:function(e,t){7>g?e.setAttribute("selected",t):e.selected=t},cb:function(t){return null===t||t===e?"":t.trim?t.trim():t.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},sd:function(e,t){return e=e||"",!(t.length>e.length)&&e.substring(0,t.length)===t},Rc:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(3===e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},qb:function(e){return m.a.Rc(e,e.ownerDocument.documentElement)},Tb:function(e){return!!m.a.Vb(e,m.a.qb)},A:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},Zb:function(e){return m.onError?function(){try{return e.apply(this,arguments)}catch(e){throw m.onError&&m.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(m.a.Zb(e),t)},dc:function(e){setTimeout(function(){throw m.onError&&m.onError(e),e},0)},q:function(e,t,r){var i=m.a.Zb(r);if(r=g&&f[t],m.options.useOnlyNativeEvents||r||!n)if(r||"function"!=typeof e.addEventListener){if(void 0===e.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");var o=function(t){i.call(e,t)},a="on"+t;e.attachEvent(a,o),m.a.G.qa(e,function(){e.detachEvent(a,o)})}else e.addEventListener(t,i,!1);else n(e).bind(t,i)},Fa:function(e,i){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var o;if("input"===m.a.A(e)&&e.type&&"click"==i.toLowerCase()?(o=e.type,o="checkbox"==o||"radio"==o):o=!1,m.options.useOnlyNativeEvents||!n||o)if("function"==typeof r.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");o=r.createEvent(p[i]||"HTMLEvents"),o.initEvent(i,!0,!0,t,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(o)}else if(o&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+i)}else n(e).trigger(i)},c:function(e){return m.I(e)?e():e},Bb:function(e){return m.I(e)?e.p():e},fb:function(e,t,r){var i;t&&("object"==typeof e.classList?(i=e.classList[r?"add":"remove"],m.a.r(t.match(_),function(t){i.call(e.classList,t)})):"string"==typeof e.className.baseVal?u(e.className,"baseVal",t,r):u(e,"className",t,r))},bb:function(t,r){var i=m.a.c(r);null!==i&&i!==e||(i="");var n=m.f.firstChild(t);!n||3!=n.nodeType||m.f.nextSibling(n)?m.f.fa(t,[t.ownerDocument.createTextNode(i)]):n.data=i,m.a.Wc(t)},vc:function(e,t){if(e.name=t,7>=g)try{e.mergeAttributes(r.createElement("<input name='"+e.name+"'/>"),!1)}catch(e){}},Wc:function(e){9<=g&&(e=1==e.nodeType?e:e.parentNode,e.style&&(e.style.zoom=e.style.zoom))},Sc:function(e){if(g){var t=e.style.width;e.style.width=0,e.style.width=t}},nd:function(e,t){e=m.a.c(e),t=m.a.c(t);for(var r=[],i=e;i<=t;i++)r.push(i);return r},W:function(e){for(var t=[],r=0,i=e.length;r<i;r++)t.push(e[r]);return t},bc:function(e){return d?Symbol(e):e},xd:6===g,yd:7===g,C:g,ic:function(e,t){for(var r=m.a.W(e.getElementsByTagName("input")).concat(m.a.W(e.getElementsByTagName("textarea"))),i="string"==typeof t?function(e){return e.name===t}:function(e){return t.test(e.name)},n=[],o=r.length-1;0<=o;o--)i(r[o])&&n.push(r[o]);return n},kd:function(e){return"string"==typeof e&&(e=m.a.cb(e))?o&&o.parse?o.parse(e):new Function("return "+e)():null},Gb:function(e,t,r){if(!o||!o.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");return o.stringify(m.a.c(e),t,r)},ld:function(e,t,i){i=i||{};var n=i.params||{},o=i.includeFields||this.gc,s=e;if("object"==typeof e&&"form"===m.a.A(e))for(var s=e.action,l=o.length-1;0<=l;l--)for(var u=m.a.ic(e,o[l]),c=u.length-1;0<=c;c--)n[u[c].name]=u[c].value;t=m.a.c(t);var d=r.createElement("form");d.style.display="none",d.action=s,d.method="post";for(var h in t)e=r.createElement("input"),e.type="hidden",e.name=h,e.value=m.a.Gb(m.a.c(t[h])),d.appendChild(e);a(n,function(e,t){var i=r.createElement("input");i.type="hidden",i.name=e,i.value=t,d.appendChild(i)}),r.body.appendChild(d),i.submitter?i.submitter(d):d.submit(),setTimeout(function(){d.parentNode.removeChild(d)},0)}}}(),m.b("utils",m.a),m.b("utils.arrayForEach",m.a.r),m.b("utils.arrayFirst",m.a.Vb),m.b("utils.arrayFilter",m.a.Ma),m.b("utils.arrayGetDistinctValues",m.a.Wb),m.b("utils.arrayIndexOf",m.a.o),m.b("utils.arrayMap",m.a.ib),m.b("utils.arrayPushAll",m.a.ta),m.b("utils.arrayRemoveItem",m.a.Na),m.b("utils.extend",m.a.extend),m.b("utils.fieldsIncludedWithJsonPost",m.a.gc),m.b("utils.getFormFields",m.a.ic),m.b("utils.peekObservable",m.a.Bb),m.b("utils.postJson",m.a.ld),m.b("utils.parseJson",m.a.kd),m.b("utils.registerEventHandler",m.a.q),m.b("utils.stringifyJson",m.a.Gb),m.b("utils.range",m.a.nd),m.b("utils.toggleDomNodeCssClass",m.a.fb),m.b("utils.triggerEvent",m.a.Fa),m.b("utils.unwrapObservable",m.a.c),m.b("utils.objectForEach",m.a.D),m.b("utils.addOrRemoveItem",m.a.ra),m.b("utils.setTextContent",m.a.bb),m.b("unwrap",m.a.c),Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if(1===arguments.length)return function(){return t.apply(e,arguments)};var r=Array.prototype.slice.call(arguments,1);return function(){var i=r.slice(0);return i.push.apply(i,arguments),t.apply(e,i)}}),m.a.e=new function(){function t(t,o){var a=t[i];if(!a||"null"===a||!n[a]){if(!o)return e;a=t[i]="ko"+r++,n[a]={}}return n[a]}var r=0,i="__ko__"+(new Date).getTime(),n={};return{get:function(r,i){var n=t(r,!1);return n===e?e:n[i]},set:function(r,i,n){n===e&&t(r,!1)===e||(t(r,!0)[i]=n)},clear:function(e){var t=e[i];return!!t&&(delete n[t],e[i]=null,!0)},J:function(){return r+++i}}},m.b("utils.domData",m.a.e),m.b("utils.domData.clear",m.a.e.clear),m.a.G=new function(){function t(t,r){var n=m.a.e.get(t,i);return n===e&&r&&(n=[],m.a.e.set(t,i,n)),n}function r(e){var i=t(e,!1);if(i)for(var i=i.slice(0),n=0;n<i.length;n++)i[n](e);if(m.a.e.clear(e),m.a.G.cleanExternalData(e),a[e.nodeType])for(i=e.firstChild;e=i;)i=e.nextSibling,8===e.nodeType&&r(e)}var i=m.a.e.J(),o={1:!0,8:!0,9:!0},a={1:!0,9:!0};return{qa:function(e,r){if("function"!=typeof r)throw Error("Callback must be a function");t(e,!0).push(r)},tc:function(r,n){var o=t(r,!1);o&&(m.a.Na(o,n),0==o.length&&m.a.e.set(r,i,e))},ba:function(e){if(o[e.nodeType]&&(r(e),a[e.nodeType])){var t=[];m.a.ta(t,e.getElementsByTagName("*"));for(var i=0,n=t.length;i<n;i++)r(t[i])}return e},removeNode:function(e){m.ba(e),e.parentNode&&e.parentNode.removeChild(e)},cleanExternalData:function(e){n&&"function"==typeof n.cleanData&&n.cleanData([e])}}},m.ba=m.a.G.ba,m.removeNode=m.a.G.removeNode,m.b("cleanNode",m.ba),m.b("removeNode",m.removeNode),m.b("utils.domNodeDisposal",m.a.G),m.b("utils.domNodeDisposal.addDisposeCallback",m.a.G.qa),m.b("utils.domNodeDisposal.removeDisposeCallback",m.a.G.tc),function(){var i=[0,"",""],o=[1,"<table>","</table>"],a=[3,"<table><tbody><tr>","</tr></tbody></table>"],s=[1,"<select multiple='multiple'>","</select>"],l={thead:o,tbody:o,tfoot:o,tr:[2,"<table><tbody>","</tbody></table>"],td:a,th:a,option:s,optgroup:s},u=8>=m.a.C;m.a.na=function(e,o){var a;if(n){ -if(n.parseHTML)a=n.parseHTML(e,o)||[];else if((a=n.clean([e],o))&&a[0]){for(var s=a[0];s.parentNode&&11!==s.parentNode.nodeType;)s=s.parentNode;s.parentNode&&s.parentNode.removeChild(s)}}else{(a=o)||(a=r);var c,s=a.parentWindow||a.defaultView||t,d=m.a.cb(e).toLowerCase(),h=a.createElement("div");for(c=(d=d.match(/^<([a-z]+)[ >]/))&&l[d[1]]||i,d=c[0],c="ignored<div>"+c[1]+e+c[2]+"</div>","function"==typeof s.innerShiv?h.appendChild(s.innerShiv(c)):(u&&a.appendChild(h),h.innerHTML=c,u&&h.parentNode.removeChild(h));d--;)h=h.lastChild;a=m.a.W(h.lastChild.childNodes)}return a},m.a.Eb=function(t,r){if(m.a.rb(t),null!==(r=m.a.c(r))&&r!==e)if("string"!=typeof r&&(r=r.toString()),n)n(t).html(r);else for(var i=m.a.na(r,t.ownerDocument),o=0;o<i.length;o++)t.appendChild(i[o])}}(),m.b("utils.parseHtmlFragment",m.a.na),m.b("utils.setHtml",m.a.Eb),m.N=function(){function t(e,r){if(e)if(8==e.nodeType){var i=m.N.pc(e.nodeValue);null!=i&&r.push({Qc:e,hd:i})}else if(1==e.nodeType)for(var i=0,n=e.childNodes,o=n.length;i<o;i++)t(n[i],r)}var r={};return{yb:function(e){if("function"!=typeof e)throw Error("You can only pass a function to ko.memoization.memoize()");var t=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);return r[t]=e,"\x3c!--[ko_memo:"+t+"]--\x3e"},Bc:function(t,i){var n=r[t];if(n===e)throw Error("Couldn't find any memo with ID "+t+". Perhaps it's already been unmemoized.");try{return n.apply(null,i||[]),!0}finally{delete r[t]}},Cc:function(e,r){var i=[];t(e,i);for(var n=0,o=i.length;n<o;n++){var a=i[n].Qc,s=[a];r&&m.a.ta(s,r),m.N.Bc(i[n].hd,s),a.nodeValue="",a.parentNode&&a.parentNode.removeChild(a)}},pc:function(e){return(e=e.match(/^\[ko_memo\:(.*?)\]$/))?e[1]:null}}}(),m.b("memoization",m.N),m.b("memoization.memoize",m.N.yb),m.b("memoization.unmemoize",m.N.Bc),m.b("memoization.parseMemoText",m.N.pc),m.b("memoization.unmemoizeDomNodeAndDescendants",m.N.Cc),m.Z=function(){function e(){if(o)for(var e,t=o,r=0;s<o;)if(e=n[s++]){if(s>t){if(5e3<=++r){s=o,m.a.dc(Error("'Too much recursion' after processing "+r+" task groups."));break}t=o}try{e()}catch(e){m.a.dc(e)}}}function i(){e(),s=o=n.length=0}var n=[],o=0,a=1,s=0;return{scheduler:t.MutationObserver?function(e){var t=r.createElement("div");return new MutationObserver(e).observe(t,{attributes:!0}),function(){t.classList.toggle("foo")}}(i):r&&"onreadystatechange"in r.createElement("script")?function(e){var t=r.createElement("script");t.onreadystatechange=function(){t.onreadystatechange=null,r.documentElement.removeChild(t),t=null,e()},r.documentElement.appendChild(t)}:function(e){setTimeout(e,0)},Za:function(e){return o||m.Z.scheduler(i),n[o++]=e,a++},cancel:function(e){(e-=a-o)>=s&&e<o&&(n[e]=null)},resetForTesting:function(){var e=o-s;return s=o=n.length=0,e},rd:e}}(),m.b("tasks",m.Z),m.b("tasks.schedule",m.Z.Za),m.b("tasks.runEarly",m.Z.rd),m.Aa={throttle:function(e,t){e.throttleEvaluation=t;var r=null;return m.B({read:e,write:function(i){clearTimeout(r),r=m.a.setTimeout(function(){e(i)},t)}})},rateLimit:function(e,t){var r,i,n;"number"==typeof t?r=t:(r=t.timeout,i=t.method),e.gb=!1,n="notifyWhenChangesStop"==i?c:u,e.Wa(function(e){return n(e,r)})},deferred:function(t,r){if(!0!==r)throw Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled.");t.gb||(t.gb=!0,t.Wa(function(r){var i,n=!1;return function(){if(!n){m.Z.cancel(i),i=m.Z.Za(r);try{n=!0,t.notifySubscribers(e,"dirty")}finally{n=!1}}}}))},notify:function(e,t){e.equalityComparer="always"==t?null:l}};var g={undefined:1,boolean:1,number:1,string:1};m.b("extenders",m.Aa),m.zc=function(e,t,r){this.$=e,this.jb=t,this.Pc=r,this.T=!1,m.H(this,"dispose",this.k)},m.zc.prototype.k=function(){this.T=!0,this.Pc()},m.K=function(){m.a.ab(this,v),v.ub(this)};var _="change",v={ub:function(e){e.F={change:[]},e.Qb=1},Y:function(e,t,r){var i=this;r=r||_;var n=new m.zc(i,t?e.bind(t):e,function(){m.a.Na(i.F[r],n),i.Ka&&i.Ka(r)});return i.ua&&i.ua(r),i.F[r]||(i.F[r]=[]),i.F[r].push(n),n},notifySubscribers:function(e,t){if(t=t||_,t===_&&this.Kb(),this.Ra(t)){var r=t===_&&this.Fc||this.F[t].slice(0);try{m.l.Xb();for(var i,n=0;i=r[n];++n)i.T||i.jb(e)}finally{m.l.end()}}},Pa:function(){return this.Qb},Zc:function(e){return this.Pa()!==e},Kb:function(){++this.Qb},Wa:function(e){var t,r,i,n,o=this,a=m.I(o);o.Ja||(o.Ja=o.notifySubscribers,o.notifySubscribers=d);var s=e(function(){o.Ha=!1,a&&n===o&&(n=o.Mb?o.Mb():o());var e=r||o.Ua(i,n);r=t=!1,e&&o.Ja(i=n)});o.Pb=function(e){o.Fc=o.F[_].slice(0),o.Ha=t=!0,n=e,s()},o.Ob=function(e){t||(i=e,o.Ja(e,"beforeChange"))},o.Hc=function(){o.Ua(i,o.p(!0))&&(r=!0)}},Ra:function(e){return this.F[e]&&this.F[e].length},Xc:function(e){if(e)return this.F[e]&&this.F[e].length||0;var t=0;return m.a.D(this.F,function(e,r){"dirty"!==e&&(t+=r.length)}),t},Ua:function(e,t){return!this.equalityComparer||!this.equalityComparer(e,t)},extend:function(e){var t=this;return e&&m.a.D(e,function(e,r){var i=m.Aa[e];"function"==typeof i&&(t=i(t,r)||t)}),t}};m.H(v,"subscribe",v.Y),m.H(v,"extend",v.extend),m.H(v,"getSubscriptionsCount",v.Xc),m.a.la&&m.a.$a(v,Function.prototype),m.K.fn=v,m.lc=function(e){return null!=e&&"function"==typeof e.Y&&"function"==typeof e.notifySubscribers},m.b("subscribable",m.K),m.b("isSubscribable",m.lc),m.xa=m.l=function(){function e(e){i.push(r),r=e}function t(){r=i.pop()}var r,i=[],n=0;return{Xb:e,end:t,sc:function(e){if(r){if(!m.lc(e))throw Error("Only subscribable things can act as dependencies");r.jb.call(r.Lc,e,e.Gc||(e.Gc=++n))}},w:function(r,i,n){try{return e(),r.apply(i,n||[])}finally{t()}},Ca:function(){if(r)return r.m.Ca()},Va:function(){if(r)return r.Va}}}(),m.b("computedContext",m.xa),m.b("computedContext.getDependenciesCount",m.xa.Ca),m.b("computedContext.isInitial",m.xa.Va),m.b("ignoreDependencies",m.wd=m.l.w);var y=m.a.bc("_latestValue");m.O=function(e){function t(){return 0<arguments.length?(t.Ua(t[y],arguments[0])&&(t.ia(),t[y]=arguments[0],t.ha()),this):(m.l.sc(t),t[y])}return t[y]=e,m.a.la||m.a.extend(t,m.K.fn),m.K.fn.ub(t),m.a.ab(t,C),m.options.deferUpdates&&m.Aa.deferred(t,!0),t};var C={equalityComparer:l,p:function(){return this[y]},ha:function(){this.notifySubscribers(this[y])},ia:function(){this.notifySubscribers(this[y],"beforeChange")}};m.a.la&&m.a.$a(C,m.K.fn);var b=m.O.md="__ko_proto__";C[b]=m.O,m.Qa=function(t,r){return null!==t&&t!==e&&t[b]!==e&&(t[b]===r||m.Qa(t[b],r))},m.I=function(e){return m.Qa(e,m.O)},m.Da=function(e){return!!("function"==typeof e&&e[b]===m.O||"function"==typeof e&&e[b]===m.B&&e.$c)},m.b("observable",m.O),m.b("isObservable",m.I),m.b("isWriteableObservable",m.Da),m.b("isWritableObservable",m.Da),m.b("observable.fn",C),m.H(C,"peek",C.p),m.H(C,"valueHasMutated",C.ha),m.H(C,"valueWillMutate",C.ia),m.ma=function(e){if("object"!=typeof(e=e||[])||!("length"in e))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");return e=m.O(e),m.a.ab(e,m.ma.fn),e.extend({trackArrayChanges:!0})},m.ma.fn={remove:function(e){for(var t=this.p(),r=[],i="function"!=typeof e||m.I(e)?function(t){return t===e}:e,n=0;n<t.length;n++){var o=t[n];i(o)&&(0===r.length&&this.ia(),r.push(o),t.splice(n,1),n--)}return r.length&&this.ha(),r},removeAll:function(t){if(t===e){var r=this.p(),i=r.slice(0);return this.ia(),r.splice(0,r.length),this.ha(),i}return t?this.remove(function(e){return 0<=m.a.o(t,e)}):[]},destroy:function(e){var t=this.p(),r="function"!=typeof e||m.I(e)?function(t){return t===e}:e;this.ia();for(var i=t.length-1;0<=i;i--)r(t[i])&&(t[i]._destroy=!0);this.ha()},destroyAll:function(t){return t===e?this.destroy(function(){return!0}):t?this.destroy(function(e){return 0<=m.a.o(t,e)}):[]},indexOf:function(e){var t=this();return m.a.o(t,e)},replace:function(e,t){var r=this.indexOf(e);0<=r&&(this.ia(),this.p()[r]=t,this.ha())}},m.a.la&&m.a.$a(m.ma.fn,m.O.fn),m.a.r("pop push reverse shift sort splice unshift".split(" "),function(e){m.ma.fn[e]=function(){var t=this.p();this.ia(),this.Yb(t,e,arguments);var r=t[e].apply(t,arguments);return this.ha(),r===t?this:r}}),m.a.r(["slice"],function(e){m.ma.fn[e]=function(){var t=this();return t[e].apply(t,arguments)}}),m.b("observableArray",m.ma),m.Aa.trackArrayChanges=function(t,r){function i(){if(!a){a=!0,o=t.notifySubscribers,t.notifySubscribers=function(e,t){return t&&t!==_||++l,o.apply(this,arguments)};var e=[].concat(t.p()||[]);s=null,n=t.Y(function(r){if(r=[].concat(r||[]),t.Ra("arrayChange")){var i;(!s||1<l)&&(s=m.a.lb(e,r,t.kb)),i=s}e=r,s=null,l=0,i&&i.length&&t.notifySubscribers(i,"arrayChange")})}}if(t.kb={},r&&"object"==typeof r&&m.a.extend(t.kb,r),t.kb.sparse=!0,!t.Yb){var n,o,a=!1,s=null,l=0,u=t.ua,c=t.Ka;t.ua=function(e){u&&u.call(t,e),"arrayChange"===e&&i()},t.Ka=function(r){c&&c.call(t,r),"arrayChange"!==r||t.Ra("arrayChange")||(o&&(t.notifySubscribers=o,o=e),n.k(),a=!1)},t.Yb=function(e,t,r){function i(e,t,r){return n[n.length]={status:e,value:t,index:r}}if(a&&!l){var n=[],o=e.length,u=r.length,c=0;switch(t){case"push":c=o;case"unshift":for(t=0;t<u;t++)i("added",r[t],c+t);break;case"pop":c=o-1;case"shift":o&&i("deleted",e[c],c);break;case"splice":t=Math.min(Math.max(0,0>r[0]?o+r[0]:r[0]),o);for(var o=1===u?o:Math.min(t+(r[1]||0),o),u=t+u-2,c=Math.max(o,u),d=[],h=[],p=2;t<c;++t,++p)t<o&&h.push(i("deleted",e[t],t)),t<u&&d.push(i("added",r[p],t));m.a.hc(h,d);break;default:return}s=n}}}};var S=m.a.bc("_state");m.m=m.B=function(t,r,i){function n(){if(0<arguments.length){if("function"!=typeof o)throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");return o.apply(a.sb,arguments),this}return m.l.sc(n),(a.V||a.t&&n.Sa())&&n.U(),a.M}if("object"==typeof t?i=t:(i=i||{},t&&(i.read=t)),"function"!=typeof i.read)throw Error("Pass a function that returns the value of the ko.computed");var o=i.write,a={M:e,da:!0,V:!0,Ta:!1,Hb:!1,T:!1,Ya:!1,t:!1,od:i.read,sb:r||i.owner,i:i.disposeWhenNodeIsRemoved||i.i||null,ya:i.disposeWhen||i.ya,pb:null,s:{},L:0,fc:null};return n[S]=a,n.$c="function"==typeof o,m.a.la||m.a.extend(n,m.K.fn),m.K.fn.ub(n),m.a.ab(n,w),i.pure?(a.Ya=!0,a.t=!0,m.a.extend(n,T)):i.deferEvaluation&&m.a.extend(n,A),m.options.deferUpdates&&m.Aa.deferred(n,!0),a.i&&(a.Hb=!0,a.i.nodeType||(a.i=null)),a.t||i.deferEvaluation||n.U(),a.i&&n.ca()&&m.a.G.qa(a.i,a.pb=function(){n.k()}),n};var w={equalityComparer:l,Ca:function(){return this[S].L},Sb:function(e,t,r){if(this[S].Ya&&t===this)throw Error("A 'pure' computed must not be called recursively");this[S].s[e]=r,r.Ia=this[S].L++,r.pa=t.Pa()},Sa:function(){var e,t,r=this[S].s;for(e in r)if(r.hasOwnProperty(e)&&(t=r[e],this.oa&&t.$.Ha||t.$.Zc(t.pa)))return!0},gd:function(){this.oa&&!this[S].Ta&&this.oa(!1)},ca:function(){var e=this[S];return e.V||0<e.L},qd:function(){this.Ha?this[S].V&&(this[S].da=!0):this.ec()},yc:function(e){if(e.gb&&!this[S].i){var t=e.Y(this.gd,this,"dirty"),r=e.Y(this.qd,this);return{$:e,k:function(){t.k(),r.k()}}}return e.Y(this.ec,this)},ec:function(){var e=this,t=e.throttleEvaluation;t&&0<=t?(clearTimeout(this[S].fc),this[S].fc=m.a.setTimeout(function(){e.U(!0)},t)):e.oa?e.oa(!0):e.U(!0)},U:function(e){var t=this[S],r=t.ya,i=!1;if(!t.Ta&&!t.T){if(t.i&&!m.a.qb(t.i)||r&&r()){if(!t.Hb)return void this.k()}else t.Hb=!1;t.Ta=!0;try{i=this.Vc(e)}finally{t.Ta=!1}return t.L||this.k(),i}},Vc:function(t){var r=this[S],i=!1,n=r.Ya?e:!r.L,o={Mc:this,Oa:r.s,ob:r.L};return m.l.Xb({Lc:o,jb:p,m:this,Va:n}),r.s={},r.L=0,o=this.Uc(r,o),this.Ua(r.M,o)&&(r.t||this.notifySubscribers(r.M,"beforeChange"),r.M=o,r.t?this.Kb():t&&this.notifySubscribers(r.M),i=!0),n&&this.notifySubscribers(r.M,"awake"),i},Uc:function(e,t){try{var r=e.od;return e.sb?r.call(e.sb):r()}finally{m.l.end(),t.ob&&!e.t&&m.a.D(t.Oa,h),e.da=e.V=!1}},p:function(e){var t=this[S];return(t.V&&(e||!t.L)||t.t&&this.Sa())&&this.U(),t.M},Wa:function(e){m.K.fn.Wa.call(this,e),this.Mb=function(){return this[S].da?this.U():this[S].V=!1,this[S].M},this.oa=function(e){this.Ob(this[S].M),this[S].V=!0,e&&(this[S].da=!0),this.Pb(this)}},k:function(){var e=this[S];!e.t&&e.s&&m.a.D(e.s,function(e,t){t.k&&t.k()}),e.i&&e.pb&&m.a.G.tc(e.i,e.pb),e.s=null,e.L=0,e.T=!0,e.da=!1,e.V=!1,e.t=!1,e.i=null}},T={ua:function(e){var t=this,r=t[S];if(!r.T&&r.t&&"change"==e){if(r.t=!1,r.da||t.Sa())r.s=null,r.L=0,t.U()&&t.Kb();else{var i=[];m.a.D(r.s,function(e,t){i[t.Ia]=e}),m.a.r(i,function(e,i){var n=r.s[e],o=t.yc(n.$);o.Ia=i,o.pa=n.pa,r.s[e]=o})}r.T||t.notifySubscribers(r.M,"awake")}},Ka:function(t){var r=this[S];r.T||"change"!=t||this.Ra("change")||(m.a.D(r.s,function(e,t){t.k&&(r.s[e]={$:t.$,Ia:t.Ia,pa:t.pa},t.k())}),r.t=!0,this.notifySubscribers(e,"asleep"))},Pa:function(){var e=this[S];return e.t&&(e.da||this.Sa())&&this.U(),m.K.fn.Pa.call(this)}},A={ua:function(e){"change"!=e&&"beforeChange"!=e||this.p()}};m.a.la&&m.a.$a(w,m.K.fn);var E=m.O.md;m.m[E]=m.O,w[E]=m.m,m.bd=function(e){return m.Qa(e,m.m)},m.cd=function(e){return m.Qa(e,m.m)&&e[S]&&e[S].Ya},m.b("computed",m.m),m.b("dependentObservable",m.m),m.b("isComputed",m.bd),m.b("isPureComputed",m.cd),m.b("computed.fn",w),m.H(w,"peek",w.p),m.H(w,"dispose",w.k),m.H(w,"isActive",w.ca),m.H(w,"getDependenciesCount",w.Ca),m.rc=function(e,t){return"function"==typeof e?m.m(e,t,{pure:!0}):(e=m.a.extend({},e),e.pure=!0,m.m(e,t))},m.b("pureComputed",m.rc),function(){function t(n,o,a){if(a=a||new i,"object"!=typeof(n=o(n))||null===n||n===e||n instanceof RegExp||n instanceof Date||n instanceof String||n instanceof Number||n instanceof Boolean)return n;var s=n instanceof Array?[]:{};return a.save(n,s),r(n,function(r){var i=o(n[r]);switch(typeof i){case"boolean":case"number":case"string":case"function":s[r]=i;break;case"object":case"undefined":var l=a.get(i);s[r]=l!==e?l:t(i,o,a)}}),s}function r(e,t){if(e instanceof Array){for(var r=0;r<e.length;r++)t(r);"function"==typeof e.toJSON&&t("toJSON")}else for(r in e)t(r)}function i(){this.keys=[],this.Lb=[]}m.Ac=function(e){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return t(e,function(e){for(var t=0;m.I(e)&&10>t;t++)e=e();return e})},m.toJSON=function(e,t,r){return e=m.Ac(e),m.a.Gb(e,t,r)},i.prototype={save:function(e,t){var r=m.a.o(this.keys,e);0<=r?this.Lb[r]=t:(this.keys.push(e),this.Lb.push(t))},get:function(t){return t=m.a.o(this.keys,t),0<=t?this.Lb[t]:e}}}(),m.b("toJS",m.Ac),m.b("toJSON",m.toJSON),function(){m.j={u:function(t){switch(m.a.A(t)){case"option":return!0===t.__ko__hasDomDataOptionValue__?m.a.e.get(t,m.d.options.zb):7>=m.a.C?t.getAttributeNode("value")&&t.getAttributeNode("value").specified?t.value:t.text:t.value;case"select":return 0<=t.selectedIndex?m.j.u(t.options[t.selectedIndex]):e;default:return t.value}},ja:function(t,r,i){switch(m.a.A(t)){case"option":switch(typeof r){case"string":m.a.e.set(t,m.d.options.zb,e),"__ko__hasDomDataOptionValue__"in t&&delete t.__ko__hasDomDataOptionValue__,t.value=r;break;default:m.a.e.set(t,m.d.options.zb,r),t.__ko__hasDomDataOptionValue__=!0,t.value="number"==typeof r?r:""}break;case"select":""!==r&&null!==r||(r=e);for(var n,o=-1,a=0,s=t.options.length;a<s;++a)if((n=m.j.u(t.options[a]))==r||""==n&&r===e){o=a;break}(i||0<=o||r===e&&1<t.size)&&(t.selectedIndex=o);break;default:null!==r&&r!==e||(r=""),t.value=r}}}}(),m.b("selectExtensions",m.j),m.b("selectExtensions.readValue",m.j.u),m.b("selectExtensions.writeValue",m.j.ja),m.h=function(){function e(e){e=m.a.cb(e),123===e.charCodeAt(0)&&(e=e.slice(1,-1));var t,r=[],a=e.match(i),s=[],l=0;if(a){a.push(",");for(var u,c=0;u=a[c];++c){var d=u.charCodeAt(0);if(44===d){if(0>=l){r.push(t&&s.length?{key:t,value:s.join("")}:{unknown:t||s.join("")}),t=l=0,s=[];continue}}else if(58===d){if(!l&&!t&&1===s.length){t=s.pop();continue}}else 47===d&&c&&1<u.length?(d=a[c-1].match(n))&&!o[d[0]]&&(e=e.substr(e.indexOf(u)+1),a=e.match(i),a.push(","),c=-1,u="/"):40===d||123===d||91===d?++l:41===d||125===d||93===d?--l:t||s.length||34!==d&&39!==d||(u=u.slice(1,-1));s.push(u)}}return r}var t=["true","false","null","undefined"],r=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,i=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),n=/[\])"'A-Za-z0-9_$]+$/,o={in:1,return:1,typeof:1},a={};return{va:[],ga:a,Ab:e,Xa:function(i,n){function o(e,i){var n;if(!c){var d=m.getBindingHandler(e);if(d&&d.preprocess&&!(i=d.preprocess(i,e,o)))return;(d=a[e])&&(n=i,0<=m.a.o(t,n)?n=!1:(d=n.match(r),n=null!==d&&(d[1]?"Object("+d[1]+")"+d[2]:n)),d=n),d&&l.push("'"+e+"':function(_z){"+n+"=_z}")}u&&(i="function(){return "+i+" }"),s.push("'"+e+"':"+i)}n=n||{};var s=[],l=[],u=n.valueAccessors,c=n.bindingParams,d="string"==typeof i?e(i):i;return m.a.r(d,function(e){o(e.key||e.unknown,e.value)}),l.length&&o("_ko_property_writers","{"+l.join(",")+" }"),s.join(",")},fd:function(e,t){for(var r=0;r<e.length;r++)if(e[r].key==t)return!0;return!1},Ga:function(e,t,r,i,n){e&&m.I(e)?!m.Da(e)||n&&e.p()===i||e(i):(e=t.get("_ko_property_writers"))&&e[r]&&e[r](i)}}}(),m.b("expressionRewriting",m.h),m.b("expressionRewriting.bindingRewriteValidators",m.h.va),m.b("expressionRewriting.parseObjectLiteral",m.h.Ab),m.b("expressionRewriting.preProcessBindings",m.h.Xa),m.b("expressionRewriting._twoWayBindings",m.h.ga),m.b("jsonExpressionRewriting",m.h),m.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",m.h.Xa),function(){function e(e){return 8==e.nodeType&&a.test(o?e.text:e.nodeValue)}function t(e){return 8==e.nodeType&&s.test(o?e.text:e.nodeValue)}function i(r,i){for(var n=r,o=1,a=[];n=n.nextSibling;){if(t(n)&&0===--o)return a;a.push(n),e(n)&&o++}if(!i)throw Error("Cannot find closing comment tag to match: "+r.nodeValue);return null}function n(e,t){var r=i(e,t);return r?0<r.length?r[r.length-1].nextSibling:e.nextSibling:null}var o=r&&"\x3c!--test--\x3e"===r.createComment("test").text,a=o?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,s=o?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,l={ul:!0,ol:!0};m.f={aa:{},childNodes:function(t){return e(t)?i(t):t.childNodes},za:function(t){if(e(t)){t=m.f.childNodes(t);for(var r=0,i=t.length;r<i;r++)m.removeNode(t[r])}else m.a.rb(t)},fa:function(t,r){if(e(t)){m.f.za(t);for(var i=t.nextSibling,n=0,o=r.length;n<o;n++)i.parentNode.insertBefore(r[n],i)}else m.a.fa(t,r)},qc:function(t,r){e(t)?t.parentNode.insertBefore(r,t.nextSibling):t.firstChild?t.insertBefore(r,t.firstChild):t.appendChild(r)},kc:function(t,r,i){i?e(t)?t.parentNode.insertBefore(r,i.nextSibling):i.nextSibling?t.insertBefore(r,i.nextSibling):t.appendChild(r):m.f.qc(t,r)},firstChild:function(r){return e(r)?!r.nextSibling||t(r.nextSibling)?null:r.nextSibling:r.firstChild},nextSibling:function(r){return e(r)&&(r=n(r)),r.nextSibling&&t(r.nextSibling)?null:r.nextSibling},Yc:e,vd:function(e){return(e=(o?e.text:e.nodeValue).match(a))?e[1]:null},oc:function(r){if(l[m.a.A(r)]){var i=r.firstChild;if(i)do{if(1===i.nodeType){var o;o=i.firstChild;var a=null;if(o)do{if(a)a.push(o);else if(e(o)){var s=n(o,!0);s?o=s:a=[o]}else t(o)&&(a=[o])}while(o=o.nextSibling);if(o=a)for(a=i.nextSibling,s=0;s<o.length;s++)a?r.insertBefore(o[s],a):r.appendChild(o[s])}}while(i=i.nextSibling)}}}}(),m.b("virtualElements",m.f),m.b("virtualElements.allowedBindings",m.f.aa),m.b("virtualElements.emptyNode",m.f.za),m.b("virtualElements.insertAfter",m.f.kc),m.b("virtualElements.prepend",m.f.qc),m.b("virtualElements.setDomNodeChildren",m.f.fa),function(){m.S=function(){this.Kc={}},m.a.extend(m.S.prototype,{nodeHasBindings:function(e){switch(e.nodeType){case 1:return null!=e.getAttribute("data-bind")||m.g.getComponentNameForNode(e);case 8:return m.f.Yc(e);default:return!1}},getBindings:function(e,t){var r=this.getBindingsString(e,t),r=r?this.parseBindingsString(r,t,e):null;return m.g.Rb(r,e,t,!1)},getBindingAccessors:function(e,t){var r=this.getBindingsString(e,t),r=r?this.parseBindingsString(r,t,e,{valueAccessors:!0}):null;return m.g.Rb(r,e,t,!0)},getBindingsString:function(e){switch(e.nodeType){case 1:return e.getAttribute("data-bind");case 8:return m.f.vd(e);default:return null}},parseBindingsString:function(e,t,r,i){try{var n,o=this.Kc,a=e+(i&&i.valueAccessors||"");if(!(n=o[a])){var s,l="with($context){with($data||{}){return{"+m.h.Xa(e,i)+"}}}";s=new Function("$context","$element",l),n=o[a]=s}return n(t,r)}catch(t){throw t.message="Unable to parse bindings.\nBindings value: "+e+"\nMessage: "+t.message,t}}}),m.S.instance=new m.S}(),m.b("bindingProvider",m.S),function(){function r(e){return function(){return e}}function i(e){return e()}function o(e){return m.a.Ea(m.l.w(e),function(t,r){return function(){return e()[r]}})}function a(e,t,i){return"function"==typeof e?o(e.bind(null,t,i)):m.a.Ea(e,r)}function s(e,t){return o(this.getBindings.bind(this,e,t))}function l(e,t,r){var i,n=m.f.firstChild(t),o=m.S.instance,a=o.preprocessNode;if(a){for(;i=n;)n=m.f.nextSibling(i),a.call(o,i);n=m.f.firstChild(t)}for(;i=n;)n=m.f.nextSibling(i),u(e,i,r)}function u(e,t,r){var i=!0,n=1===t.nodeType;n&&m.f.oc(t),(n&&r||m.S.instance.nodeHasBindings(t))&&(i=d(t,null,e,r).shouldBindDescendants),i&&!p[m.a.A(t)]&&l(e,t,!n)}function c(e){var t=[],r={},i=[];return m.a.D(e,function n(o){if(!r[o]){var a=m.getBindingHandler(o);a&&(a.after&&(i.push(o),m.a.r(a.after,function(t){if(e[t]){if(-1!==m.a.o(i,t))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+i.join(", "));n(t)}}),i.length--),t.push({key:o,jc:a})),r[o]=!0}}),t}function d(t,r,n,o){var a=m.a.e.get(t,f);if(!r){if(a)throw Error("You cannot apply bindings multiple times to the same element.");m.a.e.set(t,f,!0)}!a&&o&&m.xc(t,n);var l;if(r&&"function"!=typeof r)l=r;else{var u=m.S.instance,d=u.getBindingAccessors||s,h=m.B(function(){return(l=r?r(n,t):d.call(u,t,n))&&n.Q&&n.Q(),l},null,{i:t});l&&h.ca()||(h=null)}var p;if(l){var g=h?function(e){return function(){return i(h()[e])}}:function(e){return l[e]},_=function(){return m.a.Ea(h?h():l,i)};_.get=function(e){return l[e]&&i(g(e))},_.has=function(e){return e in l},o=c(l),m.a.r(o,function(r){var i=r.jc.init,o=r.jc.update,a=r.key;if(8===t.nodeType&&!m.f.aa[a])throw Error("The binding '"+a+"' cannot be used with virtual elements");try{"function"==typeof i&&m.l.w(function(){var r=i(t,g(a),_,n.$data,n);if(r&&r.controlsDescendantBindings){if(p!==e)throw Error("Multiple bindings ("+p+" and "+a+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");p=a}}),"function"==typeof o&&m.B(function(){o(t,g(a),_,n.$data,n)},null,{i:t})}catch(e){throw e.message='Unable to process binding "'+a+": "+l[a]+'"\nMessage: '+e.message,e}})}return{shouldBindDescendants:p===e}}function h(e){return e&&e instanceof m.R?e:new m.R(e)}m.d={};var p={script:!0,textarea:!0,template:!0};m.getBindingHandler=function(e){return m.d[e]},m.R=function(t,r,i,n,o){function a(){var e=d?t():t,o=m.a.c(e);return r?(r.Q&&r.Q(),m.a.extend(c,r),c.Q=u):(c.$parents=[],c.$root=o,c.ko=m),c.$rawData=e,c.$data=o,i&&(c[i]=o),n&&n(c,r,o),c.$data}function s(){return l&&!m.a.Tb(l)}var l,u,c=this,d="function"==typeof t&&!m.I(t);o&&o.exportDependencies?a():(u=m.B(a,null,{ya:s,i:!0}),u.ca()&&(c.Q=u,u.equalityComparer=null,l=[],u.Dc=function(t){l.push(t),m.a.G.qa(t,function(t){m.a.Na(l,t),l.length||(u.k(),c.Q=u=e)})}))},m.R.prototype.createChildContext=function(e,t,r,i){return new m.R(e,this,t,function(e,t){e.$parentContext=t,e.$parent=t.$data,e.$parents=(t.$parents||[]).slice(0),e.$parents.unshift(e.$parent),r&&r(e)},i)},m.R.prototype.extend=function(e){return new m.R(this.Q||this.$data,this,null,function(t,r){t.$rawData=r.$rawData,m.a.extend(t,"function"==typeof e?e():e)})},m.R.prototype.ac=function(e,t){return this.createChildContext(e,t,null,{exportDependencies:!0})};var f=m.a.e.J(),g=m.a.e.J();m.xc=function(e,t){if(2!=arguments.length)return m.a.e.get(e,g);m.a.e.set(e,g,t),t.Q&&t.Q.Dc(e)},m.La=function(e,t,r){return 1===e.nodeType&&m.f.oc(e),d(e,t,h(r),!0)},m.Ic=function(e,t,r){return r=h(r),m.La(e,a(t,r,e),r)},m.hb=function(e,t){1!==t.nodeType&&8!==t.nodeType||l(h(e),t,!0)},m.Ub=function(e,r){if(!n&&t.jQuery&&(n=t.jQuery),r&&1!==r.nodeType&&8!==r.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");r=r||t.document.body,u(h(e),r,!0)},m.nb=function(t){switch(t.nodeType){case 1:case 8:var r=m.xc(t);if(r)return r;if(t.parentNode)return m.nb(t.parentNode)}return e},m.Oc=function(t){return(t=m.nb(t))?t.$data:e},m.b("bindingHandlers",m.d),m.b("applyBindings",m.Ub),m.b("applyBindingsToDescendants",m.hb),m.b("applyBindingAccessorsToNode",m.La),m.b("applyBindingsToNode",m.Ic),m.b("contextFor",m.nb),m.b("dataFor",m.Oc)}(),function(e){function t(t,i){var a,s=n.hasOwnProperty(t)?n[t]:e;s?s.Y(i):(s=n[t]=new m.K,s.Y(i),r(t,function(e,r){var i=!(!r||!r.synchronous);o[t]={definition:e,dd:i},delete n[t],a||i?s.notifySubscribers(e):m.Z.Za(function(){s.notifySubscribers(e)})}),a=!0)}function r(e,t){i("getConfig",[e],function(r){r?i("loadComponent",[e,r],function(e){t(e,r)}):t(null,null)})}function i(t,r,n,o){o||(o=m.g.loaders.slice(0));var a=o.shift();if(a){var s=a[t];if(s){var l=!1;if(s.apply(a,r.concat(function(e){l?n(null):null!==e?n(e):i(t,r,n,o)}))!==e&&(l=!0,!a.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.")}else i(t,r,n,o)}else n(null)}var n={},o={};m.g={get:function(r,i){var n=o.hasOwnProperty(r)?o[r]:e;n?n.dd?m.l.w(function(){i(n.definition)}):m.Z.Za(function(){i(n.definition)}):t(r,i)},$b:function(e){delete o[e]},Nb:i},m.g.loaders=[],m.b("components",m.g),m.b("components.get",m.g.get),m.b("components.clearCachedDefinition",m.g.$b)}(),function(){function e(e,t,r,i){function n(){0==--s&&i(o)}var o={},s=2,l=r.template;r=r.viewModel,l?a(t,l,function(t){m.g.Nb("loadTemplate",[e,t],function(e){o.template=e,n()})}):n(),r?a(t,r,function(t){m.g.Nb("loadViewModel",[e,t],function(e){o[c]=e,n()})}):n()}function i(e,t,r){if("function"==typeof t)r(function(e){return new t(e)});else if("function"==typeof t[c])r(t[c]);else if("instance"in t){var n=t.instance;r(function(){return n})}else"viewModel"in t?i(e,t.viewModel,r):e("Unknown viewModel value: "+t)}function n(e){switch(m.a.A(e)){case"script":return m.a.na(e.text);case"textarea":return m.a.na(e.value);case"template":if(o(e.content))return m.a.wa(e.content.childNodes)}return m.a.wa(e.childNodes)}function o(e){return t.DocumentFragment?e instanceof DocumentFragment:e&&11===e.nodeType}function a(e,r,i){"string"==typeof r.require?s||t.require?(s||t.require)([r.require],i):e("Uses require, but no AMD loader is present"):i(r)}function l(e){return function(t){throw Error("Component '"+e+"': "+t)}}var u={};m.g.register=function(e,t){if(!t)throw Error("Invalid configuration for "+e);if(m.g.wb(e))throw Error("Component "+e+" is already registered");u[e]=t},m.g.wb=function(e){return u.hasOwnProperty(e)},m.g.ud=function(e){delete u[e],m.g.$b(e)},m.g.cc={getConfig:function(e,t){t(u.hasOwnProperty(e)?u[e]:null)},loadComponent:function(t,r,i){var n=l(t);a(n,r,function(r){e(t,n,r,i)})},loadTemplate:function(e,i,a){if(e=l(e),"string"==typeof i)a(m.a.na(i));else if(i instanceof Array)a(i);else if(o(i))a(m.a.W(i.childNodes));else if(i.element)if(i=i.element,t.HTMLElement?i instanceof HTMLElement:i&&i.tagName&&1===i.nodeType)a(n(i));else if("string"==typeof i){var s=r.getElementById(i);s?a(n(s)):e("Cannot find element with ID "+i)}else e("Unknown element type: "+i);else e("Unknown template value: "+i)},loadViewModel:function(e,t,r){i(l(e),t,r)}};var c="createViewModel";m.b("components.register",m.g.register),m.b("components.isRegistered",m.g.wb),m.b("components.unregister",m.g.ud),m.b("components.defaultLoader",m.g.cc),m.g.loaders.push(m.g.cc),m.g.Ec=u}(),function(){function e(e,r){var i=e.getAttribute("params");if(i){var i=t.parseBindingsString(i,r,e,{valueAccessors:!0,bindingParams:!0}),i=m.a.Ea(i,function(t){return m.m(t,null,{i:e})}),n=m.a.Ea(i,function(t){var r=t.p();return t.ca()?m.m({read:function(){return m.a.c(t())},write:m.Da(r)&&function(e){t()(e)},i:e}):r});return n.hasOwnProperty("$raw")||(n.$raw=i),n}return{$raw:{}}}m.g.getComponentNameForNode=function(e){var t=m.a.A(e);if(m.g.wb(t)&&(-1!=t.indexOf("-")||"[object HTMLUnknownElement]"==""+e||8>=m.a.C&&e.tagName===t))return t},m.g.Rb=function(t,r,i,n){if(1===r.nodeType){var o=m.g.getComponentNameForNode(r);if(o){if(t=t||{},t.component)throw Error('Cannot use the "component" binding on a custom element matching a component');var a={name:o,params:e(r,i)};t.component=n?function(){return a}:a}}return t};var t=new m.S;9>m.a.C&&(m.g.register=function(e){return function(t){return r.createElement(t),e.apply(this,arguments)}}(m.g.register),r.createDocumentFragment=function(e){return function(){var t,r=e(),i=m.g.Ec;for(t in i)i.hasOwnProperty(t)&&r.createElement(t);return r}}(r.createDocumentFragment))}(),function(e){function t(e,t,r){if(!(t=t.template))throw Error("Component '"+e+"' has no template");e=m.a.wa(t),m.f.fa(r,e)}function r(e,t,r,i){var n=e.createViewModel;return n?n.call(e,i,{element:t,templateNodes:r}):i}var i=0;m.d.component={init:function(e,n,o,a,s){function l(){var e=u&&u.dispose;"function"==typeof e&&e.call(u),c=u=null}var u,c,d=m.a.W(m.f.childNodes(e));return m.a.G.qa(e,l),m.m(function(){var o,a,h=m.a.c(n());if("string"==typeof h?o=h:(o=m.a.c(h.name),a=m.a.c(h.params)),!o)throw Error("No component name specified");var p=c=++i;m.g.get(o,function(i){if(c===p){if(l(),!i)throw Error("Unknown component '"+o+"'");t(o,i,e);var n=r(i,e,d,a);i=s.createChildContext(n,void 0,function(e){e.$component=n,e.$componentTemplateNodes=d}),u=n,m.hb(i,e)}})},null,{i:e}),{controlsDescendantBindings:!0}}},m.f.aa.component=!0}();var x={class:"className",for:"htmlFor"};m.d.attr={update:function(t,r){var i=m.a.c(r())||{};m.a.D(i,function(r,i){i=m.a.c(i);var n=!1===i||null===i||i===e;n&&t.removeAttribute(r),8>=m.a.C&&r in x?(r=x[r],n?t.removeAttribute(r):t[r]=i):n||t.setAttribute(r,i.toString()),"name"===r&&m.a.vc(t,n?"":i.toString())})}},function(){m.d.checked={after:["value","attr"],init:function(t,r,i){function n(){var e=t.checked,n=p?a():e;if(!m.xa.Va()&&(!l||e)){var o=m.l.w(r);if(c){var s=d?o.p():o;h!==n?(e&&(m.a.ra(s,n,!0),m.a.ra(s,h,!1)),h=n):m.a.ra(s,n,e),d&&m.Da(o)&&o(s)}else m.h.Ga(o,i,"checked",n,!0)}}function o(){var e=m.a.c(r());t.checked=c?0<=m.a.o(e,a()):s?e:a()===e}var a=m.rc(function(){return i.has("checkedValue")?m.a.c(i.get("checkedValue")):i.has("value")?m.a.c(i.get("value")):t.value}),s="checkbox"==t.type,l="radio"==t.type;if(s||l){var u=r(),c=s&&m.a.c(u)instanceof Array,d=!(c&&u.push&&u.splice),h=c?a():e,p=l||c;l&&!t.name&&m.d.uniqueName.init(t,function(){return!0}),m.m(n,null,{i:t}),m.a.q(t,"click",n),m.m(o,null,{i:t}),u=e}}},m.h.ga.checked=!0,m.d.checkedValue={update:function(e,t){e.value=m.a.c(t())}}}(),m.d.css={update:function(e,t){var r=m.a.c(t());null!==r&&"object"==typeof r?m.a.D(r,function(t,r){r=m.a.c(r),m.a.fb(e,t,r)}):(r=m.a.cb(String(r||"")),m.a.fb(e,e.__ko__cssValue,!1),e.__ko__cssValue=r,m.a.fb(e,r,!0))}},m.d.enable={update:function(e,t){var r=m.a.c(t());r&&e.disabled?e.removeAttribute("disabled"):r||e.disabled||(e.disabled=!0)}},m.d.disable={update:function(e,t){m.d.enable.update(e,function(){return!m.a.c(t())})}},m.d.event={init:function(e,t,r,i,n){var o=t()||{};m.a.D(o,function(o){"string"==typeof o&&m.a.q(e,o,function(e){var a,s=t()[o];if(s){try{var l=m.a.W(arguments);i=n.$data,l.unshift(i),a=s.apply(i,l)}finally{!0!==a&&(e.preventDefault?e.preventDefault():e.returnValue=!1)}!1===r.get(o+"Bubble")&&(e.cancelBubble=!0,e.stopPropagation&&e.stopPropagation())}})})}},m.d.foreach={mc:function(e){return function(){var t=e(),r=m.a.Bb(t);return r&&"number"!=typeof r.length?(m.a.c(t),{foreach:r.data,as:r.as,includeDestroyed:r.includeDestroyed,afterAdd:r.afterAdd,beforeRemove:r.beforeRemove, -afterRender:r.afterRender,beforeMove:r.beforeMove,afterMove:r.afterMove,templateEngine:m.X.vb}):{foreach:t,templateEngine:m.X.vb}}},init:function(e,t){return m.d.template.init(e,m.d.foreach.mc(t))},update:function(e,t,r,i,n){return m.d.template.update(e,m.d.foreach.mc(t),r,i,n)}},m.h.va.foreach=!1,m.f.aa.foreach=!0,m.d.hasfocus={init:function(e,t,r){function i(i){e.__ko_hasfocusUpdating=!0;var n=e.ownerDocument;if("activeElement"in n){var o;try{o=n.activeElement}catch(e){o=n.body}i=o===e}n=t(),m.h.Ga(n,r,"hasfocus",i,!0),e.__ko_hasfocusLastValue=i,e.__ko_hasfocusUpdating=!1}var n=i.bind(null,!0),o=i.bind(null,!1);m.a.q(e,"focus",n),m.a.q(e,"focusin",n),m.a.q(e,"blur",o),m.a.q(e,"focusout",o)},update:function(e,t){var r=!!m.a.c(t());e.__ko_hasfocusUpdating||e.__ko_hasfocusLastValue===r||(r?e.focus():e.blur(),!r&&e.__ko_hasfocusLastValue&&e.ownerDocument.body.focus(),m.l.w(m.a.Fa,null,[e,r?"focusin":"focusout"]))}},m.h.ga.hasfocus=!0,m.d.hasFocus=m.d.hasfocus,m.h.ga.hasFocus=!0,m.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(e,t){m.a.Eb(e,t())}},f("if"),f("ifnot",!1,!0),f("with",!0,!1,function(e,t){return e.ac(t)});var P={};m.d.options={init:function(e){if("select"!==m.a.A(e))throw Error("options binding applies only to SELECT elements");for(;0<e.length;)e.remove(0);return{controlsDescendantBindings:!0}},update:function(t,r,i){function n(){return m.a.Ma(t.options,function(e){return e.selected})}function o(e,t,r){var i=typeof t;return"function"==i?t(e):"string"==i?e[t]:r}function a(e,r){if(f&&c)m.j.ja(t,m.a.c(i.get("value")),!0);else if(p.length){var n=0<=m.a.o(p,m.j.u(r[0]));m.a.wc(r[0],n),f&&!n&&m.l.w(m.a.Fa,null,[t,"change"])}}var s=t.multiple,l=0!=t.length&&s?t.scrollTop:null,u=m.a.c(r()),c=i.get("valueAllowUnset")&&i.has("value"),d=i.get("optionsIncludeDestroyed");r={};var h,p=[];c||(s?p=m.a.ib(n(),m.j.u):0<=t.selectedIndex&&p.push(m.j.u(t.options[t.selectedIndex]))),u&&(void 0===u.length&&(u=[u]),h=m.a.Ma(u,function(t){return d||t===e||null===t||!m.a.c(t._destroy)}),i.has("optionsCaption")&&null!==(u=m.a.c(i.get("optionsCaption")))&&u!==e&&h.unshift(P));var f=!1;r.beforeRemove=function(e){t.removeChild(e)},u=a,i.has("optionsAfterRender")&&"function"==typeof i.get("optionsAfterRender")&&(u=function(t,r){a(0,r),m.l.w(i.get("optionsAfterRender"),null,[r[0],t!==P?t:e])}),m.a.Db(t,h,function(r,n,a){return a.length&&(p=!c&&a[0].selected?[m.j.u(a[0])]:[],f=!0),n=t.ownerDocument.createElement("option"),r===P?(m.a.bb(n,i.get("optionsCaption")),m.j.ja(n,e)):(a=o(r,i.get("optionsValue"),r),m.j.ja(n,m.a.c(a)),r=o(r,i.get("optionsText"),a),m.a.bb(n,r)),[n]},r,u),m.l.w(function(){c?m.j.ja(t,m.a.c(i.get("value")),!0):(s?p.length&&n().length<p.length:p.length&&0<=t.selectedIndex?m.j.u(t.options[t.selectedIndex])!==p[0]:p.length||0<=t.selectedIndex)&&m.a.Fa(t,"change")}),m.a.Sc(t),l&&20<Math.abs(l-t.scrollTop)&&(t.scrollTop=l)}},m.d.options.zb=m.a.e.J(),m.d.selectedOptions={after:["options","foreach"],init:function(e,t,r){m.a.q(e,"change",function(){var i=t(),n=[];m.a.r(e.getElementsByTagName("option"),function(e){e.selected&&n.push(m.j.u(e))}),m.h.Ga(i,r,"selectedOptions",n)})},update:function(e,t){if("select"!=m.a.A(e))throw Error("values binding applies only to SELECT elements");var r=m.a.c(t()),i=e.scrollTop;r&&"number"==typeof r.length&&m.a.r(e.getElementsByTagName("option"),function(e){var t=0<=m.a.o(r,m.j.u(e));e.selected!=t&&m.a.wc(e,t)}),e.scrollTop=i}},m.h.ga.selectedOptions=!0,m.d.style={update:function(t,r){var i=m.a.c(r()||{});m.a.D(i,function(r,i){i=m.a.c(i),null!==i&&i!==e&&!1!==i||(i=""),t.style[r]=i})}},m.d.submit={init:function(e,t,r,i,n){if("function"!=typeof t())throw Error("The value for a submit binding must be a function");m.a.q(e,"submit",function(r){var i,o=t();try{i=o.call(n.$data,e)}finally{!0!==i&&(r.preventDefault?r.preventDefault():r.returnValue=!1)}})}},m.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(e,t){m.a.bb(e,t())}},m.f.aa.text=!0,function(){if(t&&t.navigator)var r=function(e){if(e)return parseFloat(e[1])},i=t.opera&&t.opera.version&&parseInt(t.opera.version()),n=t.navigator.userAgent,o=r(n.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),a=r(n.match(/Firefox\/([^ ]*)/));if(10>m.a.C)var s=m.a.e.J(),l=m.a.e.J(),u=function(e){var t=this.activeElement;(t=t&&m.a.e.get(t,l))&&t(e)},c=function(e,t){var r=e.ownerDocument;m.a.e.get(r,s)||(m.a.e.set(r,s,!0),m.a.q(r,"selectionchange",u)),m.a.e.set(e,l,t)};m.d.textInput={init:function(t,r,n){function s(e,r){m.a.q(t,e,r)}function l(){var i=m.a.c(r());null!==i&&i!==e||(i=""),p!==e&&i===p?m.a.setTimeout(l,4):t.value!==i&&(f=i,t.value=i)}function u(){h||(p=t.value,h=m.a.setTimeout(d,4))}function d(){clearTimeout(h),p=h=e;var i=t.value;f!==i&&(f=i,m.h.Ga(r(),n,"textInput",i))}var h,p,f=t.value,g=9==m.a.C?u:d;10>m.a.C?(s("propertychange",function(e){"value"===e.propertyName&&g(e)}),8==m.a.C&&(s("keyup",d),s("keydown",d)),8<=m.a.C&&(c(t,g),s("dragend",u))):(s("input",d),5>o&&"textarea"===m.a.A(t)?(s("keydown",u),s("paste",u),s("cut",u)):11>i?s("keydown",u):4>a&&(s("DOMAutoComplete",d),s("dragdrop",d),s("drop",d))),s("change",d),m.m(l,null,{i:t})}},m.h.ga.textInput=!0,m.d.textinput={preprocess:function(e,t,r){r("textInput",e)}}}(),m.d.uniqueName={init:function(e,t){if(t()){var r="ko_unique_"+ ++m.d.uniqueName.Nc;m.a.vc(e,r)}}},m.d.uniqueName.Nc=0,m.d.value={after:["options","foreach"],init:function(e,t,r){if("input"!=e.tagName.toLowerCase()||"checkbox"!=e.type&&"radio"!=e.type){var i=["change"],n=r.get("valueUpdate"),o=!1,a=null;n&&("string"==typeof n&&(n=[n]),m.a.ta(i,n),i=m.a.Wb(i));var s=function(){a=null,o=!1;var i=t(),n=m.j.u(e);m.h.Ga(i,r,"value",n)};!m.a.C||"input"!=e.tagName.toLowerCase()||"text"!=e.type||"off"==e.autocomplete||e.form&&"off"==e.form.autocomplete||-1!=m.a.o(i,"propertychange")||(m.a.q(e,"propertychange",function(){o=!0}),m.a.q(e,"focus",function(){o=!1}),m.a.q(e,"blur",function(){o&&s()})),m.a.r(i,function(t){var r=s;m.a.sd(t,"after")&&(r=function(){a=m.j.u(e),m.a.setTimeout(s,0)},t=t.substring(5)),m.a.q(e,t,r)});var l=function(){var i=m.a.c(t()),n=m.j.u(e);if(null!==a&&i===a)m.a.setTimeout(l,0);else if(i!==n)if("select"===m.a.A(e)){var o=r.get("valueAllowUnset"),n=function(){m.j.ja(e,i,o)};n(),o||i===m.j.u(e)?m.a.setTimeout(n,0):m.l.w(m.a.Fa,null,[e,"change"])}else m.j.ja(e,i)};m.m(l,null,{i:e})}else m.La(e,{checkedValue:t})},update:function(){}},m.h.ga.value=!0,m.d.visible={update:function(e,t){var r=m.a.c(t()),i="none"!=e.style.display;r&&!i?e.style.display="":!r&&i&&(e.style.display="none")}},function(e){m.d[e]={init:function(t,r,i,n,o){return m.d.event.init.call(this,t,function(){var t={};return t[e]=r(),t},i,n,o)}}}("click"),m.P=function(){},m.P.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource")},m.P.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock")},m.P.prototype.makeTemplateSource=function(e,t){if("string"==typeof e){t=t||r;var i=t.getElementById(e);if(!i)throw Error("Cannot find template with ID "+e);return new m.v.n(i)}if(1==e.nodeType||8==e.nodeType)return new m.v.sa(e);throw Error("Unknown template type: "+e)},m.P.prototype.renderTemplate=function(e,t,r,i){return e=this.makeTemplateSource(e,i),this.renderTemplateSource(e,t,r,i)},m.P.prototype.isTemplateRewritten=function(e,t){return!1===this.allowTemplateRewriting||this.makeTemplateSource(e,t).data("isRewritten")},m.P.prototype.rewriteTemplate=function(e,t,r){e=this.makeTemplateSource(e,r),t=t(e.text()),e.text(t),e.data("isRewritten",!0)},m.b("templateEngine",m.P),m.Ib=function(){function e(e,t,r,i){e=m.h.Ab(e);for(var n=m.h.va,o=0;o<e.length;o++){var a=e[o].key;if(n.hasOwnProperty(a)){var s=n[a];if("function"==typeof s){if(a=s(e[o].value))throw Error(a)}else if(!s)throw Error("This template engine does not support the '"+a+"' binding within its templates")}}return r="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+m.h.Xa(e,{valueAccessors:!0})+" } })()},'"+r.toLowerCase()+"')",i.createJavaScriptEvaluatorBlock(r)+t}var t=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,r=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Tc:function(e,t,r){t.isTemplateRewritten(e,r)||t.rewriteTemplate(e,function(e){return m.Ib.jd(e,t)},r)},jd:function(i,n){return i.replace(t,function(t,r,i,o,a){return e(a,r,i,n)}).replace(r,function(t,r){return e(r,"\x3c!-- ko --\x3e","#comment",n)})},Jc:function(e,t){return m.N.yb(function(r,i){var n=r.nextSibling;n&&n.nodeName.toLowerCase()===t&&m.La(n,e,i)})}}}(),m.b("__tr_ambtns",m.Ib.Jc),function(){m.v={},m.v.n=function(e){if(this.n=e){var t=m.a.A(e);this.eb="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},m.v.n.prototype.text=function(){var e=1===this.eb?"text":2===this.eb?"value":"innerHTML";if(0==arguments.length)return this.n[e];var t=arguments[0];"innerHTML"===e?m.a.Eb(this.n,t):this.n[e]=t};var t=m.a.e.J()+"_";m.v.n.prototype.data=function(e){if(1===arguments.length)return m.a.e.get(this.n,t+e);m.a.e.set(this.n,t+e,arguments[1])};var r=m.a.e.J();m.v.n.prototype.nodes=function(){var t=this.n;if(0==arguments.length)return(m.a.e.get(t,r)||{}).mb||(3===this.eb?t.content:4===this.eb?t:e);m.a.e.set(t,r,{mb:arguments[0]})},m.v.sa=function(e){this.n=e},m.v.sa.prototype=new m.v.n,m.v.sa.prototype.text=function(){if(0==arguments.length){var t=m.a.e.get(this.n,r)||{};return t.Jb===e&&t.mb&&(t.Jb=t.mb.innerHTML),t.Jb}m.a.e.set(this.n,r,{Jb:arguments[0]})},m.b("templateSources",m.v),m.b("templateSources.domElement",m.v.n),m.b("templateSources.anonymousTemplate",m.v.sa)}(),function(){function t(e,t,r){var i;for(t=m.f.nextSibling(t);e&&(i=e)!==t;)e=m.f.nextSibling(i),r(i,e)}function r(e,r){if(e.length){var i=e[0],n=e[e.length-1],o=i.parentNode,a=m.S.instance,s=a.preprocessNode;if(s){if(t(i,n,function(e,t){var r=e.previousSibling,o=s.call(a,e);o&&(e===i&&(i=o[0]||t),e===n&&(n=o[o.length-1]||r))}),e.length=0,!i)return;i===n?e.push(i):(e.push(i,n),m.a.Ba(e,o))}t(i,n,function(e){1!==e.nodeType&&8!==e.nodeType||m.Ub(r,e)}),t(i,n,function(e){1!==e.nodeType&&8!==e.nodeType||m.N.Cc(e,[r])}),m.a.Ba(e,o)}}function i(e){return e.nodeType?e:0<e.length?e[0]:null}function n(e,t,n,o,s){s=s||{};var l=(e&&i(e)||n||{}).ownerDocument,u=s.templateEngine||a;if(m.Ib.Tc(n,u,l),n=u.renderTemplate(n,o,s,l),"number"!=typeof n.length||0<n.length&&"number"!=typeof n[0].nodeType)throw Error("Template engine must return an array of DOM nodes");switch(l=!1,t){case"replaceChildren":m.f.fa(e,n),l=!0;break;case"replaceNode":m.a.uc(e,n),l=!0;break;case"ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+t)}return l&&(r(n,o),s.afterRender&&m.l.w(s.afterRender,null,[n,o.$data])),n}function o(e,t,r){return m.I(e)?e():"function"==typeof e?e(t,r):e}var a;m.Fb=function(t){if(t!=e&&!(t instanceof m.P))throw Error("templateEngine must inherit from ko.templateEngine");a=t},m.Cb=function(t,r,s,l,u){if(s=s||{},(s.templateEngine||a)==e)throw Error("Set a template engine before calling renderTemplate");if(u=u||"replaceChildren",l){var c=i(l);return m.B(function(){var e=r&&r instanceof m.R?r:new m.R(r,null,null,null,{exportDependencies:!0}),a=o(t,e.$data,e),e=n(l,u,a,e,s);"replaceNode"==u&&(l=e,c=i(l))},null,{ya:function(){return!c||!m.a.qb(c)},i:c&&"replaceNode"==u?c.parentNode:c})}return m.N.yb(function(e){m.Cb(t,r,s,e,"replaceNode")})},m.pd=function(t,i,a,s,l){function u(e,t){r(t,d),a.afterRender&&a.afterRender(t,e),d=null}function c(e,r){return d=l.createChildContext(e,a.as,function(e){e.$index=r}),n(null,"ignoreTargetNode",o(t,e,d),d,a)}var d;return m.B(function(){var t=m.a.c(i)||[];void 0===t.length&&(t=[t]),t=m.a.Ma(t,function(t){return a.includeDestroyed||t===e||null===t||!m.a.c(t._destroy)}),m.l.w(m.a.Db,null,[s,t,c,a,u])},null,{i:s})};var s=m.a.e.J();m.d.template={init:function(e,t){var r=m.a.c(t());if("string"==typeof r||r.name)m.f.za(e);else{if("nodes"in r){if(r=r.nodes||[],m.I(r))throw Error('The "nodes" option must be a plain, non-observable array.')}else r=m.f.childNodes(e);r=m.a.nc(r),new m.v.sa(e).nodes(r)}return{controlsDescendantBindings:!0}},update:function(t,r,i,n,o){var a=r();r=m.a.c(a),i=!0,n=null,"string"==typeof r?r={}:(a=r.name,"if"in r&&(i=m.a.c(r.if)),i&&"ifnot"in r&&(i=!m.a.c(r.ifnot))),"foreach"in r?n=m.pd(a||t,i&&r.foreach||[],r,t,o):i?(o="data"in r?o.ac(r.data,r.as):o,n=m.Cb(a||t,o,r,t)):m.f.za(t),o=n,(r=m.a.e.get(t,s))&&"function"==typeof r.k&&r.k(),m.a.e.set(t,s,o&&o.ca()?o:e)}},m.h.va.template=function(e){return e=m.h.Ab(e),1==e.length&&e[0].unknown||m.h.fd(e,"name")?null:"This template engine does not support anonymous templates nested within its templates"},m.f.aa.template=!0}(),m.b("setTemplateEngine",m.Fb),m.b("renderTemplate",m.Cb),m.a.hc=function(e,t,r){if(e.length&&t.length){var i,n,o,a,s;for(i=n=0;(!r||i<r)&&(a=e[n]);++n){for(o=0;s=t[o];++o)if(a.value===s.value){a.moved=s.index,s.moved=a.index,t.splice(o,1),i=o=0;break}i+=o}}},m.a.lb=function(){function e(e,t,r,i,n){var o,a,s,l,u,c=Math.min,d=Math.max,h=[],p=e.length,f=t.length,g=f-p||1,_=p+f+1;for(o=0;o<=p;o++)for(l=s,h.push(s=[]),u=c(f,o+g),a=d(0,o-1);a<=u;a++)s[a]=a?o?e[o-1]===t[a-1]?l[a-1]:c(l[a]||_,s[a-1]||_)+1:a+1:o+1;for(c=[],d=[],g=[],o=p,a=f;o||a;)f=h[o][a]-1,a&&f===h[o][a-1]?d.push(c[c.length]={status:r,value:t[--a],index:a}):o&&f===h[o-1][a]?g.push(c[c.length]={status:i,value:e[--o],index:o}):(--a,--o,n.sparse||c.push({status:"retained",value:t[a]}));return m.a.hc(g,d,!n.dontLimitMoves&&10*p),c.reverse()}return function(t,r,i){return i="boolean"==typeof i?{dontLimitMoves:i}:i||{},t=t||[],r=r||[],t.length<r.length?e(t,r,"added","deleted",i):e(r,t,"deleted","added",i)}}(),m.b("utils.compareArrays",m.a.lb),function(){function t(t,r,i,n,o){var a=[],s=m.B(function(){var e=r(i,o,m.a.Ba(a,t))||[];0<a.length&&(m.a.uc(a,e),n&&m.l.w(n,null,[i,e,o])),a.length=0,m.a.ta(a,e)},null,{i:t,ya:function(){return!m.a.Tb(a)}});return{ea:a,B:s.ca()?s:e}}var r=m.a.e.J(),i=m.a.e.J();m.a.Db=function(n,o,a,s,l){function u(e,t){b=h[t],v!==t&&(T[e]=b),b.tb(v++),m.a.Ba(b.ea,n),g.push(b),C.push(b)}function c(e,t){if(e)for(var r=0,i=t.length;r<i;r++)t[r]&&m.a.r(t[r].ea,function(i){e(i,r,t[r].ka)})}o=o||[],s=s||{};var d=m.a.e.get(n,r)===e,h=m.a.e.get(n,r)||[],p=m.a.ib(h,function(e){return e.ka}),f=m.a.lb(p,o,s.dontLimitMoves),g=[],_=0,v=0,y=[],C=[];o=[];for(var b,S,w,T=[],p=[],A=0;S=f[A];A++)switch(w=S.moved,S.status){case"deleted":w===e&&(b=h[_],b.B&&(b.B.k(),b.B=e),m.a.Ba(b.ea,n).length&&(s.beforeRemove&&(g.push(b),C.push(b),b.ka===i?b=null:o[A]=b),b&&y.push.apply(y,b.ea))),_++;break;case"retained":u(A,_++);break;case"added":w!==e?u(A,w):(b={ka:S.value,tb:m.O(v++)},g.push(b),C.push(b),d||(p[A]=b))}m.a.e.set(n,r,g),c(s.beforeMove,T),m.a.r(y,s.beforeRemove?m.ba:m.removeNode);for(var E,A=0,d=m.f.firstChild(n);b=C[A];A++){for(b.ea||m.a.extend(b,t(n,a,b.ka,l,b.tb)),_=0;f=b.ea[_];d=f.nextSibling,E=f,_++)f!==d&&m.f.kc(n,f,E);!b.ad&&l&&(l(b.ka,b.ea,b.tb),b.ad=!0)}for(c(s.beforeRemove,o),A=0;A<o.length;++A)o[A]&&(o[A].ka=i);c(s.afterMove,T),c(s.afterAdd,p)}}(),m.b("utils.setDomNodeChildrenFromArrayMapping",m.a.Db),m.X=function(){this.allowTemplateRewriting=!1},m.X.prototype=new m.P,m.X.prototype.renderTemplateSource=function(e,t,r,i){return(t=(9>m.a.C?0:e.nodes)?e.nodes():null)?m.a.W(t.cloneNode(!0).childNodes):(e=e.text(),m.a.na(e,i))},m.X.vb=new m.X,m.Fb(m.X.vb),m.b("nativeTemplateEngine",m.X),function(){m.xb=function(){var e=this.ed=function(){if(!n||!n.tmpl)return 0;try{if(0<=n.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(e){}return 1}();this.renderTemplateSource=function(t,i,o,a){if(a=a||r,o=o||{},2>e)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var s=t.data("precompiled");return s||(s=t.text()||"",s=n.template(null,"{{ko_with $item.koBindingContext}}"+s+"{{/ko_with}}"),t.data("precompiled",s)),t=[i.$data],i=n.extend({koBindingContext:i},o.templateOptions),i=n.tmpl(s,t,i),i.appendTo(a.createElement("div")),n.fragments={},i},this.createJavaScriptEvaluatorBlock=function(e){return"{{ko_code ((function() { return "+e+" })()) }}"},this.addTemplate=function(e,t){r.write("<script type='text/html' id='"+e+"'>"+t+"<\/script>")},0<e&&(n.tmpl.tag.ko_code={open:"__.push($1 || '');"},n.tmpl.tag.ko_with={open:"with($1) {",close:"} "})},m.xb.prototype=new m.P;var e=new m.xb;0<e.ed&&m.Fb(e),m.b("jqueryTmplTemplateEngine",m.xb)}()})}()}(),define("ThirdParty/knockout-es5",[],function(){"use strict";function e(e,r){if(!e)throw new Error("When calling ko.track, you must pass an object as the first parameter.");var n=this,o=t(e,!0);return r=r||Object.getOwnPropertyNames(e),r.forEach(function(t){if(t!==d&&t!==h&&!(t in o)){var r=e[t],a=r instanceof Array,s=n.isObservable(r)?r:a?n.observableArray(r):n.observable(r);Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:s,set:n.isWriteableObservable(s)?s:void 0}),o[t]=s,a&&i(n,s)}}),e}function t(e,t){var r=e[d];return!r&&t&&(r={},Object.defineProperty(e,d,{value:r})),r}function r(t,r,i){var n=this,o={owner:t,deferEvaluation:!0};if("function"==typeof i)o.read=i;else{if("value"in i)throw new Error('For ko.defineProperty, you must not specify a "value" for the property. You must provide a "get" function.');if("function"!=typeof i.get)throw new Error('For ko.defineProperty, the third parameter must be either an evaluator function, or an options object containing a function called "get".');o.read=i.get,o.write=i.set}return t[r]=n.computed(o),e.call(n,t,[r]),t}function i(e,t){var r=null;e.computed(function(){r&&(r.dispose(),r=null);var i=t();i instanceof Array&&(r=n(e,t,i))})}function n(e,t,r){return o(e,r).subscribe(t)}function o(e,t){var r=t[h];if(!r){r=new e.subscribable,Object.defineProperty(t,h,{value:r});var i={};a(t,r,i),s(e,t,r,i)}return r}function a(e,t,r){["pop","push","reverse","shift","sort","splice","unshift"].forEach(function(i){var n=e[i];e[i]=function(){var e=n.apply(this,arguments);return!0!==r.pause&&t.notifySubscribers(this),e}})}function s(e,t,r,i){["remove","removeAll","destroy","destroyAll","replace"].forEach(function(n){Object.defineProperty(t,n,{enumerable:!1,value:function(){var o;i.pause=!0;try{o=e.observableArray.fn[n].apply(e.observableArray(t),arguments)}finally{i.pause=!1}return r.notifySubscribers(t),o}})})}function l(e,r){if(!e)return null;var i=t(e,!1);return i&&i[r]||null}function u(e,t){var r=l(e,t);r&&r.valueHasMutated()}function c(t){t.track=e,t.getObservable=l,t.valueHasMutated=u,t.defineProperty=r}var d="__knockoutObservables",h="__knockoutSubscribable";return{attachToKo:c}}),define("Widgets/SvgPathBindingHandler",[],function(){"use strict";var e="http://www.w3.org/2000/svg";return{register:function(t){t.bindingHandlers.cesiumSvgPath={init:function(r,i){var n=document.createElementNS(e,"svg:svg");n.setAttribute("class","cesium-svgPath-svg");var o=document.createElementNS(e,"path");return n.appendChild(o),t.virtualElements.setDomNodeChildren(r,[n]),t.computed({read:function(){var e=t.unwrap(i());o.setAttribute("d",t.unwrap(e.path));var r=t.unwrap(e.width),a=t.unwrap(e.height);n.setAttribute("width",r),n.setAttribute("height",a),n.setAttribute("viewBox","0 0 "+r+" "+a),e.css&&n.setAttribute("class","cesium-svgPath-svg "+t.unwrap(e.css))},disposeWhenNodeIsRemoved:r}),{controlsDescendantBindings:!0}}},t.virtualElements.allowedBindings.cesiumSvgPath=!0}}}),define("ThirdParty/knockout",["./knockout-3.4.2","./knockout-es5","../Widgets/SvgPathBindingHandler"],function(e,t,r){"use strict";return t.attachToKo(e),r.register(e),e}),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("ThirdParty/NoSleep",[],t):"object"==typeof exports?exports.NoSleep=t():e.NoSleep=t()}(this,function(){return function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,i){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var n=function(){function e(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,r,i){return r&&e(t.prototype,r),i&&e(t,i),t}}(),o=r(1),a="undefined"!=typeof navigator&&parseFloat((""+(/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))<10&&!window.MSStream,s=function(){function e(){i(this,e),a?this.noSleepTimer=null:(this.noSleepVideo=document.createElement("video"),this.noSleepVideo.setAttribute("playsinline",""),this.noSleepVideo.setAttribute("src",o),this.noSleepVideo.addEventListener("timeupdate",function(e){this.noSleepVideo.currentTime>.5&&(this.noSleepVideo.currentTime=Math.random())}.bind(this)))}return n(e,[{key:"enable",value:function(){a?(this.disable(),this.noSleepTimer=window.setInterval(function(){window.location.href="/",window.setTimeout(window.stop,0)},15e3)):this.noSleepVideo.play()}},{key:"disable",value:function(){a?this.noSleepTimer&&(window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause()}}]),e}();e.exports=s},function(e,t,r){"use strict";e.exports="data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA="}])}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("ThirdParty/pako_inflate",[],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pako=e()}}(function(){return function e(t,r,i){function n(a,s){if(!r[a]){if(!t[a]){var l="function"==typeof require&&require;if(!s&&l)return l(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[a]={exports:{}};t[a][0].call(c.exports,function(e){var r=t[a][1][e];return n(r||e)},c,c.exports,e,t,r,i)}return r[a].exports}for(var o="function"==typeof require&&require,a=0;a<i.length;a++)n(i[a]);return n}({1:[function(e,t,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;r.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)r.hasOwnProperty(i)&&(e[i]=r[i])}}return e},r.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var n={arraySet:function(e,t,r,i,n){if(t.subarray&&e.subarray)return void e.set(t.subarray(r,r+i),n);for(var o=0;o<i;o++)e[n+o]=t[r+o]},flattenChunks:function(e){var t,r,i,n,o,a;for(i=0,t=0,r=e.length;t<r;t++)i+=e[t].length;for(a=new Uint8Array(i),n=0,t=0,r=e.length;t<r;t++)o=e[t],a.set(o,n),n+=o.length;return a}},o={arraySet:function(e,t,r,i,n){for(var o=0;o<i;o++)e[n+o]=t[r+o]},flattenChunks:function(e){return[].concat.apply([],e)}};r.setTyped=function(e){e?(r.Buf8=Uint8Array,r.Buf16=Uint16Array,r.Buf32=Int32Array,r.assign(r,n)):(r.Buf8=Array,r.Buf16=Array,r.Buf32=Array,r.assign(r,o))},r.setTyped(i)},{}],2:[function(e,t,r){"use strict";function i(e,t){if(t<65537&&(e.subarray&&a||!e.subarray&&o))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var r="",i=0;i<t;i++)r+=String.fromCharCode(e[i]);return r}var n=e("./common"),o=!0,a=!0;try{String.fromCharCode.apply(null,[0])}catch(e){o=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(e){a=!1}for(var s=new n.Buf8(256),l=0;l<256;l++)s[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;s[254]=s[254]=1,r.string2buf=function(e){var t,r,i,o,a,s=e.length,l=0;for(o=0;o<s;o++)r=e.charCodeAt(o),55296==(64512&r)&&o+1<s&&56320==(64512&(i=e.charCodeAt(o+1)))&&(r=65536+(r-55296<<10)+(i-56320),o++),l+=r<128?1:r<2048?2:r<65536?3:4;for(t=new n.Buf8(l),a=0,o=0;a<l;o++)r=e.charCodeAt(o),55296==(64512&r)&&o+1<s&&56320==(64512&(i=e.charCodeAt(o+1)))&&(r=65536+(r-55296<<10)+(i-56320),o++),r<128?t[a++]=r:r<2048?(t[a++]=192|r>>>6,t[a++]=128|63&r):r<65536?(t[a++]=224|r>>>12,t[a++]=128|r>>>6&63,t[a++]=128|63&r):(t[a++]=240|r>>>18,t[a++]=128|r>>>12&63,t[a++]=128|r>>>6&63,t[a++]=128|63&r);return t},r.buf2binstring=function(e){return i(e,e.length)},r.binstring2buf=function(e){for(var t=new n.Buf8(e.length),r=0,i=t.length;r<i;r++)t[r]=e.charCodeAt(r);return t},r.buf2string=function(e,t){var r,n,o,a,l=t||e.length,u=new Array(2*l);for(n=0,r=0;r<l;)if((o=e[r++])<128)u[n++]=o;else if((a=s[o])>4)u[n++]=65533,r+=a-1;else{for(o&=2===a?31:3===a?15:7;a>1&&r<l;)o=o<<6|63&e[r++],a--;a>1?u[n++]=65533:o<65536?u[n++]=o:(o-=65536,u[n++]=55296|o>>10&1023,u[n++]=56320|1023&o)}return i(u,n)},r.utf8border=function(e,t){var r;for(t=t||e.length,t>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+s[e[r]]>t?r:t}},{"./common":1}],3:[function(e,t,r){"use strict";function i(e,t,r,i){for(var n=65535&e|0,o=e>>>16&65535|0,a=0;0!==r;){a=r>2e3?2e3:r,r-=a;do{n=n+t[i++]|0,o=o+n|0}while(--a);n%=65521,o%=65521}return n|o<<16|0}t.exports=i},{}],4:[function(e,t,r){"use strict";t.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1, -Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(e,t,r){"use strict";function i(e,t,r,i){var o=n,a=i+r;e^=-1;for(var s=i;s<a;s++)e=e>>>8^o[255&(e^t[s])];return-1^e}var n=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var i=0;i<8;i++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=i},{}],6:[function(e,t,r){"use strict";function i(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}t.exports=i},{}],7:[function(e,t,r){"use strict";t.exports=function(e,t){var r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E;r=e.state,i=e.next_in,A=e.input,n=i+(e.avail_in-5),o=e.next_out,E=e.output,a=o-(t-e.avail_out),s=o+(e.avail_out-257),l=r.dmax,u=r.wsize,c=r.whave,d=r.wnext,h=r.window,p=r.hold,f=r.bits,m=r.lencode,g=r.distcode,_=(1<<r.lenbits)-1,v=(1<<r.distbits)-1;e:do{f<15&&(p+=A[i++]<<f,f+=8,p+=A[i++]<<f,f+=8),y=m[p&_];t:for(;;){if(C=y>>>24,p>>>=C,f-=C,0===(C=y>>>16&255))E[o++]=65535&y;else{if(!(16&C)){if(0==(64&C)){y=m[(65535&y)+(p&(1<<C)-1)];continue t}if(32&C){r.mode=12;break e}e.msg="invalid literal/length code",r.mode=30;break e}b=65535&y,C&=15,C&&(f<C&&(p+=A[i++]<<f,f+=8),b+=p&(1<<C)-1,p>>>=C,f-=C),f<15&&(p+=A[i++]<<f,f+=8,p+=A[i++]<<f,f+=8),y=g[p&v];r:for(;;){if(C=y>>>24,p>>>=C,f-=C,!(16&(C=y>>>16&255))){if(0==(64&C)){y=g[(65535&y)+(p&(1<<C)-1)];continue r}e.msg="invalid distance code",r.mode=30;break e}if(S=65535&y,C&=15,f<C&&(p+=A[i++]<<f,(f+=8)<C&&(p+=A[i++]<<f,f+=8)),(S+=p&(1<<C)-1)>l){e.msg="invalid distance too far back",r.mode=30;break e}if(p>>>=C,f-=C,C=o-a,S>C){if((C=S-C)>c&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(w=0,T=h,0===d){if(w+=u-C,C<b){b-=C;do{E[o++]=h[w++]}while(--C);w=o-S,T=E}}else if(d<C){if(w+=u+d-C,(C-=d)<b){b-=C;do{E[o++]=h[w++]}while(--C);if(w=0,d<b){C=d,b-=C;do{E[o++]=h[w++]}while(--C);w=o-S,T=E}}}else if(w+=d-C,C<b){b-=C;do{E[o++]=h[w++]}while(--C);w=o-S,T=E}for(;b>2;)E[o++]=T[w++],E[o++]=T[w++],E[o++]=T[w++],b-=3;b&&(E[o++]=T[w++],b>1&&(E[o++]=T[w++]))}else{w=o-S;do{E[o++]=E[w++],E[o++]=E[w++],E[o++]=E[w++],b-=3}while(b>2);b&&(E[o++]=E[w++],b>1&&(E[o++]=E[w++]))}break}}break}}while(i<n&&o<s);b=f>>3,i-=b,f-=b<<3,p&=(1<<f)-1,e.next_in=i,e.next_out=o,e.avail_in=i<n?n-i+5:5-(i-n),e.avail_out=o<s?s-o+257:257-(o-s),r.hold=p,r.bits=f}},{}],8:[function(e,t,r){"use strict";function i(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function n(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new v.Buf16(320),this.work=new v.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function o(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=F,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new v.Buf32(me),t.distcode=t.distdyn=new v.Buf32(ge),t.sane=1,t.back=-1,D):M}function a(e){var t;return e&&e.state?(t=e.state,t.wsize=0,t.whave=0,t.wnext=0,o(e)):M}function s(e,t){var r,i;return e&&e.state?(i=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?M:(null!==i.window&&i.wbits!==t&&(i.window=null),i.wrap=r,i.wbits=t,a(e))):M}function l(e,t){var r,i;return e?(i=new n,e.state=i,i.window=null,r=s(e,t),r!==D&&(e.state=null),r):M}function u(e){return l(e,_e)}function c(e){if(ve){var t;for(g=new v.Buf32(512),_=new v.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(S(T,e.lens,0,288,g,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;S(A,e.lens,0,32,_,0,e.work,{bits:5}),ve=!1}e.lencode=g,e.lenbits=9,e.distcode=_,e.distbits=5}function d(e,t,r,i){var n,o=e.state;return null===o.window&&(o.wsize=1<<o.wbits,o.wnext=0,o.whave=0,o.window=new v.Buf8(o.wsize)),i>=o.wsize?(v.arraySet(o.window,t,r-o.wsize,o.wsize,0),o.wnext=0,o.whave=o.wsize):(n=o.wsize-o.wnext,n>i&&(n=i),v.arraySet(o.window,t,r-i,n,o.wnext),i-=n,i?(v.arraySet(o.window,t,r-i,i,0),o.wnext=i,o.whave=o.wsize):(o.wnext+=n,o.wnext===o.wsize&&(o.wnext=0),o.whave<o.wsize&&(o.whave+=n))),0}function h(e,t){var r,n,o,a,s,l,u,h,p,f,m,g,_,me,ge,_e,ve,ye,Ce,be,Se,we,Te,Ae,Ee=0,xe=new v.Buf8(4),Pe=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!e||!e.state||!e.output||!e.input&&0!==e.avail_in)return M;r=e.state,r.mode===X&&(r.mode=Q),s=e.next_out,o=e.output,u=e.avail_out,a=e.next_in,n=e.input,l=e.avail_in,h=r.hold,p=r.bits,f=l,m=u,we=D;e:for(;;)switch(r.mode){case F:if(0===r.wrap){r.mode=Q;break}for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(2&r.wrap&&35615===h){r.check=0,xe[0]=255&h,xe[1]=h>>>8&255,r.check=C(r.check,xe,2,0),h=0,p=0,r.mode=B;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&h)<<8)+(h>>8))%31){e.msg="incorrect header check",r.mode=he;break}if((15&h)!==k){e.msg="unknown compression method",r.mode=he;break}if(h>>>=4,p-=4,Se=8+(15&h),0===r.wbits)r.wbits=Se;else if(Se>r.wbits){e.msg="invalid window size",r.mode=he;break}r.dmax=1<<Se,e.adler=r.check=1,r.mode=512&h?q:X,h=0,p=0;break;case B:for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(r.flags=h,(255&r.flags)!==k){e.msg="unknown compression method",r.mode=he;break}if(57344&r.flags){e.msg="unknown header flags set",r.mode=he;break}r.head&&(r.head.text=h>>8&1),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,r.check=C(r.check,xe,2,0)),h=0,p=0,r.mode=U;case U:for(;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.head&&(r.head.time=h),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,xe[2]=h>>>16&255,xe[3]=h>>>24&255,r.check=C(r.check,xe,4,0)),h=0,p=0,r.mode=V;case V:for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.head&&(r.head.xflags=255&h,r.head.os=h>>8),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,r.check=C(r.check,xe,2,0)),h=0,p=0,r.mode=z;case z:if(1024&r.flags){for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.length=h,r.head&&(r.head.extra_len=h),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,r.check=C(r.check,xe,2,0)),h=0,p=0}else r.head&&(r.head.extra=null);r.mode=G;case G:if(1024&r.flags&&(g=r.length,g>l&&(g=l),g&&(r.head&&(Se=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),v.arraySet(r.head.extra,n,a,g,Se)),512&r.flags&&(r.check=C(r.check,n,g,a)),l-=g,a+=g,r.length-=g),r.length))break e;r.length=0,r.mode=H;case H:if(2048&r.flags){if(0===l)break e;g=0;do{Se=n[a+g++],r.head&&Se&&r.length<65536&&(r.head.name+=String.fromCharCode(Se))}while(Se&&g<l);if(512&r.flags&&(r.check=C(r.check,n,g,a)),l-=g,a+=g,Se)break e}else r.head&&(r.head.name=null);r.length=0,r.mode=W;case W:if(4096&r.flags){if(0===l)break e;g=0;do{Se=n[a+g++],r.head&&Se&&r.length<65536&&(r.head.comment+=String.fromCharCode(Se))}while(Se&&g<l);if(512&r.flags&&(r.check=C(r.check,n,g,a)),l-=g,a+=g,Se)break e}else r.head&&(r.head.comment=null);r.mode=j;case j:if(512&r.flags){for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(h!==(65535&r.check)){e.msg="header crc mismatch",r.mode=he;break}h=0,p=0}r.head&&(r.head.hcrc=r.flags>>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=X;break;case q:for(;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}e.adler=r.check=i(h),h=0,p=0,r.mode=Y;case Y:if(0===r.havedict)return e.next_out=s,e.avail_out=u,e.next_in=a,e.avail_in=l,r.hold=h,r.bits=p,O;e.adler=r.check=1,r.mode=X;case X:if(t===x||t===P)break e;case Q:if(r.last){h>>>=7&p,p-=7&p,r.mode=ue;break}for(;p<3;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}switch(r.last=1&h,h>>>=1,p-=1,3&h){case 0:r.mode=Z;break;case 1:if(c(r),r.mode=re,t===P){h>>>=2,p-=2;break e}break;case 2:r.mode=$;break;case 3:e.msg="invalid block type",r.mode=he}h>>>=2,p-=2;break;case Z:for(h>>>=7&p,p-=7&p;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if((65535&h)!=(h>>>16^65535)){e.msg="invalid stored block lengths",r.mode=he;break}if(r.length=65535&h,h=0,p=0,r.mode=K,t===P)break e;case K:r.mode=J;case J:if(g=r.length){if(g>l&&(g=l),g>u&&(g=u),0===g)break e;v.arraySet(o,n,a,g,s),l-=g,a+=g,u-=g,s+=g,r.length-=g;break}r.mode=X;break;case $:for(;p<14;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(r.nlen=257+(31&h),h>>>=5,p-=5,r.ndist=1+(31&h),h>>>=5,p-=5,r.ncode=4+(15&h),h>>>=4,p-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=he;break}r.have=0,r.mode=ee;case ee:for(;r.have<r.ncode;){for(;p<3;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.lens[Pe[r.have++]]=7&h,h>>>=3,p-=3}for(;r.have<19;)r.lens[Pe[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,Te={bits:r.lenbits},we=S(w,r.lens,0,19,r.lencode,0,r.work,Te),r.lenbits=Te.bits,we){e.msg="invalid code lengths set",r.mode=he;break}r.have=0,r.mode=te;case te:for(;r.have<r.nlen+r.ndist;){for(;Ee=r.lencode[h&(1<<r.lenbits)-1],ge=Ee>>>24,_e=Ee>>>16&255,ve=65535&Ee,!(ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(ve<16)h>>>=ge,p-=ge,r.lens[r.have++]=ve;else{if(16===ve){for(Ae=ge+2;p<Ae;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(h>>>=ge,p-=ge,0===r.have){e.msg="invalid bit length repeat",r.mode=he;break}Se=r.lens[r.have-1],g=3+(3&h),h>>>=2,p-=2}else if(17===ve){for(Ae=ge+3;p<Ae;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ge,p-=ge,Se=0,g=3+(7&h),h>>>=3,p-=3}else{for(Ae=ge+7;p<Ae;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ge,p-=ge,Se=0,g=11+(127&h),h>>>=7,p-=7}if(r.have+g>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=he;break}for(;g--;)r.lens[r.have++]=Se}}if(r.mode===he)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=he;break}if(r.lenbits=9,Te={bits:r.lenbits},we=S(T,r.lens,0,r.nlen,r.lencode,0,r.work,Te),r.lenbits=Te.bits,we){e.msg="invalid literal/lengths set",r.mode=he;break}if(r.distbits=6,r.distcode=r.distdyn,Te={bits:r.distbits},we=S(A,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,Te),r.distbits=Te.bits,we){e.msg="invalid distances set",r.mode=he;break}if(r.mode=re,t===P)break e;case re:r.mode=ie;case ie:if(l>=6&&u>=258){e.next_out=s,e.avail_out=u,e.next_in=a,e.avail_in=l,r.hold=h,r.bits=p,b(e,m),s=e.next_out,o=e.output,u=e.avail_out,a=e.next_in,n=e.input,l=e.avail_in,h=r.hold,p=r.bits,r.mode===X&&(r.back=-1);break}for(r.back=0;Ee=r.lencode[h&(1<<r.lenbits)-1],ge=Ee>>>24,_e=Ee>>>16&255,ve=65535&Ee,!(ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(_e&&0==(240&_e)){for(ye=ge,Ce=_e,be=ve;Ee=r.lencode[be+((h&(1<<ye+Ce)-1)>>ye)],ge=Ee>>>24,_e=Ee>>>16&255,ve=65535&Ee,!(ye+ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ye,p-=ye,r.back+=ye}if(h>>>=ge,p-=ge,r.back+=ge,r.length=ve,0===_e){r.mode=le;break}if(32&_e){r.back=-1,r.mode=X;break}if(64&_e){e.msg="invalid literal/length code",r.mode=he;break}r.extra=15&_e,r.mode=ne;case ne:if(r.extra){for(Ae=r.extra;p<Ae;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.length+=h&(1<<r.extra)-1,h>>>=r.extra,p-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=oe;case oe:for(;Ee=r.distcode[h&(1<<r.distbits)-1],ge=Ee>>>24,_e=Ee>>>16&255,ve=65535&Ee,!(ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(0==(240&_e)){for(ye=ge,Ce=_e,be=ve;Ee=r.distcode[be+((h&(1<<ye+Ce)-1)>>ye)],ge=Ee>>>24,_e=Ee>>>16&255,ve=65535&Ee,!(ye+ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ye,p-=ye,r.back+=ye}if(h>>>=ge,p-=ge,r.back+=ge,64&_e){e.msg="invalid distance code",r.mode=he;break}r.offset=ve,r.extra=15&_e,r.mode=ae;case ae:if(r.extra){for(Ae=r.extra;p<Ae;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.offset+=h&(1<<r.extra)-1,h>>>=r.extra,p-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=he;break}r.mode=se;case se:if(0===u)break e;if(g=m-u,r.offset>g){if((g=r.offset-g)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=he;break}g>r.wnext?(g-=r.wnext,_=r.wsize-g):_=r.wnext-g,g>r.length&&(g=r.length),me=r.window}else me=o,_=s-r.offset,g=r.length;g>u&&(g=u),u-=g,r.length-=g;do{o[s++]=me[_++]}while(--g);0===r.length&&(r.mode=ie);break;case le:if(0===u)break e;o[s++]=r.length,u--,r.mode=ie;break;case ue:if(r.wrap){for(;p<32;){if(0===l)break e;l--,h|=n[a++]<<p,p+=8}if(m-=u,e.total_out+=m,r.total+=m,m&&(e.adler=r.check=r.flags?C(r.check,o,m,s-m):y(r.check,o,m,s-m)),m=u,(r.flags?h:i(h))!==r.check){e.msg="incorrect data check",r.mode=he;break}h=0,p=0}r.mode=ce;case ce:if(r.wrap&&r.flags){for(;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(h!==(4294967295&r.total)){e.msg="incorrect length check",r.mode=he;break}h=0,p=0}r.mode=de;case de:we=I;break e;case he:we=R;break e;case pe:return N;case fe:default:return M}return e.next_out=s,e.avail_out=u,e.next_in=a,e.avail_in=l,r.hold=h,r.bits=p,(r.wsize||m!==e.avail_out&&r.mode<he&&(r.mode<ue||t!==E))&&d(e,e.output,e.next_out,m-e.avail_out)?(r.mode=pe,N):(f-=e.avail_in,m-=e.avail_out,e.total_in+=f,e.total_out+=m,r.total+=m,r.wrap&&m&&(e.adler=r.check=r.flags?C(r.check,o,m,e.next_out-m):y(r.check,o,m,e.next_out-m)),e.data_type=r.bits+(r.last?64:0)+(r.mode===X?128:0)+(r.mode===re||r.mode===K?256:0),(0===f&&0===m||t===E)&&we===D&&(we=L),we)}function p(e){if(!e||!e.state)return M;var t=e.state;return t.window&&(t.window=null),e.state=null,D}function f(e,t){var r;return e&&e.state?(r=e.state,0==(2&r.wrap)?M:(r.head=t,t.done=!1,D)):M}function m(e,t){var r,i,n=t.length;return e&&e.state?(r=e.state,0!==r.wrap&&r.mode!==Y?M:r.mode===Y&&(i=1,(i=y(i,t,n,0))!==r.check)?R:d(e,t,n,n)?(r.mode=pe,N):(r.havedict=1,D)):M}var g,_,v=e("../utils/common"),y=e("./adler32"),C=e("./crc32"),b=e("./inffast"),S=e("./inftrees"),w=0,T=1,A=2,E=4,x=5,P=6,D=0,I=1,O=2,M=-2,R=-3,N=-4,L=-5,k=8,F=1,B=2,U=3,V=4,z=5,G=6,H=7,W=8,j=9,q=10,Y=11,X=12,Q=13,Z=14,K=15,J=16,$=17,ee=18,te=19,re=20,ie=21,ne=22,oe=23,ae=24,se=25,le=26,ue=27,ce=28,de=29,he=30,pe=31,fe=32,me=852,ge=592,_e=15,ve=!0;r.inflateReset=a,r.inflateReset2=s,r.inflateResetKeep=o,r.inflateInit=u,r.inflateInit2=l,r.inflate=h,r.inflateEnd=p,r.inflateGetHeader=f,r.inflateSetDictionary=m,r.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":1,"./adler32":3,"./crc32":5,"./inffast":7,"./inftrees":9}],9:[function(e,t,r){"use strict";var i=e("../utils/common"),n=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],o=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],a=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],s=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];t.exports=function(e,t,r,l,u,c,d,h){var p,f,m,g,_,v,y,C,b,S=h.bits,w=0,T=0,A=0,E=0,x=0,P=0,D=0,I=0,O=0,M=0,R=null,N=0,L=new i.Buf16(16),k=new i.Buf16(16),F=null,B=0;for(w=0;w<=15;w++)L[w]=0;for(T=0;T<l;T++)L[t[r+T]]++;for(x=S,E=15;E>=1&&0===L[E];E--);if(x>E&&(x=E),0===E)return u[c++]=20971520,u[c++]=20971520,h.bits=1,0;for(A=1;A<E&&0===L[A];A++);for(x<A&&(x=A),I=1,w=1;w<=15;w++)if(I<<=1,(I-=L[w])<0)return-1;if(I>0&&(0===e||1!==E))return-1;for(k[1]=0,w=1;w<15;w++)k[w+1]=k[w]+L[w];for(T=0;T<l;T++)0!==t[r+T]&&(d[k[t[r+T]]++]=T);if(0===e?(R=F=d,v=19):1===e?(R=n,N-=257,F=o,B-=257,v=256):(R=a,F=s,v=-1),M=0,T=0,w=A,_=c,P=x,D=0,m=-1,O=1<<x,g=O-1,1===e&&O>852||2===e&&O>592)return 1;for(;;){y=w-D,d[T]<v?(C=0,b=d[T]):d[T]>v?(C=F[B+d[T]],b=R[N+d[T]]):(C=96,b=0),p=1<<w-D,f=1<<P,A=f;do{f-=p,u[_+(M>>D)+f]=y<<24|C<<16|b|0}while(0!==f);for(p=1<<w-1;M&p;)p>>=1;if(0!==p?(M&=p-1,M+=p):M=0,T++,0==--L[w]){if(w===E)break;w=t[r+d[T]]}if(w>x&&(M&g)!==m){for(0===D&&(D=x),_+=A,P=w-D,I=1<<P;P+D<E&&!((I-=L[P+D])<=0);)P++,I<<=1;if(O+=1<<P,1===e&&O>852||2===e&&O>592)return 1;m=M&g,u[m]=x<<24|P<<16|_-c|0}}return 0!==M&&(u[_+M]=w-D<<24|64<<16|0),h.bits=x,0}},{"../utils/common":1}],10:[function(e,t,r){"use strict";t.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(e,t,r){"use strict";function i(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}t.exports=i},{}],"/lib/inflate.js":[function(e,t,r){"use strict";function i(e){if(!(this instanceof i))return new i(e);this.options=s.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new d,this.strm.avail_out=0;var r=a.inflateInit2(this.strm,t.windowBits);if(r!==u.Z_OK)throw new Error(c[r]);this.header=new h,a.inflateGetHeader(this.strm,this.header)}function n(e,t){var r=new i(t);if(r.push(e,!0),r.err)throw r.msg||c[r.err];return r.result}function o(e,t){return t=t||{},t.raw=!0,n(e,t)}var a=e("./zlib/inflate"),s=e("./utils/common"),l=e("./utils/strings"),u=e("./zlib/constants"),c=e("./zlib/messages"),d=e("./zlib/zstream"),h=e("./zlib/gzheader"),p=Object.prototype.toString;i.prototype.push=function(e,t){var r,i,n,o,c,d,h=this.strm,f=this.options.chunkSize,m=this.options.dictionary,g=!1;if(this.ended)return!1;i=t===~~t?t:!0===t?u.Z_FINISH:u.Z_NO_FLUSH,"string"==typeof e?h.input=l.binstring2buf(e):"[object ArrayBuffer]"===p.call(e)?h.input=new Uint8Array(e):h.input=e,h.next_in=0,h.avail_in=h.input.length;do{if(0===h.avail_out&&(h.output=new s.Buf8(f),h.next_out=0,h.avail_out=f),r=a.inflate(h,u.Z_NO_FLUSH),r===u.Z_NEED_DICT&&m&&(d="string"==typeof m?l.string2buf(m):"[object ArrayBuffer]"===p.call(m)?new Uint8Array(m):m,r=a.inflateSetDictionary(this.strm,d)),r===u.Z_BUF_ERROR&&!0===g&&(r=u.Z_OK,g=!1),r!==u.Z_STREAM_END&&r!==u.Z_OK)return this.onEnd(r),this.ended=!0,!1;h.next_out&&(0!==h.avail_out&&r!==u.Z_STREAM_END&&(0!==h.avail_in||i!==u.Z_FINISH&&i!==u.Z_SYNC_FLUSH)||("string"===this.options.to?(n=l.utf8border(h.output,h.next_out),o=h.next_out-n,c=l.buf2string(h.output,n),h.next_out=o,h.avail_out=f-o,o&&s.arraySet(h.output,h.output,n,o,0),this.onData(c)):this.onData(s.shrinkBuf(h.output,h.next_out)))),0===h.avail_in&&0===h.avail_out&&(g=!0)}while((h.avail_in>0||0===h.avail_out)&&r!==u.Z_STREAM_END);return r===u.Z_STREAM_END&&(i=u.Z_FINISH),i===u.Z_FINISH?(r=a.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===u.Z_OK):i!==u.Z_SYNC_FLUSH||(this.onEnd(u.Z_OK),h.avail_out=0,!0)},i.prototype.onData=function(e){this.chunks.push(e)},i.prototype.onEnd=function(e){e===u.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},r.Inflate=i,r.inflate=n,r.inflateRaw=o,r.ungzip=n},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")}),define("Widgets/subscribeAndEvaluate",["../ThirdParty/knockout"],function(e){"use strict";function t(t,r,i,n,o){return i.call(n,t[r]),e.getObservable(t,r).subscribe(i,n,o)}return t}),define("Widgets/Animation/Animation",["../../Core/Color","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../getElement","../subscribeAndEvaluate"],function(e,t,r,i,n,o,a){"use strict";function s(t){return e.fromCssColorString(window.getComputedStyle(t).getPropertyValue("color"))}function l(e){var t=document.createElementNS(v,e.tagName);for(var r in e)if(e.hasOwnProperty(r)&&"tagName"!==r)if("children"===r){var i,n=e.children.length;for(i=0;i<n;++i)t.appendChild(l(e.children[i]))}else 0===r.indexOf("xlink:")?t.setAttributeNS(y,r.substring(6),e[r]):"textContent"===r?t.textContent=e[r]:t.setAttribute(r,e[r]);return t}function u(e,t,r){var i=document.createElementNS(v,"text");i.setAttribute("x",e),i.setAttribute("y",t),i.setAttribute("class","cesium-animation-svgText");var n=document.createElementNS(v,"tspan");return n.textContent=r,i.appendChild(n),i}function c(e,t,r){e.setAttribute("transform","translate(100,100) rotate("+r+")"),t.setAttribute("transform","rotate("+r+")")}function d(e,t){var r=t.alpha,i=1-r;return P.red=e.red*i+t.red*r,P.green=e.green*i+t.green*r,P.blue=e.blue*i+t.blue*r,P.toCssColorString()}function h(e,t,r){return l({tagName:"g",class:"cesium-animation-rectButton",transform:"translate("+e+","+t+")",children:[{tagName:"rect",class:"cesium-animation-buttonGlow",width:32,height:32,rx:2,ry:2},{tagName:"rect",class:"cesium-animation-buttonMain",width:32,height:32,rx:4,ry:4},{tagName:"use",class:"cesium-animation-buttonPath","xlink:href":r},{tagName:"title",textContent:""}]})}function p(e,t,r){return l({tagName:"g",class:"cesium-animation-rectButton",transform:"translate("+e+","+t+")",children:[{tagName:"use",class:"cesium-animation-buttonGlow","xlink:href":"#animation_pathWingButton"},{tagName:"use",class:"cesium-animation-buttonMain","xlink:href":"#animation_pathWingButton"},{tagName:"use",class:"cesium-animation-buttonPath","xlink:href":r},{tagName:"title",textContent:""}]})}function f(e,t){var r=e._viewModel,i=r.shuttleRingDragging;if(!i||_===e)if("mousedown"===t.type||i&&"mousemove"===t.type||"touchstart"===t.type&&1===t.touches.length||i&&"touchmove"===t.type&&1===t.touches.length){var n,o,a=e._centerX,s=e._centerY,l=e._svgNode,u=l.getBoundingClientRect();if("touchstart"===t.type||"touchmove"===t.type?(n=t.touches[0].clientX,o=t.touches[0].clientY):(n=t.clientX,o=t.clientY),!i&&(n>u.right||n<u.left||o<u.top||o>u.bottom))return;var c=e._shuttleRingPointer.getBoundingClientRect(),d=n-a-u.left,h=o-s-u.top,p=180*Math.atan2(h,d)/Math.PI+90;p>180&&(p-=360);var f=r.shuttleRingAngle;i||n<c.right&&n>c.left&&o>c.top&&o<c.bottom?(_=e,r.shuttleRingDragging=!0,r.shuttleRingAngle=p):p<f?r.slower():p>f&&r.faster(),t.preventDefault()}else e===_&&(_=void 0),r.shuttleRingDragging=!1}function m(e,t){this._viewModel=t,this.svgElement=e,this._enabled=void 0,this._toggled=void 0;var r=this;this._clickFunction=function(){var e=r._viewModel.command;e.canExecute&&e()},e.addEventListener("click",this._clickFunction,!0),this._subscriptions=[a(t,"toggled",this.setToggled,this),a(t,"tooltip",this.setTooltip,this),a(t.command,"canExecute",this.setEnabled,this)]}function g(e,t){function r(e){f(A,e)}e=o(e),this._viewModel=t,this._container=e,this._centerX=0,this._centerY=0,this._defsElement=void 0,this._svgNode=void 0,this._topG=void 0,this._lastHeight=void 0,this._lastWidth=void 0;var i=document.createElement("style");i.textContent=".cesium-animation-rectButton .cesium-animation-buttonGlow { filter: url(#animation_blurred); }.cesium-animation-rectButton .cesium-animation-buttonMain { fill: url(#animation_buttonNormal); }.cesium-animation-buttonToggled .cesium-animation-buttonMain { fill: url(#animation_buttonToggled); }.cesium-animation-rectButton:hover .cesium-animation-buttonMain { fill: url(#animation_buttonHovered); }.cesium-animation-buttonDisabled .cesium-animation-buttonMain { fill: url(#animation_buttonDisabled); }.cesium-animation-shuttleRingG .cesium-animation-shuttleRingSwoosh { fill: url(#animation_shuttleRingSwooshGradient); }.cesium-animation-shuttleRingG:hover .cesium-animation-shuttleRingSwoosh { fill: url(#animation_shuttleRingSwooshHovered); }.cesium-animation-shuttleRingPointer { fill: url(#animation_shuttleRingPointerGradient); }.cesium-animation-shuttleRingPausePointer { fill: url(#animation_shuttleRingPointerPaused); }.cesium-animation-knobOuter { fill: url(#animation_knobOuter); }.cesium-animation-knobInner { fill: url(#animation_knobInner); }",document.head.insertBefore(i,document.head.childNodes[0]);var n=document.createElement("div");n.className="cesium-animation-theme",n.innerHTML='<div class="cesium-animation-themeNormal"></div><div class="cesium-animation-themeHover"></div><div class="cesium-animation-themeSelect"></div><div class="cesium-animation-themeDisabled"></div><div class="cesium-animation-themeKnob"></div><div class="cesium-animation-themePointer"></div><div class="cesium-animation-themeSwoosh"></div><div class="cesium-animation-themeSwooshHover"></div>',this._theme=n,this._themeNormal=n.childNodes[0],this._themeHover=n.childNodes[1],this._themeSelect=n.childNodes[2],this._themeDisabled=n.childNodes[3],this._themeKnob=n.childNodes[4],this._themePointer=n.childNodes[5],this._themeSwoosh=n.childNodes[6],this._themeSwooshHover=n.childNodes[7];var s=document.createElementNS(v,"svg:svg");this._svgNode=s,s.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink",y);var d=document.createElementNS(v,"g");this._topG=d,this._realtimeSVG=new m(p(3,4,"#animation_pathClock"),t.playRealtimeViewModel),this._playReverseSVG=new m(h(44,99,"#animation_pathPlayReverse"),t.playReverseViewModel),this._playForwardSVG=new m(h(124,99,"#animation_pathPlay"),t.playForwardViewModel),this._pauseSVG=new m(h(84,99,"#animation_pathPause"),t.pauseViewModel);var g=document.createElementNS(v,"g");g.appendChild(this._realtimeSVG.svgElement),g.appendChild(this._playReverseSVG.svgElement),g.appendChild(this._playForwardSVG.svgElement),g.appendChild(this._pauseSVG.svgElement);var _=l({tagName:"circle",class:"cesium-animation-shuttleRingBack",cx:100,cy:100,r:99});this._shuttleRingBackPanel=_;var C=l({tagName:"g",class:"cesium-animation-shuttleRingSwoosh",children:[{tagName:"use",transform:"translate(100,97) scale(-1,1)","xlink:href":"#animation_pathSwooshFX"},{tagName:"use",transform:"translate(100,97)","xlink:href":"#animation_pathSwooshFX"},{tagName:"line",x1:100,y1:8,x2:100,y2:22}]});this._shuttleRingSwooshG=C,this._shuttleRingPointer=l({tagName:"use",class:"cesium-animation-shuttleRingPointer","xlink:href":"#animation_pathPointer"});var b=l({tagName:"g",transform:"translate(100,100)"});this._knobOuter=l({tagName:"circle",class:"cesium-animation-knobOuter",cx:0,cy:0,r:71});var S=l({tagName:"circle",class:"cesium-animation-knobInner",cx:0,cy:0,r:61});this._knobDate=u(0,-24,""),this._knobTime=u(0,-7,""),this._knobStatus=u(0,-41,"");var w=l({tagName:"circle",class:"cesium-animation-blank",cx:0,cy:0,r:61}),T=document.createElementNS(v,"g");T.setAttribute("class","cesium-animation-shuttleRingG"),e.appendChild(n),d.appendChild(T),d.appendChild(b),d.appendChild(g),T.appendChild(_),T.appendChild(C),T.appendChild(this._shuttleRingPointer),b.appendChild(this._knobOuter),b.appendChild(S),b.appendChild(this._knobDate),b.appendChild(this._knobTime),b.appendChild(this._knobStatus),b.appendChild(w),s.appendChild(d),e.appendChild(s);var A=this;this._mouseCallback=r,_.addEventListener("mousedown",r,!0),_.addEventListener("touchstart",r,!0),C.addEventListener("mousedown",r,!0),C.addEventListener("touchstart",r,!0),document.addEventListener("mousemove",r,!0),document.addEventListener("touchmove",r,!0),document.addEventListener("mouseup",r,!0),document.addEventListener("touchend",r,!0),document.addEventListener("touchcancel",r,!0),this._shuttleRingPointer.addEventListener("mousedown",r,!0),this._shuttleRingPointer.addEventListener("touchstart",r,!0),this._knobOuter.addEventListener("mousedown",r,!0),this._knobOuter.addEventListener("touchstart",r,!0);var E,x=this._knobTime.childNodes[0],P=this._knobDate.childNodes[0],D=this._knobStatus.childNodes[0];this._subscriptions=[a(t.pauseViewModel,"toggled",function(e){E!==e&&(E=e,E?A._shuttleRingPointer.setAttribute("class","cesium-animation-shuttleRingPausePointer"):A._shuttleRingPointer.setAttribute("class","cesium-animation-shuttleRingPointer"))}),a(t,"shuttleRingAngle",function(e){c(A._shuttleRingPointer,A._knobOuter,e)}),a(t,"dateLabel",function(e){P.textContent!==e&&(P.textContent=e)}),a(t,"timeLabel",function(e){x.textContent!==e&&(x.textContent=e)}),a(t,"multiplierLabel",function(e){D.textContent!==e&&(D.textContent=e)})],this.applyThemeChanges(),this.resize()}var _,v="http://www.w3.org/2000/svg",y="http://www.w3.org/1999/xlink",C=e.fromCssColorString("rgba(247,250,255,0.384)"),b=e.fromCssColorString("rgba(143,191,255,0.216)"),S=e.fromCssColorString("rgba(153,197,255,0.098)"),w=e.fromCssColorString("rgba(255,255,255,0.086)"),T=e.fromCssColorString("rgba(255,255,255,0.267)"),A=e.fromCssColorString("rgba(255,255,255,0)"),E=e.fromCssColorString("rgba(66,67,68,0.3)"),x=e.fromCssColorString("rgba(0,0,0,0.5)"),P=new e;return m.prototype.destroy=function(){this.svgElement.removeEventListener("click",this._clickFunction,!0);for(var e=this._subscriptions,t=0,r=e.length;t<r;t++)e[t].dispose();i(this)},m.prototype.isDestroyed=function(){return!1},m.prototype.setEnabled=function(e){if(this._enabled!==e){if(this._enabled=e,!e)return void this.svgElement.setAttribute("class","cesium-animation-buttonDisabled");if(this._toggled)return void this.svgElement.setAttribute("class","cesium-animation-rectButton cesium-animation-buttonToggled");this.svgElement.setAttribute("class","cesium-animation-rectButton")}},m.prototype.setToggled=function(e){this._toggled!==e&&(this._toggled=e,this._enabled&&(e?this.svgElement.setAttribute("class","cesium-animation-rectButton cesium-animation-buttonToggled"):this.svgElement.setAttribute("class","cesium-animation-rectButton")))},m.prototype.setTooltip=function(e){this.svgElement.getElementsByTagName("title")[0].textContent=e},r(g.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),g.prototype.isDestroyed=function(){return!1},g.prototype.destroy=function(){t(this._observer)&&(this._observer.disconnect(),this._observer=void 0);var e=this._mouseCallback;this._shuttleRingBackPanel.removeEventListener("mousedown",e,!0),this._shuttleRingBackPanel.removeEventListener("touchstart",e,!0),this._shuttleRingSwooshG.removeEventListener("mousedown",e,!0),this._shuttleRingSwooshG.removeEventListener("touchstart",e,!0),document.removeEventListener("mousemove",e,!0),document.removeEventListener("touchmove",e,!0),document.removeEventListener("mouseup",e,!0),document.removeEventListener("touchend",e,!0),document.removeEventListener("touchcancel",e,!0),this._shuttleRingPointer.removeEventListener("mousedown",e,!0),this._shuttleRingPointer.removeEventListener("touchstart",e,!0),this._knobOuter.removeEventListener("mousedown",e,!0),this._knobOuter.removeEventListener("touchstart",e,!0),this._container.removeChild(this._svgNode),this._container.removeChild(this._theme),this._realtimeSVG.destroy(),this._playReverseSVG.destroy(),this._playForwardSVG.destroy(),this._pauseSVG.destroy();for(var r=this._subscriptions,n=0,o=r.length;n<o;n++)r[n].dispose();return i(this)},g.prototype.resize=function(){var e=this._container.clientWidth,t=this._container.clientHeight;if(e!==this._lastWidth||t!==this._lastHeight){var r=this._svgNode,i=e,n=t;0===e&&0===t?(i=200,n=132):0===e?(n=t,i=t/132*200):0===t&&(i=e,n=e/200*132);var o=i/200,a=n/132;r.style.cssText="width: "+i+"px; height: "+n+"px; position: absolute; bottom: 0; left: 0; overflow: hidden;",r.setAttribute("width",i),r.setAttribute("height",n),r.setAttribute("viewBox","0 0 "+i+" "+n),this._topG.setAttribute("transform","scale("+o+","+a+")"),this._centerX=Math.max(1,100*o),this._centerY=Math.max(1,100*a),this._lastHeight=e,this._lastWidth=t}},g.prototype.applyThemeChanges=function(){if(!document.body.contains(this._container)){if(t(this._observer))return;var e=this;return e._observer=new MutationObserver(function(){document.body.contains(e._container)&&(e._observer.disconnect(),e._observer=void 0,e.applyThemeChanges())}),void e._observer.observe(document,{childList:!0,subtree:!0})} -var r=s(this._themeNormal),i=s(this._themeHover),n=s(this._themeSelect),o=s(this._themeDisabled),a=s(this._themeKnob),u=s(this._themePointer),c=s(this._themeSwoosh),h=s(this._themeSwooshHover),p=l({tagName:"defs",children:[{id:"animation_buttonNormal",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(r,C)},{tagName:"stop",offset:"12%","stop-color":d(r,b)},{tagName:"stop",offset:"46%","stop-color":d(r,S)},{tagName:"stop",offset:"81%","stop-color":d(r,w)}]},{id:"animation_buttonHovered",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(i,C)},{tagName:"stop",offset:"12%","stop-color":d(i,b)},{tagName:"stop",offset:"46%","stop-color":d(i,S)},{tagName:"stop",offset:"81%","stop-color":d(i,w)}]},{id:"animation_buttonToggled",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(n,C)},{tagName:"stop",offset:"12%","stop-color":d(n,b)},{tagName:"stop",offset:"46%","stop-color":d(n,S)},{tagName:"stop",offset:"81%","stop-color":d(n,w)}]},{id:"animation_buttonDisabled",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(o,T)},{tagName:"stop",offset:"75%","stop-color":d(o,A)}]},{id:"animation_blurred",tagName:"filter",width:"200%",height:"200%",x:"-50%",y:"-50%",children:[{tagName:"feGaussianBlur",stdDeviation:4,in:"SourceGraphic"}]},{id:"animation_shuttleRingSwooshGradient",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-opacity":.2,"stop-color":c.toCssColorString()},{tagName:"stop",offset:"85%","stop-opacity":.85,"stop-color":c.toCssColorString()},{tagName:"stop",offset:"95%","stop-opacity":.05,"stop-color":c.toCssColorString()}]},{id:"animation_shuttleRingSwooshHovered",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-opacity":.2,"stop-color":h.toCssColorString()},{tagName:"stop",offset:"85%","stop-opacity":.85,"stop-color":h.toCssColorString()},{tagName:"stop",offset:"95%","stop-opacity":.05,"stop-color":h.toCssColorString()}]},{id:"animation_shuttleRingPointerGradient",tagName:"linearGradient",x1:"0%",y1:"50%",x2:"100%",y2:"50%",children:[{tagName:"stop",offset:"0%","stop-color":u.toCssColorString()},{tagName:"stop",offset:"40%","stop-color":u.toCssColorString()},{tagName:"stop",offset:"60%","stop-color":d(u,x)},{tagName:"stop",offset:"100%","stop-color":d(u,x)}]},{id:"animation_shuttleRingPointerPaused",tagName:"linearGradient",x1:"0%",y1:"50%",x2:"100%",y2:"50%",children:[{tagName:"stop",offset:"0%","stop-color":"#CCC"},{tagName:"stop",offset:"40%","stop-color":"#CCC"},{tagName:"stop",offset:"60%","stop-color":"#555"},{tagName:"stop",offset:"100%","stop-color":"#555"}]},{id:"animation_knobOuter",tagName:"linearGradient",x1:"20%",y1:"0%",x2:"90%",y2:"100%",children:[{tagName:"stop",offset:"5%","stop-color":d(a,C)},{tagName:"stop",offset:"60%","stop-color":d(a,E)},{tagName:"stop",offset:"85%","stop-color":d(a,b)}]},{id:"animation_knobInner",tagName:"linearGradient",x1:"20%",y1:"0%",x2:"90%",y2:"100%",children:[{tagName:"stop",offset:"5%","stop-color":d(a,E)},{tagName:"stop",offset:"60%","stop-color":d(a,C)},{tagName:"stop",offset:"85%","stop-color":d(a,w)}]},{id:"animation_pathReset",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M24.316,5.318,9.833,13.682,9.833,5.5,5.5,5.5,5.5,25.5,9.833,25.5,9.833,17.318,24.316,25.682z"},{id:"animation_pathPause",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M13,5.5,7.5,5.5,7.5,25.5,13,25.5zM24.5,5.5,19,5.5,19,25.5,24.5,25.5z"},{id:"animation_pathPlay",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M6.684,25.682L24.316,15.5L6.684,5.318V25.682z"},{id:"animation_pathPlayReverse",tagName:"path",transform:"translate(16,16) scale(-0.85,0.85) translate(-16,-16)",d:"M6.684,25.682L24.316,15.5L6.684,5.318V25.682z"},{id:"animation_pathLoop",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M24.249,15.499c-0.009,4.832-3.918,8.741-8.75,8.75c-2.515,0-4.768-1.064-6.365-2.763l2.068-1.442l-7.901-3.703l0.744,8.694l2.193-1.529c2.244,2.594,5.562,4.242,9.26,4.242c6.767,0,12.249-5.482,12.249-12.249H24.249zM15.499,6.75c2.516,0,4.769,1.065,6.367,2.764l-2.068,1.443l7.901,3.701l-0.746-8.693l-2.192,1.529c-2.245-2.594-5.562-4.245-9.262-4.245C8.734,3.25,3.25,8.734,3.249,15.499H6.75C6.758,10.668,10.668,6.758,15.499,6.75z"},{id:"animation_pathClock",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-15.5)",d:"M15.5,2.374C8.251,2.375,2.376,8.251,2.374,15.5C2.376,22.748,8.251,28.623,15.5,28.627c7.249-0.004,13.124-5.879,13.125-13.127C28.624,8.251,22.749,2.375,15.5,2.374zM15.5,25.623C9.909,25.615,5.385,21.09,5.375,15.5C5.385,9.909,9.909,5.384,15.5,5.374c5.59,0.01,10.115,4.535,10.124,10.125C25.615,21.09,21.091,25.615,15.5,25.623zM8.625,15.5c-0.001-0.552-0.448-0.999-1.001-1c-0.553,0-1,0.448-1,1c0,0.553,0.449,1,1,1C8.176,16.5,8.624,16.053,8.625,15.5zM8.179,18.572c-0.478,0.277-0.642,0.889-0.365,1.367c0.275,0.479,0.889,0.641,1.365,0.365c0.479-0.275,0.643-0.887,0.367-1.367C9.27,18.461,8.658,18.297,8.179,18.572zM9.18,10.696c-0.479-0.276-1.09-0.112-1.366,0.366s-0.111,1.09,0.365,1.366c0.479,0.276,1.09,0.113,1.367-0.366C9.821,11.584,9.657,10.973,9.18,10.696zM22.822,12.428c0.478-0.275,0.643-0.888,0.366-1.366c-0.275-0.478-0.89-0.642-1.366-0.366c-0.479,0.278-0.642,0.89-0.366,1.367C21.732,12.54,22.344,12.705,22.822,12.428zM12.062,21.455c-0.478-0.275-1.089-0.111-1.366,0.367c-0.275,0.479-0.111,1.09,0.366,1.365c0.478,0.277,1.091,0.111,1.365-0.365C12.704,22.344,12.54,21.732,12.062,21.455zM12.062,9.545c0.479-0.276,0.642-0.888,0.366-1.366c-0.276-0.478-0.888-0.642-1.366-0.366s-0.642,0.888-0.366,1.366C10.973,9.658,11.584,9.822,12.062,9.545zM22.823,18.572c-0.48-0.275-1.092-0.111-1.367,0.365c-0.275,0.479-0.112,1.092,0.367,1.367c0.477,0.275,1.089,0.113,1.365-0.365C23.464,19.461,23.3,18.848,22.823,18.572zM19.938,7.813c-0.477-0.276-1.091-0.111-1.365,0.366c-0.275,0.48-0.111,1.091,0.366,1.367s1.089,0.112,1.366-0.366C20.581,8.702,20.418,8.089,19.938,7.813zM23.378,14.5c-0.554,0.002-1.001,0.45-1.001,1c0.001,0.552,0.448,1,1.001,1c0.551,0,1-0.447,1-1C24.378,14.949,23.929,14.5,23.378,14.5zM15.501,6.624c-0.552,0-1,0.448-1,1l-0.466,7.343l-3.004,1.96c-0.478,0.277-0.642,0.889-0.365,1.365c0.275,0.479,0.889,0.643,1.365,0.367l3.305-1.676C15.39,16.99,15.444,17,15.501,17c0.828,0,1.5-0.671,1.5-1.5l-0.5-7.876C16.501,7.072,16.053,6.624,15.501,6.624zM15.501,22.377c-0.552,0-1,0.447-1,1s0.448,1,1,1s1-0.447,1-1S16.053,22.377,15.501,22.377zM18.939,21.455c-0.479,0.277-0.643,0.889-0.366,1.367c0.275,0.477,0.888,0.643,1.366,0.365c0.478-0.275,0.642-0.889,0.366-1.365C20.028,21.344,19.417,21.18,18.939,21.455z"},{id:"animation_pathWingButton",tagName:"path",d:"m 4.5,0.5 c -2.216,0 -4,1.784 -4,4 l 0,24 c 0,2.216 1.784,4 4,4 l 13.71875,0 C 22.478584,27.272785 27.273681,22.511272 32.5,18.25 l 0,-13.75 c 0,-2.216 -1.784,-4 -4,-4 l -24,0 z"},{id:"animation_pathPointer",tagName:"path",d:"M-15,-65,-15,-55,15,-55,15,-65,0,-95z"},{id:"animation_pathSwooshFX",tagName:"path",d:"m 85,0 c 0,16.617 -4.813944,35.356 -13.131081,48.4508 h 6.099803 c 8.317138,-13.0948 13.13322,-28.5955 13.13322,-45.2124 0,-46.94483 -38.402714,-85.00262 -85.7743869,-85.00262 -1.0218522,0 -2.0373001,0.0241 -3.0506131,0.0589 45.958443,1.59437 82.723058,35.77285 82.723058,81.70532 z"}]});t(this._defsElement)?this._svgNode.replaceChild(p,this._defsElement):this._svgNode.appendChild(p),this._defsElement=p},g}),define("Widgets/createCommand",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../ThirdParty/knockout"],function(e,t,r,i,n,o){"use strict";function a(t,i){function a(){var e,r={args:arguments,cancel:!1};return s.raiseEvent(r),r.cancel||(e=t.apply(null,arguments),l.raiseEvent(e)),e}i=e(i,!0);var s=new n,l=new n;return a.canExecute=i,o.track(a,["canExecute"]),r(a,{beforeExecute:{value:s},afterExecute:{value:l}}),a}return a}),define("Widgets/ToggleButtonViewModel",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../ThirdParty/knockout"],function(e,t,r,i,n){"use strict";function o(t,r){this._command=t,r=e(r,e.EMPTY_OBJECT),this.toggled=e(r.toggled,!1),this.tooltip=e(r.tooltip,""),n.track(this,["toggled","tooltip"])}return r(o.prototype,{command:{get:function(){return this._command}}}),o}),define("Widgets/Animation/AnimationViewModel",["../../Core/binarySearch","../../Core/ClockRange","../../Core/ClockStep","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/JulianDate","../../ThirdParty/knockout","../../ThirdParty/sprintf","../createCommand","../ToggleButtonViewModel"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,t){return e-t}function h(t,r){var i=e(r,t,d);return i<0?~i:i}function p(e,t){if(Math.abs(e)<=_)return e/_;var r,i,n=_,o=v;return e>0?(r=Math.log(t[t.length-1]),i=(r-0)/(o-n),Math.exp(0+i*(e-n))):(r=Math.log(-t[0]),i=(r-0)/(o-n),-Math.exp(0+i*(Math.abs(e)-n)))}function f(e,t,i){if(i.clockStep===r.SYSTEM_CLOCK)return _;if(Math.abs(e)<=1)return e*_;var n=t[t.length-1];e>n?e=n:e<-n&&(e=-n);var o,a,s=_,l=v;return e>0?(o=Math.log(n),a=(o-0)/(l-s),(Math.log(e)-0)/a+s):(o=Math.log(-t[0]),a=(o-0)/(l-s),-((Math.log(Math.abs(e))-0)/a+s))}function m(e){var i=this;this._clockViewModel=e,this._allShuttleRingTicks=[],this._dateFormatter=m.defaultDateFormatter,this._timeFormatter=m.defaultTimeFormatter,this.shuttleRingDragging=!1,this.snapToTicks=!1,s.track(this,["_allShuttleRingTicks","_dateFormatter","_timeFormatter","shuttleRingDragging","snapToTicks"]),this._sortedFilteredPositiveTicks=[],this.setShuttleRingTicks(m.defaultTicks),this.timeLabel=void 0,s.defineProperty(this,"timeLabel",function(){return i._timeFormatter(i._clockViewModel.currentTime,i)}),this.dateLabel=void 0,s.defineProperty(this,"dateLabel",function(){return i._dateFormatter(i._clockViewModel.currentTime,i)}),this.multiplierLabel=void 0,s.defineProperty(this,"multiplierLabel",function(){var e=i._clockViewModel;if(e.clockStep===r.SYSTEM_CLOCK)return"Today";var t=e.multiplier;return t%1==0?t.toFixed(0)+"x":t.toFixed(3).replace(/0{0,3}$/,"")+"x"}),this.shuttleRingAngle=void 0,s.defineProperty(this,"shuttleRingAngle",{get:function(){return f(e.multiplier,i._allShuttleRingTicks,e)},set:function(e){e=Math.max(Math.min(e,v),-v);var t=i._allShuttleRingTicks,n=i._clockViewModel;if(n.clockStep=r.SYSTEM_CLOCK_MULTIPLIER,Math.abs(e)===v)return void(n.multiplier=e>0?t[t.length-1]:t[0]);var o=p(e,t);if(i.snapToTicks)o=t[h(o,t)];else if(0!==o){var a=Math.abs(o);if(a>100){var s=a.toFixed(0).length-2,l=Math.pow(10,s);o=Math.round(o/l)*l|0}else a>_?o=Math.round(o):a>1?o=+o.toFixed(1):a>0&&(o=+o.toFixed(2))}n.multiplier=o}}),this._canAnimate=void 0,s.defineProperty(this,"_canAnimate",function(){var e=i._clockViewModel,r=e.clockRange;if(i.shuttleRingDragging||r===t.UNBOUNDED)return!0;var n=e.multiplier,o=e.currentTime,s=e.startTime,l=!1;if(r===t.LOOP_STOP)l=a.greaterThan(o,s)||o.equals(s)&&n>0;else{var u=e.stopTime;l=a.greaterThan(o,s)&&a.lessThan(o,u)||o.equals(s)&&n>0||o.equals(u)&&n<0}return l||(e.shouldAnimate=!1),l}),this._isSystemTimeAvailable=void 0,s.defineProperty(this,"_isSystemTimeAvailable",function(){var e=i._clockViewModel;if(e.clockRange===t.UNBOUNDED)return!0;var r=e.systemTime;return a.greaterThanOrEquals(r,e.startTime)&&a.lessThanOrEquals(r,e.stopTime)}),this._isAnimating=void 0,s.defineProperty(this,"_isAnimating",function(){return i._clockViewModel.shouldAnimate&&(i._canAnimate||i.shuttleRingDragging)});var n=u(function(){var e=i._clockViewModel;e.shouldAnimate?e.shouldAnimate=!1:i._canAnimate&&(e.shouldAnimate=!0)});this._pauseViewModel=new c(n,{toggled:s.computed(function(){return!i._isAnimating}),tooltip:"Pause"});var o=u(function(){var e=i._clockViewModel,t=e.multiplier;t>0&&(e.multiplier=-t),e.shouldAnimate=!0});this._playReverseViewModel=new c(o,{toggled:s.computed(function(){return i._isAnimating&&e.multiplier<0}),tooltip:"Play Reverse"});var l=u(function(){var e=i._clockViewModel,t=e.multiplier;t<0&&(e.multiplier=-t),e.shouldAnimate=!0});this._playForwardViewModel=new c(l,{toggled:s.computed(function(){return i._isAnimating&&e.multiplier>0&&e.clockStep!==r.SYSTEM_CLOCK}),tooltip:"Play Forward"});var d=u(function(){i._clockViewModel.clockStep=r.SYSTEM_CLOCK},s.getObservable(this,"_isSystemTimeAvailable"));this._playRealtimeViewModel=new c(d,{toggled:s.computed(function(){return e.clockStep===r.SYSTEM_CLOCK}),tooltip:s.computed(function(){return i._isSystemTimeAvailable?"Today (real-time)":"Current time not in range"})}),this._slower=u(function(){var e=i._clockViewModel,t=i._allShuttleRingTicks,r=e.multiplier,n=h(r,t)-1;n>=0&&(e.multiplier=t[n])}),this._faster=u(function(){var e=i._clockViewModel,t=i._allShuttleRingTicks,r=e.multiplier,n=h(r,t)+1;n<t.length&&(e.multiplier=t[n])})}var g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],_=15,v=105;return m.defaultDateFormatter=function(e,t){var r=a.toGregorianDate(e);return g[r.month-1]+" "+r.day+" "+r.year},m.defaultTicks=[.001,.002,.005,.01,.02,.05,.1,.25,.5,1,2,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,21600,43200,86400,172800,345600,604800],m.defaultTimeFormatter=function(e,t){var r=a.toGregorianDate(e),i=Math.round(r.millisecond);return Math.abs(t._clockViewModel.multiplier)<1?l("%02d:%02d:%02d.%03d",r.hour,r.minute,r.second,i):l("%02d:%02d:%02d UTC",r.hour,r.minute,r.second)},m.prototype.getShuttleRingTicks=function(){return this._sortedFilteredPositiveTicks.slice(0)},m.prototype.setShuttleRingTicks=function(e){var t,r,i,n={},o=this._sortedFilteredPositiveTicks;for(o.length=0,t=0,r=e.length;t<r;++t)i=e[t],n.hasOwnProperty(i)||(n[i]=!0,o.push(i));o.sort(d);var a=[];for(r=o.length,t=r-1;t>=0;--t)0!==(i=o[t])&&a.push(-i);Array.prototype.push.apply(a,o),this._allShuttleRingTicks=a},n(m.prototype,{slower:{get:function(){return this._slower}},faster:{get:function(){return this._faster}},clockViewModel:{get:function(){return this._clockViewModel}},pauseViewModel:{get:function(){return this._pauseViewModel}},playReverseViewModel:{get:function(){return this._playReverseViewModel}},playForwardViewModel:{get:function(){return this._playForwardViewModel}},playRealtimeViewModel:{get:function(){return this._playRealtimeViewModel}},dateFormatter:{get:function(){return this._dateFormatter},set:function(e){this._dateFormatter=e}},timeFormatter:{get:function(){return this._timeFormatter},set:function(e){this._timeFormatter=e}}}),m._maxShuttleRingAngle=v,m._realtimeShuttleRingAngle=_,m}),define("Widgets/BaseLayerPicker/BaseLayerPickerViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/EllipsoidTerrainProvider","../../Core/isArray","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s){"use strict";function l(r){r=e(r,e.EMPTY_OBJECT);var i=r.globe,l=e(r.imageryProviderViewModels,[]),u=e(r.terrainProviderViewModels,[]);this._globe=i,this.imageryProviderViewModels=l.slice(0),this.terrainProviderViewModels=u.slice(0),this.dropDownVisible=!1,a.track(this,["imageryProviderViewModels","terrainProviderViewModels","dropDownVisible"]),this.buttonTooltip=void 0,a.defineProperty(this,"buttonTooltip",function(){var e=this.selectedImagery,r=this.selectedTerrain,i=t(e)?e.name:void 0,n=t(r)?r.name:void 0;return t(i)&&t(n)?i+"\n"+n:t(i)?i:n}),this.buttonImageUrl=void 0,a.defineProperty(this,"buttonImageUrl",function(){var e=this.selectedImagery;return t(e)?e.iconUrl:void 0}),this.selectedImagery=void 0;var c=a.observable();this._currentImageryProviders=[],a.defineProperty(this,"selectedImagery",{get:function(){return c()},set:function(e){if(c()===e)return void(this.dropDownVisible=!1);var r,i=this._currentImageryProviders,n=i.length,a=this._globe.imageryLayers;for(r=0;r<n;r++)for(var s=a.length,l=0;l<s;l++){var u=a.get(l);if(u.imageryProvider===i[r]){a.remove(u);break}}if(t(e)){var d=e.creationCommand();if(o(d)){var h=d.length;for(r=h-1;r>=0;r--)a.addImageryProvider(d[r],0);this._currentImageryProviders=d.slice(0)}else this._currentImageryProviders=[d],a.addImageryProvider(d,0)}c(e),this.dropDownVisible=!1}}),this.selectedTerrain=void 0;var d=a.observable();a.defineProperty(this,"selectedTerrain",{get:function(){return d()},set:function(e){if(d()===e)return void(this.dropDownVisible=!1);var r;t(e)&&(r=e.creationCommand()),this._globe.depthTestAgainstTerrain=!(r instanceof n),this._globe.terrainProvider=r,d(e),this.dropDownVisible=!1}});var h=this;this._toggleDropDown=s(function(){h.dropDownVisible=!h.dropDownVisible}),this.selectedImagery=e(r.selectedImageryProviderViewModel,l[0]),this.selectedTerrain=e(r.selectedTerrainProviderViewModel,u[0])}return r(l.prototype,{toggleDropDown:{get:function(){return this._toggleDropDown}},globe:{get:function(){return this._globe}}}),l}),define("Widgets/BaseLayerPicker/BaseLayerPicker",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./BaseLayerPickerViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t){e=a(e);var r=new s(t),i=document.createElement("button");i.type="button",i.className="cesium-button cesium-toolbar-button",i.setAttribute("data-bind","attr: { title: buttonTooltip },click: toggleDropDown"),e.appendChild(i);var l=document.createElement("img");l.setAttribute("draggable","false"),l.className="cesium-baseLayerPicker-selected",l.setAttribute("data-bind","attr: { src: buttonImageUrl }"),i.appendChild(l);var u=document.createElement("div");u.className="cesium-baseLayerPicker-dropDown",u.setAttribute("data-bind",'css: { "cesium-baseLayerPicker-dropDown-visible" : dropDownVisible }'),e.appendChild(u);var c=document.createElement("div");c.className="cesium-baseLayerPicker-sectionTitle",c.setAttribute("data-bind","visible: imageryProviderViewModels.length > 0"),c.innerHTML="Imagery",u.appendChild(c);var d=document.createElement("div");d.className="cesium-baseLayerPicker-choices",d.setAttribute("data-bind","foreach: imageryProviderViewModels"),u.appendChild(d);var h=document.createElement("div");h.className="cesium-baseLayerPicker-item",h.setAttribute("data-bind",'css: { "cesium-baseLayerPicker-selectedItem" : $data === $parent.selectedImagery },attr: { title: tooltip },visible: creationCommand.canExecute,click: function($data) { $parent.selectedImagery = $data; }'),d.appendChild(h);var p=document.createElement("img");p.className="cesium-baseLayerPicker-itemIcon",p.setAttribute("data-bind","attr: { src: iconUrl }"),p.setAttribute("draggable","false"),h.appendChild(p);var f=document.createElement("div");f.className="cesium-baseLayerPicker-itemLabel",f.setAttribute("data-bind","text: name"),h.appendChild(f);var m=document.createElement("div");m.className="cesium-baseLayerPicker-sectionTitle",m.setAttribute("data-bind","visible: terrainProviderViewModels.length > 0"),m.innerHTML="Terrain",u.appendChild(m);var g=document.createElement("div");g.className="cesium-baseLayerPicker-choices",g.setAttribute("data-bind","foreach: terrainProviderViewModels"),u.appendChild(g);var _=document.createElement("div");_.className="cesium-baseLayerPicker-item",_.setAttribute("data-bind",'css: { "cesium-baseLayerPicker-selectedItem" : $data === $parent.selectedTerrain },attr: { title: tooltip },visible: creationCommand.canExecute,click: function($data) { $parent.selectedTerrain = $data; }'),g.appendChild(_);var v=document.createElement("img");v.className="cesium-baseLayerPicker-itemIcon",v.setAttribute("data-bind","attr: { src: iconUrl }"),v.setAttribute("draggable","false"),_.appendChild(v);var y=document.createElement("div");y.className="cesium-baseLayerPicker-itemLabel",y.setAttribute("data-bind","text: name"),_.appendChild(y),o.applyBindings(r,i),o.applyBindings(r,u),this._viewModel=r,this._container=e,this._element=i,this._dropPanel=u,this._closeDropDown=function(e){i.contains(e.target)||u.contains(e.target)||(r.dropDownVisible=!1)},n.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeDropDown,!0):(document.addEventListener("mousedown",this._closeDropDown,!0),document.addEventListener("touchstart",this._closeDropDown,!0))}return t(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return n.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeDropDown,!0):(document.removeEventListener("mousedown",this._closeDropDown,!0),document.removeEventListener("touchstart",this._closeDropDown,!0)),o.cleanNode(this._element),o.cleanNode(this._dropPanel),this._container.removeChild(this._element),this._container.removeChild(this._dropPanel),r(this)},l}),define("Widgets/BaseLayerPicker/ProviderViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n){"use strict";function o(t){var r=t.creationFunction;e(r.canExecute)||(r=n(r)),this._creationCommand=r,this.name=t.name,this.tooltip=t.tooltip,this.iconUrl=t.iconUrl,i.track(this,["name","tooltip","iconUrl"])}return t(o.prototype,{creationCommand:{get:function(){return this._creationCommand}}}),o}),define("Widgets/BaseLayerPicker/createDefaultImageryProviderViewModels",["../../Core/buildModuleUrl","../../Scene/ArcGisMapServerImageryProvider","../../Scene/BingMapsImageryProvider","../../Scene/BingMapsStyle","../../Scene/createOpenStreetMapImageryProvider","../../Scene/createTileMapServiceImageryProvider","../../Scene/MapboxImageryProvider","../BaseLayerPicker/ProviderViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(){var l=[];return l.push(new s({name:"Bing Maps Aerial",iconUrl:e("Widgets/Images/ImageryProviders/bingAerial.png"),tooltip:"Bing Maps aerial imagery \nhttp://www.bing.com/maps",creationFunction:function(){return new r({url:"https://dev.virtualearth.net",mapStyle:i.AERIAL})}})),l.push(new s({name:"Bing Maps Aerial with Labels",iconUrl:e("Widgets/Images/ImageryProviders/bingAerialLabels.png"),tooltip:"Bing Maps aerial imagery with label overlays \nhttp://www.bing.com/maps",creationFunction:function(){return new r({url:"https://dev.virtualearth.net",mapStyle:i.AERIAL_WITH_LABELS})}})),l.push(new s({name:"Bing Maps Roads",iconUrl:e("Widgets/Images/ImageryProviders/bingRoads.png"),tooltip:"Bing Maps standard road maps\nhttp://www.bing.com/maps",creationFunction:function(){return new r({url:"https://dev.virtualearth.net",mapStyle:i.ROAD})}})),l.push(new s({name:"Mapbox Satellite",tooltip:"Mapbox satellite imagery https://www.mapbox.com/maps/",iconUrl:e("Widgets/Images/ImageryProviders/mapboxSatellite.png"),creationFunction:function(){return new a({mapId:"mapbox.satellite"})}})),l.push(new s({name:"Mapbox Streets",tooltip:"Mapbox streets imagery https://www.mapbox.com/maps/",iconUrl:e("Widgets/Images/ImageryProviders/mapboxTerrain.png"),creationFunction:function(){return new a({mapId:"mapbox.streets"})}})),l.push(new s({name:"Mapbox Streets Classic",tooltip:"Mapbox streets basic imagery https://www.mapbox.com/maps/",iconUrl:e("Widgets/Images/ImageryProviders/mapboxStreets.png"),creationFunction:function(){return new a({mapId:"mapbox.streets-basic"})}})),l.push(new s({name:"ESRI World Imagery",iconUrl:e("Widgets/Images/ImageryProviders/esriWorldImagery.png"),tooltip:"World Imagery provides one meter or better satellite and aerial imagery in many parts of the world and lower resolution satellite imagery worldwide. The map includes NASA Blue Marble: Next Generation 500m resolution imagery at small scales (above 1:1,000,000), i-cubed 15m eSAT imagery at medium-to-large scales (down to 1:70,000) for the world, and USGS 15m Landsat imagery for Antarctica. The map features 0.3m resolution imagery in the continental United States and 0.6m resolution imagery in parts of Western Europe from DigitalGlobe. In other parts of the world, 1 meter resolution imagery is available from GeoEye IKONOS, i-cubed Nationwide Prime, Getmapping, AeroGRID, IGN Spain, and IGP Portugal. Additionally, imagery at different resolutions has been contributed by the GIS User Community.\nhttp://www.esri.com",creationFunction:function(){return new t({url:"https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",enablePickFeatures:!1})}})),l.push(new s({name:"ESRI World Street Map",iconUrl:e("Widgets/Images/ImageryProviders/esriWorldStreetMap.png"),tooltip:"This worldwide street map presents highway-level data for the world. Street-level data includes the United States; much of Canada; Japan; most countries in Europe; Australia and New Zealand; India; parts of South America including Argentina, Brazil, Chile, Colombia, and Venezuela; Ghana; and parts of southern Africa including Botswana, Lesotho, Namibia, South Africa, and Swaziland.\nhttp://www.esri.com",creationFunction:function(){return new t({url:"https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",enablePickFeatures:!1})}})),l.push(new s({name:"ESRI National Geographic",iconUrl:e("Widgets/Images/ImageryProviders/esriNationalGeographic.png"),tooltip:"This web map contains the National Geographic World Map service. This map service is designed to be used as a general reference map for informational and educational purposes as well as a basemap by GIS professionals and other users for creating web maps and web mapping applications.\nhttp://www.esri.com",creationFunction:function(){return new t({url:"https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/",enablePickFeatures:!1})}})),l.push(new s({name:"Open­Street­Map",iconUrl:e("Widgets/Images/ImageryProviders/openStreetMap.png"),tooltip:"OpenStreetMap (OSM) is a collaborative project to create a free editable map of the world.\nhttp://www.openstreetmap.org",creationFunction:function(){return n({url:"https://a.tile.openstreetmap.org/"})}})),l.push(new s({name:"Stamen Watercolor",iconUrl:e("Widgets/Images/ImageryProviders/stamenWatercolor.png"),tooltip:"Reminiscent of hand drawn maps, Stamen watercolor maps apply raster effect area washes and organic edges over a paper texture to add warm pop to any map.\nhttp://maps.stamen.com",creationFunction:function(){return n({url:"https://stamen-tiles.a.ssl.fastly.net/watercolor/",credit:"Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA."})}})),l.push(new s({name:"Stamen Toner",iconUrl:e("Widgets/Images/ImageryProviders/stamenToner.png"),tooltip:"A high contrast black and white map.\nhttp://maps.stamen.com",creationFunction:function(){return n({url:"https://stamen-tiles.a.ssl.fastly.net/toner/",credit:"Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA."})}})),l.push(new s({name:"The Black Marble",iconUrl:e("Widgets/Images/ImageryProviders/blackMarble.png"),tooltip:"The lights of cities and villages trace the outlines of civilization in this global view of the Earth at night as seen by NASA/NOAA's Suomi NPP satellite.",creationFunction:function(){return o({url:"https://cesiumjs.org/blackmarble",flipXY:!0,credit:"Black Marble imagery courtesy NASA Earth Observatory"})}})),l.push(new s({name:"Natural Earth II",iconUrl:e("Widgets/Images/ImageryProviders/naturalEarthII.png"),tooltip:"Natural Earth II, darkened for contrast.\nhttp://www.naturalearthdata.com/",creationFunction:function(){return o({url:e("Assets/Textures/NaturalEarthII")})}})),l}return l}),define("Widgets/BaseLayerPicker/createDefaultTerrainProviderViewModels",["../../Core/buildModuleUrl","../../Core/CesiumTerrainProvider","../../Core/EllipsoidTerrainProvider","../BaseLayerPicker/ProviderViewModel"],function(e,t,r,i){"use strict";function n(){var n=[];return n.push(new i({name:"WGS84 Ellipsoid",iconUrl:e("Widgets/Images/TerrainProviders/Ellipsoid.png"),tooltip:"WGS84 standard ellipsoid, also known as EPSG:4326",creationFunction:function(){return new r}})),n.push(new i({name:"STK World Terrain meshes",iconUrl:e("Widgets/Images/TerrainProviders/STK.png"),tooltip:"High-resolution, mesh-based terrain for the entire globe. Free for use on the Internet. Closed-network options are available.\nhttp://www.agi.com",creationFunction:function(){return new t({url:"https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles",requestWaterMask:!0,requestVertexNormals:!0})}})),n}return n}),define("Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel",["../../Core/Check","../../Core/Color","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/ScreenSpaceEventHandler","../../Core/ScreenSpaceEventType","../../Scene/Cesium3DTileColorBlendMode","../../Scene/Cesium3DTileFeature","../../Scene/Cesium3DTileset","../../Scene/Cesium3DTileStyle","../../Scene/PerformanceDisplay","../../ThirdParty/knockout"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){return function(t){var i=e._scene.pick(t.position);r(i)&&i.primitive instanceof u&&(e.tileset=i.primitive),e.pickActive=!1}}function f(e,t){t?e._eventHandler.setInputAction(function(t){var i=e._scene.pick(t.endPosition);r(i)&&i.primitive instanceof u&&(e.tileset=i.primitive)},a.MOUSE_MOVE):(e._eventHandler.removeInputAction(a.MOUSE_MOVE),e.picking=e.picking)}function m(e){var t=e/1048576;return t<1?t.toLocaleString(void 0,y):Math.round(t).toLocaleString()}function g(e,t){if(!r(e))return"";var i=e.statistics,n='<ul class="cesium-cesiumInspector-statistics">';return n+="<li><strong>Visited: </strong>"+i.visited.toLocaleString()+"</li><li><strong>Selected: </strong>"+e._selectedTiles.length.toLocaleString()+"</li><li><strong>Commands: </strong>"+i.numberOfCommands.toLocaleString()+"</li>",n+="</ul>",t||(n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Requests: </strong>"+i.numberOfPendingRequests.toLocaleString()+"</li><li><strong>Attempted: </strong>"+i.numberOfAttemptedRequests.toLocaleString()+"</li><li><strong>Processing: </strong>"+i.numberOfTilesProcessing.toLocaleString()+"</li><li><strong>Content Ready: </strong>"+i.numberOfTilesWithContentReady.toLocaleString()+"</li><li><strong>Total: </strong>"+i.numberOfTilesTotal.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Features Selected: </strong>"+i.numberOfFeaturesSelected.toLocaleString()+"</li><li><strong>Features Loaded: </strong>"+i.numberOfFeaturesLoaded.toLocaleString()+"</li><li><strong>Points Selected: </strong>"+i.numberOfPointsSelected.toLocaleString()+"</li><li><strong>Points Loaded: </strong>"+i.numberOfPointsLoaded.toLocaleString()+"</li><li><strong>Triangles Selected: </strong>"+i.numberOfTrianglesSelected.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Tiles styled: </strong>"+i.numberOfTilesStyled.toLocaleString()+"</li><li><strong>Features styled: </strong>"+i.numberOfFeaturesStyled.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Children Union Culled: </strong>"+i.numberOfTilesCulledWithChildrenUnion.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Geometry Memory (MB): </strong>"+m(i.geometryByteLength)+"</li><li><strong>Texture Memory (MB): </strong>"+m(i.texturesByteLength)+"</li><li><strong>Batch Table Memory (MB): </strong>"+m(i.batchTableByteLength)+"</li>",n+="</ul>"),n}function _(e,t){var i=this,n=e.canvas;this._eventHandler=new o(n),this._scene=e,this._performanceContainer=t,this._canvas=n,this._performanceDisplay=new d({container:t}),this._statisticsText="",this._pickStatisticsText="",this._editorError="", -this.performance=!1,this.showStatistics=!0,this.showPickStatistics=!0,this.inspectorVisible=!0,this.tilesetVisible=!1,this.displayVisible=!1,this.updateVisible=!1,this.loggingVisible=!1,this.styleVisible=!1,this.tileDebugLabelsVisible=!1,this.optimizationVisible=!1,this.styleString="{}",this._tileset=void 0,this._feature=void 0,this._tile=void 0,h.track(this,["performance","inspectorVisible","_statisticsText","_pickStatisticsText","_editorError","showPickStatistics","showStatistics","tilesetVisible","displayVisible","updateVisible","loggingVisible","styleVisible","optimizationVisible","tileDebugLabelsVisible","styleString","_feature","_tile"]),this._properties=h.observable({}),this.properties=[],h.defineProperty(this,"properties",function(){var e=[],t=i._properties();for(var r in t)t.hasOwnProperty(r)&&e.push(r);return e});var u=h.observable();h.defineProperty(this,"dynamicScreenSpaceError",{get:function(){return u()},set:function(e){u(e),r(i._tileset)&&(i._tileset.dynamicScreenSpaceError=e)}}),this.dynamicScreenSpaceError=!1;var c=h.observable();h.defineProperty(this,"colorBlendMode",{get:function(){return c()},set:function(e){c(e),r(i._tileset)&&(i._tileset.colorBlendMode=e)}}),this.colorBlendMode=s.HIGHLIGHT;var m=h.observable();h.defineProperty(this,"picking",{get:function(){return m()},set:function(t){m(t),t?i._eventHandler.setInputAction(function(t){var n=e.pick(t.endPosition);if(n instanceof l?(i.feature=n,i.tile=n.content.tile):r(n)&&r(n.content)?(i.feature=void 0,i.tile=n.content.tile):(i.feature=void 0,i.tile=void 0),r(i._tileset))if(S&&r(n)&&r(n.content)){var o;e.pickPositionSupported&&(o=e.pickPosition(t.endPosition),r(o)&&(i._tileset.debugPickPosition=o)),i._tileset.debugPickedTile=n.content.tile}else i._tileset.debugPickedTile=void 0},a.MOUSE_MOVE):(i.feature=void 0,i.tile=void 0,i._eventHandler.removeInputAction(a.MOUSE_MOVE))}}),this.picking=!0;var g=h.observable();h.defineProperty(this,"colorize",{get:function(){return g()},set:function(e){g(e),r(i._tileset)&&(i._tileset.debugColorizeTiles=e)}}),this.colorize=!1;var _=h.observable();h.defineProperty(this,"wireframe",{get:function(){return _()},set:function(e){_(e),r(i._tileset)&&(i._tileset.debugWireframe=e)}}),this.wireframe=!1;var v=h.observable();h.defineProperty(this,"showBoundingVolumes",{get:function(){return v()},set:function(e){v(e),r(i._tileset)&&(i._tileset.debugShowBoundingVolume=e)}}),this.showBoundingVolumes=!1;var y=h.observable();h.defineProperty(this,"showContentBoundingVolumes",{get:function(){return y()},set:function(e){y(e),r(i._tileset)&&(i._tileset.debugShowContentBoundingVolume=e)}}),this.showContentBoundingVolumes=!1;var C=h.observable();h.defineProperty(this,"showRequestVolumes",{get:function(){return C()},set:function(e){C(e),r(i._tileset)&&(i._tileset.debugShowViewerRequestVolume=e)}}),this.showRequestVolumes=!1;var b=h.observable();h.defineProperty(this,"freezeFrame",{get:function(){return b()},set:function(e){b(e),r(i._tileset)&&(i._tileset.debugFreezeFrame=e,i._scene.debugShowFrustumPlanes=e)}}),this.freezeFrame=!1;var S=h.observable();h.defineProperty(this,"showOnlyPickedTileDebugLabel",{get:function(){return S()},set:function(e){S(e),r(i._tileset)&&(i._tileset.debugPickedTileLabelOnly=e)}}),this.showOnlyPickedTileDebugLabel=!1;var w=h.observable();h.defineProperty(this,"showGeometricError",{get:function(){return w()},set:function(e){w(e),r(i._tileset)&&(i._tileset.debugShowGeometricError=e)}}),this.showGeometricError=!1;var T=h.observable();h.defineProperty(this,"showRenderingStatistics",{get:function(){return T()},set:function(e){T(e),r(i._tileset)&&(i._tileset.debugShowRenderingStatistics=e)}}),this.showRenderingStatistics=!1;var A=h.observable();h.defineProperty(this,"showMemoryUsage",{get:function(){return A()},set:function(e){A(e),r(i._tileset)&&(i._tileset.debugShowMemoryUsage=e)}}),this.showMemoryUsage=!1;var E=h.observable();h.defineProperty(this,"showUrl",{get:function(){return E()},set:function(e){E(e),r(i._tileset)&&(i._tileset.debugShowUrl=e)}}),this.showUrl=!1;var x=h.observable();h.defineProperty(this,"maximumScreenSpaceError",{get:function(){return x()},set:function(e){e=Number(e),isNaN(e)||(x(e),r(i._tileset)&&(i._tileset.maximumScreenSpaceError=e))}}),this.maximumScreenSpaceError=16;var P=h.observable();h.defineProperty(this,"dynamicScreenSpaceErrorDensity",{get:function(){return P()},set:function(e){e=Number(e),isNaN(e)||(P(e),r(i._tileset)&&(i._tileset.dynamicScreenSpaceErrorDensity=e))}}),this.dynamicScreenSpaceErrorDensity=.00278,this.dynamicScreenSpaceErrorDensitySliderValue=void 0,h.defineProperty(this,"dynamicScreenSpaceErrorDensitySliderValue",{get:function(){return Math.pow(P(),1/6)},set:function(e){P(Math.pow(e,6))}});var D=h.observable();h.defineProperty(this,"dynamicScreenSpaceErrorFactor",{get:function(){return D()},set:function(e){e=Number(e),isNaN(e)||(D(e),r(i._tileset)&&(i._tileset.dynamicScreenSpaceErrorFactor=e))}}),this.dynamicScreenSpaceErrorFactor=4;var I=p(this),O=h.observable();h.defineProperty(this,"pickActive",{get:function(){return O()},set:function(e){O(e),e?i._eventHandler.setInputAction(I,a.LEFT_CLICK):i._eventHandler.removeInputAction(a.LEFT_CLICK)}}),this.pickActive=!1;var M=h.observable();h.defineProperty(this,"skipLevelOfDetail",{get:function(){return M()},set:function(e){M(e),r(i._tileset)&&(i._tileset.skipLevelOfDetail=e)}}),this.skipLevelOfDetail=!0;var R=h.observable();h.defineProperty(this,"skipScreenSpaceErrorFactor",{get:function(){return R()},set:function(e){e=Number(e),isNaN(e)||(R(e),r(i._tileset)&&(i._tileset.skipScreenSpaceErrorFactor=e))}}),this.skipScreenSpaceErrorFactor=16;var N=h.observable();h.defineProperty(this,"baseScreenSpaceError",{get:function(){return N()},set:function(e){e=Number(e),isNaN(e)||(N(e),r(i._tileset)&&(i._tileset.baseScreenSpaceError=e))}}),this.baseScreenSpaceError=1024;var L=h.observable();h.defineProperty(this,"skipLevels",{get:function(){return L()},set:function(e){e=Number(e),isNaN(e)||(L(e),r(i._tileset)&&(i._tileset.skipLevels=e))}}),this.skipLevels=1;var k=h.observable();h.defineProperty(this,"immediatelyLoadDesiredLevelOfDetail",{get:function(){return k()},set:function(e){k(e),r(i._tileset)&&(i._tileset.immediatelyLoadDesiredLevelOfDetail=e)}}),this.immediatelyLoadDesiredLevelOfDetail=!1;var F=h.observable();h.defineProperty(this,"loadSiblings",{get:function(){F()},set:function(e){F(e),r(i._tileset)&&(i._tileset.loadSiblings=e)}}),this.loadSiblings=!1,this._style=void 0,this._shouldStyle=!1,this._definedProperties=["properties","dynamicScreenSpaceError","colorBlendMode","picking","colorize","wireframe","showBoundingVolumes","showContentBoundingVolumes","showRequestVolumes","freezeFrame","maximumScreenSpaceError","dynamicScreenSpaceErrorDensity","baseScreenSpaceError","skipScreenSpaceErrorFactor","skipLevelOfDetail","skipLevels","immediatelyLoadDesiredLevelOfDetail","loadSiblings","dynamicScreenSpaceErrorDensitySliderValue","dynamicScreenSpaceErrorFactor","pickActive","showOnlyPickedTileDebugLabel","showGeometricError","showRenderingStatistics","showMemoryUsage","showUrl"],this._removePostRenderEvent=e.postRender.addEventListener(function(){i._update()}),r(this._tileset)||f(this,!0)}function v(e){if(e.featuresLength>0)return!0;var t=e.innerContents;if(r(t)){for(var i=t.length,n=0;n<i;++n)if(!v(t[n]))return!1;return!0}return!1}var y={maximumFractionDigits:3},C=[{text:"Highlight",value:s.HIGHLIGHT},{text:"Replace",value:s.REPLACE},{text:"Mix",value:s.MIX}],b=new t(1,1,0,.4),S=new t,w=new t;return i(_.prototype,{scene:{get:function(){return this._scene}},performanceContainer:{get:function(){return this._performanceContainer}},statisticsText:{get:function(){return this._statisticsText}},pickStatisticsText:{get:function(){return this._pickStatisticsText}},colorBlendModes:{get:function(){return C}},editorError:{get:function(){return this._editorError}},tileset:{get:function(){return this._tileset},set:function(e){if(this._tileset=e,this._style=void 0,this.styleString="{}",this.feature=void 0,this.tile=void 0,r(e)){var t=this;e.readyPromise.then(function(e){t.isDestroyed()||t._properties(e.properties)});for(var i=["colorize","wireframe","showBoundingVolumes","showContentBoundingVolumes","showRequestVolumes","freezeFrame","showOnlyPickedTileDebugLabel","showGeometricError","showRenderingStatistics","showMemoryUsage","showUrl"],n=i.length,o=0;o<n;++o){var a=i[o];this[a]=this[a]}this.maximumScreenSpaceError=e.maximumScreenSpaceError,this.dynamicScreenSpaceError=e.dynamicScreenSpaceError,this.dynamicScreenSpaceErrorDensity=e.dynamicScreenSpaceErrorDensity,this.dynamicScreenSpaceErrorFactor=e.dynamicScreenSpaceErrorFactor,this.colorBlendMode=e.colorBlendMode,this.skipLevelOfDetail=e.skipLevelOfDetail,this.skipScreenSpaceErrorFactor=e.skipScreenSpaceErrorFactor,this.baseScreenSpaceError=e.baseScreenSpaceError,this.skipLevels=e.skipLevels,this.immediatelyLoadDesiredLevelOfDetail=e.immediatelyLoadDesiredLevelOfDetail,this.loadSiblings=e.loadSiblings}else this._properties({});this._statisticsText=g(e,!1),this._pickStatisticsText=g(e,!0),f(this,!1)}},feature:{get:function(){return this._feature},set:function(e){if(this._feature!==e){var i=this._feature;if(r(i)&&!i.content.isDestroyed()){var n=this._scene.frameState;!this.colorize&&r(this._style)?i.color=r(this._style.color)?this._style.color.evaluateColor(n,i,S):t.WHITE:i.color=w}r(e)&&(t.clone(e.color,w),e.color=b),this._feature=e}}},tile:{get:function(){return this._tile},set:function(e){if(this._tile!==e){var i=this._tile;!r(i)||i.isDestroyed()||v(i.content)||(i.color=w),r(e)&&!v(e.content)&&(t.clone(e.color,w),e.color=b),this._tile=e}}}}),_.prototype.togglePickTileset=function(){this.pickActive=!this.pickActive},_.prototype.toggleInspector=function(){this.inspectorVisible=!this.inspectorVisible},_.prototype.toggleTileset=function(){this.tilesetVisible=!this.tilesetVisible},_.prototype.toggleDisplay=function(){this.displayVisible=!this.displayVisible},_.prototype.toggleUpdate=function(){this.updateVisible=!this.updateVisible},_.prototype.toggleLogging=function(){this.loggingVisible=!this.loggingVisible},_.prototype.toggleStyle=function(){this.styleVisible=!this.styleVisible},_.prototype.toggleTileDebugLabels=function(){this.tileDebugLabelsVisible=!this.tileDebugLabelsVisible},_.prototype.toggleOptimization=function(){this.optimizationVisible=!this.optimizationVisible},_.prototype.trimTilesCache=function(){r(this._tileset)&&this._tileset.trimLoadedTiles()},_.prototype.compileStyle=function(){var e=this._tileset;if(r(e)&&this.styleString!==JSON.stringify(e.style)){this._editorError="";try{0===this.styleString.length&&(this.styleString="{}"),this._style=new c(JSON.parse(this.styleString)),this._shouldStyle=!0}catch(e){this._editorError=e.toString()}this.feature=this._feature,this.tile=this._tile}},_.prototype.styleEditorKeyPress=function(e,t){if(9===t.keyCode){t.preventDefault();var r,i=t.target,n=i.selectionStart,o=i.selectionEnd,a=o,s=i.value.slice(n,o),l=s.split("\n"),u=l.length;if(t.shiftKey)for(r=0;r<u;++r)" "===l[r][0]&&(" "===l[r][1]?(l[r]=l[r].substr(2),a-=2):(l[r]=l[r].substr(1),a-=1));else for(r=0;r<u;++r)l[r]=" "+l[r],a+=2;var c=l.join("\n");i.value=i.value.slice(0,n)+c+i.value.slice(o),i.selectionStart=n!==o?n:a,i.selectionEnd=a}else!t.ctrlKey||10!==t.keyCode&&13!==t.keyCode||this.compileStyle();return!0},_.prototype._update=function(){var e=this._tileset;if(this.performance&&this._performanceDisplay.update(),r(e)){if(e.isDestroyed())return this.tile=void 0,this.feature=void 0,void(this.tileset=void 0);var t=e.style;this._style!==e.style&&(this._shouldStyle?(e.style=this._style,this._shouldStyle=!1):(this._style=t,this.styleString=JSON.stringify(t.style,null," ")))}this.showStatistics&&(this._statisticsText=g(e,!1),this._pickStatisticsText=g(e,!0))},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){this._eventHandler.destroy(),this._removePostRenderEvent();var e=this;return this._definedProperties.forEach(function(t){h.getObservable(e,t).dispose()}),n(this)},_.getStatistics=g,_}),define("Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector",["../../Core/Check","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../ThirdParty/knockout","../getElement","./Cesium3DTilesInspectorViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(t,r){e.defined("container",t),e.typeOf.object("scene",r),t=a(t);var i=document.createElement("div"),n=document.createElement("div");n.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : performance, "cesium-cesiumInspector-hide" : !performance}');var l=new s(r,n);this._viewModel=l,this._container=t,this._element=i;var p=document.createElement("div");p.textContent="3D Tiles Inspector",p.className="cesium-cesiumInspector-button",p.setAttribute("data-bind","click: toggleInspector"),i.appendChild(p),i.className="cesium-cesiumInspector cesium-3DTilesInspector",i.setAttribute("data-bind",'css: { "cesium-cesiumInspector-visible" : inspectorVisible, "cesium-cesiumInspector-hidden" : !inspectorVisible}'),t.appendChild(i);var f=document.createElement("div"),m=document.createElement("div"),g=document.createElement("div"),_=document.createElement("div"),v=document.createElement("div"),y=document.createElement("div"),C=document.createElement("div"),b=document.createElement("div");b.className="field-group";var S=document.createElement("label");S.className="field-label",S.appendChild(document.createTextNode("Properties: "));var w=document.createElement("div");w.setAttribute("data-bind","text: properties"),b.appendChild(S),b.appendChild(w),f.appendChild(b),f.appendChild(h("togglePickTileset","Pick Tileset","pickActive")),f.appendChild(h("trimTilesCache","Trim Tiles Cache")),f.appendChild(c("picking","Enable Picking")),m.appendChild(c("colorize","Colorize")),m.appendChild(c("wireframe","Wireframe")),m.appendChild(c("showBoundingVolumes","Bounding Volumes")),m.appendChild(c("showContentBoundingVolumes","Content Volumes")),m.appendChild(c("showRequestVolumes","Request Volumes")),g.appendChild(c("freezeFrame","Freeze Frame")),g.appendChild(c("dynamicScreenSpaceError","Dynamic Screen Space Error"));var T=document.createElement("div");T.appendChild(d("maximumScreenSpaceError",0,128,1,"Maximum Screen Space Error")),g.appendChild(T);var A=document.createElement("div");A.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : dynamicScreenSpaceError, "cesium-cesiumInspector-hide" : !dynamicScreenSpaceError}'),A.appendChild(d("dynamicScreenSpaceErrorDensitySliderValue",0,1,.005,"Screen Space Error Density","dynamicScreenSpaceErrorDensity")),A.appendChild(d("dynamicScreenSpaceErrorFactor",1,10,.1,"Screen Space Error Factor")),g.appendChild(A),_.appendChild(c("performance","Performance")),_.appendChild(n),_.appendChild(c("showStatistics","Statistics"));var E=document.createElement("div");E.className="cesium-3dTilesInspector-statistics",E.setAttribute("data-bind","html: statisticsText, visible: showStatistics"),_.appendChild(E),_.appendChild(c("showPickStatistics","Pick Statistics"));var x=document.createElement("div");x.className="cesium-3dTilesInspector-statistics",x.setAttribute("data-bind","html: pickStatisticsText, visible: showPickStatistics"),_.appendChild(x),y.appendChild(document.createTextNode("Color Blend Mode: "));var P=document.createElement("select");P.setAttribute("data-bind",'options: colorBlendModes, optionsText: "text", optionsValue: "value", value: colorBlendMode'),y.appendChild(P);var D=document.createElement("textarea");D.setAttribute("data-bind","textInput: styleString, event: { keydown: styleEditorKeyPress }"),y.className="cesium-cesiumInspector-styleEditor",y.appendChild(D);var I=h("compileStyle","Compile (Ctrl+Enter)");y.appendChild(I);var O=document.createElement("div");O.className="cesium-cesiumInspector-error",O.setAttribute("data-bind","text: editorError"),y.appendChild(O),v.appendChild(c("showOnlyPickedTileDebugLabel","Show Picked Only")),v.appendChild(c("showGeometricError","Geometric Error")),v.appendChild(c("showRenderingStatistics","Rendering Statistics")),v.appendChild(c("showMemoryUsage","Memory Usage (MB)")),v.appendChild(c("showUrl","Url")),C.appendChild(c("skipLevelOfDetail","Skip Tile LODs"));var M=document.createElement("div");M.appendChild(d("skipScreenSpaceErrorFactor",1,50,1,"Skip SSE Factor")),C.appendChild(M);var R=document.createElement("div");R.appendChild(d("baseScreenSpaceError",0,4096,1,"SSE before skipping LOD")),C.appendChild(R);var N=document.createElement("div");N.appendChild(d("skipLevels",0,10,1,"Min. levels to skip")),C.appendChild(N),C.appendChild(c("immediatelyLoadDesiredLevelOfDetail","Load only tiles that meet the max. SSE.")),C.appendChild(c("loadSiblings","Load siblings of visible tiles."));var L=u("Tileset","tilesetVisible","toggleTileset",f),k=u("Display","displayVisible","toggleDisplay",m),F=u("Update","updateVisible","toggleUpdate",g),B=u("Logging","loggingVisible","toggleLogging",_),U=u("Tile Debug Labels","tileDebugLabelsVisible","toggleTileDebugLabels",v),V=u("Style","styleVisible","toggleStyle",y),z=u("Optimization","optimizationVisible","toggleOptimization",C);i.appendChild(L),i.appendChild(k),i.appendChild(F),i.appendChild(B),i.appendChild(U),i.appendChild(V),i.appendChild(z),o.applyBindings(l,i)}function u(e,t,r,i){var n=document.createElement("span");n.className="cesium-cesiumInspector-toggleSwitch",n.setAttribute("data-bind","text: "+t+' ? "-" : "+", click: '+r);var o=document.createElement("div");o.className="cesium-cesiumInspector-sectionHeader",o.appendChild(n),o.appendChild(document.createTextNode(e));var a=document.createElement("div");a.className="cesium-cesiumInspector-section",a.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : '+t+', "cesium-cesiumInspector-hide" : !'+t+"}"),a.appendChild(i);var s=document.createElement("div");return s.className="cesium-cesiumInspector-dropDown",s.appendChild(o),s.appendChild(a),s}function c(e,t){var r=document.createElement("input");r.type="checkbox",r.setAttribute("data-bind","checked: "+e);var i=document.createElement("div");return i.appendChild(r),i.appendChild(document.createTextNode(t)),i}function d(e,r,i,n,o,a){a=t(a,e);var s=document.createElement("input");s.setAttribute("data-bind","value: "+a),s.type="number";var l=document.createElement("input");l.type="range",l.min=r,l.max=i,l.step=n,l.setAttribute("data-bind",'valueUpdate: "input", value: '+e);var u=document.createElement("div");u.appendChild(l);var c=document.createElement("div");return c.className="cesium-cesiumInspector-slider",c.appendChild(document.createTextNode(o)),c.appendChild(s),c.appendChild(u),c}function h(e,t,i){var n=document.createElement("button");n.type="button",n.textContent=t,n.className="cesium-cesiumInspector-pickButton";var o="click: "+e;return r(i)&&(o+=', css: {"cesium-cesiumInspector-pickButtonHighlight" : '+i+"}"),n.setAttribute("data-bind",o),n}return i(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return o.cleanNode(this._element),this._container.removeChild(this._element),this.viewModel.destroy(),n(this)},l}),define("Widgets/CesiumInspector/CesiumInspectorViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Rectangle","../../Core/ScreenSpaceEventHandler","../../Core/ScreenSpaceEventType","../../Scene/DebugModelMatrixPrimitive","../../Scene/PerformanceDisplay","../../Scene/TileCoordinatesImageryProvider","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t){var r;if(e(t)){r="Command Statistics";var i=t.commandsInFrustums;for(var n in i)if(i.hasOwnProperty(n)){var o,a=parseInt(n,10);if(7===a)o="1, 2 and 3";else{for(var s=[],l=2;l>=0;l--){var u=Math.pow(2,l);a>=u&&(s.push(l+1),a-=u)}o=s.reverse().join(" and ")}r+="<br>    "+i[n]+" in frustum "+o}r+="<br>Total: "+t.totalCommands}return r}function p(e,t,r){var i=Math.min(r,t);return i=Math.max(i,e)}function f(t,r){function i(t){var r=f._scene.pick({x:t.position.x,y:t.position.y});e(r)&&(f.primitive=e(r.collection)?r.collection:r.primitive),f.pickPrimitiveActive=!1}function h(t){var r,i=_.ellipsoid,o=f._scene.camera.pickEllipsoid({x:t.position.x,y:t.position.y},i);if(e(o))for(var a=i.cartesianToCartographic(o),s=_._surface.tileProvider._tilesToRenderByTextureCount,l=0;!r&&l<s.length;++l){var u=s[l];if(e(u))for(var c=0;!r&&c<u.length;++c){var d=u[c];n.contains(d.rectangle,a)&&(r=d)}}f.tile=r,f.pickTileActive=!1}var f=this,m=t.canvas,g=new o(m);this._eventHandler=g,this._scene=t,this._canvas=m,this._primitive=void 0,this._tile=void 0,this._modelMatrixPrimitive=void 0,this._performanceDisplay=void 0,this._performanceContainer=r;var _=this._scene.globe;_.depthTestAgainstTerrain=!0,this.frustums=!1,this.frustumPlanes=!1,this.performance=!1,this.shaderCacheText="",this.primitiveBoundingSphere=!1,this.primitiveReferenceFrame=!1,this.filterPrimitive=!1,this.tileBoundingSphere=!1,this.filterTile=!1,this.wireframe=!1,this.globeDepth=!1,this.pickDepth=!1,this.depthFrustum=1,this._numberOfFrustums=1,this.suspendUpdates=!1,this.tileCoordinates=!1,this.frustumStatisticText=!1,this.tileText="",this.hasPickedPrimitive=!1,this.hasPickedTile=!1,this.pickPrimitiveActive=!1,this.pickTileActive=!1,this.dropDownVisible=!0,this.generalVisible=!0,this.primitivesVisible=!1,this.terrainVisible=!1,this.depthFrustumText="",this.generalSwitchText=c.pureComputed(function(){return f.generalVisible?"-":"+"}),this.primitivesSwitchText=c.pureComputed(function(){return f.primitivesVisible?"-":"+"}),this.terrainSwitchText=c.pureComputed(function(){return f.terrainVisible?"-":"+"}),c.track(this,["frustums","frustumPlanes","performance","shaderCacheText","primitiveBoundingSphere","primitiveReferenceFrame","filterPrimitive","tileBoundingSphere","filterTile","wireframe","globeDepth","pickDepth","depthFrustum","suspendUpdates","tileCoordinates","frustumStatisticText","tileText","hasPickedPrimitive","hasPickedTile","pickPrimitiveActive","pickTileActive","dropDownVisible","generalVisible","primitivesVisible","terrainVisible","depthFrustumText"]),this._toggleDropDown=d(function(){f.dropDownVisible=!f.dropDownVisible}),this._toggleGeneral=d(function(){f.generalVisible=!f.generalVisible}),this._togglePrimitives=d(function(){f.primitivesVisible=!f.primitivesVisible}),this._toggleTerrain=d(function(){f.terrainVisible=!f.terrainVisible}),this._frustumsSubscription=c.getObservable(this,"frustums").subscribe(function(e){f._scene.debugShowFrustums=e}),this._frustumPlanesSubscription=c.getObservable(this,"frustumPlanes").subscribe(function(e){f._scene.debugShowFrustumPlanes=e}),this._performanceSubscription=c.getObservable(this,"performance").subscribe(function(e){e?f._performanceDisplay=new l({container:f._performanceContainer}):f._performanceContainer.innerHTML=""}),this._showPrimitiveBoundingSphere=d(function(){return f._primitive.debugShowBoundingVolume=f.primitiveBoundingSphere,!0}),this._primitiveBoundingSphereSubscription=c.getObservable(this,"primitiveBoundingSphere").subscribe(function(){f._showPrimitiveBoundingSphere()}),this._showPrimitiveReferenceFrame=d(function(){if(f.primitiveReferenceFrame){var t=f._primitive.modelMatrix;f._modelMatrixPrimitive=new s({modelMatrix:t}),f._scene.primitives.add(f._modelMatrixPrimitive)}else e(f._modelMatrixPrimitive)&&(f._scene.primitives.remove(f._modelMatrixPrimitive),f._modelMatrixPrimitive=void 0);return!0}),this._primitiveReferenceFrameSubscription=c.getObservable(this,"primitiveReferenceFrame").subscribe(function(){f._showPrimitiveReferenceFrame()}),this._doFilterPrimitive=d(function(){return f.filterPrimitive?f._scene.debugCommandFilter=function(t){return!(!e(f._modelMatrixPrimitive)||t.owner!==f._modelMatrixPrimitive._primitive)||!!e(f._primitive)&&(t.owner===f._primitive||t.owner===f._primitive._billboardCollection||t.owner.primitive===f._primitive)}:f._scene.debugCommandFilter=void 0,!0}),this._filterPrimitiveSubscription=c.getObservable(this,"filterPrimitive").subscribe(function(){f._doFilterPrimitive()}),this._wireframeSubscription=c.getObservable(this,"wireframe").subscribe(function(e){_._surface.tileProvider._debug.wireframe=e}),this._globeDepthSubscription=c.getObservable(this,"globeDepth").subscribe(function(e){f._scene.debugShowGlobeDepth=e}),this._pickDepthSubscription=c.getObservable(this,"pickDepth").subscribe(function(e){f._scene.debugShowPickDepth=e}),this._depthFrustumSubscription=c.getObservable(this,"depthFrustum").subscribe(function(e){f.scene.debugShowDepthFrustum=e}),this._incrementDepthFrustum=d(function(){var e=f.depthFrustum+1;return f.depthFrustum=p(1,f._numberOfFrustums,e),!0}),this._decrementDepthFrustum=d(function(){var e=f.depthFrustum-1;return f.depthFrustum=p(1,f._numberOfFrustums,e),!0}),this._suspendUpdatesSubscription=c.getObservable(this,"suspendUpdates").subscribe(function(e){_._surface._debug.suspendLodUpdate=e,e||(f.filterTile=!1)});var v;this._showTileCoordinates=d(function(){return f.tileCoordinates&&!e(v)?v=t.imageryLayers.addImageryProvider(new u({tilingScheme:t.terrainProvider.tilingScheme})):!f.tileCoordinates&&e(v)&&(t.imageryLayers.remove(v),v=void 0),!0}),this._tileCoordinatesSubscription=c.getObservable(this,"tileCoordinates").subscribe(function(){f._showTileCoordinates()}),this._tileBoundingSphereSubscription=c.getObservable(this,"tileBoundingSphere").subscribe(function(){f._showTileBoundingSphere()}),this._showTileBoundingSphere=d(function(){return f.tileBoundingSphere?_._surface.tileProvider._debug.boundingSphereTile=f._tile:_._surface.tileProvider._debug.boundingSphereTile=void 0,!0}),this._doFilterTile=d(function(){return f.filterTile?(f.suspendUpdates=!0,_._surface._tilesToRender=[],e(f._tile)&&f._tile.renderable&&_._surface._tilesToRender.push(f._tile)):f.suspendUpdates=!1,!0}),this._filterTileSubscription=c.getObservable(this,"filterTile").subscribe(function(){f.doFilterTile()}),this._pickPrimitive=d(function(){f.pickPrimitiveActive=!f.pickPrimitiveActive}),this._pickPrimitiveActiveSubscription=c.getObservable(this,"pickPrimitiveActive").subscribe(function(e){e?g.setInputAction(i,a.LEFT_CLICK):g.removeInputAction(a.LEFT_CLICK)}),this._pickTile=d(function(){f.pickTileActive=!f.pickTileActive}),this._pickTileActiveSubscription=c.getObservable(this,"pickTileActive").subscribe(function(e){e?g.setInputAction(h,a.LEFT_CLICK):g.removeInputAction(a.LEFT_CLICK)}),this._removePostRenderEvent=t.postRender.addEventListener(function(){f._update()})}return t(f.prototype,{scene:{get:function(){return this._scene}},performanceContainer:{get:function(){return this._performanceContainer}},toggleDropDown:{get:function(){return this._toggleDropDown}},showPrimitiveBoundingSphere:{get:function(){return this._showPrimitiveBoundingSphere}},showPrimitiveReferenceFrame:{get:function(){return this._showPrimitiveReferenceFrame}},doFilterPrimitive:{get:function(){return this._doFilterPrimitive}},incrementDepthFrustum:{get:function(){return this._incrementDepthFrustum}},decrementDepthFrustum:{get:function(){return this._decrementDepthFrustum}},showTileCoordinates:{get:function(){return this._showTileCoordinates}},showTileBoundingSphere:{get:function(){return this._showTileBoundingSphere}},doFilterTile:{get:function(){return this._doFilterTile}},toggleGeneral:{get:function(){return this._toggleGeneral}},togglePrimitives:{get:function(){return this._togglePrimitives}},toggleTerrain:{get:function(){return this._toggleTerrain}},pickPrimitive:{get:function(){return this._pickPrimitive}},pickTile:{get:function(){return this._pickTile}},selectParent:{get:function(){var e=this;return d(function(){e.tile=e.tile.parent})}},selectNW:{get:function(){var e=this;return d(function(){e.tile=e.tile.northwestChild})}},selectNE:{get:function(){var e=this;return d(function(){e.tile=e.tile.northeastChild})}},selectSW:{get:function(){var e=this;return d(function(){e.tile=e.tile.southwestChild})}},selectSE:{get:function(){var e=this;return d(function(){e.tile=e.tile.southeastChild})}},primitive:{get:function(){return this._primitive},set:function(t){var r=this._primitive;t!==r&&(this.hasPickedPrimitive=!0,e(r)&&(r.debugShowBoundingVolume=!1),this._scene.debugCommandFilter=void 0,e(this._modelMatrixPrimitive)&&(this._scene.primitives.remove(this._modelMatrixPrimitive),this._modelMatrixPrimitive=void 0),this._primitive=t,t.show=!1,setTimeout(function(){t.show=!0},50),this.showPrimitiveBoundingSphere(),this.showPrimitiveReferenceFrame(),this.doFilterPrimitive())}},tile:{get:function(){return this._tile},set:function(t){if(e(t)){this.hasPickedTile=!0;if(t!==this._tile){this.tileText="L: "+t.level+" X: "+t.x+" Y: "+t.y,this.tileText+="<br>SW corner: "+t.rectangle.west+", "+t.rectangle.south,this.tileText+="<br>NE corner: "+t.rectangle.east+", "+t.rectangle.north;var r=t.data;e(r)?this.tileText+="<br>Min: "+r.minimumHeight+" Max: "+r.maximumHeight:this.tileText+="<br>(Tile is not loaded)"}this._tile=t,this.showTileBoundingSphere(),this.doFilterTile()}else this.hasPickedTile=!1,this._tile=void 0}}}),f.prototype._update=function(){this.frustums&&(this.frustumStatisticText=h(this._scene.debugFrustumStatistics));var e=this._scene.numberOfFrustums;this._numberOfFrustums=e,this.depthFrustum=p(1,e,this.depthFrustum),this.depthFrustumText=this.depthFrustum+" of "+e,this.performance&&this._performanceDisplay.update(),this.primitiveReferenceFrame&&(this._modelMatrixPrimitive.modelMatrix=this._primitive.modelMatrix),this.shaderCacheText="Cached shaders: "+this._scene.context.shaderCache.numberOfShaders},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._eventHandler.destroy(),this._removePostRenderEvent(),this._frustumsSubscription.dispose(),this._frustumPlanesSubscription.dispose(),this._performanceSubscription.dispose(),this._primitiveBoundingSphereSubscription.dispose(),this._primitiveReferenceFrameSubscription.dispose(),this._filterPrimitiveSubscription.dispose(),this._wireframeSubscription.dispose(),this._globeDepthSubscription.dispose(),this._pickDepthSubscription.dispose(),this._depthFrustumSubscription.dispose(),this._suspendUpdatesSubscription.dispose(),this._tileCoordinatesSubscription.dispose(),this._tileBoundingSphereSubscription.dispose(),this._filterTileSubscription.dispose(),this._pickPrimitiveActiveSubscription.dispose(),this._pickTileActiveSubscription.dispose(),r(this)},f}),define("Widgets/CesiumInspector/CesiumInspector",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./CesiumInspectorViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){e=o(e);var r=document.createElement("div"),i=new a(t,r);this._viewModel=i,this._container=e;var s=document.createElement("div");this._element=s;var l=document.createElement("div");l.textContent="Cesium Inspector",l.className="cesium-cesiumInspector-button",l.setAttribute("data-bind","click: toggleDropDown"),s.appendChild(l),s.className="cesium-cesiumInspector",s.setAttribute("data-bind",'css: { "cesium-cesiumInspector-visible" : dropDownVisible, "cesium-cesiumInspector-hidden" : !dropDownVisible }'),e.appendChild(this._element);var u=document.createElement("div");this._panel=u,u.className="cesium-cesiumInspector-dropDown",s.appendChild(u);var c=document.createElement("div");c.className="cesium-cesiumInspector-sectionHeader";var d=document.createElement("span");d.className="cesium-cesiumInspector-toggleSwitch",d.setAttribute("data-bind","click: toggleGeneral, text: generalSwitchText"),c.appendChild(d),c.appendChild(document.createTextNode("General")),u.appendChild(c);var h=document.createElement("div");h.className="cesium-cesiumInspector-section", -h.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : generalVisible, "cesium-cesiumInspector-hide" : !generalVisible}'),u.appendChild(h);var p=document.createElement("div");h.appendChild(p);var f=document.createElement("div");f.className="cesium-cesiumInspector-frustumStatistics",f.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : frustums, "cesium-cesiumInspector-hide" : !frustums}, html: frustumStatisticText');var m=document.createElement("input");m.type="checkbox",m.setAttribute("data-bind","checked: frustums"),p.appendChild(m),p.appendChild(document.createTextNode("Show Frustums")),p.appendChild(f);var g=document.createElement("div");h.appendChild(g);var _=document.createElement("input");_.type="checkbox",_.setAttribute("data-bind","checked: frustumPlanes"),g.appendChild(_),g.appendChild(document.createTextNode("Show Frustum Planes"));var v=document.createElement("div");h.appendChild(v);var y=document.createElement("input");y.type="checkbox",y.setAttribute("data-bind","checked: performance"),v.appendChild(y),v.appendChild(document.createTextNode("Performance Display")),r.className="cesium-cesiumInspector-performanceDisplay",h.appendChild(r);var C=document.createElement("div");C.className="cesium-cesiumInspector-shaderCache",C.setAttribute("data-bind","html: shaderCacheText"),h.appendChild(C);var b=document.createElement("div");h.appendChild(b);var S=document.createElement("input");S.type="checkbox",S.setAttribute("data-bind","checked: globeDepth"),b.appendChild(S),b.appendChild(document.createTextNode("Show globe depth"));var w=document.createElement("div");b.appendChild(w);var T=document.createElement("div");h.appendChild(T);var A=document.createElement("input");A.type="checkbox",A.setAttribute("data-bind","checked: pickDepth"),T.appendChild(A),T.appendChild(document.createTextNode("Show pick depth"));var E=document.createElement("div");h.appendChild(E);var x=document.createElement("span");x.setAttribute("data-bind",'html: "     Frustum:"'),E.appendChild(x);var P=document.createElement("span");P.setAttribute("data-bind","text: depthFrustumText"),E.appendChild(P);var D=document.createElement("input");D.type="button",D.value="-",D.className="cesium-cesiumInspector-pickButton",D.setAttribute("data-bind","click: decrementDepthFrustum"),E.appendChild(D);var I=document.createElement("input");I.type="button",I.value="+",I.className="cesium-cesiumInspector-pickButton",I.setAttribute("data-bind","click: incrementDepthFrustum"),E.appendChild(I);var O=document.createElement("div");O.className="cesium-cesiumInspector-sectionHeader",d=document.createElement("span"),d.className="cesium-cesiumInspector-toggleSwitch",d.setAttribute("data-bind","click: togglePrimitives, text: primitivesSwitchText"),O.appendChild(d),O.appendChild(document.createTextNode("Primitives")),u.appendChild(O);var M=document.createElement("div");M.className="cesium-cesiumInspector-section",M.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : primitivesVisible, "cesium-cesiumInspector-hide" : !primitivesVisible}'),u.appendChild(M);var R=document.createElement("div");R.className="cesium-cesiumInspector-pickSection",M.appendChild(R);var N=document.createElement("input");N.type="button",N.value="Pick a primitive",N.className="cesium-cesiumInspector-pickButton",N.setAttribute("data-bind",'css: {"cesium-cesiumInspector-pickButtonHighlight" : pickPrimitiveActive}, click: pickPrimitive');var L=document.createElement("div");L.className="cesium-cesiumInspector-center",L.appendChild(N),R.appendChild(L);var k=document.createElement("div");R.appendChild(k);var F=document.createElement("input");F.type="checkbox",F.setAttribute("data-bind","checked: primitiveBoundingSphere, enable: hasPickedPrimitive"),k.appendChild(F),k.appendChild(document.createTextNode("Show bounding sphere"));var B=document.createElement("div");R.appendChild(B);var U=document.createElement("input");U.type="checkbox",U.setAttribute("data-bind","checked: primitiveReferenceFrame, enable: hasPickedPrimitive"),B.appendChild(U),B.appendChild(document.createTextNode("Show reference frame"));var V=document.createElement("div");this._primitiveOnly=V,R.appendChild(V);var z=document.createElement("input");z.type="checkbox",z.setAttribute("data-bind","checked: filterPrimitive, enable: hasPickedPrimitive"),V.appendChild(z),V.appendChild(document.createTextNode("Show only selected"));var G=document.createElement("div");G.className="cesium-cesiumInspector-sectionHeader",d=document.createElement("span"),d.className="cesium-cesiumInspector-toggleSwitch",d.setAttribute("data-bind","click: toggleTerrain, text: terrainSwitchText"),G.appendChild(d),G.appendChild(document.createTextNode("Terrain")),u.appendChild(G);var H=document.createElement("div");H.className="cesium-cesiumInspector-section",H.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : terrainVisible, "cesium-cesiumInspector-hide" : !terrainVisible}'),u.appendChild(H);var W=document.createElement("div");W.className="cesium-cesiumInspector-pickSection",H.appendChild(W);var j=document.createElement("input");j.type="button",j.value="Pick a tile",j.className="cesium-cesiumInspector-pickButton",j.setAttribute("data-bind",'css: {"cesium-cesiumInspector-pickButtonHighlight" : pickTileActive}, click: pickTile'),L=document.createElement("div"),L.appendChild(j),L.className="cesium-cesiumInspector-center",W.appendChild(L);var q=document.createElement("div");W.appendChild(q);var Y=document.createElement("input");Y.type="button",Y.value="Parent",Y.className="cesium-cesiumInspector-pickButton",Y.setAttribute("data-bind","click: selectParent");var X=document.createElement("input");X.type="button",X.value="NW",X.className="cesium-cesiumInspector-pickButton",X.setAttribute("data-bind","click: selectNW");var Q=document.createElement("input");Q.type="button",Q.value="NE",Q.className="cesium-cesiumInspector-pickButton",Q.setAttribute("data-bind","click: selectNE");var Z=document.createElement("input");Z.type="button",Z.value="SW",Z.className="cesium-cesiumInspector-pickButton",Z.setAttribute("data-bind","click: selectSW");var K=document.createElement("input");K.type="button",K.value="SE",K.className="cesium-cesiumInspector-pickButton",K.setAttribute("data-bind","click: selectSE");var J=document.createElement("div");J.className="cesium-cesiumInspector-tileText",q.className="cesium-cesiumInspector-frustumStatistics",q.appendChild(J),q.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : hasPickedTile, "cesium-cesiumInspector-hide" : !hasPickedTile}'),J.setAttribute("data-bind","html: tileText");var $=document.createElement("div");$.className="cesium-cesiumInspector-relativeText",$.textContent="Select relative:",q.appendChild($);var ee=document.createElement("table"),te=document.createElement("tr"),re=document.createElement("tr"),ie=document.createElement("td");ie.appendChild(Y);var ne=document.createElement("td");ne.appendChild(X);var oe=document.createElement("td");oe.appendChild(Q),te.appendChild(ie),te.appendChild(ne),te.appendChild(oe);var ae=document.createElement("td"),se=document.createElement("td");se.appendChild(Z);var le=document.createElement("td");le.appendChild(K),re.appendChild(ae),re.appendChild(se),re.appendChild(le),ee.appendChild(te),ee.appendChild(re),q.appendChild(ee);var ue=document.createElement("div");W.appendChild(ue);var ce=document.createElement("input");ce.type="checkbox",ce.setAttribute("data-bind","checked: tileBoundingSphere, enable: hasPickedTile"),ue.appendChild(ce),ue.appendChild(document.createTextNode("Show bounding volume"));var de=document.createElement("div");W.appendChild(de);var he=document.createElement("input");he.type="checkbox",he.setAttribute("data-bind","checked: filterTile, enable: hasPickedTile"),de.appendChild(he),de.appendChild(document.createTextNode("Show only selected"));var pe=document.createElement("div");H.appendChild(pe);var fe=document.createElement("input");fe.type="checkbox",fe.setAttribute("data-bind","checked: wireframe"),pe.appendChild(fe),pe.appendChild(document.createTextNode("Wireframe"));var me=document.createElement("div");H.appendChild(me);var ge=document.createElement("input");ge.type="checkbox",ge.setAttribute("data-bind","checked: suspendUpdates"),me.appendChild(ge),me.appendChild(document.createTextNode("Suspend LOD update"));var _e=document.createElement("div");H.appendChild(_e);var ve=document.createElement("input");ve.type="checkbox",ve.setAttribute("data-bind","checked: tileCoordinates"),_e.appendChild(ve),_e.appendChild(document.createTextNode("Show tile coordinates")),n.applyBindings(i,this._element)}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return n.cleanNode(this._element),this._container.removeChild(this._element),this.viewModel.destroy(),r(this)},s}),define("Widgets/CesiumWidget/CesiumWidget",["../../Core/buildModuleUrl","../../Core/Cartesian3","../../Core/Clock","../../Core/Credit","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Ellipsoid","../../Core/FeatureDetection","../../Core/formatError","../../Core/requestAnimationFrame","../../Core/ScreenSpaceEventHandler","../../Scene/BingMapsImageryProvider","../../Scene/Globe","../../Scene/Moon","../../Scene/Scene","../../Scene/SceneMode","../../Scene/ShadowMode","../../Scene/SkyAtmosphere","../../Scene/SkyBox","../../Scene/Sun","../getElement"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w){"use strict";function T(t){return e("Assets/Textures/SkyBox/tycho2t3_80_"+t+".jpg")}function A(e){function t(i){if(!e.isDestroyed())if(e._useDefaultRenderLoop)try{var n=e._targetFrameRate;if(o(n)){var a=1e3/n,s=i-r;s>a&&(e.resize(),e.render(),r=i-s%a),h(t)}else e.resize(),e.render(),h(t)}catch(t){if(e._useDefaultRenderLoop=!1,e._renderLoopRunning=!1,e._showRenderLoopErrors){e.showErrorPanel("An error occurred while rendering. Rendering has stopped.",void 0,t)}}else e._renderLoopRunning=!1}e._renderLoopRunning=!0;var r=0;h(t)}function E(e){var t=e._canvas,r=t.clientWidth,i=t.clientHeight,o=e._resolutionScale;e._supportsImageRenderingPixelated||(o*=n(window.devicePixelRatio,1)),e._canvasWidth=r,e._canvasHeight=i,r*=o,i*=o,t.width=r,t.height=i,e._canRender=0!==r&&0!==i}function x(e){var t=e._canvas,r=t.width,i=t.height;if(0!==r&&0!==i){var n=e._scene.camera.frustum;o(n.aspectRatio)?n.aspectRatio=r/i:(n.top=n.right*(i/r),n.bottom=-n.top)}}function P(e,a){e=w(e),a=n(a,{});var s=document.createElement("div");s.className="cesium-widget",e.appendChild(s);var l=document.createElement("canvas"),d=c.supportsImageRenderingPixelated();this._supportsImageRenderingPixelated=d,d&&(l.style.imageRendering=c.imageRenderingValue()),l.oncontextmenu=function(){return!1},l.onselectstart=function(){return!1},s.appendChild(l);var h=document.createElement("div");h.className="cesium-widget-credits";var A=o(a.creditContainer)?w(a.creditContainer):s;A.appendChild(h);var P=o(a.creditViewport)?w(a.creditViewport):s,I=n(a.showRenderLoopErrors,!0);this._element=s,this._container=e,this._canvas=l,this._canvasWidth=0,this._canvasHeight=0,this._creditViewport=P,this._creditContainer=A,this._innerCreditContainer=h,this._canRender=!1,this._renderLoopRunning=!1,this._showRenderLoopErrors=I,this._resolutionScale=1,this._forceResize=!1,this._clock=o(a.clock)?a.clock:new r,E(this);try{var O=new _({canvas:l,contextOptions:a.contextOptions,creditContainer:h,creditViewport:P,mapProjection:a.mapProjection,orderIndependentTranslucency:a.orderIndependentTranslucency,scene3DOnly:n(a.scene3DOnly,!1),terrainExaggeration:a.terrainExaggeration,shadows:a.shadows,mapMode2D:a.mapMode2D});this._scene=O,O.camera.constrainedAxis=t.UNIT_Z,x(this);var M=n(O.mapProjection.ellipsoid,u.WGS84),R=O.frameState.creditDisplay,N=new i({text:"Cesium",imageUrl:D,link:"http://cesiumjs.org/",showOnScreen:!0});R.addDefaultCredit(N);var L=a.globe;o(L)||(L=new m(M)),!1!==L&&(O.globe=L,O.globe.shadows=n(a.terrainShadows,y.RECEIVE_ONLY));var k=a.skyBox;o(k)||(k=new b({sources:{positiveX:T("px"),negativeX:T("mx"),positiveY:T("py"),negativeY:T("my"),positiveZ:T("pz"),negativeZ:T("mz")}})),!1!==k&&(O.skyBox=k,O.sun=new S,O.moon=new g);var F=a.skyAtmosphere;o(F)||(F=new C(M)),!1!==F&&(O.skyAtmosphere=F);var B=!1!==a.globe&&a.imageryProvider;o(B)||(B=new f({url:"https://dev.virtualearth.net"})),!1!==B&&O.imageryLayers.addImageryProvider(B),o(a.terrainProvider)&&!1!==a.globe&&(O.terrainProvider=a.terrainProvider),this._screenSpaceEventHandler=new p(l,!1),o(a.sceneMode)&&(a.sceneMode===v.SCENE2D&&this._scene.morphTo2D(0),a.sceneMode===v.COLUMBUS_VIEW&&this._scene.morphToColumbusView(0)),this._useDefaultRenderLoop=void 0,this.useDefaultRenderLoop=n(a.useDefaultRenderLoop,!0),this._targetFrameRate=void 0,this.targetFrameRate=a.targetFrameRate;var U=this;O.renderError.addEventListener(function(e,t){if(U._useDefaultRenderLoop=!1,U._renderLoopRunning=!1,U._showRenderLoopErrors){U.showErrorPanel("An error occurred while rendering. Rendering has stopped.",void 0,t)}})}catch(e){if(I){this.showErrorPanel("Error constructing CesiumWidget.",'Visit <a href="http://get.webgl.org">http://get.webgl.org</a> to verify that your web browser and hardware support WebGL. Consider trying a different web browser or updating your video drivers. Detailed error information is below:',e)}throw e}}var D="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAeCAYAAAD5AOomAAAQWUlEQVR42u1beXxOxxpudrEktkbUkriI4lZpq5JbW6pJuFG0qrFeexVRak3TBm3RUgS1hFhrCdKgQWKLrUGQBiVBJMgiq0Qiuyxzn/fzTu74ZPnS9nfrj4zf8/ty5sw7M+c8824zx0svVa3oAfqAAWAIGAHGCoy43oDb6TGqywta9JgsIq4GUAswB+oDDRXU5/ragCm3N6gm+MUkVJ+1kAg1AyyA5oAN8BrQCXiTfzsArwLWgCVQF6jJBOtXk/tikWrMGkiEtgTeAOyBfsAQS0vL8YMHD/aws7ObiuthwAeAA/A20AZozAvCRNHe6vI3k2rCprUp8DoR1qVLF1c/P7+A5OTkhyUlJaKwuETkPSkRBUUlgkpmZmbW2bNnQyZOnLgA7Z2BzkALNtM1qsl9MTSVSLUCugADAwMDTxKZVI7cfCw8DiWK6fselMLtlwSxJyxDPM4vFsXFxSWRkZFRkBsOdAdaAw2qyf37ij77RDMm1a5evXojY2NjH5BW7ruaIab4xotPd8cJV/xO0cKkPXGae97n0kR6TpHIzs7O7d279xdsvoncemwJqn3u/1lbDTnqfYXN6JCUlJS03CfFwt0/4TkiK8IEEBydWiBIy21tbaejr24cWJlpBVT6ShpVFvS10iddZP6MbFkyqpw2Kor6K5P9M33onG1Iv0omsz3Q//79+7HpuUViDsys697KyZy89ynk9Wc/x4u7DwvE48ePs2mRcARtqUTLRjxmDa6rpYWanDqZKHmyzJ+lTFlyUrZGGbIm3GdF49VQcnMjZUwTJW83Ua4NtayQmlEYKW1NlOc11RrLoAxLpqdYUSmnPlOlbk1qa21OZ7ovX758E/lTz1MpOmvp5gvp4qeL6c8sAjLNOQXF4sKFC6Hotw+nSrR46rAfb8hkN+WxVTTlyPplNuNmDArGGgFNgGZloClbHQtua8bj1eW+GnObZspY2nL1WKaOkreraKDk7jXLsEJGXG+u1b4Bz/0VZayyUkO5f2DCc5DvyZL/1inb0ONVU5+1dSBMcHrIvRwNMbqQ6u6fKGSZ4POszFaQDZNc0q9fvzkcjFkzKf/gfJjSo3c40OrBoL+7cvvXeUFYM17l1MuOTbxEV8a/uE8pZ8Ww4bouPJ62bFlyzXmebRg2jLY8jxa8WGopxEiX9jLff1Vp357zfluefyeOPxpp9WHAGl2fn/k1do+Ef/K86lYWs+hzJ7SSbXv06OFGAfAMRLtlBUjkPyfuidMyw3Fi37UM8TMCLFVj6W9qW1BYIg4ePBjEWkukdCTyZsyYMcvX13f7iRMnDv36669B0OxTBKRNx4OCggIPHDiwa+XKld+j7Xv84v/l4+Oz6PLlywHnzp07Su0gdyw4OPgYXQNHzp8/f+TixYuHw8LCDuDeGiaLXqLj6tWrlyLC9ztz5gy1PwEcV3AU89i3detWT2NjYyeWedvLy2va77//7hcREeHfsWPH91HX6/r16/7h4eH+6H+ZVtQvN3ToujXm9wPJYS6+FhYWzggmh4eGhh6hsTHnE/j7eN++fQczWY1Yc6WrIVJb0SLEu9iJ93I0JCTkKMY+PHLkSGe2MLV5TL3ytgxr88pwuHLlyvXY9CcaH6mSR5HwwRuPRWZekTgXnfPcfW0QqfMDk0Qc+nqCnDc+Pj6FNzJoE+PfeDEXhQ6FtD0rKyu9Tp06LpAbBN9/S+hYEJmnck79EazQA5myVTKeyM/Pp7jgI2AAXv4JeW/AgAGzUTdKXj969CiOF04T1jhj/qXrzrgfQ+0KUdq1azdt6tSpntrjxcTEUGroyBrdkLmoy3x0HT9+vIe2zIoVK9y5fT0eU688/2rOJqY/bTRcjsl5hqRPYF5P38nSdJrwMErzezMpX1NfHrELjiQ9fbl56SIjO5leViH6nwwMnjZt2gL5EmWh/Lf4f+U5BtauXbsJshPu3LkTLQl/+PBhVmpqagZ+HxHS0tLSCShpGRkZqXhp12i8RYsWrVP7wr1ctM9E2wy0lch88uRJoWwTFRV1A7JjoVnBss7BwWEJ6ubIa/SRgOt32VybKduvZILtMbd4JraoZcuWC8eMGbNN+7noWTt06DCVXUIL9rtNOdj8uABFW+bbb7/9js34y4o5fo5YI14h7QwNDV1yc3MLAsIfP0PS9kvpmg6Db+wXn6/pKrwOztBcn7mTXWbEPHlPvMguKBFFxYXiq819hZu3k6Y9xpgFjN+xY8cBOcmkpKQ0rh8HDCUieHNjHExgmGwHQomkKbdu3bpP10VFRcU2NjZ7UbcKWATMB74C3IBpSn8jTp48eVb2k5iYSNq4BVjJcl8zFrq5ue3Py8vLB/Kg4USa6+nTp0OkLNwUmfYFckGiTRJZH1YKc3Zp5mye+yQnJydQOyyYImtr65XDhw/3lX2B7BJlgaSxhXiL+6K99z4wwadkG/RRLP/28PBYxpaiES+mcokllW4PczcUz1Twy++ZpSTRrhJtUCSnx4gvNzkL9419xBfevUVIxEHNIEuDUp4j90ZCHjSqUHj+/AnaOmnkmFgyIa6Y8Hk5SScnp6VMwLs82Tc5wOkJv9Tfz89v3f79+73xMPTyJyrEloCI8+PGjTs0adIkX1dXVx+Yuu2ff/75tlmzZm1A+xUDBw6kHHo4/GqQHA8Lt9DT0/OSu7v70SlTpuwdMmTIFhC2tlmzZivQ9geAtOFLgLRoGhbFJSnbrVu3DahbrEXs+4pZrMm/FGj1xaJNlMRaWVmtGTZs2D7ZV3R0dA6sWJG8Riayhd1GNzbNo0nTpWWbP3/+dYXY5fyOLCsjti5Hbh/hwfODbmeVkkS5rCgpFgt2DNaQKjHTy16kZsRpBpp1IKE0uNoSkqapO3llp2YBUFuPLf01Jgf9007UFAQCv8lJmpubf4Y6J478rNgMWfHL6cRBE+1e9SXTKInVpdy7d+8KmbOhQ4d+rasMLRjML5xMLlkSBFShCrEbiXxJLDQymQ8/2rN/lKkJXQ+AdUiSxDZv3nydSuzNmzczQWaEvIZbeESuhhf5mLt375Y+Z0BAQDQW7Dl5PXfu3KW6EGvIfoEisL6Ya+p1aBz5z/N3czQdbQ5w12ieSizhu13DEPHmajYiKDXyPJmiaX8t6pSYs8FB04bM8ObAL2ijIg/9zyCtU4lFBDqJA6p2nE/KPLMVmyRbToGcq0osAq0rrFEu8Eve5IfJhOsiCxN8FXJzjx07FqYQ6426JZJYaGQKu463eO4W/EvXLiqx0Ni1MMV+ig9PR5ut0PosWbd582bKHL50cXHZIOMMGqtJkybrQWZpEDdv3rwfdCHWgCM5yo3s/f39j9G8H2Y/tRKXbgUItw2Oz5EqSfMJWvT0dCefA5PsVPHNTx+VtpkFzb4Ve0ncuHHjLq/I0UhJSv1W27Zt57F/6cpp0Gv8awfz6Lxq1ar5P/7448KxY8eSH/5UNcUffPBBQKdOnTZ37tx5la2t7VI7O7vv33nnnYUwrR6Ojo7TEIm6sFkjckfxwvIAaMyvTE1NPRC4LEFQtAH9+yOVSFYiXvLFC48ePXpF1nXv3n09mWqF2Ie4/oTHeIM19Q2+/iQhISFVIXb1iBEj9irWhCL2pXPmzPlF9aOoW4+gL13W7d69+ywtMASApe1glhez2yqXWJnH1uDVRv5tpMY0PE4Qu4IWlkmoNlb6TRKRcaHiQoS/+Ir9sMTCnYM1q27NmjW+tIqJxMOHDwfISe7bty8YdZ8pZ7r9aZOEruE7F2lFqZ+pwRNI8WG/SGTNZuKm8gIawlrusGDBgi+wsEJ+Q8Fq38W+fg7LkHv4hoKwUaNGlWoFLEwuEatqrL29PQVq86TW5+Tk5LP8aDK9PN4AvnaXPhKBbSEW6bLRo0fvkH3FxsYmcaA3m6JzWR8ZGVlKKmUoHAhORFywSysqfqui4Enbz1JE5nz16tXwrNx0nUh9Gkw5QTPfFbPX93pWo6Hpp6740EqkVOc/lNzTZgM0cKVq9qAdmSlPS5IEHjaN8h7Z5iAKpUt48LsyTYCGPcBc7+L3DvLi2xEREYSbt2/fDkdwci0sLOwwRZfbt29frmhFIdpEgehIkqFfRN9RQAzmkSvbQdvIzLqdOnWqNN+GFaAoeircVYr68rHoohG138KYN+mXji1Rny1NKeKWXDMzM/cJEyZskHIPUMiX0ntp06aNm5riSYsA0+zLpn6Ql5fXRnl/8eLFX7NVsygv3VHNcU3ev+xC23800NlrvqUBUFVBckv3jNZMBNHnSvajr/OEHLDaM3X1lSCjoFGjRmRKhyGoiKziBgWZRWf0kSeqUGbOnOlJmod44Iys+/DDD8kiuMAULlMXXWUFUfkhIhB9LpZ1WBwxHBDSexmIBXFTlcHCeMQuqidh586dK+S91atXu3EkXp83KPQrOt0xZq2loMVh2bJlmmT6+OVt0MT3qkiqk1jsM0LkFWQL0iI2rx2UjXfyo73gPzZCu64iyIhHYJMMJU2RoJ0ikBiOiNBn0KBBY/gB7UNDQ3/B/QTcT1SRmpqaQEA/D3A/HtoXGxcXd07uy3bt2nUQSPKHJkbLthIsnwifGY/5/oZ0gnxwb5ojTPG6jIyMGCySBCz4gTJKnz59+szg4OBAjBEFkuIg+wxQojHXszD983hx9Zw8efI4EBZHgFYHsjnV7JdjfkMw50R+hnikauM4QKJspb23t/dkuAeaR9ySJUuG8Lusw9ZWr7KvEU15N4P2Lt9HZKjZdTkeuk3MRcpSVmT8DKEbe2vaePlPFyX4B8IoHfiYH6AJJ+/m7PRtuL47r9revJfch/92YDK78Hxas0xHDrTeU2R6c8rkWIZcK/5mqx1vondnWUeWUdGL++7EL9SG5Tooc2ihFbH3VPpzVOZgz4ugI6durVjLpNV6lRd5Y/5tx3Puxv3Kzf5G3KaFcpjQvCqfHKmH7Y15An3hqDeRWaZo1+fkIjFjXQ9NKiNNNJFJvpR87JLdI8X95HCNj6CjOtrJ4uituXLUZKwk8pbKCUpr5fSkNZNhxe6hIbeXR3bNFBlttOKX0Izb1mfZhtyXFcu20kFOfmZrwQteHtXJI8AmvKfbUulPLiRrTtvk8WFdPhyw4P4b8DupxZrXgOfXTHnmOvyu5P6x/NxX7nIZVuXA3Yg7asyrxoG+RER4HoMorzj/SY64ijw18OIm4Xd2uTh4fq04f+OASEy7pyGUvrqYPXv2CvYfb/JEzbUOlA342lR5MDNFo+UZam1+MBPlgNuU69X25mXI1lIO6qVsTUXWrAK5GloH49qH3Ophf21l/mZlzL2G1gG9aTkfEJgoHwDU1LpvqIxZ0eG8TuTKM8VWbCKcoYGj1q1btwehegJtPVIuSVEmnd8iQDhtbW3tamxs/CGbs7a8OOooDr68z1QMlQdUH0b7kxX1sxbDSmBQzqcoBpXIGJQjo/1ZSmVzqaivyvozqOB96f+Z78b0lLPFumwabFgDe3K+NpDz0kH8rXEvNrttWUvr6/DRuJ6O+CMyf0a2Ku+pqn390Xt/6QduBopPNFe2zFrJaI2dfmv2XZbsz2op5qL6v3m8oF8vqv9/R/oB+Q1RPf41U3yT0R+x/9Xlryn/BY268qsf3smdAAAAAElFTkSuQmCC";return a(P.prototype,{container:{get:function(){return this._container}},canvas:{get:function(){return this._canvas}},creditContainer:{get:function(){return this._creditContainer}},creditViewport:{get:function(){return this._creditViewport}},scene:{get:function(){return this._scene}},imageryLayers:{get:function(){return this._scene.imageryLayers}},terrainProvider:{get:function(){return this._scene.terrainProvider},set:function(e){this._scene.terrainProvider=e}},camera:{get:function(){return this._scene.camera}},clock:{get:function(){return this._clock}},screenSpaceEventHandler:{get:function(){return this._screenSpaceEventHandler}},targetFrameRate:{get:function(){return this._targetFrameRate},set:function(e){this._targetFrameRate=e}},useDefaultRenderLoop:{get:function(){return this._useDefaultRenderLoop},set:function(e){this._useDefaultRenderLoop!==e&&(this._useDefaultRenderLoop=e,e&&!this._renderLoopRunning&&A(this))}},resolutionScale:{get:function(){return this._resolutionScale},set:function(e){this._resolutionScale=e,this._forceResize=!0}}}),P.prototype.showErrorPanel=function(e,t,r){function i(){u.style.maxHeight=Math.max(Math.round(.9*n.clientHeight-100),30)+"px"}var n=this._element,a=document.createElement("div");a.className="cesium-widget-errorPanel";var s=document.createElement("div");s.className="cesium-widget-errorPanel-content",a.appendChild(s);var l=document.createElement("div");l.className="cesium-widget-errorPanel-header",l.appendChild(document.createTextNode(e)),s.appendChild(l);var u=document.createElement("div");if(u.className="cesium-widget-errorPanel-scroll",s.appendChild(u),i(),o(window.addEventListener)&&window.addEventListener("resize",i,!1),o(t)){var c=document.createElement("div");c.className="cesium-widget-errorPanel-message",c.innerHTML="<p>"+t+"</p>",u.appendChild(c)}var h="(no error details available)";o(r)&&(h=d(r));var p=document.createElement("div");p.className="cesium-widget-errorPanel-message",p.appendChild(document.createTextNode(h)),u.appendChild(p);var f=document.createElement("div");f.className="cesium-widget-errorPanel-buttonPanel",s.appendChild(f);var m=document.createElement("button");m.setAttribute("type","button"),m.className="cesium-button",m.appendChild(document.createTextNode("OK")),m.onclick=function(){o(i)&&o(window.removeEventListener)&&window.removeEventListener("resize",i,!1),n.removeChild(a)},f.appendChild(m),n.appendChild(a),"undefined"!=typeof console&&console.error(e+"\n"+t+"\n"+h)},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){this._scene=this._scene&&this._scene.destroy(),this._container.removeChild(this._element),this._creditContainer.removeChild(this._innerCreditContainer),s(this)},P.prototype.resize=function(){var e=this._canvas,t=e.clientWidth,r=e.clientHeight;(this._forceResize||this._canvasWidth!==t||this._canvasHeight!==r)&&(this._forceResize=!1,E(this),x(this))},P.prototype.render=function(){if(this._canRender){this._scene.initializeFrame();var e=this._clock.tick();this._scene.render(e)}else this._clock.tick()},P}),define("Widgets/ClockViewModel",["../Core/Clock","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/EventHelper","../Core/JulianDate","../ThirdParty/knockout"],function(e,t,r,i,n,o,a){"use strict";function s(r){t(r)||(r=new e),this._clock=r,this._eventHelper=new n,this._eventHelper.add(r.onTick,this.synchronize,this),this.systemTime=a.observable(o.now()),this.systemTime.equalityComparer=o.equals,this.startTime=a.observable(r.startTime),this.startTime.equalityComparer=o.equals,this.startTime.subscribe(function(e){r.startTime=e,this.synchronize()},this),this.stopTime=a.observable(r.stopTime),this.stopTime.equalityComparer=o.equals,this.stopTime.subscribe(function(e){r.stopTime=e,this.synchronize()},this),this.currentTime=a.observable(r.currentTime),this.currentTime.equalityComparer=o.equals,this.currentTime.subscribe(function(e){r.currentTime=e,this.synchronize()},this),this.multiplier=a.observable(r.multiplier),this.multiplier.subscribe(function(e){r.multiplier=e,this.synchronize()},this),this.clockStep=a.observable(r.clockStep),this.clockStep.subscribe(function(e){r.clockStep=e,this.synchronize()},this),this.clockRange=a.observable(r.clockRange),this.clockRange.subscribe(function(e){r.clockRange=e,this.synchronize()},this),this.canAnimate=a.observable(r.canAnimate),this.canAnimate.subscribe(function(e){r.canAnimate=e,this.synchronize()},this),this.shouldAnimate=a.observable(r.shouldAnimate),this.shouldAnimate.subscribe(function(e){r.shouldAnimate=e,this.synchronize()},this),a.track(this,["systemTime","startTime","stopTime","currentTime","multiplier","clockStep","clockRange","canAnimate","shouldAnimate"])}return r(s.prototype,{clock:{get:function(){return this._clock}}}),s.prototype.synchronize=function(){var e=this._clock;this.systemTime=o.now(),this.startTime=e.startTime,this.stopTime=e.stopTime,this.currentTime=e.currentTime,this.multiplier=e.multiplier,this.clockStep=e.clockStep,this.clockRange=e.clockRange,this.canAnimate=e.canAnimate,this.shouldAnimate=e.shouldAnimate},s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){this._eventHelper.removeAll(),i(this)},s}),define("Widgets/Command",["../Core/DeveloperError"],function(e){"use strict";function t(){this.canExecute=void 0,this.beforeExecute=void 0,this.afterExecute=void 0,e.throwInstantiationError()}return t}),define("Widgets/FullscreenButton/FullscreenButtonViewModel",["../../Core/defaultValue","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Fullscreen","../../ThirdParty/knockout","../createCommand","../getElement"],function(e,t,r,i,n,o,a,s){"use strict";function l(t){var r=this,i=o.observable(n.fullscreen),l=o.observable(n.enabled);this.isFullscreen=void 0,o.defineProperty(this,"isFullscreen",{get:function(){return i()}}),this.isFullscreenEnabled=void 0,o.defineProperty(this,"isFullscreenEnabled",{get:function(){return l()},set:function(e){l(e&&n.enabled)}}),this.tooltip=void 0,o.defineProperty(this,"tooltip",function(){return this.isFullscreenEnabled?i()?"Exit full screen":"Full screen":"Full screen unavailable"}),this._command=a(function(){n.fullscreen?n.exitFullscreen():n.requestFullscreen(r._fullscreenElement)},o.getObservable(this,"isFullscreenEnabled")),this._fullscreenElement=e(s(t),document.body),this._callback=function(){i(n.fullscreen)},document.addEventListener(n.changeEventName,this._callback)}return t(l.prototype,{fullscreenElement:{get:function(){return this._fullscreenElement},set:function(e){this._fullscreenElement=e}},command:{get:function(){return this._command}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){document.removeEventListener(n.changeEventName,this._callback),r(this)},l}),define("Widgets/FullscreenButton/FullscreenButton",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./FullscreenButtonViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){e=o(e);var r=new a(t);r._exitFullScreenPath=u,r._enterFullScreenPath=l;var i=document.createElement("button");i.type="button",i.className="cesium-button cesium-fullscreenButton",i.setAttribute("data-bind","attr: { title: tooltip },click: command,enable: isFullscreenEnabled,cesiumSvgPath: { path: isFullscreen ? _exitFullScreenPath : _enterFullScreenPath, width: 128, height: 128 }"),e.appendChild(i),n.applyBindings(r,i),this._container=e,this._viewModel=r,this._element=i}var l="M 83.96875 17.5625 L 83.96875 17.59375 L 76.65625 24.875 L 97.09375 24.96875 L 76.09375 45.96875 L 81.9375 51.8125 L 102.78125 30.9375 L 102.875 51.15625 L 110.15625 43.875 L 110.1875 17.59375 L 83.96875 17.5625 z M 44.125 17.59375 L 17.90625 17.625 L 17.9375 43.90625 L 25.21875 51.1875 L 25.3125 30.96875 L 46.15625 51.8125 L 52 45.96875 L 31 25 L 51.4375 24.90625 L 44.125 17.59375 z M 46.0625 76.03125 L 25.1875 96.875 L 25.09375 76.65625 L 17.8125 83.9375 L 17.8125 110.21875 L 44 110.25 L 51.3125 102.9375 L 30.90625 102.84375 L 51.875 81.875 L 46.0625 76.03125 z M 82 76.15625 L 76.15625 82 L 97.15625 103 L 76.71875 103.0625 L 84.03125 110.375 L 110.25 110.34375 L 110.21875 84.0625 L 102.9375 76.8125 L 102.84375 97 L 82 76.15625 z",u="M 104.34375 17.5625 L 83.5 38.4375 L 83.40625 18.21875 L 76.125 25.5 L 76.09375 51.78125 L 102.3125 51.8125 L 102.3125 51.78125 L 109.625 44.5 L 89.1875 44.40625 L 110.1875 23.40625 L 104.34375 17.5625 z M 23.75 17.59375 L 17.90625 23.4375 L 38.90625 44.4375 L 18.5 44.53125 L 25.78125 51.8125 L 52 51.78125 L 51.96875 25.53125 L 44.6875 18.25 L 44.625 38.46875 L 23.75 17.59375 z M 25.6875 76.03125 L 18.375 83.3125 L 38.78125 83.40625 L 17.8125 104.40625 L 23.625 110.25 L 44.5 89.375 L 44.59375 109.59375 L 51.875 102.3125 L 51.875 76.0625 L 25.6875 76.03125 z M 102.375 76.15625 L 76.15625 76.1875 L 76.1875 102.4375 L 83.46875 109.71875 L 83.5625 89.53125 L 104.40625 110.375 L 110.25 104.53125 L 89.25 83.53125 L 109.6875 83.46875 L 102.375 76.15625 z";return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this._viewModel.destroy(),n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/Geocoder/GeocoderViewModel",["../../Core/BingMapsGeocoderService","../../Core/CartographicGeocoderService","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/Event","../../Core/Matrix4","../../ThirdParty/knockout","../../ThirdParty/when","../createCommand","../getElement"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(n){i(n.geocoderServices)?this._geocoderServices=n.geocoderServices:this._geocoderServices=[new t,new e({scene:n.scene})],this._viewContainer=n.container,this._scene=n.scene,this._flightDuration=n.flightDuration,this._searchText="",this._isSearchInProgress=!1,this._geocodePromise=void 0,this._complete=new a,this._suggestions=[],this._selectedSuggestion=void 0,this._showSuggestions=!0,this._updateCamera=m,this._adjustSuggestionsScroll=v,this._updateSearchSuggestions=S,this._handleArrowDown=f,this._handleArrowUp=p;var o=this;this._suggestionsVisible=l.pureComputed(function(){var e=l.getObservable(o,"_suggestions"),t=e().length>0,r=l.getObservable(o,"_showSuggestions")();return t&&r}),this._searchCommand=c(function(){if(o._focusTextbox=!1,i(o._selectedSuggestion))return o.activateSuggestion(o._selectedSuggestion),!1;o.hideSuggestions(),o.isSearchInProgress?y(o):_(o,o._geocoderServices)}),this.deselectSuggestion=function(){o._selectedSuggestion=void 0},this.handleKeyDown=function(e,t){var r="ArrowDown"===t.key||"Down"===t.key||40===t.keyCode,i="ArrowUp"===t.key||"Up"===t.key||38===t.keyCode;return(r||i)&&t.preventDefault(),!0},this.handleKeyUp=function(e,t){var r="ArrowDown"===t.key||"Down"===t.key||40===t.keyCode,i="ArrowUp"===t.key||"Up"===t.key||38===t.keyCode,n="Enter"===t.key||13===t.keyCode;return i?p(o):r?f(o):n&&o._searchCommand(),!0},this.activateSuggestion=function(e){o.hideSuggestions(),o._searchText=e.displayName;var t=e.destination;b(o),m(o,t)},this.hideSuggestions=function(){o._showSuggestions=!1,o._selectedSuggestion=void 0},this.showSuggestions=function(){o._showSuggestions=!0},this.handleMouseover=function(e,t){e!==o._selectedSuggestion&&(o._selectedSuggestion=e)},this.keepExpanded=!1,this.autoComplete=r(n.autocomplete,!0),this._focusTextbox=!1,l.track(this,["_searchText","_isSearchInProgress","keepExpanded","_suggestions","_selectedSuggestion","_showSuggestions","_focusTextbox"]);var s=l.getObservable(this,"_searchText");s.extend({rateLimit:{timeout:500}}),this._suggestionSubscription=s.subscribe(function(){S(o)}),this.isSearchInProgress=void 0,l.defineProperty(this,"isSearchInProgress",{get:function(){return this._isSearchInProgress}}),this.searchText=void 0,l.defineProperty(this,"searchText",{get:function(){return this.isSearchInProgress?"Searching...":this._searchText},set:function(e){this._searchText=e}}),this.flightDuration=void 0,l.defineProperty(this,"flightDuration",{get:function(){return this._flightDuration},set:function(e){this._flightDuration=e}})}function p(e){if(0!==e._suggestions.length){var t,r=e._suggestions.indexOf(e._selectedSuggestion);if(-1===r||0===r)return void(e._selectedSuggestion=void 0);t=r-1,e._selectedSuggestion=e._suggestions[t],v(e,t)}}function f(e){if(0!==e._suggestions.length){var t=e._suggestions.length,r=e._suggestions.indexOf(e._selectedSuggestion),i=(r+1)%t;e._selectedSuggestion=e._suggestions[i],v(e,i)}}function m(e,t){ -e._scene.camera.flyTo({destination:t,complete:function(){e._complete.raiseEvent()},duration:e._flightDuration,endTransform:s.IDENTITY})}function g(e,t,r){return e.then(function(e){return i(e)&&"fulfilled"===e.state&&e.value.length>0?e:t.geocode(r).then(function(e){return{state:"fulfilled",value:e}}).otherwise(function(e){return{state:"rejected",reason:e}})})}function _(e,t){var r=e._searchText;if(C(r))return void e.showSuggestions();e._isSearchInProgress=!0;for(var n=u.resolve(),o=0;o<t.length;o++)n=g(n,t[o],r);e._geocodePromise=n,n.then(function(t){if(!n.cancel){e._isSearchInProgress=!1;var o=t.value;if("fulfilled"===t.state&&i(o)&&o.length>0)return e._searchText=o[0].displayName,void m(e,o[0].destination);e._searchText=r+" (not found)"}})}function v(e,t){var r=d(e._viewContainer),i=r.getElementsByClassName("search-results")[0],n=r.getElementsByTagName("li"),o=n[t];if(0===t)return void(i.scrollTop=0);var a=o.offsetTop;a+o.clientHeight>i.clientHeight?i.scrollTop=a+o.clientHeight:a<i.scrollTop&&(i.scrollTop=a)}function y(e){e._isSearchInProgress=!1,i(e._geocodePromise)&&(e._geocodePromise.cancel=!0,e._geocodePromise=void 0)}function C(e){return/^\s*$/.test(e)}function b(e){l.getObservable(e,"_suggestions").removeAll()}function S(e){if(e.autoComplete){var t=e._searchText;if(b(e),!C(t)){var r=u.resolve([]);e._geocoderServices.forEach(function(e){r=r.then(function(r){return r.length>=5?r:e.geocode(t).then(function(e){return r=r.concat(e)})})}),r.then(function(t){for(var r=e._suggestions,i=0;i<t.length;i++)r.push(t[i])})}}}return n(h.prototype,{complete:{get:function(){return this._complete}},scene:{get:function(){return this._scene}},search:{get:function(){return this._searchCommand}},selectedSuggestion:{get:function(){return this._selectedSuggestion}},suggestions:{get:function(){return this._suggestions}}}),h.prototype.destroy=function(){this._suggestionSubscription.dispose()},h}),define("Widgets/Geocoder/Geocoder",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./GeocoderViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){var t=a(e.container),r=new s(e);r._startSearchPath=u,r._stopSearchPath=c;var i=document.createElement("form");i.setAttribute("data-bind","submit: search");var l=document.createElement("input");l.type="search",l.className="cesium-geocoder-input",l.setAttribute("placeholder","Enter an address or landmark..."),l.setAttribute("data-bind",'textInput: searchText,disable: isSearchInProgress,event: { keyup: handleKeyUp, keydown: handleKeyDown, mouseover: deselectSuggestion },css: { "cesium-geocoder-input-wide" : keepExpanded || searchText.length > 0 },hasFocus: _focusTextbox'),this._onTextBoxFocus=function(){setTimeout(function(){l.select()},0)},l.addEventListener("focus",this._onTextBoxFocus,!1),i.appendChild(l),this._textBox=l;var d=document.createElement("span");d.className="cesium-geocoder-searchButton",d.setAttribute("data-bind","click: search,cesiumSvgPath: { path: isSearchInProgress ? _stopSearchPath : _startSearchPath, width: 32, height: 32 }"),i.appendChild(d),t.appendChild(i);var h=document.createElement("div");h.className="search-results",h.setAttribute("data-bind","visible: _suggestionsVisible");var p=document.createElement("ul");p.setAttribute("data-bind","foreach: _suggestions");var f=document.createElement("li");p.appendChild(f),f.setAttribute("data-bind","text: $data.displayName, click: $parent.activateSuggestion, event: { mouseover: $parent.handleMouseover}, css: { active: $data === $parent._selectedSuggestion }"),h.appendChild(p),t.appendChild(h),o.applyBindings(r,i),o.applyBindings(r,h),this._container=t,this._searchSuggestionsContainer=h,this._viewModel=r,this._form=i,this._onInputBegin=function(e){t.contains(e.target)||(r._focusTextbox=!1,r.hideSuggestions())},this._onInputEnd=function(e){t.contains(e.target)&&(r._focusTextbox=!0,r.showSuggestions())},n.supportsPointerEvents()?(document.addEventListener("pointerdown",this._onInputBegin,!0),document.addEventListener("pointerup",this._onInputEnd,!0),document.addEventListener("pointercancel",this._onInputEnd,!0)):(document.addEventListener("mousedown",this._onInputBegin,!0),document.addEventListener("mouseup",this._onInputEnd,!0),document.addEventListener("touchstart",this._onInputBegin,!0),document.addEventListener("touchend",this._onInputEnd,!0),document.addEventListener("touchcancel",this._onInputEnd,!0))}var u="M29.772,26.433l-7.126-7.126c0.96-1.583,1.523-3.435,1.524-5.421C24.169,8.093,19.478,3.401,13.688,3.399C7.897,3.401,3.204,8.093,3.204,13.885c0,5.789,4.693,10.481,10.484,10.481c1.987,0,3.839-0.563,5.422-1.523l7.128,7.127L29.772,26.433zM7.203,13.885c0.006-3.582,2.903-6.478,6.484-6.486c3.579,0.008,6.478,2.904,6.484,6.486c-0.007,3.58-2.905,6.476-6.484,6.484C10.106,20.361,7.209,17.465,7.203,13.885z",c="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z";return t(l.prototype,{container:{get:function(){return this._container}},searchSuggestionsContainer:{get:function(){return this._searchSuggestionsContainer}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return n.supportsPointerEvents()?(document.removeEventListener("pointerdown",this._onInputBegin,!0),document.removeEventListener("pointerup",this._onInputEnd,!0)):(document.removeEventListener("mousedown",this._onInputBegin,!0),document.removeEventListener("mouseup",this._onInputEnd,!0),document.removeEventListener("touchstart",this._onInputBegin,!0),document.removeEventListener("touchend",this._onInputEnd,!0)),this._viewModel.destroy(),o.cleanNode(this._form),o.cleanNode(this._searchSuggestionsContainer),this._container.removeChild(this._form),this._container.removeChild(this._searchSuggestionsContainer),this._textBox.removeEventListener("focus",this._onTextBoxFocus,!1),r(this)},l}),define("Widgets/HomeButton/HomeButtonViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n){"use strict";function o(e,t){this._scene=e,this._duration=t;var r=this;this._command=n(function(){r._scene.camera.flyHome(r._duration)}),this.tooltip="View Home",i.track(this,["tooltip"])}return t(o.prototype,{scene:{get:function(){return this._scene}},command:{get:function(){return this._command}},duration:{get:function(){return this._duration},set:function(e){this._duration=e}}}),o}),define("Widgets/HomeButton/HomeButton",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./HomeButtonViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t,r){e=o(e);var i=new a(t,r);i._svgPath="M14,4l-10,8.75h20l-4.25-3.7188v-4.6562h-2.812v2.1875l-2.938-2.5625zm-7.0938,9.906v10.094h14.094v-10.094h-14.094zm2.1876,2.313h3.3122v4.25h-3.3122v-4.25zm5.8442,1.281h3.406v6.438h-3.406v-6.438z";var s=document.createElement("button");s.type="button",s.className="cesium-button cesium-toolbar-button cesium-home-button",s.setAttribute("data-bind","attr: { title: tooltip },click: command,cesiumSvgPath: { path: _svgPath, width: 28, height: 28 }"),e.appendChild(s),n.applyBindings(i,s),this._container=e,this._viewModel=i,this._element=s}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/InfoBox/InfoBoxViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/Event","../../ThirdParty/knockout"],function(e,t,r,i){"use strict";function n(){this._cameraClicked=new r,this._closeClicked=new r,this.maxHeight=500,this.enableCamera=!1,this.isCameraTracking=!1,this.showInfo=!1,this.titleText="",this.description="",i.track(this,["showInfo","titleText","description","maxHeight","enableCamera","isCameraTracking"]),this._loadingIndicatorHtml='<div class="cesium-infoBox-loadingContainer"><span class="cesium-infoBox-loading"></span></div>',this.cameraIconPath=void 0,i.defineProperty(this,"cameraIconPath",{get:function(){return!this.enableCamera||this.isCameraTracking?a:o}}),i.defineProperty(this,"_bodyless",{get:function(){return!e(this.description)||0===this.description.length}})}var o="M 13.84375 7.03125 C 11.412798 7.03125 9.46875 8.975298 9.46875 11.40625 L 9.46875 11.59375 L 2.53125 7.21875 L 2.53125 24.0625 L 9.46875 19.6875 C 9.4853444 22.104033 11.423165 24.0625 13.84375 24.0625 L 25.875 24.0625 C 28.305952 24.0625 30.28125 22.087202 30.28125 19.65625 L 30.28125 11.40625 C 30.28125 8.975298 28.305952 7.03125 25.875 7.03125 L 13.84375 7.03125 z",a="M 27.34375 1.65625 L 5.28125 27.9375 L 8.09375 30.3125 L 30.15625 4.03125 L 27.34375 1.65625 z M 13.84375 7.03125 C 11.412798 7.03125 9.46875 8.975298 9.46875 11.40625 L 9.46875 11.59375 L 2.53125 7.21875 L 2.53125 24.0625 L 9.46875 19.6875 C 9.4724893 20.232036 9.5676108 20.7379 9.75 21.21875 L 21.65625 7.03125 L 13.84375 7.03125 z M 28.21875 7.71875 L 14.53125 24.0625 L 25.875 24.0625 C 28.305952 24.0625 30.28125 22.087202 30.28125 19.65625 L 30.28125 11.40625 C 30.28125 9.8371439 29.456025 8.4902779 28.21875 7.71875 z";return n.prototype.maxHeightOffset=function(e){return this.maxHeight-e+"px"},t(n.prototype,{cameraClicked:{get:function(){return this._cameraClicked}},closeClicked:{get:function(){return this._closeClicked}}}),n}),define("Widgets/InfoBox/InfoBox",["../../Core/buildModuleUrl","../../Core/Check","../../Core/Color","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../ThirdParty/knockout","../getElement","../subscribeAndEvaluate","./InfoBoxViewModel"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t){t=s(t);var n=document.createElement("div");n.className="cesium-infoBox",n.setAttribute("data-bind",'css: { "cesium-infoBox-visible" : showInfo, "cesium-infoBox-bodyless" : _bodyless }'),t.appendChild(n);var o=document.createElement("div");o.className="cesium-infoBox-title",o.setAttribute("data-bind","text: titleText"),n.appendChild(o);var c=document.createElement("button");c.type="button",c.className="cesium-button cesium-infoBox-camera",c.setAttribute("data-bind",'attr: { title: "Focus camera on object" },click: function () { cameraClicked.raiseEvent(this); },enable: enableCamera,cesiumSvgPath: { path: cameraIconPath, width: 32, height: 32 }'),n.appendChild(c);var d=document.createElement("button");d.type="button",d.className="cesium-infoBox-close",d.setAttribute("data-bind","click: function () { closeClicked.raiseEvent(this); }"),d.innerHTML="×",n.appendChild(d);var h=document.createElement("iframe");h.className="cesium-infoBox-iframe",h.setAttribute("sandbox","allow-same-origin allow-popups allow-forms"),h.setAttribute("data-bind","style : { maxHeight : maxHeightOffset(40) }"),h.setAttribute("allowfullscreen",!0),n.appendChild(h);var p=new u;a.applyBindings(p,n),this._container=t,this._element=n,this._frame=h,this._viewModel=p,this._descriptionSubscription=void 0;var f=this;h.addEventListener("load",function(){var t=h.contentDocument,o=t.createElement("link");o.href=e("Widgets/InfoBox/InfoBoxDescription.css"),o.rel="stylesheet",o.type="text/css";var a=t.createElement("div");a.className="cesium-infoBox-description",t.head.appendChild(o),t.body.appendChild(a),f._descriptionSubscription=l(p,"description",function(e){h.style.height="5px",a.innerHTML=e;var t=null,o=a.firstElementChild;if(null!==o&&1===a.childNodes.length){var s=window.getComputedStyle(o);if(null!==s){var l=s["background-color"],u=r.fromCssColorString(l);i(u)&&0!==u.alpha&&(t=s["background-color"])}}n.style["background-color"]=t;var c=a.getBoundingClientRect().height;h.style.height=c+"px"})}),h.setAttribute("src","about:blank")}return n(c.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}},frame:{get:function(){return this._frame}}}),c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){var e=this._container;return a.cleanNode(this._element),e.removeChild(this._element),i(this._descriptionSubscription)&&this._descriptionSubscription.dispose(),o(this)},c}),define("Widgets/NavigationHelpButton/NavigationHelpButtonViewModel",["../../Core/defineProperties","../../ThirdParty/knockout","../createCommand"],function(e,t,r){"use strict";function i(){this.showInstructions=!1;var e=this;this._command=r(function(){e.showInstructions=!e.showInstructions}),this._showClick=r(function(){e._touch=!1}),this._showTouch=r(function(){e._touch=!0}),this._touch=!1,this.tooltip="Navigation Instructions",t.track(this,["tooltip","showInstructions","_touch"])}return e(i.prototype,{command:{get:function(){return this._command}},showClick:{get:function(){return this._showClick}},showTouch:{get:function(){return this._showTouch}}}),i}),define("Widgets/NavigationHelpButton/NavigationHelpButton",["../../Core/buildModuleUrl","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./NavigationHelpButtonViewModel"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(r){var i=l(r.container),n=new u,o=t(r.instructionsInitiallyVisible,!1);n.showInstructions=o,n._svgPath="M16,1.466C7.973,1.466,1.466,7.973,1.466,16c0,8.027,6.507,14.534,14.534,14.534c8.027,0,14.534-6.507,14.534-14.534C30.534,7.973,24.027,1.466,16,1.466z M17.328,24.371h-2.707v-2.596h2.707V24.371zM17.328,19.003v0.858h-2.707v-1.057c0-3.19,3.63-3.696,3.63-5.963c0-1.034-0.924-1.826-2.134-1.826c-1.254,0-2.354,0.924-2.354,0.924l-1.541-1.915c0,0,1.519-1.584,4.137-1.584c2.487,0,4.796,1.54,4.796,4.136C21.156,16.208,17.328,16.627,17.328,19.003z";var c=document.createElement("span");c.className="cesium-navigationHelpButton-wrapper",i.appendChild(c);var d=document.createElement("button");d.type="button",d.className="cesium-button cesium-toolbar-button cesium-navigation-help-button",d.setAttribute("data-bind","attr: { title: tooltip },click: command,cesiumSvgPath: { path: _svgPath, width: 32, height: 32 }"),c.appendChild(d);var h=document.createElement("div");h.className="cesium-navigation-help",h.setAttribute("data-bind",'css: { "cesium-navigation-help-visible" : showInstructions}'),c.appendChild(h);var p=document.createElement("button");p.type="button",p.className="cesium-navigation-button cesium-navigation-button-left",p.setAttribute("data-bind",'click: showClick, css: {"cesium-navigation-button-selected": !_touch, "cesium-navigation-button-unselected": _touch}');var f=document.createElement("img");f.src=e("Widgets/Images/NavigationHelp/Mouse.svg"),f.className="cesium-navigation-button-icon",f.style.width="25px",f.style.height="25px",p.appendChild(f),p.appendChild(document.createTextNode("Mouse"));var m=document.createElement("button");m.type="button",m.className="cesium-navigation-button cesium-navigation-button-right",m.setAttribute("data-bind",'click: showTouch, css: {"cesium-navigation-button-selected": _touch, "cesium-navigation-button-unselected": !_touch}');var g=document.createElement("img");g.src=e("Widgets/Images/NavigationHelp/Touch.svg"),g.className="cesium-navigation-button-icon",g.style.width="25px",g.style.height="25px",m.appendChild(g),m.appendChild(document.createTextNode("Touch")),h.appendChild(p),h.appendChild(m);var _=document.createElement("div");_.className="cesium-click-navigation-help cesium-navigation-help-instructions",_.setAttribute("data-bind",'css: { "cesium-click-navigation-help-visible" : !_touch}'),_.innerHTML=' <table> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/MouseLeft.svg")+'" width="48" height="48" /></td> <td> <div class="cesium-navigation-help-pan">Pan view</div> <div class="cesium-navigation-help-details">Left click + drag</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/MouseRight.svg")+'" width="48" height="48" /></td> <td> <div class="cesium-navigation-help-zoom">Zoom view</div> <div class="cesium-navigation-help-details">Right click + drag, or</div> <div class="cesium-navigation-help-details">Mouse wheel scroll</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/MouseMiddle.svg")+'" width="48" height="48" /></td> <td> <div class="cesium-navigation-help-rotate">Rotate view</div> <div class="cesium-navigation-help-details">Middle click + drag, or</div> <div class="cesium-navigation-help-details">CTRL + Left/Right click + drag</div> </td> </tr> </table>',h.appendChild(_);var v=document.createElement("div");v.className="cesium-touch-navigation-help cesium-navigation-help-instructions",v.setAttribute("data-bind",'css: { "cesium-touch-navigation-help-visible" : _touch}'),v.innerHTML=' <table> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchDrag.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-pan">Pan view</div> <div class="cesium-navigation-help-details">One finger drag</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchZoom.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-zoom">Zoom view</div> <div class="cesium-navigation-help-details">Two finger pinch</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchTilt.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-rotate">Tilt view</div> <div class="cesium-navigation-help-details">Two finger drag, same direction</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchRotate.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-tilt">Rotate view</div> <div class="cesium-navigation-help-details">Two finger drag, opposite direction</div> </td> </tr> </table>',h.appendChild(v),s.applyBindings(n,c),this._container=i,this._viewModel=n,this._wrapper=c,this._closeInstructions=function(e){c.contains(e.target)||(n.showInstructions=!1)},a.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeInstructions,!0):(document.addEventListener("mousedown",this._closeInstructions,!0),document.addEventListener("touchstart",this._closeInstructions,!0))}return i(c.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return a.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeInstructions,!0):(document.removeEventListener("mousedown",this._closeInstructions,!0),document.removeEventListener("touchstart",this._closeInstructions,!0)),s.cleanNode(this._wrapper),this._container.removeChild(this._wrapper),n(this)},c}),define("Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Scene/FrameRateMonitor","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s){"use strict";function l(t){this._scene=t.scene,this.lowFrameRateMessage=e(t.lowFrameRateMessage,"This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers."),this.lowFrameRateMessageDismissed=!1,this.showingLowFrameRateMessage=!1,a.track(this,["lowFrameRateMessage","lowFrameRateMessageDismissed","showingLowFrameRateMessage"]);var r=this;this._dismissMessage=s(function(){r.showingLowFrameRateMessage=!1,r.lowFrameRateMessageDismissed=!0});var i=o.fromScene(t.scene);this._unsubscribeLowFrameRate=i.lowFrameRate.addEventListener(function(){r.lowFrameRateMessageDismissed||(r.showingLowFrameRateMessage=!0)}),this._unsubscribeNominalFrameRate=i.nominalFrameRate.addEventListener(function(){r.showingLowFrameRateMessage=!1})}return r(l.prototype,{scene:{get:function(){return this._scene}},dismissMessage:{get:function(){return this._dismissMessage}}}),l.prototype.destroy=function(){return this._unsubscribeLowFrameRate(),this._unsubscribeNominalFrameRate(),i(this)},l}),define("Widgets/PerformanceWatchdog/PerformanceWatchdog",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./PerformanceWatchdogViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e){var t=o(e.container),r=new a(e),i=document.createElement("div");i.className="cesium-performance-watchdog-message-area",i.setAttribute("data-bind","visible: showingLowFrameRateMessage");var s=document.createElement("button");s.setAttribute("type","button"),s.className="cesium-performance-watchdog-message-dismiss",s.innerHTML="×",s.setAttribute("data-bind","click: dismissMessage"),i.appendChild(s);var l=document.createElement("div");l.className="cesium-performance-watchdog-message",l.setAttribute("data-bind","html: lowFrameRateMessage"),i.appendChild(l),t.appendChild(i),n.applyBindings(r,i),this._container=t,this._viewModel=r,this._element=i}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this._viewModel.destroy(),n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/ProjectionPicker/ProjectionPickerViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/EventHelper","../../Core/OrthographicFrustum","../../Scene/SceneMode","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t){this._scene=t,this._orthographic=t.camera.frustum instanceof o,this._flightInProgress=!1,this.dropDownVisible=!1,this.tooltipPerspective="Perspective Projection",this.tooltipOrthographic="Orthographic Projection",this.selectedTooltip=void 0,this.sceneMode=t.mode,s.track(this,["_orthographic","_flightInProgress","sceneMode","dropDownVisible","tooltipPerspective","tooltipOrthographic"]);var r=this;s.defineProperty(this,"selectedTooltip",function(){return r._orthographic?r.tooltipOrthographic:r.tooltipPerspective}),this._toggleDropDown=l(function(){r.sceneMode===a.SCENE2D||r._flightInProgress||(r.dropDownVisible=!r.dropDownVisible)}),this._eventHelper=new n,this._eventHelper.add(t.morphComplete,function(e,t,i,n){r.sceneMode=i,r._orthographic=i===a.SCENE2D||r._scene.camera.frustum instanceof o}),this._eventHelper.add(t.preRender,function(){r._flightInProgress=e(t.camera._currentFlight)}),this._switchToPerspective=l(function(){r.sceneMode!==a.SCENE2D&&(r._scene.camera.switchToPerspectiveFrustum(),r._orthographic=!1,r.dropDownVisible=!1)}),this._switchToOrthographic=l(function(){r.sceneMode!==a.SCENE2D&&(r._scene.camera.switchToOrthographicFrustum(),r._orthographic=!0,r.dropDownVisible=!1)}),this._sceneMode=a}return t(u.prototype,{scene:{get:function(){return this._scene}},toggleDropDown:{get:function(){return this._toggleDropDown}},switchToPerspective:{get:function(){return this._switchToPerspective}},switchToOrthographic:{get:function(){return this._switchToOrthographic}},isOrthographicProjection:{get:function(){return this._orthographic}}}),u.prototype.isDestroyed=function(){return!1},u.prototype.destroy=function(){this._eventHelper.removeAll(),r(this)},u}),define("Widgets/ProjectionPicker/ProjectionPicker",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./ProjectionPickerViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t){e=a(e);var r=new s(t);r._perspectivePath=u,r._orthographicPath=c;var i=document.createElement("span");i.className="cesium-projectionPicker-wrapper cesium-toolbar-button",e.appendChild(i);var l=document.createElement("button");l.type="button",l.className="cesium-button cesium-toolbar-button",l.setAttribute("data-bind",'css: { "cesium-projectionPicker-buttonPerspective": !_orthographic, "cesium-projectionPicker-buttonOrthographic": _orthographic, "cesium-button-disabled" : sceneMode === _sceneMode.SCENE2D || _flightInProgress, "cesium-projectionPicker-selected": dropDownVisible },attr: { title: selectedTooltip },click: toggleDropDown'),l.innerHTML='\x3c!-- ko cesiumSvgPath: { path: _perspectivePath, width: 64, height: 64, css: "cesium-projectionPicker-iconPerspective" } --\x3e\x3c!-- /ko --\x3e\x3c!-- ko cesiumSvgPath: { path: _orthographicPath, width: 64, height: 64, css: "cesium-projectionPicker-iconOrthographic" } --\x3e\x3c!-- /ko --\x3e',i.appendChild(l);var d=document.createElement("button");d.type="button",d.className="cesium-button cesium-toolbar-button cesium-projectionPicker-dropDown-icon",d.setAttribute("data-bind",'css: { "cesium-projectionPicker-visible" : (dropDownVisible && _orthographic), "cesium-projectionPicker-none" : !_orthographic, "cesium-projectionPicker-hidden" : !dropDownVisible },attr: { title: tooltipPerspective },click: switchToPerspective,cesiumSvgPath: { path: _perspectivePath, width: 64, height: 64 }'),i.appendChild(d);var h=document.createElement("button");h.type="button",h.className="cesium-button cesium-toolbar-button cesium-projectionPicker-dropDown-icon",h.setAttribute("data-bind",'css: { "cesium-projectionPicker-visible" : (dropDownVisible && !_orthographic), "cesium-projectionPicker-none" : _orthographic, "cesium-projectionPicker-hidden" : !dropDownVisible},attr: { title: tooltipOrthographic },click: switchToOrthographic,cesiumSvgPath: { path: _orthographicPath, width: 64, height: 64 }'),i.appendChild(h),o.applyBindings(r,i),this._viewModel=r,this._container=e,this._wrapper=i,this._closeDropDown=function(e){i.contains(e.target)||(r.dropDownVisible=!1)},n.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeDropDown,!0):(document.addEventListener("mousedown",this._closeDropDown,!0),document.addEventListener("touchstart",this._closeDropDown,!0))}var u="M 28.15625,10.4375 9.125,13.21875 13.75,43.25 41.75,55.09375 50.8125,37 54.5,11.9375 z m 0.125,3 19.976451,0.394265 L 43.03125,16.875 22.6875,14.28125 z M 50.971746,15.705477 47.90625,36.03125 42.53125,46 44.84375,19.3125 z M 12.625,16.03125 l 29.15625,3.6875 -2.65625,31 L 16.4375,41.125 z",c="m 31.560594,6.5254438 -20.75,12.4687502 0.1875,24.5625 22.28125,11.8125 19.5,-12 0.65625,-0.375 0,-0.75 0.0312,-23.21875 z m 0.0625,3.125 16.65625,9.5000002 -16.125,10.28125 -17.34375,-9.71875 z m 18.96875,11.1875002 0.15625,20.65625 -17.46875,10.59375 0.15625,-20.28125 z m -37.0625,1.25 17.21875,9.625 -0.15625,19.21875 -16.9375,-9 z";return t(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._viewModel.destroy(),n.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeDropDown,!0):(document.removeEventListener("mousedown",this._closeDropDown,!0),document.removeEventListener("touchstart",this._closeDropDown,!0)),o.cleanNode(this._wrapper),this._container.removeChild(this._wrapper),r(this)},l}),define("Widgets/SceneModePicker/SceneModePickerViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/EventHelper","../../Scene/SceneMode","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t,r){this._scene=t;var i=this,n=function(e,t,r,n){i.sceneMode=r,i.dropDownVisible=!1};this._eventHelper=new o,this._eventHelper.add(t.morphStart,n),this._duration=e(r,2),this.sceneMode=t.mode,this.dropDownVisible=!1,this.tooltip2D="2D",this.tooltip3D="3D",this.tooltipColumbusView="Columbus View",s.track(this,["sceneMode","dropDownVisible","tooltip2D","tooltip3D","tooltipColumbusView"]),this.selectedTooltip=void 0,s.defineProperty(this,"selectedTooltip",function(){var e=i.sceneMode;return e===a.SCENE2D?i.tooltip2D:e===a.SCENE3D?i.tooltip3D:i.tooltipColumbusView}),this._toggleDropDown=l(function(){i.dropDownVisible=!i.dropDownVisible}),this._morphTo2D=l(function(){t.morphTo2D(i._duration)}),this._morphTo3D=l(function(){t.morphTo3D(i._duration)}),this._morphToColumbusView=l(function(){t.morphToColumbusView(i._duration)}),this._sceneMode=a}return r(u.prototype,{scene:{get:function(){return this._scene}},duration:{get:function(){return this._duration},set:function(e){this._duration=e}},toggleDropDown:{get:function(){return this._toggleDropDown}},morphTo2D:{get:function(){return this._morphTo2D}},morphTo3D:{get:function(){return this._morphTo3D}},morphToColumbusView:{get:function(){return this._morphToColumbusView}}}),u.prototype.isDestroyed=function(){return!1},u.prototype.destroy=function(){this._eventHelper.removeAll(),i(this)},u}),define("Widgets/SceneModePicker/SceneModePicker",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./SceneModePickerViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r){e=a(e);var i=new s(t,r);i._globePath=u,i._flatMapPath=c,i._columbusViewPath=d;var l=document.createElement("span");l.className="cesium-sceneModePicker-wrapper cesium-toolbar-button",e.appendChild(l);var h=document.createElement("button");h.type="button",h.className="cesium-button cesium-toolbar-button",h.setAttribute("data-bind",'css: { "cesium-sceneModePicker-button2D": sceneMode === _sceneMode.SCENE2D, "cesium-sceneModePicker-button3D": sceneMode === _sceneMode.SCENE3D, "cesium-sceneModePicker-buttonColumbusView": sceneMode === _sceneMode.COLUMBUS_VIEW, "cesium-sceneModePicker-selected": dropDownVisible },attr: { title: selectedTooltip },click: toggleDropDown'),h.innerHTML='\x3c!-- ko cesiumSvgPath: { path: _globePath, width: 64, height: 64, css: "cesium-sceneModePicker-slide-svg cesium-sceneModePicker-icon3D" } --\x3e\x3c!-- /ko --\x3e\x3c!-- ko cesiumSvgPath: { path: _flatMapPath, width: 64, height: 64, css: "cesium-sceneModePicker-slide-svg cesium-sceneModePicker-icon2D" } --\x3e\x3c!-- /ko --\x3e\x3c!-- ko cesiumSvgPath: { path: _columbusViewPath, width: 64, height: 64, css: "cesium-sceneModePicker-slide-svg cesium-sceneModePicker-iconColumbusView" } --\x3e\x3c!-- /ko --\x3e',l.appendChild(h);var p=document.createElement("button");p.type="button", -p.className="cesium-button cesium-toolbar-button cesium-sceneModePicker-dropDown-icon",p.setAttribute("data-bind",'css: { "cesium-sceneModePicker-visible" : (dropDownVisible && (sceneMode !== _sceneMode.SCENE3D)) || (!dropDownVisible && (sceneMode === _sceneMode.SCENE3D)), "cesium-sceneModePicker-none" : sceneMode === _sceneMode.SCENE3D, "cesium-sceneModePicker-hidden" : !dropDownVisible },attr: { title: tooltip3D },click: morphTo3D,cesiumSvgPath: { path: _globePath, width: 64, height: 64 }'),l.appendChild(p);var f=document.createElement("button");f.type="button",f.className="cesium-button cesium-toolbar-button cesium-sceneModePicker-dropDown-icon",f.setAttribute("data-bind",'css: { "cesium-sceneModePicker-visible" : (dropDownVisible && (sceneMode !== _sceneMode.SCENE2D)), "cesium-sceneModePicker-none" : sceneMode === _sceneMode.SCENE2D, "cesium-sceneModePicker-hidden" : !dropDownVisible },attr: { title: tooltip2D },click: morphTo2D,cesiumSvgPath: { path: _flatMapPath, width: 64, height: 64 }'),l.appendChild(f);var m=document.createElement("button");m.type="button",m.className="cesium-button cesium-toolbar-button cesium-sceneModePicker-dropDown-icon",m.setAttribute("data-bind",'css: { "cesium-sceneModePicker-visible" : (dropDownVisible && (sceneMode !== _sceneMode.COLUMBUS_VIEW)) || (!dropDownVisible && (sceneMode === _sceneMode.COLUMBUS_VIEW)), "cesium-sceneModePicker-none" : sceneMode === _sceneMode.COLUMBUS_VIEW, "cesium-sceneModePicker-hidden" : !dropDownVisible},attr: { title: tooltipColumbusView },click: morphToColumbusView,cesiumSvgPath: { path: _columbusViewPath, width: 64, height: 64 }'),l.appendChild(m),o.applyBindings(i,l),this._viewModel=i,this._container=e,this._wrapper=l,this._closeDropDown=function(e){l.contains(e.target)||(i.dropDownVisible=!1)},n.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeDropDown,!0):(document.addEventListener("mousedown",this._closeDropDown,!0),document.addEventListener("touchstart",this._closeDropDown,!0))}var u="m 32.401392,4.9330437 c -7.087603,0 -14.096095,2.884602 -19.10793,7.8946843 -5.0118352,5.010083 -7.9296167,11.987468 -7.9296167,19.072999 0,7.085531 2.9177815,14.097848 7.9296167,19.107931 4.837653,4.835961 11.541408,7.631372 18.374354,7.82482 0.05712,0.01231 0.454119,0.139729 0.454119,0.139729 l 0.03493,-0.104797 c 0.08246,7.84e-4 0.162033,0.03493 0.244525,0.03493 0.08304,0 0.161515,-0.03414 0.244526,-0.03493 l 0.03493,0.104797 c 0,0 0.309474,-0.129487 0.349323,-0.139729 6.867765,-0.168094 13.582903,-2.965206 18.444218,-7.82482 2.558195,-2.5573 4.551081,-5.638134 5.903547,-8.977584 1.297191,-3.202966 2.02607,-6.661489 2.02607,-10.130347 0,-6.237309 -2.366261,-12.31219 -6.322734,-17.116794 -0.0034,-0.02316 0.0049,-0.04488 0,-0.06986 -0.01733,-0.08745 -0.104529,-0.278855 -0.104797,-0.279458 -5.31e-4,-0.0012 -0.522988,-0.628147 -0.523984,-0.62878 -3.47e-4,-2.2e-4 -0.133444,-0.03532 -0.244525,-0.06987 C 51.944299,13.447603 51.751076,13.104317 51.474391,12.827728 46.462556,7.8176457 39.488996,4.9330437 32.401392,4.9330437 z m -2.130866,3.5281554 0.104797,9.6762289 c -4.111695,-0.08361 -7.109829,-0.423664 -9.257041,-0.943171 1.198093,-2.269271 2.524531,-4.124404 3.91241,-5.414496 2.167498,-2.0147811 3.950145,-2.8540169 5.239834,-3.3185619 z m 2.794579,0 c 1.280302,0.4754953 3.022186,1.3285948 5.065173,3.2486979 1.424667,1.338973 2.788862,3.303645 3.982275,5.728886 -2.29082,0.403367 -5.381258,0.621049 -8.942651,0.698645 L 33.065105,8.4611991 z m 5.728886,0.2445256 c 4.004072,1.1230822 7.793098,3.1481363 10.724195,6.0782083 0.03468,0.03466 0.07033,0.06991 0.104797,0.104797 -0.45375,0.313891 -0.923054,0.663002 -1.956205,1.082899 -0.647388,0.263114 -1.906242,0.477396 -2.829511,0.733577 -1.382296,-2.988132 -3.027146,-5.368585 -4.785716,-7.0213781 -0.422866,-0.397432 -0.835818,-0.6453247 -1.25756,-0.9781032 z m -15.33525,0.7685092 c -0.106753,0.09503 -0.207753,0.145402 -0.31439,0.244526 -1.684973,1.5662541 -3.298068,3.8232211 -4.680919,6.5672591 -0.343797,-0.14942 -1.035052,-0.273198 -1.292493,-0.419186 -0.956528,-0.542427 -1.362964,-1.022024 -1.537018,-1.292493 -0.0241,-0.03745 -0.01868,-0.0401 -0.03493,-0.06986 2.250095,-2.163342 4.948824,-3.869984 7.859752,-5.0302421 z m -9.641296,7.0912431 c 0.464973,0.571618 0.937729,1.169056 1.956205,1.746612 0.349907,0.198425 1.107143,0.335404 1.537018,0.523983 -1.20166,3.172984 -1.998037,7.051901 -2.165798,11.772162 C 14.256557,30.361384 12.934823,30.161483 12.280427,29.90959 10.644437,29.279855 9.6888882,28.674891 9.1714586,28.267775 8.6540289,27.860658 8.6474751,27.778724 8.6474751,27.778724 l -0.069864,0.03493 C 9.3100294,23.691285 11.163248,19.798527 13.817445,16.565477 z m 37.552149,0.523984 c 2.548924,3.289983 4.265057,7.202594 4.890513,11.318043 -0.650428,0.410896 -1.756876,1.001936 -3.563088,1.606882 -1.171552,0.392383 -3.163859,0.759153 -4.960377,1.117832 -0.04367,-4.752703 -0.784809,-8.591423 -1.88634,-11.807094 0.917574,-0.263678 2.170552,-0.486495 2.864443,-0.76851 1.274693,-0.518066 2.003942,-1.001558 2.654849,-1.467153 z m -31.439008,2.619917 c 2.487341,0.672766 5.775813,1.137775 10.479669,1.222628 l 0.104797,10.689263 0,0.03493 0,0.733577 c -5.435005,-0.09059 -9.512219,-0.519044 -12.610536,-1.117831 0.106127,-4.776683 0.879334,-8.55791 2.02607,-11.562569 z m 23.264866,0.31439 c 1.073459,3.067541 1.833795,6.821314 1.816476,11.702298 -3.054474,0.423245 -7.062018,0.648559 -11.702298,0.698644 l 0,-0.838373 -0.104796,-10.654331 c 4.082416,-0.0864 7.404468,-0.403886 9.990618,-0.908238 z M 8.2632205,30.922625 c 0.7558676,0.510548 1.5529563,1.013339 3.0041715,1.57195 0.937518,0.360875 2.612202,0.647642 3.91241,0.978102 0.112814,3.85566 0.703989,7.107756 1.606883,9.920754 -1.147172,-0.324262 -2.644553,-0.640648 -3.423359,-0.978102 -1.516688,-0.657177 -2.386627,-1.287332 -2.864443,-1.71168 -0.477816,-0.424347 -0.489051,-0.489051 -0.489051,-0.489051 L 9.8002387,40.319395 C 8.791691,37.621767 8.1584238,34.769583 8.1584238,31.900727 c 0,-0.330153 0.090589,-0.648169 0.1047967,-0.978102 z m 48.2763445,0.419186 c 0.0047,0.188973 0.06986,0.36991 0.06986,0.558916 0,2.938869 -0.620228,5.873558 -1.676747,8.628261 -0.07435,0.07583 -0.06552,0.07411 -0.454119,0.349323 -0.606965,0.429857 -1.631665,1.042044 -3.318562,1.676747 -1.208528,0.454713 -3.204964,0.850894 -5.135038,1.25756 0.84593,-2.765726 1.41808,-6.005357 1.606883,-9.815957 2.232369,-0.413371 4.483758,-0.840201 5.938479,-1.327425 1.410632,-0.472457 2.153108,-0.89469 2.96924,-1.327425 z m -38.530252,2.864443 c 3.208141,0.56697 7.372279,0.898588 12.575603,0.978103 l 0.174662,9.885821 c -4.392517,-0.06139 -8.106722,-0.320566 -10.863925,-0.803441 -1.051954,-2.664695 -1.692909,-6.043794 -1.88634,-10.060483 z m 26.793022,0.31439 c -0.246298,3.923551 -0.877762,7.263679 -1.816476,9.885822 -2.561957,0.361954 -5.766249,0.560708 -9.431703,0.62878 l -0.174661,-9.815957 c 4.491734,-0.04969 8.334769,-0.293032 11.42284,-0.698645 z M 12.035901,44.860585 c 0.09977,0.04523 0.105535,0.09465 0.209594,0.139729 1.337656,0.579602 3.441099,1.058072 5.589157,1.537018 1.545042,3.399208 3.548524,5.969402 5.589157,7.789888 -3.034411,-1.215537 -5.871615,-3.007978 -8.174142,-5.309699 -1.245911,-1.245475 -2.271794,-2.662961 -3.213766,-4.156936 z m 40.69605,0 c -0.941972,1.493975 -1.967855,2.911461 -3.213765,4.156936 -2.74253,2.741571 -6.244106,4.696717 -9.955686,5.868615 0.261347,-0.241079 0.507495,-0.394491 0.768509,-0.663713 1.674841,-1.727516 3.320792,-4.181056 4.645987,-7.265904 2.962447,-0.503021 5.408965,-1.122293 7.161107,-1.781544 0.284034,-0.106865 0.337297,-0.207323 0.593848,-0.31439 z m -31.404076,2.305527 c 2.645807,0.376448 5.701178,0.649995 9.466635,0.698645 l 0.139729,7.789888 c -1.38739,-0.480844 -3.316218,-1.29837 -5.659022,-3.388427 -1.388822,-1.238993 -2.743668,-3.0113 -3.947342,-5.100106 z m 20.365491,0.104797 c -1.04872,2.041937 -2.174337,3.779068 -3.353494,4.995309 -1.853177,1.911459 -3.425515,2.82679 -4.611055,3.353494 l -0.139729,-7.789887 c 3.13091,-0.05714 5.728238,-0.278725 8.104278,-0.558916 z",c="m 2.9825053,17.550598 0,1.368113 0,26.267766 0,1.368113 1.36811,0 54.9981397,0 1.36811,0 0,-1.368113 0,-26.267766 0,-1.368113 -1.36811,0 -54.9981397,0 -1.36811,0 z m 2.73623,2.736226 10.3292497,0 0,10.466063 -10.3292497,0 0,-10.466063 z m 13.0654697,0 11.69737,0 0,10.466063 -11.69737,0 0,-10.466063 z m 14.43359,0 11.69737,0 0,10.466063 -11.69737,0 0,-10.466063 z m 14.43359,0 10.32926,0 0,10.466063 -10.32926,0 0,-10.466063 z m -41.9326497,13.202288 10.3292497,0 0,10.329252 -10.3292497,0 0,-10.329252 z m 13.0654697,0 11.69737,0 0,10.329252 -11.69737,0 0,-10.329252 z m 14.43359,0 11.69737,0 0,10.329252 -11.69737,0 0,-10.329252 z m 14.43359,0 10.32926,0 0,10.329252 -10.32926,0 0,-10.329252 z",d="m 14.723969,17.675598 -0.340489,0.817175 -11.1680536,26.183638 -0.817175,1.872692 2.076986,0 54.7506996,0 2.07698,0 -0.81717,-1.872692 -11.16805,-26.183638 -0.34049,-0.817175 -0.91933,0 -32.414586,0 -0.919322,0 z m 1.838643,2.723916 6.196908,0 -2.928209,10.418977 -7.729111,0 4.460412,-10.418977 z m 9.02297,0 4.903049,0 0,10.418977 -7.831258,0 2.928209,-10.418977 z m 7.626964,0 5.584031,0 2.62176,10.418977 -8.205791,0 0,-10.418977 z m 8.410081,0 5.51593,0 4.46042,10.418977 -7.38863,0 -2.58772,-10.418977 z m -30.678091,13.142892 8.103649,0 -2.89416,10.282782 -9.6018026,0 4.3923136,-10.282782 z m 10.929711,0 8.614384,0 0,10.282782 -11.508544,0 2.89416,-10.282782 z m 11.338299,0 8.852721,0 2.58772,10.282782 -11.440441,0 0,-10.282782 z m 11.678781,0 7.86531,0 4.39231,10.282782 -9.6699,0 -2.58772,-10.282782 z";return t(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._viewModel.destroy(),n.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeDropDown,!0):(document.removeEventListener("mousedown",this._closeDropDown,!0),document.removeEventListener("touchstart",this._closeDropDown,!0)),o.cleanNode(this._wrapper),this._container.removeChild(this._wrapper),r(this)},l}),define("Widgets/SelectionIndicator/SelectionIndicatorViewModel",["../../Core/Cartesian2","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/EasingFunction","../../Scene/SceneTransforms","../../ThirdParty/knockout"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,i,n){this._scene=e,this._screenPositionX=c,this._screenPositionY=c,this._tweens=e.tweens,this._container=t(n,document.body),this._selectionIndicatorElement=i,this._scale=1,this.position=void 0,this.showSelection=!1,s.track(this,["position","_screenPositionX","_screenPositionY","_scale","showSelection"]),this.isVisible=void 0,s.defineProperty(this,"isVisible",{get:function(){return this.showSelection&&r(this.position)}}),s.defineProperty(this,"_transform",{get:function(){return"scale("+this._scale+")"}}),this.computeScreenSpacePosition=function(t,r){return a.wgs84ToWindowCoordinates(e,t,r)}}var u=new e,c="-1000px";return l.prototype.update=function(){if(this.showSelection&&r(this.position)){var e=this.computeScreenSpacePosition(this.position,u);if(r(e)){var t=this._container,i=t.parentNode.clientWidth,n=t.parentNode.clientHeight,o=this._selectionIndicatorElement.clientWidth,a=.5*o;e.x=Math.min(Math.max(e.x,-o),i+o)-a,e.y=Math.min(Math.max(e.y,-o),n+o)-a,this._screenPositionX=Math.floor(e.x+.25)+"px",this._screenPositionY=Math.floor(e.y+.25)+"px"}else this._screenPositionX=c,this._screenPositionY=c}},l.prototype.animateAppear=function(){this._tweens.addProperty({object:this,property:"_scale",startValue:2,stopValue:1,duration:.8,easingFunction:o.EXPONENTIAL_OUT})},l.prototype.animateDepart=function(){this._tweens.addProperty({object:this,property:"_scale",startValue:this._scale,stopValue:1.5,duration:.8,easingFunction:o.EXPONENTIAL_OUT})},i(l.prototype,{container:{get:function(){return this._container}},selectionIndicatorElement:{get:function(){return this._selectionIndicatorElement}},scene:{get:function(){return this._scene}}}),l}),define("Widgets/SelectionIndicator/SelectionIndicator",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./SelectionIndicatorViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){e=o(e),this._container=e;var r=document.createElement("div");r.className="cesium-selection-wrapper",r.setAttribute("data-bind",'style: { "top" : _screenPositionY, "left" : _screenPositionX },css: { "cesium-selection-wrapper-visible" : isVisible }'),e.appendChild(r),this._element=r;var i="http://www.w3.org/2000/svg",s=document.createElementNS(i,"svg:svg");s.setAttribute("width",160),s.setAttribute("height",160),s.setAttribute("viewBox","0 0 160 160");var l=document.createElementNS(i,"g");l.setAttribute("transform","translate(80,80)"),s.appendChild(l);var u=document.createElementNS(i,"path");u.setAttribute("data-bind","attr: { transform: _transform }"),u.setAttribute("d","M -34 -34 L -34 -11.25 L -30 -15.25 L -30 -30 L -15.25 -30 L -11.25 -34 L -34 -34 z M 11.25 -34 L 15.25 -30 L 30 -30 L 30 -15.25 L 34 -11.25 L 34 -34 L 11.25 -34 z M -34 11.25 L -34 34 L -11.25 34 L -15.25 30 L -30 30 L -30 15.25 L -34 11.25 z M 34 11.25 L 30 15.25 L 30 30 L 15.25 30 L 11.25 34 L 34 34 L 34 11.25 z"),l.appendChild(u),r.appendChild(s);var c=new a(t,this._element,this._container);this._viewModel=c,n.applyBindings(this._viewModel,this._element)}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){var e=this._container;return n.cleanNode(this._element),e.removeChild(this._element),r(this)},s}),define("Widgets/Timeline/TimelineHighlightRange",["../../Core/defaultValue","../../Core/JulianDate"],function(e,t){"use strict";function r(t,r,i){this._color=t,this._height=r,this._base=e(i,0)}return r.prototype.getHeight=function(){return this._height},r.prototype.getBase=function(){return this._base},r.prototype.getStartTime=function(){return this._start},r.prototype.getStopTime=function(){return this._stop},r.prototype.setRange=function(e,t){this._start=e,this._stop=t},r.prototype.render=function(e){var r="";if(this._start&&this._stop&&this._color){var i=t.secondsDifference(this._start,e.epochJulian),n=Math.round(e.timeBarWidth*e.getAlpha(i)),o=t.secondsDifference(this._stop,e.epochJulian),a=Math.round(e.timeBarWidth*e.getAlpha(o))-n;n<0&&(a+=n,n=0),n+a>e.timeBarWidth&&(a=e.timeBarWidth-n),a>0&&(r='<span class="cesium-timeline-highlight" style="left: '+n.toString()+"px; width: "+a.toString()+"px; bottom: "+this._base.toString()+"px; height: "+this._height+"px; background-color: "+this._color+';"></span>')}return r},r});define("Widgets/Timeline/TimelineTrack",["../../Core/Color","../../Core/defined","../../Core/JulianDate"],function(e,t,r){"use strict";function i(t,r,i,n){this.interval=t,this.height=r,this.color=i||new e(.5,.5,.5,1),this.backgroundColor=n||new e(0,0,0,0)}return i.prototype.render=function(e,i){var n=this.interval.start,o=this.interval.stop,a=i.startJulian,s=r.addSeconds(i.startJulian,i.duration,new r);if(r.lessThan(n,a)&&r.greaterThan(o,s))e.fillStyle=this.color.toCssColorString(),e.fillRect(0,i.y,i.timeBarWidth,this.height);else if(r.lessThanOrEquals(n,s)&&r.greaterThanOrEquals(o,a)){var l,u,c;for(l=0;l<i.timeBarWidth;++l){var d=r.addSeconds(i.startJulian,l/i.timeBarWidth*i.duration,new r);!t(u)&&r.greaterThanOrEquals(d,n)?u=l:!t(c)&&r.greaterThanOrEquals(d,o)&&(c=l)}e.fillStyle=this.backgroundColor.toCssColorString(),e.fillRect(0,i.y,i.timeBarWidth,this.height),t(u)&&(t(c)||(c=i.timeBarWidth),e.fillStyle=this.color.toCssColorString(),e.fillRect(u,i.y,Math.max(c-u,1),this.height))}},i}),define("Widgets/Timeline/Timeline",["../../Core/ClockRange","../../Core/defined","../../Core/destroyObject","../../Core/DeveloperError","../../Core/JulianDate","../getElement","./TimelineHighlightRange","./TimelineTrack"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t){e=o(e),this.container=e;var r=document.createElement("div");r.className="cesium-timeline-main",e.appendChild(r),this._topDiv=r,this._endJulian=void 0,this._epochJulian=void 0,this._lastXPos=void 0,this._scrubElement=void 0,this._startJulian=void 0,this._timeBarSecondsSpan=void 0,this._clock=t,this._scrubJulian=t.currentTime,this._mainTicSpan=-1,this._mouseMode=v.none,this._touchMode=y.none,this._touchState={centerX:0,spanX:0},this._mouseX=0,this._timelineDrag=0,this._timelineDragLocation=void 0,this._lastHeight=void 0,this._lastWidth=void 0,this._topDiv.innerHTML='<div class="cesium-timeline-bar"></div><div class="cesium-timeline-trackContainer"><canvas class="cesium-timeline-tracks" width="10" height="1"></canvas></div><div class="cesium-timeline-needle"></div><span class="cesium-timeline-ruler"></span>',this._timeBarEle=this._topDiv.childNodes[0],this._trackContainer=this._topDiv.childNodes[1],this._trackListEle=this._topDiv.childNodes[1].childNodes[0],this._needleEle=this._topDiv.childNodes[2],this._rulerEle=this._topDiv.childNodes[3],this._context=this._trackListEle.getContext("2d"),this._trackList=[],this._highlightRanges=[],this.zoomTo(t.startTime,t.stopTime),this._onMouseDown=c(this),this._onMouseUp=d(this),this._onMouseMove=h(this),this._onMouseWheel=p(this),this._onTouchStart=f(this),this._onTouchMove=g(this),this._onTouchEnd=m(this);var i=this._timeBarEle;document.addEventListener("mouseup",this._onMouseUp,!1),document.addEventListener("mousemove",this._onMouseMove,!1),i.addEventListener("mousedown",this._onMouseDown,!1),i.addEventListener("DOMMouseScroll",this._onMouseWheel,!1),i.addEventListener("mousewheel",this._onMouseWheel,!1),i.addEventListener("touchstart",this._onTouchStart,!1),i.addEventListener("touchmove",this._onTouchMove,!1),i.addEventListener("touchend",this._onTouchEnd,!1),i.addEventListener("touchcancel",this._onTouchEnd,!1),this._topDiv.oncontextmenu=function(){return!1},t.onTick.addEventListener(this.updateFromClock,this),this.updateFromClock()}function u(e){return e<10?"0"+e.toString():e.toString()}function c(e){return function(t){e._mouseMode!==v.touchOnly&&(0===t.button?(e._mouseMode=v.scrub,e._scrubElement&&(e._scrubElement.style.backgroundPosition="-16px 0"),e._onMouseMove(t)):(e._mouseX=t.clientX,2===t.button?e._mouseMode=v.zoom:e._mouseMode=v.slide)),t.preventDefault()}}function d(e){return function(t){e._mouseMode=v.none,e._scrubElement&&(e._scrubElement.style.backgroundPosition="0 0"),e._timelineDrag=0,e._timelineDragLocation=void 0}}function h(e){return function(t){var r;if(e._mouseMode===v.scrub){t.preventDefault();var i=t.clientX-e._topDiv.getBoundingClientRect().left;i<0?(e._timelineDragLocation=0,e._timelineDrag=-.01*e._timeBarSecondsSpan):i>e._topDiv.clientWidth?(e._timelineDragLocation=e._topDiv.clientWidth,e._timelineDrag=.01*e._timeBarSecondsSpan):(e._timelineDragLocation=void 0,e._setTimeBarTime(i,i*e._timeBarSecondsSpan/e._topDiv.clientWidth))}else if(e._mouseMode===v.slide){if(r=e._mouseX-t.clientX,e._mouseX=t.clientX,0!==r){var o=r*e._timeBarSecondsSpan/e._topDiv.clientWidth;e.zoomTo(n.addSeconds(e._startJulian,o,new n),n.addSeconds(e._endJulian,o,new n))}}else e._mouseMode===v.zoom&&(r=e._mouseX-t.clientX,e._mouseX=t.clientX,0!==r&&e.zoomFrom(Math.pow(1.01,r)))}}function p(e){return function(t){var r=t.wheelDeltaY||t.wheelDelta||-t.detail;_=Math.max(Math.min(Math.abs(r),_),1),r/=_,e.zoomFrom(Math.pow(1.05,-r))}}function f(e){return function(t){var r,i,o=t.touches.length,a=e._topDiv.getBoundingClientRect().left;t.preventDefault(),e._mouseMode=v.touchOnly,1===o?(r=n.secondsDifference(e._scrubJulian,e._startJulian),i=Math.round(r*e._topDiv.clientWidth/e._timeBarSecondsSpan+a),Math.abs(t.touches[0].clientX-i)<50?(e._touchMode=y.scrub,e._scrubElement&&(e._scrubElement.style.backgroundPosition=1===o?"-16px 0":"0 0")):(e._touchMode=y.singleTap,e._touchState.centerX=t.touches[0].clientX-a)):2===o?(e._touchMode=y.slideZoom,e._touchState.centerX=.5*(t.touches[0].clientX+t.touches[1].clientX)-a,e._touchState.spanX=Math.abs(t.touches[0].clientX-t.touches[1].clientX)):e._touchMode=y.ignore}}function m(e){return function(t){var r=t.touches.length,i=e._topDiv.getBoundingClientRect().left;e._touchMode===y.singleTap?(e._touchMode=y.scrub,e._onTouchMove(t)):e._touchMode===y.scrub&&e._onTouchMove(t),e._mouseMode=v.touchOnly,1!==r?e._touchMode=r>0?y.ignore:y.none:e._touchMode===y.slideZoom&&(e._touchState.centerX=t.touches[0].clientX-i),e._scrubElement&&(e._scrubElement.style.backgroundPosition="0 0")}}function g(e){return function(r){var i,o,a,s,l,u,c=1,d=e._topDiv.getBoundingClientRect().left;e._touchMode===y.singleTap&&(e._touchMode=y.slideZoom),e._mouseMode=v.touchOnly,e._touchMode===y.scrub?(r.preventDefault(),1===r.changedTouches.length&&(o=r.changedTouches[0].clientX-d)>=0&&o<=e._topDiv.clientWidth&&e._setTimeBarTime(o,o*e._timeBarSecondsSpan/e._topDiv.clientWidth)):e._touchMode===y.slideZoom&&(a=r.touches.length,2===a?(s=.5*(r.touches[0].clientX+r.touches[1].clientX)-d,l=Math.abs(r.touches[0].clientX-r.touches[1].clientX)):1===a&&(s=r.touches[0].clientX-d,l=0),t(s)&&(l>0&&e._touchState.spanX>0?(c=e._touchState.spanX/l,u=n.addSeconds(e._startJulian,(e._touchState.centerX*e._timeBarSecondsSpan-s*e._timeBarSecondsSpan*c)/e._topDiv.clientWidth,new n)):(i=e._touchState.centerX-s,u=n.addSeconds(e._startJulian,i*e._timeBarSecondsSpan/e._topDiv.clientWidth,new n)),e.zoomTo(u,n.addSeconds(u,e._timeBarSecondsSpan*c,new n)),e._touchState.centerX=s,e._touchState.spanX=l))}}var _=1e12,v={none:0,scrub:1,slide:2,zoom:3,touchOnly:4},y={none:0,scrub:1,slideZoom:2,singleTap:3,ignore:4},C=[.001,.002,.005,.01,.02,.05,.1,.25,.5,1,2,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,21600,43200,86400,172800,345600,604800,1296e3,2592e3,5184e3,7776e3,15552e3,31536e3,63072e3,126144e3,15768e4,31536e4,63072e4,126144e4,15768e5,31536e5,63072e5,126144e5,15768e6,31536e6],b=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];return l.prototype.addEventListener=function(e,t,r){this._topDiv.addEventListener(e,t,r)},l.prototype.removeEventListener=function(e,t,r){this._topDiv.removeEventListener(e,t,r)},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){this._clock.onTick.removeEventListener(this.updateFromClock,this),document.removeEventListener("mouseup",this._onMouseUp,!1),document.removeEventListener("mousemove",this._onMouseMove,!1);var e=this._timeBarEle;e.removeEventListener("mousedown",this._onMouseDown,!1),e.removeEventListener("DOMMouseScroll",this._onMouseWheel,!1),e.removeEventListener("mousewheel",this._onMouseWheel,!1),e.removeEventListener("touchstart",this._onTouchStart,!1),e.removeEventListener("touchmove",this._onTouchMove,!1),e.removeEventListener("touchend",this._onTouchEnd,!1),e.removeEventListener("touchcancel",this._onTouchEnd,!1),this.container.removeChild(this._topDiv),r(this)},l.prototype.addHighlightRange=function(e,t,r){var i=new a(e,t,r);return this._highlightRanges.push(i),this.resize(),i},l.prototype.addTrack=function(e,t,r,i){var n=new s(e,t,r,i);return this._trackList.push(n),this._lastHeight=void 0,this.resize(),n},l.prototype.zoomTo=function(t,r){if(this._startJulian=t,this._endJulian=r,this._timeBarSecondsSpan=n.secondsDifference(r,t),this._clock&&this._clock.clockRange!==e.UNBOUNDED){var i=this._clock.startTime,o=this._clock.stopTime,a=n.secondsDifference(o,i),s=n.secondsDifference(i,this._startJulian),l=n.secondsDifference(o,this._endJulian);this._timeBarSecondsSpan>=a?(this._timeBarSecondsSpan=a,this._startJulian=this._clock.startTime,this._endJulian=this._clock.stopTime):s>0?(this._endJulian=n.addSeconds(this._endJulian,s,new n),this._startJulian=i,this._timeBarSecondsSpan=n.secondsDifference(this._endJulian,this._startJulian)):l<0&&(this._startJulian=n.addSeconds(this._startJulian,l,new n),this._endJulian=o,this._timeBarSecondsSpan=n.secondsDifference(this._endJulian,this._startJulian))}this._makeTics();var u=document.createEvent("Event");u.initEvent("setzoom",!0,!0),u.startJulian=this._startJulian,u.endJulian=this._endJulian,u.epochJulian=this._epochJulian,u.totalSpan=this._timeBarSecondsSpan,u.mainTicSpan=this._mainTicSpan,this._topDiv.dispatchEvent(u)},l.prototype.zoomFrom=function(e){var t=n.secondsDifference(this._scrubJulian,this._startJulian);e>1||t<0||t>this._timeBarSecondsSpan?t=.5*this._timeBarSecondsSpan:t+=t-.5*this._timeBarSecondsSpan;var r=this._timeBarSecondsSpan-t;this.zoomTo(n.addSeconds(this._startJulian,t-t*e,new n),n.addSeconds(this._endJulian,r*e-r,new n))},l.prototype.makeLabel=function(e){var t=n.toGregorianDate(e),r=t.millisecond,i=" UTC";if(r>0&&this._timeBarSecondsSpan<3600){for(i=Math.floor(r).toString();i.length<3;)i="0"+i;i="."+i}return b[t.month-1]+" "+t.day+" "+t.year+" "+u(t.hour)+":"+u(t.minute)+":"+u(t.second)+i},l.prototype.smallestTicInPixels=7,l.prototype._makeTics=function(){function e(e){return Math.floor(y/e)*e}function t(e,t){return Math.ceil(e/t+.5)*t}function r(e){return(e-y)/p}function i(e,t){return e-t*Math.round(e/t)}var o,a=this._timeBarEle,s=n.secondsDifference(this._scrubJulian,this._startJulian),l=Math.round(s*this._topDiv.clientWidth/this._timeBarSecondsSpan),u=l-8,c=this;this._needleEle.style.left=l.toString()+"px";var d="",h=0,p=this._timeBarSecondsSpan;p<.01?(p=.01,this._timeBarSecondsSpan=.01,this._endJulian=n.addSeconds(this._startJulian,.01,new n)):p>31536e6&&(p=31536e6,this._timeBarSecondsSpan=31536e6,this._endJulian=n.addSeconds(this._startJulian,31536e6,new n));var f=this._timeBarEle.clientWidth;f<10&&(f=10);var m,g=this._startJulian,_=Math.min(p/f*1e-5,.4),v=n.toGregorianDate(g);m=p>31536e4?n.fromDate(new Date(Date.UTC(100*Math.floor(v.year/100),0))):p>31536e3?n.fromDate(new Date(Date.UTC(10*Math.floor(v.year/10),0))):p>86400?n.fromDate(new Date(Date.UTC(v.year,0))):n.fromDate(new Date(Date.UTC(v.year,v.month,v.day)));var y=n.secondsDifference(this._startJulian,n.addSeconds(m,_,new n)),b=y+p;this._epochJulian=m,this._rulerEle.innerHTML=this.makeLabel(n.addSeconds(this._endJulian,-.01,new n));var S=this._rulerEle.offsetWidth+20;S<30&&(S=180);var w=h;h-=1e-10;var T={startTime:y,startJulian:g,epochJulian:m,duration:p,timeBarWidth:f,getAlpha:r};this._highlightRanges.forEach(function(e){d+=e.render(T)});var A=0,E=0,x=0,P=S/f;P>1&&(P=1),P*=this._timeBarSecondsSpan;var D,I=-1,O=-1,M=C.length;for(D=0;D<M;++D){var R=C[D];if(++I,A=R,R>P&&R>h)break;O<0&&f*(R/this._timeBarSecondsSpan)>=this.smallestTicInPixels&&(O=I)}if(I>0){for(;I>0;)if(--I,Math.abs(i(A,C[I]))<1e-5){C[I]>=h&&(E=C[I]);break}if(O>=0)for(;O<I;){if(Math.abs(i(E,C[O]))<1e-5&&C[O]>=h){x=C[O];break}++O}}(h=w)>1e-10&&x<1e-5&&Math.abs(h-A)>1e-10&&(x=h,h<=A+1e-10&&(E=0));var N,L=-999999;if(f*(x/this._timeBarSecondsSpan)>=3)for(o=e(x);o<=b;o=t(o,x))d+='<span class="cesium-timeline-ticTiny" style="left: '+Math.round(f*r(o)).toString()+'px;"></span>';if(f*(E/this._timeBarSecondsSpan)>=3)for(o=e(E);o<=b;o=t(o,E))d+='<span class="cesium-timeline-ticSub" style="left: '+Math.round(f*r(o)).toString()+'px;"></span>';if(f*(A/this._timeBarSecondsSpan)>=2){this._mainTicSpan=A,b+=A,o=e(A);for(var k=n.computeTaiMinusUtc(m);o<=b;){var F=n.addSeconds(g,o-y,new n);if(A>2.1){var B=n.computeTaiMinusUtc(F);Math.abs(B-k)>.1&&(o+=B-k,F=n.addSeconds(g,o-y,new n))}var U=Math.round(f*r(o)),V=this.makeLabel(F);this._rulerEle.innerHTML=V,N=this._rulerEle.offsetWidth,N<10&&(N=S);var z=U-(N/2-1);z>L?(L=z+N+5,d+='<span class="cesium-timeline-ticMain" style="left: '+U.toString()+'px;"></span><span class="cesium-timeline-ticLabel" style="left: '+z.toString()+'px;">'+V+"</span>"):d+='<span class="cesium-timeline-ticSub" style="left: '+U.toString()+'px;"></span>',o=t(o,A)}}else this._mainTicSpan=-1;d+='<span class="cesium-timeline-icon16" style="left:'+u+'px;bottom:0;background-position: 0 0;"></span>',a.innerHTML=d,this._scrubElement=a.lastChild,this._context.clearRect(0,0,this._trackListEle.width,this._trackListEle.height),T.y=0,this._trackList.forEach(function(e){e.render(c._context,T),T.y+=e.height})},l.prototype.updateFromClock=function(){this._scrubJulian=this._clock.currentTime;var e=this._scrubElement;if(t(this._scrubElement)){var r=n.secondsDifference(this._scrubJulian,this._startJulian),i=Math.round(r*this._topDiv.clientWidth/this._timeBarSecondsSpan);this._lastXPos!==i&&(this._lastXPos=i,e.style.left=i-8+"px",this._needleEle.style.left=i+"px")}t(this._timelineDragLocation)&&(this._setTimeBarTime(this._timelineDragLocation,this._timelineDragLocation*this._timeBarSecondsSpan/this._topDiv.clientWidth),this.zoomTo(n.addSeconds(this._startJulian,this._timelineDrag,new n),n.addSeconds(this._endJulian,this._timelineDrag,new n)))},l.prototype._setTimeBarTime=function(e,t){if(e=Math.round(e),this._scrubJulian=n.addSeconds(this._startJulian,t,new n),this._scrubElement){var r=e-8;this._scrubElement.style.left=r.toString()+"px",this._needleEle.style.left=e.toString()+"px"}var i=document.createEvent("Event");i.initEvent("settime",!0,!0),i.clientX=e,i.timeSeconds=t,i.timeJulian=this._scrubJulian,i.clock=this._clock,this._topDiv.dispatchEvent(i)},l.prototype.resize=function(){var e=this.container.clientWidth,t=this.container.clientHeight;if(e!==this._lastWidth||t!==this._lastHeight){this._trackContainer.style.height=t+"px";var r=1;this._trackList.forEach(function(e){r+=e.height}),this._trackListEle.style.height=r.toString()+"px",this._trackListEle.width=this._trackListEle.clientWidth,this._trackListEle.height=r,this._makeTics(),this._lastXPos=void 0,this._lastWidth=e,this._lastHeight=t}},l}),define("Widgets/VRButton/VRButtonViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/EventHelper","../../Core/Fullscreen","../../Core/OrthographicFrustum","../../ThirdParty/knockout","../../ThirdParty/NoSleep","../createCommand","../getElement"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e){var r=!1,i=window.screen;return t(i)&&(t(i.lockOrientation)?r=i.lockOrientation(e):t(i.mozLockOrientation)?r=i.mozLockOrientation(e):t(i.msLockOrientation)?r=i.msLockOrientation(e):t(i.orientation&&i.orientation.lock)&&(r=i.orientation.lock(e))),r}function p(){var e=window.screen;t(e)&&(t(e.unlockOrientation)?e.unlockOrientation():t(e.mozUnlockOrientation)?e.mozUnlockOrientation():t(e.msUnlockOrientation)?e.msUnlockOrientation():t(e.orientation&&e.orientation.unlock)&&e.orientation.unlock())}function f(e,t,r,i){i()||(r()?(t.useWebVR=!1,e._locked&&(p(),e._locked=!1),e._noSleep.disable(),a.exitFullscreen(),r(!1)):(a.fullscreen||a.requestFullscreen(e._vrElement),e._noSleep.enable(),e._locked||(e._locked=h("landscape")),t.useWebVR=!0,r(!0)))}function m(t,r){var i=this,n=l.observable(a.enabled),h=l.observable(!1);this.isVRMode=void 0,l.defineProperty(this,"isVRMode",{get:function(){return h()}}),this.isVREnabled=void 0,l.defineProperty(this,"isVREnabled",{get:function(){return n()},set:function(e){n(e&&a.enabled)}}),this.tooltip=void 0,l.defineProperty(this,"tooltip",function(){return n()?h()?"Exit VR mode":"Enter VR mode":"VR mode is unavailable"});var m=l.observable(!1);this._isOrthographic=void 0,l.defineProperty(this,"_isOrthographic",{get:function(){return m()}}),this._eventHelper=new o,this._eventHelper.add(t.preRender,function(){m(t.camera.frustum instanceof s)}),this._locked=!1,this._noSleep=new u,this._command=c(function(){f(i,t,h,m)},l.getObservable(this,"isVREnabled")),this._vrElement=e(d(r),document.body),this._callback=function(){!a.fullscreen&&h()&&(t.useWebVR=!1,i._locked&&(p(),i._locked=!1),i._noSleep.disable(),h(!1))},document.addEventListener(a.changeEventName,this._callback)}return r(m.prototype,{vrElement:{get:function(){return this._vrElement},set:function(e){this._vrElement=e}},command:{get:function(){return this._command}}}), -m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){this._eventHelper.removeAll(),document.removeEventListener(a.changeEventName,this._callback),i(this)},m}),define("Widgets/VRButton/VRButton",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./VRButtonViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t,r){e=o(e);var i=new a(t,r);i._exitVRPath=u,i._enterVRPath=l;var s=document.createElement("button");s.type="button",s.className="cesium-button cesium-vrButton",s.setAttribute("data-bind",'css: { "cesium-button-disabled" : _isOrthographic }, attr: { title: tooltip },click: command,enable: isVREnabled,cesiumSvgPath: { path: isVRMode ? _exitVRPath : _enterVRPath, width: 32, height: 32 }'),e.appendChild(s),n.applyBindings(i,s),this._container=e,this._viewModel=i,this._element=s}var l="M 5.3125 6.375 C 4.008126 6.375 2.96875 7.4141499 2.96875 8.71875 L 2.96875 19.5 C 2.96875 20.8043 4.008126 21.875 5.3125 21.875 L 13.65625 21.875 C 13.71832 20.0547 14.845166 18.59375 16.21875 18.59375 C 17.592088 18.59375 18.71881 20.0552 18.78125 21.875 L 27.09375 21.875 C 28.398125 21.875 29.4375 20.8043 29.4375 19.5 L 29.4375 8.71875 C 29.4375 7.4141499 28.398125 6.375 27.09375 6.375 L 5.3125 6.375 z M 9.625 10.4375 C 11.55989 10.4375 13.125 12.03385 13.125 13.96875 C 13.125 15.90365 11.55989 17.46875 9.625 17.46875 C 7.69011 17.46875 6.125 15.90365 6.125 13.96875 C 6.125 12.03385 7.69011 10.4375 9.625 10.4375 z M 22.46875 10.4375 C 24.40364 10.4375 25.96875 12.03385 25.96875 13.96875 C 25.96875 15.90365 24.40364 17.46875 22.46875 17.46875 C 20.53386 17.46875 18.96875 15.90365 18.96875 13.96875 C 18.96875 12.03385 20.53386 10.4375 22.46875 10.4375 z",u="M 25.770585,2.4552065 C 15.72282,13.962707 10.699956,19.704407 8.1768352,22.580207 c -1.261561,1.4379 -1.902282,2.1427 -2.21875,2.5 -0.141624,0.1599 -0.208984,0.2355 -0.25,0.2813 l 0.6875,0.75 c 10e-5,-10e-5 0.679191,0.727 0.6875,0.7187 0.01662,-0.016 0.02451,-0.024 0.03125,-0.031 0.01348,-0.014 0.04013,-0.038 0.0625,-0.062 0.04474,-0.05 0.120921,-0.1315 0.28125,-0.3126 0.320657,-0.3619 0.956139,-1.0921 2.2187499,-2.5312 2.5252219,-2.8781 7.5454589,-8.6169 17.5937499,-20.1250005 l -1.5,-1.3125 z m -20.5624998,3.9063 c -1.304375,0 -2.34375,1.0391 -2.34375,2.3437 l 0,10.8125005 c 0,1.3043 1.039375,2.375 2.34375,2.375 l 2.25,0 c 1.9518039,-2.2246 7.4710958,-8.5584 13.5624998,-15.5312005 l -15.8124998,0 z m 21.1249998,0 c -1.855467,2.1245 -2.114296,2.4005 -3.59375,4.0936995 1.767282,0.1815 3.15625,1.685301 3.15625,3.500001 0,1.9349 -1.56511,3.5 -3.5,3.5 -1.658043,0 -3.043426,-1.1411 -3.40625,-2.6875 -1.089617,1.2461 -2.647139,2.9988 -3.46875,3.9375 0.191501,-0.062 0.388502,-0.094 0.59375,-0.094 1.373338,0 2.50006,1.4614 2.5625,3.2812 l 8.3125,0 c 1.304375,0 2.34375,-1.0707 2.34375,-2.375 l 0,-10.8125005 c 0,-1.3046 -1.039375,-2.3437 -2.34375,-2.3437 l -0.65625,0 z M 9.5518351,10.423906 c 1.9348899,0 3.4999999,1.596401 3.4999999,3.531301 0,1.9349 -1.56511,3.5 -3.4999999,3.5 -1.9348899,0 -3.4999999,-1.5651 -3.4999999,-3.5 0,-1.9349 1.56511,-3.531301 3.4999999,-3.531301 z m 4.2187499,10.312601 c -0.206517,0.2356 -0.844218,0.9428 -1.03125,1.1562 l 0.8125,0 c 0.01392,-0.4081 0.107026,-0.7968 0.21875,-1.1562 z";return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this._viewModel.destroy(),n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/Viewer/Viewer",["../../Core/BoundingSphere","../../Core/Cartesian3","../../Core/Clock","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Event","../../Core/EventHelper","../../Core/isArray","../../Core/Matrix4","../../Core/Rectangle","../../Core/ScreenSpaceEventType","../../DataSources/BoundingSphereState","../../DataSources/ConstantPositionProperty","../../DataSources/DataSourceCollection","../../DataSources/DataSourceDisplay","../../DataSources/Entity","../../DataSources/EntityView","../../DataSources/Property","../../Scene/ImageryLayer","../../Scene/SceneMode","../../ThirdParty/knockout","../../ThirdParty/when","../Animation/Animation","../Animation/AnimationViewModel","../BaseLayerPicker/BaseLayerPicker","../BaseLayerPicker/createDefaultImageryProviderViewModels","../BaseLayerPicker/createDefaultTerrainProviderViewModels","../CesiumWidget/CesiumWidget","../ClockViewModel","../FullscreenButton/FullscreenButton","../Geocoder/Geocoder","../getElement","../HomeButton/HomeButton","../InfoBox/InfoBox","../NavigationHelpButton/NavigationHelpButton","../ProjectionPicker/ProjectionPicker","../SceneModePicker/SceneModePicker","../SelectionIndicator/SelectionIndicator","../subscribeAndEvaluate","../Timeline/Timeline","../VRButton/VRButton"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H){"use strict";function W(e){var t=e.clock;t.currentTime=e.timeJulian,t.shouldAnimate=!1}function j(e,t){var r=e.scene.pick(t.position);if(n(r)){var o=i(r.id,r.primitive.id);if(o instanceof v)return o}if(n(e.scene.globe))return Y(e,t.position)}function q(e,t,r){if(n(r)){var i=r.clock;n(i)&&(i.getValue(t),n(e)&&(e.updateFromClock(),e.zoomTo(i.startTime,i.stopTime)))}}function Y(e,t){var r=e.scene,i=r.camera.getPickRay(t),o=r.imageryLayers.pickImageryLayerFeatures(i,r);if(n(o)){var a=new v({id:"Loading...",description:"Loading feature information..."});return T(o,function(t){if(e.selectedEntity===a){if(!n(t)||0===t.length)return void(e.selectedEntity=X());var r=t[0],i=new v({id:r.name,description:r.description});if(n(r.position)){var o=e.scene.globe.ellipsoid.cartographicToCartesian(r.position,ie);i.position=new m(o)}e.selectedEntity=i}},function(){e.selectedEntity===a&&(e.selectedEntity=X())}),a}}function X(){return new v({id:"None",description:"No features found."})}function Q(e,t){var r=e._geocoder,i=e._homeButton,o=e._sceneModePicker,a=e._projectionPicker,s=e._baseLayerPicker,l=e._animation,u=e._timeline,c=e._fullscreenButton,d=e._infoBox,h=e._selectionIndicator,p=t?"hidden":"visible";if(n(r)&&(r.container.style.visibility=p),n(i)&&(i.container.style.visibility=p),n(o)&&(o.container.style.visibility=p),n(a)&&(a.container.style.visibility=p),n(s)&&(s.container.style.visibility=p),n(l)&&(l.container.style.visibility=p),n(u)&&(u.container.style.visibility=p),n(c)&&c.viewModel.isFullscreenEnabled&&(c.container.style.visibility=p),n(d)&&(d.container.style.visibility=p),n(h)&&(h.container.style.visibility=p),e._container){var f=t||!n(c)?0:c.container.clientWidth;e._vrButton.container.style.right=f+"px",e.forceResize()}}function Z(e,t){function o(e){var t=j(d,e);n(t)&&(C.getValueOrUndefined(t.position,d.clock.currentTime)?d.trackedEntity=t:d.zoomTo(t))}function a(e){d.selectedEntity=j(d,e)}e=N(e),t=i(t,i.EMPTY_OBJECT);var s=!(n(t.globe)&&!1===t.globe||n(t.baseLayerPicker)&&!1===t.baseLayerPicker),d=this,h=document.createElement("div");h.className="cesium-viewer",e.appendChild(h);var f=document.createElement("div");f.className="cesium-viewer-cesiumWidgetContainer",h.appendChild(f);var m=document.createElement("div");m.className="cesium-viewer-bottom",h.appendChild(m);var v,y,b=i(t.scene3DOnly,!1),S=!1;n(t.clockViewModel)?(y=t.clockViewModel,v=y.clock):(v=new r,y=new O(v),S=!0);var T=new I(f,{terrainProvider:t.terrainProvider,imageryProvider:!s&&t.imageryProvider,clock:v,skyBox:t.skyBox,skyAtmosphere:t.skyAtmosphere,sceneMode:t.sceneMode,mapProjection:t.mapProjection,globe:t.globe,orderIndependentTranslucency:t.orderIndependentTranslucency,contextOptions:t.contextOptions,useDefaultRenderLoop:t.useDefaultRenderLoop,targetFrameRate:t.targetFrameRate,showRenderLoopErrors:t.showRenderLoopErrors,creditContainer:n(t.creditContainer)?t.creditContainer:m,creditViewport:t.creditViewport,scene3DOnly:b,terrainExaggeration:t.terrainExaggeration,shadows:t.shadows,terrainShadows:t.terrainShadows,mapMode2D:t.mapMode2D}),q=t.dataSources,Y=!1;n(q)||(q=new g,Y=!0);var X=new _({scene:T.scene,dataSourceCollection:q}),K=new u;K.add(v.onTick,Z.prototype._onTick,this),K.add(T.scene.morphStart,Z.prototype._clearTrackedObject,this);var J;if(!n(t.selectionIndicator)||!1!==t.selectionIndicator){var $=document.createElement("div");$.className="cesium-viewer-selectionIndicatorContainer",h.appendChild($),J=new V($,T.scene)}var ee;if(!n(t.infoBox)||!1!==t.infoBox){var te=document.createElement("div");te.className="cesium-viewer-infoBoxContainer",h.appendChild(te),ee=new k(te);var re=ee.viewModel;K.add(re.cameraClicked,Z.prototype._onInfoBoxCameraClicked,this),K.add(re.closeClicked,Z.prototype._onInfoBoxClockClicked,this)}var ie=document.createElement("div");ie.className="cesium-viewer-toolbar",h.appendChild(ie);var ne;if(!n(t.geocoder)||!1!==t.geocoder){var oe=document.createElement("div");oe.className="cesium-viewer-geocoderContainer",ie.appendChild(oe),ne=new R({container:oe,geocoderServices:n(t.geocoder)?c(t.geocoder)?t.geocoder:[t.geocoder]:void 0,scene:T.scene}),K.add(ne.viewModel.search.beforeExecute,Z.prototype._clearObjects,this)}var ae;n(t.homeButton)&&!1===t.homeButton||(ae=new L(ie,T.scene),n(ne)&&K.add(ae.viewModel.command.afterExecute,function(){var e=ne.viewModel;e.searchText="",e.isSearchInProgress&&e.search()}),K.add(ae.viewModel.command.beforeExecute,Z.prototype._clearTrackedObject,this));var se;b||n(t.sceneModePicker)&&!1===t.sceneModePicker||(se=new U(ie,T.scene));var le;t.projectionPicker&&(le=new B(ie,T.scene));var ue,ce;if(s){var de=i(t.imageryProviderViewModels,P()),he=i(t.terrainProviderViewModels,D());ue=new x(ie,{globe:T.scene.globe,imageryProviderViewModels:de,selectedImageryProviderViewModel:t.selectedImageryProviderViewModel,terrainProviderViewModels:he,selectedTerrainProviderViewModel:t.selectedTerrainProviderViewModel});ce=ie.getElementsByClassName("cesium-baseLayerPicker-dropDown")[0]}var pe;if(!n(t.navigationHelpButton)||!1!==t.navigationHelpButton){var fe=!0;try{if(n(window.localStorage)){var me=window.localStorage.getItem("cesium-hasSeenNavHelp");n(me)&&Boolean(me)?fe=!1:window.localStorage.setItem("cesium-hasSeenNavHelp","true")}}catch(e){}pe=new F({container:ie,instructionsInitiallyVisible:i(t.navigationInstructionsInitiallyVisible,fe)})}var ge;if(!n(t.animation)||!1!==t.animation){var _e=document.createElement("div");_e.className="cesium-viewer-animationContainer",h.appendChild(_e),ge=new A(_e,new E(y))}var ve;if(!n(t.timeline)||!1!==t.timeline){var ye=document.createElement("div");ye.className="cesium-viewer-timelineContainer",h.appendChild(ye),ve=new G(ye,v),ve.addEventListener("settime",W,!1),ve.zoomTo(v.startTime,v.stopTime)}var Ce,be,Se;n(t.fullscreenButton)&&!1===t.fullscreenButton||(Se=document.createElement("div"),Se.className="cesium-viewer-fullscreenContainer",h.appendChild(Se),Ce=new M(Se,t.fullscreenElement),be=z(Ce.viewModel,"isFullscreenEnabled",function(e){Se.style.display=e?"block":"none",n(ve)&&(ve.container.style.right=Se.clientWidth+"px",ve.resize())}));var we,Te,Ae;if(t.vrButton){var Ee=document.createElement("div");Ee.className="cesium-viewer-vrContainer",h.appendChild(Ee),we=new H(Ee,T.scene,t.fullScreenElement),Te=z(we.viewModel,"isVREnabled",function(e){Ee.style.display=e?"block":"none",n(Ce)&&(Ee.style.right=Se.clientWidth+"px"),n(ve)&&(ve.container.style.right=Ee.clientWidth+"px",ve.resize())}),Ae=z(we.viewModel,"isVRMode",function(e){Q(d,e)})}this._baseLayerPickerDropDown=ce,this._fullscreenSubscription=be,this._vrSubscription=Te,this._vrModeSubscription=Ae,this._dataSourceChangedListeners={},this._automaticallyTrackDataSourceClocks=i(t.automaticallyTrackDataSourceClocks,!0),this._container=e,this._bottomContainer=m,this._element=h,this._cesiumWidget=T,this._selectionIndicator=J,this._infoBox=ee,this._dataSourceCollection=q,this._destroyDataSourceCollection=Y,this._dataSourceDisplay=X,this._clockViewModel=y,this._destroyClockViewModel=S,this._toolbar=ie,this._homeButton=ae,this._sceneModePicker=se,this._projectionPicker=le,this._baseLayerPicker=ue,this._navigationHelpButton=pe,this._animation=ge,this._timeline=ve,this._fullscreenButton=Ce,this._vrButton=we,this._geocoder=ne,this._eventHelper=K,this._lastWidth=0,this._lastHeight=0,this._allowDataSourcesToSuspendAnimation=!0,this._entityView=void 0,this._enableInfoOrSelection=n(ee)||n(J),this._clockTrackedDataSource=void 0,this._trackedEntity=void 0,this._needTrackedEntityUpdate=!1,this._selectedEntity=void 0,this._clockTrackedDataSource=void 0,this._forceResize=!1,this._zoomIsFlight=!1,this._zoomTarget=void 0,this._zoomPromise=void 0,this._zoomOptions=void 0,this._selectedEntityChanged=new l,this._trackedEntityChanged=new l,w.track(this,["_trackedEntity","_selectedEntity","_clockTrackedDataSource"]),K.add(q.dataSourceAdded,Z.prototype._onDataSourceAdded,this),K.add(q.dataSourceRemoved,Z.prototype._onDataSourceRemoved,this),K.add(T.scene.preRender,Z.prototype.resize,this),K.add(T.scene.postRender,Z.prototype._postRender,this);for(var xe=q.length,Pe=0;Pe<xe;Pe++)this._dataSourceAdded(q,q.get(Pe));this._dataSourceAdded(void 0,X.defaultDataSource),K.add(q.dataSourceAdded,Z.prototype._dataSourceAdded,this),K.add(q.dataSourceRemoved,Z.prototype._dataSourceRemoved,this),T.screenSpaceEventHandler.setInputAction(a,p.LEFT_CLICK),T.screenSpaceEventHandler.setInputAction(o,p.LEFT_DOUBLE_CLICK)}function K(e,t,r,o){$(e);var a=T.defer();return e._zoomPromise=a,e._zoomIsFlight=o,e._zoomOptions=r,T(t,function(t){if(e._zoomPromise===a){if(t instanceof b)return void t.getViewableRectangle().then(function(t){e._zoomPromise===a&&(e._zoomTarget=t)});if(t.isLoading&&n(t.loadingEvent))var r=t.loadingEvent.addEventListener(function(){r(),e._zoomPromise===a&&(e._zoomTarget=t.entities.values.slice(0))});else{if(c(t))return void(e._zoomTarget=t.slice(0));t=i(t.values,t),n(t.entities)&&(t=t.entities.values),c(t)?e._zoomTarget=t.slice(0):e._zoomTarget=[t]}}}),a.promise}function J(e){e._zoomPromise=void 0,e._zoomTarget=void 0,e._zoomOptions=void 0}function $(e){var t=e._zoomPromise;n(t)&&(J(e),t.resolve(!1))}function ee(t){var r=t._zoomTarget;if(n(r)&&t.scene.mode!==S.MORPHING){var o=t.scene,a=o.camera,s=t._zoomPromise,l=i(t._zoomOptions,{});if(r instanceof h){var u={destination:r,duration:l.duration,maximumHeight:l.maximumHeight,complete:function(){s.resolve(!0)},cancel:function(){s.resolve(!1)}};return t._zoomIsFlight?a.flyTo(u):(a.setView(u),s.resolve(!0)),void J(t)}for(var c=[],p=0,m=r.length;p<m;p++){var g=t._dataSourceDisplay.getBoundingSphere(r[p],!1,re);if(g===f.PENDING)return;g!==f.FAILED&&c.push(e.clone(re))}if(0===c.length)return void $(t);t.trackedEntity=void 0;var _=e.fromBoundingSpheres(c);t._zoomIsFlight?(J(t),a.flyToBoundingSphere(_,{duration:l.duration,maximumHeight:l.maximumHeight,complete:function(){s.resolve(!0)},cancel:function(){s.resolve(!1)},offset:l.offset})):(a.viewBoundingSphere(_,t._zoomOptions),a.lookAtTransform(d.IDENTITY),J(t),s.resolve(!0))}}function te(e){if(e._needTrackedEntityUpdate){var t=e._trackedEntity,r=e.clock.currentTime,i=C.getValueOrUndefined(t.position,r);if(n(i)){var o=e.scene,a=e._dataSourceDisplay.getBoundingSphere(t,!1,re);if(a!==f.PENDING){var s=o.mode;s!==S.COLUMBUS_VIEW&&s!==S.SCENE2D||(o.screenSpaceCameraController.enableTranslate=!1),s!==S.COLUMBUS_VIEW&&s!==S.SCENE3D||(o.screenSpaceCameraController.enableTilt=!1);var l=a!==f.FAILED?re:void 0;e._entityView=new y(t,o,o.mapProjection.ellipsoid),e._entityView.update(r,l),e._needTrackedEntityUpdate=!1}}}}var re=new e,ie=new t;return o(Z.prototype,{container:{get:function(){return this._container}},bottomContainer:{get:function(){return this._bottomContainer}},cesiumWidget:{get:function(){return this._cesiumWidget}},selectionIndicator:{get:function(){return this._selectionIndicator}},infoBox:{get:function(){return this._infoBox}},geocoder:{get:function(){return this._geocoder}},homeButton:{get:function(){return this._homeButton}},sceneModePicker:{get:function(){return this._sceneModePicker}},projectionPicker:{get:function(){return this._projectionPicker}},baseLayerPicker:{get:function(){return this._baseLayerPicker}},navigationHelpButton:{get:function(){return this._navigationHelpButton}},animation:{get:function(){return this._animation}},timeline:{get:function(){return this._timeline}},fullscreenButton:{get:function(){return this._fullscreenButton}},vrButton:{get:function(){return this._vrButton}},dataSourceDisplay:{get:function(){return this._dataSourceDisplay}},entities:{get:function(){return this._dataSourceDisplay.defaultDataSource.entities}},dataSources:{get:function(){return this._dataSourceCollection}},canvas:{get:function(){return this._cesiumWidget.canvas}},cesiumLogo:{get:function(){return this._cesiumWidget.cesiumLogo}},scene:{get:function(){return this._cesiumWidget.scene}},shadows:{get:function(){return this.scene.shadowMap.enabled},set:function(e){this.scene.shadowMap.enabled=e}},terrainShadows:{get:function(){return this.scene.globe.shadows},set:function(e){this.scene.globe.shadows=e}},shadowMap:{get:function(){return this.scene.shadowMap}},imageryLayers:{get:function(){return this.scene.imageryLayers}},terrainProvider:{get:function(){return this.scene.terrainProvider},set:function(e){this.scene.terrainProvider=e}},camera:{get:function(){return this.scene.camera}},clock:{get:function(){return this._clockViewModel.clock}},clockViewModel:{get:function(){return this._clockViewModel}},screenSpaceEventHandler:{get:function(){return this._cesiumWidget.screenSpaceEventHandler}},targetFrameRate:{get:function(){return this._cesiumWidget.targetFrameRate},set:function(e){this._cesiumWidget.targetFrameRate=e}},useDefaultRenderLoop:{get:function(){return this._cesiumWidget.useDefaultRenderLoop},set:function(e){this._cesiumWidget.useDefaultRenderLoop=e}},resolutionScale:{get:function(){return this._cesiumWidget.resolutionScale},set:function(e){this._cesiumWidget.resolutionScale=e,this._forceResize=!0}},allowDataSourcesToSuspendAnimation:{get:function(){return this._allowDataSourcesToSuspendAnimation},set:function(e){this._allowDataSourcesToSuspendAnimation=e}},trackedEntity:{get:function(){return this._trackedEntity},set:function(e){if(this._trackedEntity!==e){this._trackedEntity=e,$(this);var t=this.scene,r=t.mode;n(e)&&n(e.position)?this._needTrackedEntityUpdate=!0:(this._needTrackedEntityUpdate=!1,r!==S.COLUMBUS_VIEW&&r!==S.SCENE2D||(t.screenSpaceCameraController.enableTranslate=!0),r!==S.COLUMBUS_VIEW&&r!==S.SCENE3D||(t.screenSpaceCameraController.enableTilt=!0),this._entityView=void 0,this.camera.lookAtTransform(d.IDENTITY)),this._trackedEntityChanged.raiseEvent(e)}}},selectedEntity:{get:function(){return this._selectedEntity},set:function(e){if(this._selectedEntity!==e){this._selectedEntity=e;var t=n(this._selectionIndicator)?this._selectionIndicator.viewModel:void 0;n(e)?n(t)&&t.animateAppear():n(t)&&t.animateDepart(),this._selectedEntityChanged.raiseEvent(e)}}},selectedEntityChanged:{get:function(){return this._selectedEntityChanged}},trackedEntityChanged:{get:function(){return this._trackedEntityChanged}},clockTrackedDataSource:{get:function(){return this._clockTrackedDataSource},set:function(e){this._clockTrackedDataSource!==e&&(this._clockTrackedDataSource=e,q(this._timeline,this.clock,e))}}}),Z.prototype.extend=function(e,t){e(this,t)},Z.prototype.resize=function(){var e=this._cesiumWidget,t=this._container,r=t.clientWidth,i=t.clientHeight,o=n(this._animation),a=n(this._timeline);if(this._forceResize||r!==this._lastWidth||i!==this._lastHeight){e.resize(),this._forceResize=!1;var s=i-125,l=this._baseLayerPickerDropDown;if(n(l)&&(l.style.maxHeight=s+"px"),n(this._geocoder)){this._geocoder.searchSuggestionsContainer.style.maxHeight=s+"px"}n(this._infoBox)&&(this._infoBox.viewModel.maxHeight=s);var u,c=this._timeline,d=0,h=0,p=0;if(o&&"hidden"!==window.getComputedStyle(this._animation.container).visibility){var f=this._lastWidth;u=this._animation.container,r>900?(d=169,f<=900&&(u.style.width="169px",u.style.height="112px",this._animation.resize())):r>=600?(d=136,(f<600||f>900)&&(u.style.width="136px",u.style.height="90px",this._animation.resize())):(d=106,(f>600||0===f)&&(u.style.width="106px",u.style.height="70px",this._animation.resize())),h=d+5}if(a&&"hidden"!==window.getComputedStyle(this._timeline.container).visibility){var m=this._fullscreenButton,g=this._vrButton,_=c.container,v=_.style;p=_.clientHeight+3,v.left=d+"px";var y=0;n(m)&&(y+=m.container.clientWidth),n(g)&&(y+=g.container.clientWidth),v.right=y+"px",c.resize()}this._bottomContainer.style.left=h+"px",this._bottomContainer.style.bottom=p+"px",this._lastWidth=r,this._lastHeight=i}},Z.prototype.forceResize=function(){this._lastWidth=0,this.resize()},Z.prototype.render=function(){this._cesiumWidget.render()},Z.prototype.isDestroyed=function(){return!1},Z.prototype.destroy=function(){var e;this.screenSpaceEventHandler.removeInputAction(p.LEFT_CLICK),this.screenSpaceEventHandler.removeInputAction(p.LEFT_DOUBLE_CLICK);var t=this.dataSources,r=t.length;for(e=0;e<r;e++)this._dataSourceRemoved(t,t.get(e));return this._dataSourceRemoved(void 0,this._dataSourceDisplay.defaultDataSource),this._container.removeChild(this._element),this._element.removeChild(this._toolbar),this._eventHelper.removeAll(),n(this._geocoder)&&(this._geocoder=this._geocoder.destroy()),n(this._homeButton)&&(this._homeButton=this._homeButton.destroy()),n(this._sceneModePicker)&&(this._sceneModePicker=this._sceneModePicker.destroy()),n(this._projectionPicker)&&(this._projectionPicker=this._projectionPicker.destroy()),n(this._baseLayerPicker)&&(this._baseLayerPicker=this._baseLayerPicker.destroy()),n(this._animation)&&(this._element.removeChild(this._animation.container),this._animation=this._animation.destroy()),n(this._timeline)&&(this._timeline.removeEventListener("settime",W,!1),this._element.removeChild(this._timeline.container),this._timeline=this._timeline.destroy()),n(this._fullscreenButton)&&(this._fullscreenSubscription.dispose(),this._element.removeChild(this._fullscreenButton.container),this._fullscreenButton=this._fullscreenButton.destroy()),n(this._vrButton)&&(this._vrSubscription.dispose(),this._vrModeSubscription.dispose(),this._element.removeChild(this._vrButton.container),this._vrButton=this._vrButton.destroy()),n(this._infoBox)&&(this._element.removeChild(this._infoBox.container),this._infoBox=this._infoBox.destroy()),n(this._selectionIndicator)&&(this._element.removeChild(this._selectionIndicator.container),this._selectionIndicator=this._selectionIndicator.destroy()),this._destroyClockViewModel&&(this._clockViewModel=this._clockViewModel.destroy()),this._dataSourceDisplay=this._dataSourceDisplay.destroy(),this._cesiumWidget=this._cesiumWidget.destroy(),this._destroyDataSourceCollection&&(this._dataSourceCollection=this._dataSourceCollection.destroy()),a(this)},Z.prototype._dataSourceAdded=function(e,t){t.entities.collectionChanged.addEventListener(Z.prototype._onEntityCollectionChanged,this)},Z.prototype._dataSourceRemoved=function(e,t){var r=t.entities;r.collectionChanged.removeEventListener(Z.prototype._onEntityCollectionChanged,this),n(this.trackedEntity)&&r.getById(this.trackedEntity.id)===this.trackedEntity&&(this.trackedEntity=void 0),n(this.selectedEntity)&&r.getById(this.selectedEntity.id)===this.selectedEntity&&(this.selectedEntity=void 0)},Z.prototype._onTick=function(e){var r=e.currentTime,o=this._dataSourceDisplay.update(r);this._allowDataSourcesToSuspendAnimation&&(this._clockViewModel.canAnimate=o);var a=this._entityView;if(n(a)){var s=this._trackedEntity;this._dataSourceDisplay.getBoundingSphere(s,!1,re)===f.DONE&&a.update(r,re)}var l,u=!1,c=this.selectedEntity,d=n(c)&&this._enableInfoOrSelection;if(d&&c.isShowing&&c.isAvailable(r)){this._dataSourceDisplay.getBoundingSphere(c,!0,re)!==f.FAILED?l=re.center:n(c.position)&&(l=c.position.getValue(r,l)),u=n(l)}var h=n(this._selectionIndicator)?this._selectionIndicator.viewModel:void 0;n(h)&&(h.position=t.clone(l,h.position),h.showSelection=d&&u,h.update());var p=n(this._infoBox)?this._infoBox.viewModel:void 0;n(p)&&(p.showInfo=d,p.enableCamera=u,p.isCameraTracking=this.trackedEntity===this.selectedEntity,d?(p.titleText=i(c.name,c.id),p.description=C.getValueOrDefault(c.description,r,"")):(p.titleText="",p.description=""))},Z.prototype._onEntityCollectionChanged=function(e,t,r){for(var i=r.length,n=0;n<i;n++){var o=r[n];this.trackedEntity===o&&(this.trackedEntity=void 0),this.selectedEntity===o&&(this.selectedEntity=void 0)}},Z.prototype._onInfoBoxCameraClicked=function(e){if(e.isCameraTracking&&this.trackedEntity===this.selectedEntity)this.trackedEntity=void 0;else{var t=this.selectedEntity,r=t.position;n(r)?this.trackedEntity=this.selectedEntity:this.zoomTo(this.selectedEntity)}},Z.prototype._clearTrackedObject=function(){this.trackedEntity=void 0},Z.prototype._onInfoBoxClockClicked=function(e){this.selectedEntity=void 0},Z.prototype._clearObjects=function(){this.trackedEntity=void 0,this.selectedEntity=void 0},Z.prototype._onDataSourceChanged=function(e){this.clockTrackedDataSource===e&&q(this.timeline,this.clock,e)},Z.prototype._onDataSourceAdded=function(e,t){this._automaticallyTrackDataSourceClocks&&(this.clockTrackedDataSource=t);var r=t.entities.id,i=this._eventHelper.add(t.changedEvent,Z.prototype._onDataSourceChanged,this);this._dataSourceChangedListeners[r]=i},Z.prototype._onDataSourceRemoved=function(e,t){var r=this.clockTrackedDataSource===t,i=t.entities.id;if(this._dataSourceChangedListeners[i](),this._dataSourceChangedListeners[i]=void 0,r){var n=e.length;this._automaticallyTrackDataSourceClocks&&n>0?this.clockTrackedDataSource=e.get(n-1):this.clockTrackedDataSource=void 0}},Z.prototype.zoomTo=function(e,t){return K(this,e,t,!1)},Z.prototype.flyTo=function(e,t){return K(this,e,t,!0)},Z.prototype._postRender=function(){ee(this),te(this)},Z}),define("Widgets/Viewer/viewerCesium3DTilesInspectorMixin",["../../Core/Check","../../Core/defineProperties","../Cesium3DTilesInspector/Cesium3DTilesInspector"],function(e,t,r){"use strict";function i(e){var i=document.createElement("div");i.className="cesium-viewer-cesium3DTilesInspectorContainer",e.container.appendChild(i);var n=new r(i,e.scene);t(e,{cesium3DTilesInspector:{get:function(){return n}}})}return i}),define("Widgets/Viewer/viewerCesiumInspectorMixin",["../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../CesiumInspector/CesiumInspector"],function(e,t,r,i){"use strict";function n(e){var r=document.createElement("div");r.className="cesium-viewer-cesiumInspectorContainer",e.container.appendChild(r);var n=new i(r,e.scene);t(e,{cesiumInspector:{get:function(){return n}}})}return n}),define("Widgets/Viewer/viewerDragDropMixin",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/Event","../../Core/wrapFunction","../../DataSources/CzmlDataSource","../../DataSources/GeoJsonDataSource","../../DataSources/KmlDataSource","../getElement"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,i){function a(e){d(e),g&&(t.entities.removeAll(),t.dataSources.removeAll());for(var r=e.dataTransfer.files,i=r.length,n=0;n<i;n++){var o=r[n],a=new FileReader;a.onload=f(t,o,y,v),a.onerror=m(t,o),a.readAsText(o)}}i=e(i,e.EMPTY_OBJECT);var s=!0,l=e(i.flyToOnDrop,!0),c=new n,g=e(i.clearOnDrop,!0),_=e(i.dropTarget,t.container),v=e(i.clampToGround,!0),y=i.proxy;_=u(_),r(t,{dropTarget:{get:function(){return _},set:function(e){h(_,a),_=e,p(_,a)}},dropEnabled:{get:function(){return s},set:function(e){e!==s&&(e?p(_,a):h(_,a),s=e)}},dropError:{get:function(){return c}},clearOnDrop:{get:function(){return g},set:function(e){g=e}},flyToOnDrop:{get:function(){return l},set:function(e){l=e}},proxy:{get:function(){return y},set:function(e){y=e}},clampToGround:{get:function(){return v},set:function(e){v=e}}}),p(_,a),t.destroy=o(t,t.destroy,function(){t.dropEnabled=!1}),t._handleDrop=a}function d(e){e.stopPropagation(),e.preventDefault()}function h(e,r){var i=e;t(i)&&(i.removeEventListener("drop",r,!1),i.removeEventListener("dragenter",d,!1),i.removeEventListener("dragover",d,!1),i.removeEventListener("dragexit",d,!1))}function p(e,t){e.addEventListener("drop",t,!1),e.addEventListener("dragenter",d,!1),e.addEventListener("dragover",d,!1),e.addEventListener("dragexit",d,!1)}function f(e,r,i,n){var o=e.scene;return function(u){var c=r.name;try{var d;if(/\.czml$/i.test(c))d=a.load(JSON.parse(u.target.result),{sourceUri:c});else if(/\.geojson$/i.test(c)||/\.json$/i.test(c)||/\.topojson$/i.test(c))d=s.load(JSON.parse(u.target.result),{sourceUri:c,clampToGround:n});else{if(!/\.(kml|kmz)$/i.test(c))return void e.dropError.raiseEvent(e,c,"Unrecognized file: "+c);d=l.load(r,{sourceUri:c,proxy:i,camera:o.camera,canvas:o.canvas})}t(d)&&e.dataSources.add(d).then(function(t){e.flyToOnDrop&&e.flyTo(t)}).otherwise(function(t){e.dropError.raiseEvent(e,c,t)})}catch(t){e.dropError.raiseEvent(e,c,t)}}}function m(e,t){return function(r){e.dropError.raiseEvent(e,t.name,r.target.error)}}return c}),define("Widgets/Viewer/viewerPerformanceWatchdogMixin",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../PerformanceWatchdog/PerformanceWatchdog"],function(e,t,r,i,n){"use strict";function o(t,i){i=e(i,e.EMPTY_OBJECT);var o=new n({scene:t.scene,container:t.bottomContainer,lowFrameRateMessage:i.lowFrameRateMessage});r(t,{performanceWatchdog:{get:function(){return o}}})}return o}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,r){"use strict";function i(i){var n,o=[],a={id:void 0,result:void 0,error:void 0};return function(s){var l=s.data;o.length=0,a.id=l.id,a.error=void 0,a.result=void 0;try{a.result=i(l.parameters,o)}catch(e){e instanceof Error?a.error={name:e.name,message:e.message,stack:e.stack}:a.error=e}t(n)||(n=e(self.webkitPostMessage,self.postMessage)),l.canTransferArrayBuffer||(o.length=0);try{n(a,o)}catch(e){a.result=void 0,a.error="postMessage failed with error: "+r(e)+"\n with responseMessage: "+JSON.stringify(a),n(a)}}}return i}), -define("Cesium",["./Core/appendForwardSlash","./Core/arrayFill","./Core/arrayRemoveDuplicates","./Core/AssociativeArray","./Core/AttributeCompression","./Core/AxisAlignedBoundingBox","./Core/barycentricCoordinates","./Core/binarySearch","./Core/BingMapsApi","./Core/BingMapsGeocoderService","./Core/BoundingRectangle","./Core/BoundingSphere","./Core/BoxGeometry","./Core/BoxOutlineGeometry","./Core/buildModuleUrl","./Core/cancelAnimationFrame","./Core/Cartesian2","./Core/Cartesian3","./Core/Cartesian4","./Core/Cartographic","./Core/CartographicGeocoderService","./Core/CatmullRomSpline","./Core/CesiumTerrainProvider","./Core/Check","./Core/CircleGeometry","./Core/CircleOutlineGeometry","./Core/ClippingPlaneCollection","./Core/Clock","./Core/ClockRange","./Core/ClockStep","./Core/clone","./Core/Color","./Core/ColorGeometryInstanceAttribute","./Core/combine","./Core/ComponentDatatype","./Core/CompressedTextureBuffer","./Core/CornerType","./Core/CorridorGeometry","./Core/CorridorGeometryLibrary","./Core/CorridorOutlineGeometry","./Core/createGuid","./Core/Credit","./Core/CubicRealPolynomial","./Core/CullingVolume","./Core/CylinderGeometry","./Core/CylinderGeometryLibrary","./Core/CylinderOutlineGeometry","./Core/decodeGoogleEarthEnterpriseData","./Core/DefaultProxy","./Core/defaultValue","./Core/defined","./Core/defineProperties","./Core/deprecationWarning","./Core/destroyObject","./Core/DeveloperError","./Core/DistanceDisplayCondition","./Core/DistanceDisplayConditionGeometryInstanceAttribute","./Core/DoublyLinkedList","./Core/EarthOrientationParameters","./Core/EarthOrientationParametersSample","./Core/EasingFunction","./Core/EllipseGeometry","./Core/EllipseGeometryLibrary","./Core/EllipseOutlineGeometry","./Core/Ellipsoid","./Core/EllipsoidalOccluder","./Core/EllipsoidGeodesic","./Core/EllipsoidGeometry","./Core/EllipsoidOutlineGeometry","./Core/EllipsoidTangentPlane","./Core/EllipsoidTerrainProvider","./Core/EncodedCartesian3","./Core/Event","./Core/EventHelper","./Core/ExtrapolationType","./Core/FeatureDetection","./Core/formatError","./Core/freezeObject","./Core/FrustumGeometry","./Core/FrustumOutlineGeometry","./Core/Fullscreen","./Core/GeocoderService","./Core/GeographicProjection","./Core/GeographicTilingScheme","./Core/Geometry","./Core/GeometryAttribute","./Core/GeometryAttributes","./Core/GeometryInstance","./Core/GeometryInstanceAttribute","./Core/GeometryPipeline","./Core/GeometryType","./Core/getAbsoluteUri","./Core/getBaseUri","./Core/getExtensionFromUri","./Core/getFilenameFromUri","./Core/getImagePixels","./Core/getMagic","./Core/getStringFromTypedArray","./Core/getTimestamp","./Core/GoogleEarthEnterpriseMetadata","./Core/GoogleEarthEnterpriseTerrainData","./Core/GoogleEarthEnterpriseTerrainProvider","./Core/GoogleEarthEnterpriseTileInformation","./Core/GregorianDate","./Core/HeadingPitchRange","./Core/HeadingPitchRoll","./Core/Heap","./Core/HeightmapTerrainData","./Core/HeightmapTessellator","./Core/HermitePolynomialApproximation","./Core/HermiteSpline","./Core/Iau2000Orientation","./Core/Iau2006XysData","./Core/Iau2006XysSample","./Core/IauOrientationAxes","./Core/IauOrientationParameters","./Core/IndexDatatype","./Core/InterpolationAlgorithm","./Core/Intersect","./Core/Intersections2D","./Core/IntersectionTests","./Core/Interval","./Core/isArray","./Core/isBitSet","./Core/isBlobUri","./Core/isCrossOriginUrl","./Core/isDataUri","./Core/isLeapYear","./Core/Iso8601","./Core/joinUrls","./Core/JulianDate","./Core/KeyboardEventModifier","./Core/LagrangePolynomialApproximation","./Core/LeapSecond","./Core/LinearApproximation","./Core/LinearSpline","./Core/loadArrayBuffer","./Core/loadBlob","./Core/loadCRN","./Core/loadImage","./Core/loadImageFromTypedArray","./Core/loadImageViaBlob","./Core/loadJson","./Core/loadJsonp","./Core/loadKTX","./Core/loadText","./Core/loadWithXhr","./Core/loadXML","./Core/ManagedArray","./Core/MapboxApi","./Core/MapProjection","./Core/Math","./Core/Matrix2","./Core/Matrix3","./Core/Matrix4","./Core/mergeSort","./Core/NearFarScalar","./Core/objectToQuery","./Core/Occluder","./Core/oneTimeWarning","./Core/OrientedBoundingBox","./Core/OrthographicFrustum","./Core/OrthographicOffCenterFrustum","./Core/Packable","./Core/PackableForInterpolation","./Core/parseResponseHeaders","./Core/PerspectiveFrustum","./Core/PerspectiveOffCenterFrustum","./Core/PinBuilder","./Core/PixelFormat","./Core/Plane","./Core/PlaneGeometry","./Core/PlaneOutlineGeometry","./Core/pointInsideTriangle","./Core/PolygonGeometry","./Core/PolygonGeometryLibrary","./Core/PolygonHierarchy","./Core/PolygonOutlineGeometry","./Core/PolygonPipeline","./Core/PolylineGeometry","./Core/PolylinePipeline","./Core/PolylineVolumeGeometry","./Core/PolylineVolumeGeometryLibrary","./Core/PolylineVolumeOutlineGeometry","./Core/PrimitiveType","./Core/QuadraticRealPolynomial","./Core/QuantizedMeshTerrainData","./Core/QuarticRealPolynomial","./Core/Quaternion","./Core/QuaternionSpline","./Core/queryToObject","./Core/Queue","./Core/Ray","./Core/Rectangle","./Core/RectangleGeometry","./Core/RectangleGeometryLibrary","./Core/RectangleOutlineGeometry","./Core/ReferenceFrame","./Core/Request","./Core/requestAnimationFrame","./Core/RequestErrorEvent","./Core/RequestScheduler","./Core/RequestState","./Core/RequestType","./Core/RuntimeError","./Core/sampleTerrain","./Core/sampleTerrainMostDetailed","./Core/scaleToGeodeticSurface","./Core/ScreenSpaceEventHandler","./Core/ScreenSpaceEventType","./Core/ShowGeometryInstanceAttribute","./Core/Simon1994PlanetaryPositions","./Core/SimplePolylineGeometry","./Core/SphereGeometry","./Core/SphereOutlineGeometry","./Core/Spherical","./Core/Spline","./Core/subdivideArray","./Core/TaskProcessor","./Core/TerrainData","./Core/TerrainEncoding","./Core/TerrainMesh","./Core/TerrainProvider","./Core/TerrainQuantization","./Core/TileAvailability","./Core/TileProviderError","./Core/TilingScheme","./Core/TimeConstants","./Core/TimeInterval","./Core/TimeIntervalCollection","./Core/TimeStandard","./Core/Tipsify","./Core/Transforms","./Core/TranslationRotationScale","./Core/TridiagonalSystemSolver","./Core/TrustedServers","./Core/VertexFormat","./Core/VideoSynchronizer","./Core/Visibility","./Core/VRTheWorldTerrainProvider","./Core/WallGeometry","./Core/WallGeometryLibrary","./Core/WallOutlineGeometry","./Core/WebGLConstants","./Core/WebMercatorProjection","./Core/WebMercatorTilingScheme","./Core/WeightSpline","./Core/WindingOrder","./Core/wrapFunction","./Core/writeTextToCanvas","./DataSources/BillboardGraphics","./DataSources/BillboardVisualizer","./DataSources/BoundingSphereState","./DataSources/BoxGeometryUpdater","./DataSources/BoxGraphics","./DataSources/CallbackProperty","./DataSources/CheckerboardMaterialProperty","./DataSources/ColorMaterialProperty","./DataSources/CompositeEntityCollection","./DataSources/CompositeMaterialProperty","./DataSources/CompositePositionProperty","./DataSources/CompositeProperty","./DataSources/ConstantPositionProperty","./DataSources/ConstantProperty","./DataSources/CorridorGeometryUpdater","./DataSources/CorridorGraphics","./DataSources/createMaterialPropertyDescriptor","./DataSources/createPropertyDescriptor","./DataSources/createRawPropertyDescriptor","./DataSources/CustomDataSource","./DataSources/CylinderGeometryUpdater","./DataSources/CylinderGraphics","./DataSources/CzmlDataSource","./DataSources/DataSource","./DataSources/DataSourceClock","./DataSources/DataSourceCollection","./DataSources/DataSourceDisplay","./DataSources/dynamicGeometryGetBoundingSphere","./DataSources/DynamicGeometryUpdater","./DataSources/EllipseGeometryUpdater","./DataSources/EllipseGraphics","./DataSources/EllipsoidGeometryUpdater","./DataSources/EllipsoidGraphics","./DataSources/Entity","./DataSources/EntityCluster","./DataSources/EntityCollection","./DataSources/EntityView","./DataSources/GeoJsonDataSource","./DataSources/GeometryUpdater","./DataSources/GeometryVisualizer","./DataSources/GridMaterialProperty","./DataSources/ImageMaterialProperty","./DataSources/KmlCamera","./DataSources/KmlDataSource","./DataSources/KmlLookAt","./DataSources/KmlTour","./DataSources/KmlTourFlyTo","./DataSources/KmlTourWait","./DataSources/LabelGraphics","./DataSources/LabelVisualizer","./DataSources/MaterialProperty","./DataSources/ModelGraphics","./DataSources/ModelVisualizer","./DataSources/NodeTransformationProperty","./DataSources/PathGraphics","./DataSources/PathVisualizer","./DataSources/PlaneGeometryUpdater","./DataSources/PlaneGraphics","./DataSources/PointGraphics","./DataSources/PointVisualizer","./DataSources/PolygonGeometryUpdater","./DataSources/PolygonGraphics","./DataSources/PolylineArrowMaterialProperty","./DataSources/PolylineDashMaterialProperty","./DataSources/PolylineGeometryUpdater","./DataSources/PolylineGlowMaterialProperty","./DataSources/PolylineGraphics","./DataSources/PolylineOutlineMaterialProperty","./DataSources/PolylineVolumeGeometryUpdater","./DataSources/PolylineVolumeGraphics","./DataSources/PositionProperty","./DataSources/PositionPropertyArray","./DataSources/Property","./DataSources/PropertyArray","./DataSources/PropertyBag","./DataSources/RectangleGeometryUpdater","./DataSources/RectangleGraphics","./DataSources/ReferenceProperty","./DataSources/Rotation","./DataSources/SampledPositionProperty","./DataSources/SampledProperty","./DataSources/ScaledPositionProperty","./DataSources/StaticGeometryColorBatch","./DataSources/StaticGeometryPerMaterialBatch","./DataSources/StaticGroundGeometryColorBatch","./DataSources/StaticOutlineGeometryBatch","./DataSources/StripeMaterialProperty","./DataSources/StripeOrientation","./DataSources/TimeIntervalCollectionPositionProperty","./DataSources/TimeIntervalCollectionProperty","./DataSources/VelocityOrientationProperty","./DataSources/VelocityVectorProperty","./DataSources/Visualizer","./DataSources/WallGeometryUpdater","./DataSources/WallGraphics","./Renderer/AutomaticUniforms","./Renderer/Buffer","./Renderer/BufferUsage","./Renderer/ClearCommand","./Renderer/ComputeCommand","./Renderer/ComputeEngine","./Renderer/Context","./Renderer/ContextLimits","./Renderer/createUniform","./Renderer/createUniformArray","./Renderer/CubeMap","./Renderer/CubeMapFace","./Renderer/DrawCommand","./Renderer/Framebuffer","./Renderer/freezeRenderState","./Renderer/loadCubeMap","./Renderer/MipmapHint","./Renderer/modernizeShader","./Renderer/Pass","./Renderer/PassState","./Renderer/PickFramebuffer","./Renderer/PixelDatatype","./Renderer/Renderbuffer","./Renderer/RenderbufferFormat","./Renderer/RenderState","./Renderer/Sampler","./Renderer/ShaderCache","./Renderer/ShaderProgram","./Renderer/ShaderSource","./Renderer/Texture","./Renderer/TextureMagnificationFilter","./Renderer/TextureMinificationFilter","./Renderer/TextureWrap","./Renderer/UniformState","./Renderer/VertexArray","./Renderer/VertexArrayFacade","./Scene/Appearance","./Scene/ArcGisMapServerImageryProvider","./Scene/AttributeType","./Scene/Axis","./Scene/Batched3DModel3DTileContent","./Scene/BatchTable","./Scene/Billboard","./Scene/BillboardCollection","./Scene/BingMapsImageryProvider","./Scene/BingMapsStyle","./Scene/BlendEquation","./Scene/BlendFunction","./Scene/BlendingState","./Scene/BlendOption","./Scene/BoxEmitter","./Scene/BrdfLutGenerator","./Scene/Camera","./Scene/CameraEventAggregator","./Scene/CameraEventType","./Scene/CameraFlightPath","./Scene/Cesium3DTile","./Scene/Cesium3DTileBatchTable","./Scene/Cesium3DTileChildrenVisibility","./Scene/Cesium3DTileColorBlendMode","./Scene/Cesium3DTileContent","./Scene/Cesium3DTileContentFactory","./Scene/Cesium3DTileContentState","./Scene/Cesium3DTileFeature","./Scene/Cesium3DTileFeatureTable","./Scene/Cesium3DTileOptimizationHint","./Scene/Cesium3DTileOptimizations","./Scene/Cesium3DTileRefine","./Scene/Cesium3DTileset","./Scene/Cesium3DTilesetStatistics","./Scene/Cesium3DTilesetTraversal","./Scene/Cesium3DTileStyle","./Scene/Cesium3DTileStyleEngine","./Scene/CircleEmitter","./Scene/ClassificationPrimitive","./Scene/ClassificationType","./Scene/ColorBlendMode","./Scene/Composite3DTileContent","./Scene/ConditionsExpression","./Scene/ConeEmitter","./Scene/createOpenStreetMapImageryProvider","./Scene/createTangentSpaceDebugPrimitive","./Scene/createTileMapServiceImageryProvider","./Scene/CreditDisplay","./Scene/CullFace","./Scene/DebugAppearance","./Scene/DebugCameraPrimitive","./Scene/DebugModelMatrixPrimitive","./Scene/DepthFunction","./Scene/DepthPlane","./Scene/DeviceOrientationCameraController","./Scene/DiscardMissingTileImagePolicy","./Scene/EllipsoidPrimitive","./Scene/EllipsoidSurfaceAppearance","./Scene/Empty3DTileContent","./Scene/Expression","./Scene/ExpressionNodeType","./Scene/Fog","./Scene/FrameRateMonitor","./Scene/FrameState","./Scene/FrustumCommands","./Scene/FXAA","./Scene/getAttributeOrUniformBySemantic","./Scene/getBinaryAccessor","./Scene/GetFeatureInfoFormat","./Scene/Globe","./Scene/GlobeDepth","./Scene/GlobeSurfaceShaderSet","./Scene/GlobeSurfaceTile","./Scene/GlobeSurfaceTileProvider","./Scene/GoogleEarthEnterpriseImageryProvider","./Scene/GoogleEarthEnterpriseMapsProvider","./Scene/GridImageryProvider","./Scene/GroundPrimitive","./Scene/HeightReference","./Scene/HorizontalOrigin","./Scene/Imagery","./Scene/ImageryLayer","./Scene/ImageryLayerCollection","./Scene/ImageryLayerFeatureInfo","./Scene/ImageryProvider","./Scene/ImagerySplitDirection","./Scene/ImageryState","./Scene/Instanced3DModel3DTileContent","./Scene/InvertClassification","./Scene/JobScheduler","./Scene/JobType","./Scene/Label","./Scene/LabelCollection","./Scene/LabelStyle","./Scene/MapboxImageryProvider","./Scene/MapMode2D","./Scene/Material","./Scene/MaterialAppearance","./Scene/Model","./Scene/ModelAnimation","./Scene/ModelAnimationCache","./Scene/ModelAnimationCollection","./Scene/ModelAnimationLoop","./Scene/ModelAnimationState","./Scene/ModelInstance","./Scene/ModelInstanceCollection","./Scene/ModelMaterial","./Scene/ModelMesh","./Scene/ModelNode","./Scene/Moon","./Scene/NeverTileDiscardPolicy","./Scene/OIT","./Scene/Particle","./Scene/ParticleBurst","./Scene/ParticleEmitter","./Scene/ParticleSystem","./Scene/PerformanceDisplay","./Scene/PerInstanceColorAppearance","./Scene/PickDepth","./Scene/PointCloud3DTileContent","./Scene/PointPrimitive","./Scene/PointPrimitiveCollection","./Scene/Polyline","./Scene/PolylineCollection","./Scene/PolylineColorAppearance","./Scene/PolylineMaterialAppearance","./Scene/Primitive","./Scene/PrimitiveCollection","./Scene/PrimitivePipeline","./Scene/PrimitiveState","./Scene/QuadtreeOccluders","./Scene/QuadtreePrimitive","./Scene/QuadtreeTile","./Scene/QuadtreeTileLoadState","./Scene/QuadtreeTileProvider","./Scene/Scene","./Scene/SceneMode","./Scene/SceneTransforms","./Scene/SceneTransitioner","./Scene/ScreenSpaceCameraController","./Scene/ShadowMap","./Scene/ShadowMapShader","./Scene/ShadowMode","./Scene/SingleTileImageryProvider","./Scene/SkyAtmosphere","./Scene/SkyBox","./Scene/SphereEmitter","./Scene/StencilFunction","./Scene/StencilOperation","./Scene/StyleExpression","./Scene/Sun","./Scene/SunPostProcess","./Scene/TerrainState","./Scene/TextureAtlas","./Scene/TileBoundingRegion","./Scene/TileBoundingSphere","./Scene/TileBoundingVolume","./Scene/TileCoordinatesImageryProvider","./Scene/TileDiscardPolicy","./Scene/TileImagery","./Scene/TileOrientedBoundingBox","./Scene/TileReplacementQueue","./Scene/Tileset3DTileContent","./Scene/TileState","./Scene/TileTerrain","./Scene/TimeDynamicImagery","./Scene/TweenCollection","./Scene/UrlTemplateImageryProvider","./Scene/VerticalOrigin","./Scene/ViewportQuad","./Scene/WebMapServiceImageryProvider","./Scene/WebMapTileServiceImageryProvider","./Shaders/AdjustTranslucentFS","./Shaders/Appearances/AllMaterialAppearanceFS","./Shaders/Appearances/AllMaterialAppearanceVS","./Shaders/Appearances/BasicMaterialAppearanceFS","./Shaders/Appearances/BasicMaterialAppearanceVS","./Shaders/Appearances/EllipsoidSurfaceAppearanceFS","./Shaders/Appearances/EllipsoidSurfaceAppearanceVS","./Shaders/Appearances/PerInstanceColorAppearanceFS","./Shaders/Appearances/PerInstanceColorAppearanceVS","./Shaders/Appearances/PerInstanceFlatColorAppearanceFS","./Shaders/Appearances/PerInstanceFlatColorAppearanceVS","./Shaders/Appearances/PolylineColorAppearanceVS","./Shaders/Appearances/PolylineMaterialAppearanceVS","./Shaders/Appearances/TexturedMaterialAppearanceFS","./Shaders/Appearances/TexturedMaterialAppearanceVS","./Shaders/BillboardCollectionFS","./Shaders/BillboardCollectionVS","./Shaders/BrdfLutGeneratorFS","./Shaders/Builtin/Constants/degreesPerRadian","./Shaders/Builtin/Constants/depthRange","./Shaders/Builtin/Constants/epsilon1","./Shaders/Builtin/Constants/epsilon2","./Shaders/Builtin/Constants/epsilon3","./Shaders/Builtin/Constants/epsilon4","./Shaders/Builtin/Constants/epsilon5","./Shaders/Builtin/Constants/epsilon6","./Shaders/Builtin/Constants/epsilon7","./Shaders/Builtin/Constants/infinity","./Shaders/Builtin/Constants/maxClippingPlanes","./Shaders/Builtin/Constants/oneOverPi","./Shaders/Builtin/Constants/oneOverTwoPi","./Shaders/Builtin/Constants/passCesium3DTile","./Shaders/Builtin/Constants/passCesium3DTileClassification","./Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow","./Shaders/Builtin/Constants/passCompute","./Shaders/Builtin/Constants/passEnvironment","./Shaders/Builtin/Constants/passGlobe","./Shaders/Builtin/Constants/passOpaque","./Shaders/Builtin/Constants/passOverlay","./Shaders/Builtin/Constants/passTerrainClassification","./Shaders/Builtin/Constants/passTranslucent","./Shaders/Builtin/Constants/pi","./Shaders/Builtin/Constants/piOverFour","./Shaders/Builtin/Constants/piOverSix","./Shaders/Builtin/Constants/piOverThree","./Shaders/Builtin/Constants/piOverTwo","./Shaders/Builtin/Constants/radiansPerDegree","./Shaders/Builtin/Constants/sceneMode2D","./Shaders/Builtin/Constants/sceneMode3D","./Shaders/Builtin/Constants/sceneModeColumbusView","./Shaders/Builtin/Constants/sceneModeMorphing","./Shaders/Builtin/Constants/solarRadius","./Shaders/Builtin/Constants/threePiOver2","./Shaders/Builtin/Constants/twoPi","./Shaders/Builtin/Constants/webMercatorMaxLatitude","./Shaders/Builtin/CzmBuiltins","./Shaders/Builtin/Functions/alphaWeight","./Shaders/Builtin/Functions/antialias","./Shaders/Builtin/Functions/cascadeColor","./Shaders/Builtin/Functions/cascadeDistance","./Shaders/Builtin/Functions/cascadeMatrix","./Shaders/Builtin/Functions/cascadeWeights","./Shaders/Builtin/Functions/columbusViewMorph","./Shaders/Builtin/Functions/computePosition","./Shaders/Builtin/Functions/cosineAndSine","./Shaders/Builtin/Functions/decompressTextureCoordinates","./Shaders/Builtin/Functions/discardIfClippedWithIntersect","./Shaders/Builtin/Functions/discardIfClippedWithUnion","./Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates","./Shaders/Builtin/Functions/ellipsoidContainsPoint","./Shaders/Builtin/Functions/ellipsoidNew","./Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates","./Shaders/Builtin/Functions/equalsEpsilon","./Shaders/Builtin/Functions/eyeOffset","./Shaders/Builtin/Functions/eyeToWindowCoordinates","./Shaders/Builtin/Functions/fog","./Shaders/Builtin/Functions/geodeticSurfaceNormal","./Shaders/Builtin/Functions/getDefaultMaterial","./Shaders/Builtin/Functions/getLambertDiffuse","./Shaders/Builtin/Functions/getSpecular","./Shaders/Builtin/Functions/getWaterNoise","./Shaders/Builtin/Functions/getWgs84EllipsoidEC","./Shaders/Builtin/Functions/HSBToRGB","./Shaders/Builtin/Functions/HSLToRGB","./Shaders/Builtin/Functions/hue","./Shaders/Builtin/Functions/isEmpty","./Shaders/Builtin/Functions/isFull","./Shaders/Builtin/Functions/latitudeToWebMercatorFraction","./Shaders/Builtin/Functions/luminance","./Shaders/Builtin/Functions/metersPerPixel","./Shaders/Builtin/Functions/modelToWindowCoordinates","./Shaders/Builtin/Functions/multiplyWithColorBalance","./Shaders/Builtin/Functions/nearFarScalar","./Shaders/Builtin/Functions/octDecode","./Shaders/Builtin/Functions/packDepth","./Shaders/Builtin/Functions/phong","./Shaders/Builtin/Functions/pointAlongRay","./Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval","./Shaders/Builtin/Functions/RGBToHSB","./Shaders/Builtin/Functions/RGBToHSL","./Shaders/Builtin/Functions/RGBToXYZ","./Shaders/Builtin/Functions/saturation","./Shaders/Builtin/Functions/shadowDepthCompare","./Shaders/Builtin/Functions/shadowVisibility","./Shaders/Builtin/Functions/signNotZero","./Shaders/Builtin/Functions/tangentToEyeSpaceMatrix","./Shaders/Builtin/Functions/translateRelativeToEye","./Shaders/Builtin/Functions/translucentPhong","./Shaders/Builtin/Functions/transpose","./Shaders/Builtin/Functions/unpackDepth","./Shaders/Builtin/Functions/windowToEyeCoordinates","./Shaders/Builtin/Functions/XYZToRGB","./Shaders/Builtin/Structs/depthRangeStruct","./Shaders/Builtin/Structs/ellipsoid","./Shaders/Builtin/Structs/material","./Shaders/Builtin/Structs/materialInput","./Shaders/Builtin/Structs/ray","./Shaders/Builtin/Structs/raySegment","./Shaders/Builtin/Structs/shadowParameters","./Shaders/CompositeOITFS","./Shaders/DepthPlaneFS","./Shaders/DepthPlaneVS","./Shaders/EllipsoidFS","./Shaders/EllipsoidVS","./Shaders/GlobeFS","./Shaders/GlobeVS","./Shaders/GroundAtmosphere","./Shaders/Materials/BumpMapMaterial","./Shaders/Materials/CheckerboardMaterial","./Shaders/Materials/DotMaterial","./Shaders/Materials/ElevationContourMaterial","./Shaders/Materials/ElevationRampMaterial","./Shaders/Materials/FadeMaterial","./Shaders/Materials/GridMaterial","./Shaders/Materials/NormalMapMaterial","./Shaders/Materials/PolylineArrowMaterial","./Shaders/Materials/PolylineDashMaterial","./Shaders/Materials/PolylineGlowMaterial","./Shaders/Materials/PolylineOutlineMaterial","./Shaders/Materials/RimLightingMaterial","./Shaders/Materials/SlopeRampMaterial","./Shaders/Materials/StripeMaterial","./Shaders/Materials/Water","./Shaders/PointPrimitiveCollectionFS","./Shaders/PointPrimitiveCollectionVS","./Shaders/PolylineCommon","./Shaders/PolylineFS","./Shaders/PolylineVS","./Shaders/PostProcessFilters/AdditiveBlend","./Shaders/PostProcessFilters/BrightPass","./Shaders/PostProcessFilters/FXAA","./Shaders/PostProcessFilters/GaussianBlur1D","./Shaders/PostProcessFilters/PassThrough","./Shaders/ReprojectWebMercatorFS","./Shaders/ReprojectWebMercatorVS","./Shaders/ShadowVolumeFS","./Shaders/ShadowVolumeVS","./Shaders/SkyAtmosphereFS","./Shaders/SkyAtmosphereVS","./Shaders/SkyBoxFS","./Shaders/SkyBoxVS","./Shaders/SunFS","./Shaders/SunTextureFS","./Shaders/SunVS","./Shaders/ViewportQuadFS","./Shaders/ViewportQuadVS","./ThirdParty/Autolinker","./ThirdParty/crunch","./ThirdParty/earcut-2.1.1","./ThirdParty/GltfPipeline/addDefaults","./ThirdParty/GltfPipeline/addExtensionsRequired","./ThirdParty/GltfPipeline/addExtensionsUsed","./ThirdParty/GltfPipeline/addPipelineExtras","./ThirdParty/GltfPipeline/addToArray","./ThirdParty/GltfPipeline/byteLengthForComponentType","./ThirdParty/GltfPipeline/findAccessorMinMax","./ThirdParty/GltfPipeline/ForEach","./ThirdParty/GltfPipeline/getAccessorByteStride","./ThirdParty/GltfPipeline/getJointCountForMaterials","./ThirdParty/GltfPipeline/glslTypeToWebGLConstant","./ThirdParty/GltfPipeline/numberOfComponentsForType","./ThirdParty/GltfPipeline/parseBinaryGltf","./ThirdParty/GltfPipeline/processModelMaterialsCommon","./ThirdParty/GltfPipeline/processPbrMetallicRoughness","./ThirdParty/GltfPipeline/removeExtensionsRequired","./ThirdParty/GltfPipeline/removeExtensionsUsed","./ThirdParty/GltfPipeline/removePipelineExtras","./ThirdParty/GltfPipeline/techniqueParameterForSemantic","./ThirdParty/GltfPipeline/updateVersion","./ThirdParty/GltfPipeline/webGLConstantToGlslType","./ThirdParty/google-earth-dbroot-parser","./ThirdParty/jsep","./ThirdParty/kdbush","./ThirdParty/knockout-3.4.2","./ThirdParty/knockout-es5","./ThirdParty/knockout","./ThirdParty/measureText","./ThirdParty/mersenne-twister","./ThirdParty/NoSleep","./ThirdParty/pako_inflate","./ThirdParty/protobuf-minimal","./ThirdParty/Shaders/FXAA3_11","./ThirdParty/sprintf","./ThirdParty/topojson","./ThirdParty/Tween","./ThirdParty/Uri","./ThirdParty/when","./ThirdParty/zip","./Widgets/Animation/Animation","./Widgets/Animation/AnimationViewModel","./Widgets/BaseLayerPicker/BaseLayerPicker","./Widgets/BaseLayerPicker/BaseLayerPickerViewModel","./Widgets/BaseLayerPicker/createDefaultImageryProviderViewModels","./Widgets/BaseLayerPicker/createDefaultTerrainProviderViewModels","./Widgets/BaseLayerPicker/ProviderViewModel","./Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector","./Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel","./Widgets/CesiumInspector/CesiumInspector","./Widgets/CesiumInspector/CesiumInspectorViewModel","./Widgets/CesiumWidget/CesiumWidget","./Widgets/ClockViewModel","./Widgets/Command","./Widgets/createCommand","./Widgets/FullscreenButton/FullscreenButton","./Widgets/FullscreenButton/FullscreenButtonViewModel","./Widgets/Geocoder/Geocoder","./Widgets/Geocoder/GeocoderViewModel","./Widgets/getElement","./Widgets/HomeButton/HomeButton","./Widgets/HomeButton/HomeButtonViewModel","./Widgets/InfoBox/InfoBox","./Widgets/InfoBox/InfoBoxViewModel","./Widgets/NavigationHelpButton/NavigationHelpButton","./Widgets/NavigationHelpButton/NavigationHelpButtonViewModel","./Widgets/PerformanceWatchdog/PerformanceWatchdog","./Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel","./Widgets/ProjectionPicker/ProjectionPicker","./Widgets/ProjectionPicker/ProjectionPickerViewModel","./Widgets/SceneModePicker/SceneModePicker","./Widgets/SceneModePicker/SceneModePickerViewModel","./Widgets/SelectionIndicator/SelectionIndicator","./Widgets/SelectionIndicator/SelectionIndicatorViewModel","./Widgets/subscribeAndEvaluate","./Widgets/SvgPathBindingHandler","./Widgets/Timeline/Timeline","./Widgets/Timeline/TimelineHighlightRange","./Widgets/Timeline/TimelineTrack","./Widgets/ToggleButtonViewModel","./Widgets/Viewer/Viewer","./Widgets/Viewer/viewerCesium3DTilesInspectorMixin","./Widgets/Viewer/viewerCesiumInspectorMixin","./Widgets/Viewer/viewerDragDropMixin","./Widgets/Viewer/viewerPerformanceWatchdogMixin","./Widgets/VRButton/VRButton","./Widgets/VRButton/VRButtonViewModel","./Workers/createTaskProcessorWorker"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,C,b,S,w,T,A,E,x,P,D,I,O,M,R,N,L,k,F,B,U,V,z,G,H,W,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,Ce,be,Se,we,Te,Ae,Ee,xe,Pe,De,Ie,Oe,Me,Re,Ne,Le,ke,Fe,Be,Ue,Ve,ze,Ge,He,We,je,qe,Ye,Xe,Qe,Ze,Ke,Je,$e,et,tt,rt,it,nt,ot,at,st,lt,ut,ct,dt,ht,pt,ft,mt,gt,_t,vt,yt,Ct,bt,St,wt,Tt,At,Et,xt,Pt,Dt,It,Ot,Mt,Rt,Nt,Lt,kt,Ft,Bt,Ut,Vt,zt,Gt,Ht,Wt,jt,qt,Yt,Xt,Qt,Zt,Kt,Jt,$t,er,tr,rr,ir,nr,or,ar,sr,lr,ur,cr,dr,hr,pr,fr,mr,gr,_r,vr,yr,Cr,br,Sr,wr,Tr,Ar,Er,xr,Pr,Dr,Ir,Or,Mr,Rr,Nr,Lr,kr,Fr,Br,Ur,Vr,zr,Gr,Hr,Wr,jr,qr,Yr,Xr,Qr,Zr,Kr,Jr,$r,ei,ti,ri,ii,ni,oi,ai,si,li,ui,ci,di,hi,pi,fi,mi,gi,_i,vi,yi,Ci,bi,Si,wi,Ti,Ai,Ei,xi,Pi,Di,Ii,Oi,Mi,Ri,Ni,Li,ki,Fi,Bi,Ui,Vi,zi,Gi,Hi,Wi,ji,qi,Yi,Xi,Qi,Zi,Ki,Ji,$i,en,tn,rn,nn,on,an,sn,ln,un,cn,dn,hn,pn,fn,mn,gn,_n,vn,yn,Cn,bn,Sn,wn,Tn,An,En,xn,Pn,Dn,In,On,Mn,Rn,Nn,Ln,kn,Fn,Bn,Un,Vn,zn,Gn,Hn,Wn,jn,qn,Yn,Xn,Qn,Zn,Kn,Jn,$n,eo,to,ro,io,no,oo,ao,so,lo,uo,co,ho,po,fo,mo,go,_o,vo,yo,Co,bo,So,wo,To,Ao,Eo,xo,Po,Do,Io,Oo,Mo,Ro,No,Lo,ko,Fo,Bo,Uo,Vo,zo,Go,Ho,Wo,jo,qo,Yo,Xo,Qo,Zo,Ko,Jo,$o,ea,ta,ra,ia,na,oa,aa,sa,la,ua,ca,da,ha,pa,fa,ma,ga,_a,va,ya,Ca,ba,Sa,wa,Ta,Aa,Ea,xa,Pa,Da,Ia,Oa,Ma,Ra,Na,La,ka,Fa,Ba,Ua,Va,za,Ga,Ha,Wa,ja,qa,Ya,Xa,Qa,Za,Ka,Ja,$a,es,ts,rs,is,ns,os,as,ss,ls,us,cs,ds,hs,ps,fs,ms,gs,_s,vs,ys,Cs,bs,Ss,ws,Ts,As,Es,xs,Ps,Ds,Is,Os,Ms,Rs,Ns,Ls,ks,Fs,Bs,Us,Vs,zs,Gs,Hs,Ws,js,qs,Ys,Xs,Qs,Zs,Ks,Js,$s,el,tl,rl,il,nl,ol,al,sl,ll,ul,cl,dl,hl,pl,fl,ml,gl,_l,vl,yl,Cl,bl,Sl,wl,Tl,Al,El,xl,Pl,Dl,Il,Ol,Ml,Rl,Nl,Ll,kl,Fl,Bl,Ul,Vl,zl,Gl,Hl,Wl,jl,ql,Yl,Xl,Ql,Zl,Kl,Jl,$l,eu,tu,ru,iu,nu,ou,au,su,lu,uu,cu,du,hu,pu,fu,mu,gu,_u,vu,yu,Cu,bu,Su,wu,Tu,Au,Eu,xu,Pu,Du,Iu,Ou,Mu,Ru,Nu,Lu,ku,Fu,Bu,Uu,Vu,zu,Gu,Hu,Wu,ju,qu,Yu,Xu,Qu,Zu,Ku,Ju,$u,ec,tc,rc,ic,nc,oc,ac,sc,lc,uc,cc,dc,hc,pc,fc,mc,gc,_c,vc,yc,Cc,bc,Sc,wc,Tc,Ac,Ec,xc,Pc,Dc,Ic,Oc,Mc,Rc,Nc,Lc,kc,Fc,Bc,Uc,Vc,zc,Gc,Hc,Wc,jc,qc,Yc,Xc,Qc,Zc,Kc,Jc,$c,ed,td,rd,id,nd,od,ad,sd,ld,ud,cd,dd,hd,pd,fd,md,gd,_d,vd,yd,Cd,bd,Sd,wd,Td,Ad,Ed,xd,Pd,Dd,Id,Od,Md,Rd,Nd,Ld,kd,Fd,Bd,Ud,Vd,zd,Gd,Hd,Wd,jd,qd,Yd,Xd,Qd,Zd,Kd,Jd,$d,eh,th,rh,ih,nh,oh,ah,sh,lh,uh,ch,dh,hh,ph,fh,mh,gh,_h,vh,yh,Ch,bh,Sh,wh,Th,Ah,Eh,xh,Ph,Dh,Ih,Oh,Mh,Rh,Nh,Lh,kh,Fh,Bh,Uh,Vh,zh,Gh,Hh,Wh,jh,qh,Yh,Xh,Qh,Zh,Kh,Jh,$h,ep,tp,rp,ip,np,op,ap,sp,lp,up,cp,dp,hp,pp,fp,mp,gp,_p,vp,yp,Cp,bp,Sp,wp,Tp,Ap,Ep,xp,Pp,Dp,Ip,Op,Mp,Rp,Np,Lp,kp,Fp,Bp,Up,Vp,zp,Gp,Hp,Wp,jp,qp,Yp,Xp,Qp,Zp,Kp,Jp,$p,ef){"use strict";var tf={VERSION:"1.41",_shaders:{}};return tf.appendForwardSlash=e,tf.arrayFill=t,tf.arrayRemoveDuplicates=r,tf.AssociativeArray=i,tf.AttributeCompression=n,tf.AxisAlignedBoundingBox=o,tf.barycentricCoordinates=a,tf.binarySearch=s,tf.BingMapsApi=l,tf.BingMapsGeocoderService=u,tf.BoundingRectangle=c,tf.BoundingSphere=d,tf.BoxGeometry=h,tf.BoxOutlineGeometry=p,tf.buildModuleUrl=f,tf.cancelAnimationFrame=m,tf.Cartesian2=g,tf.Cartesian3=_,tf.Cartesian4=v,tf.Cartographic=y,tf.CartographicGeocoderService=C,tf.CatmullRomSpline=b,tf.CesiumTerrainProvider=S,tf.Check=w,tf.CircleGeometry=T,tf.CircleOutlineGeometry=A,tf.ClippingPlaneCollection=E,tf.Clock=x,tf.ClockRange=P,tf.ClockStep=D,tf.clone=I,tf.Color=O,tf.ColorGeometryInstanceAttribute=M,tf.combine=R,tf.ComponentDatatype=N,tf.CompressedTextureBuffer=L,tf.CornerType=k,tf.CorridorGeometry=F,tf.CorridorGeometryLibrary=B,tf.CorridorOutlineGeometry=U,tf.createGuid=V,tf.Credit=z,tf.CubicRealPolynomial=G,tf.CullingVolume=H,tf.CylinderGeometry=W,tf.CylinderGeometryLibrary=j,tf.CylinderOutlineGeometry=q,tf.decodeGoogleEarthEnterpriseData=Y,tf.DefaultProxy=X,tf.defaultValue=Q,tf.defined=Z,tf.defineProperties=K,tf.deprecationWarning=J,tf.destroyObject=$,tf.DeveloperError=ee,tf.DistanceDisplayCondition=te,tf.DistanceDisplayConditionGeometryInstanceAttribute=re,tf.DoublyLinkedList=ie,tf.EarthOrientationParameters=ne,tf.EarthOrientationParametersSample=oe,tf.EasingFunction=ae,tf.EllipseGeometry=se,tf.EllipseGeometryLibrary=le,tf.EllipseOutlineGeometry=ue,tf.Ellipsoid=ce,tf.EllipsoidalOccluder=de,tf.EllipsoidGeodesic=he,tf.EllipsoidGeometry=pe,tf.EllipsoidOutlineGeometry=fe,tf.EllipsoidTangentPlane=me,tf.EllipsoidTerrainProvider=ge,tf.EncodedCartesian3=_e,tf.Event=ve,tf.EventHelper=ye,tf.ExtrapolationType=Ce,tf.FeatureDetection=be,tf.formatError=Se,tf.freezeObject=we,tf.FrustumGeometry=Te,tf.FrustumOutlineGeometry=Ae,tf.Fullscreen=Ee,tf.GeocoderService=xe,tf.GeographicProjection=Pe,tf.GeographicTilingScheme=De,tf.Geometry=Ie,tf.GeometryAttribute=Oe,tf.GeometryAttributes=Me,tf.GeometryInstance=Re,tf.GeometryInstanceAttribute=Ne,tf.GeometryPipeline=Le,tf.GeometryType=ke,tf.getAbsoluteUri=Fe,tf.getBaseUri=Be,tf.getExtensionFromUri=Ue,tf.getFilenameFromUri=Ve,tf.getImagePixels=ze,tf.getMagic=Ge,tf.getStringFromTypedArray=He,tf.getTimestamp=We,tf.GoogleEarthEnterpriseMetadata=je,tf.GoogleEarthEnterpriseTerrainData=qe,tf.GoogleEarthEnterpriseTerrainProvider=Ye,tf.GoogleEarthEnterpriseTileInformation=Xe,tf.GregorianDate=Qe,tf.HeadingPitchRange=Ze,tf.HeadingPitchRoll=Ke,tf.Heap=Je,tf.HeightmapTerrainData=$e,tf.HeightmapTessellator=et,tf.HermitePolynomialApproximation=tt,tf.HermiteSpline=rt,tf.Iau2000Orientation=it,tf.Iau2006XysData=nt,tf.Iau2006XysSample=ot,tf.IauOrientationAxes=at,tf.IauOrientationParameters=st,tf.IndexDatatype=lt,tf.InterpolationAlgorithm=ut,tf.Intersect=ct,tf.Intersections2D=dt,tf.IntersectionTests=ht,tf.Interval=pt,tf.isArray=ft,tf.isBitSet=mt,tf.isBlobUri=gt,tf.isCrossOriginUrl=_t,tf.isDataUri=vt,tf.isLeapYear=yt,tf.Iso8601=Ct,tf.joinUrls=bt,tf.JulianDate=St,tf.KeyboardEventModifier=wt,tf.LagrangePolynomialApproximation=Tt,tf.LeapSecond=At,tf.LinearApproximation=Et,tf.LinearSpline=xt,tf.loadArrayBuffer=Pt,tf.loadBlob=Dt,tf.loadCRN=It,tf.loadImage=Ot,tf.loadImageFromTypedArray=Mt,tf.loadImageViaBlob=Rt,tf.loadJson=Nt,tf.loadJsonp=Lt,tf.loadKTX=kt,tf.loadText=Ft, -tf.loadWithXhr=Bt,tf.loadXML=Ut,tf.ManagedArray=Vt,tf.MapboxApi=zt,tf.MapProjection=Gt,tf.Math=Ht,tf.Matrix2=Wt,tf.Matrix3=jt,tf.Matrix4=qt,tf.mergeSort=Yt,tf.NearFarScalar=Xt,tf.objectToQuery=Qt,tf.Occluder=Zt,tf.oneTimeWarning=Kt,tf.OrientedBoundingBox=Jt,tf.OrthographicFrustum=$t,tf.OrthographicOffCenterFrustum=er,tf.Packable=tr,tf.PackableForInterpolation=rr,tf.parseResponseHeaders=ir,tf.PerspectiveFrustum=nr,tf.PerspectiveOffCenterFrustum=or,tf.PinBuilder=ar,tf.PixelFormat=sr,tf.Plane=lr,tf.PlaneGeometry=ur,tf.PlaneOutlineGeometry=cr,tf.pointInsideTriangle=dr,tf.PolygonGeometry=hr,tf.PolygonGeometryLibrary=pr,tf.PolygonHierarchy=fr,tf.PolygonOutlineGeometry=mr,tf.PolygonPipeline=gr,tf.PolylineGeometry=_r,tf.PolylinePipeline=vr,tf.PolylineVolumeGeometry=yr,tf.PolylineVolumeGeometryLibrary=Cr,tf.PolylineVolumeOutlineGeometry=br,tf.PrimitiveType=Sr,tf.QuadraticRealPolynomial=wr,tf.QuantizedMeshTerrainData=Tr,tf.QuarticRealPolynomial=Ar,tf.Quaternion=Er,tf.QuaternionSpline=xr,tf.queryToObject=Pr,tf.Queue=Dr,tf.Ray=Ir,tf.Rectangle=Or,tf.RectangleGeometry=Mr,tf.RectangleGeometryLibrary=Rr,tf.RectangleOutlineGeometry=Nr,tf.ReferenceFrame=Lr,tf.Request=kr,tf.requestAnimationFrame=Fr,tf.RequestErrorEvent=Br,tf.RequestScheduler=Ur,tf.RequestState=Vr,tf.RequestType=zr,tf.RuntimeError=Gr,tf.sampleTerrain=Hr,tf.sampleTerrainMostDetailed=Wr,tf.scaleToGeodeticSurface=jr,tf.ScreenSpaceEventHandler=qr,tf.ScreenSpaceEventType=Yr,tf.ShowGeometryInstanceAttribute=Xr,tf.Simon1994PlanetaryPositions=Qr,tf.SimplePolylineGeometry=Zr,tf.SphereGeometry=Kr,tf.SphereOutlineGeometry=Jr,tf.Spherical=$r,tf.Spline=ei,tf.subdivideArray=ti,tf.TaskProcessor=ri,tf.TerrainData=ii,tf.TerrainEncoding=ni,tf.TerrainMesh=oi,tf.TerrainProvider=ai,tf.TerrainQuantization=si,tf.TileAvailability=li,tf.TileProviderError=ui,tf.TilingScheme=ci,tf.TimeConstants=di,tf.TimeInterval=hi,tf.TimeIntervalCollection=pi,tf.TimeStandard=fi,tf.Tipsify=mi,tf.Transforms=gi,tf.TranslationRotationScale=_i,tf.TridiagonalSystemSolver=vi,tf.TrustedServers=yi,tf.VertexFormat=Ci,tf.VideoSynchronizer=bi,tf.Visibility=Si,tf.VRTheWorldTerrainProvider=wi,tf.WallGeometry=Ti,tf.WallGeometryLibrary=Ai,tf.WallOutlineGeometry=Ei,tf.WebGLConstants=xi,tf.WebMercatorProjection=Pi,tf.WebMercatorTilingScheme=Di,tf.WeightSpline=Ii,tf.WindingOrder=Oi,tf.wrapFunction=Mi,tf.writeTextToCanvas=Ri,tf.BillboardGraphics=Ni,tf.BillboardVisualizer=Li,tf.BoundingSphereState=ki,tf.BoxGeometryUpdater=Fi,tf.BoxGraphics=Bi,tf.CallbackProperty=Ui,tf.CheckerboardMaterialProperty=Vi,tf.ColorMaterialProperty=zi,tf.CompositeEntityCollection=Gi,tf.CompositeMaterialProperty=Hi,tf.CompositePositionProperty=Wi,tf.CompositeProperty=ji,tf.ConstantPositionProperty=qi,tf.ConstantProperty=Yi,tf.CorridorGeometryUpdater=Xi,tf.CorridorGraphics=Qi,tf.createMaterialPropertyDescriptor=Zi,tf.createPropertyDescriptor=Ki,tf.createRawPropertyDescriptor=Ji,tf.CustomDataSource=$i,tf.CylinderGeometryUpdater=en,tf.CylinderGraphics=tn,tf.CzmlDataSource=rn,tf.DataSource=nn,tf.DataSourceClock=on,tf.DataSourceCollection=an,tf.DataSourceDisplay=sn,tf.dynamicGeometryGetBoundingSphere=ln,tf.DynamicGeometryUpdater=un,tf.EllipseGeometryUpdater=cn,tf.EllipseGraphics=dn,tf.EllipsoidGeometryUpdater=hn,tf.EllipsoidGraphics=pn,tf.Entity=fn,tf.EntityCluster=mn,tf.EntityCollection=gn,tf.EntityView=_n,tf.GeoJsonDataSource=vn,tf.GeometryUpdater=yn,tf.GeometryVisualizer=Cn,tf.GridMaterialProperty=bn,tf.ImageMaterialProperty=Sn,tf.KmlCamera=wn,tf.KmlDataSource=Tn,tf.KmlLookAt=An,tf.KmlTour=En,tf.KmlTourFlyTo=xn,tf.KmlTourWait=Pn,tf.LabelGraphics=Dn,tf.LabelVisualizer=In,tf.MaterialProperty=On,tf.ModelGraphics=Mn,tf.ModelVisualizer=Rn,tf.NodeTransformationProperty=Nn,tf.PathGraphics=Ln,tf.PathVisualizer=kn,tf.PlaneGeometryUpdater=Fn,tf.PlaneGraphics=Bn,tf.PointGraphics=Un,tf.PointVisualizer=Vn,tf.PolygonGeometryUpdater=zn,tf.PolygonGraphics=Gn,tf.PolylineArrowMaterialProperty=Hn,tf.PolylineDashMaterialProperty=Wn,tf.PolylineGeometryUpdater=jn,tf.PolylineGlowMaterialProperty=qn,tf.PolylineGraphics=Yn,tf.PolylineOutlineMaterialProperty=Xn,tf.PolylineVolumeGeometryUpdater=Qn,tf.PolylineVolumeGraphics=Zn,tf.PositionProperty=Kn,tf.PositionPropertyArray=Jn,tf.Property=$n,tf.PropertyArray=eo,tf.PropertyBag=to,tf.RectangleGeometryUpdater=ro,tf.RectangleGraphics=io,tf.ReferenceProperty=no,tf.Rotation=oo,tf.SampledPositionProperty=ao,tf.SampledProperty=so,tf.ScaledPositionProperty=lo,tf.StaticGeometryColorBatch=uo,tf.StaticGeometryPerMaterialBatch=co,tf.StaticGroundGeometryColorBatch=ho,tf.StaticOutlineGeometryBatch=po,tf.StripeMaterialProperty=fo,tf.StripeOrientation=mo,tf.TimeIntervalCollectionPositionProperty=go,tf.TimeIntervalCollectionProperty=_o,tf.VelocityOrientationProperty=vo,tf.VelocityVectorProperty=yo,tf.Visualizer=Co,tf.WallGeometryUpdater=bo,tf.WallGraphics=So,tf.AutomaticUniforms=wo,tf.Buffer=To,tf.BufferUsage=Ao,tf.ClearCommand=Eo,tf.ComputeCommand=xo,tf.ComputeEngine=Po,tf.Context=Do,tf.ContextLimits=Io,tf.createUniform=Oo,tf.createUniformArray=Mo,tf.CubeMap=Ro,tf.CubeMapFace=No,tf.DrawCommand=Lo,tf.Framebuffer=ko,tf.freezeRenderState=Fo,tf.loadCubeMap=Bo,tf.MipmapHint=Uo,tf.modernizeShader=Vo,tf.Pass=zo,tf.PassState=Go,tf.PickFramebuffer=Ho,tf.PixelDatatype=Wo,tf.Renderbuffer=jo,tf.RenderbufferFormat=qo,tf.RenderState=Yo,tf.Sampler=Xo,tf.ShaderCache=Qo,tf.ShaderProgram=Zo,tf.ShaderSource=Ko,tf.Texture=Jo,tf.TextureMagnificationFilter=$o,tf.TextureMinificationFilter=ea,tf.TextureWrap=ta,tf.UniformState=ra,tf.VertexArray=ia,tf.VertexArrayFacade=na,tf.Appearance=oa,tf.ArcGisMapServerImageryProvider=aa,tf.AttributeType=sa,tf.Axis=la,tf.Batched3DModel3DTileContent=ua,tf.BatchTable=ca,tf.Billboard=da,tf.BillboardCollection=ha,tf.BingMapsImageryProvider=pa,tf.BingMapsStyle=fa,tf.BlendEquation=ma,tf.BlendFunction=ga,tf.BlendingState=_a,tf.BlendOption=va,tf.BoxEmitter=ya,tf.BrdfLutGenerator=Ca,tf.Camera=ba,tf.CameraEventAggregator=Sa,tf.CameraEventType=wa,tf.CameraFlightPath=Ta,tf.Cesium3DTile=Aa,tf.Cesium3DTileBatchTable=Ea,tf.Cesium3DTileChildrenVisibility=xa,tf.Cesium3DTileColorBlendMode=Pa,tf.Cesium3DTileContent=Da,tf.Cesium3DTileContentFactory=Ia,tf.Cesium3DTileContentState=Oa,tf.Cesium3DTileFeature=Ma,tf.Cesium3DTileFeatureTable=Ra,tf.Cesium3DTileOptimizationHint=Na,tf.Cesium3DTileOptimizations=La,tf.Cesium3DTileRefine=ka,tf.Cesium3DTileset=Fa,tf.Cesium3DTilesetStatistics=Ba,tf.Cesium3DTilesetTraversal=Ua,tf.Cesium3DTileStyle=Va,tf.Cesium3DTileStyleEngine=za,tf.CircleEmitter=Ga,tf.ClassificationPrimitive=Ha,tf.ClassificationType=Wa,tf.ColorBlendMode=ja,tf.Composite3DTileContent=qa,tf.ConditionsExpression=Ya,tf.ConeEmitter=Xa,tf.createOpenStreetMapImageryProvider=Qa,tf.createTangentSpaceDebugPrimitive=Za,tf.createTileMapServiceImageryProvider=Ka,tf.CreditDisplay=Ja,tf.CullFace=$a,tf.DebugAppearance=es,tf.DebugCameraPrimitive=ts,tf.DebugModelMatrixPrimitive=rs,tf.DepthFunction=is,tf.DepthPlane=ns,tf.DeviceOrientationCameraController=os,tf.DiscardMissingTileImagePolicy=as,tf.EllipsoidPrimitive=ss,tf.EllipsoidSurfaceAppearance=ls,tf.Empty3DTileContent=us,tf.Expression=cs,tf.ExpressionNodeType=ds,tf.Fog=hs,tf.FrameRateMonitor=ps,tf.FrameState=fs,tf.FrustumCommands=ms,tf.FXAA=gs,tf.getAttributeOrUniformBySemantic=_s,tf.getBinaryAccessor=vs,tf.GetFeatureInfoFormat=ys,tf.Globe=Cs,tf.GlobeDepth=bs,tf.GlobeSurfaceShaderSet=Ss,tf.GlobeSurfaceTile=ws,tf.GlobeSurfaceTileProvider=Ts,tf.GoogleEarthEnterpriseImageryProvider=As,tf.GoogleEarthEnterpriseMapsProvider=Es,tf.GridImageryProvider=xs,tf.GroundPrimitive=Ps,tf.HeightReference=Ds,tf.HorizontalOrigin=Is,tf.Imagery=Os,tf.ImageryLayer=Ms,tf.ImageryLayerCollection=Rs,tf.ImageryLayerFeatureInfo=Ns,tf.ImageryProvider=Ls,tf.ImagerySplitDirection=ks,tf.ImageryState=Fs,tf.Instanced3DModel3DTileContent=Bs,tf.InvertClassification=Us,tf.JobScheduler=Vs,tf.JobType=zs,tf.Label=Gs,tf.LabelCollection=Hs,tf.LabelStyle=Ws,tf.MapboxImageryProvider=js,tf.MapMode2D=qs,tf.Material=Ys,tf.MaterialAppearance=Xs,tf.Model=Qs,tf.ModelAnimation=Zs,tf.ModelAnimationCache=Ks,tf.ModelAnimationCollection=Js,tf.ModelAnimationLoop=$s,tf.ModelAnimationState=el,tf.ModelInstance=tl,tf.ModelInstanceCollection=rl,tf.ModelMaterial=il,tf.ModelMesh=nl,tf.ModelNode=ol,tf.Moon=al,tf.NeverTileDiscardPolicy=sl,tf.OIT=ll,tf.Particle=ul,tf.ParticleBurst=cl,tf.ParticleEmitter=dl,tf.ParticleSystem=hl,tf.PerformanceDisplay=pl,tf.PerInstanceColorAppearance=fl,tf.PickDepth=ml,tf.PointCloud3DTileContent=gl,tf.PointPrimitive=_l,tf.PointPrimitiveCollection=vl,tf.Polyline=yl,tf.PolylineCollection=Cl,tf.PolylineColorAppearance=bl,tf.PolylineMaterialAppearance=Sl,tf.Primitive=wl,tf.PrimitiveCollection=Tl,tf.PrimitivePipeline=Al,tf.PrimitiveState=El,tf.QuadtreeOccluders=xl,tf.QuadtreePrimitive=Pl,tf.QuadtreeTile=Dl,tf.QuadtreeTileLoadState=Il,tf.QuadtreeTileProvider=Ol,tf.Scene=Ml,tf.SceneMode=Rl,tf.SceneTransforms=Nl,tf.SceneTransitioner=Ll,tf.ScreenSpaceCameraController=kl,tf.ShadowMap=Fl,tf.ShadowMapShader=Bl,tf.ShadowMode=Ul,tf.SingleTileImageryProvider=Vl,tf.SkyAtmosphere=zl,tf.SkyBox=Gl,tf.SphereEmitter=Hl,tf.StencilFunction=Wl,tf.StencilOperation=jl,tf.StyleExpression=ql,tf.Sun=Yl,tf.SunPostProcess=Xl,tf.TerrainState=Ql,tf.TextureAtlas=Zl,tf.TileBoundingRegion=Kl,tf.TileBoundingSphere=Jl,tf.TileBoundingVolume=$l,tf.TileCoordinatesImageryProvider=eu,tf.TileDiscardPolicy=tu,tf.TileImagery=ru,tf.TileOrientedBoundingBox=iu,tf.TileReplacementQueue=nu,tf.Tileset3DTileContent=ou,tf.TileState=au,tf.TileTerrain=su,tf.TimeDynamicImagery=lu,tf.TweenCollection=uu,tf.UrlTemplateImageryProvider=cu,tf.VerticalOrigin=du,tf.ViewportQuad=hu,tf.WebMapServiceImageryProvider=pu,tf.WebMapTileServiceImageryProvider=fu,tf._shaders.AdjustTranslucentFS=mu,tf._shaders.AllMaterialAppearanceFS=gu,tf._shaders.AllMaterialAppearanceVS=_u,tf._shaders.BasicMaterialAppearanceFS=vu,tf._shaders.BasicMaterialAppearanceVS=yu,tf._shaders.EllipsoidSurfaceAppearanceFS=Cu,tf._shaders.EllipsoidSurfaceAppearanceVS=bu,tf._shaders.PerInstanceColorAppearanceFS=Su,tf._shaders.PerInstanceColorAppearanceVS=wu,tf._shaders.PerInstanceFlatColorAppearanceFS=Tu,tf._shaders.PerInstanceFlatColorAppearanceVS=Au,tf._shaders.PolylineColorAppearanceVS=Eu,tf._shaders.PolylineMaterialAppearanceVS=xu,tf._shaders.TexturedMaterialAppearanceFS=Pu,tf._shaders.TexturedMaterialAppearanceVS=Du,tf._shaders.BillboardCollectionFS=Iu,tf._shaders.BillboardCollectionVS=Ou,tf._shaders.BrdfLutGeneratorFS=Mu,tf._shaders.degreesPerRadian=Ru,tf._shaders.depthRange=Nu,tf._shaders.epsilon1=Lu,tf._shaders.epsilon2=ku,tf._shaders.epsilon3=Fu,tf._shaders.epsilon4=Bu,tf._shaders.epsilon5=Uu,tf._shaders.epsilon6=Vu,tf._shaders.epsilon7=zu,tf._shaders.infinity=Gu,tf._shaders.maxClippingPlanes=Hu,tf._shaders.oneOverPi=Wu,tf._shaders.oneOverTwoPi=ju,tf._shaders.passCesium3DTile=qu,tf._shaders.passCesium3DTileClassification=Yu,tf._shaders.passCesium3DTileClassificationIgnoreShow=Xu,tf._shaders.passCompute=Qu,tf._shaders.passEnvironment=Zu,tf._shaders.passGlobe=Ku,tf._shaders.passOpaque=Ju,tf._shaders.passOverlay=$u,tf._shaders.passTerrainClassification=ec,tf._shaders.passTranslucent=tc,tf._shaders.pi=rc,tf._shaders.piOverFour=ic,tf._shaders.piOverSix=nc,tf._shaders.piOverThree=oc,tf._shaders.piOverTwo=ac,tf._shaders.radiansPerDegree=sc,tf._shaders.sceneMode2D=lc,tf._shaders.sceneMode3D=uc,tf._shaders.sceneModeColumbusView=cc,tf._shaders.sceneModeMorphing=dc,tf._shaders.solarRadius=hc,tf._shaders.threePiOver2=pc,tf._shaders.twoPi=fc,tf._shaders.webMercatorMaxLatitude=mc,tf._shaders.CzmBuiltins=gc,tf._shaders.alphaWeight=_c,tf._shaders.antialias=vc,tf._shaders.cascadeColor=yc,tf._shaders.cascadeDistance=Cc,tf._shaders.cascadeMatrix=bc,tf._shaders.cascadeWeights=Sc,tf._shaders.columbusViewMorph=wc,tf._shaders.computePosition=Tc,tf._shaders.cosineAndSine=Ac,tf._shaders.decompressTextureCoordinates=Ec,tf._shaders.discardIfClippedWithIntersect=xc,tf._shaders.discardIfClippedWithUnion=Pc,tf._shaders.eastNorthUpToEyeCoordinates=Dc,tf._shaders.ellipsoidContainsPoint=Ic,tf._shaders.ellipsoidNew=Oc,tf._shaders.ellipsoidWgs84TextureCoordinates=Mc,tf._shaders.equalsEpsilon=Rc,tf._shaders.eyeOffset=Nc,tf._shaders.eyeToWindowCoordinates=Lc,tf._shaders.fog=kc,tf._shaders.geodeticSurfaceNormal=Fc,tf._shaders.getDefaultMaterial=Bc,tf._shaders.getLambertDiffuse=Uc,tf._shaders.getSpecular=Vc,tf._shaders.getWaterNoise=zc,tf._shaders.getWgs84EllipsoidEC=Gc,tf._shaders.HSBToRGB=Hc,tf._shaders.HSLToRGB=Wc,tf._shaders.hue=jc,tf._shaders.isEmpty=qc,tf._shaders.isFull=Yc,tf._shaders.latitudeToWebMercatorFraction=Xc,tf._shaders.luminance=Qc,tf._shaders.metersPerPixel=Zc,tf._shaders.modelToWindowCoordinates=Kc,tf._shaders.multiplyWithColorBalance=Jc,tf._shaders.nearFarScalar=$c,tf._shaders.octDecode=ed,tf._shaders.packDepth=td,tf._shaders.phong=rd,tf._shaders.pointAlongRay=id,tf._shaders.rayEllipsoidIntersectionInterval=nd,tf._shaders.RGBToHSB=od,tf._shaders.RGBToHSL=ad,tf._shaders.RGBToXYZ=sd,tf._shaders.saturation=ld,tf._shaders.shadowDepthCompare=ud,tf._shaders.shadowVisibility=cd,tf._shaders.signNotZero=dd,tf._shaders.tangentToEyeSpaceMatrix=hd,tf._shaders.translateRelativeToEye=pd,tf._shaders.translucentPhong=fd,tf._shaders.transpose=md,tf._shaders.unpackDepth=gd,tf._shaders.windowToEyeCoordinates=_d,tf._shaders.XYZToRGB=vd,tf._shaders.depthRangeStruct=yd,tf._shaders.ellipsoid=Cd,tf._shaders.material=bd,tf._shaders.materialInput=Sd,tf._shaders.ray=wd,tf._shaders.raySegment=Td,tf._shaders.shadowParameters=Ad,tf._shaders.CompositeOITFS=Ed,tf._shaders.DepthPlaneFS=xd,tf._shaders.DepthPlaneVS=Pd,tf._shaders.EllipsoidFS=Dd,tf._shaders.EllipsoidVS=Id,tf._shaders.GlobeFS=Od,tf._shaders.GlobeVS=Md,tf._shaders.GroundAtmosphere=Rd,tf._shaders.BumpMapMaterial=Nd,tf._shaders.CheckerboardMaterial=Ld,tf._shaders.DotMaterial=kd,tf._shaders.ElevationContourMaterial=Fd,tf._shaders.ElevationRampMaterial=Bd,tf._shaders.FadeMaterial=Ud,tf._shaders.GridMaterial=Vd,tf._shaders.NormalMapMaterial=zd,tf._shaders.PolylineArrowMaterial=Gd,tf._shaders.PolylineDashMaterial=Hd,tf._shaders.PolylineGlowMaterial=Wd,tf._shaders.PolylineOutlineMaterial=jd,tf._shaders.RimLightingMaterial=qd,tf._shaders.SlopeRampMaterial=Yd,tf._shaders.StripeMaterial=Xd,tf._shaders.Water=Qd,tf._shaders.PointPrimitiveCollectionFS=Zd,tf._shaders.PointPrimitiveCollectionVS=Kd,tf._shaders.PolylineCommon=Jd,tf._shaders.PolylineFS=$d,tf._shaders.PolylineVS=eh,tf._shaders.AdditiveBlend=th,tf._shaders.BrightPass=rh,tf._shaders.FXAA=ih,tf._shaders.GaussianBlur1D=nh,tf._shaders.PassThrough=oh,tf._shaders.ReprojectWebMercatorFS=ah,tf._shaders.ReprojectWebMercatorVS=sh,tf._shaders.ShadowVolumeFS=lh,tf._shaders.ShadowVolumeVS=uh,tf._shaders.SkyAtmosphereFS=ch,tf._shaders.SkyAtmosphereVS=dh,tf._shaders.SkyBoxFS=hh,tf._shaders.SkyBoxVS=ph,tf._shaders.SunFS=fh,tf._shaders.SunTextureFS=mh,tf._shaders.SunVS=gh,tf._shaders.ViewportQuadFS=_h,tf._shaders.ViewportQuadVS=vh,tf.Autolinker=yh,tf.crunch=Ch,tf["earcut-2.1.1"]=bh,tf.addDefaults=Sh,tf.addExtensionsRequired=wh,tf.addExtensionsUsed=Th,tf.addPipelineExtras=Ah,tf.addToArray=Eh,tf.byteLengthForComponentType=xh,tf.findAccessorMinMax=Ph,tf.ForEach=Dh,tf.getAccessorByteStride=Ih,tf.getJointCountForMaterials=Oh,tf.glslTypeToWebGLConstant=Mh,tf.numberOfComponentsForType=Rh,tf.parseBinaryGltf=Nh,tf.processModelMaterialsCommon=Lh,tf.processPbrMetallicRoughness=kh,tf.removeExtensionsRequired=Fh,tf.removeExtensionsUsed=Bh,tf.removePipelineExtras=Uh,tf.techniqueParameterForSemantic=Vh,tf.updateVersion=zh,tf.webGLConstantToGlslType=Gh,tf["google-earth-dbroot-parser"]=Hh,tf.jsep=Wh,tf.kdbush=jh,tf["knockout-3.4.2"]=qh,tf["knockout-es5"]=Yh,tf.knockout=Xh,tf.measureText=Qh,tf["mersenne-twister"]=Zh,tf.NoSleep=Kh,tf.pako_inflate=Jh,tf["protobuf-minimal"]=$h,tf.FXAA3_11=ep,tf.sprintf=tp,tf.topojson=rp,tf.Tween=ip,tf.Uri=np,tf.when=op,tf.zip=ap,tf.Animation=sp,tf.AnimationViewModel=lp,tf.BaseLayerPicker=up,tf.BaseLayerPickerViewModel=cp,tf.createDefaultImageryProviderViewModels=dp,tf.createDefaultTerrainProviderViewModels=hp,tf.ProviderViewModel=pp,tf.Cesium3DTilesInspector=fp,tf.Cesium3DTilesInspectorViewModel=mp,tf.CesiumInspector=gp,tf.CesiumInspectorViewModel=_p,tf.CesiumWidget=vp,tf.ClockViewModel=yp,tf.Command=Cp,tf.createCommand=bp,tf.FullscreenButton=Sp,tf.FullscreenButtonViewModel=wp,tf.Geocoder=Tp,tf.GeocoderViewModel=Ap,tf.getElement=Ep,tf.HomeButton=xp,tf.HomeButtonViewModel=Pp,tf.InfoBox=Dp,tf.InfoBoxViewModel=Ip,tf.NavigationHelpButton=Op,tf.NavigationHelpButtonViewModel=Mp,tf.PerformanceWatchdog=Rp,tf.PerformanceWatchdogViewModel=Np,tf.ProjectionPicker=Lp,tf.ProjectionPickerViewModel=kp,tf.SceneModePicker=Fp,tf.SceneModePickerViewModel=Bp,tf.SelectionIndicator=Up,tf.SelectionIndicatorViewModel=Vp,tf.subscribeAndEvaluate=zp,tf.SvgPathBindingHandler=Gp,tf.Timeline=Hp,tf.TimelineHighlightRange=Wp,tf.TimelineTrack=jp,tf.ToggleButtonViewModel=qp,tf.Viewer=Yp,tf.viewerCesium3DTilesInspectorMixin=Xp,tf.viewerCesiumInspectorMixin=Qp,tf.viewerDragDropMixin=Zp,tf.viewerPerformanceWatchdogMixin=Kp,tf.VRButton=Jp,tf.VRButtonViewModel=$p,tf.createTaskProcessorWorker=ef,tf}),require(["Cesium"],function(e){"use strict";("undefined"!=typeof window?window:"undefined"!=typeof self?self:{}).Cesium=e},void 0,!0)}(); \ No newline at end of file +!function(){var requirejs,require,define;!function(e){function t(e,t){return v.call(e,t)}function r(e,t){var r,i,n,o,a,s,l,u,c,d,h,p,f=t&&t.split("/"),m=g.map,_=m&&m["*"]||{};if(e){for(e=e.split("/"),a=e.length-1,g.nodeIdCompat&&b.test(e[a])&&(e[a]=e[a].replace(b,"")),"."===e[0].charAt(0)&&f&&(p=f.slice(0,f.length-1),e=p.concat(e)),c=0;c<e.length;c++)if("."===(h=e[c]))e.splice(c,1),c-=1;else if(".."===h){if(0===c||1===c&&".."===e[2]||".."===e[c-1])continue;c>0&&(e.splice(c-1,2),c-=2)}e=e.join("/")}if((f||_)&&m){for(r=e.split("/"),c=r.length;c>0;c-=1){if(i=r.slice(0,c).join("/"),f)for(d=f.length;d>0;d-=1)if((n=m[f.slice(0,d).join("/")])&&(n=n[i])){o=n,s=c;break}if(o)break;!l&&_&&_[i]&&(l=_[i],u=c)}!o&&l&&(o=l,s=u),o&&(r.splice(0,s,o),e=r.join("/"))}return e}function i(t,r){return function(){var i=y.call(arguments,0);return"string"!=typeof i[0]&&1===i.length&&i.push(null),d.apply(e,i.concat([t,r]))}}function n(e){return function(t){return r(t,e)}}function o(e){return function(t){f[e]=t}}function a(r){if(t(m,r)){var i=m[r];delete m[r],_[r]=!0,c.apply(e,i)}if(!t(f,r)&&!t(_,r))throw new Error("No "+r);return f[r]}function s(e){var t,r=e?e.indexOf("!"):-1;return r>-1&&(t=e.substring(0,r),e=e.substring(r+1,e.length)),[t,e]}function l(e){return e?s(e):[]}function u(e){return function(){return g&&g.config&&g.config[e]||{}}}var c,d,h,p,f={},m={},g={},_={},v=Object.prototype.hasOwnProperty,y=[].slice,b=/\.js$/;h=function(e,t){var i,o=s(e),l=o[0],u=t[1];return e=o[1],l&&(l=r(l,u),i=a(l)),l?e=i&&i.normalize?i.normalize(e,n(u)):r(e,u):(e=r(e,u),o=s(e),l=o[0],e=o[1],l&&(i=a(l))),{f:l?l+"!"+e:e,n:e,pr:l,p:i}},p={require:function(e){return i(e)},exports:function(e){var t=f[e];return void 0!==t?t:f[e]={}},module:function(e){return{id:e,uri:"",exports:f[e],config:u(e)}}},c=function(r,n,s,u){var c,d,g,v,y,b,C,S=[],w=typeof s;if(u=u||r,b=l(u),"undefined"===w||"function"===w){for(n=!n.length&&s.length?["require","exports","module"]:n,y=0;y<n.length;y+=1)if(v=h(n[y],b),"require"===(d=v.f))S[y]=p.require(r);else if("exports"===d)S[y]=p.exports(r),C=!0;else if("module"===d)c=S[y]=p.module(r);else if(t(f,d)||t(m,d)||t(_,d))S[y]=a(d);else{if(!v.p)throw new Error(r+" missing "+d);v.p.load(v.n,i(u,!0),o(d),{}),S[y]=f[d]}g=s?s.apply(f[r],S):void 0,r&&(c&&c.exports!==e&&c.exports!==f[r]?f[r]=c.exports:g===e&&C||(f[r]=g))}else r&&(f[r]=s)},requirejs=require=d=function(t,r,i,n,o){if("string"==typeof t)return p[t]?p[t](r):a(h(t,l(r)).f);if(!t.splice){if(g=t,g.deps&&d(g.deps,g.callback),!r)return;r.splice?(t=r,r=i,i=null):t=e}return r=r||function(){},"function"==typeof i&&(i=n,n=o),n?c(e,t,r,i):setTimeout(function(){c(e,t,r,i)},4),d},d.config=function(e){return d(e)},requirejs._defined=f,define=function(e,r,i){if("string"!=typeof e)throw new Error("See almond README: incorrect module build, no module name");r.splice||(i=r,r=[]),t(f,e)||t(m,e)||(m[e]=[e,r,i])},define.amd={jQuery:!0}}(),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function i(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var n={};return n.typeOf={},n.defined=function(i,n){if(!e(n))throw new t(r(i))},n.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(i(typeof r,"function",e))},n.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(i(typeof r,"string",e))},n.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(i(typeof r,"number",e))},n.typeOf.number.lessThan=function(e,r,i){if(n.typeOf.number(e,r),r>=i)throw new t("Expected "+e+" to be less than "+i+", actual value was "+r)},n.typeOf.number.lessThanOrEquals=function(e,r,i){if(n.typeOf.number(e,r),r>i)throw new t("Expected "+e+" to be less than or equal to "+i+", actual value was "+r)},n.typeOf.number.greaterThan=function(e,r,i){if(n.typeOf.number(e,r),r<=i)throw new t("Expected "+e+" to be greater than "+i+", actual value was "+r)},n.typeOf.number.greaterThanOrEquals=function(e,r,i){if(n.typeOf.number(e,r),r<i)throw new t("Expected "+e+" to be greater than or equal to"+i+", actual value was "+r)},n.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(i(typeof r,"object",e))},n.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(i(typeof r,"boolean",e))},n.typeOf.number.equals=function(e,r,i,o){if(n.typeOf.number(e,i),n.typeOf.number(r,o),i!==o)throw new t(e+" must be equal to "+r+", the actual values are "+i+" and "+o)},n}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("Core/arrayFill",["./Check","./defaultValue","./defined"],function(e,t,r){"use strict";function i(e,r,i,n){if("function"==typeof e.fill)return e.fill(r,i,n);for(var o=e.length>>>0,a=t(i,0),s=a<0?Math.max(o+a,0):Math.min(a,o),l=t(n,o),u=l<0?Math.max(o+l,0):Math.min(l,o);s<u;)e[s]=r,s++;return e}return i}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,i){"use strict";var n={};n.EPSILON1=.1,n.EPSILON2=.01,n.EPSILON3=.001,n.EPSILON4=1e-4,n.EPSILON5=1e-5,n.EPSILON6=1e-6,n.EPSILON7=1e-7,n.EPSILON8=1e-8,n.EPSILON9=1e-9,n.EPSILON10=1e-10,n.EPSILON11=1e-11,n.EPSILON12=1e-12,n.EPSILON13=1e-13,n.EPSILON14=1e-14,n.EPSILON15=1e-15,n.EPSILON16=1e-16,n.EPSILON17=1e-17,n.EPSILON18=1e-18,n.EPSILON19=1e-19,n.EPSILON20=1e-20,n.GRAVITATIONALPARAMETER=3986004418e5,n.SOLAR_RADIUS=6955e5,n.LUNAR_RADIUS=1737400,n.SIXTY_FOUR_KILOBYTES=65536,n.sign=function(e){return e>0?1:e<0?-1:0},n.signNotZero=function(e){return e<0?-1:1},n.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*n.clamp(e,-1,1)+.5)*r)},n.fromSNorm=function(e,r){return r=t(r,255),n.clamp(e,0,r)/r*2-1},n.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},n.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},n.lerp=function(e,t,r){return(1-r)*e+r*t},n.PI=Math.PI,n.ONE_OVER_PI=1/Math.PI,n.PI_OVER_TWO=.5*Math.PI,n.PI_OVER_THREE=Math.PI/3,n.PI_OVER_FOUR=Math.PI/4,n.PI_OVER_SIX=Math.PI/6,n.THREE_PI_OVER_TWO=3*Math.PI*.5,n.TWO_PI=2*Math.PI,n.ONE_OVER_TWO_PI=1/(2*Math.PI),n.RADIANS_PER_DEGREE=Math.PI/180,n.DEGREES_PER_RADIAN=180/Math.PI,n.RADIANS_PER_ARCSECOND=n.RADIANS_PER_DEGREE/3600,n.toRadians=function(e){return e*n.RADIANS_PER_DEGREE},n.toDegrees=function(e){return e*n.DEGREES_PER_RADIAN},n.convertLongitudeRange=function(e){var t=n.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},n.clampToLatitudeRange=function(e){return n.clamp(e,-1*n.PI_OVER_TWO,n.PI_OVER_TWO)},n.negativePiToPi=function(e){return n.zeroToTwoPi(e+n.PI)-n.PI},n.zeroToTwoPi=function(e){var t=n.mod(e,n.TWO_PI);return Math.abs(t)<n.EPSILON14&&Math.abs(e)>n.EPSILON14?n.TWO_PI:t},n.mod=function(e,t){return(e%t+t)%t},n.equalsEpsilon=function(e,r,i,n){n=t(n,i);var o=Math.abs(e-r);return o<=n||o<=i*Math.max(Math.abs(e),Math.abs(r))};var o=[1];n.factorial=function(e){var t=o.length;if(e>=t)for(var r=o[t-1],i=t;i<=e;i++)o.push(r*i);return o[e]},n.incrementWrap=function(e,r,i){return i=t(i,0),++e,e>r&&(e=i),e},n.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},n.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},n.clamp=function(e,t,r){return e<t?t:e>r?r:e};var a=new e;return n.setRandomNumberSeed=function(t){a=new e(t)},n.nextRandomNumber=function(){return a.random()},n.randomBetween=function(e,t){return n.nextRandomNumber()*(t-e)+e},n.acosClamped=function(e){return Math.acos(n.clamp(e,-1,1))},n.asinClamped=function(e){return Math.asin(n.clamp(e,-1,1))},n.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},n.logBase=function(e,t){return Math.log(e)/Math.log(t)},n.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},n}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,r,i){"use strict";function n(e,i,n){if(r(e)){n=t(n,!1);var a=e.length;if(a<2)return e;var s,l,u;for(s=1;s<a&&(l=e[s-1],u=e[s],!i(l,u,o));++s);if(s===a)return n&&i(e[0],e[e.length-1],o)?e.slice(1):e;for(var c=e.slice(0,s);s<a;++s)u=e[s],i(l,u,o)||(c.push(u),l=u);return n&&c.length>1&&i(c[0],c[c.length-1],o)&&c.shift(),c}}var o=i.EPSILON10;return n}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,i={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},n={};return t(n,{element:{get:function(){if(n.supportsFullscreen())return document[i.fullscreenElement]}},changeEventName:{get:function(){if(n.supportsFullscreen())return i.fullscreenchange}},errorEventName:{get:function(){if(n.supportsFullscreen())return i.fullscreenerror}},enabled:{get:function(){if(n.supportsFullscreen())return document[i.fullscreenEnabled]}},fullscreen:{get:function(){if(n.supportsFullscreen())return null!==n.element}}}),n.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return i.requestFullscreen="requestFullscreen",i.exitFullscreen="exitFullscreen",i.fullscreenEnabled="fullscreenEnabled",i.fullscreenElement="fullscreenElement",i.fullscreenchange="fullscreenchange",i.fullscreenerror="fullscreenerror",r=!0;for(var n,o=["webkit","moz","o","ms","khtml"],a=0,s=o.length;a<s;++a){var l=o[a];n=l+"RequestFullscreen","function"==typeof t[n]?(i.requestFullscreen=n,r=!0):(n=l+"RequestFullScreen","function"==typeof t[n]&&(i.requestFullscreen=n,r=!0)),n=l+"ExitFullscreen","function"==typeof document[n]?i.exitFullscreen=n:(n=l+"CancelFullScreen","function"==typeof document[n]&&(i.exitFullscreen=n)),n=l+"FullscreenEnabled",void 0!==document[n]?i.fullscreenEnabled=n:(n=l+"FullScreenEnabled",void 0!==document[n]&&(i.fullscreenEnabled=n)),n=l+"FullscreenElement",void 0!==document[n]?i.fullscreenElement=n:(n=l+"FullScreenElement",void 0!==document[n]&&(i.fullscreenElement=n)),n=l+"fullscreenchange",void 0!==document["on"+n]&&("ms"===l&&(n="MSFullscreenChange"),i.fullscreenchange=n),n=l+"fullscreenerror",void 0!==document["on"+n]&&("ms"===l&&(n="MSFullscreenError"),i.fullscreenerror=n)}return r},n.requestFullscreen=function(e,t){n.supportsFullscreen()&&e[i.requestFullscreen]({vrDisplay:t})},n.exitFullscreen=function(){n.supportsFullscreen()&&document[i.exitFullscreen]()},n}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function i(e){for(var t=e.split("."),r=0,i=t.length;r<i;++r)t[r]=parseInt(t[r],10);return t}function n(){if(!t(C)&&(C=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(b.userAgent);null!==e&&(C=!0,S=i(e[1]))}return C}function o(){return n()&&S}function a(){if(!t(w)&&(w=!1,!n()&&!h()&&/ Safari\/[\.0-9]+/.test(b.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(b.userAgent);null!==e&&(w=!0,T=i(e[1]))}return w}function s(){return a()&&T}function l(){if(!t(E)){E=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(b.userAgent);null!==e&&(E=!0,A=i(e[1]),A.isNightly=!!e[2])}return E}function u(){return l()&&A}function c(){if(!t(x)){x=!1;var e;"Microsoft Internet Explorer"===b.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(b.userAgent))&&(x=!0,P=i(e[1])):"Netscape"===b.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(b.userAgent))&&(x=!0,P=i(e[1]))}return x}function d(){return c()&&P}function h(){if(!t(D)){D=!1;var e=/ Edge\/([\.0-9]+)/.exec(b.userAgent);null!==e&&(D=!0,I=i(e[1]))}return D}function p(){return h()&&I}function f(){if(!t(O)){O=!1;var e=/Firefox\/([\.0-9]+)/.exec(b.userAgent);null!==e&&(O=!0,M=i(e[1]))}return O}function m(){return t(R)||(R=/Windows/i.test(b.appVersion)),R}function g(){return f()&&M}function _(){return t(L)||(L="undefined"!=typeof PointerEvent&&(!t(b.pointerEnabled)||b.pointerEnabled)),L}function v(){if(!t(k)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;k=t(r)&&""!==r,k&&(N=r)}return k}function y(){return v()?N:void 0}var b;b="undefined"!=typeof navigator?navigator:{};var C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F={isChrome:n,chromeVersion:o,isSafari:a,safariVersion:s,isWebkit:l,webkitVersion:u,isInternetExplorer:c,internetExplorerVersion:d,isEdge:h,edgeVersion:p,isFirefox:f,firefoxVersion:g,isWindows:m,hardwareConcurrency:e(b.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:v,imageRenderingValue:y};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/arraySlice",["./Check","./defaultValue","./defined","./FeatureDetection"],function(e,t,r,i){"use strict";function n(e,t,r){return o(e,t,r)}var o=function(e,t,r){return e.slice(t,r)};if(i.supportsTypedArrays()){if("function"!=typeof new Uint8Array(1).slice){var a=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];o=function(e,t,r){if("function"==typeof e.slice)return e.slice(t,r);for(var i=Array.prototype.slice.call(e,t,r),n=a.length,o=0;o<n;++o)if(e instanceof a[o]){i=new a[o](i);break}return i}}}return n}),define("Core/AssociativeArray",["./defined","./defineProperties","./DeveloperError"],function(e,t,r){"use strict";function i(){this._array=[],this._hash={}}return t(i.prototype,{length:{get:function(){return this._array.length}},values:{get:function(){return this._array}}}),i.prototype.contains=function(t){return e(this._hash[t])},i.prototype.set=function(e,t){t!==this._hash[e]&&(this.remove(e),this._hash[e]=t,this._array.push(t))},i.prototype.get=function(e){return this._hash[e]},i.prototype.remove=function(t){var r=this._hash[t],i=e(r);if(i){var n=this._array;n.splice(n.indexOf(r),1),delete this._hash[t]}return i},i.prototype.removeAll=function(){var e=this._array;e.length>0&&(this._hash={},e.length=0)},i}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,r){this.x=t(e,0),this.y=t(r,0)}a.fromElements=function(e,t,i){return r(i)?(i.x=e,i.y=t,i):new a(e,t)},a.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new a(e.x,e.y)},a.fromCartesian3=a.clone,a.fromCartesian4=a.clone,a.packedLength=2,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.x,r[i]=e.y,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.x=e[i++],n.y=e[i],n},a.packArray=function(e,t){var i=e.length;r(t)?t.length=2*i:t=new Array(2*i);for(var n=0;n<i;++n)a.pack(e[n],t,2*n);return t},a.unpackArray=function(e,t){var i=e.length;r(t)?t.length=i/2:t=new Array(i/2);for(var n=0;n<i;n+=2){var o=n/2;t[o]=a.unpack(e,n,t[o])}return t},a.fromArray=a.unpack,a.maximumComponent=function(e){return Math.max(e.x,e.y)},a.minimumComponent=function(e){return Math.min(e.x,e.y)},a.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},a.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},a.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},a.magnitude=function(e){return Math.sqrt(a.magnitudeSquared(e))};var s=new a;a.distance=function(e,t){return a.subtract(e,t,s),a.magnitude(s)},a.distanceSquared=function(e,t){return a.subtract(e,t,s),a.magnitudeSquared(s)},a.normalize=function(e,t){var r=a.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},a.dot=function(e,t){return e.x*t.x+e.y*t.y},a.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},a.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},a.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},a.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},a.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},a.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},a.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},a.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var l=new a;a.lerp=function(e,t,r,i){return a.multiplyByScalar(t,r,l),i=a.multiplyByScalar(e,1-r,i),a.add(l,i,i)};var u=new a,c=new a;a.angleBetween=function(e,t){return a.normalize(e,u),a.normalize(t,c),o.acosClamped(a.dot(u,c))};var d=new a;return a.mostOrthogonalAxis=function(e,t){var r=a.normalize(e,d);return a.abs(r,r),t=r.x<=r.y?a.clone(a.UNIT_X,t):a.clone(a.UNIT_Y,t)},a.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},a.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},a.equalsEpsilon=function(e,t,i,n){return e===t||r(e)&&r(t)&&o.equalsEpsilon(e.x,t.x,i,n)&&o.equalsEpsilon(e.y,t.y,i,n)},a.ZERO=n(new a(0,0)),a.UNIT_X=n(new a(1,0)),a.UNIT_Y=n(new a(0,1)),a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a.prototype.equalsEpsilon=function(e,t,r){return a.equalsEpsilon(this,e,t,r)},a.prototype.toString=function(){return"("+this.x+", "+this.y+")"},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,r,i){this.x=t(e,0),this.y=t(r,0),this.z=t(i,0)}a.fromSpherical=function(e,i){r(i)||(i=new a);var n=e.clock,o=e.cone,s=t(e.magnitude,1),l=s*Math.sin(o);return i.x=l*Math.cos(n),i.y=l*Math.sin(n),i.z=s*Math.cos(o),i},a.fromElements=function(e,t,i,n){return r(n)?(n.x=e,n.y=t,n.z=i,n):new a(e,t,i)},a.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new a(e.x,e.y,e.z)},a.fromCartesian4=a.clone,a.packedLength=3,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.x,r[i++]=e.y,r[i]=e.z,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.x=e[i++],n.y=e[i++],n.z=e[i],n},a.packArray=function(e,t){var i=e.length;r(t)?t.length=3*i:t=new Array(3*i);for(var n=0;n<i;++n)a.pack(e[n],t,3*n);return t},a.unpackArray=function(e,t){var i=e.length;r(t)?t.length=i/3:t=new Array(i/3);for(var n=0;n<i;n+=3){var o=n/3;t[o]=a.unpack(e,n,t[o])}return t},a.fromArray=a.unpack,a.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},a.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},a.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},a.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},a.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},a.magnitude=function(e){return Math.sqrt(a.magnitudeSquared(e))};var s=new a;a.distance=function(e,t){return a.subtract(e,t,s),a.magnitude(s)},a.distanceSquared=function(e,t){return a.subtract(e,t,s),a.magnitudeSquared(s)},a.normalize=function(e,t){var r=a.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},a.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},a.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},a.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},a.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},a.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},a.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},a.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},a.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},a.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var l=new a;a.lerp=function(e,t,r,i){return a.multiplyByScalar(t,r,l),i=a.multiplyByScalar(e,1-r,i),a.add(l,i,i)};var u=new a,c=new a;a.angleBetween=function(e,t){a.normalize(e,u),a.normalize(t,c);var r=a.dot(u,c),i=a.magnitude(a.cross(u,c,u));return Math.atan2(i,r)};var d=new a;a.mostOrthogonalAxis=function(e,t){var r=a.normalize(e,d);return a.abs(r,r),t=r.x<=r.y?r.x<=r.z?a.clone(a.UNIT_X,t):a.clone(a.UNIT_Z,t):r.y<=r.z?a.clone(a.UNIT_Y,t):a.clone(a.UNIT_Z,t)},a.projectVector=function(e,t,r){var i=a.dot(e,t)/a.dot(t,t);return a.multiplyByScalar(t,i,r)},a.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},a.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},a.equalsEpsilon=function(e,t,i,n){return e===t||r(e)&&r(t)&&o.equalsEpsilon(e.x,t.x,i,n)&&o.equalsEpsilon(e.y,t.y,i,n)&&o.equalsEpsilon(e.z,t.z,i,n)},a.cross=function(e,t,r){var i=e.x,n=e.y,o=e.z,a=t.x,s=t.y,l=t.z,u=n*l-o*s,c=o*a-i*l,d=i*s-n*a;return r.x=u,r.y=c,r.z=d,r},a.fromDegrees=function(e,t,r,i,n){return e=o.toRadians(e),t=o.toRadians(t),a.fromRadians(e,t,r,i,n)};var h=new a,p=new a,f=new a(40680631590769,40680631590769,40408299984661.445);return a.fromRadians=function(e,i,n,o,s){n=t(n,0);var l=r(o)?o.radiiSquared:f,u=Math.cos(i);h.x=u*Math.cos(e),h.y=u*Math.sin(e),h.z=Math.sin(i),h=a.normalize(h,h),a.multiplyComponents(l,h,p);var c=Math.sqrt(a.dot(h,p));return p=a.divideByScalar(p,c,p),h=a.multiplyByScalar(h,n,h),r(s)||(s=new a),a.add(p,h,s)},a.fromDegreesArray=function(e,t,i){var n=e.length;r(i)?i.length=n/2:i=new Array(n/2);for(var o=0;o<n;o+=2){var s=e[o],l=e[o+1],u=o/2;i[u]=a.fromDegrees(s,l,0,t,i[u])}return i},a.fromRadiansArray=function(e,t,i){var n=e.length;r(i)?i.length=n/2:i=new Array(n/2);for(var o=0;o<n;o+=2){var s=e[o],l=e[o+1],u=o/2;i[u]=a.fromRadians(s,l,0,t,i[u])}return i},a.fromDegreesArrayHeights=function(e,t,i){var n=e.length;r(i)?i.length=n/3:i=new Array(n/3);for(var o=0;o<n;o+=3){var s=e[o],l=e[o+1],u=e[o+2],c=o/3;i[c]=a.fromDegrees(s,l,u,t,i[c])}return i},a.fromRadiansArrayHeights=function(e,t,i){var n=e.length;r(i)?i.length=n/3:i=new Array(n/3);for(var o=0;o<n;o+=3){var s=e[o],l=e[o+1],u=e[o+2],c=o/3;i[c]=a.fromRadians(s,l,u,t,i[c])}return i},a.ZERO=n(new a(0,0,0)),a.UNIT_X=n(new a(1,0,0)),a.UNIT_Y=n(new a(0,1,0)),a.UNIT_Z=n(new a(0,0,1)),a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a.prototype.equalsEpsilon=function(e,t,r){return a.equalsEpsilon(this,e,t,r)},a.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},a}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,i,n,o){"use strict";function a(e){return e>>1^-(1&e)}var s={};s.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var i=r.x,n=r.y;r.x=(1-Math.abs(n))*o.signNotZero(i),r.y=(1-Math.abs(i))*o.signNotZero(n)}return r.x=o.toSNorm(r.x,t),r.y=o.toSNorm(r.y,t),r},s.octEncode=function(e,t){return s.octEncodeInRange(e,255,t)},s.octDecodeInRange=function(e,r,i,n){if(n.x=o.fromSNorm(e,i),n.y=o.fromSNorm(r,i),n.z=1-(Math.abs(n.x)+Math.abs(n.y)),n.z<0){var a=n.x;n.x=(1-Math.abs(n.y))*o.signNotZero(a),n.y=(1-Math.abs(a))*o.signNotZero(n.y)}return t.normalize(n,n)},s.octDecode=function(e,t,r){return s.octDecodeInRange(e,t,255,r)},s.octPackFloat=function(e){return 256*e.x+e.y};var l=new e;return s.octEncodeFloat=function(e){return s.octEncode(e,l),s.octPackFloat(l)},s.octDecodeFloat=function(e,t){var r=e/256,i=Math.floor(r),n=256*(r-i);return s.octDecode(i,n,t)},s.octPack=function(e,t,r,i){var n=s.octEncodeFloat(e),o=s.octEncodeFloat(t),a=s.octEncode(r,l);return i.x=65536*a.x+n,i.y=65536*a.y+o,i},s.octUnpack=function(e,t,r,i){var n=e.x/65536,o=Math.floor(n),a=65536*(n-o);n=e.y/65536;var l=Math.floor(n),u=65536*(n-l);s.octDecodeFloat(a,t),s.octDecodeFloat(u,r),s.octDecode(o,l,i)},s.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},s.decompressTextureCoordinates=function(e,t){var r=e/4096,i=Math.floor(r);return t.x=i/4095,t.y=(e-4096*i)/4095,t},s.zigZagDeltaDecode=function(e,t,r){for(var n=e.length,o=0,s=0,l=0,u=0;u<n;++u)o+=a(e[u]),s+=a(t[u]),e[u]=o,t[u]=s,i(r)&&(l+=a(r[u]),r[u]=l)},s}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,r,i,n){"use strict";function o(t,n,o){this.minimum=e.clone(r(t,e.ZERO)),this.maximum=e.clone(r(n,e.ZERO)),i(o)?o=e.clone(o):(o=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(o,.5,o)),this.center=o}o.fromPoints=function(t,r){if(i(r)||(r=new o),!i(t)||0===t.length)return r.minimum=e.clone(e.ZERO,r.minimum),r.maximum=e.clone(e.ZERO,r.maximum),r.center=e.clone(e.ZERO,r.center),r;for(var n=t[0].x,a=t[0].y,s=t[0].z,l=t[0].x,u=t[0].y,c=t[0].z,d=t.length,h=1;h<d;h++){var p=t[h],f=p.x,m=p.y,g=p.z;n=Math.min(f,n),l=Math.max(f,l),a=Math.min(m,a),u=Math.max(m,u),s=Math.min(g,s),c=Math.max(g,c)}var _=r.minimum;_.x=n,_.y=a,_.z=s;var v=r.maximum;v.x=l,v.y=u,v.z=c;var y=e.add(_,v,r.center);return e.multiplyByScalar(y,.5,y),r},o.clone=function(t,r){if(i(t))return i(r)?(r.minimum=e.clone(t.minimum,r.minimum),r.maximum=e.clone(t.maximum,r.maximum),r.center=e.clone(t.center,r.center),r):new o(t.minimum,t.maximum)},o.equals=function(t,r){return t===r||i(t)&&i(r)&&e.equals(t.center,r.center)&&e.equals(t.minimum,r.minimum)&&e.equals(t.maximum,r.maximum)};var a=new e;return o.intersectPlane=function(t,r){a=e.subtract(t.maximum,t.minimum,a);var i=e.multiplyByScalar(a,.5,a),o=r.normal,s=i.x*Math.abs(o.x)+i.y*Math.abs(o.y)+i.z*Math.abs(o.z),l=e.dot(t.center,o)+r.distance;return l-s>0?n.INSIDE:l+s<0?n.OUTSIDE:n.INTERSECTING},o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.intersectPlane=function(e){return o.intersectPlane(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,i){"use strict";function n(r,n,l,u,c){i(c)||(c=new t);var d,h,p,f,m,g,_,v;i(n.z)?(d=t.subtract(l,n,o),h=t.subtract(u,n,a),p=t.subtract(r,n,s),f=t.dot(d,d),m=t.dot(d,h),g=t.dot(d,p),_=t.dot(h,h),v=t.dot(h,p)):(d=e.subtract(l,n,o),h=e.subtract(u,n,a),p=e.subtract(r,n,s),f=e.dot(d,d),m=e.dot(d,h),g=e.dot(d,p),_=e.dot(h,h),v=e.dot(h,p));var y=1/(f*_-m*m);return c.y=(_*g-m*v)*y,c.z=(f*v-m*g)*y,c.x=1-c.y-c.z,c}var o=new t,a=new t,s=new t;return n}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var i,n,o=0,a=e.length-1;o<=a;)if(i=~~((o+a)/2),(n=r(e[i],t))<0)o=i+1;else{if(!(n>0))return i;a=i-1}return~(a+1)}return t}),define("Core/Credit",["./defaultValue","./defined","./defineProperties","./DeveloperError"],function(e,t,r,i){"use strict";function n(r){r=e(r,e.EMPTY_OBJECT);var i=r.text,n=r.imageUrl,s=r.link,l=e(r.showOnScreen,!1),u=t(s),c=t(n);t(i)||c||(i=s),this._text=i,this._imageUrl=n,this._link=s,this._hasLink=u,this._hasImage=c,this._showOnScreen=l;var d,h=JSON.stringify([i,n,s]);t(a[h])?d=a[h]:(d=o++,a[h]=d),this._id=d}var o=0,a={};return r(n.prototype,{text:{get:function(){return this._text}},imageUrl:{get:function(){return this._imageUrl}},link:{get:function(){return this._link}},id:{get:function(){return this._id}},showOnScreen:{get:function(){return this._showOnScreen}}}),n.prototype.hasImage=function(){return this._hasImage},n.prototype.hasLink=function(){return this._hasLink},n.equals=function(e,r){return e===r||t(e)&&t(r)&&e._id===r._id},n.prototype.equals=function(e){return n.equals(this,e)},n}),define("Core/BingMapsApi",["./Credit","./defined"],function(e,t){"use strict";var r={};r.defaultKey=void 0;var i,n=!1,o="This application is using Cesium's default Bing Maps key. Please create a new key for the application as soon as possible and prior to deployment by visiting https://www.bingmapsportal.com/, and provide your key to Cesium by setting the Cesium.BingMapsApi.defaultKey property before constructing the CesiumWidget or any other object that uses the Bing Maps API.";return r.getKey=function(e){return t(e)?e:t(r.defaultKey)?r.defaultKey:(n||(console.log(o),n=!0),"Ar9n20kTp-N8tEg3Dpx-Pgocmx3W0-GUnD_Bgt3h8g6pSeDL8yxByTVGHyMyjI2p")},r.getErrorCredit=function(n){if(!t(n)&&!t(r.defaultKey))return t(i)||(i=new e({text:o,showOnScreen:!0})),i},r}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,i){"use strict";function n(r,n,s,l,u){var c=r.x,d=r.y,h=r.z,p=n.x,f=n.y,m=n.z,g=c*c*p*p,_=d*d*f*f,v=h*h*m*m,y=g+_+v,b=Math.sqrt(1/y),C=e.multiplyByScalar(r,b,o);if(y<l)return isFinite(b)?e.clone(C,u):void 0;var S=s.x,w=s.y,T=s.z,E=a;E.x=C.x*S*2,E.y=C.y*w*2,E.z=C.z*T*2;var A,x,P,D,I,O,M,R,L,N,k,F=(1-b)*e.magnitude(r)/(.5*e.magnitude(E)),B=0;do{F-=B,P=1/(1+F*S),D=1/(1+F*w),I=1/(1+F*T),O=P*P,M=D*D,R=I*I,L=O*P,N=M*D,k=R*I,A=g*O+_*M+v*R-1,x=g*L*S+_*N*w+v*k*T;B=A/(-2*x)}while(Math.abs(A)>i.EPSILON12);return t(u)?(u.x=c*P,u.y=d*D,u.z=h*I,u):new e(c*P,d*D,h*I)}var o=new e,a=new e;return n}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,i,n,o,a){"use strict";function s(e,t,i){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(i,0)}s.fromRadians=function(e,t,n,o){return n=r(n,0),i(o)?(o.longitude=e,o.latitude=t,o.height=n,o):new s(e,t,n)},s.fromDegrees=function(e,t,r,i){return e=o.toRadians(e),t=o.toRadians(t),s.fromRadians(e,t,r,i)};var l=new e,u=new e,c=new e,d=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),p=o.EPSILON1;return s.fromCartesian=function(t,r,n){var f=i(r)?r.oneOverRadii:d,m=i(r)?r.oneOverRadiiSquared:h,g=i(r)?r._centerToleranceSquared:p,_=a(t,f,m,g,u);if(i(_)){var v=e.multiplyComponents(_,m,l);v=e.normalize(v,v);var y=e.subtract(t,_,c),b=Math.atan2(v.y,v.x),C=Math.asin(v.z),S=o.sign(e.dot(y,t))*e.magnitude(y);return i(n)?(n.longitude=b,n.latitude=C,n.height=S,n):new s(b,C,S)}},s.toCartesian=function(t,r,i){return e.fromRadians(t.longitude,t.latitude,t.height,r,i)}, +s.clone=function(e,t){if(i(e))return i(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new s(e.longitude,e.latitude,e.height)},s.equals=function(e,t){return e===t||i(e)&&i(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},s.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},s.ZERO=n(new s(0,0,0)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},s}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r,n,o){r=i(r,0),n=i(n,0),o=i(o,0),t._radii=new e(r,n,o),t._radiiSquared=new e(r*r,n*n,o*o),t._radiiToTheFourth=new e(r*r*r*r,n*n*n*n,o*o*o*o),t._oneOverRadii=new e(0===r?0:1/r,0===n?0:1/n,0===o?0:1/o),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===n?0:1/(n*n),0===o?0:1/(o*o)),t._minimumRadius=Math.min(r,n,o),t._maximumRadius=Math.max(r,n,o),t._centerToleranceSquared=l.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function d(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,r)}o(d.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),d.clone=function(t,r){if(n(t)){var i=t._radii;return n(r)?(e.clone(i,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new d(i.x,i.y,i.z)}},d.fromCartesian3=function(e,t){return n(t)||(t=new d),n(e)?(c(t,e.x,e.y,e.z),t):t},d.WGS84=s(new d(6378137,6378137,6356752.314245179)),d.UNIT_SPHERE=s(new d(1,1,1)),d.MOON=s(new d(l.LUNAR_RADIUS,l.LUNAR_RADIUS,l.LUNAR_RADIUS)),d.prototype.clone=function(e){return d.clone(this,e)},d.packedLength=e.packedLength,d.pack=function(t,r,n){return n=i(n,0),e.pack(t._radii,r,n),r},d.unpack=function(t,r,n){r=i(r,0);var o=e.unpack(t,r);return d.fromCartesian3(o,n)},d.prototype.geocentricSurfaceNormal=e.normalize,d.prototype.geodeticSurfaceNormalCartographic=function(t,r){var i=t.longitude,o=t.latitude,a=Math.cos(o),s=a*Math.cos(i),l=a*Math.sin(i),u=Math.sin(o);return n(r)||(r=new e),r.x=s,r.y=l,r.z=u,e.normalize(r,r)},d.prototype.geodeticSurfaceNormal=function(t,r){return n(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,p=new e;d.prototype.cartographicToCartesian=function(t,r){var i=h,o=p;this.geodeticSurfaceNormalCartographic(t,i),e.multiplyComponents(this._radiiSquared,i,o);var a=Math.sqrt(e.dot(i,o));return e.divideByScalar(o,a,o),e.multiplyByScalar(i,t.height,i),n(r)||(r=new e),e.add(o,i,r)},d.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;n(t)?t.length=r:t=new Array(r);for(var i=0;i<r;i++)t[i]=this.cartographicToCartesian(e[i],t[i]);return t};var f=new e,m=new e,g=new e;return d.prototype.cartesianToCartographic=function(r,i){var o=this.scaleToGeodeticSurface(r,m);if(n(o)){var a=this.geodeticSurfaceNormal(o,f),s=e.subtract(r,o,g),u=Math.atan2(a.y,a.x),c=Math.asin(a.z),d=l.sign(e.dot(s,r))*e.magnitude(s);return n(i)?(i.longitude=u,i.latitude=c,i.height=d,i):new t(u,c,d)}},d.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;n(t)?t.length=r:t=new Array(r);for(var i=0;i<r;++i)t[i]=this.cartesianToCartographic(e[i],t[i]);return t},d.prototype.scaleToGeodeticSurface=function(e,t){return u(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},d.prototype.scaleToGeocentricSurface=function(t,r){n(r)||(r=new e);var i=t.x,o=t.y,a=t.z,s=this._oneOverRadiiSquared,l=1/Math.sqrt(i*i*s.x+o*o*s.y+a*a*s.z);return e.multiplyByScalar(t,l,r)},d.prototype.transformPositionToScaledSpace=function(t,r){return n(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},d.prototype.transformPositionFromScaledSpace=function(t,r){return n(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},d.prototype.equals=function(t){return this===t||n(t)&&e.equals(this._radii,t._radii)},d.prototype.toString=function(){return this._radii.toString()},d.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,o){r=i(r,0);var a=this._squaredXOverSquaredZ;if(n(o)||(o=new e),o.x=0,o.y=0,o.z=t.z*(1-a),!(Math.abs(o.z)>=this._radii.z-r))return o},d}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,i,n){this.west=r(e,0),this.south=r(t,0),this.east=r(i,0),this.north=r(n,0)}n(l.prototype,{width:{get:function(){return l.computeWidth(this)}},height:{get:function(){return l.computeHeight(this)}}}),l.packedLength=4,l.pack=function(e,t,i){return i=r(i,0),t[i++]=e.west,t[i++]=e.south,t[i++]=e.east,t[i]=e.north,t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n.west=e[t++],n.south=e[t++],n.east=e[t++],n.north=e[t],n},l.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=s.TWO_PI),t-r},l.computeHeight=function(e){return e.north-e.south},l.fromDegrees=function(e,t,n,o,a){return e=s.toRadians(r(e,0)),t=s.toRadians(r(t,0)),n=s.toRadians(r(n,0)),o=s.toRadians(r(o,0)),i(a)?(a.west=e,a.south=t,a.east=n,a.north=o,a):new l(e,t,n,o)},l.fromRadians=function(e,t,n,o,a){return i(a)?(a.west=r(e,0),a.south=r(t,0),a.east=r(n,0),a.north=r(o,0),a):new l(e,t,n,o)},l.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,n=-Number.MAX_VALUE,o=Number.MAX_VALUE,a=-Number.MAX_VALUE,u=Number.MAX_VALUE,c=-Number.MAX_VALUE,d=0,h=e.length;d<h;d++){var p=e[d];r=Math.min(r,p.longitude),n=Math.max(n,p.longitude),u=Math.min(u,p.latitude),c=Math.max(c,p.latitude);var f=p.longitude>=0?p.longitude:p.longitude+s.TWO_PI;o=Math.min(o,f),a=Math.max(a,f)}return n-r>a-o&&(r=o,n=a,n>s.PI&&(n-=s.TWO_PI),r>s.PI&&(r-=s.TWO_PI)),i(t)?(t.west=r,t.south=u,t.east=n,t.north=c,t):new l(r,u,n,c)},l.fromCartesianArray=function(e,t,n){t=r(t,o.WGS84);for(var a=Number.MAX_VALUE,u=-Number.MAX_VALUE,c=Number.MAX_VALUE,d=-Number.MAX_VALUE,h=Number.MAX_VALUE,p=-Number.MAX_VALUE,f=0,m=e.length;f<m;f++){var g=t.cartesianToCartographic(e[f]);a=Math.min(a,g.longitude),u=Math.max(u,g.longitude),h=Math.min(h,g.latitude),p=Math.max(p,g.latitude);var _=g.longitude>=0?g.longitude:g.longitude+s.TWO_PI;c=Math.min(c,_),d=Math.max(d,_)}return u-a>d-c&&(a=c,u=d,u>s.PI&&(u-=s.TWO_PI),a>s.PI&&(a-=s.TWO_PI)),i(n)?(n.west=a,n.south=h,n.east=u,n.north=p,n):new l(a,h,u,p)},l.clone=function(e,t){if(i(e))return i(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new l(e.west,e.south,e.east,e.north)},l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},l.prototype.equalsEpsilon=function(e,t){return i(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},l.validate=function(e){},l.southwest=function(t,r){return i(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},l.northwest=function(t,r){return i(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},l.northeast=function(t,r){return i(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},l.southeast=function(t,r){return i(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},l.center=function(t,r){var n=t.east,o=t.west;n<o&&(n+=s.TWO_PI);var a=s.negativePiToPi(.5*(o+n)),l=.5*(t.south+t.north);return i(r)?(r.longitude=a,r.latitude=l,r.height=0,r):new e(a,l)},l.intersection=function(e,t,r){var n=e.east,o=e.west,a=t.east,u=t.west;n<o&&a>0?n+=s.TWO_PI:a<u&&n>0&&(a+=s.TWO_PI),n<o&&u<0?u+=s.TWO_PI:a<u&&o<0&&(o+=s.TWO_PI);var c=s.negativePiToPi(Math.max(o,u)),d=s.negativePiToPi(Math.min(n,a));if(!((e.west<e.east||t.west<t.east)&&d<=c)){var h=Math.max(e.south,t.south),p=Math.min(e.north,t.north);if(!(h>=p))return i(r)?(r.west=c,r.south=h,r.east=d,r.north=p,r):new l(c,h,d,p)}},l.simpleIntersection=function(e,t,r){var n=Math.max(e.west,t.west),o=Math.max(e.south,t.south),a=Math.min(e.east,t.east),s=Math.min(e.north,t.north);if(!(o>=s||n>=a))return i(r)?(r.west=n,r.south=o,r.east=a,r.north=s,r):new l(n,o,a,s)},l.union=function(e,t,r){i(r)||(r=new l);var n=e.east,o=e.west,a=t.east,u=t.west;n<o&&a>0?n+=s.TWO_PI:a<u&&n>0&&(a+=s.TWO_PI),n<o&&u<0?u+=s.TWO_PI:a<u&&o<0&&(o+=s.TWO_PI);var c=s.convertLongitudeRange(Math.min(o,u)),d=s.convertLongitudeRange(Math.max(n,a));return r.west=c,r.south=Math.min(e.south,t.south),r.east=d,r.north=Math.max(e.north,t.north),r},l.expand=function(e,t,r){return i(r)||(r=new l),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},l.contains=function(e,t){var r=t.longitude,i=t.latitude,n=e.west,o=e.east;return o<n&&(o+=s.TWO_PI,r<0&&(r+=s.TWO_PI)),(r>n||s.equalsEpsilon(r,n,s.EPSILON14))&&(r<o||s.equalsEpsilon(r,o,s.EPSILON14))&&i>=e.south&&i<=e.north};var u=new e;return l.subsample=function(e,t,n,a){t=r(t,o.WGS84),n=r(n,0),i(a)||(a=[]);var c=0,d=e.north,h=e.south,p=e.east,f=e.west,m=u;m.height=n,m.longitude=f,m.latitude=d,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.longitude=p,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.latitude=h,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.longitude=f,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.latitude=d<0?d:h>0?h:0;for(var g=1;g<8;++g)m.longitude=-Math.PI+g*s.PI_OVER_TWO,l.contains(e,m)&&(a[c]=t.cartographicToCartesian(m,a[c]),c++);return 0===m.latitude&&(m.longitude=f,a[c]=t.cartographicToCartesian(m,a[c]),c++,m.longitude=p,a[c]=t.cartographicToCartesian(m,a[c]),c++),a.length=c,a},l.MAX_VALUE=a(new l(-Math.PI,-s.PI_OVER_TWO,Math.PI,s.PI_OVER_TWO)),l}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,i){if(null===r||"object"!=typeof r)return r;i=e(i,!1);var n=new r.constructor;for(var o in r)if(r.hasOwnProperty(o)){var a=r[o];i&&(a=t(a,i)),n[o]=a}return n}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function r(i,n,o){o=e(o,!1);var a,s,l,u={},c=t(i),d=t(n);if(c)for(a in i)i.hasOwnProperty(a)&&(s=i[a],d&&o&&"object"==typeof s&&n.hasOwnProperty(a)?(l=n[a],u[a]="object"==typeof l?r(s,l,o):s):u[a]=s);if(d)for(a in n)n.hasOwnProperty(a)&&!u.hasOwnProperty(a)&&(l=n[a],u[a]=l);return u}return r}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(r,i){t(n[r])||(n[r]=!0,console.warn(e(i,r)))}var n={};return i.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",i}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,r){"use strict";function i(e,t){r(e,t)}return i}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=i.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return o.test(t)?t:e.toUpperCase()}function r(e,t,r,i){return(t||"")+r.toLowerCase()+(i||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var i=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(a,r).replace(n,t)),this.path&&(this.path=this.path.replace(n,t)),this.query&&(this.query=this.query.replace(n,t)),this.fragment&&(this.fragment=this.fragment.replace(n,t))};var n=/%[0-9a-z]{2}/gi,o=/[a-zA-Z0-9\-\._~]/,a=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],i=""==t[0];i&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),i&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,i){"use strict";function n(e,t){return n._implementation(e,t,document)}return n._implementation=function(r,i,n){i=t(i,t(n.baseURI,n.location.href));var o=new e(i);return new e(r).resolve(o).toString()},n}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(r,i){var n="",o=r.lastIndexOf("/");return-1!==o&&(n=r.substring(0,o+1)),i?(r=new e(r),t(r.query)&&(n+="?"+r.query),t(r.fragment)&&(n+="#"+r.fragment),n):n}return i}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(t){var r=new e(t);r.normalize();var i=r.path,n=i.lastIndexOf("/");return-1!==n&&(i=i.substr(n+1)),n=i.lastIndexOf("."),i=-1===n?"":i.substr(n+1)}return i}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(r)||(r=document.createElement("a")),r.href=window.location.href;var i=r.host,n=r.protocol;return r.href=t,r.href=r.href,n!==r.protocol||i!==r.host}var r;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function i(e){var t="";for(var i in e)if(e.hasOwnProperty(i)){var n=e[i],o=encodeURIComponent(i)+"=";if(r(n))for(var a=0,s=n.length;a<s;++a)t+=o+encodeURIComponent(n[a])+"&";else t+=o+encodeURIComponent(n)+"&"}return t=t.slice(0,-1)}return i}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function i(t){var i={};if(""===t)return i;for(var n=t.replace(/\+/g,"%20").split(/[&;]/),o=0,a=n.length;o<a;++o){var s=n[o].split("="),l=decodeURIComponent(s[0]),u=s[1];u=e(u)?decodeURIComponent(u):"";var c=i[l];"string"==typeof c?i[l]=[c,u]:r(c)?c.push(u):i[l]=u}return i}return i}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,r,i){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT);var n=e(t.throttleByServer,!1),o=n||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=o,this.throttleByServer=n,this.type=e(t.type,i.OTHER),this.serverKey=void 0,this.state=r.UNISSUED,this.deferred=void 0,this.cancelled=!1}return n.prototype.cancel=function(){this.cancelled=!0},n.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new n(this)},n}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),i=0;i<r.length;++i){var n=r[i],o=n.indexOf(": ");if(o>0){var a=n.substring(0,o),s=n.substring(o+2);t[a]=s}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,i){this.statusCode=e,this.response=r,this.responseHeaders=i,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,i,n){return t(e).then(r,i,n)}function t(e){var t,r;return e instanceof i?t=e:s(e)?(r=a(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=n(e),t}function r(t){return e(t,o)}function i(e){this.then=e}function n(e){return new i(function(r){try{return t(r?r(e):e)}catch(e){return o(e)}})}function o(e){return new i(function(r,i){try{return i?t(i(e)):o(e)}catch(e){return o(e)}})}function a(){function e(e,t,r){return h(e,t,r)}function r(e){return f(e)}function n(e){return f(o(e))}function s(e){return p(e)}var l,u,c,d,h,p,f;return u=new i(e),l={then:e,resolve:r,reject:n,progress:s,promise:u,resolver:{resolve:r,reject:n,progress:s}},c=[],d=[],h=function(e,t,r){var i,n;return i=a(),n="function"==typeof r?function(e){try{i.progress(r(e))}catch(e){i.progress(e)}}:function(e){i.progress(e)},c.push(function(r){r.then(e,t).then(i.resolve,i.reject,n)}),d.push(n),i.promise},p=function(e){return m(d,e),e},f=function(e){return e=t(e),h=e.then,f=t,p=_,m(c,e),d=c=C,e},l}function s(e){return e&&"function"==typeof e.then}function l(t,r,i,n,o){return g(2,arguments),e(t,function(t){function s(e){m(e)}function l(e){f(e)}var u,c,d,h,p,f,m,g,v,y;if(v=t.length>>>0,u=Math.max(0,Math.min(r,v)),d=[],c=v-u+1,h=[],p=a(),u)for(g=p.progress,m=function(e){h.push(e),--c||(f=m=_,p.reject(h))},f=function(e){d.push(e),--u||(f=m=_,p.resolve(d))},y=0;y<v;++y)y in t&&e(t[y],l,s,g);else p.resolve(d);return p.then(i,n,o)})}function u(e,t,r,i){function n(e){return t?t(e[0]):e[0]}return l(e,1,n,r,i)}function c(e,t,r,i){return g(1,arguments),h(e,v).then(t,r,i)}function d(){return h(arguments,v)}function h(t,r){return e(t,function(t){var i,n,o,s,l,u;if(o=n=t.length>>>0,i=[],u=a(),o)for(s=function(t,n){e(t,r).then(function(e){i[n]=e,--o||u.resolve(i)},u.reject)},l=0;l<n;l++)l in t?s(t[l],l):--o;else u.resolve(i);return u.promise})}function p(t,r){var i=b.call(arguments,1);return e(t,function(t){var n;return n=t.length,i[0]=function(t,i,o){return e(t,function(t){return e(i,function(e){return r(t,e,o,n)})})},y.apply(t,i)})}function f(t,r,i){var n=arguments.length>2;return e(t,function(e){return e=n?i:e,r.resolve(e),e},function(e){return r.reject(e),o(e)},r.progress)}function m(e,t){for(var r,i=0;r=e[i++];)r(t)}function g(e,t){for(var r,i=t.length;i>e;)if(null!=(r=t[--i])&&"function"!=typeof r)throw new Error("arg "+i+" must be a function")}function _(){}function v(e){return e}var y,b,C;return e.defer=a,e.resolve=t,e.reject=r,e.join=d,e.all=c,e.map=h,e.reduce=p,e.any=u,e.some=l,e.chain=f,e.isPromise=s,i.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(C,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return c(t,function(t){return e.apply(C,t)})})}},b=[].slice,y=[].reduce||function(e){var t,r,i,n,o;if(o=0,t=Object(this),n=t.length>>>0,r=arguments,r.length<=1)for(;;){if(o in t){i=t[o++];break}if(++o>=n)throw new TypeError}else i=r[1];for(;o<n;++o)o in t&&(i=e(i,t[o],o,t));return i},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function i(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function n(e,t){return t-e}return r(i.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),i.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},i.prototype.removeEventListener=function(e,t){for(var r=this._listeners,i=this._scopes,n=-1,o=0;o<r.length;o++)if(r[o]===e&&i[o]===t){n=o;break}return-1!==n&&(this._insideRaiseEvent?(this._toRemove.push(n),r[n]=void 0,i[n]=void 0):(r.splice(n,1),i.splice(n,1)),!0)},i.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,r=this._listeners,i=this._scopes,o=r.length;for(e=0;e<o;e++){var a=r[e];t(a)&&r[e].apply(i[e],arguments)}var s=this._toRemove;if((o=s.length)>0){for(s.sort(n),e=0;e<o;e++){var l=s[e];r.splice(l,1),i.splice(l,1)}s.length=0}this._insideRaiseEvent=!1},i}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,i){"use strict";function n(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function o(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}return i(n.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),n.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},n.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,i=this._comparator,n=this._array,a=-1,s=!0;s;){var l=2*(e+1),u=l-1;a=u<r&&i(n[u],n[e])<0?u:e,l<r&&i(n[l],n[a])<0&&(a=l),a!==e?(o(n,a,e),e=a):s=!1}},n.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},n.prototype.insert=function(e){var t=this._array,i=this._comparator,n=this._maximumLength,a=this._length++;for(a<t.length?t[a]=e:t.push(e);0!==a;){var s=Math.floor((a-1)/2);if(!(i(t[a],t[s])<0))break;o(t,a,s),a=s}var l;return r(n)&&this._length>n&&(l=t[n],this._length=n),l},n.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,i=r[e];return o(r,e,--this._length),this.heapify(e),i}},n}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t){return e.priority-t.priority}function d(){}function h(e){i(e.priorityFunction)&&(e.priority=e.priorityFunction())}function p(e){return E[e]<d.maximumRequestsPerServer}function f(e){return e.state===u.UNISSUED&&(e.state=u.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==u.CANCELLED&&(--C.numberOfActiveRequests,--E[e.serverKey],x.raiseEvent(),e.state=u.RECEIVED,e.deferred.resolve(t))}}function g(e){return function(t){e.state!==u.CANCELLED&&(++C.numberOfFailedRequests,--C.numberOfActiveRequests,--E[e.serverKey],x.raiseEvent(t),e.state=u.FAILED,e.deferred.reject(t))}}function _(e){var t=f(e);return e.state=u.ACTIVE,T.push(e),++C.numberOfActiveRequests,++C.numberOfActiveRequestsEver,++E[e.serverKey],e.requestFunction().then(m(e)).otherwise(g(e)),t}function v(e){var t=e.state===u.ACTIVE;e.state=u.CANCELLED,++C.numberOfCancelledRequests,e.deferred.reject(),t&&(--C.numberOfActiveRequests,--E[e.serverKey],++C.numberOfCancelledActiveRequests),i(e.cancelFunction)&&e.cancelFunction()}function y(){C.numberOfAttemptedRequests=0,C.numberOfCancelledRequests=0,C.numberOfCancelledActiveRequests=0}function b(){d.debugShowStatistics&&(C.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+C.numberOfAttemptedRequests),C.numberOfActiveRequests>0&&console.log("Number of active requests: "+C.numberOfActiveRequests),C.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+C.numberOfCancelledRequests),C.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+C.numberOfCancelledActiveRequests),C.numberOfFailedRequests>0&&console.log("Number of failed requests: "+C.numberOfFailedRequests),y())}var C={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},S=20,w=new a({comparator:c});w.maximumLength=S,w.reserve(S);var T=[],E={},A="undefined"!=typeof document?new e(document.location.href):new e,x=new o;return d.maximumRequests=50,d.maximumRequestsPerServer=6,d.throttleRequests=!0,d.debugShowStatistics=!1,d.requestCompletedEvent=x,n(d,{statistics:{get:function(){return C}},priorityHeapLength:{get:function(){return S},set:function(e){if(e<S)for(;w.length>e;){var t=w.pop();v(t)}S=e,w.maximumLength=e,w.reserve(e)}}}),d.update=function(){var e,t,r=0,i=T.length;for(e=0;e<i;++e)t=T[e],t.cancelled&&v(t),t.state===u.ACTIVE?r>0&&(T[e-r]=t):++r;T.length-=r;var n=w.internalArray,o=w.length;for(e=0;e<o;++e)h(n[e]);w.resort();for(var a=Math.max(d.maximumRequests-T.length,0),s=0;s<a&&w.length>0;)t=w.pop(),t.cancelled?v(t):!t.throttleByServer||p(t.serverKey)?(_(t),++s):v(t);b()},d.getServerKey=function(t){var r=new e(t).resolve(A);r.normalize();var n=r.authority;/:/.test(n)||(n=n+":"+("https"===r.scheme?"443":"80"));var o=E[n];return i(o)||(E[n]=0),n},d.request=function(e){if(l(e.url)||s(e.url))return x.raiseEvent(),e.state=u.RECEIVED,e.requestFunction();if(++C.numberOfAttemptedRequests,i(e.serverKey)||(e.serverKey=d.getServerKey(e.url)),!d.throttleRequests||!e.throttle)return _(e);if(!(T.length>=d.maximumRequests)&&(!e.throttleByServer||p(e.serverKey))){h(e);var t=w.insert(e);if(i(t)){if(t===e)return;v(t)}return f(e)}},d.clearForSpecs=function(){for(;w.length>0;){v(w.pop())}for(var e=T.length,t=0;t<e;++t)v(T[t]);T.length=0,E={},C.numberOfAttemptedRequests=0,C.numberOfActiveRequests=0,C.numberOfCancelledRequests=0,C.numberOfCancelledActiveRequests=0,C.numberOfFailedRequests=0,C.numberOfActiveRequestsEver=0},d.numberOfActiveRequestsByServer=function(e){return E[e]},d.requestHeap=w,d}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(r){var i=new e(r);i.normalize();var n=i.getAuthority();if(t(n)){if(-1!==n.indexOf("@")){n=n.split("@")[1]}if(-1===n.indexOf(":")){var o=i.getScheme();if(t(o)||(o=window.location.protocol,o=o.substring(0,o.length-1)),"http"===o)n+=":80";else{if("https"!==o)return;n+=":443"}}return n}}var n={},o={};return n.add=function(e,r){var i=e.toLowerCase()+":"+r;t(o[i])||(o[i]=!0)},n.remove=function(e,r){var i=e.toLowerCase()+":"+r;t(o[i])&&delete o[i]},n.contains=function(e){var r=i(e);return!(!t(r)||!t(o[r]))},n.clear=function(){o={}},n}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e,t){var r=e.query;if(!o(r)||0===r.length)return{};var n;if(-1===r.indexOf("=")){var a={};a[r]=void 0,n=a}else n=_(r);t._queryParameters=i(t._queryParameters,n),e.query=void 0}function x(e,t){var r=t._queryParameters,i=Object.keys(r);1!==i.length||o(r[i[0]])?e.query=g(r):e.query=i[0]}function P(e,t){return o(e)?o(e.clone)?e.clone():r(e):t}function D(e){if(e.state===C.ISSUED||e.state===C.ACTIVE)throw new S("The Resource is already being fetched.");e.state=C.UNISSUED,e.deferred=void 0}function I(e){e=n(e,n.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=P(e.templateValues,{}),this._queryParameters=P(e.queryParameters,{}),this.headers=P(e.headers,{}),this.request=n(e.request,new v),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=n(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function O(e,t){var r=e.request;r.url=e.url,r.requestFunction=function(){var r=e.url,i=!1;e.isDataUri||e.isBlobUri||(i=e.isCrossOriginUrl);var n=E.defer();return I._Implementations.createImage(r,i&&t,n),n.promise};var i=b.request(r);if(o(i))return i.otherwise(function(i){return r.state!==C.FAILED?E.reject(i):e.retryOnError(i).then(function(n){return n?(r.state=C.UNISSUED,r.deferred=void 0,O(e,t)):E.reject(i)})})}function M(e,t,r){var i={};i[t]=r,e.addQueryParameters(i);var n=e.request;n.url=e.url,n.requestFunction=function(){var t=E.defer();return window[r]=function(e){t.resolve(e);try{delete window[r]}catch(e){window[r]=void 0}},I._Implementations.loadAndExecuteScript(e.url,r,t),t.promise};var a=b.request(n);if(o(a))return a.otherwise(function(i){return n.state!==C.FAILED?E.reject(i):e.retryOnError(i).then(function(o){return o?(n.state=C.UNISSUED,n.deferred=void 0,M(e,t,r)):E.reject(i)})})}function R(e,t){D(e.request);var r=e.request;r.url=e.url,r.requestFunction=function(){ +var n=t.responseType,a=i(e.headers,t.headers),s=t.overrideMimeType,l=t.method,u=t.data,c=E.defer(),d=I._Implementations.loadWithXhr(e.url,n,l,u,a,c,s);return o(d)&&o(d.abort)&&(r.cancelFunction=function(){d.abort()}),c.promise};var n=b.request(r);if(o(n))return n.then(function(e){return e}).otherwise(function(i){return r.state!==C.FAILED?E.reject(i):e.retryOnError(i).then(function(n){return n?(r.state=C.UNISSUED,r.deferred=void 0,e.fetch(t)):E.reject(i)})})}function L(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function N(e,t){for(var r=L(e,t),i=new ArrayBuffer(r.length),n=new Uint8Array(i),o=0;o<r.length;o++)n[o]=r.charCodeAt(o);return i}function k(e,t){t=n(t,"");var r=e[1],i=!!e[2],o=e[3];switch(t){case"":case"text":return L(i,o);case"arraybuffer":return N(i,o);case"blob":var a=N(i,o);return new Blob([a],{type:r});case"document":return(new DOMParser).parseFromString(L(i,o),r);case"json":return JSON.parse(L(i,o))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();I.createIfNeeded=function(e,t){if(e instanceof I)return e.clone();if("string"!=typeof e)return e;var r=P(t,{});return r.url=e,new I(r)},a(I,{isBlobSupported:{get:function(){return F}}}),a(I.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new T(e);A(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return p(this._url)}},isCrossOriginUrl:{get:function(){return f(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),I.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var r=new T(this._url);e&&x(r,this);var i=r.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),n=this._templateValues,a=Object.keys(n);if(a.length>0)for(var s=0;s<a.length;s++){var l=a[s],u=n[l];i=i.replace(new RegExp("{"+l+"}","g"),encodeURIComponent(u))}return t&&o(this.proxy)&&(i=this.proxy.getURL(i)),i},I.prototype.addQueryParameters=function(e,t){this._queryParameters=t?i(this._queryParameters,e):i(e,this._queryParameters)},I.prototype.addTemplateValues=function(e,t){this._templateValues=t?i(this._templateValues,e):i(e,this._templateValues)},I.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,o(e.url)){var r=new T(e.url);A(r,t),r.fragment=void 0,t._url=r.resolve(new T(c(this._url))).toString()}return o(e.queryParameters)&&(t._queryParameters=i(e.queryParameters,t._queryParameters)),o(e.templateValues)&&(t._templateValues=i(e.templateValues,t.templateValues)),o(e.headers)&&(t.headers=i(e.headers,t.headers)),o(e.proxy)&&(t.proxy=e.proxy),o(e.request)?t.request=e.request:t.request=this.request.clone(),o(e.retryCallback)&&(t.retryCallback=e.retryCallback),o(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},I.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return E(!1);var r=this;return E(t(this,e)).then(function(e){return++r._retryCount,e})},I.prototype.clone=function(e){return o(e)||(e=new I({url:this._url})),e._url=this._url,e._queryParameters=r(this._queryParameters),e._templateValues=r(this._templateValues),e.headers=r(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},I.prototype.getBaseUri=function(e){return d(this.getUrlComponent(e),e)},I.prototype.appendForwardSlash=function(){this._url=e(this._url)},I.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},I.fetchArrayBuffer=function(e){return new I(e).fetchArrayBuffer()},I.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},I.fetchBlob=function(e){return new I(e).fetchBlob()},I.prototype.fetchImage=function(e,t){if(o(t)&&s("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=n(e,!1),t=n(t,!0),D(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return O(this,t);var r=this.fetchBlob();if(o(r)){var i,a;return r.then(function(e){if(o(e)){a=e;var t=window.URL.createObjectURL(e);return i=new I({url:t}),O(i)}}).then(function(e){if(o(e))return window.URL.revokeObjectURL(i.url),e.blob=a,e}).otherwise(function(e){return o(i)&&window.URL.revokeObjectURL(i.url),E.reject(e)})}},I.fetchImage=function(e){return new I(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},I.prototype.fetchText=function(){return this.fetch({responseType:"text"})},I.fetchText=function(e){return new I(e).fetchText()},I.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(o(e))return e.then(function(e){if(o(e))return JSON.parse(e)})},I.fetchJson=function(e){return new I(e).fetchJson()},I.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},I.fetchXML=function(e){return new I(e).fetchXML()},I.prototype.fetchJsonp=function(e){e=n(e,"callback"),D(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(o(window[t]));return M(this,e,t)},I.fetchJsonp=function(e){return new I(e).fetchJsonp(e.callbackParameterName)},I.prototype.fetch=function(e){return e=P(e,n.EMPTY_OBJECT),e.method="GET",R(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return I.fetch=function(e){return new I(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},I.prototype.post=function(e,r){return t.defined("data",e),r=P(r,{}),r.method="POST",r.data=e,R(this,r)},I.post=function(e){return new I(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},I._Implementations={},I._Implementations.createImage=function(e,t,r){var i=new Image;i.onload=function(){r.resolve(i)},i.onerror=function(e){r.reject(e)},t&&(w.contains(e)?i.crossOrigin="use-credentials":i.crossOrigin=""),i.src=e},I._Implementations.loadWithXhr=function(e,t,r,i,n,a,s){var l=B.exec(e);if(null!==l)return void a.resolve(k(l,t));var u=new XMLHttpRequest;if(w.contains(e)&&(u.withCredentials=!0),o(s)&&o(u.overrideMimeType)&&u.overrideMimeType(s),u.open(r,e,!0),o(n))for(var c in n)n.hasOwnProperty(c)&&u.setRequestHeader(c,n[c]);o(t)&&(u.responseType=t);var d=!1;return"string"==typeof e&&(d=0===e.indexOf("file://")),u.onload=function(){if((u.status<200||u.status>=300)&&(!d||0!==u.status))return void a.reject(new y(u.status,u.response,u.getAllResponseHeaders()));var e=u.response,r=u.responseType;if(204===u.status)a.resolve();else if(!o(e)||o(t)&&r!==t)if("json"===t&&"string"==typeof e)try{a.resolve(JSON.parse(e))}catch(e){a.reject(e)}else(""===r||"document"===r)&&o(u.responseXML)&&u.responseXML.hasChildNodes()?a.resolve(u.responseXML):""!==r&&"text"!==r||!o(u.responseText)?a.reject(new S("Invalid XMLHttpRequest response type.")):a.resolve(u.responseText);else a.resolve(e)},u.onerror=function(e){a.reject(new y)},u.send(i),u},I._Implementations.loadAndExecuteScript=function(e,t,r){var i=document.createElement("script");i.async=!0,i.src=e;var n=document.getElementsByTagName("head")[0];i.onload=function(){i.onload=void 0,n.removeChild(i)},i.onerror=function(e){r.reject(e)},n.appendChild(i)},I._DefaultImplementations={},I._DefaultImplementations.createImage=I._Implementations.createImage,I._DefaultImplementations.loadWithXhr=I._Implementations.loadWithXhr,I._DefaultImplementations.loadAndExecuteScript=I._Implementations.loadAndExecuteScript,I.DEFAULT=u(new I({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),I}),define("Core/BingMapsGeocoderService",["./BingMapsApi","./Check","./defaultValue","./defined","./defineProperties","./Rectangle","./Resource"],function(e,t,r,i,n,o,a){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT);var n=t.key;if(this._key=e.getKey(n),i(n)){var o=e.getErrorCredit(n);i(o)&&t.scene._frameState.creditDisplay.addDefaultCredit(o)}this._resource=new a({url:l,queryParameters:{key:this._key}})}var l="https://dev.virtualearth.net/REST/v1/Locations";return n(s.prototype,{url:{get:function(){return l}},key:{get:function(){return this._key}}}),s.prototype.geocode=function(e){return this._resource.getDerivedResource({queryParameters:{query:e}}).fetchJsonp("jsonp").then(function(e){return 0===e.resourceSets.length?[]:e.resourceSets[0].resources.map(function(e){var t=e.bbox,r=t[0],i=t[1],n=t[2],a=t[3];return{displayName:e.name,destination:o.fromDegrees(i,r,a,n)}})})},s}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,i,n,o,a){"use strict";function s(e){this._ellipsoid=r(e,a.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return n(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.prototype.project=function(t,r){var n=this._semimajorAxis,o=t.longitude*n,a=t.latitude*n,s=t.height;return i(r)?(r.x=o,r.y=a,r.z=s,r):new e(o,a,s)},s.prototype.unproject=function(e,r){var n=this._oneOverSemimajorAxis,o=e.x*n,a=e.y*n,s=e.z;return i(r)?(r.longitude=o,r.latitude=a,r.height=s,r):new t(o,a,s)},s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r,n){this.x=i(e,0),this.y=i(t,0),this.width=i(r,0),this.height=i(n,0)}l.packedLength=4,l.pack=function(e,t,r){return r=i(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.width,t[r]=e.height,t},l.unpack=function(e,t,r){return t=i(t,0),n(r)||(r=new l),r.x=e[t++],r.y=e[t++],r.width=e[t++],r.height=e[t],r},l.fromPoints=function(e,t){if(n(t)||(t=new l),!n(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var r=e.length,i=e[0].x,o=e[0].y,a=e[0].x,s=e[0].y,u=1;u<r;u++){var c=e[u],d=c.x,h=c.y;i=Math.min(d,i),a=Math.max(d,a),o=Math.min(h,o),s=Math.max(h,s)}return t.x=i,t.y=o,t.width=a-i,t.height=s-o,t};var u=new o,c=new t,d=new t;return l.fromRectangle=function(t,r,o){if(n(o)||(o=new l),!n(t))return o.x=0,o.y=0,o.width=0,o.height=0,o;r=i(r,u);var a=r.project(s.southwest(t,c)),h=r.project(s.northeast(t,d));return e.subtract(h,a,h),o.x=a.x,o.y=a.y,o.width=h.x,o.height=h.y,o},l.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new l(e.x,e.y,e.width,e.height)},l.union=function(e,t,r){n(r)||(r=new l);var i=Math.min(e.x,t.x),o=Math.min(e.y,t.y),a=Math.max(e.x+e.width,t.x+t.width),s=Math.max(e.y+e.height,t.y+t.height);return r.x=i,r.y=o,r.width=a-i,r.height=s-o,r},l.expand=function(e,t,r){r=l.clone(e,r);var i=t.x-r.x,n=t.y-r.y;return i>r.width?r.width=i:i<0&&(r.width-=i,r.x=t.x),n>r.height?r.height=n:n<0&&(r.height-=n,r.y=t.y),r},l.intersect=function(e,t){var r=e.x,i=e.y,n=t.x,o=t.y;return r>n+t.width||r+e.width<n||i+e.height<o||i>o+t.height?a.OUTSIDE:a.INTERSECTING},l.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.intersect=function(e){return l.intersect(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,i,n,o,a,s,l,u){this[0]=r(e,0),this[1]=r(n,0),this[2]=r(s,0),this[3]=r(t,0),this[4]=r(o,0),this[5]=r(l,0),this[6]=r(i,0),this[7]=r(a,0),this[8]=r(u,0)}function u(e){for(var t=0,r=0;r<9;++r){var i=e[r];t+=i*i}return Math.sqrt(t)}function c(e){for(var t=0,r=0;r<3;++r){var i=e[l.getElementIndex(m[r],f[r])];t+=2*i*i}return Math.sqrt(t)}function d(e,t){for(var r=s.EPSILON15,i=0,n=1,o=0;o<3;++o){var a=Math.abs(e[l.getElementIndex(m[o],f[o])]);a>i&&(n=o,i=a)}var u=1,c=0,d=f[n],h=m[n];if(Math.abs(e[l.getElementIndex(h,d)])>r){var p,g=e[l.getElementIndex(h,h)],_=e[l.getElementIndex(d,d)],v=e[l.getElementIndex(h,d)],y=(g-_)/2/v;p=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),u=1/Math.sqrt(1+p*p),c=p*u}return t=l.clone(l.IDENTITY,t),t[l.getElementIndex(d,d)]=t[l.getElementIndex(h,h)]=u,t[l.getElementIndex(h,d)]=c,t[l.getElementIndex(d,h)]=-c,t}l.packedLength=9,l.pack=function(e,t,i){return i=r(i,0),t[i++]=e[0],t[i++]=e[1],t[i++]=e[2],t[i++]=e[3],t[i++]=e[4],t[i++]=e[5],t[i++]=e[6],t[i++]=e[7],t[i++]=e[8],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new l(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},l.fromArray=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t],n[1]=e[t+1],n[2]=e[t+2],n[3]=e[t+3],n[4]=e[t+4],n[5]=e[t+5],n[6]=e[t+6],n[7]=e[t+7],n[8]=e[t+8],n},l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},l.fromQuaternion=function(e,t){var r=e.x*e.x,n=e.x*e.y,o=e.x*e.z,a=e.x*e.w,s=e.y*e.y,u=e.y*e.z,c=e.y*e.w,d=e.z*e.z,h=e.z*e.w,p=e.w*e.w,f=r-s-d+p,m=2*(n-h),g=2*(o+c),_=2*(n+h),v=-r+s-d+p,y=2*(u-a),b=2*(o-c),C=2*(u+a),S=-r-s+d+p;return i(t)?(t[0]=f,t[1]=_,t[2]=b,t[3]=m,t[4]=v,t[5]=C,t[6]=g,t[7]=y,t[8]=S,t):new l(f,m,g,_,v,y,b,C,S)},l.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),n=Math.cos(-e.heading),o=Math.cos(e.roll),a=Math.sin(-e.pitch),s=Math.sin(-e.heading),u=Math.sin(e.roll),c=r*n,d=-o*s+u*a*n,h=u*s+o*a*n,p=r*s,f=o*n+u*a*s,m=-u*n+o*a*s,g=-a,_=u*r,v=o*r;return i(t)?(t[0]=c,t[1]=p,t[2]=g,t[3]=d,t[4]=f,t[5]=_,t[6]=h,t[7]=m,t[8]=v,t):new l(c,d,h,p,f,m,g,_,v)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new l(e.x,0,0,0,e.y,0,0,0,e.z)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new l(e,0,0,0,e,0,0,0,e)},l.fromCrossProduct=function(e,t){return i(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new l(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},l.fromRotationX=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=n,t[6]=0,t[7]=-n,t[8]=r,t):new l(1,0,0,0,r,-n,0,n,r)},l.fromRotationY=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=r,t[1]=0,t[2]=-n,t[3]=0,t[4]=1,t[5]=0,t[6]=n,t[7]=0,t[8]=r,t):new l(r,0,n,0,1,0,-n,0,r)},l.fromRotationZ=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=r,t[1]=n,t[2]=0,t[3]=-n,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new l(r,-n,0,n,r,0,0,0,1)},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},l.getElementIndex=function(e,t){return 3*e+t},l.getColumn=function(e,t,r){var i=3*t,n=e[i],o=e[i+1],a=e[i+2];return r.x=n,r.y=o,r.z=a,r},l.setColumn=function(e,t,r,i){i=l.clone(e,i);var n=3*t;return i[n]=r.x,i[n+1]=r.y,i[n+2]=r.z,i},l.getRow=function(e,t,r){var i=e[t],n=e[t+3],o=e[t+6];return r.x=i,r.y=n,r.z=o,r},l.setRow=function(e,t,r,i){return i=l.clone(e,i),i[t]=r.x,i[t+3]=r.y,i[t+6]=r.z,i};var h=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,r){var i=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],n=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],o=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],a=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],s=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],l=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],u=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],d=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=i,r[1]=n,r[2]=o,r[3]=a,r[4]=s,r[5]=l,r[6]=u,r[7]=c,r[8]=d,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},l.multiplyByVector=function(e,t,r){var i=t.x,n=t.y,o=t.z,a=e[0]*i+e[3]*n+e[6]*o,s=e[1]*i+e[4]*n+e[7]*o,l=e[2]*i+e[5]*n+e[8]*o;return r.x=a,r.y=s,r.z=l,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},l.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},l.transpose=function(e,t){var r=e[0],i=e[3],n=e[6],o=e[1],a=e[4],s=e[7],l=e[2],u=e[5],c=e[8];return t[0]=r,t[1]=i,t[2]=n,t[3]=o,t[4]=a,t[5]=s,t[6]=l,t[7]=u,t[8]=c,t};var f=[1,0,0],m=[2,2,1],g=new l,_=new l;return l.computeEigenDecomposition=function(e,t){var r=s.EPSILON20,n=0,o=0;i(t)||(t={});for(var a=t.unitary=l.clone(l.IDENTITY,t.unitary),h=t.diagonal=l.clone(e,t.diagonal),p=r*u(h);o<10&&c(h)>p;)d(h,g),l.transpose(g,_),l.multiply(h,g,h),l.multiply(_,h,h),l.multiply(a,g,a),++n>2&&(++o,n=0);return t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},l.determinant=function(e){var t=e[0],r=e[3],i=e[6],n=e[1],o=e[4],a=e[7],s=e[2],l=e[5],u=e[8];return t*(o*u-l*a)+n*(l*i-r*u)+s*(r*a-o*i)},l.inverse=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[3],a=e[4],s=e[5],u=e[6],c=e[7],d=e[8],h=l.determinant(e);t[0]=a*d-c*s,t[1]=c*n-i*d,t[2]=i*s-a*n,t[3]=u*s-o*d,t[4]=r*d-u*n,t[5]=o*n-r*s,t[6]=o*c-u*a,t[7]=u*i-r*c,t[8]=r*a-o*i;var p=1/h;return l.multiplyByScalar(t,p,t)},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},l.IDENTITY=a(new l(1,0,0,0,1,0,0,0,1)),l.ZERO=a(new l(0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN1ROW0=3,l.COLUMN1ROW1=4,l.COLUMN1ROW2=5,l.COLUMN2ROW0=6,l.COLUMN2ROW1=7,l.COLUMN2ROW2=8,n(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},l}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,r,i,n){this.x=t(e,0),this.y=t(r,0),this.z=t(i,0),this.w=t(n,0)}a.fromElements=function(e,t,i,n,o){return r(o)?(o.x=e,o.y=t,o.z=i,o.w=n,o):new a(e,t,i,n)},a.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new a(e.red,e.green,e.blue,e.alpha)},a.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new a(e.x,e.y,e.z,e.w)},a.packedLength=4,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.x,r[i++]=e.y,r[i++]=e.z,r[i]=e.w,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.x=e[i++],n.y=e[i++],n.z=e[i++],n.w=e[i],n},a.packArray=function(e,t){var i=e.length;r(t)?t.length=4*i:t=new Array(4*i);for(var n=0;n<i;++n)a.pack(e[n],t,4*n);return t},a.unpackArray=function(e,t){var i=e.length;r(t)?t.length=i/4:t=new Array(i/4);for(var n=0;n<i;n+=4){var o=n/4;t[o]=a.unpack(e,n,t[o])}return t},a.fromArray=a.unpack,a.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},a.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},a.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},a.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},a.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},a.magnitude=function(e){return Math.sqrt(a.magnitudeSquared(e))};var s=new a;a.distance=function(e,t){return a.subtract(e,t,s),a.magnitude(s)},a.distanceSquared=function(e,t){return a.subtract(e,t,s),a.magnitudeSquared(s)},a.normalize=function(e,t){var r=a.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},a.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},a.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},a.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},a.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},a.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},a.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},a.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},a.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},a.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var l=new a;a.lerp=function(e,t,r,i){return a.multiplyByScalar(t,r,l),i=a.multiplyByScalar(e,1-r,i),a.add(l,i,i)};var u=new a;return a.mostOrthogonalAxis=function(e,t){var r=a.normalize(e,u);return a.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?a.clone(a.UNIT_X,t):a.clone(a.UNIT_W,t):r.z<=r.w?a.clone(a.UNIT_Z,t):a.clone(a.UNIT_W,t):r.y<=r.z?r.y<=r.w?a.clone(a.UNIT_Y,t):a.clone(a.UNIT_W,t):r.z<=r.w?a.clone(a.UNIT_Z,t):a.clone(a.UNIT_W,t)},a.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},a.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},a.equalsEpsilon=function(e,t,i,n){return e===t||r(e)&&r(t)&&o.equalsEpsilon(e.x,t.x,i,n)&&o.equalsEpsilon(e.y,t.y,i,n)&&o.equalsEpsilon(e.z,t.z,i,n)&&o.equalsEpsilon(e.w,t.w,i,n)},a.ZERO=n(new a(0,0,0,0)),a.UNIT_X=n(new a(1,0,0,0)),a.UNIT_Y=n(new a(0,1,0,0)),a.UNIT_Z=n(new a(0,0,1,0)),a.UNIT_W=n(new a(0,0,0,1)),a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a.prototype.equalsEpsilon=function(e,t,r){return a.equalsEpsilon(this,e,t,r)},a.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},a}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t,r,n,o,a,s,l,u,c,d,h,p,f,m,g){this[0]=i(e,0),this[1]=i(o,0),this[2]=i(u,0),this[3]=i(p,0),this[4]=i(t,0),this[5]=i(a,0),this[6]=i(c,0),this[7]=i(f,0),this[8]=i(r,0),this[9]=i(s,0),this[10]=i(d,0),this[11]=i(m,0),this[12]=i(n,0),this[13]=i(l,0),this[14]=i(h,0),this[15]=i(g,0)}c.packedLength=16,c.pack=function(e,t,r){return r=i(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},c.unpack=function(e,t,r){return t=i(t,0),n(r)||(r=new c),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},c.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,r,o){return r=i(r,e.ZERO),n(o)?(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=0,o[4]=t[3],o[5]=t[4],o[6]=t[5],o[7]=0,o[8]=t[6],o[9]=t[7],o[10]=t[8],o[11]=0,o[12]=r.x,o[13]=r.y,o[14]=r.z,o[15]=1,o):new c(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,r,i){n(i)||(i=new c);var o=r.x,a=r.y,s=r.z,l=t.x*t.x,u=t.x*t.y,d=t.x*t.z,h=t.x*t.w,p=t.y*t.y,f=t.y*t.z,m=t.y*t.w,g=t.z*t.z,_=t.z*t.w,v=t.w*t.w,y=l-p-g+v,b=2*(u-_),C=2*(d+m),S=2*(u+_),w=-l+p-g+v,T=2*(f-h),E=2*(d-m),A=2*(f+h),x=-l-p+g+v;return i[0]=y*o,i[1]=S*o,i[2]=E*o,i[3]=0,i[4]=b*a,i[5]=w*a,i[6]=A*a,i[7]=0,i[8]=C*s,i[9]=T*s,i[10]=x*s,i[11]=0,i[12]=e.x,i[13]=e.y,i[14]=e.z,i[15]=1,i},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(l.IDENTITY,e,t)},c.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var d=new e,h=new e,p=new e;c.fromCamera=function(t,r){var i=t.position,o=t.direction,a=t.up;e.normalize(o,d),e.normalize(e.cross(d,a,h),h),e.normalize(e.cross(h,d,p),p);var s=h.x,l=h.y,u=h.z,f=d.x,m=d.y,g=d.z,_=p.x,v=p.y,y=p.z,b=i.x,C=i.y,S=i.z,w=s*-b+l*-C+u*-S,T=_*-b+v*-C+y*-S,E=f*b+m*C+g*S;return n(r)?(r[0]=s,r[1]=_,r[2]=-f,r[3]=0,r[4]=l,r[5]=v,r[6]=-m,r[7]=0,r[8]=u,r[9]=y,r[10]=-g,r[11]=0,r[12]=w,r[13]=T,r[14]=E,r[15]=1,r):new c(s,l,u,w,_,v,y,T,-f,-m,-g,E,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,r,i,n){var o=Math.tan(.5*e),a=1/o,s=a/t,l=(i+r)/(r-i),u=2*i*r/(r-i);return n[0]=s,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=a,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=l,n[11]=-1,n[12]=0,n[13]=0,n[14]=u,n[15]=0,n},c.computeOrthographicOffCenter=function(e,t,r,i,n,o,a){var s=1/(t-e),l=1/(i-r),u=1/(o-n),c=-(t+e)*s,d=-(i+r)*l,h=-(o+n)*u;return s*=2,l*=2,u*=-2,a[0]=s,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=l,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=u,a[11]=0,a[12]=c,a[13]=d,a[14]=h,a[15]=1,a},c.computePerspectiveOffCenter=function(e,t,r,i,n,o,a){var s=2*n/(t-e),l=2*n/(i-r),u=(t+e)/(t-e),c=(i+r)/(i-r),d=-(o+n)/(o-n),h=-2*o*n/(o-n);return a[0]=s,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=l,a[6]=0,a[7]=0,a[8]=u,a[9]=c,a[10]=d,a[11]=-1,a[12]=0,a[13]=0,a[14]=h,a[15]=0,a},c.computeInfinitePerspectiveOffCenter=function(e,t,r,i,n,o){var a=2*n/(t-e),s=2*n/(i-r),l=(t+e)/(t-e),u=(i+r)/(i-r),c=-2*n;return o[0]=a,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=l,o[9]=u,o[10]=-1,o[11]=-1,o[12]=0,o[13]=0,o[14]=c,o[15]=0,o},c.computeViewportTransformation=function(e,t,r,n){e=i(e,i.EMPTY_OBJECT);var o=i(e.x,0),a=i(e.y,0),s=i(e.width,0),l=i(e.height,0);t=i(t,0),r=i(r,1);var u=.5*s,c=.5*l,d=.5*(r-t),h=u,p=c,f=d,m=o+u,g=a+c,_=t+d;return n[0]=h,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=p,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=f,n[11]=0,n[12]=m,n[13]=g,n[14]=_,n[15]=1,n},c.computeView=function(t,r,i,n,o){return o[0]=n.x,o[1]=i.x,o[2]=-r.x,o[3]=0,o[4]=n.y,o[5]=i.y,o[6]=-r.y,o[7]=0,o[8]=n.z,o[9]=i.z,o[10]=-r.z,o[11]=0,o[12]=-e.dot(n,t),o[13]=-e.dot(i,t),o[14]=e.dot(r,t),o[15]=1,o},c.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,r){var i=4*t,n=e[i],o=e[i+1],a=e[i+2],s=e[i+3];return r.x=n,r.y=o,r.z=a,r.w=s,r},c.setColumn=function(e,t,r,i){i=c.clone(e,i);var n=4*t;return i[n]=r.x,i[n+1]=r.y,i[n+2]=r.z,i[n+3]=r.w,i},c.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},c.getRow=function(e,t,r){var i=e[t],n=e[t+4],o=e[t+8],a=e[t+12];return r.x=i,r.y=n,r.z=o,r.w=a,r},c.setRow=function(e,t,r,i){return i=c.clone(e,i),i[t]=r.x,i[t+4]=r.y,i[t+8]=r.z,i[t+12]=r.w,i};var f=new e;c.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],f)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],f)),r};var m=new e;c.getMaximumScale=function(t){return c.getScale(t,m),e.maximumComponent(m)},c.multiply=function(e,t,r){var i=e[0],n=e[1],o=e[2],a=e[3],s=e[4],l=e[5],u=e[6],c=e[7],d=e[8],h=e[9],p=e[10],f=e[11],m=e[12],g=e[13],_=e[14],v=e[15],y=t[0],b=t[1],C=t[2],S=t[3],w=t[4],T=t[5],E=t[6],A=t[7],x=t[8],P=t[9],D=t[10],I=t[11],O=t[12],M=t[13],R=t[14],L=t[15],N=i*y+s*b+d*C+m*S,k=n*y+l*b+h*C+g*S,F=o*y+u*b+p*C+_*S,B=a*y+c*b+f*C+v*S,U=i*w+s*T+d*E+m*A,V=n*w+l*T+h*E+g*A,z=o*w+u*T+p*E+_*A,G=a*w+c*T+f*E+v*A,W=i*x+s*P+d*D+m*I,H=n*x+l*P+h*D+g*I,j=o*x+u*P+p*D+_*I,q=a*x+c*P+f*D+v*I,Y=i*O+s*M+d*R+m*L,X=n*O+l*M+h*R+g*L,Q=o*O+u*M+p*R+_*L,Z=a*O+c*M+f*R+v*L;return r[0]=N,r[1]=k,r[2]=F,r[3]=B,r[4]=U,r[5]=V,r[6]=z,r[7]=G,r[8]=W,r[9]=H,r[10]=j,r[11]=q,r[12]=Y,r[13]=X,r[14]=Q,r[15]=Z,r},c.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},c.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},c.multiplyTransformation=function(e,t,r){var i=e[0],n=e[1],o=e[2],a=e[4],s=e[5],l=e[6],u=e[8],c=e[9],d=e[10],h=e[12],p=e[13],f=e[14],m=t[0],g=t[1],_=t[2],v=t[4],y=t[5],b=t[6],C=t[8],S=t[9],w=t[10],T=t[12],E=t[13],A=t[14],x=i*m+a*g+u*_,P=n*m+s*g+c*_,D=o*m+l*g+d*_,I=i*v+a*y+u*b,O=n*v+s*y+c*b,M=o*v+l*y+d*b,R=i*C+a*S+u*w,L=n*C+s*S+c*w,N=o*C+l*S+d*w,k=i*T+a*E+u*A+h,F=n*T+s*E+c*A+p,B=o*T+l*E+d*A+f;return r[0]=x,r[1]=P,r[2]=D,r[3]=0,r[4]=I,r[5]=O,r[6]=M,r[7]=0,r[8]=R,r[9]=L,r[10]=N,r[11]=0,r[12]=k,r[13]=F,r[14]=B,r[15]=1,r},c.multiplyByMatrix3=function(e,t,r){ +var i=e[0],n=e[1],o=e[2],a=e[4],s=e[5],l=e[6],u=e[8],c=e[9],d=e[10],h=t[0],p=t[1],f=t[2],m=t[3],g=t[4],_=t[5],v=t[6],y=t[7],b=t[8],C=i*h+a*p+u*f,S=n*h+s*p+c*f,w=o*h+l*p+d*f,T=i*m+a*g+u*_,E=n*m+s*g+c*_,A=o*m+l*g+d*_,x=i*v+a*y+u*b,P=n*v+s*y+c*b,D=o*v+l*y+d*b;return r[0]=C,r[1]=S,r[2]=w,r[3]=0,r[4]=T,r[5]=E,r[6]=A,r[7]=0,r[8]=x,r[9]=P,r[10]=D,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},c.multiplyByTranslation=function(e,t,r){var i=t.x,n=t.y,o=t.z,a=i*e[0]+n*e[4]+o*e[8]+e[12],s=i*e[1]+n*e[5]+o*e[9]+e[13],l=i*e[2]+n*e[6]+o*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=a,r[13]=s,r[14]=l,r[15]=e[15],r};var g=new e;c.multiplyByUniformScale=function(e,t,r){return g.x=t,g.y=t,g.z=t,c.multiplyByScale(e,g,r)},c.multiplyByScale=function(e,t,r){var i=t.x,n=t.y,o=t.z;return 1===i&&1===n&&1===o?c.clone(e,r):(r[0]=i*e[0],r[1]=i*e[1],r[2]=i*e[2],r[3]=0,r[4]=n*e[4],r[5]=n*e[5],r[6]=n*e[6],r[7]=0,r[8]=o*e[8],r[9]=o*e[9],r[10]=o*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},c.multiplyByVector=function(e,t,r){var i=t.x,n=t.y,o=t.z,a=t.w,s=e[0]*i+e[4]*n+e[8]*o+e[12]*a,l=e[1]*i+e[5]*n+e[9]*o+e[13]*a,u=e[2]*i+e[6]*n+e[10]*o+e[14]*a,c=e[3]*i+e[7]*n+e[11]*o+e[15]*a;return r.x=s,r.y=l,r.z=u,r.w=c,r},c.multiplyByPointAsVector=function(e,t,r){var i=t.x,n=t.y,o=t.z,a=e[0]*i+e[4]*n+e[8]*o,s=e[1]*i+e[5]*n+e[9]*o,l=e[2]*i+e[6]*n+e[10]*o;return r.x=a,r.y=s,r.z=l,r},c.multiplyByPoint=function(e,t,r){var i=t.x,n=t.y,o=t.z,a=e[0]*i+e[4]*n+e[8]*o+e[12],s=e[1]*i+e[5]*n+e[9]*o+e[13],l=e[2]*i+e[6]*n+e[10]*o+e[14];return r.x=a,r.y=s,r.z=l,r},c.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var r=e[1],i=e[2],n=e[3],o=e[6],a=e[7],s=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=i,t[9]=o,t[10]=e[10],t[11]=e[14],t[12]=n,t[13]=a,t[14]=s,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||n(e)&&n(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new l,v=new l,y=new t,b=new t(0,0,0,1);return c.inverse=function(e,r){if(l.equalsEpsilon(c.getRotation(e,_),v,s.EPSILON7)&&t.equals(c.getRow(e,3,y),b))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var i=e[0],n=e[4],o=e[8],a=e[12],d=e[1],h=e[5],p=e[9],f=e[13],m=e[2],g=e[6],C=e[10],S=e[14],w=e[3],T=e[7],E=e[11],A=e[15],x=C*A,P=S*E,D=g*A,I=S*T,O=g*E,M=C*T,R=m*A,L=S*w,N=m*E,k=C*w,F=m*T,B=g*w,U=x*h+I*p+O*f-(P*h+D*p+M*f),V=P*d+R*p+k*f-(x*d+L*p+N*f),z=D*d+L*h+F*f-(I*d+R*h+B*f),G=M*d+N*h+B*p-(O*d+k*h+F*p),W=P*n+D*o+M*a-(x*n+I*o+O*a),H=x*i+L*o+N*a-(P*i+R*o+k*a),j=I*i+R*n+B*a-(D*i+L*n+F*a),q=O*i+k*n+F*o-(M*i+N*n+B*o);x=o*f,P=a*p,D=n*f,I=a*h,O=n*p,M=o*h,R=i*f,L=a*d,N=i*p,k=o*d,F=i*h,B=n*d;var Y=x*T+I*E+O*A-(P*T+D*E+M*A),X=P*w+R*E+k*A-(x*w+L*E+N*A),Q=D*w+L*T+F*A-(I*w+R*T+B*A),Z=M*w+N*T+B*E-(O*w+k*T+F*E),K=D*C+M*S+P*g-(O*S+x*g+I*C),J=N*S+x*m+L*C-(R*C+k*S+P*m),$=R*g+B*S+I*m-(F*S+D*m+L*g),ee=F*C+O*m+k*g-(N*g+B*C+M*m),te=i*U+n*V+o*z+a*G;if(Math.abs(te)<s.EPSILON20)throw new u("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=U*te,r[1]=V*te,r[2]=z*te,r[3]=G*te,r[4]=W*te,r[5]=H*te,r[6]=j*te,r[7]=q*te,r[8]=Y*te,r[9]=X*te,r[10]=Q*te,r[11]=Z*te,r[12]=K*te,r[13]=J*te,r[14]=$*te,r[15]=ee*te,r},c.inverseTransformation=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[4],a=e[5],s=e[6],l=e[8],u=e[9],c=e[10],d=e[12],h=e[13],p=e[14],f=-r*d-i*h-n*p,m=-o*d-a*h-s*p,g=-l*d-u*h-c*p;return t[0]=r,t[1]=o,t[2]=l,t[3]=0,t[4]=i,t[5]=a,t[6]=u,t[7]=0,t[8]=n,t[9]=s,t[10]=c,t[11]=0,t[12]=f,t[13]=m,t[14]=g,t[15]=1,t},c.IDENTITY=a(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=a(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,o(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var f=new e,m=new e,g=new e,_=new e,v=new e,y=new e,b=new e,C=new e,S=new e,w=new e,T=new e,E=new e,A=4/3*r.PI;p.fromPoints=function(t,r){if(o(r)||(r=new p),!o(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i,n=e.clone(t[0],b),a=e.clone(n,f),s=e.clone(n,m),l=e.clone(n,g),u=e.clone(n,_),c=e.clone(n,v),d=e.clone(n,y),h=t.length;for(i=1;i<h;i++){e.clone(t[i],n);var A=n.x,x=n.y,P=n.z;A<a.x&&e.clone(n,a),A>u.x&&e.clone(n,u),x<s.y&&e.clone(n,s),x>c.y&&e.clone(n,c),P<l.z&&e.clone(n,l),P>d.z&&e.clone(n,d)}var D=e.magnitudeSquared(e.subtract(u,a,C)),I=e.magnitudeSquared(e.subtract(c,s,C)),O=e.magnitudeSquared(e.subtract(d,l,C)),M=a,R=u,L=D;I>L&&(L=I,M=s,R=c),O>L&&(L=O,M=l,R=d);var N=S;N.x=.5*(M.x+R.x),N.y=.5*(M.y+R.y),N.z=.5*(M.z+R.z);var k=e.magnitudeSquared(e.subtract(R,N,C)),F=Math.sqrt(k),B=w;B.x=a.x,B.y=s.y,B.z=l.z;var U=T;U.x=u.x,U.y=c.y,U.z=d.z;var V=e.multiplyByScalar(e.add(B,U,C),.5,E),z=0;for(i=0;i<h;i++){e.clone(t[i],n);var G=e.magnitude(e.subtract(n,V,C));G>z&&(z=G);var W=e.magnitudeSquared(e.subtract(n,N,C));if(W>k){var H=Math.sqrt(W);F=.5*(F+H),k=F*F;var j=H-F;N.x=(F*N.x+j*n.x)/H,N.y=(F*N.y+j*n.y)/H,N.z=(F*N.z+j*n.z)/H}}return F<z?(e.clone(N,r.center),r.radius=F):(e.clone(V,r.center),r.radius=z),r};var x=new s,P=new e,D=new e,I=new t,O=new t;p.fromRectangle2D=function(e,t,r){return p.fromRectangleWithHeights2D(e,t,0,0,r)},p.fromRectangleWithHeights2D=function(t,r,i,a,s){if(o(s)||(s=new p),!o(t))return s.center=e.clone(e.ZERO,s.center),s.radius=0,s;r=n(r,x),h.southwest(t,I),I.height=i,h.northeast(t,O),O.height=a;var l=r.project(I,P),u=r.project(O,D),c=u.x-l.x,d=u.y-l.y,f=u.z-l.z;s.radius=.5*Math.sqrt(c*c+d*d+f*f);var m=s.center;return m.x=l.x+.5*c,m.y=l.y+.5*d,m.z=l.z+.5*f,s};var M=[];p.fromRectangle3D=function(t,r,i,s){if(r=n(r,a.WGS84),i=n(i,0),o(s)||(s=new p),!o(t))return s.center=e.clone(e.ZERO,s.center),s.radius=0,s;var l=h.subsample(t,r,i,M);return p.fromPoints(l,s)},p.fromVertices=function(t,r,i,a){if(o(a)||(a=new p),!o(t)||0===t.length)return a.center=e.clone(e.ZERO,a.center),a.radius=0,a;r=n(r,e.ZERO),i=n(i,3);var s=b;s.x=t[0]+r.x,s.y=t[1]+r.y,s.z=t[2]+r.z;var l,u=e.clone(s,f),c=e.clone(s,m),d=e.clone(s,g),h=e.clone(s,_),A=e.clone(s,v),x=e.clone(s,y),P=t.length;for(l=0;l<P;l+=i){var D=t[l]+r.x,I=t[l+1]+r.y,O=t[l+2]+r.z;s.x=D,s.y=I,s.z=O,D<u.x&&e.clone(s,u),D>h.x&&e.clone(s,h),I<c.y&&e.clone(s,c),I>A.y&&e.clone(s,A),O<d.z&&e.clone(s,d),O>x.z&&e.clone(s,x)}var M=e.magnitudeSquared(e.subtract(h,u,C)),R=e.magnitudeSquared(e.subtract(A,c,C)),L=e.magnitudeSquared(e.subtract(x,d,C)),N=u,k=h,F=M;R>F&&(F=R,N=c,k=A),L>F&&(F=L,N=d,k=x);var B=S;B.x=.5*(N.x+k.x),B.y=.5*(N.y+k.y),B.z=.5*(N.z+k.z);var U=e.magnitudeSquared(e.subtract(k,B,C)),V=Math.sqrt(U),z=w;z.x=u.x,z.y=c.y,z.z=d.z;var G=T;G.x=h.x,G.y=A.y,G.z=x.z;var W=e.multiplyByScalar(e.add(z,G,C),.5,E),H=0;for(l=0;l<P;l+=i){s.x=t[l]+r.x,s.y=t[l+1]+r.y,s.z=t[l+2]+r.z;var j=e.magnitude(e.subtract(s,W,C));j>H&&(H=j);var q=e.magnitudeSquared(e.subtract(s,B,C));if(q>U){var Y=Math.sqrt(q);V=.5*(V+Y),U=V*V;var X=Y-V;B.x=(V*B.x+X*s.x)/Y,B.y=(V*B.y+X*s.y)/Y,B.z=(V*B.z+X*s.z)/Y}}return V<H?(e.clone(B,a.center),a.radius=V):(e.clone(W,a.center),a.radius=H),a},p.fromEncodedCartesianVertices=function(t,r,i){if(o(i)||(i=new p),!o(t)||!o(r)||t.length!==r.length||0===t.length)return i.center=e.clone(e.ZERO,i.center),i.radius=0,i;var n=b;n.x=t[0]+r[0],n.y=t[1]+r[1],n.z=t[2]+r[2];var a,s=e.clone(n,f),l=e.clone(n,m),u=e.clone(n,g),c=e.clone(n,_),d=e.clone(n,v),h=e.clone(n,y),A=t.length;for(a=0;a<A;a+=3){var x=t[a]+r[a],P=t[a+1]+r[a+1],D=t[a+2]+r[a+2];n.x=x,n.y=P,n.z=D,x<s.x&&e.clone(n,s),x>c.x&&e.clone(n,c),P<l.y&&e.clone(n,l),P>d.y&&e.clone(n,d),D<u.z&&e.clone(n,u),D>h.z&&e.clone(n,h)}var I=e.magnitudeSquared(e.subtract(c,s,C)),O=e.magnitudeSquared(e.subtract(d,l,C)),M=e.magnitudeSquared(e.subtract(h,u,C)),R=s,L=c,N=I;O>N&&(N=O,R=l,L=d),M>N&&(N=M,R=u,L=h);var k=S;k.x=.5*(R.x+L.x),k.y=.5*(R.y+L.y),k.z=.5*(R.z+L.z);var F=e.magnitudeSquared(e.subtract(L,k,C)),B=Math.sqrt(F),U=w;U.x=s.x,U.y=l.y,U.z=u.z;var V=T;V.x=c.x,V.y=d.y,V.z=h.z;var z=e.multiplyByScalar(e.add(U,V,C),.5,E),G=0;for(a=0;a<A;a+=3){n.x=t[a]+r[a],n.y=t[a+1]+r[a+1],n.z=t[a+2]+r[a+2];var W=e.magnitude(e.subtract(n,z,C));W>G&&(G=W);var H=e.magnitudeSquared(e.subtract(n,k,C));if(H>F){var j=Math.sqrt(H);B=.5*(B+j),F=B*B;var q=j-B;k.x=(B*k.x+q*n.x)/j,k.y=(B*k.y+q*n.y)/j,k.z=(B*k.z+q*n.z)/j}}return B<G?(e.clone(k,i.center),i.radius=B):(e.clone(z,i.center),i.radius=G),i},p.fromCornerPoints=function(t,r,i){o(i)||(i=new p);var n=i.center;return e.add(t,r,n),e.multiplyByScalar(n,.5,n),i.radius=e.distance(n,r),i},p.fromEllipsoid=function(t,r){return o(r)||(r=new p),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var R=new e;p.fromBoundingSpheres=function(t,r){if(o(r)||(r=new p),!o(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=t.length;if(1===i)return p.clone(t[0],r);if(2===i)return p.union(t[0],t[1],r);var n,a=[];for(n=0;n<i;n++)a.push(t[n].center);r=p.fromPoints(a,r);var s=r.center,l=r.radius;for(n=0;n<i;n++){var u=t[n];l=Math.max(l,e.distance(s,u.center,R)+u.radius)}return r.radius=l,r};var L=new e,N=new e,k=new e;p.fromOrientedBoundingBox=function(t,r){o(r)||(r=new p);var i=t.halfAxes,n=c.getColumn(i,0,L),a=c.getColumn(i,1,N),s=c.getColumn(i,2,k);return e.add(n,a,n),e.add(n,s,n),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(n),r},p.clone=function(t,r){if(o(t))return o(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new p(t.center,t.radius)},p.packedLength=4,p.pack=function(e,t,r){r=n(r,0);var i=e.center;return t[r++]=i.x,t[r++]=i.y,t[r++]=i.z,t[r]=e.radius,t},p.unpack=function(e,t,r){t=n(t,0),o(r)||(r=new p);var i=r.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],r.radius=e[t],r};var F=new e,B=new e;p.union=function(t,r,i){o(i)||(i=new p);var n=t.center,a=t.radius,s=r.center,l=r.radius,u=e.subtract(s,n,F),c=e.magnitude(u);if(a>=c+l)return t.clone(i),i;if(l>=c+a)return r.clone(i),i;var d=.5*(a+c+l),h=e.multiplyByScalar(u,(-a+d)/c,B);return e.add(h,n,h),e.clone(h,i.center),i.radius=d,i};var U=new e;p.expand=function(t,r,i){i=p.clone(t,i);var n=e.magnitude(e.subtract(r,i.center,U));return n>i.radius&&(i.radius=n),i},p.intersectPlane=function(t,r){var i=t.center,n=t.radius,o=r.normal,a=e.dot(o,i)+r.distance;return a<-n?l.OUTSIDE:a<n?l.INTERSECTING:l.INSIDE},p.transform=function(e,t,r){return o(r)||(r=new p),r.center=d.multiplyByPoint(t,e.center,r.center),r.radius=d.getMaximumScale(t)*e.radius,r};var V=new e;p.distanceSquaredTo=function(t,r){var i=e.subtract(t.center,r,V);return e.magnitudeSquared(i)-t.radius*t.radius},p.transformWithoutScale=function(e,t,r){return o(r)||(r=new p),r.center=d.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var z=new e;p.computePlaneDistances=function(t,r,i,n){o(n)||(n=new u);var a=e.subtract(t.center,r,z),s=e.dot(i,a);return n.start=s-t.radius,n.stop=s+t.radius,n};for(var G=new e,W=new e,H=new e,j=new e,q=new e,Y=new t,X=new Array(8),Q=0;Q<8;++Q)X[Q]=new e;var Z=new s;return p.projectTo2D=function(t,r,i){r=n(r,Z);var o=r.ellipsoid,a=t.center,s=t.radius,l=o.geodeticSurfaceNormal(a,G),u=e.cross(e.UNIT_Z,l,W);e.normalize(u,u);var c=e.cross(l,u,H);e.normalize(c,c),e.multiplyByScalar(l,s,l),e.multiplyByScalar(c,s,c),e.multiplyByScalar(u,s,u);var d=e.negate(c,q),h=e.negate(u,j),f=X,m=f[0];e.add(l,c,m),e.add(m,u,m),m=f[1],e.add(l,c,m),e.add(m,h,m),m=f[2],e.add(l,d,m),e.add(m,h,m),m=f[3],e.add(l,d,m),e.add(m,u,m),e.negate(l,l),m=f[4],e.add(l,c,m),e.add(m,u,m),m=f[5],e.add(l,c,m),e.add(m,h,m),m=f[6],e.add(l,d,m),e.add(m,h,m),m=f[7],e.add(l,d,m),e.add(m,u,m);for(var g=f.length,_=0;_<g;++_){var v=f[_];e.add(a,v,v);var y=o.cartesianToCartographic(v,Y);r.project(y,v)}i=p.fromPoints(f,i),a=i.center;var b=a.x,C=a.y,S=a.z;return a.x=S,a.y=b,a.z=C,i},p.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},p.equals=function(t,r){return t===r||o(t)&&o(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},p.prototype.intersectPlane=function(e){return p.intersectPlane(this,e)},p.prototype.distanceSquaredTo=function(e){return p.distanceSquaredTo(this,e)},p.prototype.computePlaneDistances=function(e,t,r){return p.computePlaneDistances(this,e,t,r)},p.prototype.isOccluded=function(e){return p.isOccluded(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.volume=function(){var e=this.radius;return A*e*e*e},p}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,i,n,o){"use strict";if(!i.supportsTypedArrays())return{};var a={BYTE:o.BYTE,UNSIGNED_BYTE:o.UNSIGNED_BYTE,SHORT:o.SHORT,UNSIGNED_SHORT:o.UNSIGNED_SHORT,INT:o.INT,UNSIGNED_INT:o.UNSIGNED_INT,FLOAT:o.FLOAT,DOUBLE:o.DOUBLE};return a.getSizeInBytes=function(e){switch(e){case a.BYTE:return Int8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.SHORT:return Int16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.INT:return Int32Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case a.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case a.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},a.fromTypedArray=function(e){return e instanceof Int8Array?a.BYTE:e instanceof Uint8Array?a.UNSIGNED_BYTE:e instanceof Int16Array?a.SHORT:e instanceof Uint16Array?a.UNSIGNED_SHORT:e instanceof Int32Array?a.INT:e instanceof Uint32Array?a.UNSIGNED_INT:e instanceof Float32Array?a.FLOAT:e instanceof Float64Array?a.DOUBLE:void 0},a.validate=function(e){return t(e)&&(e===a.BYTE||e===a.UNSIGNED_BYTE||e===a.SHORT||e===a.UNSIGNED_SHORT||e===a.INT||e===a.UNSIGNED_INT||e===a.FLOAT||e===a.DOUBLE)},a.createTypedArray=function(e,t){switch(e){case a.BYTE:return new Int8Array(t);case a.UNSIGNED_BYTE:return new Uint8Array(t);case a.SHORT:return new Int16Array(t);case a.UNSIGNED_SHORT:return new Uint16Array(t);case a.INT:return new Int32Array(t);case a.UNSIGNED_INT:return new Uint32Array(t);case a.FLOAT:return new Float32Array(t);case a.DOUBLE:return new Float64Array(t)}},a.createArrayBufferView=function(t,r,i,n){switch(i=e(i,0),n=e(n,(r.byteLength-i)/a.getSizeInBytes(t)),t){case a.BYTE:return new Int8Array(r,i,n);case a.UNSIGNED_BYTE:return new Uint8Array(r,i,n);case a.SHORT:return new Int16Array(r,i,n);case a.UNSIGNED_SHORT:return new Uint16Array(r,i,n);case a.INT:return new Int32Array(r,i,n);case a.UNSIGNED_INT:return new Uint32Array(r,i,n);case a.FLOAT:return new Float32Array(r,i,n);case a.DOUBLE:return new Float64Array(r,i,n)}},a.fromName=function(e){switch(e){case"BYTE":return a.BYTE;case"UNSIGNED_BYTE":return a.UNSIGNED_BYTE;case"SHORT":return a.SHORT;case"UNSIGNED_SHORT":return a.UNSIGNED_SHORT;case"INT":return a.INT;case"UNSIGNED_INT":return a.UNSIGNED_INT;case"FLOAT":return a.FLOAT;case"DOUBLE":return a.DOUBLE}},n(a)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,o.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,n.NONE), +this.boundingSphereCV=e.boundingSphereCV}return a.computeNumberOfVertices=function(e){var t=-1;for(var i in e.attributes)if(e.attributes.hasOwnProperty(i)&&r(e.attributes[i])&&r(e.attributes[i].values)){var n=e.attributes[i],o=n.values.length/n.componentsPerAttribute;t=o}return t},a}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return i}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,i){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return n.POSITION_ONLY=i(new n({position:!0})),n.POSITION_AND_NORMAL=i(new n({position:!0,normal:!0})),n.POSITION_NORMAL_AND_ST=i(new n({position:!0,normal:!0,st:!0})),n.POSITION_AND_ST=i(new n({position:!0,st:!0})),n.POSITION_AND_COLOR=i(new n({position:!0,color:!0})),n.ALL=i(new n({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),n.DEFAULT=n.POSITION_NORMAL_AND_ST,n.packedLength=6,n.pack=function(t,r,i){return i=e(i,0),r[i++]=t.position?1:0,r[i++]=t.normal?1:0,r[i++]=t.st?1:0,r[i++]=t.tangent?1:0,r[i++]=t.bitangent?1:0,r[i]=t.color?1:0,r},n.unpack=function(r,i,o){return i=e(i,0),t(o)||(o=new n),o.position=1===r[i++],o.normal=1===r[i++],o.st=1===r[i++],o.tangent=1===r[i++],o.bitangent=1===r[i++],o.color=1===r[i],o},n.clone=function(e,r){if(t(e))return t(r)||(r=new n),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},n}),define("Core/BoxGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e){e=n(e,n.EMPTY_OBJECT);var r=e.minimum,i=e.maximum,o=n(e.vertexFormat,c.DEFAULT);this._minimum=t.clone(r),this._maximum=t.clone(i),this._vertexFormat=o,this._workerName="createBoxGeometry"}var h=new t;d.fromDimensions=function(e){e=n(e,n.EMPTY_OBJECT);var r=e.dimensions,i=t.multiplyByScalar(r,.5,new t);return new d({minimum:t.negate(i,new t),maximum:i,vertexFormat:e.vertexFormat})},d.fromAxisAlignedBoundingBox=function(e){return new d({minimum:e.minimum,maximum:e.maximum})},d.packedLength=2*t.packedLength+c.packedLength,d.pack=function(e,r,i){return i=n(i,0),t.pack(e._minimum,r,i),t.pack(e._maximum,r,i+t.packedLength),c.pack(e._vertexFormat,r,i+2*t.packedLength),r};var p=new t,f=new t,m=new c,g={minimum:p,maximum:f,vertexFormat:m};d.unpack=function(e,r,i){r=n(r,0);var a=t.unpack(e,r,p),s=t.unpack(e,r+t.packedLength,f),l=c.unpack(e,r+2*t.packedLength,m);return o(i)?(i._minimum=t.clone(a,i._minimum),i._maximum=t.clone(s,i._maximum),i._vertexFormat=c.clone(l,i._vertexFormat),i):new d(g)},d.createGeometry=function(r){var n=r._minimum,o=r._maximum,c=r._vertexFormat;if(!t.equals(n,o)){var d,p,f=new l;if(c.position&&(c.st||c.normal||c.tangent||c.bitangent)){if(c.position&&(p=new Float64Array(72),p[0]=n.x,p[1]=n.y,p[2]=o.z,p[3]=o.x,p[4]=n.y,p[5]=o.z,p[6]=o.x,p[7]=o.y,p[8]=o.z,p[9]=n.x,p[10]=o.y,p[11]=o.z,p[12]=n.x,p[13]=n.y,p[14]=n.z,p[15]=o.x,p[16]=n.y,p[17]=n.z,p[18]=o.x,p[19]=o.y,p[20]=n.z,p[21]=n.x,p[22]=o.y,p[23]=n.z,p[24]=o.x,p[25]=n.y,p[26]=n.z,p[27]=o.x,p[28]=o.y,p[29]=n.z,p[30]=o.x,p[31]=o.y,p[32]=o.z,p[33]=o.x,p[34]=n.y,p[35]=o.z,p[36]=n.x,p[37]=n.y,p[38]=n.z,p[39]=n.x,p[40]=o.y,p[41]=n.z,p[42]=n.x,p[43]=o.y,p[44]=o.z,p[45]=n.x,p[46]=n.y,p[47]=o.z,p[48]=n.x,p[49]=o.y,p[50]=n.z,p[51]=o.x,p[52]=o.y,p[53]=n.z,p[54]=o.x,p[55]=o.y,p[56]=o.z,p[57]=n.x,p[58]=o.y,p[59]=o.z,p[60]=n.x,p[61]=n.y,p[62]=n.z,p[63]=o.x,p[64]=n.y,p[65]=n.z,p[66]=o.x,p[67]=n.y,p[68]=o.z,p[69]=n.x,p[70]=n.y,p[71]=o.z,f.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:p})),c.normal){var m=new Float32Array(72);m[0]=0,m[1]=0,m[2]=1,m[3]=0,m[4]=0,m[5]=1,m[6]=0,m[7]=0,m[8]=1,m[9]=0,m[10]=0,m[11]=1,m[12]=0,m[13]=0,m[14]=-1,m[15]=0,m[16]=0,m[17]=-1,m[18]=0,m[19]=0,m[20]=-1,m[21]=0,m[22]=0,m[23]=-1,m[24]=1,m[25]=0,m[26]=0,m[27]=1,m[28]=0,m[29]=0,m[30]=1,m[31]=0,m[32]=0,m[33]=1,m[34]=0,m[35]=0,m[36]=-1,m[37]=0,m[38]=0,m[39]=-1,m[40]=0,m[41]=0,m[42]=-1,m[43]=0,m[44]=0,m[45]=-1,m[46]=0,m[47]=0,m[48]=0,m[49]=1,m[50]=0,m[51]=0,m[52]=1,m[53]=0,m[54]=0,m[55]=1,m[56]=0,m[57]=0,m[58]=1,m[59]=0,m[60]=0,m[61]=-1,m[62]=0,m[63]=0,m[64]=-1,m[65]=0,m[66]=0,m[67]=-1,m[68]=0,m[69]=0,m[70]=-1,m[71]=0,f.normal=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:m})}if(c.st){var g=new Float32Array(48);g[0]=0,g[1]=0,g[2]=1,g[3]=0,g[4]=1,g[5]=1,g[6]=0,g[7]=1,g[8]=1,g[9]=0,g[10]=0,g[11]=0,g[12]=0,g[13]=1,g[14]=1,g[15]=1,g[16]=0,g[17]=0,g[18]=1,g[19]=0,g[20]=1,g[21]=1,g[22]=0,g[23]=1,g[24]=1,g[25]=0,g[26]=0,g[27]=0,g[28]=0,g[29]=1,g[30]=1,g[31]=1,g[32]=1,g[33]=0,g[34]=0,g[35]=0,g[36]=0,g[37]=1,g[38]=1,g[39]=1,g[40]=0,g[41]=0,g[42]=1,g[43]=0,g[44]=1,g[45]=1,g[46]=0,g[47]=1,f.st=new s({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:g})}if(c.tangent){var _=new Float32Array(72);_[0]=1,_[1]=0,_[2]=0,_[3]=1,_[4]=0,_[5]=0,_[6]=1,_[7]=0,_[8]=0,_[9]=1,_[10]=0,_[11]=0,_[12]=-1,_[13]=0,_[14]=0,_[15]=-1,_[16]=0,_[17]=0,_[18]=-1,_[19]=0,_[20]=0,_[21]=-1,_[22]=0,_[23]=0,_[24]=0,_[25]=1,_[26]=0,_[27]=0,_[28]=1,_[29]=0,_[30]=0,_[31]=1,_[32]=0,_[33]=0,_[34]=1,_[35]=0,_[36]=0,_[37]=-1,_[38]=0,_[39]=0,_[40]=-1,_[41]=0,_[42]=0,_[43]=-1,_[44]=0,_[45]=0,_[46]=-1,_[47]=0,_[48]=-1,_[49]=0,_[50]=0,_[51]=-1,_[52]=0,_[53]=0,_[54]=-1,_[55]=0,_[56]=0,_[57]=-1,_[58]=0,_[59]=0,_[60]=1,_[61]=0,_[62]=0,_[63]=1,_[64]=0,_[65]=0,_[66]=1,_[67]=0,_[68]=0,_[69]=1,_[70]=0,_[71]=0,f.tangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:_})}if(c.bitangent){var v=new Float32Array(72);v[0]=0,v[1]=1,v[2]=0,v[3]=0,v[4]=1,v[5]=0,v[6]=0,v[7]=1,v[8]=0,v[9]=0,v[10]=1,v[11]=0,v[12]=0,v[13]=1,v[14]=0,v[15]=0,v[16]=1,v[17]=0,v[18]=0,v[19]=1,v[20]=0,v[21]=0,v[22]=1,v[23]=0,v[24]=0,v[25]=0,v[26]=1,v[27]=0,v[28]=0,v[29]=1,v[30]=0,v[31]=0,v[32]=1,v[33]=0,v[34]=0,v[35]=1,v[36]=0,v[37]=0,v[38]=1,v[39]=0,v[40]=0,v[41]=1,v[42]=0,v[43]=0,v[44]=1,v[45]=0,v[46]=0,v[47]=1,v[48]=0,v[49]=0,v[50]=1,v[51]=0,v[52]=0,v[53]=1,v[54]=0,v[55]=0,v[56]=1,v[57]=0,v[58]=0,v[59]=1,v[60]=0,v[61]=0,v[62]=1,v[63]=0,v[64]=0,v[65]=1,v[66]=0,v[67]=0,v[68]=1,v[69]=0,v[70]=0,v[71]=1,f.bitangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:v})}d=new Uint16Array(36),d[0]=0,d[1]=1,d[2]=2,d[3]=0,d[4]=2,d[5]=3,d[6]=6,d[7]=5,d[8]=4,d[9]=7,d[10]=6,d[11]=4,d[12]=8,d[13]=9,d[14]=10,d[15]=8,d[16]=10,d[17]=11,d[18]=14,d[19]=13,d[20]=12,d[21]=15,d[22]=14,d[23]=12,d[24]=18,d[25]=17,d[26]=16,d[27]=19,d[28]=18,d[29]=16,d[30]=20,d[31]=21,d[32]=22,d[33]=20,d[34]=22,d[35]=23}else p=new Float64Array(24),p[0]=n.x,p[1]=n.y,p[2]=n.z,p[3]=o.x,p[4]=n.y,p[5]=n.z,p[6]=o.x,p[7]=o.y,p[8]=n.z,p[9]=n.x,p[10]=o.y,p[11]=n.z,p[12]=n.x,p[13]=n.y,p[14]=o.z,p[15]=o.x,p[16]=n.y,p[17]=o.z,p[18]=o.x,p[19]=o.y,p[20]=o.z,p[21]=n.x,p[22]=o.y,p[23]=o.z,f.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:p}),d=new Uint16Array(36),d[0]=4,d[1]=5,d[2]=6,d[3]=4,d[4]=6,d[5]=7,d[6]=1,d[7]=0,d[8]=3,d[9]=1,d[10]=3,d[11]=2,d[12]=1,d[13]=6,d[14]=5,d[15]=1,d[16]=2,d[17]=6,d[18]=2,d[19]=3,d[20]=7,d[21]=2,d[22]=7,d[23]=6,d[24]=3,d[25]=0,d[26]=4,d[27]=3,d[28]=4,d[29]=7,d[30]=0,d[31]=1,d[32]=5,d[33]=0,d[34]=5,d[35]=4;var y=t.subtract(o,n,h),b=.5*t.magnitude(y);return new a({attributes:f,indices:d,primitiveType:u.TRIANGLES,boundingSphere:new e(t.ZERO,b)})}};var _;return d.getUnitBox=function(){return o(_)||(_=d.createGeometry(d.fromDimensions({dimensions:new t(1,1,1),vertexFormat:c.POSITION_ONLY}))),_},d}),define("Core/BoxOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e){e=n(e,n.EMPTY_OBJECT);var r=e.minimum,i=e.maximum;this._min=t.clone(r),this._max=t.clone(i),this._workerName="createBoxOutlineGeometry"}var d=new t;c.fromDimensions=function(e){e=n(e,n.EMPTY_OBJECT);var r=e.dimensions,i=t.multiplyByScalar(r,.5,new t);return new c({minimum:t.negate(i,new t),maximum:i})},c.fromAxisAlignedBoundingBox=function(e){return new c({minimum:e.minimum,maximum:e.maximum})},c.packedLength=2*t.packedLength,c.pack=function(e,r,i){return i=n(i,0),t.pack(e._min,r,i),t.pack(e._max,r,i+t.packedLength),r};var h=new t,p=new t,f={minimum:h,maximum:p};return c.unpack=function(e,r,i){r=n(r,0);var a=t.unpack(e,r,h),s=t.unpack(e,r+t.packedLength,p);return o(i)?(i._min=t.clone(a,i._min),i._max=t.clone(s,i._max),i):new c(f)},c.createGeometry=function(r){var n=r._min,o=r._max;if(!t.equals(n,o)){var c=new l,h=new Uint16Array(24),p=new Float64Array(24);p[0]=n.x,p[1]=n.y,p[2]=n.z,p[3]=o.x,p[4]=n.y,p[5]=n.z,p[6]=o.x,p[7]=o.y,p[8]=n.z,p[9]=n.x,p[10]=o.y,p[11]=n.z,p[12]=n.x,p[13]=n.y,p[14]=o.z,p[15]=o.x,p[16]=n.y,p[17]=o.z,p[18]=o.x,p[19]=o.y,p[20]=o.z,p[21]=n.x,p[22]=o.y,p[23]=o.z,c.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:p}),h[0]=4,h[1]=5,h[2]=5,h[3]=6,h[4]=6,h[5]=7,h[6]=7,h[7]=4,h[8]=0,h[9]=1,h[10]=1,h[11]=2,h[12]=2,h[13]=3,h[14]=3,h[15]=0,h[16]=0,h[17]=4,h[18]=1,h[19]=5,h[20]=2,h[21]=6,h[22]=3,h[23]=7;var f=t.subtract(o,n,d),m=.5*t.magnitude(f);return new a({attributes:c,indices:h,primitiveType:u.LINES,boundingSphere:new e(t.ZERO,m)})}},c}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,r,i,n){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var i=e[t].getAttribute("src"),n=p.exec(i);if(null!==n)return n[1]}}function a(){if(t(c))return c;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),c=new i({url:e})}function s(e){return n.toUrl("../"+e)}function l(e){return a().getDerivedResource({url:e}).url}function u(e){t(d)||(d=t(define.amd)&&!define.amd.toUrlUndefined&&t(n.toUrl)?s:l),t(h)||(h=document.createElement("a"));var r=d(e);return h.href=r,h.href=h.href,h.href}var c,d,h,p=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return u._cesiumScriptRegex=p,u.setBaseUrl=function(e){c=i.DEFAULT.getDerivedResource({url:e})},u}),define("Core/cancelAnimationFrame",["./defined"],function(e){"use strict";function t(e){r(e)}if("undefined"!=typeof window){var r=window.cancelAnimationFrame;return function(){if(!e(r))for(var t=["webkit","moz","ms","o"],i=0,n=t.length;i<n&&!e(r);)r=window[t[i]+"CancelAnimationFrame"],e(r)||(r=window[t[i]+"CancelRequestAnimationFrame"]),++i;e(r)||(r=clearTimeout)}(),t}}),define("Core/CartographicGeocoderService",["../ThirdParty/when","./Cartesian3","./Check"],function(e,t,r){"use strict";function i(){}return i.prototype.geocode=function(r){var i=r.match(/[^\s,\n]+/g);if(2===i.length||3===i.length){var n=+i[0],o=+i[1],a=3===i.length?+i[2]:300;if(isNaN(n)&&isNaN(o))for(var s=/^(\d+.?\d*)([nsew])/i,l=0;l<i.length;++l){var u=i[l].match(s);s.test(i[l])&&3===u.length&&(/^[ns]/i.test(u[2])?o=/^[n]/i.test(u[2])?+u[1]:-u[1]:/^[ew]/i.test(u[2])&&(n=/^[e]/i.test(u[2])?+u[1]:-u[1]))}if(!isNaN(n)&&!isNaN(o)&&!isNaN(a)){var c={displayName:r,destination:t.fromDegrees(n,o,a)};return e.resolve([c])}}return e.resolve([])},i}),define("Core/Spline",["./Check","./defaultValue","./defined","./DeveloperError","./Math"],function(e,t,r,i,n){"use strict";function o(){this.times=void 0,this.points=void 0,i.throwInstantiationError()}return o.prototype.evaluate=i.throwInstantiationError,o.prototype.findTimeInterval=function(e,r){var i=this.times,n=i.length;if(r=t(r,0),e>=i[r]){if(r+1<n&&e<i[r+1])return r;if(r+2<n&&e<i[r+2])return r+1}else if(r-1>=0&&e>=i[r-1])return r-1;var o;if(e>i[r])for(o=r;o<n-1&&!(e>=i[o]&&e<i[o+1]);++o);else for(o=r-1;o>=0&&!(e>=i[o]&&e<i[o+1]);--o);return o===n-1&&(o=n-2),o},o.prototype.wrapTime=function(e){var t,r=this.times,i=r[r.length-1],n=r[0],o=i-n;return e<n&&(t=Math.floor((n-e)/o)+1,e+=t*o),e>i&&(t=Math.floor((e-i)/o)+1,e-=t*o),e},o.prototype.clampTime=function(e){var t=this.times;return n.clamp(e,t[0],t[t.length-1])},o}),define("Core/LinearSpline",["./Cartesian3","./defaultValue","./defined","./defineProperties","./DeveloperError","./Spline"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT);var r=e.points,i=e.times;this._times=i,this._points=r,this._lastTimeIndex=0}return i(a.prototype,{times:{get:function(){return this._times}},points:{get:function(){return this._points}}}),a.prototype.findTimeInterval=o.prototype.findTimeInterval,a.prototype.wrapTime=o.prototype.wrapTime,a.prototype.clampTime=o.prototype.clampTime,a.prototype.evaluate=function(t,i){var n=this.points,o=this.times,a=this._lastTimeIndex=this.findTimeInterval(t,this._lastTimeIndex),s=(t-o[a])/(o[a+1]-o[a]);return r(i)||(i=new e),e.lerp(n[a],n[a+1],s,i)},a}),define("Core/TridiagonalSystemSolver",["./Cartesian3","./defined","./DeveloperError"],function(e,t,r){"use strict";var i={};return i.solve=function(t,r,i,n){var o,a=new Array(i.length),s=new Array(n.length),l=new Array(n.length);for(o=0;o<s.length;o++)s[o]=new e,l[o]=new e;a[0]=i[0]/r[0],s[0]=e.multiplyByScalar(n[0],1/r[0],s[0]);var u;for(o=1;o<a.length;++o)u=1/(r[o]-a[o-1]*t[o-1]),a[o]=i[o]*u,s[o]=e.subtract(n[o],e.multiplyByScalar(s[o-1],t[o-1],s[o]),s[o]),s[o]=e.multiplyByScalar(s[o],u,s[o]);for(u=1/(r[o]-a[o-1]*t[o-1]),s[o]=e.subtract(n[o],e.multiplyByScalar(s[o-1],t[o-1],s[o]),s[o]),s[o]=e.multiplyByScalar(s[o],u,s[o]),l[l.length-1]=s[s.length-1],o=l.length-2;o>=0;--o)l[o]=e.subtract(s[o],e.multiplyByScalar(l[o+1],a[o],l[o]),l[o]);return l},i}),define("Core/HermiteSpline",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./LinearSpline","./Matrix4","./Spline","./TridiagonalSystemSolver"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r,n){var o=p,a=m,s=f,l=g;o.length=a.length=t.length-1,s.length=l.length=t.length;var c;o[0]=s[0]=1,a[0]=0;var d=l[0];for(i(d)||(d=l[0]=new e),e.clone(r,d),c=1;c<o.length-1;++c)o[c]=a[c]=1,s[c]=4,d=l[c],i(d)||(d=l[c]=new e),e.subtract(t[c+1],t[c-1],d),e.multiplyByScalar(d,3,d);return o[c]=0,a[c]=1,s[c]=4,d=l[c],i(d)||(d=l[c]=new e),e.subtract(t[c+1],t[c-1],d),e.multiplyByScalar(d,3,d),s[c+1]=1,d=l[c+1],i(d)||(d=l[c+1]=new e),e.clone(n,d),u.solve(o,s,a,l)}function d(t){var r=p,n=m,o=f,a=g;r.length=n.length=t.length-1,o.length=a.length=t.length;var s;r[0]=n[0]=1,o[0]=2;var l=a[0];for(i(l)||(l=a[0]=new e),e.subtract(t[1],t[0],l),e.multiplyByScalar(l,3,l),s=1;s<r.length;++s)r[s]=n[s]=1,o[s]=4,l=a[s],i(l)||(l=a[s]=new e),e.subtract(t[s+1],t[s-1],l),e.multiplyByScalar(l,3,l);return o[s]=2,l=a[s],i(l)||(l=a[s]=new e),e.subtract(t[s],t[s-1],l),e.multiplyByScalar(l,3,l),u.solve(r,o,n,a)}function h(e){e=r(e,r.EMPTY_OBJECT);var t=e.points,i=e.times,n=e.inTangents,o=e.outTangents;this._times=i,this._points=t,this._inTangents=n,this._outTangents=o,this._lastTimeIndex=0}var p=[],f=[],m=[],g=[];n(h.prototype,{times:{get:function(){return this._times}},points:{get:function(){return this._points}},inTangents:{get:function(){return this._inTangents}},outTangents:{get:function(){return this._outTangents}}}),h.createC1=function(e){e=r(e,r.EMPTY_OBJECT);var t=e.times,i=e.points,n=e.tangents,o=n.slice(0,n.length-1);return new h({times:t,points:i,inTangents:n.slice(1,n.length),outTangents:o})},h.createNaturalCubic=function(e){e=r(e,r.EMPTY_OBJECT);var t=e.times,i=e.points;if(i.length<3)return new a({points:i,times:t});var n=d(i),o=n.slice(0,n.length-1);return new h({times:t,points:i,inTangents:n.slice(1,n.length),outTangents:o})},h.createClampedCubic=function(e){e=r(e,r.EMPTY_OBJECT);var t=e.times,i=e.points,n=e.firstTangent,o=e.lastTangent;if(i.length<3)return new a({points:i,times:t});var s=c(i,n,o),l=s.slice(0,s.length-1);return new h({times:t,points:i,inTangents:s.slice(1,s.length),outTangents:l})},h.hermiteCoefficientMatrix=new s(2,-3,0,1,-2,3,0,0,1,-2,1,0,1,-1,0,0),h.prototype.findTimeInterval=l.prototype.findTimeInterval;var _=new t,v=new e;return h.prototype.wrapTime=l.prototype.wrapTime,h.prototype.clampTime=l.prototype.clampTime,h.prototype.evaluate=function(t,r){i(r)||(r=new e);var n=this.points,o=this.times,a=this.inTangents,l=this.outTangents,u=this._lastTimeIndex=this.findTimeInterval(t,this._lastTimeIndex),c=(t-o[u])/(o[u+1]-o[u]),d=_;d.z=c,d.y=c*c,d.x=d.y*c,d.w=1;var p=s.multiplyByVector(h.hermiteCoefficientMatrix,d,d);return r=e.multiplyByScalar(n[u],p.x,r),e.multiplyByScalar(n[u+1],p.y,v),e.add(r,v,r),e.multiplyByScalar(l[u],p.z,v),e.add(r,v,r),e.multiplyByScalar(a[u],p.w,v),e.add(r,v,r)},h}),define("Core/CatmullRomSpline",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./HermiteSpline","./Matrix4","./Spline"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t){var r=t.points,i=t.times;if(r.length<3){var o=i[0],l=1/(i[1]-o),u=r[0],f=r[1];return function(t,r){n(r)||(r=new e);var i=(t-o)*l;return e.lerp(u,f,i,r)}}return function(o,l){n(l)||(l=new e);var u=t._lastTimeIndex=t.findTimeInterval(o,t._lastTimeIndex),f=(o-i[u])/(i[u+1]-i[u]),m=d;m.z=f,m.y=f*f,m.x=m.y*f,m.w=1;var g,_,v,y,b;return 0===u?(g=r[0],_=r[1],v=t.firstTangent,y=e.subtract(r[2],g,h),e.multiplyByScalar(y,.5,y),b=s.multiplyByVector(a.hermiteCoefficientMatrix,m,m)):u===r.length-2?(g=r[u],_=r[u+1],y=t.lastTangent,v=e.subtract(_,r[u-1],h),e.multiplyByScalar(v,.5,v),b=s.multiplyByVector(a.hermiteCoefficientMatrix,m,m)):(g=r[u-1],_=r[u],v=r[u+1],y=r[u+2],b=s.multiplyByVector(c.catmullRomCoefficientMatrix,m,m)),l=e.multiplyByScalar(g,b.x,l),e.multiplyByScalar(_,b.y,p),e.add(l,p,l),e.multiplyByScalar(v,b.z,p),e.add(l,p,l),e.multiplyByScalar(y,b.w,p),e.add(l,p,l)}}function c(t){t=i(t,i.EMPTY_OBJECT);var r=t.points,o=t.times,a=t.firstTangent,s=t.lastTangent;if(r.length>2&&(n(a)||(a=f,e.multiplyByScalar(r[1],2,a),e.subtract(a,r[2],a),e.subtract(a,r[0],a),e.multiplyByScalar(a,.5,a)),!n(s))){var l=r.length-1;s=m,e.multiplyByScalar(r[l-1],2,s),e.subtract(r[l],s,s),e.add(s,r[l-2],s),e.multiplyByScalar(s,.5,s)}this._times=o,this._points=r,this._firstTangent=e.clone(a),this._lastTangent=e.clone(s),this._evaluateFunction=u(this),this._lastTimeIndex=0}var d=new t,h=new e,p=new e,f=new e,m=new e;return o(c.prototype,{times:{get:function(){return this._times}},points:{get:function(){return this._points}},firstTangent:{get:function(){return this._firstTangent}},lastTangent:{get:function(){return this._lastTangent}}}),c.catmullRomCoefficientMatrix=new s(-.5,1,-.5,0,1.5,-2.5,0,1,-1.5,2,.5,0,.5,-.5,0,0),c.prototype.findTimeInterval=l.prototype.findTimeInterval,c.prototype.wrapTime=l.prototype.wrapTime,c.prototype.clampTime=l.prototype.clampTime,c.prototype.evaluate=function(e,t){return this._evaluateFunction(e,t)},c}),define("Core/GeographicTilingScheme",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./GeographicProjection","./Math","./Rectangle"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e){e=r(e,{}),this._ellipsoid=r(e.ellipsoid,o.WGS84),this._rectangle=r(e.rectangle,l.MAX_VALUE),this._projection=new a(this._ellipsoid),this._numberOfLevelZeroTilesX=r(e.numberOfLevelZeroTilesX,2),this._numberOfLevelZeroTilesY=r(e.numberOfLevelZeroTilesY,1)}return n(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},rectangle:{get:function(){return this._rectangle}},projection:{get:function(){return this._projection}}}),u.prototype.getNumberOfXTilesAtLevel=function(e){return this._numberOfLevelZeroTilesX<<e},u.prototype.getNumberOfYTilesAtLevel=function(e){return this._numberOfLevelZeroTilesY<<e},u.prototype.rectangleToNativeRectangle=function(e,t){var r=s.toDegrees(e.west),n=s.toDegrees(e.south),o=s.toDegrees(e.east),a=s.toDegrees(e.north);return i(t)?(t.west=r,t.south=n,t.east=o,t.north=a,t):new l(r,n,o,a)},u.prototype.tileXYToNativeRectangle=function(e,t,r,i){var n=this.tileXYToRectangle(e,t,r,i);return n.west=s.toDegrees(n.west),n.south=s.toDegrees(n.south),n.east=s.toDegrees(n.east),n.north=s.toDegrees(n.north),n},u.prototype.tileXYToRectangle=function(e,t,r,n){var o=this._rectangle,a=this.getNumberOfXTilesAtLevel(r),s=this.getNumberOfYTilesAtLevel(r),u=o.width/a,c=e*u+o.west,d=(e+1)*u+o.west,h=o.height/s,p=o.north-t*h,f=o.north-(t+1)*h;return i(n)||(n=new l(c,f,d,p)),n.west=c,n.south=f,n.east=d,n.north=p,n},u.prototype.positionToTileXY=function(t,r,n){var o=this._rectangle;if(l.contains(o,t)){var a=this.getNumberOfXTilesAtLevel(r),u=this.getNumberOfYTilesAtLevel(r),c=o.width/a,d=o.height/u,h=t.longitude;o.east<o.west&&(h+=s.TWO_PI);var p=(h-o.west)/c|0;p>=a&&(p=a-1);var f=(o.north-t.latitude)/d|0;return f>=u&&(f=u-1),i(n)?(n.x=p,n.y=f,n):new e(p,f)}},u}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,r,i,n,o,a){"use strict";function s(e,r){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,n(r)&&(this.cameraPosition=r)}function l(e,r,i){var n=e.transformPositionToScaledSpace(r,f),o=t.magnitudeSquared(n),a=Math.sqrt(o),s=t.divideByScalar(n,a,m);o=Math.max(1,o),a=Math.max(1,a);var l=t.dot(s,i),u=t.magnitude(t.cross(s,i,s)),c=1/a;return 1/(l*c-u*(Math.sqrt(o-1)*c))}function u(e,r,i){if(!(r<=0||r===1/0||r!==r))return t.multiplyByScalar(e,r,i)}function c(e,r){return t.equals(r,t.ZERO)?r:(e.transformPositionToScaledSpace(r,g),t.normalize(g,g))}o(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var r=this._ellipsoid,i=r.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),n=t.magnitudeSquared(i)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=i,this._distanceToLimbInScaledSpaceSquared=n}}});var d=new t;s.prototype.isPointVisible=function(e){var t=this._ellipsoid,r=t.transformPositionToScaledSpace(e,d);return this.isScaledSpacePointVisible(r)},s.prototype.isScaledSpacePointVisible=function(e){var r=this._cameraPositionInScaledSpace,i=this._distanceToLimbInScaledSpaceSquared,n=t.subtract(e,r,d),o=-t.dot(n,r);return!(i<0?o>0:o>i&&o*o/t.magnitudeSquared(n)>i)},s.prototype.computeHorizonCullingPoint=function(e,r,i){n(i)||(i=new t);for(var o=this._ellipsoid,a=c(o,e),s=0,d=0,h=r.length;d<h;++d){var p=r[d],f=l(o,p,a);s=Math.max(s,f)}return u(a,s,i)};var h=new t;s.prototype.computeHorizonCullingPointFromVertices=function(e,r,o,a,s){n(s)||(s=new t),a=i(a,t.ZERO);for(var d=this._ellipsoid,p=c(d,e),f=0,m=0,g=r.length;m<g;m+=o){h.x=r[m]+a.x,h.y=r[m+1]+a.y,h.z=r[m+2]+a.z;var _=l(d,h,p);f=Math.max(f,_)}return u(p,f,s)};var p=[];s.prototype.computeHorizonCullingPointFromRectangle=function(r,i,n){var o=a.subsample(r,i,0,p),s=e.fromPoints(o);if(!(t.magnitude(s.center)<.1*i.minimumRadius))return this.computeHorizonCullingPoint(s.center,o,n)};var f=new t,m=new t,g=new t;return s}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,i){var n=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(r)))<i?0:n}var i={};return i.computeDiscriminant=function(e,t,r){return t*t-4*e*r},i.computeRealRoots=function(e,i,n){var o;if(0===e)return 0===i?[]:[-n/i];if(0===i){if(0===n)return[0,0];var a=Math.abs(n),s=Math.abs(e);if(a<s&&a/s<t.EPSILON14)return[0,0];if(a>s&&s/a<t.EPSILON14)return[];if((o=-n/e)<0)return[];var l=Math.sqrt(o);return[-l,l]}if(0===n)return o=-i/e,o<0?[o,0]:[0,o];var u=i*i,c=4*e*n,d=r(u,-c,t.EPSILON14);if(d<0)return[];var h=-.5*r(i,t.sign(i)*Math.sqrt(d),t.EPSILON14);return i>0?[h/e,n/h]:[n/h,h/e]},i}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,i){var n,o,a=e,s=t/3,l=r/3,u=i,c=a*l,d=s*u,h=s*s,p=l*l,f=a*l-h,m=a*u-s*l,g=s*u-p,_=4*f*g-m*m;if(_<0){var v,y,b;h*d>=c*p?(v=a,y=f,b=-2*s*f+a*m):(v=u,y=g,b=-u*m+2*l*g);var C=b<0?-1:1,S=-C*Math.abs(v)*Math.sqrt(-_);o=-b+S;var w=o/2,T=w<0?-Math.pow(-w,1/3):Math.pow(w,1/3),E=o===S?-T:-y/T;return n=y<=0?T+E:-b/(T*T+E*E+y),h*d>=c*p?[(n-s)/a]:[-u/(n+l)]}var A=f,x=-2*s*f+a*m,P=g,D=-u*m+2*l*g,I=Math.sqrt(_),O=Math.sqrt(3)/2,M=Math.abs(Math.atan2(a*I,-x)/3);n=2*Math.sqrt(-A);var R=Math.cos(M);o=n*R;var L=n*(-R/2-O*Math.sin(M)),N=o+L>2*s?o-s:L-s,k=a,F=N/k;M=Math.abs(Math.atan2(u*I,-D)/3),n=2*Math.sqrt(-P),R=Math.cos(M),o=n*R,L=n*(-R/2-O*Math.sin(M));var B=-u,U=o+L<2*l?o+l:L+l,V=B/U,z=k*U,G=-N*U-k*B,W=N*B,H=(l*G-s*W)/(-s*G+l*z);return F<=H?F<=V?H<=V?[F,H,V]:[F,V,H]:[V,F,H]:F<=V?[H,F,V]:H<=V?[H,V,F]:[V,H,F]}var i={};return i.computeDiscriminant=function(e,t,r,i){var n=e*e,o=t*t,a=r*r;return 18*e*t*r*i+o*a-27*n*(i*i)-4*(e*a*r+o*t*i)},i.computeRealRoots=function(e,i,n,o){var a,s;if(0===e)return t.computeRealRoots(i,n,o);if(0===i){if(0===n){if(0===o)return[0,0,0];s=-o/e;var l=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3);return[l,l,l]}return 0===o?(a=t.computeRealRoots(e,0,n),0===a.Length?[0]:[a[0],0,a[1]]):r(e,0,n,o)}return 0===n?0===o?(s=-i/e,s<0?[s,0,0]:[0,0,s]):r(e,i,0,o):0===o?(a=t.computeRealRoots(e,i,n),0===a.length?[0]:a[1]<=0?[a[0],a[1],0]:a[0]>=0?[0,a[0],a[1]]:[a[0],0,a[1]]):r(e,i,n,o)},i}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,i){"use strict";function n(t,n,o,a){var s=t*t,l=n-3*s/8,u=o-n*t/2+s*t/8,c=a-o*t/4+n*s/16-3*s*s/256,d=e.computeRealRoots(1,2*l,l*l-4*c,-u*u);if(d.length>0){var h=-t/4,p=d[d.length-1];if(Math.abs(p)<r.EPSILON14){var f=i.computeRealRoots(1,l,c);if(2===f.length){var m,g=f[0],_=f[1];if(g>=0&&_>=0){var v=Math.sqrt(g),y=Math.sqrt(_);return[h-y,h-v,h+v,h+y]}if(g>=0&&_<0)return m=Math.sqrt(g),[h-m,h+m];if(g<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(p>0){var b=Math.sqrt(p),C=(l+p-u/b)/2,S=(l+p+u/b)/2,w=i.computeRealRoots(1,b,C),T=i.computeRealRoots(1,-b,S);return 0!==w.length?(w[0]+=h,w[1]+=h,0!==T.length?(T[0]+=h,T[1]+=h,w[1]<=T[0]?[w[0],w[1],T[0],T[1]]:T[1]<=w[0]?[T[0],T[1],w[0],w[1]]:w[0]>=T[0]&&w[1]<=T[1]?[T[0],w[0],w[1],T[1]]:T[0]>=w[0]&&T[1]<=w[1]?[w[0],T[0],T[1],w[1]]:w[0]>T[0]&&w[0]<T[1]?[T[0],w[0],T[1],w[1]]:[w[0],T[0],w[1],T[1]]):w):0!==T.length?(T[0]+=h,T[1]+=h,T):[]}}return[]}function o(t,n,o,a){var s=o*o,l=n*n,u=t*t,c=-2*n,d=o*t+l-4*a,h=u*a-o*n*t+s,p=e.computeRealRoots(1,c,d,h);if(p.length>0){var f,m,g=p[0],_=n-g,v=_*_,y=t/2,b=_/2,C=v-4*a,S=v+4*Math.abs(a),w=u-4*g,T=u+4*Math.abs(g);if(g<0||C*T<w*S){var E=Math.sqrt(w);f=E/2,m=0===E?0:(t*b-o)/E}else{var A=Math.sqrt(C);f=0===A?0:(t*b-o)/A,m=A/2}var x,P;0===y&&0===f?(x=0,P=0):r.sign(y)===r.sign(f)?(x=y+f,P=g/x):(P=y-f,x=g/P);var D,I;0===b&&0===m?(D=0,I=0):r.sign(b)===r.sign(m)?(D=b+m,I=a/D):(I=b-m,D=a/I);var O=i.computeRealRoots(1,x,D),M=i.computeRealRoots(1,P,I);if(0!==O.length)return 0!==M.length?O[1]<=M[0]?[O[0],O[1],M[0],M[1]]:M[1]<=O[0]?[M[0],M[1],O[0],O[1]]:O[0]>=M[0]&&O[1]<=M[1]?[M[0],O[0],O[1],M[1]]:M[0]>=O[0]&&M[1]<=O[1]?[O[0],M[0],M[1],O[1]]:O[0]>M[0]&&O[0]<M[1]?[M[0],O[0],M[1],O[1]]:[O[0],M[0],O[1],M[1]]:O;if(0!==M.length)return M}return[]}var a={};return a.computeDiscriminant=function(e,t,r,i,n){var o=e*e,a=o*e,s=t*t,l=s*t,u=r*r,c=u*r,d=i*i,h=d*i,p=n*n;return s*u*d-4*l*h-4*e*c*d+18*e*t*r*h-27*o*d*d+256*a*(p*n)+n*(18*l*r*i-4*s*c+16*e*u*u-80*e*t*u*i-6*e*s*d+144*o*r*d)+p*(144*e*s*r-27*s*s-128*o*u-192*o*t*i)},a.computeRealRoots=function(t,i,a,s,l){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(i,a,s,l);var u=i/t,c=a/t,d=s/t,h=l/t,p=u<0?1:0;switch(p+=c<0?p+1:p,p+=d<0?p+1:p,p+=h<0?p+1:p){case 0:return n(u,c,d,h);case 1:case 2:return o(u,c,d,h);case 3:case 4:return n(u,c,d,h);case 5:return o(u,c,d,h);case 6:case 7:return n(u,c,d,h);case 8:return o(u,c,d,h);case 9:case 10:return n(u,c,d,h);case 11:return o(u,c,d,h);case 12:case 13:case 14:case 15:return n(u,c,d,h);default:return}},a}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,i){"use strict";function n(r,i){i=e.clone(t(i,e.ZERO)),e.equals(i,e.ZERO)||e.normalize(i,i),this.origin=e.clone(t(r,e.ZERO)),this.direction=i}return n.getPoint=function(t,i,n){return r(n)||(n=new e),n=e.multiplyByScalar(t.direction,i,n),e.add(t.origin,n,n)},n}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,t,r,i){var n=t*t-4*e*r;if(!(n<0)){if(n>0){var o=1/(2*e),a=Math.sqrt(n),s=(-t+a)*o,l=(-t-a)*o;return s<l?(i.root0=s,i.root1=l):(i.root0=l,i.root1=s),i}var u=-t/(2*e);if(0!==u)return i.root0=i.root1=u,i}}function h(t,r,n){i(n)||(n=new o);var a=t.origin,s=t.direction,l=r.center,u=r.radius*r.radius,c=e.subtract(a,l,v),h=e.dot(s,s),p=2*e.dot(s,c),f=e.magnitudeSquared(c)-u,m=d(h,p,f,S);if(i(m))return n.start=m.root0,n.stop=m.root1,n}function p(e,t,r){var i=e+t;return a.sign(e)!==a.sign(t)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(t)))<r?0:i}function f(t,r,i,n,o){var c,d=n*n,h=o*o,f=(t[s.COLUMN1ROW1]-t[s.COLUMN2ROW2])*h,m=o*(n*p(t[s.COLUMN1ROW0],t[s.COLUMN0ROW1],a.EPSILON15)+r.y),g=t[s.COLUMN0ROW0]*d+t[s.COLUMN2ROW2]*h+n*r.x+i,_=h*p(t[s.COLUMN2ROW1],t[s.COLUMN1ROW2],a.EPSILON15),v=o*(n*p(t[s.COLUMN2ROW0],t[s.COLUMN0ROW2])+r.z),y=[];if(0===v&&0===_){if(c=l.computeRealRoots(f,m,g),0===c.length)return y;var b=c[0],C=Math.sqrt(Math.max(1-b*b,0));if(y.push(new e(n,o*b,o*-C)),y.push(new e(n,o*b,o*C)),2===c.length){var S=c[1],w=Math.sqrt(Math.max(1-S*S,0));y.push(new e(n,o*S,o*-w)),y.push(new e(n,o*S,o*w))}return y}var T=v*v,E=_*_,A=f*f,x=v*_,P=A+E,D=2*(m*f+x),I=2*g*f+m*m-E+T,O=2*(g*m-x),M=g*g-T;if(0===P&&0===D&&0===I&&0===O)return y;c=u.computeRealRoots(P,D,I,O,M);var R=c.length;if(0===R)return y;for(var L=0;L<R;++L){var N,k=c[L],F=k*k,B=Math.max(1-F,0),U=Math.sqrt(B);N=a.sign(f)===a.sign(g)?p(f*F+g,m*k,a.EPSILON12):a.sign(g)===a.sign(m*k)?p(f*F,m*k+g,a.EPSILON12):p(f*F+m*k,g,a.EPSILON12);var V=p(_*k,v,a.EPSILON15),z=N*V;z<0?y.push(new e(n,o*k,o*U)):z>0?y.push(new e(n,o*k,o*-U)):0!==U?(y.push(new e(n,o*k,o*-U)),y.push(new e(n,o*k,o*U)),++L):y.push(new e(n,o*k,o*U))}return y}var m={};m.rayPlane=function(t,r,n){i(n)||(n=new e);var o=t.origin,s=t.direction,l=r.normal,u=e.dot(l,s);if(!(Math.abs(u)<a.EPSILON15)){var c=(-r.distance-e.dot(l,o))/u;if(!(c<0))return n=e.multiplyByScalar(s,c,n),e.add(o,n,n)}};var g=new e,_=new e,v=new e,y=new e,b=new e;m.rayTriangleParametric=function(t,i,n,o,s){s=r(s,!1);var l,u,c,d,h,p=t.origin,f=t.direction,m=e.subtract(n,i,g),C=e.subtract(o,i,_),S=e.cross(f,C,v),w=e.dot(m,S);if(s){if(w<a.EPSILON6)return;if(l=e.subtract(p,i,y),(c=e.dot(l,S))<0||c>w)return;if(u=e.cross(l,m,b),(d=e.dot(f,u))<0||c+d>w)return;h=e.dot(C,u)/w}else{if(Math.abs(w)<a.EPSILON6)return;var T=1/w;if(l=e.subtract(p,i,y),(c=e.dot(l,S)*T)<0||c>1)return;if(u=e.cross(l,m,b),(d=e.dot(f,u)*T)<0||c+d>1)return;h=e.dot(C,u)*T}return h},m.rayTriangle=function(t,r,n,o,a,s){var l=m.rayTriangleParametric(t,r,n,o,a);if(i(l)&&!(l<0))return i(s)||(s=new e),e.multiplyByScalar(t.direction,l,s),e.add(t.origin,s,s)};var C=new c;m.lineSegmentTriangle=function(t,r,n,o,a,s,l){var u=C;e.clone(t,u.origin),e.subtract(r,t,u.direction),e.normalize(u.direction,u.direction);var c=m.rayTriangleParametric(u,n,o,a,s);if(!(!i(c)||c<0||c>e.distance(t,r)))return i(l)||(l=new e),e.multiplyByScalar(u.direction,c,l),e.add(u.origin,l,l)};var S={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=h(e,t,r),i(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r} +;var w=new c;m.lineSegmentSphere=function(t,r,n,o){var a=w;e.clone(t,a.origin);var s=e.subtract(r,t,a.direction),l=e.magnitude(s);if(e.normalize(s,s),o=h(a,n,o),!(!i(o)||o.stop<0||o.start>l))return o.start=Math.max(o.start,0),o.stop=Math.min(o.stop,l),o};var T=new e,E=new e;m.rayEllipsoid=function(t,r){var i,n,a,s,l,u=r.oneOverRadii,c=e.multiplyComponents(u,t.origin,T),d=e.multiplyComponents(u,t.direction,E),h=e.magnitudeSquared(c),p=e.dot(c,d);if(h>1){if(p>=0)return;var f=p*p;if(i=h-1,n=e.magnitudeSquared(d),a=n*i,f<a)return;if(f>a){s=p*p-a,l=-p+Math.sqrt(s);var m=l/n,g=i/l;return m<g?new o(m,g):{start:g,stop:m}}var _=Math.sqrt(i/n);return new o(_,_)}return h<1?(i=h-1,n=e.magnitudeSquared(d),a=n*i,s=p*p-a,l=-p+Math.sqrt(s),new o(0,l/n)):p<0?(n=e.magnitudeSquared(d),new o(0,-p/n)):void 0};var A=new e,x=new e,P=new e,D=new e,I=new e,O=new s,M=new s,R=new s,L=new s,N=new s,k=new s,F=new s,B=new e,U=new e,V=new t;m.grazingAltitudeLocation=function(t,r){var n=t.origin,o=t.direction;if(!e.equals(n,e.ZERO)){var l=r.geodeticSurfaceNormal(n,A);if(e.dot(o,l)>=0)return n}var u=i(this.rayEllipsoid(t,r)),c=r.transformPositionToScaledSpace(o,A),d=e.normalize(c,c),h=e.mostOrthogonalAxis(c,D),p=e.normalize(e.cross(h,d,x),x),m=e.normalize(e.cross(d,p,P),P),g=O;g[0]=d.x,g[1]=d.y,g[2]=d.z,g[3]=p.x,g[4]=p.y,g[5]=p.z,g[6]=m.x,g[7]=m.y,g[8]=m.z;var _=s.transpose(g,M),v=s.fromScale(r.radii,R),y=s.fromScale(r.oneOverRadii,L),b=N;b[0]=0,b[1]=-o.z,b[2]=o.y,b[3]=o.z,b[4]=0,b[5]=-o.x,b[6]=-o.y,b[7]=o.x,b[8]=0;var C,S,w=s.multiply(s.multiply(_,y,k),b,k),T=s.multiply(s.multiply(w,v,F),g,F),E=s.multiplyByVector(w,n,I),z=f(T,e.negate(E,A),0,0,1),G=z.length;if(G>0){for(var W=e.clone(e.ZERO,U),H=Number.NEGATIVE_INFINITY,j=0;j<G;++j){C=s.multiplyByVector(v,s.multiplyByVector(g,z[j],B),B);var q=e.normalize(e.subtract(C,n,D),D),Y=e.dot(q,o);Y>H&&(H=Y,W=e.clone(C,W))}var X=r.cartesianToCartographic(W,V);return H=a.clamp(H,0,1),S=e.magnitude(e.subtract(W,n,D))*Math.sqrt(1-H*H),S=u?-S:S,X.height=S,r.cartographicToCartesian(X,new e)}};var z=new e;return m.lineSegmentPlane=function(t,r,n,o){i(o)||(o=new e);var s=e.subtract(r,t,z),l=n.normal,u=e.dot(l,s);if(!(Math.abs(u)<a.EPSILON6)){var c=e.dot(l,t),d=-(n.distance+c)/u;if(!(d<0||d>1))return e.multiplyByScalar(s,d,o),e.add(t,o,o),o}},m.trianglePlaneIntersection=function(t,r,i,n){var o=n.normal,a=n.distance,s=e.dot(o,t)+a<0,l=e.dot(o,r)+a<0,u=e.dot(o,i)+a<0,c=0;c+=s?1:0,c+=l?1:0,c+=u?1:0;var d,h;if(1!==c&&2!==c||(d=new e,h=new e),1===c){if(s)return m.lineSegmentPlane(t,r,n,d),m.lineSegmentPlane(t,i,n,h),{positions:[t,r,i,d,h],indices:[0,3,4,1,2,4,1,4,3]};if(l)return m.lineSegmentPlane(r,i,n,d),m.lineSegmentPlane(r,t,n,h),{positions:[t,r,i,d,h],indices:[1,3,4,2,0,4,2,4,3]};if(u)return m.lineSegmentPlane(i,t,n,d),m.lineSegmentPlane(i,r,n,h),{positions:[t,r,i,d,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===c){if(!s)return m.lineSegmentPlane(r,t,n,d),m.lineSegmentPlane(i,t,n,h),{positions:[t,r,i,d,h],indices:[1,2,4,1,4,3,0,3,4]};if(!l)return m.lineSegmentPlane(i,r,n,d),m.lineSegmentPlane(t,r,n,h),{positions:[t,r,i,d,h],indices:[2,0,4,2,4,3,1,3,4]};if(!u)return m.lineSegmentPlane(t,i,n,d),m.lineSegmentPlane(r,i,n,h),{positions:[t,r,i,d,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,i,n,o,a){"use strict";function s(t,r){this.normal=e.clone(t),this.distance=r}s.fromPointNormal=function(t,i,n){var o=-e.dot(i,t);return r(n)?(e.clone(i,n.normal),n.distance=o,n):new s(i,o)};var l=new e;s.fromCartesian4=function(t,i){var n=e.fromCartesian4(t,l),o=t.w;return r(i)?(e.clone(n,i.normal),i.distance=o,i):new s(n,o)},s.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var u=new e;s.projectPointOntoPlane=function(t,i,n){r(n)||(n=new e);var o=s.getPointDistance(t,i),a=e.multiplyByScalar(t.normal,o,u);return e.subtract(i,a,n)};var c=new e;return s.transform=function(t,r,i){return a.multiplyByPointAsVector(r,t.normal,l),e.normalize(l,l),e.multiplyByScalar(t.normal,-t.distance,c),a.multiplyByPoint(r,c,c),s.fromPointNormal(c,l,i)},s.clone=function(t,i){return r(i)?(e.clone(t.normal,i.normal),i.distance=t.distance,i):new s(t.normal,t.distance)},s.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},s.ORIGIN_XY_PLANE=n(new s(e.UNIT_Z,0)),s.ORIGIN_YZ_PLANE=n(new s(e.UNIT_X,0)),s.ORIGIN_ZX_PLANE=n(new s(e.UNIT_Y,0)),s}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,i,n){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=i,this.ut1MinusUtc=n}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,i=t[r++],n=function(e,t,r,i){r||(r=" ");var n=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return i?e+n:n+e},o=function(e,t,r,i,o,a){var s=i-e.length;return s>0&&(e=r||!o?n(e,i,a,r):e.slice(0,t.length)+n("",s,"0",!0)+e.slice(t.length)),e},a=function(e,t,r,i,a,s,l){var u=e>>>0;return r=r&&u&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+n(u.toString(t),s||0,"0",!1),o(e,r,i,a,l)},s=function(e,t,r,i,n,a){return null!=i&&(e=e.slice(0,i)),o(e,"",t,r,n,a)},l=function(e,i,l,u,c,d,h){var p,f,m,g,_;if("%%"==e)return"%";for(var v=!1,y="",b=!1,C=!1,S=" ",w=l.length,T=0;l&&T<w;T++)switch(l.charAt(T)){case" ":y=" ";break;case"+":y="+";break;case"-":v=!0;break;case"'":S=l.charAt(T+1);break;case"0":b=!0;break;case"#":C=!0}if(u=u?"*"==u?+t[r++]:"*"==u.charAt(0)?+t[u.slice(1,-1)]:+u:0,u<0&&(u=-u,v=!0),!isFinite(u))throw new Error("sprintf: (minimum-)width must be finite");switch(d=d?"*"==d?+t[r++]:"*"==d.charAt(0)?+t[d.slice(1,-1)]:+d:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=i?t[i.slice(0,-1)]:t[r++],h){case"s":return s(String(_),v,u,d,b,S);case"c":return s(String.fromCharCode(+_),v,u,d,b);case"b":return a(_,2,C,v,u,d,b);case"o":return a(_,8,C,v,u,d,b);case"x":return a(_,16,C,v,u,d,b);case"X":return a(_,16,C,v,u,d,b).toUpperCase();case"u":return a(_,10,C,v,u,d,b);case"i":case"d":return p=+_||0,p=Math.round(p-p%1),f=p<0?"-":y,_=f+n(String(Math.abs(p)),d,"0",!1),o(_,f,v,u,b);case"e":case"E":case"f":case"F":case"g":case"G":return p=+_,f=p<0?"-":y,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],g=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=f+Math.abs(p)[m](d),o(_,f,v,u,b)[g]();default:return e}};return i.replace(e,l)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,i,n,o,a,s){this.year=e,this.month=t,this.day=r,this.hour=i,this.minute=n,this.second=o,this.millisecond=a,this.isLeapSecond=s}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t){return m.compare(e.julianDate,t.julianDate)}function d(e){v.julianDate=e;var r=m.leapSeconds,i=t(r,v,c);i<0&&(i=~i),i>=r.length&&(i=r.length-1);var n=r[i].offset;if(i>0){m.secondsDifference(r[i].julianDate,e)>n&&(i--,n=r[i].offset)}m.addSeconds(e,n,e)}function h(e,r){v.julianDate=e;var i=m.leapSeconds,n=t(i,v,c);if(n<0&&(n=~n),0===n)return m.addSeconds(e,-i[0].offset,r);if(n>=i.length)return m.addSeconds(e,-i[n-1].offset,r);var o=m.secondsDifference(i[n].julianDate,e);return 0===o?m.addSeconds(e,-i[n].offset,r):o<=1?void 0:m.addSeconds(e,-i[--n].offset,r)}function p(e,t,r){var i=t/l.SECONDS_PER_DAY|0;return e+=i,t-=l.SECONDS_PER_DAY*i,t<0&&(e--,t+=l.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function f(e,t,r,i,n,o,a){var s=(t-14)/12|0,u=e+4800+s,c=(1461*u/4|0)+(367*(t-2-12*s)/12|0)-(3*((u+100)/100|0)/4|0)+r-32075;(i-=12)<0&&(i+=24);var d=o+(i*l.SECONDS_PER_HOUR+n*l.SECONDS_PER_MINUTE+a*l.SECONDS_PER_MILLISECOND);return d>=43200&&(c-=1),[c,d]}function m(e,t,i){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),i=r(i,u.UTC);var n=0|e;t+=(e-n)*l.SECONDS_PER_DAY,p(n,t,this),i===u.UTC&&d(this)}var g=new o,_=[31,28,31,30,31,30,31,31,30,31,30,31],v=new s,y=/^(\d{4})$/,b=/^(\d{4})-(\d{2})$/,C=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,w=/^(\d{4})-?(\d{2})-?(\d{2})$/,T=/([Z+\-])?(\d{2})?:?(\d{2})?$/,E=/^(\d{2})(\.\d+)?/.source+T.source,A=/^(\d{2}):?(\d{2})(\.\d+)?/.source+T.source,x=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+T.source;m.fromGregorianDate=function(e,t){var r=f(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return i(t)?(p(r[0],r[1],t),d(t),t):new m(r[0],r[1],u.UTC)},m.fromDate=function(e,t){var r=f(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return i(t)?(p(r[0],r[1],t),d(t),t):new m(r[0],r[1],u.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,n,o,s=e.split("T"),l=1,c=1,h=0,g=0,v=0,T=0,P=s[0],D=s[1];if(null!==(s=P.match(w)))r=+s[1],l=+s[2],c=+s[3];else if(null!==(s=P.match(b)))r=+s[1],l=+s[2];else if(null!==(s=P.match(y)))r=+s[1];else{var I;if(null!==(s=P.match(C)))r=+s[1],I=+s[2],o=a(r);else if(null!==(s=P.match(S))){r=+s[1];var O=+s[2],M=+s[3]||0,R=new Date(Date.UTC(r,0,4));I=7*O+M-R.getUTCDay()-3}n=new Date(Date.UTC(r,0,1)),n.setUTCDate(I),l=n.getUTCMonth()+1,c=n.getUTCDate()}o=a(r);var L;if(i(D)){s=D.match(x),null!==s?(h=+s[1],g=+s[2],v=+s[3],T=1e3*+(s[4]||0),L=5):(s=D.match(A),null!==s?(h=+s[1],g=+s[2],v=60*+(s[3]||0),L=4):null!==(s=D.match(E))&&(h=+s[1],g=60*+(s[2]||0),L=3));var N=s[L],k=+s[L+1],F=+(s[L+2]||0);switch(N){case"+":h-=k,g-=F;break;case"-":h+=k,g+=F;break;case"Z":break;default:g+=new Date(Date.UTC(r,l-1,c,h,g)).getTimezoneOffset()}}var B=60===v;for(B&&v--;g>=60;)g-=60,h++;for(;h>=24;)h-=24,c++;for(n=o&&2===l?29:_[l-1];c>n;)c-=n,l++,l>12&&(l-=12,r++),n=o&&2===l?29:_[l-1];for(;g<0;)g+=60,h--;for(;h<0;)h+=24,c--;for(;c<1;)l--,l<1&&(l+=12,r--),n=o&&2===l?29:_[l-1],c+=n;var U=f(r,l,c,h,g,v,T);return i(t)?(p(U[0],U[1],t),d(t)):t=new m(U[0],U[1],u.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var P=new m(0,0,u.TAI);return m.toGregorianDate=function(e,t){var r=!1,n=h(e,P);i(n)||(m.addSeconds(e,-1,P),n=h(P,P),r=!0);var a=n.dayNumber,s=n.secondsOfDay;s>=43200&&(a+=1);var u=a+68569|0,c=4*u/146097|0;u=u-((146097*c+3)/4|0)|0;var d=4e3*(u+1)/1461001|0;u=u-(1461*d/4|0)+31|0;var p=80*u/2447|0,f=u-(2447*p/80|0)|0;u=p/11|0;var g=p+2-12*u|0,_=100*(c-49)+d+u|0,v=s/l.SECONDS_PER_HOUR|0,y=s-v*l.SECONDS_PER_HOUR,b=y/l.SECONDS_PER_MINUTE|0;y-=b*l.SECONDS_PER_MINUTE;var C=0|y,S=(y-C)/l.SECONDS_PER_MILLISECOND;return v+=12,v>23&&(v-=24),r&&(C+=1),i(t)?(t.year=_,t.month=g,t.day=f,t.hour=v,t.minute=b,t.second=C,t.millisecond=S,t.isLeapSecond=r,t):new o(_,g,f,v,b,C,S,r)},m.toDate=function(e){var t=m.toGregorianDate(e,g),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var n,o=m.toGregorianDate(t,g);return i(r)||0===o.millisecond?i(r)&&0!==r?(n=(.01*o.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",o.year,o.month,o.day,o.hour,o.minute,o.second,n)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",o.year,o.month,o.day,o.hour,o.minute,o.second):(n=(.01*o.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",o.year,o.month,o.day,o.hour,o.minute,o.second,n))},m.clone=function(e,t){if(i(e))return i(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,u.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||i(e)&&i(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/l.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*l.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/l.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){v.julianDate=e;var r=m.leapSeconds,i=t(r,v,c);return i<0&&(i=~i,--i<0&&(i=0)),r[i].offset},m.addSeconds=function(e,t,r){return p(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var i=e.secondsOfDay+t*l.SECONDS_PER_MINUTE;return p(e.dayNumber,i,r)},m.addHours=function(e,t,r){var i=e.secondsOfDay+t*l.SECONDS_PER_HOUR;return p(e.dayNumber,i,r)},m.addDays=function(e,t,r){return p(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new s(new m(2441317,43210,u.TAI),10),new s(new m(2441499,43211,u.TAI),11),new s(new m(2441683,43212,u.TAI),12),new s(new m(2442048,43213,u.TAI),13),new s(new m(2442413,43214,u.TAI),14),new s(new m(2442778,43215,u.TAI),15),new s(new m(2443144,43216,u.TAI),16),new s(new m(2443509,43217,u.TAI),17),new s(new m(2443874,43218,u.TAI),18),new s(new m(2444239,43219,u.TAI),19),new s(new m(2444786,43220,u.TAI),20),new s(new m(2445151,43221,u.TAI),21),new s(new m(2445516,43222,u.TAI),22),new s(new m(2446247,43223,u.TAI),23),new s(new m(2447161,43224,u.TAI),24),new s(new m(2447892,43225,u.TAI),25),new s(new m(2448257,43226,u.TAI),26),new s(new m(2448804,43227,u.TAI),27),new s(new m(2449169,43228,u.TAI),28),new s(new m(2449534,43229,u.TAI),29),new s(new m(2450083,43230,u.TAI),30),new s(new m(2450630,43231,u.TAI),31),new s(new m(2451179,43232,u.TAI),32),new s(new m(2453736,43233,u.TAI),33),new s(new m(2454832,43234,u.TAI),34),new s(new m(2456109,43235,u.TAI),35),new s(new m(2457204,43236,u.TAI),36),new s(new m(2457754,43237,u.TAI),37)],m}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),i(t.data))f(this,t.data);else if(i(t.url)){var n=l.createIfNeeded(t.url),o=this;this._downloadPromise=e(n.fetchJson(),function(e){f(o,e)},function(){o._dataError="An error occurred while retrieving the EOP data from the URL "+n.url+"."})}else f(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function p(e,t){return a.compare(e.julianDate,t)}function f(e,r){if(!i(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!i(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var n=r.columnNames.indexOf("modifiedJulianDateUtc"),o=r.columnNames.indexOf("xPoleWanderRadians"),l=r.columnNames.indexOf("yPoleWanderRadians"),u=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),f=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(n<0||o<0||l<0||u<0||h<0||f<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var g=e._samples=r.samples,_=e._dates=[];e._dateColumn=n,e._xPoleWanderRadiansColumn=o,e._yPoleWanderRadiansColumn=l,e._ut1MinusUtcSecondsColumn=u,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=f,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var v,y=e._addNewLeapSeconds,b=0,C=g.length;b<C;b+=e._columnCount){var S=g[b+n],w=g[b+m],T=S+c.MODIFIED_JULIAN_DATE_DIFFERENCE,E=new a(T,w,d.TAI);if(_.push(E),y){if(w!==v&&i(v)){var A=a.leapSeconds,x=t(A,E,p);if(x<0){var P=new s(E,w);A.splice(~x,0,P)}}v=w}}}function m(e,t,r,i,n){var o=r*i;n.xPoleWander=t[o+e._xPoleWanderRadiansColumn],n.yPoleWander=t[o+e._yPoleWanderRadiansColumn],n.xPoleOffset=t[o+e._xCelestialPoleOffsetRadiansColumn],n.yPoleOffset=t[o+e._yCelestialPoleOffsetRadiansColumn],n.ut1MinusUtc=t[o+e._ut1MinusUtcSecondsColumn]}function g(e,t,r){return t+e*(r-t)}function _(e,t,r,i,n,o,s){var l=e._columnCount;if(o>t.length-1)return s.xPoleWander=0,s.yPoleWander=0,s.xPoleOffset=0,s.yPoleOffset=0,s.ut1MinusUtc=0,s;var u=t[n],c=t[o];if(u.equals(c)||i.equals(u))return m(e,r,n,l,s),s;if(i.equals(c))return m(e,r,o,l,s),s;var d=a.secondsDifference(i,u)/a.secondsDifference(c,u),h=n*l,p=o*l,f=r[h+e._ut1MinusUtcSecondsColumn],_=r[p+e._ut1MinusUtcSecondsColumn],v=_-f;if(v>.5||v<-.5){var y=r[h+e._taiMinusUtcSecondsColumn],b=r[p+e._taiMinusUtcSecondsColumn];y!==b&&(c.equals(i)?f=_:_-=b-y)}return s.xPoleWander=g(d,r[h+e._xPoleWanderRadiansColumn],r[p+e._xPoleWanderRadiansColumn]),s.yPoleWander=g(d,r[h+e._yPoleWanderRadiansColumn],r[p+e._yPoleWanderRadiansColumn]),s.xPoleOffset=g(d,r[h+e._xCelestialPoleOffsetRadiansColumn],r[p+e._xCelestialPoleOffsetRadiansColumn]),s.yPoleOffset=g(d,r[h+e._yCelestialPoleOffsetRadiansColumn],r[p+e._yCelestialPoleOffsetRadiansColumn]),s.ut1MinusUtc=g(d,f,_),s}return h.NONE=o({getPromiseToLoad:function(){return e()},compute:function(e,t){return i(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new n(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(i(this._samples)){if(i(r)||(r=new n(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var o=this._dates,s=this._lastIndex,l=0,c=0;if(i(s)){var d=o[s],h=o[s+1],p=a.lessThanOrEquals(d,e),f=!i(h),m=f||a.greaterThanOrEquals(h,e);if(p&&m)return l=s,!f&&h.equals(e)&&++l,c=l+1,_(this,o,this._samples,e,l,c,r),r}var g=t(o,e,a.compare,this._dateColumn);return g>=0?(g<o.length-1&&o[g+1].equals(e)&&++g,l=g,c=g):(c=~g,(l=c-1)<0&&(l=0)),this._lastIndex=l,_(this,o,this._samples,e,l,c,r),r}if(i(this._dataError))throw new u(this._dataError)},h}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=a.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new o(this._sampleZeroJulianEphemerisDate,0,s.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,i=this._denominators=new Array(t+1),n=this._xTable=new Array(t+1),l=Math.pow(this._stepSizeDays,t),u=0;u<=t;++u){i[u]=l,n[u]=u*this._stepSizeDays;for(var c=0;c<=t;++c)c!==u&&(i[u]*=u-c);i[u]=1/i[u]}this._work=new Array(t+1),this._coef=new Array(t+1)}function u(e,t,r){var i=d;return i.dayNumber=t,i.secondsOfDay=r,o.daysDifference(i,e._sampleZeroDateTT)}function c(r,n){if(r._chunkDownloadsInProgress[n])return r._chunkDownloadsInProgress[n];var o=e.defer();r._chunkDownloadsInProgress[n]=o;var s,l=r._xysFileUrlTemplate;return s=i(l)?l.getDerivedResource({templateValues:{0:n}}):new a({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+n+".json")}),e(s.fetchJson(),function(e){r._chunkDownloadsInProgress[n]=!1;for(var t=r._samples,i=e.samples,a=n*r._samplesPerXysFile*3,s=0,l=i.length;s<l;++s)t[a+s]=i[s];o.resolve()}),o.promise}var d=new o(0,0,s.TAI);return l.prototype.preload=function(t,r,i,n){var o=u(this,t,r),a=u(this,i,n),s=o/this._stepSizeDays-this._interpolationOrder/2|0;s<0&&(s=0);var l=a/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;l>=this._totalSamples&&(l=this._totalSamples-1);for(var d=s/this._samplesPerXysFile|0,h=l/this._samplesPerXysFile|0,p=[],f=d;f<=h;++f)p.push(c(this,f));return e.all(p)},l.prototype.computeXysRadians=function(e,t,r){var o=u(this,e,t);if(!(o<0)){var a=o/this._stepSizeDays|0;if(!(a>=this._totalSamples)){var s=this._interpolationOrder,l=a-(s/2|0);l<0&&(l=0);var d=l+s;d>=this._totalSamples&&(d=this._totalSamples-1,(l=d-s)<0&&(l=0));var h=!1,p=this._samples;if(i(p[3*l])||(c(this,l/this._samplesPerXysFile|0),h=!0),i(p[3*d])||(c(this,d/this._samplesPerXysFile|0),h=!0),!h){i(r)?(r.x=0,r.y=0,r.s=0):r=new n(0,0,0);var f,m,g=o-l*this._stepSizeDays,_=this._work,v=this._denominators,y=this._coef,b=this._xTable;for(f=0;f<=s;++f)_[f]=g-b[f];for(f=0;f<=s;++f){for(y[f]=1,m=0;m<=s;++m)m!==f&&(y[f]*=_[m]);y[f]*=v[f];var C=3*(l+f);r.x+=y[f]*p[C++],r.y+=y[f]*p[C++],r.s+=y[f]*p[C]}return r}}}},l}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,i,n){this.x=r(e,0),this.y=r(t,0),this.z=r(i,0),this.w=r(n,0)}var u=new e;l.fromAxisAngle=function(t,r,n){var o=r/2,a=Math.sin(o);u=e.normalize(t,u);var s=u.x*a,c=u.y*a,d=u.z*a,h=Math.cos(o);return i(n)?(n.x=s,n.y=c,n.z=d,n.w=h,n):new l(s,c,d,h)};var c=[1,2,0],d=new Array(3);l.fromRotationMatrix=function(e,t){var r,n,o,a,u,h=e[s.COLUMN0ROW0],p=e[s.COLUMN1ROW1],f=e[s.COLUMN2ROW2],m=h+p+f;if(m>0)r=Math.sqrt(m+1),u=.5*r,r=.5/r,n=(e[s.COLUMN1ROW2]-e[s.COLUMN2ROW1])*r,o=(e[s.COLUMN2ROW0]-e[s.COLUMN0ROW2])*r,a=(e[s.COLUMN0ROW1]-e[s.COLUMN1ROW0])*r;else{var g=c,_=0;p>h&&(_=1),f>h&&f>p&&(_=2);var v=g[_],y=g[v];r=Math.sqrt(e[s.getElementIndex(_,_)]-e[s.getElementIndex(v,v)]-e[s.getElementIndex(y,y)]+1);var b=d;b[_]=.5*r,r=.5/r,u=(e[s.getElementIndex(y,v)]-e[s.getElementIndex(v,y)])*r,b[v]=(e[s.getElementIndex(v,_)]+e[s.getElementIndex(_,v)])*r,b[y]=(e[s.getElementIndex(y,_)]+e[s.getElementIndex(_,y)])*r,n=-b[0],o=-b[1],a=-b[2]}return i(t)?(t.x=n,t.y=o,t.z=a,t.w=u,t):new l(n,o,a,u)};var h=new l,p=new l,f=new l,m=new l;l.fromHeadingPitchRoll=function(t,r){return m=l.fromAxisAngle(e.UNIT_X,t.roll,h),f=l.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=l.multiply(f,m,f),p=l.fromAxisAngle(e.UNIT_Z,-t.heading,h),l.multiply(p,r,r)};var g=new e,_=new e,v=new l,y=new l,b=new l;l.packedLength=4,l.pack=function(e,t,i){return i=r(i,0),t[i++]=e.x,t[i++]=e.y,t[i++]=e.z,t[i]=e.w,t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n.x=e[t],n.y=e[t+1],n.z=e[t+2],n.w=e[t+3],n},l.packedInterpolationLength=3,l.convertPackedArrayForInterpolation=function(e,t,r,i){l.unpack(e,4*r,b),l.conjugate(b,b);for(var n=0,o=r-t+1;n<o;n++){var a=3*n;l.unpack(e,4*(t+n),v),l.multiply(v,b,v),v.w<0&&l.negate(v,v),l.computeAxis(v,g);var s=l.computeAngle(v);i[a]=g.x*s,i[a+1]=g.y*s,i[a+2]=g.z*s}},l.unpackInterpolationResult=function(t,r,n,o,a){i(a)||(a=new l),e.fromArray(t,0,_);var s=e.magnitude(_);return l.unpack(r,4*o,y),0===s?l.clone(l.IDENTITY,v):l.fromAxisAngle(_,s,v),l.multiply(v,y,a)},l.clone=function(e,t){if(i(e))return i(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new l(e.x,e.y,e.z,e.w)},l.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},l.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},l.magnitude=function(e){return Math.sqrt(l.magnitudeSquared(e))},l.normalize=function(e,t){var r=1/l.magnitude(e),i=e.x*r,n=e.y*r,o=e.z*r,a=e.w*r;return t.x=i,t.y=n,t.z=o,t.w=a,t},l.inverse=function(e,t){var r=l.magnitudeSquared(e);return t=l.conjugate(e,t),l.multiplyByScalar(t,1/r,t)},l.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},l.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},l.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},l.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},l.multiply=function(e,t,r){var i=e.x,n=e.y,o=e.z,a=e.w,s=t.x,l=t.y,u=t.z,c=t.w,d=a*s+i*c+n*u-o*l,h=a*l-i*u+n*c+o*s,p=a*u+i*l-n*s+o*c,f=a*c-i*s-n*l-o*u;return r.x=d,r.y=h,r.z=p,r.w=f,r},l.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},l.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},l.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<a.EPSILON6)return t.x=t.y=t.z=0,t;var i=1/Math.sqrt(1-r*r);return t.x=e.x*i,t.y=e.y*i,t.z=e.z*i,t},l.computeAngle=function(e){return Math.abs(e.w-1)<a.EPSILON6?0:2*Math.acos(e.w)};var C=new l;l.lerp=function(e,t,r,i){return C=l.multiplyByScalar(t,r,C),i=l.multiplyByScalar(e,1-r,i),l.add(C,i,i)};var S=new l,w=new l,T=new l;l.slerp=function(e,t,r,i){var n=l.dot(e,t),o=t;if(n<0&&(n=-n,o=S=l.negate(t,S)),1-n<a.EPSILON6)return l.lerp(e,o,r,i);var s=Math.acos(n);return w=l.multiplyByScalar(e,Math.sin((1-r)*s),w),T=l.multiplyByScalar(o,Math.sin(r*s),T),i=l.add(w,T,i),l.multiplyByScalar(i,1/Math.sin(s),i)},l.log=function(t,r){var i=a.acosClamped(t.w),n=0;return 0!==i&&(n=i/Math.sin(i)),e.multiplyByScalar(t,n,r)},l.exp=function(t,r){var i=e.magnitude(t),n=0;return 0!==i&&(n=Math.sin(i)/i),r.x=t.x*n,r.y=t.y*n,r.z=t.z*n,r.w=Math.cos(i),r};var E=new e,A=new e,x=new l,P=new l;l.computeInnerQuadrangle=function(t,r,i,n){var o=l.conjugate(r,x);l.multiply(o,i,P);var a=l.log(P,E);l.multiply(o,t,P);var s=l.log(P,A);return e.add(a,s,a),e.multiplyByScalar(a,.25,a),e.negate(a,a),l.exp(a,x),l.multiply(r,x,n)},l.squad=function(e,t,r,i,n,o){var a=l.slerp(e,t,n,x),s=l.slerp(r,i,n,P);return l.slerp(a,s,2*n*(1-n),o)};for(var D=new l,I=1.9011074535173003,O=n.supportsTypedArrays()?new Float32Array(8):[],M=n.supportsTypedArrays()?new Float32Array(8):[],R=n.supportsTypedArrays()?new Float32Array(8):[],L=n.supportsTypedArrays()?new Float32Array(8):[],N=0;N<7;++N){var k=N+1,F=2*k+1;O[N]=1/(k*F),M[N]=k/F}return O[7]=I/136,M[7]=8*I/17,l.fastSlerp=function(e,t,r,i){var n,o=l.dot(e,t);o>=0?n=1:(n=-1,o=-o);for(var a=o-1,s=1-r,u=r*r,c=s*s,d=7;d>=0;--d)R[d]=(O[d]*u-M[d])*a,L[d]=(O[d]*c-M[d])*a;var h=n*r*(1+R[0]*(1+R[1]*(1+R[2]*(1+R[3]*(1+R[4]*(1+R[5]*(1+R[6]*(1+R[7])))))))),p=s*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),f=l.multiplyByScalar(e,p,D);return l.multiplyByScalar(t,h,i),l.add(f,i,i)},l.fastSquad=function(e,t,r,i,n,o){var a=l.fastSlerp(e,t,n,x),s=l.fastSlerp(r,i,n,P);return l.fastSlerp(a,s,2*n*(1-n),o)},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},l.ZERO=o(new l(0,0,0,0)),l.IDENTITY=o(new l(0,0,0,1)),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},l}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";var b={},C={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},w={},T={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},E=new r,A=new r,x=new r;b.localFrameToFixedFrameGenerator=function(e,t){if(!C.hasOwnProperty(e)||!C[e].hasOwnProperty(t))throw new l("firstAxis and secondAxis must be east, north, up, west, south or down.");var i,n=C[e][t],o=e+t;return s(w[o])?i=w[o]:(i=function(i,o,l){if(s(l)||(l=new _),m.equalsEpsilon(i.x,0,m.EPSILON14)&&m.equalsEpsilon(i.y,0,m.EPSILON14)){var u=m.sign(i.z);r.unpack(S[e],0,E),"east"!==e&&"west"!==e&&r.multiplyByScalar(E,u,E),r.unpack(S[t],0,A),"east"!==t&&"west"!==t&&r.multiplyByScalar(A,u,A),r.unpack(S[n],0,x),"east"!==n&&"west"!==n&&r.multiplyByScalar(x,u,x)}else{o=a(o,d.WGS84),o.geodeticSurfaceNormal(i,T.up);var c=T.up,h=T.east;h.x=-i.y,h.y=i.x,h.z=0,r.normalize(h,T.east),r.cross(c,h,T.north),r.multiplyByScalar(T.up,-1,T.down),r.multiplyByScalar(T.east,-1,T.west),r.multiplyByScalar(T.north,-1,T.south),E=T[e],A=T[t],x=T[n]}return l[0]=E.x,l[1]=E.y,l[2]=E.z,l[3]=0,l[4]=A.x,l[5]=A.y,l[6]=A.z,l[7]=0,l[8]=x.x,l[9]=x.y,l[10]=x.z,l[11]=0,l[12]=i.x,l[13]=i.y,l[14]=i.z,l[15]=1,l},w[o]=i),i},b.eastNorthUpToFixedFrame=b.localFrameToFixedFrameGenerator("east","north"),b.northEastDownToFixedFrame=b.localFrameToFixedFrameGenerator("north","east"),b.northUpEastToFixedFrame=b.localFrameToFixedFrameGenerator("north","up"),b.northWestUpToFixedFrame=b.localFrameToFixedFrameGenerator("north","west");var P=new v,D=new r(1,1,1),I=new _;b.headingPitchRollToFixedFrame=function(e,t,i,n,o){n=a(n,b.eastNorthUpToFixedFrame);var s=v.fromHeadingPitchRoll(t,P),l=_.fromTranslationQuaternionRotationScale(r.ZERO,s,D,I);return o=n(e,i,o),_.multiply(o,l,o)};var O=new _,M=new g;b.headingPitchRollQuaternion=function(e,t,r,i,n){var o=b.headingPitchRollToFixedFrame(e,t,r,i,O),a=_.getRotation(o,M);return v.fromRotationMatrix(a,n)};var R=m.TWO_PI/86400,L=new f;b.computeTemeToPseudoFixedMatrix=function(e,t){L=f.addSeconds(e,-f.computeTaiMinusUtc(e),L);var r,i=L.dayNumber,n=L.secondsOfDay,o=i-2451545;r=n>=43200?(o+.5)/y.DAYS_PER_JULIAN_CENTURY:(o-.5)/y.DAYS_PER_JULIAN_CENTURY;var a=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),l=a*R%m.TWO_PI,u=72921158553e-15+1.1772758384668e-19*(i-2451545.5),c=(n+.5*y.SECONDS_PER_DAY)%y.SECONDS_PER_DAY,d=l+u*c,h=Math.cos(d),p=Math.sin(d);return s(t)?(t[0]=h,t[1]=-p,t[2]=0,t[3]=p,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new g(h,p,0,-p,h,0,0,0,1)},b.iau2006XysData=new h,b.earthOrientationParameters=u.NONE;b.preloadIcrfFixed=function(t){ +var r=t.start.dayNumber,i=t.start.secondsOfDay+32.184,n=t.stop.dayNumber,o=t.stop.secondsOfDay+32.184,a=b.iau2006XysData.preload(r,i,n,o),s=b.earthOrientationParameters.getPromiseToLoad();return e.all([a,s])},b.computeIcrfToFixedMatrix=function(e,t){s(t)||(t=new g);var r=b.computeFixedToIcrfMatrix(e,t);if(s(r))return g.transpose(r,t)};var N=new p(0,0,0),k=new c(0,0,0,0,0,0),F=new g,B=new g;b.computeFixedToIcrfMatrix=function(e,t){s(t)||(t=new g);var r=b.earthOrientationParameters.compute(e,k);if(s(r)){var i=e.dayNumber,n=e.secondsOfDay+32.184,o=b.iau2006XysData.computeXysRadians(i,n,N);if(s(o)){var a=o.x+r.xPoleOffset,l=o.y+r.yPoleOffset,u=1/(1+Math.sqrt(1-a*a-l*l)),c=F;c[0]=1-u*a*a,c[3]=-u*a*l,c[6]=a,c[1]=-u*a*l,c[4]=1-u*l*l,c[7]=l,c[2]=-a,c[5]=-l,c[8]=1-u*(a*a+l*l);var d=g.fromRotationZ(-o.s,B),h=g.multiply(c,d,F),p=e.dayNumber,_=e.secondsOfDay-f.computeTaiMinusUtc(e)+r.ut1MinusUtc,v=p-2451545,C=_/y.SECONDS_PER_DAY,S=.779057273264+C+.00273781191135448*(v+C);S=S%1*m.TWO_PI;var w=g.fromRotationZ(S,B),T=g.multiply(h,w,F),E=Math.cos(r.xPoleWander),A=Math.cos(r.yPoleWander),x=Math.sin(r.xPoleWander),P=Math.sin(r.yPoleWander),D=i-2451545+n/y.SECONDS_PER_DAY;D/=36525;var I=-47e-6*D*m.RADIANS_PER_DEGREE/3600,O=Math.cos(I),M=Math.sin(I),R=B;return R[0]=E*O,R[1]=E*M,R[2]=x,R[3]=-A*M+P*x*O,R[4]=A*O+P*x*M,R[5]=-P*E,R[6]=-P*M-A*x*O,R[7]=P*O-A*x*M,R[8]=A*E,g.multiply(T,R,t)}}};var U=new i;b.pointToWindowCoordinates=function(e,t,r,i){return i=b.pointToGLWindowCoordinates(e,t,r,i),i.y=2*t[5]-i.y,i},b.pointToGLWindowCoordinates=function(e,r,n,o){s(o)||(o=new t);var a=U;return _.multiplyByVector(e,i.fromElements(n.x,n.y,n.z,1,a),a),i.multiplyByScalar(a,1/a.w,a),_.multiplyByVector(r,a,a),t.fromCartesian4(a,o)};var V=new r,z=new r,G=new r;b.rotationMatrixFromPositionVelocity=function(e,t,i,n){var o=a(i,d.WGS84).geodeticSurfaceNormal(e,V),l=r.cross(t,o,z);r.equalsEpsilon(l,r.ZERO,m.EPSILON6)&&(l=r.clone(r.UNIT_X,l));var u=r.cross(l,t,G);return r.cross(t,u,l),r.negate(l,l),s(n)||(n=new g),n[0]=t.x,n[1]=t.y,n[2]=t.z,n[3]=l.x,n[4]=l.y,n[5]=l.z,n[6]=u.x,n[7]=u.y,n[8]=u.z,n};var W=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),H=new n,j=new r,q=new r,Y=new g,X=new _,Q=new _;return b.basisTo2D=function(e,t,i){var n=_.getTranslation(t,q),o=e.ellipsoid,a=o.cartesianToCartographic(n,H),s=e.project(a,j);r.fromElements(s.z,s.x,s.y,s);var l=b.eastNorthUpToFixedFrame(n,o,X),u=_.inverseTransformation(l,Q),c=_.getRotation(t,Y),d=_.multiplyByMatrix3(u,c,i);return _.multiply(W,d,i),_.setTranslation(i,s,i),i},b.wgs84To2DModelMatrix=function(e,t,i){var n=e.ellipsoid,o=b.eastNorthUpToFixedFrame(t,n,X),a=_.inverseTransformation(o,Q),s=n.cartesianToCartographic(t,H),l=e.project(s,j);r.fromElements(l.z,l.x,l.y,l);var u=_.fromTranslation(l,X);return _.multiply(W,a,i),_.multiply(u,i,i),i},b}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,t){t=n(t,l.WGS84),e=t.scaleToGeodeticSurface(e);var i=p.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=r.fromCartesian4(c.getColumn(i,0,m)),this._yAxis=r.fromCartesian4(c.getColumn(i,1,m));var o=r.fromCartesian4(c.getColumn(i,2,m));this._plane=d.fromPointNormal(e,o)}var m=new i;a(f.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var g=new e;f.fromPoints=function(t,r){return new f(e.fromPoints(t,g).center,r)};var _=new h,v=new r;f.prototype.projectPointOntoPlane=function(e,i){var n=_;n.origin=e,r.normalize(e,n.direction);var a=u.rayPlane(n,this._plane,v);if(o(a)||(r.negate(n.direction,n.direction),a=u.rayPlane(n,this._plane,v)),o(a)){var s=r.subtract(a,this._origin,a),l=r.dot(this._xAxis,s),c=r.dot(this._yAxis,s);return o(i)?(i.x=l,i.y=c,i):new t(l,c)}},f.prototype.projectPointsOntoPlane=function(e,t){o(t)||(t=[]);for(var r=0,i=e.length,n=0;n<i;n++){var a=this.projectPointOntoPlane(e[n],t[r]);o(a)&&(t[r]=a,r++)}return t.length=r,t},f.prototype.projectPointToNearestOnPlane=function(e,i){o(i)||(i=new t);var n=_;n.origin=e,r.clone(this._plane.normal,n.direction);var a=u.rayPlane(n,this._plane,v);o(a)||(r.negate(n.direction,n.direction),a=u.rayPlane(n,this._plane,v));var s=r.subtract(a,this._origin,a),l=r.dot(this._xAxis,s),c=r.dot(this._yAxis,s);return i.x=l,i.y=c,i},f.prototype.projectPointsToNearestOnPlane=function(e,t){o(t)||(t=[]);var r=e.length;t.length=r;for(var i=0;i<r;i++)t[i]=this.projectPointToNearestOnPlane(e[i],t[i]);return t};var y=new r;return f.prototype.projectPointsOntoEllipsoid=function(e,t){var i=e.length;o(t)?t.length=i:t=new Array(i);for(var n=this._ellipsoid,a=this._origin,s=this._xAxis,l=this._yAxis,u=y,c=0;c<i;++c){var d=e[c];r.multiplyByScalar(s,d.x,u),o(t[c])||(t[c]=new r);var h=r.add(a,u,t[c]);r.multiplyByScalar(l,d.y,u),r.add(h,u,h),n.scaleToGeocentricSurface(h,h)}return t},f}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e,t){this.center=r.clone(o(e,r.ZERO)),this.halfAxes=p.clone(o(t,p.ZERO))}function _(e,t,i,n,o,s,l,u){a(u)||(u=new g);var c=u.halfAxes;p.setColumn(c,0,e.xAxis,c),p.setColumn(c,1,e.yAxis,c),p.setColumn(c,2,e.zAxis,c);var d=A;d.x=(t+i)/2,d.y=(n+o)/2,d.z=(s+l)/2;var h=x;h.x=(i-t)/2,h.y=(o-n)/2,h.z=(l-s)/2;var f=u.center;return d=p.multiplyByVector(c,d,d),r.add(e.origin,d,f),p.multiplyByScale(c,h,c),u}g.packedLength=r.packedLength+p.packedLength,g.pack=function(e,t,i){return i=o(i,0),r.pack(e.center,t,i),p.pack(e.halfAxes,t,i+r.packedLength),t},g.unpack=function(e,t,i){return t=o(t,0),a(i)||(i=new g),r.unpack(e,t,i.center),p.unpack(e,t+r.packedLength,i.halfAxes),i};var v=new r,y=new r,b=new r,C=new r,S=new r,w=new r,T=new p,E={unitary:new p,diagonal:new p};g.fromPoints=function(e,t){if(a(t)||(t=new g),!a(e)||0===e.length)return t.halfAxes=p.ZERO,t.center=r.ZERO,t;var i,n=e.length,o=r.clone(e[0],v);for(i=1;i<n;i++)r.add(o,e[i],o);var s=1/n;r.multiplyByScalar(o,s,o);var l,u=0,c=0,d=0,h=0,f=0,m=0;for(i=0;i<n;i++)l=r.subtract(e[i],o,y),u+=l.x*l.x,c+=l.x*l.y,d+=l.x*l.z,h+=l.y*l.y,f+=l.y*l.z,m+=l.z*l.z;u*=s,c*=s,d*=s,h*=s,f*=s,m*=s;var _=T;_[0]=u,_[1]=c,_[2]=d,_[3]=c,_[4]=h,_[5]=f,_[6]=d,_[7]=f,_[8]=m;var A=p.computeEigenDecomposition(_,E),x=p.clone(A.unitary,t.halfAxes),P=p.getColumn(x,0,C),D=p.getColumn(x,1,S),I=p.getColumn(x,2,w),O=-Number.MAX_VALUE,M=-Number.MAX_VALUE,R=-Number.MAX_VALUE,L=Number.MAX_VALUE,N=Number.MAX_VALUE,k=Number.MAX_VALUE;for(i=0;i<n;i++)l=e[i],O=Math.max(r.dot(P,l),O),M=Math.max(r.dot(D,l),M),R=Math.max(r.dot(I,l),R),L=Math.min(r.dot(P,l),L),N=Math.min(r.dot(D,l),N),k=Math.min(r.dot(I,l),k);P=r.multiplyByScalar(P,.5*(L+O),P),D=r.multiplyByScalar(D,.5*(N+M),D),I=r.multiplyByScalar(I,.5*(k+R),I);var F=r.add(P,D,t.center);r.add(F,I,F);var B=b;return B.x=O-L,B.y=M-N,B.z=R-k,r.multiplyByScalar(B,.5,B),p.multiplyByScale(t.halfAxes,B,t.halfAxes),t};var A=new r,x=new r,P=new i,D=new r,I=[new i,new i,new i,new i,new i,new i,new i,new i],O=[new r,new r,new r,new r,new r,new r,new r,new r],M=[new t,new t,new t,new t,new t,new t,new t,new t];g.fromRectangle=function(e,t,r,i,n){t=o(t,0),r=o(r,0),i=o(i,l.WGS84);var a=m.center(e,P),s=i.cartographicToCartesian(a,D),c=new u(s,i),d=c.plane,h=I[0],p=I[1],g=I[2],v=I[3],y=I[4],b=I[5],C=I[6],S=I[7],w=a.longitude,T=e.south<0&&e.north>0?0:a.latitude;C.latitude=b.latitude=y.latitude=e.south,S.latitude=v.latitude=T,h.latitude=p.latitude=g.latitude=e.north,C.longitude=S.longitude=h.longitude=e.west,b.longitude=p.longitude=w,y.longitude=v.longitude=g.longitude=e.east,g.height=p.height=h.height=S.height=C.height=b.height=y.height=v.height=r,i.cartographicArrayToCartesianArray(I,O),c.projectPointsToNearestOnPlane(O,M);var E=Math.min(M[6].x,M[7].x,M[0].x),A=Math.max(M[2].x,M[3].x,M[4].x),x=Math.min(M[4].y,M[5].y,M[6].y),R=Math.max(M[0].y,M[1].y,M[2].y);return g.height=h.height=y.height=C.height=t,i.cartographicArrayToCartesianArray(I,O),_(c,E,A,x,R,Math.min(f.getPointDistance(d,O[0]),f.getPointDistance(d,O[2]),f.getPointDistance(d,O[4]),f.getPointDistance(d,O[6])),r,n)},g.clone=function(e,t){if(a(e))return a(t)?(r.clone(e.center,t.center),p.clone(e.halfAxes,t.halfAxes),t):new g(e.center,e.halfAxes)},g.intersectPlane=function(e,t){var i=e.center,n=t.normal,o=e.halfAxes,a=n.x,s=n.y,l=n.z,u=Math.abs(a*o[p.COLUMN0ROW0]+s*o[p.COLUMN0ROW1]+l*o[p.COLUMN0ROW2])+Math.abs(a*o[p.COLUMN1ROW0]+s*o[p.COLUMN1ROW1]+l*o[p.COLUMN1ROW2])+Math.abs(a*o[p.COLUMN2ROW0]+s*o[p.COLUMN2ROW1]+l*o[p.COLUMN2ROW2]),d=r.dot(n,i)+t.distance;return d<=-u?c.OUTSIDE:d>=u?c.INSIDE:c.INTERSECTING};var R=new r,L=new r,N=new r,k=new r;g.distanceSquaredTo=function(e,t){var i=r.subtract(t,e.center,A),n=e.halfAxes,o=p.getColumn(n,0,R),a=p.getColumn(n,1,L),s=p.getColumn(n,2,N),l=r.magnitude(o),u=r.magnitude(a),c=r.magnitude(s);r.normalize(o,o),r.normalize(a,a),r.normalize(s,s);var d=k;d.x=r.dot(i,o),d.y=r.dot(i,a),d.z=r.dot(i,s);var h,f=0;return d.x<-l?(h=d.x+l,f+=h*h):d.x>l&&(h=d.x-l,f+=h*h),d.y<-u?(h=d.y+u,f+=h*h):d.y>u&&(h=d.y-u,f+=h*h),d.z<-c?(h=d.z+c,f+=h*h):d.z>c&&(h=d.z-c,f+=h*h),f};var F=new r,B=new r;g.computePlaneDistances=function(e,t,i,n){a(n)||(n=new d);var o=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,l=e.center,u=e.halfAxes,c=p.getColumn(u,0,R),h=p.getColumn(u,1,L),f=p.getColumn(u,2,N),m=r.add(c,h,F);r.add(m,f,m),r.add(m,l,m);var g=r.subtract(m,t,B),_=r.dot(i,g);return o=Math.min(_,o),s=Math.max(_,s),r.add(l,c,m),r.add(m,h,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),r.add(l,c,m),r.subtract(m,h,m),r.add(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),r.add(l,c,m),r.subtract(m,h,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),r.subtract(l,c,m),r.add(m,h,m),r.add(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),r.subtract(l,c,m),r.add(m,h,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),r.subtract(l,c,m),r.subtract(m,h,m),r.add(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),r.subtract(l,c,m),r.subtract(m,h,m),r.subtract(m,f,m),r.subtract(m,t,g),_=r.dot(i,g),o=Math.min(_,o),s=Math.max(_,s),n.start=o,n.stop=s,n};var U=new e;return g.isOccluded=function(t,r){var i=e.fromOrientedBoundingBox(t,U);return!r.isBoundingSphereVisible(i)},g.prototype.intersectPlane=function(e){return g.intersectPlane(this,e)},g.prototype.distanceSquaredTo=function(e){return g.distanceSquaredTo(this,e)},g.prototype.computePlaneDistances=function(e,t,r){return g.computePlaneDistances(this,e,t,r)},g.prototype.isOccluded=function(e){return g.isOccluded(this,e)},g.equals=function(e,t){return e===t||a(e)&&a(t)&&r.equals(e.center,t.center)&&p.equals(e.halfAxes,t.halfAxes)},g.prototype.clone=function(e){return g.clone(this,e)},g.prototype.equals=function(e){return g.equals(this,e)},g}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e,t,i,a,u,h){var g,_,v,y;if(o(e)&&o(t)&&o(i)&&o(a)){var b=e.minimum,C=e.maximum,S=r.subtract(C,b,d),w=i-t;g=Math.max(r.maximumComponent(S),w)<m-1?l.BITS12:l.NONE,_=e.center,v=s.inverseTransformation(a,new s);var T=r.negate(b,c);s.multiply(s.fromTranslation(T,p),v,v);var E=c;E.x=1/S.x,E.y=1/S.y,E.z=1/S.z,s.multiply(s.fromScale(E,p),v,v),y=s.clone(a),s.setTranslation(y,r.ZERO,y),a=s.clone(a,new s);var A=s.fromTranslation(b,p),x=s.fromScale(S,f),P=s.multiply(A,x,p);s.multiply(a,P,a),s.multiply(y,P,y)}this.quantization=g,this.minimumHeight=t,this.maximumHeight=i,this.center=_,this.toScaledENU=v,this.fromScaledENU=a,this.matrix=y,this.hasVertexNormals=u,this.hasWebMercatorT=n(h,!1)}var c=new r,d=new r,h=new t,p=new s,f=new s,m=Math.pow(2,12);u.prototype.encode=function(i,n,o,u,d,p,f){var m=u.x,g=u.y;if(this.quantization===l.BITS12){o=s.multiplyByPoint(this.toScaledENU,o,c),o.x=a.clamp(o.x,0,1),o.y=a.clamp(o.y,0,1),o.z=a.clamp(o.z,0,1);var _=this.maximumHeight-this.minimumHeight,v=a.clamp((d-this.minimumHeight)/_,0,1);t.fromElements(o.x,o.y,h);var y=e.compressTextureCoordinates(h);t.fromElements(o.z,v,h);var b=e.compressTextureCoordinates(h);t.fromElements(m,g,h);var C=e.compressTextureCoordinates(h);if(i[n++]=y,i[n++]=b,i[n++]=C,this.hasWebMercatorT){t.fromElements(f,0,h);var S=e.compressTextureCoordinates(h);i[n++]=S}}else r.subtract(o,this.center,c),i[n++]=c.x,i[n++]=c.y,i[n++]=c.z,i[n++]=d,i[n++]=m,i[n++]=g,this.hasWebMercatorT&&(i[n++]=f);return this.hasVertexNormals&&(i[n++]=e.octPackFloat(p)),n},u.prototype.decodePosition=function(t,i,n){if(o(n)||(n=new r),i*=this.getStride(),this.quantization===l.BITS12){var a=e.decompressTextureCoordinates(t[i],h);n.x=a.x,n.y=a.y;var u=e.decompressTextureCoordinates(t[i+1],h);return n.z=u.x,s.multiplyByPoint(this.fromScaledENU,n,n)}return n.x=t[i],n.y=t[i+1],n.z=t[i+2],r.add(n,this.center,n)},u.prototype.decodeTextureCoordinates=function(r,i,n){return o(n)||(n=new t),i*=this.getStride(),this.quantization===l.BITS12?e.decompressTextureCoordinates(r[i+2],n):t.fromElements(r[i+4],r[i+5],n)},u.prototype.decodeHeight=function(t,r){if(r*=this.getStride(),this.quantization===l.BITS12){return e.decompressTextureCoordinates(t[r+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[r+3]},u.prototype.getOctEncodedNormal=function(e,r,i){r=(r+1)*this.getStride()-1;var n=e[r]/256,o=Math.floor(n),a=256*(n-o);return t.fromElements(o,a,i)},u.prototype.getStride=function(){var e;switch(this.quantization){case l.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var g={position3DAndHeight:0,textureCoordAndEncodedNormals:1},_={compressed0:0,compressed1:1};return u.prototype.getAttributes=function(e){var t,r=i.FLOAT,n=i.getSizeInBytes(r);if(this.quantization===l.NONE){var o=2;return this.hasWebMercatorT&&++o,this.hasVertexNormals&&++o,t=(4+o)*n,[{index:g.position3DAndHeight,vertexBuffer:e,componentDatatype:r,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:g.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:r,componentsPerAttribute:o,offsetInBytes:4*n,strideInBytes:t}]}var a=3,s=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++a,this.hasWebMercatorT&&this.hasVertexNormals?(++s,t=(a+s)*n,[{index:_.compressed0,vertexBuffer:e,componentDatatype:r,componentsPerAttribute:a,offsetInBytes:0,strideInBytes:t},{index:_.compressed1,vertexBuffer:e,componentDatatype:r,componentsPerAttribute:s,offsetInBytes:a*n,strideInBytes:t}]):[{index:_.compressed0,vertexBuffer:e,componentDatatype:r,componentsPerAttribute:a}]},u.prototype.getAttributeLocations=function(){return this.quantization===l.NONE?g:_},u.clone=function(e,t){return o(t)||(t=new u),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=r.clone(e.center),t.toScaledENU=s.clone(e.toScaledENU),t.fromScaledENU=s.clone(e.fromScaledENU),t.matrix=s.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},u}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){this._ellipsoid=r(e,a.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return n(l.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),l.mercatorAngleToGeodeticLatitude=function(e){return s.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},l.geodeticLatitudeToMercatorAngle=function(e){e>l.MaximumLatitude?e=l.MaximumLatitude:e<-l.MaximumLatitude&&(e=-l.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},l.MaximumLatitude=l.mercatorAngleToGeodeticLatitude(Math.PI),l.prototype.project=function(t,r){var n=this._semimajorAxis,o=t.longitude*n,a=l.geodeticLatitudeToMercatorAngle(t.latitude)*n,s=t.height;return i(r)?(r.x=o,r.y=a,r.z=s,r):new e(o,a,s)},l.prototype.unproject=function(e,r){var n=this._oneOverSemimajorAxis,o=e.x*n,a=l.mercatorAngleToGeodeticLatitude(e.y*n),s=e.z;return i(r)?(r.longitude=o,r.latitude=a,r.height=s,r):new t(o,a,s)},l}),define("Core/HeightmapTessellator",["./AxisAlignedBoundingBox","./BoundingSphere","./Cartesian2","./Cartesian3","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidalOccluder","./freezeObject","./Math","./Matrix4","./OrientedBoundingBox","./Rectangle","./TerrainEncoding","./Transforms","./WebMercatorProjection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";var _={};_.DEFAULT_STRUCTURE=u({heightScale:1,heightOffset:0,elementsPerHeight:1,stride:1,elementMultiplier:256,isBigEndian:!1});var v=new i,y=new d,b=new i,C=new i;return _.computeVertices=function(a){var u,S,w,T,E=Math.cos,A=Math.sin,x=Math.sqrt,P=Math.atan,D=Math.exp,I=c.PI_OVER_TWO,O=c.toRadians,M=a.heightmap,R=a.width,L=a.height,N=a.skirtHeight,k=n(a.isGeographic,!0),F=n(a.ellipsoid,s.WGS84),B=1/F.maximumRadius,U=a.nativeRectangle,V=a.rectangle;o(V)?(u=V.west,S=V.south,w=V.east,T=V.north):k?(u=O(U.west),S=O(U.south),w=O(U.east),T=O(U.north)):(u=U.west*B,S=I-2*P(D(-U.south*B)),w=U.east*B,T=I-2*P(D(-U.north*B)));var z=a.relativeToCenter,G=o(z);z=G?z:i.ZERO;var W=n(a.exaggeration,1),H=n(a.includeWebMercatorT,!1),j=n(a.structure,_.DEFAULT_STRUCTURE),q=n(j.heightScale,_.DEFAULT_STRUCTURE.heightScale),Y=n(j.heightOffset,_.DEFAULT_STRUCTURE.heightOffset),X=n(j.elementsPerHeight,_.DEFAULT_STRUCTURE.elementsPerHeight),Q=n(j.stride,_.DEFAULT_STRUCTURE.stride),Z=n(j.elementMultiplier,_.DEFAULT_STRUCTURE.elementMultiplier),K=n(j.isBigEndian,_.DEFAULT_STRUCTURE.isBigEndian),J=p.computeWidth(U),$=p.computeHeight(U),ee=J/(R-1),te=$/(L-1);k||(J*=B,$*=B);var re,ie,ne=F.radiiSquared,oe=ne.x,ae=ne.y,se=ne.z,le=65536,ue=-65536,ce=m.eastNorthUpToFixedFrame(z,F),de=d.inverseTransformation(ce,y);H&&(re=g.geodeticLatitudeToMercatorAngle(S),ie=1/(g.geodeticLatitudeToMercatorAngle(T)-re));var he=b;he.x=Number.POSITIVE_INFINITY,he.y=Number.POSITIVE_INFINITY,he.z=Number.POSITIVE_INFINITY;var pe=C;pe.x=Number.NEGATIVE_INFINITY,pe.y=Number.NEGATIVE_INFINITY,pe.z=Number.NEGATIVE_INFINITY;var fe=Number.POSITIVE_INFINITY,me=R+(N>0?2:0),ge=L+(N>0?2:0),_e=me*ge,ve=new Array(_e),ye=new Array(_e),be=new Array(_e),Ce=H?new Array(_e):[],Se=0,we=L,Te=0,Ee=R;N>0&&(--Se,++we,--Te,++Ee);for(var Ae=0,xe=Se;xe<we;++xe){var Pe=xe;Pe<0&&(Pe=0),Pe>=L&&(Pe=L-1);var De=U.north-te*Pe;De=k?O(De):I-2*P(D(-De*B));var Ie=E(De),Oe=A(De),Me=se*Oe,Re=(De-S)/(T-S);Re=c.clamp(Re,0,1);var Le;H&&(Le=(g.geodeticLatitudeToMercatorAngle(De)-re)*ie);for(var Ne=Te;Ne<Ee;++Ne){var ke=Ne;ke<0&&(ke=0),ke>=R&&(ke=R-1);var Fe=U.west+ee*ke;k?Fe=O(Fe):Fe*=B;var Be,Ue=Pe*(R*Q)+ke*Q;if(1===X)Be=M[Ue];else{Be=0;var Ve;if(K)for(Ve=0;Ve<X;++Ve)Be=Be*Z+M[Ue+Ve];else for(Ve=X-1;Ve>=0;--Ve)Be=Be*Z+M[Ue+Ve]}Be=(Be*q+Y)*W;var ze=(Fe-u)/(w-u);if(ze=c.clamp(ze,0,1),be[Ae]=new r(ze,Re),ue=Math.max(ue,Be),le=Math.min(le,Be),Ne!==ke||xe!==Pe){Ne<0?Fe-=1e-5*J:Fe+=1e-5*J,xe<0?De+=1e-5*$:De-=1e-5*$,Ie=E(De),Oe=A(De),Me=se*Oe,Be-=N}var Ge=Ie*E(Fe),We=Ie*A(Fe),He=oe*Ge,je=ae*We,qe=x(He*Ge+je*We+Me*Oe),Ye=1/qe,Xe=He*Ye,Qe=je*Ye,Ze=Me*Ye,Ke=new i;Ke.x=Xe+Ge*Be,Ke.y=Qe+We*Be,Ke.z=Ze+Oe*Be,ve[Ae]=Ke,ye[Ae]=Be,H&&(Ce[Ae]=Le),Ae++,d.multiplyByPoint(de,Ke,v),i.minimumByComponent(v,he,he),i.maximumByComponent(v,pe,pe),fe=Math.min(fe,Be)}}var Je,$e=t.fromPoints(ve);o(V)&&V.width<c.PI_OVER_TWO+c.EPSILON5&&(Je=h.fromRectangle(V,le,ue,F));var et;if(G){et=new l(F).computeHorizonCullingPoint(z,ve)}for(var tt=new e(he,pe,z),rt=new f(tt,fe,ue,ce,!1,H),it=new Float32Array(_e*rt.getStride()),nt=0,ot=0;ot<_e;++ot)nt=rt.encode(it,nt,ve[ot],be[ot],ye[ot],void 0,Ce[ot]);return{vertices:it,maximumHeight:ue,minimumHeight:le,encoding:rt,boundingSphere3D:$e,orientedBoundingBox:Je,occludeePointInScaledSpace:et}},_}),define("Core/destroyObject",["./defaultValue","./DeveloperError"],function(e,t){"use strict";function r(){return!0}function i(t,i){function n(){}i=e(i,"This object was destroyed, i.e., destroy() was called.");for(var o in t)"function"==typeof t[o]&&(t[o]=n);t.isDestroyed=r}return i}),define("Core/TaskProcessor",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./destroyObject","./DeveloperError","./Event","./getAbsoluteUri","./isCrossOriginUrl","./RuntimeError","require"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(){if(!i(g._canTransferArrayBuffer)){var t=new Worker(p("Workers/transferTypedArrayTest.js"));t.postMessage=r(t.webkitPostMessage,t.postMessage);var n=new Int8Array([99]);try{t.postMessage({array:n},[n.buffer])}catch(e){return g._canTransferArrayBuffer=!1,g._canTransferArrayBuffer}var o=e.defer();t.onmessage=function(e){var r=e.data.array,n=i(r)&&99===r[0];o.resolve(n),t.terminate(),g._canTransferArrayBuffer=n},g._canTransferArrayBuffer=o.promise}return g._canTransferArrayBuffer}function h(e,t){--e._activeTasks;var r=t.id;if(i(r)){var n=e._deferreds,a=n[r];if(i(t.error)){var s=t.error;"RuntimeError"===s.name?(s=new u(t.error.message),s.stack=t.error.stack):"DeveloperError"===s.name&&(s=new o(t.error.message),s.stack=t.error.stack),v.raiseEvent(s),a.reject(s)}else v.raiseEvent(),a.resolve(t.result);delete n[r]}}function p(e){var r=t(e);if(l(r)){var i,n='importScripts("'+r+'");';try{i=new Blob([n],{type:"application/javascript"})}catch(e){var o=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,a=new o;a.append(n),i=a.getBlob("application/javascript")}r=(window.URL||window.webkitURL).createObjectURL(i)}return r}function f(){return i(_)||(_=p("Workers/cesiumWorkerBootstrapper.js")),_}function m(e){var n=new Worker(f());n.postMessage=r(n.webkitPostMessage,n.postMessage);var o={loaderConfig:{},workerModule:g._workerModulePrefix+e._workerName};return i(g._loaderConfig)?o.loaderConfig=g._loaderConfig:i(define.amd)&&!define.amd.toUrlUndefined&&i(c.toUrl)?o.loaderConfig.baseUrl=s("..",t("Workers/cesiumWorkerBootstrapper.js")):o.loaderConfig.paths={Workers:t("Workers")},n.postMessage(o),n.onmessage=function(t){h(e,t.data)},n}function g(e,t){this._workerName=e,this._maximumActiveTasks=r(t,5),this._activeTasks=0,this._deferreds={},this._nextID=0}var _,v=new a,y=[];return g.prototype.scheduleTask=function(t,r){if(i(this._worker)||(this._worker=m(this)),!(this._activeTasks>=this._maximumActiveTasks)){++this._activeTasks;var n=this;return e(d(),function(o){i(r)?o||(r.length=0):r=y;var a=n._nextID++,s=e.defer();return n._deferreds[a]=s,n._worker.postMessage({id:a,parameters:t,canTransferArrayBuffer:o},r),s.promise})}},g.prototype.isDestroyed=function(){return!1},g.prototype.destroy=function(){return i(this._worker)&&this._worker.terminate(),n(this)},g.taskCompletedEvent=v,g._defaultWorkerModulePrefix="Workers/",g._workerModulePrefix=g._defaultWorkerModulePrefix,g._loaderConfig=void 0,g._canTransferArrayBuffer=void 0,g}),define("Core/TerrainMesh",["./defaultValue"],function(e){"use strict";function t(t,r,i,n,o,a,s,l,u,c,d){this.center=t,this.vertices=r,this.stride=e(l,6),this.indices=i,this.minimumHeight=n,this.maximumHeight=o,this.boundingSphere3D=a,this.occludeePointInScaledSpace=s,this.orientedBoundingBox=u,this.encoding=c,this.exaggeration=d}return t}),define("Core/TerrainProvider",["./defined","./defineProperties","./DeveloperError","./Math"],function(e,t,r,i){"use strict";function n(){r.throwInstantiationError()}t(n.prototype,{errorEvent:{get:r.throwInstantiationError},credit:{get:r.throwInstantiationError},tilingScheme:{get:r.throwInstantiationError},ready:{get:r.throwInstantiationError},readyPromise:{get:r.throwInstantiationError},hasWaterMask:{get:r.throwInstantiationError},hasVertexNormals:{get:r.throwInstantiationError},availability:{get:r.throwInstantiationError}});var o=[];return n.getRegularGridIndices=function(t,r){var i=o[t];e(i)||(o[t]=i=[]);var n=i[r];if(!e(n)){n=i[r]=new Uint16Array((t-1)*(r-1)*6);for(var a=0,s=0,l=0;l<r-1;++l){for(var u=0;u<t-1;++u){var c=a,d=c+t,h=d+1,p=c+1;n[s++]=c,n[s++]=d,n[s++]=p,n[s++]=p,n[s++]=d,n[s++]=h,++a}++a}}return n},n.heightmapTerrainQuality=.25,n.getEstimatedLevelZeroGeometricErrorForAHeightmap=function(e,t,r){return 2*e.maximumRadius*Math.PI*n.heightmapTerrainQuality/(t*r)},n.prototype.requestTileGeometry=r.throwInstantiationError,n.prototype.getLevelMaximumGeometricError=r.throwInstantiationError,n.prototype.getTileDataAvailable=r.throwInstantiationError,n}),define("Core/HeightmapTerrainData",["../ThirdParty/when","./defaultValue","./defined","./defineProperties","./DeveloperError","./GeographicTilingScheme","./HeightmapTessellator","./Math","./Rectangle","./TaskProcessor","./TerrainEncoding","./TerrainMesh","./TerrainProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){this._buffer=e.buffer,this._width=e.width,this._height=e.height,this._childTileMask=t(e.childTileMask,15);var i=a.DEFAULT_STRUCTURE,n=e.structure;r(n)?n!==i&&(n.heightScale=t(n.heightScale,i.heightScale),n.heightOffset=t(n.heightOffset,i.heightOffset),n.elementsPerHeight=t(n.elementsPerHeight,i.elementsPerHeight),n.stride=t(n.stride,i.stride),n.elementMultiplier=t(n.elementMultiplier,i.elementMultiplier),n.isBigEndian=t(n.isBigEndian,i.isBigEndian)):n=i,this._structure=n,this._createdByUpsampling=t(e.createdByUpsampling,!1),this._waterMask=e.waterMask,this._skirtHeight=void 0,this._bufferType=this._buffer.constructor,this._mesh=void 0}function f(e,t,r,i,n,o,a,s,l,u){var c=(l-o.west)*(a-1)/(o.east-o.west),d=(u-o.south)*(s-1)/(o.north-o.south),h=0|c,p=h+1;p>=a&&(p=a-1,h=a-2);var f=0|d,m=f+1;m>=s&&(m=s-1,f=s-2);var v=c-h,y=d-f;return f=s-1-f,m=s-1-m,g(v,y,_(e,t,r,i,n,f*a+h),_(e,t,r,i,n,f*a+p),_(e,t,r,i,n,m*a+h),_(e,t,r,i,n,m*a+p))}function m(e,t,r,i,n,o,a,s,l,u,c){var d=(l-o.west)*(a-1)/(o.east-o.west),h=(u-o.south)*(s-1)/(o.north-o.south);n>0&&(d+=1,h+=1,a+=2,s+=2);var p=n>0?a-1:a,f=0|d,m=f+1;m>=p&&(m=a-1,f=a-2);var _=n>0?s-1:s,v=0|h,y=v+1;y>=_&&(y=s-1,v=s-2);var b=d-f,C=h-v;return v=s-1-v,y=s-1-y,g(b,C,(t.decodeHeight(e,v*a+f)/c-r)/i,(t.decodeHeight(e,v*a+m)/c-r)/i,(t.decodeHeight(e,y*a+f)/c-r)/i,(t.decodeHeight(e,y*a+m)/c-r)/i)}function g(e,t,r,i,n,o){return t<e?r+e*(i-r)+t*(o-i):r+e*(o-n)+t*(n-r)}function _(e,t,r,i,n,o){o*=i;var a,s=0;if(n)for(a=0;a<t;++a)s=s*r+e[o+a];else for(a=t-1;a>=0;--a)s=s*r+e[o+a];return s}function v(e,t,r,i,n,o,a,s){a*=n;var l;if(o)for(l=0;l<t-1;++l)e[a+l]=s/i|0,s-=e[a+l]*i,i/=r;else for(l=t-1;l>0;--l)e[a+l]=s/i|0,s-=e[a+l]*i,i/=r;e[a+l]=s}i(p.prototype,{credits:{get:function(){}},waterMask:{get:function(){return this._waterMask}}});var y=new u("createVerticesFromHeightmap");return p.prototype.createMesh=function(i,n,a,s,u){var p=i.ellipsoid,f=i.tileXYToNativeRectangle(n,a,s),m=i.tileXYToRectangle(n,a,s);u=t(u,1);var g=p.cartographicToCartesian(l.center(m)),_=this._structure,v=h.getEstimatedLevelZeroGeometricErrorForAHeightmap(p,this._width,i.getNumberOfXTilesAtLevel(0)),b=v/(1<<s);this._skirtHeight=Math.min(4*b,1e3);var C=y.scheduleTask({heightmap:this._buffer,structure:_,includeWebMercatorT:!0,width:this._width,height:this._height,nativeRectangle:f,rectangle:m,relativeToCenter:g,ellipsoid:p,skirtHeight:this._skirtHeight,isGeographic:i instanceof o,exaggeration:u});if(r(C)){var S=this;return e(C,function(e){return S._mesh=new d(g,new Float32Array(e.vertices),h.getRegularGridIndices(e.gridWidth,e.gridHeight),e.minimumHeight,e.maximumHeight,e.boundingSphere3D,e.occludeePointInScaledSpace,e.numberOfAttributes,e.orientedBoundingBox,c.clone(e.encoding),u),S._buffer=void 0,S._mesh})}},p.prototype.interpolateHeight=function(e,t,i){var n,o=this._width,a=this._height,s=this._structure,l=s.stride,u=s.elementsPerHeight,c=s.elementMultiplier,d=s.isBigEndian,h=s.heightOffset,p=s.heightScale;if(r(this._mesh)){n=m(this._mesh.vertices,this._mesh.encoding,h,p,this._skirtHeight,e,o,a,t,i,this._mesh.exaggeration)}else n=f(this._buffer,u,c,l,d,e,o,a,t,i),n=n*p+h;return n},p.prototype.upsample=function(e,t,i,n,o,a,l){var u=this._width,c=this._height,d=this._structure,h=this._skirtHeight,f=d.stride,g=new this._bufferType(u*c*f),_=this._mesh;if(r(_)){for(var y=_.vertices,b=_.encoding,C=e.tileXYToRectangle(t,i,n),S=e.tileXYToRectangle(o,a,l),w=d.heightOffset,T=d.heightScale,E=_.exaggeration,A=d.elementsPerHeight,x=d.elementMultiplier,P=d.isBigEndian,D=Math.pow(x,A-1),I=0;I<c;++I)for(var O=s.lerp(S.north,S.south,I/(c-1)),M=0;M<u;++M){var R=s.lerp(S.west,S.east,M/(u-1)),L=m(y,b,w,T,h,C,u,c,R,O,E);L=L<d.lowestEncodedHeight?d.lowestEncodedHeight:L,L=L>d.highestEncodedHeight?d.highestEncodedHeight:L,v(g,A,x,D,f,P,I*u+M,L)}return new p({buffer:g,width:u,height:c,childTileMask:0,structure:this._structure,createdByUpsampling:!0})}},p.prototype.isChildAvailable=function(e,t,r,i){var n=2;return r!==2*e&&++n,i!==2*t&&(n-=2),0!=(this._childTileMask&1<<n)},p.prototype.wasCreatedByUpsampling=function(){return this._createdByUpsampling},p}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,i,n){"use strict";var o={UNSIGNED_BYTE:n.UNSIGNED_BYTE,UNSIGNED_SHORT:n.UNSIGNED_SHORT,UNSIGNED_INT:n.UNSIGNED_INT};return o.getSizeInBytes=function(e){switch(e){case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},o.validate=function(t){return e(t)&&(t===o.UNSIGNED_BYTE||t===o.UNSIGNED_SHORT||t===o.UNSIGNED_INT)},o.createTypedArray=function(e,t){return e>=i.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},o.createTypedArrayFromArrayBuffer=function(e,t,r,n){return e>=i.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,n):new Uint16Array(t,r,n)},r(o)}),define("Core/Intersections2D",["./Cartesian3","./defined","./DeveloperError"],function(e,t,r){"use strict";var i={};return i.clipTriangleAtAxisAlignedThreshold=function(e,r,i,n,o,a){t(a)?a.length=0:a=[];var s,l,u;r?(s=i<e,l=n<e,u=o<e):(s=i>e,l=n>e,u=o>e);var c,d,h,p,f,m,g=s+l+u;return 1===g?s?(c=(e-i)/(n-i),d=(e-i)/(o-i),a.push(1),a.push(2),1!==d&&(a.push(-1),a.push(0),a.push(2),a.push(d)),1!==c&&(a.push(-1),a.push(0),a.push(1),a.push(c))):l?(h=(e-n)/(o-n),p=(e-n)/(i-n),a.push(2),a.push(0),1!==p&&(a.push(-1),a.push(1),a.push(0),a.push(p)),1!==h&&(a.push(-1),a.push(1),a.push(2),a.push(h))):u&&(f=(e-o)/(i-o),m=(e-o)/(n-o),a.push(0),a.push(1),1!==m&&(a.push(-1),a.push(2),a.push(1),a.push(m)),1!==f&&(a.push(-1),a.push(2),a.push(0),a.push(f))):2===g?s||i===e?l||n===e?u||o===e||(d=(e-i)/(o-i),h=(e-n)/(o-n),a.push(2),a.push(-1),a.push(0),a.push(2),a.push(d),a.push(-1),a.push(1),a.push(2),a.push(h)):(m=(e-o)/(n-o),c=(e-i)/(n-i),a.push(1),a.push(-1),a.push(2),a.push(1),a.push(m),a.push(-1),a.push(0),a.push(1),a.push(c)):(p=(e-n)/(i-n),f=(e-o)/(i-o),a.push(0),a.push(-1),a.push(1),a.push(0),a.push(p),a.push(-1),a.push(2),a.push(0),a.push(f)):3!==g&&(a.push(0),a.push(1),a.push(2)),a},i.computeBarycentricCoordinates=function(r,i,n,o,a,s,l,u,c){var d=n-l,h=l-a,p=s-u,f=o-u,m=1/(p*d+h*f),g=i-u,_=r-l,v=(p*_+h*g)*m,y=(-f*_+d*g)*m,b=1-v-y;return t(c)?(c.x=v,c.y=y,c.z=b,c):new e(v,y,b)},i}), +define("Core/QuantizedMeshTerrainData",["../ThirdParty/when","./BoundingSphere","./Cartesian2","./Cartesian3","./defaultValue","./defined","./defineProperties","./DeveloperError","./IndexDatatype","./Intersections2D","./Math","./OrientedBoundingBox","./TaskProcessor","./TerrainEncoding","./TerrainMesh"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){function t(e,t){return a[e]-a[t]}function r(e,t){return o[e]-o[t]}this._quantizedVertices=e.quantizedVertices,this._encodedNormals=e.encodedNormals,this._indices=e.indices,this._minimumHeight=e.minimumHeight,this._maximumHeight=e.maximumHeight,this._boundingSphere=e.boundingSphere,this._orientedBoundingBox=e.orientedBoundingBox,this._horizonOcclusionPoint=e.horizonOcclusionPoint,this._credits=e.credits;var i=this._quantizedVertices.length/3,o=this._uValues=this._quantizedVertices.subarray(0,i),a=this._vValues=this._quantizedVertices.subarray(i,2*i);this._heightValues=this._quantizedVertices.subarray(2*i,3*i),this._westIndices=g(e.westIndices,t,i),this._southIndices=g(e.southIndices,r,i),this._eastIndices=g(e.eastIndices,t,i),this._northIndices=g(e.northIndices,r,i),this._westSkirtHeight=e.westSkirtHeight,this._southSkirtHeight=e.southSkirtHeight,this._eastSkirtHeight=e.eastSkirtHeight,this._northSkirtHeight=e.northSkirtHeight,this._childTileMask=n(e.childTileMask,15),this._createdByUpsampling=n(e.createdByUpsampling,!1),this._waterMask=e.waterMask,this._mesh=void 0}function g(e,t,r){y.length=e.length;for(var i=!1,n=0,o=e.length;n<o;++n)y[n]=e[n],i=i||n>0&&t(e[n-1],e[n])>0;return i?(y.sort(t),l.createTypedArray(r,y)):e}function _(e,t,r){for(var i=e._mesh,n=i.vertices,o=i.encoding,a=i.indices,s=0,l=a.length;s<l;s+=3){var c=a[s],d=a[s+1],h=a[s+2],p=o.decodeTextureCoordinates(n,c,T),f=o.decodeTextureCoordinates(n,d,E),m=o.decodeTextureCoordinates(n,h,A),g=u.computeBarycentricCoordinates(t,r,p.x,p.y,f.x,f.y,m.x,m.y,w);if(g.x>=-1e-15&&g.y>=-1e-15&&g.z>=-1e-15){var _=o.decodeHeight(n,c),v=o.decodeHeight(n,d),y=o.decodeHeight(n,h);return g.x*_+g.y*v+g.z*y}}}function v(e,t,r){for(var i=e._uValues,n=e._vValues,o=e._heightValues,a=e._indices,s=0,l=a.length;s<l;s+=3){var d=a[s],h=a[s+1],p=a[s+2],f=i[d],m=i[h],g=i[p],_=n[d],v=n[h],y=n[p],b=u.computeBarycentricCoordinates(t,r,f,_,m,v,g,y,w);if(b.x>=-1e-15&&b.y>=-1e-15&&b.z>=-1e-15){var C=b.x*o[d]+b.y*o[h]+b.z*o[p];return c.lerp(e._minimumHeight,e._maximumHeight,C/S)}}}a(m.prototype,{credits:{get:function(){return this._credits}},waterMask:{get:function(){return this._waterMask}}});var y=[],b=new h("createVerticesFromQuantizedTerrainMesh");m.prototype.createMesh=function(t,r,i,a,s){var u=t.ellipsoid,c=t.tileXYToRectangle(r,i,a);s=n(s,1);var d=b.scheduleTask({minimumHeight:this._minimumHeight,maximumHeight:this._maximumHeight,quantizedVertices:this._quantizedVertices,octEncodedNormals:this._encodedNormals,includeWebMercatorT:!0,indices:this._indices,westIndices:this._westIndices,southIndices:this._southIndices,eastIndices:this._eastIndices,northIndices:this._northIndices,westSkirtHeight:this._westSkirtHeight,southSkirtHeight:this._southSkirtHeight,eastSkirtHeight:this._eastSkirtHeight,northSkirtHeight:this._northSkirtHeight,rectangle:c,relativeToCenter:this._boundingSphere.center,ellipsoid:u,exaggeration:s});if(o(d)){var h=this;return e(d,function(e){var t=h._quantizedVertices.length/3;t+=h._westIndices.length+h._southIndices.length+h._eastIndices.length+h._northIndices.length;var r=l.createTypedArray(t,e.indices),i=new Float32Array(e.vertices),o=e.center,a=e.minimumHeight,u=e.maximumHeight,c=n(e.boundingSphere,h._boundingSphere),d=n(e.orientedBoundingBox,h._orientedBoundingBox),m=h._horizonOcclusionPoint,g=e.vertexStride,_=p.clone(e.encoding);return h._skirtIndex=e.skirtIndex,h._vertexCountWithoutSkirts=h._quantizedVertices.length/3,h._mesh=new f(o,i,r,a,u,c,m,g,d,_,s),h._quantizedVertices=void 0,h._encodedNormals=void 0,h._indices=void 0,h._uValues=void 0,h._vValues=void 0,h._heightValues=void 0,h._westIndices=void 0,h._southIndices=void 0,h._eastIndices=void 0,h._northIndices=void 0,h._mesh})}};var C=new h("upsampleQuantizedTerrainMesh");m.prototype.upsample=function(r,n,a,s,u,c,h){var p=this._mesh;if(o(this._mesh)){var f=2*n!==u,g=2*a===c,_=r.ellipsoid,v=r.tileXYToRectangle(u,c,h),y=C.scheduleTask({vertices:p.vertices,vertexCountWithoutSkirts:this._vertexCountWithoutSkirts,indices:p.indices,skirtIndex:this._skirtIndex,encoding:p.encoding,minimumHeight:this._minimumHeight,maximumHeight:this._maximumHeight,isEastChild:f,isNorthChild:g,childRectangle:v,ellipsoid:_,exaggeration:p.exaggeration});if(o(y)){var b=Math.min(this._westSkirtHeight,this._eastSkirtHeight);b=Math.min(b,this._southSkirtHeight),b=Math.min(b,this._northSkirtHeight);var S=f?.5*b:this._westSkirtHeight,w=g?.5*b:this._southSkirtHeight,T=f?this._eastSkirtHeight:.5*b,E=g?this._northSkirtHeight:.5*b;return e(y,function(e){var r,n=new Uint16Array(e.vertices),a=l.createTypedArray(n.length/3,e.indices);return o(e.encodedNormals)&&(r=new Uint8Array(e.encodedNormals)),new m({quantizedVertices:n,indices:a,encodedNormals:r,minimumHeight:e.minimumHeight,maximumHeight:e.maximumHeight,boundingSphere:t.clone(e.boundingSphere),orientedBoundingBox:d.clone(e.orientedBoundingBox),horizonOcclusionPoint:i.clone(e.horizonOcclusionPoint),westIndices:e.westIndices,southIndices:e.southIndices,eastIndices:e.eastIndices,northIndices:e.northIndices,westSkirtHeight:S,southSkirtHeight:w,eastSkirtHeight:T,northSkirtHeight:E,childTileMask:0,createdByUpsampling:!0})})}}};var S=32767,w=new i;m.prototype.interpolateHeight=function(e,t,r){var i=c.clamp((t-e.west)/e.width,0,1);i*=S;var n=c.clamp((r-e.south)/e.height,0,1);return n*=S,o(this._mesh)?_(this,i,n):v(this,i,n)};var T=new r,E=new r,A=new r;return m.prototype.isChildAvailable=function(e,t,r,i){var n=2;return r!==2*e&&++n,i!==2*t&&(n-=2),0!=(this._childTileMask&1<<n)},m.prototype.wasCreatedByUpsampling=function(){return this._createdByUpsampling},m}),define("Core/TileAvailability",["./binarySearch","./Cartographic","./defined","./defineProperties","./DeveloperError","./Rectangle"],function(e,t,r,i,n,o){"use strict";function a(e,t){this._tilingScheme=e,this._maximumLevel=t,this._rootNodes=[];for(var r=0;r<e.getNumberOfYTilesAtLevel();++r)for(var i=0;i<e.getNumberOfXTilesAtLevel();++i)this._rootNodes.push(new s(e,void 0,0,i,r))}function s(e,t,r,i,n){this.tilingScheme=e,this.parent=t,this.level=r,this.x=i,this.y=n,this.extent=e.tileXYToRectangle(i,n,r),this.rectangles=[],this._sw=void 0,this._se=void 0,this._nw=void 0,this._ne=void 0}function l(e,t,r,i,n){this.level=e,this.west=t,this.south=r,this.east=i,this.north=n}function u(e,t){var r=Math.max(e.west,t.west),i=Math.max(e.south,t.south),n=Math.min(e.east,t.east);return i<Math.min(e.north,t.north)&&r<n}function c(t,r,i){for(;r.level<t;)if(h(r.nw.extent,i))r=r.nw;else if(h(r.ne.extent,i))r=r.ne;else if(h(r.sw.extent,i))r=r.sw;else{if(!h(r.se.extent,i))break;r=r.se}if(0===r.rectangles.length||r.rectangles[r.rectangles.length-1].level<=i.level)r.rectangles.push(i);else{var n=e(r.rectangles,i.level,d);n<=0&&(n=~n),r.rectangles.splice(n,0,i)}}function d(e,t){return e.level-t}function h(e,t){return t.west>=e.west&&t.east<=e.east&&t.south>=e.south&&t.north<=e.north}function p(e,t){return t.longitude>=e.west&&t.longitude<=e.east&&t.latitude>=e.south&&t.latitude<=e.north}function f(e,t,r){for(var i=0,n=!1;!n;){var o=t._nw&&p(t._nw.extent,r),a=t._ne&&p(t._ne.extent,r),s=t._sw&&p(t._sw.extent,r),l=t._se&&p(t._se.extent,r);if(o+a+s+l>1){o&&(i=Math.max(i,f(t,t._nw,r))),a&&(i=Math.max(i,f(t,t._ne,r))),s&&(i=Math.max(i,f(t,t._sw,r))),l&&(i=Math.max(i,f(t,t._se,r)));break}o?t=t._nw:a?t=t._ne:s?t=t._sw:l?t=t._se:n=!0}for(;t!==e;){for(var u=t.rectangles,c=u.length-1;c>=0&&u[c].level>i;--c){var d=u[c];p(d,r)&&(i=d.level)}t=t.parent}return i}function m(e,t,r){if(t){var i,n=!1;for(i=0;i<r.length;++i)n=n||u(t.extent,r[i]);if(n){var o=t.rectangles;for(i=0;i<o.length;++i){var a=o[i];e[a.level]||(e[a.level]=r),e[a.level]=g(e[a.level],a)}m(e,t._nw,r),m(e,t._ne,r),m(e,t._sw,r),m(e,t._se,r)}}}function g(e,t){for(var r=[],i=0;i<e.length;++i){var n=e[i];u(n,t)?(n.west<t.west&&r.push(new o(n.west,n.south,t.west,n.north)),n.east>t.east&&r.push(new o(t.east,n.south,n.east,n.north)),n.south<t.south&&r.push(new o(Math.max(t.west,n.west),n.south,Math.min(t.east,n.east),t.south)),n.north>t.north&&r.push(new o(Math.max(t.west,n.west),t.north,Math.min(t.east,n.east),n.north))):r.push(n)}return r}var _=new o;a.prototype.addAvailableTileRange=function(e,t,r,i,n){var o=this._tilingScheme;o.tileXYToRectangle(t,r,e,_);var a=_.west,s=_.north;o.tileXYToRectangle(i,n,e,_);for(var d=_.east,h=_.south,p=new l(e,a,h,d,s),f=0;f<this._rootNodes.length;++f){var m=this._rootNodes[f];u(m.extent,p)&&c(this._maximumLevel,m,p)}},a.prototype.computeMaximumLevelAtPosition=function(e){for(var t,r=0;r<this._rootNodes.length;++r){var i=this._rootNodes[r];if(p(i.extent,e)){t=i;break}}return f(void 0,t,e)};var v=[],y=[],b=new o,C=new o;a.prototype.computeBestAvailableLevelOverRectangle=function(e){var t=v;t.length=0,e.east<e.west?(t.push(o.fromRadians(-Math.PI,e.south,e.east,e.north,b)),t.push(o.fromRadians(e.west,e.south,Math.PI,e.north,C))):t.push(e);var i=y;i.length=0;var n;for(n=0;n<this._rootNodes.length;++n)m(i,this._rootNodes[n],t);for(n=i.length-1;n>=0;--n)if(r(i[n])&&0===i[n].length)return n;return 0};var S=new t;return a.prototype.isTileAvailable=function(e,t,r){var i=this._tilingScheme.tileXYToRectangle(t,r,e,_);return o.center(i,S),this.computeMaximumLevelAtPosition(S)>=e},a.prototype.computeChildMaskForTile=function(e,t,r){var i=e+1;if(i>=this._maximumLevel)return 0;var n=0;return n|=this.isTileAvailable(i,2*t,2*r+1)?1:0,n|=this.isTileAvailable(i,2*t+1,2*r+1)?2:0,n|=this.isTileAvailable(i,2*t,2*r)?4:0,n|=this.isTileAvailable(i,2*t+1,2*r)?8:0},i(s.prototype,{nw:{get:function(){return this._nw||(this._nw=new s(this.tilingScheme,this,this.level+1,2*this.x,2*this.y)),this._nw}},ne:{get:function(){return this._ne||(this._ne=new s(this.tilingScheme,this,this.level+1,2*this.x+1,2*this.y)),this._ne}},sw:{get:function(){return this._sw||(this._sw=new s(this.tilingScheme,this,this.level+1,2*this.x,2*this.y+1)),this._sw}},se:{get:function(){return this._se||(this._se=new s(this.tilingScheme,this,this.level+1,2*this.x+1,2*this.y+1)),this._se}}}),a}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var r,i=t.name,n=t.message;r=e(i)&&e(n)?i+": "+n:t.toString();var o=t.stack;return e(o)&&(r+="\n"+o),r}return t}),define("Core/TileProviderError",["./defaultValue","./defined","./formatError"],function(e,t,r){"use strict";function i(t,r,i,n,o,a,s){this.provider=t,this.message=r,this.x=i,this.y=n,this.level=o,this.timesRetried=e(a,0),this.retry=!1,this.error=s}return i.handleError=function(e,n,o,a,s,l,u,c,d){var h=e;return t(e)?(h.provider=n,h.message=a,h.x=s,h.y=l,h.level=u,h.retry=!1,h.error=d,++h.timesRetried):h=new i(n,a,s,l,u,0,d),o.numberOfListeners>0?o.raiseEvent(h):console.log('An error occurred in "'+n.constructor.name+'": '+r(a)),h.retry&&t(c)&&c(),h},i.handleSuccess=function(e){t(e)&&(e.timesRetried=-1)},i}),define("Core/CesiumTerrainProvider",["../ThirdParty/Uri","../ThirdParty/when","./AttributeCompression","./BoundingSphere","./Cartesian3","./Credit","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./Event","./GeographicTilingScheme","./HeightmapTerrainData","./IndexDatatype","./Math","./OrientedBoundingBox","./QuantizedMeshTerrainData","./Resource","./RuntimeError","./TerrainProvider","./TileAvailability","./TileProviderError"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S){"use strict";function w(e){this.resource=e.resource,this.version=e.version,this.isHeightmap=e.isHeightmap,this.tileUrlTemplates=e.tileUrlTemplates,this.availability=e.availability,this.hasVertexNormals=e.hasVertexNormals,this.hasWaterMask=e.hasWaterMask,this.littleEndianExtensionSize=e.littleEndianExtensionSize}function T(e){function r(e){var n;if(!e.format)return n="The tile format is not specified in the layer.json file.",void(m=S.handleError(m,y,y._errorEvent,n,void 0,void 0,void 0,c));if(!e.tiles||0===e.tiles.length)return n="The layer.json file does not specify any tile URL templates.",void(m=S.handleError(m,y,y._errorEvent,n,void 0,void 0,void 0,c));var o=!1,a=!1,l=!0,u=!1;if("heightmap-1.0"===e.format)u=!0,s(y._heightmapStructure)||(y._heightmapStructure={heightScale:.2,heightOffset:-1e3,elementsPerHeight:1,stride:1,elementMultiplier:256,isBigEndian:!1,lowestEncodedHeight:0,highestEncodedHeight:65535}),a=!0,y._requestWaterMask=!0;else if(0!==e.format.indexOf("quantized-mesh-1."))return n='The tile format "'+e.format+'" is invalid or not supported.',void(m=S.handleError(m,y,y._errorEvent,n,void 0,void 0,void 0,c));var d,h=e.tiles,p=e.available;if(s(p)){d=new C(y._tilingScheme,p.length);for(var f=0;f<p.length;++f){var v=p[f],b=y._tilingScheme.getNumberOfYTilesAtLevel(f);s(A[f])||(A[f]=[]);for(var x=0;x<v.length;++x){var P=v[x],D=b-P.endY-1,I=b-P.startY-1;A[f].push([P.startX,D,P.endX,I]),d.addAvailableTileRange(f,P.startX,D,P.endX,I)}}}s(e.extensions)&&-1!==e.extensions.indexOf("octvertexnormals")?o=!0:s(e.extensions)&&-1!==e.extensions.indexOf("vertexnormals")&&(o=!0,l=!1),s(e.extensions)&&-1!==e.extensions.indexOf("watermask")&&(a=!0),y._hasWaterMask=y._hasWaterMask||a,y._hasVertexNormals=y._hasVertexNormals||o,s(e.attribution)&&(E.length>0&&(E+=" "),E+=e.attribution),T.push(new w({resource:g,version:e.version,isHeightmap:u,tileUrlTemplates:h,availability:d,hasVertexNormals:o,hasWaterMask:a,littleEndianExtensionSize:l}));var O=e.parentUrl;if(s(O)){if(!s(d))return console.log("A layer.json can't have a parentUrl if it does't have an available array."),t.resolve();g=g.getDerivedResource({url:O}),g.appendForwardSlash(),_=g.getDerivedResource({url:"layer.json"});var M=_.fetchJson();return t(M,r,i)}return t.resolve()}function i(e){var t="An error occurred while accessing "+_.url+".";m=S.handleError(m,y,y._errorEvent,t,void 0,void 0,void 0,c)}function n(e){r(e).then(function(){if(!s(m)){var e=A.length;if(e>0)for(var t=y._availability=new C(y._tilingScheme,e),r=0;r<e;++r)for(var i=A[r],n=0;n<i.length;++n){var a=i[n];t.addAvailableTileRange(r,a[0],a[1],a[2],a[3])}!s(y._credit)&&E.length>0&&(y._credit=new o({text:E})),y._ready=!0,y._readyPromise.resolve(!0)}})}function l(e){if(s(e)&&404===e.statusCode)return void n({tilejson:"2.1.0",format:"heightmap-1.0",version:"1.0.0",scheme:"tms",tiles:["{z}/{x}/{y}.terrain?v={version}"]});i(e)}function c(){var e=_.fetchJson();t(e,n,l)}s(e.proxy)&&u("CesiumTerrainProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var p=v.createIfNeeded(e.url,{proxy:e.proxy});p.appendForwardSlash(),this._tilingScheme=new h({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:1,ellipsoid:e.ellipsoid}),this._heightmapWidth=65,this._levelZeroMaximumGeometricError=b.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid,this._heightmapWidth,this._tilingScheme.getNumberOfXTilesAtLevel(0)),this._heightmapStructure=void 0,this._hasWaterMask=!1,this._hasVertexNormals=!1,this._requestVertexNormals=a(e.requestVertexNormals,!1),this._requestWaterMask=a(e.requestWaterMask,!1),this._errorEvent=new d;var f=e.credit;"string"==typeof f&&(f=new o({text:f})),this._credit=f,this._availability=void 0,this._ready=!1,this._readyPromise=t.defer();var m,g=p,_=g.getDerivedResource({url:"layer.json"}),y=this,T=this._layers=[],E="",A=[];c()}function E(e){return s(e)&&0!==e.length?{Accept:"application/vnd.quantized-mesh;extensions="+e.join("-")+",application/octet-stream;q=0.9,*/*;q=0.01"}:{Accept:"application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01"}}function A(e,t,r,i,n,o){var a=new Uint16Array(t,0,e._heightmapWidth*e._heightmapWidth);return new p({buffer:a,childTileMask:new Uint8Array(t,a.byteLength,1)[0],waterMask:new Uint8Array(t,a.byteLength+1,t.byteLength-a.byteLength-1),width:e._heightmapWidth,height:e._heightmapWidth,structure:e._heightmapStructure})}function x(e,t,o,a,s,l,u){var c=0,d=3*Float64Array.BYTES_PER_ELEMENT,h=4*Float64Array.BYTES_PER_ELEMENT,p=3*Uint16Array.BYTES_PER_ELEMENT,v=Uint16Array.BYTES_PER_ELEMENT,y=3*v,b=new DataView(t),C=new n(b.getFloat64(c,!0),b.getFloat64(c+8,!0),b.getFloat64(c+16,!0));c+=d;var S=b.getFloat32(c,!0);c+=Float32Array.BYTES_PER_ELEMENT;var w=b.getFloat32(c,!0);c+=Float32Array.BYTES_PER_ELEMENT;var T=new i(new n(b.getFloat64(c,!0),b.getFloat64(c+8,!0),b.getFloat64(c+16,!0)),b.getFloat64(c+d,!0));c+=h;var E=new n(b.getFloat64(c,!0),b.getFloat64(c+8,!0),b.getFloat64(c+16,!0));c+=d;var A=b.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var x=new Uint16Array(t,c,3*A);c+=A*p,A>65536&&(v=Uint32Array.BYTES_PER_ELEMENT,y=3*v);var D=x.subarray(0,A),I=x.subarray(A,2*A),O=x.subarray(2*A,3*A);r.zigZagDeltaDecode(D,I,O),c%v!=0&&(c+=v-c%v);var M=b.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var R=f.createTypedArrayFromArrayBuffer(A,t,c,3*M);c+=M*y;for(var L=0,N=R.length,k=0;k<N;++k){var F=R[k];R[k]=L-F,0===F&&++L}var B=b.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var U=f.createTypedArrayFromArrayBuffer(A,t,c,B);c+=B*v;var V=b.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var z=f.createTypedArrayFromArrayBuffer(A,t,c,V);c+=V*v;var G=b.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var W=f.createTypedArrayFromArrayBuffer(A,t,c,G);c+=G*v;var H=b.getUint32(c,!0);c+=Uint32Array.BYTES_PER_ELEMENT;var j=f.createTypedArrayFromArrayBuffer(A,t,c,H);c+=H*v;for(var q,Y;c<b.byteLength;){var X=b.getUint8(c,!0);c+=Uint8Array.BYTES_PER_ELEMENT;var Q=b.getUint32(c,u);c+=Uint32Array.BYTES_PER_ELEMENT,X===P.OCT_VERTEX_NORMALS&&e._requestVertexNormals?q=new Uint8Array(t,c,2*A):X===P.WATER_MASK&&e._requestWaterMask&&(Y=new Uint8Array(t,c,Q)),c+=Q}var Z,K=5*e.getLevelMaximumGeometricError(o),J=e._tilingScheme.tileXYToRectangle(a,s,o);return J.width<m.PI_OVER_TWO+m.EPSILON5&&(Z=g.fromRectangle(J,S,w,e._tilingScheme.ellipsoid)),new _({center:C,minimumHeight:S,maximumHeight:w,boundingSphere:T,orientedBoundingBox:Z,horizonOcclusionPoint:E,quantizedVertices:x,encodedNormals:q,indices:R,westIndices:U,southIndices:z,eastIndices:W,northIndices:j,westSkirtHeight:K,southSkirtHeight:K,eastSkirtHeight:K,northSkirtHeight:K,childTileMask:e.availability.computeChildMaskForTile(o,a,s),waterMask:Y})}var P={OCT_VERTEX_NORMALS:1,WATER_MASK:2};return T.prototype.requestTileGeometry=function(e,r,i,n){var o,a=this._layers,l=a.length;if(1===l)o=a[0];else for(var u=0;u<l;++u){var c=a[u];if(!s(c.availability)||c.availability.isTileAvailable(i,e,r)){o=c;break}}if(!s(o))return t.reject(new y("Terrain tile doesn't exist"));var d=o.tileUrlTemplates;if(0!==d.length){var h=this._tilingScheme.getNumberOfYTilesAtLevel(i),p=h-r-1,f=[];this._requestVertexNormals&&o.hasVertexNormals&&f.push(o.littleEndianExtensionSize?"octvertexnormals":"vertexnormals"),this._requestWaterMask&&o.hasWaterMask&&f.push("watermask");var m=o.resource.getDerivedResource({url:d[(e+p+i)%d.length],templateValues:{version:o.version,z:i,x:e,y:p},headers:E(f),request:n}),g=m.fetchArrayBuffer();if(s(g)){var _=this;return t(g,function(t){return s(_._heightmapStructure)?A(_,t,i,e,r,p):x(_,t,i,e,r,p,o.littleEndianExtensionSize)})}}},l(T.prototype,{errorEvent:{get:function(){return this._errorEvent}},credit:{get:function(){return this._credit}},tilingScheme:{get:function(){return this._tilingScheme}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},hasWaterMask:{get:function(){return this._hasWaterMask&&this._requestWaterMask}},hasVertexNormals:{get:function(){return this._hasVertexNormals&&this._requestVertexNormals}},requestVertexNormals:{get:function(){return this._requestVertexNormals}},requestWaterMask:{get:function(){return this._requestWaterMask}},availability:{get:function(){return this._availability}}}),T.prototype.getLevelMaximumGeometricError=function(e){return this._levelZeroMaximumGeometricError/(1<<e)},T.prototype.getTileDataAvailable=function(e,t,r){if(s(this._availability))return this._availability.isTileAvailable(r,e,t)},T}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,r,i){"use strict";function n(t,n,o,c,d,h,p,f,m,g){var _=t+n;e.multiplyByScalar(c,Math.cos(_),a),e.multiplyByScalar(o,Math.sin(_),s),e.add(a,s,a);var v=Math.cos(t);v*=v;var y=Math.sin(t);y*=y;var b=h/Math.sqrt(p*v+d*y),C=b/f;return i.fromAxisAngle(a,C,l),r.fromQuaternion(l,u),r.multiplyByVector(u,m,g),e.normalize(g,g),e.multiplyByScalar(g,f,g),g}var o={},a=new e,s=new e,l=new i,u=new r,c=new e,d=new e,h=new e,p=new e;o.raisePositionsToHeight=function(t,r,i){for(var n=r.ellipsoid,o=r.height,a=r.extrudedHeight,s=i?t.length/3*2:t.length/3,l=new Float64Array(3*s),u=t.length,f=i?u:0,m=0;m<u;m+=3){var g=m+1,_=m+2,v=e.fromArray(t,m,c);n.scaleToGeodeticSurface(v,v);var y=e.clone(v,d),b=n.geodeticSurfaceNormal(v,p),C=e.multiplyByScalar(b,o,h);e.add(v,C,v),i&&(e.multiplyByScalar(b,a,C),e.add(y,C,y),l[m+f]=y.x,l[g+f]=y.y,l[_+f]=y.z),l[m]=v.x,l[g]=v.y,l[_]=v.z}return l};var f=new e,m=new e,g=new e;return o.computeEllipsePositions=function(r,i,o){var a=r.semiMinorAxis,s=r.semiMajorAxis,l=r.rotation,u=r.center,p=8*r.granularity,_=a*a,v=s*s,y=s*a,b=e.magnitude(u),C=e.normalize(u,f),S=e.cross(e.UNIT_Z,u,m);S=e.normalize(S,S);var w=e.cross(C,S,g),T=1+Math.ceil(t.PI_OVER_TWO/p),E=t.PI_OVER_TWO/(T-1),A=t.PI_OVER_TWO-T*E;A<0&&(T-=Math.ceil(Math.abs(A)/E));var x,P,D,I,O,M=T*(T+2)*2,R=i?new Array(3*M):void 0,L=0,N=c,k=d,F=4*T*3,B=F-1,U=0,V=o?new Array(F):void 0;for(A=t.PI_OVER_TWO,N=n(A,l,w,S,_,y,v,b,C,N),i&&(R[L++]=N.x,R[L++]=N.y,R[L++]=N.z),o&&(V[B--]=N.z,V[B--]=N.y,V[B--]=N.x),A=t.PI_OVER_TWO-E,x=1;x<T+1;++x){if(N=n(A,l,w,S,_,y,v,b,C,N),k=n(Math.PI-A,l,w,S,_,y,v,b,C,k),i){for(R[L++]=N.x,R[L++]=N.y,R[L++]=N.z,D=2*x+2,P=1;P<D-1;++P)I=P/(D-1),O=e.lerp(N,k,I,h),R[L++]=O.x,R[L++]=O.y,R[L++]=O.z;R[L++]=k.x,R[L++]=k.y,R[L++]=k.z}o&&(V[B--]=N.z,V[B--]=N.y,V[B--]=N.x,V[U++]=k.x,V[U++]=k.y,V[U++]=k.z),A=t.PI_OVER_TWO-(x+1)*E}for(x=T;x>1;--x){if(A=t.PI_OVER_TWO-(x-1)*E,N=n(-A,l,w,S,_,y,v,b,C,N),k=n(A+Math.PI,l,w,S,_,y,v,b,C,k),i){for(R[L++]=N.x,R[L++]=N.y,R[L++]=N.z,D=2*(x-1)+2,P=1;P<D-1;++P)I=P/(D-1),O=e.lerp(N,k,I,h),R[L++]=O.x,R[L++]=O.y,R[L++]=O.z;R[L++]=k.x,R[L++]=k.y,R[L++]=k.z}o&&(V[B--]=N.z,V[B--]=N.y,V[B--]=N.x,V[U++]=k.x,V[U++]=k.y,V[U++]=k.z)}A=t.PI_OVER_TWO,N=n(-A,l,w,S,_,y,v,b,C,N);var z={};return i&&(R[L++]=N.x,R[L++]=N.y,R[L++]=N.z,z.positions=R,z.numPts=T),o&&(V[B--]=N.z,V[B--]=N.y,V[B--]=N.x,z.outerPositions=V),z},o}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,i){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=i.clone(e(t.modelMatrix,i.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return n}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function i(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}i.encode=function(e,t){r(t)||(t={high:0,low:0});var i;return e>=0?(i=65536*Math.floor(e/65536),t.high=i,t.low=e-i):(i=65536*Math.floor(-e/65536),t.high=-i,t.low=e+i),t};var n={high:0,low:0};i.fromCartesian=function(e,t){r(t)||(t=new i);var o=t.high,a=t.low;return i.encode(e.x,n),o.x=n.high,a.x=n.low,i.encode(e.y,n),o.y=n.high,a.y=n.low,i.encode(e.z,n),o.z=n.high,a.z=n.low,t};var o=new i;return i.writeElements=function(e,t,r){i.fromCartesian(e,o);var n=o.high,a=o.low;t[r]=n.x,t[r+1]=n.y,t[r+2]=n.z,t[r+3]=a.x,t[r+4]=a.y,t[r+5]=a.z},i}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var i={};return i.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var i=r.indices,n=r.maximumIndex,o=e(r.cacheSize,24),a=i.length;if(!t(n)){n=0;for(var s=0,l=i[s];s<a;)l>n&&(n=l),++s,l=i[s]}for(var u=[],c=0;c<n+1;c++)u[c]=0;for(var d=o+1,h=0;h<a;++h)d-u[i[h]]>o&&(u[i[h]]=d,++d);return(d-o+1)/(a/3)},i.tipsify=function(r){function i(e,t,r,i){for(;t.length>=1;){var o=t[t.length-1];if(t.splice(t.length-1,1),e[o].numLiveTriangles>0)return o}for(;n<i;){if(e[n].numLiveTriangles>0)return++n-1;++n}return-1}r=e(r,e.EMPTY_OBJECT);var n,o=r.indices,a=r.maximumIndex,s=e(r.cacheSize,24),l=o.length,u=0,c=0,d=o[c],h=l;if(t(a))u=a+1;else{for(;c<h;)d>u&&(u=d),++c,d=o[c];if(-1===u)return 0;++u}var p,f=[];for(p=0;p<u;p++)f[p]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};c=0;for(var m=0;c<h;)f[o[c]].vertexTriangles.push(m),++f[o[c]].numLiveTriangles,f[o[c+1]].vertexTriangles.push(m),++f[o[c+1]].numLiveTriangles,f[o[c+2]].vertexTriangles.push(m),++f[o[c+2]].numLiveTriangles,++m,c+=3;var g=0,_=s+1;n=1;var v,y,b=[],C=[],S=0,w=[],T=l/3,E=[];for(p=0;p<T;p++)E[p]=!1;for(var A,x;-1!==g;){b=[],y=f[g],x=y.vertexTriangles.length;for(var P=0;P<x;++P)if(m=y.vertexTriangles[P],!E[m]){E[m]=!0,c=m+m+m;for(var D=0;D<3;++D)A=o[c],b.push(A),C.push(A),w[S]=A,++S,v=f[A],--v.numLiveTriangles,_-v.timeStamp>s&&(v.timeStamp=_,++_),++c}g=function(e,t,r,n,o,a,s){for(var l,u=-1,c=-1,d=0;d<r.length;){var h=r[d];n[h].numLiveTriangles&&(l=0,o-n[h].timeStamp+2*n[h].numLiveTriangles<=t&&(l=o-n[h].timeStamp),(l>c||-1===c)&&(c=l,u=h)),++d}return-1===u?i(n,a,e,s):u}(o,s,b,f,_,C,u)}return w},i}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T){"use strict";function E(e,t,r,i,n){e[t++]=r,e[t++]=i,e[t++]=i,e[t++]=n,e[t++]=n,e[t]=r}function A(e){for(var t=e.length,r=t/3*6,i=g.createTypedArray(t,r),n=0,o=0;o<t;o+=3,n+=6)E(i,n,e[o],e[o+1],e[o+2]);return i}function x(e){var t=e.length;if(t>=3){var r=6*(t-2),i=g.createTypedArray(t,r);E(i,0,e[0],e[1],e[2]);for(var n=6,o=3;o<t;++o,n+=6)E(i,n,e[o-1],e[o],e[o-2]);return i}return new Uint16Array}function P(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),i=g.createTypedArray(t,r),n=e[0],o=0,a=1;a<t;++a,o+=6)E(i,o,n,e[a],e[a+1]);return i}return new Uint16Array}function D(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&u(e[r])&&u(e[r].values)){var i=e[r];t[r]=new f({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return t}function I(e,t,r){for(var i in t)if(t.hasOwnProperty(i)&&u(t[i])&&u(t[i].values))for(var n=t[i],o=0;o<n.componentsPerAttribute;++o)e[i].values.push(n.values[r*n.componentsPerAttribute+o])}function O(e,t){if(u(t))for(var r=t.values,i=r.length,o=0;o<i;o+=3)n.unpack(r,o,oe),C.multiplyByPoint(e,oe,oe),n.pack(oe,r,o)}function M(e,t){if(u(t))for(var r=t.values,i=r.length,o=0;o<i;o+=3)n.unpack(r,o,oe),b.multiplyByVector(e,oe,oe),oe=n.normalize(oe,oe),n.pack(oe,r,o)}function R(e,t){var r,i=e.length,n={},o=e[0][t].attributes;for(r in o)if(o.hasOwnProperty(r)&&u(o[r])&&u(o[r].values)){for(var a=o[r],l=a.values.length,c=!0,d=1;d<i;++d){var h=e[d][t].attributes[r];if(!u(h)||a.componentDatatype!==h.componentDatatype||a.componentsPerAttribute!==h.componentsPerAttribute||a.normalize!==h.normalize){c=!1;break}l+=h.values.length}c&&(n[r]=new f({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:s.createTypedArray(a.componentDatatype,l)}))}return n}function L(e,t){var i,o,a,s,l,c,d,h=e.length,f=(e[0].modelMatrix,u(e[0][t].indices)),m=e[0][t].primitiveType,_=R(e,t);for(i in _)if(_.hasOwnProperty(i))for(l=_[i].values,s=0,o=0;o<h;++o)for(c=e[o][t].attributes[i].values,d=c.length,a=0;a<d;++a)l[s++]=c[a];var v;if(f){var y=0;for(o=0;o<h;++o)y+=e[o][t].indices.length;var b=p.computeNumberOfVertices(new p({attributes:_,primitiveType:w.POINTS})),C=g.createTypedArray(b,y),S=0,T=0;for(o=0;o<h;++o){var E=e[o][t].indices,A=E.length;for(s=0;s<A;++s)C[S++]=T+E[s];T+=p.computeNumberOfVertices(e[o][t])}v=C}var x,P=new n,D=0;for(o=0;o<h;++o){if(x=e[o][t].boundingSphere,!u(x)){P=void 0;break}n.add(x.center,P,P)}if(u(P))for(n.divideByScalar(P,h,P),o=0;o<h;++o){x=e[o][t].boundingSphere;var I=n.magnitude(n.subtract(x.center,P,le))+x.radius;I>D&&(D=I)}return new p({attributes:_,indices:v,primitiveType:m,boundingSphere:u(P)?new r(P,D):void 0})}function N(e){if(u(e.indices))return e;for(var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,t),i=0;i<t;++i)r[i]=i;return e.indices=r,e}function k(e){var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var i=3,n=3;n<t;++n)r[i++]=n-1,r[i++]=0,r[i++]=n;return e.indices=r,e.primitiveType=w.TRIANGLES,e}function F(e){var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var i=6,n=3;n<t-1;n+=2)r[i++]=n,r[i++]=n-1,r[i++]=n+1,n+2<t&&(r[i++]=n,r[i++]=n+1,r[i++]=n+2);return e.indices=r,e.primitiveType=w.TRIANGLES,e}function B(e){if(u(e.indices))return e;for(var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,t),i=0;i<t;++i)r[i]=i;return e.indices=r,e}function U(e){var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var i=2,n=2;n<t;++n)r[i++]=n-1,r[i++]=n;return e.indices=r,e.primitiveType=w.LINES,e}function V(e){var t=p.computeNumberOfVertices(e),r=g.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var i=2,n=2;n<t;++n)r[i++]=n-1,r[i++]=n;return r[i++]=t-1,r[i]=0,e.indices=r,e.primitiveType=w.LINES,e}function z(e){switch(e.primitiveType){case w.TRIANGLE_FAN:return k(e);case w.TRIANGLE_STRIP:return F(e);case w.TRIANGLES:return N(e);case w.LINE_STRIP:return U(e);case w.LINE_LOOP:return V(e);case w.LINES:return B(e)}return e}function G(e,t){Math.abs(e.y)<y.EPSILON6&&(e.y=t?-y.EPSILON6:y.EPSILON6)}function W(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return G(e,e.y<0),G(t,t.y<0),void G(r,r.y<0);var i,n=Math.abs(e.y),o=Math.abs(t.y),a=Math.abs(r.y);i=n>o?n>a?y.sign(e.y):y.sign(r.y):o>a?y.sign(t.y):y.sign(r.y);var s=i<0;G(e,s),G(t,s),G(r,s)}function H(e,t,r,i){n.add(e,n.multiplyByScalar(n.subtract(t,e,Ce),e.y/(e.y-t.y),Ce),r),n.clone(r,i),G(r,!0),G(i,!1)}function j(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){W(e,t,r);var i=e.y<0,n=t.y<0,o=r.y<0,a=0;a+=i?1:0,a+=n?1:0,a+=o?1:0;var s=Ae.indices;1===a?(s[1]=3,s[2]=4,s[5]=6,s[7]=6,s[8]=5,i?(H(e,t,Se,Te),H(e,r,we,Ee),s[0]=0,s[3]=1,s[4]=2,s[6]=1):n?(H(t,r,Se,Te),H(t,e,we,Ee),s[0]=1,s[3]=2,s[4]=0,s[6]=2):o&&(H(r,e,Se,Te),H(r,t,we,Ee),s[0]=2,s[3]=0,s[4]=1,s[6]=0)):2===a&&(s[2]=4,s[4]=4,s[5]=3,s[7]=5,s[8]=6,i?n?o||(H(r,e,Se,Te),H(r,t,we,Ee),s[0]=0,s[1]=1,s[3]=0,s[6]=2):(H(t,r,Se,Te),H(t,e,we,Ee),s[0]=2,s[1]=0,s[3]=2,s[6]=1):(H(e,t,Se,Te),H(e,r,we,Ee),s[0]=1,s[1]=2,s[3]=1,s[6]=0));var l=Ae.positions;return l[0]=e,l[1]=t,l[2]=r,l.length=3,1!==a&&2!==a||(l[3]=Se,l[4]=we,l[5]=Te,l[6]=Ee,l.length=7),Ae}}function q(e,t){var i=e.attributes;if(0!==i.position.values.length){for(var n in i)if(i.hasOwnProperty(n)&&u(i[n])&&u(i[n].values)){var o=i[n];o.values=s.createTypedArray(o.componentDatatype,o.values)}var a=p.computeNumberOfVertices(e);return e.indices=g.createTypedArray(a,e.indices),t&&(e.boundingSphere=r.fromVertices(i.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var i in t)if(t.hasOwnProperty(i)&&u(t[i])&&u(t[i].values)){var n=t[i];r[i]=new f({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return new p({attributes:r,indices:[],primitiveType:e.primitiveType})}function X(e,t,r){var i=u(e.geometry.boundingSphere);t=q(t,i),r=q(r,i),u(r)&&!u(t)?e.geometry=r:!u(r)&&u(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r, +e.geometry=void 0)}function Q(e,r,o,a,s,l,c,d,h,p,f,m){if(u(l)||u(c)||u(d)||u(h)||u(p)){var g=n.fromArray(s,3*e,xe),_=n.fromArray(s,3*r,Pe),v=n.fromArray(s,3*o,De),y=t(a,g,_,v,Ie);if(u(l)){var b=n.fromArray(l,3*e,xe),C=n.fromArray(l,3*r,Pe),S=n.fromArray(l,3*o,De);n.multiplyByScalar(b,y.x,b),n.multiplyByScalar(C,y.y,C),n.multiplyByScalar(S,y.z,S);var w=n.add(b,C,b);n.add(w,S,w),n.normalize(w,w),n.pack(w,f.normal.values,3*m)}if(u(p)){var T=n.fromArray(p,3*e,xe),E=n.fromArray(p,3*r,Pe),A=n.fromArray(p,3*o,De);n.multiplyByScalar(T,y.x,T),n.multiplyByScalar(E,y.y,E),n.multiplyByScalar(A,y.z,A);var x;n.equals(T,n.ZERO)&&n.equals(E,n.ZERO)&&n.equals(A,n.ZERO)?(x=xe,x.x=0,x.y=0,x.z=0):(x=n.add(T,E,T),n.add(x,A,x),n.normalize(x,x)),n.pack(x,f.extrudeDirection.values,3*m)}if(u(c)){var P=n.fromArray(c,3*e,xe),D=n.fromArray(c,3*r,Pe),I=n.fromArray(c,3*o,De);n.multiplyByScalar(P,y.x,P),n.multiplyByScalar(D,y.y,D),n.multiplyByScalar(I,y.z,I);var O=n.add(P,D,P);n.add(O,I,O),n.normalize(O,O),n.pack(O,f.tangent.values,3*m)}if(u(d)){var M=n.fromArray(d,3*e,xe),R=n.fromArray(d,3*r,Pe),L=n.fromArray(d,3*o,De);n.multiplyByScalar(M,y.x,M),n.multiplyByScalar(R,y.y,R),n.multiplyByScalar(L,y.z,L);var N=n.add(M,R,M);n.add(N,L,N),n.normalize(N,N),n.pack(N,f.bitangent.values,3*m)}if(u(h)){var k=i.fromArray(h,2*e,Oe),F=i.fromArray(h,2*r,Me),B=i.fromArray(h,2*o,Re);i.multiplyByScalar(k,y.x,k),i.multiplyByScalar(F,y.y,F),i.multiplyByScalar(B,y.z,B);var U=i.add(k,F,k);i.add(U,B,U),i.pack(U,f.st.values,2*m)}}}function Z(e,t,r,i,n,o){var a=e.position.values.length/3;if(-1!==n){var s=i[n],l=r[s];return-1===l?(r[s]=a,e.position.values.push(o.x,o.y,o.z),t.push(a),a):(t.push(l),l)}return e.position.values.push(o.x,o.y,o.z),t.push(a),a}function K(e){var t,r,i,o,a,s=e.geometry,l=s.attributes,c=l.position.values,d=u(l.normal)?l.normal.values:void 0,h=u(l.bitangent)?l.bitangent.values:void 0,p=u(l.tangent)?l.tangent.values:void 0,f=u(l.st)?l.st.values:void 0,m=u(l.extrudeDirection)?l.extrudeDirection.values:void 0,g=s.indices,_=Y(s),v=Y(s),y=[];y.length=c.length/3;var b=[];for(b.length=c.length/3,a=0;a<y.length;++a)y[a]=-1,b[a]=-1;var C=g.length;for(a=0;a<C;a+=3){var S=g[a],w=g[a+1],T=g[a+2],E=n.fromArray(c,3*S),A=n.fromArray(c,3*w),x=n.fromArray(c,3*T),P=j(E,A,x);if(u(P)&&P.positions.length>3)for(var D=P.positions,I=P.indices,O=I.length,M=0;M<O;++M){var R=I[M],L=D[R];L.y<0?(t=v.attributes,r=v.indices,i=y):(t=_.attributes,r=_.indices,i=b),o=Z(t,r,i,g,R<3?a+R:-1,L),Q(S,w,T,L,c,d,p,h,f,m,t,o)}else u(P)&&(E=P.positions[0],A=P.positions[1],x=P.positions[2]),E.y<0?(t=v.attributes,r=v.indices,i=y):(t=_.attributes,r=_.indices,i=b),o=Z(t,r,i,g,a,E),Q(S,w,T,E,c,d,p,h,f,m,t,o),o=Z(t,r,i,g,a+1,A),Q(S,w,T,A,c,d,p,h,f,m,t,o),o=Z(t,r,i,g,a+2,x),Q(S,w,T,x,c,d,p,h,f,m,t,o)}X(e,v,_)}function J(e){var t,r=e.geometry,i=r.attributes,o=i.position.values,a=r.indices,s=Y(r),l=Y(r),c=a.length,d=[];d.length=o.length/3;var h=[];for(h.length=o.length/3,t=0;t<d.length;++t)d[t]=-1,h[t]=-1;for(t=0;t<c;t+=2){var p=a[t],f=a[t+1],m=n.fromArray(o,3*p,xe),g=n.fromArray(o,3*f,Pe);Math.abs(m.y)<y.EPSILON6&&(m.y<0?m.y=-y.EPSILON6:m.y=y.EPSILON6),Math.abs(g.y)<y.EPSILON6&&(g.y<0?g.y=-y.EPSILON6:g.y=y.EPSILON6);var _=s.attributes,b=s.indices,C=h,S=l.attributes,w=l.indices,T=d,E=v.lineSegmentPlane(m,g,Le,De);if(u(E)){var A=n.multiplyByScalar(n.UNIT_Y,5*y.EPSILON9,Ne);m.y<0&&(n.negate(A,A),_=l.attributes,b=l.indices,C=d,S=s.attributes,w=s.indices,T=h);var x=n.add(E,A,ke);Z(_,b,C,a,t,m),Z(_,b,C,a,-1,x),n.negate(A,A),n.add(E,A,x),Z(S,w,T,a,-1,x),Z(S,w,T,a,t+1,g)}else{var P,D,I;m.y<0?(P=l.attributes,D=l.indices,I=d):(P=s.attributes,D=s.indices,I=h),Z(P,D,I,a,t,m),Z(P,D,I,a,t+1,g)}}X(e,l,s)}function $(e){for(var t=e.attributes,r=t.position.values,i=t.prevPosition.values,o=t.nextPosition.values,a=r.length,s=0;s<a;s+=3){var l=n.unpack(r,s,Ue);if(!(l.x>0)){var u=n.unpack(i,s,Ve);(l.y<0&&u.y>0||l.y>0&&u.y<0)&&(s-3>0?(i[s]=r[s-3],i[s+1]=r[s-2],i[s+2]=r[s-1]):n.pack(l,i,s));var c=n.unpack(o,s,ze);(l.y<0&&c.y>0||l.y>0&&c.y<0)&&(s+3<a?(o[s]=r[s+3],o[s+1]=r[s+4],o[s+2]=r[s+5]):n.pack(l,o,s))}}}function ee(e){var t,r,a,s=e.geometry,l=s.attributes,c=l.position.values,d=l.prevPosition.values,h=l.nextPosition.values,p=l.expandAndWidth.values,f=u(l.st)?l.st.values:void 0,m=u(l.color)?l.color.values:void 0,g=Y(s),_=Y(s),b=!1,C=c.length/3;for(t=0;t<C;t+=4){var S=t,w=t+2,T=n.fromArray(c,3*S,Ue),E=n.fromArray(c,3*w,Ve);if(Math.abs(T.y)<Ye)for(T.y=Ye*(E.y<0?-1:1),c[3*t+1]=T.y,c[3*(t+1)+1]=T.y,r=3*S;r<3*S+12;r+=3)d[r]=c[3*t],d[r+1]=c[3*t+1],d[r+2]=c[3*t+2];if(Math.abs(E.y)<Ye)for(E.y=Ye*(T.y<0?-1:1),c[3*(t+2)+1]=E.y,c[3*(t+3)+1]=E.y,r=3*S;r<3*S+12;r+=3)h[r]=c[3*(t+2)],h[r+1]=c[3*(t+2)+1],h[r+2]=c[3*(t+2)+2];var A=g.attributes,x=g.indices,P=_.attributes,D=_.indices,I=v.lineSegmentPlane(T,E,Le,Ge);if(u(I)){b=!0;var O=n.multiplyByScalar(n.UNIT_Y,qe,We);T.y<0&&(n.negate(O,O),A=_.attributes,x=_.indices,P=g.attributes,D=g.indices);var M=n.add(I,O,He);A.position.values.push(T.x,T.y,T.z,T.x,T.y,T.z),A.position.values.push(M.x,M.y,M.z),A.position.values.push(M.x,M.y,M.z),A.prevPosition.values.push(d[3*S],d[3*S+1],d[3*S+2]),A.prevPosition.values.push(d[3*S+3],d[3*S+4],d[3*S+5]),A.prevPosition.values.push(T.x,T.y,T.z,T.x,T.y,T.z),A.nextPosition.values.push(M.x,M.y,M.z),A.nextPosition.values.push(M.x,M.y,M.z),A.nextPosition.values.push(M.x,M.y,M.z),A.nextPosition.values.push(M.x,M.y,M.z),n.negate(O,O),n.add(I,O,M),P.position.values.push(M.x,M.y,M.z),P.position.values.push(M.x,M.y,M.z),P.position.values.push(E.x,E.y,E.z,E.x,E.y,E.z),P.prevPosition.values.push(M.x,M.y,M.z),P.prevPosition.values.push(M.x,M.y,M.z),P.prevPosition.values.push(M.x,M.y,M.z),P.prevPosition.values.push(M.x,M.y,M.z),P.nextPosition.values.push(E.x,E.y,E.z,E.x,E.y,E.z),P.nextPosition.values.push(h[3*w],h[3*w+1],h[3*w+2]),P.nextPosition.values.push(h[3*w+3],h[3*w+4],h[3*w+5]);var R=i.fromArray(p,2*S,Fe),L=Math.abs(R.y);A.expandAndWidth.values.push(-1,L,1,L),A.expandAndWidth.values.push(-1,-L,1,-L),P.expandAndWidth.values.push(-1,L,1,L),P.expandAndWidth.values.push(-1,-L,1,-L);var N=n.magnitudeSquared(n.subtract(I,T,ze));if(N/=n.magnitudeSquared(n.subtract(E,T,ze)),u(m)){var k=o.fromArray(m,4*S,je),F=o.fromArray(m,4*w,je),B=y.lerp(k.x,F.x,N),U=y.lerp(k.y,F.y,N),V=y.lerp(k.z,F.z,N),z=y.lerp(k.w,F.w,N);for(r=4*S;r<4*S+8;++r)A.color.values.push(m[r]);for(A.color.values.push(B,U,V,z),A.color.values.push(B,U,V,z),P.color.values.push(B,U,V,z),P.color.values.push(B,U,V,z),r=4*w;r<4*w+8;++r)P.color.values.push(m[r])}if(u(f)){var G=i.fromArray(f,2*S,Fe),W=i.fromArray(f,2*(t+3),Be),H=y.lerp(G.x,W.x,N);for(r=2*S;r<2*S+4;++r)A.st.values.push(f[r]);for(A.st.values.push(H,G.y),A.st.values.push(H,W.y),P.st.values.push(H,G.y),P.st.values.push(H,W.y),r=2*w;r<2*w+4;++r)P.st.values.push(f[r])}a=A.position.values.length/3-4,x.push(a,a+2,a+1),x.push(a+1,a+2,a+3),a=P.position.values.length/3-4,D.push(a,a+2,a+1),D.push(a+1,a+2,a+3)}else{var j,q;for(T.y<0?(j=_.attributes,q=_.indices):(j=g.attributes,q=g.indices),j.position.values.push(T.x,T.y,T.z),j.position.values.push(T.x,T.y,T.z),j.position.values.push(E.x,E.y,E.z),j.position.values.push(E.x,E.y,E.z),r=3*t;r<3*t+12;++r)j.prevPosition.values.push(d[r]),j.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)j.expandAndWidth.values.push(p[r]),u(f)&&j.st.values.push(f[r]);if(u(m))for(r=4*t;r<4*t+16;++r)j.color.values.push(m[r]);a=j.position.values.length/3-4,q.push(a,a+2,a+1),q.push(a+1,a+2,a+3)}}b&&($(_),$(g)),X(e,_,g)}var te={};te.toWireframe=function(e){var t=e.indices;if(u(t)){switch(e.primitiveType){case w.TRIANGLES:e.indices=A(t);break;case w.TRIANGLE_STRIP:e.indices=x(t);break;case w.TRIANGLE_FAN:e.indices=P(t)}e.primitiveType=w.LINES}return e},te.createLineSegmentsForVectors=function(e,t,i){t=l(t,"normal"),i=l(i,1e4);for(var n=e.attributes.position.values,o=e.attributes[t].values,a=n.length,c=new Float64Array(2*a),d=0,h=0;h<a;h+=3)c[d++]=n[h],c[d++]=n[h+1],c[d++]=n[h+2],c[d++]=n[h]+o[h]*i,c[d++]=n[h+1]+o[h+1]*i,c[d++]=n[h+2]+o[h+2]*i;var m,g=e.boundingSphere;return u(g)&&(m=new r(g.center,g.radius+i)),new p({attributes:{position:new f({componentDatatype:s.DOUBLE,componentsPerAttribute:3,values:c})},primitiveType:w.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],i=e.attributes,n={},o=0,a=r.length;for(t=0;t<a;++t){var s=r[t];u(i[s])&&(n[s]=o++)}for(var l in i)i.hasOwnProperty(l)&&!u(n[l])&&(n[l]=o++);return n},te.reorderForPreVertexCache=function(e){var t=p.computeNumberOfVertices(e),r=e.indices;if(u(r)){for(var i=new Int32Array(t),n=0;n<t;n++)i[n]=-1;for(var o,a=r,l=a.length,c=g.createTypedArray(t,l),d=0,h=0,f=0;d<l;)o=i[a[d]],-1!==o?c[h]=o:(o=a[d],i[o]=f,c[h]=f,++f),++d,++h;e.indices=c;var m=e.attributes;for(var _ in m)if(m.hasOwnProperty(_)&&u(m[_])&&u(m[_].values)){for(var v=m[_],y=v.values,b=0,C=v.componentsPerAttribute,S=s.createTypedArray(v.componentDatatype,f*C);b<t;){var w=i[b];if(-1!==w)for(var T=0;T<C;T++)S[C*w+T]=y[C*b+T];++b}v.values=S}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===w.TRIANGLES&&u(r)){for(var i=r.length,n=0,o=0;o<i;o++)r[o]>n&&(n=r[o]);e.indices=T.tipsify({indices:r,maximumIndex:n,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=p.computeNumberOfVertices(e);if(u(e.indices)&&r>=y.SIXTY_FOUR_KILOBYTES){var i,n=[],o=[],a=0,s=D(e.attributes),l=e.indices,c=l.length;e.primitiveType===w.TRIANGLES?i=3:e.primitiveType===w.LINES?i=2:e.primitiveType===w.POINTS&&(i=1);for(var d=0;d<c;d+=i){for(var h=0;h<i;++h){var f=l[d+h],m=n[f];u(m)||(m=a++,n[f]=m,I(s,e.attributes,f)),o.push(m)}a+i>=y.SIXTY_FOUR_KILOBYTES&&(t.push(new p({attributes:s,indices:o,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),n=[],o=[],a=0,s=D(e.attributes))}0!==o.length&&t.push(new p({attributes:s,indices:o,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new n,ie=new a;te.projectTo2D=function(e,t,r,i,o){var a=e.attributes[t];o=u(o)?o:new h;for(var l=o.ellipsoid,c=a.values,d=new Float64Array(c.length),p=0,m=0;m<c.length;m+=3){var g=n.fromArray(c,m,re),_=l.cartesianToCartographic(g,ie),v=o.project(_,re);d[p++]=v.x,d[p++]=v.y,d[p++]=v.z}return e.attributes[r]=a,e.attributes[i]=new f({componentDatatype:s.DOUBLE,componentsPerAttribute:3,values:d}),delete e.attributes[t],e};var ne={high:0,low:0};te.encodeAttribute=function(e,t,r,i){for(var n=e.attributes[t],o=n.values,a=o.length,l=new Float32Array(a),u=new Float32Array(a),c=0;c<a;++c)d.encode(o[c],ne),l[c]=ne.high,u[c]=ne.low;var h=n.componentsPerAttribute;return e.attributes[r]=new f({componentDatatype:s.FLOAT,componentsPerAttribute:h,values:l}),e.attributes[i]=new f({componentDatatype:s.FLOAT,componentsPerAttribute:h,values:u}),delete e.attributes[t],e};var oe=new n,ae=new C,se=new b;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(C.equals(t,C.IDENTITY))return e;var i=e.geometry.attributes;O(t,i.position),O(t,i.prevPosition),O(t,i.nextPosition),(u(i.normal)||u(i.tangent)||u(i.bitangent))&&(C.inverse(t,ae),C.transpose(ae,ae),C.getRotation(ae,se),M(se,i.normal),M(se,i.tangent),M(se,i.bitangent));var n=e.geometry.boundingSphere;return u(n)&&(e.geometry.boundingSphere=r.transform(n,t,n)),e.modelMatrix=C.clone(C.IDENTITY),e};var le=new n;te.combineInstances=function(e){for(var t=[],r=[],i=e.length,n=0;n<i;++n){var o=e[n];u(o.geometry)?t.push(o):u(o.westHemisphereGeometry)&&u(o.eastHemisphereGeometry)&&r.push(o)}var a=[];return t.length>0&&a.push(L(t,"geometry")),r.length>0&&(a.push(L(r,"westHemisphereGeometry")),a.push(L(r,"eastHemisphereGeometry"))),a};var ue=new n,ce=new n,de=new n,he=new n;te.computeNormal=function(e){var t,r=e.indices,i=e.attributes,o=i.position.values,a=i.position.values.length/3,l=r.length,u=new Array(a),c=new Array(l/3),d=new Array(l);for(t=0;t<a;t++)u[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<l;t+=3){var p=r[t],m=r[t+1],g=r[t+2],_=3*p,v=3*m,b=3*g;ce.x=o[_],ce.y=o[_+1],ce.z=o[_+2],de.x=o[v],de.y=o[v+1],de.z=o[v+2],he.x=o[b],he.y=o[b+1],he.z=o[b+2],u[p].count++,u[m].count++,u[g].count++,n.subtract(de,ce,de),n.subtract(he,ce,he),c[h]=n.cross(de,he,new n),h++}var C=0;for(t=0;t<a;t++)u[t].indexOffset+=C,C+=u[t].count;h=0;var S;for(t=0;t<l;t+=3){S=u[r[t]];var w=S.indexOffset+S.currentCount;d[w]=h,S.currentCount++,S=u[r[t+1]],w=S.indexOffset+S.currentCount,d[w]=h,S.currentCount++,S=u[r[t+2]],w=S.indexOffset+S.currentCount,d[w]=h,S.currentCount++,h++}var T=new Float32Array(3*a);for(t=0;t<a;t++){var E=3*t;if(S=u[t],n.clone(n.ZERO,ue),S.count>0){for(h=0;h<S.count;h++)n.add(ue,c[d[S.indexOffset+h]],ue);n.equalsEpsilon(n.ZERO,ue,y.EPSILON10)&&n.clone(c[d[S.indexOffset]],ue)}n.equalsEpsilon(n.ZERO,ue,y.EPSILON10)&&(ue.z=1),n.normalize(ue,ue),T[E]=ue.x,T[E+1]=ue.y,T[E+2]=ue.z}return e.attributes.normal=new f({componentDatatype:s.FLOAT,componentsPerAttribute:3,values:T}),e};var pe=new n,fe=new n,me=new n;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),i=e.attributes.position.values,o=e.attributes.normal.values,a=e.attributes.st.values,l=e.attributes.position.values.length/3,u=r.length,c=new Array(3*l);for(t=0;t<c.length;t++)c[t]=0;var d,h,p;for(t=0;t<u;t+=3){var m=r[t],g=r[t+1],_=r[t+2];d=3*m,h=3*g,p=3*_;var v=2*m,y=2*g,b=2*_,C=i[d],S=i[d+1],w=i[d+2],T=a[v],E=a[v+1],A=a[y+1]-E,x=a[b+1]-E,P=1/((a[y]-T)*x-(a[b]-T)*A),D=(x*(i[h]-C)-A*(i[p]-C))*P,I=(x*(i[h+1]-S)-A*(i[p+1]-S))*P,O=(x*(i[h+2]-w)-A*(i[p+2]-w))*P;c[d]+=D,c[d+1]+=I,c[d+2]+=O,c[h]+=D,c[h+1]+=I,c[h+2]+=O,c[p]+=D,c[p+1]+=I,c[p+2]+=O}var M=new Float32Array(3*l),R=new Float32Array(3*l);for(t=0;t<l;t++){d=3*t,h=d+1,p=d+2;var L=n.fromArray(o,d,pe),N=n.fromArray(c,d,me),k=n.dot(L,N);n.multiplyByScalar(L,k,fe),n.normalize(n.subtract(N,fe,N),N),M[d]=N.x,M[h]=N.y,M[p]=N.z,n.normalize(n.cross(L,N,N),N),R[d]=N.x,R[h]=N.y,R[p]=N.z}return e.attributes.tangent=new f({componentDatatype:s.FLOAT,componentsPerAttribute:3,values:M}),e.attributes.bitangent=new f({componentDatatype:s.FLOAT,componentsPerAttribute:3,values:R}),e};var ge=new i,_e=new n,ve=new n,ye=new n,be=new i;te.compressVertices=function(t){var r,o,a=t.attributes.extrudeDirection;if(u(a)){var l=a.values;o=l.length/3;var c=new Float32Array(2*o),d=0;for(r=0;r<o;++r)n.fromArray(l,3*r,_e),n.equals(_e,n.ZERO)?d+=2:(be=e.octEncodeInRange(_e,65535,be),c[d++]=be.x,c[d++]=be.y);return t.attributes.compressedAttributes=new f({componentDatatype:s.FLOAT,componentsPerAttribute:2,values:c}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,p=t.attributes.st,m=u(h),g=u(p);if(!m&&!g)return t;var _,v,y,b,C=t.attributes.tangent,S=t.attributes.bitangent,w=u(C),T=u(S);m&&(_=h.values),g&&(v=p.values),w&&(y=C.values),T&&(b=S.values),o=(m?_.length:v.length)/(m?3:2);var E=o,A=g&&m?2:1;A+=w||T?1:0,E*=A;var x=new Float32Array(E),P=0;for(r=0;r<o;++r){g&&(i.fromArray(v,2*r,ge),x[P++]=e.compressTextureCoordinates(ge));var D=3*r;m&&u(y)&&u(b)?(n.fromArray(_,D,_e),n.fromArray(y,D,ve),n.fromArray(b,D,ye),e.octPack(_e,ve,ye,ge),x[P++]=ge.x,x[P++]=ge.y):(m&&(n.fromArray(_,D,_e),x[P++]=e.octEncodeFloat(_e)),w&&(n.fromArray(y,D,_e),x[P++]=e.octEncodeFloat(_e)),T&&(n.fromArray(b,D,_e),x[P++]=e.octEncodeFloat(_e)))}return t.attributes.compressedAttributes=new f({componentDatatype:s.FLOAT,componentsPerAttribute:A,values:x}),m&&delete t.attributes.normal,g&&delete t.attributes.st,T&&delete t.attributes.bitangent,w&&delete t.attributes.tangent,t};var Ce=new n,Se=new n,we=new n,Te=new n,Ee=new n,Ae={positions:new Array(7),indices:new Array(9)},xe=new n,Pe=new n,De=new n,Ie=new n,Oe=new i,Me=new i,Re=new i,Le=S.fromPointNormal(n.ZERO,n.UNIT_Y),Ne=new n,ke=new n,Fe=new i,Be=new i,Ue=new n,Ve=new n,ze=new n,Ge=new n,We=new n,He=new n,je=new o,qe=5*y.EPSILON9,Ye=y.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,i=t.boundingSphere;if(u(i)){if(i.center.x-i.radius>0||r.intersectPlane(i,S.ORIGIN_ZX_PLANE)!==_.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:K(e);break;case m.LINES:J(e)}else z(t),t.primitiveType===w.TRIANGLES?K(e):t.primitiveType===w.LINES&&J(e);return e},te}),define("Core/EllipseGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./Matrix4","./PrimitiveType","./Quaternion","./Rectangle","./Transforms","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e,i,o){var a=i.vertexFormat,s=i.center,l=i.semiMajorAxis,c=i.semiMinorAxis,h=i.ellipsoid,m=i.stRotation,g=o?e.length/3*2:e.length/3,_=i.shadowVolume,v=a.st?new Float32Array(2*g):void 0,b=a.normal?new Float32Array(3*g):void 0,C=a.tangent?new Float32Array(3*g):void 0,w=a.bitangent?new Float32Array(3*g):void 0,T=_?new Float32Array(3*g):void 0,E=0,A=z,x=G,P=W,D=new d(h),I=D.project(h.cartesianToCartographic(s,H),j),O=h.scaleToGeodeticSurface(s,L);h.geodeticSurfaceNormal(O,O);for(var M=S.fromAxisAngle(O,m,V),R=y.fromQuaternion(M,U),F=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,q),X=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Y),Q=e.length,Z=o?Q:0,K=Z/3*2,J=0;J<Q;J+=3){var $=J+1,ee=J+2,te=r.fromArray(e,J,L);if(a.st){var re=y.multiplyByVector(R,te,N),ie=D.project(h.cartesianToCartographic(re,H),k);r.subtract(ie,I,ie),B.x=(ie.x+l)/(2*l),B.y=(ie.y+c)/(2*c),F.x=Math.min(B.x,F.x),F.y=Math.min(B.y,F.y),X.x=Math.max(B.x,X.x),X.y=Math.max(B.y,X.y),o&&(v[E+K]=B.x,v[E+1+K]=B.y),v[E++]=B.x,v[E++]=B.y}(a.normal||a.tangent||a.bitangent||_)&&(A=h.geodeticSurfaceNormal(te,A),_&&(T[J+Z]=-A.x,T[$+Z]=-A.y,T[ee+Z]=-A.z),(a.normal||a.tangent||a.bitangent)&&((a.tangent||a.bitangent)&&(x=r.normalize(r.cross(r.UNIT_Z,A,x),x),y.multiplyByVector(R,x,x)),a.normal&&(b[J]=A.x,b[$]=A.y,b[ee]=A.z,o&&(b[J+Z]=-A.x,b[$+Z]=-A.y,b[ee+Z]=-A.z)),a.tangent&&(C[J]=x.x,C[$]=x.y,C[ee]=x.z,o&&(C[J+Z]=-x.x,C[$+Z]=-x.y,C[ee+Z]=-x.z)),a.bitangent&&(P=r.normalize(r.cross(A,x,P),P),w[J]=P.x,w[$]=P.y,w[ee]=P.z,o&&(w[J+Z]=P.x,w[$+Z]=P.y,w[ee+Z]=P.z))))}if(a.st){Q=v.length;for(var ne=0;ne<Q;ne+=2)v[ne]=(v[ne]-F.x)/(X.x-F.x),v[ne+1]=(v[ne+1]-F.y)/(X.y-F.y)}var oe=new f;if(a.position){var ae=u.raisePositionsToHeight(e,i,o);oe.position=new p({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:ae})}return a.st&&(oe.st=new p({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:v})),a.normal&&(oe.normal=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:b})),a.tangent&&(oe.tangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:C})),a.bitangent&&(oe.bitangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:w})),_&&(oe.extrudeDirection=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:T})),oe}function x(e){var t,r,i,n,o,a=new Array(e*(e+1)*12-6),s=0;for(t=0,i=1,n=0;n<3;n++)a[s++]=i++,a[s++]=t,a[s++]=i;for(n=2;n<e+1;++n){for(i=n*(n+1)-1,t=(n-1)*n-1,a[s++]=i++,a[s++]=t,a[s++]=i,r=2*n,o=0;o<r-1;++o)a[s++]=i,a[s++]=t++,a[s++]=t,a[s++]=i++,a[s++]=t,a[s++]=i;a[s++]=i++,a[s++]=t,a[s++]=i}for(r=2*e,++i,++t,n=0;n<r-1;++n)a[s++]=i,a[s++]=t++,a[s++]=t,a[s++]=i++,a[s++]=t,a[s++]=i;for(a[s++]=i,a[s++]=t++,a[s++]=t,a[s++]=i++,a[s++]=t++,a[s++]=t,++t,n=e-1;n>1;--n){for(a[s++]=t++,a[s++]=t,a[s++]=i,r=2*n,o=0;o<r-1;++o)a[s++]=i,a[s++]=t++,a[s++]=t,a[s++]=i++,a[s++]=t,a[s++]=i;a[s++]=t++,a[s++]=t++,a[s++]=i++}for(n=0;n<3;n++)a[s++]=t++,a[s++]=t,a[s++]=i;return a}function P(t){var i=t.center;X=r.multiplyByScalar(t.ellipsoid.geodeticSurfaceNormal(i,X),t.height,X),X=r.add(i,X,X);var n=new e(X,t.semiMajorAxis),o=u.computeEllipsePositions(t,!0,!1),a=o.positions,s=o.numPts,l=A(a,t,!1),c=x(s);return c=_.createTypedArray(a.length/3,c),{boundingSphere:n,attributes:l,indices:c}}function D(e,i){var o=i.vertexFormat,a=i.center,s=i.semiMajorAxis,l=i.semiMinorAxis,u=i.ellipsoid,c=i.height,h=i.extrudedHeight,m=i.stRotation,g=e.length/3*2,_=new Float64Array(3*g),v=o.st?new Float32Array(2*g):void 0,b=o.normal?new Float32Array(3*g):void 0,C=o.tangent?new Float32Array(3*g):void 0,w=o.bitangent?new Float32Array(3*g):void 0,T=i.shadowVolume,E=T?new Float32Array(3*g):void 0,A=0,x=z,P=G,D=W,I=new d(u),O=I.project(u.cartesianToCartographic(a,H),j),M=u.scaleToGeodeticSurface(a,L);u.geodeticSurfaceNormal(M,M);for(var R=S.fromAxisAngle(M,m,V),X=y.fromQuaternion(R,U),Q=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,q),Z=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Y),K=e.length,J=K/3*2,$=0;$<K;$+=3){var ee,te=$+1,re=$+2,ie=r.fromArray(e,$,L);if(o.st){var ne=y.multiplyByVector(X,ie,N),oe=I.project(u.cartesianToCartographic(ne,H),k);r.subtract(oe,O,oe),B.x=(oe.x+s)/(2*s),B.y=(oe.y+l)/(2*l),Q.x=Math.min(B.x,Q.x),Q.y=Math.min(B.y,Q.y),Z.x=Math.max(B.x,Z.x),Z.y=Math.max(B.y,Z.y),v[A+J]=B.x,v[A+1+J]=B.y,v[A++]=B.x,v[A++]=B.y}ie=u.scaleToGeodeticSurface(ie,ie),ee=r.clone(ie,N),x=u.geodeticSurfaceNormal(ie,x),T&&(E[$+K]=-x.x,E[te+K]=-x.y,E[re+K]=-x.z);var ae=r.multiplyByScalar(x,c,F);if(ie=r.add(ie,ae,ie),ae=r.multiplyByScalar(x,h,ae),ee=r.add(ee,ae,ee),o.position&&(_[$+K]=ee.x,_[te+K]=ee.y,_[re+K]=ee.z,_[$]=ie.x,_[te]=ie.y,_[re]=ie.z),o.normal||o.tangent||o.bitangent){D=r.clone(x,D);var se=r.fromArray(e,($+3)%K,F);r.subtract(se,ie,se);var le=r.subtract(ee,ie,k);x=r.normalize(r.cross(le,se,x),x),o.normal&&(b[$]=x.x,b[te]=x.y,b[re]=x.z,b[$+K]=x.x,b[te+K]=x.y,b[re+K]=x.z),o.tangent&&(P=r.normalize(r.cross(D,x,P),P),C[$]=P.x,C[te]=P.y,C[re]=P.z,C[$+K]=P.x,C[$+1+K]=P.y,C[$+2+K]=P.z),o.bitangent&&(w[$]=D.x,w[te]=D.y,w[re]=D.z,w[$+K]=D.x,w[te+K]=D.y,w[re+K]=D.z)}}if(o.st){K=v.length;for(var ue=0;ue<K;ue+=2)v[ue]=(v[ue]-Q.x)/(Z.x-Q.x),v[ue+1]=(v[ue+1]-Q.y)/(Z.y-Q.y)}var ce=new f;return o.position&&(ce.position=new p({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:_})),o.st&&(ce.st=new p({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:v})),o.normal&&(ce.normal=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:b})),o.tangent&&(ce.tangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:C})),o.bitangent&&(ce.bitangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:w})),T&&(ce.extrudeDirection=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:E})),ce}function I(e){for(var t=e.length/3,r=_.createTypedArray(t,6*t),i=0,n=0;n<t;n++){var o=n,a=n+t,s=(o+1)%t,l=s+t;r[i++]=o,r[i++]=a,r[i++]=s,r[i++]=s,r[i++]=a,r[i++]=l}return r}function O(t){var i=t.center,n=t.ellipsoid,o=t.semiMajorAxis,a=r.multiplyByScalar(n.geodeticSurfaceNormal(i,L),t.height,L);Q.center=r.add(i,a,Q.center),Q.radius=o,a=r.multiplyByScalar(n.geodeticSurfaceNormal(i,a),t.extrudedHeight,a),Z.center=r.add(i,a,Z.center),Z.radius=o;var s=u.computeEllipsePositions(t,!0,!0),l=s.positions,c=s.numPts,d=s.outerPositions,p=e.union(Q,Z),f=A(l,t,!0),v=x(c),y=v.length;v.length=2*y;for(var b=l.length/3,S=0;S<y;S+=3)v[S+y]=v[S+2]+b,v[S+1+y]=v[S+1]+b,v[S+2+y]=v[S]+b;var w=_.createTypedArray(2*b/3,v),T=new h({attributes:f,indices:w,primitiveType:C.TRIANGLES}),E=D(d,t);v=I(d);var P=_.createTypedArray(2*d.length/3,v),O=new h({attributes:E,indices:P,primitiveType:C.TRIANGLES}),M=g.combineInstances([new m({geometry:T}),new m({geometry:O})]);return{boundingSphere:p,attributes:M[0].attributes,indices:M[0].indices}}function M(e,t,i,n,o){T.eastNorthUpToFixedFrame(e,t,K),b.inverseTransformation(K,J);var a;for(a=0;a<4;++a)r.clone(r.ZERO,ee[a]);for(ee[0].x+=i,ee[1].x-=i,ee[2].y+=n,ee[3].y-=n,y.fromRotationZ(o,$),a=0;a<4;++a)y.multiplyByVector($,ee[a],ee[a]),b.multiplyByPoint(K,ee[a],ee[a]),t.cartesianToCartographic(ee[a],te[a]);return w.fromCartographicArray(te)}function R(e){e=o(e,o.EMPTY_OBJECT);var t=e.center,i=o(e.ellipsoid,c.WGS84),n=e.semiMajorAxis,s=e.semiMinorAxis,l=o(e.granularity,v.RADIANS_PER_DEGREE),u=o(e.height,0),d=e.extrudedHeight,h=a(d)&&Math.abs(u-d)>1,p=o(e.vertexFormat,E.DEFAULT);this._center=r.clone(t),this._semiMajorAxis=n,this._semiMinorAxis=s,this._ellipsoid=c.clone(i),this._rotation=o(e.rotation,0),this._stRotation=o(e.stRotation,0),this._height=u,this._granularity=l,this._vertexFormat=E.clone(p),this._extrudedHeight=o(d,u),this._extrude=h,this._shadowVolume=o(e.shadowVolume,!1),this._workerName="createEllipseGeometry",this._rectangle=M(this._center,this._ellipsoid,n,s,this._rotation)}var L=new r,N=new r,k=new r,F=new r,B=new t,U=new y,V=new S,z=new r,G=new r,W=new r,H=new i,j=new r,q=new t,Y=new t,X=new r,Q=new e,Z=new e,K=new b,J=new b,$=new y,ee=[new r,new r,new r,new r],te=[new i,new i,new i,new i];R.packedLength=r.packedLength+c.packedLength+E.packedLength+w.packedLength+9,R.pack=function(e,t,i){return i=o(i,0),r.pack(e._center,t,i),i+=r.packedLength,c.pack(e._ellipsoid,t,i),i+=c.packedLength,E.pack(e._vertexFormat,t,i),i+=E.packedLength,w.pack(e._rectangle,t,i),i+=w.packedLength,t[i++]=e._semiMajorAxis,t[i++]=e._semiMinorAxis,t[i++]=e._rotation,t[i++]=e._stRotation,t[i++]=e._height,t[i++]=e._granularity,t[i++]=e._extrudedHeight,t[i++]=e._extrude?1:0,t[i]=e._shadowVolume?1:0,t};var re=new r,ie=new c,ne=new E,oe=new w,ae={center:re,ellipsoid:ie,vertexFormat:ne,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,stRotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,shadowVolume:void 0};return R.unpack=function(e,t,i){t=o(t,0);var n=r.unpack(e,t,re);t+=r.packedLength;var s=c.unpack(e,t,ie);t+=c.packedLength;var l=E.unpack(e,t,ne);t+=E.packedLength;var u=w.unpack(e,t,oe);t+=w.packedLength;var d=e[t++],h=e[t++],p=e[t++],f=e[t++],m=e[t++],g=e[t++],_=e[t++],v=1===e[t++],y=1===e[t];return a(i)?(i._center=r.clone(n,i._center),i._ellipsoid=c.clone(s,i._ellipsoid),i._vertexFormat=E.clone(l,i._vertexFormat),i._semiMajorAxis=d,i._semiMinorAxis=h,i._rotation=p,i._stRotation=f,i._height=m,i._granularity=g,i._extrudedHeight=_,i._extrude=v,i._shadowVolume=y,i._rectangle=w.clone(u),i):(ae.height=m,ae.extrudedHeight=_,ae.granularity=g,ae.stRotation=f,ae.rotation=p,ae.semiMajorAxis=d,ae.semiMinorAxis=h,ae.shadowVolume=y,new R(ae))},R.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,vertexFormat:e._vertexFormat,stRotation:e._stRotation};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),r.shadowVolume=e._shadowVolume,t=O(r)):t=P(r),new h({attributes:t.attributes,indices:t.indices,primitiveType:C.TRIANGLES,boundingSphere:t.boundingSphere})}},R.createShadowVolume=function(e,t,r){var i=e._granularity,n=e._ellipsoid,o=t(i,n),a=r(i,n);return new R({center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:n,rotation:e._rotation,stRotation:e._stRotation,granularity:i,extrudedHeight:o,height:a,vertexFormat:E.POSITION_ONLY,shadowVolume:!0})},s(R.prototype,{rectangle:{get:function(){return this._rectangle}}}),R}),define("Core/CircleGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./EllipseGeometry","./Ellipsoid","./VertexFormat"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT);var t=e.radius,i={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,vertexFormat:e.vertexFormat,stRotation:e.stRotation,shadowVolume:e.shadowVolume};this._ellipseGeometry=new o(i),this._workerName="createCircleGeometry"}l.packedLength=o.packedLength,l.pack=function(e,t,r){return o.pack(e._ellipseGeometry,t,r)};var u=new o({center:new e,semiMajorAxis:1,semiMinorAxis:1}),c={center:new e,radius:void 0,ellipsoid:a.clone(a.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,vertexFormat:new s,stRotation:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0,shadowVolume:void 0};return l.unpack=function(t,r,n){var d=o.unpack(t,r,u);return c.center=e.clone(d._center,c.center),c.ellipsoid=a.clone(d._ellipsoid,c.ellipsoid),c.height=d._height,c.extrudedHeight=d._extrudedHeight,c.granularity=d._granularity,c.vertexFormat=s.clone(d._vertexFormat,c.vertexFormat),c.stRotation=d._stRotation,c.shadowVolume=d._shadowVolume,i(n)?(c.semiMajorAxis=d._semiMajorAxis,c.semiMinorAxis=d._semiMinorAxis,n._ellipseGeometry=new o(c),n):(c.radius=d._semiMajorAxis,new l(c))},l.createGeometry=function(e){return o.createGeometry(e._ellipseGeometry)},l.createShadowVolume=function(e,t,r){var i=e._ellipseGeometry._granularity,n=e._ellipseGeometry._ellipsoid,o=t(i,n),a=r(i,n);return new l({center:e._ellipseGeometry._center,radius:e._ellipseGeometry._semiMajorAxis,ellipsoid:n,stRotation:e._ellipseGeometry._stRotation,granularity:i,extrudedHeight:o,height:a,vertexFormat:s.POSITION_ONLY,shadowVolume:!0})},n(l.prototype,{rectangle:{get:function(){return this._ellipseGeometry.rectangle}}}),l}),define("Core/EllipseOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(i){var n=i.center;v=t.multiplyByScalar(i.ellipsoid.geodeticSurfaceNormal(n,v),i.height,v),v=t.add(n,v,v);for(var o=new e(v,i.semiMajorAxis),s=a.computeEllipsePositions(i,!1,!0).outerPositions,l=new c({position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:a.raisePositionsToHeight(s,i,!1)})}),h=s.length/3,p=d.createTypedArray(h,2*h),f=0,m=0;m<h;++m)p[f++]=m,p[f++]=(m+1)%h;return{boundingSphere:o,attributes:l,indices:p}}function m(n){var o=n.center,s=n.ellipsoid,l=n.semiMajorAxis,p=t.multiplyByScalar(s.geodeticSurfaceNormal(o,_),n.height,_);y.center=t.add(o,p,y.center),y.radius=l,p=t.multiplyByScalar(s.geodeticSurfaceNormal(o,p),n.extrudedHeight,p),b.center=t.add(o,p,b.center),b.radius=l;var f=a.computeEllipsePositions(n,!1,!0).outerPositions,m=new c({position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:a.raisePositionsToHeight(f,n,!0)})});f=m.position.values;var g=e.union(y,b),v=f.length/3,C=i(n.numberOfVerticalLines,16);C=h.clamp(C,0,v/2);var S=d.createTypedArray(v,2*v+2*C);v/=2;var w,T=0;for(w=0;w<v;++w)S[T++]=w,S[T++]=(w+1)%v,S[T++]=w+v,S[T++]=(w+1)%v+v;var E;if(C>0){var A=Math.min(C,v);E=Math.round(v/A);var x=Math.min(E*C,v);for(w=0;w<x;w+=E)S[T++]=w,S[T++]=w+v}return{boundingSphere:g,attributes:m,indices:S}}function g(e){e=i(e,i.EMPTY_OBJECT);var r=e.center,o=i(e.ellipsoid,s.WGS84),a=e.semiMajorAxis,l=e.semiMinorAxis,u=i(e.granularity,h.RADIANS_PER_DEGREE),c=i(e.height,0),d=e.extrudedHeight,p=n(d)&&Math.abs(c-d)>1;this._center=t.clone(r),this._semiMajorAxis=a,this._semiMinorAxis=l,this._ellipsoid=s.clone(o),this._rotation=i(e.rotation,0),this._height=c,this._granularity=u,this._extrudedHeight=d,this._extrude=p,this._numberOfVerticalLines=Math.max(i(e.numberOfVerticalLines,16),0),this._workerName="createEllipseOutlineGeometry"}var _=new t,v=new t,y=new e,b=new e;g.packedLength=t.packedLength+s.packedLength+9,g.pack=function(e,r,o){return o=i(o,0),t.pack(e._center,r,o),o+=t.packedLength,s.pack(e._ellipsoid,r,o),o+=s.packedLength,r[o++]=e._semiMajorAxis,r[o++]=e._semiMinorAxis,r[o++]=e._rotation,r[o++]=e._height,r[o++]=e._granularity,r[o++]=n(e._extrudedHeight)?1:0,r[o++]=i(e._extrudedHeight,0),r[o++]=e._extrude?1:0,r[o]=e._numberOfVerticalLines,r} +;var C=new t,S=new s,w={center:C,ellipsoid:S,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,numberOfVerticalLines:void 0};return g.unpack=function(e,r,o){r=i(r,0);var a=t.unpack(e,r,C);r+=t.packedLength;var l=s.unpack(e,r,S);r+=s.packedLength;var u=e[r++],c=e[r++],d=e[r++],h=e[r++],p=e[r++],f=e[r++],m=e[r++],_=1===e[r++],v=e[r];return n(o)?(o._center=t.clone(a,o._center),o._ellipsoid=s.clone(l,o._ellipsoid),o._semiMajorAxis=u,o._semiMinorAxis=c,o._rotation=d,o._height=h,o._granularity=p,o._extrudedHeight=f?m:void 0,o._extrude=_,o._numberOfVerticalLines=v,o):(w.height=h,w.extrudedHeight=f?m:void 0,w.granularity=p,w.rotation=d,w.semiMajorAxis=u,w.semiMinorAxis=c,w.numberOfVerticalLines=v,new g(w))},g.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,numberOfVerticalLines:e._numberOfVerticalLines};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),t=m(r)):t=f(r),new l({attributes:t.attributes,indices:t.indices,primitiveType:p.LINES,boundingSphere:t.boundingSphere})}},g}),define("Core/CircleOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipseOutlineGeometry","./Ellipsoid"],function(e,t,r,i,n,o){"use strict";function a(e){e=r(e,r.EMPTY_OBJECT);var t=e.radius,i={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,numberOfVerticalLines:e.numberOfVerticalLines};this._ellipseGeometry=new n(i),this._workerName="createCircleOutlineGeometry"}a.packedLength=n.packedLength,a.pack=function(e,t,r){return n.pack(e._ellipseGeometry,t,r)};var s=new n({center:new e,semiMajorAxis:1,semiMinorAxis:1}),l={center:new e,radius:void 0,ellipsoid:o.clone(o.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,numberOfVerticalLines:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0};return a.unpack=function(t,r,u){var c=n.unpack(t,r,s);return l.center=e.clone(c._center,l.center),l.ellipsoid=o.clone(c._ellipsoid,l.ellipsoid),l.height=c._height,l.extrudedHeight=c._extrudedHeight,l.granularity=c._granularity,l.numberOfVerticalLines=c._numberOfVerticalLines,i(u)?(l.semiMajorAxis=c._semiMajorAxis,l.semiMinorAxis=c._semiMinorAxis,u._ellipseGeometry=new n(l),u):(l.radius=c._semiMajorAxis,new a(l))},a.createGeometry=function(e){return n.createGeometry(e._ellipseGeometry)},a}),define("Core/Color",["./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math"],function(e,t,r,i,n,o){"use strict";function a(e,t,r){return r<0&&(r+=1),r>1&&(r-=1),6*r<1?e+6*(t-e)*r:2*r<1?t:3*r<2?e+(t-e)*(2/3-r)*6:e}function s(e,r,i,n){this.red=t(e,1),this.green=t(r,1),this.blue=t(i,1),this.alpha=t(n,1)}s.fromCartesian4=function(e,t){return r(t)?(t.red=e.x,t.green=e.y,t.blue=e.z,t.alpha=e.w,t):new s(e.x,e.y,e.z,e.w)},s.fromBytes=function(e,i,n,o,a){return e=s.byteToFloat(t(e,255)),i=s.byteToFloat(t(i,255)),n=s.byteToFloat(t(n,255)),o=s.byteToFloat(t(o,255)),r(a)?(a.red=e,a.green=i,a.blue=n,a.alpha=o,a):new s(e,i,n,o)},s.fromAlpha=function(e,t,i){return r(i)?(i.red=e.red,i.green=e.green,i.blue=e.blue,i.alpha=t,i):new s(e.red,e.green,e.blue,t)};var l,u,c;i.supportsTypedArrays()&&(l=new ArrayBuffer(4),u=new Uint32Array(l),c=new Uint8Array(l)),s.fromRgba=function(e,t){return u[0]=e,s.fromBytes(c[0],c[1],c[2],c[3],t)},s.fromHsl=function(e,i,n,o,l){e=t(e,0)%1,i=t(i,0),n=t(n,0),o=t(o,1);var u=n,c=n,d=n;if(0!==i){var h;h=n<.5?n*(1+i):n+i-n*i;var p=2*n-h;u=a(p,h,e+1/3),c=a(p,h,e),d=a(p,h,e-1/3)}return r(l)?(l.red=u,l.green=c,l.blue=d,l.alpha=o,l):new s(u,c,d,o)},s.fromRandom=function(e,i){e=t(e,t.EMPTY_OBJECT);var n=e.red;if(!r(n)){var a=t(e.minimumRed,0),l=t(e.maximumRed,1);n=a+o.nextRandomNumber()*(l-a)}var u=e.green;if(!r(u)){var c=t(e.minimumGreen,0),d=t(e.maximumGreen,1);u=c+o.nextRandomNumber()*(d-c)}var h=e.blue;if(!r(h)){var p=t(e.minimumBlue,0),f=t(e.maximumBlue,1);h=p+o.nextRandomNumber()*(f-p)}var m=e.alpha;if(!r(m)){var g=t(e.minimumAlpha,0),_=t(e.maximumAlpha,1);m=g+o.nextRandomNumber()*(_-g)}return r(i)?(i.red=n,i.green=u,i.blue=h,i.alpha=m,i):new s(n,u,h,m)};var d=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,h=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,p=/^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i,f=/^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i;return s.fromCssColorString=function(e,i){r(i)||(i=new s);var n=s[e.toUpperCase()];if(r(n))return s.clone(n,i),i;var o=d.exec(e);return null!==o?(i.red=parseInt(o[1],16)/15,i.green=parseInt(o[2],16)/15,i.blue=parseInt(o[3],16)/15,i.alpha=1,i):null!==(o=h.exec(e))?(i.red=parseInt(o[1],16)/255,i.green=parseInt(o[2],16)/255,i.blue=parseInt(o[3],16)/255,i.alpha=1,i):null!==(o=p.exec(e))?(i.red=parseFloat(o[1])/("%"===o[1].substr(-1)?100:255),i.green=parseFloat(o[2])/("%"===o[2].substr(-1)?100:255),i.blue=parseFloat(o[3])/("%"===o[3].substr(-1)?100:255),i.alpha=parseFloat(t(o[4],"1.0")),i):null!==(o=f.exec(e))?s.fromHsl(parseFloat(o[1])/360,parseFloat(o[2])/100,parseFloat(o[3])/100,parseFloat(t(o[4],"1.0")),i):i=void 0},s.packedLength=4,s.pack=function(e,r,i){return i=t(i,0),r[i++]=e.red,r[i++]=e.green,r[i++]=e.blue,r[i]=e.alpha,r},s.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new s),n.red=e[i++],n.green=e[i++],n.blue=e[i++],n.alpha=e[i],n},s.byteToFloat=function(e){return e/255},s.floatToByte=function(e){return 1===e?255:256*e|0},s.clone=function(e,t){if(r(e))return r(t)?(t.red=e.red,t.green=e.green,t.blue=e.blue,t.alpha=e.alpha,t):new s(e.red,e.green,e.blue,e.alpha)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.red===t.red&&e.green===t.green&&e.blue===t.blue&&e.alpha===t.alpha},s.equalsArray=function(e,t,r){return e.red===t[r]&&e.green===t[r+1]&&e.blue===t[r+2]&&e.alpha===t[r+3]},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return this===e||r(e)&&Math.abs(this.red-e.red)<=t&&Math.abs(this.green-e.green)<=t&&Math.abs(this.blue-e.blue)<=t&&Math.abs(this.alpha-e.alpha)<=t},s.prototype.toString=function(){return"("+this.red+", "+this.green+", "+this.blue+", "+this.alpha+")"},s.prototype.toCssColorString=function(){var e=s.floatToByte(this.red),t=s.floatToByte(this.green),r=s.floatToByte(this.blue);return 1===this.alpha?"rgb("+e+","+t+","+r+")":"rgba("+e+","+t+","+r+","+this.alpha+")"},s.prototype.toBytes=function(e){var t=s.floatToByte(this.red),i=s.floatToByte(this.green),n=s.floatToByte(this.blue),o=s.floatToByte(this.alpha);return r(e)?(e[0]=t,e[1]=i,e[2]=n,e[3]=o,e):[t,i,n,o]},s.prototype.toRgba=function(){return c[0]=s.floatToByte(this.red),c[1]=s.floatToByte(this.green),c[2]=s.floatToByte(this.blue),c[3]=s.floatToByte(this.alpha),u[0]},s.prototype.brighten=function(e,t){return e=1-e,t.red=1-(1-this.red)*e,t.green=1-(1-this.green)*e,t.blue=1-(1-this.blue)*e,t.alpha=this.alpha,t},s.prototype.darken=function(e,t){return e=1-e,t.red=this.red*e,t.green=this.green*e,t.blue=this.blue*e,t.alpha=this.alpha,t},s.prototype.withAlpha=function(e,t){return s.fromAlpha(this,e,t)},s.add=function(e,t,r){return r.red=e.red+t.red,r.green=e.green+t.green,r.blue=e.blue+t.blue,r.alpha=e.alpha+t.alpha,r},s.subtract=function(e,t,r){return r.red=e.red-t.red,r.green=e.green-t.green,r.blue=e.blue-t.blue,r.alpha=e.alpha-t.alpha,r},s.multiply=function(e,t,r){return r.red=e.red*t.red,r.green=e.green*t.green,r.blue=e.blue*t.blue,r.alpha=e.alpha*t.alpha,r},s.divide=function(e,t,r){return r.red=e.red/t.red,r.green=e.green/t.green,r.blue=e.blue/t.blue,r.alpha=e.alpha/t.alpha,r},s.mod=function(e,t,r){return r.red=e.red%t.red,r.green=e.green%t.green,r.blue=e.blue%t.blue,r.alpha=e.alpha%t.alpha,r},s.multiplyByScalar=function(e,t,r){return r.red=e.red*t,r.green=e.green*t,r.blue=e.blue*t,r.alpha=e.alpha*t,r},s.divideByScalar=function(e,t,r){return r.red=e.red/t,r.green=e.green/t,r.blue=e.blue/t,r.alpha=e.alpha/t,r},s.ALICEBLUE=n(s.fromCssColorString("#F0F8FF")),s.ANTIQUEWHITE=n(s.fromCssColorString("#FAEBD7")),s.AQUA=n(s.fromCssColorString("#00FFFF")),s.AQUAMARINE=n(s.fromCssColorString("#7FFFD4")),s.AZURE=n(s.fromCssColorString("#F0FFFF")),s.BEIGE=n(s.fromCssColorString("#F5F5DC")),s.BISQUE=n(s.fromCssColorString("#FFE4C4")),s.BLACK=n(s.fromCssColorString("#000000")),s.BLANCHEDALMOND=n(s.fromCssColorString("#FFEBCD")),s.BLUE=n(s.fromCssColorString("#0000FF")),s.BLUEVIOLET=n(s.fromCssColorString("#8A2BE2")),s.BROWN=n(s.fromCssColorString("#A52A2A")),s.BURLYWOOD=n(s.fromCssColorString("#DEB887")),s.CADETBLUE=n(s.fromCssColorString("#5F9EA0")),s.CHARTREUSE=n(s.fromCssColorString("#7FFF00")),s.CHOCOLATE=n(s.fromCssColorString("#D2691E")),s.CORAL=n(s.fromCssColorString("#FF7F50")),s.CORNFLOWERBLUE=n(s.fromCssColorString("#6495ED")),s.CORNSILK=n(s.fromCssColorString("#FFF8DC")),s.CRIMSON=n(s.fromCssColorString("#DC143C")),s.CYAN=n(s.fromCssColorString("#00FFFF")),s.DARKBLUE=n(s.fromCssColorString("#00008B")),s.DARKCYAN=n(s.fromCssColorString("#008B8B")),s.DARKGOLDENROD=n(s.fromCssColorString("#B8860B")),s.DARKGRAY=n(s.fromCssColorString("#A9A9A9")),s.DARKGREEN=n(s.fromCssColorString("#006400")),s.DARKGREY=s.DARKGRAY,s.DARKKHAKI=n(s.fromCssColorString("#BDB76B")),s.DARKMAGENTA=n(s.fromCssColorString("#8B008B")),s.DARKOLIVEGREEN=n(s.fromCssColorString("#556B2F")),s.DARKORANGE=n(s.fromCssColorString("#FF8C00")),s.DARKORCHID=n(s.fromCssColorString("#9932CC")),s.DARKRED=n(s.fromCssColorString("#8B0000")),s.DARKSALMON=n(s.fromCssColorString("#E9967A")),s.DARKSEAGREEN=n(s.fromCssColorString("#8FBC8F")),s.DARKSLATEBLUE=n(s.fromCssColorString("#483D8B")),s.DARKSLATEGRAY=n(s.fromCssColorString("#2F4F4F")),s.DARKSLATEGREY=s.DARKSLATEGRAY,s.DARKTURQUOISE=n(s.fromCssColorString("#00CED1")),s.DARKVIOLET=n(s.fromCssColorString("#9400D3")),s.DEEPPINK=n(s.fromCssColorString("#FF1493")),s.DEEPSKYBLUE=n(s.fromCssColorString("#00BFFF")),s.DIMGRAY=n(s.fromCssColorString("#696969")),s.DIMGREY=s.DIMGRAY,s.DODGERBLUE=n(s.fromCssColorString("#1E90FF")),s.FIREBRICK=n(s.fromCssColorString("#B22222")),s.FLORALWHITE=n(s.fromCssColorString("#FFFAF0")),s.FORESTGREEN=n(s.fromCssColorString("#228B22")),s.FUCHSIA=n(s.fromCssColorString("#FF00FF")),s.GAINSBORO=n(s.fromCssColorString("#DCDCDC")),s.GHOSTWHITE=n(s.fromCssColorString("#F8F8FF")),s.GOLD=n(s.fromCssColorString("#FFD700")),s.GOLDENROD=n(s.fromCssColorString("#DAA520")),s.GRAY=n(s.fromCssColorString("#808080")),s.GREEN=n(s.fromCssColorString("#008000")),s.GREENYELLOW=n(s.fromCssColorString("#ADFF2F")),s.GREY=s.GRAY,s.HONEYDEW=n(s.fromCssColorString("#F0FFF0")),s.HOTPINK=n(s.fromCssColorString("#FF69B4")),s.INDIANRED=n(s.fromCssColorString("#CD5C5C")),s.INDIGO=n(s.fromCssColorString("#4B0082")),s.IVORY=n(s.fromCssColorString("#FFFFF0")),s.KHAKI=n(s.fromCssColorString("#F0E68C")),s.LAVENDER=n(s.fromCssColorString("#E6E6FA")),s.LAVENDAR_BLUSH=n(s.fromCssColorString("#FFF0F5")),s.LAWNGREEN=n(s.fromCssColorString("#7CFC00")),s.LEMONCHIFFON=n(s.fromCssColorString("#FFFACD")),s.LIGHTBLUE=n(s.fromCssColorString("#ADD8E6")),s.LIGHTCORAL=n(s.fromCssColorString("#F08080")),s.LIGHTCYAN=n(s.fromCssColorString("#E0FFFF")),s.LIGHTGOLDENRODYELLOW=n(s.fromCssColorString("#FAFAD2")),s.LIGHTGRAY=n(s.fromCssColorString("#D3D3D3")),s.LIGHTGREEN=n(s.fromCssColorString("#90EE90")),s.LIGHTGREY=s.LIGHTGRAY,s.LIGHTPINK=n(s.fromCssColorString("#FFB6C1")),s.LIGHTSEAGREEN=n(s.fromCssColorString("#20B2AA")),s.LIGHTSKYBLUE=n(s.fromCssColorString("#87CEFA")),s.LIGHTSLATEGRAY=n(s.fromCssColorString("#778899")),s.LIGHTSLATEGREY=s.LIGHTSLATEGRAY,s.LIGHTSTEELBLUE=n(s.fromCssColorString("#B0C4DE")),s.LIGHTYELLOW=n(s.fromCssColorString("#FFFFE0")),s.LIME=n(s.fromCssColorString("#00FF00")),s.LIMEGREEN=n(s.fromCssColorString("#32CD32")),s.LINEN=n(s.fromCssColorString("#FAF0E6")),s.MAGENTA=n(s.fromCssColorString("#FF00FF")),s.MAROON=n(s.fromCssColorString("#800000")),s.MEDIUMAQUAMARINE=n(s.fromCssColorString("#66CDAA")),s.MEDIUMBLUE=n(s.fromCssColorString("#0000CD")),s.MEDIUMORCHID=n(s.fromCssColorString("#BA55D3")),s.MEDIUMPURPLE=n(s.fromCssColorString("#9370DB")),s.MEDIUMSEAGREEN=n(s.fromCssColorString("#3CB371")),s.MEDIUMSLATEBLUE=n(s.fromCssColorString("#7B68EE")),s.MEDIUMSPRINGGREEN=n(s.fromCssColorString("#00FA9A")),s.MEDIUMTURQUOISE=n(s.fromCssColorString("#48D1CC")),s.MEDIUMVIOLETRED=n(s.fromCssColorString("#C71585")),s.MIDNIGHTBLUE=n(s.fromCssColorString("#191970")),s.MINTCREAM=n(s.fromCssColorString("#F5FFFA")),s.MISTYROSE=n(s.fromCssColorString("#FFE4E1")),s.MOCCASIN=n(s.fromCssColorString("#FFE4B5")),s.NAVAJOWHITE=n(s.fromCssColorString("#FFDEAD")),s.NAVY=n(s.fromCssColorString("#000080")),s.OLDLACE=n(s.fromCssColorString("#FDF5E6")),s.OLIVE=n(s.fromCssColorString("#808000")),s.OLIVEDRAB=n(s.fromCssColorString("#6B8E23")),s.ORANGE=n(s.fromCssColorString("#FFA500")),s.ORANGERED=n(s.fromCssColorString("#FF4500")),s.ORCHID=n(s.fromCssColorString("#DA70D6")),s.PALEGOLDENROD=n(s.fromCssColorString("#EEE8AA")),s.PALEGREEN=n(s.fromCssColorString("#98FB98")),s.PALETURQUOISE=n(s.fromCssColorString("#AFEEEE")),s.PALEVIOLETRED=n(s.fromCssColorString("#DB7093")),s.PAPAYAWHIP=n(s.fromCssColorString("#FFEFD5")),s.PEACHPUFF=n(s.fromCssColorString("#FFDAB9")),s.PERU=n(s.fromCssColorString("#CD853F")),s.PINK=n(s.fromCssColorString("#FFC0CB")),s.PLUM=n(s.fromCssColorString("#DDA0DD")),s.POWDERBLUE=n(s.fromCssColorString("#B0E0E6")),s.PURPLE=n(s.fromCssColorString("#800080")),s.RED=n(s.fromCssColorString("#FF0000")),s.ROSYBROWN=n(s.fromCssColorString("#BC8F8F")),s.ROYALBLUE=n(s.fromCssColorString("#4169E1")),s.SADDLEBROWN=n(s.fromCssColorString("#8B4513")),s.SALMON=n(s.fromCssColorString("#FA8072")),s.SANDYBROWN=n(s.fromCssColorString("#F4A460")),s.SEAGREEN=n(s.fromCssColorString("#2E8B57")),s.SEASHELL=n(s.fromCssColorString("#FFF5EE")),s.SIENNA=n(s.fromCssColorString("#A0522D")),s.SILVER=n(s.fromCssColorString("#C0C0C0")),s.SKYBLUE=n(s.fromCssColorString("#87CEEB")),s.SLATEBLUE=n(s.fromCssColorString("#6A5ACD")),s.SLATEGRAY=n(s.fromCssColorString("#708090")),s.SLATEGREY=s.SLATEGRAY,s.SNOW=n(s.fromCssColorString("#FFFAFA")),s.SPRINGGREEN=n(s.fromCssColorString("#00FF7F")),s.STEELBLUE=n(s.fromCssColorString("#4682B4")),s.TAN=n(s.fromCssColorString("#D2B48C")),s.TEAL=n(s.fromCssColorString("#008080")),s.THISTLE=n(s.fromCssColorString("#D8BFD8")),s.TOMATO=n(s.fromCssColorString("#FF6347")),s.TURQUOISE=n(s.fromCssColorString("#40E0D0")),s.VIOLET=n(s.fromCssColorString("#EE82EE")),s.WHEAT=n(s.fromCssColorString("#F5DEB3")),s.WHITE=n(s.fromCssColorString("#FFFFFF")),s.WHITESMOKE=n(s.fromCssColorString("#F5F5F5")),s.YELLOW=n(s.fromCssColorString("#FFFF00")),s.YELLOWGREEN=n(s.fromCssColorString("#9ACD32")),s.TRANSPARENT=n(new s(0,0,0,0)),s}),define("Core/ClippingPlaneCollection",["./Cartesian3","./Cartesian4","./Check","./Color","./defaultValue","./defined","./defineProperties","./DeveloperError","./FeatureDetection","./Intersect","./Matrix4","./Plane"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e){e=n(e,n.EMPTY_OBJECT);var t=e.planes;o(t)?this._planes=t.slice(0):this._planes=[],this.enabled=n(e.enabled,!0),this.modelMatrix=c.clone(n(e.modelMatrix,c.IDENTITY)),this.edgeColor=i.clone(n(e.edgeColor,i.WHITE)),this.edgeWidth=n(e.edgeWidth,0),this._testIntersection=void 0,this._unionClippingRegions=void 0,this.unionClippingRegions=n(e.unionClippingRegions,!1)}function p(e){return e===u.OUTSIDE}function f(e){return e===u.INSIDE}function m(e,t){for(var r=e.length,i=0;i<r;++i)if(d.equals(e[i],t))return i;return-1}a(h.prototype,{length:{get:function(){return this._planes.length}},unionClippingRegions:{get:function(){return this._unionClippingRegions},set:function(e){this._unionClippingRegions!==e&&(this._unionClippingRegions=e,this._testIntersection=e?p:f)}}}),h.prototype.add=function(e){this._planes.push(e)},h.prototype.get=function(e){return this._planes[e]},h.prototype.contains=function(e){return-1!==m(this._planes,e)},h.prototype.remove=function(e){var t=this._planes,r=m(t,e);if(-1===r)return!1;for(var i=t.length-1,n=r;n<i;++n)t[n]=t[n+1];return t.length=i,!0},h.prototype.removeAll=function(){this._planes=[]};var g=new d(e.UNIT_X,0),_=new c;return h.prototype.transformAndPackPlanes=function(r,i){var n=this._planes,a=n.length,s=0;o(i)?(s=i.length,i.length=a):i=new Array(a);var l;for(l=s;l<a;++l)i[l]=new t;var u=c.multiply(r,this.modelMatrix,_);for(l=0;l<a;++l){var h=n[l],p=i[l];d.transform(h,u,g),e.clone(g.normal,p),p.w=g.distance}return i},h.prototype.clone=function(t){o(t)||(t=new h);var r,n=this.length;if(t.length!==n){var a=t._planes,s=a.length;for(a.length=n,r=s;r<n;++r)t._planes[r]=new d(e.UNIT_X,0)}for(r=0;r<n;++r)d.clone(this._planes[r],t._planes[r]);return t.enabled=this.enabled,c.clone(this.modelMatrix,t.modelMatrix),t.unionClippingRegions=this.unionClippingRegions,i.clone(this.edgeColor,t.edgeColor),t.edgeWidth=this.edgeWidth,t},h.prototype.computeIntersectionWithBoundingVolume=function(e,t){var r=this._planes,i=r.length,n=this.modelMatrix;o(t)&&(n=c.multiply(n,t,_));var a=u.INSIDE;!this.unionClippingRegions&&i>0&&(a=u.OUTSIDE);for(var s=0;s<i;++s){var l=r[s];d.transform(l,n,g);var h=e.intersectPlane(g);if(h===u.INTERSECTING)a=h;else if(this._testIntersection(h))return h}return a},h.isSupported=function(){return!l.isInternetExplorer()},h.MAX_CLIPPING_PLANES=6,h}),define("Core/ClockRange",["./freezeObject"],function(e){"use strict";return e({UNBOUNDED:0,CLAMPED:1,LOOP_STOP:2})}),define("Core/ClockStep",["./freezeObject"],function(e){"use strict";return e({TICK_DEPENDENT:0,SYSTEM_CLOCK_MULTIPLIER:1,SYSTEM_CLOCK:2})}),define("Core/getTimestamp",["./defined"],function(e){"use strict";return"undefined"!=typeof performance&&"function"==typeof performance.now&&isFinite(performance.now())?function(){return performance.now()}:function(){return Date.now()}}),define("Core/Clock",["./ClockRange","./ClockStep","./defaultValue","./defined","./defineProperties","./DeveloperError","./Event","./getTimestamp","./JulianDate"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(n){n=r(n,r.EMPTY_OBJECT);var o=n.currentTime,u=n.startTime,c=n.stopTime;o=i(o)?l.clone(o):i(u)?l.clone(u):i(c)?l.addDays(c,-1,new l):l.now(),u=i(u)?l.clone(u):l.clone(o),c=i(c)?l.clone(c):l.addDays(u,1,new l),this.startTime=u,this.stopTime=c,this.clockRange=r(n.clockRange,e.UNBOUNDED),this.canAnimate=r(n.canAnimate,!0),this.onTick=new a,this._currentTime=void 0,this._multiplier=void 0,this._clockStep=void 0,this._shouldAnimate=void 0,this._lastSystemTime=s(),this.currentTime=o,this.multiplier=r(n.multiplier,1),this.shouldAnimate=r(n.shouldAnimate,!1),this.clockStep=r(n.clockStep,t.SYSTEM_CLOCK_MULTIPLIER)}return n(u.prototype,{currentTime:{get:function(){return this._currentTime},set:function(e){l.equals(this._currentTime,e)||(this._clockStep===t.SYSTEM_CLOCK&&(this._clockStep=t.SYSTEM_CLOCK_MULTIPLIER),this._currentTime=e)}},multiplier:{get:function(){return this._multiplier},set:function(e){this._multiplier!==e&&(this._clockStep===t.SYSTEM_CLOCK&&(this._clockStep=t.SYSTEM_CLOCK_MULTIPLIER),this._multiplier=e)}},clockStep:{get:function(){return this._clockStep},set:function(e){e===t.SYSTEM_CLOCK&&(this._multiplier=1,this._shouldAnimate=!0,this._currentTime=l.now()),this._clockStep=e}},shouldAnimate:{get:function(){return this._shouldAnimate},set:function(e){this._shouldAnimate!==e&&(this._clockStep===t.SYSTEM_CLOCK&&(this._clockStep=t.SYSTEM_CLOCK_MULTIPLIER),this._shouldAnimate=e)}}}),u.prototype.tick=function(){var r=s(),i=l.clone(this._currentTime);if(this.canAnimate&&this._shouldAnimate){var n=this._clockStep;if(n===t.SYSTEM_CLOCK)i=l.now(i);else{var o=this._multiplier;if(n===t.TICK_DEPENDENT)i=l.addSeconds(i,o,i);else{var a=r-this._lastSystemTime;i=l.addSeconds(i,o*(a/1e3),i)}var u=this.clockRange,c=this.startTime,d=this.stopTime;if(u===e.CLAMPED)l.lessThan(i,c)?i=l.clone(c,i):l.greaterThan(i,d)&&(i=l.clone(d,i));else if(u===e.LOOP_STOP)for(l.lessThan(i,c)&&(i=l.clone(c,i));l.greaterThan(i,d);)i=l.addSeconds(c,l.secondsDifference(i,d),i)}}return this._currentTime=i,this._lastSystemTime=r,this.onTick.raiseEvent(this),i},u}),define("Core/ColorGeometryInstanceAttribute",["./Color","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError"],function(e,t,r,i,n,o){"use strict";function a(t,i,n,o){t=r(t,1),i=r(i,1),n=r(n,1),o=r(o,1),this.value=new Uint8Array([e.floatToByte(t),e.floatToByte(i),e.floatToByte(n),e.floatToByte(o)])}return n(a.prototype,{componentDatatype:{get:function(){return t.UNSIGNED_BYTE}},componentsPerAttribute:{get:function(){return 4}},normalize:{get:function(){return!0}}}),a.fromColor=function(e){return new a(e.red,e.green,e.blue,e.alpha)},a.toValue=function(e,t){return i(t)?e.toBytes(t):new Uint8Array(e.toBytes())},a.equals=function(e,t){return e===t||i(e)&&i(t)&&e.value[0]===t.value[0]&&e.value[1]===t.value[1]&&e.value[2]===t.value[2]&&e.value[3]===t.value[3]},a}),define("Core/CompressedTextureBuffer",["./defined","./defineProperties"],function(e,t){"use strict";function r(e,t,r,i){this._format=e,this._width=t,this._height=r,this._buffer=i}return t(r.prototype,{internalFormat:{get:function(){return this._format}},width:{get:function(){return this._width}},height:{get:function(){return this._height}},bufferView:{get:function(){return this._buffer}}}),r.clone=function(t){if(e(t))return new r(t._format,t._width,t._height,t._buffer)},r.prototype.clone=function(){return r.clone(this)},r}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){var t=e._uSquared,r=e._ellipsoid.maximumRadius,i=e._ellipsoid.minimumRadius,n=(r-i)/r,o=Math.cos(e._startHeading),a=Math.sin(e._startHeading),s=(1-n)*Math.tan(e._start.latitude),l=1/Math.sqrt(1+s*s),u=l*s,c=Math.atan2(s,o),d=l*a,h=d*d,p=1-h,f=Math.sqrt(p),m=t/4,g=m*m,_=g*m,v=g*g,y=1+m-3*g/4+5*_/4-175*v/64,b=1-m+15*g/8-35*_/8,C=1-3*m+35*g/4,S=1-5*m,w=y*c-b*Math.sin(2*c)*m/2-C*Math.sin(4*c)*g/16-S*Math.sin(6*c)*_/48-5*Math.sin(8*c)*v/512,T=e._constants;T.a=r,T.b=i,T.f=n,T.cosineHeading=o,T.sineHeading=a,T.tanU=s,T.cosineU=l,T.sineU=u,T.sigma=c,T.sineAlpha=d,T.sineSquaredAlpha=h,T.cosineSquaredAlpha=p,T.cosineAlpha=f,T.u2Over4=m,T.u4Over16=g,T.u6Over64=_,T.u8Over256=v,T.a0=y,T.a1=b,T.a2=C,T.a3=S,T.distanceRatio=w}function u(e,t){return e*t*(4+e*(4-3*t))/16}function c(e,t,r,i,n,o,a){var s=u(e,r);return(1-s)*e*t*(i+s*n*(a+s*o*(2*a*a-1)))}function d(e,t,r,i,n,o,a){var l,u,d,h,p,f=(t-r)/t,m=o-i,g=Math.atan((1-f)*Math.tan(n)),_=Math.atan((1-f)*Math.tan(a)),v=Math.cos(g),y=Math.sin(g),b=Math.cos(_),C=Math.sin(_),S=v*b,w=v*C,T=y*C,E=y*b,A=m,x=s.TWO_PI,P=Math.cos(A),D=Math.sin(A);do{P=Math.cos(A),D=Math.sin(A);var I=w-E*P;d=Math.sqrt(b*b*D*D+I*I),u=T+S*P,l=Math.atan2(d,u);var O;0===d?(O=0,h=1):(O=S*D/d,h=1-O*O),x=A,p=u-2*T/h,isNaN(p)&&(p=0),A=m+c(f,O,h,l,d,u,p)}while(Math.abs(A-x)>s.EPSILON12);var M=h*(t*t-r*r)/(r*r),R=1+M*(4096+M*(M*(320-175*M)-768))/16384,L=M*(256+M*(M*(74-47*M)-128))/1024,N=p*p,k=L*d*(p+L*(u*(2*N-1)-L*p*(4*d*d-3)*(4*N-3)/6)/4),F=r*R*(l-k),B=Math.atan2(b*D,w-E*P),U=Math.atan2(v*D,w*P-E);e._distance=F,e._startHeading=B,e._endHeading=U,e._uSquared=M}function h(r,i,n,o){e.normalize(o.cartographicToCartesian(i,m),f),e.normalize(o.cartographicToCartesian(n,m),m);d(r,o.maximumRadius,o.minimumRadius,i.longitude,i.latitude,n.longitude,n.latitude),r._start=t.clone(i,r._start),r._end=t.clone(n,r._end),r._start.height=0,r._end.height=0,l(r)}function p(e,r,o){var s=i(o,a.WGS84);this._ellipsoid=s,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,n(e)&&n(r)&&h(this,e,r,s)}var f=new e,m=new e;return o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),p.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},p.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},p.prototype.interpolateUsingSurfaceDistance=function(e,r){var i=this._constants,o=i.distanceRatio+e/i.b,a=Math.cos(2*o),s=Math.cos(4*o),l=Math.cos(6*o),u=Math.sin(2*o),d=Math.sin(4*o),h=Math.sin(6*o),p=Math.sin(8*o),f=o*o,m=o*f,g=i.u8Over256,_=i.u2Over4,v=i.u6Over64,y=i.u4Over16,b=2*m*g*a/3+o*(1-_+7*y/4-15*v/4+579*g/64-(y-15*v/4+187*g/16)*a-(5*v/4-115*g/16)*s-29*g*l/16)+(_/2-y+71*v/32-85*g/16)*u+(5*y/16-5*v/4+383*g/96)*d-f*((v-11*g/2)*u+5*g*d/2)+(29*v/96-29*g/16)*h+539*g*p/1536,C=Math.asin(Math.sin(b)*i.cosineAlpha),S=Math.atan(i.a/i.b*Math.tan(C));b-=i.sigma;var w=Math.cos(2*i.sigma+b),T=Math.sin(b),E=Math.cos(b),A=i.cosineU*E,x=i.sineU*T,P=Math.atan2(T*i.sineHeading,A-x*i.cosineHeading),D=P-c(i.f,i.sineAlpha,i.cosineSquaredAlpha,b,T,E,w);return n(r)?(r.longitude=this._start.longitude+D,r.latitude=S,r.height=0,r):new t(this._start.longitude+D,S,0)},p}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e,t,r){var i=T;i.length=e;var n;if(t===r){for(n=0;n<e;n++)i[n]=t;return i}var o=r-t,a=o/e;for(n=0;n<e;n++){var s=t+n*a;i[n]=s}return i}function p(t,r,i,n,o,a,s,l){var u=n.scaleToGeodeticSurface(t,P),c=n.scaleToGeodeticSurface(r,D),d=f.numberOfPoints(t,r,i),p=n.cartesianToCartographic(u,E),m=n.cartesianToCartographic(c,A),g=h(d,o,a);I.setEndPoints(p,m);var _=I.surfaceDistance/d,v=l;p.height=o;var y=n.cartographicToCartesian(p,x);e.pack(y,s,v),v+=3;for(var b=1;b<d;b++){var C=I.interpolateUsingSurfaceDistance(b*_,A);C.height=g[b],y=n.cartographicToCartesian(C,x),e.pack(y,s,v),v+=3}return v}var f={};f.numberOfPoints=function(t,r,i){var n=e.distance(t,r);return Math.ceil(n/i)};var m=new t;f.extractHeights=function(e,t){for(var r=e.length,i=new Array(r),n=0;n<r;n++){var o=e[n];i[n]=t.cartesianToCartographic(o,m).height}return i};var g=new c,_=new e,v=new e,y=new d(e.UNIT_X,0),b=new e,C=new d(e.UNIT_X,0),S=new e,w=new e,T=[],E=new t,A=new t,x=new e,P=new e,D=new e,I=new a;return f.wrapLongitude=function(t,n){var o=[],a=[];if(i(t)&&t.length>0){n=r(n,c.IDENTITY);var l=c.inverseTransformation(n,g),u=c.multiplyByPoint(l,e.ZERO,_),h=e.normalize(c.multiplyByPointAsVector(l,e.UNIT_Y,v),v),p=d.fromPointNormal(u,h,y),f=e.normalize(c.multiplyByPointAsVector(l,e.UNIT_X,b),b),m=d.fromPointNormal(u,f,C),T=1;o.push(e.clone(t[0]));for(var E=o[0],A=t.length,x=1;x<A;++x){var P=t[x];if(d.getPointDistance(m,E)<0||d.getPointDistance(m,P)<0){var D=s.lineSegmentPlane(E,P,p,S);if(i(D)){var I=e.multiplyByScalar(h,5e-9,w);d.getPointDistance(p,E)<0&&e.negate(I,I),o.push(e.add(D,I,new e)),a.push(T+1),e.negate(I,I),o.push(e.add(D,I,new e)),T=1}}o.push(e.clone(t[x])),T++,E=P}a.push(T)}return{positions:o,lengths:a}},f.generateArc=function(t){i(t)||(t={});var n=t.positions,a=n.length,s=r(t.ellipsoid,o.WGS84),c=r(t.height,0),d=l(c);if(a<1)return[];if(1===a){var h=s.scaleToGeodeticSurface(n[0],P);if(0!==(c=d?c[0]:c)){var m=s.geodeticSurfaceNormal(h,x);e.multiplyByScalar(m,c,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var g=t.minDistance;if(!i(g)){var _=r(t.granularity,u.RADIANS_PER_DEGREE);g=u.chordLength(_,s.maximumRadius)}var v,y=0;for(v=0;v<a-1;v++)y+=f.numberOfPoints(n[v],n[v+1],g);var b=3*(y+1),C=new Array(b),S=0;for(v=0;v<a-1;v++){S=p(n[v],n[v+1],g,s,d?c[v]:c,d?c[v+1]:c,C,S)}T.length=0;var w=n[a-1],A=s.cartesianToCartographic(w,E);A.height=d?c[a-1]:c;var D=s.cartographicToCartesian(A,x);return e.pack(D,C,b-3),C},f.generateCartesianArc=function(t){for(var r=f.generateArc(t),i=r.length/3,n=new Array(i),o=0;o<i;o++)n[o]=e.unpack(r,3*o);return n},f}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e,t){for(var r=new Array(e.length),i=0;i<e.length;i++){var n=e[i];R=t.cartesianToCartographic(n,R),r[i]=R.height,e[i]=t.scaleToGeodeticSurface(n,n)}return r}function p(e,r,i,n){var o,a=e[0],s=e[1],l=t.angleBetween(a,s),u=Math.ceil(l/n),c=new Array(u);if(r===i){for(o=0;o<u;o++)c[o]=r;return c.push(i),c}var d=i-r,h=d/u;for(o=1;o<u;o++){var p=r+o*h;c[o]=p}return c[0]=r,c.push(i),c}function f(r,i,n,a){var s=new o(n,a),l=s.projectPointOntoPlane(t.add(n,r,L),L),u=s.projectPointOntoPlane(t.add(n,i,N),N),c=e.angleBetween(l,u);return u.x*l.y-u.y*l.x>=0?-c:c}function m(e,r,i,n,o,a,u,c){var h=z,p=G;F=d.eastNorthUpToFixedFrame(e,o,F),h=l.multiplyByPointAsVector(F,k,h),h=t.normalize(h,h);var m=f(h,r,e,o);U=s.fromRotationZ(m,U),W.z=a,F=l.multiplyTransformation(F,l.fromRotationTranslation(U,W,B),F);var g=V;g[0]=u;for(var _=0;_<c;_++)for(var v=0;v<i.length;v+=3)p=t.fromArray(i,v,p),p=s.multiplyByVector(g,p,p),p=l.multiplyByPoint(F,p,p),n.push(p.x,p.y,p.z);return n}function g(e,r,i,n,o,a,s){for(var l=0;l<e.length;l+=3){n=m(t.fromArray(e,l,H),r,i,n,o,a[l/3],s,1)}return n}function _(e,t){var r=e.length,i=new Array(6*r),n=0,o=t.x+t.width/2,a=t.y+t.height/2,s=e[0];i[n++]=s.x-o,i[n++]=0,i[n++]=s.y-a;for(var l=1;l<r;l++){s=e[l];var u=s.x-o,c=s.y-a;i[n++]=u,i[n++]=0,i[n++]=c,i[n++]=u,i[n++]=0,i[n++]=c}return s=e[0],i[n++]=s.x-o,i[n++]=0,i[n++]=s.y-a,i}function v(e,t){for(var r=e.length,i=new Array(3*r),n=0,o=t.x+t.width/2,a=t.y+t.height/2,s=0;s<r;s++)i[n++]=e[s].x-o,i[n++]=0,i[n++]=e[s].y-a;return i}function y(e,r,i,o,l,u,d,h,p,f){var g,_=t.angleBetween(t.subtract(r,e,I),t.subtract(i,e,O)),v=o===n.BEVELED?0:Math.ceil(_/a.toRadians(5));g=l?s.fromQuaternion(c.fromAxisAngle(t.negate(e,I),_/(v+1),j),Y):s.fromQuaternion(c.fromAxisAngle(e,_/(v+1),j),Y);var y,b;if(r=t.clone(r,q),v>0)for(var C=f?2:1,S=0;S<v;S++)r=s.multiplyByVector(g,r,r),y=t.subtract(r,e,I),y=t.normalize(y,y),l||(y=t.negate(y,y)),b=u.scaleToGeodeticSurface(r,O),d=m(b,y,h,d,u,p,1,C);else y=t.subtract(r,e,I),y=t.normalize(y,y),l||(y=t.negate(y,y)),b=u.scaleToGeodeticSurface(r,O),d=m(b,y,h,d,u,p,1,1),i=t.clone(i,q),y=t.subtract(i,e,I),y=t.normalize(y,y),l||(y=t.negate(y,y)),b=u.scaleToGeodeticSurface(i,O),d=m(b,y,h,d,u,p,1,1);return d}var b=[new t,new t],C=new t,S=new t,w=new t,T=new t,E=new t,A=new t,x=new t,P=new t,D=new t,I=new t,O=new t,M={},R=new i,L=new t,N=new t,k=new t(-1,0,0),F=new l,B=new l,U=new s,V=s.IDENTITY.clone(),z=new t,G=new r,W=new t,H=new t,j=new c,q=new t,Y=new s;M.removeDuplicatesFromShape=function(t){for(var r=t.length,i=[],n=r-1,o=0;o<r;n=o++){var a=t[n],s=t[o];e.equals(a,s)||i.push(s)}return i},M.angleIsGreaterThanPi=function(e,r,i,n){var a=new o(i,n),s=a.projectPointOntoPlane(t.add(i,e,L),L),l=a.projectPointOntoPlane(t.add(i,r,N),N);return l.x*s.y-l.y*s.x>=0};var X=new t,Q=new t;return M.computePositions=function(e,r,i,o,s){var l=o._ellipsoid,c=h(e,l),d=o._granularity,f=o._cornerType,O=s?_(r,i):v(r,i),R=s?v(r,i):void 0,L=i.height/2,N=i.width/2,k=e.length,F=[],B=s?[]:void 0,U=C,V=S,z=w,G=T,W=E,H=A,j=x,q=P,Y=D,Z=e[0],K=e[1];G=l.geodeticSurfaceNormal(Z,G),U=t.subtract(K,Z,U),U=t.normalize(U,U),q=t.cross(G,U,q),q=t.normalize(q,q);var J=c[0],$=c[1];s&&(B=m(Z,q,R,B,l,J+L,1,1)),Y=t.clone(Z,Y),Z=K,V=t.negate(U,V);for(var ee,te,re=1;re<k-1;re++){var ie=s?2:1;K=e[re+1],U=t.subtract(K,Z,U),U=t.normalize(U,U),z=t.add(U,V,z),z=t.normalize(z,z), +G=l.geodeticSurfaceNormal(Z,G);var ne=t.multiplyByScalar(G,t.dot(U,G),X);t.subtract(U,ne,ne),t.normalize(ne,ne);var oe=t.multiplyByScalar(G,t.dot(V,G),Q);t.subtract(V,oe,oe),t.normalize(oe,oe);if(!a.equalsEpsilon(Math.abs(t.dot(ne,oe)),1,a.EPSILON7)){z=t.cross(z,G,z),z=t.cross(G,z,z),z=t.normalize(z,z);var ae=1/Math.max(.25,t.magnitude(t.cross(z,V,I))),se=M.angleIsGreaterThanPi(U,V,Z,l);se?(W=t.add(Z,t.multiplyByScalar(z,ae*N,z),W),H=t.add(W,t.multiplyByScalar(q,N,H),H),b[0]=t.clone(Y,b[0]),b[1]=t.clone(H,b[1]),ee=p(b,J+L,$+L,d),te=u.generateArc({positions:b,granularity:d,ellipsoid:l}),F=g(te,q,O,F,l,ee,1),q=t.cross(G,U,q),q=t.normalize(q,q),j=t.add(W,t.multiplyByScalar(q,N,j),j),f===n.ROUNDED||f===n.BEVELED?y(W,H,j,f,se,l,F,O,$+L,s):(z=t.negate(z,z),F=m(Z,z,O,F,l,$+L,ae,ie)),Y=t.clone(j,Y)):(W=t.add(Z,t.multiplyByScalar(z,ae*N,z),W),H=t.add(W,t.multiplyByScalar(q,-N,H),H),b[0]=t.clone(Y,b[0]),b[1]=t.clone(H,b[1]),ee=p(b,J+L,$+L,d),te=u.generateArc({positions:b,granularity:d,ellipsoid:l}),F=g(te,q,O,F,l,ee,1),q=t.cross(G,U,q),q=t.normalize(q,q),j=t.add(W,t.multiplyByScalar(q,-N,j),j),f===n.ROUNDED||f===n.BEVELED?y(W,H,j,f,se,l,F,O,$+L,s):F=m(Z,z,O,F,l,$+L,ae,ie),Y=t.clone(j,Y)),V=t.negate(U,V)}else F=m(Y,q,O,F,l,J+L,1,1),Y=Z;J=$,$=c[re+1],Z=K}b[0]=t.clone(Y,b[0]),b[1]=t.clone(Z,b[1]),ee=p(b,J+L,$+L,d),te=u.generateArc({positions:b,granularity:d,ellipsoid:l}),F=g(te,q,O,F,l,ee,1),s&&(B=m(Z,q,R,B,l,$+L,1,1)),k=F.length;var le=s?k+B.length:k,ue=new Float64Array(le);return ue.set(F),s&&ue.set(B,k),ue},M}),define("Core/CorridorGeometryLibrary",["./Cartesian3","./CornerType","./defined","./Math","./Matrix3","./PolylinePipeline","./PolylineVolumeGeometryLibrary","./Quaternion"],function(e,t,r,i,n,o,a,s){"use strict";function l(r,o,a,l,u){var c=e.angleBetween(e.subtract(o,r,p),e.subtract(a,r,f)),d=l===t.BEVELED?1:Math.ceil(c/i.toRadians(5))+1,h=3*d,m=new Array(h);m[h-3]=a.x,m[h-2]=a.y,m[h-1]=a.z;var g;g=u?n.fromQuaternion(s.fromAxisAngle(e.negate(r,p),c/d,P),D):n.fromQuaternion(s.fromAxisAngle(r,c/d,P),D);var _=0;o=e.clone(o,p);for(var v=0;v<d;v++)o=n.multiplyByVector(g,o,o),m[_++]=o.x,m[_++]=o.y,m[_++]=o.z;return m}function u(r){var i=v,n=y,o=b,a=r[1];n=e.fromArray(r[1],a.length-3,n),o=e.fromArray(r[0],0,o),i=e.multiplyByScalar(e.add(n,o,i),.5,i);var s=l(i,n,o,t.ROUNDED,!1),u=r.length-1,c=r[u-1];return a=r[u],n=e.fromArray(c,c.length-3,n),o=e.fromArray(a,0,o),i=e.multiplyByScalar(e.add(n,o,i),.5,i),[s,l(i,n,o,t.ROUNDED,!1)]}function c(t,r,i,n){var o=p;return n?o=e.add(t,r,o):(r=e.negate(r,r),o=e.add(t,r,o)),[o.x,o.y,o.z,i.x,i.y,i.z]}function d(t,r,i,n){for(var o=new Array(t.length),a=new Array(t.length),s=e.multiplyByScalar(r,i,p),l=e.negate(s,f),u=0,c=t.length-1,d=0;d<t.length;d+=3){var h=e.fromArray(t,d,m),_=e.add(h,l,g);o[u++]=_.x,o[u++]=_.y,o[u++]=_.z;var v=e.add(h,s,g);a[c--]=v.z,a[c--]=v.y,a[c--]=v.x}return n.push(o,a),n}var h={},p=new e,f=new e,m=new e,g=new e,_=[new e,new e],v=new e,y=new e,b=new e,C=new e,S=new e,w=new e,T=new e,E=new e,A=new e,x=new e,P=new s,D=new n;h.addAttribute=function(e,t,i,n){var o=t.x,a=t.y,s=t.z;r(i)&&(e[i]=o,e[i+1]=a,e[i+2]=s),r(n)&&(e[n]=s,e[n-1]=a,e[n-2]=o)};var I=new e,O=new e;return h.computePositions=function(r){var n=r.granularity,s=r.positions,h=r.ellipsoid,f=r.width/2,m=r.cornerType,g=r.saveAttributes,P=v,D=y,M=b,R=C,L=S,N=w,k=T,F=E,B=A,U=x,V=[],z=g?[]:void 0,G=g?[]:void 0,W=s[0],H=s[1];D=e.normalize(e.subtract(H,W,D),D),P=h.geodeticSurfaceNormal(W,P),R=e.normalize(e.cross(P,D,R),R),g&&(z.push(R.x,R.y,R.z),G.push(P.x,P.y,P.z)),k=e.clone(W,k),W=H,M=e.negate(D,M);var j,q,Y=[],X=s.length;for(q=1;q<X-1;q++){P=h.geodeticSurfaceNormal(W,P),H=s[q+1],D=e.normalize(e.subtract(H,W,D),D),L=e.normalize(e.add(D,M,L),L);var Q=e.multiplyByScalar(P,e.dot(D,P),I);e.subtract(D,Q,Q),e.normalize(Q,Q);var Z=e.multiplyByScalar(P,e.dot(M,P),O);e.subtract(M,Z,Z),e.normalize(Z,Z);if(!i.equalsEpsilon(Math.abs(e.dot(Q,Z)),1,i.EPSILON7)){L=e.cross(L,P,L),L=e.cross(P,L,L),L=e.normalize(L,L);var K=f/Math.max(.25,e.magnitude(e.cross(L,M,p))),J=a.angleIsGreaterThanPi(D,M,W,h);L=e.multiplyByScalar(L,K,L),J?(F=e.add(W,L,F),U=e.add(F,e.multiplyByScalar(R,f,U),U),B=e.add(F,e.multiplyByScalar(R,2*f,B),B),_[0]=e.clone(k,_[0]),_[1]=e.clone(U,_[1]),j=o.generateArc({positions:_,granularity:n,ellipsoid:h}),V=d(j,R,f,V),g&&(z.push(R.x,R.y,R.z),G.push(P.x,P.y,P.z)),N=e.clone(B,N),R=e.normalize(e.cross(P,D,R),R),B=e.add(F,e.multiplyByScalar(R,2*f,B),B),k=e.add(F,e.multiplyByScalar(R,f,k),k),m===t.ROUNDED||m===t.BEVELED?Y.push({leftPositions:l(F,N,B,m,J)}):Y.push({leftPositions:c(W,e.negate(L,L),B,J)})):(B=e.add(W,L,B),U=e.add(B,e.negate(e.multiplyByScalar(R,f,U),U),U),F=e.add(B,e.negate(e.multiplyByScalar(R,2*f,F),F),F),_[0]=e.clone(k,_[0]),_[1]=e.clone(U,_[1]),j=o.generateArc({positions:_,granularity:n,ellipsoid:h}),V=d(j,R,f,V),g&&(z.push(R.x,R.y,R.z),G.push(P.x,P.y,P.z)),N=e.clone(F,N),R=e.normalize(e.cross(P,D,R),R),F=e.add(B,e.negate(e.multiplyByScalar(R,2*f,F),F),F),k=e.add(B,e.negate(e.multiplyByScalar(R,f,k),k),k),m===t.ROUNDED||m===t.BEVELED?Y.push({rightPositions:l(B,N,F,m,J)}):Y.push({rightPositions:c(W,L,F,J)})),M=e.negate(D,M)}W=H}P=h.geodeticSurfaceNormal(W,P),_[0]=e.clone(k,_[0]),_[1]=e.clone(W,_[1]),j=o.generateArc({positions:_,granularity:n,ellipsoid:h}),V=d(j,R,f,V),g&&(z.push(R.x,R.y,R.z),G.push(P.x,P.y,P.z));var $;return m===t.ROUNDED&&($=u(V)),{positions:V,corners:Y,lefts:z,normals:G,endPositions:$}},h}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,r,n){n=n||2;var o=r&&r.length,a=o?r[0]*n:e.length,s=t(e,0,a,n,!0),u=[];if(!s)return u;var c,d,h,p,f,m,g;if(o&&(s=l(e,r,s,n)),e.length>80*n){c=h=e[0],d=p=e[1];for(var _=n;_<a;_+=n)f=e[_],m=e[_+1],f<c&&(c=f),m<d&&(d=m),f>h&&(h=f),m>p&&(p=m);g=Math.max(h-c,p-d)}return i(s,u,n,c,d,g),u}function t(e,t,r,i,n){var o,a;if(n===P(e,t,r,i)>0)for(o=t;o<r;o+=i)a=E(o,e[o],e[o+1],a);else for(o=r-i;o>=t;o-=i)a=E(o,e[o],e[o+1],a);return a&&y(a,a.next)&&(A(a),a=a.next),a}function r(e,t){if(!e)return e;t||(t=e);var r,i=e;do{if(r=!1,i.steiner||!y(i,i.next)&&0!==v(i.prev,i,i.next))i=i.next;else{if(A(i),(i=t=i.prev)===i.next)return null;r=!0}}while(r||i!==t);return t}function i(e,t,l,u,c,d,p){if(e){!p&&d&&h(e,u,c,d);for(var f,m,g=e;e.prev!==e.next;)if(f=e.prev,m=e.next,d?o(e,u,c,d):n(e))t.push(f.i/l),t.push(e.i/l),t.push(m.i/l),A(e),e=m.next,g=m.next;else if((e=m)===g){p?1===p?(e=a(e,t,l),i(e,t,l,u,c,d,2)):2===p&&s(e,t,l,u,c,d):i(r(e),t,l,u,c,d,1);break}}}function n(e){var t=e.prev,r=e,i=e.next;if(v(t,r,i)>=0)return!1;for(var n=e.next.next;n!==e.prev;){if(g(t.x,t.y,r.x,r.y,i.x,i.y,n.x,n.y)&&v(n.prev,n,n.next)>=0)return!1;n=n.next}return!0}function o(e,t,r,i){var n=e.prev,o=e,a=e.next;if(v(n,o,a)>=0)return!1;for(var s=n.x<o.x?n.x<a.x?n.x:a.x:o.x<a.x?o.x:a.x,l=n.y<o.y?n.y<a.y?n.y:a.y:o.y<a.y?o.y:a.y,u=n.x>o.x?n.x>a.x?n.x:a.x:o.x>a.x?o.x:a.x,c=n.y>o.y?n.y>a.y?n.y:a.y:o.y>a.y?o.y:a.y,d=f(s,l,t,r,i),h=f(u,c,t,r,i),p=e.nextZ;p&&p.z<=h;){if(p!==e.prev&&p!==e.next&&g(n.x,n.y,o.x,o.y,a.x,a.y,p.x,p.y)&&v(p.prev,p,p.next)>=0)return!1;p=p.nextZ}for(p=e.prevZ;p&&p.z>=d;){if(p!==e.prev&&p!==e.next&&g(n.x,n.y,o.x,o.y,a.x,a.y,p.x,p.y)&&v(p.prev,p,p.next)>=0)return!1;p=p.prevZ}return!0}function a(e,t,r){var i=e;do{var n=i.prev,o=i.next.next;!y(n,o)&&b(n,i,i.next,o)&&S(n,o)&&S(o,n)&&(t.push(n.i/r),t.push(i.i/r),t.push(o.i/r),A(i),A(i.next),i=e=o),i=i.next}while(i!==e);return i}function s(e,t,n,o,a,s){var l=e;do{for(var u=l.next.next;u!==l.prev;){if(l.i!==u.i&&_(l,u)){var c=T(l,u);return l=r(l,l.next),c=r(c,c.next),i(l,t,n,o,a,s),void i(c,t,n,o,a,s)}u=u.next}l=l.next}while(l!==e)}function l(e,i,n,o){var a,s,l,d,h,p=[];for(a=0,s=i.length;a<s;a++)l=i[a]*o,d=a<s-1?i[a+1]*o:e.length,h=t(e,l,d,o,!1),h===h.next&&(h.steiner=!0),p.push(m(h));for(p.sort(u),a=0;a<p.length;a++)c(p[a],n),n=r(n,n.next);return n}function u(e,t){return e.x-t.x}function c(e,t){if(t=d(e,t)){var i=T(t,e);r(i,i.next)}}function d(e,t){var r,i=t,n=e.x,o=e.y,a=-1/0;do{if(o<=i.y&&o>=i.next.y){var s=i.x+(o-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(s<=n&&s>a){if(a=s,s===n){if(o===i.y)return i;if(o===i.next.y)return i.next}r=i.x<i.next.x?i:i.next}}i=i.next}while(i!==t);if(!r)return null;if(n===a)return r.prev;var l,u=r,c=r.x,d=r.y,h=1/0;for(i=r.next;i!==u;)n>=i.x&&i.x>=c&&g(o<d?n:a,o,c,d,o<d?a:n,o,i.x,i.y)&&((l=Math.abs(o-i.y)/(n-i.x))<h||l===h&&i.x>r.x)&&S(i,e)&&(r=i,h=l),i=i.next;return r}function h(e,t,r,i){var n=e;do{null===n.z&&(n.z=f(n.x,n.y,t,r,i)),n.prevZ=n.prev,n.nextZ=n.next,n=n.next}while(n!==e);n.prevZ.nextZ=null,n.prevZ=null,p(n)}function p(e){var t,r,i,n,o,a,s,l,u=1;do{for(r=e,e=null,o=null,a=0;r;){for(a++,i=r,s=0,t=0;t<u&&(s++,i=i.nextZ);t++);for(l=u;s>0||l>0&&i;)0===s?(n=i,i=i.nextZ,l--):0!==l&&i?r.z<=i.z?(n=r,r=r.nextZ,s--):(n=i,i=i.nextZ,l--):(n=r,r=r.nextZ,s--),o?o.nextZ=n:e=n,n.prevZ=o,o=n;r=i}o.nextZ=null,u*=2}while(a>1);return e}function f(e,t,r,i,n){return e=32767*(e-r)/n,t=32767*(t-i)/n,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,r=e;do{t.x<r.x&&(r=t),t=t.next}while(t!==e);return r}function g(e,t,r,i,n,o,a,s){return(n-a)*(t-s)-(e-a)*(o-s)>=0&&(e-a)*(i-s)-(r-a)*(t-s)>=0&&(r-a)*(o-s)-(n-a)*(i-s)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!C(e,t)&&S(e,t)&&S(t,e)&&w(e,t)}function v(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function y(e,t){return e.x===t.x&&e.y===t.y}function b(e,t,r,i){return!!(y(e,t)&&y(r,i)||y(e,i)&&y(r,t))||v(e,t,r)>0!=v(e,t,i)>0&&v(r,i,e)>0!=v(r,i,t)>0}function C(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&b(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function S(e,t){return v(e.prev,e,e.next)<0?v(e,t,e.next)>=0&&v(e,e.prev,t)>=0:v(e,t,e.prev)<0||v(e,e.next,t)<0}function w(e,t){var r=e,i=!1,n=(e.x+t.x)/2,o=(e.y+t.y)/2;do{r.y>o!=r.next.y>o&&n<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(i=!i),r=r.next}while(r!==e);return i}function T(e,t){var r=new x(e.i,e.x,e.y),i=new x(t.i,t.x,t.y),n=e.next,o=t.prev;return e.next=t,t.prev=e,r.next=n,n.prev=r,i.next=r,r.prev=i,o.next=i,i.prev=o,i}function E(e,t,r,i){var n=new x(e,t,r);return i?(n.next=i.next,n.prev=i,i.next.prev=n,i.next=n):(n.prev=n,n.next=n),n}function A(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function x(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function P(e,t,r,i){for(var n=0,o=t,a=r-i;o<r;o+=i)n+=(e[a]-e[o])*(e[o+1]+e[a+1]),a=o;return n}return e.deviation=function(e,t,r,i){var n=t&&t.length,o=n?t[0]*r:e.length,a=Math.abs(P(e,0,o,r));if(n)for(var s=0,l=t.length;s<l;s++){var u=t[s]*r,c=s<l-1?t[s+1]*r:e.length;a-=Math.abs(P(e,u,c,r))}var d=0;for(s=0;s<i.length;s+=3){var h=i[s]*r,p=i[s+1]*r,f=i[s+2]*r;d+=Math.abs((e[h]-e[f])*(e[p+1]-e[h+1])-(e[h]-e[p])*(e[f+1]-e[h+1]))}return 0===a&&0===d?0:Math.abs((d-a)/a)},e.flatten=function(e){for(var t=e[0][0].length,r={vertices:[],holes:[],dimensions:t},i=0,n=0;n<e.length;n++){for(var o=0;o<e[n].length;o++)for(var a=0;a<t;a++)r.vertices.push(e[n][o][a]);n>0&&(i+=e[n-1].length,r.holes.push(i))}return r},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===r.CLOCKWISE||e===r.COUNTER_CLOCKWISE}};return e(r)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";var p=new r,f=new r,m={};m.computeArea2D=function(e){for(var t=e.length,r=0,i=t-1,n=0;n<t;i=n++){var o=e[i],a=e[n];r+=o.x*a.y-a.x*o.y}return.5*r},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(r,i){var n=t.packArray(r);return e(n,i,2)};var g=new r,_=new r,v=new r,y=new r,b=new r,C=new r,S=new r;return m.computeSubdivision=function(e,t,i,s){s=o(s,c.RADIANS_PER_DEGREE);var h,p=i.slice(0),f=t.length,m=new Array(3*f),w=0;for(h=0;h<f;h++){var T=t[h];m[w++]=T.x,m[w++]=T.y,m[w++]=T.z}for(var E=[],A={},x=e.maximumRadius,P=c.chordLength(s,x),D=P*P;p.length>0;){var I,O,M=p.pop(),R=p.pop(),L=p.pop(),N=r.fromArray(m,3*L,g),k=r.fromArray(m,3*R,_),F=r.fromArray(m,3*M,v),B=r.multiplyByScalar(r.normalize(N,y),x,y),U=r.multiplyByScalar(r.normalize(k,b),x,b),V=r.multiplyByScalar(r.normalize(F,C),x,C),z=r.magnitudeSquared(r.subtract(B,U,S)),G=r.magnitudeSquared(r.subtract(U,V,S)),W=r.magnitudeSquared(r.subtract(V,B,S)),H=Math.max(z,G,W);H>D?z===H?(I=Math.min(L,R)+" "+Math.max(L,R),h=A[I],a(h)||(O=r.add(N,k,S),r.multiplyByScalar(O,.5,O),m.push(O.x,O.y,O.z),h=m.length/3-1,A[I]=h),p.push(L,h,M),p.push(h,R,M)):G===H?(I=Math.min(R,M)+" "+Math.max(R,M),h=A[I],a(h)||(O=r.add(k,F,S),r.multiplyByScalar(O,.5,O),m.push(O.x,O.y,O.z),h=m.length/3-1,A[I]=h),p.push(R,h,L),p.push(h,M,L)):W===H&&(I=Math.min(M,L)+" "+Math.max(M,L),h=A[I],a(h)||(O=r.add(F,N,S),r.multiplyByScalar(O,.5,O),m.push(O.x,O.y,O.z),h=m.length/3-1,A[I]=h),p.push(M,h,R),p.push(h,L,R)):(E.push(L),E.push(R),E.push(M))}return new l({attributes:{position:new u({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:m})},indices:E,primitiveType:d.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,i,n){i=o(i,s.WGS84);var l=p,u=f;if(t=o(t,0),n=o(n,!0),a(e))for(var c=e.length,d=0;d<c;d+=3)r.fromArray(e,d,u),n&&(u=i.scaleToGeodeticSurface(u,u)),0!==t&&(l=i.geodeticSurfaceNormal(u,l),r.multiplyByScalar(l,t,l),r.add(u,l,u)),e[d]=u.x,e[d+1]=u.y,e[d+2]=u.z;return e},m}),define("Core/CorridorGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Cartographic","./ComponentDatatype","./CornerType","./CorridorGeometryLibrary","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Rectangle","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b){"use strict";function C(e,t){for(var r=0;r<e.length;r++)e[r]=t.scaleToGeodeticSurface(e[r],e[r]);return e}function S(e,t,i,n,o,s){var l=e.normals,u=e.tangents,c=e.bitangents,d=r.normalize(r.cross(i,t,k),k);s.normal&&a.addAttribute(l,t,n,o),s.tangent&&a.addAttribute(u,d,n,o),s.bitangent&&a.addAttribute(c,i,n,o)}function w(e,t,i){var o,s,u,c=e.positions,d=e.corners,h=e.endPositions,_=e.lefts,v=e.normals,y=new f,b=0,C=0,w=0;for(s=0;s<c.length;s+=2)u=c[s].length-3,b+=u,w+=2*u,C+=c[s+1].length-3;for(b+=3,C+=3,s=0;s<d.length;s++){o=d[s];var T=d[s].leftPositions;l(T)?(u=T.length,b+=u,w+=u):(u=d[s].rightPositions.length,C+=u,w+=u)}var E,A=l(h);A&&(E=h[0].length-3,b+=E,C+=E,E/=3,w+=6*E);var x,P,D,L,B,U,V=b+C,z=new Float64Array(V),G=t.normal?new Float32Array(V):void 0,W=t.tangent?new Float32Array(V):void 0,H=t.bitangent?new Float32Array(V):void 0,j={normals:G,tangents:W,bitangents:H},q=0,Y=V-1,X=I,Q=O,Z=E/2,K=m.createTypedArray(V/3,w),J=0;if(A){U=M,B=R;var $=h[0];for(X=r.fromArray(v,0,X),Q=r.fromArray(_,0,Q),s=0;s<Z;s++)U=r.fromArray($,3*(Z-1-s),U),B=r.fromArray($,3*(Z+s),B),a.addAttribute(z,B,q),a.addAttribute(z,U,void 0,Y),S(j,X,Q,q,Y,t),P=q/3,L=P+1,x=(Y-2)/3,D=x-1,K[J++]=x,K[J++]=P,K[J++]=D,K[J++]=D,K[J++]=P,K[J++]=L,q+=3,Y-=3}var ee=0,te=0,re=c[ee++],ie=c[ee++];z.set(re,q),z.set(ie,Y-ie.length+1),Q=r.fromArray(_,te,Q);var ne,oe;for(u=ie.length-3,s=0;s<u;s+=3)ne=i.geodeticSurfaceNormal(r.fromArray(re,s,k),k),oe=i.geodeticSurfaceNormal(r.fromArray(ie,u-s,F),F),X=r.normalize(r.add(ne,oe,X),X),S(j,X,Q,q,Y,t),P=q/3,L=P+1,x=(Y-2)/3,D=x-1,K[J++]=x,K[J++]=P,K[J++]=D,K[J++]=D,K[J++]=P,K[J++]=L,q+=3,Y-=3;for(ne=i.geodeticSurfaceNormal(r.fromArray(re,u,k),k),oe=i.geodeticSurfaceNormal(r.fromArray(ie,u,F),F),X=r.normalize(r.add(ne,oe,X),X),te+=3,s=0;s<d.length;s++){var ae;o=d[s];var se,le,ue=o.leftPositions,ce=o.rightPositions,de=N,he=M,pe=R;if(X=r.fromArray(v,te,X),l(ue)){for(S(j,X,Q,void 0,Y,t),Y-=3,se=L,le=D,ae=0;ae<ue.length/3;ae++)de=r.fromArray(ue,3*ae,de),K[J++]=se,K[J++]=le-ae-1,K[J++]=le-ae,a.addAttribute(z,de,void 0,Y),he=r.fromArray(z,3*(le-ae-1),he),pe=r.fromArray(z,3*se,pe),Q=r.normalize(r.subtract(he,pe,Q),Q),S(j,X,Q,void 0,Y,t),Y-=3;de=r.fromArray(z,3*se,de),he=r.subtract(r.fromArray(z,3*le,he),de,he),pe=r.subtract(r.fromArray(z,3*(le-ae),pe),de,pe),Q=r.normalize(r.add(he,pe,Q),Q),S(j,X,Q,q,void 0,t),q+=3}else{for(S(j,X,Q,q,void 0,t),q+=3,se=D,le=L,ae=0;ae<ce.length/3;ae++)de=r.fromArray(ce,3*ae,de),K[J++]=se,K[J++]=le+ae,K[J++]=le+ae+1,a.addAttribute(z,de,q),he=r.fromArray(z,3*se,he),pe=r.fromArray(z,3*(le+ae),pe),Q=r.normalize(r.subtract(he,pe,Q),Q),S(j,X,Q,q,void 0,t),q+=3;de=r.fromArray(z,3*se,de),he=r.subtract(r.fromArray(z,3*(le+ae),he),de,he),pe=r.subtract(r.fromArray(z,3*le,pe),de,pe),Q=r.normalize(r.negate(r.add(pe,he,Q),Q),Q),S(j,X,Q,void 0,Y,t),Y-=3}for(re=c[ee++],ie=c[ee++],re.splice(0,3),ie.splice(ie.length-3,3),z.set(re,q),z.set(ie,Y-ie.length+1),u=ie.length-3,te+=3,Q=r.fromArray(_,te,Q),ae=0;ae<ie.length;ae+=3)ne=i.geodeticSurfaceNormal(r.fromArray(re,ae,k),k),oe=i.geodeticSurfaceNormal(r.fromArray(ie,u-ae,F),F),X=r.normalize(r.add(ne,oe,X),X),S(j,X,Q,q,Y,t),L=q/3,P=L-1,D=(Y-2)/3,x=D+1,K[J++]=x,K[J++]=P,K[J++]=D,K[J++]=D,K[J++]=P,K[J++]=L,q+=3,Y-=3;q-=3,Y+=3}if(X=r.fromArray(v,v.length-3,X),S(j,X,Q,q,Y,t),A){q+=3,Y-=3,U=M,B=R;var fe=h[1];for(s=0;s<Z;s++)U=r.fromArray(fe,3*(E-s-1),U),B=r.fromArray(fe,3*s,B),a.addAttribute(z,U,void 0,Y),a.addAttribute(z,B,q),S(j,X,Q,q,Y,t),L=q/3,P=L-1,D=(Y-2)/3,x=D+1,K[J++]=x,K[J++]=P,K[J++]=D,K[J++]=D,K[J++]=P,K[J++]=L,q+=3,Y-=3}if(y.position=new p({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:z}),t.st){var me,ge,_e=new Float32Array(V/3*2),ve=0;if(A){b/=3,C/=3;var ye=Math.PI/(E+1);ge=1/(b-E+1),me=1/(C-E+1);var be,Ce=E/2;for(s=Ce+1;s<E+1;s++)be=g.PI_OVER_TWO+ye*s,_e[ve++]=me*(1+Math.cos(be)),_e[ve++]=.5*(1+Math.sin(be));for(s=1;s<C-E+1;s++)_e[ve++]=s*me,_e[ve++]=0;for(s=E;s>Ce;s--)be=g.PI_OVER_TWO-s*ye,_e[ve++]=1-me*(1+Math.cos(be)),_e[ve++]=.5*(1+Math.sin(be));for(s=Ce;s>0;s--)be=g.PI_OVER_TWO-ye*s,_e[ve++]=1-ge*(1+Math.cos(be)),_e[ve++]=.5*(1+Math.sin(be));for(s=b-E;s>0;s--)_e[ve++]=s*ge,_e[ve++]=1;for(s=1;s<Ce+1;s++)be=g.PI_OVER_TWO+ye*s,_e[ve++]=ge*(1+Math.cos(be)),_e[ve++]=.5*(1+Math.sin(be))}else{for(b/=3,C/=3,ge=1/(b-1),me=1/(C-1),s=0;s<C;s++)_e[ve++]=s*me,_e[ve++]=0;for(s=b;s>0;s--)_e[ve++]=(s-1)*ge,_e[ve++]=1}y.st=new p({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:_e})}return t.normal&&(y.normal=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:j.normals})),t.tangent&&(y.tangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:j.tangents})),t.bitangent&&(y.bitangent=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:j.bitangents})),{attributes:y,indices:K}}function T(e,t){if(!(t.normal||t.tangent||t.bitangent||t.st))return e;var i,n,o=e.position.values;(t.normal||t.bitangent)&&(i=e.normal.values,n=e.bitangent.values);var s,l=e.position.values.length/18,u=3*l,c=2*l,d=2*u;if(t.normal||t.bitangent||t.tangent){var h=t.normal?new Float32Array(6*u):void 0,p=t.tangent?new Float32Array(6*u):void 0,f=t.bitangent?new Float32Array(6*u):void 0,m=I,g=O,_=M,v=R,y=L,b=N,C=d;for(s=0;s<u;s+=3){var S=C+d;m=r.fromArray(o,s,m),g=r.fromArray(o,s+u,g),_=r.fromArray(o,(s+3)%u,_),g=r.subtract(g,m,g),_=r.subtract(_,m,_),v=r.normalize(r.cross(g,_,v),v),t.normal&&(a.addAttribute(h,v,S),a.addAttribute(h,v,S+3),a.addAttribute(h,v,C),a.addAttribute(h,v,C+3)),(t.tangent||t.bitangent)&&(b=r.fromArray(i,s,b),t.bitangent&&(a.addAttribute(f,b,S),a.addAttribute(f,b,S+3),a.addAttribute(f,b,C),a.addAttribute(f,b,C+3)),t.tangent&&(y=r.normalize(r.cross(b,v,y),y),a.addAttribute(p,y,S),a.addAttribute(p,y,S+3),a.addAttribute(p,y,C),a.addAttribute(p,y,C+3))),C+=6}if(t.normal){for(h.set(i),s=0;s<u;s+=3)h[s+u]=-i[s],h[s+u+1]=-i[s+1],h[s+u+2]=-i[s+2];e.normal.values=h}else e.normal=void 0;if(t.bitangent?(f.set(n),f.set(n,u),e.bitangent.values=f):e.bitangent=void 0,t.tangent){var w=e.tangent.values;p.set(w),p.set(w,u),e.tangent.values=p}}if(t.st){var T=e.st.values,E=new Float32Array(6*c);E.set(T),E.set(T,c);for(var A=2*c,x=0;x<2;x++){for(E[A++]=T[0],E[A++]=T[1],s=2;s<c;s+=2){var P=T[s],D=T[s+1];E[A++]=P,E[A++]=D,E[A++]=P,E[A++]=D}E[A++]=T[0],E[A++]=T[1]}e.st.values=E}return e}function E(e,t,r){r[t++]=e[0],r[t++]=e[1],r[t++]=e[2];for(var i=3;i<e.length;i+=3){var n=e[i],o=e[i+1],a=e[i+2];r[t++]=n,r[t++]=o,r[t++]=a,r[t++]=n,r[t++]=o,r[t++]=a}return r[t++]=e[0],r[t++]=e[1],r[t++]=e[2],r}function A(e,t){var r=new b({position:t.position,normal:t.normal||t.bitangent||e.shadowVolume,tangent:t.tangent,bitangent:t.normal||t.bitangent,st:t.st}),i=e.ellipsoid,o=a.computePositions(e),s=w(o,r,i),l=e.height,u=e.extrudedHeight,c=s.attributes,d=s.indices,h=c.position.values,f=h.length,g=new Float64Array(6*f),v=new Float64Array(f);v.set(h);var y=new Float64Array(4*f);h=_.scaleToGeodeticHeight(h,l,i),y=E(h,0,y),v=_.scaleToGeodeticHeight(v,u,i),y=E(v,2*f,y),g.set(h),g.set(v,f),g.set(y,2*f),c.position.values=g,c=T(c,t);var C,S=f/3;if(e.shadowVolume){var A=c.normal.values;f=A.length;var x=new Float32Array(6*f);for(C=0;C<f;C++)A[C]=-A[C];x.set(A,f),x=E(A,4*f,x),c.extrudeDirection=new p({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:x}),t.normal||(c.normal=void 0)}var P=d.length,D=S+S,I=m.createTypedArray(g.length/3,2*P+3*D);I.set(d);var O=P;for(C=0;C<P;C+=3){var M=d[C],R=d[C+1],L=d[C+2];I[O++]=L+S,I[O++]=R+S,I[O++]=M+S}var N,k,F,B;for(C=0;C<D;C+=2)N=C+D,k=N+D,F=N+1,B=k+1,I[O++]=N,I[O++]=k,I[O++]=F,I[O++]=F,I[O++]=k,I[O++]=B;return{attributes:c,indices:I}}function x(e,t,i,n,o,a){var s=r.subtract(t,e,B);r.normalize(s,s);var l=i.geodeticSurfaceNormal(e,U),u=r.cross(s,l,B);r.multiplyByScalar(u,n,u);var c=o.latitude,d=o.longitude,h=a.latitude,p=a.longitude;r.add(e,u,U),i.cartesianToCartographic(U,V);var f=V.latitude,m=V.longitude;c=Math.min(c,f),d=Math.min(d,m),h=Math.max(h,f),p=Math.max(p,m),r.subtract(e,u,U),i.cartesianToCartographic(U,V),f=V.latitude,m=V.longitude,c=Math.min(c,f),d=Math.min(d,m),h=Math.max(h,f),p=Math.max(p,m),o.latitude=c,o.longitude=d,a.latitude=h,a.longitude=p}function P(t,i,n,a){t=C(t,i);var s=e(t,r.equalsEpsilon),l=s.length;if(l<2||n<=0)return new y;var u=.5*n;W.latitude=Number.POSITIVE_INFINITY,W.longitude=Number.POSITIVE_INFINITY,H.latitude=Number.NEGATIVE_INFINITY,H.longitude=Number.NEGATIVE_INFINITY;var c,d;if(a===o.ROUNDED){var h=s[0];r.subtract(h,s[1],z),r.normalize(z,z),r.multiplyByScalar(z,u,z),r.add(h,z,G),i.cartesianToCartographic(G,V),c=V.latitude,d=V.longitude,W.latitude=Math.min(W.latitude,c),W.longitude=Math.min(W.longitude,d),H.latitude=Math.max(H.latitude,c),H.longitude=Math.max(H.longitude,d)}for(var p=0;p<l-1;++p)x(s[p],s[p+1],i,u,W,H);var f=s[l-1];r.subtract(f,s[l-2],z),r.normalize(z,z),r.multiplyByScalar(z,u,z),r.add(f,z,G),x(f,G,i,u,W,H),a===o.ROUNDED&&(i.cartesianToCartographic(G,V),c=V.latitude,d=V.longitude,W.latitude=Math.min(W.latitude,c),W.longitude=Math.min(W.longitude,d),H.latitude=Math.max(H.latitude,c),H.longitude=Math.max(H.longitude,d));var m=new y;return m.north=H.latitude,m.south=W.latitude,m.east=H.longitude,m.west=W.longitude,m}function D(e){e=s(e,s.EMPTY_OBJECT);var t=e.positions,i=e.width;this._positions=t,this._ellipsoid=d.clone(s(e.ellipsoid,d.WGS84)),this._vertexFormat=b.clone(s(e.vertexFormat,b.DEFAULT)),this._width=i,this._height=s(e.height,0),this._extrudedHeight=s(e.extrudedHeight,this._height),this._cornerType=s(e.cornerType,o.ROUNDED),this._granularity=s(e.granularity,g.RADIANS_PER_DEGREE),this._shadowVolume=s(e.shadowVolume,!1),this._workerName="createCorridorGeometry",this._rectangle=P(t,this._ellipsoid,i,this._cornerType),this.packedLength=1+t.length*r.packedLength+d.packedLength+b.packedLength+y.packedLength+6}var I=new r,O=new r,M=new r,R=new r,L=new r,N=new r,k=new r,F=new r,B=new r,U=new r,V=new i,z=new r,G=new r,W=new i,H=new i;D.pack=function(e,t,i){i=s(i,0);var n=e._positions,o=n.length;t[i++]=o;for(var a=0;a<o;++a,i+=r.packedLength)r.pack(n[a],t,i);return d.pack(e._ellipsoid,t,i),i+=d.packedLength,b.pack(e._vertexFormat,t,i),i+=b.packedLength,y.pack(e._rectangle,t,i),i+=y.packedLength,t[i++]=e._width,t[i++]=e._height,t[i++]=e._extrudedHeight,t[i++]=e._cornerType,t[i++]=e._granularity,t[i]=e._shadowVolume?1:0,t};var j=d.clone(d.UNIT_SPHERE),q=new b,Y=new y,X={positions:void 0,ellipsoid:j,vertexFormat:q,width:void 0,height:void 0,extrudedHeight:void 0,cornerType:void 0,granularity:void 0,shadowVolume:void 0};return D.unpack=function(e,t,i){t=s(t,0);for(var n=e[t++],o=new Array(n),a=0;a<n;++a,t+=r.packedLength)o[a]=r.unpack(e,t);var u=d.unpack(e,t,j);t+=d.packedLength;var c=b.unpack(e,t,q);t+=b.packedLength;var h=y.unpack(e,t,Y);t+=y.packedLength;var p=e[t++],f=e[t++],m=e[t++],g=e[t++],_=e[t++],v=1===e[t];return l(i)?(i._positions=o,i._ellipsoid=d.clone(u,i._ellipsoid),i._vertexFormat=b.clone(c,i._vertexFormat),i._width=p,i._height=f,i._extrudedHeight=m,i._cornerType=g,i._granularity=_,i._rectangle=y.clone(h),i._shadowVolume=v,i):(X.positions=o,X.width=p,X.height=f,X.extrudedHeight=m,X.cornerType=g,X.granularity=_,X.shadowVolume=v,new D(X))},D.createGeometry=function(i){var n=i._positions,o=i._height,s=i._width,l=i._extrudedHeight,u=o!==l,c=i._ellipsoid;n=C(n,c);var d=e(n,r.equalsEpsilon);if(!(d.length<2||s<=0)){var p,f=i._vertexFormat,m={ellipsoid:c,positions:d,width:s,cornerType:i._cornerType,granularity:i._granularity,saveAttributes:!0};if(u){var g=Math.max(o,l);l=Math.min(o,l),o=g,m.height=o,m.extrudedHeight=l,m.shadowVolume=i._shadowVolume,p=A(m,f)}else{p=w(a.computePositions(m),f,c),p.attributes.position.values=_.scaleToGeodeticHeight(p.attributes.position.values,o,c)}var y=p.attributes,b=t.fromVertices(y.position.values,void 0,3);return f.position||(p.attributes.position.values=void 0),new h({attributes:y,indices:p.indices,primitiveType:v.TRIANGLES,boundingSphere:b})}},D.createShadowVolume=function(e,t,r){var i=e._granularity,n=e._ellipsoid,o=t(i,n),a=r(i,n);return new D({positions:e._positions,width:e._width,cornerType:e._cornerType,ellipsoid:n,granularity:i,extrudedHeight:o,height:a,vertexFormat:b.POSITION_ONLY,shadowVolume:!0})},u(D.prototype,{rectangle:{get:function(){return this._rectangle}}}),D}),define("Core/CorridorOutlineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./CornerType","./CorridorGeometryLibrary","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e,t){for(var r=0;r<e.length;r++)e[r]=t.scaleToGeodeticSurface(e[r],e[r]);return e}function v(e,t){var i,s,u,c=[],f=e.positions,m=e.corners,g=e.endPositions,_=new h,v=0,y=0,b=0;for(s=0;s<f.length;s+=2)u=f[s].length-3,v+=u,b+=u/3*4,y+=f[s+1].length-3;for(v+=3,y+=3,s=0;s<m.length;s++){i=m[s];var T=m[s].leftPositions;l(T)?(u=T.length,v+=u,b+=u/3*2):(u=m[s].rightPositions.length,y+=u,b+=u/3*2)}var E,A=l(g);A&&(E=g[0].length-3,v+=E,y+=E,E/=3,b+=4*E);var x,P,D,I,O,M,R=v+y,L=new Float64Array(R),N=0,k=R-1,F=E/2,B=p.createTypedArray(R/3,b+4),U=0;if(B[U++]=N/3,B[U++]=(k-2)/3,A){c.push(N/3),M=C,O=S;var V=g[0];for(s=0;s<F;s++)M=r.fromArray(V,3*(F-1-s),M),O=r.fromArray(V,3*(F+s),O),a.addAttribute(L,O,N),a.addAttribute(L,M,void 0,k),P=N/3,I=P+1,x=(k-2)/3,D=x-1,B[U++]=x,B[U++]=D,B[U++]=P,B[U++]=I,N+=3,k-=3}var z=0,G=f[z++],W=f[z++];for(L.set(G,N),L.set(W,k-W.length+1),u=W.length-3,c.push(N/3,(k-2)/3),s=0;s<u;s+=3)P=N/3,I=P+1,x=(k-2)/3,D=x-1,B[U++]=x,B[U++]=D,B[U++]=P,B[U++]=I,N+=3,k-=3;for(s=0;s<m.length;s++){var H;i=m[s];var j,q=i.leftPositions,Y=i.rightPositions,X=w;if(l(q)){for(k-=3,j=D,c.push(I),H=0;H<q.length/3;H++)X=r.fromArray(q,3*H,X),B[U++]=j-H-1,B[U++]=j-H,a.addAttribute(L,X,void 0,k),k-=3;c.push(j-Math.floor(q.length/6)),t===o.BEVELED&&c.push((k-2)/3+1),N+=3}else{for(N+=3,j=I,c.push(D),H=0;H<Y.length/3;H++)X=r.fromArray(Y,3*H,X),B[U++]=j+H,B[U++]=j+H+1,a.addAttribute(L,X,N),N+=3;c.push(j+Math.floor(Y.length/6)),t===o.BEVELED&&c.push(N/3-1),k-=3}for(G=f[z++],W=f[z++],G.splice(0,3),W.splice(W.length-3,3),L.set(G,N),L.set(W,k-W.length+1),u=W.length-3,H=0;H<W.length;H+=3)I=N/3,P=I-1,D=(k-2)/3,x=D+1,B[U++]=x,B[U++]=D,B[U++]=P,B[U++]=I,N+=3,k-=3;N-=3,k+=3,c.push(N/3,(k-2)/3)}if(A){N+=3,k-=3,M=C,O=S;var Q=g[1];for(s=0;s<F;s++)M=r.fromArray(Q,3*(E-s-1),M),O=r.fromArray(Q,3*s,O),a.addAttribute(L,M,void 0,k),a.addAttribute(L,O,N),I=N/3,P=I-1,D=(k-2)/3,x=D+1,B[U++]=x,B[U++]=D,B[U++]=P,B[U++]=I,N+=3,k-=3;c.push(N/3)}else c.push(N/3,(k-2)/3);return B[U++]=N/3,B[U++]=(k-2)/3,_.position=new d({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:L}),{attributes:_,indices:B,wallIndices:c}}function y(e){var t=e.ellipsoid,r=a.computePositions(e),i=v(r,e.cornerType),n=i.wallIndices,o=e.height,s=e.extrudedHeight,l=i.attributes,u=i.indices,c=l.position.values,d=c.length,h=new Float64Array(d);h.set(c);var f=new Float64Array(2*d);c=m.scaleToGeodeticHeight(c,o,t),h=m.scaleToGeodeticHeight(h,s,t),f.set(c),f.set(h,d),l.position.values=f,d/=3;var g,_=u.length,y=p.createTypedArray(f.length/3,2*(_+n.length));y.set(u);var b=_;for(g=0;g<_;g+=2){var C=u[g],S=u[g+1];y[b++]=C+d,y[b++]=S+d}var w,T;for(g=0;g<n.length;g++)w=n[g],T=w+d,y[b++]=w,y[b++]=T;return{attributes:l,indices:y}}function b(e){e=s(e,s.EMPTY_OBJECT);var t=e.positions,i=e.width;this._positions=t,this._ellipsoid=u.clone(s(e.ellipsoid,u.WGS84)),this._width=i,this._height=s(e.height,0),this._extrudedHeight=s(e.extrudedHeight,this._height),this._cornerType=s(e.cornerType,o.ROUNDED),this._granularity=s(e.granularity,f.RADIANS_PER_DEGREE),this._workerName="createCorridorOutlineGeometry",this.packedLength=1+t.length*r.packedLength+u.packedLength+5}var C=new r,S=new r,w=new r;b.pack=function(e,t,i){i=s(i,0);var n=e._positions,o=n.length;t[i++]=o;for(var a=0;a<o;++a,i+=r.packedLength)r.pack(n[a],t,i);return u.pack(e._ellipsoid,t,i),i+=u.packedLength,t[i++]=e._width,t[i++]=e._height,t[i++]=e._extrudedHeight,t[i++]=e._cornerType,t[i]=e._granularity,t};var T=u.clone(u.UNIT_SPHERE),E={positions:void 0,ellipsoid:T,width:void 0,height:void 0,extrudedHeight:void 0,cornerType:void 0,granularity:void 0};return b.unpack=function(e,t,i){t=s(t,0);for(var n=e[t++],o=new Array(n),a=0;a<n;++a,t+=r.packedLength)o[a]=r.unpack(e,t);var c=u.unpack(e,t,T);t+=u.packedLength;var d=e[t++],h=e[t++],p=e[t++],f=e[t++],m=e[t];return l(i)?(i._positions=o,i._ellipsoid=u.clone(c,i._ellipsoid),i._width=d,i._height=h,i._extrudedHeight=p,i._cornerType=f,i._granularity=m,i):(E.positions=o,E.width=d,E.height=h,E.extrudedHeight=p,E.cornerType=f,E.granularity=m,new b(E))},b.createGeometry=function(i){var n=i._positions,o=i._height,s=i._width,l=i._extrudedHeight,u=o!==l,d=i._ellipsoid;n=_(n,d);var h=e(n,r.equalsEpsilon);if(!(h.length<2||s<=0)){var p,f={ellipsoid:d,positions:h,width:s,cornerType:i._cornerType,granularity:i._granularity,saveAttributes:!1};if(u){var b=Math.max(o,l);l=Math.min(o,l),o=b,f.height=o,f.extrudedHeight=l,p=y(f)}else{p=v(a.computePositions(f),f.cornerType),p.attributes.position.values=m.scaleToGeodeticHeight(p.attributes.position.values,o,d)}var C=p.attributes,S=t.fromVertices(C.position.values,void 0,3);return new c({attributes:C,indices:p.indices,primitiveType:g.LINES,boundingSphere:S})}},b}),define("Core/createGuid",[],function(){"use strict";function e(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}return e}),define("Core/CullingVolume",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./DeveloperError","./Intersect","./Plane"],function(e,t,r,i,n,o,a){"use strict";function s(e){this.planes=r(e,[])}var l=[new e,new e,new e];e.clone(e.UNIT_X,l[0]),e.clone(e.UNIT_Y,l[1]),e.clone(e.UNIT_Z,l[2]) +;var u=new e,c=new e,d=new a(new e(1,0,0),0);return s.fromBoundingSphere=function(r,n){i(n)||(n=new s);var o=l.length,a=n.planes;a.length=2*o;for(var d=r.center,h=r.radius,p=0,f=0;f<o;++f){var m=l[f],g=a[p],_=a[p+1];i(g)||(g=a[p]=new t),i(_)||(_=a[p+1]=new t),e.multiplyByScalar(m,-h,u),e.add(d,u,u),g.x=m.x,g.y=m.y,g.z=m.z,g.w=-e.dot(m,u),e.multiplyByScalar(m,h,u),e.add(d,u,u),_.x=-m.x,_.y=-m.y,_.z=-m.z,_.w=-e.dot(e.negate(m,c),u),p+=2}return n},s.prototype.computeVisibility=function(e){for(var t=this.planes,r=!1,i=0,n=t.length;i<n;++i){var s=e.intersectPlane(a.fromCartesian4(t[i],d));if(s===o.OUTSIDE)return o.OUTSIDE;s===o.INTERSECTING&&(r=!0)}return r?o.INTERSECTING:o.INSIDE},s.prototype.computeVisibilityWithPlaneMask=function(e,t){if(t===s.MASK_OUTSIDE||t===s.MASK_INSIDE)return t;for(var r=s.MASK_INSIDE,i=this.planes,n=0,l=i.length;n<l;++n){var u=n<31?1<<n:0;if(!(n<31&&0==(t&u))){var c=e.intersectPlane(a.fromCartesian4(i[n],d));if(c===o.OUTSIDE)return s.MASK_OUTSIDE;c===o.INTERSECTING&&(r|=u)}}return r},s.MASK_OUTSIDE=4294967295,s.MASK_INSIDE=0,s.MASK_INDETERMINATE=2147483647,s}),define("Core/CylinderGeometryLibrary",["./Math"],function(e){"use strict";var t={};return t.computePositions=function(t,r,i,n,o){var a,s=.5*t,l=-s,u=n+n,c=o?2*u:u,d=new Float64Array(3*c),h=0,p=0,f=o?3*u:0,m=o?3*(u+n):3*n;for(a=0;a<n;a++){var g=a/n*e.TWO_PI,_=Math.cos(g),v=Math.sin(g),y=_*i,b=v*i,C=_*r,S=v*r;d[p+f]=y,d[p+f+1]=b,d[p+f+2]=l,d[p+m]=C,d[p+m+1]=S,d[p+m+2]=s,p+=3,o&&(d[h++]=y,d[h++]=b,d[h++]=l,d[h++]=C,d[h++]=S,d[h++]=s)}return d},t}),define("Core/CylinderGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CylinderGeometryLibrary","./defaultValue","./defined","./DeveloperError","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=o(e,o.EMPTY_OBJECT);var t=e.length,r=e.topRadius,i=e.bottomRadius,n=o(e.vertexFormat,f.DEFAULT),a=o(e.slices,128);this._length=t,this._topRadius=r,this._bottomRadius=i,this._vertexFormat=f.clone(n),this._slices=a,this._workerName="createCylinderGeometry"}var g=new t,_=new r,v=new r,y=new r,b=new r;m.packedLength=f.packedLength+4,m.pack=function(e,t,r){return r=o(r,0),f.pack(e._vertexFormat,t,r),r+=f.packedLength,t[r++]=e._length,t[r++]=e._topRadius,t[r++]=e._bottomRadius,t[r]=e._slices,t};var C=new f,S={vertexFormat:C,length:void 0,topRadius:void 0,bottomRadius:void 0,slices:void 0};m.unpack=function(e,t,r){t=o(t,0);var i=f.unpack(e,t,C);t+=f.packedLength;var n=e[t++],s=e[t++],l=e[t++],u=e[t];return a(r)?(r._vertexFormat=f.clone(i,r._vertexFormat),r._length=n,r._topRadius=s,r._bottomRadius=l,r._slices=u,r):(S.length=n,S.topRadius=s,S.bottomRadius=l,S.slices=u,new m(S))},m.createGeometry=function(o){var a=o._length,s=o._topRadius,f=o._bottomRadius,m=o._vertexFormat,C=o._slices;if(!(a<=0||s<0||f<0||0===s&&0===f)){var S,w=C+C,T=C+w,E=w+w,A=n.computePositions(a,s,f,C,!0),x=m.st?new Float32Array(2*E):void 0,P=m.normal?new Float32Array(3*E):void 0,D=m.tangent?new Float32Array(3*E):void 0,I=m.bitangent?new Float32Array(3*E):void 0,O=m.normal||m.tangent||m.bitangent;if(O){var M=m.tangent||m.bitangent,R=0,L=0,N=0,k=_;k.z=0;var F=y,B=v;for(S=0;S<C;S++){var U=S/C*h.TWO_PI,V=Math.cos(U),z=Math.sin(U);O&&(k.x=V,k.y=z,M&&(F=r.normalize(r.cross(r.UNIT_Z,k,F),F)),m.normal&&(P[R++]=V,P[R++]=z,P[R++]=0,P[R++]=V,P[R++]=z,P[R++]=0),m.tangent&&(D[L++]=F.x,D[L++]=F.y,D[L++]=F.z,D[L++]=F.x,D[L++]=F.y,D[L++]=F.z),m.bitangent&&(B=r.normalize(r.cross(k,F,B),B),I[N++]=B.x,I[N++]=B.y,I[N++]=B.z,I[N++]=B.x,I[N++]=B.y,I[N++]=B.z))}for(S=0;S<C;S++)m.normal&&(P[R++]=0,P[R++]=0,P[R++]=-1),m.tangent&&(D[L++]=1,D[L++]=0,D[L++]=0),m.bitangent&&(I[N++]=0,I[N++]=-1,I[N++]=0);for(S=0;S<C;S++)m.normal&&(P[R++]=0,P[R++]=0,P[R++]=1),m.tangent&&(D[L++]=1,D[L++]=0,D[L++]=0),m.bitangent&&(I[N++]=0,I[N++]=1,I[N++]=0)}var G=12*C-12,W=d.createTypedArray(E,G),H=0,j=0;for(S=0;S<C-1;S++)W[H++]=j,W[H++]=j+2,W[H++]=j+3,W[H++]=j,W[H++]=j+3,W[H++]=j+1,j+=2;for(W[H++]=w-2,W[H++]=0,W[H++]=1,W[H++]=w-2,W[H++]=1,W[H++]=w-1,S=1;S<C-1;S++)W[H++]=w+S+1,W[H++]=w+S,W[H++]=w;for(S=1;S<C-1;S++)W[H++]=T,W[H++]=T+S,W[H++]=T+S+1;var q=0;if(m.st){var Y=Math.max(s,f);for(S=0;S<E;S++){var X=r.fromArray(A,3*S,b);x[q++]=(X.x+Y)/(2*Y),x[q++]=(X.y+Y)/(2*Y)}}var Q=new c;m.position&&(Q.position=new u({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:A})),m.normal&&(Q.normal=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:P})),m.tangent&&(Q.tangent=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:D})),m.bitangent&&(Q.bitangent=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),m.st&&(Q.st=new u({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:x})),g.x=.5*a,g.y=Math.max(f,s);var Z=new e(r.ZERO,t.magnitude(g));return new l({attributes:Q,indices:W,primitiveType:p.TRIANGLES,boundingSphere:Z})}};var w;return m.getUnitCylinder=function(){return a(w)||(w=m.createGeometry(new m({topRadius:1,bottomRadius:1,length:1,vertexFormat:f.POSITION_ONLY}))),w},m}),define("Core/CylinderOutlineGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./CylinderGeometryLibrary","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){e=a(e,a.EMPTY_OBJECT);var t=e.length,r=e.topRadius,i=e.bottomRadius,n=a(e.slices,128),o=Math.max(a(e.numberOfVerticalLines,16),0);this._length=t,this._topRadius=r,this._bottomRadius=i,this._slices=n,this._numberOfVerticalLines=o,this._workerName="createCylinderOutlineGeometry"}var f=new t;p.packedLength=5,p.pack=function(e,t,r){return r=a(r,0),t[r++]=e._length,t[r++]=e._topRadius,t[r++]=e._bottomRadius,t[r++]=e._slices,t[r]=e._numberOfVerticalLines,t};var m={length:void 0,topRadius:void 0,bottomRadius:void 0,slices:void 0,numberOfVerticalLines:void 0};return p.unpack=function(e,t,r){t=a(t,0);var i=e[t++],n=e[t++],o=e[t++],l=e[t++],u=e[t];return s(r)?(r._length=i,r._topRadius=n,r._bottomRadius=o,r._slices=l,r._numberOfVerticalLines=u,r):(m.length=i,m.topRadius=n,m.bottomRadius=o,m.slices=l,m.numberOfVerticalLines=u,new p(m))},p.createGeometry=function(i){var a=i._length,s=i._topRadius,p=i._bottomRadius,m=i._slices,g=i._numberOfVerticalLines;if(!(a<=0||s<0||p<0||0===s&&0===p)){var _,v=2*m,y=o.computePositions(a,s,p,m,!1),b=2*m;if(g>0){var C=Math.min(g,m);_=Math.round(m/C),b+=C}var S,w=d.createTypedArray(v,2*b),T=0;for(S=0;S<m-1;S++)w[T++]=S,w[T++]=S+1,w[T++]=S+m,w[T++]=S+1+m;if(w[T++]=m-1,w[T++]=0,w[T++]=m+m-1,w[T++]=m,g>0)for(S=0;S<m;S+=_)w[T++]=S,w[T++]=S+m;var E=new c;E.position=new u({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:y}),f.x=.5*a,f.y=Math.max(p,s);var A=new e(r.ZERO,t.magnitude(f));return new l({attributes:E,indices:w,primitiveType:h.LINES,boundingSphere:A})}},p}),define("Core/decodeGoogleEarthEnterpriseData",["./Check","./RuntimeError"],function(e,t){"use strict";function r(e,o){if(r.passThroughDataForTesting)return o;var a=e.byteLength;if(0===a||a%4!=0)throw new t("The length of key must be greater than 0 and a multiple of 4.");var s=new DataView(o),l=s.getUint32(0,!0);if(l===i||l===n)return o;for(var u,c=new DataView(e),d=0,h=o.byteLength,p=h-h%8,f=a,m=8;d<p;)for(m=(m+8)%24,u=m;d<p&&u<f;)s.setUint32(d,s.getUint32(d,!0)^c.getUint32(u,!0),!0),s.setUint32(d+4,s.getUint32(d+4,!0)^c.getUint32(u+4,!0),!0),d+=8,u+=24;if(d<h)for(u>=f&&(m=(m+8)%24,u=m);d<h;)s.setUint8(d,s.getUint8(d)^c.getUint8(u)),d++,u++}var i=1953029805,n=2917034100;return r.passThroughDataForTesting=!1,r}),define("Core/DefaultProxy",[],function(){"use strict";function e(e){this.proxy=e}return e.prototype.getURL=function(e){var t=-1===this.proxy.indexOf("?")?"?":"";return this.proxy+t+encodeURIComponent(e)},e}),define("Core/DistanceDisplayCondition",["./defaultValue","./defined","./defineProperties","./DeveloperError"],function(e,t,r,i){"use strict";function n(t,r){t=e(t,0),this._near=t,r=e(r,Number.MAX_VALUE),this._far=r}return r(n.prototype,{near:{get:function(){return this._near},set:function(e){this._near=e}},far:{get:function(){return this._far},set:function(e){this._far=e}}}),n.packedLength=2,n.pack=function(t,r,i){return i=e(i,0),r[i++]=t.near,r[i]=t.far,r},n.unpack=function(r,i,o){return i=e(i,0),t(o)||(o=new n),o.near=r[i++],o.far=r[i],o},n.equals=function(e,r){return e===r||t(e)&&t(r)&&e.near===r.near&&e.far===r.far},n.clone=function(e,r){if(t(e))return t(r)||(r=new n),r.near=e.near,r.far=e.far,r},n.prototype.clone=function(e){return n.clone(this,e)},n.prototype.equals=function(e){return n.equals(this,e)},n}),define("Core/DistanceDisplayConditionGeometryInstanceAttribute",["./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError"],function(e,t,r,i,n){"use strict";function o(e,r){e=t(e,0),r=t(r,Number.MAX_VALUE),this.value=new Float32Array([e,r])}return i(o.prototype,{componentDatatype:{get:function(){return e.FLOAT}},componentsPerAttribute:{get:function(){return 2}},normalize:{get:function(){return!1}}}),o.fromDistanceDisplayCondition=function(e){return new o(e.near,e.far)},o.toValue=function(e,t){return r(t)?(t[0]=e.near,t[1]=e.far,t):new Float32Array([e.near,e.far])},o}),define("Core/DoublyLinkedList",["../Core/defined","../Core/defineProperties"],function(e,t){"use strict";function r(){this.head=void 0,this.tail=void 0,this._length=0}function i(e,t,r){this.item=e,this.previous=t,this.next=r}function n(t,r){e(r.previous)&&e(r.next)?(r.previous.next=r.next,r.next.previous=r.previous):e(r.previous)?(r.previous.next=void 0,t.tail=r.previous):e(r.next)?(r.next.previous=void 0,t.head=r.next):(t.head=void 0,t.tail=void 0),r.next=void 0,r.previous=void 0}return t(r.prototype,{length:{get:function(){return this._length}}}),r.prototype.add=function(t){var r=new i(t,this.tail,void 0);return e(this.tail)?(this.tail.next=r,this.tail=r):(this.head=r,this.tail=r),++this._length,r},r.prototype.remove=function(t){e(t)&&(n(this,t),--this._length)},r.prototype.splice=function(e,t){if(e!==t){n(this,t);var r=e.next;e.next=t,this.tail===e?this.tail=t:r.previous=t,t.next=r,t.previous=e}},r}),define("ThirdParty/Tween",[],function(){void 0===Date.now&&(Date.now=function(){return(new Date).valueOf()});var e=e||function(){var e=[];return{REVISION:"13",getAll:function(){return e},removeAll:function(){e=[]},add:function(t){e.push(t)},remove:function(t){var r=e.indexOf(t);-1!==r&&e.splice(r,1)},update:function(t){if(0===e.length)return!1;var r=0;for(t=void 0!==t?t:"undefined"!=typeof window&&void 0!==window.performance&&void 0!==window.performance.now?window.performance.now():Date.now();r<e.length;)e[r].update(t)?r++:e.splice(r,1);return!0}}}();return e.Tween=function(t){var r=t,i={},n={},o={},a=1e3,s=0,l=!1,u=!1,c=!1,d=0,h=null,p=e.Easing.Linear.None,f=e.Interpolation.Linear,m=[],g=null,_=!1,v=null,y=null,b=null;for(var C in t)i[C]=parseFloat(t[C],10);this.to=function(e,t){return void 0!==t&&(a=t),n=e,this},this.start=function(t){e.add(this),u=!0,_=!1,h=void 0!==t?t:"undefined"!=typeof window&&void 0!==window.performance&&void 0!==window.performance.now?window.performance.now():Date.now(),h+=d;for(var a in n){if(n[a]instanceof Array){if(0===n[a].length)continue;n[a]=[r[a]].concat(n[a])}i[a]=r[a],i[a]instanceof Array==!1&&(i[a]*=1),o[a]=i[a]||0}return this},this.stop=function(){return u?(e.remove(this),u=!1,null!==b&&b.call(r),this.stopChainedTweens(),this):this},this.stopChainedTweens=function(){for(var e=0,t=m.length;e<t;e++)m[e].stop()},this.delay=function(e){return d=e,this},this.repeat=function(e){return s=e,this},this.yoyo=function(e){return l=e,this},this.easing=function(e){return p=e,this},this.interpolation=function(e){return f=e,this},this.chain=function(){return m=arguments,this},this.onStart=function(e){return g=e,this},this.onUpdate=function(e){return v=e,this},this.onComplete=function(e){return y=e,this},this.onStop=function(e){return b=e,this},this.update=function(e){var t;if(e<h)return!0;!1===_&&(null!==g&&g.call(r),_=!0);var u=(e-h)/a;u=u>1?1:u;var b=p(u);for(t in n){var C=i[t]||0,S=n[t];S instanceof Array?r[t]=f(S,b):("string"==typeof S&&(S=C+parseFloat(S,10)),"number"==typeof S&&(r[t]=C+(S-C)*b))}if(null!==v&&v.call(r,b),1==u){if(s>0){isFinite(s)&&s--;for(t in o){if("string"==typeof n[t]&&(o[t]=o[t]+parseFloat(n[t],10)),l){var w=o[t];o[t]=n[t],n[t]=w}i[t]=o[t]}return l&&(c=!c),h=e+d,!0}null!==y&&y.call(r);for(var T=0,E=m.length;T<E;T++)m[T].start(e);return!1}return!0}},e.Easing={Linear:{None:function(e){return e}},Quadratic:{In:function(e){return e*e},Out:function(e){return e*(2-e)},InOut:function(e){return(e*=2)<1?.5*e*e:-.5*(--e*(e-2)-1)}},Cubic:{In:function(e){return e*e*e},Out:function(e){return--e*e*e+1},InOut:function(e){return(e*=2)<1?.5*e*e*e:.5*((e-=2)*e*e+2)}},Quartic:{In:function(e){return e*e*e*e},Out:function(e){return 1- --e*e*e*e},InOut:function(e){return(e*=2)<1?.5*e*e*e*e:-.5*((e-=2)*e*e*e-2)}},Quintic:{In:function(e){return e*e*e*e*e},Out:function(e){return--e*e*e*e*e+1},InOut:function(e){return(e*=2)<1?.5*e*e*e*e*e:.5*((e-=2)*e*e*e*e+2)}},Sinusoidal:{In:function(e){return 1-Math.cos(e*Math.PI/2)},Out:function(e){return Math.sin(e*Math.PI/2)},InOut:function(e){return.5*(1-Math.cos(Math.PI*e))}},Exponential:{In:function(e){return 0===e?0:Math.pow(1024,e-1)},Out:function(e){return 1===e?1:1-Math.pow(2,-10*e)},InOut:function(e){return 0===e?0:1===e?1:(e*=2)<1?.5*Math.pow(1024,e-1):.5*(2-Math.pow(2,-10*(e-1)))}},Circular:{In:function(e){return 1-Math.sqrt(1-e*e)},Out:function(e){return Math.sqrt(1- --e*e)},InOut:function(e){return(e*=2)<1?-.5*(Math.sqrt(1-e*e)-1):.5*(Math.sqrt(1-(e-=2)*e)+1)}},Elastic:{In:function(e){var t,r=.1;return 0===e?0:1===e?1:(!r||r<1?(r=1,t=.1):t=.4*Math.asin(1/r)/(2*Math.PI),-r*Math.pow(2,10*(e-=1))*Math.sin((e-t)*(2*Math.PI)/.4))},Out:function(e){var t,r=.1;return 0===e?0:1===e?1:(!r||r<1?(r=1,t=.1):t=.4*Math.asin(1/r)/(2*Math.PI),r*Math.pow(2,-10*e)*Math.sin((e-t)*(2*Math.PI)/.4)+1)},InOut:function(e){var t,r=.1;return 0===e?0:1===e?1:(!r||r<1?(r=1,t=.1):t=.4*Math.asin(1/r)/(2*Math.PI),(e*=2)<1?r*Math.pow(2,10*(e-=1))*Math.sin((e-t)*(2*Math.PI)/.4)*-.5:r*Math.pow(2,-10*(e-=1))*Math.sin((e-t)*(2*Math.PI)/.4)*.5+1)}},Back:{In:function(e){var t=1.70158;return e*e*((t+1)*e-t)},Out:function(e){var t=1.70158;return--e*e*((t+1)*e+t)+1},InOut:function(e){var t=2.5949095;return(e*=2)<1?e*e*((t+1)*e-t)*.5:.5*((e-=2)*e*((t+1)*e+t)+2)}},Bounce:{In:function(t){return 1-e.Easing.Bounce.Out(1-t)},Out:function(e){return e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375},InOut:function(t){return t<.5?.5*e.Easing.Bounce.In(2*t):.5*e.Easing.Bounce.Out(2*t-1)+.5}}},e.Interpolation={Linear:function(t,r){var i=t.length-1,n=i*r,o=Math.floor(n),a=e.Interpolation.Utils.Linear;return r<0?a(t[0],t[1],n):r>1?a(t[i],t[i-1],i-n):a(t[o],t[o+1>i?i:o+1],n-o)},Bezier:function(t,r){var i,n=0,o=t.length-1,a=Math.pow,s=e.Interpolation.Utils.Bernstein;for(i=0;i<=o;i++)n+=a(1-r,o-i)*a(r,i)*t[i]*s(o,i);return n},CatmullRom:function(t,r){var i=t.length-1,n=i*r,o=Math.floor(n),a=e.Interpolation.Utils.CatmullRom;return t[0]===t[i]?(r<0&&(o=Math.floor(n=i*(1+r))),a(t[(o-1+i)%i],t[o],t[(o+1)%i],t[(o+2)%i],n-o)):r<0?t[0]-(a(t[0],t[0],t[1],t[1],-n)-t[0]):r>1?t[i]-(a(t[i],t[i],t[i-1],t[i-1],n-i)-t[i]):a(t[o?o-1:0],t[o],t[i<o+1?i:o+1],t[i<o+2?i:o+2],n-o)},Utils:{Linear:function(e,t,r){return(t-e)*r+e},Bernstein:function(t,r){var i=e.Interpolation.Utils.Factorial;return i(t)/i(r)/i(t-r)},Factorial:function(){var e=[1];return function(t){var r,i=1;if(e[t])return e[t];for(r=t;r>1;r--)i*=r;return e[t]=i}}(),CatmullRom:function(e,t,r,i,n){var o=.5*(r-e),a=.5*(i-t),s=n*n;return(2*t-2*r+o+a)*(n*s)+(-3*t+3*r-2*o-a)*s+o*n+t}}},e}),define("Core/EasingFunction",["../ThirdParty/Tween","./freezeObject"],function(e,t){"use strict";return t({LINEAR_NONE:e.Easing.Linear.None,QUADRACTIC_IN:e.Easing.Quadratic.In,QUADRACTIC_OUT:e.Easing.Quadratic.Out,QUADRACTIC_IN_OUT:e.Easing.Quadratic.InOut,CUBIC_IN:e.Easing.Cubic.In,CUBIC_OUT:e.Easing.Cubic.Out,CUBIC_IN_OUT:e.Easing.Cubic.InOut,QUARTIC_IN:e.Easing.Quartic.In,QUARTIC_OUT:e.Easing.Quartic.Out,QUARTIC_IN_OUT:e.Easing.Quartic.InOut,QUINTIC_IN:e.Easing.Quintic.In,QUINTIC_OUT:e.Easing.Quintic.Out,QUINTIC_IN_OUT:e.Easing.Quintic.InOut,SINUSOIDAL_IN:e.Easing.Sinusoidal.In,SINUSOIDAL_OUT:e.Easing.Sinusoidal.Out,SINUSOIDAL_IN_OUT:e.Easing.Sinusoidal.InOut,EXPONENTIAL_IN:e.Easing.Exponential.In,EXPONENTIAL_OUT:e.Easing.Exponential.Out,EXPONENTIAL_IN_OUT:e.Easing.Exponential.InOut,CIRCULAR_IN:e.Easing.Circular.In,CIRCULAR_OUT:e.Easing.Circular.Out,CIRCULAR_IN_OUT:e.Easing.Circular.InOut,ELASTIC_IN:e.Easing.Elastic.In,ELASTIC_OUT:e.Easing.Elastic.Out,ELASTIC_IN_OUT:e.Easing.Elastic.InOut,BACK_IN:e.Easing.Back.In,BACK_OUT:e.Easing.Back.Out,BACK_IN_OUT:e.Easing.Back.InOut,BOUNCE_IN:e.Easing.Bounce.In,BOUNCE_OUT:e.Easing.Bounce.Out,BOUNCE_IN_OUT:e.Easing.Bounce.InOut})}),define("Core/EllipsoidGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=n(e,n.EMPTY_OBJECT);var t=n(e.radii,C),i=Math.round(n(e.stackPartitions,64)),o=Math.round(n(e.slicePartitions,64)),a=n(e.vertexFormat,f.DEFAULT);this._radii=r.clone(t),this._stackPartitions=i,this._slicePartitions=o,this._vertexFormat=f.clone(a),this._workerName="createEllipsoidGeometry"}var g=new r,_=new r,v=new r,y=new r,b=new r,C=new r(1,1,1),S=Math.cos,w=Math.sin;m.packedLength=r.packedLength+f.packedLength+2,m.pack=function(e,t,i){return i=n(i,0),r.pack(e._radii,t,i),i+=r.packedLength,f.pack(e._vertexFormat,t,i),i+=f.packedLength,t[i++]=e._stackPartitions,t[i]=e._slicePartitions,t};var T=new r,E=new f,A={radii:T,vertexFormat:E,stackPartitions:void 0,slicePartitions:void 0};m.unpack=function(e,t,i){t=n(t,0);var a=r.unpack(e,t,T);t+=r.packedLength;var s=f.unpack(e,t,E);t+=f.packedLength;var l=e[t++],u=e[t];return o(i)?(i._radii=r.clone(a,i._radii),i._vertexFormat=f.clone(s,i._vertexFormat),i._stackPartitions=l,i._slicePartitions=u,i):(A.stackPartitions=l,A.slicePartitions=u,new m(A))},m.createGeometry=function(n){var o=n._radii;if(!(o.x<=0||o.y<=0||o.z<=0)){var a,f,m=s.fromCartesian3(o),C=n._vertexFormat,T=n._slicePartitions+1,E=n._stackPartitions+1,A=E*T,x=new Float64Array(3*A),P=6*(T-1)*(E-2),D=d.createTypedArray(A,P),I=C.normal?new Float32Array(3*A):void 0,O=C.tangent?new Float32Array(3*A):void 0,M=C.bitangent?new Float32Array(3*A):void 0,R=C.st?new Float32Array(2*A):void 0,L=new Array(T),N=new Array(T),k=0;for(a=0;a<T;a++){var F=h.TWO_PI*a/(T-1);L[a]=S(F),N[a]=w(F),x[k++]=0,x[k++]=0,x[k++]=o.z}for(a=1;a<E-1;a++){var B=Math.PI*a/(E-1),U=w(B),V=o.x*U,z=o.y*U,G=o.z*S(B);for(f=0;f<T;f++)x[k++]=L[f]*V,x[k++]=N[f]*z,x[k++]=G}for(a=0;a<T;a++)x[k++]=0,x[k++]=0,x[k++]=-o.z;var W=new c;C.position&&(W.position=new u({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:x}));var H=0,j=0,q=0,Y=0;if(C.st||C.normal||C.tangent||C.bitangent){for(a=0;a<A;a++){var X=r.fromArray(x,3*a,g),Q=m.geodeticSurfaceNormal(X,_);if(C.st){var Z=t.negate(Q,b);t.magnitude(Z)<h.EPSILON6&&(k=3*(a+T*Math.floor(.5*E)),k>x.length&&(k=3*(a-T*Math.floor(.5*E))),r.fromArray(x,k,Z),m.geodeticSurfaceNormal(Z,Z),t.negate(Z,Z)),R[H++]=Math.atan2(Z.y,Z.x)/h.TWO_PI+.5,R[H++]=Math.asin(Q.z)/Math.PI+.5}if(C.normal&&(I[j++]=Q.x,I[j++]=Q.y,I[j++]=Q.z),C.tangent||C.bitangent){var K=v;if(a<T||a>A-T-1?(r.cross(r.UNIT_X,Q,K),r.normalize(K,K)):(r.cross(r.UNIT_Z,Q,K),r.normalize(K,K)),C.tangent&&(O[q++]=K.x,O[q++]=K.y,O[q++]=K.z),C.bitangent){var J=r.cross(Q,K,y);r.normalize(J,J),M[Y++]=J.x,M[Y++]=J.y,M[Y++]=J.z}}}C.st&&(W.st=new u({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:R})),C.normal&&(W.normal=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),C.tangent&&(W.tangent=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:O})),C.bitangent&&(W.bitangent=new u({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:M}))}for(k=0,f=0;f<T-1;f++)D[k++]=T+f,D[k++]=T+f+1,D[k++]=f+1;var $,ee;for(a=1;a<E-2;a++)for($=a*T,ee=(a+1)*T,f=0;f<T-1;f++)D[k++]=ee+f,D[k++]=ee+f+1,D[k++]=$+f+1,D[k++]=ee+f,D[k++]=$+f+1,D[k++]=$+f;for(a=E-2,$=a*T,ee=(a+1)*T,f=0;f<T-1;f++)D[k++]=ee+f,D[k++]=$+f+1,D[k++]=$+f;return new l({attributes:W,indices:D,primitiveType:p.TRIANGLES,boundingSphere:e.fromEllipsoid(m)})}};var x;return m.getUnitEllipsoid=function(){return o(x)||(x=m.createGeometry(new m({radii:new r(1,1,1),vertexFormat:f.POSITION_ONLY}))),x},m}),define("Core/EllipsoidOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){e=i(e,i.EMPTY_OBJECT);var r=i(e.radii,f),n=Math.round(i(e.stackPartitions,10)),o=Math.round(i(e.slicePartitions,8)),a=Math.round(i(e.subdivisions,128));this._radii=t.clone(r),this._stackPartitions=n,this._slicePartitions=o,this._subdivisions=a,this._workerName="createEllipsoidOutlineGeometry"}var f=new t(1,1,1),m=Math.cos,g=Math.sin;p.packedLength=t.packedLength+3,p.pack=function(e,r,n){return n=i(n,0),t.pack(e._radii,r,n),n+=t.packedLength,r[n++]=e._stackPartitions,r[n++]=e._slicePartitions,r[n]=e._subdivisions,r};var _=new t,v={radii:_,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return p.unpack=function(e,r,o){r=i(r,0);var a=t.unpack(e,r,_);r+=t.packedLength;var s=e[r++],l=e[r++],u=e[r++];return n(o)?(o._radii=t.clone(a,o._radii),o._stackPartitions=s,o._slicePartitions=l,o._subdivisions=u,o):(v.stackPartitions=s,v.slicePartitions=l,v.subdivisions=u,new p(v))},p.createGeometry=function(t){var i=t._radii;if(!(i.x<=0||i.y<=0||i.z<=0)){var n,o,p,f,_,v,y=a.fromCartesian3(i),b=t._stackPartitions,C=t._slicePartitions,S=t._subdivisions,w=S*(b+C-1),T=w-C+2,E=new Float64Array(3*T),A=c.createTypedArray(T,2*w),x=0,P=new Array(S),D=new Array(S);for(n=0;n<S;n++)p=d.TWO_PI*n/S,P[n]=m(p),D[n]=g(p);for(n=1;n<b;n++)for(f=Math.PI*n/b,_=m(f),v=g(f),o=0;o<S;o++)E[x++]=i.x*P[o]*v,E[x++]=i.y*D[o]*v,E[x++]=i.z*_;for(P.length=C,D.length=C,n=0;n<C;n++)p=d.TWO_PI*n/C,P[n]=m(p),D[n]=g(p);for(E[x++]=0,E[x++]=0,E[x++]=i.z,n=1;n<S;n++)for(f=Math.PI*n/S,_=m(f),v=g(f),o=0;o<C;o++)E[x++]=i.x*P[o]*v,E[x++]=i.y*D[o]*v,E[x++]=i.z*_;for(E[x++]=0,E[x++]=0,E[x++]=-i.z,x=0,n=0;n<b-1;++n){var I=n*S;for(o=0;o<S-1;++o)A[x++]=I+o,A[x++]=I+o+1;A[x++]=I+S-1,A[x++]=I}var O=S*(b-1);for(o=1;o<C+1;++o)A[x++]=O,A[x++]=O+o;for(n=0;n<S-2;++n){var M=n*C+1+O,R=(n+1)*C+1+O;for(o=0;o<C-1;++o)A[x++]=R+o,A[x++]=M+o;A[x++]=R+C-1,A[x++]=M+C-1}var L=E.length/3-1;for(o=L-1;o>L-C-1;--o)A[x++]=L,A[x++]=o;var N=new u({position:new l({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:E})});return new s({attributes:N,indices:A,primitiveType:h.LINES,boundingSphere:e.fromEllipsoid(y)})}},p}),define("Core/EllipsoidTerrainProvider",["../ThirdParty/when","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Event","./GeographicTilingScheme","./HeightmapTerrainData","./TerrainProvider"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(i){i=t(i,{}),this._tilingScheme=i.tilingScheme,r(this._tilingScheme)||(this._tilingScheme=new a({ellipsoid:t(i.ellipsoid,n.WGS84)})),this._levelZeroMaximumGeometricError=l.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid,64,this._tilingScheme.getNumberOfXTilesAtLevel(0)),this._errorEvent=new o,this._readyPromise=e.resolve(!0)}return i(u.prototype,{errorEvent:{get:function(){return this._errorEvent}},credit:{get:function(){}},tilingScheme:{get:function(){return this._tilingScheme}},ready:{get:function(){return!0}},readyPromise:{get:function(){return this._readyPromise}},hasWaterMask:{get:function(){return!1}},hasVertexNormals:{get:function(){return!1}}}),u.prototype.requestTileGeometry=function(e,t,r,i){return new s({buffer:new Uint8Array(256),width:16,height:16})},u.prototype.getLevelMaximumGeometricError=function(e){return this._levelZeroMaximumGeometricError/(1<<e)},u.prototype.getTileDataAvailable=function(e,t,r){},u}),define("Core/EventHelper",["./defined","./DeveloperError"],function(e,t){"use strict";function r(){this._removalFunctions=[]}return r.prototype.add=function(e,t,r){var i=e.addEventListener(t,r);this._removalFunctions.push(i);var n=this;return function(){i();var e=n._removalFunctions;e.splice(e.indexOf(i),1)}},r.prototype.removeAll=function(){for(var e=this._removalFunctions,t=0,r=e.length;t<r;++t)e[t]();e.length=0},r}),define("Core/ExtrapolationType",["./freezeObject"],function(e){"use strict";return e({NONE:0,HOLD:1,EXTRAPOLATE:2})}),define("Core/OrthographicOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=i(e,i.EMPTY_OBJECT),this.left=e.left,this._left=void 0,this.right=e.right,this._right=void 0,this.top=e.top,this._top=void 0,this.bottom=e.bottom,this._bottom=void 0,this.near=i(e.near,1),this._near=this.near,this.far=i(e.far,5e8),this._far=this.far,this._cullingVolume=new r,this._orthographicMatrix=new s}function u(e){e.top===e._top&&e.bottom===e._bottom&&e.left===e._left&&e.right===e._right&&e.near===e._near&&e.far===e._far||(e._left=e.left,e._right=e.right,e._top=e.top,e._bottom=e.bottom,e._near=e.near,e._far=e.far,e._orthographicMatrix=s.computeOrthographicOffCenter(e.left,e.right,e.bottom,e.top,e.near,e.far,e._orthographicMatrix))}o(l.prototype,{projectionMatrix:{get:function(){return u(this),this._orthographicMatrix}}});var c=new e,d=new e,h=new e,p=new e;return l.prototype.computeCullingVolume=function(r,i,o){var a=this._cullingVolume.planes,s=this.top,l=this.bottom,u=this.right,f=this.left,m=this.near,g=this.far,_=e.cross(i,o,c);e.normalize(_,_);var v=d;e.multiplyByScalar(i,m,v),e.add(r,v,v);var y=h;e.multiplyByScalar(_,f,y),e.add(v,y,y);var b=a[0];return n(b)||(b=a[0]=new t),b.x=_.x,b.y=_.y,b.z=_.z,b.w=-e.dot(_,y),e.multiplyByScalar(_,u,y),e.add(v,y,y),b=a[1],n(b)||(b=a[1]=new t),b.x=-_.x,b.y=-_.y,b.z=-_.z,b.w=-e.dot(e.negate(_,p),y),e.multiplyByScalar(o,l,y),e.add(v,y,y),b=a[2],n(b)||(b=a[2]=new t),b.x=o.x,b.y=o.y,b.z=o.z,b.w=-e.dot(o,y),e.multiplyByScalar(o,s,y),e.add(v,y,y),b=a[3],n(b)||(b=a[3]=new t),b.x=-o.x,b.y=-o.y,b.z=-o.z,b.w=-e.dot(e.negate(o,p),y),b=a[4],n(b)||(b=a[4]=new t),b.x=i.x,b.y=i.y,b.z=i.z,b.w=-e.dot(i,v),e.multiplyByScalar(i,g,y),e.add(r,y,y),b=a[5],n(b)||(b=a[5]=new t),b.x=-i.x,b.y=-i.y,b.z=-i.z,b.w=-e.dot(e.negate(i,p),y),this._cullingVolume},l.prototype.getPixelDimensions=function(e,t,r,i){u(this);var n=this.right-this.left,o=this.top-this.bottom,a=n/e,s=o/t;return i.x=a,i.y=s,i},l.prototype.clone=function(e){return n(e)||(e=new l),e.left=this.left,e.right=this.right,e.top=this.top,e.bottom=this.bottom,e.near=this.near,e.far=this.far,e._left=void 0,e._right=void 0,e._top=void 0,e._bottom=void 0,e._near=void 0,e._far=void 0,e},l.prototype.equals=function(e){return n(e)&&this.right===e.right&&this.left===e.left&&this.top===e.top&&this.bottom===e.bottom&&this.near===e.near&&this.far===e.far},l}),define("Core/OrthographicFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./OrthographicOffCenterFrustum"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this._offCenterFrustum=new o,this.width=e.width,this._width=void 0,this.aspectRatio=e.aspectRatio,this._aspectRatio=void 0,this.near=t(e.near,1),this._near=this.near,this.far=t(e.far,5e8),this._far=this.far}function s(e){var t=e._offCenterFrustum;if(e.width!==e._width||e.aspectRatio!==e._aspectRatio||e.near!==e._near||e.far!==e._far){e._aspectRatio=e.aspectRatio,e._width=e.width,e._near=e.near,e._far=e.far;var r=1/e.aspectRatio;t.right=.5*e.width,t.left=-t.right,t.top=r*t.right,t.bottom=-t.top,t.near=e.near,t.far=e.far}}return a.packedLength=4,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.width,r[i++]=e.aspectRatio,r[i++]=e.near,r[i]=e.far,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.width=e[i++],n.aspectRatio=e[i++],n.near=e[i++],n.far=e[i],n},i(a.prototype,{projectionMatrix:{get:function(){return s(this),this._offCenterFrustum.projectionMatrix}}}),a.prototype.computeCullingVolume=function(e,t,r){return s(this),this._offCenterFrustum.computeCullingVolume(e,t,r)},a.prototype.getPixelDimensions=function(e,t,r,i){return s(this),this._offCenterFrustum.getPixelDimensions(e,t,r,i)},a.prototype.clone=function(e){return r(e)||(e=new a),e.aspectRatio=this.aspectRatio,e.width=this.width,e.near=this.near,e.far=this.far,e._aspectRatio=void 0,e._width=void 0,e._near=void 0,e._far=void 0,this._offCenterFrustum.clone(e._offCenterFrustum),e},a.prototype.equals=function(e){return!!r(e)&&(s(this),s(e),this.width===e.width&&this.aspectRatio===e.aspectRatio&&this.near===e.near&&this.far===e.far&&this._offCenterFrustum.equals(e._offCenterFrustum))},a}),define("Core/PerspectiveOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=i(e,i.EMPTY_OBJECT),this.left=e.left,this._left=void 0,this.right=e.right,this._right=void 0,this.top=e.top,this._top=void 0,this.bottom=e.bottom,this._bottom=void 0,this.near=i(e.near,1),this._near=this.near,this.far=i(e.far,5e8),this._far=this.far,this._cullingVolume=new r,this._perspectiveMatrix=new s,this._infinitePerspective=new s}function u(e){var t=e.top,r=e.bottom,i=e.right,n=e.left,o=e.near,a=e.far;t===e._top&&r===e._bottom&&n===e._left&&i===e._right&&o===e._near&&a===e._far||(e._left=n,e._right=i,e._top=t,e._bottom=r,e._near=o,e._far=a,e._perspectiveMatrix=s.computePerspectiveOffCenter(n,i,r,t,o,a,e._perspectiveMatrix),e._infinitePerspective=s.computeInfinitePerspectiveOffCenter(n,i,r,t,o,e._infinitePerspective))}o(l.prototype,{projectionMatrix:{get:function(){return u(this),this._perspectiveMatrix}},infiniteProjectionMatrix:{get:function(){return u(this),this._infinitePerspective}}});var c=new e,d=new e,h=new e,p=new e;return l.prototype.computeCullingVolume=function(r,i,o){var a=this._cullingVolume.planes,s=this.top,l=this.bottom,u=this.right,f=this.left,m=this.near,g=this.far,_=e.cross(i,o,c),v=d;e.multiplyByScalar(i,m,v),e.add(r,v,v);var y=h;e.multiplyByScalar(i,g,y),e.add(r,y,y);var b=p;e.multiplyByScalar(_,f,b),e.add(v,b,b),e.subtract(b,r,b),e.normalize(b,b),e.cross(b,o,b),e.normalize(b,b);var C=a[0];return n(C)||(C=a[0]=new t),C.x=b.x,C.y=b.y,C.z=b.z,C.w=-e.dot(b,r),e.multiplyByScalar(_,u,b),e.add(v,b,b),e.subtract(b,r,b),e.cross(o,b,b),e.normalize(b,b),C=a[1],n(C)||(C=a[1]=new t),C.x=b.x,C.y=b.y,C.z=b.z,C.w=-e.dot(b,r),e.multiplyByScalar(o,l,b),e.add(v,b,b),e.subtract(b,r,b),e.cross(_,b,b),e.normalize(b,b),C=a[2],n(C)||(C=a[2]=new t),C.x=b.x,C.y=b.y,C.z=b.z,C.w=-e.dot(b,r),e.multiplyByScalar(o,s,b),e.add(v,b,b),e.subtract(b,r,b),e.cross(b,_,b),e.normalize(b,b),C=a[3],n(C)||(C=a[3]=new t),C.x=b.x,C.y=b.y,C.z=b.z,C.w=-e.dot(b,r),C=a[4],n(C)||(C=a[4]=new t),C.x=i.x,C.y=i.y,C.z=i.z,C.w=-e.dot(i,v),e.negate(i,b),C=a[5],n(C)||(C=a[5]=new t),C.x=b.x,C.y=b.y,C.z=b.z,C.w=-e.dot(b,y),this._cullingVolume},l.prototype.getPixelDimensions=function(e,t,r,i){u(this);var n=1/this.near,o=this.top*n,a=2*r*o/t;o=this.right*n;var s=2*r*o/e;return i.x=s,i.y=a,i},l.prototype.clone=function(e){return n(e)||(e=new l),e.right=this.right,e.left=this.left,e.top=this.top,e.bottom=this.bottom,e.near=this.near,e.far=this.far,e._left=void 0,e._right=void 0,e._top=void 0,e._bottom=void 0,e._near=void 0,e._far=void 0,e},l.prototype.equals=function(e){ +return n(e)&&this.right===e.right&&this.left===e.left&&this.top===e.top&&this.bottom===e.bottom&&this.near===e.near&&this.far===e.far},l}),define("Core/PerspectiveFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./PerspectiveOffCenterFrustum"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this._offCenterFrustum=new o,this.fov=e.fov,this._fov=void 0,this._fovy=void 0,this._sseDenominator=void 0,this.aspectRatio=e.aspectRatio,this._aspectRatio=void 0,this.near=t(e.near,1),this._near=this.near,this.far=t(e.far,5e8),this._far=this.far,this.xOffset=t(e.xOffset,0),this._xOffset=this.xOffset,this.yOffset=t(e.yOffset,0),this._yOffset=this.yOffset}function s(e){var t=e._offCenterFrustum;e.fov===e._fov&&e.aspectRatio===e._aspectRatio&&e.near===e._near&&e.far===e._far&&e.xOffset===e._xOffset&&e.yOffset===e._yOffset||(e._aspectRatio=e.aspectRatio,e._fov=e.fov,e._fovy=e.aspectRatio<=1?e.fov:2*Math.atan(Math.tan(.5*e.fov)/e.aspectRatio),e._near=e.near,e._far=e.far,e._sseDenominator=2*Math.tan(.5*e._fovy),e._xOffset=e.xOffset,e._yOffset=e.yOffset,t.top=e.near*Math.tan(.5*e._fovy),t.bottom=-t.top,t.right=e.aspectRatio*t.top,t.left=-t.right,t.near=e.near,t.far=e.far,t.right+=e.xOffset,t.left+=e.xOffset,t.top+=e.yOffset,t.bottom+=e.yOffset)}return a.packedLength=6,a.pack=function(e,r,i){return i=t(i,0),r[i++]=e.fov,r[i++]=e.aspectRatio,r[i++]=e.near,r[i++]=e.far,r[i++]=e.xOffset,r[i]=e.yOffset,r},a.unpack=function(e,i,n){return i=t(i,0),r(n)||(n=new a),n.fov=e[i++],n.aspectRatio=e[i++],n.near=e[i++],n.far=e[i++],n.xOffset=e[i++],n.yOffset=e[i],n},i(a.prototype,{projectionMatrix:{get:function(){return s(this),this._offCenterFrustum.projectionMatrix}},infiniteProjectionMatrix:{get:function(){return s(this),this._offCenterFrustum.infiniteProjectionMatrix}},fovy:{get:function(){return s(this),this._fovy}},sseDenominator:{get:function(){return s(this),this._sseDenominator}}}),a.prototype.computeCullingVolume=function(e,t,r){return s(this),this._offCenterFrustum.computeCullingVolume(e,t,r)},a.prototype.getPixelDimensions=function(e,t,r,i){return s(this),this._offCenterFrustum.getPixelDimensions(e,t,r,i)},a.prototype.clone=function(e){return r(e)||(e=new a),e.aspectRatio=this.aspectRatio,e.fov=this.fov,e.near=this.near,e.far=this.far,e._aspectRatio=void 0,e._fov=void 0,e._near=void 0,e._far=void 0,this._offCenterFrustum.clone(e._offCenterFrustum),e},a.prototype.equals=function(e){return!!r(e)&&(s(this),s(e),this.fov===e.fov&&this.aspectRatio===e.aspectRatio&&this.near===e.near&&this.far===e.far&&this._offCenterFrustum.equals(e._offCenterFrustum))},a}),define("Core/FrustumGeometry",["./BoundingSphere","./Cartesian3","./Cartesian4","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./Matrix3","./Matrix4","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){var r,i,n=e.frustum,a=e.orientation,s=e.origin,l=o(e.vertexFormat,g.DEFAULT),u=o(e._drawNearPlane,!0);n instanceof p?(r=y,i=p.packedLength):n instanceof h&&(r=b,i=h.packedLength),this._frustumType=r,this._frustum=n.clone(),this._origin=t.clone(s),this._orientation=m.clone(a),this._drawNearPlane=u,this._vertexFormat=l,this._workerName="createFrustumGeometry",this.packedLength=2+i+t.packedLength+m.packedLength+g.packedLength}function v(e,t,r,i,n,o,s,l){for(var u=e/3*2,c=0;c<4;++c)a(t)&&(t[e]=o.x,t[e+1]=o.y,t[e+2]=o.z),a(r)&&(r[e]=s.x,r[e+1]=s.y,r[e+2]=s.z),a(i)&&(i[e]=l.x,i[e+1]=l.y,i[e+2]=l.z),e+=3;n[u]=0,n[u+1]=0,n[u+2]=1,n[u+3]=0,n[u+4]=1,n[u+5]=1,n[u+6]=0,n[u+7]=1}var y=0,b=1;_.pack=function(e,r,i){i=o(i,0);var n=e._frustumType,a=e._frustum;return r[i++]=n,n===y?(p.pack(a,r,i),i+=p.packedLength):(h.pack(a,r,i),i+=h.packedLength),t.pack(e._origin,r,i),i+=t.packedLength,m.pack(e._orientation,r,i),i+=m.packedLength,g.pack(e._vertexFormat,r,i),i+=g.packedLength,r[i]=e._drawNearPlane?1:0,r};var C=new p,S=new h,w=new m,T=new t,E=new g;_.unpack=function(e,r,i){r=o(r,0);var n,s=e[r++];s===y?(n=p.unpack(e,r,C),r+=p.packedLength):(n=h.unpack(e,r,S),r+=h.packedLength);var l=t.unpack(e,r,T);r+=t.packedLength;var u=m.unpack(e,r,w);r+=m.packedLength;var c=g.unpack(e,r,E);r+=g.packedLength;var d=1===e[r];if(!a(i))return new _({frustum:n,origin:l,orientation:u,vertexFormat:c,_drawNearPlane:d});var f=s===i._frustumType?i._frustum:void 0;return i._frustum=n.clone(f),i._frustumType=s,i._origin=t.clone(l,i._origin),i._orientation=m.clone(u,i._orientation),i._vertexFormat=g.clone(c,i._vertexFormat),i._drawNearPlane=d,i};var A=new c,x=new d,P=new d,D=new t,I=new t,O=new t,M=new t,R=new t,L=new t,N=new Array(3),k=new Array(4);k[0]=new r(-1,-1,1,1),k[1]=new r(1,-1,1,1),k[2]=new r(1,1,1,1),k[3]=new r(-1,1,1,1);for(var F=new Array(4),B=0;B<4;++B)F[B]=new r;return _._computeNearFarPlanes=function(e,i,n,s,l,u,h,p){var f=c.fromQuaternion(i,A),m=o(u,D),g=o(h,I),_=o(p,O);m=c.getColumn(f,0,m),g=c.getColumn(f,1,g),_=c.getColumn(f,2,_),t.normalize(m,m),t.normalize(g,g),t.normalize(_,_),t.negate(m,m);var v,b,C=d.computeView(e,_,g,m,x);if(n===y){var S=s.projectionMatrix,w=d.multiply(S,C,P);b=d.inverse(w,P)}else v=d.inverseTransformation(C,P);a(b)?(N[0]=s.near,N[1]=s.far):(N[0]=0,N[1]=s.near,N[2]=s.far);for(var T=0;T<2;++T)for(var E=0;E<4;++E){var M=r.clone(k[E],F[E]);if(a(b)){M=d.multiplyByVector(b,M,M);var R=1/M.w;t.multiplyByScalar(M,R,M),t.subtract(M,e,M),t.normalize(M,M);var L=t.dot(_,M);t.multiplyByScalar(M,N[T]/L,M),t.add(M,e,M)}else{a(s._offCenterFrustum)&&(s=s._offCenterFrustum);var B=N[T],U=N[T+1];M.x=.5*(M.x*(s.right-s.left)+s.left+s.right),M.y=.5*(M.y*(s.top-s.bottom)+s.bottom+s.top),M.z=.5*(M.z*(B-U)-B-U),M.w=1,d.multiplyByVector(v,M,M)}l[12*T+3*E]=M.x,l[12*T+3*E+1]=M.y,l[12*T+3*E+2]=M.z}},_.createGeometry=function(r){var i=r._frustumType,o=r._frustum,c=r._origin,d=r._orientation,h=r._drawNearPlane,p=r._vertexFormat,m=h?6:5,g=new Float64Array(72);_._computeNearFarPlanes(c,d,i,o,g);var y=24;g[y]=g[12],g[y+1]=g[13],g[y+2]=g[14],g[y+3]=g[0],g[y+4]=g[1],g[y+5]=g[2],g[y+6]=g[9],g[y+7]=g[10],g[y+8]=g[11],g[y+9]=g[21],g[y+10]=g[22],g[y+11]=g[23],y+=12,g[y]=g[15],g[y+1]=g[16],g[y+2]=g[17],g[y+3]=g[3],g[y+4]=g[4],g[y+5]=g[5],g[y+6]=g[0],g[y+7]=g[1],g[y+8]=g[2],g[y+9]=g[12],g[y+10]=g[13],g[y+11]=g[14],y+=12,g[y]=g[3],g[y+1]=g[4],g[y+2]=g[5],g[y+3]=g[15],g[y+4]=g[16],g[y+5]=g[17],g[y+6]=g[18],g[y+7]=g[19],g[y+8]=g[20],g[y+9]=g[6],g[y+10]=g[7],g[y+11]=g[8],y+=12,g[y]=g[6],g[y+1]=g[7],g[y+2]=g[8],g[y+3]=g[18],g[y+4]=g[19],g[y+5]=g[20],g[y+6]=g[21],g[y+7]=g[22],g[y+8]=g[23],g[y+9]=g[9],g[y+10]=g[10],g[y+11]=g[11],h||(g=g.subarray(12));var b=new u({position:new l({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:g})});if(a(p.normal)||a(p.tangent)||a(p.bitangent)||a(p.st)){var C=a(p.normal)?new Float32Array(12*m):void 0,S=a(p.tangent)?new Float32Array(12*m):void 0,w=a(p.bitangent)?new Float32Array(12*m):void 0,T=a(p.st)?new Float32Array(8*m):void 0,E=D,A=I,x=O,P=t.negate(E,M),N=t.negate(A,R),k=t.negate(x,L);y=0,h&&(v(y,C,S,w,T,k,E,A),y+=12),v(y,C,S,w,T,x,P,A),y+=12,v(y,C,S,w,T,P,k,A),y+=12,v(y,C,S,w,T,N,k,P),y+=12,v(y,C,S,w,T,E,x,A),y+=12,v(y,C,S,w,T,A,x,P),a(C)&&(b.normal=new l({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:C})),a(S)&&(b.tangent=new l({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:S})),a(w)&&(b.bitangent=new l({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:w})),a(T)&&(b.st=new l({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:T}))}for(var F=new Uint16Array(6*m),B=0;B<m;++B){var U=6*B,V=4*B;F[U]=V,F[U+1]=V+1,F[U+2]=V+2,F[U+3]=V,F[U+4]=V+2,F[U+5]=V+3}return new s({attributes:b,indices:F,primitiveType:f.TRIANGLES,boundingSphere:e.fromVertices(g)})},_}),define("Core/FrustumOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./FrustumGeometry","./Geometry","./GeometryAttribute","./GeometryAttributes","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e){var r,i,o=e.frustum,a=e.orientation,s=e.origin,l=n(e._drawNearPlane,!0);o instanceof d?(r=m,i=d.packedLength):o instanceof c&&(r=g,i=c.packedLength),this._frustumType=r,this._frustum=o.clone(),this._origin=t.clone(s),this._orientation=p.clone(a),this._drawNearPlane=l,this._workerName="createFrustumOutlineGeometry",this.packedLength=2+i+t.packedLength+p.packedLength}var m=0,g=1;f.pack=function(e,r,i){i=n(i,0);var o=e._frustumType,a=e._frustum;return r[i++]=o,o===m?(d.pack(a,r,i),i+=d.packedLength):(c.pack(a,r,i),i+=c.packedLength),t.pack(e._origin,r,i),i+=t.packedLength,p.pack(e._orientation,r,i),i+=p.packedLength,r[i]=e._drawNearPlane?1:0,r};var _=new d,v=new c,y=new p,b=new t;return f.unpack=function(e,r,i){r=n(r,0);var a,s=e[r++];s===m?(a=d.unpack(e,r,_),r+=d.packedLength):(a=c.unpack(e,r,v),r+=c.packedLength);var l=t.unpack(e,r,b);r+=t.packedLength;var u=p.unpack(e,r,y);r+=p.packedLength;var h=1===e[r];if(!o(i))return new f({frustum:a,origin:l,orientation:u,_drawNearPlane:h});var g=s===i._frustumType?i._frustum:void 0;return i._frustum=a.clone(g),i._frustumType=s,i._origin=t.clone(l,i._origin),i._orientation=p.clone(u,i._orientation),i._drawNearPlane=h,i},f.createGeometry=function(t){var r=t._frustumType,n=t._frustum,o=t._origin,c=t._orientation,d=t._drawNearPlane,p=new Float64Array(24);a._computeNearFarPlanes(o,c,r,n,p);for(var f,m,g=new u({position:new l({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:p})}),_=d?2:1,v=new Uint16Array(8*(_+1)),y=d?0:1;y<2;++y)f=d?8*y:0,m=4*y,v[f]=m,v[f+1]=m+1,v[f+2]=m+1,v[f+3]=m+2,v[f+4]=m+2,v[f+5]=m+3,v[f+6]=m+3,v[f+7]=m;for(y=0;y<2;++y)f=8*(_+y),m=4*y,v[f]=m,v[f+1]=m+4,v[f+2]=m+1,v[f+3]=m+5,v[f+4]=m+2,v[f+5]=m+6,v[f+6]=m+3,v[f+7]=m+7;return new s({attributes:g,indices:v,primitiveType:h.LINES,boundingSphere:e.fromVertices(p)})},f}),define("Core/GeocoderService",["./DeveloperError"],function(e){"use strict";function t(){}return t.prototype.geocode=e.throwInstantiationError,t}),define("Core/GeometryInstanceAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.value=t.value}return i}),define("Core/getFilenameFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(t){var r=new e(t);r.normalize();var i=r.path,n=i.lastIndexOf("/");return-1!==n&&(i=i.substr(n+1)),i}return i}),define("Core/getImagePixels",["./defined"],function(e){"use strict";function t(t,i,n){e(i)||(i=t.width),e(n)||(n=t.height);var o=r[i];e(o)||(o={},r[i]=o);var a=o[n];if(!e(a)){var s=document.createElement("canvas");s.width=i,s.height=n,a=s.getContext("2d"),a.globalCompositeOperation="copy",o[n]=a}return a.drawImage(t,0,0,i,n),a.getImageData(0,0,i,n).data}var r={};return t}),define("Core/getStringFromTypedArray",["./defaultValue","./defined","./DeveloperError","./RuntimeError"],function(e,t,r,i){"use strict";function n(t,r,i){return r=e(r,0),i=e(i,t.byteLength-r),t=t.subarray(r,r+i),n.decode(t)}function o(e,t,r){return t<=e&&e<=r}function a(e){for(var t=0,r=0,n=0,a=128,s=191,l=[],u=e.length,c=0;c<u;++c){var d=e[c];if(0===n){if(o(d,0,127)){l.push(d);continue}if(o(d,194,223)){n=1,t=31&d;continue}if(o(d,224,239)){224===d&&(a=160),237===d&&(s=159),n=2,t=15&d;continue}if(o(d,240,244)){240===d&&(a=144),244===d&&(s=143),n=3,t=7&d;continue}throw new i("String decoding failed.")}o(d,a,s)?(a=128,s=191,t=t<<6|63&d,++r===n&&(l.push(t),t=n=r=0)):(t=n=r=0,a=128,s=191,--c)}return l}return n.decodeWithTextDecoder=function(e){return new TextDecoder("utf-8").decode(e)},n.decodeWithFromCharCode=function(e){for(var t="",r=a(e),i=r.length,n=0;n<i;++n){var o=r[n];o<=65535?t+=String.fromCharCode(o):(o-=65536,t+=String.fromCharCode(55296+(o>>10),56320+(1023&o)))}return t},"undefined"!=typeof TextDecoder?n.decode=n.decodeWithTextDecoder:n.decode=n.decodeWithFromCharCode,n}),define("Core/getMagic",["./defaultValue","./getStringFromTypedArray"],function(e,t){"use strict";function r(r,i){return i=e(i,0),t(r,i,Math.min(4,r.length))}return r}),function(global,undefined){"use strict";!function(e,t,r){function i(r){var n=t[r];return n||e[r][0].call(n=t[r]={exports:{}},i,n,n.exports),n.exports}var n=global.protobuf=i(r[0]);"function"==typeof define&&define.amd&&define("ThirdParty/protobuf-minimal",[],function(){return n.configure(),n}),"object"==typeof module&&module&&module.exports&&(module.exports=n)}({1:[function(e,t,r){function i(e,t){for(var r=[],i=2;i<arguments.length;)r.push(arguments[i++]);var n=!0;return new Promise(function(i,o){r.push(function(e){if(n)if(n=!1,e)o(e);else{for(var t=[],r=1;r<arguments.length;)t.push(arguments[r++]);i.apply(null,t)}});try{e.apply(t||this,r)}catch(e){n&&(n=!1,o(e))}})}t.exports=i},{}],2:[function(e,t,r){var i=r;i.length=function(e){var t=e.length;if(!t)return 0;for(var r=0;--t%4>1&&"="===e.charAt(t);)++r;return Math.ceil(3*e.length)/4-r};for(var n=new Array(64),o=new Array(123),a=0;a<64;)o[n[a]=a<26?a+65:a<52?a+71:a<62?a-4:a-59|43]=a++;i.encode=function(e,t,r){for(var i,o=[],a=0,s=0;t<r;){var l=e[t++];switch(s){case 0:o[a++]=n[l>>2],i=(3&l)<<4,s=1;break;case 1:o[a++]=n[i|l>>4],i=(15&l)<<2,s=2;break;case 2:o[a++]=n[i|l>>6],o[a++]=n[63&l],s=0}}return s&&(o[a++]=n[i],o[a]=61,1===s&&(o[a+1]=61)),String.fromCharCode.apply(String,o)};i.decode=function(e,t,r){for(var i,n=r,a=0,s=0;s<e.length;){var l=e.charCodeAt(s++);if(61===l&&a>1)break;if((l=o[l])===undefined)throw Error("invalid encoding");switch(a){case 0:i=l,a=1;break;case 1:t[r++]=i<<2|(48&l)>>4,i=l,a=2;break;case 2:t[r++]=(15&i)<<4|(60&l)>>2,i=l,a=3;break;case 3:t[r++]=(3&i)<<6|l,a=0}}if(1===a)throw Error("invalid encoding");return r-n},i.test=function(e){return/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(e)}},{}],3:[function(e,t,r){function i(){this._listeners={}}t.exports=i,i.prototype.on=function(e,t,r){return(this._listeners[e]||(this._listeners[e]=[])).push({fn:t,ctx:r||this}),this},i.prototype.off=function(e,t){if(e===undefined)this._listeners={};else if(t===undefined)this._listeners[e]=[];else for(var r=this._listeners[e],i=0;i<r.length;)r[i].fn===t?r.splice(i,1):++i;return this},i.prototype.emit=function(e){var t=this._listeners[e];if(t){for(var r=[],i=1;i<arguments.length;)r.push(arguments[i++]);for(i=0;i<t.length;)t[i].fn.apply(t[i++].ctx,r)}return this}},{}],4:[function(require,module,exports){function inquire(moduleName){try{var mod=eval("quire".replace(/^/,"re"))(moduleName);if(mod&&(mod.length||Object.keys(mod).length))return mod}catch(e){}return null}module.exports=inquire},{}],5:[function(e,t,r){function i(e,t,r){var i=r||8192,n=i>>>1,o=null,a=i;return function(r){if(r<1||r>n)return e(r);a+r>i&&(o=e(i),a=0);var s=t.call(o,a,a+=r);return 7&a&&(a=1+(7|a)),s}}t.exports=i},{}],6:[function(e,t,r){var i=r;i.length=function(e){for(var t=0,r=0,i=0;i<e.length;++i)r=e.charCodeAt(i),r<128?t+=1:r<2048?t+=2:55296==(64512&r)&&56320==(64512&e.charCodeAt(i+1))?(++i,t+=4):t+=3;return t},i.read=function(e,t,r){if(r-t<1)return"";for(var i,n=null,o=[],a=0;t<r;)i=e[t++],i<128?o[a++]=i:i>191&&i<224?o[a++]=(31&i)<<6|63&e[t++]:i>239&&i<365?(i=((7&i)<<18|(63&e[t++])<<12|(63&e[t++])<<6|63&e[t++])-65536,o[a++]=55296+(i>>10),o[a++]=56320+(1023&i)):o[a++]=(15&i)<<12|(63&e[t++])<<6|63&e[t++],a>8191&&((n||(n=[])).push(String.fromCharCode.apply(String,o)),a=0);return n?(a&&n.push(String.fromCharCode.apply(String,o.slice(0,a))),n.join("")):String.fromCharCode.apply(String,o.slice(0,a))},i.write=function(e,t,r){for(var i,n,o=r,a=0;a<e.length;++a)i=e.charCodeAt(a),i<128?t[r++]=i:i<2048?(t[r++]=i>>6|192,t[r++]=63&i|128):55296==(64512&i)&&56320==(64512&(n=e.charCodeAt(a+1)))?(i=65536+((1023&i)<<10)+(1023&n),++a,t[r++]=i>>18|240,t[r++]=i>>12&63|128,t[r++]=i>>6&63|128,t[r++]=63&i|128):(t[r++]=i>>12|224,t[r++]=i>>6&63|128,t[r++]=63&i|128);return r-o}},{}],7:[function(e,t,r){function i(){n.Reader._configure(n.BufferReader),n.util._configure()}var n=r;n.build="minimal",n.roots={},n.Writer=e(14),n.BufferWriter=e(15),n.Reader=e(8),n.BufferReader=e(9),n.util=e(13),n.rpc=e(10),n.configure=i,n.Writer._configure(n.BufferWriter),i()},{10:10,13:13,14:14,15:15,8:8,9:9}],8:[function(e,t,r){function i(e,t){return RangeError("index out of range: "+e.pos+" + "+(t||1)+" > "+e.len)}function n(e){this.buf=e,this.pos=0,this.len=e.length}function o(){var e=new c(0,0),t=0;if(!(this.len-this.pos>4)){for(;t<3;++t){if(this.pos>=this.len)throw i(this);if(e.lo=(e.lo|(127&this.buf[this.pos])<<7*t)>>>0,this.buf[this.pos++]<128)return e}return e.lo=(e.lo|(127&this.buf[this.pos++])<<7*t)>>>0,e}for(;t<4;++t)if(e.lo=(e.lo|(127&this.buf[this.pos])<<7*t)>>>0,this.buf[this.pos++]<128)return e;if(e.lo=(e.lo|(127&this.buf[this.pos])<<28)>>>0,e.hi=(e.hi|(127&this.buf[this.pos])>>4)>>>0,this.buf[this.pos++]<128)return e;if(t=0,this.len-this.pos>4){for(;t<5;++t)if(e.hi=(e.hi|(127&this.buf[this.pos])<<7*t+3)>>>0,this.buf[this.pos++]<128)return e}else for(;t<5;++t){if(this.pos>=this.len)throw i(this);if(e.hi=(e.hi|(127&this.buf[this.pos])<<7*t+3)>>>0,this.buf[this.pos++]<128)return e}throw Error("invalid varint encoding")}function a(e,t){return(e[t-4]|e[t-3]<<8|e[t-2]<<16|e[t-1]<<24)>>>0}function s(){if(this.pos+8>this.len)throw i(this,8);return new c(a(this.buf,this.pos+=4),a(this.buf,this.pos+=4))}t.exports=n;var l,u=e(13),c=u.LongBits,d=u.utf8,h="undefined"!=typeof Uint8Array?function(e){if(e instanceof Uint8Array||Array.isArray(e))return new n(e);throw Error("illegal buffer")}:function(e){if(Array.isArray(e))return new n(e);throw Error("illegal buffer")};n.create=u.Buffer?function(e){return(n.create=function(e){return u.Buffer.isBuffer(e)?new l(e):h(e)})(e)}:h,n.prototype._slice=u.Array.prototype.subarray||u.Array.prototype.slice,n.prototype.uint32=function(){var e=4294967295;return function(){if(e=(127&this.buf[this.pos])>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(127&this.buf[this.pos])<<7)>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(127&this.buf[this.pos])<<14)>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(127&this.buf[this.pos])<<21)>>>0,this.buf[this.pos++]<128)return e;if(e=(e|(15&this.buf[this.pos])<<28)>>>0,this.buf[this.pos++]<128)return e;if((this.pos+=5)>this.len)throw this.pos=this.len,i(this,10);return e}}(),n.prototype.int32=function(){return 0|this.uint32()},n.prototype.sint32=function(){var e=this.uint32();return e>>>1^-(1&e)|0},n.prototype.bool=function(){return 0!==this.uint32()},n.prototype.fixed32=function(){if(this.pos+4>this.len)throw i(this,4);return a(this.buf,this.pos+=4)},n.prototype.sfixed32=function(){if(this.pos+4>this.len)throw i(this,4);return 0|a(this.buf,this.pos+=4)};var p="undefined"!=typeof Float32Array?function(){var e=new Float32Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[3]?function(r,i){return t[0]=r[i],t[1]=r[i+1],t[2]=r[i+2],t[3]=r[i+3],e[0]}:function(r,i){return t[0]=r[i+3],t[1]=r[i+2],t[2]=r[i+1],t[3]=r[i],e[0]}}():function(e,t){var r=a(e,t+4),i=2*(r>>31)+1,n=r>>>23&255,o=8388607&r;return 255===n?o?NaN:i*(1/0):0===n?1.401298464324817e-45*i*o:i*Math.pow(2,n-150)*(o+8388608)};n.prototype.float=function(){if(this.pos+4>this.len)throw i(this,4);var e=p(this.buf,this.pos);return this.pos+=4,e};var f="undefined"!=typeof Float64Array?function(){var e=new Float64Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[7]?function(r,i){return t[0]=r[i],t[1]=r[i+1],t[2]=r[i+2],t[3]=r[i+3],t[4]=r[i+4],t[5]=r[i+5],t[6]=r[i+6],t[7]=r[i+7],e[0]}:function(r,i){return t[0]=r[i+7],t[1]=r[i+6],t[2]=r[i+5],t[3]=r[i+4],t[4]=r[i+3],t[5]=r[i+2],t[6]=r[i+1],t[7]=r[i],e[0]}}():function(e,t){var r=a(e,t+4),i=a(e,t+8),n=2*(i>>31)+1,o=i>>>20&2047,s=4294967296*(1048575&i)+r;return 2047===o?s?NaN:n*(1/0):0===o?5e-324*n*s:n*Math.pow(2,o-1075)*(s+4503599627370496)};n.prototype.double=function(){if(this.pos+8>this.len)throw i(this,4);var e=f(this.buf,this.pos);return this.pos+=8,e},n.prototype.bytes=function(){var e=this.uint32(),t=this.pos,r=this.pos+e;if(r>this.len)throw i(this,e);return this.pos+=e,t===r?new this.buf.constructor(0):this._slice.call(this.buf,t,r)},n.prototype.string=function(){var e=this.bytes();return d.read(e,0,e.length)},n.prototype.skip=function(e){if("number"==typeof e){if(this.pos+e>this.len)throw i(this,e);this.pos+=e}else do{if(this.pos>=this.len)throw i(this)}while(128&this.buf[this.pos++]);return this},n.prototype.skipType=function(e){switch(e){case 0:this.skip();break;case 1:this.skip(8);break;case 2:this.skip(this.uint32());break;case 3:for(;;){if(4==(e=7&this.uint32()))break;this.skipType(e)}break;case 5:this.skip(4);break;default:throw Error("invalid wire type "+e+" at offset "+this.pos)}return this},n._configure=function(e){l=e;var t=u.Long?"toLong":"toNumber";u.merge(n.prototype,{int64:function(){return o.call(this)[t](!1)},uint64:function(){return o.call(this)[t](!0)},sint64:function(){return o.call(this).zzDecode()[t](!1)},fixed64:function(){return s.call(this)[t](!0)},sfixed64:function(){return s.call(this)[t](!1)}})}},{13:13}],9:[function(e,t,r){function i(e){n.call(this,e)}t.exports=i;var n=e(8);(i.prototype=Object.create(n.prototype)).constructor=i;var o=e(13);o.Buffer&&(i.prototype._slice=o.Buffer.prototype.slice),i.prototype.string=function(){var e=this.uint32();return this.buf.utf8Slice(this.pos,this.pos=Math.min(this.pos+e,this.len))}},{13:13,8:8}],10:[function(e,t,r){r.Service=e(11)},{11:11}],11:[function(e,t,r){function i(e,t,r){if("function"!=typeof e)throw TypeError("rpcImpl must be a function");n.EventEmitter.call(this),this.rpcImpl=e,this.requestDelimited=Boolean(t),this.responseDelimited=Boolean(r)}t.exports=i;var n=e(13);(i.prototype=Object.create(n.EventEmitter.prototype)).constructor=i,i.prototype.rpcCall=function e(t,r,i,o,a){if(!o)throw TypeError("request must be specified");var s=this;if(!a)return n.asPromise(e,s,t,r,i,o);if(!s.rpcImpl)return setTimeout(function(){a(Error("already ended"))},0),undefined;try{return s.rpcImpl(t,r[s.requestDelimited?"encodeDelimited":"encode"](o).finish(),function(e,r){if(e)return s.emit("error",e,t),a(e);if(null===r)return s.end(!0),undefined;if(!(r instanceof i))try{r=i[s.responseDelimited?"decodeDelimited":"decode"](r)}catch(e){return s.emit("error",e,t),a(e)}return s.emit("data",r,t),a(null,r)})}catch(e){return s.emit("error",e,t),setTimeout(function(){a(e)},0),undefined}},i.prototype.end=function(e){return this.rpcImpl&&(e||this.rpcImpl(null,null,null),this.rpcImpl=null,this.emit("end").off()),this}},{13:13}],12:[function(e,t,r){function i(e,t){this.lo=e>>>0,this.hi=t>>>0}t.exports=i;var n=e(13),o=i.zero=new i(0,0);o.toNumber=function(){return 0},o.zzEncode=o.zzDecode=function(){return this},o.length=function(){return 1};var a=i.zeroHash="\0\0\0\0\0\0\0\0";i.fromNumber=function(e){if(0===e)return o;var t=e<0;t&&(e=-e);var r=e>>>0,n=(e-r)/4294967296>>>0;return t&&(n=~n>>>0,r=~r>>>0,++r>4294967295&&(r=0,++n>4294967295&&(n=0))),new i(r,n)},i.from=function(e){if("number"==typeof e)return i.fromNumber(e);if(n.isString(e)){if(!n.Long)return i.fromNumber(parseInt(e,10));e=n.Long.fromString(e)}return e.low||e.high?new i(e.low>>>0,e.high>>>0):o},i.prototype.toNumber=function(e){if(!e&&this.hi>>>31){var t=1+~this.lo>>>0,r=~this.hi>>>0;return t||(r=r+1>>>0),-(t+4294967296*r)}return this.lo+4294967296*this.hi},i.prototype.toLong=function(e){return n.Long?new n.Long(0|this.lo,0|this.hi,Boolean(e)):{low:0|this.lo,high:0|this.hi,unsigned:Boolean(e)}};var s=String.prototype.charCodeAt;i.fromHash=function(e){return e===a?o:new i((s.call(e,0)|s.call(e,1)<<8|s.call(e,2)<<16|s.call(e,3)<<24)>>>0,(s.call(e,4)|s.call(e,5)<<8|s.call(e,6)<<16|s.call(e,7)<<24)>>>0)},i.prototype.toHash=function(){return String.fromCharCode(255&this.lo,this.lo>>>8&255,this.lo>>>16&255,this.lo>>>24,255&this.hi,this.hi>>>8&255,this.hi>>>16&255,this.hi>>>24)},i.prototype.zzEncode=function(){var e=this.hi>>31;return this.hi=((this.hi<<1|this.lo>>>31)^e)>>>0,this.lo=(this.lo<<1^e)>>>0,this},i.prototype.zzDecode=function(){var e=-(1&this.lo);return this.lo=((this.lo>>>1|this.hi<<31)^e)>>>0,this.hi=(this.hi>>>1^e)>>>0,this},i.prototype.length=function(){var e=this.lo,t=(this.lo>>>28|this.hi<<4)>>>0,r=this.hi>>>24;return 0===r?0===t?e<16384?e<128?1:2:e<2097152?3:4:t<16384?t<128?5:6:t<2097152?7:8:r<128?9:10}},{13:13}],13:[function(e,t,r){function i(e,t,r){for(var i=Object.keys(t),n=0;n<i.length;++n)e[i[n]]!==undefined&&r||(e[i[n]]=t[i[n]]);return e}function n(e){function t(e,r){if(!(this instanceof t))return new t(e,r);Object.defineProperty(this,"message",{get:function(){return e}}),Error.captureStackTrace?Error.captureStackTrace(this,t):Object.defineProperty(this,"stack",{value:(new Error).stack||""}),r&&i(this,r)}return(t.prototype=Object.create(Error.prototype)).constructor=t,Object.defineProperty(t.prototype,"name",{get:function(){return e}}),t.prototype.toString=function(){return this.name+": "+this.message},t}var o=r;o.asPromise=e(1),o.base64=e(2),o.EventEmitter=e(3),o.inquire=e(4),o.utf8=e(6),o.pool=e(5),o.LongBits=e(12),o.emptyArray=Object.freeze?Object.freeze([]):[],o.emptyObject=Object.freeze?Object.freeze({}):{},o.isNode=Boolean(global.process&&global.process.versions&&global.process.versions.node),o.isInteger=Number.isInteger||function(e){return"number"==typeof e&&isFinite(e)&&Math.floor(e)===e},o.isString=function(e){return"string"==typeof e||e instanceof String},o.isObject=function(e){return e&&"object"==typeof e},o.Buffer=function(){try{var e=o.inquire("buffer").Buffer;return e.prototype.utf8Write?e:null}catch(e){return null}}(),o._Buffer_from=null,o._Buffer_allocUnsafe=null,o.newBuffer=function(e){return"number"==typeof e?o.Buffer?o._Buffer_allocUnsafe(e):new o.Array(e):o.Buffer?o._Buffer_from(e):"undefined"==typeof Uint8Array?e:new Uint8Array(e)},o.Array="undefined"!=typeof Uint8Array?Uint8Array:Array,o.Long=global.dcodeIO&&global.dcodeIO.Long||o.inquire("long"),o.key2Re=/^true|false|0|1$/,o.key32Re=/^-?(?:0|[1-9][0-9]*)$/,o.key64Re=/^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/,o.longToHash=function(e){return e?o.LongBits.from(e).toHash():o.LongBits.zeroHash},o.longFromHash=function(e,t){var r=o.LongBits.fromHash(e);return o.Long?o.Long.fromBits(r.lo,r.hi,t):r.toNumber(Boolean(t))},o.merge=i,o.lcFirst=function(e){return e.charAt(0).toLowerCase()+e.substring(1)},o.newError=n,o.ProtocolError=n("ProtocolError"),o.oneOfGetter=function(e){for(var t={},r=0;r<e.length;++r)t[e[r]]=1;return function(){for(var e=Object.keys(this),r=e.length-1;r>-1;--r)if(1===t[e[r]]&&this[e[r]]!==undefined&&null!==this[e[r]])return e[r]}},o.oneOfSetter=function(e){return function(t){for(var r=0;r<e.length;++r)e[r]!==t&&delete this[e[r]]}},o.lazyResolve=function(e,t){for(var r=0;r<t.length;++r)for(var i=Object.keys(t[r]),n=0;n<i.length;++n){for(var o=t[r][i[n]].split("."),a=e;o.length;)a=a[o.shift()];t[r][i[n]]=a}},o.toJSONOptions={longs:String,enums:String,bytes:String},o._configure=function(){var e=o.Buffer;if(!e)return void(o._Buffer_from=o._Buffer_allocUnsafe=null);o._Buffer_from=e.from!==Uint8Array.from&&e.from||function(t,r){return new e(t,r)},o._Buffer_allocUnsafe=e.allocUnsafe||function(t){return new e(t)}}},{1:1,12:12,2:2,3:3,4:4,5:5,6:6}],14:[function(e,t,r){function i(e,t,r){this.fn=e,this.len=t,this.next=undefined,this.val=r}function n(){}function o(e){this.head=e.head,this.tail=e.tail,this.len=e.len,this.next=e.states}function a(){this.len=0,this.head=new i(n,0,0),this.tail=this.head,this.states=null}function s(e,t,r){t[r]=255&e}function l(e,t,r){for(;e>127;)t[r++]=127&e|128,e>>>=7;t[r]=e}function u(e,t){this.len=e,this.next=undefined,this.val=t}function c(e,t,r){for(;e.hi;)t[r++]=127&e.lo|128,e.lo=(e.lo>>>7|e.hi<<25)>>>0,e.hi>>>=7;for(;e.lo>127;)t[r++]=127&e.lo|128,e.lo=e.lo>>>7;t[r++]=e.lo}function d(e,t,r){t[r++]=255&e,t[r++]=e>>>8&255,t[r++]=e>>>16&255,t[r]=e>>>24}t.exports=a;var h,p=e(13),f=p.LongBits,m=p.base64,g=p.utf8;a.create=p.Buffer?function(){return(a.create=function(){return new h})()}:function(){return new a},a.alloc=function(e){return new p.Array(e)},p.Array!==Array&&(a.alloc=p.pool(a.alloc,p.Array.prototype.subarray)),a.prototype.push=function(e,t,r){return this.tail=this.tail.next=new i(e,t,r),this.len+=t,this},u.prototype=Object.create(i.prototype),u.prototype.fn=l,a.prototype.uint32=function(e){return this.len+=(this.tail=this.tail.next=new u((e>>>=0)<128?1:e<16384?2:e<2097152?3:e<268435456?4:5,e)).len,this},a.prototype.int32=function(e){return e<0?this.push(c,10,f.fromNumber(e)):this.uint32(e)},a.prototype.sint32=function(e){return this.uint32((e<<1^e>>31)>>>0)},a.prototype.uint64=function(e){var t=f.from(e);return this.push(c,t.length(),t)},a.prototype.int64=a.prototype.uint64,a.prototype.sint64=function(e){var t=f.from(e).zzEncode();return this.push(c,t.length(),t)},a.prototype.bool=function(e){return this.push(s,1,e?1:0)},a.prototype.fixed32=function(e){return this.push(d,4,e>>>0)},a.prototype.sfixed32=a.prototype.fixed32,a.prototype.fixed64=function(e){var t=f.from(e);return this.push(d,4,t.lo).push(d,4,t.hi)},a.prototype.sfixed64=a.prototype.fixed64;var _="undefined"!=typeof Float32Array?function(){var e=new Float32Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[3]?function(r,i,n){e[0]=r,i[n++]=t[0],i[n++]=t[1],i[n++]=t[2],i[n]=t[3]}:function(r,i,n){e[0]=r,i[n++]=t[3],i[n++]=t[2],i[n++]=t[1],i[n]=t[0]}}():function(e,t,r){var i=e<0?1:0;if(i&&(e=-e),0===e)d(1/e>0?0:2147483648,t,r);else if(isNaN(e))d(2147483647,t,r);else if(e>3.4028234663852886e38)d((i<<31|2139095040)>>>0,t,r);else if(e<1.1754943508222875e-38)d((i<<31|Math.round(e/1.401298464324817e-45))>>>0,t,r);else{var n=Math.floor(Math.log(e)/Math.LN2),o=8388607&Math.round(e*Math.pow(2,-n)*8388608);d((i<<31|n+127<<23|o)>>>0,t,r)}};a.prototype.float=function(e){return this.push(_,4,e)};var v="undefined"!=typeof Float64Array?function(){var e=new Float64Array(1),t=new Uint8Array(e.buffer);return e[0]=-0,t[7]?function(r,i,n){e[0]=r,i[n++]=t[0],i[n++]=t[1],i[n++]=t[2],i[n++]=t[3],i[n++]=t[4],i[n++]=t[5],i[n++]=t[6],i[n]=t[7]}:function(r,i,n){e[0]=r,i[n++]=t[7],i[n++]=t[6],i[n++]=t[5],i[n++]=t[4],i[n++]=t[3],i[n++]=t[2],i[n++]=t[1],i[n]=t[0]}}():function(e,t,r){var i=e<0?1:0;if(i&&(e=-e),0===e)d(0,t,r),d(1/e>0?0:2147483648,t,r+4);else if(isNaN(e))d(4294967295,t,r),d(2147483647,t,r+4);else if(e>1.7976931348623157e308)d(0,t,r),d((i<<31|2146435072)>>>0,t,r+4);else{var n;if(e<2.2250738585072014e-308)n=e/5e-324,d(n>>>0,t,r),d((i<<31|n/4294967296)>>>0,t,r+4);else{var o=Math.floor(Math.log(e)/Math.LN2);1024===o&&(o=1023),n=e*Math.pow(2,-o),d(4503599627370496*n>>>0,t,r),d((i<<31|o+1023<<20|1048576*n&1048575)>>>0,t,r+4)}}};a.prototype.double=function(e){return this.push(v,8,e)};var y=p.Array.prototype.set?function(e,t,r){t.set(e,r)}:function(e,t,r){for(var i=0;i<e.length;++i)t[r+i]=e[i]};a.prototype.bytes=function(e){var t=e.length>>>0;if(!t)return this.push(s,1,0);if(p.isString(e)){var r=a.alloc(t=m.length(e));m.decode(e,r,0),e=r}return this.uint32(t).push(y,t,e)},a.prototype.string=function(e){var t=g.length(e);return t?this.uint32(t).push(g.write,t,e):this.push(s,1,0)},a.prototype.fork=function(){return this.states=new o(this),this.head=this.tail=new i(n,0,0),this.len=0,this},a.prototype.reset=function(){return this.states?(this.head=this.states.head,this.tail=this.states.tail,this.len=this.states.len,this.states=this.states.next):(this.head=this.tail=new i(n,0,0),this.len=0),this},a.prototype.ldelim=function(){var e=this.head,t=this.tail,r=this.len;return this.reset().uint32(r),r&&(this.tail.next=e.next,this.tail=t,this.len+=r),this},a.prototype.finish=function(){for(var e=this.head.next,t=this.constructor.alloc(this.len),r=0;e;)e.fn(e.val,t,r),r+=e.len,e=e.next;return t},a._configure=function(e){h=e}},{13:13}],15:[function(e,t,r){function i(){o.call(this)}function n(e,t,r){e.length<40?a.utf8.write(e,t,r):t.utf8Write(e,r)}t.exports=i;var o=e(14) +;(i.prototype=Object.create(o.prototype)).constructor=i;var a=e(13),s=a.Buffer;i.alloc=function(e){return(i.alloc=a._Buffer_allocUnsafe)(e)};var l=s&&s.prototype instanceof Uint8Array&&"set"===s.prototype.set.name?function(e,t,r){t.set(e,r)}:function(e,t,r){if(e.copy)e.copy(t,r,0,e.length);else for(var i=0;i<e.length;)t[r++]=e[i++]};i.prototype.bytes=function(e){a.isString(e)&&(e=a._Buffer_from(e,"base64"));var t=e.length>>>0;return this.uint32(t),t&&this.push(l,t,e),this},i.prototype.string=function(e){var t=s.byteLength(e);return this.uint32(t),t&&this.push(n,t,e),this}},{13:13,14:14}]},{},[7])}("object"==typeof window&&window||"object"==typeof self&&self||this),define("ThirdParty/google-earth-dbroot-parser",["./protobuf-minimal"],function(e){"use strict";var t=e.Reader,r=(e.Writer,e.util),i=[],n=e.roots.default||(e.roots.default={});return n.keyhole=function(){var o={};return o.dbroot=function(){var o={};return o.StringEntryProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.stringId=0,i.prototype.stringValue="",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.StringEntryProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.stringId=e.fixed32();break;case 2:o.stringValue=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isInteger(e.stringId)?r.isString(e.stringValue)?null:"stringValue: string expected":"stringId: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.StringEntryProto)return e;var t=new n.keyhole.dbroot.StringEntryProto;return void 0!==e.stringId&&null!==e.stringId&&(t.stringId=e.stringId>>>0),void 0!==e.stringValue&&null!==e.stringValue&&(t.stringValue=String(e.stringValue)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.stringId=0,r.stringValue=""),void 0!==e.stringId&&null!==e.stringId&&e.hasOwnProperty("stringId")&&(r.stringId=e.stringId),void 0!==e.stringValue&&null!==e.stringValue&&e.hasOwnProperty("stringValue")&&(r.stringValue=e.stringValue),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.StringIdOrValueProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.stringId=0,i.prototype.value="",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.StringIdOrValueProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.stringId=e.fixed32();break;case 2:o.value=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.stringId||r.isInteger(e.stringId)?void 0===e.value||r.isString(e.value)?null:"value: string expected":"stringId: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.StringIdOrValueProto)return e;var t=new n.keyhole.dbroot.StringIdOrValueProto;return void 0!==e.stringId&&null!==e.stringId&&(t.stringId=e.stringId>>>0),void 0!==e.value&&null!==e.value&&(t.value=String(e.value)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.stringId=0,r.value=""),void 0!==e.stringId&&null!==e.stringId&&e.hasOwnProperty("stringId")&&(r.stringId=e.stringId),void 0!==e.value&&null!==e.value&&e.hasOwnProperty("value")&&(r.value=e.value),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.PlanetModelProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.radius=6378.137,i.prototype.flattening=.00335281066474748,i.prototype.elevationBias=0,i.prototype.negativeAltitudeExponentBias=0,i.prototype.compressedNegativeAltitudeThreshold=0,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.PlanetModelProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.radius=e.double();break;case 2:o.flattening=e.double();break;case 4:o.elevationBias=e.double();break;case 5:o.negativeAltitudeExponentBias=e.int32();break;case 6:o.compressedNegativeAltitudeThreshold=e.double();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.radius&&"number"!=typeof e.radius?"radius: number expected":void 0!==e.flattening&&"number"!=typeof e.flattening?"flattening: number expected":void 0!==e.elevationBias&&"number"!=typeof e.elevationBias?"elevationBias: number expected":void 0===e.negativeAltitudeExponentBias||r.isInteger(e.negativeAltitudeExponentBias)?void 0!==e.compressedNegativeAltitudeThreshold&&"number"!=typeof e.compressedNegativeAltitudeThreshold?"compressedNegativeAltitudeThreshold: number expected":null:"negativeAltitudeExponentBias: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PlanetModelProto)return e;var t=new n.keyhole.dbroot.PlanetModelProto;return void 0!==e.radius&&null!==e.radius&&(t.radius=Number(e.radius)),void 0!==e.flattening&&null!==e.flattening&&(t.flattening=Number(e.flattening)),void 0!==e.elevationBias&&null!==e.elevationBias&&(t.elevationBias=Number(e.elevationBias)),void 0!==e.negativeAltitudeExponentBias&&null!==e.negativeAltitudeExponentBias&&(t.negativeAltitudeExponentBias=0|e.negativeAltitudeExponentBias),void 0!==e.compressedNegativeAltitudeThreshold&&null!==e.compressedNegativeAltitudeThreshold&&(t.compressedNegativeAltitudeThreshold=Number(e.compressedNegativeAltitudeThreshold)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.radius=6378.137,r.flattening=.00335281066474748,r.elevationBias=0,r.negativeAltitudeExponentBias=0,r.compressedNegativeAltitudeThreshold=0),void 0!==e.radius&&null!==e.radius&&e.hasOwnProperty("radius")&&(r.radius=e.radius),void 0!==e.flattening&&null!==e.flattening&&e.hasOwnProperty("flattening")&&(r.flattening=e.flattening),void 0!==e.elevationBias&&null!==e.elevationBias&&e.hasOwnProperty("elevationBias")&&(r.elevationBias=e.elevationBias),void 0!==e.negativeAltitudeExponentBias&&null!==e.negativeAltitudeExponentBias&&e.hasOwnProperty("negativeAltitudeExponentBias")&&(r.negativeAltitudeExponentBias=e.negativeAltitudeExponentBias),void 0!==e.compressedNegativeAltitudeThreshold&&null!==e.compressedNegativeAltitudeThreshold&&e.hasOwnProperty("compressedNegativeAltitudeThreshold")&&(r.compressedNegativeAltitudeThreshold=e.compressedNegativeAltitudeThreshold),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.ProviderInfoProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.providerId=0,o.prototype.copyrightString=null,o.prototype.verticalPixelOffset=-1;var a={1:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ProviderInfoProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.providerId=e.int32();break;case 2:o.copyrightString=a[1].decode(e,e.uint32());break;case 3:o.verticalPixelOffset=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isInteger(e.providerId))return"providerId: integer expected";if(void 0!==e.copyrightString&&null!==e.copyrightString){var t=a[1].verify(e.copyrightString);if(t)return"copyrightString."+t}return void 0===e.verticalPixelOffset||r.isInteger(e.verticalPixelOffset)?null:"verticalPixelOffset: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ProviderInfoProto)return e;var t=new n.keyhole.dbroot.ProviderInfoProto;if(void 0!==e.providerId&&null!==e.providerId&&(t.providerId=0|e.providerId),void 0!==e.copyrightString&&null!==e.copyrightString){if("object"!=typeof e.copyrightString)throw TypeError(".keyhole.dbroot.ProviderInfoProto.copyrightString: object expected");t.copyrightString=a[1].fromObject(e.copyrightString)}return void 0!==e.verticalPixelOffset&&null!==e.verticalPixelOffset&&(t.verticalPixelOffset=0|e.verticalPixelOffset),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.providerId=0,r.copyrightString=null,r.verticalPixelOffset=-1),void 0!==e.providerId&&null!==e.providerId&&e.hasOwnProperty("providerId")&&(r.providerId=e.providerId),void 0!==e.copyrightString&&null!==e.copyrightString&&e.hasOwnProperty("copyrightString")&&(r.copyrightString=a[1].toObject(e.copyrightString,t)),void 0!==e.verticalPixelOffset&&null!==e.verticalPixelOffset&&e.hasOwnProperty("verticalPixelOffset")&&(r.verticalPixelOffset=e.verticalPixelOffset),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.PopUpProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.isBalloonStyle=!1,o.prototype.text=null,o.prototype.backgroundColorAbgr=4294967295,o.prototype.textColorAbgr=4278190080;var a={1:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.PopUpProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.isBalloonStyle=e.bool();break;case 2:o.text=a[1].decode(e,e.uint32());break;case 3:o.backgroundColorAbgr=e.fixed32();break;case 4:o.textColorAbgr=e.fixed32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.isBalloonStyle&&"boolean"!=typeof e.isBalloonStyle)return"isBalloonStyle: boolean expected";if(void 0!==e.text&&null!==e.text){var t=a[1].verify(e.text);if(t)return"text."+t}return void 0===e.backgroundColorAbgr||r.isInteger(e.backgroundColorAbgr)?void 0===e.textColorAbgr||r.isInteger(e.textColorAbgr)?null:"textColorAbgr: integer expected":"backgroundColorAbgr: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PopUpProto)return e;var t=new n.keyhole.dbroot.PopUpProto;if(void 0!==e.isBalloonStyle&&null!==e.isBalloonStyle&&(t.isBalloonStyle=Boolean(e.isBalloonStyle)),void 0!==e.text&&null!==e.text){if("object"!=typeof e.text)throw TypeError(".keyhole.dbroot.PopUpProto.text: object expected");t.text=a[1].fromObject(e.text)}return void 0!==e.backgroundColorAbgr&&null!==e.backgroundColorAbgr&&(t.backgroundColorAbgr=e.backgroundColorAbgr>>>0),void 0!==e.textColorAbgr&&null!==e.textColorAbgr&&(t.textColorAbgr=e.textColorAbgr>>>0),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.isBalloonStyle=!1,r.text=null,r.backgroundColorAbgr=4294967295,r.textColorAbgr=4278190080),void 0!==e.isBalloonStyle&&null!==e.isBalloonStyle&&e.hasOwnProperty("isBalloonStyle")&&(r.isBalloonStyle=e.isBalloonStyle),void 0!==e.text&&null!==e.text&&e.hasOwnProperty("text")&&(r.text=a[1].toObject(e.text,t)),void 0!==e.backgroundColorAbgr&&null!==e.backgroundColorAbgr&&e.hasOwnProperty("backgroundColorAbgr")&&(r.backgroundColorAbgr=e.backgroundColorAbgr),void 0!==e.textColorAbgr&&null!==e.textColorAbgr&&e.hasOwnProperty("textColorAbgr")&&(r.textColorAbgr=e.textColorAbgr),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.StyleAttributeProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.styleId="",o.prototype.providerId=0,o.prototype.polyColorAbgr=4294967295,o.prototype.lineColorAbgr=4294967295,o.prototype.lineWidth=1,o.prototype.labelColorAbgr=4294967295,o.prototype.labelScale=1,o.prototype.placemarkIconColorAbgr=4294967295,o.prototype.placemarkIconScale=1,o.prototype.placemarkIconPath=null,o.prototype.placemarkIconX=0,o.prototype.placemarkIconY=0,o.prototype.placemarkIconWidth=32,o.prototype.placemarkIconHeight=32,o.prototype.popUp=null,o.prototype.drawFlag=r.emptyArray;var a={9:"keyhole.dbroot.StringIdOrValueProto",14:"keyhole.dbroot.PopUpProto",15:"keyhole.dbroot.DrawFlagProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.StyleAttributeProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.styleId=e.string();break;case 3:o.providerId=e.int32();break;case 4:o.polyColorAbgr=e.fixed32();break;case 5:o.lineColorAbgr=e.fixed32();break;case 6:o.lineWidth=e.float();break;case 7:o.labelColorAbgr=e.fixed32();break;case 8:o.labelScale=e.float();break;case 9:o.placemarkIconColorAbgr=e.fixed32();break;case 10:o.placemarkIconScale=e.float();break;case 11:o.placemarkIconPath=a[9].decode(e,e.uint32());break;case 12:o.placemarkIconX=e.int32();break;case 13:o.placemarkIconY=e.int32();break;case 14:o.placemarkIconWidth=e.int32();break;case 15:o.placemarkIconHeight=e.int32();break;case 16:o.popUp=a[14].decode(e,e.uint32());break;case 17:o.drawFlag&&o.drawFlag.length||(o.drawFlag=[]),o.drawFlag.push(a[15].decode(e,e.uint32()));break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.styleId))return"styleId: string expected";if(void 0!==e.providerId&&!r.isInteger(e.providerId))return"providerId: integer expected";if(void 0!==e.polyColorAbgr&&!r.isInteger(e.polyColorAbgr))return"polyColorAbgr: integer expected";if(void 0!==e.lineColorAbgr&&!r.isInteger(e.lineColorAbgr))return"lineColorAbgr: integer expected";if(void 0!==e.lineWidth&&"number"!=typeof e.lineWidth)return"lineWidth: number expected";if(void 0!==e.labelColorAbgr&&!r.isInteger(e.labelColorAbgr))return"labelColorAbgr: integer expected";if(void 0!==e.labelScale&&"number"!=typeof e.labelScale)return"labelScale: number expected";if(void 0!==e.placemarkIconColorAbgr&&!r.isInteger(e.placemarkIconColorAbgr))return"placemarkIconColorAbgr: integer expected";if(void 0!==e.placemarkIconScale&&"number"!=typeof e.placemarkIconScale)return"placemarkIconScale: number expected";if(void 0!==e.placemarkIconPath&&null!==e.placemarkIconPath){var t=a[9].verify(e.placemarkIconPath);if(t)return"placemarkIconPath."+t}if(void 0!==e.placemarkIconX&&!r.isInteger(e.placemarkIconX))return"placemarkIconX: integer expected";if(void 0!==e.placemarkIconY&&!r.isInteger(e.placemarkIconY))return"placemarkIconY: integer expected";if(void 0!==e.placemarkIconWidth&&!r.isInteger(e.placemarkIconWidth))return"placemarkIconWidth: integer expected";if(void 0!==e.placemarkIconHeight&&!r.isInteger(e.placemarkIconHeight))return"placemarkIconHeight: integer expected";if(void 0!==e.popUp&&null!==e.popUp){var t=a[14].verify(e.popUp);if(t)return"popUp."+t}if(void 0!==e.drawFlag){if(!Array.isArray(e.drawFlag))return"drawFlag: array expected";for(var i=0;i<e.drawFlag.length;++i){var t=a[15].verify(e.drawFlag[i]);if(t)return"drawFlag."+t}}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.StyleAttributeProto)return e;var t=new n.keyhole.dbroot.StyleAttributeProto;if(void 0!==e.styleId&&null!==e.styleId&&(t.styleId=String(e.styleId)),void 0!==e.providerId&&null!==e.providerId&&(t.providerId=0|e.providerId),void 0!==e.polyColorAbgr&&null!==e.polyColorAbgr&&(t.polyColorAbgr=e.polyColorAbgr>>>0),void 0!==e.lineColorAbgr&&null!==e.lineColorAbgr&&(t.lineColorAbgr=e.lineColorAbgr>>>0),void 0!==e.lineWidth&&null!==e.lineWidth&&(t.lineWidth=Number(e.lineWidth)),void 0!==e.labelColorAbgr&&null!==e.labelColorAbgr&&(t.labelColorAbgr=e.labelColorAbgr>>>0),void 0!==e.labelScale&&null!==e.labelScale&&(t.labelScale=Number(e.labelScale)),void 0!==e.placemarkIconColorAbgr&&null!==e.placemarkIconColorAbgr&&(t.placemarkIconColorAbgr=e.placemarkIconColorAbgr>>>0),void 0!==e.placemarkIconScale&&null!==e.placemarkIconScale&&(t.placemarkIconScale=Number(e.placemarkIconScale)),void 0!==e.placemarkIconPath&&null!==e.placemarkIconPath){if("object"!=typeof e.placemarkIconPath)throw TypeError(".keyhole.dbroot.StyleAttributeProto.placemarkIconPath: object expected");t.placemarkIconPath=a[9].fromObject(e.placemarkIconPath)}if(void 0!==e.placemarkIconX&&null!==e.placemarkIconX&&(t.placemarkIconX=0|e.placemarkIconX),void 0!==e.placemarkIconY&&null!==e.placemarkIconY&&(t.placemarkIconY=0|e.placemarkIconY),void 0!==e.placemarkIconWidth&&null!==e.placemarkIconWidth&&(t.placemarkIconWidth=0|e.placemarkIconWidth),void 0!==e.placemarkIconHeight&&null!==e.placemarkIconHeight&&(t.placemarkIconHeight=0|e.placemarkIconHeight),void 0!==e.popUp&&null!==e.popUp){if("object"!=typeof e.popUp)throw TypeError(".keyhole.dbroot.StyleAttributeProto.popUp: object expected");t.popUp=a[14].fromObject(e.popUp)}if(e.drawFlag){if(!Array.isArray(e.drawFlag))throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: array expected");t.drawFlag=[];for(var r=0;r<e.drawFlag.length;++r){if("object"!=typeof e.drawFlag[r])throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: object expected");t.drawFlag[r]=a[15].fromObject(e.drawFlag[r])}}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.drawFlag=[]),t.defaults&&(r.styleId="",r.providerId=0,r.polyColorAbgr=4294967295,r.lineColorAbgr=4294967295,r.lineWidth=1,r.labelColorAbgr=4294967295,r.labelScale=1,r.placemarkIconColorAbgr=4294967295,r.placemarkIconScale=1,r.placemarkIconPath=null,r.placemarkIconX=0,r.placemarkIconY=0,r.placemarkIconWidth=32,r.placemarkIconHeight=32,r.popUp=null),void 0!==e.styleId&&null!==e.styleId&&e.hasOwnProperty("styleId")&&(r.styleId=e.styleId),void 0!==e.providerId&&null!==e.providerId&&e.hasOwnProperty("providerId")&&(r.providerId=e.providerId),void 0!==e.polyColorAbgr&&null!==e.polyColorAbgr&&e.hasOwnProperty("polyColorAbgr")&&(r.polyColorAbgr=e.polyColorAbgr),void 0!==e.lineColorAbgr&&null!==e.lineColorAbgr&&e.hasOwnProperty("lineColorAbgr")&&(r.lineColorAbgr=e.lineColorAbgr),void 0!==e.lineWidth&&null!==e.lineWidth&&e.hasOwnProperty("lineWidth")&&(r.lineWidth=e.lineWidth),void 0!==e.labelColorAbgr&&null!==e.labelColorAbgr&&e.hasOwnProperty("labelColorAbgr")&&(r.labelColorAbgr=e.labelColorAbgr),void 0!==e.labelScale&&null!==e.labelScale&&e.hasOwnProperty("labelScale")&&(r.labelScale=e.labelScale),void 0!==e.placemarkIconColorAbgr&&null!==e.placemarkIconColorAbgr&&e.hasOwnProperty("placemarkIconColorAbgr")&&(r.placemarkIconColorAbgr=e.placemarkIconColorAbgr),void 0!==e.placemarkIconScale&&null!==e.placemarkIconScale&&e.hasOwnProperty("placemarkIconScale")&&(r.placemarkIconScale=e.placemarkIconScale),void 0!==e.placemarkIconPath&&null!==e.placemarkIconPath&&e.hasOwnProperty("placemarkIconPath")&&(r.placemarkIconPath=a[9].toObject(e.placemarkIconPath,t)),void 0!==e.placemarkIconX&&null!==e.placemarkIconX&&e.hasOwnProperty("placemarkIconX")&&(r.placemarkIconX=e.placemarkIconX),void 0!==e.placemarkIconY&&null!==e.placemarkIconY&&e.hasOwnProperty("placemarkIconY")&&(r.placemarkIconY=e.placemarkIconY),void 0!==e.placemarkIconWidth&&null!==e.placemarkIconWidth&&e.hasOwnProperty("placemarkIconWidth")&&(r.placemarkIconWidth=e.placemarkIconWidth),void 0!==e.placemarkIconHeight&&null!==e.placemarkIconHeight&&e.hasOwnProperty("placemarkIconHeight")&&(r.placemarkIconHeight=e.placemarkIconHeight),void 0!==e.popUp&&null!==e.popUp&&e.hasOwnProperty("popUp")&&(r.popUp=a[14].toObject(e.popUp,t)),void 0!==e.drawFlag&&null!==e.drawFlag&&e.hasOwnProperty("drawFlag")){r.drawFlag=[];for(var i=0;i<e.drawFlag.length;++i)r.drawFlag[i]=a[15].toObject(e.drawFlag[i],t)}return r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.StyleMapProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.styleMapId=0,i.prototype.channelId=r.emptyArray,i.prototype.normalStyleAttribute=0,i.prototype.highlightStyleAttribute=0,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.StyleMapProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.styleMapId=e.int32();break;case 2:if(o.channelId&&o.channelId.length||(o.channelId=[]),2==(7&a))for(var s=e.uint32()+e.pos;e.pos<s;)o.channelId.push(e.int32());else o.channelId.push(e.int32());break;case 3:o.normalStyleAttribute=e.int32();break;case 4:o.highlightStyleAttribute=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isInteger(e.styleMapId))return"styleMapId: integer expected";if(void 0!==e.channelId){if(!Array.isArray(e.channelId))return"channelId: array expected";for(var t=0;t<e.channelId.length;++t)if(!r.isInteger(e.channelId[t]))return"channelId: integer[] expected"}return void 0===e.normalStyleAttribute||r.isInteger(e.normalStyleAttribute)?void 0===e.highlightStyleAttribute||r.isInteger(e.highlightStyleAttribute)?null:"highlightStyleAttribute: integer expected":"normalStyleAttribute: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.StyleMapProto)return e;var t=new n.keyhole.dbroot.StyleMapProto;if(void 0!==e.styleMapId&&null!==e.styleMapId&&(t.styleMapId=0|e.styleMapId),e.channelId){if(!Array.isArray(e.channelId))throw TypeError(".keyhole.dbroot.StyleMapProto.channelId: array expected");t.channelId=[];for(var r=0;r<e.channelId.length;++r)t.channelId[r]=0|e.channelId[r]}return void 0!==e.normalStyleAttribute&&null!==e.normalStyleAttribute&&(t.normalStyleAttribute=0|e.normalStyleAttribute),void 0!==e.highlightStyleAttribute&&null!==e.highlightStyleAttribute&&(t.highlightStyleAttribute=0|e.highlightStyleAttribute),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.channelId=[]),t.defaults&&(r.styleMapId=0,r.normalStyleAttribute=0,r.highlightStyleAttribute=0),void 0!==e.styleMapId&&null!==e.styleMapId&&e.hasOwnProperty("styleMapId")&&(r.styleMapId=e.styleMapId),void 0!==e.channelId&&null!==e.channelId&&e.hasOwnProperty("channelId")){r.channelId=[];for(var i=0;i<e.channelId.length;++i)r.channelId[i]=e.channelId[i]}return void 0!==e.normalStyleAttribute&&null!==e.normalStyleAttribute&&e.hasOwnProperty("normalStyleAttribute")&&(r.normalStyleAttribute=e.normalStyleAttribute),void 0!==e.highlightStyleAttribute&&null!==e.highlightStyleAttribute&&e.hasOwnProperty("highlightStyleAttribute")&&(r.highlightStyleAttribute=e.highlightStyleAttribute),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.ZoomRangeProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.minZoom=0,i.prototype.maxZoom=0,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ZoomRangeProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.minZoom=e.int32();break;case 2:o.maxZoom=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isInteger(e.minZoom)?r.isInteger(e.maxZoom)?null:"maxZoom: integer expected":"minZoom: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ZoomRangeProto)return e;var t=new n.keyhole.dbroot.ZoomRangeProto;return void 0!==e.minZoom&&null!==e.minZoom&&(t.minZoom=0|e.minZoom),void 0!==e.maxZoom&&null!==e.maxZoom&&(t.maxZoom=0|e.maxZoom),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.minZoom=0,r.maxZoom=0),void 0!==e.minZoom&&null!==e.minZoom&&e.hasOwnProperty("minZoom")&&(r.minZoom=e.minZoom),void 0!==e.maxZoom&&null!==e.maxZoom&&e.hasOwnProperty("maxZoom")&&(r.maxZoom=e.maxZoom),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.DrawFlagProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.drawFlagType=1;var o={0:"keyhole.dbroot.DrawFlagProto.DrawFlagType"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.DrawFlagProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.drawFlagType=e.uint32();break;default:e.skipType(7&a)}}return o},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";switch(e.drawFlagType){default:return"drawFlagType: enum value expected";case 1:case 2:case 3:case 4:case 5:}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DrawFlagProto)return e;var t=new n.keyhole.dbroot.DrawFlagProto;switch(e.drawFlagType){case"TYPE_FILL_ONLY":case 1:t.drawFlagType=1;break;case"TYPE_OUTLINE_ONLY":case 2:t.drawFlagType=2;break;case"TYPE_FILL_AND_OUTLINE":case 3:t.drawFlagType=3;break;case"TYPE_ANTIALIASING":case 4:t.drawFlagType=4;break;case"TYPE_CENTER_LABEL":case 5:t.drawFlagType=5}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.drawFlagType=t.enums===String?"TYPE_FILL_ONLY":1),void 0!==e.drawFlagType&&null!==e.drawFlagType&&e.hasOwnProperty("drawFlagType")&&(r.drawFlagType=t.enums===String?o[0][e.drawFlagType]:e.drawFlagType),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r.DrawFlagType=function(){var e={},t=Object.create(e);return t.TYPE_FILL_ONLY=1,t.TYPE_OUTLINE_ONLY=2,t.TYPE_FILL_AND_OUTLINE=3,t.TYPE_ANTIALIASING=4,t.TYPE_CENTER_LABEL=5,t}(),r}(),o.LayerProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.zoomRange=r.emptyArray,o.prototype.preserveTextLevel=30,o.prototype.lodBeginTransition=!1,o.prototype.lodEndTransition=!1;var a={0:"keyhole.dbroot.ZoomRangeProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.LayerProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.zoomRange&&o.zoomRange.length||(o.zoomRange=[]),o.zoomRange.push(a[0].decode(e,e.uint32()));break;case 2:o.preserveTextLevel=e.int32();break;case 4:o.lodBeginTransition=e.bool();break;case 5:o.lodEndTransition=e.bool();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.zoomRange){if(!Array.isArray(e.zoomRange))return"zoomRange: array expected";for(var t=0;t<e.zoomRange.length;++t){var i=a[0].verify(e.zoomRange[t]);if(i)return"zoomRange."+i}}return void 0===e.preserveTextLevel||r.isInteger(e.preserveTextLevel)?void 0!==e.lodBeginTransition&&"boolean"!=typeof e.lodBeginTransition?"lodBeginTransition: boolean expected":void 0!==e.lodEndTransition&&"boolean"!=typeof e.lodEndTransition?"lodEndTransition: boolean expected":null:"preserveTextLevel: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.LayerProto)return e;var t=new n.keyhole.dbroot.LayerProto;if(e.zoomRange){if(!Array.isArray(e.zoomRange))throw TypeError(".keyhole.dbroot.LayerProto.zoomRange: array expected");t.zoomRange=[];for(var r=0;r<e.zoomRange.length;++r){if("object"!=typeof e.zoomRange[r])throw TypeError(".keyhole.dbroot.LayerProto.zoomRange: object expected");t.zoomRange[r]=a[0].fromObject(e.zoomRange[r])}}return void 0!==e.preserveTextLevel&&null!==e.preserveTextLevel&&(t.preserveTextLevel=0|e.preserveTextLevel),void 0!==e.lodBeginTransition&&null!==e.lodBeginTransition&&(t.lodBeginTransition=Boolean(e.lodBeginTransition)),void 0!==e.lodEndTransition&&null!==e.lodEndTransition&&(t.lodEndTransition=Boolean(e.lodEndTransition)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.zoomRange=[]),t.defaults&&(r.preserveTextLevel=30,r.lodBeginTransition=!1,r.lodEndTransition=!1),void 0!==e.zoomRange&&null!==e.zoomRange&&e.hasOwnProperty("zoomRange")){r.zoomRange=[];for(var i=0;i<e.zoomRange.length;++i)r.zoomRange[i]=a[0].toObject(e.zoomRange[i],t)}return void 0!==e.preserveTextLevel&&null!==e.preserveTextLevel&&e.hasOwnProperty("preserveTextLevel")&&(r.preserveTextLevel=e.preserveTextLevel),void 0!==e.lodBeginTransition&&null!==e.lodBeginTransition&&e.hasOwnProperty("lodBeginTransition")&&(r.lodBeginTransition=e.lodBeginTransition),void 0!==e.lodEndTransition&&null!==e.lodEndTransition&&e.hasOwnProperty("lodEndTransition")&&(r.lodEndTransition=e.lodEndTransition),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.FolderProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return r.prototype.isExpandable=!0,r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.FolderProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.isExpandable=e.bool();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.isExpandable&&"boolean"!=typeof e.isExpandable?"isExpandable: boolean expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.FolderProto)return e;var t=new n.keyhole.dbroot.FolderProto;return void 0!==e.isExpandable&&null!==e.isExpandable&&(t.isExpandable=Boolean(e.isExpandable)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.isExpandable=!0),void 0!==e.isExpandable&&null!==e.isExpandable&&e.hasOwnProperty("isExpandable")&&(r.isExpandable=e.isExpandable),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.RequirementProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.requiredVram="",i.prototype.requiredClientVer="",i.prototype.probability="",i.prototype.requiredUserAgent="",i.prototype.requiredClientCapabilities="",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.RequirementProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 3:o.requiredVram=e.string();break;case 4:o.requiredClientVer=e.string();break;case 5:o.probability=e.string();break;case 6:o.requiredUserAgent=e.string();break;case 7:o.requiredClientCapabilities=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.requiredVram||r.isString(e.requiredVram)?void 0===e.requiredClientVer||r.isString(e.requiredClientVer)?void 0===e.probability||r.isString(e.probability)?void 0===e.requiredUserAgent||r.isString(e.requiredUserAgent)?void 0===e.requiredClientCapabilities||r.isString(e.requiredClientCapabilities)?null:"requiredClientCapabilities: string expected":"requiredUserAgent: string expected":"probability: string expected":"requiredClientVer: string expected":"requiredVram: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.RequirementProto)return e;var t=new n.keyhole.dbroot.RequirementProto;return void 0!==e.requiredVram&&null!==e.requiredVram&&(t.requiredVram=String(e.requiredVram)),void 0!==e.requiredClientVer&&null!==e.requiredClientVer&&(t.requiredClientVer=String(e.requiredClientVer)),void 0!==e.probability&&null!==e.probability&&(t.probability=String(e.probability)), +void 0!==e.requiredUserAgent&&null!==e.requiredUserAgent&&(t.requiredUserAgent=String(e.requiredUserAgent)),void 0!==e.requiredClientCapabilities&&null!==e.requiredClientCapabilities&&(t.requiredClientCapabilities=String(e.requiredClientCapabilities)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.requiredVram="",r.requiredClientVer="",r.probability="",r.requiredUserAgent="",r.requiredClientCapabilities=""),void 0!==e.requiredVram&&null!==e.requiredVram&&e.hasOwnProperty("requiredVram")&&(r.requiredVram=e.requiredVram),void 0!==e.requiredClientVer&&null!==e.requiredClientVer&&e.hasOwnProperty("requiredClientVer")&&(r.requiredClientVer=e.requiredClientVer),void 0!==e.probability&&null!==e.probability&&e.hasOwnProperty("probability")&&(r.probability=e.probability),void 0!==e.requiredUserAgent&&null!==e.requiredUserAgent&&e.hasOwnProperty("requiredUserAgent")&&(r.requiredUserAgent=e.requiredUserAgent),void 0!==e.requiredClientCapabilities&&null!==e.requiredClientCapabilities&&e.hasOwnProperty("requiredClientCapabilities")&&(r.requiredClientCapabilities=e.requiredClientCapabilities),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.LookAtProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return r.prototype.longitude=0,r.prototype.latitude=0,r.prototype.range=0,r.prototype.tilt=0,r.prototype.heading=0,r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.LookAtProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.longitude=e.float();break;case 2:o.latitude=e.float();break;case 3:o.range=e.float();break;case 4:o.tilt=e.float();break;case 5:o.heading=e.float();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":"number"!=typeof e.longitude?"longitude: number expected":"number"!=typeof e.latitude?"latitude: number expected":void 0!==e.range&&"number"!=typeof e.range?"range: number expected":void 0!==e.tilt&&"number"!=typeof e.tilt?"tilt: number expected":void 0!==e.heading&&"number"!=typeof e.heading?"heading: number expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.LookAtProto)return e;var t=new n.keyhole.dbroot.LookAtProto;return void 0!==e.longitude&&null!==e.longitude&&(t.longitude=Number(e.longitude)),void 0!==e.latitude&&null!==e.latitude&&(t.latitude=Number(e.latitude)),void 0!==e.range&&null!==e.range&&(t.range=Number(e.range)),void 0!==e.tilt&&null!==e.tilt&&(t.tilt=Number(e.tilt)),void 0!==e.heading&&null!==e.heading&&(t.heading=Number(e.heading)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.longitude=0,r.latitude=0,r.range=0,r.tilt=0,r.heading=0),void 0!==e.longitude&&null!==e.longitude&&e.hasOwnProperty("longitude")&&(r.longitude=e.longitude),void 0!==e.latitude&&null!==e.latitude&&e.hasOwnProperty("latitude")&&(r.latitude=e.latitude),void 0!==e.range&&null!==e.range&&e.hasOwnProperty("range")&&(r.range=e.range),void 0!==e.tilt&&null!==e.tilt&&e.hasOwnProperty("tilt")&&(r.tilt=e.tilt),void 0!==e.heading&&null!==e.heading&&e.hasOwnProperty("heading")&&(r.heading=e.heading),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.NestedFeatureProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.featureType=1,o.prototype.kmlUrl=null,o.prototype.databaseUrl="",o.prototype.layer=null,o.prototype.folder=null,o.prototype.requirement=null,o.prototype.channelId=0,o.prototype.displayName=null,o.prototype.isVisible=!0,o.prototype.isEnabled=!0,o.prototype.isChecked=!1,o.prototype.layerMenuIconPath="icons/773_l.png",o.prototype.description=null,o.prototype.lookAt=null,o.prototype.assetUuid="",o.prototype.isSaveLocked=!0,o.prototype.children=r.emptyArray,o.prototype.clientConfigScriptName="",o.prototype.dioramaDataChannelBase=-1,o.prototype.replicaDataChannelBase=-1;var a={0:"keyhole.dbroot.NestedFeatureProto.FeatureType",1:"keyhole.dbroot.StringIdOrValueProto",3:"keyhole.dbroot.LayerProto",4:"keyhole.dbroot.FolderProto",5:"keyhole.dbroot.RequirementProto",7:"keyhole.dbroot.StringIdOrValueProto",12:"keyhole.dbroot.StringIdOrValueProto",13:"keyhole.dbroot.LookAtProto",16:"keyhole.dbroot.NestedFeatureProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.NestedFeatureProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.featureType=e.uint32();break;case 2:o.kmlUrl=a[1].decode(e,e.uint32());break;case 21:o.databaseUrl=e.string();break;case 3:o.layer=a[3].decode(e,e.uint32());break;case 4:o.folder=a[4].decode(e,e.uint32());break;case 5:o.requirement=a[5].decode(e,e.uint32());break;case 6:o.channelId=e.int32();break;case 7:o.displayName=a[7].decode(e,e.uint32());break;case 8:o.isVisible=e.bool();break;case 9:o.isEnabled=e.bool();break;case 10:o.isChecked=e.bool();break;case 11:o.layerMenuIconPath=e.string();break;case 12:o.description=a[12].decode(e,e.uint32());break;case 13:o.lookAt=a[13].decode(e,e.uint32());break;case 15:o.assetUuid=e.string();break;case 16:o.isSaveLocked=e.bool();break;case 17:o.children&&o.children.length||(o.children=[]),o.children.push(a[16].decode(e,e.uint32()));break;case 18:o.clientConfigScriptName=e.string();break;case 19:o.dioramaDataChannelBase=e.int32();break;case 20:o.replicaDataChannelBase=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.featureType)switch(e.featureType){default:return"featureType: enum value expected";case 1:case 2:case 3:case 4:}if(void 0!==e.kmlUrl&&null!==e.kmlUrl){var t=a[1].verify(e.kmlUrl);if(t)return"kmlUrl."+t}if(void 0!==e.databaseUrl&&!r.isString(e.databaseUrl))return"databaseUrl: string expected";if(void 0!==e.layer&&null!==e.layer){var t=a[3].verify(e.layer);if(t)return"layer."+t}if(void 0!==e.folder&&null!==e.folder){var t=a[4].verify(e.folder);if(t)return"folder."+t}if(void 0!==e.requirement&&null!==e.requirement){var t=a[5].verify(e.requirement);if(t)return"requirement."+t}if(!r.isInteger(e.channelId))return"channelId: integer expected";if(void 0!==e.displayName&&null!==e.displayName){var t=a[7].verify(e.displayName);if(t)return"displayName."+t}if(void 0!==e.isVisible&&"boolean"!=typeof e.isVisible)return"isVisible: boolean expected";if(void 0!==e.isEnabled&&"boolean"!=typeof e.isEnabled)return"isEnabled: boolean expected";if(void 0!==e.isChecked&&"boolean"!=typeof e.isChecked)return"isChecked: boolean expected";if(void 0!==e.layerMenuIconPath&&!r.isString(e.layerMenuIconPath))return"layerMenuIconPath: string expected";if(void 0!==e.description&&null!==e.description){var t=a[12].verify(e.description);if(t)return"description."+t}if(void 0!==e.lookAt&&null!==e.lookAt){var t=a[13].verify(e.lookAt);if(t)return"lookAt."+t}if(void 0!==e.assetUuid&&!r.isString(e.assetUuid))return"assetUuid: string expected";if(void 0!==e.isSaveLocked&&"boolean"!=typeof e.isSaveLocked)return"isSaveLocked: boolean expected";if(void 0!==e.children){if(!Array.isArray(e.children))return"children: array expected";for(var i=0;i<e.children.length;++i){var t=a[16].verify(e.children[i]);if(t)return"children."+t}}return void 0===e.clientConfigScriptName||r.isString(e.clientConfigScriptName)?void 0===e.dioramaDataChannelBase||r.isInteger(e.dioramaDataChannelBase)?void 0===e.replicaDataChannelBase||r.isInteger(e.replicaDataChannelBase)?null:"replicaDataChannelBase: integer expected":"dioramaDataChannelBase: integer expected":"clientConfigScriptName: string expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.NestedFeatureProto)return e;var t=new n.keyhole.dbroot.NestedFeatureProto;switch(e.featureType){case"TYPE_POINT_Z":case 1:t.featureType=1;break;case"TYPE_POLYGON_Z":case 2:t.featureType=2;break;case"TYPE_LINE_Z":case 3:t.featureType=3;break;case"TYPE_TERRAIN":case 4:t.featureType=4}if(void 0!==e.kmlUrl&&null!==e.kmlUrl){if("object"!=typeof e.kmlUrl)throw TypeError(".keyhole.dbroot.NestedFeatureProto.kmlUrl: object expected");t.kmlUrl=a[1].fromObject(e.kmlUrl)}if(void 0!==e.databaseUrl&&null!==e.databaseUrl&&(t.databaseUrl=String(e.databaseUrl)),void 0!==e.layer&&null!==e.layer){if("object"!=typeof e.layer)throw TypeError(".keyhole.dbroot.NestedFeatureProto.layer: object expected");t.layer=a[3].fromObject(e.layer)}if(void 0!==e.folder&&null!==e.folder){if("object"!=typeof e.folder)throw TypeError(".keyhole.dbroot.NestedFeatureProto.folder: object expected");t.folder=a[4].fromObject(e.folder)}if(void 0!==e.requirement&&null!==e.requirement){if("object"!=typeof e.requirement)throw TypeError(".keyhole.dbroot.NestedFeatureProto.requirement: object expected");t.requirement=a[5].fromObject(e.requirement)}if(void 0!==e.channelId&&null!==e.channelId&&(t.channelId=0|e.channelId),void 0!==e.displayName&&null!==e.displayName){if("object"!=typeof e.displayName)throw TypeError(".keyhole.dbroot.NestedFeatureProto.displayName: object expected");t.displayName=a[7].fromObject(e.displayName)}if(void 0!==e.isVisible&&null!==e.isVisible&&(t.isVisible=Boolean(e.isVisible)),void 0!==e.isEnabled&&null!==e.isEnabled&&(t.isEnabled=Boolean(e.isEnabled)),void 0!==e.isChecked&&null!==e.isChecked&&(t.isChecked=Boolean(e.isChecked)),void 0!==e.layerMenuIconPath&&null!==e.layerMenuIconPath&&(t.layerMenuIconPath=String(e.layerMenuIconPath)),void 0!==e.description&&null!==e.description){if("object"!=typeof e.description)throw TypeError(".keyhole.dbroot.NestedFeatureProto.description: object expected");t.description=a[12].fromObject(e.description)}if(void 0!==e.lookAt&&null!==e.lookAt){if("object"!=typeof e.lookAt)throw TypeError(".keyhole.dbroot.NestedFeatureProto.lookAt: object expected");t.lookAt=a[13].fromObject(e.lookAt)}if(void 0!==e.assetUuid&&null!==e.assetUuid&&(t.assetUuid=String(e.assetUuid)),void 0!==e.isSaveLocked&&null!==e.isSaveLocked&&(t.isSaveLocked=Boolean(e.isSaveLocked)),e.children){if(!Array.isArray(e.children))throw TypeError(".keyhole.dbroot.NestedFeatureProto.children: array expected");t.children=[];for(var r=0;r<e.children.length;++r){if("object"!=typeof e.children[r])throw TypeError(".keyhole.dbroot.NestedFeatureProto.children: object expected");t.children[r]=a[16].fromObject(e.children[r])}}return void 0!==e.clientConfigScriptName&&null!==e.clientConfigScriptName&&(t.clientConfigScriptName=String(e.clientConfigScriptName)),void 0!==e.dioramaDataChannelBase&&null!==e.dioramaDataChannelBase&&(t.dioramaDataChannelBase=0|e.dioramaDataChannelBase),void 0!==e.replicaDataChannelBase&&null!==e.replicaDataChannelBase&&(t.replicaDataChannelBase=0|e.replicaDataChannelBase),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.children=[]),t.defaults&&(r.featureType=t.enums===String?"TYPE_POINT_Z":1,r.kmlUrl=null,r.databaseUrl="",r.layer=null,r.folder=null,r.requirement=null,r.channelId=0,r.displayName=null,r.isVisible=!0,r.isEnabled=!0,r.isChecked=!1,r.layerMenuIconPath="icons/773_l.png",r.description=null,r.lookAt=null,r.assetUuid="",r.isSaveLocked=!0,r.clientConfigScriptName="",r.dioramaDataChannelBase=-1,r.replicaDataChannelBase=-1),void 0!==e.featureType&&null!==e.featureType&&e.hasOwnProperty("featureType")&&(r.featureType=t.enums===String?a[0][e.featureType]:e.featureType),void 0!==e.kmlUrl&&null!==e.kmlUrl&&e.hasOwnProperty("kmlUrl")&&(r.kmlUrl=a[1].toObject(e.kmlUrl,t)),void 0!==e.databaseUrl&&null!==e.databaseUrl&&e.hasOwnProperty("databaseUrl")&&(r.databaseUrl=e.databaseUrl),void 0!==e.layer&&null!==e.layer&&e.hasOwnProperty("layer")&&(r.layer=a[3].toObject(e.layer,t)),void 0!==e.folder&&null!==e.folder&&e.hasOwnProperty("folder")&&(r.folder=a[4].toObject(e.folder,t)),void 0!==e.requirement&&null!==e.requirement&&e.hasOwnProperty("requirement")&&(r.requirement=a[5].toObject(e.requirement,t)),void 0!==e.channelId&&null!==e.channelId&&e.hasOwnProperty("channelId")&&(r.channelId=e.channelId),void 0!==e.displayName&&null!==e.displayName&&e.hasOwnProperty("displayName")&&(r.displayName=a[7].toObject(e.displayName,t)),void 0!==e.isVisible&&null!==e.isVisible&&e.hasOwnProperty("isVisible")&&(r.isVisible=e.isVisible),void 0!==e.isEnabled&&null!==e.isEnabled&&e.hasOwnProperty("isEnabled")&&(r.isEnabled=e.isEnabled),void 0!==e.isChecked&&null!==e.isChecked&&e.hasOwnProperty("isChecked")&&(r.isChecked=e.isChecked),void 0!==e.layerMenuIconPath&&null!==e.layerMenuIconPath&&e.hasOwnProperty("layerMenuIconPath")&&(r.layerMenuIconPath=e.layerMenuIconPath),void 0!==e.description&&null!==e.description&&e.hasOwnProperty("description")&&(r.description=a[12].toObject(e.description,t)),void 0!==e.lookAt&&null!==e.lookAt&&e.hasOwnProperty("lookAt")&&(r.lookAt=a[13].toObject(e.lookAt,t)),void 0!==e.assetUuid&&null!==e.assetUuid&&e.hasOwnProperty("assetUuid")&&(r.assetUuid=e.assetUuid),void 0!==e.isSaveLocked&&null!==e.isSaveLocked&&e.hasOwnProperty("isSaveLocked")&&(r.isSaveLocked=e.isSaveLocked),void 0!==e.children&&null!==e.children&&e.hasOwnProperty("children")){r.children=[];for(var i=0;i<e.children.length;++i)r.children[i]=a[16].toObject(e.children[i],t)}return void 0!==e.clientConfigScriptName&&null!==e.clientConfigScriptName&&e.hasOwnProperty("clientConfigScriptName")&&(r.clientConfigScriptName=e.clientConfigScriptName),void 0!==e.dioramaDataChannelBase&&null!==e.dioramaDataChannelBase&&e.hasOwnProperty("dioramaDataChannelBase")&&(r.dioramaDataChannelBase=e.dioramaDataChannelBase),void 0!==e.replicaDataChannelBase&&null!==e.replicaDataChannelBase&&e.hasOwnProperty("replicaDataChannelBase")&&(r.replicaDataChannelBase=e.replicaDataChannelBase),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.FeatureType=function(){var e={},t=Object.create(e);return t.TYPE_POINT_Z=1,t.TYPE_POLYGON_Z=2,t.TYPE_LINE_Z=3,t.TYPE_TERRAIN=4,t}(),o}(),o.MfeDomainFeaturesProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.countryCode="",o.prototype.domainName="",o.prototype.supportedFeatures=r.emptyArray;var a={2:"keyhole.dbroot.MfeDomainFeaturesProto.SupportedFeature"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.MfeDomainFeaturesProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.countryCode=e.string();break;case 2:o.domainName=e.string();break;case 3:if(o.supportedFeatures&&o.supportedFeatures.length||(o.supportedFeatures=[]),2==(7&a))for(var s=e.uint32()+e.pos;e.pos<s;)o.supportedFeatures.push(e.uint32());else o.supportedFeatures.push(e.uint32());break;default:e.skipType(7&a)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.countryCode))return"countryCode: string expected";if(!r.isString(e.domainName))return"domainName: string expected";if(void 0!==e.supportedFeatures){if(!Array.isArray(e.supportedFeatures))return"supportedFeatures: array expected";for(var t=0;t<e.supportedFeatures.length;++t)switch(e.supportedFeatures[t]){default:return"supportedFeatures: enum value[] expected";case 0:case 1:case 2:}}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.MfeDomainFeaturesProto)return e;var t=new n.keyhole.dbroot.MfeDomainFeaturesProto;if(void 0!==e.countryCode&&null!==e.countryCode&&(t.countryCode=String(e.countryCode)),void 0!==e.domainName&&null!==e.domainName&&(t.domainName=String(e.domainName)),e.supportedFeatures){if(!Array.isArray(e.supportedFeatures))throw TypeError(".keyhole.dbroot.MfeDomainFeaturesProto.supportedFeatures: array expected");t.supportedFeatures=[];for(var r=0;r<e.supportedFeatures.length;++r)switch(e.supportedFeatures[r]){default:case"GEOCODING":case 0:t.supportedFeatures[r]=0;break;case"LOCAL_SEARCH":case 1:t.supportedFeatures[r]=1;break;case"DRIVING_DIRECTIONS":case 2:t.supportedFeatures[r]=2}}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.supportedFeatures=[]),t.defaults&&(r.countryCode="",r.domainName=""),void 0!==e.countryCode&&null!==e.countryCode&&e.hasOwnProperty("countryCode")&&(r.countryCode=e.countryCode),void 0!==e.domainName&&null!==e.domainName&&e.hasOwnProperty("domainName")&&(r.domainName=e.domainName),void 0!==e.supportedFeatures&&null!==e.supportedFeatures&&e.hasOwnProperty("supportedFeatures")){r.supportedFeatures=[];for(var i=0;i<e.supportedFeatures.length;++i)r.supportedFeatures[i]=t.enums===String?a[2][e.supportedFeatures[i]]:e.supportedFeatures[i]}return r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.SupportedFeature=function(){var e={},t=Object.create(e);return t.GEOCODING=0,t.LOCAL_SEARCH=1,t.DRIVING_DIRECTIONS=2,t}(),o}(),o.ClientOptionsProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.disableDiskCache=!1,o.prototype.disableEmbeddedBrowserVista=!1,o.prototype.drawAtmosphere=!0,o.prototype.drawStars=!0,o.prototype.shaderFilePrefix="",o.prototype.useProtobufQuadtreePackets=!1,o.prototype.useExtendedCopyrightIds=!0,o.prototype.precipitationsOptions=null,o.prototype.captureOptions=null,o.prototype.show_2dMapsIcon=!0,o.prototype.disableInternalBrowser=!1,o.prototype.internalBrowserBlacklist="",o.prototype.internalBrowserOriginWhitelist="*",o.prototype.polarTileMergingLevel=0,o.prototype.jsBridgeRequestWhitelist="http://*.google.com/*",o.prototype.mapsOptions=null;var a={7:"keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions",8:"keyhole.dbroot.ClientOptionsProto.CaptureOptions",15:"keyhole.dbroot.ClientOptionsProto.MapsOptions"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ClientOptionsProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.disableDiskCache=e.bool();break;case 2:o.disableEmbeddedBrowserVista=e.bool();break;case 3:o.drawAtmosphere=e.bool();break;case 4:o.drawStars=e.bool();break;case 5:o.shaderFilePrefix=e.string();break;case 6:o.useProtobufQuadtreePackets=e.bool();break;case 7:o.useExtendedCopyrightIds=e.bool();break;case 8:o.precipitationsOptions=a[7].decode(e,e.uint32());break;case 9:o.captureOptions=a[8].decode(e,e.uint32());break;case 10:o.show_2dMapsIcon=e.bool();break;case 11:o.disableInternalBrowser=e.bool();break;case 12:o.internalBrowserBlacklist=e.string();break;case 13:o.internalBrowserOriginWhitelist=e.string();break;case 14:o.polarTileMergingLevel=e.int32();break;case 15:o.jsBridgeRequestWhitelist=e.string();break;case 16:o.mapsOptions=a[15].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.disableDiskCache&&"boolean"!=typeof e.disableDiskCache)return"disableDiskCache: boolean expected";if(void 0!==e.disableEmbeddedBrowserVista&&"boolean"!=typeof e.disableEmbeddedBrowserVista)return"disableEmbeddedBrowserVista: boolean expected";if(void 0!==e.drawAtmosphere&&"boolean"!=typeof e.drawAtmosphere)return"drawAtmosphere: boolean expected";if(void 0!==e.drawStars&&"boolean"!=typeof e.drawStars)return"drawStars: boolean expected";if(void 0!==e.shaderFilePrefix&&!r.isString(e.shaderFilePrefix))return"shaderFilePrefix: string expected";if(void 0!==e.useProtobufQuadtreePackets&&"boolean"!=typeof e.useProtobufQuadtreePackets)return"useProtobufQuadtreePackets: boolean expected";if(void 0!==e.useExtendedCopyrightIds&&"boolean"!=typeof e.useExtendedCopyrightIds)return"useExtendedCopyrightIds: boolean expected";if(void 0!==e.precipitationsOptions&&null!==e.precipitationsOptions){var t=a[7].verify(e.precipitationsOptions);if(t)return"precipitationsOptions."+t}if(void 0!==e.captureOptions&&null!==e.captureOptions){var t=a[8].verify(e.captureOptions);if(t)return"captureOptions."+t}if(void 0!==e.show_2dMapsIcon&&"boolean"!=typeof e.show_2dMapsIcon)return"show_2dMapsIcon: boolean expected";if(void 0!==e.disableInternalBrowser&&"boolean"!=typeof e.disableInternalBrowser)return"disableInternalBrowser: boolean expected";if(void 0!==e.internalBrowserBlacklist&&!r.isString(e.internalBrowserBlacklist))return"internalBrowserBlacklist: string expected";if(void 0!==e.internalBrowserOriginWhitelist&&!r.isString(e.internalBrowserOriginWhitelist))return"internalBrowserOriginWhitelist: string expected";if(void 0!==e.polarTileMergingLevel&&!r.isInteger(e.polarTileMergingLevel))return"polarTileMergingLevel: integer expected";if(void 0!==e.jsBridgeRequestWhitelist&&!r.isString(e.jsBridgeRequestWhitelist))return"jsBridgeRequestWhitelist: string expected";if(void 0!==e.mapsOptions&&null!==e.mapsOptions){var t=a[15].verify(e.mapsOptions);if(t)return"mapsOptions."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto)return e;var t=new n.keyhole.dbroot.ClientOptionsProto;if(void 0!==e.disableDiskCache&&null!==e.disableDiskCache&&(t.disableDiskCache=Boolean(e.disableDiskCache)),void 0!==e.disableEmbeddedBrowserVista&&null!==e.disableEmbeddedBrowserVista&&(t.disableEmbeddedBrowserVista=Boolean(e.disableEmbeddedBrowserVista)),void 0!==e.drawAtmosphere&&null!==e.drawAtmosphere&&(t.drawAtmosphere=Boolean(e.drawAtmosphere)),void 0!==e.drawStars&&null!==e.drawStars&&(t.drawStars=Boolean(e.drawStars)),void 0!==e.shaderFilePrefix&&null!==e.shaderFilePrefix&&(t.shaderFilePrefix=String(e.shaderFilePrefix)),void 0!==e.useProtobufQuadtreePackets&&null!==e.useProtobufQuadtreePackets&&(t.useProtobufQuadtreePackets=Boolean(e.useProtobufQuadtreePackets)),void 0!==e.useExtendedCopyrightIds&&null!==e.useExtendedCopyrightIds&&(t.useExtendedCopyrightIds=Boolean(e.useExtendedCopyrightIds)),void 0!==e.precipitationsOptions&&null!==e.precipitationsOptions){if("object"!=typeof e.precipitationsOptions)throw TypeError(".keyhole.dbroot.ClientOptionsProto.precipitationsOptions: object expected");t.precipitationsOptions=a[7].fromObject(e.precipitationsOptions)}if(void 0!==e.captureOptions&&null!==e.captureOptions){if("object"!=typeof e.captureOptions)throw TypeError(".keyhole.dbroot.ClientOptionsProto.captureOptions: object expected");t.captureOptions=a[8].fromObject(e.captureOptions)}if(void 0!==e.show_2dMapsIcon&&null!==e.show_2dMapsIcon&&(t.show_2dMapsIcon=Boolean(e.show_2dMapsIcon)),void 0!==e.disableInternalBrowser&&null!==e.disableInternalBrowser&&(t.disableInternalBrowser=Boolean(e.disableInternalBrowser)),void 0!==e.internalBrowserBlacklist&&null!==e.internalBrowserBlacklist&&(t.internalBrowserBlacklist=String(e.internalBrowserBlacklist)),void 0!==e.internalBrowserOriginWhitelist&&null!==e.internalBrowserOriginWhitelist&&(t.internalBrowserOriginWhitelist=String(e.internalBrowserOriginWhitelist)),void 0!==e.polarTileMergingLevel&&null!==e.polarTileMergingLevel&&(t.polarTileMergingLevel=0|e.polarTileMergingLevel),void 0!==e.jsBridgeRequestWhitelist&&null!==e.jsBridgeRequestWhitelist&&(t.jsBridgeRequestWhitelist=String(e.jsBridgeRequestWhitelist)),void 0!==e.mapsOptions&&null!==e.mapsOptions){if("object"!=typeof e.mapsOptions)throw TypeError(".keyhole.dbroot.ClientOptionsProto.mapsOptions: object expected");t.mapsOptions=a[15].fromObject(e.mapsOptions)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.disableDiskCache=!1,r.disableEmbeddedBrowserVista=!1,r.drawAtmosphere=!0,r.drawStars=!0,r.shaderFilePrefix="",r.useProtobufQuadtreePackets=!1,r.useExtendedCopyrightIds=!0,r.precipitationsOptions=null,r.captureOptions=null,r.show_2dMapsIcon=!0,r.disableInternalBrowser=!1,r.internalBrowserBlacklist="",r.internalBrowserOriginWhitelist="*",r.polarTileMergingLevel=0,r.jsBridgeRequestWhitelist="http://*.google.com/*",r.mapsOptions=null),void 0!==e.disableDiskCache&&null!==e.disableDiskCache&&e.hasOwnProperty("disableDiskCache")&&(r.disableDiskCache=e.disableDiskCache),void 0!==e.disableEmbeddedBrowserVista&&null!==e.disableEmbeddedBrowserVista&&e.hasOwnProperty("disableEmbeddedBrowserVista")&&(r.disableEmbeddedBrowserVista=e.disableEmbeddedBrowserVista),void 0!==e.drawAtmosphere&&null!==e.drawAtmosphere&&e.hasOwnProperty("drawAtmosphere")&&(r.drawAtmosphere=e.drawAtmosphere),void 0!==e.drawStars&&null!==e.drawStars&&e.hasOwnProperty("drawStars")&&(r.drawStars=e.drawStars),void 0!==e.shaderFilePrefix&&null!==e.shaderFilePrefix&&e.hasOwnProperty("shaderFilePrefix")&&(r.shaderFilePrefix=e.shaderFilePrefix),void 0!==e.useProtobufQuadtreePackets&&null!==e.useProtobufQuadtreePackets&&e.hasOwnProperty("useProtobufQuadtreePackets")&&(r.useProtobufQuadtreePackets=e.useProtobufQuadtreePackets),void 0!==e.useExtendedCopyrightIds&&null!==e.useExtendedCopyrightIds&&e.hasOwnProperty("useExtendedCopyrightIds")&&(r.useExtendedCopyrightIds=e.useExtendedCopyrightIds),void 0!==e.precipitationsOptions&&null!==e.precipitationsOptions&&e.hasOwnProperty("precipitationsOptions")&&(r.precipitationsOptions=a[7].toObject(e.precipitationsOptions,t)),void 0!==e.captureOptions&&null!==e.captureOptions&&e.hasOwnProperty("captureOptions")&&(r.captureOptions=a[8].toObject(e.captureOptions,t)),void 0!==e.show_2dMapsIcon&&null!==e.show_2dMapsIcon&&e.hasOwnProperty("show_2dMapsIcon")&&(r.show_2dMapsIcon=e.show_2dMapsIcon),void 0!==e.disableInternalBrowser&&null!==e.disableInternalBrowser&&e.hasOwnProperty("disableInternalBrowser")&&(r.disableInternalBrowser=e.disableInternalBrowser),void 0!==e.internalBrowserBlacklist&&null!==e.internalBrowserBlacklist&&e.hasOwnProperty("internalBrowserBlacklist")&&(r.internalBrowserBlacklist=e.internalBrowserBlacklist),void 0!==e.internalBrowserOriginWhitelist&&null!==e.internalBrowserOriginWhitelist&&e.hasOwnProperty("internalBrowserOriginWhitelist")&&(r.internalBrowserOriginWhitelist=e.internalBrowserOriginWhitelist),void 0!==e.polarTileMergingLevel&&null!==e.polarTileMergingLevel&&e.hasOwnProperty("polarTileMergingLevel")&&(r.polarTileMergingLevel=e.polarTileMergingLevel),void 0!==e.jsBridgeRequestWhitelist&&null!==e.jsBridgeRequestWhitelist&&e.hasOwnProperty("jsBridgeRequestWhitelist")&&(r.jsBridgeRequestWhitelist=e.jsBridgeRequestWhitelist),void 0!==e.mapsOptions&&null!==e.mapsOptions&&e.hasOwnProperty("mapsOptions")&&(r.mapsOptions=a[15].toObject(e.mapsOptions,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.PrecipitationsOptions=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.imageUrl="",o.prototype.imageExpireTime=900,o.prototype.maxColorDistance=20,o.prototype.imageLevel=5,o.prototype.weatherMapping=r.emptyArray,o.prototype.cloudsLayerUrl="",o.prototype.animationDecelerationDelay=20;var a={4:"keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.imageUrl=e.string();break;case 2:o.imageExpireTime=e.int32();break;case 3:o.maxColorDistance=e.int32();break;case 4:o.imageLevel=e.int32();break;case 5:o.weatherMapping&&o.weatherMapping.length||(o.weatherMapping=[]),o.weatherMapping.push(a[4].decode(e,e.uint32()));break;case 6:o.cloudsLayerUrl=e.string();break;case 7:o.animationDecelerationDelay=e.float();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.imageUrl&&!r.isString(e.imageUrl))return"imageUrl: string expected";if(void 0!==e.imageExpireTime&&!r.isInteger(e.imageExpireTime))return"imageExpireTime: integer expected";if(void 0!==e.maxColorDistance&&!r.isInteger(e.maxColorDistance))return"maxColorDistance: integer expected";if(void 0!==e.imageLevel&&!r.isInteger(e.imageLevel))return"imageLevel: integer expected";if(void 0!==e.weatherMapping){if(!Array.isArray(e.weatherMapping))return"weatherMapping: array expected";for(var t=0;t<e.weatherMapping.length;++t){var i=a[4].verify(e.weatherMapping[t]);if(i)return"weatherMapping."+i}}return void 0===e.cloudsLayerUrl||r.isString(e.cloudsLayerUrl)?void 0!==e.animationDecelerationDelay&&"number"!=typeof e.animationDecelerationDelay?"animationDecelerationDelay: number expected":null:"cloudsLayerUrl: string expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions;if(void 0!==e.imageUrl&&null!==e.imageUrl&&(t.imageUrl=String(e.imageUrl)),void 0!==e.imageExpireTime&&null!==e.imageExpireTime&&(t.imageExpireTime=0|e.imageExpireTime),void 0!==e.maxColorDistance&&null!==e.maxColorDistance&&(t.maxColorDistance=0|e.maxColorDistance),void 0!==e.imageLevel&&null!==e.imageLevel&&(t.imageLevel=0|e.imageLevel),e.weatherMapping){if(!Array.isArray(e.weatherMapping))throw TypeError(".keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.weatherMapping: array expected");t.weatherMapping=[];for(var r=0;r<e.weatherMapping.length;++r){if("object"!=typeof e.weatherMapping[r])throw TypeError(".keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.weatherMapping: object expected");t.weatherMapping[r]=a[4].fromObject(e.weatherMapping[r])}}return void 0!==e.cloudsLayerUrl&&null!==e.cloudsLayerUrl&&(t.cloudsLayerUrl=String(e.cloudsLayerUrl)),void 0!==e.animationDecelerationDelay&&null!==e.animationDecelerationDelay&&(t.animationDecelerationDelay=Number(e.animationDecelerationDelay)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.weatherMapping=[]),t.defaults&&(r.imageUrl="",r.imageExpireTime=900,r.maxColorDistance=20,r.imageLevel=5,r.cloudsLayerUrl="",r.animationDecelerationDelay=20),void 0!==e.imageUrl&&null!==e.imageUrl&&e.hasOwnProperty("imageUrl")&&(r.imageUrl=e.imageUrl),void 0!==e.imageExpireTime&&null!==e.imageExpireTime&&e.hasOwnProperty("imageExpireTime")&&(r.imageExpireTime=e.imageExpireTime),void 0!==e.maxColorDistance&&null!==e.maxColorDistance&&e.hasOwnProperty("maxColorDistance")&&(r.maxColorDistance=e.maxColorDistance),void 0!==e.imageLevel&&null!==e.imageLevel&&e.hasOwnProperty("imageLevel")&&(r.imageLevel=e.imageLevel),void 0!==e.weatherMapping&&null!==e.weatherMapping&&e.hasOwnProperty("weatherMapping")){r.weatherMapping=[];for(var i=0;i<e.weatherMapping.length;++i)r.weatherMapping[i]=a[4].toObject(e.weatherMapping[i],t)}return void 0!==e.cloudsLayerUrl&&null!==e.cloudsLayerUrl&&e.hasOwnProperty("cloudsLayerUrl")&&(r.cloudsLayerUrl=e.cloudsLayerUrl),void 0!==e.animationDecelerationDelay&&null!==e.animationDecelerationDelay&&e.hasOwnProperty("animationDecelerationDelay")&&(r.animationDecelerationDelay=e.animationDecelerationDelay),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.WeatherMapping=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.colorAbgr=0,o.prototype.weatherType=0,o.prototype.elongation=1,o.prototype.opacity=0,o.prototype.fogDensity=0,o.prototype.speed0=0,o.prototype.speed1=0,o.prototype.speed2=0,o.prototype.speed3=0;var a={1:"keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping.WeatherType"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.colorAbgr=e.uint32() +;break;case 2:o.weatherType=e.uint32();break;case 3:o.elongation=e.float();break;case 4:o.opacity=e.float();break;case 5:o.fogDensity=e.float();break;case 6:o.speed0=e.float();break;case 7:o.speed1=e.float();break;case 8:o.speed2=e.float();break;case 9:o.speed3=e.float();break;default:e.skipType(7&a)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isInteger(e.colorAbgr))return"colorAbgr: integer expected";switch(e.weatherType){default:return"weatherType: enum value expected";case 0:case 1:case 2:}return void 0!==e.elongation&&"number"!=typeof e.elongation?"elongation: number expected":void 0!==e.opacity&&"number"!=typeof e.opacity?"opacity: number expected":void 0!==e.fogDensity&&"number"!=typeof e.fogDensity?"fogDensity: number expected":void 0!==e.speed0&&"number"!=typeof e.speed0?"speed0: number expected":void 0!==e.speed1&&"number"!=typeof e.speed1?"speed1: number expected":void 0!==e.speed2&&"number"!=typeof e.speed2?"speed2: number expected":void 0!==e.speed3&&"number"!=typeof e.speed3?"speed3: number expected":null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping;switch(void 0!==e.colorAbgr&&null!==e.colorAbgr&&(t.colorAbgr=e.colorAbgr>>>0),e.weatherType){case"NO_PRECIPITATION":case 0:t.weatherType=0;break;case"RAIN":case 1:t.weatherType=1;break;case"SNOW":case 2:t.weatherType=2}return void 0!==e.elongation&&null!==e.elongation&&(t.elongation=Number(e.elongation)),void 0!==e.opacity&&null!==e.opacity&&(t.opacity=Number(e.opacity)),void 0!==e.fogDensity&&null!==e.fogDensity&&(t.fogDensity=Number(e.fogDensity)),void 0!==e.speed0&&null!==e.speed0&&(t.speed0=Number(e.speed0)),void 0!==e.speed1&&null!==e.speed1&&(t.speed1=Number(e.speed1)),void 0!==e.speed2&&null!==e.speed2&&(t.speed2=Number(e.speed2)),void 0!==e.speed3&&null!==e.speed3&&(t.speed3=Number(e.speed3)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.colorAbgr=0,r.weatherType=t.enums===String?"NO_PRECIPITATION":0,r.elongation=1,r.opacity=0,r.fogDensity=0,r.speed0=0,r.speed1=0,r.speed2=0,r.speed3=0),void 0!==e.colorAbgr&&null!==e.colorAbgr&&e.hasOwnProperty("colorAbgr")&&(r.colorAbgr=e.colorAbgr),void 0!==e.weatherType&&null!==e.weatherType&&e.hasOwnProperty("weatherType")&&(r.weatherType=t.enums===String?a[1][e.weatherType]:e.weatherType),void 0!==e.elongation&&null!==e.elongation&&e.hasOwnProperty("elongation")&&(r.elongation=e.elongation),void 0!==e.opacity&&null!==e.opacity&&e.hasOwnProperty("opacity")&&(r.opacity=e.opacity),void 0!==e.fogDensity&&null!==e.fogDensity&&e.hasOwnProperty("fogDensity")&&(r.fogDensity=e.fogDensity),void 0!==e.speed0&&null!==e.speed0&&e.hasOwnProperty("speed0")&&(r.speed0=e.speed0),void 0!==e.speed1&&null!==e.speed1&&e.hasOwnProperty("speed1")&&(r.speed1=e.speed1),void 0!==e.speed2&&null!==e.speed2&&e.hasOwnProperty("speed2")&&(r.speed2=e.speed2),void 0!==e.speed3&&null!==e.speed3&&e.hasOwnProperty("speed3")&&(r.speed3=e.speed3),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.WeatherType=function(){var e={},t=Object.create(e);return t.NO_PRECIPITATION=0,t.RAIN=1,t.SNOW=2,t}(),o}(),o}(),o.CaptureOptions=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.allowSaveAsImage=!0,i.prototype.maxFreeCaptureRes=2400,i.prototype.maxPremiumCaptureRes=4800,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ClientOptionsProto.CaptureOptions;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.allowSaveAsImage=e.bool();break;case 2:o.maxFreeCaptureRes=e.int32();break;case 3:o.maxPremiumCaptureRes=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.allowSaveAsImage&&"boolean"!=typeof e.allowSaveAsImage?"allowSaveAsImage: boolean expected":void 0===e.maxFreeCaptureRes||r.isInteger(e.maxFreeCaptureRes)?void 0===e.maxPremiumCaptureRes||r.isInteger(e.maxPremiumCaptureRes)?null:"maxPremiumCaptureRes: integer expected":"maxFreeCaptureRes: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.CaptureOptions)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.CaptureOptions;return void 0!==e.allowSaveAsImage&&null!==e.allowSaveAsImage&&(t.allowSaveAsImage=Boolean(e.allowSaveAsImage)),void 0!==e.maxFreeCaptureRes&&null!==e.maxFreeCaptureRes&&(t.maxFreeCaptureRes=0|e.maxFreeCaptureRes),void 0!==e.maxPremiumCaptureRes&&null!==e.maxPremiumCaptureRes&&(t.maxPremiumCaptureRes=0|e.maxPremiumCaptureRes),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.allowSaveAsImage=!0,r.maxFreeCaptureRes=2400,r.maxPremiumCaptureRes=4800),void 0!==e.allowSaveAsImage&&null!==e.allowSaveAsImage&&e.hasOwnProperty("allowSaveAsImage")&&(r.allowSaveAsImage=e.allowSaveAsImage),void 0!==e.maxFreeCaptureRes&&null!==e.maxFreeCaptureRes&&e.hasOwnProperty("maxFreeCaptureRes")&&(r.maxFreeCaptureRes=e.maxFreeCaptureRes),void 0!==e.maxPremiumCaptureRes&&null!==e.maxPremiumCaptureRes&&e.hasOwnProperty("maxPremiumCaptureRes")&&(r.maxPremiumCaptureRes=e.maxPremiumCaptureRes),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.MapsOptions=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.enableMaps=!1,i.prototype.docsAutoDownloadEnabled=!1,i.prototype.docsAutoDownloadInterval=0,i.prototype.docsAutoUploadEnabled=!1,i.prototype.docsAutoUploadDelay=0,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ClientOptionsProto.MapsOptions;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.enableMaps=e.bool();break;case 2:o.docsAutoDownloadEnabled=e.bool();break;case 3:o.docsAutoDownloadInterval=e.int32();break;case 4:o.docsAutoUploadEnabled=e.bool();break;case 5:o.docsAutoUploadDelay=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.enableMaps&&"boolean"!=typeof e.enableMaps?"enableMaps: boolean expected":void 0!==e.docsAutoDownloadEnabled&&"boolean"!=typeof e.docsAutoDownloadEnabled?"docsAutoDownloadEnabled: boolean expected":void 0===e.docsAutoDownloadInterval||r.isInteger(e.docsAutoDownloadInterval)?void 0!==e.docsAutoUploadEnabled&&"boolean"!=typeof e.docsAutoUploadEnabled?"docsAutoUploadEnabled: boolean expected":void 0===e.docsAutoUploadDelay||r.isInteger(e.docsAutoUploadDelay)?null:"docsAutoUploadDelay: integer expected":"docsAutoDownloadInterval: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ClientOptionsProto.MapsOptions)return e;var t=new n.keyhole.dbroot.ClientOptionsProto.MapsOptions;return void 0!==e.enableMaps&&null!==e.enableMaps&&(t.enableMaps=Boolean(e.enableMaps)),void 0!==e.docsAutoDownloadEnabled&&null!==e.docsAutoDownloadEnabled&&(t.docsAutoDownloadEnabled=Boolean(e.docsAutoDownloadEnabled)),void 0!==e.docsAutoDownloadInterval&&null!==e.docsAutoDownloadInterval&&(t.docsAutoDownloadInterval=0|e.docsAutoDownloadInterval),void 0!==e.docsAutoUploadEnabled&&null!==e.docsAutoUploadEnabled&&(t.docsAutoUploadEnabled=Boolean(e.docsAutoUploadEnabled)),void 0!==e.docsAutoUploadDelay&&null!==e.docsAutoUploadDelay&&(t.docsAutoUploadDelay=0|e.docsAutoUploadDelay),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.enableMaps=!1,r.docsAutoDownloadEnabled=!1,r.docsAutoDownloadInterval=0,r.docsAutoUploadEnabled=!1,r.docsAutoUploadDelay=0),void 0!==e.enableMaps&&null!==e.enableMaps&&e.hasOwnProperty("enableMaps")&&(r.enableMaps=e.enableMaps),void 0!==e.docsAutoDownloadEnabled&&null!==e.docsAutoDownloadEnabled&&e.hasOwnProperty("docsAutoDownloadEnabled")&&(r.docsAutoDownloadEnabled=e.docsAutoDownloadEnabled),void 0!==e.docsAutoDownloadInterval&&null!==e.docsAutoDownloadInterval&&e.hasOwnProperty("docsAutoDownloadInterval")&&(r.docsAutoDownloadInterval=e.docsAutoDownloadInterval),void 0!==e.docsAutoUploadEnabled&&null!==e.docsAutoUploadEnabled&&e.hasOwnProperty("docsAutoUploadEnabled")&&(r.docsAutoUploadEnabled=e.docsAutoUploadEnabled),void 0!==e.docsAutoUploadDelay&&null!==e.docsAutoUploadDelay&&e.hasOwnProperty("docsAutoUploadDelay")&&(r.docsAutoUploadDelay=e.docsAutoUploadDelay),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o}(),o.FetchingOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.maxRequestsPerQuery=1,i.prototype.forceMaxRequestsPerQuery=!1,i.prototype.sortBatches=!1,i.prototype.maxDrawable=2,i.prototype.maxImagery=2,i.prototype.maxTerrain=5,i.prototype.maxQuadtree=5,i.prototype.maxDioramaMetadata=1,i.prototype.maxDioramaData=0,i.prototype.maxConsumerFetchRatio=1,i.prototype.maxProEcFetchRatio=0,i.prototype.safeOverallQps=0,i.prototype.safeImageryQps=0,i.prototype.domainsForHttps="google.com gstatic.com",i.prototype.hostsForHttp="",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.FetchingOptionsProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.maxRequestsPerQuery=e.int32();break;case 12:o.forceMaxRequestsPerQuery=e.bool();break;case 13:o.sortBatches=e.bool();break;case 2:o.maxDrawable=e.int32();break;case 3:o.maxImagery=e.int32();break;case 4:o.maxTerrain=e.int32();break;case 5:o.maxQuadtree=e.int32();break;case 6:o.maxDioramaMetadata=e.int32();break;case 7:o.maxDioramaData=e.int32();break;case 8:o.maxConsumerFetchRatio=e.float();break;case 9:o.maxProEcFetchRatio=e.float();break;case 10:o.safeOverallQps=e.float();break;case 11:o.safeImageryQps=e.float();break;case 14:o.domainsForHttps=e.string();break;case 15:o.hostsForHttp=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.maxRequestsPerQuery||r.isInteger(e.maxRequestsPerQuery)?void 0!==e.forceMaxRequestsPerQuery&&"boolean"!=typeof e.forceMaxRequestsPerQuery?"forceMaxRequestsPerQuery: boolean expected":void 0!==e.sortBatches&&"boolean"!=typeof e.sortBatches?"sortBatches: boolean expected":void 0===e.maxDrawable||r.isInteger(e.maxDrawable)?void 0===e.maxImagery||r.isInteger(e.maxImagery)?void 0===e.maxTerrain||r.isInteger(e.maxTerrain)?void 0===e.maxQuadtree||r.isInteger(e.maxQuadtree)?void 0===e.maxDioramaMetadata||r.isInteger(e.maxDioramaMetadata)?void 0===e.maxDioramaData||r.isInteger(e.maxDioramaData)?void 0!==e.maxConsumerFetchRatio&&"number"!=typeof e.maxConsumerFetchRatio?"maxConsumerFetchRatio: number expected":void 0!==e.maxProEcFetchRatio&&"number"!=typeof e.maxProEcFetchRatio?"maxProEcFetchRatio: number expected":void 0!==e.safeOverallQps&&"number"!=typeof e.safeOverallQps?"safeOverallQps: number expected":void 0!==e.safeImageryQps&&"number"!=typeof e.safeImageryQps?"safeImageryQps: number expected":void 0===e.domainsForHttps||r.isString(e.domainsForHttps)?void 0===e.hostsForHttp||r.isString(e.hostsForHttp)?null:"hostsForHttp: string expected":"domainsForHttps: string expected":"maxDioramaData: integer expected":"maxDioramaMetadata: integer expected":"maxQuadtree: integer expected":"maxTerrain: integer expected":"maxImagery: integer expected":"maxDrawable: integer expected":"maxRequestsPerQuery: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.FetchingOptionsProto)return e;var t=new n.keyhole.dbroot.FetchingOptionsProto;return void 0!==e.maxRequestsPerQuery&&null!==e.maxRequestsPerQuery&&(t.maxRequestsPerQuery=0|e.maxRequestsPerQuery),void 0!==e.forceMaxRequestsPerQuery&&null!==e.forceMaxRequestsPerQuery&&(t.forceMaxRequestsPerQuery=Boolean(e.forceMaxRequestsPerQuery)),void 0!==e.sortBatches&&null!==e.sortBatches&&(t.sortBatches=Boolean(e.sortBatches)),void 0!==e.maxDrawable&&null!==e.maxDrawable&&(t.maxDrawable=0|e.maxDrawable),void 0!==e.maxImagery&&null!==e.maxImagery&&(t.maxImagery=0|e.maxImagery),void 0!==e.maxTerrain&&null!==e.maxTerrain&&(t.maxTerrain=0|e.maxTerrain),void 0!==e.maxQuadtree&&null!==e.maxQuadtree&&(t.maxQuadtree=0|e.maxQuadtree),void 0!==e.maxDioramaMetadata&&null!==e.maxDioramaMetadata&&(t.maxDioramaMetadata=0|e.maxDioramaMetadata),void 0!==e.maxDioramaData&&null!==e.maxDioramaData&&(t.maxDioramaData=0|e.maxDioramaData),void 0!==e.maxConsumerFetchRatio&&null!==e.maxConsumerFetchRatio&&(t.maxConsumerFetchRatio=Number(e.maxConsumerFetchRatio)),void 0!==e.maxProEcFetchRatio&&null!==e.maxProEcFetchRatio&&(t.maxProEcFetchRatio=Number(e.maxProEcFetchRatio)),void 0!==e.safeOverallQps&&null!==e.safeOverallQps&&(t.safeOverallQps=Number(e.safeOverallQps)),void 0!==e.safeImageryQps&&null!==e.safeImageryQps&&(t.safeImageryQps=Number(e.safeImageryQps)),void 0!==e.domainsForHttps&&null!==e.domainsForHttps&&(t.domainsForHttps=String(e.domainsForHttps)),void 0!==e.hostsForHttp&&null!==e.hostsForHttp&&(t.hostsForHttp=String(e.hostsForHttp)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.maxRequestsPerQuery=1,r.forceMaxRequestsPerQuery=!1,r.sortBatches=!1,r.maxDrawable=2,r.maxImagery=2,r.maxTerrain=5,r.maxQuadtree=5,r.maxDioramaMetadata=1,r.maxDioramaData=0,r.maxConsumerFetchRatio=1,r.maxProEcFetchRatio=0,r.safeOverallQps=0,r.safeImageryQps=0,r.domainsForHttps="google.com gstatic.com",r.hostsForHttp=""),void 0!==e.maxRequestsPerQuery&&null!==e.maxRequestsPerQuery&&e.hasOwnProperty("maxRequestsPerQuery")&&(r.maxRequestsPerQuery=e.maxRequestsPerQuery),void 0!==e.forceMaxRequestsPerQuery&&null!==e.forceMaxRequestsPerQuery&&e.hasOwnProperty("forceMaxRequestsPerQuery")&&(r.forceMaxRequestsPerQuery=e.forceMaxRequestsPerQuery),void 0!==e.sortBatches&&null!==e.sortBatches&&e.hasOwnProperty("sortBatches")&&(r.sortBatches=e.sortBatches),void 0!==e.maxDrawable&&null!==e.maxDrawable&&e.hasOwnProperty("maxDrawable")&&(r.maxDrawable=e.maxDrawable),void 0!==e.maxImagery&&null!==e.maxImagery&&e.hasOwnProperty("maxImagery")&&(r.maxImagery=e.maxImagery),void 0!==e.maxTerrain&&null!==e.maxTerrain&&e.hasOwnProperty("maxTerrain")&&(r.maxTerrain=e.maxTerrain),void 0!==e.maxQuadtree&&null!==e.maxQuadtree&&e.hasOwnProperty("maxQuadtree")&&(r.maxQuadtree=e.maxQuadtree),void 0!==e.maxDioramaMetadata&&null!==e.maxDioramaMetadata&&e.hasOwnProperty("maxDioramaMetadata")&&(r.maxDioramaMetadata=e.maxDioramaMetadata),void 0!==e.maxDioramaData&&null!==e.maxDioramaData&&e.hasOwnProperty("maxDioramaData")&&(r.maxDioramaData=e.maxDioramaData),void 0!==e.maxConsumerFetchRatio&&null!==e.maxConsumerFetchRatio&&e.hasOwnProperty("maxConsumerFetchRatio")&&(r.maxConsumerFetchRatio=e.maxConsumerFetchRatio),void 0!==e.maxProEcFetchRatio&&null!==e.maxProEcFetchRatio&&e.hasOwnProperty("maxProEcFetchRatio")&&(r.maxProEcFetchRatio=e.maxProEcFetchRatio),void 0!==e.safeOverallQps&&null!==e.safeOverallQps&&e.hasOwnProperty("safeOverallQps")&&(r.safeOverallQps=e.safeOverallQps),void 0!==e.safeImageryQps&&null!==e.safeImageryQps&&e.hasOwnProperty("safeImageryQps")&&(r.safeImageryQps=e.safeImageryQps),void 0!==e.domainsForHttps&&null!==e.domainsForHttps&&e.hasOwnProperty("domainsForHttps")&&(r.domainsForHttps=e.domainsForHttps),void 0!==e.hostsForHttp&&null!==e.hostsForHttp&&e.hasOwnProperty("hostsForHttp")&&(r.hostsForHttp=e.hostsForHttp),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.TimeMachineOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.serverUrl="",i.prototype.isTimemachine=!1,i.prototype.dwellTimeMs=500,i.prototype.discoverabilityAltitudeMeters=15e3,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.TimeMachineOptionsProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.serverUrl=e.string();break;case 2:o.isTimemachine=e.bool();break;case 3:o.dwellTimeMs=e.int32();break;case 4:o.discoverabilityAltitudeMeters=e.int32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.serverUrl||r.isString(e.serverUrl)?void 0!==e.isTimemachine&&"boolean"!=typeof e.isTimemachine?"isTimemachine: boolean expected":void 0===e.dwellTimeMs||r.isInteger(e.dwellTimeMs)?void 0===e.discoverabilityAltitudeMeters||r.isInteger(e.discoverabilityAltitudeMeters)?null:"discoverabilityAltitudeMeters: integer expected":"dwellTimeMs: integer expected":"serverUrl: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.TimeMachineOptionsProto)return e;var t=new n.keyhole.dbroot.TimeMachineOptionsProto;return void 0!==e.serverUrl&&null!==e.serverUrl&&(t.serverUrl=String(e.serverUrl)),void 0!==e.isTimemachine&&null!==e.isTimemachine&&(t.isTimemachine=Boolean(e.isTimemachine)),void 0!==e.dwellTimeMs&&null!==e.dwellTimeMs&&(t.dwellTimeMs=0|e.dwellTimeMs),void 0!==e.discoverabilityAltitudeMeters&&null!==e.discoverabilityAltitudeMeters&&(t.discoverabilityAltitudeMeters=0|e.discoverabilityAltitudeMeters),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.serverUrl="",r.isTimemachine=!1,r.dwellTimeMs=500,r.discoverabilityAltitudeMeters=15e3),void 0!==e.serverUrl&&null!==e.serverUrl&&e.hasOwnProperty("serverUrl")&&(r.serverUrl=e.serverUrl),void 0!==e.isTimemachine&&null!==e.isTimemachine&&e.hasOwnProperty("isTimemachine")&&(r.isTimemachine=e.isTimemachine),void 0!==e.dwellTimeMs&&null!==e.dwellTimeMs&&e.hasOwnProperty("dwellTimeMs")&&(r.dwellTimeMs=e.dwellTimeMs),void 0!==e.discoverabilityAltitudeMeters&&null!==e.discoverabilityAltitudeMeters&&e.hasOwnProperty("discoverabilityAltitudeMeters")&&(r.discoverabilityAltitudeMeters=e.discoverabilityAltitudeMeters),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.AutopiaOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.metadataServerUrl="http://cbk0.google.com/cbk",i.prototype.depthmapServerUrl="http://cbk0.google.com/cbk",i.prototype.coverageOverlayUrl="",i.prototype.maxImageryQps=0,i.prototype.maxMetadataDepthmapQps=0,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.AutopiaOptionsProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.metadataServerUrl=e.string();break;case 2:o.depthmapServerUrl=e.string();break;case 3:o.coverageOverlayUrl=e.string();break;case 4:o.maxImageryQps=e.float();break;case 5:o.maxMetadataDepthmapQps=e.float();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.metadataServerUrl||r.isString(e.metadataServerUrl)?void 0===e.depthmapServerUrl||r.isString(e.depthmapServerUrl)?void 0===e.coverageOverlayUrl||r.isString(e.coverageOverlayUrl)?void 0!==e.maxImageryQps&&"number"!=typeof e.maxImageryQps?"maxImageryQps: number expected":void 0!==e.maxMetadataDepthmapQps&&"number"!=typeof e.maxMetadataDepthmapQps?"maxMetadataDepthmapQps: number expected":null:"coverageOverlayUrl: string expected":"depthmapServerUrl: string expected":"metadataServerUrl: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.AutopiaOptionsProto)return e;var t=new n.keyhole.dbroot.AutopiaOptionsProto;return void 0!==e.metadataServerUrl&&null!==e.metadataServerUrl&&(t.metadataServerUrl=String(e.metadataServerUrl)),void 0!==e.depthmapServerUrl&&null!==e.depthmapServerUrl&&(t.depthmapServerUrl=String(e.depthmapServerUrl)),void 0!==e.coverageOverlayUrl&&null!==e.coverageOverlayUrl&&(t.coverageOverlayUrl=String(e.coverageOverlayUrl)),void 0!==e.maxImageryQps&&null!==e.maxImageryQps&&(t.maxImageryQps=Number(e.maxImageryQps)),void 0!==e.maxMetadataDepthmapQps&&null!==e.maxMetadataDepthmapQps&&(t.maxMetadataDepthmapQps=Number(e.maxMetadataDepthmapQps)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.metadataServerUrl="http://cbk0.google.com/cbk",r.depthmapServerUrl="http://cbk0.google.com/cbk",r.coverageOverlayUrl="",r.maxImageryQps=0,r.maxMetadataDepthmapQps=0),void 0!==e.metadataServerUrl&&null!==e.metadataServerUrl&&e.hasOwnProperty("metadataServerUrl")&&(r.metadataServerUrl=e.metadataServerUrl),void 0!==e.depthmapServerUrl&&null!==e.depthmapServerUrl&&e.hasOwnProperty("depthmapServerUrl")&&(r.depthmapServerUrl=e.depthmapServerUrl),void 0!==e.coverageOverlayUrl&&null!==e.coverageOverlayUrl&&e.hasOwnProperty("coverageOverlayUrl")&&(r.coverageOverlayUrl=e.coverageOverlayUrl),void 0!==e.maxImageryQps&&null!==e.maxImageryQps&&e.hasOwnProperty("maxImageryQps")&&(r.maxImageryQps=e.maxImageryQps),void 0!==e.maxMetadataDepthmapQps&&null!==e.maxMetadataDepthmapQps&&e.hasOwnProperty("maxMetadataDepthmapQps")&&(r.maxMetadataDepthmapQps=e.maxMetadataDepthmapQps),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.CSIOptionsProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.samplingPercentage=0,i.prototype.experimentId="",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.CSIOptionsProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.samplingPercentage=e.int32();break;case 2:o.experimentId=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.samplingPercentage||r.isInteger(e.samplingPercentage)?void 0===e.experimentId||r.isString(e.experimentId)?null:"experimentId: string expected":"samplingPercentage: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.CSIOptionsProto)return e;var t=new n.keyhole.dbroot.CSIOptionsProto;return void 0!==e.samplingPercentage&&null!==e.samplingPercentage&&(t.samplingPercentage=0|e.samplingPercentage),void 0!==e.experimentId&&null!==e.experimentId&&(t.experimentId=String(e.experimentId)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.samplingPercentage=0,r.experimentId=""),void 0!==e.samplingPercentage&&null!==e.samplingPercentage&&e.hasOwnProperty("samplingPercentage")&&(r.samplingPercentage=e.samplingPercentage),void 0!==e.experimentId&&null!==e.experimentId&&e.hasOwnProperty("experimentId")&&(r.experimentId=e.experimentId),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.SearchTabProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.isVisible=!1,o.prototype.tabLabel=null,o.prototype.baseUrl="",o.prototype.viewportPrefix="",o.prototype.inputBox=r.emptyArray,o.prototype.requirement=null;var a={1:"keyhole.dbroot.StringIdOrValueProto",4:"keyhole.dbroot.SearchTabProto.InputBoxInfo",5:"keyhole.dbroot.RequirementProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.SearchTabProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.isVisible=e.bool();break;case 2:o.tabLabel=a[1].decode(e,e.uint32());break;case 3:o.baseUrl=e.string();break;case 4:o.viewportPrefix=e.string();break;case 5:o.inputBox&&o.inputBox.length||(o.inputBox=[]),o.inputBox.push(a[4].decode(e,e.uint32()));break;case 6:o.requirement=a[5].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if("boolean"!=typeof e.isVisible)return"isVisible: boolean expected";if(void 0!==e.tabLabel&&null!==e.tabLabel){var t=a[1].verify(e.tabLabel);if(t)return"tabLabel."+t}if(void 0!==e.baseUrl&&!r.isString(e.baseUrl))return"baseUrl: string expected";if(void 0!==e.viewportPrefix&&!r.isString(e.viewportPrefix))return"viewportPrefix: string expected";if(void 0!==e.inputBox){if(!Array.isArray(e.inputBox))return"inputBox: array expected";for(var i=0;i<e.inputBox.length;++i){var t=a[4].verify(e.inputBox[i]);if(t)return"inputBox."+t}}if(void 0!==e.requirement&&null!==e.requirement){var t=a[5].verify(e.requirement);if(t)return"requirement."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.SearchTabProto)return e;var t=new n.keyhole.dbroot.SearchTabProto;if(void 0!==e.isVisible&&null!==e.isVisible&&(t.isVisible=Boolean(e.isVisible)),void 0!==e.tabLabel&&null!==e.tabLabel){if("object"!=typeof e.tabLabel)throw TypeError(".keyhole.dbroot.SearchTabProto.tabLabel: object expected");t.tabLabel=a[1].fromObject(e.tabLabel)}if(void 0!==e.baseUrl&&null!==e.baseUrl&&(t.baseUrl=String(e.baseUrl)),void 0!==e.viewportPrefix&&null!==e.viewportPrefix&&(t.viewportPrefix=String(e.viewportPrefix)),e.inputBox){if(!Array.isArray(e.inputBox))throw TypeError(".keyhole.dbroot.SearchTabProto.inputBox: array expected");t.inputBox=[];for(var r=0;r<e.inputBox.length;++r){if("object"!=typeof e.inputBox[r])throw TypeError(".keyhole.dbroot.SearchTabProto.inputBox: object expected");t.inputBox[r]=a[4].fromObject(e.inputBox[r])}}if(void 0!==e.requirement&&null!==e.requirement){if("object"!=typeof e.requirement)throw TypeError(".keyhole.dbroot.SearchTabProto.requirement: object expected");t.requirement=a[5].fromObject(e.requirement)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.inputBox=[]),t.defaults&&(r.isVisible=!1,r.tabLabel=null,r.baseUrl="",r.viewportPrefix="",r.requirement=null),void 0!==e.isVisible&&null!==e.isVisible&&e.hasOwnProperty("isVisible")&&(r.isVisible=e.isVisible),void 0!==e.tabLabel&&null!==e.tabLabel&&e.hasOwnProperty("tabLabel")&&(r.tabLabel=a[1].toObject(e.tabLabel,t)),void 0!==e.baseUrl&&null!==e.baseUrl&&e.hasOwnProperty("baseUrl")&&(r.baseUrl=e.baseUrl),void 0!==e.viewportPrefix&&null!==e.viewportPrefix&&e.hasOwnProperty("viewportPrefix")&&(r.viewportPrefix=e.viewportPrefix),void 0!==e.inputBox&&null!==e.inputBox&&e.hasOwnProperty("inputBox")){r.inputBox=[];for(var i=0;i<e.inputBox.length;++i)r.inputBox[i]=a[4].toObject(e.inputBox[i],t)}return void 0!==e.requirement&&null!==e.requirement&&e.hasOwnProperty("requirement")&&(r.requirement=a[5].toObject(e.requirement,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.InputBoxInfo=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.label=null,o.prototype.queryVerb="",o.prototype.queryPrepend="";var a={0:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.SearchTabProto.InputBoxInfo;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.label=a[0].decode(e,e.uint32());break;case 2:o.queryVerb=e.string();break;case 3:o.queryPrepend=e.string();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";var t=a[0].verify(e.label);return t?"label."+t:r.isString(e.queryVerb)?void 0===e.queryPrepend||r.isString(e.queryPrepend)?null:"queryPrepend: string expected":"queryVerb: string expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.SearchTabProto.InputBoxInfo)return e;var t=new n.keyhole.dbroot.SearchTabProto.InputBoxInfo;if(void 0!==e.label&&null!==e.label){if("object"!=typeof e.label)throw TypeError(".keyhole.dbroot.SearchTabProto.InputBoxInfo.label: object expected");t.label=a[0].fromObject(e.label)}return void 0!==e.queryVerb&&null!==e.queryVerb&&(t.queryVerb=String(e.queryVerb)),void 0!==e.queryPrepend&&null!==e.queryPrepend&&(t.queryPrepend=String(e.queryPrepend)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.label=null,r.queryVerb="",r.queryPrepend=""),void 0!==e.label&&null!==e.label&&e.hasOwnProperty("label")&&(r.label=a[0].toObject(e.label,t)),void 0!==e.queryVerb&&null!==e.queryVerb&&e.hasOwnProperty("queryVerb")&&(r.queryVerb=e.queryVerb),void 0!==e.queryPrepend&&null!==e.queryPrepend&&e.hasOwnProperty("queryPrepend")&&(r.queryPrepend=e.queryPrepend),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o}(),o.CobrandProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.logoUrl="",o.prototype.xCoord=null,o.prototype.yCoord=null,o.prototype.tiePoint=6,o.prototype.screenSize=0;var a={1:"keyhole.dbroot.CobrandProto.Coord",2:"keyhole.dbroot.CobrandProto.Coord",3:"keyhole.dbroot.CobrandProto.TiePoint"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.CobrandProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.logoUrl=e.string();break;case 2:o.xCoord=a[1].decode(e,e.uint32());break;case 3:o.yCoord=a[2].decode(e,e.uint32());break;case 4:o.tiePoint=e.uint32();break;case 5:o.screenSize=e.double();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.logoUrl))return"logoUrl: string expected";if(void 0!==e.xCoord&&null!==e.xCoord){var t=a[1].verify(e.xCoord);if(t)return"xCoord."+t}if(void 0!==e.yCoord&&null!==e.yCoord){var t=a[2].verify(e.yCoord);if(t)return"yCoord."+t}if(void 0!==e.tiePoint)switch(e.tiePoint){default:return"tiePoint: enum value expected";case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:}return void 0!==e.screenSize&&"number"!=typeof e.screenSize?"screenSize: number expected":null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.CobrandProto)return e;var t=new n.keyhole.dbroot.CobrandProto;if(void 0!==e.logoUrl&&null!==e.logoUrl&&(t.logoUrl=String(e.logoUrl)),void 0!==e.xCoord&&null!==e.xCoord){if("object"!=typeof e.xCoord)throw TypeError(".keyhole.dbroot.CobrandProto.xCoord: object expected");t.xCoord=a[1].fromObject(e.xCoord)}if(void 0!==e.yCoord&&null!==e.yCoord){if("object"!=typeof e.yCoord)throw TypeError(".keyhole.dbroot.CobrandProto.yCoord: object expected");t.yCoord=a[2].fromObject(e.yCoord)}switch(e.tiePoint){case"TOP_LEFT":case 0:t.tiePoint=0;break;case"TOP_CENTER":case 1:t.tiePoint=1;break;case"TOP_RIGHT":case 2:t.tiePoint=2;break;case"MID_LEFT":case 3:t.tiePoint=3;break;case"MID_CENTER":case 4:t.tiePoint=4;break;case"MID_RIGHT":case 5:t.tiePoint=5;break;case"BOTTOM_LEFT":case 6:t.tiePoint=6;break;case"BOTTOM_CENTER":case 7:t.tiePoint=7;break;case"BOTTOM_RIGHT":case 8:t.tiePoint=8}return void 0!==e.screenSize&&null!==e.screenSize&&(t.screenSize=Number(e.screenSize)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.logoUrl="",r.xCoord=null,r.yCoord=null,r.tiePoint=t.enums===String?"BOTTOM_LEFT":6,r.screenSize=0),void 0!==e.logoUrl&&null!==e.logoUrl&&e.hasOwnProperty("logoUrl")&&(r.logoUrl=e.logoUrl),void 0!==e.xCoord&&null!==e.xCoord&&e.hasOwnProperty("xCoord")&&(r.xCoord=a[1].toObject(e.xCoord,t)),void 0!==e.yCoord&&null!==e.yCoord&&e.hasOwnProperty("yCoord")&&(r.yCoord=a[2].toObject(e.yCoord,t)), +void 0!==e.tiePoint&&null!==e.tiePoint&&e.hasOwnProperty("tiePoint")&&(r.tiePoint=t.enums===String?a[3][e.tiePoint]:e.tiePoint),void 0!==e.screenSize&&null!==e.screenSize&&e.hasOwnProperty("screenSize")&&(r.screenSize=e.screenSize),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.Coord=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return r.prototype.value=0,r.prototype.isRelative=!1,r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.CobrandProto.Coord;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.value=e.double();break;case 2:o.isRelative=e.bool();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":"number"!=typeof e.value?"value: number expected":void 0!==e.isRelative&&"boolean"!=typeof e.isRelative?"isRelative: boolean expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.CobrandProto.Coord)return e;var t=new n.keyhole.dbroot.CobrandProto.Coord;return void 0!==e.value&&null!==e.value&&(t.value=Number(e.value)),void 0!==e.isRelative&&null!==e.isRelative&&(t.isRelative=Boolean(e.isRelative)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.value=0,r.isRelative=!1),void 0!==e.value&&null!==e.value&&e.hasOwnProperty("value")&&(r.value=e.value),void 0!==e.isRelative&&null!==e.isRelative&&e.hasOwnProperty("isRelative")&&(r.isRelative=e.isRelative),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.TiePoint=function(){var e={},t=Object.create(e);return t.TOP_LEFT=0,t.TOP_CENTER=1,t.TOP_RIGHT=2,t.MID_LEFT=3,t.MID_CENTER=4,t.MID_RIGHT=5,t.BOTTOM_LEFT=6,t.BOTTOM_CENTER=7,t.BOTTOM_RIGHT=8,t}(),o}(),o.DatabaseDescriptionProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.databaseName=null,o.prototype.databaseUrl="";var a={0:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.DatabaseDescriptionProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.databaseName=a[0].decode(e,e.uint32());break;case 2:o.databaseUrl=e.string();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.databaseName&&null!==e.databaseName){var t=a[0].verify(e.databaseName);if(t)return"databaseName."+t}return r.isString(e.databaseUrl)?null:"databaseUrl: string expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DatabaseDescriptionProto)return e;var t=new n.keyhole.dbroot.DatabaseDescriptionProto;if(void 0!==e.databaseName&&null!==e.databaseName){if("object"!=typeof e.databaseName)throw TypeError(".keyhole.dbroot.DatabaseDescriptionProto.databaseName: object expected");t.databaseName=a[0].fromObject(e.databaseName)}return void 0!==e.databaseUrl&&null!==e.databaseUrl&&(t.databaseUrl=String(e.databaseUrl)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.databaseName=null,r.databaseUrl=""),void 0!==e.databaseName&&null!==e.databaseName&&e.hasOwnProperty("databaseName")&&(r.databaseName=a[0].toObject(e.databaseName,t)),void 0!==e.databaseUrl&&null!==e.databaseUrl&&e.hasOwnProperty("databaseUrl")&&(r.databaseUrl=e.databaseUrl),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.ConfigScriptProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.scriptName="",i.prototype.scriptData="",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.ConfigScriptProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.scriptName=e.string();break;case 2:o.scriptData=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isString(e.scriptName)?r.isString(e.scriptData)?null:"scriptData: string expected":"scriptName: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.ConfigScriptProto)return e;var t=new n.keyhole.dbroot.ConfigScriptProto;return void 0!==e.scriptName&&null!==e.scriptName&&(t.scriptName=String(e.scriptName)),void 0!==e.scriptData&&null!==e.scriptData&&(t.scriptData=String(e.scriptData)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.scriptName="",r.scriptData=""),void 0!==e.scriptName&&null!==e.scriptName&&e.hasOwnProperty("scriptName")&&(r.scriptName=e.scriptName),void 0!==e.scriptData&&null!==e.scriptData&&e.hasOwnProperty("scriptData")&&(r.scriptData=e.scriptData),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.SwoopParamsProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return r.prototype.startDistInMeters=0,r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.SwoopParamsProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.startDistInMeters=e.double();break;default:e.skipType(7&a)}}return o},r.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0!==e.startDistInMeters&&"number"!=typeof e.startDistInMeters?"startDistInMeters: number expected":null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.SwoopParamsProto)return e;var t=new n.keyhole.dbroot.SwoopParamsProto;return void 0!==e.startDistInMeters&&null!==e.startDistInMeters&&(t.startDistInMeters=Number(e.startDistInMeters)),t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.startDistInMeters=0),void 0!==e.startDistInMeters&&null!==e.startDistInMeters&&e.hasOwnProperty("startDistInMeters")&&(r.startDistInMeters=e.startDistInMeters),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.PostingServerProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.name=null,r.prototype.baseUrl=null,r.prototype.postWizardPath=null,r.prototype.fileSubmitPath=null;var o={0:"keyhole.dbroot.StringIdOrValueProto",1:"keyhole.dbroot.StringIdOrValueProto",2:"keyhole.dbroot.StringIdOrValueProto",3:"keyhole.dbroot.StringIdOrValueProto"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,a=new n.keyhole.dbroot.PostingServerProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:a.name=o[0].decode(e,e.uint32());break;case 2:a.baseUrl=o[1].decode(e,e.uint32());break;case 3:a.postWizardPath=o[2].decode(e,e.uint32());break;case 4:a.fileSubmitPath=o[3].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.name&&null!==e.name){var t=o[0].verify(e.name);if(t)return"name."+t}if(void 0!==e.baseUrl&&null!==e.baseUrl){var t=o[1].verify(e.baseUrl);if(t)return"baseUrl."+t}if(void 0!==e.postWizardPath&&null!==e.postWizardPath){var t=o[2].verify(e.postWizardPath);if(t)return"postWizardPath."+t}if(void 0!==e.fileSubmitPath&&null!==e.fileSubmitPath){var t=o[3].verify(e.fileSubmitPath);if(t)return"fileSubmitPath."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PostingServerProto)return e;var t=new n.keyhole.dbroot.PostingServerProto;if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.PostingServerProto.name: object expected");t.name=o[0].fromObject(e.name)}if(void 0!==e.baseUrl&&null!==e.baseUrl){if("object"!=typeof e.baseUrl)throw TypeError(".keyhole.dbroot.PostingServerProto.baseUrl: object expected");t.baseUrl=o[1].fromObject(e.baseUrl)}if(void 0!==e.postWizardPath&&null!==e.postWizardPath){if("object"!=typeof e.postWizardPath)throw TypeError(".keyhole.dbroot.PostingServerProto.postWizardPath: object expected");t.postWizardPath=o[2].fromObject(e.postWizardPath)}if(void 0!==e.fileSubmitPath&&null!==e.fileSubmitPath){if("object"!=typeof e.fileSubmitPath)throw TypeError(".keyhole.dbroot.PostingServerProto.fileSubmitPath: object expected");t.fileSubmitPath=o[3].fromObject(e.fileSubmitPath)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.name=null,r.baseUrl=null,r.postWizardPath=null,r.fileSubmitPath=null),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=o[0].toObject(e.name,t)),void 0!==e.baseUrl&&null!==e.baseUrl&&e.hasOwnProperty("baseUrl")&&(r.baseUrl=o[1].toObject(e.baseUrl,t)),void 0!==e.postWizardPath&&null!==e.postWizardPath&&e.hasOwnProperty("postWizardPath")&&(r.postWizardPath=o[2].toObject(e.postWizardPath,t)),void 0!==e.fileSubmitPath&&null!==e.fileSubmitPath&&e.hasOwnProperty("fileSubmitPath")&&(r.fileSubmitPath=o[3].toObject(e.fileSubmitPath,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.PlanetaryDatabaseProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.url=null,r.prototype.name=null;var o={0:"keyhole.dbroot.StringIdOrValueProto",1:"keyhole.dbroot.StringIdOrValueProto"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,a=new n.keyhole.dbroot.PlanetaryDatabaseProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:a.url=o[0].decode(e,e.uint32());break;case 2:a.name=o[1].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";var t=o[0].verify(e.url);if(t)return"url."+t;var t=o[1].verify(e.name);return t?"name."+t:null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.PlanetaryDatabaseProto)return e;var t=new n.keyhole.dbroot.PlanetaryDatabaseProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.url: object expected");t.url=o[0].fromObject(e.url)}if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.name: object expected");t.name=o[1].fromObject(e.name)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.name=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=o[1].toObject(e.name,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.LogServerProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.url=null,o.prototype.enable=!1,o.prototype.throttlingFactor=1;var a={0:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.LogServerProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.url=a[0].decode(e,e.uint32());break;case 2:o.enable=e.bool();break;case 3:o.throttlingFactor=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=a[0].verify(e.url);if(t)return"url."+t}return void 0!==e.enable&&"boolean"!=typeof e.enable?"enable: boolean expected":void 0===e.throttlingFactor||r.isInteger(e.throttlingFactor)?null:"throttlingFactor: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.LogServerProto)return e;var t=new n.keyhole.dbroot.LogServerProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.LogServerProto.url: object expected");t.url=a[0].fromObject(e.url)}return void 0!==e.enable&&null!==e.enable&&(t.enable=Boolean(e.enable)),void 0!==e.throttlingFactor&&null!==e.throttlingFactor&&(t.throttlingFactor=0|e.throttlingFactor),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.enable=!1,r.throttlingFactor=1),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=a[0].toObject(e.url,t)),void 0!==e.enable&&null!==e.enable&&e.hasOwnProperty("enable")&&(r.enable=e.enable),void 0!==e.throttlingFactor&&null!==e.throttlingFactor&&e.hasOwnProperty("throttlingFactor")&&(r.throttlingFactor=e.throttlingFactor),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.EndSnippetProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.model=null,o.prototype.authServerUrl=null,o.prototype.disableAuthentication=!1,o.prototype.mfeDomains=r.emptyArray,o.prototype.mfeLangParam="hl=$5Bhl5D",o.prototype.adsUrlPatterns="",o.prototype.reverseGeocoderUrl=null,o.prototype.reverseGeocoderProtocolVersion=3,o.prototype.skyDatabaseIsAvailable=!0,o.prototype.skyDatabaseUrl=null,o.prototype.defaultWebPageIntlUrl=null,o.prototype.numStartUpTips=17,o.prototype.startUpTipsUrl=null,o.prototype.numProStartUpTips=0,o.prototype.proStartUpTipsUrl=null,o.prototype.startupTipsIntlUrl=null,o.prototype.userGuideIntlUrl=null,o.prototype.supportCenterIntlUrl=null,o.prototype.businessListingIntlUrl=null,o.prototype.supportAnswerIntlUrl=null,o.prototype.supportTopicIntlUrl=null,o.prototype.supportRequestIntlUrl=null,o.prototype.earthIntlUrl=null,o.prototype.addContentUrl=null,o.prototype.sketchupNotInstalledUrl=null,o.prototype.sketchupErrorUrl=null,o.prototype.freeLicenseUrl=null,o.prototype.proLicenseUrl=null,o.prototype.tutorialUrl=null,o.prototype.keyboardShortcutsUrl=null,o.prototype.releaseNotesUrl=null,o.prototype.hideUserData=!1,o.prototype.useGeLogo=!0,o.prototype.dioramaDescriptionUrlBase=null,o.prototype.dioramaDefaultColor=4291281607,o.prototype.dioramaBlacklistUrl=null,o.prototype.clientOptions=null,o.prototype.fetchingOptions=null,o.prototype.timeMachineOptions=null,o.prototype.csiOptions=null,o.prototype.searchTab=r.emptyArray,o.prototype.cobrandInfo=r.emptyArray,o.prototype.validDatabase=r.emptyArray,o.prototype.configScript=r.emptyArray,o.prototype.deauthServerUrl=null,o.prototype.swoopParameters=null,o.prototype.bbsServerInfo=null,o.prototype.dataErrorServerInfo=null,o.prototype.planetaryDatabase=r.emptyArray,o.prototype.logServer=null,o.prototype.autopiaOptions=null,o.prototype.searchConfig=null,o.prototype.searchInfo=null,o.prototype.elevationServiceBaseUrl="http://maps.google.com/maps/api/elevation/",o.prototype.elevationProfileQueryDelay=500,o.prototype.proUpgradeUrl=null,o.prototype.earthCommunityUrl=null,o.prototype.googleMapsUrl=null,o.prototype.sharingUrl=null,o.prototype.privacyPolicyUrl=null,o.prototype.doGplusUserCheck=!1,o.prototype.rocktreeDataProto=null,o.prototype.filmstripConfig=r.emptyArray,o.prototype.showSigninButton=!1,o.prototype.proMeasureUpsellUrl=null,o.prototype.proPrintUpsellUrl=null,o.prototype.starDataProto=null,o.prototype.feedbackUrl=null,o.prototype.oauth2LoginUrl=null;var a={0:"keyhole.dbroot.PlanetModelProto",1:"keyhole.dbroot.StringIdOrValueProto",3:"keyhole.dbroot.MfeDomainFeaturesProto",6:"keyhole.dbroot.StringIdOrValueProto",9:"keyhole.dbroot.StringIdOrValueProto",10:"keyhole.dbroot.StringIdOrValueProto",12:"keyhole.dbroot.StringIdOrValueProto",14:"keyhole.dbroot.StringIdOrValueProto",15:"keyhole.dbroot.StringIdOrValueProto",16:"keyhole.dbroot.StringIdOrValueProto",17:"keyhole.dbroot.StringIdOrValueProto",18:"keyhole.dbroot.StringIdOrValueProto",19:"keyhole.dbroot.StringIdOrValueProto",20:"keyhole.dbroot.StringIdOrValueProto",21:"keyhole.dbroot.StringIdOrValueProto",22:"keyhole.dbroot.StringIdOrValueProto",23:"keyhole.dbroot.StringIdOrValueProto",24:"keyhole.dbroot.StringIdOrValueProto",25:"keyhole.dbroot.StringIdOrValueProto",26:"keyhole.dbroot.StringIdOrValueProto",27:"keyhole.dbroot.StringIdOrValueProto",28:"keyhole.dbroot.StringIdOrValueProto",29:"keyhole.dbroot.StringIdOrValueProto",30:"keyhole.dbroot.StringIdOrValueProto",33:"keyhole.dbroot.StringIdOrValueProto",35:"keyhole.dbroot.StringIdOrValueProto",36:"keyhole.dbroot.ClientOptionsProto",37:"keyhole.dbroot.FetchingOptionsProto",38:"keyhole.dbroot.TimeMachineOptionsProto",39:"keyhole.dbroot.CSIOptionsProto",40:"keyhole.dbroot.SearchTabProto",41:"keyhole.dbroot.CobrandProto",42:"keyhole.dbroot.DatabaseDescriptionProto",43:"keyhole.dbroot.ConfigScriptProto",44:"keyhole.dbroot.StringIdOrValueProto",45:"keyhole.dbroot.SwoopParamsProto",46:"keyhole.dbroot.PostingServerProto",47:"keyhole.dbroot.PostingServerProto",48:"keyhole.dbroot.PlanetaryDatabaseProto",49:"keyhole.dbroot.LogServerProto",50:"keyhole.dbroot.AutopiaOptionsProto",51:"keyhole.dbroot.EndSnippetProto.SearchConfigProto",52:"keyhole.dbroot.EndSnippetProto.SearchInfoProto",55:"keyhole.dbroot.StringIdOrValueProto",56:"keyhole.dbroot.StringIdOrValueProto",57:"keyhole.dbroot.StringIdOrValueProto",58:"keyhole.dbroot.StringIdOrValueProto",59:"keyhole.dbroot.StringIdOrValueProto",61:"keyhole.dbroot.EndSnippetProto.RockTreeDataProto",62:"keyhole.dbroot.EndSnippetProto.FilmstripConfigProto",64:"keyhole.dbroot.StringIdOrValueProto",65:"keyhole.dbroot.StringIdOrValueProto",66:"keyhole.dbroot.EndSnippetProto.StarDataProto",67:"keyhole.dbroot.StringIdOrValueProto",68:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.model=a[0].decode(e,e.uint32());break;case 2:o.authServerUrl=a[1].decode(e,e.uint32());break;case 3:o.disableAuthentication=e.bool();break;case 4:o.mfeDomains&&o.mfeDomains.length||(o.mfeDomains=[]),o.mfeDomains.push(a[3].decode(e,e.uint32()));break;case 5:o.mfeLangParam=e.string();break;case 6:o.adsUrlPatterns=e.string();break;case 7:o.reverseGeocoderUrl=a[6].decode(e,e.uint32());break;case 8:o.reverseGeocoderProtocolVersion=e.int32();break;case 9:o.skyDatabaseIsAvailable=e.bool();break;case 10:o.skyDatabaseUrl=a[9].decode(e,e.uint32());break;case 11:o.defaultWebPageIntlUrl=a[10].decode(e,e.uint32());break;case 12:o.numStartUpTips=e.int32();break;case 13:o.startUpTipsUrl=a[12].decode(e,e.uint32());break;case 51:o.numProStartUpTips=e.int32();break;case 52:o.proStartUpTipsUrl=a[14].decode(e,e.uint32());break;case 64:o.startupTipsIntlUrl=a[15].decode(e,e.uint32());break;case 14:o.userGuideIntlUrl=a[16].decode(e,e.uint32());break;case 15:o.supportCenterIntlUrl=a[17].decode(e,e.uint32());break;case 16:o.businessListingIntlUrl=a[18].decode(e,e.uint32());break;case 17:o.supportAnswerIntlUrl=a[19].decode(e,e.uint32());break;case 18:o.supportTopicIntlUrl=a[20].decode(e,e.uint32());break;case 19:o.supportRequestIntlUrl=a[21].decode(e,e.uint32());break;case 20:o.earthIntlUrl=a[22].decode(e,e.uint32());break;case 21:o.addContentUrl=a[23].decode(e,e.uint32());break;case 22:o.sketchupNotInstalledUrl=a[24].decode(e,e.uint32());break;case 23:o.sketchupErrorUrl=a[25].decode(e,e.uint32());break;case 24:o.freeLicenseUrl=a[26].decode(e,e.uint32());break;case 25:o.proLicenseUrl=a[27].decode(e,e.uint32());break;case 48:o.tutorialUrl=a[28].decode(e,e.uint32());break;case 49:o.keyboardShortcutsUrl=a[29].decode(e,e.uint32());break;case 50:o.releaseNotesUrl=a[30].decode(e,e.uint32());break;case 26:o.hideUserData=e.bool();break;case 27:o.useGeLogo=e.bool();break;case 28:o.dioramaDescriptionUrlBase=a[33].decode(e,e.uint32());break;case 29:o.dioramaDefaultColor=e.uint32();break;case 53:o.dioramaBlacklistUrl=a[35].decode(e,e.uint32());break;case 30:o.clientOptions=a[36].decode(e,e.uint32());break;case 31:o.fetchingOptions=a[37].decode(e,e.uint32());break;case 32:o.timeMachineOptions=a[38].decode(e,e.uint32());break;case 33:o.csiOptions=a[39].decode(e,e.uint32());break;case 34:o.searchTab&&o.searchTab.length||(o.searchTab=[]),o.searchTab.push(a[40].decode(e,e.uint32()));break;case 35:o.cobrandInfo&&o.cobrandInfo.length||(o.cobrandInfo=[]),o.cobrandInfo.push(a[41].decode(e,e.uint32()));break;case 36:o.validDatabase&&o.validDatabase.length||(o.validDatabase=[]),o.validDatabase.push(a[42].decode(e,e.uint32()));break;case 37:o.configScript&&o.configScript.length||(o.configScript=[]),o.configScript.push(a[43].decode(e,e.uint32()));break;case 38:o.deauthServerUrl=a[44].decode(e,e.uint32());break;case 39:o.swoopParameters=a[45].decode(e,e.uint32());break;case 40:o.bbsServerInfo=a[46].decode(e,e.uint32());break;case 41:o.dataErrorServerInfo=a[47].decode(e,e.uint32());break;case 42:o.planetaryDatabase&&o.planetaryDatabase.length||(o.planetaryDatabase=[]),o.planetaryDatabase.push(a[48].decode(e,e.uint32()));break;case 43:o.logServer=a[49].decode(e,e.uint32());break;case 44:o.autopiaOptions=a[50].decode(e,e.uint32());break;case 54:o.searchConfig=a[51].decode(e,e.uint32());break;case 45:o.searchInfo=a[52].decode(e,e.uint32());break;case 46:o.elevationServiceBaseUrl=e.string();break;case 47:o.elevationProfileQueryDelay=e.int32();break;case 55:o.proUpgradeUrl=a[55].decode(e,e.uint32());break;case 56:o.earthCommunityUrl=a[56].decode(e,e.uint32());break;case 57:o.googleMapsUrl=a[57].decode(e,e.uint32());break;case 58:o.sharingUrl=a[58].decode(e,e.uint32());break;case 59:o.privacyPolicyUrl=a[59].decode(e,e.uint32());break;case 60:o.doGplusUserCheck=e.bool();break;case 61:o.rocktreeDataProto=a[61].decode(e,e.uint32());break;case 62:o.filmstripConfig&&o.filmstripConfig.length||(o.filmstripConfig=[]),o.filmstripConfig.push(a[62].decode(e,e.uint32()));break;case 63:o.showSigninButton=e.bool();break;case 65:o.proMeasureUpsellUrl=a[64].decode(e,e.uint32());break;case 66:o.proPrintUpsellUrl=a[65].decode(e,e.uint32());break;case 67:o.starDataProto=a[66].decode(e,e.uint32());break;case 68:o.feedbackUrl=a[67].decode(e,e.uint32());break;case 69:o.oauth2LoginUrl=a[68].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.model&&null!==e.model){var t=a[0].verify(e.model);if(t)return"model."+t}if(void 0!==e.authServerUrl&&null!==e.authServerUrl){var t=a[1].verify(e.authServerUrl);if(t)return"authServerUrl."+t}if(void 0!==e.disableAuthentication&&"boolean"!=typeof e.disableAuthentication)return"disableAuthentication: boolean expected";if(void 0!==e.mfeDomains){if(!Array.isArray(e.mfeDomains))return"mfeDomains: array expected";for(var i=0;i<e.mfeDomains.length;++i){var t=a[3].verify(e.mfeDomains[i]);if(t)return"mfeDomains."+t}}if(void 0!==e.mfeLangParam&&!r.isString(e.mfeLangParam))return"mfeLangParam: string expected";if(void 0!==e.adsUrlPatterns&&!r.isString(e.adsUrlPatterns))return"adsUrlPatterns: string expected";if(void 0!==e.reverseGeocoderUrl&&null!==e.reverseGeocoderUrl){var t=a[6].verify(e.reverseGeocoderUrl);if(t)return"reverseGeocoderUrl."+t}if(void 0!==e.reverseGeocoderProtocolVersion&&!r.isInteger(e.reverseGeocoderProtocolVersion))return"reverseGeocoderProtocolVersion: integer expected";if(void 0!==e.skyDatabaseIsAvailable&&"boolean"!=typeof e.skyDatabaseIsAvailable)return"skyDatabaseIsAvailable: boolean expected";if(void 0!==e.skyDatabaseUrl&&null!==e.skyDatabaseUrl){var t=a[9].verify(e.skyDatabaseUrl);if(t)return"skyDatabaseUrl."+t}if(void 0!==e.defaultWebPageIntlUrl&&null!==e.defaultWebPageIntlUrl){var t=a[10].verify(e.defaultWebPageIntlUrl);if(t)return"defaultWebPageIntlUrl."+t}if(void 0!==e.numStartUpTips&&!r.isInteger(e.numStartUpTips))return"numStartUpTips: integer expected";if(void 0!==e.startUpTipsUrl&&null!==e.startUpTipsUrl){var t=a[12].verify(e.startUpTipsUrl);if(t)return"startUpTipsUrl."+t}if(void 0!==e.numProStartUpTips&&!r.isInteger(e.numProStartUpTips))return"numProStartUpTips: integer expected";if(void 0!==e.proStartUpTipsUrl&&null!==e.proStartUpTipsUrl){var t=a[14].verify(e.proStartUpTipsUrl);if(t)return"proStartUpTipsUrl."+t}if(void 0!==e.startupTipsIntlUrl&&null!==e.startupTipsIntlUrl){var t=a[15].verify(e.startupTipsIntlUrl);if(t)return"startupTipsIntlUrl."+t}if(void 0!==e.userGuideIntlUrl&&null!==e.userGuideIntlUrl){var t=a[16].verify(e.userGuideIntlUrl);if(t)return"userGuideIntlUrl."+t}if(void 0!==e.supportCenterIntlUrl&&null!==e.supportCenterIntlUrl){var t=a[17].verify(e.supportCenterIntlUrl);if(t)return"supportCenterIntlUrl."+t}if(void 0!==e.businessListingIntlUrl&&null!==e.businessListingIntlUrl){var t=a[18].verify(e.businessListingIntlUrl);if(t)return"businessListingIntlUrl."+t}if(void 0!==e.supportAnswerIntlUrl&&null!==e.supportAnswerIntlUrl){var t=a[19].verify(e.supportAnswerIntlUrl);if(t)return"supportAnswerIntlUrl."+t}if(void 0!==e.supportTopicIntlUrl&&null!==e.supportTopicIntlUrl){var t=a[20].verify(e.supportTopicIntlUrl);if(t)return"supportTopicIntlUrl."+t}if(void 0!==e.supportRequestIntlUrl&&null!==e.supportRequestIntlUrl){var t=a[21].verify(e.supportRequestIntlUrl);if(t)return"supportRequestIntlUrl."+t}if(void 0!==e.earthIntlUrl&&null!==e.earthIntlUrl){var t=a[22].verify(e.earthIntlUrl);if(t)return"earthIntlUrl."+t}if(void 0!==e.addContentUrl&&null!==e.addContentUrl){var t=a[23].verify(e.addContentUrl);if(t)return"addContentUrl."+t}if(void 0!==e.sketchupNotInstalledUrl&&null!==e.sketchupNotInstalledUrl){var t=a[24].verify(e.sketchupNotInstalledUrl);if(t)return"sketchupNotInstalledUrl."+t}if(void 0!==e.sketchupErrorUrl&&null!==e.sketchupErrorUrl){var t=a[25].verify(e.sketchupErrorUrl);if(t)return"sketchupErrorUrl."+t}if(void 0!==e.freeLicenseUrl&&null!==e.freeLicenseUrl){var t=a[26].verify(e.freeLicenseUrl);if(t)return"freeLicenseUrl."+t}if(void 0!==e.proLicenseUrl&&null!==e.proLicenseUrl){var t=a[27].verify(e.proLicenseUrl);if(t)return"proLicenseUrl."+t}if(void 0!==e.tutorialUrl&&null!==e.tutorialUrl){var t=a[28].verify(e.tutorialUrl);if(t)return"tutorialUrl."+t}if(void 0!==e.keyboardShortcutsUrl&&null!==e.keyboardShortcutsUrl){var t=a[29].verify(e.keyboardShortcutsUrl);if(t)return"keyboardShortcutsUrl."+t}if(void 0!==e.releaseNotesUrl&&null!==e.releaseNotesUrl){var t=a[30].verify(e.releaseNotesUrl);if(t)return"releaseNotesUrl."+t}if(void 0!==e.hideUserData&&"boolean"!=typeof e.hideUserData)return"hideUserData: boolean expected";if(void 0!==e.useGeLogo&&"boolean"!=typeof e.useGeLogo)return"useGeLogo: boolean expected";if(void 0!==e.dioramaDescriptionUrlBase&&null!==e.dioramaDescriptionUrlBase){var t=a[33].verify(e.dioramaDescriptionUrlBase);if(t)return"dioramaDescriptionUrlBase."+t}if(void 0!==e.dioramaDefaultColor&&!r.isInteger(e.dioramaDefaultColor))return"dioramaDefaultColor: integer expected";if(void 0!==e.dioramaBlacklistUrl&&null!==e.dioramaBlacklistUrl){var t=a[35].verify(e.dioramaBlacklistUrl);if(t)return"dioramaBlacklistUrl."+t}if(void 0!==e.clientOptions&&null!==e.clientOptions){var t=a[36].verify(e.clientOptions);if(t)return"clientOptions."+t}if(void 0!==e.fetchingOptions&&null!==e.fetchingOptions){var t=a[37].verify(e.fetchingOptions);if(t)return"fetchingOptions."+t}if(void 0!==e.timeMachineOptions&&null!==e.timeMachineOptions){var t=a[38].verify(e.timeMachineOptions);if(t)return"timeMachineOptions."+t}if(void 0!==e.csiOptions&&null!==e.csiOptions){var t=a[39].verify(e.csiOptions);if(t)return"csiOptions."+t}if(void 0!==e.searchTab){if(!Array.isArray(e.searchTab))return"searchTab: array expected";for(var i=0;i<e.searchTab.length;++i){var t=a[40].verify(e.searchTab[i]);if(t)return"searchTab."+t}}if(void 0!==e.cobrandInfo){if(!Array.isArray(e.cobrandInfo))return"cobrandInfo: array expected";for(var i=0;i<e.cobrandInfo.length;++i){var t=a[41].verify(e.cobrandInfo[i]);if(t)return"cobrandInfo."+t}}if(void 0!==e.validDatabase){if(!Array.isArray(e.validDatabase))return"validDatabase: array expected";for(var i=0;i<e.validDatabase.length;++i){var t=a[42].verify(e.validDatabase[i]);if(t)return"validDatabase."+t}}if(void 0!==e.configScript){if(!Array.isArray(e.configScript))return"configScript: array expected";for(var i=0;i<e.configScript.length;++i){var t=a[43].verify(e.configScript[i]);if(t)return"configScript."+t}}if(void 0!==e.deauthServerUrl&&null!==e.deauthServerUrl){var t=a[44].verify(e.deauthServerUrl);if(t)return"deauthServerUrl."+t}if(void 0!==e.swoopParameters&&null!==e.swoopParameters){var t=a[45].verify(e.swoopParameters);if(t)return"swoopParameters."+t}if(void 0!==e.bbsServerInfo&&null!==e.bbsServerInfo){var t=a[46].verify(e.bbsServerInfo);if(t)return"bbsServerInfo."+t}if(void 0!==e.dataErrorServerInfo&&null!==e.dataErrorServerInfo){var t=a[47].verify(e.dataErrorServerInfo);if(t)return"dataErrorServerInfo."+t}if(void 0!==e.planetaryDatabase){if(!Array.isArray(e.planetaryDatabase))return"planetaryDatabase: array expected";for(var i=0;i<e.planetaryDatabase.length;++i){var t=a[48].verify(e.planetaryDatabase[i]);if(t)return"planetaryDatabase."+t}}if(void 0!==e.logServer&&null!==e.logServer){var t=a[49].verify(e.logServer);if(t)return"logServer."+t}if(void 0!==e.autopiaOptions&&null!==e.autopiaOptions){var t=a[50].verify(e.autopiaOptions);if(t)return"autopiaOptions."+t}if(void 0!==e.searchConfig&&null!==e.searchConfig){var t=a[51].verify(e.searchConfig);if(t)return"searchConfig."+t}if(void 0!==e.searchInfo&&null!==e.searchInfo){var t=a[52].verify(e.searchInfo);if(t)return"searchInfo."+t}if(void 0!==e.elevationServiceBaseUrl&&!r.isString(e.elevationServiceBaseUrl))return"elevationServiceBaseUrl: string expected";if(void 0!==e.elevationProfileQueryDelay&&!r.isInteger(e.elevationProfileQueryDelay))return"elevationProfileQueryDelay: integer expected";if(void 0!==e.proUpgradeUrl&&null!==e.proUpgradeUrl){var t=a[55].verify(e.proUpgradeUrl);if(t)return"proUpgradeUrl."+t}if(void 0!==e.earthCommunityUrl&&null!==e.earthCommunityUrl){var t=a[56].verify(e.earthCommunityUrl);if(t)return"earthCommunityUrl."+t}if(void 0!==e.googleMapsUrl&&null!==e.googleMapsUrl){var t=a[57].verify(e.googleMapsUrl);if(t)return"googleMapsUrl."+t}if(void 0!==e.sharingUrl&&null!==e.sharingUrl){var t=a[58].verify(e.sharingUrl);if(t)return"sharingUrl."+t}if(void 0!==e.privacyPolicyUrl&&null!==e.privacyPolicyUrl){var t=a[59].verify(e.privacyPolicyUrl);if(t)return"privacyPolicyUrl."+t}if(void 0!==e.doGplusUserCheck&&"boolean"!=typeof e.doGplusUserCheck)return"doGplusUserCheck: boolean expected";if(void 0!==e.rocktreeDataProto&&null!==e.rocktreeDataProto){var t=a[61].verify(e.rocktreeDataProto);if(t)return"rocktreeDataProto."+t}if(void 0!==e.filmstripConfig){if(!Array.isArray(e.filmstripConfig))return"filmstripConfig: array expected";for(var i=0;i<e.filmstripConfig.length;++i){var t=a[62].verify(e.filmstripConfig[i]);if(t)return"filmstripConfig."+t}}if(void 0!==e.showSigninButton&&"boolean"!=typeof e.showSigninButton)return"showSigninButton: boolean expected";if(void 0!==e.proMeasureUpsellUrl&&null!==e.proMeasureUpsellUrl){var t=a[64].verify(e.proMeasureUpsellUrl);if(t)return"proMeasureUpsellUrl."+t}if(void 0!==e.proPrintUpsellUrl&&null!==e.proPrintUpsellUrl){var t=a[65].verify(e.proPrintUpsellUrl);if(t)return"proPrintUpsellUrl."+t}if(void 0!==e.starDataProto&&null!==e.starDataProto){var t=a[66].verify(e.starDataProto);if(t)return"starDataProto."+t}if(void 0!==e.feedbackUrl&&null!==e.feedbackUrl){var t=a[67].verify(e.feedbackUrl);if(t)return"feedbackUrl."+t}if(void 0!==e.oauth2LoginUrl&&null!==e.oauth2LoginUrl){var t=a[68].verify(e.oauth2LoginUrl);if(t)return"oauth2LoginUrl."+t}return null},o.fromObject=function(e){ +if(e instanceof n.keyhole.dbroot.EndSnippetProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto;if(void 0!==e.model&&null!==e.model){if("object"!=typeof e.model)throw TypeError(".keyhole.dbroot.EndSnippetProto.model: object expected");t.model=a[0].fromObject(e.model)}if(void 0!==e.authServerUrl&&null!==e.authServerUrl){if("object"!=typeof e.authServerUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.authServerUrl: object expected");t.authServerUrl=a[1].fromObject(e.authServerUrl)}if(void 0!==e.disableAuthentication&&null!==e.disableAuthentication&&(t.disableAuthentication=Boolean(e.disableAuthentication)),e.mfeDomains){if(!Array.isArray(e.mfeDomains))throw TypeError(".keyhole.dbroot.EndSnippetProto.mfeDomains: array expected");t.mfeDomains=[];for(var r=0;r<e.mfeDomains.length;++r){if("object"!=typeof e.mfeDomains[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.mfeDomains: object expected");t.mfeDomains[r]=a[3].fromObject(e.mfeDomains[r])}}if(void 0!==e.mfeLangParam&&null!==e.mfeLangParam&&(t.mfeLangParam=String(e.mfeLangParam)),void 0!==e.adsUrlPatterns&&null!==e.adsUrlPatterns&&(t.adsUrlPatterns=String(e.adsUrlPatterns)),void 0!==e.reverseGeocoderUrl&&null!==e.reverseGeocoderUrl){if("object"!=typeof e.reverseGeocoderUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.reverseGeocoderUrl: object expected");t.reverseGeocoderUrl=a[6].fromObject(e.reverseGeocoderUrl)}if(void 0!==e.reverseGeocoderProtocolVersion&&null!==e.reverseGeocoderProtocolVersion&&(t.reverseGeocoderProtocolVersion=0|e.reverseGeocoderProtocolVersion),void 0!==e.skyDatabaseIsAvailable&&null!==e.skyDatabaseIsAvailable&&(t.skyDatabaseIsAvailable=Boolean(e.skyDatabaseIsAvailable)),void 0!==e.skyDatabaseUrl&&null!==e.skyDatabaseUrl){if("object"!=typeof e.skyDatabaseUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.skyDatabaseUrl: object expected");t.skyDatabaseUrl=a[9].fromObject(e.skyDatabaseUrl)}if(void 0!==e.defaultWebPageIntlUrl&&null!==e.defaultWebPageIntlUrl){if("object"!=typeof e.defaultWebPageIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.defaultWebPageIntlUrl: object expected");t.defaultWebPageIntlUrl=a[10].fromObject(e.defaultWebPageIntlUrl)}if(void 0!==e.numStartUpTips&&null!==e.numStartUpTips&&(t.numStartUpTips=0|e.numStartUpTips),void 0!==e.startUpTipsUrl&&null!==e.startUpTipsUrl){if("object"!=typeof e.startUpTipsUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.startUpTipsUrl: object expected");t.startUpTipsUrl=a[12].fromObject(e.startUpTipsUrl)}if(void 0!==e.numProStartUpTips&&null!==e.numProStartUpTips&&(t.numProStartUpTips=0|e.numProStartUpTips),void 0!==e.proStartUpTipsUrl&&null!==e.proStartUpTipsUrl){if("object"!=typeof e.proStartUpTipsUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.proStartUpTipsUrl: object expected");t.proStartUpTipsUrl=a[14].fromObject(e.proStartUpTipsUrl)}if(void 0!==e.startupTipsIntlUrl&&null!==e.startupTipsIntlUrl){if("object"!=typeof e.startupTipsIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.startupTipsIntlUrl: object expected");t.startupTipsIntlUrl=a[15].fromObject(e.startupTipsIntlUrl)}if(void 0!==e.userGuideIntlUrl&&null!==e.userGuideIntlUrl){if("object"!=typeof e.userGuideIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.userGuideIntlUrl: object expected");t.userGuideIntlUrl=a[16].fromObject(e.userGuideIntlUrl)}if(void 0!==e.supportCenterIntlUrl&&null!==e.supportCenterIntlUrl){if("object"!=typeof e.supportCenterIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.supportCenterIntlUrl: object expected");t.supportCenterIntlUrl=a[17].fromObject(e.supportCenterIntlUrl)}if(void 0!==e.businessListingIntlUrl&&null!==e.businessListingIntlUrl){if("object"!=typeof e.businessListingIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.businessListingIntlUrl: object expected");t.businessListingIntlUrl=a[18].fromObject(e.businessListingIntlUrl)}if(void 0!==e.supportAnswerIntlUrl&&null!==e.supportAnswerIntlUrl){if("object"!=typeof e.supportAnswerIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.supportAnswerIntlUrl: object expected");t.supportAnswerIntlUrl=a[19].fromObject(e.supportAnswerIntlUrl)}if(void 0!==e.supportTopicIntlUrl&&null!==e.supportTopicIntlUrl){if("object"!=typeof e.supportTopicIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.supportTopicIntlUrl: object expected");t.supportTopicIntlUrl=a[20].fromObject(e.supportTopicIntlUrl)}if(void 0!==e.supportRequestIntlUrl&&null!==e.supportRequestIntlUrl){if("object"!=typeof e.supportRequestIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.supportRequestIntlUrl: object expected");t.supportRequestIntlUrl=a[21].fromObject(e.supportRequestIntlUrl)}if(void 0!==e.earthIntlUrl&&null!==e.earthIntlUrl){if("object"!=typeof e.earthIntlUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.earthIntlUrl: object expected");t.earthIntlUrl=a[22].fromObject(e.earthIntlUrl)}if(void 0!==e.addContentUrl&&null!==e.addContentUrl){if("object"!=typeof e.addContentUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.addContentUrl: object expected");t.addContentUrl=a[23].fromObject(e.addContentUrl)}if(void 0!==e.sketchupNotInstalledUrl&&null!==e.sketchupNotInstalledUrl){if("object"!=typeof e.sketchupNotInstalledUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.sketchupNotInstalledUrl: object expected");t.sketchupNotInstalledUrl=a[24].fromObject(e.sketchupNotInstalledUrl)}if(void 0!==e.sketchupErrorUrl&&null!==e.sketchupErrorUrl){if("object"!=typeof e.sketchupErrorUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.sketchupErrorUrl: object expected");t.sketchupErrorUrl=a[25].fromObject(e.sketchupErrorUrl)}if(void 0!==e.freeLicenseUrl&&null!==e.freeLicenseUrl){if("object"!=typeof e.freeLicenseUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.freeLicenseUrl: object expected");t.freeLicenseUrl=a[26].fromObject(e.freeLicenseUrl)}if(void 0!==e.proLicenseUrl&&null!==e.proLicenseUrl){if("object"!=typeof e.proLicenseUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.proLicenseUrl: object expected");t.proLicenseUrl=a[27].fromObject(e.proLicenseUrl)}if(void 0!==e.tutorialUrl&&null!==e.tutorialUrl){if("object"!=typeof e.tutorialUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.tutorialUrl: object expected");t.tutorialUrl=a[28].fromObject(e.tutorialUrl)}if(void 0!==e.keyboardShortcutsUrl&&null!==e.keyboardShortcutsUrl){if("object"!=typeof e.keyboardShortcutsUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.keyboardShortcutsUrl: object expected");t.keyboardShortcutsUrl=a[29].fromObject(e.keyboardShortcutsUrl)}if(void 0!==e.releaseNotesUrl&&null!==e.releaseNotesUrl){if("object"!=typeof e.releaseNotesUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.releaseNotesUrl: object expected");t.releaseNotesUrl=a[30].fromObject(e.releaseNotesUrl)}if(void 0!==e.hideUserData&&null!==e.hideUserData&&(t.hideUserData=Boolean(e.hideUserData)),void 0!==e.useGeLogo&&null!==e.useGeLogo&&(t.useGeLogo=Boolean(e.useGeLogo)),void 0!==e.dioramaDescriptionUrlBase&&null!==e.dioramaDescriptionUrlBase){if("object"!=typeof e.dioramaDescriptionUrlBase)throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaDescriptionUrlBase: object expected");t.dioramaDescriptionUrlBase=a[33].fromObject(e.dioramaDescriptionUrlBase)}if(void 0!==e.dioramaDefaultColor&&null!==e.dioramaDefaultColor&&(t.dioramaDefaultColor=e.dioramaDefaultColor>>>0),void 0!==e.dioramaBlacklistUrl&&null!==e.dioramaBlacklistUrl){if("object"!=typeof e.dioramaBlacklistUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaBlacklistUrl: object expected");t.dioramaBlacklistUrl=a[35].fromObject(e.dioramaBlacklistUrl)}if(void 0!==e.clientOptions&&null!==e.clientOptions){if("object"!=typeof e.clientOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.clientOptions: object expected");t.clientOptions=a[36].fromObject(e.clientOptions)}if(void 0!==e.fetchingOptions&&null!==e.fetchingOptions){if("object"!=typeof e.fetchingOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.fetchingOptions: object expected");t.fetchingOptions=a[37].fromObject(e.fetchingOptions)}if(void 0!==e.timeMachineOptions&&null!==e.timeMachineOptions){if("object"!=typeof e.timeMachineOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.timeMachineOptions: object expected");t.timeMachineOptions=a[38].fromObject(e.timeMachineOptions)}if(void 0!==e.csiOptions&&null!==e.csiOptions){if("object"!=typeof e.csiOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.csiOptions: object expected");t.csiOptions=a[39].fromObject(e.csiOptions)}if(e.searchTab){if(!Array.isArray(e.searchTab))throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: array expected");t.searchTab=[];for(var r=0;r<e.searchTab.length;++r){if("object"!=typeof e.searchTab[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: object expected");t.searchTab[r]=a[40].fromObject(e.searchTab[r])}}if(e.cobrandInfo){if(!Array.isArray(e.cobrandInfo))throw TypeError(".keyhole.dbroot.EndSnippetProto.cobrandInfo: array expected");t.cobrandInfo=[];for(var r=0;r<e.cobrandInfo.length;++r){if("object"!=typeof e.cobrandInfo[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.cobrandInfo: object expected");t.cobrandInfo[r]=a[41].fromObject(e.cobrandInfo[r])}}if(e.validDatabase){if(!Array.isArray(e.validDatabase))throw TypeError(".keyhole.dbroot.EndSnippetProto.validDatabase: array expected");t.validDatabase=[];for(var r=0;r<e.validDatabase.length;++r){if("object"!=typeof e.validDatabase[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.validDatabase: object expected");t.validDatabase[r]=a[42].fromObject(e.validDatabase[r])}}if(e.configScript){if(!Array.isArray(e.configScript))throw TypeError(".keyhole.dbroot.EndSnippetProto.configScript: array expected");t.configScript=[];for(var r=0;r<e.configScript.length;++r){if("object"!=typeof e.configScript[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.configScript: object expected");t.configScript[r]=a[43].fromObject(e.configScript[r])}}if(void 0!==e.deauthServerUrl&&null!==e.deauthServerUrl){if("object"!=typeof e.deauthServerUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.deauthServerUrl: object expected");t.deauthServerUrl=a[44].fromObject(e.deauthServerUrl)}if(void 0!==e.swoopParameters&&null!==e.swoopParameters){if("object"!=typeof e.swoopParameters)throw TypeError(".keyhole.dbroot.EndSnippetProto.swoopParameters: object expected");t.swoopParameters=a[45].fromObject(e.swoopParameters)}if(void 0!==e.bbsServerInfo&&null!==e.bbsServerInfo){if("object"!=typeof e.bbsServerInfo)throw TypeError(".keyhole.dbroot.EndSnippetProto.bbsServerInfo: object expected");t.bbsServerInfo=a[46].fromObject(e.bbsServerInfo)}if(void 0!==e.dataErrorServerInfo&&null!==e.dataErrorServerInfo){if("object"!=typeof e.dataErrorServerInfo)throw TypeError(".keyhole.dbroot.EndSnippetProto.dataErrorServerInfo: object expected");t.dataErrorServerInfo=a[47].fromObject(e.dataErrorServerInfo)}if(e.planetaryDatabase){if(!Array.isArray(e.planetaryDatabase))throw TypeError(".keyhole.dbroot.EndSnippetProto.planetaryDatabase: array expected");t.planetaryDatabase=[];for(var r=0;r<e.planetaryDatabase.length;++r){if("object"!=typeof e.planetaryDatabase[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.planetaryDatabase: object expected");t.planetaryDatabase[r]=a[48].fromObject(e.planetaryDatabase[r])}}if(void 0!==e.logServer&&null!==e.logServer){if("object"!=typeof e.logServer)throw TypeError(".keyhole.dbroot.EndSnippetProto.logServer: object expected");t.logServer=a[49].fromObject(e.logServer)}if(void 0!==e.autopiaOptions&&null!==e.autopiaOptions){if("object"!=typeof e.autopiaOptions)throw TypeError(".keyhole.dbroot.EndSnippetProto.autopiaOptions: object expected");t.autopiaOptions=a[50].fromObject(e.autopiaOptions)}if(void 0!==e.searchConfig&&null!==e.searchConfig){if("object"!=typeof e.searchConfig)throw TypeError(".keyhole.dbroot.EndSnippetProto.searchConfig: object expected");t.searchConfig=a[51].fromObject(e.searchConfig)}if(void 0!==e.searchInfo&&null!==e.searchInfo){if("object"!=typeof e.searchInfo)throw TypeError(".keyhole.dbroot.EndSnippetProto.searchInfo: object expected");t.searchInfo=a[52].fromObject(e.searchInfo)}if(void 0!==e.elevationServiceBaseUrl&&null!==e.elevationServiceBaseUrl&&(t.elevationServiceBaseUrl=String(e.elevationServiceBaseUrl)),void 0!==e.elevationProfileQueryDelay&&null!==e.elevationProfileQueryDelay&&(t.elevationProfileQueryDelay=0|e.elevationProfileQueryDelay),void 0!==e.proUpgradeUrl&&null!==e.proUpgradeUrl){if("object"!=typeof e.proUpgradeUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.proUpgradeUrl: object expected");t.proUpgradeUrl=a[55].fromObject(e.proUpgradeUrl)}if(void 0!==e.earthCommunityUrl&&null!==e.earthCommunityUrl){if("object"!=typeof e.earthCommunityUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.earthCommunityUrl: object expected");t.earthCommunityUrl=a[56].fromObject(e.earthCommunityUrl)}if(void 0!==e.googleMapsUrl&&null!==e.googleMapsUrl){if("object"!=typeof e.googleMapsUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.googleMapsUrl: object expected");t.googleMapsUrl=a[57].fromObject(e.googleMapsUrl)}if(void 0!==e.sharingUrl&&null!==e.sharingUrl){if("object"!=typeof e.sharingUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.sharingUrl: object expected");t.sharingUrl=a[58].fromObject(e.sharingUrl)}if(void 0!==e.privacyPolicyUrl&&null!==e.privacyPolicyUrl){if("object"!=typeof e.privacyPolicyUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.privacyPolicyUrl: object expected");t.privacyPolicyUrl=a[59].fromObject(e.privacyPolicyUrl)}if(void 0!==e.doGplusUserCheck&&null!==e.doGplusUserCheck&&(t.doGplusUserCheck=Boolean(e.doGplusUserCheck)),void 0!==e.rocktreeDataProto&&null!==e.rocktreeDataProto){if("object"!=typeof e.rocktreeDataProto)throw TypeError(".keyhole.dbroot.EndSnippetProto.rocktreeDataProto: object expected");t.rocktreeDataProto=a[61].fromObject(e.rocktreeDataProto)}if(e.filmstripConfig){if(!Array.isArray(e.filmstripConfig))throw TypeError(".keyhole.dbroot.EndSnippetProto.filmstripConfig: array expected");t.filmstripConfig=[];for(var r=0;r<e.filmstripConfig.length;++r){if("object"!=typeof e.filmstripConfig[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.filmstripConfig: object expected");t.filmstripConfig[r]=a[62].fromObject(e.filmstripConfig[r])}}if(void 0!==e.showSigninButton&&null!==e.showSigninButton&&(t.showSigninButton=Boolean(e.showSigninButton)),void 0!==e.proMeasureUpsellUrl&&null!==e.proMeasureUpsellUrl){if("object"!=typeof e.proMeasureUpsellUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.proMeasureUpsellUrl: object expected");t.proMeasureUpsellUrl=a[64].fromObject(e.proMeasureUpsellUrl)}if(void 0!==e.proPrintUpsellUrl&&null!==e.proPrintUpsellUrl){if("object"!=typeof e.proPrintUpsellUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.proPrintUpsellUrl: object expected");t.proPrintUpsellUrl=a[65].fromObject(e.proPrintUpsellUrl)}if(void 0!==e.starDataProto&&null!==e.starDataProto){if("object"!=typeof e.starDataProto)throw TypeError(".keyhole.dbroot.EndSnippetProto.starDataProto: object expected");t.starDataProto=a[66].fromObject(e.starDataProto)}if(void 0!==e.feedbackUrl&&null!==e.feedbackUrl){if("object"!=typeof e.feedbackUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.feedbackUrl: object expected");t.feedbackUrl=a[67].fromObject(e.feedbackUrl)}if(void 0!==e.oauth2LoginUrl&&null!==e.oauth2LoginUrl){if("object"!=typeof e.oauth2LoginUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.oauth2LoginUrl: object expected");t.oauth2LoginUrl=a[68].fromObject(e.oauth2LoginUrl)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.mfeDomains=[],r.searchTab=[],r.cobrandInfo=[],r.validDatabase=[],r.configScript=[],r.planetaryDatabase=[],r.filmstripConfig=[]),t.defaults&&(r.model=null,r.authServerUrl=null,r.disableAuthentication=!1,r.mfeLangParam="hl=$5Bhl5D",r.adsUrlPatterns="",r.reverseGeocoderUrl=null,r.reverseGeocoderProtocolVersion=3,r.skyDatabaseIsAvailable=!0,r.skyDatabaseUrl=null,r.defaultWebPageIntlUrl=null,r.numStartUpTips=17,r.startUpTipsUrl=null,r.numProStartUpTips=0,r.proStartUpTipsUrl=null,r.startupTipsIntlUrl=null,r.userGuideIntlUrl=null,r.supportCenterIntlUrl=null,r.businessListingIntlUrl=null,r.supportAnswerIntlUrl=null,r.supportTopicIntlUrl=null,r.supportRequestIntlUrl=null,r.earthIntlUrl=null,r.addContentUrl=null,r.sketchupNotInstalledUrl=null,r.sketchupErrorUrl=null,r.freeLicenseUrl=null,r.proLicenseUrl=null,r.tutorialUrl=null,r.keyboardShortcutsUrl=null,r.releaseNotesUrl=null,r.hideUserData=!1,r.useGeLogo=!0,r.dioramaDescriptionUrlBase=null,r.dioramaDefaultColor=4291281607,r.dioramaBlacklistUrl=null,r.clientOptions=null,r.fetchingOptions=null,r.timeMachineOptions=null,r.csiOptions=null,r.deauthServerUrl=null,r.swoopParameters=null,r.bbsServerInfo=null,r.dataErrorServerInfo=null,r.logServer=null,r.autopiaOptions=null,r.searchConfig=null,r.searchInfo=null,r.elevationServiceBaseUrl="http://maps.google.com/maps/api/elevation/",r.elevationProfileQueryDelay=500,r.proUpgradeUrl=null,r.earthCommunityUrl=null,r.googleMapsUrl=null,r.sharingUrl=null,r.privacyPolicyUrl=null,r.doGplusUserCheck=!1,r.rocktreeDataProto=null,r.showSigninButton=!1,r.proMeasureUpsellUrl=null,r.proPrintUpsellUrl=null,r.starDataProto=null,r.feedbackUrl=null,r.oauth2LoginUrl=null),void 0!==e.model&&null!==e.model&&e.hasOwnProperty("model")&&(r.model=a[0].toObject(e.model,t)),void 0!==e.authServerUrl&&null!==e.authServerUrl&&e.hasOwnProperty("authServerUrl")&&(r.authServerUrl=a[1].toObject(e.authServerUrl,t)),void 0!==e.disableAuthentication&&null!==e.disableAuthentication&&e.hasOwnProperty("disableAuthentication")&&(r.disableAuthentication=e.disableAuthentication),void 0!==e.mfeDomains&&null!==e.mfeDomains&&e.hasOwnProperty("mfeDomains")){r.mfeDomains=[];for(var i=0;i<e.mfeDomains.length;++i)r.mfeDomains[i]=a[3].toObject(e.mfeDomains[i],t)}if(void 0!==e.mfeLangParam&&null!==e.mfeLangParam&&e.hasOwnProperty("mfeLangParam")&&(r.mfeLangParam=e.mfeLangParam),void 0!==e.adsUrlPatterns&&null!==e.adsUrlPatterns&&e.hasOwnProperty("adsUrlPatterns")&&(r.adsUrlPatterns=e.adsUrlPatterns),void 0!==e.reverseGeocoderUrl&&null!==e.reverseGeocoderUrl&&e.hasOwnProperty("reverseGeocoderUrl")&&(r.reverseGeocoderUrl=a[6].toObject(e.reverseGeocoderUrl,t)),void 0!==e.reverseGeocoderProtocolVersion&&null!==e.reverseGeocoderProtocolVersion&&e.hasOwnProperty("reverseGeocoderProtocolVersion")&&(r.reverseGeocoderProtocolVersion=e.reverseGeocoderProtocolVersion),void 0!==e.skyDatabaseIsAvailable&&null!==e.skyDatabaseIsAvailable&&e.hasOwnProperty("skyDatabaseIsAvailable")&&(r.skyDatabaseIsAvailable=e.skyDatabaseIsAvailable),void 0!==e.skyDatabaseUrl&&null!==e.skyDatabaseUrl&&e.hasOwnProperty("skyDatabaseUrl")&&(r.skyDatabaseUrl=a[9].toObject(e.skyDatabaseUrl,t)),void 0!==e.defaultWebPageIntlUrl&&null!==e.defaultWebPageIntlUrl&&e.hasOwnProperty("defaultWebPageIntlUrl")&&(r.defaultWebPageIntlUrl=a[10].toObject(e.defaultWebPageIntlUrl,t)),void 0!==e.numStartUpTips&&null!==e.numStartUpTips&&e.hasOwnProperty("numStartUpTips")&&(r.numStartUpTips=e.numStartUpTips),void 0!==e.startUpTipsUrl&&null!==e.startUpTipsUrl&&e.hasOwnProperty("startUpTipsUrl")&&(r.startUpTipsUrl=a[12].toObject(e.startUpTipsUrl,t)),void 0!==e.numProStartUpTips&&null!==e.numProStartUpTips&&e.hasOwnProperty("numProStartUpTips")&&(r.numProStartUpTips=e.numProStartUpTips),void 0!==e.proStartUpTipsUrl&&null!==e.proStartUpTipsUrl&&e.hasOwnProperty("proStartUpTipsUrl")&&(r.proStartUpTipsUrl=a[14].toObject(e.proStartUpTipsUrl,t)),void 0!==e.startupTipsIntlUrl&&null!==e.startupTipsIntlUrl&&e.hasOwnProperty("startupTipsIntlUrl")&&(r.startupTipsIntlUrl=a[15].toObject(e.startupTipsIntlUrl,t)),void 0!==e.userGuideIntlUrl&&null!==e.userGuideIntlUrl&&e.hasOwnProperty("userGuideIntlUrl")&&(r.userGuideIntlUrl=a[16].toObject(e.userGuideIntlUrl,t)),void 0!==e.supportCenterIntlUrl&&null!==e.supportCenterIntlUrl&&e.hasOwnProperty("supportCenterIntlUrl")&&(r.supportCenterIntlUrl=a[17].toObject(e.supportCenterIntlUrl,t)),void 0!==e.businessListingIntlUrl&&null!==e.businessListingIntlUrl&&e.hasOwnProperty("businessListingIntlUrl")&&(r.businessListingIntlUrl=a[18].toObject(e.businessListingIntlUrl,t)),void 0!==e.supportAnswerIntlUrl&&null!==e.supportAnswerIntlUrl&&e.hasOwnProperty("supportAnswerIntlUrl")&&(r.supportAnswerIntlUrl=a[19].toObject(e.supportAnswerIntlUrl,t)),void 0!==e.supportTopicIntlUrl&&null!==e.supportTopicIntlUrl&&e.hasOwnProperty("supportTopicIntlUrl")&&(r.supportTopicIntlUrl=a[20].toObject(e.supportTopicIntlUrl,t)),void 0!==e.supportRequestIntlUrl&&null!==e.supportRequestIntlUrl&&e.hasOwnProperty("supportRequestIntlUrl")&&(r.supportRequestIntlUrl=a[21].toObject(e.supportRequestIntlUrl,t)),void 0!==e.earthIntlUrl&&null!==e.earthIntlUrl&&e.hasOwnProperty("earthIntlUrl")&&(r.earthIntlUrl=a[22].toObject(e.earthIntlUrl,t)),void 0!==e.addContentUrl&&null!==e.addContentUrl&&e.hasOwnProperty("addContentUrl")&&(r.addContentUrl=a[23].toObject(e.addContentUrl,t)),void 0!==e.sketchupNotInstalledUrl&&null!==e.sketchupNotInstalledUrl&&e.hasOwnProperty("sketchupNotInstalledUrl")&&(r.sketchupNotInstalledUrl=a[24].toObject(e.sketchupNotInstalledUrl,t)),void 0!==e.sketchupErrorUrl&&null!==e.sketchupErrorUrl&&e.hasOwnProperty("sketchupErrorUrl")&&(r.sketchupErrorUrl=a[25].toObject(e.sketchupErrorUrl,t)),void 0!==e.freeLicenseUrl&&null!==e.freeLicenseUrl&&e.hasOwnProperty("freeLicenseUrl")&&(r.freeLicenseUrl=a[26].toObject(e.freeLicenseUrl,t)),void 0!==e.proLicenseUrl&&null!==e.proLicenseUrl&&e.hasOwnProperty("proLicenseUrl")&&(r.proLicenseUrl=a[27].toObject(e.proLicenseUrl,t)),void 0!==e.tutorialUrl&&null!==e.tutorialUrl&&e.hasOwnProperty("tutorialUrl")&&(r.tutorialUrl=a[28].toObject(e.tutorialUrl,t)),void 0!==e.keyboardShortcutsUrl&&null!==e.keyboardShortcutsUrl&&e.hasOwnProperty("keyboardShortcutsUrl")&&(r.keyboardShortcutsUrl=a[29].toObject(e.keyboardShortcutsUrl,t)),void 0!==e.releaseNotesUrl&&null!==e.releaseNotesUrl&&e.hasOwnProperty("releaseNotesUrl")&&(r.releaseNotesUrl=a[30].toObject(e.releaseNotesUrl,t)),void 0!==e.hideUserData&&null!==e.hideUserData&&e.hasOwnProperty("hideUserData")&&(r.hideUserData=e.hideUserData),void 0!==e.useGeLogo&&null!==e.useGeLogo&&e.hasOwnProperty("useGeLogo")&&(r.useGeLogo=e.useGeLogo),void 0!==e.dioramaDescriptionUrlBase&&null!==e.dioramaDescriptionUrlBase&&e.hasOwnProperty("dioramaDescriptionUrlBase")&&(r.dioramaDescriptionUrlBase=a[33].toObject(e.dioramaDescriptionUrlBase,t)),void 0!==e.dioramaDefaultColor&&null!==e.dioramaDefaultColor&&e.hasOwnProperty("dioramaDefaultColor")&&(r.dioramaDefaultColor=e.dioramaDefaultColor),void 0!==e.dioramaBlacklistUrl&&null!==e.dioramaBlacklistUrl&&e.hasOwnProperty("dioramaBlacklistUrl")&&(r.dioramaBlacklistUrl=a[35].toObject(e.dioramaBlacklistUrl,t)),void 0!==e.clientOptions&&null!==e.clientOptions&&e.hasOwnProperty("clientOptions")&&(r.clientOptions=a[36].toObject(e.clientOptions,t)),void 0!==e.fetchingOptions&&null!==e.fetchingOptions&&e.hasOwnProperty("fetchingOptions")&&(r.fetchingOptions=a[37].toObject(e.fetchingOptions,t)),void 0!==e.timeMachineOptions&&null!==e.timeMachineOptions&&e.hasOwnProperty("timeMachineOptions")&&(r.timeMachineOptions=a[38].toObject(e.timeMachineOptions,t)),void 0!==e.csiOptions&&null!==e.csiOptions&&e.hasOwnProperty("csiOptions")&&(r.csiOptions=a[39].toObject(e.csiOptions,t)),void 0!==e.searchTab&&null!==e.searchTab&&e.hasOwnProperty("searchTab")){r.searchTab=[];for(var i=0;i<e.searchTab.length;++i)r.searchTab[i]=a[40].toObject(e.searchTab[i],t)}if(void 0!==e.cobrandInfo&&null!==e.cobrandInfo&&e.hasOwnProperty("cobrandInfo")){r.cobrandInfo=[];for(var i=0;i<e.cobrandInfo.length;++i)r.cobrandInfo[i]=a[41].toObject(e.cobrandInfo[i],t)}if(void 0!==e.validDatabase&&null!==e.validDatabase&&e.hasOwnProperty("validDatabase")){r.validDatabase=[];for(var i=0;i<e.validDatabase.length;++i)r.validDatabase[i]=a[42].toObject(e.validDatabase[i],t)}if(void 0!==e.configScript&&null!==e.configScript&&e.hasOwnProperty("configScript")){r.configScript=[];for(var i=0;i<e.configScript.length;++i)r.configScript[i]=a[43].toObject(e.configScript[i],t)}if(void 0!==e.deauthServerUrl&&null!==e.deauthServerUrl&&e.hasOwnProperty("deauthServerUrl")&&(r.deauthServerUrl=a[44].toObject(e.deauthServerUrl,t)),void 0!==e.swoopParameters&&null!==e.swoopParameters&&e.hasOwnProperty("swoopParameters")&&(r.swoopParameters=a[45].toObject(e.swoopParameters,t)),void 0!==e.bbsServerInfo&&null!==e.bbsServerInfo&&e.hasOwnProperty("bbsServerInfo")&&(r.bbsServerInfo=a[46].toObject(e.bbsServerInfo,t)),void 0!==e.dataErrorServerInfo&&null!==e.dataErrorServerInfo&&e.hasOwnProperty("dataErrorServerInfo")&&(r.dataErrorServerInfo=a[47].toObject(e.dataErrorServerInfo,t)),void 0!==e.planetaryDatabase&&null!==e.planetaryDatabase&&e.hasOwnProperty("planetaryDatabase")){r.planetaryDatabase=[];for(var i=0;i<e.planetaryDatabase.length;++i)r.planetaryDatabase[i]=a[48].toObject(e.planetaryDatabase[i],t)}if(void 0!==e.logServer&&null!==e.logServer&&e.hasOwnProperty("logServer")&&(r.logServer=a[49].toObject(e.logServer,t)),void 0!==e.autopiaOptions&&null!==e.autopiaOptions&&e.hasOwnProperty("autopiaOptions")&&(r.autopiaOptions=a[50].toObject(e.autopiaOptions,t)),void 0!==e.searchConfig&&null!==e.searchConfig&&e.hasOwnProperty("searchConfig")&&(r.searchConfig=a[51].toObject(e.searchConfig,t)),void 0!==e.searchInfo&&null!==e.searchInfo&&e.hasOwnProperty("searchInfo")&&(r.searchInfo=a[52].toObject(e.searchInfo,t)),void 0!==e.elevationServiceBaseUrl&&null!==e.elevationServiceBaseUrl&&e.hasOwnProperty("elevationServiceBaseUrl")&&(r.elevationServiceBaseUrl=e.elevationServiceBaseUrl),void 0!==e.elevationProfileQueryDelay&&null!==e.elevationProfileQueryDelay&&e.hasOwnProperty("elevationProfileQueryDelay")&&(r.elevationProfileQueryDelay=e.elevationProfileQueryDelay),void 0!==e.proUpgradeUrl&&null!==e.proUpgradeUrl&&e.hasOwnProperty("proUpgradeUrl")&&(r.proUpgradeUrl=a[55].toObject(e.proUpgradeUrl,t)),void 0!==e.earthCommunityUrl&&null!==e.earthCommunityUrl&&e.hasOwnProperty("earthCommunityUrl")&&(r.earthCommunityUrl=a[56].toObject(e.earthCommunityUrl,t)),void 0!==e.googleMapsUrl&&null!==e.googleMapsUrl&&e.hasOwnProperty("googleMapsUrl")&&(r.googleMapsUrl=a[57].toObject(e.googleMapsUrl,t)),void 0!==e.sharingUrl&&null!==e.sharingUrl&&e.hasOwnProperty("sharingUrl")&&(r.sharingUrl=a[58].toObject(e.sharingUrl,t)),void 0!==e.privacyPolicyUrl&&null!==e.privacyPolicyUrl&&e.hasOwnProperty("privacyPolicyUrl")&&(r.privacyPolicyUrl=a[59].toObject(e.privacyPolicyUrl,t)),void 0!==e.doGplusUserCheck&&null!==e.doGplusUserCheck&&e.hasOwnProperty("doGplusUserCheck")&&(r.doGplusUserCheck=e.doGplusUserCheck),void 0!==e.rocktreeDataProto&&null!==e.rocktreeDataProto&&e.hasOwnProperty("rocktreeDataProto")&&(r.rocktreeDataProto=a[61].toObject(e.rocktreeDataProto,t)),void 0!==e.filmstripConfig&&null!==e.filmstripConfig&&e.hasOwnProperty("filmstripConfig")){r.filmstripConfig=[];for(var i=0;i<e.filmstripConfig.length;++i)r.filmstripConfig[i]=a[62].toObject(e.filmstripConfig[i],t)}return void 0!==e.showSigninButton&&null!==e.showSigninButton&&e.hasOwnProperty("showSigninButton")&&(r.showSigninButton=e.showSigninButton),void 0!==e.proMeasureUpsellUrl&&null!==e.proMeasureUpsellUrl&&e.hasOwnProperty("proMeasureUpsellUrl")&&(r.proMeasureUpsellUrl=a[64].toObject(e.proMeasureUpsellUrl,t)),void 0!==e.proPrintUpsellUrl&&null!==e.proPrintUpsellUrl&&e.hasOwnProperty("proPrintUpsellUrl")&&(r.proPrintUpsellUrl=a[65].toObject(e.proPrintUpsellUrl,t)),void 0!==e.starDataProto&&null!==e.starDataProto&&e.hasOwnProperty("starDataProto")&&(r.starDataProto=a[66].toObject(e.starDataProto,t)),void 0!==e.feedbackUrl&&null!==e.feedbackUrl&&e.hasOwnProperty("feedbackUrl")&&(r.feedbackUrl=a[67].toObject(e.feedbackUrl,t)),void 0!==e.oauth2LoginUrl&&null!==e.oauth2LoginUrl&&e.hasOwnProperty("oauth2LoginUrl")&&(r.oauth2LoginUrl=a[68].toObject(e.oauth2LoginUrl,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.SearchConfigProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.searchServer=r.emptyArray,o.prototype.oneboxService=r.emptyArray,o.prototype.kmlSearchUrl=null,o.prototype.kmlRenderUrl=null,o.prototype.searchHistoryUrl=null,o.prototype.errorPageUrl=null;var a={0:"keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer",1:"keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto",2:"keyhole.dbroot.StringIdOrValueProto",3:"keyhole.dbroot.StringIdOrValueProto",4:"keyhole.dbroot.StringIdOrValueProto",5:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.searchServer&&o.searchServer.length||(o.searchServer=[]),o.searchServer.push(a[0].decode(e,e.uint32()));break;case 2:o.oneboxService&&o.oneboxService.length||(o.oneboxService=[]),o.oneboxService.push(a[1].decode(e,e.uint32()));break;case 3:o.kmlSearchUrl=a[2].decode(e,e.uint32());break;case 4:o.kmlRenderUrl=a[3].decode(e,e.uint32());break;case 6:o.searchHistoryUrl=a[4].decode(e,e.uint32());break;case 5:o.errorPageUrl=a[5].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.searchServer){if(!Array.isArray(e.searchServer))return"searchServer: array expected";for(var t=0;t<e.searchServer.length;++t){var r=a[0].verify(e.searchServer[t]);if(r)return"searchServer."+r}}if(void 0!==e.oneboxService){if(!Array.isArray(e.oneboxService))return"oneboxService: array expected";for(var t=0;t<e.oneboxService.length;++t){var r=a[1].verify(e.oneboxService[t]);if(r)return"oneboxService."+r}}if(void 0!==e.kmlSearchUrl&&null!==e.kmlSearchUrl){var r=a[2].verify(e.kmlSearchUrl);if(r)return"kmlSearchUrl."+r}if(void 0!==e.kmlRenderUrl&&null!==e.kmlRenderUrl){var r=a[3].verify(e.kmlRenderUrl);if(r)return"kmlRenderUrl."+r}if(void 0!==e.searchHistoryUrl&&null!==e.searchHistoryUrl){var r=a[4].verify(e.searchHistoryUrl);if(r)return"searchHistoryUrl."+r}if(void 0!==e.errorPageUrl&&null!==e.errorPageUrl){var r=a[5].verify(e.errorPageUrl);if(r)return"errorPageUrl."+r}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto;if(e.searchServer){if(!Array.isArray(e.searchServer))throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchServer: array expected");t.searchServer=[];for(var r=0;r<e.searchServer.length;++r){if("object"!=typeof e.searchServer[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchServer: object expected");t.searchServer[r]=a[0].fromObject(e.searchServer[r])}}if(e.oneboxService){if(!Array.isArray(e.oneboxService))throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.oneboxService: array expected");t.oneboxService=[];for(var r=0;r<e.oneboxService.length;++r){if("object"!=typeof e.oneboxService[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.oneboxService: object expected");t.oneboxService[r]=a[1].fromObject(e.oneboxService[r])}}if(void 0!==e.kmlSearchUrl&&null!==e.kmlSearchUrl){if("object"!=typeof e.kmlSearchUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.kmlSearchUrl: object expected");t.kmlSearchUrl=a[2].fromObject(e.kmlSearchUrl)}if(void 0!==e.kmlRenderUrl&&null!==e.kmlRenderUrl){if("object"!=typeof e.kmlRenderUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.kmlRenderUrl: object expected");t.kmlRenderUrl=a[3].fromObject(e.kmlRenderUrl)}if(void 0!==e.searchHistoryUrl&&null!==e.searchHistoryUrl){if("object"!=typeof e.searchHistoryUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchHistoryUrl: object expected") +;t.searchHistoryUrl=a[4].fromObject(e.searchHistoryUrl)}if(void 0!==e.errorPageUrl&&null!==e.errorPageUrl){if("object"!=typeof e.errorPageUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.errorPageUrl: object expected");t.errorPageUrl=a[5].fromObject(e.errorPageUrl)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.searchServer=[],r.oneboxService=[]),t.defaults&&(r.kmlSearchUrl=null,r.kmlRenderUrl=null,r.searchHistoryUrl=null,r.errorPageUrl=null),void 0!==e.searchServer&&null!==e.searchServer&&e.hasOwnProperty("searchServer")){r.searchServer=[];for(var i=0;i<e.searchServer.length;++i)r.searchServer[i]=a[0].toObject(e.searchServer[i],t)}if(void 0!==e.oneboxService&&null!==e.oneboxService&&e.hasOwnProperty("oneboxService")){r.oneboxService=[];for(var i=0;i<e.oneboxService.length;++i)r.oneboxService[i]=a[1].toObject(e.oneboxService[i],t)}return void 0!==e.kmlSearchUrl&&null!==e.kmlSearchUrl&&e.hasOwnProperty("kmlSearchUrl")&&(r.kmlSearchUrl=a[2].toObject(e.kmlSearchUrl,t)),void 0!==e.kmlRenderUrl&&null!==e.kmlRenderUrl&&e.hasOwnProperty("kmlRenderUrl")&&(r.kmlRenderUrl=a[3].toObject(e.kmlRenderUrl,t)),void 0!==e.searchHistoryUrl&&null!==e.searchHistoryUrl&&e.hasOwnProperty("searchHistoryUrl")&&(r.searchHistoryUrl=a[4].toObject(e.searchHistoryUrl,t)),void 0!==e.errorPageUrl&&null!==e.errorPageUrl&&e.hasOwnProperty("errorPageUrl")&&(r.errorPageUrl=a[5].toObject(e.errorPageUrl,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.SearchServer=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.name=null,o.prototype.url=null,o.prototype.type=0,o.prototype.htmlTransformUrl=null,o.prototype.kmlTransformUrl=null,o.prototype.supplementalUi=null,o.prototype.suggestion=r.emptyArray,o.prototype.searchlet=r.emptyArray,o.prototype.requirements=null,o.prototype.suggestServer=null;var a={0:"keyhole.dbroot.StringIdOrValueProto",1:"keyhole.dbroot.StringIdOrValueProto",2:"keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.ResultType",3:"keyhole.dbroot.StringIdOrValueProto",4:"keyhole.dbroot.StringIdOrValueProto",5:"keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi",6:"keyhole.dbroot.StringIdOrValueProto",7:"keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto",8:"keyhole.dbroot.RequirementProto",9:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.name=a[0].decode(e,e.uint32());break;case 2:o.url=a[1].decode(e,e.uint32());break;case 3:o.type=e.uint32();break;case 4:o.htmlTransformUrl=a[3].decode(e,e.uint32());break;case 5:o.kmlTransformUrl=a[4].decode(e,e.uint32());break;case 6:o.supplementalUi=a[5].decode(e,e.uint32());break;case 9:o.suggestion&&o.suggestion.length||(o.suggestion=[]),o.suggestion.push(a[6].decode(e,e.uint32()));break;case 7:o.searchlet&&o.searchlet.length||(o.searchlet=[]),o.searchlet.push(a[7].decode(e,e.uint32()));break;case 8:o.requirements=a[8].decode(e,e.uint32());break;case 10:o.suggestServer=a[9].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.name&&null!==e.name){var t=a[0].verify(e.name);if(t)return"name."+t}if(void 0!==e.url&&null!==e.url){var t=a[1].verify(e.url);if(t)return"url."+t}if(void 0!==e.type)switch(e.type){default:return"type: enum value expected";case 0:case 1:}if(void 0!==e.htmlTransformUrl&&null!==e.htmlTransformUrl){var t=a[3].verify(e.htmlTransformUrl);if(t)return"htmlTransformUrl."+t}if(void 0!==e.kmlTransformUrl&&null!==e.kmlTransformUrl){var t=a[4].verify(e.kmlTransformUrl);if(t)return"kmlTransformUrl."+t}if(void 0!==e.supplementalUi&&null!==e.supplementalUi){var t=a[5].verify(e.supplementalUi);if(t)return"supplementalUi."+t}if(void 0!==e.suggestion){if(!Array.isArray(e.suggestion))return"suggestion: array expected";for(var r=0;r<e.suggestion.length;++r){var t=a[6].verify(e.suggestion[r]);if(t)return"suggestion."+t}}if(void 0!==e.searchlet){if(!Array.isArray(e.searchlet))return"searchlet: array expected";for(var r=0;r<e.searchlet.length;++r){var t=a[7].verify(e.searchlet[r]);if(t)return"searchlet."+t}}if(void 0!==e.requirements&&null!==e.requirements){var t=a[8].verify(e.requirements);if(t)return"requirements."+t}if(void 0!==e.suggestServer&&null!==e.suggestServer){var t=a[9].verify(e.suggestServer);if(t)return"suggestServer."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer;if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.name: object expected");t.name=a[0].fromObject(e.name)}if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.url: object expected");t.url=a[1].fromObject(e.url)}switch(e.type){case"RESULT_TYPE_KML":case 0:t.type=0;break;case"RESULT_TYPE_XML":case 1:t.type=1}if(void 0!==e.htmlTransformUrl&&null!==e.htmlTransformUrl){if("object"!=typeof e.htmlTransformUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.htmlTransformUrl: object expected");t.htmlTransformUrl=a[3].fromObject(e.htmlTransformUrl)}if(void 0!==e.kmlTransformUrl&&null!==e.kmlTransformUrl){if("object"!=typeof e.kmlTransformUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.kmlTransformUrl: object expected");t.kmlTransformUrl=a[4].fromObject(e.kmlTransformUrl)}if(void 0!==e.supplementalUi&&null!==e.supplementalUi){if("object"!=typeof e.supplementalUi)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.supplementalUi: object expected");t.supplementalUi=a[5].fromObject(e.supplementalUi)}if(e.suggestion){if(!Array.isArray(e.suggestion))throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestion: array expected");t.suggestion=[];for(var r=0;r<e.suggestion.length;++r){if("object"!=typeof e.suggestion[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestion: object expected");t.suggestion[r]=a[6].fromObject(e.suggestion[r])}}if(e.searchlet){if(!Array.isArray(e.searchlet))throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.searchlet: array expected");t.searchlet=[];for(var r=0;r<e.searchlet.length;++r){if("object"!=typeof e.searchlet[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.searchlet: object expected");t.searchlet[r]=a[7].fromObject(e.searchlet[r])}}if(void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.requirements: object expected");t.requirements=a[8].fromObject(e.requirements)}if(void 0!==e.suggestServer&&null!==e.suggestServer){if("object"!=typeof e.suggestServer)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestServer: object expected");t.suggestServer=a[9].fromObject(e.suggestServer)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.suggestion=[],r.searchlet=[]),t.defaults&&(r.name=null,r.url=null,r.type=t.enums===String?"RESULT_TYPE_KML":0,r.htmlTransformUrl=null,r.kmlTransformUrl=null,r.supplementalUi=null,r.requirements=null,r.suggestServer=null),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=a[0].toObject(e.name,t)),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=a[1].toObject(e.url,t)),void 0!==e.type&&null!==e.type&&e.hasOwnProperty("type")&&(r.type=t.enums===String?a[2][e.type]:e.type),void 0!==e.htmlTransformUrl&&null!==e.htmlTransformUrl&&e.hasOwnProperty("htmlTransformUrl")&&(r.htmlTransformUrl=a[3].toObject(e.htmlTransformUrl,t)),void 0!==e.kmlTransformUrl&&null!==e.kmlTransformUrl&&e.hasOwnProperty("kmlTransformUrl")&&(r.kmlTransformUrl=a[4].toObject(e.kmlTransformUrl,t)),void 0!==e.supplementalUi&&null!==e.supplementalUi&&e.hasOwnProperty("supplementalUi")&&(r.supplementalUi=a[5].toObject(e.supplementalUi,t)),void 0!==e.suggestion&&null!==e.suggestion&&e.hasOwnProperty("suggestion")){r.suggestion=[];for(var i=0;i<e.suggestion.length;++i)r.suggestion[i]=a[6].toObject(e.suggestion[i],t)}if(void 0!==e.searchlet&&null!==e.searchlet&&e.hasOwnProperty("searchlet")){r.searchlet=[];for(var i=0;i<e.searchlet.length;++i)r.searchlet[i]=a[7].toObject(e.searchlet[i],t)}return void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=a[8].toObject(e.requirements,t)),void 0!==e.suggestServer&&null!==e.suggestServer&&e.hasOwnProperty("suggestServer")&&(r.suggestServer=a[9].toObject(e.suggestServer,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.ResultType=function(){var e={},t=Object.create(e);return t.RESULT_TYPE_KML=0,t.RESULT_TYPE_XML=1,t}(),o.SupplementalUi=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.url=null,o.prototype.label=null,o.prototype.height=160;var a={0:"keyhole.dbroot.StringIdOrValueProto",1:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.url=a[0].decode(e,e.uint32());break;case 2:o.label=a[1].decode(e,e.uint32());break;case 3:o.height=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=a[0].verify(e.url);if(t)return"url."+t}if(void 0!==e.label&&null!==e.label){var t=a[1].verify(e.label);if(t)return"label."+t}return void 0===e.height||r.isInteger(e.height)?null:"height: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.url: object expected");t.url=a[0].fromObject(e.url)}if(void 0!==e.label&&null!==e.label){if("object"!=typeof e.label)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.label: object expected");t.label=a[1].fromObject(e.label)}return void 0!==e.height&&null!==e.height&&(t.height=0|e.height),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.label=null,r.height=160),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=a[0].toObject(e.url,t)),void 0!==e.label&&null!==e.label&&e.hasOwnProperty("label")&&(r.label=a[1].toObject(e.label,t)),void 0!==e.height&&null!==e.height&&e.hasOwnProperty("height")&&(r.height=e.height),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.SearchletProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.url=null,r.prototype.name=null,r.prototype.requirements=null;var o={0:"keyhole.dbroot.StringIdOrValueProto",1:"keyhole.dbroot.StringIdOrValueProto",2:"keyhole.dbroot.RequirementProto"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,a=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:a.url=o[0].decode(e,e.uint32());break;case 2:a.name=o[1].decode(e,e.uint32());break;case 3:a.requirements=o[2].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=o[0].verify(e.url);if(t)return"url."+t}if(void 0!==e.name&&null!==e.name){var t=o[1].verify(e.name);if(t)return"name."+t}if(void 0!==e.requirements&&null!==e.requirements){var t=o[2].verify(e.requirements);if(t)return"requirements."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.url: object expected");t.url=o[0].fromObject(e.url)}if(void 0!==e.name&&null!==e.name){if("object"!=typeof e.name)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.name: object expected");t.name=o[1].fromObject(e.name)}if(void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.requirements: object expected");t.requirements=o[2].fromObject(e.requirements)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null,r.name=null,r.requirements=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),void 0!==e.name&&null!==e.name&&e.hasOwnProperty("name")&&(r.name=o[1].toObject(e.name,t)),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=o[2].toObject(e.requirements,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o}(),o.OneboxServiceProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.serviceUrl=null,r.prototype.requirements=null;var o={0:"keyhole.dbroot.StringIdOrValueProto",1:"keyhole.dbroot.RequirementProto"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,a=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:a.serviceUrl=o[0].decode(e,e.uint32());break;case 2:a.requirements=o[1].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.serviceUrl&&null!==e.serviceUrl){var t=o[0].verify(e.serviceUrl);if(t)return"serviceUrl."+t}if(void 0!==e.requirements&&null!==e.requirements){var t=o[1].verify(e.requirements);if(t)return"requirements."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto;if(void 0!==e.serviceUrl&&null!==e.serviceUrl){if("object"!=typeof e.serviceUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.serviceUrl: object expected");t.serviceUrl=o[0].fromObject(e.serviceUrl)}if(void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.requirements: object expected");t.requirements=o[1].fromObject(e.requirements)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.serviceUrl=null,r.requirements=null),void 0!==e.serviceUrl&&null!==e.serviceUrl&&e.hasOwnProperty("serviceUrl")&&(r.serviceUrl=o[0].toObject(e.serviceUrl,t)),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=o[1].toObject(e.requirements,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o}(),o.SearchInfoProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.defaultUrl="http://maps.google.com/maps",i.prototype.geocodeParam="q",i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto.SearchInfoProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.defaultUrl=e.string();break;case 2:o.geocodeParam=e.string();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":void 0===e.defaultUrl||r.isString(e.defaultUrl)?void 0===e.geocodeParam||r.isString(e.geocodeParam)?null:"geocodeParam: string expected":"defaultUrl: string expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.SearchInfoProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.SearchInfoProto;return void 0!==e.defaultUrl&&null!==e.defaultUrl&&(t.defaultUrl=String(e.defaultUrl)),void 0!==e.geocodeParam&&null!==e.geocodeParam&&(t.geocodeParam=String(e.geocodeParam)),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.defaultUrl="http://maps.google.com/maps",r.geocodeParam="q"),void 0!==e.defaultUrl&&null!==e.defaultUrl&&e.hasOwnProperty("defaultUrl")&&(r.defaultUrl=e.defaultUrl),void 0!==e.geocodeParam&&null!==e.geocodeParam&&e.hasOwnProperty("geocodeParam")&&(r.geocodeParam=e.geocodeParam),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.RockTreeDataProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.url=null;var o={0:"keyhole.dbroot.StringIdOrValueProto"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,a=new n.keyhole.dbroot.EndSnippetProto.RockTreeDataProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:a.url=o[0].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=o[0].verify(e.url);if(t)return"url."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.RockTreeDataProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.RockTreeDataProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.RockTreeDataProto.url: object expected");t.url=o[0].fromObject(e.url)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o.FilmstripConfigProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.requirements=null,o.prototype.alleycatUrlTemplate=null,o.prototype.fallbackAlleycatUrlTemplate=null,o.prototype.metadataUrlTemplate=null,o.prototype.thumbnailUrlTemplate=null,o.prototype.kmlUrlTemplate=null,o.prototype.featuredToursUrl=null,o.prototype.enableViewportFallback=!1,o.prototype.viewportFallbackDistance=0,o.prototype.imageryType=r.emptyArray;var a={0:"keyhole.dbroot.RequirementProto",1:"keyhole.dbroot.StringIdOrValueProto",2:"keyhole.dbroot.StringIdOrValueProto",3:"keyhole.dbroot.StringIdOrValueProto",4:"keyhole.dbroot.StringIdOrValueProto",5:"keyhole.dbroot.StringIdOrValueProto",6:"keyhole.dbroot.StringIdOrValueProto",9:"keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.requirements=a[0].decode(e,e.uint32());break;case 2:o.alleycatUrlTemplate=a[1].decode(e,e.uint32());break;case 9:o.fallbackAlleycatUrlTemplate=a[2].decode(e,e.uint32());break;case 3:o.metadataUrlTemplate=a[3].decode(e,e.uint32());break;case 4:o.thumbnailUrlTemplate=a[4].decode(e,e.uint32());break;case 5:o.kmlUrlTemplate=a[5].decode(e,e.uint32());break;case 6:o.featuredToursUrl=a[6].decode(e,e.uint32());break;case 7:o.enableViewportFallback=e.bool();break;case 8:o.viewportFallbackDistance=e.uint32();break;case 10:o.imageryType&&o.imageryType.length||(o.imageryType=[]),o.imageryType.push(a[9].decode(e,e.uint32()));break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.requirements&&null!==e.requirements){var t=a[0].verify(e.requirements);if(t)return"requirements."+t}if(void 0!==e.alleycatUrlTemplate&&null!==e.alleycatUrlTemplate){var t=a[1].verify(e.alleycatUrlTemplate);if(t)return"alleycatUrlTemplate."+t}if(void 0!==e.fallbackAlleycatUrlTemplate&&null!==e.fallbackAlleycatUrlTemplate){var t=a[2].verify(e.fallbackAlleycatUrlTemplate);if(t)return"fallbackAlleycatUrlTemplate."+t}if(void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){var t=a[3].verify(e.metadataUrlTemplate);if(t)return"metadataUrlTemplate."+t}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){var t=a[4].verify(e.thumbnailUrlTemplate);if(t)return"thumbnailUrlTemplate."+t}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){var t=a[5].verify(e.kmlUrlTemplate);if(t)return"kmlUrlTemplate."+t}if(void 0!==e.featuredToursUrl&&null!==e.featuredToursUrl){var t=a[6].verify(e.featuredToursUrl);if(t)return"featuredToursUrl."+t}if(void 0!==e.enableViewportFallback&&"boolean"!=typeof e.enableViewportFallback)return"enableViewportFallback: boolean expected";if(void 0!==e.viewportFallbackDistance&&!r.isInteger(e.viewportFallbackDistance))return"viewportFallbackDistance: integer expected";if(void 0!==e.imageryType){if(!Array.isArray(e.imageryType))return"imageryType: array expected";for(var i=0;i<e.imageryType.length;++i){var t=a[9].verify(e.imageryType[i]);if(t)return"imageryType."+t}}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto;if(void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.requirements: object expected");t.requirements=a[0].fromObject(e.requirements)}if(void 0!==e.alleycatUrlTemplate&&null!==e.alleycatUrlTemplate){if("object"!=typeof e.alleycatUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.alleycatUrlTemplate: object expected");t.alleycatUrlTemplate=a[1].fromObject(e.alleycatUrlTemplate)}if(void 0!==e.fallbackAlleycatUrlTemplate&&null!==e.fallbackAlleycatUrlTemplate){if("object"!=typeof e.fallbackAlleycatUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.fallbackAlleycatUrlTemplate: object expected");t.fallbackAlleycatUrlTemplate=a[2].fromObject(e.fallbackAlleycatUrlTemplate)}if(void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){if("object"!=typeof e.metadataUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.metadataUrlTemplate: object expected");t.metadataUrlTemplate=a[3].fromObject(e.metadataUrlTemplate)}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){if("object"!=typeof e.thumbnailUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.thumbnailUrlTemplate: object expected");t.thumbnailUrlTemplate=a[4].fromObject(e.thumbnailUrlTemplate)}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){if("object"!=typeof e.kmlUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.kmlUrlTemplate: object expected");t.kmlUrlTemplate=a[5].fromObject(e.kmlUrlTemplate)}if(void 0!==e.featuredToursUrl&&null!==e.featuredToursUrl){if("object"!=typeof e.featuredToursUrl)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.featuredToursUrl: object expected");t.featuredToursUrl=a[6].fromObject(e.featuredToursUrl)}if(void 0!==e.enableViewportFallback&&null!==e.enableViewportFallback&&(t.enableViewportFallback=Boolean(e.enableViewportFallback)),void 0!==e.viewportFallbackDistance&&null!==e.viewportFallbackDistance&&(t.viewportFallbackDistance=e.viewportFallbackDistance>>>0),e.imageryType){if(!Array.isArray(e.imageryType))throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: array expected");t.imageryType=[];for(var r=0;r<e.imageryType.length;++r){if("object"!=typeof e.imageryType[r])throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: object expected");t.imageryType[r]=a[9].fromObject(e.imageryType[r])}}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.imageryType=[]),t.defaults&&(r.requirements=null,r.alleycatUrlTemplate=null,r.fallbackAlleycatUrlTemplate=null,r.metadataUrlTemplate=null,r.thumbnailUrlTemplate=null,r.kmlUrlTemplate=null,r.featuredToursUrl=null,r.enableViewportFallback=!1,r.viewportFallbackDistance=0),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=a[0].toObject(e.requirements,t)),void 0!==e.alleycatUrlTemplate&&null!==e.alleycatUrlTemplate&&e.hasOwnProperty("alleycatUrlTemplate")&&(r.alleycatUrlTemplate=a[1].toObject(e.alleycatUrlTemplate,t)),void 0!==e.fallbackAlleycatUrlTemplate&&null!==e.fallbackAlleycatUrlTemplate&&e.hasOwnProperty("fallbackAlleycatUrlTemplate")&&(r.fallbackAlleycatUrlTemplate=a[2].toObject(e.fallbackAlleycatUrlTemplate,t)),void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate&&e.hasOwnProperty("metadataUrlTemplate")&&(r.metadataUrlTemplate=a[3].toObject(e.metadataUrlTemplate,t)),void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate&&e.hasOwnProperty("thumbnailUrlTemplate")&&(r.thumbnailUrlTemplate=a[4].toObject(e.thumbnailUrlTemplate,t)),void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate&&e.hasOwnProperty("kmlUrlTemplate")&&(r.kmlUrlTemplate=a[5].toObject(e.kmlUrlTemplate,t)),void 0!==e.featuredToursUrl&&null!==e.featuredToursUrl&&e.hasOwnProperty("featuredToursUrl")&&(r.featuredToursUrl=a[6].toObject(e.featuredToursUrl,t)),void 0!==e.enableViewportFallback&&null!==e.enableViewportFallback&&e.hasOwnProperty("enableViewportFallback")&&(r.enableViewportFallback=e.enableViewportFallback),void 0!==e.viewportFallbackDistance&&null!==e.viewportFallbackDistance&&e.hasOwnProperty("viewportFallbackDistance")&&(r.viewportFallbackDistance=e.viewportFallbackDistance),void 0!==e.imageryType&&null!==e.imageryType&&e.hasOwnProperty("imageryType")){r.imageryType=[];for(var i=0;i<e.imageryType.length;++i)r.imageryType[i]=a[9].toObject(e.imageryType[i],t)}return r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.AlleycatImageryTypeProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.imageryTypeId=0,o.prototype.imageryTypeLabel="",o.prototype.metadataUrlTemplate=null,o.prototype.thumbnailUrlTemplate=null,o.prototype.kmlUrlTemplate=null;var a={2:"keyhole.dbroot.StringIdOrValueProto",3:"keyhole.dbroot.StringIdOrValueProto",4:"keyhole.dbroot.StringIdOrValueProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:o.imageryTypeId=e.int32();break;case 2:o.imageryTypeLabel=e.string();break;case 3:o.metadataUrlTemplate=a[2].decode(e,e.uint32());break;case 4:o.thumbnailUrlTemplate=a[3].decode(e,e.uint32());break;case 5:o.kmlUrlTemplate=a[4].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.imageryTypeId&&!r.isInteger(e.imageryTypeId))return"imageryTypeId: integer expected";if(void 0!==e.imageryTypeLabel&&!r.isString(e.imageryTypeLabel))return"imageryTypeLabel: string expected";if(void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){var t=a[2].verify(e.metadataUrlTemplate);if(t)return"metadataUrlTemplate."+t}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){var t=a[3].verify(e.thumbnailUrlTemplate);if(t)return"thumbnailUrlTemplate."+t}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){var t=a[4].verify(e.kmlUrlTemplate);if(t)return"kmlUrlTemplate."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto;if(void 0!==e.imageryTypeId&&null!==e.imageryTypeId&&(t.imageryTypeId=0|e.imageryTypeId),void 0!==e.imageryTypeLabel&&null!==e.imageryTypeLabel&&(t.imageryTypeLabel=String(e.imageryTypeLabel)),void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate){if("object"!=typeof e.metadataUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.metadataUrlTemplate: object expected");t.metadataUrlTemplate=a[2].fromObject(e.metadataUrlTemplate)}if(void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate){if("object"!=typeof e.thumbnailUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.thumbnailUrlTemplate: object expected");t.thumbnailUrlTemplate=a[3].fromObject(e.thumbnailUrlTemplate)}if(void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate){if("object"!=typeof e.kmlUrlTemplate)throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.kmlUrlTemplate: object expected");t.kmlUrlTemplate=a[4].fromObject(e.kmlUrlTemplate)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.imageryTypeId=0,r.imageryTypeLabel="",r.metadataUrlTemplate=null,r.thumbnailUrlTemplate=null,r.kmlUrlTemplate=null),void 0!==e.imageryTypeId&&null!==e.imageryTypeId&&e.hasOwnProperty("imageryTypeId")&&(r.imageryTypeId=e.imageryTypeId),void 0!==e.imageryTypeLabel&&null!==e.imageryTypeLabel&&e.hasOwnProperty("imageryTypeLabel")&&(r.imageryTypeLabel=e.imageryTypeLabel),void 0!==e.metadataUrlTemplate&&null!==e.metadataUrlTemplate&&e.hasOwnProperty("metadataUrlTemplate")&&(r.metadataUrlTemplate=a[2].toObject(e.metadataUrlTemplate,t)),void 0!==e.thumbnailUrlTemplate&&null!==e.thumbnailUrlTemplate&&e.hasOwnProperty("thumbnailUrlTemplate")&&(r.thumbnailUrlTemplate=a[3].toObject(e.thumbnailUrlTemplate,t)),void 0!==e.kmlUrlTemplate&&null!==e.kmlUrlTemplate&&e.hasOwnProperty("kmlUrlTemplate")&&(r.kmlUrlTemplate=a[4].toObject(e.kmlUrlTemplate,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o}(),o.StarDataProto=function(){function r(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}r.prototype.url=null;var o={0:"keyhole.dbroot.StringIdOrValueProto"};return i.push(o),r.decode=function(e,r){e instanceof t||(e=t.create(e)) +;for(var i=void 0===r?e.len:e.pos+r,a=new n.keyhole.dbroot.EndSnippetProto.StarDataProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 1:a.url=o[0].decode(e,e.uint32());break;default:e.skipType(7&s)}}return a},r.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.url&&null!==e.url){var t=o[0].verify(e.url);if(t)return"url."+t}return null},r.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EndSnippetProto.StarDataProto)return e;var t=new n.keyhole.dbroot.EndSnippetProto.StarDataProto;if(void 0!==e.url&&null!==e.url){if("object"!=typeof e.url)throw TypeError(".keyhole.dbroot.EndSnippetProto.StarDataProto.url: object expected");t.url=o[0].fromObject(e.url)}return t},r.from=r.fromObject,r.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=o[0].toObject(e.url,t)),r},r.prototype.toObject=function(e){return this.constructor.toObject(this,e)},r.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},r}(),o}(),o.DbRootRefProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.url="",o.prototype.isCritical=!1,o.prototype.requirements=null;var a={2:"keyhole.dbroot.RequirementProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.DbRootRefProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 2:o.url=e.string();break;case 1:o.isCritical=e.bool();break;case 3:o.requirements=a[2].decode(e,e.uint32());break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(!r.isString(e.url))return"url: string expected";if(void 0!==e.isCritical&&"boolean"!=typeof e.isCritical)return"isCritical: boolean expected";if(void 0!==e.requirements&&null!==e.requirements){var t=a[2].verify(e.requirements);if(t)return"requirements."+t}return null},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DbRootRefProto)return e;var t=new n.keyhole.dbroot.DbRootRefProto;if(void 0!==e.url&&null!==e.url&&(t.url=String(e.url)),void 0!==e.isCritical&&null!==e.isCritical&&(t.isCritical=Boolean(e.isCritical)),void 0!==e.requirements&&null!==e.requirements){if("object"!=typeof e.requirements)throw TypeError(".keyhole.dbroot.DbRootRefProto.requirements: object expected");t.requirements=a[2].fromObject(e.requirements)}return t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.url="",r.isCritical=!1,r.requirements=null),void 0!==e.url&&null!==e.url&&e.hasOwnProperty("url")&&(r.url=e.url),void 0!==e.isCritical&&null!==e.isCritical&&e.hasOwnProperty("isCritical")&&(r.isCritical=e.isCritical),void 0!==e.requirements&&null!==e.requirements&&e.hasOwnProperty("requirements")&&(r.requirements=a[2].toObject(e.requirements,t)),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.DatabaseVersionProto=function(){function i(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}return i.prototype.quadtreeVersion=0,i.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.DatabaseVersionProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.quadtreeVersion=e.uint32();break;default:e.skipType(7&a)}}return o},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":r.isInteger(e.quadtreeVersion)?null:"quadtreeVersion: integer expected"},i.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DatabaseVersionProto)return e;var t=new n.keyhole.dbroot.DatabaseVersionProto;return void 0!==e.quadtreeVersion&&null!==e.quadtreeVersion&&(t.quadtreeVersion=e.quadtreeVersion>>>0),t},i.from=i.fromObject,i.toObject=function(e,t){t||(t={});var r={};return t.defaults&&(r.quadtreeVersion=0),void 0!==e.quadtreeVersion&&null!==e.quadtreeVersion&&e.hasOwnProperty("quadtreeVersion")&&(r.quadtreeVersion=e.quadtreeVersion),r},i.prototype.toObject=function(e){return this.constructor.toObject(this,e)},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),o.DbRootProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.databaseName=null,o.prototype.imageryPresent=!0,o.prototype.protoImagery=!1,o.prototype.terrainPresent=!1,o.prototype.providerInfo=r.emptyArray,o.prototype.nestedFeature=r.emptyArray,o.prototype.styleAttribute=r.emptyArray,o.prototype.styleMap=r.emptyArray,o.prototype.endSnippet=null,o.prototype.translationEntry=r.emptyArray,o.prototype.language="en",o.prototype.version=5,o.prototype.dbrootReference=r.emptyArray,o.prototype.databaseVersion=null,o.prototype.refreshTimeout=0;var a={0:"keyhole.dbroot.StringIdOrValueProto",4:"keyhole.dbroot.ProviderInfoProto",5:"keyhole.dbroot.NestedFeatureProto",6:"keyhole.dbroot.StyleAttributeProto",7:"keyhole.dbroot.StyleMapProto",8:"keyhole.dbroot.EndSnippetProto",9:"keyhole.dbroot.StringEntryProto",12:"keyhole.dbroot.DbRootRefProto",13:"keyhole.dbroot.DatabaseVersionProto"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.DbRootProto;e.pos<i;){var s=e.uint32();switch(s>>>3){case 15:o.databaseName=a[0].decode(e,e.uint32());break;case 1:o.imageryPresent=e.bool();break;case 14:o.protoImagery=e.bool();break;case 2:o.terrainPresent=e.bool();break;case 3:o.providerInfo&&o.providerInfo.length||(o.providerInfo=[]),o.providerInfo.push(a[4].decode(e,e.uint32()));break;case 4:o.nestedFeature&&o.nestedFeature.length||(o.nestedFeature=[]),o.nestedFeature.push(a[5].decode(e,e.uint32()));break;case 5:o.styleAttribute&&o.styleAttribute.length||(o.styleAttribute=[]),o.styleAttribute.push(a[6].decode(e,e.uint32()));break;case 6:o.styleMap&&o.styleMap.length||(o.styleMap=[]),o.styleMap.push(a[7].decode(e,e.uint32()));break;case 7:o.endSnippet=a[8].decode(e,e.uint32());break;case 8:o.translationEntry&&o.translationEntry.length||(o.translationEntry=[]),o.translationEntry.push(a[9].decode(e,e.uint32()));break;case 9:o.language=e.string();break;case 10:o.version=e.int32();break;case 11:o.dbrootReference&&o.dbrootReference.length||(o.dbrootReference=[]),o.dbrootReference.push(a[12].decode(e,e.uint32()));break;case 13:o.databaseVersion=a[13].decode(e,e.uint32());break;case 16:o.refreshTimeout=e.int32();break;default:e.skipType(7&s)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.databaseName&&null!==e.databaseName){var t=a[0].verify(e.databaseName);if(t)return"databaseName."+t}if(void 0!==e.imageryPresent&&"boolean"!=typeof e.imageryPresent)return"imageryPresent: boolean expected";if(void 0!==e.protoImagery&&"boolean"!=typeof e.protoImagery)return"protoImagery: boolean expected";if(void 0!==e.terrainPresent&&"boolean"!=typeof e.terrainPresent)return"terrainPresent: boolean expected";if(void 0!==e.providerInfo){if(!Array.isArray(e.providerInfo))return"providerInfo: array expected";for(var i=0;i<e.providerInfo.length;++i){var t=a[4].verify(e.providerInfo[i]);if(t)return"providerInfo."+t}}if(void 0!==e.nestedFeature){if(!Array.isArray(e.nestedFeature))return"nestedFeature: array expected";for(var i=0;i<e.nestedFeature.length;++i){var t=a[5].verify(e.nestedFeature[i]);if(t)return"nestedFeature."+t}}if(void 0!==e.styleAttribute){if(!Array.isArray(e.styleAttribute))return"styleAttribute: array expected";for(var i=0;i<e.styleAttribute.length;++i){var t=a[6].verify(e.styleAttribute[i]);if(t)return"styleAttribute."+t}}if(void 0!==e.styleMap){if(!Array.isArray(e.styleMap))return"styleMap: array expected";for(var i=0;i<e.styleMap.length;++i){var t=a[7].verify(e.styleMap[i]);if(t)return"styleMap."+t}}if(void 0!==e.endSnippet&&null!==e.endSnippet){var t=a[8].verify(e.endSnippet);if(t)return"endSnippet."+t}if(void 0!==e.translationEntry){if(!Array.isArray(e.translationEntry))return"translationEntry: array expected";for(var i=0;i<e.translationEntry.length;++i){var t=a[9].verify(e.translationEntry[i]);if(t)return"translationEntry."+t}}if(void 0!==e.language&&!r.isString(e.language))return"language: string expected";if(void 0!==e.version&&!r.isInteger(e.version))return"version: integer expected";if(void 0!==e.dbrootReference){if(!Array.isArray(e.dbrootReference))return"dbrootReference: array expected";for(var i=0;i<e.dbrootReference.length;++i){var t=a[12].verify(e.dbrootReference[i]);if(t)return"dbrootReference."+t}}if(void 0!==e.databaseVersion&&null!==e.databaseVersion){var t=a[13].verify(e.databaseVersion);if(t)return"databaseVersion."+t}return void 0===e.refreshTimeout||r.isInteger(e.refreshTimeout)?null:"refreshTimeout: integer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.DbRootProto)return e;var t=new n.keyhole.dbroot.DbRootProto;if(void 0!==e.databaseName&&null!==e.databaseName){if("object"!=typeof e.databaseName)throw TypeError(".keyhole.dbroot.DbRootProto.databaseName: object expected");t.databaseName=a[0].fromObject(e.databaseName)}if(void 0!==e.imageryPresent&&null!==e.imageryPresent&&(t.imageryPresent=Boolean(e.imageryPresent)),void 0!==e.protoImagery&&null!==e.protoImagery&&(t.protoImagery=Boolean(e.protoImagery)),void 0!==e.terrainPresent&&null!==e.terrainPresent&&(t.terrainPresent=Boolean(e.terrainPresent)),e.providerInfo){if(!Array.isArray(e.providerInfo))throw TypeError(".keyhole.dbroot.DbRootProto.providerInfo: array expected");t.providerInfo=[];for(var r=0;r<e.providerInfo.length;++r){if("object"!=typeof e.providerInfo[r])throw TypeError(".keyhole.dbroot.DbRootProto.providerInfo: object expected");t.providerInfo[r]=a[4].fromObject(e.providerInfo[r])}}if(e.nestedFeature){if(!Array.isArray(e.nestedFeature))throw TypeError(".keyhole.dbroot.DbRootProto.nestedFeature: array expected");t.nestedFeature=[];for(var r=0;r<e.nestedFeature.length;++r){if("object"!=typeof e.nestedFeature[r])throw TypeError(".keyhole.dbroot.DbRootProto.nestedFeature: object expected");t.nestedFeature[r]=a[5].fromObject(e.nestedFeature[r])}}if(e.styleAttribute){if(!Array.isArray(e.styleAttribute))throw TypeError(".keyhole.dbroot.DbRootProto.styleAttribute: array expected");t.styleAttribute=[];for(var r=0;r<e.styleAttribute.length;++r){if("object"!=typeof e.styleAttribute[r])throw TypeError(".keyhole.dbroot.DbRootProto.styleAttribute: object expected");t.styleAttribute[r]=a[6].fromObject(e.styleAttribute[r])}}if(e.styleMap){if(!Array.isArray(e.styleMap))throw TypeError(".keyhole.dbroot.DbRootProto.styleMap: array expected");t.styleMap=[];for(var r=0;r<e.styleMap.length;++r){if("object"!=typeof e.styleMap[r])throw TypeError(".keyhole.dbroot.DbRootProto.styleMap: object expected");t.styleMap[r]=a[7].fromObject(e.styleMap[r])}}if(void 0!==e.endSnippet&&null!==e.endSnippet){if("object"!=typeof e.endSnippet)throw TypeError(".keyhole.dbroot.DbRootProto.endSnippet: object expected");t.endSnippet=a[8].fromObject(e.endSnippet)}if(e.translationEntry){if(!Array.isArray(e.translationEntry))throw TypeError(".keyhole.dbroot.DbRootProto.translationEntry: array expected");t.translationEntry=[];for(var r=0;r<e.translationEntry.length;++r){if("object"!=typeof e.translationEntry[r])throw TypeError(".keyhole.dbroot.DbRootProto.translationEntry: object expected");t.translationEntry[r]=a[9].fromObject(e.translationEntry[r])}}if(void 0!==e.language&&null!==e.language&&(t.language=String(e.language)),void 0!==e.version&&null!==e.version&&(t.version=0|e.version),e.dbrootReference){if(!Array.isArray(e.dbrootReference))throw TypeError(".keyhole.dbroot.DbRootProto.dbrootReference: array expected");t.dbrootReference=[];for(var r=0;r<e.dbrootReference.length;++r){if("object"!=typeof e.dbrootReference[r])throw TypeError(".keyhole.dbroot.DbRootProto.dbrootReference: object expected");t.dbrootReference[r]=a[12].fromObject(e.dbrootReference[r])}}if(void 0!==e.databaseVersion&&null!==e.databaseVersion){if("object"!=typeof e.databaseVersion)throw TypeError(".keyhole.dbroot.DbRootProto.databaseVersion: object expected");t.databaseVersion=a[13].fromObject(e.databaseVersion)}return void 0!==e.refreshTimeout&&null!==e.refreshTimeout&&(t.refreshTimeout=0|e.refreshTimeout),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var r={};if((t.arrays||t.defaults)&&(r.providerInfo=[],r.nestedFeature=[],r.styleAttribute=[],r.styleMap=[],r.translationEntry=[],r.dbrootReference=[]),t.defaults&&(r.databaseName=null,r.imageryPresent=!0,r.protoImagery=!1,r.terrainPresent=!1,r.endSnippet=null,r.language="en",r.version=5,r.databaseVersion=null,r.refreshTimeout=0),void 0!==e.databaseName&&null!==e.databaseName&&e.hasOwnProperty("databaseName")&&(r.databaseName=a[0].toObject(e.databaseName,t)),void 0!==e.imageryPresent&&null!==e.imageryPresent&&e.hasOwnProperty("imageryPresent")&&(r.imageryPresent=e.imageryPresent),void 0!==e.protoImagery&&null!==e.protoImagery&&e.hasOwnProperty("protoImagery")&&(r.protoImagery=e.protoImagery),void 0!==e.terrainPresent&&null!==e.terrainPresent&&e.hasOwnProperty("terrainPresent")&&(r.terrainPresent=e.terrainPresent),void 0!==e.providerInfo&&null!==e.providerInfo&&e.hasOwnProperty("providerInfo")){r.providerInfo=[];for(var i=0;i<e.providerInfo.length;++i)r.providerInfo[i]=a[4].toObject(e.providerInfo[i],t)}if(void 0!==e.nestedFeature&&null!==e.nestedFeature&&e.hasOwnProperty("nestedFeature")){r.nestedFeature=[];for(var i=0;i<e.nestedFeature.length;++i)r.nestedFeature[i]=a[5].toObject(e.nestedFeature[i],t)}if(void 0!==e.styleAttribute&&null!==e.styleAttribute&&e.hasOwnProperty("styleAttribute")){r.styleAttribute=[];for(var i=0;i<e.styleAttribute.length;++i)r.styleAttribute[i]=a[6].toObject(e.styleAttribute[i],t)}if(void 0!==e.styleMap&&null!==e.styleMap&&e.hasOwnProperty("styleMap")){r.styleMap=[];for(var i=0;i<e.styleMap.length;++i)r.styleMap[i]=a[7].toObject(e.styleMap[i],t)}if(void 0!==e.endSnippet&&null!==e.endSnippet&&e.hasOwnProperty("endSnippet")&&(r.endSnippet=a[8].toObject(e.endSnippet,t)),void 0!==e.translationEntry&&null!==e.translationEntry&&e.hasOwnProperty("translationEntry")){r.translationEntry=[];for(var i=0;i<e.translationEntry.length;++i)r.translationEntry[i]=a[9].toObject(e.translationEntry[i],t)}if(void 0!==e.language&&null!==e.language&&e.hasOwnProperty("language")&&(r.language=e.language),void 0!==e.version&&null!==e.version&&e.hasOwnProperty("version")&&(r.version=e.version),void 0!==e.dbrootReference&&null!==e.dbrootReference&&e.hasOwnProperty("dbrootReference")){r.dbrootReference=[];for(var i=0;i<e.dbrootReference.length;++i)r.dbrootReference[i]=a[12].toObject(e.dbrootReference[i],t)}return void 0!==e.databaseVersion&&null!==e.databaseVersion&&e.hasOwnProperty("databaseVersion")&&(r.databaseVersion=a[13].toObject(e.databaseVersion,t)),void 0!==e.refreshTimeout&&null!==e.refreshTimeout&&e.hasOwnProperty("refreshTimeout")&&(r.refreshTimeout=e.refreshTimeout),r},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o}(),o.EncryptedDbRootProto=function(){function o(e){if(e)for(var t=Object.keys(e),r=0;r<t.length;++r)this[t[r]]=e[t[r]]}o.prototype.encryptionType=0,o.prototype.encryptionData=r.newBuffer([]),o.prototype.dbrootData=r.newBuffer([]);var a={0:"keyhole.dbroot.EncryptedDbRootProto.EncryptionType"};return i.push(a),o.decode=function(e,r){e instanceof t||(e=t.create(e));for(var i=void 0===r?e.len:e.pos+r,o=new n.keyhole.dbroot.EncryptedDbRootProto;e.pos<i;){var a=e.uint32();switch(a>>>3){case 1:o.encryptionType=e.uint32();break;case 2:o.encryptionData=e.bytes();break;case 3:o.dbrootData=e.bytes();break;default:e.skipType(7&a)}}return o},o.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(void 0!==e.encryptionType)switch(e.encryptionType){default:return"encryptionType: enum value expected";case 0:}return void 0===e.encryptionData||e.encryptionData&&"number"==typeof e.encryptionData.length||r.isString(e.encryptionData)?void 0===e.dbrootData||e.dbrootData&&"number"==typeof e.dbrootData.length||r.isString(e.dbrootData)?null:"dbrootData: buffer expected":"encryptionData: buffer expected"},o.fromObject=function(e){if(e instanceof n.keyhole.dbroot.EncryptedDbRootProto)return e;var t=new n.keyhole.dbroot.EncryptedDbRootProto;switch(e.encryptionType){case"ENCRYPTION_XOR":case 0:t.encryptionType=0}return void 0!==e.encryptionData&&null!==e.encryptionData&&("string"==typeof e.encryptionData?r.base64.decode(e.encryptionData,t.encryptionData=r.newBuffer(r.base64.length(e.encryptionData)),0):e.encryptionData.length&&(t.encryptionData=e.encryptionData)),void 0!==e.dbrootData&&null!==e.dbrootData&&("string"==typeof e.dbrootData?r.base64.decode(e.dbrootData,t.dbrootData=r.newBuffer(r.base64.length(e.dbrootData)),0):e.dbrootData.length&&(t.dbrootData=e.dbrootData)),t},o.from=o.fromObject,o.toObject=function(e,t){t||(t={});var i={};return t.defaults&&(i.encryptionType=t.enums===String?"ENCRYPTION_XOR":0,i.encryptionData=t.bytes===String?"":[],i.dbrootData=t.bytes===String?"":[]),void 0!==e.encryptionType&&null!==e.encryptionType&&e.hasOwnProperty("encryptionType")&&(i.encryptionType=t.enums===String?a[0][e.encryptionType]:e.encryptionType),void 0!==e.encryptionData&&null!==e.encryptionData&&e.hasOwnProperty("encryptionData")&&(i.encryptionData=t.bytes===String?r.base64.encode(e.encryptionData,0,e.encryptionData.length):t.bytes===Array?Array.prototype.slice.call(e.encryptionData):e.encryptionData),void 0!==e.dbrootData&&null!==e.dbrootData&&e.hasOwnProperty("dbrootData")&&(i.dbrootData=t.bytes===String?r.base64.encode(e.dbrootData,0,e.dbrootData.length):t.bytes===Array?Array.prototype.slice.call(e.dbrootData):e.dbrootData),i},o.prototype.toObject=function(e){return this.constructor.toObject(this,e)},o.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},o.EncryptionType=function(){var e={},t=Object.create(e);return t.ENCRYPTION_XOR=0,t}(),o}(),o}(),o}(),r.lazyResolve(n,i),n.keyhole.dbroot}),define("Core/isBitSet",[],function(){"use strict";function e(e,t){return 0!=(e&t)}return e}),define("Core/GoogleEarthEnterpriseTileInformation",["./defined","./isBitSet"],function(e,t){"use strict";function r(e,t,r,i,n,o){this._bits=e,this.cnodeVersion=t,this.imageryVersion=r,this.terrainVersion=i,this.imageryProvider=n,this.terrainProvider=o,this.ancestorHasTerrain=!1,this.terrainState=void 0}var i=[1,2,4,8];return r.clone=function(t,i){return e(i)?(i._bits=t._bits,i.cnodeVersion=t.cnodeVersion,i.imageryVersion=t.imageryVersion,i.terrainVersion=t.terrainVersion,i.imageryProvider=t.imageryProvider,i.terrainProvider=t.terrainProvider):i=new r(t._bits,t.cnodeVersion,t.imageryVersion,t.terrainVersion,t.imageryProvider,t.terrainProvider),i.ancestorHasTerrain=t.ancestorHasTerrain,i.terrainState=t.terrainState,i},r.prototype.setParent=function(e){this.ancestorHasTerrain=e.ancestorHasTerrain||this.hasTerrain()},r.prototype.hasSubtree=function(){return t(this._bits,16)},r.prototype.hasImagery=function(){return t(this._bits,64)},r.prototype.hasTerrain=function(){return t(this._bits,128)},r.prototype.hasChildren=function(){return t(this._bits,15)},r.prototype.hasChild=function(e){return t(this._bits,i[e])},r.prototype.getChildBitmask=function(){return 15&this._bits},r}),define("Core/GoogleEarthEnterpriseMetadata",["../ThirdParty/google-earth-dbroot-parser","../ThirdParty/when","./appendForwardSlash","./Check","./Credit","./defaultValue","./defined","./defineProperties","./deprecationWarning","./GoogleEarthEnterpriseTileInformation","./isBitSet","./Math","./Request","./Resource","./RuntimeError","./TaskProcessor"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e){var r,i=e;"string"==typeof i||i instanceof p||(a(e.proxy)&&l("GoogleEarthEnterpriseMetadata","The options.url & options.proxy parameters have been deprecated. Specify a URL string or a Resource as the only parameter."),i=e.url,r=e.proxy);var n=p.createIfNeeded(i,{proxy:r});n.appendForwardSlash(),this._resource=n,this.imageryPresent=!0,this.protoImagery=void 0,this.terrainPresent=!0,this.negativeAltitudeExponentBias=32,this.negativeAltitudeThreshold=d.EPSILON12,this.providers={},this.key=void 0,this._quadPacketVersion=1,this._tileInfo={},this._subtreePromises={};var o=this;this._readyPromise=y(this).then(function(){return o.getQuadTreePacket("",o._quadPacketVersion)}).then(function(){return!0}).otherwise(function(e){var r="An error occurred while accessing "+v(o,"",1).url+".";return t.reject(new f(r))})}function _(e,r,i){var n=e._tileInfo,o=r,s=n[o];if(a(s)&&(!s.hasSubtree()||s.hasChildren()))return s;for(;void 0===s&&o.length>1;)o=o.substring(0,o.length-1),s=n[o];var l,u=e._subtreePromises,c=u[o];return a(c)?c.then(function(){return l=new h({throttle:i.throttle,throttleByServer:i.throttleByServer,type:i.type,priorityFunction:i.priorityFunction}),_(e,r,l)}):a(s)&&s.hasSubtree()?(c=e.getQuadTreePacket(o,s.cnodeVersion,i),a(c)?(u[o]=c,c.then(function(){return l=new h({throttle:i.throttle,throttleByServer:i.throttleByServer,type:i.type,priorityFunction:i.priorityFunction}),_(e,r,l)}).always(function(){delete u[o]})):void 0):t.reject(new f("Couldn't load metadata for tile "+r))}function v(e,t,r,i){return e._resource.getDerivedResource({url:"flatfile?q2-0"+t+"-q."+r.toString(),request:i})}function y(t){var r=t._resource.getDerivedResource({url:"dbRoot.v5",queryParameters:{output:"proto"}});return r.fetchArrayBuffer().then(function(r){var i=e.EncryptedDbRootProto.decode(new Uint8Array(r)),n=i.encryptionData,o=n.byteOffset,a=o+n.byteLength,s=t.key=n.buffer.slice(o,a);n=i.dbrootData,o=n.byteOffset,a=o+n.byteLength;var l=n.buffer.slice(o,a);return C.scheduleTask({buffer:l,type:"DbRoot",key:s},[l])}).then(function(r){var i=e.DbRootProto.decode(new Uint8Array(r.buffer));if(t.imageryPresent=o(i.imageryPresent,t.imageryPresent),t.protoImagery=i.protoImagery,t.terrainPresent=o(i.terrainPresent,t.terrainPresent),a(i.endSnippet)&&a(i.endSnippet.model)){var s=i.endSnippet.model;t.negativeAltitudeExponentBias=o(s.negativeAltitudeExponentBias,t.negativeAltitudeExponentBias),t.negativeAltitudeThreshold=o(s.compressedNegativeAltitudeThreshold,t.negativeAltitudeThreshold)}a(i.databaseVersion)&&(t._quadPacketVersion=o(i.databaseVersion.quadtreeVersion,t._quadPacketVersion));for(var l=t.providers,u=o(i.providerInfo,[]),c=u.length,d=0;d<c;++d){var h=u[d],p=h.copyrightString;a(p)&&(l[h.providerId]=new n({text:p.value}))}}).otherwise(function(){console.log("Failed to retrieve "+r.url+". Using defaults."),t.key=b})}var b=function(e){for(var t=e.length,r=new ArrayBuffer(t),i=new Uint8Array(r),n=0;n<t;++n)i[n]=e.charCodeAt(n);return r}('Eô½\vyâjE"’,ÍqøIFgQ\0B%Æèa,f)\bÆ4Üjb%y\nwmiÖðœk“¡½NuàA[ß@V\fÙ»r›|3SîOlÔq°{ÀEVZ­wUe\v3’*¬l5Å0sø3>mF8J´Ýð.ÝuڌDt"úa"\f3"So¯9D\vŒ9Ù9L¹¿«\\ŒP_Ÿ"uxéq‘h;Áěð<VqH‚\'UfYNe˜u£aF}a?A\0Ÿ×´4M·F°Õ¸Š\'{‹Ü+»Mg0ÈÑö\\Pú[/F›n5/\'C.ë\n\f^¥se4ål.jC\'c#U©?q{gC}:¯ÍâTUœýKÆâŸ/(íË\\Æ-fˆ§;/*"N°k.Ý\r•}}GºC²²+>Mª>}æÎI‰Ææx\fa1-¤O¥~q ˆì\r1èN\v\0nPh}=\b\r•¦n£h—$[kó#ó¶s³\r\v@ÀŸØQ]ú".jßI\0¹ wUÆïj¿{GLƒîÜÜF…©­S+S4ÿ”Yä8è1ƒN¹XFkË-#†’p\x005ˆ"Ï1²&/çÃu-6,rt°#G·ÓÑ&…7râ\0ŒDÏÚ3-Þ`†i#i*|ÍKQ\r•T9w.)ê¦P¢joP™\\>TûïP[\vE‰m(w7ێJfJo™ åpâ¹q~\fmI-zþrÇòY0»]såÉ êxì ðŠB|G`°½&·q¶ÇŸÑ3‚=Ó«îc™È+S D\\qÆÌD2O<ÊÀ)=RÓaX©}e´ÜÏ\rô=ñ\b©BÚ#\tØ¿^PIøMÀËGLO÷{+ØÅ1’;µoÜl\r’ˆўÛ?âéÚ_ԄâFaZÞUϤ\0¾ýÎgñJi—æ HØ]~®q N®ÀV©‘<‚rçvì)IÖ]-ƒãÛ6©;f—‡jÕ¶=P^R¹KÇsWxÉô.Y•“oÐKW>\'\'Ç`Û;íšSD>?’mw¢\në?R¨ÆU^1I7…ôÅ&-©¿‹\'TÚÃj å*x°Öprª‹h½ˆ÷_H±~ÀXL?fù>áeÀp§Ï8i¯ðVldIœ\'­xtO‡ÞV9\0Úw\vË-‰û5Oõ\bQ`Á\nZGM&30xÚÀœFGâ[y`In7gS\n>éìF9²ñ4\rƄSuná\fYÙÞ)…{II¥wy¾IV.6ç\v:»Ob{ÒM1•/½8{¨O!áìFpv•})"xˆ\nÝ\\ÚÞQÏðüYRe|3ßóHÚ»*uÛ`²Ôüíì5¨ÿ(1-È܈F|Š["');s(g.prototype,{url:{get:function(){return this._resource.url}},proxy:{get:function(){return this._resource.proxy}},resource:{get:function(){return this._resource}},readyPromise:{get:function(){return this._readyPromise}}}),g.tileXYToQuadKey=function(e,t,r){for(var i="",n=r;n>=0;--n){var o=1<<n,a=0;c(t,o)?c(e,o)&&(a|=1):(a|=2,c(e,o)||(a|=1)),i+=a}return i},g.quadKeyToTileXY=function(e){for(var t=0,r=0,i=e.length-1,n=i;n>=0;--n){var o=1<<n,a=+e[i-n];c(a,2)?c(a,1)||(t|=o):(r|=o,c(a,1)&&(t|=o))}return{x:t,y:r,level:i}},g.prototype.isValid=function(e){var t=this.getTileInformationFromQuadKey(e);if(a(t))return null!==t;for(var r,i=!0,n=e;n.length>1;){if(r=n.substring(n.length-1),n=n.substring(0,n.length-1),t=this.getTileInformationFromQuadKey(n),a(t)){t.hasSubtree()||t.hasChild(parseInt(r))||(i=!1);break}if(null===t){i=!1;break}}return i};var C=new m("decodeGoogleEarthEnterprisePacket",Number.POSITIVE_INFINITY);return g.prototype.getQuadTreePacket=function(e,t,r){t=o(t,1),e=o(e,"");var i=v(this,e,t,r),n=i.fetchArrayBuffer();if(a(n)){var s=this._tileInfo,l=this.key;return n.then(function(t){return C.scheduleTask({buffer:t,quadKey:e,type:"Metadata",key:l},[t]).then(function(t){var r,i=-1;if(""!==e){i=e.length+1;var n=t[e];r=s[e],r._bits|=n._bits,delete t[e]}var o=Object.keys(t);o.sort(function(e,t){return e.length-t.length});for(var a=o.length,l=0;l<a;++l){var c=o[l];if(null!==t[c]){var d=u.clone(t[c]),h=c.length;if(h===i)d.setParent(r);else if(h>1){var p=s[c.substring(0,c.length-1)];d.setParent(p)}s[c]=d}else s[c]=null}})})}},g.prototype.populateSubtree=function(e,t,r,i){return _(this,g.tileXYToQuadKey(e,t,r),i)},g.prototype.getTileInformation=function(e,t,r){var i=g.tileXYToQuadKey(e,t,r);return this._tileInfo[i]},g.prototype.getTileInformationFromQuadKey=function(e){return this._tileInfo[e]},g}),define("Core/GoogleEarthEnterpriseTerrainData",["./BoundingSphere","./Cartesian2","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./IndexDatatype","./Intersections2D","./Math","./OrientedBoundingBox","./QuantizedMeshTerrainData","./Rectangle","./TaskProcessor","./TerrainEncoding","./TerrainMesh"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){e=n(e,n.EMPTY_OBJECT),this._buffer=e.buffer,this._credits=e.credits,this._negativeAltitudeExponentBias=e.negativeAltitudeExponentBias,this._negativeElevationThreshold=e.negativeElevationThreshold;var t=n(e.childTileMask,15),r=3&t;r|=4&t?8:0,r|=8&t?4:0,this._childTileMask=r,this._createdByUpsampling=n(e.createdByUpsampling,!1),this._skirtHeight=void 0,this._bufferType=this._buffer.constructor,this._mesh=void 0,this._minimumHeight=void 0,this._maximumHeight=void 0,this._vertexCountWithoutSkirts=void 0,this._skirtIndex=void 0}function v(e,t,r){for(var i=e._mesh,n=i.vertices,o=i.encoding,a=i.indices,s=0,l=a.length;s<l;s+=3){var c=a[s],d=a[s+1],h=a[s+2],p=o.decodeTextureCoordinates(n,c,T),f=o.decodeTextureCoordinates(n,d,E),m=o.decodeTextureCoordinates(n,h,A),g=u.computeBarycentricCoordinates(t,r,p.x,p.y,f.x,f.y,m.x,m.y,x);if(g.x>=-1e-15&&g.y>=-1e-15&&g.z>=-1e-15){var _=o.decodeHeight(n,c),v=o.decodeHeight(n,d),y=o.decodeHeight(n,h);return g.x*_+g.y*v+g.z*y}}}function y(e,t,r,i){var n=e._buffer,o=0,a=0,s=0;r>.5?(t>.5?(o=2,a=.5):o=3,s=.5):t>.5&&(o=1,a=.5);for(var l=new DataView(n),d=0,h=0;h<o;++h)d+=l.getUint32(d,!0),d+=D;d+=D,d+=2*M;var p=c.toRadians(180*l.getFloat64(d,!0));d+=M;var f=c.toRadians(180*l.getFloat64(d,!0));d+=M;var m=i.width/p/2,g=i.height/f/2,_=l.getInt32(d,!0);d+=I;var v=3*l.getInt32(d,!0);d+=I,d+=I;var y,b=new Array(_),C=new Array(_),S=new Array(_);for(y=0;y<_;++y)b[y]=a+l.getUint8(d++)*m,C[y]=s+l.getUint8(d++)*g,S[y]=6371010*l.getFloat32(d,!0),d+=O;var w=new Array(v);for(y=0;y<v;++y)w[y]=l.getUint16(d,!0),d+=P;for(y=0;y<v;y+=3){var T=w[y],E=w[y+1],A=w[y+2],R=b[T],L=b[E],N=b[A],k=C[T],F=C[E],B=C[A],U=u.computeBarycentricCoordinates(t,r,R,k,L,F,N,B,x);if(U.x>=-1e-15&&U.y>=-1e-15&&U.z>=-1e-15)return U.x*S[T]+U.y*S[E]+U.z*S[A]}}a(_.prototype,{credits:{get:function(){return this._credits}},waterMask:{get:function(){}}});var b=new f("createVerticesFromGoogleEarthEnterpriseBuffer"),C=new p,S=new p;_.prototype.createMesh=function(e,t,r,i,a){var s=e.ellipsoid;e.tileXYToNativeRectangle(t,r,i,C),e.tileXYToRectangle(t,r,i,S),a=n(a,1);var l=s.cartographicToCartesian(p.center(S)),u=40075.16/(1<<i);this._skirtHeight=Math.min(8*u,1e3);var c=b.scheduleTask({buffer:this._buffer,nativeRectangle:C,rectangle:S,relativeToCenter:l,ellipsoid:s,skirtHeight:this._skirtHeight,exaggeration:a,includeWebMercatorT:!0,negativeAltitudeExponentBias:this._negativeAltitudeExponentBias,negativeElevationThreshold:this._negativeElevationThreshold});if(o(c)){var d=this;return c.then(function(e){return d._mesh=new g(l,new Float32Array(e.vertices),new Uint16Array(e.indices),e.minimumHeight,e.maximumHeight,e.boundingSphere3D,e.occludeePointInScaledSpace,e.numberOfAttributes,e.orientedBoundingBox,m.clone(e.encoding),a),d._vertexCountWithoutSkirts=e.vertexCountWithoutSkirts,d._skirtIndex=e.skirtIndex,d._minimumHeight=e.minimumHeight,d._maximumHeight=e.maximumHeight,d._buffer=void 0,d._mesh})}},_.prototype.interpolateHeight=function(e,t,r){var i=c.clamp((t-e.west)/e.width,0,1),n=c.clamp((r-e.south)/e.height,0,1);return o(this._mesh)?v(this,i,n):y(this,i,n,e)};var w=new f("upsampleQuantizedTerrainMesh");_.prototype.upsample=function(t,i,n,a,s,u,c){var p=this._mesh;if(o(this._mesh)){var f=2*i!==s,m=2*n===u,g=t.ellipsoid,_=t.tileXYToRectangle(s,u,c),v=w.scheduleTask({vertices:p.vertices,vertexCountWithoutSkirts:this._vertexCountWithoutSkirts,indices:p.indices,skirtIndex:this._skirtIndex,encoding:p.encoding,minimumHeight:this._minimumHeight,maximumHeight:this._maximumHeight,isEastChild:f,isNorthChild:m,childRectangle:_,ellipsoid:g,exaggeration:p.exaggeration});if(o(v)){var y=this;return v.then(function(t){var i=new Uint16Array(t.vertices),n=l.createTypedArray(i.length/3,t.indices),o=y._skirtHeight;return new h({quantizedVertices:i,indices:n,minimumHeight:t.minimumHeight,maximumHeight:t.maximumHeight,boundingSphere:e.clone(t.boundingSphere),orientedBoundingBox:d.clone(t.orientedBoundingBox),horizonOcclusionPoint:r.clone(t.horizonOcclusionPoint),westIndices:t.westIndices,southIndices:t.southIndices,eastIndices:t.eastIndices,northIndices:t.northIndices,westSkirtHeight:o,southSkirtHeight:o,eastSkirtHeight:o,northSkirtHeight:o,childTileMask:0,createdByUpsampling:!0,credits:y._credits})})}}},_.prototype.isChildAvailable=function(e,t,r,i){var n=2;return r!==2*e&&++n,i!==2*t&&(n-=2),0!=(this._childTileMask&1<<n)},_.prototype.wasCreatedByUpsampling=function(){return this._createdByUpsampling};var T=new t,E=new t,A=new t,x=new r,P=Uint16Array.BYTES_PER_ELEMENT,D=Uint32Array.BYTES_PER_ELEMENT,I=Int32Array.BYTES_PER_ELEMENT,O=Float32Array.BYTES_PER_ELEMENT,M=Float64Array.BYTES_PER_ELEMENT;return _}),define("Core/GoogleEarthEnterpriseTerrainProvider",["../ThirdParty/when","./Credit","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./Event","./GeographicTilingScheme","./GoogleEarthEnterpriseMetadata","./GoogleEarthEnterpriseTerrainData","./HeightmapTerrainData","./JulianDate","./Math","./Rectangle","./Request","./RequestState","./RequestType","./Resource","./RuntimeError","./TaskProcessor","./TileProviderError"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C){"use strict";function S(){this._terrainCache={},this._lastTidy=h.now()}function w(n){n=r(n,{}),i(n.proxy)&&o("GoogleEarthEnterpriseTerrainProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var a;if(i(n.metadata))a=n.metadata;else{var c=v.createIfNeeded(n.url,{proxy:n.proxy});a=new u(c)}this._metadata=a,this._tilingScheme=new l({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,rectangle:new f(-p.PI,-p.PI,p.PI,p.PI),ellipsoid:n.ellipsoid});var d=n.credit;"string"==typeof d&&(d=new t({text:d})),this._credit=d,this._levelZeroMaximumGeometricError=40075.16,this._terrainCache=new S,this._terrainPromises={}, +this._terrainRequests={},this._errorEvent=new s,this._ready=!1;var h,m=this;this._readyPromise=a.readyPromise.then(function(t){if(!a.terrainPresent){var r=new y("The server "+a.url+" doesn't have terrain");return h=C.handleError(h,m,m._errorEvent,r.message,void 0,void 0,void 0,r),e.reject(r)}return C.handleSuccess(h),m._ready=t,t}).otherwise(function(t){return h=C.handleError(h,m,m._errorEvent,t.message,void 0,void 0,void 0,t),e.reject(t)})}function T(e,t,r){var n=t.getChildBitmask();if(t.terrainState===A.PARENT){n=0;for(var o=0;o<4;++o){var a=r.getTileInformationFromQuadKey(e+o.toString());i(a)&&a.hasTerrain()&&(n|=1<<o)}}return n}function E(e,t,r,n){return r=i(r)&&r>0?r:1,e._metadata.resource.getDerivedResource({url:"flatfile?f1c-0"+t+"-t."+r.toString(),request:n})}var A={UNKNOWN:0,NONE:1,SELF:2,PARENT:3},x=new h;S.prototype.add=function(e,t){this._terrainCache[e]={buffer:t,timestamp:h.now()}},S.prototype.get=function(e){var t=this._terrainCache,r=t[e];if(i(r))return delete this._terrainCache[e],r.buffer},S.prototype.tidy=function(){if(h.now(x),h.secondsDifference(x,this._lastTidy)>10){for(var e=this._terrainCache,t=Object.keys(e),r=t.length,i=0;i<r;++i){var n=t[i],o=e[n];h.secondsDifference(x,o.timestamp)>10&&delete e[n]}h.clone(x,this._lastTidy)}},n(w.prototype,{url:{get:function(){return this._metadata.url}},proxy:{get:function(){return this._metadata.proxy}},tilingScheme:{get:function(){return this._tilingScheme}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasWaterMask:{get:function(){return!1}},hasVertexNormals:{get:function(){return!1}},availability:{get:function(){}}});var P=new b("decodeGoogleEarthEnterprisePacket",Number.POSITIVE_INFINITY);return w.prototype.requestTileGeometry=function(t,r,n,o){var a=u.tileXYToQuadKey(t,r,n),s=this._terrainCache,l=this._metadata,h=l.getTileInformationFromQuadKey(a);if(!i(h))return e.reject(new y("Terrain tile doesn't exist"));var p=h.terrainState;i(p)||(p=h.terrainState=A.UNKNOWN);var f=s.get(a);if(i(f)){var m=l.providers[h.terrainProvider];return new c({buffer:f,childTileMask:T(a,h,l),credits:i(m)?[m]:void 0,negativeAltitudeExponentBias:l.negativeAltitudeExponentBias,negativeElevationThreshold:l.negativeAltitudeThreshold})}if(s.tidy(),!h.ancestorHasTerrain)return new d({buffer:new Uint8Array(256),width:16,height:16});if(p===A.NONE)return e.reject(new y("Terrain tile doesn't exist"));var _,v=a,b=-1;switch(p){case A.SELF:b=h.terrainVersion;break;case A.PARENT:v=v.substring(0,v.length-1),_=l.getTileInformationFromQuadKey(v),b=_.terrainVersion;break;case A.UNKNOWN:h.hasTerrain()?b=h.terrainVersion:(v=v.substring(0,v.length-1),_=l.getTileInformationFromQuadKey(v),i(_)&&_.hasTerrain()&&(b=_.terrainVersion))}if(b<0)return e.reject(new y("Terrain tile doesn't exist"));var C,S,w=this._terrainPromises,x=this._terrainRequests;if(i(w[v]))C=w[v],S=x[v];else{S=o;var D=E(this,v,b,S).fetchArrayBuffer();if(!i(D))return;C=D.then(function(t){return i(t)?P.scheduleTask({buffer:t,type:"Terrain",key:l.key},[t]).then(function(e){var t=l.getTileInformationFromQuadKey(v);t.terrainState=A.SELF,s.add(v,e[0]);for(var r=t.terrainProvider,n=e.length-1,o=0;o<n;++o){var a=v+o.toString(),u=l.getTileInformationFromQuadKey(a);i(u)&&(s.add(a,e[o+1]),u.terrainState=A.PARENT,0===u.terrainProvider&&(u.terrainProvider=r))}}):e.reject(new y("Failed to load terrain."))}),w[v]=C,x[v]=S,C=C.always(function(){delete w[v],delete x[v]})}return C.then(function(){var t=s.get(a);if(i(t)){var r=l.providers[h.terrainProvider];return new c({buffer:t,childTileMask:T(a,h,l),credits:i(r)?[r]:void 0,negativeAltitudeExponentBias:l.negativeAltitudeExponentBias,negativeElevationThreshold:l.negativeAltitudeThreshold})}return e.reject(new y("Failed to load terrain."))}).otherwise(function(t){return S.state===g.CANCELLED?(o.state=S.state,e.reject(t)):(h.terrainState=A.NONE,e.reject(t))})},w.prototype.getLevelMaximumGeometricError=function(e){return this._levelZeroMaximumGeometricError/(1<<e)},w.prototype.getTileDataAvailable=function(e,t,r){var n=this._metadata,o=u.tileXYToQuadKey(e,t,r),a=n.getTileInformation(e,t,r);if(null===a)return!1;if(i(a)){if(!a.ancestorHasTerrain)return!0;var s=a.terrainState;if(s===A.NONE)return!1;if(!(i(s)&&s!==A.UNKNOWN||(a.terrainState=A.UNKNOWN,a.hasTerrain()))){o=o.substring(0,o.length-1);var l=n.getTileInformationFromQuadKey(o);if(!i(l)||!l.hasTerrain())return!1}return!0}if(n.isValid(o)){var c=new m({throttle:!0,throttleByServer:!0,type:_.TERRAIN});n.populateSubtree(e,t,r,c)}return!1},w}),define("Core/HeadingPitchRange",["./defaultValue","./defined"],function(e,t){"use strict";function r(t,r,i){this.heading=e(t,0),this.pitch=e(r,0),this.range=e(i,0)}return r.clone=function(e,i){if(t(e))return t(i)||(i=new r),i.heading=e.heading,i.pitch=e.pitch,i.range=e.range,i},r}),define("Core/HeadingPitchRoll",["./defaultValue","./defined","./DeveloperError","./Math"],function(e,t,r,i){"use strict";function n(t,r,i){this.heading=e(t,0),this.pitch=e(r,0),this.roll=e(i,0)}return n.fromQuaternion=function(e,r){t(r)||(r=new n);var i=2*(e.w*e.y-e.z*e.x),o=1-2*(e.x*e.x+e.y*e.y),a=2*(e.w*e.x+e.y*e.z),s=1-2*(e.y*e.y+e.z*e.z),l=2*(e.w*e.z+e.x*e.y);return r.heading=-Math.atan2(l,s),r.roll=Math.atan2(a,o),r.pitch=-Math.asin(i),r},n.fromDegrees=function(e,r,o,a){return t(a)||(a=new n),a.heading=e*i.RADIANS_PER_DEGREE,a.pitch=r*i.RADIANS_PER_DEGREE,a.roll=o*i.RADIANS_PER_DEGREE,a},n.clone=function(e,r){if(t(e))return t(r)?(r.heading=e.heading,r.pitch=e.pitch,r.roll=e.roll,r):new n(e.heading,e.pitch,e.roll)},n.equals=function(e,r){return e===r||t(e)&&t(r)&&e.heading===r.heading&&e.pitch===r.pitch&&e.roll===r.roll},n.equalsEpsilon=function(e,r,n,o){return e===r||t(e)&&t(r)&&i.equalsEpsilon(e.heading,r.heading,n,o)&&i.equalsEpsilon(e.pitch,r.pitch,n,o)&&i.equalsEpsilon(e.roll,r.roll,n,o)},n.prototype.clone=function(e){return n.clone(this,e)},n.prototype.equals=function(e){return n.equals(this,e)},n.prototype.equalsEpsilon=function(e,t,r){return n.equalsEpsilon(this,e,t,r)},n.prototype.toString=function(){return"("+this.heading+", "+this.pitch+", "+this.roll+")"},n}),define("Core/HermitePolynomialApproximation",["./defaultValue","./defined","./DeveloperError","./Math"],function(e,t,r,i){"use strict";function n(e,t,r,i,o,a){var s,l,u,c=0;if(i>0){for(l=0;l<o;l++){for(s=!1,u=0;u<a.length&&!s;u++)l===a[u]&&(s=!0);s||(a.push(l),c+=n(e,t,r,i-1,o,a),a.splice(a.length-1,1))}return c}for(c=1,l=0;l<o;l++){for(s=!1,u=0;u<a.length&&!s;u++)l===a[u]&&(s=!0);s||(c*=e-r[t[l]])}return c}function o(e,t,r,n,o,a){for(var s,l,u=-1,c=t.length,d=c*(c+1)/2,h=0;h<o;h++){var p=Math.floor(h*d);for(s=0;s<c;s++)l=t[s]*o*(a+1)+h,e[p+s]=n[l];for(var f=1;f<c;f++){var m=0,g=Math.floor(f*(1-f)/2)+c*f,_=!1;for(s=0;s<c-f;s++){var v,y,b=r[t[s]],C=r[t[s+f]];if(C-b<=0)l=t[s]*o*(a+1)+o*f+h,v=n[l],y=v/i.factorial(f),e[p+g+m]=y,m++;else{var S=Math.floor((f-1)*(2-f)/2)+c*(f-1);v=e[p+S+s+1]-e[p+S+s],y=v/(C-b),e[p+g+m]=y,m++}_=_||0!==v}_&&(u=Math.max(u,f))}}return u}var a=i.factorial,s={type:"Hermite"};s.getRequiredDataPoints=function(t,r){return r=e(r,0),Math.max(Math.floor((t+1)/(r+1)),2)},s.interpolateOrderZero=function(e,r,i,o,s){t(s)||(s=new Array(o));var l,u,c,d,h,p,f=r.length,m=new Array(o);for(l=0;l<o;l++){s[l]=0;var g=new Array(f);for(m[l]=g,u=0;u<f;u++)g[u]=[]}var _=f,v=new Array(_);for(l=0;l<_;l++)v[l]=l;var y=f-1;for(d=0;d<o;d++){for(u=0;u<_;u++)p=v[u]*o+d,m[d][0].push(i[p]);for(l=1;l<_;l++){var b=!1;for(u=0;u<_-l;u++){var C,S=r[v[u]],w=r[v[u+l]];w-S<=0?(p=v[u]*o+o*l+d,C=i[p],m[d][l].push(C/a(l))):(C=m[d][l-1][u+1]-m[d][l-1][u],m[d][l].push(C/(w-S))),b=b||0!==C}b||(y=l-1)}}for(c=0,h=0;c<=h;c++)for(l=c;l<=y;l++){var T=n(e,v,r,c,l,[]);for(d=0;d<o;d++){var E=m[d][l][0];s[d+c*o]+=E*T}}return s};var l=[];return s.interpolate=function(e,r,i,a,s,u,c){var d=a*(u+1);t(c)||(c=new Array(d));for(var h=0;h<d;h++)c[h]=0;var p,f=r.length,m=new Array(f*(s+1));for(p=0;p<f;p++)for(var g=0;g<s+1;g++)m[p*(s+1)+g]=p;for(var _=m.length,v=l,y=o(v,m,r,i,a,s),b=[],C=_*(_+1)/2,S=Math.min(y,u),w=0;w<=S;w++)for(p=w;p<=y;p++){b.length=0;for(var T=n(e,m,r,w,p,b),E=Math.floor(p*(1-p)/2)+_*p,A=0;A<a;A++){var x=Math.floor(A*C),P=v[x+E];c[A+w*a]+=P*T}}return c},s}),define("Core/IauOrientationParameters",[],function(){"use strict";function e(e,t,r,i){this.rightAscension=e,this.declination=t,this.rotation=r,this.rotationRate=i}return e}),define("Core/Iau2000Orientation",["./defined","./IauOrientationParameters","./JulianDate","./Math","./TimeConstants"],function(e,t,r,i,n){"use strict";var o={},a=-.0529921,s=-.1059842,l=13.0120009,u=13.3407154,c=26.4057084,d=13.064993,h=1.7484877,p=new r;return o.ComputeMoon=function(o,f){e(o)||(o=r.now()),p=r.addSeconds(o,32.184,p);var m=r.totalDays(p)-2451545,g=m/n.DAYS_PER_JULIAN_CENTURY,_=(125.045+a*m)*i.RADIANS_PER_DEGREE,v=(250.089+s*m)*i.RADIANS_PER_DEGREE,y=(260.008+l*m)*i.RADIANS_PER_DEGREE,b=(176.625+u*m)*i.RADIANS_PER_DEGREE,C=(357.529+.9856003*m)*i.RADIANS_PER_DEGREE,S=(311.589+c*m)*i.RADIANS_PER_DEGREE,w=(134.963+d*m)*i.RADIANS_PER_DEGREE,T=(276.617+.3287146*m)*i.RADIANS_PER_DEGREE,E=(34.226+h*m)*i.RADIANS_PER_DEGREE,A=(15.134+-.1589763*m)*i.RADIANS_PER_DEGREE,x=(119.743+.0036096*m)*i.RADIANS_PER_DEGREE,P=(239.961+.1643573*m)*i.RADIANS_PER_DEGREE,D=(25.053+12.9590088*m)*i.RADIANS_PER_DEGREE,I=Math.sin(_),O=Math.sin(v),M=Math.sin(y),R=Math.sin(b),L=Math.sin(C),N=Math.sin(S),k=Math.sin(w),F=Math.sin(T),B=Math.sin(E),U=Math.sin(A),V=Math.sin(x),z=Math.sin(P),G=Math.sin(D),W=Math.cos(_),H=Math.cos(v),j=Math.cos(y),q=Math.cos(b),Y=Math.cos(C),X=Math.cos(S),Q=Math.cos(w),Z=Math.cos(T),K=Math.cos(E),J=Math.cos(A),$=Math.cos(x),ee=Math.cos(P),te=Math.cos(D),re=(269.9949+.0031*g-3.8787*I-.1204*O+.07*M-.0172*R+.0072*N-.0052*U+.0043*G)*i.RADIANS_PER_DEGREE,ie=(66.5392+.013*g+1.5419*W+.0239*H-.0278*j+.0068*q-.0029*X+9e-4*Q+8e-4*J-9e-4*te)*i.RADIANS_PER_DEGREE,ne=(38.3213+13.17635815*m-1.4e-12*m*m+3.561*I+.1208*O-.0642*M+.0158*R+.0252*L-.0066*N-.0047*k-.0046*F+.0028*B+.0052*U+.004*V+.0019*z-.0044*G)*i.RADIANS_PER_DEGREE,oe=(13.17635815-2*m*1.4e-12+3.561*W*a+.1208*H*s-.0642*j*l+.0158*q*u+.0252*Y*.9856003-.0066*X*c-.0047*Q*d-.0046*Z*.3287146+.0028*K*h+.0052*J*-.1589763+.004*$*.0036096+.0019*ee*.1643573-.0044*te*12.9590088)/86400*i.RADIANS_PER_DEGREE;return e(f)||(f=new t),f.rightAscension=re,f.declination=ie,f.rotation=ne,f.rotationRate=oe,f},o}),define("Core/IauOrientationAxes",["./Cartesian3","./defined","./Iau2000Orientation","./JulianDate","./Math","./Matrix3","./Quaternion"],function(e,t,r,i,n,o,a){"use strict";function s(e){t(e)&&"function"==typeof e||(e=r.ComputeMoon),this._computeFunction=e}function l(r,i,a){var s=u;s.x=Math.cos(r+n.PI_OVER_TWO),s.y=Math.sin(r+n.PI_OVER_TWO),s.z=0;var l=Math.cos(i),h=d;h.x=l*Math.cos(r),h.y=l*Math.sin(r),h.z=Math.sin(i);var p=e.cross(h,s,c);return t(a)||(a=new o),a[0]=s.x,a[1]=p.x,a[2]=h.x,a[3]=s.y,a[4]=p.y,a[5]=h.y,a[6]=s.z,a[7]=p.z,a[8]=h.z,a}var u=new e,c=new e,d=new e,h=new o,p=new a;return s.prototype.evaluate=function(r,s){t(r)||(r=i.now());var u=this._computeFunction(r),c=l(u.rightAscension,u.declination,s),d=n.zeroToTwoPi(u.rotation),f=a.fromAxisAngle(e.UNIT_Z,d,p),m=o.fromQuaternion(a.conjugate(f,f),h);return o.multiply(m,c,c)},s}),define("Core/InterpolationAlgorithm",["./DeveloperError"],function(e){"use strict";var t={};return t.type=void 0,t.getRequiredDataPoints=e.throwInstantiationError,t.interpolateOrderZero=e.throwInstantiationError,t.interpolate=e.throwInstantiationError,t}),define("Core/TimeInterval",["./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./JulianDate"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.start=r(e.start)?o.clone(e.start):new o,this.stop=r(e.stop)?o.clone(e.stop):new o,this.data=e.data,this.isStartIncluded=t(e.isStartIncluded,!0),this.isStopIncluded=t(e.isStopIncluded,!0)}i(a.prototype,{isEmpty:{get:function(){var e=o.compare(this.stop,this.start);return e<0||0===e&&(!this.isStartIncluded||!this.isStopIncluded)}}});var s={start:void 0,stop:void 0,isStartIncluded:void 0,isStopIncluded:void 0,data:void 0};return a.fromIso8601=function(e,i){var n=e.iso8601.split("/"),l=o.fromIso8601(n[0]),u=o.fromIso8601(n[1]),c=t(e.isStartIncluded,!0),d=t(e.isStopIncluded,!0),h=e.data;return r(i)?(i.start=l,i.stop=u,i.isStartIncluded=c,i.isStopIncluded=d,i.data=h,i):(s.start=l,s.stop=u,s.isStartIncluded=c,s.isStopIncluded=d,s.data=h,new a(s))},a.toIso8601=function(e,t){return o.toIso8601(e.start,t)+"/"+o.toIso8601(e.stop,t)},a.clone=function(e,t){if(r(e))return r(t)?(t.start=e.start,t.stop=e.stop,t.isStartIncluded=e.isStartIncluded,t.isStopIncluded=e.isStopIncluded,t.data=e.data,t):new a(e)},a.equals=function(e,t,i){return e===t||r(e)&&r(t)&&(e.isEmpty&&t.isEmpty||e.isStartIncluded===t.isStartIncluded&&e.isStopIncluded===t.isStopIncluded&&o.equals(e.start,t.start)&&o.equals(e.stop,t.stop)&&(e.data===t.data||r(i)&&i(e.data,t.data)))},a.equalsEpsilon=function(e,t,i,n){return e===t||r(e)&&r(t)&&(e.isEmpty&&t.isEmpty||e.isStartIncluded===t.isStartIncluded&&e.isStopIncluded===t.isStopIncluded&&o.equalsEpsilon(e.start,t.start,i)&&o.equalsEpsilon(e.stop,t.stop,i)&&(e.data===t.data||r(n)&&n(e.data,t.data)))},a.intersect=function(e,t,i,n){if(!r(t))return a.clone(a.EMPTY,i);var s=e.start,l=e.stop,u=t.start,c=t.stop,d=o.greaterThanOrEquals(u,s)&&o.greaterThanOrEquals(l,u),h=!d&&o.lessThanOrEquals(u,s)&&o.lessThanOrEquals(s,c);if(!d&&!h)return a.clone(a.EMPTY,i);var p=e.isStartIncluded,f=e.isStopIncluded,m=t.isStartIncluded,g=t.isStopIncluded,_=o.lessThan(l,c);return i.start=d?u:s,i.isStartIncluded=p&&m||!o.equals(u,s)&&(d&&m||h&&p),i.stop=_?l:c,i.isStopIncluded=_?f:f&&g||!o.equals(c,l)&&g,i.data=r(n)?n(e.data,t.data):e.data,i},a.contains=function(e,t){if(e.isEmpty)return!1;var r=o.compare(e.start,t);if(0===r)return e.isStartIncluded;var i=o.compare(t,e.stop);return 0===i?e.isStopIncluded:r<0&&i<0},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.equals=function(e,t){return a.equals(this,e,t)},a.prototype.equalsEpsilon=function(e,t,r){return a.equalsEpsilon(this,e,t,r)},a.prototype.toString=function(){return a.toIso8601(this)},a.EMPTY=n(new a({start:new o,stop:new o,isStartIncluded:!1,isStopIncluded:!1})),a}),define("Core/Iso8601",["./freezeObject","./JulianDate","./TimeInterval"],function(e,t,r){"use strict";var i=e(t.fromIso8601("0000-01-01T00:00:00Z")),n=e(t.fromIso8601("9999-12-31T24:00:00Z"));return{MINIMUM_VALUE:i,MAXIMUM_VALUE:n,MAXIMUM_INTERVAL:e(new r({start:i,stop:n}))}}),define("Core/KeyboardEventModifier",["./freezeObject"],function(e){"use strict";return e({SHIFT:0,CTRL:1,ALT:2})}),define("Core/LagrangePolynomialApproximation",["./defined"],function(e){"use strict";var t={type:"Lagrange"};return t.getRequiredDataPoints=function(e){return Math.max(e+1,2)},t.interpolateOrderZero=function(t,r,i,n,o){e(o)||(o=new Array(n));var a,s,l=r.length;for(a=0;a<n;a++)o[a]=0;for(a=0;a<l;a++){var u=1;for(s=0;s<l;s++)if(s!==a){var c=r[a]-r[s];u*=(t-r[s])/c}for(s=0;s<n;s++)o[s]+=u*i[a*n+s]}return o},t}),define("Core/LinearApproximation",["./defined","./DeveloperError"],function(e,t){"use strict";var r={type:"Linear"};return r.getRequiredDataPoints=function(e){return 2},r.interpolateOrderZero=function(t,r,i,n,o){e(o)||(o=new Array(n));var a,s,l,u=r[0],c=r[1];for(a=0;a<n;a++)s=i[a],l=i[a+n],o[a]=((l-s)*t+c*s-u*l)/(c-u);return o},r}),define("Core/loadArrayBuffer",["./Check","./defined","./deprecationWarning","./Resource"],function(e,t,r,i){"use strict";function n(e,t,n){return r("loadArrayBuffer","loadArrayBuffer is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchArrayBuffer instead."),i.createIfNeeded(e,{headers:t,request:n}).fetchArrayBuffer()}return n}),define("Core/loadBlob",["./Check","./defined","./deprecationWarning","./Resource"],function(e,t,r,i){"use strict";function n(e,t,n){return r("loadBlob","loadBlob is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchBlob instead."),i.createIfNeeded(e,{headers:t,request:n}).fetchBlob()}return n}),define("Core/loadCRN",["../ThirdParty/when","./CompressedTextureBuffer","./defined","./deprecationWarning","./DeveloperError","./Resource","./TaskProcessor"],function(e,t,r,i,n,o,a){"use strict";function s(n,a,s){r(a)&&i("loadCRN.headers","The headers parameter has been deprecated. Set the headers property on the Resource parameter."),r(s)&&i("loadCRN.request","The request parameter has been deprecated. Set the request property on the Resource parameter.");var u;if(n instanceof ArrayBuffer||ArrayBuffer.isView(n))u=e.resolve(n);else{u=o.createIfNeeded(n,{headers:a,request:s}).fetchArrayBuffer()}if(r(u))return u.then(function(e){if(r(e)){var t=[];return e instanceof ArrayBuffer?t.push(e):0===e.byteOffset&&e.byteLength===e.buffer.byteLength?t.push(e.buffer):(e=e.slice(0,e.length),t.push(e.buffer)),l.scheduleTask(e,t)}}).then(function(e){return t.clone(e)})}var l=new a("transcodeCRNToDXT",Number.POSITIVE_INFINITY);return s}),define("Core/loadImage",["./Check","./defined","./defineProperties","./deprecationWarning","./Resource"],function(e,t,r,i,n){"use strict";function o(e,t,r){return i("loadImage","loadImage is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchImage instead."),n.createIfNeeded(e,{request:r}).fetchImage(!1,t)}return r(o,{createImage:{get:function(){return n._Implementations.createImage},set:function(e){n._Implementations.createImage=e}},defaultCreateImage:{get:function(){return n._DefaultImplementations.createImage}}}),o}),define("Core/loadImageFromTypedArray",["../ThirdParty/when","./Check","./Resource"],function(e,t,r){"use strict";function i(t,i,n){var o=new Blob([t],{type:i}),a=window.URL.createObjectURL(o);return new r({url:a,request:n}).fetchImage().then(function(e){return window.URL.revokeObjectURL(a),e},function(t){return window.URL.revokeObjectURL(a),e.reject(t)})}return i});define("Core/loadImageViaBlob",["./Check","./defined","./deprecationWarning","./Resource"],function(e,t,r,i){"use strict";function n(e,t){return r("loadImageViaBlob","loadImageViaBlob is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchImage instead."),i.createIfNeeded(e,{request:t}).fetchImage(!0)}return n}),define("Core/loadJson",["./clone","./defined","./deprecationWarning","./DeveloperError","./Resource"],function(e,t,r,i,n){"use strict";function o(e,t,i){return r("loadJson","loadJson is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchJson instead."),n.createIfNeeded(e,{headers:t,request:i}).fetchJson()}return o}),define("Core/loadJsonp",["./clone","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./Resource"],function(e,t,r,i,n,o){"use strict";function a(r,n,a){i("loadJsonp","loadJsonp is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchJsonp instead.");var s,l;if("object"==typeof n){var u=n;t(u.parameters)&&(l=e(u.parameters)),t(u.proxy)&&(s=u.proxy),n=u.callbackParameterName}return o.createIfNeeded(r,{proxy:s,queryParameters:l,request:a}).fetchJsonp(n)}return r(a,{loadAndExecuteScript:{get:function(){return o._Implementations.loadAndExecuteScript},set:function(e){o._Implementations.loadAndExecuteScript=e}},defaultLoadAndExecuteScript:{get:function(){return o._DefaultImplementations.loadAndExecuteScript}}}),a}),define("Renderer/PixelDatatype",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={UNSIGNED_BYTE:t.UNSIGNED_BYTE,UNSIGNED_SHORT:t.UNSIGNED_SHORT,UNSIGNED_INT:t.UNSIGNED_INT,FLOAT:t.FLOAT,UNSIGNED_INT_24_8:t.UNSIGNED_INT_24_8,UNSIGNED_SHORT_4_4_4_4:t.UNSIGNED_SHORT_4_4_4_4,UNSIGNED_SHORT_5_5_5_1:t.UNSIGNED_SHORT_5_5_5_1,UNSIGNED_SHORT_5_6_5:t.UNSIGNED_SHORT_5_6_5,isPacked:function(e){return e===r.UNSIGNED_INT_24_8||e===r.UNSIGNED_SHORT_4_4_4_4||e===r.UNSIGNED_SHORT_5_5_5_1||e===r.UNSIGNED_SHORT_5_6_5},sizeInBytes:function(e){switch(e){case r.UNSIGNED_BYTE:return 1;case r.UNSIGNED_SHORT:case r.UNSIGNED_SHORT_4_4_4_4:case r.UNSIGNED_SHORT_5_5_5_1:case r.UNSIGNED_SHORT_5_6_5:return 2;case r.UNSIGNED_INT:case r.FLOAT:case r.UNSIGNED_INT_24_8:return 4}},validate:function(e){return e===r.UNSIGNED_BYTE||e===r.UNSIGNED_SHORT||e===r.UNSIGNED_INT||e===r.FLOAT||e===r.UNSIGNED_INT_24_8||e===r.UNSIGNED_SHORT_4_4_4_4||e===r.UNSIGNED_SHORT_5_5_5_1||e===r.UNSIGNED_SHORT_5_6_5}};return e(r)}),define("Core/PixelFormat",["../Renderer/PixelDatatype","./freezeObject","./WebGLConstants"],function(e,t,r){"use strict";var i={DEPTH_COMPONENT:r.DEPTH_COMPONENT,DEPTH_STENCIL:r.DEPTH_STENCIL,ALPHA:r.ALPHA,RGB:r.RGB,RGBA:r.RGBA,LUMINANCE:r.LUMINANCE,LUMINANCE_ALPHA:r.LUMINANCE_ALPHA,RGB_DXT1:r.COMPRESSED_RGB_S3TC_DXT1_EXT,RGBA_DXT1:r.COMPRESSED_RGBA_S3TC_DXT1_EXT,RGBA_DXT3:r.COMPRESSED_RGBA_S3TC_DXT3_EXT,RGBA_DXT5:r.COMPRESSED_RGBA_S3TC_DXT5_EXT,RGB_PVRTC_4BPPV1:r.COMPRESSED_RGB_PVRTC_4BPPV1_IMG,RGB_PVRTC_2BPPV1:r.COMPRESSED_RGB_PVRTC_2BPPV1_IMG,RGBA_PVRTC_4BPPV1:r.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,RGBA_PVRTC_2BPPV1:r.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,RGB_ETC1:r.COMPRESSED_RGB_ETC1_WEBGL,componentsLength:function(e){switch(e){case i.RGB:case i.RGBA:return 4;case i.LUMINANCE_ALPHA:return 2;case i.ALPHA:case i.LUMINANCE:default:return 1}},validate:function(e){return e===i.DEPTH_COMPONENT||e===i.DEPTH_STENCIL||e===i.ALPHA||e===i.RGB||e===i.RGBA||e===i.LUMINANCE||e===i.LUMINANCE_ALPHA||e===i.RGB_DXT1||e===i.RGBA_DXT1||e===i.RGBA_DXT3||e===i.RGBA_DXT5||e===i.RGB_PVRTC_4BPPV1||e===i.RGB_PVRTC_2BPPV1||e===i.RGBA_PVRTC_4BPPV1||e===i.RGBA_PVRTC_2BPPV1||e===i.RGB_ETC1},isColorFormat:function(e){return e===i.ALPHA||e===i.RGB||e===i.RGBA||e===i.LUMINANCE||e===i.LUMINANCE_ALPHA},isDepthFormat:function(e){return e===i.DEPTH_COMPONENT||e===i.DEPTH_STENCIL},isCompressedFormat:function(e){return e===i.RGB_DXT1||e===i.RGBA_DXT1||e===i.RGBA_DXT3||e===i.RGBA_DXT5||e===i.RGB_PVRTC_4BPPV1||e===i.RGB_PVRTC_2BPPV1||e===i.RGBA_PVRTC_4BPPV1||e===i.RGBA_PVRTC_2BPPV1||e===i.RGB_ETC1},isDXTFormat:function(e){return e===i.RGB_DXT1||e===i.RGBA_DXT1||e===i.RGBA_DXT3||e===i.RGBA_DXT5},isPVRTCFormat:function(e){return e===i.RGB_PVRTC_4BPPV1||e===i.RGB_PVRTC_2BPPV1||e===i.RGBA_PVRTC_4BPPV1||e===i.RGBA_PVRTC_2BPPV1},isETC1Format:function(e){return e===i.RGB_ETC1},compressedTextureSizeInBytes:function(e,t,r){switch(e){case i.RGB_DXT1:case i.RGBA_DXT1:case i.RGB_ETC1:return Math.floor((t+3)/4)*Math.floor((r+3)/4)*8;case i.RGBA_DXT3:case i.RGBA_DXT5:return Math.floor((t+3)/4)*Math.floor((r+3)/4)*16;case i.RGB_PVRTC_4BPPV1:case i.RGBA_PVRTC_4BPPV1:return Math.floor((Math.max(t,8)*Math.max(r,8)*4+7)/8);case i.RGB_PVRTC_2BPPV1:case i.RGBA_PVRTC_2BPPV1:return Math.floor((Math.max(t,16)*Math.max(r,8)*2+7)/8);default:return 0}},textureSizeInBytes:function(t,r,n,o){var a=i.componentsLength(t);return e.isPacked(r)&&(a=1),a*e.sizeInBytes(r)*n*o}};return t(i)}),define("Core/loadKTX",["../ThirdParty/when","./Check","./CompressedTextureBuffer","./defined","./deprecationWarning","./PixelFormat","./Resource","./RuntimeError"],function(e,t,r,i,n,o,a,s){"use strict";function l(t,r,o){i(r)&&n("loadCRN.headers","The headers parameter has been deprecated. Set the headers property on the Resource parameter."),i(o)&&n("loadCRN.request","The request parameter has been deprecated. Set the request property on the Resource parameter.");var s;if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))s=e.resolve(t);else{s=a.createIfNeeded(t,{headers:r,request:o}).fetchArrayBuffer()}if(i(s))return s.then(function(e){if(i(e))return u(e)})}function u(e){for(var t=new Uint8Array(e),n=!0,a=0;a<c.length;++a)if(c[a]!==t[a]){n=!1;break}if(!n)throw new s("Invalid KTX file.");var l,u;i(e.buffer)?(l=new DataView(e.buffer),u=e.byteOffset):(l=new DataView(e),u=0),u+=12;var p=l.getUint32(u,!0);if(u+=h,p!==d)throw new s("File is the wrong endianness.");var f=l.getUint32(u,!0);u+=h;var m=l.getUint32(u,!0);u+=h;var g=l.getUint32(u,!0);u+=h;var _=l.getUint32(u,!0);u+=h;var v=l.getUint32(u,!0);u+=h;var y=l.getUint32(u,!0);u+=h;var b=l.getUint32(u,!0);u+=h;var C=l.getUint32(u,!0);u+=h;var S=l.getUint32(u,!0);u+=h;var w=l.getUint32(u,!0);u+=h;var T=l.getUint32(u,!0);u+=h;var E=l.getUint32(u,!0);u+=h,u+=E;var A=l.getUint32(u,!0);u+=h;var x;if(x=i(e.buffer)?new Uint8Array(e.buffer,u,A):new Uint8Array(e,u,A),32849===_?_=o.RGB:32856===_&&(_=o.RGBA),!o.validate(_))throw new s("glInternalFormat is not a valid format.");if(o.isCompressedFormat(_)){if(0!==f)throw new s("glType must be zero when the texture is compressed.");if(1!==m)throw new s("The type size for compressed textures must be 1.");if(0!==g)throw new s("glFormat must be zero when the texture is compressed.")}else if(v!==g)throw new s("The base internal format must be the same as the format for uncompressed textures.");if(0!==C)throw new s("3D textures are unsupported.");if(0!==S)throw new s("Texture arrays are unsupported.");if(1!==w)throw new s("Cubemaps are unsupported.");if(T>1){var P=o.isCompressedFormat(_)?o.compressedTextureSizeInBytes(_,y,b):o.textureSizeInBytes(_,y,b);x=new Uint8Array(x.buffer,x.byteOffset,P)}return new r(_,y,b,x)}var c=[171,75,84,88,32,49,49,187,13,10,26,10],d=67305985,h=4;return l}),define("Core/loadText",["./Check","./defined","./deprecationWarning","./Resource"],function(e,t,r,i){"use strict";function n(e,t,n){return r("loadText","loadText is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchText instead."),i.createIfNeeded(e,{headers:t,request:n}).fetchText()}return n}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defineProperties","./deprecationWarning","./Resource"],function(e,t,r,i,n){"use strict";function o(e){return i("loadWithXhr","loadWithXhr is deprecated and will be removed in Cesium 1.44. Please use Resource.fetch instead."),new n(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})}return r(o,{load:{get:function(){return n._Implementations.loadWithXhr},set:function(e){n._Implementations.loadWithXhr=e}},defaultLoad:{get:function(){return n._DefaultImplementations.loadWithXhr}}}),o}),define("Core/loadXML",["./Check","./defined","./deprecationWarning","./Resource"],function(e,t,r,i){"use strict";function n(e,t,n){return r("loadXML","loadXML is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchXML instead."),i.createIfNeeded(e,{headers:t,request:n}).fetchXML()}return n}),define("Core/ManagedArray",["./Check","./defaultValue","./defineProperties"],function(e,t,r){"use strict";function i(e){e=t(e,0),this._array=new Array(e),this._length=e}return r(i.prototype,{length:{get:function(){return this._length},set:function(e){this._length=e,e>this._array.length&&(this._array.length=e)}},values:{get:function(){return this._array}}}),i.prototype.get=function(e){return this._array[e]},i.prototype.set=function(e,t){e>=this.length&&(this.length=e+1),this._array[e]=t},i.prototype.push=function(e){var t=this.length++;this._array[t]=e},i.prototype.pop=function(){return this._array[--this.length]},i.prototype.reserve=function(e){e>this._array.length&&(this._array.length=e)},i.prototype.resize=function(e){this.length=e},i.prototype.trim=function(e){e=t(e,this.length),this._array.length=e},i}),define("Core/MapboxApi",["./Credit","./defined"],function(e,t){"use strict";var r={};r.defaultAccessToken=void 0;var i,n=!1,o="This application is using Cesium's default Mapbox access token. Please create a new access token for the application as soon as possible and prior to deployment by visiting https://www.mapbox.com/account/apps/, and provide your token to Cesium by setting the Cesium.MapboxApi.defaultAccessToken property before constructing the CesiumWidget or any other object that uses the Mapbox API.";return r.getAccessToken=function(e){return t(e)?e:t(r.defaultAccessToken)?r.defaultAccessToken:(n||(console.log(o),n=!0),"pk.eyJ1IjoiYW5hbHl0aWNhbGdyYXBoaWNzIiwiYSI6ImNpd204Zm4wejAwNzYyeW5uNjYyZmFwdWEifQ.7i-VIZZWX8pd1bTfxIVj9g")},r.getErrorCredit=function(n){if(!t(n)&&!t(r.defaultAccessToken))return t(i)||(i=new e({text:o,showOnScreen:!0})),i},r}),define("Core/MapProjection",["./defineProperties","./DeveloperError"],function(e,t){"use strict";function r(){t.throwInstantiationError()}return e(r.prototype,{ellipsoid:{get:t.throwInstantiationError}}),r.prototype.project=t.throwInstantiationError,r.prototype.unproject=t.throwInstantiationError,r}),define("Core/Matrix2",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./freezeObject"],function(e,t,r,i,n,o){"use strict";function a(e,t,i,n){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(t,0),this[3]=r(n,0)}a.packedLength=4,a.pack=function(e,t,i){return i=r(i,0),t[i++]=e[0],t[i++]=e[1],t[i++]=e[2],t[i++]=e[3],t},a.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new a),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n},a.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):new a(e[0],e[2],e[1],e[3])},a.fromArray=function(e,t,n){return t=r(t,0),i(n)||(n=new a),n[0]=e[t],n[1]=e[t+1],n[2]=e[t+2],n[3]=e[t+3],n},a.fromColumnMajorArray=function(e,t){return a.clone(e,t)},a.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[2],t[2]=e[1],t[3]=e[3],t):new a(e[0],e[1],e[2],e[3])},a.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=e.y,t):new a(e.x,0,0,e.y)},a.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=e,t):new a(e,0,0,e)},a.fromRotation=function(e,t){var r=Math.cos(e),n=Math.sin(e);return i(t)?(t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t):new a(r,-n,n,r)},a.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):[e[0],e[1],e[2],e[3]]},a.getElementIndex=function(e,t){return 2*e+t},a.getColumn=function(e,t,r){var i=2*t,n=e[i],o=e[i+1];return r.x=n,r.y=o,r},a.setColumn=function(e,t,r,i){i=a.clone(e,i);var n=2*t;return i[n]=r.x,i[n+1]=r.y,i},a.getRow=function(e,t,r){var i=e[t],n=e[t+2];return r.x=i,r.y=n,r},a.setRow=function(e,t,r,i){return i=a.clone(e,i),i[t]=r.x,i[t+2]=r.y,i};var s=new e;a.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],s)),r.y=e.magnitude(e.fromElements(t[2],t[3],s)),r};var l=new e;return a.getMaximumScale=function(t){return a.getScale(t,l),e.maximumComponent(l)},a.multiply=function(e,t,r){var i=e[0]*t[0]+e[2]*t[1],n=e[0]*t[2]+e[2]*t[3],o=e[1]*t[0]+e[3]*t[1],a=e[1]*t[2]+e[3]*t[3];return r[0]=i,r[1]=o,r[2]=n,r[3]=a,r},a.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r},a.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r},a.multiplyByVector=function(e,t,r){var i=e[0]*t.x+e[2]*t.y,n=e[1]*t.x+e[3]*t.y;return r.x=i,r.y=n,r},a.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r},a.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.y,r[3]=e[3]*t.y,r},a.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},a.transpose=function(e,t){var r=e[0],i=e[2],n=e[1],o=e[3];return t[0]=r,t[1]=i,t[2]=n,t[3]=o,t},a.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t},a.equals=function(e,t){return e===t||i(e)&&i(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},a.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]},a.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r},a.IDENTITY=o(new a(1,0,0,1)),a.ZERO=o(new a(0,0,0,0)),a.COLUMN0ROW0=0,a.COLUMN0ROW1=1,a.COLUMN1ROW0=2,a.COLUMN1ROW1=3,n(a.prototype,{length:{get:function(){return a.packedLength}}}),a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a.prototype.equalsEpsilon=function(e,t){return a.equalsEpsilon(this,e,t)},a.prototype.toString=function(){return"("+this[0]+", "+this[2]+")\n("+this[1]+", "+this[3]+")"},a}), +define("Core/mergeSort",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e,t,r,i,n,s){var l,u,c=n-i+1,d=s-n,h=o,p=a;for(l=0;l<c;++l)h[l]=e[i+l];for(u=0;u<d;++u)p[u]=e[n+u+1];l=0,u=0;for(var f=i;f<=s;++f){var m=h[l],g=p[u];l<c&&(u>=d||t(m,g,r)<=0)?(e[f]=m,++l):u<d&&(e[f]=g,++u)}}function i(e,t,n,o,a){if(!(o>=a)){var s=Math.floor(.5*(o+a));i(e,t,n,o,s),i(e,t,n,s+1,a),r(e,t,n,o,s,a)}}function n(e,t,r){var n=e.length,s=Math.ceil(.5*n);o.length=s,a.length=s,i(e,t,r,0,n-1),o.length=0,a.length=0}var o=[],a=[];return n}),define("Core/NearFarScalar",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function i(t,r,i,n){this.near=e(t,0),this.nearValue=e(r,0),this.far=e(i,1),this.farValue=e(n,0)}return i.clone=function(e,r){if(t(e))return t(r)?(r.near=e.near,r.nearValue=e.nearValue,r.far=e.far,r.farValue=e.farValue,r):new i(e.near,e.nearValue,e.far,e.farValue)},i.packedLength=4,i.pack=function(t,r,i){return i=e(i,0),r[i++]=t.near,r[i++]=t.nearValue,r[i++]=t.far,r[i]=t.farValue,r},i.unpack=function(r,n,o){return n=e(n,0),t(o)||(o=new i),o.near=r[n++],o.nearValue=r[n++],o.far=r[n++],o.farValue=r[n],o},i.equals=function(e,r){return e===r||t(e)&&t(r)&&e.near===r.near&&e.nearValue===r.nearValue&&e.far===r.far&&e.farValue===r.farValue},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/Visibility",["./freezeObject"],function(e){"use strict";return e({NONE:-1,PARTIAL:0,FULL:1})}),define("Core/Occluder",["./BoundingSphere","./Cartesian3","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math","./Rectangle","./Visibility"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){this._occluderPosition=t.clone(e.center),this._occluderRadius=e.radius,this._horizonDistance=0,this._horizonPlaneNormal=void 0,this._horizonPlanePosition=void 0,this._cameraPosition=void 0,this.cameraPosition=r}var d=new t;n(c.prototype,{position:{get:function(){return this._occluderPosition}},radius:{get:function(){return this._occluderRadius}},cameraPosition:{set:function(e){e=t.clone(e,this._cameraPosition);var r,i,n,o=t.subtract(this._occluderPosition,e,d),a=t.magnitudeSquared(o),s=this._occluderRadius*this._occluderRadius;if(a>s){r=Math.sqrt(a-s),a=1/Math.sqrt(a),i=t.multiplyByScalar(o,a,d);var l=r*r*a;n=t.add(e,t.multiplyByScalar(i,l,d),d)}else r=Number.MAX_VALUE;this._horizonDistance=r,this._horizonPlaneNormal=i,this._horizonPlanePosition=n,this._cameraPosition=e}}}),c.fromBoundingSphere=function(e,r,n){return i(n)?(t.clone(e.center,n._occluderPosition),n._occluderRadius=e.radius,n.cameraPosition=r,n):new c(e,r)};var h=new t;c.prototype.isPointVisible=function(e){if(this._horizonDistance!==Number.MAX_VALUE){var r=t.subtract(e,this._occluderPosition,h),i=this._occluderRadius;if((i=t.magnitudeSquared(r)-i*i)>0)return i=Math.sqrt(i)+this._horizonDistance,r=t.subtract(e,this._cameraPosition,r),i*i>t.magnitudeSquared(r)}return!1};var p=new t;c.prototype.isBoundingSphereVisible=function(e){var r=t.clone(e.center,p),i=e.radius;if(this._horizonDistance!==Number.MAX_VALUE){var n=t.subtract(r,this._occluderPosition,h),o=this._occluderRadius-i;if(o=t.magnitudeSquared(n)-o*o,i<this._occluderRadius)return o>0&&(o=Math.sqrt(o)+this._horizonDistance,n=t.subtract(r,this._cameraPosition,n),o*o+i*i>t.magnitudeSquared(n));if(o>0){n=t.subtract(r,this._cameraPosition,n);var a=t.magnitudeSquared(n),s=this._occluderRadius*this._occluderRadius,l=i*i;return(this._horizonDistance*this._horizonDistance+s)*l>a*s||(o=Math.sqrt(o)+this._horizonDistance)*o+l>a}return!0}return!1};var f=new t;c.prototype.computeVisibility=function(e){var r=t.clone(e.center),i=e.radius;if(i>this._occluderRadius)return u.FULL;if(this._horizonDistance!==Number.MAX_VALUE){var n=t.subtract(r,this._occluderPosition,f),o=this._occluderRadius-i,a=t.magnitudeSquared(n);if((o=a-o*o)>0){o=Math.sqrt(o)+this._horizonDistance,n=t.subtract(r,this._cameraPosition,n);var s=t.magnitudeSquared(n);return o*o+i*i<s?u.NONE:(o=this._occluderRadius+i,(o=a-o*o)>0?(o=Math.sqrt(o)+this._horizonDistance,s<o*o+i*i?u.FULL:u.PARTIAL):(n=t.subtract(r,this._horizonPlanePosition,n),t.dot(n,this._horizonPlaneNormal)>-i?u.PARTIAL:u.FULL))}}return u.NONE};var m=new t;c.computeOccludeePoint=function(e,r,i){var n=t.clone(r),o=t.clone(e.center),a=e.radius,s=i.length,l=t.normalize(t.subtract(n,o,m),m),u=-t.dot(l,o),d=c._anyRotationVector(o,l,u),h=c._horizonToPlaneNormalDotProduct(e,l,u,d,i[0]);if(h){for(var p,f=1;f<s;++f){if(!(p=c._horizonToPlaneNormalDotProduct(e,l,u,d,i[f])))return;p<h&&(h=p)}if(!(h<.0017453283658983088)){var g=a/h;return t.add(o,t.multiplyByScalar(l,g,m),m)}}};var g=[];c.computeOccludeePointFromRectangle=function(i,n){n=r(n,a.WGS84);var o=l.subsample(i,n,0,g),s=e.fromPoints(o),u=t.ZERO;if(!t.equals(u,s.center))return c.computeOccludeePoint(new e(u,n.minimumRadius),s.center,o)};var _=new t;c._anyRotationVector=function(e,r,i){var n=t.abs(r,_),o=n.x>n.y?0:1;(0===o&&n.z>n.x||1===o&&n.z>n.y)&&(o=2);var a,s=new t;0===o?(n.x=e.x,n.y=e.y+1,n.z=e.z+1,a=t.UNIT_X):1===o?(n.x=e.x+1,n.y=e.y,n.z=e.z+1,a=t.UNIT_Y):(n.x=e.x+1,n.y=e.y+1,n.z=e.z,a=t.UNIT_Z);var l=(t.dot(r,n)+i)/-t.dot(r,a);return t.normalize(t.subtract(t.add(n,t.multiplyByScalar(a,l,s),n),e,n),n)};var v=new t;c._rotationVector=function(e,r,i,n,o){var a=t.subtract(n,e,v);if(a=t.normalize(a,a),t.dot(r,a)<.9999999847691291){var l=t.cross(r,a,a);if(t.magnitude(l)>s.EPSILON13)return t.normalize(l,new t)}return o};var y=new t,b=new t,C=new t,S=new t;return c._horizonToPlaneNormalDotProduct=function(e,r,i,n,o){var a=t.clone(o,y),s=t.clone(e.center,b),l=e.radius,u=t.subtract(s,a,C),c=t.magnitudeSquared(u),d=l*l;if(c<d)return!1;var h=c-d,p=Math.sqrt(h),f=Math.sqrt(c),m=1/f,g=p*m,_=g*p;u=t.normalize(u,u);var v=t.add(a,t.multiplyByScalar(u,_,S),S),w=Math.sqrt(h-_*_),T=this._rotationVector(s,r,i,a,n),E=t.fromElements(T.x*T.x*u.x+(T.x*T.y-T.z)*u.y+(T.x*T.z+T.y)*u.z,(T.x*T.y+T.z)*u.x+T.y*T.y*u.y+(T.y*T.z-T.x)*u.z,(T.x*T.z-T.y)*u.x+(T.y*T.z+T.x)*u.y+T.z*T.z*u.z,y);E=t.normalize(E,E);var A=t.multiplyByScalar(E,w,y);T=t.normalize(t.subtract(t.add(v,A,C),s,C),C);var x=t.dot(r,T);T=t.normalize(t.subtract(t.subtract(v,A,T),s,T),T);var P=t.dot(r,T);return x<P?x:P},c}),define("Core/Packable",["./DeveloperError"],function(e){"use strict";return{packedLength:void 0,pack:e.throwInstantiationError,unpack:e.throwInstantiationError}}),define("Core/PackableForInterpolation",["./DeveloperError"],function(e){"use strict";return{packedInterpolationLength:void 0,convertPackedArrayForInterpolation:e.throwInstantiationError,unpackInterpolationResult:e.throwInstantiationError}}),define("ThirdParty/measureText",[],function(){var e=function(e,t){return document.defaultView.getComputedStyle(e,null).getPropertyValue(t)};return function(t,r,i,n){var o=t.measureText(r),a=e(t.canvas,"font-family"),s=e(t.canvas,"font-size").replace("px",""),l=e(t.canvas,"font-style"),u=e(t.canvas,"font-weight"),c=!/\S/.test(r);o.fontsize=s;var d=document.createElement("div");d.style.position="absolute",d.style.opacity=0,d.style.font=l+" "+u+" "+s+"px "+a,d.innerHTML=r+"<br/>"+r,document.body.appendChild(d),o.leading=1.2*s;var h=e(d,"height");if(h=h.replace("px",""),h>=2*s&&(o.leading=h/2|0),document.body.removeChild(d),c)o.ascent=0,o.descent=0,o.bounds={minx:0,maxx:o.width,miny:0,maxy:0},o.height=0;else{var p=document.createElement("canvas");p.width=o.width+100,p.height=3*s,p.style.opacity=1,p.style.fontFamily=a,p.style.fontSize=s,p.style.fontStyle=l,p.style.fontWeight=u;var f=p.getContext("2d");f.font=l+" "+u+" "+s+"px "+a;var m=p.width,g=p.height,_=g/2;f.fillStyle="white",f.fillRect(-1,-1,m+2,g+2),i&&(f.strokeStyle="black",f.lineWidth=t.lineWidth,f.strokeText(r,50,_)),n&&(f.fillStyle="black",f.fillText(r,50,_));for(var v=f.getImageData(0,0,m,g).data,y=0,b=4*m,C=v.length;++y<C&&255===v[y];);var S=y/b|0;for(y=C-1;--y>0&&255===v[y];);var w=y/b|0;for(y=0;y<C&&255===v[y];)(y+=b)>=C&&(y=y-C+4);var T=y%b/4|0,E=1;for(y=C-3;y>=0&&255===v[y];)(y-=b)<0&&(y=C-3-4*E++);var A=y%b/4+1|0;o.ascent=_-S,o.descent=w-_,o.bounds={minx:T-50,maxx:A-50,miny:0,maxy:w-S},o.height=w-S+1}return o}}),define("Core/writeTextToCanvas",["../ThirdParty/measureText","./Color","./defaultValue","./defined","./DeveloperError"],function(e,t,r,i,n){"use strict";function o(n,o){if(""!==n){o=r(o,r.EMPTY_OBJECT);var s=r(o.font,"10px sans-serif"),l=r(o.stroke,!1),u=r(o.fill,!0),c=r(o.strokeWidth,1),d=r(o.backgroundColor,t.TRANSPARENT),h=r(o.padding,0),p=2*h,f=document.createElement("canvas");f.width=1,f.height=1,f.style.font=s;var m=f.getContext("2d");i(a)||(i(m.imageSmoothingEnabled)?a="imageSmoothingEnabled":i(m.mozImageSmoothingEnabled)?a="mozImageSmoothingEnabled":i(m.webkitImageSmoothingEnabled)?a="webkitImageSmoothingEnabled":i(m.msImageSmoothingEnabled)&&(a="msImageSmoothingEnabled")),m.font=s,m.lineJoin="round",m.lineWidth=c,m[a]=!1,m.textBaseline=r(o.textBaseline,"bottom"),f.style.visibility="hidden",document.body.appendChild(f);var g=e(m,n,l,u);f.dimensions=g,document.body.removeChild(f),f.style.visibility="";var _=-g.bounds.minx,v=Math.ceil(g.width)+_+p,y=g.height+p,b=y-g.ascent+p,C=y-b+p;if(f.width=v,f.height=y,m.font=s,m.lineJoin="round",m.lineWidth=c,m[a]=!1,d!==t.TRANSPARENT&&(m.fillStyle=d.toCssColorString(),m.fillRect(0,0,f.width,f.height)),l){var S=r(o.strokeColor,t.BLACK);m.strokeStyle=S.toCssColorString(),m.strokeText(n,_+h,C)}if(u){var w=r(o.fillColor,t.WHITE);m.fillStyle=w.toCssColorString(),m.fillText(n,_+h,C)}return f}}var a;return o}),define("Core/PinBuilder",["./buildModuleUrl","./Color","./defined","./DeveloperError","./Resource","./writeTextToCanvas"],function(e,t,r,i,n,o){"use strict";function a(){this._cache={}}function s(e,t,r){e.save(),e.scale(r/24,r/24),e.fillStyle=t.toCssColorString(),e.strokeStyle=t.brighten(.6,c).toCssColorString(),e.lineWidth=.846,e.beginPath(),e.moveTo(6.72,.422),e.lineTo(17.28,.422),e.bezierCurveTo(18.553,.422,19.577,1.758,19.577,3.415),e.lineTo(19.577,10.973),e.bezierCurveTo(19.577,12.63,18.553,13.966,17.282,13.966),e.lineTo(14.386,14.008),e.lineTo(11.826,23.578),e.lineTo(9.614,14.008),e.lineTo(6.719,13.965),e.bezierCurveTo(5.446,13.983,4.422,12.629,4.422,10.972),e.lineTo(4.422,3.416),e.bezierCurveTo(4.423,1.76,5.447,.423,6.718,.423),e.closePath(),e.fill(),e.stroke(),e.restore()}function l(e,r,i){var n=i/2.5,o=n,a=n;r.width>r.height?a=n*(r.height/r.width):r.width<r.height&&(o=n*(r.width/r.height));var s=Math.round((i-o)/2),l=Math.round(7/24*i-a/2);e.globalCompositeOperation="destination-out",e.drawImage(r,s-1,l,o,a),e.drawImage(r,s,l-1,o,a),e.drawImage(r,s+1,l,o,a),e.drawImage(r,s,l+1,o,a),e.globalCompositeOperation="destination-over",e.fillStyle=t.BLACK.toCssColorString(),e.fillRect(s-1,l-1,o+2,a+2),e.globalCompositeOperation="destination-out",e.drawImage(r,s,l,o,a),e.globalCompositeOperation="destination-over",e.fillStyle=t.WHITE.toCssColorString(),e.fillRect(s-1,l-2,o+2,a+2)}function u(e,t,i,a,u){d[0]=e,d[1]=t,d[2]=i,d[3]=a;var c=JSON.stringify(d),h=u[c];if(r(h))return h;var p=document.createElement("canvas");p.width=a,p.height=a;var f=p.getContext("2d");if(s(f,i,a),r(e)){var m=n.createIfNeeded(e),g=m.fetchImage().then(function(e){return l(f,e,a),u[c]=p,p});return u[c]=g,g}if(r(t)){var _=o(t,{font:"bold "+a+"px sans-serif"});l(f,_,a)}return u[c]=p,p}a.prototype.fromColor=function(e,t){return u(void 0,void 0,e,t,this._cache)},a.prototype.fromUrl=function(e,t,r){return u(e,void 0,t,r,this._cache)},a.prototype.fromMakiIconId=function(t,r,i){return u(e("Assets/Textures/maki/"+encodeURIComponent(t)+".png"),void 0,r,i,this._cache)},a.prototype.fromText=function(e,t,r){return u(void 0,e,t,r,this._cache)};var c=new t,d=new Array(4);return a}),define("Core/PlaneGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e){e=n(e,n.EMPTY_OBJECT);var t=n(e.vertexFormat,c.DEFAULT);this._vertexFormat=t,this._workerName="createPlaneGeometry"}d.packedLength=c.packedLength,d.pack=function(e,t,r){return r=n(r,0),c.pack(e._vertexFormat,t,r),t};var h=new c,p={vertexFormat:h};d.unpack=function(e,t,r){t=n(t,0);var i=c.unpack(e,t,h);return o(r)?(r._vertexFormat=c.clone(i,r._vertexFormat),r):new d(p)};var f=new t(-.5,-.5,0),m=new t(.5,.5,0);return d.createGeometry=function(r){var n,o,c=r._vertexFormat,d=new l;if(c.position){if(o=new Float64Array(12),o[0]=f.x,o[1]=f.y,o[2]=0,o[3]=m.x,o[4]=f.y,o[5]=0,o[6]=m.x,o[7]=m.y,o[8]=0,o[9]=f.x,o[10]=m.y,o[11]=0,d.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:o}),c.normal){var h=new Float32Array(12);h[0]=0,h[1]=0,h[2]=1,h[3]=0,h[4]=0,h[5]=1,h[6]=0,h[7]=0,h[8]=1,h[9]=0,h[10]=0,h[11]=1,d.normal=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:h})}if(c.st){var p=new Float32Array(8);p[0]=0,p[1]=0,p[2]=1,p[3]=0,p[4]=1,p[5]=1,p[6]=0,p[7]=1,d.st=new s({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:p})}if(c.tangent){var g=new Float32Array(12);g[0]=1,g[1]=0,g[2]=0,g[3]=1,g[4]=0,g[5]=0,g[6]=1,g[7]=0,g[8]=0,g[9]=1,g[10]=0,g[11]=0,d.tangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:g})}if(c.bitangent){var _=new Float32Array(12);_[0]=0,_[1]=1,_[2]=0,_[3]=0,_[4]=1,_[5]=0,_[6]=0,_[7]=1,_[8]=0,_[9]=0,_[10]=1,_[11]=0,d.bitangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:_})}n=new Uint16Array(6),n[0]=0,n[1]=1,n[2]=2,n[3]=0,n[4]=2,n[5]=3}return new a({attributes:d,indices:n,primitiveType:u.TRIANGLES,boundingSphere:new e(t.ZERO,Math.sqrt(2))})},d}),define("Core/PlaneOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(){this._workerName="createPlaneOutlineGeometry"}c.packedLength=0,c.pack=function(e,t){return t},c.unpack=function(e,t,r){return o(r)?r:new c};var d=new t(-.5,-.5,0),h=new t(.5,.5,0);return c.createGeometry=function(){var r=new l,n=new Uint16Array(8),o=new Float64Array(12);return o[0]=d.x,o[1]=d.y,o[2]=d.z,o[3]=h.x,o[4]=d.y,o[5]=d.z,o[6]=h.x,o[7]=h.y,o[8]=d.z,o[9]=d.x,o[10]=h.y,o[11]=d.z,r.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:o}),n[0]=0,n[1]=1,n[2]=1,n[3]=2,n[4]=2,n[5]=3,n[6]=3,n[7]=0,new a({attributes:r,indices:n,primitiveType:u.LINES,boundingSphere:new e(t.ZERO,Math.sqrt(2))})},c}),define("Core/pointInsideTriangle",["./barycentricCoordinates","./Cartesian3"],function(e,t){"use strict";function r(t,r,n,o){return e(t,r,n,o,i),i.x>0&&i.y>0&&i.z>0}var i=new t;return r}),define("Core/Queue",["./defineProperties"],function(e){"use strict";function t(){this._array=[],this._offset=0,this._length=0}return e(t.prototype,{length:{get:function(){return this._length}}}),t.prototype.enqueue=function(e){this._array.push(e),this._length++},t.prototype.dequeue=function(){if(0!==this._length){var e=this._array,t=this._offset,r=e[t];return e[t]=void 0,t++,t>10&&2*t>e.length&&(this._array=e.slice(t),t=0),this._offset=t,this._length--,r}},t.prototype.peek=function(){if(0!==this._length)return this._array[this._offset]},t.prototype.contains=function(e){return-1!==this._array.indexOf(e)},t.prototype.clear=function(){this._array.length=this._offset=this._length=0},t.prototype.sort=function(e){this._offset>0&&(this._array=this._array.slice(this._offset),this._offset=0),this._array.sort(e)},t}),define("Core/PolygonGeometryLibrary",["./arrayRemoveDuplicates","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e,r,i,n){return t.subtract(r,e,v),t.multiplyByScalar(v,i/n,v),t.add(e,v,v),[v.x,v.y,v.z]}var _={};_.computeHierarchyPackedLength=function(e){for(var r=0,i=[e];i.length>0;){var o=i.pop();if(n(o)){r+=2;var a=o.positions,s=o.holes;if(n(a)&&(r+=a.length*t.packedLength),n(s))for(var l=s.length,u=0;u<l;++u)i.push(s[u])}}return r},_.packPolygonHierarchy=function(e,r,i){for(var o=[e];o.length>0;){var a=o.pop();if(n(a)){var s=a.positions,l=a.holes;if(r[i++]=n(s)?s.length:0,r[i++]=n(l)?l.length:0,n(s))for(var u=s.length,c=0;c<u;++c,i+=3)t.pack(s[c],r,i);if(n(l))for(var d=l.length,h=0;h<d;++h)o.push(l[h])}}return i},_.unpackPolygonHierarchy=function(e,r){for(var i=e[r++],n=e[r++],o=new Array(i),a=n>0?new Array(n):void 0,s=0;s<i;++s,r+=t.packedLength)o[s]=t.unpack(e,r);for(var l=0;l<n;++l)a[l]=_.unpackPolygonHierarchy(e,r),r=a[l].startingIndex,delete a[l].startingIndex;return{positions:o,holes:a,startingIndex:r}};var v=new t;_.subdivideLineCount=function(e,r,i){var n=t.distance(e,r),o=n/i,a=Math.max(0,Math.ceil(Math.log(o)/Math.log(2)));return Math.pow(2,a)},_.subdivideLine=function(e,r,i,o){var a=_.subdivideLineCount(e,r,i),s=t.distance(e,r),l=s/a;n(o)||(o=[]);var u=o;u.length=3*a;for(var c=0,d=0;d<a;d++){var h=g(e,r,d*l,s);u[c++]=h[0],u[c++]=h[1],u[c++]=h[2]}return u};var y=new t,b=new t,C=new t,S=new t;_.scaleToGeodeticHeightExtruded=function(e,r,a,s,l){s=i(s,o.WGS84);var u=y,c=b,d=C,h=S;if(n(e)&&n(e.attributes)&&n(e.attributes.position))for(var p=e.attributes.position.values,f=p.length/2,m=0;m<f;m+=3)t.fromArray(p,m,d),s.geodeticSurfaceNormal(d,u),h=s.scaleToGeodeticSurface(d,h),c=t.multiplyByScalar(u,a,c),c=t.add(h,c,c),p[m+f]=c.x,p[m+1+f]=c.y,p[m+2+f]=c.z,l&&(h=t.clone(d,h)),c=t.multiplyByScalar(u,r,c),c=t.add(h,c,c),p[m]=c.x,p[m+1]=c.y,p[m+2]=c.z;return e},_.polygonsFromHierarchy=function(r,i,o,a){var s=[],l=[],u=new f;for(u.enqueue(r);0!==u.length;){var c=u.dequeue(),d=c.positions,p=c.holes;if(d=e(d,t.equalsEpsilon,!0),!(d.length<3)){var g=o.projectPointsOntoPlane(d),_=[],v=h.computeWindingOrder2D(g);v===m.CLOCKWISE&&(g.reverse(),d=d.slice().reverse());var y,b,C=d.slice(),S=n(p)?p.length:0,w=[];for(y=0;y<S;y++){var T=p[y],E=e(T.positions,t.equalsEpsilon,!0);if(!(E.length<3)){var A=o.projectPointsOntoPlane(E);v=h.computeWindingOrder2D(A),v===m.CLOCKWISE&&(A.reverse(),E=E.slice().reverse()),w.push(E),_.push(C.length),C=C.concat(E),g=g.concat(A);var x=0;for(n(T.holes)&&(x=T.holes.length),b=0;b<x;b++)u.enqueue(T.holes[b])}}if(!i){for(y=0;y<d.length;y++)a.scaleToGeodeticSurface(d[y],d[y]);for(y=0;y<w.length;y++){var P=w[y];for(b=0;b<P.length;++b)a.scaleToGeodeticSurface(P[b],P[b])}}s.push({outerRing:d,holes:w}),l.push({positions:C,positions2D:g,holes:_})}}return{hierarchy:s,polygons:l}},_.createGeometryFromPositions=function(e,t,i,n,o){var l=h.triangulate(t.positions2D,t.holes);l.length<3&&(l=[0,1,2]);var c=t.positions;if(n){for(var d=c.length,f=new Array(3*d),m=0,g=0;g<d;g++){var _=c[g];f[m++]=_.x,f[m++]=_.y,f[m++]=_.z}var v=new a({attributes:{position:new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:f})},indices:l,primitiveType:p.TRIANGLES});return o.normal?u.computeNormal(v):v}return h.computeSubdivision(e,c,l,i)};var w=[],T=new t,E=new t;return _.computeWallGeometry=function(e,i,n,o){var u,h,f,m,g,v=e.length,y=0;if(o)for(h=3*v*2,u=new Array(2*h),f=0;f<v;f++)m=e[f],g=e[(f+1)%v],u[y]=u[y+h]=m.x,++y,u[y]=u[y+h]=m.y,++y,u[y]=u[y+h]=m.z,++y,u[y]=u[y+h]=g.x,++y,u[y]=u[y+h]=g.y,++y,u[y]=u[y+h]=g.z,++y;else{var b=d.chordLength(n,i.maximumRadius),C=0;for(f=0;f<v;f++)C+=_.subdivideLineCount(e[f],e[(f+1)%v],b);for(h=3*(C+v),u=new Array(2*h),f=0;f<v;f++){m=e[f],g=e[(f+1)%v];for(var S=_.subdivideLine(m,g,b,w),A=S.length,x=0;x<A;++x,++y)u[y]=S[x],u[y+h]=S[x];u[y]=g.x,u[y+h]=g.x,++y,u[y]=g.y,u[y+h]=g.y,++y,u[y]=g.z,u[y+h]=g.z,++y}}v=u.length;var P=c.createTypedArray(v/3,v-6*e.length),D=0;for(v/=6,f=0;f<v;f++){var I=f,O=I+1,M=I+v,R=M+1;m=t.fromArray(u,3*I,T),g=t.fromArray(u,3*O,E),t.equalsEpsilon(m,g,d.EPSILON14)||(P[D++]=I,P[D++]=M,P[D++]=O,P[D++]=O,P[D++]=M,P[D++]=R)}return new a({attributes:new l({position:new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:u})}),indices:P,primitiveType:p.TRIANGLES})},_}),define("Core/PolygonGeometry",["./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Geometry","./GeometryAttribute","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./PolygonGeometryLibrary","./PolygonPipeline","./Quaternion","./Rectangle","./VertexFormat","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e,t,r,n){for(var o=S.fromAxisAngle(e._plane.normal,r,R),a=y.fromQuaternion(o,L),s=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,c=Number.POSITIVE_INFINITY,d=Number.NEGATIVE_INFINITY,h=t.length,p=0;p<h;++p){var f=i.clone(t[p],M);y.multiplyByVector(a,f,f);var m=e.projectPointOntoPlane(f,O);l(m)&&(s=Math.min(s,m.x),u=Math.max(u,m.x),c=Math.min(c,m.y),d=Math.max(d,m.y))}return n.x=s,n.y=c,n.width=u-s,n.height=d-c,n}function x(e,t,r,i){var n=i.cartesianToCartographic(e,N),o=n.height,a=i.cartesianToCartographic(t,k);a.height=o,i.cartographicToCartesian(a,t);var s=i.cartesianToCartographic(r,k);s.height=o-100,i.cartographicToCartesian(s,r)}function P(e){var t=e.vertexFormat,n=e.geometry,o=e.shadowVolume;if(t.st||t.normal||t.tangent||t.bitangent||o){var s=e.boundingRectangle,l=e.tangentPlane,u=e.ellipsoid,c=e.stRotation,d=e.wall,h=e.top||d,p=e.bottom||d,m=e.perPositionHeight,g=Y;g.x=s.x,g.y=s.y;var _,b=n.attributes.position.values,C=b.length,w=t.st?new Float32Array(C/3*2):void 0;t.normal&&(_=m&&h&&!d?n.attributes.normal.values:new Float32Array(C));var T=t.tangent?new Float32Array(C):void 0,E=t.bitangent?new Float32Array(C):void 0,A=o?new Float32Array(C):void 0,P=0,D=0,I=U,O=V,M=z,R=!0,L=S.fromAxisAngle(l._plane.normal,c,Z),N=y.fromQuaternion(L,K),k=0,F=0;h&&p&&(k=C/2,F=C/3,C/=2);for(var J=0;J<C;J+=3){var $=i.fromArray(b,J,Q);if(t.st){var ee=y.multiplyByVector(N,$,B);ee=u.scaleToGeodeticSurface(ee,ee);var te=l.projectPointOntoPlane(ee,X);r.subtract(te,g,te);var re=v.clamp(te.x/s.width,0,1),ie=v.clamp(te.y/s.height,0,1);p&&(w[P+F]=re,w[P+1+F]=ie),h&&(w[P]=re,w[P+1]=ie),P+=2}if(t.normal||t.tangent||t.bitangent||o){var ne=D+1,oe=D+2;if(d){if(J+3<C){var ae=i.fromArray(b,J+3,G);if(R){var se=i.fromArray(b,J+C,W);m&&x($,ae,se,u),i.subtract(ae,$,ae),i.subtract(se,$,se),I=i.normalize(i.cross(se,ae,I),I),R=!1}i.equalsEpsilon(ae,$,v.EPSILON10)&&(R=!0)}(t.tangent||t.bitangent)&&(M=u.geodeticSurfaceNormal($,M),t.tangent&&(O=i.normalize(i.cross(M,I,O),O)))}else I=u.geodeticSurfaceNormal($,I),(t.tangent||t.bitangent)&&(m&&(H=i.fromArray(_,D,H),j=i.cross(i.UNIT_Z,H,j),j=i.normalize(y.multiplyByVector(N,j,j),j),t.bitangent&&(q=i.normalize(i.cross(H,j,q),q))),O=i.cross(i.UNIT_Z,I,O),O=i.normalize(y.multiplyByVector(N,O,O),O),t.bitangent&&(M=i.normalize(i.cross(I,O,M),M)));t.normal&&(e.wall?(_[D+k]=I.x,_[ne+k]=I.y,_[oe+k]=I.z):p&&(_[D+k]=-I.x,_[ne+k]=-I.y,_[oe+k]=-I.z),(h&&!m||d)&&(_[D]=I.x,_[ne]=I.y,_[oe]=I.z)),o&&(d&&(I=u.geodeticSurfaceNormal($,I)),A[D+k]=-I.x,A[ne+k]=-I.y,A[oe+k]=-I.z),t.tangent&&(e.wall?(T[D+k]=O.x,T[ne+k]=O.y,T[oe+k]=O.z):p&&(T[D+k]=-O.x,T[ne+k]=-O.y,T[oe+k]=-O.z),h&&(m?(T[D]=j.x,T[ne]=j.y,T[oe]=j.z):(T[D]=O.x,T[ne]=O.y,T[oe]=O.z))),t.bitangent&&(p&&(E[D+k]=M.x,E[ne+k]=M.y,E[oe+k]=M.z),h&&(m?(E[D]=q.x,E[ne]=q.y,E[oe]=q.z):(E[D]=M.x,E[ne]=M.y,E[oe]=M.z))),D+=3}}t.st&&(n.attributes.st=new f({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:w})),t.normal&&(n.attributes.normal=new f({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:_})),t.tangent&&(n.attributes.tangent=new f({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:T})),t.bitangent&&(n.attributes.bitangent=new f({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:E})),o&&(n.attributes.extrudeDirection=new f({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:A}))}return n}function D(e,t,r,i,n,o,a,s){var l,u={walls:[]};if(o||a){var c,d,p=b.createGeometryFromPositions(e,t,r,n,s),f=p.attributes.position.values,g=p.indices;if(o&&a){var v=f.concat(f);c=v.length/3,d=_.createTypedArray(c,2*g.length),d.set(g);var y=g.length,S=c/2;for(l=0;l<y;l+=3){var w=d[l]+S,T=d[l+1]+S,A=d[l+2]+S;d[l+y]=A,d[l+1+y]=T,d[l+2+y]=w}if(p.attributes.position.values=v,n){var x=p.attributes.normal.values;p.attributes.normal.values=new Float32Array(v.length),p.attributes.normal.values.set(x)}p.indices=d}else if(a){for(c=f.length/3,d=_.createTypedArray(c,g.length),l=0;l<g.length;l+=3)d[l]=g[l+2],d[l+1]=g[l+1],d[l+2]=g[l];p.indices=d}u.topAndBottom=new m({geometry:p})}var P=i.outerRing,D=h.fromPoints(P,e),I=D.projectPointsOntoPlane(P,J),O=C.computeWindingOrder2D(I);O===E.CLOCKWISE&&(P=P.slice().reverse());var M=b.computeWallGeometry(P,e,r,n);u.walls.push(new m({geometry:M}));var R=i.holes;for(l=0;l<R.length;l++){var L=R[l];D=h.fromPoints(L,e),I=D.projectPointsOntoPlane(L,J),O=C.computeWindingOrder2D(I),O===E.COUNTER_CLOCKWISE&&(L=L.slice().reverse()),M=b.computeWallGeometry(L,e,r),u.walls.push(new m({geometry:M}))}return u}function I(e){var t=e.polygonHierarchy,r=s(e.vertexFormat,T.DEFAULT),i=s(e.ellipsoid,d.WGS84),n=s(e.granularity,v.RADIANS_PER_DEGREE),o=s(e.stRotation,0),a=s(e.height,0),u=s(e.perPositionHeight,!1),c=e.extrudedHeight,h=l(c);if(!u&&h)if(v.equalsEpsilon(a,c,v.EPSILON10))c=void 0,h=!1;else{var p=c;c=Math.min(p,a),a=Math.max(p,a)}this._vertexFormat=T.clone(r),this._ellipsoid=d.clone(i),this._granularity=n,this._stRotation=o,this._height=a,this._extrudedHeight=s(c,0),this._extrude=h,this._closeTop=s(e.closeTop,!0),this._closeBottom=s(e.closeBottom,!0),this._polygonHierarchy=t,this._perPositionHeight=u,this._shadowVolume=s(e.shadowVolume,!1),this._workerName="createPolygonGeometry";var f=t.positions;!l(f)||f.length<3?this._rectangle=new w:this._rectangle=w.fromCartesianArray(f,i),this.packedLength=b.computeHierarchyPackedLength(t)+d.packedLength+T.packedLength+w.packedLength+10}var O=new r,M=new i,R=new S,L=new y,N=new n,k=new n,F=new e,B=new i,U=new i,V=new i,z=new i,G=new i,W=new i,H=new i,j=new i,q=new i,Y=new r,X=new r,Q=new i,Z=new S,K=new y,J=[];I.fromPositions=function(e){return e=s(e,s.EMPTY_OBJECT),new I({polygonHierarchy:{positions:e.positions},height:e.height,extrudedHeight:e.extrudedHeight,vertexFormat:e.vertexFormat,stRotation:e.stRotation,ellipsoid:e.ellipsoid,granularity:e.granularity,perPositionHeight:e.perPositionHeight,closeTop:e.closeTop,closeBottom:e.closeBottom})},I.pack=function(e,t,r){return r=s(r,0),r=b.packPolygonHierarchy(e._polygonHierarchy,t,r),d.pack(e._ellipsoid,t,r),r+=d.packedLength,T.pack(e._vertexFormat,t,r),r+=T.packedLength,w.pack(e._rectangle,t,r),r+=w.packedLength,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._granularity,t[r++]=e._stRotation,t[r++]=e._extrude?1:0,t[r++]=e._perPositionHeight?1:0,t[r++]=e._closeTop?1:0,t[r++]=e._closeBottom?1:0,t[r++]=e._shadowVolume?1:0,t[r]=e.packedLength,t};var $=d.clone(d.UNIT_SPHERE),ee=new T,te=new w,re={polygonHierarchy:{}};return I.unpack=function(e,t,r){t=s(t,0);var i=b.unpackPolygonHierarchy(e,t);t=i.startingIndex,delete i.startingIndex;var n=d.unpack(e,t,$);t+=d.packedLength;var o=T.unpack(e,t,ee);t+=T.packedLength;var a=w.unpack(e,t,te);t+=w.packedLength;var u=e[t++],c=e[t++],h=e[t++],p=e[t++],f=1===e[t++],m=1===e[t++],g=1===e[t++],_=1===e[t++],v=1===e[t++],y=e[t];return l(r)||(r=new I(re)),r._polygonHierarchy=i,r._ellipsoid=d.clone(n,r._ellipsoid),r._vertexFormat=T.clone(o,r._vertexFormat),r._height=u,r._extrudedHeight=c,r._granularity=h,r._stRotation=p,r._extrude=f,r._perPositionHeight=m,r._closeTop=g,r._closeBottom=_,r._rectangle=w.clone(a),r._shadowVolume=v,r.packedLength=y,r},I.createGeometry=function(e){var r=e._vertexFormat,i=e._ellipsoid,n=e._granularity,o=e._stRotation,a=e._height,s=e._extrudedHeight,l=e._extrude,u=e._polygonHierarchy,c=e._perPositionHeight,d=e._closeTop,f=e._closeBottom,v=u.positions;if(!(v.length<3)){var y=h.fromPoints(v,i),S=b.polygonsFromHierarchy(u,c,y,i),w=S.hierarchy,T=S.polygons;if(0!==w.length){v=w[0].outerRing;var E,x,I=A(y,v,o,F),O=[],M={perPositionHeight:c,vertexFormat:r,geometry:void 0,tangentPlane:y,boundingRectangle:I,ellipsoid:i,stRotation:o,bottom:!1,top:!0,wall:!1};if(l)for(M.top=d,M.bottom=f,M.shadowVolume=e._shadowVolume,x=0;x<T.length;x++){E=D(i,T[x],n,w[x],c,d,f,r);var R;d&&f?(R=E.topAndBottom,M.geometry=b.scaleToGeodeticHeightExtruded(R.geometry,a,s,i,c)):d?(R=E.topAndBottom,R.geometry.attributes.position.values=C.scaleToGeodeticHeight(R.geometry.attributes.position.values,a,i,!c),M.geometry=R.geometry):f&&(R=E.topAndBottom,R.geometry.attributes.position.values=C.scaleToGeodeticHeight(R.geometry.attributes.position.values,s,i,!0),M.geometry=R.geometry),(d||f)&&(M.wall=!1,R.geometry=P(M),O.push(R));var L=E.walls;M.wall=!0;for(var N=0;N<L.length;N++){var k=L[N];M.geometry=b.scaleToGeodeticHeightExtruded(k.geometry,a,s,i,c),k.geometry=P(M),O.push(k)}}else for(x=0;x<T.length;x++)E=new m({geometry:b.createGeometryFromPositions(i,T[x],n,c,r)}),E.geometry.attributes.position.values=C.scaleToGeodeticHeight(E.geometry.attributes.position.values,a,i,!c),M.geometry=E.geometry,E.geometry=P(M),O.push(E);E=g.combineInstances(O)[0],E.attributes.position.values=new Float64Array(E.attributes.position.values),E.indices=_.createTypedArray(E.attributes.position.values.length/3,E.indices);var B=E.attributes,U=t.fromVertices(B.position.values);return r.position||delete B.position,new p({attributes:B,indices:E.indices,primitiveType:E.primitiveType,boundingSphere:U})}}},I.createShadowVolume=function(e,t,r){var i=e._granularity,n=e._ellipsoid,o=t(i,n),a=r(i,n);return new I({polygonHierarchy:e._polygonHierarchy,ellipsoid:n,stRotation:e._stRotation,granularity:i,perPositionHeight:!1,extrudedHeight:o,height:a,vertexFormat:T.POSITION_ONLY,shadowVolume:!0})},u(I.prototype,{rectangle:{get:function(){return this._rectangle}}}),I}),define("Core/PolygonHierarchy",["./defined"],function(e){"use strict";function t(t,r){this.positions=e(t)?t:[],this.holes=e(r)?r:[]}return t}),define("Core/PolygonOutlineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./PolygonGeometryLibrary","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C){"use strict";function S(e,t,r,i){var o=u.fromPoints(t,e),a=o.projectPointsOntoPlane(t,E);v.computeWindingOrder2D(a)===C.CLOCKWISE&&(a.reverse(),t=t.slice().reverse());var s,l,f=t.length,g=0;if(i)for(s=new Float64Array(2*f*3),l=0;l<f;l++){var b=t[l],S=t[(l+1)%f];s[g++]=b.x,s[g++]=b.y,s[g++]=b.z,s[g++]=S.x,s[g++]=S.y,s[g++]=S.z}else{var w=0;for(l=0;l<f;l++)w+=_.subdivideLineCount(t[l],t[(l+1)%f],r);for(s=new Float64Array(3*w),l=0;l<f;l++)for(var T=_.subdivideLine(t[l],t[(l+1)%f],r,A),x=T.length,P=0;P<x;++P)s[g++]=T[P]}f=s.length/3;var D=2*f,I=m.createTypedArray(f,D);for(g=0,l=0;l<f-1;l++)I[g++]=l,I[g++]=l+1;return I[g++]=f-1,I[g++]=0,new p({geometry:new c({attributes:new h({position:new d({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:s})}),indices:I,primitiveType:y.LINES})})}function w(e,t,r,i){var o=u.fromPoints(t,e),a=o.projectPointsOntoPlane(t,E);v.computeWindingOrder2D(a)===C.CLOCKWISE&&(a.reverse(),t=t.slice().reverse());var s,l,f=t.length,g=new Array(f),b=0;if(i)for(s=new Float64Array(2*f*3*2),l=0;l<f;++l){g[l]=b/3;var S=t[l],w=t[(l+1)%f];s[b++]=S.x,s[b++]=S.y,s[b++]=S.z,s[b++]=w.x,s[b++]=w.y,s[b++]=w.z}else{var T=0;for(l=0;l<f;l++)T+=_.subdivideLineCount(t[l],t[(l+1)%f],r);for(s=new Float64Array(3*T*2),l=0;l<f;++l){g[l]=b/3;for(var x=_.subdivideLine(t[l],t[(l+1)%f],r,A),P=x.length,D=0;D<P;++D)s[b++]=x[D]}}f=s.length/6 +;var I=g.length,O=2*(2*f+I),M=m.createTypedArray(f,O);for(b=0,l=0;l<f;++l)M[b++]=l,M[b++]=(l+1)%f,M[b++]=l+f,M[b++]=(l+1)%f+f;for(l=0;l<I;l++){var R=g[l];M[b++]=R,M[b++]=R+f}return new p({geometry:new c({attributes:new h({position:new d({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:s})}),indices:M,primitiveType:y.LINES})})}function T(e){var t=e.polygonHierarchy,r=o(e.ellipsoid,l.WGS84),i=o(e.granularity,g.RADIANS_PER_DEGREE),n=o(e.height,0),s=o(e.perPositionHeight,!1),u=e.extrudedHeight,c=a(u);if(c&&!s){var d=u;u=Math.min(d,n),n=Math.max(d,n)}this._ellipsoid=l.clone(r),this._granularity=i,this._height=n,this._extrudedHeight=o(u,0),this._extrude=c,this._polygonHierarchy=t,this._perPositionHeight=s,this._workerName="createPolygonOutlineGeometry",this.packedLength=_.computeHierarchyPackedLength(t)+l.packedLength+6}var E=[],A=[];T.pack=function(e,t,r){return r=o(r,0),r=_.packPolygonHierarchy(e._polygonHierarchy,t,r),l.pack(e._ellipsoid,t,r),r+=l.packedLength,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._granularity,t[r++]=e._extrude?1:0,t[r++]=e._perPositionHeight?1:0,t[r++]=e.packedLength,t};var x=l.clone(l.UNIT_SPHERE),P={polygonHierarchy:{}};return T.unpack=function(e,t,r){t=o(t,0);var i=_.unpackPolygonHierarchy(e,t);t=i.startingIndex,delete i.startingIndex;var n=l.unpack(e,t,x);t+=l.packedLength;var s=e[t++],u=e[t++],c=e[t++],d=1===e[t++],h=1===e[t++],p=e[t++];return a(r)||(r=new T(P)),r._polygonHierarchy=i,r._ellipsoid=l.clone(n,r._ellipsoid),r._height=s,r._extrudedHeight=u,r._granularity=c,r._extrude=d,r._perPositionHeight=h,r.packedLength=p,r},T.fromPositions=function(e){return e=o(e,o.EMPTY_OBJECT),new T({polygonHierarchy:{positions:e.positions},height:e.height,extrudedHeight:e.extrudedHeight,ellipsoid:e.ellipsoid,granularity:e.granularity,perPositionHeight:e.perPositionHeight})},T.createGeometry=function(i){var n=i._ellipsoid,o=i._granularity,s=i._height,l=i._extrudedHeight,u=i._extrude,d=i._polygonHierarchy,h=i._perPositionHeight,p=[],m=new b;m.enqueue(d);for(var y;0!==m.length;){var C=m.dequeue(),T=C.positions;if(T=e(T,r.equalsEpsilon,!0),!(T.length<3)){var E=C.holes?C.holes.length:0;for(y=0;y<E;y++){var A=C.holes[y];if(A.positions=e(A.positions,r.equalsEpsilon,!0),!(A.positions.length<3)){p.push(A.positions);var x=0;a(A.holes)&&(x=A.holes.length);for(var P=0;P<x;P++)m.enqueue(A.holes[P])}}p.push(T)}}if(0!==p.length){var D,I=[],O=g.chordLength(o,n.maximumRadius);if(u)for(y=0;y<p.length;y++)D=w(n,p[y],O,h),D.geometry=_.scaleToGeodeticHeightExtruded(D.geometry,s,l,n,h),I.push(D);else for(y=0;y<p.length;y++)D=S(n,p[y],O,h),D.geometry.attributes.position.values=v.scaleToGeodeticHeight(D.geometry.attributes.position.values,s,n,!h),I.push(D);D=f.combineInstances(I)[0];var M=t.fromVertices(D.attributes.position.values);return new c({attributes:D.attributes,indices:D.indices,primitiveType:D.primitiveType,boundingSphere:M})}},T}),define("Core/PolylineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryType","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(e,t,r,n,o){var a=b;a.length=o;var s,l=r.red,u=r.green,c=r.blue,d=r.alpha,h=n.red,p=n.green,f=n.blue,m=n.alpha;if(i.equals(r,n)){for(s=0;s<o;s++)a[s]=i.clone(r);return a}var g=(h-l)/o,_=(p-u)/o,v=(f-c)/o,y=(m-d)/o;for(s=0;s<o;s++)a[s]=new i(l+s*g,u+s*_,c+s*v,d+s*y);return a}function y(e){e=o(e,o.EMPTY_OBJECT);var t=e.positions,n=e.colors,s=o(e.width,1),u=o(e.colorsPerVertex,!1);this._positions=t,this._colors=n,this._width=s,this._colorsPerVertex=u,this._vertexFormat=_.clone(o(e.vertexFormat,_.DEFAULT)),this._followSurface=o(e.followSurface,!0),this._granularity=o(e.granularity,f.RADIANS_PER_DEGREE),this._ellipsoid=l.clone(o(e.ellipsoid,l.WGS84)),this._workerName="createPolylineGeometry";var c=1+t.length*r.packedLength;c+=a(n)?1+n.length*i.packedLength:1,this.packedLength=c+l.packedLength+_.packedLength+4}var b=[];y.pack=function(e,t,n){n=o(n,0);var s,u=e._positions,c=u.length;for(t[n++]=c,s=0;s<c;++s,n+=r.packedLength)r.pack(u[s],t,n);var d=e._colors;for(c=a(d)?d.length:0,t[n++]=c,s=0;s<c;++s,n+=i.packedLength)i.pack(d[s],t,n);return l.pack(e._ellipsoid,t,n),n+=l.packedLength,_.pack(e._vertexFormat,t,n),n+=_.packedLength,t[n++]=e._width,t[n++]=e._colorsPerVertex?1:0,t[n++]=e._followSurface?1:0,t[n]=e._granularity,t};var C=l.clone(l.UNIT_SPHERE),S=new _,w={positions:void 0,colors:void 0,ellipsoid:C,vertexFormat:S,width:void 0,colorsPerVertex:void 0,followSurface:void 0,granularity:void 0};y.unpack=function(e,t,n){t=o(t,0);var s,u=e[t++],c=new Array(u);for(s=0;s<u;++s,t+=r.packedLength)c[s]=r.unpack(e,t);u=e[t++];var d=u>0?new Array(u):void 0;for(s=0;s<u;++s,t+=i.packedLength)d[s]=i.unpack(e,t);var h=l.unpack(e,t,C);t+=l.packedLength;var p=_.unpack(e,t,S);t+=_.packedLength;var f=e[t++],m=1===e[t++],g=1===e[t++],v=e[t];return a(n)?(n._positions=c,n._colors=d,n._ellipsoid=l.clone(h,n._ellipsoid),n._vertexFormat=_.clone(p,n._vertexFormat),n._width=f,n._colorsPerVertex=m,n._followSurface=g,n._granularity=v,n):(w.positions=c,w.colors=d,w.width=f,w.colorsPerVertex=m,w.followSurface=g,w.granularity=v,new y(w))};var T=new r,E=new r,A=new r,x=new r;return y.createGeometry=function(o){var s,l,_,y=o._width,C=o._vertexFormat,S=o._colors,w=o._colorsPerVertex,P=o._followSurface,D=o._granularity,I=o._ellipsoid,O=e(o._positions,r.equalsEpsilon),M=O.length;if(!(M<2||y<=0)){if(P){var R=m.extractHeights(O,I),L=f.chordLength(D,I.maximumRadius);if(a(S)){var N=1;for(s=0;s<M-1;++s)N+=m.numberOfPoints(O[s],O[s+1],L);var k=new Array(N),F=0;for(s=0;s<M-1;++s){var B=O[s],U=O[s+1],V=S[s],z=m.numberOfPoints(B,U,L);if(w&&s<N){var G=S[s+1],W=v(B,U,V,G,z),H=W.length;for(l=0;l<H;++l)k[F++]=W[l]}else for(l=0;l<z;++l)k[F++]=i.clone(V)}k[F]=i.clone(S[S.length-1]),S=k,b.length=0}O=m.generateCartesianArc({positions:O,minDistance:L,ellipsoid:I,height:R})}M=O.length;var j,q=4*M-4,Y=new Float64Array(3*q),X=new Float64Array(3*q),Q=new Float64Array(3*q),Z=new Float32Array(2*q),K=C.st?new Float32Array(2*q):void 0,J=a(S)?new Uint8Array(4*q):void 0,$=0,ee=0,te=0,re=0;for(l=0;l<M;++l){0===l?(j=T,r.subtract(O[0],O[1],j),r.add(O[0],j,j)):j=O[l-1],r.clone(j,A),r.clone(O[l],E),l===M-1?(j=T,r.subtract(O[M-1],O[M-2],j),r.add(O[M-1],j,j)):j=O[l+1],r.clone(j,x);var ie,ne;a(J)&&(ie=0===l||w?S[l]:S[l-1],l!==M-1&&(ne=S[l]));var oe=0===l?2:0,ae=l===M-1?2:4;for(_=oe;_<ae;++_){r.pack(E,Y,$),r.pack(A,X,$),r.pack(x,Q,$),$+=3;var se=_-2<0?-1:1;if(Z[ee++]=_%2*2-1,Z[ee++]=se*y,C.st&&(K[te++]=l/(M-1),K[te++]=Math.max(Z[ee-2],0)),a(J)){var le=_<2?ie:ne;J[re++]=i.floatToByte(le.red),J[re++]=i.floatToByte(le.green),J[re++]=i.floatToByte(le.blue),J[re++]=i.floatToByte(le.alpha)}}}var ue=new d;ue.position=new c({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:Y}),ue.prevPosition=new c({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:X}),ue.nextPosition=new c({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:Q}),ue.expandAndWidth=new c({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:Z}),C.st&&(ue.st=new c({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:K})),a(J)&&(ue.color=new c({componentDatatype:n.UNSIGNED_BYTE,componentsPerAttribute:4,values:J,normalize:!0}));var ce=p.createTypedArray(q,6*M-6),de=0,he=0,pe=M-1;for(l=0;l<pe;++l)ce[he++]=de,ce[he++]=de+2,ce[he++]=de+1,ce[he++]=de+1,ce[he++]=de+2,ce[he++]=de+3,de+=4;return new u({attributes:ue,indices:ce,primitiveType:g.TRIANGLES,boundingSphere:t.fromPoints(O),geometryType:h.POLYLINES})}},y}),define("Core/PolylineVolumeGeometry",["./arrayRemoveDuplicates","./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CornerType","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./oneTimeWarning","./PolygonPipeline","./PolylineVolumeGeometryLibrary","./PrimitiveType","./VertexFormat","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S){"use strict";function w(e,t,i,n){var a=new p;n.position&&(a.position=new h({componentDatatype:o.DOUBLE,componentsPerAttribute:3,values:e}));var s,l,u,c,g,y,C=t.length,S=e.length/3,w=(S-2*C)/(2*C),T=v.triangulate(t),E=(w-1)*C*6+2*T.length,A=m.createTypedArray(S,E),x=2*C,P=0;for(s=0;s<w-1;s++){for(l=0;l<C-1;l++)u=2*l+s*C*2,y=u+x,c=u+1,g=c+x,A[P++]=c,A[P++]=u,A[P++]=g,A[P++]=g,A[P++]=u,A[P++]=y;u=2*C-2+s*C*2,c=u+1,g=c+x,y=u+x,A[P++]=c,A[P++]=u,A[P++]=g,A[P++]=g,A[P++]=u,A[P++]=y}if(n.st||n.tangent||n.bitangent){var D,I,O=new Float32Array(2*S),M=1/(w-1),R=1/i.height,L=i.height/2,N=0;for(s=0;s<w;s++){for(D=s*M,I=R*(t[0].y+L),O[N++]=D,O[N++]=I,l=1;l<C;l++)I=R*(t[l].y+L),O[N++]=D,O[N++]=I,O[N++]=D,O[N++]=I;I=R*(t[0].y+L),O[N++]=D,O[N++]=I}for(l=0;l<C;l++)D=0,I=R*(t[l].y+L),O[N++]=D,O[N++]=I;for(l=0;l<C;l++)D=(w-1)*M,I=R*(t[l].y+L),O[N++]=D,O[N++]=I;a.st=new h({componentDatatype:o.FLOAT,componentsPerAttribute:2,values:new Float32Array(O)})}var k=S-2*C;for(s=0;s<T.length;s+=3){var F=T[s]+k,B=T[s+1]+k,U=T[s+2]+k;A[P++]=F,A[P++]=B,A[P++]=U,A[P++]=U+C,A[P++]=B+C,A[P++]=F+C}var V=new d({attributes:a,indices:A,boundingSphere:r.fromVertices(e),primitiveType:b.TRIANGLES});if(n.normal&&(V=f.computeNormal(V)),n.tangent||n.bitangent){try{V=f.computeTangentAndBitangent(V)}catch(e){_("polyline-volume-tangent-bitangent","Unable to compute tangents and bitangents for polyline volume geometry")}n.tangent||(V.attributes.tangent=void 0),n.bitangent||(V.attributes.bitangent=void 0),n.st||(V.attributes.st=void 0)}return V}function T(e){e=s(e,s.EMPTY_OBJECT);var t=e.polylinePositions,r=e.shapePositions;this._positions=t,this._shape=r,this._ellipsoid=c.clone(s(e.ellipsoid,c.WGS84)),this._cornerType=s(e.cornerType,a.ROUNDED),this._vertexFormat=C.clone(s(e.vertexFormat,C.DEFAULT)),this._granularity=s(e.granularity,g.RADIANS_PER_DEGREE),this._workerName="createPolylineVolumeGeometry";var o=1+t.length*n.packedLength;o+=1+r.length*i.packedLength,this.packedLength=o+c.packedLength+C.packedLength+2}T.pack=function(e,t,r){r=s(r,0);var o,a=e._positions,l=a.length;for(t[r++]=l,o=0;o<l;++o,r+=n.packedLength)n.pack(a[o],t,r);var u=e._shape;for(l=u.length,t[r++]=l,o=0;o<l;++o,r+=i.packedLength)i.pack(u[o],t,r);return c.pack(e._ellipsoid,t,r),r+=c.packedLength,C.pack(e._vertexFormat,t,r),r+=C.packedLength,t[r++]=e._cornerType,t[r]=e._granularity,t};var E=c.clone(c.UNIT_SPHERE),A=new C,x={polylinePositions:void 0,shapePositions:void 0,ellipsoid:E,vertexFormat:A,cornerType:void 0,granularity:void 0};T.unpack=function(e,t,r){t=s(t,0);var o,a=e[t++],u=new Array(a);for(o=0;o<a;++o,t+=n.packedLength)u[o]=n.unpack(e,t);a=e[t++];var d=new Array(a);for(o=0;o<a;++o,t+=i.packedLength)d[o]=i.unpack(e,t);var h=c.unpack(e,t,E);t+=c.packedLength;var p=C.unpack(e,t,A);t+=C.packedLength;var f=e[t++],m=e[t];return l(r)?(r._positions=u,r._shape=d,r._ellipsoid=c.clone(h,r._ellipsoid),r._vertexFormat=C.clone(p,r._vertexFormat),r._cornerType=f,r._granularity=m,r):(x.polylinePositions=u,x.shapePositions=d,x.cornerType=f,x.granularity=m,new T(x))};var P=new t;return T.createGeometry=function(r){var i=r._positions,o=e(i,n.equalsEpsilon),a=r._shape;if(a=y.removeDuplicatesFromShape(a),!(o.length<2||a.length<3)){v.computeWindingOrder2D(a)===S.CLOCKWISE&&a.reverse();var s=t.fromPoints(a,P);return w(y.computePositions(o,a,s,r,!0),a,s,r._vertexFormat)}},T}),define("Core/PolylineVolumeOutlineGeometry",["./arrayRemoveDuplicates","./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CornerType","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PolylineVolumeGeometryLibrary","./PrimitiveType","./WindingOrder"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(e,t){var i=new p;i.position=new h({componentDatatype:o.DOUBLE,componentsPerAttribute:3,values:e});var n,a,s=t.length,l=i.position.values.length/3,u=e.length/3,c=u/s,m=f.createTypedArray(l,2*s*(c+1)),g=0;n=0;var _=n*s;for(a=0;a<s-1;a++)m[g++]=a+_,m[g++]=a+_+1;for(m[g++]=s-1+_,m[g++]=_,n=c-1,_=n*s,a=0;a<s-1;a++)m[g++]=a+_,m[g++]=a+_+1;for(m[g++]=s-1+_,m[g++]=_,n=0;n<c-1;n++){var y=s*n,b=y+s;for(a=0;a<s;a++)m[g++]=a+y,m[g++]=a+b}return new d({attributes:i,indices:f.createTypedArray(l,m),boundingSphere:r.fromVertices(e),primitiveType:v.LINES})}function C(e){e=s(e,s.EMPTY_OBJECT);var t=e.polylinePositions,r=e.shapePositions;this._positions=t,this._shape=r,this._ellipsoid=c.clone(s(e.ellipsoid,c.WGS84)),this._cornerType=s(e.cornerType,a.ROUNDED),this._granularity=s(e.granularity,m.RADIANS_PER_DEGREE),this._workerName="createPolylineVolumeOutlineGeometry";var o=1+t.length*n.packedLength;o+=1+r.length*i.packedLength,this.packedLength=o+c.packedLength+2}C.pack=function(e,t,r){r=s(r,0);var o,a=e._positions,l=a.length;for(t[r++]=l,o=0;o<l;++o,r+=n.packedLength)n.pack(a[o],t,r);var u=e._shape;for(l=u.length,t[r++]=l,o=0;o<l;++o,r+=i.packedLength)i.pack(u[o],t,r);return c.pack(e._ellipsoid,t,r),r+=c.packedLength,t[r++]=e._cornerType,t[r]=e._granularity,t};var S=c.clone(c.UNIT_SPHERE),w={polylinePositions:void 0,shapePositions:void 0,ellipsoid:S,height:void 0,cornerType:void 0,granularity:void 0};C.unpack=function(e,t,r){t=s(t,0);var o,a=e[t++],u=new Array(a);for(o=0;o<a;++o,t+=n.packedLength)u[o]=n.unpack(e,t);a=e[t++];var d=new Array(a);for(o=0;o<a;++o,t+=i.packedLength)d[o]=i.unpack(e,t);var h=c.unpack(e,t,S);t+=c.packedLength;var p=e[t++],f=e[t];return l(r)?(r._positions=u,r._shape=d,r._ellipsoid=c.clone(h,r._ellipsoid),r._cornerType=p,r._granularity=f,r):(w.polylinePositions=u,w.shapePositions=d,w.cornerType=p,w.granularity=f,new C(w))};var T=new t;return C.createGeometry=function(r){var i=r._positions,o=e(i,n.equalsEpsilon),a=r._shape;if(a=_.removeDuplicatesFromShape(a),!(o.length<2||a.length<3)){g.computeWindingOrder2D(a)===y.CLOCKWISE&&a.reverse();var s=t.fromPoints(a,T);return b(_.computePositions(o,a,s,r,!1),a)}},C}),define("Core/QuaternionSpline",["./defaultValue","./defined","./defineProperties","./DeveloperError","./Quaternion","./Spline"],function(e,t,r,i,n,o){"use strict";function a(e){var r=e.points,i=e.times;return function(o,a){t(a)||(a=new n);var s=e._lastTimeIndex=e.findTimeInterval(o,e._lastTimeIndex),l=(o-i[s])/(i[s+1]-i[s]),u=r[s],c=r[s+1];return n.fastSlerp(u,c,l,a)}}function s(t){t=e(t,e.EMPTY_OBJECT);var r=t.points,i=t.times;this._times=i,this._points=r,this._evaluateFunction=a(this),this._lastTimeIndex=0}return r(s.prototype,{times:{get:function(){return this._times}},points:{get:function(){return this._points}}}),s.prototype.findTimeInterval=o.prototype.findTimeInterval,s.prototype.wrapTime=o.prototype.wrapTime,s.prototype.clampTime=o.prototype.clampTime,s.prototype.evaluate=function(e,t){return this._evaluateFunction(e,t)},s}),define("Core/RectangleGeometryLibrary",["./Cartesian3","./Cartographic","./defined","./DeveloperError","./GeographicProjection","./Math","./Matrix2","./Rectangle"],function(e,t,r,i,n,o,a,s){"use strict";function l(t,r,i,n,o,s,l){var u=Math.cos(r),c=n*u,d=i*u,h=Math.sin(r),m=n*h,v=i*h;f=_.project(t,f),f=e.subtract(f,g,f);var y=a.fromRotation(r,p);f=a.multiplyByVector(y,f,f),f=e.add(f,g,f),t=_.unproject(f,t),s-=1,l-=1;var b=t.latitude,C=b+s*v,S=b-c*l,w=b-c*l+s*v,T=Math.max(b,C,S,w),E=Math.min(b,C,S,w),A=t.longitude,x=A+s*d,P=A+l*m,D=A+l*m+s*d;return{north:T,south:E,east:Math.max(A,x,P,D),west:Math.min(A,x,P,D),granYCos:c,granYSin:m,granXCos:d,granXSin:v,nwCorner:t}}var u=Math.cos,c=Math.sin,d=Math.sqrt,h={};h.computePosition=function(e,t,i,n,o){var a=e.ellipsoid.radiiSquared,s=e.nwCorner,l=e.rectangle,h=s.latitude-e.granYCos*t+i*e.granXSin,p=u(h),f=c(h),m=a.z*f,g=s.longitude+t*e.granYSin+i*e.granXCos,_=p*u(g),v=p*c(g),y=a.x*_,b=a.y*v,C=d(y*_+b*v+m*f);if(n.x=y/C,n.y=b/C,n.z=m/C,r(e.vertexFormat)&&e.vertexFormat.st){var S=e.stNwCorner;r(S)?(h=S.latitude-e.stGranYCos*t+i*e.stGranXSin,g=S.longitude+t*e.stGranYSin+i*e.stGranXCos,o.x=(g-e.stWest)*e.lonScalar,o.y=(h-e.stSouth)*e.latScalar):(o.x=(g-l.west)*e.lonScalar,o.y=(h-l.south)*e.latScalar)}};var p=new a,f=new e,m=new t,g=new e,_=new n;return h.computeOptions=function(e,t,r,i){var n,a,u,c,d,h=e._granularity,p=e._ellipsoid,f=e._surfaceHeight,v=e._rotation,y=e._stRotation,b=e._extrudedHeight,C=t.east,S=t.west,w=t.north,T=t.south,E=w-T;S>C?(d=o.TWO_PI-S+C,n=Math.ceil(d/h)+1,a=Math.ceil(E/h)+1,u=d/(n-1),c=E/(a-1)):(d=C-S,n=Math.ceil(d/h)+1,a=Math.ceil(E/h)+1,u=d/(n-1),c=E/(a-1)),r=s.northwest(t,r);var A=s.center(t,m);0===v&&0===y||(A.longitude<r.longitude&&(A.longitude+=o.TWO_PI),g=_.project(A,g));var x=c,P=u,D={granYCos:x,granYSin:0,granXCos:P,granXSin:0,ellipsoid:p,surfaceHeight:f,extrudedHeight:b,nwCorner:r,rectangle:t,width:n,height:a};if(0!==v){var I=l(r,v,u,c,A,n,a);w=I.north,T=I.south,C=I.east,S=I.west,D.granYCos=I.granYCos,D.granYSin=I.granYSin,D.granXCos=I.granXCos,D.granXSin=I.granXSin,t.north=w,t.south=T,t.east=C,t.west=S}if(0!==y){v-=y,i=s.northwest(t,i);var O=l(i,v,u,c,A,n,a);D.stGranYCos=O.granYCos,D.stGranXCos=O.granXCos,D.stGranYSin=O.granYSin,D.stGranXSin=O.granXSin,D.stNwCorner=i,D.stWest=O.west,D.stSouth=O.south}return D},h}),define("Core/RectangleGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./PolygonPipeline","./PrimitiveType","./Quaternion","./Rectangle","./RectangleGeometryLibrary","./VertexFormat"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T){"use strict";function E(e,t){var r=new d({attributes:new p,primitiveType:b.TRIANGLES});return r.attributes.position=new h({componentDatatype:o.DOUBLE,componentsPerAttribute:3,values:t.positions}),e.normal&&(r.attributes.normal=new h({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:t.normals})),e.tangent&&(r.attributes.tangent=new h({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:t.tangents})),e.bitangent&&(r.attributes.bitangent=new h({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:t.bitangents})),r}function A(e,t,i,n){var o=e.length,a=t.normal?new Float32Array(o):void 0,s=t.tangent?new Float32Array(o):void 0,l=t.bitangent?new Float32Array(o):void 0,u=0,c=F,d=k,h=N;if(t.normal||t.tangent||t.bitangent)for(var p=0;p<o;p+=3){var f=r.fromArray(e,p,L),m=u+1,g=u+2;h=i.geodeticSurfaceNormal(f,h),(t.tangent||t.bitangent)&&(r.cross(r.UNIT_Z,h,d),v.multiplyByVector(n,d,d),r.normalize(d,d),t.bitangent&&r.normalize(r.cross(h,d,c),c)),t.normal&&(a[u]=h.x,a[m]=h.y,a[g]=h.z),t.tangent&&(s[u]=d.x,s[m]=d.y,s[g]=d.z),t.bitangent&&(l[u]=c.x,l[m]=c.y,l[g]=c.z),u+=3}return E(t,{positions:e,normals:a,tangents:s,bitangents:l})}function x(e,t,i){var n=e.length,o=t.normal?new Float32Array(n):void 0,a=t.tangent?new Float32Array(n):void 0,s=t.bitangent?new Float32Array(n):void 0,l=0,u=0,c=0,d=!0,h=F,p=k,f=N;if(t.normal||t.tangent||t.bitangent)for(var m=0;m<n;m+=6){var g=r.fromArray(e,m,L),v=r.fromArray(e,(m+6)%n,G);if(d){var y=r.fromArray(e,(m+3)%n,W);r.subtract(v,g,v),r.subtract(y,g,y),f=r.normalize(r.cross(y,v,f),f),d=!1}r.equalsEpsilon(v,g,_.EPSILON10)&&(d=!0),(t.tangent||t.bitangent)&&(h=i.geodeticSurfaceNormal(g,h),t.tangent&&(p=r.normalize(r.cross(h,f,p),p))),t.normal&&(o[l++]=f.x,o[l++]=f.y,o[l++]=f.z,o[l++]=f.x,o[l++]=f.y,o[l++]=f.z),t.tangent&&(a[u++]=p.x,a[u++]=p.y,a[u++]=p.z,a[u++]=p.x,a[u++]=p.y,a[u++]=p.z),t.bitangent&&(s[c++]=h.x,s[c++]=h.y,s[c++]=h.z,s[c++]=h.x,s[c++]=h.y,s[c++]=h.z)}return E(t,{positions:e,normals:o,tangents:a,bitangents:s})}function P(e){for(var t=e.vertexFormat,r=e.ellipsoid,i=e.size,n=e.height,a=e.width,s=t.position?new Float64Array(3*i):void 0,l=t.st?new Float32Array(2*i):void 0,u=0,c=0,d=L,p=U,f=Number.MAX_VALUE,m=Number.MAX_VALUE,_=-Number.MAX_VALUE,v=-Number.MAX_VALUE,y=0;y<n;++y)for(var b=0;b<a;++b)w.computePosition(e,y,b,d,p),s[u++]=d.x,s[u++]=d.y,s[u++]=d.z,t.st&&(l[c++]=p.x,l[c++]=p.y,f=Math.min(f,p.x),m=Math.min(m,p.y),_=Math.max(_,p.x),v=Math.max(v,p.y));if(t.st&&(f<0||m<0||_>1||v>1))for(var C=0;C<l.length;C+=2)l[C]=(l[C]-f)/(_-f),l[C+1]=(l[C+1]-m)/(v-m);for(var S=A(s,t,r,e.tangentRotationMatrix),T=6*(a-1)*(n-1),E=g.createTypedArray(i,T),x=0,P=0,D=0;D<n-1;++D){for(var I=0;I<a-1;++I){var O=x,M=O+a,R=M+1,N=O+1;E[P++]=O,E[P++]=M,E[P++]=N,E[P++]=N,E[P++]=M,E[P++]=R,++x}++x}return S.indices=E,t.st&&(S.attributes.st=new h({componentDatatype:o.FLOAT,componentsPerAttribute:2,values:l})),S}function D(e,t,r,i,n){return e[t++]=i[r],e[t++]=i[r+1],e[t++]=i[r+2],e[t++]=n[r],e[t++]=n[r+1],e[t++]=n[r+2],e}function I(e,t,r,i){return e[t++]=i[r],e[t++]=i[r+1],e[t++]=i[r],e[t++]=i[r+1],e}function O(e){var t,i=e.shadowVolume,n=e.vertexFormat,a=e.surfaceHeight,s=e.extrudedHeight,l=Math.min(s,a),u=Math.max(s,a),c=e.height,d=e.width,p=e.ellipsoid;i&&(e.vertexFormat=T.clone(n,H),e.vertexFormat.normal=!0);var v=P(e);if(_.equalsEpsilon(l,u,_.EPSILON10))return v;var b=y.scaleToGeodeticHeight(v.attributes.position.values,u,p,!1);b=new Float64Array(b);var C=b.length,S=2*C,w=new Float64Array(S);w.set(b);var E=y.scaleToGeodeticHeight(v.attributes.position.values,l,p);w.set(E,C),v.attributes.position.values=w;var A,O,M=n.normal?new Float32Array(S):void 0,R=n.tangent?new Float32Array(S):void 0,L=n.bitangent?new Float32Array(S):void 0,N=n.st?new Float32Array(S/3*2):void 0;if(n.normal){for(O=v.attributes.normal.values,M.set(O),t=0;t<C;t++)O[t]=-O[t];M.set(O,C),v.attributes.normal.values=M}if(i){O=v.attributes.normal.values,n.normal||(v.attributes.normal=void 0);var k=new Float32Array(S);for(t=0;t<C;t++)O[t]=-O[t];k.set(O,C),v.attributes.extrudeDirection=new h({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:k})}if(n.tangent){var F=v.attributes.tangent.values;for(R.set(F),t=0;t<C;t++)F[t]=-F[t];R.set(F,C),v.attributes.tangent.values=R}if(n.bitangent){var B=v.attributes.bitangent.values;L.set(B),L.set(B,C),v.attributes.bitangent.values=L}n.st&&(A=v.attributes.st.values,N.set(A),N.set(A,C/3*2),v.attributes.st.values=N);var U=v.indices,V=U.length,z=C/3,j=g.createTypedArray(S/3,2*V);for(j.set(U),t=0;t<V;t+=3)j[t+V]=U[t+2]+z,j[t+1+V]=U[t+1]+z,j[t+2+V]=U[t]+z;v.indices=j;var q,Y=2*d+2*c-4,X=2*(Y+4),Q=new Float64Array(3*X),Z=i?new Float32Array(3*X):void 0,K=n.st?new Float32Array(2*X):void 0,J=0,$=0,ee=0,te=d*c;for(t=0;t<te;t+=d)q=3*t,Q=D(Q,J,q,b,E),J+=6,n.st&&(K=I(K,$,2*t,A),$+=4),i&&(ee+=3,Z[ee++]=O[q],Z[ee++]=O[q+1],Z[ee++]=O[q+2]);for(t=te-d;t<te;t++)q=3*t,Q=D(Q,J,q,b,E),J+=6,n.st&&(K=I(K,$,2*t,A),$+=4),i&&(ee+=3,Z[ee++]=O[q],Z[ee++]=O[q+1],Z[ee++]=O[q+2]);for(t=te-1;t>0;t-=d)q=3*t,Q=D(Q,J,q,b,E),J+=6,n.st&&(K=I(K,$,2*t,A),$+=4),i&&(ee+=3,Z[ee++]=O[q],Z[ee++]=O[q+1],Z[ee++]=O[q+2]);for(t=d-1;t>=0;t--)q=3*t,Q=D(Q,J,q,b,E),J+=6,n.st&&(K=I(K,$,2*t,A),$+=4),i&&(ee+=3,Z[ee++]=O[q],Z[ee++]=O[q+1],Z[ee++]=O[q+2]);var re=x(Q,n,p);n.st&&(re.attributes.st=new h({componentDatatype:o.FLOAT,componentsPerAttribute:2,values:K})),i&&(re.attributes.extrudeDirection=new h({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:Z}));var ie,ne,oe,ae,se=g.createTypedArray(X,6*Y);C=Q.length/3;var le=0;for(t=0;t<C-1;t+=2){ie=t,ae=(ie+2)%C;var ue=r.fromArray(Q,3*ie,G),ce=r.fromArray(Q,3*ae,W);r.equalsEpsilon(ue,ce,_.EPSILON10)||(ne=(ie+1)%C,oe=(ne+2)%C,se[le++]=ie,se[le++]=ne,se[le++]=ae,se[le++]=ae,se[le++]=ne,se[le++]=oe)}return re.indices=se,re=m.combineInstances([new f({geometry:v}),new f({geometry:re})]),re[0]}function M(e,t,r){if(0===r)return S.clone(e);S.northeast(e,Q[0]),S.northwest(e,Q[1]),S.southeast(e,Q[2]),S.southwest(e,Q[3]),t.cartographicArrayToCartesianArray(Q,X);var i=t.geodeticSurfaceNormalCartographic(S.center(e,q));C.fromAxisAngle(i,r,Y),v.fromQuaternion(Y,j);for(var n=0;n<4;++n)v.multiplyByVector(j,X[n],X[n]);return t.cartesianArrayToCartographicArray(X,Q),S.fromCartographicArray(Q)}function R(e){e=a(e,a.EMPTY_OBJECT);var t=e.rectangle,r=a(e.rotation,0);this._rectangle=t,this._granularity=a(e.granularity,_.RADIANS_PER_DEGREE),this._ellipsoid=c.clone(a(e.ellipsoid,c.WGS84)),this._surfaceHeight=a(e.height,0),this._rotation=r,this._stRotation=a(e.stRotation,0),this._vertexFormat=T.clone(a(e.vertexFormat,T.DEFAULT)),this._extrudedHeight=a(e.extrudedHeight,0),this._extrude=s(e.extrudedHeight),this._closeTop=a(e.closeTop,!0),this._closeBottom=a(e.closeBottom,!0),this._shadowVolume=a(e.shadowVolume,!1),this._workerName="createRectangleGeometry",this._rotatedRectangle=M(this._rectangle,this._ellipsoid,r)}var L=new r,N=new r,k=new r,F=new r,B=new S,U=new t,V=new e,z=new e,G=new r,W=new r,H=new T,j=new v,q=new r,Y=new C,X=[new r,new r,new r,new r],Q=[new i,new i,new i,new i];R.packedLength=S.packedLength+c.packedLength+T.packedLength+S.packedLength+9,R.pack=function(e,t,r){return r=a(r,0),S.pack(e._rectangle,t,r),r+=S.packedLength,c.pack(e._ellipsoid,t,r),r+=c.packedLength,T.pack(e._vertexFormat,t,r),r+=T.packedLength,S.pack(e._rotatedRectangle,t,r),r+=S.packedLength,t[r++]=e._granularity,t[r++]=e._surfaceHeight,t[r++]=e._rotation,t[r++]=e._stRotation,t[r++]=e._extrudedHeight,t[r++]=e._extrude?1:0,t[r++]=e._closeTop?1:0,t[r++]=e._closeBottom?1:0,t[r]=e._shadowVolume?1:0,t};var Z=new S,K=new S,J=c.clone(c.UNIT_SPHERE),$={rectangle:Z,ellipsoid:J,vertexFormat:H,granularity:void 0,height:void 0,rotation:void 0,stRotation:void 0,extrudedHeight:void 0,closeTop:void 0,closeBottom:void 0,shadowVolume:void 0};R.unpack=function(e,t,r){t=a(t,0);var i=S.unpack(e,t,Z);t+=S.packedLength;var n=c.unpack(e,t,J);t+=c.packedLength;var o=T.unpack(e,t,H);t+=T.packedLength;var l=S.unpack(e,t,K);t+=S.packedLength;var u=e[t++],d=e[t++],h=e[t++],p=e[t++],f=e[t++],m=1===e[t++],g=1===e[t++],_=1===e[t++],v=1===e[t];return s(r)?(r._rectangle=S.clone(i,r._rectangle),r._ellipsoid=c.clone(n,r._ellipsoid),r._vertexFormat=T.clone(o,r._vertexFormat),r._granularity=u,r._surfaceHeight=d,r._rotation=h,r._stRotation=p,r._extrudedHeight=m?f:void 0,r._extrude=m,r._closeTop=g,r._closeBottom=_,r._rotatedRectangle=l,r._shadowVolume=v,r):($.granularity=u,$.height=d,$.rotation=h,$.stRotation=p,$.extrudedHeight=m?f:void 0,$.closeTop=g,$.closeBottom=_,$.shadowVolume=v,new R($))};var ee=new v,te=new i,re=new i,ie=new C,ne=new i;return R.createGeometry=function(t){if(!_.equalsEpsilon(t._rectangle.north,t._rectangle.south,_.EPSILON10)&&!_.equalsEpsilon(t._rectangle.east,t._rectangle.west,_.EPSILON10)){var r=S.clone(t._rectangle,B),i=t._ellipsoid,n=t._surfaceHeight,o=t._extrude,a=t._extrudedHeight,s=t._rotation,l=t._stRotation,u=t._vertexFormat,c=w.computeOptions(t,r,te,re),h=ee;if(0!==l||0!==s){var p=S.center(r,ne),f=i.geodeticSurfaceNormalCartographic(p,G);C.fromAxisAngle(f,-l,ie),v.fromQuaternion(ie,h)}else v.clone(v.IDENTITY,h);c.lonScalar=1/t._rectangle.width,c.latScalar=1/t._rectangle.height,c.vertexFormat=u,c.rotation=s,c.stRotation=l,c.tangentRotationMatrix=h,c.size=c.width*c.height;var m,g;if(r=t._rectangle,o){c.shadowVolume=t._shadowVolume,m=O(c);var b=e.fromRectangle3D(r,i,n,z),T=e.fromRectangle3D(r,i,a,V);g=e.union(b,T)}else m=P(c),m.attributes.position.values=y.scaleToGeodeticHeight(m.attributes.position.values,n,i,!1),g=e.fromRectangle3D(r,i,n);return u.position||delete m.attributes.position,new d({attributes:m.attributes,indices:m.indices,primitiveType:m.primitiveType,boundingSphere:g})}},R.createShadowVolume=function(e,t,r){var i=e._granularity,n=e._ellipsoid,o=t(i,n),a=r(i,n);return new R({rectangle:e._rectangle,rotation:e._rotation,ellipsoid:n,stRotation:e._stRotation,granularity:i,extrudedHeight:a,height:o,closeTop:!0,closeBottom:!0,vertexFormat:T.POSITION_ONLY,shadowVolume:!0})},l(R.prototype,{rectangle:{get:function(){return this._rotatedRectangle}}}),R}),define("Core/RectangleOutlineGeometry",["./BoundingSphere","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Rectangle","./RectangleGeometryLibrary"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){var t,r=e.size,n=e.height,o=e.width,a=new Float64Array(3*r),s=0,h=0,p=S;for(t=0;t<o;t++)g.computePosition(e,h,t,p),a[s++]=p.x,a[s++]=p.y,a[s++]=p.z;for(t=o-1,h=1;h<n;h++)g.computePosition(e,h,t,p),a[s++]=p.x,a[s++]=p.y,a[s++]=p.z;for(h=n-1,t=o-2;t>=0;t--)g.computePosition(e,h,t,p),a[s++]=p.x,a[s++]=p.y,a[s++]=p.z;for(t=0,h=n-2;h>0;h--)g.computePosition(e,h,t,p),a[s++]=p.x,a[s++]=p.y,a[s++]=p.z;for(var m=a.length/3*2,_=d.createTypedArray(a.length/3,m),v=0,y=0;y<a.length/3-1;y++)_[v++]=y,_[v++]=y+1;_[v++]=a.length/3-1,_[v++]=0;var b=new l({attributes:new c,primitiveType:f.LINES});return b.attributes.position=new u({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:a}),b.indices=_,b}function v(e){var t=e.surfaceHeight,r=e.extrudedHeight,i=e.ellipsoid,n=Math.min(r,t),o=Math.max(r,t),a=_(e);if(h.equalsEpsilon(n,o,h.EPSILON10))return a;var s=e.height,l=e.width,u=p.scaleToGeodeticHeight(a.attributes.position.values,o,i,!1),c=u.length,f=new Float64Array(2*c);f.set(u);var m=p.scaleToGeodeticHeight(a.attributes.position.values,n,i);f.set(m,c),a.attributes.position.values=f;var g=f.length/3*2+8,v=d.createTypedArray(f.length/3,g);c=f.length/6;for(var y=0,b=0;b<c-1;b++)v[y++]=b,v[y++]=b+1,v[y++]=b+c,v[y++]=b+c+1;return v[y++]=c-1,v[y++]=0,v[y++]=c+c-1,v[y++]=c,v[y++]=0,v[y++]=c,v[y++]=l-1,v[y++]=c+l-1,v[y++]=l+s-2,v[y++]=l+s-2+c,v[y++]=2*l+s-3,v[y++]=2*l+s-3+c,a.indices=v,a}function y(e){e=n(e,n.EMPTY_OBJECT);var t=e.rectangle,r=n(e.granularity,h.RADIANS_PER_DEGREE),i=n(e.ellipsoid,s.WGS84),o=n(e.height,0),a=n(e.rotation,0),l=e.extrudedHeight;this._rectangle=t,this._granularity=r,this._ellipsoid=i,this._surfaceHeight=o,this._rotation=a,this._extrudedHeight=l,this._workerName="createRectangleOutlineGeometry"}var b=new e,C=new e,S=new t,w=new m;y.packedLength=m.packedLength+s.packedLength+5,y.pack=function(e,t,r){return r=n(r,0),m.pack(e._rectangle,t,r),r+=m.packedLength,s.pack(e._ellipsoid,t,r),r+=s.packedLength,t[r++]=e._granularity,t[r++]=e._surfaceHeight,t[r++]=e._rotation,t[r++]=o(e._extrudedHeight)?1:0,t[r]=n(e._extrudedHeight,0),t};var T=new m,E=s.clone(s.UNIT_SPHERE),A={rectangle:T,ellipsoid:E,granularity:void 0,height:void 0,rotation:void 0,extrudedHeight:void 0};y.unpack=function(e,t,r){t=n(t,0);var i=m.unpack(e,t,T);t+=m.packedLength;var a=s.unpack(e,t,E);t+=s.packedLength;var l=e[t++],u=e[t++],c=e[t++],d=e[t++],h=e[t];return o(r)?(r._rectangle=m.clone(i,r._rectangle),r._ellipsoid=s.clone(a,r._ellipsoid),r._surfaceHeight=u,r._rotation=c,r._extrudedHeight=d?h:void 0,r):(A.granularity=l,A.height=u,A.rotation=c,A.extrudedHeight=d?h:void 0,new y(A))};var x=new r;return y.createGeometry=function(t){var r=m.clone(t._rectangle,w),i=t._ellipsoid,n=t._surfaceHeight,a=t._extrudedHeight,s=g.computeOptions(t,r,x);s.size=2*s.width+2*s.height-4;var u,c;if(r=t._rectangle,!h.equalsEpsilon(r.north,r.south,h.EPSILON10)&&!h.equalsEpsilon(r.east,r.west,h.EPSILON10)){if(o(a)){u=v(s);var d=e.fromRectangle3D(r,i,n,C),y=e.fromRectangle3D(r,i,a,b);c=e.union(d,y)}else u=_(s),u.attributes.position.values=p.scaleToGeodeticHeight(u.attributes.position.values,n,i,!1),c=e.fromRectangle3D(r,i,n);return new l({attributes:u.attributes,indices:u.indices,primitiveType:f.LINES,boundingSphere:c})}},y}),define("Core/ReferenceFrame",["./freezeObject"],function(e){"use strict";return e({FIXED:0,INERTIAL:1})}),define("Core/requestAnimationFrame",["./defined","./getTimestamp"],function(e,t){"use strict";function r(e){return i(e)}if("undefined"!=typeof window){var i=window.requestAnimationFrame;return function(){ +if(!e(i))for(var r=["webkit","moz","ms","o"],n=0,o=r.length;n<o&&!e(i);)i=window[r[n]+"RequestAnimationFrame"],++n;if(!e(i)){var a=0;i=function(e){var r=t(),i=Math.max(1e3/60-(r-a),0);return a=r+i,setTimeout(function(){e(a)},i)}}}(),r}}),define("Core/sampleTerrain",["../ThirdParty/when","./Check"],function(e,t){"use strict";function r(e,t,r){return e.readyPromise.then(function(){return i(e,t,r)})}function i(t,r,i){var a,s=t.tilingScheme,l=[],u={};for(a=0;a<i.length;++a){var c=s.positionToTileXY(i[a],r),d=c.toString();if(!u.hasOwnProperty(d)){var h={x:c.x,y:c.y,level:r,tilingScheme:s,terrainProvider:t,positions:[]};u[d]=h,l.push(h)}u[d].positions.push(i[a])}var p=[];for(a=0;a<l.length;++a){var f=l[a],m=f.terrainProvider.requestTileGeometry(f.x,f.y,f.level),g=e(m,n(f),o(f));p.push(g)}return e.all(p,function(){return i})}function n(e){var t=e.positions,r=e.tilingScheme.tileXYToRectangle(e.x,e.y,e.level);return function(e){for(var i=0;i<t.length;++i){var n=t[i];n.height=e.interpolateHeight(r,n.longitude,n.latitude)}}}function o(e){var t=e.positions;return function(){for(var e=0;e<t.length;++e){t[e].height=void 0}}}return r}),define("Core/sampleTerrainMostDetailed",["../ThirdParty/when","./defined","./DeveloperError","./sampleTerrain"],function(e,t,r,i){"use strict";function n(r,n){return r.readyPromise.then(function(){for(var o=[],a=r.availability,s=0;s<n.length;++s){var l=n[s],u=a.computeMaximumLevelAtPosition(l),c=o[u];t(c)||(o[u]=c=[]),c.push(l)}return e.all(o.map(function(e,n){if(t(e))return i(r,n,e)})).then(function(){return n})})}return n}),define("Core/ScreenSpaceEventType",["./freezeObject"],function(e){"use strict";return e({LEFT_DOWN:0,LEFT_UP:1,LEFT_CLICK:2,LEFT_DOUBLE_CLICK:3,RIGHT_DOWN:5,RIGHT_UP:6,RIGHT_CLICK:7,MIDDLE_DOWN:10,MIDDLE_UP:11,MIDDLE_CLICK:12,MOUSE_MOVE:15,WHEEL:16,PINCH_START:17,PINCH_END:18,PINCH_MOVE:19})}),define("Core/ScreenSpaceEventHandler",["./AssociativeArray","./Cartesian2","./defaultValue","./defined","./destroyObject","./DeveloperError","./FeatureDetection","./getTimestamp","./KeyboardEventModifier","./ScreenSpaceEventType"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t,r){var i=e._element;if(i===document)return r.x=t.clientX,r.y=t.clientY,r;var n=i.getBoundingClientRect();return r.x=t.clientX-n.left,r.y=t.clientY-n.top,r}function d(e,t){var r=e;return i(t)&&(r+="+"+t),r}function h(e){return e.shiftKey?l.SHIFT:e.ctrlKey?l.CTRL:e.altKey?l.ALT:void 0}function p(e,t,r,i){function n(t){i(e,t)}r.addEventListener(t,n,!1),e._removalFunctions.push(function(){r.removeEventListener(t,n,!1)})}function f(e){var t=e._element,r=i(t.disableRootEvents)?t:document;a.supportsPointerEvents()?(p(e,"pointerdown",t,P),p(e,"pointerup",t,D),p(e,"pointermove",t,I),p(e,"pointercancel",t,D)):(p(e,"mousedown",t,v),p(e,"mouseup",r,y),p(e,"mousemove",r,b),p(e,"touchstart",t,w),p(e,"touchend",r,T),p(e,"touchmove",r,A),p(e,"touchcancel",r,T)),p(e,"dblclick",t,C);var n;n="onwheel"in t?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll",p(e,n,t,S)}function m(e){for(var t=e._removalFunctions,r=0;r<t.length;++r)t[r]()}function g(e){e._lastSeenTouchEvent=s()}function _(e){return s()-e._lastSeenTouchEvent>O.mouseEmulationIgnoreMilliseconds}function v(e,r){if(_(e)){var n=r.button;e._buttonDown=n;var o;if(n===M.LEFT)o=u.LEFT_DOWN;else if(n===M.MIDDLE)o=u.MIDDLE_DOWN;else{if(n!==M.RIGHT)return;o=u.RIGHT_DOWN}var a=c(e,r,e._primaryPosition);t.clone(a,e._primaryStartPosition),t.clone(a,e._primaryPreviousPosition);var s=h(r),l=e.getInputAction(o,s);i(l)&&(t.clone(a,R.position),l(R),r.preventDefault())}}function y(e,r){if(_(e)){var n=r.button;e._buttonDown=void 0;var o,a;if(n===M.LEFT)o=u.LEFT_UP,a=u.LEFT_CLICK;else if(n===M.MIDDLE)o=u.MIDDLE_UP,a=u.MIDDLE_CLICK;else{if(n!==M.RIGHT)return;o=u.RIGHT_UP,a=u.RIGHT_CLICK}var s=h(r),l=e.getInputAction(o,s),d=e.getInputAction(a,s);if(i(l)||i(d)){var p=c(e,r,e._primaryPosition);if(i(l)&&(t.clone(p,L.position),l(L)),i(d)){var f=e._primaryStartPosition,m=f.x-p.x,g=f.y-p.y;Math.sqrt(m*m+g*g)<e._clickPixelTolerance&&(t.clone(p,N.position),d(N))}}}}function b(e,r){if(_(e)){var n=h(r),o=c(e,r,e._primaryPosition),a=e._primaryPreviousPosition,s=e.getInputAction(u.MOUSE_MOVE,n);i(s)&&(t.clone(a,k.startPosition),t.clone(o,k.endPosition),s(k)),t.clone(o,a),i(e._buttonDown)&&r.preventDefault()}}function C(e,t){var r,n=t.button;if(n===M.LEFT){r=u.LEFT_DOUBLE_CLICK;var o=h(t),a=e.getInputAction(r,o);i(a)&&(c(e,t,F.position),a(F))}}function S(e,t){var r;if(i(t.deltaY)){var n=t.deltaMode;r=n===t.DOM_DELTA_PIXEL?-t.deltaY:n===t.DOM_DELTA_LINE?40*-t.deltaY:120*-t.deltaY}else r=t.detail>0?-120*t.detail:t.wheelDelta;if(i(r)){var o=h(t),a=e.getInputAction(u.WHEEL,o);i(a)&&(a(r),t.preventDefault())}}function w(e,r){g(e);var i,n,o,a=r.changedTouches,s=a.length,l=e._positions;for(i=0;i<s;++i)n=a[i],o=n.identifier,l.set(o,c(e,n,new t));E(e,r);var u=e._previousPositions;for(i=0;i<s;++i)n=a[i],o=n.identifier,u.set(o,t.clone(l.get(o)))}function T(e,t){g(e);var r,i,n,o=t.changedTouches,a=o.length,s=e._positions;for(r=0;r<a;++r)i=o[r],n=i.identifier,s.remove(n);E(e,t);var l=e._previousPositions;for(r=0;r<a;++r)i=o[r],n=i.identifier,l.remove(n)}function E(e,r){var n,o,a=h(r),s=e._positions,l=e._previousPositions,c=s.length;if(1!==c&&e._buttonDown===M.LEFT&&(e._buttonDown=void 0,n=e.getInputAction(u.LEFT_UP,a),i(n)&&(t.clone(e._primaryPosition,V.position),n(V)),0===c&&(o=e.getInputAction(u.LEFT_CLICK,a),i(o)))){var d=e._primaryStartPosition,p=l.values[0],f=d.x-p.x,m=d.y-p.y;Math.sqrt(f*f+m*m)<e._clickPixelTolerance&&(t.clone(e._primaryPosition,z.position),o(z))}if(2!==c&&e._isPinching&&(e._isPinching=!1,n=e.getInputAction(u.PINCH_END,a),i(n)&&n()),1===c){var g=s.values[0];t.clone(g,e._primaryPosition),t.clone(g,e._primaryStartPosition),t.clone(g,e._primaryPreviousPosition),e._buttonDown=M.LEFT,n=e.getInputAction(u.LEFT_DOWN,a),i(n)&&(t.clone(g,B.position),n(B)),r.preventDefault()}2===c&&(e._isPinching=!0,n=e.getInputAction(u.PINCH_START,a),i(n)&&(t.clone(s.values[0],U.position1),t.clone(s.values[1],U.position2),n(U),r.preventDefault()))}function A(e,r){g(e);var n,o,a,s=r.changedTouches,l=s.length,u=e._positions;for(n=0;n<l;++n){o=s[n],a=o.identifier;var d=u.get(a);i(d)&&c(e,o,d)}x(e,r);var h=e._previousPositions;for(n=0;n<l;++n)o=s[n],a=o.identifier,t.clone(u.get(a),h.get(a))}function x(e,r){var n,o=h(r),a=e._positions,s=e._previousPositions,l=a.length;if(1===l&&e._buttonDown===M.LEFT){var c=a.values[0];t.clone(c,e._primaryPosition);var d=e._primaryPreviousPosition;n=e.getInputAction(u.MOUSE_MOVE,o),i(n)&&(t.clone(d,G.startPosition),t.clone(c,G.endPosition),n(G)),t.clone(c,d),r.preventDefault()}else if(2===l&&e._isPinching&&(n=e.getInputAction(u.PINCH_MOVE,o),i(n))){var p=a.values[0],f=a.values[1],m=s.values[0],g=s.values[1],_=f.x-p.x,v=f.y-p.y,y=.25*Math.sqrt(_*_+v*v),b=g.x-m.x,C=g.y-m.y,S=.25*Math.sqrt(b*b+C*C),w=.125*(f.y+p.y),T=.125*(g.y+m.y),E=Math.atan2(v,_),A=Math.atan2(C,b);t.fromElements(0,S,W.distance.startPosition),t.fromElements(0,y,W.distance.endPosition),t.fromElements(A,T,W.angleAndHeight.startPosition),t.fromElements(E,w,W.angleAndHeight.endPosition),n(W)}}function P(e,r){if(r.target.setPointerCapture(r.pointerId),"touch"===r.pointerType){var i=e._positions,n=r.pointerId;i.set(n,c(e,r,new t)),E(e,r);e._previousPositions.set(n,t.clone(i.get(n)))}else v(e,r)}function D(e,t){if("touch"===t.pointerType){var r=e._positions,i=t.pointerId;r.remove(i),E(e,t);e._previousPositions.remove(i)}else y(e,t)}function I(e,r){if("touch"===r.pointerType){var n=e._positions,o=r.pointerId,a=n.get(o);if(!i(a))return;c(e,r,a),x(e,r);var s=e._previousPositions;t.clone(n.get(o),s.get(o))}else b(e,r)}function O(i){this._inputEvents={},this._buttonDown=void 0,this._isPinching=!1,this._lastSeenTouchEvent=-O.mouseEmulationIgnoreMilliseconds,this._primaryStartPosition=new t,this._primaryPosition=new t,this._primaryPreviousPosition=new t,this._positions=new e,this._previousPositions=new e,this._removalFunctions=[],this._clickPixelTolerance=5,this._element=r(i,document),f(this)}var M={LEFT:0,MIDDLE:1,RIGHT:2},R={position:new t},L={position:new t},N={position:new t},k={startPosition:new t,endPosition:new t},F={position:new t},B={position:new t},U={position1:new t,position2:new t},V={position:new t},z={position:new t},G={startPosition:new t,endPosition:new t},W={distance:{startPosition:new t,endPosition:new t},angleAndHeight:{startPosition:new t,endPosition:new t}};return O.prototype.setInputAction=function(e,t,r){var i=d(t,r);this._inputEvents[i]=e},O.prototype.getInputAction=function(e,t){var r=d(e,t);return this._inputEvents[r]},O.prototype.removeInputAction=function(e,t){var r=d(e,t);delete this._inputEvents[r]},O.prototype.isDestroyed=function(){return!1},O.prototype.destroy=function(){return m(this),n(this)},O.mouseEmulationIgnoreMilliseconds=800,O}),define("Core/ShowGeometryInstanceAttribute",["./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError"],function(e,t,r,i,n){"use strict";function o(e){e=t(e,!0),this.value=o.toValue(e)}return i(o.prototype,{componentDatatype:{get:function(){return e.UNSIGNED_BYTE}},componentsPerAttribute:{get:function(){return 1}},normalize:{get:function(){return!1}}}),o.toValue=function(e,t){return r(t)?(t[0]=e,t):new Uint8Array([e])},o}),define("Core/Simon1994PlanetaryPositions",["./Cartesian3","./defined","./DeveloperError","./JulianDate","./Math","./Matrix3","./TimeConstants","./TimeStandard"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){var t=6.239996+.0172019696544*e;return.001657*Math.sin(t+.01671*Math.sin(t))}function u(e,t){t=i.addSeconds(e,b,t);var r=i.totalDays(t)-C;return t=i.addSeconds(t,l(r),t)}function c(r,i,a,s,l,u,c){a<0&&(a=-a,l+=n.PI);var p=r*(1-i),f=s-l,g=l,_=h(u-s,i);d(i,0);m(f,a,g,A);var v=p*(1+i),y=Math.cos(_),b=Math.sin(_),C=1+i*y,S=v/C;return t(c)?(c.x=S*y,c.y=S*b,c.z=0):c=new e(S*y,S*b,0),o.multiplyByVector(A,c,c)}function d(e,t){return e<=t?"Circular":e<1-t?"Elliptical":e<=1+t?"Parabolic":"Hyperbolic"}function h(e,t){return f(p(e,t),t)}function p(e,t){var r=Math.floor(e/n.TWO_PI);e-=r*n.TWO_PI;var i,o=e+t*Math.sin(e)/(1-Math.sin(e+t)+Math.sin(e)),a=Number.MAX_VALUE;for(i=0;i<x&&Math.abs(a-o)>P;++i){a=o;o=a-(a-t*Math.sin(a)-e)/(1-t*Math.cos(a))}return a=o+r*n.TWO_PI}function f(e,t){var r=Math.floor(e/n.TWO_PI);e-=r*n.TWO_PI;var i=Math.cos(e)-t,o=Math.sin(e)*Math.sqrt(1-t*t),a=Math.atan2(o,i);return a=n.zeroToTwoPi(a),e<0&&(a-=n.TWO_PI),a+=r*n.TWO_PI}function m(e,r,i,n){var a=Math.cos(e),s=Math.sin(e),l=Math.cos(r),u=Math.sin(r),c=Math.cos(i),d=Math.sin(i);return t(n)?(n[0]=c*a-d*s*l,n[1]=d*a+c*s*l,n[2]=s*u,n[3]=-c*s-d*a*l,n[4]=-d*s+c*a*l,n[5]=a*u,n[6]=d*u,n[7]=-c*u,n[8]=l):n=new o(c*a-d*s*l,-c*s-d*a*l,d*u,d*a+c*s*l,-d*s+c*a*l,-c*u,s*u,a*u,l),n}function g(e,t){u(e,Ae);var r=Ae.dayNumber-S.dayNumber+(Ae.secondsOfDay-S.secondsOfDay)/a.SECONDS_PER_DAY,i=r/(10*a.DAYS_PER_JULIAN_CENTURY),n=.3595362*i,o=D+V*Math.cos(M*n)+X*Math.sin(M*n)+z*Math.cos(R*n)+Q*Math.sin(R*n)+G*Math.cos(L*n)+Z*Math.sin(L*n)+W*Math.cos(N*n)+K*Math.sin(N*n)+H*Math.cos(k*n)+J*Math.sin(k*n)+j*Math.cos(F*n)+$*Math.sin(F*n)+q*Math.cos(B*n)+ee*Math.sin(B*n)+Y*Math.cos(U*n)+te*Math.sin(U*n),s=I+O*i+ce*Math.cos(re*n)+ve*Math.sin(re*n)+de*Math.cos(ie*n)+ye*Math.sin(ie*n)+he*Math.cos(ne*n)+be*Math.sin(ne*n)+pe*Math.cos(oe*n)+Ce*Math.sin(oe*n)+fe*Math.cos(ae*n)+Se*Math.sin(ae*n)+me*Math.cos(se*n)+we*Math.sin(se*n)+ge*Math.cos(le*n)+Te*Math.sin(le*n)+_e*Math.cos(ue*n)+Ee*Math.sin(ue*n);return c(o,.0167086342-.0004203654*i,469.97289*E*i,102.93734808*T+11612.3529*E*i,174.87317577*T-8679.27034*E*i,s,t)}function _(e,t){u(e,Ae);var r=Ae.dayNumber-S.dayNumber+(Ae.secondsOfDay-S.secondsOfDay)/a.SECONDS_PER_DAY,i=r/a.DAYS_PER_JULIAN_CENTURY,n=i*i,o=n*i,s=o*i,l=383397.7725+.004*i,d=.055545526-1.6e-8*i,h=5.15668983*T,p=-8e-5*i+.02966*n-42e-6*o-1.3e-7*s,f=83.35324312*T,m=14643420.2669*i-38.2702*n-.045047*o+21301e-8*s,g=125.04455501*T,_=-6967919.3631*i+6.3602*n+.007625*o-3586e-8*s,v=218.31664563*T,y=1732559343.4847*i-6.391*n+.006588*o-3169e-8*s,b=297.85019547*T+E*(1602961601.209*i-6.3706*n+.006593*o-3169e-8*s),C=93.27209062*T+E*(1739527262.8478*i-12.7512*n-.001037*o+417e-8*s),A=134.96340251*T+E*(1717915923.2178*i+31.8792*n+.051635*o-2447e-7*s),x=357.52910918*T+E*(129596581.0481*i-.5532*n+136e-6*o-1149e-8*s),P=310.17137918*T-E*(6967051.436*i+6.2068*n+.007618*o-3219e-8*s),D=2*b,I=4*b,O=6*b,M=2*A,R=3*A,L=4*A,N=2*C;l+=3400.4*Math.cos(D)-635.6*Math.cos(D-A)-235.6*Math.cos(A)+218.1*Math.cos(D-x)+181*Math.cos(D+A),d+=.014216*Math.cos(D-A)+.008551*Math.cos(D-M)-.001383*Math.cos(A)+.001356*Math.cos(D+A)-.001147*Math.cos(I-R)-914e-6*Math.cos(I-M)+869e-6*Math.cos(D-x-A)-627e-6*Math.cos(D)-394e-6*Math.cos(I-L)+282e-6*Math.cos(D-x-M)-279e-6*Math.cos(b-A)-236e-6*Math.cos(M)+231e-6*Math.cos(I)+229e-6*Math.cos(O-L)-201e-6*Math.cos(M-N),p+=486.26*Math.cos(D-N)-40.13*Math.cos(D)+37.51*Math.cos(N)+25.73*Math.cos(M-N)+19.97*Math.cos(D-x-N),m+=-55609*Math.sin(D-A)-34711*Math.sin(D-M)-9792*Math.sin(A)+9385*Math.sin(I-R)+7505*Math.sin(I-M)+5318*Math.sin(D+A)+3484*Math.sin(I-L)-3417*Math.sin(D-x-A)-2530*Math.sin(O-L)-2376*Math.sin(D)-2075*Math.sin(D-R)-1883*Math.sin(M)-1736*Math.sin(O-5*A)+1626*Math.sin(x)-1370*Math.sin(O-R),_+=-5392*Math.sin(D-N)-540*Math.sin(x)-441*Math.sin(D)+423*Math.sin(N)-288*Math.sin(M-N),y+=-3332.9*Math.sin(D)+1197.4*Math.sin(D-A)-662.5*Math.sin(x)+396.3*Math.sin(A)-218*Math.sin(D-x);var k=2*P,F=3*P;p+=46.997*Math.cos(P)*i-.614*Math.cos(D-N+P)*i+.614*Math.cos(D-N-P)*i-.0297*Math.cos(k)*n-.0335*Math.cos(P)*n+.0012*Math.cos(D-N+k)*n-16e-5*Math.cos(P)*o+4e-5*Math.cos(F)*o+4e-5*Math.cos(k)*o;var B=2.116*Math.sin(P)*i-.111*Math.sin(D-N-P)*i-.0015*Math.sin(P)*n;return m+=B,y+=B,_+=-520.77*Math.sin(P)*i+13.66*Math.sin(D-N+P)*i+1.12*Math.sin(D-P)*i-1.06*Math.sin(N-P)*i+.66*Math.sin(k)*n+.371*Math.sin(P)*n-.035*Math.sin(D-N+k)*n-.015*Math.sin(D-N+P)*n+.0014*Math.sin(P)*o-.0011*Math.sin(F)*o-9e-4*Math.sin(k)*o,l*=w,c(l,d,h+p*E,f+m*E,g+_*E,v+y*E,t)}function v(t,r){return r=_(t,r),e.multiplyByScalar(r,xe,r)}var y={},b=32.184,C=2451545,S=new i(2451545,0,s.TAI),w=1e3,T=n.RADIANS_PER_DEGREE,E=n.RADIANS_PER_ARCSECOND,A=new o,x=50,P=n.EPSILON8,D=149598022260.7121,I=100.46645683*T,O=1295977422.83429*E,M=16002,R=21863,L=32004,N=10931,k=14529,F=16368,B=15318,U=32794,V=64e-7*14959787e4,z=-2273887.624,G=927506.794,W=14959787e4*-8e-7,H=32e-7*14959787e4,j=-613351.267,q=284235.953,Y=-164557.657,X=-2243968.05,Q=-688150.202,Z=1017265.516,K=807828.498,J=14e-7*14959787e4,$=359034.888,ee=14959787e4*-28e-7,te=329115.314,re=10,ie=16002,ne=21863,oe=10931,ae=1473,se=32004,le=4387,ue=73,ce=-325e-7,de=-322e-7,he=1e-7*-79,pe=232*1e-7,fe=1e-7*-52,me=97e-7,ge=55e-7,_e=-41e-7,ve=-105e-7,ye=-137e-7,be=258e-7,Ce=35e-7,Se=1e-7*-116,we=-88e-7,Te=-112e-7,Ee=-8e-6,Ae=new i(0,0,s.TAI),xe=-.01215058143522694,Pe=new o(1.0000000000000002,5.619723173785822e-16,4.690511510146299e-19,-5.154129427414611e-16,.9174820620691819,-.39777715593191376,-2.23970096136568e-16,.39777715593191376,.9174820620691819),De=new e;return y.computeSunPositionInEarthInertialFrame=function(r,n){return t(r)||(r=i.now()),t(n)||(n=new e),De=g(r,De),n=e.negate(De,n),v(r,De),e.subtract(n,De,n),o.multiplyByVector(Pe,n,n),n},y.computeMoonPositionInEarthInertialFrame=function(e,r){return t(e)||(e=i.now()),r=_(e,r),o.multiplyByVector(Pe,r,r),r},y}),define("Core/SimplePolylineGeometry",["./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e,t,i,n,o,a,s){var l,u=p.numberOfPoints(e,t,o),c=i.red,d=i.green,h=i.blue,f=i.alpha,m=n.red,g=n.green,_=n.blue,v=n.alpha;if(r.equals(i,n)){for(l=0;l<u;l++)a[s++]=r.floatToByte(c),a[s++]=r.floatToByte(d),a[s++]=r.floatToByte(h),a[s++]=r.floatToByte(f);return s}var y=(m-c)/u,b=(g-d)/u,C=(_-h)/u,S=(v-f)/u,w=s;for(l=0;l<u;l++)a[w++]=r.floatToByte(c+l*y),a[w++]=r.floatToByte(d+l*b),a[w++]=r.floatToByte(h+l*C),a[w++]=r.floatToByte(f+l*S);return w}function g(e){e=n(e,n.EMPTY_OBJECT);var i=e.positions,a=e.colors,l=n(e.colorsPerVertex,!1);this._positions=i,this._colors=a,this._colorsPerVertex=l,this._followSurface=n(e.followSurface,!0),this._granularity=n(e.granularity,h.RADIANS_PER_DEGREE),this._ellipsoid=n(e.ellipsoid,s.WGS84),this._workerName="createSimplePolylineGeometry";var u=1+i.length*t.packedLength;u+=o(a)?1+a.length*r.packedLength:1,this.packedLength=u+s.packedLength+3}g.pack=function(e,i,a){a=n(a,0);var l,u=e._positions,c=u.length;for(i[a++]=c,l=0;l<c;++l,a+=t.packedLength)t.pack(u[l],i,a);var d=e._colors;for(c=o(d)?d.length:0,i[a++]=c,l=0;l<c;++l,a+=r.packedLength)r.pack(d[l],i,a);return s.pack(e._ellipsoid,i,a),a+=s.packedLength,i[a++]=e._colorsPerVertex?1:0,i[a++]=e._followSurface?1:0,i[a]=e._granularity,i},g.unpack=function(e,i,a){i=n(i,0);var l,u=e[i++],c=new Array(u);for(l=0;l<u;++l,i+=t.packedLength)c[l]=t.unpack(e,i);u=e[i++];var d=u>0?new Array(u):void 0;for(l=0;l<u;++l,i+=r.packedLength)d[l]=r.unpack(e,i);var h=s.unpack(e,i);i+=s.packedLength;var p=1===e[i++],f=1===e[i++],m=e[i];return o(a)?(a._positions=c,a._colors=d,a._ellipsoid=h,a._colorsPerVertex=p,a._followSurface=f,a._granularity=m,a):new g({positions:c,colors:d,ellipsoid:h,colorsPerVertex:p,followSurface:f,granularity:m})};var _=new Array(2),v=new Array(2),y={positions:_,height:v,ellipsoid:void 0,minDistance:void 0};return g.createGeometry=function(n){var a,s,g,b,C,S=n._positions,w=n._colors,T=n._colorsPerVertex,E=n._followSurface,A=n._granularity,x=n._ellipsoid,P=h.chordLength(A,x.maximumRadius),D=o(w)&&!T,I=S.length,O=0;if(E){var M=p.extractHeights(S,x),R=y;if(R.minDistance=P,R.ellipsoid=x,D){var L=0;for(a=0;a<I-1;a++)L+=p.numberOfPoints(S[a],S[a+1],P)+1;s=new Float64Array(3*L),b=new Uint8Array(4*L),R.positions=_,R.height=v;var N=0;for(a=0;a<I-1;++a){_[0]=S[a],_[1]=S[a+1],v[0]=M[a],v[1]=M[a+1];var k=p.generateArc(R);if(o(w)){var F=k.length/3;C=w[a];for(var B=0;B<F;++B)b[N++]=r.floatToByte(C.red),b[N++]=r.floatToByte(C.green),b[N++]=r.floatToByte(C.blue),b[N++]=r.floatToByte(C.alpha)}s.set(k,O),O+=k.length}}else if(R.positions=S,R.height=M,s=new Float64Array(p.generateArc(R)),o(w)){for(b=new Uint8Array(s.length/3*4),a=0;a<I-1;++a){var U=S[a],V=S[a+1],z=w[a],G=w[a+1];O=m(U,V,z,G,P,b,O)}var W=w[I-1];b[O++]=r.floatToByte(W.red),b[O++]=r.floatToByte(W.green),b[O++]=r.floatToByte(W.blue),b[O++]=r.floatToByte(W.alpha)}}else{g=D?2*I-2:I,s=new Float64Array(3*g),b=o(w)?new Uint8Array(4*g):void 0;var H=0,j=0;for(a=0;a<I;++a){var q=S[a];if(D&&a>0&&(t.pack(q,s,H),H+=3,C=w[a-1],b[j++]=r.floatToByte(C.red),b[j++]=r.floatToByte(C.green),b[j++]=r.floatToByte(C.blue),b[j++]=r.floatToByte(C.alpha)),D&&a===I-1)break;t.pack(q,s,H),H+=3,o(w)&&(C=w[a],b[j++]=r.floatToByte(C.red),b[j++]=r.floatToByte(C.green),b[j++]=r.floatToByte(C.blue),b[j++]=r.floatToByte(C.alpha))}}var Y=new c;Y.position=new u({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:s}),o(w)&&(Y.color=new u({componentDatatype:i.UNSIGNED_BYTE,componentsPerAttribute:4,values:b,normalize:!0})),g=s.length/3;var X=2*(g-1),Q=d.createTypedArray(g,X),Z=0;for(a=0;a<g-1;++a)Q[Z++]=a,Q[Z++]=a+1;return new l({attributes:Y,indices:Q,primitiveType:f.LINES,boundingSphere:e.fromPoints(S)})},g}),define("Core/SphereGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipsoidGeometry","./VertexFormat"],function(e,t,r,i,n,o){"use strict";function a(t){var i=r(t.radius,1),o=new e(i,i,i),a={radii:o,stackPartitions:t.stackPartitions,slicePartitions:t.slicePartitions,vertexFormat:t.vertexFormat};this._ellipsoidGeometry=new n(a),this._workerName="createSphereGeometry"}a.packedLength=n.packedLength,a.pack=function(e,t,r){return n.pack(e._ellipsoidGeometry,t,r)};var s=new n,l={radius:void 0,radii:new e,vertexFormat:new o,stackPartitions:void 0,slicePartitions:void 0};return a.unpack=function(t,r,u){var c=n.unpack(t,r,s);return l.vertexFormat=o.clone(c._vertexFormat,l.vertexFormat),l.stackPartitions=c._stackPartitions,l.slicePartitions=c._slicePartitions,i(u)?(e.clone(c._radii,l.radii),u._ellipsoidGeometry=new n(l),u):(l.radius=c._radii.x,new a(l))},a.createGeometry=function(e){return n.createGeometry(e._ellipsoidGeometry)},a}),define("Core/SphereOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipsoidOutlineGeometry"],function(e,t,r,i,n){"use strict";function o(t){var i=r(t.radius,1),o=new e(i,i,i),a={radii:o,stackPartitions:t.stackPartitions,slicePartitions:t.slicePartitions,subdivisions:t.subdivisions};this._ellipsoidGeometry=new n(a),this._workerName="createSphereOutlineGeometry"}o.packedLength=n.packedLength,o.pack=function(e,t,r){return n.pack(e._ellipsoidGeometry,t,r)};var a=new n,s={radius:void 0,radii:new e,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return o.unpack=function(t,r,l){var u=n.unpack(t,r,a);return s.stackPartitions=u._stackPartitions,s.slicePartitions=u._slicePartitions,s.subdivisions=u._subdivisions,i(l)?(e.clone(u._radii,s.radii),l._ellipsoidGeometry=new n(s),l):(s.radius=u._radii.x,new o(s))},o.createGeometry=function(e){return n.createGeometry(e._ellipsoidGeometry)},o}),define("Core/Spherical",["./Check","./defaultValue","./defined"],function(e,t,r){"use strict";function i(e,r,i){this.clock=t(e,0),this.cone=t(r,0),this.magnitude=t(i,1)}return i.fromCartesian3=function(e,t){var n=e.x,o=e.y,a=e.z,s=n*n+o*o;return r(t)||(t=new i),t.clock=Math.atan2(o,n),t.cone=Math.atan2(Math.sqrt(s),a),t.magnitude=Math.sqrt(s+a*a),t},i.clone=function(e,t){if(r(e))return r(t)?(t.clock=e.clock,t.cone=e.cone,t.magnitude=e.magnitude,t):new i(e.clock,e.cone,e.magnitude)},i.normalize=function(e,t){return r(t)?(t.clock=e.clock,t.cone=e.cone,t.magnitude=1,t):new i(e.clock,e.cone,1)},i.equals=function(e,t){return e===t||r(e)&&r(t)&&e.clock===t.clock&&e.cone===t.cone&&e.magnitude===t.magnitude},i.equalsEpsilon=function(e,i,n){return n=t(n,0),e===i||r(e)&&r(i)&&Math.abs(e.clock-i.clock)<=n&&Math.abs(e.cone-i.cone)<=n&&Math.abs(e.magnitude-i.magnitude)<=n},i.prototype.equals=function(e){return i.equals(this,e)},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.equalsEpsilon=function(e,t){return i.equalsEpsilon(this,e,t)},i.prototype.toString=function(){return"("+this.clock+", "+this.cone+", "+this.magnitude+")"},i}),define("Core/subdivideArray",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e,t){for(var r=[],i=e.length,n=0;n<i;){var o=Math.ceil((i-n)/t--);r.push(e.slice(n,n+o)),n+=o}return r}return r}),define("Core/TerrainData",["./defineProperties","./DeveloperError"],function(e,t){"use strict";function r(){t.throwInstantiationError()}return e(r.prototype,{credits:{get:t.throwInstantiationError},waterMask:{get:t.throwInstantiationError}}),r.prototype.interpolateHeight=t.throwInstantiationError,r.prototype.isChildAvailable=t.throwInstantiationError,r.prototype.createMesh=t.throwInstantiationError,r.prototype.upsample=t.throwInstantiationError,r.prototype.wasCreatedByUpsampling=t.throwInstantiationError,r}),define("Core/TilingScheme",["./defineProperties","./DeveloperError"],function(e,t){"use strict";function r(e){}return e(r.prototype,{ellipsoid:{get:t.throwInstantiationError},rectangle:{get:t.throwInstantiationError},projection:{get:t.throwInstantiationError}}),r.prototype.getNumberOfXTilesAtLevel=t.throwInstantiationError,r.prototype.getNumberOfYTilesAtLevel=t.throwInstantiationError,r.prototype.rectangleToNativeRectangle=t.throwInstantiationError,r.prototype.tileXYToNativeRectangle=t.throwInstantiationError,r.prototype.tileXYToRectangle=t.throwInstantiationError,r.prototype.positionToTileXY=t.throwInstantiationError,r}),define("Core/TimeIntervalCollection",["./binarySearch","./defaultValue","./defined","./defineProperties","./DeveloperError","./Event","./GregorianDate","./isLeapYear","./Iso8601","./JulianDate","./TimeInterval"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,t){return u.compare(e.start,t.start)}function h(e){if(this._intervals=[],this._changedEvent=new o,r(e))for(var t=e.length,i=0;i<t;i++)this.addInterval(e[i])}function p(e,t,i){r(i)||(i=new u),u.toGregorianDate(e,g);var n=g.millisecond+t.millisecond,o=g.second+t.second,a=g.minute+t.minute,l=g.hour+t.hour,c=g.day+t.day,d=g.month+t.month,h=g.year+t.year;for(n>=1e3&&(o+=Math.floor(n/1e3),n%=1e3),o>=60&&(a+=Math.floor(o/60),o%=60),a>=60&&(l+=Math.floor(a/60),a%=60),l>=24&&(c+=Math.floor(l/24),l%=24),_[2]=s(h)?29:28;c>_[d]||d>=13;)c>_[d]&&(c-=_[d],++d),d>=13&&(--d,h+=Math.floor(d/12),d%=12,++d),_[2]=s(h)?29:28;return g.millisecond=n,g.second=o,g.minute=a,g.hour=l,g.day=c,g.month=d,g.year=h,u.fromGregorianDate(g,i)}function f(e,t){if(!r(e)||0===e.length)return!1;if(t.year=0,t.month=0,t.day=0,t.hour=0,t.minute=0,t.second=0,t.millisecond=0,"P"===e[0]){var i=e.match(y);if(!r(i))return!1;if(r(i[1])&&(t.year=Number(i[1].replace(",","."))),r(i[2])&&(t.month=Number(i[2].replace(",","."))),r(i[3])&&(t.day=7*Number(i[3].replace(",","."))),r(i[4])&&(t.day+=Number(i[4].replace(",","."))),r(i[5])&&(t.hour=Number(i[5].replace(",","."))),r(i[6])&&(t.minute=Number(i[6].replace(",","."))),r(i[7])){var n=Number(i[7].replace(",","."));t.second=Math.floor(n),t.millisecond=n%1*1e3}}else"Z"!==e[e.length-1]&&(e+="Z"),u.toGregorianDate(u.fromIso8601(e,v),t);return t.year||t.month||t.day||t.hour||t.minute||t.second||t.millisecond}i(h.prototype,{changedEvent:{get:function(){return this._changedEvent}},start:{get:function(){var e=this._intervals;return 0===e.length?void 0:e[0].start}},isStartIncluded:{get:function(){var e=this._intervals;return 0!==e.length&&e[0].isStartIncluded}},stop:{get:function(){var e=this._intervals,t=e.length;return 0===t?void 0:e[t-1].stop}},isStopIncluded:{get:function(){var e=this._intervals,t=e.length;return 0!==t&&e[t-1].isStopIncluded}},length:{get:function(){return this._intervals.length}},isEmpty:{get:function(){return 0===this._intervals.length}}}),h.prototype.equals=function(e,t){if(this===e)return!0;if(!(e instanceof h))return!1;var r=this._intervals,i=e._intervals,n=r.length;if(n!==i.length)return!1;for(var o=0;o<n;o++)if(!c.equals(r[o],i[o],t))return!1;return!0},h.prototype.get=function(e){return this._intervals[e]},h.prototype.removeAll=function(){this._intervals.length>0&&(this._intervals.length=0,this._changedEvent.raiseEvent(this))},h.prototype.findIntervalContainingDate=function(e){var t=this.indexOf(e);return t>=0?this._intervals[t]:void 0},h.prototype.findDataForIntervalContainingDate=function(e){var t=this.indexOf(e);return t>=0?this._intervals[t].data:void 0},h.prototype.contains=function(e){return this.indexOf(e)>=0};var m=new c;h.prototype.indexOf=function(t){var r=this._intervals;m.start=t,m.stop=t;var i=e(r,m,d);return i>=0?r[i].isStartIncluded?i:i>0&&r[i-1].stop.equals(t)&&r[i-1].isStopIncluded?i-1:~i:(i=~i,i>0&&i-1<r.length&&c.contains(r[i-1],t)?i-1:~i)},h.prototype.findInterval=function(e){e=t(e,t.EMPTY_OBJECT);for(var i=e.start,n=e.stop,o=e.isStartIncluded,a=e.isStopIncluded,s=this._intervals,l=0,u=s.length;l<u;l++){var c=s[l];if((!r(i)||c.start.equals(i))&&(!r(n)||c.stop.equals(n))&&(!r(o)||c.isStartIncluded===o)&&(!r(a)||c.isStopIncluded===a))return s[l]}},h.prototype.addInterval=function(t,i){if(!t.isEmpty){var n,o,a=this._intervals;if(0===a.length||u.greaterThan(t.start,a[a.length-1].stop))return a.push(t),void this._changedEvent.raiseEvent(this);for(o=e(a,t,d),o<0?o=~o:o>0&&t.isStartIncluded&&a[o-1].isStartIncluded&&a[o-1].start.equals(t.start)?--o:o<a.length&&!t.isStartIncluded&&a[o].isStartIncluded&&a[o].start.equals(t.start)&&++o,o>0&&((n=u.compare(a[o-1].stop,t.start))>0||0===n&&(a[o-1].isStopIncluded||t.isStartIncluded))&&((r(i)?i(a[o-1].data,t.data):a[o-1].data===t.data)?(t=new c(u.greaterThan(t.stop,a[o-1].stop)?{start:a[o-1].start,stop:t.stop,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:t.isStopIncluded,data:t.data}:{start:a[o-1].start,stop:a[o-1].stop,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:a[o-1].isStopIncluded||t.stop.equals(a[o-1].stop)&&t.isStopIncluded,data:t.data}),a.splice(o-1,1),--o):(n=u.compare(a[o-1].stop,t.stop),n>0||0===n&&a[o-1].isStopIncluded&&!t.isStopIncluded?a.splice(o-1,1,new c({start:a[o-1].start,stop:t.start,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:!t.isStartIncluded,data:a[o-1].data}),new c({start:t.stop,stop:a[o-1].stop,isStartIncluded:!t.isStopIncluded,isStopIncluded:a[o-1].isStopIncluded,data:a[o-1].data})):a[o-1]=new c({start:a[o-1].start,stop:t.start,isStartIncluded:a[o-1].isStartIncluded,isStopIncluded:!t.isStartIncluded,data:a[o-1].data})));o<a.length&&((n=u.compare(t.stop,a[o].start))>0||0===n&&(t.isStopIncluded||a[o].isStartIncluded));)if(r(i)?i(a[o].data,t.data):a[o].data===t.data)t=new c({start:t.start,stop:u.greaterThan(a[o].stop,t.stop)?a[o].stop:t.stop,isStartIncluded:t.isStartIncluded,isStopIncluded:u.greaterThan(a[o].stop,t.stop)?a[o].isStopIncluded:t.isStopIncluded,data:t.data}),a.splice(o,1);else{if(a[o]=new c({start:t.stop,stop:a[o].stop,isStartIncluded:!t.isStopIncluded,isStopIncluded:a[o].isStopIncluded,data:a[o].data}),!a[o].isEmpty)break;a.splice(o,1)}a.splice(o,0,t),this._changedEvent.raiseEvent(this)}},h.prototype.removeInterval=function(t){if(t.isEmpty)return!1;var r=!1,i=this._intervals,n=e(i,t,d);n<0&&(n=~n);var o=t.start,a=t.stop,s=t.isStartIncluded,l=t.isStopIncluded;if(n>0){var h=i[n-1],p=h.stop;(u.greaterThan(p,o)||c.equals(p,o)&&h.isStopIncluded&&s)&&(r=!0,(u.greaterThan(p,a)||h.isStopIncluded&&!l&&c.equals(p,a))&&i.splice(n,0,new c({start:a,stop:p,isStartIncluded:!l,isStopIncluded:h.isStopIncluded,data:h.data})),i[n-1]=new c({start:h.start,stop:o,isStartIncluded:h.isStartIncluded,isStopIncluded:!s,data:h.data}))}var f=i[n];for(n<i.length&&!s&&f.isStartIncluded&&o.equals(f.start)&&(r=!0,i.splice(n,0,new c({start:f.start,stop:f.start,isStartIncluded:!0,isStopIncluded:!0,data:f.data})),++n,f=i[n]);n<i.length&&u.greaterThan(a,f.stop);)r=!0,i.splice(n,1),f=i[n];return n<i.length&&a.equals(f.stop)&&(r=!0,!l&&f.isStopIncluded?(n+1<i.length&&i[n+1].start.equals(a)&&f.data===i[n+1].data?(i.splice(n,1),f=new c({start:f.start,stop:f.stop,isStartIncluded:!0,isStopIncluded:f.isStopIncluded,data:f.data})):f=new c({start:a,stop:a,isStartIncluded:!0,isStopIncluded:!0,data:f.data}),i[n]=f):i.splice(n,1)),n<i.length&&(u.greaterThan(a,f.start)||a.equals(f.start)&&l&&f.isStartIncluded)&&(r=!0,i[n]=new c({start:a,stop:f.stop,isStartIncluded:!l,isStopIncluded:f.isStopIncluded,data:f.data})),r&&this._changedEvent.raiseEvent(this),r},h.prototype.intersect=function(e,t,i){for(var n=0,o=0,a=new h,s=this._intervals,l=e._intervals;n<s.length&&o<l.length;){var d=s[n],p=l[o];if(u.lessThan(d.stop,p.start))++n;else if(u.lessThan(p.stop,d.start))++o;else{if(r(i)||r(t)&&t(d.data,p.data)||!r(t)&&p.data===d.data){var f=c.intersect(d,p,new c,i);f.isEmpty||a.addInterval(f,t)}u.lessThan(d.stop,p.stop)||d.stop.equals(p.stop)&&!d.isStopIncluded&&p.isStopIncluded?++n:++o}}return a},h.fromJulianDateArray=function(e,i){r(i)||(i=new h);var n,o=e.julianDates,a=o.length,s=e.dataCallback,u=t(e.isStartIncluded,!0),d=t(e.isStopIncluded,!0),p=t(e.leadingInterval,!1),f=t(e.trailingInterval,!1),m=0;p&&(++m,n=new c({start:l.MINIMUM_VALUE,stop:o[0],isStartIncluded:!0,isStopIncluded:!u}),n.data=r(s)?s(n,i.length):i.length,i.addInterval(n));for(var g=0;g<a-1;++g){var _=o[g],v=o[g+1];n=new c({start:_,stop:v,isStartIncluded:i.length!==m||u,isStopIncluded:g===a-2&&d}),n.data=r(s)?s(n,i.length):i.length,i.addInterval(n),_=v}return f&&(n=new c({start:o[a-1],stop:l.MAXIMUM_VALUE,isStartIncluded:!d,isStopIncluded:!0}),n.data=r(s)?s(n,i.length):i.length,i.addInterval(n)),i};var g=new a,_=[0,31,28,31,30,31,30,31,31,30,31,30,31],v=new u,y=/P(?:([\d.,]+)Y)?(?:([\d.,]+)M)?(?:([\d.,]+)W)?(?:([\d.,]+)D)?(?:T(?:([\d.,]+)H)?(?:([\d.,]+)M)?(?:([\d.,]+)S)?)?/,b=new a;return h.fromIso8601=function(e,t){var r=e.iso8601.split("/"),i=u.fromIso8601(r[0]),n=u.fromIso8601(r[1]),o=[] +;if(f(r[2],b)){var a=u.clone(i);for(o.push(a);u.compare(a,n)<0;){a=p(a,b);u.compare(n,a)<=0&&u.clone(n,a),o.push(a)}}else o.push(i,n);return h.fromJulianDateArray({julianDates:o,isStartIncluded:e.isStartIncluded,isStopIncluded:e.isStopIncluded,leadingInterval:e.leadingInterval,trailingInterval:e.trailingInterval,dataCallback:e.dataCallback},t)},h.fromIso8601DateArray=function(e,t){return h.fromJulianDateArray({julianDates:e.iso8601Dates.map(function(e){return u.fromIso8601(e)}),isStartIncluded:e.isStartIncluded,isStopIncluded:e.isStopIncluded,leadingInterval:e.leadingInterval,trailingInterval:e.trailingInterval,dataCallback:e.dataCallback},t)},h.fromIso8601DurationArray=function(e,i){for(var n,o,a=e.epoch,s=e.iso8601Durations,l=t(e.relativeToPrevious,!1),u=[],c=s.length,d=0;d<c;++d)(f(s[d],b)||0===d)&&(n=l&&r(o)?p(o,b):p(a,b),u.push(n),o=n);return h.fromJulianDateArray({julianDates:u,isStartIncluded:e.isStartIncluded,isStopIncluded:e.isStopIncluded,leadingInterval:e.leadingInterval,trailingInterval:e.trailingInterval,dataCallback:e.dataCallback},i)},h}),define("Core/TranslationRotationScale",["./Cartesian3","./defaultValue","./defined","./Quaternion"],function(e,t,r,i){"use strict";var n=new e(1,1,1),o=e.ZERO,a=i.IDENTITY,s=function(r,s,l){this.translation=e.clone(t(r,o)),this.rotation=i.clone(t(s,a)),this.scale=e.clone(t(l,n))};return s.prototype.equals=function(t){return this===t||r(t)&&e.equals(this.translation,t.translation)&&i.equals(this.rotation,t.rotation)&&e.equals(this.scale,t.scale)},s}),define("Core/VideoSynchronizer",["./defaultValue","./defined","./defineProperties","./destroyObject","./Iso8601","./JulianDate"],function(e,t,r,i,n,o){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this._clock=void 0,this._element=void 0,this._clockSubscription=void 0,this._seekFunction=void 0,this.clock=t.clock,this.element=t.element,this.epoch=e(t.epoch,n.MINIMUM_VALUE),this.tolerance=e(t.tolerance,1),this._seeking=!1,this._seekFunction=void 0,this._firstTickAfterSeek=!1}function s(e){return function(){e._seeking=!1,e._firstTickAfterSeek=!0}}return r(a.prototype,{clock:{get:function(){return this._clock},set:function(e){var r=this._clock;r!==e&&(t(r)&&(this._clockSubscription(),this._clockSubscription=void 0),t(e)&&(this._clockSubscription=e.onTick.addEventListener(a.prototype._onTick,this)),this._clock=e)}},element:{get:function(){return this._element},set:function(e){var r=this._element;r!==e&&(t(r)&&r.removeEventListener("seeked",this._seekFunction,!1),t(e)&&(this._seeking=!1,this._seekFunction=s(this),e.addEventListener("seeked",this._seekFunction,!1)),this._element=e,this._seeking=!1,this._firstTickAfterSeek=!1)}}}),a.prototype.destroy=function(){return this.element=void 0,this.clock=void 0,i(this)},a.prototype.isDestroyed=function(){return!1},a.prototype._onTick=function(r){var i=this._element;if(t(i)&&!(i.readyState<2)){var a=i.paused,s=r.shouldAnimate;if(s===a&&(s?i.play():i.pause()),this._seeking||this._firstTickAfterSeek)return void(this._firstTickAfterSeek=!1);i.playbackRate=r.multiplier;var l,u=r.currentTime,c=e(this.epoch,n.MINIMUM_VALUE),d=o.secondsDifference(u,c),h=i.duration,p=i.currentTime;i.loop?(d%=h,d<0&&(d=h-d),l=d):l=d>h?h:d<0?0:d;var f=s?e(this.tolerance,1):.001;Math.abs(l-p)>f&&(this._seeking=!0,i.currentTime=l)}},a}),define("Core/VRTheWorldTerrainProvider",["../ThirdParty/when","./Credit","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./Ellipsoid","./Event","./GeographicTilingScheme","./getImagePixels","./HeightmapTerrainData","./Math","./Rectangle","./Resource","./TerrainProvider","./TileProviderError"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e,t){this.rectangle=e,this.maxLevel=t}function v(n){function a(e){var t=e.getElementsByTagName("SRS")[0].textContent;if("EPSG:4326"!==t)return void c("SRS "+t+" is not supported.");C._tilingScheme=new u({ellipsoid:S});var r=e.getElementsByTagName("TileFormat")[0];C._heightmapWidth=parseInt(r.getAttribute("width"),10),C._heightmapHeight=parseInt(r.getAttribute("height"),10),C._levelZeroMaximumGeometricError=m.getEstimatedLevelZeroGeometricErrorForAHeightmap(S,Math.min(C._heightmapWidth,C._heightmapHeight),C._tilingScheme.getNumberOfXTilesAtLevel(0));for(var i=e.getElementsByTagName("DataExtent"),n=0;n<i.length;++n){var o=i[n],a=h.toRadians(parseFloat(o.getAttribute("minx"))),s=h.toRadians(parseFloat(o.getAttribute("miny"))),l=h.toRadians(parseFloat(o.getAttribute("maxx"))),d=h.toRadians(parseFloat(o.getAttribute("maxy"))),f=parseInt(o.getAttribute("maxlevel"),10);C._rectangles.push(new _(new p(a,s,l,d),f))}C._ready=!0,C._readyPromise.resolve(!0)}function c(e){var t=r(e,"An error occurred while accessing "+C._resource.url+".");b=g.handleError(b,C,C._errorEvent,t,void 0,void 0,void 0,d)}function d(){e(C._resource.fetchXML(),a,c)}n=r(n,r.EMPTY_OBJECT),i(n.proxy)&&o("VRTheWorldTerrainProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var v=f.createIfNeeded(n.url,{proxy:n.proxy});this._resource=v,this._errorEvent=new l,this._ready=!1,this._readyPromise=e.defer(),this._terrainDataStructure={heightScale:.001,heightOffset:-1e3,elementsPerHeight:3,stride:4,elementMultiplier:256,isBigEndian:!0,lowestEncodedHeight:0,highestEncodedHeight:16777215};var y=n.credit;"string"==typeof y&&(y=new t({text:y})),this._credit=y,this._tilingScheme=void 0,this._rectangles=[];var b,C=this,S=r(n.ellipsoid,s.WGS84);d()}function y(e,t,r,n){for(var o=e._tilingScheme,a=e._rectangles,s=o.tileXYToRectangle(t,r,n),l=0,u=0;u<a.length&&15!==l;++u){var c=a[u];if(!(c.maxLevel<=n)){var d=c.rectangle,h=p.intersection(d,s,C);i(h)&&(b(o,d,2*t,2*r,n+1)&&(l|=4),b(o,d,2*t+1,2*r,n+1)&&(l|=8),b(o,d,2*t,2*r+1,n+1)&&(l|=1),b(o,d,2*t+1,2*r+1,n+1)&&(l|=2))}}return l}function b(e,t,r,n,o){var a=e.tileXYToRectangle(r,n,o);return i(p.intersection(a,t,C))}n(v.prototype,{errorEvent:{get:function(){return this._errorEvent}},credit:{get:function(){return this._credit}},tilingScheme:{get:function(){return this._tilingScheme}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},hasWaterMask:{get:function(){return!1}},hasVertexNormals:{get:function(){return!1}}}),v.prototype.requestTileGeometry=function(t,r,n,o){var a=this._tilingScheme.getNumberOfYTilesAtLevel(n),s=this._resource.getDerivedResource({url:n+"/"+t+"/"+(a-r-1)+".tif",queryParameters:{cesium:!0},request:o}),l=s.fetchImage();if(i(l)){var u=this;return e(l,function(e){return new d({buffer:c(e),width:u._heightmapWidth,height:u._heightmapHeight,childTileMask:y(u,t,r,n),structure:u._terrainDataStructure})})}},v.prototype.getLevelMaximumGeometricError=function(e){return this._levelZeroMaximumGeometricError/(1<<e)};var C=new p;return v.prototype.getTileDataAvailable=function(e,t,r){},v}),define("Core/WallGeometryLibrary",["./Cartographic","./defined","./EllipsoidTangentPlane","./Math","./PolygonPipeline","./PolylinePipeline","./WindingOrder"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){return i.equalsEpsilon(e.latitude,t.latitude,i.EPSILON14)&&i.equalsEpsilon(e.longitude,t.longitude,i.EPSILON14)}function l(r,i,n,o){var a=i.length;if(!(a<2)){var l=t(o),u=t(n),h=!0,p=new Array(a),f=new Array(a),m=new Array(a),g=i[0];p[0]=g;var _=r.cartesianToCartographic(g,c);u&&(_.height=n[0]),h=h&&_.height<=0,f[0]=_.height,m[0]=l?o[0]:0;for(var v=1,y=1;y<a;++y){var b=i[y],C=r.cartesianToCartographic(b,d);u&&(C.height=n[y]),h=h&&C.height<=0,s(_,C)?_.height<C.height&&(f[v-1]=C.height):(p[v]=b,f[v]=C.height,m[v]=l?o[y]:0,e.clone(C,_),++v)}if(!(h||v<2))return p.length=v,f.length=v,m.length=v,{positions:p,topHeights:f,bottomHeights:m}}}var u={},c=new e,d=new e,h=new Array(2),p=new Array(2),f={positions:void 0,height:void 0,granularity:void 0,ellipsoid:void 0};return u.computePositions=function(e,s,u,c,d,m){var g=l(e,s,u,c);if(t(g)){if(s=g.positions,u=g.topHeights,c=g.bottomHeights,s.length>=3){var _=r.fromPoints(s,e),v=_.projectPointsOntoPlane(s);n.computeWindingOrder2D(v)===a.CLOCKWISE&&(s.reverse(),u.reverse(),c.reverse())}var y,b,C=s.length,S=C-2,w=i.chordLength(d,e.maximumRadius),T=f;if(T.minDistance=w,T.ellipsoid=e,m){var E,A=0;for(E=0;E<C-1;E++)A+=o.numberOfPoints(s[E],s[E+1],w)+1;y=new Float64Array(3*A),b=new Float64Array(3*A);var x=h,P=p;T.positions=x,T.height=P;var D=0;for(E=0;E<C-1;E++){x[0]=s[E],x[1]=s[E+1],P[0]=u[E],P[1]=u[E+1];var I=o.generateArc(T);y.set(I,D),P[0]=c[E],P[1]=c[E+1],b.set(o.generateArc(T),D),D+=I.length}}else T.positions=s,T.height=u,y=new Float64Array(o.generateArc(T)),T.height=c,b=new Float64Array(o.generateArc(T));return{bottomPositions:b,topPositions:y,numCorners:S}}},u}),define("Core/WallGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat","./WallGeometryLibrary"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=i(e,i.EMPTY_OBJECT);var r=e.positions,o=e.maximumHeights,s=e.minimumHeights,l=i(e.vertexFormat,p.DEFAULT),u=i(e.granularity,d.RADIANS_PER_DEGREE),c=i(e.ellipsoid,a.WGS84);this._positions=r,this._minimumHeights=s,this._maximumHeights=o,this._vertexFormat=p.clone(l),this._granularity=u,this._ellipsoid=a.clone(c),this._workerName="createWallGeometry";var h=1+r.length*t.packedLength+2;n(s)&&(h+=s.length),n(o)&&(h+=o.length),this.packedLength=h+a.packedLength+p.packedLength+1}var g=new t,_=new t,v=new t,y=new t,b=new t,C=new t,S=new t,w=new t;m.pack=function(e,r,o){o=i(o,0);var s,l=e._positions,u=l.length;for(r[o++]=u,s=0;s<u;++s,o+=t.packedLength)t.pack(l[s],r,o);var c=e._minimumHeights;if(u=n(c)?c.length:0,r[o++]=u,n(c))for(s=0;s<u;++s)r[o++]=c[s];var d=e._maximumHeights;if(u=n(d)?d.length:0,r[o++]=u,n(d))for(s=0;s<u;++s)r[o++]=d[s];return a.pack(e._ellipsoid,r,o),o+=a.packedLength,p.pack(e._vertexFormat,r,o),o+=p.packedLength,r[o]=e._granularity,r};var T=a.clone(a.UNIT_SPHERE),E=new p,A={positions:void 0,minimumHeights:void 0,maximumHeights:void 0,ellipsoid:T,vertexFormat:E,granularity:void 0};return m.unpack=function(e,r,o){r=i(r,0);var s,l=e[r++],u=new Array(l);for(s=0;s<l;++s,r+=t.packedLength)u[s]=t.unpack(e,r);l=e[r++];var c;if(l>0)for(c=new Array(l),s=0;s<l;++s)c[s]=e[r++];l=e[r++];var d;if(l>0)for(d=new Array(l),s=0;s<l;++s)d[s]=e[r++];var h=a.unpack(e,r,T);r+=a.packedLength;var f=p.unpack(e,r,E);r+=p.packedLength;var g=e[r];return n(o)?(o._positions=u,o._minimumHeights=c,o._maximumHeights=d,o._ellipsoid=a.clone(h,o._ellipsoid),o._vertexFormat=p.clone(f,o._vertexFormat),o._granularity=g,o):(A.positions=u,A.minimumHeights=c,A.maximumHeights=d,A.granularity=g,new m(A))},m.fromConstantHeights=function(e){e=i(e,i.EMPTY_OBJECT);var t,r,o=e.positions,a=e.minimumHeight,s=e.maximumHeight,l=n(a),u=n(s);if(l||u){var c=o.length;t=l?new Array(c):void 0,r=u?new Array(c):void 0;for(var d=0;d<c;++d)l&&(t[d]=a),u&&(r[d]=s)}return new m({positions:o,maximumHeights:r,minimumHeights:t,ellipsoid:e.ellipsoid,vertexFormat:e.vertexFormat})},m.createGeometry=function(i){var o=i._positions,a=i._minimumHeights,p=i._maximumHeights,m=i._vertexFormat,T=i._granularity,E=i._ellipsoid,A=f.computePositions(E,o,p,a,T,!0);if(n(A)){var x=A.bottomPositions,P=A.topPositions,D=A.numCorners,I=P.length,O=2*I,M=m.position?new Float64Array(O):void 0,R=m.normal?new Float32Array(O):void 0,L=m.tangent?new Float32Array(O):void 0,N=m.bitangent?new Float32Array(O):void 0,k=m.st?new Float32Array(O/3*2):void 0,F=0,B=0,U=0,V=0,z=0,G=w,W=S,H=C,j=!0;I/=3;var q,Y=0,X=1/(I-o.length+1);for(q=0;q<I;++q){var Q=3*q,Z=t.fromArray(P,Q,g),K=t.fromArray(x,Q,_);if(m.position&&(M[F++]=K.x,M[F++]=K.y,M[F++]=K.z,M[F++]=Z.x,M[F++]=Z.y,M[F++]=Z.z),m.st&&(k[z++]=Y,k[z++]=0,k[z++]=Y,k[z++]=1),m.normal||m.tangent||m.bitangent){var J,$=t.clone(t.ZERO,b),ee=E.scaleToGeodeticSurface(t.fromArray(P,Q,_),_);if(q+1<I&&(J=E.scaleToGeodeticSurface(t.fromArray(P,Q+3,v),v),$=t.fromArray(P,Q+3,b)),j){var te=t.subtract($,Z,y),re=t.subtract(ee,Z,g);G=t.normalize(t.cross(re,te,G),G),j=!1}t.equalsEpsilon(J,ee,d.EPSILON10)?j=!0:(Y+=X,m.tangent&&(W=t.normalize(t.subtract(J,ee,W),W)),m.bitangent&&(H=t.normalize(t.cross(G,W,H),H))),m.normal&&(R[B++]=G.x,R[B++]=G.y,R[B++]=G.z,R[B++]=G.x,R[B++]=G.y,R[B++]=G.z),m.tangent&&(L[V++]=W.x,L[V++]=W.y,L[V++]=W.z,L[V++]=W.x,L[V++]=W.y,L[V++]=W.z),m.bitangent&&(N[U++]=H.x,N[U++]=H.y,N[U++]=H.z,N[U++]=H.x,N[U++]=H.y,N[U++]=H.z)}}var ie=new u;m.position&&(ie.position=new l({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:M})),m.normal&&(ie.normal=new l({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:R})),m.tangent&&(ie.tangent=new l({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:L})),m.bitangent&&(ie.bitangent=new l({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:N})),m.st&&(ie.st=new l({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:k}));var ne=O/3;O-=6*(D+1);var oe=c.createTypedArray(ne,O),ae=0;for(q=0;q<ne-2;q+=2){var se=q,le=q+2,ue=t.fromArray(M,3*se,g),ce=t.fromArray(M,3*le,_);if(!t.equalsEpsilon(ue,ce,d.EPSILON10)){var de=q+1,he=q+3;oe[ae++]=de,oe[ae++]=se,oe[ae++]=he,oe[ae++]=he,oe[ae++]=se,oe[ae++]=le}}return new s({attributes:ie,indices:oe,primitiveType:h.TRIANGLES,boundingSphere:new e.fromVertices(M)})}},m}),define("Core/WallOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./WallGeometryLibrary"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e){e=i(e,i.EMPTY_OBJECT);var r=e.positions,o=e.maximumHeights,s=e.minimumHeights,l=i(e.granularity,d.RADIANS_PER_DEGREE),u=i(e.ellipsoid,a.WGS84);this._positions=r,this._minimumHeights=s,this._maximumHeights=o,this._granularity=l,this._ellipsoid=a.clone(u),this._workerName="createWallOutlineGeometry";var c=1+r.length*t.packedLength+2;n(s)&&(c+=s.length),n(o)&&(c+=o.length),this.packedLength=c+a.packedLength+1}var m=new t,g=new t;f.pack=function(e,r,o){o=i(o,0);var s,l=e._positions,u=l.length;for(r[o++]=u,s=0;s<u;++s,o+=t.packedLength)t.pack(l[s],r,o);var c=e._minimumHeights;if(u=n(c)?c.length:0,r[o++]=u,n(c))for(s=0;s<u;++s)r[o++]=c[s];var d=e._maximumHeights;if(u=n(d)?d.length:0,r[o++]=u,n(d))for(s=0;s<u;++s)r[o++]=d[s];return a.pack(e._ellipsoid,r,o),o+=a.packedLength,r[o]=e._granularity,r};var _=a.clone(a.UNIT_SPHERE),v={positions:void 0,minimumHeights:void 0,maximumHeights:void 0,ellipsoid:_,granularity:void 0};return f.unpack=function(e,r,o){r=i(r,0);var s,l=e[r++],u=new Array(l);for(s=0;s<l;++s,r+=t.packedLength)u[s]=t.unpack(e,r);l=e[r++];var c;if(l>0)for(c=new Array(l),s=0;s<l;++s)c[s]=e[r++];l=e[r++];var d;if(l>0)for(d=new Array(l),s=0;s<l;++s)d[s]=e[r++];var h=a.unpack(e,r,_);r+=a.packedLength;var p=e[r];return n(o)?(o._positions=u,o._minimumHeights=c,o._maximumHeights=d,o._ellipsoid=a.clone(h,o._ellipsoid),o._granularity=p,o):(v.positions=u,v.minimumHeights=c,v.maximumHeights=d,v.granularity=p,new f(v))},f.fromConstantHeights=function(e){e=i(e,i.EMPTY_OBJECT);var t,r,o=e.positions,a=e.minimumHeight,s=e.maximumHeight,l=n(a),u=n(s);if(l||u){var c=o.length;t=l?new Array(c):void 0,r=u?new Array(c):void 0;for(var d=0;d<c;++d)l&&(t[d]=a),u&&(r[d]=s)}return new f({positions:o,maximumHeights:r,minimumHeights:t,ellipsoid:e.ellipsoid})},f.createGeometry=function(i){var o=i._positions,a=i._minimumHeights,f=i._maximumHeights,_=i._granularity,v=i._ellipsoid,y=p.computePositions(v,o,f,a,_,!1);if(n(y)){var b=y.bottomPositions,C=y.topPositions,S=C.length,w=2*S,T=new Float64Array(w),E=0;S/=3;var A;for(A=0;A<S;++A){var x=3*A,P=t.fromArray(C,x,m),D=t.fromArray(b,x,g);T[E++]=D.x,T[E++]=D.y,T[E++]=D.z,T[E++]=P.x,T[E++]=P.y,T[E++]=P.z}var I=new u({position:new l({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:T})}),O=w/3;w=2*O-4+O;var M=c.createTypedArray(O,w),R=0;for(A=0;A<O-2;A+=2){var L=A,N=A+2,k=t.fromArray(T,3*L,m),F=t.fromArray(T,3*N,g);if(!t.equalsEpsilon(k,F,d.EPSILON10)){var B=A+1,U=A+3;M[R++]=B,M[R++]=L,M[R++]=B,M[R++]=U,M[R++]=L,M[R++]=N}}return M[R++]=O-2,M[R++]=O-1,new s({attributes:I,indices:M,primitiveType:h.LINES,boundingSphere:new e.fromVertices(T)})}},f}),define("Core/WebMercatorTilingScheme",["./Cartesian2","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Rectangle","./WebMercatorProjection"],function(e,t,r,i,n,o,a){"use strict";function s(i){if(i=t(i,{}),this._ellipsoid=t(i.ellipsoid,n.WGS84),this._numberOfLevelZeroTilesX=t(i.numberOfLevelZeroTilesX,1),this._numberOfLevelZeroTilesY=t(i.numberOfLevelZeroTilesY,1),this._projection=new a(this._ellipsoid),r(i.rectangleSouthwestInMeters)&&r(i.rectangleNortheastInMeters))this._rectangleSouthwestInMeters=i.rectangleSouthwestInMeters,this._rectangleNortheastInMeters=i.rectangleNortheastInMeters;else{var s=this._ellipsoid.maximumRadius*Math.PI;this._rectangleSouthwestInMeters=new e(-s,-s),this._rectangleNortheastInMeters=new e(s,s)}var l=this._projection.unproject(this._rectangleSouthwestInMeters),u=this._projection.unproject(this._rectangleNortheastInMeters);this._rectangle=new o(l.longitude,l.latitude,u.longitude,u.latitude)}return i(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},rectangle:{get:function(){return this._rectangle}},projection:{get:function(){return this._projection}}}),s.prototype.getNumberOfXTilesAtLevel=function(e){return this._numberOfLevelZeroTilesX<<e},s.prototype.getNumberOfYTilesAtLevel=function(e){return this._numberOfLevelZeroTilesY<<e},s.prototype.rectangleToNativeRectangle=function(e,t){var i=this._projection,n=i.project(o.southwest(e)),a=i.project(o.northeast(e));return r(t)?(t.west=n.x,t.south=n.y,t.east=a.x,t.north=a.y,t):new o(n.x,n.y,a.x,a.y)},s.prototype.tileXYToNativeRectangle=function(e,t,i,n){var a=this.getNumberOfXTilesAtLevel(i),s=this.getNumberOfYTilesAtLevel(i),l=(this._rectangleNortheastInMeters.x-this._rectangleSouthwestInMeters.x)/a,u=this._rectangleSouthwestInMeters.x+e*l,c=this._rectangleSouthwestInMeters.x+(e+1)*l,d=(this._rectangleNortheastInMeters.y-this._rectangleSouthwestInMeters.y)/s,h=this._rectangleNortheastInMeters.y-t*d,p=this._rectangleNortheastInMeters.y-(t+1)*d;return r(n)?(n.west=u,n.south=p,n.east=c,n.north=h,n):new o(u,p,c,h)},s.prototype.tileXYToRectangle=function(t,r,i,n){var o=this.tileXYToNativeRectangle(t,r,i,n),a=this._projection,s=a.unproject(new e(o.west,o.south)),l=a.unproject(new e(o.east,o.north));return o.west=s.longitude,o.south=s.latitude,o.east=l.longitude,o.north=l.latitude,o},s.prototype.positionToTileXY=function(t,i,n){var a=this._rectangle;if(o.contains(a,t)){var s=this.getNumberOfXTilesAtLevel(i),l=this.getNumberOfYTilesAtLevel(i),u=this._rectangleNortheastInMeters.x-this._rectangleSouthwestInMeters.x,c=u/s,d=this._rectangleNortheastInMeters.y-this._rectangleSouthwestInMeters.y,h=d/l,p=this._projection,f=p.project(t),m=f.x-this._rectangleSouthwestInMeters.x,g=this._rectangleNortheastInMeters.y-f.y,_=m/c|0;_>=s&&(_=s-1);var v=g/h|0;return v>=l&&(v=l-1),r(n)?(n.x=_,n.y=v,n):new e(_,v)}},s}),define("Core/WeightSpline",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./Spline"],function(e,t,r,i,n,o){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT);var r=e.weights,i=e.times;this._times=i,this._weights=r,this._count=r.length/i.length,this._lastTimeIndex=0}return i(a.prototype,{times:{get:function(){return this._times}},weights:{get:function(){return this._weights}}}),a.prototype.findTimeInterval=o.prototype.findTimeInterval,a.prototype.wrapTime=o.prototype.wrapTime,a.prototype.clampTime=o.prototype.clampTime,a.prototype.evaluate=function(e,t){var i=this.weights,n=this.times,o=this._lastTimeIndex=this.findTimeInterval(e,this._lastTimeIndex),a=(e-n[o])/(n[o+1]-n[o]);r(t)||(t=new Array(this._count));for(var s=0;s<this._count;s++){var l=o*this._count+s;t[s]=i[l]*(1-a)+i[l+this._count]*a}return t},a}),define("Core/wrapFunction",["./DeveloperError"],function(e){"use strict";function t(e,t,r){return function(){r.apply(e,arguments),t.apply(e,arguments)}}return t}),define("DataSources/ConstantProperty",["../Core/defined","../Core/defineProperties","../Core/Event"],function(e,t,r){"use strict";function i(e){this._value=void 0,this._hasClone=!1,this._hasEquals=!1,this._definitionChanged=new r,this.setValue(e)}return t(i.prototype,{isConstant:{value:!0},definitionChanged:{get:function(){return this._definitionChanged}}}),i.prototype.getValue=function(e,t){return this._hasClone?this._value.clone(t):this._value},i.prototype.setValue=function(t){var r=this._value;if(r!==t){var i=e(t),n=i&&"function"==typeof t.clone,o=i&&"function"==typeof t.equals;(!o||!t.equals(r))&&(this._hasClone=n,this._hasEquals=o,this._value=n?t.clone(this._value):t,this._definitionChanged.raiseEvent(this))}},i.prototype.equals=function(e){return this===e||e instanceof i&&(!this._hasEquals&&this._value===e._value||this._hasEquals&&this._value.equals(e._value))},i.prototype.valueOf=function(){return this._value},i.prototype.toString=function(){return String(this._value)},i}),define("DataSources/createPropertyDescriptor",["../Core/defaultValue","../Core/defined","./ConstantProperty"],function(e,t,r){"use strict";function i(e,r,i,n,o){return{configurable:n,get:function(){return this[r]},set:function(n){var a=this[r],s=this[i];t(s)&&(s(),this[i]=void 0),!(void 0!==n)||t(n)&&t(n.getValue)||!t(o)||(n=o(n)),a!==n&&(this[r]=n,this._definitionChanged.raiseEvent(this,e,n,a)),t(n)&&t(n.definitionChanged)&&(this[i]=n.definitionChanged.addEventListener(function(){this._definitionChanged.raiseEvent(this,e,n,n)},this))}}}function n(e){return new r(e)}function o(t,r,o){return i(t,"_"+t.toString(),"_"+t.toString()+"Subscription",e(r,!1),e(o,n))}return o}),define("DataSources/BillboardGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createPropertyDescriptor"],function(e,t,r,i,n,o){"use strict";function a(t){this._image=void 0,this._imageSubscription=void 0,this._imageSubRegion=void 0,this._imageSubRegionSubscription=void 0,this._width=void 0,this._widthSubscription=void 0,this._height=void 0,this._heightSubscription=void 0,this._scale=void 0,this._scaleSubscription=void 0,this._rotation=void 0,this._rotationSubscription=void 0,this._alignedAxis=void 0,this._alignedAxisSubscription=void 0,this._horizontalOrigin=void 0,this._horizontalOriginSubscription=void 0,this._verticalOrigin=void 0,this._verticalOriginSubscription=void 0,this._color=void 0,this._colorSubscription=void 0,this._eyeOffset=void 0,this._eyeOffsetSubscription=void 0,this._heightReference=void 0,this._heightReferenceSubscription=void 0,this._pixelOffset=void 0,this._pixelOffsetSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._scaleByDistance=void 0,this._scaleByDistanceSubscription=void 0,this._translucencyByDistance=void 0,this._translucencyByDistanceSubscription=void 0,this._pixelOffsetScaleByDistance=void 0,this._pixelOffsetScaleByDistanceSubscription=void 0,this._sizeInMeters=void 0,this._sizeInMetersSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._disableDepthTestDistance=void 0,this._disableDepthTestDistanceSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(a.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},image:o("image"),imageSubRegion:o("imageSubRegion"),scale:o("scale"),rotation:o("rotation"),alignedAxis:o("alignedAxis"),horizontalOrigin:o("horizontalOrigin"),verticalOrigin:o("verticalOrigin"),color:o("color"),eyeOffset:o("eyeOffset"),heightReference:o("heightReference"),pixelOffset:o("pixelOffset"),show:o("show"),width:o("width"),height:o("height"),scaleByDistance:o("scaleByDistance"),translucencyByDistance:o("translucencyByDistance"),pixelOffsetScaleByDistance:o("pixelOffsetScaleByDistance"),sizeInMeters:o("sizeInMeters"),distanceDisplayCondition:o("distanceDisplayCondition"),disableDepthTestDistance:o("disableDepthTestDistance")}),a.prototype.clone=function(e){return t(e)?(e.color=this._color,e.eyeOffset=this._eyeOffset,e.heightReference=this._heightReference,e.horizontalOrigin=this._horizontalOrigin,e.image=this._image,e.imageSubRegion=this._imageSubRegion,e.pixelOffset=this._pixelOffset,e.scale=this._scale,e.rotation=this._rotation,e.alignedAxis=this._alignedAxis,e.show=this._show,e.verticalOrigin=this._verticalOrigin,e.width=this._width,e.height=this._height,e.scaleByDistance=this._scaleByDistance,e.translucencyByDistance=this._translucencyByDistance,e.pixelOffsetScaleByDistance=this._pixelOffsetScaleByDistance,e.sizeInMeters=this._sizeInMeters,e.distanceDisplayCondition=this._distanceDisplayCondition,e.disableDepthTestDistance=this._disableDepthTestDistance,e):new a(this)},a.prototype.merge=function(t){this.color=e(this._color,t.color),this.eyeOffset=e(this._eyeOffset,t.eyeOffset),this.heightReference=e(this._heightReference,t.heightReference),this.horizontalOrigin=e(this._horizontalOrigin,t.horizontalOrigin),this.image=e(this._image,t.image),this.imageSubRegion=e(this._imageSubRegion,t.imageSubRegion),this.pixelOffset=e(this._pixelOffset,t.pixelOffset),this.scale=e(this._scale,t.scale),this.rotation=e(this._rotation,t.rotation),this.alignedAxis=e(this._alignedAxis,t.alignedAxis),this.show=e(this._show,t.show),this.verticalOrigin=e(this._verticalOrigin,t.verticalOrigin),this.width=e(this._width,t.width),this.height=e(this._height,t.height),this.scaleByDistance=e(this._scaleByDistance,t.scaleByDistance),this.translucencyByDistance=e(this._translucencyByDistance,t.translucencyByDistance),this.pixelOffsetScaleByDistance=e(this._pixelOffsetScaleByDistance,t.pixelOffsetScaleByDistance),this.sizeInMeters=e(this._sizeInMeters,t.sizeInMeters),this.distanceDisplayCondition=e(this._distanceDisplayCondition,t.distanceDisplayCondition),this.disableDepthTestDistance=e(this._disableDepthTestDistance,t.disableDepthTestDistance)},a}),define("Scene/HeightReference",["../Core/freezeObject"],function(e){"use strict";return e({NONE:0,CLAMP_TO_GROUND:1,RELATIVE_TO_GROUND:2})}),define("Scene/HorizontalOrigin",["../Core/freezeObject"],function(e){"use strict";return e({CENTER:0,LEFT:1,RIGHT:-1})}),define("Scene/VerticalOrigin",["../Core/freezeObject"],function(e){"use strict";return e({CENTER:0,BOTTOM:1,BASELINE:2,TOP:-1})}),define("DataSources/BoundingSphereState",["../Core/freezeObject"],function(e){"use strict";return e({DONE:0,PENDING:1,FAILED:2})}),define("DataSources/Property",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError"],function(e,t,r,i){"use strict";function n(){i.throwInstantiationError()}return r(n.prototype,{isConstant:{get:i.throwInstantiationError},definitionChanged:{get:i.throwInstantiationError}}),n.prototype.getValue=i.throwInstantiationError,n.prototype.equals=i.throwInstantiationError,n.equals=function(e,r){return e===r||t(e)&&e.equals(r)},n.arrayEquals=function(e,r){if(e===r)return!0;if(!t(e)||!t(r)||e.length!==r.length)return!1;for(var i=e.length,o=0;o<i;o++)if(!n.equals(e[o],r[o]))return!1;return!0},n.isConstant=function(e){return!t(e)||e.isConstant},n.getValueOrUndefined=function(e,r,i){return t(e)?e.getValue(r,i):void 0},n.getValueOrDefault=function(r,i,n,o){return t(r)?e(r.getValue(i,o),n):n},n.getValueOrClonedDefault=function(e,r,i,n){var o;return t(e)&&(o=e.getValue(r,n)),t(o)||(o=i.clone(o)),o},n}),define("DataSources/BillboardVisualizer",["../Core/AssociativeArray","../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/NearFarScalar","../Scene/HeightReference","../Scene/HorizontalOrigin","../Scene/VerticalOrigin","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){this.entity=e,this.billboard=void 0,this.textureValue=void 0}function g(t,r){r.collectionChanged.addEventListener(g.prototype._onCollectionChanged,this),this._cluster=t,this._entityCollection=r,this._items=new e,this._onCollectionChanged(r,r.values,[],[])}function _(e,t,r){o(e)&&(e.billboard=void 0,r.removeBillboard(t))}var v=n.WHITE,y=i.ZERO,b=c.NONE,C=r.ZERO,S=i.ZERO,w=d.CENTER,T=h.CENTER,E=new i,A=new n,x=new i,P=new r,D=new u,I=new u,O=new u,M=new t,R=new l;return g.prototype.update=function(e){for(var t=this._items.values,r=this._cluster,i=0,n=t.length;i<n;i++){var a,s=t[i],l=s.entity,u=l._billboard,c=s.billboard,d=l.isShowing&&l.isAvailable(e)&&f.getValueOrDefault(u._show,e,!0);if(d&&(E=f.getValueOrUndefined(l._position,e,E),a=f.getValueOrUndefined(u._image,e),d=o(E)&&o(a)),d){f.isConstant(l._position)||(r._clusterDirty=!0),o(c)||(c=r.getBillboard(l),c.id=l,c.image=void 0,s.billboard=c),c.show=d,o(c.image)&&s.textureValue===a||(c.image=a,s.textureValue=a),c.position=E,c.color=f.getValueOrDefault(u._color,e,v,A),c.eyeOffset=f.getValueOrDefault(u._eyeOffset,e,y,x),c.heightReference=f.getValueOrDefault(u._heightReference,e,b),c.pixelOffset=f.getValueOrDefault(u._pixelOffset,e,C,P),c.scale=f.getValueOrDefault(u._scale,e,1),c.rotation=f.getValueOrDefault(u._rotation,e,0),c.alignedAxis=f.getValueOrDefault(u._alignedAxis,e,S),c.horizontalOrigin=f.getValueOrDefault(u._horizontalOrigin,e,w),c.verticalOrigin=f.getValueOrDefault(u._verticalOrigin,e,T),c.width=f.getValueOrUndefined(u._width,e),c.height=f.getValueOrUndefined(u._height,e),c.scaleByDistance=f.getValueOrUndefined(u._scaleByDistance,e,D),c.translucencyByDistance=f.getValueOrUndefined(u._translucencyByDistance,e,I),c.pixelOffsetScaleByDistance=f.getValueOrUndefined(u._pixelOffsetScaleByDistance,e,O),c.sizeInMeters=f.getValueOrDefault(u._sizeInMeters,e,!1),c.distanceDisplayCondition=f.getValueOrUndefined(u._distanceDisplayCondition,e,R),c.disableDepthTestDistance=f.getValueOrDefault(u._disableDepthTestDistance,e,0);var h=f.getValueOrUndefined(u._imageSubRegion,e,M);o(h)&&c.setImageSubRegion(c._imageId,h)}else _(s,l,r)}return!0},g.prototype.getBoundingSphere=function(e,t){var r=this._items.get(e.id);if(!o(r)||!o(r.billboard))return p.FAILED;var n=r.billboard;if(n.heightReference===c.NONE)t.center=i.clone(n.position,t.center);else{if(!o(n._clampedPosition))return p.PENDING;t.center=i.clone(n._clampedPosition,t.center)}return t.radius=0,p.DONE},g.prototype.isDestroyed=function(){return!1},g.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(g.prototype._onCollectionChanged,this);for(var e=this._entityCollection.values,t=0;t<e.length;t++)this._cluster.removeBillboard(e[t]);return a(this)},g.prototype._onCollectionChanged=function(e,t,r,i){var n,a,s=this._items,l=this._cluster;for(n=t.length-1;n>-1;n--)a=t[n],o(a._billboard)&&o(a._position)&&s.set(a.id,new m(a));for(n=i.length-1;n>-1;n--)a=i[n],o(a._billboard)&&o(a._position)?s.contains(a.id)||s.set(a.id,new m(a)):(_(s.get(a.id),a,l),s.remove(a.id));for(n=r.length-1;n>-1;n--)a=r[n],_(s.get(a.id),a,l),s.remove(a.id)},g}),define("Shaders/Appearances/AllMaterialAppearanceFS",[],function(){"use strict" +;return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec3 v_tangentEC;\nvarying vec3 v_bitangentEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nmat3 tangentToEyeMatrix = czm_tangentToEyeSpaceMatrix(v_normalEC, v_tangentEC, v_bitangentEC);\nvec3 normalEC = normalize(v_normalEC);\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.tangentToEyeMatrix = tangentToEyeMatrix;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nmaterialInput.st = v_st;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/AllMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute vec3 tangent;\nattribute vec3 bitangent;\nattribute vec2 st;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec3 v_tangentEC;\nvarying vec3 v_bitangentEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\nv_tangentEC = czm_normal * tangent;\nv_bitangentEC = czm_normal * bitangent;\nv_st = st;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Shaders/Appearances/BasicMaterialAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nvec3 normalEC = normalize(v_normalEC);\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/BasicMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Shaders/Appearances/TexturedMaterialAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nvec3 normalEC = normalize(v_normalEC);;\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nmaterialInput.st = v_st;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/TexturedMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute vec2 st;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\nv_st = st;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Scene/BlendEquation",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({ADD:t.FUNC_ADD,SUBTRACT:t.FUNC_SUBTRACT,REVERSE_SUBTRACT:t.FUNC_REVERSE_SUBTRACT,MIN:t.MIN,MAX:t.MAX})}),define("Scene/BlendFunction",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({ZERO:t.ZERO,ONE:t.ONE,SOURCE_COLOR:t.SRC_COLOR,ONE_MINUS_SOURCE_COLOR:t.ONE_MINUS_SRC_COLOR,DESTINATION_COLOR:t.DST_COLOR,ONE_MINUS_DESTINATION_COLOR:t.ONE_MINUS_DST_COLOR,SOURCE_ALPHA:t.SRC_ALPHA,ONE_MINUS_SOURCE_ALPHA:t.ONE_MINUS_SRC_ALPHA,DESTINATION_ALPHA:t.DST_ALPHA,ONE_MINUS_DESTINATION_ALPHA:t.ONE_MINUS_DST_ALPHA,CONSTANT_COLOR:t.CONSTANT_COLOR,ONE_MINUS_CONSTANT_COLOR:t.ONE_MINUS_CONSTANT_ALPHA,CONSTANT_ALPHA:t.CONSTANT_ALPHA,ONE_MINUS_CONSTANT_ALPHA:t.ONE_MINUS_CONSTANT_ALPHA,SOURCE_ALPHA_SATURATE:t.SRC_ALPHA_SATURATE})}),define("Scene/BlendingState",["../Core/freezeObject","./BlendEquation","./BlendFunction"],function(e,t,r){"use strict";return e({DISABLED:e({enabled:!1}),ALPHA_BLEND:e({enabled:!0,equationRgb:t.ADD,equationAlpha:t.ADD,functionSourceRgb:r.SOURCE_ALPHA,functionSourceAlpha:r.SOURCE_ALPHA,functionDestinationRgb:r.ONE_MINUS_SOURCE_ALPHA,functionDestinationAlpha:r.ONE_MINUS_SOURCE_ALPHA}),PRE_MULTIPLIED_ALPHA_BLEND:e({enabled:!0,equationRgb:t.ADD,equationAlpha:t.ADD,functionSourceRgb:r.ONE,functionSourceAlpha:r.ONE,functionDestinationRgb:r.ONE_MINUS_SOURCE_ALPHA,functionDestinationAlpha:r.ONE_MINUS_SOURCE_ALPHA}),ADDITIVE_BLEND:e({enabled:!0,equationRgb:t.ADD,equationAlpha:t.ADD,functionSourceRgb:r.SOURCE_ALPHA,functionSourceAlpha:r.SOURCE_ALPHA,functionDestinationRgb:r.ONE,functionDestinationAlpha:r.ONE})})}),define("Scene/CullFace",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({FRONT:t.FRONT,BACK:t.BACK,FRONT_AND_BACK:t.FRONT_AND_BACK})}),define("Scene/Appearance",["../Core/clone","../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","./BlendingState","./CullFace"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this.material=e.material,this.translucent=r(e.translucent,!0),this._vertexShaderSource=e.vertexShaderSource,this._fragmentShaderSource=e.fragmentShaderSource,this._renderState=e.renderState,this._closed=r(e.closed,!1)}return n(s.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}}}),s.prototype.getFragmentShaderSource=function(){var e=[];return this.flat&&e.push("#define FLAT"),this.faceForward&&e.push("#define FACE_FORWARD"),i(this.material)&&e.push(this.material.shaderSource),e.push(this.fragmentShaderSource),e.join("\n")},s.prototype.isTranslucent=function(){return i(this.material)&&this.material.isTranslucent()||!i(this.material)&&this.translucent},s.prototype.getRenderState=function(){var t=this.isTranslucent(),r=e(this.renderState,!1);return t?(r.depthMask=!1,r.blending=o.ALPHA_BLEND):r.depthMask=!0,r},s.getDefaultRenderState=function(e,r,n){var s={depthTest:{enabled:!0}};return e&&(s.depthMask=!1,s.blending=o.ALPHA_BLEND),r&&(s.cull={enabled:!0,face:a.BACK}),i(n)&&(s=t(n,s,!0)),s},s}),define("Renderer/ContextLimits",["../Core/defineProperties"],function(e){"use strict";var t={_maximumCombinedTextureImageUnits:0,_maximumCubeMapSize:0,_maximumFragmentUniformVectors:0,_maximumTextureImageUnits:0,_maximumRenderbufferSize:0,_maximumTextureSize:0,_maximumVaryingVectors:0,_maximumVertexAttributes:0,_maximumVertexTextureImageUnits:0,_maximumVertexUniformVectors:0,_minimumAliasedLineWidth:0,_maximumAliasedLineWidth:0,_minimumAliasedPointSize:0,_maximumAliasedPointSize:0,_maximumViewportWidth:0,_maximumViewportHeight:0,_maximumTextureFilterAnisotropy:0,_maximumDrawBuffers:0,_maximumColorAttachments:0,_highpFloatSupported:!1,_highpIntSupported:!1};return e(t,{maximumCombinedTextureImageUnits:{get:function(){return t._maximumCombinedTextureImageUnits}},maximumCubeMapSize:{get:function(){return t._maximumCubeMapSize}},maximumFragmentUniformVectors:{get:function(){return t._maximumFragmentUniformVectors}},maximumTextureImageUnits:{get:function(){return t._maximumTextureImageUnits}},maximumRenderbufferSize:{get:function(){return t._maximumRenderbufferSize}},maximumTextureSize:{get:function(){return t._maximumTextureSize}},maximumVaryingVectors:{get:function(){return t._maximumVaryingVectors}},maximumVertexAttributes:{get:function(){return t._maximumVertexAttributes}},maximumVertexTextureImageUnits:{get:function(){return t._maximumVertexTextureImageUnits}},maximumVertexUniformVectors:{get:function(){return t._maximumVertexUniformVectors}},minimumAliasedLineWidth:{get:function(){return t._minimumAliasedLineWidth}},maximumAliasedLineWidth:{get:function(){return t._maximumAliasedLineWidth}},minimumAliasedPointSize:{get:function(){return t._minimumAliasedPointSize}},maximumAliasedPointSize:{get:function(){return t._maximumAliasedPointSize}},maximumViewportWidth:{get:function(){return t._maximumViewportWidth}},maximumViewportHeight:{get:function(){return t._maximumViewportHeight}},maximumTextureFilterAnisotropy:{get:function(){return t._maximumTextureFilterAnisotropy}},maximumDrawBuffers:{get:function(){return t._maximumDrawBuffers}},maximumColorAttachments:{get:function(){return t._maximumColorAttachments}},highpFloatSupported:{get:function(){return t._highpFloatSupported}},highpIntSupported:{get:function(){return t._highpIntSupported}}}),t}),define("Renderer/CubeMapFace",["../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/DeveloperError","./PixelDatatype"],function(e,t,r,i,n){"use strict";function o(e,t,r,i,n,o,a,s,l){this._gl=e,this._texture=t,this._textureTarget=r,this._targetFace=i,this._pixelFormat=n,this._pixelDatatype=o,this._size=a,this._preMultiplyAlpha=s,this._flipY=l}return r(o.prototype,{pixelFormat:{get:function(){return this._pixelFormat}},pixelDatatype:{get:function(){return this._pixelDatatype}},_target:{get:function(){return this._targetFace}}}),o.prototype.copyFrom=function(e,r,i){r=t(r,0),i=t(i,0);var n=this._gl,o=this._textureTarget;n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this._preMultiplyAlpha),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,this._flipY),n.activeTexture(n.TEXTURE0),n.bindTexture(o,this._texture),e.arrayBufferView?n.texSubImage2D(this._targetFace,0,r,i,e.width,e.height,this._pixelFormat,this._pixelDatatype,e.arrayBufferView):n.texSubImage2D(this._targetFace,0,r,i,this._pixelFormat,this._pixelDatatype,e),n.bindTexture(o,null)},o.prototype.copyFromFramebuffer=function(e,r,i,n,o,a){e=t(e,0),r=t(r,0),i=t(i,0),n=t(n,0),o=t(o,this._size),a=t(a,this._size);var s=this._gl,l=this._textureTarget;s.activeTexture(s.TEXTURE0),s.bindTexture(l,this._texture),s.copyTexSubImage2D(this._targetFace,0,e,r,i,n,o,a),s.bindTexture(l,null)},o}),define("Renderer/MipmapHint",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={DONT_CARE:t.DONT_CARE,FASTEST:t.FASTEST,NICEST:t.NICEST,validate:function(e){return e===r.DONT_CARE||e===r.FASTEST||e===r.NICEST}};return e(r)}),define("Renderer/TextureMagnificationFilter",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={NEAREST:t.NEAREST,LINEAR:t.LINEAR,validate:function(e){return e===r.NEAREST||e===r.LINEAR}};return e(r)}),define("Renderer/TextureMinificationFilter",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={NEAREST:t.NEAREST,LINEAR:t.LINEAR,NEAREST_MIPMAP_NEAREST:t.NEAREST_MIPMAP_NEAREST,LINEAR_MIPMAP_NEAREST:t.LINEAR_MIPMAP_NEAREST,NEAREST_MIPMAP_LINEAR:t.NEAREST_MIPMAP_LINEAR,LINEAR_MIPMAP_LINEAR:t.LINEAR_MIPMAP_LINEAR,validate:function(e){return e===r.NEAREST||e===r.LINEAR||e===r.NEAREST_MIPMAP_NEAREST||e===r.LINEAR_MIPMAP_NEAREST||e===r.NEAREST_MIPMAP_LINEAR||e===r.LINEAR_MIPMAP_LINEAR}};return e(r)}),define("Renderer/TextureWrap",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={CLAMP_TO_EDGE:t.CLAMP_TO_EDGE,REPEAT:t.REPEAT,MIRRORED_REPEAT:t.MIRRORED_REPEAT,validate:function(e){return e===r.CLAMP_TO_EDGE||e===r.REPEAT||e===r.MIRRORED_REPEAT}};return e(r)}),define("Renderer/Sampler",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","./TextureMagnificationFilter","./TextureMinificationFilter","./TextureWrap"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT);var i=t(e.wrapS,s.CLAMP_TO_EDGE),n=t(e.wrapT,s.CLAMP_TO_EDGE),l=t(e.minificationFilter,a.LINEAR),u=t(e.magnificationFilter,o.LINEAR),c=r(e.maximumAnisotropy)?e.maximumAnisotropy:1;this._wrapS=i,this._wrapT=n,this._minificationFilter=l,this._magnificationFilter=u,this._maximumAnisotropy=c}return i(l.prototype,{wrapS:{get:function(){return this._wrapS}},wrapT:{get:function(){return this._wrapT}},minificationFilter:{get:function(){return this._minificationFilter}},magnificationFilter:{get:function(){return this._magnificationFilter}},maximumAnisotropy:{get:function(){return this._maximumAnisotropy}}}),l}),define("Renderer/CubeMap",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Math","../Core/PixelFormat","./ContextLimits","./CubeMapFace","./MipmapHint","./PixelDatatype","./Sampler","./TextureMagnificationFilter","./TextureMinificationFilter"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){function i(e,t){t.arrayBufferView?v.texImage2D(e,0,p,c,c,0,p,f,t.arrayBufferView):v.texImage2D(e,0,p,p,f,t)}e=t(e,t.EMPTY_OBJECT);var n,o=e.context,a=e.source;if(r(a)){var l=[a.positiveX,a.negativeX,a.positiveY,a.negativeY,a.positiveZ,a.negativeZ];n=l[0].width,l[0].height}else n=e.width,e.height;var c=n,p=t(e.pixelFormat,s.RGBA),f=t(e.pixelDatatype,d.UNSIGNED_BYTE),m=6*s.textureSizeInBytes(p,f,c,c),g=e.preMultiplyAlpha||p===s.RGB||p===s.LUMINANCE,_=t(e.flipY,!0),v=o._gl,y=v.TEXTURE_CUBE_MAP,b=v.createTexture();v.activeTexture(v.TEXTURE0),v.bindTexture(y,b),r(a)?(v.pixelStorei(v.UNPACK_PREMULTIPLY_ALPHA_WEBGL,g),v.pixelStorei(v.UNPACK_FLIP_Y_WEBGL,_),i(v.TEXTURE_CUBE_MAP_POSITIVE_X,a.positiveX),i(v.TEXTURE_CUBE_MAP_NEGATIVE_X,a.negativeX),i(v.TEXTURE_CUBE_MAP_POSITIVE_Y,a.positiveY),i(v.TEXTURE_CUBE_MAP_NEGATIVE_Y,a.negativeY),i(v.TEXTURE_CUBE_MAP_POSITIVE_Z,a.positiveZ),i(v.TEXTURE_CUBE_MAP_NEGATIVE_Z,a.negativeZ)):(v.texImage2D(v.TEXTURE_CUBE_MAP_POSITIVE_X,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_NEGATIVE_X,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_POSITIVE_Y,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_NEGATIVE_Y,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_POSITIVE_Z,0,p,c,c,0,p,f,null),v.texImage2D(v.TEXTURE_CUBE_MAP_NEGATIVE_Z,0,p,c,c,0,p,f,null)),v.bindTexture(y,null),this._gl=v,this._textureFilterAnisotropic=o._textureFilterAnisotropic,this._textureTarget=y,this._texture=b,this._pixelFormat=p,this._pixelDatatype=f,this._size=c,this._hasMipmap=!1,this._sizeInBytes=m,this._preMultiplyAlpha=g,this._flipY=_,this._sampler=void 0,this._positiveX=new u(v,b,y,v.TEXTURE_CUBE_MAP_POSITIVE_X,p,f,c,g,_),this._negativeX=new u(v,b,y,v.TEXTURE_CUBE_MAP_NEGATIVE_X,p,f,c,g,_),this._positiveY=new u(v,b,y,v.TEXTURE_CUBE_MAP_POSITIVE_Y,p,f,c,g,_),this._negativeY=new u(v,b,y,v.TEXTURE_CUBE_MAP_NEGATIVE_Y,p,f,c,g,_),this._positiveZ=new u(v,b,y,v.TEXTURE_CUBE_MAP_POSITIVE_Z,p,f,c,g,_),this._negativeZ=new u(v,b,y,v.TEXTURE_CUBE_MAP_NEGATIVE_Z,p,f,c,g,_),this.sampler=r(e.sampler)?e.sampler:new h}return i(m.prototype,{positiveX:{get:function(){return this._positiveX}},negativeX:{get:function(){return this._negativeX}},positiveY:{get:function(){return this._positiveY}},negativeY:{get:function(){return this._negativeY}},positiveZ:{get:function(){return this._positiveZ}},negativeZ:{get:function(){return this._negativeZ}},sampler:{get:function(){return this._sampler},set:function(e){var t=e.minificationFilter,i=e.magnificationFilter,n=t===f.NEAREST_MIPMAP_NEAREST||t===f.NEAREST_MIPMAP_LINEAR||t===f.LINEAR_MIPMAP_NEAREST||t===f.LINEAR_MIPMAP_LINEAR;this._pixelDatatype===d.FLOAT&&(t=n?f.NEAREST_MIPMAP_NEAREST:f.NEAREST,i=p.NEAREST);var o=this._gl,a=this._textureTarget;o.activeTexture(o.TEXTURE0),o.bindTexture(a,this._texture),o.texParameteri(a,o.TEXTURE_MIN_FILTER,t),o.texParameteri(a,o.TEXTURE_MAG_FILTER,i),o.texParameteri(a,o.TEXTURE_WRAP_S,e.wrapS),o.texParameteri(a,o.TEXTURE_WRAP_T,e.wrapT),r(this._textureFilterAnisotropic)&&o.texParameteri(a,this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,e.maximumAnisotropy),o.bindTexture(a,null),this._sampler=e}},pixelFormat:{get:function(){return this._pixelFormat}},pixelDatatype:{get:function(){return this._pixelDatatype}},width:{get:function(){return this._size}},height:{get:function(){return this._size}},sizeInBytes:{get:function(){return this._hasMipmap?Math.floor(4*this._sizeInBytes/3):this._sizeInBytes}},preMultiplyAlpha:{get:function(){return this._preMultiplyAlpha}},flipY:{get:function(){return this._flipY}},_target:{get:function(){return this._textureTarget}}}),m.prototype.generateMipmap=function(e){e=t(e,c.DONT_CARE),this._hasMipmap=!0;var r=this._gl,i=this._textureTarget;r.hint(r.GENERATE_MIPMAP_HINT,e),r.activeTexture(r.TEXTURE0),r.bindTexture(i,this._texture),r.generateMipmap(i),r.bindTexture(i,null)},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){return this._gl.deleteTexture(this._texture),this._positiveX=n(this._positiveX),this._negativeX=n(this._negativeX),this._positiveY=n(this._positiveY),this._negativeY=n(this._negativeY),this._positiveZ=n(this._positiveZ),this._negativeZ=n(this._negativeZ),n(this)},m}),define("Renderer/Texture",["../Core/Cartesian2","../Core/Check","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Math","../Core/PixelFormat","../Core/WebGLConstants","./ContextLimits","./MipmapHint","./PixelDatatype","./Sampler","./TextureMagnificationFilter","./TextureMinificationFilter"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(t){t=i(t,i.EMPTY_OBJECT);var o=t.context,a=t.width,s=t.height,l=t.source;n(l)&&(n(a)||(a=i(l.videoWidth,l.width)),n(s)||(s=i(l.videoHeight,l.height)));var d=i(t.pixelFormat,u.RGBA),h=i(t.pixelDatatype,p.UNSIGNED_BYTE),m=d,g=u.isCompressedFormat(m);if(o.webgl2&&(d===u.DEPTH_STENCIL?m=c.DEPTH24_STENCIL8:d===u.DEPTH_COMPONENT&&(h===p.UNSIGNED_SHORT?m=c.DEPTH_COMPONENT16:h===p.UNSIGNED_INT&&(m=c.DEPTH_COMPONENT24)),h===p.FLOAT))switch(d){case u.RGBA:m=c.RGBA32F;break;case u.RGB:m=c.RGB32F;break;case u.RG:m=c.RG32F;break;case u.R:m=c.R32F}var _=t.preMultiplyAlpha||d===u.RGB||d===u.LUMINANCE,v=i(t.flipY,!0),y=o._gl,b=y.TEXTURE_2D,C=y.createTexture();y.activeTexture(y.TEXTURE0),y.bindTexture(b,C),n(l)?(y.pixelStorei(y.UNPACK_PREMULTIPLY_ALPHA_WEBGL,_),y.pixelStorei(y.UNPACK_FLIP_Y_WEBGL,v),n(l.arrayBufferView)?g?y.compressedTexImage2D(b,0,m,a,s,0,l.arrayBufferView):y.texImage2D(b,0,m,a,s,0,d,h,l.arrayBufferView):n(l.framebuffer)?(l.framebuffer!==o.defaultFramebuffer&&l.framebuffer._bind(),y.copyTexImage2D(b,0,m,l.xOffset,l.yOffset,a,s,0),l.framebuffer!==o.defaultFramebuffer&&l.framebuffer._unBind()):y.texImage2D(b,0,m,d,h,l)):y.texImage2D(b,0,m,a,s,0,d,h,null),y.bindTexture(b,null);var S;S=g?u.compressedTextureSizeInBytes(d,a,s):u.textureSizeInBytes(d,h,a,s),this._id=r(),this._context=o,this._textureFilterAnisotropic=o._textureFilterAnisotropic,this._textureTarget=b,this._texture=C,this._pixelFormat=d,this._pixelDatatype=h,this._width=a,this._height=s,this._dimensions=new e(a,s),this._hasMipmap=!1,this._sizeInBytes=S,this._preMultiplyAlpha=_,this._flipY=v,this._sampler=void 0,this.sampler=n(t.sampler)?t.sampler:new f}return _.fromFramebuffer=function(e){e=i(e,i.EMPTY_OBJECT);var t=e.context,r=t._gl,o=i(e.pixelFormat,u.RGB),a=i(e.framebufferXOffset,0),s=i(e.framebufferYOffset,0),l=i(e.width,r.drawingBufferWidth),c=i(e.height,r.drawingBufferHeight),d=e.framebuffer;return new _({context:t,width:l,height:c,pixelFormat:o,source:{framebuffer:n(d)?d:t.defaultFramebuffer,xOffset:a,yOffset:s,width:l,height:c}})},o(_.prototype,{id:{get:function(){return this._id}},sampler:{get:function(){return this._sampler},set:function(e){var t=e.minificationFilter,r=e.magnificationFilter,i=t===g.NEAREST_MIPMAP_NEAREST||t===g.NEAREST_MIPMAP_LINEAR||t===g.LINEAR_MIPMAP_NEAREST||t===g.LINEAR_MIPMAP_LINEAR;this._pixelDatatype===p.FLOAT&&(t=i?g.NEAREST_MIPMAP_NEAREST:g.NEAREST,r=m.NEAREST);var o=this._context._gl,a=this._textureTarget;o.activeTexture(o.TEXTURE0),o.bindTexture(a,this._texture),o.texParameteri(a,o.TEXTURE_MIN_FILTER,t),o.texParameteri(a,o.TEXTURE_MAG_FILTER,r),o.texParameteri(a,o.TEXTURE_WRAP_S,e.wrapS),o.texParameteri(a,o.TEXTURE_WRAP_T,e.wrapT),n(this._textureFilterAnisotropic)&&o.texParameteri(a,this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,e.maximumAnisotropy),o.bindTexture(a,null),this._sampler=e}},pixelFormat:{get:function(){return this._pixelFormat}},pixelDatatype:{get:function(){return this._pixelDatatype}},dimensions:{get:function(){return this._dimensions}},preMultiplyAlpha:{get:function(){return this._preMultiplyAlpha}},flipY:{get:function(){return this._flipY}},width:{get:function(){return this._width}},height:{get:function(){return this._height}},sizeInBytes:{get:function(){return this._hasMipmap?Math.floor(4*this._sizeInBytes/3):this._sizeInBytes}},_target:{get:function(){return this._textureTarget}}}),_.prototype.copyFrom=function(e,t,r){t=i(t,0),r=i(r,0);var n=this._context._gl,o=this._textureTarget;n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this._preMultiplyAlpha),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,this._flipY),n.activeTexture(n.TEXTURE0),n.bindTexture(o,this._texture),e.arrayBufferView?n.texSubImage2D(o,0,t,r,e.width,e.height,this._pixelFormat,this._pixelDatatype,e.arrayBufferView):n.texSubImage2D(o,0,t,r,this._pixelFormat,this._pixelDatatype,e),n.bindTexture(o,null)},_.prototype.copyFromFramebuffer=function(e,t,r,n,o,a){e=i(e,0),t=i(t,0),r=i(r,0),n=i(n,0),o=i(o,this._width),a=i(a,this._height);var s=this._context._gl,l=this._textureTarget;s.activeTexture(s.TEXTURE0),s.bindTexture(l,this._texture),s.copyTexSubImage2D(l,0,e,t,r,n,o,a),s.bindTexture(l,null)},_.prototype.generateMipmap=function(e){e=i(e,h.DONT_CARE),this._hasMipmap=!0;var t=this._context._gl,r=this._textureTarget;t.hint(t.GENERATE_MIPMAP_HINT,e),t.activeTexture(t.TEXTURE0),t.bindTexture(r,this._texture),t.generateMipmap(r),t.bindTexture(r,null)},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return this._context._gl.deleteTexture(this._texture),a(this)},_}),define("Shaders/Materials/BumpMapMaterial",[],function(){"use strict";return"uniform sampler2D image;\nuniform float strength;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nvec2 centerPixel = fract(repeat * st);\nfloat centerBump = texture2D(image, centerPixel).channel;\nfloat imageWidth = float(imageDimensions.x);\nvec2 rightPixel = fract(repeat * (st + vec2(1.0 / imageWidth, 0.0)));\nfloat rightBump = texture2D(image, rightPixel).channel;\nfloat imageHeight = float(imageDimensions.y);\nvec2 leftPixel = fract(repeat * (st + vec2(0.0, 1.0 / imageHeight)));\nfloat topBump = texture2D(image, leftPixel).channel;\nvec3 normalTangentSpace = normalize(vec3(centerBump - rightBump, centerBump - topBump, clamp(1.0 - strength, 0.1, 1.0)));\nvec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\nmaterial.normal = normalEC;\nmaterial.diffuse = vec3(0.01);\nreturn material;\n}\n"}),define("Shaders/Materials/CheckerboardMaterial",[],function(){"use strict";return"uniform vec4 lightColor;\nuniform vec4 darkColor;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat b = mod(floor(repeat.s * st.s) + floor(repeat.t * st.t), 2.0);\nfloat scaledWidth = fract(repeat.s * st.s);\nscaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\nfloat scaledHeight = fract(repeat.t * st.t);\nscaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\nfloat value = min(scaledWidth, scaledHeight);\nvec4 currentColor = mix(lightColor, darkColor, b);\nvec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03);\nmaterial.diffuse = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/DotMaterial",[],function(){"use strict";return"uniform vec4 lightColor;\nuniform vec4 darkColor;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat b = smoothstep(0.3, 0.32, length(fract(repeat * materialInput.st) - 0.5));\nvec4 color = mix(lightColor, darkColor, b);\nmaterial.diffuse = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/ElevationContourMaterial",[],function(){"use strict";return"#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\nuniform vec4 color;\nuniform float spacing;\nuniform float width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat distanceToContour = mod(materialInput.height, spacing);\n#ifdef GL_OES_standard_derivatives\nfloat dxc = abs(dFdx(materialInput.height));\nfloat dyc = abs(dFdy(materialInput.height));\nfloat dF = max(dxc, dyc) * width;\nmaterial.alpha = (distanceToContour < dF) ? 1.0 : 0.0;\n#else\nmaterial.alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0;\n#endif\nmaterial.diffuse = color.rgb;\nreturn material;\n}\n"}),define("Shaders/Materials/ElevationRampMaterial",[],function(){"use strict";return"uniform sampler2D image;\nuniform float minimumHeight;\nuniform float maximumHeight;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat scaledHeight = clamp((materialInput.height - minimumHeight) / (maximumHeight - minimumHeight), 0.0, 1.0);\nvec4 rampColor = texture2D(image, vec2(scaledHeight, 0.5));\nmaterial.diffuse = rampColor.rgb;\nmaterial.alpha = rampColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/FadeMaterial",[],function(){"use strict";return"uniform vec4 fadeInColor;\nuniform vec4 fadeOutColor;\nuniform float maximumDistance;\nuniform bool repeat;\nuniform vec2 fadeDirection;\nuniform vec2 time;\nfloat getTime(float t, float coord)\n{\nfloat scalar = 1.0 / maximumDistance;\nfloat q = distance(t, coord) * scalar;\nif (repeat)\n{\nfloat r = distance(t, coord + 1.0) * scalar;\nfloat s = distance(t, coord - 1.0) * scalar;\nq = min(min(r, s), q);\n}\nreturn clamp(q, 0.0, 1.0);\n}\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat s = getTime(time.x, st.s) * fadeDirection.s;\nfloat t = getTime(time.y, st.t) * fadeDirection.t;\nfloat u = length(vec2(s, t));\nvec4 color = mix(fadeInColor, fadeOutColor, u);\nmaterial.emission = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/GridMaterial",[],function(){"use strict";return"#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\nuniform vec4 color;\nuniform float cellAlpha;\nuniform vec2 lineCount;\nuniform vec2 lineThickness;\nuniform vec2 lineOffset;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat scaledWidth = fract(lineCount.s * st.s - lineOffset.s);\nscaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\nfloat scaledHeight = fract(lineCount.t * st.t - lineOffset.t);\nscaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\nfloat value;\n#ifdef GL_OES_standard_derivatives\nconst float fuzz = 1.2;\nvec2 thickness = (lineThickness * czm_resolutionScale) - 1.0;\nvec2 dx = abs(dFdx(st));\nvec2 dy = abs(dFdy(st));\nvec2 dF = vec2(max(dx.s, dy.s), max(dx.t, dy.t)) * lineCount;\nvalue = min(\nsmoothstep(dF.s * thickness.s, dF.s * (fuzz + thickness.s), scaledWidth),\nsmoothstep(dF.t * thickness.t, dF.t * (fuzz + thickness.t), scaledHeight));\n#else\nconst float fuzz = 0.05;\nvec2 range = 0.5 - (lineThickness * 0.05);\nvalue = min(\n1.0 - smoothstep(range.s, range.s + fuzz, scaledWidth),\n1.0 - smoothstep(range.t, range.t + fuzz, scaledHeight));\n#endif\nfloat dRim = 1.0 - abs(dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC)));\nfloat sRim = smoothstep(0.8, 1.0, dRim);\nvalue *= (1.0 - sRim);\nvec3 halfColor = color.rgb * 0.5;\nmaterial.diffuse = halfColor;\nmaterial.emission = halfColor;\nmaterial.alpha = color.a * (1.0 - ((1.0 - cellAlpha) * value));\nreturn material;\n}\n"}),define("Shaders/Materials/NormalMapMaterial",[],function(){"use strict";return"uniform sampler2D image;\nuniform float strength;\nuniform vec2 repeat;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec4 textureValue = texture2D(image, fract(repeat * materialInput.st));\nvec3 normalTangentSpace = textureValue.channels;\nnormalTangentSpace.xy = normalTangentSpace.xy * 2.0 - 1.0;\nnormalTangentSpace.z = clamp(1.0 - strength, 0.1, 1.0);\nnormalTangentSpace = normalize(normalTangentSpace);\nvec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\nmaterial.normal = normalEC;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineArrowMaterial",[],function(){"use strict";return"#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\nuniform vec4 color;\nvarying float v_width;\nfloat getPointOnLine(vec2 p0, vec2 p1, float x)\n{\nfloat slope = (p0.y - p1.y) / (p0.x - p1.x);\nreturn slope * (x - p0.x) + p0.y;\n}\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\n#ifdef GL_OES_standard_derivatives\nfloat base = 1.0 - abs(fwidth(st.s)) * 10.0;\n#else\nfloat base = 0.99;\n#endif\nvec2 center = vec2(1.0, 0.5);\nfloat ptOnUpperLine = getPointOnLine(vec2(base, 1.0), center, st.s);\nfloat ptOnLowerLine = getPointOnLine(vec2(base, 0.0), center, st.s);\nfloat halfWidth = 0.15;\nfloat s = step(0.5 - halfWidth, st.t);\ns *= 1.0 - step(0.5 + halfWidth, st.t);\ns *= 1.0 - step(base, st.s);\nfloat t = step(base, materialInput.st.s);\nt *= 1.0 - step(ptOnUpperLine, st.t);\nt *= step(ptOnLowerLine, st.t);\nfloat dist;\nif (st.s < base)\n{\nfloat d1 = abs(st.t - (0.5 - halfWidth));\nfloat d2 = abs(st.t - (0.5 + halfWidth));\ndist = min(d1, d2);\n}\nelse\n{\nfloat d1 = czm_infinity;\nif (st.t < 0.5 - halfWidth && st.t > 0.5 + halfWidth)\n{\nd1 = abs(st.s - base);\n}\nfloat d2 = abs(st.t - ptOnUpperLine);\nfloat d3 = abs(st.t - ptOnLowerLine);\ndist = min(min(d1, d2), d3);\n}\nvec4 outsideColor = vec4(0.0);\nvec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0));\nvec4 outColor = czm_antialias(outsideColor, color, currentColor, dist);\nmaterial.diffuse = outColor.rgb;\nmaterial.alpha = outColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineDashMaterial",[],function(){"use strict" +;return"uniform vec4 color;\nuniform vec4 gapColor;\nuniform float dashLength;\nuniform float dashPattern;\nvarying float v_polylineAngle;\nconst float maskLength = 16.0;\nmat2 rotate(float rad) {\nfloat c = cos(rad);\nfloat s = sin(rad);\nreturn mat2(\nc, s,\n-s, c\n);\n}\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 pos = rotate(v_polylineAngle) * gl_FragCoord.xy;\nfloat dashPosition = fract(pos.x / dashLength);\nfloat maskIndex = floor(dashPosition * maskLength);\nfloat maskTest = floor(dashPattern / pow(2.0, maskIndex));\nvec4 fragColor = (mod(maskTest, 2.0) < 1.0) ? gapColor : color;\nif (fragColor.a < 0.005) {\ndiscard;\n}\nmaterial.emission = fragColor.rgb;\nmaterial.alpha = fragColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineGlowMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform float glowPower;\nvarying float v_width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5);\nmaterial.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb);\nmaterial.alpha = clamp(0.0, 1.0, glow) * color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/PolylineOutlineMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform vec4 outlineColor;\nuniform float outlineWidth;\nvarying float v_width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec2 st = materialInput.st;\nfloat halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width;\nfloat b = step(0.5 - halfInteriorWidth, st.t);\nb *= 1.0 - step(0.5 + halfInteriorWidth, st.t);\nfloat d1 = abs(st.t - (0.5 - halfInteriorWidth));\nfloat d2 = abs(st.t - (0.5 + halfInteriorWidth));\nfloat dist = min(d1, d2);\nvec4 currentColor = mix(outlineColor, color, b);\nvec4 outColor = czm_antialias(outlineColor, color, currentColor, dist);\nmaterial.diffuse = outColor.rgb;\nmaterial.alpha = outColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/RimLightingMaterial",[],function(){"use strict";return"uniform vec4 color;\nuniform vec4 rimColor;\nuniform float width;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat d = 1.0 - dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC));\nfloat s = smoothstep(1.0 - width, 1.0, d);\nmaterial.diffuse = color.rgb;\nmaterial.emission = rimColor.rgb * s;\nmaterial.alpha = mix(color.a, rimColor.a, s);\nreturn material;\n}\n"}),define("Shaders/Materials/SlopeRampMaterial",[],function(){"use strict";return"uniform sampler2D image;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nvec4 rampColor = texture2D(image, vec2(materialInput.slope, 0.5));\nmaterial.diffuse = rampColor.rgb;\nmaterial.alpha = rampColor.a;\nreturn material;\n}\n"}),define("Shaders/Materials/StripeMaterial",[],function(){"use strict";return"uniform vec4 evenColor;\nuniform vec4 oddColor;\nuniform float offset;\nuniform float repeat;\nuniform bool horizontal;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat coord = mix(materialInput.st.s, materialInput.st.t, float(horizontal));\nfloat value = fract((coord - offset) * (repeat * 0.5));\nfloat dist = min(value, min(abs(value - 0.5), 1.0 - value));\nvec4 currentColor = mix(evenColor, oddColor, step(0.5, value));\nvec4 color = czm_antialias(evenColor, oddColor, currentColor, dist);\nmaterial.diffuse = color.rgb;\nmaterial.alpha = color.a;\nreturn material;\n}\n"}),define("Shaders/Materials/Water",[],function(){"use strict";return"uniform sampler2D specularMap;\nuniform sampler2D normalMap;\nuniform vec4 baseWaterColor;\nuniform vec4 blendColor;\nuniform float frequency;\nuniform float animationSpeed;\nuniform float amplitude;\nuniform float specularIntensity;\nuniform float fadeFactor;\nczm_material czm_getMaterial(czm_materialInput materialInput)\n{\nczm_material material = czm_getDefaultMaterial(materialInput);\nfloat time = czm_frameNumber * animationSpeed;\nfloat fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);\nfloat specularMapValue = texture2D(specularMap, materialInput.st).r;\nvec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);\nvec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));\nnormalTangentSpace.xy /= fade;\nnormalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);\nnormalTangentSpace = normalize(normalTangentSpace);\nfloat tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);\nmaterial.alpha = specularMapValue;\nmaterial.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);\nmaterial.diffuse += (0.1 * tsPerturbationRatio);\nmaterial.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);\nmaterial.specular = specularIntensity;\nmaterial.shininess = 10.0;\nreturn material;\n}\n"}),define("Scene/Material",["../Core/Cartesian2","../Core/clone","../Core/Color","../Core/combine","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/isArray","../Core/loadCRN","../Core/loadKTX","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4","../Core/Resource","../Renderer/CubeMap","../Renderer/Texture","../Shaders/Materials/BumpMapMaterial","../Shaders/Materials/CheckerboardMaterial","../Shaders/Materials/DotMaterial","../Shaders/Materials/ElevationContourMaterial","../Shaders/Materials/ElevationRampMaterial","../Shaders/Materials/FadeMaterial","../Shaders/Materials/GridMaterial","../Shaders/Materials/NormalMapMaterial","../Shaders/Materials/PolylineArrowMaterial","../Shaders/Materials/PolylineDashMaterial","../Shaders/Materials/PolylineGlowMaterial","../Shaders/Materials/PolylineOutlineMaterial","../Shaders/Materials/RimLightingMaterial","../Shaders/Materials/SlopeRampMaterial","../Shaders/Materials/StripeMaterial","../Shaders/Materials/Water","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N){"use strict";function k(e){this.type=void 0,this.shaderSource=void 0,this.materials=void 0,this.uniforms=void 0,this._uniforms=void 0,this.translucent=void 0,this._strict=void 0,this._template=void 0,this._count=void 0,this._texturePaths={},this._loadedImages=[],this._loadedCubeMaps=[],this._textures={},this._updateFunctions=[],this._defaultTexture=void 0,F(e,this),s(this,{type:{value:this.type,writable:!1}}),a(k._uniformList[this.type])||(k._uniformList[this.type]=Object.keys(this._uniforms))}function F(e,r){e=o(e,o.EMPTY_OBJECT),r._strict=o(e.strict,!1),r._count=o(e.count,0),r._template=t(o(e.fabric,o.EMPTY_OBJECT)),r._template.uniforms=t(o(r._template.uniforms,o.EMPTY_OBJECT)),r._template.materials=t(o(r._template.materials,o.EMPTY_OBJECT)),r.type=a(r._template.type)?r._template.type:n(),r.shaderSource="",r.materials={},r.uniforms={},r._uniforms={},r._translucentFunctions=[];var s,l=k._materialCache.getMaterial(r.type);if(a(l)){var u=t(l.fabric,!0);r._template=i(r._template,u,!0),s=l.translucent}z(r),a(l)||k._materialCache.addMaterial(r.type,r),G(r),j(r),X(r);var c=0===r._translucentFunctions.length||void 0;if(s=o(s,c),s=o(e.translucent,s),a(s))if("function"==typeof s){var d=function(){return s(r)};r._translucentFunctions.push(d)}else r._translucentFunctions.push(s)}function B(e,t,r,i){if(a(e))for(var n in e)if(e.hasOwnProperty(n)){var o=-1!==t.indexOf(n);(i&&!o||!i&&o)&&r(n,t)}}function U(e,t){}function V(e,t){}function z(e){var t=e._template,r=t.uniforms,i=t.materials,n=t.components;B(t,K,U,!0),B(n,J,U,!0);var o=[];for(var a in i)i.hasOwnProperty(a)&&o.push(a);B(r,o,V,!1)}function G(e){var t=e._template.components,r=e._template.source;if(a(r))e.shaderSource+=r+"\n";else{if(e.shaderSource+="czm_material czm_getMaterial(czm_materialInput materialInput)\n{\n",e.shaderSource+="czm_material material = czm_getDefaultMaterial(materialInput);\n",a(t))for(var i in t)t.hasOwnProperty(i)&&(e.shaderSource+="material."+i+" = "+t[i]+";\n");e.shaderSource+="return material;\n}\n"}}function W(e){var t;return function(r,i){var n=r.uniforms,o=n[e],s=t!==o;t=o;var l,u,c=r._textures[e];if(o instanceof HTMLVideoElement)if(o.readyState>=2){if(s&&a(c)&&(c!==i.defaultTexture&&c.destroy(),c=void 0),!a(c)||c===i.defaultTexture)return c=new v({context:i,source:o}),void(r._textures[e]=c);c.copyFrom(o)}else a(c)||(r._textures[e]=i.defaultTexture);else{if(o instanceof v&&o!==c){r._texturePaths[e]=void 0;var p=r._textures[e];return p!==r._defaultTexture&&p.destroy(),r._textures[e]=o,l=e+"Dimensions",void(n.hasOwnProperty(l)&&(u=n[l],u.x=o._width,u.y=o._height))}if(a(c)||(r._texturePaths[e]=void 0,a(r._defaultTexture)||(r._defaultTexture=i.defaultTexture),c=r._textures[e]=r._defaultTexture,l=e+"Dimensions",n.hasOwnProperty(l)&&(u=n[l],u.x=c._width,u.y=c._height)),o!==k.DefaultImageId&&o!==r._texturePaths[e]){if("string"==typeof o){var f,m=new g({url:o});f=ee.test(o)?h(m):te.test(o)?d(m):m.fetchImage(),N(f,function(t){r._loadedImages.push({id:e,image:t})})}else o instanceof HTMLCanvasElement&&r._loadedImages.push({id:e,image:o});r._texturePaths[e]=o}}}}function H(e){return function(t,r){var i=t.uniforms[e];if(i instanceof _){var n=t._textures[e];return n!==t._defaultTexture&&n.destroy(),t._texturePaths[e]=void 0,void(t._textures[e]=i)}if(a(t._textures[e])||(t._texturePaths[e]=void 0,t._textures[e]=r.defaultCubeMap),i!==k.DefaultCubeMapId){var o=i.positiveX+i.negativeX+i.positiveY+i.negativeY+i.positiveZ+i.negativeZ;if(o!==t._texturePaths[e]){var s=[g.createIfNeeded(i.positiveX).fetchImage(),g.createIfNeeded(i.negativeX).fetchImage(),g.createIfNeeded(i.positiveY).fetchImage(),g.createIfNeeded(i.negativeY).fetchImage(),g.createIfNeeded(i.positiveZ).fetchImage(),g.createIfNeeded(i.negativeZ).fetchImage()];N.all(s).then(function(r){t._loadedCubeMaps.push({id:e,images:r})}),t._texturePaths[e]=o}}}}function j(e){var t=e._template.uniforms;for(var r in t)t.hasOwnProperty(r)&&q(e,r)}function q(e,t){var r=(e._strict,e._template.uniforms),i=r[t],n=Y(i);if("channels"===n)Q(e,t,i,!1);else{if("sampler2D"===n){var o=t+"Dimensions";Z(e,o)>0&&(r[o]={type:"ivec3",x:1,y:1},q(e,o))}if(!new RegExp("uniform\\s+"+n+"\\s+"+t+"\\s*;").test(e.shaderSource)){var a="uniform "+n+" "+t+";";e.shaderSource=a+e.shaderSource}var s=t+"_"+e._count++;if(Q(e,t,s),e.uniforms[t]=i,"sampler2D"===n)e._uniforms[s]=function(){return e._textures[t]},e._updateFunctions.push(W(t));else if("samplerCube"===n)e._uniforms[s]=function(){return e._textures[t]},e._updateFunctions.push(H(t));else if(-1!==n.indexOf("mat")){var l=new $[n];e._uniforms[s]=function(){return $[n].fromColumnMajorArray(e.uniforms[t],l)}}else e._uniforms[s]=function(){return e.uniforms[t]}}}function Y(e){var t=e.type;if(!a(t)){var r=typeof e;if("number"===r)t="float";else if("boolean"===r)t="bool";else if("string"===r||e instanceof HTMLCanvasElement)t=/^([rgba]){1,4}$/i.test(e)?"channels":e===k.DefaultCubeMapId?"samplerCube":"sampler2D";else if("object"===r)if(c(e))4!==e.length&&9!==e.length&&16!==e.length||(t="mat"+Math.sqrt(e.length));else{var i=0;for(var n in e)e.hasOwnProperty(n)&&(i+=1);i>=2&&i<=4?t="vec"+i:6===i&&(t="samplerCube")}}return t}function X(e){var t=e._strict,r=e._template.materials;for(var n in r)if(r.hasOwnProperty(n)){var o=new k({strict:t,fabric:r[n],count:e._count});e._count=o._count,e._uniforms=i(e._uniforms,o._uniforms,!0),e.materials[n]=o,e._translucentFunctions=e._translucentFunctions.concat(o._translucentFunctions);var a="czm_getMaterial_"+e._count++;Q(o,"czm_getMaterial",a),e.shaderSource=o.shaderSource+e.shaderSource;var s=a+"(materialInput)";Q(e,n,s)}}function Q(e,t,r,i){i=o(i,!0);var n=0,a="([\\w"+(i?".":"")+"])?",s=new RegExp(a+t+"([\\w])?","g");return e.shaderSource=e.shaderSource.replace(s,function(e,t,i){return t||i?e:(n+=1,r)}),n}function Z(e,t,r){return Q(e,t,t,r)}k._uniformList={},k.fromType=function(e,t){var r=new k({fabric:{type:e}});if(a(t))for(var i in t)t.hasOwnProperty(i)&&(r.uniforms[i]=t[i]);return r},k.prototype.isTranslucent=function(){if(a(this.translucent))return"function"==typeof this.translucent?this.translucent():this.translucent;for(var e=!0,t=this._translucentFunctions,r=t.length,i=0;i<r;++i){var n=t[i];if(!(e="function"==typeof n?e&&n():e&&n))break}return e},k.prototype.update=function(e){var t,r,i=this._loadedImages,n=i.length;for(t=0;t<n;++t){var o=i[t];r=o.id;var s,l=o.image;s=new v(a(l.internalFormat)?{context:e,pixelFormat:l.internalFormat,width:l.width,height:l.height,source:{arrayBufferView:l.bufferView}}:{context:e,source:l}),this._textures[r]=s;var u=r+"Dimensions";if(this.uniforms.hasOwnProperty(u)){var c=this.uniforms[u];c.x=s._width,c.y=s._height}}i.length=0;var d=this._loadedCubeMaps;for(n=d.length,t=0;t<n;++t){var h=d[t];r=h.id;var p=h.images,f=new _({context:e,source:{positiveX:p[0],negativeX:p[1],positiveY:p[2],negativeY:p[3],positiveZ:p[4],negativeZ:p[5]}});this._textures[r]=f}d.length=0;var m=this._updateFunctions;for(n=m.length,t=0;t<n;++t)m[t](this,e);var g=this.materials;for(var y in g)g.hasOwnProperty(y)&&g[y].update(e)},k.prototype.isDestroyed=function(){return!1},k.prototype.destroy=function(){var e=this._textures;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];r!==this._defaultTexture&&r.destroy()}var i=this.materials;for(var n in i)i.hasOwnProperty(n)&&i[n].destroy();return l(this)};var K=["type","materials","uniforms","components","source"],J=["diffuse","specular","shininess","normal","emission","alpha"],$={mat2:p,mat3:f,mat4:m},ee=/\.ktx$/i,te=/\.crn$/i;return k._materialCache={_materials:{},addMaterial:function(e,t){this._materials[e]=t},getMaterial:function(e){return this._materials[e]}},k.DefaultImageId="czm_defaultImage",k.DefaultCubeMapId="czm_defaultCubeMap",k.ColorType="Color",k._materialCache.addMaterial(k.ColorType,{fabric:{type:k.ColorType,uniforms:{color:new r(1,0,0,.5)},components:{diffuse:"color.rgb",alpha:"color.a"}},translucent:function(e){return e.uniforms.color.alpha<1}}),k.ImageType="Image",k._materialCache.addMaterial(k.ImageType,{fabric:{type:k.ImageType,uniforms:{image:k.DefaultImageId,repeat:new e(1,1),color:new r(1,1,1,1)},components:{diffuse:"texture2D(image, fract(repeat * materialInput.st)).rgb * color.rgb",alpha:"texture2D(image, fract(repeat * materialInput.st)).a * color.a"}},translucent:function(e){return e.uniforms.color.alpha<1}}),k.DiffuseMapType="DiffuseMap",k._materialCache.addMaterial(k.DiffuseMapType,{fabric:{type:k.DiffuseMapType,uniforms:{image:k.DefaultImageId,channels:"rgb",repeat:new e(1,1)},components:{diffuse:"texture2D(image, fract(repeat * materialInput.st)).channels"}},translucent:!1}),k.AlphaMapType="AlphaMap",k._materialCache.addMaterial(k.AlphaMapType,{fabric:{type:k.AlphaMapType,uniforms:{image:k.DefaultImageId,channel:"a",repeat:new e(1,1)},components:{alpha:"texture2D(image, fract(repeat * materialInput.st)).channel"}},translucent:!0}),k.SpecularMapType="SpecularMap",k._materialCache.addMaterial(k.SpecularMapType,{fabric:{type:k.SpecularMapType,uniforms:{image:k.DefaultImageId,channel:"r",repeat:new e(1,1)},components:{specular:"texture2D(image, fract(repeat * materialInput.st)).channel"}},translucent:!1}),k.EmissionMapType="EmissionMap",k._materialCache.addMaterial(k.EmissionMapType,{fabric:{type:k.EmissionMapType,uniforms:{image:k.DefaultImageId,channels:"rgb",repeat:new e(1,1)},components:{emission:"texture2D(image, fract(repeat * materialInput.st)).channels"}},translucent:!1}),k.BumpMapType="BumpMap",k._materialCache.addMaterial(k.BumpMapType,{fabric:{type:k.BumpMapType,uniforms:{image:k.DefaultImageId,channel:"r",strength:.8,repeat:new e(1,1)},source:y},translucent:!1}),k.NormalMapType="NormalMap",k._materialCache.addMaterial(k.NormalMapType,{fabric:{type:k.NormalMapType,uniforms:{image:k.DefaultImageId,channels:"rgb",strength:.8,repeat:new e(1,1)},source:A},translucent:!1}),k.GridType="Grid",k._materialCache.addMaterial(k.GridType,{fabric:{type:k.GridType,uniforms:{color:new r(0,1,0,1),cellAlpha:.1,lineCount:new e(8,8),lineThickness:new e(1,1),lineOffset:new e(0,0)},source:E},translucent:function(e){var t=e.uniforms;return t.color.alpha<1||t.cellAlpha<1}}),k.StripeType="Stripe",k._materialCache.addMaterial(k.StripeType,{fabric:{type:k.StripeType,uniforms:{horizontal:!0,evenColor:new r(1,1,1,.5),oddColor:new r(0,0,1,.5),offset:0,repeat:5},source:R},translucent:function(e){var t=e.uniforms;return t.evenColor.alpha<1||t.oddColor.alpha<1}}),k.CheckerboardType="Checkerboard",k._materialCache.addMaterial(k.CheckerboardType,{fabric:{type:k.CheckerboardType,uniforms:{lightColor:new r(1,1,1,.5),darkColor:new r(0,0,0,.5),repeat:new e(5,5)},source:b},translucent:function(e){var t=e.uniforms;return t.lightColor.alpha<1||t.darkColor.alpha<1}}),k.DotType="Dot",k._materialCache.addMaterial(k.DotType,{fabric:{type:k.DotType,uniforms:{lightColor:new r(1,1,0,.75),darkColor:new r(0,1,1,.75),repeat:new e(5,5)},source:C},translucent:function(e){var t=e.uniforms;return t.lightColor.alpha<1||t.darkColor.alpha<1}}),k.WaterType="Water",k._materialCache.addMaterial(k.WaterType,{fabric:{type:k.WaterType,uniforms:{baseWaterColor:new r(.2,.3,.6,1),blendColor:new r(0,1,.699,1),specularMap:k.DefaultImageId,normalMap:k.DefaultImageId,frequency:10,animationSpeed:.01,amplitude:1,specularIntensity:.5,fadeFactor:1},source:L},translucent:function(e){var t=e.uniforms;return t.baseWaterColor.alpha<1||t.blendColor.alpha<1}}),k.RimLightingType="RimLighting",k._materialCache.addMaterial(k.RimLightingType,{fabric:{type:k.RimLightingType,uniforms:{color:new r(1,0,0,.7),rimColor:new r(1,1,1,.4),width:.3},source:O},translucent:function(e){var t=e.uniforms;return t.color.alpha<1||t.rimColor.alpha<1}}),k.FadeType="Fade",k._materialCache.addMaterial(k.FadeType,{fabric:{type:k.FadeType,uniforms:{fadeInColor:new r(1,0,0,1),fadeOutColor:new r(0,0,0,0),maximumDistance:.5,repeat:!0,fadeDirection:{x:!0,y:!0},time:new e(.5,.5)},source:T},translucent:function(e){var t=e.uniforms;return t.fadeInColor.alpha<1||t.fadeOutColor.alpha<1}}),k.PolylineArrowType="PolylineArrow",k._materialCache.addMaterial(k.PolylineArrowType,{fabric:{type:k.PolylineArrowType,uniforms:{color:new r(1,1,1,1)},source:x},translucent:!0}),k.PolylineDashType="PolylineDash",k._materialCache.addMaterial(k.PolylineDashType,{fabric:{type:k.PolylineDashType,uniforms:{color:new r(1,0,1,1),gapColor:new r(0,0,0,0),dashLength:16,dashPattern:255},source:P},translucent:!0}),k.PolylineGlowType="PolylineGlow",k._materialCache.addMaterial(k.PolylineGlowType,{fabric:{type:k.PolylineGlowType,uniforms:{color:new r(0,.5,1,1),glowPower:.25},source:D},translucent:!0}),k.PolylineOutlineType="PolylineOutline",k._materialCache.addMaterial(k.PolylineOutlineType,{fabric:{type:k.PolylineOutlineType,uniforms:{color:new r(1,1,1,1),outlineColor:new r(1,0,0,1),outlineWidth:1},source:I},translucent:function(e){var t=e.uniforms;return t.color.alpha<1||t.outlineColor.alpha<1}}),k.ElevationContourType="ElevationContour",k._materialCache.addMaterial(k.ElevationContourType,{fabric:{type:k.ElevationContourType,uniforms:{spacing:100,color:new r(1,0,0,1),width:1},source:S},translucent:!1}),k.ElevationRampType="ElevationRamp",k._materialCache.addMaterial(k.ElevationRampType,{fabric:{type:k.ElevationRampType,uniforms:{image:k.DefaultImageId,minimumHeight:0,maximumHeight:1e4},source:w},translucent:!1}),k.SlopeRampMaterialType="SlopeRamp",k._materialCache.addMaterial(k.SlopeRampMaterialType,{fabric:{type:k.SlopeRampMaterialType,uniforms:{image:k.DefaultImageId},source:M},translucent:!1}),k}),define("Scene/MaterialAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/freezeObject","../Core/VertexFormat","../Shaders/Appearances/AllMaterialAppearanceFS","../Shaders/Appearances/AllMaterialAppearanceVS","../Shaders/Appearances/BasicMaterialAppearanceFS","../Shaders/Appearances/BasicMaterialAppearanceVS","../Shaders/Appearances/TexturedMaterialAppearanceFS","../Shaders/Appearances/TexturedMaterialAppearanceVS","./Appearance","./Material"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.translucent,!0),n=e(r.closed,!1),o=e(r.materialSupport,p.MaterialSupport.TEXTURED);this.material=t(r.material)?r.material:h.fromType(h.ColorType),this.translucent=i,this._vertexShaderSource=e(r.vertexShaderSource,o.vertexShaderSource),this._fragmentShaderSource=e(r.fragmentShaderSource,o.fragmentShaderSource),this._renderState=d.getDefaultRenderState(i,n,r.renderState),this._closed=n,this._materialSupport=o,this._vertexFormat=o.vertexFormat,this._flat=e(r.flat,!1),this._faceForward=e(r.faceForward,!n)}return r(p.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},materialSupport:{get:function(){return this._materialSupport}},vertexFormat:{get:function(){return this._vertexFormat}},flat:{get:function(){return this._flat}},faceForward:{get:function(){return this._faceForward}}}),p.prototype.getFragmentShaderSource=d.prototype.getFragmentShaderSource,p.prototype.isTranslucent=d.prototype.isTranslucent,p.prototype.getRenderState=d.prototype.getRenderState,p.MaterialSupport={BASIC:i({vertexFormat:n.POSITION_AND_NORMAL,vertexShaderSource:l,fragmentShaderSource:s}),TEXTURED:i({vertexFormat:n.POSITION_NORMAL_AND_ST,vertexShaderSource:c,fragmentShaderSource:u}),ALL:i({vertexFormat:n.ALL,vertexShaderSource:a,fragmentShaderSource:o})},p}),define("Shaders/Appearances/PerInstanceColorAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec4 v_color;\nvoid main()\n{\nvec3 positionToEyeEC = -v_positionEC;\nvec3 normalEC = normalize(v_normalEC);\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nczm_materialInput materialInput;\nmaterialInput.normalEC = normalEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getDefaultMaterial(materialInput);\nmaterial.diffuse = v_color.rgb;\nmaterial.alpha = v_color.a;\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n}\n"}),define("Shaders/Appearances/PerInstanceColorAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 normal;\nattribute vec4 color;\nattribute float batchId;\nvarying vec3 v_positionEC;\nvarying vec3 v_normalEC;\nvarying vec4 v_color;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_normalEC = czm_normal * normal;\nv_color = color;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Shaders/Appearances/PerInstanceFlatColorAppearanceFS",[],function(){"use strict";return"varying vec4 v_color;\nvoid main()\n{\ngl_FragColor = v_color;\n}\n"}),define("Shaders/Appearances/PerInstanceFlatColorAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec4 color;\nattribute float batchId;\nvarying vec4 v_color;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_color = color;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Scene/PerInstanceColorAppearance",["../Core/defaultValue","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/PerInstanceColorAppearanceFS","../Shaders/Appearances/PerInstanceColorAppearanceVS","../Shaders/Appearances/PerInstanceFlatColorAppearanceFS","../Shaders/Appearances/PerInstanceFlatColorAppearanceVS","./Appearance"],function(e,t,r,i,n,o,a,s){"use strict";function l(t){t=e(t,e.EMPTY_OBJECT);var r=e(t.translucent,!0),u=e(t.closed,!1),c=e(t.flat,!1),d=c?a:n,h=c?o:i,p=c?l.FLAT_VERTEX_FORMAT:l.VERTEX_FORMAT;this.material=void 0,this.translucent=r,this._vertexShaderSource=e(t.vertexShaderSource,d),this._fragmentShaderSource=e(t.fragmentShaderSource,h),this._renderState=s.getDefaultRenderState(r,u,t.renderState),this._closed=u,this._vertexFormat=p,this._flat=c,this._faceForward=e(t.faceForward,!u)}return t(l.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return this._vertexFormat}},flat:{get:function(){return this._flat}},faceForward:{get:function(){return this._faceForward}}}),l.VERTEX_FORMAT=r.POSITION_AND_NORMAL,l.FLAT_VERTEX_FORMAT=r.POSITION_ONLY,l.prototype.getFragmentShaderSource=s.prototype.getFragmentShaderSource,l.prototype.isTranslucent=s.prototype.isTranslucent,l.prototype.getRenderState=s.prototype.getRenderState,l}),define("Renderer/BufferUsage",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={STREAM_DRAW:t.STREAM_DRAW,STATIC_DRAW:t.STATIC_DRAW,DYNAMIC_DRAW:t.DYNAMIC_DRAW,validate:function(e){return e===r.STREAM_DRAW||e===r.STATIC_DRAW||e===r.DYNAMIC_DRAW}};return e(r)}),define("Renderer/DrawCommand",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/PrimitiveType"],function(e,t,r,i){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this._boundingVolume=t.boundingVolume,this._orientedBoundingBox=t.orientedBoundingBox,this._cull=e(t.cull,!0),this._modelMatrix=t.modelMatrix,this._primitiveType=e(t.primitiveType,i.TRIANGLES),this._vertexArray=t.vertexArray,this._count=t.count,this._offset=e(t.offset,0),this._instanceCount=e(t.instanceCount,0),this._shaderProgram=t.shaderProgram,this._uniformMap=t.uniformMap,this._renderState=t.renderState,this._framebuffer=t.framebuffer,this._pass=t.pass,this._executeInClosestFrustum=e(t.executeInClosestFrustum,!1),this._owner=t.owner,this._debugShowBoundingVolume=e(t.debugShowBoundingVolume,!1),this._debugOverlappingFrustums=0,this._castShadows=e(t.castShadows,!1),this._receiveShadows=e(t.receiveShadows,!1),this.dirty=!0,this.lastDirtyTime=0,this.derivedCommands={}}return r(n.prototype,{boundingVolume:{get:function(){return this._boundingVolume},set:function(e){this._boundingVolume!==e&&(this._boundingVolume=e,this.dirty=!0)}},orientedBoundingBox:{get:function(){return this._orientedBoundingBox},set:function(e){this._orientedBoundingBox!==e&&(this._orientedBoundingBox=e,this.dirty=!0)}},cull:{get:function(){return this._cull},set:function(e){this._cull!==e&&(this._cull=e,this.dirty=!0)}},modelMatrix:{get:function(){return this._modelMatrix},set:function(e){this._modelMatrix!==e&&(this._modelMatrix=e,this.dirty=!0)}},primitiveType:{get:function(){return this._primitiveType},set:function(e){this._primitiveType!==e&&(this._primitiveType=e,this.dirty=!0)}},vertexArray:{get:function(){return this._vertexArray},set:function(e){this._vertexArray!==e&&(this._vertexArray=e,this.dirty=!0)}},count:{get:function(){return this._count},set:function(e){this._count!==e&&(this._count=e,this.dirty=!0)}},offset:{get:function(){return this._offset},set:function(e){this._offset!==e&&(this._offset=e,this.dirty=!0)}},instanceCount:{get:function(){return this._instanceCount},set:function(e){this._instanceCount!==e&&(this._instanceCount=e,this.dirty=!0)}},shaderProgram:{get:function(){return this._shaderProgram},set:function(e){this._shaderProgram!==e&&(this._shaderProgram=e,this.dirty=!0)}},castShadows:{get:function(){return this._castShadows},set:function(e){this._castShadows!==e&&(this._castShadows=e,this.dirty=!0)}},receiveShadows:{get:function(){return this._receiveShadows},set:function(e){this._receiveShadows!==e&&(this._receiveShadows=e,this.dirty=!0)}},uniformMap:{get:function(){return this._uniformMap},set:function(e){this._uniformMap!==e&&(this._uniformMap=e,this.dirty=!0)}},renderState:{get:function(){return this._renderState},set:function(e){this._renderState!==e&&(this._renderState=e,this.dirty=!0)}},framebuffer:{get:function(){return this._framebuffer},set:function(e){this._framebuffer!==e&&(this._framebuffer=e,this.dirty=!0)}},pass:{get:function(){return this._pass},set:function(e){this._pass!==e&&(this._pass=e,this.dirty=!0)}},executeInClosestFrustum:{get:function(){return this._executeInClosestFrustum},set:function(e){this._executeInClosestFrustum!==e&&(this._executeInClosestFrustum=e,this.dirty=!0)}},owner:{get:function(){return this._owner},set:function(e){this._owner!==e&&(this._owner=e,this.dirty=!0)}},debugShowBoundingVolume:{get:function(){return this._debugShowBoundingVolume},set:function(e){this._debugShowBoundingVolume!==e&&(this._debugShowBoundingVolume=e,this.dirty=!0)}},debugOverlappingFrustums:{get:function(){return this._debugOverlappingFrustums},set:function(e){this._debugOverlappingFrustums!==e&&(this._debugOverlappingFrustums=e,this.dirty=!0)}}}),n.shallowClone=function(e,r){if(t(e))return t(r)||(r=new n),r._boundingVolume=e._boundingVolume,r._orientedBoundingBox=e._orientedBoundingBox,r._cull=e._cull,r._modelMatrix=e._modelMatrix,r._primitiveType=e._primitiveType,r._vertexArray=e._vertexArray,r._count=e._count,r._offset=e._offset,r._instanceCount=e._instanceCount,r._shaderProgram=e._shaderProgram,r._uniformMap=e._uniformMap,r._renderState=e._renderState,r._framebuffer=e._framebuffer,r._pass=e._pass,r._executeInClosestFrustum=e._executeInClosestFrustum,r._owner=e._owner,r._debugShowBoundingVolume=e._debugShowBoundingVolume,r._debugOverlappingFrustums=e._debugOverlappingFrustums,r._castShadows=e._castShadows,r._receiveShadows=e._receiveShadows,r.dirty=!0,r.lastDirtyTime=0,r},n.prototype.execute=function(e,t){e.draw(this,t)},n}),define("Renderer/Pass",["../Core/freezeObject"],function(e){"use strict";return e({ENVIRONMENT:0,COMPUTE:1,GLOBE:2,TERRAIN_CLASSIFICATION:3,CESIUM_3D_TILE:4,CESIUM_3D_TILE_CLASSIFICATION:5,CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW:6,CLASSIFICATION:7,OPAQUE:8,TRANSLUCENT:9,OVERLAY:10,NUMBER_OF_PASSES:11})}),define("Renderer/freezeRenderState",["../Core/freezeObject"],function(e){"use strict";function t(r){if("object"!=typeof r||null===r)return r;for(var i,n=Object.keys(r),o=0;o<n.length;o++)i=n[o],r.hasOwnProperty(i)&&"_applyFunctions"!==i&&(r[i]=t(r[i]));return e(r)}return t}),define("Renderer/RenderState",["../Core/BoundingRectangle","../Core/Color","../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/WebGLConstants","../Core/WindingOrder","./ContextLimits","./freezeRenderState"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(n){var s=r(n,{}),l=r(s.cull,{}),u=r(s.polygonOffset,{}),c=r(s.scissorTest,{}),d=r(c.rectangle,{}),h=r(s.depthRange,{}),p=r(s.depthTest,{}),f=r(s.colorMask,{}),m=r(s.blending,{}),g=r(m.color,{}),_=r(s.stencilTest,{}),v=r(_.frontOperation,{}),y=r(_.backOperation,{}),b=r(s.sampleCoverage,{}),C=s.viewport;this.frontFace=r(s.frontFace,a.COUNTER_CLOCKWISE),this.cull={enabled:r(l.enabled,!1),face:r(l.face,o.BACK)},this.lineWidth=r(s.lineWidth,1),this.polygonOffset={enabled:r(u.enabled,!1),factor:r(u.factor,0),units:r(u.units,0)},this.scissorTest={enabled:r(c.enabled,!1),rectangle:e.clone(d)},this.depthRange={near:r(h.near,0),far:r(h.far,1)},this.depthTest={enabled:r(p.enabled,!1),func:r(p.func,o.LESS)},this.colorMask={red:r(f.red,!0),green:r(f.green,!0),blue:r(f.blue,!0),alpha:r(f.alpha,!0)},this.depthMask=r(s.depthMask,!0),this.stencilMask=r(s.stencilMask,-1),this.blending={enabled:r(m.enabled,!1),color:new t(r(g.red,0),r(g.green,0),r(g.blue,0),r(g.alpha,0)),equationRgb:r(m.equationRgb,o.FUNC_ADD),equationAlpha:r(m.equationAlpha,o.FUNC_ADD),functionSourceRgb:r(m.functionSourceRgb,o.ONE), +functionSourceAlpha:r(m.functionSourceAlpha,o.ONE),functionDestinationRgb:r(m.functionDestinationRgb,o.ZERO),functionDestinationAlpha:r(m.functionDestinationAlpha,o.ZERO)},this.stencilTest={enabled:r(_.enabled,!1),frontFunction:r(_.frontFunction,o.ALWAYS),backFunction:r(_.backFunction,o.ALWAYS),reference:r(_.reference,0),mask:r(_.mask,-1),frontOperation:{fail:r(v.fail,o.KEEP),zFail:r(v.zFail,o.KEEP),zPass:r(v.zPass,o.KEEP)},backOperation:{fail:r(y.fail,o.KEEP),zFail:r(y.zFail,o.KEEP),zPass:r(y.zPass,o.KEEP)}},this.sampleCoverage={enabled:r(b.enabled,!1),value:r(b.value,1),invert:r(b.invert,!1)},this.viewport=i(C)?new e(C.x,C.y,C.width,C.height):void 0,this.id=0,this._applyFunctions=[]}function c(e,t,r){r?e.enable(t):e.disable(t)}function d(e,t){e.frontFace(t.frontFace)}function h(e,t){var r=t.cull,i=r.enabled;c(e,e.CULL_FACE,i),i&&e.cullFace(r.face)}function p(e,t){e.lineWidth(t.lineWidth)}function f(e,t){var r=t.polygonOffset,i=r.enabled;c(e,e.POLYGON_OFFSET_FILL,i),i&&e.polygonOffset(r.factor,r.units)}function m(e,t,r){var n=t.scissorTest,o=i(r.scissorTest)?r.scissorTest.enabled:n.enabled;if(c(e,e.SCISSOR_TEST,o),o){var a=i(r.scissorTest)?r.scissorTest.rectangle:n.rectangle;e.scissor(a.x,a.y,a.width,a.height)}}function g(e,t){var r=t.depthRange;e.depthRange(r.near,r.far)}function _(e,t){var r=t.depthTest,i=r.enabled;c(e,e.DEPTH_TEST,i),i&&e.depthFunc(r.func)}function v(e,t){var r=t.colorMask;e.colorMask(r.red,r.green,r.blue,r.alpha)}function y(e,t){e.depthMask(t.depthMask)}function b(e,t){e.stencilMask(t.stencilMask)}function C(e,t){e.blendColor(t.red,t.green,t.blue,t.alpha)}function S(e,t,r){var n=t.blending,o=i(r.blendingEnabled)?r.blendingEnabled:n.enabled;c(e,e.BLEND,o),o&&(C(e,n.color),e.blendEquationSeparate(n.equationRgb,n.equationAlpha),e.blendFuncSeparate(n.functionSourceRgb,n.functionDestinationRgb,n.functionSourceAlpha,n.functionDestinationAlpha))}function w(e,t){var r=t.stencilTest,i=r.enabled;if(c(e,e.STENCIL_TEST,i),i){var n=r.frontFunction,o=r.backFunction,a=r.reference,s=r.mask;e.stencilFunc(n,a,s),e.stencilFuncSeparate(e.BACK,o,a,s),e.stencilFuncSeparate(e.FRONT,n,a,s);var l=r.frontOperation,u=l.fail,d=l.zFail,h=l.zPass;e.stencilOpSeparate(e.FRONT,u,d,h);var p=r.backOperation,f=p.fail,m=p.zFail,g=p.zPass;e.stencilOpSeparate(e.BACK,f,m,g)}}function T(e,t){var r=t.sampleCoverage,i=r.enabled;c(e,e.SAMPLE_COVERAGE,i),i&&e.sampleCoverage(r.value,r.invert)}function E(e,t,n){var o=r(t.viewport,n.viewport);i(o)||(o=D,o.width=n.context.drawingBufferWidth,o.height=n.context.drawingBufferHeight),n.context.uniformState.viewport=o,e.viewport(o.x,o.y,o.width,o.height)}function A(e,t){var r=[];return e.frontFace!==t.frontFace&&r.push(d),e.cull.enabled===t.cull.enabled&&e.cull.face===t.cull.face||r.push(h),e.lineWidth!==t.lineWidth&&r.push(p),e.polygonOffset.enabled===t.polygonOffset.enabled&&e.polygonOffset.factor===t.polygonOffset.factor&&e.polygonOffset.units===t.polygonOffset.units||r.push(f),e.depthRange.near===t.depthRange.near&&e.depthRange.far===t.depthRange.far||r.push(g),e.depthTest.enabled===t.depthTest.enabled&&e.depthTest.func===t.depthTest.func||r.push(_),e.colorMask.red===t.colorMask.red&&e.colorMask.green===t.colorMask.green&&e.colorMask.blue===t.colorMask.blue&&e.colorMask.alpha===t.colorMask.alpha||r.push(v),e.depthMask!==t.depthMask&&r.push(y),e.stencilMask!==t.stencilMask&&r.push(b),e.stencilTest.enabled===t.stencilTest.enabled&&e.stencilTest.frontFunction===t.stencilTest.frontFunction&&e.stencilTest.backFunction===t.stencilTest.backFunction&&e.stencilTest.reference===t.stencilTest.reference&&e.stencilTest.mask===t.stencilTest.mask&&e.stencilTest.frontOperation.fail===t.stencilTest.frontOperation.fail&&e.stencilTest.frontOperation.zFail===t.stencilTest.frontOperation.zFail&&e.stencilTest.backOperation.fail===t.stencilTest.backOperation.fail&&e.stencilTest.backOperation.zFail===t.stencilTest.backOperation.zFail&&e.stencilTest.backOperation.zPass===t.stencilTest.backOperation.zPass||r.push(w),e.sampleCoverage.enabled===t.sampleCoverage.enabled&&e.sampleCoverage.value===t.sampleCoverage.value&&e.sampleCoverage.invert===t.sampleCoverage.invert||r.push(T),r}var x=0,P={};u.fromCache=function(e){var t=JSON.stringify(e),r=P[t];if(i(r))return++r.referenceCount,r.state;var n=new u(e),o=JSON.stringify(n);return r=P[o],i(r)||(n.id=x++,r={referenceCount:0,state:n},P[o]=r),++r.referenceCount,P[t]={referenceCount:1,state:r.state},r.state},u.removeFromCache=function(e){var t=new u(e),r=JSON.stringify(t),n=P[r],o=JSON.stringify(e),a=P[o];i(a)&&0===--a.referenceCount&&(delete P[o],i(n)&&--n.referenceCount),i(n)&&0===n.referenceCount&&delete P[r]},u.getCache=function(){return P},u.clearCache=function(){P={}};var D=new e;return u.apply=function(e,t,r){d(e,t),h(e,t),p(e,t),f(e,t),g(e,t),_(e,t),v(e,t),y(e,t),b(e,t),w(e,t),T(e,t),m(e,t,r),S(e,t,r),E(e,t,r)},u.partialApply=function(e,t,r,n,o,a){if(t!==r){var s=r._applyFunctions[t.id];i(s)||(s=A(t,r),r._applyFunctions[t.id]=s);for(var l=s.length,u=0;u<l;++u)s[u](e,r)}((i(n.scissorTest)?n.scissorTest:t.scissorTest)!==(i(o.scissorTest)?o.scissorTest:r.scissorTest)||a)&&m(e,r,o);var c=i(n.blendingEnabled)?n.blendingEnabled:t.blending.enabled,d=i(o.blendingEnabled)?o.blendingEnabled:r.blending.enabled;(c!==d||d&&t.blending!==r.blending)&&S(e,r,o),t===r&&n===o&&n.context===o.context||E(e,r,o)},u.getState=function(r){return{frontFace:r.frontFace,cull:{enabled:r.cull.enabled,face:r.cull.face},lineWidth:r.lineWidth,polygonOffset:{enabled:r.polygonOffset.enabled,factor:r.polygonOffset.factor,units:r.polygonOffset.units},scissorTest:{enabled:r.scissorTest.enabled,rectangle:e.clone(r.scissorTest.rectangle)},depthRange:{near:r.depthRange.near,far:r.depthRange.far},depthTest:{enabled:r.depthTest.enabled,func:r.depthTest.func},colorMask:{red:r.colorMask.red,green:r.colorMask.green,blue:r.colorMask.blue,alpha:r.colorMask.alpha},depthMask:r.depthMask,stencilMask:r.stencilMask,blending:{enabled:r.blending.enabled,color:t.clone(r.blending.color),equationRgb:r.blending.equationRgb,equationAlpha:r.blending.equationAlpha,functionSourceRgb:r.blending.functionSourceRgb,functionSourceAlpha:r.blending.functionSourceAlpha,functionDestinationRgb:r.blending.functionDestinationRgb,functionDestinationAlpha:r.blending.functionDestinationAlpha},stencilTest:{enabled:r.stencilTest.enabled,frontFunction:r.stencilTest.frontFunction,backFunction:r.stencilTest.backFunction,reference:r.stencilTest.reference,mask:r.stencilTest.mask,frontOperation:{fail:r.stencilTest.frontOperation.fail,zFail:r.stencilTest.frontOperation.zFail,zPass:r.stencilTest.frontOperation.zPass},backOperation:{fail:r.stencilTest.backOperation.fail,zFail:r.stencilTest.backOperation.zFail,zPass:r.stencilTest.backOperation.zPass}},sampleCoverage:{enabled:r.sampleCoverage.enabled,value:r.sampleCoverage.value,invert:r.sampleCoverage.invert},viewport:i(r.viewport)?e.clone(r.viewport):void 0}},u}),define("Renderer/AutomaticUniforms",["../Core/Cartesian3","../Core/Matrix4","../Core/WebGLConstants"],function(e,t,r){"use strict";function i(e){this._size=e.size,this._datatype=e.datatype,this.getValue=e.getValue}var n=new e;if("undefined"==typeof WebGLRenderingContext)return{};var o={};return o[r.FLOAT]="float",o[r.FLOAT_VEC2]="vec2",o[r.FLOAT_VEC3]="vec3",o[r.FLOAT_VEC4]="vec4",o[r.INT]="int",o[r.INT_VEC2]="ivec2",o[r.INT_VEC3]="ivec3",o[r.INT_VEC4]="ivec4",o[r.BOOL]="bool",o[r.BOOL_VEC2]="bvec2",o[r.BOOL_VEC3]="bvec3",o[r.BOOL_VEC4]="bvec4",o[r.FLOAT_MAT2]="mat2",o[r.FLOAT_MAT3]="mat3",o[r.FLOAT_MAT4]="mat4",o[r.SAMPLER_2D]="sampler2D",o[r.SAMPLER_CUBE]="samplerCube",i.prototype.getDeclaration=function(e){var t="uniform "+o[this._datatype]+" "+e,r=this._size;return t+=1===r?";":"["+r.toString()+"];"},{czm_viewport:new i({size:1,datatype:r.FLOAT_VEC4,getValue:function(e){return e.viewportCartesian4}}),czm_viewportOrthographic:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.viewportOrthographic}}),czm_viewportTransformation:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.viewportTransformation}}),czm_globeDepthTexture:new i({size:1,datatype:r.SAMPLER_2D,getValue:function(e){return e.globeDepthTexture}}),czm_model:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.model}}),czm_inverseModel:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseModel}}),czm_view:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.view}}),czm_view3D:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.view3D}}),czm_viewRotation:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.viewRotation}}),czm_viewRotation3D:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.viewRotation3D}}),czm_inverseView:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseView}}),czm_inverseView3D:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseView3D}}),czm_inverseViewRotation:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.inverseViewRotation}}),czm_inverseViewRotation3D:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.inverseViewRotation3D}}),czm_projection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.projection}}),czm_inverseProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseProjection}}),czm_infiniteProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.infiniteProjection}}),czm_modelView:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.modelView}}),czm_modelView3D:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.modelView3D}}),czm_modelViewRelativeToEye:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.modelViewRelativeToEye}}),czm_inverseModelView:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseModelView}}),czm_inverseModelView3D:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseModelView3D}}),czm_viewProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.viewProjection}}),czm_inverseViewProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseViewProjection}}),czm_modelViewProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.modelViewProjection}}),czm_inverseModelViewProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.inverseModelViewProjection}}),czm_modelViewProjectionRelativeToEye:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.modelViewProjectionRelativeToEye}}),czm_modelViewInfiniteProjection:new i({size:1,datatype:r.FLOAT_MAT4,getValue:function(e){return e.modelViewInfiniteProjection}}),czm_normal:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.normal}}),czm_normal3D:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.normal3D}}),czm_inverseNormal:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.inverseNormal}}),czm_inverseNormal3D:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.inverseNormal3D}}),czm_eyeHeight2D:new i({size:1,datatype:r.FLOAT_VEC2,getValue:function(e){return e.eyeHeight2D}}),czm_entireFrustum:new i({size:1,datatype:r.FLOAT_VEC2,getValue:function(e){return e.entireFrustum}}),czm_currentFrustum:new i({size:1,datatype:r.FLOAT_VEC2,getValue:function(e){return e.currentFrustum}}),czm_frustumPlanes:new i({size:1,datatype:r.FLOAT_VEC4,getValue:function(e){return e.frustumPlanes}}),czm_sunPositionWC:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.sunPositionWC}}),czm_sunPositionColumbusView:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.sunPositionColumbusView}}),czm_sunDirectionEC:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.sunDirectionEC}}),czm_sunDirectionWC:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.sunDirectionWC}}),czm_moonDirectionEC:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.moonDirectionEC}}),czm_encodedCameraPositionMCHigh:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.encodedCameraPositionMCHigh}}),czm_encodedCameraPositionMCLow:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return e.encodedCameraPositionMCLow}}),czm_viewerPositionWC:new i({size:1,datatype:r.FLOAT_VEC3,getValue:function(e){return t.getTranslation(e.inverseView,n)}}),czm_frameNumber:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.frameState.frameNumber}}),czm_morphTime:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.frameState.morphTime}}),czm_sceneMode:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.frameState.mode}}),czm_pass:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.pass}}),czm_backgroundColor:new i({size:1,datatype:r.FLOAT_VEC4,getValue:function(e){return e.backgroundColor}}),czm_brdfLut:new i({size:1,datatype:r.SAMPLER_2D,getValue:function(e){return e.brdfLut}}),czm_environmentMap:new i({size:1,datatype:r.SAMPLER_CUBE,getValue:function(e){return e.environmentMap}}),czm_temeToPseudoFixed:new i({size:1,datatype:r.FLOAT_MAT3,getValue:function(e){return e.temeToPseudoFixedMatrix}}),czm_resolutionScale:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.resolutionScale}}),czm_fogDensity:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.fogDensity}}),czm_imagerySplitPosition:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.imagerySplitPosition}}),czm_geometricToleranceOverMeter:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.geometricToleranceOverMeter}}),czm_minimumDisableDepthTestDistance:new i({size:1,datatype:r.FLOAT,getValue:function(e){return e.minimumDisableDepthTestDistance}}),czm_invertClassificationColor:new i({size:1,datatype:r.FLOAT_VEC4,getValue:function(e){return e.invertClassificationColor}})}}),define("Renderer/createUniform",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Color","../Core/defined","../Core/DeveloperError","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4","../Core/RuntimeError"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t,r,i){switch(t.type){case e.FLOAT:return new d(e,t,r,i);case e.FLOAT_VEC2:return new h(e,t,r,i);case e.FLOAT_VEC3:return new p(e,t,r,i);case e.FLOAT_VEC4:return new f(e,t,r,i);case e.SAMPLER_2D:case e.SAMPLER_CUBE:return new m(e,t,r,i);case e.INT:case e.BOOL:return new g(e,t,r,i);case e.INT_VEC2:case e.BOOL_VEC2:return new _(e,t,r,i);case e.INT_VEC3:case e.BOOL_VEC3:return new v(e,t,r,i);case e.INT_VEC4:case e.BOOL_VEC4:return new y(e,t,r,i);case e.FLOAT_MAT2:return new b(e,t,r,i);case e.FLOAT_MAT3:return new C(e,t,r,i);case e.FLOAT_MAT4:return new S(e,t,r,i);default:throw new u("Unrecognized uniform type: "+t.type+' for uniform "'+r+'".')}}function d(e,t,r,i){this.name=r,this.value=void 0,this._value=0,this._gl=e,this._location=i}function h(t,r,i,n){this.name=i,this.value=void 0,this._value=new e,this._gl=t,this._location=n}function p(e,t,r,i){this.name=r,this.value=void 0,this._value=void 0,this._gl=e,this._location=i}function f(e,t,r,i){this.name=r,this.value=void 0,this._value=void 0,this._gl=e,this._location=i}function m(e,t,r,i){this.name=r,this.value=void 0,this._gl=e,this._location=i,this.textureUnitIndex=void 0}function g(e,t,r,i){this.name=r,this.value=void 0,this._value=0,this._gl=e,this._location=i}function _(t,r,i,n){this.name=i,this.value=void 0,this._value=new e,this._gl=t,this._location=n}function v(e,r,i,n){this.name=i,this.value=void 0,this._value=new t,this._gl=e,this._location=n}function y(e,t,i,n){this.name=i,this.value=void 0,this._value=new r,this._gl=e,this._location=n}function b(e,t,r,i){this.name=r,this.value=void 0,this._value=new Float32Array(4),this._gl=e,this._location=i}function C(e,t,r,i){this.name=r,this.value=void 0,this._value=new Float32Array(9),this._gl=e,this._location=i}function S(e,t,r,i){this.name=r,this.value=void 0,this._value=new Float32Array(16),this._gl=e,this._location=i}return d.prototype.set=function(){this.value!==this._value&&(this._value=this.value,this._gl.uniform1f(this._location,this.value))},h.prototype.set=function(){var t=this.value;e.equals(t,this._value)||(e.clone(t,this._value),this._gl.uniform2f(this._location,t.x,t.y))},p.prototype.set=function(){var e=this.value;n(e.red)?i.equals(e,this._value)||(this._value=i.clone(e,this._value),this._gl.uniform3f(this._location,e.red,e.green,e.blue)):n(e.x)&&(t.equals(e,this._value)||(this._value=t.clone(e,this._value),this._gl.uniform3f(this._location,e.x,e.y,e.z)))},f.prototype.set=function(){var e=this.value;n(e.red)?i.equals(e,this._value)||(this._value=i.clone(e,this._value),this._gl.uniform4f(this._location,e.red,e.green,e.blue,e.alpha)):n(e.x)&&(r.equals(e,this._value)||(this._value=r.clone(e,this._value),this._gl.uniform4f(this._location,e.x,e.y,e.z,e.w)))},m.prototype.set=function(){var e=this._gl;e.activeTexture(e.TEXTURE0+this.textureUnitIndex);var t=this.value;e.bindTexture(t._target,t._texture)},m.prototype._setSampler=function(e){return this.textureUnitIndex=e,this._gl.uniform1i(this._location,e),e+1},g.prototype.set=function(){this.value!==this._value&&(this._value=this.value,this._gl.uniform1i(this._location,this.value))},_.prototype.set=function(){var t=this.value;e.equals(t,this._value)||(e.clone(t,this._value),this._gl.uniform2i(this._location,t.x,t.y))},v.prototype.set=function(){var e=this.value;t.equals(e,this._value)||(t.clone(e,this._value),this._gl.uniform3i(this._location,e.x,e.y,e.z))},y.prototype.set=function(){var e=this.value;r.equals(e,this._value)||(r.clone(e,this._value),this._gl.uniform4i(this._location,e.x,e.y,e.z,e.w))},b.prototype.set=function(){a.equalsArray(this.value,this._value,0)||(a.toArray(this.value,this._value),this._gl.uniformMatrix2fv(this._location,!1,this._value))},C.prototype.set=function(){s.equalsArray(this.value,this._value,0)||(s.toArray(this.value,this._value),this._gl.uniformMatrix3fv(this._location,!1,this._value))},S.prototype.set=function(){l.equalsArray(this.value,this._value,0)||(l.toArray(this.value,this._value),this._gl.uniformMatrix4fv(this._location,!1,this._value))},c}),define("Renderer/createUniformArray",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Color","../Core/defined","../Core/DeveloperError","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4","../Core/RuntimeError"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,t,r,i){switch(t.type){case e.FLOAT:return new d(e,t,r,i);case e.FLOAT_VEC2:return new h(e,t,r,i);case e.FLOAT_VEC3:return new p(e,t,r,i);case e.FLOAT_VEC4:return new f(e,t,r,i);case e.SAMPLER_2D:case e.SAMPLER_CUBE:return new m(e,t,r,i);case e.INT:case e.BOOL:return new g(e,t,r,i);case e.INT_VEC2:case e.BOOL_VEC2:return new _(e,t,r,i);case e.INT_VEC3:case e.BOOL_VEC3:return new v(e,t,r,i);case e.INT_VEC4:case e.BOOL_VEC4:return new y(e,t,r,i);case e.FLOAT_MAT2:return new b(e,t,r,i);case e.FLOAT_MAT3:return new C(e,t,r,i);case e.FLOAT_MAT4:return new S(e,t,r,i);default:throw new u("Unrecognized uniform type: "+t.type+' for uniform "'+r+'".')}}function d(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(n),this._gl=e,this._location=i[0]}function h(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(2*n),this._gl=e,this._location=i[0]}function p(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(3*n),this._gl=e,this._location=i[0]}function f(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(4*n),this._gl=e,this._location=i[0]}function m(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(n),this._gl=e,this._locations=i,this.textureUnitIndex=void 0}function g(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Int32Array(n),this._gl=e,this._location=i[0]}function _(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Int32Array(2*n),this._gl=e,this._location=i[0]}function v(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Int32Array(3*n),this._gl=e,this._location=i[0]}function y(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Int32Array(4*n),this._gl=e,this._location=i[0]}function b(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(4*n),this._gl=e,this._location=i[0]}function C(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(9*n),this._gl=e,this._location=i[0]}function S(e,t,r,i){var n=i.length;this.name=r,this.value=new Array(n),this._value=new Float32Array(16*n),this._gl=e,this._location=i[0]}return d.prototype.set=function(){for(var e=this.value,t=e.length,r=this._value,i=!1,n=0;n<t;++n){var o=e[n];o!==r[n]&&(r[n]=o,i=!0)}i&&this._gl.uniform1fv(this._location,r)},h.prototype.set=function(){for(var t=this.value,r=t.length,i=this._value,n=!1,o=0,a=0;a<r;++a){var s=t[a];e.equalsArray(s,i,o)||(e.pack(s,i,o),n=!0),o+=2}n&&this._gl.uniform2fv(this._location,i)},p.prototype.set=function(){for(var e=this.value,r=e.length,i=this._value,o=!1,a=0,s=0;s<r;++s){var l=e[s];n(l.red)?l.red===i[a]&&l.green===i[a+1]&&l.blue===i[a+2]||(i[a]=l.red,i[a+1]=l.green,i[a+2]=l.blue,o=!0):n(l.x)&&(t.equalsArray(l,i,a)||(t.pack(l,i,a),o=!0)),a+=3}o&&this._gl.uniform3fv(this._location,i)},f.prototype.set=function(){for(var e=this.value,t=e.length,o=this._value,a=!1,s=0,l=0;l<t;++l){var u=e[l];n(u.red)?i.equalsArray(u,o,s)||(i.pack(u,o,s),a=!0):n(u.x)&&(r.equalsArray(u,o,s)||(r.pack(u,o,s),a=!0)),s+=4}a&&this._gl.uniform4fv(this._location,o)},m.prototype.set=function(){for(var e=this._gl,t=e.TEXTURE0+this.textureUnitIndex,r=this.value,i=r.length,n=0;n<i;++n){var o=r[n];e.activeTexture(t+n),e.bindTexture(o._target,o._texture)}},m.prototype._setSampler=function(e){this.textureUnitIndex=e;for(var t=this._locations,r=t.length,i=0;i<r;++i){var n=e+i;this._gl.uniform1i(t[i],n)}return e+r},g.prototype.set=function(){for(var e=this.value,t=e.length,r=this._value,i=!1,n=0;n<t;++n){var o=e[n];o!==r[n]&&(r[n]=o,i=!0)}i&&this._gl.uniform1iv(this._location,r)},_.prototype.set=function(){for(var t=this.value,r=t.length,i=this._value,n=!1,o=0,a=0;a<r;++a){var s=t[a];e.equalsArray(s,i,o)||(e.pack(s,i,o),n=!0),o+=2}n&&this._gl.uniform2iv(this._location,i)},v.prototype.set=function(){for(var e=this.value,r=e.length,i=this._value,n=!1,o=0,a=0;a<r;++a){var s=e[a];t.equalsArray(s,i,o)||(t.pack(s,i,o),n=!0),o+=3}n&&this._gl.uniform3iv(this._location,i)},y.prototype.set=function(){for(var e=this.value,t=e.length,i=this._value,n=!1,o=0,a=0;a<t;++a){var s=e[a];r.equalsArray(s,i,o)||(r.pack(s,i,o),n=!0),o+=4}n&&this._gl.uniform4iv(this._location,i)},b.prototype.set=function(){for(var e=this.value,t=e.length,r=this._value,i=!1,n=0,o=0;o<t;++o){var s=e[o];a.equalsArray(s,r,n)||(a.pack(s,r,n),i=!0),n+=4}i&&this._gl.uniformMatrix2fv(this._location,!1,r)},C.prototype.set=function(){for(var e=this.value,t=e.length,r=this._value,i=!1,n=0,o=0;o<t;++o){var a=e[o];s.equalsArray(a,r,n)||(s.pack(a,r,n),i=!0),n+=9}i&&this._gl.uniformMatrix3fv(this._location,!1,r)},S.prototype.set=function(){for(var e=this.value,t=e.length,r=this._value,i=!1,n=0,o=0;o<t;++o){var a=e[o];l.equalsArray(a,r,n)||(l.pack(a,r,n),i=!0),n+=16}i&&this._gl.uniformMatrix4fv(this._location,!1,r)},c}),define("Renderer/ShaderProgram",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/RuntimeError","./AutomaticUniforms","./ContextLimits","./createUniform","./createUniformArray"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e){var t=p(e.vertexShaderText,e.fragmentShaderText);this._gl=e.gl,this._logShaderCompilation=e.logShaderCompilation,this._debugShaders=e.debugShaders,this._attributeLocations=e.attributeLocations,this._program=void 0,this._numberOfVertexAttributes=void 0,this._vertexAttributes=void 0,this._uniformsByName=void 0,this._uniforms=void 0,this._automaticUniforms=void 0,this._manualUniforms=void 0,this._duplicateUniformNames=t.duplicateUniformNames,this._cachedShader=void 0,this.maximumTextureUnitIndex=void 0,this._vertexShaderSource=e.vertexShaderSource,this._vertexShaderText=e.vertexShaderText,this._fragmentShaderSource=e.fragmentShaderSource,this._fragmentShaderText=t.fragmentShaderText,this.id=b++}function h(e){var t=[],i=e.match(/uniform.*?(?![^{]*})(?=[=\[;])/g);if(r(i))for(var n=i.length,o=0;o<n;o++){var a=i[o].trim(),s=a.slice(a.lastIndexOf(" ")+1);t.push(s)}return t}function p(e,t){var r={};if(!l.highpFloatSupported||!l.highpIntSupported){var i,n,o,a,s=h(e),u=h(t),c=s.length,d=u.length;for(i=0;i<c;i++)for(n=0;n<d;n++)if(s[i]===u[n]){o=s[i],a="czm_mediump_"+o;var p=new RegExp(o+"\\b","g");t=t.replace(p,a),r[a]=o}}return{fragmentShaderText:t,duplicateUniformNames:r}}function f(e,t){var i=t._vertexShaderText,n=t._fragmentShaderText,o=e.createShader(e.VERTEX_SHADER);e.shaderSource(o,i),e.compileShader(o);var s=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(s,n),e.compileShader(s);var l=e.createProgram();e.attachShader(l,o),e.attachShader(l,s),e.deleteShader(o),e.deleteShader(s);var u=t._attributeLocations;if(r(u))for(var c in u)u.hasOwnProperty(c)&&e.bindAttribLocation(l,u[c],c);e.linkProgram(l);var d;if(!e.getProgramParameter(l,e.LINK_STATUS)){var h=t._debugShaders;if(!e.getShaderParameter(s,e.COMPILE_STATUS)){if(d=e.getShaderInfoLog(s),console.error(C+"Fragment shader compile log: "+d),r(h)){var p=h.getTranslatedShaderSource(s);""!==p?console.error(C+"Translated fragment shader source:\n"+p):console.error(C+"Fragment shader translation failed.")}throw e.deleteProgram(l),new a("Fragment shader failed to compile. Compile log: "+d)}if(!e.getShaderParameter(o,e.COMPILE_STATUS)){if(d=e.getShaderInfoLog(o),console.error(C+"Vertex shader compile log: "+d),r(h)){var f=h.getTranslatedShaderSource(o);""!==f?console.error(C+"Translated vertex shader source:\n"+f):console.error(C+"Vertex shader translation failed.")}throw e.deleteProgram(l),new a("Vertex shader failed to compile. Compile log: "+d)}throw d=e.getProgramInfoLog(l),console.error(C+"Shader program link log: "+d),r(h)&&(console.error(C+"Translated vertex shader source:\n"+h.getTranslatedShaderSource(o)),console.error(C+"Translated fragment shader source:\n"+h.getTranslatedShaderSource(s))),e.deleteProgram(l),new a("Program failed to link. Link log: "+d)}var m=t._logShaderCompilation;return m&&(d=e.getShaderInfoLog(o),r(d)&&d.length>0&&console.log(C+"Vertex shader compile log: "+d)),m&&(d=e.getShaderInfoLog(s),r(d)&&d.length>0&&console.log(C+"Fragment shader compile log: "+d)),m&&(d=e.getProgramInfoLog(l),r(d)&&d.length>0&&console.log(C+"Shader program link log: "+d)),l}function m(e,t,r){for(var i={},n=0;n<r;++n){var o=e.getActiveAttrib(t,n),a=e.getAttribLocation(t,o.name);i[o.name]={name:o.name,type:o.type,index:a}}return i}function g(e,t){for(var i={},n=[],o=[],a=e.getProgramParameter(t,e.ACTIVE_UNIFORMS),s=0;s<a;++s){var l=e.getActiveUniform(t,s),d=-1!==l.name.indexOf("[0]",l.name.length-"[0]".length)?l.name.slice(0,l.name.length-3):l.name;if(0!==d.indexOf("gl_"))if(l.name.indexOf("[")<0){var h=e.getUniformLocation(t,d);if(null!==h){var p=u(e,l,d,h);i[d]=p,n.push(p),p._setSampler&&o.push(p)}}else{var f,m,g,_,v=d.indexOf("[");if(v>=0){if(f=i[d.slice(0,v)],!r(f))continue;m=f._locations,m.length<=1&&(g=f.value,null!==(_=e.getUniformLocation(t,d))&&(m.push(_),g.push(e.getUniform(t,_))))}else{m=[];for(var y=0;y<l.size;++y)null!==(_=e.getUniformLocation(t,d+"["+y+"]"))&&m.push(_);f=c(e,l,d,m),i[d]=f,n.push(f),f._setSampler&&o.push(f)}}}return{uniformsByName:i,uniforms:n,samplerUniforms:o}}function _(e,t){var i=[],n=[];for(var o in t)if(t.hasOwnProperty(o)){var a=t[o],l=o,u=e._duplicateUniformNames[l];r(u)&&(a.name=u,l=u);var c=s[l];r(c)?i.push({uniform:a,automaticUniform:c}):n.push(a)}return{automaticUniforms:i,manualUniforms:n}}function v(e,t,r){e.useProgram(t);for(var i=0,n=r.length,o=0;o<n;++o)i=r[o]._setSampler(i);return e.useProgram(null),i}function y(e){if(!r(e._program)){var t=e._gl,i=f(t,e,e._debugShaders),n=t.getProgramParameter(i,t.ACTIVE_ATTRIBUTES),o=g(t,i),a=_(e,o.uniformsByName);e._program=i,e._numberOfVertexAttributes=n,e._vertexAttributes=m(t,i,n),e._uniformsByName=o.uniformsByName,e._uniforms=o.uniforms,e._automaticUniforms=a.automaticUniforms,e._manualUniforms=a.manualUniforms,e.maximumTextureUnitIndex=v(t,i,o.samplerUniforms)}}var b=0;d.fromCache=function(e){return e=t(e,t.EMPTY_OBJECT),e.context.shaderCache.getShaderProgram(e)},d.replaceCache=function(e){return e=t(e,t.EMPTY_OBJECT),e.context.shaderCache.replaceShaderProgram(e)},i(d.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},vertexAttributes:{get:function(){return y(this),this._vertexAttributes}},numberOfVertexAttributes:{get:function(){return y(this),this._numberOfVertexAttributes}},allUniforms:{get:function(){return y(this),this._uniformsByName}}});var C="[Cesium WebGL] ";return d.prototype._bind=function(){y(this),this._gl.useProgram(this._program)},d.prototype._setUniforms=function(e,t,i){var n,o;if(r(e)){var a=this._manualUniforms;for(n=a.length,o=0;o<n;++o){var s=a[o];s.value=e[s.name]()}}var l=this._automaticUniforms;for(n=l.length,o=0;o<n;++o){var u=l[o];u.uniform.value=u.automaticUniform.getValue(t)}var c=this._uniforms;for(n=c.length,o=0;o<n;++o)c[o].set();if(i){var d=this._gl,h=this._program;d.validateProgram(h)}},d.prototype.isDestroyed=function(){return!1},d.prototype.destroy=function(){this._cachedShader.cache.releaseShaderProgram(this)},d.prototype.finalDestroy=function(){return this._gl.deleteProgram(this._program),n(this)},d}),define("Renderer/modernizeShader",["../Core/defined","../Core/DeveloperError"],function(e,t){"use strict";function r(e,r){var n=/#define OUTPUT_DECLARATION/,c=e.split("\n");if(/#version 300 es/g.test(e))return e;var d,h,p=-1;for(d=0;d<c.length;++d)if(h=c[d],n.test(h)){p=d;break}if(-1===p)throw new t("Could not find a #define OUTPUT_DECLARATION!");var f=[];for(d=0;d<10;d++){var m="gl_FragData\\["+d+"\\]",g="czm_out"+d;new RegExp(m,"g").test(e)&&(s(g,f),i(m,g,c),c.splice(p,0,"layout(location = "+d+") out vec4 "+g+";"),p+=1)}o("gl_FragColor",c)&&(s("czm_fragColor",f),i("gl_FragColor","czm_fragColor",c),c.splice(p,0,"layout(location = 0) out vec4 czm_fragColor;"),p+=1);var _=l(f,c),v={};for(d=0;d<c.length;d++){h=c[d];for(var y in _)if(_.hasOwnProperty(y)){var b=new RegExp("(layout)[^]+(out)[^]+("+y+")[^]+","g");b.test(h)&&(v[h]=y)}}for(var C in v)if(v.hasOwnProperty(C)){var S,w=v[C],T=c.indexOf(C),E=_[w],A=E.length;for(S=0;S<A;S++)c.splice(T,0,E[S]);for(T+=A+1,S=A-1;S>=0;S--)c.splice(T,0,"#endif //"+E[S])}var x=!1;for(d=0;d<c.length;d++)/#version/.test(c[d])&&(c[d]="#version 300 es",x=!0);return x||c.splice(0,0,"#version 300 es"),u("EXT_draw_buffers",c),u("EXT_frag_depth",c),i("texture2D","texture",c),i("texture3D","texture",c),i("textureCube","texture",c),i("gl_FragDepthEXT","gl_FragDepth",c),r?i("varying","in",c):(i("attribute","in",c),i("varying","out",c)),a(c)}function i(e,t,r){for(var i="(^|[^\\w])("+e+")($|[^\\w])",n=new RegExp(i,"g"),o=r.length,a=0;a<o;++a){var s=r[a];r[a]=s.replace(n,"$1"+t+"$3")}}function n(e,t,r){for(var i=r.length,n=0;n<i;++n){var o=r[n];r[n]=o.replace(e,t)}}function o(e,t){for(var r="(^|[^\\w])("+e+")($|[^\\w])",i=new RegExp(r,"g"),n=t.length,o=0;o<n;++o){var a=t[o];if(i.test(a))return!0}return!1}function a(e){for(var t="",r=e.length,i=0;i<r;++i)t+=e[i]+"\n";return t}function s(e,t){-1===t.indexOf(e)&&t.push(e)}function l(t,r){for(var i={},n=t.length,o=[],a=0;a<r.length;++a){var s=r[a],l=/(#ifdef|#if)/g.test(s),u=/#else/g.test(s),c=/#endif/g.test(s);if(l)o.push(s);else if(u){var d=o[o.length-1],h=d.replace("ifdef","ifndef");/if/g.test(h)&&(h=h.replace(/(#if\s+)(\S*)([^]*)/,"$1!($2)$3")), +o.pop(),o.push(h)}else if(c)o.pop();else if(!/layout/g.test(s))for(var p=0;p<n;++p){var f=t[p];-1!==s.indexOf(f)&&(e(i[f])?i[f]=i[f].filter(function(e){return o.indexOf(e)>=0}):i[f]=o.slice())}}return i}function u(e,t){var r="#extension\\s+GL_"+e+"\\s+:\\s+[a-zA-Z0-9]+\\s*$";n(new RegExp(r,"g"),"",t)}return r}),define("Shaders/Builtin/Constants/degreesPerRadian",[],function(){"use strict";return"const float czm_degreesPerRadian = 57.29577951308232;\n"}),define("Shaders/Builtin/Constants/depthRange",[],function(){"use strict";return"const czm_depthRangeStruct czm_depthRange = czm_depthRangeStruct(0.0, 1.0);\n"}),define("Shaders/Builtin/Constants/epsilon1",[],function(){"use strict";return"const float czm_epsilon1 = 0.1;\n"}),define("Shaders/Builtin/Constants/epsilon2",[],function(){"use strict";return"const float czm_epsilon2 = 0.01;\n"}),define("Shaders/Builtin/Constants/epsilon3",[],function(){"use strict";return"const float czm_epsilon3 = 0.001;\n"}),define("Shaders/Builtin/Constants/epsilon4",[],function(){"use strict";return"const float czm_epsilon4 = 0.0001;\n"}),define("Shaders/Builtin/Constants/epsilon5",[],function(){"use strict";return"const float czm_epsilon5 = 0.00001;\n"}),define("Shaders/Builtin/Constants/epsilon6",[],function(){"use strict";return"const float czm_epsilon6 = 0.000001;\n"}),define("Shaders/Builtin/Constants/epsilon7",[],function(){"use strict";return"const float czm_epsilon7 = 0.0000001;\n"}),define("Shaders/Builtin/Constants/infinity",[],function(){"use strict";return"const float czm_infinity = 5906376272000.0;\n"}),define("Shaders/Builtin/Constants/maxClippingPlanes",[],function(){"use strict";return"const int czm_maxClippingPlanes = 6;\n"}),define("Shaders/Builtin/Constants/oneOverPi",[],function(){"use strict";return"const float czm_oneOverPi = 0.3183098861837907;\n"}),define("Shaders/Builtin/Constants/oneOverTwoPi",[],function(){"use strict";return"const float czm_oneOverTwoPi = 0.15915494309189535;\n"}),define("Shaders/Builtin/Constants/passCesium3DTile",[],function(){"use strict";return"const float czm_passCesium3DTile = 4.0;\n"}),define("Shaders/Builtin/Constants/passCesium3DTileClassification",[],function(){"use strict";return"const float czm_passCesium3DTileClassification = 5.0;\n"}),define("Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow",[],function(){"use strict";return"const float czm_passCesium3DTileClassificationIgnoreShow = 6.0;\n"}),define("Shaders/Builtin/Constants/passClassification",[],function(){"use strict";return"const float czm_passClassification = 7.0;\n"}),define("Shaders/Builtin/Constants/passCompute",[],function(){"use strict";return"const float czm_passCompute = 1.0;\n"}),define("Shaders/Builtin/Constants/passEnvironment",[],function(){"use strict";return"const float czm_passEnvironment = 0.0;\n"}),define("Shaders/Builtin/Constants/passGlobe",[],function(){"use strict";return"const float czm_passGlobe = 2.0;\n"}),define("Shaders/Builtin/Constants/passOpaque",[],function(){"use strict";return"const float czm_passOpaque = 8.0;\n"}),define("Shaders/Builtin/Constants/passOverlay",[],function(){"use strict";return"const float czm_passOverlay = 10.0;\n"}),define("Shaders/Builtin/Constants/passTerrainClassification",[],function(){"use strict";return"const float czm_passTerrainClassification = 3.0;\n"}),define("Shaders/Builtin/Constants/passTranslucent",[],function(){"use strict";return"const float czm_passTranslucent = 9.0;\n"}),define("Shaders/Builtin/Constants/pi",[],function(){"use strict";return"const float czm_pi = 3.141592653589793;\n"}),define("Shaders/Builtin/Constants/piOverFour",[],function(){"use strict";return"const float czm_piOverFour = 0.7853981633974483;\n"}),define("Shaders/Builtin/Constants/piOverSix",[],function(){"use strict";return"const float czm_piOverSix = 0.5235987755982988;\n"}),define("Shaders/Builtin/Constants/piOverThree",[],function(){"use strict";return"const float czm_piOverThree = 1.0471975511965976;\n"}),define("Shaders/Builtin/Constants/piOverTwo",[],function(){"use strict";return"const float czm_piOverTwo = 1.5707963267948966;\n"}),define("Shaders/Builtin/Constants/radiansPerDegree",[],function(){"use strict";return"const float czm_radiansPerDegree = 0.017453292519943295;\n"}),define("Shaders/Builtin/Constants/sceneMode2D",[],function(){"use strict";return"const float czm_sceneMode2D = 2.0;\n"}),define("Shaders/Builtin/Constants/sceneMode3D",[],function(){"use strict";return"const float czm_sceneMode3D = 3.0;\n"}),define("Shaders/Builtin/Constants/sceneModeColumbusView",[],function(){"use strict";return"const float czm_sceneModeColumbusView = 1.0;\n"}),define("Shaders/Builtin/Constants/sceneModeMorphing",[],function(){"use strict";return"const float czm_sceneModeMorphing = 0.0;\n"}),define("Shaders/Builtin/Constants/solarRadius",[],function(){"use strict";return"const float czm_solarRadius = 695500000.0;\n"}),define("Shaders/Builtin/Constants/threePiOver2",[],function(){"use strict";return"const float czm_threePiOver2 = 4.71238898038469;\n"}),define("Shaders/Builtin/Constants/twoPi",[],function(){"use strict";return"const float czm_twoPi = 6.283185307179586;\n"}),define("Shaders/Builtin/Constants/webMercatorMaxLatitude",[],function(){"use strict";return"const float czm_webMercatorMaxLatitude = 1.4844222297453324;\n"}),define("Shaders/Builtin/Structs/depthRangeStruct",[],function(){"use strict";return"struct czm_depthRangeStruct\n{\nfloat near;\nfloat far;\n};\n"}),define("Shaders/Builtin/Structs/ellipsoid",[],function(){"use strict";return"struct czm_ellipsoid\n{\nvec3 center;\nvec3 radii;\nvec3 inverseRadii;\nvec3 inverseRadiiSquared;\n};\n"}),define("Shaders/Builtin/Structs/material",[],function(){"use strict";return"struct czm_material\n{\nvec3 diffuse;\nfloat specular;\nfloat shininess;\nvec3 normal;\nvec3 emission;\nfloat alpha;\n};\n"}),define("Shaders/Builtin/Structs/materialInput",[],function(){"use strict";return"struct czm_materialInput\n{\nfloat s;\nvec2 st;\nvec3 str;\nvec3 normalEC;\nmat3 tangentToEyeMatrix;\nvec3 positionToEyeEC;\nfloat height;\nfloat slope;\n};\n"}),define("Shaders/Builtin/Structs/ray",[],function(){"use strict";return"struct czm_ray\n{\nvec3 origin;\nvec3 direction;\n};\n"}),define("Shaders/Builtin/Structs/raySegment",[],function(){"use strict";return"struct czm_raySegment\n{\nfloat start;\nfloat stop;\n};\nconst czm_raySegment czm_emptyRaySegment = czm_raySegment(-czm_infinity, -czm_infinity);\nconst czm_raySegment czm_fullRaySegment = czm_raySegment(0.0, czm_infinity);\n"}),define("Shaders/Builtin/Structs/shadowParameters",[],function(){"use strict";return"struct czm_shadowParameters\n{\n#ifdef USE_CUBE_MAP_SHADOW\nvec3 texCoords;\n#else\nvec2 texCoords;\n#endif\nfloat depthBias;\nfloat depth;\nfloat nDotL;\nvec2 texelStepSize;\nfloat normalShadingSmooth;\nfloat darkness;\n};\n"}),define("Shaders/Builtin/Functions/alphaWeight",[],function(){"use strict";return"float czm_alphaWeight(float a)\n{\nfloat x = 2.0 * (gl_FragCoord.x - czm_viewport.x) / czm_viewport.z - 1.0;\nfloat y = 2.0 * (gl_FragCoord.y - czm_viewport.y) / czm_viewport.w - 1.0;\nfloat z = (gl_FragCoord.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\nvec4 q = vec4(x, y, z, 0.0);\nq /= gl_FragCoord.w;\nif (czm_inverseProjection != mat4(0.0)) {\nq = czm_inverseProjection * q;\n} else {\nfloat top = czm_frustumPlanes.x;\nfloat bottom = czm_frustumPlanes.y;\nfloat left = czm_frustumPlanes.z;\nfloat right = czm_frustumPlanes.w;\nfloat near = czm_currentFrustum.x;\nfloat far = czm_currentFrustum.y;\nq.x = (q.x * (right - left) + left + right) * 0.5;\nq.y = (q.y * (top - bottom) + bottom + top) * 0.5;\nq.z = (q.z * (near - far) - near - far) * 0.5;\nq.w = 1.0;\n}\nreturn pow(a + 0.01, 4.0) + max(1e-2, min(3.0 * 1e3, 100.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0))));\n}\n"}),define("Shaders/Builtin/Functions/antialias",[],function(){"use strict";return"vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist, float fuzzFactor)\n{\nfloat val1 = clamp(dist / fuzzFactor, 0.0, 1.0);\nfloat val2 = clamp((dist - 0.5) / fuzzFactor, 0.0, 1.0);\nval1 = val1 * (1.0 - val2);\nval1 = val1 * val1 * (3.0 - (2.0 * val1));\nval1 = pow(val1, 0.5);\nvec4 midColor = (color1 + color2) * 0.5;\nreturn mix(midColor, currentColor, val1);\n}\nvec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist)\n{\nreturn czm_antialias(color1, color2, currentColor, dist, 0.1);\n}\n"}),define("Shaders/Builtin/Functions/cascadeColor",[],function(){"use strict";return"vec4 czm_cascadeColor(vec4 weights)\n{\nreturn vec4(1.0, 0.0, 0.0, 1.0) * weights.x +\nvec4(0.0, 1.0, 0.0, 1.0) * weights.y +\nvec4(0.0, 0.0, 1.0, 1.0) * weights.z +\nvec4(1.0, 0.0, 1.0, 1.0) * weights.w;\n}\n"}),define("Shaders/Builtin/Functions/cascadeDistance",[],function(){"use strict";return"uniform vec4 shadowMap_cascadeDistances;\nfloat czm_cascadeDistance(vec4 weights)\n{\nreturn dot(shadowMap_cascadeDistances, weights);\n}\n"}),define("Shaders/Builtin/Functions/cascadeMatrix",[],function(){"use strict";return"uniform mat4 shadowMap_cascadeMatrices[4];\nmat4 czm_cascadeMatrix(vec4 weights)\n{\nreturn shadowMap_cascadeMatrices[0] * weights.x +\nshadowMap_cascadeMatrices[1] * weights.y +\nshadowMap_cascadeMatrices[2] * weights.z +\nshadowMap_cascadeMatrices[3] * weights.w;\n}\n"}),define("Shaders/Builtin/Functions/cascadeWeights",[],function(){"use strict";return"uniform vec4 shadowMap_cascadeSplits[2];\nvec4 czm_cascadeWeights(float depthEye)\n{\nvec4 near = step(shadowMap_cascadeSplits[0], vec4(depthEye));\nvec4 far = step(depthEye, shadowMap_cascadeSplits[1]);\nreturn near * far;\n}\n"}),define("Shaders/Builtin/Functions/columbusViewMorph",[],function(){"use strict";return"vec4 czm_columbusViewMorph(vec4 position2D, vec4 position3D, float time)\n{\nvec3 p = mix(position2D.xyz, position3D.xyz, time);\nreturn vec4(p, 1.0);\n}\n"}),define("Shaders/Builtin/Functions/computePosition",[],function(){"use strict";return"vec4 czm_computePosition();\n"}),define("Shaders/Builtin/Functions/cosineAndSine",[],function(){"use strict";return"vec2 cordic(float angle)\n{\nvec2 vector = vec2(6.0725293500888267e-1, 0.0);\nfloat sense = (angle < 0.0) ? -1.0 : 1.0;\nmat2 rotation = mat2(1.0, sense, -sense, 1.0);\nvector = rotation * vector;\nangle -= sense * 7.8539816339744828e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfloat factor = sense * 5.0e-1;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 4.6364760900080609e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 2.5e-1;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 2.4497866312686414e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.25e-1;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.2435499454676144e-1;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 6.25e-2;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 6.2418809995957350e-2;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.125e-2;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.1239833430268277e-2;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.5625e-2;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.5623728620476831e-2;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 7.8125e-3;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 7.8123410601011111e-3;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.90625e-3;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.9062301319669718e-3;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.953125e-3;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.9531225164788188e-3;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 9.765625e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 9.7656218955931946e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 4.8828125e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 4.8828121119489829e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 2.44140625e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 2.4414062014936177e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.220703125e-4;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.2207031189367021e-4;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 6.103515625e-5;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 6.1035156174208773e-5;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.0517578125e-5;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.0517578115526096e-5;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.52587890625e-5;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.5258789061315762e-5;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 7.62939453125e-6;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 7.6293945311019700e-6;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 3.814697265625e-6;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 3.8146972656064961e-6;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.9073486328125e-6;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 1.9073486328101870e-6;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 9.5367431640625e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 9.5367431640596084e-7;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 4.76837158203125e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 4.7683715820308884e-7;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 2.384185791015625e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nangle -= sense * 2.3841857910155797e-7;\nsense = (angle < 0.0) ? -1.0 : 1.0;\nfactor = sense * 1.1920928955078125e-7;\nrotation[0][1] = factor;\nrotation[1][0] = -factor;\nvector = rotation * vector;\nreturn vector;\n}\nvec2 czm_cosineAndSine(float angle)\n{\nif (angle < -czm_piOverTwo || angle > czm_piOverTwo)\n{\nif (angle < 0.0)\n{\nreturn -cordic(angle + czm_pi);\n}\nelse\n{\nreturn -cordic(angle - czm_pi);\n}\n}\nelse\n{\nreturn cordic(angle);\n}\n}\n"}),define("Shaders/Builtin/Functions/decompressTextureCoordinates",[],function(){"use strict";return"vec2 czm_decompressTextureCoordinates(float encoded)\n{\nfloat temp = encoded / 4096.0;\nfloat xZeroTo4095 = floor(temp);\nfloat stx = xZeroTo4095 / 4095.0;\nfloat sty = (encoded - xZeroTo4095 * 4096.0) / 4095.0;\nreturn vec2(stx, sty);\n}\n"}),define("Shaders/Builtin/Functions/depthClampFarPlane",[],function(){"use strict";return"varying float v_WindowZ;\nvec4 czm_depthClampFarPlane(vec4 coords)\n{\nv_WindowZ = (0.5 * (coords.z / coords.w) + 0.5) * coords.w;\ncoords.z = min(coords.z, coords.w);\nreturn coords;\n}\n"}),define("Shaders/Builtin/Functions/discardIfClippedWithIntersect",[],function(){"use strict";return"float czm_discardIfClippedWithIntersect(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n{\nif (clippingPlanesLength > 0)\n{\nbool clipped = true;\nvec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\nvec3 clipNormal = vec3(0.0);\nvec3 clipPosition = vec3(0.0);\nfloat clipAmount = 0.0;\nfloat pixelWidth = czm_metersPerPixel(position);\nfor (int i = 0; i < czm_maxClippingPlanes; ++i)\n{\nif (i == clippingPlanesLength)\n{\nbreak;\n}\nclipNormal = clippingPlanes[i].xyz;\nclipPosition = -clippingPlanes[i].w * clipNormal;\nfloat amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\nclipAmount = max(amount, clipAmount);\nclipped = clipped && (amount <= 0.0);\n}\nif (clipped)\n{\ndiscard;\n}\nreturn clipAmount;\n}\nreturn 0.0;\n}\n"}),define("Shaders/Builtin/Functions/discardIfClippedWithUnion",[],function(){"use strict";return"float czm_discardIfClippedWithUnion(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n{\nif (clippingPlanesLength > 0)\n{\nvec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\nvec3 clipNormal = vec3(0.0);\nvec3 clipPosition = vec3(0.0);\nfloat clipAmount = 0.0;\nfloat pixelWidth = czm_metersPerPixel(position);\nfor (int i = 0; i < czm_maxClippingPlanes; ++i)\n{\nif (i == clippingPlanesLength)\n{\nbreak;\n}\nclipNormal = clippingPlanes[i].xyz;\nclipPosition = -clippingPlanes[i].w * clipNormal;\nfloat amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\nclipAmount = max(amount, clipAmount);\nif (amount <= 0.0)\n{\ndiscard;\n}\n}\nreturn clipAmount;\n}\nreturn 0.0;\n}\n"}),define("Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates",[],function(){"use strict";return"mat3 czm_eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)\n{\nvec3 tangentMC = normalize(vec3(-positionMC.y, positionMC.x, 0.0));\nvec3 tangentEC = normalize(czm_normal3D * tangentMC);\nvec3 bitangentEC = normalize(cross(normalEC, tangentEC));\nreturn mat3(\ntangentEC.x, tangentEC.y, tangentEC.z,\nbitangentEC.x, bitangentEC.y, bitangentEC.z,\nnormalEC.x, normalEC.y, normalEC.z);\n}\n"}),define("Shaders/Builtin/Functions/ellipsoidContainsPoint",[],function(){"use strict";return"bool czm_ellipsoidContainsPoint(czm_ellipsoid ellipsoid, vec3 point)\n{\nvec3 scaled = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(point, 1.0)).xyz;\nreturn (dot(scaled, scaled) <= 1.0);\n}\n"}),define("Shaders/Builtin/Functions/ellipsoidNew",[],function(){"use strict";return"czm_ellipsoid czm_ellipsoidNew(vec3 center, vec3 radii)\n{\nvec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\nvec3 inverseRadiiSquared = inverseRadii * inverseRadii;\nczm_ellipsoid temp = czm_ellipsoid(center, radii, inverseRadii, inverseRadiiSquared);\nreturn temp;\n}\n"}),define("Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates",[],function(){"use strict";return"vec2 czm_ellipsoidWgs84TextureCoordinates(vec3 normal)\n{\nreturn vec2(atan(normal.y, normal.x) * czm_oneOverTwoPi + 0.5, asin(normal.z) * czm_oneOverPi + 0.5);\n}\n"}),define("Shaders/Builtin/Functions/equalsEpsilon",[],function(){"use strict";return"bool czm_equalsEpsilon(vec4 left, vec4 right, float epsilon) {\nreturn all(lessThanEqual(abs(left - right), vec4(epsilon)));\n}\nbool czm_equalsEpsilon(vec3 left, vec3 right, float epsilon) {\nreturn all(lessThanEqual(abs(left - right), vec3(epsilon)));\n}\nbool czm_equalsEpsilon(vec2 left, vec2 right, float epsilon) {\nreturn all(lessThanEqual(abs(left - right), vec2(epsilon)));\n}\nbool czm_equalsEpsilon(float left, float right, float epsilon) {\nreturn (abs(left - right) <= epsilon);\n}\n"}),define("Shaders/Builtin/Functions/eyeOffset",[],function(){"use strict";return"vec4 czm_eyeOffset(vec4 positionEC, vec3 eyeOffset)\n{\nvec4 p = positionEC;\nvec4 zEyeOffset = normalize(p) * eyeOffset.z;\np.xy += eyeOffset.xy + zEyeOffset.xy;\np.z += zEyeOffset.z;\nreturn p;\n}\n"}),define("Shaders/Builtin/Functions/eyeToWindowCoordinates",[],function(){"use strict";return"vec4 czm_eyeToWindowCoordinates(vec4 positionEC)\n{\nvec4 q = czm_projection * positionEC;\nq.xyz /= q.w;\nq.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\nreturn q;\n}\n"}),define("Shaders/Builtin/Functions/fog",[],function(){"use strict";return"vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor)\n{\nfloat scalar = distanceToCamera * czm_fogDensity;\nfloat fog = 1.0 - exp(-(scalar * scalar));\nreturn mix(color, fogColor, fog);\n}\n"}),define("Shaders/Builtin/Functions/geodeticSurfaceNormal",[],function(){"use strict";return"vec3 czm_geodeticSurfaceNormal(vec3 positionOnEllipsoid, vec3 ellipsoidCenter, vec3 oneOverEllipsoidRadiiSquared)\n{\nreturn normalize((positionOnEllipsoid - ellipsoidCenter) * oneOverEllipsoidRadiiSquared);\n}\n"}),define("Shaders/Builtin/Functions/getDefaultMaterial",[],function(){"use strict";return"czm_material czm_getDefaultMaterial(czm_materialInput materialInput)\n{\nczm_material material;\nmaterial.diffuse = vec3(0.0);\nmaterial.specular = 0.0;\nmaterial.shininess = 1.0;\nmaterial.normal = materialInput.normalEC;\nmaterial.emission = vec3(0.0);\nmaterial.alpha = 1.0;\nreturn material;\n}\n"}),define("Shaders/Builtin/Functions/getLambertDiffuse",[],function(){"use strict";return"float czm_getLambertDiffuse(vec3 lightDirectionEC, vec3 normalEC)\n{\nreturn max(dot(lightDirectionEC, normalEC), 0.0);\n}\n"}),define("Shaders/Builtin/Functions/getSpecular",[],function(){"use strict";return"float czm_getSpecular(vec3 lightDirectionEC, vec3 toEyeEC, vec3 normalEC, float shininess)\n{\nvec3 toReflectedLight = reflect(-lightDirectionEC, normalEC);\nfloat specular = max(dot(toReflectedLight, toEyeEC), 0.0);\nreturn pow(specular, max(shininess, czm_epsilon2));\n}\n"}),define("Shaders/Builtin/Functions/getWaterNoise",[],function(){"use strict";return"vec4 czm_getWaterNoise(sampler2D normalMap, vec2 uv, float time, float angleInRadians)\n{\nfloat cosAngle = cos(angleInRadians);\nfloat sinAngle = sin(angleInRadians);\nvec2 s0 = vec2(1.0/17.0, 0.0);\nvec2 s1 = vec2(-1.0/29.0, 0.0);\nvec2 s2 = vec2(1.0/101.0, 1.0/59.0);\nvec2 s3 = vec2(-1.0/109.0, -1.0/57.0);\ns0 = vec2((cosAngle * s0.x) - (sinAngle * s0.y), (sinAngle * s0.x) + (cosAngle * s0.y));\ns1 = vec2((cosAngle * s1.x) - (sinAngle * s1.y), (sinAngle * s1.x) + (cosAngle * s1.y));\ns2 = vec2((cosAngle * s2.x) - (sinAngle * s2.y), (sinAngle * s2.x) + (cosAngle * s2.y));\ns3 = vec2((cosAngle * s3.x) - (sinAngle * s3.y), (sinAngle * s3.x) + (cosAngle * s3.y));\nvec2 uv0 = (uv/103.0) + (time * s0);\nvec2 uv1 = uv/107.0 + (time * s1) + vec2(0.23);\nvec2 uv2 = uv/vec2(897.0, 983.0) + (time * s2) + vec2(0.51);\nvec2 uv3 = uv/vec2(991.0, 877.0) + (time * s3) + vec2(0.71);\nuv0 = fract(uv0);\nuv1 = fract(uv1);\nuv2 = fract(uv2);\nuv3 = fract(uv3);\nvec4 noise = (texture2D(normalMap, uv0)) +\n(texture2D(normalMap, uv1)) +\n(texture2D(normalMap, uv2)) +\n(texture2D(normalMap, uv3));\nreturn ((noise / 4.0) - 0.5) * 2.0;\n}\n"}),define("Shaders/Builtin/Functions/getWgs84EllipsoidEC",[],function(){"use strict";return"czm_ellipsoid czm_getWgs84EllipsoidEC()\n{\nvec3 radii = vec3(6378137.0, 6378137.0, 6356752.314245);\nvec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\nvec3 inverseRadiiSquared = inverseRadii * inverseRadii;\nczm_ellipsoid temp = czm_ellipsoid(czm_view[3].xyz, radii, inverseRadii, inverseRadiiSquared);\nreturn temp;\n}\n"}),define("Shaders/Builtin/Functions/HSBToRGB",[],function(){"use strict";return"const vec4 K_HSB2RGB = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\nvec3 czm_HSBToRGB(vec3 hsb)\n{\nvec3 p = abs(fract(hsb.xxx + K_HSB2RGB.xyz) * 6.0 - K_HSB2RGB.www);\nreturn hsb.z * mix(K_HSB2RGB.xxx, clamp(p - K_HSB2RGB.xxx, 0.0, 1.0), hsb.y);\n}\n"}),define("Shaders/Builtin/Functions/HSLToRGB",[],function(){"use strict";return"vec3 hueToRGB(float hue)\n{\nfloat r = abs(hue * 6.0 - 3.0) - 1.0;\nfloat g = 2.0 - abs(hue * 6.0 - 2.0);\nfloat b = 2.0 - abs(hue * 6.0 - 4.0);\nreturn clamp(vec3(r, g, b), 0.0, 1.0);\n}\nvec3 czm_HSLToRGB(vec3 hsl)\n{\nvec3 rgb = hueToRGB(hsl.x);\nfloat c = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;\nreturn (rgb - 0.5) * c + hsl.z;\n}\n"}),define("Shaders/Builtin/Functions/hue",[],function(){"use strict";return"vec3 czm_hue(vec3 rgb, float adjustment)\n{\nconst mat3 toYIQ = mat3(0.299, 0.587, 0.114,\n0.595716, -0.274453, -0.321263,\n0.211456, -0.522591, 0.311135);\nconst mat3 toRGB = mat3(1.0, 0.9563, 0.6210,\n1.0, -0.2721, -0.6474,\n1.0, -1.107, 1.7046);\nvec3 yiq = toYIQ * rgb;\nfloat hue = atan(yiq.z, yiq.y) + adjustment;\nfloat chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);\nvec3 color = vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));\nreturn toRGB * color;\n}\n"}),define("Shaders/Builtin/Functions/isEmpty",[],function(){"use strict";return"bool czm_isEmpty(czm_raySegment interval)\n{\nreturn (interval.stop < 0.0);\n}\n"});define("Shaders/Builtin/Functions/isFull",[],function(){"use strict";return"bool czm_isFull(czm_raySegment interval)\n{\nreturn (interval.start == 0.0 && interval.stop == czm_infinity);\n}\n"}),define("Shaders/Builtin/Functions/latitudeToWebMercatorFraction",[],function(){"use strict";return"float czm_latitudeToWebMercatorFraction(float latitude, float southMercatorY, float oneOverMercatorHeight)\n{\nfloat sinLatitude = sin(latitude);\nfloat mercatorY = 0.5 * log((1.0 + sinLatitude) / (1.0 - sinLatitude));\nreturn (mercatorY - southMercatorY) * oneOverMercatorHeight;\n}\n"}),define("Shaders/Builtin/Functions/luminance",[],function(){"use strict";return"float czm_luminance(vec3 rgb)\n{\nconst vec3 W = vec3(0.2125, 0.7154, 0.0721);\nreturn dot(rgb, W);\n}\n"}),define("Shaders/Builtin/Functions/metersPerPixel",[],function(){"use strict";return"float czm_metersPerPixel(vec4 positionEC)\n{\nfloat width = czm_viewport.z;\nfloat height = czm_viewport.w;\nfloat pixelWidth;\nfloat pixelHeight;\nfloat top = czm_frustumPlanes.x;\nfloat bottom = czm_frustumPlanes.y;\nfloat left = czm_frustumPlanes.z;\nfloat right = czm_frustumPlanes.w;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nfloat frustumWidth = right - left;\nfloat frustumHeight = top - bottom;\npixelWidth = frustumWidth / width;\npixelHeight = frustumHeight / height;\n}\nelse\n{\nfloat distanceToPixel = -positionEC.z;\nfloat inverseNear = 1.0 / czm_currentFrustum.x;\nfloat tanTheta = top * inverseNear;\npixelHeight = 2.0 * distanceToPixel * tanTheta / height;\ntanTheta = right * inverseNear;\npixelWidth = 2.0 * distanceToPixel * tanTheta / width;\n}\nreturn max(pixelWidth, pixelHeight);\n}\n"}),define("Shaders/Builtin/Functions/modelToWindowCoordinates",[],function(){"use strict";return"vec4 czm_modelToWindowCoordinates(vec4 position)\n{\nvec4 q = czm_modelViewProjection * position;\nq.xyz /= q.w;\nq.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\nreturn q;\n}\n"}),define("Shaders/Builtin/Functions/multiplyWithColorBalance",[],function(){"use strict";return"vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right)\n{\nconst vec3 W = vec3(0.2125, 0.7154, 0.0721);\nvec3 target = left * right;\nfloat leftLuminance = dot(left, W);\nfloat rightLuminance = dot(right, W);\nfloat targetLuminance = dot(target, W);\nreturn ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target;\n}\n"}),define("Shaders/Builtin/Functions/nearFarScalar",[],function(){"use strict";return"float czm_nearFarScalar(vec4 nearFarScalar, float cameraDistSq)\n{\nfloat valueAtMin = nearFarScalar.y;\nfloat valueAtMax = nearFarScalar.w;\nfloat nearDistanceSq = nearFarScalar.x * nearFarScalar.x;\nfloat farDistanceSq = nearFarScalar.z * nearFarScalar.z;\nfloat t = (cameraDistSq - nearDistanceSq) / (farDistanceSq - nearDistanceSq);\nt = pow(clamp(t, 0.0, 1.0), 0.2);\nreturn mix(valueAtMin, valueAtMax, t);\n}\n"}),define("Shaders/Builtin/Functions/octDecode",[],function(){"use strict";return"vec3 czm_octDecode(vec2 encoded, float range)\n{\nif (encoded.x == 0.0 && encoded.y == 0.0) {\nreturn vec3(0.0, 0.0, 0.0);\n}\nencoded = encoded / range * 2.0 - 1.0;\nvec3 v = vec3(encoded.x, encoded.y, 1.0 - abs(encoded.x) - abs(encoded.y));\nif (v.z < 0.0)\n{\nv.xy = (1.0 - abs(v.yx)) * czm_signNotZero(v.xy);\n}\nreturn normalize(v);\n}\nvec3 czm_octDecode(vec2 encoded)\n{\nreturn czm_octDecode(encoded, 255.0);\n}\nvec3 czm_octDecode(float encoded)\n{\nfloat temp = encoded / 256.0;\nfloat x = floor(temp);\nfloat y = (temp - x) * 256.0;\nreturn czm_octDecode(vec2(x, y));\n}\nvoid czm_octDecode(vec2 encoded, out vec3 vector1, out vec3 vector2, out vec3 vector3)\n{\nfloat temp = encoded.x / 65536.0;\nfloat x = floor(temp);\nfloat encodedFloat1 = (temp - x) * 65536.0;\ntemp = encoded.y / 65536.0;\nfloat y = floor(temp);\nfloat encodedFloat2 = (temp - y) * 65536.0;\nvector1 = czm_octDecode(encodedFloat1);\nvector2 = czm_octDecode(encodedFloat2);\nvector3 = czm_octDecode(vec2(x, y));\n}\n"}),define("Shaders/Builtin/Functions/packDepth",[],function(){"use strict";return"vec4 czm_packDepth(float depth)\n{\nvec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nenc = fract(enc);\nenc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\nreturn enc;\n}\n"}),define("Shaders/Builtin/Functions/phong",[],function(){"use strict";return"float czm_private_getLambertDiffuseOfMaterial(vec3 lightDirectionEC, czm_material material)\n{\nreturn czm_getLambertDiffuse(lightDirectionEC, material.normal);\n}\nfloat czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm_material material)\n{\nreturn czm_getSpecular(lightDirectionEC, toEyeEC, material.normal, material.shininess);\n}\nvec4 czm_phong(vec3 toEye, czm_material material)\n{\nfloat diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material);\nif (czm_sceneMode == czm_sceneMode3D) {\ndiffuse += czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 1.0, 0.0), material);\n}\nfloat specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material) + czm_private_getSpecularOfMaterial(czm_moonDirectionEC, toEye, material);\nvec3 materialDiffuse = material.diffuse * 0.5;\nvec3 ambient = materialDiffuse;\nvec3 color = ambient + material.emission;\ncolor += materialDiffuse * diffuse;\ncolor += material.specular * specular;\nreturn vec4(color, material.alpha);\n}\nvec4 czm_private_phong(vec3 toEye, czm_material material)\n{\nfloat diffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material);\nfloat specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material);\nvec3 ambient = vec3(0.0);\nvec3 color = ambient + material.emission;\ncolor += material.diffuse * diffuse;\ncolor += material.specular * specular;\nreturn vec4(color, material.alpha);\n}\n"}),define("Shaders/Builtin/Functions/pointAlongRay",[],function(){"use strict";return"vec3 czm_pointAlongRay(czm_ray ray, float time)\n{\nreturn ray.origin + (time * ray.direction);\n}\n"}),define("Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval",[],function(){"use strict" +;return"czm_raySegment czm_rayEllipsoidIntersectionInterval(czm_ray ray, czm_ellipsoid ellipsoid)\n{\nvec3 q = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.origin, 1.0)).xyz;\nvec3 w = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.direction, 0.0)).xyz;\nq = q - ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ellipsoid.center, 1.0)).xyz;\nfloat q2 = dot(q, q);\nfloat qw = dot(q, w);\nif (q2 > 1.0)\n{\nif (qw >= 0.0)\n{\nreturn czm_emptyRaySegment;\n}\nelse\n{\nfloat qw2 = qw * qw;\nfloat difference = q2 - 1.0;\nfloat w2 = dot(w, w);\nfloat product = w2 * difference;\nif (qw2 < product)\n{\nreturn czm_emptyRaySegment;\n}\nelse if (qw2 > product)\n{\nfloat discriminant = qw * qw - product;\nfloat temp = -qw + sqrt(discriminant);\nfloat root0 = temp / w2;\nfloat root1 = difference / temp;\nif (root0 < root1)\n{\nczm_raySegment i = czm_raySegment(root0, root1);\nreturn i;\n}\nelse\n{\nczm_raySegment i = czm_raySegment(root1, root0);\nreturn i;\n}\n}\nelse\n{\nfloat root = sqrt(difference / w2);\nczm_raySegment i = czm_raySegment(root, root);\nreturn i;\n}\n}\n}\nelse if (q2 < 1.0)\n{\nfloat difference = q2 - 1.0;\nfloat w2 = dot(w, w);\nfloat product = w2 * difference;\nfloat discriminant = qw * qw - product;\nfloat temp = -qw + sqrt(discriminant);\nczm_raySegment i = czm_raySegment(0.0, temp / w2);\nreturn i;\n}\nelse\n{\nif (qw < 0.0)\n{\nfloat w2 = dot(w, w);\nczm_raySegment i = czm_raySegment(0.0, -qw / w2);\nreturn i;\n}\nelse\n{\nreturn czm_emptyRaySegment;\n}\n}\n}\n"}),define("Shaders/Builtin/Functions/RGBToHSB",[],function(){"use strict";return"const vec4 K_RGB2HSB = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\nvec3 czm_RGBToHSB(vec3 rgb)\n{\nvec4 p = mix(vec4(rgb.bg, K_RGB2HSB.wz), vec4(rgb.gb, K_RGB2HSB.xy), step(rgb.b, rgb.g));\nvec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r));\nfloat d = q.x - min(q.w, q.y);\nreturn vec3(abs(q.z + (q.w - q.y) / (6.0 * d + czm_epsilon7)), d / (q.x + czm_epsilon7), q.x);\n}\n"}),define("Shaders/Builtin/Functions/RGBToHSL",[],function(){"use strict";return"vec3 RGBtoHCV(vec3 rgb)\n{\nvec4 p = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0 / 3.0) : vec4(rgb.gb, 0.0, -1.0 / 3.0);\nvec4 q = (rgb.r < p.x) ? vec4(p.xyw, rgb.r) : vec4(rgb.r, p.yzx);\nfloat c = q.x - min(q.w, q.y);\nfloat h = abs((q.w - q.y) / (6.0 * c + czm_epsilon7) + q.z);\nreturn vec3(h, c, q.x);\n}\nvec3 czm_RGBToHSL(vec3 rgb)\n{\nvec3 hcv = RGBtoHCV(rgb);\nfloat l = hcv.z - hcv.y * 0.5;\nfloat s = hcv.y / (1.0 - abs(l * 2.0 - 1.0) + czm_epsilon7);\nreturn vec3(hcv.x, s, l);\n}\n"}),define("Shaders/Builtin/Functions/RGBToXYZ",[],function(){"use strict";return"vec3 czm_RGBToXYZ(vec3 rgb)\n{\nconst mat3 RGB2XYZ = mat3(0.4124, 0.2126, 0.0193,\n0.3576, 0.7152, 0.1192,\n0.1805, 0.0722, 0.9505);\nvec3 xyz = RGB2XYZ * rgb;\nvec3 Yxy;\nYxy.r = xyz.g;\nfloat temp = dot(vec3(1.0), xyz);\nYxy.gb = xyz.rg / temp;\nreturn Yxy;\n}\n"}),define("Shaders/Builtin/Functions/saturation",[],function(){"use strict";return"vec3 czm_saturation(vec3 rgb, float adjustment)\n{\nconst vec3 W = vec3(0.2125, 0.7154, 0.0721);\nvec3 intensity = vec3(dot(rgb, W));\nreturn mix(intensity, rgb, adjustment);\n}\n"}),define("Shaders/Builtin/Functions/shadowDepthCompare",[],function(){"use strict";return"float czm_sampleShadowMap(samplerCube shadowMap, vec3 d)\n{\nreturn czm_unpackDepth(textureCube(shadowMap, d));\n}\nfloat czm_sampleShadowMap(sampler2D shadowMap, vec2 uv)\n{\n#ifdef USE_SHADOW_DEPTH_TEXTURE\nreturn texture2D(shadowMap, uv).r;\n#else\nreturn czm_unpackDepth(texture2D(shadowMap, uv));\n#endif\n}\nfloat czm_shadowDepthCompare(samplerCube shadowMap, vec3 uv, float depth)\n{\nreturn step(depth, czm_sampleShadowMap(shadowMap, uv));\n}\nfloat czm_shadowDepthCompare(sampler2D shadowMap, vec2 uv, float depth)\n{\nreturn step(depth, czm_sampleShadowMap(shadowMap, uv));\n}\n"}),define("Shaders/Builtin/Functions/shadowVisibility",[],function(){"use strict";return"float czm_private_shadowVisibility(float visibility, float nDotL, float normalShadingSmooth, float darkness)\n{\n#ifdef USE_NORMAL_SHADING\n#ifdef USE_NORMAL_SHADING_SMOOTH\nfloat strength = clamp(nDotL / normalShadingSmooth, 0.0, 1.0);\n#else\nfloat strength = step(0.0, nDotL);\n#endif\nvisibility *= strength;\n#endif\nvisibility = max(visibility, darkness);\nreturn visibility;\n}\n#ifdef USE_CUBE_MAP_SHADOW\nfloat czm_shadowVisibility(samplerCube shadowMap, czm_shadowParameters shadowParameters)\n{\nfloat depthBias = shadowParameters.depthBias;\nfloat depth = shadowParameters.depth;\nfloat nDotL = shadowParameters.nDotL;\nfloat normalShadingSmooth = shadowParameters.normalShadingSmooth;\nfloat darkness = shadowParameters.darkness;\nvec3 uvw = shadowParameters.texCoords;\ndepth -= depthBias;\nfloat visibility = czm_shadowDepthCompare(shadowMap, uvw, depth);\nreturn czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n}\n#else\nfloat czm_shadowVisibility(sampler2D shadowMap, czm_shadowParameters shadowParameters)\n{\nfloat depthBias = shadowParameters.depthBias;\nfloat depth = shadowParameters.depth;\nfloat nDotL = shadowParameters.nDotL;\nfloat normalShadingSmooth = shadowParameters.normalShadingSmooth;\nfloat darkness = shadowParameters.darkness;\nvec2 uv = shadowParameters.texCoords;\ndepth -= depthBias;\n#ifdef USE_SOFT_SHADOWS\nvec2 texelStepSize = shadowParameters.texelStepSize;\nfloat radius = 1.0;\nfloat dx0 = -texelStepSize.x * radius;\nfloat dy0 = -texelStepSize.y * radius;\nfloat dx1 = texelStepSize.x * radius;\nfloat dy1 = texelStepSize.y * radius;\nfloat visibility = (\nczm_shadowDepthCompare(shadowMap, uv, depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx0, 0.0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx1, 0.0), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy1), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy1), depth) +\nczm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy1), depth)\n) * (1.0 / 9.0);\n#else\nfloat visibility = czm_shadowDepthCompare(shadowMap, uv, depth);\n#endif\nreturn czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n}\n#endif\n"}),define("Shaders/Builtin/Functions/signNotZero",[],function(){"use strict";return"float czm_signNotZero(float value)\n{\nreturn value >= 0.0 ? 1.0 : -1.0;\n}\nvec2 czm_signNotZero(vec2 value)\n{\nreturn vec2(czm_signNotZero(value.x), czm_signNotZero(value.y));\n}\nvec3 czm_signNotZero(vec3 value)\n{\nreturn vec3(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z));\n}\nvec4 czm_signNotZero(vec4 value)\n{\nreturn vec4(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z), czm_signNotZero(value.w));\n}\n"}),define("Shaders/Builtin/Functions/tangentToEyeSpaceMatrix",[],function(){"use strict";return"mat3 czm_tangentToEyeSpaceMatrix(vec3 normalEC, vec3 tangentEC, vec3 bitangentEC)\n{\nvec3 normal = normalize(normalEC);\nvec3 tangent = normalize(tangentEC);\nvec3 bitangent = normalize(bitangentEC);\nreturn mat3(tangent.x , tangent.y , tangent.z,\nbitangent.x, bitangent.y, bitangent.z,\nnormal.x , normal.y , normal.z);\n}\n"}),define("Shaders/Builtin/Functions/translateRelativeToEye",[],function(){"use strict";return"vec4 czm_translateRelativeToEye(vec3 high, vec3 low)\n{\nvec3 highDifference = high - czm_encodedCameraPositionMCHigh;\nvec3 lowDifference = low - czm_encodedCameraPositionMCLow;\nreturn vec4(highDifference + lowDifference, 1.0);\n}\n"}),define("Shaders/Builtin/Functions/translucentPhong",[],function(){"use strict";return"vec4 czm_translucentPhong(vec3 toEye, czm_material material)\n{\nfloat diffuse = czm_getLambertDiffuse(vec3(0.0, 0.0, 1.0), material.normal);\nif (czm_sceneMode == czm_sceneMode3D) {\ndiffuse += czm_getLambertDiffuse(vec3(0.0, 1.0, 0.0), material.normal);\n}\ndiffuse = clamp(diffuse, 0.0, 1.0);\nfloat specular = czm_getSpecular(czm_sunDirectionEC, toEye, material.normal, material.shininess);\nspecular += czm_getSpecular(czm_moonDirectionEC, toEye, material.normal, material.shininess);\nvec3 materialDiffuse = material.diffuse * 0.5;\nvec3 ambient = materialDiffuse;\nvec3 color = ambient + material.emission;\ncolor += materialDiffuse * diffuse;\ncolor += material.specular * specular;\nreturn vec4(color, material.alpha);\n}\n"}),define("Shaders/Builtin/Functions/transpose",[],function(){"use strict";return"mat2 czm_transpose(mat2 matrix)\n{\nreturn mat2(\nmatrix[0][0], matrix[1][0],\nmatrix[0][1], matrix[1][1]);\n}\nmat3 czm_transpose(mat3 matrix)\n{\nreturn mat3(\nmatrix[0][0], matrix[1][0], matrix[2][0],\nmatrix[0][1], matrix[1][1], matrix[2][1],\nmatrix[0][2], matrix[1][2], matrix[2][2]);\n}\nmat4 czm_transpose(mat4 matrix)\n{\nreturn mat4(\nmatrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],\nmatrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],\nmatrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],\nmatrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);\n}\n"}),define("Shaders/Builtin/Functions/unpackDepth",[],function(){"use strict";return"float czm_unpackDepth(vec4 packedDepth)\n{\nreturn dot(packedDepth, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n}\n"}),define("Shaders/Builtin/Functions/windowToEyeCoordinates",[],function(){"use strict";return"vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate)\n{\nfloat x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0;\nfloat y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0;\nfloat z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\nvec4 q = vec4(x, y, z, 1.0);\nq /= fragmentCoordinate.w;\nif (czm_inverseProjection != mat4(0.0)) {\nq = czm_inverseProjection * q;\n} else {\nfloat top = czm_frustumPlanes.x;\nfloat bottom = czm_frustumPlanes.y;\nfloat left = czm_frustumPlanes.z;\nfloat right = czm_frustumPlanes.w;\nfloat near = czm_currentFrustum.x;\nfloat far = czm_currentFrustum.y;\nq.x = (q.x * (right - left) + left + right) * 0.5;\nq.y = (q.y * (top - bottom) + bottom + top) * 0.5;\nq.z = (q.z * (near - far) - near - far) * 0.5;\nq.w = 1.0;\n}\nreturn q;\n}\n"}),define("Shaders/Builtin/Functions/writeDepthClampedToFarPlane",[],function(){"use strict";return"varying float v_WindowZ;\nvoid czm_writeDepthClampedToFarPlane()\n{\n#ifdef GL_EXT_frag_depth\ngl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n#endif\n}\n"}),define("Shaders/Builtin/Functions/XYZToRGB",[],function(){"use strict";return"vec3 czm_XYZToRGB(vec3 Yxy)\n{\nconst mat3 XYZ2RGB = mat3( 3.2405, -0.9693, 0.0556,\n-1.5371, 1.8760, -0.2040,\n-0.4985, 0.0416, 1.0572);\nvec3 xyz;\nxyz.r = Yxy.r * Yxy.g / Yxy.b;\nxyz.g = Yxy.r;\nxyz.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b;\nreturn XYZ2RGB * xyz;\n}\n"}),define("Shaders/Builtin/CzmBuiltins",["./Constants/degreesPerRadian","./Constants/depthRange","./Constants/epsilon1","./Constants/epsilon2","./Constants/epsilon3","./Constants/epsilon4","./Constants/epsilon5","./Constants/epsilon6","./Constants/epsilon7","./Constants/infinity","./Constants/maxClippingPlanes","./Constants/oneOverPi","./Constants/oneOverTwoPi","./Constants/passCesium3DTile","./Constants/passCesium3DTileClassification","./Constants/passCesium3DTileClassificationIgnoreShow","./Constants/passClassification","./Constants/passCompute","./Constants/passEnvironment","./Constants/passGlobe","./Constants/passOpaque","./Constants/passOverlay","./Constants/passTerrainClassification","./Constants/passTranslucent","./Constants/pi","./Constants/piOverFour","./Constants/piOverSix","./Constants/piOverThree","./Constants/piOverTwo","./Constants/radiansPerDegree","./Constants/sceneMode2D","./Constants/sceneMode3D","./Constants/sceneModeColumbusView","./Constants/sceneModeMorphing","./Constants/solarRadius","./Constants/threePiOver2","./Constants/twoPi","./Constants/webMercatorMaxLatitude","./Structs/depthRangeStruct","./Structs/ellipsoid","./Structs/material","./Structs/materialInput","./Structs/ray","./Structs/raySegment","./Structs/shadowParameters","./Functions/alphaWeight","./Functions/antialias","./Functions/cascadeColor","./Functions/cascadeDistance","./Functions/cascadeMatrix","./Functions/cascadeWeights","./Functions/columbusViewMorph","./Functions/computePosition","./Functions/cosineAndSine","./Functions/decompressTextureCoordinates","./Functions/depthClampFarPlane","./Functions/discardIfClippedWithIntersect","./Functions/discardIfClippedWithUnion","./Functions/eastNorthUpToEyeCoordinates","./Functions/ellipsoidContainsPoint","./Functions/ellipsoidNew","./Functions/ellipsoidWgs84TextureCoordinates","./Functions/equalsEpsilon","./Functions/eyeOffset","./Functions/eyeToWindowCoordinates","./Functions/fog","./Functions/geodeticSurfaceNormal","./Functions/getDefaultMaterial","./Functions/getLambertDiffuse","./Functions/getSpecular","./Functions/getWaterNoise","./Functions/getWgs84EllipsoidEC","./Functions/HSBToRGB","./Functions/HSLToRGB","./Functions/hue","./Functions/isEmpty","./Functions/isFull","./Functions/latitudeToWebMercatorFraction","./Functions/luminance","./Functions/metersPerPixel","./Functions/modelToWindowCoordinates","./Functions/multiplyWithColorBalance","./Functions/nearFarScalar","./Functions/octDecode","./Functions/packDepth","./Functions/phong","./Functions/pointAlongRay","./Functions/rayEllipsoidIntersectionInterval","./Functions/RGBToHSB","./Functions/RGBToHSL","./Functions/RGBToXYZ","./Functions/saturation","./Functions/shadowDepthCompare","./Functions/shadowVisibility","./Functions/signNotZero","./Functions/tangentToEyeSpaceMatrix","./Functions/translateRelativeToEye","./Functions/translucentPhong","./Functions/transpose","./Functions/unpackDepth","./Functions/windowToEyeCoordinates","./Functions/writeDepthClampedToFarPlane","./Functions/XYZToRGB"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,be,Ce,Se,we,Te,Ee,Ae,xe,Pe,De,Ie,Oe,Me,Re,Le,Ne,ke,Fe,Be,Ue,Ve,ze,Ge,We,He,je,qe,Ye,Xe){"use strict";return{czm_degreesPerRadian:e,czm_depthRange:t,czm_epsilon1:r,czm_epsilon2:i,czm_epsilon3:n,czm_epsilon4:o,czm_epsilon5:a,czm_epsilon6:s,czm_epsilon7:l,czm_infinity:u,czm_maxClippingPlanes:c,czm_oneOverPi:d,czm_oneOverTwoPi:h,czm_passCesium3DTile:p,czm_passCesium3DTileClassification:f,czm_passCesium3DTileClassificationIgnoreShow:m,czm_passClassification:g,czm_passCompute:_,czm_passEnvironment:v,czm_passGlobe:y,czm_passOpaque:b,czm_passOverlay:C,czm_passTerrainClassification:S,czm_passTranslucent:w,czm_pi:T,czm_piOverFour:E,czm_piOverSix:A,czm_piOverThree:x,czm_piOverTwo:P,czm_radiansPerDegree:D,czm_sceneMode2D:I,czm_sceneMode3D:O,czm_sceneModeColumbusView:M,czm_sceneModeMorphing:R,czm_solarRadius:L,czm_threePiOver2:N,czm_twoPi:k,czm_webMercatorMaxLatitude:F,czm_depthRangeStruct:B,czm_ellipsoid:U,czm_material:V,czm_materialInput:z,czm_ray:G,czm_raySegment:W,czm_shadowParameters:H,czm_alphaWeight:j,czm_antialias:q,czm_cascadeColor:Y,czm_cascadeDistance:X,czm_cascadeMatrix:Q,czm_cascadeWeights:Z,czm_columbusViewMorph:K,czm_computePosition:J,czm_cosineAndSine:$,czm_decompressTextureCoordinates:ee,czm_depthClampFarPlane:te,czm_discardIfClippedWithIntersect:re,czm_discardIfClippedWithUnion:ie,czm_eastNorthUpToEyeCoordinates:ne,czm_ellipsoidContainsPoint:oe,czm_ellipsoidNew:ae,czm_ellipsoidWgs84TextureCoordinates:se,czm_equalsEpsilon:le,czm_eyeOffset:ue,czm_eyeToWindowCoordinates:ce,czm_fog:de,czm_geodeticSurfaceNormal:he,czm_getDefaultMaterial:pe,czm_getLambertDiffuse:fe,czm_getSpecular:me,czm_getWaterNoise:ge,czm_getWgs84EllipsoidEC:_e,czm_HSBToRGB:ve,czm_HSLToRGB:ye,czm_hue:be,czm_isEmpty:Ce,czm_isFull:Se,czm_latitudeToWebMercatorFraction:we,czm_luminance:Te,czm_metersPerPixel:Ee,czm_modelToWindowCoordinates:Ae,czm_multiplyWithColorBalance:xe,czm_nearFarScalar:Pe,czm_octDecode:De,czm_packDepth:Ie,czm_phong:Oe,czm_pointAlongRay:Me,czm_rayEllipsoidIntersectionInterval:Re,czm_RGBToHSB:Le,czm_RGBToHSL:Ne,czm_RGBToXYZ:ke,czm_saturation:Fe,czm_shadowDepthCompare:Be,czm_shadowVisibility:Ue,czm_signNotZero:Ve,czm_tangentToEyeSpaceMatrix:ze,czm_translateRelativeToEye:Ge,czm_translucentPhong:We,czm_transpose:He,czm_unpackDepth:je,czm_windowToEyeCoordinates:qe,czm_writeDepthClampedToFarPlane:Ye,czm_XYZToRGB:Xe}}),define("Renderer/ShaderSource",["../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Renderer/modernizeShader","../Shaders/Builtin/CzmBuiltins","./AutomaticUniforms"],function(e,t,r,i,n,o){"use strict";function a(e){return e=e.replace(/\/\/.*/g,""),e.replace(/\/\*\*[\s\S]*?\*\//gm,function(e){for(var t=e.match(/\n/gm).length,r="",i=0;i<t;++i)r+="\n";return r})}function s(e,r,i){for(var n,o=0;o<i.length;++o)i[o].name===e&&(n=i[o]);return t(n)||(r=a(r),n={name:e,glslSource:r,dependsOn:[],requiredBy:[],evaluated:!1},i.push(n)),n}function l(e,r){if(!e.evaluated){e.evaluated=!0;var i=e.glslSource.match(/\bczm_[a-zA-Z0-9_]*/g);t(i)&&null!==i&&(i=i.filter(function(e,t){return i.indexOf(e)===t}),i.forEach(function(t){if(t!==e.name&&h._czmBuiltinsAndUniforms.hasOwnProperty(t)){var i=s(t,h._czmBuiltinsAndUniforms[t],r);e.dependsOn.push(i),i.requiredBy.push(e),l(i,r)}}))}}function u(e){for(var t=[],r=[];e.length>0;){var i=e.pop();r.push(i),0===i.requiredBy.length&&t.push(i)}for(;t.length>0;){var n=t.shift();e.push(n);for(var o=0;o<n.dependsOn.length;++o){var a=n.dependsOn[o],s=a.requiredBy.indexOf(n);a.requiredBy.splice(s,1),0===a.requiredBy.length&&t.push(a)}}for(var l=[],u=0;u<r.length;++u)0!==r[u].requiredBy.length&&l.push(r[u])}function c(e){var t=[],r=s("main",e,t);l(r,t),u(t);for(var i="",n=t.length-1;n>=0;--n)i=i+t[n].glslSource+"\n";return i.replace(r.glslSource,"")}function d(e,r,n){var o,s,l="",u=e.sources;if(t(u))for(o=0,s=u.length;o<s;++o)l+="\n#line 0\n"+u[o];l=a(l);var d;l=l.replace(/#version\s+(.*?)\n/gm,function(e,t){return d=t,"\n"});var p=[];l=l.replace(/#extension.*\n/gm,function(e){return p.push(e),"\n"}),l=l.replace(/precision\s(lowp|mediump|highp)\s(float|int);/,"");var f=e.pickColorQualifier;t(f)&&(l=h.createPickFragmentShaderSource(l,f));var m="";t(d)&&(m="#version "+d+"\n");var g=p.length;for(o=0;o<g;o++)m+=p[o];r&&(m+="#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n#else\n precision mediump float;\n#endif\n\n");var _=e.defines;if(t(_))for(o=0,s=_.length;o<s;++o){var v=_[o];0!==v.length&&(m+="#define "+v+"\n")}return n.webgl2&&(m+="#define OUTPUT_DECLARATION\n\n"),e.includeBuiltIns&&(m+=c(l)),m+="\n#line 0\n",m+=l,n.webgl2&&(m=i(m,r,!0)),m}function h(r){r=e(r,e.EMPTY_OBJECT);var i=r.pickColorQualifier;this.defines=t(r.defines)?r.defines.slice(0):[],this.sources=t(r.sources)?r.sources.slice(0):[],this.pickColorQualifier=i,this.includeBuiltIns=e(r.includeBuiltIns,!0)}h.prototype.clone=function(){return new h({sources:this.sources,defines:this.defines,pickColorQuantifier:this.pickColorQualifier,includeBuiltIns:this.includeBuiltIns})},h.replaceMain=function(e,t){return t="void "+t+"()",e.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g,t)},h.prototype.createCombinedVertexShader=function(e){return d(this,!1,e)},h.prototype.createCombinedFragmentShader=function(e){return d(this,!0,e)},h._czmBuiltinsAndUniforms={};for(var p in n)n.hasOwnProperty(p)&&(h._czmBuiltinsAndUniforms[p]=n[p]);for(var f in o)if(o.hasOwnProperty(f)){var m=o[f];"function"==typeof m.getDeclaration&&(h._czmBuiltinsAndUniforms[f]=m.getDeclaration(f))}h.createPickVertexShaderSource=function(e){return h.replaceMain(e,"czm_old_main")+"\nattribute vec4 pickColor; \nvarying vec4 czm_pickColor; \nvoid main() \n{ \n czm_old_main(); \n czm_pickColor = pickColor; \n}"},h.createPickFragmentShaderSource=function(e,t){return h.replaceMain(e,"czm_old_main")+"\n"+t+" vec4 czm_pickColor; \nvoid main() \n{ \n czm_old_main(); \n if (gl_FragColor.a == 0.0) { \n discard; \n } \n gl_FragColor = czm_pickColor; \n}"},h.findVarying=function(e,t){for(var r=e.sources,i=t.length,n=0;n<i;++n)for(var o=t[n],a=r.length,s=0;s<a;++s)if(-1!==r[s].indexOf(o))return o};var g=["v_normalEC","v_normal"];h.findNormalVarying=function(e){return h.findVarying(e,g)};var _=["v_positionEC"];return h.findPositionVarying=function(e){return h.findVarying(e,_)},h}),define("Renderer/Buffer",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/IndexDatatype","../Core/WebGLConstants","./BufferUsage"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e){e=t(e,t.EMPTY_OBJECT);var i=e.context._gl,n=e.bufferTarget,o=e.typedArray,a=e.sizeInBytes,s=e.usage,l=r(o);l&&(a=o.byteLength);var u=i.createBuffer();i.bindBuffer(n,u),i.bufferData(n,l?o:a,s),i.bindBuffer(n,null),this._gl=i,this._webgl2=e.context._webgl2,this._bufferTarget=n,this._sizeInBytes=a,this._usage=s,this._buffer=u,this.vertexArrayDestroyable=!0}return u.createVertexBuffer=function(e){return new u({context:e.context,bufferTarget:s.ARRAY_BUFFER,typedArray:e.typedArray,sizeInBytes:e.sizeInBytes,usage:e.usage})},u.createIndexBuffer=function(e){var t=e.context,r=e.indexDatatype,n=a.getSizeInBytes(r),o=new u({context:t,bufferTarget:s.ELEMENT_ARRAY_BUFFER,typedArray:e.typedArray,sizeInBytes:e.sizeInBytes,usage:e.usage}),l=o.sizeInBytes/n;return i(o,{indexDatatype:{get:function(){return r}},bytesPerIndex:{get:function(){return n}},numberOfIndices:{get:function(){return l}}}),o},i(u.prototype,{sizeInBytes:{get:function(){return this._sizeInBytes}},usage:{get:function(){return this._usage}}}),u.prototype._getBuffer=function(){return this._buffer},u.prototype.copyFromArrayView=function(e,r){r=t(r,0);var i=this._gl,n=this._bufferTarget;i.bindBuffer(n,this._buffer),i.bufferSubData(n,r,e),i.bindBuffer(n,null)},u.prototype.copyFromBuffer=function(e,t,r,i){var n=s.COPY_READ_BUFFER,o=s.COPY_WRITE_BUFFER,a=this._gl;a.bindBuffer(o,this._buffer),a.bindBuffer(n,e._buffer),a.copyBufferSubData(n,o,t,r,i),a.bindBuffer(o,null),a.bindBuffer(n,null)},u.prototype.getBufferData=function(e,r,i,n){r=t(r,0),i=t(i,0);var o=this._gl,a=s.COPY_READ_BUFFER;o.bindBuffer(a,this._buffer),o.getBufferSubData(a,r,e,i,n),o.bindBuffer(a,null)},u.prototype.isDestroyed=function(){return!1},u.prototype.destroy=function(){return this._gl.deleteBuffer(this._buffer),n(this)},u}),define("Renderer/VertexArray",["../Core/Check","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Geometry","../Core/IndexDatatype","../Core/Math","../Core/RuntimeError","./Buffer","./BufferUsage","./ContextLimits"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,n,o,a){var s=i(n.vertexBuffer),l=i(n.value),u=n.value?n.value.length:n.componentsPerAttribute,c={index:r(n.index,o),enabled:r(n.enabled,!0),vertexBuffer:n.vertexBuffer,value:l?n.value.slice(0):void 0,componentsPerAttribute:u,componentDatatype:r(n.componentDatatype,t.FLOAT),normalize:r(n.normalize,!1),offsetInBytes:r(n.offsetInBytes,0),strideInBytes:r(n.strideInBytes,0),instanceDivisor:r(n.instanceDivisor,0)};if(s)c.vertexAttrib=function(e){var t=this.index;e.bindBuffer(e.ARRAY_BUFFER,this.vertexBuffer._getBuffer()),e.vertexAttribPointer(t,this.componentsPerAttribute,this.componentDatatype,this.normalize,this.strideInBytes,this.offsetInBytes),e.enableVertexAttribArray(t),this.instanceDivisor>0&&(a.glVertexAttribDivisor(t,this.instanceDivisor),a._vertexAttribDivisors[t]=this.instanceDivisor,a._previousDrawInstanced=!0)},c.disableVertexAttribArray=function(e){e.disableVertexAttribArray(this.index),this.instanceDivisor>0&&a.glVertexAttribDivisor(o,0)};else{switch(c.componentsPerAttribute){case 1:c.vertexAttrib=function(e){e.vertexAttrib1fv(this.index,this.value)};break;case 2:c.vertexAttrib=function(e){e.vertexAttrib2fv(this.index,this.value)};break;case 3:c.vertexAttrib=function(e){e.vertexAttrib3fv(this.index,this.value)};break;case 4:c.vertexAttrib=function(e){e.vertexAttrib4fv(this.index,this.value)}}c.disableVertexAttribArray=function(e){}}e.push(c)}function m(e,t,r){for(var n=0;n<t.length;++n){var o=t[n];o.enabled&&o.vertexAttrib(e)}i(r)&&e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,r._getBuffer())}function g(e){e=r(e,r.EMPTY_OBJECT);var n,o=e.context,a=o._gl,s=e.attributes,l=e.indexBuffer,u=[],c=1,d=!1,h=!1,p=s.length;for(n=0;n<p;++n)f(u,s[n],n,o);for(p=u.length,n=0;n<p;++n){var g=u[n];if(i(g.vertexBuffer)&&0===g.instanceDivisor){var _=g.strideInBytes||g.componentsPerAttribute*t.getSizeInBytes(g.componentDatatype);c=g.vertexBuffer.sizeInBytes/_;break}}for(n=0;n<p;++n)u[n].instanceDivisor>0&&(d=!0),i(u[n].value)&&(h=!0);var v;o.vertexArrayObject&&(v=o.glCreateVertexArray(),o.glBindVertexArray(v),m(a,u,l),o.glBindVertexArray(null)),this._numberOfVertices=c,this._hasInstancedAttributes=d,this._hasConstantAttributes=h,this._context=o,this._gl=a,this._vao=v,this._attributes=u,this._indexBuffer=l}function _(e){return e.values.length/e.componentsPerAttribute}function v(e){return t.getSizeInBytes(e.componentDatatype)*e.componentsPerAttribute}function y(e){var r,n,o,a=[];for(n in e)e.hasOwnProperty(n)&&i(e[n])&&i(e[n].values)&&(a.push(n),e[n].componentDatatype===t.DOUBLE&&(e[n].componentDatatype=t.FLOAT,e[n].values=t.createTypedArray(t.FLOAT,e[n].values)));var s,l=a.length;if(l>0)for(s=_(e[a[0]]),r=1;r<l;++r){var u=_(e[a[r]]);if(u!==s)throw new c("Each attribute list must have the same number of vertices. Attribute "+a[r]+" has a different number of vertices ("+u.toString()+") than attribute "+a[0]+" ("+s.toString()+").")}a.sort(function(r,i){return t.getSizeInBytes(e[i].componentDatatype)-t.getSizeInBytes(e[r].componentDatatype)});var d=0,h={};for(r=0;r<l;++r)n=a[r],o=e[n],h[n]=d,d+=v(o);if(d>0){var p=t.getSizeInBytes(e[a[0]].componentDatatype),f=d%p;0!==f&&(d+=p-f);var m=s*d,g=new ArrayBuffer(m),y={};for(r=0;r<l;++r){n=a[r];var b=t.getSizeInBytes(e[n].componentDatatype);y[n]={pointer:t.createTypedArray(e[n].componentDatatype,g),index:h[n]/b,strideInComponentType:d/b}}for(r=0;r<s;++r)for(var C=0;C<l;++C){n=a[C],o=e[n];for(var S=o.values,w=y[n],T=w.pointer,E=o.componentsPerAttribute,A=0;A<E;++A)T[w.index+A]=S[r*E+A];w.index+=w.strideInComponentType}return{buffer:g,offsetsInBytes:h,vertexSizeInBytes:d}}}function b(e){var t=e._context,r=e._hasInstancedAttributes;if(r||t._previousDrawInstanced){t._previousDrawInstanced=r;var i,n=t._vertexAttribDivisors,o=e._attributes,a=p.maximumVertexAttributes;if(r){var s=o.length;for(i=0;i<s;++i){var l=o[i];if(l.enabled){var u=l.instanceDivisor,c=l.index;u!==n[c]&&(t.glVertexAttribDivisor(c,u),n[c]=u)}}}else for(i=0;i<a;++i)n[i]>0&&(t.glVertexAttribDivisor(i,0),n[i]=0)}}function C(e,t){for(var r=e._attributes,n=r.length,o=0;o<n;++o){var a=r[o];a.enabled&&i(a.value)&&a.vertexAttrib(t)}}return g.fromGeometry=function(e){e=r(e,r.EMPTY_OBJECT);var n,o,a,c=e.context,p=r(e.geometry,r.EMPTY_OBJECT),f=r(e.bufferUsage,h.DYNAMIC_DRAW),m=r(e.attributeLocations,r.EMPTY_OBJECT),_=r(e.interleave,!1),v=e.vertexArrayAttributes,b=i(v)?v:[],C=p.attributes;if(_){var S=y(C);if(i(S)){a=d.createVertexBuffer({context:c,typedArray:S.buffer,usage:f});var w=S.offsetsInBytes,T=S.vertexSizeInBytes;for(n in C)C.hasOwnProperty(n)&&i(C[n])&&(o=C[n],i(o.values)?b.push({index:m[n],vertexBuffer:a,componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,offsetInBytes:w[n],strideInBytes:T}):b.push({index:m[n],value:o.value,componentDatatype:o.componentDatatype,normalize:o.normalize}))}}else for(n in C)if(C.hasOwnProperty(n)&&i(C[n])){o=C[n];var E=o.componentDatatype;E===t.DOUBLE&&(E=t.FLOAT),a=void 0,i(o.values)&&(a=d.createVertexBuffer({context:c,typedArray:t.createTypedArray(E,o.values),usage:f})),b.push({index:m[n],vertexBuffer:a,value:o.value,componentDatatype:E,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize})}var A,x=p.indices;return i(x)&&(A=s.computeNumberOfVertices(p)>=u.SIXTY_FOUR_KILOBYTES&&c.elementIndexUint?d.createIndexBuffer({context:c,typedArray:new Uint32Array(x),usage:f,indexDatatype:l.UNSIGNED_INT}):d.createIndexBuffer({context:c,typedArray:new Uint16Array(x),usage:f,indexDatatype:l.UNSIGNED_SHORT})),new g({context:c,attributes:b,indexBuffer:A})},n(g.prototype,{numberOfAttributes:{get:function(){return this._attributes.length}},numberOfVertices:{get:function(){return this._numberOfVertices}},indexBuffer:{get:function(){return this._indexBuffer}}}),g.prototype.getAttribute=function(e){return this._attributes[e]},g.prototype._bind=function(){i(this._vao)?(this._context.glBindVertexArray(this._vao),this._context.instancedArrays&&b(this),this._hasConstantAttributes&&C(this,this._gl)):m(this._gl,this._attributes,this._indexBuffer)},g.prototype._unBind=function(){if(i(this._vao))this._context.glBindVertexArray(null);else{for(var e=this._attributes,t=this._gl,r=0;r<e.length;++r){var n=e[r];n.enabled&&n.disableVertexAttribArray(t)}this._indexBuffer&&t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null)}},g.prototype.isDestroyed=function(){return!1},g.prototype.destroy=function(){for(var e=this._attributes,t=0;t<e.length;++t){var r=e[t].vertexBuffer;i(r)&&!r.isDestroyed()&&r.vertexArrayDestroyable&&r.destroy()}var n=this._indexBuffer;return i(n)&&!n.isDestroyed()&&n.vertexArrayDestroyable&&n.destroy(),i(this._vao)&&this._context.glDeleteVertexArray(this._vao),o(this)},g}),define("Scene/BatchTable",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/combine","../Core/ComponentDatatype","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/Math","../Core/PixelFormat","../Renderer/ContextLimits","../Renderer/PixelDatatype","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(t,i,n){if(this._attributes=i,this._numberOfInstances=n,0!==i.length){var o=y(i),a=t.floatingPointTexture,s=o===p.FLOAT&&!a,l=C(i,s),u=S(l,i,s),c=Math.floor(h.maximumTextureSize/u),d=Math.min(n,c),f=u*d,m=Math.ceil(n/d),g=1/f,_=.5*g,v=1/m,b=.5*v;this._textureDimensions=new e(f,m),this._textureStep=new r(g,_,v,b),this._pixelDatatype=s?p.UNSIGNED_BYTE:o,this._packFloats=s,this._offsets=l,this._stride=u,this._texture=void 0;var w=4*f*m;this._batchValues=o!==p.FLOAT||s?new Uint8Array(w):new Float32Array(w),this._batchValuesDirty=!1}}function y(e){for(var t=!1,r=e.length,i=0;i<r;++i)if(e[i].componentDatatype!==n.UNSIGNED_BYTE){t=!0;break}return t?p.FLOAT:p.UNSIGNED_BYTE}function b(i,n){var o=i[n].componentsPerAttribute;return 2===o?e:3===o?t:4===o?r:Number}function C(e,t){for(var r=new Array(e.length),i=0,o=e.length,a=0;a<o;++a){var s=e[a],l=s.componentDatatype;r[a]=i,l!==n.UNSIGNED_BYTE&&t?i+=4:++i}return r}function S(e,t,r){var i=e.length,o=e[i-1];return t[i-1].componentDatatype!==n.UNSIGNED_BYTE&&r?o+4:o+1}function w(e){var t=e.w/2,r=Math.floor(t),i=2*(t-r);if(r-=U,i=2*i-1,i=-i,r>=U)return i<0?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY;var n=i*e.x*k;return n+=i*e.y*F,(n+=i*e.z*B)*Math.pow(10,r)}function T(e,t,i){var n=r.unpack(e,t,L),o=w(n);n=r.unpack(e,t+4,L);var a=w(n);n=r.unpack(e,t+8,L);var s=w(n);n=r.unpack(e,t+12,L);var l=w(n);return r.fromElements(o,a,s,l,i)}function E(e,t){if(V[0]=e,0===(e=V[0]))return r.clone(r.ZERO,t);var i,n=e<0?1:0;isFinite(e)?(e=Math.abs(e),i=Math.floor(c.logBase(e,10))+1,e/=Math.pow(10,i)):(e=.1,i=U);var o=e*N;return t.x=Math.floor(o),o=(o-t.x)*N,t.y=Math.floor(o),o=(o-t.y)*N,t.z=Math.floor(o),t.w=2*(i+U)+n,t}function A(e,t,i){var n=E(e.x,L);r.pack(n,t,i),n=E(e.y,n),r.pack(n,t,i+4),n=E(e.z,n),r.pack(n,t,i+8),n=E(e.w,n),r.pack(n,t,i+12)}function x(e,t){var r=e._textureDimensions;e._texture=new m({context:t,pixelFormat:d.RGBA,pixelDatatype:e._pixelDatatype,width:r.x,height:r.y, +sampler:new f({minificationFilter:_.NEAREST,magnificationFilter:g.NEAREST})})}function P(e){var t=e._textureDimensions;e._texture.copyFrom({width:t.x,height:t.y,arrayBufferView:e._batchValues})}function D(e){var t=e._stride;return 1===e._textureDimensions.y?"uniform vec4 batchTextureStep; \nvec2 computeSt(float batchId) \n{ \n float stepX = batchTextureStep.x; \n float centerX = batchTextureStep.y; \n float numberOfAttributes = float("+t+"); \n return vec2(centerX + (batchId * numberOfAttributes * stepX), 0.5); \n} \n":"uniform vec4 batchTextureStep; \nuniform vec2 batchTextureDimensions; \nvec2 computeSt(float batchId) \n{ \n float stepX = batchTextureStep.x; \n float centerX = batchTextureStep.y; \n float stepY = batchTextureStep.z; \n float centerY = batchTextureStep.w; \n float numberOfAttributes = float("+t+"); \n float xId = mod(batchId * numberOfAttributes, batchTextureDimensions.x); \n float yId = floor(batchId * numberOfAttributes / batchTextureDimensions.x); \n return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n} \n"}function I(e){return e._packFloats?"float unpackFloat(vec4 value) \n{ \n value *= 255.0; \n float temp = value.w / 2.0; \n float exponent = floor(temp); \n float sign = (temp - exponent) * 2.0; \n exponent = exponent - float("+U+"); \n sign = sign * 2.0 - 1.0; \n sign = -sign; \n float unpacked = sign * value.x * float("+k+"); \n unpacked += sign * value.y * float("+F+"); \n unpacked += sign * value.z * float("+B+"); \n return unpacked * pow(10.0, exponent); \n} \n":""}function O(e){return 1===e?"float":"vec"+e}function M(e){return 1===e?".x":2===e?".xy":3===e?".xyz":""}function R(e,t){var r=e._attributes,i=r[t],o=i.componentsPerAttribute,a=i.functionName,s=O(o),l=M(o),u=e._offsets[t],c=s+" "+a+"(float batchId) \n{ \n vec2 st = computeSt(batchId); \n st.x += batchTextureStep.x * float("+u+"); \n";return e._packFloats&&i.componentDatatype!==p.UNSIGNED_BYTE?c+="vec4 textureValue; \ntextureValue.x = unpackFloat(texture2D(batchTexture, st)); \ntextureValue.y = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x, 0.0))); \ntextureValue.z = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 2.0, 0.0))); \ntextureValue.w = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 3.0, 0.0))); \n":c+=" vec4 textureValue = texture2D(batchTexture, st); \n",c+=" "+s+" value = textureValue"+l+"; \n",e._pixelDatatype!==p.UNSIGNED_BYTE||i.componentDatatype!==n.UNSIGNED_BYTE||i.normalize?e._pixelDatatype===p.FLOAT&&i.componentDatatype===n.UNSIGNED_BYTE&&i.normalize&&(c+="value /= 255.0; \n"):c+="value *= 255.0; \n",c+=" return value; \n} \n"}a(v.prototype,{attributes:{get:function(){return this._attributes}},numberOfInstances:{get:function(){return this._numberOfInstances}}});var L=new r,N=256,k=1/N,F=1/65536,B=1/16777216,U=38;if(u.supportsTypedArrays()){var V=new Float32Array(1),z=new r;v.prototype.getBatchedAttribute=function(e,t,i){var n,a=this._attributes,s=this._offsets[t],l=this._stride,u=4*l*e+4*s;n=this._packFloats&&a[t].componentDatatype!==p.UNSIGNED_BYTE?T(this._batchValues,u,z):r.unpack(this._batchValues,u,z);var c=b(a,t);return o(c.fromCartesian4)?c.fromCartesian4(n,i):o(c.clone)?c.clone(n,i):n.x};var G=[void 0,void 0,new e,new t,new r],W=new r;return v.prototype.setBatchedAttribute=function(e,t,i){var n=this._attributes,a=G[n[t].componentsPerAttribute],s=this.getBatchedAttribute(e,t,a),l=b(this._attributes,t);if(!(o(l.equals)?l.equals(s,i):s===i)){var u=W;u.x=o(i.x)?i.x:i,u.y=o(i.y)?i.y:0,u.z=o(i.z)?i.z:0,u.w=o(i.w)?i.w:0;var c=this._offsets[t],d=this._stride,h=4*d*e+4*c;this._packFloats&&n[t].componentDatatype!==p.UNSIGNED_BYTE?A(u,this._batchValues,h):r.pack(u,this._batchValues,h),this._batchValuesDirty=!0}},v.prototype.update=function(e){o(this._texture)&&!this._batchValuesDirty||0===this._attributes.length||(this._batchValuesDirty=!1,o(this._texture)||x(this,e.context),P(this))},v.prototype.getUniformMapCallback=function(){var e=this;return function(t){return 0===e._attributes.length?t:i(t,{batchTexture:function(){return e._texture},batchTextureDimensions:function(){return e._textureDimensions},batchTextureStep:function(){return e._textureStep}})}},v.prototype.getVertexShaderCallback=function(){var e=this._attributes;if(0===e.length)return function(e){return e};var t="uniform sampler2D batchTexture; \n";t+=D(this)+"\n",t+=I(this)+"\n";for(var r=e.length,i=0;i<r;++i)t+=R(this,i);return function(e){var r=e.indexOf("void main"),i=e.substring(0,r),n=e.substring(r);return i+"\n"+t+"\n"+n}},v.prototype.isDestroyed=function(){return!1},v.prototype.destroy=function(){return this._texture=this._texture&&this._texture.destroy(),s(this)},v}}),define("Scene/DepthFunction",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({NEVER:t.NEVER,LESS:t.LESS,EQUAL:t.EQUAL,LESS_OR_EQUAL:t.LEQUAL,GREATER:t.GREATER,NOT_EQUAL:t.NOTEQUAL,GREATER_OR_EQUAL:t.GEQUAL,ALWAYS:t.ALWAYS})}),define("Scene/PrimitivePipeline",["../Core/BoundingSphere","../Core/ComponentDatatype","../Core/defined","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/GeographicProjection","../Core/Geometry","../Core/GeometryAttribute","../Core/GeometryAttributes","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Matrix4","../Core/WebMercatorProjection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,t,i){var n,o=!i,a=e.length;if(!o&&a>1){var s=e[0].modelMatrix;for(n=1;n<a;++n)if(!h.equals(s,e[n].modelMatrix)){o=!0;break}}if(o)for(n=0;n<a;++n)r(e[n].geometry)&&c.transformToWorldCoordinates(e[n]);else h.multiplyTransformation(t,e[0].modelMatrix,t)}function m(e,r){var i=e.attributes,n=i.position,o=n.values.length/n.componentsPerAttribute;i.batchId=new l({componentDatatype:t.FLOAT,componentsPerAttribute:1,values:new Float32Array(o)});for(var a=i.batchId.values,s=0;s<o;++s)a[s]=r}function g(e){for(var t=e.length,i=0;i<t;++i){var n=e[i];r(n.geometry)?m(n.geometry,i):r(n.westHemisphereGeometry)&&r(n.eastHemisphereGeometry)&&(m(n.westHemisphereGeometry,i),m(n.eastHemisphereGeometry,i))}}function _(i){var n,o,a=i.instances,s=i.projection,l=i.elementIndexUintSupported,u=i.scene3DOnly,d=i.vertexCacheOptimize,h=i.compressVertices,p=i.modelMatrix,m=a.length;for(n=0;n<m;++n)if(r(a[n].geometry)){a[n].geometry.primitiveType;break}if(f(a,p,u),!u)for(n=0;n<m;++n)r(a[n].geometry)&&c.splitLongitude(a[n]);if(g(a),d)for(n=0;n<m;++n){var _=a[n];r(_.geometry)?(c.reorderForPostVertexCache(_.geometry),c.reorderForPreVertexCache(_.geometry)):r(_.westHemisphereGeometry)&&r(_.eastHemisphereGeometry)&&(c.reorderForPostVertexCache(_.westHemisphereGeometry),c.reorderForPreVertexCache(_.westHemisphereGeometry),c.reorderForPostVertexCache(_.eastHemisphereGeometry),c.reorderForPreVertexCache(_.eastHemisphereGeometry))}var v=c.combineInstances(a);for(m=v.length,n=0;n<m;++n){o=v[n];var y,b=o.attributes;if(u)for(y in b)b.hasOwnProperty(y)&&b[y].componentDatatype===t.DOUBLE&&c.encodeAttribute(o,y,y+"3DHigh",y+"3DLow");else for(y in b)if(b.hasOwnProperty(y)&&b[y].componentDatatype===t.DOUBLE){var C=y+"3D",S=y+"2D";c.projectTo2D(o,y,C,S,s),r(o.boundingSphere)&&"position"===y&&(o.boundingSphereCV=e.fromVertices(o.attributes.position2D.values)),c.encodeAttribute(o,C,C+"High",C+"Low"),c.encodeAttribute(o,S,S+"High",S+"Low")}h&&c.compressVertices(o)}if(!l){var w=[];for(m=v.length,n=0;n<m;++n)o=v[n],w=w.concat(c.fitToUnsignedShortIndices(o));v=w}return v}function v(e,t,i,n){var o,a,s,l=n.length-1;if(l>=0){var u=n[l];o=u.offset+u.count,s=u.index,a=i[s].indices.length}else o=0,s=0,a=i[s].indices.length;for(var c=e.length,d=0;d<c;++d){var h=e[d],p=h[t];if(r(p)){var f=p.indices.length;o+f>a&&(o=0,a=i[++s].indices.length),n.push({index:s,offset:o,count:f}),o+=f}}}function y(e,t){var r=[];return v(e,"geometry",t,r),v(e,"westHemisphereGeometry",t,r),v(e,"eastHemisphereGeometry",t,r),r}function b(e,t){var i=e.attributes;for(var n in i)if(i.hasOwnProperty(n)){var o=i[n];r(o)&&r(o.values)&&t.push(o.values.buffer)}r(e.indices)&&t.push(e.indices.buffer)}function C(e,t){for(var r=e.length,i=0;i<r;++i)b(e[i],t)}function S(t){for(var i=1,n=t.length,o=0;o<n;o++){var a=t[o];if(++i,r(a)){var s=a.attributes;i+=6+2*e.packedLength+(r(a.indices)?a.indices.length:0);for(var l in s)if(s.hasOwnProperty(l)&&r(s[l])){var u=s[l];i+=5+u.values.length}}}return i}function w(e,t){var r=e.length,i=new Float64Array(1+16*r),n=0;i[n++]=r;for(var o=0;o<r;o++){var a=e[o];h.pack(a.modelMatrix,i,n),n+=h.packedLength}return t.push(i.buffer),i}function T(e){for(var t=e,r=new Array(t[0]),i=0,n=1;n<t.length;){var o=h.unpack(t,n);n+=h.packedLength,r[i++]={modelMatrix:o}}return r}function E(t){var i=t.length,n=1+(e.packedLength+1)*i,o=new Float32Array(n),a=0;o[a++]=i;for(var s=0;s<i;++s){var l=t[s];r(l)?(o[a++]=1,e.pack(t[s],o,a)):o[a++]=0,a+=e.packedLength}return o}function A(t){for(var r=new Array(t[0]),i=0,n=1;n<t.length;)1===t[n++]&&(r[i]=e.unpack(t,n)),++i,n+=e.packedLength;return r}if(!o.supportsTypedArrays())return{};var x={};return x.combineGeometry=function(t){var i,n,o,a=t.instances,s=a.length;s>0&&(i=_(t),i.length>0&&(n=c.createAttributeLocations(i[0]),t.createPickOffsets&&(o=y(a,i))));for(var l=new Array(s),u=new Array(s),d=0;d<s;++d){var h=a[d],p=h.geometry;r(p)&&(l[d]=p.boundingSphere,u[d]=p.boundingSphereCV);var f=h.eastHemisphereGeometry,m=h.westHemisphereGeometry;r(f)&&r(m)&&(r(f.boundingSphere)&&r(m.boundingSphere)&&(l[d]=e.union(f.boundingSphere,m.boundingSphere)),r(f.boundingSphereCV)&&r(m.boundingSphereCV)&&(u[d]=e.union(f.boundingSphereCV,m.boundingSphereCV)))}return{geometries:i,modelMatrix:t.modelMatrix,attributeLocations:n,pickOffsets:o,boundingSpheres:l,boundingSpheresCV:u}},x.packCreateGeometryResults=function(t,i){var n=new Float64Array(S(t)),o=[],a={},s=t.length,l=0;n[l++]=s;for(var u=0;u<s;u++){var c=t[u],d=r(c);if(n[l++]=d?1:0,d){n[l++]=c.primitiveType,n[l++]=c.geometryType;var h=r(c.boundingSphere)?1:0;n[l++]=h,h&&e.pack(c.boundingSphere,n,l),l+=e.packedLength;var p=r(c.boundingSphereCV)?1:0;n[l++]=p,p&&e.pack(c.boundingSphereCV,n,l),l+=e.packedLength;var f=c.attributes,m=[];for(var g in f)f.hasOwnProperty(g)&&r(f[g])&&(m.push(g),r(a[g])||(a[g]=o.length,o.push(g)));n[l++]=m.length;for(var _=0;_<m.length;_++){var v=m[_],y=f[v];n[l++]=a[v],n[l++]=y.componentDatatype,n[l++]=y.componentsPerAttribute,n[l++]=y.normalize?1:0,n[l++]=y.values.length,n.set(y.values,l),l+=y.values.length}var b=r(c.indices)?c.indices.length:0;n[l++]=b,b>0&&(n.set(c.indices,l),l+=b)}}return i.push(n.buffer),{stringTable:o,packedData:n}},x.unpackCreateGeometryResults=function(r){for(var i,n=r.stringTable,o=r.packedData,a=new Array(o[0]),c=0,h=1;h<o.length;){if(1===o[h++]){var p,f,m=o[h++],g=o[h++];1===o[h++]&&(p=e.unpack(o,h)),h+=e.packedLength;1===o[h++]&&(f=e.unpack(o,h)),h+=e.packedLength;var _,v,y,b=new u,C=o[h++];for(i=0;i<C;i++){var S=n[o[h++]],w=o[h++];y=o[h++];var T=0!==o[h++];_=o[h++],v=t.createTypedArray(w,_);for(var E=0;E<_;E++)v[E]=o[h++];b[S]=new l({componentDatatype:w,componentsPerAttribute:y,normalize:T,values:v})}var A;if((_=o[h++])>0){var x=v.length/y;for(A=d.createTypedArray(x,_),i=0;i<_;i++)A[i]=o[h++]}a[c++]=new s({primitiveType:m,geometryType:g,boundingSphere:p,boundingSphereCV:f,indices:A,attributes:b})}else a[c++]=void 0}return a},x.packCombineGeometryParameters=function(e,t){for(var r=e.createGeometryResults,i=r.length,n=0;n<i;n++)t.push(r[n].packedData.buffer);return{createGeometryResults:e.createGeometryResults,packedInstances:w(e.instances,t),ellipsoid:e.ellipsoid,isGeographic:e.projection instanceof a,elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e.createPickOffsets}},x.unpackCombineGeometryParameters=function(e){for(var t=T(e.packedInstances),r=e.createGeometryResults,i=r.length,o=0,s=0;s<i;s++)for(var l=x.unpackCreateGeometryResults(r[s]),u=l.length,c=0;c<u;c++){var d=l[c],f=t[o];f.geometry=d,++o}var m=n.clone(e.ellipsoid);return{instances:t,ellipsoid:m,projection:e.isGeographic?new a(m):new p(m),elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:h.clone(e.modelMatrix),createPickOffsets:e.createPickOffsets}},x.packCombineGeometryResults=function(e,t){r(e.geometries)&&C(e.geometries,t);var i=E(e.boundingSpheres),n=E(e.boundingSpheresCV);return t.push(i.buffer,n.buffer),{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:i,boundingSpheresCV:n}},x.unpackCombineGeometryResults=function(e){return{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:A(e.boundingSpheres),boundingSpheresCV:A(e.boundingSpheresCV)}},x}),define("Scene/PrimitiveState",["../Core/freezeObject"],function(e){"use strict";return e({READY:0,CREATING:1,CREATED:2,COMBINING:3,COMBINED:4,COMPLETE:5,FAILED:6})}),define("Scene/SceneMode",["../Core/freezeObject"],function(e){"use strict";var t={MORPHING:0,COLUMBUS_VIEW:1,SCENE2D:2,SCENE3D:3};return t.getMorphTime=function(e){if(e===t.SCENE3D)return 1;if(e!==t.MORPHING)return 0},e(t)}),define("Scene/ShadowMode",["../Core/freezeObject"],function(e){"use strict";var t={DISABLED:0,ENABLED:1,CAST_ONLY:2,RECEIVE_ONLY:3,NUMBER_OF_SHADOW_MODES:4};return t.castShadows=function(e){return e===t.ENABLED||e===t.CAST_ONLY},t.receiveShadows=function(e){return e===t.ENABLED||e===t.RECEIVE_ONLY},t.fromCastReceive=function(e,r){return e&&r?t.ENABLED:e?t.CAST_ONLY:r?t.RECEIVE_ONLY:t.DISABLED},e(t)}),define("Scene/Primitive",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/clone","../Core/Color","../Core/combine","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EncodedCartesian3","../Core/FeatureDetection","../Core/Geometry","../Core/GeometryAttribute","../Core/GeometryAttributes","../Core/isArray","../Core/Matrix4","../Core/RuntimeError","../Core/subdivideArray","../Core/TaskProcessor","../Renderer/BufferUsage","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../ThirdParty/when","./BatchTable","./CullFace","./DepthFunction","./PrimitivePipeline","./PrimitiveState","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U){"use strict";function V(e){e=u(e,u.EMPTY_OBJECT),this.geometryInstances=e.geometryInstances,this.appearance=e.appearance,this._appearance=void 0,this._material=void 0,this.depthFailAppearance=e.depthFailAppearance,this._depthFailAppearance=void 0,this._depthFailMaterial=void 0,this.modelMatrix=b.clone(u(e.modelMatrix,b.IDENTITY)),this._modelMatrix=new b,this.show=u(e.show,!0),this._vertexCacheOptimize=u(e.vertexCacheOptimize,!1),this._interleave=u(e.interleave,!1),this._releaseGeometryInstances=u(e.releaseGeometryInstances,!0),this._allowPicking=u(e.allowPicking,!0),this._asynchronous=u(e.asynchronous,!0),this._compressVertices=u(e.compressVertices,!0),this.cull=u(e.cull,!0),this.debugShowBoundingVolume=u(e.debugShowBoundingVolume,!1),this.rtcCenter=e.rtcCenter,this.shadows=u(e.shadows,U.DISABLED),this._translucent=void 0,this._state=F.READY,this._geometries=[],this._error=void 0,this._numberOfInstances=0,this._boundingSpheres=[],this._boundingSphereWC=[],this._boundingSphereCV=[],this._boundingSphere2D=[],this._boundingSphereMorph=[],this._perInstanceAttributeCache=[],this._instanceIds=[],this._lastPerInstanceAttributeIndex=0,this._va=[],this._attributeLocations=void 0,this._primitiveType=void 0,this._frontFaceRS=void 0,this._backFaceRS=void 0,this._sp=void 0,this._depthFailAppearance=void 0,this._spDepthFail=void 0,this._frontFaceDepthFailRS=void 0,this._backFaceDepthFailRS=void 0,this._pickRS=void 0,this._pickSP=void 0,this._pickIds=[],this._colorCommands=[],this._pickCommands=[],this._readOnlyInstanceAttributes=e._readOnlyInstanceAttributes,this._createBoundingVolumeFunction=e._createBoundingVolumeFunction,this._createRenderStatesFunction=e._createRenderStatesFunction,this._createShaderProgramFunction=e._createShaderProgramFunction,this._createCommandsFunction=e._createCommandsFunction,this._updateAndQueueCommandsFunction=e._updateAndQueueCommandsFunction,this._createPickOffsets=e._createPickOffsets,this._pickOffsets=void 0,this._createGeometryResults=void 0,this._ready=!1,this._readyPromise=M.defer(),this._batchTable=void 0,this._batchTableAttributeIndices=void 0,this._instanceBoundingSpheres=void 0,this._instanceBoundingSpheresCV=void 0,this._batchTableBoundingSpheresUpdated=!1,this._batchTableBoundingSphereAttributeIndices=void 0}function z(e){var t,r=e.length,i=[],n=e[0].attributes;for(t in n)if(n.hasOwnProperty(t)){for(var o=n[t],a=!0,s=1;s<r;++s){var l=e[s].attributes[t];if(!c(l)||o.componentDatatype!==l.componentDatatype||o.componentsPerAttribute!==l.componentsPerAttribute||o.normalize!==l.normalize){a=!1;break}}a&&i.push(t)}return i}function G(e){var n=e.length;return 1===n?e[0]:2===n?t.unpack(e,0,de):3===n?r.unpack(e,0,he):4===n?i.unpack(e,0,pe):void 0}function W(e,t){var r=e.geometryInstances,i=y(r)?r:[r],n=i.length;if(0!==n){var o,s,d,h=z(i),p=h.length,f=e.allowPicking,m=[],g={},_={},v=i[0],b=v.attributes;for(o=0;o<p;++o)s=h[o],d=b[s],g[s]=o,m.push({functionName:"czm_batchTable_"+s,componentDatatype:d.componentDatatype,componentsPerAttribute:d.componentsPerAttribute,normalize:d.normalize});-1!==h.indexOf("distanceDisplayCondition")&&(m.push({functionName:"czm_batchTable_boundingSphereCenter3DHigh",componentDatatype:l.FLOAT,componentsPerAttribute:3},{functionName:"czm_batchTable_boundingSphereCenter3DLow",componentDatatype:l.FLOAT,componentsPerAttribute:3},{functionName:"czm_batchTable_boundingSphereCenter2DHigh",componentDatatype:l.FLOAT,componentsPerAttribute:3},{functionName:"czm_batchTable_boundingSphereCenter2DLow",componentDatatype:l.FLOAT,componentsPerAttribute:3},{functionName:"czm_batchTable_boundingSphereRadius",componentDatatype:l.FLOAT,componentsPerAttribute:1}),_.center3DHigh=m.length-5,_.center3DLow=m.length-4,_.center2DHigh=m.length-3,_.center2DLow=m.length-2,_.radius=m.length-1),f&&m.push({functionName:"czm_batchTable_pickColor",componentDatatype:l.UNSIGNED_BYTE,componentsPerAttribute:4,normalize:!0});var C=m.length,S=new R(t,m,n);for(o=0;o<n;++o){var w=i[o];b=w.attributes;for(var T=0;T<p;++T){s=h[T],d=b[s];var E=G(d.value),A=g[s];S.setBatchedAttribute(o,A,E)}if(f){var x={primitive:u(w.pickPrimitive,e)};c(w.id)&&(x.id=w.id);var P=t.createPickId(x);e._pickIds.push(P);var D=P.color,I=pe;I.x=a.floatToByte(D.red),I.y=a.floatToByte(D.green),I.z=a.floatToByte(D.blue),I.w=a.floatToByte(D.alpha),S.setBatchedAttribute(o,C-1,I)}}e._batchTable=S,e._batchTableAttributeIndices=g,e._batchTableBoundingSphereAttributeIndices=_}}function H(e){var t;return t=y(e.values)?e.values.slice(0):new e.values.constructor(e.values),new _({componentDatatype:e.componentDatatype,componentsPerAttribute:e.componentsPerAttribute,normalize:e.normalize,values:t})}function j(t){var r=t.attributes,i=new v;for(var n in r)r.hasOwnProperty(n)&&c(r[n])&&(i[n]=H(r[n]));var o;if(c(t.indices)){var a=t.indices;o=y(a)?a.slice(0):new a.constructor(a)}return new g({attributes:i,indices:o,primitiveType:t.primitiveType,boundingSphere:e.clone(t.boundingSphere)})}function q(e,t){return{geometry:t,modelMatrix:b.clone(e.modelMatrix),pickPrimitive:e.pickPrimitive,id:e.id}}function Y(e,t){if(!e.compressVertices)return t;var r=-1!==t.search(/attribute\s+vec3\s+normal;/g),i=-1!==t.search(/attribute\s+vec2\s+st;/g);if(!r&&!i)return t;var n=-1!==t.search(/attribute\s+vec3\s+tangent;/g),o=-1!==t.search(/attribute\s+vec3\s+bitangent;/g),a=i&&r?2:1;a+=n||o?1:0;var s=a>1?"vec"+a:"float",l="compressedAttributes",u="attribute "+s+" "+l+";",c="",d="";if(i){c+="vec2 st;\n";d+=" st = czm_decompressTextureCoordinates("+(a>1?l+".x":l)+");\n"}r&&n&&o?(c+="vec3 normal;\nvec3 tangent;\nvec3 bitangent;\n",d+=" czm_octDecode("+l+"."+(i?"yz":"xy")+", normal, tangent, bitangent);\n"):(r&&(c+="vec3 normal;\n",d+=" normal = czm_octDecode("+l+(a>1?"."+(i?"y":"x"):"")+");\n"),n&&(c+="vec3 tangent;\n",d+=" tangent = czm_octDecode("+l+"."+(i&&r?"z":"y")+");\n"),o&&(c+="vec3 bitangent;\n",d+=" bitangent = czm_octDecode("+l+"."+(i&&r?"z":"y")+");\n"));var h=t;return h=h.replace(/attribute\s+vec3\s+normal;/g,""),h=h.replace(/attribute\s+vec2\s+st;/g,""),h=h.replace(/attribute\s+vec3\s+tangent;/g,""),h=h.replace(/attribute\s+vec3\s+bitangent;/g,""),h=I.replaceMain(h,"czm_non_compressed_main"),[u,c,h,"void main() \n{ \n"+d+" czm_non_compressed_main(); \n}"].join("\n")}function X(e){var t=I.replaceMain(e,"czm_non_depth_clamp_main");return t+="varying float v_WindowZ;\nvoid main() {\n czm_non_depth_clamp_main();\n vec4 position = gl_Position;\n v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n position.z = min(position.z, position.w);\n gl_Position = position;}\n"}function Q(e){var t=I.replaceMain(e,"czm_non_depth_clamp_main");return t+="varying float v_WindowZ;\nvoid main() {\n czm_non_depth_clamp_main();\n#ifdef GL_EXT_frag_depth\n gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n#endif\n}\n",t="#ifdef GL_EXT_frag_depth\n#extension GL_EXT_frag_depth : enable\n#endif\n"+t}function Z(e,t){e.vertexAttributes}function K(e,t){return function(){return e[t]}}function J(e,t){var r,i,n,o,a=e._instanceIds;if(e._state===F.READY){r=y(e.geometryInstances)?e.geometryInstances:[e.geometryInstances];var s=e._numberOfInstances=r.length,l=[],d=[];for(n=0;n<s;++n)i=r[n].geometry,a.push(r[n].id),d.push({moduleName:i._workerName,geometry:i});if(!c(me))for(me=new Array(ge),n=0;n<ge;n++)me[n]=new w("createGeometry",Number.POSITIVE_INFINITY);var h;for(d=S(d,ge),n=0;n<d.length;n++){var p=0,f=d[n],m=f.length;for(o=0;o<m;++o)h=f[o],i=h.geometry,c(i.constructor.pack)&&(h.offset=p,p+=u(i.constructor.packedLength,i.packedLength));var g;if(p>0){var _=new Float64Array(p);for(g=[_.buffer],o=0;o<m;++o)h=f[o],i=h.geometry,c(i.constructor.pack)&&(i.constructor.pack(i,_,h.offset),h.geometry=_)}l.push(me[n].scheduleTask({subTasks:d[n]},g))}e._state=F.CREATING,M.all(l,function(t){e._createGeometryResults=t,e._state=F.CREATED}).otherwise(function(r){ce(e,t,F.FAILED,r)})}else if(e._state===F.CREATED){var v=[];r=y(e.geometryInstances)?e.geometryInstances:[e.geometryInstances];var C=t.scene3DOnly,T=t.mapProjection,E=_e.scheduleTask(k.packCombineGeometryParameters({createGeometryResults:e._createGeometryResults,instances:r,ellipsoid:T.ellipsoid,projection:T,elementIndexUintSupported:t.context.elementIndexUint,scene3DOnly:C,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e._createPickOffsets},v),v);e._createGeometryResults=void 0,e._state=F.COMBINING,M(E,function(r){var i=k.unpackCombineGeometryResults(r);e._geometries=i.geometries,e._attributeLocations=i.attributeLocations,e.modelMatrix=b.clone(i.modelMatrix,e.modelMatrix),e._pickOffsets=i.pickOffsets,e._instanceBoundingSpheres=i.boundingSpheres,e._instanceBoundingSpheresCV=i.boundingSpheresCV,c(e._geometries)&&e._geometries.length>0?e._state=F.COMBINED:ce(e,t,F.FAILED,void 0)}).otherwise(function(r){ce(e,t,F.FAILED,r)})}}function $(e,t){var r,i,n=y(e.geometryInstances)?e.geometryInstances:[e.geometryInstances],o=e._numberOfInstances=n.length,a=new Array(o),s=e._instanceIds,l=0;for(i=0;i<o;i++){r=n[i];var u,d=r.geometry;u=c(d.attributes)&&c(d.primitiveType)?j(d):d.constructor.createGeometry(d),a[l++]=q(r,u),s.push(r.id)}a.length=l;var h=t.scene3DOnly,p=t.mapProjection,f=k.combineGeometry({instances:a,ellipsoid:p.ellipsoid,projection:p,elementIndexUintSupported:t.context.elementIndexUint,scene3DOnly:h,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e._createPickOffsets});e._geometries=f.geometries,e._attributeLocations=f.attributeLocations,e.modelMatrix=b.clone(f.modelMatrix,e.modelMatrix),e._pickOffsets=f.pickOffsets,e._instanceBoundingSpheres=f.boundingSpheres,e._instanceBoundingSpheresCV=f.boundingSpheresCV,c(e._geometries)&&e._geometries.length>0?e._state=F.COMBINED:ce(e,t,F.FAILED,void 0)}function ee(t,r){if(c(t._batchTableAttributeIndices.distanceDisplayCondition)&&!t._batchTableBoundingSpheresUpdated){for(var i=t._batchTableBoundingSphereAttributeIndices,n=i.center3DHigh,o=i.center3DLow,a=i.center2DHigh,s=i.center2DLow,l=i.radius,u=r.mapProjection,d=u.ellipsoid,h=t._batchTable,p=t._instanceBoundingSpheres,m=p.length,g=0;g<m;++g){var _=p[g];if(c(_)){var v=t.modelMatrix;c(v)&&(_=e.transform(_,v,Ce));var y=_.center,b=_.radius,C=f.fromCartesian(y,ve);h.setBatchedAttribute(g,n,C.high),h.setBatchedAttribute(g,o,C.low);var S=d.cartesianToCartographic(y,ye),w=u.project(S,be);C=f.fromCartesian(w,ve),h.setBatchedAttribute(g,a,C.high),h.setBatchedAttribute(g,s,C.low),h.setBatchedAttribute(g,l,b)}}t._batchTableBoundingSpheresUpdated=!0}}function te(t,r){for(var i=t._attributeLocations,n=t._geometries,o=r.scene3DOnly,a=r.context,s=[],l=n.length,u=0;u<l;++u){var d=n[u];if(s.push(O.fromGeometry({context:a,geometry:d,attributeLocations:i,bufferUsage:T.STATIC_DRAW,interleave:t._interleave})),c(t._createBoundingVolumeFunction))t._createBoundingVolumeFunction(r,d);else if(t._boundingSpheres.push(e.clone(d.boundingSphere)),t._boundingSphereWC.push(new e),!o){var h=d.boundingSphereCV.center,p=h.x,f=h.y,m=h.z;h.x=m,h.y=p,h.z=f,t._boundingSphereCV.push(e.clone(d.boundingSphereCV)),t._boundingSphere2D.push(new e),t._boundingSphereMorph.push(new e)}}t._va=s,t._primitiveType=n[0].primitiveType,t.releaseGeometryInstances&&(t.geometryInstances=void 0),t._geometries=void 0,ce(t,r,F.COMPLETE,void 0)}function re(e,t,r,i){var n,a=r.getRenderState();i?(n=o(a,!1),n.cull={enabled:!0,face:L.BACK},e._frontFaceRS=P.fromCache(n),n.cull.face=L.FRONT,e._backFaceRS=P.fromCache(n)):(e._frontFaceRS=P.fromCache(a),e._backFaceRS=e._frontFaceRS),n=o(a,!1),c(e._depthFailAppearance)&&(n.depthTest.enabled=!1),e.allowPicking?i?(n.cull={enabled:!1},e._pickRS=P.fromCache(n)):e._pickRS=P.fromCache(n):(n.colorMask={red:!1,green:!1,blue:!1,alpha:!1},i?(n.cull={enabled:!1},e._pickRS=P.fromCache(n)):e._pickRS=P.fromCache(n)),c(e._depthFailAppearance)&&(a=e._depthFailAppearance.getRenderState(),n=o(a,!1),n.depthTest.func=N.GREATER,i?(n.cull={enabled:!0,face:L.BACK},e._frontFaceDepthFailRS=P.fromCache(n),n.cull.face=L.FRONT,e._backFaceDepthFailRS=P.fromCache(n)):(e._frontFaceDepthFailRS=P.fromCache(n),e._backFaceDepthFailRS=e._frontFaceRS))}function ie(e,t,r){var i=t.context,n=e._attributeLocations,o=e._batchTable.getVertexShaderCallback()(r.vertexShaderSource);o=V._appendShowToShader(e,o),o=V._appendDistanceDisplayConditionToShader(e,o,t.scene3DOnly),o=V._updateColorAttribute(e,o,!1),o=Y(e,o),o=V._modifyShaderPosition(e,o,t.scene3DOnly);var a=r.getFragmentShaderSource();if(e.allowPicking){var s=I.createPickVertexShaderSource(o);s=V._updatePickColorAttribute(s),e._pickSP=D.replaceCache({context:i,shaderProgram:e._pickSP,vertexShaderSource:s,fragmentShaderSource:I.createPickFragmentShaderSource(a,"varying"),attributeLocations:n})}else e._pickSP=D.fromCache({context:i,vertexShaderSource:o,fragmentShaderSource:a,attributeLocations:n});Z(e._pickSP,n),e._sp=D.replaceCache({context:i,shaderProgram:e._sp,vertexShaderSource:o,fragmentShaderSource:a,attributeLocations:n}),Z(e._sp,n),c(e._depthFailAppearance)&&(o=e._batchTable.getVertexShaderCallback()(e._depthFailAppearance.vertexShaderSource),o=V._appendShowToShader(e,o),o=V._appendDistanceDisplayConditionToShader(e,o,t.scene3DOnly),o=V._updateColorAttribute(e,o,!0),o=Y(e,o),o=V._modifyShaderPosition(e,o,t.scene3DOnly),o=X(o),a=Q(e._depthFailAppearance.getFragmentShaderSource()),e._spDepthFail=D.replaceCache({context:i,shaderProgram:e._spDepthFail,vertexShaderSource:o,fragmentShaderSource:a,attributeLocations:n}),Z(e._spDepthFail,n))}function ne(e,t,r,i){var n=c(r)?r._uniforms:void 0,o={},a=t.uniforms;if(c(a))for(var l in a)a.hasOwnProperty(l)&&(o[l]=K(a,l));var u=s(o,n);return u=e._batchTable.getUniformMapCallback()(u),c(e.rtcCenter)&&(u.u_modifiedModelView=function(){var t=i.context.uniformState.view;return b.multiply(t,e._modelMatrix,Se),b.multiplyByPoint(Se,e.rtcCenter,we),b.setTranslation(Se,we,Se),Se}),u}function oe(e,t,r,i,n,o,a,s){var l,u=ne(e,t,r,s);c(e._depthFailAppearance)&&(l=ne(e,e._depthFailAppearance,e._depthFailAppearance.material,s));var d=i?x.TRANSLUCENT:x.OPAQUE,h=n?2:1;h*=c(e._depthFailAppearance)?2:1,o.length=e._va.length*h,a.length=e._va.length;for(var p=o.length,f=0,m=0,g=0;g<p;++g){var _;n&&(_=o[g],c(_)||(_=o[g]=new A({owner:e,primitiveType:e._primitiveType})),_.vertexArray=e._va[m],_.renderState=e._backFaceRS,_.shaderProgram=e._sp,_.uniformMap=u,_.pass=d,++g),_=o[g],c(_)||(_=o[g]=new A({owner:e,primitiveType:e._primitiveType})),_.vertexArray=e._va[m],_.renderState=e._frontFaceRS,_.shaderProgram=e._sp,_.uniformMap=u,_.pass=d,c(e._depthFailAppearance)&&(n&&(++g,_=o[g],c(_)||(_=o[g]=new A({owner:e,primitiveType:e._primitiveType})),_.vertexArray=e._va[m],_.renderState=e._backFaceDepthFailRS,_.shaderProgram=e._spDepthFail,_.uniformMap=l,_.pass=d),++g,_=o[g],c(_)||(_=o[g]=new A({owner:e,primitiveType:e._primitiveType})),_.vertexArray=e._va[m],_.renderState=e._frontFaceDepthFailRS,_.shaderProgram=e._spDepthFail,_.uniformMap=l,_.pass=d);var v=a[f];c(v)||(v=a[f]=new A({owner:e,primitiveType:e._primitiveType})),v.vertexArray=e._va[m],v.renderState=e._pickRS,v.shaderProgram=e._pickSP,v.uniformMap=u,v.pass=d,++f,++m}}function ae(e,t,r,i,n,o,a,s){V._updateBoundingVolumes(e,t,n);var l;t.mode===B.SCENE3D?l=e._boundingSphereWC:t.mode===B.COLUMBUS_VIEW?l=e._boundingSphereCV:t.mode===B.SCENE2D&&c(e._boundingSphere2D)?l=e._boundingSphere2D:c(e._boundingSphereMorph)&&(l=e._boundingSphereMorph);var u=t.commandList,d=t.passes;if(d.render){var h=U.castShadows(e.shadows),p=U.receiveShadows(e.shadows),f=r.length,m=s?2:1;m*=c(e._depthFailAppearance)?2:1;for(var g=0;g<f;++g){var _=Math.floor(g/m),v=r[g];v.modelMatrix=n,v.boundingVolume=l[_],v.cull=o,v.debugShowBoundingVolume=a,v.castShadows=h,v.receiveShadows=p,u.push(v)}}if(d.pick)for(var y=i.length,b=0;b<y;++b){var C=i[b];C.modelMatrix=n,C.boundingVolume=l[b],C.cull=o,u.push(C)}}function se(e,t,r){return function(){var i=e.getBatchedAttribute(t,r),n=e.attributes[r],o=n.componentsPerAttribute,a=l.createTypedArray(n.componentDatatype,o);return c(i.constructor.pack)?i.constructor.pack(i,a,0):a[0]=i,a}}function le(e,t,r){return function(i){var n=G(i);e.setBatchedAttribute(t,r,n)}}function ue(t,r,i){r.boundingSphere={get:function(){var r=t._instanceBoundingSpheres[i],n=t.modelMatrix;return c(n)&&c(r)&&(r=e.transform(r,n)),r}},r.boundingSphereCV={get:function(){return t._instanceBoundingSpheresCV[i]}}}function ce(e,t,r,i){e._error=i,e._state=r,t.afterRender.push(function(){e._ready=e._state===F.COMPLETE||e._state===F.FAILED,c(i)?e._readyPromise.reject(i):e._readyPromise.resolve(e)})}d(V.prototype,{vertexCacheOptimize:{get:function(){return this._vertexCacheOptimize}},interleave:{get:function(){return this._interleave}},releaseGeometryInstances:{get:function(){return this._releaseGeometryInstances}},allowPicking:{get:function(){return this._allowPicking}},asynchronous:{get:function(){return this._asynchronous}},compressVertices:{get:function(){return this._compressVertices}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}}}) +;var de=new t,he=new r,pe=new i,fe=/attribute\s+vec(?:3|4)\s+(.*)3DHigh;/g;V._modifyShaderPosition=function(e,t,r){for(var i,n="",o="",a="";null!==(i=fe.exec(t));){var s=i[1],l="vec4 czm_compute"+s[0].toUpperCase()+s.substr(1)+"()";"vec4 czm_computePosition()"!==l&&(n+=l+";\n"),c(e.rtcCenter)?(t=t.replace(/attribute\s+vec(?:3|4)\s+position3DHigh;/g,""),t=t.replace(/attribute\s+vec(?:3|4)\s+position3DLow;/g,""),n+="uniform mat4 u_modifiedModelView;\n",o+="attribute vec4 position;\n",a+=l+"\n{\n return u_modifiedModelView * position;\n}\n\n",t=t.replace(/czm_modelViewRelativeToEye\s+\*\s+/g,""),t=t.replace(/czm_modelViewProjectionRelativeToEye/g,"czm_projection")):r?a+=l+"\n{\n return czm_translateRelativeToEye("+s+"3DHigh, "+s+"3DLow);\n}\n\n":(o+="attribute vec3 "+s+"2DHigh;\nattribute vec3 "+s+"2DLow;\n",a+=l+"\n{\n vec4 p;\n if (czm_morphTime == 1.0)\n {\n p = czm_translateRelativeToEye("+s+"3DHigh, "+s+"3DLow);\n }\n else if (czm_morphTime == 0.0)\n {\n p = czm_translateRelativeToEye("+s+"2DHigh.zxy, "+s+"2DLow.zxy);\n }\n else\n {\n p = czm_columbusViewMorph(\n czm_translateRelativeToEye("+s+"2DHigh.zxy, "+s+"2DLow.zxy),\n czm_translateRelativeToEye("+s+"3DHigh, "+s+"3DLow),\n czm_morphTime);\n }\n return p;\n}\n\n")}return[n,o,t,a].join("\n")},V._appendShowToShader=function(e,t){if(!c(e._batchTableAttributeIndices.show))return t;return I.replaceMain(t,"czm_non_show_main")+"\nvoid main() \n{ \n czm_non_show_main(); \n gl_Position *= czm_batchTable_show(batchId); \n}"},V._updateColorAttribute=function(e,t,r){if(!c(e._batchTableAttributeIndices.color)&&!c(e._batchTableAttributeIndices.depthFailColor))return t;if(-1===t.search(/attribute\s+vec4\s+color;/g))return t;var i=t;return i=i.replace(/attribute\s+vec4\s+color;/g,""),i=r?i.replace(/(\b)color(\b)/g,"$1czm_batchTable_depthFailColor(batchId)$2"):i.replace(/(\b)color(\b)/g,"$1czm_batchTable_color(batchId)$2")},V._updatePickColorAttribute=function(e){var t=e.replace(/attribute\s+vec4\s+pickColor;/g,"");return t=t.replace(/(\b)pickColor(\b)/g,"$1czm_batchTable_pickColor(batchId)$2")},V._appendDistanceDisplayConditionToShader=function(e,t,r){if(!c(e._batchTableAttributeIndices.distanceDisplayCondition))return t;var i=I.replaceMain(t,"czm_non_distanceDisplayCondition_main"),n="void main() \n{ \n czm_non_distanceDisplayCondition_main(); \n vec2 distanceDisplayCondition = czm_batchTable_distanceDisplayCondition(batchId);\n vec3 boundingSphereCenter3DHigh = czm_batchTable_boundingSphereCenter3DHigh(batchId);\n vec3 boundingSphereCenter3DLow = czm_batchTable_boundingSphereCenter3DLow(batchId);\n vec3 boundingSphereCenter2DHigh = czm_batchTable_boundingSphereCenter2DHigh(batchId);\n vec3 boundingSphereCenter2DLow = czm_batchTable_boundingSphereCenter2DLow(batchId);\n float boundingSphereRadius = czm_batchTable_boundingSphereRadius(batchId);\n";return n+=r?" vec4 centerRTE = czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow);\n":" vec4 centerRTE;\n if (czm_morphTime == 1.0)\n {\n centerRTE = czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow);\n }\n else if (czm_morphTime == 0.0)\n {\n centerRTE = czm_translateRelativeToEye(boundingSphereCenter2DHigh.zxy, boundingSphereCenter2DLow.zxy);\n }\n else\n {\n centerRTE = czm_columbusViewMorph(\n czm_translateRelativeToEye(boundingSphereCenter2DHigh.zxy, boundingSphereCenter2DLow.zxy),\n czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow),\n czm_morphTime);\n }\n",n+=" float radiusSq = boundingSphereRadius * boundingSphereRadius; \n float distanceSq; \n if (czm_sceneMode == czm_sceneMode2D) \n { \n distanceSq = czm_eyeHeight2D.y - radiusSq; \n } \n else \n { \n distanceSq = dot(centerRTE.xyz, centerRTE.xyz) - radiusSq; \n } \n distanceSq = max(distanceSq, 0.0); \n float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x; \n float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y; \n float show = (distanceSq >= nearSq && distanceSq <= farSq) ? 1.0 : 0.0; \n gl_Position *= show; \n}",i+"\n"+n};var me,ge=Math.max(m.hardwareConcurrency-1,1),_e=new w("combineGeometry",Number.POSITIVE_INFINITY),ve=new f,ye=new n,be=new r,Ce=new e,Se=new b,we=new r;return V._updateBoundingVolumes=function(t,r,i){var n,o,a,s=t.appearance.pixelSize;if(c(s))for(o=t._boundingSpheres.length,n=0;n<o;++n){a=t._boundingSpheres[n];var l=t._boundingSphereWC[n],u=r.camera.getPixelSize(a,r.context.drawingBufferWidth,r.context.drawingBufferHeight),d=u*s;l.radius=a.radius+d}if(!b.equals(i,t._modelMatrix))for(b.clone(i,t._modelMatrix),o=t._boundingSpheres.length,n=0;n<o;++n)a=t._boundingSpheres[n],c(a)&&(t._boundingSphereWC[n]=e.transform(a,i,t._boundingSphereWC[n]),r.scene3DOnly||(t._boundingSphere2D[n]=e.clone(t._boundingSphereCV[n],t._boundingSphere2D[n]),t._boundingSphere2D[n].center.x=0,t._boundingSphereMorph[n]=e.union(t._boundingSphereWC[n],t._boundingSphereCV[n])))},V.prototype.update=function(e){if(!(!c(this.geometryInstances)&&0===this._va.length||c(this.geometryInstances)&&y(this.geometryInstances)&&0===this.geometryInstances.length||!c(this.appearance)||e.mode!==B.SCENE3D&&e.scene3DOnly||!e.passes.render&&!e.passes.pick)){if(c(this._error))throw this._error;if(this._state!==F.FAILED){var t=e.context;if(c(this._batchTable)||W(this,t),this._batchTable.attributes.length>0){if(0===E.maximumVertexTextureImageUnits)throw new C("Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero.");this._batchTable.update(e)}if(this._state!==F.COMPLETE&&this._state!==F.COMBINED&&(this.asynchronous?J(this,e):$(this,e)),this._state===F.COMBINED&&(ee(this,e),te(this,e)),this.show&&this._state===F.COMPLETE){var r=this.appearance,i=r.material,n=!1,o=!1;this._appearance!==r?(this._appearance=r,this._material=i,n=!0,o=!0):this._material!==i&&(this._material=i,o=!0);var a=this.depthFailAppearance,s=c(a)?a.material:void 0;this._depthFailAppearance!==a?(this._depthFailAppearance=a,this._depthFailMaterial=s,n=!0,o=!0):this._depthFailMaterial!==s&&(this._depthFailMaterial=s,o=!0);var l=this._appearance.isTranslucent();this._translucent!==l&&(this._translucent=l,n=!0),c(this._material)&&this._material.update(t);var d=r.closed&&l;if(n){u(this._createRenderStatesFunction,re)(this,t,r,d)}if(o){u(this._createShaderProgramFunction,ie)(this,e,r)}if(n||o){u(this._createCommandsFunction,oe)(this,r,i,l,d,this._colorCommands,this._pickCommands,e)}u(this._updateAndQueueCommandsFunction,ae)(this,e,this._colorCommands,this._pickCommands,this.modelMatrix,this.cull,this.debugShowBoundingVolume,d)}}}},V.prototype.getGeometryInstanceAttributes=function(e){for(var t=-1,r=this._lastPerInstanceAttributeIndex,i=this._instanceIds,n=i.length,o=0;o<n;++o){var a=(r+o)%n;if(e===i[a]){t=a;break}}if(-1!==t){var s=this._perInstanceAttributeCache[t];if(c(s))return s;var l=this._batchTable,u=this._batchTableAttributeIndices;s={};var h={};for(var p in u)if(u.hasOwnProperty(p)){var f=u[p];h[p]={get:se(l,t,f)};var m=!0,g=this._readOnlyInstanceAttributes;if(m&&c(g)){n=g.length;for(var _=0;_<n;++_)if(p===g[_]){m=!1;break}}m&&(h[p].set=le(l,t,f))}return ue(this,h,t),d(s,h),this._lastPerInstanceAttributeIndex=t,this._perInstanceAttributeCache[t]=s,s}},V.prototype.isDestroyed=function(){return!1},V.prototype.destroy=function(){var e,t;this._sp=this._sp&&this._sp.destroy(),this._pickSP=this._pickSP&&this._pickSP.destroy();var r=this._va;for(e=r.length,t=0;t<e;++t)r[t].destroy();this._va=void 0;var i=this._pickIds;for(e=i.length,t=0;t<e;++t)i[t].destroy();return this._pickIds=void 0,this._batchTable=this._batchTable&&this._batchTable.destroy(),this._instanceIds=void 0,this._perInstanceAttributeCache=void 0,this._attributeLocations=void 0,h(this)},V}),define("DataSources/ColorMaterialProperty",["../Core/Color","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o){"use strict";function a(e){this._definitionChanged=new i,this._color=void 0,this._colorSubscription=void 0,this.color=e}return r(a.prototype,{isConstant:{get:function(){return o.isConstant(this._color)}},definitionChanged:{get:function(){return this._definitionChanged}},color:n("color")}),a.prototype.getType=function(e){return"Color"},a.prototype.getValue=function(r,i){return t(i)||(i={}),i.color=o.getValueOrClonedDefault(this._color,r,e.WHITE,i.color),i},a.prototype.equals=function(e){return this===e||e instanceof a&&o.equals(this._color,e._color)},a}),define("DataSources/dynamicGeometryGetBoundingSphere",["../Core/BoundingSphere","../Core/defined","../Core/DeveloperError","./BoundingSphereState"],function(e,t,r,i){"use strict";function n(r,n,o,a){var s;return t(n)&&n.show&&n.ready&&(s=n.getGeometryInstanceAttributes(r),t(s)&&t(s.boundingSphere))?(e.clone(s.boundingSphere,a),i.DONE):t(o)&&o.show&&o.ready&&(s=o.getGeometryInstanceAttributes(r),t(s)&&t(s.boundingSphere))?(e.clone(s.boundingSphere,a),i.DONE):t(n)&&!n.ready||t(o)&&!o.ready?i.PENDING:i.FAILED}return n}),define("DataSources/MaterialProperty",["../Core/Color","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Scene/Material"],function(e,t,r,i,n){"use strict";function o(){i.throwInstantiationError()}return r(o.prototype,{isConstant:{get:i.throwInstantiationError},definitionChanged:{get:i.throwInstantiationError}}),o.prototype.getType=i.throwInstantiationError,o.prototype.getValue=i.throwInstantiationError,o.prototype.equals=i.throwInstantiationError,o.getValue=function(r,i,o){var a;return t(i)&&(a=i.getType(r),t(a))?(t(o)&&o.type===a||(o=n.fromType(a)),i.getValue(r,o.uniforms),o):(t(o)&&o.type===n.ColorType||(o=n.fromType(n.ColorType)),e.clone(e.WHITE,o.uniforms.color),o)},o}),define("DataSources/BoxGeometryUpdater",["../Core/BoxGeometry","../Core/BoxOutlineGeometry","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/ShowGeometryInstanceAttribute","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.dimensions=void 0}function E(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(E.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new d,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"box",e.box,void 0)}function A(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(r.WHITE),P=new b(!0),D=new b(!0),I=new b(!1),O=new b(r.BLACK),M=new b(v.DISABLED),R=new b(new u),L=new r;return a(E,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),a(E.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!o(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!o(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!0},geometryChanged:{get:function(){return this._geometryChanged}}}),E.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},E.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},E.prototype.createFillGeometryInstance=function(t){var n,a,s=this._entity,l=s.isAvailable(t),u=new f(l&&s.isShowing&&this._showProperty.getValue(t)&&this._fillProperty.getValue(t)),d=this._distanceDisplayConditionProperty.getValue(t),m=c.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var g=r.WHITE;o(this._materialProperty.color)&&(this._materialProperty.color.isConstant||l)&&(g=this._materialProperty.color.getValue(t)),a=i.fromColor(g),n={show:u,distanceDisplayCondition:m,color:a}}else n={show:u,distanceDisplayCondition:m};return new h({id:s,geometry:e.fromDimensions(this._options),modelMatrix:s.computeModelMatrix(p.MINIMUM_VALUE),attributes:n})},E.prototype.createOutlineGeometryInstance=function(e){var n=this._entity,o=n.isAvailable(e),a=w.getValueOrDefault(this._outlineColorProperty,e,r.BLACK),s=this._distanceDisplayConditionProperty.getValue(e);return new h({id:n,geometry:t.fromDimensions(this._options),modelMatrix:n.computeModelMatrix(p.MINIMUM_VALUE),attributes:{show:new f(o&&n.isShowing&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)),color:i.fromColor(a),distanceDisplayCondition:c.fromDistanceDisplayCondition(s)}})},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){this._entitySubscription(),s(this)},E.prototype._onEntityPropertyChanged=function(e,t,r,i){if("availability"===t||"position"===t||"orientation"===t||"box"===t){var a=this._entity.box;if(!o(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!o(s)||!s.isConstant||s.getValue(p.MINIMUM_VALUE),u=a.outline,c=o(u);if(c&&u.isConstant&&(c=u.getValue(p.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=a.dimensions,h=e.position,f=a.show;if(!o(d)||!o(h)||o(f)&&f.isConstant&&!f.getValue(p.MINIMUM_VALUE))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var _=n(a.material,x),v=_ instanceof y;this._materialProperty=_,this._fillProperty=n(s,D),this._showProperty=n(f,P),this._showOutlineProperty=n(a.outline,I),this._outlineColorProperty=c?n(a.outlineColor,O):void 0,this._shadowsProperty=n(a.shadows,M),this._distanceDisplayConditionProperty=n(a.distanceDisplayCondition,R);var b=a.outlineWidth;if(this._fillEnabled=l,this._outlineEnabled=c,h.isConstant&&w.isConstant(e.orientation)&&d.isConstant&&w.isConstant(b)){var C=this._options;C.vertexFormat=v?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,C.dimensions=d.getValue(p.MINIMUM_VALUE,C.dimensions),this._outlineWidth=o(b)?b.getValue(p.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},E.prototype.createDynamicUpdater=function(e){return new A(e,this)},A.prototype.update=function(n){var a=this._primitives;a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var s=this._geometryUpdater,l=s._entity,u=l.box;if(l.isShowing&&l.isAvailable(n)&&w.getValueOrDefault(u.show,n,!0)){var d=this._options,p=l.computeModelMatrix(n),f=w.getValueOrUndefined(u.dimensions,n,d.dimensions);if(o(p)&&o(f)){d.dimensions=f;var v=this._geometryUpdater.shadowsProperty.getValue(n),y=this._geometryUpdater.distanceDisplayConditionProperty,b=y.getValue(n),C=c.fromDistanceDisplayCondition(b);if(w.getValueOrDefault(u.fill,n,!0)){var T=S.getValue(n,s.fillMaterialProperty,this._material);this._material=T;var E=new m({material:T,translucent:T.isTranslucent(),closed:!0});d.vertexFormat=E.vertexFormat,this._primitive=a.add(new _({geometryInstances:new h({id:l,geometry:e.fromDimensions(d),modelMatrix:p,attributes:{distanceDisplayCondition:C}}),appearance:E,asynchronous:!1,shadows:v}))}if(w.getValueOrDefault(u.outline,n,!1)){d.vertexFormat=g.VERTEX_FORMAT;var A=w.getValueOrClonedDefault(u.outlineColor,n,r.BLACK,L),x=w.getValueOrDefault(u.outlineWidth,n,1),P=1!==A.alpha;this._outlinePrimitive=a.add(new _({geometryInstances:new h({id:l,geometry:t.fromDimensions(d),modelMatrix:p,attributes:{color:i.fromColor(A),distanceDisplayCondition:C}}),appearance:new g({flat:!0,translucent:P,renderState:{lineWidth:s._scene.clampLineWidth(x)}}),asynchronous:!1,shadows:v}))}}}},A.prototype.getBoundingSphere=function(e,t){return C(e,this._primitive,this._outlinePrimitive,t)},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),s(this)},E}),define("DataSources/ImageMaterialProperty",["../Core/Cartesian2","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT),this._definitionChanged=new o,this._image=void 0,this._imageSubscription=void 0,this._repeat=void 0,this._repeatSubscription=void 0,this._color=void 0,this._colorSubscription=void 0,this._transparent=void 0,this._transparentSubscription=void 0,this.image=e.image,this.repeat=e.repeat,this.color=e.color,this.transparent=e.transparent}var u=new e(1,1),c=t.WHITE;return n(l.prototype,{isConstant:{get:function(){return s.isConstant(this._image)&&s.isConstant(this._repeat)}},definitionChanged:{get:function(){return this._definitionChanged}},image:a("image"),repeat:a("repeat"),color:a("color"),transparent:a("transparent")}),l.prototype.getType=function(e){return"Image"},l.prototype.getValue=function(e,t){return i(t)||(t={}),t.image=s.getValueOrUndefined(this._image,e),t.repeat=s.getValueOrClonedDefault(this._repeat,e,u,t.repeat),t.color=s.getValueOrClonedDefault(this._color,e,c,t.color),s.getValueOrDefault(this._transparent,e,!1)&&(t.color.alpha=Math.min(.99,t.color.alpha)),t},l.prototype.equals=function(e){return this===e||e instanceof l&&s.equals(this._image,e._image)&&s.equals(this._color,e._color)&&s.equals(this._transparent,e._transparent)&&s.equals(this._repeat,e._repeat)},l}),define("DataSources/createMaterialPropertyDescriptor",["../Core/Color","../Core/DeveloperError","../Core/Resource","./ColorMaterialProperty","./createPropertyDescriptor","./ImageMaterialProperty"],function(e,t,r,i,n,o){"use strict";function a(t){if(t instanceof e)return new i(t);if("string"==typeof t||t instanceof r||t instanceof HTMLCanvasElement||t instanceof HTMLVideoElement){var n=new o;return n.image=t,n}}function s(e,t){return n(e,t,a)}return s}),define("DataSources/BoxGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._dimensions=void 0,this._dimensionsSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),dimensions:a("dimensions"),material:o("material"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.dimensions=this.dimensions,e.show=this.show,e.material=this.material,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.dimensions=e(this.dimensions,t.dimensions),this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/CallbackProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event"],function(e,t,r,i){"use strict";function n(e,t){this._callback=void 0,this._isConstant=void 0,this._definitionChanged=new i,this.setCallback(e,t)}return t(n.prototype,{isConstant:{get:function(){return this._isConstant}},definitionChanged:{get:function(){return this._definitionChanged}}}),n.prototype.getValue=function(e,t){return this._callback(e,t)},n.prototype.setCallback=function(e,t){var r=this._callback!==e||this._isConstant!==t;this._callback=e,this._isConstant=t,r&&this._definitionChanged.raiseEvent(this)},n.prototype.equals=function(e){return this===e||e instanceof n&&this._callback===e._callback&&this._isConstant===e._isConstant},n}),define("DataSources/CheckerboardMaterialProperty",["../Core/Cartesian2","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT),this._definitionChanged=new o,this._evenColor=void 0,this._evenColorSubscription=void 0,this._oddColor=void 0,this._oddColorSubscription=void 0,this._repeat=void 0,this._repeatSubscription=void 0,this.evenColor=e.evenColor,this.oddColor=e.oddColor,this.repeat=e.repeat}var u=t.WHITE,c=t.BLACK,d=new e(2,2);return n(l.prototype,{isConstant:{get:function(){return s.isConstant(this._evenColor)&&s.isConstant(this._oddColor)&&s.isConstant(this._repeat)}},definitionChanged:{get:function(){return this._definitionChanged}},evenColor:a("evenColor"),oddColor:a("oddColor"),repeat:a("repeat")}),l.prototype.getType=function(e){return"Checkerboard"},l.prototype.getValue=function(e,t){return i(t)||(t={}),t.lightColor=s.getValueOrClonedDefault(this._evenColor,e,u,t.lightColor),t.darkColor=s.getValueOrClonedDefault(this._oddColor,e,c,t.darkColor),t.repeat=s.getValueOrDefault(this._repeat,e,d),t},l.prototype.equals=function(e){return this===e||e instanceof l&&s.equals(this._evenColor,e._evenColor)&&s.equals(this._oddColor,e._oddColor)&&s.equals(this._repeat,e._repeat)},l}),define("DataSources/PositionProperty",["../Core/Cartesian3","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Matrix3","../Core/ReferenceFrame","../Core/Transforms"],function(e,t,r,i,n,o,a){"use strict";function s(){i.throwInstantiationError()}r(s.prototype,{isConstant:{get:i.throwInstantiationError},definitionChanged:{get:i.throwInstantiationError},referenceFrame:{get:i.throwInstantiationError}}),s.prototype.getValue=i.throwInstantiationError,s.prototype.getValueInReferenceFrame=i.throwInstantiationError,s.prototype.equals=i.throwInstantiationError;var l=new n;return s.convertToReferenceFrame=function(r,i,s,u,c){if(!t(i))return i;if(t(c)||(c=new e),s===u)return e.clone(i,c);var d=a.computeIcrfToFixedMatrix(r,l);return t(d)||(d=a.computeTemeToPseudoFixedMatrix(r,l)),s===o.INERTIAL?n.multiplyByVector(d,i,c):s===o.FIXED?n.multiplyByVector(n.transpose(d,l),i,c):void 0},s}),define("DataSources/ConstantPositionProperty",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/ReferenceFrame","./PositionProperty"],function(e,t,r,i,n,o,a,s){"use strict";function l(r,i){this._definitionChanged=new o,this._value=e.clone(r),this._referenceFrame=t(i,a.FIXED)}return i(l.prototype,{isConstant:{get:function(){return!r(this._value)||this._referenceFrame===a.FIXED}},definitionChanged:{get:function(){return this._definitionChanged}},referenceFrame:{get:function(){return this._referenceFrame}}}),l.prototype.getValue=function(e,t){return this.getValueInReferenceFrame(e,a.FIXED,t)},l.prototype.setValue=function(t,i){var n=!1;e.equals(this._value,t)||(n=!0,this._value=e.clone(t)),r(i)&&this._referenceFrame!==i&&(n=!0,this._referenceFrame=i),n&&this._definitionChanged.raiseEvent(this)},l.prototype.getValueInReferenceFrame=function(e,t,r){return s.convertToReferenceFrame(e,this._value,this._referenceFrame,t,r)},l.prototype.equals=function(t){return this===t||t instanceof l&&e.equals(this._value,t._value)&&this._referenceFrame===t._referenceFrame},l}),define("DataSources/CorridorGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._positions=void 0,this._positionsSubscription=void 0,this._height=void 0,this._heightSubscription=void 0,this._extrudedHeight=void 0,this._extrudedHeightSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._width=void 0,this._widthSubscription=void 0,this._cornerType=void 0,this._cornerTypeSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),material:o("material"),positions:a("positions"),height:a("height"),extrudedHeight:a("extrudedHeight"),granularity:a("granularity"),width:a("width"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),cornerType:a("cornerType"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.material=this.material,e.positions=this.positions,e.height=this.height,e.extrudedHeight=this.extrudedHeight,e.granularity=this.granularity,e.width=this.width,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.cornerType=this.cornerType,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.positions=e(this.positions,t.positions),this.height=e(this.height,t.height),this.extrudedHeight=e(this.extrudedHeight,t.extrudedHeight),this.granularity=e(this.granularity,t.granularity),this.width=e(this.width,t.width),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.cornerType=e(this.cornerType,t.cornerType),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/createRawPropertyDescriptor",["./createPropertyDescriptor"],function(e){"use strict";function t(e){return e}function r(r,i){return e(r,i,t)}return r}),define("DataSources/CylinderGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._length=void 0,this._lengthSubscription=void 0,this._topRadius=void 0,this._topRadiusSubscription=void 0,this._bottomRadius=void 0,this._bottomRadiusSubscription=void 0,this._numberOfVerticalLines=void 0,this._numberOfVerticalLinesSubscription=void 0,this._slices=void 0,this._slicesSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},length:a("length"),topRadius:a("topRadius"),bottomRadius:a("bottomRadius"),numberOfVerticalLines:a("numberOfVerticalLines"),slices:a("slices"),show:a("show"),material:o("material"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.bottomRadius=this.bottomRadius,e.length=this.length,e.topRadius=this.topRadius,e.show=this.show,e.material=this.material,e.numberOfVerticalLines=this.numberOfVerticalLines,e.slices=this.slices,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.bottomRadius=e(this.bottomRadius,t.bottomRadius),this.length=e(this.length,t.length),this.topRadius=e(this.topRadius,t.topRadius),this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.numberOfVerticalLines=e(this.numberOfVerticalLines,t.numberOfVerticalLines),this.slices=e(this.slices,t.slices),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/EllipseGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._semiMajorAxis=void 0,this._semiMajorAxisSubscription=void 0,this._semiMinorAxis=void 0, +this._semiMinorAxisSubscription=void 0,this._rotation=void 0,this._rotationSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._height=void 0,this._heightSubscription=void 0,this._extrudedHeight=void 0,this._extrudedHeightSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._stRotation=void 0,this._stRotationSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._numberOfVerticalLines=void 0,this._numberOfVerticalLinesSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},semiMajorAxis:a("semiMajorAxis"),semiMinorAxis:a("semiMinorAxis"),rotation:a("rotation"),show:a("show"),material:o("material"),height:a("height"),extrudedHeight:a("extrudedHeight"),granularity:a("granularity"),stRotation:a("stRotation"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),numberOfVerticalLines:a("numberOfVerticalLines"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.rotation=this.rotation,e.semiMajorAxis=this.semiMajorAxis,e.semiMinorAxis=this.semiMinorAxis,e.show=this.show,e.material=this.material,e.height=this.height,e.extrudedHeight=this.extrudedHeight,e.granularity=this.granularity,e.stRotation=this.stRotation,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.numberOfVerticalLines=this.numberOfVerticalLines,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.rotation=e(this.rotation,t.rotation),this.semiMajorAxis=e(this.semiMajorAxis,t.semiMajorAxis),this.semiMinorAxis=e(this.semiMinorAxis,t.semiMinorAxis),this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.height=e(this.height,t.height),this.extrudedHeight=e(this.extrudedHeight,t.extrudedHeight),this.granularity=e(this.granularity,t.granularity),this.stRotation=e(this.stRotation,t.stRotation),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.numberOfVerticalLines=e(this.numberOfVerticalLines,t.numberOfVerticalLines),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/EllipsoidGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._radii=void 0,this._radiiSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._stackPartitions=void 0,this._stackPartitionsSubscription=void 0,this._slicePartitions=void 0,this._slicePartitionsSubscription=void 0,this._subdivisions=void 0,this._subdivisionsSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),radii:a("radii"),material:o("material"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),stackPartitions:a("stackPartitions"),slicePartitions:a("slicePartitions"),subdivisions:a("subdivisions"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.radii=this.radii,e.material=this.material,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.stackPartitions=this.stackPartitions,e.slicePartitions=this.slicePartitions,e.subdivisions=this.subdivisions,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.radii=e(this.radii,t.radii),this.material=e(this.material,t.material),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.stackPartitions=e(this.stackPartitions,t.stackPartitions),this.slicePartitions=e(this.slicePartitions,t.slicePartitions),this.subdivisions=e(this.subdivisions,t.subdivisions),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/LabelGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createPropertyDescriptor"],function(e,t,r,i,n,o){"use strict";function a(t){this._text=void 0,this._textSubscription=void 0,this._font=void 0,this._fontSubscription=void 0,this._style=void 0,this._styleSubscription=void 0,this._fillColor=void 0,this._fillColorSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._horizontalOrigin=void 0,this._horizontalOriginSubscription=void 0,this._verticalOrigin=void 0,this._verticalOriginSubscription=void 0,this._eyeOffset=void 0,this._eyeOffsetSubscription=void 0,this._heightReference=void 0,this._heightReferenceSubscription=void 0,this._pixelOffset=void 0,this._pixelOffsetSubscription=void 0,this._scale=void 0,this._scaleSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._showBackground=void 0,this._showBackgroundSubscription=void 0,this._backgroundColor=void 0,this._backgroundColorSubscription=void 0,this._backgroundPadding=void 0,this._backgroundPaddingSubscription=void 0,this._translucencyByDistance=void 0,this._translucencyByDistanceSubscription=void 0,this._pixelOffsetScaleByDistance=void 0,this._pixelOffsetScaleByDistanceSubscription=void 0,this._scaleByDistance=void 0,this._scaleByDistanceSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._disableDepthTestDistance=void 0,this._disableDepthTestDistanceSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(a.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},text:o("text"),font:o("font"),style:o("style"),fillColor:o("fillColor"),outlineColor:o("outlineColor"),outlineWidth:o("outlineWidth"),horizontalOrigin:o("horizontalOrigin"),verticalOrigin:o("verticalOrigin"),eyeOffset:o("eyeOffset"),heightReference:o("heightReference"),pixelOffset:o("pixelOffset"),scale:o("scale"),show:o("show"),showBackground:o("showBackground"),backgroundColor:o("backgroundColor"),backgroundPadding:o("backgroundPadding"),translucencyByDistance:o("translucencyByDistance"),pixelOffsetScaleByDistance:o("pixelOffsetScaleByDistance"),scaleByDistance:o("scaleByDistance"),distanceDisplayCondition:o("distanceDisplayCondition"),disableDepthTestDistance:o("disableDepthTestDistance")}),a.prototype.clone=function(e){return t(e)?(e.text=this.text,e.font=this.font,e.show=this.show,e.style=this.style,e.fillColor=this.fillColor,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.showBackground=this.showBackground,e.backgroundColor=this.backgroundColor,e.backgroundPadding=this.backgroundPadding,e.scale=this.scale,e.horizontalOrigin=this.horizontalOrigin,e.verticalOrigin=this.verticalOrigin,e.eyeOffset=this.eyeOffset,e.heightReference=this.heightReference,e.pixelOffset=this.pixelOffset,e.translucencyByDistance=this.translucencyByDistance,e.pixelOffsetScaleByDistance=this.pixelOffsetScaleByDistance,e.scaleByDistance=this.scaleByDistance,e.distanceDisplayCondition=this.distanceDisplayCondition,e.disableDepthTestDistance=this.disableDepthTestDistance,e):new a(this)},a.prototype.merge=function(t){this.text=e(this.text,t.text),this.font=e(this.font,t.font),this.show=e(this.show,t.show),this.style=e(this.style,t.style),this.fillColor=e(this.fillColor,t.fillColor),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.showBackground=e(this.showBackground,t.showBackground),this.backgroundColor=e(this.backgroundColor,t.backgroundColor),this.backgroundPadding=e(this.backgroundPadding,t.backgroundPadding),this.scale=e(this.scale,t.scale),this.horizontalOrigin=e(this.horizontalOrigin,t.horizontalOrigin),this.verticalOrigin=e(this.verticalOrigin,t.verticalOrigin),this.eyeOffset=e(this.eyeOffset,t.eyeOffset),this.heightReference=e(this.heightReference,t.heightReference),this.pixelOffset=e(this.pixelOffset,t.pixelOffset),this.translucencyByDistance=e(this.translucencyByDistance,t.translucencyByDistance),this.pixelOffsetScaleByDistance=e(this.pixelOffsetScaleByDistance,t.pixelOffsetScaleByDistance),this.scaleByDistance=e(this.scaleByDistance,t.scaleByDistance),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition),this.disableDepthTestDistance=e(this.disableDepthTestDistance,t.disableDepthTestDistance)},a}),define("DataSources/NodeTransformationProperty",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","../Core/TranslationRotationScale","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";var s=new n,l=function(t){t=e(t,e.EMPTY_OBJECT),this._definitionChanged=new i,this._translation=void 0,this._translationSubscription=void 0,this._rotation=void 0,this._rotationSubscription=void 0,this._scale=void 0,this._scaleSubscription=void 0,this.translation=t.translation,this.rotation=t.rotation,this.scale=t.scale};return r(l.prototype,{isConstant:{get:function(){return a.isConstant(this._translation)&&a.isConstant(this._rotation)&&a.isConstant(this._scale)}},definitionChanged:{get:function(){return this._definitionChanged}},translation:o("translation"),rotation:o("rotation"),scale:o("scale")}),l.prototype.getValue=function(e,r){return t(r)||(r=new n),r.translation=a.getValueOrClonedDefault(this._translation,e,s.translation,r.translation),r.rotation=a.getValueOrClonedDefault(this._rotation,e,s.rotation,r.rotation),r.scale=a.getValueOrClonedDefault(this._scale,e,s.scale,r.scale),r},l.prototype.equals=function(e){return this===e||e instanceof l&&a.equals(this._translation,e._translation)&&a.equals(this._rotation,e._rotation)&&a.equals(this._scale,e._scale)},l}),define("DataSources/PropertyBag",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./ConstantProperty","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){return new o(e)}function u(e,t){var r=e._propertyNames,i=t._propertyNames,n=r.length;if(n!==i.length)return!1;for(var o=0;o<n;++o){var a=r[o];if(-1===i.indexOf(a))return!1;if(!s.equals(e[a],t[a]))return!1}return!0}var c=function(e,r){this._propertyNames=[],this._definitionChanged=new n,t(e)&&this.merge(e,r)};return r(c.prototype,{propertyNames:{get:function(){return this._propertyNames}},isConstant:{get:function(){for(var e=this._propertyNames,t=0,r=e.length;t<r;t++)if(!s.isConstant(this[e[t]]))return!1;return!0}},definitionChanged:{get:function(){return this._definitionChanged}}}),c.prototype.hasProperty=function(e){return-1!==this._propertyNames.indexOf(e)},c.prototype.addProperty=function(r,i,n){this._propertyNames.push(r),Object.defineProperty(this,r,a(r,!0,e(n,l))),t(i)&&(this[r]=i),this._definitionChanged.raiseEvent(this)},c.prototype.removeProperty=function(e){var t=this._propertyNames,r=t.indexOf(e);this._propertyNames.splice(r,1),delete this[e],this._definitionChanged.raiseEvent(this)},c.prototype.getValue=function(e,r){t(r)||(r={});for(var i=this._propertyNames,n=0,o=i.length;n<o;n++){var a=i[n];r[a]=s.getValueOrUndefined(this[a],e,r[a])}return r},c.prototype.merge=function(e,r){for(var i=this._propertyNames,n=t(e._propertyNames)?e._propertyNames:Object.keys(e),o=0,a=n.length;o<a;o++){var s=n[o],l=this[s],u=e[s];void 0===l&&-1===i.indexOf(s)&&this.addProperty(s,void 0,r),void 0!==u&&(void 0!==l?t(l)&&t(l.merge)&&l.merge(u):t(u)&&t(u.merge)&&t(u.clone)?this[s]=u.clone():this[s]=u)}},c.prototype.equals=function(e){return this===e||e instanceof c&&u(this,e)},c}),define("DataSources/ModelGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createPropertyDescriptor","./NodeTransformationProperty","./PropertyBag"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){return new a(e)}function u(e){return new s(e,l)}function c(t){this._show=void 0,this._showSubscription=void 0,this._scale=void 0,this._scaleSubscription=void 0,this._minimumPixelSize=void 0,this._minimumPixelSizeSubscription=void 0,this._maximumScale=void 0,this._maximumScaleSubscription=void 0,this._incrementallyLoadTextures=void 0,this._incrementallyLoadTexturesSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._uri=void 0,this._uriSubscription=void 0,this._runAnimations=void 0,this._clampAnimations=void 0,this._runAnimationsSubscription=void 0,this._nodeTransformations=void 0,this._nodeTransformationsSubscription=void 0,this._heightReference=void 0,this._heightReferenceSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._silhouetteColor=void 0,this._silhouetteColorSubscription=void 0,this._silhouetteSize=void 0,this._silhouetteSizeSubscription=void 0,this._color=void 0,this._colorSubscription=void 0,this._colorBlendMode=void 0,this._colorBlendModeSubscription=void 0,this._colorBlendAmount=void 0,this._colorBlendAmountSubscription=void 0,this._clippingPlanes=void 0,this._clippingPlanesSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(c.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:o("show"),scale:o("scale"),minimumPixelSize:o("minimumPixelSize"),maximumScale:o("maximumScale"),incrementallyLoadTextures:o("incrementallyLoadTextures"),shadows:o("shadows"),uri:o("uri"),runAnimations:o("runAnimations"),clampAnimations:o("clampAnimations"),nodeTransformations:o("nodeTransformations",void 0,u),heightReference:o("heightReference"),distanceDisplayCondition:o("distanceDisplayCondition"),silhouetteColor:o("silhouetteColor"),silhouetteSize:o("silhouetteSize"),color:o("color"),colorBlendMode:o("colorBlendMode"),colorBlendAmount:o("colorBlendAmount"),clippingPlanes:o("clippingPlanes")}),c.prototype.clone=function(e){return t(e)?(e.show=this.show,e.scale=this.scale,e.minimumPixelSize=this.minimumPixelSize,e.maximumScale=this.maximumScale,e.incrementallyLoadTextures=this.incrementallyLoadTextures,e.shadows=this.shadows,e.uri=this.uri,e.runAnimations=this.runAnimations,e.clampAnimations=this.clampAnimations,e.nodeTransformations=this.nodeTransformations,e.heightReference=this._heightReference,e.distanceDisplayCondition=this.distanceDisplayCondition,e.silhouetteColor=this.silhouetteColor,e.silhouetteSize=this.silhouetteSize,e.color=this.color,e.colorBlendMode=this.colorBlendMode,e.colorBlendAmount=this.colorBlendAmount,e.clippingPlanes=this.clippingPlanes,e):new c(this)},c.prototype.merge=function(r){this.show=e(this.show,r.show),this.scale=e(this.scale,r.scale),this.minimumPixelSize=e(this.minimumPixelSize,r.minimumPixelSize),this.maximumScale=e(this.maximumScale,r.maximumScale),this.incrementallyLoadTextures=e(this.incrementallyLoadTextures,r.incrementallyLoadTextures),this.shadows=e(this.shadows,r.shadows),this.uri=e(this.uri,r.uri),this.runAnimations=e(this.runAnimations,r.runAnimations),this.clampAnimations=e(this.clampAnimations,r.clampAnimations),this.heightReference=e(this.heightReference,r.heightReference),this.distanceDisplayCondition=e(this.distanceDisplayCondition,r.distanceDisplayCondition),this.silhouetteColor=e(this.silhouetteColor,r.silhouetteColor),this.silhouetteSize=e(this.silhouetteSize,r.silhouetteSize),this.color=e(this.color,r.color),this.colorBlendMode=e(this.colorBlendMode,r.colorBlendMode),this.colorBlendAmount=e(this.colorBlendAmount,r.colorBlendAmount),this.clippingPlanes=e(this.clippingPlanes,r.clippingPlanes);var i=r.nodeTransformations;if(t(i)){var n=this.nodeTransformations;t(n)?n.merge(i):this.nodeTransformations=new s(i,l)}},c}),define("DataSources/PathGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._material=void 0,this._materialSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._width=void 0,this._widthSubscription=void 0,this._resolution=void 0,this._resolutionSubscription=void 0,this._leadTime=void 0,this._leadTimeSubscription=void 0,this._trailTime=void 0,this._trailTimeSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),material:o("material"),width:a("width"),resolution:a("resolution"),leadTime:a("leadTime"),trailTime:a("trailTime"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.material=this.material,e.width=this.width,e.resolution=this.resolution,e.show=this.show,e.leadTime=this.leadTime,e.trailTime=this.trailTime,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.material=e(this.material,t.material),this.width=e(this.width,t.width),this.resolution=e(this.resolution,t.resolution),this.show=e(this.show,t.show),this.leadTime=e(this.leadTime,t.leadTime),this.trailTime=e(this.trailTime,t.trailTime),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/PlaneGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._plane=void 0,this._planeSubscription=void 0,this._dimensions=void 0,this._dimensionsSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),plane:a("plane"),dimensions:a("dimensions"),material:o("material"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.plane=this.plane,e.dimensions=this.dimensions,e.show=this.show,e.material=this.material,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.plane=e(this.plane,t.plane),this.dimensions=e(this.dimensions,t.dimensions),this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/PointGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createPropertyDescriptor"],function(e,t,r,i,n,o){"use strict";function a(t){this._color=void 0,this._colorSubscription=void 0,this._pixelSize=void 0,this._pixelSizeSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._show=void 0,this._showSubscription=void 0,this._scaleByDistance=void 0,this._scaleByDistanceSubscription=void 0,this._translucencyByDistance=void 0,this._translucencyByDistanceSubscription=void 0,this._heightReference=void 0,this._heightReferenceSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._disableDepthTestDistance=void 0,this._disableDepthTestDistanceSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(a.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),pixelSize:o("pixelSize"),outlineColor:o("outlineColor"),outlineWidth:o("outlineWidth"),show:o("show"),scaleByDistance:o("scaleByDistance"),translucencyByDistance:o("translucencyByDistance"),heightReference:o("heightReference"),distanceDisplayCondition:o("distanceDisplayCondition"),disableDepthTestDistance:o("disableDepthTestDistance")}),a.prototype.clone=function(e){return t(e)?(e.color=this.color,e.pixelSize=this.pixelSize,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.show=this.show,e.scaleByDistance=this.scaleByDistance,e.translucencyByDistance=this._translucencyByDistance,e.heightReference=this.heightReference,e.distanceDisplayCondition=this.distanceDisplayCondition,e.disableDepthTestDistance=this.disableDepthTestDistance,e):new a(this)},a.prototype.merge=function(t){this.color=e(this.color,t.color),this.pixelSize=e(this.pixelSize,t.pixelSize),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.show=e(this.show,t.show),this.scaleByDistance=e(this.scaleByDistance,t.scaleByDistance),this.translucencyByDistance=e(this._translucencyByDistance,t.translucencyByDistance),this.heightReference=e(this.heightReference,t.heightReference),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition),this.disableDepthTestDistance=e(this.disableDepthTestDistance,t.disableDepthTestDistance)},a}),define("DataSources/PolygonGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._hierarchy=void 0,this._hierarchySubscription=void 0,this._height=void 0,this._heightSubscription=void 0,this._extrudedHeight=void 0,this._extrudedHeightSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._stRotation=void 0,this._stRotationSubscription=void 0,this._perPositionHeight=void 0,this._perPositionHeightSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._definitionChanged=new n,this._closeTop=void 0,this._closeTopSubscription=void 0,this._closeBottom=void 0,this._closeBottomSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),material:o("material"),hierarchy:a("hierarchy"),height:a("height"),extrudedHeight:a("extrudedHeight"),granularity:a("granularity"),stRotation:a("stRotation"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),perPositionHeight:a("perPositionHeight"),closeTop:a("closeTop"),closeBottom:a("closeBottom"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.material=this.material,e.hierarchy=this.hierarchy,e.height=this.height,e.extrudedHeight=this.extrudedHeight,e.granularity=this.granularity,e.stRotation=this.stRotation,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.perPositionHeight=this.perPositionHeight,e.closeTop=this.closeTop,e.closeBottom=this.closeBottom,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.hierarchy=e(this.hierarchy,t.hierarchy),this.height=e(this.height,t.height),this.extrudedHeight=e(this.extrudedHeight,t.extrudedHeight),this.granularity=e(this.granularity,t.granularity),this.stRotation=e(this.stRotation,t.stRotation),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.perPositionHeight=e(this.perPositionHeight,t.perPositionHeight),this.closeTop=e(this.closeTop,t.closeTop),this.closeBottom=e(this.closeBottom,t.closeBottom),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/PolylineGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._depthFailMaterial=void 0,this._depthFailMaterialSubscription=void 0,this._positions=void 0,this._positionsSubscription=void 0,this._followSurface=void 0,this._followSurfaceSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._widthSubscription=void 0,this._width=void 0,this._widthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),material:o("material"),depthFailMaterial:o("depthFailMaterial"),positions:a("positions"),width:a("width"),followSurface:a("followSurface"),granularity:a("granularity"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.material=this.material,e.depthFailMaterial=this.depthFailMaterial,e.positions=this.positions,e.width=this.width,e.followSurface=this.followSurface,e.granularity=this.granularity,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.depthFailMaterial=e(this.depthFailMaterial,t.depthFailMaterial),this.positions=e(this.positions,t.positions),this.width=e(this.width,t.width),this.followSurface=e(this.followSurface,t.followSurface),this.granularity=e(this.granularity,t.granularity),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/PolylineVolumeGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._positions=void 0,this._positionsSubscription=void 0,this._shape=void 0,this._shapeSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._cornerType=void 0,this._cornerTypeSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubsription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),material:o("material"),positions:a("positions"),shape:a("shape"),granularity:a("granularity"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),cornerType:a("cornerType"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.material=this.material,e.positions=this.positions,e.shape=this.shape,e.granularity=this.granularity,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.cornerType=this.cornerType,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.positions=e(this.positions,t.positions),this.shape=e(this.shape,t.shape),this.granularity=e(this.granularity,t.granularity),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.cornerType=e(this.cornerType,t.cornerType),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/RectangleGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._coordinates=void 0,this._coordinatesSubscription=void 0,this._height=void 0,this._heightSubscription=void 0,this._extrudedHeight=void 0,this._extrudedHeightSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._stRotation=void 0,this._stRotationSubscription=void 0,this._rotation=void 0,this._rotationSubscription=void 0,this._closeTop=void 0,this._closeTopSubscription=void 0,this._closeBottom=void 0,this._closeBottomSubscription=void 0,this._fill=void 0,this._fillSubscription=void 0, +this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distancedisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),coordinates:a("coordinates"),material:o("material"),height:a("height"),extrudedHeight:a("extrudedHeight"),granularity:a("granularity"),stRotation:a("stRotation"),rotation:a("rotation"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),closeTop:a("closeTop"),closeBottom:a("closeBottom"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.coordinates=this.coordinates,e.material=this.material,e.height=this.height,e.extrudedHeight=this.extrudedHeight,e.granularity=this.granularity,e.stRotation=this.stRotation,e.rotation=this.rotation,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.closeTop=this.closeTop,e.closeBottom=this.closeBottom,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.coordinates=e(this.coordinates,t.coordinates),this.material=e(this.material,t.material),this.height=e(this.height,t.height),this.extrudedHeight=e(this.extrudedHeight,t.extrudedHeight),this.granularity=e(this.granularity,t.granularity),this.stRotation=e(this.stRotation,t.stRotation),this.rotation=e(this.rotation,t.rotation),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.closeTop=e(this.closeTop,t.closeTop),this.closeBottom=e(this.closeBottom,t.closeBottom),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/WallGraphics",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./createMaterialPropertyDescriptor","./createPropertyDescriptor"],function(e,t,r,i,n,o,a){"use strict";function s(t){this._show=void 0,this._showSubscription=void 0,this._material=void 0,this._materialSubscription=void 0,this._positions=void 0,this._positionsSubscription=void 0,this._minimumHeights=void 0,this._minimumHeightsSubscription=void 0,this._maximumHeights=void 0,this._maximumHeightsSubscription=void 0,this._granularity=void 0,this._granularitySubscription=void 0,this._fill=void 0,this._fillSubscription=void 0,this._outline=void 0,this._outlineSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this._shadows=void 0,this._shadowsSubscription=void 0,this._distanceDisplayCondition=void 0,this._distanceDisplayConditionSubscription=void 0,this._definitionChanged=new n,this.merge(e(t,e.EMPTY_OBJECT))}return r(s.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},show:a("show"),material:o("material"),positions:a("positions"),minimumHeights:a("minimumHeights"),maximumHeights:a("maximumHeights"),granularity:a("granularity"),fill:a("fill"),outline:a("outline"),outlineColor:a("outlineColor"),outlineWidth:a("outlineWidth"),shadows:a("shadows"),distanceDisplayCondition:a("distanceDisplayCondition")}),s.prototype.clone=function(e){return t(e)?(e.show=this.show,e.material=this.material,e.positions=this.positions,e.minimumHeights=this.minimumHeights,e.maximumHeights=this.maximumHeights,e.granularity=this.granularity,e.fill=this.fill,e.outline=this.outline,e.outlineColor=this.outlineColor,e.outlineWidth=this.outlineWidth,e.shadows=this.shadows,e.distanceDisplayCondition=this.distanceDisplayCondition,e):new s(this)},s.prototype.merge=function(t){this.show=e(this.show,t.show),this.material=e(this.material,t.material),this.positions=e(this.positions,t.positions),this.minimumHeights=e(this.minimumHeights,t.minimumHeights),this.maximumHeights=e(this.maximumHeights,t.maximumHeights),this.granularity=e(this.granularity,t.granularity),this.fill=e(this.fill,t.fill),this.outline=e(this.outline,t.outline),this.outlineColor=e(this.outlineColor,t.outlineColor),this.outlineWidth=e(this.outlineWidth,t.outlineWidth),this.shadows=e(this.shadows,t.shadows),this.distanceDisplayCondition=e(this.distanceDisplayCondition,t.distanceDisplayCondition)},s}),define("DataSources/Entity",["../Core/Cartesian3","../Core/Check","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/Matrix3","../Core/Matrix4","../Core/Quaternion","../Core/Transforms","./BillboardGraphics","./BoxGraphics","./ConstantPositionProperty","./CorridorGraphics","./createPropertyDescriptor","./createRawPropertyDescriptor","./CylinderGraphics","./EllipseGraphics","./EllipsoidGraphics","./LabelGraphics","./ModelGraphics","./PathGraphics","./PlaneGraphics","./PointGraphics","./PolygonGraphics","./PolylineGraphics","./PolylineVolumeGraphics","./Property","./PropertyBag","./RectangleGraphics","./WallGraphics"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M){"use strict";function R(e){return new f(e)}function L(e,t){return g(e,void 0,function(e){return e instanceof t?e:new t(e)})}function N(e){e=i(e,i.EMPTY_OBJECT);var t=e.id;n(t)||(t=r()),this._availability=void 0,this._id=t,this._definitionChanged=new s,this._name=e.name,this._show=i(e.show,!0),this._parent=void 0,this._propertyNames=["billboard","box","corridor","cylinder","description","ellipse","ellipsoid","label","model","orientation","path","plane","point","polygon","polyline","polylineVolume","position","properties","rectangle","viewFrom","wall"],this._billboard=void 0,this._billboardSubscription=void 0,this._box=void 0,this._boxSubscription=void 0,this._corridor=void 0,this._corridorSubscription=void 0,this._cylinder=void 0,this._cylinderSubscription=void 0,this._description=void 0,this._descriptionSubscription=void 0,this._ellipse=void 0,this._ellipseSubscription=void 0,this._ellipsoid=void 0,this._ellipsoidSubscription=void 0,this._label=void 0,this._labelSubscription=void 0,this._model=void 0,this._modelSubscription=void 0,this._orientation=void 0,this._orientationSubscription=void 0,this._path=void 0,this._pathSubscription=void 0,this._plane=void 0,this._planeSubscription=void 0,this._point=void 0,this._pointSubscription=void 0,this._polygon=void 0,this._polygonSubscription=void 0,this._polyline=void 0,this._polylineSubscription=void 0,this._polylineVolume=void 0,this._polylineVolumeSubscription=void 0,this._position=void 0,this._positionSubscription=void 0,this._properties=void 0,this._propertiesSubscription=void 0,this._rectangle=void 0,this._rectangleSubscription=void 0,this._viewFrom=void 0,this._viewFromSubscription=void 0,this._wall=void 0,this._wallSubscription=void 0,this._children=[],this.entityCollection=void 0,this.parent=e.parent,this.merge(e)}function k(e,t,r){for(var i=t.length,n=0;n<i;n++){var o=t[n],a=o._show;(!r&&a)!==(r&&a)&&k(o,o._children,r)}e._definitionChanged.raiseEvent(e,"isShowing",r,!r)}o(N.prototype,{availability:_("availability"),id:{get:function(){return this._id}},definitionChanged:{get:function(){return this._definitionChanged}},name:_("name"),show:{get:function(){return this._show},set:function(e){if(e!==this._show){var t=this.isShowing;this._show=e;var r=this.isShowing;t!==r&&k(this,this._children,r),this._definitionChanged.raiseEvent(this,"show",e,!e)}}},isShowing:{get:function(){return this._show&&(!n(this.entityCollection)||this.entityCollection.show)&&(!n(this._parent)||this._parent.isShowing)}},parent:{get:function(){return this._parent},set:function(e){var t=this._parent;if(t!==e){var r=this.isShowing;if(n(t)){var i=t._children.indexOf(this);t._children.splice(i,1)}this._parent=e,n(e)&&e._children.push(this);var o=this.isShowing;r!==o&&k(this,this._children,o),this._definitionChanged.raiseEvent(this,"parent",e,t)}}},propertyNames:{get:function(){return this._propertyNames}},billboard:L("billboard",h),box:L("box",p),corridor:L("corridor",m),cylinder:L("cylinder",v),description:g("description"),ellipse:L("ellipse",y),ellipsoid:L("ellipsoid",b),label:L("label",C),model:L("model",S),orientation:g("orientation"),path:L("path",w),plane:L("plane",T),point:L("point",E),polygon:L("polygon",A),polyline:L("polyline",x),polylineVolume:L("polylineVolume",P),properties:L("properties",I),position:function(e){return g(e,void 0,R)}("position"),rectangle:L("rectangle",O),viewFrom:g("viewFrom"),wall:L("wall",M)}),N.prototype.isAvailable=function(e){var t=this._availability;return!n(t)||t.contains(e)},N.prototype.addProperty=function(e){this._propertyNames.push(e),Object.defineProperty(this,e,_(e,!0))},N.prototype.removeProperty=function(e){var t=this._propertyNames,r=t.indexOf(e);this._propertyNames.splice(r,1),delete this[e]},N.prototype.merge=function(e){this.name=i(this.name,e.name),this.availability=i(e.availability,this.availability);for(var t=this._propertyNames,r=n(e._propertyNames)?e._propertyNames:Object.keys(e),o=r.length,a=0;a<o;a++){var s=r[a];if("parent"!==s){var l=this[s],u=e[s];n(l)||-1!==t.indexOf(s)||this.addProperty(s),n(u)&&(n(l)?n(l.merge)&&l.merge(u):n(u.merge)&&n(u.clone)?this[s]=u.clone():this[s]=u)}}};var F=new l,B=new e,U=new c;return N.prototype.computeModelMatrix=function(e,r){t.typeOf.object("time",e);var i=D.getValueOrUndefined(this._position,e,B);if(n(i)){var o=D.getValueOrUndefined(this._orientation,e,U);return r=n(o)?u.fromRotationTranslation(l.fromQuaternion(o,F),i,r):d.eastNorthUpToFixedFrame(i,void 0,r)}},N}),define("DataSources/EntityCollection",["../Core/AssociativeArray","../Core/createGuid","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/Iso8601","../Core/JulianDate","../Core/RuntimeError","../Core/TimeInterval","./Entity"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e){if(e._firing)return void(e._refire=!0);if(0===e._suspendCount){var t=e._addedEntities,r=e._removedEntities,i=e._changedEntities;if(0!==i.length||0!==t.length||0!==r.length){e._firing=!0;do{e._refire=!1;var n=t.values.slice(0),o=r.values.slice(0),a=i.values.slice(0);t.removeAll(),r.removeAll(),i.removeAll(),e._collectionChanged.raiseEvent(e,n,o,a)}while(e._refire);e._firing=!1}}}function h(r){this._owner=r,this._entities=new e,this._addedEntities=new e,this._removedEntities=new e,this._changedEntities=new e,this._suspendCount=0,this._collectionChanged=new o,this._id=t(),this._show=!0,this._firing=!1,this._refire=!1}var p={id:void 0};return h.prototype.suspendEvents=function(){this._suspendCount++},h.prototype.resumeEvents=function(){this._suspendCount--,d(this)},h.collectionChangedEventCallback=void 0,i(h.prototype,{collectionChanged:{get:function(){return this._collectionChanged}},id:{get:function(){return this._id}},values:{get:function(){return this._entities.values}},show:{get:function(){return this._show},set:function(e){if(e!==this._show){this.suspendEvents();var t,r=[],i=this._entities.values,n=i.length;for(t=0;t<n;t++)r.push(i[t].isShowing);for(this._show=e,t=0;t<n;t++){var o=r[t],a=i[t];o!==a.isShowing&&a.definitionChanged.raiseEvent(a,"isShowing",a.isShowing,o)}this.resumeEvents()}}},owner:{get:function(){return this._owner}}}),h.prototype.computeAvailability=function(){for(var e=a.MAXIMUM_VALUE,t=a.MINIMUM_VALUE,i=this._entities.values,n=0,o=i.length;n<o;n++){var l=i[n],c=l.availability;if(r(c)){var d=c.start,h=c.stop;s.lessThan(d,e)&&!d.equals(a.MINIMUM_VALUE)&&(e=d),s.greaterThan(h,t)&&!h.equals(a.MAXIMUM_VALUE)&&(t=h)}}return a.MAXIMUM_VALUE.equals(e)&&(e=a.MINIMUM_VALUE),a.MINIMUM_VALUE.equals(t)&&(t=a.MAXIMUM_VALUE),new u({start:e,stop:t})},h.prototype.add=function(e){e instanceof c||(e=new c(e));var t=e.id,r=this._entities;if(r.contains(t))throw new l("An entity with id "+t+" already exists in this collection.");return e.entityCollection=this,r.set(t,e),this._removedEntities.remove(t)||this._addedEntities.set(t,e),e.definitionChanged.addEventListener(h.prototype._onEntityDefinitionChanged,this),d(this),e},h.prototype.remove=function(e){return!!r(e)&&this.removeById(e.id)},h.prototype.contains=function(e){return this._entities.get(e.id)===e},h.prototype.removeById=function(e){if(!r(e))return!1;var t=this._entities,i=t.get(e);return!!this._entities.remove(e)&&(this._addedEntities.remove(e)||(this._removedEntities.set(e,i),this._changedEntities.remove(e)),this._entities.remove(e),i.definitionChanged.removeEventListener(h.prototype._onEntityDefinitionChanged,this),d(this),!0)},h.prototype.removeAll=function(){for(var e=this._entities,t=e.length,i=e.values,n=this._addedEntities,o=this._removedEntities,a=0;a<t;a++){var s=i[a],l=s.id,u=n.get(l);r(u)||(s.definitionChanged.removeEventListener(h.prototype._onEntityDefinitionChanged,this),o.set(l,s))}e.removeAll(),n.removeAll(),this._changedEntities.removeAll(),d(this)},h.prototype.getById=function(e){return this._entities.get(e)},h.prototype.getOrCreateEntity=function(e){var t=this._entities.get(e);return r(t)||(p.id=e,t=new c(p),this.add(t)),t},h.prototype._onEntityDefinitionChanged=function(e){var t=e.id;this._addedEntities.contains(t)||this._changedEntities.set(t,e),d(this)},h}),define("DataSources/CompositeEntityCollection",["../Core/createGuid","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Math","./Entity","./EntityCollection"],function(e,t,r,i,n,o,a){"use strict";function s(e){for(var t=e.propertyNames,r=t.length,i=0;i<r;i++)e[t[i]]=void 0}function l(e,t,r,i){m[0]=r,m[1]=i.id,t[JSON.stringify(m)]=i.definitionChanged.addEventListener(d.prototype._onDefinitionChanged,e)}function u(e,t,r,i){m[0]=r,m[1]=i.id;var n=JSON.stringify(m);t[n](),t[n]=void 0}function c(e){if(e._shouldRecomposite=!0,0===e._suspendCount){var r,i,n,c,h,p,m=e._collections,g=m.length,_=e._collectionsCopy,v=_.length,y=e._composite,b=new a(e),C=e._eventHash;for(r=0;r<v;r++)for(h=_[r],h.collectionChanged.removeEventListener(d.prototype._onCollectionChanged,e),n=h.values,p=h.id,c=n.length-1;c>-1;c--)i=n[c],u(e,C,p,i);for(r=g-1;r>=0;r--)for(h=m[r],h.collectionChanged.addEventListener(d.prototype._onCollectionChanged,e),n=h.values,p=h.id,c=n.length-1;c>-1;c--){i=n[c],l(e,C,p,i);var S=b.getById(i.id);t(S)||(S=y.getById(i.id),t(S)?s(S):(f.id=i.id,S=new o(f)),b.add(S)),S.merge(i)}e._collectionsCopy=m.slice(0),y.suspendEvents(),y.removeAll();var w=b.values;for(r=0;r<w.length;r++)y.add(w[r]);y.resumeEvents()}}function d(r,i){this._owner=i,this._composite=new a(this),this._suspendCount=0,this._collections=t(r)?r.slice():[],this._collectionsCopy=[],this._id=e(),this._eventHash={},c(this),this._shouldRecomposite=!1}function h(e,t){return e.indexOf(t)}function p(e,t,r){var i=e._collections;if(t=n.clamp(t,0,i.length-1),r=n.clamp(r,0,i.length-1),t!==r){var o=i[t];i[t]=i[r],i[r]=o,c(e)}}var f={id:void 0},m=new Array(2);return r(d.prototype,{collectionChanged:{get:function(){return this._composite._collectionChanged}},id:{get:function(){return this._id}},values:{get:function(){return this._composite.values}},owner:{get:function(){return this._owner}}}),d.prototype.addCollection=function(e,r){t(r)?this._collections.splice(r,0,e):(r=this._collections.length,this._collections.push(e)),c(this)},d.prototype.removeCollection=function(e){var t=this._collections.indexOf(e);return-1!==t&&(this._collections.splice(t,1),c(this),!0)},d.prototype.removeAllCollections=function(){this._collections.length=0,c(this)},d.prototype.containsCollection=function(e){return-1!==this._collections.indexOf(e)},d.prototype.contains=function(e){return this._composite.contains(e)},d.prototype.indexOfCollection=function(e){return this._collections.indexOf(e)},d.prototype.getCollection=function(e){return this._collections[e]},d.prototype.getCollectionsLength=function(){return this._collections.length},d.prototype.raiseCollection=function(e){var t=h(this._collections,e);p(this,t,t+1)},d.prototype.lowerCollection=function(e){var t=h(this._collections,e);p(this,t,t-1)},d.prototype.raiseCollectionToTop=function(e){var t=h(this._collections,e);t!==this._collections.length-1&&(this._collections.splice(t,1),this._collections.push(e),c(this))},d.prototype.lowerCollectionToBottom=function(e){var t=h(this._collections,e);0!==t&&(this._collections.splice(t,1),this._collections.splice(0,0,e),c(this))},d.prototype.suspendEvents=function(){this._suspendCount++,this._composite.suspendEvents()},d.prototype.resumeEvents=function(){this._suspendCount--,this._shouldRecomposite&&0===this._suspendCount&&(c(this),this._shouldRecomposite=!1),this._composite.resumeEvents()},d.prototype.computeAvailability=function(){return this._composite.computeAvailability()},d.prototype.getById=function(e){return this._composite.getById(e)},d.prototype._onCollectionChanged=function(e,r,i){var n=this._collectionsCopy,a=n.length,c=this._composite;c.suspendEvents();var d,h,p,m,g=i.length,_=this._eventHash,v=e.id;for(d=0;d<g;d++){var y=i[d];u(this,_,v,y);var b=y.id;for(h=a-1;h>=0;h--)p=n[h].getById(b),t(p)&&(t(m)||(m=c.getById(b),s(m)),m.merge(p));t(m)||c.removeById(b),m=void 0}var C=r.length;for(d=0;d<C;d++){var S=r[d];l(this,_,v,S);var w=S.id;for(h=a-1;h>=0;h--)p=n[h].getById(w),t(p)&&(t(m)||(m=c.getById(w),t(m)?s(m):(f.id=w,m=new o(f),c.add(m))),m.merge(p));m=void 0}c.resumeEvents()},d.prototype._onDefinitionChanged=function(e,r,i,n){for(var o=this._collections,a=this._composite,s=o.length,l=e.id,u=a.getById(l),c=u[r],d=!t(c),h=!0,p=s-1;p>=0;p--){var f=o[p].getById(e.id);if(t(f)){var m=f[r];if(t(m)){if(h){if(h=!1,!t(m.merge)||!t(m.clone)){c=m;break}c=m.clone(c)}c.merge(m)}}}d&&-1===u.propertyNames.indexOf(r)&&u.addProperty(r),u[r]=c},d}),define("DataSources/CompositeProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/EventHelper","../Core/TimeIntervalCollection","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(t,r,i,n){function o(){i.raiseEvent(t)}var a=[];r.removeAll();for(var s=n.length,l=0;l<s;l++){var u=n.get(l);e(u.data)&&-1===a.indexOf(u.data)&&r.add(u.data.definitionChanged,o)}}function l(){this._eventHelper=new n,this._definitionChanged=new i,this._intervals=new o,this._intervals.changedEvent.addEventListener(l.prototype._intervalsChanged,this)}return t(l.prototype,{isConstant:{get:function(){return this._intervals.isEmpty}},definitionChanged:{get:function(){return this._definitionChanged}},intervals:{get:function(){return this._intervals}}}),l.prototype.getValue=function(t,r){var i=this._intervals.findDataForIntervalContainingDate(t);if(e(i))return i.getValue(t,r)},l.prototype.equals=function(e){return this===e||e instanceof l&&this._intervals.equals(e._intervals,a.equals)},l.prototype._intervalsChanged=function(){s(this,this._eventHelper,this._definitionChanged,this._intervals),this._definitionChanged.raiseEvent(this)},l}),define("DataSources/CompositeMaterialProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./CompositeProperty","./Property"],function(e,t,r,i,n,o){"use strict";function a(){this._definitionChanged=new i,this._composite=new n,this._composite.definitionChanged.addEventListener(a.prototype._raiseDefinitionChanged,this)}return t(a.prototype,{isConstant:{get:function(){return this._composite.isConstant}},definitionChanged:{get:function(){return this._definitionChanged}},intervals:{get:function(){return this._composite._intervals}}}),a.prototype.getType=function(t){var r=this._composite._intervals.findDataForIntervalContainingDate(t);if(e(r))return r.getType(t)},a.prototype.getValue=function(t,r){var i=this._composite._intervals.findDataForIntervalContainingDate(t);if(e(i))return i.getValue(t,r)},a.prototype.equals=function(e){return this===e||e instanceof a&&this._composite.equals(e._composite,o.equals)},a.prototype._raiseDefinitionChanged=function(){this._definitionChanged.raiseEvent(this)},a}),define("DataSources/CompositePositionProperty",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/ReferenceFrame","./CompositeProperty","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(t){this._referenceFrame=e(t,o.FIXED),this._definitionChanged=new n,this._composite=new a,this._composite.definitionChanged.addEventListener(l.prototype._raiseDefinitionChanged,this)}return r(l.prototype,{isConstant:{get:function(){return this._composite.isConstant}},definitionChanged:{get:function(){return this._definitionChanged}},intervals:{get:function(){return this._composite.intervals}},referenceFrame:{get:function(){return this._referenceFrame},set:function(e){this._referenceFrame=e}}}),l.prototype.getValue=function(e,t){return this.getValueInReferenceFrame(e,o.FIXED,t)},l.prototype.getValueInReferenceFrame=function(e,r,i){var n=this._composite._intervals.findDataForIntervalContainingDate(e);if(t(n))return n.getValueInReferenceFrame(e,r,i)},l.prototype.equals=function(e){return this===e||e instanceof l&&this._referenceFrame===e._referenceFrame&&this._composite.equals(e._composite,s.equals)},l.prototype._raiseDefinitionChanged=function(){this._definitionChanged.raiseEvent(this)},l}),define("Shaders/ShadowVolumeFS",[],function(){"use strict";return"#ifdef GL_EXT_frag_depth\n#extension GL_EXT_frag_depth : enable\n#endif\n#ifdef VECTOR_TILE\nuniform vec4 u_highlightColor;\n#else\nvarying vec4 v_color;\n#endif\nvoid main(void)\n{\n#ifdef VECTOR_TILE\ngl_FragColor = u_highlightColor;\n#else\ngl_FragColor = v_color;\n#endif\nczm_writeDepthClampedToFarPlane();\n}\n"}),define("Shaders/ShadowVolumeVS",[],function(){"use strict";return"#ifdef VECTOR_TILE\nattribute vec3 position;\nattribute float a_batchId;\nuniform mat4 u_modifiedModelViewProjection;\n#else\nattribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec4 color;\nattribute float batchId;\n#endif\n#ifdef EXTRUDED_GEOMETRY\nattribute vec3 extrudeDirection;\nuniform float u_globeMinimumAltitude;\n#endif\n#ifndef VECTOR_TILE\nvarying vec4 v_color;\n#endif\nvoid main()\n{\n#ifdef VECTOR_TILE\ngl_Position = czm_depthClampFarPlane(u_modifiedModelViewProjection * vec4(position, 1.0));\n#else\nv_color = color;\nvec4 position = czm_computePosition();\n#ifdef EXTRUDED_GEOMETRY\nfloat delta = min(u_globeMinimumAltitude, czm_geometricToleranceOverMeter * length(position.xyz));\ndelta *= czm_sceneMode == czm_sceneMode3D ? 1.0 : 0.0;\nposition = position + vec4(extrudeDirection * delta, 0.0);\n#endif\ngl_Position = czm_depthClampFarPlane(czm_modelViewProjectionRelativeToEye * position);\n#endif\n}\n"}),define("Scene/ClassificationType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,CESIUM_3D_TILE:1,BOTH:2})}),define("Scene/StencilFunction",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({NEVER:t.NEVER,LESS:t.LESS,EQUAL:t.EQUAL,LESS_OR_EQUAL:t.LEQUAL,GREATER:t.GREATER,NOT_EQUAL:t.NOTEQUAL,GREATER_OR_EQUAL:t.GEQUAL,ALWAYS:t.ALWAYS})}),define("Scene/StencilOperation",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";return e({ZERO:t.ZERO,KEEP:t.KEEP,REPLACE:t.REPLACE,INCREMENT:t.INCR,DECREMENT:t.DECR,INVERT:t.INVERT,INCREMENT_WRAP:t.INCR_WRAP,DECREMENT_WRAP:t.DECR_WRAP})}),define("Scene/ClassificationPrimitive",["../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/GeometryInstance","../Core/isArray","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Shaders/ShadowVolumeFS","../Shaders/ShadowVolumeVS","../ThirdParty/when","./BlendingState","./ClassificationType","./DepthFunction","./PerInstanceColorAppearance","./Primitive","./SceneMode","./StencilFunction","./StencilOperation"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){"use strict";function T(e){e=t(e,t.EMPTY_OBJECT),this.geometryInstances=e.geometryInstances,this.show=t(e.show,!0),this.classificationType=t(e.classificationType,_.BOTH),this.debugShowBoundingVolume=t(e.debugShowBoundingVolume,!1),this.debugShowShadowVolume=t(e.debugShowShadowVolume,!1),this._debugShowShadowVolume=!1,this._extruded=t(e._extruded,!1),this._uniformMap=e._uniformMap,this._sp=void 0,this._spStencil=void 0,this._spPick=void 0,this._rsStencilPreloadPass=void 0,this._rsStencilDepthPass=void 0,this._rsColorPass=void 0,this._rsPickPass=void 0,this._commandsIgnoreShow=[],this._ready=!1,this._readyPromise=m.defer(),this._primitive=void 0,this._pickPrimitive=e._pickPrimitive;var i,n=new y({flat:!0});r(this.geometryInstances)&&s(this.geometryInstances)&&this.geometryInstances.length>1&&(i=k),this._createBoundingVolumeFunction=e._createBoundingVolumeFunction,this._updateAndQueueCommandsFunction=e._updateAndQueueCommandsFunction,this._primitiveOptions={geometryInstances:void 0,appearance:n,vertexCacheOptimize:t(e.vertexCacheOptimize,!1),interleave:t(e.interleave,!1),releaseGeometryInstances:t(e.releaseGeometryInstances,!0),allowPicking:t(e.allowPicking,!0),asynchronous:t(e.asynchronous,!0),compressVertices:t(e.compressVertices,!0),_readOnlyInstanceAttributes:i,_createBoundingVolumeFunction:void 0,_createRenderStatesFunction:void 0,_createShaderProgramFunction:void 0,_createCommandsFunction:void 0,_updateAndQueueCommandsFunction:void 0,_createPickOffsets:!0}}function E(e){return{colorMask:{red:!1,green:!1,blue:!1,alpha:!1},stencilTest:{enabled:e,frontFunction:S.ALWAYS,frontOperation:{fail:w.KEEP,zFail:w.DECREMENT_WRAP,zPass:w.DECREMENT_WRAP},backFunction:S.ALWAYS,backOperation:{fail:w.KEEP,zFail:w.INCREMENT_WRAP,zPass:w.INCREMENT_WRAP},reference:B,mask:F},depthTest:{enabled:!1},depthMask:!1}}function A(e){return{colorMask:{red:!1,green:!1,blue:!1,alpha:!1},stencilTest:{enabled:e,frontFunction:S.ALWAYS,frontOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.INCREMENT_WRAP},backFunction:S.ALWAYS,backOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},reference:B,mask:F},depthTest:{enabled:!0,func:v.LESS_OR_EQUAL},depthMask:!1}}function x(e){return{stencilTest:{enabled:e,frontFunction:S.NOT_EQUAL,frontOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},backFunction:S.NOT_EQUAL,backOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},reference:B,mask:F},depthTest:{enabled:!1},depthMask:!1,blending:g.ALPHA_BLEND}}function P(e,t,i,n){if(!r(e._rsStencilPreloadPass)){var o=!e.debugShowShadowVolume;e._rsStencilPreloadPass=c.fromCache(E(o)),e._rsStencilDepthPass=c.fromCache(A(o)),e._rsColorPass=c.fromCache(x(o)),e._rsPickPass=c.fromCache(U)}}function D(e,t){if(!e.compressVertices)return t;if(-1!==t.search(/attribute\s+vec3\s+extrudeDirection;/g)){var r=t;r=r.replace(/attribute\s+vec3\s+extrudeDirection;/g,""),r=h.replaceMain(r,"czm_non_compressed_main");return["attribute vec2 compressedAttributes;","vec3 extrudeDirection;\n",r,"void main() \n{ \n extrudeDirection = czm_octDecode(compressedAttributes, 65535.0);\n czm_non_compressed_main(); \n}"].join("\n")}}function I(e,t,i){if(!r(e._sp)){var n=t.context,o=e._primitive,a=f;a=e._primitive._batchTable.getVertexShaderCallback()(a),a=b._appendDistanceDisplayConditionToShader(o,a),a=b._modifyShaderPosition(e,a,t.scene3DOnly),a=b._updateColorAttribute(o,a),e._extruded&&(a=D(o,a));var s=e._extruded?"EXTRUDED_GEOMETRY":"",l=new h({defines:[s],sources:[a]}),u=new h({sources:[p]}),c=e._primitive._attributeLocations;if(e._spStencil=d.replaceCache({context:n,shaderProgram:e._spStencil,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:c}),e._primitive.allowPicking){var m=h.createPickVertexShaderSource(a);m=b._appendShowToShader(o,m),m=b._updatePickColorAttribute(m);var g=new h({defines:[s],sources:[m]}),_=new h({sources:[p],pickColorQualifier:"varying"});e._spPick=d.replaceCache({context:n,shaderProgram:e._spPick,vertexShaderSource:g,fragmentShaderSource:_,attributeLocations:c})}else e._spPick=d.fromCache({context:n,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:c});a=b._appendShowToShader(o,a),l=new h({defines:[s],sources:[a]}),e._sp=d.replaceCache({context:n,shaderProgram:e._sp,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:c})}}function O(e,t){var i=e._primitive,n=3*i._va.length;t.length=n;var o,a,s=0,c=i._batchTable.getUniformMapCallback()(e._uniformMap);for(o=0;o<n;o+=3){var d=i._va[s++];a=t[o],r(a)||(a=t[o]=new l({owner:e,primitiveType:i._primitiveType})),a.vertexArray=d,a.renderState=e._rsStencilPreloadPass,a.shaderProgram=e._sp,a.uniformMap=c,a=t[o+1],r(a)||(a=t[o+1]=new l({owner:e,primitiveType:i._primitiveType})),a.vertexArray=d,a.renderState=e._rsStencilDepthPass,a.shaderProgram=e._sp,a.uniformMap=c,a=t[o+2],r(a)||(a=t[o+2]=new l({owner:e,primitiveType:i._primitiveType})),a.vertexArray=d,a.renderState=e._rsColorPass,a.shaderProgram=e._sp,a.uniformMap=c}var h=e._commandsIgnoreShow,p=e._spStencil,f=0;n=h.length=n/3*2;for(var m=0;m<n;m+=2){var g=h[m]=l.shallowClone(t[f],h[m]);g.shaderProgram=p,g.pass=u.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW,g=h[m+1]=l.shallowClone(t[f+1],h[m+1]),g.shaderProgram=p,g.pass=u.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW,f+=3}}function M(e,t){var i=e._primitive,n=i._pickOffsets,o=3*n.length;t.length=o;var a,s,u=0,c=i._batchTable.getUniformMapCallback()(e._uniformMap);for(a=0;a<o;a+=3){var d=n[u++],h=d.offset,p=d.count,f=i._va[d.index];s=t[a],r(s)||(s=t[a]=new l({owner:e,primitiveType:i._primitiveType})),s.vertexArray=f,s.offset=h,s.count=p,s.renderState=e._rsStencilPreloadPass,s.shaderProgram=e._spStencil,s.uniformMap=c,s=t[a+1],r(s)||(s=t[a+1]=new l({owner:e,primitiveType:i._primitiveType})),s.vertexArray=f,s.offset=h,s.count=p,s.renderState=e._rsStencilDepthPass,s.shaderProgram=e._spStencil,s.uniformMap=c,s=t[a+2],r(s)||(s=t[a+2]=new l({owner:e,primitiveType:i._primitiveType})),s.vertexArray=f,s.offset=h,s.count=p,s.renderState=e._rsPickPass,s.shaderProgram=e._spPick,s.uniformMap=c}}function R(e,t,r,i,n,o,a){O(e,o),M(e,a)}function L(e,t){return Math.floor(e%t/3)}function N(e,t,i,n,o,a,s,l){var c=e._primitive;b._updateBoundingVolumes(c,t,o);var d;t.mode===C.SCENE3D?d=c._boundingSphereWC:t.mode===C.COLUMBUS_VIEW?d=c._boundingSphereCV:t.mode===C.SCENE2D&&r(c._boundingSphere2D)?d=c._boundingSphere2D:r(c._boundingSphereMorph)&&(d=c._boundingSphereMorph);var h,p,f=t.commandList,m=t.passes;switch(e.classificationType){case _.TERRAIN:p=u.TERRAIN_CLASSIFICATION;break;case _.CESIUM_3D_TILE:p=u.CESIUM_3D_TILE_CLASSIFICATION;break;default:p=u.CLASSIFICATION}if(m.render){var g,v=i.length;for(h=0;h<v;++h)g=i[h],g.modelMatrix=o,g.boundingVolume=d[L(h,v)],g.cull=a,g.debugShowBoundingVolume=s,g.pass=p,f.push(g);if(t.invertClassification){var y=e._commandsIgnoreShow,S=y.length;for(h=0;h<S;++h){var w=Math.floor(h/2);g=y[h],g.modelMatrix=o,g.boundingVolume=d[w],g.cull=a,g.debugShowBoundingVolume=s,f.push(g)}}}if(m.pick){var T=n.length,E=c._pickOffsets;for(h=0;h<T;++h){var A=E[L(h,T)],x=n[h];x.modelMatrix=o,x.boundingVolume=d[A.index],x.cull=a,x.pass=p,f.push(x)}}}var k=["color"];i(T.prototype,{vertexCacheOptimize:{get:function(){return this._primitiveOptions.vertexCacheOptimize}},interleave:{get:function(){return this._primitiveOptions.interleave}},releaseGeometryInstances:{get:function(){return this._primitiveOptions.releaseGeometryInstances}},allowPicking:{get:function(){return this._primitiveOptions.allowPicking}},asynchronous:{get:function(){return this._primitiveOptions.asynchronous}},compressVertices:{get:function(){return this._primitiveOptions.compressVertices}},ready:{get:function(){return this._ready}},readyPromise:{ +get:function(){return this._readyPromise.promise}}}),T.isSupported=function(e){return e.context.stencilBuffer};var F=15,B=0,U={stencilTest:{enabled:!0,frontFunction:S.NOT_EQUAL,frontOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},backFunction:S.NOT_EQUAL,backOperation:{fail:w.KEEP,zFail:w.KEEP,zPass:w.DECREMENT_WRAP},reference:B,mask:F},depthTest:{enabled:!1},depthMask:!1};return T.prototype.update=function(e){if(this.show&&(r(this._primitive)||r(this.geometryInstances))){var i=this,n=this._primitiveOptions;if(!r(this._primitive)){var o,l,u=s(this.geometryInstances)?this.geometryInstances:[this.geometryInstances],d=u.length,h=new Array(d);for(o=0;o<d;++o)l=u[o],h[o]=new a({geometry:l.geometry,attributes:l.attributes,modelMatrix:l.modelMatrix,id:l.id,pickPrimitive:t(this._pickPrimitive,i)});n.geometryInstances=h,r(this._createBoundingVolumeFunction)&&(n._createBoundingVolumeFunction=function(e,t){i._createBoundingVolumeFunction(e,t)}),n._createRenderStatesFunction=function(e,t,r,n){P(i,t)},n._createShaderProgramFunction=function(e,t,r){I(i,t)},n._createCommandsFunction=function(e,t,r,n,o,a,s){R(i,void 0,void 0,!0,!1,a,s)},r(this._updateAndQueueCommandsFunction)?n._updateAndQueueCommandsFunction=function(e,t,r,n,o,a,s,l){i._updateAndQueueCommandsFunction(e,t,r,n,o,a,s,l)}:n._updateAndQueueCommandsFunction=function(e,t,r,n,o,a,s,l){N(i,t,r,n,o,a,s,l)},this._primitive=new b(n),this._primitive.readyPromise.then(function(e){i._ready=!0,i.releaseGeometryInstances&&(i.geometryInstances=void 0);var t=e._error;r(t)?i._readyPromise.reject(t):i._readyPromise.resolve(i)})}this.debugShowShadowVolume&&!this._debugShowShadowVolume&&this._ready?(this._debugShowShadowVolume=!0,this._rsStencilPreloadPass=c.fromCache(E(!1)),this._rsStencilDepthPass=c.fromCache(A(!1)),this._rsColorPass=c.fromCache(x(!1))):!this.debugShowShadowVolume&&this._debugShowShadowVolume&&(this._debugShowShadowVolume=!1,this._rsStencilPreloadPass=c.fromCache(E(!0)),this._rsStencilDepthPass=c.fromCache(A(!0)),this._rsColorPass=c.fromCache(x(!0))),this._primitive.debugShowBoundingVolume=this.debugShowBoundingVolume,this._primitive.update(e)}},T.prototype.getGeometryInstanceAttributes=function(e){return this._primitive.getGeometryInstanceAttributes(e)},T.prototype.isDestroyed=function(){return!1},T.prototype.destroy=function(){return this._primitive=this._primitive&&this._primitive.destroy(),this._sp=this._sp&&this._sp.destroy(),this._spPick=this._spPick&&this._spPick.destroy(),n(this)},T}),define("Scene/GroundPrimitive",["../Core/BoundingSphere","../Core/buildModuleUrl","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/GeographicTilingScheme","../Core/GeometryInstance","../Core/isArray","../Core/Math","../Core/OrientedBoundingBox","../Core/Rectangle","../Core/Resource","../Renderer/Pass","../ThirdParty/when","./ClassificationPrimitive","./ClassificationType","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C){"use strict";function S(e){e=o(e,o.EMPTY_OBJECT),this.geometryInstances=e.geometryInstances,this.show=o(e.show,!0),this.classificationType=o(e.classificationType,b.BOTH),this.debugShowBoundingVolume=o(e.debugShowBoundingVolume,!1),this.debugShowShadowVolume=o(e.debugShowShadowVolume,!1),this._boundingVolumes=[],this._boundingVolumes2D=[],this._ready=!1,this._readyPromise=v.defer(),this._primitive=void 0,this._maxHeight=void 0,this._minHeight=void 0,this._maxTerrainHeight=S._defaultMaxTerrainHeight,this._minTerrainHeight=S._defaultMinTerrainHeight,this._boundingSpheresKeys=[],this._boundingSpheres=[];var t=this;this._primitiveOptions={geometryInstances:void 0,vertexCacheOptimize:o(e.vertexCacheOptimize,!1),interleave:o(e.interleave,!1),releaseGeometryInstances:o(e.releaseGeometryInstances,!0),allowPicking:o(e.allowPicking,!0),asynchronous:o(e.asynchronous,!0),compressVertices:o(e.compressVertices,!0),_createBoundingVolumeFunction:void 0,_updateAndQueueCommandsFunction:void 0,_pickPrimitive:t,_extruded:!0,_uniformMap:M}}function w(e){return function(t,r){var i=r.maximumRadius,n=i/Math.cos(.5*t)-i;return e._maxHeight+n}}function T(e){return function(t,r){return e._minHeight}}function E(e,t){var r=e.mapProjection.ellipsoid;{if(a(t.attributes)&&a(t.attributes.position3DHigh)){for(var n=t.attributes.position3DHigh.values,o=t.attributes.position3DLow.values,s=n.length,l=Number.POSITIVE_INFINITY,u=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,d=Number.NEGATIVE_INFINITY,h=0;h<s;h+=3){var p=i.unpack(n,h,L),f=i.unpack(o,h,N),m=i.add(p,f,k),g=r.cartesianToCartographic(m,F),_=g.latitude,v=g.longitude;l=Math.min(l,_),u=Math.min(u,v),c=Math.max(c,_),d=Math.max(d,v)}var y=B;return y.north=c,y.south=l,y.east=d,y.west=u,y}if(a(t.rectangle))return t.rectangle}}function A(e){n.fromRadians(e.east,e.north,0,V[0]),n.fromRadians(e.west,e.north,0,V[1]),n.fromRadians(e.east,e.south,0,V[2]),n.fromRadians(e.west,e.south,0,V[3]);var t,r=0,i=0,o=0,a=0,s=S._terrainHeightsMaxLevel;for(t=0;t<=s;++t){for(var l=!1,u=0;u<4;++u){var c=V[u];if(U.positionToTileXY(c,t,z),0===u)o=z.x,a=z.y;else if(o!==z.x||a!==z.y){l=!0;break}}if(l)break;r=o,i=a}if(0!==t)return{x:r,y:i,level:t>s?s:t-1}}function x(e,t,r){var n=A(t),o=S._defaultMinTerrainHeight,s=S._defaultMaxTerrainHeight;if(a(n)){var l=n.level+"-"+n.x+"-"+n.y,u=S._terrainHeights[l];a(u)&&(o=u[0],s=u[1]),r.cartographicToCartesian(m.northeast(t,H),G),r.cartographicToCartesian(m.southwest(t,H),W),i.subtract(W,G,j),i.add(G,i.multiplyByScalar(j,.5,j),j);var c=r.scaleToGeodeticSurface(j,q);if(a(c)){var d=i.distance(j,c);o=Math.min(o,-d)}else o=S._defaultMinTerrainHeight}e._minTerrainHeight=Math.max(S._defaultMinTerrainHeight,o),e._maxTerrainHeight=s}function P(t,r){var i=A(t),n=S._defaultMaxTerrainHeight;if(a(i)){var o=i.level+"-"+i.x+"-"+i.y,s=S._terrainHeights[o];a(s)&&(n=s[1])}var l=e.fromRectangle3D(t,r,0);return e.fromRectangle3D(t,r,n,Y),e.union(l,Y,l)}function D(t,r,n){var o=r.mapProjection.ellipsoid,a=E(r,n);if(a.width<p.PI){var s=f.fromRectangle(a,t._maxHeight,t._minHeight,o);t._boundingVolumes.push(s)}else{var l=n.attributes.position3DHigh.values,u=n.attributes.position3DLow.values;t._boundingVolumes.push(e.fromEncodedCartesianVertices(l,u))}if(!r.scene3DOnly){var c=r.mapProjection,d=e.fromRectangleWithHeights2D(a,c,t._maxHeight,t._minHeight);i.fromElements(d.center.z,d.center.x,d.center.y,d.center),t._boundingVolumes2D.push(d)}}function I(e,t){return Math.floor(e%t/3)}function O(e,t,r,i,n,o,a,s){var l;l=t.mode===C.SCENE3D?e._boundingVolumes:e._boundingVolumes2D;var u;switch(e.classificationType){case b.TERRAIN:u=_.TERRAIN_CLASSIFICATION;break;case b.CESIUM_3D_TILE:u=_.CESIUM_3D_TILE_CLASSIFICATION;break;default:u=_.CLASSIFICATION}var c=t.commandList,d=t.passes;if(d.render){var h,p,f=r.length;for(h=0;h<f;++h)p=r[h],p.owner=e,p.modelMatrix=n,p.boundingVolume=l[I(h,f)],p.cull=o,p.debugShowBoundingVolume=a,p.pass=u,c.push(p);if(t.invertClassification){var m=e._primitive._commandsIgnoreShow,g=m.length;for(h=0;h<g;++h){var v=Math.floor(h/2);p=m[h],p.modelMatrix=n,p.boundingVolume=l[v],p.cull=o,p.debugShowBoundingVolume=a,c.push(p)}}}if(d.pick)for(var y=i.length,S=e._primitive._primitive,w=S._pickOffsets,T=0;T<y;++T){var E=w[I(T,y)],A=l[E.index],x=i[T];x.owner=e,x.modelMatrix=n,x.boundingVolume=A,x.cull=o,x.pass=u,c.push(x)}}var M={u_globeMinimumAltitude:function(){return 55e3}},R=new g({url:t("Assets/approximateTerrainHeights.json")});s(S.prototype,{vertexCacheOptimize:{get:function(){return this._primitiveOptions.vertexCacheOptimize}},interleave:{get:function(){return this._primitiveOptions.interleave}},releaseGeometryInstances:{get:function(){return this._primitiveOptions.releaseGeometryInstances}},allowPicking:{get:function(){return this._primitiveOptions.allowPicking}},asynchronous:{get:function(){return this._primitiveOptions.asynchronous}},compressVertices:{get:function(){return this._primitiveOptions.compressVertices}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}}}),S.isSupported=y.isSupported,S._defaultMaxTerrainHeight=9e3,S._defaultMinTerrainHeight=-1e5,S._terrainHeights=void 0,S._terrainHeightsMaxLevel=6;var L=new i,N=new i,k=new i,F=new n,B=new m,U=new c,V=[new n,new n,new n,new n],z=new r,G=new i,W=new i,H=new n,j=new i,q=new i,Y=new e;return S._initialized=!1,S._initPromise=void 0,S.initializeTerrainHeights=function(){var e=S._initPromise;return a(e)?e:(S._initPromise=R.fetchJson().then(function(e){S._initialized=!0,S._terrainHeights=e}),S._initPromise)},S.prototype.update=function(e){if(this.show&&(a(this._primitive)||a(this.geometryInstances))){if(!S._initialized)return void S.initializeTerrainHeights();var t=this,r=this._primitiveOptions;if(!a(this._primitive)){var i,n,o,s,l,u=e.mapProjection.ellipsoid,c=h(this.geometryInstances)?this.geometryInstances:[this.geometryInstances],p=c.length,f=new Array(p);for(s=0;s<p;++s){i=c[s],n=i.geometry;var g=E(e,n);a(l)?a(g)&&m.union(l,g,l):l=g;var _=i.id;if(a(_)&&a(g)){var v=P(g,u);this._boundingSpheresKeys.push(_),this._boundingSpheres.push(v)}o=n.constructor,!a(o)||a(o.createShadowVolume)}x(this,l,e.mapProjection.ellipsoid);var b=e.terrainExaggeration;for(this._minHeight=this._minTerrainHeight*b,this._maxHeight=this._maxTerrainHeight*b,s=0;s<p;++s)i=c[s],n=i.geometry,o=n.constructor,f[s]=new d({geometry:o.createShadowVolume(n,T(this),w(this)),attributes:i.attributes,id:i.id});r.geometryInstances=f,r._createBoundingVolumeFunction=function(e,r){D(t,e,r)},r._updateAndQueueCommandsFunction=function(e,r,i,n,o,a,s,l){O(t,r,i,n,o,a,s,l)},this._primitive=new y(r),this._primitive.readyPromise.then(function(e){t._ready=!0,t.releaseGeometryInstances&&(t.geometryInstances=void 0);var r=e._error;a(r)?t._readyPromise.reject(r):t._readyPromise.resolve(t)})}this._primitive.debugShowShadowVolume=this.debugShowShadowVolume,this._primitive.debugShowBoundingVolume=this.debugShowBoundingVolume,this._primitive.update(e)}},S.prototype.getBoundingSphere=function(e){var t=this._boundingSpheresKeys.indexOf(e);if(-1!==t)return this._boundingSpheres[t]},S.prototype.getGeometryInstanceAttributes=function(e){return this._primitive.getGeometryInstanceAttributes(e)},S.prototype.isDestroyed=function(){return!1},S.prototype.destroy=function(){return this._primitive=this._primitive&&this._primitive.destroy(),l(this)},S}),define("DataSources/CorridorGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/CorridorGeometry","../Core/CorridorOutlineGeometry","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/oneTimeWarning","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e){this.id=e,this.vertexFormat=void 0,this.positions=void 0,this.width=void 0,this.cornerType=void 0,this.height=void 0,this.extrudedHeight=void 0,this.granularity=void 0}function x(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(x.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._isClosed=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new d,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._onTerrain=!1,this._options=new A(e),this._onEntityPropertyChanged(e,"corridor",e.corridor,void 0)}function P(e,t,r){this._primitives=e,this._groundPrimitives=t,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=r,this._options=new A(r._entity)}var D=new C(e.WHITE),I=new S(!0),O=new S(!0),M=new S(!1),R=new S(e.BLACK),L=new S(b.DISABLED),N=new S(new u),k=new e;return a(x,{perInstanceColorAppearanceType:{value:v},materialAppearanceType:{value:_}}),a(x.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!o(this._entity.availability)&&E.isConstant(this._showProperty)&&E.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!o(this._entity.availability)&&E.isConstant(this._showProperty)&&E.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayCondition}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return this._isClosed}},onTerrain:{get:function(){return this._onTerrain}},geometryChanged:{get:function(){return this._geometryChanged}}}),x.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},x.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},x.prototype.createFillGeometryInstance=function(i){var n,a,s=this._entity,l=s.isAvailable(i),u=new m(l&&s.isShowing&&this._showProperty.getValue(i)&&this._fillProperty.getValue(i)),d=c.fromDistanceDisplayCondition(this._distanceDisplayCondition.getValue(i));if(this._materialProperty instanceof C){var p=e.WHITE;o(this._materialProperty.color)&&(this._materialProperty.color.isConstant||l)&&(p=this._materialProperty.color.getValue(i)),a=t.fromColor(p),n={show:u,distanceDisplayCondition:d,color:a}}else n={show:u,distanceDisplayCondition:d};return new h({id:s,geometry:new r(this._options),attributes:n})},x.prototype.createOutlineGeometryInstance=function(r){var n=this._entity,o=n.isAvailable(r),a=E.getValueOrDefault(this._outlineColorProperty,r,e.BLACK);return new h({id:n,geometry:new i(this._options),attributes:{show:new m(o&&n.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(a),distanceDisplayCondition:c.fromDistanceDisplayCondition(this._distanceDisplayCondition.getValue(r))}})},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){this._entitySubscription(),s(this)},x.prototype._onEntityPropertyChanged=function(e,t,r,i){if("availability"===t||"corridor"===t){var a=this._entity.corridor;if(!o(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!o(s)||!s.isConstant||s.getValue(p.MINIMUM_VALUE),u=a.outline,c=o(u);if(c&&u.isConstant&&(c=u.getValue(p.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=a.positions,h=a.show;if(o(h)&&h.isConstant&&!h.getValue(p.MINIMUM_VALUE)||!o(d))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var m=n(a.material,D),y=m instanceof C;this._materialProperty=m,this._fillProperty=n(s,O),this._showProperty=n(h,I),this._showOutlineProperty=n(a.outline,M),this._outlineColorProperty=c?n(a.outlineColor,R):void 0,this._shadowsProperty=n(a.shadows,L),this._distanceDisplayCondition=n(a.distanceDisplayCondition,N);var b=a.height,S=a.extrudedHeight,w=a.granularity,T=a.width,A=a.outlineWidth,x=a.cornerType,P=l&&!o(b)&&!o(S)&&y&&g.isSupported(this._scene);if(c&&P&&(f(f.geometryOutlines),c=!1),this._fillEnabled=l,this._onTerrain=P,this._isClosed=o(S)||P,this._outlineEnabled=c,d.isConstant&&E.isConstant(b)&&E.isConstant(S)&&E.isConstant(w)&&E.isConstant(T)&&E.isConstant(A)&&E.isConstant(x)&&(!P||E.isConstant(m))){var k=this._options;k.vertexFormat=y?v.VERTEX_FORMAT:_.MaterialSupport.TEXTURED.vertexFormat,k.positions=d.getValue(p.MINIMUM_VALUE,k.positions),k.height=o(b)?b.getValue(p.MINIMUM_VALUE):void 0,k.extrudedHeight=o(S)?S.getValue(p.MINIMUM_VALUE):void 0,k.granularity=o(w)?w.getValue(p.MINIMUM_VALUE):void 0,k.width=o(T)?T.getValue(p.MINIMUM_VALUE):void 0,k.cornerType=o(x)?x.getValue(p.MINIMUM_VALUE):void 0,this._outlineWidth=o(A)?A.getValue(p.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},x.prototype.createDynamicUpdater=function(e,t){return new P(e,t,this)},P.prototype.update=function(n){var a=this._geometryUpdater,s=a._onTerrain,l=this._primitives,u=this._groundPrimitives;s?u.removeAndDestroy(this._primitive):(l.removeAndDestroy(this._primitive),l.removeAndDestroy(this._outlinePrimitive),this._outlinePrimitive=void 0),this._primitive=void 0;var d=a._entity,p=d.corridor;if(d.isShowing&&d.isAvailable(n)&&E.getValueOrDefault(p.show,n,!0)){var f=this._options,m=E.getValueOrUndefined(p.positions,n,f.positions),b=E.getValueOrUndefined(p.width,n);if(o(m)&&o(b)){f.positions=m,f.width=b,f.height=E.getValueOrUndefined(p.height,n),f.extrudedHeight=E.getValueOrUndefined(p.extrudedHeight,n),f.granularity=E.getValueOrUndefined(p.granularity,n),f.cornerType=E.getValueOrUndefined(p.cornerType,n);var C=this._geometryUpdater.shadowsProperty.getValue(n),S=this._geometryUpdater.distanceDisplayConditionProperty.getValue(n),w=c.fromDistanceDisplayCondition(S);if(!o(p.fill)||p.fill.getValue(n)){var A=a.fillMaterialProperty,x=T.getValue(n,A,this._material);if(this._material=x,s){var P=e.WHITE;o(A.color)&&(P=A.color.getValue(n)),this._primitive=u.add(new g({geometryInstances:new h({id:d,geometry:new r(f),attributes:{color:t.fromColor(P),distanceDisplayCondition:w}}),asynchronous:!1,shadows:C}))}else{var D=new _({material:x,translucent:x.isTranslucent(),closed:o(f.extrudedHeight)});f.vertexFormat=D.vertexFormat,this._primitive=l.add(new y({geometryInstances:new h({id:d,geometry:new r(f),attributes:{distanceDisplayCondition:w}}),appearance:D,asynchronous:!1,shadows:C}))}}if(!s&&o(p.outline)&&p.outline.getValue(n)){f.vertexFormat=v.VERTEX_FORMAT;var I=E.getValueOrClonedDefault(p.outlineColor,n,e.BLACK,k),O=E.getValueOrDefault(p.outlineWidth,n,1),M=1!==I.alpha;this._outlinePrimitive=l.add(new y({geometryInstances:new h({id:d,geometry:new i(f),attributes:{color:t.fromColor(I),distanceDisplayCondition:w}}),appearance:new v({flat:!0,translucent:M,renderState:{lineWidth:a._scene.clampLineWidth(O)}}),asynchronous:!1,shadows:C}))}}}},P.prototype.getBoundingSphere=function(e,t){return w(e,this._primitive,this._outlinePrimitive,t)},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){var e=this._primitives,t=this._groundPrimitives;this._geometryUpdater._onTerrain?t.removeAndDestroy(this._primitive):e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),s(this)},x}),define("DataSources/DataSource",["../Core/defineProperties","../Core/DeveloperError"],function(e,t){"use strict";function r(){t.throwInstantiationError()}return e(r.prototype,{name:{get:t.throwInstantiationError},clock:{get:t.throwInstantiationError},entities:{get:t.throwInstantiationError},isLoading:{get:t.throwInstantiationError},changedEvent:{get:t.throwInstantiationError},errorEvent:{get:t.throwInstantiationError},loadingEvent:{get:t.throwInstantiationError},show:{get:t.throwInstantiationError},clustering:{get:t.throwInstantiationError}}),r.prototype.update=t.throwInstantiationError,r.setLoading=function(e,t){e._isLoading!==t&&(t?e._entityCollection.suspendEvents():e._entityCollection.resumeEvents(),e._isLoading=t,e._loading.raiseEvent(e,t))},r}),define("Scene/SceneTransforms",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/defined","../Core/DeveloperError","../Core/Math","../Core/Matrix4","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/Transforms","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e,t,n,o){var a=n.viewMatrix,s=l.multiplyByVector(a,i.fromElements(e.x,e.y,e.z,1,b),b),u=r.multiplyComponents(t,r.normalize(s,C),C);return s.x+=t.x+u.x,s.y+=t.y+u.y,s.z+=u.z,l.multiplyByVector(n.frustum.projectionMatrix,s,o)}var f={},m=new i(0,0,0,1),g=new i,_=new e,v=new t,y=new t;f.wgs84ToWindowCoordinates=function(e,t,i){return f.wgs84WithEyeOffsetToWindowCoordinates(e,t,r.ZERO,i)};var b=new i,C=new r,S=new n(Math.PI,s.PI_OVER_TWO),w=new r,T=new r;f.wgs84WithEyeOffsetToWindowCoordinates=function(e,i,n,a){var b=e.frameState,C=f.computeActualWgs84Position(b,i,m);if(o(C)){var E=e.canvas,A=_;A.x=0,A.y=0,A.width=E.clientWidth,A.height=E.clientHeight;var x=e.camera,P=!1;if(b.mode===h.SCENE2D){var D=e.mapProjection,I=S,O=D.project(I,w),M=r.clone(x.position,T),R=x.frustum.clone(),L=l.computeViewportTransformation(A,0,1,new l),N=x.frustum.projectionMatrix,k=x.positionWC.y,F=r.fromElements(s.sign(k)*O.x-k,0,-x.positionWC.x),B=d.pointToGLWindowCoordinates(N,L,F);if(0===k||B.x<=0||B.x>=E.clientWidth)P=!0;else{if(B.x>.5*E.clientWidth){A.width=B.x,x.frustum.right=O.x-k,g=p(C,n,x,g),f.clipToGLWindowCoordinates(A,g,v),A.x+=B.x,x.position.x=-x.position.x;var U=x.frustum.right;x.frustum.right=-x.frustum.left,x.frustum.left=-U,g=p(C,n,x,g),f.clipToGLWindowCoordinates(A,g,y)}else{A.x+=B.x,A.width-=B.x,x.frustum.left=-O.x-k,g=p(C,n,x,g),f.clipToGLWindowCoordinates(A,g,v),A.x=A.x-A.width,x.position.x=-x.position.x;var V=x.frustum.left;x.frustum.left=-x.frustum.right,x.frustum.right=-V,g=p(C,n,x,g),f.clipToGLWindowCoordinates(A,g,y)}r.clone(M,x.position),x.frustum=R.clone(),a=t.clone(v,a),(a.x<0||a.x>E.clientWidth)&&(a.x=y.x)}}if(b.mode!==h.SCENE2D||P){if(g=p(C,n,x,g),g.z<0&&!(x.frustum instanceof u)&&!(x.frustum instanceof c))return;a=f.clipToGLWindowCoordinates(A,g,a)}return a.y=E.clientHeight-a.y,a}},f.wgs84ToDrawingBufferCoordinates=function(e,t,r){if(r=f.wgs84ToWindowCoordinates(e,t,r),o(r))return f.transformWindowToDrawingBuffer(e,r,r)};var E=new r,A=new n;f.computeActualWgs84Position=function(e,t,i){var n=e.mode;if(n===h.SCENE3D)return r.clone(t,i);var a=e.mapProjection,l=a.ellipsoid.cartesianToCartographic(t,A);if(o(l)){if(a.project(l,E),n===h.COLUMBUS_VIEW)return r.fromElements(E.z,E.x,E.y,i);if(n===h.SCENE2D)return r.fromElements(0,E.x,E.y,i);var u=e.morphTime;return r.fromElements(s.lerp(E.z,t.x,u),s.lerp(E.x,t.y,u),s.lerp(E.y,t.z,u),i)}};var x=new r,P=new r,D=new l;f.clipToGLWindowCoordinates=function(e,i,n){return r.divideByScalar(i,i.w,x),l.computeViewportTransformation(e,0,1,D),l.multiplyByPoint(D,x,P),t.fromCartesian3(P,n)},f.transformWindowToDrawingBuffer=function(e,r,i){var n=e.canvas,o=e.drawingBufferWidth/n.clientWidth,a=e.drawingBufferHeight/n.clientHeight;return t.fromElements(r.x*o,r.y*a,i)};var I=new i,O=new i;return f.drawingBufferToWgs84Coordinates=function(e,t,n,a){var s=e.context,u=s.uniformState,c=e._passState.viewport,d=i.clone(i.UNIT_W,I);d.x=(t.x-c.x)/c.width*2-1,d.y=(t.y-c.y)/c.height*2-1,d.z=2*n-1,d.w=1;var h,p=e.camera.frustum;if(o(p.fovy)){h=l.multiplyByVector(u.inverseViewProjection,d,O);var f=1/h.w;r.multiplyByScalar(h,f,h)}else{o(p._offCenterFrustum)&&(p=p._offCenterFrustum);var m=u.currentFrustum;h=O,h.x=.5*(d.x*(p.right-p.left)+p.left+p.right),h.y=.5*(d.y*(p.top-p.bottom)+p.bottom+p.top),h.z=.5*(d.z*(m.x-m.y)-m.x-m.y),h.w=1,h=l.multiplyByVector(u.inverseView,h,h)}return r.fromCartesian4(h,a)},f}),define("Scene/Billboard",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Matrix4","../Core/NearFarScalar","../Core/Resource","./HeightReference","./HorizontalOrigin","./SceneMode","./SceneTransforms","./VerticalOrigin"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(e,i){e=s(e,s.EMPTY_OBJECT);var n=e.translucencyByDistance,u=e.pixelOffsetScaleByDistance,c=e.scaleByDistance,h=e.distanceDisplayCondition;l(n)&&(n=p.clone(n)),l(u)&&(u=p.clone(u)),l(c)&&(c=p.clone(c)),l(h)&&(h=d.clone(h)),this._show=s(e.show,!0),this._position=r.clone(s(e.position,r.ZERO)),this._actualPosition=r.clone(this._position),this._pixelOffset=t.clone(s(e.pixelOffset,t.ZERO)),this._translate=new t(0,0),this._eyeOffset=r.clone(s(e.eyeOffset,r.ZERO)),this._heightReference=s(e.heightReference,m.NONE),this._verticalOrigin=s(e.verticalOrigin,y.CENTER),this._horizontalOrigin=s(e.horizontalOrigin,g.CENTER),this._scale=s(e.scale,1),this._color=o.clone(s(e.color,o.WHITE)),this._rotation=s(e.rotation,0),this._alignedAxis=r.clone(s(e.alignedAxis,r.ZERO)),this._width=e.width,this._height=e.height,this._scaleByDistance=c,this._translucencyByDistance=n,this._pixelOffsetScaleByDistance=u,this._sizeInMeters=s(e.sizeInMeters,!1),this._distanceDisplayCondition=h,this._disableDepthTestDistance=s(e.disableDepthTestDistance,0),this._id=e.id,this._collection=s(e.collection,i),this._pickId=void 0,this._pickPrimitive=s(e._pickPrimitive,this),this._billboardCollection=i,this._dirty=!1,this._index=-1,this._batchIndex=void 0,this._imageIndex=-1,this._imageIndexPromise=void 0,this._imageId=void 0,this._image=void 0,this._imageSubRegion=void 0,this._imageWidth=void 0,this._imageHeight=void 0;var f=e.image,v=e.imageId;l(f)&&(l(v)||(v="string"==typeof f?f:l(f.src)?f.src:a()),this._imageId=v,this._image=f),l(e.imageSubRegion)&&(this._imageId=v,this._imageSubRegion=e.imageSubRegion),l(this._billboardCollection._textureAtlas)&&this._loadImage(),this._actualClampedPosition=void 0,this._removeCallbackFunc=void 0,this._mode=_.SCENE3D,this._clusterShow=!0,this._updateClamping()}function C(e,t){var r=e._billboardCollection;l(r)&&(r._updateBillboard(e,t),e._dirty=!0)}var S=b.SHOW_INDEX=0,w=b.POSITION_INDEX=1,T=b.PIXEL_OFFSET_INDEX=2,E=b.EYE_OFFSET_INDEX=3,A=b.HORIZONTAL_ORIGIN_INDEX=4,x=b.VERTICAL_ORIGIN_INDEX=5,P=b.SCALE_INDEX=6,D=b.IMAGE_INDEX_INDEX=7,I=b.COLOR_INDEX=8,O=b.ROTATION_INDEX=9,M=b.ALIGNED_AXIS_INDEX=10,R=b.SCALE_BY_DISTANCE_INDEX=11,L=b.TRANSLUCENCY_BY_DISTANCE_INDEX=12,N=b.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX=13,k=b.DISTANCE_DISPLAY_CONDITION=14,F=b.DISABLE_DEPTH_DISTANCE=15;b.NUMBER_OF_PROPERTIES=16,u(b.prototype,{show:{get:function(){return this._show},set:function(e){this._show!==e&&(this._show=e,C(this,S))}},position:{get:function(){return this._position},set:function(e){var t=this._position;r.equals(t,e)||(r.clone(e,t),r.clone(e,this._actualPosition),this._updateClamping(),C(this,w))}},heightReference:{get:function(){return this._heightReference},set:function(e){e!==this._heightReference&&(this._heightReference=e,this._updateClamping(),C(this,w))}},pixelOffset:{get:function(){return this._pixelOffset},set:function(e){var r=this._pixelOffset;t.equals(r,e)||(t.clone(e,r),C(this,T))}},scaleByDistance:{get:function(){return this._scaleByDistance},set:function(e){var t=this._scaleByDistance;p.equals(t,e)||(this._scaleByDistance=p.clone(e,t),C(this,R))}},translucencyByDistance:{get:function(){return this._translucencyByDistance},set:function(e){var t=this._translucencyByDistance;p.equals(t,e)||(this._translucencyByDistance=p.clone(e,t),C(this,L))}},pixelOffsetScaleByDistance:{get:function(){return this._pixelOffsetScaleByDistance},set:function(e){var t=this._pixelOffsetScaleByDistance;p.equals(t,e)||(this._pixelOffsetScaleByDistance=p.clone(e,t),C(this,N))}},eyeOffset:{get:function(){return this._eyeOffset},set:function(e){var t=this._eyeOffset;r.equals(t,e)||(r.clone(e,t),C(this,E))}},horizontalOrigin:{get:function(){return this._horizontalOrigin},set:function(e){this._horizontalOrigin!==e&&(this._horizontalOrigin=e,C(this,A))}},verticalOrigin:{get:function(){return this._verticalOrigin},set:function(e){this._verticalOrigin!==e&&(this._verticalOrigin=e,C(this,x))}},scale:{get:function(){return this._scale},set:function(e){this._scale!==e&&(this._scale=e,C(this,P))}},color:{get:function(){return this._color},set:function(e){var t=this._color;o.equals(t,e)||(o.clone(e,t),C(this,I))}},rotation:{get:function(){return this._rotation},set:function(e){this._rotation!==e&&(this._rotation=e,C(this,O))}},alignedAxis:{get:function(){return this._alignedAxis},set:function(e){var t=this._alignedAxis;r.equals(t,e)||(r.clone(e,t),C(this,M))}},width:{get:function(){return s(this._width,this._imageWidth)},set:function(e){this._width!==e&&(this._width=e,C(this,D))}},height:{get:function(){return s(this._height,this._imageHeight)},set:function(e){this._height!==e&&(this._height=e,C(this,D))}},sizeInMeters:{get:function(){return this._sizeInMeters},set:function(e){this._sizeInMeters!==e&&(this._sizeInMeters=e,C(this,I))}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){d.equals(e,this._distanceDisplayCondition)||(this._distanceDisplayCondition=d.clone(e,this._distanceDisplayCondition),C(this,k))}},disableDepthTestDistance:{get:function(){return this._disableDepthTestDistance},set:function(e){this._disableDepthTestDistance!==e&&(this._disableDepthTestDistance=e,C(this,F))}},id:{get:function(){return this._id},set:function(e){this._id=e,l(this._pickId)&&(this._pickId.object.id=e)}},pickPrimitive:{get:function(){return this._pickPrimitive},set:function(e){this._pickPrimitive=e,l(this._pickId)&&(this._pickId.object.primitive=e)}},image:{get:function(){return this._imageId},set:function(e){l(e)?"string"==typeof e?this.setImage(e,e):e instanceof f?this.setImage(e.url,e):l(e.src)?this.setImage(e.src,e):this.setImage(a(),e):(this._imageIndex=-1,this._imageSubRegion=void 0,this._imageId=void 0,this._image=void 0,this._imageIndexPromise=void 0,C(this,D))}},ready:{get:function(){return-1!==this._imageIndex}},_clampedPosition:{get:function(){return this._actualClampedPosition},set:function(e){this._actualClampedPosition=r.clone(e,this._actualClampedPosition),C(this,w)}},clusterShow:{get:function(){return this._clusterShow},set:function(e){this._clusterShow!==e&&(this._clusterShow=e,C(this,S))}}}),b.prototype.getPickId=function(e){return l(this._pickId)||(this._pickId=e.createPickId({primitive:this._pickPrimitive,collection:this._collection,id:this._id})),this._pickId},b.prototype._updateClamping=function(){b._updateClamping(this._billboardCollection,this)};var B=new n,U=new r;b._updateClamping=function(e,t){function i(e){if(t._heightReference===m.RELATIVE_TO_GROUND)if(t._mode===_.SCENE3D){var i=s.cartesianToCartographic(e,B);i.height+=h.height,s.cartographicToCartesian(i,e)}else e.x+=h.height;t._clampedPosition=r.clone(e,t._clampedPosition)}var o=e._scene;if(l(o)&&l(o.globe)){var a=o.globe,s=a.ellipsoid,u=a._surface,c=o.frameState.mode,d=c!==t._mode;if(t._mode=c,(t._heightReference===m.NONE||d)&&l(t._removeCallbackFunc)&&(t._removeCallbackFunc(),t._removeCallbackFunc=void 0,t._clampedPosition=void 0),t._heightReference!==m.NONE&&l(t._position)){var h=s.cartesianToCartographic(t._position);if(!l(h))return void(t._actualClampedPosition=void 0);l(t._removeCallbackFunc)&&t._removeCallbackFunc(),t._removeCallbackFunc=u.updateHeight(h,i),n.clone(h,B);var p=a.getHeight(h);l(p)&&(B.height=p),s.cartographicToCartesian(B,U),i(U)}}},b.prototype._loadImage=function(){var t,r=this._billboardCollection._textureAtlas,i=this._imageId,n=this._image,o=this._imageSubRegion +;if(l(n)&&(t=r.addImage(i,n)),l(o)&&(t=r.addSubRegion(i,o)),this._imageIndexPromise=t,l(t)){var a=this;t.then(function(t){if(a._imageId===i&&a._image===n&&e.equals(a._imageSubRegion,o)){var s=r.textureCoordinates[t];a._imageWidth=r.texture.width*s.width,a._imageHeight=r.texture.height*s.height,a._imageIndex=t,a._ready=!0,a._image=void 0,a._imageIndexPromise=void 0,C(a,D)}}).otherwise(function(e){console.error("Error loading image for billboard: "+e),a._imageIndexPromise=void 0})}},b.prototype.setImage=function(e,t){this._imageId!==e&&(this._imageIndex=-1,this._imageSubRegion=void 0,this._imageId=e,this._image=t,l(this._billboardCollection._textureAtlas)&&this._loadImage())},b.prototype.setImageSubRegion=function(t,r){this._imageId===t&&e.equals(this._imageSubRegion,r)||(this._imageIndex=-1,this._imageId=t,this._imageSubRegion=e.clone(r),l(this._billboardCollection._textureAtlas)&&this._loadImage())},b.prototype._setTranslate=function(e){var r=this._translate;t.equals(r,e)||(t.clone(e,r),C(this,T))},b.prototype._getActualPosition=function(){return l(this._clampedPosition)?this._clampedPosition:this._actualPosition},b.prototype._setActualPosition=function(e){l(this._clampedPosition)||r.clone(e,this._actualPosition),C(this,w)};var V=new i;b._computeActualPosition=function(e,t,r,i){return l(e._clampedPosition)?(r.mode!==e._mode&&e._updateClamping(),e._clampedPosition):r.mode===_.SCENE3D?t:(h.multiplyByPoint(i,t,V),v.computeActualWgs84Position(r,V))};var z=new r;b._computeScreenSpacePosition=function(e,r,i,n,o,a){var s=h.multiplyByPoint(e,r,z),u=v.wgs84WithEyeOffsetToWindowCoordinates(o,s,i,a);if(l(u))return t.add(u,n,u),u};var G=new t(0,0);return b.prototype.computeScreenSpacePosition=function(e,r){var i=this._billboardCollection;l(r)||(r=new t),t.clone(this._pixelOffset,G),t.add(G,this._translate,G);var n=i.modelMatrix,o=this._position;if(l(this._clampedPosition)&&(o=this._clampedPosition,e.mode!==_.SCENE3D)){var a=e.mapProjection,s=a.ellipsoid,u=a.unproject(o,B);o=s.cartographicToCartesian(u,z),n=h.IDENTITY}return b._computeScreenSpacePosition(n,o,this._eyeOffset,G,e,r)},b.getScreenSpaceBoundingBox=function(t,r,i){var n=t.width,o=t.height,a=t.scale;n*=a,o*=a;var s=r.x;t.horizontalOrigin===g.RIGHT?s-=n:t.horizontalOrigin===g.CENTER&&(s-=.5*n);var u=r.y;return t.verticalOrigin===y.BOTTOM||t.verticalOrigin===y.BASELINE?u-=o:t.verticalOrigin===y.CENTER&&(u-=.5*o),l(i)||(i=new e),i.x=s,i.y=u,i.width=n,i.height=o,i},b.prototype.equals=function(i){return this===i||l(i)&&this._id===i._id&&r.equals(this._position,i._position)&&this._imageId===i._imageId&&this._show===i._show&&this._scale===i._scale&&this._verticalOrigin===i._verticalOrigin&&this._horizontalOrigin===i._horizontalOrigin&&this._heightReference===i._heightReference&&e.equals(this._imageSubRegion,i._imageSubRegion)&&o.equals(this._color,i._color)&&t.equals(this._pixelOffset,i._pixelOffset)&&t.equals(this._translate,i._translate)&&r.equals(this._eyeOffset,i._eyeOffset)&&p.equals(this._scaleByDistance,i._scaleByDistance)&&p.equals(this._translucencyByDistance,i._translucencyByDistance)&&p.equals(this._pixelOffsetScaleByDistance,i._pixelOffsetScaleByDistance)&&d.equals(this._distanceDisplayCondition,i._distanceDisplayCondition)&&this._disableDepthTestDistance===i._disableDepthTestDistance},b.prototype._destroy=function(){l(this._customData)&&(this._billboardCollection._scene.globe._surface.removeTileCustomData(this._customData),this._customData=void 0),l(this._removeCallbackFunc)&&(this._removeCallbackFunc(),this._removeCallbackFunc=void 0),this.image=void 0,this._pickId=this._pickId&&this._pickId.destroy(),this._billboardCollection=void 0},b}),define("Renderer/VertexArrayFacade",["../Core/Check","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Math","./Buffer","./BufferUsage","./VertexArray"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,n,o,a){function s(e,r){return t.getSizeInBytes(r.componentDatatype)-t.getSizeInBytes(e.componentDatatype)}var l=c._verifyAttributes(n);o=r(o,0);for(var u,d,h=[],p={},f=l.length,m=0;m<f;++m){var g=l[m];g.vertexBuffer?h.push(g):(d=g.usage,u=p[d],i(u)||(u=p[d]=[]),u.push(g))}this._allBuffers=[];for(d in p)if(p.hasOwnProperty(d)){u=p[d],u.sort(s);var _=c._vertexSizeInBytes(u),v=u[0].usage,y={vertexSizeInBytes:_,vertexBuffer:void 0,usage:v,needsCommit:!1,arrayBuffer:void 0,arrayViews:c._createArrayViews(u,_)};this._allBuffers.push(y)}this._size=0,this._instanced=r(a,!1),this._precreated=h,this._context=e,this.writers=void 0,this.va=void 0,this.resize(o)}function d(e,t){if(t.needsCommit&&t.vertexSizeInBytes>0){t.needsCommit=!1;var r=t.vertexBuffer,n=e._size*t.vertexSizeInBytes,o=i(r);if(!o||r.sizeInBytes<n)return o&&r.destroy(),t.vertexBuffer=s.createVertexBuffer({context:e._context,typedArray:t.arrayBuffer,usage:t.usage}),t.vertexBuffer.vertexArrayDestroyable=!1,!0;t.vertexBuffer.copyFromArrayView(t.arrayBuffer)}return!1}function h(e,t,r){if(e.needsCommit&&e.vertexSizeInBytes>0){var i=e.vertexSizeInBytes*t,n=e.vertexSizeInBytes*r;e.vertexBuffer.copyFromArrayView(new Uint8Array(e.arrayBuffer,i,n),i)}}function p(e){var t=e.va;if(i(t)){for(var r=t.length,n=0;n<r;++n)t[n].va.destroy();e.va=void 0}}c._verifyAttributes=function(e){for(var i=[],n=0;n<e.length;++n){var o=e[n],a={index:r(o.index,n),enabled:r(o.enabled,!0),componentsPerAttribute:o.componentsPerAttribute,componentDatatype:r(o.componentDatatype,t.FLOAT),normalize:r(o.normalize,!1),vertexBuffer:o.vertexBuffer,usage:r(o.usage,l.STATIC_DRAW)};i.push(a)}for(var s=new Array(i.length),u=0;u<i.length;++u){s[i[u].index]=!0}return i},c._vertexSizeInBytes=function(e){for(var r=0,i=e.length,n=0;n<i;++n){var o=e[n];r+=o.componentsPerAttribute*t.getSizeInBytes(o.componentDatatype)}var a=i>0?t.getSizeInBytes(e[0].componentDatatype):0,s=a>0?r%a:0;return r+=0===s?0:a-s},c._createArrayViews=function(e,r){for(var i=[],n=0,o=e.length,a=0;a<o;++a){var s=e[a],l=s.componentDatatype;i.push({index:s.index,enabled:s.enabled,componentsPerAttribute:s.componentsPerAttribute,componentDatatype:l,normalize:s.normalize,offsetInBytes:n,vertexSizeInComponentType:r/t.getSizeInBytes(l),view:void 0}),n+=s.componentsPerAttribute*t.getSizeInBytes(l)}return i},c.prototype.resize=function(e){this._size=e;var t=this._allBuffers;this.writers=[];for(var r=0,i=t.length;r<i;++r){var n=t[r];c._resize(n,this._size),c._appendWriters(this.writers,n)}p(this)},c._resize=function(e,r){if(e.vertexSizeInBytes>0){var n=new ArrayBuffer(r*e.vertexSizeInBytes);if(i(e.arrayBuffer))for(var o=new Uint8Array(n),a=new Uint8Array(e.arrayBuffer),s=a.length,l=0;l<s;++l)o[l]=a[l];for(var u=e.arrayViews,c=u.length,d=0;d<c;++d){var h=u[d];h.view=t.createArrayBufferView(h.componentDatatype,n,h.offsetInBytes)}e.arrayBuffer=n}};var f=[function(e,t,r){return function(i,n){t[i*r]=n,e.needsCommit=!0}},function(e,t,r){return function(i,n,o){var a=i*r;t[a]=n,t[a+1]=o,e.needsCommit=!0}},function(e,t,r){return function(i,n,o,a){var s=i*r;t[s]=n,t[s+1]=o,t[s+2]=a,e.needsCommit=!0}},function(e,t,r){return function(i,n,o,a,s){var l=i*r;t[l]=n,t[l+1]=o,t[l+2]=a,t[l+3]=s,e.needsCommit=!0}}];return c._appendWriters=function(e,t){for(var r=t.arrayViews,i=r.length,n=0;n<i;++n){var o=r[n];e[o.index]=f[o.componentsPerAttribute-1](t,o.view,o.vertexSizeInComponentType)}},c.prototype.commit=function(e){var t,r,n,o=!1,s=this._allBuffers;for(r=0,n=s.length;r<n;++r)t=s[r],o=d(this,t)||o;if(o||!i(this.va)){p(this);for(var l=this.va=[],h=i(e)?Math.ceil(this._size/(a.SIXTY_FOUR_KILOBYTES-1)):1,f=0;f<h;++f){var m=[];for(r=0,n=s.length;r<n;++r){t=s[r];var g=f*(t.vertexSizeInBytes*(a.SIXTY_FOUR_KILOBYTES-1));c._appendAttributes(m,t,g,this._instanced)}m=m.concat(this._precreated),l.push({va:new u({context:this._context,attributes:m,indexBuffer:e}),indicesCount:1.5*(f!==h-1?a.SIXTY_FOUR_KILOBYTES-1:this._size%(a.SIXTY_FOUR_KILOBYTES-1))})}}},c._appendAttributes=function(e,t,r,i){for(var n=t.arrayViews,o=n.length,a=0;a<o;++a){var s=n[a];e.push({index:s.index,enabled:s.enabled,componentsPerAttribute:s.componentsPerAttribute,componentDatatype:s.componentDatatype,normalize:s.normalize,vertexBuffer:t.vertexBuffer,offsetInBytes:r+s.offsetInBytes,strideInBytes:t.vertexSizeInBytes,instanceDivisor:i?1:0})}},c.prototype.subCommit=function(e,t){for(var r=this._allBuffers,i=0,n=r.length;i<n;++i)h(r[i],e,t)},c.prototype.endSubCommits=function(){for(var e=this._allBuffers,t=0,r=e.length;t<r;++t)e[t].needsCommit=!1},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){for(var e=this._allBuffers,t=0,r=e.length;t<r;++t){var i=e[t];i.vertexBuffer=i.vertexBuffer&&i.vertexBuffer.destroy()}return p(this),n(this)},c}),define("Shaders/BillboardCollectionFS",[],function(){"use strict";return"uniform sampler2D u_atlas;\n#ifdef VECTOR_TILE\nuniform vec4 u_highlightColor;\n#endif\nvarying vec2 v_textureCoordinates;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#else\nvarying vec4 v_color;\n#endif\nvoid main()\n{\n#ifdef RENDER_FOR_PICK\nvec4 vertexColor = vec4(1.0, 1.0, 1.0, 1.0);\n#else\nvec4 vertexColor = v_color;\n#endif\nvec4 color = texture2D(u_atlas, v_textureCoordinates) * vertexColor;\n#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\nif (color.a < 0.005)\n{\ndiscard;\n}\n#else\n#ifdef OPAQUE\nif (color.a < 0.995)\n{\ndiscard;\n}\n#else\nif (color.a >= 0.995)\n{\ndiscard;\n}\n#endif\n#endif\n#ifdef VECTOR_TILE\ncolor *= u_highlightColor;\n#endif\n#ifdef RENDER_FOR_PICK\ngl_FragColor = v_pickColor;\n#else\ngl_FragColor = color;\n#endif\n}\n"}),define("Shaders/BillboardCollectionVS",[],function(){"use strict";return"#ifdef INSTANCED\nattribute vec2 direction;\n#endif\nattribute vec4 positionHighAndScale;\nattribute vec4 positionLowAndRotation;\nattribute vec4 compressedAttribute0;\nattribute vec4 compressedAttribute1;\nattribute vec4 compressedAttribute2;\nattribute vec4 eyeOffset;\nattribute vec4 scaleByDistance;\nattribute vec4 pixelOffsetScaleByDistance;\nattribute vec3 distanceDisplayConditionAndDisableDepth;\n#ifdef VECTOR_TILE\nattribute float a_batchId;\n#endif\nvarying vec2 v_textureCoordinates;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#else\nvarying vec4 v_color;\n#endif\nconst float UPPER_BOUND = 32768.0;\nconst float SHIFT_LEFT16 = 65536.0;\nconst float SHIFT_LEFT8 = 256.0;\nconst float SHIFT_LEFT7 = 128.0;\nconst float SHIFT_LEFT5 = 32.0;\nconst float SHIFT_LEFT3 = 8.0;\nconst float SHIFT_LEFT2 = 4.0;\nconst float SHIFT_LEFT1 = 2.0;\nconst float SHIFT_RIGHT8 = 1.0 / 256.0;\nconst float SHIFT_RIGHT7 = 1.0 / 128.0;\nconst float SHIFT_RIGHT5 = 1.0 / 32.0;\nconst float SHIFT_RIGHT3 = 1.0 / 8.0;\nconst float SHIFT_RIGHT2 = 1.0 / 4.0;\nconst float SHIFT_RIGHT1 = 1.0 / 2.0;\nvec4 computePositionWindowCoordinates(vec4 positionEC, vec2 imageSize, float scale, vec2 direction, vec2 origin, vec2 translate, vec2 pixelOffset, vec3 alignedAxis, bool validAlignedAxis, float rotation, bool sizeInMeters)\n{\nvec2 halfSize = imageSize * scale * czm_resolutionScale * 0.5;\nhalfSize *= ((direction * 2.0) - 1.0);\nvec2 originTranslate = origin * abs(halfSize);\n#if defined(ROTATION) || defined(ALIGNED_AXIS)\nif (validAlignedAxis || rotation != 0.0)\n{\nfloat angle = rotation;\nif (validAlignedAxis)\n{\nvec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0);\nangle += sign(-projectedAlignedAxis.x) * acos( sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) /\n(projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y) );\n}\nfloat cosTheta = cos(angle);\nfloat sinTheta = sin(angle);\nmat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta);\nhalfSize = rotationMatrix * halfSize;\n}\n#endif\nif (sizeInMeters)\n{\npositionEC.xy += halfSize;\n}\nvec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\nif (sizeInMeters)\n{\noriginTranslate /= czm_metersPerPixel(positionEC);\n}\npositionWC.xy += originTranslate;\nif (!sizeInMeters)\n{\npositionWC.xy += halfSize;\n}\npositionWC.xy += translate;\npositionWC.xy += (pixelOffset * czm_resolutionScale);\nreturn positionWC;\n}\nvoid main()\n{\nvec3 positionHigh = positionHighAndScale.xyz;\nvec3 positionLow = positionLowAndRotation.xyz;\nfloat scale = positionHighAndScale.w;\n#if defined(ROTATION) || defined(ALIGNED_AXIS)\nfloat rotation = positionLowAndRotation.w;\n#else\nfloat rotation = 0.0;\n#endif\nfloat compressed = compressedAttribute0.x;\nvec2 pixelOffset;\npixelOffset.x = floor(compressed * SHIFT_RIGHT7);\ncompressed -= pixelOffset.x * SHIFT_LEFT7;\npixelOffset.x -= UPPER_BOUND;\nvec2 origin;\norigin.x = floor(compressed * SHIFT_RIGHT5);\ncompressed -= origin.x * SHIFT_LEFT5;\norigin.y = floor(compressed * SHIFT_RIGHT3);\ncompressed -= origin.y * SHIFT_LEFT3;\norigin -= vec2(1.0);\nfloat show = floor(compressed * SHIFT_RIGHT2);\ncompressed -= show * SHIFT_LEFT2;\n#ifdef INSTANCED\nvec2 textureCoordinatesBottomLeft = czm_decompressTextureCoordinates(compressedAttribute0.w);\nvec2 textureCoordinatesRange = czm_decompressTextureCoordinates(eyeOffset.w);\nvec2 textureCoordinates = textureCoordinatesBottomLeft + direction * textureCoordinatesRange;\n#else\nvec2 direction;\ndirection.x = floor(compressed * SHIFT_RIGHT1);\ndirection.y = compressed - direction.x * SHIFT_LEFT1;\nvec2 textureCoordinates = czm_decompressTextureCoordinates(compressedAttribute0.w);\n#endif\nfloat temp = compressedAttribute0.y * SHIFT_RIGHT8;\npixelOffset.y = -(floor(temp) - UPPER_BOUND);\nvec2 translate;\ntranslate.y = (temp - floor(temp)) * SHIFT_LEFT16;\ntemp = compressedAttribute0.z * SHIFT_RIGHT8;\ntranslate.x = floor(temp) - UPPER_BOUND;\ntranslate.y += (temp - floor(temp)) * SHIFT_LEFT8;\ntranslate.y -= UPPER_BOUND;\ntemp = compressedAttribute1.x * SHIFT_RIGHT8;\nvec2 imageSize = vec2(floor(temp), compressedAttribute2.w);\n#ifdef EYE_DISTANCE_TRANSLUCENCY\nvec4 translucencyByDistance;\ntranslucencyByDistance.x = compressedAttribute1.z;\ntranslucencyByDistance.z = compressedAttribute1.w;\ntranslucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\ntemp = compressedAttribute1.y * SHIFT_RIGHT8;\ntranslucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n#endif\n#ifdef ALIGNED_AXIS\nvec3 alignedAxis = czm_octDecode(floor(compressedAttribute1.y * SHIFT_RIGHT8));\ntemp = compressedAttribute2.z * SHIFT_RIGHT5;\nbool validAlignedAxis = (temp - floor(temp)) * SHIFT_LEFT1 > 0.0;\n#else\nvec3 alignedAxis = vec3(0.0);\nbool validAlignedAxis = false;\n#endif\n#ifdef RENDER_FOR_PICK\ntemp = compressedAttribute2.y;\n#else\ntemp = compressedAttribute2.x;\n#endif\nvec4 color;\ntemp = temp * SHIFT_RIGHT8;\ncolor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\ncolor.g = (temp - floor(temp)) * SHIFT_LEFT8;\ncolor.r = floor(temp);\ntemp = compressedAttribute2.z * SHIFT_RIGHT8;\nbool sizeInMeters = floor((temp - floor(temp)) * SHIFT_LEFT7) > 0.0;\ntemp = floor(temp) * SHIFT_RIGHT8;\n#ifdef RENDER_FOR_PICK\ncolor.a = (temp - floor(temp)) * SHIFT_LEFT8;\nvec4 pickColor = color / 255.0;\n#else\ncolor.a = floor(temp);\ncolor /= 255.0;\n#endif\nvec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\nvec4 positionEC = czm_modelViewRelativeToEye * p;\npositionEC = czm_eyeOffset(positionEC, eyeOffset.xyz);\npositionEC.xyz *= show;\n#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(EYE_DISTANCE_PIXEL_OFFSET) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\nfloat lengthSq;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nlengthSq = czm_eyeHeight2D.y;\n}\nelse\n{\nlengthSq = dot(positionEC.xyz, positionEC.xyz);\n}\n#endif\n#ifdef EYE_DISTANCE_SCALING\nfloat distanceScale = czm_nearFarScalar(scaleByDistance, lengthSq);\nscale *= distanceScale;\ntranslate *= distanceScale;\nif (scale == 0.0)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\nfloat translucency = 1.0;\n#ifdef EYE_DISTANCE_TRANSLUCENCY\ntranslucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\nif (translucency == 0.0)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\n#ifdef EYE_DISTANCE_PIXEL_OFFSET\nfloat pixelOffsetScale = czm_nearFarScalar(pixelOffsetScaleByDistance, lengthSq);\npixelOffset *= pixelOffsetScale;\n#endif\n#ifdef DISTANCE_DISPLAY_CONDITION\nfloat nearSq = distanceDisplayConditionAndDisableDepth.x;\nfloat farSq = distanceDisplayConditionAndDisableDepth.y;\nif (lengthSq < nearSq || lengthSq > farSq)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\nvec4 positionWC = computePositionWindowCoordinates(positionEC, imageSize, scale, direction, origin, translate, pixelOffset, alignedAxis, validAlignedAxis, rotation, sizeInMeters);\ngl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\nv_textureCoordinates = textureCoordinates;\n#ifdef DISABLE_DEPTH_DISTANCE\nfloat disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\nif (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n{\ndisableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n}\nif (disableDepthTestDistance != 0.0)\n{\nfloat zclip = gl_Position.z / gl_Position.w;\nbool clipped = (zclip < -1.0 || zclip > 1.0);\nif (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n{\ngl_Position.z = -gl_Position.w;\n}\n}\n#endif\n#ifdef RENDER_FOR_PICK\nv_pickColor = pickColor;\n#else\nv_color = color;\nv_color.a *= translucency;\n#endif\n}\n"}),define("Scene/BlendOption",["../Core/freezeObject"],function(e){"use strict";return e({OPAQUE:0,TRANSLUCENT:1,OPAQUE_AND_TRANSLUCENT:2})}),define("Renderer/Framebuffer",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/PixelFormat","./ContextLimits"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r){var i=e._gl;i.framebufferTexture2D(i.FRAMEBUFFER,t,r._target,r._texture,0)}function u(e,t,r){var i=e._gl;i.framebufferRenderbuffer(i.FRAMEBUFFER,t,i.RENDERBUFFER,r._getRenderbuffer())}function c(e){e=t(e,t.EMPTY_OBJECT);var i=e.context._gl;s.maximumColorAttachments;this._gl=i,this._framebuffer=i.createFramebuffer(),this._colorTextures=[],this._colorRenderbuffers=[],this._activeColorAttachments=[],this._depthTexture=void 0,this._depthRenderbuffer=void 0,this._stencilRenderbuffer=void 0,this._depthStencilTexture=void 0,this._depthStencilRenderbuffer=void 0,this.destroyAttachments=t(e.destroyAttachments,!0);r(e.depthTexture)||r(e.depthRenderbuffer),r(e.depthStencilTexture)||r(e.depthStencilRenderbuffer);this._bind();var n,o,a,c,d;if(r(e.colorTextures)){var h=e.colorTextures;for(c=this._colorTextures.length=this._activeColorAttachments.length=h.length,a=0;a<c;++a)n=h[a],d=this._gl.COLOR_ATTACHMENT0+a,l(this,d,n),this._activeColorAttachments[a]=d,this._colorTextures[a]=n}if(r(e.colorRenderbuffers)){var p=e.colorRenderbuffers;for(c=this._colorRenderbuffers.length=this._activeColorAttachments.length=p.length,a=0;a<c;++a)o=p[a],d=this._gl.COLOR_ATTACHMENT0+a,u(this,d,o),this._activeColorAttachments[a]=d,this._colorRenderbuffers[a]=o}r(e.depthTexture)&&(n=e.depthTexture,l(this,this._gl.DEPTH_ATTACHMENT,n),this._depthTexture=n),r(e.depthRenderbuffer)&&(o=e.depthRenderbuffer,u(this,this._gl.DEPTH_ATTACHMENT,o),this._depthRenderbuffer=o),r(e.stencilRenderbuffer)&&(o=e.stencilRenderbuffer,u(this,this._gl.STENCIL_ATTACHMENT,o),this._stencilRenderbuffer=o),r(e.depthStencilTexture)&&(n=e.depthStencilTexture,l(this,this._gl.DEPTH_STENCIL_ATTACHMENT,n),this._depthStencilTexture=n),r(e.depthStencilRenderbuffer)&&(o=e.depthStencilRenderbuffer,u(this,this._gl.DEPTH_STENCIL_ATTACHMENT,o),this._depthStencilRenderbuffer=o),this._unBind()}return i(c.prototype,{status:{get:function(){this._bind();var e=this._gl.checkFramebufferStatus(this._gl.FRAMEBUFFER);return this._unBind(),e}},numberOfColorAttachments:{get:function(){return this._activeColorAttachments.length}},depthTexture:{get:function(){return this._depthTexture}},depthRenderbuffer:{get:function(){return this._depthRenderbuffer}},stencilRenderbuffer:{get:function(){return this._stencilRenderbuffer}},depthStencilTexture:{get:function(){return this._depthStencilTexture}},depthStencilRenderbuffer:{get:function(){return this._depthStencilRenderbuffer}},hasDepthAttachment:{get:function(){return!!(this.depthTexture||this.depthRenderbuffer||this.depthStencilTexture||this.depthStencilRenderbuffer)}}}),c.prototype._bind=function(){var e=this._gl;e.bindFramebuffer(e.FRAMEBUFFER,this._framebuffer)},c.prototype._unBind=function(){var e=this._gl;e.bindFramebuffer(e.FRAMEBUFFER,null)},c.prototype._getActiveColorAttachments=function(){return this._activeColorAttachments},c.prototype.getColorTexture=function(e){return this._colorTextures[e]},c.prototype.getColorRenderbuffer=function(e){return this._colorRenderbuffers[e]},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){if(this.destroyAttachments){for(var e=0,t=this._colorTextures,i=t.length;e<i;++e){var o=t[e];r(o)&&o.destroy()}var a=this._colorRenderbuffers;for(i=a.length,e=0;e<i;++e){var s=a[e];r(s)&&s.destroy()}this._depthTexture=this._depthTexture&&this._depthTexture.destroy(),this._depthRenderbuffer=this._depthRenderbuffer&&this._depthRenderbuffer.destroy(),this._stencilRenderbuffer=this._stencilRenderbuffer&&this._stencilRenderbuffer.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),this._depthStencilRenderbuffer=this._depthStencilRenderbuffer&&this._depthStencilRenderbuffer.destroy()}return this._gl.deleteFramebuffer(this._framebuffer),n(this)},c}),define("Scene/TextureAtlas",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/PixelFormat","../Core/Resource","../Core/RuntimeError","../Renderer/Framebuffer","../Renderer/Texture","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,r,n,o,a){this.bottomLeft=i(e,t.ZERO),this.topRight=i(r,t.ZERO),this.childNode1=n,this.childNode2=o,this.imageIndex=a}function m(e){e=i(e,i.EMPTY_OBJECT);var t=i(e.borderWidthInPixels,1),n=i(e.initialSize,y);this._context=e.context,this._pixelFormat=i(e.pixelFormat,l.RGBA),this._borderWidthInPixels=t,this._textureCoordinates=[],this._guid=r(),this._idHash={},this._initialSize=n,this._root=void 0}function g(e,r){var i=e._context,o=e.numberOfImages,a=e._borderWidthInPixels;if(o>0){for(var s=e._texture.width,l=e._texture.height,u=2*(s+r.width+a),c=2*(l+r.height+a),p=s/u,m=l/c,g=new f(new t(s+a,a),new t(u,l)),_=new f(new t,new t(u,l),e._root,g),v=new f(new t(a,l+a),new t(u,c)),y=new f(new t,new t(u,c),_,v),b=0;b<e._textureCoordinates.length;b++){var C=e._textureCoordinates[b];n(C)&&(C.x*=p,C.y*=m,C.width*=p,C.height*=m)}var S=new h({context:e._context,width:u,height:c,pixelFormat:e._pixelFormat}),w=new d({context:i,colorTextures:[e._texture],destroyAttachments:!1});w._bind(),S.copyFromFramebuffer(0,0,0,0,u,c),w._unBind(),w.destroy(),e._texture=e._texture&&e._texture.destroy(),e._texture=S,e._root=y}else{var T=2*(r.width+2*a),E=2*(r.height+2*a);T<e._initialSize.x&&(T=e._initialSize.x),E<e._initialSize.y&&(E=e._initialSize.y),e._texture=e._texture&&e._texture.destroy(),e._texture=new h({context:e._context,width:T,height:E,pixelFormat:e._pixelFormat}),e._root=new f(new t(a,a),new t(T,E))}}function _(e,r,i){if(n(r)){if(!n(r.childNode1)&&!n(r.childNode2)){if(n(r.imageIndex))return;var o=r.topRight.x-r.bottomLeft.x,a=r.topRight.y-r.bottomLeft.y,s=o-i.width,l=a-i.height;if(s<0||l<0)return;if(0===s&&0===l)return r;if(s>l){r.childNode1=new f(new t(r.bottomLeft.x,r.bottomLeft.y),new t(r.bottomLeft.x+i.width,r.topRight.y));var u=r.bottomLeft.x+i.width+e._borderWidthInPixels;u<r.topRight.x&&(r.childNode2=new f(new t(u,r.bottomLeft.y),new t(r.topRight.x,r.topRight.y)))}else{r.childNode1=new f(new t(r.bottomLeft.x,r.bottomLeft.y),new t(r.topRight.x,r.bottomLeft.y+i.height));var c=r.bottomLeft.y+i.height+e._borderWidthInPixels;c<r.topRight.y&&(r.childNode2=new f(new t(r.bottomLeft.x,c),new t(r.topRight.x,r.topRight.y)))}return _(e,r.childNode1,i)}return _(e,r.childNode1,i)||_(e,r.childNode2,i)}}function v(t,i,o){var a=_(t,t._root,i);if(n(a)){a.imageIndex=o;var s=t._texture.width,l=t._texture.height,u=a.topRight.x-a.bottomLeft.x,c=a.topRight.y-a.bottomLeft.y,d=a.bottomLeft.x/s,h=a.bottomLeft.y/l,p=u/s,f=c/l;t._textureCoordinates[o]=new e(d,h,p,f),t._texture.copyFrom(i,a.bottomLeft.x,a.bottomLeft.y)}else g(t,i),v(t,i,o);t._guid=r()}var y=new t(16,16);return o(m.prototype,{borderWidthInPixels:{get:function(){return this._borderWidthInPixels}},textureCoordinates:{get:function(){return this._textureCoordinates}},texture:{get:function(){return n(this._texture)||(this._texture=new h({context:this._context,width:this._initialSize.x,height:this._initialSize.y,pixelFormat:this._pixelFormat})),this._texture}},numberOfImages:{get:function(){return this._textureCoordinates.length}},guid:{get:function(){return this._guid}}}),m.prototype.addImage=function(e,t){var r=this._idHash[e];if(n(r))return r;if("function"==typeof t)t=t(e);else if("string"==typeof t||t instanceof u){var i=u.createIfNeeded(t);t=i.fetchImage()}var o=this;return r=p(t,function(e){if(o.isDestroyed())return-1;var t=o.numberOfImages;return v(o,e,t),t}),this._idHash[e]=r,r},m.prototype.addSubRegion=function(t,i){var o=this._idHash[t];if(!n(o))throw new c('image with id "'+t+'" not found in the atlas.');var a=this;return p(o,function(t){if(-1===t)return-1;var n=a._texture.width,o=a._texture.height,s=a.numberOfImages,l=a._textureCoordinates[t],u=l.x+i.x/n,c=l.y+i.y/o,d=i.width/n,h=i.height/o;return a._textureCoordinates.push(new e(u,c,d,h)),a._guid=r(),s})},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){return this._texture=this._texture&&this._texture.destroy(),a(this)},m}),define("Scene/BillboardCollection",["../Core/AttributeCompression","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EncodedCartesian3","../Core/IndexDatatype","../Core/Math","../Core/Matrix4","../Core/WebGLConstants","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArrayFacade","../Shaders/BillboardCollectionFS","../Shaders/BillboardCollectionVS","./Billboard","./BlendingState","./BlendOption","./HeightReference","./HorizontalOrigin","./SceneMode","./TextureAtlas","./VerticalOrigin"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R){"use strict";function L(e){e=a(e,a.EMPTY_OBJECT),this._scene=e.scene,this._batchTable=e.batchTable,this._textureAtlas=void 0,this._textureAtlasGUID=void 0,this._destroyTextureAtlas=!0,this._sp=void 0,this._spTranslucent=void 0,this._spPick=void 0,this._rsOpaque=void 0,this._rsTranslucent=void 0,this._vaf=void 0,this._billboards=[],this._billboardsToUpdate=[],this._billboardsToUpdateIndex=0,this._billboardsRemoved=!1,this._createVertexArray=!1,this._shaderRotation=!1,this._compiledShaderRotation=!1,this._compiledShaderRotationPick=!1,this._shaderAlignedAxis=!1,this._compiledShaderAlignedAxis=!1,this._compiledShaderAlignedAxisPick=!1,this._shaderScaleByDistance=!1,this._compiledShaderScaleByDistance=!1,this._compiledShaderScaleByDistancePick=!1,this._shaderTranslucencyByDistance=!1,this._compiledShaderTranslucencyByDistance=!1,this._compiledShaderTranslucencyByDistancePick=!1,this._shaderPixelOffsetScaleByDistance=!1,this._compiledShaderPixelOffsetScaleByDistance=!1,this._compiledShaderPixelOffsetScaleByDistancePick=!1,this._shaderDistanceDisplayCondition=!1,this._compiledShaderDistanceDisplayCondition=!1,this._compiledShaderDistanceDisplayConditionPick=!1,this._shaderDisableDepthDistance=!1,this._compiledShaderDisableDepthDistance=!1,this._compiledShaderDisableDepthDistancePick=!1,this._propertiesChanged=new Uint32Array(_e),this._maxSize=0,this._maxEyeOffset=0,this._maxScale=1,this._maxPixelOffset=0,this._allHorizontalCenter=!0,this._allVerticalCenter=!0,this._allSizedInMeters=!0,this._baseVolume=new t,this._baseVolumeWC=new t,this._baseVolume2D=new t,this._boundingVolume=new t,this._boundingVolumeDirty=!1,this._colorCommands=[],this._pickCommands=[],this.modelMatrix=f.clone(a(e.modelMatrix,f.IDENTITY)),this._modelMatrix=f.clone(f.IDENTITY),this.debugShowBoundingVolume=a(e.debugShowBoundingVolume,!1),this.blendOption=a(e.blendOption,P.OPAQUE_AND_TRANSLUCENT),this._blendOption=void 0,this._mode=O.SCENE3D,this._buffersUsage=[_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW,_.STATIC_DRAW],this._highlightColor=n.clone(n.WHITE);var r=this;this._uniforms={u_atlas:function(){return r._textureAtlas.texture},u_highlightColor:function(){return r._highlightColor}};var i=this._scene;s(i)&&s(i.terrainProviderChanged)&&(this._removeCallbackFunc=i.terrainProviderChanged.addEventListener(function(){for(var e=this._billboards,t=e.length,r=0;r<t;++r)e[r]._updateClamping()},this))}function N(e){for(var t=e.length,r=0;r<t;++r)e[r]&&e[r]._destroy()}function k(e){if(e._billboardsRemoved){e._billboardsRemoved=!1;for(var t=[],r=e._billboards,i=r.length,n=0,o=0;n<i;++n){var a=r[n];a&&(a._index=o++,t.push(a))}e._billboards=t}}function F(e){var t=e.cache.billboardCollection_indexBufferBatched;if(s(t))return t;for(var r=new Uint16Array(98298),i=0,n=0;i<98298;i+=6,n+=4)r[i]=n,r[i+1]=n+1,r[i+2]=n+2,r[i+3]=n+0,r[i+4]=n+2,r[i+5]=n+3;return t=g.createIndexBuffer({context:e,typedArray:r,usage:_.STATIC_DRAW,indexDatatype:h.UNSIGNED_SHORT}),t.vertexArrayDestroyable=!1,e.cache.billboardCollection_indexBufferBatched=t,t}function B(e){var t=e.cache.billboardCollection_indexBufferInstanced;return s(t)?t:(t=g.createIndexBuffer({context:e,typedArray:new Uint16Array([0,1,2,0,2,3]),usage:_.STATIC_DRAW,indexDatatype:h.UNSIGNED_SHORT}),t.vertexArrayDestroyable=!1,e.cache.billboardCollection_indexBufferInstanced=t,t)}function U(e){var t=e.cache.billboardCollection_vertexBufferInstanced;return s(t)?t:(t=g.createVertexBuffer({context:e,typedArray:new Float32Array([0,0,1,0,1,1,0,1]),usage:_.STATIC_DRAW}),t.vertexArrayDestroyable=!1,e.cache.billboardCollection_vertexBufferInstanced=t,t)}function V(e,t,r,i,n){var a=[{index:ee.positionHighAndScale,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[re]},{index:ee.positionLowAndRotation,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[re]},{index:ee.compressedAttribute0,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[ie]},{index:ee.compressedAttribute1,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[pe]},{index:ee.compressedAttribute2,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[ue]},{index:ee.eyeOffset,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[ne]},{index:ee.scaleByDistance,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[he]},{index:ee.pixelOffsetScaleByDistance,componentsPerAttribute:4,componentDatatype:o.FLOAT,usage:r[fe]},{index:ee.distanceDisplayConditionAndDisableDepth,componentsPerAttribute:3,componentDatatype:o.FLOAT,usage:r[me]}];return i&&a.push({index:ee.direction,componentsPerAttribute:2,componentDatatype:o.FLOAT,vertexBuffer:U(e)}),s(n)&&a.push({index:ee.a_batchId,componentsPerAttribute:1,componentDatatyps:o.FLOAT,bufferUsage:_.STATIC_DRAW}),new w(e,a,i?t:4*t,i)}function z(e,r,i,n,o){var a,s=n[ee.positionHighAndScale],l=n[ee.positionLowAndRotation],u=o._getActualPosition();e._mode===O.SCENE3D&&(t.expand(e._baseVolume,u,e._baseVolume),e._boundingVolumeDirty=!0),d.fromCartesian(u,Ce) +;var c=o.scale,h=o.rotation;0!==h&&(e._shaderRotation=!0),e._maxScale=Math.max(e._maxScale,c);var p=Ce.high,f=Ce.low;e._instanced?(a=o._index,s(a,p.x,p.y,p.z,c),l(a,f.x,f.y,f.z,h)):(a=4*o._index,s(a+0,p.x,p.y,p.z,c),s(a+1,p.x,p.y,p.z,c),s(a+2,p.x,p.y,p.z,c),s(a+3,p.x,p.y,p.z,c),l(a+0,f.x,f.y,f.z,h),l(a+1,f.x,f.y,f.z,h),l(a+2,f.x,f.y,f.z,h),l(a+3,f.x,f.y,f.z,h))}function G(t,r,i,n,o){var a,s=n[ee.compressedAttribute0],l=o.pixelOffset,u=l.x,c=l.y,d=o._translate,h=d.x,f=d.y;t._maxPixelOffset=Math.max(t._maxPixelOffset,Math.abs(u+h),Math.abs(-c+f));var m=o.horizontalOrigin,g=o._verticalOrigin,_=o.show&&o.clusterShow;0===o.color.alpha&&(_=!1),g===R.BASELINE&&(g=R.BOTTOM),t._allHorizontalCenter=t._allHorizontalCenter&&m===I.CENTER,t._allVerticalCenter=t._allVerticalCenter&&g===R.CENTER;var v=0,y=0,b=0,C=0,S=o._imageIndex;if(-1!==S){var w=i[S];v=w.x,y=w.y,b=w.width,C=w.height}var T=v+b,E=y+C,A=Math.floor(p.clamp(u,-we,we)+we)*Ae;A+=(m+1)*xe,A+=(g+1)*Pe,A+=(_?1:0)*De;var x=Math.floor(p.clamp(c,-we,we)+we)*Ee,P=Math.floor(p.clamp(h,-we,we)+we)*Ee,D=(p.clamp(f,-we,we)+we)*Ie,O=Math.floor(D),M=Math.floor((D-O)*Ee);x+=O,P+=M,Se.x=v,Se.y=y;var L=e.compressTextureCoordinates(Se);Se.x=T;var N=e.compressTextureCoordinates(Se);Se.y=E;var k=e.compressTextureCoordinates(Se);Se.x=v;var F=e.compressTextureCoordinates(Se);t._instanced?(a=o._index,s(a,A,x,P,L)):(a=4*o._index,s(a+0,A+Oe,x,P,L),s(a+1,A+Me,x,P,N),s(a+2,A+Re,x,P,k),s(a+3,A+Le,x,P,F))}function W(t,r,n,o,l){var u,c=o[ee.compressedAttribute1],d=l.alignedAxis;i.equals(d,i.ZERO)||(t._shaderAlignedAxis=!0);var h=0,f=1,m=1,g=1,_=l.translucencyByDistance;s(_)&&(h=_.near,f=_.nearValue,m=_.far,g=_.farValue,1===f&&1===g||(t._shaderTranslucencyByDistance=!0));var v=0,y=l._imageIndex;if(-1!==y){v=n[y].width}var b=t._textureAtlas.texture.width,C=Math.round(a(l.width,b*v));t._maxSize=Math.max(t._maxSize,C);var S=p.clamp(C,0,Te),w=0;Math.abs(i.magnitudeSquared(d)-1)<p.EPSILON6&&(w=e.octEncodeFloat(d)),f=p.clamp(f,0,1),f=1===f?255:255*f|0,S=S*Ee+f,g=p.clamp(g,0,1),g=1===g?255:255*g|0,w=w*Ee+g,t._instanced?(u=l._index,c(u,S,w,h,m)):(u=4*l._index,c(u+0,S,w,h,m),c(u+1,S,w,h,m),c(u+2,S,w,h,m),c(u+3,S,w,h,m))}function H(e,t,r,o,l){var u,c=o[ee.compressedAttribute2],d=l.color,h=s(e._batchTable)?n.WHITE:l.getPickId(t).color,f=l.sizeInMeters?1:0,m=Math.abs(i.magnitudeSquared(l.alignedAxis)-1)<p.EPSILON6?1:0;e._allSizedInMeters=e._allSizedInMeters&&1===f;var g=0,_=l._imageIndex;if(-1!==_){g=r[_].height}var v=e._textureAtlas.texture.dimensions,y=Math.round(a(l.height,v.y*g));e._maxSize=Math.max(e._maxSize,y);var b=n.floatToByte(d.red),C=n.floatToByte(d.green),S=n.floatToByte(d.blue),w=b*Te+C*Ee+S;b=n.floatToByte(h.red),C=n.floatToByte(h.green),S=n.floatToByte(h.blue);var T=b*Te+C*Ee+S,E=n.floatToByte(d.alpha)*Te+n.floatToByte(h.alpha)*Ee;E+=2*f+m,e._instanced?(u=l._index,c(u,w,T,E,y)):(u=4*l._index,c(u+0,w,T,E,y),c(u+1,w,T,E,y),c(u+2,w,T,E,y),c(u+3,w,T,E,y))}function j(t,r,i,n,o){var a,s=n[ee.eyeOffset],l=o.eyeOffset,u=l.z;if(o._heightReference!==D.NONE&&(u*=1.005),t._maxEyeOffset=Math.max(t._maxEyeOffset,Math.abs(l.x),Math.abs(l.y),Math.abs(u)),t._instanced){var c=0,d=0,h=o._imageIndex;if(-1!==h){var p=i[h];c=p.width,d=p.height}Se.x=c,Se.y=d;var f=e.compressTextureCoordinates(Se);a=o._index,s(a,l.x,l.y,u,f)}else a=4*o._index,s(a+0,l.x,l.y,u,0),s(a+1,l.x,l.y,u,0),s(a+2,l.x,l.y,u,0),s(a+3,l.x,l.y,u,0)}function q(e,t,r,i,n){var o,a=i[ee.scaleByDistance],l=0,u=1,c=1,d=1,h=n.scaleByDistance;s(h)&&(l=h.near,u=h.nearValue,c=h.far,d=h.farValue,1===u&&1===d||(e._shaderScaleByDistance=!0)),e._instanced?(o=n._index,a(o,l,u,c,d)):(o=4*n._index,a(o+0,l,u,c,d),a(o+1,l,u,c,d),a(o+2,l,u,c,d),a(o+3,l,u,c,d))}function Y(e,t,r,i,n){var o,a=i[ee.pixelOffsetScaleByDistance],l=0,u=1,c=1,d=1,h=n.pixelOffsetScaleByDistance;s(h)&&(l=h.near,u=h.nearValue,c=h.far,d=h.farValue,1===u&&1===d||(e._shaderPixelOffsetScaleByDistance=!0)),e._instanced?(o=n._index,a(o,l,u,c,d)):(o=4*n._index,a(o+0,l,u,c,d),a(o+1,l,u,c,d),a(o+2,l,u,c,d),a(o+3,l,u,c,d))}function X(e,t,r,i,n){var o,a=i[ee.distanceDisplayConditionAndDisableDepth],l=0,u=Number.MAX_VALUE,c=n.distanceDisplayCondition;s(c)&&(l=c.near,u=c.far,l*=l,u*=u,e._shaderDistanceDisplayCondition=!0);var d=n.disableDepthTestDistance;d*=d,d>0&&(e._shaderDisableDepthDistance=!0,d===Number.POSITIVE_INFINITY&&(d=-1)),e._instanced?(o=n._index,a(o,l,u,d)):(o=4*n._index,a(o+0,l,u,d),a(o+1,l,u,d),a(o+2,l,u,d),a(o+3,l,u,d))}function Q(e,t,r,i,n){if(s(e._batchTable)){var o,a=i[ee.a_batchId],l=n._batchIndex;e._instanced?(o=n._index,a(o,l)):(o=4*n._index,a(o+0,l),a(o+1,l),a(o+2,l),a(o+3,l))}}function Z(e,t,r,i,n){z(e,t,r,i,n),G(e,t,r,i,n),W(e,t,r,i,n),H(e,t,r,i,n),j(e,t,r,i,n),q(e,t,r,i,n),Y(e,t,r,i,n),X(e,t,r,i,n),Q(e,t,r,i,n)}function K(e,r,i,n,o,a){var l;n.mode===O.SCENE3D?(l=e._baseVolume,e._boundingVolumeDirty=!0):l=e._baseVolume2D;for(var u=[],c=0;c<i;++c){var d=r[c],h=d.position,p=A._computeActualPosition(d,h,n,o);s(p)&&(d._setActualPosition(p),a?u.push(p):t.expand(l,p,l))}a&&t.fromPoints(u,l)}function J(e,t){var r=t.mode,i=e._billboards,n=e._billboardsToUpdate,o=e._modelMatrix;e._createVertexArray||e._mode!==r||r!==O.SCENE3D&&!f.equals(o,e.modelMatrix)?(e._mode=r,f.clone(e.modelMatrix,o),e._createVertexArray=!0,r!==O.SCENE3D&&r!==O.SCENE2D&&r!==O.COLUMBUS_VIEW||K(e,i,i.length,t,o,!0)):r===O.MORPHING?K(e,i,i.length,t,o,!0):r!==O.SCENE2D&&r!==O.COLUMBUS_VIEW||K(e,n,e._billboardsToUpdateIndex,t,o,!1)}function $(e,t,r){var i=1;e._allSizedInMeters&&0===e._maxPixelOffset||(i=t.camera.getPixelSize(r,t.context.drawingBufferWidth,t.context.drawingBufferHeight));var n=i*e._maxScale*e._maxSize*2;e._allHorizontalCenter&&e._allVerticalCenter&&(n*=.5);var o=i*e._maxPixelOffset+e._maxEyeOffset;r.radius+=n+o}var ee,te=A.SHOW_INDEX,re=A.POSITION_INDEX,ie=A.PIXEL_OFFSET_INDEX,ne=A.EYE_OFFSET_INDEX,oe=A.HORIZONTAL_ORIGIN_INDEX,ae=A.VERTICAL_ORIGIN_INDEX,se=A.SCALE_INDEX,le=A.IMAGE_INDEX_INDEX,ue=A.COLOR_INDEX,ce=A.ROTATION_INDEX,de=A.ALIGNED_AXIS_INDEX,he=A.SCALE_BY_DISTANCE_INDEX,pe=A.TRANSLUCENCY_BY_DISTANCE_INDEX,fe=A.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX,me=A.DISTANCE_DISPLAY_CONDITION_INDEX,ge=A.DISABLE_DEPTH_DISTANCE,_e=A.NUMBER_OF_PROPERTIES,ve={positionHighAndScale:0,positionLowAndRotation:1,compressedAttribute0:2,compressedAttribute1:3,compressedAttribute2:4,eyeOffset:5,scaleByDistance:6,pixelOffsetScaleByDistance:7,distanceDisplayConditionAndDisableDepth:8,a_batchId:9},ye={direction:0,positionHighAndScale:1,positionLowAndRotation:2,compressedAttribute0:3,compressedAttribute1:4,compressedAttribute2:5,eyeOffset:6,scaleByDistance:7,pixelOffsetScaleByDistance:8,distanceDisplayConditionAndDisableDepth:9,a_batchId:10};l(L.prototype,{length:{get:function(){return k(this),this._billboards.length}},textureAtlas:{get:function(){return this._textureAtlas},set:function(e){this._textureAtlas!==e&&(this._textureAtlas=this._destroyTextureAtlas&&this._textureAtlas&&this._textureAtlas.destroy(),this._textureAtlas=e,this._createVertexArray=!0)}},destroyTextureAtlas:{get:function(){return this._destroyTextureAtlas},set:function(e){this._destroyTextureAtlas=e}}}),L.prototype.add=function(e){var t=new A(e,this);return t._index=this._billboards.length,this._billboards.push(t),this._createVertexArray=!0,t},L.prototype.remove=function(e){return!!this.contains(e)&&(this._billboards[e._index]=null,this._billboardsRemoved=!0,this._createVertexArray=!0,e._destroy(),!0)},L.prototype.removeAll=function(){N(this._billboards),this._billboards=[],this._billboardsToUpdate=[],this._billboardsToUpdateIndex=0,this._billboardsRemoved=!1,this._createVertexArray=!0},L.prototype._updateBillboard=function(e,t){e._dirty||(this._billboardsToUpdate[this._billboardsToUpdateIndex++]=e),++this._propertiesChanged[t]},L.prototype.contains=function(e){return s(e)&&e._billboardCollection===this},L.prototype.get=function(e){return k(this),this._billboards[e]};var be;L.prototype.computeNewBuffersUsage=function(){for(var e=this._buffersUsage,t=!1,r=this._propertiesChanged,i=0;i<_e;++i){var n=0===r[i]?_.STATIC_DRAW:_.STREAM_DRAW;t=t||e[i]!==n,e[i]=n}return t};var Ce=new d,Se=new r,we=32768,Te=65536,Ee=256,Ae=128,xe=32,Pe=8,De=4,Ie=1/256,Oe=0,Me=2,Re=3,Le=1,Ne=[];return L.prototype.update=function(e){k(this);var r=this._billboards,i=r.length,n=e.context;this._instanced=n.instancedArrays,ee=this._instanced?ye:ve,be=this._instanced?B:F;var o=this._textureAtlas;if(!s(o)){o=this._textureAtlas=new M({context:n});for(var a=0;a<i;++a)r[a]._loadImage()}var l=o.textureCoordinates;if(0!==l.length){J(this,e),r=this._billboards,i=r.length;var u=this._billboardsToUpdate,c=this._billboardsToUpdateIndex,d=this._propertiesChanged,h=o.guid,p=this._createVertexArray||this._textureAtlasGUID!==h;this._textureAtlasGUID=h;var g,_=e.passes,w=_.pick;if(p||!w&&this.computeNewBuffersUsage()){this._createVertexArray=!1;for(var A=0;A<_e;++A)d[A]=0;if(this._vaf=this._vaf&&this._vaf.destroy(),i>0){this._vaf=V(n,i,this._buffersUsage,this._instanced,this._batchTable),g=this._vaf.writers;for(var D=0;D<i;++D){var I=this._billboards[D];I._dirty=!1,Z(this,n,l,g,I)}this._vaf.commit(be(n))}this._billboardsToUpdateIndex=0}else if(c>0){var R=Ne;R.length=0,(d[re]||d[ce]||d[se])&&R.push(z),(d[le]||d[ie]||d[oe]||d[ae]||d[te])&&(R.push(G),this._instanced&&R.push(j)),(d[le]||d[de]||d[pe])&&(R.push(W),R.push(H)),(d[le]||d[ue])&&R.push(H),d[ne]&&R.push(j),d[he]&&R.push(q),d[fe]&&R.push(Y),(d[me]||d[ge])&&R.push(X);var L=R.length;if(g=this._vaf.writers,c/i>.1){for(var N=0;N<c;++N){var U=u[N];U._dirty=!1;for(var Q=0;Q<L;++Q)R[Q](this,n,l,g,U)}this._vaf.commit(be(n))}else{for(var K=0;K<c;++K){var Ce=u[K];Ce._dirty=!1;for(var Se=0;Se<L;++Se)R[Se](this,n,l,g,Ce);this._instanced?this._vaf.subCommit(Ce._index,1):this._vaf.subCommit(4*Ce._index,4)}this._vaf.endSubCommits()}this._billboardsToUpdateIndex=0}if(c>1.5*i&&(u.length=i),s(this._vaf)&&s(this._vaf.va)){this._boundingVolumeDirty&&(this._boundingVolumeDirty=!1,t.transform(this._baseVolume,this.modelMatrix,this._baseVolumeWC));var we,Te=f.IDENTITY;e.mode===O.SCENE3D?(Te=this.modelMatrix,we=t.clone(this._baseVolumeWC,this._boundingVolume)):we=t.clone(this._baseVolume2D,this._boundingVolume),$(this,e,we);var Ee=this._blendOption!==this.blendOption;if(this._blendOption=this.blendOption,Ee){this._blendOption===P.OPAQUE||this._blendOption===P.OPAQUE_AND_TRANSLUCENT?this._rsOpaque=b.fromCache({depthTest:{enabled:!0,func:m.LESS},depthMask:!0}):this._rsOpaque=void 0;var Ae=this._blendOption===P.TRANSLUCENT;this._blendOption===P.TRANSLUCENT||this._blendOption===P.OPAQUE_AND_TRANSLUCENT?this._rsTranslucent=b.fromCache({depthTest:{enabled:!0,func:Ae?m.LEQUAL:m.LESS},depthMask:Ae,blending:x.ALPHA_BLEND}):this._rsTranslucent=void 0}this._shaderDisableDepthDistance=this._shaderDisableDepthDistance||0!==e.minimumDisableDepthTestDistance;var xe,Pe,De,Ie,Oe;if(Ee||this._shaderRotation!==this._compiledShaderRotation||this._shaderAlignedAxis!==this._compiledShaderAlignedAxis||this._shaderScaleByDistance!==this._compiledShaderScaleByDistance||this._shaderTranslucencyByDistance!==this._compiledShaderTranslucencyByDistance||this._shaderPixelOffsetScaleByDistance!==this._compiledShaderPixelOffsetScaleByDistance||this._shaderDistanceDisplayCondition!==this._compiledShaderDistanceDisplayCondition||this._shaderDisableDepthDistance!==this._compiledShaderDisableDepthDistance){xe=E,Pe=T,Oe=[],s(this._batchTable)&&(Oe.push("VECTOR_TILE"),xe=this._batchTable.getVertexShaderCallback(!1,"a_batchId",void 0)(xe),Pe=this._batchTable.getFragmentShaderCallback(!1,void 0)(Pe)),De=new S({defines:Oe,sources:[xe]}),this._instanced&&De.defines.push("INSTANCED"),this._shaderRotation&&De.defines.push("ROTATION"),this._shaderAlignedAxis&&De.defines.push("ALIGNED_AXIS"),this._shaderScaleByDistance&&De.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&De.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderPixelOffsetScaleByDistance&&De.defines.push("EYE_DISTANCE_PIXEL_OFFSET"),this._shaderDistanceDisplayCondition&&De.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&De.defines.push("DISABLE_DEPTH_DISTANCE");var Me=s(this._batchTable)?"VECTOR_TILE":"";this._blendOption===P.OPAQUE_AND_TRANSLUCENT&&(Ie=new S({defines:["OPAQUE",Me],sources:[Pe]}),this._sp=C.replaceCache({context:n,shaderProgram:this._sp,vertexShaderSource:De,fragmentShaderSource:Ie,attributeLocations:ee}),Ie=new S({defines:["TRANSLUCENT",Me],sources:[Pe]}),this._spTranslucent=C.replaceCache({context:n,shaderProgram:this._spTranslucent,vertexShaderSource:De,fragmentShaderSource:Ie,attributeLocations:ee})),this._blendOption===P.OPAQUE&&(Ie=new S({defines:[Me],sources:[Pe]}),this._sp=C.replaceCache({context:n,shaderProgram:this._sp,vertexShaderSource:De,fragmentShaderSource:Ie,attributeLocations:ee})),this._blendOption===P.TRANSLUCENT&&(Ie=new S({defines:[Me],sources:[Pe]}),this._spTranslucent=C.replaceCache({context:n,shaderProgram:this._spTranslucent,vertexShaderSource:De,fragmentShaderSource:Ie,attributeLocations:ee})),this._compiledShaderRotation=this._shaderRotation,this._compiledShaderAlignedAxis=this._shaderAlignedAxis,this._compiledShaderScaleByDistance=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistance=this._shaderTranslucencyByDistance,this._compiledShaderPixelOffsetScaleByDistance=this._shaderPixelOffsetScaleByDistance,this._compiledShaderDistanceDisplayCondition=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistance=this._shaderDisableDepthDistance}s(this._spPick)&&this._shaderRotation===this._compiledShaderRotationPick&&this._shaderAlignedAxis===this._compiledShaderAlignedAxisPick&&this._shaderScaleByDistance===this._compiledShaderScaleByDistancePick&&this._shaderTranslucencyByDistance===this._compiledShaderTranslucencyByDistancePick&&this._shaderPixelOffsetScaleByDistance===this._compiledShaderPixelOffsetScaleByDistancePick&&this._shaderDistanceDisplayCondition===this._compiledShaderDistanceDisplayConditionPick&&this._shaderDisableDepthDistance===this._compiledShaderDisableDepthDistancePick||(xe=E,Pe=T,Oe=[],s(this._batchTable)&&(Oe.push("VECTOR_TILE"),xe=this._batchTable.getPickVertexShaderCallback("a_batchId")(xe),Pe=this._batchTable.getPickFragmentShaderCallback()(Pe)),Oe.push(s(this._batchTable)?"":"RENDER_FOR_PICK"),De=new S({defines:Oe,sources:[xe]}),this._instanced&&De.defines.push("INSTANCED"),this._shaderRotation&&De.defines.push("ROTATION"),this._shaderAlignedAxis&&De.defines.push("ALIGNED_AXIS"),this._shaderScaleByDistance&&De.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&De.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderPixelOffsetScaleByDistance&&De.defines.push("EYE_DISTANCE_PIXEL_OFFSET"),this._shaderDistanceDisplayCondition&&De.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&De.defines.push("DISABLE_DEPTH_DISTANCE"),Ie=new S({defines:Oe,sources:[Pe]}),this._spPick=C.replaceCache({context:n,shaderProgram:this._spPick,vertexShaderSource:De,fragmentShaderSource:Ie,attributeLocations:ee}),this._compiledShaderRotationPick=this._shaderRotation,this._compiledShaderAlignedAxisPick=this._shaderAlignedAxis,this._compiledShaderScaleByDistancePick=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistancePick=this._shaderTranslucencyByDistance,this._compiledShaderPixelOffsetScaleByDistancePick=this._shaderPixelOffsetScaleByDistance,this._compiledShaderDistanceDisplayConditionPick=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistancePick=this._shaderDisableDepthDistance);var Re,Le,ke,Fe,Be,Ue=e.commandList;if(_.render){var Ve=this._colorCommands,ze=this._blendOption===P.OPAQUE,Ge=this._blendOption===P.OPAQUE_AND_TRANSLUCENT;Re=this._vaf.va,Le=Re.length,Fe=this._uniforms,s(this._batchTable)&&(Fe=this._batchTable.getUniformMapCallback()(Fe)),Ve.length=Le;var We=Ge?2*Le:Le;for(Be=0;Be<We;++Be){ke=Ve[Be],s(ke)||(ke=Ve[Be]=new v);var He=ze||Ge&&Be%2==0;ke.pass=He||!Ge?y.OPAQUE:y.TRANSLUCENT,ke.owner=this;var je=Ge?Math.floor(Be/2):Be;ke.boundingVolume=we,ke.modelMatrix=Te,ke.count=Re[je].indicesCount,ke.shaderProgram=He?this._sp:this._spTranslucent,ke.uniformMap=Fe,ke.vertexArray=Re[je].va,ke.renderState=He?this._rsOpaque:this._rsTranslucent,ke.debugShowBoundingVolume=this.debugShowBoundingVolume,this._instanced&&(ke.count=6,ke.instanceCount=i),Ue.push(ke)}}if(w){var qe=this._pickCommands;for(Re=this._vaf.va,Le=Re.length,Fe=this._uniforms,s(this._batchTable)&&(Fe=this._batchTable.getPickUniformMapCallback()(Fe)),qe.length=Le,Be=0;Be<Le;++Be)ke=qe[Be],s(ke)||(ke=qe[Be]=new v({pass:y.OPAQUE,owner:this})),ke.boundingVolume=we,ke.modelMatrix=Te,ke.count=Re[Be].indicesCount,ke.shaderProgram=this._spPick,ke.uniformMap=Fe,ke.vertexArray=Re[Be].va,ke.renderState=this._rsOpaque,this._instanced&&(ke.count=6,ke.instanceCount=i),Ue.push(ke)}}}},L.prototype.isDestroyed=function(){return!1},L.prototype.destroy=function(){return s(this._removeCallbackFunc)&&(this._removeCallbackFunc(),this._removeCallbackFunc=void 0),this._textureAtlas=this._destroyTextureAtlas&&this._textureAtlas&&this._textureAtlas.destroy(),this._sp=this._sp&&this._sp.destroy(),this._spTranslucent=this._spTranslucent&&this._spTranslucent.destroy(),this._spPick=this._spPick&&this._spPick.destroy(),this._vaf=this._vaf&&this._vaf.destroy(),N(this._billboards),u(this)},L}),define("Scene/LabelStyle",["../Core/freezeObject"],function(e){"use strict";return e({FILL:0,OUTLINE:1,FILL_AND_OUTLINE:2})}),define("Scene/Label",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/freezeObject","../Core/NearFarScalar","./Billboard","./HeightReference","./HorizontalOrigin","./LabelStyle","./VerticalOrigin"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e){e._rebindAllGlyphs||e._repositionAllGlyphs||e._labelCollection._labelsToUpdate.push(e),e._rebindAllGlyphs=!0}function _(e){e._rebindAllGlyphs||e._repositionAllGlyphs||e._labelCollection._labelsToUpdate.push(e),e._repositionAllGlyphs=!0}function v(e,a){e=n(e,n.EMPTY_OBJECT);var s=e.translucencyByDistance,u=e.pixelOffsetScaleByDistance,d=e.scaleByDistance,g=e.distanceDisplayCondition;o(s)&&(s=c.clone(s)),o(u)&&(u=c.clone(u)),o(d)&&(d=c.clone(d)),o(g)&&(g=l.clone(g)),this._renderedText=void 0,this._text=void 0,this._show=n(e.show,!0),this._font=n(e.font,"30px sans-serif"),this._fillColor=i.clone(n(e.fillColor,i.WHITE)),this._outlineColor=i.clone(n(e.outlineColor,i.BLACK)),this._outlineWidth=n(e.outlineWidth,1),this._showBackground=n(e.showBackground,!1),this._backgroundColor=n(e.backgroundColor,new i(.165,.165,.165,.8)),this._backgroundPadding=n(e.backgroundPadding,new t(7,5)),this._style=n(e.style,f.FILL),this._verticalOrigin=n(e.verticalOrigin,m.BASELINE),this._horizontalOrigin=n(e.horizontalOrigin,p.LEFT),this._pixelOffset=t.clone(n(e.pixelOffset,t.ZERO)),this._eyeOffset=r.clone(n(e.eyeOffset,r.ZERO)),this._position=r.clone(n(e.position,r.ZERO)),this._scale=n(e.scale,1),this._id=e.id,this._translucencyByDistance=s,this._pixelOffsetScaleByDistance=u,this._scaleByDistance=d,this._heightReference=n(e.heightReference,h.NONE),this._distanceDisplayCondition=g,this._disableDepthTestDistance=n(e.disableDepthTestDistance,0),this._labelCollection=a,this._glyphs=[],this._backgroundBillboard=void 0,this._batchIndex=void 0,this._rebindAllGlyphs=!0,this._repositionAllGlyphs=!0,this._actualClampedPosition=void 0,this._removeCallbackFunc=void 0,this._mode=void 0,this._clusterShow=!0,this.text=n(e.text,""),this._updateClamping()}function y(e,t){for(var r=/[a-zA-Z0-9]/,i=/[()[\]{}<>]/,n=[],o="",a=T.LTR,s="",l=e.length,u=0;u<l;++u){var c=e.charAt(u);s=t.test(c)?T.RTL:r.test(c)?T.LTR:i.test(c)?T.BRACKETS:T.WEAK,0===u&&(a=s),a===s&&s!==T.BRACKETS?o+=c:(""!==o&&n.push({Type:a,Word:o}),a=s,o=c)}return n.push({Type:s,Word:o}),n}function b(e){return e.split("").reverse().join("")}function C(e,t,r){return e.slice(0,t)+r+e.slice(t)}function S(e){switch(e){case"(":return")";case")":return"(";case"[":return"]";case"]":return"[";case"{":return"}";case"}":return"{";case"<":return">";case">":return"<"}}function w(e){for(var t=e.split("\n"),r="",i=0;i<t.length;i++){for(var n=t[i],o=E.test(n.charAt(0)),a=y(n,E),s=0,l="",u=0;u<a.length;++u){var c=a[u],d=c.Type===T.BRACKETS?S(c.Word):c.Word;o?c.Type===T.RTL?(l=b(c.Word)+l,s=0):c.Type===T.LTR?(l=C(l,s,c.Word),s+=c.Word.length):c.Type!==T.WEAK&&c.Type!==T.BRACKETS||(c.Type===T.WEAK&&a[u-1].Type===T.BRACKETS?l=b(c.Word)+l:a[u-1].Type===T.RTL?(l=d+l,s=0):a.length>u+1?a[u+1].Type===T.RTL?(l=d+l,s=0):(l=C(l,s,c.Word),s+=c.Word.length):l=C(l,0,d)):c.Type===T.RTL?l=C(l,s,b(c.Word)):c.Type===T.LTR?(l+=c.Word,s=l.length):c.Type!==T.WEAK&&c.Type!==T.BRACKETS||(u>0&&a[u-1].Type===T.RTL?a.length>u+1?a[u+1].Type===T.RTL?l=C(l,s,d):(l+=c.Word,s=l.length):l+=c.Word:(l+=c.Word,s=l.length))}r+=l,i<t.length-1&&(r+="\n")}return r}var T=u({LTR:0,RTL:1,WEAK:2,BRACKETS:3});a(v.prototype,{show:{get:function(){return this._show},set:function(e){if(this._show!==e){this._show=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r].billboard;o(n)&&(n.show=e)}var a=this._backgroundBillboard;o(a)&&(a.show=e)}}},position:{get:function(){return this._position},set:function(e){var t=this._position;if(!r.equals(t,e)){r.clone(e,t);for(var i=this._glyphs,n=0,a=i.length;n<a;n++){var s=i[n].billboard;o(s)&&(s.position=e)}var l=this._backgroundBillboard;o(l)&&(l.position=e),this._updateClamping()}}},heightReference:{get:function(){return this._heightReference},set:function(e){if(e!==this._heightReference){this._heightReference=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r].billboard;o(n)&&(n.heightReference=e)}var a=this._backgroundBillboard;o(a)&&(a.heightReference=e),_(this),this._updateClamping()}}},text:{get:function(){return this._text},set:function(e){this._text!==e&&(this._text=e,this._renderedText=v.enableRightToLeftDetection?w(e):e,g(this))}},font:{get:function(){return this._font},set:function(e){this._font!==e&&(this._font=e,g(this))}},fillColor:{get:function(){return this._fillColor},set:function(e){var t=this._fillColor;i.equals(t,e)||(i.clone(e,t),g(this))}},outlineColor:{get:function(){return this._outlineColor},set:function(e){var t=this._outlineColor;i.equals(t,e)||(i.clone(e,t),g(this))}},outlineWidth:{get:function(){return this._outlineWidth},set:function(e){this._outlineWidth!==e&&(this._outlineWidth=e,g(this))}},showBackground:{get:function(){return this._showBackground},set:function(e){this._showBackground!==e&&(this._showBackground=e,g(this))}},backgroundColor:{get:function(){return this._backgroundColor},set:function(e){var t=this._backgroundColor;if(!i.equals(t,e)){i.clone(e,t);var r=this._backgroundBillboard;o(r)&&(r.color=t)}}},backgroundPadding:{get:function(){return this._backgroundPadding},set:function(e){var r=this._backgroundPadding;t.equals(r,e)||(t.clone(e,r),_(this))}},style:{get:function(){return this._style},set:function(e){this._style!==e&&(this._style=e,g(this))}},pixelOffset:{get:function(){return this._pixelOffset},set:function(e){var r=this._pixelOffset;if(!t.equals(r,e)){t.clone(e,r);for(var i=this._glyphs,n=0,a=i.length;n<a;n++){var s=i[n];o(s.billboard)&&(s.billboard.pixelOffset=e)}var l=this._backgroundBillboard;o(l)&&(l.pixelOffset=e)}}},translucencyByDistance:{get:function(){return this._translucencyByDistance},set:function(e){var t=this._translucencyByDistance;if(!c.equals(t,e)){this._translucencyByDistance=c.clone(e,t);for(var r=this._glyphs,i=0,n=r.length;i<n;i++){var a=r[i];o(a.billboard)&&(a.billboard.translucencyByDistance=e)}var s=this._backgroundBillboard;o(s)&&(s.translucencyByDistance=e)}}},pixelOffsetScaleByDistance:{get:function(){return this._pixelOffsetScaleByDistance},set:function(e){var t=this._pixelOffsetScaleByDistance;if(!c.equals(t,e)){this._pixelOffsetScaleByDistance=c.clone(e,t);for(var r=this._glyphs,i=0,n=r.length;i<n;i++){var a=r[i];o(a.billboard)&&(a.billboard.pixelOffsetScaleByDistance=e)}var s=this._backgroundBillboard;o(s)&&(s.pixelOffsetScaleByDistance=e)}}},scaleByDistance:{get:function(){return this._scaleByDistance},set:function(e){var t=this._scaleByDistance;if(!c.equals(t,e)){this._scaleByDistance=c.clone(e,t);for(var r=this._glyphs,i=0,n=r.length;i<n;i++){var a=r[i];o(a.billboard)&&(a.billboard.scaleByDistance=e)}var s=this._backgroundBillboard;o(s)&&(s.scaleByDistance=e)}}},eyeOffset:{get:function(){return this._eyeOffset},set:function(e){var t=this._eyeOffset;if(!r.equals(t,e)){r.clone(e,t);for(var i=this._glyphs,n=0,a=i.length;n<a;n++){var s=i[n];o(s.billboard)&&(s.billboard.eyeOffset=e)}var l=this._backgroundBillboard;o(l)&&(l.eyeOffset=e)}}},horizontalOrigin:{get:function(){return this._horizontalOrigin},set:function(e){this._horizontalOrigin!==e&&(this._horizontalOrigin=e,_(this))}},verticalOrigin:{get:function(){return this._verticalOrigin},set:function(e){if(this._verticalOrigin!==e){this._verticalOrigin=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r];o(n.billboard)&&(n.billboard.verticalOrigin=e)}var a=this._backgroundBillboard;o(a)&&(a.verticalOrigin=e),_(this)}}},scale:{get:function(){return this._scale},set:function(e){if(this._scale!==e){this._scale=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r];o(n.billboard)&&(n.billboard.scale=e)}var a=this._backgroundBillboard;o(a)&&(a.scale=e),_(this)}}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){if(!l.equals(e,this._distanceDisplayCondition)){this._distanceDisplayCondition=l.clone(e,this._distanceDisplayCondition);for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r];o(n.billboard)&&(n.billboard.distanceDisplayCondition=e)}var a=this._backgroundBillboard;o(a)&&(a.distanceDisplayCondition=e)}}},disableDepthTestDistance:{get:function(){return this._disableDepthTestDistance},set:function(e){if(this._disableDepthTestDistance!==e){this._disableDepthTestDistance=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r];o(n.billboard)&&(n.billboard.disableDepthTestDistance=e)}var a=this._backgroundBillboard;o(a)&&(a.disableDepthTestDistance=e)}}},id:{get:function(){return this._id},set:function(e){if(this._id!==e){this._id=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r];o(n.billboard)&&(n.billboard.id=e)}var a=this._backgroundBillboard;o(a)&&(a.id=e)}}},_clampedPosition:{get:function(){return this._actualClampedPosition},set:function(e){this._actualClampedPosition=r.clone(e,this._actualClampedPosition);for(var t=this._glyphs,i=0,n=t.length;i<n;i++){var a=t[i];o(a.billboard)&&(a.billboard._clampedPosition=e)}var s=this._backgroundBillboard;o(s)&&(s._clampedPosition=e)}},clusterShow:{get:function(){return this._clusterShow},set:function(e){if(this._clusterShow!==e){this._clusterShow=e;for(var t=this._glyphs,r=0,i=t.length;r<i;r++){var n=t[r];o(n.billboard)&&(n.billboard.clusterShow=e)}var a=this._backgroundBillboard;o(a)&&(a.clusterShow=e)}}}}),v.prototype._updateClamping=function(){d._updateClamping(this._labelCollection,this)},v.prototype.computeScreenSpacePosition=function(e,r){o(r)||(r=new t);var i=this._labelCollection,n=i.modelMatrix,a=o(this._actualClampedPosition)?this._actualClampedPosition:this._position;return d._computeScreenSpacePosition(n,a,this._eyeOffset,this._pixelOffset,e,r)},v.getScreenSpaceBoundingBox=function(t,r,i){var n=0,a=0,s=0,l=0,u=t.scale,c=t._labelCollection._resolutionScale,d=t._backgroundBillboard;if(o(d))n=r.x+d._translate.x/c,a=r.y-d._translate.y/c,s=d.width*u,l=d.height*u,t.verticalOrigin===m.BOTTOM||t.verticalOrigin===m.BASELINE?a-=l:t.verticalOrigin===m.CENTER&&(a-=.5*l);else{n=Number.POSITIVE_INFINITY,a=Number.POSITIVE_INFINITY;for(var h=0,p=0,f=t._glyphs,g=f.length,_=0;_<g;++_){var v=f[_],y=v.billboard;if(o(y)){var b=r.x+y._translate.x/c,C=r.y-y._translate.y/c,S=y.width*u,w=y.height*u;t.verticalOrigin===m.BOTTOM||t.verticalOrigin===m.BASELINE?C-=w:t.verticalOrigin===m.CENTER&&(C-=.5*w),n=Math.min(n,b),a=Math.min(a,C),h=Math.max(h,b+S),p=Math.max(p,C+w)}}s=h-n,l=p-a}return o(i)||(i=new e),i.x=n,i.y=a,i.width=s,i.height=l,i},v.prototype.equals=function(e){return this===e||o(e)&&this._show===e._show&&this._scale===e._scale&&this._outlineWidth===e._outlineWidth&&this._showBackground===e._showBackground&&this._style===e._style&&this._verticalOrigin===e._verticalOrigin&&this._horizontalOrigin===e._horizontalOrigin&&this._heightReference===e._heightReference&&this._renderedText===e._renderedText&&this._font===e._font&&r.equals(this._position,e._position)&&i.equals(this._fillColor,e._fillColor)&&i.equals(this._outlineColor,e._outlineColor)&&i.equals(this._backgroundColor,e._backgroundColor)&&t.equals(this._backgroundPadding,e._backgroundPadding)&&t.equals(this._pixelOffset,e._pixelOffset)&&r.equals(this._eyeOffset,e._eyeOffset)&&c.equals(this._translucencyByDistance,e._translucencyByDistance)&&c.equals(this._pixelOffsetScaleByDistance,e._pixelOffsetScaleByDistance)&&c.equals(this._scaleByDistance,e._scaleByDistance)&&l.equals(this._distanceDisplayCondition,e._distanceDisplayCondition)&&this._disableDepthTestDistance===e._disableDepthTestDistance&&this._id===e._id},v.prototype.isDestroyed=function(){return!1},v.enableRightToLeftDetection=!1;var E=new RegExp("[א-ת؀-ۿݐ-ݿࢠ-ࣿ]");return v}),define("Scene/LabelCollection",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Matrix4","../Core/writeTextToCanvas","./BillboardCollection","./BlendOption","./HorizontalOrigin","./Label","./LabelStyle","./TextureAtlas","./VerticalOrigin"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(){this.textureInfo=void 0,this.dimensions=void 0,this.billboard=void 0}function v(e,t,r){this.labelCollection=e,this.index=t,this.dimensions=r}function y(e,t){var r=document.createElement("canvas");r.width=I.x,r.height=I.y;var i=r.getContext("2d");i.fillStyle="#fff",i.fillRect(0,0,r.width,r.height),e.addImage(D,r).then(function(e){t._whitePixelIndex=e})}function b(e,t,r,i,n,o,a){return M.font=t,M.fillColor=r,M.strokeColor=i,M.strokeWidth=n,a===g.CENTER?M.textBaseline="middle":a===g.TOP?M.textBaseline="top":M.textBaseline="bottom",M.fill=o===f.FILL||o===f.FILL_AND_OUTLINE,M.stroke=o===f.OUTLINE||o===f.FILL_AND_OUTLINE,u(e,M)}function C(e,t){t.textureInfo=void 0,t.dimensions=void 0;var r=t.billboard;n(r)&&(r.show=!1,r.image=void 0,n(r._removeCallbackFunc)&&(r._removeCallbackFunc(),r._removeCallbackFunc=void 0),e._spareBillboards.push(r),t.billboard=void 0)}function S(e,t,r,i){e.addImage(t,r).then(function(e){i.index=e})}function w(e,t){var r,i,o,a=t._renderedText,s=a.length,l=t._glyphs,u=l.length;if(s<u)for(i=s;i<u;++i)C(e,l[i]);l.length=s;var c=t._showBackground&&a.split("\n").join("").length>0,d=t._backgroundBillboard,p=e._backgroundBillboardCollection;c?(n(d)||(d=p.add({collection:e,image:D,imageSubRegion:O}),t._backgroundBillboard=d),d.color=t._backgroundColor,d.show=t._show,d.position=t._position,d.eyeOffset=t._eyeOffset,d.pixelOffset=t._pixelOffset,d.horizontalOrigin=h.LEFT,d.verticalOrigin=t._verticalOrigin,d.heightReference=t._heightReference,d.scale=t._scale,d.pickPrimitive=t,d.id=t._id,d.translucencyByDistance=t._translucencyByDistance,d.pixelOffsetScaleByDistance=t._pixelOffsetScaleByDistance,d.scaleByDistance=t._scaleByDistance,d.distanceDisplayCondition=t._distanceDisplayCondition,d.disableDepthTestDistance=t._disableDepthTestDistance):n(d)&&(p.remove(d),t._backgroundBillboard=d=void 0);var f=e._glyphTextureCache;for(o=0;o<s;++o){var m=a.charAt(o),g=t._font,y=t._fillColor,w=t._outlineColor,T=t._outlineWidth,E=t._style,A=t._verticalOrigin,x=JSON.stringify([m,g,y.toRgba(),w.toRgba(),T,+E,+A]),P=f[x];if(!n(P)){var I=b(m,g,y,w,T,E,A);P=new v(e,-1,I.dimensions),f[x]=P,I.width>0&&I.height>0&&S(e._textureAtlas,x,I,P)}if(r=l[o], +n(r)?-1===P.index?C(e,r):n(r.textureInfo)&&(r.textureInfo=void 0):(r=new _,l[o]=r),r.textureInfo=P,r.dimensions=P.dimensions,-1!==P.index){var M=r.billboard,R=e._spareBillboards;n(M)||(M=R.length>0?R.pop():e._billboardCollection.add({collection:e}),r.billboard=M),M.show=t._show,M.position=t._position,M.eyeOffset=t._eyeOffset,M.pixelOffset=t._pixelOffset,M.horizontalOrigin=h.LEFT,M.verticalOrigin=t._verticalOrigin,M.heightReference=t._heightReference,M.scale=t._scale,M.pickPrimitive=t,M.id=t._id,M.image=x,M.translucencyByDistance=t._translucencyByDistance,M.pixelOffsetScaleByDistance=t._pixelOffsetScaleByDistance,M.scaleByDistance=t._scaleByDistance,M.distanceDisplayCondition=t._distanceDisplayCondition,M.disableDepthTestDistance=t._disableDepthTestDistance,M._batchIndex=t._batchIndex}}t._repositionAllGlyphs=!0}function T(e,t,r){return t===h.CENTER?-e/2:t===h.RIGHT?-(e+r.x):r.x}function E(e,r){var i,o,a=e._glyphs,s=e._renderedText,l=0,u=0,c=[],d=Number.NEGATIVE_INFINITY,p=0,f=1,m=0,_=a.length,v=e._backgroundBillboard,y=L;for(t.clone(n(v)?e._backgroundPadding:t.ZERO,y),m=0;m<_;++m)"\n"===s.charAt(m)?(c.push(l),++f,l=0):(i=a[m],o=i.dimensions,p=Math.max(p,o.height-o.descent),d=Math.max(d,o.descent),l+=o.width-o.bounds.minx,m<_-1&&(l+=a[m+1].dimensions.bounds.minx),u=Math.max(u,l));c.push(l);var b=p+d,C=e._scale,S=e._horizontalOrigin,w=e._verticalOrigin,E=0,A=c[E],x=T(A,S,y),D=P*b,I=D*(f-1);R.x=x*C*r,R.y=0;var O=0;for(m=0;m<_;++m)if("\n"===s.charAt(m))++E,O+=D,A=c[E],x=T(A,S,y),R.x=x*C*r;else if(i=a[m],o=i.dimensions,w===g.TOP?R.y=o.height-p-y.y:w===g.CENTER?R.y=(I+o.height-p)/2:w===g.BASELINE?R.y=I:R.y=I+d+y.y,R.y=(R.y-o.descent-O)*C*r,n(i.billboard)&&i.billboard._setTranslate(R),m<_-1){var M=a[m+1];R.x+=(o.width-o.bounds.minx+M.dimensions.bounds.minx)*C*r}n(v)&&s.split("\n").join("").length>0&&(x=S===h.CENTER?-u/2-y.x:S===h.RIGHT?-(u+2*y.x):0,R.x=x*C*r,w===g.TOP?R.y=b-p-d:w===g.CENTER?R.y=(b-p)/2-d:w===g.BASELINE?R.y=-y.y-d:R.y=0,R.y=R.y*C*r,v.width=u+2*y.x,v.height=b+I+2*y.y,v._setTranslate(R))}function A(e,t){for(var r=t._glyphs,i=0,o=r.length;i<o;++i)C(e,r[i]);n(t._backgroundBillboard)&&(e._backgroundBillboardCollection.remove(t._backgroundBillboard),t._backgroundBillboard=void 0),t._labelCollection=void 0,n(t._removeCallbackFunc)&&t._removeCallbackFunc(),a(t)}function x(e){e=i(e,i.EMPTY_OBJECT),this._scene=e.scene,this._batchTable=e.batchTable,this._textureAtlas=void 0,this._backgroundTextureAtlas=void 0,this._whitePixelIndex=void 0,this._backgroundBillboardCollection=new c({scene:this._scene}),this._backgroundBillboardCollection.destroyTextureAtlas=!1,this._billboardCollection=new c({scene:this._scene,batchTable:this._batchTable}),this._billboardCollection.destroyTextureAtlas=!1,this._spareBillboards=[],this._glyphTextureCache={},this._labels=[],this._labelsToUpdate=[],this._totalGlyphCount=0,this._resolutionScale=void 0,this._highlightColor=r.clone(r.WHITE),this.modelMatrix=l.clone(i(e.modelMatrix,l.IDENTITY)),this.debugShowBoundingVolume=i(e.debugShowBoundingVolume,!1),this.blendOption=i(e.blendOption,d.OPAQUE_AND_TRANSLUCENT)}var P=1.2,D="ID_WHITE_PIXEL",I=new t(4,4),O=new e(1,1,1,1),M={},R=new t,L=new t;return o(x.prototype,{length:{get:function(){return this._labels.length}}}),x.prototype.add=function(e){var t=new p(e,this);return this._labels.push(t),this._labelsToUpdate.push(t),t},x.prototype.remove=function(e){if(n(e)&&e._labelCollection===this){var t=this._labels.indexOf(e);if(-1!==t)return this._labels.splice(t,1),A(this,e),!0}return!1},x.prototype.removeAll=function(){for(var e=this._labels,t=0,r=e.length;t<r;++t)A(this,e[t]);e.length=0},x.prototype.contains=function(e){return n(e)&&e._labelCollection===this},x.prototype.get=function(e){return this._labels[e]},x.prototype.update=function(e){var t=this._billboardCollection,r=this._backgroundBillboardCollection;t.modelMatrix=this.modelMatrix,t.debugShowBoundingVolume=this.debugShowBoundingVolume,r.modelMatrix=this.modelMatrix,r.debugShowBoundingVolume=this.debugShowBoundingVolume;var i=e.context;n(this._textureAtlas)||(this._textureAtlas=new m({context:i}),t.textureAtlas=this._textureAtlas),n(this._backgroundTextureAtlas)||(this._backgroundTextureAtlas=new m({context:i,initialSize:I}),r.textureAtlas=this._backgroundTextureAtlas,y(this._backgroundTextureAtlas,this));var o=i.uniformState,a=o.resolutionScale,s=this._resolutionScale!==a;this._resolutionScale=a;var l;l=s?this._labels:this._labelsToUpdate;for(var u=l.length,c=0;c<u;++c){var h=l[c];if(!h.isDestroyed()){var p=h._glyphs.length;h._rebindAllGlyphs&&(w(this,h),h._rebindAllGlyphs=!1),(s||h._repositionAllGlyphs)&&(E(h,a),h._repositionAllGlyphs=!1);var f=h._glyphs.length-p;this._totalGlyphCount+=f}}var g=r.length>0?d.TRANSLUCENT:this.blendOption;t.blendOption=g,r.blendOption=g,t._highlightColor=this._highlightColor,r._highlightColor=this._highlightColor,this._labelsToUpdate.length=0,r.update(e),t.update(e)},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){return this.removeAll(),this._billboardCollection=this._billboardCollection.destroy(),this._textureAtlas=this._textureAtlas&&this._textureAtlas.destroy(),this._backgroundBillboardCollection=this._backgroundBillboardCollection.destroy(),this._backgroundTextureAtlas=this._backgroundTextureAtlas&&this._backgroundTextureAtlas.destroy(),a(this)},x}),define("Scene/PointPrimitive",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Matrix4","../Core/NearFarScalar","./SceneMode","./SceneTransforms"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e,t){e=o(e,o.EMPTY_OBJECT);var i=e.translucencyByDistance,s=e.scaleByDistance,l=e.distanceDisplayCondition;a(i)&&(i=d.clone(i)),a(s)&&(s=d.clone(s)),a(l)&&(l=u.clone(l)),this._show=o(e.show,!0),this._position=r.clone(o(e.position,r.ZERO)),this._actualPosition=r.clone(this._position),this._color=n.clone(o(e.color,n.WHITE)),this._outlineColor=n.clone(o(e.outlineColor,n.TRANSPARENT)),this._outlineWidth=o(e.outlineWidth,0),this._pixelSize=o(e.pixelSize,10),this._scaleByDistance=s,this._translucencyByDistance=i,this._distanceDisplayCondition=l,this._disableDepthTestDistance=o(e.disableDepthTestDistance,0),this._id=e.id,this._collection=o(e.collection,t),this._clusterShow=!0,this._pickId=void 0,this._pointPrimitiveCollection=t,this._dirty=!1,this._index=-1}function m(e,t){var r=e._pointPrimitiveCollection;a(r)&&(r._updatePointPrimitive(e,t),e._dirty=!0)}var g=f.SHOW_INDEX=0,_=f.POSITION_INDEX=1,v=f.COLOR_INDEX=2,y=f.OUTLINE_COLOR_INDEX=3,b=f.OUTLINE_WIDTH_INDEX=4,C=f.PIXEL_SIZE_INDEX=5,S=f.SCALE_BY_DISTANCE_INDEX=6,w=f.TRANSLUCENCY_BY_DISTANCE_INDEX=7,T=f.DISTANCE_DISPLAY_CONDITION_INDEX=8,E=f.DISABLE_DEPTH_DISTANCE_INDEX=9;f.NUMBER_OF_PROPERTIES=10,s(f.prototype,{show:{get:function(){return this._show},set:function(e){this._show!==e&&(this._show=e,m(this,g))}},position:{get:function(){return this._position},set:function(e){var t=this._position;r.equals(t,e)||(r.clone(e,t),r.clone(e,this._actualPosition),m(this,_))}},scaleByDistance:{get:function(){return this._scaleByDistance},set:function(e){var t=this._scaleByDistance;d.equals(t,e)||(this._scaleByDistance=d.clone(e,t),m(this,S))}},translucencyByDistance:{get:function(){return this._translucencyByDistance},set:function(e){var t=this._translucencyByDistance;d.equals(t,e)||(this._translucencyByDistance=d.clone(e,t),m(this,w))}},pixelSize:{get:function(){return this._pixelSize},set:function(e){this._pixelSize!==e&&(this._pixelSize=e,m(this,C))}},color:{get:function(){return this._color},set:function(e){var t=this._color;n.equals(t,e)||(n.clone(e,t),m(this,v))}},outlineColor:{get:function(){return this._outlineColor},set:function(e){var t=this._outlineColor;n.equals(t,e)||(n.clone(e,t),m(this,y))}},outlineWidth:{get:function(){return this._outlineWidth},set:function(e){this._outlineWidth!==e&&(this._outlineWidth=e,m(this,b))}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){u.equals(this._distanceDisplayCondition,e)||(this._distanceDisplayCondition=u.clone(e,this._distanceDisplayCondition),m(this,T))}},disableDepthTestDistance:{get:function(){return this._disableDepthTestDistance},set:function(e){this._disableDepthTestDistance!==e&&(this._disableDepthTestDistance=e,m(this,E))}},id:{get:function(){return this._id},set:function(e){this._id=e,a(this._pickId)&&(this._pickId.object.id=e)}},clusterShow:{get:function(){return this._clusterShow},set:function(e){this._clusterShow!==e&&(this._clusterShow=e,m(this,g))}}}),f.prototype.getPickId=function(e){return a(this._pickId)||(this._pickId=e.createPickId({primitive:this,collection:this._collection,id:this._id})),this._pickId},f.prototype._getActualPosition=function(){return this._actualPosition},f.prototype._setActualPosition=function(e){r.clone(e,this._actualPosition),m(this,_)};var A=new i;f._computeActualPosition=function(e,t,r){return t.mode===h.SCENE3D?e:(c.multiplyByPoint(r,e,A),p.computeActualWgs84Position(t,A))};var x=new i;return f._computeScreenSpacePosition=function(e,t,r,n){var o=c.multiplyByVector(e,i.fromElements(t.x,t.y,t.z,1,x),x);return p.wgs84ToWindowCoordinates(r,o,n)},f.prototype.computeScreenSpacePosition=function(e,r){var i=this._pointPrimitiveCollection;a(r)||(r=new t);var n=i.modelMatrix,o=f._computeScreenSpacePosition(n,this._actualPosition,e,r);if(a(o))return o.y=e.canvas.clientHeight-o.y,o},f.getScreenSpaceBoundingBox=function(t,r,i){var n=t.pixelSize,o=.5*n,s=r.x-o,l=r.y-o,u=n,c=n;return a(i)||(i=new e),i.x=s,i.y=l,i.width=u,i.height=c,i},f.prototype.equals=function(e){return this===e||a(e)&&this._id===e._id&&r.equals(this._position,e._position)&&n.equals(this._color,e._color)&&this._pixelSize===e._pixelSize&&this._outlineWidth===e._outlineWidth&&this._show===e._show&&n.equals(this._outlineColor,e._outlineColor)&&d.equals(this._scaleByDistance,e._scaleByDistance)&&d.equals(this._translucencyByDistance,e._translucencyByDistance)&&u.equals(this._distanceDisplayCondition,e._distanceDisplayCondition)&&this._disableDepthTestDistance===e._disableDepthTestDistance},f.prototype._destroy=function(){this._pickId=this._pickId&&this._pickId.destroy(),this._pointPrimitiveCollection=void 0},f}),define("Shaders/PointPrimitiveCollectionFS",[],function(){"use strict";return"varying vec4 v_color;\nvarying vec4 v_outlineColor;\nvarying float v_innerPercent;\nvarying float v_pixelDistance;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#endif\nvoid main()\n{\nfloat distanceToCenter = length(gl_PointCoord - vec2(0.5));\nfloat maxDistance = max(0.0, 0.5 - v_pixelDistance);\nfloat wholeAlpha = 1.0 - smoothstep(maxDistance, 0.5, distanceToCenter);\nfloat innerAlpha = 1.0 - smoothstep(maxDistance * v_innerPercent, 0.5 * v_innerPercent, distanceToCenter);\nvec4 color = mix(v_outlineColor, v_color, innerAlpha);\ncolor.a *= wholeAlpha;\n#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\nif (color.a < 0.005)\n{\ndiscard;\n}\n#else\n#ifdef OPAQUE\nif (color.a < 0.995)\n{\ndiscard;\n}\n#else\nif (color.a >= 0.995)\n{\ndiscard;\n}\n#endif\n#endif\n#ifdef RENDER_FOR_PICK\ngl_FragColor = v_pickColor;\n#else\ngl_FragColor = color;\n#endif\n}\n"}),define("Shaders/PointPrimitiveCollectionVS",[],function(){"use strict";return"uniform float u_maxTotalPointSize;\nattribute vec4 positionHighAndSize;\nattribute vec4 positionLowAndOutline;\nattribute vec4 compressedAttribute0;\nattribute vec4 compressedAttribute1;\nattribute vec4 scaleByDistance;\nattribute vec3 distanceDisplayConditionAndDisableDepth;\nvarying vec4 v_color;\nvarying vec4 v_outlineColor;\nvarying float v_innerPercent;\nvarying float v_pixelDistance;\n#ifdef RENDER_FOR_PICK\nvarying vec4 v_pickColor;\n#endif\nconst float SHIFT_LEFT8 = 256.0;\nconst float SHIFT_RIGHT8 = 1.0 / 256.0;\nvoid main()\n{\nvec3 positionHigh = positionHighAndSize.xyz;\nvec3 positionLow = positionLowAndOutline.xyz;\nfloat outlineWidthBothSides = 2.0 * positionLowAndOutline.w;\nfloat totalSize = positionHighAndSize.w + outlineWidthBothSides;\nfloat outlinePercent = outlineWidthBothSides / totalSize;\ntotalSize *= czm_resolutionScale;\ntotalSize += 3.0;\nfloat temp = compressedAttribute1.x * SHIFT_RIGHT8;\nfloat show = floor(temp);\n#ifdef EYE_DISTANCE_TRANSLUCENCY\nvec4 translucencyByDistance;\ntranslucencyByDistance.x = compressedAttribute1.z;\ntranslucencyByDistance.z = compressedAttribute1.w;\ntranslucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\ntemp = compressedAttribute1.y * SHIFT_RIGHT8;\ntranslucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n#endif\nvec4 color;\nvec4 outlineColor;\n#ifdef RENDER_FOR_PICK\ncolor = vec4(0.0);\noutlineColor = vec4(0.0);\nvec4 pickColor;\ntemp = compressedAttribute0.z * SHIFT_RIGHT8;\npickColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\npickColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\npickColor.r = floor(temp);\n#else\ntemp = compressedAttribute0.x * SHIFT_RIGHT8;\ncolor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\ncolor.g = (temp - floor(temp)) * SHIFT_LEFT8;\ncolor.r = floor(temp);\ntemp = compressedAttribute0.y * SHIFT_RIGHT8;\noutlineColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\ntemp = floor(temp) * SHIFT_RIGHT8;\noutlineColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\noutlineColor.r = floor(temp);\n#endif\ntemp = compressedAttribute0.w * SHIFT_RIGHT8;\n#ifdef RENDER_FOR_PICK\npickColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\npickColor = pickColor / 255.0;\n#endif\ntemp = floor(temp) * SHIFT_RIGHT8;\noutlineColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\noutlineColor /= 255.0;\ncolor.a = floor(temp);\ncolor /= 255.0;\nvec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\nvec4 positionEC = czm_modelViewRelativeToEye * p;\npositionEC.xyz *= show;\n#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\nfloat lengthSq;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nlengthSq = czm_eyeHeight2D.y;\n}\nelse\n{\nlengthSq = dot(positionEC.xyz, positionEC.xyz);\n}\n#endif\n#ifdef EYE_DISTANCE_SCALING\ntotalSize *= czm_nearFarScalar(scaleByDistance, lengthSq);\n#endif\ntotalSize = min(totalSize, u_maxTotalPointSize);\nif (totalSize < 1.0)\n{\npositionEC.xyz = vec3(0.0);\ntotalSize = 1.0;\n}\nfloat translucency = 1.0;\n#ifdef EYE_DISTANCE_TRANSLUCENCY\ntranslucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\nif (translucency < 0.004)\n{\npositionEC.xyz = vec3(0.0);\n}\n#endif\n#ifdef DISTANCE_DISPLAY_CONDITION\nfloat nearSq = distanceDisplayConditionAndDisableDepth.x;\nfloat farSq = distanceDisplayConditionAndDisableDepth.y;\nif (lengthSq < nearSq || lengthSq > farSq) {\npositionEC.xyz = vec3(0.0);\n}\n#endif\nvec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\ngl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\n#ifdef DISABLE_DEPTH_DISTANCE\nfloat disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\nif (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n{\ndisableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n}\nif (disableDepthTestDistance != 0.0)\n{\nfloat zclip = gl_Position.z / gl_Position.w;\nbool clipped = (zclip < -1.0 || zclip > 1.0);\nif (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n{\ngl_Position.z = -gl_Position.w;\n}\n}\n#endif\nv_color = color;\nv_color.a *= translucency;\nv_outlineColor = outlineColor;\nv_outlineColor.a *= translucency;\nv_innerPercent = 1.0 - outlinePercent;\nv_pixelDistance = 2.0 / totalSize;\ngl_PointSize = totalSize;\n#ifdef RENDER_FOR_PICK\nv_pickColor = pickColor;\n#endif\n}\n"}),define("Scene/PointPrimitiveCollection",["../Core/BoundingSphere","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EncodedCartesian3","../Core/Math","../Core/Matrix4","../Core/PrimitiveType","../Core/WebGLConstants","../Renderer/BufferUsage","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArrayFacade","../Shaders/PointPrimitiveCollectionFS","../Shaders/PointPrimitiveCollectionVS","./BlendingState","./BlendOption","./PointPrimitive","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A){"use strict";function x(t){t=i(t,i.EMPTY_OBJECT),this._sp=void 0,this._spTranslucent=void 0,this._spPick=void 0,this._rsOpaque=void 0,this._rsTranslucent=void 0,this._vaf=void 0,this._pointPrimitives=[],this._pointPrimitivesToUpdate=[],this._pointPrimitivesToUpdateIndex=0,this._pointPrimitivesRemoved=!1,this._createVertexArray=!1,this._shaderScaleByDistance=!1,this._compiledShaderScaleByDistance=!1,this._compiledShaderScaleByDistancePick=!1,this._shaderTranslucencyByDistance=!1,this._compiledShaderTranslucencyByDistance=!1,this._compiledShaderTranslucencyByDistancePick=!1,this._shaderDistanceDisplayCondition=!1,this._compiledShaderDistanceDisplayCondition=!1,this._compiledShaderDistanceDisplayConditionPick=!1,this._shaderDisableDepthDistance=!1,this._compiledShaderDisableDepthDistance=!1,this._compiledShaderDisableDepthDistancePick=!1,this._propertiesChanged=new Uint32Array(Z),this._maxPixelSize=1,this._baseVolume=new e,this._baseVolumeWC=new e,this._baseVolume2D=new e,this._boundingVolume=new e,this._boundingVolumeDirty=!1,this._colorCommands=[],this._pickCommands=[],this.modelMatrix=c.clone(i(t.modelMatrix,c.IDENTITY)),this._modelMatrix=c.clone(c.IDENTITY),this.debugShowBoundingVolume=i(t.debugShowBoundingVolume,!1),this.blendOption=i(t.blendOption,T.OPAQUE_AND_TRANSLUCENT),this._blendOption=void 0,this._mode=A.SCENE3D,this._maxTotalPointSize=1,this._buffersUsage=[p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW,p.STATIC_DRAW];var r=this;this._uniforms={u_maxTotalPointSize:function(){return r._maxTotalPointSize}}}function P(e){for(var t=e.length,r=0;r<t;++r)e[r]&&e[r]._destroy()}function D(e){if(e._pointPrimitivesRemoved){e._pointPrimitivesRemoved=!1;for(var t=[],r=e._pointPrimitives,i=r.length,n=0,o=0;n<i;++n){var a=r[n];a&&(a._index=o++,t.push(a))}e._pointPrimitives=t}}function I(e,t,i){return new b(e,[{index:K.positionHighAndSize,componentsPerAttribute:4,componentDatatype:r.FLOAT,usage:i[z]},{index:K.positionLowAndShow,componentsPerAttribute:4,componentDatatype:r.FLOAT,usage:i[z]},{index:K.compressedAttribute0,componentsPerAttribute:4,componentDatatype:r.FLOAT,usage:i[G]},{index:K.compressedAttribute1,componentsPerAttribute:4,componentDatatype:r.FLOAT,usage:i[Y]},{index:K.scaleByDistance,componentsPerAttribute:4,componentDatatype:r.FLOAT,usage:i[q]},{index:K.distanceDisplayConditionAndDisableDepth,componentsPerAttribute:3,componentDatatype:r.FLOAT,usage:i[X]}],t)}function O(t,r,i,n){var o=n._index,a=n._getActualPosition();t._mode===A.SCENE3D&&(e.expand(t._baseVolume,a,t._baseVolume),t._boundingVolumeDirty=!0),l.fromCartesian(a,J);var s=n.pixelSize,u=n.outlineWidth;t._maxPixelSize=Math.max(t._maxPixelSize,s+u);var c=i[K.positionHighAndSize],d=J.high;c(o,d.x,d.y,d.z,s);var h=i[K.positionLowAndOutline],p=J.low;h(o,p.x,p.y,p.z,u)}function M(e,r,i,n){var o=n._index,a=n.color,s=n.getPickId(r).color,l=n.outlineColor,u=t.floatToByte(a.red),c=t.floatToByte(a.green),d=t.floatToByte(a.blue),h=u*$+c*ee+d;u=t.floatToByte(l.red),c=t.floatToByte(l.green),d=t.floatToByte(l.blue);var p=u*$+c*ee+d;u=t.floatToByte(s.red),c=t.floatToByte(s.green),d=t.floatToByte(s.blue);var f=u*$+c*ee+d,m=t.floatToByte(a.alpha)*$+t.floatToByte(l.alpha)*ee+t.floatToByte(s.alpha);(0,i[K.compressedAttribute0])(o,h,p,f,m)}function R(e,t,r,i){var o=i._index,a=0,s=1,l=1,c=1,d=i.translucencyByDistance;n(d)&&(a=d.near,s=d.nearValue,l=d.far,c=d.farValue,1===s&&1===c||(e._shaderTranslucencyByDistance=!0));var h=i.show&&i.clusterShow;0===i.color.alpha&&0===i.outlineColor.alpha&&(h=!1),s=u.clamp(s,0,1),s=1===s?255:255*s|0;var p=(h?1:0)*ee+s;c=u.clamp(c,0,1),c=1===c?255:255*c|0;var f=c;(0,r[K.compressedAttribute1])(o,p,f,a,l)}function L(e,t,r,i){var o=i._index,a=r[K.scaleByDistance],s=0,l=1,u=1,c=1,d=i.scaleByDistance;n(d)&&(s=d.near,l=d.nearValue,u=d.far,c=d.farValue,1===l&&1===c||(e._shaderScaleByDistance=!0)),a(o,s,l,u,c)}function N(e,t,r,i){var o=i._index,a=r[K.distanceDisplayConditionAndDisableDepth],s=0,l=Number.MAX_VALUE,u=i.distanceDisplayCondition;n(u)&&(s=u.near,l=u.far,s*=s,l*=l,e._shaderDistanceDisplayCondition=!0);var c=i.disableDepthTestDistance;c*=c,c>0&&(e._shaderDisableDepthDistance=!0,c===Number.POSITIVE_INFINITY&&(c=-1)),a(o,s,l,c)}function k(e,t,r,i){O(e,t,r,i),M(e,t,r,i),R(e,t,r,i),L(e,t,r,i),N(e,t,r,i)}function F(t,r,i,o,a,s){var l;o.mode===A.SCENE3D?(l=t._baseVolume,t._boundingVolumeDirty=!0):l=t._baseVolume2D;for(var u=[],c=0;c<i;++c){var d=r[c],h=d.position,p=E._computeActualPosition(h,o,a);n(p)&&(d._setActualPosition(p),s?u.push(p):e.expand(l,p,l))}s&&e.fromPoints(u,l)}function B(e,t){var r=t.mode,i=e._pointPrimitives,n=e._pointPrimitivesToUpdate,o=e._modelMatrix;e._createVertexArray||e._mode!==r||r!==A.SCENE3D&&!c.equals(o,e.modelMatrix)?(e._mode=r,c.clone(e.modelMatrix,o),e._createVertexArray=!0,r!==A.SCENE3D&&r!==A.SCENE2D&&r!==A.COLUMBUS_VIEW||F(e,i,i.length,t,o,!0)):r===A.MORPHING?F(e,i,i.length,t,o,!0):r!==A.SCENE2D&&r!==A.COLUMBUS_VIEW||F(e,n,e._pointPrimitivesToUpdateIndex,t,o,!1)}function U(e,t,r){var i=t.camera.getPixelSize(r,t.context.drawingBufferWidth,t.context.drawingBufferHeight),n=i*e._maxPixelSize;r.radius+=n}var V=E.SHOW_INDEX,z=E.POSITION_INDEX,G=E.COLOR_INDEX,W=E.OUTLINE_COLOR_INDEX,H=E.OUTLINE_WIDTH_INDEX,j=E.PIXEL_SIZE_INDEX,q=E.SCALE_BY_DISTANCE_INDEX,Y=E.TRANSLUCENCY_BY_DISTANCE_INDEX,X=E.DISTANCE_DISPLAY_CONDITION_INDEX,Q=E.DISABLE_DEPTH_DISTANCE_INDEX,Z=E.NUMBER_OF_PROPERTIES,K={positionHighAndSize:0,positionLowAndOutline:1,compressedAttribute0:2,compressedAttribute1:3,scaleByDistance:4,distanceDisplayConditionAndDisableDepth:5};o(x.prototype,{length:{get:function(){return D(this),this._pointPrimitives.length}}}),x.prototype.add=function(e){var t=new E(e,this);return t._index=this._pointPrimitives.length,this._pointPrimitives.push(t),this._createVertexArray=!0,t},x.prototype.remove=function(e){return!!this.contains(e)&&(this._pointPrimitives[e._index]=null,this._pointPrimitivesRemoved=!0,this._createVertexArray=!0,e._destroy(),!0)},x.prototype.removeAll=function(){P(this._pointPrimitives),this._pointPrimitives=[],this._pointPrimitivesToUpdate=[],this._pointPrimitivesToUpdateIndex=0,this._pointPrimitivesRemoved=!1,this._createVertexArray=!0},x.prototype._updatePointPrimitive=function(e,t){e._dirty||(this._pointPrimitivesToUpdate[this._pointPrimitivesToUpdateIndex++]=e),++this._propertiesChanged[t]},x.prototype.contains=function(e){return n(e)&&e._pointPrimitiveCollection===this},x.prototype.get=function(e){return D(this),this._pointPrimitives[e]},x.prototype.computeNewBuffersUsage=function(){for(var e=this._buffersUsage,t=!1,r=this._propertiesChanged,i=0;i<Z;++i){var n=0===r[i]?p.STATIC_DRAW:p.STREAM_DRAW;t=t||e[i]!==n,e[i]=n}return t};var J=new l,$=65536,ee=256,te=[];return x.prototype.update=function(t){D(this),this._maxTotalPointSize=f.maximumAliasedPointSize,B(this,t);var r,i=this._pointPrimitives,o=i.length,a=this._pointPrimitivesToUpdate,s=this._pointPrimitivesToUpdateIndex,l=this._propertiesChanged,u=this._createVertexArray,p=t.context,b=t.passes,E=b.pick;if(u||!E&&this.computeNewBuffersUsage()){this._createVertexArray=!1;for(var x=0;x<Z;++x)l[x]=0;if(this._vaf=this._vaf&&this._vaf.destroy(),o>0){this._vaf=I(p,o,this._buffersUsage),r=this._vaf.writers;for(var P=0;P<o;++P){var F=this._pointPrimitives[P];F._dirty=!1,k(this,p,r,F)}this._vaf.commit()}this._pointPrimitivesToUpdateIndex=0}else if(s>0){var J=te;J.length=0,(l[z]||l[H]||l[j])&&J.push(O),(l[G]||l[W])&&J.push(M),(l[V]||l[Y])&&J.push(R),l[q]&&J.push(L),(l[X]||l[Q])&&J.push(N);var $=J.length;if(r=this._vaf.writers,s/o>.1){for(var ee=0;ee<s;++ee){var re=a[ee];re._dirty=!1;for(var ie=0;ie<$;++ie)J[ie](this,p,r,re)}this._vaf.commit()}else{for(var ne=0;ne<s;++ne){var oe=a[ne];oe._dirty=!1;for(var ae=0;ae<$;++ae)J[ae](this,p,r,oe);this._vaf.subCommit(oe._index,1)}this._vaf.endSubCommits()}this._pointPrimitivesToUpdateIndex=0}if(s>1.5*o&&(a.length=o),n(this._vaf)&&n(this._vaf.va)){this._boundingVolumeDirty&&(this._boundingVolumeDirty=!1,e.transform(this._baseVolume,this.modelMatrix,this._baseVolumeWC));var se,le=c.IDENTITY;t.mode===A.SCENE3D?(le=this.modelMatrix,se=e.clone(this._baseVolumeWC,this._boundingVolume)):se=e.clone(this._baseVolume2D,this._boundingVolume),U(this,t,se);var ue=this._blendOption!==this.blendOption;this._blendOption=this.blendOption,ue&&(this._blendOption===T.OPAQUE||this._blendOption===T.OPAQUE_AND_TRANSLUCENT?this._rsOpaque=_.fromCache({depthTest:{enabled:!0,func:h.LEQUAL},depthMask:!0}):this._rsOpaque=void 0,this._blendOption===T.TRANSLUCENT||this._blendOption===T.OPAQUE_AND_TRANSLUCENT?this._rsTranslucent=_.fromCache({depthTest:{enabled:!0,func:h.LEQUAL},depthMask:!1,blending:w.ALPHA_BLEND}):this._rsTranslucent=void 0),this._shaderDisableDepthDistance=this._shaderDisableDepthDistance||0!==t.minimumDisableDepthTestDistance;var ce,de;(ue||this._shaderScaleByDistance&&!this._compiledShaderScaleByDistance||this._shaderTranslucencyByDistance&&!this._compiledShaderTranslucencyByDistance||this._shaderDistanceDisplayCondition&&!this._compiledShaderDistanceDisplayCondition||this._shaderDisableDepthDistance!==this._compiledShaderDisableDepthDistance)&&(ce=new y({sources:[S]}),this._shaderScaleByDistance&&ce.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&ce.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderDistanceDisplayCondition&&ce.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&ce.defines.push("DISABLE_DEPTH_DISTANCE"),this._blendOption===T.OPAQUE_AND_TRANSLUCENT&&(de=new y({defines:["OPAQUE"],sources:[C]}),this._sp=v.replaceCache({context:p,shaderProgram:this._sp,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K}),de=new y({defines:["TRANSLUCENT"],sources:[C]}),this._spTranslucent=v.replaceCache({context:p,shaderProgram:this._spTranslucent,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K})),this._blendOption===T.OPAQUE&&(de=new y({sources:[C]}),this._sp=v.replaceCache({context:p,shaderProgram:this._sp,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K})),this._blendOption===T.TRANSLUCENT&&(de=new y({sources:[C]}),this._spTranslucent=v.replaceCache({context:p,shaderProgram:this._spTranslucent,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K})),this._compiledShaderScaleByDistance=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistance=this._shaderTranslucencyByDistance,this._compiledShaderDistanceDisplayCondition=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistance=this._shaderDisableDepthDistance),(!n(this._spPick)||this._shaderScaleByDistance&&!this._compiledShaderScaleByDistancePick||this._shaderTranslucencyByDistance&&!this._compiledShaderTranslucencyByDistancePick||this._shaderDistanceDisplayCondition&&!this._compiledShaderDistanceDisplayConditionPick||this._shaderDisableDepthDistance!==this._compiledShaderDisableDepthDistancePick)&&(ce=new y({defines:["RENDER_FOR_PICK"],sources:[S]}),this._shaderScaleByDistance&&ce.defines.push("EYE_DISTANCE_SCALING"),this._shaderTranslucencyByDistance&&ce.defines.push("EYE_DISTANCE_TRANSLUCENCY"),this._shaderDistanceDisplayCondition&&ce.defines.push("DISTANCE_DISPLAY_CONDITION"),this._shaderDisableDepthDistance&&ce.defines.push("DISABLE_DEPTH_DISTANCE"),de=new y({defines:["RENDER_FOR_PICK"],sources:[C]}),this._spPick=v.replaceCache({context:p,shaderProgram:this._spPick,vertexShaderSource:ce,fragmentShaderSource:de,attributeLocations:K}),this._compiledShaderScaleByDistancePick=this._shaderScaleByDistance,this._compiledShaderTranslucencyByDistancePick=this._shaderTranslucencyByDistance,this._compiledShaderDistanceDisplayConditionPick=this._shaderDistanceDisplayCondition,this._compiledShaderDisableDepthDistancePick=this._shaderDisableDepthDistance);var he,pe,fe,me,ge=t.commandList;if(b.render){var _e=this._colorCommands,ve=this._blendOption===T.OPAQUE,ye=this._blendOption===T.OPAQUE_AND_TRANSLUCENT;he=this._vaf.va,pe=he.length,_e.length=pe;var be=ye?2*pe:pe;for(me=0;me<be;++me){var Ce=ve||ye&&me%2==0;fe=_e[me],n(fe)||(fe=_e[me]=new m),fe.primitiveType=d.POINTS,fe.pass=Ce||!ye?g.OPAQUE:g.TRANSLUCENT,fe.owner=this;var Se=ye?Math.floor(me/2):me;fe.boundingVolume=se,fe.modelMatrix=le,fe.shaderProgram=Ce?this._sp:this._spTranslucent,fe.uniformMap=this._uniforms,fe.vertexArray=he[Se].va,fe.renderState=Ce?this._rsOpaque:this._rsTranslucent,fe.debugShowBoundingVolume=this.debugShowBoundingVolume,ge.push(fe)}}if(E){var we=this._pickCommands;for(he=this._vaf.va,pe=he.length,we.length=pe,me=0;me<pe;++me)fe=we[me],n(fe)||(fe=we[me]=new m({primitiveType:d.POINTS,pass:g.OPAQUE,owner:this})),fe.boundingVolume=se,fe.modelMatrix=le,fe.shaderProgram=this._spPick,fe.uniformMap=this._uniforms,fe.vertexArray=he[me].va,fe.renderState=this._rsOpaque,ge.push(fe)}}},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){return this._sp=this._sp&&this._sp.destroy(),this._spTranslucent=this._spTranslucent&&this._spTranslucent.destroy(),this._spPick=this._spPick&&this._spPick.destroy(),this._vaf=this._vaf&&this._vaf.destroy(),P(this._pointPrimitives),a(this)},x}),define("ThirdParty/kdbush",[],function(){"use strict";function e(e,r,i,n,o){return new t(e,r,i,n,o)}function t(e,t,n,a,s){t=t||r,n=n||i,s=s||Array,this.nodeSize=a||64,this.points=e,this.ids=new s(e.length),this.coords=new s(2*e.length);for(var l=0;l<e.length;l++)this.ids[l]=l,this.coords[2*l]=t(e[l]),this.coords[2*l+1]=n(e[l]);o(this.ids,this.coords,this.nodeSize,0,this.ids.length-1,0)}function r(e){return e[0]}function i(e){return e[1]}function n(e,t,r,i,n,o,a){for(var s,l,u=[0,e.length-1,0],c=[];u.length;){var d=u.pop(),h=u.pop(),p=u.pop();if(h-p<=a)for(var f=p;f<=h;f++)s=t[2*f],l=t[2*f+1],s>=r&&s<=n&&l>=i&&l<=o&&c.push(e[f]);else{var m=Math.floor((p+h)/2);s=t[2*m],l=t[2*m+1],s>=r&&s<=n&&l>=i&&l<=o&&c.push(e[m]);var g=(d+1)%2;(0===d?r<=s:i<=l)&&(u.push(p),u.push(m-1),u.push(g)),(0===d?n>=s:o>=l)&&(u.push(m+1),u.push(h),u.push(g))}}return c}function o(e,t,r,i,n,s){if(!(n-i<=r)){var l=Math.floor((i+n)/2);a(e,t,l,i,n,s%2),o(e,t,r,i,l-1,s+1),o(e,t,r,l+1,n,s+1)}}function a(e,t,r,i,n,o){for(;n>i;){if(n-i>600){var l=n-i+1,u=r-i+1,c=Math.log(l),d=.5*Math.exp(2*c/3),h=.5*Math.sqrt(c*d*(l-d)/l)*(u-l/2<0?-1:1);a(e,t,r,Math.max(i,Math.floor(r-u*d/l+h)),Math.min(n,Math.floor(r+(l-u)*d/l+h)),o)}var p=t[2*r+o],f=i,m=n;for(s(e,t,i,r),t[2*n+o]>p&&s(e,t,i,n);f<m;){for(s(e,t,f,m),f++,m--;t[2*f+o]<p;)f++;for(;t[2*m+o]>p;)m--}t[2*i+o]===p?s(e,t,i,m):(m++,s(e,t,m,n)),m<=r&&(i=m+1),r<=m&&(n=m-1)}}function s(e,t,r,i){l(e,r,i),l(t,2*r,2*i),l(t,2*r+1,2*i+1)}function l(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}function u(e,t,r,i,n,o){for(var a=[0,e.length-1,0],s=[],l=n*n;a.length;){var u=a.pop(),d=a.pop(),h=a.pop();if(d-h<=o)for(var p=h;p<=d;p++)c(t[2*p],t[2*p+1],r,i)<=l&&s.push(e[p]);else{var f=Math.floor((h+d)/2),m=t[2*f],g=t[2*f+1];c(m,g,r,i)<=l&&s.push(e[f]);var _=(u+1)%2;(0===u?r-n<=m:i-n<=g)&&(a.push(h),a.push(f-1),a.push(_)),(0===u?r+n>=m:i+n>=g)&&(a.push(f+1),a.push(d),a.push(_))}}return s}function c(e,t,r,i){var n=e-r,o=t-i;return n*n+o*o}return t.prototype={range:function(e,t,r,i){return n(this.ids,this.coords,e,t,r,i,this.nodeSize)},within:function(e,t,r){return u(this.ids,this.coords,e,t,r,this.nodeSize)}},e}), +define("DataSources/EntityCluster",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/EllipsoidalOccluder","../Core/Event","../Core/Matrix4","../Scene/Billboard","../Scene/BillboardCollection","../Scene/Label","../Scene/LabelCollection","../Scene/PointPrimitive","../Scene/PointPrimitiveCollection","../Scene/SceneMode","../ThirdParty/kdbush"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){e=i(e,i.EMPTY_OBJECT),this._enabled=i(e.enabled,!1),this._pixelRange=i(e.pixelRange,80),this._minimumClusterSize=i(e.minimumClusterSize,2),this._clusterBillboards=i(e.clusterBillboards,!0),this._clusterLabels=i(e.clusterLabels,!0),this._clusterPoints=i(e.clusterPoints,!0),this._labelCollection=void 0,this._billboardCollection=void 0,this._pointCollection=void 0,this._clusterBillboardCollection=void 0,this._clusterLabelCollection=void 0,this._clusterPointCollection=void 0,this._collectionIndicesByEntity={},this._unusedLabelIndices=[],this._unusedBillboardIndices=[],this._unusedPointIndices=[],this._previousClusters=[],this._previousHeight=void 0,this._enabledDirty=!1,this._clusterDirty=!1,this._cluster=void 0,this._removeEventListener=void 0,this._clusterEvent=new s}function v(e){return e.coord.x}function y(e){return e.coord.y}function b(e,t){e.x-=t,e.y-=t,e.width+=2*t,e.height+=2*t}function C(t,r,i,o,a){if(n(t._labelCollection)&&o._clusterLabels?a=d.getScreenSpaceBoundingBox(t,r,a):n(t._billboardCollection)&&o._clusterBillboards?a=u.getScreenSpaceBoundingBox(t,r,a):n(t._pointPrimitiveCollection)&&o._clusterPoints&&(a=p.getScreenSpaceBoundingBox(t,r,a)),b(a,i),o._clusterLabels&&!n(t._labelCollection)&&n(t.id)&&T(o,t.id)&&n(t.id._label)){var s=o._collectionIndicesByEntity[t.id],l=o._labelCollection.get(s),c=d.getScreenSpaceBoundingBox(l,r,O);b(c,i),a=e.union(a,c,a)}return a}function S(e,t){if(e.clusterShow=!0,!n(e._labelCollection)&&n(e.id)&&T(t,e.id)&&n(e.id._label)){var r=t._collectionIndicesByEntity[e.id];t._labelCollection.get(r).clusterShow=!0}}function w(e,t,r,i){var n={billboard:i._clusterBillboardCollection.add(),label:i._clusterLabelCollection.add(),point:i._clusterPointCollection.add()};n.billboard.show=!1,n.point.show=!1,n.label.show=!0,n.label.text=t.toLocaleString(),n.label.id=r,n.billboard.position=n.label.position=n.point.position=e,i._clusterEvent.raiseEvent(r,n)}function T(e,t){return n(e)&&n(e._collectionIndicesByEntity[t])&&n(e._collectionIndicesByEntity[t].labelIndex)}function E(e,t,r,i,o){if(n(e))for(var a=e.length,s=0;s<a;++s){var l=e.get(s);if(l.clusterShow=!1,l.show&&(o._scene.mode!==m.SCENE3D||i.isPointVisible(l.position))){var u=o._clusterLabels&&n(l._labelCollection),c=o._clusterBillboards&&n(l.id._billboard),d=o._clusterPoints&&n(l.id._point);if(!u||!d&&!c){var h=l.computeScreenSpacePosition(r);n(h)&&t.push({index:s,collection:e,clustered:!1,coord:h})}}}}function A(i){return function(o){if(!(n(o)&&o<.05)&&i.enabled){var s=i._scene,d=i._labelCollection,p=i._billboardCollection,m=i._pointCollection;if((n(d)||n(p)||n(m))&&(i._clusterBillboards||i._clusterLabels||i._clusterPoints)){var _=i._clusterLabelCollection,b=i._clusterBillboardCollection,T=i._clusterPointCollection;n(_)?_.removeAll():_=i._clusterLabelCollection=new h({scene:s}),n(b)?b.removeAll():b=i._clusterBillboardCollection=new c({scene:s}),n(T)?T.removeAll():T=i._clusterPointCollection=new f;var A=i._pixelRange,x=i._minimumClusterSize,P=i._previousClusters,D=[],I=i._previousHeight,O=s.camera.positionCartographic.height,N=s.mapProjection.ellipsoid,k=s.camera.positionWC,F=new a(N,k),B=[];i._clusterLabels&&E(d,B,s,F,i),i._clusterBillboards&&E(p,B,s,F,i),i._clusterPoints&&E(m,B,s,F,i);var U,V,z,G,W,H,j,q,Y,X,Q,Z,K=g(B,v,y,64,Int32Array);if(O<I)for(z=P.length,U=0;U<z;++U){var J=P[U];if(F.isPointVisible(J.position)){var $=u._computeScreenSpacePosition(l.IDENTITY,J.position,r.ZERO,t.ZERO,s);if(n($)){var ee=1-O/I,te=J.width=J.width*ee,re=J.height=J.height*ee;te=Math.max(te,J.minimumWidth),re=Math.max(re,J.minimumHeight);var ie=$.x-.5*te,ne=$.y-.5*re,oe=$.x+te,ae=$.y+re;for(W=K.range(ie,ne,oe,ae),H=W.length,X=0,Y=[],V=0;V<H;++V)j=W[V],q=B[j],q.clustered||(++X,Q=q.collection,Z=q.index,Y.push(Q.get(Z).id));if(X>=x)for(w(J.position,X,Y,i),D.push(J),V=0;V<H;++V)B[W[V]].clustered=!0}}}for(z=B.length,U=0;U<z;++U){var se=B[U];if(!se.clustered){se.clustered=!0,Q=se.collection,Z=se.index;var le=Q.get(Z);G=C(le,se.coord,A,i,M);var ue=e.clone(G,R);W=K.range(G.x,G.y,G.x+G.width,G.y+G.height),H=W.length;var ce=r.clone(le.position);for(X=1,Y=[le.id],V=0;V<H;++V)if(j=W[V],q=B[j],!q.clustered){var de=q.collection.get(q.index),he=C(de,q.coord,A,i,L);r.add(de.position,ce,ce),e.union(ue,he,ue),++X,Y.push(de.id)}if(X>=x){var pe=r.multiplyByScalar(ce,1/X,ce);for(w(pe,X,Y,i),D.push({position:pe,width:ue.width,height:ue.height,minimumWidth:G.width,minimumHeight:G.height}),V=0;V<H;++V)B[W[V]].clustered=!0}else S(le,i)}}0===_.length&&(_.destroy(),i._clusterLabelCollection=void 0),0===b.length&&(b.destroy(),i._clusterBillboardCollection=void 0),0===T.length&&(T.destroy(),i._clusterPointCollection=void 0),i._previousClusters=D,i._previousHeight=O}}}}function x(e,t,r,i){return function(o){var a=this[e];n(this._collectionIndicesByEntity)||(this._collectionIndicesByEntity={});var s=this._collectionIndicesByEntity[o.id];if(n(s)||(s=this._collectionIndicesByEntity[o.id]={billboardIndex:void 0,labelIndex:void 0,pointIndex:void 0}),n(a)&&n(s[i]))return a.get(s[i]);n(a)||(a=this[e]=new t({scene:this._scene}));var l,u,c=this[r];return c.length>0?(l=c.pop(),u=a.get(l)):(u=a.add(),l=a.length-1),s[i]=l,this._clusterDirty=!0,u}}function P(e,t){var r=e._collectionIndicesByEntity[t];n(r.billboardIndex)||n(r.labelIndex)||n(r.pointIndex)||delete e._collectionIndicesByEntity[t]}function D(e){if(n(e))for(var t=e.length,r=0;r<t;++r)e.get(r).clusterShow=!0}function I(e){e.enabled||(n(e._clusterLabelCollection)&&e._clusterLabelCollection.destroy(),n(e._clusterBillboardCollection)&&e._clusterBillboardCollection.destroy(),n(e._clusterPointCollection)&&e._clusterPointCollection.destroy(),e._clusterLabelCollection=void 0,e._clusterBillboardCollection=void 0,e._clusterPointCollection=void 0,D(e._labelCollection),D(e._billboardCollection),D(e._pointCollection))}var O=new e,M=new e,R=new e,L=new e;return _.prototype._initialize=function(e){this._scene=e;var t=A(this);this._cluster=t,this._removeEventListener=e.camera.changed.addEventListener(t)},o(_.prototype,{enabled:{get:function(){return this._enabled},set:function(e){this._enabledDirty=e!==this._enabled,this._enabled=e}},pixelRange:{get:function(){return this._pixelRange},set:function(e){this._clusterDirty=this._clusterDirty||e!==this._pixelRange,this._pixelRange=e}},minimumClusterSize:{get:function(){return this._minimumClusterSize},set:function(e){this._clusterDirty=this._clusterDirty||e!==this._minimumClusterSize,this._minimumClusterSize=e}},clusterEvent:{get:function(){return this._clusterEvent}},clusterBillboards:{get:function(){return this._clusterBillboards},set:function(e){this._clusterDirty=this._clusterDirty||e!==this._clusterBillboards,this._clusterBillboards=e}},clusterLabels:{get:function(){return this._clusterLabels},set:function(e){this._clusterDirty=this._clusterDirty||e!==this._clusterLabels,this._clusterLabels=e}},clusterPoints:{get:function(){return this._clusterPoints},set:function(e){this._clusterDirty=this._clusterDirty||e!==this._clusterPoints,this._clusterPoints=e}}}),_.prototype.getLabel=x("_labelCollection",h,"_unusedLabelIndices","labelIndex"),_.prototype.removeLabel=function(e){var t=this._collectionIndicesByEntity&&this._collectionIndicesByEntity[e.id];if(n(this._labelCollection)&&n(t)&&n(t.labelIndex)){var r=t.labelIndex;t.labelIndex=void 0,P(this,e.id);var i=this._labelCollection.get(r);i.show=!1,i.text="",i.id=void 0,this._unusedLabelIndices.push(r),this._clusterDirty=!0}},_.prototype.getBillboard=x("_billboardCollection",c,"_unusedBillboardIndices","billboardIndex"),_.prototype.removeBillboard=function(e){var t=this._collectionIndicesByEntity&&this._collectionIndicesByEntity[e.id];if(n(this._billboardCollection)&&n(t)&&n(t.billboardIndex)){var r=t.billboardIndex;t.billboardIndex=void 0,P(this,e.id);var i=this._billboardCollection.get(r);i.id=void 0,i.show=!1,i.image=void 0,this._unusedBillboardIndices.push(r),this._clusterDirty=!0}},_.prototype.getPoint=x("_pointCollection",f,"_unusedPointIndices","pointIndex"),_.prototype.removePoint=function(e){var t=this._collectionIndicesByEntity&&this._collectionIndicesByEntity[e.id];if(n(this._pointCollection)&&n(t)&&n(t.pointIndex)){var r=t.pointIndex;t.pointIndex=void 0,P(this,e.id);var i=this._pointCollection.get(r);i.show=!1,i.id=void 0,this._unusedPointIndices.push(r),this._clusterDirty=!0}},_.prototype.update=function(e){var t;n(this._labelCollection)&&this._labelCollection.length>0&&0===this._labelCollection.get(0)._glyphs.length&&(t=e.commandList,e.commandList=[],this._labelCollection.update(e),e.commandList=t),n(this._billboardCollection)&&this._billboardCollection.length>0&&!n(this._billboardCollection.get(0).width)&&(t=e.commandList,e.commandList=[],this._billboardCollection.update(e),e.commandList=t),this._enabledDirty&&(this._enabledDirty=!1,I(this),this._clusterDirty=!0),this._clusterDirty&&(this._clusterDirty=!1,this._cluster()),n(this._clusterLabelCollection)&&this._clusterLabelCollection.update(e),n(this._clusterBillboardCollection)&&this._clusterBillboardCollection.update(e),n(this._clusterPointCollection)&&this._clusterPointCollection.update(e),n(this._labelCollection)&&this._labelCollection.update(e),n(this._billboardCollection)&&this._billboardCollection.update(e),n(this._pointCollection)&&this._pointCollection.update(e)},_.prototype.destroy=function(){this._labelCollection=this._labelCollection&&this._labelCollection.destroy(),this._billboardCollection=this._billboardCollection&&this._billboardCollection.destroy(),this._pointCollection=this._pointCollection&&this._pointCollection.destroy(),this._clusterLabelCollection=this._clusterLabelCollection&&this._clusterLabelCollection.destroy(),this._clusterBillboardCollection=this._clusterBillboardCollection&&this._clusterBillboardCollection.destroy(),this._clusterPointCollection=this._clusterPointCollection&&this._clusterPointCollection.destroy(),n(this._removeEventListener)&&(this._removeEventListener(),this._removeEventListener=void 0),this._labelCollection=void 0,this._billboardCollection=void 0,this._pointCollection=void 0,this._clusterBillboardCollection=void 0,this._clusterLabelCollection=void 0,this._clusterPointCollection=void 0,this._collectionIndicesByEntity=void 0,this._unusedLabelIndices=[],this._unusedBillboardIndices=[],this._unusedPointIndices=[],this._previousClusters=[],this._previousHeight=void 0,this._enabledDirty=!1,this._pixelRangeDirty=!1,this._minimumClusterSizeDirty=!1},_}),define("DataSources/CustomDataSource",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","./DataSource","./EntityCluster","./EntityCollection"],function(e,t,r,i,n,o,a){"use strict";function s(e){this._name=e,this._clock=void 0,this._changed=new i,this._error=new i,this._isLoading=!1,this._loading=new i,this._entityCollection=new a(this),this._entityCluster=new o}return t(s.prototype,{name:{get:function(){return this._name},set:function(e){this._name!==e&&(this._name=e,this._changed.raiseEvent(this))}},clock:{get:function(){return this._clock},set:function(e){this._clock!==e&&(this._clock=e,this._changed.raiseEvent(this))}},entities:{get:function(){return this._entityCollection}},isLoading:{get:function(){return this._isLoading},set:function(e){n.setLoading(this,e)}},changedEvent:{get:function(){return this._changed}},errorEvent:{get:function(){return this._error}},loadingEvent:{get:function(){return this._loading}},show:{get:function(){return this._entityCollection.show},set:function(e){this._entityCollection.show=e}},clustering:{get:function(){return this._entityCluster},set:function(e){this._entityCluster=e}}}),s}),define("DataSources/CylinderGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/CylinderGeometry","../Core/CylinderOutlineGeometry","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/ShowGeometryInstanceAttribute","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.length=void 0,this.topRadius=void 0,this.bottomRadius=void 0,this.slices=void 0,this.numberOfVerticalLines=void 0}function E(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(E.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new d,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"cylinder",e.cylinder,void 0)}function A(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(e.WHITE),P=new b(!0),D=new b(!0),I=new b(!1),O=new b(e.BLACK),M=new b(v.DISABLED),R=new b(new u),L=new e;return a(E,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),a(E.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!o(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!o(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!0},geometryChanged:{get:function(){return this._geometryChanged}}}),E.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},E.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},E.prototype.createFillGeometryInstance=function(i){var n,a,s=this._entity,l=s.isAvailable(i),u=new f(l&&s.isShowing&&this._showProperty.getValue(i)&&this._fillProperty.getValue(i)),d=this._distanceDisplayConditionProperty.getValue(i),m=c.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var g=e.WHITE;o(this._materialProperty.color)&&(this._materialProperty.color.isConstant||l)&&(g=this._materialProperty.color.getValue(i)),a=t.fromColor(g),n={show:u,distanceDisplayCondition:m,color:a}}else n={show:u,distanceDisplayCondition:m};return new h({id:s,geometry:new r(this._options),modelMatrix:s.computeModelMatrix(p.MINIMUM_VALUE),attributes:n})},E.prototype.createOutlineGeometryInstance=function(r){var n=this._entity,o=n.isAvailable(r),a=w.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),s=this._distanceDisplayConditionProperty.getValue(r);return new h({id:n,geometry:new i(this._options),modelMatrix:n.computeModelMatrix(p.MINIMUM_VALUE),attributes:{show:new f(o&&n.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(a),distanceDisplayCondition:c.fromDistanceDisplayCondition(s)}})},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){this._entitySubscription(),s(this)},E.prototype._onEntityPropertyChanged=function(e,t,r,i){if("availability"===t||"position"===t||"orientation"===t||"cylinder"===t){var a=e.cylinder;if(!o(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!o(s)||!s.isConstant||s.getValue(p.MINIMUM_VALUE),u=a.outline,c=o(u);if(c&&u.isConstant&&(c=u.getValue(p.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=e.position,h=a.length,f=a.topRadius,_=a.bottomRadius,v=a.show;if(o(v)&&v.isConstant&&!v.getValue(p.MINIMUM_VALUE)||!o(d)||!o(h)||!o(f)||!o(_))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var b=n(a.material,x),C=b instanceof y;this._materialProperty=b,this._fillProperty=n(s,D),this._showProperty=n(v,P),this._showOutlineProperty=n(a.outline,I),this._outlineColorProperty=c?n(a.outlineColor,O):void 0,this._shadowsProperty=n(a.shadows,M),this._distanceDisplayConditionProperty=n(a.distanceDisplayCondition,R);var S=a.slices,T=a.outlineWidth,E=a.numberOfVerticalLines;if(this._fillEnabled=l,this._outlineEnabled=c,d.isConstant&&w.isConstant(e.orientation)&&h.isConstant&&f.isConstant&&_.isConstant&&w.isConstant(S)&&w.isConstant(T)&&w.isConstant(E)){var A=this._options;A.vertexFormat=C?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,A.length=h.getValue(p.MINIMUM_VALUE),A.topRadius=f.getValue(p.MINIMUM_VALUE),A.bottomRadius=_.getValue(p.MINIMUM_VALUE),A.slices=o(S)?S.getValue(p.MINIMUM_VALUE):void 0,A.numberOfVerticalLines=o(E)?E.getValue(p.MINIMUM_VALUE):void 0,this._outlineWidth=o(T)?T.getValue(p.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},E.prototype.createDynamicUpdater=function(e){return new A(e,this)},A.prototype.update=function(n){var a=this._primitives;a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var s=this._geometryUpdater,l=s._entity,u=l.cylinder;if(l.isShowing&&l.isAvailable(n)&&w.getValueOrDefault(u.show,n,!0)){var d=this._options,p=l.computeModelMatrix(n),f=w.getValueOrUndefined(u.length,n),v=w.getValueOrUndefined(u.topRadius,n),y=w.getValueOrUndefined(u.bottomRadius,n);if(o(p)&&o(f)&&o(v)&&o(y)){d.length=f,d.topRadius=v,d.bottomRadius=y,d.slices=w.getValueOrUndefined(u.slices,n),d.numberOfVerticalLines=w.getValueOrUndefined(u.numberOfVerticalLines,n);var b=this._geometryUpdater.shadowsProperty.getValue(n),C=this._geometryUpdater.distanceDisplayConditionProperty,T=C.getValue(n),E=c.fromDistanceDisplayCondition(T);if(w.getValueOrDefault(u.fill,n,!0)){var A=S.getValue(n,s.fillMaterialProperty,this._material);this._material=A;var x=new m({material:A,translucent:A.isTranslucent(),closed:!0});d.vertexFormat=x.vertexFormat,this._primitive=a.add(new _({geometryInstances:new h({id:l,geometry:new r(d),modelMatrix:p,attributes:{distanceDisplayCondition:E}}),appearance:x,asynchronous:!1,shadows:b}))}if(w.getValueOrDefault(u.outline,n,!1)){d.vertexFormat=g.VERTEX_FORMAT;var P=w.getValueOrClonedDefault(u.outlineColor,n,e.BLACK,L),D=w.getValueOrDefault(u.outlineWidth,n,1),I=1!==P.alpha;this._outlinePrimitive=a.add(new _({geometryInstances:new h({id:l,geometry:new i(d),modelMatrix:p,attributes:{color:t.fromColor(P),distanceDisplayCondition:E}}),appearance:new g({flat:!0,translucent:I,renderState:{lineWidth:s._scene.clampLineWidth(D)}}),asynchronous:!1,shadows:b}))}}}},A.prototype.getBoundingSphere=function(e,t){return C(e,this._primitive,this._outlinePrimitive,t)},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),s(this)},E}),define("Scene/ColorBlendMode",["../Core/freezeObject","../Core/Math"],function(e,t){"use strict";var r={HIGHLIGHT:0,REPLACE:1,MIX:2};return r.getColorBlend=function(e,i){return e===r.HIGHLIGHT?0:e===r.REPLACE?1:e===r.MIX?t.clamp(i,t.EPSILON4,1):void 0},e(r)}),define("DataSources/DataSourceClock",["../Core/Clock","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/JulianDate","./createRawPropertyDescriptor"],function(e,t,r,i,n,o,a,s){"use strict";function l(){this._startTime=void 0,this._stopTime=void 0,this._currentTime=void 0,this._clockRange=void 0,this._clockStep=void 0,this._multiplier=void 0,this._definitionChanged=new o}return i(l.prototype,{definitionChanged:{get:function(){return this._definitionChanged}},startTime:s("startTime"),stopTime:s("stopTime"),currentTime:s("currentTime"),clockRange:s("clockRange"),clockStep:s("clockStep"),multiplier:s("multiplier")}),l.prototype.clone=function(e){return r(e)||(e=new l),e.startTime=this.startTime,e.stopTime=this.stopTime,e.currentTime=this.currentTime,e.clockRange=this.clockRange,e.clockStep=this.clockStep,e.multiplier=this.multiplier,e},l.prototype.equals=function(e){return this===e||r(e)&&a.equals(this.startTime,e.startTime)&&a.equals(this.stopTime,e.stopTime)&&a.equals(this.currentTime,e.currentTime)&&this.clockRange===e.clockRange&&this.clockStep===e.clockStep&&this.multiplier===e.multiplier},l.prototype.merge=function(e){this.startTime=t(this.startTime,e.startTime),this.stopTime=t(this.stopTime,e.stopTime),this.currentTime=t(this.currentTime,e.currentTime),this.clockRange=t(this.clockRange,e.clockRange),this.clockStep=t(this.clockStep,e.clockStep),this.multiplier=t(this.multiplier,e.multiplier)},l.prototype.getValue=function(i){return r(i)||(i=new e),i.startTime=t(this.startTime,i.startTime),i.stopTime=t(this.stopTime,i.stopTime),i.currentTime=t(this.currentTime,i.currentTime),i.clockRange=t(this.clockRange,i.clockRange),i.multiplier=t(this.multiplier,i.multiplier),i.clockStep=t(this.clockStep,i.clockStep),i},l}),define("DataSources/GridMaterialProperty",["../Core/Cartesian2","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=r(e,r.EMPTY_OBJECT),this._definitionChanged=new o,this._color=void 0,this._colorSubscription=void 0,this._cellAlpha=void 0,this._cellAlphaSubscription=void 0,this._lineCount=void 0,this._lineCountSubscription=void 0,this._lineThickness=void 0,this._lineThicknessSubscription=void 0,this._lineOffset=void 0,this._lineOffsetSubscription=void 0,this.color=e.color,this.cellAlpha=e.cellAlpha,this.lineCount=e.lineCount,this.lineThickness=e.lineThickness,this.lineOffset=e.lineOffset}var u=t.WHITE,c=new e(8,8),d=new e(0,0),h=new e(1,1);return n(l.prototype,{isConstant:{get:function(){return s.isConstant(this._color)&&s.isConstant(this._cellAlpha)&&s.isConstant(this._lineCount)&&s.isConstant(this._lineThickness)&&s.isConstant(this._lineOffset)}},definitionChanged:{get:function(){return this._definitionChanged}},color:a("color"),cellAlpha:a("cellAlpha"),lineCount:a("lineCount"),lineThickness:a("lineThickness"),lineOffset:a("lineOffset")}),l.prototype.getType=function(e){return"Grid"},l.prototype.getValue=function(e,t){return i(t)||(t={}),t.color=s.getValueOrClonedDefault(this._color,e,u,t.color),t.cellAlpha=s.getValueOrDefault(this._cellAlpha,e,.1),t.lineCount=s.getValueOrClonedDefault(this._lineCount,e,c,t.lineCount),t.lineThickness=s.getValueOrClonedDefault(this._lineThickness,e,h,t.lineThickness),t.lineOffset=s.getValueOrClonedDefault(this._lineOffset,e,d,t.lineOffset),t},l.prototype.equals=function(e){return this===e||e instanceof l&&s.equals(this._color,e._color)&&s.equals(this._cellAlpha,e._cellAlpha)&&s.equals(this._lineCount,e._lineCount)&&s.equals(this._lineThickness,e._lineThickness)&&s.equals(this._lineOffset,e._lineOffset)},l}),define("DataSources/PolylineArrowMaterialProperty",["../Core/Color","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o){"use strict";function a(e){this._definitionChanged=new i,this._color=void 0,this._colorSubscription=void 0,this.color=e}return r(a.prototype,{isConstant:{get:function(){return o.isConstant(this._color)}},definitionChanged:{get:function(){return this._definitionChanged}},color:n("color")}),a.prototype.getType=function(e){return"PolylineArrow"},a.prototype.getValue=function(r,i){return t(i)||(i={}),i.color=o.getValueOrClonedDefault(this._color,r,e.WHITE,i.color),i},a.prototype.equals=function(e){return this===e||e instanceof a&&o.equals(this._color,e._color)},a}),define("DataSources/PolylineDashMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._color=void 0,this._colorSubscription=void 0,this._gapColor=void 0,this._gapColorSubscription=void 0,this._dashLength=void 0,this._dashLengthSubscription=void 0,this._dashPattern=void 0,this._dashPatternSubscription=void 0,this.color=e.color,this.gapColor=e.gapColor,this.dashLength=e.dashLength,this.dashPattern=e.dashPattern}var l=e.WHITE,u=e.TRANSPARENT;return i(s.prototype,{isConstant:{get:function(){return a.isConstant(this._color)&&a.isConstant(this._gapColor)&&a.isConstant(this._dashLength)&&a.isConstant(this._dashPattern)}},definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),gapColor:o("gapColor"),dashLength:o("dashLength"),dashPattern:o("dashPattern")}),s.prototype.getType=function(e){return"PolylineDash"},s.prototype.getValue=function(e,t){return r(t)||(t={}),t.color=a.getValueOrClonedDefault(this._color,e,l,t.color),t.gapColor=a.getValueOrClonedDefault(this._gapColor,e,u,t.gapColor),t.dashLength=a.getValueOrDefault(this._dashLength,e,16,t.dashLength),t.dashPattern=a.getValueOrDefault(this._dashPattern,e,255,t.dashPattern),t},s.prototype.equals=function(e){return this===e||e instanceof s&&a.equals(this._color,e._color)&&a.equals(this._gapColor,e._gapColor)&&a.equals(this._dashLength,e._dashLength)&&a.equals(this._dashPattern,e._dashPattern)},s}),define("DataSources/PolylineGlowMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._color=void 0,this._colorSubscription=void 0,this._glowPower=void 0,this._glowPowerSubscription=void 0,this.color=e.color,this.glowPower=e.glowPower}var l=e.WHITE;return i(s.prototype,{isConstant:{get:function(){return a.isConstant(this._color)&&a.isConstant(this._glow)}},definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),glowPower:o("glowPower")}),s.prototype.getType=function(e){return"PolylineGlow"},s.prototype.getValue=function(e,t){return r(t)||(t={}),t.color=a.getValueOrClonedDefault(this._color,e,l,t.color),t.glowPower=a.getValueOrDefault(this._glowPower,e,.25,t.glowPower),t},s.prototype.equals=function(e){return this===e||e instanceof s&&a.equals(this._color,e._color)&&a.equals(this._glowPower,e._glowPower)},s}),define("DataSources/PolylineOutlineMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._color=void 0,this._colorSubscription=void 0,this._outlineColor=void 0,this._outlineColorSubscription=void 0,this._outlineWidth=void 0,this._outlineWidthSubscription=void 0,this.color=e.color,this.outlineColor=e.outlineColor,this.outlineWidth=e.outlineWidth}var l=e.WHITE,u=e.BLACK;return i(s.prototype,{isConstant:{get:function(){return a.isConstant(this._color)&&a.isConstant(this._outlineColor)&&a.isConstant(this._outlineWidth)}},definitionChanged:{get:function(){return this._definitionChanged}},color:o("color"),outlineColor:o("outlineColor"),outlineWidth:o("outlineWidth")}),s.prototype.getType=function(e){return"PolylineOutline"},s.prototype.getValue=function(e,t){return r(t)||(t={}),t.color=a.getValueOrClonedDefault(this._color,e,l,t.color),t.outlineColor=a.getValueOrClonedDefault(this._outlineColor,e,u,t.outlineColor),t.outlineWidth=a.getValueOrDefault(this._outlineWidth,e,1),t},s.prototype.equals=function(e){return this===e||e instanceof s&&a.equals(this._color,e._color)&&a.equals(this._outlineColor,e._outlineColor)&&a.equals(this._outlineWidth,e._outlineWidth)},s}),define("DataSources/PositionPropertyArray",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/EventHelper","../Core/ReferenceFrame","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(t,r){this._value=void 0,this._definitionChanged=new n,this._eventHelper=new o,this._referenceFrame=e(r,a.FIXED),this.setValue(t)}return r(l.prototype,{isConstant:{get:function(){var e=this._value;if(!t(e))return!0;for(var r=e.length,i=0;i<r;i++)if(!s.isConstant(e[i]))return!1;return!0}},definitionChanged:{get:function(){return this._definitionChanged}},referenceFrame:{get:function(){return this._referenceFrame}}}),l.prototype.getValue=function(e,t){return this.getValueInReferenceFrame(e,a.FIXED,t)},l.prototype.getValueInReferenceFrame=function(e,r,i){var n=this._value;if(t(n)){var o=n.length;t(i)||(i=new Array(o));for(var a=0,s=0;a<o;){var l=n[a],u=l.getValueInReferenceFrame(e,r,i[a]);t(u)&&(i[s]=u,s++),a++}return i.length=s,i}},l.prototype.setValue=function(e){var r=this._eventHelper;if(r.removeAll(),t(e)){this._value=e.slice();for(var i=e.length,n=0;n<i;n++){var o=e[n];t(o)&&r.add(o.definitionChanged,l.prototype._raiseDefinitionChanged,this)}}else this._value=void 0;this._definitionChanged.raiseEvent(this)},l.prototype.equals=function(e){return this===e||e instanceof l&&this._referenceFrame===e._referenceFrame&&s.arrayEquals(this._value,e._value)},l.prototype._raiseDefinitionChanged=function(){this._definitionChanged.raiseEvent(this)},l}),define("DataSources/PropertyArray",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/EventHelper","./Property"],function(e,t,r,i,n,o){"use strict";function a(e){this._value=void 0,this._definitionChanged=new i,this._eventHelper=new n,this.setValue(e)}return t(a.prototype,{isConstant:{get:function(){var t=this._value;if(!e(t))return!0;for(var r=t.length,i=0;i<r;i++)if(!o.isConstant(t[i]))return!1;return!0}},definitionChanged:{get:function(){return this._definitionChanged}}}),a.prototype.getValue=function(t,r){var i=this._value;if(e(i)){var n=i.length;e(r)||(r=new Array(n));for(var o=0,a=0;o<n;){var s=this._value[o],l=s.getValue(t,r[o]);e(l)&&(r[a]=l,a++),o++}return r.length=a,r}},a.prototype.setValue=function(t){var r=this._eventHelper;if(r.removeAll(),e(t)){this._value=t.slice();for(var i=t.length,n=0;n<i;n++){var o=t[n];e(o)&&r.add(o.definitionChanged,a.prototype._raiseDefinitionChanged,this)}}else this._value=void 0;this._definitionChanged.raiseEvent(this)},a.prototype.equals=function(e){ +return this===e||e instanceof a&&o.arrayEquals(this._value,e._value)},a.prototype._raiseDefinitionChanged=function(){this._definitionChanged.raiseEvent(this)},a}),define("DataSources/ReferenceProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/RuntimeError","./Property"],function(e,t,r,i,n,o){"use strict";function a(t){var r=!0;if(t._resolveEntity){var i=t._targetCollection.getById(t._targetId);if(e(i)?(i.definitionChanged.addEventListener(l.prototype._onTargetEntityDefinitionChanged,t),t._targetEntity=i,t._resolveEntity=!1):(i=t._targetEntity,r=!1),!e(i))throw new n('target entity "'+t._targetId+'" could not be resolved.')}return r}function s(t){var r=t._targetProperty;if(t._resolveProperty){var i=a(t),o=t._targetPropertyNames;r=t._targetEntity;for(var s=o.length,l=0;l<s&&e(r);l++)r=r[o[l]];if(e(r))t._targetProperty=r,t._resolveProperty=!i;else if(!e(t._targetProperty))throw new n('targetProperty "'+t._targetId+"."+o.join(".")+'" could not be resolved.')}return r}function l(e,t,r){this._targetCollection=e,this._targetId=t,this._targetPropertyNames=r,this._targetProperty=void 0,this._targetEntity=void 0,this._definitionChanged=new i,this._resolveEntity=!0,this._resolveProperty=!0,e.collectionChanged.addEventListener(l.prototype._onCollectionChanged,this)}return t(l.prototype,{isConstant:{get:function(){return o.isConstant(s(this))}},definitionChanged:{get:function(){return this._definitionChanged}},referenceFrame:{get:function(){return s(this).referenceFrame}},targetId:{get:function(){return this._targetId}},targetCollection:{get:function(){return this._targetCollection}},targetPropertyNames:{get:function(){return this._targetPropertyNames}},resolvedProperty:{get:function(){return s(this)}}}),l.fromString=function(e,t){for(var r,i=[],n=!0,o=!1,a="",s=0;s<t.length;++s){var u=t.charAt(s);o?(a+=u,o=!1):"\\"===u?o=!0:n&&"#"===u?(r=a,n=!1,a=""):n||"."!==u?a+=u:(i.push(a),a="")}return i.push(a),new l(e,r,i)},l.prototype.getValue=function(e,t){return s(this).getValue(e,t)},l.prototype.getValueInReferenceFrame=function(e,t,r){return s(this).getValueInReferenceFrame(e,t,r)},l.prototype.getType=function(e){return s(this).getType(e)},l.prototype.equals=function(e){if(this===e)return!0;var t=this._targetPropertyNames,r=e._targetPropertyNames;if(this._targetCollection!==e._targetCollection||this._targetId!==e._targetId||t.length!==r.length)return!1;for(var i=this._targetPropertyNames.length,n=0;n<i;n++)if(t[n]!==r[n])return!1;return!0},l.prototype._onTargetEntityDefinitionChanged=function(e,t,r,i){this._targetPropertyNames[0]===t&&(this._resolveProperty=!0,this._definitionChanged.raiseEvent(this))},l.prototype._onCollectionChanged=function(t,r,i){var n=this._targetEntity;e(n)&&(-1!==i.indexOf(n)?(n.definitionChanged.removeEventListener(l.prototype._onTargetEntityDefinitionChanged,this),this._resolveEntity=!0,this._resolveProperty=!0):this._resolveEntity&&(s(this),this._resolveEntity||this._definitionChanged.raiseEvent(this)))},l}),define("DataSources/Rotation",["../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/Math"],function(e,t,r,i){"use strict";return{packedLength:1,pack:function(t,r,i){return i=e(i,0),r[i]=t,r},unpack:function(t,r,i){return r=e(r,0),t[r]},convertPackedArrayForInterpolation:function(t,r,n,o){r=e(r,0),n=e(n,t.length);for(var a,s=0,l=n-r+1;s<l;s++){var u=t[r+s];0===s||Math.abs(a-u)<Math.PI?o[s]=u:o[s]=u-i.TWO_PI,a=u}},unpackInterpolationResult:function(e,t,r,n,o){return o=e[0],o<0?o+i.TWO_PI:o}}}),define("DataSources/SampledProperty",["../Core/binarySearch","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/ExtrapolationType","../Core/JulianDate","../Core/LinearApproximation"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e,t,r){var i,n=e.length,o=r.length,a=n+o;if(e.length=a,n!==t){var s=n-1;for(i=a-1;i>=t;i--)e[i]=e[s--]}for(i=0;i<o;i++)e[t++]=r[i]}function c(e,t){return e instanceof s?e:"string"==typeof e?s.fromIso8601(e):s.addSeconds(t,e,new s)}function d(t,i,n,o,a){for(var l,d,h,p,g,_,v=0;v<o.length;){g=c(o[v],t),h=e(i,g,s.compare);var y=0,b=0;if(h<0){for(h=~h,p=h*a,d=void 0,_=i[h];v<o.length&&(g=c(o[v],t),!(r(d)&&s.compare(d,g)>=0||r(_)&&s.compare(g,_)>=0));){for(f[y++]=g,v+=1,l=0;l<a;l++)m[b++]=o[v],v+=1;d=g}y>0&&(m.length=b,u(n,p,m),f.length=y,u(i,h,f))}else{for(l=0;l<a;l++)v++,n[h*a+l]=o[v];v++}}}function h(e,i){var n=e;n===Number&&(n=p);var s,u=n.packedLength,c=t(n.packedInterpolationLength,u),d=0;if(r(i)){var h=i.length;s=new Array(h);for(var f=0;f<h;f++){var m=i[f];m===Number&&(m=p);var g=m.packedLength;u+=g,c+=t(m.packedInterpolationLength,g),s[f]=m}d=h}this._type=e,this._innerType=n,this._interpolationDegree=1,this._interpolationAlgorithm=l,this._numberOfPoints=0,this._times=[],this._values=[],this._xTable=[],this._yTable=[],this._packedLength=u,this._packedInterpolationLength=c,this._updateTableLength=!0,this._interpolationResult=new Array(c),this._definitionChanged=new o,this._derivativeTypes=i,this._innerDerivativeTypes=s,this._inputOrder=d,this._forwardExtrapolationType=a.NONE,this._forwardExtrapolationDuration=0,this._backwardExtrapolationType=a.NONE,this._backwardExtrapolationDuration=0}var p={packedLength:1,pack:function(e,r,i){i=t(i,0),r[i]=e},unpack:function(e,r,i){return r=t(r,0),e[r]}},f=[],m=[];return i(h.prototype,{isConstant:{get:function(){return 0===this._values.length}},definitionChanged:{get:function(){return this._definitionChanged}},type:{get:function(){return this._type}},derivativeTypes:{get:function(){return this._derivativeTypes}},interpolationDegree:{get:function(){return this._interpolationDegree}},interpolationAlgorithm:{get:function(){return this._interpolationAlgorithm}},forwardExtrapolationType:{get:function(){return this._forwardExtrapolationType},set:function(e){this._forwardExtrapolationType!==e&&(this._forwardExtrapolationType=e,this._definitionChanged.raiseEvent(this))}},forwardExtrapolationDuration:{get:function(){return this._forwardExtrapolationDuration},set:function(e){this._forwardExtrapolationDuration!==e&&(this._forwardExtrapolationDuration=e,this._definitionChanged.raiseEvent(this))}},backwardExtrapolationType:{get:function(){return this._backwardExtrapolationType},set:function(e){this._backwardExtrapolationType!==e&&(this._backwardExtrapolationType=e,this._definitionChanged.raiseEvent(this))}},backwardExtrapolationDuration:{get:function(){return this._backwardExtrapolationDuration},set:function(e){this._backwardExtrapolationDuration!==e&&(this._backwardExtrapolationDuration=e,this._definitionChanged.raiseEvent(this))}}}),h.prototype.getValue=function(t,i){var n=this._times,o=n.length;if(0!==o){var l,u=this._innerType,c=this._values,d=e(n,t,s.compare);if(d<0){if(0===(d=~d)){var h=n[d];if(l=this._backwardExtrapolationDuration,this._backwardExtrapolationType===a.NONE||0!==l&&s.secondsDifference(h,t)>l)return;if(this._backwardExtrapolationType===a.HOLD)return u.unpack(c,0,i)}if(d>=o){d=o-1;var p=n[d];if(l=this._forwardExtrapolationDuration,this._forwardExtrapolationType===a.NONE||0!==l&&s.secondsDifference(t,p)>l)return;if(this._forwardExtrapolationType===a.HOLD)return d=o-1,u.unpack(c,d*u.packedLength,i)}var f=this._xTable,m=this._yTable,g=this._interpolationAlgorithm,_=this._packedInterpolationLength,v=this._inputOrder;if(this._updateTableLength){this._updateTableLength=!1;var y=Math.min(g.getRequiredDataPoints(this._interpolationDegree,v),o);y!==this._numberOfPoints&&(this._numberOfPoints=y,f.length=y,m.length=y*_)}var b=this._numberOfPoints-1;if(b<1)return;var C=0,S=o-1;if(S-C+1>=b+1){var w=d-(b/2|0)-1;w<C&&(w=C);var T=w+b;T>S&&(T=S,(w=T-b)<C&&(w=C)),C=w,S=T}for(var E=S-C+1,A=0;A<E;++A)f[A]=s.secondsDifference(n[C+A],n[S]);if(r(u.convertPackedArrayForInterpolation))u.convertPackedArrayForInterpolation(c,C,S,m);else for(var x=0,P=this._packedLength,D=C*P,I=(S+1)*P;D<I;)m[x]=c[D],D++,x++;var O,M=s.secondsDifference(t,n[S]);if(0!==v&&r(g.interpolate)){var R=Math.floor(_/(v+1));O=g.interpolate(M,f,m,R,v,v,this._interpolationResult)}else O=g.interpolateOrderZero(M,f,m,_,this._interpolationResult);return r(u.unpackInterpolationResult)?u.unpackInterpolationResult(O,c,C,S,i):u.unpack(O,0,i)}return u.unpack(c,d*this._packedLength,i)}},h.prototype.setInterpolationOptions=function(e){if(r(e)){var t=!1,i=e.interpolationAlgorithm,n=e.interpolationDegree;r(i)&&this._interpolationAlgorithm!==i&&(this._interpolationAlgorithm=i,t=!0),r(n)&&this._interpolationDegree!==n&&(this._interpolationDegree=n,t=!0),t&&(this._updateTableLength=!0,this._definitionChanged.raiseEvent(this))}},h.prototype.addSample=function(e,t,i){var n=this._innerDerivativeTypes,o=r(n),a=this._innerType,s=[];if(s.push(e),a.pack(t,s,s.length),o)for(var l=n.length,u=0;u<l;u++)n[u].pack(i[u],s,s.length);d(void 0,this._times,this._values,s,this._packedLength),this._updateTableLength=!0,this._definitionChanged.raiseEvent(this)},h.prototype.addSamples=function(e,t,i){for(var n=this._innerDerivativeTypes,o=r(n),a=this._innerType,s=e.length,l=[],u=0;u<s;u++)if(l.push(e[u]),a.pack(t[u],l,l.length),o)for(var c=i[u],h=n.length,p=0;p<h;p++)n[p].pack(c[p],l,l.length);d(void 0,this._times,this._values,l,this._packedLength),this._updateTableLength=!0,this._definitionChanged.raiseEvent(this)},h.prototype.addSamplesPackedArray=function(e,t){d(t,this._times,this._values,e,this._packedLength),this._updateTableLength=!0,this._definitionChanged.raiseEvent(this)},h.prototype.equals=function(e){if(this===e)return!0;if(!r(e))return!1;if(this._type!==e._type||this._interpolationDegree!==e._interpolationDegree||this._interpolationAlgorithm!==e._interpolationAlgorithm)return!1;var t=this._derivativeTypes,i=r(t),n=e._derivativeTypes;if(i!==r(n))return!1;var o,a;if(i){if((a=t.length)!==n.length)return!1;for(o=0;o<a;o++)if(t[o]!==n[o])return!1}var l=this._times,u=e._times;if((a=l.length)!==u.length)return!1;for(o=0;o<a;o++)if(!s.equals(l[o],u[o]))return!1;var c=this._values,d=e._values;for(o=0;o<a;o++)if(c[o]!==d[o])return!1;return!0},h._mergeNewSamples=d,h}),define("DataSources/SampledPositionProperty",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/ReferenceFrame","./PositionProperty","./Property","./SampledProperty"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(r,i){i=t(i,0);var n;if(i>0){n=new Array(i);for(var s=0;s<i;s++)n[s]=e}this._numberOfDerivatives=i,this._property=new u(e,n),this._definitionChanged=new o,this._referenceFrame=t(r,a.FIXED),this._property._definitionChanged.addEventListener(function(){this._definitionChanged.raiseEvent(this)},this)}return i(c.prototype,{isConstant:{get:function(){return this._property.isConstant}},definitionChanged:{get:function(){return this._definitionChanged}},referenceFrame:{get:function(){return this._referenceFrame}},interpolationDegree:{get:function(){return this._property.interpolationDegree}},interpolationAlgorithm:{get:function(){return this._property.interpolationAlgorithm}},numberOfDerivatives:{get:function(){return this._numberOfDerivatives}},forwardExtrapolationType:{get:function(){return this._property.forwardExtrapolationType},set:function(e){this._property.forwardExtrapolationType=e}},forwardExtrapolationDuration:{get:function(){return this._property.forwardExtrapolationDuration},set:function(e){this._property.forwardExtrapolationDuration=e}},backwardExtrapolationType:{get:function(){return this._property.backwardExtrapolationType},set:function(e){this._property.backwardExtrapolationType=e}},backwardExtrapolationDuration:{get:function(){return this._property.backwardExtrapolationDuration},set:function(e){this._property.backwardExtrapolationDuration=e}}}),c.prototype.getValue=function(e,t){return this.getValueInReferenceFrame(e,a.FIXED,t)},c.prototype.getValueInReferenceFrame=function(e,t,i){if(i=this._property.getValue(e,i),r(i))return s.convertToReferenceFrame(e,i,this._referenceFrame,t,i)},c.prototype.setInterpolationOptions=function(e){this._property.setInterpolationOptions(e)},c.prototype.addSample=function(e,t,r){this._numberOfDerivatives;this._property.addSample(e,t,r)},c.prototype.addSamples=function(e,t,r){this._property.addSamples(e,t,r)},c.prototype.addSamplesPackedArray=function(e,t){this._property.addSamplesPackedArray(e,t)},c.prototype.equals=function(e){return this===e||e instanceof c&&l.equals(this._property,e._property)&&this._referenceFrame===e._referenceFrame},c}),define("DataSources/StripeOrientation",["../Core/freezeObject"],function(e){"use strict";return e({HORIZONTAL:0,VERTICAL:1})}),define("DataSources/StripeMaterialProperty",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","./createPropertyDescriptor","./Property","./StripeOrientation"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT),this._definitionChanged=new n,this._orientation=void 0,this._orientationSubscription=void 0,this._evenColor=void 0,this._evenColorSubscription=void 0,this._oddColor=void 0,this._oddColorSubscription=void 0,this._offset=void 0,this._offsetSubscription=void 0,this._repeat=void 0,this._repeatSubscription=void 0,this.orientation=e.orientation,this.evenColor=e.evenColor,this.oddColor=e.oddColor,this.offset=e.offset,this.repeat=e.repeat}var u=s.HORIZONTAL,c=e.WHITE,d=e.BLACK;return i(l.prototype,{isConstant:{get:function(){return a.isConstant(this._orientation)&&a.isConstant(this._evenColor)&&a.isConstant(this._oddColor)&&a.isConstant(this._offset)&&a.isConstant(this._repeat)}},definitionChanged:{get:function(){return this._definitionChanged}},orientation:o("orientation"),evenColor:o("evenColor"),oddColor:o("oddColor"),offset:o("offset"),repeat:o("repeat")}),l.prototype.getType=function(e){return"Stripe"},l.prototype.getValue=function(e,t){return r(t)||(t={}),t.horizontal=a.getValueOrDefault(this._orientation,e,u)===s.HORIZONTAL,t.evenColor=a.getValueOrClonedDefault(this._evenColor,e,c,t.evenColor),t.oddColor=a.getValueOrClonedDefault(this._oddColor,e,d,t.oddColor),t.offset=a.getValueOrDefault(this._offset,e,0),t.repeat=a.getValueOrDefault(this._repeat,e,1),t},l.prototype.equals=function(e){return this===e||e instanceof l&&a.equals(this._orientation,e._orientation)&&a.equals(this._evenColor,e._evenColor)&&a.equals(this._oddColor,e._oddColor)&&a.equals(this._offset,e._offset)&&a.equals(this._repeat,e._repeat)},l}),define("DataSources/TimeIntervalCollectionPositionProperty",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/ReferenceFrame","../Core/TimeIntervalCollection","./PositionProperty","./Property"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t){this._definitionChanged=new n,this._intervals=new a,this._intervals.changedEvent.addEventListener(u.prototype._intervalsChanged,this),this._referenceFrame=e(t,o.FIXED)}return r(u.prototype,{isConstant:{get:function(){return this._intervals.isEmpty}},definitionChanged:{get:function(){return this._definitionChanged}},intervals:{get:function(){return this._intervals}},referenceFrame:{get:function(){return this._referenceFrame}}}),u.prototype.getValue=function(e,t){return this.getValueInReferenceFrame(e,o.FIXED,t)},u.prototype.getValueInReferenceFrame=function(e,r,i){var n=this._intervals.findDataForIntervalContainingDate(e);if(t(n))return s.convertToReferenceFrame(e,n,this._referenceFrame,r,i)},u.prototype.equals=function(e){return this===e||e instanceof u&&this._intervals.equals(e._intervals,l.equals)&&this._referenceFrame===e._referenceFrame},u.prototype._intervalsChanged=function(){this._definitionChanged.raiseEvent(this)},u}),define("DataSources/TimeIntervalCollectionProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/TimeIntervalCollection","./Property"],function(e,t,r,i,n,o){"use strict";function a(){this._definitionChanged=new i,this._intervals=new n,this._intervals.changedEvent.addEventListener(a.prototype._intervalsChanged,this)}return t(a.prototype,{isConstant:{get:function(){return this._intervals.isEmpty}},definitionChanged:{get:function(){return this._definitionChanged}},intervals:{get:function(){return this._intervals}}}),a.prototype.getValue=function(t,r){var i=this._intervals.findDataForIntervalContainingDate(t);return e(i)&&"function"==typeof i.clone?i.clone(r):i},a.prototype.equals=function(e){return this===e||e instanceof a&&this._intervals.equals(e._intervals,o.equals)},a.prototype._intervalsChanged=function(){this._definitionChanged.raiseEvent(this)},a}),define("DataSources/VelocityVectorProperty",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/JulianDate","./Property"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,r){this._position=void 0,this._subscription=void 0,this._definitionChanged=new o,this._normalize=t(r,!0),this.position=e}i(l.prototype,{isConstant:{get:function(){return s.isConstant(this._position)}},definitionChanged:{get:function(){return this._definitionChanged}},position:{get:function(){return this._position},set:function(e){var t=this._position;t!==e&&(r(t)&&this._subscription(),this._position=e,r(e)&&(this._subscription=e._definitionChanged.addEventListener(function(){this._definitionChanged.raiseEvent(this)},this)),this._definitionChanged.raiseEvent(this))}},normalize:{get:function(){return this._normalize},set:function(e){this._normalize!==e&&(this._normalize=e,this._definitionChanged.raiseEvent(this))}}});var u=new e,c=new e,d=new a;return l.prototype.getValue=function(e,t){return this._getValue(e,t)},l.prototype._getValue=function(t,i,n){r(i)||(i=new e);var o=this._position;if(s.isConstant(o))return this._normalize?void 0:e.clone(e.ZERO,i);var l=o.getValue(t,u),h=o.getValue(a.addSeconds(t,1/60,d),c);if(r(l)&&(r(h)||(h=l,l=o.getValue(a.addSeconds(t,-1/60,d),c),r(l)))){if(e.equals(l,h))return this._normalize?void 0:e.clone(e.ZERO,i);r(n)&&l.clone(n);var p=e.subtract(h,l,i);return this._normalize?e.normalize(p,i):e.divideByScalar(p,1/60,i)}},l.prototype.equals=function(e){return this===e||e instanceof l&&s.equals(this._position,e._position)},l}),define("DataSources/VelocityOrientationProperty",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Ellipsoid","../Core/Event","../Core/Matrix3","../Core/Quaternion","../Core/Transforms","./Property","./VelocityVectorProperty"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,r){this._velocityVectorProperty=new c(e,!0),this._subscription=void 0,this._ellipsoid=void 0,this._definitionChanged=new o,this.ellipsoid=t(r,n.WGS84);var i=this;this._velocityVectorProperty.definitionChanged.addEventListener(function(){i._definitionChanged.raiseEvent(i)})}i(d.prototype,{isConstant:{get:function(){return u.isConstant(this._velocityVectorProperty)}},definitionChanged:{get:function(){return this._definitionChanged}},position:{get:function(){return this._velocityVectorProperty.position},set:function(e){this._velocityVectorProperty.position=e}},ellipsoid:{get:function(){return this._ellipsoid},set:function(e){this._ellipsoid!==e&&(this._ellipsoid=e,this._definitionChanged.raiseEvent(this))}}});var h=new e,p=new e,f=new a;return d.prototype.getValue=function(e,t){var i=this._velocityVectorProperty._getValue(e,p,h);if(r(i))return l.rotationMatrixFromPositionVelocity(h,i,this._ellipsoid,f),s.fromRotationMatrix(f,t)},d.prototype.equals=function(e){return this===e||e instanceof d&&u.equals(this._velocityVectorProperty,e._velocityVectorProperty)&&(this._ellipsoid===e._ellipsoid||this._ellipsoid.equals(e._ellipsoid))},d}),define("DataSources/CzmlDataSource",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/ClockRange","../Core/ClockStep","../Core/Color","../Core/CornerType","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Ellipsoid","../Core/Event","../Core/ExtrapolationType","../Core/getFilenameFromUri","../Core/HermitePolynomialApproximation","../Core/isArray","../Core/Iso8601","../Core/JulianDate","../Core/LagrangePolynomialApproximation","../Core/LinearApproximation","../Core/Math","../Core/NearFarScalar","../Core/Quaternion","../Core/Rectangle","../Core/ReferenceFrame","../Core/Resource","../Core/RuntimeError","../Core/Spherical","../Core/TimeInterval","../Core/TimeIntervalCollection","../Scene/ColorBlendMode","../Scene/HeightReference","../Scene/HorizontalOrigin","../Scene/LabelStyle","../Scene/ShadowMode","../Scene/VerticalOrigin","../ThirdParty/Uri","../ThirdParty/when","./BillboardGraphics","./BoxGraphics","./ColorMaterialProperty","./CompositeMaterialProperty","./CompositePositionProperty","./CompositeProperty","./ConstantPositionProperty","./ConstantProperty","./CorridorGraphics","./CylinderGraphics","./DataSource","./DataSourceClock","./EllipseGraphics","./EllipsoidGraphics","./EntityCluster","./EntityCollection","./GridMaterialProperty","./ImageMaterialProperty","./LabelGraphics","./ModelGraphics","./NodeTransformationProperty","./PathGraphics","./PointGraphics","./PolygonGraphics","./PolylineArrowMaterialProperty","./PolylineDashMaterialProperty","./PolylineGlowMaterialProperty","./PolylineGraphics","./PolylineOutlineMaterialProperty","./PositionPropertyArray","./PropertyArray","./PropertyBag","./RectangleGraphics","./ReferenceProperty","./Rotation","./SampledPositionProperty","./SampledProperty","./StripeMaterialProperty","./StripeOrientation","./TimeIntervalCollectionPositionProperty","./TimeIntervalCollectionProperty","./VelocityOrientationProperty","./VelocityVectorProperty","./WallGraphics"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,be,Ce,Se,we,Te,Ee,Ae,xe,Pe,De,Ie,Oe,Me){"use strict";function Re(){}function Le(e,t){return"#"===t[0]&&(t=Ft+t),Se.fromString(e,t)}function Ne(e,t,i){if(c(i.reference))return Le(t,i.reference);if(c(i.velocityReference)){var n=Le(t,i.velocityReference);switch(e){case r:case Re:return new Oe(n,e===Re);case x:return new Ie(n)}}throw new O(JSON.stringify(i)+" is not valid CZML.")}function ke(e){var t=e.rgbaf;if(c(t))return t;var r=e.rgba;if(c(r)){var i=r.length;if(i===a.packedLength)return[a.byteToFloat(r[0]),a.byteToFloat(r[1]),a.byteToFloat(r[2]),a.byteToFloat(r[3])];t=new Array(i);for(var n=0;n<i;n+=5)t[n]=r[n],t[n+1]=a.byteToFloat(r[n+1]),t[n+2]=a.byteToFloat(r[n+2]),t[n+3]=a.byteToFloat(r[n+3]),t[n+4]=a.byteToFloat(r[n+4]);return t}}function Fe(e,t){var r=u(e.uri,e);return c(t)?t.getDerivedResource({url:r}):I.createIfNeeded(r)}function Be(e){var t=e.wsen;if(c(t))return t;var r=e.wsenDegrees;if(c(r)){var i=r.length;if(i===P.packedLength)return[E.toRadians(r[0]),E.toRadians(r[1]),E.toRadians(r[2]),E.toRadians(r[3])];t=new Array(i);for(var n=0;n<i;n+=5)t[n]=r[n],t[n+1]=E.toRadians(r[n+1]),t[n+2]=E.toRadians(r[n+2]),t[n+3]=E.toRadians(r[n+3]),t[n+4]=E.toRadians(r[n+4]);return t}}function Ue(e){var t=e.length;if(Ut.magnitude=1,2===t)return Ut.clock=e[0],Ut.cone=e[1],r.fromSpherical(Ut,Bt),[Bt.x,Bt.y,Bt.z];for(var i=new Array(t/3*4),n=0,o=0;n<t;n+=3,o+=4)i[o]=e[n],Ut.clock=e[n+1],Ut.cone=e[n+2],r.fromSpherical(Ut,Bt),i[o+1]=Bt.x,i[o+2]=Bt.y,i[o+3]=Bt.z;return i}function Ve(e){var t=e.length;if(3===t)return Ut.clock=e[0],Ut.cone=e[1],Ut.magnitude=e[2],r.fromSpherical(Ut,Bt),[Bt.x,Bt.y,Bt.z];for(var i=new Array(t),n=0;n<t;n+=4)i[n]=e[n],Ut.clock=e[n+1],Ut.cone=e[n+2],Ut.magnitude=e[n+3],r.fromSpherical(Ut,Bt),i[n+1]=Bt.x,i[n+2]=Bt.y,i[n+3]=Bt.z;return i}function ze(e){var t=e.length;if(3===t)return Vt.longitude=e[0],Vt.latitude=e[1],Vt.height=e[2],m.WGS84.cartographicToCartesian(Vt,Bt),[Bt.x,Bt.y,Bt.z];for(var r=new Array(t),i=0;i<t;i+=4)r[i]=e[i],Vt.longitude=e[i+1],Vt.latitude=e[i+2],Vt.height=e[i+3],m.WGS84.cartographicToCartesian(Vt,Bt),r[i+1]=Bt.x,r[i+2]=Bt.y,r[i+3]=Bt.z;return r}function Ge(e){var t=e.length;if(3===t)return Vt.longitude=E.toRadians(e[0]),Vt.latitude=E.toRadians(e[1]),Vt.height=e[2],m.WGS84.cartographicToCartesian(Vt,Bt),[Bt.x,Bt.y,Bt.z];for(var r=new Array(t),i=0;i<t;i+=4)r[i]=e[i],Vt.longitude=E.toRadians(e[i+1]),Vt.latitude=E.toRadians(e[i+2]),Vt.height=e[i+3],m.WGS84.cartographicToCartesian(Vt,Bt),r[i+1]=Bt.x,r[i+2]=Bt.y,r[i+3]=Bt.z;return r}function We(e){var t=e.cartesian;if(c(t))return t;var r=e.cartesianVelocity;if(c(r))return r;var i=e.unitCartesian;if(c(i))return i;var n=e.unitSpherical;if(c(n))return Ue(n);var o=e.spherical;if(c(o))return Ve(o);var a=e.cartographicRadians;if(c(a))return ze(a);var s=e.cartographicDegrees;if(c(s))return Ge(s);throw new O(JSON.stringify(e)+" is not a valid CZML interval.")}function He(e,t){r.unpack(e,t,Bt),r.normalize(Bt,Bt),r.pack(Bt,e,t)}function je(e){var t=We(e);if(3===t.length)return He(t,0),t;for(var r=1;r<t.length;r+=4)He(t,r);return t}function qe(e,t){x.unpack(e,t,Gt),x.normalize(Gt,Gt),x.pack(Gt,e,t)}function Ye(e){var t=e.unitQuaternion;if(c(t)){if(4===t.length)return qe(t,0),t;for(var r=1;r<t.length;r+=5)qe(t,r)}return t}function Xe(i){return"boolean"==typeof i?Boolean:"number"==typeof i?Number:"string"==typeof i?String:i.hasOwnProperty("array")?Array:i.hasOwnProperty("boolean")?Boolean:i.hasOwnProperty("boundingRectangle")?e:i.hasOwnProperty("cartesian2")?t:i.hasOwnProperty("cartesian")||i.hasOwnProperty("spherical")||i.hasOwnProperty("cartographicRadians")||i.hasOwnProperty("cartographicDegrees")?r:i.hasOwnProperty("unitCartesian")||i.hasOwnProperty("unitSpherical")?Re:i.hasOwnProperty("rgba")||i.hasOwnProperty("rgbaf")?a:i.hasOwnProperty("colorBlendMode")?N:i.hasOwnProperty("cornerType")?s:i.hasOwnProperty("heightReference")?k:i.hasOwnProperty("horizontalOrigin")?F:i.hasOwnProperty("date")?S:i.hasOwnProperty("labelStyle")?B:i.hasOwnProperty("number")?Number:i.hasOwnProperty("nearFarScalar")?A:i.hasOwnProperty("distanceDisplayCondition")?f:i.hasOwnProperty("object")||i.hasOwnProperty("value")?Object:i.hasOwnProperty("unitQuaternion")?x:i.hasOwnProperty("shadowMode")?U:i.hasOwnProperty("string")?String:i.hasOwnProperty("stripeOrientation")?xe:i.hasOwnProperty("wsen")||i.hasOwnProperty("wsenDegrees")?P:i.hasOwnProperty("uri")?z:i.hasOwnProperty("verticalOrigin")?V:Object}function Qe(i,n,o){switch(i){case Array:return n.array;case Boolean:return u(n.boolean,n);case e:return n.boundingRectangle;case t:return n.cartesian2;case r:return We(n);case Re:return je(n);case a:return ke(n);case N:return N[u(n.colorBlendMode,n)];case s:return s[u(n.cornerType,n)];case k:return k[u(n.heightReference,n)];case F:return F[u(n.horizontalOrigin,n)];case Image:return Fe(n,o);case S:return S.fromIso8601(u(n.date,n));case B:return B[u(n.labelStyle,n)];case Number:return u(n.number,n);case A:return n.nearFarScalar;case f:return n.distanceDisplayCondition;case Object:return u(u(n.object,n.value),n);case x:return Ye(n);case we:return u(n.number,n);case U:return U[u(u(n.shadowMode,n.shadows),n)];case String:return u(n.string,n);case xe:return xe[u(n.stripeOrientation,n)];case P:return Be(n);case z:return Fe(n,o);case V:return V[u(n.verticalOrigin,n)];default:throw new O(i)}}function Ze(e,t){var r=e.interpolationAlgorithm;(c(r)||c(e.interpolationDegree))&&t.setInterpolationOptions({interpolationAlgorithm:Wt[r],interpolationDegree:e.interpolationDegree});var i=e.forwardExtrapolationType;c(i)&&(t.forwardExtrapolationType=_[i]);var n=e.forwardExtrapolationDuration;c(n)&&(t.forwardExtrapolationDuration=n);var o=e.backwardExtrapolationType;c(o)&&(t.backwardExtrapolationType=_[o]);var a=e.backwardExtrapolationDuration;c(a)&&(t.backwardExtrapolationDuration=a)}function Ke(e,t,r,i,n,o,a){var s,l=i.interval;c(l)?(Ht.iso8601=l,s=R.fromIso8601(Ht),c(n)&&(s=R.intersect(s,n,zt))):c(n)&&(s=n);var d,h,p,f,m=!c(i.reference)&&!c(i.velocityReference),g=c(s)&&!s.equals(C.MAXIMUM_INTERVAL);m&&(p=Qe(e,i,o),d=u(e.packedLength,1),f=u(p.length,1),h=!c(i.array)&&"string"!=typeof p&&f>d&&e!==Object);var _="function"==typeof e.unpack&&e!==we;if(!h&&!g)return void(t[r]=m?new Z(_?e.unpack(p,0):p):Ne(e,a,i));var v,y=t[r],b=i.epoch;if(c(b)&&(v=S.fromIso8601(b)),h&&!g)return y instanceof Ee||(y=new Ee(e),t[r]=y),y.addSamplesPackedArray(p,v),void Ze(i,y);var w;if(!h&&g)return s=s.clone(),s.data=m?_?e.unpack(p,0):p:Ne(e,a,i),c(y)||(y=m?new De:new X,t[r]=y),void(m&&y instanceof De?y.intervals.addInterval(s):y instanceof X?(m&&(s.data=new Z(s.data)),y.intervals.addInterval(s)):(w=C.MAXIMUM_INTERVAL.clone(),w.data=y,y=new X,t[r]=y,y.intervals.addInterval(w),m&&(s.data=new Z(s.data)),y.intervals.addInterval(s)));c(y)||(y=new X,t[r]=y),y instanceof X||(w=C.MAXIMUM_INTERVAL.clone(),w.data=y,y=new X,t[r]=y,y.intervals.addInterval(w));var T=y.intervals;w=T.findInterval(s),c(w)&&w.data instanceof Ee||(w=s.clone(),w.data=new Ee(e),T.addInterval(w)),w.data.addSamplesPackedArray(p,v),Ze(i,w.data)}function Je(e,t,r,i,n,o,a){if(c(i))if(b(i))for(var s=0,l=i.length;s<l;s++)Ke(e,t,r,i[s],n,o,a);else Ke(e,t,r,i,n,o,a)}function $e(e,t,i,n,o,a){var s,l=i.interval;c(l)?(Ht.iso8601=l,s=R.fromIso8601(Ht),c(n)&&(s=R.intersect(s,n,zt))):c(n)&&(s=n);var d,h,p,f=!1,m=c(i.cartesianVelocity)?1:0,g=r.packedLength*(m+1),_=!c(i.reference),v=c(s)&&!s.equals(C.MAXIMUM_INTERVAL);if(_&&(c(i.referenceFrame)&&(d=D[i.referenceFrame]),d=u(d,D.FIXED),h=We(i),p=u(h.length,1),f=p>g),!f&&!v)return void(e[t]=_?new Q(r.unpack(h),d):Le(a,i.reference));var y,b=e[t],w=i.epoch;if(c(w)&&(y=S.fromIso8601(w)),f&&!v)return b instanceof Te&&(!c(d)||b.referenceFrame===d)||(b=new Te(d,m),e[t]=b),b.addSamplesPackedArray(h,y),void Ze(i,b);var T;if(!f&&v)return s=s.clone(),s.data=_?r.unpack(h):Le(a,i.reference),c(b)||(b=_?new Pe(d):new Y(d),e[t]=b),void(_&&b instanceof Pe&&c(d)&&b.referenceFrame===d?b.intervals.addInterval(s):b instanceof Y?(_&&(s.data=new Q(s.data,d)),b.intervals.addInterval(s)):(T=C.MAXIMUM_INTERVAL.clone(),T.data=b,b=new Y(b.referenceFrame),e[t]=b,b.intervals.addInterval(T),_&&(s.data=new Q(s.data,d)),b.intervals.addInterval(s)));c(b)?b instanceof Y||(T=C.MAXIMUM_INTERVAL.clone(),T.data=b,b=new Y(b.referenceFrame),e[t]=b,b.intervals.addInterval(T)):(b=new Y(d),e[t]=b);var E=b.intervals;T=E.findInterval(s),c(T)&&T.data instanceof Te&&(!c(d)||T.data.referenceFrame===d)||(T=s.clone(),T.data=new Te(d,m),E.addInterval(T)),T.data.addSamplesPackedArray(h,y),Ze(i,T.data)}function et(e,t,r,i,n,o){if(c(r))if(b(r))for(var a=0,s=r.length;a<s;a++)$e(e,t,r[a],i,n,o);else $e(e,t,r,i,n,o)}function tt(e,r,i,n,o,s){var l,u=i.interval;c(u)?(Ht.iso8601=u,l=R.fromIso8601(Ht),c(n)&&(l=R.intersect(l,n,zt))):c(n)&&(l=n);var d,h,p=e[r];if(c(l)){p instanceof q||(p=new q,e[r]=p);var f=p.intervals;h=f.findInterval({start:l.start,stop:l.stop}),c(h)?d=h.data:(h=l.clone(),f.addInterval(h))}else d=p;var m;c(i.solidColor)?(d instanceof j||(d=new j),m=i.solidColor,Je(a,d,"color",m.color,void 0,void 0,s)):c(i.grid)?(d instanceof oe||(d=new oe),m=i.grid,Je(a,d,"color",m.color,void 0,o,s),Je(Number,d,"cellAlpha",m.cellAlpha,void 0,o,s),Je(t,d,"lineCount",m.lineCount,void 0,o,s),Je(t,d,"lineThickness",m.lineThickness,void 0,o,s),Je(t,d,"lineOffset",m.lineOffset,void 0,o,s)):c(i.image)?(d instanceof ae||(d=new ae),m=i.image,Je(Image,d,"image",m.image,void 0,o,s),Je(t,d,"repeat",m.repeat,void 0,o,s),Je(a,d,"color",m.color,void 0,o,s),Je(Boolean,d,"transparent",m.transparent,void 0,o,s)):c(i.stripe)?(d instanceof Ae||(d=new Ae),m=i.stripe,Je(xe,d,"orientation",m.orientation,void 0,o,s),Je(a,d,"evenColor",m.evenColor,void 0,o,s),Je(a,d,"oddColor",m.oddColor,void 0,o,s),Je(Number,d,"offset",m.offset,void 0,o,s),Je(Number,d,"repeat",m.repeat,void 0,o,s)):c(i.polylineOutline)?(d instanceof _e||(d=new _e),m=i.polylineOutline,Je(a,d,"color",m.color,void 0,o,s),Je(a,d,"outlineColor",m.outlineColor,void 0,o,s), +Je(Number,d,"outlineWidth",m.outlineWidth,void 0,o,s)):c(i.polylineGlow)?(d instanceof me||(d=new me),m=i.polylineGlow,Je(a,d,"color",m.color,void 0,o,s),Je(Number,d,"glowPower",m.glowPower,void 0,o,s)):c(i.polylineArrow)?(d instanceof pe||(d=new pe),m=i.polylineArrow,Je(a,d,"color",m.color,void 0,void 0,s)):c(i.polylineDash)&&(d instanceof fe||(d=new fe),m=i.polylineDash,Je(a,d,"color",m.color,void 0,void 0,s),Je(a,d,"gapColor",m.gapColor,void 0,void 0,s),Je(Number,d,"dashLength",m.dashLength,void 0,o,s),Je(Number,d,"dashPattern",m.dashPattern,void 0,o,s)),c(h)?h.data=d:e[r]=d}function rt(e,t,r,i,n,o){if(c(r))if(b(r))for(var a=0,s=r.length;a<s;a++)tt(e,t,r[a],i,n,o);else tt(e,t,r,i,n,o)}function it(e,t,r,i){e.name=u(t.name,e.name)}function nt(e,t,r,i){var n=t.description;c(n)&&Je(String,e,"description",n,void 0,i,r)}function ot(e,t,r,i){var n=t.position;c(n)&&et(e,"position",n,void 0,i,r)}function at(e,t,i,n){var o=t.viewFrom;c(o)&&Je(r,e,"viewFrom",o,void 0,n,i)}function st(e,t,r,i){var n=t.orientation;c(n)&&Je(x,e,"orientation",n,void 0,i,r)}function lt(e,t,r,i){var n=t.properties;if(c(n)){c(e.properties)||(e.properties=new be);for(var o in n)if(n.hasOwnProperty(o)){e.properties.hasProperty(o)||e.properties.addProperty(o);var a=n[o];if(b(a))for(var s=0,l=a.length;s<l;s++)Ke(Xe(a[s]),e.properties,o,a[s],void 0,i,r);else Ke(Xe(a),e.properties,o,a,void 0,i,r)}}}function ut(e,t,r,i){var n=r.references;if(c(n)){var o=n.map(function(e){return Le(i,e)}),a=r.interval;if(c(a)){if(a=R.fromIso8601(a),!(e[t]instanceof Y)){a.data=new ye(o);var s=new X;s.intervals.addInterval(a),e[t]=s}}else e[t]=new ye(o)}else Je(Array,e,t,r,void 0,void 0,i)}function ct(e,t,r,i){if(c(r))if(b(r))for(var n=0,o=r.length;n<o;++n)ut(e,t,r[n],i);else ut(e,t,r,i)}function dt(e,t,i,n){if(c(i.references)){var o=i.references.map(function(e){return Le(n,e)}),a=i.interval;if(c(a)){if(a=R.fromIso8601(a),!(e[t]instanceof Y)){a.data=new ve(o);var s=new Y;s.intervals.addInterval(a),e[t]=s}}else e[t]=new ve(o)}else c(i.cartesian)?i.array=r.unpackArray(i.cartesian):c(i.cartographicRadians)?i.array=r.fromRadiansArrayHeights(i.cartographicRadians):c(i.cartographicDegrees)&&(i.array=r.fromDegreesArrayHeights(i.cartographicDegrees)),c(i.array)&&Je(Array,e,t,i,void 0,void 0,n)}function ht(e,t,r,i){if(c(r))if(b(r))for(var n=0,o=r.length;n<o;n++)dt(e,t,r[n],i);else dt(e,t,r,i)}function pt(e,t,r,i){var n,o=t.availability;if(c(o)){var a;if(b(o))for(var s=o.length,l=0;l<s;l++)c(a)||(a=new L),Ht.iso8601=o[l],n=R.fromIso8601(Ht),a.addInterval(n);else Ht.iso8601=o,n=R.fromIso8601(Ht),a=new L,a.addInterval(n);e.availability=a}}function ft(e,t,r,i,n){c(t)&&Je(Re,e,"alignedAxis",t,r,i,n)}function mt(i,n,o,s){var l=n.billboard;if(c(l)){var u,d=l.interval;c(d)&&(Ht.iso8601=d,u=R.fromIso8601(Ht));var h=i.billboard;c(h)||(i.billboard=h=new W),Je(Boolean,h,"show",l.show,u,s,o),Je(Image,h,"image",l.image,u,s,o),Je(Number,h,"scale",l.scale,u,s,o),Je(t,h,"pixelOffset",l.pixelOffset,u,s,o),Je(r,h,"eyeOffset",l.eyeOffset,u,s,o),Je(F,h,"horizontalOrigin",l.horizontalOrigin,u,s,o),Je(V,h,"verticalOrigin",l.verticalOrigin,u,s,o),Je(k,h,"heightReference",l.heightReference,u,s,o),Je(a,h,"color",l.color,u,s,o),Je(we,h,"rotation",l.rotation,u,s,o),ft(h,l.alignedAxis,u,s,o),Je(Boolean,h,"sizeInMeters",l.sizeInMeters,u,s,o),Je(Number,h,"width",l.width,u,s,o),Je(Number,h,"height",l.height,u,s,o),Je(A,h,"scaleByDistance",l.scaleByDistance,u,s,o),Je(A,h,"translucencyByDistance",l.translucencyByDistance,u,s,o),Je(A,h,"pixelOffsetScaleByDistance",l.pixelOffsetScaleByDistance,u,s,o),Je(e,h,"imageSubRegion",l.imageSubRegion,u,s,o),Je(f,h,"distanceDisplayCondition",l.distanceDisplayCondition,u,s,o),Je(Number,h,"disableDepthTestDistance",l.disableDepthTestDistance,u,s,o)}}function gt(e,t,i,n){var o=t.box;if(c(o)){var s,l=o.interval;c(l)&&(Ht.iso8601=l,s=R.fromIso8601(Ht));var u=e.box;c(u)||(e.box=u=new H),Je(Boolean,u,"show",o.show,s,n,i),Je(r,u,"dimensions",o.dimensions,s,n,i),Je(Boolean,u,"fill",o.fill,s,n,i),rt(u,"material",o.material,s,n,i),Je(Boolean,u,"outline",o.outline,s,n,i),Je(a,u,"outlineColor",o.outlineColor,s,n,i),Je(Number,u,"outlineWidth",o.outlineWidth,s,n,i),Je(U,u,"shadows",o.shadows,s,n,i),Je(f,u,"distanceDisplayCondition",o.distanceDisplayCondition,s,n,i)}}function _t(e,t,r,i){var n=t.corridor;if(c(n)){var o,l=n.interval;c(l)&&(Ht.iso8601=l,o=R.fromIso8601(Ht));var u=e.corridor;c(u)||(e.corridor=u=new K),Je(Boolean,u,"show",n.show,o,i,r),ht(u,"positions",n.positions,r),Je(Number,u,"width",n.width,o,i,r),Je(Number,u,"height",n.height,o,i,r),Je(Number,u,"extrudedHeight",n.extrudedHeight,o,i,r),Je(s,u,"cornerType",n.cornerType,o,i,r),Je(Number,u,"granularity",n.granularity,o,i,r),Je(Boolean,u,"fill",n.fill,o,i,r),rt(u,"material",n.material,o,i,r),Je(Boolean,u,"outline",n.outline,o,i,r),Je(a,u,"outlineColor",n.outlineColor,o,i,r),Je(Number,u,"outlineWidth",n.outlineWidth,o,i,r),Je(U,u,"shadows",n.shadows,o,i,r),Je(f,u,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function vt(e,t,r,i){var n=t.cylinder;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.cylinder;c(l)||(e.cylinder=l=new J),Je(Boolean,l,"show",n.show,o,i,r),Je(Number,l,"length",n.length,o,i,r),Je(Number,l,"topRadius",n.topRadius,o,i,r),Je(Number,l,"bottomRadius",n.bottomRadius,o,i,r),Je(Boolean,l,"fill",n.fill,o,i,r),rt(l,"material",n.material,o,i,r),Je(Boolean,l,"outline",n.outline,o,i,r),Je(a,l,"outlineColor",n.outlineColor,o,i,r),Je(Number,l,"outlineWidth",n.outlineWidth,o,i,r),Je(Number,l,"numberOfVerticalLines",n.numberOfVerticalLines,o,i,r),Je(Number,l,"slices",n.slices,o,i,r),Je(U,l,"shadows",n.shadows,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function yt(e,t){var r=e.version;if(c(r)&&"string"==typeof r){var i=r.split(".");if(2===i.length){if("1"!==i[0])throw new O("Cesium only supports CZML version 1.");t._version=r}}if(!c(t._version))throw new O("CZML version information invalid. It is expected to be a property on the document object in the <Major>.<Minor> version format.");var n=t._documentPacket;c(e.name)&&(n.name=e.name);var o=e.clock;if(c(o)){var a=n.clock;c(a)?(a.interval=u(o.interval,a.interval),a.currentTime=u(o.currentTime,a.currentTime),a.range=u(o.range,a.range),a.step=u(o.step,a.step),a.multiplier=u(o.multiplier,a.multiplier)):n.clock={interval:o.interval,currentTime:o.currentTime,range:o.range,step:o.step,multiplier:o.multiplier}}}function bt(e,t,r,i){var n=t.ellipse;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.ellipse;c(l)||(e.ellipse=l=new te),Je(Boolean,l,"show",n.show,o,i,r),Je(Number,l,"semiMajorAxis",n.semiMajorAxis,o,i,r),Je(Number,l,"semiMinorAxis",n.semiMinorAxis,o,i,r),Je(Number,l,"height",n.height,o,i,r),Je(Number,l,"extrudedHeight",n.extrudedHeight,o,i,r),Je(we,l,"rotation",n.rotation,o,i,r),Je(we,l,"stRotation",n.stRotation,o,i,r),Je(Number,l,"granularity",n.granularity,o,i,r),Je(Boolean,l,"fill",n.fill,o,i,r),rt(l,"material",n.material,o,i,r),Je(Boolean,l,"outline",n.outline,o,i,r),Je(a,l,"outlineColor",n.outlineColor,o,i,r),Je(Number,l,"outlineWidth",n.outlineWidth,o,i,r),Je(Number,l,"numberOfVerticalLines",n.numberOfVerticalLines,o,i,r),Je(U,l,"shadows",n.shadows,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function Ct(e,t,i,n){var o=t.ellipsoid;if(c(o)){var s,l=o.interval;c(l)&&(Ht.iso8601=l,s=R.fromIso8601(Ht));var u=e.ellipsoid;c(u)||(e.ellipsoid=u=new re),Je(Boolean,u,"show",o.show,s,n,i),Je(r,u,"radii",o.radii,s,n,i),Je(Boolean,u,"fill",o.fill,s,n,i),rt(u,"material",o.material,s,n,i),Je(Boolean,u,"outline",o.outline,s,n,i),Je(a,u,"outlineColor",o.outlineColor,s,n,i),Je(Number,u,"outlineWidth",o.outlineWidth,s,n,i),Je(Number,u,"stackPartitions",o.stackPartitions,s,n,i),Je(Number,u,"slicePartitions",o.slicePartitions,s,n,i),Je(Number,u,"subdivisions",o.subdivisions,s,n,i),Je(U,u,"shadows",o.shadows,s,n,i),Je(f,u,"distanceDisplayCondition",o.distanceDisplayCondition,s,n,i)}}function St(e,i,n,o){var s=i.label;if(c(s)){var l,u=s.interval;c(u)&&(Ht.iso8601=u,l=R.fromIso8601(Ht));var d=e.label;c(d)||(e.label=d=new se),Je(Boolean,d,"show",s.show,l,o,n),Je(String,d,"text",s.text,l,o,n),Je(String,d,"font",s.font,l,o,n),Je(B,d,"style",s.style,l,o,n),Je(Number,d,"scale",s.scale,l,o,n),Je(Boolean,d,"showBackground",s.showBackground,l,o,n),Je(a,d,"backgroundColor",s.backgroundColor,l,o,n),Je(t,d,"backgroundPadding",s.backgroundPadding,l,o,n),Je(t,d,"pixelOffset",s.pixelOffset,l,o,n),Je(r,d,"eyeOffset",s.eyeOffset,l,o,n),Je(F,d,"horizontalOrigin",s.horizontalOrigin,l,o,n),Je(V,d,"verticalOrigin",s.verticalOrigin,l,o,n),Je(k,d,"heightReference",s.heightReference,l,o,n),Je(a,d,"fillColor",s.fillColor,l,o,n),Je(a,d,"outlineColor",s.outlineColor,l,o,n),Je(Number,d,"outlineWidth",s.outlineWidth,l,o,n),Je(A,d,"translucencyByDistance",s.translucencyByDistance,l,o,n),Je(A,d,"pixelOffsetScaleByDistance",s.pixelOffsetScaleByDistance,l,o,n),Je(A,d,"scaleByDistance",s.scaleByDistance,l,o,n),Je(f,d,"distanceDisplayCondition",s.distanceDisplayCondition,l,o,n),Je(Number,d,"disableDepthTestDistance",s.disableDepthTestDistance,l,o,n)}}function wt(e,t,r,i){var n=t.model;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.model;c(l)||(e.model=l=new le),Je(Boolean,l,"show",n.show,o,i,r),Je(z,l,"uri",n.gltf,o,i,r),Je(Number,l,"scale",n.scale,o,i,r),Je(Number,l,"minimumPixelSize",n.minimumPixelSize,o,i,r),Je(Number,l,"maximumScale",n.maximumScale,o,i,r),Je(Boolean,l,"incrementallyLoadTextures",n.incrementallyLoadTextures,o,i,r),Je(Boolean,l,"runAnimations",n.runAnimations,o,i,r),Je(Boolean,l,"clampAnimations",n.clampAnimations,o,i,r),Je(U,l,"shadows",n.shadows,o,i,r),Je(k,l,"heightReference",n.heightReference,o,i,r),Je(a,l,"silhouetteColor",n.silhouetteColor,o,i,r),Je(Number,l,"silhouetteSize",n.silhouetteSize,o,i,r),Je(a,l,"color",n.color,o,i,r),Je(N,l,"colorBlendMode",n.colorBlendMode,o,i,r),Je(Number,l,"colorBlendAmount",n.colorBlendAmount,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r);var u=n.nodeTransformations;if(c(u))if(b(u))for(var d=0,h=u.length;d<h;d++)Tt(l,u[d],o,i,r);else Tt(l,u,o,i,r)}}function Tt(e,t,i,n,o){var a,s=t.interval;c(s)?(Ht.iso8601=s,a=R.fromIso8601(Ht),c(i)&&(a=R.intersect(a,i,zt))):c(i)&&(a=i);for(var l=e.nodeTransformations,u=Object.keys(t),d=0,h=u.length;d<h;++d){var p=u[d];if("interval"!==p){var f=t[p];if(c(f)){c(l)||(e.nodeTransformations=l=new be),l.hasProperty(p)||l.addProperty(p);var m=l[p];c(m)||(l[p]=m=new ue),Je(r,m,"translation",f.translation,a,n,o),Je(x,m,"rotation",f.rotation,a,n,o),Je(r,m,"scale",f.scale,a,n,o)}}}}function Et(e,t,r,i){var n=t.path;if(c(n)){var o,a=n.interval;c(a)&&(Ht.iso8601=a,o=R.fromIso8601(Ht));var s=e.path;c(s)||(e.path=s=new ce),Je(Boolean,s,"show",n.show,o,i,r),Je(Number,s,"width",n.width,o,i,r),Je(Number,s,"resolution",n.resolution,o,i,r),Je(Number,s,"leadTime",n.leadTime,o,i,r),Je(Number,s,"trailTime",n.trailTime,o,i,r),rt(s,"material",n.material,o,i,r),Je(f,s,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function At(e,t,r,i){var n=t.point;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.point;c(l)||(e.point=l=new de),Je(Boolean,l,"show",n.show,o,i,r),Je(Number,l,"pixelSize",n.pixelSize,o,i,r),Je(k,l,"heightReference",n.heightReference,o,i,r),Je(a,l,"color",n.color,o,i,r),Je(a,l,"outlineColor",n.outlineColor,o,i,r),Je(Number,l,"outlineWidth",n.outlineWidth,o,i,r),Je(A,l,"scaleByDistance",n.scaleByDistance,o,i,r),Je(A,l,"translucencyByDistance",n.translucencyByDistance,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r),Je(Number,l,"disableDepthTestDistance",n.disableDepthTestDistance,o,i,r)}}function xt(e,t,r,i){var n=t.polygon;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.polygon;c(l)||(e.polygon=l=new he),Je(Boolean,l,"show",n.show,o,i,r),ht(l,"hierarchy",n.positions,r),Je(Number,l,"height",n.height,o,i,r),Je(Number,l,"extrudedHeight",n.extrudedHeight,o,i,r),Je(we,l,"stRotation",n.stRotation,o,i,r),Je(Number,l,"granularity",n.granularity,o,i,r),Je(Boolean,l,"fill",n.fill,o,i,r),rt(l,"material",n.material,o,i,r),Je(Boolean,l,"outline",n.outline,o,i,r),Je(a,l,"outlineColor",n.outlineColor,o,i,r),Je(Number,l,"outlineWidth",n.outlineWidth,o,i,r),Je(Boolean,l,"perPositionHeight",n.perPositionHeight,o,i,r),Je(Boolean,l,"closeTop",n.closeTop,o,i,r),Je(Boolean,l,"closeBottom",n.closeBottom,o,i,r),Je(U,l,"shadows",n.shadows,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function Pt(e,t,r,i){var n=t.polyline;if(c(n)){var o,a=n.interval;c(a)&&(Ht.iso8601=a,o=R.fromIso8601(Ht));var s=e.polyline;c(s)||(e.polyline=s=new ge),Je(Boolean,s,"show",n.show,o,i,r),ht(s,"positions",n.positions,r),Je(Number,s,"width",n.width,o,i,r),Je(Number,s,"granularity",n.granularity,o,i,r),rt(s,"material",n.material,o,i,r),rt(s,"depthFailMaterial",n.depthFailMaterial,o,i,r),Je(Boolean,s,"followSurface",n.followSurface,o,i,r),Je(U,s,"shadows",n.shadows,o,i,r),Je(f,s,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function Dt(e,t,r,i){var n=t.rectangle;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.rectangle;c(l)||(e.rectangle=l=new Ce),Je(Boolean,l,"show",n.show,o,i,r),Je(P,l,"coordinates",n.coordinates,o,i,r),Je(Number,l,"height",n.height,o,i,r),Je(Number,l,"extrudedHeight",n.extrudedHeight,o,i,r),Je(we,l,"rotation",n.rotation,o,i,r),Je(we,l,"stRotation",n.stRotation,o,i,r),Je(Number,l,"granularity",n.granularity,o,i,r),Je(Boolean,l,"fill",n.fill,o,i,r),rt(l,"material",n.material,o,i,r),Je(Boolean,l,"outline",n.outline,o,i,r),Je(a,l,"outlineColor",n.outlineColor,o,i,r),Je(Number,l,"outlineWidth",n.outlineWidth,o,i,r),Je(Boolean,l,"closeTop",n.closeTop,o,i,r),Je(Boolean,l,"closeBottom",n.closeBottom,o,i,r),Je(U,l,"shadows",n.shadows,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function It(e,t,r,i){var n=t.wall;if(c(n)){var o,s=n.interval;c(s)&&(Ht.iso8601=s,o=R.fromIso8601(Ht));var l=e.wall;c(l)||(e.wall=l=new Me),Je(Boolean,l,"show",n.show,o,i,r),ht(l,"positions",n.positions,r),ct(l,"minimumHeights",n.minimumHeights,r),ct(l,"maximumHeights",n.maximumHeights,r),Je(Number,l,"granularity",n.granularity,o,i,r),Je(Boolean,l,"fill",n.fill,o,i,r),rt(l,"material",n.material,o,i,r),Je(Boolean,l,"outline",n.outline,o,i,r),Je(a,l,"outlineColor",n.outlineColor,o,i,r),Je(Number,l,"outlineWidth",n.outlineWidth,o,i,r),Je(U,l,"shadows",n.shadows,o,i,r),Je(f,l,"distanceDisplayCondition",n.distanceDisplayCondition,o,i,r)}}function Ot(e,t,r,i,n){var o=e.id;if(c(o)||(o=l()),Ft=o,!c(n._version)&&"document"!==o)throw new O("The first CZML packet is required to be the document object.");if(!0===e.delete)t.removeById(o);else if("document"===o)yt(e,n);else{var a=t.getOrCreateEntity(o),s=e.parent;c(s)&&(a.parent=t.getOrCreateEntity(s));for(var u=r.length-1;u>-1;u--)r[u](a,e,t,i)}Ft=void 0}function Mt(e){var t,r=e._documentPacket.clock;if(!c(r)){if(!c(e._clock)){var i=e._entityCollection.computeAvailability();if(!i.start.equals(C.MINIMUM_VALUE)){var a=i.start,s=i.stop,l=S.secondsDifference(s,a),d=Math.round(l/120);return t=new ee,t.startTime=S.clone(a),t.stopTime=S.clone(s),t.clockRange=n.LOOP_STOP,t.multiplier=d,t.currentTime=S.clone(a),t.clockStep=o.SYSTEM_CLOCK_MULTIPLIER,e._clock=t,!0}}return!1}if(c(e._clock)?t=e._clock.clone():(t=new ee,t.startTime=C.MINIMUM_VALUE.clone(),t.stopTime=C.MAXIMUM_VALUE.clone(),t.currentTime=C.MINIMUM_VALUE.clone(),t.clockRange=n.LOOP_STOP,t.clockStep=o.SYSTEM_CLOCK_MULTIPLIER,t.multiplier=1),c(r.interval)){Ht.iso8601=r.interval;var h=R.fromIso8601(Ht);t.startTime=h.start,t.stopTime=h.stop}return c(r.currentTime)&&(t.currentTime=S.fromIso8601(r.currentTime)),c(r.range)&&(t.clockRange=u(n[r.range],n.LOOP_STOP)),c(r.step)&&(t.clockStep=u(o[r.step],o.SYSTEM_CLOCK_MULTIPLIER)),c(r.multiplier)&&(t.multiplier=r.multiplier),!t.equals(e._clock)&&(e._clock=t.clone(e._clock),!0)}function Rt(e,t,r,i){r=u(r,u.EMPTY_OBJECT),c(r.query)&&h("CzmlDataSource.query","The options.query parameter has been deprecated. Specify czml or options.sourceUri as a Resource instance and add query parameters there.");var n=t,o=r.sourceUri,a=r.query;return("string"==typeof t||t instanceof I)&&(t=I.createIfNeeded(t,{queryParameters:a}),n=t.fetchJson(),o=u(o,t.clone())),o=I.createIfNeeded(o,{queryParameters:a}),$.setLoading(e,!0),G(n,function(t){return Lt(e,t,o,i)}).otherwise(function(t){return $.setLoading(e,!1),e._error.raiseEvent(e,t),console.log(t),G.reject(t)})}function Lt(e,t,r,i){$.setLoading(e,!0);var n=e._entityCollection;i&&(e._version=void 0,e._documentPacket=new Nt,n.removeAll()),kt._processCzml(t,n,r,void 0,e);var o=Mt(e),a=e._documentPacket;return c(a.name)&&e._name!==a.name?(e._name=a.name,o=!0):!c(e._name)&&c(r)&&(e._name=v(r.getUrlComponent()),o=!0),$.setLoading(e,!1),o&&e._changed.raiseEvent(e),e}function Nt(){this.name=void 0,this.clock=void 0}function kt(e){this._name=e,this._changed=new g,this._error=new g,this._isLoading=!1,this._loading=new g,this._clock=void 0,this._documentPacket=new Nt,this._version=void 0,this._entityCollection=new ne(this),this._entityCluster=new ie}Re.packedLength=r.packedLength,Re.unpack=r.unpack,Re.pack=r.pack;var Ft,Bt=new r,Ut=new M,Vt=new i,zt=new R,Gt=new x,Wt={HERMITE:y,LAGRANGE:w,LINEAR:T},Ht={iso8601:void 0};return kt.load=function(e,t){return(new kt).load(e,t)},d(kt.prototype,{name:{get:function(){return this._name}},clock:{get:function(){return this._clock}},entities:{get:function(){return this._entityCollection}},isLoading:{get:function(){return this._isLoading}},changedEvent:{get:function(){return this._changed}},errorEvent:{get:function(){return this._error}},loadingEvent:{get:function(){return this._loading}},show:{get:function(){return this._entityCollection.show},set:function(e){this._entityCollection.show=e}},clustering:{get:function(){return this._entityCluster},set:function(e){this._entityCluster=e}}}),kt.updaters=[mt,gt,_t,vt,bt,Ct,St,wt,it,nt,Et,At,xt,Pt,lt,Dt,ot,at,It,st,pt],kt.prototype.process=function(e,t){return Rt(this,e,t,!1)},kt.prototype.load=function(e,t){return Rt(this,e,t,!0)},kt.processPacketData=Je,kt.processPositionPacketData=et,kt.processMaterialPacketData=rt,kt._processCzml=function(e,t,r,i,n){if(i=c(i)?i:kt.updaters,b(e))for(var o=0,a=e.length;o<a;o++)Ot(e[o],t,i,r,n);else Ot(e,t,i,r,n)},kt}),define("DataSources/DataSourceCollection",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../ThirdParty/when"],function(e,t,r,i,n,o,a){"use strict";function s(){this._dataSources=[],this._dataSourceAdded=new o,this._dataSourceRemoved=new o}return r(s.prototype,{length:{get:function(){return this._dataSources.length}},dataSourceAdded:{get:function(){return this._dataSourceAdded}},dataSourceRemoved:{get:function(){return this._dataSourceRemoved}}}),s.prototype.add=function(e){var t=this,r=this._dataSources;return a(e,function(e){return r===t._dataSources&&(t._dataSources.push(e),t._dataSourceAdded.raiseEvent(t,e)),e})},s.prototype.remove=function(t,r){r=e(r,!1);var i=this._dataSources.indexOf(t);return-1!==i&&(this._dataSources.splice(i,1),this._dataSourceRemoved.raiseEvent(this,t),r&&"function"==typeof t.destroy&&t.destroy(),!0)},s.prototype.removeAll=function(t){t=e(t,!1);for(var r=this._dataSources,i=0,n=r.length;i<n;++i){var o=r[i];this._dataSourceRemoved.raiseEvent(this,o),t&&"function"==typeof o.destroy&&o.destroy()}this._dataSources=[]},s.prototype.contains=function(e){return-1!==this.indexOf(e)},s.prototype.indexOf=function(e){return this._dataSources.indexOf(e)},s.prototype.get=function(e){return this._dataSources[e]},s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this.removeAll(!0),i(this)},s}),define("DataSources/EllipseGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/EllipseGeometry","../Core/EllipseOutlineGeometry","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/oneTimeWarning","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e){this.id=e,this.vertexFormat=void 0,this.center=void 0,this.semiMajorAxis=void 0,this.semiMinorAxis=void 0,this.rotation=void 0,this.height=void 0,this.extrudedHeight=void 0,this.granularity=void 0,this.stRotation=void 0,this.numberOfVerticalLines=void 0}function x(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(x.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._isClosed=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new d,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._onTerrain=!1,this._options=new A(e),this._onEntityPropertyChanged(e,"ellipse",e.ellipse,void 0)}function P(e,t,r){this._primitives=e,this._groundPrimitives=t,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=r,this._options=new A(r._entity)}var D=new C(e.WHITE),I=new S(!0),O=new S(!0),M=new S(!1),R=new S(e.BLACK),L=new S(b.DISABLED),N=new S(new s),k=new e;return n(x,{perInstanceColorAppearanceType:{value:v},materialAppearanceType:{value:_}}),n(x.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&E.isConstant(this._showProperty)&&E.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&E.isConstant(this._showProperty)&&E.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return this._isClosed}},onTerrain:{get:function(){return this._onTerrain}},geometryChanged:{get:function(){return this._geometryChanged}}}),x.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},x.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},x.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),c=new m(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),p=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof C){var f=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(f=this._materialProperty.color.getValue(r)),o=t.fromColor(f),n={show:c,distanceDisplayCondition:p,color:o}}else n={show:c,distanceDisplayCondition:p};return new h({id:a,geometry:new u(this._options),attributes:n})},x.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=E.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new h({id:i,geometry:new c(this._options),attributes:{show:new m(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){this._entitySubscription(),o(this)},x.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"position"===t||"ellipse"===t){var a=this._entity.ellipse;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(p.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(p.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=this._entity.position,h=a.semiMajorAxis,m=a.semiMinorAxis,y=a.show;if(i(y)&&y.isConstant&&!y.getValue(p.MINIMUM_VALUE)||!i(d)||!i(h)||!i(m))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var b=r(a.material,D),S=b instanceof C;this._materialProperty=b,this._fillProperty=r(s,O),this._showProperty=r(y,I),this._showOutlineProperty=r(a.outline,M),this._outlineColorProperty=c?r(a.outlineColor,R):void 0,this._shadowsProperty=r(a.shadows,L),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,N);var w=a.rotation,T=a.height,A=a.extrudedHeight,x=a.granularity,P=a.stRotation,k=a.outlineWidth,F=a.numberOfVerticalLines,B=l&&!i(T)&&!i(A)&&S&&g.isSupported(this._scene);if(c&&B&&(f(f.geometryOutlines),c=!1),this._fillEnabled=l,this._onTerrain=B,this._isClosed=i(A)||B,this._outlineEnabled=c,d.isConstant&&h.isConstant&&m.isConstant&&E.isConstant(w)&&E.isConstant(T)&&E.isConstant(A)&&E.isConstant(x)&&E.isConstant(P)&&E.isConstant(k)&&E.isConstant(F)&&(!B||E.isConstant(b))){var U=this._options;U.vertexFormat=S?v.VERTEX_FORMAT:_.MaterialSupport.TEXTURED.vertexFormat,U.center=d.getValue(p.MINIMUM_VALUE,U.center),U.semiMajorAxis=h.getValue(p.MINIMUM_VALUE,U.semiMajorAxis),U.semiMinorAxis=m.getValue(p.MINIMUM_VALUE,U.semiMinorAxis),U.rotation=i(w)?w.getValue(p.MINIMUM_VALUE):void 0,U.height=i(T)?T.getValue(p.MINIMUM_VALUE):void 0,U.extrudedHeight=i(A)?A.getValue(p.MINIMUM_VALUE):void 0,U.granularity=i(x)?x.getValue(p.MINIMUM_VALUE):void 0,U.stRotation=i(P)?P.getValue(p.MINIMUM_VALUE):void 0,U.numberOfVerticalLines=i(F)?F.getValue(p.MINIMUM_VALUE):void 0,this._outlineWidth=i(k)?k.getValue(p.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},x.prototype.createDynamicUpdater=function(e,t){return new P(e,t,this)},P.prototype.update=function(r){var n=this._geometryUpdater,o=n._onTerrain,a=this._primitives,s=this._groundPrimitives;o?s.removeAndDestroy(this._primitive):(a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._outlinePrimitive=void 0),this._primitive=void 0;var d=n._entity,p=d.ellipse;if(d.isShowing&&d.isAvailable(r)&&E.getValueOrDefault(p.show,r,!0)){var f=this._options,m=E.getValueOrUndefined(d.position,r,f.center),b=E.getValueOrUndefined(p.semiMajorAxis,r),C=E.getValueOrUndefined(p.semiMinorAxis,r);if(i(m)&&i(b)&&i(C)){f.center=m,f.semiMajorAxis=b,f.semiMinorAxis=C,f.rotation=E.getValueOrUndefined(p.rotation,r),f.height=E.getValueOrUndefined(p.height,r),f.extrudedHeight=E.getValueOrUndefined(p.extrudedHeight,r),f.granularity=E.getValueOrUndefined(p.granularity,r),f.stRotation=E.getValueOrUndefined(p.stRotation,r),f.numberOfVerticalLines=E.getValueOrUndefined(p.numberOfVerticalLines,r);var S=this._geometryUpdater.shadowsProperty.getValue(r),w=this._geometryUpdater.distanceDisplayConditionProperty,A=w.getValue(r),x=l.fromDistanceDisplayCondition(A);if(E.getValueOrDefault(p.fill,r,!0)){var P=n.fillMaterialProperty,D=T.getValue(r,P,this._material);if(this._material=D,o){var I=e.WHITE;i(P.color)&&(I=P.color.getValue(r)),this._primitive=s.add(new g({geometryInstances:new h({id:d,geometry:new u(f),attributes:{color:t.fromColor(I),distanceDisplayCondition:x}}),asynchronous:!1,shadows:S}))}else{var O=new _({material:D,translucent:D.isTranslucent(),closed:i(f.extrudedHeight)});f.vertexFormat=O.vertexFormat,this._primitive=a.add(new y({geometryInstances:new h({id:d,geometry:new u(f)}),attributes:{distanceDisplayCondition:x},appearance:O,asynchronous:!1,shadows:S}))}}if(!o&&E.getValueOrDefault(p.outline,r,!1)){f.vertexFormat=v.VERTEX_FORMAT;var M=E.getValueOrClonedDefault(p.outlineColor,r,e.BLACK,k),R=E.getValueOrDefault(p.outlineWidth,r,1),L=1!==M.alpha;this._outlinePrimitive=a.add(new y({geometryInstances:new h({id:d,geometry:new c(f),attributes:{color:t.fromColor(M),distanceDisplayCondition:x}}),appearance:new v({flat:!0,translucent:L,renderState:{lineWidth:n._scene.clampLineWidth(R)}}),asynchronous:!1,shadows:S}))}}}},P.prototype.getBoundingSphere=function(e,t){return w(e,this._primitive,this._outlinePrimitive,t)},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){var e=this._primitives,t=this._groundPrimitives;this._geometryUpdater._onTerrain?t.removeAndDestroy(this._primitive):e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},x}),define("DataSources/EllipsoidGeometryUpdater",["../Core/Cartesian3","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/EllipsoidGeometry","../Core/EllipsoidOutlineGeometry","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/Matrix4","../Core/ShowGeometryInstanceAttribute","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/SceneMode","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A){"use strict";function x(e){this.id=e,this.vertexFormat=void 0,this.radii=void 0,this.stackPartitions=void 0,this.slicePartitions=void 0,this.subdivisions=void 0}function P(e,t){this._scene=t,this._entity=e,this._entitySubscription=e.definitionChanged.addEventListener(P.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new h,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new x(e),this._onEntityPropertyChanged(e,"ellipsoid",e.ellipsoid,void 0)}function D(e,t){this._entity=t._entity,this._scene=t._scene,this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new x(t._entity),this._modelMatrix=new m,this._material=void 0,this._attributes=void 0,this._outlineAttributes=void 0,this._lastSceneMode=void 0,this._lastShow=void 0,this._lastOutlineShow=void 0,this._lastOutlineWidth=void 0,this._lastOutlineColor=void 0}var I=new S(t.WHITE),O=new w(!0),M=new w(!0),R=new w(!1),L=new w(t.BLACK),N=new w(C.DISABLED),k=new w(new l),F=new e,B=new t,U=new e(1,1,1);return o(P,{perInstanceColorAppearanceType:{value:v},materialAppearanceType:{value:_}}),o(P.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){ +return!this._fillEnabled||!n(this._entity.availability)&&A.isConstant(this._showProperty)&&A.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!n(this._entity.availability)&&A.isConstant(this._showProperty)&&A.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!0},geometryChanged:{get:function(){return this._geometryChanged}}}),P.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},P.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},P.prototype.createFillGeometryInstance=function(e){var i,o,a=this._entity,s=a.isAvailable(e),l=new g(s&&a.isShowing&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)),d=this._distanceDisplayConditionProperty.getValue(e),h=u.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof S){var m=t.WHITE;n(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(m=this._materialProperty.color.getValue(e)),o=r.fromColor(m),i={show:l,distanceDisplayCondition:h,color:o}}else i={show:l,distanceDisplayCondition:h};return new p({id:a,geometry:new c(this._options),modelMatrix:a.computeModelMatrix(f.MINIMUM_VALUE),attributes:i})},P.prototype.createOutlineGeometryInstance=function(e){var i=this._entity,n=i.isAvailable(e),o=A.getValueOrDefault(this._outlineColorProperty,e,t.BLACK),a=this._distanceDisplayConditionProperty.getValue(e);return new p({id:i,geometry:new d(this._options),modelMatrix:i.computeModelMatrix(f.MINIMUM_VALUE),attributes:{show:new g(n&&i.isShowing&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)),color:r.fromColor(o),distanceDisplayCondition:u.fromDistanceDisplayCondition(a)}})},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){this._entitySubscription(),a(this)},P.prototype._onEntityPropertyChanged=function(e,t,r,o){if("availability"===t||"position"===t||"orientation"===t||"ellipsoid"===t){var a=e.ellipsoid;if(!n(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!n(s)||!s.isConstant||s.getValue(f.MINIMUM_VALUE),u=a.outline,c=n(u);if(c&&u.isConstant&&(c=u.getValue(f.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=e.position,h=a.radii,p=a.show;if(n(p)&&p.isConstant&&!p.getValue(f.MINIMUM_VALUE)||!n(d)||!n(h))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var m=i(a.material,I),g=m instanceof S;this._materialProperty=m,this._fillProperty=i(s,M),this._showProperty=i(p,O),this._showOutlineProperty=i(a.outline,R),this._outlineColorProperty=c?i(a.outlineColor,L):void 0,this._shadowsProperty=i(a.shadows,N),this._distanceDisplayConditionProperty=i(a.distanceDisplayCondition,k),this._fillEnabled=l,this._outlineEnabled=c;var y=a.stackPartitions,b=a.slicePartitions,C=a.outlineWidth,w=a.subdivisions;if(d.isConstant&&A.isConstant(e.orientation)&&h.isConstant&&A.isConstant(y)&&A.isConstant(b)&&A.isConstant(C)&&A.isConstant(w)){var T=this._options;T.vertexFormat=g?v.VERTEX_FORMAT:_.MaterialSupport.TEXTURED.vertexFormat,T.radii=h.getValue(f.MINIMUM_VALUE,T.radii),T.stackPartitions=n(y)?y.getValue(f.MINIMUM_VALUE):void 0,T.slicePartitions=n(b)?b.getValue(f.MINIMUM_VALUE):void 0,T.subdivisions=n(w)?w.getValue(f.MINIMUM_VALUE):void 0,this._outlineWidth=n(C)?C.getValue(f.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},P.prototype.createDynamicUpdater=function(e){return new D(e,this)},D.prototype.update=function(e){var o=this._entity,a=o.ellipsoid;if(!o.isShowing||!o.isAvailable(e)||!A.getValueOrDefault(a.show,e,!0))return n(this._primitive)&&(this._primitive.show=!1),void(n(this._outlinePrimitive)&&(this._outlinePrimitive.show=!1));var s=A.getValueOrUndefined(a.radii,e,F),h=o.computeModelMatrix(e,this._modelMatrix);if(!n(h)||!n(s))return n(this._primitive)&&(this._primitive.show=!1),void(n(this._outlinePrimitive)&&(this._outlinePrimitive.show=!1));var f,C=A.getValueOrDefault(a.fill,e,!0),S=A.getValueOrDefault(a.outline,e,!1),w=A.getValueOrClonedDefault(a.outlineColor,e,t.BLACK,B),T=E.getValue(e,i(a.material,I),this._material);this._material=T;var x=A.getValueOrUndefined(a.stackPartitions,e),P=A.getValueOrUndefined(a.slicePartitions,e),D=A.getValueOrUndefined(a.subdivisions,e),O=A.getValueOrDefault(a.outlineWidth,e,1),M=this._scene.mode,R=M===b.SCENE3D,L=this._options,N=this._geometryUpdater.shadowsProperty.getValue(e),k=this._geometryUpdater.distanceDisplayConditionProperty,V=k.getValue(e),z=u.fromDistanceDisplayCondition(V);if(R&&this._lastSceneMode===M&&n(this._primitive)&&L.stackPartitions===x&&L.slicePartitions===P&&L.subdivisions===D&&this._lastOutlineWidth===O){if(this._primitive.ready){var G=this._primitive,W=this._outlinePrimitive;G.show=!0,W.show=!0,f=G.appearance,f.material=T;var H=this._attributes;n(H)||(H=G.getGeometryInstanceAttributes(o),this._attributes=H),C!==this._lastShow&&(H.show=g.toValue(C,H.show),this._lastShow=C);var j=this._outlineAttributes;n(j)||(j=W.getGeometryInstanceAttributes(o),this._outlineAttributes=j),S!==this._lastOutlineShow&&(j.show=g.toValue(S,j.show),this._lastOutlineShow=S),t.equals(w,this._lastOutlineColor)||(j.color=r.toValue(w,j.color),t.clone(w,this._lastOutlineColor)),l.equals(V,this._lastDistanceDisplayCondition)||(H.distanceDisplayCondition=u.toValue(V,H.distanceDisplayCondition),j.distanceDisplayCondition=u.toValue(V,j.distanceDisplayCondition),l.clone(V,this._lastDistanceDisplayCondition))}}else{var q=this._primitives;q.removeAndDestroy(this._primitive),q.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0,this._lastSceneMode=M,this._lastOutlineWidth=O,L.stackPartitions=x,L.slicePartitions=P,L.subdivisions=D,L.radii=R?U:s,f=new _({material:T,translucent:T.isTranslucent(),closed:!0}),L.vertexFormat=f.vertexFormat,this._primitive=q.add(new y({geometryInstances:new p({id:o,geometry:new c(L),modelMatrix:R?void 0:h,attributes:{show:new g(C),distanceDisplayCondition:z}}),appearance:f,asynchronous:!1,shadows:N})),L.vertexFormat=v.VERTEX_FORMAT,this._outlinePrimitive=q.add(new y({geometryInstances:new p({id:o,geometry:new d(L),modelMatrix:R?void 0:h,attributes:{show:new g(S),color:r.fromColor(w),distanceDisplayCondition:z}}),appearance:new v({flat:!0,translucent:1!==w.alpha,renderState:{lineWidth:this._geometryUpdater._scene.clampLineWidth(O)}}),asynchronous:!1,shadows:N})),this._lastShow=C,this._lastOutlineShow=S,this._lastOutlineColor=t.clone(w,this._lastOutlineColor),this._lastDistanceDisplayCondition=V}R&&(s.x=Math.max(s.x,.001),s.y=Math.max(s.y,.001),s.z=Math.max(s.z,.001),h=m.multiplyByScale(h,s,h),this._primitive.modelMatrix=h,this._outlinePrimitive.modelMatrix=h)},D.prototype.getBoundingSphere=function(e,t){return T(e,this._primitive,this._outlinePrimitive,t)},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),a(this)},P}),define("DataSources/StaticGeometryColorBatch",["../Core/AssociativeArray","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defined","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/ShowGeometryInstanceAttribute","../Scene/Primitive","./BoundingSphereState","./ColorMaterialProperty","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t,r,n,o,a,s,l){this.translucent=r,this.appearanceType=n,this.depthFailAppearanceType=o,this.depthFailMaterialProperty=a,this.depthFailMaterial=void 0,this.closed=s,this.shadows=l,this.primitives=t,this.createPrimitive=!1,this.waitingOnCreate=!1,this.primitive=void 0,this.oldPrimitive=void 0,this.geometry=new e,this.updaters=new e,this.updatersWithAttributes=new e,this.attributes=new e,this.subscriptions=new e,this.showsUpdated=new e,this.itemsToRemove=[],this.invalidated=!1;var u;i(a)&&(u=a.definitionChanged.addEventListener(h.prototype.onMaterialChanged,this)),this.removeMaterialSubscription=u}function p(e,t,r,i,n){this._solidItems=[],this._translucentItems=[],this._primitives=e,this._appearanceType=t,this._depthFailAppearanceType=r,this._closed=i,this._shadows=n}function f(e,t){for(var r=e.length,i=r-1;i>=0;i--){var n=e[i];if(n.remove(t)&&0===n.updaters.length)return e.splice(i,1),n.destroy(),!0}return!1}function m(e,t,r){for(var i=!1,n=t.length,o=0;o<n;++o){var a=t[o],s=a.itemsToRemove,l=s.length;if(l>0)for(o=0;o<l;o++){var u=s[o];a.remove(u),e.add(r,u),i=!0}}return i}function g(e,t,r,i){var n,o=t.length;for(n=o-1;n>=0;n--){var a=t[n];if(a.invalidated){t.splice(n,1);for(var s=a.updaters.values,l=s.length,u=0;u<l;u++)e.add(r,s[u]);a.destroy()}}for(o=t.length,n=0;n<o;++n)i=t[n].update(r)&&i;return i}function _(e,t,r){for(var i=e.length,n=0;n<i;n++){var o=e[n];if(o.contains(t))return o.getBoundingSphere(t,r)}return l.FAILED}function v(e){for(var t=e.length,r=0;r<t;r++)e[r].destroy();e.length=0}var y=new t,b=new n;return h.prototype.onMaterialChanged=function(){this.invalidated=!0},h.prototype.isMaterial=function(e){var t=this.depthFailMaterialProperty,r=e.depthFailMaterialProperty;return r===t||!!i(t)&&t.equals(r)},h.prototype.add=function(e,t){var r=e.entity.id;if(this.createPrimitive=!0,this.geometry.set(r,t),this.updaters.set(r,e),e.hasConstantFill&&e.fillMaterialProperty.isConstant&&d.isConstant(e.distanceDisplayConditionProperty)){var i=this;this.subscriptions.set(r,e.entity.definitionChanged.addEventListener(function(t,r,n,o){"isShowing"===r&&i.showsUpdated.set(t.id,e)}))}else this.updatersWithAttributes.set(r,e)},h.prototype.remove=function(e){var t=e.entity.id;if(this.createPrimitive=this.geometry.remove(t)||this.createPrimitive,this.updaters.remove(t)){this.updatersWithAttributes.remove(t);var r=this.subscriptions.get(t);i(r)&&(r(),this.subscriptions.remove(t))}},h.prototype.update=function(e){var l,h,p=!0,f=0,m=this.primitive,g=this.primitives;if(this.createPrimitive){var _=this.geometry.values,v=_.length;if(v>0){for(i(m)&&(i(this.oldPrimitive)?g.remove(m):this.oldPrimitive=m),h=0;h<v;h++){var C=_[h],S=C.attributes;l=this.attributes.get(C.id.id),i(l)&&(i(S.show)&&(S.show.value=l.show),i(S.color)&&(S.color.value=l.color),i(S.depthFailColor)&&(S.depthFailColor.value=l.depthFailColor))}var w;i(this.depthFailAppearanceType)&&(i(this.depthFailMaterialProperty)&&(this.depthFailMaterial=c.getValue(e,this.depthFailMaterialProperty,this.depthFailMaterial)),w=new this.depthFailAppearanceType({material:this.depthFailMaterial,translucent:this.translucent,closed:this.closed})),m=new s({asynchronous:!0,geometryInstances:_,appearance:new this.appearanceType({translucent:this.translucent,closed:this.closed}),depthFailAppearance:w,shadows:this.shadows}),g.add(m),p=!1}else{i(m)&&(g.remove(m),m=void 0);var T=this.oldPrimitive;i(T)&&(g.remove(T),this.oldPrimitive=void 0)}this.attributes.removeAll(),this.primitive=m,this.createPrimitive=!1,this.waitingOnCreate=!0}else if(i(m)&&m.ready){i(this.oldPrimitive)&&(g.remove(this.oldPrimitive),this.oldPrimitive=void 0),!i(this.depthFailAppearanceType)||this.depthFailMaterialProperty instanceof u||(this.depthFailMaterial=c.getValue(e,this.depthFailMaterialProperty,this.depthFailMaterial),this.primitive.depthFailAppearance.material=this.depthFailMaterial);var E=this.updatersWithAttributes.values,A=E.length,x=this.waitingOnCreate;for(h=0;h<A;h++){var P=E[h],D=this.geometry.get(P.entity.id);if(l=this.attributes.get(D.id.id),i(l)||(l=m.getGeometryInstanceAttributes(D.id),this.attributes.set(D.id.id,l)),!P.fillMaterialProperty.isConstant||x){var I=P.fillMaterialProperty.color;I.getValue(e,y),t.equals(l._lastColor,y)||(l._lastColor=t.clone(y,l._lastColor),l.color=r.toValue(y,l.color),(this.translucent&&255===l.color[3]||!this.translucent&&255!==l.color[3])&&(this.itemsToRemove[f++]=P))}if(i(this.depthFailAppearanceType)&&this.depthFailAppearanceType instanceof u&&(!P.depthFailMaterialProperty.isConstant||x)){var O=P.depthFailMaterialProperty.color;O.getValue(e,y),t.equals(l._lastDepthFailColor,y)||(l._lastDepthFailColor=t.clone(y,l._lastDepthFailColor),l.depthFailColor=r.toValue(y,l.depthFailColor))}var M=P.entity.isShowing&&(P.hasConstantFill||P.isFilled(e)),R=1===l.show[0];M!==R&&(l.show=a.toValue(M,l.show));var L=P.distanceDisplayConditionProperty;if(!d.isConstant(L)){var N=L.getValue(e,b);n.equals(N,l._lastDistanceDisplayCondition)||(l._lastDistanceDisplayCondition=n.clone(N,l._lastDistanceDisplayCondition),l.distanceDisplayCondition=o.toValue(N,l.distanceDisplayCondition))}}this.updateShows(m),this.waitingOnCreate=!1}else i(m)&&!m.ready&&(p=!1);return this.itemsToRemove.length=f,p},h.prototype.updateShows=function(e){for(var t=this.showsUpdated.values,r=t.length,n=0;n<r;n++){var o=t[n],s=this.geometry.get(o.entity.id),l=this.attributes.get(s.id.id);i(l)||(l=e.getGeometryInstanceAttributes(s.id),this.attributes.set(s.id.id,l));var u=o.entity.isShowing;u!==(1===l.show[0])&&(l.show=a.toValue(u,l.show))}this.showsUpdated.removeAll()},h.prototype.contains=function(e){return this.updaters.contains(e.id)},h.prototype.getBoundingSphere=function(e,t){var r=this.primitive;if(!r.ready)return l.PENDING;var n=r.getGeometryInstanceAttributes(e);return!i(n)||!i(n.boundingSphere)||i(n.show)&&0===n.show[0]?l.FAILED:(n.boundingSphere.clone(t),l.DONE)},h.prototype.removeAllPrimitives=function(){var e=this.primitives,t=this.primitive;i(t)&&(e.remove(t),this.primitive=void 0,this.geometry.removeAll(),this.updaters.removeAll());var r=this.oldPrimitive;i(r)&&(e.remove(r),this.oldPrimitive=void 0)},h.prototype.destroy=function(){var e=this.primitive,t=this.primitives;i(e)&&t.remove(e);var r=this.oldPrimitive;i(r)&&t.remove(r),i(this.removeMaterialSubscription)&&this.removeMaterialSubscription()},p.prototype.add=function(e,t){var r,i,n=t.createFillGeometryInstance(e);255===n.attributes.color.value[3]?(r=this._solidItems,i=!1):(r=this._translucentItems,i=!0);for(var o=r.length,a=0;a<o;a++){var s=r[a];if(s.isMaterial(t))return void s.add(t,n)}var l=new h(this._primitives,i,this._appearanceType,this._depthFailAppearanceType,t.depthFailMaterialProperty,this._closed,this._shadows);l.add(t,n),r.push(l)},p.prototype.remove=function(e){f(this._solidItems,e)||f(this._translucentItems,e)},p.prototype.update=function(e){var t=g(this,this._solidItems,e,!0);t=g(this,this._translucentItems,e,t)&&t;var r=m(this,this._solidItems,e),i=m(this,this._translucentItems,e);return(r||i)&&(t=g(this,this._solidItems,e,t)&&t,t=g(this,this._translucentItems,e,t)&&t),t},p.prototype.getBoundingSphere=function(e,t){var r=_(this._solidItems,e,t);return r===l.FAILED?_(this._translucentItems,e,t):r},p.prototype.removeAllPrimitives=function(){v(this._solidItems),v(this._translucentItems)},p}),define("DataSources/StaticGeometryPerMaterialBatch",["../Core/AssociativeArray","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defined","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/ShowGeometryInstanceAttribute","../Scene/Primitive","./BoundingSphereState","./ColorMaterialProperty","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t,r,i,n,o,a,s){this.primitives=t,this.appearanceType=r,this.materialProperty=i,this.depthFailAppearanceType=n,this.depthFailMaterialProperty=o,this.closed=a,this.shadows=s,this.updaters=new e,this.createPrimitive=!0,this.primitive=void 0,this.oldPrimitive=void 0,this.geometry=new e,this.material=void 0,this.depthFailMaterial=void 0,this.updatersWithAttributes=new e,this.attributes=new e,this.invalidated=!1,this.removeMaterialSubscription=i.definitionChanged.addEventListener(h.prototype.onMaterialChanged,this),this.subscriptions=new e,this.showsUpdated=new e}function p(e,t,r,i,n){this._items=[],this._primitives=e,this._appearanceType=t,this._depthFailAppearanceType=r,this._closed=i,this._shadows=n}var f=new n;h.prototype.onMaterialChanged=function(){this.invalidated=!0},h.prototype.isMaterial=function(e){var t=this.materialProperty,r=e.fillMaterialProperty,n=this.depthFailMaterialProperty,o=e.depthFailMaterialProperty;if(r===t&&o===n)return!0;var a=i(t)&&t.equals(r);return a=(!i(n)&&!i(o)||i(n)&&n.equals(o))&&a},h.prototype.add=function(e,t){var r=t.entity.id;if(this.updaters.set(r,t),this.geometry.set(r,t.createFillGeometryInstance(e)),t.hasConstantFill&&t.fillMaterialProperty.isConstant&&d.isConstant(t.distanceDisplayConditionProperty)){var i=this;this.subscriptions.set(r,t.entity.definitionChanged.addEventListener(function(e,r,n,o){"isShowing"===r&&i.showsUpdated.set(e.id,t)}))}else this.updatersWithAttributes.set(r,t);this.createPrimitive=!0},h.prototype.remove=function(e){var t=e.entity.id;if(this.createPrimitive=this.geometry.remove(t)||this.createPrimitive,this.updaters.remove(t)){this.updatersWithAttributes.remove(t);var r=this.subscriptions.get(t);i(r)&&(r(),this.subscriptions.remove(t))}return this.createPrimitive};var m=new t;return h.prototype.update=function(e){var l,h,p=!0,g=this.primitive,_=this.primitives,v=this.geometry.values;if(this.createPrimitive){var y=v.length;if(y>0){for(i(g)&&(i(this.oldPrimitive)?_.remove(g):this.oldPrimitive=g),h=0;h<y;h++){var b=v[h],C=b.attributes;l=this.attributes.get(b.id.id),i(l)&&(i(C.show)&&(C.show.value=l.show),i(C.color)&&(C.color.value=l.color),i(C.depthFailColor)&&(C.depthFailColor.value=l.depthFailColor))}this.material=c.getValue(e,this.materialProperty,this.material);var S;if(i(this.depthFailMaterialProperty)){var w;this.depthFailMaterialProperty instanceof c?(this.depthFailMaterial=c.getValue(e,this.depthFailMaterialProperty,this.depthFailMaterial),w=this.depthFailMaterial.isTranslucent()):w=this.material.isTranslucent(),S=new this.depthFailAppearanceType({material:this.depthFailMaterial,translucent:w,closed:this.closed})}g=new s({asynchronous:!0,geometryInstances:v,appearance:new this.appearanceType({material:this.material,translucent:this.material.isTranslucent(),closed:this.closed}),depthFailAppearance:S,shadows:this.shadows}),_.add(g),p=!1}else{i(g)&&(_.remove(g),g=void 0);var T=this.oldPrimitive;i(T)&&(_.remove(T),this.oldPrimitive=void 0)}this.attributes.removeAll(),this.primitive=g,this.createPrimitive=!1}else if(i(g)&&g.ready){i(this.oldPrimitive)&&(_.remove(this.oldPrimitive),this.oldPrimitive=void 0),this.material=c.getValue(e,this.materialProperty,this.material),this.primitive.appearance.material=this.material,!i(this.depthFailAppearanceType)||this.depthFailMaterialProperty instanceof u||(this.depthFailMaterial=c.getValue(e,this.depthFailMaterialProperty,this.depthFailMaterial),this.primitive.depthFailAppearance.material=this.depthFailMaterial);var E=this.updatersWithAttributes.values,A=E.length;for(h=0;h<A;h++){var x=E[h],P=x.entity,D=this.geometry.get(P.id);if(l=this.attributes.get(D.id.id),i(l)||(l=g.getGeometryInstanceAttributes(D.id),this.attributes.set(D.id.id,l)),i(this.depthFailAppearanceType)&&this.depthFailAppearanceType instanceof u&&!x.depthFailMaterialProperty.isConstant){var I=x.depthFailMaterialProperty.color;I.getValue(e,m),t.equals(l._lastDepthFailColor,m)||(l._lastDepthFailColor=t.clone(m,l._lastDepthFailColor),l.depthFailColor=r.toValue(m,l.depthFailColor))}var O=P.isShowing&&(x.hasConstantFill||x.isFilled(e)),M=1===l.show[0];O!==M&&(l.show=a.toValue(O,l.show));var R=x.distanceDisplayConditionProperty;if(!d.isConstant(R)){var L=R.getValue(e,f);n.equals(L,l._lastDistanceDisplayCondition)||(l._lastDistanceDisplayCondition=n.clone(L,l._lastDistanceDisplayCondition),l.distanceDisplayCondition=o.toValue(L,l.distanceDisplayCondition))}}this.updateShows(g)}else i(g)&&!g.ready&&(p=!1);return p},h.prototype.updateShows=function(e){for(var t=this.showsUpdated.values,r=t.length,n=0;n<r;n++){var o=t[n],s=o.entity,l=this.geometry.get(s.id),u=this.attributes.get(l.id.id);i(u)||(u=e.getGeometryInstanceAttributes(l.id),this.attributes.set(l.id.id,u));var c=s.isShowing;c!==(1===u.show[0])&&(u.show=a.toValue(c,u.show))}this.showsUpdated.removeAll()},h.prototype.contains=function(e){return this.updaters.contains(e.id)},h.prototype.getBoundingSphere=function(e,t){var r=this.primitive;if(!r.ready)return l.PENDING;var n=r.getGeometryInstanceAttributes(e);return!i(n)||!i(n.boundingSphere)||i(n.show)&&0===n.show[0]?l.FAILED:(n.boundingSphere.clone(t),l.DONE)},h.prototype.destroy=function(){var e=this.primitive,t=this.primitives;i(e)&&t.remove(e);var r=this.oldPrimitive;i(r)&&t.remove(r),this.removeMaterialSubscription()},p.prototype.add=function(e,t){for(var r=this._items,i=r.length,n=0;n<i;n++){var o=r[n];if(o.isMaterial(t))return void o.add(e,t)}var a=new h(this._primitives,this._appearanceType,t.fillMaterialProperty,this._depthFailAppearanceType,t.depthFailMaterialProperty,this._closed,this._shadows);a.add(e,t),r.push(a)},p.prototype.remove=function(e){for(var t=this._items,r=t.length,i=r-1;i>=0;i--){var n=t[i];if(n.remove(e)){0===n.updaters.length&&(t.splice(i,1),n.destroy());break}}},p.prototype.update=function(e){var t,r=this._items,i=r.length;for(t=i-1;t>=0;t--){var n=r[t];if(n.invalidated){r.splice(t,1);for(var o=n.updaters.values,a=o.length,s=0;s<a;s++)this.add(e,o[s]);n.destroy()}}var l=!0;for(t=0;t<i;t++)l=r[t].update(e)&&l;return l},p.prototype.getBoundingSphere=function(e,t){for(var r=this._items,i=r.length,n=0;n<i;n++){var o=r[n];if(o.contains(e))return o.getBoundingSphere(e,t)}return l.FAILED},p.prototype.removeAllPrimitives=function(){for(var e=this._items,t=e.length,r=0;r<t;r++)e[r].destroy();this._items.length=0},p}),define("DataSources/StaticGroundGeometryColorBatch",["../Core/AssociativeArray","../Core/Color","../Core/defined","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t,r,i){this.primitives=t,this.color=r,this.key=i,this.createPrimitive=!1,this.waitingOnCreate=!1,this.primitive=void 0,this.oldPrimitive=void 0,this.geometry=new e,this.updaters=new e,this.updatersWithAttributes=new e,this.attributes=new e,this.subscriptions=new e,this.showsUpdated=new e,this.itemsToRemove=[],this.isDirty=!1}function c(t){this._batches=new e,this._primitives=t}var d=new t,h=new i;u.prototype.add=function(e,t){var r=e.entity.id;if(this.createPrimitive=!0,this.geometry.set(r,t),this.updaters.set(r,e),e.hasConstantFill&&e.fillMaterialProperty.isConstant&&l.isConstant(e.distanceDisplayConditionProperty)){var i=this;this.subscriptions.set(r,e.entity.definitionChanged.addEventListener(function(t,r,n,o){"isShowing"===r&&i.showsUpdated.set(t.id,e)}))}else this.updatersWithAttributes.set(r,e)},u.prototype.remove=function(e){var t=e.entity.id;if(this.createPrimitive=this.geometry.remove(t)||this.createPrimitive,this.updaters.remove(t)){this.updatersWithAttributes.remove(t);var i=this.subscriptions.get(t);r(i)&&(i(),this.subscriptions.remove(t))}};var p=new Array(4);return u.prototype.update=function(e){var s,u,c=!0,f=0,m=this.primitive,g=this.primitives;if(this.createPrimitive){var _=this.geometry.values,v=_.length;if(v>0){for(r(m)&&(r(this.oldPrimitive)?g.remove(m):this.oldPrimitive=m),u=0;u<v;u++){var y=_[u],b=y.attributes;s=this.attributes.get(y.id.id),r(s)&&(r(b.show)&&(b.show.value=s.show),r(b.color)&&(b.color.value=s.color))}m=new a({asynchronous:!0,geometryInstances:_}),g.add(m),c=!1}else{r(m)&&(g.remove(m),m=void 0);var C=this.oldPrimitive;r(C)&&(g.remove(C),this.oldPrimitive=void 0)}this.attributes.removeAll(),this.primitive=m,this.createPrimitive=!1,this.waitingOnCreate=!0}else if(r(m)&&m.ready){r(this.oldPrimitive)&&(g.remove(this.oldPrimitive),this.oldPrimitive=void 0);var S=this.updatersWithAttributes.values,w=S.length,T=this.waitingOnCreate;for(u=0;u<w;u++){var E=S[u],A=this.geometry.get(E.entity.id);if(s=this.attributes.get(A.id.id),r(s)||(s=m.getGeometryInstanceAttributes(A.id),this.attributes.set(A.id.id,s)),!E.fillMaterialProperty.isConstant||T){var x=E.fillMaterialProperty.color;if(x.getValue(e,d),!t.equals(s._lastColor,d)){s._lastColor=t.clone(d,s._lastColor);var P=this.color,D=d.toBytes(p);P[0]===D[0]&&P[1]===D[1]&&P[2]===D[2]&&P[3]===D[3]||(this.itemsToRemove[f++]=E)}}var I=E.entity.isShowing&&(E.hasConstantFill||E.isFilled(e)),O=1===s.show[0];I!==O&&(s.show=o.toValue(I,s.show));var M=E.distanceDisplayConditionProperty;if(!l.isConstant(M)){var R=M.getValue(e,h);i.equals(R,s._lastDistanceDisplayCondition)||(s._lastDistanceDisplayCondition=i.clone(R,s._lastDistanceDisplayCondition),s.distanceDisplayCondition=n.toValue(R,s.distanceDisplayCondition))}}this.updateShows(m),this.waitingOnCreate=!1}else r(m)&&!m.ready&&(c=!1);return this.itemsToRemove.length=f,c},u.prototype.updateShows=function(e){for(var t=this.showsUpdated.values,i=t.length,n=0;n<i;n++){var a=t[n],s=this.geometry.get(a.entity.id),l=this.attributes.get(s.id.id);r(l)||(l=e.getGeometryInstanceAttributes(s.id),this.attributes.set(s.id.id,l));var u=a.entity.isShowing;u!==(1===l.show[0])&&(l.show=o.toValue(u,l.show))}this.showsUpdated.removeAll()},u.prototype.contains=function(e){return this.updaters.contains(e.id)},u.prototype.getBoundingSphere=function(e,t){var i=this.primitive;if(!i.ready)return s.PENDING;var n=i.getBoundingSphere(e);return r(n)?(n.clone(t),s.DONE):s.FAILED},u.prototype.removeAllPrimitives=function(){var e=this.primitives,t=this.primitive;r(t)&&(e.remove(t),this.primitive=void 0,this.geometry.removeAll(),this.updaters.removeAll());var i=this.oldPrimitive;r(i)&&(e.remove(i),this.oldPrimitive=void 0)},c.prototype.add=function(e,t){var r,i=t.createFillGeometryInstance(e),n=this._batches,o=new Uint32Array(i.attributes.color.value.buffer)[0];return n.contains(o)?r=n.get(o):(r=new u(this._primitives,i.attributes.color.value,o),n.set(o,r)),r.add(t,i),r},c.prototype.remove=function(e){for(var t=this._batches.values,r=t.length,i=0;i<r;++i)if(t[i].remove(e))return},c.prototype.update=function(e){var t,r,i=!0,n=this._batches,o=n.values,a=o.length;for(t=0;t<a;++t)i=o[t].update(e)&&i;for(t=0;t<a;++t)for(var s=o[t],l=s.itemsToRemove,u=l.length,c=0;c<u;c++){r=l[c],s.remove(r);var d=this.add(e,r);s.isDirty=!0,d.isDirty=!0}var h=o.slice(),p=h.length;for(t=0;t<p;++t){var f=h[t];f.isDirty&&(i=h[t].update(e)&&i,f.isDirty=!1),0===f.geometry.length&&n.remove(f.key)}return i},c.prototype.getBoundingSphere=function(e,t){for(var r=this._batches.values,i=r.length,n=0;n<i;++n){var o=r[n];if(o.contains(e))return o.getBoundingSphere(e,t)}return s.FAILED},c.prototype.removeAllPrimitives=function(){for(var e=this._batches.values,t=e.length,r=0;r<t;++r)e[r].removeAllPrimitives()},c}),define("DataSources/StaticOutlineGeometryBatch",["../Core/AssociativeArray","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defined","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/ShowGeometryInstanceAttribute","../Scene/PerInstanceColorAppearance","../Scene/Primitive","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(t,r,i,n){this.translucent=r,this.width=i,this.shadows=n,this.primitives=t,this.createPrimitive=!1,this.waitingOnCreate=!1,this.primitive=void 0,this.oldPrimitive=void 0,this.geometry=new e,this.updaters=new e,this.updatersWithAttributes=new e,this.attributes=new e,this.itemsToRemove=[],this.subscriptions=new e,this.showsUpdated=new e}function h(t,r,i){this._primitives=t,this._scene=r,this._shadows=i,this._solidBatches=new e,this._translucentBatches=new e}d.prototype.add=function(e,t){var r=e.entity.id;if(this.createPrimitive=!0,this.geometry.set(r,t),this.updaters.set(r,e),e.hasConstantOutline&&e.outlineColorProperty.isConstant&&c.isConstant(e.distanceDisplayConditionProperty)){var i=this;this.subscriptions.set(r,e.entity.definitionChanged.addEventListener(function(t,r,n,o){"isShowing"===r&&i.showsUpdated.set(t.id,e)}))}else this.updatersWithAttributes.set(r,e)},d.prototype.remove=function(e){var t=e.entity.id;if(this.createPrimitive=this.geometry.remove(t)||this.createPrimitive,this.updaters.remove(t)){this.updatersWithAttributes.remove(t);var r=this.subscriptions.get(t);i(r)&&(r(),this.subscriptions.remove(t))}};var p=new t,f=new n;return d.prototype.update=function(e){var u,d,h=!0,m=0,g=this.primitive,_=this.primitives;if(this.createPrimitive){var v=this.geometry.values,y=v.length;if(y>0){for(i(g)&&(i(this.oldPrimitive)?_.remove(g):this.oldPrimitive=g),d=0;d<y;d++){var b=v[d],C=b.attributes;u=this.attributes.get(b.id.id),i(u)&&(i(C.show)&&(C.show.value=u.show),i(C.color)&&(C.color.value=u.color))}g=new l({asynchronous:!0,geometryInstances:v,appearance:new s({flat:!0,translucent:this.translucent,renderState:{lineWidth:this.width}}),shadows:this.shadows}),_.add(g),h=!1}else{i(g)&&(_.remove(g),g=void 0);var S=this.oldPrimitive;i(S)&&(_.remove(S),this.oldPrimitive=void 0)}this.attributes.removeAll(),this.primitive=g,this.createPrimitive=!1,this.waitingOnCreate=!0}else if(i(g)&&g.ready){i(this.oldPrimitive)&&(_.remove(this.oldPrimitive),this.oldPrimitive=void 0);var w=this.updatersWithAttributes.values,T=w.length,E=this.waitingOnCreate;for(d=0;d<T;d++){var A=w[d],x=this.geometry.get(A.entity.id);if(u=this.attributes.get(x.id.id),i(u)||(u=g.getGeometryInstanceAttributes(x.id),this.attributes.set(x.id.id,u)),!A.outlineColorProperty.isConstant||E){var P=A.outlineColorProperty;P.getValue(e,p),t.equals(u._lastColor,p)||(u._lastColor=t.clone(p,u._lastColor),u.color=r.toValue(p,u.color),(this.translucent&&255===u.color[3]||!this.translucent&&255!==u.color[3])&&(this.itemsToRemove[m++]=A))}var D=A.entity.isShowing&&(A.hasConstantOutline||A.isOutlineVisible(e)),I=1===u.show[0];D!==I&&(u.show=a.toValue(D,u.show));var O=A.distanceDisplayConditionProperty;if(!c.isConstant(O)){var M=O.getValue(e,f);n.equals(M,u._lastDistanceDisplayCondition)||(u._lastDistanceDisplayCondition=n.clone(M,u._lastDistanceDisplayCondition),u.distanceDisplayCondition=o.toValue(M,u.distanceDisplayCondition))}}this.updateShows(g),this.waitingOnCreate=!1}else i(g)&&!g.ready&&(h=!1);return this.itemsToRemove.length=m,h},d.prototype.updateShows=function(e){for(var t=this.showsUpdated.values,r=t.length,n=0;n<r;n++){var o=t[n],s=this.geometry.get(o.entity.id),l=this.attributes.get(s.id.id);i(l)||(l=e.getGeometryInstanceAttributes(s.id),this.attributes.set(s.id.id,l));var u=o.entity.isShowing;u!==(1===l.show[0])&&(l.show=a.toValue(u,l.show))}this.showsUpdated.removeAll()},d.prototype.contains=function(e){return this.updaters.contains(e.id)},d.prototype.getBoundingSphere=function(e,t){var r=this.primitive;if(!r.ready)return u.PENDING;var n=r.getGeometryInstanceAttributes(e);return!i(n)||!i(n.boundingSphere)||i(n.show)&&0===n.show[0]?u.FAILED:(n.boundingSphere.clone(t),u.DONE)},d.prototype.removeAllPrimitives=function(){var e=this.primitives,t=this.primitive;i(t)&&(e.remove(t),this.primitive=void 0,this.geometry.removeAll(),this.updaters.removeAll());var r=this.oldPrimitive;i(r)&&(e.remove(r),this.oldPrimitive=void 0)},h.prototype.add=function(e,t){ +var r,n,o=t.createOutlineGeometryInstance(e),a=this._scene.clampLineWidth(t.outlineWidth);255===o.attributes.color.value[3]?(r=this._solidBatches,n=r.get(a),i(n)||(n=new d(this._primitives,!1,a,this._shadows),r.set(a,n)),n.add(t,o)):(r=this._translucentBatches,n=r.get(a),i(n)||(n=new d(this._primitives,!0,a,this._shadows),r.set(a,n)),n.add(t,o))},h.prototype.remove=function(e){var t,r=this._solidBatches.values,i=r.length;for(t=0;t<i;t++)if(r[t].remove(e))return;var n=this._translucentBatches.values,o=n.length;for(t=0;t<o;t++)if(n[t].remove(e))return},h.prototype.update=function(e){var t,r,i,n,o,a=this._solidBatches.values,s=a.length,l=this._translucentBatches.values,u=l.length,c=!0,d=!1;do{for(d=!1,r=0;r<s;r++){n=a[r],c=n.update(e),o=n.itemsToRemove;var h=o.length;if(h>0)for(d=!0,t=0;t<h;t++)i=o[t],n.remove(i),this.add(e,i)}for(r=0;r<u;r++){n=l[r],c=n.update(e),o=n.itemsToRemove;var p=o.length;if(p>0)for(d=!0,t=0;t<p;t++)i=o[t],n.remove(i),this.add(e,i)}}while(d);return c},h.prototype.getBoundingSphere=function(e,t){var r,i=this._solidBatches.values,n=i.length;for(r=0;r<n;r++){var o=i[r];if(o.contains(e))return o.getBoundingSphere(e,t)}var a=this._translucentBatches.values,s=a.length;for(r=0;r<s;r++){var l=a[r];if(l.contains(e))return l.getBoundingSphere(e,t)}return u.FAILED},h.prototype.removeAllPrimitives=function(){var e,t=this._solidBatches.values,r=t.length;for(e=0;e<r;e++)t[e].removeAllPrimitives();var i=this._translucentBatches.values,n=i.length;for(e=0;e<n;e++)i[e].removeAllPrimitives()},h}),define("DataSources/GeometryVisualizer",["../Core/AssociativeArray","../Core/BoundingSphere","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Scene/ShadowMode","./BoundingSphereState","./ColorMaterialProperty","./StaticGeometryColorBatch","./StaticGeometryPerMaterialBatch","./StaticGroundGeometryColorBatch","./StaticOutlineGeometryBatch"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t,r){this._primitives=t,this._groundPrimitives=r,this._dynamicUpdaters=new e}function p(e,t){for(var r=e._batches,i=r.length,n=0;n<i;n++)r[n].remove(t)}function f(e,t,i){if(i.isDynamic)return void e._dynamicBatch.add(t,i);var n;(i.outlineEnabled||i.fillEnabled)&&(n=i.shadowsProperty.getValue(t)),i.outlineEnabled&&e._outlineBatches[n].add(t,i);var a=0;r(i.depthFailMaterialProperty)&&(a=i.depthFailMaterialProperty instanceof s?1:2);var l;r(n)&&(l=n+a*o.NUMBER_OF_SHADOW_MODES),i.fillEnabled&&(i.onTerrain?e._groundColorBatch.add(t,i):i.isClosed?i.fillMaterialProperty instanceof s?e._closedColorBatches[l].add(t,i):e._closedMaterialBatches[l].add(t,i):i.fillMaterialProperty instanceof s?e._openColorBatches[l].add(t,i):e._openMaterialBatches[l].add(t,i))}function m(t,r,i){this._type=t;var n=r.primitives,a=r.groundPrimitives;this._scene=r,this._primitives=n,this._groundPrimitives=a,this._entityCollection=void 0,this._addedObjects=new e,this._removedObjects=new e,this._changedObjects=new e;var s=o.NUMBER_OF_SHADOW_MODES;this._outlineBatches=new Array(s),this._closedColorBatches=new Array(3*s),this._closedMaterialBatches=new Array(3*s),this._openColorBatches=new Array(3*s),this._openMaterialBatches=new Array(3*s);for(var p=0;p<s;++p)this._outlineBatches[p]=new d(n,r,p),this._closedColorBatches[p]=new l(n,t.perInstanceColorAppearanceType,void 0,!0,p),this._closedMaterialBatches[p]=new u(n,t.materialAppearanceType,void 0,!0,p),this._openColorBatches[p]=new l(n,t.perInstanceColorAppearanceType,void 0,!1,p),this._openMaterialBatches[p]=new u(n,t.materialAppearanceType,void 0,!1,p),this._closedColorBatches[p+s]=new l(n,t.perInstanceColorAppearanceType,t.perInstanceColorAppearanceType,!0,p),this._closedMaterialBatches[p+s]=new u(n,t.materialAppearanceType,t.perInstanceColorAppearanceType,!0,p),this._openColorBatches[p+s]=new l(n,t.perInstanceColorAppearanceType,t.perInstanceColorAppearanceType,!1,p),this._openMaterialBatches[p+s]=new u(n,t.materialAppearanceType,t.perInstanceColorAppearanceType,!1,p),this._closedColorBatches[p+2*s]=new l(n,t.perInstanceColorAppearanceType,t.materialAppearanceType,!0,p),this._closedMaterialBatches[p+2*s]=new u(n,t.materialAppearanceType,t.materialAppearanceType,!0,p),this._openColorBatches[p+2*s]=new l(n,t.perInstanceColorAppearanceType,t.materialAppearanceType,!1,p),this._openMaterialBatches[p+2*s]=new u(n,t.materialAppearanceType,t.materialAppearanceType,!1,p);this._groundColorBatch=new c(a),this._dynamicBatch=new h(n,a),this._batches=this._outlineBatches.concat(this._closedColorBatches,this._closedMaterialBatches,this._openColorBatches,this._openMaterialBatches,this._groundColorBatch,this._dynamicBatch),this._subscriptions=new e,this._updaters=new e,this._entityCollection=i,i.collectionChanged.addEventListener(m.prototype._onCollectionChanged,this),this._onCollectionChanged(i,i.values,g)}var g=[];h.prototype.add=function(e,t){this._dynamicUpdaters.set(t.entity.id,t.createDynamicUpdater(this._primitives,this._groundPrimitives))},h.prototype.remove=function(e){var t=e.entity.id,i=this._dynamicUpdaters.get(t);r(i)&&(this._dynamicUpdaters.remove(t),i.destroy())},h.prototype.update=function(e){for(var t=this._dynamicUpdaters.values,r=0,i=t.length;r<i;r++)t[r].update(e);return!0},h.prototype.removeAllPrimitives=function(){for(var e=this._dynamicUpdaters.values,t=0,r=e.length;t<r;t++)e[t].destroy();this._dynamicUpdaters.removeAll()},h.prototype.getBoundingSphere=function(e,t){var i=this._dynamicUpdaters.get(e.id);return r(i)&&r(i.getBoundingSphere)?i.getBoundingSphere(e,t):a.FAILED},m.prototype.update=function(e){var t,r,i,n,o=this._addedObjects,a=o.values,s=this._removedObjects,l=s.values,u=this._changedObjects,c=u.values;for(t=c.length-1;t>-1;t--)r=c[t],i=r.id,n=this._updaters.get(i),n.entity===r?(p(this,n),f(this,e,n)):(l.push(r),a.push(r));for(t=l.length-1;t>-1;t--)r=l[t],i=r.id,n=this._updaters.get(i),p(this,n),n.destroy(),this._updaters.remove(i),this._subscriptions.get(i)(),this._subscriptions.remove(i);for(t=a.length-1;t>-1;t--)r=a[t],i=r.id,n=new this._type(r,this._scene),this._updaters.set(i,n),f(this,e,n),this._subscriptions.set(i,n.geometryChanged.addEventListener(m._onGeometryChanged,this));o.removeAll(),s.removeAll(),u.removeAll();var d=!0,h=this._batches,g=h.length;for(t=0;t<g;t++)d=h[t].update(e)&&d;return d};var _=[],v=new t;return m.prototype.getBoundingSphere=function(e,r){for(var i=_,n=v,o=0,s=a.DONE,l=this._batches,u=l.length,c=0;c<u;c++){if((s=l[c].getBoundingSphere(e,n))===a.PENDING)return a.PENDING;s===a.DONE&&(i[o]=t.clone(n,i[o]),o++)}return 0===o?a.FAILED:(i.length=o,t.fromBoundingSpheres(i,r),a.DONE)},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(m.prototype._onCollectionChanged,this),this._addedObjects.removeAll(),this._removedObjects.removeAll();var e,t=this._batches,r=t.length;for(e=0;e<r;e++)t[e].removeAllPrimitives();var n=this._subscriptions.values;for(r=n.length,e=0;e<r;e++)n[e]();return this._subscriptions.removeAll(),i(this)},m._onGeometryChanged=function(e){var t=this._removedObjects,i=this._changedObjects,n=e.entity,o=n.id;r(t.get(o))||r(i.get(o))||i.set(o,n)},m.prototype._onCollectionChanged=function(e,t,r){var i,n,o,a=this._addedObjects,s=this._removedObjects,l=this._changedObjects;for(i=r.length-1;i>-1;i--)o=r[i],n=o.id,a.remove(n)||(s.set(n,o),l.remove(n));for(i=t.length-1;i>-1;i--)o=t[i],n=o.id,s.remove(n)?l.set(n,o):a.set(n,o)},m}),define("DataSources/LabelVisualizer",["../Core/AssociativeArray","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/NearFarScalar","../Scene/HeightReference","../Scene/HorizontalOrigin","../Scene/LabelStyle","../Scene/VerticalOrigin","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e){this.entity=e,this.label=void 0,this.index=void 0}function _(t,r){r.collectionChanged.addEventListener(_.prototype._onCollectionChanged,this),this._cluster=t,this._entityCollection=r,this._items=new e,this._onCollectionChanged(r,r.values,[],[])}function v(e,t,r){o(e)&&(e.label=void 0,r.removeLabel(t))}var y=h.FILL,b=i.WHITE,C=i.BLACK,S=new i(.165,.165,.165,.8),w=new t(7,5),T=t.ZERO,E=r.ZERO,A=c.NONE,x=d.CENTER,P=p.CENTER,D=new r,I=new i,O=new i,M=new i,R=new t,L=new r,N=new t,k=new u,F=new u,B=new u,U=new l;return _.prototype.update=function(e){for(var t=this._items.values,r=this._cluster,i=0,n=t.length;i<n;i++){var a,s=t[i],l=s.entity,u=l._label,c=s.label,d=l.isShowing&&l.isAvailable(e)&&m.getValueOrDefault(u._show,e,!0);d&&(D=m.getValueOrUndefined(l._position,e,D),a=m.getValueOrUndefined(u._text,e),d=o(D)&&o(a)),d?(m.isConstant(l._position)||(r._clusterDirty=!0),o(c)||(c=r.getLabel(l),c.id=l,s.label=c),c.show=!0,c.position=D,c.text=a,c.scale=m.getValueOrDefault(u._scale,e,1),c.font=m.getValueOrDefault(u._font,e,"30px sans-serif"),c.style=m.getValueOrDefault(u._style,e,y),c.fillColor=m.getValueOrDefault(u._fillColor,e,b,I),c.outlineColor=m.getValueOrDefault(u._outlineColor,e,C,O),c.outlineWidth=m.getValueOrDefault(u._outlineWidth,e,1),c.showBackground=m.getValueOrDefault(u._showBackground,e,!1),c.backgroundColor=m.getValueOrDefault(u._backgroundColor,e,S,M),c.backgroundPadding=m.getValueOrDefault(u._backgroundPadding,e,w,R),c.pixelOffset=m.getValueOrDefault(u._pixelOffset,e,T,N),c.eyeOffset=m.getValueOrDefault(u._eyeOffset,e,E,L),c.heightReference=m.getValueOrDefault(u._heightReference,e,A),c.horizontalOrigin=m.getValueOrDefault(u._horizontalOrigin,e,x),c.verticalOrigin=m.getValueOrDefault(u._verticalOrigin,e,P),c.translucencyByDistance=m.getValueOrUndefined(u._translucencyByDistance,e,k),c.pixelOffsetScaleByDistance=m.getValueOrUndefined(u._pixelOffsetScaleByDistance,e,F),c.scaleByDistance=m.getValueOrUndefined(u._scaleByDistance,e,B),c.distanceDisplayCondition=m.getValueOrUndefined(u._distanceDisplayCondition,e,U),c.disableDepthTestDistance=m.getValueOrDefault(u._disableDepthTestDistance,e,0)):v(s,l,r)}return!0},_.prototype.getBoundingSphere=function(e,t){var i=this._items.get(e.id);if(!o(i)||!o(i.label))return f.FAILED;var a=i.label;return t.center=r.clone(n(a._clampedPosition,a.position),t.center),t.radius=0,f.DONE},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(_.prototype._onCollectionChanged,this);for(var e=this._entityCollection.values,t=0;t<e.length;t++)this._cluster.removeLabel(e[t]);return a(this)},_.prototype._onCollectionChanged=function(e,t,r,i){var n,a,s=this._items,l=this._cluster;for(n=t.length-1;n>-1;n--)a=t[n],o(a._label)&&o(a._position)&&s.set(a.id,new g(a));for(n=i.length-1;n>-1;n--)a=i[n],o(a._label)&&o(a._position)?s.contains(a.id)||s.set(a.id,new g(a)):(v(s.get(a.id),a,l),s.remove(a.id));for(n=r.length-1;n>-1;n--)a=r[n],v(s.get(a.id),a,l),s.remove(a.id)},_}),define("ThirdParty/GltfPipeline/addToArray",[],function(){"use strict";function e(e,t){return e.push(t),e.length-1}return e}),define("ThirdParty/GltfPipeline/ForEach",["../../Core/defined"],function(e){"use strict";var t={};return t.object=function(t,r){if(e(t))for(var i=0;i<t.length;i++){var n=t[i],o=r(n,i);if("number"==typeof o)i+=o;else if(o)break}},t.topLevel=function(e,r,i){var n=e[r];t.object(n,i)},t.accessor=function(e,r){t.topLevel(e,"accessors",r)},t.accessorWithSemantic=function(e,r,i){t.mesh(e,function(e){t.meshPrimitive(e,function(e){t.meshPrimitiveAttribute(e,function(t,n){0===n.indexOf(r)&&i(t,n,e)})})})},t.animation=function(e,r){t.topLevel(e,"animations",r)},t.animationSampler=function(r,i){var n=r.samplers;e(n)&&t.object(n,i)},t.buffer=function(e,r){t.topLevel(e,"buffers",r)},t.bufferView=function(e,r){t.topLevel(e,"bufferViews",r)},t.camera=function(e,r){t.topLevel(e,"cameras",r)},t.image=function(e,r){t.topLevel(e,"images",r)},t.material=function(e,r){t.topLevel(e,"materials",r)},t.materialValue=function(t,r){var i=t.values;if(e(i))for(var n in i)i.hasOwnProperty(n)&&r(i[n],n)},t.mesh=function(e,r){t.topLevel(e,"meshes",r)},t.meshPrimitive=function(t,r){var i=t.primitives;if(e(i))for(var n=i.length,o=0;o<n;o++){var a=i[o];r(a,o)}},t.meshPrimitiveAttribute=function(t,r){var i=t.attributes;if(e(i))for(var n in i)i.hasOwnProperty(n)&&r(i[n],n)},t.meshPrimitiveTargetAttribute=function(t,r){var i=t.targets;if(e(i))for(var n in i)if(i.hasOwnProperty(n)){var o=i[n];for(var a in o)o.hasOwnProperty(a)&&"extras"!==a&&r(o[a],a)}},t.node=function(e,r){t.topLevel(e,"nodes",r)},t.nodeInTree=function(r,i,n){var o=r.nodes;if(e(o))for(var a=0;a<i.length;a++){var s=i[a],l=o[s];if(e(l)){n(l,s);var u=l.children;e(u)&&t.nodeInTree(r,u,n)}}},t.nodeInScene=function(r,i,n){var o=i.nodes;e(o)&&t.nodeInTree(r,o,n)},t.program=function(e,r){t.topLevel(e,"programs",r)},t.sampler=function(e,r){t.topLevel(e,"samplers",r)},t.scene=function(e,r){t.topLevel(e,"scenes",r)},t.shader=function(e,r){t.topLevel(e,"shaders",r)},t.skin=function(e,r){t.topLevel(e,"skins",r)},t.techniqueAttribute=function(t,r){var i=t.attributes;if(e(i))for(var n in i)if(i.hasOwnProperty(n)&&r(i[n],n))break},t.techniqueParameter=function(t,r){var i=t.parameters;if(e(i))for(var n in i)if(i.hasOwnProperty(n)&&r(i[n],n))break},t.technique=function(e,r){t.topLevel(e,"techniques",r)},t.texture=function(e,r){t.topLevel(e,"textures",r)},t}),define("ThirdParty/GltfPipeline/addDefaults",["./addToArray","./ForEach","../../Core/clone","../../Core/defaultValue","../../Core/defined","../../Core/WebGLConstants"],function(e,t,r,i,n,o){"use strict";function a(e,t){for(var r in t)if(t.hasOwnProperty(r)){var o=t[r];if("function"==typeof o&&(o=o(e)),n(o))if("object"==typeof o)if(Array.isArray(o)){var s=i(e[r],[]);if(o.length>0){var l=o[0];if("object"==typeof l)for(var u=s.length,c=0;c<u;c++)a(s[c],l);else s=i(e[r],o)}e[r]=s}else{var d=o["*"];e[r]=i(e[r],{});var h=e[r];if(n(d)){for(var p in h)if(h.hasOwnProperty(p)&&"extras"!==p){var f=h[p];a(f,d)}}else a(h,o)}else e[r]=i(e[r],o)}}function s(t){for(var i,o=t.materials,a=t.meshes,s=a.length,l=0;l<s;l++)for(var u=a[l],c=u.primitives,d=c.length,h=0;h<d;h++){var p=c[h];n(p.material)||(n(i)||(i=e(o,r(m,!0))),p.material=i)}}function l(t){for(var o,a=t.materials,s=t.techniques,l=t.programs,u=t.shaders,c=a.length,d=0;d<c;d++){var h=a[d],p=h.technique,f=i(h.extensions,{}),m=f.KHR_materials_common;if(!n(p)){if(!n(o)&&!n(m)){var b=r(g,!0);o=e(s,b);var C=r(_,!0);b.program=e(l,C);var S=r(v,!0);C.vertexShader=e(u,S);var w=r(y,!0);C.fragmentShader=e(u,w)}h.technique=o}}}function u(e){for(var t=e.accessors,r=t.length,i=0;i<r;i++){var o=t[i];n(o.byteOffset)||(o.byteOffset=0)}for(var a=e.bufferViews,s=a.length,l=0;l<s;l++){var u=a[l];n(u.byteOffset)||(u.byteOffset=0)}}function c(e){n(e.scenes)&&!n(e.scene)&&(e.scene=0)}function d(e){for(var t=e.techniques,r=t.length,i=0;i<r;i++){var o=t[i],a=o.parameters;n(a.diffuse)&&(a.diffuse.semantic="_3DTILESDIFFUSE")}}function h(e){var r={},i=0;if(t.bufferView(e,function(e,t){n(e.target)||(r[t]=!0,i++)}),i>0){var a=e.accessors,s=e.bufferViews;t.mesh(e,function(e){if(t.meshPrimitive(e,function(e){var l=e.indices;if(n(l)){var u=a[l],c=u.bufferView;if(r[c]){var d=s[c];n(d)&&(d.target=o.ELEMENT_ARRAY_BUFFER,r[c]=!1,i--)}}t.meshPrimitiveAttribute(e,function(e){var t=a[e],l=t.bufferView;if(r[l]){var u=s[l];n(u)&&(u.target=o.ARRAY_BUFFER,r[l]=!1,i--)}}),t.meshPrimitiveTargetAttribute(e,function(e){var t=a[e].bufferView;if(r[t]){var l=s[t];n(l)&&(l.target=o.ARRAY_BUFFER,r[t]=!1,i--)}})}),0===i)return!0})}}function p(e,t){return t=i(t,{}),a(e,f),s(e),l(e),u(e),c(e),h(e),t.optimizeForCesium&&d(e),e}var f={accessors:[],animations:[{channels:[],samplers:[{interpolation:"LINEAR"}]}],asset:{},buffers:[{byteLength:0,type:"arraybuffer"}],bufferViews:[{byteLength:0}],cameras:[],images:[],materials:[{values:function(e){var t=i(e.extensions,{}),r=t.KHR_materials_common;if(!n(r))return{}},extensions:function(e){var t=i(e.extensions,{}),r=t.KHR_materials_common;if(n(r)){var o=r.technique,a={ambient:[0,0,0,1],emission:[0,0,0,1],transparency:1};return"CONSTANT"!==o&&(a.diffuse=[0,0,0,1],"LAMBERT"!==o&&(a.specular=[0,0,0,1],a.shininess=0)),{KHR_materials_common:{doubleSided:!1,transparent:!1,values:a}}}}}],meshes:[{primitives:[{attributes:{},mode:o.TRIANGLES}]}],nodes:[{children:[],matrix:function(e){if(!n(e.translation)&&!n(e.rotation)&&!n(e.scale))return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},rotation:function(e){if(n(e.translation)||n(e.scale))return[0,0,0,1]},scale:function(e){if(n(e.translation)||n(e.rotation))return[1,1,1]},translation:function(e){if(n(e.rotation)||n(e.scale))return[0,0,0]}}],programs:[{attributes:[]}],samplers:[{magFilter:o.LINEAR,minFilter:o.NEAREST_MIPMAP_LINEAR,wrapS:o.REPEAT,wrapT:o.REPEAT}],scenes:[{nodes:[]}],shaders:[],skins:[{bindShapeMatrix:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}],techniques:[{parameters:{},attributes:{},uniforms:{},states:{enable:[]}}],textures:[{format:o.RGBA,internalFormat:o.RGBA,target:o.TEXTURE_2D,type:o.UNSIGNED_BYTE}],extensionsUsed:[],extensionsRequired:[]},m={values:{emission:[.5,.5,.5,1]},extras:{_pipeline:{}}},g={attributes:{a_position:"position"},parameters:{modelViewMatrix:{semantic:"MODELVIEW",type:o.FLOAT_MAT4},projectionMatrix:{semantic:"PROJECTION",type:o.FLOAT_MAT4},emission:{type:o.FLOAT_VEC4,value:[.5,.5,.5,1]},position:{semantic:"POSITION",type:o.FLOAT_VEC3}},states:{enable:[o.CULL_FACE,o.DEPTH_TEST]},uniforms:{u_modelViewMatrix:"modelViewMatrix",u_projectionMatrix:"projectionMatrix",u_emission:"emission"}},_={attributes:["a_position"]},v={type:o.VERTEX_SHADER,extras:{_pipeline:{extension:".vert",source:"precision highp float;\n\nuniform mat4 u_modelViewMatrix;\nuniform mat4 u_projectionMatrix;\n\nattribute vec3 a_position;\n\nvoid main (void)\n{\n gl_Position = u_projectionMatrix * u_modelViewMatrix * vec4(a_position, 1.0);\n}\n"}}},y={type:o.FRAGMENT_SHADER,extras:{_pipeline:{extension:".frag",source:"precision highp float;\n\nuniform vec4 u_emission;\n\nvoid main(void)\n{\n gl_FragColor = u_emission;\n}\n"}}};return p}),define("ThirdParty/GltfPipeline/addPipelineExtras",["../../Core/defaultValue","../../Core/defined"],function(e,t){"use strict";function r(r){var n=[];for(var o in r)if(r.hasOwnProperty(o))for(var a=r[o],s=a.length,l=0;l<s;l++){var u=a[l];t(u)&&"object"==typeof u&&(u.extras=e(u.extras,{}),u.extras._pipeline=e(u.extras._pipeline,{}),n.push(u))}for(;n.length>0;){var c=n.pop();for(var d in c)if(c.hasOwnProperty(d)){var h=c[d];t(h)&&"object"==typeof h&&"extras"!==d&&(n.push(h),i[d]||Array.isArray(h)||(h.extras=e(h.extras,{}),h.extras._pipeline=e(h.extras._pipeline,{})))}}return r.extras=e(r.extras,{}),r.extras._pipeline=e(r.extras._pipeline,{}),r.asset=e(r.asset,{}),r.asset.extras=e(r.asset.extras,{}),t(r.asset.extras)&&"object"!=typeof r.asset.extras&&(r.asset.extras={extras:r.asset.extras}),r.asset.extras._pipeline=e(r.asset.extras._pipeline,{}),r}var i={attributes:!0,uniforms:!0,extensions:!0,values:!0,samplers:!0};return r}),define("ThirdParty/GltfPipeline/byteLengthForComponentType",["../../Core/WebGLConstants"],function(e){"use strict";function t(t){switch(t){case e.BYTE:case e.UNSIGNED_BYTE:return 1;case e.SHORT:case e.UNSIGNED_SHORT:return 2;case e.FLOAT:case e.UNSIGNED_INT:return 4}}return t}),define("ThirdParty/GltfPipeline/numberOfComponentsForType",[],function(){"use strict";function e(e){switch(e){case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":case"MAT2":return 4;case"MAT3":return 9;case"MAT4":return 16}}return e}),define("ThirdParty/GltfPipeline/getAccessorByteStride",["./byteLengthForComponentType","./numberOfComponentsForType","../../Core/defined"],function(e,t,r){"use strict";function i(i,n){var o=i.bufferViews[n.bufferView];return r(o.byteStride)&&o.byteStride>0?o.byteStride:e(n.componentType)*t(n.type)}return i}),define("ThirdParty/GltfPipeline/removeExtensionsRequired",["../../Core/defined"],function(e){"use strict";function t(t,r){var i=t.extensionsRequired;if(e(i)){var n=i.indexOf(r);n>=0&&i.splice(n,1),0===i.length&&delete t.extensionsRequired}}return t}),define("ThirdParty/GltfPipeline/removeExtensionsUsed",["./removeExtensionsRequired","../../Core/defined"],function(e,t){"use strict";function r(r,i){var n=r.extensionsUsed;if(t(n)){var o=n.indexOf(i);o>=0&&n.splice(o,1),e(r,i),0===n.length&&delete r.extensionsUsed}}return r}),define("ThirdParty/GltfPipeline/addExtensionsUsed",["../../Core/defined"],function(e){"use strict";function t(t,r){var i=t.extensionsUsed;e(i)||(i=[],t.extensionsUsed=i),i.indexOf(r)<0&&i.push(r)}return t}),define("ThirdParty/GltfPipeline/addExtensionsRequired",["./addExtensionsUsed","../../Core/defined"],function(e,t){"use strict";function r(r,i){var n=r.extensionsRequired;t(n)||(n=[],r.extensionsRequired=n),n.indexOf(i)<0&&n.push(i),e(r,i)}return r}),define("ThirdParty/GltfPipeline/updateVersion",["./addExtensionsRequired","./addToArray","./ForEach","./getAccessorByteStride","./numberOfComponentsForType","../../Core/Cartesian3","../../Core/Math","../../Core/clone","../../Core/ComponentDatatype","../../Core/defaultValue","../../Core/defined","../../Core/Quaternion","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e,t){t=u(t,{});var r=t.targetVersion,i=e.version;e.asset=u(e.asset,{version:"1.0"}),i=u(i,e.asset.version),F.hasOwnProperty(i)||(c(i)&&(i=(""+i).substring(0,3)),F.hasOwnProperty(i)||(i="1.0"));for(var n=F[i];c(n)&&i!==r;)n(e),i=e.asset.version,n=F[i];return e}function f(e){var t=e.materials;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r],n=i.instanceTechnique;c(n)&&(i.technique=n.technique,i.values=n.values,delete i.instanceTechnique)}}function m(e){var t=e.meshes;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r],n=i.primitives;if(c(n))for(var o=n.length,a=0;a<o;a++){var s=n[a],l=u(s.primitive,h.TRIANGLES);s.mode=u(s.mode,l),delete s.primitive}}}function g(e){var t=e.nodes,r=new o,i=new d;for(var n in t)if(t.hasOwnProperty(n)){var a=t[n];if(c(a.rotation)){var s=a.rotation;o.fromArray(s,0,r),d.fromAxisAngle(r,s[3],i),a.rotation=[i.x,i.y,i.z,i.w]}var l=a.instanceSkin;c(l)&&(a.skeletons=l.skeletons,a.skin=l.skin,a.meshes=l.meshes,delete a.instanceSkin)}}function _(e){var t=e.animations,r=e.accessors,i=e.bufferViews,a=e.buffers,s={},u=new o,h=new d;for(var p in t)if(t.hasOwnProperty(p)){var f=t[p],m=f.channels,g=f.parameters,_=f.samplers;if(c(m))for(var v=m.length,y=0;y<v;++y){var b=m[y];if("rotation"===b.target.path){var C=g[_[b.sampler].output];if(c(s[C]))continue;s[C]=!0;for(var S=r[C],w=i[S.bufferView],T=a[w.buffer],E=T.extras._pipeline.source,A=E.byteOffset+w.byteOffset+S.byteOffset,x=S.componentType,P=S.count,D=n(S.type),I=S.count*D,O=l.createArrayBufferView(x,E.buffer,A,I),M=0;M<P;M++){var R=M*D;o.unpack(O,R,u);var L=O[R+3];d.fromAxisAngle(u,L,h),d.pack(h,O,R)}}}}}function v(e){var t=e.techniques;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r],n=i.passes;if(c(n)){var o=u(i.pass,"defaultPass");if(n.hasOwnProperty(o)){var a=n[o],s=a.instanceProgram;i.attributes=u(i.attributes,s.attributes),i.program=u(i.program,s.program),i.uniforms=u(i.uniforms,s.uniforms),i.states=u(i.states,a.states)}delete i.passes,delete i.pass}}}function y(e){c(e.asset)||(e.asset={});var t=e.asset;if(t.version="1.0",c(t.profile)&&"string"!=typeof t.profile||(t.profile={}),c(e.version)&&delete e.version,f(e),m(e),g(e),_(e),v(e),c(e.lights)){var r=u(e.extensions,{});e.extensions=r;var i=u(r.KHR_materials_common,{});r.KHR_materials_common=i,i.lights=e.lights,delete e.lights}c(e.allExtensions)&&(e.extensionsUsed=e.allExtensions,e.allExtensions=void 0)}function b(e){var t=e.animations;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r],n=i.parameters;if(c(n)){var o=i.samplers;for(var a in o)if(o.hasOwnProperty(a)){var s=o[a];s.input=n[s.input],s.output=n[s.output]}delete i.parameters}}}function C(e,t){var r=[];for(var i in e)if(e.hasOwnProperty(i)){var n=e[i];t[i]=r.length,r.push(n),c(n.name)||"object"!=typeof n||(n.name=i)}return r}function S(e){var i,n,o={accessors:{},animations:{},bufferViews:{},buffers:{},cameras:{},materials:{},meshes:{},nodes:{},programs:{},shaders:{},skins:{},techniques:{}},a={},s=e.nodes;for(var l in s)s.hasOwnProperty(l)&&(n=s[l].jointName,c(n)&&(a[n]=l));for(var u in e)if(e.hasOwnProperty(u)&&"extras"!==u&&"asset"!==u&&"extensions"!==u){var d={},h=e[u];"object"!=typeof h||Array.isArray(h)||(e[u]=C(h,d),o[u]=d,"animations"===u&&(d={},h.samplers=C(h.samplers,d),o[u].samplers=d))}for(n in a)a.hasOwnProperty(n)&&(a[n]=o.nodes[a[n]]);c(e.scene)&&(e.scene=o.scenes[e.scene]),r.bufferView(e,function(e){c(e.buffer)&&(e.buffer=o.buffers[e.buffer])}),r.accessor(e,function(e){c(e.bufferView)&&(e.bufferView=o.bufferViews[e.bufferView])}),r.shader(e,function(e){var t=e.extensions;if(c(t)){var r=t.KHR_binary_glTF;c(r)&&(e.bufferView=o.bufferViews[r.bufferView],delete t.KHR_binary_glTF),0===Object.keys(t).length&&delete e.extensions}}),r.program(e,function(e){c(e.vertexShader)&&(e.vertexShader=o.shaders[e.vertexShader]),c(e.fragmentShader)&&(e.fragmentShader=o.shaders[e.fragmentShader])}),r.technique(e,function(e){c(e.program)&&(e.program=o.programs[e.program]),r.techniqueParameter(e,function(e){c(e.node)&&(e.node=o.nodes[e.node]);var t=e.value;if(c(t))if(Array.isArray(t)){if(1===t.length){var r=t[0];"string"==typeof r&&(t[0]=o.textures[r])}}else"string"==typeof t&&(e.value=[o.textures[t]])})}),r.mesh(e,function(e){r.meshPrimitive(e,function(e){c(e.indices)&&(e.indices=o.accessors[e.indices]),r.meshPrimitiveAttribute(e,function(t,r){e.attributes[r]=o.accessors[t]}),c(e.material)&&(e.material=o.materials[e.material])})}),r.node(e,function(r){var n=r.children;if(c(n)){var a=n.length;for(i=0;i<a;i++)n[i]=o.nodes[n[i]]}if(c(r.meshes)){var s=r.meshes,l=s.length;if(l>0)for(r.mesh=o.meshes[s[0]],i=1;i<l;i++){var u={mesh:o.meshes[s[i]],extras:{_pipeline:{}}},d=t(e.nodes,u);c(n)||(n=[],r.children=n),n.push(d)}delete r.meshes}if(c(r.camera)&&(r.camera=o.cameras[r.camera]),c(r.skeletons)){var h=r.skeletons;if(h.length>0&&c(r.skin)){e.skins[o.skins[r.skin]].skeleton=o.nodes[h[0]]}delete r.skeletons}c(r.skin)&&(r.skin=o.skins[r.skin]),c(r.jointName)&&delete r.jointName}),r.skin(e,function(e){c(e.inverseBindMatrices)&&(e.inverseBindMatrices=o.accessors[e.inverseBindMatrices]);var t=[],r=e.jointNames;if(c(r)){for(i=0;i<r.length;i++)t[i]=a[r[i]];e.joints=t,delete e.jointNames}}),r.scene(e,function(e){var t=e.nodes;if(c(t)){var r=t.length;for(i=0;i<r;i++)t[i]=o.nodes[t[i]]}}),r.animation(e,function(e){var t={};e.samplers=C(e.samplers,t),r.animationSampler(e,function(e){e.input=o.accessors[e.input],e.output=o.accessors[e.output]});var n=e.channels;if(c(n)){var a=n.length;for(i=0;i<a;i++){var s=n[i];s.sampler=t[s.sampler];var l=s.target;c(l)&&(l.node=o.nodes[l.id],delete l.id)}}}),r.material(e,function(e){c(e.technique)&&(e.technique=o.techniques[e.technique]),r.materialValue(e,function(t,r){if(Array.isArray(t)){if(1===t.length){var i=t[0];"string"==typeof i&&(t[0]=o.textures[i])}}else"string"==typeof t&&(e.values[r]={index:o.textures[t]})});var t=e.extensions;if(c(t)){var i=t.KHR_materials_common;c(i)&&r.materialValue(i,function(e,t){if(Array.isArray(e)){if(1===e.length){var r=e[0];"string"==typeof r&&(e[0]=o.textures[r])}}else"string"==typeof e&&(i.values[t]={index:o.textures[e]})})}}),r.image(e,function(e){var t=e.extensions;if(c(t)){var r=t.KHR_binary_glTF;c(r)&&(e.bufferView=o.bufferViews[r.bufferView],e.mimeType=r.mimeType,delete t.KHR_binary_glTF),0===Object.keys(t).length&&delete e.extensions}if(c(e.extras)){var i=e.extras.compressedImage3DTiles;for(var n in i)if(i.hasOwnProperty(n)){var a=i[n],s=a.extensions;if(c(s)){var l=s.KHR_binary_glTF;c(l)&&(a.bufferView=o.bufferViews[l.bufferView],a.mimeType=l.mimeType,delete s.KHR_binary_glTF),0===Object.keys(s).length&&delete a.extensions}}}}),r.texture(e,function(e){c(e.sampler)&&(e.sampler=o.samplers[e.sampler]),c(e.source)&&(e.source=o.images[e.source])})}function w(e){delete e.asset.profile}function T(e){var t=e.extensionsUsed;if(e.extensionsRequired=u(e.extensionsRequired,[]),c(t))for(var r=t.length,i=0;i<r;i++){var n=t[i];c(B[n])&&e.extensionsRequired.push(n)}}function E(e){r.buffer(e,function(e){delete e.type})}function A(e){r.mesh(e,function(e){r.meshPrimitive(e,function(e){r.meshPrimitiveAttribute(e,function(t,r){"TEXCOORD"===r?e.attributes.TEXCOORD_0=t:"COLOR"===r&&(e.attributes.COLOR_0=t)}),delete e.attributes.TEXCOORD,delete e.attributes.COLOR})}),r.technique(e,function(e){r.techniqueParameter(e,function(e){var t=e.semantic;c(t)&&("TEXCOORD"===t?e.semantic="TEXCOORD_0":"COLOR"===t&&(e.semantic="COLOR_0"))})})}function x(e){var t={};r.mesh(e,function(e){r.meshPrimitive(e,function(e){r.meshPrimitiveAttribute(e,function(e,r){if("_"!==r.charAt(0)){var i=r.search(/_[0-9]+/g),n=r;if(i>=0&&(n=r.substring(0,i)),!c(U[n])){var o="_"+r;t[r]=o}}});for(var i in t)if(t.hasOwnProperty(i)){var n=t[i],o=e.attributes[i];c(o)&&(delete e.attributes[i],e.attributes[n]=o)}})}),r.technique(e,function(e){r.techniqueParameter(e,function(e){var r=t[e.semantic];c(r)&&(e.semantic=r)})})}function P(e){r.technique(e,function(e){var t=e.states;if(c(t)){var r=t.functions;c(r)&&delete r.scissor;var i=t.enable;if(c(i)){var n=i.indexOf(h.SCISSOR_TEST);n>=0&&i.splice(n,1)}}})}function D(e){r.technique(e,function(e){var t=e.states;if(c(t)){var r=t.functions;if(c(r)){var i=r.blendColor;if(c(i))for(var n=0;n<4;n++)i[n]=a.clamp(i[n],0,1);var o=r.depthRange;c(o)&&(o[1]=a.clamp(o[1],0,1),o[0]=a.clamp(o[0],0,o[1]))}}})}function I(e){r.camera(e,function(e){var t=e.perspective;if(c(t)){var r=t.aspectRatio;c(r)&&0===r&&delete t.aspectRatio;var i=t.yfov;c(i)&&0===i&&(t.yfov=1)}})}function O(e){r.buffer(e,function(e){c(e.byteLength)||(e.byteLength=e.extras._pipeline.source.length)}),r.bufferView(e,function(t){if(!c(t.byteLength)){var r=t.buffer,i=e.buffers[r];t.byteLength=i.byteLength}})}function M(e){var n=e.bufferViews,o={};r.accessor(e,function(r){var a=r.bufferView;if(c(a)){c(o[a])||(o[a]=!0);var l=s(n[a]),u=c(r.byteStride)&&0!==r.byteStride?r.byteStride:i(e,r);c(u)&&(l.byteStride=u,0!==l.byteStride&&(l.byteLength=r.count*u),l.byteOffset+=r.byteOffset,r.byteOffset=0,delete r.byteStride),r.bufferView=t(n,l)}});var a={},l=0;r.bufferView(e,function(e,t){c(o[t])?l++:a[t]=t-l});var u=0;for(var d in o)if(c(d)){var h=parseInt(d)-u;n.splice(h,1),u++}r.accessor(e,function(e){var t=e.bufferView;c(t)&&(e.bufferView=a[t])}),r.shader(e,function(e){var t=e.bufferView;c(t)&&(e.bufferView=a[t])}),r.image(e,function(e){var t=e.bufferView;if(c(t)&&(e.bufferView=a[t]),c(e.extras)){var r=e.extras.compressedImage3DTiles;for(var i in r)if(r.hasOwnProperty(i)){var n=r[i],o=n.bufferView;c(o)&&(n.bufferView=a[o])}}})}function R(e){r.technique(e,function(e){r.techniqueAttribute(e,function(t){var r=e.parameters[t];c(r.value)&&delete r.value})})}function L(e){r.technique(e,function(e){r.techniqueParameter(e,function(e){if(c(e.count)){var t=e.semantic;(!c(t)||"JOINTMATRIX"!==t&&0!==t.indexOf("_"))&&delete e.count}})})}function N(t){var r=t.techniques;c(r)&&r.length>0&&e(t,"KHR_technique_webgl")}function k(e){c(e.asset)||(e.asset={}),e.asset.version="2.0",f(e),b(e),S(e),w(e),T(e),O(e),M(e),E(e),A(e),x(e),P(e),D(e),I(e),R(e),L(e),N(e)}var F={.8:y,"1.0":k,"2.0":void 0},B={CESIUM_RTC:!0,KHR_materials_common:!0,WEB3D_quantized_attributes:!0},U={POSITION:!0,NORMAL:!0,TEXCOORD:!0,COLOR:!0,JOINT:!0,WEIGHT:!0};return p}),define("ThirdParty/GltfPipeline/parseBinaryGltf",["./addPipelineExtras","./removeExtensionsUsed","./updateVersion","../../Core/ComponentDatatype","../../Core/defined","../../Core/DeveloperError","../../Core/getMagic","../../Core/getStringFromTypedArray","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(u){var c=i.createArrayBufferView(l.INT,u.buffer,u.byteOffset,5);if("glTF"!==a(u))throw new o("File is not valid binary glTF");var d=c[1];if(1!==d&&2!==d)throw new o("Binary glTF version is not 1 or 2");var h,p,f;if(1===d){f=c[2];var m=c[3] +;if(0!==c[4])throw new o("Binary glTF scene format is not JSON");var g=20+m,_=s(u,20,m);h=JSON.parse(_);var v=u.subarray(g,f);if(p=h.buffers,n(p)&&Object.keys(p).length>0){var y=p.binary_glTF;n(y)||(y=p.KHR_binary_glTF),n(y)&&(y.extras={_pipeline:{source:v}})}r(h),t(h,"KHR_binary_glTF"),e(h)}if(2===d){f=c[2];for(var b,C=12;C<f;){var S=i.createArrayBufferView(l.INT,u.buffer,u.byteOffset+C,2),w=S[0],T=S[1];C+=8;var E=u.subarray(C,C+w);if(C+=w,1313821514===T){var A=s(E);h=JSON.parse(A),e(h)}else 5130562===T&&(b=E)}if(n(h)&&n(b)&&(p=h.buffers,n(p)&&p.length>0)){p[0].extras._pipeline.source=b}}return h}return u}),define("ThirdParty/GltfPipeline/techniqueParameterForSemantic",["../../Core/defined"],function(e){"use strict";function t(t,r){var i=t.parameters;for(var n in i)if(i.hasOwnProperty(n)){var o=i[n],a=o.semantic;if(e(a)&&a===r)return n}}return t}),define("ThirdParty/GltfPipeline/webGLConstantToGlslType",["../../Core/WebGLConstants"],function(e){"use strict";function t(t){switch(t){case e.FLOAT:return"float";case e.FLOAT_VEC2:return"vec2";case e.FLOAT_VEC3:return"vec3";case e.FLOAT_VEC4:return"vec4";case e.FLOAT_MAT2:return"mat2";case e.FLOAT_MAT3:return"mat3";case e.FLOAT_MAT4:return"mat4";case e.SAMPLER_2D:return"sampler2D";case e.BOOL:return"bool"}}return t}),define("ThirdParty/GltfPipeline/glslTypeToWebGLConstant",["../../Core/WebGLConstants"],function(e){"use strict";function t(t){switch(t){case"float":return e.FLOAT;case"vec2":return e.FLOAT_VEC2;case"vec3":return e.FLOAT_VEC3;case"vec4":return e.FLOAT_VEC4;case"mat2":return e.FLOAT_MAT2;case"mat3":return e.FLOAT_MAT3;case"mat4":return e.FLOAT_MAT4;case"sampler2D":return e.SAMPLER_2D}}return t}),define("ThirdParty/GltfPipeline/processModelMaterialsCommon",["./addToArray","./ForEach","./numberOfComponentsForType","./techniqueParameterForSemantic","./webGLConstantToGlslType","./glslTypeToWebGLConstant","../../Core/clone","../../Core/defined","../../Core/defaultValue","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){if(r=l(r,{}),s(e)){var i=!1,n=e.extensionsRequired,o=e.extensionsUsed;if(s(o)){var a=o.indexOf("KHR_materials_common");a>=0&&(o.splice(a,1),i=!0),s(n)&&(a=n.indexOf("KHR_materials_common"))>=0&&n.splice(a,1)}if(i){s(e.programs)||(e.programs=[]),s(e.shaders)||(e.shaders=[]),s(e.techniques)||(e.techniques=[]),m(e);var u=d(e);y(e);var c={};t.material(e,function(t){if(s(t.extensions)&&s(t.extensions.KHR_materials_common)){var i=t.extensions.KHR_materials_common,n=f(i),o=c[n];s(o)||(o=h(e,i,u,r),c[n]=o),t.values={};var a=i.values;for(var l in a)if(a.hasOwnProperty(l)){var d=a[l];t.values[l]=d}t.technique=o,delete t.extensions.KHR_materials_common,0===Object.keys(t.extensions).length&&delete t.extensions}}),s(e.extensions)&&(delete e.extensions.KHR_materials_common,0===Object.keys(e.extensions).length&&delete e.extensions),v(e)}return e}}function d(e){var t,r={};if(s(e.extensions)&&s(e.extensions.KHR_materials_common)&&(t=e.extensions.KHR_materials_common.lights),s(t)){var i=e.nodes;for(var n in i)if(i.hasOwnProperty(n)){var o=i[n];if(s(o.extensions)&&s(o.extensions.KHR_materials_common)){var a=o.extensions.KHR_materials_common.light;s(a)&&s(t[a])&&(t[a].node=n),delete o.extensions.KHR_materials_common}}var l=0;for(var c in t)if(t.hasOwnProperty(c)){var d=t[c],h=d.type;if("ambient"!==h&&!s(d.node)){delete t[c];continue}var p="light"+l.toString();switch(d.baseName=p,h){case"ambient":var f=d.ambient;r[p+"Color"]={type:u.FLOAT_VEC3,value:f.color};break;case"directional":var m=d.directional;r[p+"Color"]={type:u.FLOAT_VEC3,value:m.color},s(d.node)&&(r[p+"Transform"]={node:d.node,semantic:"MODELVIEW",type:u.FLOAT_MAT4});break;case"point":var g=d.point;r[p+"Color"]={type:u.FLOAT_VEC3,value:g.color},s(d.node)&&(r[p+"Transform"]={node:d.node,semantic:"MODELVIEW",type:u.FLOAT_MAT4}),r[p+"Attenuation"]={type:u.FLOAT_VEC3,value:[g.constantAttenuation,g.linearAttenuation,g.quadraticAttenuation]};break;case"spot":var _=d.spot;r[p+"Color"]={type:u.FLOAT_VEC3,value:_.color},s(d.node)&&(r[p+"Transform"]={node:d.node,semantic:"MODELVIEW",type:u.FLOAT_MAT4},r[p+"InverseTransform"]={node:d.node,semantic:"MODELVIEWINVERSE",type:u.FLOAT_MAT4,useInFragment:!0}),r[p+"Attenuation"]={type:u.FLOAT_VEC3,value:[_.constantAttenuation,_.linearAttenuation,_.quadraticAttenuation]},r[p+"FallOff"]={type:u.FLOAT_VEC2,value:[_.fallOffAngle,_.fallOffExponent]}}++l}}return r}function h(t,i,a,c){var d,h=l(c.optimizeForCesium,!1),f=s(t.extensions)&&s(t.extensions.CESIUM_RTC),m=l(c.addBatchIdToGeneratedShaders,!1),_=t.techniques,v=t.shaders,y=t.programs,b=i.technique.toUpperCase();s(t.extensions)&&s(t.extensions.KHR_materials_common)&&(d=t.extensions.KHR_materials_common.lights);var C=i.values;s(i.transparent)&&(C.transparent=i.transparent),s(i.doubleSided)&&(C.doubleSided=i.doubleSided);var S=l(i.jointCount,0),w=S>0,T=i.extras._pipeline.primitive,E=T.skinning,A=T.hasVertexColors,x="precision highp float;\n",P="precision highp float;\n",D="CONSTANT"!==b,I={modelViewMatrix:{semantic:f?"CESIUM_RTC_MODELVIEW":"MODELVIEW",type:u.FLOAT_MAT4},projectionMatrix:{semantic:"PROJECTION",type:u.FLOAT_MAT4}};D&&(I.normalMatrix={semantic:"MODELVIEWINVERSETRANSPOSE",type:u.FLOAT_MAT3}),w&&(I.jointMatrix={count:S,semantic:"JOINTMATRIX",type:u.FLOAT_MAT4});var O,M=!1;for(var R in C)if(C.hasOwnProperty(R)&&"transparent"!==R&&"doubleSided"!==R){var L=p(R,C[R]);O=R.toLowerCase(),M||L!==u.SAMPLER_2D||(M=!0),I[O]={type:L}}if(s(I.diffuse)&&h&&(I.diffuse.semantic="_3DTILESDIFFUSE"),s(a))for(var N in a)a.hasOwnProperty(N)&&(I[N]=a[N]);var k={};for(var F in I)if(I.hasOwnProperty(F)&&"extras"!==F){var B=I[F];k["u_"+F]=F;var U=s(B.count)?"["+B.count+"]":"";B.type!==u.FLOAT_MAT3&&B.type!==u.FLOAT_MAT4||B.useInFragment?(P+="uniform "+n(B.type)+" u_"+F+U+";\n",delete B.useInFragment):x+="uniform "+n(B.type)+" u_"+F+U+";\n"}var V="";if(w){var z,G,W=r(E.type),H=!1;if(0===E.type.indexOf("MAT")&&(H=!0,W=Math.sqrt(W)),H)for(z=0;z<W;z++)for(G=0;G<W;G++)V+=0===z&&0===G?" mat4 skinMat = ":" skinMat += ",V+="a_weight["+z+"]["+G+"] * u_jointMatrix[int(a_joint["+z+"]["+G+"])];\n";else for(z=0;z<W;z++)V+=0===z?" mat4 skinMat = ":" skinMat += ",V+="a_weight["+z+"] * u_jointMatrix[int(a_joint["+z+"])];\n"}var j={a_position:"position"};I.position={semantic:"POSITION",type:u.FLOAT_VEC3},x+="attribute vec3 a_position;\n",x+="varying vec3 v_positionEC;\n",V+=w?" vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);\n":" vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);\n",V+=" v_positionEC = pos.xyz;\n",V+=" gl_Position = u_projectionMatrix * pos;\n",P+="varying vec3 v_positionEC;\n",D&&(j.a_normal="normal",I.normal={semantic:"NORMAL",type:u.FLOAT_VEC3},x+="attribute vec3 a_normal;\n",x+="varying vec3 v_normal;\n",V+=w?" v_normal = u_normalMatrix * mat3(skinMat) * a_normal;\n":" v_normal = u_normalMatrix * a_normal;\n",P+="varying vec3 v_normal;\n");var q;if(M&&(j.a_texcoord_0="texcoord_0",I.texcoord_0={semantic:"TEXCOORD_0",type:u.FLOAT_VEC2},q="v_texcoord_0",x+="attribute vec2 a_texcoord_0;\n",x+="varying vec2 "+q+";\n",V+=" "+q+" = a_texcoord_0;\n",P+="varying vec2 "+q+";\n"),w){j.a_joint="joint";var Y=g(E.type),X=o(Y);I.joint={semantic:"JOINT",type:X},j.a_weight="weight",I.weight={semantic:"WEIGHT",type:X},x+="attribute "+Y+" a_joint;\n",x+="attribute "+Y+" a_weight;\n"}A&&(j.a_vertexColor="vertexColor",I.vertexColor={semantic:"COLOR_0",type:u.FLOAT_VEC4},x+="attribute vec4 a_vertexColor;\n",x+="varying vec4 v_vertexColor;\n",V+=" v_vertexColor = a_vertexColor;\n",P+="varying vec4 v_vertexColor;\n"),m&&(j.a_batchId="batchId",I.batchId={semantic:"_BATCHID",type:u.FLOAT},x+="attribute float a_batchId;\n");var Q=D&&("BLINN"===b||"PHONG"===b)&&s(I.specular)&&s(I.shininess)&&I.shininess>0,Z=!1,K=!1,J="";for(var $ in d)if(d.hasOwnProperty($)){var ee=d[$],te=ee.type.toLowerCase(),re=ee.baseName;J+=" {\n";var ie,ne,oe="u_"+re+"Color";"ambient"===te?(K=!0,J+=" ambientLight += "+oe+";\n"):D&&(Z=!0,ie="v_"+re+"Direction",ne="v_"+re+"Position","point"!==te&&(x+="varying vec3 "+ie+";\n",P+="varying vec3 "+ie+";\n",V+=" "+ie+" = mat3(u_"+re+"Transform) * vec3(0.,0.,1.);\n","directional"===te&&(J+=" vec3 l = normalize("+ie+");\n")),"directional"!==te?(x+="varying vec3 "+ne+";\n",P+="varying vec3 "+ne+";\n",V+=" "+ne+" = u_"+re+"Transform[3].xyz;\n",J+=" vec3 VP = "+ne+" - v_positionEC;\n",J+=" vec3 l = normalize(VP);\n",J+=" float range = length(VP);\n",J+=" float attenuation = 1.0 / (u_"+re+"Attenuation.x + ",J+="(u_"+re+"Attenuation.y * range) + ",J+="(u_"+re+"Attenuation.z * range * range));\n"):J+=" float attenuation = 1.0;\n","spot"===te&&(J+=" float spotDot = dot(l, normalize("+ie+"));\n",J+=" if (spotDot < cos(u_"+re+"FallOff.x * 0.5))\n",J+=" {\n",J+=" attenuation = 0.0;\n",J+=" }\n",J+=" else\n",J+=" {\n",J+=" attenuation *= max(0.0, pow(spotDot, u_"+re+"FallOff.y));\n",J+=" }\n"),J+=" diffuseLight += "+oe+"* max(dot(normal,l), 0.) * attenuation;\n",Q&&("BLINN"===b?(J+=" vec3 h = normalize(l + viewDir);\n",J+=" float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n"):(J+=" vec3 reflectDir = reflect(-l, normal);\n",J+=" float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n"),J+=" specularLight += "+oe+" * specularIntensity;\n")),J+=" }\n"}if(K||(J+=" ambientLight += vec3(0.2, 0.2, 0.2);\n"),!Z&&"CONSTANT"!==b){J+=h?" vec3 l = normalize(czm_sunDirectionEC);\n":" vec3 l = vec3(0.0, 0.0, 1.0);\n";J+=" diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal,l), "+(h?"0.2":"0.0")+");\n",Q&&("BLINN"===b?(J+=" vec3 h = normalize(l + viewDir);\n",J+=" float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n"):(J+=" vec3 reflectDir = reflect(-l, normal);\n",J+=" float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n"),J+=" specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity;\n")}x+="void main(void) {\n",x+=V,x+="}\n",P+="void main(void) {\n";var ae=" vec3 color = vec3(0.0, 0.0, 0.0);\n";D&&(P+=" vec3 normal = normalize(v_normal);\n",i.doubleSided&&(P+=" if (gl_FrontFacing == false)\n",P+=" {\n",P+=" normal = -normal;\n",P+=" }\n"));var se;"CONSTANT"!==b?(s(I.diffuse)&&(I.diffuse.type===u.SAMPLER_2D?P+=" vec4 diffuse = texture2D(u_diffuse, "+q+");\n":P+=" vec4 diffuse = u_diffuse;\n",P+=" vec3 diffuseLight = vec3(0.0, 0.0, 0.0);\n",ae+=" color += diffuse.rgb * diffuseLight;\n"),Q&&(I.specular.type===u.SAMPLER_2D?P+=" vec3 specular = texture2D(u_specular, "+q+").rgb;\n":P+=" vec3 specular = u_specular.rgb;\n",P+=" vec3 specularLight = vec3(0.0, 0.0, 0.0);\n",ae+=" color += specular * specularLight;\n"),se=s(I.transparency)?" gl_FragColor = vec4(color * diffuse.a * u_transparency, diffuse.a * u_transparency);\n":" gl_FragColor = vec4(color * diffuse.a, diffuse.a);\n"):se=s(I.transparency)?" gl_FragColor = vec4(color * u_transparency, u_transparency);\n":" gl_FragColor = vec4(color, 1.0);\n",A&&(ae+=" color *= v_vertexColor.rgb;\n"),s(I.emission)&&(I.emission.type===u.SAMPLER_2D?P+=" vec3 emission = texture2D(u_emission, "+q+").rgb;\n":P+=" vec3 emission = u_emission.rgb;\n",ae+=" color += emission;\n"),(s(I.ambient)||"CONSTANT"!==b)&&(s(I.ambient)?I.ambient.type===u.SAMPLER_2D?P+=" vec3 ambient = texture2D(u_ambient, "+q+").rgb;\n":P+=" vec3 ambient = u_ambient.rgb;\n":P+=" vec3 ambient = diffuse.rgb;\n",ae+=" color += ambient * ambientLight;\n"),P+=" vec3 viewDir = -normalize(v_positionEC);\n",P+=" vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n",P+=J,P+=ae,P+=se,P+="}\n";var le;le=C.transparent?{enable:[u.DEPTH_TEST,u.BLEND],functions:{depthMask:[!1],blendEquationSeparate:[u.FUNC_ADD,u.FUNC_ADD],blendFuncSeparate:[u.ONE,u.ONE_MINUS_SRC_ALPHA,u.ONE,u.ONE_MINUS_SRC_ALPHA]}}:i.doubleSided?{enable:[u.DEPTH_TEST]}:{enable:[u.CULL_FACE,u.DEPTH_TEST]};var ue=e(v,{type:u.VERTEX_SHADER,extras:{_pipeline:{source:x,extension:".glsl"}}}),ce=e(v,{type:u.FRAGMENT_SHADER,extras:{_pipeline:{source:P,extension:".glsl"}}}),de=Object.keys(j),he=e(y,{attributes:de,fragmentShader:ce,vertexShader:ue});return e(_,{attributes:j,parameters:I,program:he,states:le,uniforms:k})}function p(e,t){var r;switch(r=s(t.value)?t.value:s(t.index)?[t.index]:t,e){case"ambient":case"diffuse":case"emission":case"specular":return 1===r.length?u.SAMPLER_2D:u.FLOAT_VEC4;case"shininess":case"transparency":return u.FLOAT;case"transparent":case"doubleSided":return u.BOOL}}function f(e){var t="";t+="technique:"+e.technique+";";for(var r=e.values,i=Object.keys(r).sort(),n=i.length,o=0;o<n;++o){var a=i[o];r.hasOwnProperty(a)&&(t+=a+":"+p(a,r[a]),t+=";")}t+=l(e.doubleSided,l(e.values.doubleSided,!1)).toString()+";",t+=l(e.transparent,l(e.values.transparent,!1)).toString()+";";var s=l(e.jointCount,0);t+=s.toString()+";";var u=e.extras._pipeline.primitive,c=u.skinning;return s>0&&(t+=c.type+";"),t+=u.hasVertexColors}function m(e){s(e.extensions)||(e.extensions={});var t=e.extensions;s(t.KHR_materials_common)||(t.KHR_materials_common={});var r=t.KHR_materials_common;s(r.lights)||(r.lights={});for(var i=r.lights,n=i.length,o=0;o<n;o++){var a=i[o];if("ambient"===a.type){s(a.ambient)||(a.ambient={});var u=a.ambient;s(u.color)||(u.color=[1,1,1])}else if("directional"===a.type){s(a.directional)||(a.directional={});var c=a.directional;s(c.color)||(c.color=[1,1,1])}else if("point"===a.type){s(a.point)||(a.point={});var d=a.point;s(d.color)||(d.color=[1,1,1]),d.constantAttenuation=l(d.constantAttenuation,1),d.linearAttenuation=l(d.linearAttenuation,0),d.quadraticAttenuation=l(d.quadraticAttenuation,0)}else if("spot"===a.type){s(a.spot)||(a.spot={});var h=a.spot;s(h.color)||(h.color=[1,1,1]),h.constantAttenuation=l(h.constantAttenuation,1),h.fallOffAngle=l(h.fallOffAngle,3.14159265),h.fallOffExponent=l(h.fallOffExponent,0),h.linearAttenuation=l(h.linearAttenuation,0),h.quadraticAttenuation=l(h.quadraticAttenuation,0)}}}function g(e){return"SCALAR"===e?"float":e.toLowerCase()}function _(e,t){var r=e.accessors,n=e.materials,o=e.techniques,a=e.programs,l=e.shaders,u=t.attributes,c=n[t.material],d=o[c.technique],h=a[d.program],p=l[h.vertexShader];for(var f in u)if(u.hasOwnProperty(f)&&!s(i(d,f))){var m=u[f],_=r[m],v=f.toLowerCase();"_"===v.charAt(0)&&(v=v.slice(1));var y="a_"+v;d.parameters[v]={semantic:f,type:_.componentType},d.attributes[y]=v,h.attributes.push(y);var b=p.extras._pipeline,C=b.source;C="attribute "+g(_.type)+" "+y+";\n"+C,b.source=C}}function v(e){t.mesh(e,function(r){t.meshPrimitive(r,function(t){_(e,t)})})}function y(r){var i=r.accessors,n=r.materials;t.mesh(r,function(r){t.meshPrimitive(r,function(t){var r=t.material,o=n[r];if(s(o.extensions)&&s(o.extensions.KHR_materials_common)){var l,u,c=o.extensions.KHR_materials_common,d=t.attributes.JOINT;if(s(d)){var h=i[d];l=h.componentType,u=h.type}var p=s(d),f=s(t.attributes.COLOR_0),m=c.extras._pipeline.primitive;if(s(m)){if(m.skinning.skinned!==p||m.skinning.type!==u||m.hasVertexColors!==f){var g=a(o,!0);g.extensions.KHR_materials_common.extras._pipeline.primitive={skinning:{skinned:p,componentType:l,type:u},hasVertexColors:f},r=e(n,g),t.material=r}}else c.extras._pipeline.primitive={skinning:{skinned:p,componentType:l,type:u},hasVertexColors:f}}})})}return c}),define("ThirdParty/GltfPipeline/processPbrMetallicRoughness",["./addToArray","./ForEach","./numberOfComponentsForType","./techniqueParameterForSemantic","./webGLConstantToGlslType","./glslTypeToWebGLConstant","../../Core/clone","../../Core/defined","../../Core/defaultValue","../../Core/WebGLConstants"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){r=l(r,{});var i=!1;return t.material(e,function(e){s(e.pbrMetallicRoughness)&&(i=!0)}),i&&(s(e.programs)||(e.programs=[]),s(e.shaders)||(e.shaders=[]),s(e.techniques)||(e.techniques=[]),g(e),t.material(e,function(t){var i=t.pbrMetallicRoughness;if(s(i)){var n=d(e,t,r);t.values=i,t.technique=n,delete t.pbrMetallicRoughness}}),m(e)),e}function d(i,a,c){var d=l(c.optimizeForCesium,!1),f=s(i.extensions)&&s(i.extensions.CESIUM_RTC),m=l(c.addBatchIdToGeneratedShaders,!1),g=i.techniques,_=i.shaders,v=i.programs,y=a.pbrMetallicRoughness;for(var b in a)(a.hasOwnProperty(b)&&(b.indexOf("Texture")>=0||b.indexOf("Factor")>=0)||"doubleSided"===b)&&(y[b]=a[b]);var C,S="precision highp float;\n",w="precision highp float;\n";s(i.skins)&&(C=i.skins[0]);var T,E=s(C)?C.joints:[],A=E.length,x=a.extras._pipeline.primitive,P=x.skinning,D=P.skinned,I=x.hasVertexColors,O=!1,M=!1;t.mesh(i,function(e){t.meshPrimitive(e,function(e){var t=e.targets;!M&&s(t)&&(M=!0,T=t);var r=e.attributes;for(var i in r)i.indexOf("TANGENT")>=0&&(O=!0)})});var R={modelViewMatrix:{semantic:f?"CESIUM_RTC_MODELVIEW":"MODELVIEW",type:u.FLOAT_MAT4},projectionMatrix:{semantic:"PROJECTION",type:u.FLOAT_MAT4}};R.normalMatrix={semantic:"MODELVIEWINVERSETRANSPOSE",type:u.FLOAT_MAT3},D&&(R.jointMatrix={count:A,semantic:"JOINTMATRIX",type:u.FLOAT_MAT4}),M&&(R.morphWeights={count:T.length,semantic:"MORPHWEIGHTS",type:u.FLOAT});var L=!1;for(var N in y)if(y.hasOwnProperty(N)){var k=h(N);L||k!==u.SAMPLER_2D||(L=!0),R[N]={type:k}}var F={};for(var B in R)if(R.hasOwnProperty(B)&&"extras"!==B){var U=R[B];F["u_"+B]=B;var V=s(U.count)?"["+U.count+"]":"";U.type!==u.FLOAT_MAT3&&U.type!==u.FLOAT_MAT4&&"morphWeights"!==B||U.useInFragment?(w+="uniform "+n(U.type)+" u_"+B+V+";\n",delete U.useInFragment):S+="uniform "+n(U.type)+" u_"+B+V+";\n"}var z="";if(D){var G,W,H=r(P.type),j=!1;if(0===P.type.indexOf("MAT")&&(j=!0,H=Math.sqrt(H)),j)for(G=0;G<H;G++)for(W=0;W<H;W++)z+=0===G&&0===W?" mat4 skinMatrix = ":" skinMatrix += ",z+="a_weight["+G+"]["+W+"] * u_jointMatrix[int(a_joint["+G+"]["+W+"])];\n";else for(G=0;G<H;G++)z+=0===G?" mat4 skinMatrix = ":" skinMatrix += ",z+="a_weight["+G+"] * u_jointMatrix[int(a_joint["+G+"])];\n"}var q={a_position:"position"};if(R.position={semantic:"POSITION",type:u.FLOAT_VEC3},S+="attribute vec3 a_position;\n",S+="varying vec3 v_positionEC;\n",d&&(S+="varying vec3 v_positionWC;\n"),z+=" vec3 weightedPosition = a_position;\n",z+=" vec3 weightedNormal = a_normal;\n",O&&(z+=" vec3 weightedTangent = a_tangent;\n"),M)for(var Y=0;Y<T.length;Y++){var X=T[Y];for(var Q in X)if(X.hasOwnProperty(Q)&&"extras"!==Q){var Z=Q.toLowerCase()+"_"+Y;q["a_"+Z]=Z,R[Z]={semantic:Q+"_"+Y,type:u.FLOAT_VEC3},S+="attribute vec3 a_"+Z+";\n","POSITION"===Q?z+=" weightedPosition += u_morphWeights["+Y+"] * a_"+Z+";\n":"NORMAL"===Q?z+=" weightedNormal += u_morphWeights["+Y+"] * a_"+Z+";\n":"TANGENT"===Q&&(z+=" weightedTangent += u_morphWeights["+Y+"] * a_"+Z+";\n")}}z+=D?" vec4 position = skinMatrix * vec4(weightedPosition, 1.0);\n":" vec4 position = vec4(weightedPosition, 1.0);\n",d&&(z+=" v_positionWC = (czm_model * position).xyz;\n"),z+=" position = u_modelViewMatrix * position;\n",z+=" v_positionEC = position.xyz;\n",z+=" gl_Position = u_projectionMatrix * position;\n",w+="varying vec3 v_positionEC;\n",d&&(w+="varying vec3 v_positionWC;\n"),q.a_normal="normal",R.normal={semantic:"NORMAL",type:u.FLOAT_VEC3},S+="attribute vec3 a_normal;\n",S+="varying vec3 v_normal;\n",z+=D?" v_normal = u_normalMatrix * mat3(skinMatrix) * weightedNormal;\n":" v_normal = u_normalMatrix * weightedNormal;\n",w+="varying vec3 v_normal;\n",O&&(q.a_tangent="tangent",R.tangent={semantic:"TANGENT",type:u.FLOAT_VEC3},S+="attribute vec3 a_tangent;\n",S+="varying vec3 v_tangent;\n",z+=" v_tangent = (u_modelViewMatrix * vec4(weightedTangent, 1.0)).xyz;\n",w+="varying vec3 v_tangent;\n");var K;if(L&&(q.a_texcoord_0="texcoord_0",R.texcoord_0={semantic:"TEXCOORD_0",type:u.FLOAT_VEC2},K="v_texcoord_0",S+="attribute vec2 a_texcoord_0;\n",S+="varying vec2 "+K+";\n",z+=" "+K+" = a_texcoord_0;\n",w+="varying vec2 "+K+";\n"),D){q.a_joint="joint";var J=p(P.type),$=o(J);R.joint={semantic:"JOINTS_0",type:$},q.a_weight="weight",R.weight={semantic:"WEIGHTS_0",type:$},S+="attribute "+J+" a_joint;\n",S+="attribute "+J+" a_weight;\n"}I&&(q.a_vertexColor="vertexColor",R.vertexColor={semantic:"COLOR_0",type:u.FLOAT_VEC4},S+="attribute vec4 a_vertexColor;\n",S+="varying vec4 v_vertexColor;\n",z+=" v_vertexColor = a_vertexColor;\n",w+="varying vec4 v_vertexColor;\n"),m&&(q.a_batchId="batchId",R.batchId={semantic:"_BATCHID",type:u.FLOAT},S+="attribute float a_batchId;\n"),S+="void main(void) \n{\n",S+=z,S+="}\n",w+="const float M_PI = 3.141592653589793;\n",w+="vec3 lambertianDiffuse(vec3 baseColor) \n{\n return baseColor / M_PI;\n}\n\n",w+="vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n{\n return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);\n}\n\n",w+="vec3 fresnelSchlick(float metalness, float VdotH) \n{\n return metalness + (vec3(1.0) - metalness) * pow(1.0 - VdotH, 5.0);\n}\n\n",w+="float smithVisibilityG1(float NdotV, float roughness) \n{\n float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n return NdotV / (NdotV * (1.0 - k) + k);\n}\n\n",w+="float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n{\n return smithVisibilityG1(NdotL, roughness) * smithVisibilityG1(NdotV, roughness);\n}\n\n",w+="float GGX(float roughness, float NdotH) \n{\n float roughnessSquared = roughness * roughness;\n float f = (NdotH * roughnessSquared - NdotH) * NdotH + 1.0;\n return roughnessSquared / (M_PI * f * f);\n}\n\n",w+="void main(void) \n{\n",w+=" vec3 ng = normalize(v_normal);\n",s(y.normalTexture)?O?(w+=" vec3 t = normalize(v_tangent);\n",w+=" vec3 b = normalize(cross(ng, t));\n",w+=" mat3 tbn = mat3(t, b, ng);\n",w+=" vec3 n = texture2D(u_normalTexture, "+K+").rgb;\n",w+=" n = normalize(tbn * (2.0 * n - 1.0));\n"):(w="#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\n"+w,w+="#ifdef GL_OES_standard_derivatives\n",w+=" vec3 pos_dx = dFdx(v_positionEC);\n",w+=" vec3 pos_dy = dFdy(v_positionEC);\n",w+=" vec3 tex_dx = dFdx(vec3("+K+",0.0));\n",w+=" vec3 tex_dy = dFdy(vec3("+K+",0.0));\n",w+=" vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n",w+=" t = normalize(t - ng * dot(ng, t));\n",w+=" vec3 b = normalize(cross(ng, t));\n",w+=" mat3 tbn = mat3(t, b, ng);\n",w+=" vec3 n = texture2D(u_normalTexture, "+K+").rgb;\n",w+=" n = normalize(tbn * (2.0 * n - 1.0));\n",w+="#else\n",w+=" vec3 n = ng;\n",w+="#endif\n"):w+=" vec3 n = ng;\n",y.doubleSided&&(w+=" if (!gl_FrontFacing)\n",w+=" {\n",w+=" n = -n;\n",w+=" }\n"),s(y.baseColorTexture)?(w+=" vec4 baseColorWithAlpha = texture2D(u_baseColorTexture, "+K+");\n",s(y.baseColorFactor)&&(w+=" baseColorWithAlpha *= u_baseColorFactor;\n")):s(y.baseColorFactor)?w+=" vec4 baseColorWithAlpha = u_baseColorFactor;\n":w+=" vec4 baseColorWithAlpha = vec4(1.0);\n",I&&(w+=" baseColorWithAlpha *= v_vertexColor;\n"),w+=" vec3 baseColor = baseColorWithAlpha.rgb;\n",s(y.metallicRoughnessTexture)?(w+=" vec3 metallicRoughness = texture2D(u_metallicRoughnessTexture, "+K+").rgb;\n",w+=" float metalness = clamp(metallicRoughness.b, 0.0, 1.0);\n",w+=" float roughness = clamp(metallicRoughness.g, 0.04, 1.0);\n",s(y.metallicFactor)&&(w+=" metalness *= u_metallicFactor;\n"),s(y.roughnessFactor)&&(w+=" roughness *= u_roughnessFactor;\n")):(s(y.metallicFactor)?w+=" float metalness = clamp(u_metallicFactor, 0.0, 1.0);\n":w+=" float metalness = 1.0;\n",s(y.roughnessFactor)?w+=" float roughness = clamp(u_roughnessFactor, 0.04, 1.0);\n":w+=" float roughness = 1.0;\n"),w+=" vec3 v = -normalize(v_positionEC);\n",w+=" vec3 lightColor = vec3(1.0, 1.0, 1.0);\n",w+=d?" vec3 l = normalize(czm_sunDirectionEC);\n":" vec3 l = vec3(0.0, 0.0, 1.0);\n",w+=" vec3 h = normalize(v + l);\n",d?(w+=" vec3 r = normalize(czm_inverseViewRotation * normalize(reflect(v, n)));\n",w+=" czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\n",w+=" float vertexRadius = length(v_positionWC);\n",w+=" float horizonDotNadir = 1.0 - ellipsoid.radii.x / vertexRadius;\n",w+=" float reflectionDotNadir = dot(r, normalize(v_positionWC));\n",w+=" r.x = -r.x;\n",w+=" r = -normalize(czm_temeToPseudoFixed * r);\n",w+=" r.x = -r.x;\n"):w+=" vec3 r = normalize(reflect(v, n));\n",w+=" float NdotL = clamp(dot(n, l), 0.001, 1.0);\n",w+=" float NdotV = abs(dot(n, v)) + 0.001;\n",w+=" float NdotH = clamp(dot(n, h), 0.0, 1.0);\n",w+=" float LdotH = clamp(dot(l, h), 0.0, 1.0);\n",w+=" float VdotH = clamp(dot(v, h), 0.0, 1.0);\n",w+=" vec3 f0 = vec3(0.04);\n",w+=" float alpha = roughness * roughness;\n",w+=" vec3 diffuseColor = baseColor * (1.0 - metalness);\n",w+=" vec3 specularColor = mix(f0, baseColor, metalness);\n",w+=" float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n",w+=" vec3 r90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));\n",w+=" vec3 r0 = specularColor.rgb;\n",w+=" vec3 F = fresnelSchlick2(r0, r90, VdotH);\n",w+=" float G = smithVisibilityGGX(alpha, NdotL, NdotV);\n",w+=" float D = GGX(alpha, NdotH);\n",w+=" vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(baseColor);\n",w+=" vec3 specularContribution = F * G * D / (4.0 * NdotL * NdotV);\n",w+=" vec3 color = NdotL * lightColor * (diffuseContribution + specularContribution);\n",d&&(w+=" float inverseRoughness = 1.0 - roughness;\n",w+=" inverseRoughness *= inverseRoughness;\n",w+=" vec3 sceneSkyBox = textureCube(czm_environmentMap, r).rgb * inverseRoughness;\n",w+=" float atmosphereHeight = 0.05;\n",w+=" float blendRegionSize = 0.1 * ((1.0 - inverseRoughness) * 8.0 + 1.1 - horizonDotNadir);\n",w+=" float farAboveHorizon = clamp(horizonDotNadir - blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n",w+=" float aroundHorizon = clamp(horizonDotNadir + blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n",w+=" float farBelowHorizon = clamp(horizonDotNadir + blendRegionSize * 1.5, 1.0e-10 - blendRegionSize, 0.99999);\n",w+=" float smoothstepHeight = smoothstep(0.0, atmosphereHeight, horizonDotNadir);\n",w+=" float lightScale = smoothstepHeight * 1.5 + 1.0;\n",w+=" vec3 diffuseIrradiance = mix(vec3(0.5), vec3(0.05), smoothstepHeight);\n",w+=" vec3 belowHorizonColor = mix(vec3(0.1, 0.2, 0.4), vec3(0.2, 0.5, 0.7), smoothstepHeight);\n",w+=" vec3 nadirColor = belowHorizonColor * 0.5;\n",w+=" vec3 aboveHorizonColor = vec3(0.8, 0.9, 0.95);\n",w+=" vec3 blueSkyColor = mix(vec3(0.09, 0.13, 0.24), aboveHorizonColor, reflectionDotNadir * inverseRoughness * 0.5 + 0.5);\n",w+=" vec3 zenithColor = mix(blueSkyColor, sceneSkyBox, smoothstepHeight);\n",w+=" vec3 specularIrradiance = mix(zenithColor, aboveHorizonColor, smoothstep(farAboveHorizon, aroundHorizon, reflectionDotNadir) * inverseRoughness);\n",w+=" specularIrradiance = mix(specularIrradiance, belowHorizonColor, smoothstep(aroundHorizon, farBelowHorizon, reflectionDotNadir) * inverseRoughness);\n",w+=" specularIrradiance = mix(specularIrradiance, nadirColor, smoothstep(farBelowHorizon, 1.0, reflectionDotNadir) * inverseRoughness);\n",w+=" vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n",w+=" vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * (specularColor * brdfLut.x + brdfLut.y));\n",w+=" color = color * lightScale + IBLColor;\n"),s(y.occlusionTexture)&&(w+=" color *= texture2D(u_occlusionTexture, "+K+").r;\n"),s(y.emissiveTexture)?(w+=" vec3 emissive = texture2D(u_emissiveTexture, "+K+").rgb;\n",s(y.emissiveFactor)&&(w+=" emissive *= u_emissiveFactor;\n"),w+=" color += emissive;\n"):s(y.emissiveFactor)&&(w+=" color += u_emissiveFactor;\n");var ee=a.alphaMode;if(s(ee))if("MASK"===ee){var te=a.alphaCutoff;s(te)?w+=" gl_FragColor = vec4(color, int(baseColorWithAlpha.a >= "+te+"));\n":w+=" gl_FragColor = vec4(color, 1.0);\n"}else w+="BLEND"===ee?" gl_FragColor = vec4(color, baseColorWithAlpha.a);\n":" gl_FragColor = vec4(color, 1.0);\n";else w+=" gl_FragColor = vec4(color, 1.0);\n";w+="}\n";var re;re=s(ee)&&"OPAQUE"!==ee?{enable:[u.DEPTH_TEST,u.BLEND],functions:{depthMask:[!1],blendEquationSeparate:[u.FUNC_ADD,u.FUNC_ADD],blendFuncSeparate:[u.ONE,u.ONE_MINUS_SRC_ALPHA,u.ONE,u.ONE_MINUS_SRC_ALPHA]}}:y.doubleSided?{enable:[u.DEPTH_TEST]}:{enable:[u.CULL_FACE,u.DEPTH_TEST]};var ie=e(_,{type:u.VERTEX_SHADER,extras:{_pipeline:{source:S,extension:".glsl"}}}),ne=e(_,{type:u.FRAGMENT_SHADER,extras:{_pipeline:{source:w,extension:".glsl"}}}),oe=Object.keys(q),ae=e(v,{attributes:oe,fragmentShader:ne,vertexShader:ie});return e(g,{attributes:q,parameters:R,program:ae,states:re,uniforms:F})}function h(e){switch(e){case"baseColorFactor":return u.FLOAT_VEC4;case"metallicFactor":case"roughnessFactor":return u.FLOAT;case"baseColorTexture":case"metallicRoughnessTexture":case"normalTexture":case"occlusionTexture":case"emissiveTexture":return u.SAMPLER_2D;case"emissiveFactor":return u.FLOAT_VEC3;case"doubleSided":return u.BOOL}}function p(e){return"SCALAR"===e?"float":e.toLowerCase()}function f(e,t){var r=e.accessors,n=e.materials,o=e.techniques,a=e.programs,l=e.shaders,u=t.targets,c=t.attributes;for(var d in u)if(s(d)){var h=u[d];for(var f in h)"extras"!==f&&(c[f+"_"+d]=h[f])}var m=n[t.material],g=o[m.technique],_=a[g.program],v=l[_.vertexShader];for(var y in c)if(c.hasOwnProperty(y)&&!s(i(g,y))){var b=c[y],C=r[b],S=y.toLowerCase();"_"===S.charAt(0)&&(S=S.slice(1));var w="a_"+S;g.parameters[S]={semantic:y,type:C.componentType},g.attributes[w]=S,_.attributes.push(w);var T=v.extras._pipeline,E=T.source;E="attribute "+p(C.type)+" "+w+";\n"+E,T.source=E}}function m(e){t.mesh(e,function(r){t.meshPrimitive(r,function(t){f(e,t)})})}function g(r){var i=r.accessors,n=r.materials;t.mesh(r,function(r){t.meshPrimitive(r,function(t){var r,o,l=t.material,u=n[l],c=t.attributes.JOINTS_0;if(s(c)){var d=i[c];r=d.componentType,o=d.type}var h=s(c),p=s(t.attributes.COLOR_0),f=u.extras._pipeline.primitive;if(s(f)){if(f.skinning.skinned!==h||f.skinning.type!==o||f.hasVertexColors!==p){var m=a(u,!0);m.extras._pipeline.skinning={skinning:{skinned:h,componentType:r,type:o},hasVertexColors:p},l=e(n,m),t.material=l}}else u.extras._pipeline.primitive={skinning:{skinned:h,componentType:r,type:o},hasVertexColors:p}})})}return c}),define("Scene/AttributeType",["../Core/freezeObject"],function(e){"use strict";return e({SCALAR:"SCALAR",VEC2:"VEC2",VEC3:"VEC3",VEC4:"VEC4",MAT2:"MAT2",MAT3:"MAT3",MAT4:"MAT4"})}),define("Scene/Axis",["../Core/Check","../Core/freezeObject","../Core/Math","../Core/Matrix3","../Core/Matrix4"],function(e,t,r,i,n){"use strict";var o={X:0,Y:1,Z:2,Y_UP_TO_Z_UP:n.fromRotationTranslation(i.fromRotationX(r.PI_OVER_TWO)),Z_UP_TO_Y_UP:n.fromRotationTranslation(i.fromRotationX(-r.PI_OVER_TWO)),X_UP_TO_Z_UP:n.fromRotationTranslation(i.fromRotationY(-r.PI_OVER_TWO)),Z_UP_TO_X_UP:n.fromRotationTranslation(i.fromRotationY(r.PI_OVER_TWO)),X_UP_TO_Y_UP:n.fromRotationTranslation(i.fromRotationZ(r.PI_OVER_TWO)),Y_UP_TO_X_UP:n.fromRotationTranslation(i.fromRotationZ(-r.PI_OVER_TWO)),fromName:function(e){return o[e]}};return t(o)}),define("Scene/JobType",["../Core/freezeObject"],function(e){"use strict";return e({TEXTURE:0,PROGRAM:1,BUFFER:2,NUMBER_OF_JOB_TYPES:3})}),define("Scene/ModelAnimationCache",["./AttributeType","../Core/Cartesian3","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/LinearSpline","../Core/Matrix4","../Core/Quaternion","../Core/QuaternionSpline","../Core/WebGLConstants","../Core/WeightSpline","../ThirdParty/GltfPipeline/getAccessorByteStride","../ThirdParty/GltfPipeline/numberOfComponentsForType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(){}function f(e,t){var r=e.gltf,i=r.buffers,n=r.bufferViews,o=n[t.bufferView],a=i[o.buffer],s=o.byteOffset+t.byteOffset,l=t.count*h(t.type),u=_.test(a.uri)?"":a.uri +;return e.cacheKey+"//"+u+"/"+s+"/"+l}function m(e,t,r){return e.cacheKey+"//"+t+"/"+r}function g(e){this._value=e}var _=/^data\:/i,v={};p.getAnimationParameterValues=function(e,o){var a=f(e,o),l=v[a];if(!n(l)){var u=e.gltf,c=u.buffers,p=u.bufferViews,m=p[o.bufferView],g=m.buffer,_=c[g],y=_.extras._pipeline.source,b=o.componentType,C=o.type,S=h(C),w=o.count,T=d(u,o);l=new Array(w);for(var E=i(o.byteOffset,0),A=m.byteOffset+E,x=0;x<w;x++){var P=r.createArrayBufferView(b,y.buffer,y.byteOffset+A,S);"SCALAR"===C?l[x]=P[0]:"VEC3"===C?l[x]=t.fromArray(P):"VEC4"===C&&(l[x]=s.unpack(P)),A+=T}n(e.cacheKey)&&(v[a]=l)}return l};var y={};g.prototype.evaluate=function(e,t){return this._value},p.getAnimationSpline=function(e,t,r,i,a,s,u,d){var h=m(e,t,i),p=y[h];if(!n(p)){var f=s,_=d;1===f.length&&1===_.length?p=new g(_[0]):"LINEAR"===a.interpolation&&("translation"===u||"scale"===u?p=new o({times:f,points:_}):"rotation"===u?p=new l({times:f,points:_}):"weights"===u&&(p=new c({times:f,weights:_}))),n(e.cacheKey)&&(y[h]=p)}return p};var b={};return p.getSkinInverseBindMatrices=function(t,i){var o=f(t,i),s=b[o];if(!n(s)){var l=t.gltf,c=l.buffers,p=l.bufferViews,m=i.bufferView,g=p[m],_=g.buffer,v=c[_],y=v.extras._pipeline.source,C=i.componentType,S=i.type,w=i.count,T=d(l,i),E=g.byteOffset+i.byteOffset,A=h(S);if(s=new Array(w),C===u.FLOAT&&S===e.MAT4)for(var x=0;x<w;++x){var P=r.createArrayBufferView(C,y.buffer,y.byteOffset+E,A);s[x]=a.fromArray(P),E+=T}b[o]=s}return s},p}),define("Scene/ModelAnimationLoop",["../Core/freezeObject"],function(e){"use strict";return e({NONE:0,REPEAT:1,MIRRORED_REPEAT:2})}),define("Scene/ModelAnimationState",["../Core/freezeObject"],function(e){"use strict";return e({STOPPED:0,ANIMATING:1})}),define("Scene/ModelAnimation",["../Core/defaultValue","../Core/defineProperties","../Core/Event","../Core/JulianDate","./ModelAnimationLoop","./ModelAnimationState"],function(e,t,r,i,n,o){"use strict";function a(t,a,s){this._name=s.name,this._startTime=i.clone(t.startTime),this._delay=e(t.delay,0),this._stopTime=t.stopTime,this.removeOnStop=e(t.removeOnStop,!1),this._speedup=e(t.speedup,1),this._reverse=e(t.reverse,!1),this._loop=e(t.loop,n.NONE),this.start=new r,this.update=new r,this.stop=new r,this._state=o.STOPPED,this._runtimeAnimation=s,this._computedStartTime=void 0,this._duration=void 0;var l=this;this._raiseStartEvent=function(){l.start.raiseEvent(a,l)},this._updateEventTime=0,this._raiseUpdateEvent=function(){l.update.raiseEvent(a,l,l._updateEventTime)},this._raiseStopEvent=function(){l.stop.raiseEvent(a,l)}}return t(a.prototype,{name:{get:function(){return this._name}},startTime:{get:function(){return this._startTime}},delay:{get:function(){return this._delay}},stopTime:{get:function(){return this._stopTime}},speedup:{get:function(){return this._speedup}},reverse:{get:function(){return this._reverse}},loop:{get:function(){return this._loop}}}),a}),define("Scene/ModelAnimationCollection",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/JulianDate","../Core/Math","./ModelAnimation","./ModelAnimationLoop","./ModelAnimationState"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e){this.animationAdded=new n,this.animationRemoved=new n,this._model=e,this._scheduledAnimations=[],this._previousTime=void 0}function d(e,t,r){var i=e._model,n=i._runtime.animations,o=n[t],a=new s(r,i,o);return e._scheduledAnimations.push(a),e.animationAdded.raiseEvent(i,a),a}function h(e,t){for(var r=e.channelEvaluators,i=r.length,n=0;n<i;++n)r[n](t)}function p(e,t,r){return function(){e.animationRemoved.raiseEvent(t,r)}}r(c.prototype,{length:{get:function(){return this._scheduledAnimations.length}}}),c.prototype.add=function(r){r=e(r,e.EMPTY_OBJECT);var i=this._model,n=i._runtime.animations;if(t(r.index))return d(this,r.index,r);for(var o,a=n.length,s=0;s<a;++s)if(n[s].name===r.name){o=s;break}return d(this,o,r)},c.prototype.addAll=function(t){t=e(t,e.EMPTY_OBJECT);for(var r=[],i=this._model,n=i._runtime.animations,o=n.length,a=0;a<o;++a)r.push(d(this,a,t));return r},c.prototype.remove=function(e){if(t(e)){var r=this._scheduledAnimations,i=r.indexOf(e);if(-1!==i)return r.splice(i,1),this.animationRemoved.raiseEvent(this._model,e),!0}return!1},c.prototype.removeAll=function(){var e=this._model,t=this._scheduledAnimations,r=t.length;this._scheduledAnimations=[];for(var i=0;i<r;++i)this.animationRemoved.raiseEvent(e,t[i])},c.prototype.contains=function(e){return!!t(e)&&-1!==this._scheduledAnimations.indexOf(e)},c.prototype.get=function(e){return this._scheduledAnimations[e]};var f=[];return c.prototype.update=function(r){var i=this._scheduledAnimations,n=i.length;if(0===n)return this._previousTime=void 0,!1;if(o.equals(r.time,this._previousTime))return!1;this._previousTime=o.clone(r.time,this._previousTime);for(var s=!1,c=r.time,d=this._model,m=0;m<n;++m){var g=i[m],_=g._runtimeAnimation;t(g._computedStartTime)||(g._computedStartTime=o.addSeconds(e(g.startTime,c),g.delay,new o)),t(g._duration)||(g._duration=_.stopTime*(1/g.speedup));var v=g._computedStartTime,y=g._duration,b=g.stopTime,C=0!==y?o.secondsDifference(c,v)/y:0,S=C>=0,w=g.loop===l.REPEAT||g.loop===l.MIRRORED_REPEAT;if((S||w&&!t(g.startTime))&&(C<=1||w)&&(!t(b)||o.lessThanOrEquals(c,b))){if(g._state===u.STOPPED&&(g._state=u.ANIMATING,g.start.numberOfListeners>0&&r.afterRender.push(g._raiseStartEvent)),g.loop===l.REPEAT)C-=Math.floor(C);else if(g.loop===l.MIRRORED_REPEAT){var T=Math.floor(C),E=C-T;C=T%2==1?1-E:E}g.reverse&&(C=1-C);var A=C*y*g.speedup;A=a.clamp(A,_.startTime,_.stopTime),h(_,A),g.update.numberOfListeners>0&&(g._updateEventTime=A,r.afterRender.push(g._raiseUpdateEvent)),s=!0}else S&&g._state===u.ANIMATING&&(g._state=u.STOPPED,g.stop.numberOfListeners>0&&r.afterRender.push(g._raiseStopEvent),g.removeOnStop&&f.push(g))}n=f.length;for(var x=0;x<n;++x){var P=f[x];i.splice(i.indexOf(P),1),r.afterRender.push(p(this,d,P))}return f.length=0,s},c}),define("Scene/ModelLoadResources",["../Core/Queue"],function(e){"use strict";function t(){this.vertexBuffersToCreate=new e,this.indexBuffersToCreate=new e,this.buffers={},this.pendingBufferLoads=0,this.programsToCreate=new e,this.shaders={},this.pendingShaderLoads=0,this.texturesToCreate=new e,this.pendingTextureLoads=0,this.texturesToCreateFromBufferView=new e,this.pendingBufferViewToImage=0,this.createSamplers=!0,this.createSkins=!0,this.createRuntimeAnimations=!0,this.createVertexArrays=!0,this.createRenderStates=!0,this.createUniformMaps=!0,this.createRuntimeNodes=!0,this.skinnedNodesIds=[]}function r(e,t,r){return e.subarray(t,t+r)}return t.prototype.getBuffer=function(e){return r(this.buffers[e.buffer],e.byteOffset,e.byteLength)},t.prototype.finishedPendingBufferLoads=function(){return 0===this.pendingBufferLoads},t.prototype.finishedBuffersCreation=function(){return 0===this.pendingBufferLoads&&0===this.vertexBuffersToCreate.length&&0===this.indexBuffersToCreate.length},t.prototype.finishedProgramCreation=function(){return 0===this.pendingShaderLoads&&0===this.programsToCreate.length},t.prototype.finishedTextureCreation=function(){var e=0===this.pendingTextureLoads,t=0===this.texturesToCreate.length&&0===this.texturesToCreateFromBufferView.length;return e&&t},t.prototype.finishedEverythingButTextureCreation=function(){var e=0===this.pendingBufferLoads&&0===this.pendingShaderLoads,t=0===this.vertexBuffersToCreate.length&&0===this.indexBuffersToCreate.length&&0===this.programsToCreate.length&&0===this.pendingBufferViewToImage;return e&&t},t.prototype.finished=function(){return this.finishedTextureCreation()&&this.finishedEverythingButTextureCreation()},t}),define("Scene/ModelMaterial",["../Core/defined","../Core/defineProperties","../Core/DeveloperError"],function(e,t,r){"use strict";function i(e,t,r){this._name=t.name,this._id=r,this._uniformMap=e._uniformMaps[r]}return t(i.prototype,{name:{get:function(){return this._name}},id:{get:function(){return this._id}}}),i.prototype.setValue=function(e,t){var r=this._uniformMap.values[e];r.value=r.clone(t,r.value)},i.prototype.getValue=function(t){var r=this._uniformMap.values[t];if(e(r))return r.value},i}),define("Scene/ModelMesh",["../Core/defineProperties"],function(e){"use strict";function t(e,t,r){for(var i=[],n=e.primitives,o=n.length,a=0;a<o;++a){var s=n[a];i[a]=t[s.material]}this._name=e.name,this._materials=i,this._id=r}return e(t.prototype,{name:{get:function(){return this._name}},id:{get:function(){return this._id}},materials:{get:function(){return this._materials}}}),t}),define("Scene/ModelNode",["../Core/defineProperties","../Core/Matrix4"],function(e,t){"use strict";function r(e,r,i,n,o){this._model=e,this._runtimeNode=i,this._name=r.name,this._id=n,this.useMatrix=!1,this._show=!0,this._matrix=t.clone(o)}return e(r.prototype,{name:{get:function(){return this._name}},id:{get:function(){return this._id}},show:{get:function(){return this._show},set:function(e){this._show!==e&&(this._show=e,this._model._perNodeShowDirty=!0)}},matrix:{get:function(){return this._matrix},set:function(e){this._matrix=t.clone(e,this._matrix),this.useMatrix=!0;var r=this._model;r._cesiumAnimationsDirty=!0,this._runtimeNode.dirtyNumber=r._maxDirtyNumber}}}),r.prototype.setMatrix=function(e){t.clone(e,this._matrix)},r}),define("Scene/ModelUtility",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/defined","../Core/defineProperties","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4","../Core/Quaternion","../Core/RuntimeError","../Core/WebGLConstants","../Renderer/ShaderSource","./AttributeType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e,t,r){var i=e.indexOf(t);return e.replace(new RegExp(t,"g"),function(e,t){return i===t?e:r})}function f(e,t){var r=e.accessors[t],n=r.extensions;if(i(n))return n.WEB3D_quantized_attributes}function m(e,t,r){var i=t.material,n=e.materials[i],o=n.technique,a=e.techniques[o];for(var s in a.parameters)if(a.parameters.hasOwnProperty(s)){var l=a.parameters[s].semantic;if(l===r){var u=a.attributes;for(var c in u)if(u.hasOwnProperty(c)){var d=u[c];if(d===s)return c}}}}function g(e){var t={value:e,clone:function(e,t){return e},func:function(){return t.value}};return t}function _(t){var r={value:e.fromArray(t),clone:e.clone,func:function(){return r.value}};return r}function v(e){var r={value:t.fromArray(e),clone:t.clone,func:function(){return r.value}};return r}function y(e){var t={value:r.fromArray(e),clone:r.clone,func:function(){return t.value}};return t}function b(e){var t={value:o.fromColumnMajorArray(e),clone:o.clone,func:function(){return t.value}};return t}function C(e){var t={value:a.fromColumnMajorArray(e),clone:a.clone,func:function(){return t.value}};return t}function S(e){var t={value:s.fromColumnMajorArray(e),clone:s.clone,func:function(){return t.value}};return t}function w(e,t,r){this._value=void 0,this._textureId=e.index,this._textures=t,this._defaultTexture=r}function T(e,t,r){var i=new w(e,t,r);return i.func=function(){return i.value},i}function E(e){return[e[0],e[1],e[2],e[3],e[5],e[6],e[7],e[8],e[10],e[11],e[12],e[13],e[15],e[16],e[17],e[18]]}function A(e){return[e[20],e[21],e[22],e[23]]}var x={};x.getAccessorMinMax=function(e,t){var r=e.accessors[t],n=r.extensions,o=r.min,a=r.max;if(i(n)){var s=n.WEB3D_quantized_attributes;i(s)&&(o=s.decodedMin,a=s.decodedMax)}return{min:o,max:a}},x.getAttributeOrUniformBySemantic=function(e,t,r){var n,o=e.techniques;for(var a in o)if(o.hasOwnProperty(a)){var s=o[a];if(i(r)&&s.program!==r)continue;var l=s.parameters,u=s.attributes,c=s.uniforms;for(var d in u)if(u.hasOwnProperty(d)&&(n=l[u[d]],i(n)&&n.semantic===t))return d;for(var h in c)if(c.hasOwnProperty(h)&&(n=l[c[h]],i(n)&&n.semantic===t))return h}},x.getDiffuseAttributeOrUniform=function(e,t){var r=x.getAttributeOrUniformBySemantic(e,"COLOR_0",t);return i(r)||(r=x.getAttributeOrUniformBySemantic(e,"_3DTILESDIFFUSE",t)),r};var P=new t,D=new l,I=new t;x.getTransform=function(e,r){return i(e.matrix)?s.fromColumnMajorArray(e.matrix,r):s.fromTranslationQuaternionRotationScale(t.fromArray(e.translation,0,P),l.unpack(e.rotation,0,D),t.fromArray(e.scale,0,I),r)},x.getUsedExtensions=function(e){var t=e.extensionsUsed,r={};if(i(t))for(var n=t.length,o=0;o<n;o++){var a=t[o];r[a]=!0}return r},x.getRequiredExtensions=function(e){var t=e.extensionsRequired,r={};if(i(t))for(var n=t.length,o=0;o<n;o++){var a=t[o];r[a]=!0}return r},x.checkSupportedExtensions=function(e){for(var t in e)if(e.hasOwnProperty(t)&&"CESIUM_RTC"!==t&&"KHR_technique_webgl"!==t&&"KHR_binary_glTF"!==t&&"KHR_materials_common"!==t&&"WEB3D_quantized_attributes"!==t)throw new u("Unsupported glTF Extension: "+t)},x.checkSupportedGlExtensions=function(e,t){if(i(e))for(var r=e.length,n=0;n<r;n++){var o=e[n];if("OES_element_index_uint"!==o)throw new u("Unsupported WebGL Extension: "+o);if(!t.elementIndexUint)throw new u("OES_element_index_uint WebGL extension is not enabled.")}},x.modifyShaderForQuantizedAttributes=function(e,t,r){var n={},o=t.attributes;for(var a in o)if(o.hasOwnProperty(a)){var s=m(e,t,a),l=t.attributes[a];"_"===a.charAt(0)&&(a=a.substring(1));var u="gltf_u_dec_"+a.toLowerCase(),c=u+"_scale",h=u+"_translate";if(!i(n[u])&&!i(n[c])){var g=f(e,l);if(i(g)){var _=g.decodeMatrix,v="gltf_decoded_"+a,y=s.replace("a_","gltf_a_dec_"),b=Math.floor(Math.sqrt(_.length));r=p(r,s,y);var C;C=b>2?"vec"+(b-1):"float",r=C+" "+y+";\n"+r;var S="";5===b?(r="uniform mat4 "+c+";\n"+r,r="uniform vec4 "+h+";\n"+r,S="\nvoid main() {\n "+y+" = "+c+" * "+s+" + "+h+";\n "+v+"();\n}\n",n[c]={mat:4},n[h]={vec:4}):(r="uniform mat"+b+" "+u+";\n"+r,S="\nvoid main() {\n "+y+" = "+C+"("+u+" * vec"+b+"("+s+",1.0));\n "+v+"();\n}\n",n[u]={mat:b}),r=d.replaceMain(r,v),r+=S}}}return{shader:r,uniforms:n}},n(w.prototype,{value:{get:function(){if(!i(this._value)){var e=this._textures[this._textureId];if(!i(e))return this._defaultTexture;this._value=e}return this._value},set:function(e){this._value=e}}}),w.prototype.clone=function(e){return e},w.prototype.func=void 0;var O={};O[c.FLOAT]=g,O[c.FLOAT_VEC2]=_,O[c.FLOAT_VEC3]=v,O[c.FLOAT_VEC4]=y,O[c.INT]=g,O[c.INT_VEC2]=_,O[c.INT_VEC3]=v,O[c.INT_VEC4]=y,O[c.BOOL]=g,O[c.BOOL_VEC2]=_,O[c.BOOL_VEC3]=v,O[c.BOOL_VEC4]=y,O[c.FLOAT_MAT2]=b,O[c.FLOAT_MAT3]=C,O[c.FLOAT_MAT4]=S,O[c.SAMPLER_2D]=T,x.createUniformFunction=function(e,t,r,i){return O[e](t,r,i)},x.createUniformsForQuantizedAttributes=function(e,t,r){var n=e.accessors,l={},u={},c=t.attributes;for(var d in c)if(c.hasOwnProperty(d)){var p=c[d],f=n[p],m=f.extensions;if("_"===d.charAt(0)&&(d=d.substring(1)),i(m)){var g=m.WEB3D_quantized_attributes;if(i(g)){var _=g.decodeMatrix,v="gltf_u_dec_"+d.toLowerCase();switch(f.type){case h.SCALAR:u[v]=b(_).func,l[v]=!0;break;case h.VEC2:u[v]=C(_).func,l[v]=!0;break;case h.VEC3:u[v]=S(_).func,l[v]=!0;break;case h.VEC4:var w=v+"_scale",T=v+"_translate";u[w]=S(E(_)).func,u[T]=y(A(_)).func,l[w]=!0,l[T]=!0}}}}for(var x in r)if(r.hasOwnProperty(x)&&!l[x]){var P=r[x];i(P.mat)&&(2===P.mat?u[x]=b(o.IDENTITY).func:3===P.mat?u[x]=C(a.IDENTITY).func:4===P.mat&&(u[x]=S(s.IDENTITY).func)),i(P.vec)&&4===P.vec&&(u[x]=y([0,0,0,0]).func)}return u};var M=new t,R={MODEL:function(e,t){return function(){return e.model}},VIEW:function(e,t){return function(){return e.view}},PROJECTION:function(e,t){return function(){return e.projection}},MODELVIEW:function(e,t){return function(){return e.modelView}},CESIUM_RTC_MODELVIEW:function(e,r){var n=new s;return function(){return i(r._rtcCenter)?(s.getTranslation(e.model,M),t.add(M,r._rtcCenter,M),s.multiplyByPoint(e.view,M,M),s.setTranslation(e.modelView,M,n)):e.modelView}},MODELVIEWPROJECTION:function(e,t){return function(){return e.modelViewProjection}},MODELINVERSE:function(e,t){return function(){return e.inverseModel}},VIEWINVERSE:function(e,t){return function(){return e.inverseView}},PROJECTIONINVERSE:function(e,t){return function(){return e.inverseProjection}},MODELVIEWINVERSE:function(e,t){return function(){return e.inverseModelView}},MODELVIEWPROJECTIONINVERSE:function(e,t){return function(){return e.inverseModelViewProjection}},MODELINVERSETRANSPOSE:function(e,t){return function(){return e.inverseTransposeModel}},MODELVIEWINVERSETRANSPOSE:function(e,t){return function(){return e.normal}},VIEWPORT:function(e,t){return function(){return e.viewportCartesian4}}};return x.getGltfSemanticUniforms=function(){return R},x}),define("Scene/Model",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/ClippingPlaneCollection","../Core/clone","../Core/Color","../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/FeatureDetection","../Core/getAbsoluteUri","../Core/getMagic","../Core/getStringFromTypedArray","../Core/IndexDatatype","../Core/loadCRN","../Core/loadImageFromTypedArray","../Core/loadKTX","../Core/Math","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4","../Core/PixelFormat","../Core/Plane","../Core/PrimitiveType","../Core/Resource","../Core/Quaternion","../Core/Queue","../Core/RuntimeError","../Core/Transforms","../Core/WebGLConstants","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/Sampler","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Renderer/VertexArray","../ThirdParty/GltfPipeline/addDefaults","../ThirdParty/GltfPipeline/addPipelineExtras","../ThirdParty/GltfPipeline/ForEach","../ThirdParty/GltfPipeline/getAccessorByteStride","../ThirdParty/GltfPipeline/numberOfComponentsForType","../ThirdParty/GltfPipeline/parseBinaryGltf","../ThirdParty/GltfPipeline/processModelMaterialsCommon","../ThirdParty/GltfPipeline/processPbrMetallicRoughness","../ThirdParty/GltfPipeline/updateVersion","../ThirdParty/Uri","../ThirdParty/when","./AttributeType","./Axis","./BlendingState","./ColorBlendMode","./HeightReference","./JobType","./ModelAnimationCache","./ModelAnimationCollection","./ModelLoadResources","./ModelMaterial","./ModelMesh","./ModelNode","./ModelUtility","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,be){"use strict";function Ce(e,t){e._cachedGltf=t}function Se(e){this._gltf=e.gltf,this.ready=e.ready,this.modelsToLoad=[],this.count=0}function we(t){t=u(t,u.EMPTY_OBJECT);var r=t.cacheKey;this._cacheKey=r,this._cachedGltf=void 0,this._releaseGltfJson=u(t.releaseGltfJson,!1);var i;if(c(r)&&c(hr[r])&&hr[r].ready)i=hr[r],++i.count;else{var n=t.gltf;if(c(n)){if(n instanceof ArrayBuffer&&(n=new Uint8Array(n)),n instanceof Uint8Array){i=new Se({gltf:ee(n),ready:!0})}else i=new Se({gltf:t.gltf,ready:!0});i.count=1,c(r)&&(hr[r]=i)}}Ce(this,i);var o=u(t.basePath,"");this._resource=O.createIfNeeded(o),this.show=u(t.show,!0),this.silhouetteColor=u(t.silhouetteColor,s.RED),this._silhouetteColor=new s,this._silhouetteColorPreviousAlpha=1,this._normalAttributeName=void 0,this.silhouetteSize=u(t.silhouetteSize,0),this.modelMatrix=x.clone(u(t.modelMatrix,x.IDENTITY)),this._modelMatrix=x.clone(this.modelMatrix),this._clampedModelMatrix=void 0,this.scale=u(t.scale,1),this._scale=this.scale,this.minimumPixelSize=u(t.minimumPixelSize,0),this._minimumPixelSize=this.minimumPixelSize,this.maximumScale=t.maximumScale,this._maximumScale=this.maximumScale,this.id=t.id,this._id=t.id,this.heightReference=u(t.heightReference,ce.NONE),this._heightReference=this.heightReference,this._heightChanged=!1,this._removeUpdateHeightCallback=void 0;var a=t.scene;this._scene=a,c(a)&&c(a.terrainProviderChanged)&&(this._terrainProviderChangedCallback=a.terrainProviderChanged.addEventListener(function(){this._heightChanged=!0},this)),this._pickObject=t.pickObject,this._allowPicking=u(t.allowPicking,!0),this._ready=!1,this._readyPromise=oe.defer(),this.activeAnimations=new pe(this),this.clampAnimations=u(t.clampAnimations,!0),this._defaultTexture=void 0,this._incrementallyLoadTextures=u(t.incrementallyLoadTextures,!0),this._asynchronous=u(t.asynchronous,!0),this.shadows=u(t.shadows,be.ENABLED),this._shadows=this.shadows,this.color=u(t.color,s.WHITE),this._color=new s,this._colorPreviousAlpha=1,this.colorBlendMode=u(t.colorBlendMode,ue.HIGHLIGHT),this.colorBlendAmount=u(t.colorBlendAmount,.5),this.clippingPlanes=t.clippingPlanes,this.debugShowBoundingVolume=u(t.debugShowBoundingVolume,!1),this._debugShowBoundingVolume=!1,this.debugWireframe=u(t.debugWireframe,!1),this._debugWireframe=!1,this._distanceDisplayCondition=t.distanceDisplayCondition,this._addBatchIdToGeneratedShaders=t.addBatchIdToGeneratedShaders,this._precreatedAttributes=t.precreatedAttributes,this._vertexShaderLoaded=t.vertexShaderLoaded,this._fragmentShaderLoaded=t.fragmentShaderLoaded,this._uniformMapLoaded=t.uniformMapLoaded,this._pickVertexShaderLoaded=t.pickVertexShaderLoaded,this._pickFragmentShaderLoaded=t.pickFragmentShaderLoaded,this._pickUniformMapLoaded=t.pickUniformMapLoaded,this._ignoreCommands=u(t.ignoreCommands,!1),this._requestType=t.requestType,this._upAxis=u(t.upAxis,se.Y),this.cull=u(t.cull,!0),this.opaquePass=u(t.opaquePass,V.OPAQUE),this._computedModelMatrix=new x,this._modelViewMatrix=x.clone(x.IDENTITY),this._initialRadius=void 0,this._boundingSphere=void 0,this._scaledBoundingSphere=new e,this._state=dr.NEEDS_LOAD,this._loadResources=void 0,this._mode=void 0,this._perNodeShowDirty=!1,this._cesiumAnimationsDirty=!1,this._dirty=!1,this._maxDirtyNumber=0,this._runtime={animations:void 0,rootNodes:void 0,nodes:void 0,nodesByName:void 0,skinnedNodes:void 0,meshesByName:void 0,materialsByName:void 0,materialsById:void 0},this._uniformMaps={},this._extensionsUsed=void 0,this._extensionsRequired=void 0,this._quantizedUniforms={},this._programPrimitives={},this._rendererResources={buffers:{},vertexArrays:{},programs:{},pickPrograms:{},silhouettePrograms:{},textures:{},samplers:{},renderStates:{}},this._cachedRendererResources=void 0,this._loadRendererResourcesFromCache=!1,this._updatedGltfVersion=!1,this._cachedGeometryByteLength=0,this._cachedTexturesByteLength=0,this._geometryByteLength=0,this._texturesByteLength=0,this._trianglesLength=0,this._nodeCommands=[],this._pickIds=[],this._rtcCenter=void 0,this._rtcCenterEye=void 0,this._rtcCenter3D=void 0,this._rtcCenter2D=void 0,this._packedClippingPlanes=[]}function Te(e){return e.stencilBuffer}function Ee(e){return"glTF"===v(e)}function Ae(e,t,r){return e._runtime[t][r]}function xe(t){for(var i=t.gltf,n=i.nodes,o=i.meshes,a=i.scenes[i.scene].nodes,s=a.length,l=[],u=new r(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE),d=new r(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),h=0;h<s;++h){var p=n[a[h]];for(p._transformToRoot=ve.getTransform(p),l.push(p);l.length>0;){p=l.pop();var f=p._transformToRoot,m=p.mesh;if(c(m))for(var g=o[m],_=g.primitives,v=_.length,y=0;y<v;++y){var b=_[y].attributes.POSITION;if(c(b)){var C=ve.getAccessorMinMax(i,b),S=r.fromArray(C.min,0,pr),w=r.fromArray(C.max,0,fr);c(u)&&c(d)&&(x.multiplyByPoint(f,S,S),x.multiplyByPoint(f,w,w),r.minimumByComponent(u,S,u),r.maximumByComponent(d,w,d))}}for(var T=p.children,E=T.length,A=0;A<E;++A){var P=n[T[A]];P._transformToRoot=ve.getTransform(P),x.multiplyTransformation(f,P._transformToRoot,P._transformToRoot),l.push(P)}delete p._transformToRoot}}var D=e.fromCornerPoints(u,d);return t._upAxis===se.Y?e.transformWithoutScale(D,se.Y_UP_TO_Z_UP,D):t._upAxis===se.X&&e.transformWithoutScale(D,se.X_UP_TO_Z_UP,D),D}function Pe(e,t,r){return function(){e._state=dr.FAILED,e._readyPromise.reject(new L("Failed to load "+t+": "+r))}}function De(e){var t=e.gltf,r=e._loadResources;K.buffer(t,function(e,t){r.buffers[t]=e.extras._pipeline.source})}function Ie(e,t){return function(r){var i=e._loadResources,n=new Uint8Array(r);--i.pendingBufferLoads,e.gltf.buffers[t].extras._pipeline.source=n}}function Oe(e){var t=e._loadResources,r=e.gltf.buffers;for(var i in r)if(r.hasOwnProperty(i)){var n=r[i];if(n.extras=u(n.extras,{}),n.extras._pipeline=u(n.extras._pipeline,{}),c(n.extras._pipeline.source))t.buffers[i]=n.extras._pipeline.source;else{var o=e._resource.getDerivedResource({url:n.uri});++t.pendingBufferLoads,o.fetchArrayBuffer().then(Ie(e,i)).otherwise(Pe(e,"buffer",o.url))}}}function Me(e){var t=e.gltf.bufferViews,r=e._loadResources.vertexBuffersToCreate;K.bufferView(e.gltf,function(e,t){e.target===k.ARRAY_BUFFER&&r.enqueue(t)});var i=e._loadResources.indexBuffersToCreate,n={};K.accessor(e.gltf,function(e){var r=e.bufferView;t[r].target!==k.ELEMENT_ARRAY_BUFFER||c(n[r])||(n[r]=!0,i.enqueue({id:r,componentType:e.componentType}))})}function Re(e,t,r){return function(i){var n=e._loadResources;n.shaders[r]={source:i,type:t,bufferView:void 0},--n.pendingShaderLoads,e.gltf.shaders[r].extras._pipeline.source=i}}function Le(e){var t=e.gltf,r=t.buffers,i=t.bufferViews;K.shader(t,function(t,n){if(c(t.bufferView)){var o=t.bufferView,a=i[o],s=a.buffer,l=r[s],u=y(l.extras._pipeline.source,a.byteOffset,a.byteLength);e._loadResources.shaders[n]={source:u,bufferView:void 0},t.extras._pipeline.source=u}else if(c(t.extras._pipeline.source))e._loadResources.shaders[n]={source:t.extras._pipeline.source,bufferView:void 0};else{++e._loadResources.pendingShaderLoads;var d=e._resource.getDerivedResource({url:t.uri});d.fetchText().then(Re(e,t.type,n)).otherwise(Pe(e,"shader",d.url))}})}function Ne(e){K.program(e.gltf,function(t,r){e._loadResources.programsToCreate.enqueue(r)})}function ke(e,t,r){return function(i){var n=e.gltf,o=e._loadResources;--o.pendingTextureLoads,o.texturesToCreate.enqueue({id:t,image:i,bufferView:i.bufferView,width:i.width,height:i.height,internalFormat:i.internalFormat}),n.images[r].extras._pipeline.source=i}}function Fe(e,t){var r,i=e.gltf,n=i.images;K.texture(i,function(i,o){var a=i.source,s=n[a],l=s.extras,u=s.bufferView,d=s.mimeType;if(r=s.uri,c(l)&&c(l.compressedImage3DTiles)){var h=l.compressedImage3DTiles.crunch,p=l.compressedImage3DTiles.s3tc,f=l.compressedImage3DTiles.pvrtc1,m=l.compressedImage3DTiles.etc1;t.s3tc&&c(h)?(d=h.mimeType,c(h.bufferView)?u=h.bufferView:r=h.uri):t.s3tc&&c(p)?(d=p.mimeType,c(p.bufferView)?u=p.bufferView:r=p.uri):t.pvrtc&&c(f)?(d=f.mimeType,c(f.bufferView)?u=f.bufferView:r=f.uri):t.etc1&&c(m)&&(d=m.mimeType,c(m.bufferView)?u=m.bufferView:r=m.uri)}if(c(u))e._loadResources.texturesToCreateFromBufferView.enqueue({id:o,image:void 0,bufferView:u,mimeType:d});else{++e._loadResources.pendingTextureLoads;var g,_=e._resource.getDerivedResource({url:r});g=mr.test(r)?w(_):gr.test(r)?C(_):_.fetchImage(),g.then(ke(e,o,a)).otherwise(Pe(e,"image",_.url))}})}function Be(e){var t={},r={},i=[],n=e._loadResources.skinnedNodesIds;K.node(e.gltf,function(o,a){var s={matrix:void 0,translation:void 0,rotation:void 0,scale:void 0,computedShow:!0,transformToRoot:new x,computedMatrix:new x,dirtyNumber:0,commands:[],inverseBindMatrices:void 0,bindShapeMatrix:void 0,joints:[],computedJointMatrices:[],jointName:o.jointName,weights:[],children:[],parents:[],publicNode:void 0};s.publicNode=new _e(e,o,s,a,ve.getTransform(o)),t[a]=s,r[o.name]=s,c(o.skin)&&(n.push(a),i.push(s))}),e._runtime.nodes=t,e._runtime.nodesByName=r,e._runtime.skinnedNodes=i}function Ue(e){var t={},r={},i=e._uniformMaps;K.material(e.gltf,function(n,o){i[o]={uniformMap:void 0,values:void 0,jointMatrixUniformName:void 0,morphWeightsUniformName:void 0};var a=new me(e,n,o);t[n.name]=a,r[o]=a}),e._runtime.materialsByName=t,e._runtime.materialsById=r}function Ve(e){var t={},r=e._runtime.materialsById;K.mesh(e.gltf,function(i,n){if(t[i.name]=new ge(i,r,n),c(e.extensionsUsed.WEB3D_quantized_attributes))for(var o=i.primitives,a=o.length,s=0;s<a;s++){var l=o[s],u=je(e,l),d=e._programPrimitives[u];c(d)||(d=[],e._programPrimitives[u]=d),d.push(l)}}),e._runtime.meshesByName=t}function ze(e,t,r){var i=t._loadResources,n=t.gltf.bufferViews,o=n[e],a=F.createVertexBuffer({context:r,typedArray:i.getBuffer(o),usage:B.STATIC_DRAW});a.vertexArrayDestroyable=!1,t._rendererResources.buffers[e]=a,t._geometryByteLength+=a.sizeInBytes}function Ge(e,t,r,i){var n=r._loadResources,o=r.gltf.bufferViews,a=o[e],s=F.createIndexBuffer({context:i,typedArray:n.getBuffer(a),usage:B.STATIC_DRAW,indexDatatype:t});s.vertexArrayDestroyable=!1,r._rendererResources.buffers[e]=s,r._geometryByteLength+=s.sizeInBytes}function We(e,t){var r=e._loadResources;if(0===r.pendingBufferLoads){var i,n=t.context,o=r.vertexBuffersToCreate,a=r.indexBuffersToCreate;if(e.asynchronous){for(;o.length>0&&(yr.set(o.peek(),e,n),t.jobScheduler.execute(yr,de.BUFFER));)o.dequeue();for(;a.length>0&&(i=a.peek(),br.set(i.id,i.componentType,e,n),t.jobScheduler.execute(br,de.BUFFER));)a.dequeue()}else{for(;o.length>0;)ze(o.dequeue(),e,n);for(;a.length>0;)i=a.dequeue(),Ge(i.id,i.componentType,e,n)}}}function He(e,t){var r,i={},n=t.length;for(r=1;r<n;++r){var o=t[r];if(/pos/i.test(o)){t[r]=t[0],t[0]=o;break}}for(r=0;r<n;++r)i[t[r]]=r;return i}function je(e,t){var r=e.gltf,i=t.material,n=r.materials[i],o=n.technique;return r.techniques[o].program}function qe(e,t,r){for(var i,n=r._programPrimitives[t],o=0;o<n.length&&(i=n[o],je(r,i)!==t);o++);var a=ve.modifyShaderForQuantizedAttributes(r.gltf,i,e);return r._quantizedUniforms[t]=a.uniforms,r._programPrimitives[t]=void 0,a.shader}function Ye(e){var t=e.gltf;return!!c(t.asset)&&u(t.asset.premultipliedAlpha,!1)}function Xe(e,t){return e=H.replaceMain(e,"gltf_blend_main"),e+="uniform vec4 gltf_color; \nuniform float gltf_colorBlend; \nvoid main() \n{ \n gltf_blend_main(); \n",t&&(e+=" float alpha = 1.0 - ceil(gl_FragColor.a) + gl_FragColor.a; \n gl_FragColor.rgb /= alpha; \n"),e+=" gl_FragColor.rgb = mix(gl_FragColor.rgb, gltf_color.rgb, gltf_colorBlend); \n float highlight = ceil(gltf_colorBlend); \n gl_FragColor.rgb *= mix(gltf_color.rgb, vec3(1.0), highlight); \n gl_FragColor.a *= gltf_color.a; \n} \n"}function Qe(e,t,r){return c(r)&&(e=r(e,t)),e}function Ze(e,t,r){var i=t.gltf.programs,n=t.gltf.shaders,a=i[e],s=He(t,a.attributes),l=n[a.vertexShader].extras._pipeline.source,u=n[a.fragmentShader].extras._pipeline.source,d=a.attributes.length,h=t._precreatedAttributes;if(c(h))for(var p in h)h.hasOwnProperty(p)&&(s[p]=d++);t.extensionsUsed.WEB3D_quantized_attributes&&(l=qe(l,e,t));var f=Ye(t),m=Xe(u,f);o.isSupported()&&(m=Jt(m));var g=Qe(l,e,t._vertexShaderLoaded),_=Qe(m,e,t._fragmentShaderLoaded);if(t._rendererResources.programs[e]=W.fromCache({context:r,vertexShaderSource:g,fragmentShaderSource:_,attributeLocations:s}),t.allowPicking){var v=Qe(l,e,t._pickVertexShaderLoaded),y=Qe(u,e,t._pickFragmentShaderLoaded);t._pickFragmentShaderLoaded||(y=H.createPickFragmentShaderSource(u,"uniform")),t._rendererResources.pickPrograms[e]=W.fromCache({context:r,vertexShaderSource:v,fragmentShaderSource:y,attributeLocations:s})}}function Ke(e,t){var r=e._loadResources,i=r.programsToCreate;if(0===r.pendingShaderLoads&&0===r.pendingBufferLoads){var n=t.context;if(e.asynchronous)for(;i.length>0&&(Sr.set(i.peek(),e,n),t.jobScheduler.execute(Sr,de.PROGRAM));)i.dequeue();else for(;i.length>0;)Ze(i.dequeue(),e,n)}}function Je(e,t){return function(r){e.texturesToCreate.enqueue({id:t.id,image:r,bufferView:void 0}),--e.pendingBufferViewToImage}}function $e(e){var t=e._loadResources;if(0===t.pendingBufferLoads)for(;t.texturesToCreateFromBufferView.length>0;){var r=t.texturesToCreateFromBufferView.dequeue(),i=e.gltf,n=i.bufferViews[r.bufferView],o=i.textures[r.id].source,a=Pe(e,"image","id: "+r.id+", bufferView: "+r.bufferView);if("image/ktx"===r.mimeType)w(t.getBuffer(n)).then(ke(e,r.id,o)).otherwise(a),++e._loadResources.pendingTextureLoads;else if("image/crn"===r.mimeType)C(t.getBuffer(n)).then(ke(e,r.id,o)).otherwise(a),++e._loadResources.pendingTextureLoads;else{var s=Je(t,r) +;S(t.getBuffer(n),r.mimeType).then(s).otherwise(a),++t.pendingBufferViewToImage}}}function et(e,t){var r=e._loadResources;if(r.createSamplers){r.createSamplers=!1;var i=e._rendererResources.samplers,n=e.gltf.samplers;for(var o in n)if(n.hasOwnProperty(o)){var a=n[o];i[o]=new G({wrapS:a.wrapS,wrapT:a.wrapT,minificationFilter:a.minFilter,magnificationFilter:a.magFilter})}}}function tt(e,t,r){var i=t.gltf.textures,n=i[e.id],o=t._rendererResources.samplers,a=o[n.sampler];a=u(a,new G({wrapS:Y.REPEAT,wrapT:Y.REPEAT}));var s,l=e.internalFormat,d=!(c(l)&&P.isCompressedFormat(l)||a.minificationFilter!==q.NEAREST_MIPMAP_NEAREST&&a.minificationFilter!==q.NEAREST_MIPMAP_LINEAR&&a.minificationFilter!==q.LINEAR_MIPMAP_NEAREST&&a.minificationFilter!==q.LINEAR_MIPMAP_LINEAR),h=d||a.wrapS===Y.REPEAT||a.wrapS===Y.MIRRORED_REPEAT||a.wrapT===Y.REPEAT||a.wrapT===Y.MIRRORED_REPEAT,p=e.image;if(c(l)&&n.target===k.TEXTURE_2D)s=new j({context:r,source:{arrayBufferView:e.bufferView},width:e.width,height:e.height,pixelFormat:l,sampler:a});else if(c(p)){var f=!T.isPowerOfTwo(p.width)||!T.isPowerOfTwo(p.height);if(h&&f){var m=document.createElement("canvas");m.width=T.nextPowerOfTwo(p.width),m.height=T.nextPowerOfTwo(p.height);var g=m.getContext("2d");g.drawImage(p,0,0,p.width,p.height,0,0,m.width,m.height),p=m}n.target===k.TEXTURE_2D&&(s=new j({context:r,source:p,pixelFormat:n.internalFormat,pixelDatatype:n.type,sampler:a,flipY:!1}),d&&s.generateMipmap())}c(s)&&(t._rendererResources.textures[e.id]=s,t._texturesByteLength+=s.sizeInBytes)}function rt(e,t){var r=t.context,i=e._loadResources.texturesToCreate;if(e.asynchronous)for(;i.length>0&&(Tr.set(i.peek(),e,r),t.jobScheduler.execute(Tr,de.TEXTURE));)i.dequeue();else for(;i.length>0;)tt(i.dequeue(),e,r)}function it(e,t){var r,i,n=e.gltf,o=n.techniques,a=n.materials,s={},l=o[a[t.material].technique],u=l.parameters,d=l.attributes,h=e._rendererResources.programs[l.program],p=h.vertexAttributes,f=h._attributeLocations;for(r in p)if(p.hasOwnProperty(r)){var m=d[r];if(i=p[r].index,c(m)){var g=u[m];s[g.semantic]=i}}var _=e._precreatedAttributes;if(c(_))for(r in _)_.hasOwnProperty(r)&&(i=f[r],s[r]=i);return s}function nt(e,t){for(var r=e.length,i={},n=0;n<r;++n)for(var o=[e[n]];o.length>0;){var a=o.pop(),s=t[a];c(s)&&(i[a]=a);for(var l=s.children,u=l.length,d=0;d<u;++d)o.push(l[d])}return i}function ot(e,t){for(var r=e.gltf,i=r.skins,n=r.nodes,o=e._runtime.nodes,a=e._loadResources.skinnedNodesIds,s=a.length,l=0;l<s;++l){var u=a[l],d=o[u],h=n[u],p=t[h.skin];d.inverseBindMatrices=p.inverseBindMatrices,d.bindShapeMatrix=p.bindShapeMatrix;var f=[],m=i[h.skin];c(m.skeleton)&&f.push(m.skeleton);for(var g=nt(f,n),_=i[h.skin].joints,v=_.length,y=0;y<v;++y){var b=_[y],C=g[b],S=o[C];d.joints.push(S)}}}function at(e){var t=e._loadResources;if(0===t.pendingBufferLoads&&t.createSkins){t.createSkins=!1;var r=e.gltf,i=r.accessors,n={};K.skin(r,function(t,r){var o,a=i[t.inverseBindMatrices];x.equals(t.bindShapeMatrix,x.IDENTITY)||(o=x.clone(t.bindShapeMatrix)),n[r]={inverseBindMatrices:he.getSkinInverseBindMatrices(e,a),bindShapeMatrix:o}}),ot(e,n)}}function st(e,t,r,i){return function(n){c(i)&&(n=e.clampAnimations?i.clampTime(n):i.wrapTime(n),t[r]=i.evaluate(n,t[r]),t.dirtyNumber=e._maxDirtyNumber)}}function lt(e){var t=e._loadResources;if(t.finishedPendingBufferLoads()&&t.createRuntimeAnimations){t.createRuntimeAnimations=!1,e._runtime.animations=[];for(var r=e._runtime.nodes,i=e.gltf.animations,n=e.gltf.accessors,o=i.length,a=0;a<o;++a){for(var s=i[a],l=s.channels,u=s.samplers,c=Number.MAX_VALUE,d=-Number.MAX_VALUE,h=l.length,p=new Array(h),f=0;f<h;++f){var m=l[f],g=m.target,_=g.path,v=u[m.sampler],y=he.getAnimationParameterValues(e,n[v.input]),b=he.getAnimationParameterValues(e,n[v.output]);c=Math.min(c,y[0]),d=Math.max(d,y[y.length-1]);var C=he.getAnimationSpline(e,a,s,m.sampler,v,y,_,b);p[f]=st(e,r[g.node],g.path,C)}e._runtime.animations[a]={name:s.name,startTime:c,stopTime:d,channelEvaluators:p}}}}function ut(e,t){var r=e._loadResources;if(r.finishedBuffersCreation()&&r.finishedProgramCreation()&&r.createVertexArrays){r.createVertexArrays=!1;var i=e._rendererResources.buffers,n=e._rendererResources.vertexArrays,o=e.gltf,a=o.accessors,s=o.meshes;for(var l in s)if(s.hasOwnProperty(l))for(var u=s[l].primitives,d=u.length,h=0;h<d;++h){var p,f,m,g=u[h],_=it(e,g),v=[],y=g.attributes;for(p in y)if(y.hasOwnProperty(p)&&(f=_[p],c(f))){var b=a[y[p]],C=!1;c(b.normalized)&&b.normalized&&(C=!0),v.push({index:f,vertexBuffer:i[b.bufferView],componentsPerAttribute:$(b.type),componentDatatype:b.componentType,normalize:C,offsetInBytes:b.byteOffset,strideInBytes:J(o,b)})}var S=e._precreatedAttributes;if(c(S))for(p in S)S.hasOwnProperty(p)&&(f=_[p],c(f)&&(m=S[p],m.index=f,v.push(m)));var w;if(c(g.indices)){var T=a[g.indices];w=i[T.bufferView]}n[l+".primitive."+h]=new X({context:t,attributes:v,indexBuffer:w})}}}function ct(e){var t={};t[k.BLEND]=!1,t[k.CULL_FACE]=!1,t[k.DEPTH_TEST]=!1,t[k.POLYGON_OFFSET_FILL]=!1;var r,i=e.enable,n=i.length;for(r=0;r<n;++r)t[i[r]]=!0;return t}function dt(e,t){var r=e._loadResources,i=e.gltf.techniques;if(r.createRenderStates){r.createRenderStates=!1;for(var n in i)i.hasOwnProperty(n)&&ht(e,n,t)}}function ht(e,t,r){var i=e._rendererResources.renderStates,n=e.gltf.techniques,o=n[t],a=o.states,s=ct(a),l=u(a.functions,u.EMPTY_OBJECT),d=u(l.blendColor,[0,0,0,0]),h=u(l.blendEquationSeparate,[k.FUNC_ADD,k.FUNC_ADD]),p=u(l.blendFuncSeparate,[k.ONE,k.ZERO,k.ONE,k.ZERO]),f=u(l.colorMask,[!0,!0,!0,!0]),m=u(l.depthRange,[0,1]),g=u(l.polygonOffset,[0,0]);s[k.BLEND]&&Ye(e)&&p[0]===k.ONE&&p[1]===k.ONE_MINUS_SRC_ALPHA&&(p[0]=k.SRC_ALPHA,p[1]=k.ONE_MINUS_SRC_ALPHA,p[2]=k.SRC_ALPHA,p[3]=k.ONE_MINUS_SRC_ALPHA),i[t]=z.fromCache({frontFace:c(l.frontFace)?l.frontFace[0]:k.CCW,cull:{enabled:s[k.CULL_FACE],face:c(l.cullFace)?l.cullFace[0]:k.BACK},lineWidth:c(l.lineWidth)?l.lineWidth[0]:1,polygonOffset:{enabled:s[k.POLYGON_OFFSET_FILL],factor:g[0],units:g[1]},depthRange:{near:m[0],far:m[1]},depthTest:{enabled:s[k.DEPTH_TEST],func:c(l.depthFunc)?l.depthFunc[0]:k.LESS},colorMask:{red:f[0],green:f[1],blue:f[2],alpha:f[3]},depthMask:!c(l.depthMask)||l.depthMask[0],blending:{enabled:s[k.BLEND],color:{red:d[0],green:d[1],blue:d[2],alpha:d[3]},equationRgb:h[0],equationAlpha:h[1],functionSourceRgb:p[0],functionDestinationRgb:p[1],functionSourceAlpha:p[2],functionDestinationAlpha:p[3]}})}function pt(e,t,r,i){var n=t._runtime.nodes[e];return Er[r](i,t,n)}function ft(e,t){var r=e._loadResources;if(r.finishedProgramCreation()&&r.createUniformMaps){r.createUniformMaps=!1;var i=e.gltf,n=i.materials,o=i.techniques,a=e._uniformMaps,s=e._rendererResources.textures,l=e._defaultTexture;for(var u in n)if(n.hasOwnProperty(u)){var d,h=n[u];d=h.values;var p,f,m=o[h.technique],g=m.parameters,_=m.uniforms,v={},y={};for(var b in _)if(_.hasOwnProperty(b)&&"extras"!==b){var C=_[b],S=g[C];if(c(d[C])){var w=ve.createUniformFunction(S.type,d[C],s,l);v[b]=w.func,y[C]=w}else if(c(S.node))v[b]=pt(S.node,e,S.semantic,t.uniformState);else if(c(S.semantic))"JOINTMATRIX"===S.semantic?p=b:"MORPHWEIGHTS"===S.semantic?f=b:v[b]=ve.getGltfSemanticUniforms()[S.semantic](t.uniformState,e);else if(c(S.value)){var T=ve.createUniformFunction(S.type,S.value,s,l);v[b]=T.func,y[C]=T}}var E=a[u];E.uniformMap=v,E.values=y,E.jointMatrixUniformName=p,E.morphWeightsUniformName=f}}}function mt(e,t){var r=je(e,t),i=e._quantizedUniforms[r];return ve.createUniformsForQuantizedAttributes(e.gltf,t,i)}function gt(e){return function(){return e}}function _t(e){return function(){return e.computedJointMatrices}}function vt(e){return function(){return e.weights}}function yt(e){return function(){return e.silhouetteColor}}function bt(e){return function(){return e.silhouetteSize}}function Ct(e){return function(){return e.color}}function St(e){return function(){return e._packedClippingPlanes.length}}function wt(e){return function(){var t=e.clippingPlanes;return!!c(t)&&t.unionClippingRegions}}function Tt(e){return function(){var t=e.clippingPlanes,r=e._packedClippingPlanes;return c(t)&&t.enabled&&t.transformAndPackPlanes(e._modelViewMatrix,r),r}}function Et(e){return function(){var t=e.clippingPlanes;if(!c(t))return s.WHITE.withAlpha(0);var r=s.clone(t.edgeColor);return r.alpha=t.edgeWidth,r}}function At(e){return function(){return ue.getColorBlend(e.colorBlendMode,e.colorBlendAmount)}}function xt(e,t){switch(e.mode){case I.TRIANGLES:return t/3;case I.TRIANGLE_STRIP:case I.TRIANGLE_FAN:return Math.max(t-2,0);default:return 0}}function Pt(t,i,n,o,a){for(var s=t._nodeCommands,u=t._pickIds,d=t.allowPicking,h=t._runtime.meshesByName,p=t._rendererResources,f=p.vertexArrays,m=p.programs,g=p.pickPrograms,_=p.renderStates,v=t._uniformMaps,y=t.gltf,C=y.accessors,S=y.meshes,w=y.techniques,T=y.materials,E=i.mesh,A=S[E],P=A.primitives,D=P.length,I=0;I<D;++I){var O,M=P[I],R=C[M.indices],L=T[M.material],N=w[L.technique],k=N.program,F=M.attributes.POSITION;if(c(F)){var B=ve.getAccessorMinMax(y,F);O=e.fromCornerPoints(r.fromArray(B.min),r.fromArray(B.max))}var z,G,W=f[E+".primitive."+I];if(c(R))G=R.count,z=R.byteOffset/b.getSizeInBytes(R.componentType);else{G=C[M.attributes.POSITION].count,z=0}t._trianglesLength+=xt(M,G);var H=v[M.material],j=H.uniformMap;if(c(H.jointMatrixUniformName)){var q={};q[H.jointMatrixUniformName]=_t(n),j=l(j,q)}if(c(H.morphWeightsUniformName)){var Y={};Y[H.morphWeightsUniformName]=vt(n),j=l(j,Y)}if(j=l(j,{gltf_color:Ct(t),gltf_colorBlend:At(t),gltf_clippingPlanesLength:St(t),gltf_clippingPlanesUnionRegions:wt(t),gltf_clippingPlanes:Tt(t,o),gltf_clippingPlanesEdgeStyle:Et(t)}),c(t._uniformMapLoaded)&&(j=t._uniformMapLoaded(j,k,n)),t.extensionsUsed.WEB3D_quantized_attributes){var X=mt(t,M);j=l(j,X)}var Q=_[L.technique],Z=Q.blending.enabled,K=t._pickObject;c(K)||(K={primitive:t,id:t.id,node:n.publicNode,mesh:h[A.name]});var J,$=be.castShadows(t._shadows),ee=be.receiveShadows(t._shadows),te=new U({boundingVolume:new e,cull:t.cull,modelMatrix:new x,primitiveType:M.mode,vertexArray:W,count:G,offset:z,shaderProgram:m[N.program],castShadows:$,receiveShadows:ee,uniformMap:j,renderState:Q,owner:K,pass:Z?V.TRANSLUCENT:t.opaquePass});if(d){var re;if(c(t._pickFragmentShaderLoaded))re=c(t._pickUniformMapLoaded)?t._pickUniformMapLoaded(j):l(j);else{var ie=o.createPickId(K);u.push(ie);var ne={czm_pickColor:gt(ie.color)};re=l(j,ne)}J=new U({boundingVolume:new e,cull:t.cull,modelMatrix:new x,primitiveType:M.mode,vertexArray:W,count:G,offset:z,shaderProgram:g[N.program],uniformMap:re,renderState:Q,owner:K,pass:Z?V.TRANSLUCENT:t.opaquePass})}var oe,ae;a||(oe=U.shallowClone(te),oe.boundingVolume=new e,oe.modelMatrix=new x,d&&(ae=U.shallowClone(J),ae.boundingVolume=new e,ae.modelMatrix=new x));var se={show:!0,boundingSphere:O,command:te,pickCommand:J,command2D:oe,pickCommand2D:ae,silhouetteModelCommand:void 0,silhouetteModelCommand2D:void 0,silhouetteColorCommand:void 0,silhouetteColorCommand2D:void 0,translucentCommand:void 0,translucentCommand2D:void 0};n.commands.push(se),s.push(se)}}function Dt(e,t,i){var n=e._loadResources;if(n.finishedEverythingButTextureCreation()&&n.createRuntimeNodes){n.createRuntimeNodes=!1;for(var o=[],a=e._runtime.nodes,s=e.gltf,l=s.nodes,u=s.skins,d=s.scenes[s.scene],h=d.nodes,p=h.length,f=[],m={},g=0;g<p;++g){f.push({parentRuntimeNode:void 0,gltfNode:l[h[g]],id:h[g]});for(var _=[];f.length>0;){var v=f.pop();m[v.id]=!0;var y=v.parentRuntimeNode,b=v.gltfNode,C=a[v.id];if(0===C.parents.length)if(c(b.matrix))C.matrix=x.fromColumnMajorArray(b.matrix);else{var S=b.rotation;C.translation=r.fromArray(b.translation),C.rotation=M.unpack(S),C.scale=r.fromArray(b.scale)}c(y)?(y.children.push(C),C.parents.push(y)):o.push(C),c(b.mesh)&&Pt(e,b,C,t,i);for(var w=b.children,T=w.length,E=0;E<T;E++){var A=w[E];m[A]||f.push({parentRuntimeNode:C,gltfNode:l[A],id:w[E]})}var P=b.skin;if(c(P)&&_.push(u[P].skeleton),0===f.length)for(var D=0;D<_.length;D++){var I=_[D];m[I]||f.push({parentRuntimeNode:void 0,gltfNode:l[I],id:I})}}}e._runtime.rootNodes=o,e._runtime.nodes=a}}function It(e){var t=0;for(var r in e)e.hasOwnProperty(r)&&(t+=e[r].sizeInBytes);return t}function Ot(e){var t=0;for(var r in e)e.hasOwnProperty(r)&&(t+=e[r].sizeInBytes);return t}function Mt(e,t){var r=t.context,i=t.scene3DOnly;if(ve.checkSupportedGlExtensions(e.gltf.glExtensionsUsed,r),e._loadRendererResourcesFromCache){var n=e._rendererResources,o=e._cachedRendererResources;n.buffers=o.buffers,n.vertexArrays=o.vertexArrays,n.programs=o.programs,n.pickPrograms=o.pickPrograms,n.silhouettePrograms=o.silhouettePrograms,n.textures=o.textures,n.samplers=o.samplers,n.renderStates=o.renderStates,c(e._precreatedAttributes)&&ut(e,r),e._cachedGeometryByteLength+=It(o.buffers),e._cachedTexturesByteLength+=Ot(o.textures)}else We(e,t),Ke(e,t),et(e,r),$e(e),rt(e,t);at(e),lt(e),e._loadRendererResourcesFromCache||(ut(e,r),dt(e,r)),ft(e,r),Dt(e,r,i)}function Rt(e,t){var r=e.publicNode,i=r.matrix;r.useMatrix&&c(i)?x.clone(i,t):c(e.matrix)?x.clone(e.matrix,t):(x.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t),r.setMatrix(t))}function Lt(t,n,o,a){var s=t._maxDirtyNumber,l=t.allowPicking,u=t._runtime.rootNodes,d=u.length,h=Ar,p=t._computedModelMatrix;if(t._mode!==ye.SCENE3D&&!t._ignoreCommands){var f=x.getColumn(p,3,xr);if(i.equals(f,i.UNIT_W)){var m=t.boundingSphere.center,g=N.wgs84To2DModelMatrix(a,m,Pr);p=x.multiply(g,p,Pr),c(t._rtcCenter)&&(x.setTranslation(p,i.UNIT_W,p),t._rtcCenter=t._rtcCenter2D)}else p=N.basisTo2D(a,p,Pr),t._rtcCenter=t._rtcCenter3D}for(var _=0;_<d;++_){var v=u[_];for(Rt(v,v.transformToRoot),h.push(v);h.length>0;){v=h.pop();var y=v.transformToRoot,b=v.commands;if(v.dirtyNumber===s||n||o){var C=x.multiplyTransformation(p,y,v.computedMatrix),S=b.length;if(S>0)for(var w=0;w<S;++w){var E=b[w],A=E.command;if(x.clone(C,A.modelMatrix),e.transform(E.boundingSphere,A.modelMatrix,A.boundingVolume),c(t._rtcCenter)&&r.add(t._rtcCenter,A.boundingVolume.center,A.boundingVolume.center),l){var P=E.pickCommand;x.clone(A.modelMatrix,P.modelMatrix),e.clone(A.boundingVolume,P.boundingVolume)}if(A=E.command2D,c(A)&&t._mode===ye.SCENE2D&&(x.clone(C,A.modelMatrix),A.modelMatrix[13]-=2*T.sign(A.modelMatrix[13])*T.PI*a.ellipsoid.maximumRadius,e.transform(E.boundingSphere,A.modelMatrix,A.boundingVolume),l)){var D=E.pickCommand2D;x.clone(A.modelMatrix,D.modelMatrix),e.clone(A.boundingVolume,D.boundingVolume)}}}for(var I=v.children,O=I.length,M=0;M<O;++M){var R=I[M];R.dirtyNumber=Math.max(R.dirtyNumber,v.dirtyNumber),(R.dirtyNumber===s||o)&&(Rt(R,R.transformToRoot),x.multiplyTransformation(y,R.transformToRoot,R.transformToRoot)),h.push(R)}}}++t._maxDirtyNumber}function Nt(e){for(var t=e._runtime.skinnedNodes,r=t.length,i=0;i<r;++i){var n=t[i];Dr=x.inverseTransformation(n.transformToRoot,Dr);for(var o=n.computedJointMatrices,a=n.joints,s=n.bindShapeMatrix,l=n.inverseBindMatrices,u=l.length,d=0;d<u;++d)c(o[d])||(o[d]=new x),o[d]=x.multiplyTransformation(Dr,a[d].transformToRoot,o[d]),o[d]=x.multiplyTransformation(o[d],l[d],o[d]),c(s)&&(o[d]=x.multiplyTransformation(o[d],s,o[d]))}}function kt(e){for(var t=e._runtime.rootNodes,r=t.length,i=Ar,n=0;n<r;++n){var o=t[n];for(o.computedShow=o.publicNode.show,i.push(o);i.length>0;){o=i.pop();for(var a=o.computedShow,s=o.commands,l=s.length,u=0;u<l;++u)s[u].show=a;for(var c=o.children,d=c.length,h=0;h<d;++h){var p=c[h];p.computedShow=a&&p.publicNode.show,i.push(p)}}}}function Ft(e,t){var r=e.id;if(e._id!==r){e._id=r;for(var i=e._pickIds,n=i.length,o=0;o<n;++o)i[o].object.id=r}}function Bt(e){if(e._debugWireframe!==e.debugWireframe){e._debugWireframe=e.debugWireframe;for(var t=e.debugWireframe?I.LINES:I.TRIANGLES,r=e._nodeCommands,i=r.length,n=0;n<i;++n)r[n].command.primitiveType=t}}function Ut(e){if(e.debugShowBoundingVolume!==e._debugShowBoundingVolume){e._debugShowBoundingVolume=e.debugShowBoundingVolume;for(var t=e.debugShowBoundingVolume,r=e._nodeCommands,i=r.length,n=0;n<i;++n)r[n].command.debugShowBoundingVolume=t}}function Vt(e){if(e.shadows!==e._shadows){e._shadows=e.shadows;for(var t=be.castShadows(e.shadows),r=be.receiveShadows(e.shadows),i=e._nodeCommands,n=i.length,o=0;o<n;o++){var a=i[o];a.command.castShadows=t,a.command.receiveShadows=r}}}function zt(e){var t=a(e,!0);return t.cull.enabled=!1,t.depthTest.enabled=!0,t.depthMask=!1,t.blending=le.ALPHA_BLEND,z.fromCache(t)}function Gt(e){var t=U.shallowClone(e);return t.pass=V.TRANSLUCENT,t.renderState=zt(e.renderState),t}function Wt(e,t){var r=t.scene3DOnly,i=e.color.alpha;if(i>0&&i<1){var n=e._nodeCommands,o=n.length;if(!c(n[0].translucentCommand))for(var a=0;a<o;++a){var s=n[a],l=s.command;if(s.translucentCommand=Gt(l),!r){var u=s.command2D;s.translucentCommand2D=Gt(u)}}}}function Ht(e,t){var r=e._rendererResources.programs;for(var i in r)if(r.hasOwnProperty(i)&&r[i]===t)return i}function jt(e,t,r){var i=t.vertexShaderSource.sources[0],n=t._attributeLocations,o=e._normalAttributeName;i=H.replaceMain(i,"gltf_silhouette_main"),i+="uniform float gltf_silhouetteSize; \nvoid main() \n{ \n gltf_silhouette_main(); \n vec3 n = normalize(czm_normal3D * "+o+"); \n n.x *= czm_projection[0][0]; \n n.y *= czm_projection[1][1]; \n vec4 clip = gl_Position; \n clip.xy += n.xy * clip.w * gltf_silhouetteSize / czm_viewport.z; \n gl_Position = clip; \n}";return W.fromCache({context:r.context,vertexShaderSource:i,fragmentShaderSource:"uniform vec4 gltf_silhouetteColor; \nvoid main() \n{ \n gl_FragColor = gltf_silhouetteColor; \n}",attributeLocations:n})}function qt(e,t){return Te(t.context)&&e.silhouetteSize>0&&e.silhouetteColor.alpha>0&&c(e._normalAttributeName)}function Yt(e){for(var t=e._nodeCommands,r=t.length,i=0;i<r;++i){if(t[i].command.pass===V.TRANSLUCENT)return!0}return!1}function Xt(e){return e.color.alpha>0&&e.color.alpha<1}function Qt(e){return 0===e.color.alpha}function Zt(e,t){return Math.floor(e)!==Math.floor(t)||Math.ceil(e)!==Math.ceil(t)}function Kt(e,t){for(var r=++Ir%255,i=Yt(e)||Xt(e)||e.silhouetteColor.alpha<1,n=e._rendererResources.silhouettePrograms,o=t.scene3DOnly,s=e._nodeCommands,u=s.length,d=0;d<u;++d){var h=s[d],p=h.command,f=Xt(e)?h.translucentCommand:p,m=U.shallowClone(f),g=a(f.renderState);g.stencilTest={enabled:!0,frontFunction:k.ALWAYS,backFunction:k.ALWAYS,reference:r,mask:-1,frontOperation:{fail:k.KEEP,zFail:k.KEEP,zPass:k.REPLACE},backOperation:{fail:k.KEEP,zFail:k.KEEP,zPass:k.REPLACE}},Qt(e)&&(g.colorMask={red:!1,green:!1,blue:!1,alpha:!1},g.depthMask=!1),g=z.fromCache(g),m.renderState=g,h.silhouetteModelCommand=m;var _=U.shallowClone(p);g=a(p.renderState,!0),g.depthTest.enabled=!0,g.cull.enabled=!1,i&&(_.pass=V.TRANSLUCENT,g.depthMask=!1,g.blending=le.ALPHA_BLEND),g.stencilTest={enabled:!0,frontFunction:k.NOTEQUAL,backFunction:k.NOTEQUAL,reference:r,mask:-1,frontOperation:{fail:k.KEEP,zFail:k.KEEP,zPass:k.KEEP},backOperation:{fail:k.KEEP,zFail:k.KEEP,zPass:k.KEEP}},g=z.fromCache(g);var v=p.shaderProgram,y=Ht(e,v),b=n[y];c(b)||(b=jt(e,v,t),n[y]=b);var C=l(p.uniformMap,{gltf_silhouetteColor:yt(e),gltf_silhouetteSize:bt(e)});if(_.renderState=g,_.shaderProgram=b,_.uniformMap=C,_.castShadows=!1,_.receiveShadows=!1,h.silhouetteColorCommand=_,!o){var S=h.command2D,w=U.shallowClone(m);w.boundingVolume=S.boundingVolume,w.modelMatrix=S.modelMatrix,h.silhouetteModelCommand2D=w;var T=U.shallowClone(_);w.boundingVolume=S.boundingVolume,w.modelMatrix=S.modelMatrix,h.silhouetteColorCommand2D=T}}}function Jt(e){return e=H.replaceMain(e,"gltf_clip_main"),e+="uniform int gltf_clippingPlanesLength; \nuniform bool gltf_clippingPlanesUnionRegions; \nuniform vec4 gltf_clippingPlanes[czm_maxClippingPlanes]; \nuniform vec4 gltf_clippingPlanesEdgeStyle; \nvoid main() \n{ \n gltf_clip_main(); \n if (gltf_clippingPlanesLength > 0) \n { \n float clipDistance; \n if (gltf_clippingPlanesUnionRegions) \n { \n clipDistance = czm_discardIfClippedWithUnion(gltf_clippingPlanes, gltf_clippingPlanesLength); \n } \n else \n { \n clipDistance = czm_discardIfClippedWithIntersect(gltf_clippingPlanes, gltf_clippingPlanesLength); \n } \n \n vec4 clippingPlanesEdgeColor = vec4(1.0); \n clippingPlanesEdgeColor.rgb = gltf_clippingPlanesEdgeStyle.rgb; \n float clippingPlanesEdgeWidth = gltf_clippingPlanesEdgeStyle.a; \n if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n { \n gl_FragColor = clippingPlanesEdgeColor; \n } \n } \n} \n"}function $t(e,t){if(qt(e,t)){var r=e._nodeCommands,i=Zt(e.color.alpha,e._colorPreviousAlpha)||Zt(e.silhouetteColor.alpha,e._silhouetteColorPreviousAlpha)||!c(r[0].silhouetteModelCommand);e._colorPreviousAlpha=e.color.alpha,e._silhouetteColorPreviousAlpha=e.silhouetteColor.alpha,i&&Kt(e,t)}}function er(e){var t=e.clippingPlanes,r=0;c(t)&&t.enabled&&(r=t.length);var n=e._packedClippingPlanes,o=n.length;if(o!==r){n.length=r;for(var a=o;a<r;++a)n[a]=new i}}function tr(e,t,r){return Or.center=e,Or.radius=t,r.camera.getPixelSize(Or,r.context.drawingBufferWidth,r.context.drawingBufferHeight)}function rr(e,t){var i=e.scale;if(0!==e.minimumPixelSize){var n=t.context,o=Math.max(n.drawingBufferWidth,n.drawingBufferHeight),a=c(e._clampedModelMatrix)?e._clampedModelMatrix:e.modelMatrix;if(Mr.x=a[12],Mr.y=a[13],Mr.z=a[14],c(e._rtcCenter)&&r.add(e._rtcCenter,Mr,Mr),e._mode!==ye.SCENE3D){var s=t.mapProjection,l=s.ellipsoid.cartesianToCartographic(Mr,Rr);s.project(l,Mr),r.fromElements(Mr.z,Mr.x,Mr.y,Mr)}var u=e.boundingSphere.radius,d=tr(Mr,u,t),h=1/d;Math.min(h*(2*u),o)<e.minimumPixelSize&&(i=e.minimumPixelSize*d/(2*e._initialRadius))}return c(e.maximumScale)?Math.min(e.maximumScale,i):i}function ir(e){c(e._cacheKey)&&c(e._cachedGltf)&&0==--e._cachedGltf.count&&delete hr[e._cacheKey],e._cachedGltf=void 0}function nr(e,t){this.buffers=void 0,this.vertexArrays=void 0,this.programs=void 0,this.pickPrograms=void 0,this.silhouettePrograms=void 0,this.textures=void 0,this.samplers=void 0,this.renderStates=void 0,this.ready=!1,this.context=e,this.cacheKey=t,this.count=0}function or(e){for(var t in e)e.hasOwnProperty(t)&&e[t].destroy()}function ar(e){or(e.buffers),or(e.vertexArrays),or(e.programs),or(e.pickPrograms),or(e.silhouettePrograms),or(e.textures)}function sr(e,t,r){return function(i){if(e.heightReference===ce.RELATIVE_TO_GROUND){var n=t.cartesianToCartographic(i,Rr);n.height+=r.height,t.cartographicToCartesian(n,i)}var o=e._clampedModelMatrix;x.clone(e.modelMatrix,o),o[12]=i.x,o[13]=i.y,o[14]=i.z,e._heightChanged=!0}}function lr(e){c(e._removeUpdateHeightCallback)&&(e._removeUpdateHeightCallback(),e._removeUpdateHeightCallback=void 0);var t=e._scene;if(!c(t)||!c(t.globe)||e.heightReference===ce.NONE)return void(e._clampedModelMatrix=void 0);var r=t.globe,i=r.ellipsoid,o=e.modelMatrix;Mr.x=o[12],Mr.y=o[13],Mr.z=o[14];var a=i.cartesianToCartographic(Mr);c(e._clampedModelMatrix)||(e._clampedModelMatrix=x.clone(o,new x));var s=r._surface;e._removeUpdateHeightCallback=s.updateHeight(a,sr(e,i,a));var l=r.getHeight(a);if(c(l)){var u=sr(e,i,a);n.clone(a,Rr),Rr.height=l,i.cartographicToCartesian(Rr,Mr),u(Mr)}}function ur(e,t){var i,n=e.distanceDisplayCondition,o=n.near*n.near,a=n.far*n.far;if(t.mode===ye.SCENE2D){i=.5*(t.camera.frustum.right-t.camera.frustum.left),i*=i}else{var s=x.getTranslation(e.modelMatrix,Lr);if(t.mode===ye.COLUMBUS_VIEW){var l=t.mapProjection,u=l.ellipsoid,c=u.cartesianToCartographic(s,Nr);s=l.project(c,s),r.fromElements(s.z,s.x,s.y,s)}i=r.distanceSquared(s,t.camera.positionWC)}return i>=o&&i<=a}if(!g.supportsTypedArrays())return{};var cr=new r,dr={NEEDS_LOAD:0,LOADING:1,LOADED:2,FAILED:3};d(Se.prototype,{gltf:{set:function(e){this._gltf=e},get:function(){return this._gltf}}}),Se.prototype.makeReady=function(e){this.gltf=e;for(var t=this.modelsToLoad,r=t.length,i=0;i<r;++i){var n=t[i];n.isDestroyed()||Ce(n,this)}this.modelsToLoad=void 0,this.ready=!0};var hr={};d(we.prototype,{gltf:{get:function(){return c(this._cachedGltf)?this._cachedGltf.gltf:void 0}},releaseGltfJson:{get:function(){return this._releaseGltfJson}},cacheKey:{get:function(){return this._cacheKey}},basePath:{get:function(){return this._resource.url}},boundingSphere:{get:function(){var e=this.modelMatrix;this.heightReference!==ce.NONE&&this._clampedModelMatrix&&(e=this._clampedModelMatrix);var t=x.getScale(e,cr),i=c(this.maximumScale)?Math.min(this.maximumScale,this.scale):this.scale;r.multiplyByScalar(t,i,t);var n=this._scaledBoundingSphere;return n.center=r.multiplyComponents(this._boundingSphere.center,t,n.center),n.radius=r.maximumComponent(t)*this._initialRadius,c(this._rtcCenter)&&r.add(this._rtcCenter,n.center,n.center),n}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},asynchronous:{get:function(){return this._asynchronous}},allowPicking:{get:function(){return this._allowPicking}},incrementallyLoadTextures:{get:function(){return this._incrementallyLoadTextures}},pendingTextureLoads:{get:function(){return c(this._loadResources)?this._loadResources.pendingTextureLoads:0}},dirty:{get:function(){return this._dirty}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){this._distanceDisplayCondition=m.clone(e,this._distanceDisplayCondition)}},extensionsUsed:{get:function(){return c(this._extensionsUsed)||(this._extensionsUsed=ve.getUsedExtensions(this.gltf)),this._extensionsUsed}},extensionsRequired:{get:function(){return c(this._extensionsRequired)||(this._extensionsRequired=ve.getRequiredExtensions(this.gltf)),this._extensionsRequired}},upAxis:{get:function(){return this._upAxis}},trianglesLength:{get:function(){return this._trianglesLength}},geometryByteLength:{get:function(){return this._geometryByteLength}},texturesByteLength:{get:function(){return this._texturesByteLength}},cachedGeometryByteLength:{get:function(){return this._cachedGeometryByteLength}},cachedTexturesByteLength:{get:function(){return this._cachedTexturesByteLength}}}),we.silhouetteSupported=function(e){return Te(e.context)},we.fromGltf=function(e){c(e.headers)&&h("Model.fromGltf.headers","The options.headers parameter has been deprecated. Specify options.url as a Resource instance and set the headers property there.");var t=e.url;e=a(e);var r=O.createIfNeeded(t,{headers:e.headers}),i=u(e.basePath,r.clone()),n=O.createIfNeeded(i,{headers:e.headers}),o=u(e.cacheKey,_(r.url));c(e.basePath)&&!c(e.cacheKey)&&(o+=n.url),e.cacheKey=o,e.basePath=n;var s=new we(e),l=hr[o];return c(l)?l.ready||(++l.count,l.modelsToLoad.push(s)):(l=new Se({ready:!1}),l.count=1,l.modelsToLoad.push(s),Ce(s,l),hr[o]=l,c(r.headers.Accept)||(r.headers.Accept="model/gltf-binary,model/gltf+json;q=0.8,application/json;q=0.2,*/*;q=0.01"),r.fetchArrayBuffer().then(function(e){var t=new Uint8Array(e);if(Ee(t)){var r=ee(t);l.makeReady(r,t)}else{var i=y(t);l.makeReady(JSON.parse(i))}}).otherwise(Pe(s,"model",t))),s},we._gltfCache=hr,we.prototype.getNode=function(e){var t=Ae(this,"nodesByName",e);return c(t)?t.publicNode:void 0},we.prototype.getMesh=function(e){return Ae(this,"meshesByName",e)},we.prototype.getMaterial=function(e){return Ae(this,"materialsByName",e)};var pr=new r,fr=new r,mr=/(^data:image\/ktx)|(\.ktx$)/i,gr=/(^data:image\/crn)|(\.crn$)/i,_r=function(){this.id=void 0,this.model=void 0,this.context=void 0};_r.prototype.set=function(e,t,r){this.id=e,this.model=t,this.context=r},_r.prototype.execute=function(){ze(this.id,this.model,this.context)};var vr=function(){this.id=void 0,this.componentType=void 0,this.model=void 0,this.context=void 0};vr.prototype.set=function(e,t,r,i){this.id=e,this.componentType=t,this.model=r,this.context=i},vr.prototype.execute=function(){Ge(this.id,this.componentType,this.model,this.context)};var yr=new _r,br=new vr,Cr=function(){this.id=void 0,this.model=void 0,this.context=void 0};Cr.prototype.set=function(e,t,r){this.id=e,this.model=t,this.context=r},Cr.prototype.execute=function(){Ze(this.id,this.model,this.context)};var Sr=new Cr,wr=function(){this.gltfTexture=void 0,this.model=void 0,this.context=void 0};wr.prototype.set=function(e,t,r){this.gltfTexture=e,this.model=t,this.context=r},wr.prototype.execute=function(){tt(this.gltfTexture,this.model,this.context)};var Tr=new wr,Er={MODEL:function(e,t,r){return function(){return r.computedMatrix}},VIEW:function(e,t,r){return function(){return e.view}},PROJECTION:function(e,t,r){return function(){return e.projection}},MODELVIEW:function(e,t,r){var i=new x;return function(){return x.multiplyTransformation(e.view,r.computedMatrix,i)}},CESIUM_RTC_MODELVIEW:function(e,t,r){var i=new x;return function(){return x.multiplyTransformation(e.view,r.computedMatrix,i),x.setTranslation(i,t._rtcCenterEye,i)}},MODELVIEWPROJECTION:function(e,t,r){var i=new x;return function(){return x.multiplyTransformation(e.view,r.computedMatrix,i),x.multiply(e._projection,i,i)}},MODELINVERSE:function(e,t,r){var i=new x;return function(){return x.inverse(r.computedMatrix,i)}},VIEWINVERSE:function(e,t){return function(){return e.inverseView}},PROJECTIONINVERSE:function(e,t,r){return function(){return e.inverseProjection}},MODELVIEWINVERSE:function(e,t,r){var i=new x,n=new x;return function(){return x.multiplyTransformation(e.view,r.computedMatrix,i),x.inverse(i,n)}},MODELVIEWPROJECTIONINVERSE:function(e,t,r){var i=new x,n=new x;return function(){return x.multiplyTransformation(e.view,r.computedMatrix,i),x.multiply(e._projection,i,i),x.inverse(i,n)}},MODELINVERSETRANSPOSE:function(e,t,r){var i=new x,n=new A;return function(){return x.inverse(r.computedMatrix,i),x.getRotation(i,n),A.transpose(n,n)}},MODELVIEWINVERSETRANSPOSE:function(e,t,r){var i=new x,n=new x,o=new A;return function(){return x.multiplyTransformation(e.view,r.computedMatrix,i),x.inverse(i,n),x.getRotation(n,o),A.transpose(o,o)}},VIEWPORT:function(e,t,r){return function(){return e.viewportCartesian4}}},Ar=[],xr=new i,Pr=new x,Dr=new x,Ir=0,Or=new e,Mr=new r,Rr=new n;nr.prototype.release=function(){if(0==--this.count)return c(this.cacheKey)&&delete this.context.cache.modelRendererResourceCache[this.cacheKey],ar(this),p(this)};var Lr=new r,Nr=new n;return we.prototype.update=function(e){if(e.mode!==ye.MORPHING){var t=e.context;if(this._defaultTexture=t.defaultTexture,this._state===dr.NEEDS_LOAD&&c(this.gltf)){var i,n=this.cacheKey;if(c(n)){t.cache.modelRendererResourceCache=u(t.cache.modelRendererResourceCache,{});var o=t.cache.modelRendererResourceCache;if(i=o[this.cacheKey],c(i)){if(!i.ready)return;++i.count,this._loadRendererResourcesFromCache=!0}else i=new nr(t,n),i.count=1,o[this.cacheKey]=i;this._cachedRendererResources=i}else i=new nr(t),i.count=1,this._cachedRendererResources=i;if(this._state=dr.LOADING,this._state!==dr.FAILED){var a=this.gltf.extensions;if(c(a)&&c(a.CESIUM_RTC)){var s=r.fromArray(a.CESIUM_RTC.center);if(!r.equals(s,r.ZERO)){this._rtcCenter3D=s;var l=e.mapProjection,d=l.ellipsoid,h=d.cartesianToCartographic(this._rtcCenter3D),p=l.project(h);r.fromElements(p.z,p.x,p.y,p),this._rtcCenter2D=p,this._rtcCenterEye=new r,this._rtcCenter=this._rtcCenter3D}}this._loadResources=new fe,this._loadRendererResourcesFromCache||Oe(this)}}var f=this._loadResources,m=this._incrementallyLoadTextures,g=!1;if(this._state===dr.LOADING){if(0===f.pendingBufferLoads){if(!this._updatedGltfVersion){var _={optimizeForCesium:!0,addBatchIdToGeneratedShaders:this._addBatchIdToGeneratedShaders};e.brdfLutGenerator.update(e),ie(this.gltf),ve.checkSupportedExtensions(this.extensionsRequired),Z(this.gltf),Q(this.gltf),te(this.gltf,_),re(this.gltf,_),De(this),this._loadRendererResourcesFromCache||(Me(this),Le(this),Ne(this),Fe(this,t)),Ue(this),Ve(this),Be(this),this._boundingSphere=xe(this),this._initialRadius=this._boundingSphere.radius,this._updatedGltfVersion=!0}this._updatedGltfVersion&&0===f.pendingShaderLoads&&Mt(this,e)}(f.finished()||m&&f.finishedEverythingButTextureCreation())&&(this._state=dr.LOADED,g=!0)}if(c(f)&&this._state===dr.LOADED&&(m&&!g&&Mt(this,e),f.finished())){ +this._loadResources=void 0;var v=this._rendererResources,y=this._cachedRendererResources;y.buffers=v.buffers,y.vertexArrays=v.vertexArrays,y.programs=v.programs,y.pickPrograms=v.pickPrograms,y.silhouettePrograms=v.silhouettePrograms,y.textures=v.textures,y.samplers=v.samplers,y.renderStates=v.renderStates,y.ready=!0,this._normalAttributeName=ve.getAttributeOrUniformBySemantic(this.gltf,"NORMAL"),c(this._precreatedAttributes)&&(y.vertexArrays={}),this.releaseGltfJson&&ir(this)}var b=qt(this,e),C=Xt(this),S=Qt(this),w=!c(this.distanceDisplayCondition)||ur(this,e),E=this.show&&w&&0!==this.scale&&(!S||b);if(E&&this._state===dr.LOADED||g){var A=this.activeAnimations.update(e)||this._cesiumAnimationsDirty;this._cesiumAnimationsDirty=!1,this._dirty=!1;var P=this.modelMatrix,D=e.mode!==this._mode;this._mode=e.mode;var I=!x.equals(this._modelMatrix,P)||this._scale!==this.scale||this._minimumPixelSize!==this.minimumPixelSize||0!==this.minimumPixelSize||this._maximumScale!==this.maximumScale||this._heightReference!==this.heightReference||this._heightChanged||D;if(I||g){x.clone(P,this._modelMatrix),lr(this),c(this._clampedModelMatrix)&&(P=this._clampedModelMatrix),this._scale=this.scale,this._minimumPixelSize=this.minimumPixelSize,this._maximumScale=this.maximumScale,this._heightReference=this.heightReference,this._heightChanged=!1;var O=rr(this,e),M=this._computedModelMatrix;x.multiplyByUniformScale(P,O,M),this._upAxis===se.Y?x.multiplyTransformation(M,se.Y_UP_TO_Z_UP,M):this._upAxis===se.X&&x.multiplyTransformation(M,se.X_UP_TO_Z_UP,M)}var R=this.clippingPlanes;c(R)&&R.enabled&&x.multiply(t.uniformState.view3D,P,this._modelViewMatrix),(A||I||g)&&(Lt(this,I,g,e.mapProjection),this._dirty=!0,(A||g)&&Nt(this)),this._perNodeShowDirty&&(this._perNodeShowDirty=!1,kt(this)),Ft(this,t),Bt(this),Ut(this),Vt(this),Wt(this,e),$t(this,e),er(this)}if(g){var L=this;return void e.afterRender.push(function(){L._ready=!0,L._readyPromise.resolve(L)})}if(E&&!this._ignoreCommands){var N,k,F,B=e.commandList,U=e.passes,V=this._nodeCommands,z=V.length,G=e.mapProjection.ellipsoid.maximumRadius*T.PI;if(U.render){for(N=0;N<z;++N)if(k=V[N],k.show){var W=C?k.translucentCommand:k.command;if(W=b?k.silhouetteModelCommand:W,B.push(W),F=k.command.boundingVolume,e.mode===ye.SCENE2D&&(F.center.y+F.radius>G||F.center.y-F.radius<G)){var H=C?k.translucentCommand2D:k.command2D;H=b?k.silhouetteModelCommand2D:H,B.push(H)}}if(b)for(N=0;N<z;++N)k=V[N],k.show&&(B.push(k.silhouetteColorCommand),F=k.command.boundingVolume,e.mode===ye.SCENE2D&&(F.center.y+F.radius>G||F.center.y-F.radius<G)&&B.push(k.silhouetteColorCommand2D))}if(U.pick&&this.allowPicking)for(N=0;N<z;++N)if(k=V[N],k.show){var j=k.pickCommand;B.push(j),F=j.boundingVolume,e.mode===ye.SCENE2D&&(F.center.y+F.radius>G||F.center.y-F.radius<G)&&B.push(k.pickCommand2D)}}}},we.prototype.isDestroyed=function(){return!1},we.prototype.destroy=function(){c(this._precreatedAttributes)&&or(this._rendererResources.vertexArrays),c(this._removeUpdateHeightCallback)&&(this._removeUpdateHeightCallback(),this._removeUpdateHeightCallback=void 0),c(this._terrainProviderChangedCallback)&&(this._terrainProviderChangedCallback(),this._terrainProviderChangedCallback=void 0),this._rendererResources=void 0,this._cachedRendererResources=this._cachedRendererResources&&this._cachedRendererResources.release();for(var e=this._pickIds,t=e.length,r=0;r<t;++r)e[r].destroy();return ir(this),p(this)},we}),define("DataSources/ModelVisualizer",["../Core/AssociativeArray","../Core/BoundingSphere","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Matrix4","../Core/Resource","../Scene/ColorBlendMode","../Scene/HeightReference","../Scene/Model","../Scene/ModelAnimationLoop","../Scene/ShadowMode","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(t,r){r.collectionChanged.addEventListener(m.prototype._onCollectionChanged,this),this._scene=t,this._primitives=t.primitives,this._entityCollection=r,this._modelHash={},this._entitiesToVisualize=new e,this._onCollectionChanged(r,r.values,[],[])}function g(e,t,r,n){var o=r[t.id];i(o)&&(n.removeAndDestroy(o.modelPrimitive),delete r[t.id])}function _(e,t){var r=t[e.id];i(r)&&(r.nodeTransformationsScratch={})}function v(e){console.error(e)}var y=h.ENABLED,b=u.NONE,C=r.RED,S=r.WHITE,w=l.HIGHLIGHT,T=new a,E=new a;return m.prototype.update=function(e){for(var t=this._entitiesToVisualize.values,r=this._modelHash,n=this._primitives,o=0,l=t.length;o<l;o++){var u,h,p=t[o],m=p._model,g=r[p.id],_=p.isShowing&&p.isAvailable(e)&&f.getValueOrDefault(m._show,e,!0);if(_&&(h=p.computeModelMatrix(e,T),u=s.createIfNeeded(f.getValueOrUndefined(m._uri,e)),_=i(h)&&i(u)),_){var A=i(g)?g.modelPrimitive:void 0;if(i(A)&&u.url===g.url||(i(A)&&(n.removeAndDestroy(A),delete r[p.id]),A=c.fromGltf({url:u,incrementallyLoadTextures:f.getValueOrDefault(m._incrementallyLoadTextures,e,!0),scene:this._scene}),A.readyPromise.otherwise(v),A.id=p,n.add(A),g={modelPrimitive:A,url:u.url,animationsRunning:!1,nodeTransformationsScratch:{},originalNodeMatrixHash:{}},r[p.id]=g),A.show=!0,A.scale=f.getValueOrDefault(m._scale,e,1),A.minimumPixelSize=f.getValueOrDefault(m._minimumPixelSize,e,0),A.maximumScale=f.getValueOrUndefined(m._maximumScale,e),A.modelMatrix=a.clone(h,A.modelMatrix),A.shadows=f.getValueOrDefault(m._shadows,e,y),A.heightReference=f.getValueOrDefault(m._heightReference,e,b),A.distanceDisplayCondition=f.getValueOrUndefined(m._distanceDisplayCondition,e),A.silhouetteColor=f.getValueOrDefault(m._silhouetteColor,e,C,A._silhouetteColor),A.silhouetteSize=f.getValueOrDefault(m._silhouetteSize,e,0),A.color=f.getValueOrDefault(m._color,e,S,A._color),A.colorBlendMode=f.getValueOrDefault(m._colorBlendMode,e,w),A.colorBlendAmount=f.getValueOrDefault(m._colorBlendAmount,e,.5),A.clippingPlanes=f.getValueOrUndefined(m._clippingPlanes,e),A.clampAnimations=f.getValueOrDefault(m._clampAnimations,e,!0),A.ready){var x=f.getValueOrDefault(m._runAnimations,e,!0);g.animationsRunning!==x&&(x?A.activeAnimations.addAll({loop:d.REPEAT}):A.activeAnimations.removeAll(),g.animationsRunning=x);var P=f.getValueOrUndefined(m._nodeTransformations,e,g.nodeTransformationsScratch);if(i(P))for(var D=g.originalNodeMatrixHash,I=Object.keys(P),O=0,M=I.length;O<M;++O){var R=I[O],L=P[R];if(i(L)){var N=A.getNode(R);if(i(N)){var k=D[R];i(k)||(k=N.matrix.clone(),D[R]=k);var F=a.fromTranslationRotationScale(L,E);N.matrix=a.multiply(k,F,F)}}}}}else i(g)&&(g.modelPrimitive.show=!1)}return!0},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(m.prototype._onCollectionChanged,this);for(var e=this._entitiesToVisualize.values,t=this._modelHash,r=this._primitives,i=e.length-1;i>-1;i--)g(this,e[i],t,r);return n(this)},m.prototype.getBoundingSphere=function(e,r){var n=this._modelHash[e.id];if(!i(n))return p.FAILED;var o=n.modelPrimitive;if(!i(o)||!o.show)return p.FAILED;if(!o.ready)return p.PENDING;if(o.heightReference===u.NONE)t.transform(o.boundingSphere,o.modelMatrix,r);else{if(!i(o._clampedModelMatrix))return p.PENDING;t.transform(o.boundingSphere,o._clampedModelMatrix,r)}return p.DONE},m.prototype._onCollectionChanged=function(e,t,r,n){var o,a,s=this._entitiesToVisualize,l=this._modelHash,u=this._primitives;for(o=t.length-1;o>-1;o--)a=t[o],i(a._model)&&i(a._position)&&s.set(a.id,a);for(o=n.length-1;o>-1;o--)a=n[o],i(a._model)&&i(a._position)?(_(a,l),s.set(a.id,a)):(g(this,a,l,u),s.remove(a.id));for(o=r.length-1;o>-1;o--)a=r[o],g(this,a,l,u),s.remove(a.id)},m}),define("Shaders/PolylineCommon",[],function(){"use strict";return"void clipLineSegmentToNearPlane(\nvec3 p0,\nvec3 p1,\nout vec4 positionWC,\nout bool clipped,\nout bool culledByNearPlane)\n{\nculledByNearPlane = false;\nclipped = false;\nvec3 p1ToP0 = p1 - p0;\nfloat magnitude = length(p1ToP0);\nvec3 direction = normalize(p1ToP0);\nfloat endPoint0Distance = -(czm_currentFrustum.x + p0.z);\nfloat denominator = -direction.z;\nif (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7)\n{\nculledByNearPlane = true;\n}\nelse if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7)\n{\nfloat t = (czm_currentFrustum.x + p0.z) / denominator;\nif (t < 0.0 || t > magnitude)\n{\nculledByNearPlane = true;\n}\nelse\n{\np0 = p0 + t * direction;\nclipped = true;\n}\n}\npositionWC = czm_eyeToWindowCoordinates(vec4(p0, 1.0));\n}\nvec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)\n{\nvec4 endPointWC, p0, p1;\nbool culledByNearPlane, clipped;\n#ifdef POLYLINE_DASH\nvec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);\nvec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);\nvec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);\nvec2 lineDir;\nif (usePrevious) {\nlineDir = normalize(positionWindow.xy - previousWindow.xy);\n}\nelse {\nlineDir = normalize(nextWindow.xy - positionWindow.xy);\n}\nangle = atan(lineDir.x, lineDir.y) - 1.570796327;\nangle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;\n#endif\nclipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane);\nclipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane);\nclipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane);\nif (culledByNearPlane)\n{\nreturn vec4(0.0, 0.0, 0.0, 1.0);\n}\nvec2 prevWC = normalize(p0.xy - endPointWC.xy);\nvec2 nextWC = normalize(p1.xy - endPointWC.xy);\nfloat expandWidth = width * 0.5;\nvec2 direction;\nif (czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))\n{\ndirection = vec2(-nextWC.y, nextWC.x);\n}\nelse if (czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) || clipped)\n{\ndirection = vec2(prevWC.y, -prevWC.x);\n}\nelse\n{\nvec2 normal = vec2(-nextWC.y, nextWC.x);\ndirection = normalize((nextWC + prevWC) * 0.5);\nif (dot(direction, normal) < 0.0)\n{\ndirection = -direction;\n}\nfloat sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);\nexpandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);\n}\nvec2 offset = direction * expandDirection * expandWidth * czm_resolutionScale;\nreturn vec4(endPointWC.xy + offset, -endPointWC.z, 1.0);\n}\nvec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)\n{\nvec4 positionEC = czm_modelViewRelativeToEye * position;\nvec4 prevEC = czm_modelViewRelativeToEye * previous;\nvec4 nextEC = czm_modelViewRelativeToEye * next;\nreturn getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);\n}\n"}),define("Shaders/PolylineFS",[],function(){"use strict";return"#ifdef VECTOR_TILE\nuniform vec4 u_highlightColor;\n#endif\nvarying vec2 v_st;\nvoid main()\n{\nczm_materialInput materialInput;\nmaterialInput.s = v_st.s;\nmaterialInput.st = v_st;\nmaterialInput.str = vec3(v_st, 0.0);\nczm_material material = czm_getMaterial(materialInput);\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#ifdef VECTOR_TILE\ngl_FragColor *= u_highlightColor;\n#endif\n}\n"}),define("Shaders/PolylineVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 position2DHigh;\nattribute vec3 position2DLow;\nattribute vec3 prevPosition3DHigh;\nattribute vec3 prevPosition3DLow;\nattribute vec3 prevPosition2DHigh;\nattribute vec3 prevPosition2DLow;\nattribute vec3 nextPosition3DHigh;\nattribute vec3 nextPosition3DLow;\nattribute vec3 nextPosition2DHigh;\nattribute vec3 nextPosition2DLow;\nattribute vec4 texCoordExpandAndBatchIndex;\nvarying vec2 v_st;\nvarying float v_width;\nvarying vec4 czm_pickColor;\nvarying float v_polylineAngle;\nvoid main()\n{\nfloat texCoord = texCoordExpandAndBatchIndex.x;\nfloat expandDir = texCoordExpandAndBatchIndex.y;\nbool usePrev = texCoordExpandAndBatchIndex.z < 0.0;\nfloat batchTableIndex = texCoordExpandAndBatchIndex.w;\nvec2 widthAndShow = batchTable_getWidthAndShow(batchTableIndex);\nfloat width = widthAndShow.x + 0.5;\nfloat show = widthAndShow.y;\nif (width < 1.0)\n{\nshow = 0.0;\n}\nvec4 pickColor = batchTable_getPickColor(batchTableIndex);\nvec4 p, prev, next;\nif (czm_morphTime == 1.0)\n{\np = czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz);\nprev = czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz);\nnext = czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz);\n}\nelse if (czm_morphTime == 0.0)\n{\np = czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy);\nprev = czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy);\nnext = czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy);\n}\nelse\n{\np = czm_columbusViewMorph(\nczm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy),\nczm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz),\nczm_morphTime);\nprev = czm_columbusViewMorph(\nczm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy),\nczm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz),\nczm_morphTime);\nnext = czm_columbusViewMorph(\nczm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy),\nczm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz),\nczm_morphTime);\n}\n#ifdef DISTANCE_DISPLAY_CONDITION\nvec3 centerHigh = batchTable_getCenterHigh(batchTableIndex);\nvec4 centerLowAndRadius = batchTable_getCenterLowAndRadius(batchTableIndex);\nvec3 centerLow = centerLowAndRadius.xyz;\nfloat radius = centerLowAndRadius.w;\nvec2 distanceDisplayCondition = batchTable_getDistanceDisplayCondition(batchTableIndex);\nfloat lengthSq;\nif (czm_sceneMode == czm_sceneMode2D)\n{\nlengthSq = czm_eyeHeight2D.y;\n}\nelse\n{\nvec4 center = czm_translateRelativeToEye(centerHigh.xyz, centerLow.xyz);\nlengthSq = max(0.0, dot(center.xyz, center.xyz) - radius * radius);\n}\nfloat nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x;\nfloat farSq = distanceDisplayCondition.y * distanceDisplayCondition.y;\nif (lengthSq < nearSq || lengthSq > farSq)\n{\nshow = 0.0;\n}\n#endif\nvec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\ngl_Position = czm_viewportOrthographic * positionWC * show;\nv_st = vec2(texCoord, clamp(expandDir, 0.0, 1.0));\nv_width = width;\nczm_pickColor = pickColor;\n}\n"}),define("Scene/Polyline",["../Core/arrayRemoveDuplicates","../Core/BoundingSphere","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/Matrix4","../Core/PolylinePipeline","./Material"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(a,s){a=n(a,n.EMPTY_OBJECT),this._show=n(a.show,!0),this._width=n(a.width,1),this._loop=n(a.loop,!1),this._distanceDisplayCondition=a.distanceDisplayCondition,this._material=a.material,o(this._material)||(this._material=d.fromType(d.ColorType,{color:new i(1,1,1,1)}));var l=a.positions;o(l)||(l=[]),this._positions=l,this._actualPositions=e(l,r.equalsEpsilon),this._loop&&this._actualPositions.length>2&&(this._actualPositions===this._positions&&(this._actualPositions=l.slice()),this._actualPositions.push(r.clone(this._actualPositions[0]))),this._length=this._actualPositions.length,this._id=a.id;var h;o(s)&&(h=u.clone(s.modelMatrix)),this._modelMatrix=h,this._segments=c.wrapLongitude(this._actualPositions,h),this._actualLength=void 0,this._propertiesChanged=new Uint32Array(b),this._polylineCollection=s,this._dirty=!1,this._pickId=void 0,this._boundingVolume=t.fromPoints(this._actualPositions),this._boundingVolumeWC=t.transform(this._boundingVolume,this._modelMatrix),this._boundingVolume2D=new t}function p(e,t){++e._propertiesChanged[t];var r=e._polylineCollection;o(r)&&(r._updatePolyline(e,t),e._dirty=!0)}var f=h.POSITION_INDEX=0,m=h.SHOW_INDEX=1,g=h.WIDTH_INDEX=2,_=h.MATERIAL_INDEX=3,v=h.POSITION_SIZE_INDEX=4,y=h.DISTANCE_DISPLAY_CONDITION=5,b=h.NUMBER_OF_PROPERTIES=6;return a(h.prototype,{show:{get:function(){return this._show},set:function(e){e!==this._show&&(this._show=e,p(this,m))}},positions:{get:function(){return this._positions},set:function(i){var n=e(i,r.equalsEpsilon);this._loop&&n.length>2&&(n===i&&(n=i.slice()),n.push(r.clone(n[0]))),this._actualPositions.length===n.length&&this._actualPositions.length===this._length||p(this,v),this._positions=i,this._actualPositions=n,this._length=n.length,this._boundingVolume=t.fromPoints(this._actualPositions,this._boundingVolume),this._boundingVolumeWC=t.transform(this._boundingVolume,this._modelMatrix,this._boundingVolumeWC),p(this,f),this.update()}},material:{get:function(){return this._material},set:function(e){this._material!==e&&(this._material=e,p(this,_))}},width:{get:function(){return this._width},set:function(e){e!==this._width&&(this._width=e,p(this,g))}},loop:{get:function(){return this._loop},set:function(e){if(e!==this._loop){var t=this._actualPositions;e?t.length>2&&!r.equals(t[0],t[t.length-1])&&(t.length===this._positions.length&&(this._actualPositions=t=this._positions.slice()),t.push(r.clone(t[0]))):t.length>2&&r.equals(t[0],t[t.length-1])&&(t.length-1===this._positions.length?this._actualPositions=this._positions:t.pop()),this._loop=e,p(this,v)}}},id:{get:function(){return this._id},set:function(e){this._id=e,o(this._pickId)&&(this._pickId.object.id=e)}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){l.equals(e,this._distanceDisplayCondition)||(this._distanceDisplayCondition=l.clone(e,this._distanceDisplayCondition),p(this,y))}}}),h.prototype.update=function(){var e=u.IDENTITY;o(this._polylineCollection)&&(e=this._polylineCollection.modelMatrix);var r=this._segments.positions.length,i=this._segments.lengths,n=this._propertiesChanged[f]>0||this._propertiesChanged[v]>0;if(u.equals(e,this._modelMatrix)&&!n||(this._segments=c.wrapLongitude(this._actualPositions,e),this._boundingVolumeWC=t.transform(this._boundingVolume,e,this._boundingVolumeWC)),this._modelMatrix=u.clone(e,this._modelMatrix),this._segments.positions.length!==r)p(this,v);else for(var a=i.length,s=0;s<a;++s)if(i[s]!==this._segments.lengths[s]){p(this,v);break}},h.prototype.getPickId=function(e){return o(this._pickId)||(this._pickId=e.createPickId({primitive:this,collection:this._polylineCollection,id:this._id})),this._pickId},h.prototype._clean=function(){this._dirty=!1;for(var e=this._propertiesChanged,t=0;t<b-1;++t)e[t]=0},h.prototype._destroy=function(){this._pickId=this._pickId&&this._pickId.destroy(),this._material=this._material&&this._material.destroy(),this._polylineCollection=void 0},h}),define("Scene/PolylineCollection",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/combine","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EncodedCartesian3","../Core/IndexDatatype","../Core/Intersect","../Core/Math","../Core/Matrix4","../Core/Plane","../Core/RuntimeError","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/VertexArray","../Shaders/PolylineCommon","../Shaders/PolylineFS","../Shaders/PolylineVS","./BatchTable","./BlendingState","./Material","./Polyline","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F){"use strict";function B(e){e=l(e,l.EMPTY_OBJECT),this.modelMatrix=_.clone(l(e.modelMatrix,_.IDENTITY)),this._modelMatrix=_.clone(_.IDENTITY),this.debugShowBoundingVolume=l(e.debugShowBoundingVolume,!1),this._opaqueRS=void 0,this._translucentRS=void 0,this._colorCommands=[],this._pickCommands=[],this._polylinesUpdated=!1,this._polylinesRemoved=!1,this._createVertexArray=!1,this._propertiesChanged=new Uint32Array(ae),this._polylines=[],this._polylineBuckets={},this._positionBufferUsage={bufferUsage:C.STATIC_DRAW,frameCount:0},this._mode=void 0,this._polylinesToUpdate=[],this._vertexArrays=[],this._positionBuffer=void 0,this._texCoordExpandAndBatchIndexBuffer=void 0,this._batchTable=void 0,this._createBatchTable=!1,this._useHighlightColor=!1,this._highlightColor=o.clone(o.WHITE);var t=this;this._uniformMap={u_highlightColor:function(){return t._highlightColor}}}function U(e,t){u(e._batchTable)&&e._batchTable.destroy();var r=[{functionName:"batchTable_getWidthAndShow",componentDatatype:s.UNSIGNED_BYTE,componentsPerAttribute:2},{functionName:"batchTable_getPickColor",componentDatatype:s.UNSIGNED_BYTE,componentsPerAttribute:4,normalize:!0},{functionName:"batchTable_getCenterHigh",componentDatatype:s.FLOAT,componentsPerAttribute:3},{functionName:"batchTable_getCenterLowAndRadius",componentDatatype:s.FLOAT,componentsPerAttribute:4},{functionName:"batchTable_getDistanceDisplayCondition",componentDatatype:s.FLOAT,componentsPerAttribute:2}];e._batchTable=new R(t,r,e._polylines.length)}function V(t,r,i,n,o){for(var s=r.context,l=r.commandList,c=i.length,d=0,h=!0,p=t._vertexArrays,f=t.debugShowBoundingVolume,m=t._batchTable,g=m.getUniformMapCallback(),_=p.length,v=0;v<_;++v)for(var y=p[v],b=y.buckets,C=b.length,S=0;S<C;++S){for(var E,A,x,P,D=b[S],I=D.offset,O=o?D.bucket.shaderProgram:D.bucket.pickShaderProgram,M=D.bucket.polylines,R=M.length,L=0,N=0;N<R;++N){var k=M[N],B=H(k._material);if(B!==E){if(u(E)&&L>0){var U=A.isTranslucent();d>=c?(x=new w({owner:t}),i.push(x)):x=i[d],++d,P=a(g(A._uniforms),t._uniformMap),x.boundingVolume=e.clone(de,x.boundingVolume),x.modelMatrix=n,x.shaderProgram=O,x.vertexArray=y.va,x.renderState=U?t._translucentRS:t._opaqueRS,x.pass=U?T.TRANSLUCENT:T.OPAQUE,x.debugShowBoundingVolume=!!o&&f,x.uniformMap=P,x.count=L,x.offset=I,I+=L,L=0,h=!0,l.push(x)}A=k._material,A.update(s),E=B}for(var V=k._locatorBuckets,z=V.length,G=0;G<z;++G){var W=V[G];W.locator===D&&(L+=W.count)}var j;r.mode===F.SCENE3D?j=k._boundingVolumeWC:r.mode===F.COLUMBUS_VIEW?j=k._boundingVolume2D:r.mode===F.SCENE2D?u(k._boundingVolume2D)&&(j=e.clone(k._boundingVolume2D,he),j.center.x=0):u(k._boundingVolumeWC)&&u(k._boundingVolume2D)&&(j=e.union(k._boundingVolumeWC,k._boundingVolume2D,he)),h?(h=!1,e.clone(j,de)):e.union(j,de,de)}u(E)&&L>0&&(d>=c?(x=new w({owner:t}),i.push(x)):x=i[d],++d,P=a(g(A._uniforms),t._uniformMap),x.boundingVolume=e.clone(de,x.boundingVolume),x.modelMatrix=n,x.shaderProgram=O,x.vertexArray=y.va,x.renderState=A.isTranslucent()?t._translucentRS:t._opaqueRS,x.pass=A.isTranslucent()?T.TRANSLUCENT:T.OPAQUE,x.debugShowBoundingVolume=!!o&&f,x.uniformMap=P,x.count=L,x.offset=I,h=!0,l.push(x)),E=void 0}i.length=d}function z(e){var t=!1,r=e._propertiesChanged,i=e._positionBufferUsage;return r[re]?i.bufferUsage!==C.STREAM_DRAW?(t=!0,i.bufferUsage=C.STREAM_DRAW,i.frameCount=100):i.frameCount=100:i.bufferUsage!==C.STATIC_DRAW&&(0===i.frameCount?(t=!0,i.bufferUsage=C.STATIC_DRAW):i.frameCount--),t}function G(e,t,r){e._createVertexArray=!1,X(e),Q(e),j(e);var i,n,o=[[]],a=o[0],l=e._batchTable,c=e._useHighlightColor,d=[0],h=0,p=[[]],m=0,_=e._polylineBuckets;for(i in _)_.hasOwnProperty(i)&&(n=_[i],n.updateShader(t,l,c),m+=n.lengthOfPositions);if(m>0){var v,y=e._mode,S=new Float32Array(6*m*3),w=new Float32Array(4*m),T=0,E=0,A=0;for(i in _)if(_.hasOwnProperty(i)){n=_[i],n.write(S,w,T,E,A,l,t,r),y===F.MORPHING&&(u(v)||(v=new Float32Array(6*m*3)),n.writeForMorph(v,T));var x=n.lengthOfPositions;T+=6*x*3,E+=4*x,A+=4*x,h=n.updateIndices(o,d,p,h)}var P=e._positionBufferUsage.bufferUsage,I=C.STATIC_DRAW;e._positionBuffer=b.createVertexBuffer({context:t,typedArray:S,usage:P});var O;u(v)&&(O=b.createVertexBuffer({context:t,typedArray:v,usage:P})),e._texCoordExpandAndBatchIndexBuffer=b.createVertexBuffer({context:t,typedArray:w,usage:I});for(var M=3*Float32Array.BYTES_PER_ELEMENT,R=4*Float32Array.BYTES_PER_ELEMENT,L=0,N=o.length,k=0;k<N;++k)if(a=o[k],a.length>0){var B=new Uint16Array(a),U=b.createIndexBuffer({context:t,typedArray:B,usage:C.STATIC_DRAW,indexDatatype:f.UNSIGNED_SHORT});L+=d[k];var V,z,G,W,H=6*(k*(M*g.SIXTY_FOUR_KILOBYTES)-L*M),q=M+H,Y=M+q,Z=M+Y,K=M+Z,J=M+K,$=k*(R*g.SIXTY_FOUR_KILOBYTES)-L*R,ee=[{index:se.position3DHigh,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:H,strideInBytes:6*M},{index:se.position3DLow,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:q,strideInBytes:6*M},{index:se.position2DHigh,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:H,strideInBytes:6*M},{index:se.position2DLow,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:q,strideInBytes:6*M},{index:se.prevPosition3DHigh,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:Y,strideInBytes:6*M},{index:se.prevPosition3DLow,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:Z,strideInBytes:6*M},{index:se.prevPosition2DHigh,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:Y,strideInBytes:6*M},{index:se.prevPosition2DLow,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:Z,strideInBytes:6*M},{index:se.nextPosition3DHigh,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:K,strideInBytes:6*M},{index:se.nextPosition3DLow,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:J,strideInBytes:6*M},{index:se.nextPosition2DHigh,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:K,strideInBytes:6*M},{index:se.nextPosition2DLow,componentsPerAttribute:3,componentDatatype:s.FLOAT,offsetInBytes:J,strideInBytes:6*M},{index:se.texCoordExpandAndBatchIndex,componentsPerAttribute:4,componentDatatype:s.FLOAT,vertexBuffer:e._texCoordExpandAndBatchIndexBuffer,offsetInBytes:$}];y===F.SCENE3D?(V=e._positionBuffer,z="vertexBuffer",G=pe,W="value"):y===F.SCENE2D||y===F.COLUMBUS_VIEW?(V=pe,z="value",G=e._positionBuffer,W="vertexBuffer"):(V=O,z="vertexBuffer",G=e._positionBuffer,W="vertexBuffer"),ee[0][z]=V,ee[1][z]=V,ee[2][W]=G,ee[3][W]=G,ee[4][z]=V,ee[5][z]=V,ee[6][W]=G,ee[7][W]=G,ee[8][z]=V,ee[9][z]=V,ee[10][W]=G,ee[11][W]=G;var te=new D({context:t,attributes:ee,indexBuffer:U});e._vertexArrays.push({va:te,buckets:p[k]})}}}function W(e,t){return t instanceof P?t.id:t}function H(e){var t=N._uniformList[e.type],r=t.length;fe.length=2*r;for(var i=0,n=0;n<r;++n){var o=t[n];fe[i]=o,fe[i+1]=e._uniforms[o](),i+=2}return e.type+":"+JSON.stringify(fe,W)}function j(e){for(var t=e._mode,r=e._modelMatrix,i=e._polylineBuckets={},n=e._polylines,o=n.length,a=0;a<o;++a){var s=n[a];if(s._actualPositions.length>1){s.update();var l=s.material,c=i[l.type];u(c)||(c=i[l.type]=new J(l,t,r)),c.addPolyline(s)}}}function q(e,t){var r=t.mode;e._mode===r&&_.equals(e._modelMatrix,e.modelMatrix)||(e._mode=r,e._modelMatrix=_.clone(e.modelMatrix),e._createVertexArray=!0)}function Y(e){if(e._polylinesRemoved){e._polylinesRemoved=!1;for(var t=[],r=e._polylines.length,i=0,n=0;i<r;++i){var o=e._polylines[i];u(o)&&(o._index=n++,t.push(o))}e._polylines=t}}function X(e){for(var t=e._polylines,r=t.length,i=0;i<r;++i)if(u(t[i])){var n=t[i]._bucket;u(n)&&(n.shaderProgram=n.shaderProgram&&n.shaderProgram.destroy())}}function Q(e){for(var t=e._vertexArrays.length,r=0;r<t;++r)e._vertexArrays[r].va.destroy();e._vertexArrays.length=0}function Z(e){for(var t=e._polylines,r=t.length,i=0;i<r;++i)u(t[i])&&t[i]._destroy()}function K(e,t,r){this.count=e,this.offset=t,this.bucket=r}function J(e,t,r){this.polylines=[],this.lengthOfPositions=0,this.material=e,this.shaderProgram=void 0,this.pickShaderProgram=void 0,this.mode=t,this.modelMatrix=r}function $(e){return r.dot(r.UNIT_X,e._boundingVolume.center)<0||e._boundingVolume.intersectPlane(v.ORIGIN_ZX_PLANE)===m.INTERSECTING}var ee=k.SHOW_INDEX,te=k.WIDTH_INDEX,re=k.POSITION_INDEX,ie=k.MATERIAL_INDEX,ne=k.POSITION_SIZE_INDEX,oe=k.DISTANCE_DISPLAY_CONDITION,ae=k.NUMBER_OF_PROPERTIES,se={texCoordExpandAndBatchIndex:0,position3DHigh:1,position3DLow:2,position2DHigh:3,position2DLow:4,prevPosition3DHigh:5,prevPosition3DLow:6,prevPosition2DHigh:7,prevPosition2DLow:8,nextPosition3DHigh:9,nextPosition3DLow:10,nextPosition2DHigh:11,nextPosition2DLow:12};c(B.prototype,{length:{get:function(){return Y(this),this._polylines.length}}}),B.prototype.add=function(e){var t=new k(e,this);return t._index=this._polylines.length,this._polylines.push(t),this._createVertexArray=!0,this._createBatchTable=!0,t},B.prototype.remove=function(e){if(this.contains(e)){if(this._polylines[e._index]=void 0,this._polylinesRemoved=!0,this._createVertexArray=!0,this._createBatchTable=!0,u(e._bucket)){var t=e._bucket;t.shaderProgram=t.shaderProgram&&t.shaderProgram.destroy(),t.pickShaderProgram=t.pickShaderProgram&&t.pickShaderProgram.destroy()}return e._destroy(),!0}return!1},B.prototype.removeAll=function(){X(this),Z(this),this._polylineBuckets={},this._polylinesRemoved=!1,this._polylines.length=0,this._polylinesToUpdate.length=0,this._createVertexArray=!0},B.prototype.contains=function(e){return u(e)&&e._polylineCollection===this},B.prototype.get=function(e){return Y(this),this._polylines[e]};var le=new p,ue=new i,ce=new t;B.prototype.update=function(e){if(Y(this),0!==this._polylines.length){q(this,e);var r,n=e.context,o=e.mapProjection,a=this._propertiesChanged;if(this._createBatchTable){if(0===S.maximumVertexTextureImageUnits)throw new y("Vertex texture fetch support is required to render polylines. The maximum number of vertex texture image units must be greater than zero.");U(this,n),this._createBatchTable=!1}if(this._createVertexArray||z(this))G(this,n,o);else if(this._polylinesUpdated){var s=this._polylinesToUpdate;if(this._mode!==F.SCENE3D)for(var l=s.length,c=0;c<l;++c)r=s[c],r.update();if(a[ne]||a[ie])G(this,n,o);else for(var d=s.length,h=this._polylineBuckets,f=0;f<d;++f){r=s[f],a=r._propertiesChanged;var m=r._bucket,g=0;for(var v in h)if(h.hasOwnProperty(v)){if(h[v]===m){a[re]&&m.writeUpdate(g,r,this._positionBuffer,o);break}g+=h[v].lengthOfPositions}if((a[ee]||a[te])&&this._batchTable.setBatchedAttribute(r._index,0,new t(r._width,r._show)),this._batchTable.attributes.length>2){if(a[re]||a[ne]){var b=e.mode===F.SCENE2D?r._boundingVolume2D:r._boundingVolumeWC,C=p.fromCartesian(b.center,le),w=i.fromElements(C.low.x,C.low.y,C.low.z,b.radius,ue);this._batchTable.setBatchedAttribute(r._index,2,C.high),this._batchTable.setBatchedAttribute(r._index,3,w)}if(a[oe]){var T=ce;T.x=0,T.y=Number.MAX_VALUE;var A=r.distanceDisplayCondition;u(A)&&(T.x=A.near,T.y=A.far),this._batchTable.setBatchedAttribute(r._index,4,T)}}r._clean()}s.length=0,this._polylinesUpdated=!1}a=this._propertiesChanged;for(var x=0;x<ae;++x)a[x]=0;var P=_.IDENTITY;e.mode===F.SCENE3D&&(P=this.modelMatrix);var D=e.passes,I=0!==e.morphTime;if(u(this._opaqueRS)&&this._opaqueRS.depthTest.enabled===I||(this._opaqueRS=E.fromCache({depthMask:I,depthTest:{enabled:I}})),u(this._translucentRS)&&this._translucentRS.depthTest.enabled===I||(this._translucentRS=E.fromCache({blending:L.ALPHA_BLEND,depthMask:!I,depthTest:{enabled:I}})),this._batchTable.update(e),D.render){V(this,e,this._colorCommands,P,!0)}if(D.pick){V(this,e,this._pickCommands,P,!1)}}};var de=new e,he=new e;B.prototype.isDestroyed=function(){return!1},B.prototype.destroy=function(){return Q(this),X(this),Z(this),this._batchTable=this._batchTable&&this._batchTable.destroy(),d(this)};var pe=[0,0,0],fe=[];B.prototype._updatePolyline=function(e,t){this._polylinesUpdated=!0,this._polylinesToUpdate.push(e),++this._propertiesChanged[t]},J.prototype.addPolyline=function(e){this.polylines.push(e),e._actualLength=this.getPolylinePositionsLength(e),this.lengthOfPositions+=e._actualLength, +e._bucket=this},J.prototype.updateShader=function(e,t,r){if(!u(this.shaderProgram)){var i=["DISTANCE_DISPLAY_CONDITION"];r&&i.push("VECTOR_TILE"),-1!==this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g)&&i.push("POLYLINE_DASH");var n=new x({defines:i,sources:[this.material.shaderSource,O]}),o=t.getVertexShaderCallback()(M),a=new x({defines:i,sources:[I,o]}),s=new x({sources:n.sources,pickColorQualifier:"varying"});this.shaderProgram=A.fromCache({context:e,vertexShaderSource:a,fragmentShaderSource:n,attributeLocations:se}),this.pickShaderProgram=A.fromCache({context:e,vertexShaderSource:a,fragmentShaderSource:s,attributeLocations:se})}},J.prototype.getPolylinePositionsLength=function(e){var t;if(this.mode===F.SCENE3D||!$(e))return 4*(t=e._actualPositions.length)-4;var r=0,i=e._segments.lengths;t=i.length;for(var n=0;n<t;++n)r+=4*i[n]-4;return r};var me=new r,ge=new r,_e=new r,ve=new r,ye=new i,be=new t;J.prototype.write=function(e,t,n,a,s,l,c,d){for(var h=this.mode,f=d.ellipsoid.maximumRadius*g.PI,m=this.polylines,_=m.length,v=0;v<_;++v){for(var y,b=m[v],C=b.width,S=b.show&&C>0,w=b._index,T=this.getSegments(b,d),E=T.positions,A=T.lengths,x=E.length,P=b.getPickId(c).color,D=0,I=0,O=0;O<x;++O){0===O?b._loop?y=E[x-2]:(y=ve,r.subtract(E[0],E[1],y),r.add(E[0],y,y)):y=E[O-1],r.clone(y,ge),r.clone(E[O],me),O===x-1?b._loop?y=E[1]:(y=ve,r.subtract(E[x-1],E[x-2],y),r.add(E[x-1],y,y)):y=E[O+1],r.clone(y,_e);var M=A[D];O===I+M&&(I+=M,++D);var R=O-I==0,L=O===I+A[D]-1;h===F.SCENE2D&&(ge.z=0,me.z=0,_e.z=0),h!==F.SCENE2D&&h!==F.MORPHING||(R||L)&&f-Math.abs(me.x)<1&&((me.x<0&&ge.x>0||me.x>0&&ge.x<0)&&r.clone(me,ge),(me.x<0&&_e.x>0||me.x>0&&_e.x<0)&&r.clone(me,_e));for(var N=R?2:0,k=L?2:4,B=N;B<k;++B){p.writeElements(me,e,n),p.writeElements(ge,e,n+6),p.writeElements(_e,e,n+12);var U=B-2<0?-1:1;t[s]=O/(x-1),t[s+1]=B%2*2-1,t[s+2]=U,t[s+3]=w,n+=18,s+=4}}var V=ye;V.x=o.floatToByte(P.red),V.y=o.floatToByte(P.green),V.z=o.floatToByte(P.blue),V.w=o.floatToByte(P.alpha);var z=be;z.x=C,z.y=S?1:0;var G=h===F.SCENE2D?b._boundingVolume2D:b._boundingVolumeWC,W=p.fromCartesian(G.center,le),H=W.high,j=i.fromElements(W.low.x,W.low.y,W.low.z,G.radius,ue),q=ce;q.x=0,q.y=Number.MAX_VALUE;var Y=b.distanceDisplayCondition;u(Y)&&(q.x=Y.near,q.y=Y.far),l.setBatchedAttribute(w,0,z),l.setBatchedAttribute(w,1,V),l.attributes.length>2&&(l.setBatchedAttribute(w,2,H),l.setBatchedAttribute(w,3,j),l.setBatchedAttribute(w,4,q))}};var Ce=new r,Se=new r,we=new r,Te=new r;J.prototype.writeForMorph=function(e,t){for(var i=this.modelMatrix,n=this.polylines,o=n.length,a=0;a<o;++a)for(var s=n[a],l=s._segments.positions,u=s._segments.lengths,c=l.length,d=0,h=0,f=0;f<c;++f){var m;0===f?s._loop?m=l[c-2]:(m=Te,r.subtract(l[0],l[1],m),r.add(l[0],m,m)):m=l[f-1],m=_.multiplyByPoint(i,m,Se);var g,v=_.multiplyByPoint(i,l[f],Ce);f===c-1?s._loop?g=l[1]:(g=Te,r.subtract(l[c-1],l[c-2],g),r.add(l[c-1],g,g)):g=l[f+1],g=_.multiplyByPoint(i,g,we);var y=u[d];f===h+y&&(h+=y,++d);for(var b=f-h==0,C=f===h+u[d]-1,S=b?2:0,w=C?2:4,T=S;T<w;++T)p.writeElements(v,e,t),p.writeElements(m,e,t+6),p.writeElements(g,e,t+12),t+=18}};var Ee=new Array(1);J.prototype.updateIndices=function(e,t,r,i){var n=r.length-1,o=new K(0,i,this);r[n].push(o);var a=0,s=e[e.length-1],l=0;s.length>0&&(l=s[s.length-1]+1);for(var u=this.polylines,c=u.length,d=0;d<c;++d){var h=u[d];h._locatorBuckets=[];var p;if(this.mode===F.SCENE3D){p=Ee;var f=h._actualPositions.length;if(!(f>0))continue;p[0]=f}else p=h._segments.lengths;var m=p.length;if(m>0){for(var _=0,v=0;v<m;++v)for(var y=p[v]-1,b=0;b<y;++b)l+4>g.SIXTY_FOUR_KILOBYTES&&(h._locatorBuckets.push({locator:o,count:_}),_=0,t.push(4),s=[],e.push(s),l=0,o.count=a,a=0,i=0,o=new K(0,0,this),r[++n]=[o]),s.push(l,l+2,l+1),s.push(l+1,l+2,l+3),_+=6,a+=6,i+=6,l+=4;h._locatorBuckets.push({locator:o,count:_}),l+4>g.SIXTY_FOUR_KILOBYTES&&(t.push(0),s=[],e.push(s),l=0,o.count=a,i=0,a=0,o=new K(0,0,this),r[++n]=[o])}h._clean()}return o.count=a,i},J.prototype.getPolylineStartIndex=function(e){for(var t=this.polylines,r=0,i=t.length,n=0;n<i;++n){var o=t[n];if(o===e)break;r+=o._actualLength}return r};var Ae={positions:void 0,lengths:void 0},xe=new Array(1),Pe=new r,De=new n;J.prototype.getSegments=function(t,i){var n=t._actualPositions;if(this.mode===F.SCENE3D)return xe[0]=n.length,Ae.positions=n,Ae.lengths=xe,Ae;$(t)&&(n=t._segments.positions);for(var o,a=i.ellipsoid,s=[],l=this.modelMatrix,u=n.length,c=Pe,d=0;d<u;++d)o=n[d],c=_.multiplyByPoint(l,o,c),s.push(i.project(a.cartesianToCartographic(c,De)));if(s.length>0){t._boundingVolume2D=e.fromPoints(s,t._boundingVolume2D);var h=t._boundingVolume2D.center;t._boundingVolume2D.center=new r(h.z,h.x,h.y)}return Ae.positions=s,Ae.lengths=t._segments.lengths,Ae};var Ie;return J.prototype.writeUpdate=function(e,t,i,n){var o=this.mode,a=n.ellipsoid.maximumRadius*g.PI,s=t._actualLength;if(s){e+=this.getPolylineStartIndex(t);var l=Ie,c=6*s*3;!u(l)||l.length<c?l=Ie=new Float32Array(c):l.length>c&&(l=new Float32Array(l.buffer,0,c));var d,h=this.getSegments(t,n),f=h.positions,m=h.lengths,_=0,v=0,y=0;s=f.length;for(var b=0;b<s;++b){0===b?t._loop?d=f[s-2]:(d=ve,r.subtract(f[0],f[1],d),r.add(f[0],d,d)):d=f[b-1],r.clone(d,ge),r.clone(f[b],me),b===s-1?t._loop?d=f[1]:(d=ve,r.subtract(f[s-1],f[s-2],d),r.add(f[s-1],d,d)):d=f[b+1],r.clone(d,_e);var C=m[v];b===y+C&&(y+=C,++v);var S=b-y==0,w=b===y+m[v]-1;o===F.SCENE2D&&(ge.z=0,me.z=0,_e.z=0),o!==F.SCENE2D&&o!==F.MORPHING||(S||w)&&a-Math.abs(me.x)<1&&((me.x<0&&ge.x>0||me.x>0&&ge.x<0)&&r.clone(me,ge),(me.x<0&&_e.x>0||me.x>0&&_e.x<0)&&r.clone(me,_e));for(var T=S?2:0,E=w?2:4,A=T;A<E;++A)p.writeElements(me,l,_),p.writeElements(ge,l,_+6),p.writeElements(_e,l,_+12),_+=18}i.copyFromArrayView(l,18*Float32Array.BYTES_PER_ELEMENT*e)}},B}),define("DataSources/ScaledPositionProperty",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Ellipsoid","../Core/Event","../Core/ReferenceFrame","./Property"],function(e,t,r,i,n,o,a){"use strict";function s(e){this._definitionChanged=new n,this._value=void 0,this._removeSubscription=void 0,this.setValue(e)}return t(s.prototype,{isConstant:{get:function(){return a.isConstant(this._value)}},definitionChanged:{get:function(){return this._definitionChanged}},referenceFrame:{get:function(){return e(this._value)?this._value.referenceFrame:o.FIXED}}}),s.prototype.getValue=function(e,t){return this.getValueInReferenceFrame(e,o.FIXED,t)},s.prototype.setValue=function(t){this._value!==t&&(this._value=t,e(this._removeSubscription)&&(this._removeSubscription(),this._removeSubscription=void 0),e(t)&&(this._removeSubscription=t.definitionChanged.addEventListener(this._raiseDefinitionChanged,this)),this._definitionChanged.raiseEvent(this))},s.prototype.getValueInReferenceFrame=function(t,r,n){if(e(this._value))return n=this._value.getValueInReferenceFrame(t,r,n),e(n)?i.WGS84.scaleToGeodeticSurface(n,n):void 0},s.prototype.equals=function(e){return this===e||e instanceof s&&this._value===e._value},s.prototype._raiseDefinitionChanged=function(){this._definitionChanged.raiseEvent(this)},s}),define("DataSources/PathVisualizer",["../Core/AssociativeArray","../Core/Cartesian3","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/JulianDate","../Core/Matrix3","../Core/Matrix4","../Core/ReferenceFrame","../Core/TimeInterval","../Core/Transforms","../Scene/PolylineCollection","../Scene/SceneMode","./CompositePositionProperty","./ConstantPositionProperty","./MaterialProperty","./Property","./ReferenceProperty","./SampledPositionProperty","./ScaledPositionProperty","./TimeIntervalCollectionPositionProperty"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b){"use strict";function C(e){this.entity=e,this.polyline=void 0,this.index=void 0,this.updater=void 0}function S(e,t,i,n,a,s,l,u,c){var d,h=u;d=e.getValueInReferenceFrame(t,s,c[h]),r(d)&&(c[h++]=d);for(var p,f,m,g=!r(a)||o.lessThanOrEquals(a,t)||o.greaterThanOrEquals(a,i),_=0,v=n.length,y=n[_],b=i,C=!1;_<v;){if(!g&&o.greaterThanOrEquals(y,a)&&(d=e.getValueInReferenceFrame(a,s,c[h]),r(d)&&(c[h++]=d),g=!0),o.greaterThan(y,t)&&o.lessThan(y,b)&&!y.equals(a)&&(d=e.getValueInReferenceFrame(y,s,c[h]),r(d)&&(c[h++]=d)),_<v-1){if(l>0&&!C){var S=n[_+1],w=o.secondsDifference(S,y);C=w>l,C&&(p=Math.ceil(w/l),f=0,m=w/Math.max(p,2),p=Math.max(p-1,1))}if(C&&f<p){y=o.addSeconds(y,m,new o),f++;continue}}C=!1,_++,y=n[_]}return d=e.getValueInReferenceFrame(i,s,c[h]),r(d)&&(c[h++]=d),h}function w(e,t,i,n,a,s,l,u){for(var c,d=0,h=l,p=t,f=Math.max(s,60),m=!r(n)||o.lessThanOrEquals(n,t)||o.greaterThanOrEquals(n,i);o.lessThan(p,i);)!m&&o.greaterThanOrEquals(p,n)&&(m=!0,c=e.getValueInReferenceFrame(n,a,u[h]),r(c)&&(u[h]=c,h++)),c=e.getValueInReferenceFrame(p,a,u[h]),r(c)&&(u[h]=c,h++),d++,p=o.addSeconds(t,f*d,new o);return c=e.getValueInReferenceFrame(i,a,u[h]),r(c)&&(u[h]=c,h++),h}function T(e,t,i,n,a,s,l,c){R.start=t,R.stop=i;for(var d=l,h=e.intervals,p=0;p<h.length;p++){var f=h.get(p);if(!u.intersect(f,R,O).isEmpty){var m=f.start;f.isStartIncluded||(m=f.isStopIncluded?f.stop:o.addSeconds(f.start,o.secondsDifference(f.stop,f.start)/2,new o));var g=e.getValueInReferenceFrame(m,a,c[d]);r(g)&&(c[d]=g,d++)}}return d}function E(e,t,i,n,o,a,s,l){var u=e.getValueInReferenceFrame(t,o,l[s]);return r(u)&&(l[s++]=u),s}function A(e,t,r,i,n,a,s,l){M.start=t,M.stop=r;for(var c=s,d=e.intervals,h=0;h<d.length;h++){var p=d.get(h);if(!u.intersect(p,M,O).isEmpty){var f=p.start,m=p.stop,g=t;o.greaterThan(f,g)&&(g=f);var _=r;o.lessThan(m,_)&&(_=m),c=x(p.data,g,_,i,n,a,c,l)}}return c}function x(e,t,r,i,n,o,a,s){for(;e instanceof _;)e=e.resolvedProperty;if(e instanceof v){a=S(e,t,r,e._property._times,i,n,o,a,s)}else a=e instanceof p?A(e,t,r,i,n,o,a,s):e instanceof b?T(e,t,r,i,n,o,a,s):e instanceof f||e instanceof y&&g.isConstant(e)?E(e,t,r,i,n,o,a,s):w(e,t,r,i,n,o,a,s);return a}function P(e,t,i,n,o,a,s){r(s)||(s=[]);var l=x(e,t,i,n,o,a,0,s);return s.length=l,s}function D(e,t){this._unusedIndexes=[],this._polylineCollection=new d,this._scene=e,this._referenceFrame=t,e.primitives.add(this._polylineCollection)}function I(t,r){r.collectionChanged.addEventListener(I.prototype._onCollectionChanged,this),this._scene=t,this._updaters={},this._entityCollection=r,this._items=new e,this._onCollectionChanged(r,r.values,[],[])}var O=new u,M=new u,R=new u,L=new a;return D.prototype.update=function(e){if(this._referenceFrame===l.INERTIAL){var i=c.computeIcrfToFixedMatrix(e,L);r(i)||(i=c.computeTemeToPseudoFixedMatrix(e,L)),s.fromRotationTranslation(i,t.ZERO,this._polylineCollection.modelMatrix)}},D.prototype.updateObject=function(e,t){var i,n,a=t.entity,s=a._path,l=a._position,u=s._show,c=t.polyline,d=a.isShowing&&(!r(u)||u.getValue(e));if(d){var h=g.getValueOrUndefined(s._leadTime,e),p=g.getValueOrUndefined(s._trailTime,e),f=a._availability,_=r(f),v=r(h),y=r(p);if(d=_||v&&y){if(y&&(i=o.addSeconds(e,-p,new o)),v&&(n=o.addSeconds(e,h,new o)),_){var b=f.start,C=f.stop;y&&!o.greaterThan(b,i)||(i=b),v&&!o.lessThan(C,n)||(n=C)}d=o.lessThan(i,n)}}if(!d)return void(r(c)&&(this._unusedIndexes.push(t.index),t.polyline=void 0,c.show=!1,t.index=void 0));if(!r(c)){var S=this._unusedIndexes;if(S.length>0){var w=S.pop();c=this._polylineCollection.get(w),t.index=w}else t.index=this._polylineCollection.length,c=this._polylineCollection.add();c.id=a,t.polyline=c}var T=g.getValueOrDefault(s._resolution,e,60);c.show=!0,c.positions=P(l,i,n,e,this._referenceFrame,T,c.positions.slice()),c.material=m.getValue(e,s._material,c.material),c.width=g.getValueOrDefault(s._width,e,1),c.distanceDisplayCondition=g.getValueOrUndefined(s._distanceDisplayCondition,e,c.distanceDisplayCondition)},D.prototype.removeObject=function(e){var t=e.polyline;r(t)&&(this._unusedIndexes.push(e.index),e.polyline=void 0,t.show=!1,t.id=void 0,e.index=void 0)},D.prototype.destroy=function(){return this._scene.primitives.remove(this._polylineCollection),i(this)},I.prototype.update=function(e){var t=this._updaters;for(var i in t)t.hasOwnProperty(i)&&t[i].update(e);for(var n=this._items.values,o=0,a=n.length;o<a;o++){var s=n[o],u=s.entity,c=u._position,d=s.updater,p=l.FIXED;this._scene.mode===h.SCENE3D&&(p=c.referenceFrame);var f=this._updaters[p];d===f&&r(f)?f.updateObject(e,s):(r(d)&&d.removeObject(s),r(f)||(f=new D(this._scene,p),f.update(e),this._updaters[p]=f),s.updater=f,r(f)&&f.updateObject(e,s))}return!0},I.prototype.isDestroyed=function(){return!1},I.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(I.prototype._onCollectionChanged,this);var e=this._updaters;for(var t in e)e.hasOwnProperty(t)&&e[t].destroy();return i(this)},I.prototype._onCollectionChanged=function(e,t,i,n){var o,a,s,l=this._items;for(o=t.length-1;o>-1;o--)a=t[o],r(a._path)&&r(a._position)&&l.set(a.id,new C(a));for(o=n.length-1;o>-1;o--)a=n[o],r(a._path)&&r(a._position)?l.contains(a.id)||l.set(a.id,new C(a)):(s=l.get(a.id),r(s)&&(s.updater.removeObject(s),l.remove(a.id)));for(o=i.length-1;o>-1;o--)a=i[o],s=l.get(a.id),r(s)&&(r(s.updater)&&s.updater.removeObject(s),l.remove(a.id))},I._subSample=P,I}),define("DataSources/PlaneGeometryUpdater",["../Core/PlaneGeometry","../Core/PlaneOutlineGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/Matrix4","../Core/ShowGeometryInstanceAttribute","../Core/Quaternion","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x){"use strict";function P(e){this.id=e,this.vertexFormat=void 0,this.plane=void 0,this.dimensions=void 0}function D(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(D.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new p,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new P(e),this._onEntityPropertyChanged(e,"plane",e.plane,void 0)}function I(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new P(t._entity)}function O(e,t,n,o){var a,l;s(e)?(a=e.normal,l=e.distance):(a=i.clone(i.UNIT_X,G),l=0),s(t)||(t=new r(1,1));var u=i.multiplyByScalar(a,-l,z);u=g.multiplyByPoint(n,u,u);var c=g.multiplyByPointAsVector(n,a,G);i.normalize(c,c);var d=M(c,i.UNIT_Z),h=r.clone(t,W);return h.z=1,g.fromTranslationQuaternionRotationScale(u,d,h,o)}function M(e,t){var r=i.angleBetween(e,t);if(0===r)return v.clone(v.IDENTITY,j);var n=i.cross(t,e,H);return v.fromAxisAngle(n,r,j)}var R=new w(n.WHITE),L=new T(!0),N=new T(!0),k=new T(!1),F=new T(n.BLACK),B=new T(S.DISABLED),U=new T(new d),V=new n;l(D,{perInstanceColorAppearanceType:{value:b},materialAppearanceType:{value:y}}),l(D.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!s(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!s(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!1},geometryChanged:{get:function(){return this._geometryChanged}}}),D.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},D.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},D.prototype.createFillGeometryInstance=function(t){var r,i,a=this._entity,l=a.isAvailable(t),u=new _(l&&a.isShowing&&this._showProperty.getValue(t)&&this._fillProperty.getValue(t)),c=this._distanceDisplayConditionProperty.getValue(t),d=h.fromDistanceDisplayCondition(c);if(this._materialProperty instanceof w){var p=n.WHITE;s(this._materialProperty.color)&&(this._materialProperty.color.isConstant||l)&&(p=this._materialProperty.color.getValue(t)),i=o.fromColor(p),r={show:u,distanceDisplayCondition:d,color:i}}else r={show:u,distanceDisplayCondition:d};var m=a.plane,g=this._options,v=a.computeModelMatrix(t),y=x.getValueOrDefault(m.plane,t,g.plane),b=x.getValueOrUndefined(m.dimensions,t,g.dimensions);if(s(v)&&s(y)&&s(b))return g.plane=y,g.dimensions=b,v=O(y,b,v,v),new f({id:a,geometry:new e(this._options),modelMatrix:v,attributes:r})},D.prototype.createOutlineGeometryInstance=function(e){var r=this._entity,i=r.isAvailable(e),a=x.getValueOrDefault(this._outlineColorProperty,e,n.BLACK),l=this._distanceDisplayConditionProperty.getValue(e),u=r.plane,c=this._options,d=r.computeModelMatrix(e),p=x.getValueOrDefault(u.plane,e,c.plane),m=x.getValueOrUndefined(u.dimensions,e,c.dimensions);if(s(d)&&s(p)&&s(m))return c.plane=p,c.dimensions=m,d=O(p,m,d,d),new f({id:r,geometry:new t,modelMatrix:d,attributes:{show:new _(i&&r.isShowing&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)),color:o.fromColor(a),distanceDisplayCondition:h.fromDistanceDisplayCondition(l)}})},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){this._entitySubscription(),u(this)},D.prototype._onEntityPropertyChanged=function(e,t,r,i){if("availability"===t||"position"===t||"orientation"===t||"plane"===t){var n=this._entity.plane;if(!s(n))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var o=n.fill,l=!s(o)||!o.isConstant||o.getValue(m.MINIMUM_VALUE),u=n.outline,c=s(u);if(c&&u.isConstant&&(c=u.getValue(m.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var d=n.plane,h=n.dimensions,p=e.position,f=n.show;if(!s(d)||!s(h)||!s(p)||s(f)&&f.isConstant&&!f.getValue(m.MINIMUM_VALUE))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var g=a(n.material,R),_=g instanceof w;this._materialProperty=g,this._fillProperty=a(o,N),this._showProperty=a(f,L),this._showOutlineProperty=a(n.outline,k),this._outlineColorProperty=c?a(n.outlineColor,F):void 0,this._shadowsProperty=a(n.shadows,B),this._distanceDisplayConditionProperty=a(n.distanceDisplayCondition,U);var v=n.outlineWidth;if(this._fillEnabled=l,this._outlineEnabled=c,p.isConstant&&x.isConstant(e.orientation)&&d.isConstant&&h.isConstant&&x.isConstant(v)){var C=this._options;C.vertexFormat=_?b.VERTEX_FORMAT:y.MaterialSupport.TEXTURED.vertexFormat,C.plane=d.getValue(m.MINIMUM_VALUE,C.plane),C.dimensions=h.getValue(m.MINIMUM_VALUE,C.dimensions),this._outlineWidth=s(v)?v.getValue(m.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},D.prototype.createDynamicUpdater=function(e){return new I(e,this)},I.prototype.update=function(r){var i=this._primitives;i.removeAndDestroy(this._primitive),i.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var a=this._geometryUpdater,l=a._entity,u=l.plane;if(l.isShowing&&l.isAvailable(r)&&x.getValueOrDefault(u.show,r,!0)){var c=this._options,d=l.computeModelMatrix(r),p=x.getValueOrDefault(u.plane,r,c.plane),m=x.getValueOrUndefined(u.dimensions,r,c.dimensions);if(s(d)&&s(p)&&s(m)){c.plane=p,c.dimensions=m,d=O(p,m,d,d);var g=this._geometryUpdater.shadowsProperty.getValue(r),_=this._geometryUpdater.distanceDisplayConditionProperty,v=_.getValue(r),S=h.fromDistanceDisplayCondition(v);if(x.getValueOrDefault(u.fill,r,!0)){var w=A.getValue(r,a.fillMaterialProperty,this._material);this._material=w;var T=new y({material:w,translucent:w.isTranslucent(),closed:!0});c.vertexFormat=T.vertexFormat,this._primitive=i.add(new C({geometryInstances:new f({id:l,geometry:new e,modelMatrix:d,attributes:{distanceDisplayCondition:S}}),appearance:T,asynchronous:!1,shadows:g}))}if(x.getValueOrDefault(u.outline,r,!1)){c.vertexFormat=b.VERTEX_FORMAT;var E=x.getValueOrClonedDefault(u.outlineColor,r,n.BLACK,V),P=x.getValueOrDefault(u.outlineWidth,r,1),D=1!==E.alpha;this._outlinePrimitive=i.add(new C({geometryInstances:new f({id:l,geometry:new t,modelMatrix:d,attributes:{color:o.fromColor(E),distanceDisplayCondition:S}}),appearance:new b({flat:!0,translucent:D,renderState:{lineWidth:a._scene.clampLineWidth(P)}}),asynchronous:!1,shadows:g}))}}}};var z=new i,G=new i,W=new i,H=new i,j=new v;return I.prototype.getBoundingSphere=function(e,t){return E(e,this._primitive,this._outlinePrimitive,t)},I.prototype.isDestroyed=function(){return!1},I.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),u(this)},D}),define("Scene/createBillboardPointCallback",[],function(){"use strict";function e(e,t,r,i,n){return function(){var o=document.createElement("canvas"),a=n+2*i;o.height=o.width=a;var s=o.getContext("2d");return s.clearRect(0,0,a,a),0!==i&&(s.beginPath(),s.arc(a/2,a/2,a/2,0,2*Math.PI,!0),s.closePath(),s.fillStyle=r,s.fill(),e<1&&(s.save(),s.globalCompositeOperation="destination-out",s.beginPath(),s.arc(a/2,a/2,n/2,0,2*Math.PI,!0),s.closePath(),s.fillStyle="black",s.fill(),s.restore())),s.beginPath(),s.arc(a/2,a/2,n/2,0,2*Math.PI,!0),s.closePath(),s.fillStyle=t,s.fill(),o}}return e}),define("DataSources/PointVisualizer",["../Core/AssociativeArray","../Core/Cartesian3","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/NearFarScalar","../Scene/createBillboardPointCallback","../Scene/HeightReference","./BoundingSphereState","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e){this.entity=e,this.pointPrimitive=void 0,this.billboard=void 0,this.color=void 0,this.outlineColor=void 0,this.pixelSize=void 0,this.outlineWidth=void 0}function p(t,r){r.collectionChanged.addEventListener(p.prototype._onCollectionChanged,this),this._cluster=t,this._entityCollection=r,this._items=new e,this._onCollectionChanged(r,r.values,[],[])}function f(e,t,r){if(i(e)){var n=e.pointPrimitive;if(i(n))return e.pointPrimitive=void 0,void r.removePoint(t);var o=e.billboard;i(o)&&(e.billboard=void 0,r.removeBillboard(t))}}var m=r.WHITE,g=r.BLACK,_=new r,v=new t,y=new r,b=new s,C=new s,S=new a;return p.prototype.update=function(e){for(var t=this._items.values,n=this._cluster,o=0,a=t.length;o<a;o++){var s=t[o],c=s.entity,h=c._point,p=s.pointPrimitive,w=s.billboard,T=d.getValueOrDefault(h._heightReference,e,u.NONE),E=c.isShowing&&c.isAvailable(e)&&d.getValueOrDefault(h._show,e,!0);if(E&&(v=d.getValueOrUndefined(c._position,e,v),E=i(v)),E){d.isConstant(c._position)||(n._clusterDirty=!0);var A=!1;if(T===u.NONE||i(w)?T!==u.NONE||i(p)||(i(w)&&(f(s,c,n),w=void 0),p=n.getPoint(c),p.id=c,s.pointPrimitive=p):(i(p)&&(f(s,c,n),p=void 0),w=n.getBillboard(c),w.id=c,w.image=void 0,s.billboard=w,A=!0),i(p))p.show=!0,p.position=v,p.scaleByDistance=d.getValueOrUndefined(h._scaleByDistance,e,b),p.translucencyByDistance=d.getValueOrUndefined(h._translucencyByDistance,e,C),p.color=d.getValueOrDefault(h._color,e,m,_),p.outlineColor=d.getValueOrDefault(h._outlineColor,e,g,y),p.outlineWidth=d.getValueOrDefault(h._outlineWidth,e,0),p.pixelSize=d.getValueOrDefault(h._pixelSize,e,1),p.distanceDisplayCondition=d.getValueOrUndefined(h._distanceDisplayCondition,e,S),p.disableDepthTestDistance=d.getValueOrDefault(h._disableDepthTestDistance,e,0);else if(i(w)){w.show=!0,w.position=v,w.scaleByDistance=d.getValueOrUndefined(h._scaleByDistance,e,b),w.translucencyByDistance=d.getValueOrUndefined(h._translucencyByDistance,e,C),w.distanceDisplayCondition=d.getValueOrUndefined(h._distanceDisplayCondition,e,S),w.disableDepthTestDistance=d.getValueOrDefault(h._disableDepthTestDistance,e,0),w.heightReference=T;var x=d.getValueOrDefault(h._color,e,m,_),P=d.getValueOrDefault(h._outlineColor,e,g,y),D=Math.round(d.getValueOrDefault(h._outlineWidth,e,0)),I=Math.max(1,Math.round(d.getValueOrDefault(h._pixelSize,e,1)));if(D>0?(w.scale=1,A=A||D!==s.outlineWidth||I!==s.pixelSize||!r.equals(x,s.color)||!r.equals(P,s.outlineColor)):(w.scale=I/50,I=50,A=A||D!==s.outlineWidth||!r.equals(x,s.color)||!r.equals(P,s.outlineColor)),A){s.color=r.clone(x,s.color),s.outlineColor=r.clone(P,s.outlineColor),s.pixelSize=I,s.outlineWidth=D;var O=x.alpha,M=x.toCssColorString(),R=P.toCssColorString(),L=JSON.stringify([M,I,R,D]);w.setImage(L,l(O,M,R,D,I))}}}else f(s,c,n)}return!0},p.prototype.getBoundingSphere=function(e,r){var n=this._items.get(e.id);if(!i(n)||!i(n.pointPrimitive)&&!i(n.billboard))return c.FAILED;if(i(n.pointPrimitive))r.center=t.clone(n.pointPrimitive.position,r.center);else{var o=n.billboard;if(!i(o._clampedPosition))return c.PENDING;r.center=t.clone(o._clampedPosition,r.center)}return r.radius=0,c.DONE},p.prototype.isDestroyed=function(){return!1},p.prototype.destroy=function(){this._entityCollection.collectionChanged.removeEventListener(p.prototype._onCollectionChanged,this);for(var e=this._entityCollection.values,t=0;t<e.length;t++)this._cluster.removePoint(e[t]);return n(this)},p.prototype._onCollectionChanged=function(e,t,r,n){var o,a,s=this._items,l=this._cluster;for(o=t.length-1;o>-1;o--)a=t[o],i(a._point)&&i(a._position)&&s.set(a.id,new h(a));for(o=n.length-1;o>-1;o--)a=n[o],i(a._point)&&i(a._position)?s.contains(a.id)||s.set(a.id,new h(a)):(f(s.get(a.id),a,l),s.remove(a.id));for(o=r.length-1;o>-1;o--)a=r[o],f(s.get(a.id),a,l),s.remove(a.id)},p}),define("DataSources/PolygonGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/isArray","../Core/Iso8601","../Core/oneTimeWarning","../Core/PolygonGeometry","../Core/PolygonHierarchy","../Core/PolygonOutlineGeometry","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x){"use strict";function P(e){this.id=e,this.vertexFormat=void 0,this.polygonHierarchy=void 0,this.perPositionHeight=void 0,this.closeTop=void 0,this.closeBottom=void 0,this.height=void 0,this.extrudedHeight=void 0,this.granularity=void 0,this.stRotation=void 0}function D(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(D.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._isClosed=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._onTerrain=!1,this._options=new P(e),this._onEntityPropertyChanged(e,"polygon",e.polygon,void 0)}function I(e,t,r){this._primitives=e,this._groundPrimitives=t,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=r,this._options=new P(r._entity)}var O=new w(e.WHITE),M=new T(!0),R=new T(!0),L=new T(!1),N=new T(e.BLACK),k=new T(S.DISABLED),F=new T(new s),B=new e;return n(D,{perInstanceColorAppearanceType:{value:b},materialAppearanceType:{value:y}}),n(D.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&x.isConstant(this._showProperty)&&x.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return this._isClosed}},onTerrain:{get:function(){return this._onTerrain}},geometryChanged:{get:function(){return this._geometryChanged}}}),D.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},D.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},D.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new _(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),h=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof w){var p=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(p=this._materialProperty.color.getValue(r)),o=t.fromColor(p),n={show:u,distanceDisplayCondition:h,color:o}}else n={show:u,distanceDisplayCondition:h};return new c({id:a,geometry:new f(this._options),attributes:n})},D.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=x.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new g(this._options),attributes:{show:new _(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){this._entitySubscription(),o(this)},D.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"polygon"===t){var a=this._entity.polygon;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(h.MINIMUM_VALUE),u=a.perPositionHeight,c=i(u)&&(!u.isConstant||u.getValue(h.MINIMUM_VALUE)),f=a.outline,g=i(f);if(g&&f.isConstant&&(g=f.getValue(h.MINIMUM_VALUE)),!l&&!g)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1, +this._geometryChanged.raiseEvent(this)));var _=a.hierarchy,C=a.show;if(i(C)&&C.isConstant&&!C.getValue(h.MINIMUM_VALUE)||!i(_))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var S=r(a.material,O),T=S instanceof w;this._materialProperty=S,this._fillProperty=r(s,R),this._showProperty=r(C,M),this._showOutlineProperty=r(a.outline,L),this._outlineColorProperty=g?r(a.outlineColor,N):void 0,this._shadowsProperty=r(a.shadows,k),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,F);var E=a.height,A=a.extrudedHeight,P=a.granularity,D=a.stRotation,I=a.outlineWidth,B=l&&!i(E)&&!i(A)&&T&&!c&&v.isSupported(this._scene);g&&B&&(p(p.geometryOutlines),g=!1);var U=a.perPositionHeight,V=a.closeTop,z=a.closeBottom;if(this._fillEnabled=l,this._onTerrain=B,this._outlineEnabled=g,_.isConstant&&x.isConstant(E)&&x.isConstant(A)&&x.isConstant(P)&&x.isConstant(D)&&x.isConstant(I)&&x.isConstant(u)&&x.isConstant(U)&&x.isConstant(V)&&x.isConstant(z)&&(!B||x.isConstant(S))){var G=this._options;G.vertexFormat=T?b.VERTEX_FORMAT:y.MaterialSupport.TEXTURED.vertexFormat;var W=_.getValue(h.MINIMUM_VALUE);d(W)&&(W=new m(W));var H=x.getValueOrUndefined(E,h.MINIMUM_VALUE),j=x.getValueOrDefault(V,h.MINIMUM_VALUE,!0),q=x.getValueOrDefault(z,h.MINIMUM_VALUE,!0),Y=x.getValueOrUndefined(A,h.MINIMUM_VALUE);G.polygonHierarchy=W,G.height=H,G.extrudedHeight=Y,G.granularity=x.getValueOrUndefined(P,h.MINIMUM_VALUE),G.stRotation=x.getValueOrUndefined(D,h.MINIMUM_VALUE),G.perPositionHeight=x.getValueOrUndefined(U,h.MINIMUM_VALUE),G.closeTop=j,G.closeBottom=q,this._outlineWidth=x.getValueOrDefault(I,h.MINIMUM_VALUE,1),this._isClosed=i(Y)&&Y!==H&&j&&q,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},D.prototype.createDynamicUpdater=function(e,t){return new I(e,t,this)},I.prototype.update=function(r){var n=this._geometryUpdater,o=n._onTerrain,a=this._primitives,s=this._groundPrimitives;o?s.removeAndDestroy(this._primitive):(a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._outlinePrimitive=void 0),this._primitive=void 0;var l=n._entity,u=l.polygon;if(l.isShowing&&l.isAvailable(r)&&x.getValueOrDefault(u.show,r,!0)){var h=this._options,p=x.getValueOrUndefined(u.hierarchy,r);if(i(p)){d(p)?h.polygonHierarchy=new m(p):h.polygonHierarchy=p;var _=x.getValueOrDefault(u.closeTop,r,!0),S=x.getValueOrDefault(u.closeBottom,r,!0);h.height=x.getValueOrUndefined(u.height,r),h.extrudedHeight=x.getValueOrUndefined(u.extrudedHeight,r),h.granularity=x.getValueOrUndefined(u.granularity,r),h.stRotation=x.getValueOrUndefined(u.stRotation,r),h.perPositionHeight=x.getValueOrUndefined(u.perPositionHeight,r),h.closeTop=_,h.closeBottom=S;var w=this._geometryUpdater.shadowsProperty.getValue(r);if(x.getValueOrDefault(u.fill,r,!0)){var T=n.fillMaterialProperty,E=A.getValue(r,T,this._material);if(this._material=E,o){var P=e.WHITE;i(T.color)&&(P=T.color.getValue(r)),this._primitive=s.add(new v({geometryInstances:new c({id:l,geometry:new f(h),attributes:{color:t.fromColor(P)}}),asynchronous:!1,shadows:w}))}else{var D=new y({material:E,translucent:E.isTranslucent(),closed:i(h.extrudedHeight)&&h.extrudedHeight!==h.height&&_&&S});h.vertexFormat=D.vertexFormat,this._primitive=a.add(new C({geometryInstances:new c({id:l,geometry:new f(h)}),appearance:D,asynchronous:!1,shadows:w}))}}if(!o&&x.getValueOrDefault(u.outline,r,!1)){h.vertexFormat=b.VERTEX_FORMAT;var I=x.getValueOrClonedDefault(u.outlineColor,r,e.BLACK,B),O=x.getValueOrDefault(u.outlineWidth,r,1),M=1!==I.alpha;this._outlinePrimitive=a.add(new C({geometryInstances:new c({id:l,geometry:new g(h),attributes:{color:t.fromColor(I)}}),appearance:new b({flat:!0,translucent:M,renderState:{lineWidth:n._scene.clampLineWidth(O)}}),asynchronous:!1,shadows:w}))}}}},I.prototype.getBoundingSphere=function(e,t){return E(e,this._primitive,this._outlinePrimitive,t)},I.prototype.isDestroyed=function(){return!1},I.prototype.destroy=function(){var e=this._primitives,t=this._groundPrimitives;this._geometryUpdater._onTerrain?t.removeAndDestroy(this._primitive):e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},D}),define("Shaders/Appearances/PolylineColorAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 prevPosition3DHigh;\nattribute vec3 prevPosition3DLow;\nattribute vec3 nextPosition3DHigh;\nattribute vec3 nextPosition3DLow;\nattribute vec2 expandAndWidth;\nattribute vec4 color;\nattribute float batchId;\nvarying vec4 v_color;\nvoid main()\n{\nfloat expandDir = expandAndWidth.x;\nfloat width = abs(expandAndWidth.y) + 0.5;\nbool usePrev = expandAndWidth.y < 0.0;\nvec4 p = czm_computePosition();\nvec4 prev = czm_computePrevPosition();\nvec4 next = czm_computeNextPosition();\nv_color = color;\nfloat angle;\nvec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);\ngl_Position = czm_viewportOrthographic * positionWC;\n}\n"}),define("Scene/PolylineColorAppearance",["../Core/defaultValue","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/PerInstanceFlatColorAppearanceFS","../Shaders/Appearances/PolylineColorAppearanceVS","../Shaders/PolylineCommon","./Appearance"],function(e,t,r,i,n,o,a){"use strict";function s(t){t=e(t,e.EMPTY_OBJECT);var r=e(t.translucent,!0),i=s.VERTEX_FORMAT;this.material=void 0,this.translucent=r,this._vertexShaderSource=e(t.vertexShaderSource,l),this._fragmentShaderSource=e(t.fragmentShaderSource,u),this._renderState=a.getDefaultRenderState(r,!1,t.renderState),this._closed=!1,this._vertexFormat=i}var l=o+"\n"+n,u=i;return t(s.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return this._vertexFormat}}}),s.VERTEX_FORMAT=r.POSITION_ONLY,s.prototype.getFragmentShaderSource=a.prototype.getFragmentShaderSource,s.prototype.isTranslucent=a.prototype.isTranslucent,s.prototype.getRenderState=a.prototype.getRenderState,s}),define("Shaders/Appearances/PolylineMaterialAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec3 prevPosition3DHigh;\nattribute vec3 prevPosition3DLow;\nattribute vec3 nextPosition3DHigh;\nattribute vec3 nextPosition3DLow;\nattribute vec2 expandAndWidth;\nattribute vec2 st;\nattribute float batchId;\nvarying float v_width;\nvarying vec2 v_st;\nvarying float v_polylineAngle;\nvoid main()\n{\nfloat expandDir = expandAndWidth.x;\nfloat width = abs(expandAndWidth.y) + 0.5;\nbool usePrev = expandAndWidth.y < 0.0;\nvec4 p = czm_computePosition();\nvec4 prev = czm_computePrevPosition();\nvec4 next = czm_computeNextPosition();\nv_width = width;\nv_st = st;\nvec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\ngl_Position = czm_viewportOrthographic * positionWC;\n}\n"}),define("Scene/PolylineMaterialAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/PolylineMaterialAppearanceVS","../Shaders/PolylineCommon","../Shaders/PolylineFS","./Appearance","./Material"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.translucent,!0),n=u.VERTEX_FORMAT;this.material=t(r.material)?r.material:l.fromType(l.ColorType),this.translucent=i,this._vertexShaderSource=e(r.vertexShaderSource,c),this._fragmentShaderSource=e(r.fragmentShaderSource,d),this._renderState=s.getDefaultRenderState(i,!1,r.renderState),this._closed=!1,this._vertexFormat=n}var c=o+"\n"+n,d=a;return r(u.prototype,{vertexShaderSource:{get:function(){var e=this._vertexShaderSource;return-1!==this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g)&&(e="#define POLYLINE_DASH\n"+e),e}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return this._vertexFormat}}}),u.VERTEX_FORMAT=i.POSITION_AND_ST,u.prototype.getFragmentShaderSource=s.prototype.getFragmentShaderSource,u.prototype.isTranslucent=s.prototype.isTranslucent,u.prototype.getRenderState=s.prototype.getRenderState,u}),define("DataSources/PolylineGeometryUpdater",["../Core/BoundingSphere","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/PolylineGeometry","../Core/PolylinePipeline","../Core/ShowGeometryInstanceAttribute","../Scene/PolylineCollection","../Scene/PolylineColorAppearance","../Scene/PolylineMaterialAppearance","../Scene/ShadowMode","./BoundingSphereState","./ColorMaterialProperty","./ConstantProperty","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T){"use strict";function E(e){this.id=e,this.vertexFormat=void 0,this.positions=void 0,this.width=void 0,this.followSurface=void 0,this.granularity=void 0}function A(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(A.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._geometryChanged=new c,this._showProperty=void 0,this._materialProperty=void 0,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._depthFailMaterialProperty=void 0,this._options=new E(e),this._onEntityPropertyChanged(e,"polyline",e.polyline,void 0)}function x(e,t){var r=t._scene.id,i=P[r];!n(i)||i.isDestroyed()?(i=new g,P[r]=i,e.add(i)):e.contains(i)||e.add(i);var o=i.add();o.id=t._entity,this._line=o,this._primitives=e,this._geometryUpdater=t,this._positions=[]}var P={},D=new C(t.WHITE),I=new S(!0),O=new S(y.DISABLED),M=new S(new l);o(A,{perInstanceColorAppearanceType:{value:_},materialAppearanceType:{value:v}}),o(A.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!n(this._entity.availability)&&T.isConstant(this._showProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},depthFailMaterialProperty:{get:function(){return this._depthFailMaterialProperty}},outlineEnabled:{value:!1},hasConstantOutline:{value:!0},outlineColorProperty:{value:void 0},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!1},geometryChanged:{get:function(){return this._geometryChanged}}}),A.prototype.isOutlineVisible=function(e){return!1},A.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)},A.prototype.createFillGeometryInstance=function(e){var i,o=this._entity,a=o.isAvailable(e),s=new m(a&&o.isShowing&&this._showProperty.getValue(e)),l=this._distanceDisplayConditionProperty.getValue(e),c=u.fromDistanceDisplayCondition(l),h={show:s,distanceDisplayCondition:c};return this._materialProperty instanceof C&&(i=t.WHITE,n(this._materialProperty.color)&&(this._materialProperty.color.isConstant||a)&&(i=this._materialProperty.color.getValue(e)),h.color=r.fromColor(i)),n(this._depthFailMaterialProperty)&&this._depthFailMaterialProperty instanceof C&&(i=t.WHITE,n(this._depthFailMaterialProperty.color)&&(this._depthFailMaterialProperty.color.isConstant||a)&&(i=this._depthFailMaterialProperty.color.getValue(e)),h.depthFailColor=r.fromColor(i)),new d({id:o,geometry:new p(this._options),attributes:h})},A.prototype.createOutlineGeometryInstance=function(e){},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){this._entitySubscription(),a(this)},A.prototype._onEntityPropertyChanged=function(e,t,r,o){if("availability"===t||"polyline"===t){var a=this._entity.polyline;if(!n(a))return void(this._fillEnabled&&(this._fillEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.positions,l=a.show;if(n(l)&&l.isConstant&&!l.getValue(h.MINIMUM_VALUE)||!n(s))return void(this._fillEnabled&&(this._fillEnabled=!1,this._geometryChanged.raiseEvent(this)));var u=i(a.material,D),c=u instanceof C;this._materialProperty=u,this._depthFailMaterialProperty=a.depthFailMaterial,this._showProperty=i(l,I),this._shadowsProperty=i(a.shadows,O),this._distanceDisplayConditionProperty=i(a.distanceDisplayCondition,M),this._fillEnabled=!0;var d=a.width,p=a.followSurface,f=a.granularity;if(s.isConstant&&T.isConstant(d)&&T.isConstant(p)&&T.isConstant(f)){var m=this._options,g=s.getValue(h.MINIMUM_VALUE,m.positions);if(!n(g)||g.length<2)return void(this._fillEnabled&&(this._fillEnabled=!1,this._geometryChanged.raiseEvent(this)));var y;y=c&&(!n(this._depthFailMaterialProperty)||this._depthFailMaterialProperty instanceof C)?_.VERTEX_FORMAT:v.VERTEX_FORMAT,m.vertexFormat=y,m.positions=g,m.width=n(d)?d.getValue(h.MINIMUM_VALUE):void 0,m.followSurface=n(p)?p.getValue(h.MINIMUM_VALUE):void 0,m.granularity=n(f)?f.getValue(h.MINIMUM_VALUE):void 0,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},A.prototype.createDynamicUpdater=function(e){return new x(e,this)};var R={positions:void 0,granularity:void 0,height:void 0,ellipsoid:void 0};return x.prototype.update=function(e){var t=this._geometryUpdater,r=t._entity,i=r.polyline,o=this._line;if(!r.isShowing||!r.isAvailable(e)||!T.getValueOrDefault(i._show,e,!0))return void(o.show=!1);var a=i.positions,s=T.getValueOrUndefined(a,e,this._positions);if(!n(s)||s.length<2)return void(o.show=!1);var l=T.getValueOrDefault(i._followSurface,e,!0),u=t._scene.globe;l&&n(u)&&(R.ellipsoid=u.ellipsoid,R.positions=s,R.granularity=T.getValueOrUndefined(i._granularity,e),R.height=f.extractHeights(s,u.ellipsoid),s=f.generateCartesianArc(R)),o.show=!0,o.positions=s.slice(),o.material=w.getValue(e,t.fillMaterialProperty,o.material),o.width=T.getValueOrDefault(i._width,e,1),o.distanceDisplayCondition=T.getValueOrUndefined(i._distanceDisplayCondition,e,o.distanceDisplayCondition)},x.prototype.getBoundingSphere=function(t,r){var i=this._line;return i.show&&i.positions.length>0?(e.fromPoints(i.positions,r),b.DONE):b.FAILED},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){var e=this._geometryUpdater,t=e._scene.id,r=P[t];r.remove(this._line),0===r.length&&(this._primitives.removeAndDestroy(r),delete P[t]),a(this)},A}),define("DataSources/PolylineVolumeGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/PolylineVolumeGeometry","../Core/PolylineVolumeOutlineGeometry","../Core/ShowGeometryInstanceAttribute","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.polylinePositions=void 0,this.shapePositions=void 0,this.cornerType=void 0,this.granularity=void 0}function E(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(E.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"polylineVolume",e.polylineVolume,void 0)}function A(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(e.WHITE),P=new b(!0),D=new b(!0),I=new b(!1),O=new b(e.BLACK),M=new b(v.DISABLED),R=new b(new s),L=new e;return n(E,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),n(E.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{value:!0},geometryChanged:{get:function(){return this._geometryChanged}}}),E.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},E.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},E.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new f(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),p=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var m=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(m=this._materialProperty.color.getValue(r)),o=t.fromColor(m),n={show:u,distanceDisplayCondition:p,color:o}}else n={show:u,distanceDisplayCondition:p};return new c({id:a,geometry:new h(this._options),attributes:n})},E.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=w.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new p(this._options),attributes:{show:new f(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){this._entitySubscription(),o(this)},E.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"polylineVolume"===t){var a=this._entity.polylineVolume;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(d.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(d.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var h=a.positions,p=a.shape,f=a.show;if(!i(h)||!i(p)||i(f)&&f.isConstant&&!f.getValue(d.MINIMUM_VALUE))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var _=r(a.material,x),v=_ instanceof y;this._materialProperty=_,this._fillProperty=r(s,D),this._showProperty=r(f,P),this._showOutlineProperty=r(a.outline,I),this._outlineColorProperty=c?r(a.outlineColor,O):void 0,this._shadowsProperty=r(a.shadows,M),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,R);var b=a.granularity,C=a.outlineWidth,S=a.cornerType;if(this._fillEnabled=l,this._outlineEnabled=c,h.isConstant&&p.isConstant&&w.isConstant(b)&&w.isConstant(C)&&w.isConstant(S)){var T=this._options;T.vertexFormat=v?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,T.polylinePositions=h.getValue(d.MINIMUM_VALUE,T.polylinePositions),T.shapePositions=p.getValue(d.MINIMUM_VALUE,T.shape),T.granularity=i(b)?b.getValue(d.MINIMUM_VALUE):void 0,T.cornerType=i(S)?S.getValue(d.MINIMUM_VALUE):void 0,this._outlineWidth=i(C)?C.getValue(d.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},E.prototype.createDynamicUpdater=function(e){return new A(e,this)},A.prototype.update=function(r){var n=this._primitives;n.removeAndDestroy(this._primitive),n.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var o=this._geometryUpdater,a=o._entity,s=a.polylineVolume;if(a.isShowing&&a.isAvailable(r)&&w.getValueOrDefault(s.show,r,!0)){var l=this._options,u=w.getValueOrUndefined(s.positions,r,l.polylinePositions),d=w.getValueOrUndefined(s.shape,r);if(i(u)&&i(d)){l.polylinePositions=u,l.shapePositions=d,l.granularity=w.getValueOrUndefined(s.granularity,r),l.cornerType=w.getValueOrUndefined(s.cornerType,r);var f=this._geometryUpdater.shadowsProperty.getValue(r);if(!i(s.fill)||s.fill.getValue(r)){var v=S.getValue(r,o.fillMaterialProperty,this._material);this._material=v;var y=new m({material:v,translucent:v.isTranslucent(),closed:!0});l.vertexFormat=y.vertexFormat,this._primitive=n.add(new _({geometryInstances:new c({id:a,geometry:new h(l)}),appearance:y,asynchronous:!1,shadows:f}))}if(i(s.outline)&&s.outline.getValue(r)){l.vertexFormat=g.VERTEX_FORMAT;var b=w.getValueOrClonedDefault(s.outlineColor,r,e.BLACK,L),C=w.getValueOrDefault(s.outlineWidth,r,1),T=1!==b.alpha;this._outlinePrimitive=n.add(new _({geometryInstances:new c({id:a,geometry:new p(l),attributes:{color:t.fromColor(b)}}),appearance:new g({flat:!0,translucent:T,renderState:{lineWidth:o._scene.clampLineWidth(C)}}),asynchronous:!1,shadows:f}))}}}},A.prototype.getBoundingSphere=function(e,t){return C(e,this._primitive,this._outlinePrimitive,t)},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},E}),define("DataSources/RectangleGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/oneTimeWarning","../Core/RectangleGeometry","../Core/RectangleOutlineGeometry","../Core/ShowGeometryInstanceAttribute","../Scene/GroundPrimitive","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e){this.id=e,this.vertexFormat=void 0,this.rectangle=void 0,this.closeBottom=void 0,this.closeTop=void 0,this.height=void 0,this.extrudedHeight=void 0,this.granularity=void 0,this.stRotation=void 0,this.rotation=void 0}function x(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(x.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._isClosed=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._onTerrain=!1,this._options=new A(e),this._onEntityPropertyChanged(e,"rectangle",e.rectangle,void 0)}function P(e,t,r){this._primitives=e,this._groundPrimitives=t,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=r,this._options=new A(r._entity)}var D=new C(e.WHITE),I=new S(!0),O=new S(!0),M=new S(!1),R=new S(e.BLACK),L=new S(b.DISABLED),N=new S(new s),k=new e;return n(x,{perInstanceColorAppearanceType:{value:v},materialAppearanceType:{value:_}}),n(x.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&E.isConstant(this._showProperty)&&E.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&E.isConstant(this._showProperty)&&E.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return this._isClosed}},onTerrain:{get:function(){return this._onTerrain}},geometryChanged:{get:function(){return this._geometryChanged}}}),x.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},x.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},x.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new m(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),h=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof C){var f=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(f=this._materialProperty.color.getValue(r)),o=t.fromColor(f),n={show:u,distanceDisplayCondition:h,color:o}}else n={show:u,distanceDisplayCondition:h};return new c({id:a,geometry:new p(this._options),attributes:n})},x.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=E.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new f(this._options),attributes:{show:new m(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){this._entitySubscription(),o(this)},x.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"rectangle"===t){var a=this._entity.rectangle;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(d.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(d.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var p=a.coordinates,f=a.show;if(i(f)&&f.isConstant&&!f.getValue(d.MINIMUM_VALUE)||!i(p))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var m=r(a.material,D),y=m instanceof C;this._materialProperty=m,this._fillProperty=r(s,O),this._showProperty=r(f,I),this._showOutlineProperty=r(a.outline,M),this._outlineColorProperty=c?r(a.outlineColor,R):void 0,this._shadowsProperty=r(a.shadows,L),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,N);var b=a.height,S=a.extrudedHeight,w=a.granularity,T=a.stRotation,A=a.rotation,x=a.outlineWidth,P=a.closeBottom,k=a.closeTop,F=l&&!i(b)&&!i(S)&&y&&g.isSupported(this._scene);if(c&&F&&(h(h.geometryOutlines),c=!1),this._fillEnabled=l,this._onTerrain=F,this._outlineEnabled=c,p.isConstant&&E.isConstant(b)&&E.isConstant(S)&&E.isConstant(w)&&E.isConstant(T)&&E.isConstant(A)&&E.isConstant(x)&&E.isConstant(P)&&E.isConstant(k)&&(!F||E.isConstant(m))){var B=this._options;B.vertexFormat=y?v.VERTEX_FORMAT:_.MaterialSupport.TEXTURED.vertexFormat,B.rectangle=p.getValue(d.MINIMUM_VALUE,B.rectangle),B.height=i(b)?b.getValue(d.MINIMUM_VALUE):void 0,B.extrudedHeight=i(S)?S.getValue(d.MINIMUM_VALUE):void 0,B.granularity=i(w)?w.getValue(d.MINIMUM_VALUE):void 0,B.stRotation=i(T)?T.getValue(d.MINIMUM_VALUE):void 0,B.rotation=i(A)?A.getValue(d.MINIMUM_VALUE):void 0,B.closeBottom=i(P)?P.getValue(d.MINIMUM_VALUE):void 0,B.closeTop=i(k)?k.getValue(d.MINIMUM_VALUE):void 0,this._isClosed=i(S)&&i(B.closeTop)&&i(B.closeBottom)&&B.closeTop&&B.closeBottom,this._outlineWidth=i(x)?x.getValue(d.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},x.prototype.createDynamicUpdater=function(e,t){return new P(e,t,this)},P.prototype.update=function(r){var n=this._geometryUpdater,o=n._onTerrain,a=this._primitives,s=this._groundPrimitives;o?s.removeAndDestroy(this._primitive):(a.removeAndDestroy(this._primitive),a.removeAndDestroy(this._outlinePrimitive),this._outlinePrimitive=void 0),this._primitive=void 0;var l=n._entity,u=l.rectangle;if(l.isShowing&&l.isAvailable(r)&&E.getValueOrDefault(u.show,r,!0)){var d=this._options,h=E.getValueOrUndefined(u.coordinates,r,d.rectangle);if(i(h)){d.rectangle=h,d.height=E.getValueOrUndefined(u.height,r),d.extrudedHeight=E.getValueOrUndefined(u.extrudedHeight,r),d.granularity=E.getValueOrUndefined(u.granularity,r),d.stRotation=E.getValueOrUndefined(u.stRotation,r),d.rotation=E.getValueOrUndefined(u.rotation,r),d.closeBottom=E.getValueOrUndefined(u.closeBottom,r),d.closeTop=E.getValueOrUndefined(u.closeTop,r);var m=this._geometryUpdater.shadowsProperty.getValue(r);if(E.getValueOrDefault(u.fill,r,!0)){var b=n.fillMaterialProperty,C=T.getValue(r,b,this._material);if(this._material=C,o){var S=e.WHITE;i(b.color)&&(S=b.color.getValue(r)),this._primitive=s.add(new g({geometryInstances:new c({id:l,geometry:new p(d),attributes:{color:t.fromColor(S)}}),asynchronous:!1,shadows:m}))}else{var w=new _({material:C,translucent:C.isTranslucent(),closed:i(d.extrudedHeight)});d.vertexFormat=w.vertexFormat,this._primitive=a.add(new y({geometryInstances:new c({id:l,geometry:new p(d)}),appearance:w,asynchronous:!1,shadows:m}))}}if(!o&&E.getValueOrDefault(u.outline,r,!1)){d.vertexFormat=v.VERTEX_FORMAT;var A=E.getValueOrClonedDefault(u.outlineColor,r,e.BLACK,k),x=E.getValueOrDefault(u.outlineWidth,r,1),P=1!==A.alpha;this._outlinePrimitive=a.add(new y({geometryInstances:new c({id:l,geometry:new f(d),attributes:{color:t.fromColor(A)}}),appearance:new v({flat:!0,translucent:P,renderState:{lineWidth:n._scene.clampLineWidth(x)}}),asynchronous:!1,shadows:m}))}}}},P.prototype.getBoundingSphere=function(e,t){ +return w(e,this._primitive,this._outlinePrimitive,t)},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){var e=this._primitives,t=this._groundPrimitives;this._geometryUpdater._onTerrain?t.removeAndDestroy(this._primitive):e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},x}),define("DataSources/WallGeometryUpdater",["../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/DistanceDisplayCondition","../Core/DistanceDisplayConditionGeometryInstanceAttribute","../Core/Event","../Core/GeometryInstance","../Core/Iso8601","../Core/ShowGeometryInstanceAttribute","../Core/WallGeometry","../Core/WallOutlineGeometry","../Scene/MaterialAppearance","../Scene/PerInstanceColorAppearance","../Scene/Primitive","../Scene/ShadowMode","./ColorMaterialProperty","./ConstantProperty","./dynamicGeometryGetBoundingSphere","./MaterialProperty","./Property"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){"use strict";function T(e){this.id=e,this.vertexFormat=void 0,this.positions=void 0,this.minimumHeights=void 0,this.maximumHeights=void 0,this.granularity=void 0}function E(e,t){this._entity=e,this._scene=t,this._entitySubscription=e.definitionChanged.addEventListener(E.prototype._onEntityPropertyChanged,this),this._fillEnabled=!1,this._dynamic=!1,this._outlineEnabled=!1,this._geometryChanged=new u,this._showProperty=void 0,this._materialProperty=void 0,this._hasConstantOutline=!0,this._showOutlineProperty=void 0,this._outlineColorProperty=void 0,this._outlineWidth=1,this._shadowsProperty=void 0,this._distanceDisplayConditionProperty=void 0,this._options=new T(e),this._onEntityPropertyChanged(e,"wall",e.wall,void 0)}function A(e,t){this._primitives=e,this._primitive=void 0,this._outlinePrimitive=void 0,this._geometryUpdater=t,this._options=new T(t._entity)}var x=new y(e.WHITE),P=new b(!0),D=new b(!0),I=new b(!1),O=new b(e.BLACK),M=new b(v.DISABLED),R=new b(new s),L=new e;return n(E,{perInstanceColorAppearanceType:{value:g},materialAppearanceType:{value:m}}),n(E.prototype,{entity:{get:function(){return this._entity}},fillEnabled:{get:function(){return this._fillEnabled}},hasConstantFill:{get:function(){return!this._fillEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._fillProperty)}},fillMaterialProperty:{get:function(){return this._materialProperty}},outlineEnabled:{get:function(){return this._outlineEnabled}},hasConstantOutline:{get:function(){return!this._outlineEnabled||!i(this._entity.availability)&&w.isConstant(this._showProperty)&&w.isConstant(this._showOutlineProperty)}},outlineColorProperty:{get:function(){return this._outlineColorProperty}},outlineWidth:{get:function(){return this._outlineWidth}},shadowsProperty:{get:function(){return this._shadowsProperty}},distanceDisplayConditionProperty:{get:function(){return this._distanceDisplayConditionProperty}},isDynamic:{get:function(){return this._dynamic}},isClosed:{get:function(){return!1}},geometryChanged:{get:function(){return this._geometryChanged}}}),E.prototype.isOutlineVisible=function(e){var t=this._entity;return this._outlineEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._showOutlineProperty.getValue(e)},E.prototype.isFilled=function(e){var t=this._entity;return this._fillEnabled&&t.isAvailable(e)&&this._showProperty.getValue(e)&&this._fillProperty.getValue(e)},E.prototype.createFillGeometryInstance=function(r){var n,o,a=this._entity,s=a.isAvailable(r),u=new h(s&&a.isShowing&&this._showProperty.getValue(r)&&this._fillProperty.getValue(r)),d=this._distanceDisplayConditionProperty.getValue(r),f=l.fromDistanceDisplayCondition(d);if(this._materialProperty instanceof y){var m=e.WHITE;i(this._materialProperty.color)&&(this._materialProperty.color.isConstant||s)&&(m=this._materialProperty.color.getValue(r)),o=t.fromColor(m),n={show:u,distanceDisplayCondition:f,color:o}}else n={show:u,distanceDisplayCondition:f};return new c({id:a,geometry:new p(this._options),attributes:n})},E.prototype.createOutlineGeometryInstance=function(r){var i=this._entity,n=i.isAvailable(r),o=w.getValueOrDefault(this._outlineColorProperty,r,e.BLACK),a=this._distanceDisplayConditionProperty.getValue(r);return new c({id:i,geometry:new f(this._options),attributes:{show:new h(n&&i.isShowing&&this._showProperty.getValue(r)&&this._showOutlineProperty.getValue(r)),color:t.fromColor(o),distanceDisplayCondition:l.fromDistanceDisplayCondition(a)}})},E.prototype.isDestroyed=function(){return!1},E.prototype.destroy=function(){this._entitySubscription(),o(this)},E.prototype._onEntityPropertyChanged=function(e,t,n,o){if("availability"===t||"wall"===t){var a=this._entity.wall;if(!i(a))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var s=a.fill,l=!i(s)||!s.isConstant||s.getValue(d.MINIMUM_VALUE),u=a.outline,c=i(u);if(c&&u.isConstant&&(c=u.getValue(d.MINIMUM_VALUE)),!l&&!c)return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var h=a.positions,p=a.show;if(i(p)&&p.isConstant&&!p.getValue(d.MINIMUM_VALUE)||!i(h))return void((this._fillEnabled||this._outlineEnabled)&&(this._fillEnabled=!1,this._outlineEnabled=!1,this._geometryChanged.raiseEvent(this)));var f=r(a.material,x),_=f instanceof y;this._materialProperty=f,this._fillProperty=r(s,D),this._showProperty=r(p,P),this._showOutlineProperty=r(a.outline,I),this._outlineColorProperty=c?r(a.outlineColor,O):void 0,this._shadowsProperty=r(a.shadows,M),this._distanceDisplayConditionProperty=r(a.distanceDisplayCondition,R);var v=a.minimumHeights,b=a.maximumHeights,C=a.outlineWidth,S=a.granularity;if(this._fillEnabled=l,this._outlineEnabled=c,h.isConstant&&w.isConstant(v)&&w.isConstant(b)&&w.isConstant(C)&&w.isConstant(S)){var T=this._options;T.vertexFormat=_?g.VERTEX_FORMAT:m.MaterialSupport.TEXTURED.vertexFormat,T.positions=h.getValue(d.MINIMUM_VALUE,T.positions),T.minimumHeights=i(v)?v.getValue(d.MINIMUM_VALUE,T.minimumHeights):void 0,T.maximumHeights=i(b)?b.getValue(d.MINIMUM_VALUE,T.maximumHeights):void 0,T.granularity=i(S)?S.getValue(d.MINIMUM_VALUE):void 0,this._outlineWidth=i(C)?C.getValue(d.MINIMUM_VALUE):1,this._dynamic=!1,this._geometryChanged.raiseEvent(this)}else this._dynamic||(this._dynamic=!0,this._geometryChanged.raiseEvent(this))}},E.prototype.createDynamicUpdater=function(e){return new A(e,this)},A.prototype.update=function(r){var n=this._primitives;n.removeAndDestroy(this._primitive),n.removeAndDestroy(this._outlinePrimitive),this._primitive=void 0,this._outlinePrimitive=void 0;var o=this._geometryUpdater,a=o._entity,s=a.wall;if(a.isShowing&&a.isAvailable(r)&&w.getValueOrDefault(s.show,r,!0)){var l=this._options,u=w.getValueOrUndefined(s.positions,r,l.positions);if(i(u)){l.positions=u,l.minimumHeights=w.getValueOrUndefined(s.minimumHeights,r,l.minimumHeights),l.maximumHeights=w.getValueOrUndefined(s.maximumHeights,r,l.maximumHeights),l.granularity=w.getValueOrUndefined(s.granularity,r);var d=this._geometryUpdater.shadowsProperty.getValue(r);if(w.getValueOrDefault(s.fill,r,!0)){var h=S.getValue(r,o.fillMaterialProperty,this._material);this._material=h;var v=new m({material:h,translucent:h.isTranslucent(),closed:i(l.extrudedHeight)});l.vertexFormat=v.vertexFormat,this._primitive=n.add(new _({geometryInstances:new c({id:a,geometry:new p(l)}),appearance:v,asynchronous:!1,shadows:d}))}if(w.getValueOrDefault(s.outline,r,!1)){l.vertexFormat=g.VERTEX_FORMAT;var y=w.getValueOrClonedDefault(s.outlineColor,r,e.BLACK,L),b=w.getValueOrDefault(s.outlineWidth,r,1),C=1!==y.alpha;this._outlinePrimitive=n.add(new _({geometryInstances:new c({id:a,geometry:new f(l),attributes:{color:t.fromColor(y)}}),appearance:new g({flat:!0,translucent:C,renderState:{lineWidth:o._scene.clampLineWidth(b)}}),asynchronous:!1,shadows:d}))}}}},A.prototype.getBoundingSphere=function(e,t){return C(e,this._primitive,this._outlinePrimitive,t)},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){var e=this._primitives;e.removeAndDestroy(this._primitive),e.removeAndDestroy(this._outlinePrimitive),o(this)},E}),define("DataSources/DataSourceDisplay",["../Core/BoundingSphere","../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EventHelper","../Scene/GroundPrimitive","./BillboardVisualizer","./BoundingSphereState","./BoxGeometryUpdater","./CorridorGeometryUpdater","./CustomDataSource","./CylinderGeometryUpdater","./EllipseGeometryUpdater","./EllipsoidGeometryUpdater","./GeometryVisualizer","./LabelVisualizer","./ModelVisualizer","./PathVisualizer","./PlaneGeometryUpdater","./PointVisualizer","./PolygonGeometryUpdater","./PolylineGeometryUpdater","./PolylineVolumeGeometryUpdater","./RectangleGeometryUpdater","./WallGeometryUpdater"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x){"use strict";function P(e){l.initializeTerrainHeights();var t=e.scene,i=e.dataSourceCollection;this._eventHelper=new s,this._eventHelper.add(i.dataSourceAdded,this._onDataSourceAdded,this),this._eventHelper.add(i.dataSourceRemoved,this._onDataSourceRemoved,this),this._dataSourceCollection=i,this._scene=t,this._visualizersCallback=r(e.visualizersCallback,P.defaultVisualizersCallback);for(var n=0,o=i.length;n<o;n++)this._onDataSourceAdded(i,i.get(n));var a=new p;this._onDataSourceAdded(void 0,a),this._defaultDataSource=a,this._ready=!1}P.defaultVisualizersCallback=function(e,t,r){var i=r.entities;return[new u(t,i),new _(d,e,i),new _(f,e,i),new _(h,e,i),new _(m,e,i),new _(g,e,i),new _(C,e,i),new _(w,e,i),new _(T,e,i),new _(E,e,i),new _(A,e,i),new _(x,e,i),new v(t,i),new y(e,i),new S(t,i),new b(e,i)]},n(P.prototype,{scene:{get:function(){return this._scene}},dataSources:{get:function(){return this._dataSourceCollection}},defaultDataSource:{get:function(){return this._defaultDataSource}},ready:{get:function(){return this._ready}}}),P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){this._eventHelper.removeAll();for(var e=this._dataSourceCollection,t=0,r=e.length;t<r;++t)this._onDataSourceRemoved(this._dataSourceCollection,e.get(t));return this._onDataSourceRemoved(void 0,this._defaultDataSource),o(this)},P.prototype.update=function(e){if(!l._initialized)return this._ready=!1,!1;var t,r,n,o,a=!0,s=this._dataSourceCollection,u=s.length;for(t=0;t<u;t++){var c=s.get(t);for(i(c.update)&&(a=c.update(e)&&a),n=c._visualizers,o=n.length,r=0;r<o;r++)a=n[r].update(e)&&a}for(n=this._defaultDataSource._visualizers,o=n.length,r=0;r<o;r++)a=n[r].update(e)&&a;return this._ready=a,a};var D=[],I=new e;return P.prototype.getBoundingSphere=function(t,r,n){if(!this._ready)return c.PENDING;var o,a,s=this._defaultDataSource;if(!s.entities.contains(t)){s=void 0;var l=this._dataSourceCollection;for(a=l.length,o=0;o<a;o++){var u=l.get(o);if(u.entities.contains(t)){s=u;break}}}if(!i(s))return c.FAILED;var d=D,h=I,p=0,f=c.DONE,m=s._visualizers,g=m.length;for(o=0;o<g;o++){var _=m[o];if(i(_.getBoundingSphere)){if(f=m[o].getBoundingSphere(t,h),!r&&f===c.PENDING)return c.PENDING;f===c.DONE&&(d[p]=e.clone(h,d[p]),p++)}}return 0===p?c.FAILED:(d.length=p,e.fromBoundingSpheres(d,n),c.DONE)},P.prototype._onDataSourceAdded=function(e,t){var r=this._scene,i=t.clustering;i._initialize(r),r.primitives.add(i),t._visualizers=this._visualizersCallback(r,i,t)},P.prototype._onDataSourceRemoved=function(e,t){var r=this._scene,i=t.clustering;r.primitives.remove(i);for(var n=t._visualizers,o=n.length,a=0;a<o;a++)n[a].destroy();t._visualizers=void 0},P}),define("DataSources/DynamicGeometryUpdater",["../Core/DeveloperError"],function(e){"use strict";function t(){e.throwInstantiationError()}return t.prototype.update=e.throwInstantiationError,t.prototype.getBoundingSphere=e.throwInstantiationError,t.prototype.isDestroyed=e.throwInstantiationError,t.prototype.destroy=e.throwInstantiationError,t}),define("DataSources/EntityView",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Ellipsoid","../Core/HeadingPitchRange","../Core/JulianDate","../Core/Math","../Core/Matrix3","../Core/Matrix4","../Core/Transforms","../Scene/SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(t,i,n,o,a,c,p){var f=t.scene.mode,x=a.getValue(c,t._lastCartesian);if(r(x)){var P,D,I,O=!1,M=!1;if(f===h.SCENE3D){s.addSeconds(c,.001,E);var R=a.getValue(E,y);if(r(R)||(s.addSeconds(c,-.001,E),R=a.getValue(E,y),M=!0),r(R)){var L,N=d.computeFixedToIcrfMatrix(c,m),k=d.computeFixedToIcrfMatrix(E,g);r(N)&&r(k)?L=u.transpose(N,_):(L=d.computeTemeToPseudoFixedMatrix(c,_),N=u.transpose(L,m),k=d.computeTemeToPseudoFixedMatrix(E,g),u.transpose(k,k));var F=u.multiplyByVector(N,x,w),B=u.multiplyByVector(k,R,T);e.subtract(F,B,S);var U=1e3*e.magnitude(S),V=3986004418e5,z=-V/(U*U-2*V/e.magnitude(F));z<0||z>A*p.maximumRadius?(P=b,e.normalize(x,P),e.negate(P,P),I=e.clone(e.UNIT_Z,C),D=e.cross(I,P,y),e.magnitude(D)>l.EPSILON7&&(e.normalize(P,P),e.normalize(D,D),I=e.cross(P,D,C),e.normalize(I,I),O=!0)):e.equalsEpsilon(x,R,l.EPSILON7)||(I=b,e.normalize(F,I),e.normalize(B,B),D=e.cross(I,B,C),M&&(D=e.multiplyByScalar(D,-1,D)),e.equalsEpsilon(D,e.ZERO,l.EPSILON7)||(P=e.cross(D,I,y),u.multiplyByVector(L,P,P),u.multiplyByVector(L,D,D),u.multiplyByVector(L,I,I),e.normalize(P,P),e.normalize(D,D),e.normalize(I,I),O=!0))}}r(t.boundingSphere)&&(x=t.boundingSphere.center);var G,W,H;o&&(G=e.clone(i.position,S),W=e.clone(i.direction,w),H=e.clone(i.up,T));var j=v;O?(j[0]=P.x,j[1]=P.y,j[2]=P.z,j[3]=0,j[4]=D.x,j[5]=D.y,j[6]=D.z,j[7]=0,j[8]=I.x,j[9]=I.y,j[10]=I.z,j[11]=0,j[12]=x.x,j[13]=x.y,j[14]=x.z,j[15]=0):d.eastNorthUpToFixedFrame(x,p,j),i._setTransform(j),o&&(e.clone(G,i.position),e.clone(W,i.direction),e.clone(H,i.up),e.cross(W,H,i.right))}if(n){var q=f===h.SCENE2D||e.equals(t._offset3D,e.ZERO)?void 0:t._offset3D;i.lookAtTransform(i.transform,q)}}function f(r,i,n){this.entity=r,this.scene=i,this.ellipsoid=t(n,o.WGS84),this.boundingSphere=void 0,this._lastEntity=void 0,this._mode=void 0,this._lastCartesian=new e,this._defaultOffset3D=void 0,this._offset3D=new e}var m=new u,g=new u,_=new u,v=new c,y=new e,b=new e,C=new e,S=new e,w=new e,T=new e,E=new s,A=1.25;i(f,{defaultOffset3D:{get:function(){return this._defaultOffset3D},set:function(t){this._defaultOffset3D=e.clone(t,new e)}}}),f.defaultOffset3D=new e(-14e3,3500,3500);var x=new a,P=new e;return f.prototype.update=function(t,i){var n=this.scene,o=this.entity,a=this.ellipsoid,s=n.mode;if(s!==h.MORPHING){var u=o.position,c=o!==this._lastEntity,d=s!==this._mode,m=this._offset3D,g=n.camera,_=c||d,v=!0;if(c){var y=o.viewFrom,b=r(y);if(!b&&r(i)){x.pitch=-l.PI_OVER_FOUR,x.range=0;var C=u.getValue(t,P);if(r(C)){var S=2-1/Math.max(1,e.magnitude(C)/a.maximumRadius);x.pitch*=S}g.viewBoundingSphere(i,x),this.boundingSphere=i,_=!1,v=!1}else b&&r(y.getValue(t,m))||e.clone(f._defaultOffset3D,m)}else d||n.mode===h.MORPHING||this._mode===h.SCENE2D||e.clone(g.position,m);this._lastEntity=o,this._mode=n.mode!==h.MORPHING?n.mode:this._mode,n.mode!==h.MORPHING&&p(this,g,_,v,u,t,a)}},f}),function(){function e(e,t){function r(t){var r,i=e.arcs[t<0?~t:t],n=i[0];return e.transform?(r=[0,0],i.forEach(function(e){r[0]+=e[0],r[1]+=e[1]})):r=i[i.length-1],t<0?[r,n]:[n,r]}function i(e,t){for(var r in e){var i=e[r];delete t[i.start],delete i.start,delete i.end,i.forEach(function(e){n[e<0?~e:e]=1}),s.push(i)}}var n={},o={},a={},s=[],l=-1;return t.forEach(function(r,i){var n,o=e.arcs[r<0?~r:r];o.length<3&&!o[1][0]&&!o[1][1]&&(n=t[++l],t[l]=r,t[i]=n)}),t.forEach(function(e){var t,i,n=r(e),s=n[0],l=n[1];if(t=a[s])if(delete a[t.end],t.push(e),t.end=l,i=o[l]){delete o[i.start];var u=i===t?t:t.concat(i);o[u.start=t.start]=a[u.end=i.end]=u}else o[t.start]=a[t.end]=t;else if(t=o[l])if(delete o[t.start],t.unshift(e),t.start=s,i=a[s]){delete a[i.end];var c=i===t?t:i.concat(t);o[c.start=i.start]=a[c.end=t.end]=c}else o[t.start]=a[t.end]=t;else t=[e],o[t.start=s]=a[t.end=l]=t}),i(a,o),i(o,a),t.forEach(function(e){n[e<0?~e:e]||s.push([e])}),s}function t(t,r,i){function n(e){var t=e<0?~e:e;(c[t]||(c[t]=[])).push({i:e,g:u})}function o(e){e.forEach(n)}function a(e){e.forEach(o)}function s(e){"GeometryCollection"===e.type?e.geometries.forEach(s):e.type in d&&(u=e,d[e.type](e.arcs))}var l=[];if(arguments.length>1){var u,c=[],d={LineString:o,MultiLineString:a,Polygon:a,MultiPolygon:function(e){e.forEach(a)}};s(r),c.forEach(arguments.length<3?function(e){l.push(e[0].i)}:function(e){i(e[0].g,e[e.length-1].g)&&l.push(e[0].i)})}else for(var h=0,p=t.arcs.length;h<p;++h)l.push(h);return{type:"MultiLineString",arcs:e(t,l)}}function r(t,r){function i(e){e.forEach(function(t){t.forEach(function(t){(s[t=t<0?~t:t]||(s[t]=[])).push(e)})}),l.push(e)}function o(e){return d(a(t,{type:"Polygon",arcs:[e]}).coordinates[0])>0}var s={},l=[],u=[];return r.forEach(function(e){"Polygon"===e.type?i(e.arcs):"MultiPolygon"===e.type&&e.arcs.forEach(i)}),l.forEach(function(e){if(!e._){var t=[],r=[e];for(e._=1,u.push(t);e=r.pop();)t.push(e),e.forEach(function(e){e.forEach(function(e){s[e<0?~e:e].forEach(function(e){e._||(e._=1,r.push(e))})})})}}),l.forEach(function(e){delete e._}),{type:"MultiPolygon",arcs:u.map(function(r){var i=[];if(r.forEach(function(e){e.forEach(function(e){e.forEach(function(e){s[e<0?~e:e].length<2&&i.push(e)})})}),i=e(t,i),(n=i.length)>1)for(var a,l=o(r[0][0]),u=0;u<n;++u)if(l===o(i[u])){a=i[0],i[0]=i[u],i[u]=a;break}return i})}}function i(e,t){return"GeometryCollection"===t.type?{type:"FeatureCollection",features:t.geometries.map(function(t){return o(e,t)})}:o(e,t)}function o(e,t){var r={type:"Feature",id:t.id,properties:t.properties||{},geometry:a(e,t)};return null==t.id&&delete r.id,r}function a(e,t){function r(e,t){t.length&&t.pop();for(var r,i=c[e<0?~e:e],n=0,o=i.length;n<o;++n)t.push(r=i[n].slice()),u(r,n);e<0&&s(t,o)}function i(e){return e=e.slice(),u(e,0),e}function n(e){for(var t=[],i=0,n=e.length;i<n;++i)r(e[i],t);return t.length<2&&t.push(t[0].slice()),t}function o(e){for(var t=n(e);t.length<4;)t.push(t[0].slice());return t}function a(e){return e.map(o)}function l(e){var t=e.type;return"GeometryCollection"===t?{type:t,geometries:e.geometries.map(l)}:t in d?{type:t,coordinates:d[t](e)}:null}var u=m(e.transform),c=e.arcs,d={Point:function(e){return i(e.coordinates)},MultiPoint:function(e){return e.coordinates.map(i)},LineString:function(e){return n(e.arcs)},MultiLineString:function(e){return e.arcs.map(n)},Polygon:function(e){return a(e.arcs)},MultiPolygon:function(e){return e.arcs.map(a)}};return l(t)}function s(e,t){for(var r,i=e.length,n=i-t;n<--i;)r=e[n],e[n++]=e[i],e[i]=r}function l(e,t){for(var r=0,i=e.length;r<i;){var n=r+i>>>1;e[n]<t?r=n+1:i=n}return r}function u(e){function t(e,t){e.forEach(function(e){e<0&&(e=~e);var r=n[e];r?r.push(t):n[e]=[t]})}function r(e,r){e.forEach(function(e){t(e,r)})}function i(e,t){"GeometryCollection"===e.type?e.geometries.forEach(function(e){i(e,t)}):e.type in a&&a[e.type](e.arcs,t)}var n={},o=e.map(function(){return[]}),a={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(e,t){e.forEach(function(e){r(e,t)})}};e.forEach(i);for(var s in n)for(var u=n[s],c=u.length,d=0;d<c;++d)for(var h=d+1;h<c;++h){var p,f=u[d],m=u[h];(p=o[f])[s=l(p,m)]!==m&&p.splice(s,0,m),(p=o[m])[s=l(p,f)]!==f&&p.splice(s,0,f)}return o}function c(e,t){function r(e){o.remove(e),e[1][2]=t(e),o.push(e)}var i=m(e.transform),n=g(e.transform),o=f();return t||(t=h),e.arcs.forEach(function(e){for(var a,s,l=[],u=0,c=0,d=e.length;c<d;++c)s=e[c],i(e[c]=[s[0],s[1],1/0],c);for(var c=1,d=e.length-1;c<d;++c)a=e.slice(c-1,c+2),a[1][2]=t(a),l.push(a),o.push(a);for(var c=0,d=l.length;c<d;++c)a=l[c],a.previous=l[c-1],a.next=l[c+1];for(;a=o.pop();){var h=a.previous,p=a.next;a[1][2]<u?a[1][2]=u:u=a[1][2],h&&(h.next=p,h[2]=a[2],r(h)),p&&(p.previous=h,p[0]=a[0],r(p))}e.forEach(n)}),e}function d(e){for(var t,r=-1,i=e.length,n=e[i-1],o=0;++r<i;)t=n,n=e[r],o+=t[0]*n[1]-t[1]*n[0];return.5*o}function h(e){var t=e[0],r=e[1],i=e[2];return Math.abs((t[0]-i[0])*(r[1]-t[1])-(t[0]-r[0])*(i[1]-t[1]))}function p(e,t){return e[1][2]-t[1][2]}function f(){function e(e,t){for(;t>0;){var r=(t+1>>1)-1,n=i[r];if(p(e,n)>=0)break;i[n._=t]=n,i[e._=t=r]=e}}function t(e,t){for(;;){var r=t+1<<1,o=r-1,a=t,s=i[a];if(o<n&&p(i[o],s)<0&&(s=i[a=o]),r<n&&p(i[r],s)<0&&(s=i[a=r]),a===t)break;i[s._=t]=s,i[e._=t=a]=e}}var r={},i=[],n=0;return r.push=function(t){return e(i[t._=n]=t,n++),n},r.pop=function(){if(!(n<=0)){var e,r=i[0];return--n>0&&(e=i[n],t(i[e._=0]=e,0)),r}},r.remove=function(r){var o,a=r._;if(i[a]===r)return a!==--n&&(o=i[n],(p(o,r)<0?e:t)(i[o._=a]=o,a)),a},r}function m(e){if(!e)return _;var t,r,i=e.scale[0],n=e.scale[1],o=e.translate[0],a=e.translate[1];return function(e,s){s||(t=r=0),e[0]=(t+=e[0])*i+o,e[1]=(r+=e[1])*n+a}}function g(e){if(!e)return _;var t,r,i=e.scale[0],n=e.scale[1],o=e.translate[0],a=e.translate[1];return function(e,s){s||(t=r=0);var l=(e[0]-o)/i|0,u=(e[1]-a)/n|0;e[0]=l-t,e[1]=u-r,t=l,r=u}}function _(){}var v={version:"1.6.18",mesh:function(e){return a(e,t.apply(this,arguments))},meshArcs:t,merge:function(e){return a(e,r.apply(this,arguments))},mergeArcs:r,feature:i,neighbors:u,presimplify:c};"function"==typeof define&&define.amd?define("ThirdParty/topojson",v):"object"==typeof module&&module.exports?module.exports=v:this.topojson=v}(),define("DataSources/GeoJsonDataSource",["../Core/Cartesian3","../Core/Color","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/getFilenameFromUri","../Core/PinBuilder","../Core/PolygonHierarchy","../Core/Resource","../Core/RuntimeError","../Scene/HeightReference","../Scene/VerticalOrigin","../ThirdParty/topojson","../ThirdParty/when","./BillboardGraphics","./CallbackProperty","./ColorMaterialProperty","./ConstantPositionProperty","./ConstantProperty","./CorridorGraphics","./DataSource","./EntityCluster","./EntityCollection","./PolygonGraphics","./PolylineGraphics"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x){"use strict";function P(t){return e.fromDegrees(t[0],t[1],t[2])}function D(e,t){var r="";for(var i in e)if(e.hasOwnProperty(i)){if(i===t||-1!==ae.indexOf(i))continue;var o=e[i];n(o)&&(r+="object"==typeof o?"<tr><th>"+i+"</th><td>"+D(o)+"</td></tr>":"<tr><th>"+i+"</th><td>"+o+"</td></tr>")}return r.length>0&&(r='<table class="cesium-infoBox-defaultTable"><tbody>'+r+"</tbody></table>"),r}function I(e,t,r){var i;return function(o,a){return n(i)||(i=e(t,r)),i}}function O(e,t){return new v(I(D,e,t),!0)}function M(e,t,i){var o=e.id;if(n(o)&&"Feature"===e.type){for(var a=2,s=o;n(t.getById(s));)s=o+"_"+a,a++;o=s}else o=r();var l=t.getOrCreateEntity(o),u=e.properties;if(n(u)){l.properties=u;var c,d=u.title;if(n(d))l.name=d,c="title";else{var h=Number.MAX_VALUE;for(var p in u)if(u.hasOwnProperty(p)&&u[p]){var f=p.toLowerCase();if(h>1&&"title"===f){h=1,c=p;break}h>2&&"name"===f?(h=2,c=p):h>3&&/title/i.test(p)?(h=3,c=p):h>4&&/name/i.test(p)&&(h=4,c=p)}n(c)&&(l.name=u[c])}var m=u.description;null!==m&&(l.description=n(m)?new C(m):i(u,c))}return l}function R(e,t){for(var r=new Array(e.length),i=0;i<e.length;i++)r[i]=t(e[i]);return r}function L(e,t,r,i,o){if(null===t.geometry)return void M(t,e._entityCollection,o.describe);if(!n(t.geometry))throw new h("feature.geometry is required.");var a=t.geometry.type,s=le[a];if(!n(s))throw new h("Unknown geometry type: "+a);s(e,t,t.geometry,i,o)}function N(e,t,r,i,n){for(var o=t.features,a=0,s=o.length;a<s;a++)L(e,o[a],void 0,i,n)}function k(e,t,r,i,o){for(var a=r.geometries,s=0,l=a.length;s<l;s++){var u=a[s],c=u.type,d=le[c];if(!n(d))throw new h("Unknown geometry type: "+c);d(e,t,u,i,o)}}function F(e,r,o,a,s){var l=s.markerSymbol,u=s.markerColor,c=s.markerSize,d=r.properties;if(n(d)){var h=d["marker-color"];n(h)&&(u=t.fromCssColorString(h)),c=i(oe[d["marker-size"]],c);var m=d["marker-symbol"];n(m)&&(l=m)}var v;v=n(l)?1===l.length?e._pinBuilder.fromText(l.toUpperCase(),u,c):e._pinBuilder.fromMakiIconId(l,u,c):e._pinBuilder.fromColor(u,c);var y=new _;y.verticalOrigin=new C(f.BOTTOM),2===a.length&&s.clampToGround&&(y.heightReference=p.CLAMP_TO_GROUND);var S=M(r,e._entityCollection,s.describe);S.billboard=y,S.position=new b(o(a));var w=g(v).then(function(e){y.image=new C(e)}).otherwise(function(){y.image=new C(e._pinBuilder.fromColor(u,c))});e._promises.push(w)}function B(e,t,r,i,n){F(e,t,i,r.coordinates,n)}function U(e,t,r,i,n){for(var o=r.coordinates,a=0;a<o.length;a++)F(e,t,i,o[a],n)}function V(e,r,i,o,a){var s=a.strokeMaterialProperty,l=a.strokeWidthProperty,u=r.properties;if(n(u)){var c=u["stroke-width"];n(c)&&(l=new C(c));var d,h=u.stroke;n(h)&&(d=t.fromCssColorString(h));var p=u["stroke-opacity"];n(p)&&1!==p&&(n(d)||(d=s.color.clone()),d.alpha=p),n(d)&&(s=new y(d))}var f,m=M(r,e._entityCollection,a.describe);a.clampToGround?(f=new S,m.corridor=f):(f=new x,m.polyline=f),f.material=s,f.width=l,f.positions=new C(R(o,i))}function z(e,t,r,i,n){V(e,t,i,r.coordinates,n)}function G(e,t,r,i,n){for(var o=r.coordinates,a=0;a<o.length;a++)V(e,t,i,o[a],n)}function W(e,r,i,o,a){if(0!==o.length&&0!==o[0].length){var s=a.strokeMaterialProperty.color,l=a.fillMaterialProperty,u=a.strokeWidthProperty,d=r.properties;if(n(d)){var h=d["stroke-width"];n(h)&&(u=new C(h));var p,f=d.stroke;n(f)&&(p=t.fromCssColorString(f));var m=d["stroke-opacity"];n(m)&&1!==m&&(n(p)||(p=a.strokeMaterialProperty.color.clone()),p.alpha=m),n(p)&&(s=new C(p));var g,_=d.fill;n(_)&&(g=t.fromCssColorString(_),g.alpha=l.color.alpha),m=d["fill-opacity"],n(m)&&m!==l.color.alpha&&(n(g)||(g=l.color.clone()),g.alpha=m),n(g)&&(l=new y(g))}var v=new A;v.outline=new C(!0),v.outlineColor=s,v.outlineWidth=u,v.material=l;for(var b=[],S=1,w=o.length;S<w;S++)b.push(new c(R(o[S],i)));var T=o[0];v.hierarchy=new C(new c(R(T,i),b)),T[0].length>2?v.perPositionHeight=new C(!0):a.clampToGround||(v.height=0);M(r,e._entityCollection,a.describe).polygon=v}}function H(e,t,r,i,n){W(e,t,i,r.coordinates,n)}function j(e,t,r,i,n){for(var o=r.coordinates,a=0;a<o.length;a++)W(e,t,i,o[a],n)}function q(e,t,r,i,n){for(var o in r.objects)if(r.objects.hasOwnProperty(o)){var a=m.feature(r,r.objects[o]),s=se[a.type];s(e,a,a,i,n)}}function Y(e){this._name=e,this._changed=new s,this._error=new s,this._isLoading=!1,this._loading=new s,this._entityCollection=new E(this),this._promises=[],this._pinBuilder=new u,this._entityCluster=new T}function X(e,t,r,i){var o;n(i)&&(o=l(i)),n(o)&&e._name!==o&&(e._name=o,e._changed.raiseEvent(e));var a=se[t.type];if(!n(a))throw new h("Unsupported GeoJSON object type: "+t.type);var s=t.crs,u=null!==s?P:null;if(n(s)){if(!n(s.properties))throw new h("crs.properties is undefined.");var c=s.properties;if("name"===s.type){if(u=Z[c.name],!n(u))throw new h("Unknown crs name: "+c.name)}else if("link"===s.type){var d=K[c.href];if(n(d)||(d=J[c.type]),!n(d))throw new h("Unable to resolve crs link: "+JSON.stringify(c));u=d(c)}else{if("EPSG"!==s.type)throw new h("Unknown crs type: "+s.type);if(u=Z["EPSG:"+c.code],!n(u))throw new h("Unknown crs EPSG code: "+c.code)}}return g(u,function(i){return e._entityCollection.removeAll(),null!==i&&a(e,t,t,i,r),g.all(e._promises,function(){return e._promises.length=0,w.setLoading(e,!1),e})})}var Q,Z={"urn:ogc:def:crs:OGC:1.3:CRS84":P,"EPSG:4326":P,"urn:ogc:def:crs:EPSG::4326":P},K={},J={},$=48,ee=t.ROYALBLUE,te=t.YELLOW,re=2,ie=t.fromBytes(255,255,0,100),ne=!1,oe={small:24,medium:48,large:64},ae=["title","description","marker-size","marker-symbol","marker-color","stroke","stroke-opacity","stroke-width","fill","fill-opacity"],se={Feature:L,FeatureCollection:N,GeometryCollection:k,LineString:z,MultiLineString:G,MultiPoint:U,MultiPolygon:j,Point:B,Polygon:H,Topology:q},le={GeometryCollection:k,LineString:z,MultiLineString:G,MultiPoint:U,MultiPolygon:j,Point:B,Polygon:H,Topology:q};return Y.load=function(e,t){return(new Y).load(e,t)},o(Y,{markerSize:{get:function(){return $},set:function(e){$=e}},markerSymbol:{get:function(){return Q},set:function(e){Q=e}},markerColor:{get:function(){return ee},set:function(e){ee=e}},stroke:{get:function(){return te},set:function(e){te=e}},strokeWidth:{get:function(){return re},set:function(e){re=e}},fill:{get:function(){return ie},set:function(e){ie=e}},clampToGround:{get:function(){return ne},set:function(e){ne=e}},crsNames:{get:function(){return Z}},crsLinkHrefs:{get:function(){return K}},crsLinkTypes:{get:function(){return J}}}),o(Y.prototype,{name:{get:function(){return this._name},set:function(e){this._name!==e&&(this._name=e,this._changed.raiseEvent(this))}},clock:{value:void 0,writable:!1},entities:{get:function(){return this._entityCollection}},isLoading:{get:function(){return this._isLoading}},changedEvent:{get:function(){return this._changed}},errorEvent:{get:function(){return this._error}},loadingEvent:{get:function(){return this._loading}},show:{get:function(){return this._entityCollection.show},set:function(e){this._entityCollection.show=e}},clustering:{get:function(){return this._entityCluster},set:function(e){this._entityCluster=e}}}),Y.prototype.load=function(e,t){w.setLoading(this,!0);var r=e;t=i(t,i.EMPTY_OBJECT);var n=t.sourceUri;("string"==typeof e||e instanceof d)&&(e=d.createIfNeeded(e),r=e.fetchJson(),n=i(n,e.getUrlComponent())),t={describe:i(t.describe,O),markerSize:i(t.markerSize,$),markerSymbol:i(t.markerSymbol,Q),markerColor:i(t.markerColor,ee),strokeWidthProperty:new C(i(t.strokeWidth,re)),strokeMaterialProperty:new y(i(t.stroke,te)),fillMaterialProperty:new y(i(t.fill,ie)),clampToGround:i(t.clampToGround,ne)};var o=this;return g(r,function(e){return X(o,e,t,n)}).otherwise(function(e){return w.setLoading(o,!1),o._error.raiseEvent(o,e),console.log(e),g.reject(e)})},Y}),define("DataSources/GeometryUpdater",["../Core/defineProperties","../Core/DeveloperError"],function(e,t){"use strict";function r(e,r){t.throwInstantiationError()}return e(r,{perInstanceColorAppearanceType:{get:t.throwInstantiationError},materialAppearanceType:{get:t.throwInstantiationError}}),e(r.prototype,{entity:{get:t.throwInstantiationError},fillEnabled:{get:t.throwInstantiationError},hasConstantFill:{get:t.throwInstantiationError},fillMaterialProperty:{get:t.throwInstantiationError},outlineEnabled:{get:t.throwInstantiationError},hasConstantOutline:{get:t.throwInstantiationError},outlineColorProperty:{get:t.throwInstantiationError},outlineWidth:{get:t.throwInstantiationError},isDynamic:{get:t.throwInstantiationError},isClosed:{get:t.throwInstantiationError},geometryChanged:{get:t.throwInstantiationError}}),r.prototype.isOutlineVisible=t.throwInstantiationError,r.prototype.isFilled=t.throwInstantiationError,r.prototype.createFillGeometryInstance=t.throwInstantiationError,r.prototype.createOutlineGeometryInstance=t.throwInstantiationError,r.prototype.isDestroyed=t.throwInstantiationError,r.prototype.destroy=t.throwInstantiationError,r.prototype.createDynamicUpdater=t.throwInstantiationError,r}),define("DataSources/KmlCamera",[],function(){"use strict";function e(e,t){this.position=e,this.headingPitchRoll=t}return e}),function(e,t){"function"==typeof define&&define.amd?define("ThirdParty/Autolinker",[],function(){return e.Autolinker=t()}):"object"==typeof exports?module.exports=t():e.Autolinker=t()}(this,function(){var e=function(t){e.Util.assign(this,t);var r=this.hashtag;if(!1!==r&&"twitter"!==r&&"facebook"!==r)throw new Error("invalid `hashtag` cfg - see docs")};return e.prototype={constructor:e,urls:!0,email:!0,twitter:!0,phone:!0,hashtag:!1,newWindow:!0,stripPrefix:!0,truncate:void 0,className:"",htmlParser:void 0,matchParser:void 0,tagBuilder:void 0,link:function(e){for(var t=this.getHtmlParser(),r=t.parse(e),i=0,n=[],o=0,a=r.length;o<a;o++){ +var s=r[o],l=s.getType(),u=s.getText();if("element"===l)"a"===s.getTagName()&&(s.isClosing()?i=Math.max(i-1,0):i++),n.push(u);else if("entity"===l||"comment"===l)n.push(u);else if(0===i){var c=this.linkifyStr(u);n.push(c)}else n.push(u)}return n.join("")},linkifyStr:function(e){return this.getMatchParser().replace(e,this.createMatchReturnVal,this)},createMatchReturnVal:function(t){var r;return this.replaceFn&&(r=this.replaceFn.call(this,this,t)),"string"==typeof r?r:!1===r?t.getMatchedText():r instanceof e.HtmlTag?r.toAnchorString():this.getTagBuilder().build(t).toAnchorString()},getHtmlParser:function(){var t=this.htmlParser;return t||(t=this.htmlParser=new e.htmlParser.HtmlParser),t},getMatchParser:function(){var t=this.matchParser;return t||(t=this.matchParser=new e.matchParser.MatchParser({urls:this.urls,email:this.email,twitter:this.twitter,phone:this.phone,hashtag:this.hashtag,stripPrefix:this.stripPrefix})),t},getTagBuilder:function(){var t=this.tagBuilder;return t||(t=this.tagBuilder=new e.AnchorTagBuilder({newWindow:this.newWindow,truncate:this.truncate,className:this.className})),t}},e.link=function(t,r){return new e(r).link(t)},e.match={},e.htmlParser={},e.matchParser={},e.Util={abstractMethod:function(){throw"abstract"},trimRegex:/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,assign:function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e},extend:function(t,r){var i=t.prototype,n=function(){};n.prototype=i;var o;o=r.hasOwnProperty("constructor")?r.constructor:function(){i.constructor.apply(this,arguments)};var a=o.prototype=new n;return a.constructor=o,a.superclass=i,delete r.constructor,e.Util.assign(a,r),o},ellipsis:function(e,t,r){return e.length>t&&(r=null==r?"..":r,e=e.substring(0,t-r.length)+r),e},indexOf:function(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,i=e.length;r<i;r++)if(e[r]===t)return r;return-1},splitAndCapture:function(e,t){if(!t.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var r,i=[],n=0;r=t.exec(e);)i.push(e.substring(n,r.index)),i.push(r[0]),n=r.index+r[0].length;return i.push(e.substring(n)),i},trim:function(e){return e.replace(this.trimRegex,"")}},e.HtmlTag=e.Util.extend(Object,{whitespaceRegex:/\s+/,constructor:function(t){e.Util.assign(this,t),this.innerHtml=this.innerHtml||this.innerHTML},setTagName:function(e){return this.tagName=e,this},getTagName:function(){return this.tagName||""},setAttr:function(e,t){return this.getAttrs()[e]=t,this},getAttr:function(e){return this.getAttrs()[e]},setAttrs:function(t){var r=this.getAttrs();return e.Util.assign(r,t),this},getAttrs:function(){return this.attrs||(this.attrs={})},setClass:function(e){return this.setAttr("class",e)},addClass:function(t){for(var r,i=this.getClass(),n=this.whitespaceRegex,o=e.Util.indexOf,a=i?i.split(n):[],s=t.split(n);r=s.shift();)-1===o(a,r)&&a.push(r);return this.getAttrs().class=a.join(" "),this},removeClass:function(t){for(var r,i=this.getClass(),n=this.whitespaceRegex,o=e.Util.indexOf,a=i?i.split(n):[],s=t.split(n);a.length&&(r=s.shift());){var l=o(a,r);-1!==l&&a.splice(l,1)}return this.getAttrs().class=a.join(" "),this},getClass:function(){return this.getAttrs().class||""},hasClass:function(e){return-1!==(" "+this.getClass()+" ").indexOf(" "+e+" ")},setInnerHtml:function(e){return this.innerHtml=e,this},getInnerHtml:function(){return this.innerHtml||""},toAnchorString:function(){var e=this.getTagName(),t=this.buildAttrsStr();return t=t?" "+t:"",["<",e,t,">",this.getInnerHtml(),"</",e,">"].join("")},buildAttrsStr:function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'="'+e[r]+'"');return t.join(" ")}}),e.AnchorTagBuilder=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},build:function(t){return new e.HtmlTag({tagName:"a",attrs:this.createAttrs(t.getType(),t.getAnchorHref()),innerHtml:this.processAnchorText(t.getAnchorText())})},createAttrs:function(e,t){var r={href:t},i=this.createCssClass(e);return i&&(r.class=i),this.newWindow&&(r.target="_blank"),r},createCssClass:function(e){var t=this.className;return t?t+" "+t+"-"+e:""},processAnchorText:function(e){return e=this.doTruncate(e)},doTruncate:function(t){return e.Util.ellipsis(t,this.truncate||Number.POSITIVE_INFINITY)}}),e.htmlParser.HtmlParser=e.Util.extend(Object,{htmlRegex:function(){var e=/!--([\s\S]+?)--/,t=/[0-9a-zA-Z][0-9a-zA-Z:]*/,r=/[^\s\0"'>\/=\x01-\x1F\x7F]+/,i=/(?:"[^"]*?"|'[^']*?'|[^'"=<>`\s]+)/,n=r.source+"(?:\\s*=\\s*"+i.source+")?";return new RegExp(["(?:","<(!DOCTYPE)","(?:","\\s+","(?:",n,"|",i.source+")",")*",">",")","|","(?:","<(/)?","(?:",e.source,"|","(?:","("+t.source+")","(?:","\\s+",n,")*","\\s*/?",")",")",">",")"].join(""),"gi")}(),htmlCharacterEntitiesRegex:/( | |<|<|>|>|"|"|')/gi,parse:function(e){for(var t,r,i=this.htmlRegex,n=0,o=[];null!==(t=i.exec(e));){var a=t[0],s=t[3],l=t[1]||t[4],u=!!t[2],c=e.substring(n,t.index);c&&(r=this.parseTextAndEntityNodes(c),o.push.apply(o,r)),s?o.push(this.createCommentNode(a,s)):o.push(this.createElementNode(a,l,u)),n=t.index+a.length}if(n<e.length){var d=e.substring(n);d&&(r=this.parseTextAndEntityNodes(d),o.push.apply(o,r))}return o},parseTextAndEntityNodes:function(t){for(var r=[],i=e.Util.splitAndCapture(t,this.htmlCharacterEntitiesRegex),n=0,o=i.length;n<o;n+=2){var a=i[n],s=i[n+1];a&&r.push(this.createTextNode(a)),s&&r.push(this.createEntityNode(s))}return r},createCommentNode:function(t,r){return new e.htmlParser.CommentNode({text:t,comment:e.Util.trim(r)})},createElementNode:function(t,r,i){return new e.htmlParser.ElementNode({text:t,tagName:r.toLowerCase(),closing:i})},createEntityNode:function(t){return new e.htmlParser.EntityNode({text:t})},createTextNode:function(t){return new e.htmlParser.TextNode({text:t})}}),e.htmlParser.HtmlNode=e.Util.extend(Object,{text:"",constructor:function(t){e.Util.assign(this,t)},getType:e.Util.abstractMethod,getText:function(){return this.text}}),e.htmlParser.CommentNode=e.Util.extend(e.htmlParser.HtmlNode,{comment:"",getType:function(){return"comment"},getComment:function(){return this.comment}}),e.htmlParser.ElementNode=e.Util.extend(e.htmlParser.HtmlNode,{tagName:"",closing:!1,getType:function(){return"element"},getTagName:function(){return this.tagName},isClosing:function(){return this.closing}}),e.htmlParser.EntityNode=e.Util.extend(e.htmlParser.HtmlNode,{getType:function(){return"entity"}}),e.htmlParser.TextNode=e.Util.extend(e.htmlParser.HtmlNode,{getType:function(){return"text"}}),e.matchParser.MatchParser=e.Util.extend(Object,{urls:!0,email:!0,twitter:!0,phone:!0,hashtag:!1,stripPrefix:!0,matcherRegex:function(){var e=/(^|[^\w])@(\w{1,15})/,t=/(^|[^\w])#(\w{1,15})/,r=/(?:[\-;:&=\+\$,\w\.]+@)/,i=/(?:\+?\d{1,3}[-\s.])?\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/,n=/(?:[A-Za-z][-.+A-Za-z0-9]+:(?![A-Za-z][-.+A-Za-z0-9]+:\/\/)(?!\d+\/?)(?:\/\/)?)/,o=/(?:www\.)/,a=/[A-Za-z0-9\.\-]*[A-Za-z0-9\-]/,s=/\.(?:international|construction|contractors|enterprises|photography|productions|foundation|immobilien|industries|management|properties|technology|christmas|community|directory|education|equipment|institute|marketing|solutions|vacations|bargains|boutique|builders|catering|cleaning|clothing|computer|democrat|diamonds|graphics|holdings|lighting|partners|plumbing|supplies|training|ventures|academy|careers|company|cruises|domains|exposed|flights|florist|gallery|guitars|holiday|kitchen|neustar|okinawa|recipes|rentals|reviews|shiksha|singles|support|systems|agency|berlin|camera|center|coffee|condos|dating|estate|events|expert|futbol|kaufen|luxury|maison|monash|museum|nagoya|photos|repair|report|social|supply|tattoo|tienda|travel|viajes|villas|vision|voting|voyage|actor|build|cards|cheap|codes|dance|email|glass|house|mango|ninja|parts|photo|shoes|solar|today|tokyo|tools|watch|works|aero|arpa|asia|best|bike|blue|buzz|camp|club|cool|coop|farm|fish|gift|guru|info|jobs|kiwi|kred|land|limo|link|menu|mobi|moda|name|pics|pink|post|qpon|rich|ruhr|sexy|tips|vote|voto|wang|wien|wiki|zone|bar|bid|biz|cab|cat|ceo|com|edu|gov|int|kim|mil|net|onl|org|pro|pub|red|tel|uno|wed|xxx|xyz|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/,l=/[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]?!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]]/;return new RegExp(["(",e.source,")","|","(",r.source,a.source,s.source,")","|","(","(?:","(",n.source,a.source,")","|","(?:","(.?//)?",o.source,a.source,")","|","(?:","(.?//)?",a.source,s.source,")",")","(?:"+l.source+")?",")","|","(",i.source,")","|","(",t.source,")"].join(""),"gi")}(),charBeforeProtocolRelMatchRegex:/^(.)?\/\//,constructor:function(t){e.Util.assign(this,t),this.matchValidator=new e.MatchValidator},replace:function(e,t,r){var i=this;return e.replace(this.matcherRegex,function(e,n,o,a,s,l,u,c,d,h,p,f,m){var g=i.processCandidateMatch(e,n,o,a,s,l,u,c,d,h,p,f,m);if(g){var _=t.call(r,g.match);return g.prefixStr+_+g.suffixStr}return e})},processCandidateMatch:function(t,r,i,n,o,a,s,l,u,c,d,h,p){var f,m=l||u,g="",_="";if(a&&!this.urls||o&&!this.email||c&&!this.phone||r&&!this.twitter||d&&!this.hashtag||!this.matchValidator.isValidMatch(a,s,m))return null;if(this.matchHasUnbalancedClosingParen(t)&&(t=t.substr(0,t.length-1),_=")"),o)f=new e.match.Email({matchedText:t,email:o});else if(r)i&&(g=i,t=t.slice(1)),f=new e.match.Twitter({matchedText:t,twitterHandle:n});else if(c){var v=t.replace(/\D/g,"");f=new e.match.Phone({matchedText:t,number:v})}else if(d)h&&(g=h,t=t.slice(1)),f=new e.match.Hashtag({matchedText:t,serviceName:this.hashtag,hashtag:p});else{if(m){var y=m.match(this.charBeforeProtocolRelMatchRegex)[1]||"";y&&(g=y,t=t.slice(1))}f=new e.match.Url({matchedText:t,url:t,protocolUrlMatch:!!s,protocolRelativeMatch:!!m,stripPrefix:this.stripPrefix})}return{prefixStr:g,suffixStr:_,match:f}},matchHasUnbalancedClosingParen:function(e){if(")"===e.charAt(e.length-1)){var t=e.match(/\(/g),r=e.match(/\)/g);if((t&&t.length||0)<(r&&r.length||0))return!0}return!1}}),e.MatchValidator=e.Util.extend(Object,{invalidProtocolRelMatchRegex:/^[\w]\/\//,hasFullProtocolRegex:/^[A-Za-z][-.+A-Za-z0-9]+:\/\//,uriSchemeRegex:/^[A-Za-z][-.+A-Za-z0-9]+:/,hasWordCharAfterProtocolRegex:/:[^\s]*?[A-Za-z]/,isValidMatch:function(e,t,r){return!(t&&!this.isValidUriScheme(t)||this.urlMatchDoesNotHaveProtocolOrDot(e,t)||this.urlMatchDoesNotHaveAtLeastOneWordChar(e,t)||this.isInvalidProtocolRelativeMatch(r))},isValidUriScheme:function(e){var t=e.match(this.uriSchemeRegex)[0].toLowerCase();return"javascript:"!==t&&"vbscript:"!==t},urlMatchDoesNotHaveProtocolOrDot:function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf("."))},urlMatchDoesNotHaveAtLeastOneWordChar:function(e,t){return!(!e||!t)&&!this.hasWordCharAfterProtocolRegex.test(e)},isInvalidProtocolRelativeMatch:function(e){return!!e&&this.invalidProtocolRelMatchRegex.test(e)}}),e.match.Match=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},getType:e.Util.abstractMethod,getMatchedText:function(){return this.matchedText},getAnchorHref:e.Util.abstractMethod,getAnchorText:e.Util.abstractMethod}),e.match.Email=e.Util.extend(e.match.Match,{getType:function(){return"email"},getEmail:function(){return this.email},getAnchorHref:function(){return"mailto:"+this.email},getAnchorText:function(){return this.email}}),e.match.Hashtag=e.Util.extend(e.match.Match,{getType:function(){return"hashtag"},getHashtag:function(){return this.hashtag},getAnchorHref:function(){var e=this.serviceName,t=this.hashtag;switch(e){case"twitter":return"https://twitter.com/hashtag/"+t;case"facebook":return"https://www.facebook.com/hashtag/"+t;default:throw new Error("Unknown service name to point hashtag to: ",e)}},getAnchorText:function(){return"#"+this.hashtag}}),e.match.Phone=e.Util.extend(e.match.Match,{getType:function(){return"phone"},getNumber:function(){return this.number},getAnchorHref:function(){return"tel:"+this.number},getAnchorText:function(){return this.matchedText}}),e.match.Twitter=e.Util.extend(e.match.Match,{getType:function(){return"twitter"},getTwitterHandle:function(){return this.twitterHandle},getAnchorHref:function(){return"https://twitter.com/"+this.twitterHandle},getAnchorText:function(){return"@"+this.twitterHandle}}),e.match.Url=e.Util.extend(e.match.Match,{urlPrefixRegex:/^(https?:\/\/)?(www\.)?/i,protocolRelativeRegex:/^\/\//,protocolPrepended:!1,getType:function(){return"url"},getUrl:function(){var e=this.url;return this.protocolRelativeMatch||this.protocolUrlMatch||this.protocolPrepended||(e=this.url="http://"+e,this.protocolPrepended=!0),e},getAnchorHref:function(){return this.getUrl().replace(/&/g,"&")},getAnchorText:function(){var e=this.getUrl();return this.protocolRelativeMatch&&(e=this.stripProtocolRelativePrefix(e)),this.stripPrefix&&(e=this.stripUrlPrefix(e)),e=this.removeTrailingSlash(e)},stripUrlPrefix:function(e){return e.replace(this.urlPrefixRegex,"")},stripProtocolRelativePrefix:function(e){return e.replace(this.protocolRelativeRegex,"")},removeTrailingSlash:function(e){return"/"===e.charAt(e.length-1)&&(e=e.slice(0,-1)),e}}),e}),define("ThirdParty/zip",["../Core/buildModuleUrl","../Core/defineProperties"],function(e,t){var r={};return function(r){function i(){var e=-1,t=this;t.append=function(r){var i,n=t.table;for(i=0;i<r.length;i++)e=e>>>8^n[255&(e^r[i])]},t.get=function(){return~e}}function n(e,t,r){return e.slice?e.slice(t,t+r):e.webkitSlice?e.webkitSlice(t,t+r):e.mozSlice?e.mozSlice(t,t+r):e.msSlice?e.msSlice(t,t+r):void 0}function o(e,t){var r,i;return r=new ArrayBuffer(e),i=new Uint8Array(r),t&&i.set(t,0),{buffer:r,array:i,view:new DataView(r)}}function a(){}function s(e){function t(t,r){var o=new Blob([e],{type:V});i=new u(o),i.init(function(){n.size=i.size,t()},r)}function r(e,t,r,n){i.readUint8Array(e,t,r,n)}var i,n=this;n.size=0,n.init=t,n.readUint8Array=r}function l(e){function t(t){for(var r=e.length;"="==e.charAt(r-1);)r--;i=e.indexOf(",")+1,n.size=Math.floor(.75*(r-i)),t()}function r(t,r,n){var a,s=o(r),l=4*Math.floor(t/3),u=4*Math.ceil((t+r)/3),c=window.atob(e.substring(l+i,u+i)),d=t-3*Math.floor(l/4);for(a=d;a<d+r;a++)s.array[a-d]=c.charCodeAt(a);n(s.array)}var i,n=this;n.size=0,n.init=t,n.readUint8Array=r}function u(e){function t(t){this.size=e.size,t()}function r(t,r,i,o){var a=new FileReader;a.onload=function(e){i(new Uint8Array(e.target.result))},a.onerror=o,a.readAsArrayBuffer(n(e,t,r))}var i=this;i.size=0,i.init=t,i.readUint8Array=r}function c(){}function d(e){function t(e){n=new Blob([],{type:V}),e()}function r(e,t){n=new Blob([n,P?e:e.buffer],{type:V}),t()}function i(t,r){var i=new FileReader;i.onload=function(e){t(e.target.result)},i.onerror=r,i.readAsText(n,e)}var n,o=this;o.init=t,o.writeUint8Array=r,o.getData=i}function h(e){function t(t){o+="data:"+(e||"")+";base64,",t()}function r(e,t){var r,i=a.length,n=a;for(a="",r=0;r<3*Math.floor((i+e.length)/3)-i;r++)n+=String.fromCharCode(e[r]);for(;r<e.length;r++)a+=String.fromCharCode(e[r]);n.length>2?o+=window.btoa(n):a=n,t()}function i(e){e(o+window.btoa(a))}var n=this,o="",a="";n.init=t,n.writeUint8Array=r,n.getData=i}function p(e){function t(t){n=new Blob([],{type:e}),t()}function r(t,r){n=new Blob([n,P?t:t.buffer],{type:e}),r()}function i(e){e(n)}var n,o=this;o.init=t,o.writeUint8Array=r,o.getData=i}function f(e,t,r,i,n,o,a,s,l,u){function c(){e.removeEventListener(z,d,!1),s(f)}function d(e){var t=e.data,i=t.data;t.onappend&&(f+=i.length,r.writeUint8Array(i,function(){o(!1,i),h()},u)),t.onflush&&(i?(f+=i.length,r.writeUint8Array(i,function(){o(!1,i),c()},u)):c()),t.progress&&a&&a(p+t.current,n)}function h(){p=m*F,p<n?t.readUint8Array(i+p,Math.min(F,n-p),function(t){e.postMessage({append:!0,data:t}),m++,a&&a(p,n),o(!0,t)},l):e.postMessage({flush:!0})}var p,f,m=0;f=0,e.addEventListener(z,d,!1),h()}function m(e,t,r,i,n,o,a,s,l,u){function c(){var f;d=h*F,d<n?t.readUint8Array(i+d,Math.min(F,n-d),function(t){var s=e.append(t,function(){a&&a(i+d,n)});p+=s.length,o(!0,t),r.writeUint8Array(s,function(){o(!1,s),h++,setTimeout(c,1)},u),a&&a(d,n)},l):(f=e.flush(),f?(p+=f.length,r.writeUint8Array(f,function(){o(!1,f),s(p)},u)):s(p))}var d,h=0,p=0;c()}function g(e,t,n,o,a,s,l,u,c){function d(e,t){a&&!e&&g.append(t)}function h(e){s(e,g.get())}var p,g=new i;return r.zip.useWebWorkers?(p=new Worker(r.zip.workerScriptsPath+B),f(p,e,t,n,o,d,l,h,u,c)):m(new r.zip.Inflater,e,t,n,o,d,l,h,u,c),p}function _(e,t,n,o,a,s,l){function u(e,t){e&&p.append(t)}function c(e){o(e,p.get())}function d(){h.removeEventListener(z,d,!1),f(h,e,t,0,e.size,u,a,c,s,l)}var h,p=new i;return r.zip.useWebWorkers?(h=new Worker(r.zip.workerScriptsPath+U),h.addEventListener(z,d,!1),h.postMessage({init:!0,level:n})):m(new r.zip.Deflater,e,t,0,e.size,u,a,c,s,l),h}function v(e,t,r,n,o,a,s,l,u){function c(){var i=d*F;i<n?e.readUint8Array(r+i,Math.min(F,n-i),function(e){o&&h.append(e),s&&s(i,n,e),t.writeUint8Array(e,function(){d++,c()},u)},l):a(n,h.get())}var d=0,h=new i;c()}function y(e){var t,r,i="",n=["Ç","ü","é","â","ä","à","å","ç","ê","ë","è","ï","î","ì","Ä","Å","É","æ","Æ","ô","ö","ò","û","ù","ÿ","Ö","Ü","ø","£","Ø","×","ƒ","á","í","ó","ú","ñ","Ñ","ª","º","¿","®","¬","½","¼","¡","«","»","_","_","_","¦","¦","Á","Â","À","©","¦","¦","+","+","¢","¥","+","+","-","-","+","-","+","ã","Ã","+","+","-","-","¦","-","+","¤","ð","Ð","Ê","Ë","È","i","Í","Î","Ï","+","+","_","_","¦","Ì","_","Ó","ß","Ô","Ò","õ","Õ","µ","þ","Þ","Ú","Û","Ù","ý","Ý","¯","´","­","±","_","¾","¶","§","÷","¸","°","¨","·","¹","³","²","_"," "];for(t=0;t<e.length;t++)r=255&e.charCodeAt(t),i+=r>127?n[r-128]:String.fromCharCode(r);return i}function b(e){return decodeURIComponent(escape(e))}function C(e){var t,r="";for(t=0;t<e.length;t++)r+=String.fromCharCode(e[t]);return r}function S(e){var t=(4294901760&e)>>16,r=65535&e;try{return new Date(1980+((65024&t)>>9),((480&t)>>5)-1,31&t,(63488&r)>>11,(2016&r)>>5,2*(31&r),0)}catch(e){}}function w(e,t,r,i,n){return e.version=t.view.getUint16(r,!0),e.bitFlag=t.view.getUint16(r+2,!0),e.compressionMethod=t.view.getUint16(r+4,!0),e.lastModDateRaw=t.view.getUint32(r+6,!0),e.lastModDate=S(e.lastModDateRaw),1==(1&e.bitFlag)?void n(I):((i||8!=(8&e.bitFlag))&&(e.crc32=t.view.getUint32(r+10,!0),e.compressedSize=t.view.getUint32(r+14,!0),e.uncompressedSize=t.view.getUint32(r+18,!0)),4294967295===e.compressedSize||4294967295===e.uncompressedSize?void n(O):(e.filenameLength=t.view.getUint16(r+22,!0),void(e.extraFieldLength=t.view.getUint16(r+24,!0))))}function T(e,t){function r(){}function i(r,n){e.readUint8Array(e.size-r,r,function(e){var t=o(e.length,e).view;1347093766!=t.getUint32(0)?i(r+1,n):n(t)},function(){t(M)})}return r.prototype.getData=function(r,i,n,a){function s(e,t){h&&h.terminate(),h=null,e&&e(t)}function l(e){var t=o(4);return t.view.setUint32(0,e),p.crc32==t.view.getUint32(0)}function u(e,t){a&&!l(t)?c():r.getData(function(e){s(i,e)})}function c(){s(t,N)}function d(){s(t,L)}var h,p=this;e.readUint8Array(p.offset,30,function(i){var s,l=o(i.length,i);if(1347093252!=l.view.getUint32(0))return void t(D);w(p,l,4,!1,t),s=p.offset+30+p.filenameLength+p.extraFieldLength,r.init(function(){0===p.compressionMethod?v(e,r,s,p.compressedSize,a,u,n,c,d):h=g(e,r,s,p.compressedSize,a,u,n,c,d)},d)},c)},{getEntries:function(n){if(e.size<22)return void t(D);i(22,function(i){var a,s;a=i.getUint32(16,!0),s=i.getUint16(8,!0),e.readUint8Array(a,e.size-a,function(e){var i,a,l,u,c=0,d=[],h=o(e.length,e);for(i=0;i<s;i++){if(a=new r,1347092738!=h.view.getUint32(c))return void t(D);w(a,h,c+6,!0,t),a.commentLength=h.view.getUint16(c+32,!0),a.directory=16==(16&h.view.getUint8(c+38)),a.offset=h.view.getUint32(c+42,!0),l=C(h.array.subarray(c+46,c+46+a.filenameLength)),a.filename=2048==(2048&a.bitFlag)?b(l):y(l),a.directory||"/"!=a.filename.charAt(a.filename.length-1)||(a.directory=!0),u=C(h.array.subarray(c+46+a.filenameLength+a.extraFieldLength,c+46+a.filenameLength+a.extraFieldLength+a.commentLength)),a.comment=2048==(2048&a.bitFlag)?b(u):y(u),d.push(a),c+=46+a.filenameLength+a.extraFieldLength+a.commentLength}n(d)},function(){t(M)})})},close:function(e){e&&e()}}}function E(e){return unescape(encodeURIComponent(e))}function A(e){var t,r=[];for(t=0;t<e.length;t++)r.push(e.charCodeAt(t));return r}function x(e,t,r){function i(e,t){s&&s.terminate(),s=null,e&&e(t)}function n(){i(t,R)}function a(){i(t,N)}var s,l={},u=[],c=0;return{add:function(d,h,p,f,m){function g(t){var i;w=m.lastModDate||new Date,C=o(26),l[d]={headerArray:C.array,directory:m.directory,filename:S,offset:c,comment:A(E(m.comment||""))},C.view.setUint32(0,335546376),m.version&&C.view.setUint8(0,m.version),r||0===m.level||m.directory||C.view.setUint16(4,2048),C.view.setUint16(6,(w.getHours()<<6|w.getMinutes())<<5|w.getSeconds()/2,!0),C.view.setUint16(8,(w.getFullYear()-1980<<4|w.getMonth()+1)<<5|w.getDate(),!0),C.view.setUint16(22,S.length,!0),i=o(30+S.length),i.view.setUint32(0,1347093252),i.array.set(C.array,4),i.array.set(S,30),c+=i.array.length,e.writeUint8Array(i.array,t,n)}function y(t,r){var a=o(16);c+=t||0,a.view.setUint32(0,1347094280),void 0!==r&&(C.view.setUint32(10,r,!0),a.view.setUint32(4,r,!0)),h&&(a.view.setUint32(8,t,!0),C.view.setUint32(14,t,!0),a.view.setUint32(12,h.size,!0),C.view.setUint32(18,h.size,!0)),e.writeUint8Array(a.array,function(){c+=16,i(p)},n)}function b(){if(m=m||{},d=d.trim(),m.directory&&"/"!=d.charAt(d.length-1)&&(d+="/"),l.hasOwnProperty(d))return void t(k);S=A(E(d)),u.push(d),g(function(){h?r||0===m.level?v(h,e,0,h.size,!0,y,f,a,n):s=_(h,e,m.level,y,f,a,n):y()},n)}var C,S,w;h?h.init(b,a):b()},close:function(t){var r,a,s,d=0,h=0;for(a=0;a<u.length;a++)s=l[u[a]],d+=46+s.filename.length+s.comment.length;for(r=o(d+22),a=0;a<u.length;a++)s=l[u[a]],r.view.setUint32(h,1347092738),r.view.setUint16(h+4,5120),r.array.set(s.headerArray,h+6),r.view.setUint16(h+32,s.comment.length,!0),s.directory&&r.view.setUint8(h+38,16),r.view.setUint32(h+42,s.offset,!0),r.array.set(s.filename,h+46),r.array.set(s.comment,h+46+s.filename.length),h+=46+s.filename.length+s.comment.length;r.view.setUint32(h,1347093766),r.view.setUint16(h+8,u.length,!0),r.view.setUint16(h+10,u.length,!0),r.view.setUint32(h+12,d,!0),r.view.setUint32(h+16,c,!0),e.writeUint8Array(r.array,function(){i(function(){e.getData(t)})},n)}}}var P,D="File format is not recognized.",I="File contains encrypted entry.",O="File is using Zip64 (4gb+ file size).",M="Error while reading zip file.",R="Error while writing zip file.",L="Error while writing file data.",N="Error while reading file data.",k="File already exists.",F=524288,B="inflate.js",U="deflate.js",V="text/plain",z="message";try{P=0===new Blob([new DataView(new ArrayBuffer(0))]).size}catch(e){}i.prototype.table=function(){var e,t,r,i=[];for(e=0;e<256;e++){for(r=e,t=0;t<8;t++)1&r?r=r>>>1^3988292384:r>>>=1;i[e]=r}return i}(),s.prototype=new a,s.prototype.constructor=s,l.prototype=new a,l.prototype.constructor=l,u.prototype=new a,u.prototype.constructor=u,c.prototype.getData=function(e){e(this.data)},d.prototype=new c,d.prototype.constructor=d,h.prototype=new c,h.prototype.constructor=h,p.prototype=new c,p.prototype.constructor=p,r.zip={Reader:a,Writer:c,BlobReader:u,Data64URIReader:l,TextReader:s,BlobWriter:p,Data64URIWriter:h,TextWriter:d,createReader:function(e,t,r){e.init(function(){t(T(e,r))},r)},createWriter:function(e,t,r,i){e.init(function(){t(x(e,r,i))},r)},useWebWorkers:!0};var G;t(r.zip,{workerScriptsPath:{get:function(){return void 0===G&&(G=e("ThirdParty/Workers/")),G}}})}(r),r.zip}),define("DataSources/KmlLookAt",[],function(){"use strict";function e(e,t){this.position=e,this.headingPitchRange=t}return e}),define("DataSources/KmlTour",["../Core/Event","../Core/defined"],function(e,t){"use strict";function r(t,r){this.id=r,this.name=t,this.playlistIndex=0,this.playlist=[],this.tourStart=new e,this.tourEnd=new e,this.entryStart=new e,this.entryEnd=new e,this._activeEntries=[]}function i(e){for(var t=e.pop();void 0!==t;t=e.pop())t.stop()}function n(e,r,i){var n=this.playlist[this.playlistIndex];if(n){var a=o.bind(this,e,r,i);if(this._activeEntries.push(n),this.entryStart.raiseEvent(n),n.blocking)n.play(a,e.scene.camera,r);else{var s=this;n.play(function(){s.entryEnd.raiseEvent(n);var e=s._activeEntries.indexOf(n);e>=0&&s._activeEntries.splice(e,1)}),a(e,r,i)}}else t(i)&&i(!1)}function o(e,t,r,i){var o=this.playlist[this.playlistIndex];if(this.entryEnd.raiseEvent(o,i),i)r(i);else{var a=this._activeEntries.indexOf(o);a>=0&&this._activeEntries.splice(a,1),this.playlistIndex++,n.call(this,e,t,r)}}return r.prototype.addPlaylistEntry=function(e){this.playlist.push(e)},r.prototype.play=function(e,t){this.tourStart.raiseEvent();var r=this;n.call(this,e,t,function(e){r.playlistIndex=0,e||i(r._activeEntries),r.tourEnd.raiseEvent(e)})},r.prototype.stop=function(){i(this._activeEntries)},r}),define("DataSources/KmlTourFlyTo",["../Core/defined","../Core/combine","../Core/BoundingSphere","../Core/EasingFunction"],function(e,t,r,i){"use strict";function n(e,t,r){this.type="KmlTourFlyTo",this.blocking=!0,this.activeCamera=null,this.activeCallback=null,this.duration=e,this.view=r,this.flyToMode=t}return n.prototype.play=function(t,i,n){if(this.activeCamera=i,e(t)&&null!==t){var o=this;this.activeCallback=function(r){delete o.activeCallback,delete o.activeCamera,t(!e(r)&&r)}}var a=this.getCameraOptions(n);if(this.view.headingPitchRoll)i.flyTo(a);else if(this.view.headingPitchRange){var s=new r(this.view.position);i.flyToBoundingSphere(s,a)}},n.prototype.stop=function(){e(this.activeCamera)&&this.activeCamera.cancelFlight(),e(this.activeCallback)&&this.activeCallback(!0)},n.prototype.getCameraOptions=function(r){var n={duration:this.duration};return e(this.activeCallback)&&(n.complete=this.activeCallback),"smooth"===this.flyToMode&&(n.easingFunction=i.LINEAR_NONE),this.view.headingPitchRoll?(n.destination=this.view.position,n.orientation=this.view.headingPitchRoll):this.view.headingPitchRange&&(n.offset=this.view.headingPitchRange),e(r)&&(n=t(n,r)),n},n}),define("DataSources/KmlTourWait",["../Core/defined"],function(e){"use strict";function t(e){this.type="KmlTourWait",this.blocking=!0,this.duration=e,this.timeout=null}return t.prototype.play=function(e){var t=this;this.activeCallback=e,this.timeout=setTimeout(function(){delete t.activeCallback,e(!1)},1e3*this.duration)},t.prototype.stop=function(){clearTimeout(this.timeout),e(this.activeCallback)&&this.activeCallback(!0)},t}),define("DataSources/KmlDataSource",["../Core/AssociativeArray","../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/ClockRange","../Core/ClockStep","../Core/Color","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Ellipsoid","../Core/Event","../Core/getExtensionFromUri","../Core/getFilenameFromUri","../Core/Iso8601","../Core/JulianDate","../Core/Math","../Core/NearFarScalar","../Core/objectToQuery","../Core/oneTimeWarning","../Core/PinBuilder","../Core/PolygonHierarchy","../Core/queryToObject","../Core/Rectangle","../Core/Resource","../Core/RuntimeError","../Core/TimeInterval","../Core/TimeIntervalCollection","../Core/HeadingPitchRoll","../Core/HeadingPitchRange","../Scene/HeightReference","../Scene/HorizontalOrigin","../Scene/LabelStyle","../Scene/SceneMode","../ThirdParty/Autolinker","../ThirdParty/Uri","../ThirdParty/when","../ThirdParty/zip","./BillboardGraphics","./CompositePositionProperty","./CorridorGraphics","./DataSource","./DataSourceClock","./Entity","./EntityCluster","./EntityCollection","./LabelGraphics","./PathGraphics","./PolygonGraphics","./PolylineGraphics","./PositionPropertyArray","./RectangleGraphics","./ReferenceProperty","./SampledPositionProperty","./ScaledPositionProperty","./TimeIntervalCollectionProperty","./WallGraphics","./KmlLookAt","./KmlCamera","./KmlTour","./KmlTourFlyTo","./KmlTourWait"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de){"use strict";function he(e){var t=e.slice(0,Math.min(4,e.size)),r=V.defer(),i=new FileReader;return i.addEventListener("load",function(){r.resolve(1347093252===new DataView(i.result).getUint32(0,!1))}),i.addEventListener("error",function(){r.reject(i.error)}),i.readAsArrayBuffer(t),r.promise}function pe(e){var t=V.defer(),r=new FileReader;return r.addEventListener("load",function(){t.resolve(r.result)}),r.addEventListener("error",function(){t.reject(r.error)}),r.readAsText(e),t.promise}function fe(e){var t,r,i,n,o={xsi:"http://www.w3.org/2001/XMLSchema-instance"};for(var a in o)o.hasOwnProperty(a)&&(i=RegExp("[< ]"+a+":"),n="xmlns:"+a+"=",i.test(e)&&-1===e.indexOf(n)&&(c(t)||(t=e.substr(0,e.indexOf("<kml")+4),r=e.substr(t.length)),t+=" "+n+'"'+o[a]+'"'));return c(t)&&(e=t+r),e}function me(e){for(var t,r,i,n=e.indexOf("xmlns:"),o=e.indexOf(">",n);-1!==n&&n<o;)t=e.slice(n,e.indexOf('"',n)),r=n,n=e.indexOf(t,n+1),-1!==n?(i=e.indexOf('"',e.indexOf('"',n)+1),e=e.slice(0,n-1)+e.slice(i+1,e.length),n=e.indexOf("xmlns:",r-1)):n=e.indexOf("xmlns:",r+1);return e}function ge(e,t,r){e.getData(new z.TextWriter,function(e){e=fe(e),e=me(e),t.kml=Mt.parseFromString(e,"application/xml"),r.resolve()})}function _e(e,t,r){var i=u(Ot.detectFromFilename(e.filename),"application/octet-stream");e.getData(new z.Data64URIWriter(i),function(i){t[e.filename]=i,r.resolve()})}function ve(e,t,r,i){for(var n=i.keys,o=new U("."),a=e.querySelectorAll(t),s=0;s<a.length;s++){var l=a[s],u=l.getAttribute(r),c=new U(u).resolve(o).toString(),d=n.indexOf(c);if(-1!==d){var h=n[d];l.setAttribute(r,i[h]),"a"===t&&null===l.getAttribute("download")&&l.setAttribute("download",h)}}}function ye(e,t,r,i){for(var n=e.querySelectorAll(t),o=0;o<n.length;o++){var a=n[o],s=a.getAttribute(r),l=Me(s,i);a.setAttribute(r,l.url)}}function be(e,t,r){var i=Ee(e,"id");i=c(i)&&0!==i.length?i:l(),c(r)&&(i=r+i);var n=t.getById(i);return c(n)&&(i=l(),c(r)&&(i=r+i)),n=t.add(new Y({id:i})),c(n.kml)||(n.addProperty("kml"),n.kml=new It),n}function Ce(e,t){return"absolute"===e||"relativeToGround"===e||"relativeToSeaFloor"===t}function Se(e){if(!c(e))return i.fromDegrees(0,0,0);var t=e.match(/[^\s,\n]+/g);if(!c(t))return i.fromDegrees(0,0,0);var r=parseFloat(t[0]),n=parseFloat(t[1]),o=parseFloat(t[2]);return r=isNaN(r)?0:r,n=isNaN(n)?0:n,o=isNaN(o)?0:o,i.fromDegrees(r,n,o)}function we(e){if(c(e)){var t=e.textContent.match(/[^\s\n]+/g);if(c(t)){for(var r=t.length,i=new Array(r),n=0,o=0;o<r;o++)i[n++]=Se(t[o]);return i}}}function Te(e,t){if(c(e)){var r=e.getAttribute(t);if(null!==r){var i=parseFloat(r);return isNaN(i)?void 0:i}}}function Ee(e,t){if(c(e)){var r=e.getAttribute(t);return null!==r?r:void 0}}function Ae(e,t,r){if(c(e))for(var i=e.childNodes,n=i.length,o=0;o<n;o++){var a=i[o];if(a.localName===t&&-1!==r.indexOf(a.namespaceURI))return a}}function xe(e,t,r){if(c(e)){for(var i=[],n=e.getElementsByTagNameNS("*",t),o=n.length,a=0;a<o;a++){var s=n[a];s.localName===t&&-1!==r.indexOf(s.namespaceURI)&&i.push(s)}return i}}function Pe(e,t,r){if(!c(e))return[];for(var i=[],n=e.childNodes,o=n.length,a=0;a<o;a++){var s=n[a];s.localName===t&&-1!==r.indexOf(s.namespaceURI)&&i.push(s)}return i}function De(e,t,r){var i=Ae(e,t,r);if(c(i)){var n=parseFloat(i.textContent);return isNaN(n)?void 0:n}}function Ie(e,t,r){var i=Ae(e,t,r) +;if(c(i))return i.textContent.trim()}function Oe(e,t,r){var i=Ae(e,t,r);if(c(i)){var n=i.textContent.trim();return"1"===n||/^true$/i.test(n)}}function Me(e,t,r){if(c(e)){var i;if(c(r)){var n=r[e];if(c(n))i=new P({url:n});else{var o=new U(t.getUrlComponent());n=r[new U(e).resolve(o)],c(n)&&(i=new P({url:n}))}}return c(i)||(i=t.getDerivedResource({url:e})),i}}function Re(e,t){if(c(e)&&!/^\s*$/gm.test(e)){"#"===e[0]&&(e=e.substring(1));var r=parseInt(e.substring(0,2),16)/255,i=parseInt(e.substring(2,4),16)/255,n=parseInt(e.substring(4,6),16)/255,o=parseInt(e.substring(6,8),16)/255;return t?(o>0?Wt.maximumRed=o:Wt.red=0,n>0?Wt.maximumGreen=n:Wt.green=0,i>0?Wt.maximumBlue=i:Wt.blue=0,Wt.alpha=r,s.fromRandom(Wt)):new s(o,n,i,r)}}function Le(e,t,r){var i=Ie(e,t,r);if(c(i))return Re(i,"random"===Ie(e,"colorMode",r))}function Ne(e){var t=Ae(e,"TimeStamp",Gt.kmlgx),r=Ie(t,"when",Gt.kmlgx);if(c(t)&&c(r)&&0!==r.length){var i=y.fromIso8601(r),n=new O;return n.addInterval(new I({start:i,stop:v.MAXIMUM_VALUE})),n}}function ke(e){var t=Ae(e,"TimeSpan",Gt.kmlgx);if(c(t)){var r,i=Ae(t,"begin",Gt.kmlgx),n=c(i)?y.fromIso8601(i.textContent):void 0,o=Ae(t,"end",Gt.kmlgx),a=c(o)?y.fromIso8601(o.textContent):void 0;if(c(n)&&c(a)){if(y.lessThan(a,n)){var s=n;n=a,a=s}r=new O,r.addInterval(new I({start:n,stop:a}))}else c(n)?(r=new O,r.addInterval(new I({start:n,stop:v.MAXIMUM_VALUE}))):c(a)&&(r=new O,r.addInterval(new I({start:v.MINIMUM_VALUE,stop:a})));return r}}function Fe(){var e=new G;return e.width=Lt,e.height=Lt,e.scaleByDistance=new C(Nt,kt,Ft,Bt),e.pixelOffsetScaleByDistance=new C(Nt,kt,Ft,Bt),e}function Be(){var e=new J;return e.outline=!0,e.outlineColor=s.WHITE,e}function Ue(){var e=new Z;return e.translucencyByDistance=new C(3e6,1,5e6,0),e.pixelOffset=new r(17,0),e.horizontalOrigin=N.LEFT,e.font="16px sans-serif",e.style=k.FILL_AND_OUTLINE,e}function Ve(e,t,r,i,n){var o=Ie(e,"href",Gt.kml);if(c(o)&&0!==o.length){if(0===o.indexOf("root://icons/palette-")){var a=o.charAt(21),s=u(De(e,"x",Gt.gx),0),l=u(De(e,"y",Gt.gx),0);s=Math.min(s/32,7),l=7-Math.min(l/32,7);o="https://maps.google.com/mapfiles/kml/pal"+a+"/icon"+(8*l+s)+".png"}var d=Me(o,r,i);if(n){var h=Ie(e,"refreshMode",Gt.kml),p=Ie(e,"viewRefreshMode",Gt.kml);"onInterval"===h||"onExpire"===h?w("kml-refreshMode-"+h,"KML - Unsupported Icon refreshMode: "+h):"onStop"!==p&&"onRegion"!==p||w("kml-refreshMode-"+p,"KML - Unsupported Icon viewRefreshMode: "+p);var f=u(Ie(e,"viewBoundScale",Gt.kml),1),m="onStop"===p?"BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]":"",g=u(Ie(e,"viewFormat",Gt.kml),m),_=Ie(e,"httpQuery",Gt.kml);return c(g)&&d.addQueryParameters(A(bt(g))),c(_)&&d.addQueryParameters(A(bt(_))),Ct(d,t._camera,t._canvas,f,t._lastCameraView.bbox),d}return d}}function ze(e,n,o,a,s){var l=De(n,"scale",Gt.kml),d=De(n,"heading",Gt.kml),h=Le(n,"color",Gt.kml),p=Ae(n,"Icon",Gt.kml),f=Ve(p,e,a,s,!1);c(p)&&!c(f)&&(f=!1);var m=De(p,"x",Gt.gx),g=De(p,"y",Gt.gx),_=De(p,"w",Gt.gx),v=De(p,"h",Gt.gx),y=Ae(n,"hotSpot",Gt.kml),C=Te(y,"x"),S=Te(y,"y"),w=Ee(y,"xunits"),T=Ee(y,"yunits"),E=o.billboard;c(E)||(E=Fe(),o.billboard=E),E.image=f,E.scale=l,E.color=h,(c(m)||c(g)||c(_)||c(v))&&(E.imageSubRegion=new t(m,g,_,v)),c(d)&&0!==d&&(E.rotation=b.toRadians(-d),E.alignedAxis=i.UNIT_Z),l=u(l,1);var A,x;c(C)&&("pixels"===w?A=-C*l:"insetPixels"===w?A=(C-Lt)*l:"fraction"===w&&(A=-C*Lt*l),A+=.5*Lt*l),c(S)&&("pixels"===T?x=S*l:"insetPixels"===T?x=(-S+Lt)*l:"fraction"===T&&(x=S*Lt*l),x-=.5*Lt*l),(c(A)||c(x))&&(E.pixelOffset=new r(A,x))}function Ge(e,t,r,i,n){for(var o=0,a=t.childNodes.length;o<a;o++){var l=t.childNodes.item(o);if("IconStyle"===l.localName)ze(e,l,r,i,n);else if("LabelStyle"===l.localName){var d=r.label;c(d)||(d=Ue(),r.label=d),d.scale=u(De(l,"scale",Gt.kml),d.scale),d.fillColor=u(Le(l,"color",Gt.kml),d.fillColor),d.text=r.name}else if("LineStyle"===l.localName){var h=r.polyline;c(h)||(h=new $,r.polyline=h),h.width=De(l,"width",Gt.kml),h.material=Le(l,"color",Gt.kml),c(Le(l,"outerColor",Gt.gx))&&w("kml-gx:outerColor","KML - gx:outerColor is not supported in a LineStyle"),c(De(l,"outerWidth",Gt.gx))&&w("kml-gx:outerWidth","KML - gx:outerWidth is not supported in a LineStyle"),c(De(l,"physicalWidth",Gt.gx))&&w("kml-gx:physicalWidth","KML - gx:physicalWidth is not supported in a LineStyle"),c(Oe(l,"labelVisibility",Gt.gx))&&w("kml-gx:labelVisibility","KML - gx:labelVisibility is not supported in a LineStyle")}else if("PolyStyle"===l.localName){var p=r.polygon;c(p)||(p=Be(),r.polygon=p),p.material=u(Le(l,"color",Gt.kml),p.material),p.fill=u(Oe(l,"fill",Gt.kml),p.fill),p.outline=u(Oe(l,"outline",Gt.kml),p.outline)}else if("BalloonStyle"===l.localName){var f=u(Re(Ie(l,"bgColor",Gt.kml)),s.WHITE),m=u(Re(Ie(l,"textColor",Gt.kml)),s.BLACK),g=Ie(l,"text",Gt.kml);r.addProperty("balloonStyle"),r.balloonStyle={bgColor:f,textColor:m,text:g}}else if("ListStyle"===l.localName){var _=Ie(l,"listItemType",Gt.kml);"radioFolder"!==_&&"checkOffOnly"!==_||w("kml-listStyle-"+_,"KML - Unsupported ListStyle with listItemType: "+_)}}}function We(e,t,r,i,n){for(var o,a=new Y,s=-1,l=t.childNodes,u=l.length,d=0;d<u;d++){var h=l[d];"Style"!==h.localName&&"StyleMap"!==h.localName||(s=d)}if(-1!==s){var p=l[s];if("Style"===p.localName)Ge(e,p,a,i,n);else for(var f=Pe(p,"Pair",Gt.kml),m=0;m<f.length;m++){var g=f[m],_=Ie(g,"key",Gt.kml);if("normal"===_){var v=Ie(g,"styleUrl",Gt.kml);if(c(v))o=r.getById(v),c(o)||(o=r.getById("#"+v)),c(o)&&a.merge(o);else{var y=Ae(g,"Style",Gt.kml);Ge(e,y,a,i,n)}}else w("kml-styleMap-"+_,"KML - Unsupported StyleMap key: "+_)}}var b=Ie(t,"styleUrl",Gt.kml);if(c(b)){var C=b;if("#"!==b[0]&&-1!==b.indexOf("#")){var S=b.split("#"),T=S[0];C=i.getDerivedResource({url:T}).getUrlComponent()+"#"+S[1]}o=r.getById(C),c(o)||(o=r.getById("#"+C)),c(o)&&a.merge(o)}return a}function He(e,t,r){return t.fetchXML().then(function(i){return je(e,i,r,t,!0)})}function je(e,t,r,i,n,o){var a,s,l,u,d=xe(t,"Style",Gt.kml);if(c(d)){var h=d.length;for(a=0;a<h;a++)u=d[a],s=Ee(u,"id"),c(s)&&(s="#"+s,n&&c(i)&&(s=i.getUrlComponent()+s),c(r.getById(s))||(l=new Y({id:s}),r.add(l),Ge(e,u,l,i,o)))}var p=xe(t,"StyleMap",Gt.kml);if(c(p)){var f=p.length;for(a=0;a<f;a++){var m=p[a];if(s=Ee(m,"id"),c(s))for(var g=Pe(m,"Pair",Gt.kml),_=0;_<g.length;_++){var v=g[_],y=Ie(v,"key",Gt.kml);if("normal"===y){if(s="#"+s,n&&c(i)&&(s=i.getUrlComponent()+s),!c(r.getById(s))){l=r.getOrCreateEntity(s);var b=Ie(v,"styleUrl",Gt.kml);if(c(b)){"#"!==b[0]&&(b="#"+b),n&&c(i)&&(b=i.getUrlComponent()+b);var C=r.getById(b);c(C)&&l.merge(C)}else u=Ae(v,"Style",Gt.kml),Ge(e,u,l,i,o)}}else w("kml-styleMap-"+y,"KML - Unsupported StyleMap key: "+y)}}}var S=[],T=t.getElementsByTagName("styleUrl"),E=T.length;for(a=0;a<E;a++){var A=T[a].textContent;if("#"!==A[0]){var x=A.split("#");if(2===x.length){var P=x[0],D=i.getDerivedResource({url:P});S.push(He(e,D,r))}}}return S}function qe(e,t,r){var i=new re(e,t.id,["position"]),n=new ne(t.position);t.polyline=c(r.polyline)?r.polyline.clone():new $,t.polyline.positions=new ee([i,n])}function Ye(e,t){return!c(e)&&!c(t)||"clampToGround"===e?L.CLAMP_TO_GROUND:"relativeToGround"===e?L.RELATIVE_TO_GROUND:"absolute"===e?L.NONE:"clampToSeaFloor"===t?(w("kml-gx:altitudeMode-clampToSeaFloor","KML - <gx:altitudeMode>:clampToSeaFloor is currently not supported, using <kml:altitudeMode>:clampToGround."),L.CLAMP_TO_GROUND):"relativeToSeaFloor"===t?(w("kml-gx:altitudeMode-relativeToSeaFloor","KML - <gx:altitudeMode>:relativeToSeaFloor is currently not supported, using <kml:altitudeMode>:relativeToGround."),L.RELATIVE_TO_GROUND):(c(e)?w("kml-altitudeMode-unknown","KML - Unknown <kml:altitudeMode>:"+e+", using <kml:altitudeMode>:CLAMP_TO_GROUND."):w("kml-gx:altitudeMode-unknown","KML - Unknown <gx:altitudeMode>:"+t+", using <kml:altitudeMode>:CLAMP_TO_GROUND."),L.CLAMP_TO_GROUND)}function Xe(e,t,r){return"relativeToSeaFloor"===r||"absolute"===t||"relativeToGround"===t?e:((c(t)&&"clampToGround"!==t||c(r)&&"clampToSeaFloor"!==r)&&w("kml-altitudeMode-unknown","KML - Unknown altitudeMode: "+u(t,r)),new ne(e))}function Qe(e,t,r){if(c(e)){if("relativeToSeaFloor"===r||"absolute"===t||"relativeToGround"===t)return e;(c(t)&&"clampToGround"!==t||c(r)&&"clampToSeaFloor"!==r)&&w("kml-altitudeMode-unknown","KML - Unknown altitudeMode: "+u(t,r));for(var i=e.length,n=0;n<i;n++){var o=e[n];f.WGS84.scaleToGeodeticSurface(o,o)}return e}}function Ze(e,t,i,n){var o=t.label;c(o)||(o=c(i.label)?i.label.clone():Ue(),t.label=o),o.text=t.name;var a=t.billboard;c(a)||(a=c(i.billboard)?i.billboard.clone():Fe(),t.billboard=a),c(a.image)?a.image.getValue()||(a.image=void 0):a.image=e._pinBuilder.fromColor(s.YELLOW,64);var l=1;c(a.scale)&&(l=a.scale.getValue(),0!==l?o.pixelOffset=new r(16*l+1,0):(o.pixelOffset=void 0,o.horizontalOrigin=void 0)),c(n)&&e._clampToGround&&(a.heightReference=n,o.heightReference=n)}function Ke(e,t){var r=e.path;c(r)||(r=new K,r.leadTime=0,e.path=r);var i=t.polyline;c(i)&&(r.material=i.material,r.width=i.width)}function Je(e,t,r,i,n){var o=Ie(r,"coordinates",Gt.kml),a=Ie(r,"altitudeMode",Gt.kml),s=Ie(r,"altitudeMode",Gt.gx),l=Oe(r,"extrude",Gt.kml),u=Se(o);return i.position=u,Ze(e,i,n,Ye(a,s)),l&&Ce(a,s)&&qe(t,i,n),!0}function $e(e,t,r,i,n){var o=Ae(r,"coordinates",Gt.kml),a=Ie(r,"altitudeMode",Gt.kml),l=Ie(r,"altitudeMode",Gt.gx),d=Oe(r,"extrude",Gt.kml),h=Oe(r,"tessellate",Gt.kml),p=Ce(a,l);c(De(r,"drawOrder",Gt.gx))&&w("kml-gx:drawOrder","KML - gx:drawOrder is not supported in LineStrings");var f=we(o),m=n.polyline;if(p&&d){var g=new ae;i.wall=g,g.positions=f;var _=n.polygon;c(_)&&(g.fill=_.fill,g.material=_.material),g.outline=!0,c(m)?(g.outlineColor=c(m.material)?m.material.color:s.WHITE,g.outlineWidth=m.width):c(_)&&(g.outlineColor=c(_.material)?_.material.color:s.WHITE)}else if(e._clampToGround&&!p&&h){var y=new H;i.corridor=y,y.positions=f,c(m)?(y.material=c(m.material)?m.material.color.getValue(v.MINIMUM_VALUE):s.WHITE,y.width=u(m.width,1)):(y.material=s.WHITE,y.width=1)}else m=c(m)?m.clone():new $,i.polyline=m,m.positions=Qe(f,a,l),h&&!p||(m.followSurface=!1);return!0}function et(e,t,r,i,n){var o=Ae(r,"outerBoundaryIs",Gt.kml),a=Ae(o,"LinearRing",Gt.kml),l=Ae(a,"coordinates",Gt.kml),u=we(l),d=Oe(r,"extrude",Gt.kml),h=Ie(r,"altitudeMode",Gt.kml),p=Ie(r,"altitudeMode",Gt.gx),f=Ce(h,p),m=c(n.polygon)?n.polygon.clone():Be(),g=n.polyline;if(c(g)&&(m.outlineColor=c(g.material)?g.material.color:s.WHITE,m.outlineWidth=g.width),i.polygon=m,f?(m.perPositionHeight=!0,m.extrudedHeight=d?0:void 0):e._clampToGround||(m.height=0),c(u)){for(var _=new E(u),v=Pe(r,"innerBoundaryIs",Gt.kml),y=0;y<v.length;y++){a=Pe(v[y],"LinearRing",Gt.kml);for(var b=0;b<a.length;b++)l=Ae(a[b],"coordinates",Gt.kml),u=we(l),c(u)&&_.holes.push(new E(u))}m.hierarchy=_}return!0}function tt(e,t,r,i,n){var o=Ie(r,"altitudeMode",Gt.kml),a=Ie(r,"altitudeMode",Gt.gx),s=Pe(r,"coord",Gt.gx),l=Pe(r,"angles",Gt.gx),u=Pe(r,"when",Gt.kml),c=Oe(r,"extrude",Gt.kml),d=Ce(o,a);l.length>0&&w("kml-gx:angles","KML - gx:angles are not supported in gx:Tracks");for(var h=Math.min(s.length,u.length),p=[],f=[],m=0;m<h;m++){var g=Se(s[m].textContent);p.push(g),f.push(y.fromIso8601(u[m].textContent))}var _=new ie;return _.addSamples(f,p),i.position=_,Ze(e,i,n,Ye(o,a)),Ke(i,n),i.availability=new O,u.length>0&&i.availability.addInterval(new I({start:f[0],stop:f[f.length-1]})),d&&c&&qe(t,i,n),!0}function rt(e,t,r,i,n,o,a,s,l){var u=e[0],c=e[e.length-1],d=new ie;d.addSamples(e,t),r.intervals.addInterval(new I({start:u,stop:c,isStartIncluded:l,isStopIncluded:l,data:Xe(d,a,s)})),i.addInterval(new I({start:u,stop:c,isStartIncluded:l,isStopIncluded:l})),n.intervals.addInterval(new I({start:u,stop:c,isStartIncluded:l,isStopIncluded:l,data:o}))}function it(e,t,r,i,n){for(var o,a,s,l=Oe(r,"interpolate",Gt.gx),u=Pe(r,"Track",Gt.gx),d=!1,h=new oe,p=new O,f=new W,m=0,g=u.length;m<g;m++){var _=u[m],v=Pe(_,"when",Gt.kml),b=Pe(_,"coord",Gt.gx),C=Ie(_,"altitudeMode",Gt.kml),S=Ie(_,"altitudeMode",Gt.gx),w=Ce(C,S),T=Oe(_,"extrude",Gt.kml),E=Math.min(b.length,v.length),A=[];o=[];for(var x=0;x<E;x++){var P=Se(b[x].textContent);A.push(P),o.push(y.fromIso8601(v[x].textContent))}l&&(c(a)&&rt([a,o[0]],[s,A[0]],f,p,h,!1,"absolute",void 0,!1),a=o[E-1],s=A[A.length-1]),rt(o,A,f,p,h,w&&T,C,S,!0),d=d||w&&T}return i.availability=p,i.position=f,Ze(e,i,n),Ke(i,n),d&&(qe(t,i,n),i.polyline.show=h),!0}function nt(e,t,r,i,n,o){for(var a=r.childNodes,s=!1,l=0,u=a.length;l<u;l++){var d=a.item(l),h=Ht[d.localName];if(c(h)){var p=be(d,t,o);p.parent=i,p.name=i.name,p.availability=i.availability,p.description=i.description,p.kml=i.kml,h(e,t,d,p,n)&&(s=!0)}}return s}function ot(e,t,r,i,n){return w("kml-unsupportedGeometry","KML - Unsupported geometry: "+r.localName),!1}function at(e,t){var r=Ae(e,"ExtendedData",Gt.kml);if(c(r)){c(Ae(r,"SchemaData",Gt.kml))&&w("kml-schemaData","KML - SchemaData is unsupported"),c(Ee(r,"xmlns:prefix"))&&w("kml-extendedData","KML - ExtendedData with xmlns:prefix is unsupported");var i={},n=Pe(r,"Data",Gt.kml);if(c(n))for(var o=n.length,a=0;a<o;a++){var s=n[a],l=Ee(s,"name");c(l)&&(i[l]={displayName:Ie(s,"displayName",Gt.kml),value:Ie(s,"value",Gt.kml)})}t.kml.extendedData=i}}function st(e,t,r,i,n){var o,a,l,d=t.kml,h=d.extendedData,p=Ie(e,"description",Gt.kml),f=u(t.balloonStyle,r.balloonStyle),m=s.WHITE,g=s.BLACK,_=p;c(f)&&(m=u(f.bgColor,s.WHITE),g=u(f.textColor,s.BLACK),_=u(f.text,p));var v;if(c(_)){if(_=_.replace("$[name]",u(t.name,"")),_=_.replace("$[description]",u(p,"")),_=_.replace("$[address]",u(d.address,"")),_=_.replace("$[Snippet]",u(d.snippet,"")),_=_.replace("$[id]",t.id),_=_.replace("$[geDirections]",""),c(h)){var y=_.match(/\$\[.+?\]/g);if(null!==y)for(o=0;o<y.length;o++){var b=y[o],C=b.substr(2,b.length-3),S=/\/displayName$/.test(C);C=C.replace(/\/displayName$/,""),v=h[C],c(v)&&(v=S?v.displayName:v.value),c(v)&&(_=_.replace(b,u(v,"")))}}}else if(c(h)&&(l=Object.keys(h),l.length>0)){for(_='<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>',o=0;o<l.length;o++)a=l[o],v=h[a],_+="<tr><th>"+u(v.displayName,a)+"</th><td>"+u(v.value,"")+"</td></tr>";_+="</tbody></table>"}if(c(_)){_=Rt.link(_),jt.innerHTML=_;var w=jt.querySelectorAll("a");for(o=0;o<w.length;o++)w[o].setAttribute("target","_blank");c(i)&&i.keys.length>1&&(ve(jt,"a","href",i),ve(jt,"img","src",i)),ye(jt,"a","href",n),ye(jt,"img","src",n);var T='<div class="cesium-infoBox-description-lighter" style="';T+="overflow:auto;",T+="word-wrap:break-word;",T+="background-color:"+m.toCssColorString()+";",T+="color:"+g.toCssColorString()+";",T+='">',T+=jt.innerHTML+"</div>",jt.innerHTML="",t.description=T}}function lt(e,t,r,i,n,o,a,s,l){function d(e){return!e||e.show&&d(e.parent)}var h=be(r,i,l),p=h.kml,f=We(e,r,n,o,a),m=Ie(r,"name",Gt.kml);h.name=m,h.parent=t;var g=ke(r);c(g)||(g=Ne(r)),h.availability=g,Pt(h);var _=Oe(r,"visibility",Gt.kml);h.show=d(t)&&u(_,!0);var v=Ae(r,"author",Gt.atom),y=p.author;y.name=Ie(v,"name",Gt.atom),y.uri=Ie(v,"uri",Gt.atom),y.email=Ie(v,"email",Gt.atom);var b=Ae(r,"link",Gt.atom),C=p.link;return C.href=Ee(b,"href"),C.hreflang=Ee(b,"hreflang"),C.rel=Ee(b,"rel"),C.type=Ee(b,"type"),C.title=Ee(b,"title"),C.length=Ee(b,"length"),p.address=Ie(r,"address",Gt.kml),p.phoneNumber=Ie(r,"phoneNumber",Gt.kml),p.snippet=Ie(r,"Snippet",Gt.kml),at(r,h),st(r,h,f,a,o),_t(r,h),gt(r,h),c(Ae(r,"Region",Gt.kml))&&w("kml-region","KML - Placemark Regions are unsupported"),{entity:h,styleEntity:f}}function ut(e,t,r,i,n,o,a,s,l){for(var u=Object.keys(qt),c=u.length,d=0;d<c;d++)for(var h=u[d],p=qt[h],f=r.childNodes,m=f.length,g=0;g<m;g++){var _=f[g];_.localName!==h||-1===Gt.kml.indexOf(_.namespaceURI)&&-1===Gt.gx.indexOf(_.namespaceURI)||p(e,t,_,i,n,o,a,s,l)}}function ct(e,t,r,i,n,o,a,s,l){ut(e,lt(e,t,r,i,n,o,a,s,l).entity,r,i,n,o,a,s,l)}function dt(e,t,r,i,n,o,a,s,l){for(var u=lt(e,t,r,i,n,o,a,s,l),d=u.entity,h=u.styleEntity,p=!1,f=r.childNodes,m=0,g=f.length;m<g&&!p;m++){var _=f.item(m),v=Ht[_.localName];c(v)&&(v(e,i,_,d,h,d.id),p=!0)}p||(d.merge(h),Ze(e,d,h))}function ht(e,t,r,i,n,o,a,s,l){var u=Ie(r,"name",Gt.kml),d=Ee(r,"id"),h=new ue(u,d),p=Ae(r,"Playlist",Gt.gx);if(p)for(var f=p.childNodes,m=0;m<f.length;m++){var g=f[m];if(g.localName){var _=Yt[g.localName];_?_(h,g):console.log("Unknown KML Tour playlist entry type "+g.localName)}}c(e.kmlTours)||(e.kmlTours=[]),e.kmlTours.push(h)}function pt(e,t){w("KML Tour unsupported node "+t.localName)}function ft(e,t){var r=De(t,"duration",Gt.gx);e.addPlaylistEntry(new de(r))}function mt(e,t){var r=De(t,"duration",Gt.gx),i=Ie(t,"flyToMode",Gt.gx),n={kml:{}};_t(t,n),gt(t,n);var o=n.kml.lookAt||n.kml.camera,a=new ce(r,i,o);e.addPlaylistEntry(a)}function gt(e,t){var r=Ae(e,"Camera",Gt.kml);if(c(r)){var n=u(De(r,"longitude",Gt.kml),0),o=u(De(r,"latitude",Gt.kml),0),a=u(De(r,"altitude",Gt.kml),0),s=u(De(r,"heading",Gt.kml),0),l=u(De(r,"tilt",Gt.kml),0),d=u(De(r,"roll",Gt.kml),0),h=i.fromDegrees(n,o,a),p=M.fromDegrees(s,l-90,d);t.kml.camera=new le(h,p)}}function _t(e,t){var r=Ae(e,"LookAt",Gt.kml);if(c(r)){var n=u(De(r,"longitude",Gt.kml),0),o=u(De(r,"latitude",Gt.kml),0),a=u(De(r,"altitude",Gt.kml),0),s=De(r,"heading",Gt.kml),l=De(r,"tilt",Gt.kml),d=u(De(r,"range",Gt.kml),0);l=b.toRadians(u(l,0)),s=b.toRadians(u(s,0));var h=new R(s,l-b.PI_OVER_TWO,d),p=i.fromDegrees(n,o,a);t.kml.lookAt=new se(p,h)}}function vt(e,t,r,i,n,o,a,s,l){var u,d=lt(e,t,r,i,n,o,a,s,l),h=d.entity,p=!1,f=we(Ae(r,"LatLonQuad",Gt.gx));if(c(f))u=Be(),u.hierarchy=new E(f),h.polygon=u,p=!0;else{u=new te,h.rectangle=u;var m=Ae(r,"LatLonBox",Gt.kml);if(c(m)){var g=De(m,"west",Gt.kml),_=De(m,"south",Gt.kml),v=De(m,"east",Gt.kml),y=De(m,"north",Gt.kml);c(g)&&(g=b.negativePiToPi(b.toRadians(g))),c(_)&&(_=b.clampToLatitudeRange(b.toRadians(_))),c(v)&&(v=b.negativePiToPi(b.toRadians(v))),c(y)&&(y=b.clampToLatitudeRange(b.toRadians(y))),u.coordinates=new x(g,_,v,y);var C=De(m,"rotation",Gt.kml);if(c(C)){var S=b.toRadians(C);u.rotation=S,u.stRotation=S}}}var T=Ae(r,"Icon",Gt.kml),A=Ve(T,e,o,a,!0);if(c(A)){p&&w("kml-gx:LatLonQuad","KML - gx:LatLonQuad Icon does not support texture projection.");var P=De(T,"x",Gt.gx),D=De(T,"y",Gt.gx),I=De(T,"w",Gt.gx),O=De(T,"h",Gt.gx);(c(P)||c(D)||c(I)||c(O))&&w("kml-groundOverlay-xywh","KML - gx:x, gx:y, gx:w, gx:h aren't supported for GroundOverlays"),u.material=A,u.material.color=Le(r,"color",Gt.kml),u.material.transparent=!0}else u.material=Le(r,"color",Gt.kml);var M=Ie(r,"altitudeMode",Gt.kml);c(M)?"absolute"===M?u.height=De(r,"altitude",Gt.kml):"clampToGround"!==M&&w("kml-altitudeMode-unknown","KML - Unknown altitudeMode: "+M):(M=Ie(r,"altitudeMode",Gt.gx),"relativeToSeaFloor"===M?(w("kml-altitudeMode-relativeToSeaFloor","KML - altitudeMode relativeToSeaFloor is currently not supported, treating as absolute."),u.height=De(r,"altitude",Gt.kml)):"clampToSeaFloor"===M?w("kml-altitudeMode-clampToSeaFloor","KML - altitudeMode clampToSeaFloor is currently not supported, treating as clampToGround."):c(M)&&w("kml-altitudeMode-unknown","KML - Unknown altitudeMode: "+M))}function yt(e,t,r,i,n,o,a,s,l){e._unsupportedNode.raiseEvent(e,t,r,i,n,o,a),w("kml-unsupportedFeature-"+r.nodeName,"KML - Unsupported feature: "+r.nodeName)}function bt(e){if(!c(e)||0===e.length)return"";var t=e[0];return"&"!==t&&"?"!==t||(e=e.substring(1)),e}function Ct(e,t,r,n,o){function a(e){return e<-b.PI_OVER_TWO?-b.PI_OVER_TWO:e>b.PI_OVER_TWO?b.PI_OVER_TWO:e}function s(e){return e>b.PI?e-b.TWO_PI:e<-b.PI?e+b.TWO_PI:e}var l=S(e.queryParameters);if(l=l.replace(/%5B/g,"[").replace(/%5D/g,"]"),c(t)&&t._mode!==F.MORPHING){var d,h,p=f.WGS84;if(o=u(o,Qt),c(r)&&(Kt.x=.5*r.clientWidth,Kt.y=.5*r.clientHeight,d=t.pickEllipsoid(Kt,p,Jt)),c(d)?h=p.cartesianToCartographic(d,Zt):(h=x.center(o,Zt),d=p.cartographicToCartesian(h)),c(n)&&!b.equalsEpsilon(n,1,b.EPSILON9)){var m=o.width*n*.5,g=o.height*n*.5;o=new x(s(h.longitude-m),a(h.latitude-g),s(h.longitude+m),a(h.latitude+g))}l=l.replace("[bboxWest]",b.toDegrees(o.west).toString()),l=l.replace("[bboxSouth]",b.toDegrees(o.south).toString()),l=l.replace("[bboxEast]",b.toDegrees(o.east).toString()),l=l.replace("[bboxNorth]",b.toDegrees(o.north).toString());var _=b.toDegrees(h.longitude).toString(),v=b.toDegrees(h.latitude).toString();l=l.replace("[lookatLon]",_),l=l.replace("[lookatLat]",v),l=l.replace("[lookatTilt]",b.toDegrees(t.pitch).toString()),l=l.replace("[lookatHeading]",b.toDegrees(t.heading).toString()),l=l.replace("[lookatRange]",i.distance(t.positionWC,d)),l=l.replace("[lookatTerrainLon]",_),l=l.replace("[lookatTerrainLat]",v),l=l.replace("[lookatTerrainAlt]",h.height.toString()),p.cartesianToCartographic(t.positionWC,Zt),l=l.replace("[cameraLon]",b.toDegrees(Zt.longitude).toString()),l=l.replace("[cameraLat]",b.toDegrees(Zt.latitude).toString()),l=l.replace("[cameraAlt]",b.toDegrees(Zt.height).toString());var y=t.frustum,C=y.aspectRatio,w="",T="";if(c(C)){var E=b.toDegrees(y.fov);C>1?(w=E,T=E/C):(T=E,w=E*C)}l=l.replace("[horizFov]",w.toString()),l=l.replace("[vertFov]",T.toString())}else l=l.replace("[bboxWest]","-180"),l=l.replace("[bboxSouth]","-90"),l=l.replace("[bboxEast]","180"),l=l.replace("[bboxNorth]","90"),l=l.replace("[lookatLon]",""),l=l.replace("[lookatLat]",""),l=l.replace("[lookatRange]",""),l=l.replace("[lookatTilt]",""),l=l.replace("[lookatHeading]",""),l=l.replace("[lookatTerrainLon]",""),l=l.replace("[lookatTerrainLat]",""),l=l.replace("[lookatTerrainAlt]",""),l=l.replace("[cameraLon]",""),l=l.replace("[cameraLat]",""),l=l.replace("[cameraAlt]",""),l=l.replace("[horizFov]",""),l=l.replace("[vertFov]","");c(r)?(l=l.replace("[horizPixels]",r.clientWidth),l=l.replace("[vertPixels]",r.clientHeight)):(l=l.replace("[horizPixels]",""),l=l.replace("[vertPixels]","")),l=l.replace("[terrainEnabled]","1"),l=l.replace("[clientVersion]","1"),l=l.replace("[kmlVersion]","2.2"),l=l.replace("[clientName]","Cesium"),l=l.replace("[language]","English"),e.addQueryParameters(A(l))}function St(e,t,r,i,n,o,a,s,d){var h=lt(e,t,r,i,n,o,a,s,d),p=h.entity,f=Ae(r,"Link",Gt.kml);if(c(f)||(f=Ae(r,"Url",Gt.kml)),c(f)){var m,g,_=Ie(f,"href",Gt.kml);if(c(_)){var v=_;if(_=Me(_,o,a),/^data:/.test(_.getUrlComponent()))/\.kmz/i.test(o.getUrlComponent())||(v=o.getDerivedResource({url:v}));else{v=_.clone(),m=Ie(f,"viewRefreshMode",Gt.kml),g=u(Ie(f,"viewBoundScale",Gt.kml),1);var b="onStop"===m?"BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]":"",C=u(Ie(f,"viewFormat",Gt.kml),b),S=Ie(f,"httpQuery",Gt.kml);c(C)&&_.addQueryParameters(A(bt(C))),c(S)&&_.addQueryParameters(A(bt(S))),Ct(_,e._camera,e._canvas,g,e._lastCameraView.bbox)}var T={sourceUri:v,uriResolver:a,context:p.id},E=new Q,x=At(e,E,_,T).then(function(t){var r=e._entityCollection,i=E.values;r.suspendEvents();for(var n=0;n<i.length;n++){var o=i[n];c(o.parent)||(o.parent=p,Pt(o)),r.add(o)}r.resumeEvents();var a=Ie(f,"refreshMode",Gt.kml),s=u(De(f,"refreshInterval",Gt.kml),0);if("onInterval"===a&&s>0||"onExpire"===a||"onStop"===m){var d=Ae(t,"NetworkLinkControl",Gt.kml),h=c(d),v=y.now(),b={id:l(),href:_,cookie:{},lastUpdated:v,updating:!1,entity:p,viewBoundScale:g,needsUpdate:!1,cameraUpdateTime:v},C=0;if(h&&(b.cookie=A(u(Ie(d,"cookie",Gt.kml),"")),C=u(De(d,"minRefreshPeriod",Gt.kml),0)),"onInterval"===a)h&&(s=Math.max(C,s)),b.refreshMode=Xt.INTERVAL,b.time=s;else if("onExpire"===a){var S;if(h&&(S=Ie(d,"expires",Gt.kml)),c(S))try{var T=y.fromIso8601(S),x=y.secondsDifference(T,v);x>0&&x<C&&y.addSeconds(v,C,T),b.refreshMode=Xt.EXPIRE,b.time=T}catch(e){w("kml-refreshMode-onInterval-onExpire","KML - NetworkLinkControl expires is not a valid date")}else w("kml-refreshMode-onExpire","KML - refreshMode of onExpire requires the NetworkLinkControl to have an expires element")}else e._camera?(b.refreshMode=Xt.STOP,b.time=u(De(f,"viewRefreshTime",Gt.kml),0)):w("kml-refrehMode-onStop-noCamera","A NetworkLink with viewRefreshMode=onStop requires a camera be passed in when creating the KmlDataSource");c(b.refreshMode)&&e._networkLinks.set(b.id,b)}else"onRegion"===m&&w("kml-refrehMode-onRegion","KML - Unsupported viewRefreshMode: onRegion")}).otherwise(function(t){w("An error occured during loading "+_.url),e._error.raiseEvent(e,t)});s.push(x)}}}function wt(e,t,r,i,n,o,a,s,l){var u=qt[t.localName];c(u)?u(e,r,t,i,n,o,a,s,l):yt(e,r,t,i,n,o,a,s,l)}function Tt(e,t,r,i,n,o){t.removeAll();var a=[],s=r.documentElement,l="Document"===s.localName?s:Ae(s,"Document",Gt.kml),u=Ie(l,"name",Gt.kml);c(u)||(u=_(i.getUrlComponent())),c(e._name)||(e._name=u);var d=new Q(e);return V.all(je(e,r,d,i,!1,n)).then(function(){var s=r.documentElement;if("kml"===s.localName)for(var l=s.childNodes,u=0;u<l.length;u++){var h=l[u];if(c(qt[h.localName])){s=h;break}}return t.suspendEvents(),wt(e,s,void 0,t,d,i,n,a,o),t.resumeEvents(),V.all(a).then(function(){return r.documentElement})})}function Et(e,t,r,i){var n=V.defer();return z.createReader(new z.BlobReader(r),function(r){r.getEntries(function(o){for(var a,s,l=[],u={},d=0;d<o.length;d++){var h=o[d];if(!h.directory){var p=V.defer();l.push(p.promise),/\.kml$/i.test(h.filename)?c(a)&&/\//i.test(h.filename)?_e(h,u,p):(c(a)&&_e(a,u,s),a=h,s=p):_e(h,u,p)}}c(a)&&ge(a,u,s),V.all(l).then(function(){return r.close(),c(u.kml)?(u.keys=Object.keys(u),Tt(e,t,u.kml,i,u)):void n.reject(new D("KMZ file does not contain a KML document."))}).then(n.resolve).otherwise(n.reject)})},function(e){n.reject(e)}),n.promise}function At(e,t,r,i){i=u(i,u.EMPTY_OBJECT);var n=i.sourceUri,o=i.uriResolver,a=i.context,s=i.query;c(i.query)&&h("KmlDataSource.query","The options.query parameter has been deprecated. Specify data or options.sourceUri as a Resource instance and add query parameters there."),c(e._proxy)&&h("KmlDataSource.proxy","The options.proxy parameter has been deprecated. Specify data or options.sourceUri as a Resource instance and set the proxy property there.");var l=r;return"string"==typeof r||r instanceof P?(r=P.createIfNeeded(r,{proxy:e._proxy,queryParameters:s}),l=r.fetchBlob(),n=u(n,r.clone())):n=u(n,P.DEFAULT.clone()),n=P.createIfNeeded(n),c(e._proxy)&&(n.proxy=e._proxy),c(s)&&n.addQueryParameters(s),V(l).then(function(r){return r instanceof Blob?he(r).then(function(i){return i?Et(e,t,r,n):pe(r).then(function(r){r=fe(r),r=me(r);var i,s;try{i=Mt.parseFromString(r,"application/xml")}catch(e){s=e.toString()}if(c(s)||i.body||"parsererror"===i.documentElement.tagName){var l=c(s)?s:i.documentElement.firstChild.nodeValue;throw l||(l=i.body.innerText),new D(l)}return Tt(e,t,i,n,o,a)})}):Tt(e,t,r,n,o,a)}).otherwise(function(t){return e._error.raiseEvent(e,t),console.log(t),V.reject(t)})}function xt(t){t=u(t,{});var r=t.camera,n=t.canvas;this._changed=new m,this._error=new m,this._loading=new m,this._refresh=new m,this._unsupportedNode=new m,this._clock=void 0,this._entityCollection=new Q(this),this._name=void 0,this._isLoading=!1,this._proxy=t.proxy,this._pinBuilder=new T,this._networkLinks=new e,this._entityCluster=new X,this._canvas=n,this._camera=r,this._lastCameraView={position:c(r)?i.clone(r.positionWC):void 0,direction:c(r)?i.clone(r.directionWC):void 0,up:c(r)?i.clone(r.upWC):void 0,bbox:c(r)?r.computeViewRectangle():x.clone(x.MAX_VALUE)}}function Pt(e){var t=e.parent;if(c(t)){var r=t.availability;if(c(r)){var i=e.availability;c(i)?i.intersect(r):e.availability=r}}}function Dt(e,t,r,i,n){return function(o){function a(e){C.remove(e);for(var t=e._children,r=t.length,i=0;i<r;++i)a(t[i])}if(i.contains(t.id)){var s=!1,l=Ae(o,"NetworkLinkControl",Gt.kml),d=c(l),h=0;if(d){if(c(Ae(l,"Update",Gt.kml)))return w("kml-networkLinkControl-update","KML - NetworkLinkControl updates aren't supported."),t.updating=!1,void i.remove(t.id);t.cookie=A(u(Ie(l,"cookie",Gt.kml),"")),h=u(De(l,"minRefreshPeriod",Gt.kml),0)}var p=y.now(),f=t.refreshMode;if(f===Xt.INTERVAL)c(l)&&(t.time=Math.max(h,t.time));else if(f===Xt.EXPIRE){var m;if(c(l)&&(m=Ie(l,"expires",Gt.kml)),c(m))try{var g=y.fromIso8601(m),_=y.secondsDifference(g,p);_>0&&_<h&&y.addSeconds(p,h,g),t.time=g}catch(e){w("kml-networkLinkControl-expires","KML - NetworkLinkControl expires is not a valid date"),s=!0}else w("kml-refreshMode-onExpire","KML - refreshMode of onExpire requires the NetworkLinkControl to have an expires element"),s=!0}var b=t.entity,C=e._entityCollection,S=r.values;C.suspendEvents();var T,E=C.values.slice();for(T=0;T<E.length;++T){var x=E[T];x.parent===b&&(x.parent=void 0,a(x))}for(C.resumeEvents(),C.suspendEvents(),T=0;T<S.length;T++){var P=S[T];c(P.parent)||(P.parent=b,Pt(P)),C.add(P)}C.resumeEvents(),s?i.remove(t.id):t.lastUpdated=p;var D=C.computeAvailability(),I=D.start,O=D.stop,M=y.equals(I,v.MINIMUM_VALUE),R=y.equals(O,v.MAXIMUM_VALUE);if(!M||!R){var L=e._clock;L.startTime===I&&L.stopTime===O||(L.startTime=I,L.stopTime=O,e._changed.raiseEvent(e))}t.updating=!1,t.needsUpdate=!1,e._refresh.raiseEvent(e,n.getUrlComponent(!0))}}}function It(){this.author={name:void 0,uri:void 0,email:void 0},this.link={href:void 0,hreflang:void 0,rel:void 0,type:void 0,title:void 0,length:void 0},this.address=void 0,this.phoneNumber=void 0,this.snippet=void 0,this.extendedData=void 0}if("undefined"==typeof DOMParser)return{};var Ot={avi:"video/x-msvideo",bmp:"image/bmp",bz2:"application/x-bzip2",chm:"application/vnd.ms-htmlhelp",css:"text/css",csv:"text/csv",doc:"application/msword",dvi:"application/x-dvi",eps:"application/postscript",flv:"video/x-flv",gif:"image/gif",gz:"application/x-gzip",htm:"text/html",html:"text/html",ico:"image/vnd.microsoft.icon",jnlp:"application/x-java-jnlp-file",jpeg:"image/jpeg",jpg:"image/jpeg",m3u:"audio/x-mpegurl",m4v:"video/mp4",mathml:"application/mathml+xml",mid:"audio/midi",midi:"audio/midi",mov:"video/quicktime",mp3:"audio/mpeg",mp4:"video/mp4",mp4v:"video/mp4",mpeg:"video/mpeg",mpg:"video/mpeg",odp:"application/vnd.oasis.opendocument.presentation",ods:"application/vnd.oasis.opendocument.spreadsheet",odt:"application/vnd.oasis.opendocument.text",ogg:"application/ogg",pdf:"application/pdf",png:"image/png",pps:"application/vnd.ms-powerpoint",ppt:"application/vnd.ms-powerpoint",ps:"application/postscript",qt:"video/quicktime",rdf:"application/rdf+xml",rss:"application/rss+xml",rtf:"application/rtf",svg:"image/svg+xml",swf:"application/x-shockwave-flash",text:"text/plain",tif:"image/tiff",tiff:"image/tiff",txt:"text/plain",wav:"audio/x-wav",wma:"audio/x-ms-wma",wmv:"video/x-ms-wmv",xml:"application/xml",zip:"application/zip",detectFromFilename:function(e){var t=e.toLowerCase();return t=g(t),Ot[t]}},Mt=new DOMParser,Rt=new B({stripPrefix:!1,twitter:!1,email:!1,replaceFn:function(e,t){if(!t.protocolUrlMatch)return!1}}),Lt=32,Nt=2414016,kt=1,Ft=16093e3,Bt=.1,Ut=[null,void 0,"http://www.opengis.net/kml/2.2","http://earth.google.com/kml/2.2","http://earth.google.com/kml/2.1","http://earth.google.com/kml/2.0"],Vt=["http://www.google.com/kml/ext/2.2"],zt=["http://www.w3.org/2005/Atom"],Gt={kml:Ut,gx:Vt,atom:zt,kmlgx:Ut.concat(Vt)},Wt={},Ht={Point:Je,LineString:$e,LinearRing:$e,Polygon:et,Track:tt,MultiTrack:it,MultiGeometry:nt,Model:ot},jt=document.createElement("div"),qt={Document:ut,Folder:ct,Placemark:dt,NetworkLink:St,GroundOverlay:vt,PhotoOverlay:yt,ScreenOverlay:yt,Tour:ht},Yt={FlyTo:mt,Wait:ft,SoundCue:pt,AnimatedUpdate:pt,TourControl:pt},Xt={INTERVAL:0,EXPIRE:1,STOP:2},Qt=new x,Zt=new n,Kt=new r,Jt=new i;xt.load=function(e,t){return t=u(t,u.EMPTY_OBJECT),new xt(t).load(e,t)},d(xt.prototype,{name:{get:function(){return this._name},set:function(e){this._name!==e&&(this._name=e,this._changed.raiseEvent(this))}},clock:{get:function(){return this._clock}},entities:{get:function(){return this._entityCollection}},isLoading:{get:function(){return this._isLoading}},changedEvent:{get:function(){return this._changed}},errorEvent:{get:function(){return this._error}},loadingEvent:{get:function(){return this._loading}},refreshEvent:{get:function(){return this._refresh}},unsupportedNodeEvent:{get:function(){return this._unsupportedNode}},show:{get:function(){return this._entityCollection.show},set:function(e){this._entityCollection.show=e}},clustering:{get:function(){return this._entityCluster},set:function(e){this._entityCluster=e}}}), +xt.prototype.load=function(e,t){t=u(t,{}),j.setLoading(this,!0);var r=this._name;this._name=void 0,this._clampToGround=u(t.clampToGround,!1);var i=this;return At(this,this._entityCollection,e,t).then(function(){var e,t=i._entityCollection.computeAvailability(),n=t.start,s=t.stop,l=y.equals(n,v.MINIMUM_VALUE),u=y.equals(s,v.MAXIMUM_VALUE);if(!l||!u){var c;l&&(c=new Date,c.setHours(0,0,0,0),n=y.fromDate(c)),u&&(c=new Date,c.setHours(24,0,0,0),s=y.fromDate(c)),e=new q,e.startTime=n,e.stopTime=s,e.currentTime=y.clone(n),e.clockRange=o.LOOP_STOP,e.clockStep=a.SYSTEM_CLOCK_MULTIPLIER,e.multiplier=Math.round(Math.min(Math.max(y.secondsDifference(s,n)/60,1),31556900))}var d=!1;return e!==i._clock&&(i._clock=e,d=!0),r!==i._name&&(d=!0),d&&i._changed.raiseEvent(i),j.setLoading(i,!1),i}).otherwise(function(e){return j.setLoading(i,!1),i._error.raiseEvent(i,e),console.log(e),V.reject(e)})};var $t=new e;return xt.prototype.update=function(t){function r(e){for(var t=e._children,i=t.length,n=0;n<i;++n){var o=t[n];$t.set(o.id,o),r(o)}}var n=this._networkLinks;if(0===n.length)return!0;var o=y.now(),a=this;$t.removeAll();var s=!1,l=this._lastCameraView,u=this._camera;!c(u)||u.positionWC.equalsEpsilon(l.position,b.EPSILON7)&&u.directionWC.equalsEpsilon(l.direction,b.EPSILON7)&&u.upWC.equalsEpsilon(l.up,b.EPSILON7)||(l.position=i.clone(u.positionWC),l.direction=i.clone(u.directionWC),l.up=i.clone(u.upWC),l.bbox=u.computeViewRectangle(),s=!0);var d=new e,h=!1;return n.values.forEach(function(e){var t=e.entity;if(!$t.contains(t.id)){if(!e.updating){var i=!1;if(e.refreshMode===Xt.INTERVAL?y.secondsDifference(o,e.lastUpdated)>e.time&&(i=!0):e.refreshMode===Xt.EXPIRE?y.greaterThan(o,e.time)&&(i=!0):e.refreshMode===Xt.STOP&&(s&&(e.needsUpdate=!0,e.cameraUpdateTime=o),e.needsUpdate&&y.secondsDifference(o,e.cameraUpdateTime)>=e.time&&(i=!0)),i){r(t),e.updating=!0;var n=new Q,u=e.href.clone();u.addQueryParameters(e.cookie),Ct(u,a._camera,a._canvas,e.viewBoundScale,l.bbox),At(a,n,u,{context:t.id}).then(Dt(a,e,n,d,u)).otherwise(function(t){var r="NetworkLink "+e.href+" refresh failed: "+t;console.log(r),a._error.raiseEvent(a,r)}),h=!0}}d.set(e.id,e)}}),h&&(this._networkLinks=d,this._changed.raiseEvent(this)),!0},xt}),define("DataSources/Visualizer",["../Core/DeveloperError"],function(e){"use strict";function t(){e.throwInstantiationError()}return t.prototype.update=e.throwInstantiationError,t.prototype.getBoundingSphere=e.throwInstantiationError,t.prototype.isDestroyed=e.throwInstantiationError,t.prototype.destroy=e.throwInstantiationError,t}),define("Renderer/ClearCommand",["../Core/Color","../Core/defaultValue","../Core/freezeObject"],function(e,t,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.color=e.color,this.depth=e.depth,this.stencil=e.stencil,this.renderState=e.renderState,this.framebuffer=e.framebuffer,this.owner=e.owner,this.pass=e.pass}return i.ALL=r(new i({color:new e(0,0,0,0),depth:1,stencil:0})),i.prototype.execute=function(e,t){e.clear(this,t)},i}),define("Renderer/ComputeCommand",["../Core/defaultValue","./Pass"],function(e,t){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT),this.vertexArray=r.vertexArray,this.fragmentShaderSource=r.fragmentShaderSource,this.shaderProgram=r.shaderProgram,this.uniformMap=r.uniformMap,this.outputTexture=r.outputTexture,this.preExecute=r.preExecute,this.postExecute=r.postExecute,this.persists=e(r.persists,!1),this.pass=t.COMPUTE,this.owner=r.owner}return r.prototype.execute=function(e){e.execute(this)},r}),define("Shaders/ViewportQuadVS",[],function(){"use strict";return"attribute vec4 position;\nattribute vec2 textureCoordinates;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_Position = position;\nv_textureCoordinates = textureCoordinates;\n}\n"});define("Renderer/ComputeEngine",["../Core/BoundingRectangle","../Core/Check","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/PrimitiveType","../Shaders/ViewportQuadVS","./ClearCommand","./DrawCommand","./Framebuffer","./RenderState","./ShaderProgram"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){this._context=e}function f(e,t){return new c({context:e,colorTextures:[t],destroyAttachments:!1})}function m(e,t){return h.fromCache({context:e,vertexShaderSource:s,fragmentShaderSource:t,attributeLocations:{position:0,textureCoordinates:1}})}function g(t,r){return i(_)&&_.viewport.width===t&&_.viewport.height===r||(_=d.fromCache({viewport:new e(0,0,t,r)})),_}var _,v=new u({primitiveType:a.TRIANGLES}),y=new l({color:new r(0,0,0,0)});return p.prototype.execute=function(e){i(e.preExecute)&&e.preExecute(e);var t=e.outputTexture,r=t.width,n=t.height,o=this._context,a=i(e.vertexArray)?e.vertexArray:o.getViewportQuadVertexArray(),s=i(e.shaderProgram)?e.shaderProgram:m(o,e.fragmentShaderSource),l=f(o,t),u=g(r,n),c=e.uniformMap,d=y;d.framebuffer=l,d.renderState=u,d.execute(o);var h=v;h.vertexArray=a,h.renderState=u,h.shaderProgram=s,h.uniformMap=c,h.framebuffer=l,h.execute(o),l.destroy(),e.persists||(s.destroy(),i(e.vertexArray)&&a.destroy()),i(e.postExecute)&&e.postExecute(t)},p.prototype.isDestroyed=function(){return!1},p.prototype.destroy=function(){return n(this)},p}),define("Renderer/PassState",[],function(){"use strict";function e(e){this.context=e,this.framebuffer=void 0,this.blendingEnabled=void 0,this.scissorTest=void 0,this.viewport=void 0}return e}),define("Renderer/RenderbufferFormat",["../Core/freezeObject","../Core/WebGLConstants"],function(e,t){"use strict";var r={RGBA4:t.RGBA4,RGB5_A1:t.RGB5_A1,RGB565:t.RGB565,DEPTH_COMPONENT16:t.DEPTH_COMPONENT16,STENCIL_INDEX8:t.STENCIL_INDEX8,DEPTH_STENCIL:t.DEPTH_STENCIL,validate:function(e){return e===r.RGBA4||e===r.RGB5_A1||e===r.RGB565||e===r.DEPTH_COMPONENT16||e===r.STENCIL_INDEX8||e===r.DEPTH_STENCIL}};return e(r)}),define("Renderer/Renderbuffer",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","./ContextLimits","./RenderbufferFormat"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT);var i=e.context,n=i._gl,o=(a.maximumRenderbufferSize,t(e.format,s.RGBA4)),l=r(e.width)?e.width:n.drawingBufferWidth,u=r(e.height)?e.height:n.drawingBufferHeight;this._gl=n,this._format=o,this._width=l,this._height=u,this._renderbuffer=this._gl.createRenderbuffer(),n.bindRenderbuffer(n.RENDERBUFFER,this._renderbuffer),n.renderbufferStorage(n.RENDERBUFFER,o,l,u),n.bindRenderbuffer(n.RENDERBUFFER,null)}return i(l.prototype,{format:{get:function(){return this._format}},width:{get:function(){return this._width}},height:{get:function(){return this._height}}}),l.prototype._getRenderbuffer=function(){return this._renderbuffer},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._gl.deleteRenderbuffer(this._renderbuffer),n(this)},l}),define("Renderer/PickFramebuffer",["../Core/BoundingRectangle","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","./Framebuffer","./PassState","./Renderbuffer","./RenderbufferFormat","./Texture"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t){var r=new a(t);r.blendingEnabled=!1,r.scissorTest={enabled:!0,rectangle:new e},r.viewport=new e,this._context=t,this._fb=void 0,this._passState=r,this._width=0,this._height=0}c.prototype.begin=function(t){var r=this._context,n=r.drawingBufferWidth,a=r.drawingBufferHeight;return e.clone(t,this._passState.scissorTest.rectangle),i(this._fb)&&this._width===n&&this._height===a||(this._width=n,this._height=a,this._fb=this._fb&&this._fb.destroy(),this._fb=new o({context:r,colorTextures:[new u({context:r,width:n,height:a})],depthStencilRenderbuffer:new s({context:r,format:l.DEPTH_STENCIL})}),this._passState.framebuffer=this._fb),this._passState.viewport.width=n,this._passState.viewport.height=a,this._passState};var d=new t;return c.prototype.end=function(e){for(var n=r(e.width,1),o=r(e.height,1),a=this._context,s=a.readPixels({x:e.x,y:e.y,width:n,height:o,framebuffer:this._fb}),l=Math.max(n,o),u=l*l,c=Math.floor(.5*n),h=Math.floor(.5*o),p=0,f=0,m=0,g=-1,_=0;_<u;++_){if(-c<=p&&p<=c&&-h<=f&&f<=h){var v=4*((h-f)*n+p+c);d.red=t.byteToFloat(s[v]),d.green=t.byteToFloat(s[v+1]),d.blue=t.byteToFloat(s[v+2]),d.alpha=t.byteToFloat(s[v+3]);var y=a.getObjectByPickColor(d);if(i(y))return y}if(p===f||p<0&&-p===f||p>0&&p===1-f){var b=m;m=-g,g=b}p+=m,f+=g}},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return this._fb=this._fb&&this._fb.destroy(),n(this)},c}),define("Renderer/ShaderCache",["../Core/defined","../Core/defineProperties","../Core/destroyObject","./ShaderProgram","./ShaderSource"],function(e,t,r,i,n){"use strict";function o(e){this._context=e,this._shaders={},this._numberOfShaders=0,this._shadersToRelease={}}function a(e,t){for(var r=t.derivedKeywords,i=r.length,n=0;n<i;++n){var o=r[n]+t.keyword;a(e,e._shaders[o])}delete e._shaders[t.keyword],t.shaderProgram.finalDestroy()}return t(o.prototype,{numberOfShaders:{get:function(){return this._numberOfShaders}}}),o.prototype.replaceShaderProgram=function(t){return e(t.shaderProgram)&&t.shaderProgram.destroy(),this.getShaderProgram(t)},o.prototype.getShaderProgram=function(t){var r=t.vertexShaderSource,o=t.fragmentShaderSource,a=t.attributeLocations;"string"==typeof r&&(r=new n({sources:[r]})),"string"==typeof o&&(o=new n({sources:[o]}));var s,l=r.createCombinedVertexShader(this._context),u=o.createCombinedFragmentShader(this._context),c=l+u+JSON.stringify(a);if(e(this._shaders[c]))s=this._shaders[c],delete this._shadersToRelease[c];else{var d=this._context,h=new i({gl:d._gl,logShaderCompilation:d.logShaderCompilation,debugShaders:d.debugShaders,vertexShaderSource:r,vertexShaderText:l,fragmentShaderSource:o,fragmentShaderText:u,attributeLocations:a});s={cache:this,shaderProgram:h,keyword:c,derivedKeywords:[],count:0},h._cachedShader=s,this._shaders[c]=s,++this._numberOfShaders}return++s.count,s.shaderProgram},o.prototype.getDerivedShaderProgram=function(t,r){var i=t._cachedShader,n=r+i.keyword,o=this._shaders[n];if(e(o))return o.shaderProgram},o.prototype.createDerivedShaderProgram=function(e,t,r){var o=e._cachedShader,a=t+o.keyword,s=r.vertexShaderSource,l=r.fragmentShaderSource,u=r.attributeLocations;"string"==typeof s&&(s=new n({sources:[s]})),"string"==typeof l&&(l=new n({sources:[l]}));var c=this._context,d=s.createCombinedVertexShader(c),h=l.createCombinedFragmentShader(c),p=new i({gl:c._gl,logShaderCompilation:c.logShaderCompilation,debugShaders:c.debugShaders,vertexShaderSource:s,vertexShaderText:d,fragmentShaderSource:l,fragmentShaderText:h,attributeLocations:u}),f={cache:this,shaderProgram:p,keyword:a,derivedKeywords:[],count:0};return o.derivedKeywords.push(t),p._cachedShader=f,this._shaders[a]=f,p},o.prototype.destroyReleasedShaderPrograms=function(){var e=this._shadersToRelease;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];a(this,r),--this._numberOfShaders}this._shadersToRelease={}},o.prototype.releaseShaderProgram=function(t){if(e(t)){var r=t._cachedShader;r&&0==--r.count&&(this._shadersToRelease[r.keyword]=r)}},o.prototype.isDestroyed=function(){return!1},o.prototype.destroy=function(){var e=this._shaders;for(var t in e)e.hasOwnProperty(t)&&e[t].shaderProgram.finalDestroy();return r(this)},o}),define("Renderer/UniformState",["./Sampler","../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/EncodedCartesian3","../Core/Math","../Core/Matrix3","../Core/Matrix4","../Core/OrthographicFrustum","../Core/Simon1994PlanetaryPositions","../Core/Transforms","../Scene/SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(){this.globeDepthTexture=void 0,this._viewport=new t,this._viewportCartesian4=new n,this._viewportDirty=!1,this._viewportOrthographicMatrix=p.clone(p.IDENTITY),this._viewportTransformation=p.clone(p.IDENTITY),this._model=p.clone(p.IDENTITY),this._view=p.clone(p.IDENTITY),this._inverseView=p.clone(p.IDENTITY),this._projection=p.clone(p.IDENTITY),this._infiniteProjection=p.clone(p.IDENTITY),this._entireFrustum=new r,this._currentFrustum=new r,this._frustumPlanes=new n,this._frameState=void 0,this._temeToPseudoFixed=h.clone(p.IDENTITY),this._view3DDirty=!0,this._view3D=new p,this._inverseView3DDirty=!0,this._inverseView3D=new p,this._inverseModelDirty=!0,this._inverseModel=new p,this._inverseTransposeModelDirty=!0,this._inverseTransposeModel=new h,this._viewRotation=new h,this._inverseViewRotation=new h,this._viewRotation3D=new h,this._inverseViewRotation3D=new h,this._inverseProjectionDirty=!0,this._inverseProjection=new p,this._modelViewDirty=!0,this._modelView=new p,this._modelView3DDirty=!0,this._modelView3D=new p,this._modelViewRelativeToEyeDirty=!0,this._modelViewRelativeToEye=new p,this._inverseModelViewDirty=!0,this._inverseModelView=new p,this._inverseModelView3DDirty=!0,this._inverseModelView3D=new p,this._viewProjectionDirty=!0,this._viewProjection=new p,this._inverseViewProjectionDirty=!0,this._inverseViewProjection=new p,this._modelViewProjectionDirty=!0,this._modelViewProjection=new p,this._inverseModelViewProjectionDirty=!0,this._inverseModelViewProjection=new p,this._modelViewProjectionRelativeToEyeDirty=!0,this._modelViewProjectionRelativeToEye=new p,this._modelViewInfiniteProjectionDirty=!0,this._modelViewInfiniteProjection=new p,this._normalDirty=!0,this._normal=new h,this._normal3DDirty=!0,this._normal3D=new h,this._inverseNormalDirty=!0,this._inverseNormal=new h,this._inverseNormal3DDirty=!0,this._inverseNormal3D=new h,this._encodedCameraPositionMCDirty=!0,this._encodedCameraPositionMC=new c,this._cameraPosition=new i,this._sunPositionWC=new i,this._sunPositionColumbusView=new i,this._sunDirectionWC=new i,this._sunDirectionEC=new i,this._moonDirectionEC=new i,this._pass=void 0,this._mode=void 0,this._mapProjection=void 0,this._cameraDirection=new i,this._cameraRight=new i,this._cameraUp=new i,this._frustum2DWidth=0,this._eyeHeight2D=new r,this._resolutionScale=1,this._orthographicIn3D=!1,this._backgroundColor=new a,this._brdfLut=new e,this._environmentMap=new e,this._fogDensity=void 0,this._invertClassificationColor=void 0,this._imagerySplitPosition=0,this._pixelSizePerMeter=void 0,this._geometricToleranceOverMeter=void 0,this._minimumDisableDepthTestDistance=void 0}function y(e,t){p.clone(t,e._view),p.getRotation(t,e._viewRotation),e._view3DDirty=!0,e._inverseView3DDirty=!0,e._modelViewDirty=!0,e._modelView3DDirty=!0,e._modelViewRelativeToEyeDirty=!0,e._inverseModelViewDirty=!0,e._inverseModelView3DDirty=!0,e._viewProjectionDirty=!0,e._inverseViewProjectionDirty=!0,e._modelViewProjectionDirty=!0,e._modelViewProjectionRelativeToEyeDirty=!0,e._modelViewInfiniteProjectionDirty=!0,e._normalDirty=!0,e._inverseNormalDirty=!0,e._normal3DDirty=!0,e._inverseNormal3DDirty=!0}function b(e,t){p.clone(t,e._inverseView),p.getRotation(t,e._inverseViewRotation)}function C(e,t){p.clone(t,e._projection),e._inverseProjectionDirty=!0,e._viewProjectionDirty=!0,e._inverseViewProjectionDirty=!0,e._modelViewProjectionDirty=!0,e._modelViewProjectionRelativeToEyeDirty=!0}function S(e,t){p.clone(t,e._infiniteProjection),e._modelViewInfiniteProjectionDirty=!0}function w(e,t){i.clone(t.positionWC,e._cameraPosition),i.clone(t.directionWC,e._cameraDirection),i.clone(t.rightWC,e._cameraRight),i.clone(t.upWC,e._cameraUp),e._encodedCameraPositionMCDirty=!0}function T(e,t){l(g.computeIcrfToFixedMatrix(t.time,q))||(q=g.computeTemeToPseudoFixedMatrix(t.time,q));var r=m.computeSunPositionInEarthInertialFrame(t.time,e._sunPositionWC);h.multiplyByVector(q,r,r),i.normalize(r,e._sunDirectionWC),r=h.multiplyByVector(e.viewRotation3D,r,e._sunDirectionEC),i.normalize(r,r),r=m.computeMoonPositionInEarthInertialFrame(t.time,e._moonDirectionEC),h.multiplyByVector(q,r,r),h.multiplyByVector(e.viewRotation3D,r,r),i.normalize(r,r);var n=t.mapProjection,o=n.ellipsoid,a=o.cartesianToCartographic(e._sunPositionWC,Y);n.project(a,e._sunPositionColumbusView)}function E(e){if(e._viewportDirty){var t=e._viewport;p.computeOrthographicOffCenter(t.x,t.x+t.width,t.y,t.y+t.height,0,1,e._viewportOrthographicMatrix),p.computeViewportTransformation(t,0,1,e._viewportTransformation),e._viewportDirty=!1}}function A(e){e._inverseProjectionDirty&&(e._inverseProjectionDirty=!1,e._mode===_.SCENE2D||e._mode===_.MORPHING||e._orthographicIn3D?p.clone(p.ZERO,e._inverseProjection):p.inverse(e._projection,e._inverseProjection))}function x(e){e._modelViewDirty&&(e._modelViewDirty=!1,p.multiplyTransformation(e._view,e._model,e._modelView))}function P(e){e._modelView3DDirty&&(e._modelView3DDirty=!1,p.multiplyTransformation(e.view3D,e._model,e._modelView3D))}function D(e){e._inverseModelViewDirty&&(e._inverseModelViewDirty=!1,p.inverse(e.modelView,e._inverseModelView))}function I(e){e._inverseModelView3DDirty&&(e._inverseModelView3DDirty=!1,p.inverse(e.modelView3D,e._inverseModelView3D))}function O(e){e._viewProjectionDirty&&(e._viewProjectionDirty=!1,p.multiply(e._projection,e._view,e._viewProjection))}function M(e){e._inverseViewProjectionDirty&&(e._inverseViewProjectionDirty=!1,p.inverse(e.viewProjection,e._inverseViewProjection))}function R(e){e._modelViewProjectionDirty&&(e._modelViewProjectionDirty=!1,p.multiply(e._projection,e.modelView,e._modelViewProjection))}function L(e){if(e._modelViewRelativeToEyeDirty){e._modelViewRelativeToEyeDirty=!1;var t=e.modelView,r=e._modelViewRelativeToEye;r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=0,r[13]=0,r[14]=0,r[15]=t[15]}}function N(e){e._inverseModelViewProjectionDirty&&(e._inverseModelViewProjectionDirty=!1,p.inverse(e.modelViewProjection,e._inverseModelViewProjection))}function k(e){e._modelViewProjectionRelativeToEyeDirty&&(e._modelViewProjectionRelativeToEyeDirty=!1,p.multiply(e._projection,e.modelViewRelativeToEye,e._modelViewProjectionRelativeToEye))}function F(e){e._modelViewInfiniteProjectionDirty&&(e._modelViewInfiniteProjectionDirty=!1,p.multiply(e._infiniteProjection,e.modelView,e._modelViewInfiniteProjection))}function B(e){if(e._normalDirty){e._normalDirty=!1;var t=e._normal;p.getRotation(e.inverseModelView,t),h.transpose(t,t)}}function U(e){if(e._normal3DDirty){e._normal3DDirty=!1;var t=e._normal3D;p.getRotation(e.inverseModelView3D,t),h.transpose(t,t)}}function V(e){e._inverseNormalDirty&&(e._inverseNormalDirty=!1,p.getRotation(e.inverseModelView,e._inverseNormal))}function z(e){e._inverseNormal3DDirty&&(e._inverseNormal3DDirty=!1,p.getRotation(e.inverseModelView3D,e._inverseNormal3D))}function G(e){e._encodedCameraPositionMCDirty&&(e._encodedCameraPositionMCDirty=!1,p.multiplyByPoint(e.inverseModel,e._cameraPosition,X),c.fromCartesian(X,e._encodedCameraPositionMC))}function W(e,t,r,n,o,a,s,u){var c=Q;c.x=e.y,c.y=e.z,c.z=e.x;var h=Z;h.x=r.y,h.y=r.z,h.z=r.x;var f=K;f.x=n.y,f.y=n.z,f.z=n.x;var m=J;m.x=t.y,m.y=t.z,m.z=t.x,a===_.SCENE2D&&(c.z=.5*o);var v=s.unproject(c,$);v.longitude=d.clamp(v.longitude,-Math.PI,Math.PI),v.latitude=d.clamp(v.latitude,-d.PI_OVER_TWO,d.PI_OVER_TWO);var y=s.ellipsoid,b=y.cartographicToCartesian(v,ee),C=g.eastNorthUpToFixedFrame(b,y,te);return p.multiplyByPointAsVector(C,h,h),p.multiplyByPointAsVector(C,f,f),p.multiplyByPointAsVector(C,m,m),l(u)||(u=new p),u[0]=h.x,u[1]=f.x,u[2]=-m.x,u[3]=0,u[4]=h.y,u[5]=f.y,u[6]=-m.y,u[7]=0,u[8]=h.z,u[9]=f.z,u[10]=-m.z,u[11]=0,u[12]=-i.dot(h,b),u[13]=-i.dot(f,b),u[14]=i.dot(m,b),u[15]=1,u}function H(e){e._view3DDirty&&(e._mode===_.SCENE3D?p.clone(e._view,e._view3D):W(e._cameraPosition,e._cameraDirection,e._cameraRight,e._cameraUp,e._frustum2DWidth,e._mode,e._mapProjection,e._view3D),p.getRotation(e._view3D,e._viewRotation3D),e._view3DDirty=!1)}function j(e){e._inverseView3DDirty&&(p.inverseTransformation(e.view3D,e._inverseView3D),p.getRotation(e._inverseView3D,e._inverseViewRotation3D),e._inverseView3DDirty=!1)}u(v.prototype,{frameState:{get:function(){return this._frameState}},viewport:{get:function(){return this._viewport},set:function(e){if(!t.equals(e,this._viewport)){t.clone(e,this._viewport);var r=this._viewport,i=this._viewportCartesian4;i.x=r.x,i.y=r.y,i.z=r.width,i.w=r.height,this._viewportDirty=!0}}},viewportCartesian4:{get:function(){return this._viewportCartesian4}},viewportOrthographic:{get:function(){return E(this),this._viewportOrthographicMatrix}},viewportTransformation:{get:function(){return E(this),this._viewportTransformation}},model:{get:function(){return this._model},set:function(e){p.clone(e,this._model),this._modelView3DDirty=!0,this._inverseModelView3DDirty=!0,this._inverseModelDirty=!0,this._inverseTransposeModelDirty=!0,this._modelViewDirty=!0,this._inverseModelViewDirty=!0,this._modelViewRelativeToEyeDirty=!0,this._inverseModelViewDirty=!0,this._modelViewProjectionDirty=!0,this._inverseModelViewProjectionDirty=!0,this._modelViewProjectionRelativeToEyeDirty=!0,this._modelViewInfiniteProjectionDirty=!0,this._normalDirty=!0,this._inverseNormalDirty=!0,this._normal3DDirty=!0,this._inverseNormal3DDirty=!0,this._encodedCameraPositionMCDirty=!0}},inverseModel:{get:function(){return this._inverseModelDirty&&(this._inverseModelDirty=!1,p.inverse(this._model,this._inverseModel)),this._inverseModel}},inverseTransposeModel:{get:function(){var e=this._inverseTransposeModel;return this._inverseTransposeModelDirty&&(this._inverseTransposeModelDirty=!1,p.getRotation(this.inverseModel,e),h.transpose(e,e)),e}},view:{get:function(){return this._view}},view3D:{get:function(){return H(this),this._view3D}},viewRotation:{get:function(){return H(this),this._viewRotation}},viewRotation3D:{get:function(){return H(this),this._viewRotation3D}},inverseView:{get:function(){return this._inverseView}},inverseView3D:{get:function(){return j(this),this._inverseView3D}},inverseViewRotation:{get:function(){return this._inverseViewRotation}},inverseViewRotation3D:{get:function(){return j(this),this._inverseViewRotation3D}},projection:{get:function(){return this._projection}},inverseProjection:{get:function(){return A(this),this._inverseProjection}},infiniteProjection:{get:function(){return this._infiniteProjection}},modelView:{get:function(){return x(this),this._modelView}},modelView3D:{get:function(){return P(this),this._modelView3D}},modelViewRelativeToEye:{get:function(){return L(this),this._modelViewRelativeToEye}},inverseModelView:{get:function(){return D(this),this._inverseModelView}},inverseModelView3D:{get:function(){return I(this),this._inverseModelView3D}},viewProjection:{get:function(){return O(this),this._viewProjection}},inverseViewProjection:{get:function(){return M(this),this._inverseViewProjection}},modelViewProjection:{get:function(){return R(this),this._modelViewProjection}},inverseModelViewProjection:{get:function(){return N(this),this._inverseModelViewProjection}},modelViewProjectionRelativeToEye:{get:function(){return k(this),this._modelViewProjectionRelativeToEye}},modelViewInfiniteProjection:{get:function(){return F(this),this._modelViewInfiniteProjection}},normal:{get:function(){return B(this),this._normal}},normal3D:{get:function(){return U(this),this._normal3D}},inverseNormal:{get:function(){return V(this),this._inverseNormal}},inverseNormal3D:{get:function(){return z(this),this._inverseNormal3D}},entireFrustum:{get:function(){return this._entireFrustum}},currentFrustum:{get:function(){return this._currentFrustum}},frustumPlanes:{get:function(){return this._frustumPlanes}},eyeHeight2D:{get:function(){return this._eyeHeight2D}},sunPositionWC:{get:function(){return this._sunPositionWC}},sunPositionColumbusView:{get:function(){return this._sunPositionColumbusView}},sunDirectionWC:{get:function(){return this._sunDirectionWC}},sunDirectionEC:{get:function(){return this._sunDirectionEC}},moonDirectionEC:{get:function(){return this._moonDirectionEC}},encodedCameraPositionMCHigh:{get:function(){return G(this),this._encodedCameraPositionMC.high}},encodedCameraPositionMCLow:{get:function(){return G(this),this._encodedCameraPositionMC.low}},temeToPseudoFixedMatrix:{get:function(){return this._temeToPseudoFixed}},resolutionScale:{get:function(){return this._resolutionScale}},fogDensity:{get:function(){return this._fogDensity}},geometricToleranceOverMeter:{get:function(){return this._geometricToleranceOverMeter}},pass:{get:function(){return this._pass}},backgroundColor:{get:function(){return this._backgroundColor}},brdfLut:{get:function(){return this._brdfLut}},environmentMap:{get:function(){return this._environmentMap}},imagerySplitPosition:{get:function(){return this._imagerySplitPosition}},minimumDisableDepthTestDistance:{get:function(){return this._minimumDisableDepthTestDistance}},invertClassificationColor:{get:function(){return this._invertClassificationColor}}});var q=new h,Y=new o;v.prototype.updateCamera=function(e){y(this,e.viewMatrix),b(this,e.inverseViewMatrix),w(this,e),this._entireFrustum.x=e.frustum.near,this._entireFrustum.y=e.frustum.far,this.updateFrustum(e.frustum),this._orthographicIn3D=this._mode!==_.SCENE2D&&e.frustum instanceof f},v.prototype.updateFrustum=function(e){C(this,e.projectionMatrix),l(e.infiniteProjectionMatrix)&&S(this,e.infiniteProjectionMatrix),this._currentFrustum.x=e.near,this._currentFrustum.y=e.far,l(e._offCenterFrustum)&&(e=e._offCenterFrustum),this._frustumPlanes.x=e.top,this._frustumPlanes.y=e.bottom,this._frustumPlanes.z=e.left,this._frustumPlanes.w=e.right},v.prototype.updatePass=function(e){this._pass=e},v.prototype.update=function(e){this._mode=e.mode,this._mapProjection=e.mapProjection;var t=e.context._canvas;this._resolutionScale=t.width/t.clientWidth;var r=e.camera;this.updateCamera(r),e.mode===_.SCENE2D?(this._frustum2DWidth=r.frustum.right-r.frustum.left,this._eyeHeight2D.x=.5*this._frustum2DWidth,this._eyeHeight2D.y=this._eyeHeight2D.x*this._eyeHeight2D.x):(this._frustum2DWidth=0,this._eyeHeight2D.x=0,this._eyeHeight2D.y=0),T(this,e);var i=e.brdfLutGenerator,n=l(i)?i.colorTexture:void 0;this._brdfLut=n,this._environmentMap=s(e.environmentMap,e.context.defaultCubeMap),this._fogDensity=e.fog.density,this._invertClassificationColor=e.invertClassificationColor,this._frameState=e,this._temeToPseudoFixed=g.computeTemeToPseudoFixedMatrix(e.time,this._temeToPseudoFixed),this._imagerySplitPosition=e.imagerySplitPosition*e.context.drawingBufferWidth;var o,u=r.frustum.fov,c=this._viewport;o=c.height>c.width?2*Math.tan(.5*u)/c.height:2*Math.tan(.5*u)/c.width,this._geometricToleranceOverMeter=o*e.maximumScreenSpaceError,a.clone(e.backgroundColor,this._backgroundColor),this._minimumDisableDepthTestDistance=e.minimumDisableDepthTestDistance,this._minimumDisableDepthTestDistance*=this._minimumDisableDepthTestDistance,this._minimumDisableDepthTestDistance===Number.POSITIVE_INFINITY&&(this._minimumDisableDepthTestDistance=-1)};var X=new i,Q=new i,Z=new i,K=new i,J=new i,$=new o,ee=new i,te=new p;return v}),define("Renderer/Context",["../Core/Check","../Core/clone","../Core/Color","../Core/ComponentDatatype","../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Geometry","../Core/GeometryAttribute","../Core/Matrix4","../Core/PrimitiveType","../Core/RuntimeError","../Core/WebGLConstants","../Shaders/ViewportQuadVS","./BufferUsage","./ClearCommand","./ContextLimits","./CubeMap","./DrawCommand","./PassState","./PickFramebuffer","./RenderState","./ShaderCache","./ShaderProgram","./Texture","./UniformState","./VertexArray"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D){"use strict";function I(e,t){var r="WebGL Error: ";switch(t){case e.INVALID_ENUM:r+="INVALID_ENUM";break;case e.INVALID_VALUE:r+="INVALID_VALUE";break;case e.INVALID_OPERATION:r+="INVALID_OPERATION";break;case e.OUT_OF_MEMORY:r+="OUT_OF_MEMORY";break;case e.CONTEXT_LOST_WEBGL:r+="CONTEXT_LOST_WEBGL lost";break;default:r+="Unknown ("+t+")"}return r}function O(e,t,r,i){for(var n=I(e,i)+": "+t.name+"(",o=0;o<r.length;++o)0!==o&&(n+=", "),n+=r[o];return n+=");"}function M(e,t,r){var i=e.getError();if(i!==e.NO_ERROR)throw new f(O(e,t,r,i))}function R(e,t,r){return{get:function(){var i=e[t];return r(e,"get: "+t,i),e[t]},set:function(i){e[t]=i,r(e,"set: "+t,i)}}}function L(e,t){if(!a(t))return e;var r={};for(var i in e){var n=e[i];n instanceof Function?r[i]=function(r){return function(){var i=r.apply(e,arguments);return t(e,r,arguments),i}}(n):Object.defineProperty(r,i,R(e,i,t))}return r}function N(e,t){for(var r=t.length,i=0;i<r;++i){var n=e.getExtension(t[i]);if(n)return n}}function k(e,i){if("undefined"==typeof WebGLRenderingContext)throw new f("The browser does not support WebGL. Visit http://get.webgl.org.");this._canvas=e,i=t(i,!0),i=o(i,{}),i.allowTextureFilterAnisotropic=o(i.allowTextureFilterAnisotropic,!0);var s=o(i.webgl,{});s.alpha=o(s.alpha,!1),s.stencil=o(s.stencil,!0);var l,u=o(i.requestWebgl2,!1)&&"undefined"!=typeof WebGL2RenderingContext,c=!1,d=i.getWebGLStub;if(a(d))l=d(e,s);else if(u&&(l=e.getContext("webgl2",s)||e.getContext("experimental-webgl2",s)||void 0,a(l)&&(c=!0)),a(l)||(l=e.getContext("webgl",s)||e.getContext("experimental-webgl",s)||void 0),!a(l))throw new f("The browser supports WebGL, but initialization failed.");this._originalGLContext=l,this._gl=l,this._webgl2=c,this._id=n(),this.validateFramebuffer=!1,this.validateShaderProgram=!1,this.logShaderCompilation=!1,this._throwOnWebGLError=!1,this._shaderCache=new E(this);var h=l;this._stencilBits=h.getParameter(h.STENCIL_BITS),y._maximumCombinedTextureImageUnits=h.getParameter(h.MAX_COMBINED_TEXTURE_IMAGE_UNITS),y._maximumCubeMapSize=h.getParameter(h.MAX_CUBE_MAP_TEXTURE_SIZE),y._maximumFragmentUniformVectors=h.getParameter(h.MAX_FRAGMENT_UNIFORM_VECTORS),y._maximumTextureImageUnits=h.getParameter(h.MAX_TEXTURE_IMAGE_UNITS),y._maximumRenderbufferSize=h.getParameter(h.MAX_RENDERBUFFER_SIZE),y._maximumTextureSize=h.getParameter(h.MAX_TEXTURE_SIZE),y._maximumVaryingVectors=h.getParameter(h.MAX_VARYING_VECTORS),y._maximumVertexAttributes=h.getParameter(h.MAX_VERTEX_ATTRIBS),y._maximumVertexTextureImageUnits=h.getParameter(h.MAX_VERTEX_TEXTURE_IMAGE_UNITS),y._maximumVertexUniformVectors=h.getParameter(h.MAX_VERTEX_UNIFORM_VECTORS);var p=h.getParameter(h.ALIASED_LINE_WIDTH_RANGE);y._minimumAliasedLineWidth=p[0],y._maximumAliasedLineWidth=p[1];var g=h.getParameter(h.ALIASED_POINT_SIZE_RANGE);y._minimumAliasedPointSize=g[0],y._maximumAliasedPointSize=g[1];var _=h.getParameter(h.MAX_VIEWPORT_DIMS);y._maximumViewportWidth=_[0],y._maximumViewportHeight=_[1];var v=h.getShaderPrecisionFormat(h.FRAGMENT_SHADER,h.HIGH_FLOAT);y._highpFloatSupported=0!==v.precision;var b=h.getShaderPrecisionFormat(h.FRAGMENT_SHADER,h.HIGH_INT);y._highpIntSupported=0!==b.rangeMax,this._antialias=h.getContextAttributes().antialias,this._standardDerivatives=!!N(h,["OES_standard_derivatives"]),this._blendMinmax=!!N(h,["EXT_blend_minmax"]),this._elementIndexUint=!!N(h,["OES_element_index_uint"]),this._depthTexture=!!N(h,["WEBGL_depth_texture","WEBKIT_WEBGL_depth_texture"]),this._textureFloat=!!N(h,["OES_texture_float"]),this._fragDepth=!!N(h,["EXT_frag_depth"]),this._debugShaders=N(h,["WEBGL_debug_shaders"]),this._colorBufferFloat=this._webgl2&&!!N(h,["EXT_color_buffer_float"]),this._s3tc=!!N(h,["WEBGL_compressed_texture_s3tc","MOZ_WEBGL_compressed_texture_s3tc","WEBKIT_WEBGL_compressed_texture_s3tc"]),this._pvrtc=!!N(h,["WEBGL_compressed_texture_pvrtc","WEBKIT_WEBGL_compressed_texture_pvrtc"]),this._etc1=!!N(h,["WEBGL_compressed_texture_etc1"]);var C=i.allowTextureFilterAnisotropic?N(h,["EXT_texture_filter_anisotropic","WEBKIT_EXT_texture_filter_anisotropic"]):void 0;this._textureFilterAnisotropic=C,y._maximumTextureFilterAnisotropy=a(C)?h.getParameter(C.MAX_TEXTURE_MAX_ANISOTROPY_EXT):1;var w,A,x,D,I,O,M,R,L,k;if(c){var F=this;w=function(){return F._gl.createVertexArray()},A=function(e){F._gl.bindVertexArray(e)}, +x=function(e){F._gl.deleteVertexArray(e)},D=function(e,t,r,i,n){h.drawElementsInstanced(e,t,r,i,n)},I=function(e,t,r,i){h.drawArraysInstanced(e,t,r,i)},O=function(e,t){h.vertexAttribDivisor(e,t)},M=function(e){h.drawBuffers(e)}}else R=N(h,["OES_vertex_array_object"]),a(R)&&(w=function(){return R.createVertexArrayOES()},A=function(e){R.bindVertexArrayOES(e)},x=function(e){R.deleteVertexArrayOES(e)}),L=N(h,["ANGLE_instanced_arrays"]),a(L)&&(D=function(e,t,r,i,n){L.drawElementsInstancedANGLE(e,t,r,i,n)},I=function(e,t,r,i){L.drawArraysInstancedANGLE(e,t,r,i)},O=function(e,t){L.vertexAttribDivisorANGLE(e,t)}),k=N(h,["WEBGL_draw_buffers"]),a(k)&&(M=function(e){k.drawBuffersWEBGL(e)});this.glCreateVertexArray=w,this.glBindVertexArray=A,this.glDeleteVertexArray=x,this.glDrawElementsInstanced=D,this.glDrawArraysInstanced=I,this.glVertexAttribDivisor=O,this.glDrawBuffers=M,this._vertexArrayObject=!!R,this._instancedArrays=!!L,this._drawBuffers=!!k,y._maximumDrawBuffers=this.drawBuffers?h.getParameter(m.MAX_DRAW_BUFFERS):1,y._maximumColorAttachments=this.drawBuffers?h.getParameter(m.MAX_COLOR_ATTACHMENTS):1,this._clearColor=new r(0,0,0,0),this._clearDepth=1,this._clearStencil=0;var B=new P,U=new S(this),V=T.fromCache();this._defaultPassState=U,this._defaultRenderState=V,this._defaultTexture=void 0,this._defaultCubeMap=void 0,this._us=B,this._currentRenderState=V,this._currentPassState=U,this._currentFramebuffer=void 0,this._maxFrameTextureUnitIndex=0,this._vertexAttribDivisors=[],this._previousDrawInstanced=!1;for(var z=0;z<y._maximumVertexAttributes;z++)this._vertexAttribDivisors.push(0);this._pickObjects={},this._nextPickColor=new Uint32Array(1),this.options=i,this.cache={},T.apply(h,V,U)}function F(e){}function B(e,t,r,i){var n=e._currentRenderState,o=e._currentPassState;e._currentRenderState=t,e._currentPassState=r,T.partialApply(e._gl,n,t,o,r,i)}function U(e,t){if(t!==e._currentFramebuffer){e._currentFramebuffer=t;var r=H;if(a(t))t._bind(),F(e),r=t._getActiveColorAttachments();else{var i=e._gl;i.bindFramebuffer(i.FRAMEBUFFER,null)}e.drawBuffers&&e.glDrawBuffers(r)}}function V(e,t,r,i){var n=o(r._renderState,e._defaultRenderState);U(e,t),B(e,n,i,!1);var a=r._shaderProgram;a._bind(),e._maxFrameTextureUnitIndex=Math.max(e._maxFrameTextureUnitIndex,a.maximumTextureUnitIndex)}function z(e,t){var r=t._primitiveType,i=t._vertexArray,n=t._offset,s=t._count,l=t.instanceCount;e._us.model=o(t._modelMatrix,h.IDENTITY),t._shaderProgram._setUniforms(t._uniformMap,e._us,e.validateShaderProgram),i._bind();var u=i.indexBuffer;a(u)?(n*=u.bytesPerIndex,s=o(s,u.numberOfIndices),0===l?e._gl.drawElements(r,s,u.indexDatatype,n):e.glDrawElementsInstanced(r,s,u.indexDatatype,n,l)):(s=o(s,i.numberOfVertices),0===l?e._gl.drawArrays(r,n,s):e.glDrawArraysInstanced(r,n,s,l)),i._unBind()}function G(e,t,r){this._pickObjects=e,this.key=t,this.color=r}var W={};s(k.prototype,{id:{get:function(){return this._id}},webgl2:{get:function(){return this._webgl2}},canvas:{get:function(){return this._canvas}},shaderCache:{get:function(){return this._shaderCache}},uniformState:{get:function(){return this._us}},stencilBits:{get:function(){return this._stencilBits}},stencilBuffer:{get:function(){return this._stencilBits>=8}},antialias:{get:function(){return this._antialias}},standardDerivatives:{get:function(){return this._standardDerivatives||this._webgl2}},blendMinmax:{get:function(){return this._blendMinmax||this._webgl2}},elementIndexUint:{get:function(){return this._elementIndexUint||this._webgl2}},depthTexture:{get:function(){return this._depthTexture||this._webgl2}},floatingPointTexture:{get:function(){return this._textureFloat||this._colorBufferFloat}},textureFilterAnisotropic:{get:function(){return!!this._textureFilterAnisotropic}},s3tc:{get:function(){return this._s3tc}},pvrtc:{get:function(){return this._pvrtc}},etc1:{get:function(){return this._etc1}},vertexArrayObject:{get:function(){return this._vertexArrayObject||this._webgl2}},fragmentDepth:{get:function(){return this._fragDepth||this._webgl2}},instancedArrays:{get:function(){return this._instancedArrays||this._webgl2}},colorBufferFloat:{get:function(){return this._colorBufferFloat}},drawBuffers:{get:function(){return this._drawBuffers||this._webgl2}},debugShaders:{get:function(){return this._debugShaders}},throwOnWebGLError:{get:function(){return this._throwOnWebGLError},set:function(e){this._throwOnWebGLError=e,this._gl=L(this._originalGLContext,e?M:void 0)}},defaultTexture:{get:function(){return void 0===this._defaultTexture&&(this._defaultTexture=new x({context:this,source:{width:1,height:1,arrayBufferView:new Uint8Array([255,255,255,255])}})),this._defaultTexture}},defaultCubeMap:{get:function(){if(void 0===this._defaultCubeMap){var e={width:1,height:1,arrayBufferView:new Uint8Array([255,255,255,255])};this._defaultCubeMap=new b({context:this,source:{positiveX:e,negativeX:e,positiveY:e,negativeY:e,positiveZ:e,negativeZ:e}})}return this._defaultCubeMap}},drawingBufferHeight:{get:function(){return this._gl.drawingBufferHeight}},drawingBufferWidth:{get:function(){return this._gl.drawingBufferWidth}},defaultFramebuffer:{get:function(){return W}}});var H;"undefined"!=typeof WebGLRenderingContext&&(H=[m.BACK]);var j=new v;k.prototype.clear=function(e,t){e=o(e,j),t=o(t,this._defaultPassState);var i=this._gl,n=0,s=e.color,l=e.depth,u=e.stencil;a(s)&&(r.equals(this._clearColor,s)||(r.clone(s,this._clearColor),i.clearColor(s.red,s.green,s.blue,s.alpha)),n|=i.COLOR_BUFFER_BIT),a(l)&&(l!==this._clearDepth&&(this._clearDepth=l,i.clearDepth(l)),n|=i.DEPTH_BUFFER_BIT),a(u)&&(u!==this._clearStencil&&(this._clearStencil=u,i.clearStencil(u)),n|=i.STENCIL_BUFFER_BIT),B(this,o(e.renderState,this._defaultRenderState),t,!0),U(this,o(e.framebuffer,t.framebuffer)),i.clear(n)},k.prototype.draw=function(e,t){t=o(t,this._defaultPassState),V(this,o(e._framebuffer,t.framebuffer),e,t),z(this,e)},k.prototype.endFrame=function(){var e=this._gl;e.useProgram(null),this._currentFramebuffer=void 0,e.bindFramebuffer(e.FRAMEBUFFER,null);var t=H;this.drawBuffers&&this.glDrawBuffers(t);var r=this._maxFrameTextureUnitIndex;this._maxFrameTextureUnitIndex=0;for(var i=0;i<r;++i)e.activeTexture(e.TEXTURE0+i),e.bindTexture(e.TEXTURE_2D,null),e.bindTexture(e.TEXTURE_CUBE_MAP,null)},k.prototype.readPixels=function(e){var t=this._gl;e=e||{};var r=Math.max(e.x||0,0),i=Math.max(e.y||0,0),n=e.width||t.drawingBufferWidth,o=e.height||t.drawingBufferHeight,a=e.framebuffer,s=new Uint8Array(4*n*o);return U(this,a),t.readPixels(r,i,n,o,t.RGBA,t.UNSIGNED_BYTE,s),s};var q={position:0,textureCoordinates:1};return k.prototype.getViewportQuadVertexArray=function(){var e=this.cache.viewportQuad_vertexArray;if(!a(e)){var t=new c({attributes:{position:new d({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:[-1,-1,1,-1,1,1,-1,1]}),textureCoordinates:new d({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:[0,0,1,0,1,1,0,1]})},indices:new Uint16Array([0,1,2,0,2,3]),primitiveType:p.TRIANGLES});e=D.fromGeometry({context:this,geometry:t,attributeLocations:q,bufferUsage:_.STATIC_DRAW,interleave:!0}),this.cache.viewportQuad_vertexArray=e}return e},k.prototype.createViewportQuadCommand=function(e,t){return t=o(t,o.EMPTY_OBJECT),new C({vertexArray:this.getViewportQuadVertexArray(),primitiveType:p.TRIANGLES,renderState:t.renderState,shaderProgram:A.fromCache({context:this,vertexShaderSource:g,fragmentShaderSource:e,attributeLocations:q}),uniformMap:t.uniformMap,owner:t.owner,framebuffer:t.framebuffer,pass:t.pass})},k.prototype.createPickFramebuffer=function(){return new w(this)},k.prototype.getObjectByPickColor=function(e){return this._pickObjects[e.toRgba()]},s(G.prototype,{object:{get:function(){return this._pickObjects[this.key]},set:function(e){this._pickObjects[this.key]=e}}}),G.prototype.destroy=function(){delete this._pickObjects[this.key]},k.prototype.createPickId=function(e){++this._nextPickColor[0];var t=this._nextPickColor[0];if(0===t)throw new f("Out of unique Pick IDs.");return this._pickObjects[t]=e,new G(this._pickObjects,t,r.fromRgba(t))},k.prototype.isDestroyed=function(){return!1},k.prototype.destroy=function(){var e=this.cache;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];a(r.destroy)&&r.destroy()}return this._shaderCache=this._shaderCache.destroy(),this._defaultTexture=this._defaultTexture&&this._defaultTexture.destroy(),this._defaultCubeMap=this._defaultCubeMap&&this._defaultCubeMap.destroy(),l(this)},k}),define("Renderer/loadCubeMap",["../Core/Check","../Core/defined","../Core/DeveloperError","../Core/Resource","../ThirdParty/when","./CubeMap"],function(e,t,r,i,n,o){"use strict";function a(e,t){var r=[i.createIfNeeded(t.positiveX).fetchImage(),i.createIfNeeded(t.negativeX).fetchImage(),i.createIfNeeded(t.positiveY).fetchImage(),i.createIfNeeded(t.negativeY).fetchImage(),i.createIfNeeded(t.positiveZ).fetchImage(),i.createIfNeeded(t.negativeZ).fetchImage()];return n.all(r,function(t){return new o({context:e,source:{positiveX:t[0],negativeX:t[1],positiveY:t[2],negativeY:t[3],positiveZ:t[4],negativeZ:t[5]}})})}return a}),define("Scene/DiscardMissingTileImagePolicy",["../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/getImagePixels","../Core/Resource","../ThirdParty/when"],function(e,t,r,i,n,o){"use strict";function a(r){function a(e){t(e.blob)&&(u._missingImageByteLength=e.blob.size);var n=i(e);if(r.disableCheckIfAllPixelsAreTransparent){for(var o=!0,a=e.width,s=r.pixelsToCheck,l=0,c=s.length;o&&l<c;++l){var d=s[l];n[4*d.x+d.y*a+3]>0&&(o=!1)}o&&(n=void 0)}u._missingImagePixels=n,u._isReady=!0}function s(){u._missingImagePixels=void 0,u._isReady=!0}r=e(r,e.EMPTY_OBJECT),this._pixelsToCheck=r.pixelsToCheck,this._missingImagePixels=void 0,this._missingImageByteLength=void 0,this._isReady=!1;var l=n.createIfNeeded(r.missingImageUrl),u=this;o(l.fetchImage(!0),a,s)}return a.prototype.isReady=function(){return this._isReady},a.prototype.shouldDiscardImage=function(e){var r=this._pixelsToCheck,n=this._missingImagePixels;if(!t(n))return!1;if(t(e.blob)&&e.blob.size!==this._missingImageByteLength)return!1;for(var o=i(e),a=e.width,s=0,l=r.length;s<l;++s)for(var u=r[s],c=4*u.x+u.y*a,d=0;d<4;++d){var h=c+d;if(o[h]!==n[h])return!1}return!0},a}),define("Scene/ImageryLayerFeatureInfo",["../Core/defined"],function(e){"use strict";function t(){this.name=void 0,this.description=void 0,this.position=void 0,this.data=void 0,this.imageryLayer=void 0}return t.prototype.configureNameFromProperties=function(t){var r,i=10;for(var n in t)if(t.hasOwnProperty(n)&&t[n]){var o=n.toLowerCase();i>1&&"name"===o?(i=1,r=n):i>2&&"title"===o?(i=2,r=n):i>3&&/name/i.test(n)?(i=3,r=n):i>4&&/title/i.test(n)&&(i=4,r=n)}e(r)&&(this.name=t[r])},t.prototype.configureDescriptionFromProperties=function(t){function r(t){var i='<table class="cesium-infoBox-defaultTable">';for(var n in t)if(t.hasOwnProperty(n)){var o=t[n];e(o)&&(i+="object"==typeof o?"<tr><td>"+n+"</td><td>"+r(o)+"</td></tr>":"<tr><td>"+n+"</td><td>"+o+"</td></tr>")}return i+="</table>"}this.description=r(t)},t}),define("Scene/ImageryProvider",["../Core/Check","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/loadCRN","../Core/loadKTX","../Core/Resource"],function(e,t,r,i,n,o,a,s){"use strict";function l(){this.defaultAlpha=void 0,this.defaultBrightness=void 0,this.defaultContrast=void 0,this.defaultHue=void 0,this.defaultSaturation=void 0,this.defaultGamma=void 0,this.defaultMinificationFilter=void 0,this.defaultMagnificationFilter=void 0,n.throwInstantiationError()}r(l.prototype,{ready:{get:n.throwInstantiationError},readyPromise:{get:n.throwInstantiationError},rectangle:{get:n.throwInstantiationError},tileWidth:{get:n.throwInstantiationError},tileHeight:{get:n.throwInstantiationError},maximumLevel:{get:n.throwInstantiationError},minimumLevel:{get:n.throwInstantiationError},tilingScheme:{get:n.throwInstantiationError},tileDiscardPolicy:{get:n.throwInstantiationError},errorEvent:{get:n.throwInstantiationError},credit:{get:n.throwInstantiationError},proxy:{get:n.throwInstantiationError},hasAlphaChannel:{get:n.throwInstantiationError}}),l.prototype.getTileCredits=n.throwInstantiationError,l.prototype.requestImage=n.throwInstantiationError,l.prototype.pickFeatures=n.throwInstantiationError;var u=/\.ktx$/i,c=/\.crn$/i;return l.loadImage=function(e,r,n){t(n)&&i("ImageryProvider.loadImage.request","The request parameter has been deprecated. Set the request property on the Resource parameter.");var l=s.createIfNeeded(r,{request:n});return u.test(l)?a(l):c.test(l)?o(l):t(e.tileDiscardPolicy)?l.fetchImage(!0):l.fetchImage()},l}),define("Scene/ArcGisMapServerImageryProvider",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/Math","../Core/Rectangle","../Core/Resource","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorProjection","../Core/WebMercatorTilingScheme","../ThirdParty/when","./DiscardMissingTileImagePolicy","./ImageryLayerFeatureInfo","./ImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C){"use strict";function S(r){function a(n){var a=n.tileInfo;if(o(a)){if(S._tileWidth=a.rows,S._tileHeight=a.cols,102100===a.spatialReference.wkid||102113===a.spatialReference.wkid)S._tilingScheme=new _({ellipsoid:r.ellipsoid});else{if(4326!==n.tileInfo.spatialReference.wkid){var s="Tile spatial reference WKID "+n.tileInfo.spatialReference.wkid+" is not supported.";return void(C=m.handleError(C,S,S._errorEvent,s,void 0,void 0,void 0,d))}S._tilingScheme=new c({ellipsoid:r.ellipsoid})}if(S._maximumLevel=n.tileInfo.lods.length-1,o(n.fullExtent)){if(o(n.fullExtent.spatialReference)&&o(n.fullExtent.spatialReference.wkid))if(102100===n.fullExtent.spatialReference.wkid||102113===n.fullExtent.spatialReference.wkid){var l=new g,u=n.fullExtent,p=l.unproject(new t(Math.max(u.xmin,-S._tilingScheme.ellipsoid.maximumRadius*Math.PI),Math.max(u.ymin,-S._tilingScheme.ellipsoid.maximumRadius*Math.PI),0)),f=l.unproject(new t(Math.min(u.xmax,S._tilingScheme.ellipsoid.maximumRadius*Math.PI),Math.min(u.ymax,S._tilingScheme.ellipsoid.maximumRadius*Math.PI),0));S._rectangle=new h(p.longitude,p.latitude,f.longitude,f.latitude)}else{if(4326!==n.fullExtent.spatialReference.wkid){var v="fullExtent.spatialReference WKID "+n.fullExtent.spatialReference.wkid+" is not supported.";return void(C=m.handleError(C,S,S._errorEvent,v,void 0,void 0,void 0,d))}S._rectangle=h.fromDegrees(n.fullExtent.xmin,n.fullExtent.ymin,n.fullExtent.xmax,n.fullExtent.ymax)}}else S._rectangle=S._tilingScheme.rectangle;o(S._tileDiscardPolicy)||(S._tileDiscardPolicy=new y({missingImageUrl:w(S,0,0,S._maximumLevel).url,pixelsToCheck:[new e(0,0),new e(200,20),new e(20,200),new e(80,110),new e(160,130)],disableCheckIfAllPixelsAreTransparent:!0})),S._useTiles=!0}else S._useTiles=!1;o(n.copyrightText)&&n.copyrightText.length>0&&(S._credit=new i({text:n.copyrightText})),S._ready=!0,S._readyPromise.resolve(!0),m.handleSuccess(C)}function l(e){var t="An error occurred while accessing "+S._resource.url+".";C=m.handleError(C,S,S._errorEvent,t,void 0,void 0,void 0,d),S._readyPromise.reject(new f(t))}function d(){var e=S._resource.getDerivedResource({queryParameters:{f:"json"}}),t=e.fetchJsonp();v(t,a,l)}r=n(r,{}),o(r.proxy)&&s("ArcGisMapServerImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var b=p.createIfNeeded(r.url,{proxy:r.proxy});b.appendForwardSlash(),o(r.token)&&b.addQueryParameters({token:r.token}),this._resource=b,this._tileDiscardPolicy=r.tileDiscardPolicy,this._tileWidth=n(r.tileWidth,256),this._tileHeight=n(r.tileHeight,256),this._maximumLevel=r.maximumLevel,this._tilingScheme=n(r.tilingScheme,new c({ellipsoid:r.ellipsoid})),this._credit=void 0,this._useTiles=n(r.usePreCachedTilesIfAvailable,!0),this._rectangle=n(r.rectangle,this._tilingScheme.rectangle),this._layers=r.layers,this.enablePickFeatures=n(r.enablePickFeatures,!0),this._errorEvent=new u,this._ready=!1,this._readyPromise=v.defer();var C,S=this;this._useTiles?d():(this._ready=!0,this._readyPromise.resolve(!0))}function w(e,t,r,i,n){var o;if(e._useTiles)o=e._resource.getDerivedResource({url:"tile/"+i+"/"+r+"/"+t,request:n});else{var a=e._tilingScheme.tileXYToNativeRectangle(t,r,i),s=a.west+","+a.south+","+a.east+","+a.north,l={bbox:s,size:e._tileWidth+","+e._tileHeight,format:"png",transparent:!0,f:"image"};e._tilingScheme instanceof c?(l.bboxSR=4326,l.imageSR=4326):(l.bboxSR=3857,l.imageSR=3857),e.layers&&(l.layers="show:"+e.layers),o=e._resource.getDerivedResource({url:"export",request:n,queryParameters:l})}return o}return a(S.prototype,{url:{get:function(){return this._resource._url}},token:{get:function(){return this._resource.queryParameters.token}},proxy:{get:function(){return this._resource.proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},usingPrecachedTiles:{get:function(){return this._useTiles}},hasAlphaChannel:{get:function(){return!0}},layers:{get:function(){return this._layers}}}),S.prototype.getTileCredits=function(e,t,r){},S.prototype.requestImage=function(e,t,r,i){return C.loadImage(this,w(this,e,t,r,i))},S.prototype.pickFeatures=function(e,i,n,a,s){if(this.enablePickFeatures){var l,u,h,p=this._tilingScheme.tileXYToNativeRectangle(e,i,n);if(this._tilingScheme instanceof c)l=d.toDegrees(a),u=d.toDegrees(s),h="4326";else{var f=this._tilingScheme.projection.project(new r(a,s,0));l=f.x,u=f.y,h="3857"}var m="visible";o(this._layers)&&(m+=":"+this._layers);var _={f:"json",tolerance:2,geometryType:"esriGeometryPoint",geometry:l+","+u,mapExtent:p.west+","+p.south+","+p.east+","+p.north,imageDisplay:this._tileWidth+","+this._tileHeight+",96",sr:h,layers:m};return this._resource.getDerivedResource({url:"identify",queryParameters:_}).fetchJson().then(function(e){var i=[],n=e.results;if(!o(n))return i;for(var a=0;a<n.length;++a){var s=n[a],l=new b;if(l.data=s,l.name=s.value,l.properties=s.attributes,l.configureDescriptionFromProperties(s.attributes),"esriGeometryPoint"===s.geometryType&&s.geometry){var u=s.geometry.spatialReference&&s.geometry.spatialReference.wkid?s.geometry.spatialReference.wkid:4326;if(4326===u||4283===u)l.position=r.fromDegrees(s.geometry.x,s.geometry.y,s.geometry.z);else if(102100===u||900913===u||3857===u){var c=new g;l.position=c.unproject(new t(s.geometry.x,s.geometry.y,s.geometry.z))}}i.push(l)}return i})}},S}),define("Scene/Cesium3DTileColorBlendMode",["../Core/freezeObject"],function(e){"use strict";return e({HIGHLIGHT:0,REPLACE:1,MIX:2})}),define("Scene/getBinaryAccessor",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/ComponentDatatype","../Core/Matrix2","../Core/Matrix3","../Core/Matrix4"],function(e,t,r,i,n,o,a){"use strict";function s(e){var t,r=e.componentType;t="string"==typeof r?i.fromName(r):r;var n=l[e.type],o=u[e.type];return{componentsPerAttribute:n,classType:o,createArrayBufferView:function(e,r,o){return i.createArrayBufferView(t,e,r,n*o)}}}var l={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},u={SCALAR:void 0,VEC2:e,VEC3:t,VEC4:r,MAT2:n,MAT3:o,MAT4:a};return s}),define("Scene/Cesium3DTileBatchTable",["../Core/arrayFill","../Core/Cartesian2","../Core/Cartesian4","../Core/Check","../Core/clone","../Core/Color","../Core/combine","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Math","../Core/PixelFormat","../Core/RuntimeError","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Sampler","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","./AttributeType","./BlendingState","./Cesium3DTileColorBlendMode","./CullFace","./getBinaryAccessor","./StencilFunction","./StencilOperation"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M){"use strict";function R(e,i,n,o,a){this.featuresLength=i,this._translucentFeaturesLength=0,this.batchTableJson=n,this.batchTableBinary=o;var s,l;u(n)&&(s=n.HIERARCHY,u(s)&&(delete n.HIERARCHY,s=L(s,o)),l=R.getBinaryProperties(i,n,o)),this._batchTableHierarchy=s,this._batchTableBinaryProperties=l,this._showAlphaProperties=void 0,this._batchValues=void 0,this._batchValuesDirty=!1,this._batchTexture=void 0,this._defaultTexture=void 0,this._pickTexture=void 0,this._pickIds=[],this._content=e,this._colorChangedCallback=a;var c,d;if(i>0){var h=Math.min(i,g.maximumTextureSize),p=Math.ceil(i/g.maximumTextureSize),f=1/h,m=.5*f,_=1/p,v=.5*_;c=new t(h,p),d=new r(f,m,_,v)}this._textureDimensions=c,this._textureStep=d}function L(t,r){var i,n,o,c=t.instancesLength,d=t.classes,h=t.classIds,p=t.parentCounts,f=t.parentIds,m=c;u(h.byteOffset)&&(h.componentType=l(h.componentType,s.UNSIGNED_SHORT),h.type=A.SCALAR,o=I(h),h=o.createArrayBufferView(r.buffer,r.byteOffset+h.byteOffset,c));var g;if(u(p))for(u(p.byteOffset)&&(p.componentType=l(p.componentType,s.UNSIGNED_SHORT),p.type=A.SCALAR,o=I(p),p=o.createArrayBufferView(r.buffer,r.byteOffset+p.byteOffset,c)),g=new Uint16Array(c),m=0,i=0;i<c;++i)g[i]=m,m+=p[i];u(f)&&u(f.byteOffset)&&(f.componentType=l(f.componentType,s.UNSIGNED_SHORT),f.type=A.SCALAR,o=I(f),f=o.createArrayBufferView(r.buffer,r.byteOffset+f.byteOffset,m));var _=d.length;for(i=0;i<_;++i){var v=d[i].length,y=d[i].instances,b=R.getBinaryProperties(v,y,r);d[i].instances=a(b,y)}var C=e(new Array(_),0),S=new Uint16Array(c);for(i=0;i<c;++i)n=h[i],S[i]=C[n],++C[n];return{classes:d,classIds:h,classIndexes:S,parentCounts:p,parentIndexes:g,parentIds:f}}function N(e){var t=e._textureDimensions;return t.x*t.y*4}function k(t){if(!u(t._batchValues)){var r=N(t),i=new Uint8Array(r);e(i,255),t._batchValues=i}return t._batchValues}function F(t){if(!u(t._showAlphaProperties)){var r=2*t.featuresLength,i=new Uint8Array(r);e(i,255),t._showAlphaProperties=i}return t._showAlphaProperties}function B(e,t){var r=e.typedArray,i=e.componentCount;return 1===i?r[t]:e.type.unpack(r,t*i)}function U(e,t,r){var i=e.typedArray,n=e.componentCount;1===n?i[t]=r:e.type.pack(r,i,t*n)}function V(e,t,r){var i=e.classIds,n=e.parentCounts,o=e.parentIds,a=e.parentIndexes,s=i.length,l=ce;l.length=Math.max(l.length,s);var c=++he,d=de;for(d.length=0,d.push(t);d.length>0;)if(t=d.pop(),l[t]!==c){l[t]=c;var h=r(e,t);if(u(h))return h;for(var p=n[t],f=a[t],m=0;m<p;++m){var g=o[f+m];g!==t&&d.push(g)}}}function z(e,t,r){for(var i=!0;i;){var n=r(e,t);if(u(n))return n;var o=e.parentIds[t];i=o!==t,t=o}}function G(e,t,r){var i=e.parentCounts,n=e.parentIds;return u(n)?u(i)?V(e,t,r):z(e,t,r):r(e,t)}function W(e,t,r){var i=e._batchTableHierarchy,n=G(i,t,function(e,t){var i=e.classIds[t],n=e.classes[i].instances;if(u(n[r]))return!0});return u(n)}function H(e,t,r){G(e._batchTableHierarchy,t,function(e,t){var i=e.classIds[t],n=e.classes[i].instances;for(var o in n)n.hasOwnProperty(o)&&-1===r.indexOf(o)&&r.push(o)})}function j(e,t,r){return G(e._batchTableHierarchy,t,function(e,t){var i=e.classIds[t],o=e.classes[i],a=e.classIndexes[t],s=o.instances[r];if(u(s))return u(s.typedArray)?B(s,a):n(s[a],!0)})}function q(e,t,r,i){var o=e._batchTableHierarchy,a=G(o,t,function(e,t){var o=e.classIds[t],a=e.classes[o],s=e.classIndexes[t],l=a.instances[r];if(u(l))return u(l.typedArray)?U(l,s,i):l[s]=n(i,!0),!0});return u(a)}function Y(e){return 1===e._textureDimensions.y?"uniform vec4 tile_textureStep; \nvec2 computeSt(float batchId) \n{ \n float stepX = tile_textureStep.x; \n float centerX = tile_textureStep.y; \n return vec2(centerX + (batchId * stepX), 0.5); \n} \n":"uniform vec4 tile_textureStep; \nuniform vec2 tile_textureDimensions; \nvec2 computeSt(float batchId) \n{ \n float stepX = tile_textureStep.x; \n float centerX = tile_textureStep.y; \n float stepY = tile_textureStep.z; \n float centerY = tile_textureStep.w; \n float xId = mod(batchId, tile_textureDimensions.x); \n float yId = floor(batchId / tile_textureDimensions.x); \n return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n} \n"}function X(e,t){return e=S.replaceMain(e,"tile_main"),t?e+"uniform float tile_colorBlend; \nvoid tile_color(vec4 tile_featureColor) \n{ \n tile_main(); \n gl_FragColor.a *= tile_featureColor.a; \n float highlight = ceil(tile_colorBlend); \n gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n} \n":e+"void tile_color(vec4 tile_featureColor) \n{ \n tile_main(); \n} \n"}function Q(e,t,r){if(!u(t))return X(e,r);var i=new RegExp("(uniform|attribute|in)\\s+(vec[34]|sampler2D)\\s+"+t+";"),n=e.match(i);if(!u(n))return X(e,r);var o=n[0],a=n[2];e=S.replaceMain(e,"tile_main"),e=e.replace(o,"");var s;if("vec3"===a||"vec4"===a){var l="vec3"===a?"vec4("+t+", 1.0)":t,c="vec3"===a?"tile_diffuse.xyz":"tile_diffuse";i=new RegExp(t,"g"),e=e.replace(i,c),s=" vec4 source = "+l+"; \n tile_diffuse = tile_diffuse_final(source, tile_featureColor); \n tile_main(); \n"}else"sampler2D"===a&&(i=new RegExp("texture2D\\("+t+".*?(\\)\\)|\\))","g"),e=e.replace(i,"tile_diffuse_final($&, tile_diffuse)"),s=" tile_diffuse = tile_featureColor; \n tile_main(); \n");return e="uniform float tile_colorBlend; \nvec4 tile_diffuse = vec4(1.0); \nbool isWhite(vec3 color) \n{ \n return all(greaterThan(color, vec3(1.0 - czm_epsilon3))); \n} \nvec4 tile_diffuse_final(vec4 sourceDiffuse, vec4 tileDiffuse) \n{ \n vec4 blendDiffuse = mix(sourceDiffuse, tileDiffuse, tile_colorBlend); \n vec4 diffuse = isWhite(tileDiffuse.rgb) ? sourceDiffuse : blendDiffuse; \n return vec4(diffuse.rgb, sourceDiffuse.a); \n} \n"+o+"\n"+e+"\nvoid tile_color(vec4 tile_featureColor) \n{ \n"+s,r&&(e+=" gl_FragColor.a *= tile_featureColor.a; \n float highlight = ceil(tile_colorBlend); \n gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n"),e+="} \n"}function Z(e){var t=e._content._tileset,r=t.colorBlendMode,i=t.colorBlendAmount;return r===P.HIGHLIGHT?0:r===P.REPLACE?1:r===P.MIX?p.clamp(i,p.EPSILON4,1):void 0}function K(e,t){e.castShadows=t.castShadows,e.receiveShadows=t.receiveShadows,e.primitiveType=t.primitiveType}function J(e){var t=e._translucentFeaturesLength;return 0===t?pe.ALL_OPAQUE:t===e.featuresLength?pe.ALL_TRANSLUCENT:pe.OPAQUE_AND_TRANSLUCENT}function $(e){var t=_.shallowClone(e),r=t.pass===v.TRANSLUCENT;return t.uniformMap=u(t.uniformMap)?t.uniformMap:{},t.uniformMap.tile_translucentCommand=function(){return r},t}function ee(e){var t=_.shallowClone(e);return t.pass=v.TRANSLUCENT,t.renderState=ie(e.renderState),t}function te(e){var t=_.shallowClone(e),r=n(t.renderState,!0);return r.cull.enabled=!0,r.cull.face=D.FRONT,r.colorMask={red:!1,green:!1,blue:!1,alpha:!1},r.polygonOffset={enabled:!0,factor:5,units:5},t.renderState=b.fromCache(r),t.castShadows=!1,t.receiveShadows=!1,t}function re(e,t){var r=e;if(e.renderState.depthMask){r=_.shallowClone(e);var i=n(r.renderState,!0);i.stencilTest.enabled=!0,i.stencilTest.mask=240,i.stencilTest.reference=t<<4,i.stencilTest.frontFunction=O.GREATER_OR_EQUAL,i.stencilTest.frontOperation.zPass=M.REPLACE,r.renderState=b.fromCache(i)}return r}function ie(e){var t=n(e,!0);return t.cull.enabled=!1,t.depthTest.enabled=!0,t.depthMask=!1,t.blending=x.ALPHA_BLEND,b.fromCache(t)}function ne(e,t,r){var i=e._textureDimensions;return new w({context:t,pixelFormat:f.RGBA,pixelDatatype:y.UNSIGNED_BYTE,source:{width:i.x,height:i.y,arrayBufferView:r},sampler:new C({minificationFilter:E.NEAREST,magnificationFilter:T.NEAREST})})}function oe(e,t){var r=e.featuresLength;if(!u(e._pickTexture)&&r>0){for(var i=e._pickIds,n=N(e),a=new Uint8Array(n),s=e._content,l=0;l<r;++l){var c=t.createPickId(s.getFeature(l));i.push(c);var d=c.color,h=4*l;a[h]=o.floatToByte(d.red),a[h+1]=o.floatToByte(d.green),a[h+2]=o.floatToByte(d.blue),a[h+3]=o.floatToByte(d.alpha)}e._pickTexture=ne(e,t,a),s._tileset._statistics.batchTableByteLength+=e._pickTexture.sizeInBytes}}function ae(e){var t=e._textureDimensions;e._batchTexture.copyFrom({width:t.x,height:t.y,arrayBufferView:e._batchValues})}var se=o.WHITE;c(R.prototype,{memorySizeInBytes:{get:function(){var e=0;return u(this._pickTexture)&&(e+=this._pickTexture.sizeInBytes),u(this._batchTexture)&&(e+=this._batchTexture.sizeInBytes),e}}}),R.getBinaryProperties=function(e,t,r){var i;for(var n in t)if(t.hasOwnProperty(n)){var o=t[n],a=o.byteOffset;if(u(a)){var s=o.componentType,l=o.type;if(!u(s))throw new m("componentType is required.");if(!u(l))throw new m("type is required.");if(!u(r))throw new m("Property "+n+" requires a batch table binary.");var c=I(o),d=c.componentsPerAttribute,h=c.classType,p=c.createArrayBufferView(r.buffer,r.byteOffset+a,e);u(i)||(i={}),i[n]={typedArray:p,componentCount:d,type:h}}}return i},R.prototype.setShow=function(e,t){if(!t||u(this._showAlphaProperties)){var r=F(this),i=2*e,n=t?255:0;if(r[i]!==n){r[i]=n;k(this)[4*e+3]=t?r[i+1]:0,this._batchValuesDirty=!0}}},R.prototype.setAllShow=function(e){for(var t=this.featuresLength,r=0;r<t;++r)this.setShow(r,e)},R.prototype.getShow=function(e){if(!u(this._showAlphaProperties))return!0;var t=2*e;return 255===this._showAlphaProperties[t]};var le=new Array(4);R.prototype.setColor=function(e,t){if(!o.equals(t,se)||u(this._batchValues)){var r=t.toBytes(le),i=r[3],n=k(this),a=4*e,s=F(this),l=2*e;if(n[a]!==r[0]||n[a+1]!==r[1]||n[a+2]!==r[2]||s[l+1]!==i){n[a]=r[0],n[a+1]=r[1],n[a+2]=r[2];var c=255!==s[l+1],d=0!==s[l];n[a+3]=d?i:0,s[l+1]=i;var h=255!==i;h&&!c?++this._translucentFeaturesLength:!h&&c&&--this._translucentFeaturesLength,this._batchValuesDirty=!0,u(this._colorChangedCallback)&&this._colorChangedCallback(e,t)}}},R.prototype.setAllColor=function(e){for(var t=this.featuresLength,r=0;r<t;++r)this.setColor(r,e)},R.prototype.getColor=function(e,t){if(!u(this._batchValues))return o.clone(se,t);var r=this._batchValues,i=4*e,n=this._showAlphaProperties,a=2*e;return o.fromBytes(r[i],r[i+1],r[i+2],n[a+1],t)};var ue=new o;R.prototype.applyStyle=function(e,t){if(!u(t))return this.setAllColor(se),void this.setAllShow(!0);for(var r=this._content,i=this.featuresLength,n=0;n<i;++n){var o=r.getFeature(n),a=u(t.color)?t.color.evaluateColor(e,o,ue):se,s=!u(t.show)||t.show.evaluate(e,o);this.setColor(n,a),this.setShow(n,s)}};var ce=[],de=[],he=0;R.prototype.isClass=function(e,t){var r=this._batchTableHierarchy;if(!u(r))return!1;var i=G(r,e,function(e,r){var i=e.classIds[r];if(e.classes[i].name===t)return!0});return u(i)},R.prototype.isExactClass=function(e,t){return this.getExactClassName(e)===t},R.prototype.getExactClassName=function(e){var t=this._batchTableHierarchy;if(u(t)){var r=t.classIds[e];return t.classes[r].name}},R.prototype.hasProperty=function(e,t){var r=this.batchTableJson;return u(r)&&u(r[t])||u(this._batchTableHierarchy)&&W(this,e,t)},R.prototype.getPropertyNames=function(e,t){t=u(t)?t:[],t.length=0;var r=this.batchTableJson;for(var i in r)r.hasOwnProperty(i)&&t.push(i);return u(this._batchTableHierarchy)&&H(this,e,t),t},R.prototype.getProperty=function(e,t){if(u(this.batchTableJson)){if(u(this._batchTableBinaryProperties)){var r=this._batchTableBinaryProperties[t];if(u(r))return B(r,e)}var i=this.batchTableJson[t];if(u(i))return n(i[e],!0) +;if(u(this._batchTableHierarchy)){var o=j(this,e,t);if(u(o))return o}}},R.prototype.setProperty=function(e,t,r){var i=this.featuresLength;if(u(this._batchTableBinaryProperties)){var o=this._batchTableBinaryProperties[t];if(u(o))return void U(o,e,r)}if(!u(this._batchTableHierarchy)||!q(this,e,t,r)){u(this.batchTableJson)||(this.batchTableJson={});var a=this.batchTableJson[t];u(a)||(this.batchTableJson[t]=new Array(i),a=this.batchTableJson[t]),a[e]=n(r,!0)}},R.prototype.getVertexShaderCallback=function(e,t,r){if(0!==this.featuresLength){var i=this;return function(n){var o,a=Q(n,r,!1);return g.maximumVertexTextureImageUnits>0?(o="",e&&(o+="uniform bool tile_translucentCommand; \n"),o+="uniform sampler2D tile_batchTexture; \nvarying vec4 tile_featureColor; \nvoid main() \n{ \n vec2 st = computeSt("+t+"); \n vec4 featureProperties = texture2D(tile_batchTexture, st); \n tile_color(featureProperties); \n float show = ceil(featureProperties.a); \n gl_Position *= show; \n",e&&(o+=" bool isStyleTranslucent = (featureProperties.a != 1.0); \n if (czm_pass == czm_passTranslucent) \n { \n if (!isStyleTranslucent && !tile_translucentCommand) \n { \n gl_Position *= 0.0; \n } \n } \n else \n { \n if (isStyleTranslucent) \n { \n gl_Position *= 0.0; \n } \n } \n"),o+=" tile_featureColor = featureProperties; \n}"):o="varying vec2 tile_featureSt; \nvoid main() \n{ \n tile_color(vec4(1.0)); \n tile_featureSt = computeSt("+t+"); \n}",a+"\n"+Y(i)+o}}},R.prototype.getFragmentShaderCallback=function(e,t){if(0!==this.featuresLength)return function(r){return r=Q(r,t,!0),g.maximumVertexTextureImageUnits>0?r+="varying vec4 tile_featureColor; \nvoid main() \n{ \n tile_color(tile_featureColor); \n}":(e&&(r+="uniform bool tile_translucentCommand; \n"),r+="uniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n if (featureProperties.a == 0.0) { \n discard; \n } \n",e&&(r+=" bool isStyleTranslucent = (featureProperties.a != 1.0); \n if (czm_pass == czm_passTranslucent) \n { \n if (!isStyleTranslucent && !tile_translucentCommand) \n { \n discard; \n } \n } \n else \n { \n if (isStyleTranslucent) \n { \n discard; \n } \n } \n"),r+=" tile_color(featureProperties); \n} \n"),r}},R.prototype.getClassificationFragmentShaderCallback=function(){if(0!==this.featuresLength)return function(e){return e=S.replaceMain(e,"tile_main"),g.maximumVertexTextureImageUnits>0?e+="varying vec4 tile_featureColor; \nvoid main() \n{ \n gl_FragColor = tile_featureColor; \n}":e+="uniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n if (featureProperties.a == 0.0) { \n discard; \n } \n gl_FragColor = featureProperties; \n} \n",e}},R.prototype.getUniformMapCallback=function(){if(0!==this.featuresLength){var e=this;return function(t){return a(t,{tile_batchTexture:function(){return l(e._batchTexture,e._defaultTexture)},tile_textureDimensions:function(){return e._textureDimensions},tile_textureStep:function(){return e._textureStep},tile_colorBlend:function(){return Z(e)}})}}},R.prototype.getPickVertexShaderCallback=function(e){if(0!==this.featuresLength){var t=this;return function(r){var i,n=S.replaceMain(r,"tile_main");return i=g.maximumVertexTextureImageUnits>0?"uniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n vec2 st = computeSt("+e+"); \n vec4 featureProperties = texture2D(tile_batchTexture, st); \n float show = ceil(featureProperties.a); \n gl_Position *= show; \n tile_featureSt = st; \n}":"varying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n tile_featureSt = computeSt("+e+"); \n}",n+"\n"+Y(t)+i}}},R.prototype.getPickFragmentShaderCallback=function(){if(0!==this.featuresLength)return function(e){var t,r=S.replaceMain(e,"tile_main");return t=g.maximumVertexTextureImageUnits>0?"uniform sampler2D tile_pickTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n if (gl_FragColor.a == 0.0) { \n discard; \n } \n gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n}":"uniform sampler2D tile_pickTexture; \nuniform sampler2D tile_batchTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n if (featureProperties.a == 0.0) { \n discard; \n } \n tile_main(); \n if (gl_FragColor.a == 0.0) { \n discard; \n } \n gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n}",r+"\n"+t}},R.prototype.getPickVertexShaderCallbackIgnoreShow=function(e){if(0!==this.featuresLength){var t=this;return function(r){var i=S.replaceMain(r,"tile_main"),n="varying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n tile_featureSt = computeSt("+e+"); \n}";return i+"\n"+Y(t)+n}}},R.prototype.getPickFragmentShaderCallbackIgnoreShow=function(){if(0!==this.featuresLength)return function(e){return S.replaceMain(e,"tile_main")+"\nuniform sampler2D tile_pickTexture; \nvarying vec2 tile_featureSt; \nvoid main() \n{ \n tile_main(); \n gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n}"}},R.prototype.getPickUniformMapCallback=function(){if(0!==this.featuresLength){var e=this;return function(t){return a({tile_batchTexture:function(){return l(e._batchTexture,e._defaultTexture)},tile_textureDimensions:function(){return e._textureDimensions},tile_textureStep:function(){return e._textureStep},tile_pickTexture:function(){return e._pickTexture}},t)}}};var pe={ALL_OPAQUE:0,ALL_TRANSLUCENT:1,OPAQUE_AND_TRANSLUCENT:2};return R.prototype.addDerivedCommands=function(e,t,r){for(var i=e.commandList,n=i.length,o=this._content._tile,a=o._tileset,s=a._skipLevelOfDetail&&a._hasMixedContent&&e.context.stencilBuffer,l=J(this),c=t;c<n;++c){var d=i[c],h=d.derivedCommands.tileset;u(h)||(h={},d.derivedCommands.tileset=h,h.originalCommand=$(d)),K(h.originalCommand,d),l!==pe.ALL_OPAQUE&&(u(h.translucent)||(h.translucent=ee(h.originalCommand)),K(h.translucent,d)),s&&(d.pass===v.TRANSLUCENT||r||(u(h.zback)||(h.zback=te(h.originalCommand)),a._backfaceCommands.push(h.zback)),u(h.stencil)&&o._selectionDepth===o._lastSelectionDepth||(h.stencil=re(h.originalCommand,o._selectionDepth),o._lastSelectionDepth=o._selectionDepth),K(h.stencil,d));var p=s?h.stencil:h.originalCommand,f=h.translucent;d.pass!==v.TRANSLUCENT?(l===pe.ALL_OPAQUE&&(i[c]=p),l===pe.ALL_TRANSLUCENT&&(i[c]=f),l===pe.OPAQUE_AND_TRANSLUCENT&&(i[c]=p,i.push(f))):i[c]=p}},R.prototype.update=function(e,t){var r=t.context;this._defaultTexture=r.defaultTexture,t.passes.pick&&oe(this,r),this._batchValuesDirty&&(this._batchValuesDirty=!1,u(this._batchTexture)||(this._batchTexture=ne(this,r,this._batchValues),e._statistics.batchTableByteLength+=this._batchTexture.sizeInBytes),ae(this))},R.prototype.isDestroyed=function(){return!1},R.prototype.destroy=function(){this._batchTexture=this._batchTexture&&this._batchTexture.destroy(),this._pickTexture=this._pickTexture&&this._pickTexture.destroy();for(var e=this._pickIds,t=e.length,r=0;r<t;++r)e[r].destroy();return d(this)},R}),define("Scene/Cesium3DTileFeature",["../Core/Color","../Core/defined","../Core/defineProperties"],function(e,t,r){"use strict";function i(e,t){this._content=e,this._batchId=t,this._color=void 0}return r(i.prototype,{show:{get:function(){return this._content.batchTable.getShow(this._batchId)},set:function(e){this._content.batchTable.setShow(this._batchId,e)}},color:{get:function(){return t(this._color)||(this._color=new e),this._content.batchTable.getColor(this._batchId,this._color)},set:function(e){this._content.batchTable.setColor(this._batchId,e)}},content:{get:function(){return this._content}},tileset:{get:function(){return this._content.tileset}},primitive:{get:function(){return this._content.tileset}}}),i.prototype.hasProperty=function(e){return this._content.batchTable.hasProperty(this._batchId,e)},i.prototype.getPropertyNames=function(e){return this._content.batchTable.getPropertyNames(this._batchId,e)},i.prototype.getProperty=function(e){return this._content.batchTable.getProperty(this._batchId,e)},i.prototype.setProperty=function(e,t){this._content.batchTable.setProperty(this._batchId,e,t),this._content.featurePropertiesDirty=!0},i.prototype.isExactClass=function(e){return this._content.batchTable.isExactClass(this._batchId,e)},i.prototype.isClass=function(e){return this._content.batchTable.isClass(this._batchId,e)},i.prototype.getExactClassName=function(){return this._content.batchTable.getExactClassName(this._batchId)},i}),define("Scene/Cesium3DTileFeatureTable",["../Core/ComponentDatatype","../Core/defaultValue","../Core/defined"],function(e,t,r){"use strict";function i(e,t){this.json=e,this.buffer=t,this._cachedTypedArrays={},this.featuresLength=0}function n(t,i,n,o,a,s){var l=t._cachedTypedArrays,u=l[i];return r(u)||(u=e.createArrayBufferView(n,t.buffer.buffer,t.buffer.byteOffset+s,a*o),l[i]=u),u}function o(t,i,n,o){var a=t._cachedTypedArrays,s=a[i];return r(s)||(s=e.createTypedArray(n,o),a[i]=s),s}return i.prototype.getGlobalProperty=function(i,o,a){var s=this.json[i];if(r(s))return r(s.byteOffset)?(o=t(o,e.UNSIGNED_INT),a=t(a,1),n(this,i,o,a,1,s.byteOffset)):s},i.prototype.getPropertyArray=function(t,i,a){var s=this.json[t];if(r(s))return r(s.byteOffset)?(r(s.componentType)&&(i=e.fromName(s.componentType)),n(this,t,i,a,this.featuresLength,s.byteOffset)):o(this,t,i,s)},i.prototype.getProperty=function(e,t,i,n,o){var a=this.json[e];if(r(a)){var s=this.getPropertyArray(e,t,i);if(1===i)return s[n];for(var l=0;l<i;++l)o[l]=s[i*n+l];return o}},i}),define("Scene/Vector3DTileBatch",[],function(){"use strict";function e(e){this.offset=e.offset,this.count=e.count,this.color=e.color,this.batchIds=e.batchIds}return e}),define("ThirdParty/jsep",[],function(){if(function(e){"use strict";var t=function(e,t){var r=new Error(e+" at character "+t);throw r.index=t,r.description=e,r},r={"-":!0,"!":!0,"~":!0,"+":!0},i={"||":1,"&&":2,"|":3,"^":4,"&":5,"==":6,"!=":6,"===":6,"!==":6,"<":7,">":7,"<=":7,">=":7,"<<":8,">>":8,">>>":8,"+":9,"-":9,"*":10,"/":10,"%":10},n=function(e){var t,r=0;for(var i in e)(t=i.length)>r&&e.hasOwnProperty(i)&&(r=t);return r},o=n(r),a=n(i),s={true:!0,false:!1,null:null},l=function(e){return i[e]||0},u=function(e,t,r){return{type:"||"===e||"&&"===e?"LogicalExpression":"BinaryExpression",operator:e,left:t,right:r}},c=function(e){return e>=48&&e<=57},d=function(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||e>=128&&!i[String.fromCharCode(e)]},h=function(e){return 36===e||95===e||e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||e>=128&&!i[String.fromCharCode(e)]},p=function(e){for(var n,p,f=0,m=e.charAt,g=e.charCodeAt,_=function(t){return m.call(e,t)},v=function(t){return g.call(e,t)},y=e.length,b=function(){for(var e=v(f);32===e||9===e;)e=v(++f)},C=function(){var e,r,i=w();return b(),63!==v(f)?i:(f++,e=C(),e||t("Expected expression",f),b(),58===v(f)?(f++,r=C(),r||t("Expected expression",f),{type:"ConditionalExpression",test:i,consequent:e,alternate:r}):void t("Expected :",f))},S=function(){b();for(var t=e.substr(f,a),r=t.length;r>0;){if(i.hasOwnProperty(t))return f+=r,t;t=t.substr(0,--r)}return!1},w=function(){var e,r,i,n,o,a,s,c;if(a=T(),!(r=S()))return a;for(o={value:r,prec:l(r)},s=T(),s||t("Expected expression after "+r,f),n=[a,o,s];(r=S())&&0!==(i=l(r));){for(o={value:r,prec:i};n.length>2&&i<=n[n.length-2].prec;)s=n.pop(),r=n.pop().value,a=n.pop(),e=u(r,a,s),n.push(e);e=T(),e||t("Expected expression after "+r,f),n.push(o,e)}for(c=n.length-1,e=n[c];c>1;)e=u(n[c-1].value,n[c-2],e),c-=2;return e},T=function(){var t,i,n;if(b(),t=v(f),c(t)||46===t)return E();if(39===t||34===t)return A();if(d(t)||40===t)return D();if(91===t)return O();for(i=e.substr(f,o),n=i.length;n>0;){if(r.hasOwnProperty(i))return f+=n,{type:"UnaryExpression",operator:i,argument:T(),prefix:!0};i=i.substr(0,--n)}return!1},E=function(){for(var e,r,i="";c(v(f));)i+=_(f++);if(46===v(f))for(i+=_(f++);c(v(f));)i+=_(f++);if("e"===(e=_(f))||"E"===e){for(i+=_(f++),e=_(f),"+"!==e&&"-"!==e||(i+=_(f++));c(v(f));)i+=_(f++);c(v(f-1))||t("Expected exponent ("+i+_(f)+")",f)}return r=v(f),d(r)?t("Variable names cannot start with a number ("+i+_(f)+")",f):46===r&&t("Unexpected period",f),{type:"Literal",value:parseFloat(i),raw:i}},A=function(){for(var e,r="",i=_(f++),n=!1;f<y;){if((e=_(f++))===i){n=!0;break}if("\\"===e)switch(e=_(f++)){case"n":r+="\n";break;case"r":r+="\r";break;case"t":r+="\t";break;case"b":r+="\b";break;case"f":r+="\f";break;case"v":r+="\v";break;default:r+="\\"+e}else r+=e}return n||t('Unclosed quote after "'+r+'"',f),{type:"Literal",value:r,raw:i+r+i}},x=function(){var r,i=v(f),n=f;for(d(i)?f++:t("Unexpected "+_(f),f);f<y&&(i=v(f),h(i));)f++;return r=e.slice(n,f),s.hasOwnProperty(r)?{type:"Literal",value:s[r],raw:r}:"this"===r?{type:"ThisExpression"}:{type:"Identifier",name:r}},P=function(e){for(var r,i,n=[],o=!1;f<y;){if(b(),(r=v(f))===e){o=!0,f++;break}44===r?f++:(i=C(),i&&"Compound"!==i.type||t("Expected comma",f),n.push(i))}return o||t("Expected "+String.fromCharCode(e),f),n},D=function(){var e,r;for(e=v(f),r=40===e?I():x(),b(),e=v(f);46===e||91===e||40===e;)f++,46===e?(b(),r={type:"MemberExpression",computed:!1,object:r,property:x()}):91===e?(r={type:"MemberExpression",computed:!0,object:r,property:C()},b(),e=v(f),93!==e&&t("Unclosed [",f),f++):40===e&&(r={type:"CallExpression",arguments:P(41),callee:r}),b(),e=v(f);return r},I=function(){f++;var e=C();if(b(),41===v(f))return f++,e;t("Unclosed (",f)},O=function(){return f++,{type:"ArrayExpression",elements:P(93)}},M=[];f<y;)n=v(f),59===n||44===n?f++:(p=C())?M.push(p):f<y&&t('Unexpected "'+_(f)+'"',f);return 1===M.length?M[0]:{type:"Compound",body:M}};if(p.version="0.3.1",p.toString=function(){return"JavaScript Expression Parser (JSEP) v"+p.version},p.addUnaryOp=function(e){return o=Math.max(e.length,o),r[e]=!0,this},p.addBinaryOp=function(e,t){return a=Math.max(e.length,a),i[e]=t,this},p.addLiteral=function(e,t){return s[e]=t,this},p.removeUnaryOp=function(e){return delete r[e],e.length===o&&(o=n(r)),this},p.removeAllUnaryOps=function(){return r={},o=0,this},p.removeBinaryOp=function(e){return delete i[e],e.length===a&&(a=n(i)),this},p.removeAllBinaryOps=function(){return i={},a=0,this},p.removeLiteral=function(e){return delete s[e],this},p.removeAllLiterals=function(){return s={},this},"undefined"==typeof exports){var f=e.jsep;e.jsep=p,p.noConflict=function(){return e.jsep===p&&(e.jsep=f),p}}else"undefined"!=typeof module&&module.exports?exports=module.exports=p:exports.parse=p}(this),"undefined"!=typeof jsep)return jsep.noConflict()}),define("Scene/ExpressionNodeType",["../Core/freezeObject"],function(e){"use strict";return e({VARIABLE:0,UNARY:1,BINARY:2,TERNARY:3,CONDITIONAL:4,MEMBER:5,FUNCTION_CALL:6,ARRAY:7,REGEX:8,VARIABLE_IN_STRING:9,LITERAL_NULL:10,LITERAL_BOOLEAN:11,LITERAL_NUMBER:12,LITERAL_STRING:13,LITERAL_COLOR:14,LITERAL_VECTOR:15,LITERAL_REGEX:16,LITERAL_UNDEFINED:17,BUILTIN_VARIABLE:18})}),define("Scene/Expression",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Check","../Core/Color","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/isArray","../Core/Math","../Core/RuntimeError","../ThirdParty/jsep","./ExpressionNodeType"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e,t){this._expression=e,e=A(e,t),e=D(x(e)),d.addBinaryOp("=~",0),d.addBinaryOp("!~",0);var r;try{r=d(e)}catch(e){throw new c(e)}this._runtimeAst=V(this,r)}function f(e){return e-Math.floor(e)}function m(e){return Math.pow(2,e)}function g(e){return u.logBase(e,2)}function _(i){return function(n,o){if("number"==typeof o)return i(o);if(o instanceof e)return e.fromElements(i(o.x),i(o.y),$.getCartesian2());if(o instanceof t)return t.fromElements(i(o.x),i(o.y),i(o.z),$.getCartesian3());if(o instanceof r)return r.fromElements(i(o.x),i(o.y),i(o.z),i(o.w),$.getCartesian4());throw new c('Function "'+n+'" requires a vector or number argument. Argument is '+o+".")}}function v(i,n){return function(o,a,s){if(n&&"number"==typeof s){if("number"==typeof a)return i(a,s);if(a instanceof e)return e.fromElements(i(a.x,s),i(a.y,s),$.getCartesian2());if(a instanceof t)return t.fromElements(i(a.x,s),i(a.y,s),i(a.z,s),$.getCartesian3());if(a instanceof r)return r.fromElements(i(a.x,s),i(a.y,s),i(a.z,s),i(a.w,s),$.getCartesian4())}if("number"==typeof a&&"number"==typeof s)return i(a,s);if(a instanceof e&&s instanceof e)return e.fromElements(i(a.x,s.x),i(a.y,s.y),$.getCartesian2());if(a instanceof t&&s instanceof t)return t.fromElements(i(a.x,s.x),i(a.y,s.y),i(a.z,s.z),$.getCartesian3());if(a instanceof r&&s instanceof r)return r.fromElements(i(a.x,s.x),i(a.y,s.y),i(a.z,s.z),i(a.w,s.w),$.getCartesian4());throw new c('Function "'+o+'" requires vector or number arguments of matching types. Arguments are '+a+" and "+s+".")}}function y(i,n){return function(o,a,s,l){if(n&&"number"==typeof l){if("number"==typeof a&&"number"==typeof s)return i(a,s,l);if(a instanceof e&&s instanceof e)return e.fromElements(i(a.x,s.x,l),i(a.y,s.y,l),$.getCartesian2());if(a instanceof t&&s instanceof t)return t.fromElements(i(a.x,s.x,l),i(a.y,s.y,l),i(a.z,s.z,l),$.getCartesian3());if(a instanceof r&&s instanceof r)return r.fromElements(i(a.x,s.x,l),i(a.y,s.y,l),i(a.z,s.z,l),i(a.w,s.w,l),$.getCartesian4())}if("number"==typeof a&&"number"==typeof s&&"number"==typeof l)return i(a,s,l);if(a instanceof e&&s instanceof e&&l instanceof e)return e.fromElements(i(a.x,s.x,l.x),i(a.y,s.y,l.y),$.getCartesian2());if(a instanceof t&&s instanceof t&&l instanceof t)return t.fromElements(i(a.x,s.x,l.x),i(a.y,s.y,l.y),i(a.z,s.z,l.z),$.getCartesian3());if(a instanceof r&&s instanceof r&&l instanceof r)return r.fromElements(i(a.x,s.x,l.x),i(a.y,s.y,l.y),i(a.z,s.z,l.z),i(a.w,s.w,l.w),$.getCartesian4());throw new c('Function "'+o+'" requires vector or number arguments of matching types. Arguments are '+a+", "+s+", and "+l+".")}}function b(i,n){if("number"==typeof n)return Math.abs(n);if(n instanceof e)return e.magnitude(n);if(n instanceof t)return t.magnitude(n);if(n instanceof r)return r.magnitude(n);throw new c('Function "'+i+'" requires a vector or number argument. Argument is '+n+".")}function C(i,n){if("number"==typeof n)return 1;if(n instanceof e)return e.normalize(n,$.getCartesian2());if(n instanceof t)return t.normalize(n,$.getCartesian3());if(n instanceof r)return r.normalize(n,$.getCartesian4());throw new c('Function "'+i+'" requires a vector or number argument. Argument is '+n+".")}function S(i,n,o){if("number"==typeof n&&"number"==typeof o)return Math.abs(n-o);if(n instanceof e&&o instanceof e)return e.distance(n,o);if(n instanceof t&&o instanceof t)return t.distance(n,o);if(n instanceof r&&o instanceof r)return r.distance(n,o);throw new c('Function "'+i+'" requires vector or number arguments of matching types. Arguments are '+n+" and "+o+".")}function w(i,n,o){if("number"==typeof n&&"number"==typeof o)return n*o;if(n instanceof e&&o instanceof e)return e.dot(n,o);if(n instanceof t&&o instanceof t)return t.dot(n,o);if(n instanceof r&&o instanceof r)return r.dot(n,o);throw new c('Function "'+i+'" requires vector or number arguments of matching types. Arguments are '+n+" and "+o+".")}function T(e,r,i){if(r instanceof t&&i instanceof t)return t.cross(r,i,$.getCartesian3());throw new c('Function "'+e+'" requires vec3 arguments. Arguments are '+r+" and "+i+".")}function E(e,t,r,i,n){this._type=e,this._value=t,this._left=r,this._right=i,this._test=n,this.evaluate=void 0,z(this)}function A(e,t){if(!o(t))return e;for(var r in t)if(t.hasOwnProperty(r)){var i=new RegExp("\\$\\{"+r+"\\}","g"),n="("+t[r]+")";o(n)&&(e=e.replace(i,n))}return e}function x(e){return e.replace(ie,ne)}function P(e){return e.replace(oe,"\\")}function D(e){for(var t=e,r="",i=t.indexOf("${");i>=0;){var n,o=t.indexOf("'"),a=t.indexOf('"');if(o>=0&&o<i)n=t.indexOf("'",o+1),r+=t.substr(0,n+1),t=t.substr(n+1),i=t.indexOf("${");else if(a>=0&&a<i)n=t.indexOf('"',a+1),r+=t.substr(0,n+1),t=t.substr(n+1),i=t.indexOf("${");else{r+=t.substr(0,i);var s=t.indexOf("}");if(s<0)throw new c("Unmatched {.");r+="czm_"+t.substr(i+2,s-(i+2)),t=t.substr(s+1),i=t.indexOf("${")}}return r+=t}function I(e){var t=typeof e.value;return null===e.value?new E(h.LITERAL_NULL,null):"boolean"===t?new E(h.LITERAL_BOOLEAN,e.value):"number"===t?new E(h.LITERAL_NUMBER,e.value):"string"===t?e.value.indexOf("${")>=0?new E(h.VARIABLE_IN_STRING,e.value):new E(h.LITERAL_STRING,P(e.value)):void 0}function O(e,t){var r,i,n,a,s=t.arguments,l=s.length;if("MemberExpression"===t.callee.type){r=t.callee.property.name;var u=t.callee.object;if("test"===r||"exec"===r){if("regExp"!==u.callee.name)throw new c(r+" is not a function.");return 0===l?"test"===r?new E(h.LITERAL_BOOLEAN,!1):new E(h.LITERAL_NULL,null):(n=V(e,u),a=V(e,s[0]),new E(h.FUNCTION_CALL,r,n,a))}if("toString"===r)return i=V(e,u),new E(h.FUNCTION_CALL,r,i);throw new c('Unexpected function call "'+r+'".')}if("color"===(r=t.callee.name)){if(0===l)return new E(h.LITERAL_COLOR,r);if(i=V(e,s[0]),o(s[1])){var d=V(e,s[1]);return new E(h.LITERAL_COLOR,r,[i,d])}return new E(h.LITERAL_COLOR,r,[i])}if("rgb"===r||"hsl"===r){if(l<3)throw new c(r+" requires three arguments.");return i=[V(e,s[0]),V(e,s[1]),V(e,s[2])],new E(h.LITERAL_COLOR,r,i)}if("rgba"===r||"hsla"===r){if(l<4)throw new c(r+" requires four arguments.");return i=[V(e,s[0]),V(e,s[1]),V(e,s[2]),V(e,s[3])],new E(h.LITERAL_COLOR,r,i)}if("vec2"===r||"vec3"===r||"vec4"===r){i=new Array(l);for(var p=0;p<l;++p)i[p]=V(e,s[p]);return new E(h.LITERAL_VECTOR,r,i)}if("isNaN"===r||"isFinite"===r)return 0===l?"isNaN"===r?new E(h.LITERAL_BOOLEAN,!0):new E(h.LITERAL_BOOLEAN,!1):(i=V(e,s[0]),new E(h.UNARY,r,i));if("isExactClass"===r||"isClass"===r){if(l<1||l>1)throw new c(r+" requires exactly one argument.");return i=V(e,s[0]),new E(h.UNARY,r,i)}if("getExactClassName"===r){if(l>0)throw new c(r+" does not take any argument.");return new E(h.UNARY,r)}if(o(se[r])){if(1!==l)throw new c(r+" requires exactly one argument.");return i=V(e,s[0]),new E(h.UNARY,r,i)}if(o(le[r])){if(2!==l)throw new c(r+" requires exactly two arguments.");return n=V(e,s[0]),a=V(e,s[1]),new E(h.BINARY,r,n,a)}if(o(ue[r])){if(3!==l)throw new c(r+" requires exactly three arguments.");n=V(e,s[0]),a=V(e,s[1]);var f=V(e,s[2]);return new E(h.TERNARY,r,n,a,f)}if("Boolean"===r)return 0===l?new E(h.LITERAL_BOOLEAN,!1):(i=V(e,s[0]),new E(h.UNARY,r,i));if("Number"===r)return 0===l?new E(h.LITERAL_NUMBER,0):(i=V(e,s[0]),new E(h.UNARY,r,i));if("String"===r)return 0===l?new E(h.LITERAL_STRING,""):(i=V(e,s[0]),new E(h.UNARY,r,i));if("regExp"===r)return M(e,t);throw new c('Unexpected function call "'+r+'".')}function M(e,t){var r=t.arguments;if(0===r.length)return new E(h.LITERAL_REGEX,new RegExp);var i,n=V(e,r[0]);if(r.length>1){var o=V(e,r[1]);if(F(n)&&F(o)){try{i=new RegExp(P(String(n._value)),o._value)}catch(e){throw new c(e)}return new E(h.LITERAL_REGEX,i)}return new E(h.REGEX,n,o)}if(F(n)){try{i=new RegExp(P(String(n._value)))}catch(e){throw new c(e)}return new E(h.LITERAL_REGEX,i)}return new E(h.REGEX,n)}function R(e){if(B(e.name)){var t=U(e.name);return"tiles3d_"===t.substr(0,8)?new E(h.BUILTIN_VARIABLE,t):new E(h.VARIABLE,t)}if("NaN"===e.name)return new E(h.LITERAL_NUMBER,NaN);if("Infinity"===e.name)return new E(h.LITERAL_NUMBER,1/0);if("undefined"===e.name)return new E(h.LITERAL_UNDEFINED,void 0);throw new c(e.name+" is not defined.")}function L(e){var t=e.property.name;return"PI"===t?new E(h.LITERAL_NUMBER,Math.PI):"E"===t?new E(h.LITERAL_NUMBER,Math.E):void 0}function N(e){if("POSITIVE_INFINITY"===e.property.name)return new E(h.LITERAL_NUMBER,Number.POSITIVE_INFINITY)}function k(e,t){if("Math"===t.object.name)return L(t);if("Number"===t.object.name)return N(t);var r,i=V(e,t.object);return t.computed?(r=V(e,t.property),new E(h.MEMBER,"brackets",i,r)):(r=new E(h.LITERAL_STRING,t.property.name),new E(h.MEMBER,"dot",i,r))}function F(e){return e._type>=h.LITERAL_NULL}function B(e){return"czm_"===e.substr(0,4)}function U(e){return e.substr(4)}function V(e,t){var r,i,n,o;if("Literal"===t.type)r=I(t);else if("CallExpression"===t.type)r=O(e,t);else if("Identifier"===t.type)r=R(t);else if("UnaryExpression"===t.type){i=t.operator;var a=V(e,t.argument);if(!(ee.indexOf(i)>-1))throw new c('Unexpected operator "'+i+'".');r=new E(h.UNARY,i,a)}else if("BinaryExpression"===t.type){if(i=t.operator,n=V(e,t.left),o=V(e,t.right),!(te.indexOf(i)>-1))throw new c('Unexpected operator "'+i+'".');r=new E(h.BINARY,i,n,o)}else if("LogicalExpression"===t.type)i=t.operator,n=V(e,t.left),o=V(e,t.right),te.indexOf(i)>-1&&(r=new E(h.BINARY,i,n,o));else if("ConditionalExpression"===t.type){var s=V(e,t.test);n=V(e,t.consequent),o=V(e,t.alternate),r=new E(h.CONDITIONAL,"?",n,o,s)}else if("MemberExpression"===t.type)r=k(e,t);else{if("ArrayExpression"!==t.type)throw new c("Compound"===t.type?"Provide exactly one expression.":"Cannot parse expression.");for(var l=[],u=0;u<t.elements.length;u++)l[u]=V(e,t.elements[u]);r=new E(h.ARRAY,l)}return r}function z(e){e._type===h.CONDITIONAL?e.evaluate=e._evaluateConditional:e._type===h.FUNCTION_CALL?"test"===e._value?e.evaluate=e._evaluateRegExpTest:"exec"===e._value?e.evaluate=e._evaluateRegExpExec:"toString"===e._value&&(e.evaluate=e._evaluateToString):e._type===h.UNARY?"!"===e._value?e.evaluate=e._evaluateNot:"-"===e._value?e.evaluate=e._evaluateNegative:"+"===e._value?e.evaluate=e._evaluatePositive:"isNaN"===e._value?e.evaluate=e._evaluateNaN:"isFinite"===e._value?e.evaluate=e._evaluateIsFinite:"isExactClass"===e._value?e.evaluate=e._evaluateIsExactClass:"isClass"===e._value?e.evaluate=e._evaluateIsClass:"getExactClassName"===e._value?e.evaluate=e._evaluategetExactClassName:"Boolean"===e._value?e.evaluate=e._evaluateBooleanConversion:"Number"===e._value?e.evaluate=e._evaluateNumberConversion:"String"===e._value?e.evaluate=e._evaluateStringConversion:o(se[e._value])&&(e.evaluate=W(e._value)):e._type===h.BINARY?"+"===e._value?e.evaluate=e._evaluatePlus:"-"===e._value?e.evaluate=e._evaluateMinus:"*"===e._value?e.evaluate=e._evaluateTimes:"/"===e._value?e.evaluate=e._evaluateDivide:"%"===e._value?e.evaluate=e._evaluateMod:"==="===e._value?e.evaluate=e._evaluateEqualsStrict:"!=="===e._value?e.evaluate=e._evaluateNotEqualsStrict:"<"===e._value?e.evaluate=e._evaluateLessThan:"<="===e._value?e.evaluate=e._evaluateLessThanOrEquals:">"===e._value?e.evaluate=e._evaluateGreaterThan:">="===e._value?e.evaluate=e._evaluateGreaterThanOrEquals:"&&"===e._value?e.evaluate=e._evaluateAnd:"||"===e._value?e.evaluate=e._evaluateOr:"=~"===e._value?e.evaluate=e._evaluateRegExpMatch:"!~"===e._value?e.evaluate=e._evaluateRegExpNotMatch:o(le[e._value])&&(e.evaluate=H(e._value)):e._type===h.TERNARY?e.evaluate=j(e._value):e._type===h.MEMBER?"brackets"===e._value?e.evaluate=e._evaluateMemberBrackets:e.evaluate=e._evaluateMemberDot:e._type===h.ARRAY?e.evaluate=e._evaluateArray:e._type===h.VARIABLE?e.evaluate=e._evaluateVariable:e._type===h.VARIABLE_IN_STRING?e.evaluate=e._evaluateVariableString:e._type===h.LITERAL_COLOR?e.evaluate=e._evaluateLiteralColor:e._type===h.LITERAL_VECTOR?e.evaluate=e._evaluateLiteralVector:e._type===h.LITERAL_STRING?e.evaluate=e._evaluateLiteralString:e._type===h.REGEX?e.evaluate=e._evaluateRegExp:e._type===h.BUILTIN_VARIABLE?"tiles3d_tileset_time"===e._value&&(e.evaluate=G):e.evaluate=e._evaluateLiteral}function G(e,t){return t.content.tileset.timeSinceLoad}function W(e){var t=se[e];return function(r,i){var n=this._left.evaluate(r,i);return t(e,n)}}function H(e){var t=le[e];return function(r,i){var n=this._left.evaluate(r,i),o=this._right.evaluate(r,i);return t(e,n,o)}}function j(e){var t=ue[e];return function(r,i){var n=this._left.evaluate(r,i),o=this._right.evaluate(r,i),a=this._test.evaluate(r,i);return t(e,n,o,a)}}function q(e){return"feature"===e._value}function Y(e){for(var t=e._left,r=t.length,i=0;i<r;++i)if(t[i]._type!==h.LITERAL_NUMBER)return;var o=t[0]._value,a=t[1]._value,s=t[2]._value,l=4===r?t[3]._value:1;return n.fromHsl(o,a,s,l,ae)}function X(e){for(var t=e._left,r=t.length,i=0;i<r;++i)if(t[i]._type!==h.LITERAL_NUMBER)return;var n=ae;return n.red=t[0]._value/255,n.green=t[1]._value/255,n.blue=t[2]._value/255,n.alpha=4===r?t[3]._value:1,n}function Q(e){return e%1==0?e.toFixed(1):e.toString()}function Z(e){return"vec3("+Q(e.red)+", "+Q(e.green)+", "+Q(e.blue)+")"}function K(e){return"vec4("+Q(e.red)+", "+Q(e.green)+", "+Q(e.blue)+", "+Q(e.alpha)+")"}function J(e,t,r,i){for(var n=e.length,o=new Array(n),a=0;a<n;++a)o[a]=e[a].getShaderExpression(t,r,i);return o}a(p.prototype,{expression:{get:function(){return this._expression}}});var $={arrayIndex:0,arrayArray:[[]],cartesian2Index:0,cartesian3Index:0,cartesian4Index:0,cartesian2Array:[new e],cartesian3Array:[new t],cartesian4Array:[new r],reset:function(){this.arrayIndex=0,this.cartesian2Index=0,this.cartesian3Index=0,this.cartesian4Index=0},getArray:function(){this.arrayIndex>=this.arrayArray.length&&this.arrayArray.push([]);var e=this.arrayArray[this.arrayIndex++];return e.length=0,e},getCartesian2:function(){return this.cartesian2Index>=this.cartesian2Array.length&&this.cartesian2Array.push(new e),this.cartesian2Array[this.cartesian2Index++]},getCartesian3:function(){return this.cartesian3Index>=this.cartesian3Array.length&&this.cartesian3Array.push(new t),this.cartesian3Array[this.cartesian3Index++]},getCartesian4:function(){return this.cartesian4Index>=this.cartesian4Array.length&&this.cartesian4Array.push(new r),this.cartesian4Array[this.cartesian4Index++]}};p.prototype.evaluate=function(i,o,a){$.reset();var s=this._runtimeAst.evaluate(i,o);return a instanceof n&&s instanceof r?n.fromCartesian4(s,a):s instanceof e||s instanceof t||s instanceof r?s.clone(a):s},p.prototype.evaluateColor=function(e,t,r){$.reset();var i=this._runtimeAst.evaluate(e,t);return n.fromCartesian4(i,r)},p.prototype.getShaderFunction=function(e,t,r,i){var n=this.getShaderExpression(t,r);return n=i+" "+e+"() \n{ \n return "+n+"; \n} \n"},p.prototype.getShaderExpression=function(e,t){return this._runtimeAst.getShaderExpression(e,t)};var ee=["!","-","+"],te=["+","-","*","/","%","===","!==",">",">=","<","<=","&&","||","!~","=~"],re=/\${(.*?)}/g,ie=/\\/g,ne="@#%",oe=/@#%/g,ae=new n,se={abs:_(Math.abs),sqrt:_(Math.sqrt),cos:_(Math.cos),sin:_(Math.sin),tan:_(Math.tan),acos:_(Math.acos),asin:_(Math.asin),atan:_(Math.atan),radians:_(u.toRadians),degrees:_(u.toDegrees),sign:_(u.sign),floor:_(Math.floor),ceil:_(Math.ceil),round:_(Math.round),exp:_(Math.exp),exp2:_(m),log:_(Math.log),log2:_(g),fract:_(f),length:b,normalize:C},le={atan2:v(Math.atan2,!1),pow:v(Math.pow,!1),min:v(Math.min,!0),max:v(Math.max,!0),distance:S,dot:w,cross:T},ue={clamp:y(u.clamp,!0),mix:y(u.lerp,!0)};return E.prototype._evaluateLiteral=function(e,t){return this._value},E.prototype._evaluateLiteralColor=function(e,t){var i=ae,a=this._left;if("color"===this._value)o(a)?a.length>1?(n.fromCssColorString(a[0].evaluate(e,t),i),i.alpha=a[1].evaluate(e,t)):n.fromCssColorString(a[0].evaluate(e,t),i):n.fromBytes(255,255,255,255,i);else if("rgb"===this._value)n.fromBytes(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),255,i);else if("rgba"===this._value){var s=255*a[3].evaluate(e,t);n.fromBytes(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),s,i)}else"hsl"===this._value?n.fromHsl(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),1,i):"hsla"===this._value&&n.fromHsl(a[0].evaluate(e,t),a[1].evaluate(e,t),a[2].evaluate(e,t),a[3].evaluate(e,t),i);return r.fromColor(i,$.getCartesian4())},E.prototype._evaluateLiteralVector=function(i,n){ +for(var o=$.getArray(),a=this._value,s=this._left,l=s.length,u=0;u<l;++u){var d=s[u].evaluate(i,n);if("number"==typeof d)o.push(d);else if(d instanceof e)o.push(d.x,d.y);else if(d instanceof t)o.push(d.x,d.y,d.z);else{if(!(d instanceof r))throw new c(a+" argument must be a vector or number. Argument is "+d+".");o.push(d.x,d.y,d.z,d.w)}}var h=o.length,p=parseInt(a.charAt(3));if(0===h)throw new c("Invalid "+a+" constructor. No valid arguments.");if(h<p&&h>1)throw new c("Invalid "+a+" constructor. Not enough arguments.");if(h>p&&l>1)throw new c("Invalid "+a+" constructor. Too many arguments.");if(1===h){var f=o[0];o.push(f,f,f)}return"vec2"===a?e.fromArray(o,0,$.getCartesian2()):"vec3"===a?t.fromArray(o,0,$.getCartesian3()):"vec4"===a?r.fromArray(o,0,$.getCartesian4()):void 0},E.prototype._evaluateLiteralString=function(e,t){return this._value},E.prototype._evaluateVariableString=function(e,t){for(var r=this._value,i=re.exec(r);null!==i;){var n=i[0],a=i[1],s=t.getProperty(a);o(s)||(s=""),r=r.replace(n,s),i=re.exec(r)}return r},E.prototype._evaluateVariable=function(e,t){return t.getProperty(this._value)},E.prototype._evaluateMemberDot=function(i,n){if(q(this._left))return n.getProperty(this._right.evaluate(i,n));var a=this._left.evaluate(i,n);if(o(a)){var s=this._right.evaluate(i,n);if(a instanceof e||a instanceof t||a instanceof r){if("r"===s)return a.x;if("g"===s)return a.y;if("b"===s)return a.z;if("a"===s)return a.w}return a[s]}},E.prototype._evaluateMemberBrackets=function(i,n){if(q(this._left))return n.getProperty(this._right.evaluate(i,n));var a=this._left.evaluate(i,n);if(o(a)){var s=this._right.evaluate(i,n);if(a instanceof e||a instanceof t||a instanceof r){if(0===s||"r"===s)return a.x;if(1===s||"g"===s)return a.y;if(2===s||"b"===s)return a.z;if(3===s||"a"===s)return a.w}return a[s]}},E.prototype._evaluateArray=function(e,t){for(var r=[],i=0;i<this._value.length;i++)r[i]=this._value[i].evaluate(e,t);return r},E.prototype._evaluateNot=function(e,t){var r=this._left.evaluate(e,t);if("boolean"!=typeof r)throw new c('Operator "!" requires a boolean argument. Argument is '+r+".");return!r},E.prototype._evaluateNegative=function(i,n){var o=this._left.evaluate(i,n);if(o instanceof e)return e.negate(o,$.getCartesian2());if(o instanceof t)return t.negate(o,$.getCartesian3());if(o instanceof r)return r.negate(o,$.getCartesian4());if("number"==typeof o)return-o;throw new c('Operator "-" requires a vector or number argument. Argument is '+o+".")},E.prototype._evaluatePositive=function(i,n){var o=this._left.evaluate(i,n);if(!(o instanceof e||o instanceof t||o instanceof r||"number"==typeof o))throw new c('Operator "+" requires a vector or number argument. Argument is '+o+".");return o},E.prototype._evaluateLessThan=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if("number"!=typeof r||"number"!=typeof i)throw new c('Operator "<" requires number arguments. Arguments are '+r+" and "+i+".");return r<i},E.prototype._evaluateLessThanOrEquals=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if("number"!=typeof r||"number"!=typeof i)throw new c('Operator "<=" requires number arguments. Arguments are '+r+" and "+i+".");return r<=i},E.prototype._evaluateGreaterThan=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if("number"!=typeof r||"number"!=typeof i)throw new c('Operator ">" requires number arguments. Arguments are '+r+" and "+i+".");return r>i},E.prototype._evaluateGreaterThanOrEquals=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if("number"!=typeof r||"number"!=typeof i)throw new c('Operator ">=" requires number arguments. Arguments are '+r+" and "+i+".");return r>=i},E.prototype._evaluateOr=function(e,t){var r=this._left.evaluate(e,t);if("boolean"!=typeof r)throw new c('Operator "||" requires boolean arguments. First argument is '+r+".");if(r)return!0;var i=this._right.evaluate(e,t);if("boolean"!=typeof i)throw new c('Operator "||" requires boolean arguments. Second argument is '+i+".");return r||i},E.prototype._evaluateAnd=function(e,t){var r=this._left.evaluate(e,t);if("boolean"!=typeof r)throw new c('Operator "&&" requires boolean arguments. First argument is '+r+".");if(!r)return!1;var i=this._right.evaluate(e,t);if("boolean"!=typeof i)throw new c('Operator "&&" requires boolean arguments. Second argument is '+i+".");return r&&i},E.prototype._evaluatePlus=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.add(o,a,$.getCartesian2());if(a instanceof t&&o instanceof t)return t.add(o,a,$.getCartesian3());if(a instanceof r&&o instanceof r)return r.add(o,a,$.getCartesian4());if("string"==typeof o||"string"==typeof a)return o+a;if("number"==typeof o&&"number"==typeof a)return o+a;throw new c('Operator "+" requires vector or number arguments of matching types, or at least one string argument. Arguments are '+o+" and "+a+".")},E.prototype._evaluateMinus=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.subtract(o,a,$.getCartesian2());if(a instanceof t&&o instanceof t)return t.subtract(o,a,$.getCartesian3());if(a instanceof r&&o instanceof r)return r.subtract(o,a,$.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o-a;throw new c('Operator "-" requires vector or number arguments of matching types. Arguments are '+o+" and "+a+".")},E.prototype._evaluateTimes=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.multiplyComponents(o,a,$.getCartesian2());if(a instanceof e&&"number"==typeof o)return e.multiplyByScalar(a,o,$.getCartesian2());if(o instanceof e&&"number"==typeof a)return e.multiplyByScalar(o,a,$.getCartesian2());if(a instanceof t&&o instanceof t)return t.multiplyComponents(o,a,$.getCartesian3());if(a instanceof t&&"number"==typeof o)return t.multiplyByScalar(a,o,$.getCartesian3());if(o instanceof t&&"number"==typeof a)return t.multiplyByScalar(o,a,$.getCartesian3());if(a instanceof r&&o instanceof r)return r.multiplyComponents(o,a,$.getCartesian4());if(a instanceof r&&"number"==typeof o)return r.multiplyByScalar(a,o,$.getCartesian4());if(o instanceof r&&"number"==typeof a)return r.multiplyByScalar(o,a,$.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o*a;throw new c('Operator "*" requires vector or number arguments. If both arguments are vectors they must be matching types. Arguments are '+o+" and "+a+".")},E.prototype._evaluateDivide=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.divideComponents(o,a,$.getCartesian2());if(o instanceof e&&"number"==typeof a)return e.divideByScalar(o,a,$.getCartesian2());if(a instanceof t&&o instanceof t)return t.divideComponents(o,a,$.getCartesian3());if(o instanceof t&&"number"==typeof a)return t.divideByScalar(o,a,$.getCartesian3());if(a instanceof r&&o instanceof r)return r.divideComponents(o,a,$.getCartesian4());if(o instanceof r&&"number"==typeof a)return r.divideByScalar(o,a,$.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o/a;throw new c('Operator "/" requires vector or number arguments of matching types, or a number as the second argument. Arguments are '+o+" and "+a+".")},E.prototype._evaluateMod=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);if(a instanceof e&&o instanceof e)return e.fromElements(o.x%a.x,o.y%a.y,$.getCartesian2());if(a instanceof t&&o instanceof t)return t.fromElements(o.x%a.x,o.y%a.y,o.z%a.z,$.getCartesian3());if(a instanceof r&&o instanceof r)return r.fromElements(o.x%a.x,o.y%a.y,o.z%a.z,o.w%a.w,$.getCartesian4());if("number"==typeof o&&"number"==typeof a)return o%a;throw new c('Operator "%" requires vector or number arguments of matching types. Arguments are '+o+" and "+a+".")},E.prototype._evaluateEqualsStrict=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);return a instanceof e&&o instanceof e||a instanceof t&&o instanceof t||a instanceof r&&o instanceof r?o.equals(a):o===a},E.prototype._evaluateNotEqualsStrict=function(i,n){var o=this._left.evaluate(i,n),a=this._right.evaluate(i,n);return a instanceof e&&o instanceof e||a instanceof t&&o instanceof t||a instanceof r&&o instanceof r?!o.equals(a):o!==a},E.prototype._evaluateConditional=function(e,t){var r=this._test.evaluate(e,t);if("boolean"!=typeof r)throw new c("Conditional argument of conditional expression must be a boolean. Argument is "+r+".");return r?this._left.evaluate(e,t):this._right.evaluate(e,t)},E.prototype._evaluateNaN=function(e,t){return isNaN(this._left.evaluate(e,t))},E.prototype._evaluateIsFinite=function(e,t){return isFinite(this._left.evaluate(e,t))},E.prototype._evaluateIsExactClass=function(e,t){return t.isExactClass(this._left.evaluate(e,t))},E.prototype._evaluateIsClass=function(e,t){return t.isClass(this._left.evaluate(e,t))},E.prototype._evaluategetExactClassName=function(e,t){return t.getExactClassName()},E.prototype._evaluateBooleanConversion=function(e,t){return Boolean(this._left.evaluate(e,t))},E.prototype._evaluateNumberConversion=function(e,t){return Number(this._left.evaluate(e,t))},E.prototype._evaluateStringConversion=function(e,t){return String(this._left.evaluate(e,t))},E.prototype._evaluateRegExp=function(e,t){var r=this._value.evaluate(e,t),i="";o(this._left)&&(i=this._left.evaluate(e,t));var n;try{n=new RegExp(r,i)}catch(e){throw new c(e)}return n},E.prototype._evaluateRegExpTest=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(!(r instanceof RegExp&&"string"==typeof i))throw new c("RegExp.test requires the first argument to be a RegExp and the second argument to be a string. Arguments are "+r+" and "+i+".");return r.test(i)},E.prototype._evaluateRegExpMatch=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(r instanceof RegExp&&"string"==typeof i)return r.test(i);if(i instanceof RegExp&&"string"==typeof r)return i.test(r);throw new c('Operator "=~" requires one RegExp argument and one string argument. Arguments are '+r+" and "+i+".")},E.prototype._evaluateRegExpNotMatch=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(r instanceof RegExp&&"string"==typeof i)return!r.test(i);if(i instanceof RegExp&&"string"==typeof r)return!i.test(r);throw new c('Operator "!~" requires one RegExp argument and one string argument. Arguments are '+r+" and "+i+".")},E.prototype._evaluateRegExpExec=function(e,t){var r=this._left.evaluate(e,t),i=this._right.evaluate(e,t);if(!(r instanceof RegExp&&"string"==typeof i))throw new c("RegExp.exec requires the first argument to be a RegExp and the second argument to be a string. Arguments are "+r+" and "+i+".");var n=r.exec(i);return o(n)?n[1]:null},E.prototype._evaluateToString=function(i,n){var o=this._left.evaluate(i,n);if(o instanceof RegExp||o instanceof e||o instanceof t||o instanceof r)return String(o);throw new c('Unexpected function call "'+this._value+'".')},E.prototype.getShaderExpression=function(e,t,r){var i,a,s,u,d=this._type,p=this._value;switch(o(this._left)&&(a=l(this._left)?J(this._left,e,t,this):this._left.getShaderExpression(e,t,this)),o(this._right)&&(s=this._right.getShaderExpression(e,t,this)),o(this._test)&&(u=this._test.getShaderExpression(e,t,this)),l(this._value)&&(p=J(this._value,e,t,this)),d){case h.VARIABLE:return e+p;case h.UNARY:if("Boolean"===p)return"bool("+a+")";if("Number"===p)return"float("+a+")";if("round"===p)return"floor("+a+" + 0.5)";if(o(se[p]))return p+"("+a+")";if("isNaN"===p||"isFinite"===p||"String"===p||"isExactClass"===p||"isClass"===p||"getExactClassName"===p)throw new c('Error generating style shader: "'+p+'" is not supported.');return o(se[p])?p+"("+a+")":p+a;case h.BINARY:return"%"===p?"mod("+a+", "+s+")":"==="===p?"("+a+" == "+s+")":"!=="===p?"("+a+" != "+s+")":"atan2"===p?"atan("+a+", "+s+")":o(le[p])?p+"("+a+", "+s+")":"("+a+" "+p+" "+s+")";case h.TERNARY:if(o(ue[p]))return p+"("+a+", "+s+", "+u+")";break;case h.CONDITIONAL:return"("+u+" ? "+a+" : "+s+")";case h.MEMBER:return"r"===s||"x"===s||"0.0"===s?a+"[0]":"g"===s||"y"===s||"1.0"===s?a+"[1]":"b"===s||"z"===s||"2.0"===s?a+"[2]":"a"===s||"w"===s||"3.0"===s?a+"[3]":a+"[int("+s+")]";case h.FUNCTION_CALL:throw new c('Error generating style shader: "'+p+'" is not supported.');case h.ARRAY:if(4===p.length)return"vec4("+p[0]+", "+p[1]+", "+p[2]+", "+p[3]+")";if(3===p.length)return"vec3("+p[0]+", "+p[1]+", "+p[2]+")";if(2===p.length)return"vec2("+p[0]+", "+p[1]+")";throw new c("Error generating style shader: Invalid array length. Array length should be 2, 3, or 4.");case h.REGEX:throw new c("Error generating style shader: Regular expressions are not supported.");case h.VARIABLE_IN_STRING:throw new c("Error generating style shader: Converting a variable to a string is not supported.");case h.LITERAL_NULL:throw new c("Error generating style shader: null is not supported.");case h.LITERAL_BOOLEAN:return p?"true":"false";case h.LITERAL_NUMBER:return Q(p);case h.LITERAL_STRING:if(o(r)&&r._type===h.MEMBER&&("r"===p||"g"===p||"b"===p||"a"===p||"x"===p||"y"===p||"z"===p||"w"===p))return p;if(i=n.fromCssColorString(p,ae),o(i))return Z(i);throw new c("Error generating style shader: String literals are not supported.");case h.LITERAL_COLOR:var f=a;if("color"===p){if(!o(f))return"vec4(1.0)";if(f.length>1){var m=f[0],g=f[1];return"1.0"!==g&&(t.translucent=!0),"vec4("+m+", "+g+")"}return"vec4("+f[0]+", 1.0)"}if("rgb"===p)return i=X(this),o(i)?K(i):"vec4("+f[0]+" / 255.0, "+f[1]+" / 255.0, "+f[2]+" / 255.0, 1.0)";if("rgba"===p)return"1.0"!==f[3]&&(t.translucent=!0),i=X(this),o(i)?K(i):"vec4("+f[0]+" / 255.0, "+f[1]+" / 255.0, "+f[2]+" / 255.0, "+f[3]+")";if("hsl"===p)return i=Y(this),o(i)?K(i):"vec4(czm_HSLToRGB(vec3("+f[0]+", "+f[1]+", "+f[2]+")), 1.0)";if("hsla"===p)return i=Y(this),o(i)?(1!==i.alpha&&(t.translucent=!0),K(i)):("1.0"!==f[3]&&(t.translucent=!0),"vec4(czm_HSLToRGB(vec3("+f[0]+", "+f[1]+", "+f[2]+")), "+f[3]+")");break;case h.LITERAL_VECTOR:for(var _=a.length,v=p+"(",y=0;y<_;++y)v+=a[y],y<_-1&&(v+=", ");return v+=")";case h.LITERAL_REGEX:throw new c("Error generating style shader: Regular expressions are not supported.");case h.LITERAL_UNDEFINED:throw new c("Error generating style shader: undefined is not supported.");case h.BUILTIN_VARIABLE:if("tiles3d_tileset_time"===p)return"u_tilesetTime"}},p}),define("Scene/Vector3DTilePrimitive",["../Core/Cartesian3","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/IndexDatatype","../Core/Matrix4","../Core/PrimitiveType","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../Shaders/ShadowVolumeFS","../Shaders/ShadowVolumeVS","./BlendingState","./Cesium3DTileFeature","./ClassificationType","./DepthFunction","./Expression","./StencilFunction","./StencilOperation","./Vector3DTileBatch"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x){"use strict";function P(r){r=i(r,i.EMPTY_OBJECT),this._batchTable=r.batchTable,this._batchIds=r.batchIds,this._positions=r.positions,this._vertexBatchIds=r.vertexBatchIds,this._indices=r.indices,this._indexCounts=r.indexCounts,this._indexOffsets=r.indexOffsets,this._batchedIndices=r.batchedIndices,this._boundingVolume=r.boundingVolume,this._boundingVolumes=r.boundingVolumes,this._center=i(r.center,e.ZERO),this._va=void 0,this._sp=void 0,this._spStencil=void 0,this._spPick=void 0,this._uniformMap=void 0,this._vaSwap=void 0,this._rsStencilPreloadPass=void 0,this._rsStencilDepthPass=void 0,this._rsColorPass=void 0,this._rsPickPass=void 0,this._rsWireframe=void 0,this._commands=[],this._commandsIgnoreShow=[],this._pickCommands=[],this._constantColor=t.clone(t.WHITE),this._highlightColor=this._constantColor,this._batchDirty=!0,this._pickCommandsDirty=!0,this._framesSinceLastRebatch=0,this._updatingAllCommands=!1,this._trianglesLength=this._indices.length/3,this._geometryByteLength=this._indices.byteLength+this._positions.byteLength+this._vertexBatchIds.byteLength,this.debugWireframe=!1,this._debugWireframe=this.debugWireframe,this._wireframeDirty=!1,this.forceRebatch=!1,this.classificationType=i(r.classificationType,S.BOTH),this._vertexShaderSource=r._vertexShaderSource,this._fragmentShaderSource=r._fragmentShaderSource,this._attributeLocations=r._attributeLocations,this._pickVertexShaderSource=r._pickVertexShaderSource,this._pickFragmentShaderSource=r._pickFragmentShaderSource,this._uniformMap=r._uniformMap,this._pickUniformMap=r._pickUniformMap,this._modelMatrix=r._modelMatrix,this._boundingSphere=r._boundingSphere,this._batchIdLookUp={};for(var n=this._batchIds.length,o=0;o<n;++o){var a=this._batchIds[o];this._batchIdLookUp[a]=o}}function D(e,t){if(!n(e._va)){var i=c.createVertexBuffer({context:t,typedArray:e._positions,usage:d.STATIC_DRAW}),o=c.createVertexBuffer({context:t,typedArray:e._vertexBatchIds,usage:d.STATIC_DRAW}),a=c.createIndexBuffer({context:t,typedArray:e._indices,usage:d.DYNAMIC_DRAW,indexDatatype:2===e._indices.BYTES_PER_ELEMENT?s.UNSIGNED_SHORT:s.UNSIGNED_INT}),l=[{index:0,vertexBuffer:i,componentDatatype:r.fromTypedArray(e._positions),componentsPerAttribute:3},{index:1,vertexBuffer:o,componentDatatype:r.fromTypedArray(e._vertexBatchIds),componentsPerAttribute:1}];e._va=new _({context:t,attributes:l,indexBuffer:a}),t.webgl2&&(e._vaSwap=new _({context:t,attributes:l,indexBuffer:c.createIndexBuffer({context:t,sizeInBytes:a.sizeInBytes,usage:d.DYNAMIC_DRAW,indexDatatype:a.indexDatatype})})),e._batchedPositions=void 0,e._transferrableBatchIds=void 0,e._vertexBatchIds=void 0,e._verticesPromise=void 0}}function I(e,t){if(!n(e._sp)){var r=e._batchTable,o=i(e._attributeLocations,q),a=e._vertexShaderSource;if(n(a))return e._sp=m.fromCache({context:t,vertexShaderSource:a,fragmentShaderSource:e._fragmentShaderSource,attributeLocations:o}),e._spStencil=e._sp,void(e._spPick=m.fromCache({context:t,vertexShaderSource:e._pickVertexShaderSource,fragmentShaderSource:e._pickFragmentShaderSource,attributeLocations:o}));var s=r.getVertexShaderCallback(!1,"a_batchId",void 0)(y),l=r.getFragmentShaderCallback()(v,!1,void 0),u=new g({defines:["VECTOR_TILE"],sources:[s]}),c=new g({defines:["VECTOR_TILE"],sources:[l]});e._sp=m.fromCache({context:t,vertexShaderSource:u,fragmentShaderSource:c,attributeLocations:o}),u=new g({defines:["VECTOR_TILE"],sources:[y]}),c=new g({defines:["VECTOR_TILE"],sources:[v]}),e._spStencil=m.fromCache({context:t,vertexShaderSource:u,fragmentShaderSource:c,attributeLocations:o}),s=r.getPickVertexShaderCallbackIgnoreShow("a_batchId")(y),l=r.getPickFragmentShaderCallbackIgnoreShow()(v);var d=new g({defines:["VECTOR_TILE"],sources:[s]}),h=new g({defines:["VECTOR_TILE"],sources:[l]});e._spPick=m.fromCache({context:t,vertexShaderSource:d,fragmentShaderSource:h,attributeLocations:o})}}function O(e){n(e._rsStencilPreloadPass)||(e._rsStencilPreloadPass=f.fromCache(Y),e._rsStencilDepthPass=f.fromCache(X),e._rsColorPass=f.fromCache(Q),e._rsPickPass=f.fromCache(Z))}function M(e,t){if(!n(e._uniformMap)){var r={u_modifiedModelViewProjection:function(){var r=t.uniformState.view,i=t.uniformState.projection;return l.clone(r,K),l.multiplyByPoint(K,e._center,J),l.setTranslation(K,J,K),l.multiply(i,K,K),K},u_highlightColor:function(){return e._highlightColor}};e._uniformMap=e._batchTable.getUniformMapCallback()(r),e._pickUniformMap=e._batchTable.getPickUniformMapCallback()(e._uniformMap)}}function R(e,t,r,i,n,o,a){for(var s=e.constructor.BYTES_PER_ELEMENT,l=o.length,u=0;u<l;++u){var c=o[u],d=a[c],h=i[d],p=n[d],f=new e.constructor(e.buffer,s*h,p);t.set(f,r),i[d]=r,r+=p}return r}function L(e,r){var i=e._indices,n=e._indexOffsets,o=e._indexCounts,a=e._batchIdLookUp,s=new i.constructor(i.length),l=r.pop(),u=[l],c=R(i,s,0,n,o,l.batchIds,a);for(l.offset=0,l.count=c;r.length>0;){var d=r.pop();if(t.equals(d.color,l.color))c=R(i,s,c,n,o,d.batchIds,a),l.batchIds=l.batchIds.concat(d.batchIds),l.count=c-l.offset;else{var h=c;c=R(i,s,c,n,o,d.batchIds,a),d.offset=h,d.count=c-h,u.push(d),l=d}}e._va.indexBuffer.copyFromArrayView(s),e._indices=s,e._batchedIndices=u}function N(e,t,r,i,n,o,a){for(var s=e.bytesPerIndex,l=o.length,u=0;u<l;++u){var c=o[u],d=a[c],h=i[d],p=n[d];t.copyFromBuffer(e,h*s,r*s,p*s),i[d]=r,r+=p}return r}function k(e,r){var i=e._indexOffsets,n=e._indexCounts,o=e._batchIdLookUp,a=r.pop(),s=[a],l=e._va.indexBuffer,u=e._vaSwap.indexBuffer,c=N(l,u,0,i,n,a.batchIds,o);for(a.offset=0,a.count=c;r.length>0;){var d=r.pop();if(t.equals(d.color,a.color))c=N(l,u,c,i,n,d.batchIds,o),a.batchIds=a.batchIds.concat(d.batchIds),a.count=c-a.offset;else{var h=c;c=N(l,u,c,i,n,d.batchIds,o),d.offset=h,d.count=c-h,s.push(d),a=d}}var p=e._va;e._va=e._vaSwap,e._vaSwap=p,e._batchedIndices=s}function F(e,t){return t.color.toRgba()-e.color.toRgba()}function B(e,t){if(!e._batchDirty)return!1;for(var r=e._batchedIndices,i=r.length,o=!1,a={},s=0;s<i;++s){var l=r[s].color,u=l.toRgba();if(n(a[u])){o=!0;break}a[u]=!0}return o?o&&!e.forceRebatch&&e._framesSinceLastRebatch<120?void++e._framesSinceLastRebatch:(r.sort(F),t.webgl2?k(e,r):L(e,r),e._framesSinceLastRebatch=0,e._batchDirty=!1,e._pickCommandsDirty=!0,e._wireframeDirty=!0,!0):(e._batchDirty=!1,!1)}function U(e,t){var r=B(e,t),o=e._commands,a=e._batchedIndices,s=a.length,u=3*s;if(!n(o)||r||o.length!==u){o.length=u;for(var c=e._va,d=e._sp,p=i(e._modelMatrix,l.IDENTITY),f=e._uniformMap,m=e._boundingVolume,g=0;g<s;++g){var _=a[g].offset,v=a[g].count,y=o[3*g];n(y)||(y=o[3*g]=new h({owner:e})),y.vertexArray=c,y.modelMatrix=p,y.offset=_,y.count=v,y.renderState=e._rsStencilPreloadPass,y.shaderProgram=d,y.uniformMap=f,y.boundingVolume=m,y.cull=!1;var b=o[3*g+1];n(b)||(b=o[3*g+1]=new h({owner:e})),b.vertexArray=c,b.modelMatrix=p,b.offset=_,b.count=v,b.renderState=e._rsStencilDepthPass,b.shaderProgram=d,b.uniformMap=f,b.boundingVolume=m,b.cull=!1;var C=o[3*g+2];n(C)||(C=o[3*g+2]=new h({owner:e})),C.vertexArray=c,C.modelMatrix=p,C.offset=_,C.count=v,C.renderState=e._rsColorPass,C.shaderProgram=d,C.uniformMap=f,C.boundingVolume=m,C.cull=!1}e._commandsDirty=!0}}function V(e,t){if(e.classificationType!==S.TERRAIN&&t.invertClassification&&(!n(e._commandsIgnoreShow)||e._commandsDirty)){for(var r=e._commands,i=e._commandsIgnoreShow,o=e._spStencil,a=r.length,s=i.length=a/3*2,l=0,u=0;u<s;u+=2){var c=i[u]=h.shallowClone(r[l],i[u]);c.shaderProgram=o,c.pass=p.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW,c=i[u+1]=h.shallowClone(r[l+1],i[u+1]),c.shaderProgram=o,c.pass=p.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW,l+=3}e._commandsDirty=!1}}function z(e){if(e._pickCommandsDirty){var t=e._indexOffsets.length,r=e._pickCommands;r.length=3*t;for(var o=e._va,a=e._spStencil,s=e._spPick,u=i(e._modelMatrix,l.IDENTITY),c=e._pickUniformMap,d=0;d<t;++d){var p=e._indexOffsets[d],f=e._indexCounts[d],m=n(e._boundingVolumes)?e._boundingVolumes[d]:e.boundingVolume,g=r[3*d];n(g)||(g=r[3*d]=new h({owner:e})),g.vertexArray=o,g.modelMatrix=u,g.offset=p,g.count=f,g.renderState=e._rsStencilPreloadPass,g.shaderProgram=a,g.uniformMap=c,g.boundingVolume=m;var _=r[3*d+1];n(_)||(_=r[3*d+1]=new h({owner:e})),_.vertexArray=o,_.modelMatrix=u,_.offset=p,_.count=f,_.renderState=e._rsStencilDepthPass,_.shaderProgram=a,_.uniformMap=c,_.boundingVolume=m;var v=r[3*d+2];n(v)||(v=r[3*d+2]=new h({owner:e})),v.vertexArray=o,v.modelMatrix=u,v.offset=p,v.count=f,v.renderState=e._rsPickPass,v.shaderProgram=s,v.uniformMap=c,v.boundingVolume=m}e._pickCommandsDirty=!1}}function G(e,r){e._updatingAllCommands=!0;var i,n=e._batchIds,o=n.length;for(i=0;i<o;++i){var a=n[i],s=r[a];s.show=!0,s.color=t.WHITE}var l=e._batchedIndices;for(o=l.length,i=0;i<o;++i)l[i].color=t.clone(t.WHITE);e._updatingAllCommands=!1,e._batchDirty=!0}function W(e,t,r,i){var o,a,s=e.commandList,l=r.length;for(o=0;o<l;++o)a=r[o],a.pass=t,s.push(a);if(e.invertClassification&&n(i))for(l=i.length,o=0;o<l;++o)a=i[o],a.pass=t,s.push(a)}function H(e,t){for(var r=e.commandList,i=t.length,n=0;n<i;n+=3){var o=t[n+2];o.pass=p.OPAQUE,r.push(o)}}function j(e){var t=e.debugWireframe===e._debugWireframe;if(!(t=t&&!(e.debugWireframe&&e._wireframeDirty))){n(e._rsWireframe)||(e._rsWireframe=f.fromCache({}));var r,i;e.debugWireframe?(r=e._rsWireframe,i=u.LINES):(r=e._rsColorPass,i=u.TRIANGLES);for(var o=e._commands,a=o.length,s=0;s<a;s+=3){var l=o[s+2];l.renderState=r,l.primitiveType=i}e._debugWireframe=e.debugWireframe,e._wireframeDirty=!1}}o(P.prototype,{trianglesLength:{get:function(){return this._trianglesLength}},geometryByteLength:{get:function(){return this._geometryByteLength}}});var q={position:0,a_batchId:1},Y={colorMask:{red:!1,green:!1,blue:!1,alpha:!1},stencilTest:{enabled:!0,frontFunction:E.ALWAYS,frontOperation:{fail:A.KEEP,zFail:A.DECREMENT_WRAP,zPass:A.DECREMENT_WRAP},backFunction:E.ALWAYS,backOperation:{fail:A.KEEP,zFail:A.INCREMENT_WRAP,zPass:A.INCREMENT_WRAP},reference:0,mask:15},depthTest:{enabled:!1},depthMask:!1},X={colorMask:{red:!1,green:!1,blue:!1,alpha:!1},stencilTest:{enabled:!0,frontFunction:E.ALWAYS,frontOperation:{fail:A.KEEP,zFail:A.KEEP,zPass:A.INCREMENT_WRAP},backFunction:E.ALWAYS,backOperation:{fail:A.KEEP,zFail:A.KEEP,zPass:A.DECREMENT_WRAP},reference:0,mask:15},depthTest:{enabled:!0,func:w.LESS_OR_EQUAL},depthMask:!1},Q={stencilTest:{enabled:!0,frontFunction:E.NOT_EQUAL,frontOperation:{fail:A.KEEP,zFail:A.KEEP,zPass:A.DECREMENT_WRAP},backFunction:E.NOT_EQUAL,backOperation:{fail:A.KEEP,zFail:A.KEEP,zPass:A.DECREMENT_WRAP},reference:0,mask:15},depthTest:{enabled:!1},depthMask:!1,blending:b.ALPHA_BLEND},Z={stencilTest:{enabled:!0,frontFunction:E.NOT_EQUAL,frontOperation:{fail:A.KEEP,zFail:A.KEEP,zPass:A.DECREMENT_WRAP},backFunction:E.NOT_EQUAL,backOperation:{fail:A.KEEP,zFail:A.KEEP,zPass:A.DECREMENT_WRAP},reference:0,mask:15},depthTest:{enabled:!1},depthMask:!1},K=new l,J=new e;P.prototype.createFeatures=function(e,t){for(var r=this._batchIds,i=r.length,n=0;n<i;++n){var o=r[n];t[o]=new C(e,o)}},P.prototype.applyDebugSettings=function(e,t){this._highlightColor=e?t:this._constantColor};var $=new t,ee=t.WHITE,te=/\$/;return P.prototype.applyStyle=function(e,r,i){if(!n(r))return void G(this,i);var o=r.color,a=o instanceof T&&!te.test(o.expression);this._updatingAllCommands=a;var s,l=this._batchIds,u=l.length;for(s=0;s<u;++s){var c=l[s],d=i[c];d.color=n(r.color)?r.color.evaluateColor(e,d,$):ee,d.show=!n(r.show)||r.show.evaluate(e,d)}if(a){var h=this._batchedIndices;for(u=h.length,s=0;s<u;++s)h[s].color=t.clone(t.WHITE);this._updatingAllCommands=!1,this._batchDirty=!0}},P.prototype.updateCommands=function(e,r){if(!this._updatingAllCommands){var i=this._batchIdLookUp,o=i[e];if(n(o)){var a,s=this._indexOffsets,l=this._indexCounts,u=s[o],c=l[o],d=this._batchedIndices,h=d.length;for(a=0;a<h;++a){var p=d[a].offset,f=d[a].count;if(u>=p&&u<p+f)break}d.push(new x({color:t.clone(r),offset:u,count:c,batchIds:[e]}));for(var m=[],g=[],_=d[a].batchIds,v=_.length,y=0;y<v;++y){var b=_[y];if(b!==e){s[i[b]]<u?m.push(b):g.push(b)}}0!==g.length&&d.push(new x({color:t.clone(d[a].color),offset:u+c,count:d[a].offset+d[a].count-(u+c),batchIds:g})),0!==m.length?(d[a].count=u-d[a].offset,d[a].batchIds=m):d.splice(a,1),this._batchDirty=!0}}},P.prototype.update=function(e){var t=e.context;D(this,t),I(this,t),O(this),M(this,t);var r;switch(this.classificationType){case S.TERRAIN:r=p.TERRAIN_CLASSIFICATION;break;case S.CESIUM_3D_TILE:r=p.CESIUM_3D_TILE_CLASSIFICATION;break;default:r=p.CLASSIFICATION}var i=e.passes;i.render&&(U(this,t),V(this,e),j(this),this._debugWireframe?H(e,this._commands):W(e,r,this._commands,this._commandsIgnoreShow)),i.pick&&(z(this),W(e,r,this._pickCommands))},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){return this._va=this._va&&this._va.destroy(),this._sp=this._sp&&this._sp.destroy(),this._spPick=this._spPick&&this._spPick.destroy(),this._vaSwap=this._vaSwap&&this._vaSwap.destroy(),a(this)},P}),define("Scene/ClassificationModel",["../Core/arraySlice","../Core/BoundingSphere","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/combine","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/IndexDatatype","../Core/Matrix4","../Core/PrimitiveType","../Core/Quaternion","../Core/Resource","../Core/RuntimeError","../Core/Transforms","../Core/WebGLConstants","../ThirdParty/GltfPipeline/ForEach","../ThirdParty/GltfPipeline/getAccessorByteStride","../ThirdParty/GltfPipeline/numberOfComponentsForType","../ThirdParty/GltfPipeline/parseBinaryGltf","../ThirdParty/when","./Axis","./ClassificationType","./ModelLoadResources","./ModelUtility","./SceneMode","./Vector3DTileBatch","./Vector3DTilePrimitive"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R){"use strict";function L(e){e=l(e,l.EMPTY_OBJECT);var r=e.gltf;if(r instanceof ArrayBuffer&&(r=new Uint8Array(r)),!(r instanceof Uint8Array))throw new y("Only binary glTF is supported as a classifier.");r=E(r);var i=r.nodes,n=r.meshes,o=i[0],a=o.mesh;if(1!==i.length||!u(a))throw new y("Only one node is supported for classification and it must have a mesh.");if(1!==n.length)throw new y("Only one mesh is supported when using b3dm for classification.");var s=n[0].primitives;if(1!==s.length)throw new y("Only one primitive per mesh is supported when using b3dm for classification.");var c=s[0].attributes.POSITION;if(!u(c))throw new y("The mesh must have a position attribute.");var d=s[0].attributes._BATCHID;if(!u(d))throw new y("The mesh must have a batch id attribute.");this._gltf=r;var h=l(e.basePath,"");this._resource=v.createIfNeeded(h),this.show=l(e.show,!0),this.modelMatrix=m.clone(l(e.modelMatrix,m.IDENTITY)),this._modelMatrix=m.clone(this.modelMatrix),this._ready=!1,this._readyPromise=A.defer(),this.debugShowBoundingVolume=l(e.debugShowBoundingVolume,!1),this._debugShowBoundingVolume=!1,this.debugWireframe=l(e.debugWireframe,!1),this._debugWireframe=!1,this._classificationType=e.classificationType,this._vertexShaderLoaded=e.vertexShaderLoaded,this._classificationShaderLoaded=e.classificationShaderLoaded,this._uniformMapLoaded=e.uniformMapLoaded,this._pickVertexShaderLoaded=e.pickVertexShaderLoaded,this._pickFragmentShaderLoaded=e.pickFragmentShaderLoaded,this._pickUniformMapLoaded=e.pickUniformMapLoaded,this._ignoreCommands=l(e.ignoreCommands,!1),this._upAxis=l(e.upAxis,x.Y),this._batchTable=e.batchTable,this._computedModelMatrix=new m,this._initialRadius=void 0,this._boundingSphere=void 0,this._scaledBoundingSphere=new t,this._state=ie.NEEDS_LOAD,this._loadResources=void 0,this._mode=void 0,this._dirty=!1,this._nodeMatrix=new m,this._primitive=void 0,this._extensionsUsed=void 0,this._extensionsRequired=void 0,this._quantizedUniforms=void 0,this._buffers={},this._vertexArray=void 0,this._shaderProgram=void 0,this._pickShaderProgram=void 0,this._uniformMap=void 0,this._geometryByteLength=0,this._trianglesLength=0,this._rtcCenter=void 0,this._rtcCenterEye=void 0,this._rtcCenter3D=void 0,this._rtcCenter2D=void 0}function N(e){var i=e.gltf,n=i.nodes,o=i.meshes,a=new r(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE),s=new r(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),l=n[0],c=l.mesh,d=I.getTransform(l),h=o[c],p=h.primitives[0],f=p.attributes.POSITION,g=I.getAccessorMinMax(i,f),_=r.fromArray(g.min,0,ne),v=r.fromArray(g.max,0,oe);u(a)&&u(s)&&(m.multiplyByPoint(d,_,_),m.multiplyByPoint(d,v,v),r.minimumByComponent(a,_,a),r.maximumByComponent(s,v,s));var y=t.fromCornerPoints(a,s);return e._upAxis===x.Y?t.transformWithoutScale(y,x.Y_UP_TO_Z_UP,y):e._upAxis===x.X&&t.transformWithoutScale(y,x.X_UP_TO_Z_UP,y),y}function k(e,t,r){return function(){e._state=ie.FAILED, +e._readyPromise.reject(new y("Failed to load "+t+": "+r))}}function F(e){var t=e.gltf,r=e._loadResources;S.buffer(t,function(e,t){r.buffers[t]=e.extras._pipeline.source})}function B(e,t){return function(r){var i=e._loadResources,n=new Uint8Array(r);--i.pendingBufferLoads,e.gltf.buffers[t].extras._pipeline.source=n}}function U(e){for(var t=e._loadResources,r=e.gltf.buffers,i=r.length,n=0;n<i;++n){var o=r[n];if(o.extras=l(o.extras,{}),o.extras._pipeline=l(o.extras._pipeline,{}),u(o.extras._pipeline.source))t.buffers[n]=o.extras._pipeline.source;else{var a=e._resource.getDerivedResource({url:o.uri});++t.pendingBufferLoads,a.fetchArrayBuffer().then(B(e,n)).otherwise(k(e,"buffer",a.uri))}}}function V(e){var t=e.gltf.bufferViews,r=e._loadResources.vertexBuffersToCreate;S.bufferView(e.gltf,function(e,t){e.target===C.ARRAY_BUFFER&&r.enqueue(t)});var i=e._loadResources.indexBuffersToCreate,n={};S.accessor(e.gltf,function(e){var r=e.bufferView;t[r].target!==C.ELEMENT_ARRAY_BUFFER||u(n[r])||(n[r]=!0,i.enqueue({id:r,componentType:e.componentType}))})}function z(e,t){var r=t._loadResources,i=t.gltf.bufferViews,n=i[e],o=r.getBuffer(n);t._buffers[e]=o,t._geometryByteLength+=o.byteLength}function G(e,t,r){var i=r._loadResources,n=r.gltf.bufferViews,o=n[e],a={typedArray:i.getBuffer(o),indexDatatype:t};r._buffers[e]=a,r._geometryByteLength+=a.typedArray.byteLength}function W(e){var t=e._loadResources;if(0===t.pendingBufferLoads){for(var r=t.vertexBuffersToCreate,i=t.indexBuffersToCreate;r.length>0;)z(r.dequeue(),e);for(;i.length>0;){var n=i.dequeue();G(n.id,n.componentType,e)}}}function H(e,t){var r=t.gltf.meshes[0].primitives[0],i=I.modifyShaderForQuantizedAttributes(t.gltf,r,e);return t._quantizedUniforms=i.uniforms,i.shader}function j(e,t){return u(t)&&(e=t(e)),e}function q(e){var t=I.getAttributeOrUniformBySemantic(e.gltf,"POSITION"),r=I.getAttributeOrUniformBySemantic(e.gltf,"_BATCHID"),i={};i[t]=0,i[r]=1;var n,o,a=I.getAttributeOrUniformBySemantic(e.gltf,"MODELVIEWPROJECTION");if(u(a))n="uniform mat4 "+a+";\n",o=" vec4 positionInClipCoords = "+a+" * vec4("+t+", 1.0);\n";else{var s=I.getAttributeOrUniformBySemantic(e.gltf,"PROJECTION"),l=I.getAttributeOrUniformBySemantic(e.gltf,"MODELVIEW");u(l)||(l=I.getAttributeOrUniformBySemantic(e.gltf,"CESIUM_RTC_MODELVIEW")),n="uniform mat4 "+l+";\nuniform mat4 "+s+";\n",o=" vec4 positionInClipCoords = "+s+" * "+l+" * vec4("+t+", 1.0);\n"}var c="attribute vec3 "+t+";\nattribute float "+r+";\n"+n+"void main() {\n"+o+" gl_Position = czm_depthClampFarPlane(positionInClipCoords);\n}\n",d="#ifdef GL_EXT_frag_depth\n#extension GL_EXT_frag_depth : enable\n#endif\nvoid main() \n{ \n gl_FragColor = vec4(1.0); \n czm_writeDepthClampedToFarPlane();\n}\n";e.extensionsUsed.WEB3D_quantized_attributes&&(c=H(c,e));var h=j(c,e._vertexShaderLoaded),p=j(d,e._classificationShaderLoaded);e._shaderProgram={vertexShaderSource:h,fragmentShaderSource:p,attributeLocations:i};var f=j(c,e._pickVertexShaderLoaded),m=j(d,e._pickFragmentShaderLoaded);e._pickShaderProgram={vertexShaderSource:f,fragmentShaderSource:m,attributeLocations:i}}function Y(){return{POSITION:0,_BATCHID:1}}function X(e){if(e._loadResources.finishedBuffersCreation()&&!u(e._vertexArray)){var t=e._buffers,r=e.gltf,i=r.accessors,n=r.meshes,o=n[0].primitives,a=o[0],s=Y(),l={},c=a.attributes;for(var d in c)if(c.hasOwnProperty(d)){var h=s[d];if(u(h)){var p=i[c[d]];l[d]={index:h,vertexBuffer:t[p.bufferView],componentsPerAttribute:T(p.type),componentDatatype:p.componentType,offsetInBytes:p.byteOffset,strideInBytes:w(r,p)}}}var f;u(a.indices)&&(f=t[i[a.indices].bufferView]),e._vertexArray={attributes:l,indexBuffer:f}}}function Q(e,t){if(!u(e._uniformMap)){var r=e.gltf.techniques,i=r[0],n=i.parameters,o=i.uniforms,a={};for(var s in o)if(o.hasOwnProperty(s)&&"extras"!==s){var l=o[s],c=n[l];if(!u(c.semantic)||!u(ae[c.semantic]))continue;a[s]=ae[c.semantic](t.uniformState,e)}e._uniformMap=a}}function Z(e,t){return I.createUniformsForQuantizedAttributes(e.gltf,t,e._quantizedUniforms)}function K(e,t){switch(e.mode){case g.TRIANGLES:return t/3;case g.TRIANGLE_STRIP:case g.TRIANGLE_FAN:return Math.max(t-2,0);default:return 0}}function J(i){var n,l,c=i._batchTable,d=i._uniformMap,h=i._vertexArray,p=i.gltf,g=p.accessors,_=p.meshes,v=_[0].primitives[0],y=g[v.indices],b=v.attributes.POSITION,C=I.getAccessorMinMax(p,b),S=t.fromCornerPoints(r.fromArray(C.min),r.fromArray(C.max));if(u(y))l=y.count,n=y.byteOffset/f.getSizeInBytes(y.componentType);else{l=g[v.attributes.POSITION].count,n=0}if(i._trianglesLength+=K(v,l),u(i._uniformMapLoaded)&&(d=i._uniformMapLoaded(d)),i.extensionsUsed.WEB3D_quantized_attributes){var w=Z(i,v);d=a(d,w)}var T=h.attributes.POSITION,E=T.componentDatatype,A=T.vertexBuffer,x=A.byteOffset,P=A.byteLength/s.getSizeInBytes(E),D=s.createArrayBufferView(E,A.buffer,x,P);T=h.attributes._BATCHID,E=T.componentDatatype,A=T.vertexBuffer,x=A.byteOffset,P=A.byteLength/s.getSizeInBytes(E);var O,L=s.createArrayBufferView(E,A.buffer,x,P),N=h.indexBuffer.typedArray;O=h.indexBuffer.indexDatatype===f.UNSIGNED_SHORT?new Uint16Array(N.buffer,N.byteOffset,N.byteLength/Uint16Array.BYTES_PER_ELEMENT):new Uint32Array(N.buffer,N.byteOffset,N.byteLength/Uint32Array.BYTES_PER_ELEMENT),D=e(D),L=e(L),O=e(O,n,n+l);var k=[],F=[],B=[],U=[],V=L[O[0]];k.push(V),B.push(0);for(var z,G,W,H=O.length,j=1;j<H;++j)(z=L[O[j]])!==V&&(G=B[B.length-1],W=j-G,k.push(z),F.push(W),B.push(j),U.push(new M({offset:G,count:W,batchIds:[V],color:o.WHITE})),V=z);G=B[B.length-1],W=H-G,F.push(W),U.push(new M({offset:G,count:W,batchIds:[V],color:o.WHITE}));var q,Y=i._shaderProgram,X=Y.vertexShaderSource,Q=Y.fragmentShaderSource,J=Y.attributeLocations,$=i._pickShaderProgram,ee=$.vertexShaderSource,te=$.fragmentShaderSource;q=u(i._pickUniformMapLoaded)?i._pickUniformMapLoaded(d):a(d),i._primitive=new R({classificationType:i._classificationType,positions:D,indices:O,indexOffsets:B,indexCounts:F,batchIds:k,vertexBatchIds:L,batchedIndices:U,batchTable:c,boundingVolume:new t,_vertexShaderSource:X,_fragmentShaderSource:Q,_attributeLocations:J,_pickVertexShaderSource:ee,_pickFragmentShaderSource:te,_uniformMap:d,_pickUniformMap:q,_modelMatrix:new m,_boundingSphere:S}),i._buffers=void 0,i._vertexArray=void 0,i._shaderProgram=void 0,i._pickShaderProgram=void 0,i._uniformMap=void 0}function $(e){if(e._loadResources.finished()&&!u(e._primitive)){var t=e.gltf,r=t.nodes,i=r[0];e._nodeMatrix=I.getTransform(i,e._nodeMatrix),J(e)}}function ee(e,t){var r=t.context;I.checkSupportedGlExtensions(e.gltf.glExtensionsUsed,r),W(e),q(e),X(e),Q(e,r),$(e)}function te(e,n,o,a){var s=e._computedModelMatrix;if(e._mode!==O.SCENE3D&&!e._ignoreCommands){var l=m.getColumn(s,3,se);if(i.equals(l,i.UNIT_W)){var c=e.boundingSphere.center,d=b.wgs84To2DModelMatrix(a,c,le);s=m.multiply(d,s,le),u(e._rtcCenter)&&(m.setTranslation(s,i.UNIT_W,s),e._rtcCenter=e._rtcCenter2D)}else s=b.basisTo2D(a,s,le),e._rtcCenter=e._rtcCenter3D}var h=e._primitive;(n||o)&&(m.multiplyTransformation(s,e._nodeMatrix,h._modelMatrix),t.transform(h._boundingSphere,h._modelMatrix,h._boundingVolume),u(e._rtcCenter)&&r.add(e._rtcCenter,h._boundingVolume.center,h._boundingVolume.center))}if(!p.supportsTypedArrays())return{};var re=new r,ie={NEEDS_LOAD:0,LOADING:1,LOADED:2,FAILED:3};c(L.prototype,{gltf:{get:function(){return this._gltf}},basePath:{get:function(){return this._resource.url}},boundingSphere:{get:function(){var e=this.modelMatrix,t=m.getScale(e,re),i=this._scaledBoundingSphere;return i.center=r.multiplyComponents(this._boundingSphere.center,t,i.center),i.radius=r.maximumComponent(t)*this._initialRadius,u(this._rtcCenter)&&r.add(this._rtcCenter,i.center,i.center),i}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},dirty:{get:function(){return this._dirty}},extensionsUsed:{get:function(){return u(this._extensionsUsed)||(this._extensionsUsed=I.getUsedExtensions(this.gltf)),this._extensionsUsed}},extensionsRequired:{get:function(){return u(this._extensionsRequired)||(this._extensionsRequired=I.getRequiredExtensions(this.gltf)),this._extensionsRequired}},upAxis:{get:function(){return this._upAxis}},trianglesLength:{get:function(){return this._trianglesLength}},geometryByteLength:{get:function(){return this._geometryByteLength}},texturesByteLength:{get:function(){return 0}},classificationType:{get:function(){return this._classificationType}}});var ne=new r,oe=new r,ae={PROJECTION:function(e,t){return I.getGltfSemanticUniforms().PROJECTION(e,t)},MODELVIEW:function(e,t){return I.getGltfSemanticUniforms().MODELVIEW(e,t)},CESIUM_RTC_MODELVIEW:function(e,t){return I.getGltfSemanticUniforms().CESIUM_RTC_MODELVIEW(e,t)},MODELVIEWPROJECTION:function(e,t){return I.getGltfSemanticUniforms().MODELVIEWPROJECTION(e,t)}},se=new i,le=new m;return L.prototype.updateCommands=function(e,t){this._primitive.updateCommands(e,t)},L.prototype.update=function(e){if(e.mode!==O.MORPHING){if(this._state===ie.NEEDS_LOAD&&u(this.gltf)&&(this._state=ie.LOADING,this._state!==ie.FAILED)){var t=this.gltf.extensions;if(u(t)&&u(t.CESIUM_RTC)){var i=r.fromArray(t.CESIUM_RTC.center);if(!r.equals(i,r.ZERO)){this._rtcCenter3D=i;var n=e.mapProjection,o=n.ellipsoid,a=o.cartesianToCartographic(this._rtcCenter3D),s=n.project(a);r.fromElements(s.z,s.x,s.y,s),this._rtcCenter2D=s,this._rtcCenterEye=new r,this._rtcCenter=this._rtcCenter3D}}this._loadResources=new D,U(this)}var l=this._loadResources,c=!1;this._state===ie.LOADING&&(0===l.pendingBufferLoads&&(I.checkSupportedExtensions(this.extensionsRequired),F(this),V(this),this._boundingSphere=N(this),this._initialRadius=this._boundingSphere.radius,ee(this,e)),l.finished()&&(this._state=ie.LOADED,c=!0)),u(l)&&this._state===ie.LOADED&&(c||ee(this,e),l.finished()&&(this._loadResources=void 0));var d=this.show;if(d&&this._state===ie.LOADED||c){this._dirty=!1;var h=this.modelMatrix,p=e.mode!==this._mode;this._mode=e.mode;var f=!m.equals(this._modelMatrix,h)||p;if(f||c){m.clone(h,this._modelMatrix);var g=this._computedModelMatrix;m.clone(h,g),this._upAxis===x.Y?m.multiplyTransformation(g,x.Y_UP_TO_Z_UP,g):this._upAxis===x.X&&m.multiplyTransformation(g,x.X_UP_TO_Z_UP,g)}(f||c)&&(te(this,f,c,e.mapProjection),this._dirty=!0)}if(c){var _=this;return void e.afterRender.push(function(){_._ready=!0,_._readyPromise.resolve(_)})}d&&!this._ignoreCommands&&(this._primitive.debugShowBoundingVolume=this.debugShowBoundingVolume,this._primitive.debugWireframe=this.debugWireframe,this._primitive.update(e))}},L.prototype.isDestroyed=function(){return!1},L.prototype.destroy=function(){return this._primitive=this._primitive&&this._primitive.destroy(),d(this)},L}),define("Scene/Batched3DModel3DTileContent",["../Core/ClippingPlaneCollection","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/getBaseUri","../Core/getStringFromTypedArray","../Core/RequestType","../Core/RuntimeError","../Renderer/Pass","./Cesium3DTileBatchTable","./Cesium3DTileFeature","./Cesium3DTileFeatureTable","./ClassificationModel","./Model","./ModelUtility"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(e,t,r,i,n){this._tileset=e,this._tile=t,this._resource=r,this._model=void 0,this._batchTable=void 0,this._features=void 0,this.featurePropertiesDirty=!1,x(this,i,n)}function C(e){var t=y.getAttributeOrUniformBySemantic(e,"_BATCHID");return i(t)||(t=y.getAttributeOrUniformBySemantic(e,"BATCHID"),i(t)&&b._deprecationWarning("b3dm-legacy-batchid","The glTF in this b3dm uses the semantic `BATCHID`. Application-specific semantics should be prefixed with an underscore: `_BATCHID`.")),t}function S(e){return function(t,r){var n=e._batchTable,o=e._model.gltf,a=!i(e._tileset.classificationType),s=C(o),l=y.getDiffuseAttributeOrUniform(o,r),u=n.getVertexShaderCallback(a,s,l);return i(u)?u(t):t}}function w(e){return function(t){var r=e._batchTable,n=e._model.gltf,o=C(n),a=r.getPickVertexShaderCallback(o);return i(a)?a(t):t}}function T(e){return function(t,r){var n=e._batchTable,o=e._model.gltf,a=!i(e._tileset.classificationType),s=y.getDiffuseAttributeOrUniform(o,r),l=n.getFragmentShaderCallback(a,s);return i(l)?l(t):t}}function E(e){return function(t){var r=e._batchTable,n=r.getClassificationFragmentShaderCallback();return i(n)?n(t):t}}function A(e){return function(t,r){e._model.updateCommands(t,r)}}function x(t,n,o){var a=t._tileset,s=t._tile,l=t._resource,u=r(o,0);o=u;var m=new Uint8Array(n),y=new DataView(n);o+=D;var C=y.getUint32(o,!0);if(1!==C)throw new h("Only Batched 3D Model version 1 is supported. Version "+C+" is not.");o+=D;var x=y.getUint32(o,!0);o+=D;var P=y.getUint32(o,!0);o+=D;var I=y.getUint32(o,!0);o+=D;var O=y.getUint32(o,!0);o+=D;var M=y.getUint32(o,!0);o+=D;var R;O>=570425344?(o-=2*D,R=P,O=I,M=0,P=0,I=0,b._deprecationWarning("b3dm-legacy-header","This b3dm header is using the legacy format [batchLength] [batchTableByteLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.")):M>=570425344&&(o-=D,R=O,O=P,M=I,P=0,I=0,b._deprecationWarning("b3dm-legacy-header","This b3dm header is using the legacy format [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md."));var L;if(0===P)L={BATCH_LENGTH:r(R,0)};else{var N=c(m,o,P);L=JSON.parse(N),o+=P}var k=new Uint8Array(n,o,I);o+=I;var F=new g(L,k);R=F.getGlobalProperty("BATCH_LENGTH"),F.featuresLength=R;var B,U;if(O>0){var V=c(m,o,O);B=JSON.parse(V),o+=O,M>0&&(U=new Uint8Array(n,o,M),U=new Uint8Array(U),o+=M)}var z;i(a.classificationType)&&(z=A(t));var G=new f(t,R,B,U,z);t._batchTable=G;var W=u+x-o;if(0===W)throw new h("glTF byte length must be greater than 0.");var H;o%4==0?H=new Uint8Array(n,o,W):(b._deprecationWarning("b3dm-glb-unaligned","The embedded glb is not aligned to a 4-byte boundary."),H=new Uint8Array(m.subarray(o,o+W)));var j={content:t,primitive:a};if(i(a.classificationType))t._model=new _({gltf:H,cull:!1,basePath:l,requestType:d.TILES3D,modelMatrix:s.computedTransform,upAxis:a._gltfUpAxis,debugWireframe:a.debugWireframe,vertexShaderLoaded:S(t),classificationShaderLoaded:E(t),uniformMapLoaded:G.getUniformMapCallback(),pickVertexShaderLoaded:w(t),pickFragmentShaderLoaded:G.getPickFragmentShaderCallback(),pickUniformMapLoaded:G.getPickUniformMapCallback(),classificationType:a._classificationType,batchTable:G});else{var q;q=i(a.clippingPlanes)?a.clippingPlanes.clone():new e({enabled:!1}),t._model=new v({gltf:H,cull:!1,releaseGltfJson:!0,opaquePass:p.CESIUM_3D_TILE,basePath:l,requestType:d.TILES3D,modelMatrix:s.computedTransform,upAxis:a._gltfUpAxis,shadows:a.shadows,debugWireframe:a.debugWireframe,incrementallyLoadTextures:!1,vertexShaderLoaded:S(t),fragmentShaderLoaded:T(t),uniformMapLoaded:G.getUniformMapCallback(),pickVertexShaderLoaded:w(t),pickFragmentShaderLoaded:G.getPickFragmentShaderCallback(),pickUniformMapLoaded:G.getPickUniformMapCallback(),addBatchIdToGeneratedShaders:R>0,pickObject:j,clippingPlanes:q})}}function P(e){var t=e.featuresLength;if(!i(e._features)&&t>0){for(var r=new Array(t),n=0;n<t;++n)r[n]=new m(e,n);e._features=r}}if(!l.supportsTypedArrays())return{};b._deprecationWarning=o,n(b.prototype,{featuresLength:{get:function(){return this._batchTable.featuresLength}},pointsLength:{get:function(){return 0}},trianglesLength:{get:function(){return this._model.trianglesLength}},geometryByteLength:{get:function(){return this._model.geometryByteLength}},texturesByteLength:{get:function(){return this._model.texturesByteLength}},batchTableByteLength:{get:function(){return this._batchTable.memorySizeInBytes}},innerContents:{get:function(){}},readyPromise:{get:function(){return this._model.readyPromise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){return this._batchTable}}});var D=Uint32Array.BYTES_PER_ELEMENT;return b.prototype.hasProperty=function(e,t){return this._batchTable.hasProperty(e,t)},b.prototype.getFeature=function(e){return P(this),this._features[e]},b.prototype.applyDebugSettings=function(e,r){r=e?r:t.WHITE,0===this.featuresLength?this._model.color=r:this._batchTable.setAllColor(r)},b.prototype.applyStyle=function(e,t){this._batchTable.applyStyle(e,t)},b.prototype.update=function(e,t){var r=t.commandList.length;this._batchTable.update(e,t),this._model.modelMatrix=this._tile.computedTransform,this._model.shadows=this._tileset.shadows,this._model.debugWireframe=this._tileset.debugWireframe;var n=this._tileset.clippingPlanes,o=this._model.clippingPlanes;if(i(n)?(n.clone(o),o.enabled=n.enabled&&this._tile._isClipped):i(o)&&o.enabled&&(o.enabled=!1),this._model.update(t),r<t.commandList.length&&t.passes.render&&!i(e.classificationType)){var a=this._tile._finalResolution;this._batchTable.addDerivedCommands(t,r,a)}},b.prototype.isDestroyed=function(){return!1},b.prototype.destroy=function(){return this._model=this._model&&this._model.destroy(),this._batchTable=this._batchTable&&this._batchTable.destroy(),a(this)},b}),define("Scene/BingMapsStyle",["../Core/freezeObject"],function(e){"use strict";return e({AERIAL:"Aerial",AERIAL_WITH_LABELS:"AerialWithLabels",ROAD:"Road",CANVAS_DARK:"CanvasDark",CANVAS_LIGHT:"CanvasLight",CANVAS_GRAY:"CanvasGray",ORDNANCE_SURVEY:"OrdnanceSurvey",COLLINS_BART:"CollinsBart"})}),define("Scene/BingMapsImageryProvider",["../Core/BingMapsApi","../Core/Cartesian2","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/Math","../Core/Rectangle","../Core/Resource","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorTilingScheme","../ThirdParty/when","./BingMapsStyle","./DiscardMissingTileImagePolicy","./ImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(o){function s(e){if(1!==e.resourceSets.length)return void v();var i=e.resourceSets[0].resources[0];E._tileWidth=i.imageWidth,E._tileHeight=i.imageHeight,E._maximumLevel=i.zoomMax-1,E._imageUrlSubdomains=i.imageUrlSubdomains,E._imageUrlTemplate=i.imageUrl;var o=E._tileProtocol;if(!n(o)){var a=document.location.protocol;o=/^http/.test(a)?a:"http:"}E._imageUrlTemplate=E._imageUrlTemplate.replace(/^http:/,o),n(E._tileDiscardPolicy)||(E._tileDiscardPolicy=new _({missingImageUrl:b(E,0,0,E._maximumLevel).url,pixelsToCheck:[new t(0,0),new t(120,140),new t(130,160),new t(200,50),new t(200,200)],disableCheckIfAllPixelsAreTransparent:!0}));var s=E._attributionList=i.imageryProviders;s||(s=E._attributionList=[]);for(var l=0,d=s.length;l<d;++l){var h=s[l];h.credit=new r({text:h.attribution});for(var f=h.coverageAreas,m=0,g=h.coverageAreas.length;m<g;++m){var y=f[m],C=y.bbox;y.bbox=new c(u.toRadians(C[1]),u.toRadians(C[0]),u.toRadians(C[3]),u.toRadians(C[2]))}}E._ready=!0,E._readyPromise.resolve(!0),p.handleSuccess(w)}function v(e){var t="An error occurred while accessing "+T.url+".";w=p.handleError(w,E,E._errorEvent,t,void 0,void 0,void 0,C),E._readyPromise.reject(new h(t))}function C(){var e=T.fetchJsonp("jsonp");m(e,s,v)}o=i(o,{}),n(o.proxy)&&a("BingMapsImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there."),this._key=e.getKey(o.key),this._keyErrorCredit=e.getErrorCredit(o.key);var S=d.createIfNeeded(o.url,{proxy:o.proxy});S.addQueryParameters({key:this._key}),this._resource=S,this._tileProtocol=o.tileProtocol,this._mapStyle=i(o.mapStyle,g.AERIAL),this._culture=i(o.culture,""),this._tileDiscardPolicy=o.tileDiscardPolicy,this._proxy=o.proxy,this._credit=new r({text:"Bing Imagery",imageUrl:y._logoData,link:"http://www.bing.com"}),this.defaultGamma=1,this._tilingScheme=new f({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,ellipsoid:o.ellipsoid}),this._tileWidth=void 0,this._tileHeight=void 0,this._maximumLevel=void 0,this._imageUrlTemplate=void 0,this._imageUrlSubdomains=void 0,this._errorEvent=new l,this._ready=!1,this._readyPromise=m.defer();var w,T=S.getDerivedResource({url:"/REST/v1/Imagery/Metadata/"+this._mapStyle,queryParameters:{incl:"ImageryProviders"}}),E=this;C()}function b(e,t,r,i,n){var o=e._imageUrlTemplate,a=e._imageUrlSubdomains,s=(t+r+i)%a.length;return e._resource.getDerivedResource({url:o,request:n,templateValues:{quadkey:y.tileXYToQuadKey(t,r,i),subdomain:a[s],culture:e._culture}})}function C(e,t,r){++t;for(var i=[],o=0,a=e.length;o<a;++o){for(var s=e[o],l=s.coverageAreas,u=!1,d=0,h=s.coverageAreas.length;!u&&d<h;++d){var p=l[d];if(t>=p.zoomMin&&t<=p.zoomMax){var f=c.intersection(r,p.bbox,w);n(f)&&(u=!0)}}u&&i.push(s.credit)}return i}o(y.prototype,{url:{get:function(){return this._resource.url}},proxy:{get:function(){return this._resource.proxy}},key:{get:function(){return this._key}},mapStyle:{get:function(){return this._mapStyle}},culture:{get:function(){return this._culture}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!1}}});var S=new c;y.prototype.getTileCredits=function(e,t,r){var i=this._tilingScheme.tileXYToRectangle(e,t,r,S),o=C(this._attributionList,r,i);return n(this._keyErrorCredit)&&o.push(this._keyErrorCredit),o},y.prototype.requestImage=function(e,t,r,i){return v.loadImage(this,b(this,e,t,r,i))},y.prototype.pickFeatures=function(e,t,r,i,n){},y._logoData="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAAaCAYAAAAEy1RnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3gIDEgcPTMnXOQAAClZJREFUWMPdWGtsFNcV/u689uH1+sXaONhlWQzBENtxiUFBpBSLd60IpXHSNig4URtSYQUkRJNSi0igViVVVBJBaBsiAgKRQJSG8AgEHCCWU4iBCprY2MSgXfOI16y9D3s9Mzsztz9yB12WNU2i9Ecy0tHOzN4793zn3POdcy7BnRfJ8I7iB3SRDPeEExswLz8Y0DZIAYDIRGAgLQAm+7Xle31J3L3Anp1MZPY+BUBjorN332vgYhpgV1FRUd6TTz45ubq6OtDV1SXpuu5g//Oept9wNwlMyAi8IXDjyF245TsDTdivDMATCATGNDU1/WbhwoWPTZs2bWx1dXWhx+Oxrl+/PqTrus5t9W8KWEzjinTAYhro/xuBStwiIgBnJBLxKIoy1u/3V/r9/krDMMz3339/Z3t7e38ikUgCMDLEt8W+Q0cAI3McYTDDmZxh7DESG5Ni43jg9Gsa+X+OsxWxPSJTSj3JZFK5ZRVJErOzs8e6XC4fgGwALhbzDgAKU1hK28KEA6PMmTMn56233qpevnz5PQDcbJ7EzVUAuMrLy3MBeABkcWOEDELSyFe4y7iMoHkriZZlKYZh8ASHZDKpJJPJHAC5APIA5APIAeBlCjo5TwlpXnbOmTPHP3fu3KZVq1atZKBcDJQ9x7V48WJfc3Pzhp6enj+tXLnyR8w4MjdG4gyVDk7KICMClzKlLUrpbQMNw5AkScppbGz8cWdn57WjR4/2caw+DEBlYjO8wX1foZQWuN3uKZIklQD4G+fhlG0Yl8uVm5WVVW6app6dne0D0G8vnxbjJntHubCUOK/badZICyWanrJuAaeUknTQpmlKkUhEWbx48U8LCwtHhUKha+fPn+85fPhwV0tLyzUACSZx9jvMFhIByNFoVDEMw/qKB5HPvJfkUqBr9+7deklJyZ/j8bi5ffv2OAslieMLsG+m2DybT2QuzEQOsF5SUqJfvXo1yc2l6Xn6rgSRSCSEc+fOhVeuXLmwoqJixvTp0wcWLFgQ7unpudHR0dF97ty5z/fu3XseQJh5adjeerquy5ZlCalUivh8Pt8HH3ywzOPxyD09PZ81NjZ+2NnZaQEQx40b54vFYqaqquEVK1b4a2tr/WvWrDn18ssv144fP36SqqoD69ev371nz57rDLwAwHHkyJGfjRs3rtowDOv06dOnu7q6rs6bN2/s7Nmz9zIjDKenWoFZKg/AlMLCwl82Nzf/m3LX22+/fXb06NF/ALC8u7u7m6ZdkUhksL29/UpLS0vzunXrVgAoBzAaQBGAiY2NjUui0ei1RCLRFwwG/9PX19cVi8WCqqoOdHd3HysrK6sDMCccDl8IBoOtiqIsOnbs2D+i0eiV3t7ez8Ph8GeRSKRT07TB/v7+i1OnTp0HYBqABzs7O/+paVo0Fot1RyKRi/F4/Gp/f39XIpHoZnoUMn6wU+ZtRDaymwmxZFk2AWjvvvvuJ/F4PMn/n5+fn1VeXu6fOXNmbU1NzUOM4Bz8QqIoyg6HwxuLxfq3bdu2a+vWrW/09/dfKy0tffDVV199BEC20+n0ud3uQgBup9Pp83g8JYqieE+ePPnxxo0bt33xxRen8/Ly7n3hhRcWASh47bXX5pWVldWFw+GuXbt27XjzzTd3BoPBDq/XG1AUZRRHmAKPVfqaoKkgCCkA+oYNG84Eg0FHTU1N5ezZs8eWlJQ4CSF8/LvZYhJPQoQQpFKpwcrKyo1su9HBwUF99erVv588eXINgOOmacIwDEopdaZSKUIpxYkTJz6sr68/BMBav379RcMwZk2aNOl+AP+qq6t7xDTNVEVFxR+j0WgSAJk4ceKlTz/9tNzpdHpZvIvpjVW6pykhhBJCbkvwgiAQQogEQL558ybdtGlTsLm5OWJZdxZmlmWll5OUEEJN0zSGhob6GcOrALSzZ8/2apqWcLlc2axGACNRkRAimqaph0Kh68xIwwB0y7IMSZKcABz5+fkl8Xj8y2g0apOb5na7rYGBgS/JV54Q0qpAAoBKaS0jBWClg1ZVFeFw2AlgVF1dXeDpp5+eWVFRUVpcXOzgvQwAbrcbDJhdudlGpKZpGtx6JCcnRxIEQbQsS2PjbjM+AMvlchnMSBaXkr7ymCCIhmEYfMoVRVESBEHI0CaTTNubssUsQRBuubCtra33pZdeCk6YMCGwZs2aipqaGn9paWmuJEl3JP0bN258eeTIkRMABrm0YomiaImiKGVlZeWxLecAgBkzZvgdDkfWjRs3ggA0bpfpoiiahBCqKEqKAy2yULMA6MlkMp6Xl3cP1x2SWCwmFhQU+CmlFhfHNFOevpX4LcvSJUkyAeDQoUOh119//fpTTz01Zf78+UWBQCBHUZQ7yE/TNGPfvn0n33vvvSP79+//BECMeZsCMGRZNgRBgNPpHHXx4sVVDQ0Nf1+wYMGYJ554YikAevDgwUMA4oIgQJZlSggZdDqdBiGEZGdn6ww0tQlJURTT4/EMHz9+/MCjjz7622AwuHbZsmVbiouLvWvXrm1wOp3ZqVRqaKQTIInf1gAMl8ulU0q1CxcuBGOxmL5u3bryQCDgycrKEjORXGtra8eOHTsOHz169OyVK1cuA+hlRYrGlNRkWR7UNO2mYRiaz+cb3dLS8gYhhOi6Hj116tSOVatWHQNALcsaME0zLghClBDSZ9+zQsZ2SoJS2udwOKLPPffcvsrKyrJAIPDQ/v37txiGofX19V3r7e29UlBQMHqEVpjwnrYA6PF4PK6q6s2qqqqpZWVlitvtljOB7enpiWzbtu3wgQMHTre1tV0E0MeKkkGuIhMAqHv37u30er3Px+NxlyiKygMPPOAnhFiXLl0Kbd68uYPNsXbu3Lk6mUwaqqr2btmyZUdtbe3hd955pwvAEFNcO3jw4K/b2tqiqqpGIpGI4/HHH/9rQ0PDCa/XOyoSidDLly8PNTU1PcZ4QuNK1ju6NYHFRAGASXPnzv1Fa2vrxzTDpapqateuXR/Nnz+/SVGUhwFMBzCBFSLZLF75DsrJGpXRAH4EIABgPIBxAEoBFAPwARjFif1sNzZ25+VlOhaxufcCqAFQC+BhAPVLliz5XSqVUkOhUAuAKWnFyR3dlsw+fg+A+8eMGfPzTZs2bY9GozEb8JkzZ9qXLl36l+Li4l8B+AmAyQDGsGrOzfXNPGPawG2l85jksmcPm+vihH+2W1iF3bvZPN+sWbPuGx4eDrW3t+85fvz41o6OjmZN04Y0TYvV19cvYIbN5QqUjG2mwj5YAqDK4XDMe+aZZ55vbW09+sorr2yuqqpqYFatAuBn3uB7XzJCY297XeaUd2RoGzOJmHb6IjFj5D777LP3DQwMfDw8PBxSVbUvkUj0hEKhj1588cXH2O7zMSPdplumoxveMx5Zlj3jx4/39vb26gMDA4MsvgYZo+p8Pr7LqQX5Ds/U7d0jFxUVZS1atKg4Nzc317Isp67rZldXV6y5ufkmI78hFtcmrx8ZweMit6XsUs4+6kmlgbW+peLf9gyMZNCR374G0y/FxEzX8b/8+bkXEBxKFwAAAABJRU5ErkJggg==",y.tileXYToQuadKey=function(e,t,r){for(var i="",n=r;n>=0;--n){var o=1<<n,a=0;0!=(e&o)&&(a|=1),0!=(t&o)&&(a|=2),i+=a}return i},y.quadKeyToTileXY=function(e){for(var t=0,r=0,i=e.length-1,n=i;n>=0;--n){var o=1<<n,a=+e[i-n];0!=(1&a)&&(t|=o),0!=(2&a)&&(r|=o)}return{x:t,y:r,level:i}};var w=new c;return y}),define("Scene/BoxEmitter",["../Core/Cartesian3","../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/Math"],function(e,t,r,i,n){"use strict";function o(t){t=r(t,a),this._dimensions=e.clone(t)}var a=new e(1,1,1);i(o.prototype,{dimensions:{get:function(){return this._dimensions},set:function(t){e.clone(t,this._dimensions)}}});var s=new e;return o.prototype.emit=function(t){var r=this._dimensions,i=e.multiplyByScalar(r,.5,s),o=n.randomBetween(-i.x,i.x),a=n.randomBetween(-i.y,i.y),l=n.randomBetween(-i.z,i.z);t.position=e.fromElements(o,a,l,t.position),t.velocity=e.normalize(t.position,t.velocity)},o}),define("Shaders/BrdfLutGeneratorFS",[],function(){"use strict";return"varying vec2 v_textureCoordinates;\nconst float M_PI = 3.141592653589793;\nfloat vdcRadicalInverse(int i)\n{\nfloat r;\nfloat base = 2.0;\nfloat value = 0.0;\nfloat invBase = 1.0 / base;\nfloat invBi = invBase;\nfor (int x = 0; x < 100; x++)\n{\nif (i <= 0)\n{\nbreak;\n}\nr = mod(float(i), base);\nvalue += r * invBi;\ninvBi *= invBase;\ni = int(float(i) * invBase);\n}\nreturn value;\n}\nvec2 hammersley2D(int i, int N)\n{\nreturn vec2(float(i) / float(N), vdcRadicalInverse(i));\n}\nvec3 importanceSampleGGX(vec2 xi, float roughness, vec3 N)\n{\nfloat a = roughness * roughness;\nfloat phi = 2.0 * M_PI * xi.x;\nfloat cosTheta = sqrt((1.0 - xi.y) / (1.0 + (a * a - 1.0) * xi.y));\nfloat sinTheta = sqrt(1.0 - cosTheta * cosTheta);\nvec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);\nvec3 upVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\nvec3 tangentX = normalize(cross(upVector, N));\nvec3 tangentY = cross(N, tangentX);\nreturn tangentX * H.x + tangentY * H.y + N * H.z;\n}\nfloat G1_Smith(float NdotV, float k)\n{\nreturn NdotV / (NdotV * (1.0 - k) + k);\n}\nfloat G_Smith(float roughness, float NdotV, float NdotL)\n{\nfloat k = roughness * roughness / 2.0;\nreturn G1_Smith(NdotV, k) * G1_Smith(NdotL, k);\n}\nvec2 integrateBrdf(float roughness, float NdotV)\n{\nvec3 V = vec3(sqrt(1.0 - NdotV * NdotV), 0.0, NdotV);\nfloat A = 0.0;\nfloat B = 0.0;\nconst int NumSamples = 1024;\nfor (int i = 0; i < NumSamples; i++)\n{\nvec2 xi = hammersley2D(i, NumSamples);\nvec3 H = importanceSampleGGX(xi, roughness, vec3(0.0, 0.0, 1.0));\nvec3 L = 2.0 * dot(V, H) * H - V;\nfloat NdotL = clamp(L.z, 0.0, 1.0);\nfloat NdotH = clamp(H.z, 0.0, 1.0);\nfloat VdotH = clamp(dot(V, H), 0.0, 1.0);\nif (NdotL > 0.0)\n{\nfloat G = G_Smith(roughness, NdotV, NdotL);\nfloat G_Vis = G * VdotH / (NdotH * NdotV);\nfloat Fc = pow(1.0 - VdotH, 5.0);\nA += (1.0 - Fc) * G_Vis;\nB += Fc * G_Vis;\n}\n}\nreturn vec2(A, B) / float(NumSamples);\n}\nvoid main()\n{\ngl_FragColor = vec4(integrateBrdf(1.0 - v_textureCoordinates.y, v_textureCoordinates.x), 0.0, 1.0);\n}\n"}),define("Scene/BrdfLutGenerator",["../Core/BoundingRectangle","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/PixelFormat","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Shaders/BrdfLutGeneratorFS"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(){this._framebuffer=void 0,this._colorTexture=void 0,this._drawCommand=void 0}function m(t,r){var i=t._framebuffer,n=r.createViewportQuadCommand(p,{framebuffer:i,renderState:s.fromCache({viewport:new e(0,0,256,256)})});t._drawCommand=n}function g(e,t){var r=new u({context:t,width:256,height:256,pixelFormat:n.RGBA,pixelDatatype:a.UNSIGNED_BYTE,sampler:new l({wrapS:h.CLAMP_TO_EDGE,wrapT:h.CLAMP_TO_EDGE,minificationFilter:d.NEAREST,magnificationFilter:c.NEAREST})});e._colorTexture=r;var i=new o({context:t,colorTextures:[r],destroyAttachments:!1});e._framebuffer=i}return r(f.prototype,{colorTexture:{get:function(){return this._colorTexture}}}),f.prototype.update=function(e){if(!t(this._colorTexture)){var r=e.context;g(this,r),m(this,r),this._drawCommand.execute(r),this._framebuffer=this._framebuffer&&this._framebuffer.destroy(),this._drawCommand.shaderProgram=this._drawCommand.shaderProgram&&this._drawCommand.shaderProgram.destroy()}},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._colorTexture=this._colorTexture&&this._colorTexture.destroy(),i(this)},f}),define("Scene/CameraFlightPath",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/EasingFunction","../Core/Math","../Core/PerspectiveFrustum","../Core/PerspectiveOffCenterFrustum","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,t,r){var i,n,o;if(e instanceof l){var a=Math.tan(.5*e.fovy);return i=e.near,n=e.near*a,o=e.aspectRatio*n,Math.max(t*i/o,r*i/n)}return e instanceof u?(i=e.near,n=e.top,o=e.right,Math.max(t*i/o,r*i/n)):Math.max(t,r)}function h(e,t,r,i){if(n(i)&&r(.5)>i){var o=r(0),a=r(1),l=r(.5),u=l-o,c=l-a;return function(i){var n=r(i);if(i<=.5){var l=(n-o)/u;return s.lerp(e,-s.PI_OVER_TWO,l)}var d=(n-a)/c;return s.lerp(-s.PI_OVER_TWO,t,1-d)}}return function(r){return s.lerp(e,t,r)}}function p(e,r,i,o,a){var l=a,u=Math.max(i,o);if(!n(l)){var c=e.position,h=r,p=e.up,f=e.right,m=e.frustum,g=t.subtract(c,h,w),_=t.magnitude(t.multiplyByScalar(p,t.dot(g,p),T)),v=t.magnitude(t.multiplyByScalar(f,t.dot(g,f),T));l=Math.min(.2*d(m,_,v),1e9)}if(u<l){var y=-Math.pow(1e6*(l-i),1/8),b=Math.pow(1e6*(l-o),1/8);return function(e){var t=e*(b-y)+y;return-Math.pow(t,8)/1e6+l}}return function(e){return s.lerp(i,o,e)} +}function f(e,t){return s.equalsEpsilon(e,s.TWO_PI,s.EPSILON11)&&(e=0),t>e+Math.PI?e+=s.TWO_PI:t<e-Math.PI&&(e-=s.TWO_PI),e}function m(r,i,n,o,a,l,u){function c(t){var r=t.time/i;d.setView({orientation:{heading:s.lerp(g,o,r),pitch:s.lerp(m,a,r),roll:s.lerp(_,l,r)}}),e.lerp(h,n,r,d.position),d.position.z=v(r)}var d=r.camera,h=t.clone(d.position,E),m=d.pitch,g=f(d.heading,o),_=f(d.roll,l),v=p(d,n,h.z,n.z,u);return c}function g(e,t){e.longitude<t.longitude?e.longitude+=s.TWO_PI:t.longitude+=s.TWO_PI}function _(e,t){var r=e.longitude-t.longitude;r<-s.PI?e.longitude+=s.TWO_PI:r>s.PI&&(t.longitude+=s.TWO_PI)}function v(e,i,o,a,l,u,c,d,m,v){var y=e.camera,b=e.mapProjection,C=b.ellipsoid,S=r.clone(y.positionCartographic,A),w=y.pitch,T=f(y.heading,a),E=f(y.roll,u),P=C.cartesianToCartographic(o,x);S.longitude=s.zeroToTwoPi(S.longitude),P.longitude=s.zeroToTwoPi(P.longitude);var D=!1;if(n(d)){var I=s.zeroToTwoPi(d),O=Math.min(S.longitude,P.longitude),M=Math.max(S.longitude,P.longitude),R=I>=O&&I<=M;if(n(m)){var L=Math.abs(S.longitude-P.longitude),N=s.TWO_PI-L;(R?L:N)<(R?N:L)*m&&!R&&(D=!0)}else R||(D=!0)}D?g(S,P):_(S,P);var k=p(y,o,S.height,P.height,c),F=h(w,l,k,v);return function(){var e=S.longitude,r=P.longitude,n=S.latitude,o=P.latitude;return function(l){var c=l.time/i,d=t.fromRadians(s.lerp(e,r,c),s.lerp(n,o,c),k(c));y.setView({destination:d,orientation:{heading:s.lerp(T,a,c),pitch:F(c),roll:s.lerp(E,u,c)}})}}()}function y(r,i,n,o,a,l,u){function c(t){var r=t.time/i;d.setView({orientation:{heading:s.lerp(m,o,r)}}),e.lerp(h,n,r,d.position);var a=_(r),l=d.frustum,u=l.top/l.right,c=.5*(a-(l.right-l.left));l.right+=c,l.left-=c,l.top=u*l.right,l.bottom=-l.top}var d=r.camera,h=t.clone(d.position,E),m=f(d.heading,o),g=d.frustum.right-d.frustum.left,_=p(d,n,g,n.z,u);return c}function b(e,t){return{startObject:{},stopObject:{},duration:0,complete:e,cancel:t}}function C(e,t){function r(){"function"==typeof t&&t(),e.enableInputs=!0}return r}var S={},w=new t,T=new t,E=new t,A=new r,x=new r,P=new r,D=new t;return S.createTween=function(r,o){o=i(o,i.EMPTY_OBJECT);var l=o.destination,u=r.mode;if(u===c.MORPHING)return b();var d=i(o.convert,!0),h=r.mapProjection,p=h.ellipsoid,f=o.maximumHeight,g=o.flyOverLongitude,_=o.flyOverLongitudeWeight,S=o.pitchAdjustHeight,w=o.easingFunction;d&&u!==c.SCENE3D&&(p.cartesianToCartographic(l,P),l=h.project(P,D));var T=r.camera,E=o.endTransform;n(E)&&T._setTransform(E);var A=o.duration;n(A)||(A=Math.ceil(t.distance(T.position,l)/1e6)+2,A=Math.min(A,3));var x=i(o.heading,0),I=i(o.pitch,-s.PI_OVER_TWO),O=i(o.roll,0),M=r.screenSpaceCameraController;M.enableInputs=!1;var R=C(M,o.complete),L=C(M,o.cancel),N=T.frustum,k=r.mode===c.SCENE2D;if(k=k&&e.equalsEpsilon(T.position,l,s.EPSILON6),k=k&&s.equalsEpsilon(Math.max(N.right-N.left,N.top-N.bottom),l.z,s.EPSILON6),k=k||r.mode!==c.SCENE2D&&t.equalsEpsilon(l,T.position,s.EPSILON10),k=k&&s.equalsEpsilon(s.negativePiToPi(x),s.negativePiToPi(T.heading),s.EPSILON10)&&s.equalsEpsilon(s.negativePiToPi(I),s.negativePiToPi(T.pitch),s.EPSILON10)&&s.equalsEpsilon(s.negativePiToPi(O),s.negativePiToPi(T.roll),s.EPSILON10))return b(R,L);var F=new Array(4);if(F[c.SCENE2D]=y,F[c.SCENE3D]=v,F[c.COLUMBUS_VIEW]=m,A<=0){return b(function(){F[u](r,1,l,x,I,O,f,g,_,S)({time:1}),"function"==typeof R&&R()},L)}var B=F[u](r,A,l,x,I,O,f,g,_,S);if(!n(w)){var U=T.positionCartographic.height;w=U>(u===c.SCENE3D?p.cartesianToCartographic(l).height:l.z)&&U>11500?a.CUBIC_OUT:a.QUINTIC_IN_OUT}return{duration:A,easingFunction:w,startObject:{time:0},stopObject:{time:A},update:B,complete:R,cancel:L}},S}),define("Scene/MapMode2D",["../Core/freezeObject"],function(e){"use strict";return e({ROTATE:0,INFINITE_SCROLL:1})}),define("Scene/Camera",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/EasingFunction","../Core/Ellipsoid","../Core/EllipsoidGeodesic","../Core/Event","../Core/HeadingPitchRange","../Core/HeadingPitchRoll","../Core/Intersect","../Core/IntersectionTests","../Core/Math","../Core/Matrix3","../Core/Matrix4","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/Quaternion","../Core/Ray","../Core/Rectangle","../Core/Transforms","./CameraFlightPath","./MapMode2D","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D){"use strict";function I(e){this._scene=e,this._transform=y.clone(y.IDENTITY),this._invTransform=y.clone(y.IDENTITY),this._actualTransform=y.clone(y.IDENTITY),this._actualInvTransform=y.clone(y.IDENTITY),this._transformChanged=!1,this.position=new r,this._position=new r,this._positionWC=new r,this._positionCartographic=new n,this.direction=new r,this._direction=new r,this._directionWC=new r,this.up=new r,this._up=new r,this._upWC=new r,this.right=new r,this._right=new r,this._rightWC=new r,this.frustum=new S,this.frustum.aspectRatio=e.drawingBufferWidth/e.drawingBufferHeight,this.frustum.fov=_.toRadians(60),this.defaultMoveAmount=1e5,this.defaultLookAmount=Math.PI/60,this.defaultRotateAmount=Math.PI/3600,this.defaultZoomAmount=1e5,this.constrainedAxis=void 0,this.maximumZoomFactor=1.5,this._moveStart=new h,this._moveEnd=new h,this._changed=new h,this._changedPosition=void 0,this._changedDirection=void 0,this._changedFrustum=void 0,this.percentageChanged=.5,this._viewMatrix=new y,this._invViewMatrix=new y,O(this),this._mode=D.SCENE3D,this._modeChanged=!0;var t=e.mapProjection;this._projection=t,this._maxCoord=t.project(new n(Math.PI,_.PI_OVER_TWO)),this._max2Dfrustum=void 0,this._suspendTerrainAdjustment=!1,Q(this,I.DEFAULT_VIEW_RECTANGLE,this.position,!0);var i=r.magnitude(this.position);i+=i*I.DEFAULT_VIEW_FACTOR,r.normalize(this.position,this.position),r.multiplyByScalar(this.position,i,this.position)}function O(e){y.computeView(e._position,e._direction,e._up,e._right,e._viewMatrix),y.multiply(e._viewMatrix,e._actualInvTransform,e._viewMatrix),y.inverseTransformation(e._viewMatrix,e._invViewMatrix)}function M(e){A.basisTo2D(e._projection,e._transform,e._actualTransform)}function R(e){var t=e._projection,n=t.ellipsoid,o=y.getColumn(e._transform,3,me),a=n.cartesianToCartographic(o,he),s=t.project(a,pe),l=ge;l.x=s.z,l.y=s.x,l.z=s.y,l.w=1;var u=i.clone(i.UNIT_X,ye),c=i.add(y.getColumn(e._transform,0,fe),o,fe);n.cartesianToCartographic(c,a),t.project(a,s);var d=_e;d.x=s.z,d.y=s.x,d.z=s.y,d.w=0,r.subtract(d,l,d),d.x=0;var h=ve;if(r.magnitudeSquared(d)>_.EPSILON10)r.cross(u,d,h);else{var p=i.add(y.getColumn(e._transform,1,fe),o,fe);n.cartesianToCartographic(p,a),t.project(a,s),h.x=s.z,h.y=s.x,h.z=s.y,h.w=0,r.subtract(h,l,h),h.x=0,r.magnitudeSquared(h)<_.EPSILON10&&(i.clone(i.UNIT_Y,d),i.clone(i.UNIT_Z,h))}r.cross(h,u,d),r.normalize(d,d),r.cross(u,d,h),r.normalize(h,h),y.setColumn(e._actualTransform,0,d,e._actualTransform),y.setColumn(e._actualTransform,1,h,e._actualTransform),y.setColumn(e._actualTransform,2,u,e._actualTransform),y.setColumn(e._actualTransform,3,l,e._actualTransform)}function L(e){var t=e._mode,i=!1,n=0;t===D.SCENE2D&&(n=e.frustum.right-e.frustum.left,i=n!==e._positionCartographic.height);var o=e._position,a=!r.equals(o,e.position)||i;a&&(o=r.clone(e.position,e._position));var s=e._direction,l=!r.equals(s,e.direction);l&&(r.normalize(e.direction,e.direction),s=r.clone(e.direction,e._direction));var u=e._up,c=!r.equals(u,e.up);c&&(r.normalize(e.up,e.up),u=r.clone(e.up,e._up));var d=e._right,h=!r.equals(d,e.right);h&&(r.normalize(e.right,e.right),d=r.clone(e.right,e._right));var p=e._transformChanged||e._modeChanged;e._transformChanged=!1,p&&(y.inverseTransformation(e._transform,e._invTransform),e._mode===D.COLUMBUS_VIEW||e._mode===D.SCENE2D?y.equals(y.IDENTITY,e._transform)?y.clone(I.TRANSFORM_2D,e._actualTransform):e._mode===D.COLUMBUS_VIEW?M(e):R(e):y.clone(e._transform,e._actualTransform),y.inverseTransformation(e._actualTransform,e._actualInvTransform),e._modeChanged=!1);var f=e._actualTransform;if(a||p)if(e._positionWC=y.multiplyByPoint(f,o,e._positionWC),t===D.SCENE3D||t===D.MORPHING)e._positionCartographic=e._projection.ellipsoid.cartesianToCartographic(e._positionWC,e._positionCartographic);else{var m=be;m.x=e._positionWC.y,m.y=e._positionWC.z,m.z=e._positionWC.x,t===D.SCENE2D&&(m.z=n),e._projection.unproject(m,e._positionCartographic)}if(l||c||h){var g=r.dot(s,r.cross(u,d,be));if(Math.abs(1-g)>_.EPSILON2){var v=1/r.magnitudeSquared(u),b=r.dot(u,s)*v,C=r.multiplyByScalar(s,b,be);u=r.normalize(r.subtract(u,C,e._up),e._up),r.clone(u,e.up),d=r.cross(s,u,e._right),r.clone(d,e.right)}}(l||p)&&(e._directionWC=y.multiplyByPointAsVector(f,s,e._directionWC),r.normalize(e._directionWC,e._directionWC)),(c||p)&&(e._upWC=y.multiplyByPointAsVector(f,u,e._upWC),r.normalize(e._upWC,e._upWC)),(h||p)&&(e._rightWC=y.multiplyByPointAsVector(f,d,e._rightWC),r.normalize(e._rightWC,e._rightWC)),(a||l||c||h||p)&&O(e)}function N(e,t){var r;return r=_.equalsEpsilon(Math.abs(e.z),1,_.EPSILON3)?Math.atan2(t.y,t.x)-_.PI_OVER_TWO:Math.atan2(e.y,e.x)-_.PI_OVER_TWO,_.TWO_PI-_.zeroToTwoPi(r)}function k(e){return _.PI_OVER_TWO-_.acosClamped(e.z)}function F(e,t,r){var i=0;return _.equalsEpsilon(Math.abs(e.z),1,_.EPSILON3)||(i=Math.atan2(-r.z,t.z),i=_.zeroToTwoPi(i+_.TWO_PI)),i}function B(e,t,i){var n=y.clone(e.transform,Oe),o=A.eastNorthUpToFixedFrame(t,e._projection.ellipsoid,Me);e._setTransform(o),r.clone(r.ZERO,e.position),i.heading=i.heading-_.PI_OVER_TWO;var a=w.fromHeadingPitchRoll(i,Re),s=v.fromQuaternion(a,Le);v.getColumn(s,0,e.direction),v.getColumn(s,2,e.up),r.cross(e.direction,e.up,e.right),e._setTransform(n),e._adjustOrthographicFrustum(!0)}function U(e,t,i,n){var o=y.clone(e.transform,Oe);if(e._setTransform(y.IDENTITY),!r.equals(t,e.positionWC)){if(n){var a=e._projection,s=a.ellipsoid.cartesianToCartographic(t,Ne);t=a.project(s,Ie)}r.clone(t,e.position)}i.heading=i.heading-_.PI_OVER_TWO;var l=w.fromHeadingPitchRoll(i,Re),u=v.fromQuaternion(l,Le);v.getColumn(u,0,e.direction),v.getColumn(u,2,e.up),r.cross(e.direction,e.up,e.right),e._setTransform(o),e._adjustOrthographicFrustum(!0)}function V(e,i,n,o){var a=y.clone(e.transform,Oe);if(e._setTransform(y.IDENTITY),!r.equals(i,e.positionWC)){if(o){var s=e._projection,l=s.ellipsoid.cartesianToCartographic(i,Ne);i=s.project(l,Ie)}t.clone(i,e.position);var u=.5*-i.z,c=-u,d=e.frustum;if(c>u){var h=d.top/d.right;d.right=c,d.left=u,d.top=d.right*h,d.bottom=-d.top}}if(e._scene.mapMode2D===P.ROTATE){n.heading=n.heading-_.PI_OVER_TWO,n.pitch=-_.PI_OVER_TWO,n.roll=0;var p=w.fromHeadingPitchRoll(n,Re),f=v.fromQuaternion(p,Le);v.getColumn(f,2,e.up),r.cross(e.direction,e.up,e.right)}e._setTransform(a)}function z(e,t,i,n){var o=r.clone(i.direction,ke),a=r.clone(i.up,Fe);if(e._scene.mode===D.SCENE3D){var s=e._projection.ellipsoid,l=A.eastNorthUpToFixedFrame(t,s,Ce),u=y.inverseTransformation(l,Se);y.multiplyByPointAsVector(u,o,o),y.multiplyByPointAsVector(u,a,a)}var c=r.cross(o,a,Be);return n.heading=N(o,a),n.pitch=k(o),n.roll=F(o,a,c),n}function G(e,t){var r,i,n=e._scene.mapMode2D===P.ROTATE,o=e._maxCoord.x,a=e._maxCoord.y;n?(i=o,r=-i):(i=t.x-2*o,r=t.x+2*o),t.x>o&&(t.x=i),t.x<-o&&(t.x=r),t.y>a&&(t.y=a),t.y<-a&&(t.y=-a)}function W(e,t){var i=e.position,n=r.normalize(i,Ye);if(a(e.constrainedAxis)){var o=r.equalsEpsilon(n,e.constrainedAxis,_.EPSILON2),s=r.equalsEpsilon(n,r.negate(e.constrainedAxis,Ze),_.EPSILON2);if(o||s)(o&&t<0||s&&t>0)&&e.rotate(e.right,t);else{var l=r.normalize(e.constrainedAxis,Xe),u=r.dot(n,l),c=_.acosClamped(u);t>0&&t>c&&(t=c-_.EPSILON4),u=r.dot(n,r.negate(l,Ze)),c=_.acosClamped(u),t<0&&-t>c&&(t=-c+_.EPSILON4);var d=r.cross(l,n,Qe);e.rotate(d,t)}}else e.rotate(e.right,t)}function H(e,t){a(e.constrainedAxis)?e.rotate(e.constrainedAxis,t):e.rotate(e.up,t)}function j(e,t){var r,i=e.frustum;if(t*=.5,Math.abs(i.top)+Math.abs(i.bottom)>Math.abs(i.left)+Math.abs(i.right)){var n=i.top-t,o=i.bottom+t,a=e._maxCoord.y;e._scene.mapMode2D===P.ROTATE&&(a*=e.maximumZoomFactor),o>a&&(o=a,n=-a),n<=o&&(n=1,o=-1),r=i.right/i.top,i.top=n,i.bottom=o,i.right=i.top*r,i.left=-i.right}else{var s=i.right-t,l=i.left+t,u=e._maxCoord.x;e._scene.mapMode2D===P.ROTATE&&(u*=e.maximumZoomFactor),s>u&&(s=u,l=-u),s<=l&&(s=1,l=-1),r=i.top/i.right,i.right=s,i.left=l,i.top=i.right*r,i.bottom=-i.top}}function q(e,t){e.move(e.direction,t)}function Y(e,t,i){t=_.clamp(t,-_.PI_OVER_TWO,_.PI_OVER_TWO),e=_.zeroToTwoPi(e)-_.PI_OVER_TWO;var n=w.fromAxisAngle(r.UNIT_Y,-t,$e),o=w.fromAxisAngle(r.UNIT_Z,-e,et),a=w.multiply(o,n,o),s=v.fromQuaternion(a,tt),l=r.clone(r.UNIT_X,Je);return v.multiplyByVector(s,l,l),r.negate(l,l),r.multiplyByScalar(l,i,l),l}function X(e,t,i,n){return Math.abs(r.dot(t,i))/n-r.dot(e,i)}function Q(e,t,i,n){var o=e._projection.ellipsoid,s=n?e:pt,l=t.north,u=t.south,c=t.east,h=t.west;h>c&&(c+=_.TWO_PI);var p,f=.5*(h+c);if(u<-_.PI_OVER_TWO+_.RADIANS_PER_DEGREE&&l>_.PI_OVER_TWO-_.RADIANS_PER_DEGREE)p=0;else{var m=it;m.longitude=f,m.latitude=l,m.height=0;var g=nt;g.longitude=f,g.latitude=u,g.height=0;var v=rt;a(v)&&v.ellipsoid===o||(rt=v=new d(void 0,void 0,o)),v.setEndPoints(m,g),p=v.interpolateUsingFraction(.5,it).latitude}var y=it;y.longitude=f,y.latitude=p,y.height=0;var C=o.cartographicToCartesian(y,dt),S=it;S.longitude=c,S.latitude=l;var w=o.cartographicToCartesian(S,ot);S.longitude=h;var T=o.cartographicToCartesian(S,st);S.longitude=f;var E=o.cartographicToCartesian(S,ut);S.latitude=u;var A=o.cartographicToCartesian(S,ct);S.longitude=c;var x=o.cartographicToCartesian(S,lt);S.longitude=h;var P=o.cartographicToCartesian(S,at);r.subtract(T,C,T),r.subtract(x,C,x),r.subtract(w,C,w),r.subtract(P,C,P),r.subtract(E,C,E),r.subtract(A,C,A);var D=o.geodeticSurfaceNormal(C,s.direction);r.negate(D,D);var I=r.cross(D,r.UNIT_Z,s.right);r.normalize(I,I);var O,M=r.cross(I,D,s.up);if(e.frustum instanceof b){var R,L,N=Math.max(r.distance(w,T),r.distance(x,P)),k=Math.max(r.distance(w,x),r.distance(T,P)),F=e.frustum._offCenterFrustum.right/e.frustum._offCenterFrustum.top,B=k*F;N>B?(R=N,L=R/F):(L=k,R=B),O=Math.max(R,L)}else{var U=Math.tan(.5*e.frustum.fovy),V=e.frustum.aspectRatio*U;if(O=Math.max(X(D,M,T,U),X(D,M,x,U),X(D,M,w,U),X(D,M,P,U),X(D,M,E,U),X(D,M,A,U),X(D,I,T,V),X(D,I,x,V),X(D,I,w,V),X(D,I,P,V),X(D,I,E,V),X(D,I,A,V)),u<0&&l>0){var z=it;z.longitude=h,z.latitude=0,z.height=0;var G=o.cartographicToCartesian(z,ht);r.subtract(G,C,G),O=Math.max(O,X(D,M,G,U),X(D,I,G,V)),z.longitude=c,G=o.cartographicToCartesian(z,ht),r.subtract(G,C,G),O=Math.max(O,X(D,M,G,U),X(D,I,G,V))}}return r.add(C,r.multiplyByScalar(D,-O,ht),i)}function Z(e,t,r){var i=e._projection;t.west>t.east&&(t=E.MAX_VALUE);var n=e._actualTransform,o=e._actualInvTransform,s=ft;s.longitude=t.east,s.latitude=t.north;var l=i.project(s,mt);y.multiplyByPoint(n,l,l),y.multiplyByPoint(o,l,l),s.longitude=t.west,s.latitude=t.south;var u=i.project(s,gt);if(y.multiplyByPoint(n,u,u),y.multiplyByPoint(o,u,u),r.x=.5*(l.x-u.x)+u.x,r.y=.5*(l.y-u.y)+u.y,a(e.frustum.fovy)){var c=Math.tan(.5*e.frustum.fovy),d=e.frustum.aspectRatio*c;r.z=.5*Math.max((l.x-u.x)/d,(l.y-u.y)/c)}else{var h=l.x-u.x,p=l.y-u.y;r.z=Math.max(h,p)}return r}function K(e,t,r){var i=e._projection;t.west>t.east&&(t=E.MAX_VALUE);var n=_t;n.longitude=t.east,n.latitude=t.north;var o=i.project(n,vt);n.longitude=t.west,n.latitude=t.south;var a,s,l=i.project(n,yt),u=.5*Math.abs(o.x-l.x),c=.5*Math.abs(o.y-l.y),d=e.frustum.right/e.frustum.top,h=c*d;return u>h?(a=u,s=a/d):(s=c,a=h),c=Math.max(2*a,2*s),r.x=.5*(o.x-l.x)+l.x,r.y=.5*(o.y-l.y)+l.y,n=i.unproject(r,n),n.height=c,r=i.project(n,r)}function J(e,t,r,i){r=o(r,c.WGS84);var n=e.getPickRay(t,bt),a=g.rayEllipsoid(n,r);if(a){var s=a.start>0?a.start:a.stop;return T.getPoint(n,s,i)}}function $(e,t,r,i){var n=e.getPickRay(t,Ct),o=n.origin;o.z=0;var a=r.unproject(o);if(!(a.latitude<-_.PI_OVER_TWO||a.latitude>_.PI_OVER_TWO))return r.ellipsoid.cartographicToCartesian(a,i)}function ee(e,t,i,n){var o=e.getPickRay(t,St),a=-o.origin.x/o.direction.x;T.getPoint(o,a,n);var s=i.unproject(new r(n.y,n.z,0));if(!(s.latitude<-_.PI_OVER_TWO||s.latitude>_.PI_OVER_TWO||s.longitude<-Math.PI||s.longitude>Math.PI))return i.ellipsoid.cartographicToCartesian(s,n)}function te(e,t,i){var n=e._scene.canvas,o=n.clientWidth,a=n.clientHeight,s=Math.tan(.5*e.frustum.fovy),l=e.frustum.aspectRatio*s,u=e.frustum.near,c=2/o*t.x-1,d=2/a*(a-t.y)-1,h=e.positionWC;r.clone(h,i.origin);var p=r.multiplyByScalar(e.directionWC,u,wt);r.add(h,p,p);var f=r.multiplyByScalar(e.rightWC,c*u*l,Tt),m=r.multiplyByScalar(e.upWC,d*u*s,Et),g=r.add(p,f,i.direction);return r.add(g,m,g),r.subtract(g,h,g),r.normalize(g,g),i}function re(e,t,i){var n=e._scene.canvas,o=n.clientWidth,s=n.clientHeight,l=e.frustum;a(l._offCenterFrustum)&&(l=l._offCenterFrustum);var u=2/o*t.x-1;u*=.5*(l.right-l.left);var c=2/s*(s-t.y)-1;c*=.5*(l.top-l.bottom);var d=i.origin;return r.clone(e.position,d),r.multiplyByScalar(e.right,u,At),r.add(At,d,d),r.multiplyByScalar(e.up,c,At),r.add(At,d,d),r.clone(e.directionWC,i.direction),e._mode===D.COLUMBUS_VIEW&&r.fromElements(i.origin.z,i.origin.x,i.origin.y,i.origin),i}function ie(e,t,i,n,o,a){function s(i){var n=r.lerp(t,l,i.time,new r);e.worldToCameraCoordinatesPoint(n,e.position)}var l=r.clone(t);return i.y>n?l.y-=i.y-n:i.y<-n&&(l.y+=-n-i.y),i.z>o?l.z-=i.z-o:i.z<-o&&(l.z+=-o-i.z),{easingFunction:u.EXPONENTIAL_OUT,startObject:{time:0},stopObject:{time:1},duration:a,update:s}}function ne(e,t){var i=e.position,n=e.direction,o=e.worldToCameraCoordinatesVector(r.UNIT_X,It),a=-r.dot(o,i)/r.dot(o,n),s=r.add(i,r.multiplyByScalar(n,a,Ot),Ot);e.cameraToWorldCoordinatesPoint(s,s),i=e.cameraToWorldCoordinatesPoint(e.position,Mt);var l=Math.tan(.5*e.frustum.fovy),u=e.frustum.aspectRatio*l,c=r.magnitude(r.subtract(i,s,Rt)),d=u*c,h=l*c,p=e._maxCoord.x,f=e._maxCoord.y,m=Math.max(d-p,p),g=Math.max(h-f,f);if(i.z<-m||i.z>m||i.y<-g||i.y>g){var _=s.y<-m||s.y>m,v=s.z<-g||s.z>g;if(_||v)return ie(e,i,s,m,g,t)}}function oe(e,t){var r=e.frustum,i=Math.tan(.5*r.fovy),n=r.aspectRatio*i;return Math.max(t/n,t/i)}function ae(e,t){var r=e.frustum;a(r._offCenterFrustum)&&(r=r._offCenterFrustum);var i,n,o=r.right/r.top,s=t*o;return t>s?(i=t,n=i/o):(n=t,i=s),1.5*Math.max(i,n)}function se(e,t,r){a(r)||(r=p.clone(I.DEFAULT_OFFSET));var i=e._scene.screenSpaceCameraController.minimumZoomDistance,n=e._scene.screenSpaceCameraController.maximumZoomDistance,o=r.range;if(!a(o)||0===o){var s=t.radius;0===s?r.range=kt:e.frustum instanceof b||e._mode===D.SCENE2D?r.range=ae(e,s):r.range=oe(e,s),r.range=_.clamp(r.range,i,n)}return r}function le(e,t){var i,n,o=t.radii,a=e.positionWC,s=r.multiplyComponents(t.oneOverRadii,a,jt),l=r.magnitude(s),u=r.normalize(s,qt);r.equalsEpsilon(u,r.UNIT_Z,_.EPSILON10)?(i=new r(0,1,0),n=new r(0,0,1)):(i=r.normalize(r.cross(r.UNIT_Z,u,Yt),Yt),n=r.normalize(r.cross(u,i,Xt),Xt));var c=Math.sqrt(r.magnitudeSquared(s)-1),d=r.multiplyByScalar(u,1/l,jt),h=c/l,p=r.multiplyByScalar(i,h,qt),f=r.multiplyByScalar(n,h,Yt),m=r.add(d,f,Qt[0]);r.subtract(m,p,m),r.multiplyComponents(o,m,m);var g=r.subtract(d,f,Qt[1]);r.subtract(g,p,g),r.multiplyComponents(o,g,g);var v=r.subtract(d,f,Qt[2]);r.add(v,p,v),r.multiplyComponents(o,v,v);var y=r.add(d,f,Qt[3]);return r.add(y,p,y),r.multiplyComponents(o,y,y),Qt}function ue(e,t,r,i,n,o){Zt.x=e,Zt.y=t;var s=i.pickEllipsoid(Zt,n,Kt);return a(s)?(Jt[r]=n.cartesianToCartographic(s,Jt[r]),1):(Jt[r]=n.cartesianToCartographic(o[r],Jt[r]),0)}I.TRANSFORM_2D=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),I.TRANSFORM_2D_INVERSE=y.inverseTransformation(I.TRANSFORM_2D,new y),I.DEFAULT_VIEW_RECTANGLE=E.fromDegrees(-95,-20,-70,90),I.DEFAULT_VIEW_FACTOR=.5,I.DEFAULT_OFFSET=new p(0,-_.PI_OVER_FOUR,0),I.prototype._updateCameraChanged=function(){var e=this;if(0!==e._changed.numberOfListeners){var t=e.percentageChanged;if(e._mode===D.SCENE2D){if(!a(e._changedFrustum))return e._changedPosition=r.clone(e.position,e._changedPosition),void(e._changedFrustum=e.frustum.clone());var i,n=e.position,o=e._changedPosition,s=e.frustum,l=e._changedFrustum,u=n.x+s.left,c=n.x+s.right,d=o.x+l.left,h=o.x+l.right,p=n.y+s.bottom,f=n.y+s.top,m=o.y+l.bottom,g=o.y+l.top,v=Math.max(u,d),y=Math.min(c,h),b=Math.max(p,m),C=Math.min(f,g);if(v>=y||b>=f)i=1;else{var S=l;u<d&&c>h&&p<m&&f>g&&(S=s),i=1-(y-v)*(C-b)/((S.right-S.left)*(S.top-S.bottom))}return void(i>t&&(e._changed.raiseEvent(i),e._changedPosition=r.clone(e.position,e._changedPosition),e._changedFrustum=e.frustum.clone(e._changedFrustum)))}if(!a(e._changedDirection))return e._changedPosition=r.clone(e.positionWC,e._changedPosition),void(e._changedDirection=r.clone(e.directionWC,e._changedDirection));var w,T=_.acosClamped(r.dot(e.directionWC,e._changedDirection));w=a(e.frustum.fovy)?T/(.5*e.frustum.fovy):T;var E=r.distance(e.positionWC,e._changedPosition),A=E/e.positionCartographic.height;(w>t||A>t)&&(e._changed.raiseEvent(Math.max(w,A)),e._changedPosition=r.clone(e.positionWC,e._changedPosition),e._changedDirection=r.clone(e.directionWC,e._changedDirection))}};var ce=new y,de=new n;I.prototype._adjustHeightForTerrain=function(){var e=this._scene,t=e.screenSpaceCameraController,i=t.enableCollisionDetection,n=t.minimumCollisionTerrainHeight,o=t.minimumZoomDistance;if(!this._suspendTerrainAdjustment&&i){var s=this._mode,l=e.globe;if(a(l)&&s!==D.SCENE2D&&s!==D.MORPHING){var u,c,d=l.ellipsoid,h=e.mapProjection;y.equals(this.transform,y.IDENTITY)||(u=y.clone(this.transform,ce),c=r.magnitude(this.position),this._setTransform(y.IDENTITY));var p=de;s===D.SCENE3D?d.cartesianToCartographic(this.position,p):h.unproject(this.position,p);var f=!1;if(p.height<n){var m=l.getHeight(p);a(m)&&(m+=o,p.height<m&&(p.height=m,s===D.SCENE3D?d.cartographicToCartesian(p,this.position):h.project(p,this.position),f=!0))}a(u)&&(this._setTransform(u),f&&(r.normalize(this.position,this.position),r.negate(this.position,this.direction),r.multiplyByScalar(this.position,Math.max(c,o),this.position),r.normalize(this.direction,this.direction),r.cross(this.direction,this.up,this.right),r.cross(this.right,this.direction,this.up)))}}};var he=new n,pe=new r,fe=new r,me=new i,ge=new i,_e=new i,ve=new i,ye=new i,be=new r,Ce=new y,Se=new y;s(I.prototype,{transform:{get:function(){return this._transform}},inverseTransform:{get:function(){return L(this),this._invTransform}},viewMatrix:{get:function(){return L(this),this._viewMatrix}},inverseViewMatrix:{get:function(){return L(this),this._invViewMatrix}},positionCartographic:{get:function(){return L(this),this._positionCartographic}},positionWC:{get:function(){return L(this),this._positionWC}},directionWC:{get:function(){return L(this),this._directionWC}},upWC:{get:function(){return L(this),this._upWC}},rightWC:{get:function(){return L(this),this._rightWC}},heading:{get:function(){if(this._mode!==D.MORPHING){var e=this._projection.ellipsoid,t=y.clone(this._transform,Ce),r=A.eastNorthUpToFixedFrame(this.positionWC,e,Se);this._setTransform(r);var i=N(this.direction,this.up);return this._setTransform(t),i}}},pitch:{get:function(){if(this._mode!==D.MORPHING){var e=this._projection.ellipsoid,t=y.clone(this._transform,Ce),r=A.eastNorthUpToFixedFrame(this.positionWC,e,Se);this._setTransform(r);var i=k(this.direction);return this._setTransform(t),i}}},roll:{get:function(){if(this._mode!==D.MORPHING){var e=this._projection.ellipsoid,t=y.clone(this._transform,Ce),r=A.eastNorthUpToFixedFrame(this.positionWC,e,Se);this._setTransform(r);var i=F(this.direction,this.up,this.right);return this._setTransform(t),i}}},moveStart:{get:function(){return this._moveStart}},moveEnd:{get:function(){return this._moveEnd}},changed:{get:function(){return this._changed}}}),I.prototype.update=function(e){var t=!1;if(e!==this._mode&&(this._mode=e,this._modeChanged=e!==D.MORPHING,t=this._mode===D.SCENE2D),t){var r=this._max2Dfrustum=this.frustum.clone(),i=r.top/r.right;r.right=2*this._maxCoord.x,r.left=-r.right,r.top=i*r.right,r.bottom=-r.top}this._mode===D.SCENE2D&&G(this,this.position);var n=this._scene.globe,o=!a(n)||n._surface.tileProvider.ready&&0===n._surface._tileLoadQueueHigh.length&&0===n._surface._tileLoadQueueMedium.length&&0===n._surface._tileLoadQueueLow.length&&0===n._surface._debug.tilesWaitingForChildren;this._suspendTerrainAdjustment&&(this._suspendTerrainAdjustment=!o),this._adjustHeightForTerrain()};var we=new r,Te=new r,Ee=new r;I.prototype._setTransform=function(e){var t=r.clone(this.positionWC,we),i=r.clone(this.upWC,Te),n=r.clone(this.directionWC,Ee);y.clone(e,this._transform),this._transformChanged=!0,L(this);var o=this._actualInvTransform;y.multiplyByPoint(o,t,this.position),y.multiplyByPointAsVector(o,n,this.direction),y.multiplyByPointAsVector(o,i,this.up),r.cross(this.direction,this.up,this.right),L(this)};var Ae=new t,xe=new T,Pe=new r,De=new r;I.prototype._adjustOrthographicFrustum=function(e){if(this.frustum instanceof b&&(e||!(this._positionCartographic.height<15e4))){if(!y.equals(y.IDENTITY,this.transform))return void(this.frustum.width=r.magnitude(this.position));var t,i,n=this._scene,o=n._globe;if(a(o)){var s=Ae;s.x=n.drawingBufferWidth/2,s.y=n.drawingBufferHeight/2;var l=this.getPickRay(s,xe);if(t=o.pick(l,n,Pe),n.pickPositionSupported&&(i=n.pickPositionWorldCoordinates(s,De)),a(t)&&a(i)){var u=a(i)?r.distance(i,this.positionWC):Number.POSITIVE_INFINITY,c=a(t)?r.distance(t,this.positionWC):Number.POSITIVE_INFINITY;this.frustum.width=Math.min(u,c)}else a(i)?this.frustum.width=r.distance(i,this.positionWC):a(t)&&(this.frustum.width=r.distance(t,this.positionWC))}if(!a(o)||!a(t)&&!a(i)){var d=Math.max(this.positionCartographic.height,0);this.frustum.width=d}}};var Ie=new r,Oe=new y,Me=new y,Re=new w,Le=new v,Ne=new n,ke=new r,Fe=new r,Be=new r,Ue={destination:void 0,orientation:{direction:void 0,up:void 0,heading:void 0,pitch:void 0,roll:void 0},convert:void 0,endTransform:void 0},Ve=new f;I.prototype.setView=function(e){e=o(e,o.EMPTY_OBJECT);var t=o(e.orientation,o.EMPTY_OBJECT),i=this._mode;if(i!==D.MORPHING){a(e.endTransform)&&this._setTransform(e.endTransform);var n=o(e.convert,!0),s=o(e.destination,r.clone(this.positionWC,Ie));a(s)&&a(s.west)&&(s=this.getRectangleCameraCoordinates(s,Ie),n=!1),a(t.direction)&&(t=z(this,s,t,Ue.orientation)),Ve.heading=o(t.heading,0),Ve.pitch=o(t.pitch,-_.PI_OVER_TWO),Ve.roll=o(t.roll,0),this._suspendTerrainAdjustment=!0,i===D.SCENE3D?B(this,s,Ve):i===D.SCENE2D?V(this,s,Ve,n):U(this,s,Ve,n)}};var ze=new r;I.prototype.flyHome=function(e){var t=this._mode;if(t===D.MORPHING&&this._scene.completeMorph(),t===D.SCENE2D)this.flyTo({destination:I.DEFAULT_VIEW_RECTANGLE,duration:e,endTransform:y.IDENTITY});else if(t===D.SCENE3D){var i=this.getRectangleCameraCoordinates(I.DEFAULT_VIEW_RECTANGLE),n=r.magnitude(i);n+=n*I.DEFAULT_VIEW_FACTOR,r.normalize(i,i),r.multiplyByScalar(i,n,i),this.flyTo({destination:i,duration:e,endTransform:y.IDENTITY})}else if(t===D.COLUMBUS_VIEW){var o=this._projection.ellipsoid.maximumRadius,a=new r(0,-1,1);a=r.multiplyByScalar(r.normalize(a,a),5*o,a),this.flyTo({destination:a,duration:e,orientation:{heading:0,pitch:-Math.acos(r.normalize(a,ze).z),roll:0},endTransform:y.IDENTITY,convert:!1})}},I.prototype.worldToCameraCoordinates=function(e,t){return a(t)||(t=new i),L(this),y.multiplyByVector(this._actualInvTransform,e,t)},I.prototype.worldToCameraCoordinatesPoint=function(e,t){return a(t)||(t=new r),L(this),y.multiplyByPoint(this._actualInvTransform,e,t)},I.prototype.worldToCameraCoordinatesVector=function(e,t){return a(t)||(t=new r),L(this),y.multiplyByPointAsVector(this._actualInvTransform,e,t)},I.prototype.cameraToWorldCoordinates=function(e,t){return a(t)||(t=new i),L(this),y.multiplyByVector(this._actualTransform,e,t)},I.prototype.cameraToWorldCoordinatesPoint=function(e,t){return a(t)||(t=new r),L(this),y.multiplyByPoint(this._actualTransform,e,t)},I.prototype.cameraToWorldCoordinatesVector=function(e,t){return a(t)||(t=new r),L(this),y.multiplyByPointAsVector(this._actualTransform,e,t)};var Ge=new r;I.prototype.move=function(e,t){var i=this.position;r.multiplyByScalar(e,t,Ge),r.add(i,Ge,i),this._mode===D.SCENE2D&&G(this,i),this._adjustOrthographicFrustum(!0)},I.prototype.moveForward=function(e){e=o(e,this.defaultMoveAmount),this._mode===D.SCENE2D?j(this,e):this.move(this.direction,e)},I.prototype.moveBackward=function(e){e=o(e,this.defaultMoveAmount),this._mode===D.SCENE2D?j(this,-e):this.move(this.direction,-e)},I.prototype.moveUp=function(e){e=o(e,this.defaultMoveAmount),this.move(this.up,e)},I.prototype.moveDown=function(e){e=o(e,this.defaultMoveAmount),this.move(this.up,-e)},I.prototype.moveRight=function(e){e=o(e,this.defaultMoveAmount),this.move(this.right,e)},I.prototype.moveLeft=function(e){e=o(e,this.defaultMoveAmount),this.move(this.right,-e)},I.prototype.lookLeft=function(e){e=o(e,this.defaultLookAmount),this._mode!==D.SCENE2D&&this.look(this.up,-e)},I.prototype.lookRight=function(e){e=o(e,this.defaultLookAmount),this._mode!==D.SCENE2D&&this.look(this.up,e)},I.prototype.lookUp=function(e){e=o(e,this.defaultLookAmount),this._mode!==D.SCENE2D&&this.look(this.right,-e)},I.prototype.lookDown=function(e){e=o(e,this.defaultLookAmount),this._mode!==D.SCENE2D&&this.look(this.right,e)};var We=new w,He=new v;I.prototype.look=function(e,t){var r=o(t,this.defaultLookAmount),i=w.fromAxisAngle(e,-r,We),n=v.fromQuaternion(i,He),a=this.direction,s=this.up,l=this.right;v.multiplyByVector(n,a,a),v.multiplyByVector(n,s,s),v.multiplyByVector(n,l,l)},I.prototype.twistLeft=function(e){e=o(e,this.defaultLookAmount),this.look(this.direction,e)},I.prototype.twistRight=function(e){e=o(e,this.defaultLookAmount),this.look(this.direction,-e)};var je=new w,qe=new v;I.prototype.rotate=function(e,t){var i=o(t,this.defaultRotateAmount),n=w.fromAxisAngle(e,-i,je),a=v.fromQuaternion(n,qe);v.multiplyByVector(a,this.position,this.position),v.multiplyByVector(a,this.direction,this.direction),v.multiplyByVector(a,this.up,this.up),r.cross(this.direction,this.up,this.right),r.cross(this.right,this.direction,this.up),this._adjustOrthographicFrustum(!1)},I.prototype.rotateDown=function(e){e=o(e,this.defaultRotateAmount),W(this,e)},I.prototype.rotateUp=function(e){e=o(e,this.defaultRotateAmount),W(this,-e)};var Ye=new r,Xe=new r,Qe=new r,Ze=new r;I.prototype.rotateRight=function(e){e=o(e,this.defaultRotateAmount),H(this,-e)},I.prototype.rotateLeft=function(e){e=o(e,this.defaultRotateAmount),H(this,e)},I.prototype.zoomIn=function(e){e=o(e,this.defaultZoomAmount),this._mode===D.SCENE2D?j(this,e):q(this,e)},I.prototype.zoomOut=function(e){e=o(e,this.defaultZoomAmount),this._mode===D.SCENE2D?j(this,-e):q(this,-e)},I.prototype.getMagnitude=function(){return this._mode===D.SCENE3D?r.magnitude(this.position):this._mode===D.COLUMBUS_VIEW?Math.abs(this.position.z):this._mode===D.SCENE2D?Math.max(this.frustum.right-this.frustum.left,this.frustum.top-this.frustum.bottom):void 0};var Ke=new y;I.prototype.lookAt=function(e,t){var r=A.eastNorthUpToFixedFrame(e,c.WGS84,Ke);this.lookAtTransform(r,t)};var Je=new r,$e=new w,et=new w,tt=new v;I.prototype.lookAtTransform=function(e,i){if(this._setTransform(e),a(i)){var n;if(n=a(i.heading)?Y(i.heading,i.pitch,i.range):i,this._mode===D.SCENE2D){t.clone(t.ZERO,this.position),r.negate(n,this.up),this.up.z=0,r.magnitudeSquared(this.up)<_.EPSILON10&&r.clone(r.UNIT_Y,this.up),r.normalize(this.up,this.up),this._setTransform(y.IDENTITY),r.negate(r.UNIT_Z,this.direction),r.cross(this.direction,this.up,this.right),r.normalize(this.right,this.right);var o=this.frustum,s=o.top/o.right;return o.right=.5*r.magnitude(n),o.left=-o.right,o.top=s*o.right,o.bottom=-o.top,void this._setTransform(e)}r.clone(n,this.position),r.negate(this.position,this.direction),r.normalize(this.direction,this.direction),r.cross(this.direction,r.UNIT_Z,this.right),r.magnitudeSquared(this.right)<_.EPSILON10&&r.clone(r.UNIT_X,this.right),r.normalize(this.right,this.right),r.cross(this.right,this.direction,this.up),r.normalize(this.up,this.up),this._adjustOrthographicFrustum(!0)}} +;var rt,it=new n,nt=new n,ot=new r,at=new r,st=new r,lt=new r,ut=new r,ct=new r,dt=new r,ht=new r,pt={direction:new r,right:new r,up:new r},ft=new n,mt=new r,gt=new r,_t=new n,vt=new r,yt=new r;I.prototype.getRectangleCameraCoordinates=function(e,t){var i=this._mode;return a(t)||(t=new r),i===D.SCENE3D?Q(this,e,t):i===D.COLUMBUS_VIEW?Z(this,e,t):i===D.SCENE2D?K(this,e,t):void 0};var bt=new T,Ct=new T,St=new T;I.prototype.pickEllipsoid=function(e,t,i){var n=this._scene.canvas;if(0!==n.clientWidth&&0!==n.clientHeight){if(a(i)||(i=new r),t=o(t,c.WGS84),this._mode===D.SCENE3D)i=J(this,e,t,i);else if(this._mode===D.SCENE2D)i=$(this,e,this._projection,i);else{if(this._mode!==D.COLUMBUS_VIEW)return;i=ee(this,e,this._projection,i)}return i}};var wt=new r,Tt=new r,Et=new r,At=new r;I.prototype.getPickRay=function(e,t){a(t)||(t=new T);var r=this.frustum;return a(r.aspectRatio)&&a(r.fov)&&a(r.near)?te(this,e,t):re(this,e,t)};var xt=new r,Pt=new r;I.prototype.distanceToBoundingSphere=function(e){var t=r.subtract(this.positionWC,e.center,xt),i=r.multiplyByScalar(this.directionWC,r.dot(t,this.directionWC),Pt);return Math.max(0,r.magnitude(i)-e.radius)};var Dt=new t;I.prototype.getPixelSize=function(e,t,r){var i=this.distanceToBoundingSphere(e),n=this.frustum.getPixelDimensions(t,r,i,Dt);return Math.max(n.x,n.y)};var It=new r,Ot=new r,Mt=new r,Rt=new r;I.prototype.createCorrectPositionTween=function(e){if(this._mode===D.COLUMBUS_VIEW)return ne(this,e)};var Lt=new r,Nt={destination:void 0,heading:void 0,pitch:void 0,roll:void 0,duration:void 0,complete:void 0,cancel:void 0,endTransform:void 0,maximumHeight:void 0,easingFunction:void 0};I.prototype.cancelFlight=function(){a(this._currentFlight)&&(this._currentFlight.cancelTween(),this._currentFlight=void 0)},I.prototype.flyTo=function(e){e=o(e,o.EMPTY_OBJECT);var t=e.destination;if(this._mode!==D.MORPHING){this.cancelFlight();var r=o(e.orientation,o.EMPTY_OBJECT);if(a(r.direction)&&(r=z(this,t,r,Ue.orientation)),a(e.duration)&&e.duration<=0){var i=Ue;return i.destination=e.destination,i.orientation.heading=r.heading,i.orientation.pitch=r.pitch,i.orientation.roll=r.roll,i.convert=e.convert,i.endTransform=e.endTransform,this.setView(i),void("function"==typeof e.complete&&e.complete())}var n=a(t.west);n&&(t=this.getRectangleCameraCoordinates(t,Lt));var s,l=this;Nt.destination=t,Nt.heading=r.heading,Nt.pitch=r.pitch,Nt.roll=r.roll,Nt.duration=e.duration,Nt.complete=function(){s===l._currentFlight&&(l._currentFlight=void 0),a(e.complete)&&e.complete()},Nt.cancel=e.cancel,Nt.endTransform=e.endTransform,Nt.convert=!n&&e.convert,Nt.maximumHeight=e.maximumHeight,Nt.pitchAdjustHeight=e.pitchAdjustHeight,Nt.flyOverLongitude=e.flyOverLongitude,Nt.flyOverLongitudeWeight=e.flyOverLongitudeWeight,Nt.easingFunction=e.easingFunction;var u=this._scene;s=u.tweens.add(x.createTween(u,Nt)),this._currentFlight=s}};var kt=100;I.prototype.viewBoundingSphere=function(e,t){t=se(this,e,t),this.lookAt(e.center,t)};var Ft=new y,Bt=new r,Ut=new r,Vt=new r,zt=new r,Gt=new i,Wt=new w,Ht=new v;I.prototype.flyToBoundingSphere=function(e,t){t=o(t,o.EMPTY_OBJECT);var i=this._mode===D.SCENE2D||this._mode===D.COLUMBUS_VIEW;this._setTransform(y.IDENTITY);var n,a=se(this,e,t.offset);n=i?r.multiplyByScalar(r.UNIT_Z,a.range,Bt):Y(a.heading,a.pitch,a.range);var s=A.eastNorthUpToFixedFrame(e.center,c.WGS84,Ft);y.multiplyByPoint(s,n,n);var l,u;if(!i){if(l=r.subtract(e.center,n,Ut),r.normalize(l,l),u=y.multiplyByPointAsVector(s,r.UNIT_Z,Vt),1-Math.abs(r.dot(l,u))<_.EPSILON6){var d=w.fromAxisAngle(l,a.heading,Wt),h=v.fromQuaternion(d,Ht);r.fromCartesian4(y.getColumn(s,1,Gt),u),v.multiplyByVector(h,u,u)}var p=r.cross(l,u,zt);r.cross(p,l,u),r.normalize(u,u)}this.flyTo({destination:n,orientation:{direction:l,up:u},duration:t.duration,complete:t.complete,cancel:t.cancel,endTransform:t.endTransform,maximumHeight:t.maximumHeight,easingFunction:t.easingFunction,flyOverLongitude:t.flyOverLongitude,flyOverLongitudeWeight:t.flyOverLongitudeWeight,pitchAdjustHeight:t.pitchAdjustHeight})};var jt=new r,qt=new r,Yt=new r,Xt=new r,Qt=[new r,new r,new r,new r],Zt=new t,Kt=new r,Jt=[new n,new n,new n,new n];return I.prototype.computeViewRectangle=function(t,i){t=o(t,c.WGS84);var n=this.frustum.computeCullingVolume(this.positionWC,this.directionWC,this.upWC),a=new e(r.ZERO,t.maximumRadius);if(n.computeVisibility(a)!==m.OUTSIDE){var s=this._scene.canvas,l=s.clientWidth,u=s.clientHeight,d=0,h=le(this,t);if(d+=ue(0,0,0,this,t,h),d+=ue(0,u,1,this,t,h),d+=ue(l,u,2,this,t,h),(d+=ue(l,0,3,this,t,h))<2)return E.MAX_VALUE;i=E.fromCartographicArray(Jt,i);for(var p=0,f=Jt[3].longitude,g=0;g<4;++g){var v=Jt[g].longitude,y=Math.abs(v-f);y>_.PI?p+=_.TWO_PI-y:p+=y,f=v}return _.equalsEpsilon(Math.abs(p),_.TWO_PI,_.EPSILON9)&&(i.west=-_.PI,i.east=_.PI,Jt[0].latitude>=0?i.north=_.PI_OVER_TWO:i.south=-_.PI_OVER_TWO),i}},I.prototype.switchToPerspectiveFrustum=function(){if(!(this._mode===D.SCENE2D||this.frustum instanceof S)){var e=this._scene;this.frustum=new S,this.frustum.aspectRatio=e.drawingBufferWidth/e.drawingBufferHeight,this.frustum.fov=_.toRadians(60)}},I.prototype.switchToOrthographicFrustum=function(){if(!(this._mode===D.SCENE2D||this.frustum instanceof b)){var e=this._scene;this.frustum=new b,this.frustum.aspectRatio=e.drawingBufferWidth/e.drawingBufferHeight,this.frustum.width=r.magnitude(this.position);var t=this.frustum.projectionMatrix;a(t)&&this._adjustOrthographicFrustum(!0)}},I.clone=function(e,t){return a(t)||(t=new I(e._scene)),r.clone(e.position,t.position),r.clone(e.direction,t.direction),r.clone(e.up,t.up),r.clone(e.right,t.right),y.clone(e._transform,t.transform),t._transformChanged=!0,t},I}),define("Scene/CameraEventType",["../Core/freezeObject"],function(e){"use strict";return e({LEFT_DRAG:0,RIGHT_DRAG:1,MIDDLE_DRAG:2,WHEEL:3,PINCH:4})}),define("Scene/CameraEventAggregator",["../Core/Cartesian2","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/KeyboardEventModifier","../Core/Math","../Core/ScreenSpaceEventHandler","../Core/ScreenSpaceEventType","./CameraEventType"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e,r){var i=e;return t(r)&&(i+="+"+r),i}function d(t,r){e.clone(t.distance.startPosition,r.distance.startPosition),e.clone(t.distance.endPosition,r.distance.endPosition),e.clone(t.angleAndHeight.startPosition,r.angleAndHeight.startPosition),e.clone(t.angleAndHeight.endPosition,r.angleAndHeight.endPosition)}function h(r,i,n){var o=c(u.PINCH,i),a=r._update,s=r._isDown,h=r._eventStartPosition,p=r._pressTime,f=r._releaseTime;a[o]=!0,s[o]=!1,h[o]=new e;var m=r._movement[o];t(m)||(m=r._movement[o]={}),m.distance={startPosition:new e,endPosition:new e},m.angleAndHeight={startPosition:new e,endPosition:new e},m.prevAngle=0,r._eventHandler.setInputAction(function(t){r._buttonsDown++,s[o]=!0,p[o]=new Date,e.lerp(t.position1,t.position2,.5,h[o])},l.PINCH_START,i),r._eventHandler.setInputAction(function(){r._buttonsDown=Math.max(r._buttonsDown-1,0),s[o]=!1,f[o]=new Date},l.PINCH_END,i),r._eventHandler.setInputAction(function(t){if(s[o]){a[o]?(d(t,m),a[o]=!1,m.prevAngle=m.angleAndHeight.startPosition.x):(e.clone(t.distance.endPosition,m.distance.endPosition),e.clone(t.angleAndHeight.endPosition,m.angleAndHeight.endPosition));for(var r=m.angleAndHeight.endPosition.x,i=m.prevAngle,l=2*Math.PI;r>=i+Math.PI;)r-=l;for(;r<i-Math.PI;)r+=l;m.angleAndHeight.endPosition.x=-r*n.clientWidth/12,m.angleAndHeight.startPosition.x=-i*n.clientWidth/12}},l.PINCH_MOVE,i)}function p(r,i){var n=c(u.WHEEL,i),o=r._update;o[n]=!0;var s=r._movement[n];t(s)||(s=r._movement[n]={}),s.startPosition=new e,s.endPosition=new e,r._eventHandler.setInputAction(function(t){var r=15*a.toRadians(t);o[n]?(e.clone(e.ZERO,s.startPosition),s.endPosition.x=0,s.endPosition.y=r,o[n]=!1):s.endPosition.y=s.endPosition.y+r},l.WHEEL,i)}function f(r,i,n){var o=c(n,i),a=r._isDown,s=r._eventStartPosition,d=r._pressTime,h=r._releaseTime;a[o]=!1,s[o]=new e;var p=r._lastMovement[o];t(p)||(p=r._lastMovement[o]={startPosition:new e,endPosition:new e,valid:!1});var f,m;n===u.LEFT_DRAG?(f=l.LEFT_DOWN,m=l.LEFT_UP):n===u.RIGHT_DRAG?(f=l.RIGHT_DOWN,m=l.RIGHT_UP):n===u.MIDDLE_DRAG&&(f=l.MIDDLE_DOWN,m=l.MIDDLE_UP),r._eventHandler.setInputAction(function(t){r._buttonsDown++,p.valid=!1,a[o]=!0,d[o]=new Date,e.clone(t.position,s[o])},f,i),r._eventHandler.setInputAction(function(){r._buttonsDown=Math.max(r._buttonsDown-1,0),a[o]=!1,h[o]=new Date},m,i)}function m(t,r){e.clone(t.startPosition,r.startPosition),e.clone(t.endPosition,r.endPosition)}function g(r,i){var n=r._update,o=r._movement,a=r._lastMovement,s=r._isDown;for(var d in u)if(u.hasOwnProperty(d)){var h=u[d];if(t(h)){var p=c(h,i);n[p]=!0,t(r._lastMovement[p])||(r._lastMovement[p]={startPosition:new e,endPosition:new e,valid:!1}),t(r._movement[p])||(r._movement[p]={startPosition:new e,endPosition:new e})}}r._eventHandler.setInputAction(function(l){for(var d in u)if(u.hasOwnProperty(d)){var h=u[d];if(t(h)){var p=c(h,i);s[p]&&(n[p]?(m(o[p],a[p]),a[p].valid=!0,m(l,o[p]),n[p]=!1):e.clone(l.endPosition,o[p].endPosition))}}e.clone(l.endPosition,r._currentMousePosition)},l.MOUSE_MOVE,i)}function _(r){this._eventHandler=new s(r,!0),this._update={},this._movement={},this._lastMovement={},this._isDown={},this._eventStartPosition={},this._pressTime={},this._releaseTime={},this._buttonsDown=0,this._currentMousePosition=new e,p(this,void 0),h(this,void 0,r),f(this,void 0,u.LEFT_DRAG),f(this,void 0,u.RIGHT_DRAG),f(this,void 0,u.MIDDLE_DRAG),g(this,void 0);for(var i in o)if(o.hasOwnProperty(i)){var n=o[i];t(n)&&(p(this,n),h(this,n,r),f(this,n,u.LEFT_DRAG),f(this,n,u.RIGHT_DRAG),f(this,n,u.MIDDLE_DRAG),g(this,n))}}return r(_.prototype,{currentMousePosition:{get:function(){return this._currentMousePosition}},anyButtonDown:{get:function(){var e=!(this._update[c(u.WHEEL)]&&this._update[c(u.WHEEL,o.SHIFT)]&&this._update[c(u.WHEEL,o.CTRL)]&&this._update[c(u.WHEEL,o.ALT)]);return this._buttonsDown>0||e}}}),_.prototype.isMoving=function(e,t){var r=c(e,t);return!this._update[r]},_.prototype.getMovement=function(e,t){var r=c(e,t);return this._movement[r]},_.prototype.getLastMovement=function(e,t){var r=c(e,t),i=this._lastMovement[r];if(i.valid)return i},_.prototype.isButtonDown=function(e,t){var r=c(e,t);return this._isDown[r]},_.prototype.getStartMousePosition=function(e,t){if(e===u.WHEEL)return this._currentMousePosition;var r=c(e,t);return this._eventStartPosition[r]},_.prototype.getButtonPressTime=function(e,t){var r=c(e,t);return this._pressTime[r]},_.prototype.getButtonReleaseTime=function(e,t){var r=c(e,t);return this._releaseTime[r]},_.prototype.reset=function(){for(var e in this._update)this._update.hasOwnProperty(e)&&(this._update[e]=!0)},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return this._eventHandler=this._eventHandler&&this._eventHandler.destroy(),i(this)},_}),define("Scene/Cesium3DTileChildrenVisibility",["../Core/freezeObject"],function(e){"use strict";return e({NONE:0,VISIBLE:1,IN_REQUEST_VOLUME:2,VISIBLE_IN_REQUEST_VOLUME:4,VISIBLE_NOT_IN_REQUEST_VOLUME:8})}),define("Scene/Composite3DTileContent",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/FeatureDetection","../Core/getMagic","../Core/RuntimeError","../ThirdParty/when"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r,i,n,o){this._tileset=e,this._tile=t,this._resource=r,this._contents=[],this._readyPromise=s.defer(),u(this,i,n,o)}function u(r,i,n,l){n=e(n,0);var u=new Uint8Array(i),d=new DataView(i);n+=c;var h=d.getUint32(n,!0);if(1!==h)throw new a("Only Composite Tile version 1 is supported. Version "+h+" is not.");n+=c,n+=c;var p=d.getUint32(n,!0);n+=c;for(var f=[],m=0;m<p;++m){var g=o(u,n),_=d.getUint32(n+2*c,!0),v=l[g];if(!t(v))throw new a("Unknown tile content type, "+g+", inside Composite tile");var y=v(r._tileset,r._tile,r._resource,i,n);r._contents.push(y),f.push(y.readyPromise),n+=_}s.all(f).then(function(){r._readyPromise.resolve(r)}).otherwise(function(e){r._readyPromise.reject(e)})}if(!n.supportsTypedArrays())return{};r(l.prototype,{featurePropertiesDirty:{get:function(){for(var e=this._contents,t=e.length,r=0;r<t;++r)if(e[r].featurePropertiesDirty)return!0;return!1},set:function(e){for(var t=this._contents,r=t.length,i=0;i<r;++i)t[i].featurePropertiesDirty=e}},featuresLength:{get:function(){return 0}},pointsLength:{get:function(){return 0}},trianglesLength:{get:function(){return 0}},geometryByteLength:{get:function(){return 0}},texturesByteLength:{get:function(){return 0}},batchTableByteLength:{get:function(){return 0}},innerContents:{get:function(){return this._contents}},readyPromise:{get:function(){return this._readyPromise.promise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){}}});var c=Uint32Array.BYTES_PER_ELEMENT;return l.prototype.hasProperty=function(e,t){return!1},l.prototype.getFeature=function(e){},l.prototype.applyDebugSettings=function(e,t){for(var r=this._contents,i=r.length,n=0;n<i;++n)r[n].applyDebugSettings(e,t)},l.prototype.applyStyle=function(e,t){for(var r=this._contents,i=r.length,n=0;n<i;++n)r[n].applyStyle(e,t)},l.prototype.update=function(e,t){for(var r=this._contents,i=r.length,n=0;n<i;++n)r[n].update(e,t)},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){for(var e=this._contents,t=e.length,r=0;r<t;++r)e[r].destroy();return i(this)},l}),define("Scene/Vector3DTileGeometry",["../Core/arraySlice","../Core/BoundingSphere","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Matrix4","../Core/TaskProcessor","../ThirdParty/when","./ClassificationType","./Vector3DTileBatch","./Vector3DTilePrimitive"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(e){this._boxes=e.boxes,this._boxBatchIds=e.boxBatchIds,this._cylinders=e.cylinders,this._cylinderBatchIds=e.cylinderBatchIds,this._ellipsoids=e.ellipsoids,this._ellipsoidBatchIds=e.ellipsoidBatchIds,this._spheres=e.spheres,this._sphereBatchIds=e.sphereBatchIds,this._modelMatrix=e.modelMatrix,this._batchTable=e.batchTable,this._boundingVolume=e.boundingVolume,this._center=e.center,o(this._center)||(o(this._boundingVolume)?this._center=r.clone(this._boundingVolume.center):this._center=r.clone(r.ZERO)),this._boundingVolumes=void 0,this._batchedIndices=void 0,this._indices=void 0,this._indexOffsets=void 0,this._indexCounts=void 0,this._positions=void 0,this._vertexBatchIds=void 0,this._batchIds=void 0,this._batchTableColors=void 0,this._packedBuffer=void 0,this._ready=!1,this._readyPromise=c.defer(),this._verticesPromise=void 0,this._primitive=void 0,this.debugWireframe=!1,this.forceRebatch=!1,this.classificationType=d.CESIUM_3D_TILE}function m(e){var t=new Float64Array(l.packedLength+r.packedLength),i=0;return r.pack(e._center,t,i),i+=r.packedLength,l.pack(e._modelMatrix,t,i),t}function g(e,r){for(var n=0,o=r[n++],a=r[n++],s=e._boundingVolumes=new Array(a),l=0;l<a;++l)s[l]=t.unpack(r,n),n+=t.packedLength;for(var u=r[n++],c=e._batchedIndices=new Array(u),d=0;d<u;++d){var p=i.unpack(r,n);n+=i.packedLength;for(var f=r[n++],m=r[n++],g=r[n++],_=new Array(g),v=0;v<g;++v)_[v]=r[n++];c[d]=new h({color:p,offset:f,count:m,batchIds:_})}return o}function _(t){if(!o(t._primitive)){if(!o(t._verticesPromise)){var r=t._boxes,i=t._boxBatchIds,a=t._cylinders,s=t._cylinderBatchIds,l=t._ellipsoids,u=t._ellipsoidBatchIds,c=t._spheres,d=t._sphereBatchIds,h=t._batchTableColors,f=t._packedBuffer;if(!o(h)){var _=0;o(t._boxes)&&(r=t._boxes=e(r),i=t._boxBatchIds=e(i),_+=i.length),o(t._cylinders)&&(a=t._cylinders=e(a),s=t._cylinderBatchIds=e(s),_+=s.length),o(t._ellipsoids)&&(l=t._ellipsoids=e(l),u=t._ellipsoidBatchIds=e(u),_+=u.length),o(t._spheres)&&(c=t._sphere=e(c),d=t._sphereBatchIds=e(d),_+=d.length),h=t._batchTableColors=new Uint32Array(_);for(var b=t._batchTable,C=0;C<_;++C){var S=b.getColor(C,y);h[C]=S.toRgba()}f=t._packedBuffer=m(t)}var w=[];o(r)&&w.push(r.buffer,i.buffer),o(a)&&w.push(a.buffer,s.buffer),o(l)&&w.push(l.buffer,u.buffer),o(c)&&w.push(c.buffer,d.buffer),w.push(h.buffer,f.buffer);var T={boxes:o(r)?r.buffer:void 0,boxBatchIds:o(r)?i.buffer:void 0,cylinders:o(a)?a.buffer:void 0,cylinderBatchIds:o(a)?s.buffer:void 0,ellipsoids:o(l)?l.buffer:void 0,ellipsoidBatchIds:o(l)?u.buffer:void 0,spheres:o(c)?c.buffer:void 0,sphereBatchIds:o(c)?d.buffer:void 0,batchTableColors:h.buffer,packedBuffer:f.buffer},E=t._verticesPromise=v.scheduleTask(T,w);if(!o(E))return;E.then(function(e){var r=new Float64Array(e.packedBuffer),i=g(t,r);t._indices=2===i?new Uint16Array(e.indices):new Uint32Array(e.indices),t._indexOffsets=new Uint32Array(e.indexOffsets),t._indexCounts=new Uint32Array(e.indexCounts),t._positions=new Float32Array(e.positions),t._vertexBatchIds=new Uint16Array(e.vertexBatchIds),t._batchIds=new Uint16Array(e.batchIds),t._ready=!0})}t._ready&&!o(t._primitive)&&(t._primitive=new p({batchTable:t._batchTable,positions:t._positions,batchIds:t._batchIds,vertexBatchIds:t._vertexBatchIds,indices:t._indices,indexOffsets:t._indexOffsets,indexCounts:t._indexCounts,batchedIndices:t._batchedIndices,boundingVolume:t._boundingVolume,boundingVolumes:t._boundingVolumes,center:t._center,pickObject:n(t._pickObject,t)}),t._boxes=void 0,t._boxBatchIds=void 0,t._cylinders=void 0,t._cylinderBatchIds=void 0,t._ellipsoids=void 0,t._ellipsoidBatchIds=void 0,t._spheres=void 0,t._sphereBatchIds=void 0,t._center=void 0,t._modelMatrix=void 0,t._batchTable=void 0,t._boundingVolume=void 0,t._boundingVolumes=void 0,t._batchedIndices=void 0,t._indices=void 0,t._indexOffsets=void 0,t._indexCounts=void 0,t._positions=void 0,t._vertexBatchIds=void 0,t._batchIds=void 0,t._batchTableColors=void 0,t._packedBuffer=void 0,t._verticesPromise=void 0,t._readyPromise.resolve())}}a(f.prototype,{trianglesLength:{get:function(){return o(this._primitive)?this._primitive.trianglesLength:0}},geometryByteLength:{get:function(){return o(this._primitive)?this._primitive.geometryByteLength:0}},readyPromise:{get:function(){return this._readyPromise.promise}}}),f.packedBoxLength=l.packedLength+r.packedLength,f.packedCylinderLength=l.packedLength+2,f.packedEllipsoidLength=l.packedLength+r.packedLength,f.packedSphereLength=r.packedLength+1;var v=new u("createVectorTileGeometries"),y=new i;return f.prototype.createFeatures=function(e,t){this._primitive.createFeatures(e,t)},f.prototype.applyDebugSettings=function(e,t){this._primitive.applyDebugSettings(e,t)},f.prototype.applyStyle=function(e,t,r){this._primitive.applyStyle(e,t,r)},f.prototype.updateCommands=function(e,t){this._primitive.updateCommands(e,t)},f.prototype.update=function(e){_(this),this._ready&&(this._primitive.debugWireframe=this.debugWireframe,this._primitive.forceRebatch=this.forceRebatch,this._primitive.classificationType=this.classificationType,this._primitive.update(e))},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._primitive=this._primitive&&this._primitive.destroy(),s(this)},f}),define("Scene/Geometry3DTileContent",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/getMagic","../Core/getStringFromTypedArray","../Core/Math","../Core/Matrix4","../Core/Rectangle","../Core/RuntimeError","../ThirdParty/when","./Cesium3DTileBatchTable","./Vector3DTileGeometry"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e,t,r,i,n){this._tileset=e,this._tile=t,this._resource=r,this._geometries=void 0,this._contentReadyPromise=void 0,this._readyPromise=f.defer(),this._batchTable=void 0,this._features=void 0,this.featurePropertiesDirty=!1,b(this,i,n)}function v(e){return function(t,i){r(e._geometries)&&e._geometries.updateCommands(t,i)}}function y(e,i){var n,o,a,s,l,u=t(e.BOXES_LENGTH,0),c=t(e.CYLINDERS_LENGTH,0),d=t(e.ELLIPSOIDS_LENGTH,0),h=t(e.SPHERES_LENGTH,0);if(u>0&&r(e.BOX_BATCH_IDS)){var f=i.byteOffset+e.BOX_BATCH_IDS.byteOffset;n=new Uint16Array(i.buffer,f,u)}if(c>0&&r(e.CYLINDER_BATCH_IDS)){var m=i.byteOffset+e.CYLINDER_BATCH_IDS.byteOffset;o=new Uint16Array(i.buffer,m,c)}if(d>0&&r(e.ELLIPSOID_BATCH_IDS)){var g=i.byteOffset+e.ELLIPSOID_BATCH_IDS.byteOffset;a=new Uint16Array(i.buffer,g,d)}if(h>0&&r(e.SPHERE_BATCH_IDS)){var _=i.byteOffset+e.SPHERE_BATCH_IDS.byteOffset;s=new Uint16Array(i.buffer,_,h)}var v=r(n)||r(o)||r(a)||r(s),y=u>0&&!r(n)||c>0&&!r(o)||d>0&&!r(a)||h>0&&!r(s);if(v&&y)throw new p("If one group of batch ids is defined, then all batch ids must be defined.");if(!(r(n)||r(o)||r(a)||r(s))){var b=0;if(!r(n)&&u>0)for(n=new Uint16Array(u),l=0;l<u;++l)n[l]=b++;if(!r(o)&&c>0)for(o=new Uint16Array(c),l=0;l<c;++l)o[l]=b++;if(!r(a)&&d>0)for(a=new Uint16Array(d),l=0;l<d;++l)a[l]=b++;if(!r(s)&&h>0)for(s=new Uint16Array(h),l=0;l<h;++l)s[l]=b++}return{boxes:n,cylinders:o,ellipsoids:a,spheres:s}}function b(i,n,o){o=t(o,0);var a=new Uint8Array(n),s=new DataView(n);o+=S;var l=s.getUint32(o,!0);if(1!==l)throw new p("Only Geometry tile version 1 is supported. Version "+l+" is not.");o+=S;var c=s.getUint32(o,!0);if(o+=S,0===c)return void i._readyPromise.resolve(i);var h=s.getUint32(o,!0);if(o+=S,0===h)throw new p("Feature table must have a byte length greater than zero");var f=s.getUint32(o,!0);o+=S;var _=s.getUint32(o,!0);o+=S;var b=s.getUint32(o,!0);o+=S;var C=u(a,o,h),w=JSON.parse(C);o+=h;var T=new Uint8Array(n,o,f);o+=f;var E,A;if(_>0){var x=u(a,o,_);E=JSON.parse(x),o+=_,b>0&&(A=new Uint8Array(n,o,b),A=new Uint8Array(A))}var P=t(w.BOXES_LENGTH,0),D=t(w.CYLINDERS_LENGTH,0),I=t(w.ELLIPSOIDS_LENGTH,0),O=t(w.SPHERES_LENGTH,0),M=P+D+I+O,R=new m(i,M,E,A,v(i));if(i._batchTable=R,0!==M){var L,N=i._tile.computedTransform;r(w.RTC_CENTER)&&(L=e.unpack(w.RTC_CENTER),d.multiplyByPoint(N,L,L));var k=y(w,T);if(P>0||D>0||I>0||O>0){var F,B,U,V;if(P>0){var z=T.byteOffset+w.BOXES.byteOffset;F=new Float32Array(T.buffer,z,g.packedBoxLength*P)}if(D>0){var G=T.byteOffset+w.CYLINDERS.byteOffset;B=new Float32Array(T.buffer,G,g.packedCylinderLength*D)}if(I>0){var W=T.byteOffset+w.ELLIPSOIDS.byteOffset;U=new Float32Array(T.buffer,W,g.packedEllipsoidLength*I)}if(O>0){var H=T.byteOffset+w.SPHERES.byteOffset;V=new Float32Array(T.buffer,H,g.packedSphereLength*O)}i._geometries=new g({boxes:F,boxBatchIds:k.boxes,cylinders:B,cylinderBatchIds:k.cylinders,ellipsoids:U,ellipsoidBatchIds:k.ellipsoids,spheres:V,sphereBatchIds:k.spheres,center:L,modelMatrix:N,batchTable:R,boundingVolume:i._tile._boundingVolume.boundingVolume})}}}function C(e){var t=e.featuresLength;if(!r(e._features)&&t>0){var i=new Array(t);r(e._geometries)&&e._geometries.createFeatures(e,i),e._features=i}}if(!s.supportsTypedArrays())return{};i(_.prototype,{featuresLength:{get:function(){return r(this._batchTable)?this._batchTable.featuresLength:0}},pointsLength:{get:function(){return 0}},trianglesLength:{get:function(){return r(this._geometries)?this._geometries.trianglesLength:0}},geometryByteLength:{get:function(){return r(this._geometries)?this._geometries.geometryByteLength:0}},texturesByteLength:{get:function(){return 0}},batchTableByteLength:{get:function(){return r(this._batchTable)?this._batchTable.memorySizeInBytes:0}},innerContents:{get:function(){}},readyPromise:{get:function(){return this._readyPromise.promise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){return this._batchTable}}});var S=Uint32Array.BYTES_PER_ELEMENT;return _.prototype.hasProperty=function(e,t){return this._batchTable.hasProperty(e,t)},_.prototype.getFeature=function(e){return C(this),this._features[e]},_.prototype.applyDebugSettings=function(e,t){r(this._geometries)&&this._geometries.applyDebugSettings(e,t)},_.prototype.applyStyle=function(e,t){C(this),r(this._geometries)&&this._geometries.applyStyle(e,t,this._features)},_.prototype.update=function(e,t){if(r(this._batchTable)&&this._batchTable.update(e,t),r(this._geometries)&&(this._geometries.classificationType=this._tileset.classificationType,this._geometries.debugWireframe=this._tileset.debugWireframe,this._geometries.update(t)),!r(this._contentReadyPromise)){var i=this;this._contentReadyPromise=this._geometries.readyPromise.then(function(){i._readyPromise.resolve(i)})}},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return this._geometries=this._geometries&&this._geometries.destroy(),this._batchTable=this._batchTable&&this._batchTable.destroy(),n(this)},_}),define("Scene/ModelInstance",["../Core/defineProperties","../Core/Matrix4"],function(e,t){"use strict";function r(e,r,i){this.primitive=e,this._modelMatrix=t.clone(r),this._instanceId=i}return e(r.prototype,{instanceId:{get:function(){return this._instanceId}},model:{get:function(){return this.primitive._model}},modelMatrix:{get:function(){return t.clone(this._modelMatrix)},set:function(e){t.clone(e,this._modelMatrix),this.primitive.expandBoundingSphere(this._modelMatrix),this.primitive._dirty=!0}}}),r}),define("Scene/ModelInstanceCollection",["../Core/BoundingSphere","../Core/Cartesian3","../Core/clone","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/DeveloperError","../Core/Matrix4","../Core/PrimitiveType","../Core/Resource","../Core/RuntimeError","../Core/Transforms","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/ShaderSource","../ThirdParty/when","./Model","./ModelInstance","./ModelUtility","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A){"use strict";function x(e){e=o(e,o.EMPTY_OBJECT),this.show=o(e.show,!0),this._instancingSupported=!1,this._dynamic=o(e.dynamic,!1),this._allowPicking=o(e.allowPicking,!0),this._ready=!1,this._readyPromise=C.defer(),this._state=ie.NEEDS_LOAD,this._dirty=!1,this._cull=o(e.cull,!0),this._opaquePass=o(e.opaquePass,y.OPAQUE),this._instances=P(this,e.instances),this._batchTable=e.batchTable,this._model=void 0,this._vertexBufferTypedArray=void 0,this._vertexBuffer=void 0,this._batchIdBuffer=void 0,this._instancedUniformsByProgram=void 0,this._drawCommands=[],this._pickCommands=[],this._modelCommands=void 0,this._boundingSphere=D(this),this._center=t.clone(this._boundingSphere.center),this._rtcTransform=new d,this._rtcModelView=new d,this._mode=void 0,this.modelMatrix=d.clone(d.IDENTITY),this._modelMatrix=d.clone(this.modelMatrix),this._url=p.createIfNeeded(e.url),this._requestType=e.requestType,this._gltf=e.gltf,this._basePath=p.createIfNeeded(e.basePath),this._asynchronous=e.asynchronous,this._incrementallyLoadTextures=e.incrementallyLoadTextures,this._upAxis=e.upAxis,this.shadows=o(e.shadows,A.ENABLED),this._shadows=this.shadows,this.debugShowBoundingVolume=o(e.debugShowBoundingVolume,!1),this._debugShowBoundingVolume=!1,this.debugWireframe=o(e.debugWireframe,!1),this._debugWireframe=!1}function P(e,t){t=o(t,[]);for(var r=t.length,i=new Array(r),n=0;n<r;++n){var a=t[n],s=a.modelMatrix,l=o(a.batchId,n);i[n]=new w(e,s,l)}return i}function D(r){for(var i=r.length,n=new Array(i),o=0;o<i;++o)n[o]=d.getTranslation(r._instances[o]._modelMatrix,new t);return e.fromPoints(n)}function I(e,t){if(a(e._instancedUniformsByProgram))return e._instancedUniformsByProgram[t];var r={};e._instancedUniformsByProgram=r;var i=["MODEL","MODELVIEW","CESIUM_RTC_MODELVIEW","MODELVIEWPROJECTION","MODELINVERSE","MODELVIEWINVERSE","MODELVIEWPROJECTIONINVERSE","MODELINVERSETRANSPOSE","MODELVIEWINVERSETRANSPOSE"],n=["MODELVIEW","CESIUM_RTC_MODELVIEW","MODELVIEWPROJECTION","MODELVIEWINVERSETRANSPOSE"],o=e._model.gltf,s=o.techniques;for(var l in s)if(s.hasOwnProperty(l)){var u=s[l],c=u.parameters,d=u.uniforms,h=u.program;if(!a(r[h])){var p={};r[h]=p;for(var m in d)if(d.hasOwnProperty(m)){var g=d[m],_=c[g],v=_.semantic;if(a(v)&&i.indexOf(v)>-1){if(!(n.indexOf(v)>-1))throw new f('Shader program cannot be optimized for instancing. Parameter "'+_+'" in program "'+t+'" uses unsupported semantic "'+v+'"');p[m]=v}}}}return r[t]}function O(e){return function(t,r){var i=I(e,r),n=a(e._batchTable),o=b.replaceMain(t,"czm_instancing_main"),s="",l="";for(var u in i)if(i.hasOwnProperty(u)){var c,d=i[u];"MODELVIEW"===d||"CESIUM_RTC_MODELVIEW"===d?c="czm_instanced_modelView":"MODELVIEWPROJECTION"===d?(c="czm_instanced_modelViewProjection",s+="mat4 czm_instanced_modelViewProjection;\n",l+="czm_instanced_modelViewProjection = czm_projection * czm_instanced_modelView;\n"):"MODELVIEWINVERSETRANSPOSE"===d&&(c="czm_instanced_modelViewInverseTranspose",s+="mat3 czm_instanced_modelViewInverseTranspose;\n",l+="czm_instanced_modelViewInverseTranspose = mat3(czm_instanced_modelView);\n");var h=new RegExp("uniform.*"+u+".*");o=o.replace(h,""),h=new RegExp(u+"\\b","g"),o=o.replace(h,c)}var p=n?"attribute float a_batchId;\n":"",f="uniform mat4 czm_instanced_modifiedModelView;\nuniform mat4 czm_instanced_nodeTransform;\n"+s+"mat4 czm_instanced_modelView;\nattribute vec4 czm_modelMatrixRow0;\nattribute vec4 czm_modelMatrixRow1;\nattribute vec4 czm_modelMatrixRow2;\n"+p+o+"void main()\n{\n mat4 czm_instanced_model = mat4(czm_modelMatrixRow0.x, czm_modelMatrixRow1.x, czm_modelMatrixRow2.x, 0.0, czm_modelMatrixRow0.y, czm_modelMatrixRow1.y, czm_modelMatrixRow2.y, 0.0, czm_modelMatrixRow0.z, czm_modelMatrixRow1.z, czm_modelMatrixRow2.z, 0.0, czm_modelMatrixRow0.w, czm_modelMatrixRow1.w, czm_modelMatrixRow2.w, 1.0);\n czm_instanced_modelView = czm_instanced_modifiedModelView * czm_instanced_model * czm_instanced_nodeTransform;\n"+l+" czm_instancing_main();\n}";if(ae=f,n){var m=e._model.gltf,g=T.getDiffuseAttributeOrUniform(m,r);f=e._batchTable.getVertexShaderCallback(!0,"a_batchId",g)(f)}return f}}function M(e){return function(t,r){var i=e._batchTable;if(a(i)){var n=e._model.gltf,o=T.getDiffuseAttributeOrUniform(n,r);t=i.getFragmentShaderCallback(!0,o)(t)}return t}}function R(e){return function(t){t=ae;var r=a(e._batchTable),i=e._allowPicking;return r?t=e._batchTable.getPickVertexShaderCallback("a_batchId")(t):i&&(t=b.createPickVertexShaderSource(t)),t}}function L(e){return function(t){var r=a(e._batchTable),i=e._allowPicking;return r?t=e._batchTable.getPickFragmentShaderCallback()(t):i&&(t=b.createPickFragmentShaderSource(t,"varying")),t}}function N(e,t){return function(){return d.multiply(t.uniformState.view,e._rtcTransform,e._rtcModelView)}}function k(e){return function(){return e.computedMatrix}}function F(e,t){return function(i,n,o){i=r(i),i.czm_instanced_modifiedModelView=N(e,t),i.czm_instanced_nodeTransform=k(o);var s=I(e,n);for(var l in s)s.hasOwnProperty(l)&&delete i[l];return a(e._batchTable)&&(i=e._batchTable.getUniformMapCallback()(i)),i}}function B(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getPickUniformMapCallback()(t)),t}}function U(e){return function(t,r){if(a(e._batchTable)){var i=e._model.gltf,n=T.getDiffuseAttributeOrUniform(i,r);t=e._batchTable.getVertexShaderCallback(!0,"a_batchId",n)(t),t="uniform float a_batchId\n;"+t}return t}}function V(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getPickVertexShaderCallback("a_batchId")(t),t="uniform float a_batchId\n;"+t),t}}function z(e){return function(t){var r=a(e._batchTable),i=e._allowPicking;return r?t=e._batchTable.getPickFragmentShaderCallback()(t):i&&(t=b.createPickFragmentShaderSource(t,"uniform")),t}}function G(e){return function(t){return a(e._batchTable)&&(t=e._batchTable.getUniformMapCallback()(t)),t}}function W(e){var t=e._instances,r=e.length,i=e._center,n=e._vertexBufferTypedArray;a(n)||(n=new Float32Array(12*r)),e._dynamic&&(e._vertexBufferTypedArray=n);for(var o=0;o<r;++o){ +var s=t[o]._modelMatrix,l=d.clone(s,oe);l[12]-=i.x,l[13]-=i.y,l[14]-=i.z;var u=12*o;n[u+0]=l[0],n[u+1]=l[4],n[u+2]=l[8],n[u+3]=l[12],n[u+4]=l[1],n[u+5]=l[5],n[u+6]=l[9],n[u+7]=l[13],n[u+8]=l[2],n[u+9]=l[6],n[u+10]=l[10],n[u+11]=l[14]}return n}function H(e,t){var r,n=e._instances,o=e.length,s=e._dynamic,l=a(e._batchTable),u=e._allowPicking;if(l){var c=new Uint16Array(o);for(r=0;r<o;++r)c[r]=n[r]._instanceId;e._batchIdBuffer=g.createVertexBuffer({context:t,typedArray:c,usage:_.STATIC_DRAW})}if(u&&!l){var d=new Uint8Array(4*o);for(r=0;r<o;++r){var h=e._pickIds[r],p=h.color,f=4*r;d[f]=i.floatToByte(p.red),d[f+1]=i.floatToByte(p.green),d[f+2]=i.floatToByte(p.blue),d[f+3]=i.floatToByte(p.alpha)}e._pickIdBuffer=g.createVertexBuffer({context:t,typedArray:d,usage:_.STATIC_DRAW})}var m=W(e);e._vertexBuffer=g.createVertexBuffer({context:t,typedArray:m,usage:s?_.STREAM_DRAW:_.STATIC_DRAW})}function j(e){var t=W(e);e._vertexBuffer.copyFromArrayView(t)}function q(e,t){for(var r=e._instances,i=r.length,n=new Array(i),o=0;o<i;++o)n[o]=t.createPickId(r[o]);return n}function Y(e,t){var r=e._instancingSupported,i=a(e._batchTable),o=e._allowPicking,s={url:e._url,requestType:e._requestType,gltf:e._gltf,basePath:e._basePath,shadows:e._shadows,cacheKey:void 0,asynchronous:e._asynchronous,allowPicking:o,incrementallyLoadTextures:e._incrementallyLoadTextures,upAxis:e._upAxis,precreatedAttributes:void 0,vertexShaderLoaded:void 0,fragmentShaderLoaded:void 0,uniformMapLoaded:void 0,pickVertexShaderLoaded:void 0,pickFragmentShaderLoaded:void 0,pickUniformMapLoaded:void 0,ignoreCommands:!0,opaquePass:e._opaquePass};if(o&&!i&&(e._pickIds=q(e,t)),r){H(e,t);var l=n.getSizeInBytes(n.FLOAT),u={czm_modelMatrixRow0:{index:0,vertexBuffer:e._vertexBuffer,componentsPerAttribute:4,componentDatatype:n.FLOAT,normalize:!1,offsetInBytes:0,strideInBytes:12*l,instanceDivisor:1},czm_modelMatrixRow1:{index:0,vertexBuffer:e._vertexBuffer,componentsPerAttribute:4,componentDatatype:n.FLOAT,normalize:!1,offsetInBytes:4*l,strideInBytes:12*l,instanceDivisor:1},czm_modelMatrixRow2:{index:0,vertexBuffer:e._vertexBuffer,componentsPerAttribute:4,componentDatatype:n.FLOAT,normalize:!1,offsetInBytes:8*l,strideInBytes:12*l,instanceDivisor:1}};i&&(u.a_batchId={index:0,vertexBuffer:e._batchIdBuffer,componentsPerAttribute:1,componentDatatype:n.UNSIGNED_SHORT,normalize:!1,offsetInBytes:0,strideInBytes:0,instanceDivisor:1}),o&&!i&&(u.pickColor={index:0,vertexBuffer:e._pickIdBuffer,componentsPerAttribute:4,componentDatatype:n.UNSIGNED_BYTE,normalize:!0,offsetInBytes:0,strideInBytes:0,instanceDivisor:1}),s.precreatedAttributes=u,s.vertexShaderLoaded=O(e),s.fragmentShaderLoaded=M(e),s.uniformMapLoaded=F(e,t),s.pickVertexShaderLoaded=R(e),s.pickFragmentShaderLoaded=L(e),s.pickUniformMapLoaded=B(e),a(e._url)&&(s.cacheKey=e._url.getUrlComponent()+"#instanced")}else s.vertexShaderLoaded=U(e),s.fragmentShaderLoaded=M(e),s.uniformMapLoaded=G(e,t),s.pickVertexShaderLoaded=V(e),s.pickFragmentShaderLoaded=z(e),s.pickUniformMapLoaded=B(e);a(e._url)?e._model=S.fromGltf(s):e._model=new S(s)}function X(e){if(e._debugWireframe!==e.debugWireframe){e._debugWireframe=e.debugWireframe;for(var t=e.debugWireframe?h.LINES:h.TRIANGLES,r=e._drawCommands,i=r.length,n=0;n<i;++n)r[n].primitiveType=t}}function Q(e){if(e.debugShowBoundingVolume!==e._debugShowBoundingVolume){e._debugShowBoundingVolume=e.debugShowBoundingVolume;for(var t=e._drawCommands,r=t.length,i=0;i<r;++i)t[i].debugShowBoundingVolume=e.debugShowBoundingVolume}}function Z(e,t,r){for(var i=t.length,n=e.length,o=e.allowPicking,a=e._boundingSphere,s=e._cull,l=0;l<i;++l){var u=v.shallowClone(t[l]);if(u.instanceCount=n,u.boundingVolume=a,u.cull=s,e._drawCommands.push(u),o){var c=v.shallowClone(r[l]);c.instanceCount=n,c.boundingVolume=a,c.cull=s,e._pickCommands.push(c)}}}function K(e){return function(){return e}}function J(e){return function(){return e}}function $(t,i,n){for(var o=t._instances,s=i.length,l=t.length,u=t.allowPicking,c=a(t._batchTable),h=t._cull,p=0;p<s;++p)for(var f=0;f<l;++f){var m=v.shallowClone(i[p]);if(m.modelMatrix=new d,m.boundingVolume=new e,m.cull=h,m.uniformMap=r(m.uniformMap),c&&(m.uniformMap.a_batchId=K(o[f]._instanceId)),t._drawCommands.push(m),u){var g=v.shallowClone(n[p]);if(g.modelMatrix=new d,g.boundingVolume=new e,g.cull=h,g.uniformMap=r(g.uniformMap),c)g.uniformMap.a_batchId=K(o[f]._instanceId);else if(u){var _=t._pickIds[f];g.uniformMap.czm_pickColor=J(_.color)}t._pickCommands.push(g)}}}function ee(t){for(var r=t._modelCommands,i=r.length,n=t.length,o=t.allowPicking,a=t._rtcTransform,s=t._center,l=0;l<i;++l)for(var u=r[l],c=0;c<n;++c){var h=l*n+c,p=t._drawCommands[h],f=d.clone(t._instances[c]._modelMatrix,oe);f[12]-=s.x,f[13]-=s.y,f[14]-=s.z,f=d.multiply(a,f,oe);var m=u.modelMatrix,g=p.modelMatrix;d.multiply(f,m,g);var _=u.boundingVolume,v=p.boundingVolume;if(e.transform(_,f,v),o){var y=t._pickCommands[h];d.clone(g,y.modelMatrix),e.clone(v,y.boundingVolume)}}}function te(e){for(var t=e._nodeCommands,r=t.length,i=[],n=[],o=0;o<r;++o){var a=t[o];a.show&&(i.push(a.command),n.push(a.pickCommand))}return{draw:i,pick:n}}function re(e){if(e.shadows!==e._shadows){e._shadows=e.shadows;for(var t=A.castShadows(e.shadows),r=A.receiveShadows(e.shadows),i=e._drawCommands,n=i.length,o=0;o<n;++o){var a=i[o];a.castShadows=t,a.receiveShadows=r}}}var ie={NEEDS_LOAD:0,LOADING:1,LOADED:2,FAILED:3};s(x.prototype,{allowPicking:{get:function(){return this._allowPicking}},length:{get:function(){return this._instances.length}},activeAnimations:{get:function(){return this._model.activeAnimations}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}}});var ne=new t,oe=new d;x.prototype.expandBoundingSphere=function(t){var r=d.getTranslation(t,ne);e.expand(this._boundingSphere,r,this._boundingSphere)};var ae;return x.prototype.update=function(e){if(e.mode!==E.MORPHING&&this.show&&0!==this.length){var r=e.context;if(this._state===ie.NEEDS_LOAD){this._state=ie.LOADING,this._instancingSupported=r.instancedArrays,Y(this,r);var i=this;this._model.readyPromise.otherwise(function(e){i._state=ie.FAILED,i._readyPromise.reject(e)})}var n=this._instancingSupported,o=this._model;if(o.update(e),o.ready&&this._state===ie.LOADING){this._state=ie.LOADED,this._ready=!0;var a=o.boundingSphere.radius+t.magnitude(o.boundingSphere.center);this._boundingSphere.radius+=a;var s=te(o);return this._modelCommands=s.draw,n?Z(this,s.draw,s.pick):($(this,s.draw,s.pick),ee(this)),void this._readyPromise.resolve(this)}if(this._state===ie.LOADED){var l=e.mode!==this._mode,u=this.modelMatrix,c=!d.equals(this._modelMatrix,u);if(l||c){this._mode=e.mode,d.clone(u,this._modelMatrix);var h=d.multiplyByTranslation(this._modelMatrix,this._center,this._rtcTransform);this._mode!==E.SCENE3D&&(h=m.basisTo2D(e.mapProjection,h,h)),d.getTranslation(h,this._boundingSphere.center)}n&&this._dirty&&(this._dynamic=!0,this._dirty=!1,j(this)),!n&&(o.dirty||this._dirty||l||c)&&ee(this),re(this),X(this),Q(this);for(var p=e.passes,f=e.commandList,g=p.render?this._drawCommands:this._pickCommands,_=g.length,v=0;v<_;++v)f.push(g[v])}}},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){this._model=this._model&&this._model.destroy();var e=this._pickIds;if(a(e))for(var t=e.length,r=0;r<t;++r)e[r].destroy();return u(this)},x}),define("Scene/Instanced3DModel3DTileContent",["../Core/AttributeCompression","../Core/Cartesian3","../Core/ClippingPlaneCollection","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/getBaseUri","../Core/getStringFromTypedArray","../Core/Matrix3","../Core/Matrix4","../Core/Quaternion","../Core/RequestType","../Core/RuntimeError","../Core/Transforms","../Core/TranslationRotationScale","../Renderer/Pass","./Cesium3DTileBatchTable","./Cesium3DTileFeature","./Cesium3DTileFeatureTable","./ModelInstanceCollection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A){"use strict";function x(e,t,r,i,n){this._tileset=e,this._tile=t,this._resource=r,this._modelInstanceCollection=void 0,this._batchTable=void 0,this._features=void 0,this.featurePropertiesDirty=!1,P(this,i,n)}function P(r,i,s){var l=o(s,0);s=l;var u=new Uint8Array(i),c=new DataView(i);s+=I;var h=c.getUint32(s,!0);if(1!==h)throw new y("Only Instanced 3D Model version 1 is supported. Version "+h+" is not.");s+=I;var p=c.getUint32(s,!0);s+=I;var T=c.getUint32(s,!0);if(0===T)throw new y("featureTableJsonByteLength is zero, the feature table must be defined.");s+=I;var P=c.getUint32(s,!0);s+=I;var D=c.getUint32(s,!0);s+=I;var R=c.getUint32(s,!0);s+=I;var L=c.getUint32(s,!0);if(1!==L&&0!==L)throw new y("Only glTF format 0 (uri) or 1 (embedded) are supported. Format "+L+" is not.");s+=I;var N=f(u,s,T),k=JSON.parse(N);s+=T;var F=new Uint8Array(i,s,P);s+=P;var B=new E(k,F),U=B.getGlobalProperty("INSTANCES_LENGTH");if(B.featuresLength=U,!a(U))throw new y("Feature table global property: INSTANCES_LENGTH must be defined");var V,z;if(D>0){var G=f(u,s,D);V=JSON.parse(G),s+=D,R>0&&(z=new Uint8Array(i,s,R),z=new Uint8Array(z),s+=R)}r._batchTable=new w(r,U,V,z);var W=l+p-s;if(0===W)throw new y("glTF byte length is zero, i3dm must have a glTF to instance.");var H;s%4==0?H=new Uint8Array(i,s,W):(x._deprecationWarning("i3dm-glb-unaligned","The embedded glb is not aligned to a 4-byte boundary."),H=new Uint8Array(u.subarray(s,s+W)));var j={instances:new Array(U),batchTable:r._batchTable,cull:!1,url:void 0,requestType:v.TILES3D,gltf:void 0,basePath:void 0,incrementallyLoadTextures:!1,upAxis:r._tileset._gltfUpAxis,opaquePass:S.CESIUM_3D_TILE};if(0===L){var q=f(H);q=q.replace(/[\s\0]+$/,""),j.url=r._resource.getDerivedResource({url:q})}else j.gltf=H,j.basePath=r._resource.clone();var Y,X=B.getGlobalProperty("EAST_NORTH_UP"),Q=B.getGlobalProperty("RTC_CENTER",n.FLOAT,3);a(Q)&&(Y=t.unpack(Q));for(var Z=j.instances,K=new t,J=new Array(3),$=new t,ee=new t,te=new t,re=new m,ie=new _,ne=new t,oe=new C,ae=new g,se=0;se<U;se++){var le=B.getProperty("POSITION",n.FLOAT,3,se,O);if(!a(le)){le=J;var ue=B.getProperty("POSITION_QUANTIZED",n.UNSIGNED_SHORT,3,se,O);if(!a(ue))throw new y("Either POSITION or POSITION_QUANTIZED must be defined for each instance.");var ce=B.getGlobalProperty("QUANTIZED_VOLUME_OFFSET",n.FLOAT,3);if(!a(ce))throw new y("Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.");var de=B.getGlobalProperty("QUANTIZED_VOLUME_SCALE",n.FLOAT,3);if(!a(de))throw new y("Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.");for(var he=0;he<3;he++)le[he]=ue[he]/65535*de[he]+ce[he]}t.unpack(le,0,K),a(Y)&&t.add(K,Y,K),oe.translation=K;var pe=B.getProperty("NORMAL_UP",n.FLOAT,3,se,O),fe=B.getProperty("NORMAL_RIGHT",n.FLOAT,3,se,M),me=!1;if(a(pe)){if(!a(fe))throw new y("To define a custom orientation, both NORMAL_UP and NORMAL_RIGHT must be defined.");t.unpack(pe,0,ee),t.unpack(fe,0,$),me=!0}else{var ge=B.getProperty("NORMAL_UP_OCT32P",n.UNSIGNED_SHORT,2,se,O),_e=B.getProperty("NORMAL_RIGHT_OCT32P",n.UNSIGNED_SHORT,2,se,M);if(a(ge)){if(!a(_e))throw new y("To define a custom orientation with oct-encoded vectors, both NORMAL_UP_OCT32P and NORMAL_RIGHT_OCT32P must be defined.");e.octDecodeInRange(ge[0],ge[1],65535,ee),e.octDecodeInRange(_e[0],_e[1],65535,$),me=!0}else X?(b.eastNorthUpToFixedFrame(K,d.WGS84,ae),g.getRotation(ae,re)):m.clone(m.IDENTITY,re)}me&&(t.cross($,ee,te),t.normalize(te,te),m.setColumn(re,0,$,re),m.setColumn(re,1,ee,re),m.setColumn(re,2,te,re)),_.fromRotationMatrix(re,ie),oe.rotation=ie,ne=t.fromElements(1,1,1,ne);var ve=B.getProperty("SCALE",n.FLOAT,1,se);a(ve)&&t.multiplyByScalar(ne,ve,ne);var ye=B.getProperty("SCALE_NON_UNIFORM",n.FLOAT,3,se,O);a(ye)&&(ne.x*=ye[0],ne.y*=ye[1],ne.z*=ye[2]),oe.scale=ne;var be=B.getProperty("BATCH_ID",n.UNSIGNED_SHORT,1,se);a(be)||(be=se),g.fromTranslationRotationScale(oe,ae);var Ce=ae.clone();Z[se]={modelMatrix:Ce,batchId:be}}r._modelInstanceCollection=new A(j)}function D(e){var t=e.featuresLength;if(!a(e._features)&&t>0){for(var r=new Array(t),i=0;i<t;++i)r[i]=new T(e,i);e._features=r}}if(!h.supportsTypedArrays())return{};x._deprecationWarning=l,s(x.prototype,{featuresLength:{get:function(){return this._batchTable.featuresLength}},pointsLength:{get:function(){return 0}},trianglesLength:{get:function(){var e=this._modelInstanceCollection._model;return a(e)?e.trianglesLength:0}},geometryByteLength:{get:function(){var e=this._modelInstanceCollection._model;return a(e)?e.geometryByteLength:0}},texturesByteLength:{get:function(){var e=this._modelInstanceCollection._model;return a(e)?e.texturesByteLength:0}},batchTableByteLength:{get:function(){return this._batchTable.memorySizeInBytes}},innerContents:{get:function(){}},readyPromise:{get:function(){return this._modelInstanceCollection.readyPromise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){return this._batchTable}}});var I=Uint32Array.BYTES_PER_ELEMENT,O=new Array(4),M=new Array(4);return x.prototype.hasProperty=function(e,t){return this._batchTable.hasProperty(e,t)},x.prototype.getFeature=function(e){this.featuresLength;return D(this),this._features[e]},x.prototype.applyDebugSettings=function(e,t){t=e?t:i.WHITE,this._batchTable.setAllColor(t)},x.prototype.applyStyle=function(e,t){this._batchTable.applyStyle(e,t)},x.prototype.update=function(e,t){var i=t.commandList.length;this._batchTable.update(e,t),this._modelInstanceCollection.modelMatrix=this._tile.computedTransform,this._modelInstanceCollection.shadows=this._tileset.shadows,this._modelInstanceCollection.debugWireframe=this._tileset.debugWireframe,this._modelInstanceCollection.update(t);var n=this._tileset.clippingPlanes,o=this._modelInstanceCollection._model,s=o.clippingPlanes;a(n)?(a(s)||(o.clippingPlanes=new r,s=o.clippingPlanes),n.clone(s),s.enabled=n.enabled&&this._tile._isClipped):a(s)&&s.enabled&&(s.enabled=!1),i<t.commandList.length&&t.passes.render&&this._batchTable.addDerivedCommands(t,i,!1)},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){return this._modelInstanceCollection=this._modelInstanceCollection&&this._modelInstanceCollection.destroy(),this._batchTable=this._batchTable&&this._batchTable.destroy(),u(this)},x}),define("Scene/PointCloud3DTileContent",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/ClippingPlaneCollection","../Core/Color","../Core/combine","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/getStringFromTypedArray","../Core/Matrix3","../Core/Matrix4","../Core/oneTimeWarning","../Core/OrthographicFrustum","../Core/Plane","../Core/PrimitiveType","../Core/RuntimeError","../Core/Transforms","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../ThirdParty/when","./BlendingState","./Cesium3DTileBatchTable","./Cesium3DTileFeature","./Cesium3DTileFeatureTable","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k){"use strict";function F(e,t,r,i,o){this._tileset=e,this._tile=t,this._resource=r,this._parsedContent=void 0,this._drawCommand=void 0,this._pickCommand=void 0,this._pickId=void 0,this._isTranslucent=!1,this._styleTranslucent=!1,this._constantColor=n.clone(n.WHITE),this._rtcCenter=void 0,this._batchTable=void 0,this._styleableShaderAttributes=void 0,this._isQuantized=!1,this._isOctEncoded16P=!1,this._isRGB565=!1,this._hasColors=!1,this._hasNormals=!1,this._hasBatchIds=!1,this._isClipped=!1,this._unionClippingRegions=!1,this.backFaceCulling=!1,this._backFaceCulling=!1,this._opaqueRenderState=void 0,this._translucentRenderState=void 0,this._highlightColor=n.clone(n.WHITE),this._pointSize=1,this._quantizedVolumeScale=void 0,this._quantizedVolumeOffset=void 0,this._modelMatrix=m.clone(m.IDENTITY),this._mode=void 0,this._readyPromise=I.defer(),this._pointsLength=0,this._geometryByteLength=0,this._features=void 0,this._packedClippingPlanes=[],this._modelViewMatrix=m.clone(m.IDENTITY),this.featurePropertiesDirty=!1,this._attenuation=!1,this._geometricErrorScale=void 0,this._maximumAttenuation=void 0,this._baseResolution=void 0,this._baseResolutionApproximation=void 0,B(this,i,o)}function B(e,r,i){i=s(i,0);var o=new Uint8Array(r),u=new DataView(r);i+=j;var c=u.getUint32(i,!0);if(1!==c)throw new b("Only Point Cloud tile version 1 is supported. Version "+c+" is not.");i+=j,i+=j;var d=u.getUint32(i,!0);if(0===d)throw new b("Feature table must have a byte length greater than zero");i+=j;var h=u.getUint32(i,!0);i+=j;var f=u.getUint32(i,!0);i+=j;var m=u.getUint32(i,!0);i+=j;var _=p(o,i,d),v=JSON.parse(_);i+=d;var y=new Uint8Array(r,i,h);i+=h;var C,S;if(f>0){var w=p(o,i,f);C=JSON.parse(w),i+=f,m>0&&(S=new Uint8Array(r,i,m),i+=m)}var T=new L(v,y),E=T.getGlobalProperty("POINTS_LENGTH");if(T.featuresLength=E,!l(E))throw new b("Feature table global property: POINTS_LENGTH must be defined");var A,x=!1;if(l(v.POSITION)){A=T.getPropertyArray("POSITION",a.FLOAT,3);var P=T.getGlobalProperty("RTC_CENTER",a.FLOAT,3);l(P)&&(e._rtcCenter=t.unpack(P))}else if(l(v.POSITION_QUANTIZED)){A=T.getPropertyArray("POSITION_QUANTIZED",a.UNSIGNED_SHORT,3),x=!0;var D=T.getGlobalProperty("QUANTIZED_VOLUME_SCALE",a.FLOAT,3);if(!l(D))throw new b("Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.");e._quantizedVolumeScale=t.unpack(D);var I=T.getGlobalProperty("QUANTIZED_VOLUME_OFFSET",a.FLOAT,3);if(!l(I))throw new b("Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.");e._quantizedVolumeOffset=t.unpack(I)}if(!l(A))throw new b("Either POSITION or POSITION_QUANTIZED must be defined.");var O,R=!1,N=!1;if(l(v.RGBA))O=T.getPropertyArray("RGBA",a.UNSIGNED_BYTE,4),R=!0;else if(l(v.RGB))O=T.getPropertyArray("RGB",a.UNSIGNED_BYTE,3);else if(l(v.RGB565))O=T.getPropertyArray("RGB565",a.UNSIGNED_SHORT,1),N=!0;else if(l(v.CONSTANT_RGBA)){var k=T.getGlobalProperty("CONSTANT_RGBA",a.UNSIGNED_BYTE,4);e._constantColor=n.fromBytes(k[0],k[1],k[2],k[3],e._constantColor)}else e._constantColor=n.clone(n.DARKGRAY,e._constantColor);e._isTranslucent=R;var F,B=!1;l(v.NORMAL)?F=T.getPropertyArray("NORMAL",a.FLOAT,3):l(v.NORMAL_OCT16P)&&(F=T.getPropertyArray("NORMAL_OCT16P",a.UNSIGNED_BYTE,2),B=!0);var U;if(l(v.BATCH_ID)){U=T.getPropertyArray("BATCH_ID",a.UNSIGNED_SHORT,1);var V=T.getGlobalProperty("BATCH_LENGTH");if(!l(V))throw new b("Global property: BATCH_LENGTH must be defined when BATCH_ID is defined.");l(S)&&(S=new Uint8Array(S)),e._batchTable=new M(e,V,C,S)}var z;if(!l(U)&&l(S)){z=M.getBinaryProperties(E,C,S);for(var G in z)if(z.hasOwnProperty(G)){var W=z[G],H=W.typedArray,q=a.fromTypedArray(H);q!==a.INT&&q!==a.UNSIGNED_INT&&q!==a.DOUBLE||(g("Cast pnts property to floats",'Point cloud property "'+G+'" will be casted to a float array because INT, UNSIGNED_INT, and DOUBLE are not valid WebGL vertex attribute types. Some precision may be lost.'),W.typedArray=new Float32Array(H))}}e._parsedContent={positions:A,colors:O,normals:F,batchIds:U,styleableProperties:z},e._pointsLength=E,e._isQuantized=x,e._isOctEncoded16P=B,e._isRGB565=N,e._hasColors=l(O),e._hasNormals=l(F),e._hasBatchIds=l(U);var Y=e._tile.contentBoundingVolume.boundingSphere.volume();e._baseResolutionApproximation=Math.cbrt(Y/E)}function U(e,t){var r=t.context,i=e._parsedContent,s=e._pointsLength,u=i.positions,c=i.colors,d=i.normals,h=i.batchIds,p=i.styleableProperties,f=l(p),g=e._isQuantized,v=e._isOctEncoded16P,b=e._isRGB565,C=e._isTranslucent,x=e._hasColors,P=e._hasNormals,I=e._hasBatchIds,M=e._batchTable,R=l(M),L=[],k={};if(e._styleableShaderAttributes=k,f){var F=K;for(var B in p)if(p.hasOwnProperty(B)){var U=p[B],V=U.typedArray,z=U.componentCount,G=a.fromTypedArray(V),W=S.createVertexBuffer({context:r,typedArray:U.typedArray,usage:w.STATIC_DRAW});e._geometryByteLength+=W.sizeInBytes;var H={index:F,vertexBuffer:W,componentsPerAttribute:z,componentDatatype:G,normalize:!1,offsetInBytes:0,strideInBytes:0};L.push(H),k[B]={location:F,componentCount:z},++F}}var j={u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier:function(){var i=q;if(i.x=e._attenuation?e._maximumAttenuation:e._pointSize,i.y=e._tileset.timeSinceLoad,e._attenuation){var n=e.tile.geometricError;0===n&&(n=l(e._baseResolution)?e._baseResolution:e._baseResolutionApproximation);var o,a=t.camera.frustum;o=t.mode===N.SCENE2D||a instanceof _?Number.POSITIVE_INFINITY:r.drawingBufferHeight/t.camera.frustum.sseDenominator,i.z=n*e._geometricErrorScale,i.w=o}return i},u_highlightColor:function(){return e._highlightColor},u_constantColor:function(){return e._constantColor},u_clippingPlanesLength:function(){return e._packedClippingPlanes.length},u_clippingPlanes:function(){return e._packedClippingPlanes},u_clippingPlanesEdgeStyle:function(){var t=e._tileset.clippingPlanes;if(!l(t))return n.WHITE.withAlpha(0);var r=n.clone(t.edgeColor);return r.alpha=t.edgeWidth,r}};g&&(j=o(j,{u_quantizedVolumeScale:function(){return e._quantizedVolumeScale}}));var J=S.createVertexBuffer({context:r,typedArray:u,usage:w.STATIC_DRAW});e._geometryByteLength+=J.sizeInBytes;var $;x&&($=S.createVertexBuffer({context:r,typedArray:c,usage:w.STATIC_DRAW}),e._geometryByteLength+=$.sizeInBytes);var ee;P&&(ee=S.createVertexBuffer({context:r,typedArray:d,usage:w.STATIC_DRAW}),e._geometryByteLength+=ee.sizeInBytes);var te;I&&(te=S.createVertexBuffer({context:r,typedArray:h,usage:w.STATIC_DRAW}),e._geometryByteLength+=te.sizeInBytes);var re=[];if(g?re.push({index:Y,vertexBuffer:J,componentsPerAttribute:3,componentDatatype:a.UNSIGNED_SHORT,normalize:!0,offsetInBytes:0,strideInBytes:0}):re.push({index:Y,vertexBuffer:J,componentsPerAttribute:3,componentDatatype:a.FLOAT,normalize:!1,offsetInBytes:0,strideInBytes:0}),x)if(b)re.push({index:X,vertexBuffer:$,componentsPerAttribute:1,componentDatatype:a.UNSIGNED_SHORT,normalize:!1,offsetInBytes:0,strideInBytes:0});else{var ie=C?4:3;re.push({index:X,vertexBuffer:$,componentsPerAttribute:ie,componentDatatype:a.UNSIGNED_BYTE,normalize:!0,offsetInBytes:0,strideInBytes:0})}P&&(v?re.push({index:Q,vertexBuffer:ee,componentsPerAttribute:2,componentDatatype:a.UNSIGNED_BYTE,normalize:!1,offsetInBytes:0,strideInBytes:0}):re.push({index:Q,vertexBuffer:ee,componentsPerAttribute:3,componentDatatype:a.FLOAT,normalize:!1,offsetInBytes:0,strideInBytes:0})),I&&re.push({index:Z,vertexBuffer:te,componentsPerAttribute:1,componentDatatype:a.fromTypedArray(h),normalize:!1,offsetInBytes:0,strideInBytes:0}),f&&(re=re.concat(L));var ne=new D({context:r,attributes:re}),oe=j;R&&(oe=M.getUniformMapCallback()(j));var ae;R?ae=M.getPickUniformMapCallback()(j):(e._pickId=r.createPickId({primitive:e._tileset,content:e}),ae=o(j,{czm_pickColor:function(){return e._pickId.color}})),e._opaqueRenderState=A.fromCache({depthTest:{enabled:!0}}),e._translucentRenderState=A.fromCache({depthTest:{enabled:!0},depthMask:!1,blending:O.ALPHA_BLEND}),e._drawCommand=new T({boundingVolume:void 0,cull:!1,modelMatrix:new m,primitiveType:y.POINTS,vertexArray:ne,count:s,shaderProgram:void 0,uniformMap:oe,renderState:C?e._translucentRenderState:e._opaqueRenderState,pass:C?E.TRANSLUCENT:E.CESIUM_3D_TILE,owner:e,castShadows:!1,receiveShadows:!1}),e._pickCommand=new T({boundingVolume:void 0,cull:!1,modelMatrix:new m,primitiveType:y.POINTS,vertexArray:ne,count:s,shaderProgram:void 0,uniformMap:ae,renderState:C?e._translucentRenderState:e._opaqueRenderState,pass:C?E.TRANSLUCENT:E.CESIUM_3D_TILE,owner:e})}function V(e,t){for(var r=/czm_tiles3d_style_(\w+)/g,i=r.exec(e);null!==i;){var n=i[1];-1===t.indexOf(n)&&t.push(n),i=r.exec(e)}}function z(e,t){for(var r=e.numberOfAttributes,i=0;i<r;++i){var n=e.getAttribute(i);if(n.index===t)return n}}function G(e){for(var t=J.length,r=0;r<t;++r){var i=J[r],n="czm_tiles3d_style_"+i,o=i.toLowerCase();e=e.replace(new RegExp(n+"(\\W)","g"),o+"$1")}return e.replace("()","(vec3 position, vec3 position_absolute, vec4 color, vec3 normal)")}function W(e,t,r){var n,o,a,s,u,c,d=t.context,h=e._batchTable,p=l(h),f=l(r),m=e._isQuantized,g=e._isOctEncoded16P,_=e._isRGB565,v=e._isTranslucent,y=e._hasColors,C=e._hasNormals,S=e._hasBatchIds,w=e._backFaceCulling,T=e._drawCommand.vertexArray,E=e._tileset.clippingPlanes,A=e._attenuation,D=v;if(p&&(f=!1),f){var I={translucent:!1};s=r.getColorShaderFunction("getColorFromStyle","czm_tiles3d_style_",I),u=r.getShowShaderFunction("getShowFromStyle","czm_tiles3d_style_",I),c=r.getPointSizeShaderFunction("getPointSizeFromStyle","czm_tiles3d_style_",I),l(s)&&I.translucent&&(D=!0)}e._styleTranslucent=D;var O=l(s),M=l(u),R=l(c),L=l(E)&&E.enabled&&e._tile._isClipped&&i.isSupported(),N=[];O&&(V(s,N),s=G(s)),M&&(V(u,N),u=G(u)),R&&(V(c,N),c=G(c));var k=N.indexOf("COLOR")>=0,F=N.indexOf("NORMAL")>=0,B=N.filter(function(e){return-1===J.indexOf(e)});if(F&&!C)throw new b("Style references the NORMAL semantic but the point cloud does not have normals");var U=e._styleableShaderAttributes;for(o in U)if(U.hasOwnProperty(o)){a=U[o];var W=B.indexOf(o)>=0,H=z(T,a.location);H.enabled=W}var j=y&&(!O||k);if(y){z(T,X).enabled=j}var q={a_position:Y};j&&(q.a_color=X),C&&(q.a_normal=Q),S&&(q.a_batchId=Z);var K="",$=B.length;for(n=0;n<$;++n){if(o=B[n],a=U[o],!l(a))throw new b('Style references a property "'+o+'" that does not exist or is not styleable.');var ee,te=a.componentCount,re="czm_tiles3d_style_"+o;ee=1===te?"float":"vec"+te,K+="attribute "+ee+" "+re+"; \n",q[re]=a.location}var ie="attribute vec3 a_position; \nvarying vec4 v_color; \nuniform vec4 u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier; \nuniform vec4 u_constantColor; \nuniform vec4 u_highlightColor; \n";ie+="float u_pointSize; \nfloat u_tilesetTime; \n",A&&(ie+="float u_geometricError; \nfloat u_depthMultiplier; \n"),ie+=K,j&&(ie+=v?"attribute vec4 a_color; \n":_?"attribute float a_color; \nconst float SHIFT_RIGHT_11 = 1.0 / 2048.0; \nconst float SHIFT_RIGHT_5 = 1.0 / 32.0; \nconst float SHIFT_LEFT_11 = 2048.0; \nconst float SHIFT_LEFT_5 = 32.0; \nconst float NORMALIZE_6 = 1.0 / 64.0; \nconst float NORMALIZE_5 = 1.0 / 32.0; \n":"attribute vec3 a_color; \n"),C&&(ie+=g?"attribute vec2 a_normal; \n":"attribute vec3 a_normal; \n"),S&&(ie+="attribute float a_batchId; \n"),m&&(ie+="uniform vec3 u_quantizedVolumeScale; \n"),O&&(ie+=s),M&&(ie+=u),R&&(ie+=c),ie+="void main() \n{ \n u_pointSize = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.x; \n u_tilesetTime = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.y; \n",A&&(ie+=" u_geometricError = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.z; \n u_depthMultiplier = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.w; \n"),ie+=j?v?" vec4 color = a_color; \n":_?" float compressed = a_color; \n float r = floor(compressed * SHIFT_RIGHT_11); \n compressed -= r * SHIFT_LEFT_11; \n float g = floor(compressed * SHIFT_RIGHT_5); \n compressed -= g * SHIFT_LEFT_5; \n float b = compressed; \n vec3 rgb = vec3(r * NORMALIZE_5, g * NORMALIZE_6, b * NORMALIZE_5); \n vec4 color = vec4(rgb, 1.0); \n":" vec4 color = vec4(a_color, 1.0); \n":" vec4 color = u_constantColor; \n",ie+=m?" vec3 position = a_position * u_quantizedVolumeScale; \n":" vec3 position = a_position; \n",ie+=" vec3 position_absolute = vec3(czm_model * vec4(position, 1.0)); \n",ie+=C?g?" vec3 normal = czm_octDecode(a_normal); \n":" vec3 normal = a_normal; \n":" vec3 normal = vec3(1.0); \n",O&&(ie+=" color = getColorFromStyle(position, position_absolute, color, normal); \n"),M&&(ie+=" float show = float(getShowFromStyle(position, position_absolute, color, normal)); \n"),ie+=R?" gl_PointSize = getPointSizeFromStyle(position, position_absolute, color, normal); \n":A?" vec4 positionEC = czm_modelView * vec4(position, 1.0); \n float depth = -positionEC.z; \n gl_PointSize = min((u_geometricError / depth) * u_depthMultiplier, u_pointSize); \n":" gl_PointSize = u_pointSize; \n",ie+=" color = color * u_highlightColor; \n",C&&(ie+=" normal = czm_normal * normal; \n float diffuseStrength = czm_getLambertDiffuse(czm_sunDirectionEC, normal); \n diffuseStrength = max(diffuseStrength, 0.4); \n color.xyz *= diffuseStrength; \n"),ie+=" v_color = color; \n gl_Position = czm_modelViewProjection * vec4(position, 1.0); \n",C&&w&&(ie+=" float visible = step(-normal.z, 0.0); \n gl_Position *= visible; \n gl_PointSize *= visible; \n"),M&&(ie+=" gl_Position *= show; \n gl_PointSize *= show; \n"),ie+="} \n";var ne="varying vec4 v_color; \n";if(L&&(ne+="uniform int u_clippingPlanesLength;uniform vec4 u_clippingPlanes[czm_maxClippingPlanes]; \nuniform vec4 u_clippingPlanesEdgeStyle; \n"),ne+="void main() \n{ \n gl_FragColor = v_color; \n",L){ne+=" float clipDistance = "+(E.unionClippingRegions?"czm_discardIfClippedWithUnion":"czm_discardIfClippedWithIntersect")+"(u_clippingPlanes, u_clippingPlanesLength); \n vec4 clippingPlanesEdgeColor = vec4(1.0); \n clippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb; \n float clippingPlanesEdgeWidth = u_clippingPlanesEdgeStyle.a; \n if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n { \n gl_FragColor = clippingPlanesEdgeColor; \n } \n"}ne+="} \n";var oe=ie,ae=ne;p&&(oe=h.getVertexShaderCallback(!1,"a_batchId",void 0)(oe),ae=h.getFragmentShaderCallback(!1,void 0)(ae));var se=ie,le=ne;p?(se=h.getPickVertexShaderCallback("a_batchId")(se),le=h.getPickFragmentShaderCallback()(le)):le=P.createPickFragmentShaderSource(le,"uniform");var ue=e._drawCommand;l(ue.shaderProgram)&&ue.shaderProgram.destroy(),ue.shaderProgram=x.fromCache({context:d,vertexShaderSource:oe,fragmentShaderSource:ae,attributeLocations:q});var ce=e._pickCommand;l(ce.shaderProgram)&&ce.shaderProgram.destroy(),ce.shaderProgram=x.fromCache({context:d,vertexShaderSource:se,fragmentShaderSource:le,attributeLocations:q});try{ue.shaderProgram._bind()}catch(e){throw new b("Error generating style shader: this may be caused by a type mismatch, index out-of-bounds, or other syntax error.")}}function H(e){var t=e.featuresLength;if(!l(e._features)&&t>0){for(var r=new Array(t),i=0;i<t;++i)r[i]=new R(e,i);e._features=r}}if(!h.supportsTypedArrays())return{};u(F.prototype,{featuresLength:{get:function(){return l(this._batchTable)?this._batchTable.featuresLength:0}},pointsLength:{get:function(){return this._pointsLength}},trianglesLength:{get:function(){return 0}},geometryByteLength:{get:function(){return this._geometryByteLength}},texturesByteLength:{get:function(){return 0}},batchTableByteLength:{get:function(){return l(this._batchTable)?this._batchTable.memorySizeInBytes:0}},innerContents:{get:function(){}},readyPromise:{get:function(){return this._readyPromise.promise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){return this._batchTable}}});var j=Uint32Array.BYTES_PER_ELEMENT,q=new r,Y=0,X=1,Q=2,Z=3,K=4,J=["POSITION","COLOR","NORMAL","POSITION_ABSOLUTE"];F.prototype.hasProperty=function(e,t){return!!l(this._batchTable)&&this._batchTable.hasProperty(e,t)},F.prototype.getFeature=function(e){if(l(this._batchTable)){this.featuresLength;return H(this),this._features[e]}},F.prototype.applyDebugSettings=function(e,t){this._highlightColor=e?t:n.WHITE},F.prototype.applyStyle=function(e,t){l(this._batchTable)?this._batchTable.applyStyle(e,t):W(this,e,t)};var $=new r,ee=new m +;return F.prototype.update=function(e,t){var i=this._tile.computedTransform,n=!m.equals(this._modelMatrix,i),o=n||this._mode!==t.mode;this._mode=t.mode;var a=t.context,s=this._tileset.clippingPlanes,u=l(s)&&s.enabled&&this._tile._isClipped,c=!1,d=0;u&&(c=s.unionClippingRegions,d=s.length);var h=this._packedClippingPlanes;if(h.length!==d){h.length=d;for(var p=0;p<d;++p)h[p]=new r}l(this._drawCommand)||(U(this,t),W(this,t,e.style),o=!0,this._readyPromise.resolve(this),this._parsedContent=void 0),this._isClipped===u&&this._unionClippingRegions===c||(this._isClipped=u,this._unionClippingRegions=c,W(this,t,e.style));var f=this._tileset.pointCloudShading;if(l(f)){var g=this._attenuation;this._attenuation=f.attenuation,this._geometricErrorScale=f.geometricErrorScale,this._maximumAttenuation=l(f.maximumAttenuation)?f.maximumAttenuation:e.maximumScreenSpaceError,this._baseResolution=f.baseResolution,this._attenuation!==g&&W(this,t,e.style)}if(o){if(m.clone(i,this._modelMatrix),l(this._rtcCenter)?m.multiplyByTranslation(i,this._rtcCenter,this._drawCommand.modelMatrix):l(this._quantizedVolumeOffset)?m.multiplyByTranslation(i,this._quantizedVolumeOffset,this._drawCommand.modelMatrix):m.clone(i,this._drawCommand.modelMatrix),t.mode!==N.SCENE3D){var _=t.mapProjection;i=this._drawCommand.modelMatrix;var v=m.getColumn(i,3,$);if(r.equals(v,r.UNIT_W)){var y=this._tile.boundingSphere.center,b=C.wgs84To2DModelMatrix(_,y,ee);m.multiply(b,i,i)}else C.basisTo2D(_,i,i)}m.clone(this._drawCommand.modelMatrix,this._pickCommand.modelMatrix);var S;S=l(this._tile._contentBoundingVolume)?this._mode===N.SCENE3D?this._tile._contentBoundingVolume.boundingSphere:this._tile._contentBoundingVolume2D.boundingSphere:this._mode===N.SCENE3D?this._tile._boundingVolume.boundingSphere:this._tile._boundingVolume2D.boundingSphere,this._drawCommand.boundingVolume=S,this._pickCommand.boundingVolume=S}u&&(m.multiply(a.uniformState.view3D,i,this._modelViewMatrix),s.transformAndPackPlanes(this._modelViewMatrix,h)),this._drawCommand.castShadows=k.castShadows(e.shadows),this._drawCommand.receiveShadows=k.receiveShadows(e.shadows),this.backFaceCulling!==this._backFaceCulling&&(this._backFaceCulling=this.backFaceCulling,W(this,t,e.style));var w=this._highlightColor.alpha<1||this._constantColor.alpha<1||this._styleTranslucent;this._drawCommand.renderState=w?this._translucentRenderState:this._opaqueRenderState,this._drawCommand.pass=w?E.TRANSLUCENT:E.CESIUM_3D_TILE,l(this._batchTable)&&this._batchTable.update(e,t);var T=t.commandList,A=t.passes;A.render&&T.push(this._drawCommand),A.pick&&T.push(this._pickCommand)},F.prototype.isDestroyed=function(){return!1},F.prototype.destroy=function(){var e=this._drawCommand,t=this._pickCommand;return l(e)&&(e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),e.shaderProgram=e.shaderProgram&&e.shaderProgram.destroy(),t.shaderProgram=t.shaderProgram&&t.shaderProgram.destroy()),this._batchTable=this._batchTable&&this._batchTable.destroy(),c(this)},F}),define("Scene/Tileset3DTileContent",["../Core/defaultValue","../Core/defineProperties","../Core/destroyObject","../Core/getStringFromTypedArray","../Core/RuntimeError","../ThirdParty/when"],function(e,t,r,i,n,o){"use strict";function a(e,t,r,i,n){this._tileset=e,this._tile=t,this._resource=r,this._readyPromise=o.defer(),this.featurePropertiesDirty=!1,s(this,i,n)}function s(t,r,o){o=e(o,0);var a,s=new Uint8Array(r),l=i(s,o);try{a=JSON.parse(l)}catch(e){return void t._readyPromise.reject(new n("Invalid tile content."))}t._tileset.loadTileset(t._resource,a,t._tile),t._readyPromise.resolve(t)}return t(a.prototype,{featuresLength:{get:function(){return 0}},pointsLength:{get:function(){return 0}},trianglesLength:{get:function(){return 0}},geometryByteLength:{get:function(){return 0}},texturesByteLength:{get:function(){return 0}},batchTableByteLength:{get:function(){return 0}},innerContents:{get:function(){}},readyPromise:{get:function(){return this._readyPromise.promise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){}}}),a.prototype.hasProperty=function(e,t){return!1},a.prototype.getFeature=function(e){},a.prototype.applyDebugSettings=function(e,t){},a.prototype.applyStyle=function(e,t){},a.prototype.update=function(e,t){},a.prototype.isDestroyed=function(){return!1},a.prototype.destroy=function(){return r(this)},a}),define("Scene/Cesium3DTilePointFeature",["../Core/Cartesian3","../Core/Cartographic","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Ellipsoid","./createBillboardPointCallback"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r,i,n){this._content=e,this._billboard=r,this._label=i,this._polyline=n,this._batchId=t,this._billboardImage=void 0,this._billboardColor=void 0,this._billboardOutlineColor=void 0,this._billboardOutlineWidth=void 0,this._billboardSize=void 0,this._pointSize=void 0,this._color=void 0,this._pointSize=void 0,this._pointOutlineColor=void 0,this._pointOutlineWidth=void 0,this._heightOffset=void 0,u(this)}function u(e){var t=e._billboard;if(n(e._billboardImage)&&e._billboardImage!==t.image)return void(t.image=e._billboardImage);if(!n(e._billboardImage)){var o=i(e._color,l.defaultColor),a=i(e._pointOutlineColor,l.defaultPointOutlineColor),u=i(e._pointOutlineWidth,l.defaultPointOutlineWidth),c=i(e._pointSize,l.defaultPointSize),d=e._billboardColor,h=e._billboardOutlineColor,p=e._billboardOutlineWidth,f=e._billboardSize;if(!r.equals(o,d)||!r.equals(a,h)||u!==p||c!==f){e._billboardColor=r.clone(o,e._billboardColor),e._billboardOutlineColor=r.clone(a,e._billboardOutlineColor),e._billboardOutlineWidth=u,e._billboardSize=c;var m=o.alpha,g=o.toCssColorString(),_=a.toCssColorString(),v=JSON.stringify([g,c,_,u]);t.setImage(v,s(m,g,_,u,c))}}}var c=new t;return o(l.prototype,{show:{get:function(){return this._label.show},set:function(e){this._label.show=e,this._billboard.show=e,this._polyline.show=e}},color:{get:function(){return this._color},set:function(e){this._color=r.clone(e,this._color),u(this)}},pointSize:{get:function(){return this._pointSize},set:function(e){this._pointSize=e,u(this)}},pointOutlineColor:{get:function(){return this._pointOutlineColor},set:function(e){this._pointOutlineColor=r.clone(e,this._pointOutlineColor),u(this)}},pointOutlineWidth:{get:function(){return this._pointOutlineWidth},set:function(e){this._pointOutlineWidth=e,u(this)}},labelColor:{get:function(){return this._label.fillColor},set:function(e){this._label.fillColor=e,this._polyline.show=this._label.show&&e.alpha>0}},labelOutlineColor:{get:function(){return this._label.outlineColor},set:function(e){this._label.outlineColor=e}},labelOutlineWidth:{get:function(){return this._label.outlineWidth},set:function(e){this._label.outlineWidth=e}},font:{get:function(){return this._label.font},set:function(e){this._label.font=e}},labelStyle:{get:function(){return this._label.style},set:function(e){this._label.style=e}},labelText:{get:function(){return this._label.text},set:function(e){n(e)||(e=""),this._label.text=e}},backgroundColor:{get:function(){return this._label.backgroundColor},set:function(e){this._label.backgroundColor=e}},backgroundPadding:{get:function(){return this._label.backgroundPadding},set:function(e){this._label.backgroundPadding=e}},backgroundEnabled:{get:function(){return this._label.showBackground},set:function(e){this._label.showBackground=e}},scaleByDistance:{get:function(){return this._label.scaleByDistance},set:function(e){this._label.scaleByDistance=e,this._billboard.scaleByDistance=e}},translucencyByDistance:{get:function(){return this._label.translucencyByDistance},set:function(e){this._label.translucencyByDistance=e,this._billboard.translucencyByDistance=e}},distanceDisplayCondition:{get:function(){return this._label.distanceDisplayCondition},set:function(e){this._label.distanceDisplayCondition=e,this._polyline.distanceDisplayCondition=e,this._billboard.distanceDisplayCondition=e}},heightOffset:{get:function(){return this._heightOffset},set:function(e){var t=i(this._heightOffset,0),r=this._content.tileset.ellipsoid,n=r.cartesianToCartographic(this._billboard.position,c);n.height=n.height-t+e;var o=r.cartographicToCartesian(n);this._billboard.position=o,this._label.position=this._billboard.position,this._polyline.positions=[this._polyline.positions[0],o],this._heightOffset=e}},anchorLineEnabled:{get:function(){return this._polyline.show},set:function(e){this._polyline.show=e}},anchorLineColor:{get:function(){return this._polyline.material.uniforms.color},set:function(e){this._polyline.material.uniforms.color=e}},image:{get:function(){return this._billboardImage},set:function(e){var t=this._billboardImage!==e;this._billboardImage=e,t&&u(this)}},disableDepthTestDistance:{get:function(){return this._label.disableDepthTestDistance},set:function(e){this._label.disableDepthTestDistance=e,this._billboard.disableDepthTestDistance=e}},horizontalOrigin:{get:function(){return this._billboard.horizontalOrigin},set:function(e){this._billboard.horizontalOrigin=e}},verticalOrigin:{get:function(){return this._billboard.verticalOrigin},set:function(e){this._billboard.verticalOrigin=e}},labelHorizontalOrigin:{get:function(){return this._label.horizontalOrigin},set:function(e){this._label.horizontalOrigin=e}},labelVerticalOrigin:{get:function(){return this._label.verticalOrigin},set:function(e){this._label.verticalOrigin=e}},content:{get:function(){return this._content}},tileset:{get:function(){return this._content.tileset}},primitive:{get:function(){return this._content.tileset}}}),l.defaultColor=r.WHITE,l.defaultPointOutlineColor=r.BLACK,l.defaultPointOutlineWidth=0,l.defaultPointSize=8,l.prototype.hasProperty=function(e){return this._content.batchTable.hasProperty(this._batchId,e)},l.prototype.getPropertyNames=function(e){return this._content.batchTable.getPropertyNames(this._batchId,e)},l.prototype.getProperty=function(e){return this._content.batchTable.getProperty(this._batchId,e)},l.prototype.setProperty=function(e,t){this._content.batchTable.setProperty(this._batchId,e,t),this._content.featurePropertiesDirty=!0},l.prototype.isExactClass=function(e){return this._content.batchTable.isExactClass(this._batchId,e)},l.prototype.isClass=function(e){return this._content.batchTable.isClass(this._batchId,e)},l.prototype.getExactClassName=function(){return this._content.batchTable.getExactClassName(this._batchId)},l}),define("Scene/Vector3DTilePoints",["../Core/arraySlice","../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DistanceDisplayCondition","../Core/Ellipsoid","../Core/NearFarScalar","../Core/Rectangle","../Core/TaskProcessor","../ThirdParty/when","./BillboardCollection","./Cesium3DTilePointFeature","./HorizontalOrigin","./LabelCollection","./LabelStyle","./PolylineCollection","./VerticalOrigin"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(e){this._positions=e.positions,this._batchTable=e.batchTable,this._batchIds=e.batchIds,this._rectangle=e.rectangle,this._minHeight=e.minimumHeight,this._maxHeight=e.maximumHeight,this._billboardCollection=void 0,this._labelCollection=void 0,this._polylineCollection=void 0,this._verticesPromise=void 0,this._packedBuffer=void 0,this._ready=!1,this._readyPromise=h.defer(),this._resolvedPromise=!1}function C(e,t){var r=e._rectangle,i=e._minHeight,n=e._maxHeight,o=2+c.packedLength+l.packedLength,a=new Float64Array(o),s=0;return a[s++]=i,a[s++]=n,c.pack(r,a,s),s+=c.packedLength,l.pack(t,a,s),a}function S(t,i){if(!n(t._billboardCollection)){var o;if(!n(t._verticesPromise)){o=t._positions;var a=t._packedBuffer;n(a)||(o=t._positions=e(o),t._batchIds=e(t._batchIds),a=t._packedBuffer=C(t,i));var s=[o.buffer,a.buffer],l={positions:o.buffer,packedBuffer:a.buffer},u=t._verticesPromise=T.scheduleTask(l,s);if(!n(u))return;u.then(function(e){t._positions=new Float64Array(e.positions),t._ready=!0})}if(t._ready&&!n(t._billboardCollection)){o=t._positions;var c=t._batchTable,d=t._batchIds,h=t._billboardCollection=new p({batchTable:c}),f=t._labelCollection=new g({batchTable:c}),m=t._polylineCollection=new v;m._useHighlightColor=!0;for(var _=o.length/3,y=0;y<_;++y){var b=d[y],S=r.unpack(o,3*y,E),w=h.add();w.position=S,w._batchIndex=b;var A=f.add();A.text=" ",A.position=S,A._batchIndex=b;m.add().positions=[r.clone(S),r.clone(S)]}t._positions=void 0,t._packedBuffer=void 0}}}function w(e,r){for(var n=e._batchIds,o=n.length,a=0;a<o;++a){var s=n[a],l=r[s];l.show=!0,l.pointSize=f.defaultPointSize,l.color=f.defaultColor,l.pointOutlineColor=f.defaultPointOutlineColor,l.pointOutlineWidth=f.defaultPointOutlineWidth,l.labelColor=i.WHITE,l.labelOutlineColor=i.WHITE,l.labelOutlineWidth=1,l.font="30px sans-serif",l.labelStyle=_.FILL,l.labelText=void 0,l.backgroundColor=new i(.165,.165,.165,.8),l.backgroundPadding=new t(7,5),l.backgroundEnabled=!1,l.scaleByDistance=void 0,l.translucencyByDistance=void 0,l.distanceDisplayCondition=void 0,l.heightOffset=0,l.anchorLineEnabled=!1,l.anchorLineColor=i.WHITE,l.image=void 0,l.disableDepthTestDistance=0,l.horizontalOrigin=m.CENTER,l.verticalOrigin=y.CENTER,l.labelHorizontalOrigin=m.RIGHT,l.labelVerticalOrigin=y.BASELINE}}o(b.prototype,{pointsLength:{get:function(){return this._billboardCollection.length}},texturesByteLength:{get:function(){return this._billboardCollection.textureAtlas.texture.sizeInBytes+this._labelCollection._textureAtlas.texture.sizeInBytes}},readyPromise:{get:function(){return this._readyPromise.promise}}});var T=new d("createVectorTilePoints"),E=new r;b.prototype.createFeatures=function(e,t){for(var r=this._billboardCollection,i=this._labelCollection,n=this._polylineCollection,o=this._batchIds,a=o.length,s=0;s<a;++s){var l=o[s],u=r.get(s),c=i.get(s),d=n.get(s);t[l]=new f(e,l,u,c,d)}},b.prototype.applyDebugSettings=function(e,t){e?(i.clone(t,this._billboardCollection._highlightColor),i.clone(t,this._labelCollection._highlightColor),i.clone(t,this._polylineCollection._highlightColor)):(i.clone(i.WHITE,this._billboardCollection._highlightColor),i.clone(i.WHITE,this._labelCollection._highlightColor),i.clone(i.WHITE,this._polylineCollection._highlightColor))};var A=new i,x=new i,P=new i,D=new i,I=new i,O=new i,M=new u,R=new u,L=new s;return b.prototype.applyStyle=function(e,t,r){if(!n(t))return void w(this,r);for(var i=this._batchIds,o=i.length,a=0;a<o;++a){var s=i[a],l=r[s];if(n(t.show)&&(l.show=t.show.evaluate(e,l)),n(t.pointSize)&&(l.pointSize=t.pointSize.evaluate(e,l)),n(t.color)&&(l.color=t.color.evaluateColor(e,l,A)),n(t.pointOutlineColor)&&(l.pointOutlineColor=t.pointOutlineColor.evaluateColor(e,l,x)),n(t.pointOutlineWidth)&&(l.pointOutlineWidth=t.pointOutlineWidth.evaluate(e,l)),n(t.labelColor)&&(l.labelColor=t.labelColor.evaluateColor(e,l,P)),n(t.labelOutlineColor)&&(l.labelOutlineColor=t.labelOutlineColor.evaluateColor(e,l,D)),n(t.labelOutlineWidth)&&(l.labelOutlineWidth=t.labelOutlineWidth.evaluate(e,l)),n(t.font)&&(l.font=t.font.evaluate(e,l)),n(t.labelStyle)&&(l.labelStyle=t.labelStyle.evaluate(e,l)),n(t.labelText)?l.labelText=t.labelText.evaluate(e,l):l.labelText=void 0,n(t.backgroundColor)&&(l.backgroundColor=t.backgroundColor.evaluateColor(e,l,I)),n(t.backgroundPadding)&&(l.backgroundPadding=t.backgroundPadding.evaluate(e,l)),n(t.backgroundEnabled)&&(l.backgroundEnabled=t.backgroundEnabled.evaluate(e,l)),n(t.scaleByDistance)){var u=t.scaleByDistance.evaluate(e,l);M.near=u.x,M.nearValue=u.y,M.far=u.z,M.farValue=u.w,l.scaleByDistance=M}else l.scaleByDistance=void 0;if(n(t.translucencyByDistance)){var c=t.translucencyByDistance.evaluate(e,l);R.near=c.x,R.nearValue=c.y,R.far=c.z,R.farValue=c.w,l.translucencyByDistance=R}else l.translucencyByDistance=void 0;if(n(t.distanceDisplayCondition)){var d=t.distanceDisplayCondition.evaluate(e,l);L.near=d.x,L.far=d.y,l.distanceDisplayCondition=L}else l.distanceDisplayCondition=void 0;n(t.heightOffset)&&(l.heightOffset=t.heightOffset.evaluate(e,l)),n(t.anchorLineEnabled)&&(l.anchorLineEnabled=t.anchorLineEnabled.evaluate(e,l)),n(t.anchorLineColor)&&(l.anchorLineColor=t.anchorLineColor.evaluateColor(e,l,O)),n(t.image)?l.image=t.image.evaluate(e,l):l.image=void 0,n(t.disableDepthTestDistance)&&(l.disableDepthTestDistance=t.disableDepthTestDistance.evaluate(e,l)),n(t.horizontalOrigin)&&(l.horizontalOrigin=t.horizontalOrigin.evaluate(e,l)),n(t.verticalOrigin)&&(l.verticalOrigin=t.verticalOrigin.evaluate(e,l)),n(t.labelHorizontalOrigin)&&(l.labelHorizontalOrigin=t.labelHorizontalOrigin.evaluate(e,l)),n(t.labelVerticalOrigin)&&(l.labelVerticalOrigin=t.labelVerticalOrigin.evaluate(e,l))}},b.prototype.update=function(e){S(this,e.mapProjection.ellipsoid),this._ready&&(this._polylineCollection.update(e),this._billboardCollection.update(e),this._labelCollection.update(e),this._resolvedPromise||(this._readyPromise.resolve(),this._resolvedPromise=!0))},b.prototype.isDestroyed=function(){return!1},b.prototype.destroy=function(){return this._billboardCollection=this._billboardCollection&&this._billboardCollection.destroy(),this._labelCollection=this._labelCollection&&this._labelCollection.destroy(),this._polylineCollection=this._polylineCollection&&this._polylineCollection.destroy(),a(this)},b}),define("Scene/Vector3DTilePolygons",["../Core/arraySlice","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Ellipsoid","../Core/IndexDatatype","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/Rectangle","../Core/TaskProcessor","../ThirdParty/when","./ClassificationType","./Vector3DTileBatch","./Vector3DTilePrimitive"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){this._batchTable=e.batchTable,this._batchIds=e.batchIds,this._positions=e.positions,this._counts=e.counts,this._indices=e.indices,this._indexCounts=e.indexCounts,this._indexOffsets=void 0,this._batchTableColors=void 0,this._packedBuffer=void 0,this._batchedPositions=void 0,this._transferrableBatchIds=void 0,this._vertexBatchIds=void 0,this._ellipsoid=i(e.ellipsoid,s.WGS84),this._minimumHeight=e.minimumHeight,this._maximumHeight=e.maximumHeight,this._polygonMinimumHeights=e.polygonMinimumHeights,this._polygonMaximumHeights=e.polygonMaximumHeights,this._center=i(e.center,t.ZERO),this._rectangle=e.rectangle,this._center=void 0,this._boundingVolume=e.boundingVolume,this._boundingVolumes=void 0,this._batchedIndices=void 0,this._ready=!1,this._readyPromise=p.defer(),this._verticesPromise=void 0,this._primitive=void 0,this.debugWireframe=!1,this.forceRebatch=!1,this.classificationType=f.CESIUM_3D_TILE}function v(e){var r=new Float64Array(3+t.packedLength+s.packedLength+d.packedLength),i=0;return r[i++]=e._indices.BYTES_PER_ELEMENT,r[i++]=e._minimumHeight,r[i++]=e._maximumHeight,t.pack(e._center,r,i),i+=t.packedLength,s.pack(e._ellipsoid,r,i),i+=s.packedLength,d.pack(e._rectangle,r,i),r}function y(e,t){for(var i=1,n=t[i++],o=e._boundingVolumes=new Array(n),a=0;a<n;++a)o[a]=c.unpack(t,i),i+=c.packedLength;for(var s=t[i++],l=e._batchedIndices=new Array(s),u=0;u<s;++u){var d=r.unpack(t,i);i+=r.packedLength;for(var h=t[i++],p=t[i++],f=t[i++],g=new Array(f),_=0;_<f;++_)g[_]=t[i++];l[u]=new m({color:d,offset:h,count:p,batchIds:g})}}function b(t){if(!n(t._primitive)){if(!n(t._verticesPromise)){var r=t._positions,i=t._counts,o=t._indexCounts,a=t._indices,s=t._transferrableBatchIds,u=t._batchTableColors,c=t._packedBuffer;if(!n(u)){r=t._positions=e(t._positions),i=t._counts=e(t._counts),o=t._indexCounts=e(t._indexCounts),a=t._indices=e(t._indices),t._center=t._ellipsoid.cartographicToCartesian(d.center(t._rectangle)),s=t._transferrableBatchIds=new Uint32Array(t._batchIds),u=t._batchTableColors=new Uint32Array(s.length);for(var h=t._batchTable,f=u.length,m=0;m<f;++m){var _=h.getColor(m,S);u[m]=_.toRgba()}c=t._packedBuffer=v(t)}var b=[r.buffer,i.buffer,o.buffer,a.buffer,s.buffer,u.buffer,c.buffer],w={packedBuffer:c.buffer,positions:r.buffer,counts:i.buffer,indexCounts:o.buffer,indices:a.buffer,batchIds:s.buffer,batchTableColors:u.buffer},T=t._polygonMinimumHeights,E=t._polygonMaximumHeights;n(T)&&n(E)&&(b.push(T.buffer,E.buffer),w.minimumHeights=T,w.maximumHeights=E);var A=t._verticesPromise=C.scheduleTask(w,b);if(!n(A))return;p(A,function(e){t._positions=void 0,t._counts=void 0,t._polygonMinimumHeights=void 0,t._polygonMaximumHeights=void 0;var r=new Float64Array(e.packedBuffer),i=r[0];y(t,r),t._indices=2===l.getSizeInBytes(i)?new Uint16Array(e.indices):new Uint32Array(e.indices),t._indexOffsets=new Uint32Array(e.indexOffsets),t._indexCounts=new Uint32Array(e.indexCounts),t._batchedPositions=new Float32Array(e.positions),t._vertexBatchIds=new Uint16Array(e.batchIds),t._ready=!0})}t._ready&&!n(t._primitive)&&(t._primitive=new g({batchTable:t._batchTable,positions:t._batchedPositions,batchIds:t._batchIds,vertexBatchIds:t._vertexBatchIds,indices:t._indices,indexOffsets:t._indexOffsets,indexCounts:t._indexCounts,batchedIndices:t._batchedIndices,boundingVolume:t._boundingVolume,boundingVolumes:t._boundingVolumes,center:t._center}),t._batchTable=void 0,t._batchIds=void 0,t._positions=void 0,t._counts=void 0,t._indices=void 0,t._indexCounts=void 0,t._indexOffsets=void 0,t._batchTableColors=void 0,t._packedBuffer=void 0,t._batchedPositions=void 0,t._transferrableBatchIds=void 0,t._vertexBatchIds=void 0,t._ellipsoid=void 0,t._minimumHeight=void 0,t._maximumHeight=void 0,t._polygonMinimumHeights=void 0,t._polygonMaximumHeights=void 0,t._center=void 0,t._rectangle=void 0,t._boundingVolume=void 0,t._boundingVolumes=void 0,t._batchedIndices=void 0,t._verticesPromise=void 0,t._readyPromise.resolve())}}o(_.prototype,{trianglesLength:{get:function(){return n(this._primitive)?this._primitive.trianglesLength:0}},geometryByteLength:{get:function(){return n(this._primitive)?this._primitive.geometryByteLength:0}},readyPromise:{get:function(){return this._readyPromise.promise}}});var C=new h("createVectorTilePolygons"),S=new r;return _.prototype.createFeatures=function(e,t){this._primitive.createFeatures(e,t)},_.prototype.applyDebugSettings=function(e,t){this._primitive.applyDebugSettings(e,t)},_.prototype.applyStyle=function(e,t,r){this._primitive.applyStyle(e,t,r)},_.prototype.updateCommands=function(e,t){this._primitive.updateCommands(e,t)},_.prototype.update=function(e){b(this),this._ready&&(this._primitive.debugWireframe=this.debugWireframe,this._primitive.forceRebatch=this.forceRebatch,this._primitive.classificationType=this.classificationType,this._primitive.update(e))},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return this._primitive=this._primitive&&this._primitive.destroy(),a(this)},_}),define("Shaders/Vector3DTilePolylinesVS",[],function(){"use strict";return"attribute vec4 currentPosition;\nattribute vec4 previousPosition;\nattribute vec4 nextPosition;\nattribute vec2 expandAndWidth;\nattribute float a_batchId;\nuniform mat4 u_modifiedModelView;\nvoid main()\n{\nfloat expandDir = expandAndWidth.x;\nfloat width = abs(expandAndWidth.y) + 0.5;\nbool usePrev = expandAndWidth.y < 0.0;\nvec4 p = u_modifiedModelView * currentPosition;\nvec4 prev = u_modifiedModelView * previousPosition;\nvec4 next = u_modifiedModelView * nextPosition;\nfloat angle;\nvec4 positionWC = getPolylineWindowCoordinatesEC(p, prev, next, expandDir, width, usePrev, angle);\ngl_Position = czm_viewportOrthographic * positionWC;\n}\n"}),define("Scene/Vector3DTilePolylines",["../Core/arraySlice","../Core/Cartesian3","../Core/Color","../Core/ComponentDatatype","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Ellipsoid","../Core/IndexDatatype","../Core/Matrix4","../Core/Rectangle","../Core/TaskProcessor","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../Shaders/PolylineCommon","../Shaders/Vector3DTilePolylinesVS","../ThirdParty/when","./BlendingState","./Cesium3DTileFeature"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E){"use strict";function A(e){this._positions=e.positions,this._widths=e.widths,this._counts=e.counts,this._batchIds=e.batchIds,this._ellipsoid=n(e.ellipsoid,l.WGS84),this._minimumHeight=e.minimumHeight,this._maximumHeight=e.maximumHeight,this._center=e.center,this._rectangle=e.rectangle,this._boundingVolume=e.boundingVolume,this._batchTable=e.batchTable,this._va=void 0,this._sp=void 0,this._rs=void 0,this._uniformMap=void 0,this._command=void 0,this._spPick=void 0,this._rsPick=void 0,this._pickCommand=void 0,this._transferrableBatchIds=void 0,this._packedBuffer=void 0,this._currentPositions=void 0,this._previousPositions=void 0,this._nextPositions=void 0,this._expandAndWidth=void 0,this._vertexBatchIds=void 0,this._indices=void 0,this._constantColor=r.clone(r.WHITE),this._highlightColor=this._constantColor,this._trianglesLength=0,this._geometryByteLength=0,this._ready=!1,this._readyPromise=w.defer(),this._verticesPromise=void 0}function x(e){var r=e._rectangle,i=e._minimumHeight,n=e._maximumHeight,o=e._ellipsoid,a=e._center,s=2+d.packedLength+l.packedLength+t.packedLength,u=new Float64Array(s),c=0;return u[c++]=i,u[c++]=n,d.pack(r,u,c),c+=d.packedLength,l.pack(o,u,c),c+=l.packedLength,t.pack(a,u,c),u}function P(t,r){if(!o(t._va)){if(!o(t._verticesPromise)){var n=t._positions,a=t._widths,s=t._counts,l=t._transferrableBatchIds,c=t._packedBuffer;o(c)||(n=t._positions=e(n),a=t._widths=e(a),s=t._counts=e(s),l=t._transferrableBatchIds=e(t._batchIds),c=t._packedBuffer=x(t));var d=[n.buffer,a.buffer,s.buffer,l.buffer,c.buffer],h={positions:n.buffer,widths:a.buffer,counts:s.buffer,batchIds:l.buffer,packedBuffer:c.buffer},m=t._verticesPromise=N.scheduleTask(h,d);if(!o(m))return;w(m,function(e){t._currentPositions=new Float32Array(e.currentPositions),t._previousPositions=new Float32Array(e.previousPositions),t._nextPositions=new Float32Array(e.nextPositions),t._expandAndWidth=new Float32Array(e.expandAndWidth),t._vertexBatchIds=new Uint16Array(e.batchIds);var r=e.indexDatatype;t._indices=r===u.UNSIGNED_SHORT?new Uint16Array(e.indices):new Uint32Array(e.indices),t._ready=!0})}if(t._ready&&!o(t._va)){var g=t._currentPositions,_=t._previousPositions,v=t._nextPositions,y=t._expandAndWidth,C=t._vertexBatchIds,S=t._indices,T=_.byteLength+g.byteLength+v.byteLength;T+=y.byteLength+C.byteLength+S.byteLength,t._trianglesLength=S.length/3,t._geometryByteLength=T;var E=p.createVertexBuffer({context:r,typedArray:_,usage:f.STATIC_DRAW}),A=p.createVertexBuffer({context:r,typedArray:g,usage:f.STATIC_DRAW}),P=p.createVertexBuffer({context:r,typedArray:v,usage:f.STATIC_DRAW}),D=p.createVertexBuffer({context:r,typedArray:y,usage:f.STATIC_DRAW}),I=p.createVertexBuffer({context:r,typedArray:C,usage:f.STATIC_DRAW}),O=p.createIndexBuffer({context:r,typedArray:S,usage:f.STATIC_DRAW,indexDatatype:2===S.BYTES_PER_ELEMENT?u.UNSIGNED_SHORT:u.UNSIGNED_INT}),M=[{index:k.previousPosition,vertexBuffer:E,componentDatatype:i.FLOAT,componentsPerAttribute:3},{index:k.currentPosition,vertexBuffer:A,componentDatatype:i.FLOAT,componentsPerAttribute:3},{index:k.nextPosition,vertexBuffer:P,componentDatatype:i.FLOAT,componentsPerAttribute:3},{index:k.expandAndWidth,vertexBuffer:D,componentDatatype:i.FLOAT,componentsPerAttribute:2},{index:k.a_batchId,vertexBuffer:I,componentDatatype:i.UNSIGNED_SHORT,componentsPerAttribute:1}];t._va=new b({context:r,attributes:M,indexBuffer:O}),t._positions=void 0,t._widths=void 0,t._counts=void 0,t._ellipsoid=void 0,t._minimumHeight=void 0,t._maximumHeight=void 0,t._rectangle=void 0,t._transferrableBatchIds=void 0,t._packedBuffer=void 0,t._currentPositions=void 0,t._previousPositions=void 0,t._nextPositions=void 0,t._expandAndWidth=void 0,t._vertexBatchIds=void 0,t._indices=void 0,t._readyPromise.resolve()}}}function D(e,t){o(e._uniformMap)||(e._uniformMap={u_modifiedModelView:function(){var r=t.uniformState.view;return c.clone(r,F),c.multiplyByPoint(F,e._center,B),c.setTranslation(F,B,F),F},u_highlightColor:function(){return e._highlightColor}})}function I(e){if(!o(e._rs)){var t={enabled:!0,factor:-5,units:-5};e._rs=_.fromCache({blending:T.ALPHA_BLEND,depthMask:!1,depthTest:{enabled:!0},polygonOffset:t}),e._rsPick=_.fromCache({depthMask:!1,depthTest:{enabled:!0},polygonOffset:t})}}function O(e,t){if(!o(e._sp)){var r=e._batchTable,i=r.getVertexShaderCallback(!1,"a_batchId",void 0)(S),n=r.getFragmentShaderCallback()(U,!1,void 0),a=new y({defines:["VECTOR_TILE"],sources:[C,i]}),s=new y({defines:["VECTOR_TILE"],sources:[n]});e._sp=v.fromCache({context:t,vertexShaderSource:a,fragmentShaderSource:s,attributeLocations:k}),i=r.getPickVertexShaderCallback("a_batchId")(S),n=r.getPickFragmentShaderCallback()(U,!1,void 0);var l=new y({defines:["VECTOR_TILE"],sources:[C,i]}),u=new y({defines:["VECTOR_TILE"],sources:[n]});e._spPick=v.fromCache({context:t,vertexShaderSource:l,fragmentShaderSource:u,attributeLocations:k})}}function M(e,t){if(!o(e._command)){var r=e._batchTable.getUniformMapCallback()(e._uniformMap);e._command=new m({owner:e,vertexArray:e._va,renderState:e._rs,shaderProgram:e._sp,uniformMap:r,boundingVolume:e._boundingVolume,pass:g.TRANSLUCENT})}t.commandList.push(e._command)}function R(e,t){if(!o(e._pickCommand)){var r=e._batchTable.getPickUniformMapCallback()(e._uniformMap);e._pickCommand=new m({owner:e,vertexArray:e._va,renderState:e._rsPick,shaderProgram:e._spPick,uniformMap:r,boundingVolume:e._boundingVolume,pass:g.TRANSLUCENT})}t.commandList.push(e._pickCommand)}function L(e,t){for(var i=e._batchIds,n=i.length,o=0;o<n;++o){var a=i[o],s=t[a];s.show=!0,s.color=r.WHITE}}a(A.prototype,{trianglesLength:{get:function(){return this._trianglesLength}},geometryByteLength:{get:function(){return this._geometryByteLength}},readyPromise:{get:function(){return this._readyPromise.promise}}});var N=new h("createVectorTilePolylines"),k={previousPosition:0,currentPosition:1,nextPosition:2,expandAndWidth:3,a_batchId:4},F=new c,B=new t,U="uniform vec4 u_highlightColor; \nvoid main()\n{\n gl_FragColor = u_highlightColor;\n}\n";A.prototype.createFeatures=function(e,t){for(var r=this._batchIds,i=r.length,n=0;n<i;++n){var o=r[n];t[o]=new E(e,o)}},A.prototype.applyDebugSettings=function(e,t){this._highlightColor=e?t:this._constantColor};var V=new r,z=r.WHITE;return A.prototype.applyStyle=function(e,t,r){if(!o(t))return void L(this,r);for(var i=this._batchIds,n=i.length,a=0;a<n;++a){var s=i[a],l=r[s];l.color=o(t.color)?t.color.evaluateColor(e,l,V):z,l.show=!o(t.show)||t.show.evaluate(e,l)}},A.prototype.update=function(e){var t=e.context;if(P(this,t),D(this,t),O(this,t),I(this),this._ready){var r=e.passes;r.render&&M(this,e),r.pick&&R(this,e)}},A.prototype.isDestroyed=function(){return!1},A.prototype.destroy=function(){return this._va=this._va&&this._va.destroy(),this._sp=this._sp&&this._sp.destroy(),this._spPick=this._spPick&&this._spPick.destroy(),s(this)},A}),define("Scene/Vector3DTileContent",["../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/getMagic","../Core/getStringFromTypedArray","../Core/Math","../Core/Matrix4","../Core/Rectangle","../Core/RuntimeError","../ThirdParty/when","./Cesium3DTileBatchTable","./Vector3DTilePoints","./Vector3DTilePolygons","./Vector3DTilePolylines"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(e,t,r,i,n){this._tileset=e,this._tile=t,this._resource=r,this._polygons=void 0,this._polylines=void 0,this._points=void 0,this._contentReadyPromise=void 0,this._readyPromise=f.defer(),this._batchTable=void 0,this._features=void 0,this.featurePropertiesDirty=!1,S(this,i,n)}function b(e){return function(t,i){ +r(e._polygons)&&e._polygons.updateCommands(t,i)}}function C(e,i){var n,o,a,s,l=t(e.POLYGONS_LENGTH,0),u=t(e.POLYLINES_LENGTH,0),c=t(e.POINTS_LENGTH,0);if(l>0&&r(e.POLYGON_BATCH_IDS)){var d=i.byteOffset+e.POLYGON_BATCH_IDS.byteOffset;n=new Uint16Array(i.buffer,d,l)}if(u>0&&r(e.POLYLINE_BATCH_IDS)){var h=i.byteOffset+e.POLYLINE_BATCH_IDS.byteOffset;o=new Uint16Array(i.buffer,h,u)}if(c>0&&r(e.POINT_BATCH_IDS)){var f=i.byteOffset+e.POINT_BATCH_IDS.byteOffset;a=new Uint16Array(i.buffer,f,c)}var m=r(n)||r(o)||r(a),g=l>0&&!r(n)||u>0&&!r(o)||c>0&&!r(a);if(m&&g)throw new p("If one group of batch ids is defined, then all batch ids must be defined.");if(!r(n)&&!r(o)&&!r(a)){var _=0;if(!r(n)&&l>0)for(n=new Uint16Array(l),s=0;s<l;++s)n[s]=_++;if(!r(o)&&u>0)for(o=new Uint16Array(u),s=0;s<u;++s)o[s]=_++;if(!r(a)&&c>0)for(a=new Uint16Array(c),s=0;s<c;++s)a[s]=_++}return{polygons:n,polylines:o,points:a}}function S(i,n,o){o=t(o,0);var s=new Uint8Array(n),l=new DataView(n);o+=E;var f=l.getUint32(o,!0);if(1!==f)throw new p("Only Vector tile version 1 is supported. Version "+f+" is not.");o+=E;var y=l.getUint32(o,!0);if(o+=E,0===y)return void i._readyPromise.resolve(i);var S=l.getUint32(o,!0);if(o+=E,0===S)throw new p("Feature table must have a byte length greater than zero");var w=l.getUint32(o,!0);o+=E;var A=l.getUint32(o,!0);o+=E;var x=l.getUint32(o,!0);o+=E;var P=l.getUint32(o,!0);o+=E;var D=l.getUint32(o,!0);o+=E;var I=l.getUint32(o,!0);o+=E;var O=l.getUint32(o,!0);o+=E;var M=u(s,o,S),R=JSON.parse(M);o+=S;var L=new Uint8Array(n,o,w);o+=w;var N,k;if(A>0){var F=u(s,o,A);N=JSON.parse(F),o+=A,x>0&&(k=new Uint8Array(n,o,x),k=new Uint8Array(k),o+=x)}var B=t(R.POLYGONS_LENGTH,0),U=t(R.POLYLINES_LENGTH,0),V=t(R.POINTS_LENGTH,0),z=B+U+V,G=new m(i,z,N,k,b(i));if(i._batchTable=G,0!==z){var W,H,j;if(!r(R.REGION))throw new p("REGION is required in the feature table.");var q=R.REGION;W=h.unpack(q),H=q[4],j=q[5];var Y,X=i._tile.computedTransform;r(R.RTC_CENTER)?(Y=e.unpack(R.RTC_CENTER),d.multiplyByPoint(X,Y,Y)):(Y=h.center(W),Y.height=c.lerp(H,j,.5),Y=a.WGS84.cartographicToCartesian(Y));var Q=C(R,L);if(o+=o%4,B>0){var Z=new Uint32Array(n,o,P/E);o+=P;var K=new Uint16Array(n,o,D/T);o+=D;var J,$,ee=L.byteOffset+R.POLYGON_COUNT.byteOffset,te=new Uint32Array(L.buffer,ee,B),re=L.byteOffset+R.POLYGON_INDEX_COUNT.byteOffset,ie=new Uint32Array(L.buffer,re,B);if(r(R.POLYGON_MINIMUM_HEIGHTS)&&r(R.POLYGON_MAXIMUM_HEIGHTS)){var ne=L.byteOffset+R.POLYGON_MINIMUM_HEIGHTS.byteOffset;J=new Float32Array(L.buffer,ne,B);var oe=L.byteOffset+R.POLYGON_MAXIMUM_HEIGHTS.byteOffset;$=new Float32Array(L.buffer,oe,B)}i._polygons=new _({positions:K,counts:te,indexCounts:ie,indices:Z,minimumHeight:H,maximumHeight:j,polygonMinimumHeights:J,polygonMaximumHeights:$,center:Y,rectangle:W,boundingVolume:i._tile._boundingVolume.boundingVolume,batchTable:G,batchIds:Q.polygons,modelMatrix:X})}if(U>0){var ae=new Uint16Array(n,o,I/T);o+=I;var se,le=L.byteOffset+R.POLYLINE_COUNT.byteOffset,ue=new Uint32Array(L.buffer,le,U);if(r(R.POLYLINE_WIDTHS)){var ce=L.byteOffset+R.POLYLINE_WIDTHS.byteOffset;se=new Uint16Array(L.buffer,ce,U)}else{se=new Uint16Array(U);for(var de=0;de<U;++de)se[de]=2}i._polylines=new v({positions:ae,widths:se,counts:ue,batchIds:Q.polylines,minimumHeight:H,maximumHeight:j,center:Y,rectangle:W,boundingVolume:i._tile._boundingVolume.boundingVolume,batchTable:G})}if(V>0){var he=new Uint16Array(n,o,O/T);i._points=new g({positions:he,batchIds:Q.points,minimumHeight:H,maximumHeight:j,rectangle:W,batchTable:G})}}}function w(e){var t=e.featuresLength;if(!r(e._features)&&t>0){var i=new Array(t);r(e._polygons)&&e._polygons.createFeatures(e,i),r(e._polylines)&&e._polylines.createFeatures(e,i),r(e._points)&&e._points.createFeatures(e,i),e._features=i}}if(!s.supportsTypedArrays())return{};i(y.prototype,{featuresLength:{get:function(){return r(this._batchTable)?this._batchTable.featuresLength:0}},pointsLength:{get:function(){return r(this._points)?this._points.pointsLength:0}},trianglesLength:{get:function(){var e=0;return r(this._polygons)&&(e+=this._polygons.trianglesLength),r(this._polylines)&&(e+=this._polylines.trianglesLength),e}},geometryByteLength:{get:function(){var e=0;return r(this._polygons)&&(e+=this._polygons.geometryByteLength),r(this._polylines)&&(e+=this._polylines.geometryByteLength),e}},texturesByteLength:{get:function(){return r(this._points)?this._points.texturesByteLength:0}},batchTableByteLength:{get:function(){return r(this._batchTable)?this._batchTable.memorySizeInBytes:0}},innerContents:{get:function(){}},readyPromise:{get:function(){return this._readyPromise.promise}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){return this._resource.getUrlComponent(!0)}},batchTable:{get:function(){return this._batchTable}}});var T=Uint16Array.BYTES_PER_ELEMENT,E=Uint32Array.BYTES_PER_ELEMENT;return y.prototype.hasProperty=function(e,t){return this._batchTable.hasProperty(e,t)},y.prototype.getFeature=function(e){return w(this),this._features[e]},y.prototype.applyDebugSettings=function(e,t){r(this._polygons)&&this._polygons.applyDebugSettings(e,t),r(this._polylines)&&this._polylines.applyDebugSettings(e,t),r(this._points)&&this._points.applyDebugSettings(e,t)},y.prototype.applyStyle=function(e,t){w(this),r(this._polygons)&&this._polygons.applyStyle(e,t,this._features),r(this._polylines)&&this._polylines.applyStyle(e,t,this._features),r(this._points)&&this._points.applyStyle(e,t,this._features)},y.prototype.update=function(e,t){if(r(this._batchTable)&&this._batchTable.update(e,t),r(this._polygons)&&(this._polygons.classificationType=this._tileset.classificationType,this._polygons.update(t)),r(this._polylines)&&this._polylines.update(t),r(this._points)&&this._points.update(t),!r(this._contentReadyPromise)){var i=r(this._points)?this._points.readyPromise:void 0,n=r(this._polygons)?this._polygons.readyPromise:void 0,o=r(this._polylines)?this._polylines.readyPromise:void 0,a=this;this._contentReadyPromise=f.all([i,n,o]).then(function(){a._readyPromise.resolve(a)})}},y.prototype.isDestroyed=function(){return!1},y.prototype.destroy=function(){return this._polygons=this._polygons&&this._polygons.destroy(),this._polylines=this._polylines&&this._polylines.destroy(),this._points=this._points&&this._points.destroy(),this._batchTable=this._batchTable&&this._batchTable.destroy(),n(this)},y}),define("Scene/Cesium3DTileContentFactory",["./Batched3DModel3DTileContent","./Composite3DTileContent","./Geometry3DTileContent","./Instanced3DModel3DTileContent","./PointCloud3DTileContent","./Tileset3DTileContent","./Vector3DTileContent"],function(e,t,r,i,n,o,a){"use strict";var s={b3dm:function(t,r,i,n,o){return new e(t,r,i,n,o)},pnts:function(e,t,r,i,o){return new n(e,t,r,i,o)},i3dm:function(e,t,r,n,o){return new i(e,t,r,n,o)},cmpt:function(e,r,i,n,o){return new t(e,r,i,n,o,s)},json:function(e,t,r,i,n){return new o(e,t,r,i,n)},geom:function(e,t,i,n,o){return new r(e,t,i,n,o)},vctr:function(e,t,r,i,n){return new a(e,t,r,i,n)}};return s}),define("Scene/Cesium3DTileContentState",["../Core/freezeObject"],function(e){"use strict";return e({UNLOADED:0,LOADING:1,PROCESSING:2,READY:3,EXPIRED:4,FAILED:5})}),define("Scene/Cesium3DTileOptimizationHint",["../Core/freezeObject"],function(e){"use strict";return e({NOT_COMPUTED:-1,USE_OPTIMIZATION:1,SKIP_OPTIMIZATION:0})}),define("Scene/Cesium3DTileRefine",["../Core/freezeObject"],function(e){"use strict";return e({ADD:0,REPLACE:1})}),define("Scene/Empty3DTileContent",["../Core/defineProperties","../Core/destroyObject"],function(e,t){"use strict";function r(e,t){this._tileset=e,this._tile=t,this.featurePropertiesDirty=!1}return e(r.prototype,{featuresLength:{get:function(){return 0}},pointsLength:{get:function(){return 0}},trianglesLength:{get:function(){return 0}},geometryByteLength:{get:function(){return 0}},texturesByteLength:{get:function(){return 0}},batchTableByteLength:{get:function(){return 0}},innerContents:{get:function(){}},readyPromise:{get:function(){}},tileset:{get:function(){return this._tileset}},tile:{get:function(){return this._tile}},url:{get:function(){}},batchTable:{get:function(){}}}),r.prototype.hasProperty=function(e,t){return!1},r.prototype.getFeature=function(e){},r.prototype.applyDebugSettings=function(e,t){},r.prototype.applyStyle=function(e,t){},r.prototype.update=function(e,t){},r.prototype.isDestroyed=function(){return!1},r.prototype.destroy=function(){return t(this)},r}),define("Scene/TileBoundingRegion",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Cartographic","../Core/Check","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defineProperties","../Core/Ellipsoid","../Core/GeometryInstance","../Core/IntersectionTests","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/Plane","../Core/Ray","../Core/Rectangle","../Core/RectangleOutlineGeometry","./PerInstanceColorAppearance","./Primitive","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(r){this.rectangle=f.clone(r.rectangle),this.minimumHeight=o(r.minimumHeight,0),this.maximumHeight=o(r.maximumHeight,0),this.southwestCornerCartesian=new t,this.northeastCornerCartesian=new t,this.westNormal=new t,this.southNormal=new t,this.eastNormal=new t,this.northNormal=new t;var i=o(r.ellipsoid,s.WGS84);b(this,r.rectangle,i),this._orientedBoundingBox=d.fromRectangle(this.rectangle,this.minimumHeight,this.maximumHeight,i),this._boundingSphere=e.fromOrientedBoundingBox(this._orientedBoundingBox)}function b(e,r,i){i.cartographicToCartesian(f.southwest(r),e.southwestCornerCartesian),i.cartographicToCartesian(f.northeast(r),e.northeastCornerCartesian),x.longitude=r.west,x.latitude=.5*(r.south+r.north),x.height=0;var n=i.cartographicToCartesian(x,E),o=t.cross(n,t.UNIT_Z,C);t.normalize(o,e.westNormal),x.longitude=r.east;var a=i.cartographicToCartesian(x,A),s=t.cross(t.UNIT_Z,a,C);t.normalize(s,e.eastNormal);var l,c=t.subtract(n,a,C),d=t.normalize(c,T),p=r.south;if(p>0){x.longitude=.5*(r.west+r.east),x.latitude=p;var m=i.cartographicToCartesian(x,D.origin);t.clone(d,D.direction);var g=h.fromPointNormal(e.southwestCornerCartesian,e.westNormal,P);u.rayPlane(D,g,e.southwestCornerCartesian),l=i.geodeticSurfaceNormal(m,S)}else l=i.geodeticSurfaceNormalCartographic(f.southeast(r),S);var _=t.cross(l,c,w);t.normalize(_,e.southNormal);var v,y=r.north;if(y<0){x.longitude=.5*(r.west+r.east),x.latitude=y;var b=i.cartographicToCartesian(x,D.origin);t.negate(d,D.direction);var I=h.fromPointNormal(e.northeastCornerCartesian,e.eastNormal,P);u.rayPlane(D,I,e.northeastCornerCartesian),v=i.geodeticSurfaceNormal(b,S)}else v=i.geodeticSurfaceNormalCartographic(f.northwest(r),S);var O=t.cross(c,v,w);t.normalize(O,e.northNormal)}a(y.prototype,{boundingVolume:{get:function(){return this._orientedBoundingBox}},boundingSphere:{get:function(){return this._boundingSphere}}});var C=new t,S=new t,w=new t,T=new t,E=new t,A=new t,x=new r,P=new h(t.UNIT_X,0),D=new p,I=new t,O=new t,M=new t(0,-1,0),R=new t(0,0,-1),L=new t;return y.prototype.distanceToCamera=function(e){var r=e.camera,i=r.positionWC,n=r.positionCartographic,o=0;if(!f.contains(this.rectangle,n)){var a=this.southwestCornerCartesian,s=this.northeastCornerCartesian,l=this.westNormal,u=this.southNormal,c=this.eastNormal,d=this.northNormal;e.mode!==v.SCENE3D&&(a=e.mapProjection.project(f.southwest(this.rectangle),I),a.z=a.y,a.y=a.x,a.x=0,s=e.mapProjection.project(f.northeast(this.rectangle),O),s.z=s.y,s.y=s.x,s.x=0,l=M,c=t.UNIT_Y,u=R,d=t.UNIT_Z);var h=t.subtract(i,a,L),p=t.dot(h,l),m=t.dot(h,u),g=t.subtract(i,s,L),_=t.dot(g,c),y=t.dot(g,d);p>0?o+=p*p:_>0&&(o+=_*_),m>0?o+=m*m:y>0&&(o+=y*y)}var b;b=e.mode===v.SCENE3D?n.height:i.x;var C=e.mode===v.SCENE3D?this.maximumHeight:0,S=b-C;return S>0&&(o+=S*S),Math.sqrt(o)},y.prototype.intersectPlane=function(e){return this._orientedBoundingBox.intersectPlane(e)},y.prototype.createDebugVolume=function(e){var t=new c.clone(c.IDENTITY),r=new m({rectangle:this.rectangle,height:this.minimumHeight,extrudedHeight:this.maximumHeight}),i=new l({geometry:r,modelMatrix:t,attributes:{color:n.fromColor(e)}});return new _({geometryInstances:i,appearance:new g({translucent:!1,flat:!0}),asynchronous:!1})},y}),define("Scene/TileBoundingSphere",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Check","../Core/ColorGeometryInstanceAttribute","../Core/defineProperties","../Core/GeometryInstance","../Core/Matrix4","../Core/SphereOutlineGeometry","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r){this._boundingSphere=new e(t,r)}return n(c.prototype,{center:{get:function(){return this._boundingSphere.center}},radius:{get:function(){return this._boundingSphere.radius}},boundingVolume:{get:function(){return this._boundingSphere}},boundingSphere:{get:function(){return this._boundingSphere}}}),c.prototype.distanceToCamera=function(e){var r=this._boundingSphere;return Math.max(0,t.distance(r.center,e.camera.positionWC)-r.radius)},c.prototype.intersectPlane=function(t){return e.intersectPlane(this._boundingSphere,t)},c.prototype.update=function(e,r){t.clone(e,this._boundingSphere.center),this._boundingSphere.radius=r},c.prototype.createDebugVolume=function(e){var t=new s({radius:this.radius}),r=a.fromTranslation(this.center,new a.clone(a.IDENTITY)),n=new o({geometry:t,modelMatrix:r,attributes:{color:i.fromColor(e)}});return new u({geometryInstances:n,appearance:new l({translucent:!1,flat:!0}),asynchronous:!1})},c}),define("Scene/TileOrientedBoundingBox",["../Core/BoundingSphere","../Core/BoxOutlineGeometry","../Core/Cartesian3","../Core/Check","../Core/ColorGeometryInstanceAttribute","../Core/defineProperties","../Core/GeometryInstance","../Core/Matrix3","../Core/Matrix4","../Core/OrientedBoundingBox","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t,r){this._orientedBoundingBox=new u(t,r),this._boundingSphere=e.fromOrientedBoundingBox(this._orientedBoundingBox)}return o(h.prototype,{boundingVolume:{get:function(){return this._orientedBoundingBox}},boundingSphere:{get:function(){return this._boundingSphere}}}),h.prototype.distanceToCamera=function(e){return Math.sqrt(this._orientedBoundingBox.distanceSquaredTo(e.camera.positionWC))},h.prototype.intersectPlane=function(e){return this._orientedBoundingBox.intersectPlane(e)},h.prototype.update=function(t,i){r.clone(t,this._orientedBoundingBox.center),s.clone(i,this._orientedBoundingBox.halfAxes),e.fromOrientedBoundingBox(this._orientedBoundingBox,this._boundingSphere)},h.prototype.createDebugVolume=function(e){var i=new t({minimum:new r(-1,-1,-1),maximum:new r(1,1,1)}),o=l.fromRotationTranslation(this.boundingVolume.halfAxes,this.boundingVolume.center),s=new a({geometry:i,modelMatrix:o,attributes:{color:n.fromColor(e)}});return new d({geometryInstances:s,appearance:new c({translucent:!1,flat:!0}),asynchronous:!1})},h}),define("Scene/Cesium3DTile",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Color","../Core/CullingVolume","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/getMagic","../Core/Intersect","../Core/JulianDate","../Core/Matrix3","../Core/Matrix4","../Core/Plane","../Core/Rectangle","../Core/Request","../Core/RequestScheduler","../Core/RequestState","../Core/RequestType","../Core/Resource","../Core/RuntimeError","../ThirdParty/when","./Cesium3DTileChildrenVisibility","./Cesium3DTileContentFactory","./Cesium3DTileContentState","./Cesium3DTileOptimizationHint","./Cesium3DTileRefine","./Empty3DTileContent","./SceneMode","./TileBoundingRegion","./TileBoundingSphere","./TileOrientedBoundingBox"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M){"use strict";function R(e,t,i,n){this._tileset=e,this._header=i;var a=i.content;this.transform=o(i.transform)?p.unpack(i.transform):p.clone(p.IDENTITY);var s=o(n)?n.computedTransform:e.modelMatrix,l=p.multiply(s,this.transform,new p);this.computedTransform=l,this._boundingVolume=this.createBoundingVolume(i.boundingVolume,l),this._boundingVolume2D=void 0;var u;o(a)&&o(a.boundingVolume)&&(u=this.createBoundingVolume(a.boundingVolume,l)),this._contentBoundingVolume=u,this._contentBoundingVolume2D=void 0;var c;o(i.viewerRequestVolume)&&(c=this.createBoundingVolume(i.viewerRequestVolume,l)),this._viewerRequestVolume=c,this.geometricError=i.geometricError,o(this.geometricError)||(this.geometricError=o(n)?n.geometricError:e._geometricError,R._deprecationWarning("geometricErrorUndefined","Required property geometricError is undefined for this tile. Using parent's geometric error instead."));var h;o(i.refine)?("replace"!==i.refine&&"add"!==i.refine||R._deprecationWarning("lowercase-refine",'This tile uses a lowercase refine "'+i.refine+'". Instead use "'+i.refine.toUpperCase()+'".'),h="REPLACE"===i.refine.toUpperCase()?x.REPLACE:x.ADD):h=o(n)?n.refine:x.REPLACE,this.refine=h,this.children=[],this.parent=n;var f,m,g,v,y;if(t=b.createIfNeeded(t),o(a)){var C=a.url;e._brokenUrlWorkaround&&C.length>0&&"/"===C[0]&&(C=a.url=C.substring(1)),m=!1,g=E.UNLOADED,v=t.getDerivedResource({url:C}),y=_.getServerKey(v.getUrlComponent())}else f=new P(e,this),m=!0,g=E.READY;this._content=f,this._contentResource=v,this._contentState=g,this._contentReadyToProcessPromise=void 0,this._contentReadyPromise=void 0,this._expiredContent=void 0,this._serverKey=y,this.hasEmptyContent=m,this.hasRenderableContent=!1,this.hasTilesetContent=!1,this.replacementNode=void 0;var S,T,D=i.expire;o(D)&&(S=D.duration,o(D.date)&&(T=d.fromIso8601(D.date))),this.expireDuration=S,this.expireDate=T,this.selected=!1,this.lastStyleTime=0,this._optimChildrenWithinParent=A.NOT_COMPUTED,this._distanceToCamera=0,this._visibilityPlaneMask=0,this._childrenVisibility=w.VISIBLE,this._lastSelectedFrameNumber=-1,this._screenSpaceError=0,this._screenSpaceErrorComputedFrame=-1,this._finalResolution=!0,this._depth=0,this._centerZDepth=0,this._stackLength=0,this._selectedFrame=-1,this._selectionDepth=0,this._lastSelectionDepth=void 0,this._requestedFrame=void 0,this._lastVisitedFrame=void 0,this._ancestorWithContent=void 0,this._ancestorWithLoadedContent=void 0,this._isClipped=!0,this._debugBoundingVolume=void 0,this._debugContentBoundingVolume=void 0,this._debugViewerRequestVolume=void 0,this._debugColor=r.fromRandom({alpha:1}),this._debugColorizeTiles=!1,this._commandsLength=0,this._color=void 0,this._colorDirty=!1}function L(e){if(o(e.expireDuration)){var t=d.now(H);d.addSeconds(t,e.expireDuration,t),o(e.expireDate)?d.lessThan(e.expireDate,t)&&d.clone(t,e.expireDate):e.expireDate=d.clone(t)}}function N(e){return function(t){e._contentState=E.FAILED,e._contentReadyPromise.reject(t),e._contentReadyToProcessPromise.reject(t)}}function k(e){return function(){return e._distanceToCamera}}function F(t,r){if(r.mode!==D.SCENE3D&&!o(t._boundingVolume2D)){var i=t._boundingVolume.boundingSphere,n=e.projectTo2D(i,r.mapProjection,j);t._boundingVolume2D=new O(n.center,n.radius)}return r.mode!==D.SCENE3D?t._boundingVolume2D:t._boundingVolume}function B(t,r){if(r.mode!==D.SCENE3D&&!o(t._contentBoundingVolume2D)){var i=t._contentBoundingVolume.boundingSphere,n=e.projectTo2D(i,r.mapProjection,j);t._contentBoundingVolume2D=new O(n.center,n.radius)}return r.mode!==D.SCENE3D?t._contentBoundingVolume2D:t._contentBoundingVolume}function U(e,r,i){var n=t.fromElements(e[0],e[1],e[2],Z),a=h.fromArray(e,3,Q);n=p.multiplyByPoint(r,n,n);var s=p.getRotation(r,Y);return a=h.multiply(s,a,a),o(i)?(i.update(n,a),i):new M(n,a)}function V(e,t){var r=m.unpack(e,0,K);return o(t)?t:new I({rectangle:r,minimumHeight:e[4],maximumHeight:e[5]})}function z(e,r,i){var n=t.fromElements(e[0],e[1],e[2],Z),a=e[3];n=p.multiplyByPoint(r,n,n);var s=p.getScale(r,X);return a*=t.maximumComponent(s),o(i)?(i.update(n,a),i):new O(n,a)}function G(e,t,i){var n=o(e._header.content)&&o(e._header.content.boundingVolume),a=t.debugShowBoundingVolume||t.debugShowContentBoundingVolume&&!n;if(a){if(!o(e._debugBoundingVolume)){var s=e._finalResolution?n?r.WHITE:r.RED:r.YELLOW;e._debugBoundingVolume=e._boundingVolume.createDebugVolume(s)}e._debugBoundingVolume.update(i)}else!a&&o(e._debugBoundingVolume)&&(e._debugBoundingVolume=e._debugBoundingVolume.destroy());t.debugShowContentBoundingVolume&&n?(o(e._debugContentBoundingVolume)||(e._debugContentBoundingVolume=e._contentBoundingVolume.createDebugVolume(r.BLUE)),e._debugContentBoundingVolume.update(i)):!t.debugShowContentBoundingVolume&&o(e._debugContentBoundingVolume)&&(e._debugContentBoundingVolume=e._debugContentBoundingVolume.destroy()),t.debugShowViewerRequestVolume&&o(e._viewerRequestVolume)?(o(e._debugViewerRequestVolume)||(e._debugViewerRequestVolume=e._viewerRequestVolume.createDebugVolume(r.YELLOW)),e._debugViewerRequestVolume.update(i)):!t.debugShowViewerRequestVolume&&o(e._debugViewerRequestVolume)&&(e._debugViewerRequestVolume=e._debugViewerRequestVolume.destroy());var l=t.debugColorizeTiles&&!e._debugColorizeTiles,u=!t.debugColorizeTiles&&e._debugColorizeTiles;l?(e._debugColorizeTiles=!0,e.color=e._debugColor):u&&(e._debugColorizeTiles=!1,e.color=r.WHITE),e._colorDirty&&(e._colorDirty=!1,e._content.applyDebugSettings(!0,e._color)),u&&t.makeStyleDirty()}function W(e,t,r){var i=e._content,n=e._expiredContent;if(o(n)){if(!e.contentReady)return void n.update(t,r);e._expiredContent.destroy(),e._expiredContent=void 0}i.update(t,r)}R._deprecationWarning=s,a(R.prototype,{tileset:{get:function(){return this._tileset}},content:{get:function(){return this._content}},contentBoundingVolume:{get:function(){return n(this._contentBoundingVolume,this._boundingVolume)}},boundingSphere:{get:function(){return this._boundingVolume.boundingSphere}},color:{get:function(){return o(this._color)||(this._color=new r),r.clone(this._color)},set:function(e){this._color=r.clone(e,this._color),this._colorDirty=!0}},contentAvailable:{get:function(){return this.contentReady||o(this._expiredContent)&&this._contentState!==E.FAILED}},contentReady:{get:function(){return this._contentState===E.READY}},contentUnloaded:{get:function(){return this._contentState===E.UNLOADED}},contentExpired:{get:function(){return this._contentState===E.EXPIRED}},contentReadyToProcessPromise:{get:function(){if(o(this._contentReadyToProcessPromise))return this._contentReadyToProcessPromise.promise}},contentReadyPromise:{get:function(){if(o(this._contentReadyPromise))return this._contentReadyPromise.promise}},commandsLength:{get:function(){return this._commandsLength}}});var H=new d;R.prototype.updateExpiration=function(){if(o(this.expireDate)&&this.contentReady&&!this.hasEmptyContent){var e=d.now(H);d.lessThan(this.expireDate,e)&&(this._contentState=E.EXPIRED,this._expiredContent=this._content)}},R.prototype.requestContent=function(){var e=this,t=this._tileset;if(this.hasEmptyContent)return!1;var r=this._contentResource.clone(),i=this.contentExpired;i&&r.addQueryParameters({expired:this.expireDate.toString()});var n=new g({throttle:!0,throttleByServer:!0,type:y.TILES3D,priorityFunction:k(this),serverKey:this._serverKey});r.request=n;var a=r.fetchArrayBuffer();if(!o(a))return!1;var s=this._contentState;this._contentState=E.LOADING,this._contentReadyToProcessPromise=S.defer(),this._contentReadyPromise=S.defer(),i&&(this.expireDate=void 0);var l=N(this);return a.then(function(r){if(e.isDestroyed())return void l();var i,n=new Uint8Array(r),a=u(n),s=T[a];return t._disableSkipLevelOfDetail=t._disableSkipLevelOfDetail||"vctr"===a||"geom"===a,o(s)?(i=s(t,e,e._contentResource,r,0),e.hasRenderableContent=!0):(i=T.json(t,e,e._contentResource,r,0),e.hasTilesetContent=!0),e._content=i,e._contentState=E.PROCESSING,e._contentReadyToProcessPromise.resolve(i),i.readyPromise.then(function(t){if(e.isDestroyed())return void l();L(e),e.lastStyleTime=0,e._contentState=E.READY,e._contentReadyPromise.resolve(t)})}).otherwise(function(r){if(n.state===v.CANCELLED)return e._contentState=s,--t.statistics.numberOfPendingRequests,void++t.statistics.numberOfAttemptedRequests;l(r)}),!0},R.prototype.unloadContent=function(){this.hasRenderableContent&&(this._content=this._content&&this._content.destroy(),this._contentState=E.UNLOADED,this._contentReadyToProcessPromise=void 0,this._contentReadyPromise=void 0,this.replacementNode=void 0,this.lastStyleTime=0,this._debugColorizeTiles=!1,this._debugBoundingVolume=this._debugBoundingVolume&&this._debugBoundingVolume.destroy(),this._debugContentBoundingVolume=this._debugContentBoundingVolume&&this._debugContentBoundingVolume.destroy(),this._debugViewerRequestVolume=this._debugViewerRequestVolume&&this._debugViewerRequestVolume.destroy())};var j=new e;R.prototype.visibility=function(e,t){var r=e.cullingVolume,n=F(this,e),a=this._tileset,s=a.clippingPlanes;if(o(s)&&s.enabled){var l=a._root.computedTransform,u=s.computeIntersectionWithBoundingVolume(n,l);if(this._isClipped=u!==c.INSIDE,u===c.OUTSIDE)return i.MASK_OUTSIDE}return r.computeVisibilityWithPlaneMask(n,t)},R.prototype.contentVisibility=function(e){if(!o(this._contentBoundingVolume))return c.INSIDE;var t=e.cullingVolume,r=B(this,e),i=this._tileset,n=i.clippingPlanes;if(o(n)&&n.enabled){var a=i._root.computedTransform,s=n.computeIntersectionWithBoundingVolume(r,a);if(this._isClipped=s!==c.INSIDE,s===c.OUTSIDE)return c.OUTSIDE}return t.computeVisibility(r)},R.prototype.distanceToTile=function(e){return F(this,e).distanceToCamera(e)};var q=new t;R.prototype.distanceToTileCenter=function(e){var r=F(this,e),i=r.boundingVolume,n=t.subtract(i.center,e.camera.positionWC,q),o=t.magnitude(n);return t.divideByScalar(n,o,n),o*t.dot(e.camera.directionWC,n)},R.prototype.insideViewerRequestVolume=function(e){var t=this._viewerRequestVolume;return!o(t)||0===t.distanceToCamera(e)};var Y=new h,X=new t,Q=new h,Z=new t,K=new m;R.prototype.createBoundingVolume=function(e,t,r){if(!o(e))throw new C("boundingVolume must be defined");if(o(e.box))return U(e.box,t,r);if(o(e.region))return V(e.region,r);if(o(e.sphere))return z(e.sphere,t,r);throw new C("boundingVolume must contain a sphere, region, or box")};var J=new p;R.prototype.updateTransform=function(e){e=n(e,p.IDENTITY);var t=p.multiply(e,this.transform,J);if(!p.equals(t,this.computedTransform)){p.clone(t,this.computedTransform);var r=this._header,i=this._header.content;this._boundingVolume=this.createBoundingVolume(r.boundingVolume,t,this._boundingVolume),o(this._contentBoundingVolume)&&(this._contentBoundingVolume=this.createBoundingVolume(i.boundingVolume,t,this._contentBoundingVolume)),o(this._viewerRequestVolume)&&(this._viewerRequestVolume=this.createBoundingVolume(r.viewerRequestVolume,t,this._viewerRequestVolume)),this._debugBoundingVolume=this._debugBoundingVolume&&this._debugBoundingVolume.destroy(),this._debugContentBoundingVolume=this._debugContentBoundingVolume&&this._debugContentBoundingVolume.destroy(),this._debugViewerRequestVolume=this._debugViewerRequestVolume&&this._debugViewerRequestVolume.destroy()}},R.prototype.update=function(e,t){var r=t.commandList.length;G(this,e,t),W(this,e,t),this._commandsLength=t.commandList.length-r};var $=[];return R.prototype.process=function(e,t){var r=t.commandList;t.commandList=$,this._content.update(e,t),$.length=0,t.commandList=r},R.prototype.isDestroyed=function(){return!1},R.prototype.destroy=function(){return this._content=this._content&&this._content.destroy(),this._expiredContent=this._expiredContent&&!this._expiredContent.isDestroyed()&&this._expiredContent.destroy(),this._debugBoundingVolume=this._debugBoundingVolume&&this._debugBoundingVolume.destroy(),this._debugContentBoundingVolume=this._debugContentBoundingVolume&&this._debugContentBoundingVolume.destroy(),this._debugViewerRequestVolume=this._debugViewerRequestVolume&&this._debugViewerRequestVolume.destroy(),l(this)},R}),define("Scene/Cesium3DTileContent",["../Core/defineProperties","../Core/DeveloperError"],function(e,t){"use strict";function r(e,t,r,i,n){this.featurePropertiesDirty=!1}return e(r.prototype,{featuresLength:{get:function(){t.throwInstantiationError()}},pointsLength:{get:function(){t.throwInstantiationError()}},trianglesLength:{get:function(){t.throwInstantiationError()}},geometryByteLength:{get:function(){t.throwInstantiationError()}},texturesByteLength:{get:function(){t.throwInstantiationError()}},batchTableByteLength:{get:function(){t.throwInstantiationError()}},innerContents:{get:function(){t.throwInstantiationError()}},readyPromise:{get:function(){t.throwInstantiationError()}},tileset:{get:function(){t.throwInstantiationError()}},tile:{get:function(){t.throwInstantiationError()}},url:{get:function(){t.throwInstantiationError()}},batchTable:{get:function(){t.throwInstantiationError()}}}),r.prototype.hasProperty=function(e,r){t.throwInstantiationError()},r.prototype.getFeature=function(e){t.throwInstantiationError()},r.prototype.applyDebugSettings=function(e,r){t.throwInstantiationError()},r.prototype.applyStyle=function(e,r){t.throwInstantiationError()},r.prototype.update=function(e,r){t.throwInstantiationError()},r.prototype.isDestroyed=function(){t.throwInstantiationError()},r.prototype.destroy=function(){t.throwInstantiationError()},r}),define("Scene/Cesium3DTileOptimizations",["../Core/Cartesian3","../Core/Check","./Cesium3DTileOptimizationHint","./TileBoundingRegion","./TileOrientedBoundingBox"],function(e,t,r,i,n){"use strict";var o={},a=new e;return o.checkChildrenWithinParent=function(t){var o=t.children,s=o.length,l=t._boundingVolume;if(l instanceof n||l instanceof i){var u=l._orientedBoundingBox;t._optimChildrenWithinParent=r.USE_OPTIMIZATION;for(var c=0;c<s;++c){var d=o[c],h=d._boundingVolume;if(!(h instanceof n||h instanceof i)){t._optimChildrenWithinParent=r.SKIP_OPTIMIZATION;break}var p=h._orientedBoundingBox,f=e.subtract(p.center,u.center,a),m=e.magnitude(f);e.divideByScalar(f,m,f);if(Math.abs(u.halfAxes[0]*f.x)+Math.abs(u.halfAxes[1]*f.y)+Math.abs(u.halfAxes[2]*f.z)+Math.abs(u.halfAxes[3]*f.x)+Math.abs(u.halfAxes[4]*f.y)+Math.abs(u.halfAxes[5]*f.z)+Math.abs(u.halfAxes[6]*f.x)+Math.abs(u.halfAxes[7]*f.y)+Math.abs(u.halfAxes[8]*f.z)<=Math.abs(p.halfAxes[0]*f.x)+Math.abs(p.halfAxes[1]*f.y)+Math.abs(p.halfAxes[2]*f.z)+Math.abs(p.halfAxes[3]*f.x)+Math.abs(p.halfAxes[4]*f.y)+Math.abs(p.halfAxes[5]*f.z)+Math.abs(p.halfAxes[6]*f.x)+Math.abs(p.halfAxes[7]*f.y)+Math.abs(p.halfAxes[8]*f.z)+m){t._optimChildrenWithinParent=r.SKIP_OPTIMIZATION;break}}}return t._optimChildrenWithinParent===r.USE_OPTIMIZATION},o}),define("Scene/Cesium3DTilesetStatistics",["../Core/defined"],function(e){"use strict";function t(){this.selected=0,this.visited=0,this.numberOfCommands=0,this.numberOfAttemptedRequests=0,this.numberOfPendingRequests=0,this.numberOfTilesProcessing=0,this.numberOfTilesWithContentReady=0,this.numberOfTilesTotal=0,this.numberOfFeaturesSelected=0,this.numberOfFeaturesLoaded=0,this.numberOfPointsSelected=0,this.numberOfPointsLoaded=0,this.numberOfTrianglesSelected=0,this.numberOfTilesStyled=0,this.numberOfFeaturesStyled=0,this.numberOfTilesCulledWithChildrenUnion=0,this.geometryByteLength=0,this.texturesByteLength=0,this.batchTableByteLength=0}function r(t,i,n,o){var a=i.innerContents,s=i.pointsLength,l=i.trianglesLength,u=i.featuresLength,c=i.geometryByteLength,d=i.texturesByteLength,h=i.batchTableByteLength;if(o?(t.numberOfFeaturesLoaded+=n?-u:u,t.numberOfPointsLoaded+=n?-s:s,t.geometryByteLength+=n?-c:c,t.texturesByteLength+=n?-d:d,t.batchTableByteLength+=n?-h:h):(t.numberOfFeaturesSelected+=n?-u:u,t.numberOfPointsSelected+=n?-s:s,t.numberOfTrianglesSelected+=n?-l:l),e(a))for(var p=a.length,f=0;f<p;++f)r(t,a[f],n,o)}return t.prototype.clear=function(){this.selected=0,this.visited=0,this.numberOfCommands=0,this.numberOfAttemptedRequests=0,this.numberOfFeaturesSelected=0,this.numberOfPointsSelected=0,this.numberOfTrianglesSelected=0,this.numberOfTilesStyled=0,this.numberOfFeaturesStyled=0,this.numberOfTilesCulledWithChildrenUnion=0}, +t.prototype.incrementSelectionCounts=function(e){r(this,e,!1,!1)},t.prototype.incrementLoadCounts=function(e){r(this,e,!1,!0)},t.prototype.decrementLoadCounts=function(e){r(this,e,!0,!0)},t.clone=function(e,t){t.selected=e.selected,t.visited=e.visited,t.numberOfCommands=e.numberOfCommands,t.selected=e.selected,t.numberOfAttemptedRequests=e.numberOfAttemptedRequests,t.numberOfPendingRequests=e.numberOfPendingRequests,t.numberOfTilesProcessing=e.numberOfTilesProcessing,t.numberOfTilesWithContentReady=e.numberOfTilesWithContentReady,t.numberOfTilesTotal=e.numberOfTilesTotal,t.numberOfFeaturesSelected=e.numberOfFeaturesSelected,t.numberOfFeaturesLoaded=e.numberOfFeaturesLoaded,t.numberOfPointsSelected=e.numberOfPointsSelected,t.numberOfPointsLoaded=e.numberOfPointsLoaded,t.numberOfTrianglesSelected=e.numberOfTrianglesSelected,t.numberOfTilesStyled=e.numberOfTilesStyled,t.numberOfFeaturesStyled=e.numberOfFeaturesStyled,t.numberOfTilesCulledWithChildrenUnion=e.numberOfTilesCulledWithChildrenUnion,t.geometryByteLength=e.geometryByteLength,t.texturesByteLength=e.texturesByteLength,t.batchTableByteLength=e.batchTableByteLength},t}),define("Scene/Cesium3DTilesetTraversal",["../Core/CullingVolume","../Core/defined","../Core/freezeObject","../Core/Intersect","../Core/ManagedArray","../Core/Math","../Core/OrthographicFrustum","./Cesium3DTileChildrenVisibility","./Cesium3DTileRefine","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,r,i){if(!t.debugFreezeFrame){var n=t._maximumScreenSpaceError;t._desiredTiles.length=0,t._selectedTiles.length=0,t._requestedTiles.length=0,t._selectedTilesToStyle.length=0,t._hasMixedContent=!1;var o=t._replacementList;o.splice(o.tail,t._replacementSentinel);var a=t._root;if(a.updateTransform(t._modelMatrix),a.insideViewerRequestVolume(r)&&(a._distanceToCamera=a.distanceToTile(r),!(P(t,t._geometricError,a,r)<=n)&&(a._visibilityPlaneMask=a.visibility(r,e.MASK_INDETERMINATE),a._visibilityPlaneMask!==e.MASK_OUTSIDE))){if(A(t,a,r,!0),t._skipLevelOfDetail)t.immediatelyLoadDesiredLevelOfDetail?t._skipTraversal.execute(t,a,r,i):(t._baseTraversal.leaves=t._skipTraversal.queue1,t._baseTraversal.execute(t,a,t.baseScreenSpaceError,r,i),t._skipTraversal.execute(t,void 0,r,i));else{t._baseTraversal.execute(t,a,n,r,i);for(var s=t._baseTraversal.leaves,l=s.length,u=0;u<l;++u)t._desiredTiles.push(s.get(u))}d(t,r,i),h(t,a,r),t._desiredTiles.trim()}}}function d(e,r,i){for(var n=e._desiredTiles,o=n.length,a=0;a<o;++a){var s=n.get(a);if(L(s))s.selected=!0,s._selectedFrame=r.frameNumber;else{var u=s._ancestorWithLoadedContent;if(s.hasRenderableContent&&s.contentAvailable&&(u=s),t(u))u.selected=!0,u._selectedFrame=r.frameNumber;else for(B.push(s);B.length>0;)for(var c=B.pop(),d=c.children,h=d.length,p=0;p<h;++p){var f=d[p];w(e,f,i),f.contentAvailable&&(f.selected=!0,f._finalResolution=!0,f._selectedFrame=r.frameNumber),f._depth-s._depth<2&&(f.contentAvailable&&f.refine!==l.ADD||B.push(f))}}}}function h(e,r,i){var n,o=U,a=V;for(o.push(r);o.length>0||a.length>0;){if(a.length>0){var s=a[a.length-1];if(s._stackLength===o.length){a.pop(),s===n&&(s._finalResolution=!0),p(e,s,i);continue}}var u=o.pop();if(t(u)&&C(u,i)){var c=u.selected&&u._selectedFrame===i.frameNumber&&u.hasRenderableContent,d=u.children,h=d.length;if(d.sort(f),c)if(u.refine===l.ADD)u._finalResolution=!0,p(e,u,i);else{if(u._selectionDepth=a.length,u._selectionDepth>0&&(e._hasMixedContent=!0),n=u,0===h){u._finalResolution=!0,p(e,u,i);continue}a.push(u),u._stackLength=o.length}for(var m=0;m<h;++m){var g=d[m];o.push(g)}}}}function p(t,r,n){if(r.contentAvailable&&(r._visibilityPlaneMask===e.MASK_INSIDE||r.contentVisibility(n)!==i.OUTSIDE)){t._selectedTiles.push(r);var o=r.content;o.featurePropertiesDirty?(o.featurePropertiesDirty=!1,r.lastStyleTime=0,t._selectedTilesToStyle.push(r)):r._lastSelectedFrameNumber===n.frameNumber-1&&0!==r.lastStyleTime||t._selectedTilesToStyle.push(r),r._lastSelectedFrameNumber=n.frameNumber}}function f(e,t){return 0===t._distanceToCamera&&0===e._distanceToCamera?t._centerZDepth-e._centerZDepth:t._distanceToCamera-e._distanceToCamera}function m(){this.tileset=void 0,this.frameState=void 0,this.outOfCore=void 0,this.stack=new n,this.leaves=new n,this.baseScreenSpaceError=void 0,this.internalDFS=new _}function g(e,r,i,n){if(L(r)&&e._desiredTiles.push(r),r.hasTilesetContent&&r.contentExpired)return!1;if(r._screenSpaceError<=i&&!r.hasTilesetContent)return b(r,n),!1;var o=b(r,n),a=r.refine===l.ADD,u=r.refine===l.REPLACE&&0!=(o&s.VISIBLE_IN_REQUEST_VOLUME);return a||u||r.hasTilesetContent||!t(r._ancestorWithContent)}function _(){this.tileset=void 0,this.frameState=void 0,this.outOfCore=void 0,this.baseScreenSpaceError=void 0,this.stack=new n,this.allLoaded=void 0}function v(e){this.tileset=void 0,this.frameState=void 0,this.outOfCore=void 0,this.queue1=new n,this.queue2=new n,this.internalDFS=new y(e.selectionHeuristic),this.maxChildrenLength=0,this.scratchQueue=new n}function y(e){this.selectionHeuristic=e,this.tileset=void 0,this.frameState=void 0,this.outOfCore=void 0,this.root=void 0,this.queue=void 0,this.stack=new n}function b(e,t){if(C(e,t))return e._childrenVisibility;var r=e.children;return I(r,e.computedTransform),D(r,t),x(e,t)}function C(e,t){return e._lastVisitedFrame===t.frameNumber}function S(e,r,i,n){++e._statistics.visited,r.selected=!1,r._finalResolution=!1,T(r,i),w(e,r,n),r.updateExpiration(),r._ancestorWithContent=void 0,r._ancestorWithLoadedContent=void 0;var o=r.parent;if(t(o)){var a=o.refine===l.REPLACE;r._ancestorWithContent=a&&o.hasRenderableContent?o:o._ancestorWithContent,r._ancestorWithLoadedContent=a&&o.hasRenderableContent&&o.contentAvailable?o:o._ancestorWithLoadedContent}}function w(e,r,i){if(i){var n=r.replacementNode;t(n)&&e._replacementList.splice(e._replacementSentinel,n)}}function T(e,t){e._screenSpaceErrorComputedFrame!==t.frameNumber&&(e._screenSpaceErrorComputedFrame=t.frameNumber,e._screenSpaceError=P(e._tileset,e.geometricError,e,t))}function E(e,r,i){return!t(r.parent)||r.parent.refine!==l.ADD||M(e,r,i)}function A(e,t,r,i){(t.contentUnloaded||t.contentExpired)&&t._requestedFrame!==r.frameNumber&&(i&&!E(e,t,r)||(t._requestedFrame=r.frameNumber,e._requestedTiles.push(t)))}function x(t,r){for(var i=s.NONE,n=t.children,o=n.length,a=t._visibilityPlaneMask,l=0;l<o;++l){var u=n[l],c=u.visibility(r,a);O(c)&&(i|=s.VISIBLE),u.insideViewerRequestVolume(r)?(i|=s.IN_REQUEST_VOLUME,O(c)&&(i|=s.VISIBLE_IN_REQUEST_VOLUME)):(O(c)&&(i|=s.VISIBLE_NOT_IN_REQUEST_VOLUME),c=e.MASK_OUTSIDE),u._visibilityPlaneMask=c}return t._childrenVisibility=i,i}function P(e,r,i,n){if(0===r)return 0;var s,l=n.camera,c=l.frustum,d=n.context,h=d.drawingBufferHeight;if(n.mode===u.SCENE2D||c instanceof a){t(c._offCenterFrustum)&&(c=c._offCenterFrustum);var p=d.drawingBufferWidth;s=r/(Math.max(c.top-c.bottom,c.right-c.left)/Math.max(p,h))}else{var f=Math.max(i._distanceToCamera,o.EPSILON7);if(s=r*h/(f*l.frustum.sseDenominator),e.dynamicScreenSpaceError){var m=e._dynamicScreenSpaceErrorComputedDensity,g=e.dynamicScreenSpaceErrorFactor;s-=o.fog(f,m)*g}}return s}function D(e,t){for(var r=e.length,i=0;i<r;++i){var n=e[i];n._distanceToCamera=n.distanceToTile(t),n._centerZDepth=n.distanceToTileCenter(t)}}function I(e,t){for(var r=e.length,i=0;i<r;++i){e[i].updateTransform(t)}}function O(t){return t!==e.MASK_OUTSIDE}function M(e,r,i){var n=e._maximumScreenSpaceError,o=r.parent;if(!t(o))return O(r._visibilityPlaneMask);var a=o.refine===l.ADD&&o._screenSpaceError>n;return O(r._visibilityPlaneMask)&&(!a||P(e,o.geometricError,r,i)>n)}function R(e){return e.refine===l.ADD||0===e.children.length||e._childrenVisibility&0!==s.VISIBLE}function L(e){return e.refine===l.ADD&&e.hasRenderableContent}function N(e,r){var i=r.stack;!t(e)||t(r.shouldVisit)&&!r.shouldVisit(e)||i.push(e);for(var n=0;i.length>0;){n=Math.max(n,i.length);var o=i.pop();r.visitStart(o);for(var a=r.getChildren(o),s=!t(a.get),l=a.length,u=0;u<l;++u){var c=s?a[u]:a.get(u);t(r.shouldVisit)&&!r.shouldVisit(c)||i.push(c)}0===l&&t(r.leafHandler)&&r.leafHandler(o),r.visitEnd(o)}i.trim(n)}function k(e,r){var i=r.queue1,n=r.queue2;!t(e)||t(r.shouldVisit)&&!r.shouldVisit(e)||i.push(e);for(var o=0;i.length>0;){var a=i.length;o=Math.max(o,a);for(var s=0;s<a;++s){var l=i.get(s);r.visitStart(l);for(var u=r.getChildren(l),c=!t(u.get),d=u.length,h=0;h<d;++h){var p=c?u[h]:u.get(h);t(r.shouldVisit)&&!r.shouldVisit(p)||n.push(p)}0===d&&t(r.leafHandler)&&r.leafHandler(l),r.visitEnd(l)}i.length=0;var f=i;i=n,n=f,r.queue1=i,r.queue2=n}i.length=0,n.length=0,i.trim(o),n.trim(o)}var F={},B=[],U=[],V=[],z=r([]);return m.prototype.execute=function(e,t,r,i,n){this.tileset=e,this.frameState=i,this.outOfCore=n,this.leaves.length=0,this.baseScreenSpaceError=Math.max(r,this.tileset._maximumScreenSpaceError),this.internalDFS.tileset=this.tileset,this.internalDFS.frameState=this.frameState,this.internalDFS.outOfCore=this.outOfCore,this.internalDFS.baseScreenSpaceError=this.baseScreenSpaceError,N(t,this)},m.prototype.visitStart=function(e){C(e,this.frameState)||S(this.tileset,e,this.frameState,this.outOfCore)},m.prototype.visitEnd=function(e){e._lastVisitedFrame=this.frameState.frameNumber},m.prototype.getChildren=function(e){var t=this.tileset,r=this.outOfCore,i=this.frameState;if(!g(t,e,this.baseScreenSpaceError,i))return z;for(var n=e.children,o=n.length,a=!0,s=e.refine===l.REPLACE&&e.hasRenderableContent,u=0;u<o;++u){var c=n[u];A(t,c,i,!0),w(t,c,r),s&&(a=c.hasEmptyContent?a&&this.internalDFS.execute(c):a&&c.contentAvailable)}return a?n:z},m.prototype.shouldVisit=function(e){return O(e._visibilityPlaneMask)},m.prototype.leafHandler=function(e){if(this.tileset._skipLevelOfDetail||!L(e)){if(e.refine===l.REPLACE&&!R(e))return void++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion;this.leaves.push(e)}},_.prototype.execute=function(e){return this.allLoaded=!0,N(e,this),this.allLoaded},_.prototype.visitStart=function(e){C(e,this.frameState)||S(this.tileset,e,this.frameState,this.outOfCore)},_.prototype.visitEnd=m.prototype.visitEnd,_.prototype.shouldVisit=function(e){return!e.hasRenderableContent&&O(e._visibilityPlaneMask)},_.prototype.getChildren=function(e){var t=this.tileset,r=this.frameState,i=this.outOfCore;if(!g(t,e,this.baseScreenSpaceError,r))return z;for(var n=e.children,o=n.length,a=0;a<o;++a){var s=n[a];A(t,s,r,!0),w(t,s,i),e.contentAvailable||(this.allLoaded=!1)}return n},_.prototype.updateAndCheckChildren=m.prototype.updateAndCheckChildren,v.prototype.execute=function(e,t,r,i){this.tileset=e,this.frameState=r,this.outOfCore=i,this.internalDFS.frameState=r,this.internalDFS.outOfCore=i,this.maxChildrenLength=0,k(t,this),this.queue1.length=0,this.queue2.length=0,this.scratchQueue.length=0,this.scratchQueue.trim(this.maxChildrenLength)},v.prototype.visitStart=function(e){C(e,this.frameState)||S(this.tileset,e,this.frameState,this.outOfCore)},v.prototype.visitEnd=m.prototype.visitEnd,v.prototype.getChildren=function(e){return this.scratchQueue.length=0,this.internalDFS.execute(e,this.scratchQueue),this.maxChildrenLength=Math.max(this.maxChildrenLength,this.scratchQueue.length),this.scratchQueue},v.prototype.leafHandler=function(e){L(e)||C(e,this.frameState)||this.tileset._desiredTiles.push(e)},y.prototype.execute=function(e,t){this.tileset=e._tileset,this.root=e,this.queue=t,N(e,this)},y.prototype.visitStart=function(e){C(e,this.frameState)||S(this.tileset,e,this.frameState,this.outOfCore)},y.prototype.visitEnd=m.prototype.visitEnd,y.prototype.getChildren=function(e){var r=this.tileset,i=r._maximumScreenSpaceError;if(e.hasTilesetContent&&e.contentExpired)return z;if(!e.hasTilesetContent){if(e.refine===l.ADD&&(A(r,e,this.frameState,!0),L(e)&&r._desiredTiles.push(e)),e._screenSpaceError<=i)return b(e,this.frameState),z;if(!e.hasEmptyContent&&e.contentUnloaded&&t(e._ancestorWithLoadedContent)&&this.selectionHeuristic(r,e._ancestorWithLoadedContent,e))return b(e,this.frameState),z}var n=b(e,this.frameState),o=e.refine===l.ADD&&e._screenSpaceError>i,a=e.refine===l.REPLACE&&0!=(n&s.VISIBLE_IN_REQUEST_VOLUME);if(n&s.VISIBLE_NOT_IN_REQUEST_VOLUME&&e.refine===l.REPLACE&&this.tileset._desiredTiles.push(e),o||a||e.hasTilesetContent){for(var u=e.children,c=u.length,d=0;d<c;++d)w(r,u[d],this.outOfCore);return u}return z},y.prototype.shouldVisit=function(e){return M(this.tileset,e,this.frameState)},y.prototype.leafHandler=function(e){if(e!==this.root){if(e.refine===l.REPLACE&&!R(e))return void++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion;if(!e.hasEmptyContent)if(this.tileset.loadSiblings)for(var t=e.parent,r=t.children,i=r.length,n=0;n<i;++n)A(this.tileset,r[n],this.frameState,!1),w(this.tileset,r[n],this.outOfCore);else A(this.tileset,e,this.frameState,!0),w(this.tileset,e,this.outOfCore);this.queue.push(e)}else L(e)||this.tileset._desiredTiles.push(e)},F.selectTiles=c,F.BaseTraversal=m,F.SkipTraversal=v,F}),define("Scene/Cesium3DTileStyleEngine",["../Core/defined","../Core/defineProperties"],function(e,t){"use strict";function r(){this._style=void 0,this._styleDirty=!1,this._lastStyleTime=0}return t(r.prototype,{style:{get:function(){return this._style},set:function(e){this._style=e,this._styleDirty=!0}}}),r.prototype.makeDirty=function(){this._styleDirty=!0},r.prototype.applyStyle=function(t,r){if(t.ready&&(!e(this._style)||this._style.ready)){var i=this._styleDirty;r.passes.render&&(this._styleDirty=!1),i&&++this._lastStyleTime;for(var n=this._lastStyleTime,o=t._statistics,a=i?t._selectedTiles:t._selectedTilesToStyle,s=a.length,l=0;l<s;++l){var u=a[l];if(u.selected&&u.lastStyleTime!==n){var c=u.content;u.lastStyleTime=n,c.applyStyle(r,this._style),o.numberOfFeaturesStyled+=c.featuresLength,++o.numberOfTilesStyled}}}},r}),define("Shaders/PostProcessFilters/PointCloudEyeDomeLighting",[],function(){"use strict";return"#extension GL_EXT_frag_depth : enable\nuniform sampler2D u_pointCloud_colorTexture;\nuniform sampler2D u_pointCloud_ecAndLogDepthTexture;\nuniform vec3 u_distancesAndEdlStrength;\nvarying vec2 v_textureCoordinates;\nvec2 neighborContribution(float log2Depth, vec2 padding)\n{\nvec2 depthAndLog2Depth = texture2D(u_pointCloud_ecAndLogDepthTexture, v_textureCoordinates + padding).zw;\nif (depthAndLog2Depth.x == 0.0)\n{\nreturn vec2(0.0);\n}\nelse\n{\nreturn vec2(max(0.0, log2Depth - depthAndLog2Depth.y), 1.0);\n}\n}\nvoid main()\n{\nvec4 ecAlphaDepth = texture2D(u_pointCloud_ecAndLogDepthTexture, v_textureCoordinates);\nif (length(ecAlphaDepth.xyz) < czm_epsilon7)\n{\ndiscard;\n}\nelse\n{\nvec4 color = texture2D(u_pointCloud_colorTexture, v_textureCoordinates);\nfloat distX = u_distancesAndEdlStrength.x;\nfloat distY = u_distancesAndEdlStrength.y;\nvec2 responseAndCount = vec2(0.0);\nresponseAndCount += neighborContribution(ecAlphaDepth.a, vec2(0, distY));\nresponseAndCount += neighborContribution(ecAlphaDepth.a, vec2(distX, 0));\nresponseAndCount += neighborContribution(ecAlphaDepth.a, vec2(0, -distY));\nresponseAndCount += neighborContribution(ecAlphaDepth.a, vec2(-distX, 0));\nfloat response = responseAndCount.x / responseAndCount.y;\nfloat shade = exp(-response * 300.0 * u_distancesAndEdlStrength.z);\ncolor.rgb *= shade;\ngl_FragColor = vec4(color);\ngl_FragDepthEXT = czm_eyeToWindowCoordinates(vec4(ecAlphaDepth.xyz, 1.0)).z;\n}\n}\n"}),define("Scene/PointCloudEyeDomeLighting",["../Core/Cartesian3","../Core/clone","../Core/Color","../Core/combine","../Core/ComponentDatatype","../Core/defined","../Core/destroyObject","../Core/FeatureDetection","../Core/Geometry","../Core/GeometryAttribute","../Core/PixelFormat","../Core/PrimitiveType","../Renderer/BufferUsage","../Renderer/ClearCommand","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/Pass","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Sampler","../Renderer/ShaderSource","../Renderer/ShaderProgram","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Renderer/VertexArray","../Scene/BlendEquation","../Scene/BlendFunction","../Scene/BlendingState","../Scene/StencilFunction","../Scene/StencilOperation","../Shaders/PostProcessFilters/PointCloudEyeDomeLighting"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M){"use strict";function R(){this._framebuffer=void 0,this._colorTexture=void 0,this._ecAndLogDepthTexture=void 0,this._depthTexture=void 0,this._drawCommand=void 0,this._clearCommand=void 0,this._strength=1,this._radius=1}function L(){return new y({wrapS:E.CLAMP_TO_EDGE,wrapT:E.CLAMP_TO_EDGE,minificationFilter:T.NEAREST,magnificationFilter:w.NEAREST})}function N(e){var t=e._framebuffer;o(t)&&(e._colorTexture.destroy(),e._ecAndLogDepthTexture.destroy(),e._depthTexture.destroy(),t.destroy(),e._framebuffer=void 0,e._colorTexture=void 0,e._ecAndLogDepthTexture=void 0,e._depthTexture=void 0,e._drawCommand=void 0,e._clearCommand=void 0)}function k(e,t){var r=t.drawingBufferWidth,i=t.drawingBufferHeight,n=new S({context:t,width:r,height:i,pixelFormat:c.RGBA,pixelDatatype:s.isFirefox()?_.FLOAT:_.UNSIGNED_BYTE,sampler:L()}),o=new S({context:t,width:r,height:i,pixelFormat:c.RGBA,pixelDatatype:_.FLOAT,sampler:L()}),a=new S({context:t,width:r,height:i,pixelFormat:c.DEPTH_COMPONENT,pixelDatatype:_.UNSIGNED_INT,sampler:L()});e._framebuffer=new m({context:t,colorTextures:[n,o],depthTexture:a,destroyAttachments:!1}),e._colorTexture=n,e._ecAndLogDepthTexture=o,e._depthTexture=a}function F(e,t){var i=M,n={u_pointCloud_colorTexture:function(){return e._colorTexture},u_pointCloud_ecAndLogDepthTexture:function(){return e._ecAndLogDepthTexture},u_distancesAndEdlStrength:function(){return z.x=e._radius/t.drawingBufferWidth,z.y=e._radius/t.drawingBufferHeight,z.z=e._strength,z}},o=v.fromCache({blending:D.ALPHA_BLEND,depthMask:!0,depthTest:{enabled:!0}});e._drawCommand=t.createViewportQuadCommand(i,{uniformMap:n,renderState:o,pass:g.CESIUM_3D_TILE,owner:e}),e._clearCommand=new p({framebuffer:e._framebuffer,color:new r(0,0,0,0),depth:1,renderState:v.fromCache(),pass:g.CESIUM_3D_TILE,owner:e})}function B(e,t){var r=t.drawingBufferWidth,i=t.drawingBufferHeight,n=e._colorTexture,a=!1,s=o(n)&&(n.width!==r||n.height!==i);return o(n)&&!s||(N(e),k(e,t),F(e,t),a=!0),a}function U(e){return e.floatingPointTexture&&e.drawBuffers&&e.fragmentDepth}function V(e,t){var r=e.shaderCache.getDerivedShaderProgram(t,"EC");if(!o(r)){var i=t._attributeLocations,n=t.vertexShaderSource.clone(),a=t.fragmentShaderSource.clone();n.sources=n.sources.map(function(e){return e=b.replaceMain(e,"czm_point_cloud_post_process_main")}),a.sources=a.sources.map(function(e){return e=b.replaceMain(e,"czm_point_cloud_post_process_main"),e=e.replace(/gl_FragColor/g,"gl_FragData[0]")}),n.sources.push("varying vec3 v_positionEC; \nvoid main() \n{ \n czm_point_cloud_post_process_main(); \n v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n}"),a.sources.unshift("#extension GL_EXT_draw_buffers : enable \n"),a.sources.push("varying vec3 v_positionEC; \nvoid main() \n{ \n czm_point_cloud_post_process_main(); \n gl_FragData[1] = vec4(v_positionEC, log2(-v_positionEC.z)); \n}"),r=e.shaderCache.createDerivedShaderProgram(t,"EC",{vertexShaderSource:n,fragmentShaderSource:a,attributeLocations:i})}return r}var z=new e;return R.isSupported=U,R.prototype.update=function(e,t,r){var i=e.passes,n=i.pick&&!i.render;if(U(e.context)&&!n){this._strength=r.pointCloudShading.eyeDomeLightingStrength,this._radius=r.pointCloudShading.eyeDomeLightingRadius;var a,s=B(this,e.context),l=e.commandList,u=l.length;for(a=t;a<u;++a){var c=l[a];if(c.primitiveType===d.POINTS&&c.pass!==g.TRANSLUCENT){var h=c.derivedCommands.pointCloudProcessor;(!o(h)||c.dirty||s||h.framebuffer!==this._framebuffer)&&(h=f.shallowClone(c),c.derivedCommands.pointCloudProcessor=h,h.framebuffer=this._framebuffer,h.shaderProgram=V(e.context,c.shaderProgram),h.castShadows=!1,h.receiveShadows=!1),l[a]=h}}var p=this._clearCommand,m=this._drawCommand;l.push(m),l.push(p)}},R.prototype.isDestroyed=function(){return!1},R.prototype.destroy=function(){return N(this),a(this)},R}),define("Scene/PointCloudShading",["../Core/defaultValue","./PointCloudEyeDomeLighting"],function(e,t){"use strict";function r(t){var r=e(t,{});this.attenuation=e(r.attenuation,!1),this.geometricErrorScale=e(r.geometricErrorScale,1),this.maximumAttenuation=r.maximumAttenuation,this.baseResolution=r.baseResolution,this.eyeDomeLighting=e(r.eyeDomeLighting,!0),this.eyeDomeLightingStrength=e(r.eyeDomeLightingStrength,1),this.eyeDomeLightingRadius=e(r.eyeDomeLightingRadius,1)}return r.isSupported=function(e){return t.isSupported(e.context)},r}),define("Scene/Cesium3DTileset",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/destroyObject","../Core/DeveloperError","../Core/DoublyLinkedList","../Core/Ellipsoid","../Core/Event","../Core/getBaseUri","../Core/getExtensionFromUri","../Core/getMagic","../Core/isDataUri","../Core/JulianDate","../Core/ManagedArray","../Core/Math","../Core/Matrix4","../Core/Resource","../Core/RuntimeError","../Renderer/ClearCommand","../Renderer/Pass","../ThirdParty/when","./Axis","./Cesium3DTile","./Cesium3DTileColorBlendMode","./Cesium3DTileOptimizations","./Cesium3DTilesetStatistics","./Cesium3DTilesetTraversal","./Cesium3DTileStyleEngine","./ClassificationType","./LabelCollection","./PointCloudShading","./PointCloudEyeDomeLighting","./SceneMode","./ShadowMode","./TileBoundingRegion","./TileBoundingSphere","./TileOrientedBoundingBox"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z){"use strict";function G(e){e=n(e,n.EMPTY_OBJECT);var t,r=C.createIfNeeded(e.url),i=r;"json"===r.extension?t=r.getBaseUri(!0):r.isDataUri?t="":(r.appendForwardSlash(),i=r.getDerivedResource({url:"tileset.json"}),t=r.url),this._url=r.url,this._tilesetUrl=i.url,this._basePath=t,this._root=void 0,this._asset=void 0,this._properties=void 0,this._geometricError=void 0,this._gltfUpAxis=void 0,this._processingQueue=[],this._selectedTiles=[],this._requestedTiles=[],this._desiredTiles=new v,this._selectedTilesToStyle=[],this._loadTimestamp=void 0,this._timeSinceLoad=0;var a=new c;this._replacementList=a,this._replacementSentinel=a.add(),this._trimTiles=!1,this._cullWithChildrenBounds=n(e.cullWithChildrenBounds,!0),this._hasMixedContent=!1,this._baseTraversal=new O.BaseTraversal,this._skipTraversal=new O.SkipTraversal({selectionHeuristic:q}),this._backfaceCommands=new v,this._maximumScreenSpaceError=n(e.maximumScreenSpaceError,16),this._maximumMemoryUsage=n(e.maximumMemoryUsage,512),this._styleEngine=new M,this._modelMatrix=o(e.modelMatrix)?b.clone(e.modelMatrix):b.clone(b.IDENTITY),this._statistics=new I,this._statisticsLastColor=new I,this._statisticsLastPick=new I,this._tilesLoaded=!1,this._tileDebugLabels=void 0,this._readyPromise=E.defer(),this._classificationType=e.classificationType,this._ellipsoid=n(e.ellipsoid,d.WGS84),this.dynamicScreenSpaceError=n(e.dynamicScreenSpaceError,!1),this.dynamicScreenSpaceErrorDensity=.00278,this.dynamicScreenSpaceErrorFactor=4,this.dynamicScreenSpaceErrorHeightFalloff=.25,this._dynamicScreenSpaceErrorComputedDensity=0,this.shadows=n(e.shadows,B.ENABLED),this.show=n(e.show,!0),this.colorBlendMode=P.HIGHLIGHT,this.colorBlendAmount=.5,this.pointCloudShading=new N(e.pointCloudShading),this._pointCloudEyeDomeLighting=new k,this.loadProgress=new h,this.allTilesLoaded=new h,this.tileLoad=new h,this.tileUnload=new h,this.tileFailed=new h,this.tileVisible=new h,this.skipLevelOfDetail=n(e.skipLevelOfDetail,!0),this._skipLevelOfDetail=this.skipLevelOfDetail,this._disableSkipLevelOfDetail=!1,this.baseScreenSpaceError=n(e.baseScreenSpaceError,1024),this.skipScreenSpaceErrorFactor=n(e.skipScreenSpaceErrorFactor,16),this.skipLevels=n(e.skipLevels,1),this.immediatelyLoadDesiredLevelOfDetail=n(e.immediatelyLoadDesiredLevelOfDetail,!1),this.loadSiblings=n(e.loadSiblings,!1),this.clippingPlanes=e.clippingPlanes,this.debugFreezeFrame=n(e.debugFreezeFrame,!1),this.debugColorizeTiles=n(e.debugColorizeTiles,!1),this.debugWireframe=n(e.debugWireframe,!1),this.debugShowBoundingVolume=n(e.debugShowBoundingVolume,!1),this.debugShowContentBoundingVolume=n(e.debugShowContentBoundingVolume,!1),this.debugShowViewerRequestVolume=n(e.debugShowViewerRequestVolume,!1),this._tileDebugLabels=void 0,this.debugPickedTileLabelOnly=!1,this.debugPickedTile=void 0,this.debugPickPosition=void 0,this.debugShowGeometricError=n(e.debugShowGeometricError,!1),this.debugShowRenderingStatistics=n(e.debugShowRenderingStatistics,!1),this.debugShowMemoryUsage=n(e.debugShowMemoryUsage,!1),this.debugShowUrl=n(e.debugShowUrl,!1),this._brokenUrlWorkaround=!1;var l=this;G.loadJson(i).then(function(e){return W(l,i,e)}).then(function(e){l._brokenUrlWorkaround&&s("Cesium3DTileset.leadingSlash","Having a leading slash in a tile URL that is actually relative to the tileset.json is deprecated."),l._root=l.loadTileset(i,e);var t=o(e.asset.gltfUpAxis)?A.fromName(e.asset.gltfUpAxis):A.Y;l._asset=e.asset,l._properties=e.properties,l._geometricError=e.geometricError,l._gltfUpAxis=t,l._readyPromise.resolve(l)}).otherwise(function(e){l._readyPromise.reject(e)})}function W(e,t,r){var i=H(r.root);return o(i)&&0!==i.length?t.getDerivedResource({url:i}).fetchArrayBuffer().then(function(t){var i=new Uint8Array(t),n=m(i);return e._brokenUrlWorkaround="b3dm"!==n,r}).otherwise(function(){return e._brokenUrlWorkaround=!0,r}):r}function H(e){var t=e.content;if(o(t)&&o(t.url))return se.test(t.url)?t.url:"";var r=e.children;if(o(r))for(var i=r.length,n=0;n<i;++n){var a=H(r[n]);if(o(a))return a}}function j(e,i){var n,o,a,s,l,u=i.camera,c=e._root,d=c.contentBoundingVolume;if(d instanceof U)n=t.normalize(u.positionWC,le),o=u.directionWC,a=u.positionCartographic.height,s=d.minimumHeight,l=d.maximumHeight;else{var h=b.inverseTransformation(c.computedTransform,ce),p=i.mapProjection.ellipsoid,f=d.boundingVolume,m=b.multiplyByPoint(h,f.center,de);if(t.magnitude(m)>p.minimumRadius){var g=r.fromCartesian(m,p,ue);n=t.normalize(u.positionWC,le),o=u.directionWC,a=u.positionCartographic.height,s=0,l=2*g.height}else{var _=b.multiplyByPoint(h,u.positionWC,he);if(n=t.UNIT_Z,o=b.multiplyByPointAsVector(h,u.directionWC,pe),o=t.normalize(o,o),a=_.z,d instanceof z){var v=c._header.boundingVolume.box[11];s=m.z-v,l=m.z+v}else if(d instanceof V){var C=f.radius;s=m.z-C,l=m.z+C}}}var S=e.dynamicScreenSpaceErrorHeightFalloff,w=s+(l-s)*S,T=l,E=y.clamp((a-w)/(T-w),0,1),A=Math.abs(t.dot(o,n)),x=1-A;x*=1-E;var P=e.dynamicScreenSpaceErrorDensity;P*=x,e._dynamicScreenSpaceErrorComputedDensity=P}function q(e,t,r){var i=e._skipLevelOfDetail?e.skipLevels:0,n=e._skipLevelOfDetail?e.skipScreenSpaceErrorFactor:1;return t!==r&&!r.hasEmptyContent&&!e.immediatelyLoadDesiredLevelOfDetail&&r._screenSpaceError<t._screenSpaceError/n&&r._depth>t._depth+i}function Y(e,t){if(!t.hasEmptyContent){var r=e._statistics,i=t.contentExpired;if(!t.requestContent())return void++r.numberOfAttemptedRequests;i&&(t.hasRenderableContent?(r.decrementLoadCounts(t.content),--e._statistics.numberOfTilesWithContentReady):t.hasTilesetContent&&ie(e,t)),++r.numberOfPendingRequests;var n=Z(e,t);t.contentReadyToProcessPromise.then(Q(e,t)),t.contentReadyPromise.then(function(){n(),e.tileLoad.raiseEvent(t)}).otherwise(function(r){n();var i=t._contentResource.url,a=o(r.message)?r.message:r.toString();e.tileFailed.numberOfListeners>0?e.tileFailed.raiseEvent({url:i,message:a}):(console.log("A 3D tile failed to load: "+i),console.log("Error: "+a))})}}function X(e,t){if(t)for(var r=e._requestedTiles,i=r.length,n=0;n<i;++n)Y(e,r[n])}function Q(e,t){return function(){e._processingQueue.push(t),--e._statistics.numberOfPendingRequests,++e._statistics.numberOfTilesProcessing}}function Z(e,t){return function(){var r=e._processingQueue.indexOf(t);if(-1===r)return void--e._statistics.numberOfPendingRequests;e._processingQueue.splice(r,1),--e._statistics.numberOfTilesProcessing,t.hasRenderableContent&&(e._statistics.incrementLoadCounts(t.content),++e._statistics.numberOfTilesWithContentReady,o(t.replacementNode)||(t.replacementNode=e._replacementList.add(t)))}}function K(e,t){for(var r=e._processingQueue,i=r.length,n=i-1;n>=0;--n)r[n].process(e,t)}function J(e){var t=e/1048576;return t<1?t.toLocaleString(void 0,me):Math.round(t).toLocaleString()}function $(e){var r=e._boundingVolume.boundingVolume,i=r.halfAxes,n=r.radius,a=t.clone(r.center,fe);if(o(i))a.x+=.75*(i[0]+i[3]+i[6]),a.y+=.75*(i[1]+i[4]+i[7]),a.z+=.75*(i[2]+i[5]+i[8]);else if(o(n)){var s=t.normalize(r.center,fe);s=t.multiplyByScalar(s,.75*n,fe),a=t.add(s,r.center,fe)}return a}function ee(e,t,r){var i="",n=0;if(t.debugShowGeometricError&&(i+="\nGeometric error: "+e.geometricError,n++),t.debugShowRenderingStatistics){i+="\nCommands: "+e.commandsLength,n++;e.content.pointsLength>0&&(i+="\nPoints: "+e.content.pointsLength,n++);e.content.trianglesLength>0&&(i+="\nTriangles: "+e.content.trianglesLength,n++),i+="\nFeatures: "+e.content.featuresLength,n++}t.debugShowMemoryUsage&&(i+="\nTexture Memory: "+J(e.content.texturesByteLength),i+="\nGeometry Memory: "+J(e.content.geometryByteLength),n+=2),t.debugShowUrl&&(i+="\nUrl: "+e._header.content.url,n++);var o={text:i.substring(1),position:r,font:19-n+"px sans-serif",showBackground:!0,disableDepthTestDistance:Number.POSITIVE_INFINITY};return t._tileDebugLabels.add(o)}function te(t,r){var i=t._selectedTiles,n=i.length;if(t._tileDebugLabels.removeAll(),t.debugPickedTileLabelOnly){if(o(t.debugPickedTile)){var a=o(t.debugPickPosition)?t.debugPickPosition:$(t.debugPickedTile),s=ee(t.debugPickedTile,t,a);s.pixelOffset=new e(15,-15)}}else for(var l=0;l<n;++l){var u=i[l];ee(u,t,$(u))}t._tileDebugLabels.update(r)}function re(e,t){e._styleEngine.applyStyle(e,t);var r,i=e._statistics,n=t.commandList,a=n.length,s=e._selectedTiles,l=s.length,u=e.tileVisible,c=e._skipLevelOfDetail&&e._hasMixedContent&&t.context.stencilBuffer&&l>0;e._backfaceCommands.length=0,c&&n.push(ge);var d=n.length;for(r=0;r<l;++r){var h=s[r];h.selected&&(u.raiseEvent(h),h.update(e,t),i.incrementSelectionCounts(h.content),++i.selected)}var p=n.length,f=p-d;if(e._backfaceCommands.trim(),c){var m=e._backfaceCommands.values,g=m.length;for(n.length+=g,r=f-1;r>=0;--r)n[d+g+r]=n[d+r];for(r=0;r<g;++r)n[d+r]=m[r]}i.numberOfCommands=n.length-a,e.pointCloudShading.attenuation&&e.pointCloudShading.eyeDomeLighting&&f>0&&e._pointCloudEyeDomeLighting.update(t,a,e),e.debugShowGeometricError||e.debugShowRenderingStatistics||e.debugShowMemoryUsage||e.debugShowUrl?(o(e._tileDebugLabels)||(e._tileDebugLabels=new L),te(e,t)):e._tileDebugLabels=e._tileDebugLabels&&e._tileDebugLabels.destroy()}function ie(e,t){var r=t,i=e._statistics,n=_e;for(n.push(t);n.length>0;){t=n.pop();for(var o=t.children,a=o.length,s=0;s<a;++s)n.push(o[s]);t!==r&&(ne(e,t),t.destroy(),--i.numberOfTilesTotal)}r.children=[]}function ne(e,t){var r=t.replacementNode;if(o(r)){var i=e._statistics,n=e._replacementList;e.tileUnload.raiseEvent(t),n.remove(r),i.decrementLoadCounts(t.content),--i.numberOfTilesWithContentReady}}function oe(e){var t=e._trimTiles;e._trimTiles=!1;for(var r=e._replacementList,i=e.totalMemoryUsageInBytes,n=1024*e._maximumMemoryUsage*1024,o=e._replacementSentinel,a=r.head;a!==o&&(i>n||t);){var s=a.item;a=a.next,ne(e,s),s.unloadContent(),i=e.totalMemoryUsageInBytes}}function ae(e,t){var r=e._statistics,i=e._statisticsLastColor,n=r.numberOfPendingRequests,o=r.numberOfTilesProcessing,a=i.numberOfPendingRequests,s=i.numberOfTilesProcessing,l=n!==a||o!==s;l&&t.afterRender.push(function(){e.loadProgress.raiseEvent(n,o)}),e._tilesLoaded=0===r.numberOfPendingRequests&&0===r.numberOfTilesProcessing&&0===r.numberOfAttemptedRequests,l&&e._tilesLoaded&&t.afterRender.push(function(){e.allTilesLoaded.raiseEvent()})}var se=/^\/.+\.b3dm$/;a(G.prototype,{asset:{get:function(){return this._asset}},properties:{get:function(){ +return this._properties}},ready:{get:function(){return o(this._root)}},readyPromise:{get:function(){return this._readyPromise.promise}},tilesLoaded:{get:function(){return this._tilesLoaded}},url:{get:function(){return this._url}},basePath:{get:function(){return s("Cesium3DTileset.basePath","Cesium3DTileset.basePath has been deprecated. All tiles are relative to the url of the tileset.json that contains them. Use the url property instead."),this._basePath}},style:{get:function(){return this._styleEngine.style},set:function(e){this._styleEngine.style=e}},maximumScreenSpaceError:{get:function(){return this._maximumScreenSpaceError},set:function(e){this._maximumScreenSpaceError=e}},maximumMemoryUsage:{get:function(){return this._maximumMemoryUsage},set:function(e){this._maximumMemoryUsage=e}},boundingSphere:{get:function(){return this._root.boundingSphere}},modelMatrix:{get:function(){return this._modelMatrix},set:function(e){this._modelMatrix=b.clone(e,this._modelMatrix),o(this._root)&&this._root.updateTransform(this._modelMatrix)}},timeSinceLoad:{get:function(){return this._timeSinceLoad}},totalMemoryUsageInBytes:{get:function(){var e=this._statistics;return e.texturesByteLength+e.geometryByteLength+e.batchTableByteLength}},styleEngine:{get:function(){return this._styleEngine}},statistics:{get:function(){return this._statistics}},classificationType:{get:function(){return this._classificationType}},ellipsoid:{get:function(){return this._ellipsoid}}}),G.loadJson=function(e){return C.createIfNeeded(e).fetchJson()},G.prototype.makeStyleDirty=function(){this._styleEngine.makeDirty()},G.prototype.loadTileset=function(e,t,r){var i=t.asset;if(!o(i))throw new S("Tileset must have an asset property.");if("0.0"!==i.version&&"1.0"!==i.version)throw new S("The tileset must be 3D Tiles version 0.0 or 1.0. See https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status");var a=this._statistics;if(!o(e.queryParameters.v)){var s={v:n(i.tilesetVersion,"0.0")};this._basePath+="?v="+s.v,e.addQueryParameters(s)}var l=new x(this,e,t.root,r);o(r)&&(r.children.push(l),l._depth=r._depth+1),++a.numberOfTilesTotal;var u=[];for(u.push({header:t.root,tile3D:l});u.length>0;){var c=u.pop(),d=c.tile3D,h=c.header.children;if(o(h))for(var p=h.length,f=0;f<p;++f){var m=h[f],g=new x(this,e,m,d);d.children.push(g),g._depth=d._depth+1,++a.numberOfTilesTotal,u.push({header:m,tile3D:g})}this._cullWithChildrenBounds&&D.checkChildrenWithinParent(d)}return l};var le=new t,ue=new r,ce=new b,de=new t,he=new t,pe=new t,fe=new t,me={maximumFractionDigits:3},ge=new w({stencil:0,pass:T.CESIUM_3D_TILE}),_e=[];return G.prototype.trimLoadedTiles=function(){this._trimTiles=!0},G.prototype.update=function(e){if(e.mode!==F.MORPHING&&this.show&&this.ready){o(this._loadTimestamp)||(this._loadTimestamp=_.clone(e.time)),this._timeSinceLoad=Math.max(1e3*_.secondsDifference(e.time,this._loadTimestamp),0),this._skipLevelOfDetail=this.skipLevelOfDetail&&!o(this._classificationType)&&!this._disableSkipLevelOfDetail;var t=e.passes,r=t.pick&&!t.render,i=!r,n=this._statistics;n.clear(),i&&K(this,e),this.dynamicScreenSpaceError&&j(this,e),O.selectTiles(this,e,i),X(this,i),re(this,e),i&&oe(this),ae(this,e);var a=r?this._statisticsLastPick:this._statisticsLastColor;I.clone(n,a)}},G.prototype.isDestroyed=function(){return!1},G.prototype.destroy=function(){if(this._tileDebugLabels=this._tileDebugLabels&&this._tileDebugLabels.destroy(),o(this._root)){var e=_e;for(e.push(this._root);e.length>0;){var t=e.pop();t.destroy();for(var r=t.children,i=r.length,n=0;n<i;++n)e.push(r[n])}}return this._root=void 0,l(this)},G}),define("Scene/ConditionsExpression",["../Core/clone","../Core/defined","../Core/defineProperties","./Expression"],function(e,t,r,i){"use strict";function n(t,r){this._conditionsExpression=e(t,!0),this._conditions=t.conditions,this._runtimeConditions=void 0,a(this,r)}function o(e,t){this.condition=e,this.expression=t}function a(e,r){var n=[],a=e._conditions;if(t(a)){for(var s=a.length,l=0;l<s;++l){var u=a[l],c=String(u[0]),d=String(u[1]);n.push(new o(new i(c,r),new i(d,r)))}e._runtimeConditions=n}}return r(n.prototype,{conditionsExpression:{get:function(){return this._conditionsExpression}}}),n.prototype.evaluate=function(e,r,i){var n=this._runtimeConditions;if(t(n))for(var o=n.length,a=0;a<o;++a){var s=n[a];if(s.condition.evaluate(e,r))return s.expression.evaluate(e,r,i)}},n.prototype.evaluateColor=function(e,r,i){var n=this._runtimeConditions;if(t(n))for(var o=n.length,a=0;a<o;++a){var s=n[a];if(s.condition.evaluate(e,r))return s.expression.evaluateColor(e,r,i)}},n.prototype.getShaderFunction=function(e,r,i,n){var o=this._runtimeConditions;if(t(o)&&0!==o.length){for(var a="",s=o.length,l=0;l<s;++l){var u=o[l],c=u.condition.getShaderExpression(r,i),d=u.expression.getShaderExpression(r,i);a+=" "+(0===l?"if":"else if")+" ("+c+") \n { \n return "+d+"; \n } \n"}return a=n+" "+e+"() \n{ \n"+a+" return "+n+"(1.0); \n} \n"}},n}),define("Scene/Cesium3DTileStyle",["../Core/clone","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Resource","../ThirdParty/when","./ConditionsExpression","./Expression"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(e){this._style=void 0,this._ready=!1,this._show=void 0,this._color=void 0,this._pointSize=void 0,this._pointOutlineColor=void 0,this._pointOutlineWidth=void 0,this._labelColor=void 0,this._labelOutlineColor=void 0,this._labelOutlineWidth=void 0,this._font=void 0,this._labelStyle=void 0,this._labelText=void 0,this._backgroundColor=void 0,this._backgroundPadding=void 0,this._backgroundEnabled=void 0,this._scaleByDistance=void 0,this._translucencyByDistance=void 0,this._distanceDisplayCondition=void 0,this._heightOffset=void 0,this._anchorLineEnabled=void 0,this._anchorLineColor=void 0,this._image=void 0,this._disableDepthTestDistance=void 0,this._horizontalOrigin=void 0,this._verticalOrigin=void 0,this._labelHorizontalOrigin=void 0,this._labelVerticalOrigin=void 0,this._meta=void 0,this._colorShaderFunction=void 0,this._showShaderFunction=void 0,this._pointSizeShaderFunction=void 0,this._colorShaderFunctionReady=!1,this._showShaderFunctionReady=!1,this._pointSizeShaderFunctionReady=!1,this._colorShaderTranslucent=!1;var t;if("string"==typeof e||e instanceof o){t=o.createIfNeeded(e).fetchJson(e)}else t=a.resolve(e);var r=this;this._readyPromise=t.then(function(e){return c(r,e),r})}function c(i,n){i._style=e(n,!0),n=t(n,t.EMPTY_OBJECT),i.show=n.show,i.color=n.color,i.pointSize=n.pointSize,i.pointOutlineColor=n.pointOutlineColor,i.pointOutlineWidth=n.pointOutlineWidth,i.labelColor=n.labelColor,i.labelOutlineColor=n.labelOutlineColor,i.labelOutlineWidth=n.labelOutlineWidth,i.labelStyle=n.labelStyle,i.font=n.font,i.labelText=n.labelText,i.backgroundColor=n.backgroundColor,i.backgroundPadding=n.backgroundPadding,i.backgroundEnabled=n.backgroundEnabled,i.scaleByDistance=n.scaleByDistance,i.translucencyByDistance=n.translucencyByDistance,i.distanceDisplayCondition=n.distanceDisplayCondition,i.heightOffset=n.heightOffset,i.anchorLineEnabled=n.anchorLineEnabled,i.anchorLineColor=n.anchorLineColor,i.image=n.image,i.disableDepthTestDistance=n.disableDepthTestDistance,i.horizontalOrigin=n.horizontalOrigin,i.verticalOrigin=n.verticalOrigin,i.labelHorizontalOrigin=n.labelHorizontalOrigin,i.labelVerticalOrigin=n.labelVerticalOrigin;var o={};if(r(n.meta)){var a=n.defines,s=t(n.meta,t.EMPTY_OBJECT);for(var u in s)s.hasOwnProperty(u)&&(o[u]=new l(s[u],a))}i._meta=o,i._ready=!0}function d(e,i){var n=t(e._style,t.EMPTY_OBJECT).defines;if(r(i))return"boolean"==typeof i||"number"==typeof i?new l(String(i)):"string"==typeof i?new l(i,n):r(i.conditions)?new s(i,n):i}return i(u.prototype,{style:{get:function(){return this._style}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise}},show:{get:function(){return this._show},set:function(e){this._show=d(this,e),this._showShaderFunctionReady=!1}},color:{get:function(){return this._color},set:function(e){this._color=d(this,e),this._colorShaderFunctionReady=!1}},pointSize:{get:function(){return this._pointSize},set:function(e){this._pointSize=d(this,e),this._pointSizeShaderFunctionReady=!1}},pointOutlineColor:{get:function(){return this._pointOutlineColor},set:function(e){this._pointOutlineColor=d(this,e)}},pointOutlineWidth:{get:function(){return this._pointOutlineWidth},set:function(e){this._pointOutlineWidth=d(this,e)}},labelColor:{get:function(){return this._labelColor},set:function(e){this._labelColor=d(this,e)}},labelOutlineColor:{get:function(){return this._labelOutlineColor},set:function(e){this._labelOutlineColor=d(this,e)}},labelOutlineWidth:{get:function(){return this._labelOutlineWidth},set:function(e){this._labelOutlineWidth=d(this,e)}},font:{get:function(){return this._font},set:function(e){this._font=d(this,e)}},labelStyle:{get:function(){return this._labelStyle},set:function(e){this._labelStyle=d(this,e)}},labelText:{get:function(){return this._labelText},set:function(e){this._labelText=d(this,e)}},backgroundColor:{get:function(){return this._backgroundColor},set:function(e){this._backgroundColor=d(this,e)}},backgroundPadding:{get:function(){return this._backgroundPadding},set:function(e){this._backgroundPadding=d(this,e)}},backgroundEnabled:{get:function(){return this._backgroundEnabled},set:function(e){this._backgroundEnabled=d(this,e)}},scaleByDistance:{get:function(){return this._scaleByDistance},set:function(e){this._scaleByDistance=d(this,e)}},translucencyByDistance:{get:function(){return this._translucencyByDistance},set:function(e){this._translucencyByDistance=d(this,e)}},distanceDisplayCondition:{get:function(){return this._distanceDisplayCondition},set:function(e){this._distanceDisplayCondition=d(this,e)}},heightOffset:{get:function(){return this._heightOffset},set:function(e){this._heightOffset=d(this,e)}},anchorLineEnabled:{get:function(){return this._anchorLineEnabled},set:function(e){this._anchorLineEnabled=d(this,e)}},anchorLineColor:{get:function(){return this._anchorLineColor},set:function(e){this._anchorLineColor=d(this,e)}},image:{get:function(){return this._image},set:function(e){this._image=d(this,e)}},disableDepthTestDistance:{get:function(){return this._disableDepthTestDistance},set:function(e){this._disableDepthTestDistance=d(this,e)}},horizontalOrigin:{get:function(){return this._horizontalOrigin},set:function(e){this._horizontalOrigin=d(this,e)}},verticalOrigin:{get:function(){return this._verticalOrigin},set:function(e){this._verticalOrigin=d(this,e)}},labelHorizontalOrigin:{get:function(){return this._labelHorizontalOrigin},set:function(e){this._labelHorizontalOrigin=d(this,e)}},labelVerticalOrigin:{get:function(){return this._labelVerticalOrigin},set:function(e){this._labelVerticalOrigin=d(this,e)}},meta:{get:function(){return this._meta},set:function(e){this._meta=e}}}),u.prototype.getColorShaderFunction=function(e,t,i){return this._colorShaderFunctionReady?(i.translucent=this._colorShaderTranslucent,this._colorShaderFunction):(this._colorShaderFunctionReady=!0,this._colorShaderFunction=r(this.color)?this.color.getShaderFunction(e,t,i,"vec4"):void 0,this._colorShaderTranslucent=i.translucent,this._colorShaderFunction)},u.prototype.getShowShaderFunction=function(e,t,i){return this._showShaderFunctionReady?this._showShaderFunction:(this._showShaderFunctionReady=!0,this._showShaderFunction=r(this.show)?this.show.getShaderFunction(e,t,i,"bool"):void 0,this._showShaderFunction)},u.prototype.getPointSizeShaderFunction=function(e,t,i){return this._pointSizeShaderFunctionReady?this._pointSizeShaderFunction:(this._pointSizeShaderFunctionReady=!0,this._pointSizeShaderFunction=r(this.pointSize)?this.pointSize.getShaderFunction(e,t,i,"float"):void 0,this._pointSizeShaderFunction)},u}),define("Scene/UrlTemplateImageryProvider",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/clone","../Core/combine","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/isArray","../Core/Math","../Core/Rectangle","../Core/Resource","../Core/WebMercatorTilingScheme","../ThirdParty/when","./ImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(e){this._errorEvent=new d,this._resource=void 0,this._urlSchemeZeroPadding=void 0,this._pickFeaturesResource=void 0,this._tileWidth=void 0,this._tileHeight=void 0,this._maximumLevel=void 0,this._minimumLevel=void 0,this._tilingScheme=void 0,this._rectangle=void 0,this._tileDiscardPolicy=void 0,this._credit=void 0,this._hasAlphaChannel=void 0,this._readyPromise=void 0,this._tags=void 0,this._pickFeaturesTags=void 0,this.enablePickFeatures=!0,this.reinitialize(e)}function C(e,t,r,i,n){ie=!1,oe=!1;var o=e._resource,a=o.getUrlComponent(!0),l=e._tags,u={},c=a.match(ee);return s(c)&&c.forEach(function(n){var o=n.substring(1,n.length-1);s(l[o])&&(u[o]=l[o](e,t,r,i))}),o.getDerivedResource({request:n,templateValues:u})}function S(e,t,r,i,n,o,a){ie=!1,oe=!1,se=!1,ue=!1;var l=e._pickFeaturesResource,u=l.getUrlComponent(!0),c=e._pickFeaturesTags,d={},h=u.match(ee);return s(h)&&h.forEach(function(l){var u=l.substring(1,l.length-1);s(c[u])&&(d[u]=c[u](e,t,r,i,n,o,a))}),l.getDerivedResource({templateValues:d})}function w(e,t,r){if(e&&e.urlSchemeZeroPadding&&e.urlSchemeZeroPadding.hasOwnProperty(t)){var i=e.urlSchemeZeroPadding[t];if("string"==typeof i){var n=i.length;n>1&&(r=r.length>=n?r:new Array(n-r.toString().length+1).join("0")+r)}}return r}function T(e,t,r,i){return w(e,"{x}",t)}function E(e,t,r,i){return w(e,"{reverseX}",e.tilingScheme.getNumberOfXTilesAtLevel(i)-t-1)}function A(e,t,r,i){return w(e,"{y}",r)}function x(e,t,r,i){return w(e,"{reverseY}",e.tilingScheme.getNumberOfYTilesAtLevel(i)-r-1)}function P(e,t,r,i){var n=e.maximumLevel;return w(e,"{reverseZ}",s(n)&&i<n?n-i-1:i)}function D(e,t,r,i){return w(e,"{z}",i)}function I(e,t,r,i){var n=(t+r+i)%e._subdomains.length;return e._subdomains[n]}function O(e,t,r,i){ie||(e.tilingScheme.tileXYToRectangle(t,r,i,ne),ne.west=f.toDegrees(ne.west),ne.south=f.toDegrees(ne.south),ne.east=f.toDegrees(ne.east),ne.north=f.toDegrees(ne.north),ie=!0)}function M(e,t,r,i){return O(e,t,r,i),ne.west}function R(e,t,r,i){return O(e,t,r,i),ne.south}function L(e,t,r,i){return O(e,t,r,i),ne.east}function N(e,t,r,i){return O(e,t,r,i),ne.north}function k(e,t,r,i){oe||(e.tilingScheme.tileXYToNativeRectangle(t,r,i,ae),oe=!0)}function F(e,t,r,i){return k(e,t,r,i),ae.west}function B(e,t,r,i){return k(e,t,r,i),ae.south}function U(e,t,r,i){return k(e,t,r,i),ae.east}function V(e,t,r,i){return k(e,t,r,i),ae.north}function z(e,t,r,i){return e.tileWidth}function G(e,t,r,i){return e.tileHeight}function W(e,t,r,i,n,o,a){return Y(e,t,r,i,n,o),le.x}function H(e,t,r,i,n,o,a){return Y(e,t,r,i,n,o),le.y}function j(e,t,r,i,n,o,a){return Y(e,t,r,i,n,o),e.tileWidth-le.x-1}function q(e,t,r,i,n,o,a){return Y(e,t,r,i,n,o),e.tileHeight-le.y-1}function Y(e,t,r,i,n,o,a){if(!se){J(e,t,r,i,n,o);var s=de,l=e.tilingScheme.tileXYToNativeRectangle(t,r,i,ce);le.x=e.tileWidth*(s.x-l.west)/l.width|0,le.y=e.tileHeight*(l.north-s.y)/l.height|0,se=!0}}function X(e,t,r,i,n,o,a){return f.toDegrees(n)}function Q(e,t,r,i,n,o,a){return f.toDegrees(o)}function Z(e,t,r,i,n,o,a){return J(e,t,r,i,n,o),de.x}function K(e,t,r,i,n,o,a){return J(e,t,r,i,n,o),de.y}function J(e,t,r,i,n,o,a){if(!ue){if(e.tilingScheme instanceof h)de.x=f.toDegrees(n),de.y=f.toDegrees(o);else{var s=he;s.longitude=n,s.latitude=o,e.tilingScheme.projection.project(s,de)}ue=!0}}function $(e,t,r,i,n,o,a){return a}var ee=/{[^}]+}/g,te={x:T,y:A,z:D,s:I,reverseX:E,reverseY:x,reverseZ:P,westDegrees:M,southDegrees:R,eastDegrees:L,northDegrees:N,westProjected:F,southProjected:B,eastProjected:U,northProjected:V,width:z,height:G},re=n(te,{i:W,j:H,reverseI:j,reverseJ:q,longitudeDegrees:X,latitudeDegrees:Q,longitudeProjected:Z,latitudeProjected:K,format:$});l(b.prototype,{url:{get:function(){return this._resource.url}},urlSchemeZeroPadding:{get:function(){return this._urlSchemeZeroPadding}},pickFeaturesUrl:{get:function(){return this._pickFeaturesResource.url}},proxy:{get:function(){return this._resource.proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return this._minimumLevel}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return s(this._resource)}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return this._hasAlphaChannel}}}),b.prototype.reinitialize=function(e){var t=this;t._readyPromise=v(e).then(function(r){s(e.proxy)&&u("UrlTemplateImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var i=r.customTags,l=n(te,i),c=n(re,i),d=g.createIfNeeded(r.url,{proxy:r.proxy}),h=g.createIfNeeded(r.pickFeaturesUrl,{proxy:r.proxy});t.enablePickFeatures=a(r.enablePickFeatures,t.enablePickFeatures),t._urlSchemeZeroPadding=a(r.urlSchemeZeroPadding,t.urlSchemeZeroPadding),t._tileDiscardPolicy=r.tileDiscardPolicy,t._getFeatureInfoFormats=r.getFeatureInfoFormats,t._subdomains=r.subdomains,p(t._subdomains)?t._subdomains=t._subdomains.slice():s(t._subdomains)&&t._subdomains.length>0?t._subdomains=t._subdomains.split(""):t._subdomains=["a","b","c"],t._tileWidth=a(r.tileWidth,256),t._tileHeight=a(r.tileHeight,256),t._minimumLevel=a(r.minimumLevel,0),t._maximumLevel=r.maximumLevel,t._tilingScheme=a(r.tilingScheme,new _({ellipsoid:r.ellipsoid})),t._rectangle=a(r.rectangle,t._tilingScheme.rectangle),t._rectangle=m.intersection(t._rectangle,t._tilingScheme.rectangle),t._hasAlphaChannel=a(r.hasAlphaChannel,!0);var f=r.credit;return"string"==typeof f&&(f=new o({text:f})),t._credit=f,t._resource=d,t._tags=l,t._pickFeaturesResource=h,t._pickFeaturesTags=c,!0})},b.prototype.getTileCredits=function(e,t,r){},b.prototype.requestImage=function(e,t,r,i){return y.loadImage(this,C(this,e,t,r,i))},b.prototype.pickFeatures=function(e,t,r,i,n){function o(e,t){return e.callback(t)}function a(){if(l>=u._getFeatureInfoFormats.length)return v([]);var s=u._getFeatureInfoFormats[l],c=S(u,e,t,r,i,n,s.format);return++l,"json"===s.type?c.fetchJson().then(s.callback).otherwise(a):"xml"===s.type?c.fetchXML().then(s.callback).otherwise(a):"text"===s.type||"html"===s.type?c.fetchText().then(s.callback).otherwise(a):c.fetch({responseType:s.format}).then(o.bind(void 0,s)).otherwise(a)}if(this.enablePickFeatures&&s(this._pickFeaturesResource)&&0!==this._getFeatureInfoFormats.length){var l=0,u=this;return a()}};var ie=!1,ne=new m,oe=!1,ae=new m,se=!1,le=new e,ue=!1,ce=new m,de=new t,he=new r;return b}),define("Scene/createTileMapServiceImageryProvider",["../Core/Cartesian2","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/deprecationWarning","../Core/DeveloperError","../Core/GeographicTilingScheme","../Core/Rectangle","../Core/Resource","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorTilingScheme","../ThirdParty/when","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(o){function f(n){for(var l,h,p,f=/tileformat/i,m=/tileset/i,S=/tilesets/i,w=/boundingbox/i,T=[],E=n.childNodes[0].childNodes,A=0;A<E.length;A++)if(f.test(E.item(A).nodeName))l=E.item(A);else if(S.test(E.item(A).nodeName)){p=E.item(A);for(var x=E.item(A).childNodes,P=0;P<x.length;P++)m.test(x.item(P).nodeName)&&T.push(x.item(P))}else w.test(E.item(A).nodeName)&&(h=E.item(A));var D;if(!i(p)||!i(h))return D="Unable to find expected tilesets or bbox attributes in "+y.url+".",v=c.handleError(v,C,C.errorEvent,D,void 0,void 0,void 0,g),void(v.retry||b.reject(new u(D)));var I=r(o.fileExtension,l.getAttribute("extension")),O=r(o.tileWidth,parseInt(l.getAttribute("width"),10)),M=r(o.tileHeight,parseInt(l.getAttribute("height"),10)),R=r(o.minimumLevel,parseInt(T[0].getAttribute("order"),10)),L=r(o.maximumLevel,parseInt(T[T.length-1].getAttribute("order"),10)),N=p.getAttribute("profile"),k=o.tilingScheme;if(!i(k))if("geodetic"===N||"global-geodetic"===N)k=new a({ellipsoid:o.ellipsoid});else{if("mercator"!==N&&"global-mercator"!==N)return D=y.url+"specifies an unsupported profile attribute, "+N+".",v=c.handleError(v,C,C.errorEvent,D,void 0,void 0,void 0,g),void(v.retry||b.reject(new u(D)));k=new d({ellipsoid:o.ellipsoid})}var F=s.clone(o.rectangle);if(!i(F)){var B,U,V,z;r(o.flipXY,!1)?(V=new e(parseFloat(h.getAttribute("miny")),parseFloat(h.getAttribute("minx"))),z=new e(parseFloat(h.getAttribute("maxy")),parseFloat(h.getAttribute("maxx")))):(V=new e(parseFloat(h.getAttribute("minx")),parseFloat(h.getAttribute("miny"))),z=new e(parseFloat(h.getAttribute("maxx")),parseFloat(h.getAttribute("maxy"))));var G="geodetic"===N||"mercator"===N;if(k instanceof a||G)B=t.fromDegrees(V.x,V.y),U=t.fromDegrees(z.x,z.y);else{var W=k.projection;B=W.unproject(V),U=W.unproject(z)}F=new s(B.longitude,B.latitude,U.longitude,U.latitude)}F.west<k.rectangle.west&&(F.west=k.rectangle.west),F.east>k.rectangle.east&&(F.east=k.rectangle.east),F.south<k.rectangle.south&&(F.south=k.rectangle.south),F.north>k.rectangle.north&&(F.north=k.rectangle.north);var H=k.positionToTileXY(s.southwest(F),R),j=k.positionToTileXY(s.northeast(F),R);(Math.abs(j.x-H.x)+1)*(Math.abs(j.y-H.y)+1)>4&&(R=0);var q=_.getDerivedResource({url:"{z}/{x}/{reverseY}."+I});b.resolve({url:q,tilingScheme:k,rectangle:F,tileWidth:O,tileHeight:M,minimumLevel:R,maximumLevel:L,tileDiscardPolicy:o.tileDiscardPolicy,credit:o.credit})}function m(e){var t=r(o.fileExtension,"png"),n=r(o.tileWidth,256),a=r(o.tileHeight,256),s=r(o.minimumLevel,0),l=o.maximumLevel,u=i(o.tilingScheme)?o.tilingScheme:new d({ellipsoid:o.ellipsoid}),c=r(o.rectangle,u.rectangle),h=_.getDerivedResource({url:"{z}/{x}/{reverseY}."+t});b.resolve({url:h,tilingScheme:u,rectangle:c,tileWidth:n,tileHeight:a,minimumLevel:s,maximumLevel:l,tileDiscardPolicy:o.tileDiscardPolicy,credit:o.credit})}function g(){y.fetchXML().then(f).otherwise(m)}o=r(o,{}),i(o.proxy)&&n("createTileMapServiceImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var _=l.createIfNeeded(o.url,{proxy:o.proxy});_.appendForwardSlash();var v,y=_.getDerivedResource({url:"tilemapresource.xml"}),b=h.defer(),C=new p(b.promise);return g(),C}return f}),define("Scene/GoogleEarthEnterpriseMapsProvider",["../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/Rectangle","../Core/Resource","../Core/RuntimeError","../Core/TileProviderError","../Core/WebMercatorTilingScheme","../ThirdParty/when","./ImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(i){function o(e){var t;try{t=JSON.parse(e)}catch(r){t=JSON.parse(e.replace(/([\[\{,])[\n\r ]*([A-Za-z0-9]+)[\n\r ]*:/g,'$1"$2":'))}for(var n,o=0;o<t.layers.length;o++)if(t.layers[o].id===S._channel){n=t.layers[o];break}var a;if(!r(n))throw a="Could not find layer with channel (id) of "+S._channel+".",b=d.handleError(b,S,S._errorEvent,a,void 0,void 0,void 0,g),new c(a);if(!r(n.version))throw a="Could not find a version in channel (id) "+S._channel+".",b=d.handleError(b,S,S._errorEvent,a,void 0,void 0,void 0,g),new c(a);if(S._version=n.version,r(t.projection)&&"flat"===t.projection)S._tilingScheme=new s({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,rectangle:new l(-Math.PI,-Math.PI,Math.PI,Math.PI),ellipsoid:i.ellipsoid});else{if(r(t.projection)&&"mercator"!==t.projection)throw a="Unsupported projection "+t.projection+".",b=d.handleError(b,S,S._errorEvent,a,void 0,void 0,void 0,g),new c(a);S._tilingScheme=new h({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,ellipsoid:i.ellipsoid})}S._ready=!0,S._readyPromise.resolve(!0),d.handleSuccess(b)}function f(e){var t="An error occurred while accessing "+C.url+".";b=d.handleError(b,S,S._errorEvent,t,void 0,void 0,void 0,g),S._readyPromise.reject(new c(t))}function g(){var e=C.fetchText();p(e,o,f)}i=t(i,{}),r(i.proxy)&&n("GoogleEarthEnterpriseMapsProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var _=i.url,v=t(i.path,"/default_map"),y=u.createIfNeeded(_+v,{proxy:i.proxy});y.appendForwardSlash(),this._resource=y,this._url=_,this._path=v,this._tileDiscardPolicy=i.tileDiscardPolicy,this._channel=i.channel,this._requestType="ImageryMaps",this._credit=new e({text:"Google Imagery",imageUrl:m._logoData,link:"http://www.google.com/enterprise/mapsearth/products/earthenterprise.html"}),this.defaultGamma=1.9,this._tilingScheme=void 0,this._version=void 0,this._tileWidth=256,this._tileHeight=256,this._maximumLevel=i.maximumLevel,this._errorEvent=new a,this._ready=!1,this._readyPromise=p.defer();var b,C=y.getDerivedResource({url:"query",queryParameters:{request:"Json",vars:"geeServerDefs",is2d:"t"}}),S=this;g()}return i(m.prototype,{url:{get:function(){return this._url}},path:{get:function(){return this._path}},proxy:{get:function(){return this._resource.proxy}},channel:{get:function(){return this._channel}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},version:{get:function(){return this._version}},requestType:{get:function(){return this._requestType}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!0}}}),m.prototype.getTileCredits=function(e,t,r){},m.prototype.requestImage=function(e,t,r,i){var n=this._resource.getDerivedResource({url:"query",request:i,queryParameters:{request:this._requestType,channel:this._channel,version:this._version,x:e,y:t,z:r+1}});return f.loadImage(this,n)},m.prototype.pickFeatures=function(e,t,r,i,n){}, +m._logoData="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAAnCAYAAACmP2LfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAHdElNRQfcDB4TJDr1mp5kAAAAGnRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAB1zSURBVHhe7ZwHeFTFFsf/u+l9N70npOxuSAKEFFIhCSH0qhEQUHkgKCgWUFGBB6IoCAoo0ntooaRvEkIIBBBpoYSa3nvvfd+5u4sQUigPfMX8v2/Y3Tkzs3fv/d0z58zcgF69Ql1SY+MM1wQJem44ZeiJk8beEOqPwG6uC7ZqyElb9eo/JZEIkH2nRQkBIlNMauuPCS3uGN/kjkmNDghoskBAgzrZ2NLmf1+JwIKQpYsoxdmIV9+N07onCegzBPM9bOdmYKnazF6g/1N6UySPqSJzvCaaiLHtP8G/Phq+FRfgU5ogKWUXMLT6Mvzqr2BE40mMadqO8c3zMabBC6PqDDC8SlY60t9HByCLVTKu+ERmHr5TWI9wjVxEaOZivWo1pil8D1tZeWnLXv1l8iZ3PF2kjymiWRgvCoJv5U243IyAXcQq8A9Mg9W+4bDe6wv+kVGwCZkL+4Sf4ZR+BZ5VGQR3EkbWn8Hopm3wq54Lz2JD6ah/P21XGopQ9Qoc16jGSqVyTJWbQbUsibFXf42mihTwZpsvAtp3k0dOhFOSEH1+ngaDefrgjFCgFkxY8fCisCBvKgODzxRh9qslBFGfYmDGLbiV5mBwRRo8KtPhVBgPu8teMP7u73chD6kMRYRGBY5xqrFKqQwz5SdTbS/Qf5mmUYw8rf01CjHC4VP7AHZxO6E3qy9ZZCQNnio2rE/4o9/tkxiQUYp+KRXgx8XC5FsXcLz/hkCrDUU4pxLHuDVYpdwL9F+qqSJZKlPwenskfOoI5tN7YPCJGVme7wKYr5EBXzgYfW+mwTI0Gjrznaj2WW+I/y8dVPdDGLcKRzXrsEqlHO8oTKHaXqAZWe9hQXCi63NhHWYI3ilfWIW/YLjqL2JRiOFBJRz+LffhcPs09D+0J8vzn3zXdBnYnp8Mi6NboTWzH9X8fVc+DhDQodxqAroe36lU9AJNWr4cEAjNwI8OAC9cT1rbUfzwGeCfKiL7dGnNc+q1NiO80b4BY1oT4V6WDcsdc6j2xbyq4wMWrA9rQmeWFn36ey/jBaoPQ4hmLYI0G/AtAf22fC/QDols8ITrIYi/Bl6knbS2o3gRbxHQxQQ0k0S/gCa2v4OJovPwacqAQ1ICjL40klr+UrWoQbFBETo18jCpZsOoFODkvuCNJYoHW3QKXFEM7ETRcKfiQe8d6NVIFImXvg4skhY40mxnQYVRIIeA1qrHEc1GrFSpxFtP99AiFbDbNKDZpAzzGkVYVcvBuBJQEo/9/6C+dyjPitwLwak74D8V6Bfw0P5VShjXFoTR7TfhUZkL29M/wfATJan1lauWC3aDOgyaVDCuTgbf1bFkfmtkye1ogsK2asivLYfCglIoD8qCknI2NHuG4QSVGMgQyMbt0fioRYh9VYcRU7QX55uDcaHtFOJEsThMtmWtQgxsDodsWaC0c3ea3MzGBJEqxrfbYmzr6xjfPAeTmt5HQPO7eK1xDibUz8eY+k8xtHYJPCtXwvHOu7AXMrMTsF/TH8HajTis1YwVqpWY0TXQDKy1OpBr5EJA52Fukxx+bmKxtjWx2DuaWawNlZD5qhzyo9KhpHAbKpJO/6t65UCPbPHA2PYrGNacgkElabCJJDev/MpDhUKKnuq44LRoYEK1IiswkS1zYCfk5y+F0qjvoTwqBOof34dGeAnUL1ZCLboEnJ9zoe0QD/Nuj00UBVXRabzVLETM3S0ICfwA8yc7Y6C3ANYbZsA7aQ1W1xzEfZEQ6dT2BkG9pP4ouo7jGE1u42JS20QMrzkCr4xwuN4+AM+cYII3EaNar2J86zmMrP8DHulCON4NhU3YWuhOYy6SZENpH9cfx7WacFC7BSvUqjBDsRPQIiugURvazeqYVaqAw6dYrJ9WQy7gayj4nYDy3HtQOVQGpYRqKEWXQf2HdGha/AFdae9Xr4czz0ubISRA75ECbSut7agegO75OLxpahze8j5GtifBpzEDLiV30Dd2mNT6StWiCbVmLt5rUkBQCEt2zWzIMSA8HgrIBkLD+Sp0jhHISYXQ/KMYukfvQ3fQxq68XCTBHId/tMTg7LV1CFs4BszJ6hBarBgHlcRv8H7tbuSKQpFPYGe0BmND+nZ0npECaPKf0r4UIxsuoF/IMpitsAVnrA4s15uh3x8fwLXkLobUZGJIXTqcUzbDaJE5FAVq0t4S7dEcjqMEc6B2K5arVWN6Z6AbdOmm5mJelQKOHWSxF44Cy4CqxW0s6RwchCovFRohdGNfLgX3WiZ0N4aD++y7jfwYJUrAPCle/ZjKV+BFTSegrGAZIm3QjXhBytTWB3zhByzryMUU986jz16wD+96ijCNUIAgmkc3tS6G7GERjCbgR82B4OTbEESqIiCIcqsIYzoGGyrBEMSmgh8xBoIIAR2fAHZhj8Z9DOhl9FHeKkSDvn809fuc+iyCddRYaiOZBTvIt1YJfs0b4N+WDO+GHPLQN2Ab7S61vjJV60C9SRPvNSqzTpxlyQfS1dGUmjppK7gW16B/LhN6abnQu5cDwzO3YNhhqqK4WJY887sEdGzWFpxfOxmDpKZOOvgWFB8sx9L6nShvP4FyUQjKGg5gScpGKEqbUE7RxiGYv6QQ4zIG/r4D2m88sjEy/EIW/a6+TQ4gHe5VhXCvy4JL7gLYnesI2i6t4Tii04r92u1YKt767gB0ozrkGzmY26zEOh7Hkt+kAKhLTX9qOVVdg9aoNOjcToR+wUVKLYKgN0Zq7l7884wn9CKgr4AfWw/B6SwqKQRKOdXVghe9CpbherASSjtIpGpxRIHFjwygNreoXy0lb+lU7lHJBP9kPcGXQnBNghUB/Lh44fbUp5JA+5Hs71LbPPLCVRDEJZDNGIJgeQI6mG6KegKzldq1U7tGKjQmHR8vwl86kgRoAQN0xBw6ztn0nQ/ocxEdQ7L4d/BjG6g+m8aZTL/xsXPuW82Fb8t+DG1Ox5D6XAwqvQ67OA+p9ZWoUQPsei78mjSwNU9GLmEzVGZJTd3qFPTn3YZhXgYMMjNhlHsDxms/hNWfoUdrNPgEc2h7BG5d/Bo7Blt0BuNxXf4MVmXrkdRyEHWiY6hr2oc7mevRX2wc18gioEeI1+N9a+/CNnImVAZ0mhEoNOPAJT8MHjUF8KTiWhqHgbfMpVaJdhLQh3XasU9bJAZ6ekeg6zQwgEKuLSWysmd3QGmatLqD8qDNug3dCX/AIPk4jGr2wDB/JXTmkan70IvmZTY/rB9BdZlKLkG0lG0d5klAObKsw1+jzyFiWPnRawiaDrMYwTyMwMwh220WP2IWFVfqN4CKO8E3n0C6R/ZUej9Y2kUiMdDRFTRePH3nA3q/m7xpAEtAXl0QrkTwscnmS/3eptdzNEYevZLnZ5booqk8tuYs9tAny+n1LL1mghezlcULH0VtHamOZhvhIvoNOXQsd2EZIbluYnlWaMO75TCFG9kYXJ8H14o76H/10Z3yClSrCm6jGtbWK7LC7kIlYRfUmY2XHnUa+mbXYRSfCuNCptyE6b1jMBD/EPKwchQPLxGdxOWWI8iKXYBPqLozgI8pfA5YBWvxbfMeNLUfRmPTLjRnr8YKsdGvRQ5j2zZTSSRQ78H+7GhxfScFAINypsG9ukDspZ0LKKE+O0pqlGi71ggcIqD3dga6RhFKjSqYT+VEFkvu/E9Q+HNWKaE2VVDgVkPFqwAaay5CN3En9M59BM2vfKDs7AvljjPGE5LlharQdL+LoCmhOHU0rIUyD+NgVTOa+q2iVQiIcAKpHtbhXuJOjPqeVCRYThNE6VTvKNs3hM3cHGIxntxKyCbP7Erj1lHZJbVIJAG6iiCroZCAPGukvOyASJbvCgoaAoKoAQ1kHcGC7nmZDkmhBR2PfSQLtkcl4zCSAE2eO6qExYuYxrE4KqdvelBiM4+ncYQy1IY8d0wbhUSLJAZGbsUceNYdwJCGPAyuy4NbZToG3JoO1Qk9AvHvqF4ejo0KCKlisyl04Jw+AE1ma71HRUJP+QqM1t2HcVEyTEoSYVYQCuN3HenCt4XDhGA+KorAnYZ9KIj5ELOl3XpU/k/wrt+OmraDaG7cjpacbxFvYAAZDG5Vw/DWCxjRdp+ATsWAS6+D69H1+XDNsoVb1T06b0VwzCmBIOYdqUWibTojcFBH1CXQctBtUcA6Oh/RmVC4sBmKA5j6erC1qqE4sRpqG25A43QIOHuXgvOmP5R4ZH6m5UY2L9SSLjZ5sKjjsI/o8olH8ngjCZoSgmw9DMIl3t42Up0g+pq89/sEjLK47knZhSkSuDepJP4JOyNJyEFAR8VQKMOR1nbWM69yxNJYwh+VLE90ffPyxLE3EwL9Jq0huWQqwL1iA7zq8+FVl0+epgBO6T+gb2TH+OglqgastxtZrNNlkLt8E5oJx6HZdab7mFZBk3UZRjMewCT7HkzLfodZxREYr5sBjiIBPYiAPt8ehvSGPSg5vwjzpd16VNkmmDTswp22QDTXbkJrxhJkzHGDFoUQmvBpvo2hrZl0TnLhlLIYfUO7nt7dSg3hURcP1/JiDEgphuXBqVKLRFsfA3oJAf3mI6Cr2OjTwGYdqWGzzmZD6WoYVCfehdqsZKjuuwS1oB1Q+5piHac3oaxBzZ9vLZ4nHEeesoXg6niDPSYWP9yUgD5PHu48eKE64krHcErchHIEuRysTpAXjObQWIYEHiV4EQYEojp5aEoyY+IIpOQugKYYOnIdJXrdJ63PtWwXMQM6m6SVT4gfZkbHV0XHsVtaQ3K8yoJr0YfwoHDDq5ZiQSqDik/B4Q9taYtn18gyNia1qGJsmTrGlUjK2FJ1jCjRwOASDnkxDvN95ZD/og5yl0qgfCMJ2leDoeksHaFHXYOJVyrMkm/DrPwMzGr2wmjnLGipthyHL0W7t9pDkduwF2U3lmGFtvbTdyirt0OreT+iWwPRUrUBbSkLkT/fCUZwKVYikBMwpDlPXNzLwuAQ2rWX8KzUh2dDDJyLSmB7/S5Mf3WRWiR6CPSezkCXQs6qBnLCKsheyoXqnTCoL9oOFd9/Qtl9KJT6UJMX3/zhCz8iuCjhiviSYtMx3ZTJBN8lCE7eIRgF0p6krRRaRBDskTTGySBKws5SuUjJHYUiMQdpzCUE0Q3y5MnSDhJJQg5JUvjSgO5hHZofaioGmvc40IycMgbRtJktjgOZ5Ma9irzSg46xYHcaVEZevkgBHqUWGFK+FENKQ+BdGAq/wiMYWbwHI6h4FwTDOes0BMKFMHxPNg9qn1dANakYanfuQSs5FJoTpaP1qBswsSGgb9+EeUU0Af0LDH4dBhXlmv3wajuOpPYQFDcEojxtNQ6sn9ZzUsiofjfUWg/iYOt+tJatRtvN95DqZgxNuKTKwLV4Jdyqc8Wz1uCGTLjmDIVDQqewQ8anwpJi6GsYkF4Ey2O/QvsfXKlJIgboAwT07s5AZ0G1TylUIsuhdKMI6vcuQ3PVAqg+9UZ8JvGEywiuNoIwD4IzaV2X+HSa1otgE3+NwJImVkycG0kx8snfyUZJW+QFApeSu+hN9BpIn6n+ZBp9bqDv+C8Fum+8IpzzJNOmR3UhTaGFcC07iAHXmamuZw28C/S/aIt+CcthF7+ToN0EQdhqOFzcBu/Sm/ApvAGX3DzYXIiF9jtWTJf74L6ZC83UfGg8SId2xnloSZKxp+gWjC0J6KSrMK8KhmnlSugtInpkCzaBV78Hl5oPoaLpECrLt+Bi4jfgS7t1q+YDUGsPwj5KDFsLlqD97JuIpmpZmP+TftM1ezjlxsOllM4H3eReDWHwKrOBW84jqMeK5OBTv4Bu6HxxgqU1s/N3MkAHSoH+ioCe+gjoJHB0s8ENLID6/UJo3E+GVlwoNEwY278tXhR50RhmeexzgmM8JXjdF36MHwEoiXn70Csv6gxBm8PiRc6gJFD1HDzFpq1cP0omo5QJZAfqQzH0f6uHZjQgeR4cC/IJZCnUtSkYVPAWBiX2/CdU/S7Ql+9TgtFCTaiP0qAEXA2yRsqwuzECziWZcM4tgv2DSljF7ID+l+JNh9+hY38HuvcYmLOhk5EEnVPfQOmpW+33YGaXhj53E2BWuxvGebOh5cPUX/sWSgXrsa9mB2qaDqCK4C7I2IA3jn8u7tat2g6D034MIbWb0fZgHlr2DscXUhNNuYdkYRPrg/7JiXDMLYBrZS6GNEZgVJM/JjWY4I16G4xr/BCDq2nKjjoAvY+Zpwo7eXBskQK9Swr0lEdAn4a2wk3o/DMNWmn54KYUQIuZsebGQuXFQ42H4kfNk4QckSOkNZ1lGkGAUoInOKkAm2jJsVtH+om9Nj9ytZxNcNdhljXByo+JJXj/i4G2u2xM02YInPJLxFB7VudTPH0ZHkWu0hbPpwHpfnAszoFDVgVsb1fDMmoL9L8S7wTFQE/1AvR33oB+QSp0czKgl34B2iO9uwJCKib5SGaZjbqLPlkhMG1YDr1gQyioSs24vQTDitagsnIL6loCUVu9C2EJK9FjYtsWBNP2Q7hb9A155zdwY5mTeGexo0w32hEcy2F7JQaOqZfgk38KY6rDMKFBiGHNt+iGPgCNYd0/s/sbAb2fgN5JQC9Wq8bkR0AzioOOx3Xo30mGbnY+tNMKoJOQCm03qfnFxRf6E1yUFAqZJcyuZRWuQmB+TWHJcgJfkjPxImcSSIUsXviMx/O9DvqfALrPDjb6nhuBAWkZ5JFKKTYuIqhz4FUdAo9CGwzO7Ra2LjUg0w9OxdlwyKxAXzHQm8lDi4HeAT1WMPSHnYXR7aswKE6Gfl4K9PdfgZ6+uG8XSmMbKyXD/LsEmFduglH2NHA7rA3Hvg+Ve1/gYO4KNFRvQUPLQVRU7MG4yn1dJ4eiULAo3JhW9xsa77+Hml8GY8FQ425uAM5wRRivNoPlTjs4XhoH35oLGFZ/S/wglyDkbWmrrsUAvY+A3kHlSwJ6ihKzCvLnuQyElmIs9LdfhmHxA+jn5kI3jcrRFOjxU6DTbTx9DybsOBh0f034EeYEVyaFD0IYhnQ9y1pTIsiPvU5AnKYkUBL78yKmQhDLgDRPSWtPp/HFkFtHqFCfRBr73wX67qsD+qFsEubCnqKBAZllcCkkT12RjSHVMfApH0bJXfcH+aQGZg6FU1EWeeoK2NwgoMM3Q++zP/fq/Smf2g392ZEwzk2Acfl9GBHURmuSYPyn132oHBizH8B8wjX0SadQI2cWtOZZQbHTdEgRn8XN93EiczFayn5GU3Mg7lJMPab5SEeoCWZZ0TF4Ne/A/ZSPUbXdDz9Qdddrrk/KtcwR7jX34VXDzGCFGFT0GzyLu922x069kdiv145tOu34jlOHBWoz4arUAZQt0LYOhmFcHJ2H6zAsYnZDc2FwKhv60+m9UQrLUJ4hSYQAVhpM1O6jj30EDD33Q6frZyoY8cMVaWZZR560kuB5V9H6iVUas+Py5L1/IHsT2ZldR4nEkMdkUd8Y8tYd43mLIMhYhenDWvgjQSQiGFOkiEv0rEAzK2u8yG10M2WwBWFdb6q9NKDNd6rCOuYD9L2VI/57QMfcEniU5cCnJgG+lR9haAnz4MzT5ZjmA4e8HBqnGtYXamF+nK7bpx0uwHxoqGyE3sKD5HHjYVJ1C6Z5qTD5Ph2G1hnQEV/0LBhxU2E+4yYsbgTCJGsuNBfYQrnjA0CPxDo2CRYJ0xGesgD1ZWvQ3LQbKeSJ54uC0UcUDVVRGExFR/FB2y7cSf4C+Zv9sXSUeQ9P2z2pQdnmBHQsPKqKqFCyWJsM75o1GMw8O/iEhFZs/KK9CD9wRfhCTYTP1dqwnBOHrQYz8IuuH5ZxxI/MLQZH5kfoeu6D4cVQGNecgXHFbRgXZsD4Xg5MjqfDeE0KTBbRDLXsLiwOR8HkxCJoOs+Eavdr08ZBBGdYP7rYzAZILsH3LYUYtgSsAXlYRwLqW0r8Ksl2id4/Onaz47IE+kayUfwddYhsgwkqXRrLgOpHEuyhVF9B7ytoTAL//qNjeFagGfGEi5nvYPEifqOx/ek4p1J/8aKBWC8N6Icy2+oL6zOhECTmw46SuoHZpXBn/pK7/DK8K1bCp3Q0vAv7wqfIBD55OuS9teFVYASPfAFccseThw+E4Ho5LOMqYB6ZCeOdK6H1bleJH2sOOPZradqlC3otDqY5F2GafQmmCZdgFnMBZteEML2yCnprh0CZWVp66gbDuD5Q2uSLUacm43jSB0gq+h55JeuRX7wRqUUbkJL8DS4GTcPqCdZgduZ6XiZjgvcp9fIY3aAH/yY+3KvcMDBjLSXQBXDML4VbaQG8a9PgUxcOzyIneKY/Or6FHDO8q7INY+RiMFJaJijE4i2VeEylej/FDs99TAPH8Dvofv8bDK/vhVHxMRhX0W+vOgXTijiY5UXANGkNnYeRUGN2VrsPNx6XVaQNgRNM03sBgUjeOKJJ/Cr+LNzFsg61YB5/elyKtic0qM031CaZAG0gqJnVEuYBIoI49gy9D6DXrQR3GoU2j3YE+WE2FI9TGBG1FLywnhNbPt1Y/OhY+o5iGqsGNmdLaVxfqZUB+g0Iztwi2AOkNZ3FCzOm30bHeHK9tKYHKfPZMFhlAtM9c2EpjALv93zY3qlE/8xyOOUVUTiSBrfy83CvDIdbRZC4uJSGwzHzd0qgkmEVfRnGW/dC79vPobtkFLRmm0HDpVt43MnrzoOm/dfQeeOf0P3wB+guJogXrIDuhHfAsdOFbKdQ5GkaYQbNNYNht2c8/AOnYNKB6Ri//Q14zRwIuohdPC76pCbWKGFCkx9GNC7B0NZD8CiJh8Odi7A59zud7EuwvU4hVUYZBhUXwqsqA56V0RiUM1Dam36UoiyFuprQhc6fRZuKKhV5+rcLKD2hrPQ+NPsvgNb0j6C9eCG0v/kU2l9/BK0ZM8EdRJQ833noG8Qib6lDkA0lYD6i8GIJlffZ/IhhbJtQjW4TP164EiWWztTnH9T+a4L/MxpjAn02hWWYDAQnefSZzm7Io7zDOpiSzGh3grwPwd3zDccPZdH4phBEkXcWBrD4wlE07qObw5pmBUGsK43T/YPfgmAFWEe5U2EeCXhGcV5nQ3u2KrTf6w+jdTNhtud7mB/ZC4vg43QAwbAMDYLF0e3os+8HGP80D7oLx0F9dD+oj9AGZ4Y85K0Yj/Vs3kQiFgeybFPIySiDzdwAz9O3JzHjPNtYk8gjv948FOOatlGodR0Dk07Bau9n0F8wFBp+luBO1CXeuDD51Q3830PRP7UIzgUlcC0vhHPRSdic6eI53ecT3W0sKyjI2EFRxhzyz3sOO8voBkEUTclYhAyshCwr642PR79diwlbBOEs8vLMFjgbbuelhpeoz5rEDxsNNl/+9ON5RWJOLsXCysQdh5IhWWbzhUmoel6v/l/RxGpZTKgbh3EtEZQMp5AX2ASd2f3AVu7695ky/7nOuc2U/BZSCFIGp+I82F/rfprsVa/+Mk0sZ2F0tTvGNZ+gRO8B7C/HQ92beWine+/IDWDBbJUmbBN/hUNOGRyyStH34vfQeP3ZV4R61atXIu9Kefg1rIB/XRJciwso9nymLXmxbP+wxcCsVAxIKwfv1AZoDH96jN6rXr1SuVeowKsuFINrs+BSXATbc59JLU/XwCwdDMw7B/vUEpgHfQYZ7v9HCNar/2E55ynDpSwYrhXF4uKUeQiY0/Oy3kM555nCITcJgmvp0F30Yo8L9KpXL1X9E2XhkPoVBuYWwbmolKDOhmv+WHiXyGNkgbTRE1pOublXkRycCz+AfUoRzPdsgKJN1w/19KpXf7n6xlnCPikE/SkWdswrozDkNoZUfIWhFTYYWaPy4a6NkgSR2XAZXSOLIWUWcCv7FP1T7sH8wFZwp7ycxz971auXIm4AG+b77MFLEKLv7ULJMy0FefCsPAOv0t0YUrIMg0s+gVfxYrgVbIJLUSzsrl2F2ZZl4L7J/Pdp/956ca969UrEna0O41/HwSJ4F3in42Fz5Trsbt5Bv3u30e9uImyvnoV15GGY/LIA6kOZP1966pZ8r3r1n5eqhwZ0F/aB4ToHGK9zh/FPHjD60RE6H1tDaaA2cdy7mvFfI+BffksPNrEksu0AAAAASUVORK5CYII=",m}),define("Scene/MapboxImageryProvider",["../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/MapboxApi","../Core/Resource","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(i){i=t(i,t.EMPTY_OBJECT);var o=i.mapId;r(i.proxy)&&n("MapboxImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var u=i.url;r(u)||(u="https://api.mapbox.com/v4/"),this._url=u;var p=s.createIfNeeded(u,{proxy:i.proxy}),f=a.getAccessToken(i.accessToken);this._mapId=o,this._accessToken=f,this._accessTokenErrorCredit=a.getErrorCredit(i.accessToken);var m=t(i.format,"png");/\./.test(m)||(m="."+m),this._format=m;var g=p.getUrlComponent();if(c.test(g)||(g+="/"),g+=o+"/{z}/{x}/{y}"+this._format,p.url=g,p.addQueryParameters({access_token:f}),r(i.credit)){var _=i.credit;"string"==typeof _&&(_=new e({text:_})),d=_,h.length=0}this._resource=p,this._imageryProvider=new l({url:p,credit:d,ellipsoid:i.ellipsoid,minimumLevel:i.minimumLevel,maximumLevel:i.maximumLevel,rectangle:i.rectangle})}var c=/\/$/,d=new e({text:"© Mapbox © OpenStreetMap",link:"https://www.mapbox.com/about/maps/"}),h=[new e({text:"Improve this map",link:"https://www.mapbox.com/map-feedback/"})];return i(u.prototype,{url:{get:function(){return this._url}},ready:{get:function(){return this._imageryProvider.ready}},readyPromise:{get:function(){return this._imageryProvider.readyPromise}},rectangle:{get:function(){return this._imageryProvider.rectangle}},tileWidth:{get:function(){return this._imageryProvider.tileWidth}},tileHeight:{get:function(){return this._imageryProvider.tileHeight}},maximumLevel:{get:function(){return this._imageryProvider.maximumLevel}},minimumLevel:{get:function(){return this._imageryProvider.minimumLevel}},tilingScheme:{get:function(){return this._imageryProvider.tilingScheme}},tileDiscardPolicy:{get:function(){return this._imageryProvider.tileDiscardPolicy}},errorEvent:{get:function(){return this._imageryProvider.errorEvent}},credit:{get:function(){return this._imageryProvider.credit}},proxy:{get:function(){return this._imageryProvider.proxy}},hasAlphaChannel:{get:function(){return this._imageryProvider.hasAlphaChannel}}}),u.prototype.getTileCredits=function(e,t,i){var n=h.slice();return r(this._accessTokenErrorCredit)&&n.push(this._accessTokenErrorCredit),n},u.prototype.requestImage=function(e,t,r,i){return this._imageryProvider.requestImage(e,t,r,i)},u.prototype.pickFeatures=function(e,t,r,i,n){return this._imageryProvider.pickFeatures(e,t,r,i,n)},u}),define("Scene/SingleTileImageryProvider",["../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/Rectangle","../Core/Resource","../Core/RuntimeError","../Core/TileProviderError","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(i){function o(e){b._image=e,b._tileWidth=e.width,b._tileHeight=e.height,b._ready=!0,b._readyPromise.resolve(!0),d.handleSuccess(b._errorEvent)}function p(e){var t="Failed to load image "+m.url+".";y=d.handleError(y,b,b._errorEvent,t,0,0,0,f,e),b._readyPromise.reject(new c(t))}function f(){h(m.fetchImage(),o,p)}i=t(i,{}),r(i.proxy)&&n("SingleTileImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var m=u.createIfNeeded(i.url,{proxy:i.proxy}),g=t(i.rectangle,l.MAX_VALUE),_=new s({rectangle:g,numberOfLevelZeroTilesX:1,numberOfLevelZeroTilesY:1,ellipsoid:i.ellipsoid});this._tilingScheme=_,this._resource=m,this._image=void 0,this._texture=void 0,this._tileWidth=0,this._tileHeight=0,this._errorEvent=new a,this._ready=!1,this._readyPromise=h.defer();var v=i.credit;"string"==typeof v&&(v=new e({text:v})),this._credit=v;var y,b=this;f()}return i(p.prototype,{url:{get:function(){return this._resource.url}},proxy:{get:function(){return this._resource.proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return 0}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise.promise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!0}}}),p.prototype.getTileCredits=function(e,t,r){},p.prototype.requestImage=function(e,t,r,i){return this._image},p.prototype.pickFeatures=function(e,t,r,i,n){},p}),define("Scene/GetFeatureInfoFormat",["../Core/Cartographic","../Core/defined","../Core/DeveloperError","../Core/RuntimeError","./ImageryLayerFeatureInfo"],function(e,t,r,i,n){"use strict";function o(e,r,i){this.type=e,t(r)||("json"===e?r="application/json":"xml"===e?r="text/xml":"html"===e?r="text/html":"text"===e&&(r="text/plain")),this.format=r,t(i)||("json"===e?i=a:"xml"===e?i=s:"html"===e?i=m:"text"===e&&(i=m)),this.callback=i}function a(r){for(var i=[],o=r.features,a=0;a<o.length;++a){var s=o[a],l=new n;if(l.data=s,l.properties=s.properties,l.configureNameFromProperties(s.properties),l.configureDescriptionFromProperties(s.properties),t(s.geometry)&&"Point"===s.geometry.type){var u=s.geometry.coordinates[0],c=s.geometry.coordinates[1];l.position=e.fromDegrees(u,c)}i.push(l)}return i}function s(e){var t=e.documentElement;if("MultiFeatureCollection"===t.localName&&t.namespaceURI===g)return l(e);if("FeatureInfoResponse"===t.localName&&t.namespaceURI===_)return u(e);if("FeatureCollection"===t.localName&&t.namespaceURI===v)return c(e);if("ServiceExceptionReport"===t.localName)throw new i((new XMLSerializer).serializeToString(t));return"msGMLOutput"===t.localName?d(e):f(e)}function l(e){for(var t=[],r=e.documentElement,i=r.getElementsByTagNameNS(g,"Feature"),o=0;o<i.length;++o){for(var a=i[o],s={},l=a.getElementsByTagNameNS(g,"Val"),u=0;u<l.length;++u){var c=l[u];if(c.hasAttribute("ref")){var d=c.getAttribute("ref"),h=c.textContent.trim();s[d]=h}}var p=new n;p.data=a,p.properties=s,p.configureNameFromProperties(s),p.configureDescriptionFromProperties(s),t.push(p)}return t}function u(e){var t,r=e.documentElement,i=[],n=r.getElementsByTagNameNS("*","FIELDS");if(n.length>0)for(var o=0;o<n.length;++o){var a=n[o];t={};for(var s=a.attributes,l=0;l<s.length;++l){var u=s[l];t[u.name]=u.value}i.push(p(a,t))}else for(var c=r.getElementsByTagNameNS("*","FeatureInfo"),d=0;d<c.length;++d){var h=c[d];t={};for(var f=h.childNodes,m=0;m<f.length;++m){var g=f[m];g.nodeType===Node.ELEMENT_NODE&&(t[g.localName]=g.textContent)}i.push(p(h,t))}return i}function c(e){for(var t=[],r=e.documentElement,i=r.getElementsByTagNameNS(y,"featureMember"),n=0;n<i.length;++n){var o=i[n],a={};h(o,a),t.push(p(o,a))}return t}function d(e){for(var r,n=[],o=e.documentElement.childNodes,a=0;a<o.length;a++)if(o[a].nodeType===Node.ELEMENT_NODE){r=o[a];break}if(!t(r))throw new i("Unable to find first child of the feature info xml document");for(var s=r.childNodes,l=0;l<s.length;++l){var u=s[l];if(u.nodeType===Node.ELEMENT_NODE){var c={};h(u,c),n.push(p(u,c))}}return n}function h(e,t){for(var r=!0,i=0;i<e.childNodes.length;++i){var n=e.childNodes[i];n.nodeType===Node.ELEMENT_NODE&&(r=!1),"Point"!==n.localName&&"LineString"!==n.localName&&"Polygon"!==n.localName&&"boundedBy"!==n.localName&&(n.hasChildNodes()&&h(n,t)&&(t[n.localName]=n.textContent))}return r}function p(e,t){var r=new n;return r.data=e,r.properties=t,r.configureNameFromProperties(t),r.configureDescriptionFromProperties(t),r}function f(e){var t=(new XMLSerializer).serializeToString(e),r=document.createElement("div"),i=document.createElement("pre");i.textContent=t,r.appendChild(i);var o=new n;return o.data=e,o.description=r.innerHTML,[o]}function m(e){if(!b.test(e)&&!C.test(e)){var t,r=S.exec(e);r&&r.length>1&&(t=r[1]);var i=new n;return i.name=t,i.description=e,i.data=e,[i]}}var g="http://www.mapinfo.com/mxp",_="http://www.esri.com/wms",v="http://www.opengis.net/wfs",y="http://www.opengis.net/gml",b=/<body>\s*<\/body>/im,C=/<ServiceExceptionReport([\s\S]*)<\/ServiceExceptionReport>/im,S=/<title>([\s\S]*)<\/title>/im;return o}),define("Scene/WebMapServiceImageryProvider",["../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/freezeObject","../Core/GeographicTilingScheme","../Core/objectToQuery","../Core/queryToObject","../Core/Resource","../Core/WebMercatorTilingScheme","../ThirdParty/Uri","./GetFeatureInfoFormat","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=t(e,t.EMPTY_OBJECT),r(e.proxy)&&n("WebMapServiceImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var i=c.createIfNeeded(e.url,{proxy:e.proxy}),o=i.clone();i.addQueryParameters(m.DefaultParameters,!0),o.addQueryParameters(m.GetFeatureInfoDefaultParameters,!0),r(e.parameters)&&i.addQueryParameters(g(e.parameters)),r(e.getFeatureInfoParameters)&&o.addQueryParameters(g(e.getFeatureInfoParameters));var a={};a.layers=e.layers,a.bbox="{westProjected},{southProjected},{eastProjected},{northProjected}",a.width="{width}",a.height="{height}",parseFloat(i.queryParameters.version)>=1.3?a.crs=e.tilingScheme instanceof d?"EPSG:3857":"CRS:84":a.srs=e.tilingScheme instanceof d?"EPSG:3857":"EPSG:4326",i.addQueryParameters(a,!0),o.addQueryParameters(a,!0);var l={query_layers:e.layers,x:"{i}",y:"{j}",info_format:"{format}"};o.addQueryParameters(l,!0),this._resource=i,this._pickFeaturesResource=o,this._layers=e.layers,this._tileProvider=new f({url:i,pickFeaturesUrl:o,tilingScheme:t(e.tilingScheme,new s({ellipsoid:e.ellipsoid})),rectangle:e.rectangle,tileWidth:e.tileWidth,tileHeight:e.tileHeight,minimumLevel:e.minimumLevel,maximumLevel:e.maximumLevel,subdomains:e.subdomains,tileDiscardPolicy:e.tileDiscardPolicy,credit:e.credit,getFeatureInfoFormats:t(e.getFeatureInfoFormats,m.DefaultGetFeatureInfoFormats),enablePickFeatures:e.enablePickFeatures})}function g(e){var t={};for(var r in e)e.hasOwnProperty(r)&&(t[r.toLowerCase()]=e[r]);return t}return i(m.prototype,{url:{get:function(){return this._resource._url}},proxy:{get:function(){return this._resource.proxy}},layers:{get:function(){return this._layers}},tileWidth:{get:function(){return this._tileProvider.tileWidth}},tileHeight:{get:function(){return this._tileProvider.tileHeight}},maximumLevel:{get:function(){return this._tileProvider.maximumLevel}},minimumLevel:{get:function(){return this._tileProvider.minimumLevel}},tilingScheme:{get:function(){return this._tileProvider.tilingScheme}},rectangle:{get:function(){return this._tileProvider.rectangle}},tileDiscardPolicy:{get:function(){return this._tileProvider.tileDiscardPolicy}},errorEvent:{get:function(){return this._tileProvider.errorEvent}},ready:{get:function(){return this._tileProvider.ready}},readyPromise:{get:function(){return this._tileProvider.readyPromise}},credit:{get:function(){return this._tileProvider.credit}},hasAlphaChannel:{get:function(){return this._tileProvider.hasAlphaChannel}},enablePickFeatures:{get:function(){return this._tileProvider.enablePickFeatures},set:function(e){this._tileProvider.enablePickFeatures=e}}}),m.prototype.getTileCredits=function(e,t,r){return this._tileProvider.getTileCredits(e,t,r)},m.prototype.requestImage=function(e,t,r,i){return this._tileProvider.requestImage(e,t,r,i)},m.prototype.pickFeatures=function(e,t,r,i,n){return this._tileProvider.pickFeatures(e,t,r,i,n)},m.DefaultParameters=a({service:"WMS",version:"1.1.1",request:"GetMap",styles:"",format:"image/jpeg"}),m.GetFeatureInfoDefaultParameters=a({service:"WMS",version:"1.1.1",request:"GetFeatureInfo"}),m.DefaultGetFeatureInfoFormats=a([a(new p("json","application/json")),a(new p("xml","text/xml")),a(new p("text","text/html"))]),m}),define("Scene/TimeDynamicImagery",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/JulianDate","../Core/Request","../Core/RequestType"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){e=t(e,t.EMPTY_OBJECT),this._tileCache={},this._tilesRequestedForInterval=[];var r=this._clock=e.clock;this._times=e.times,this._requestImageFunction=e.requestImageFunction,this._reloadFunction=e.reloadFunction,this._currentIntervalIndex=-1,r.onTick.addEventListener(this._clockOnTick,this),this._clockOnTick(r)}function u(e,t,r){return e+"-"+t+"-"+r}function c(e){var t=e.split("-");if(3===t.length)return{x:Number(t[0]),y:Number(t[1]),level:Number(t[2])}}function d(e){var t=e._times;if(r(t)){var i=e._clock,n=i.currentTime,a=i.canAnimate&&i.shouldAnimate,s=i.multiplier;if(a||0===s){var l,u=t.indexOf(n);if(-1!==u){var c=t.get(u);return s>0?(l=o.secondsDifference(c.stop,n),++u):(l=o.secondsDifference(c.start,n),--u),l/=s,u>=0&&l<=5?t.get(u):void 0}}}}function h(e,t,i){var n=e._times.indexOf(i.start),o=e._tileCache,l=o[n];r(l)||(l=o[n]={});var u=t.key;if(r(l[u]))return!0;var d=c(u),h=new a({throttle:!0,throttleByServer:!0,type:s.IMAGERY,priorityFunction:t.priorityFunction}),p=e._requestImageFunction(d.x,d.y,d.level,h,i);return!!r(p)&&(l[u]={promise:p,request:h},!0)}return i(l.prototype,{clock:{get:function(){return this._clock},set:function(e){this._clock!==e&&(this._clock=e,this._clockOnTick(e),this._reloadFunction())}},times:{get:function(){return this._times},set:function(e){this._times!==e&&(this._times=e,this._clockOnTick(this._clock),this._reloadFunction())}},currentInterval:{get:function(){return this._times.get(this._currentIntervalIndex)}}}),l.prototype.getFromCache=function(e,t,i,n){var o,a=u(e,t,i),s=this._tileCache[this._currentIntervalIndex];if(r(s)&&r(s[a])){var l=s[a];o=l.promise.otherwise(function(e){throw n.state=l.request.state,e}),delete s[a]}return o},l.prototype.checkApproachingInterval=function(e,t,i,n){var o=u(e,t,i),a=this._tilesRequestedForInterval,s=d(this),l={key:o,priorityFunction:n.priorityFunction};r(s)&&h(this,l,s)||a.push(l),a.length>=512&&a.splice(0,256)},l.prototype._clockOnTick=function(e){var t=e.currentTime,i=this._times,n=i.indexOf(t),o=this._currentIntervalIndex;if(n!==o){var a=this._tileCache[o];for(var s in a)a.hasOwnProperty(s)&&a[s].request.cancel();return delete this._tileCache[o],this._tilesRequestedForInterval=[],this._currentIntervalIndex=n,void this._reloadFunction()}var l=d(this);if(r(l))for(var u=this._tilesRequestedForInterval,c=!0;c&&0!==u.length;){var p=u.pop();(c=h(this,p,l))||u.push(p)}},l}),define("Scene/WebMapTileServiceImageryProvider",["../Core/combine","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/freezeObject","../Core/isArray","../Core/objectToQuery","../Core/queryToObject","../Core/Rectangle","../Core/Resource","../Core/WebMercatorTilingScheme","../ThirdParty/Uri","../ThirdParty/when","./ImageryProvider","./TimeDynamicImagery"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(e){e=r(e,r.EMPTY_OBJECT),i(e.proxy)&&o("WebMapTileServiceImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var n=p.createIfNeeded(e.url,{proxy:e.proxy}),a=e.style,l=e.tileMatrixSetID;if(n.url.indexOf("{")>=0){var c={style:a,Style:a,TileMatrixSet:l};n.addTemplateValues(c),this._useKvp=!1}else n.addQueryParameters(C),this._useKvp=!0;this._resource=n,this._layer=e.layer,this._style=a,this._tileMatrixSetID=l,this._tileMatrixLabels=e.tileMatrixLabels,this._format=r(e.format,"image/jpeg"),this._tileDiscardPolicy=e.tileDiscardPolicy,this._tilingScheme=i(e.tilingScheme)?e.tilingScheme:new f({ellipsoid:e.ellipsoid}),this._tileWidth=r(e.tileWidth,256),this._tileHeight=r(e.tileHeight,256),this._minimumLevel=r(e.minimumLevel,0),this._maximumLevel=e.maximumLevel,this._rectangle=r(e.rectangle,this._tilingScheme.rectangle),this._dimensions=e.dimensions;var d=this;this._reload=void 0,i(e.times)&&(this._timeDynamicImagery=new v({clock:e.clock,times:e.times,requestImageFunction:function(e,t,r,i,n){return b(d,e,t,r,i,n)},reloadFunction:function(){i(d._reload)&&d._reload()}})),this._readyPromise=g.resolve(!0);var m=this._tilingScheme.positionToTileXY(h.southwest(this._rectangle),this._minimumLevel),_=this._tilingScheme.positionToTileXY(h.northeast(this._rectangle),this._minimumLevel);Math.abs(_.x-m.x),Math.abs(_.y-m.y);this._errorEvent=new s;var y=e.credit;this._credit="string"==typeof y?new t({text:y}):y,this._subdomains=e.subdomains,u(this._subdomains)?this._subdomains=this._subdomains.slice():i(this._subdomains)&&this._subdomains.length>0?this._subdomains=this._subdomains.split(""):this._subdomains=["a","b","c"]}function b(t,r,n,o,a,s){var l,u=t._tileMatrixLabels,c=i(u)?u[o]:o.toString(),d=t._subdomains,h=t._dimensions,p=i(s)?s.data:void 0;if(t._useKvp){var f={};f.tilematrix=c,f.layer=t._layer,f.style=t._style,f.tilerow=n,f.tilecol=r,f.tilematrixset=t._tileMatrixSetID,f.format=t._format,i(h)&&(f=e(f,h)),i(p)&&(f=e(f,p)),l=t._resource.getDerivedResource({queryParameters:f,request:a})}else{var m={TileMatrix:c,TileRow:n.toString(),TileCol:r.toString(),s:d[(r+n+o)%d.length]};l=t._resource.getDerivedResource({request:a}),l.addTemplateValues(m),i(h)&&l.addTemplateValues(h),i(p)&&l.addTemplateValues(p)}return _.loadImage(t,l)}var C=l({service:"WMTS",version:"1.0.0",request:"GetTile"});return n(y.prototype,{url:{get:function(){return this._resource.url}},proxy:{get:function(){return this._resource.proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return this._minimumLevel}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},format:{get:function(){return this._format}},ready:{value:!0},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!0}},clock:{get:function(){return this._timeDynamicImagery.clock},set:function(e){this._timeDynamicImagery.clock=e}},times:{get:function(){return this._timeDynamicImagery.times},set:function(e){this._timeDynamicImagery.times=e}},dimensions:{get:function(){return this._dimensions},set:function(e){this._dimensions!==e&&(this._dimensions=e,i(this._reload)&&this._reload())}}}),y.prototype.getTileCredits=function(e,t,r){},y.prototype.requestImage=function(e,t,r,n){var o,a,s=this._timeDynamicImagery;return i(s)&&(a=s.currentInterval,o=s.getFromCache(e,t,r,n)),i(o)||(o=b(this,e,t,r,n,a)),i(o)&&i(s)&&s.checkApproachingInterval(e,t,r,n),o},y.prototype.pickFeatures=function(e,t,r,i,n){},y}),define("Scene/CesiumIonResource",["../Core/Check","../Core/defaultValue","../Core/defined","../Core/loadJson","../Core/Resource","../Core/RuntimeError","../ThirdParty/when","./ArcGisMapServerImageryProvider","./BingMapsImageryProvider","./createTileMapServiceImageryProvider","./GoogleEarthEnterpriseMapsProvider","./MapboxImageryProvider","./SingleTileImageryProvider","./UrlTemplateImageryProvider","./WebMapServiceImageryProvider","./WebMapTileServiceImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m){"use strict";function g(e,t,r){n.call(this,e),this.ionEndpoint=t,this.ionEndpointResource=r,this.ionRoot=void 0}function _(e,t){var i,n=function(e,n){return r(n)&&(401===n.statusCode||n.target instanceof Image)?(r(i)||(i=g._loadJson(t).then(function(t){var i=e.ionRoot;return r(i)&&(i.ionEndpoint=t,i.queryParameters.access_token=t.accessToken),t}).always(function(e){return i=void 0,e})),i.then(function(t){return e.ionEndpoint=t,e.queryParameters.access_token=t.accessToken,!0})):a.resolve(!1)};return n._pendingPromise=i,n}return g.create=function(e,t){return new g({url:e.url,retryAttempts:1,queryParameters:{access_token:e.accessToken},retryCallback:_(e,t)},e,t)},r(Object.create)&&(g.prototype=Object.create(n.prototype),g.prototype.constructor=g),g.prototype.clone=function(e){var i=t(this.ionRoot,this);return r(e)||(e=new g({url:this._url},i.ionEndpoint,i.ionEndpointResource)),e=n.prototype.clone.call(this,e),e.ionRoot=i,e.queryParameters.access_token=i.queryParameters.access_token,e},g._CesiumIonResource=g,g._createRetryCallback=_,g._loadJson=i,g}),define("Scene/CesiumIon",["../Core/Check","../Core/clone","../Core/defaultValue","../Core/defined","../Core/loadJson","../Core/Resource","../Core/RuntimeError","../ThirdParty/when","./ArcGisMapServerImageryProvider","./BingMapsImageryProvider","./Cesium3DTileset","./CesiumIonResource","./createTileMapServiceImageryProvider","./GoogleEarthEnterpriseMapsProvider","./MapboxImageryProvider","./SingleTileImageryProvider","./UrlTemplateImageryProvider","./WebMapServiceImageryProvider","./WebMapTileServiceImageryProvider"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(e){return function(t){return new e(t)}}var b={};b.defaultAccessToken=void 0,b.defaultServerUrl="https://api.cesium.com",b.createResource=function(e,t){var r=b._createEndpointResource(e,t) +;return b._loadJson(r).then(function(e){var t=e.externalType;if(!i(t))return d.create(e,r);if("3DTILES"===t||"STK_TERRAIN_SERVER"===t)return new o({url:e.options.url});throw new a("CesiumIon.createResource does not support external imagery assets; use CesiumIon.createImageryProvider instead.")})},b._createEndpointResource=function(e,t){t=r(t,r.EMPTY_OBJECT);var n=r(t.serverUrl,b.defaultServerUrl),a=r(t.accessToken,b.defaultAccessToken),s={url:n+"/v1/assets/"+e+"/endpoint"};return i(a)&&(s.queryParameters={access_token:a}),new o(s)};var C={ARCGIS_MAPSERVER:y(l),BING:y(u),GOOGLE_EARTH:y(p),MAPBOX:y(f),SINGLE_TILE:y(m),TMS:h,URL_TEMPLATE:y(g),WMS:y(_),WMTS:y(v)};return b.createImageryProvider=function(e,t){var r=b._createEndpointResource(e,t);return b._loadJson(r).then(function(t){if("IMAGERY"!==t.type)throw new a("Cesium ion asset "+e+" is not an imagery asset.");var n=t.externalType;if(!i(n))return h({url:d.create(t,r)});var o=C[n];if(!i(o))throw new a("Unrecognized Cesium ion imagery type: "+n);return o(t.options)}).then(function(e){return e.readyPromise.then(function(){return e})})},b.create3DTileset=function(e,n){n=r(n,r.EMPTY_OBJECT);var s=b._createEndpointResource(e,n);return b._loadJson(s).then(function(r){if("3DTILES"!==r.type)throw new a("Cesium ion asset "+e+" is not a 3D Tiles asset.");var l,u=r.externalType;if(i(u)){if("3DTILES"!==u)throw new a("Unrecognized Cesium ion external 3DTILES type: "+u);l=new o({url:r.options.url})}else l=d.create(r,s);var h=n.tilesetOptions;return i(h)?(h=t(h),h.url=l):h={url:l},new c(h).readyPromise})},b._loadJson=function(e){return e.fetchJson()},b}),define("Scene/CircleEmitter",["../Core/Cartesian3","../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/Math"],function(e,t,r,i,n){"use strict";function o(e){e=r(e,1),this._radius=r(e,1)}return i(o.prototype,{radius:{get:function(){return this._radius},set:function(e){this._radius=e}}}),o.prototype.emit=function(t){var r=n.randomBetween(0,n.TWO_PI),i=n.randomBetween(0,this._radius),o=i*Math.cos(r),a=i*Math.sin(r);t.position=e.fromElements(o,a,0,t.position),t.velocity=e.clone(e.UNIT_Z,t.velocity)},o}),define("Scene/ConeEmitter",["../Core/Cartesian3","../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/Math"],function(e,t,r,i,n){"use strict";function o(e){this._angle=r(e,a)}var a=n.toRadians(30);return i(o.prototype,{angle:{get:function(){return this._angle},set:function(e){this._angle=e}}}),o.prototype.emit=function(t){var r=Math.tan(this._angle),i=n.randomBetween(0,n.TWO_PI),o=n.randomBetween(0,r),a=o*Math.cos(i),s=o*Math.sin(i);t.velocity=e.fromElements(a,s,1,t.velocity),e.normalize(t.velocity,t.velocity),t.position=e.clone(e.ZERO,t.position)},o}),define("Scene/createOpenStreetMapImageryProvider",["../Core/appendForwardSlash","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/deprecationWarning","../Core/DeveloperError","../Core/Rectangle","../Core/Resource","../Core/WebMercatorTilingScheme","./UrlTemplateImageryProvider"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(o){o=r(o,{});var c=r(o.url,"https://a.tile.openstreetmap.org/");c=e(c),c+="{z}/{x}/{y}."+r(o.fileExtension,"png"),i(o.proxy)&&n("createOpenStreetMapImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var h=s.createIfNeeded(c,{proxy:o.proxy}),p=new l({ellipsoid:o.ellipsoid}),f=r(o.minimumLevel,0),m=o.maximumLevel,g=r(o.rectangle,p.rectangle),_=p.positionToTileXY(a.southwest(g),f),v=p.positionToTileXY(a.northeast(g),f),y=(Math.abs(v.x-_.x),Math.abs(v.y-_.y),r(o.credit,d));return"string"==typeof y&&(y=new t({text:y})),new u({url:h,credit:y,tilingScheme:p,tileWidth:256,tileHeight:256,minimumLevel:f,maximumLevel:m,rectangle:g})}var d=new t({text:"MapQuest, Open Street Map and contributors, CC-BY-SA"});return c}),define("Scene/createTangentSpaceDebugPrimitive",["../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/DeveloperError","../Core/GeometryInstance","../Core/GeometryPipeline","../Core/Matrix4","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(i){i=t(i,t.EMPTY_OBJECT);var u=[],c=i.geometry;r(c.attributes)&&r(c.primitiveType)||(c=c.constructor.createGeometry(c));var d=c.attributes,h=a.clone(t(i.modelMatrix,a.IDENTITY)),p=t(i.length,1e4);if(r(d.normal)&&u.push(new n({geometry:o.createLineSegmentsForVectors(c,"normal",p),attributes:{color:new e(1,0,0,1)},modelMatrix:h})),r(d.tangent)&&u.push(new n({geometry:o.createLineSegmentsForVectors(c,"tangent",p),attributes:{color:new e(0,1,0,1)},modelMatrix:h})),r(d.bitangent)&&u.push(new n({geometry:o.createLineSegmentsForVectors(c,"bitangent",p),attributes:{color:new e(0,0,1,1)},modelMatrix:h})),u.length>0)return new l({asynchronous:!1,geometryInstances:u,appearance:new s({flat:!0,translucent:!1})})}return u}),define("Scene/CreditDisplay",["../Core/Check","../Core/Credit","../Core/defaultValue","../Core/defined","../Core/destroyObject"],function(e,t,r,i,n){"use strict";function o(e,t){if(!i(e.element)){var r=e.text,n=e.link;if(e.hasLink()){var o=document.createElement("a");o.textContent=r,o.href=n,o.target="_blank",t.appendChild(o)}else t.textContent=r;return t.className="cesium-credit-text",e.element=t,t}return e.element}function a(e,t,r){if(!i(e.element)){var n=e.text,o=e.link,a=document.createElement("img");if(a.src=e.imageUrl,a.style["vertical-align"]=r?"middle":"bottom",i(n)&&(a.alt=n,a.title=n),e.hasLink()){var s=document.createElement("a");s.appendChild(a),s.href=o,s.target="_blank",t.appendChild(s)}else t.appendChild(a);t.className="cesium-credit-image",e.element=t}return e.element}function s(e,r){for(var i=e.length,n=0;n<i;n++){var o=e[n];if(t.equals(o,r))return!0}return!1}function l(e,t){var r,n,a,s=e._displayedCredits.textCredits,l=e._textContainer;for(r=0;r<t.length;r++)if(a=t[r],i(a))if(-1===(n=s.indexOf(a))){var u=o(a,document.createElement("span"));if(i(u)){if(l.hasChildNodes()){var c=document.createElement("span");c.textContent=e._delimiter,c.className="cesium-credit-delimiter",l.appendChild(c)}l.appendChild(u)}}else s.splice(n,1)}function u(e,t){var r,n,o,s=e._displayedCredits.imageCredits,l=e._imageContainer;for(r=0;r<t.length;r++)if(o=t[r],i(o))if(-1===(n=s.indexOf(o))){var u=a(o,document.createElement("span"),!1);l.appendChild(u)}else s.splice(n,1)}function c(e,t){var r,n,s,l=e._displayedCredits.lightboxCredits,u=e._creditList;for(r=0;r<t.length;r++)if(s=t[r],i(s))if(-1===(n=l.indexOf(s))){var c;c=s.hasImage()?a(s,document.createElement("li"),!0):o(s,document.createElement("li")),u.appendChild(c)}else l.splice(n,1)}function d(e){var t=e.element;if(i(t)){var r=t.parentNode;if(!e.hasImage()&&e.showOnScreen){var n=t.previousSibling;null===n&&(n=t.nextSibling),null!==n&&r.removeChild(n)}r.removeChild(t)}}function h(e){var t,r,n=e._displayedCredits.textCredits;for(t=0;t<n.length;t++)r=n[t],i(r)&&d(r);var o=e._displayedCredits.imageCredits;for(t=0;t<o.length;t++)r=o[t],i(r)&&d(r)}function p(e){var t,r,n=e._displayedCredits.lightboxCredits;for(t=0;t<n.length;t++)r=n[t],i(r)&&d(r)}function f(e){var t=e._lightboxCredits,r=e.viewport.clientWidth,i=e.viewport.clientHeight;r!==e._lastViewportWidth&&(r<v?(t.className="cesium-credit-lightbox cesium-credit-lightbox-mobile",t.style.marginTop="0"):(t.className="cesium-credit-lightbox cesium-credit-lightbox-expanded",t.style.marginTop=Math.floor(.5*(i-t.clientHeight))+"px"),e._lastViewportWidth=r),r>=v&&i!==e._lastViewportHeight&&(t.style.marginTop=Math.floor(.5*(i-t.clientHeight))+"px",e._lastViewportHeight=i)}function m(e,t){var r=e+" {";for(var i in t)t.hasOwnProperty(i)&&(r+=i+": "+t[i]+"; ");return r+=" }\n"}function g(){var e=document.head,t=document.createElement("style"),r="";r+=m(".cesium-credit-lightbox-overlay",{display:"none","z-index":"1",position:"absolute",top:"0",left:"0",width:"100%",height:"100%","background-color":"rgba(80, 80, 80, 0.8)"}),r+=m(".cesium-credit-lightbox",{"background-color":"#303336",color:b,position:"relative","min-height":y+"px",margin:"auto"}),r+=m(".cesium-credit-lightbox > ul > li > a, .cesium-credit-lightbox > ul > li > a:visited",{color:b}),r+=m(".cesium-credit-lightbox > ul > li > a:hover",{color:C}),r+=m(".cesium-credit-lightbox.cesium-credit-lightbox-expanded",{border:"1px solid #444","border-radius":"5px","max-width":"370px"}),r+=m(".cesium-credit-lightbox.cesium-credit-lightbox-mobile",{height:"100%",width:"100%"}),r+=m(".cesium-credit-lightbox-title",{padding:"20px 20px 0 20px"}),r+=m(".cesium-credit-lightbox-close",{"font-size":"18pt",cursor:"pointer",position:"absolute",top:"0",right:"6px",color:b}),r+=m(".cesium-credit-lightbox-close:hover",{color:C}),r+=m(".cesium-credit-lightbox > ul",{margin:"0",padding:"12px 20px 12px 40px","font-size":"13px"}),r+=m(".cesium-credit-lightbox > ul > li",{"padding-bottom":"6px"}),r+=m(".cesium-credit-expand-link",{"padding-left":"5px",cursor:"pointer","text-decoration":"underline",color:b}),r+=m(".cesium-credit-expand-link:hover",{color:C}),r+=m(".cesium-credit-text",{color:b}),t.innerHTML=r,e.insertBefore(t,e.firstChild)}function _(e,t,i){var n=this;i=r(i,document.body);var o=document.createElement("div");o.className="cesium-credit-lightbox-overlay",i.appendChild(o);var a=document.createElement("div");a.className="cesium-credit-lightbox",o.appendChild(a),o.onclick=function(e){e.target!==a&&n.hideLightbox()};var s=document.createElement("div");s.className="cesium-credit-lightbox-title",s.textContent="Data provided by:",a.appendChild(s);var l=document.createElement("a");l.onclick=this.hideLightbox.bind(this),l.innerHTML="×",l.className="cesium-credit-lightbox-close",a.appendChild(l);var u=document.createElement("ul");a.appendChild(u);var c=document.createElement("span");c.className="cesium-credit-imageContainer",e.appendChild(c);var d=document.createElement("span");d.className="cesium-credit-textContainer",e.appendChild(d);var h=document.createElement("a");h.className="cesium-credit-expand-link",h.onclick=this.showLightbox.bind(this),h.textContent="Data attribution",e.appendChild(h),g(),this._delimiter=r(t," • "),this._textContainer=d,this._imageContainer=c,this._lastViewportHeight=void 0,this._lastViewportWidth=void 0,this._lightboxCredits=a,this._creditList=u,this._lightbox=o,this._expandLink=h,this._expanded=!1,this._defaultImageCredits=[],this._defaultTextCredits=[],this._displayedCredits={imageCredits:[],textCredits:[],lightboxCredits:[]},this._currentFrameCredits={imageCredits:[],textCredits:[],lightboxCredits:[]},this.viewport=i,this.container=e}var v=576,y=100,b="#ffffff",C="#48b";return _.prototype.addCredit=function(e){e.showOnScreen?e.hasImage()?this._currentFrameCredits.imageCredits[e.id]=e:this._currentFrameCredits.textCredits[e.id]=e:this._currentFrameCredits.lightboxCredits[e.id]=e},_.prototype.addDefaultCredit=function(e){if(e.hasImage()){var t=this._defaultImageCredits;s(t,e)||t.push(e)}else{var r=this._defaultTextCredits;s(r,e)||r.push(e)}},_.prototype.removeDefaultCredit=function(e){var t;e.hasImage()?-1!==(t=this._defaultImageCredits.indexOf(e))&&this._defaultImageCredits.splice(t,1):-1!==(t=this._defaultTextCredits.indexOf(e))&&this._defaultTextCredits.splice(t,1)},_.prototype.showLightbox=function(){this._lightbox.style.display="block",this._expanded=!0},_.prototype.hideLightbox=function(){this._lightbox.style.display="none",this._expanded=!1},_.prototype.update=function(){var e=[];this._expanded&&i(this._creditsToUpdate)&&(f(this),c(this,this._creditsToUpdate),e=this._creditsToUpdate.slice()),p(this),this._displayedCredits.lightboxCredits=e},_.prototype.beginFrame=function(){this._currentFrameCredits.imageCredits.length=0,this._currentFrameCredits.textCredits.length=0,this._currentFrameCredits.lightboxCredits.length=0},_.prototype.endFrame=function(){u(this,this._defaultImageCredits),l(this,this._defaultTextCredits),u(this,this._currentFrameCredits.imageCredits),l(this,this._currentFrameCredits.textCredits);var e=this._defaultTextCredits.concat(this._currentFrameCredits.textCredits),t=this._defaultImageCredits.concat(this._currentFrameCredits.imageCredits),r=this._currentFrameCredits.lightboxCredits.length>0;this._expandLink.style.display=r?"inline":"none",h(this),this._displayedCredits.textCredits=e,this._displayedCredits.imageCredits=t,this._creditsToUpdate=this._currentFrameCredits.lightboxCredits.slice()},_.prototype.destroy=function(){return this.container.removeChild(this._textContainer),this.container.removeChild(this._imageContainer),this.container.removeChild(this._expandLink),this.viewport.removeChild(this._lightbox),n(this)},_.prototype.isDestroyed=function(){return!1},_}),define("Scene/DebugAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","./Appearance"],function(e,t,r,i,n){"use strict";function o(r){r=e(r,e.EMPTY_OBJECT);var i=r.attributeName,o=r.perInstanceAttribute;t(o)||(o=!1);var a,s=e(r.glslDatatype,"vec3"),l="v_"+i;if("normal"===i||"tangent"===i||"bitangent"===i)a="vec4 getColor() { return vec4(("+l+" + vec3(1.0)) * 0.5, 1.0); }\n";else switch("st"===i&&(s="vec2"),s){case"float":a="vec4 getColor() { return vec4(vec3("+l+"), 1.0); }\n";break;case"vec2":a="vec4 getColor() { return vec4("+l+", 0.0, 1.0); }\n";break;case"vec3":a="vec4 getColor() { return vec4("+l+", 1.0); }\n";break;case"vec4":a="vec4 getColor() { return "+l+"; }\n"}var u="attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute float batchId;\n"+(o?"":"attribute "+s+" "+i+";\n")+"varying "+s+" "+l+";\nvoid main()\n{\nvec4 p = czm_translateRelativeToEye(position3DHigh, position3DLow);\n"+(o?l+" = czm_batchTable_"+i+"(batchId);\n":l+" = "+i+";\n")+"gl_Position = czm_modelViewProjectionRelativeToEye * p;\n}",c="varying "+s+" "+l+";\n"+a+"\nvoid main()\n{\ngl_FragColor = getColor();\n}";this.material=void 0,this.translucent=e(r.translucent,!1),this._vertexShaderSource=e(r.vertexShaderSource,u),this._fragmentShaderSource=e(r.fragmentShaderSource,c),this._renderState=n.getDefaultRenderState(!1,!1,r.renderState),this._closed=e(r.closed,!1),this._attributeName=i,this._glslDatatype=s}return r(o.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},attributeName:{get:function(){return this._attributeName}},glslDatatype:{get:function(){return this._glslDatatype}}}),o.prototype.getFragmentShaderSource=n.prototype.getFragmentShaderSource,o.prototype.isTranslucent=n.prototype.isTranslucent,o.prototype.getRenderState=n.prototype.getRenderState,o}),define("Scene/DebugCameraPrimitive",["../Core/Cartesian3","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/FrustumGeometry","../Core/FrustumOutlineGeometry","../Core/GeometryInstance","../Core/Matrix3","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/PerspectiveOffCenterFrustum","../Core/Quaternion","./PerInstanceColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(e){e=i(e,i.EMPTY_OBJECT),this._camera=e.camera,this._color=i(e.color,t.CYAN),this._updateOnChange=i(e.updateOnChange,!0),this.show=i(e.show,!0),this.id=e.id,this._id=void 0,this._outlinePrimitives=[],this._planesPrimitives=[]}var y=new e,b=new c,C=new m,S=new p,w=new f,T=new d,E=new h,A=new t,x=[1,1e5];return v.prototype.update=function(i){if(this.show){var n,o,a=this._planesPrimitives,h=this._outlinePrimitives;if(this._updateOnChange){for(o=a.length,n=0;n<o;++n)h[n]=h[n]&&h[n].destroy(),a[n]=a[n]&&a[n].destroy();a.length=0,h.length=0}if(0===a.length){var v,P=this._camera,D=P.frustum;v=D instanceof p?S:D instanceof f?w:D instanceof d?T:E,v=D.clone(v);var I=i.frustumSplits,O=I.length-1;O<=0&&(I=x,I[0]=this._camera.frustum.near,I[1]=this._camera.frustum.far,O=1);var M=P.positionWC,R=P.directionWC,L=P.upWC,N=P.rightWC;N=e.negate(N,y);var k=b;c.setColumn(k,0,N,k),c.setColumn(k,1,L,k),c.setColumn(k,2,R,k);var F=m.fromRotationMatrix(k,C);for(a.length=h.length=O,n=0;n<O;++n)v.near=I[n],v.far=I[n+1],a[n]=new _({geometryInstances:new u({geometry:new s({origin:M,orientation:F,frustum:v,_drawNearPlane:0===n}),attributes:{color:r.fromColor(t.fromAlpha(this._color,.1,A))},id:this.id,pickPrimitive:this}),appearance:new g({translucent:!0,flat:!0}),asynchronous:!1}),h[n]=new _({geometryInstances:new u({geometry:new l({origin:M,orientation:F,frustum:v,_drawNearPlane:0===n}),attributes:{color:r.fromColor(this._color)},id:this.id,pickPrimitive:this}),appearance:new g({translucent:!1,flat:!0}),asynchronous:!1})}for(o=a.length,n=0;n<o;++n)h[n].update(i),a[n].update(i)}},v.prototype.isDestroyed=function(){return!1},v.prototype.destroy=function(){for(var e=this._planesPrimitives.length,t=0;t<e;++t)this._outlinePrimitives[t]=this._outlinePrimitives[t]&&this._outlinePrimitives[t].destroy(),this._planesPrimitives[t]=this._planesPrimitives[t]&&this._planesPrimitives[t].destroy();return o(this)},v}),define("Scene/DebugModelMatrixPrimitive",["../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/GeometryInstance","../Core/Matrix4","../Core/PolylineGeometry","./PolylineColorAppearance","./Primitive"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(e){e=r(e,r.EMPTY_OBJECT),this.length=r(e.length,1e7),this._length=void 0,this.width=r(e.width,2),this._width=void 0,this.show=r(e.show,!0),this.modelMatrix=a.clone(r(e.modelMatrix,a.IDENTITY)),this._modelMatrix=new a,this.id=e.id,this._id=void 0,this._primitive=void 0}return c.prototype.update=function(r){if(this.show){if(!i(this._primitive)||!a.equals(this._modelMatrix,this.modelMatrix)||this._length!==this.length||this._width!==this.width||this._id!==this.id){this._modelMatrix=a.clone(this.modelMatrix,this._modelMatrix),this._length=this.length,this._width=this.width,this._id=this.id,i(this._primitive)&&this._primitive.destroy(),0===this.modelMatrix[12]&&0===this.modelMatrix[13]&&0===this.modelMatrix[14]&&(this.modelMatrix[14]=.01);var n=new o({geometry:new s({positions:[e.ZERO,e.UNIT_X],width:this.width,vertexFormat:l.VERTEX_FORMAT,colors:[t.RED,t.RED],followSurface:!1}),modelMatrix:a.multiplyByUniformScale(this.modelMatrix,this.length,new a),id:this.id,pickPrimitive:this}),c=new o({geometry:new s({positions:[e.ZERO,e.UNIT_Y],width:this.width,vertexFormat:l.VERTEX_FORMAT,colors:[t.GREEN,t.GREEN],followSurface:!1}),modelMatrix:a.multiplyByUniformScale(this.modelMatrix,this.length,new a),id:this.id,pickPrimitive:this}),d=new o({geometry:new s({positions:[e.ZERO,e.UNIT_Z],width:this.width,vertexFormat:l.VERTEX_FORMAT,colors:[t.BLUE,t.BLUE],followSurface:!1}),modelMatrix:a.multiplyByUniformScale(this.modelMatrix,this.length,new a),id:this.id,pickPrimitive:this});this._primitive=new u({geometryInstances:[n,c,d],appearance:new l,asynchronous:!1})}this._primitive.update(r)}},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return this._primitive=this._primitive&&this._primitive.destroy(),n(this)},c}),define("Shaders/DepthPlaneFS",[],function(){"use strict";return"varying vec4 positionEC;\nvoid main()\n{\nczm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\nvec3 direction = normalize(positionEC.xyz);\nczm_ray ray = czm_ray(vec3(0.0), direction);\nczm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);\nif (!czm_isEmpty(intersection))\n{\ngl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n}\nelse\n{\ndiscard;\n}\n}\n"}),define("Shaders/DepthPlaneVS",[],function(){"use strict";return"attribute vec4 position;\nvarying vec4 positionEC;\nvoid main()\n{\npositionEC = czm_modelView * position;\ngl_Position = czm_projection * positionEC;\n}\n"}),define("Scene/DepthPlane",["../Core/BoundingSphere","../Core/Cartesian3","../Core/ComponentDatatype","../Core/defined","../Core/FeatureDetection","../Core/Geometry","../Core/GeometryAttribute","../Core/PrimitiveType","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/VertexArray","../Shaders/DepthPlaneFS","../Shaders/DepthPlaneVS","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(){this._rs=void 0,this._sp=void 0,this._va=void 0,this._command=void 0,this._mode=void 0}function v(e,r){var i=e.radii,n=r.camera.positionWC,o=t.multiplyComponents(e.oneOverRadii,n,b),a=t.magnitude(o),s=t.normalize(o,C),l=t.normalize(t.cross(t.UNIT_Z,o,S),S),u=t.normalize(t.cross(s,l,w),w),c=Math.sqrt(t.magnitudeSquared(o)-1),d=t.multiplyByScalar(s,1/a,b),h=c/a,p=t.multiplyByScalar(l,h,C),f=t.multiplyByScalar(u,h,S),m=t.add(d,f,w);t.subtract(m,p,m),t.multiplyComponents(i,m,m),t.pack(m,y,0);var g=t.subtract(d,f,w);t.subtract(g,p,g),t.multiplyComponents(i,g,g),t.pack(g,y,3);var _=t.add(d,f,w);t.add(_,p,_),t.multiplyComponents(i,_,_),t.pack(_,y,6);var v=t.subtract(d,f,w);return t.add(v,p,v),t.multiplyComponents(i,v,v),t.pack(v,y,9),y}var y=n.supportsTypedArrays()?new Float32Array(12):[],b=new t,C=new t,S=new t,w=new t;return _.prototype.update=function(n){if(this._mode=n.mode,n.mode===g.SCENE3D){var _=n.context,y=n.mapProjection.ellipsoid;i(this._command)||(this._rs=d.fromCache({cull:{enabled:!0},depthTest:{enabled:!0},colorMask:{red:!1,green:!1,blue:!1,alpha:!1}}),this._sp=h.fromCache({context:_,vertexShaderSource:m,fragmentShaderSource:f,attributeLocations:{position:0}}),this._command=new u({renderState:this._rs,shaderProgram:this._sp,boundingVolume:new e(t.ZERO,y.maximumRadius),pass:c.OPAQUE,owner:this}));var b=v(y,n);if(i(this._va))this._va.getAttribute(0).vertexBuffer.copyFromArrayView(b);else{var C=new o({attributes:{position:new a({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:b})},indices:[0,1,2,2,1,3],primitiveType:s.TRIANGLES});this._va=p.fromGeometry({context:_,geometry:C,attributeLocations:{position:0},bufferUsage:l.DYNAMIC_DRAW}),this._command.vertexArray=this._va}}},_.prototype.execute=function(e,t){this._mode===g.SCENE3D&&this._command.execute(e,t)},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){this._sp=this._sp&&this._sp.destroy(),this._va=this._va&&this._va.destroy()},_}),define("Scene/DeviceOrientationCameraController",["../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Math","../Core/Matrix3","../Core/Quaternion"],function(e,t,r,i,n,o){"use strict";function a(t){function r(t){var r=t.alpha;if(!e(r))return n._alpha=void 0,n._beta=void 0,void(n._gamma=void 0);n._alpha=i.toRadians(r),n._beta=i.toRadians(t.beta),n._gamma=i.toRadians(t.gamma)}this._scene=t,this._lastAlpha=void 0,this._lastBeta=void 0,this._lastGamma=void 0,this._alpha=void 0,this._beta=void 0,this._gamma=void 0;var n=this;window.addEventListener("deviceorientation",r,!1),this._removeListener=function(){window.removeEventListener("deviceorientation",r,!1)}}function s(e,t,r,i){var a=e.direction,s=e.right,d=e.up,h=o.fromAxisAngle(a,r,u),p=o.fromAxisAngle(s,i,l),f=o.multiply(p,h,p),m=o.fromAxisAngle(d,t,u);o.multiply(m,f,f);var g=n.fromQuaternion(f,c);n.multiplyByVector(g,s,s),n.multiplyByVector(g,d,d),n.multiplyByVector(g,a,a)}var l=new o,u=new o,c=new n;return a.prototype.update=function(){if(e(this._alpha)){e(this._lastAlpha)||(this._lastAlpha=this._alpha,this._lastBeta=this._beta,this._lastGamma=this._gamma);var t=this._lastAlpha-this._alpha,r=this._lastBeta-this._beta,i=this._lastGamma-this._gamma;s(this._scene.camera,-t,r,i),this._lastAlpha=this._alpha,this._lastBeta=this._beta,this._lastGamma=this._gamma}},a.prototype.isDestroyed=function(){return!1},a.prototype.destroy=function(){return this._removeListener(),t(this)},a}),define("Shaders/EllipsoidFS",[],function(){"use strict";return"#ifdef WRITE_DEPTH\n#ifdef GL_EXT_frag_depth\n#extension GL_EXT_frag_depth : enable\n#endif\n#endif\nuniform vec3 u_radii;\nuniform vec3 u_oneOverEllipsoidRadiiSquared;\nvarying vec3 v_positionEC;\nvec4 computeEllipsoidColor(czm_ray ray, float intersection, float side)\n{\nvec3 positionEC = czm_pointAlongRay(ray, intersection);\nvec3 positionMC = (czm_inverseModelView * vec4(positionEC, 1.0)).xyz;\nvec3 geodeticNormal = normalize(czm_geodeticSurfaceNormal(positionMC, vec3(0.0), u_oneOverEllipsoidRadiiSquared));\nvec3 sphericalNormal = normalize(positionMC / u_radii);\nvec3 normalMC = geodeticNormal * side;\nvec3 normalEC = normalize(czm_normal * normalMC);\nvec2 st = czm_ellipsoidWgs84TextureCoordinates(sphericalNormal);\nvec3 positionToEyeEC = -positionEC;\nczm_materialInput materialInput;\nmaterialInput.s = st.s;\nmaterialInput.st = st;\nmaterialInput.str = (positionMC + u_radii) / u_radii;\nmaterialInput.normalEC = normalEC;\nmaterialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(positionMC, normalEC);\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef ONLY_SUN_LIGHTING\nreturn czm_private_phong(normalize(positionToEyeEC), material);\n#else\nreturn czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\nvoid main()\n{\nfloat maxRadius = max(u_radii.x, max(u_radii.y, u_radii.z)) * 1.5;\nvec3 direction = normalize(v_positionEC);\nvec3 ellipsoidCenter = czm_modelView[3].xyz;\nfloat t1 = -1.0;\nfloat t2 = -1.0;\nfloat b = -2.0 * dot(direction, ellipsoidCenter);\nfloat c = dot(ellipsoidCenter, ellipsoidCenter) - maxRadius * maxRadius;\nfloat discriminant = b * b - 4.0 * c;\nif (discriminant >= 0.0) {\nt1 = (-b - sqrt(discriminant)) * 0.5;\nt2 = (-b + sqrt(discriminant)) * 0.5;\n}\nif (t1 < 0.0 && t2 < 0.0) {\ndiscard;\n}\nfloat t = min(t1, t2);\nif (t < 0.0) {\nt = 0.0;\n}\nczm_ellipsoid ellipsoid = czm_ellipsoidNew(ellipsoidCenter, u_radii);\nczm_ray ray = czm_ray(t * direction, direction);\nczm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);\nif (czm_isEmpty(intersection))\n{\ndiscard;\n}\nvec4 outsideFaceColor = (intersection.start != 0.0) ? computeEllipsoidColor(ray, intersection.start, 1.0) : vec4(0.0);\nvec4 insideFaceColor = (outsideFaceColor.a < 1.0) ? computeEllipsoidColor(ray, intersection.stop, -1.0) : vec4(0.0);\ngl_FragColor = mix(insideFaceColor, outsideFaceColor, outsideFaceColor.a);\ngl_FragColor.a = 1.0 - (1.0 - insideFaceColor.a) * (1.0 - outsideFaceColor.a);\n#ifdef WRITE_DEPTH\n#ifdef GL_EXT_frag_depth\nt = (intersection.start != 0.0) ? intersection.start : intersection.stop;\nvec3 positionEC = czm_pointAlongRay(ray, t);\nvec4 positionCC = czm_projection * vec4(positionEC, 1.0);\nfloat z = positionCC.z / positionCC.w;\nfloat n = czm_depthRange.near;\nfloat f = czm_depthRange.far;\ngl_FragDepthEXT = (z * (f - n) + f + n) * 0.5;\n#endif\n#endif\n}\n"}),define("Shaders/EllipsoidVS",[],function(){"use strict";return"attribute vec3 position;\nuniform vec3 u_radii;\nvarying vec3 v_positionEC;\nvoid main()\n{\nvec4 p = vec4(u_radii * position, 1.0);\nv_positionEC = (czm_modelView * p).xyz;\ngl_Position = czm_modelViewProjection * p;\ngl_Position.z = clamp(gl_Position.z, czm_depthRange.near, czm_depthRange.far);\n}\n"}),define("Scene/EllipsoidPrimitive",["../Core/BoundingSphere","../Core/BoxGeometry","../Core/Cartesian3","../Core/combine","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Matrix4","../Core/VertexFormat","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../Shaders/EllipsoidFS","../Shaders/EllipsoidVS","./BlendingState","./CullFace","./Material","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S){"use strict";function w(t){t=n(t,n.EMPTY_OBJECT),this.center=r.clone(n(t.center,r.ZERO)),this._center=new r,this.radii=r.clone(t.radii),this._radii=new r,this._oneOverEllipsoidRadiiSquared=new r,this._boundingSphere=new e,this.modelMatrix=l.clone(n(t.modelMatrix,l.IDENTITY)),this._modelMatrix=new l,this._computedModelMatrix=new l,this.show=n(t.show,!0),this.material=n(t.material,C.fromType(C.ColorType)),this._material=void 0,this._translucent=void 0,this.id=t.id,this._id=void 0,this.debugShowBoundingVolume=n(t.debugShowBoundingVolume,!1),this.onlySunLighting=n(t.onlySunLighting,!1),this._onlySunLighting=!1,this._depthTestEnabled=n(t.depthTestEnabled,!0),this._sp=void 0,this._rs=void 0,this._va=void 0,this._pickSP=void 0,this._pickId=void 0,this._colorCommand=new d({owner:n(t._owner,this)}),this._pickCommand=new d({owner:n(t._owner,this)});var i=this;this._uniforms={u_radii:function(){return i.radii},u_oneOverEllipsoidRadiiSquared:function(){return i._oneOverEllipsoidRadiiSquared}},this._pickUniforms={czm_pickColor:function(){return i._pickId.color}}}function T(e){var i=e.cache.ellipsoidPrimitive_vertexArray;if(o(i))return i;var n=t.createGeometry(t.fromDimensions({dimensions:new r(2,2,2),vertexFormat:u.POSITION_ONLY}));return i=g.fromGeometry({context:e,geometry:n,attributeLocations:E,bufferUsage:c.STATIC_DRAW,interleave:!0}),e.cache.ellipsoidPrimitive_vertexArray=i,i}var E={position:0};return w.prototype.update=function(t){if(this.show&&t.mode===S.SCENE3D&&o(this.center)&&o(this.radii)){var n=t.context,a=this.material.isTranslucent(),s=this._translucent!==a;o(this._rs)&&!s||(this._translucent=a,this._rs=p.fromCache({cull:{enabled:!0,face:b.FRONT},depthTest:{enabled:this._depthTestEnabled},depthMask:!a&&n.fragmentDepth,blending:a?y.ALPHA_BLEND:void 0})),o(this._va)||(this._va=T(n));var u=!1,c=this.radii;if(!r.equals(this._radii,c)){r.clone(c,this._radii);var d=this._oneOverEllipsoidRadiiSquared;d.x=1/(c.x*c.x),d.y=1/(c.y*c.y),d.z=1/(c.z*c.z),u=!0}l.equals(this.modelMatrix,this._modelMatrix)&&r.equals(this.center,this._center)||(l.clone(this.modelMatrix,this._modelMatrix),r.clone(this.center,this._center),l.multiplyByTranslation(this.modelMatrix,this.center,this._computedModelMatrix),u=!0),u&&(r.clone(r.ZERO,this._boundingSphere.center),this._boundingSphere.radius=r.maximumComponent(c),e.transform(this._boundingSphere,this._computedModelMatrix,this._boundingSphere));var g=this._material!==this.material;this._material=this.material,this._material.update(n);var C=this.onlySunLighting!==this._onlySunLighting;this._onlySunLighting=this.onlySunLighting;var w,A=this._colorCommand;(g||C||s)&&(w=new m({sources:[this.material.shaderSource,_]}),this.onlySunLighting&&w.defines.push("ONLY_SUN_LIGHTING"),!a&&n.fragmentDepth&&w.defines.push("WRITE_DEPTH"),this._sp=f.replaceCache({context:n,shaderProgram:this._sp,vertexShaderSource:v,fragmentShaderSource:w,attributeLocations:E}),A.vertexArray=this._va,A.renderState=this._rs,A.shaderProgram=this._sp,A.uniformMap=i(this._uniforms,this.material._uniforms),A.executeInClosestFrustum=a);var x=t.commandList,P=t.passes;if(P.render&&(A.boundingVolume=this._boundingSphere,A.debugShowBoundingVolume=this.debugShowBoundingVolume,A.modelMatrix=this._computedModelMatrix,A.pass=a?h.TRANSLUCENT:h.OPAQUE,x.push(A)),P.pick){var D=this._pickCommand;o(this._pickId)&&this._id===this.id||(this._id=this.id,this._pickId=this._pickId&&this._pickId.destroy(),this._pickId=n.createPickId({primitive:this,id:this.id})),(g||C||!o(this._pickSP))&&(w=new m({sources:[this.material.shaderSource,_],pickColorQualifier:"uniform"}),this.onlySunLighting&&w.defines.push("ONLY_SUN_LIGHTING"),!a&&n.fragmentDepth&&w.defines.push("WRITE_DEPTH"),this._pickSP=f.replaceCache({context:n,shaderProgram:this._pickSP,vertexShaderSource:v,fragmentShaderSource:w,attributeLocations:E}),D.vertexArray=this._va,D.renderState=this._rs,D.shaderProgram=this._pickSP,D.uniformMap=i(i(this._uniforms,this._pickUniforms),this.material._uniforms),D.executeInClosestFrustum=a),D.boundingVolume=this._boundingSphere,D.modelMatrix=this._computedModelMatrix, +D.pass=a?h.TRANSLUCENT:h.OPAQUE,x.push(D)}}},w.prototype.isDestroyed=function(){return!1},w.prototype.destroy=function(){return this._sp=this._sp&&this._sp.destroy(),this._pickSP=this._pickSP&&this._pickSP.destroy(),this._pickId=this._pickId&&this._pickId.destroy(),a(this)},w}),define("Shaders/Appearances/EllipsoidSurfaceAppearanceFS",[],function(){"use strict";return"varying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec2 v_st;\nvoid main()\n{\nczm_materialInput materialInput;\nvec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n#ifdef FACE_FORWARD\nnormalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n#endif\nmaterialInput.s = v_st.s;\nmaterialInput.st = v_st;\nmaterialInput.str = vec3(v_st, 0.0);\nmaterialInput.normalEC = normalEC;\nmaterialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\nvec3 positionToEyeEC = -v_positionEC;\nmaterialInput.positionToEyeEC = positionToEyeEC;\nczm_material material = czm_getMaterial(materialInput);\n#ifdef FLAT\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n#else\ngl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n#endif\n}\n"}),define("Shaders/Appearances/EllipsoidSurfaceAppearanceVS",[],function(){"use strict";return"attribute vec3 position3DHigh;\nattribute vec3 position3DLow;\nattribute vec2 st;\nattribute float batchId;\nvarying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec2 v_st;\nvoid main()\n{\nvec4 p = czm_computePosition();\nv_positionMC = position3DHigh + position3DLow;\nv_positionEC = (czm_modelViewRelativeToEye * p).xyz;\nv_st = st;\ngl_Position = czm_modelViewProjectionRelativeToEye * p;\n}\n"}),define("Scene/EllipsoidSurfaceAppearance",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/VertexFormat","../Shaders/Appearances/EllipsoidSurfaceAppearanceFS","../Shaders/Appearances/EllipsoidSurfaceAppearanceVS","./Appearance","./Material"],function(e,t,r,i,n,o,a,s){"use strict";function l(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.translucent,!0),l=e(r.aboveGround,!1);this.material=t(r.material)?r.material:s.fromType(s.ColorType),this.translucent=e(r.translucent,!0),this._vertexShaderSource=e(r.vertexShaderSource,o),this._fragmentShaderSource=e(r.fragmentShaderSource,n),this._renderState=a.getDefaultRenderState(i,!l,r.renderState),this._closed=!1,this._flat=e(r.flat,!1),this._faceForward=e(r.faceForward,l),this._aboveGround=l}return r(l.prototype,{vertexShaderSource:{get:function(){return this._vertexShaderSource}},fragmentShaderSource:{get:function(){return this._fragmentShaderSource}},renderState:{get:function(){return this._renderState}},closed:{get:function(){return this._closed}},vertexFormat:{get:function(){return l.VERTEX_FORMAT}},flat:{get:function(){return this._flat}},faceForward:{get:function(){return this._faceForward}},aboveGround:{get:function(){return this._aboveGround}}}),l.VERTEX_FORMAT=i.POSITION_AND_ST,l.prototype.getFragmentShaderSource=a.prototype.getFragmentShaderSource,l.prototype.isTranslucent=a.prototype.isTranslucent,l.prototype.getRenderState=a.prototype.getRenderState,l}),define("Scene/Fog",["../Core/Cartesian3","../Core/defined","../Core/Math","./SceneMode"],function(e,t,r,i){"use strict";function n(){this.enabled=!0,this.density=2e-4,this.screenSpaceErrorFactor=2,this.minimumBrightness=.1}function o(e){var t=a,r=t.length;if(e<t[0])return h=0;if(e>t[r-1])return h=r-2;if(e>=t[h]){if(h+1<r&&e<t[h+1])return h;if(h+2<r&&e<t[h+2])return++h}else if(h-1>=0&&e>=t[h-1])return--h;var i;for(i=0;i<r-2&&!(e>=t[i]&&e<t[i+1]);++i);return h=i}for(var a=[359.393,800.749,1275.6501,2151.1192,3141.7763,4777.5198,6281.2493,12364.307,15900.765,49889.0549,78026.8259,99260.7344,120036.3873,151011.0158,156091.1953,203849.3112,274866.9803,319916.3149,493552.0528,628733.5874],s=[2e-5,2e-4,1e-4,7e-5,5e-5,4e-5,3e-5,19e-6,1e-5,85e-7,62e-7,58e-7,53e-7,52e-7,51e-7,42e-7,4e-6,34e-7,26e-7,22e-7],l=0;l<s.length;++l)s[l]*=1e6;for(var u=s[1],c=s[s.length-1],d=0;d<s.length;++d)s[d]=(s[d]-c)/(u-c);var h=0,p=new e;return n.prototype.update=function(n){if(n.fog.enabled=this.enabled){var l=n.camera,d=l.positionCartographic;if(!t(d)||d.height>8e5||n.mode!==i.SCENE3D)return void(n.fog.enabled=!1);var h=d.height,f=o(h),m=r.clamp((h-a[f])/(a[f+1]-a[f]),0,1),g=r.lerp(s[f],s[f+1],m),_=1e6*this.density;g=g*(_-_/u*c)*1e-6;var v=e.normalize(l.positionWC,p);g*=1-Math.abs(e.dot(l.directionWC,v)),n.fog.density=g,n.fog.sse=this.screenSpaceErrorFactor,n.fog.minimumBrightness=this.minimumBrightness}},n}),define("Scene/FrameRateMonitor",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../Core/getTimestamp","../Core/TimeConstants"],function(e,t,r,i,n,o,a,s){"use strict";function l(r){function i(){c(n)}this._scene=r.scene,this.samplingWindow=e(r.samplingWindow,l.defaultSettings.samplingWindow),this.quietPeriod=e(r.quietPeriod,l.defaultSettings.quietPeriod),this.warmupPeriod=e(r.warmupPeriod,l.defaultSettings.warmupPeriod),this.minimumFrameRateDuringWarmup=e(r.minimumFrameRateDuringWarmup,l.defaultSettings.minimumFrameRateDuringWarmup),this.minimumFrameRateAfterWarmup=e(r.minimumFrameRateAfterWarmup,l.defaultSettings.minimumFrameRateAfterWarmup),this._lowFrameRate=new o,this._nominalFrameRate=new o,this._frameTimes=[],this._needsQuietPeriod=!0,this._quietPeriodEndTime=0,this._warmupPeriodEndTime=0,this._frameRateIsLow=!1,this._lastFramesPerSecond=void 0,this._pauseCount=0;var n=this;this._preUpdateRemoveListener=this._scene.preUpdate.addEventListener(function(e,t){u(n,t)}),this._hiddenPropertyName=void 0!==document.hidden?"hidden":void 0!==document.mozHidden?"mozHidden":void 0!==document.msHidden?"msHidden":void 0!==document.webkitHidden?"webkitHidden":void 0;var a=void 0!==document.hidden?"visibilitychange":void 0!==document.mozHidden?"mozvisibilitychange":void 0!==document.msHidden?"msvisibilitychange":void 0!==document.webkitHidden?"webkitvisibilitychange":void 0;this._visibilityChangeRemoveListener=void 0,t(a)&&(document.addEventListener(a,i,!1),this._visibilityChangeRemoveListener=function(){document.removeEventListener(a,i,!1)})}function u(e,t){if(!(e._pauseCount>0)){var r=a();if(e._needsQuietPeriod)e._needsQuietPeriod=!1,e._frameTimes.length=0,e._quietPeriodEndTime=r+e.quietPeriod/s.SECONDS_PER_MILLISECOND,e._warmupPeriodEndTime=e._quietPeriodEndTime+(e.warmupPeriod+e.samplingWindow)/s.SECONDS_PER_MILLISECOND;else if(r>=e._quietPeriodEndTime){e._frameTimes.push(r);var i=r-e.samplingWindow/s.SECONDS_PER_MILLISECOND;if(e._frameTimes.length>=2&&e._frameTimes[0]<=i){for(;e._frameTimes.length>=2&&e._frameTimes[1]<i;)e._frameTimes.shift();var n=(r-e._frameTimes[0])/(e._frameTimes.length-1);e._lastFramesPerSecond=1e3/n;var o=1e3/(r>e._warmupPeriodEndTime?e.minimumFrameRateAfterWarmup:e.minimumFrameRateDuringWarmup);n>o?e._frameRateIsLow||(e._frameRateIsLow=!0,e._needsQuietPeriod=!0,e.lowFrameRate.raiseEvent(e.scene,e._lastFramesPerSecond)):e._frameRateIsLow&&(e._frameRateIsLow=!1,e._needsQuietPeriod=!0,e.nominalFrameRate.raiseEvent(e.scene,e._lastFramesPerSecond))}}}}function c(e){document[e._hiddenPropertyName]?e.pause():e.unpause()}return l.defaultSettings={samplingWindow:5,quietPeriod:2,warmupPeriod:5,minimumFrameRateDuringWarmup:4,minimumFrameRateAfterWarmup:8},l.fromScene=function(e){return t(e._frameRateMonitor)&&!e._frameRateMonitor.isDestroyed()||(e._frameRateMonitor=new l({scene:e})),e._frameRateMonitor},r(l.prototype,{scene:{get:function(){return this._scene}},lowFrameRate:{get:function(){return this._lowFrameRate}},nominalFrameRate:{get:function(){return this._nominalFrameRate}},lastFramesPerSecond:{get:function(){return this._lastFramesPerSecond}}}),l.prototype.pause=function(){1===++this._pauseCount&&(this._frameTimes.length=0,this._lastFramesPerSecond=void 0)},l.prototype.unpause=function(){--this._pauseCount<=0&&(this._pauseCount=0,this._needsQuietPeriod=!0)},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._preUpdateRemoveListener(),t(this._visibilityChangeRemoveListener)&&this._visibilityChangeRemoveListener(),i(this)},l}),define("Scene/FrameState",["./SceneMode"],function(e){"use strict";function t(t,r,i){this.context=t,this.commandList=[],this.shadowMaps=[],this.brdfLutGenerator=void 0,this.environmentMap=void 0,this.mode=e.SCENE3D,this.morphTime=e.getMorphTime(e.SCENE3D),this.frameNumber=0,this.time=void 0,this.jobScheduler=i,this.mapProjection=void 0,this.camera=void 0,this.cullingVolume=void 0,this.occluder=void 0,this.maximumScreenSpaceError=void 0,this.passes={render:!1,pick:!1,depth:!1},this.creditDisplay=r,this.afterRender=[],this.scene3DOnly=!1,this.fog={enabled:!1,density:void 0,sse:void 0,minimumBrightness:void 0},this.terrainExaggeration=1,this.shadowHints={shadowsEnabled:!0,shadowMaps:[],lightShadowMaps:[],nearPlane:1,farPlane:5e3,closestObjectSize:1e3,lastDirtyTime:0,outOfView:!0},this.imagerySplitPosition=0,this.frustumSplits=[],this.backgroundColor=void 0,this.minimumDisableDepthTestDistance=void 0,this.invertClassification=!1,this.invertClassificationColor=void 0}return t}),define("Scene/FrustumCommands",["../Core/defaultValue","../Renderer/Pass"],function(e,t){"use strict";function r(r,i){this.near=e(r,0),this.far=e(i,0);for(var n=t.NUMBER_OF_PASSES,o=new Array(n),a=new Array(n),s=0;s<n;++s)o[s]=[],a[s]=0;this.commands=o,this.indices=a}return r}),define("Shaders/PostProcessFilters/FXAA",[],function(){"use strict";return"varying vec2 v_textureCoordinates;\nuniform sampler2D u_texture;\nuniform vec2 u_fxaaQualityRcpFrame;\nconst float fxaaQualitySubpix = 0.5;\nconst float fxaaQualityEdgeThreshold = 0.125;\nconst float fxaaQualityEdgeThresholdMin = 0.0833;\nvoid main()\n{\nvec4 color = FxaaPixelShader(\nv_textureCoordinates,\nu_texture,\nu_fxaaQualityRcpFrame,\nfxaaQualitySubpix,\nfxaaQualityEdgeThreshold,\nfxaaQualityEdgeThresholdMin);\nfloat alpha = texture2D(u_texture, v_textureCoordinates).a;\ngl_FragColor = vec4(color.rgb, alpha);\n}\n"}),define("ThirdParty/Shaders/FXAA3_11",[],function(){"use strict";return"#if (FXAA_QUALITY_PRESET == 10)\n#define FXAA_QUALITY_PS 3\n#define FXAA_QUALITY_P0 1.5\n#define FXAA_QUALITY_P1 3.0\n#define FXAA_QUALITY_P2 12.0\n#endif\n#if (FXAA_QUALITY_PRESET == 11)\n#define FXAA_QUALITY_PS 4\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 3.0\n#define FXAA_QUALITY_P3 12.0\n#endif\n#if (FXAA_QUALITY_PRESET == 12)\n#define FXAA_QUALITY_PS 5\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 4.0\n#define FXAA_QUALITY_P4 12.0\n#endif\n#if (FXAA_QUALITY_PRESET == 13)\n#define FXAA_QUALITY_PS 6\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 4.0\n#define FXAA_QUALITY_P5 12.0\n#endif\n#if (FXAA_QUALITY_PRESET == 14)\n#define FXAA_QUALITY_PS 7\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 4.0\n#define FXAA_QUALITY_P6 12.0\n#endif\n#if (FXAA_QUALITY_PRESET == 15)\n#define FXAA_QUALITY_PS 8\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 2.0\n#define FXAA_QUALITY_P6 4.0\n#define FXAA_QUALITY_P7 12.0\n#endif\n#if (FXAA_QUALITY_PRESET == 20)\n#define FXAA_QUALITY_PS 3\n#define FXAA_QUALITY_P0 1.5\n#define FXAA_QUALITY_P1 2.0\n#define FXAA_QUALITY_P2 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 21)\n#define FXAA_QUALITY_PS 4\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 22)\n#define FXAA_QUALITY_PS 5\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 23)\n#define FXAA_QUALITY_PS 6\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 24)\n#define FXAA_QUALITY_PS 7\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 3.0\n#define FXAA_QUALITY_P6 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 25)\n#define FXAA_QUALITY_PS 8\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 2.0\n#define FXAA_QUALITY_P6 4.0\n#define FXAA_QUALITY_P7 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 26)\n#define FXAA_QUALITY_PS 9\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 2.0\n#define FXAA_QUALITY_P6 2.0\n#define FXAA_QUALITY_P7 4.0\n#define FXAA_QUALITY_P8 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 27)\n#define FXAA_QUALITY_PS 10\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 2.0\n#define FXAA_QUALITY_P6 2.0\n#define FXAA_QUALITY_P7 2.0\n#define FXAA_QUALITY_P8 4.0\n#define FXAA_QUALITY_P9 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 28)\n#define FXAA_QUALITY_PS 11\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 2.0\n#define FXAA_QUALITY_P6 2.0\n#define FXAA_QUALITY_P7 2.0\n#define FXAA_QUALITY_P8 2.0\n#define FXAA_QUALITY_P9 4.0\n#define FXAA_QUALITY_P10 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 29)\n#define FXAA_QUALITY_PS 12\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.5\n#define FXAA_QUALITY_P2 2.0\n#define FXAA_QUALITY_P3 2.0\n#define FXAA_QUALITY_P4 2.0\n#define FXAA_QUALITY_P5 2.0\n#define FXAA_QUALITY_P6 2.0\n#define FXAA_QUALITY_P7 2.0\n#define FXAA_QUALITY_P8 2.0\n#define FXAA_QUALITY_P9 2.0\n#define FXAA_QUALITY_P10 4.0\n#define FXAA_QUALITY_P11 8.0\n#endif\n#if (FXAA_QUALITY_PRESET == 39)\n#define FXAA_QUALITY_PS 12\n#define FXAA_QUALITY_P0 1.0\n#define FXAA_QUALITY_P1 1.0\n#define FXAA_QUALITY_P2 1.0\n#define FXAA_QUALITY_P3 1.0\n#define FXAA_QUALITY_P4 1.0\n#define FXAA_QUALITY_P5 1.5\n#define FXAA_QUALITY_P6 2.0\n#define FXAA_QUALITY_P7 2.0\n#define FXAA_QUALITY_P8 2.0\n#define FXAA_QUALITY_P9 2.0\n#define FXAA_QUALITY_P10 4.0\n#define FXAA_QUALITY_P11 8.0\n#endif\n#define FxaaBool bool\n#define FxaaFloat float\n#define FxaaFloat2 vec2\n#define FxaaFloat3 vec3\n#define FxaaFloat4 vec4\n#define FxaaHalf float\n#define FxaaHalf2 vec2\n#define FxaaHalf3 vec3\n#define FxaaHalf4 vec4\n#define FxaaInt2 vec2\n#define FxaaTex sampler2D\n#define FxaaSat(x) clamp(x, 0.0, 1.0)\n#define FxaaTexTop(t, p) texture2D(t, p)\n#define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r))\nFxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }\nFxaaFloat4 FxaaPixelShader(\nFxaaFloat2 pos,\nFxaaTex tex,\nFxaaFloat2 fxaaQualityRcpFrame,\nFxaaFloat fxaaQualitySubpix,\nFxaaFloat fxaaQualityEdgeThreshold,\nFxaaFloat fxaaQualityEdgeThresholdMin\n) {\nFxaaFloat2 posM;\nposM.x = pos.x;\nposM.y = pos.y;\nFxaaFloat4 rgbyM = FxaaTexTop(tex, posM);\n#define lumaM rgbyM.y\nFxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));\nFxaaFloat maxSM = max(lumaS, lumaM);\nFxaaFloat minSM = min(lumaS, lumaM);\nFxaaFloat maxESM = max(lumaE, maxSM);\nFxaaFloat minESM = min(lumaE, minSM);\nFxaaFloat maxWN = max(lumaN, lumaW);\nFxaaFloat minWN = min(lumaN, lumaW);\nFxaaFloat rangeMax = max(maxWN, maxESM);\nFxaaFloat rangeMin = min(minWN, minESM);\nFxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;\nFxaaFloat range = rangeMax - rangeMin;\nFxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);\nFxaaBool earlyExit = range < rangeMaxClamped;\nif(earlyExit)\nreturn rgbyM;\nFxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));\nFxaaFloat lumaNS = lumaN + lumaS;\nFxaaFloat lumaWE = lumaW + lumaE;\nFxaaFloat subpixRcpRange = 1.0/range;\nFxaaFloat subpixNSWE = lumaNS + lumaWE;\nFxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;\nFxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;\nFxaaFloat lumaNESE = lumaNE + lumaSE;\nFxaaFloat lumaNWNE = lumaNW + lumaNE;\nFxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;\nFxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;\nFxaaFloat lumaNWSW = lumaNW + lumaSW;\nFxaaFloat lumaSWSE = lumaSW + lumaSE;\nFxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);\nFxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);\nFxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;\nFxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;\nFxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;\nFxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;\nFxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;\nFxaaFloat lengthSign = fxaaQualityRcpFrame.x;\nFxaaBool horzSpan = edgeHorz >= edgeVert;\nFxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;\nif(!horzSpan) lumaN = lumaW;\nif(!horzSpan) lumaS = lumaE;\nif(horzSpan) lengthSign = fxaaQualityRcpFrame.y;\nFxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;\nFxaaFloat gradientN = lumaN - lumaM;\nFxaaFloat gradientS = lumaS - lumaM;\nFxaaFloat lumaNN = lumaN + lumaM;\nFxaaFloat lumaSS = lumaS + lumaM;\nFxaaBool pairN = abs(gradientN) >= abs(gradientS);\nFxaaFloat gradient = max(abs(gradientN), abs(gradientS));\nif(pairN) lengthSign = -lengthSign;\nFxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);\nFxaaFloat2 posB;\nposB.x = posM.x;\nposB.y = posM.y;\nFxaaFloat2 offNP;\noffNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;\noffNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;\nif(!horzSpan) posB.x += lengthSign * 0.5;\nif( horzSpan) posB.y += lengthSign * 0.5;\nFxaaFloat2 posN;\nposN.x = posB.x - offNP.x * FXAA_QUALITY_P0;\nposN.y = posB.y - offNP.y * FXAA_QUALITY_P0;\nFxaaFloat2 posP;\nposP.x = posB.x + offNP.x * FXAA_QUALITY_P0;\nposP.y = posB.y + offNP.y * FXAA_QUALITY_P0;\nFxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;\nFxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));\nFxaaFloat subpixE = subpixC * subpixC;\nFxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));\nif(!pairN) lumaNN = lumaSS;\nFxaaFloat gradientScaled = gradient * 1.0/4.0;\nFxaaFloat lumaMM = lumaM - lumaNN * 0.5;\nFxaaFloat subpixF = subpixD * subpixE;\nFxaaBool lumaMLTZero = lumaMM < 0.0;\nlumaEndN -= lumaNN * 0.5;\nlumaEndP -= lumaNN * 0.5;\nFxaaBool doneN = abs(lumaEndN) >= gradientScaled;\nFxaaBool doneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;\nFxaaBool doneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;\n#if (FXAA_QUALITY_PS > 3)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;\n#if (FXAA_QUALITY_PS > 4)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;\n#if (FXAA_QUALITY_PS > 5)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;\n#if (FXAA_QUALITY_PS > 6)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;\n#if (FXAA_QUALITY_PS > 7)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;\n#if (FXAA_QUALITY_PS > 8)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;\n#if (FXAA_QUALITY_PS > 9)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;\n#if (FXAA_QUALITY_PS > 10)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;\n#if (FXAA_QUALITY_PS > 11)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;\n#if (FXAA_QUALITY_PS > 12)\nif(doneNP) {\nif(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));\nif(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));\nif(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\nif(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\ndoneN = abs(lumaEndN) >= gradientScaled;\ndoneP = abs(lumaEndP) >= gradientScaled;\nif(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;\nif(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;\ndoneNP = (!doneN) || (!doneP);\nif(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;\nif(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\n#endif\n}\nFxaaFloat dstN = posM.x - posN.x;\nFxaaFloat dstP = posP.x - posM.x;\nif(!horzSpan) dstN = posM.y - posN.y;\nif(!horzSpan) dstP = posP.y - posM.y;\nFxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;\nFxaaFloat spanLength = (dstP + dstN);\nFxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;\nFxaaFloat spanLengthRcp = 1.0/spanLength;\nFxaaBool directionN = dstN < dstP;\nFxaaFloat dst = min(dstN, dstP);\nFxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;\nFxaaFloat subpixG = subpixF * subpixF;\nFxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;\nFxaaFloat subpixH = subpixG * fxaaQualitySubpix;\nFxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;\nFxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);\nif(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;\nif( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;\nreturn FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);\n}\n"}),define("Scene/FXAA",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Color","../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/Renderbuffer","../Renderer/RenderbufferFormat","../Renderer/RenderState","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Shaders/PostProcessFilters/FXAA","../ThirdParty/Shaders/FXAA3_11"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(){this._texture=void 0,this._depthStencilTexture=void 0,this._depthStencilRenderbuffer=void 0,this._fbo=void 0,this._command=void 0,this._viewport=new e,this._rs=void 0,this._useScissorTest=!1,this._scissorRectangle=void 0;var t=new a({color:new r(0,0,0,0),depth:1,owner:this});this._clearCommand=t,this._qualityPreset=39}function b(e){e._fbo=e._fbo&&e._fbo.destroy(),e._texture=e._texture&&e._texture.destroy(),e._depthStencilTexture=e._depthStencilTexture&&e._depthStencilTexture.destroy(),e._depthStencilRenderbuffer=e._depthStencilRenderbuffer&&e._depthStencilRenderbuffer.destroy(),e._fbo=void 0,e._texture=void 0,e._depthStencilTexture=void 0,e._depthStencilRenderbuffer=void 0,i(e._command)&&(e._command.shaderProgram=e._command.shaderProgram&&e._command.shaderProgram.destroy(),e._command=void 0)}return y.prototype.update=function(r,n){var a=r.drawingBufferWidth,y=r.drawingBufferHeight,b=this._texture,C=!i(b)||b.width!==a||b.height!==y;if(C&&(this._texture=this._texture&&this._texture.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),this._depthStencilRenderbuffer=this._depthStencilRenderbuffer&&this._depthStencilRenderbuffer.destroy(),this._texture=new p({context:r,width:a,height:y,pixelFormat:o.RGBA,pixelDatatype:l.UNSIGNED_BYTE,sampler:new h({wrapS:g.CLAMP_TO_EDGE,wrapT:g.CLAMP_TO_EDGE,minificationFilter:m.LINEAR,magnificationFilter:f.LINEAR})}),r.depthTexture?this._depthStencilTexture=new p({context:r,width:a,height:y,pixelFormat:o.DEPTH_STENCIL,pixelDatatype:l.UNSIGNED_INT_24_8}):this._depthStencilRenderbuffer=new u({context:r,width:a,height:y,format:c.DEPTH_STENCIL})),i(this._fbo)&&!C||(this._fbo=this._fbo&&this._fbo.destroy(),this._fbo=new s({context:r,colorTextures:[this._texture],depthStencilTexture:this._depthStencilTexture,depthStencilRenderbuffer:this._depthStencilRenderbuffer,destroyAttachments:!1})),!i(this._command)){var S="#define FXAA_QUALITY_PRESET "+this._qualityPreset+"\n"+v+"\n"+_;this._command=r.createViewportQuadCommand(S,{owner:this})}this._viewport.width=a,this._viewport.height=y;var w=!e.equals(this._viewport,n.viewport),T=w!==this._useScissorTest;if(this._useScissorTest=w,e.equals(this._scissorRectangle,n.viewport)||(this._scissorRectangle=e.clone(n.viewport,this._scissorRectangle),T=!0),i(this._rs)&&e.equals(this._rs.viewport,this._viewport)&&!T||(this._rs=d.fromCache({viewport:this._viewport,scissorTest:{enabled:this._useScissorTest,rectangle:this._scissorRectangle}})),this._command.renderState=this._rs,C){var E=this,A=new t(1/this._texture.width,1/this._texture.height);this._command.uniformMap={u_texture:function(){return E._texture},u_fxaaQualityRcpFrame:function(){return A}}}},y.prototype.execute=function(e,t){this._command.execute(e,t)},y.prototype.clear=function(e,t,i){var n=t.framebuffer;t.framebuffer=this._fbo,r.clone(i,this._clearCommand.color),this._clearCommand.execute(e,t),t.framebuffer=n},y.prototype.getColorFramebuffer=function(){return this._fbo},y.prototype.isDestroyed=function(){return!1},y.prototype.destroy=function(){return b(this),n(this)},y}),define("Shaders/GlobeFS",[],function(){"use strict" +;return"uniform vec4 u_initialColor;\n#if TEXTURE_UNITS > 0\nuniform sampler2D u_dayTextures[TEXTURE_UNITS];\nuniform vec4 u_dayTextureTranslationAndScale[TEXTURE_UNITS];\nuniform bool u_dayTextureUseWebMercatorT[TEXTURE_UNITS];\n#ifdef APPLY_ALPHA\nuniform float u_dayTextureAlpha[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_SPLIT\nuniform float u_dayTextureSplit[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_BRIGHTNESS\nuniform float u_dayTextureBrightness[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_CONTRAST\nuniform float u_dayTextureContrast[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_HUE\nuniform float u_dayTextureHue[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_SATURATION\nuniform float u_dayTextureSaturation[TEXTURE_UNITS];\n#endif\n#ifdef APPLY_GAMMA\nuniform float u_dayTextureOneOverGamma[TEXTURE_UNITS];\n#endif\nuniform vec4 u_dayTextureTexCoordsRectangle[TEXTURE_UNITS];\n#endif\n#ifdef SHOW_REFLECTIVE_OCEAN\nuniform sampler2D u_waterMask;\nuniform vec4 u_waterMaskTranslationAndScale;\nuniform float u_zoomedOutOceanSpecularIntensity;\n#endif\n#ifdef SHOW_OCEAN_WAVES\nuniform sampler2D u_oceanNormalMap;\n#endif\n#ifdef ENABLE_DAYNIGHT_SHADING\nuniform vec2 u_lightingFadeDistance;\n#endif\n#ifdef ENABLE_CLIPPING_PLANES\nuniform int u_clippingPlanesLength;\nuniform vec4 u_clippingPlanes[czm_maxClippingPlanes];\nuniform vec4 u_clippingPlanesEdgeStyle;\n#endif\n#if defined(FOG) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))\nuniform float u_minimumBrightness;\n#endif\nvarying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec3 v_textureCoordinates;\nvarying vec3 v_normalMC;\nvarying vec3 v_normalEC;\n#ifdef APPLY_MATERIAL\nvarying float v_height;\nvarying float v_slope;\n#endif\n#ifdef FOG\nvarying float v_distance;\nvarying vec3 v_rayleighColor;\nvarying vec3 v_mieColor;\n#endif\nvec4 sampleAndBlend(\nvec4 previousColor,\nsampler2D textureToSample,\nvec2 tileTextureCoordinates,\nvec4 textureCoordinateRectangle,\nvec4 textureCoordinateTranslationAndScale,\nfloat textureAlpha,\nfloat textureBrightness,\nfloat textureContrast,\nfloat textureHue,\nfloat textureSaturation,\nfloat textureOneOverGamma,\nfloat split)\n{\nvec2 alphaMultiplier = step(textureCoordinateRectangle.st, tileTextureCoordinates);\ntextureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;\nalphaMultiplier = step(vec2(0.0), textureCoordinateRectangle.pq - tileTextureCoordinates);\ntextureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;\nvec2 translation = textureCoordinateTranslationAndScale.xy;\nvec2 scale = textureCoordinateTranslationAndScale.zw;\nvec2 textureCoordinates = tileTextureCoordinates * scale + translation;\nvec4 value = texture2D(textureToSample, textureCoordinates);\nvec3 color = value.rgb;\nfloat alpha = value.a;\n#ifdef APPLY_SPLIT\nfloat splitPosition = czm_imagerySplitPosition;\nif (split < 0.0 && gl_FragCoord.x > splitPosition) {\nalpha = 0.0;\n}\nelse if (split > 0.0 && gl_FragCoord.x < splitPosition) {\nalpha = 0.0;\n}\n#endif\n#ifdef APPLY_BRIGHTNESS\ncolor = mix(vec3(0.0), color, textureBrightness);\n#endif\n#ifdef APPLY_CONTRAST\ncolor = mix(vec3(0.5), color, textureContrast);\n#endif\n#ifdef APPLY_HUE\ncolor = czm_hue(color, textureHue);\n#endif\n#ifdef APPLY_SATURATION\ncolor = czm_saturation(color, textureSaturation);\n#endif\n#ifdef APPLY_GAMMA\ncolor = pow(color, vec3(textureOneOverGamma));\n#endif\nfloat sourceAlpha = alpha * textureAlpha;\nfloat outAlpha = mix(previousColor.a, 1.0, sourceAlpha);\nvec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha;\nreturn vec4(outColor, outAlpha);\n}\nvec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates);\nvec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue);\nvoid main()\n{\n#ifdef ENABLE_CLIPPING_PLANES\n#ifdef UNION_CLIPPING_REGIONS\nfloat clipDistance = czm_discardIfClippedWithUnion(u_clippingPlanes, u_clippingPlanesLength);\n#else\nfloat clipDistance = czm_discardIfClippedWithIntersect(u_clippingPlanes, u_clippingPlanesLength);\n#endif\n#endif\nvec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0));\n#ifdef SHOW_TILE_BOUNDARIES\nif (v_textureCoordinates.x < (1.0/256.0) || v_textureCoordinates.x > (255.0/256.0) ||\nv_textureCoordinates.y < (1.0/256.0) || v_textureCoordinates.y > (255.0/256.0))\n{\ncolor = vec4(1.0, 0.0, 0.0, 1.0);\n}\n#endif\n#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING)\nvec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0));\nvec3 normalEC = czm_normal3D * normalMC;\n#endif\n#ifdef SHOW_REFLECTIVE_OCEAN\nvec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy;\nvec2 waterMaskScale = u_waterMaskTranslationAndScale.zw;\nvec2 waterMaskTextureCoordinates = v_textureCoordinates.xy * waterMaskScale + waterMaskTranslation;\nfloat mask = texture2D(u_waterMask, waterMaskTextureCoordinates).r;\nif (mask > 0.0)\n{\nmat3 enuToEye = czm_eastNorthUpToEyeCoordinates(v_positionMC, normalEC);\nvec2 ellipsoidTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC);\nvec2 ellipsoidFlippedTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC.zyx);\nvec2 textureCoordinates = mix(ellipsoidTextureCoordinates, ellipsoidFlippedTextureCoordinates, czm_morphTime * smoothstep(0.9, 0.95, normalMC.z));\ncolor = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, color, mask);\n}\n#endif\n#ifdef APPLY_MATERIAL\nczm_materialInput materialInput;\nmaterialInput.st = v_textureCoordinates.st;\nmaterialInput.normalEC = normalize(v_normalEC);\nmaterialInput.slope = v_slope;\nmaterialInput.height = v_height;\nczm_material material = czm_getMaterial(materialInput);\ncolor.xyz = mix(color.xyz, material.diffuse, material.alpha);\n#endif\n#ifdef ENABLE_VERTEX_LIGHTING\nfloat diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalize(v_normalEC)) * 0.9 + 0.3, 0.0, 1.0);\nvec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a);\n#elif defined(ENABLE_DAYNIGHT_SHADING)\nfloat diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0);\nfloat cameraDist = length(czm_view[3]);\nfloat fadeOutDist = u_lightingFadeDistance.x;\nfloat fadeInDist = u_lightingFadeDistance.y;\nfloat t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);\ndiffuseIntensity = mix(1.0, diffuseIntensity, t);\nvec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a);\n#else\nvec4 finalColor = color;\n#endif\n#ifdef ENABLE_CLIPPING_PLANES\nvec4 clippingPlanesEdgeColor = vec4(1.0);\nclippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb;\nfloat clippingPlanesEdgeWidth = u_clippingPlanesEdgeStyle.a;\nif (clipDistance < clippingPlanesEdgeWidth)\n{\nfinalColor = clippingPlanesEdgeColor;\n}\n#endif\n#ifdef FOG\nconst float fExposure = 2.0;\nvec3 fogColor = v_mieColor + finalColor.rgb * v_rayleighColor;\nfogColor = vec3(1.0) - exp(-fExposure * fogColor);\n#if defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING)\nfloat darken = clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), u_minimumBrightness, 1.0);\nfogColor *= darken;\n#endif\ngl_FragColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor), finalColor.a);\n#else\ngl_FragColor = finalColor;\n#endif\n}\n#ifdef SHOW_REFLECTIVE_OCEAN\nfloat waveFade(float edge0, float edge1, float x)\n{\nfloat y = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\nreturn pow(1.0 - y, 5.0);\n}\nfloat linearFade(float edge0, float edge1, float x)\n{\nreturn clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n}\nconst float oceanFrequencyLowAltitude = 825000.0;\nconst float oceanAnimationSpeedLowAltitude = 0.004;\nconst float oceanOneOverAmplitudeLowAltitude = 1.0 / 2.0;\nconst float oceanSpecularIntensity = 0.5;\nconst float oceanFrequencyHighAltitude = 125000.0;\nconst float oceanAnimationSpeedHighAltitude = 0.008;\nconst float oceanOneOverAmplitudeHighAltitude = 1.0 / 2.0;\nvec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float maskValue)\n{\nvec3 positionToEyeEC = -positionEyeCoordinates;\nfloat positionToEyeECLength = length(positionToEyeEC);\nvec3 normalizedpositionToEyeEC = normalize(normalize(positionToEyeEC));\nfloat waveIntensity = waveFade(70000.0, 1000000.0, positionToEyeECLength);\n#ifdef SHOW_OCEAN_WAVES\nfloat time = czm_frameNumber * oceanAnimationSpeedHighAltitude;\nvec4 noise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyHighAltitude, time, 0.0);\nvec3 normalTangentSpaceHighAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeHighAltitude);\ntime = czm_frameNumber * oceanAnimationSpeedLowAltitude;\nnoise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyLowAltitude, time, 0.0);\nvec3 normalTangentSpaceLowAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeLowAltitude);\nfloat highAltitudeFade = linearFade(0.0, 60000.0, positionToEyeECLength);\nfloat lowAltitudeFade = 1.0 - linearFade(20000.0, 60000.0, positionToEyeECLength);\nvec3 normalTangentSpace =\n(highAltitudeFade * normalTangentSpaceHighAltitude) +\n(lowAltitudeFade * normalTangentSpaceLowAltitude);\nnormalTangentSpace = normalize(normalTangentSpace);\nnormalTangentSpace.xy *= waveIntensity;\nnormalTangentSpace = normalize(normalTangentSpace);\n#else\nvec3 normalTangentSpace = vec3(0.0, 0.0, 1.0);\n#endif\nvec3 normalEC = enuToEye * normalTangentSpace;\nconst vec3 waveHighlightColor = vec3(0.3, 0.45, 0.6);\nfloat diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * maskValue;\nvec3 diffuseHighlight = waveHighlightColor * diffuseIntensity;\n#ifdef SHOW_OCEAN_WAVES\nfloat tsPerturbationRatio = normalTangentSpace.z;\nvec3 nonDiffuseHighlight = mix(waveHighlightColor * 5.0 * (1.0 - tsPerturbationRatio), vec3(0.0), diffuseIntensity);\n#else\nvec3 nonDiffuseHighlight = vec3(0.0);\n#endif\nfloat specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0) + 0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0);\nfloat surfaceReflectance = mix(0.0, mix(u_zoomedOutOceanSpecularIntensity, oceanSpecularIntensity, waveIntensity), maskValue);\nfloat specular = specularIntensity * surfaceReflectance;\nreturn vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a);\n}\n#endif // #ifdef SHOW_REFLECTIVE_OCEAN\n"}),define("Shaders/GlobeVS",[],function(){"use strict";return"#ifdef QUANTIZATION_BITS12\nattribute vec4 compressed0;\nattribute float compressed1;\n#else\nattribute vec4 position3DAndHeight;\nattribute vec4 textureCoordAndEncodedNormals;\n#endif\nuniform vec3 u_center3D;\nuniform mat4 u_modifiedModelView;\nuniform mat4 u_modifiedModelViewProjection;\nuniform vec4 u_tileRectangle;\nuniform vec2 u_southAndNorthLatitude;\nuniform vec2 u_southMercatorYAndOneOverHeight;\nvarying vec3 v_positionMC;\nvarying vec3 v_positionEC;\nvarying vec3 v_textureCoordinates;\nvarying vec3 v_normalMC;\nvarying vec3 v_normalEC;\n#ifdef APPLY_MATERIAL\nvarying float v_slope;\nvarying float v_height;\n#endif\n#ifdef FOG\nvarying float v_distance;\nvarying vec3 v_mieColor;\nvarying vec3 v_rayleighColor;\n#endif\nvec4 getPosition(vec3 position, float height, vec2 textureCoordinates);\nfloat get2DYPositionFraction(vec2 textureCoordinates);\nvec4 getPosition3DMode(vec3 position, float height, vec2 textureCoordinates)\n{\nreturn u_modifiedModelViewProjection * vec4(position, 1.0);\n}\nfloat get2DMercatorYPositionFraction(vec2 textureCoordinates)\n{\nconst float maxTileWidth = 0.003068;\nfloat positionFraction = textureCoordinates.y;\nfloat southLatitude = u_southAndNorthLatitude.x;\nfloat northLatitude = u_southAndNorthLatitude.y;\nif (northLatitude - southLatitude > maxTileWidth)\n{\nfloat southMercatorY = u_southMercatorYAndOneOverHeight.x;\nfloat oneOverMercatorHeight = u_southMercatorYAndOneOverHeight.y;\nfloat currentLatitude = mix(southLatitude, northLatitude, textureCoordinates.y);\ncurrentLatitude = clamp(currentLatitude, -czm_webMercatorMaxLatitude, czm_webMercatorMaxLatitude);\npositionFraction = czm_latitudeToWebMercatorFraction(currentLatitude, southMercatorY, oneOverMercatorHeight);\n}\nreturn positionFraction;\n}\nfloat get2DGeographicYPositionFraction(vec2 textureCoordinates)\n{\nreturn textureCoordinates.y;\n}\nvec4 getPositionPlanarEarth(vec3 position, float height, vec2 textureCoordinates)\n{\nfloat yPositionFraction = get2DYPositionFraction(textureCoordinates);\nvec4 rtcPosition2D = vec4(height, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordinates.x, yPositionFraction)), 1.0);\nreturn u_modifiedModelViewProjection * rtcPosition2D;\n}\nvec4 getPosition2DMode(vec3 position, float height, vec2 textureCoordinates)\n{\nreturn getPositionPlanarEarth(position, 0.0, textureCoordinates);\n}\nvec4 getPositionColumbusViewMode(vec3 position, float height, vec2 textureCoordinates)\n{\nreturn getPositionPlanarEarth(position, height, textureCoordinates);\n}\nvec4 getPositionMorphingMode(vec3 position, float height, vec2 textureCoordinates)\n{\nvec3 position3DWC = position + u_center3D;\nfloat yPositionFraction = get2DYPositionFraction(textureCoordinates);\nvec4 position2DWC = vec4(height, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordinates.x, yPositionFraction)), 1.0);\nvec4 morphPosition = czm_columbusViewMorph(position2DWC, vec4(position3DWC, 1.0), czm_morphTime);\nreturn czm_modelViewProjection * morphPosition;\n}\n#ifdef QUANTIZATION_BITS12\nuniform vec2 u_minMaxHeight;\nuniform mat4 u_scaleAndBias;\n#endif\nvoid main()\n{\n#ifdef QUANTIZATION_BITS12\nvec2 xy = czm_decompressTextureCoordinates(compressed0.x);\nvec2 zh = czm_decompressTextureCoordinates(compressed0.y);\nvec3 position = vec3(xy, zh.x);\nfloat height = zh.y;\nvec2 textureCoordinates = czm_decompressTextureCoordinates(compressed0.z);\nheight = height * (u_minMaxHeight.y - u_minMaxHeight.x) + u_minMaxHeight.x;\nposition = (u_scaleAndBias * vec4(position, 1.0)).xyz;\n#if (defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL)) && defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = czm_decompressTextureCoordinates(compressed0.w).x;\nfloat encodedNormal = compressed1;\n#elif defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = czm_decompressTextureCoordinates(compressed0.w).x;\nfloat encodedNormal = 0.0;\n#elif defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL)\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = compressed0.w;\n#else\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = 0.0;\n#endif\n#else\nvec3 position = position3DAndHeight.xyz;\nfloat height = position3DAndHeight.w;\nvec2 textureCoordinates = textureCoordAndEncodedNormals.xy;\n#if (defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)) && defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = textureCoordAndEncodedNormals.z;\nfloat encodedNormal = textureCoordAndEncodedNormals.w;\n#elif defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = textureCoordAndEncodedNormals.z;\n#elif defined(INCLUDE_WEB_MERCATOR_Y)\nfloat webMercatorT = textureCoordAndEncodedNormals.z;\nfloat encodedNormal = 0.0;\n#else\nfloat webMercatorT = textureCoordinates.y;\nfloat encodedNormal = 0.0;\n#endif\n#endif\nvec3 position3DWC = position + u_center3D;\ngl_Position = getPosition(position, height, textureCoordinates);\nv_textureCoordinates = vec3(textureCoordinates, webMercatorT);\n#if defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)\nv_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz;\nv_positionMC = position3DWC;\nvec3 normalMC = czm_octDecode(encodedNormal);\nv_normalMC = normalMC;\nv_normalEC = czm_normal3D * v_normalMC;\n#elif defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(GENERATE_POSITION)\nv_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz;\nv_positionMC = position3DWC;\n#endif\n#ifdef FOG\nAtmosphereColor atmosColor = computeGroundAtmosphereFromSpace(position3DWC);\nv_mieColor = atmosColor.mie;\nv_rayleighColor = atmosColor.rayleigh;\nv_distance = length((czm_modelView3D * vec4(position3DWC, 1.0)).xyz);\n#endif\n#ifdef APPLY_MATERIAL\nvec3 finalNormal = normalMC;\nvec3 ellipsoidNormal = normalize(position3DWC.xyz);\nv_slope = abs(dot(ellipsoidNormal, finalNormal));\nv_height = height;\n#endif\n}\n"}),define("Shaders/GroundAtmosphere",[],function(){"use strict";return"const float fInnerRadius = 6378137.0;\nconst float fOuterRadius = 6378137.0 * 1.025;\nconst float fOuterRadius2 = fOuterRadius * fOuterRadius;\nconst float Kr = 0.0025;\nconst float Km = 0.0015;\nconst float ESun = 15.0;\nconst float fKrESun = Kr * ESun;\nconst float fKmESun = Km * ESun;\nconst float fKr4PI = Kr * 4.0 * czm_pi;\nconst float fKm4PI = Km * 4.0 * czm_pi;\nconst float fScale = 1.0 / (fOuterRadius - fInnerRadius);\nconst float fScaleDepth = 0.25;\nconst float fScaleOverScaleDepth = fScale / fScaleDepth;\nstruct AtmosphereColor\n{\nvec3 mie;\nvec3 rayleigh;\n};\nconst int nSamples = 2;\nconst float fSamples = 2.0;\nfloat scale(float fCos)\n{\nfloat x = 1.0 - fCos;\nreturn fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\n}\nAtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos)\n{\nvec3 v3InvWavelength = vec3(1.0 / pow(0.650, 4.0), 1.0 / pow(0.570, 4.0), 1.0 / pow(0.475, 4.0));\nvec3 v3Ray = v3Pos - czm_viewerPositionWC;\nfloat fFar = length(v3Ray);\nv3Ray /= fFar;\nfloat fCameraHeight = length(czm_viewerPositionWC);\nfloat fCameraHeight2 = fCameraHeight * fCameraHeight;\nfloat B = 2.0 * length(czm_viewerPositionWC) * dot(normalize(czm_viewerPositionWC), v3Ray);\nfloat C = fCameraHeight2 - fOuterRadius2;\nfloat fDet = max(0.0, B*B - 4.0 * C);\nfloat fNear = 0.5 * (-B - sqrt(fDet));\nvec3 v3Start = czm_viewerPositionWC + v3Ray * fNear;\nfFar -= fNear;\nfloat fDepth = exp((fInnerRadius - fOuterRadius) / fScaleDepth);\nfloat fLightAngle = 1.0;\nfloat fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);\nfloat fCameraScale = scale(fCameraAngle);\nfloat fLightScale = scale(fLightAngle);\nfloat fCameraOffset = fDepth*fCameraScale;\nfloat fTemp = (fLightScale + fCameraScale);\nfloat fSampleLength = fFar / fSamples;\nfloat fScaledLength = fSampleLength * fScale;\nvec3 v3SampleRay = v3Ray * fSampleLength;\nvec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;\nvec3 v3FrontColor = vec3(0.0);\nvec3 v3Attenuate = vec3(0.0);\nfor(int i=0; i<nSamples; i++)\n{\nfloat fHeight = length(v3SamplePoint);\nfloat fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));\nfloat fScatter = fDepth*fTemp - fCameraOffset;\nv3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));\nv3FrontColor += v3Attenuate * (fDepth * fScaledLength);\nv3SamplePoint += v3SampleRay;\n}\nAtmosphereColor color;\ncolor.mie = v3FrontColor * (v3InvWavelength * fKrESun + fKmESun);\ncolor.rayleigh = v3Attenuate;\nreturn color;\n}\n"}),define("Scene/GlobeSurfaceShaderSet",["../Core/defined","../Core/destroyObject","../Core/TerrainQuantization","../Renderer/ShaderProgram","../Scene/SceneMode"],function(e,t,r,i,n){"use strict";function o(e,t,r,i){this.numberOfDayTextures=e,this.flags=t,this.material=r,this.shaderProgram=i}function a(){this.baseVertexShaderSource=void 0,this.baseFragmentShaderSource=void 0,this._shadersByTexturesFlags=[],this._pickShaderPrograms=[],this.material=void 0}function s(e){var t;switch(e){case n.SCENE3D:t="vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPosition3DMode(position, height, textureCoordinates); }";break;case n.SCENE2D:case n.COLUMBUS_VIEW:t="vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionColumbusViewMode(position, height, textureCoordinates); }";break;case n.MORPHING:t="vec4 getPosition(vec3 position, float height, vec2 textureCoordinates) { return getPositionMorphingMode(position, height, textureCoordinates); }"}return t}function l(e){return e?"float get2DYPositionFraction(vec2 textureCoordinates) { return get2DMercatorYPositionFraction(textureCoordinates); }":"float get2DYPositionFraction(vec2 textureCoordinates) { return get2DGeographicYPositionFraction(textureCoordinates); }"}return a.prototype.getShaderProgram=function(t,n,a,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){var T=0,E="",A=n.pickTerrain.mesh.encoding;A.quantization===r.BITS12&&(T=1,E="QUANTIZATION_BITS12");var x=t.mode,P=x|u<<2|c<<3|d<<4|h<<5|p<<6|f<<7|g<<8|_<<9|v<<10|y<<11|b<<12|C<<13|T<<14|m<<15|S<<16,D=n.surfaceShader;if(e(D)&&D.numberOfDayTextures===a&&D.flags===P&&D.material===this.material)return D.shaderProgram;var I=this._shadersByTexturesFlags[a];if(e(I)||(I=this._shadersByTexturesFlags[a]=[]),D=I[P],!e(D)||D.material!==this.material){var O=this.baseVertexShaderSource.clone(),M=this.baseFragmentShaderSource.clone();O.defines.push(E),M.defines.push("TEXTURE_UNITS "+a),u&&M.defines.push("APPLY_BRIGHTNESS"),c&&M.defines.push("APPLY_CONTRAST"),d&&M.defines.push("APPLY_HUE"),h&&M.defines.push("APPLY_SATURATION"),p&&M.defines.push("APPLY_GAMMA"),f&&M.defines.push("APPLY_ALPHA"),g&&(M.defines.push("SHOW_REFLECTIVE_OCEAN"),O.defines.push("SHOW_REFLECTIVE_OCEAN")),_&&M.defines.push("SHOW_OCEAN_WAVES"),v&&(y?(O.defines.push("ENABLE_VERTEX_LIGHTING"),M.defines.push("ENABLE_VERTEX_LIGHTING")):(O.defines.push("ENABLE_DAYNIGHT_SHADING"),M.defines.push("ENABLE_DAYNIGHT_SHADING"))),O.defines.push("INCLUDE_WEB_MERCATOR_Y"),M.defines.push("INCLUDE_WEB_MERCATOR_Y"),C&&(O.defines.push("FOG"),M.defines.push("FOG")),m&&M.defines.push("APPLY_SPLIT"),S&&(M.defines.push("ENABLE_CLIPPING_PLANES"),w&&M.defines.push("UNION_CLIPPING_REGIONS"));for(var R=" vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates)\n {\n vec4 color = initialColor;\n",L=0;L<a;++L)R+=" color = sampleAndBlend(\n color,\n u_dayTextures["+L+"],\n u_dayTextureUseWebMercatorT["+L+"] ? textureCoordinates.xz : textureCoordinates.xy,\n u_dayTextureTexCoordsRectangle["+L+"],\n u_dayTextureTranslationAndScale["+L+"],\n "+(f?"u_dayTextureAlpha["+L+"]":"1.0")+",\n "+(u?"u_dayTextureBrightness["+L+"]":"0.0")+",\n "+(c?"u_dayTextureContrast["+L+"]":"0.0")+",\n "+(d?"u_dayTextureHue["+L+"]":"0.0")+",\n "+(h?"u_dayTextureSaturation["+L+"]":"0.0")+",\n "+(p?"u_dayTextureOneOverGamma["+L+"]":"0.0")+",\n "+(m?"u_dayTextureSplit["+L+"]":"0.0")+"\n );\n";R+=" return color;\n }",M.sources.push(R),O.sources.push(s(x)),O.sources.push(l(b));var N=i.fromCache({context:t.context,vertexShaderSource:O,fragmentShaderSource:M,attributeLocations:A.getAttributeLocations()});D=I[P]=new o(a,P,this.material,N)}return n.surfaceShader=D,D.shaderProgram},a.prototype.getPickShaderProgram=function(t,n,o){var a=0,u="",c=n.pickTerrain.mesh.encoding;c.quantization===r.BITS12&&(a=1,u="QUANTIZATION_BITS12");var d=t.mode,h=d|o<<2|a<<3,p=this._pickShaderPrograms[h];if(!e(p)){var f=this.baseVertexShaderSource.clone();f.defines.push(u),f.sources.push(s(d)),f.sources.push(l(o));p=this._pickShaderPrograms[h]=i.fromCache({context:t.context,vertexShaderSource:f,fragmentShaderSource:"void main()\n{\n gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n}\n",attributeLocations:c.getAttributeLocations()})}return p},a.prototype.destroy=function(){var r,i,n=this._shadersByTexturesFlags;for(var o in n)if(n.hasOwnProperty(o)){var a=n[o];if(!e(a))continue;for(r in a)a.hasOwnProperty(r)&&(i=a[r],e(i)&&i.shaderProgram.destroy())}var s=this._pickShaderPrograms;for(r in s)s.hasOwnProperty(r)&&(i=s[r],i.destroy());return t(this)},a}),define("Scene/ImageryState",["../Core/freezeObject"],function(e){"use strict";return e({UNLOADED:0,TRANSITIONING:1,RECEIVED:2,TEXTURE_LOADED:3,READY:4,FAILED:5,INVALID:6,PLACEHOLDER:7})}),define("Scene/QuadtreeTileLoadState",["../Core/freezeObject"],function(e){"use strict";return e({START:0,LOADING:1,DONE:2,FAILED:3})}),define("Scene/TerrainState",["../Core/freezeObject"],function(e){"use strict";return e({FAILED:0,UNLOADED:1,RECEIVING:2,RECEIVED:3,TRANSFORMING:4,TRANSFORMED:5,READY:6})}),define("Scene/TileTerrain",["../Core/BoundingSphere","../Core/Cartesian3","../Core/defined","../Core/DeveloperError","../Core/IndexDatatype","../Core/OrientedBoundingBox","../Core/Request","../Core/RequestState","../Core/RequestType","../Core/TileProviderError","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/VertexArray","../ThirdParty/when","./TerrainState"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){this.state=f.UNLOADED,this.data=void 0,this.mesh=void 0,this.vertexArray=void 0,this.upsampleDetails=e,this.request=void 0}function g(e,t,i,n,o,c){function d(t){e.data=t,e.state=f.RECEIVED,e.request=void 0}function h(){if(e.request.state===s.CANCELLED)return e.data=void 0,e.state=f.UNLOADED,void(e.request=void 0);e.state=f.FAILED,e.request=void 0;var r="Failed to obtain terrain tile X: "+i+" Y: "+n+" Level: "+o+".";t._requestError=u.handleError(t._requestError,t,t.errorEvent,r,i,n,o,m)}function m(){var s=new a({throttle:!0,throttleByServer:!0,type:l.TERRAIN,priorityFunction:c});e.request=s,e.data=t.requestTileGeometry(i,n,o,s),r(e.data)?(e.state=f.RECEIVING,p(e.data,d,h)):(e.state=f.UNLOADED,e.request=void 0)}m()}function _(e,t,i,n,o,a){var s=i.tilingScheme,l=e.data,u=l.createMesh(s,n,o,a,t.terrainExaggeration);r(u)&&(e.state=f.TRANSFORMING,p(u,function(t){e.mesh=t,e.state=f.TRANSFORMED},function(){e.state=f.FAILED}))}function v(e,t,i,o,a,s){var l=e.mesh.vertices,u=c.createVertexBuffer({context:t,typedArray:l,usage:d.STATIC_DRAW}),p=e.mesh.encoding.getAttributes(u),m=e.mesh.indices.indexBuffers||{},g=m[t.id];if(!r(g)||g.isDestroyed()){var _=e.mesh.indices,v=2===_.BYTES_PER_ELEMENT?n.UNSIGNED_SHORT:n.UNSIGNED_INT;g=c.createIndexBuffer({context:t,typedArray:_,usage:d.STATIC_DRAW,indexDatatype:v}),g.vertexArrayDestroyable=!1,g.referenceCount=1,m[t.id]=g,e.mesh.indices.indexBuffers=m}else++g.referenceCount;e.vertexArray=new h({context:t,attributes:p,indexBuffer:g}),e.state=f.READY}return m.prototype.freeResources=function(){if(this.state=f.UNLOADED,this.data=void 0,this.mesh=void 0,r(this.vertexArray)){var e=this.vertexArray.indexBuffer;this.vertexArray.destroy(),this.vertexArray=void 0,!e.isDestroyed()&&r(e.referenceCount)&&0===--e.referenceCount&&e.destroy()}},m.prototype.publishToTile=function(r){var i=r.data,n=this.mesh;t.clone(n.center,i.center),i.minimumHeight=n.minimumHeight,i.maximumHeight=n.maximumHeight,i.boundingSphere3D=e.clone(n.boundingSphere3D,i.boundingSphere3D),i.orientedBoundingBox=o.clone(n.orientedBoundingBox,i.orientedBoundingBox),i.tileBoundingRegion.minimumHeight=n.minimumHeight,i.tileBoundingRegion.maximumHeight=n.maximumHeight,r.data.occludeePointInScaledSpace=t.clone(n.occludeePointInScaledSpace,i.occludeePointInScaledSpace)},m.prototype.processLoadStateMachine=function(e,t,r,i,n,o){this.state===f.UNLOADED&&g(this,t,r,i,n,o),this.state===f.RECEIVED&&_(this,e,t,r,i,n),this.state===f.TRANSFORMED&&v(this,e.context,t,r,i,n)},m.prototype.processUpsampleStateMachine=function(e,t,i,n,o){if(this.state===f.UNLOADED){var a=this.upsampleDetails,s=a.data,l=a.x,u=a.y,c=a.level;if(this.data=s.upsample(t.tilingScheme,l,u,c,i,n,o),!r(this.data))return;this.state=f.RECEIVING;var d=this;p(this.data,function(e){d.data=e,d.state=f.RECEIVED},function(){d.state=f.FAILED})}this.state===f.RECEIVED&&_(this,e,t,i,n,o),this.state===f.TRANSFORMED&&v(this,e.context,t,i,n,o)},m}),define("Scene/GlobeSurfaceTile",["../Core/BoundingSphere","../Core/Cartesian3","../Core/Cartesian4","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/IntersectionTests","../Core/PixelFormat","../Renderer/PixelDatatype","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","./ImageryState","./QuadtreeTileLoadState","./SceneMode","./TerrainState","./TileBoundingRegion","./TileTerrain"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(){this.imagery=[],this.waterMaskTexture=void 0,this.waterMaskTranslationAndScale=new r(0,0,1,1),this.terrainData=void 0,this.center=new t,this.vertexArray=void 0,this.minimumHeight=0,this.maximumHeight=0,this.boundingSphere3D=new e,this.boundingSphere2D=new e,this.orientedBoundingBox=void 0,this.tileBoundingRegion=void 0,this.occludeePointInScaledSpace=new t,this.loadedTerrain=void 0,this.upsampledTerrain=void 0,this.pickBoundingSphere=new e,this.pickTerrain=void 0,this.surfaceShader=void 0,this.isClipped=!0}function C(e,r,i,o,a,s){if(e.decodePosition(o,a,s),n(r)&&r!==g.SCENE3D){var l=i.ellipsoid,u=l.cartesianToCartographic(s);i.project(u,s),t.fromElements(s.z,s.x,s.y,s)}return s}function S(e){var t,r;return n(e.parent)&&n(e.parent.data)&&(t=e.parent.data.minimumHeight,r=e.parent.data.maximumHeight),new v({rectangle:e.rectangle,ellipsoid:e.tilingScheme.ellipsoid,minimumHeight:t,maximumHeight:r})}function w(e,t){return function(){return e.tileBoundingRegion.distanceToCamera(t)}}function T(e,t,r){var i=e.data,o=A(e);n(o)&&(i.upsampledTerrain=new y(o)),O(e,t)&&(i.loadedTerrain=new y);for(var a=0,s=r.length;a<s;++a){var l=r.get(a);l.show&&l._createTileImagerySkeletons(e,t)}}function E(e,t,r,o){var a=e.data,s=a.loadedTerrain,l=a.upsampledTerrain,u=!1;n(s)&&(s.processLoadStateMachine(t,r,e.x,e.y,e.level,e._priorityFunction),s.state>=_.RECEIVED&&(a.terrainData!==s.data&&(a.terrainData=s.data,R(t.context,a),D(e)),u=!0),s.state===_.READY?(s.publishToTile(e),n(e.data.vertexArray)&&o.push(e.data.vertexArray),e.data.vertexArray=s.vertexArray,s.vertexArray=void 0,a.pickTerrain=i(a.loadedTerrain,a.upsampledTerrain),a.loadedTerrain=void 0,a.upsampledTerrain=void 0):s.state===_.FAILED&&(a.loadedTerrain=void 0)),!u&&n(l)&&(l.processUpsampleStateMachine(t,r,e.x,e.y,e.level),l.state>=_.RECEIVED&&a.terrainData!==l.data&&(a.terrainData=l.data,r.hasWaterMask&&L(e),x(e)),l.state===_.READY?(l.publishToTile(e),n(e.data.vertexArray)&&o.push(e.data.vertexArray),e.data.vertexArray=l.vertexArray,l.vertexArray=void 0,a.pickTerrain=a.upsampledTerrain,a.upsampledTerrain=void 0):l.state===_.FAILED&&(a.upsampledTerrain=void 0))}function A(e){for(var t=e.parent;n(t)&&n(t.data)&&!n(t.data.terrainData);)t=t.parent;if(n(t)&&n(t.data))return{data:t.data.terrainData,x:t.x,y:t.y,level:t.level}}function x(e){P(e,e._southwestChild),P(e,e._southeastChild),P(e,e._northwestChild),P(e,e._northeastChild)}function P(e,t){if(n(t)&&t.state!==m.START){var r=t.data;if(n(r.terrainData)&&!r.terrainData.wasCreatedByUpsampling())return;n(r.upsampledTerrain)&&r.upsampledTerrain.freeResources(),r.upsampledTerrain=new y({data:e.data.terrainData,x:e.x,y:e.y,level:e.level}),t.state=m.LOADING}}function D(e){var t=e.data;I(e,t,e.southwestChild),I(e,t,e.southeastChild),I(e,t,e.northwestChild),I(e,t,e.northeastChild)}function I(e,t,r){if(r.state!==m.START){var i=r.data;if(n(i.terrainData)&&!i.terrainData.wasCreatedByUpsampling())return;n(i.upsampledTerrain)&&i.upsampledTerrain.freeResources(),i.upsampledTerrain=new y({data:t.terrainData,x:e.x,y:e.y,level:e.level}),t.terrainData.isChildAvailable(e.x,e.y,r.x,r.y)&&(n(i.loadedTerrain)||(i.loadedTerrain=new y)),r.state=m.LOADING}}function O(e,t){var r=t.getTileDataAvailable(e.x,e.y,e.level);if(n(r))return r;var i=e.parent;return!n(i)||!(!n(i.data)||!n(i.data.terrainData))&&i.data.terrainData.isChildAvailable(i.x,i.y,e.x,e.y)}function M(e){var t=e.cache.tile_waterMaskData;if(!n(t)){var r=new c({context:e,pixelFormat:s.LUMINANCE,pixelDatatype:l.UNSIGNED_BYTE,source:{arrayBufferView:new Uint8Array([255]),width:1,height:1}});r.referenceCount=1;t={allWaterTexture:r,sampler:new u({wrapS:p.CLAMP_TO_EDGE,wrapT:p.CLAMP_TO_EDGE, +minificationFilter:h.LINEAR,magnificationFilter:d.LINEAR}),destroy:function(){this.allWaterTexture.destroy()}},e.cache.tile_waterMaskData=t}return t}function R(e,t){var i=t.waterMaskTexture;n(i)&&(--i.referenceCount,0===i.referenceCount&&i.destroy(),t.waterMaskTexture=void 0);var o=t.terrainData.waterMask;if(n(o)){var a,u=M(e),d=o.length;if(1===d){if(0===o[0])return;a=u.allWaterTexture}else{var h=Math.sqrt(d);a=new c({context:e,pixelFormat:s.LUMINANCE,pixelDatatype:l.UNSIGNED_BYTE,source:{width:h,height:h,arrayBufferView:o},sampler:u.sampler}),a.referenceCount=0}++a.referenceCount,t.waterMaskTexture=a,r.fromElements(0,0,1,1,t.waterMaskTranslationAndScale)}}function L(e){for(var t=e.data,r=e.parent;n(r)&&!n(r.data.terrainData)||r.data.terrainData.wasCreatedByUpsampling();)r=r.parent;if(n(r)&&n(r.data.waterMaskTexture)){t.waterMaskTexture=r.data.waterMaskTexture,++t.waterMaskTexture.referenceCount;var i=r.rectangle,o=e.rectangle,a=o.width,s=o.height,l=a/i.width,u=s/i.height;t.waterMaskTranslationAndScale.x=l*(o.west-i.west)/a,t.waterMaskTranslationAndScale.y=u*(o.south-i.south)/s,t.waterMaskTranslationAndScale.z=l,t.waterMaskTranslationAndScale.w=u}}o(b.prototype,{eligibleForUnloading:{get:function(){for(var e=this.loadedTerrain,t=n(e)&&(e.state===_.RECEIVING||e.state===_.TRANSFORMING),r=this.upsampledTerrain,i=n(r)&&(r.state===_.RECEIVING||r.state===_.TRANSFORMING),o=!t&&!i,a=this.imagery,s=0,l=a.length;o&&s<l;++s){var u=a[s];o=!n(u.loadingImagery)||u.loadingImagery.state!==f.TRANSITIONING}return o}}});var N=new t,k=new t,F=new t,B=new t;return b.prototype.pick=function(e,r,i,o,s){var l=this.pickTerrain;if(n(l)){var u=l.mesh;if(n(u))for(var c=u.vertices,d=u.indices,h=u.encoding,p=d.length,f=0;f<p;f+=3){var m=d[f],g=d[f+1],_=d[f+2],v=C(h,r,i,c,m,N),y=C(h,r,i,c,g,k),b=C(h,r,i,c,_,F),S=a.rayTriangle(e,v,y,b,o,B);if(n(S))return t.clone(S,s)}}},b.prototype.freeResources=function(){n(this.waterMaskTexture)&&(--this.waterMaskTexture.referenceCount,0===this.waterMaskTexture.referenceCount&&this.waterMaskTexture.destroy(),this.waterMaskTexture=void 0),this.terrainData=void 0,n(this.loadedTerrain)&&(this.loadedTerrain.freeResources(),this.loadedTerrain=void 0),n(this.upsampledTerrain)&&(this.upsampledTerrain.freeResources(),this.upsampledTerrain=void 0),n(this.pickTerrain)&&(this.pickTerrain.freeResources(),this.pickTerrain=void 0);var e,t,r=this.imagery;for(e=0,t=r.length;e<t;++e)r[e].freeResources();this.imagery.length=0,this.freeVertexArray()},b.prototype.freeVertexArray=function(){var e;n(this.vertexArray)&&(e=this.vertexArray.indexBuffer,this.vertexArray=this.vertexArray.destroy(),!e.isDestroyed()&&n(e.referenceCount)&&0===--e.referenceCount&&e.destroy()),n(this.wireframeVertexArray)&&(e=this.wireframeVertexArray.indexBuffer,this.wireframeVertexArray=this.wireframeVertexArray.destroy(),!e.isDestroyed()&&n(e.referenceCount)&&0===--e.referenceCount&&e.destroy())},b.processStateMachine=function(e,t,r,i,o){var a=e.data;n(a)||(a=e.data=new b,a.tileBoundingRegion=S(e)),n(e._priorityFunction)||(e._priorityFunction=w(a,t)),e.state===m.START&&(T(e,r,i),e.state=m.LOADING),e.state===m.LOADING&&E(e,t,r,o);var s,l,u=n(a.vertexArray),c=!n(a.loadedTerrain)&&!n(a.upsampledTerrain),d=n(a.terrainData)&&a.terrainData.wasCreatedByUpsampling(),h=a.imagery;for(s=0,l=h.length;s<l;++s){var p=h[s];if(n(p.loadingImagery)){if(p.loadingImagery.state===f.PLACEHOLDER){var g=p.loadingImagery.imageryLayer;if(g.imageryProvider.ready){p.freeResources(),h.splice(s,1),g._createTileImagerySkeletons(e,r,s),--s,l=h.length;continue}d=!1}var _=p.processStateMachine(e,t);c=c&&_,u=u&&(_||n(p.readyImagery)),d=d&&n(p.loadingImagery)&&(p.loadingImagery.state===f.FAILED||p.loadingImagery.state===f.INVALID)}else d=!1}if(e.upsampledFromParent=d,s===l&&(u&&(e.renderable=!0),c)){var v=e._loadedCallbacks,y={};for(var C in v)v.hasOwnProperty(C)&&(v[C](e)||(y[C]=v[C]));e._loadedCallbacks=y,e.state=m.DONE,e._priorityFunction=void 0}},b}),define("Shaders/ReprojectWebMercatorFS",[],function(){"use strict";return"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_FragColor = texture2D(u_texture, v_textureCoordinates);\n}\n"}),define("Shaders/ReprojectWebMercatorVS",[],function(){"use strict";return"attribute vec4 position;\nattribute float webMercatorT;\nuniform vec2 u_textureDimensions;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nv_textureCoordinates = vec2(position.x, webMercatorT);\ngl_Position = czm_viewportOrthographic * (position * vec4(u_textureDimensions, 1.0, 1.0));\n}\n"}),define("Scene/Imagery",["../Core/defined","../Core/destroyObject","./ImageryState"],function(e,t,r){"use strict";function i(t,i,n,o,a){if(this.imageryLayer=t,this.x=i,this.y=n,this.level=o,this.request=void 0,0!==o){var s=i/2|0,l=n/2|0,u=o-1;this.parent=t.getImageryFromCache(s,l,u)}if(this.state=r.UNLOADED,this.imageUrl=void 0,this.image=void 0,this.texture=void 0,this.textureWebMercator=void 0,this.credits=void 0,this.referenceCount=0,!e(a)&&t.imageryProvider.ready){a=t.imageryProvider.tilingScheme.tileXYToRectangle(i,n,o)}this.rectangle=a}return i.createPlaceholder=function(e){var t=new i(e,0,0,0);return t.addReference(),t.state=r.PLACEHOLDER,t},i.prototype.addReference=function(){++this.referenceCount},i.prototype.releaseReference=function(){return--this.referenceCount,0===this.referenceCount?(this.imageryLayer.removeImageryFromCache(this),e(this.parent)&&this.parent.releaseReference(),e(this.image)&&e(this.image.destroy)&&this.image.destroy(),e(this.texture)&&this.texture.destroy(),e(this.textureWebMercator)&&this.texture!==this.textureWebMercator&&this.textureWebMercator.destroy(),t(this),0):this.referenceCount},i.prototype.processStateMachine=function(e,t,i){this.state===r.UNLOADED&&(this.state=r.TRANSITIONING,this.imageryLayer._requestImagery(this,i)),this.state===r.RECEIVED&&(this.state=r.TRANSITIONING,this.imageryLayer._createTexture(e.context,this));var n=this.state===r.READY&&t&&!this.texture;(this.state===r.TEXTURE_LOADED||n)&&(this.state=r.TRANSITIONING,this.imageryLayer._reprojectTexture(e,this,t))},i}),define("Scene/ImagerySplitDirection",["../Core/freezeObject"],function(e){"use strict";return e({LEFT:-1,NONE:0,RIGHT:1})}),define("Scene/TileImagery",["../Core/defined","./ImageryState"],function(e,t){"use strict";function r(e,t,r){this.readyImagery=void 0,this.loadingImagery=e,this.textureCoordinateRectangle=t,this.textureTranslationAndScale=void 0,this.useWebMercatorT=r}return r.prototype.freeResources=function(){e(this.readyImagery)&&this.readyImagery.releaseReference(),e(this.loadingImagery)&&this.loadingImagery.releaseReference()},r.prototype.processStateMachine=function(r,i){var n=this.loadingImagery,o=n.imageryLayer;if(n.processStateMachine(i,!this.useWebMercatorT,r._priorityFunction),n.state===t.READY)return e(this.readyImagery)&&this.readyImagery.releaseReference(),this.readyImagery=this.loadingImagery,this.loadingImagery=void 0,this.textureTranslationAndScale=o._calculateTextureTranslationAndScale(r,this),!0;for(var a,s=n.parent;e(s)&&(s.state!==t.READY||!this.useWebMercatorT&&!e(s.texture));)s.state!==t.FAILED&&s.state!==t.INVALID&&(a=a||s),s=s.parent;return this.readyImagery!==s&&(e(this.readyImagery)&&this.readyImagery.releaseReference(),this.readyImagery=s,e(s)&&(s.addReference(),this.textureTranslationAndScale=o._calculateTextureTranslationAndScale(r,this))),(n.state===t.FAILED||n.state===t.INVALID)&&(!e(a)||(a.processStateMachine(i,!this.useWebMercatorT,r._priorityFunction),!1))},r}),define("Scene/ImageryLayer",["../Core/Cartesian2","../Core/Cartesian4","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/GeographicTilingScheme","../Core/IndexDatatype","../Core/Math","../Core/PixelFormat","../Core/Rectangle","../Core/Request","../Core/RequestState","../Core/RequestType","../Core/TerrainProvider","../Core/TileProviderError","../Core/WebMercatorProjection","../Core/WebMercatorTilingScheme","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ComputeCommand","../Renderer/ContextLimits","../Renderer/MipmapHint","../Renderer/Sampler","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Renderer/VertexArray","../Shaders/ReprojectWebMercatorFS","../Shaders/ReprojectWebMercatorVS","../ThirdParty/when","./Imagery","./ImagerySplitDirection","./ImageryState","./TileImagery"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U){"use strict";function V(e,t){this._imageryProvider=e,t=r(t,{}),this.alpha=r(t.alpha,r(e.defaultAlpha,1)),this.brightness=r(t.brightness,r(e.defaultBrightness,V.DEFAULT_BRIGHTNESS)),this.contrast=r(t.contrast,r(e.defaultContrast,V.DEFAULT_CONTRAST)),this.hue=r(t.hue,r(e.defaultHue,V.DEFAULT_HUE)),this.saturation=r(t.saturation,r(e.defaultSaturation,V.DEFAULT_SATURATION)),this.gamma=r(t.gamma,r(e.defaultGamma,V.DEFAULT_GAMMA)),this.splitDirection=r(t.splitDirection,r(e.defaultSplit,V.DEFAULT_SPLIT)),this.minificationFilter=r(t.minificationFilter,r(e.defaultMinificationFilter,V.DEFAULT_MINIFICATION_FILTER)),this.magnificationFilter=r(t.magnificationFilter,r(e.defaultMagnificationFilter,V.DEFAULT_MAGNIFICATION_FILTER)),this.show=r(t.show,!0),this._minimumTerrainLevel=t.minimumTerrainLevel,this._maximumTerrainLevel=t.maximumTerrainLevel,this._rectangle=r(t.rectangle,h.MAX_VALUE),this._maximumAnisotropy=t.maximumAnisotropy,this._imageryCache={},this._skeletonPlaceholder=new U(k.createPlaceholder(this)),this._show=!0,this._layerIndex=-1,this._isBaseLayer=!1,this._requestImageError=void 0,this._reprojectComputeCommands=[]}function z(e,t,r){return e+":"+t+":"+r}function G(e,t,n,o){var a=e.minificationFilter,s=e.magnificationFilter;if(a===I.LINEAR&&s===D.LINEAR&&!d.isCompressedFormat(o.pixelFormat)&&c.isPowerOfTwo(o.width)&&c.isPowerOfTwo(o.height)){a=I.LINEAR_MIPMAP_LINEAR;var l=w.maximumTextureFilterAnisotropy,u=Math.min(l,r(e._maximumAnisotropy,l)),h=z(a,s,u),p=t.cache.imageryLayerMipmapSamplers;i(p)||(p={},t.cache.imageryLayerMipmapSamplers=p);var f=p[h];i(f)||(f=p[h]=new E({wrapS:O.CLAMP_TO_EDGE,wrapT:O.CLAMP_TO_EDGE,minificationFilter:a,magnificationFilter:s,maximumAnisotropy:u})),o.generateMipmap(T.NICEST),o.sampler=f}else{var m=z(a,s,0),g=t.cache.imageryLayerNonMipmapSamplers;i(g)||(g={},t.cache.imageryLayerNonMipmapSamplers=g);var _=g[m];i(_)||(_=g[m]=new E({wrapS:O.CLAMP_TO_EDGE,wrapT:O.CLAMP_TO_EDGE,minificationFilter:a,magnificationFilter:s})),o.sampler=_}n.state=B.READY}function W(e,t,r){return JSON.stringify([e,t,r])}function H(e,t,r,n){var o=t.cache.imageryLayer_reproject;if(!i(o)){o=t.cache.imageryLayer_reproject={vertexArray:void 0,shaderProgram:void 0,sampler:void 0,destroy:function(){i(this.framebuffer)&&this.framebuffer.destroy(),i(this.vertexArray)&&this.vertexArray.destroy(),i(this.shaderProgram)&&this.shaderProgram.destroy()}};for(var a=new Float32Array(256),s=0,l=0;l<64;++l){var d=l/63;a[s++]=0,a[s++]=d,a[s++]=1,a[s++]=d}var h={position:0,webMercatorT:1},p=g.getRegularGridIndices(2,64),f=b.createIndexBuffer({context:t,typedArray:p,usage:C.STATIC_DRAW,indexDatatype:u.UNSIGNED_SHORT});o.vertexArray=new M({context:t,attributes:[{index:h.position,vertexBuffer:b.createVertexBuffer({context:t,typedArray:a,usage:C.STATIC_DRAW}),componentsPerAttribute:2},{index:h.webMercatorT,vertexBuffer:b.createVertexBuffer({context:t,sizeInBytes:512,usage:C.STREAM_DRAW}),componentsPerAttribute:1}],indexBuffer:f});var m=new x({sources:[L]});o.shaderProgram=A.fromCache({context:t,vertexShaderSource:m,fragmentShaderSource:R,attributeLocations:h}),o.sampler=new E({wrapS:O.CLAMP_TO_EDGE,wrapT:O.CLAMP_TO_EDGE,minificationFilter:I.LINEAR,magnificationFilter:D.LINEAR})}r.sampler=o.sampler;var _=r.width,v=r.height;Z.textureDimensions.x=_,Z.textureDimensions.y=v,Z.texture=r;var y=Math.sin(n.south),S=.5*Math.log((1+y)/(1-y));y=Math.sin(n.north);var w=.5*Math.log((1+y)/(1-y)),N=1/(w-S),k=new P({context:t,width:_,height:v,pixelFormat:r.pixelFormat,pixelDatatype:r.pixelDatatype,preMultiplyAlpha:r.preMultiplyAlpha});c.isPowerOfTwo(_)&&c.isPowerOfTwo(v)&&k.generateMipmap(T.NICEST);for(var F=n.south,B=n.north,U=K,V=0,z=0;z<64;++z){var G=z/63,W=c.lerp(F,B,G);y=Math.sin(W);var H=.5*Math.log((1+y)/(1-y)),j=(H-S)*N;U[V++]=j,U[V++]=j}o.vertexArray.getAttribute(1).vertexBuffer.copyFromArrayView(U),e.shaderProgram=o.shaderProgram,e.outputTexture=k,e.uniformMap=Z,e.vertexArray=o.vertexArray}function j(e,t,r){var i=e._imageryProvider,n=i.tilingScheme,o=n.ellipsoid,a=e._imageryProvider.tilingScheme instanceof l?1:Math.cos(r),s=n.rectangle,u=o.maximumRadius*s.width*a/(i.tileWidth*n.getNumberOfXTilesAtLevel(0)),c=u/t,d=Math.log(c)/Math.log(2);return 0|Math.round(d)}n(V.prototype,{imageryProvider:{get:function(){return this._imageryProvider}},rectangle:{get:function(){return this._rectangle}}}),V.DEFAULT_BRIGHTNESS=1,V.DEFAULT_CONTRAST=1,V.DEFAULT_HUE=0,V.DEFAULT_SATURATION=1,V.DEFAULT_GAMMA=1,V.DEFAULT_SPLIT=F.NONE,V.DEFAULT_MINIFICATION_FILTER=I.LINEAR,V.DEFAULT_MAGNIFICATION_FILTER=D.LINEAR,V.prototype.isBaseLayer=function(){return this._isBaseLayer},V.prototype.isDestroyed=function(){return!1},V.prototype.destroy=function(){return o(this)};var q=new h,Y=new h,X=new h,Q=new h;V.prototype.getViewableRectangle=function(){var e=this._imageryProvider,t=this._rectangle;return e.readyPromise.then(function(){return h.intersection(e.rectangle,t)})},V.prototype._createTileImagerySkeletons=function(e,r,n){var o=e.data;if(i(this._minimumTerrainLevel)&&e.level<this._minimumTerrainLevel)return!1;if(i(this._maximumTerrainLevel)&&e.level>this._maximumTerrainLevel)return!1;var a=this._imageryProvider;if(i(n)||(n=o.imagery.length),!a.ready)return this._skeletonPlaceholder.loadingImagery.addReference(),o.imagery.splice(n,0,this._skeletonPlaceholder),!0;var s=a.tilingScheme instanceof y&&e.rectangle.north<v.MaximumLatitude&&e.rectangle.south>-v.MaximumLatitude,l=h.intersection(a.rectangle,this._rectangle,q),u=h.intersection(e.rectangle,l,Y);if(!i(u)){if(!this.isBaseLayer())return!1;var c=l,d=e.rectangle;u=Y,d.south>=c.north?u.north=u.south=c.north:d.north<=c.south?u.north=u.south=c.south:(u.south=Math.max(d.south,c.south),u.north=Math.min(d.north,c.north)),d.west>=c.east?u.west=u.east=c.east:d.east<=c.west?u.west=u.east=c.west:(u.west=Math.max(d.west,c.west),u.east=Math.min(d.east,c.east))}var p=0;u.south>0?p=u.south:u.north<0&&(p=u.north);var f=1*r.getLevelMaximumGeometricError(e.level),m=j(this,f,p);m=Math.max(0,m);var g=a.maximumLevel;if(m>g&&(m=g),i(a.minimumLevel)){var _=a.minimumLevel;m<_&&(m=_)}var b=a.tilingScheme,C=b.positionToTileXY(h.northwest(u),m),S=b.positionToTileXY(h.southeast(u),m),w=e.rectangle.width/512,T=e.rectangle.height/512,E=b.tileXYToRectangle(C.x,C.y,m);Math.abs(E.south-e.rectangle.north)<T&&C.y<S.y&&++C.y,Math.abs(E.east-e.rectangle.west)<w&&C.x<S.x&&++C.x;var A=b.tileXYToRectangle(S.x,S.y,m);Math.abs(A.north-e.rectangle.south)<T&&S.y>C.y&&--S.y,Math.abs(A.west-e.rectangle.east)<w&&S.x>C.x&&--S.x;var x,P=h.clone(e.rectangle,Q),D=b.tileXYToRectangle(C.x,C.y,m),I=h.intersection(D,l,X);s?(b.rectangleToNativeRectangle(P,P),b.rectangleToNativeRectangle(D,D),b.rectangleToNativeRectangle(I,I),b.rectangleToNativeRectangle(l,l),x=b.tileXYToNativeRectangle.bind(b),w=P.width/512,T=P.height/512):x=b.tileXYToRectangle.bind(b);var O,M,R=0,L=1;!this.isBaseLayer()&&Math.abs(I.west-P.west)>=w&&(R=Math.min(1,(I.west-P.west)/P.width)),!this.isBaseLayer()&&Math.abs(I.north-P.north)>=T&&(L=Math.max(0,(I.north-P.south)/P.height));for(var N=L,k=C.x;k<=S.x;k++)if(O=R,D=x(k,C.y,m),I=h.simpleIntersection(D,l,X),i(I)){R=Math.min(1,(I.east-P.west)/P.width),k===S.x&&(this.isBaseLayer()||Math.abs(I.east-P.east)<w)&&(R=1),L=N;for(var F=C.y;F<=S.y;F++)if(M=L,D=x(k,F,m),I=h.simpleIntersection(D,l,X),i(I)){L=Math.max(0,(I.south-P.south)/P.height),F===S.y&&(this.isBaseLayer()||Math.abs(I.south-P.south)<T)&&(L=0);var B=new t(O,L,R,M),V=this.getImageryFromCache(k,F,m);o.imagery.splice(n,0,new U(V,B,s)),++n}}return!0},V.prototype._calculateTextureTranslationAndScale=function(e,r){var i=r.readyImagery.rectangle,n=e.rectangle;if(r.useWebMercatorT){var o=r.readyImagery.imageryLayer.imageryProvider.tilingScheme;i=o.rectangleToNativeRectangle(i,q),n=o.rectangleToNativeRectangle(n,Q)}var a=n.width,s=n.height,l=a/i.width,u=s/i.height;return new t(l*(n.west-i.west)/a,u*(n.south-i.south)/s,l,u)},V.prototype._requestImagery=function(e,t){function r(t){if(!i(t))return n();e.image=t,e.state=B.RECEIVED,e.request=void 0,_.handleSuccess(s._requestImageError)}function n(t){if(e.request.state===f.CANCELLED)return e.state=B.UNLOADED,void(e.request=void 0);e.state=B.FAILED,e.request=void 0;var r="Failed to obtain image tile X: "+e.x+" Y: "+e.y+" Level: "+e.level+".";s._requestImageError=_.handleError(s._requestImageError,a,a.errorEvent,r,e.x,e.y,e.level,o,t)}function o(){var o=new p({throttle:!0,throttleByServer:!0,type:m.IMAGERY,priorityFunction:t});e.request=o,e.state=B.TRANSITIONING;var s=a.requestImage(e.x,e.y,e.level,o);if(!i(s))return e.state=B.UNLOADED,void(e.request=void 0);i(a.getTileCredits)&&(e.credits=a.getTileCredits(e.x,e.y,e.level)),N(s,r,n)}var a=this._imageryProvider,s=this;o()},V.prototype._createTexture=function(e,t){var r=this._imageryProvider,n=t.image;if(i(r.tileDiscardPolicy)){var o=r.tileDiscardPolicy;if(i(o)){if(!o.isReady())return void(t.state=B.RECEIVED);if(o.shouldDiscardImage(n))return void(t.state=B.INVALID)}}var a,s=new E({minificationFilter:this.minificationFilter,magnificationFilter:this.magnificationFilter});a=new P(i(n.internalFormat)?{context:e,pixelFormat:n.internalFormat,width:n.width,height:n.height,source:{arrayBufferView:n.bufferView},sampler:s}:{context:e,source:n,pixelFormat:r.hasAlphaChannel?d.RGBA:d.RGB,sampler:s}),r.tilingScheme instanceof y?t.textureWebMercator=a:t.texture=a,t.image=void 0,t.state=B.TEXTURE_LOADED},V.prototype._reprojectTexture=function(e,t,i){var n=t.textureWebMercator||t.texture,o=t.rectangle,a=e.context;if((i=r(i,!0))&&!(this._imageryProvider.tilingScheme instanceof l)&&o.width/n.width>1e-5){var s=this;t.addReference();var u=new S({persists:!0,owner:this,preExecute:function(e){H(e,a,n,t.rectangle)},postExecute:function(e){t.texture=e,G(s,a,t,e),t.releaseReference()}});this._reprojectComputeCommands.push(u)}else i&&(t.texture=n),G(this,a,t,n)},V.prototype.queueReprojectionCommands=function(e){for(var t=this._reprojectComputeCommands,r=t.length,i=0;i<r;++i)e.commandList.push(t[i]);t.length=0},V.prototype.cancelReprojections=function(){this._reprojectComputeCommands.length=0},V.prototype.getImageryFromCache=function(e,t,r,n){var o=W(e,t,r),a=this._imageryCache[o];return i(a)||(a=new k(this,e,t,r,n),this._imageryCache[o]=a),a.addReference(),a},V.prototype.removeImageryFromCache=function(e){var t=W(e.x,e.y,e.level);delete this._imageryCache[t]};var Z={u_textureDimensions:function(){return this.textureDimensions},u_texture:function(){return this.texture},textureDimensions:new e,texture:void 0},K=s.supportsTypedArrays()?new Float32Array(128):void 0;return V}),define("Scene/GlobeSurfaceTileProvider",["../Core/BoundingSphere","../Core/BoxOutlineGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/ClippingPlaneCollection","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/combine","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../Core/GeometryInstance","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Intersect","../Core/Math","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/OrthographicFrustum","../Core/Plane","../Core/PrimitiveType","../Core/Rectangle","../Core/SphereOutlineGeometry","../Core/TerrainQuantization","../Core/Visibility","../Core/WebMercatorProjection","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Pass","../Renderer/RenderState","../Renderer/VertexArray","../Scene/BlendingState","../Scene/DepthFunction","../Scene/PerInstanceColorAppearance","../Scene/Primitive","./GlobeSurfaceTile","./ImageryLayer","./QuadtreeTileLoadState","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j){"use strict";function q(e){this.lightingFadeOutDistance=65e5,this.lightingFadeInDistance=9e6,this.hasWaterMask=!1,this.oceanNormalMap=void 0,this.zoomedOutOceanSpecularIntensity=.5,this.enableLighting=!1,this.shadows=j.RECEIVE_ONLY,this._quadtree=void 0,this._terrainProvider=e.terrainProvider,this._imageryLayers=e.imageryLayers,this._surfaceShaderSet=e.surfaceShaderSet,this._renderState=void 0,this._blendRenderState=void 0,this._pickRenderState=void 0,this._errorEvent=new f,this._imageryLayers.layerAdded.addEventListener(q.prototype._onLayerAdded,this),this._imageryLayers.layerRemoved.addEventListener(q.prototype._onLayerRemoved,this),this._imageryLayers.layerMoved.addEventListener(q.prototype._onLayerMoved,this),this._imageryLayers.layerShownOrHidden.addEventListener(q.prototype._onLayerShownOrHidden,this),this._tileLoadedEvent=new f,this._imageryLayersUpdatedEvent=new f,this._layerOrderChanged=!1,this._tilesToRenderByTextureCount=[],this._drawCommands=[],this._uniformMaps=[],this._pickCommands=[],this._usedDrawCommands=0,this._usedPickCommands=0,this._vertexArraysToDestroy=[],this._debug={wireframe:!1,boundingSphereTile:void 0},this._baseColor=void 0,this._firstPassInitialColor=void 0,this.baseColor=new a(0,0,.5,1),this.clippingPlanes=void 0}function Y(e,t){var r=e.loadingImagery;c(r)||(r=e.readyImagery);var i=t.loadingImagery;return c(i)||(i=t.readyImagery),r.imageryLayer._layerIndex-i.imageryLayer._layerIndex}function X(e){var t=e.indexBuffer;e.destroy(),!t.isDestroyed()&&c(t.referenceCount)&&0===--t.referenceCount&&t.destroy()}function Q(e,t){var r=t.creditDisplay;e._terrainProvider.ready&&c(e._terrainProvider.credit)&&r.addCredit(e._terrainProvider.credit);for(var i=e._imageryLayers,n=0,o=i.length;n<o;++n){var a=i.get(n).imageryProvider;a.ready&&c(a.credit)&&r.addCredit(a.credit)}}function Z(e,t,r){return function(i){var n,o,a,s=-1,l=i.data.imagery,d=l.length;for(a=0;a<d;++a)if(n=l[a],o=u(n.readyImagery,n.loadingImagery),o.imageryLayer===t){s=a;break}if(-1!==s){var h=s+e;if(n=l[h],o=c(n)?u(n.readyImagery,n.loadingImagery):void 0,!c(o)||o.imageryLayer!==t)return!t._createTileImagerySkeletons(i,r,h);for(a=s;a<h;++a)l[a].freeResources();l.splice(s,e)}return!0}}function K(e){return{u_initialColor:function(){return this.properties.initialColor},u_zoomedOutOceanSpecularIntensity:function(){return this.properties.zoomedOutOceanSpecularIntensity},u_oceanNormalMap:function(){return this.properties.oceanNormalMap},u_lightingFadeDistance:function(){return this.properties.lightingFadeDistance},u_center3D:function(){return this.properties.center3D},u_tileRectangle:function(){return this.properties.tileRectangle},u_modifiedModelView:function(){var t=e.context.uniformState.view,r=b.multiplyByPoint(t,this.properties.rtc,se);return b.setTranslation(t,r,ie),ie},u_modifiedModelViewProjection:function(){var t=e.context.uniformState.view,r=e.context.uniformState.projection,i=b.multiplyByPoint(t,this.properties.rtc,se);return b.setTranslation(t,i,ne),b.multiply(r,ne,ne),ne},u_dayTextures:function(){return this.properties.dayTextures},u_dayTextureTranslationAndScale:function(){return this.properties.dayTextureTranslationAndScale},u_dayTextureTexCoordsRectangle:function(){return this.properties.dayTextureTexCoordsRectangle},u_dayTextureUseWebMercatorT:function(){return this.properties.dayTextureUseWebMercatorT},u_dayTextureAlpha:function(){return this.properties.dayTextureAlpha},u_dayTextureBrightness:function(){return this.properties.dayTextureBrightness},u_dayTextureContrast:function(){return this.properties.dayTextureContrast},u_dayTextureHue:function(){return this.properties.dayTextureHue},u_dayTextureSaturation:function(){return this.properties.dayTextureSaturation},u_dayTextureOneOverGamma:function(){return this.properties.dayTextureOneOverGamma},u_dayIntensity:function(){return this.properties.dayIntensity},u_southAndNorthLatitude:function(){return this.properties.southAndNorthLatitude},u_southMercatorYAndOneOverHeight:function(){return this.properties.southMercatorYAndOneOverHeight},u_waterMask:function(){return this.properties.waterMask},u_waterMaskTranslationAndScale:function(){return this.properties.waterMaskTranslationAndScale},u_minMaxHeight:function(){return this.properties.minMaxHeight},u_scaleAndBias:function(){return this.properties.scaleAndBias},u_dayTextureSplit:function(){return this.properties.dayTextureSplit},u_clippingPlanesLength:function(){return this.properties.clippingPlanes.length},u_clippingPlanes:function(){return this.properties.clippingPlanes},u_clippingPlanesEdgeStyle:function(){var e=this.properties.clippingPlanesEdgeColor;return e.alpha=this.properties.clippingPlanesEdgeWidth,e},u_minimumBrightness:function(){return e.fog.minimumBrightness},properties:{initialColor:new n(0,0,.5,1),zoomedOutOceanSpecularIntensity:.5,oceanNormalMap:void 0,lightingFadeDistance:new r(65e5,9e6),center3D:void 0,rtc:new i,modifiedModelView:new b,tileRectangle:new n,dayTextures:[],dayTextureTranslationAndScale:[],dayTextureTexCoordsRectangle:[],dayTextureUseWebMercatorT:[],dayTextureAlpha:[],dayTextureBrightness:[],dayTextureContrast:[],dayTextureHue:[],dayTextureSaturation:[],dayTextureOneOverGamma:[],dayTextureSplit:[],dayIntensity:0,southAndNorthLatitude:new r,southMercatorYAndOneOverHeight:new r,waterMask:void 0,waterMaskTranslationAndScale:new n,minMaxHeight:new r,scaleAndBias:new b,clippingPlanes:[],clippingPlanesEdgeColor:a.clone(a.WHITE),clippingPlanesEdgeWidth:0}}}function J(e,t,r){var i=r.data;c(i.wireframeVertexArray)||c(i.terrainData)&&c(i.terrainData._mesh)&&(i.wireframeVertexArray=$(e,i.vertexArray,i.terrainData._mesh))}function $(e,t,r){var i={indices:r.indices,primitiveType:T.TRIANGLES};g.toWireframe(i);var n=i.indices,o=I.createIndexBuffer({context:e,typedArray:n,usage:O.STATIC_DRAW,indexDatatype:_.UNSIGNED_SHORT});return new k({context:e,attributes:t._attributes,indexBuffer:o})}function ee(t,r,s){var u=r.data,d=s.creditDisplay,h=u.terrainData;if(c(h)&&c(h.credits))for(var p=h.credits,f=0,m=p.length;f<m;++f)d.addCredit(p[f]);var g=M.maximumTextureImageUnits,_=u.waterMaskTexture,v=t.hasWaterMask&&c(_),S=t.oceanNormalMap,w=v&&c(S),A=t.terrainProvider.ready&&t.terrainProvider.hasVertexNormals,P=s.fog.enabled,I=j.castShadows(t.shadows),O=j.receiveShadows(t.shadows);v&&--g,w&&--g;var N=u.center,k=u.pickTerrain.mesh.encoding,F=oe,B=0,U=0,V=0,z=0,W=!1;if(s.mode!==H.SCENE3D){var q=s.mapProjection,Y=q.project(E.southwest(r.rectangle),le),X=q.project(E.northeast(r.rectangle),ue);if(F.x=Y.x,F.y=Y.y,F.z=X.x,F.w=X.y,s.mode!==H.MORPHING&&(N=ae,N.x=0,N.y=.5*(F.z+F.x),N.z=.5*(F.w+F.y),F.x-=N.y,F.y-=N.z,F.z-=N.y,F.w-=N.z),s.mode===H.SCENE2D&&k.quantization===x.BITS12){var Q=1/(Math.pow(2,12)-1)*.5,Z=(F.z-F.x)*Q,$=(F.w-F.y)*Q;F.x-=Z,F.y-=$,F.z+=Z,F.w+=$}q instanceof D&&(B=r.rectangle.south,U=r.rectangle.north,V=D.geodeticLatitudeToMercatorAngle(B),z=1/(D.geodeticLatitudeToMercatorAngle(U)-V),W=!0)}var ee=u.imagery,te=0,re=ee.length,ie=t._renderState,ne=t._blendRenderState,se=ie,fe=t._firstPassInitialColor,me=s.context;c(t._debug.boundingSphereTile)||he();do{var ge,_e,ve=0;t._drawCommands.length<=t._usedDrawCommands?(ge=new R,ge.owner=r,ge.cull=!1,ge.boundingVolume=new e,ge.orientedBoundingBox=void 0,_e=K(s),t._drawCommands.push(ge),t._uniformMaps.push(_e)):(ge=t._drawCommands[t._usedDrawCommands],_e=t._uniformMaps[t._usedDrawCommands]),ge.owner=r,++t._usedDrawCommands,r===t._debug.boundingSphereTile&&(c(u.orientedBoundingBox)?ce(u.orientedBoundingBox,a.RED).update(s):c(u.boundingSphere3D)&&de(u.boundingSphere3D,a.RED).update(s));var ye=_e.properties;n.clone(fe,ye.initialColor),ye.oceanNormalMap=S,ye.lightingFadeDistance.x=t.lightingFadeOutDistance,ye.lightingFadeDistance.y=t.lightingFadeInDistance,ye.zoomedOutOceanSpecularIntensity=t.zoomedOutOceanSpecularIntensity,ye.center3D=u.center,i.clone(N,ye.rtc),n.clone(F,ye.tileRectangle),ye.southAndNorthLatitude.x=B,ye.southAndNorthLatitude.y=U,ye.southMercatorYAndOneOverHeight.x=V,ye.southMercatorYAndOneOverHeight.y=z;for(var be=P&&y.fog(r._distance,s.fog.density)>y.EPSILON3,Ce=!1,Se=!1,we=!1,Te=!1,Ee=!1,Ae=!1,xe=!1;ve<g&&te<re;){var Pe=ee[te],De=Pe.readyImagery;if(++te,c(De)&&0!==De.imageryLayer.alpha){var Ie=Pe.useWebMercatorT?De.textureWebMercator:De.texture,Oe=De.imageryLayer;if(c(Pe.textureTranslationAndScale)||(Pe.textureTranslationAndScale=Oe._calculateTextureTranslationAndScale(r,Pe)),ye.dayTextures[ve]=Ie,ye.dayTextureTranslationAndScale[ve]=Pe.textureTranslationAndScale,ye.dayTextureTexCoordsRectangle[ve]=Pe.textureCoordinateRectangle,ye.dayTextureUseWebMercatorT[ve]=Pe.useWebMercatorT,ye.dayTextureAlpha[ve]=Oe.alpha,Ae=Ae||1!==ye.dayTextureAlpha[ve],ye.dayTextureBrightness[ve]=Oe.brightness,Ce=Ce||ye.dayTextureBrightness[ve]!==G.DEFAULT_BRIGHTNESS,ye.dayTextureContrast[ve]=Oe.contrast,Se=Se||ye.dayTextureContrast[ve]!==G.DEFAULT_CONTRAST,ye.dayTextureHue[ve]=Oe.hue,we=we||ye.dayTextureHue[ve]!==G.DEFAULT_HUE,ye.dayTextureSaturation[ve]=Oe.saturation,Te=Te||ye.dayTextureSaturation[ve]!==G.DEFAULT_SATURATION,ye.dayTextureOneOverGamma[ve]=1/Oe.gamma,Ee=Ee||ye.dayTextureOneOverGamma[ve]!==1/G.DEFAULT_GAMMA,ye.dayTextureSplit[ve]=Oe.splitDirection,xe=xe||0!==ye.dayTextureSplit[ve],c(De.credits))for(var Me=De.credits,Re=0,Le=Me.length;Re<Le;++Re)d.addCredit(Me[Re]);++ve}}ye.dayTextures.length=ve,ye.waterMask=_,n.clone(u.waterMaskTranslationAndScale,ye.waterMaskTranslationAndScale),ye.minMaxHeight.x=k.minimumHeight,ye.minMaxHeight.y=k.maximumHeight,b.clone(k.matrix,ye.scaleAndBias);var Ne=t.clippingPlanes,ke=0;c(Ne)&&r.isClipped&&(ke=Ne.length);var Fe=ye.clippingPlanes,Be=Fe.length;if(Be!==ke){Fe.length=ke;for(var Ue=Be;Ue<ke;++Ue)Fe[Ue]=new n}c(Ne)&&Ne.enabled&&r.isClipped&&(Ne.transformAndPackPlanes(me.uniformState.view,Fe),ye.clippingPlanesEdgeColor=a.clone(Ne.edgeColor,ye.clippingPlanesEdgeColor),ye.clippingPlanesEdgeWidth=Ne.edgeWidth);var Ve=c(Ne)&&Ne.enabled&&ye.clippingPlanes.length>0&&o.isSupported(),ze=!!Ve&&Ne.unionClippingRegions;c(t.uniformMap)&&(_e=l(_e,t.uniformMap)),ge.shaderProgram=t._surfaceShaderSet.getShaderProgram(s,u,ve,Ce,Se,we,Te,Ee,Ae,xe,v,w,t.enableLighting,A,W,be,Ve,ze),ge.castShadows=I,ge.receiveShadows=O,ge.renderState=se,ge.primitiveType=T.TRIANGLES,ge.vertexArray=u.vertexArray,ge.uniformMap=_e,ge.pass=L.GLOBE,t._debug.wireframe&&(J(me,t,r),c(u.wireframeVertexArray)&&(ge.vertexArray=u.wireframeVertexArray,ge.primitiveType=T.LINES));var Ge=ge.boundingVolume,We=ge.orientedBoundingBox;s.mode!==H.SCENE3D?(e.fromRectangleWithHeights2D(r.rectangle,s.mapProjection,u.minimumHeight,u.maximumHeight,Ge),i.fromElements(Ge.center.z,Ge.center.x,Ge.center.y,Ge.center),s.mode===H.MORPHING&&(Ge=e.union(u.boundingSphere3D,Ge,Ge))):(ge.boundingVolume=e.clone(u.boundingSphere3D,Ge),ge.orientedBoundingBox=C.clone(u.orientedBoundingBox,We)),s.commandList.push(ge),se=ne,fe=pe}while(te<re)}function te(e,t,r){var i;e._pickCommands.length<=e._usedPickCommands?(i=new R,i.cull=!1,e._pickCommands.push(i)):i=e._pickCommands[e._usedPickCommands],++e._usedPickCommands;var n=t.owner.data,o=r.projection instanceof D;i.shaderProgram=e._surfaceShaderSet.getPickShaderProgram(r,n,o),i.renderState=e._pickRenderState,i.owner=t.owner,i.primitiveType=t.primitiveType,i.vertexArray=t.vertexArray,i.uniformMap=t.uniformMap,i.boundingVolume=t.boundingVolume,i.orientedBoundingBox=t.orientedBoundingBox,i.pass=t.pass,r.commandList.push(i)}d(q.prototype,{baseColor:{get:function(){return this._baseColor},set:function(e){this._baseColor=e,this._firstPassInitialColor=n.fromColor(e,this._firstPassInitialColor)}},quadtree:{get:function(){ +return this._quadtree},set:function(e){this._quadtree=e}},ready:{get:function(){return this._terrainProvider.ready&&(0===this._imageryLayers.length||this._imageryLayers.get(0).imageryProvider.ready)}},tilingScheme:{get:function(){return this._terrainProvider.tilingScheme}},errorEvent:{get:function(){return this._errorEvent}},tileLoadedEvent:{get:function(){return this._tileLoadedEvent}},imageryLayersUpdatedEvent:{get:function(){return this._imageryLayersUpdatedEvent}},terrainProvider:{get:function(){return this._terrainProvider},set:function(e){this._terrainProvider!==e&&(this._terrainProvider=e,c(this._quadtree)&&this._quadtree.invalidateAllTiles())}}}),q.prototype.update=function(e){this._imageryLayers._update()},q.prototype.initialize=function(e){this._imageryLayers.queueReprojectionCommands(e),this._layerOrderChanged&&(this._layerOrderChanged=!1,this._quadtree.forEachLoadedTile(function(e){e.data.imagery.sort(Y)})),Q(this,e);for(var t=this._vertexArraysToDestroy,r=t.length,i=0;i<r;++i)X(t[i]);t.length=0},q.prototype.beginUpdate=function(e){for(var t=this._tilesToRenderByTextureCount,r=0,i=t.length;r<i;++r){var n=t[r];c(n)&&(n.length=0)}this._usedDrawCommands=0},q.prototype.endUpdate=function(e){c(this._renderState)||(this._renderState=N.fromCache({cull:{enabled:!0},depthTest:{enabled:!0,func:B.LESS}}),this._blendRenderState=N.fromCache({cull:{enabled:!0},depthTest:{enabled:!0,func:B.LESS_OR_EQUAL},blending:F.ALPHA_BLEND}));for(var t=this._tilesToRenderByTextureCount,r=0,i=t.length;r<i;++r){var n=t[r];if(c(n))for(var o=0,a=n.length;o<a;++o)ee(this,n[o],e)}},q.prototype.updateForPick=function(e){c(this._pickRenderState)||(this._pickRenderState=N.fromCache({colorMask:{red:!1,green:!1,blue:!1,alpha:!1},depthTest:{enabled:!0}})),this._usedPickCommands=0;for(var t=this._drawCommands,r=0,i=this._usedDrawCommands;r<i;++r)te(this,t[r],e)},q.prototype.cancelReprojections=function(){this._imageryLayers.cancelReprojections()},q.prototype.getLevelMaximumGeometricError=function(e){return this._terrainProvider.getLevelMaximumGeometricError(e)},q.prototype.loadTile=function(e,t){z.processStateMachine(t,e,this._terrainProvider,this._imageryLayers,this._vertexArraysToDestroy);var r=this._tileLoadedEvent;t._loadedCallbacks.tileLoadedEvent=function(e){return r.raiseEvent(),!0}};var re=new e;q.prototype.computeTileVisibility=function(t,r,n){var o=this.computeDistanceToTile(t,r);if(t._distance=o,r.fog.enabled&&y.fog(o,r.fog.density)>=1)return P.NONE;var a=t.data,s=r.cullingVolume,l=u(a.orientedBoundingBox,a.boundingSphere3D);r.mode!==H.SCENE3D&&(l=re,e.fromRectangleWithHeights2D(t.rectangle,r.mapProjection,a.minimumHeight,a.maximumHeight,l),i.fromElements(l.center.z,l.center.x,l.center.y,l.center),r.mode===H.MORPHING&&(l=e.union(a.boundingSphere3D,l,l)));var d=this.clippingPlanes;if(c(d)&&d.enabled){var h=d.computeIntersectionWithBoundingVolume(l);if(t.isClipped=h!==v.INSIDE,h===v.OUTSIDE)return P.NONE}var p=s.computeVisibility(l);if(p===v.OUTSIDE)return P.NONE;var f=r.mode===H.SCENE3D&&r.camera.frustum instanceof S;if(r.mode===H.SCENE3D&&!f&&c(n)){var m=a.occludeePointInScaledSpace;return c(m)?n.ellipsoid.isScaledSpacePointVisible(m)?p:P.NONE:p}return p};var ie=new b,ne=new b,oe=new n,ae=new i,se=new i,le=new i,ue=new i;q.prototype.showTileThisFrame=function(e,t){for(var r=0,i=e.data.imagery,n=0,o=i.length;n<o;++n){var a=i[n];c(a.readyImagery)&&0!==a.readyImagery.imageryLayer.alpha&&++r}var s=this._tilesToRenderByTextureCount[r];c(s)||(s=[],this._tilesToRenderByTextureCount[r]=s),s.push(e);var l=this._debug;++l.tilesRendered,l.texturesRendered+=r},q.prototype.computeDistanceToTile=function(e,t){return e.data.tileBoundingRegion.distanceToCamera(t)},q.prototype.isDestroyed=function(){return!1},q.prototype.destroy=function(){return this._tileProvider=this._tileProvider&&this._tileProvider.destroy(),h(this)},q.prototype._onLayerAdded=function(e,t){if(e.show){var r=this._terrainProvider,i=this,n=e.imageryProvider,o=this._imageryLayersUpdatedEvent;n._reload=function(){e._imageryCache={},i._quadtree.forEachLoadedTile(function(t){if(!c(t._loadedCallbacks[e._layerIndex])){var i,n=t.data.imagery,o=n.length,a=-1,s=0;for(i=0;i<o;++i){var l=n[i];if(u(l.readyImagery,l.loadingImagery).imageryLayer===e)-1===a&&(a=i),++s;else if(-1!==a)break}if(-1!==a){var d=a+s;e._createTileImagerySkeletons(t,r,d)&&(t._loadedCallbacks[e._layerIndex]=Z(s,e,r),t.state=W.LOADING)}}})},this._quadtree.forEachLoadedTile(function(t){e._createTileImagerySkeletons(t,r)&&(t.state=W.LOADING)}),this._layerOrderChanged=!0,o.raiseEvent()}},q.prototype._onLayerRemoved=function(e,t){this._quadtree.forEachLoadedTile(function(t){for(var r=t.data.imagery,i=-1,n=0,o=0,a=r.length;o<a;++o){var s=r[o],l=s.loadingImagery;if(c(l)||(l=s.readyImagery),l.imageryLayer===e)-1===i&&(i=o),s.freeResources(),++n;else if(-1!==i)break}-1!==i&&r.splice(i,n)}),c(e.imageryProvider)&&(e.imageryProvider._reload=void 0),this._imageryLayersUpdatedEvent.raiseEvent()},q.prototype._onLayerMoved=function(e,t,r){this._layerOrderChanged=!0,this._imageryLayersUpdatedEvent.raiseEvent()},q.prototype._onLayerShownOrHidden=function(e,t,r){r?this._onLayerAdded(e,t):this._onLayerRemoved(e,t)};var ce,de,he;!function(){function e(e){return new V({geometryInstances:e,appearance:new U({translucent:!1,flat:!0}),asynchronous:!1})}var r,n,o=new m({geometry:t.fromDimensions({dimensions:new i(2,2,2)})}),a=new m({geometry:new A({radius:1})}),l=new b;ce=function(t,i){return t===r?n:(he(),r=t,l=b.fromRotationTranslation(t.halfAxes,t.center,l),o.modelMatrix=l,o.attributes.color=s.fromColor(i),n=e(o))},de=function(t,i){return t===r?n:(he(),r=t,l=b.fromTranslation(t.center,l),l=b.multiplyByUniformScale(l,t.radius,l),a.modelMatrix=l,a.attributes.color=s.fromColor(i),n=e(a))},he=function(){c(n)&&(n.destroy(),n=void 0,r=void 0)}}();var pe=new n(0,0,0,0);return q}),define("Scene/ImageryLayerCollection",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Event","../Core/Math","../Core/Rectangle","../ThirdParty/when","./ImageryLayer"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(){this._layers=[],this.layerAdded=new o,this.layerRemoved=new o,this.layerMoved=new o,this.layerShownOrHidden=new o}function d(e,t){return e.indexOf(t)}function h(e,t,r){var i=e._layers;if(t=a.clamp(t,0,i.length-1),r=a.clamp(r,0,i.length-1),t!==r){var n=i[t];i[t]=i[r],i[r]=n,e._update(),e.layerMoved.raiseEvent(n,r,t)}}r(c.prototype,{length:{get:function(){return this._layers.length}}}),c.prototype.add=function(e,r){t(r)?this._layers.splice(r,0,e):(r=this._layers.length,this._layers.push(e)),this._update(),this.layerAdded.raiseEvent(e,r)},c.prototype.addImageryProvider=function(e,t){var r=new u(e);return this.add(r,t),r},c.prototype.remove=function(t,r){r=e(r,!0);var i=this._layers.indexOf(t);return-1!==i&&(this._layers.splice(i,1),this._update(),this.layerRemoved.raiseEvent(t,i),r&&t.destroy(),!0)},c.prototype.removeAll=function(t){t=e(t,!0);for(var r=this._layers,i=0,n=r.length;i<n;i++){var o=r[i];this.layerRemoved.raiseEvent(o,i),t&&o.destroy()}this._layers=[]},c.prototype.contains=function(e){return-1!==this.indexOf(e)},c.prototype.indexOf=function(e){return this._layers.indexOf(e)},c.prototype.get=function(e){return this._layers[e]},c.prototype.raise=function(e){var t=d(this._layers,e);h(this,t,t+1)},c.prototype.lower=function(e){var t=d(this._layers,e);h(this,t,t-1)},c.prototype.raiseToTop=function(e){var t=d(this._layers,e);t!==this._layers.length-1&&(this._layers.splice(t,1),this._layers.push(e),this._update(),this.layerMoved.raiseEvent(e,this._layers.length-1,t))},c.prototype.lowerToBottom=function(e){var t=d(this._layers,e);0!==t&&(this._layers.splice(t,1),this._layers.splice(0,0,e),this._update(),this.layerMoved.raiseEvent(e,0,t))};var p=new s;return c.prototype.pickImageryLayerFeatures=function(e,r){var i=r.globe.pick(e,r);if(t(i)){for(var n,o=r.globe.ellipsoid.cartesianToCartographic(i),u=r.globe._surface._tilesToRender,c=0;!t(n)&&c<u.length;++c){var d=u[c];s.contains(d.rectangle,o)&&(n=d)}if(t(n)){for(var h=n.data.imagery,f=[],m=[],g=h.length-1;g>=0;--g){var _=h[g],v=_.readyImagery;if(t(v)){var y=v.imageryLayer.imageryProvider;if(t(y.pickFeatures)&&s.contains(v.rectangle,o)){var b=p;if(b.west=a.lerp(n.rectangle.west,n.rectangle.east,_.textureCoordinateRectangle.x-1/1024),b.east=a.lerp(n.rectangle.west,n.rectangle.east,_.textureCoordinateRectangle.z+1/1024),b.south=a.lerp(n.rectangle.south,n.rectangle.north,_.textureCoordinateRectangle.y-1/1024),b.north=a.lerp(n.rectangle.south,n.rectangle.north,_.textureCoordinateRectangle.w+1/1024),s.contains(b,o)){var C=y.pickFeatures(v.x,v.y,v.level,o.longitude,o.latitude);t(C)&&(f.push(C),m.push(v.imageryLayer))}}}}if(0!==f.length)return l.all(f,function(e){for(var r=[],i=0;i<e.length;++i){var n=e[i],a=m[i];if(t(n)&&n.length>0)for(var s=0;s<n.length;++s){var l=n[s];l.imageryLayer=a,t(l.position)||(l.position=o),r.push(l)}}return r})}}},c.prototype.queueReprojectionCommands=function(e){for(var t=this._layers,r=0,i=t.length;r<i;++r)t[r].queueReprojectionCommands(e)},c.prototype.cancelReprojections=function(){for(var e=this._layers,t=0,r=e.length;t<r;++t)e[t].cancelReprojections()},c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return this.removeAll(!0),i(this)},c.prototype._update=function(){var e,r,i,n,o=!0,a=this._layers;for(i=0,n=a.length;i<n;++i)r=a[i],r._layerIndex=i,r.show?(r._isBaseLayer=o,o=!1):r._isBaseLayer=!1,r.show!==r._show&&(t(r._show)&&(t(e)||(e=[]),e.push(r)),r._show=r.show);if(t(e))for(i=0,n=e.length;i<n;++i)r=e[i],this.layerShownOrHidden.raiseEvent(r,r._layerIndex,r.show)},c}),define("Scene/QuadtreeOccluders",["../Core/Cartesian3","../Core/defineProperties","../Core/EllipsoidalOccluder"],function(e,t,r){"use strict";function i(t){this._ellipsoid=new r(t.ellipsoid,e.ZERO)}return t(i.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),i}),define("Scene/QuadtreeTile",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Rectangle","./QuadtreeTileLoadState"],function(e,t,r,i,n){"use strict";function o(e){this._tilingScheme=e.tilingScheme,this._x=e.x,this._y=e.y,this._level=e.level,this._parent=e.parent,this._rectangle=this._tilingScheme.tileXYToRectangle(this._x,this._y,this._level),this._southwestChild=void 0,this._southeastChild=void 0,this._northwestChild=void 0,this._northeastChild=void 0,this._replacementPrevious=void 0,this._replacementNext=void 0,this._distance=0,this._priorityFunction=void 0,this._customData=[],this._frameUpdated=void 0,this._frameRendered=void 0,this._loadedCallbacks={},this.state=n.START,this.renderable=!1,this.upsampledFromParent=!1,this.data=void 0}function a(t){e(t)&&t.freeResources()}return o.createLevelZeroTiles=function(e){for(var t=e.getNumberOfXTilesAtLevel(0),r=e.getNumberOfYTilesAtLevel(0),i=new Array(t*r),n=0,a=0;a<r;++a)for(var s=0;s<t;++s)i[n++]=new o({tilingScheme:e,x:s,y:a,level:0});return i},o.prototype._updateCustomData=function(t,r,n){var o,a,s,l=this.customData;if(e(r)&&e(n)){for(l=l.filter(function(e){return-1===n.indexOf(e)}),this._customData=l,s=this._rectangle,o=0;o<r.length;++o)a=r[o],i.contains(s,a.positionCartographic)&&l.push(a);this._frameUpdated=t}else{var u=this._parent;if(e(u)&&this._frameUpdated!==u._frameUpdated){l.length=0,s=this._rectangle;var c=u.customData;for(o=0;o<c.length;++o)a=c[o],i.contains(s,a.positionCartographic)&&l.push(a);this._frameUpdated=u._frameUpdated}}},t(o.prototype,{tilingScheme:{get:function(){return this._tilingScheme}},x:{get:function(){return this._x}},y:{get:function(){return this._y}},level:{get:function(){return this._level}},parent:{get:function(){return this._parent}},rectangle:{get:function(){return this._rectangle}},children:{get:function(){return[this.northwestChild,this.northeastChild,this.southwestChild,this.southeastChild]}},southwestChild:{get:function(){return e(this._southwestChild)||(this._southwestChild=new o({tilingScheme:this.tilingScheme,x:2*this.x,y:2*this.y+1,level:this.level+1,parent:this})),this._southwestChild}},southeastChild:{get:function(){return e(this._southeastChild)||(this._southeastChild=new o({tilingScheme:this.tilingScheme,x:2*this.x+1,y:2*this.y+1,level:this.level+1,parent:this})),this._southeastChild}},northwestChild:{get:function(){return e(this._northwestChild)||(this._northwestChild=new o({tilingScheme:this.tilingScheme,x:2*this.x,y:2*this.y,level:this.level+1,parent:this})),this._northwestChild}},northeastChild:{get:function(){return e(this._northeastChild)||(this._northeastChild=new o({tilingScheme:this.tilingScheme,x:2*this.x+1,y:2*this.y,level:this.level+1,parent:this})),this._northeastChild}},customData:{get:function(){return this._customData}},needsLoading:{get:function(){return this.state<n.DONE}},eligibleForUnloading:{get:function(){var t=!0;return e(this.data)&&(t=this.data.eligibleForUnloading,e(t)||(t=!0)),t}}}),o.prototype.freeResources=function(){this.state=n.START,this.renderable=!1,this.upsampledFromParent=!1,e(this.data)&&e(this.data.freeResources)&&this.data.freeResources(),a(this._southwestChild),this._southwestChild=void 0,a(this._southeastChild),this._southeastChild=void 0,a(this._northwestChild),this._northwestChild=void 0,a(this._northeastChild),this._northeastChild=void 0},o}),define("Scene/TileReplacementQueue",["../Core/defined"],function(e){"use strict";function t(){this.head=void 0,this.tail=void 0,this.count=0,this._lastBeforeStartOfFrame=void 0}function r(e,t){var r=t.replacementPrevious,i=t.replacementNext;t===e._lastBeforeStartOfFrame&&(e._lastBeforeStartOfFrame=i),t===e.head?e.head=i:r.replacementNext=i,t===e.tail?e.tail=r:i.replacementPrevious=r,t.replacementPrevious=void 0,t.replacementNext=void 0,--e.count}return t.prototype.markStartOfRenderFrame=function(){this._lastBeforeStartOfFrame=this.head},t.prototype.trimTiles=function(t){for(var i=this.tail,n=!0;n&&e(this._lastBeforeStartOfFrame)&&this.count>t&&e(i);){n=i!==this._lastBeforeStartOfFrame;var o=i.replacementPrevious;i.eligibleForUnloading&&(i.freeResources(),r(this,i)),i=o}},t.prototype.markTileRendered=function(t){var i=this.head;return i===t?void(t===this._lastBeforeStartOfFrame&&(this._lastBeforeStartOfFrame=t.replacementNext)):(++this.count,e(i)?((e(t.replacementPrevious)||e(t.replacementNext))&&r(this,t),t.replacementPrevious=void 0,t.replacementNext=i,i.replacementPrevious=t,void(this.head=t)):(t.replacementPrevious=void 0,t.replacementNext=void 0,this.head=t,void(this.tail=t)))},t}),define("Scene/QuadtreePrimitive",["../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../Core/getTimestamp","../Core/Math","../Core/OrthographicFrustum","../Core/Ray","../Core/Rectangle","../Core/Visibility","./QuadtreeOccluders","./QuadtreeTile","./QuadtreeTileLoadState","./SceneMode","./TileReplacementQueue"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_){"use strict";function v(e){this._tileProvider=e.tileProvider,this._tileProvider.quadtree=this,this._debug={enableDebugOutput:!1,maxDepth:0,tilesVisited:0,tilesCulled:0,tilesRendered:0,tilesWaitingForChildren:0,lastMaxDepth:-1,lastTilesVisited:-1,lastTilesCulled:-1,lastTilesRendered:-1,lastTilesWaitingForChildren:-1,suspendLodUpdate:!1};var t=this._tileProvider.tilingScheme,i=t.ellipsoid;this._tilesToRender=[],this._tileLoadQueueHigh=[],this._tileLoadQueueMedium=[],this._tileLoadQueueLow=[],this._tileReplacementQueue=new _,this._levelZeroTiles=void 0,this._loadQueueTimeSlice=5,this._addHeightCallbacks=[],this._removeHeightCallbacks=[],this._tileToUpdateHeights=[],this._lastTileIndex=0,this._updateHeightsTimeSlice=2,this.maximumScreenSpaceError=r(e.maximumScreenSpaceError,2),this.tileCacheSize=r(e.tileCacheSize,100),this._occluders=new p({ellipsoid:i}),this._tileLoadProgressEvent=new a,this._lastTileLoadQueueLength=0}function y(e){var t=e._debug;t.maxDepth=0,t.tilesVisited=0,t.tilesCulled=0,t.tilesRendered=0,t.tilesWaitingForChildren=0,e._tileLoadQueueHigh.length=0,e._tileLoadQueueMedium.length=0,e._tileLoadQueueLow.length=0}function b(e,t){var r=e._tileLoadQueueHigh.length+e._tileLoadQueueMedium.length+e._tileLoadQueueLow.length;r!==e._lastTileLoadQueueLength&&(t.afterRender.push(a.prototype.raiseEvent.bind(e._tileLoadProgressEvent,r)),e._lastTileLoadQueueLength=r);var i=e._debug;i.enableDebugOutput&&!i.suspendLodUpdate&&(i.tilesVisited===i.lastTilesVisited&&i.tilesRendered===i.lastTilesRendered&&i.tilesCulled===i.lastTilesCulled&&i.maxDepth===i.lastMaxDepth&&i.tilesWaitingForChildren===i.lastTilesWaitingForChildren||(console.log("Visited "+i.tilesVisited+", Rendered: "+i.tilesRendered+", Culled: "+i.tilesCulled+", Max Depth: "+i.maxDepth+", Waiting for children: "+i.tilesWaitingForChildren),i.lastTilesVisited=i.tilesVisited,i.lastTilesRendered=i.tilesRendered,i.lastTilesCulled=i.tilesCulled,i.lastMaxDepth=i.maxDepth,i.lastTilesWaitingForChildren=i.tilesWaitingForChildren))}function C(e,t){var r=d.center(e.rectangle,k),i=r.longitude-N.longitude,n=r.latitude-N.latitude;r=d.center(t.rectangle,k);var o=r.longitude-N.longitude,a=r.latitude-N.latitude;return i*i+n*n-(o*o+a*a)}function S(e,t){var r=e._debug;if(!r.suspendLodUpdate){e._tilesToRender.length=0;var n=e._tileProvider;if(!i(e._levelZeroTiles)){if(!n.ready)return;var o=n.tilingScheme;e._levelZeroTiles=f.createLevelZeroTiles(o)}e._occluders.ellipsoid.cameraPosition=t.camera.positionWC;var a,s=e._levelZeroTiles,l=s.length>1?e._occluders:void 0;N=t.camera.positionCartographic,s.sort(C);var u,c,d=e._addHeightCallbacks,p=e._removeHeightCallbacks,m=t.frameNumber;if(d.length>0||p.length>0){for(u=0,c=s.length;u<c;++u)a=s[u],a._updateCustomData(m,d,p);d.length=0,p.length=0}for(u=0,c=s.length;u<c;++u)a=s[u],e._tileReplacementQueue.markTileRendered(a),a.renderable?n.computeTileVisibility(a,t,l)!==h.NONE?w(e,t,a):(a.needsLoading&&e._tileLoadQueueLow.push(a),++r.tilesCulled):(a.needsLoading&&e._tileLoadQueueHigh.push(a),++r.tilesWaitingForChildren)}}function w(e,t,r){var i=e._debug;if(++i.tilesVisited,e._tileReplacementQueue.markTileRendered(r),r._updateCustomData(t.frameNumber),r.level>i.maxDepth&&(i.maxDepth=r.level),P(e,t,r)<e.maximumScreenSpaceError)return r.needsLoading&&e._tileLoadQueueMedium.push(r),void I(e,r);var n=r.southwestChild,o=r.southeastChild,a=r.northwestChild,s=r.northeastChild,l=n.renderable&&o.renderable&&a.renderable&&s.renderable,u=n.upsampledFromParent&&o.upsampledFromParent&&a.upsampledFromParent&&s.upsampledFromParent;l?u?(I(e,r),T(e,t.camera.positionCartographic,n,o,a,s),r.needsLoading&&e._tileLoadQueueMedium.push(r)):(A(e,n,o,a,s,t),r.needsLoading&&e._tileLoadQueueLow.push(r)):(T(e,t.camera.positionCartographic,n,o,a,s),I(e,r),r.needsLoading&&e._tileLoadQueueLow.push(r))}function T(e,t,r,i,n,o){t.longitude<r.east?t.latitude<r.north?(E(e,r),E(e,i),E(e,n),E(e,o)):(E(e,n),E(e,r),E(e,o),E(e,i)):t.latitude<r.north?(E(e,i),E(e,r),E(e,o),E(e,n)):(E(e,o),E(e,n),E(e,i),E(e,r))}function E(e,t){e._tileReplacementQueue.markTileRendered(t),t.needsLoading&&(t.renderable?e._tileLoadQueueLow.push(t):e._tileLoadQueueHigh.push(t))}function A(e,t,r,i,n,o){var a=o.camera.positionCartographic,s=e._tileProvider,l=e._occluders;a.longitude<t.rectangle.east?a.latitude<t.rectangle.north?(x(e,t,s,o,l),x(e,r,s,o,l),x(e,i,s,o,l),x(e,n,s,o,l)):(x(e,i,s,o,l),x(e,t,s,o,l),x(e,n,s,o,l),x(e,r,s,o,l)):a.latitude<t.rectangle.north?(x(e,r,s,o,l),x(e,t,s,o,l),x(e,n,s,o,l),x(e,i,s,o,l)):(x(e,n,s,o,l),x(e,i,s,o,l),x(e,r,s,o,l),x(e,t,s,o,l))}function x(e,t,r,i,n){r.computeTileVisibility(t,i,n)!==h.NONE?w(e,i,t):(++e._debug.tilesCulled,e._tileReplacementQueue.markTileRendered(t),t.needsLoading&&e._tileLoadQueueLow.push(t))}function P(e,t,r){if(t.mode===g.SCENE2D||t.camera.frustum instanceof u)return D(e,t,r);var i=e._tileProvider.getLevelMaximumGeometricError(r.level),n=r._distance,o=t.context.drawingBufferHeight,a=t.camera.frustum.sseDenominator,s=i*o/(n*a);return t.fog.enabled&&(s-=l.fog(n,t.fog.density)*t.fog.sse),s}function D(e,t,r){var n=t.camera,o=n.frustum;i(o._offCenterFrustum)&&(o=o._offCenterFrustum);var a=t.context,s=a.drawingBufferWidth,u=a.drawingBufferHeight,c=e._tileProvider.getLevelMaximumGeometricError(r.level),d=Math.max(o.top-o.bottom,o.right-o.left)/Math.max(s,u),h=c/d;return t.fog.enabled&&t.mode!==g.SCENE2D&&(h-=l.fog(r._distance,t.fog.density)*t.fog.sse),h}function I(e,t){e._tilesToRender.push(t),++e._debug.tilesRendered}function O(e,t){var r=e._tileLoadQueueHigh,i=e._tileLoadQueueMedium,n=e._tileLoadQueueLow;if(0!==r.length||0!==i.length||0!==n.length){e._tileReplacementQueue.trimTiles(e.tileCacheSize);var o=s()+e._loadQueueTimeSlice,a=e._tileProvider;M(e,t,a,o,r),M(e,t,a,o,i),M(e,t,a,o,n)}}function M(e,t,r,i,n){for(var o=0,a=n.length;o<a&&s()<i;++o){var l=n[o];e._tileReplacementQueue.markTileRendered(l),r.loadTile(t,l)}}function R(n,o){for(var a=n._tileToUpdateHeights,l=n._tileProvider.terrainProvider,u=s(),c=n._updateHeightsTimeSlice,h=u+c,p=o.mode,f=o.mapProjection,m=f.ellipsoid;a.length>0;){var _,v=a[0],y=v.customData,b=y.length,C=!1;for(_=n._lastTileIndex;_<b;++_){var S=y[_];if(v.level>S.level){if(i(S.positionOnEllipsoidSurface)||(S.positionOnEllipsoidSurface=e.fromRadians(S.positionCartographic.longitude,S.positionCartographic.latitude,0,m)),p===g.SCENE3D){var w=m.geodeticSurfaceNormal(S.positionOnEllipsoidSurface,F.direction),T=m.getSurfaceNormalIntersectionWithZAxis(S.positionOnEllipsoidSurface,11500,F.origin);if(!i(T)){var E=Math.min(r(v.data.minimumHeight,0),-11500),A=e.multiplyByScalar(w,Math.abs(E)+1,U);e.subtract(S.positionOnEllipsoidSurface,A,F.origin)}}else t.clone(S.positionCartographic,B),B.height=-11500,f.project(B,U),e.fromElements(U.z,U.x,U.y,U),e.clone(U,F.origin),e.clone(e.UNIT_X,F.direction);var x=v.data.pick(F,p,f,!1,U);i(x)&&S.callback(x),S.level=v.level}else if(v.level===S.level){for(var P,D=v.children,I=D.length,O=0;O<I&&(P=D[O],!d.contains(P.rectangle,S.positionCartographic));++O);var M=l.getTileDataAvailable(P.x,P.y,P.level),R=v.parent;(i(M)&&!M||i(R)&&i(R.data)&&i(R.data.terrainData)&&!R.data.terrainData.isChildAvailable(R.x,R.y,P.x,P.y))&&S.removeFunc()}if(s()>=h){C=!0;break}}if(C){n._lastTileIndex=_;break}n._lastTileIndex=0,a.shift()}}function L(e,t){for(var r=e._tileProvider,i=e._tilesToRender,n=e._tileToUpdateHeights,o=0,a=i.length;o<a;++o){var s=i[o];r.showTileThisFrame(s,t),s._frameRendered!==t.frameNumber-1&&n.push(s),s._frameRendered=t.frameNumber}}n(v.prototype,{tileProvider:{get:function(){return this._tileProvider}},tileLoadProgressEvent:{get:function(){return this._tileLoadProgressEvent}}}),v.prototype.invalidateAllTiles=function(){var e=this._tileReplacementQueue;e.head=void 0,e.tail=void 0,e.count=0,y(this);var t=this._levelZeroTiles;if(i(t))for(var r=0;r<t.length;++r){for(var n=t[r],o=n.customData,a=o.length,s=0;s<a;++s){var l=o[s];l.level=0,this._addHeightCallbacks.push(l)}t[r].freeResources()}this._levelZeroTiles=void 0,this._tileProvider.cancelReprojections()},v.prototype.forEachLoadedTile=function(e){for(var t=this._tileReplacementQueue.head;i(t);)t.state!==m.START&&e(t),t=t.replacementNext},v.prototype.forEachRenderedTile=function(e){for(var t=this._tilesToRender,r=0,i=t.length;r<i;++r)e(t[r])},v.prototype.updateHeight=function(e,t){var r=this,i={positionOnEllipsoidSurface:void 0,positionCartographic:e,level:-1,callback:t};return i.removeFunc=function(){for(var e=r._addHeightCallbacks,t=e.length,n=0;n<t;++n)if(e[n]===i){e.splice(n,1);break}r._removeHeightCallbacks.push(i)},r._addHeightCallbacks.push(i),i.removeFunc},v.prototype.update=function(e){i(this._tileProvider.update)&&this._tileProvider.update(e)},v.prototype.beginFrame=function(e){e.passes.render&&(this._tileProvider.initialize(e),this._debug.suspendLodUpdate||(y(this),this._tileReplacementQueue.markStartOfRenderFrame()))},v.prototype.render=function(e){var t=e.passes,r=this._tileProvider;t.render&&(r.beginUpdate(e),S(this,e),L(this,e),r.endUpdate(e)),t.pick&&this._tilesToRender.length>0&&r.updateForPick(e)},v.prototype.endFrame=function(e){e.passes.render&&e.mode!==g.MORPHING&&(O(this,e),R(this,e),b(this,e))},v.prototype.isDestroyed=function(){return!1},v.prototype.destroy=function(){this._tileProvider=this._tileProvider&&this._tileProvider.destroy()};var N,k=new t,F=new c,B=new t,U=new e;return v}),define("Scene/Globe",["../Core/BoundingSphere","../Core/buildModuleUrl","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/EllipsoidTerrainProvider","../Core/Event","../Core/IntersectionTests","../Core/Ray","../Core/Rectangle","../Core/Resource","../Renderer/ShaderSource","../Renderer/Texture","../Shaders/GlobeFS","../Shaders/GlobeVS","../Shaders/GroundAtmosphere","../ThirdParty/when","./GlobeSurfaceShaderSet","./GlobeSurfaceTileProvider","./ImageryLayerCollection","./Material","./QuadtreePrimitive","./SceneMode","./ShadowMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P){"use strict";function D(e){e=n(e,u.WGS84);var r=new c({ellipsoid:e}),i=new T;this._ellipsoid=e,this._imageryLayerCollection=i,this._surfaceShaderSet=new S,this._material=void 0,this._surface=new A({tileProvider:new w({terrainProvider:r,imageryLayers:i,surfaceShaderSet:this._surfaceShaderSet})}),this._terrainProvider=r,this._terrainProviderChanged=new d,I(this),this.show=!0,this._oceanNormalMapResourceDirty=!0,this._oceanNormalMapResource=new m({url:t("Assets/Textures/waterNormalsSmall.jpg")}),this.maximumScreenSpaceError=2,this.tileCacheSize=100,this.enableLighting=!1,this.lightingFadeOutDistance=65e5,this.lightingFadeInDistance=9e6,this.showWaterEffect=!0,this.depthTestAgainstTerrain=!1,this.shadows=P.RECEIVE_ONLY,this._oceanNormalMap=void 0,this._zoomedOutOceanSpecularIntensity=.5}function I(e){var t=[],r=o(e._material)&&(e._material.shaderSource.match(/slope/)||e._material.shaderSource.match("normalEC")),i=[];!o(e._material)||r&&!e._terrainProvider.requestVertexNormals?e._surface._tileProvider.uniformMap=void 0:(i.push(e._material.shaderSource),t.push("APPLY_MATERIAL"),e._surface._tileProvider.uniformMap=e._material._uniforms),i.push(v),e._surfaceShaderSet.baseVertexShaderSource=new g({sources:[b,y],defines:t}),e._surfaceShaderSet.baseFragmentShaderSource=new g({sources:i,defines:t}),e._surfaceShaderSet.material=e._material}function O(t){return function(r,i){return e.distanceSquaredTo(r.pickBoundingSphere,t)-e.distanceSquaredTo(i.pickBoundingSphere,t)}}function M(e,t){return f.contains(e.rectangle,t)?e:void 0}a(D.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},imageryLayers:{get:function(){return this._imageryLayerCollection}},imageryLayersUpdatedEvent:{get:function(){return this._surface.tileProvider.imageryLayersUpdatedEvent}},tileLoadedEvent:{get:function(){return this._surface.tileProvider.tileLoadedEvent}},baseColor:{get:function(){return this._surface.tileProvider.baseColor},set:function(e){this._surface.tileProvider.baseColor=e}},clippingPlanes:{get:function(){return this._surface.tileProvider.clippingPlanes},set:function(e){this._surface.tileProvider.clippingPlanes=e}},oceanNormalMapUrl:{get:function(){return this._oceanNormalMapResource.url},set:function(e){this._oceanNormalMapResource.url=e,this._oceanNormalMapResourceDirty=!0}},terrainProvider:{get:function(){return this._terrainProvider},set:function(e){e!==this._terrainProvider&&(this._terrainProvider=e,this._terrainProviderChanged.raiseEvent(e),o(this._material)&&I(this))}},terrainProviderChanged:{get:function(){return this._terrainProviderChanged}},tileLoadProgressEvent:{get:function(){return this._surface.tileLoadProgressEvent}},material:{get:function(){return this._material},set:function(e){this._material!==e&&(this._material=e,I(this))}}});var R=[],L={start:0,stop:0};D.prototype.pick=function(t,i,n){var a=i.mode,s=i.mapProjection,l=R;l.length=0;var u,c,d=this._surface._tilesToRender,p=d.length;for(c=0;c<p;++c){u=d[c];var f=u.data;if(o(f)){var m=f.pickBoundingSphere;a!==x.SCENE3D?(e.fromRectangleWithHeights2D(u.rectangle,s,f.minimumHeight,f.maximumHeight,m),r.fromElements(m.center.z,m.center.x,m.center.y,m.center)):e.clone(f.boundingSphere3D,m);var g=h.raySphere(t,m,L);o(g)&&l.push(f)}}l.sort(O(t.origin));var _;for(p=l.length,c=0;c<p&&(_=l[c].pick(t,i.mode,i.mapProjection,!0,n),!o(_));++c);return _};var N=new r,k=new r,F=new i,B=new p;return D.prototype.getHeight=function(e){var t=this._surface._levelZeroTiles;if(o(t)){var i,a,s=t.length;for(a=0;a<s&&(i=t[a],!f.contains(i.rectangle,e));++a);if(o(i)&&f.contains(i.rectangle,e)){for(;i.renderable;)i=M(i.southwestChild,e)||M(i.southeastChild,e)||M(i.northwestChild,e)||i.northeastChild;for(;o(i)&&(!o(i.data)||!o(i.data.pickTerrain));)i=i.parent;if(o(i)){var l=this._surface._tileProvider.tilingScheme.ellipsoid,u=r.fromRadians(e.longitude,e.latitude,0,l,N),c=B,d=l.geodeticSurfaceNormal(u,c.direction),h=l.getSurfaceNormalIntersectionWithZAxis(u,11500,c.origin);if(!o(h)){var p=Math.min(n(i.data.minimumHeight,0),-11500),m=r.multiplyByScalar(d,Math.abs(p)+1,k);r.subtract(u,m,c.origin)}var g=i.data.pick(c,void 0,void 0,!1,k);if(o(g))return l.cartesianToCartographic(g,F).height}}}},D.prototype.update=function(e){this.show&&e.passes.render&&this._surface.update(e)},D.prototype.beginFrame=function(e){var t=this._surface,r=t.tileProvider,i=this.terrainProvider,n=this.showWaterEffect&&i.ready&&i.hasWaterMask;if(n&&this._oceanNormalMapResourceDirty){this._oceanNormalMapResourceDirty=!1;var a=this._oceanNormalMapResource,s=a.url;if(o(s)){var l=this;C(a.fetchImage(),function(t){s===l._oceanNormalMapResource.url&&(l._oceanNormalMap=l._oceanNormalMap&&l._oceanNormalMap.destroy(),l._oceanNormalMap=new _({context:e.context,source:t}))})}else this._oceanNormalMap=this._oceanNormalMap&&this._oceanNormalMap.destroy()}var u=e.passes,c=e.mode;u.render&&(c===x.SCENE3D?this._zoomedOutOceanSpecularIntensity=.5:this._zoomedOutOceanSpecularIntensity=0,t.maximumScreenSpaceError=this.maximumScreenSpaceError,t.tileCacheSize=this.tileCacheSize,r.terrainProvider=this.terrainProvider,r.lightingFadeOutDistance=this.lightingFadeOutDistance,r.lightingFadeInDistance=this.lightingFadeInDistance,r.zoomedOutOceanSpecularIntensity=this._zoomedOutOceanSpecularIntensity,r.hasWaterMask=n,r.oceanNormalMap=this._oceanNormalMap,r.enableLighting=this.enableLighting,r.shadows=this.shadows,t.beginFrame(e))},D.prototype.render=function(e){if(this.show){o(this._material)&&this._material.update(e.context);var t=this._surface,r=e.passes;r.render&&t.render(e),r.pick&&t.render(e)}},D.prototype.endFrame=function(e){this.show&&e.passes.render&&this._surface.endFrame(e)},D.prototype.isDestroyed=function(){return!1},D.prototype.destroy=function(){return this._surfaceShaderSet=this._surfaceShaderSet&&this._surfaceShaderSet.destroy(),this._surface=this._surface&&this._surface.destroy(),this._oceanNormalMap=this._oceanNormalMap&&this._oceanNormalMap.destroy(),s(this)},D}),define("Shaders/PostProcessFilters/PassThrough",[],function(){"use strict";return"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_FragColor = texture2D(u_texture, v_textureCoordinates);\n}\n"}),define("Scene/GlobeDepth",["../Core/BoundingRectangle","../Core/Color","../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Texture","../Shaders/PostProcessFilters/PassThrough"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(){this._colorTexture=void 0,this._depthStencilTexture=void 0,this._globeDepthTexture=void 0,this.framebuffer=void 0,this._copyDepthFramebuffer=void 0,this._clearColorCommand=void 0,this._copyColorCommand=void 0,this._copyDepthCommand=void 0,this._viewport=new e,this._rs=void 0,this._useScissorTest=!1,this._scissorRectangle=void 0, +this._debugGlobeDepthViewportCommand=void 0}function h(e,t,i){if(!r(e._debugGlobeDepthViewportCommand)){e._debugGlobeDepthViewportCommand=t.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n float n_range = czm_depthRange.near;\n float f_range = czm_depthRange.far;\n float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n}\n",{uniformMap:{u_texture:function(){return e._globeDepthTexture}},owner:e})}e._debugGlobeDepthViewportCommand.execute(t,i)}function p(e){e._colorTexture=e._colorTexture&&!e._colorTexture.isDestroyed()&&e._colorTexture.destroy(),e._depthStencilTexture=e._depthStencilTexture&&!e._depthStencilTexture.isDestroyed()&&e._depthStencilTexture.destroy(),e._globeDepthTexture=e._globeDepthTexture&&!e._globeDepthTexture.isDestroyed()&&e._globeDepthTexture.destroy()}function f(e){e.framebuffer=e.framebuffer&&!e.framebuffer.isDestroyed()&&e.framebuffer.destroy(),e._copyDepthFramebuffer=e._copyDepthFramebuffer&&!e._copyDepthFramebuffer.isDestroyed()&&e._copyDepthFramebuffer.destroy()}function m(e,t,r,i){e._colorTexture=new u({context:t,width:r,height:i,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE}),e._depthStencilTexture=new u({context:t,width:r,height:i,pixelFormat:n.DEPTH_STENCIL,pixelDatatype:s.UNSIGNED_INT_24_8}),e._globeDepthTexture=new u({context:t,width:r,height:i,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE})}function g(e,t){e.framebuffer=new a({context:t,colorTextures:[e._colorTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._copyDepthFramebuffer=new a({context:t,colorTextures:[e._globeDepthTexture],destroyAttachments:!1})}function _(e,t,i,n){var o=e._colorTexture,a=!r(o)||o.width!==i||o.height!==n;r(e.framebuffer)&&!a||(p(e),f(e),m(e,t,i,n),g(e,t))}function v(i,n,a,s,u){i._viewport.width=a,i._viewport.height=s;var d=!e.equals(i._viewport,u.viewport),h=d!==i._useScissorTest;if(i._useScissorTest=d,e.equals(i._scissorRectangle,u.viewport)||(i._scissorRectangle=e.clone(u.viewport,i._scissorRectangle),h=!0),r(i._rs)&&e.equals(i._viewport,i._rs.viewport)&&!h||(i._rs=l.fromCache({viewport:i._viewport,scissorTest:{enabled:i._useScissorTest,rectangle:i._scissorRectangle}})),!r(i._copyDepthCommand)){i._copyDepthCommand=n.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n}\n",{uniformMap:{u_texture:function(){return i._depthStencilTexture}},owner:i})}i._copyDepthCommand.framebuffer=i._copyDepthFramebuffer,r(i._copyColorCommand)||(i._copyColorCommand=n.createViewportQuadCommand(c,{uniformMap:{u_texture:function(){return i._colorTexture}},owner:i})),i._copyDepthCommand.renderState=i._rs,i._copyColorCommand.renderState=i._rs,r(i._clearColorCommand)||(i._clearColorCommand=new o({color:new t(0,0,0,0),stencil:0,owner:i})),i._clearColorCommand.framebuffer=i.framebuffer}return d.prototype.executeDebugGlobeDepth=function(e,t){h(this,e,t)},d.prototype.update=function(e,t){var r=e.drawingBufferWidth,i=e.drawingBufferHeight;_(this,e,r,i),v(this,e,r,i,t),e.uniformState.globeDepthTexture=void 0},d.prototype.executeCopyDepth=function(e,t){r(this._copyDepthCommand)&&(this._copyDepthCommand.execute(e,t),e.uniformState.globeDepthTexture=this._globeDepthTexture)},d.prototype.executeCopyColor=function(e,t){r(this._copyColorCommand)&&this._copyColorCommand.execute(e,t)},d.prototype.clear=function(e,i,n){var o=this._clearColorCommand;r(o)&&(t.clone(n,o.color),o.execute(e,i))},d.prototype.isDestroyed=function(){return!1},d.prototype.destroy=function(){p(this),f(this),r(this._copyColorCommand)&&(this._copyColorCommand.shaderProgram=this._copyColorCommand.shaderProgram.destroy()),r(this._copyDepthCommand)&&(this._copyDepthCommand.shaderProgram=this._copyDepthCommand.shaderProgram.destroy());var e=this._debugGlobeDepthViewportCommand;return r(e)&&(e.shaderProgram=e.shaderProgram.destroy()),i(this)},d}),define("Scene/GoogleEarthEnterpriseImageryProvider",["../Core/Credit","../Core/decodeGoogleEarthEnterpriseData","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/deprecationWarning","../Core/DeveloperError","../Core/Event","../Core/GeographicTilingScheme","../Core/GoogleEarthEnterpriseMetadata","../Core/loadImageFromTypedArray","../Core/Math","../Core/Rectangle","../Core/Request","../Core/Resource","../Core/RuntimeError","../Core/TileProviderError","../ThirdParty/protobuf-minimal","../ThirdParty/when"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(){this._image=new Image}function b(t){t=r(t,r.EMPTY_OBJECT),i(t.proxy)&&o("GoogleEarthEnterpriseImageryProvider.proxy","The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.");var n;if(i(t.metadata))n=t.metadata;else{var a=f.createIfNeeded(t.url,{proxy:t.proxy});n=new u(a)}this._metadata=n,this._tileDiscardPolicy=t.tileDiscardPolicy,this._tilingScheme=new l({numberOfLevelZeroTilesX:2,numberOfLevelZeroTilesY:2,rectangle:new h(-d.PI,-d.PI,d.PI,d.PI),ellipsoid:t.ellipsoid});var c=t.credit;"string"==typeof c&&(c=new e({text:c})),this._credit=c,this._tileWidth=256,this._tileHeight=256,this._maximumLevel=23,i(this._tileDiscardPolicy)||(this._tileDiscardPolicy=new y),this._errorEvent=new s,this._ready=!1;var p,_=this;this._readyPromise=n.readyPromise.then(function(e){if(!n.imageryPresent){var t=new m("The server "+n.url+" doesn't have imagery");return p=g.handleError(p,_,_._errorEvent,t.message,void 0,void 0,void 0,t),v.reject(t)}return g.handleSuccess(p),_._ready=e,e}).otherwise(function(e){return p=g.handleError(p,_,_._errorEvent,e.message,void 0,void 0,void 0,e),v.reject(e)})}function C(e,t,r,n,o,a){var s=u.tileXYToQuadKey(r,n,o),l=t.imageryVersion;return l=i(l)&&l>0?l:1,e._metadata.resource.getDerivedResource({url:"flatfile?f1-0"+s+"-i."+l.toString(),request:a})}function S(e){var t="JFIF";if(e[6]===t.charCodeAt(0)&&e[7]===t.charCodeAt(1)&&e[8]===t.charCodeAt(2)&&e[9]===t.charCodeAt(3))return"image/jpeg";var r="PNG";return e[1]===r.charCodeAt(0)&&e[2]===r.charCodeAt(1)&&e[3]===r.charCodeAt(2)?"image/png":void 0}function w(e){for(var t=_.Reader.create(e),r=t.len,n={};t.pos<r;){var o=t.uint32();switch(o>>>3){case 1:n.imageType=t.uint32();break;case 2:n.imageData=t.bytes();break;case 3:n.alphaType=t.uint32();break;case 4:n.imageAlpha=t.bytes();break;case 5:var a=n.copyrightIds;if(i(a)||(a=n.copyrightIds=[]),2==(7&o))for(var s=t.uint32()+t.pos;t.pos<s;)a.push(t.uint32());else a.push(t.uint32());break;default:t.skipType(7&o)}}var l=n.imageType;if(i(l))switch(l){case 0:n.imageType="image/jpeg";break;case 4:n.imageType="image/png";break;default:throw new m("GoogleEarthEnterpriseImageryProvider: Unsupported image type.")}var u=n.alphaType;return i(u)&&0!==u&&(console.log("GoogleEarthEnterpriseImageryProvider: External alpha not supported."),delete n.alphaType,delete n.imageAlpha),n}return y.prototype.isReady=function(){return!0},y.prototype.shouldDiscardImage=function(e){return e===this._image},n(b.prototype,{url:{get:function(){return this._metadata.url}},proxy:{get:function(){return this._metadata.proxy}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){return this._maximumLevel}},minimumLevel:{get:function(){return 0}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){return this._tileDiscardPolicy}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return this._ready}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){return this._credit}},hasAlphaChannel:{get:function(){return!1}}}),b.prototype.getTileCredits=function(e,t,r){var n=this._metadata,o=n.getTileInformation(e,t,r);if(i(o)){var a=n.providers[o.imageryProvider];if(i(a))return[a]}},b.prototype.requestImage=function(e,r,n,o){var a=this._tileDiscardPolicy._image,s=this._metadata,l=u.tileXYToQuadKey(e,r,n),d=s.getTileInformation(e,r,n);if(!i(d)){if(s.isValid(l)){var h=new p({throttle:o.throttle,throttleByServer:o.throttleByServer,type:o.type,priorityFunction:o.priorityFunction});return void s.populateSubtree(e,r,n,h)}return a}if(!d.hasImagery())return a;var f=C(this,d,e,r,n,o).fetchArrayBuffer();return i(f)?f.then(function(e){t(s.key,e);var r,n=new Uint8Array(e),o=s.protoImagery;if(i(o)&&o||(r=S(n)),!i(r)&&(!i(o)||o)){var l=w(n);r=l.imageType,n=l.imageData}return i(r)&&i(n)?c(n,r):a}):void 0},b.prototype.pickFeatures=function(e,t,r,i,n){},b}),define("Scene/GridImageryProvider",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","../Core/GeographicTilingScheme","../ThirdParty/when"],function(e,t,r,i,n,o,a){"use strict";function s(e){e=t(e,t.EMPTY_OBJECT),this._tilingScheme=r(e.tilingScheme)?e.tilingScheme:new o({ellipsoid:e.ellipsoid}),this._cells=t(e.cells,8),this._color=t(e.color,l),this._glowColor=t(e.glowColor,u),this._glowWidth=t(e.glowWidth,6),this._backgroundColor=t(e.backgroundColor,c),this._errorEvent=new n,this._tileWidth=t(e.tileWidth,256),this._tileHeight=t(e.tileHeight,256),this._canvasSize=t(e.canvasSize,256),this._canvas=this._createGridCanvas(),this._readyPromise=a.resolve(!0)}var l=new e(1,1,1,.4),u=new e(0,1,0,.05),c=new e(0,.5,0,.2);return i(s.prototype,{proxy:{get:function(){}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){}},minimumLevel:{get:function(){}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return!0}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){}},hasAlphaChannel:{get:function(){return!0}}}),s.prototype._drawGrid=function(e){for(var t=this._canvasSize,r=0;r<=this._cells;++r){var i=r/this._cells,n=1+i*(t-1);e.moveTo(n,0),e.lineTo(n,t),e.moveTo(0,n),e.lineTo(t,n)}e.stroke()},s.prototype._createGridCanvas=function(){var e=document.createElement("canvas");e.width=this._canvasSize,e.height=this._canvasSize;var t=this._canvasSize,r=e.getContext("2d"),i=this._backgroundColor.toCssColorString();r.fillStyle=i,r.fillRect(0,0,t,t);var n=this._glowColor.toCssColorString();r.strokeStyle=n,r.lineWidth=this._glowWidth,r.strokeRect(0,0,t,t),this._drawGrid(r),r.lineWidth=.5*this._glowWidth,r.strokeRect(0,0,t,t),this._drawGrid(r);var o=this._color.toCssColorString();return r.strokeStyle=o,r.lineWidth=2,r.strokeRect(0,0,t,t),r.lineWidth=1,this._drawGrid(r),e},s.prototype.getTileCredits=function(e,t,r){},s.prototype.requestImage=function(e,t,r,i){return this._canvas},s.prototype.pickFeatures=function(e,t,r,i,n){},s}),define("Scene/InvertClassification",["../Core/Color","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/PixelFormat","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Sampler","../Renderer/ShaderSource","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","../Shaders/PostProcessFilters/PassThrough","./BlendingState","./StencilFunction","./StencilOperation"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v){"use strict";function y(){this.previousFramebuffer=void 0,this._previousFramebuffer=void 0,this._texture=void 0,this._classifiedTexture=void 0,this._depthStencilTexture=void 0,this._fbo=void 0,this._fboClassified=void 0,this._rsUnclassified=void 0,this._rsClassified=void 0,this._unclassifiedCommand=void 0,this._classifiedCommand=void 0,this._translucentCommand=void 0,this._clearColorCommand=new o({color:new e(0,0,0,0),owner:this}),this._clearCommand=new o({color:new e(0,0,0,0),depth:1,stencil:0});var t=this;this._uniformMap={u_texture:function(){return t._texture},u_depth:function(){return t._depthStencilTexture},u_classified:function(){return t._classifiedTexture}}}r(y.prototype,{unclassifiedCommand:{get:function(){return this._unclassifiedCommand}}}),y.isTranslucencySupported=function(e){return e.depthTexture&&e.fragmentDepth};var b={depthMask:!1,stencilTest:{enabled:!0,frontFunction:_.EQUAL,frontOperation:{fail:v.KEEP,zFail:v.KEEP,zPass:v.KEEP},backFunction:_.NEVER,reference:0,mask:15},blending:g.ALPHA_BLEND},C={depthMask:!1,stencilTest:{enabled:!0,frontFunction:_.NOT_EQUAL,frontOperation:{fail:v.KEEP,zFail:v.KEEP,zPass:v.KEEP},backFunction:_.NEVER,reference:0,mask:15},blending:g.ALPHA_BLEND},S={depthMask:!0,depthTest:{enabled:!0},blending:g.ALPHA_BLEND};return y.prototype.update=function(e){var r=this._texture,i=!t(r)||this.previousFramebuffer!==this._previousFramebuffer;this._previousFramebuffer=this.previousFramebuffer;var o=e.drawingBufferWidth,g=e.drawingBufferHeight,_=!t(r)||r.width!==o||r.height!==g;if((_||i)&&(this._texture=this._texture&&this._texture.destroy(),this._classifiedTexture=this._classifiedTexture&&this._classifiedTexture.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),this._texture=new d({context:e,width:o,height:g,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE,sampler:new u({wrapS:f.CLAMP_TO_EDGE,wrapT:f.CLAMP_TO_EDGE,minificationFilter:p.LINEAR,magnificationFilter:h.LINEAR})}),t(this._previousFramebuffer)||(this._classifiedTexture=new d({context:e,width:o,height:g,pixelFormat:n.RGBA,pixelDatatype:s.UNSIGNED_BYTE,sampler:new u({wrapS:f.CLAMP_TO_EDGE,wrapT:f.CLAMP_TO_EDGE,minificationFilter:p.LINEAR,magnificationFilter:h.LINEAR})}),this._depthStencilTexture=new d({context:e,width:o,height:g,pixelFormat:n.DEPTH_STENCIL,pixelDatatype:s.UNSIGNED_INT_24_8}))),!t(this._fbo)||_||i){this._fbo=this._fbo&&this._fbo.destroy(),this._fboClassified=this._fboClassified&&this._fboClassified.destroy();var v,y;t(this._previousFramebuffer)?(v=this._previousFramebuffer.depthStencilTexture,y=this._previousFramebuffer.depthStencilRenderbuffer):v=this._depthStencilTexture,this._fbo=new a({context:e,colorTextures:[this._texture],depthStencilTexture:v,depthStencilRenderbuffer:y,destroyAttachments:!1}),t(this._previousFramebuffer)||(this._fboClassified=new a({context:e,colorTextures:[this._classifiedTexture],depthStencilTexture:v,destroyAttachments:!1}))}if(t(this._rsUnclassified)||(this._rsUnclassified=l.fromCache(b),this._rsClassified=l.fromCache(C),this._rsDefault=l.fromCache(S)),!t(this._unclassifiedCommand)||i){t(this._unclassifiedCommand)&&(this._unclassifiedCommand.shaderProgram=this._unclassifiedCommand.shaderProgram&&this._unclassifiedCommand.shaderProgram.destroy(),this._classifiedCommand.shaderProgram=this._classifiedCommand.shaderProgram&&this._classifiedCommand.shaderProgram.destroy());var w=t(this._previousFramebuffer)?"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n vec4 color = texture2D(u_texture, v_textureCoordinates);\n if (color.a == 0.0)\n {\n discard;\n }\n#ifdef UNCLASSIFIED\n gl_FragColor = color * czm_invertClassificationColor;\n#else\n gl_FragColor = color;\n#endif\n}\n":"#extension GL_EXT_frag_depth : enable\nuniform sampler2D u_texture;\nuniform sampler2D u_depth;\nuniform sampler2D u_classified;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n vec4 color = texture2D(u_texture, v_textureCoordinates);\n if (color.a == 0.0)\n {\n discard;\n }\n bool isClassified = all(equal(texture2D(u_classified, v_textureCoordinates), vec4(0.0)));\n#ifdef UNCLASSIFIED\n vec4 highlightColor = czm_invertClassificationColor;\n if (isClassified)\n {\n discard;\n }\n#else\n vec4 highlightColor = vec4(1.0);\n if (!isClassified)\n {\n discard;\n }\n#endif\n gl_FragColor = color * highlightColor;\n gl_FragDepthEXT = texture2D(u_depth, v_textureCoordinates).r;\n}\n",T=new c({defines:["UNCLASSIFIED"],sources:[w]}),E=new c({sources:[w]});this._unclassifiedCommand=e.createViewportQuadCommand(T,{renderState:t(this._previousFramebuffer)?this._rsUnclassified:this._rsDefault,uniformMap:this._uniformMap,owner:this}),this._classifiedCommand=e.createViewportQuadCommand(E,{renderState:t(this._previousFramebuffer)?this._rsClassified:this._rsDefault,uniformMap:this._uniformMap,owner:this}),t(this._translucentCommand)&&(this._translucentCommand.shaderProgram=this._translucentCommand.shaderProgram&&this._translucentCommand.shaderProgram.destroy()),t(this._previousFramebuffer)||(this._translucentCommand=e.createViewportQuadCommand(m,{renderState:this._rsUnclassified,uniformMap:this._uniformMap,owner:this}))}},y.prototype.clear=function(e,r){var i=r.framebuffer;t(this._previousFramebuffer)?(r.framebuffer=this._fbo,this._clearColorCommand.execute(e,r)):(r.framebuffer=this._fbo,this._clearCommand.execute(e,r),r.framebuffer=this._fboClassified,this._clearCommand.execute(e,r)),r.framebuffer=i},y.prototype.executeClassified=function(e,r){if(!t(this._previousFramebuffer)){var i=r.framebuffer;r.framebuffer=this._fboClassified,this._translucentCommand.execute(e,r),r.framebuffer=i}this._classifiedCommand.execute(e,r)},y.prototype.executeUnclassified=function(e,t){this._unclassifiedCommand.execute(e,t)},y.prototype.isDestroyed=function(){return!1},y.prototype.destroy=function(){return this._fbo=this._fbo&&this._fbo.destroy(),this._texture=this._texture&&this._texture.destroy(),this._depthStencilTexture=this._depthStencilTexture&&this._depthStencilTexture.destroy(),t(this._unclassifiedCommand)&&(this._unclassifiedCommand.shaderProgram=this._unclassifiedCommand.shaderProgram&&this._unclassifiedCommand.shaderProgram.destroy(),this._classifiedCommand.shaderProgram=this._classifiedCommand.shaderProgram&&this._classifiedCommand.shaderProgram.destroy()),i(this)},y}),define("Scene/JobScheduler",["../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/getTimestamp","./JobType"],function(e,t,r,i,n){"use strict";function o(e){this._total=e,this.usedThisFrame=0,this.stolenFromMeThisFrame=0,this.starvedThisFrame=!1,this.starvedLastFrame=!1}function a(t){var r=new Array(n.NUMBER_OF_JOB_TYPES);r[n.TEXTURE]=new o(e(t)?t[n.TEXTURE]:10),r[n.PROGRAM]=new o(e(t)?t[n.PROGRAM]:10),r[n.BUFFER]=new o(e(t)?t[n.BUFFER]:30);var i,a=r.length,s=0;for(i=0;i<a;++i)s+=r[i].total;var l=new Array(a);for(i=0;i<a;++i)l[i]=!1;this._totalBudget=s,this._totalUsedThisFrame=0,this._budgets=r,this._executedThisFrame=l}return t(o.prototype,{total:{get:function(){return this._total}}}),a.getTimestamp=i,t(a.prototype,{totalBudget:{get:function(){return this._totalBudget}}}),a.prototype.disableThisFrame=function(){this._totalUsedThisFrame=this._totalBudget},a.prototype.resetBudgets=function(){for(var e=this._budgets,t=e.length,r=0;r<t;++r){var i=e[r];i.starvedLastFrame=i.starvedThisFrame,i.starvedThisFrame=!1,i.usedThisFrame=0,i.stolenFromMeThisFrame=0}this._totalUsedThisFrame=0},a.prototype.execute=function(e,t){var r=this._budgets,i=r[t],n=this._executedThisFrame[t];if(this._totalUsedThisFrame>=this._totalBudget&&n)return i.starvedThisFrame=!0,!1;var o;if(i.usedThisFrame+i.stolenFromMeThisFrame>=i.total){var s,l=r.length;for(s=0;s<l&&(o=r[s],!(o.usedThisFrame+o.stolenFromMeThisFrame<o.total)||o.starvedLastFrame);++s);if(s===l&&n)return!1;n&&(i.starvedThisFrame=!0)}var u=a.getTimestamp();e.execute();var c=a.getTimestamp()-u;return this._totalUsedThisFrame+=c,o?o.stolenFromMeThisFrame+=c:i.usedThisFrame+=c,this._executedThisFrame[t]=!0,!0},a}),define("Scene/Moon",["../Core/buildModuleUrl","../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Ellipsoid","../Core/IauOrientationAxes","../Core/Matrix3","../Core/Matrix4","../Core/Simon1994PlanetaryPositions","../Core/Transforms","./EllipsoidPrimitive","./Material"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p){"use strict";function f(t){t=r(t,r.EMPTY_OBJECT);var n=t.textureUrl;i(n)||(n=e("Assets/Textures/moonSmall.jpg")),this.show=r(t.show,!0),this.textureUrl=n,this._ellipsoid=r(t.ellipsoid,a.MOON),this.onlySunLighting=r(t.onlySunLighting,!0),this._ellipsoidPrimitive=new h({radii:this.ellipsoid.radii,material:p.fromType(p.ImageType),depthTestEnabled:!1,_owner:this}),this._ellipsoidPrimitive.material.translucent=!1,this._axes=new s}n(f.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}});var m=new l,g=new l,_=new t,v=[];return f.prototype.update=function(e){if(this.show){var t=this._ellipsoidPrimitive;t.material.uniforms.image=this.textureUrl,t.onlySunLighting=this.onlySunLighting;var r=e.time;i(d.computeIcrfToFixedMatrix(r,m))||d.computeTemeToPseudoFixedMatrix(r,m);var n=this._axes.evaluate(r,g);l.transpose(n,n),l.multiply(m,n,n);var o=c.computeMoonPositionInEarthInertialFrame(r,_);l.multiplyByVector(m,o,o),u.fromRotationTranslation(n,o,t.modelMatrix);var a=e.commandList;return e.commandList=v,v.length=0,t.update(e),e.commandList=a,1===v.length?v[0]:void 0}},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._ellipsoidPrimitive=this._ellipsoidPrimitive&&this._ellipsoidPrimitive.destroy(),o(this)},f}),define("Scene/NeverTileDiscardPolicy",[],function(){"use strict";function e(e){}return e.prototype.isReady=function(){return!0},e.prototype.shouldDiscardImage=function(e){return!1},e}),define("Shaders/AdjustTranslucentFS",[],function(){"use strict";return"#ifdef MRT\n#extension GL_EXT_draw_buffers : enable\n#endif\nuniform vec4 u_bgColor;\nuniform sampler2D u_depthTexture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nif (texture2D(u_depthTexture, v_textureCoordinates).r < 1.0)\n{\n#ifdef MRT\ngl_FragData[0] = u_bgColor;\ngl_FragData[1] = vec4(u_bgColor.a);\n#else\ngl_FragColor = u_bgColor;\n#endif\nreturn;\n}\ndiscard;\n}\n"}),define("Shaders/CompositeOITFS",[],function(){"use strict";return"uniform sampler2D u_opaque;\nuniform sampler2D u_accumulation;\nuniform sampler2D u_revealage;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec4 opaque = texture2D(u_opaque, v_textureCoordinates);\nvec4 accum = texture2D(u_accumulation, v_textureCoordinates);\nfloat r = texture2D(u_revealage, v_textureCoordinates).r;\n#ifdef MRT\nvec4 transparent = vec4(accum.rgb / clamp(r, 1e-4, 5e4), accum.a);\n#else\nvec4 transparent = vec4(accum.rgb / clamp(accum.a, 1e-4, 5e4), r);\n#endif\ngl_FragColor = (1.0 - transparent.a) * transparent + transparent.a * opaque;\nif (opaque != czm_backgroundColor)\n{\ngl_FragColor.a = 1.0;\n}\n}\n"}),define("Scene/OIT",["../Core/BoundingRectangle","../Core/Color","../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Core/WebGLConstants","../Renderer/ClearCommand","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/ShaderSource","../Renderer/Texture","../Shaders/AdjustTranslucentFS","../Shaders/CompositeOITFS","./BlendEquation","./BlendFunction"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(r){this._translucentMultipassSupport=!1,this._translucentMRTSupport=!1;var i=r.floatingPointTexture&&r.depthTexture;this._translucentMRTSupport=r.drawBuffers&&i,this._translucentMultipassSupport=!this._translucentMRTSupport&&i,this._opaqueFBO=void 0,this._opaqueTexture=void 0,this._depthStencilTexture=void 0,this._accumulationTexture=void 0,this._translucentFBO=void 0,this._alphaFBO=void 0,this._adjustTranslucentFBO=void 0,this._adjustAlphaFBO=void 0,this._opaqueClearCommand=new a({color:new t(0,0,0,0),owner:this}),this._translucentMRTClearCommand=new a({color:new t(0,0,0,1),owner:this}),this._translucentMultipassClearCommand=new a({color:new t(0,0,0,0),owner:this}),this._alphaClearCommand=new a({color:new t(1,1,1,1),owner:this}),this._translucentRenderStateCache={},this._alphaRenderStateCache={},this._compositeCommand=void 0,this._adjustTranslucentCommand=void 0,this._adjustAlphaCommand=void 0,this._viewport=new e,this._rs=void 0,this._useScissorTest=!1,this._scissorRectangle=void 0}function v(e){e._accumulationTexture=e._accumulationTexture&&!e._accumulationTexture.isDestroyed()&&e._accumulationTexture.destroy(),e._revealageTexture=e._revealageTexture&&!e._revealageTexture.isDestroyed()&&e._revealageTexture.destroy()}function y(e){e._translucentFBO=e._translucentFBO&&!e._translucentFBO.isDestroyed()&&e._translucentFBO.destroy(),e._alphaFBO=e._alphaFBO&&!e._alphaFBO.isDestroyed()&&e._alphaFBO.destroy(),e._adjustTranslucentFBO=e._adjustTranslucentFBO&&!e._adjustTranslucentFBO.isDestroyed()&&e._adjustTranslucentFBO.destroy(),e._adjustAlphaFBO=e._adjustAlphaFBO&&!e._adjustAlphaFBO.isDestroyed()&&e._adjustAlphaFBO.destroy()}function b(e){v(e),y(e)}function C(e,t,r,i){v(e);var o=new Float32Array(r*i*4);e._accumulationTexture=new h({context:t,pixelFormat:n.RGBA,pixelDatatype:u.FLOAT,source:{arrayBufferView:o,width:r,height:i}}),e._revealageTexture=new h({context:t,pixelFormat:n.RGBA,pixelDatatype:u.FLOAT,source:{arrayBufferView:o,width:r,height:i}})}function S(e,t){y(e);var r=o.FRAMEBUFFER_COMPLETE,i=!0;if(e._translucentMRTSupport&&(e._translucentFBO=new l({context:t,colorTextures:[e._accumulationTexture,e._revealageTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._adjustTranslucentFBO=new l({context:t,colorTextures:[e._accumulationTexture,e._revealageTexture],destroyAttachments:!1}),e._translucentFBO.status===r&&e._adjustTranslucentFBO.status===r||(y(e),e._translucentMRTSupport=!1)),!e._translucentMRTSupport){e._translucentFBO=new l({context:t,colorTextures:[e._accumulationTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._alphaFBO=new l({context:t,colorTextures:[e._revealageTexture],depthStencilTexture:e._depthStencilTexture,destroyAttachments:!1}),e._adjustTranslucentFBO=new l({context:t,colorTextures:[e._accumulationTexture],destroyAttachments:!1}),e._adjustAlphaFBO=new l({context:t,colorTextures:[e._revealageTexture],destroyAttachments:!1});var n=e._translucentFBO.status===r,a=e._alphaFBO.status===r,s=e._adjustTranslucentFBO.status===r,u=e._adjustAlphaFBO.status===r;n&&a&&s&&u||(b(e),e._translucentMultipassSupport=!1,i=!1)}return i}function w(e,t,i,n){var o=i[n.id];if(!r(o)){var a=c.getState(n);a.depthMask=!1,a.blending=t,o=c.fromCache(a),i[n.id]=o}return o}function T(e,t,r){return w(t,R,e._translucentRenderStateCache,r)}function E(e,t,r){return w(t,L,e._translucentRenderStateCache,r)}function A(e,t,r){return w(t,N,e._alphaRenderStateCache,r)}function x(e,t,i,n){var o=e.shaderCache.getDerivedShaderProgram(t,i);if(!r(o)){var a=t._attributeLocations,s=t.fragmentShaderSource.clone();s.sources=s.sources.map(function(e){return e=d.replaceMain(e,"czm_translucent_main"),e=e.replace(/gl_FragColor/g,"czm_gl_FragColor"),e=e.replace(/\bdiscard\b/g,"czm_discard = true"),e=e.replace(/czm_phong/g,"czm_translucentPhong")}),s.sources.splice(0,0,(-1!==n.indexOf("gl_FragData")?"#extension GL_EXT_draw_buffers : enable \n":"")+"vec4 czm_gl_FragColor;\nbool czm_discard = false;\n"),s.sources.push("void main()\n{\n czm_translucent_main();\n if (czm_discard)\n {\n discard;\n }\n"+n+"}\n"),o=e.shaderCache.createDerivedShaderProgram(t,i,{vertexShaderSource:t.vertexShaderSource,fragmentShaderSource:s,attributeLocations:a})}return o}function P(e,t){return x(e,t,"translucentMRT",k)}function D(e,t){return x(e,t,"translucentMultipass",F)}function I(e,t){return x(e,t,"alphaMultipass",B)}function O(e,t,i,n,o,a){var s,l,u,c=t.context,d=n.framebuffer,h=o.length,p=t.frameState.shadowHints.shadowsEnabled;n.framebuffer=e._adjustTranslucentFBO,e._adjustTranslucentCommand.execute(c,n),n.framebuffer=e._adjustAlphaFBO,e._adjustAlphaCommand.execute(c,n);var f=e._opaqueFBO;for(n.framebuffer=e._translucentFBO,u=0;u<h;++u)s=o[u],l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.translucentCommand:s.derivedCommands.oit.translucentCommand,i(l,t,c,n,f);for(r(a)&&(s=a.unclassifiedCommand,l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.translucentCommand:s.derivedCommands.oit.translucentCommand,i(l,t,c,n,f)),n.framebuffer=e._alphaFBO,u=0;u<h;++u)s=o[u],l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.alphaCommand:s.derivedCommands.oit.alphaCommand,i(l,t,c,n,f);r(a)&&(s=a.unclassifiedCommand,l=p&&s.receiveShadows?s.derivedCommands.oit.shadows.alphaCommand:s.derivedCommands.oit.alphaCommand,i(l,t,c,n,f)),n.framebuffer=d}function M(e,t,i,n,o,a){var s=t.context,l=n.framebuffer,u=o.length,c=t.frameState.shadowHints.shadowsEnabled;n.framebuffer=e._adjustTranslucentFBO,e._adjustTranslucentCommand.execute(s,n);var d=e._opaqueFBO;n.framebuffer=e._translucentFBO;for(var h,p,f=0;f<u;++f)h=o[f],p=c&&h.receiveShadows?h.derivedCommands.oit.shadows.translucentCommand:h.derivedCommands.oit.translucentCommand,i(p,t,s,n,d);r(a)&&(h=a.unclassifiedCommand,p=c&&h.receiveShadows?h.derivedCommands.oit.shadows.translucentCommand:h.derivedCommands.oit.translucentCommand,i(p,t,s,n,d)),n.framebuffer=l}_.prototype.update=function(t,i,n){if(this.isSupported()){this._opaqueFBO=n,this._opaqueTexture=n.getColorTexture(0),this._depthStencilTexture=n.depthStencilTexture;var o=this._opaqueTexture.width,a=this._opaqueTexture.height,s=this._accumulationTexture,l=!r(s)||s.width!==o||s.height!==a;if(l&&C(this,t,o,a),r(this._translucentFBO)&&!l||S(this,t)){var u,h,m=this;r(this._compositeCommand)||(u=new d({sources:[f]}),this._translucentMRTSupport&&u.defines.push("MRT"),h={u_opaque:function(){return m._opaqueTexture},u_accumulation:function(){return m._accumulationTexture},u_revealage:function(){return m._revealageTexture}},this._compositeCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this})),r(this._adjustTranslucentCommand)||(this._translucentMRTSupport?(u=new d({defines:["MRT"],sources:[p]}),h={u_bgColor:function(){return m._translucentMRTClearCommand.color},u_depthTexture:function(){return m._depthStencilTexture}},this._adjustTranslucentCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this})):this._translucentMultipassSupport&&(u=new d({sources:[p]}),h={u_bgColor:function(){return m._translucentMultipassClearCommand.color},u_depthTexture:function(){return m._depthStencilTexture}},this._adjustTranslucentCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this}),h={u_bgColor:function(){return m._alphaClearCommand.color},u_depthTexture:function(){return m._depthStencilTexture}},this._adjustAlphaCommand=t.createViewportQuadCommand(u,{uniformMap:h,owner:this}))),this._viewport.width=o,this._viewport.height=a;var g=!e.equals(this._viewport,i.viewport),_=g!==this._useScissorTest;this._useScissorTest=g,e.equals(this._scissorRectangle,i.viewport)||(this._scissorRectangle=e.clone(i.viewport,this._scissorRectangle),_=!0),r(this._rs)&&e.equals(this._viewport,this._rs.viewport)&&!_||(this._rs=c.fromCache({viewport:this._viewport,scissorTest:{enabled:this._useScissorTest,rectangle:this._scissorRectangle}})),r(this._compositeCommand)&&(this._compositeCommand.renderState=this._rs),this._adjustTranslucentCommand&&(this._adjustTranslucentCommand.renderState=this._rs),r(this._adjustAlphaCommand)&&(this._adjustAlphaCommand.renderState=this._rs)}}};var R={enabled:!0,color:new t(0,0,0,0),equationRgb:m.ADD,equationAlpha:m.ADD,functionSourceRgb:g.ONE,functionDestinationRgb:g.ONE,functionSourceAlpha:g.ZERO,functionDestinationAlpha:g.ONE_MINUS_SOURCE_ALPHA},L={enabled:!0,color:new t(0,0,0,0),equationRgb:m.ADD,equationAlpha:m.ADD,functionSourceRgb:g.ONE,functionDestinationRgb:g.ONE,functionSourceAlpha:g.ONE,functionDestinationAlpha:g.ONE},N={enabled:!0,color:new t(0,0,0,0),equationRgb:m.ADD,equationAlpha:m.ADD,functionSourceRgb:g.ZERO, +functionDestinationRgb:g.ONE_MINUS_SOURCE_ALPHA,functionSourceAlpha:g.ZERO,functionDestinationAlpha:g.ONE_MINUS_SOURCE_ALPHA},k=" vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n float ai = czm_gl_FragColor.a;\n float wzi = czm_alphaWeight(ai);\n gl_FragData[0] = vec4(Ci * wzi, ai);\n gl_FragData[1] = vec4(ai * wzi);\n",F=" vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n float ai = czm_gl_FragColor.a;\n float wzi = czm_alphaWeight(ai);\n gl_FragColor = vec4(Ci, ai) * wzi;\n",B=" float ai = czm_gl_FragColor.a;\n gl_FragColor = vec4(ai);\n";return _.prototype.createDerivedCommands=function(e,t,i){if(r(i)||(i={}),this._translucentMRTSupport){var n,o;r(i.translucentCommand)&&(n=i.translucentCommand.shaderProgram,o=i.translucentCommand.renderState),i.translucentCommand=s.shallowClone(e,i.translucentCommand),r(n)&&i.shaderProgramId===e.shaderProgram.id?(i.translucentCommand.shaderProgram=n,i.translucentCommand.renderState=o):(i.translucentCommand.shaderProgram=P(t,e.shaderProgram),i.translucentCommand.renderState=T(this,t,e.renderState),i.shaderProgramId=e.shaderProgram.id)}else{var a,l,u,c;r(i.translucentCommand)&&(a=i.translucentCommand.shaderProgram,l=i.translucentCommand.renderState,u=i.alphaCommand.shaderProgram,c=i.alphaCommand.renderState),i.translucentCommand=s.shallowClone(e,i.translucentCommand),i.alphaCommand=s.shallowClone(e,i.alphaCommand),r(a)&&i.shaderProgramId===e.shaderProgram.id?(i.translucentCommand.shaderProgram=a,i.translucentCommand.renderState=l,i.alphaCommand.shaderProgram=u,i.alphaCommand.renderState=c):(i.translucentCommand.shaderProgram=D(t,e.shaderProgram),i.translucentCommand.renderState=E(this,t,e.renderState),i.alphaCommand.shaderProgram=I(t,e.shaderProgram),i.alphaCommand.renderState=A(this,t,e.renderState),i.shaderProgramId=e.shaderProgram.id)}return i},_.prototype.executeCommands=function(e,t,r,i,n){if(this._translucentMRTSupport)return void M(this,e,t,r,i,n);O(this,e,t,r,i,n)},_.prototype.execute=function(e,t){this._compositeCommand.execute(e,t)},_.prototype.clear=function(e,r,i){var n=r.framebuffer;r.framebuffer=this._opaqueFBO,t.clone(i,this._opaqueClearCommand.color),this._opaqueClearCommand.execute(e,r),r.framebuffer=this._translucentFBO,(this._translucentMRTSupport?this._translucentMRTClearCommand:this._translucentMultipassClearCommand).execute(e,r),this._translucentMultipassSupport&&(r.framebuffer=this._alphaFBO,this._alphaClearCommand.execute(e,r)),r.framebuffer=n},_.prototype.isSupported=function(){return this._translucentMRTSupport||this._translucentMultipassSupport},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return b(this),r(this._compositeCommand)&&(this._compositeCommand.shaderProgram=this._compositeCommand.shaderProgram&&this._compositeCommand.shaderProgram.destroy()),r(this._adjustTranslucentCommand)&&(this._adjustTranslucentCommand.shaderProgram=this._adjustTranslucentCommand.shaderProgram&&this._adjustTranslucentCommand.shaderProgram.destroy()),r(this._adjustAlphaCommand)&&(this._adjustAlphaCommand.shaderProgram=this._adjustAlphaCommand.shaderProgram&&this._adjustAlphaCommand.shaderProgram.destroy()),i(this)},_}),define("Scene/Particle",["../Core/Cartesian2","../Core/Cartesian3","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties"],function(e,t,r,i,n,o){"use strict";function a(n){n=i(n,i.EMPTY_OBJECT),this.mass=i(n.mass,1),this.position=t.clone(i(n.position,t.ZERO)),this.velocity=t.clone(i(n.velocity,t.ZERO)),this.life=i(n.life,Number.MAX_VALUE),this.image=n.image,this.startColor=r.clone(i(n.startColor,r.WHITE)),this.endColor=r.clone(i(n.endColor,r.WHITE)),this.startScale=i(n.startScale,1),this.endScale=i(n.endScale,1),this.size=e.clone(i(n.size,s)),this._age=0,this._normalizedAge=0,this._billboard=void 0}var s=new e(1,1);o(a.prototype,{age:{get:function(){return this._age}},normalizedAge:{get:function(){return this._normalizedAge}}});var l=new t;return a.prototype.update=function(e,r){if(t.multiplyByScalar(this.velocity,e,l),t.add(this.position,l,this.position),n(r))for(var i=r.length,o=0;o<i;++o){var a=r[o];"function"==typeof a&&a(this,e)}return this._age+=e,this.life===Number.MAX_VALUE?this._normalizedAge=0:this._normalizedAge=this._age/this.life,this._age<=this.life},a}),define("Scene/ParticleBurst",["../Core/defaultValue","../Core/defineProperties"],function(e,t){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.time=e(t.time,0),this.minimum=e(t.minimum,0),this.maximum=e(t.maximum,50),this._complete=!1}return t(r.prototype,{complete:{get:function(){return this._complete}}}),r}),define("Scene/ParticleEmitter",["../Core/DeveloperError"],function(e){"use strict";function t(e){}return t.prototype.emit=function(t){e.throwInstantiationError()},t}),define("Scene/ParticleSystem",["../Core/Cartesian2","../Core/Cartesian3","../Core/Check","../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Event","../Core/JulianDate","../Core/Math","../Core/Matrix4","./BillboardCollection","./CircleEmitter","./Particle"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f){"use strict";function m(e){e=n(e,n.EMPTY_OBJECT),this.show=n(e.show,!0),this.forces=e.forces,this.loop=n(e.loop,!0),this.image=n(e.image,void 0);var t=e.emitter;o(t)||(t=new p(.5)),this._emitter=t,this._bursts=e.bursts,this._modelMatrix=d.clone(n(e.modelMatrix,d.IDENTITY)),this._emitterModelMatrix=d.clone(n(e.emitterModelMatrix,d.IDENTITY)),this._matrixDirty=!0,this._combinedMatrix=new d,this._startColor=i.clone(n(e.startColor,i.WHITE)),this._endColor=i.clone(n(e.endColor,i.WHITE)),this._startScale=n(e.startScale,1),this._endScale=n(e.endScale,1),this._rate=n(e.rate,5),this._minimumSpeed=n(e.speed,n(e.minimumSpeed,1)),this._maximumSpeed=n(e.speed,n(e.maximumSpeed,1)),this._minimumLife=n(e.life,n(e.minimumLife,5)),this._maximumLife=n(e.life,n(e.maximumLife,5)),this._minimumMass=n(e.mass,n(e.minimumMass,1)),this._maximumMass=n(e.mass,n(e.maximumMass,1)),this._minimumWidth=n(e.width,n(e.minimumWidth,1)),this._maximumWidth=n(e.width,n(e.maximumWidth,1)),this._minimumHeight=n(e.height,n(e.minimumHeight,1)),this._maximumHeight=n(e.height,n(e.maximumHeight,1)),this._lifeTime=n(e.lifeTime,Number.MAX_VALUE),this._billboardCollection=void 0,this._particles=[],this._particlePool=[],this._previousTime=void 0,this._currentTime=0,this._carryOver=0,this._complete=new l,this._isComplete=!1,this._updateParticlePool=!0,this._particleEstimate=0}function g(e){var t=e._rate,r=e._maximumLife,i=0,n=e._bursts;if(o(n))for(var a=n.length,s=0;s<a;++s)i+=n[s].maximum;for(var l=e._billboardCollection,u=e.image,c=Math.ceil(t*r+i),d=e._particles,h=e._particlePool,p=Math.max(c-d.length-h.length,0),m=0;m<p;++m){var g=new f;g._billboard=l.add({image:u}),h.push(g)}e._particleEstimate=c}function _(e){var t=e._particlePool.pop();return o(t)||(t=new f),t}function v(e,t){e._particlePool.push(t)}function y(e){for(var t=e._particles,r=e._particlePool,i=e._billboardCollection,n=t.length,o=r.length,a=e._particleEstimate,s=o-Math.max(a-n-o,0),l=s;l<o;++l){var u=r[l];i.remove(u._billboard)}r.length=s}function b(e){o(e._billboard)&&(e._billboard.show=!1)}function C(e,t){var r=t._billboard;o(r)||(r=t._billboard=e._billboardCollection.add({image:t.image})),r.width=t.size.x,r.height=t.size.y,r.position=t.position,r.show=!0;var n=c.lerp(t.startColor.red,t.endColor.red,t.normalizedAge),a=c.lerp(t.startColor.green,t.endColor.green,t.normalizedAge),s=c.lerp(t.startColor.blue,t.endColor.blue,t.normalizedAge),l=c.lerp(t.startColor.alpha,t.endColor.alpha,t.normalizedAge);r.color=new i(n,a,s,l);var u=c.lerp(t.startScale,t.endScale,t.normalizedAge);r.scale=u}function S(r,n){n.startColor=i.clone(r._startColor,n.startColor),n.endColor=i.clone(r._endColor,n.endColor),n.startScale=r._startScale,n.endScale=r._endScale,n.image=r.image,n.life=c.randomBetween(r._minimumLife,r._maximumLife),n.mass=c.randomBetween(r._minimumMass,r._maximumMass);var o=c.randomBetween(r._minimumWidth,r._maximumWidth),a=c.randomBetween(r._minimumHeight,r._maximumHeight);n.size=e.fromElements(o,a,n.size),n._normalizedAge=0,n._age=0;var s=c.randomBetween(r._minimumSpeed,r._maximumSpeed);t.multiplyByScalar(n.velocity,s,n.velocity),r._particles.push(n)}function w(e,t){if(e._isComplete)return 0;t=c.mod(t,e._lifeTime);var r=t*e._rate,i=Math.floor(r);if(e._carryOver+=r-i,e._carryOver>1&&(i++,e._carryOver-=1),o(e.bursts))for(var n=e.bursts.length,a=0;a<n;a++){var s=e.bursts[a],l=e._currentTime;o(s)&&!s._complete&&l>s.time&&(i+=c.randomBetween(s.minimum,s.maximum),s._complete=!0)}return i}a(m.prototype,{emitter:{get:function(){return this._emitter},set:function(e){this._emitter=e}},bursts:{get:function(){return this._bursts},set:function(e){this._bursts=e,this._updateParticlePool=!0}},modelMatrix:{get:function(){return this._modelMatrix},set:function(e){this._matrixDirty=this._matrixDirty||!d.equals(this._modelMatrix,e),d.clone(e,this._modelMatrix)}},emitterModelMatrix:{get:function(){return this._emitterModelMatrix},set:function(e){this._matrixDirty=this._matrixDirty||!d.equals(this._emitterModelMatrix,e),d.clone(e,this._emitterModelMatrix)}},startColor:{get:function(){return this._startColor},set:function(e){i.clone(e,this._startColor)}},endColor:{get:function(){return this._endColor},set:function(e){i.clone(e,this._endColor)}},startScale:{get:function(){return this._startScale},set:function(e){this._startScale=e}},endScale:{get:function(){return this._endScale},set:function(e){this._endScale=e}},rate:{get:function(){return this._rate},set:function(e){this._rate=e,this._updateParticlePool=!0}},minimumSpeed:{get:function(){return this._minimumSpeed},set:function(e){this._minimumSpeed=e}},maximumSpeed:{get:function(){return this._maximumSpeed},set:function(e){this._maximumSpeed=e}},minimumLife:{get:function(){return this._minimumLife},set:function(e){this._minimumLife=e}},maximumLife:{get:function(){return this._maximumLife},set:function(e){this._maximumLife=e,this._updateParticlePool=!0}},minimumMass:{get:function(){return this._minimumMass},set:function(e){this._minimumMass=e}},maximumMass:{get:function(){return this._maximumMass},set:function(e){this._maximumMass=e}},minimumWidth:{get:function(){return this._minimumWidth},set:function(e){this._minimumWidth=e}},maximumWidth:{get:function(){return this._maximumWidth},set:function(e){this._maximumWidth=e}},minimumHeight:{get:function(){return this._minimumHeight},set:function(e){this._minimumHeight=e}},maximumHeight:{get:function(){return this._maximumHeight},set:function(e){this._maximumHeight=e}},lifeTime:{get:function(){return this._lifeTime},set:function(e){this._lifeTime=e}},complete:{get:function(){return this._complete}},isComplete:{get:function(){return this._isComplete}}});var T=new t;return m.prototype.update=function(e){if(this.show){o(this._billboardCollection)||(this._billboardCollection=new h),this._updateParticlePool&&(g(this),this._updateParticlePool=!1);var r=0;this._previousTime&&(r=u.secondsDifference(e.time,this._previousTime)),r<0&&(r=0);var i,n,a=this._particles,s=this._emitter,l=this.forces,p=a.length;for(i=0;i<p;++i)n=a[i],n.update(r,l)?C(this,n):(b(n),v(this,n),a[i]=a[p-1],--i,--p);a.length=p;var f=w(this,r);if(f>0&&o(s)){this._matrixDirty&&(this._combinedMatrix=d.multiply(this.modelMatrix,this.emitterModelMatrix,this._combinedMatrix),this._matrixDirty=!1);var m=this._combinedMatrix;for(i=0;i<f;i++)n=_(this),this._emitter.emit(n),t.add(n.position,n.velocity,T),d.multiplyByPoint(m,T,T),n.position=d.multiplyByPoint(m,n.position,n.position),t.subtract(T,n.position,n.velocity),t.normalize(n.velocity,n.velocity),S(this,n),C(this,n)}if(this._billboardCollection.update(e),this._previousTime=u.clone(e.time,this._previousTime),this._currentTime+=r,this._lifeTime!==Number.MAX_VALUE&&this._currentTime>this._lifeTime)if(this.loop){if(this._currentTime=c.mod(this._currentTime,this._lifeTime),this.bursts){var E=this.bursts.length;for(i=0;i<E;i++)this.bursts[i]._complete=!1}}else this._isComplete=!0,this._complete.raiseEvent(this);e.frameNumber%120==0&&y(this)}},m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){return this._billboardCollection=this._billboardCollection&&this._billboardCollection.destroy(),s(this)},m}),define("Widgets/getElement",["../Core/DeveloperError"],function(e){"use strict";function t(e){if("string"==typeof e){e=document.getElementById(e)}return e}return t}),define("Scene/PerformanceDisplay",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/getTimestamp","../Widgets/getElement"],function(e,t,r,i,n,o,a){"use strict";function s(t){t=e(t,e.EMPTY_OBJECT);var r=a(t.container);this._container=r;var i=document.createElement("div");i.className="cesium-performanceDisplay";var n=document.createElement("div");n.className="cesium-performanceDisplay-fps",this._fpsText=document.createTextNode(""),n.appendChild(this._fpsText);var s=document.createElement("div");s.className="cesium-performanceDisplay-ms",this._msText=document.createTextNode(""),s.appendChild(this._msText),i.appendChild(s),i.appendChild(n),this._container.appendChild(i),this._lastFpsSampleTime=o(),this._lastMsSampleTime=o(),this._fpsFrameCount=0,this._msFrameCount=0,this._throttled=!1;var l=document.createElement("div");l.className="cesium-performanceDisplay-throttled",this._throttledText=document.createTextNode(""),l.appendChild(this._throttledText),i.appendChild(l)}return r(s.prototype,{throttled:{get:function(){return this._throttled},set:function(e){this._throttled!==e&&(this._throttledText.nodeValue=e?"(throttled)":"",this._throttled=e)}}}),s.prototype.update=function(t){var r=o(),i=e(t,!0);this._fpsFrameCount++;var n=r-this._lastFpsSampleTime;if(n>1e3){var a="N/A";i&&(a=1e3*this._fpsFrameCount/n|0),this._fpsText.nodeValue=a+" FPS",this._lastFpsSampleTime=r,this._fpsFrameCount=0}this._msFrameCount++;var s=r-this._lastMsSampleTime;if(s>200){var l="N/A";i&&(l=(s/this._msFrameCount).toFixed(2)),this._msText.nodeValue=l+" MS",this._lastMsSampleTime=r,this._msFrameCount=0}},s.prototype.destroy=function(){return i(this)},s}),define("Scene/PickDepth",["../Core/defined","../Core/destroyObject","../Core/PixelFormat","../Renderer/Framebuffer","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/Texture"],function(e,t,r,i,n,o,a){"use strict";function s(){this.framebuffer=void 0,this._depthTexture=void 0,this._textureToCopy=void 0,this._copyDepthCommand=void 0,this._debugPickDepthViewportCommand=void 0}function l(t,r,i){if(!e(t._debugPickDepthViewportCommand)){t._debugPickDepthViewportCommand=r.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n float n_range = czm_depthRange.near;\n float f_range = czm_depthRange.far;\n float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n}\n",{uniformMap:{u_texture:function(){return t._depthTexture}},owner:t})}t._debugPickDepthViewportCommand.execute(r,i)}function u(e){e._depthTexture=e._depthTexture&&!e._depthTexture.isDestroyed()&&e._depthTexture.destroy()}function c(e){e.framebuffer=e.framebuffer&&!e.framebuffer.isDestroyed()&&e.framebuffer.destroy()}function d(e,t,i,o){e._depthTexture=new a({context:t,width:i,height:o,pixelFormat:r.RGBA,pixelDatatype:n.UNSIGNED_BYTE})}function h(e,t,r,n){u(e),c(e),d(e,t,r,n),e.framebuffer=new i({context:t,colorTextures:[e._depthTexture],destroyAttachments:!1})}function p(t,r,i){var n=i.width,o=i.height,a=t._depthTexture,s=!e(a)||a.width!==n||a.height!==o;e(t.framebuffer)&&!s||h(t,r,n,o)}function f(t,r,i){if(!e(t._copyDepthCommand)){t._copyDepthCommand=r.createViewportQuadCommand("uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\n gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n}\n",{renderState:o.fromCache(),uniformMap:{u_texture:function(){return t._textureToCopy}},owner:t})}t._textureToCopy=i,t._copyDepthCommand.framebuffer=t.framebuffer}return s.prototype.executeDebugPickDepth=function(e,t){l(this,e,t)},s.prototype.update=function(e,t){p(this,e,t),f(this,e,t)},s.prototype.executeCopyDepth=function(e,t){this._copyDepthCommand.execute(e,t)},s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return u(this),c(this),this._copyDepthCommand.shaderProgram=e(this._copyDepthCommand.shaderProgram)&&this._copyDepthCommand.shaderProgram.destroy(),t(this)},s}),define("Scene/PrimitiveCollection",["../Core/createGuid","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError"],function(e,t,r,i,n,o){"use strict";function a(r){r=t(r,t.EMPTY_OBJECT),this._primitives=[],this._guid=e(),this.show=t(r.show,!0),this.destroyPrimitives=t(r.destroyPrimitives,!0)}function s(e,t){return e._primitives.indexOf(t)}return i(a.prototype,{length:{get:function(){return this._primitives.length}}}),a.prototype.add=function(e){var t=e._external=e._external||{};return(t._composites=t._composites||{})[this._guid]={collection:this},this._primitives.push(e),e},a.prototype.remove=function(e){if(this.contains(e)){var t=this._primitives.indexOf(e);if(-1!==t)return this._primitives.splice(t,1),delete e._external._composites[this._guid],this.destroyPrimitives&&e.destroy(),!0}return!1},a.prototype.removeAndDestroy=function(e){var t=this.remove(e);return t&&!this.destroyPrimitives&&e.destroy(),t},a.prototype.removeAll=function(){if(this.destroyPrimitives)for(var e=this._primitives,t=e.length,r=0;r<t;++r)e[r].destroy();this._primitives=[]},a.prototype.contains=function(e){return!!(r(e)&&e._external&&e._external._composites&&e._external._composites[this._guid])},a.prototype.raise=function(e){if(r(e)){var t=s(this,e),i=this._primitives;if(t!==i.length-1){var n=i[t];i[t]=i[t+1],i[t+1]=n}}},a.prototype.raiseToTop=function(e){if(r(e)){var t=s(this,e),i=this._primitives;t!==i.length-1&&(i.splice(t,1),i.push(e))}},a.prototype.lower=function(e){if(r(e)){var t=s(this,e),i=this._primitives;if(0!==t){var n=i[t];i[t]=i[t-1],i[t-1]=n}}},a.prototype.lowerToBottom=function(e){if(r(e)){var t=s(this,e),i=this._primitives;0!==t&&(i.splice(t,1),i.unshift(e))}},a.prototype.get=function(e){return this._primitives[e]},a.prototype.update=function(e){if(this.show)for(var t=this._primitives,r=0;r<t.length;++r)t[r].update(e)},a.prototype.isDestroyed=function(){return!1},a.prototype.destroy=function(){return this.removeAll(),n(this)},a}),define("Scene/QuadtreeTileProvider",["../Core/defineProperties","../Core/DeveloperError"],function(e,t){"use strict";function r(){t.throwInstantiationError()}return r.computeDefaultLevelZeroMaximumGeometricError=function(e){return 2*e.ellipsoid.maximumRadius*Math.PI*.25/(65*e.getNumberOfXTilesAtLevel(0))},e(r.prototype,{quadtree:{get:t.throwInstantiationError,set:t.throwInstantiationError},ready:{get:t.throwInstantiationError},tilingScheme:{get:t.throwInstantiationError},errorEvent:{get:t.throwInstantiationError}}),r.prototype.update=t.throwInstantiationError,r.prototype.beginUpdate=t.throwInstantiationError,r.prototype.endUpdate=t.throwInstantiationError,r.prototype.getLevelMaximumGeometricError=t.throwInstantiationError,r.prototype.loadTile=t.throwInstantiationError,r.prototype.computeTileVisibility=t.throwInstantiationError,r.prototype.showTileThisFrame=t.throwInstantiationError,r.prototype.computeDistanceToTile=t.throwInstantiationError,r.prototype.isDestroyed=t.throwInstantiationError,r.prototype.destroy=t.throwInstantiationError,r}),define("Scene/SceneTransitioner",["../Core/Cartesian3","../Core/Cartographic","../Core/Check","../Core/defined","../Core/destroyObject","../Core/EasingFunction","../Core/Math","../Core/Matrix4","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/Ray","../Core/ScreenSpaceEventHandler","../Core/ScreenSpaceEventType","../Core/Transforms","./Camera","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g){"use strict";function _(e){this._scene=e,this._currentTweens=[],this._morphHandler=void 0,this._morphCancelled=!1,this._completeMorph=void 0,this._morphToOrthographic=!1}function v(e,t){if(e._scene.completeMorphOnUserInput){e._morphHandler=new h(e._scene.canvas,!1);var r=function(){e._morphCancelled=!0,t(e)};e._completeMorph=r,e._morphHandler.setInputAction(r,p.LEFT_DOWN),e._morphHandler.setInputAction(r,p.MIDDLE_DOWN),e._morphHandler.setInputAction(r,p.RIGHT_DOWN),e._morphHandler.setInputAction(r,p.WHEEL)}}function y(e){for(var t=e._currentTweens,r=0;r<t.length;++r)t[r].cancelTween();e._currentTweens.length=0,e._morphHandler=e._morphHandler&&e._morphHandler.destroy()}function b(e,t){var r=e._scene,i=r.camera,n=q,o=n.position,a=n.direction,l=n.up,u=r.mapProjection.unproject(i.position,X);t.cartographicToCartesian(u,o);var c=t.scaleToGeodeticSurface(o,Q),d=f.eastNorthUpToFixedFrame(c,t,Z);return s.multiplyByPointAsVector(d,i.direction,a),s.multiplyByPointAsVector(d,i.up,l),n}function C(t,r,i,n){function a(t){w(c,p,t.time,u.position),w(d,f,t.time,u.direction),w(h,g,t.time,u.up),e.cross(u.direction,u.up,u.right),e.normalize(u.right,u.right)}r*=.5;var l=t._scene,u=l.camera,c=e.clone(u.position,K),d=e.clone(u.direction,J),h=e.clone(u.up,$),p=s.multiplyByPoint(m.TRANSFORM_2D_INVERSE,i.position,ee),f=s.multiplyByPointAsVector(m.TRANSFORM_2D_INVERSE,i.direction,te),g=s.multiplyByPointAsVector(m.TRANSFORM_2D_INVERSE,i.up,re),_=l.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:a,complete:function(){I(t,l,0,1,r,n)}});t._currentTweens.push(_)}function S(t,r,i){function n(t){w(p,_,t.time,u.position),w(f,y,t.time,u.direction),w(m,S,t.time,u.up),e.cross(u.direction,u.up,u.right),e.normalize(u.right,u.right);var r=u.frustum;r.right=a.lerp(T,E,t.time),r.left=-r.right,r.top=r.right*(l.drawingBufferHeight/l.drawingBufferWidth),r.bottom=-r.top,u.position.z=2*l.mapProjection.ellipsoid.maximumRadius}r/=3;var s,l=t._scene,u=l.camera;r>0?(s=q,e.fromDegrees(0,0,5*i.maximumRadius,i,s.position),e.negate(s.position,s.direction),e.normalize(s.direction,s.direction),e.clone(e.UNIT_Z,s.up)):(u.position.z=u.frustum.right-u.frustum.left,s=b(t,i));var c;t._morphToOrthographic?(c=ie,c.aspectRatio=l.drawingBufferWidth/l.drawingBufferHeight,c.width=u.frustum.right-u.frustum.left):(c=Y,c.aspectRatio=l.drawingBufferWidth/l.drawingBufferHeight,c.fov=a.toRadians(60)),s.frustum=c;var d=O(s);v(t,d);var h,p=e.clone(u.position,ne),f=e.clone(u.direction,oe),m=e.clone(u.up,ae),_=e.fromElements(0,0,5*i.maximumRadius,se),y=e.negate(e.UNIT_Z,le),S=e.clone(e.UNIT_Y,ue),T=u.frustum.right,E=.5*_.z;if(h=t._morphToOrthographic?function(){C(t,r,s,d)}:function(){x(t,r,s,function(){C(t,r,s,d)})},r>0){var A=l.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:n,complete:function(){l._mode=g.MORPHING,h()}});t._currentTweens.push(A)}else h()}function w(t,r,i,n){return e.lerp(t,r,i,n)}function T(e,t,r,i,n){function s(e){c.frustum.fov=a.lerp(d,h,e.time);var t=p/Math.tan(.5*c.frustum.fov);i(c,t)}var u=e._scene,c=u.camera;if(!(c.frustum instanceof l)){var d=c.frustum.fov,h=.5*a.RADIANS_PER_DEGREE,p=r.position.z*Math.tan(.5*d);c.frustum.far=p/Math.tan(.5*h)+1e7;var f=u.tweens.add({duration:t,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:s,complete:function(){c.frustum=r.frustum.clone(),n(e)}});e._currentTweens.push(f)}}function E(t,r){function n(t){w(c,g,t.time,u.position),w(d,p,t.time,u.direction),w(h,f,t.time,u.up),e.cross(u.direction,u.up,u.right),e.normalize(u.right,u.right),u._adjustOrthographicFrustum(!0)}function a(e,t){e.position.z=t}r*=.5;var l=t._scene,u=l.camera,c=e.clone(u.position,ce),d=e.clone(u.direction,de),h=e.clone(u.up,he),p=e.negate(e.UNIT_Z,fe),f=e.clone(e.UNIT_Y,me),g=pe;if(r>0)e.clone(e.ZERO,pe),g.z=5*l.mapProjection.ellipsoid.maximumRadius;else{e.clone(c,pe);var _=_e;s.multiplyByPoint(m.TRANSFORM_2D,c,_.origin),s.multiplyByPointAsVector(m.TRANSFORM_2D,d,_.direction);var y=l.globe;if(i(y)){var b=y.pick(_,l,ve);i(b)&&(s.multiplyByPoint(m.TRANSFORM_2D_INVERSE,b,g),g.z+=e.distance(c,g))}}var C=ge;C.right=.5*g.z,C.left=-C.right,C.top=C.right*(l.drawingBufferHeight/l.drawingBufferWidth),C.bottom=-C.top;var S=ye;S.position=g,S.direction=p,S.up=f,S.frustum=C;var E=M(S);v(t,E);var A=l.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:n,complete:function(){T(t,r,S,a,E)}});t._currentTweens.push(A)}function A(t,r,n){function o(e,t){e.position.x=t}function a(){T(t,r,c,o,w)}r*=.5;var l=t._scene,u=l.camera,c=Ce;if(r>0)e.clone(e.ZERO,c.position),c.position.z=5*n.maximumRadius,e.negate(e.UNIT_Z,c.direction),e.clone(e.UNIT_Y,c.up);else{n.cartesianToCartographic(u.positionWC,be),l.mapProjection.project(be,c.position),e.negate(e.UNIT_Z,c.direction),e.clone(e.UNIT_Y,c.up);var d=Te;e.clone(c.position2D,d.origin);var h=e.clone(u.directionWC,d.direction),p=n.scaleToGeodeticSurface(u.positionWC,Ae),g=f.eastNorthUpToFixedFrame(p,n,Ee);s.inverseTransformation(g,g),s.multiplyByPointAsVector(g,h,h),s.multiplyByPointAsVector(m.TRANSFORM_2D,h,h);var _=l.globe;if(i(_)){var y=_.pick(d,l,we);if(i(y)){var b=e.distance(c.position2D,y);y.x+=b,e.clone(y,c.position2D)}}}s.multiplyByPoint(m.TRANSFORM_2D,c.position,c.position2D),s.multiplyByPointAsVector(m.TRANSFORM_2D,c.direction,c.direction2D),s.multiplyByPointAsVector(m.TRANSFORM_2D,c.up,c.up2D);var C=c.frustum;C.right=.5*c.position.z,C.left=-C.right,C.top=C.right*(l.drawingBufferHeight/l.drawingBufferWidth),C.bottom=-C.top;var S=Se;s.multiplyByPoint(m.TRANSFORM_2D_INVERSE,c.position2D,S.position),e.clone(c.direction,S.direction),e.clone(c.up,S.up),S.frustum=C;var w=M(S);v(t,w),D(t,r,c,a)}function x(e,t,r,i){function n(e){l.frustum.fov=a.lerp(d,c,e.time),l.position.z=h/Math.tan(.5*l.frustum.fov)}var s=e._scene,l=s.camera,u=l.frustum.right-l.frustum.left;l.frustum=r.frustum.clone();var c=l.frustum.fov,d=.5*a.RADIANS_PER_DEGREE,h=u*Math.tan(.5*c);l.frustum.far=h/Math.tan(.5*d)+1e7,l.frustum.fov=d;var p=s.tweens.add({duration:t,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:n,complete:function(){i(e)}});e._currentTweens.push(p)}function P(t,r,i,n){function a(){function a(t){w(h,u,t.time,l.position),w(p,c,t.time,l.direction),w(f,d,t.time,l.up),e.cross(l.direction,l.up,l.right),e.normalize(l.right,l.right)}l.frustum=i.frustum.clone();var h=e.clone(l.position,ne),p=e.clone(l.direction,oe),f=e.clone(l.up,ae);h.z=u.z;var m=s.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:a,complete:function(){n(t)}});t._currentTweens.push(m)}r*=.5;var s=t._scene,l=s.camera,u=e.clone(i.position,se),c=e.clone(i.direction,le),d=e.clone(i.up,ue);s._mode=g.MORPHING,t._morphToOrthographic?a():x(t,0,i,a)}function D(t,r,i,n){function a(t){w(u,h,t.time,l.position),w(c,p,t.time,l.direction),w(d,f,t.time,l.up),e.cross(l.direction,l.up,l.right),e.normalize(l.right,l.right),l._adjustOrthographicFrustum(!0)}var s=t._scene,l=s.camera,u=e.clone(l.position,ne),c=e.clone(l.direction,oe),d=e.clone(l.up,ae),h=e.clone(i.position2D,se),p=e.clone(i.direction2D,le),f=e.clone(i.up2D,ue),m=s.tweens.add({duration:r,easingFunction:o.QUARTIC_OUT,startObject:{time:0},stopObject:{time:1},update:a,complete:function(){I(t,s,1,0,r,n)}});t._currentTweens.push(m)}function I(e,t,r,n,a,s){var l={object:t,property:"morphTime",startValue:r,stopValue:n,duration:a,easingFunction:o.QUARTIC_OUT};i(s)&&(l.complete=function(){s(e)});var u=t.tweens.addProperty(l);e._currentTweens.push(u)}function O(t){return function(r){var n=r._scene;if(n._mode=g.SCENE3D,n.morphTime=g.getMorphTime(g.SCENE3D),y(r),r._previousMode!==g.MORPHING||r._morphCancelled){r._morphCancelled=!1;var o=n.camera;e.clone(t.position,o.position),e.clone(t.direction,o.direction),e.clone(t.up,o.up),e.cross(o.direction,o.up,o.right),e.normalize(o.right,o.right),o.frustum=t.frustum.clone()}var a=i(r._completeMorph);r._completeMorph=void 0,n.camera.update(n.mode),r._scene.morphComplete.raiseEvent(r,r._previousMode,g.SCENE3D,a)}}function M(t){return function(r){var n=r._scene;n._mode=g.SCENE2D,n.morphTime=g.getMorphTime(g.SCENE2D),y(r);var o=n.camera;e.clone(t.position,o.position),o.position.z=2*n.mapProjection.ellipsoid.maximumRadius,e.clone(t.direction,o.direction),e.clone(t.up,o.up),e.cross(o.direction,o.up,o.right),e.normalize(o.right,o.right),o.frustum=t.frustum.clone();var a=i(r._completeMorph);r._completeMorph=void 0,n.camera.update(n.mode),r._scene.morphComplete.raiseEvent(r,r._previousMode,g.SCENE2D,a)}}function R(t){return function(r){var n=r._scene;if(n._mode=g.COLUMBUS_VIEW,n.morphTime=g.getMorphTime(g.COLUMBUS_VIEW),y(r),r._previousModeMode!==g.MORPHING||r._morphCancelled){r._morphCancelled=!1;var o=n.camera;e.clone(t.position,o.position),e.clone(t.direction,o.direction),e.clone(t.up,o.up),e.cross(o.direction,o.up,o.right),e.normalize(o.right,o.right)}var a=i(r._completeMorph);r._completeMorph=void 0,n.camera.update(n.mode),r._scene.morphComplete.raiseEvent(r,r._previousMode,g.COLUMBUS_VIEW,a)}}_.prototype.completeMorph=function(){i(this._completeMorph)&&this._completeMorph()},_.prototype.morphTo2D=function(e,t){i(this._completeMorph)&&this._completeMorph();var r=this._scene;this._previousMode=r.mode,this._morphToOrthographic=r.camera.frustum instanceof l,this._previousMode!==g.SCENE2D&&this._previousMode!==g.MORPHING&&(this._scene.morphStart.raiseEvent(this,this._previousMode,g.SCENE2D,!0),r._mode=g.MORPHING,r.camera._setTransform(s.IDENTITY),this._previousMode===g.COLUMBUS_VIEW?E(this,e):A(this,e,t),0===e&&i(this._completeMorph)&&this._completeMorph())};var L=new e,N=new e,k=new e,F=new e,B=new e,U=new e,V=new e,z=new t,G=new s,W=new c,H=new l,j={position:void 0,direction:void 0,up:void 0,position2D:void 0,direction2D:void 0,up2D:void 0,frustum:void 0};_.prototype.morphToColumbusView=function(t,r){i(this._completeMorph)&&this._completeMorph();var n=this._scene;if(this._previousMode=n.mode,this._previousMode!==g.COLUMBUS_VIEW&&this._previousMode!==g.MORPHING){this._scene.morphStart.raiseEvent(this,this._previousMode,g.COLUMBUS_VIEW,!0),n.camera._setTransform(s.IDENTITY);var o=L,l=N,u=k;if(t>0)o.x=0,o.y=-1,o.z=1,o=e.multiplyByScalar(e.normalize(o,o),5*r.maximumRadius,o),e.negate(e.normalize(o,l),l),e.cross(e.UNIT_X,l,u);else{var c=n.camera;if(this._previousMode===g.SCENE2D)e.clone(c.position,o),o.z=c.frustum.right-c.frustum.left,e.negate(e.UNIT_Z,l),e.clone(e.UNIT_Y,u);else{e.clone(c.positionWC,o),e.clone(c.directionWC,l),e.clone(c.upWC,u);var d=r.scaleToGeodeticSurface(o,V),h=f.eastNorthUpToFixedFrame(d,r,G);s.inverseTransformation(h,h),n.mapProjection.project(r.cartesianToCartographic(o,z),o),s.multiplyByPointAsVector(h,l,l),s.multiplyByPointAsVector(h,u,u)}}var p;this._morphToOrthographic?(p=H,p.width=n.camera.frustum.right-n.camera.frustum.left,p.aspectRatio=n.drawingBufferWidth/n.drawingBufferHeight):(p=W,p.aspectRatio=n.drawingBufferWidth/n.drawingBufferHeight,p.fov=a.toRadians(60));var _=j;_.position=o,_.direction=l,_.up=u,_.frustum=p;var y=R(_);v(this,y),this._previousMode===g.SCENE2D?P(this,t,_,y):(_.position2D=s.multiplyByPoint(m.TRANSFORM_2D,o,F),_.direction2D=s.multiplyByPointAsVector(m.TRANSFORM_2D,l,B),_.up2D=s.multiplyByPointAsVector(m.TRANSFORM_2D,u,U),n._mode=g.MORPHING,D(this,t,_,y)),0===t&&i(this._completeMorph)&&this._completeMorph()}};var q={position:new e,direction:new e,up:new e,frustum:void 0},Y=new c;_.prototype.morphTo3D=function(t,r){i(this._completeMorph)&&this._completeMorph();var n=this._scene;if(this._previousMode=n.mode,this._previousMode!==g.SCENE3D&&this._previousMode!==g.MORPHING){if(this._scene.morphStart.raiseEvent(this,this._previousMode,g.SCENE3D,!0), +n._mode=g.MORPHING,n.camera._setTransform(s.IDENTITY),this._previousMode===g.SCENE2D)S(this,t,r);else{var o;t>0?(o=q,e.fromDegrees(0,0,5*r.maximumRadius,r,o.position),e.negate(o.position,o.direction),e.normalize(o.direction,o.direction),e.clone(e.UNIT_Z,o.up)):o=b(this,r);var u,c=n.camera;c.frustum instanceof l?u=c.frustum.clone():(u=Y,u.aspectRatio=n.drawingBufferWidth/n.drawingBufferHeight,u.fov=a.toRadians(60)),o.frustum=u;var d=O(o);v(this,d),C(this,t,o,d)}0===t&&i(this._completeMorph)&&this._completeMorph()}},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){return y(this),n(this)};var X=new t,Q=new e,Z=new s,K=new e,J=new e,$=new e,ee=new e,te=new e,re=new e,ie=new l,ne=new e,oe=new e,ae=new e,se=new e,le=new e,ue=new e,ce=new e,de=new e,he=new e,pe=new e,fe=new e,me=new e,ge=new u,_e=new d,ve=new e,ye={position:void 0,direction:void 0,up:void 0,frustum:void 0},be=new t,Ce={position:new e,direction:new e,up:new e,position2D:new e,direction2D:new e,up2D:new e,frustum:new u},Se={position:new e,direction:new e,up:new e,frustum:void 0},we=new e,Te=new d,Ee=new s,Ae=new e;return _}),define("Scene/TweenCollection",["../Core/clone","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/EasingFunction","../Core/getTimestamp","../Core/TimeConstants","../ThirdParty/Tween"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t,r,i,n,o,a,s,l,u,c){this._tweens=t,this._tweenjs=r,this._startObject=e(i),this._stopObject=e(n),this._duration=o,this._delay=a,this._easingFunction=s,this._update=l,this._complete=u,this.cancel=c,this.needsStart=!0}function c(){this._tweens=[]}return i(u.prototype,{startObject:{get:function(){return this._startObject}},stopObject:{get:function(){return this._stopObject}},duration:{get:function(){return this._duration}},delay:{get:function(){return this._delay}},easingFunction:{get:function(){return this._easingFunction}},update:{get:function(){return this._update}},complete:{get:function(){return this._complete}},tweenjs:{get:function(){return this._tweenjs}}}),u.prototype.cancelTween=function(){this._tweens.remove(this)},i(c.prototype,{length:{get:function(){return this._tweens.length}}}),c.prototype.add=function(i){if(i=t(i,t.EMPTY_OBJECT),0===i.duration)return r(i.complete)&&i.complete(),new u(this);var n=i.duration/s.SECONDS_PER_MILLISECOND,a=t(i.delay,0),c=a/s.SECONDS_PER_MILLISECOND,d=t(i.easingFunction,o.LINEAR_NONE),h=i.startObject,p=new l.Tween(h);p.to(e(i.stopObject),n),p.delay(c),p.easing(d),r(i.update)&&p.onUpdate(function(){i.update(h)}),p.onComplete(t(i.complete,null)),p.repeat(t(i._repeat,0));var f=new u(this,p,i.startObject,i.stopObject,i.duration,a,d,i.update,i.complete,i.cancel);return this._tweens.push(f),f},c.prototype.addProperty=function(e){function r(e){i[n]=e.value}e=t(e,t.EMPTY_OBJECT);var i=e.object,n=e.property,o=e.startValue,a=e.stopValue;return this.add({startObject:{value:o},stopObject:{value:a},duration:t(e.duration,3),delay:e.delay,easingFunction:e.easingFunction,update:r,complete:e.complete,cancel:e.cancel,_repeat:e._repeat})},c.prototype.addAlpha=function(e){function i(e){for(var t=o.length,r=0;r<t;++r)n.uniforms[o[r]].alpha=e.alpha}e=t(e,t.EMPTY_OBJECT);var n=e.material,o=[];for(var a in n.uniforms)n.uniforms.hasOwnProperty(a)&&r(n.uniforms[a])&&r(n.uniforms[a].alpha)&&o.push(a);return this.add({startObject:{alpha:t(e.startValue,0)},stopObject:{alpha:t(e.stopValue,1)},duration:t(e.duration,3),delay:e.delay,easingFunction:e.easingFunction,update:i,complete:e.complete,cancel:e.cancel})},c.prototype.addOffsetIncrement=function(e){e=t(e,t.EMPTY_OBJECT);var r=e.material,i=r.uniforms;return this.addProperty({object:i,property:"offset",startValue:i.offset,stopValue:i.offset+1,duration:e.duration,delay:e.delay,easingFunction:e.easingFunction,update:e.update,cancel:e.cancel,_repeat:1/0})},c.prototype.remove=function(e){if(!r(e))return!1;var t=this._tweens.indexOf(e);return-1!==t&&(e.tweenjs.stop(),r(e.cancel)&&e.cancel(),this._tweens.splice(t,1),!0)},c.prototype.removeAll=function(){for(var e=this._tweens,t=0;t<e.length;++t){var i=e[t];i.tweenjs.stop(),r(i.cancel)&&i.cancel()}e.length=0},c.prototype.contains=function(e){return r(e)&&-1!==this._tweens.indexOf(e)},c.prototype.get=function(e){return this._tweens[e]},c.prototype.update=function(e){var t=this._tweens,i=0;for(e=r(e)?e/s.SECONDS_PER_MILLISECOND:a();i<t.length;){var n=t[i],o=n.tweenjs;n.needsStart?(n.needsStart=!1,o.start(e)):o.update(e)?i++:(o.stop(),t.splice(i,1))}},c}),define("Scene/ScreenSpaceCameraController",["../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/Ellipsoid","../Core/HeadingPitchRoll","../Core/IntersectionTests","../Core/isArray","../Core/KeyboardEventModifier","../Core/Math","../Core/Matrix3","../Core/Matrix4","../Core/OrthographicFrustum","../Core/Plane","../Core/Quaternion","../Core/Ray","../Core/Transforms","./CameraEventAggregator","./CameraEventType","./MapMode2D","./SceneMode","./SceneTransforms","./TweenCollection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A){"use strict";function x(r){this.enableInputs=!0,this.enableTranslate=!0,this.enableZoom=!0,this.enableRotate=!0,this.enableTilt=!0,this.enableLook=!0,this.inertiaSpin=.9,this.inertiaTranslate=.9,this.inertiaZoom=.8,this.maximumMovementRatio=.1,this.bounceAnimationTime=3,this.minimumZoomDistance=1,this.maximumZoomDistance=Number.POSITIVE_INFINITY,this.translateEventTypes=S.LEFT_DRAG,this.zoomEventTypes=[S.RIGHT_DRAG,S.WHEEL,S.PINCH],this.rotateEventTypes=S.LEFT_DRAG,this.tiltEventTypes=[S.MIDDLE_DRAG,S.PINCH,{eventType:S.LEFT_DRAG,modifier:h.CTRL},{eventType:S.RIGHT_DRAG,modifier:h.CTRL}],this.lookEventTypes={eventType:S.LEFT_DRAG,modifier:h.SHIFT},this.minimumPickingTerrainHeight=15e4,this._minimumPickingTerrainHeight=this.minimumPickingTerrainHeight,this.minimumCollisionTerrainHeight=15e3,this._minimumCollisionTerrainHeight=this.minimumCollisionTerrainHeight,this.minimumTrackBallHeight=75e5,this._minimumTrackBallHeight=this.minimumTrackBallHeight,this.enableCollisionDetection=!0,this._scene=r,this._globe=void 0,this._ellipsoid=void 0,this._aggregator=new C(r.canvas),this._lastInertiaSpinMovement=void 0,this._lastInertiaZoomMovement=void 0,this._lastInertiaTranslateMovement=void 0,this._lastInertiaTiltMovement=void 0,this._tweens=new A,this._tween=void 0,this._horizontalRotationAxis=void 0,this._tiltCenterMousePosition=new e(-1,-1),this._tiltCenter=new t,this._rotateMousePosition=new e(-1,-1),this._rotateStartPosition=new t,this._strafeStartPosition=new t,this._zoomMouseStart=new e(-1,-1),this._zoomWorldPosition=new t,this._useZoomWorldPosition=!1,this._tiltCVOffMap=!1,this._looking=!1,this._rotating=!1,this._strafing=!1,this._zoomingOnVector=!1,this._rotatingZoom=!1;var n=r.mapProjection;this._maxCoord=n.project(new i(Math.PI,p.PI_OVER_TWO)),this._zoomFactor=5,this._rotateFactor=void 0,this._rotateRateRangeAdjustment=void 0,this._maximumRotateRate=1.77,this._minimumRotateRate=2e-4,this._minimumZoomRate=20,this._maximumZoomRate=5906376272e3}function P(e,t){if(e<0)return 0;var r=25*(1-t);return Math.exp(-r*e)}function D(t){return e.equalsEpsilon(t.startPosition,t.endPosition,p.EPSILON14)}function I(t,r,i,n,a,s,l){var u=s[l];o(u)||(u=s[l]={startPosition:new e,endPosition:new e,motion:new e,active:!1});var c=t.getButtonPressTime(r,i),d=t.getButtonReleaseTime(r,i),h=c&&d&&(d.getTime()-c.getTime())/1e3,p=new Date,f=d&&(p.getTime()-d.getTime())/1e3;if(c&&d&&h<te){var m=P(f,n);if(u.active)u.startPosition=e.clone(u.endPosition,u.startPosition),u.endPosition=e.multiplyByScalar(u.motion,m,u.endPosition),u.endPosition=e.add(u.startPosition,u.endPosition,u.endPosition),u.motion=e.clone(e.ZERO,u.motion);else{var g=t.getLastMovement(r,i);if(!o(g)||D(g))return;u.motion.x=.5*(g.endPosition.x-g.startPosition.x),u.motion.y=.5*(g.endPosition.y-g.startPosition.y),u.startPosition=e.clone(g.startPosition,u.startPosition),u.endPosition=e.multiplyByScalar(u.motion,m,u.endPosition),u.endPosition=e.add(u.startPosition,u.endPosition,u.endPosition),u.active=!0}if(isNaN(u.endPosition.x)||isNaN(u.endPosition.y)||e.distance(u.startPosition,u.endPosition)<.5)return void(u.active=!1);if(!t.isButtonDown(r,i)){a(s,t.getStartMousePosition(r,i),u)}}else u.active=!1}function O(e,t,r,i,n,a){if(o(r)){var s=e._aggregator;d(r)||(re[0]=r,r=re);for(var l=r.length,u=0;u<l;++u){var c=r[u],h=o(c.eventType)?c.eventType:c,p=c.modifier,f=s.isMoving(h,p)&&s.getMovement(h,p),m=s.getStartMousePosition(h,p);e.enableInputs&&t&&(f?i(e,m,f):n<1&&I(s,h,p,n,i,e,a))}}}function M(r,i,n,a,s,l){var u=1;o(l)&&(u=p.clamp(Math.abs(l),.25,1));var c=r.minimumZoomDistance*u,d=r.maximumZoomDistance,h=s-c,f=a*h;f=p.clamp(f,r._minimumZoomRate,r._maximumZoomRate);var m=n.endPosition.y-n.startPosition.y,_=m/r._scene.canvas.clientHeight;_=Math.min(_,r.maximumMovementRatio);var v=f*_;if(!(v>0&&Math.abs(s-c)<1||v<0&&Math.abs(s-d)<1)){s-v<c?v=s-c-1:s-v>d&&(v=s-d);var y=r._scene,b=y.camera,C=y.mode,S=Ae.orientation;if(S.heading=b.heading,S.pitch=b.pitch,S.roll=b.roll,b.frustum instanceof g)return void(Math.abs(v)>0&&(b.zoomIn(v),b._adjustOrthographicFrustum()));var w,A=e.equals(i,r._zoomMouseStart),x=r._zoomingOnVector,P=r._rotatingZoom;if(A||(r._zoomMouseStart=e.clone(i,r._zoomMouseStart),o(r._globe)&&(w=C!==T.SCENE2D?B(r,i,ne):b.getPickRay(i,ie).origin),o(w)?(r._useZoomWorldPosition=!0,r._zoomWorldPosition=t.clone(w,r._zoomWorldPosition)):r._useZoomWorldPosition=!1,x=r._zoomingOnVector=!1,P=r._rotatingZoom=!1),!r._useZoomWorldPosition)return void b.zoomIn(v);var D=C===T.COLUMBUS_VIEW;if(b.positionCartographic.height<2e6&&(P=!0),!A||P){if(C===T.SCENE2D){var I=r._zoomWorldPosition,O=b.position;if(!t.equals(I,O)&&b.positionCartographic.height<2*r._maxCoord.x){var M=b.position.x,R=t.subtract(I,O,ae);t.normalize(R,R);var L=t.distance(I,O)*v/(.5*b.getMagnitude());b.move(R,.5*L),(b.position.x<0&&M>0||b.position.x>0&&M<0)&&(w=b.getPickRay(i,ie).origin,r._zoomWorldPosition=t.clone(w,r._zoomWorldPosition))}}else if(C===T.SCENE3D){var N=t.normalize(b.position,he);if(b.positionCartographic.height<3e3&&Math.abs(t.dot(b.direction,N))<.6)D=!0;else{var k=y.canvas,F=se;F.x=k.clientWidth/2,F.y=k.clientHeight/2;var U=B(r,F,le);if(o(U)&&b.positionCartographic.height<1e6){var V=fe;t.clone(b.position,V);var z=r._zoomWorldPosition,G=pe;if(G=t.normalize(z,G),t.dot(G,N)<0)return;var W=Se,H=_e;t.clone(b.direction,H),t.add(V,t.multiplyByScalar(H,1e3,we),W);var j=ve,q=ye;t.subtract(z,V,j),t.normalize(j,q);var Y=t.dot(N,q);if(Y>=0)return void(r._zoomMouseStart.x=-1);var X=Math.acos(-Y),Q=t.magnitude(V),Z=t.magnitude(z),K=Q-v,J=t.magnitude(j),$=Math.asin(p.clamp(J/Z*Math.sin(X),-1,1)),ee=Math.asin(p.clamp(K/Z*Math.sin(X),-1,1)),te=$-ee+X,re=me;t.normalize(V,re);var xe=ge;xe=t.cross(q,re,xe),xe=t.normalize(xe,xe),t.normalize(t.cross(re,xe,we),H),t.multiplyByScalar(t.normalize(W,we),t.magnitude(W)-v,W),t.normalize(V,V),t.multiplyByScalar(V,K,V);var Pe=be;t.multiplyByScalar(t.add(t.multiplyByScalar(re,Math.cos(te)-1,Te),t.multiplyByScalar(H,Math.sin(te),Ee),we),K,Pe),t.add(V,Pe,V),t.normalize(W,re),t.normalize(t.cross(re,xe,we),H);var De=Ce;return t.multiplyByScalar(t.add(t.multiplyByScalar(re,Math.cos(te)-1,Te),t.multiplyByScalar(H,Math.sin(te),Ee),we),t.magnitude(W),De),t.add(W,De,W),t.clone(V,b.position),t.normalize(t.subtract(W,V,we),b.direction),t.clone(b.direction,b.direction),t.cross(b.direction,b.up,b.right),t.cross(b.right,b.direction,b.up),void b.setView(Ae)}if(o(U)){var Ie=t.normalize(U,ue),Oe=t.normalize(r._zoomWorldPosition,ce),Me=t.dot(Oe,Ie);if(Me>0&&Me<1){var Re=p.acosClamped(Me),Le=t.cross(Oe,Ie,de),Ne=Math.abs(Re)>p.toRadians(20)?.75*b.positionCartographic.height:b.positionCartographic.height-v,ke=v/Ne;b.rotate(Le,Re*ke)}}else D=!0}}r._rotatingZoom=!D}if(!A&&D||x){var Fe,Be=E.wgs84ToWindowCoordinates(y,r._zoomWorldPosition,oe);Fe=C!==T.COLUMBUS_VIEW&&e.equals(i,r._zoomMouseStart)&&o(Be)?b.getPickRay(Be,ie):b.getPickRay(i,ie);var Ue=Fe.direction;C===T.COLUMBUS_VIEW&&t.fromElements(Ue.y,Ue.z,Ue.x,Ue),b.move(Ue,v),r._zoomingOnVector=!0}else b.zoomIn(v);b.setView(Ae)}}function R(e,r,i){var n=e._scene,o=n.camera,a=o.getPickRay(i.startPosition,xe).origin,s=o.getPickRay(i.endPosition,Pe).origin,l=t.subtract(a,s,De),u=t.magnitude(l);u>0&&(t.normalize(l,l),o.move(l,u))}function L(e,t,r){o(r.distance)&&(r=r.distance);var i=e._scene,n=i.camera;M(e,t,r,e._zoomFactor,n.getMagnitude())}function N(t,r,i){if(o(i.angleAndHeight))return void k(t,r,i.angleAndHeight);var n=t._scene,a=n.camera,s=n.canvas,l=s.clientWidth,u=s.clientHeight,c=Ie;c.x=2/l*i.startPosition.x-1,c.y=2/u*(u-i.startPosition.y)-1,c=e.normalize(c,c);var d=Oe;d.x=2/l*i.endPosition.x-1,d.y=2/u*(u-i.endPosition.y)-1,d=e.normalize(d,d);var h=p.acosClamped(c.x);c.y<0&&(h=p.TWO_PI-h);var f=p.acosClamped(d.x);d.y<0&&(f=p.TWO_PI-f);var m=f-h;a.twistRight(m)}function k(e,t,r){var i=e._rotateFactor*e._rotateRateRangeAdjustment;i>e._maximumRotateRate&&(i=e._maximumRotateRate),i<e._minimumRotateRate&&(i=e._minimumRotateRate);var n=e._scene,o=n.camera,a=n.canvas,s=(r.endPosition.x-r.startPosition.x)/a.clientWidth;s=Math.min(s,e.maximumMovementRatio);var l=i*s*Math.PI*4;o.twistRight(l)}function F(e){var t=e._scene.mapMode2D===w.ROTATE;m.equals(m.IDENTITY,e._scene.camera.transform)?(O(e,e.enableTranslate,e.translateEventTypes,R,e.inertiaTranslate,"_lastInertiaTranslateMovement"),O(e,e.enableZoom,e.zoomEventTypes,L,e.inertiaZoom,"_lastInertiaZoomMovement"),t&&O(e,e.enableRotate,e.tiltEventTypes,N,e.inertiaSpin,"_lastInertiaTiltMovement")):(O(e,e.enableZoom,e.zoomEventTypes,L,e.inertiaZoom,"_lastInertiaZoomMovement"),t&&O(e,e.enableRotate,e.translateEventTypes,N,e.inertiaSpin,"_lastInertiaSpinMovement"))}function B(e,r,i){var n=e._scene,a=e._globe,s=n.camera;if(o(a)){var l;n.pickPositionSupported&&(l=n.pickPositionWorldCoordinates(r,Re));var u=s.getPickRay(r,Me),c=a.pick(u,n,Le);return(o(l)?t.distance(l,s.positionWC):Number.POSITIVE_INFINITY)<(o(c)?t.distance(c,s.positionWC):Number.POSITIVE_INFINITY)?t.clone(l,i):t.clone(c,i)}}function U(r,i,n){if(t.equals(i,r._translateMousePosition)||(r._looking=!1),t.equals(i,r._strafeMousePosition)||(r._strafing=!1),r._looking)return void $(r,i,n);if(r._strafing)return void j(r,i,n);var a,s=r._scene,l=s.camera,u=e.clone(n.startPosition,Ge),d=e.clone(n.endPosition,We),h=l.getPickRay(u,Ne),f=t.clone(t.ZERO,Ve),m=t.UNIT_X;if(l.position.z<r._minimumPickingTerrainHeight&&(a=B(r,u,Fe),o(a)&&(f.x=a.x)),f.x>l.position.z&&o(a))return t.clone(a,r._strafeStartPosition),r._strafing=!0,j(r,i,n),void(r._strafeMousePosition=e.clone(i,r._strafeMousePosition));var g=_.fromPointNormal(f,m,ze);h=l.getPickRay(u,Ne);var v=c.rayPlane(h,g,Fe),y=l.getPickRay(d,ke),b=c.rayPlane(y,g,Be);if(!o(v)||!o(b))return r._looking=!0,$(r,i,n),void e.clone(i,r._translateMousePosition);var C=t.subtract(v,b,Ue),S=C.x;C.x=C.y,C.y=C.z,C.z=S;var w=t.magnitude(C);w>p.EPSILON6&&(t.normalize(C,C),l.move(C,w))}function V(t,r,i){if(o(i.angleAndHeight)&&(i=i.angleAndHeight),e.equals(r,t._tiltCenterMousePosition)||(t._tiltCVOffMap=!1,t._looking=!1),t._looking)return void $(t,r,i);var n=t._scene,a=n.camera,s=t._maxCoord,l=Math.abs(a.position.x)-s.x<0&&Math.abs(a.position.y)-s.y<0;t._tiltCVOffMap||!l||a.position.z>t._minimumPickingTerrainHeight?(t._tiltCVOffMap=!0,z(t,r,i)):G(t,r,i)}function z(r,i,n){var a=r._scene,s=a.camera,u=a.canvas,c=He;c.x=u.clientWidth/2,c.y=u.clientHeight/2;var d,h=s.getPickRay(c,je),f=t.UNIT_X,g=h.origin,_=h.direction,v=t.dot(f,_);if(Math.abs(v)>p.EPSILON6&&(d=-t.dot(f,g)/v),!o(d)||d<=0)return r._looking=!0,$(r,i,n),void e.clone(i,r._tiltCenterMousePosition);var y=t.multiplyByScalar(_,d,qe);t.add(g,y,y);var C=a.mapProjection,S=C.ellipsoid;t.fromElements(y.y,y.z,y.x,y);var w=C.unproject(y,$e);S.cartographicToCartesian(w,y);var T=b.eastNorthUpToFixedFrame(y,S,Xe),E=r._globe,A=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var x=m.clone(s.transform,et);s._setTransform(T),Y(r,i,n,t.UNIT_Z),s._setTransform(x),r._globe=E,r._ellipsoid=A;var P=A.maximumRadius;r._rotateFactor=1/P,r._rotateRateRangeAdjustment=P}function G(r,i,n){var a,s,u=r._scene,d=u.camera,h=t.UNIT_X;if(e.equals(i,r._tiltCenterMousePosition))a=t.clone(r._tiltCenter,qe);else{if(d.position.z<r._minimumPickingTerrainHeight&&(a=B(r,i,qe)),!o(a)){s=d.getPickRay(i,je);var g,y=s.origin,C=s.direction,S=t.dot(h,C);if(Math.abs(S)>p.EPSILON6&&(g=-t.dot(h,y)/S),!o(g)||g<=0)return r._looking=!0,$(r,i,n),void e.clone(i,r._tiltCenterMousePosition);a=t.multiplyByScalar(C,g,qe),t.add(y,a,a)}e.clone(i,r._tiltCenterMousePosition),t.clone(a,r._tiltCenter)}var w=u.canvas,T=He;T.x=w.clientWidth/2,T.y=r._tiltCenterMousePosition.y,s=d.getPickRay(T,je);var E=t.clone(t.ZERO,Ze);E.x=a.x;var A=_.fromPointNormal(E,h,Ke),x=c.rayPlane(s,A,Ye),P=d._projection,D=P.ellipsoid;t.fromElements(a.y,a.z,a.x,a);var I=P.unproject(a,$e);D.cartographicToCartesian(I,a);var O,M=b.eastNorthUpToFixedFrame(a,D,Xe);o(x)?(t.fromElements(x.y,x.z,x.x,x),I=P.unproject(x,$e),D.cartographicToCartesian(I,x),O=b.eastNorthUpToFixedFrame(x,D,Qe)):O=M;var R=r._globe,L=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var N=t.UNIT_Z,k=m.clone(d.transform,et);d._setTransform(M);var F=t.cross(t.UNIT_Z,t.normalize(d.position,Je),Je),U=t.dot(d.right,F);if(Y(r,i,n,N,!1,!0),d._setTransform(O),U<0){n.startPosition.y>n.endPosition.y&&(N=void 0);var V=d.constrainedAxis;d.constrainedAxis=void 0,Y(r,i,n,N,!0,!1),d.constrainedAxis=V}else Y(r,i,n,N,!0,!1);if(o(d.constrainedAxis)){var z=t.cross(d.direction,d.constrainedAxis,it);t.equalsEpsilon(z,t.ZERO,p.EPSILON6)||(t.dot(z,d.right)<0&&t.negate(z,z),t.cross(z,d.direction,d.up),t.cross(d.direction,d.up,d.right),t.normalize(d.up,d.up),t.normalize(d.right,d.right))}d._setTransform(k),r._globe=R,r._ellipsoid=L;var G=L.maximumRadius;r._rotateFactor=1/G,r._rotateRateRangeAdjustment=G;var W=t.clone(d.positionWC,Je);if(d._adjustHeightForTerrain(),!t.equals(d.positionWC,W)){d._setTransform(O),d.worldToCameraCoordinatesPoint(W,W);var H=t.magnitudeSquared(W);t.magnitudeSquared(d.position)>H&&(t.normalize(d.position,d.position),t.multiplyByScalar(d.position,Math.sqrt(H),d.position));var j=t.angleBetween(W,d.position),q=t.cross(W,d.position,W);t.normalize(q,q);var X=v.fromAxisAngle(q,j,tt),Q=f.fromQuaternion(X,rt);f.multiplyByVector(Q,d.direction,d.direction),f.multiplyByVector(Q,d.up,d.up),t.cross(d.direction,d.up,d.right),t.cross(d.right,d.direction,d.up),d._setTransform(k)}}function W(e,r,i){o(i.distance)&&(i=i.distance);var n=e._scene,a=n.camera,s=n.canvas,l=nt;l.x=s.clientWidth/2,l.y=s.clientHeight/2;var u,c=a.getPickRay(l,ot);a.position.z<e._minimumPickingTerrainHeight&&(u=B(e,l,at));var d;if(o(u))d=t.distance(c.origin,u);else{var h=t.UNIT_X,p=c.origin,f=c.direction;d=-t.dot(h,p)/t.dot(h,f)}M(e,r,i,e._zoomFactor,d)}function H(e){var t=e._scene,r=t.camera;if(m.equals(m.IDENTITY,r.transform)){var i=e._tweens;if(e._aggregator.anyButtonDown&&i.removeAll(),O(e,e.enableTilt,e.tiltEventTypes,V,e.inertiaSpin,"_lastInertiaTiltMovement"),O(e,e.enableTranslate,e.translateEventTypes,U,e.inertiaTranslate,"_lastInertiaTranslateMovement"),O(e,e.enableZoom,e.zoomEventTypes,W,e.inertiaZoom,"_lastInertiaZoomMovement"),O(e,e.enableLook,e.lookEventTypes,$),!(e._aggregator.anyButtonDown||o(e._lastInertiaZoomMovement)&&e._lastInertiaZoomMovement.active||o(e._lastInertiaTranslateMovement)&&e._lastInertiaTranslateMovement.active||i.contains(e._tween))){var n=r.createCorrectPositionTween(e.bounceAnimationTime);o(n)&&(e._tween=i.add(n))}i.update()}else O(e,e.enableRotate,e.rotateEventTypes,Y,e.inertiaSpin,"_lastInertiaSpinMovement"),O(e,e.enableZoom,e.zoomEventTypes,Q,e.inertiaZoom,"_lastInertiaZoomMovement")}function j(e,r,i){var n=e._scene,a=n.camera,s=B(e,i.startPosition,dt);if(o(s)){var l=i.endPosition,u=a.getPickRay(l,st),d=t.clone(a.direction,ct);n.mode===T.COLUMBUS_VIEW&&t.fromElements(d.z,d.x,d.y,d);var h=_.fromPointNormal(s,d,lt),p=c.rayPlane(u,h,ut);o(p)&&(d=t.subtract(s,p,d),n.mode===T.COLUMBUS_VIEW&&t.fromElements(d.y,d.z,d.x,d),t.add(a.position,d,a.position))}}function q(r,i,n){var a=r._scene,s=a.camera;if(!m.equals(s.transform,m.IDENTITY))return void Y(r,i,n);var u,c,d,h,p=r._ellipsoid.geodeticSurfaceNormal(s.position,gt),f=r._ellipsoid.cartesianToCartographic(s.positionWC,pt).height,g=r._globe,_=!1;if(o(g)&&f<r._minimumPickingTerrainHeight&&(h=B(r,n.startPosition,dt),o(h))){var v=s.getPickRay(n.startPosition,Me),y=r._ellipsoid.geodeticSurfaceNormal(h);_=Math.abs(t.dot(v.direction,y))<.05,_&&!r._looking&&(r._rotating=!1,r._strafing=!0)}if(e.equals(i,r._rotateMousePosition))return void(r._looking?$(r,i,n,p):r._rotating?Y(r,i,n):r._strafing?(t.clone(h,r._strafeStartPosition),j(r,i,n)):(u=t.magnitude(r._rotateStartPosition),c=ft,c.x=c.y=c.z=u,d=l.fromCartesian3(c,mt),X(r,i,n,d)));r._looking=!1,r._rotating=!1,r._strafing=!1,o(g)&&f<r._minimumPickingTerrainHeight?o(h)?t.magnitude(s.position)<t.magnitude(h)?(t.clone(h,r._strafeStartPosition),r._strafing=!0,j(r,i,n)):(u=t.magnitude(h),c=ft,c.x=c.y=c.z=u,d=l.fromCartesian3(c,mt),X(r,i,n,d),t.clone(h,r._rotateStartPosition)):(r._looking=!0,$(r,i,n,p)):o(s.pickEllipsoid(n.startPosition,r._ellipsoid,ht))?(X(r,i,n,r._ellipsoid),t.clone(ht,r._rotateStartPosition)):f>r._minimumTrackBallHeight?(r._rotating=!0,Y(r,i,n)):(r._looking=!0,$(r,i,n,p)),e.clone(i,r._rotateMousePosition)}function Y(e,r,i,a,s,l){s=n(s,!1),l=n(l,!1);var u=e._scene,c=u.camera,d=u.canvas,h=c.constrainedAxis;o(a)&&(c.constrainedAxis=a);var p=t.magnitude(c.position),f=e._rotateFactor*(p-e._rotateRateRangeAdjustment);f>e._maximumRotateRate&&(f=e._maximumRotateRate),f<e._minimumRotateRate&&(f=e._minimumRotateRate);var m=(i.startPosition.x-i.endPosition.x)/d.clientWidth,g=(i.startPosition.y-i.endPosition.y)/d.clientHeight;m=Math.min(m,e.maximumMovementRatio),g=Math.min(g,e.maximumMovementRatio);var _=f*m*Math.PI*2,v=f*g*Math.PI;s||c.rotateRight(_),l||c.rotateUp(v),c.constrainedAxis=h}function X(r,i,n,a){var s=r._scene,l=s.camera,u=e.clone(n.startPosition,wt),c=e.clone(n.endPosition,Tt),d=l.pickEllipsoid(u,a,_t),h=l.pickEllipsoid(c,a,vt);if(!o(d)||!o(h))return r._rotating=!0,void Y(r,i,n);if(d=l.worldToCameraCoordinates(d,d),h=l.worldToCameraCoordinates(h,h),o(l.constrainedAxis)){var f=l.constrainedAxis,m=t.mostOrthogonalAxis(f,yt);t.cross(m,f,m),t.normalize(m,m);var g=t.cross(f,m,bt),_=t.magnitude(d),v=t.dot(f,d),y=Math.acos(v/_),b=t.multiplyByScalar(f,v,Ct);t.subtract(d,b,b),t.normalize(b,b);var C=t.magnitude(h),S=t.dot(f,h),w=Math.acos(S/C),T=t.multiplyByScalar(f,S,St);t.subtract(h,T,T),t.normalize(T,T);var E=Math.acos(t.dot(b,m));t.dot(b,g)<0&&(E=p.TWO_PI-E);var A=Math.acos(t.dot(T,m));t.dot(T,g)<0&&(A=p.TWO_PI-A);var x,P=E-A;x=t.equalsEpsilon(f,l.position,p.EPSILON2)?l.right:t.cross(f,l.position,yt);var D,I=t.cross(f,x,yt),O=t.dot(I,t.subtract(d,f,bt)),M=t.dot(I,t.subtract(h,f,bt));D=O>0&&M>0?w-y:O>0&&M<=0?t.dot(l.position,f)>0?-y-w:y+w:y-w,l.rotateRight(P),l.rotateUp(D)}else{t.normalize(d,d),t.normalize(h,h);var R=t.dot(d,h),L=t.cross(d,h,yt);if(R<1&&!t.equalsEpsilon(L,t.ZERO,p.EPSILON14)){var N=Math.acos(R);l.rotate(L,N)}}}function Q(e,r,i){o(i.distance)&&(i=i.distance);var n=e._ellipsoid,a=e._scene,s=a.camera,l=a.canvas,u=nt;u.x=l.clientWidth/2,u.y=l.clientHeight/2;var c,d=s.getPickRay(u,ot),h=n.cartesianToCartographic(s.position,At).height;h<e._minimumPickingTerrainHeight&&(c=B(e,u,at));var p;p=o(c)?t.distance(d.origin,c):h;var f=t.normalize(s.position,Et);M(e,r,i,e._zoomFactor,p,t.dot(f,s.direction))}function Z(t,r,i){var n=t._scene,a=n.camera;if(m.equals(a.transform,m.IDENTITY)){if(o(i.angleAndHeight)&&(i=i.angleAndHeight),e.equals(r,t._tiltCenterMousePosition)||(t._tiltOnEllipsoid=!1,t._looking=!1),t._looking){return void $(t,r,i,t._ellipsoid.geodeticSurfaceNormal(a.position,Ft))}var s=t._ellipsoid,l=s.cartesianToCartographic(a.position,kt);t._tiltOnEllipsoid||l.height>t._minimumCollisionTerrainHeight?(t._tiltOnEllipsoid=!0,K(t,r,i)):J(t,r,i)}}function K(r,i,n){var a=r._ellipsoid,s=r._scene,u=s.camera,d=.25*r.minimumZoomDistance,h=a.cartesianToCartographic(u.positionWC,Bt).height;if(!(h-d-1<p.EPSILON3&&n.endPosition.y-n.startPosition.y<0)){var f=s.canvas,g=xt;g.x=f.clientWidth/2,g.y=f.clientHeight/2;var _,v=u.getPickRay(g,Pt),C=c.rayEllipsoid(v,a);if(o(C))_=y.getPoint(v,C.start,Dt);else{if(!(h>r._minimumTrackBallHeight)){r._looking=!0;return $(r,i,n,r._ellipsoid.geodeticSurfaceNormal(u.position,Ft)),void e.clone(i,r._tiltCenterMousePosition)}var S=c.grazingAltitudeLocation(v,a);if(!o(S))return;var w=a.cartesianToCartographic(S,kt);w.height=0,_=a.cartographicToCartesian(w,Dt)}var T=b.eastNorthUpToFixedFrame(_,a,Ot),E=r._globe,A=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var x=m.clone(u.transform,Rt);u._setTransform(T),Y(r,i,n,t.UNIT_Z),u._setTransform(x),r._globe=E,r._ellipsoid=A;var P=A.maximumRadius;r._rotateFactor=1/P,r._rotateRateRangeAdjustment=P}}function J(r,i,n){var a,s,u,d=r._ellipsoid,h=r._scene,g=h.camera;if(e.equals(i,r._tiltCenterMousePosition))a=t.clone(r._tiltCenter,Dt);else{if(a=B(r,i,Dt),!o(a)){if(s=g.getPickRay(i,Pt),u=c.rayEllipsoid(s,d),!o(u)){if(d.cartesianToCartographic(g.position,kt).height<=r._minimumTrackBallHeight){r._looking=!0;$(r,i,n,r._ellipsoid.geodeticSurfaceNormal(g.position,Ft)),e.clone(i,r._tiltCenterMousePosition)}return}a=y.getPoint(s,u.start,Dt)}e.clone(i,r._tiltCenterMousePosition),t.clone(a,r._tiltCenter)}var _=h.canvas,C=xt;C.x=_.clientWidth/2,C.y=r._tiltCenterMousePosition.y,s=g.getPickRay(C,Pt);var S=t.magnitude(a),w=t.fromElements(S,S,S,ft),T=l.fromCartesian3(w,mt);if(u=c.rayEllipsoid(s,T),o(u)){var E=t.magnitude(s.origin)>S?u.start:u.stop,A=y.getPoint(s,E,It),x=b.eastNorthUpToFixedFrame(a,d,Ot),P=b.eastNorthUpToFixedFrame(A,T,Mt),D=r._globe,I=r._ellipsoid;r._globe=void 0,r._ellipsoid=l.UNIT_SPHERE,r._rotateFactor=1,r._rotateRateRangeAdjustment=1;var O=t.UNIT_Z,M=m.clone(g.transform,Rt);g._setTransform(x);var R=t.cross(A,g.positionWC,it),L=t.dot(g.rightWC,R);if(Y(r,i,n,O,!1,!0),g._setTransform(P),L<0){n.startPosition.y>n.endPosition.y&&(O=void 0);var N=g.constrainedAxis;g.constrainedAxis=void 0,Y(r,i,n,O,!0,!1),g.constrainedAxis=N}else Y(r,i,n,O,!0,!1);if(o(g.constrainedAxis)){var k=t.cross(g.direction,g.constrainedAxis,it);t.equalsEpsilon(k,t.ZERO,p.EPSILON6)||(t.dot(k,g.right)<0&&t.negate(k,k),t.cross(k,g.direction,g.up),t.cross(g.direction,g.up,g.right),t.normalize(g.up,g.up),t.normalize(g.right,g.right))}g._setTransform(M),r._globe=D,r._ellipsoid=I;var F=I.maximumRadius;r._rotateFactor=1/F,r._rotateRateRangeAdjustment=F;var U=t.clone(g.positionWC,it);if(g._adjustHeightForTerrain(),!t.equals(g.positionWC,U)){g._setTransform(P),g.worldToCameraCoordinatesPoint(U,U);var V=t.magnitudeSquared(U);t.magnitudeSquared(g.position)>V&&(t.normalize(g.position,g.position),t.multiplyByScalar(g.position,Math.sqrt(V),g.position));var z=t.angleBetween(U,g.position),G=t.cross(U,g.position,U);t.normalize(G,G);var W=v.fromAxisAngle(G,z,Lt),H=f.fromQuaternion(W,Nt);f.multiplyByVector(H,g.direction,g.direction),f.multiplyByVector(H,g.up,g.up),t.cross(g.direction,g.up,g.right),t.cross(g.right,g.direction,g.up),g._setTransform(M)}}}function $(e,r,i,a){var s=e._scene,l=s.camera,u=Ut;u.x=i.startPosition.x,u.y=0;var c=Vt;c.x=i.endPosition.x,c.y=0;var d,h,f=l.getPickRay(u,zt),m=l.getPickRay(c,Gt),_=0;l.frustum instanceof g?(d=f.origin,h=m.origin,t.add(l.direction,d,d),t.add(l.direction,h,h),t.subtract(d,l.position,d),t.subtract(h,l.position,h),t.normalize(d,d),t.normalize(h,h)):(d=f.direction,h=m.direction);var v=t.dot(d,h);v<1&&(_=Math.acos(v)),_=i.startPosition.x>i.endPosition.x?-_:_;var y=e._horizontalRotationAxis;if(o(a)?l.look(a,-_):o(y)?l.look(y,-_):l.lookLeft(_),u.x=0,u.y=i.startPosition.y,c.x=0,c.y=i.endPosition.y,f=l.getPickRay(u,zt),m=l.getPickRay(c,Gt),_=0,l.frustum instanceof g?(d=f.origin,h=m.origin,t.add(l.direction,d,d),t.add(l.direction,h,h),t.subtract(d,l.position,d),t.subtract(h,l.position,h),t.normalize(d,d),t.normalize(h,h)):(d=f.direction,h=m.direction),v=t.dot(d,h),v<1&&(_=Math.acos(v)),_=i.startPosition.y>i.endPosition.y?-_:_,a=n(a,y),o(a)){var b=l.direction,C=t.negate(a,Wt),S=t.equalsEpsilon(b,a,p.EPSILON2),w=t.equalsEpsilon(b,C,p.EPSILON2);if(S||w)(S&&_<0||w&&_>0)&&l.look(l.right,-_);else{v=t.dot(b,a);var T=p.acosClamped(v);_>0&&_>T&&(_=T-p.EPSILON4),v=t.dot(b,C),T=p.acosClamped(v),_<0&&-_>T&&(_=-T+p.EPSILON4);var E=t.cross(a,b,Ht);l.look(E,_)}}else l.lookUp(_)}function ee(e){O(e,e.enableRotate,e.rotateEventTypes,q,e.inertiaSpin,"_lastInertiaSpinMovement"),O(e,e.enableZoom,e.zoomEventTypes,Q,e.inertiaZoom,"_lastInertiaZoomMovement"),O(e,e.enableTilt,e.tiltEventTypes,Z,e.inertiaSpin,"_lastInertiaTiltMovement"),O(e,e.enableLook,e.lookEventTypes,$)}var te=.4,re=[],ie=new y,ne=new t,oe=new e,ae=new t,se=new e,le=new t,ue=new t,ce=new t,de=new t,he=new t,pe=new t,fe=new t,me=new t,ge=new t,_e=new t,ve=new t,ye=new t,be=new t,Ce=new t,Se=new t,we=new t,Te=new t,Ee=new t,Ae={orientation:new u},xe=new y,Pe=new y,De=new t,Ie=new e,Oe=new e,Me=new y,Re=new t,Le=new t,Ne=new y,ke=new y,Fe=new t,Be=new t,Ue=new t,Ve=new t,ze=new _(t.UNIT_X,0),Ge=new e,We=new e,He=new e,je=new y,qe=new t,Ye=new t,Xe=new m,Qe=new m,Ze=new t,Ke=new _(t.UNIT_X,0),Je=new t,$e=new i,et=new m,tt=new v,rt=new f,it=new t,nt=new e,ot=new y,at=new t,st=new y,lt=new _(t.UNIT_X,0),ut=new t,ct=new t,dt=new t,ht=new t,pt=new i,ft=new t,mt=new l,gt=new t,_t=r.clone(r.UNIT_W),vt=r.clone(r.UNIT_W),yt=new t,bt=new t,Ct=new t,St=new t,wt=new e,Tt=new e,Et=new t,At=new i,xt=new e,Pt=new y,Dt=new t,It=new t,Ot=new m,Mt=new m,Rt=new m,Lt=new v,Nt=new f,kt=new i,Ft=new t,Bt=new i,Ut=new e,Vt=new e,zt=new y,Gt=new y,Wt=new t,Ht=new t;return x.prototype.update=function(){m.equals(this._scene.camera.transform,m.IDENTITY)?(this._globe=this._scene.globe,this._ellipsoid=o(this._globe)?this._globe.ellipsoid:this._scene.mapProjection.ellipsoid):(this._globe=void 0,this._ellipsoid=l.UNIT_SPHERE),this._minimumCollisionTerrainHeight=this.minimumCollisionTerrainHeight*this._scene.terrainExaggeration,this._minimumPickingTerrainHeight=this.minimumPickingTerrainHeight*this._scene.terrainExaggeration,this._minimumTrackBallHeight=this.minimumTrackBallHeight*this._scene.terrainExaggeration;var e=this._ellipsoid.maximumRadius;this._rotateFactor=1/e,this._rotateRateRangeAdjustment=e;var r=this._scene,i=r.mode;i===T.SCENE2D?F(this):i===T.COLUMBUS_VIEW?(this._horizontalRotationAxis=t.UNIT_Z,H(this)):i===T.SCENE3D&&(this._horizontalRotationAxis=void 0,ee(this)),this._aggregator.reset()},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){return this._tweens.removeAll(),this._aggregator=this._aggregator&&this._aggregator.destroy(),a(this)},x}),define("Scene/ShadowMapShader",["../Core/defined","../Renderer/ShaderSource"],function(e,t){"use strict";function r(){}return r.getShadowCastShaderKeyword=function(e,t,r,i){return"castShadow "+e+" "+t+" "+r+" "+i},r.createShadowCastVertexShader=function(r,i,n){var o=r.defines.slice(0),a=r.sources.slice(0);n&&o.push("GENERATE_POSITION");var s=t.findPositionVarying(r),l=e(s);if(i&&!l){for(var u=a.length,c=0;c<u;++c)a[c]=t.replaceMain(a[c],"czm_shadow_cast_main");a.push("varying vec3 v_positionEC; \nvoid main() \n{ \n czm_shadow_cast_main(); \n v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n}")}return new t({defines:o,sources:a})},r.createShadowCastFragmentShader=function(r,i,n,o){var a=r.defines.slice(0),s=r.sources.slice(0),l=t.findPositionVarying(r),u=e(l);u||(l="v_positionEC");for(var c=s.length,d=0;d<c;++d)s[d]=t.replaceMain(s[d],"czm_shadow_cast_main");var h="";return i&&(u||(h+="varying vec3 v_positionEC; \n"),h+="uniform vec4 shadowMap_lightPositionEC; \n"), +h+=o?"void main() \n{ \n":"void main() \n{ \n czm_shadow_cast_main(); \n if (gl_FragColor.a == 0.0) \n { \n discard; \n } \n",h+=i?" float distance = length("+l+"); \n if (distance >= shadowMap_lightPositionEC.w) \n { \n discard; \n } \n distance /= shadowMap_lightPositionEC.w; // radius \n gl_FragColor = czm_packDepth(distance); \n":n?" gl_FragColor = vec4(1.0); \n":" gl_FragColor = czm_packDepth(gl_FragCoord.z); \n",h+="} \n",s.push(h),new t({defines:a,sources:s})},r.getShadowReceiveShaderKeyword=function(e,t,r,i){return"receiveShadow "+e._usesDepthTexture+e._polygonOffsetSupported+e._isPointLight+e._isSpotLight+(e._numberOfCascades>1)+e.debugCascadeColors+e.softShadows+t+r+i},r.createShadowReceiveVertexShader=function(e,r,i){var n=e.defines.slice(0),o=e.sources.slice(0);return r&&(i?n.push("GENERATE_POSITION_AND_NORMAL"):n.push("GENERATE_POSITION")),new t({defines:n,sources:o})},r.createShadowReceiveFragmentShader=function(r,i,n,o,a){for(var s=t.findNormalVarying(r),l=!o&&e(s)||o&&a,u=t.findPositionVarying(r),c=e(u),d=i._usesDepthTexture,h=i._polygonOffsetSupported,p=i._isPointLight,f=i._isSpotLight,m=i._numberOfCascades>1,g=i.debugCascadeColors,_=i.softShadows,v=p?i._pointBias:o?i._terrainBias:i._primitiveBias,y=r.defines.slice(0),b=r.sources.slice(0),C=b.length,S=0;S<C;++S)b[S]=t.replaceMain(b[S],"czm_shadow_receive_main");p?y.push("USE_CUBE_MAP_SHADOW"):d&&y.push("USE_SHADOW_DEPTH_TEXTURE"),_&&!p&&y.push("USE_SOFT_SHADOWS"),m&&n&&o&&(l?y.push("ENABLE_VERTEX_LIGHTING"):y.push("ENABLE_DAYNIGHT_SHADING")),n&&v.normalShading&&l&&(y.push("USE_NORMAL_SHADING"),v.normalShadingSmooth>0&&y.push("USE_NORMAL_SHADING_SMOOTH"));var w="";return w+=p?"uniform samplerCube shadowMap_textureCube; \n":"uniform sampler2D shadowMap_texture; \n",w+="uniform mat4 shadowMap_matrix; \nuniform vec3 shadowMap_lightDirectionEC; \nuniform vec4 shadowMap_lightPositionEC; \nuniform vec4 shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness; \nuniform vec4 shadowMap_texelSizeDepthBiasAndNormalShadingSmooth; \nvec4 getPositionEC() \n{ \n"+(c?" return vec4("+u+", 1.0); \n":" return czm_windowToEyeCoordinates(gl_FragCoord); \n")+"} \nvec3 getNormalEC() \n{ \n"+(l?" return normalize("+s+"); \n":" return vec3(1.0); \n")+"} \nvoid applyNormalOffset(inout vec4 positionEC, vec3 normalEC, float nDotL) \n{ \n"+(v.normalOffset&&l?" float normalOffset = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.x; \n float normalOffsetScale = 1.0 - nDotL; \n vec3 offset = normalOffset * normalOffsetScale * normalEC; \n positionEC.xyz += offset; \n":"")+"} \n",w+="void main() \n{ \n czm_shadow_receive_main(); \n vec4 positionEC = getPositionEC(); \n vec3 normalEC = getNormalEC(); \n float depth = -positionEC.z; \n",w+=" czm_shadowParameters shadowParameters; \n shadowParameters.texelStepSize = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.xy; \n shadowParameters.depthBias = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.z; \n shadowParameters.normalShadingSmooth = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.w; \n shadowParameters.darkness = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.w; \n",o?w+=" shadowParameters.depthBias *= max(depth * 0.01, 1.0); \n":h||(w+=" shadowParameters.depthBias *= mix(1.0, 100.0, depth * 0.0015); \n"),w+=p?" vec3 directionEC = positionEC.xyz - shadowMap_lightPositionEC.xyz; \n float distance = length(directionEC); \n directionEC = normalize(directionEC); \n float radius = shadowMap_lightPositionEC.w; \n // Stop early if the fragment is beyond the point light radius \n if (distance > radius) \n { \n return; \n } \n vec3 directionWC = czm_inverseViewRotation * directionEC; \n shadowParameters.depth = distance / radius; \n shadowParameters.nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n shadowParameters.texCoords = directionWC; \n float visibility = czm_shadowVisibility(shadowMap_textureCube, shadowParameters); \n":f?" vec3 directionEC = normalize(positionEC.xyz - shadowMap_lightPositionEC.xyz); \n float nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n applyNormalOffset(positionEC, normalEC, nDotL); \n vec4 shadowPosition = shadowMap_matrix * positionEC; \n // Spot light uses a perspective projection, so perform the perspective divide \n shadowPosition /= shadowPosition.w; \n // Stop early if the fragment is not in the shadow bounds \n if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n { \n return; \n } \n shadowParameters.texCoords = shadowPosition.xy; \n shadowParameters.depth = shadowPosition.z; \n shadowParameters.nDotL = nDotL; \n float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n":m?" float maxDepth = shadowMap_cascadeSplits[1].w; \n // Stop early if the eye depth exceeds the last cascade \n if (depth > maxDepth) \n { \n return; \n } \n // Get the cascade based on the eye-space depth \n vec4 weights = czm_cascadeWeights(depth); \n // Apply normal offset \n float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n applyNormalOffset(positionEC, normalEC, nDotL); \n // Transform position into the cascade \n vec4 shadowPosition = czm_cascadeMatrix(weights) * positionEC; \n // Get visibility \n shadowParameters.texCoords = shadowPosition.xy; \n shadowParameters.depth = shadowPosition.z; \n shadowParameters.nDotL = nDotL; \n float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n // Fade out shadows that are far away \n float shadowMapMaximumDistance = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.z; \n float fade = max((depth - shadowMapMaximumDistance * 0.8) / (shadowMapMaximumDistance * 0.2), 0.0); \n visibility = mix(visibility, 1.0, fade); \n"+(g?" // Draw cascade colors for debugging \n gl_FragColor *= czm_cascadeColor(weights); \n":""):" float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n applyNormalOffset(positionEC, normalEC, nDotL); \n vec4 shadowPosition = shadowMap_matrix * positionEC; \n // Stop early if the fragment is not in the shadow bounds \n if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n { \n return; \n } \n shadowParameters.texCoords = shadowPosition.xy; \n shadowParameters.depth = shadowPosition.z; \n shadowParameters.nDotL = nDotL; \n float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n",w+=" gl_FragColor.rgb *= visibility; \n} \n",b.push(w),new t({defines:y,sources:b})},r}),define("Scene/ShadowMap",["../Core/BoundingRectangle","../Core/BoundingSphere","../Core/BoxOutlineGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/clone","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/combine","../Core/CullingVolume","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/FeatureDetection","../Core/GeometryInstance","../Core/Intersect","../Core/Math","../Core/Matrix4","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/PixelFormat","../Core/Quaternion","../Core/SphereOutlineGeometry","../Core/WebGLConstants","../Renderer/ClearCommand","../Renderer/ContextLimits","../Renderer/CubeMap","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/Pass","../Renderer/PassState","../Renderer/PixelDatatype","../Renderer/Renderbuffer","../Renderer/RenderbufferFormat","../Renderer/RenderState","../Renderer/Sampler","../Renderer/Texture","../Renderer/TextureMagnificationFilter","../Renderer/TextureMinificationFilter","../Renderer/TextureWrap","./Camera","./CullFace","./DebugCameraPrimitive","./PerInstanceColorAppearance","./Primitive","./ShadowMapShader"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q){"use strict";function Z(e){e=h(e,h.EMPTY_OBJECT);var r=e.context;this._enabled=h(e.enabled,!0),this._softShadows=h(e.softShadows,!1),this._normalOffset=h(e.normalOffset,!0),this.dirty=!0,this.fromLightSource=h(e.fromLightSource,!0),this.darkness=h(e.darkness,.3),this._darkness=this.darkness,this.maximumDistance=h(e.maximumDistance,5e3),this._outOfView=!1,this._outOfViewPrevious=!1,this._needsUpdate=!0;var a=!0;(_.isInternetExplorer()||_.isEdge()||(_.isChrome()||_.isFirefox())&&_.isWindows()&&!r.depthTexture)&&(a=!1),this._polygonOffsetSupported=a,this._terrainBias={polygonOffset:a,polygonOffsetFactor:1.1,polygonOffsetUnits:4,normalOffset:this._normalOffset,normalOffsetScale:.5,normalShading:!0,normalShadingSmooth:.3,depthBias:1e-4},this._primitiveBias={polygonOffset:a,polygonOffsetFactor:1.1,polygonOffsetUnits:4,normalOffset:this._normalOffset,normalOffsetScale:.1,normalShading:!0,normalShadingSmooth:.05,depthBias:2e-5},this._pointBias={polygonOffset:!1,polygonOffsetFactor:1.1,polygonOffsetUnits:4,normalOffset:this._normalOffset,normalOffsetScale:0,normalShading:!0,normalShadingSmooth:.1,depthBias:5e-4},this._depthAttachment=void 0,this._colorAttachment=void 0,this._shadowMapMatrix=new C,this._shadowMapTexture=void 0,this._lightDirectionEC=new n,this._lightPositionEC=new o,this._distance=0,this._lightCamera=e.lightCamera,this._shadowMapCamera=new fe,this._shadowMapCullingVolume=void 0,this._sceneCamera=void 0,this._boundingSphere=new t,this._isPointLight=h(e.isPointLight,!1),this._pointLightRadius=h(e.pointLightRadius,100),this._cascadesEnabled=!this._isPointLight&&h(e.cascadesEnabled,!0),this._numberOfCascades=this._cascadesEnabled?h(e.numberOfCascades,4):0,this._fitNearFar=!0,this._maximumCascadeDistances=[25,150,700,Number.MAX_VALUE],this._textureSize=new i,this._isSpotLight=!1,this._cascadesEnabled?this._shadowMapCamera.frustum=new S:p(this._lightCamera.frustum.fov)&&(this._isSpotLight=!0),this._cascadeSplits=[new o,new o],this._cascadeMatrices=[new C,new C,new C,new C],this._cascadeDistances=new o;var s;s=this._isPointLight?6:this._cascadesEnabled?this._numberOfCascades:1,this._passes=new Array(s);for(var u=0;u<s;++u)this._passes[u]=new K(r);this.debugShow=!1,this.debugFreezeFrame=!1,this._debugFreezeFrame=!1,this._debugCascadeColors=!1,this._debugLightFrustum=void 0,this._debugCameraFrustum=void 0,this._debugCascadeFrustums=new Array(this._numberOfCascades),this._debugShadowViewCommand=void 0,this._usesDepthTexture=r.depthTexture,this._isPointLight&&(this._usesDepthTexture=!1),this._primitiveRenderState=void 0,this._terrainRenderState=void 0,this._pointRenderState=void 0,$(this),this._clearCommand=new P({depth:1,color:new l}),this._clearPassState=new L(r),this._size=h(e.size,2048),this.size=this._size}function K(e){this.camera=new fe,this.passState=new L(e),this.framebuffer=void 0,this.textureOffsets=void 0,this.commandList=[],this.cullingVolume=void 0}function J(e,t){return B.fromCache({cull:{enabled:!0,face:j.BACK},depthTest:{enabled:!0},colorMask:{red:e,green:e,blue:e,alpha:e},depthMask:!0,polygonOffset:{enabled:t.polygonOffset,factor:t.polygonOffsetFactor,units:t.polygonOffsetUnits}})}function $(e){var t=!e._usesDepthTexture;e._primitiveRenderState=J(t,e._primitiveBias),e._terrainRenderState=J(t,e._terrainBias),e._pointRenderState=J(t,e._pointBias)}function ee(e){for(var t=e._passes.length,r=0;r<t;++r){var i=e._passes[r],n=i.framebuffer;p(n)&&!n.isDestroyed()&&n.destroy(),i.framebuffer=void 0}e._depthAttachment=e._depthAttachment&&e._depthAttachment.destroy(),e._colorAttachment=e._colorAttachment&&e._colorAttachment.destroy()}function te(){return new U({wrapS:W.CLAMP_TO_EDGE,wrapT:W.CLAMP_TO_EDGE,minificationFilter:G.NEAREST,magnificationFilter:z.NEAREST})}function re(e,t){for(var r=new k({context:t,width:e._textureSize.x,height:e._textureSize.y,format:F.DEPTH_COMPONENT16}),i=new V({context:t,width:e._textureSize.x,height:e._textureSize.y,pixelFormat:T.RGBA,pixelDatatype:N.UNSIGNED_BYTE,sampler:te()}),n=new M({context:t,depthRenderbuffer:r,colorTextures:[i],destroyAttachments:!1}),o=e._passes.length,a=0;a<o;++a){var s=e._passes[a];s.framebuffer=n,s.passState.framebuffer=n}e._shadowMapTexture=i,e._depthAttachment=r,e._colorAttachment=i}function ie(e,t){for(var r=new V({context:t,width:e._textureSize.x,height:e._textureSize.y,pixelFormat:T.DEPTH_STENCIL,pixelDatatype:N.UNSIGNED_INT_24_8,sampler:te()}),i=new M({context:t,depthStencilTexture:r,destroyAttachments:!1}),n=e._passes.length,o=0;o<n;++o){var a=e._passes[o];a.framebuffer=i,a.passState.framebuffer=i}e._shadowMapTexture=r,e._depthAttachment=r}function ne(e,t){for(var r=new k({context:t,width:e._textureSize.x,height:e._textureSize.y,format:F.DEPTH_COMPONENT16}),i=new I({context:t,width:e._textureSize.x,height:e._textureSize.y,pixelFormat:T.RGBA,pixelDatatype:N.UNSIGNED_BYTE,sampler:te()}),n=[i.negativeX,i.negativeY,i.negativeZ,i.positiveX,i.positiveY,i.positiveZ],o=0;o<6;++o){var a=new M({context:t,depthRenderbuffer:r,colorTextures:[n[o]],destroyAttachments:!1}),s=e._passes[o];s.framebuffer=a,s.passState.framebuffer=a}e._shadowMapTexture=i,e._depthAttachment=r,e._colorAttachment=i}function oe(e,t){e._isPointLight?ne(e,t):e._usesDepthTexture?ie(e,t):re(e,t)}function ae(e,t){e._usesDepthTexture&&e._passes[0].framebuffer.status!==x.FRAMEBUFFER_COMPLETE&&(e._usesDepthTexture=!1,$(e),ee(e),oe(e,t))}function se(e,t){p(e._passes[0].framebuffer)&&e._shadowMapTexture.width===e._textureSize.x||(ee(e),oe(e,t),ae(e,t),le(e,t))}function le(e,t,r){r=h(r,0),(e._isPointLight||0===r)&&(e._clearCommand.framebuffer=e._passes[r].framebuffer,e._clearCommand.execute(t,e._clearPassState))}function ue(t,r){t._size=r;var i=t._passes,n=i.length,o=t._textureSize;if(t._isPointLight){r=D.maximumCubeMapSize>=r?r:D.maximumCubeMapSize,o.x=r,o.y=r;var a=new e(0,0,r,r);i[0].passState.viewport=a,i[1].passState.viewport=a,i[2].passState.viewport=a,i[3].passState.viewport=a,i[4].passState.viewport=a,i[5].passState.viewport=a}else 1===n?(r=D.maximumTextureSize>=r?r:D.maximumTextureSize,o.x=r,o.y=r,i[0].passState.viewport=new e(0,0,r,r)):4===n&&(r=D.maximumTextureSize>=2*r?r:D.maximumTextureSize/2,o.x=2*r,o.y=2*r,i[0].passState.viewport=new e(0,0,r,r),i[1].passState.viewport=new e(r,0,r,r),i[2].passState.viewport=new e(0,r,r,r),i[3].passState.viewport=new e(r,r,r,r));t._clearPassState.viewport=new e(0,0,o.x,o.y);for(var s=0;s<n;++s){var l=i[s],u=l.passState.viewport,c=u.x/o.x,d=u.y/o.y,h=u.width/o.x,p=u.height/o.y;l.textureOffsets=new C(h,0,0,c,0,p,0,d,0,0,1,0,0,0,0,1)}}function ce(e,t){var r;r=e._isPointLight?"uniform samplerCube shadowMap_textureCube; \nvarying vec2 v_textureCoordinates; \nvoid main() \n{ \n vec2 uv = v_textureCoordinates; \n vec3 dir; \n \n if (uv.y < 0.5) \n { \n if (uv.x < 0.333) \n { \n dir.x = -1.0; \n dir.y = uv.x * 6.0 - 1.0; \n dir.z = uv.y * 4.0 - 1.0; \n } \n else if (uv.x < 0.666) \n { \n dir.y = -1.0; \n dir.x = uv.x * 6.0 - 3.0; \n dir.z = uv.y * 4.0 - 1.0; \n } \n else \n { \n dir.z = -1.0; \n dir.x = uv.x * 6.0 - 5.0; \n dir.y = uv.y * 4.0 - 1.0; \n } \n } \n else \n { \n if (uv.x < 0.333) \n { \n dir.x = 1.0; \n dir.y = uv.x * 6.0 - 1.0; \n dir.z = uv.y * 4.0 - 3.0; \n } \n else if (uv.x < 0.666) \n { \n dir.y = 1.0; \n dir.x = uv.x * 6.0 - 3.0; \n dir.z = uv.y * 4.0 - 3.0; \n } \n else \n { \n dir.z = 1.0; \n dir.x = uv.x * 6.0 - 5.0; \n dir.y = uv.y * 4.0 - 3.0; \n } \n } \n \n float shadow = czm_unpackDepth(textureCube(shadowMap_textureCube, dir)); \n gl_FragColor = vec4(vec3(shadow), 1.0); \n} \n":"uniform sampler2D shadowMap_texture; \nvarying vec2 v_textureCoordinates; \nvoid main() \n{ \n"+(e._usesDepthTexture?" float shadow = texture2D(shadowMap_texture, v_textureCoordinates).r; \n":" float shadow = czm_unpackDepth(texture2D(shadowMap_texture, v_textureCoordinates)); \n")+" gl_FragColor = vec4(vec3(shadow), 1.0); \n} \n";var i=t.createViewportQuadCommand(r,{uniformMap:{shadowMap_texture:function(){return e._shadowMapTexture},shadowMap_textureCube:function(){return e._shadowMapTexture}}});return i.pass=R.OVERLAY,i}function de(t,r){var i=r.context,n=r.context.drawingBufferWidth,o=r.context.drawingBufferHeight,a=.3*Math.min(n,o),s=Se;s.x=n-a,s.y=0,s.width=a,s.height=a;var l=t._debugShadowViewCommand;p(l)||(l=ce(t,i),t._debugShadowViewCommand=l),p(l.renderState)&&e.equals(l.renderState.viewport,s)||(l.renderState=B.fromCache({viewport:e.clone(s)})),r.commandList.push(t._debugShadowViewCommand)}function he(e,t){var i=new v({geometry:new r({minimum:new n(-.5,-.5,-.5),maximum:new n(.5,.5,.5)}),attributes:{color:u.fromColor(t)}}),o=new v({geometry:new A({radius:.5}),attributes:{color:u.fromColor(t)}});return new X({geometryInstances:[i,o],appearance:new Y({translucent:!1,flat:!0}),asynchronous:!1,modelMatrix:e})}function pe(e,t){de(e,t);var r=e.debugFreezeFrame&&!e._debugFreezeFrame;if(e._debugFreezeFrame=e.debugFreezeFrame,e.debugFreezeFrame&&(r&&(e._debugCameraFrustum=e._debugCameraFrustum&&e._debugCameraFrustum.destroy(),e._debugCameraFrustum=new q({camera:e._sceneCamera,color:l.CYAN,updateOnChange:!1})),e._debugCameraFrustum.update(t)),e._cascadesEnabled){if(e.debugFreezeFrame){r&&(e._debugLightFrustum=e._debugLightFrustum&&e._debugLightFrustum.destroy(),e._debugLightFrustum=new q({camera:e._shadowMapCamera,color:l.YELLOW,updateOnChange:!1})),e._debugLightFrustum.update(t);for(var i=0;i<e._numberOfCascades;++i)r&&(e._debugCascadeFrustums[i]=e._debugCascadeFrustums[i]&&e._debugCascadeFrustums[i].destroy(),e._debugCascadeFrustums[i]=new q({camera:e._passes[i].camera,color:xe[i],updateOnChange:!1})),e._debugCascadeFrustums[i].update(t)}}else if(e._isPointLight){if(!p(e._debugLightFrustum)||e._needsUpdate){var o=e._shadowMapCamera.positionWC,a=E.IDENTITY,s=2*e._pointLightRadius,u=n.fromElements(s,s,s,Pe),c=C.fromTranslationQuaternionRotationScale(o,a,u,Te);e._debugLightFrustum=e._debugLightFrustum&&e._debugLightFrustum.destroy(),e._debugLightFrustum=he(c,l.YELLOW)}e._debugLightFrustum.update(t)}else p(e._debugLightFrustum)&&!e._needsUpdate||(e._debugLightFrustum=new q({camera:e._shadowMapCamera,color:l.YELLOW,updateOnChange:!1})),e._debugLightFrustum.update(t)}function fe(){this.viewMatrix=new C,this.inverseViewMatrix=new C,this.frustum=void 0,this.positionCartographic=new a,this.positionWC=new n,this.directionWC=n.clone(n.UNIT_Z),this.upWC=n.clone(n.UNIT_Y),this.rightWC=n.clone(n.UNIT_X),this.viewProjectionMatrix=new C}function me(e,t){var r,i=e._shadowMapCamera,a=e._sceneCamera,s=a.frustum.near,l=a.frustum.far,u=e._numberOfCascades,c=l-s,d=l/s,h=.9,p=!1;t.shadowHints.closestObjectSize<200&&(p=!0,h=.9);var f=Me,m=Ie;for(m[0]=s,m[u]=l,r=0;r<u;++r){var g=(r+1)/u,_=s*Math.pow(d,g),v=s+c*g,y=b.lerp(v,_,h);m[r+1]=y,f[r]=y-m[r]}if(p){for(r=0;r<u;++r)f[r]=Math.min(f[r],e._maximumCascadeDistances[r]);var S=m[0];for(r=0;r<u-1;++r)S+=f[r],m[r+1]=S}o.unpack(m,0,e._cascadeSplits[0]),o.unpack(m,1,e._cascadeSplits[1]),o.unpack(f,0,e._cascadeDistances);var w=i.frustum,T=w.left,E=w.right,A=w.bottom,x=w.top,P=w.near,D=w.far,I=i.positionWC,O=i.directionWC,M=i.upWC,R=a.frustum.clone(Oe),L=i.getViewProjection();for(r=0;r<u;++r){R.near=m[r],R.far=m[r+1];for(var N=C.multiply(R.projectionMatrix,a.viewMatrix,Te),k=C.inverse(N,Te),F=C.multiply(L,k,Te),B=n.fromElements(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE,Re),U=n.fromElements(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE,Le),V=0;V<8;++V){var z=o.clone(we[V],Ee[V]);C.multiplyByVector(F,z,z),n.divideByScalar(z,z.w,z),n.minimumByComponent(z,B,B),n.maximumByComponent(z,U,U)}B.x=Math.max(B.x,0),B.y=Math.max(B.y,0),B.z=0,U.x=Math.min(U.x,1),U.y=Math.min(U.y,1),U.z=Math.min(U.z,1);var G=e._passes[r],W=G.camera;W.clone(i);var H=W.frustum;H.left=T+B.x*(E-T),H.right=T+U.x*(E-T),H.bottom=A+B.y*(x-A),H.top=A+U.y*(x-A),H.near=P+B.z*(D-P),H.far=P+U.z*(D-P),G.cullingVolume=W.frustum.computeCullingVolume(I,O,M);var j=e._cascadeMatrices[r];C.multiply(W.getViewProjection(),a.inverseViewMatrix,j),C.multiply(G.textureOffsets,j,j)}}function ge(e,t){var r=e._shadowMapCamera,i=e._sceneCamera,a=C.multiply(i.frustum.projectionMatrix,i.viewMatrix,Te),s=C.inverse(a,Te),l=r.directionWC,u=i.directionWC,c=n.cross(l,u,ke);u=n.cross(c,l,Fe),n.normalize(u,u),n.normalize(c,c);for(var d=n.fromElements(0,0,0,Be),h=C.computeView(d,l,u,c,Ne),p=C.multiply(h,s,Te),f=n.fromElements(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE,Re),m=n.fromElements(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE,Le),g=0;g<8;++g){var _=o.clone(we[g],Ee[g]);C.multiplyByVector(p,_,_),n.divideByScalar(_,_.w,_),n.minimumByComponent(_,f,f),n.maximumByComponent(_,m,m)}m.z+=1e3,f.z-=10;var v=Be;v.x=-.5*(f.x+m.x),v.y=-.5*(f.y+m.y),v.z=-m.z;var y=C.fromTranslation(v,Te);h=C.multiply(y,h,h);var b=.5*(m.x-f.x),S=.5*(m.y-f.y),w=m.z-f.z,T=r.frustum;T.left=-b,T.right=b,T.bottom=-S,T.top=S,T.near=.01,T.far=w,C.clone(h,r.viewMatrix),C.inverse(h,r.inverseViewMatrix),C.getTranslation(r.inverseViewMatrix,r.positionWC),t.mapProjection.ellipsoid.cartesianToCartographic(r.positionWC,r.positionCartographic),n.clone(l,r.directionWC),n.clone(u,r.upWC),n.clone(c,r.rightWC)}function _e(e,t){var r=new w;r.fov=b.PI_OVER_TWO,r.near=1,r.far=e._pointLightRadius,r.aspectRatio=1;for(var i=0;i<6;++i){var n=e._passes[i].camera;n.positionWC=e._shadowMapCamera.positionWC,n.positionCartographic=t.mapProjection.ellipsoid.cartesianToCartographic(n.positionWC,n.positionCartographic),n.directionWC=Ue[i],n.upWC=Ve[i],n.rightWC=ze[i],C.computeView(n.positionWC,n.directionWC,n.upWC,n.rightWC,n.viewMatrix),C.inverse(n.viewMatrix,n.inverseViewMatrix),n.frustum=r}}function ve(e,r){var i=e._sceneCamera,o=e._shadowMapCamera,a=He;if(e._cascadesEnabled){if(i.frustum.near>=e.maximumDistance)return e._outOfView=!0,void(e._needsUpdate=!1);var s=r.mapProjection.ellipsoid.geodeticSurfaceNormal(i.positionWC,Ge),l=n.negate(o.directionWC,We),u=n.dot(s,l),c=b.clamp(u/.1,0,1);if(e._darkness=b.lerp(1,e.darkness,c),u<0)return e._outOfView=!0,void(e._needsUpdate=!1);e._needsUpdate=!0,e._outOfView=!1}else if(e._isPointLight)a.center=o.positionWC,a.radius=e._pointLightRadius,e._outOfView=r.cullingVolume.computeVisibility(a)===y.OUTSIDE,e._needsUpdate=!e._outOfView&&!e._boundingSphere.equals(a),t.clone(a,e._boundingSphere);else{var d=o.frustum.far/2,h=n.add(o.positionWC,n.multiplyByScalar(o.directionWC,d,je),je);a.center=h,a.radius=d,e._outOfView=r.cullingVolume.computeVisibility(a)===y.OUTSIDE,e._needsUpdate=!e._outOfView&&!e._boundingSphere.equals(a),t.clone(a,e._boundingSphere)}}function ye(e,t){var r=t.camera,i=e._lightCamera,o=e._sceneCamera,a=e._shadowMapCamera;e._cascadesEnabled?n.clone(i.directionWC,a.directionWC):e._isPointLight?n.clone(i.positionWC,a.positionWC):a.clone(i);var s=e._lightDirectionEC;C.multiplyByPointAsVector(r.viewMatrix,a.directionWC,s),n.normalize(s,s),n.negate(s,s),C.multiplyByPoint(r.viewMatrix,a.positionWC,e._lightPositionEC),e._lightPositionEC.w=e._pointLightRadius;var l,u;e._fitNearFar?(l=Math.min(t.shadowHints.nearPlane,e.maximumDistance),u=Math.min(t.shadowHints.farPlane,e.maximumDistance+1)):(l=r.frustum.near,u=e.maximumDistance),e._sceneCamera=H.clone(r,o),r.frustum.clone(e._sceneCamera.frustum),e._sceneCamera.frustum.near=l,e._sceneCamera.frustum.far=u,e._distance=u-l,ve(e,t),!e._outOfViewPrevious&&e._outOfView&&(e._needsUpdate=!0),e._outOfViewPrevious=e._outOfView}function be(e,t,r){var i=e._isPointLight?e._pointBias:r?e._terrainBias:e._primitiveBias,n={shadowMap_texture:function(){return e._shadowMapTexture},shadowMap_textureCube:function(){return e._shadowMapTexture},shadowMap_matrix:function(){return e._shadowMapMatrix},shadowMap_cascadeSplits:function(){return e._cascadeSplits},shadowMap_cascadeMatrices:function(){return e._cascadeMatrices},shadowMap_lightDirectionEC:function(){return e._lightDirectionEC},shadowMap_lightPositionEC:function(){return e._lightPositionEC},shadowMap_cascadeDistances:function(){return e._cascadeDistances},shadowMap_texelSizeDepthBiasAndNormalShadingSmooth:function(){var t=qe;return t.x=1/e._textureSize.x,t.y=1/e._textureSize.y,o.fromElements(t.x,t.y,i.depthBias,i.normalShadingSmooth,this.combinedUniforms1)},shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness:function(){return o.fromElements(i.normalOffsetScale,e._distance,e.maximumDistance,e._darkness,this.combinedUniforms2)},combinedUniforms1:new o,combinedUniforms2:new o};return c(t,n,!1)}function Ce(e,t,r,i,n,o){var a,l,u;if(p(o)&&(a=o.shaderProgram,l=o.renderState,u=o.uniformMap),o=O.shallowClone(r,o),o.castShadows=!0,o.receiveShadows=!1,!p(a)||n!==r.shaderProgram.id||t){var c=r.shaderProgram,d=r.pass===R.GLOBE,h=r.pass!==R.TRANSLUCENT,f=e._isPointLight,m=e._usesDepthTexture,g=Q.getShadowCastShaderKeyword(f,d,m,h);if(a=i.shaderCache.getDerivedShaderProgram(c,g),!p(a)){var _=c.vertexShaderSource,v=c.fragmentShaderSource,y=Q.createShadowCastVertexShader(_,f,d),b=Q.createShadowCastFragmentShader(v,f,m,h);a=i.shaderCache.createDerivedShaderProgram(c,g,{vertexShaderSource:y,fragmentShaderSource:b,attributeLocations:c._attributeLocations})}l=e._primitiveRenderState,f?l=e._pointRenderState:d&&(l=e._terrainRenderState);r.renderState.cull.enabled||(l=s(l,!1),l.cull=s(l.cull,!1),l.cull.enabled=!1,l=B.fromCache(l)),u=be(e,r.uniformMap,d)}return o.shaderProgram=a,o.renderState=l,o.uniformMap=u,o}Z.MAXIMUM_DISTANCE=2e4,Z.prototype.debugCreateRenderStates=function(){$(this)},f(Z.prototype,{enabled:{get:function(){return this._enabled},set:function(e){this.dirty=this._enabled!==e,this._enabled=e}},normalOffset:{get:function(){return this._normalOffset},set:function(e){this.dirty=this._normalOffset!==e,this._normalOffset=e,this._terrainBias.normalOffset=e,this._primitiveBias.normalOffset=e,this._pointBias.normalOffset=e}},softShadows:{get:function(){return this._softShadows},set:function(e){this.dirty=this._softShadows!==e,this._softShadows=e}},size:{get:function(){return this._size},set:function(e){ue(this,e)}},outOfView:{get:function(){return this._outOfView}},shadowMapCullingVolume:{get:function(){return this._shadowMapCullingVolume}},passes:{get:function(){return this._passes}},isPointLight:{get:function(){return this._isPointLight}},debugCascadeColors:{get:function(){return this._debugCascadeColors},set:function(e){this.dirty=this._debugCascadeColors!==e,this._debugCascadeColors=e}}});var Se=new e,we=new Array(8);we[0]=new o(-1,-1,-1,1),we[1]=new o(1,-1,-1,1),we[2]=new o(1,1,-1,1),we[3]=new o(-1,1,-1,1),we[4]=new o(-1,-1,1,1),we[5]=new o(1,-1,1,1),we[6]=new o(1,1,1,1),we[7]=new o(-1,1,1,1);for(var Te=new C,Ee=new Array(8),Ae=0;Ae<8;++Ae)Ee[Ae]=new o;var xe=[l.RED,l.GREEN,l.BLUE,l.MAGENTA],Pe=new n;fe.prototype.clone=function(e){C.clone(e.viewMatrix,this.viewMatrix),C.clone(e.inverseViewMatrix,this.inverseViewMatrix),this.frustum=e.frustum.clone(this.frustum),a.clone(e.positionCartographic,this.positionCartographic),n.clone(e.positionWC,this.positionWC),n.clone(e.directionWC,this.directionWC),n.clone(e.upWC,this.upWC),n.clone(e.rightWC,this.rightWC)};var De=new C(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);fe.prototype.getViewProjection=function(){var e=this.viewMatrix,t=this.frustum.projectionMatrix;return C.multiply(t,e,this.viewProjectionMatrix),C.multiply(De,this.viewProjectionMatrix,this.viewProjectionMatrix),this.viewProjectionMatrix};var Ie=new Array(5),Oe=new w,Me=new Array(4),Re=new n,Le=new n,Ne=new C,ke=new n,Fe=new n,Be=new n,Ue=[new n(-1,0,0),new n(0,-1,0),new n(0,0,-1),new n(1,0,0),new n(0,1,0),new n(0,0,1)],Ve=[new n(0,-1,0),new n(0,0,-1),new n(0,-1,0),new n(0,-1,0),new n(0,0,1),new n(0,-1,0)],ze=[new n(0,0,1),new n(1,0,0),new n(-1,0,0),new n(0,0,-1),new n(1,0,0),new n(1,0,0)],Ge=new n,We=new n,He=new t,je=He.center;Z.prototype.update=function(e){if(ye(this,e),this._needsUpdate)if(se(this,e.context),this._isPointLight&&_e(this,e),this._cascadesEnabled&&(ge(this,e),this._numberOfCascades>1&&me(this,e)),this._isPointLight)this._shadowMapCullingVolume=d.fromBoundingSphere(this._boundingSphere);else{var t=this._shadowMapCamera,r=t.positionWC,i=t.directionWC,n=t.upWC;this._shadowMapCullingVolume=t.frustum.computeCullingVolume(r,i,n),1===this._passes.length&&this._passes[0].camera.clone(t)}if(1===this._passes.length){var o=this._sceneCamera.inverseViewMatrix;C.multiply(this._shadowMapCamera.getViewProjection(),o,this._shadowMapMatrix)}this.debugShow&&pe(this,e)},Z.prototype.updatePass=function(e,t){le(this,e,t)};var qe=new i;return Z.createDerivedCommands=function(e,t,r,i,n,o){p(o)||(o={});var a=t.length>0,s=r.shaderProgram,l=s.vertexShaderSource,u=s.fragmentShaderSource,c=r.pass===R.GLOBE,d=!1;if(c&&(d=r.owner.data.pickTerrain.mesh.encoding.hasVertexNormals),r.castShadows){var h=o.castCommands;p(h)||(h=o.castCommands=[]);var f=o.castShaderProgramId,m=e.length;h.length=m;for(var g=0;g<m;++g)h[g]=Ce(e[g],i,r,n,f,h[g]);o.castShaderProgramId=r.shaderProgram.id}if(r.receiveShadows&&a){var _,v;p(o.receiveCommand)&&(_=o.receiveCommand.shaderProgram,v=o.receiveCommand.uniformMap),o.receiveCommand=O.shallowClone(r,o.receiveCommand),o.castShadows=!1,o.receiveShadows=!0;var y=o.receiveShaderCastShadows!==r.castShadows,b=o.receiveShaderProgramId!==r.shaderProgram.id;if(!p(_)||b||i||y){var C=Q.getShadowReceiveShaderKeyword(t[0],r.castShadows,c,d);if(_=n.shaderCache.getDerivedShaderProgram(s,C),!p(_)){var S=Q.createShadowReceiveVertexShader(l,c,d),w=Q.createShadowReceiveFragmentShader(u,t[0],r.castShadows,c,d);_=n.shaderCache.createDerivedShaderProgram(s,C,{vertexShaderSource:S,fragmentShaderSource:w,attributeLocations:s._attributeLocations})}v=be(t[0],r.uniformMap,c)}o.receiveCommand.shaderProgram=_,o.receiveCommand.uniformMap=v,o.receiveShaderProgramId=r.shaderProgram.id,o.receiveShaderCastShadows=r.castShadows}return o},Z.prototype.isDestroyed=function(){return!1},Z.prototype.destroy=function(){ee(this),this._debugLightFrustum=this._debugLightFrustum&&this._debugLightFrustum.destroy(),this._debugCameraFrustum=this._debugCameraFrustum&&this._debugCameraFrustum.destroy(),this._debugShadowViewCommand=this._debugShadowViewCommand&&this._debugShadowViewCommand.shaderProgram&&this._debugShadowViewCommand.shaderProgram.destroy();for(var e=0;e<this._numberOfCascades;++e)this._debugCascadeFrustums[e]=this._debugCascadeFrustums[e]&&this._debugCascadeFrustums[e].destroy();return m(this)},Z}),define("Shaders/PostProcessFilters/AdditiveBlend",[],function(){"use strict";return"uniform sampler2D u_texture0;\nuniform sampler2D u_texture1;\nuniform vec2 u_center;\nuniform float u_radius;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec4 color0 = texture2D(u_texture0, v_textureCoordinates);\nvec4 color1 = texture2D(u_texture1, v_textureCoordinates);\nfloat x = length(gl_FragCoord.xy - u_center) / u_radius;\nfloat t = smoothstep(0.5, 0.8, x);\ngl_FragColor = mix(color0 + color1, color0, t);\n}\n"}),define("Shaders/PostProcessFilters/BrightPass",[],function(){"use strict" +;return"uniform sampler2D u_texture;\nuniform float u_avgLuminance;\nuniform float u_threshold;\nuniform float u_offset;\nvarying vec2 v_textureCoordinates;\nfloat key(float avg)\n{\nfloat guess = 1.5 - (1.5 / (avg * 0.1 + 1.0));\nreturn max(0.0, guess) + 0.1;\n}\nvoid main()\n{\nvec4 color = texture2D(u_texture, v_textureCoordinates);\nvec3 xyz = czm_RGBToXYZ(color.rgb);\nfloat luminance = xyz.r;\nfloat scaledLum = key(u_avgLuminance) * luminance / u_avgLuminance;\nfloat brightLum = max(scaledLum - u_threshold, 0.0);\nfloat brightness = brightLum / (u_offset + brightLum);\nxyz.r = brightness;\ngl_FragColor = vec4(czm_XYZToRGB(xyz), 1.0);\n}\n"}),define("Shaders/PostProcessFilters/GaussianBlur1D",[],function(){"use strict";return"#define SAMPLES 8\nuniform float delta;\nuniform float sigma;\nuniform float direction;\nuniform sampler2D u_texture;\nuniform vec2 u_step;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec2 st = v_textureCoordinates;\nvec2 dir = vec2(1.0 - direction, direction);\nvec3 g;\ng.x = 1.0 / (sqrt(czm_twoPi) * sigma);\ng.y = exp((-0.5 * delta * delta) / (sigma * sigma));\ng.z = g.y * g.y;\nvec4 result = texture2D(u_texture, st) * g.x;\nfor (int i = 1; i < SAMPLES; ++i)\n{\ng.xy *= g.yz;\nvec2 offset = float(i) * dir * u_step;\nresult += texture2D(u_texture, st - offset) * g.x;\nresult += texture2D(u_texture, st + offset) * g.x;\n}\ngl_FragColor = result;\n}\n"}),define("Scene/SunPostProcess",["../Core/BoundingRectangle","../Core/Cartesian2","../Core/Cartesian4","../Core/Color","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/Math","../Core/Matrix4","../Core/PixelFormat","../Core/Transforms","../Renderer/ClearCommand","../Renderer/Framebuffer","../Renderer/PassState","../Renderer/PixelDatatype","../Renderer/Renderbuffer","../Renderer/RenderbufferFormat","../Renderer/RenderState","../Renderer/Texture","../Shaders/PostProcessFilters/AdditiveBlend","../Shaders/PostProcessFilters/BrightPass","../Shaders/PostProcessFilters/GaussianBlur1D","../Shaders/PostProcessFilters/PassThrough"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S){"use strict";function w(){this._fbo=void 0,this._downSampleFBO1=void 0,this._downSampleFBO2=void 0,this._clearFBO1Command=void 0,this._clearFBO2Command=void 0,this._downSampleCommand=void 0,this._brightPassCommand=void 0,this._blurXCommand=void 0,this._blurYCommand=void 0,this._blendCommand=void 0,this._fullScreenCommand=void 0,this._downSamplePassState=new p,this._downSamplePassState.scissorTest={enable:!0,rectangle:new e},this._upSamplePassState=new p,this._upSamplePassState.scissorTest={enabled:!0,rectangle:new e},this._uCenter=new t,this._uRadius=void 0,this._blurStep=new t}w.prototype.clear=function(e,t){var r=this._clearFBO1Command;i.clone(n(t,i.BLACK),r.color),r.execute(e),r=this._clearFBO2Command,i.clone(n(t,i.BLACK),r.color),r.execute(e)},w.prototype.execute=function(e,t){this._downSampleCommand.execute(e,this._downSamplePassState),this._brightPassCommand.execute(e,this._downSamplePassState),this._blurXCommand.execute(e,this._downSamplePassState),this._blurYCommand.execute(e,this._downSamplePassState),this._fullScreenCommand.framebuffer=t,this._blendCommand.framebuffer=t,this._fullScreenCommand.execute(e),this._blendCommand.execute(e,this._upSamplePassState)};var T=new e,E=new e,A=new r,x=new t,P=new t,D=new l;return w.prototype.update=function(e){var r=e.context,n=e.viewport,a=r.drawingBufferWidth,p=r.drawingBufferHeight,w=this;if(!o(this._downSampleCommand)){this._clearFBO1Command=new d({color:new i}),this._clearFBO2Command=new d({color:new i});var I={};this._downSampleCommand=r.createViewportQuadCommand(S,{uniformMap:I,owner:this}),I={u_avgLuminance:function(){return.5},u_threshold:function(){return.25},u_offset:function(){return.1}},this._brightPassCommand=r.createViewportQuadCommand(b,{uniformMap:I,owner:this});I={delta:function(){return 1},sigma:function(){return 2},direction:function(){return 0}},this._blurXCommand=r.createViewportQuadCommand(C,{uniformMap:I,owner:this}),I={delta:function(){return 1},sigma:function(){return 2},direction:function(){return 1}},this._blurYCommand=r.createViewportQuadCommand(C,{uniformMap:I,owner:this}),I={u_center:function(){return w._uCenter},u_radius:function(){return w._uRadius}},this._blendCommand=r.createViewportQuadCommand(y,{uniformMap:I,owner:this}),I={},this._fullScreenCommand=r.createViewportQuadCommand(S,{uniformMap:I,owner:this})}var O=Math.pow(2,Math.ceil(Math.log(a)/Math.log(2))-2),M=Math.pow(2,Math.ceil(Math.log(p)/Math.log(2))-2),R=Math.max(1,O,M),L=E;L.width=R,L.height=R;var N=this._fbo,k=o(N)&&N.getColorTexture(0)||void 0;if(!o(k)||k.width!==a||k.height!==p){N=N&&N.destroy(),this._downSampleFBO1=this._downSampleFBO1&&this._downSampleFBO1.destroy(),this._downSampleFBO2=this._downSampleFBO2&&this._downSampleFBO2.destroy(),this._blurStep.x=this._blurStep.y=1/R;var F=[new v({context:r,width:a,height:p})];N=r.depthTexture?this._fbo=new h({context:r,colorTextures:F,depthTexture:new v({context:r,width:a,height:p,pixelFormat:u.DEPTH_COMPONENT,pixelDatatype:f.UNSIGNED_SHORT})}):this._fbo=new h({context:r,colorTextures:F,depthRenderbuffer:new m({context:r,format:g.DEPTH_COMPONENT16})}),this._downSampleFBO1=new h({context:r,colorTextures:[new v({context:r,width:R,height:R})]}),this._downSampleFBO2=new h({context:r,colorTextures:[new v({context:r,width:R,height:R})]}),this._clearFBO1Command.framebuffer=this._downSampleFBO1,this._clearFBO2Command.framebuffer=this._downSampleFBO2,this._downSampleCommand.framebuffer=this._downSampleFBO1,this._brightPassCommand.framebuffer=this._downSampleFBO2,this._blurXCommand.framebuffer=this._downSampleFBO1,this._blurYCommand.framebuffer=this._downSampleFBO2;var B=_.fromCache({viewport:L});this._downSampleCommand.uniformMap.u_texture=function(){return N.getColorTexture(0)},this._downSampleCommand.renderState=B,this._brightPassCommand.uniformMap.u_texture=function(){return w._downSampleFBO1.getColorTexture(0)},this._brightPassCommand.renderState=B,this._blurXCommand.uniformMap.u_texture=function(){return w._downSampleFBO2.getColorTexture(0)},this._blurXCommand.uniformMap.u_step=function(){return w._blurStep},this._blurXCommand.renderState=B,this._blurYCommand.uniformMap.u_texture=function(){return w._downSampleFBO1.getColorTexture(0)},this._blurYCommand.uniformMap.u_step=function(){return w._blurStep},this._blurYCommand.renderState=B;var U=T;U.width=a,U.height=p;var V=_.fromCache({viewport:U});this._blendCommand.uniformMap.u_texture0=function(){return N.getColorTexture(0)},this._blendCommand.uniformMap.u_texture1=function(){return w._downSampleFBO2.getColorTexture(0)},this._blendCommand.renderState=V,this._fullScreenCommand.uniformMap.u_texture=function(){return N.getColorTexture(0)},this._fullScreenCommand.renderState=V}var z=r.uniformState,G=z.sunPositionWC,W=z.view,H=z.viewProjection,j=z.projection,q=l.computeViewportTransformation(n,0,1,D),Y=l.multiplyByPoint(W,G,A),X=c.pointToGLWindowCoordinates(H,q,G,x);Y.x+=s.SOLAR_RADIUS;var Q=c.pointToGLWindowCoordinates(j,q,Y,Y),Z=30*t.magnitude(t.subtract(Q,X,Q))*2,K=P;K.x=Z,K.y=Z;var J=this._upSamplePassState.scissorTest.rectangle;return J.x=Math.max(X.x-.5*K.x,0),J.y=Math.max(X.y-.5*K.y,0),J.width=Math.min(K.x,a),J.height=Math.min(K.y,p),this._uCenter=t.clone(X,this._uCenter),this._uRadius=.15*Math.max(K.x,K.y),q=l.computeViewportTransformation(L,0,1,D),X=c.pointToGLWindowCoordinates(H,q,G,x),K.x*=O/a,K.y*=M/p,J=this._downSamplePassState.scissorTest.rectangle,J.x=Math.max(X.x-.5*K.x,0),J.y=Math.max(X.y-.5*K.y,0),J.width=Math.min(K.x,a),J.height=Math.min(K.y,p),this._downSamplePassState.context=r,this._upSamplePassState.context=r,this._fbo},w.prototype.isDestroyed=function(){return!1},w.prototype.destroy=function(){return this._fbo=this._fbo&&this._fbo.destroy(),this._downSampleFBO1=this._downSampleFBO1&&this._downSampleFBO1.destroy(),this._downSampleFBO2=this._downSampleFBO2&&this._downSampleFBO2.destroy(),this._downSampleCommand=this._downSampleCommand&&this._downSampleCommand.shaderProgram&&this._downSampleCommand.shaderProgram.destroy(),this._brightPassCommand=this._brightPassCommand&&this._brightPassCommand.shaderProgram&&this._brightPassCommand.shaderProgram.destroy(),this._blurXCommand=this._blurXCommand&&this._blurXCommand.shaderProgram&&this._blurXCommand.shaderProgram.destroy(),this._blurYCommand=this._blurYCommand&&this._blurYCommand.shaderProgram&&this._blurYCommand.shaderProgram.destroy(),this._blendCommand=this._blendCommand&&this._blendCommand.shaderProgram&&this._blendCommand.shaderProgram.destroy(),this._fullScreenCommand=this._fullScreenCommand&&this._fullScreenCommand.shaderProgram&&this._fullScreenCommand.shaderProgram.destroy(),a(this)},w}),define("Scene/Scene",["../Core/BoundingRectangle","../Core/BoundingSphere","../Core/BoxGeometry","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/Cartographic","../Core/Color","../Core/ColorGeometryInstanceAttribute","../Core/createGuid","../Core/CullingVolume","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/DeveloperError","../Core/EllipsoidGeometry","../Core/Event","../Core/GeographicProjection","../Core/GeometryInstance","../Core/GeometryPipeline","../Core/getTimestamp","../Core/Intersect","../Core/Interval","../Core/JulianDate","../Core/Math","../Core/Matrix4","../Core/mergeSort","../Core/Occluder","../Core/OrthographicFrustum","../Core/OrthographicOffCenterFrustum","../Core/PerspectiveFrustum","../Core/PerspectiveOffCenterFrustum","../Core/PixelFormat","../Core/RequestScheduler","../Core/ShowGeometryInstanceAttribute","../Core/TaskProcessor","../Core/Transforms","../Renderer/ClearCommand","../Renderer/ComputeEngine","../Renderer/Context","../Renderer/ContextLimits","../Renderer/DrawCommand","../Renderer/Framebuffer","../Renderer/Pass","../Renderer/PassState","../Renderer/PixelDatatype","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/Texture","./BrdfLutGenerator","./Camera","./CreditDisplay","./DebugCameraPrimitive","./DepthPlane","./DeviceOrientationCameraController","./Fog","./FrameState","./FrustumCommands","./FXAA","./GlobeDepth","./InvertClassification","./JobScheduler","./MapMode2D","./OIT","./PerformanceDisplay","./PerInstanceColorAppearance","./PickDepth","./Primitive","./PrimitiveCollection","./SceneMode","./SceneTransforms","./SceneTransitioner","./ScreenSpaceCameraController","./ShadowMap","./SunPostProcess","./TweenCollection"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,be,Ce,Se,we){"use strict";function Te(t){t=d(t,d.EMPTY_OBJECT);var r=t.canvas,i=t.contextOptions,n=t.creditContainer,o=t.creditViewport,a=h(n),l=new V(r,i);a||(n=document.createElement("div"),n.style.position="absolute",n.style.bottom="0",n.style["text-shadow"]="0 0 2px #000000",n.style.color="#ffffff",n.style["font-size"]="10px",n.style["padding-right"]="5px",r.parentNode.appendChild(n)),h(o)||(o=r.parentNode),this._id=u(),this._jobScheduler=new ue,this._frameState=new ne(l,new $(n," • ",o),this._jobScheduler),this._frameState.scene3DOnly=d(t.scene3DOnly,!1),this._removeCreditContainer=!a,this._creditContainer=n;var c=new j(l);c.viewport=new e,c.viewport.x=0,c.viewport.y=0,c.viewport.width=l.drawingBufferWidth,c.viewport.height=l.drawingBufferHeight,this._passState=c,this._canvas=r,this._context=l,this._computeEngine=new U(l),this._globe=void 0,this._primitives=new ge,this._groundPrimitives=new ge,this._tweens=new we,this._shaderFrameCount=0,this._sunPostProcess=void 0,this._computeCommandList=[],this._frustumCommandsList=[],this._overlayCommandList=[],this._pickFramebuffer=void 0,this._useOIT=d(t.orderIndependentTranslucency,!0),this._executeOITFunction=void 0;var p;l.depthTexture&&(p=new se);var f;this._useOIT&&h(p)&&(f=new de(l)),this._globeDepth=p,this._depthPlane=new te,this._oit=f,this._fxaa=new ae,this._clearColorCommand=new B({color:new s,stencil:0,owner:this}),this._depthClearCommand=new B({depth:1,owner:this}),this._stencilClearCommand=new B({stencil:0}),this._pickDepths=[],this._debugGlobeDepths=[],this._pickDepthPassState=void 0,this._pickDepthFramebuffer=void 0,this._pickDepthFramebufferWidth=void 0,this._pickDepthFramebufferHeight=void 0,this._depthOnlyRenderStateCache={},this._transitioner=new ye(this),this._preUpdate=new _,this._postUpdate=new _,this._renderError=new _,this._preRender=new _,this._postRender=new _,this._cameraStartFired=!1,this._cameraMovedTime=void 0,this._pickPositionCache={},this._pickPositionCacheDirty=!1,this._minimumDisableDepthTestDistance=0,this.rethrowRenderErrors=!1,this.completeMorphOnUserInput=!0,this.morphStart=new _,this.morphComplete=new _,this.skyBox=void 0,this.skyAtmosphere=void 0,this.sun=void 0,this.sunBloom=!0,this._sunBloom=void 0,this.moon=void 0,this.backgroundColor=s.clone(s.BLACK),this._mode=_e.SCENE3D,this._mapProjection=h(t.mapProjection)?t.mapProjection:new v,this.morphTime=1,this.farToNearRatio=1e3,this.nearToFarDistance2D=175e4,this.debugCommandFilter=void 0,this.debugShowCommands=!1,this.debugShowFrustums=!1,this._debugFrustumStatistics=void 0,this.debugShowFramesPerSecond=!1,this.debugShowGlobeDepth=!1,this.debugShowDepthFrustum=1,this.debugShowFrustumPlanes=!1,this._debugShowFrustumPlanes=!1,this._debugFrustumPlanes=void 0,this.fxaa=!0,this.useDepthPicking=!0,this.pickTranslucentDepth=!1,this.cameraEventWaitTime=500,this.copyGlobeDepth=!1,this.fog=new ie,this._sunCamera=new J(this),this.shadowMap=new Ce({context:l,lightCamera:this._sunCamera,enabled:d(t.shadows,!1)}),this.invertClassification=!1,this.invertClassificationColor=s.clone(s.WHITE),this._actualInvertClassificationColor=s.clone(this._invertClassificationColor),this._invertClassification=new le,this.focalLength=void 0,this.eyeSeparation=void 0,this._brdfLutGenerator=new K,this._terrainExaggeration=d(t.terrainExaggeration,1),this._performanceDisplay=void 0,this._debugVolume=void 0;var m=new J(this);this._camera=m,this._cameraClone=J.clone(m),this._screenSpaceCameraController=new be(this),this._mapMode2D=d(t.mapMode2D,ce.INFINITE_SCROLL),this._environmentState={skyBoxCommand:void 0,skyAtmosphereCommand:void 0,sunDrawCommand:void 0,sunComputeCommand:void 0,moonCommand:void 0,isSunVisible:!1,isMoonVisible:!1,isReadyForAtmosphere:!1,isSkyAtmosphereVisible:!1,clearGlobeDepth:!1,useDepthPlane:!1,originalFramebuffer:void 0,useGlobeDepthFramebuffer:!1,useOIT:!1,useFXAA:!1,useInvertClassification:!1},this._useWebVR=!1,this._cameraVR=void 0,this._aspectRatioVR=void 0,this.requestRenderMode=d(t.requestRenderMode,!1),this._renderRequested=!0,this.maximumRenderTimeChange=d(t.maximumRenderTimeChange,0),this._lastRenderTime=void 0,this._removeRequestListenerCallback=L.requestCompletedEvent.addEventListener(_t(this)),this._removeTaskProcessorListenerCallback=k.taskCompletedEvent.addEventListener(_t(this)),this._removeGlobeCallbacks=[];var g=m.frustum.near,y=m.frustum.far,b=Math.ceil(Math.log(y/g)/Math.log(this.farToNearRatio));Me(g,y,this.farToNearRatio,b,this._frustumCommandsList,!1,void 0),Oe(this,0,T.now()),this.initializeFrame()}function Ee(e,t){for(var r=0;r<e._removeGlobeCallbacks.length;++r)e._removeGlobeCallbacks[r]();e._removeGlobeCallbacks.length=0;var i=[];h(t)&&(i.push(t.tileLoadedEvent.addEventListener(_t(e))),i.push(t.imageryLayersUpdatedEvent.addEventListener(_t(e)))),e._removeGlobeCallbacks=i}function Ae(e,t){var r=Math.max(Math.abs(e.x),Math.abs(t.x)),i=Math.max(Math.abs(e.y),Math.abs(t.y)),n=Math.max(Math.abs(e.z),Math.abs(t.z));return Math.max(Math.max(r,i),n)}function xe(e,t,r){var i=1/Math.max(1,Ae(e.position,t.position));return n.multiplyByScalar(e.position,i,bt),n.multiplyByScalar(t.position,i,Ct),n.equalsEpsilon(bt,Ct,r)&&n.equalsEpsilon(e.direction,t.direction,r)&&n.equalsEpsilon(e.up,t.up,r)&&n.equalsEpsilon(e.right,t.right,r)&&A.equalsEpsilon(e.transform,t.transform,r)}function Pe(e,t){var r=e.frameState,i=e._context,n=r.shadowHints.shadowsEnabled,o=r.shadowHints.shadowMaps,a=r.shadowHints.lightShadowMaps,s=n&&a.length>0,l=!1,u=r.shadowHints.lastDirtyTime;t.lastDirtyTime!==u&&(t.lastDirtyTime=u,t.dirty=!0,l=!0);var c=t.derivedCommands;if(t.dirty&&h(c)){t.dirty=!1,n&&(t.receiveShadows||t.castShadows)&&(c.shadows=Ce.createDerivedCommands(o,a,t,l,i,c.shadows));var d=e._oit;t.pass===H.TRANSLUCENT&&h(d)&&d.isSupported()&&(s&&t.receiveShadows?(c.oit=h(c.oit)?c.oit:{},c.oit.shadows=d.createDerivedCommands(t.derivedCommands.shadows.receiveCommand,i,c.oit.shadows)):c.oit=d.createDerivedCommands(t,i,c.oit)),c.depth=mt(e,t,i,c.depth)}}function De(e){var t=e.globe;if(e._mode===_e.SCENE3D&&h(t)){var r=t.ellipsoid;return St.radius=r.minimumRadius,yt=P.fromBoundingSphere(St,e._camera.positionWC,yt)}}function Ie(e){e.render=!1,e.pick=!1,e.depth=!1}function Oe(e,t,r){var i=e._camera,n=e._frameState;n.commandList.length=0,n.shadowMaps.length=0,n.brdfLutGenerator=e._brdfLutGenerator,n.environmentMap=e.skyBox&&e.skyBox._cubeMap,n.mode=e._mode,n.morphTime=e.morphTime,n.mapProjection=e.mapProjection,n.frameNumber=t,n.time=T.clone(r,n.time),n.camera=i,n.cullingVolume=i.frustum.computeCullingVolume(i.positionWC,i.directionWC,i.upWC),n.occluder=De(e),n.terrainExaggeration=e._terrainExaggeration,n.minimumDisableDepthTestDistance=e._minimumDisableDepthTestDistance,n.invertClassification=e.invertClassification,e._actualInvertClassificationColor=s.clone(e.invertClassificationColor,e._actualInvertClassificationColor),le.isTranslucencySupported(e._context)||(e._actualInvertClassificationColor.alpha=1),n.invertClassificationColor=e._actualInvertClassificationColor,h(e.globe)?n.maximumScreenSpaceError=e.globe.maximumScreenSpaceError:n.maximumScreenSpaceError=2,Ie(n.passes)}function Me(e,t,r,i,n,o,a){n.length=i;for(var s=0;s<i;++s){var l,u;o?(l=Math.min(t-a,e+s*a),u=Math.min(t,l+a)):(l=Math.max(e,Math.pow(r,s)*e),u=Math.min(t,r*l));var c=n[s];h(c)?(c.near=l,c.far=u):c=n[s]=new oe(l,u)}}function Re(e,t,r){e.debugShowFrustums&&(t.debugOverlappingFrustums=0),e.frameState.passes.pick||Pe(e,t);for(var i=e._frustumCommandsList,n=i.length,o=0;o<n;++o){var a=i[o],s=a.near,l=a.far;if(!(r.start>l)){if(r.stop<s)break;var u=t.pass,c=a.indices[u]++;if(a.commands[u][c]=t,e.debugShowFrustums&&(t.debugOverlappingFrustums|=1<<o),t.executeInClosestFrustum)break}}if(e.debugShowFrustums){var d=e._debugFrustumStatistics.commandsInFrustums;d[t.debugOverlappingFrustums]=h(d[t.debugOverlappingFrustums])?d[t.debugOverlappingFrustums]+1:1,++e._debugFrustumStatistics.totalCommands}}function Le(e,t,r){return h(e)&&(!h(e.boundingVolume)||!e.cull||t.computeVisibility(e.boundingVolume)!==S.OUTSIDE&&(!h(r)||!e.boundingVolume.isOccluded(r)))}function Ne(e){var t=e._frameState,r=t.camera,i=r.directionWC,n=r.positionWC,o=e._computeCommandList,a=e._overlayCommandList,s=t.commandList;e.debugShowFrustums&&(e._debugFrustumStatistics={totalCommands:0,commandsInFrustums:{}});for(var l=e._frustumCommandsList,u=l.length,c=H.NUMBER_OF_PASSES,d=0;d<u;++d)for(var p=0;p<c;++p)l[d].indices[p]=0;o.length=0,a.length=0;for(var f=Number.MAX_VALUE,m=-Number.MAX_VALUE,g=!1,_=t.shadowHints.shadowsEnabled,v=Number.MAX_VALUE,y=-Number.MAX_VALUE,b=Number.MAX_VALUE,C=t.mode===_e.SCENE3D?t.occluder:void 0,S=t.cullingVolume,w=wt.planes,T=0;T<5;++T)w[T]=S.planes[T];S=wt;for(var A=s.length,x=0;x<A;++x){var P=s[x],D=P.pass;if(D===H.COMPUTE)o.push(P);else if(D===H.OVERLAY)a.push(P);else{var I=P.boundingVolume;if(h(I)){if(!Le(P,S,C))continue;if(Tt=I.computePlaneDistances(n,i,Tt),f=Math.min(f,Tt.start),m=Math.max(m,Tt.stop),_&&P.receiveShadows&&Tt.start<Ce.MAXIMUM_DISTANCE&&!(D===H.GLOBE&&Tt.start<-100&&Tt.stop>100)){var O=Tt.stop-Tt.start;D!==H.GLOBE&&Tt.start<100&&(b=Math.min(b,O)),v=Math.min(v,Tt.start),y=Math.max(y,Tt.stop)}}else Tt.start=r.frustum.near,Tt.stop=r.frustum.far,g=!(P instanceof B);Re(e,P,Tt)}}g?(f=r.frustum.near,m=r.frustum.far):(f=Math.min(Math.max(f,r.frustum.near),r.frustum.far),m=Math.max(Math.min(m,r.frustum.far),f),_&&(v=Math.min(Math.max(v,r.frustum.near),r.frustum.far),y=Math.max(Math.min(y,r.frustum.far),v))),_&&(t.shadowHints.nearPlane=v,t.shadowHints.farPlane=y,t.shadowHints.closestObjectSize=b);var M,R=e.mode===_e.SCENE2D,L=e.farToNearRatio;R?(m=Math.min(m,r.position.z+e.nearToFarDistance2D),f=Math.min(f,m),M=Math.ceil(Math.max(1,m-f)/e.nearToFarDistance2D)):M=Math.ceil(Math.log(m/f)/Math.log(L)),f!==Number.MAX_VALUE&&(M!==u||0!==l.length&&(f<l[0].near||m>l[u-1].far&&!E.equalsEpsilon(m,l[u-1].far,E.EPSILON8)))&&(Me(f,m,L,M,l,R,e.nearToFarDistance2D),Ne(e));var N=t.frustumSplits;N.length=M+1;for(var k=0;k<M;++k)N[k]=l[k].near,k===M-1&&(N[k+1]=l[k].far)}function ke(e){var t={},r=e.vertexAttributes;for(var i in r)r.hasOwnProperty(i)&&(t[i]=r[i].index);return t}function Fe(e,t,r){var i=t.context,n=d(r,e.shaderProgram),o=n.fragmentShaderSource.clone(),a=[];o.sources=o.sources.map(function(e){e=Q.replaceMain(e,"czm_Debug_main");for(var t,r=/gl_FragData\[(\d+)\]/g;null!==(t=r.exec(e));)-1===a.indexOf(t[1])&&a.push(t[1]);return e});var l,u=a.length,c="void main() \n{ \n czm_Debug_main(); \n";if(t.debugShowCommands){h(e._debugColor)||(e._debugColor=s.fromRandom());var p=e._debugColor;if(u>0)for(l=0;l<u;++l)c+=" gl_FragData["+a[l]+"].rgb *= vec3("+p.red+", "+p.green+", "+p.blue+"); \n";else c+=" gl_FragColor.rgb *= vec3("+p.red+", "+p.green+", "+p.blue+"); \n"}if(t.debugShowFrustums){var f=1&e.debugOverlappingFrustums?"1.0":"0.0",m=2&e.debugOverlappingFrustums?"1.0":"0.0",g=4&e.debugOverlappingFrustums?"1.0":"0.0";if(u>0)for(l=0;l<u;++l)c+=" gl_FragData["+a[l]+"].rgb *= vec3("+f+", "+m+", "+g+"); \n";else c+=" gl_FragColor.rgb *= vec3("+f+", "+m+", "+g+"); \n"}c+="}",o.sources.push(c);var _=ke(n);return X.fromCache({context:i,vertexShaderSource:n.vertexShaderSource,fragmentShaderSource:o,attributeLocations:_})}function Be(e,t,r){var i=G.shallowClone(e);i.shaderProgram=Fe(e,t),i.execute(t.context,r),i.shaderProgram.destroy()}function Ue(e,t,i,o,a){if(!h(t.debugCommandFilter)||t.debugCommandFilter(e)){if(e instanceof B)return void e.execute(i,o);var s=t.frameState.shadowHints.shadowsEnabled,u=s&&t.frameState.shadowHints.lightShadowMaps.length>0;if(t.debugShowCommands||t.debugShowFrustums?Be(e,t,o):u&&e.receiveShadows&&h(e.derivedCommands.shadows)?e.derivedCommands.shadows.receiveCommand.execute(i,o):t.frameState.passes.depth&&h(e.derivedCommands.depth)?e.derivedCommands.depth.depthOnlyCommand.execute(i,o):e.execute(i,o),e.debugShowBoundingVolume&&h(e.boundingVolume)){var c=t._frameState,d=e.boundingVolume;h(t._debugVolume)&&t._debugVolume.destroy();var p,f=n.clone(d.center);if(c.mode!==_e.SCENE3D){f=A.multiplyByPoint(Et,f,f);var m=c.mapProjection,_=m.unproject(f);f=m.ellipsoid.cartographicToCartesian(_)}if(h(d.radius)){var v=d.radius;p=b.toWireframe(g.createGeometry(new g({radii:new n(v,v,v),vertexFormat:pe.FLAT_VERTEX_FORMAT}))),t._debugVolume=new me({geometryInstances:new y({geometry:p,modelMatrix:A.fromTranslation(f),attributes:{color:new l(1,0,0,1)}}),appearance:new pe({flat:!0,translucent:!1}),asynchronous:!1})}else{var C=d.halfAxes;p=b.toWireframe(r.createGeometry(r.fromDimensions({dimensions:new n(2,2,2),vertexFormat:pe.FLAT_VERTEX_FORMAT}))),t._debugVolume=new me({geometryInstances:new y({geometry:p,modelMatrix:A.fromRotationTranslation(C,f,new A),attributes:{color:new l(1,0,0,1)}}),appearance:new pe({flat:!0,translucent:!1}),asynchronous:!1})}var S=c.commandList,w=c.commandList=[];t._debugVolume.update(c);var T;h(a)&&(T=o.framebuffer,o.framebuffer=a),w[0].execute(i,o),h(T)&&(o.framebuffer=T),c.commandList=S}}}function Ve(e,t,r){return t.boundingVolume.distanceSquaredTo(r)-e.boundingVolume.distanceSquaredTo(r)}function ze(e,t,r,i,n){var o=e.context;x(i,Ve,e._camera.positionWC),h(n)&&t(n.unclassifiedCommand,e,o,r);for(var a=i.length,s=0;s<a;++s)t(i[s],e,o,r)}function Ge(e,t){var r=e._debugGlobeDepths[t];return!h(r)&&e.context.depthTexture&&(r=new se,e._debugGlobeDepths[t]=r),r}function We(e,t){var r=e._pickDepths[t];return h(r)||(r=new fe,e._pickDepths[t]=r),r}function He(e,t){var r=e._camera,i=e.context,n=i.uniformState;n.updateCamera(r);var o;o=h(r.frustum.fov)?r.frustum.clone(At):h(r.frustum.infiniteProjectionMatrix)?r.frustum.clone(xt):h(r.frustum.width)?r.frustum.clone(Pt):r.frustum.clone(Dt),o.near=r.frustum.near,o.far=r.frustum.far,n.updateFrustum(o),n.updatePass(H.ENVIRONMENT);var a=e._useWebVR&&e.mode!==_e.SCENE2D,s=e._frameState.passes,l=s.pick,u=s.depth,c=e._environmentState;if(!l){var d=c.skyBoxCommand;if(h(d)&&Ue(d,e,i,t),c.isSkyAtmosphereVisible&&Ue(c.skyAtmosphereCommand,e,i,t),c.isSunVisible&&(c.sunDrawCommand.execute(i,t),e.sunBloom&&!a)){var p;p=c.useGlobeDepthFramebuffer?e._globeDepth.framebuffer:c.useFXAA?e._fxaa.getColorFramebuffer():c.originalFramebuffer,e._sunPostProcess.execute(i,p),t.framebuffer=p}c.isMoonVisible&&c.moonCommand.execute(i,t)}var f;c.useOIT?(h(e._executeOITFunction)||(e._executeOITFunction=function(e,t,r,i,n){e._oit.executeCommands(e,t,r,i,n)}),f=e._executeOITFunction):f=ze;for(var m,g=c.clearGlobeDepth,_=c.useDepthPlane,v=e._depthClearCommand,y=e._depthPlane,b=r.position.z,C=e._frustumCommandsList,S=C.length,w=0;w<S;++w){var T=S-w-1,E=C[T];e.mode===_e.SCENE2D?(r.position.z=b-E.near+1,o.far=Math.max(1,E.far-E.near),o.near=1,n.update(e.frameState),n.updateFrustum(o)):(o.near=0!==T?E.near*vt:E.near,o.far=E.far,n.updateFrustum(o));var A,x=e.debugShowGlobeDepth?Ge(e,T):e._globeDepth;e.debugShowGlobeDepth&&h(x)&&c.useGlobeDepthFramebuffer&&(A=t.framebuffer,t.framebuffer=x.framebuffer),v.execute(i,t),e._stencilClearCommand.execute(i,t),n.updatePass(H.GLOBE);var P=E.commands[H.GLOBE],D=E.indices[H.GLOBE];for(m=0;m<D;++m)Ue(P[m],e,i,t);for(h(x)&&c.useGlobeDepthFramebuffer&&(e.copyGlobeDepth||e.debugShowGlobeDepth)&&(x.update(i,t),x.executeCopyDepth(i,t)),e.debugShowGlobeDepth&&h(x)&&c.useGlobeDepthFramebuffer&&(t.framebuffer=A),n.updatePass(H.TERRAIN_CLASSIFICATION),P=E.commands[H.TERRAIN_CLASSIFICATION],D=E.indices[H.TERRAIN_CLASSIFICATION],m=0;m<D;++m)Ue(P[m],e,i,t);for(n.updatePass(H.CLASSIFICATION),P=E.commands[H.CLASSIFICATION],D=E.indices[H.CLASSIFICATION],m=0;m<D;++m)Ue(P[m],e,i,t);if(g&&v.execute(i,t),!c.useInvertClassification||l){for(n.updatePass(H.CESIUM_3D_TILE),P=E.commands[H.CESIUM_3D_TILE],D=E.indices[H.CESIUM_3D_TILE],m=0;m<D;++m)Ue(P[m],e,i,t);for(n.updatePass(H.CESIUM_3D_TILE_CLASSIFICATION),P=E.commands[H.CESIUM_3D_TILE_CLASSIFICATION],D=E.indices[H.CESIUM_3D_TILE_CLASSIFICATION],m=0;m<D;++m)Ue(P[m],e,i,t);for(n.updatePass(H.CLASSIFICATION),P=E.commands[H.CLASSIFICATION],D=E.indices[H.CLASSIFICATION],m=0;m<D;++m)Ue(P[m],e,i,t)}else{e._invertClassification.clear(i,t);var I=t.framebuffer;for(t.framebuffer=e._invertClassification._fbo,n.updatePass(H.CESIUM_3D_TILE),P=E.commands[H.CESIUM_3D_TILE],D=E.indices[H.CESIUM_3D_TILE],m=0;m<D;++m)Ue(P[m],e,i,t);for(n.updatePass(H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW),P=E.commands[H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW],D=E.indices[H.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW],m=0;m<D;++m)Ue(P[m],e,i,t);for(t.framebuffer=I,e._invertClassification.executeClassified(i,t),1===e.frameState.invertClassificationColor.alpha&&e._invertClassification.executeUnclassified(i,t),D>0&&i.stencilBuffer&&e._stencilClearCommand.execute(i,t),n.updatePass(H.CESIUM_3D_TILE_CLASSIFICATION),P=E.commands[H.CESIUM_3D_TILE_CLASSIFICATION],D=E.indices[H.CESIUM_3D_TILE_CLASSIFICATION],m=0;m<D;++m)Ue(P[m],e,i,t);for(n.updatePass(H.CLASSIFICATION),P=E.commands[H.CLASSIFICATION],D=E.indices[H.CLASSIFICATION],m=0;m<D;++m)Ue(P[m],e,i,t)}for(D>0&&i.stencilBuffer&&e._stencilClearCommand.execute(i,t),g&&_&&y.execute(i,t),n.updatePass(H.OPAQUE),P=E.commands[H.OPAQUE],D=E.indices[H.OPAQUE],m=0;m<D;++m)Ue(P[m],e,i,t);0!==T&&e.mode!==_e.SCENE2D&&(o.near=E.near,n.updateFrustum(o));var O;if(!l&&c.useInvertClassification&&e.frameState.invertClassificationColor.alpha<1&&(O=e._invertClassification),n.updatePass(H.TRANSLUCENT),P=E.commands[H.TRANSLUCENT],P.length=E.indices[H.TRANSLUCENT],f(e,Ue,t,P,O),h(x)&&(c.useGlobeDepthFramebuffer||u)&&e.useDepthPicking){var M=u?t.framebuffer.depthStencilTexture:x.framebuffer.depthStencilTexture,R=We(e,T);R.update(i,M),R.executeCopyDepth(i,t)}}}function je(e){e.context.uniformState.updatePass(H.COMPUTE);var t=e._environmentState.sunComputeCommand;h(t)&&t.execute(e._computeEngine);for(var r=e._computeCommandList,i=r.length,n=0;n<i;++n)r[n].execute(e._computeEngine)}function qe(e,t){e.context.uniformState.updatePass(H.OVERLAY);for(var r=e.context,i=e._overlayCommandList,n=i.length,o=0;o<n;++o)i[o].execute(r,t)}function Ye(e,t,r){for(var i=r.shadowMapCullingVolume,n=r.isPointLight,o=r.passes,a=o.length,s=t.length,l=0;l<s;++l){var u=t[l];if(Pe(e,u),u.castShadows&&(u.pass===H.GLOBE||u.pass===H.CESIUM_3D_TILE||u.pass===H.OPAQUE||u.pass===H.TRANSLUCENT)&&Le(u,i))if(n)for(var c=0;c<a;++c)o[c].commandList.push(u);else if(1===a)o[0].commandList.push(u);else for(var d=!1,h=a-1;h>=0;--h){var p=o[h].cullingVolume;if(Le(u,p))o[h].commandList.push(u),d=!0;else if(d)break}}}function Xe(e){var t=e.frameState,r=t.shadowHints.shadowMaps,i=r.length;if(t.shadowHints.shadowsEnabled)for(var n=e.context,o=n.uniformState,a=0;a<i;++a){var s=r[a];if(!s.outOfView){var l,u=s.passes,c=u.length;for(l=0;l<c;++l)u[l].commandList.length=0;var d=e.frameState.commandList;for(Ye(e,d,s),l=0;l<c;++l){var h=s.passes[l];o.updateCamera(h.camera),s.updatePass(n,l);for(var p=h.commandList.length,f=0;f<p;++f){var m=h.commandList[f];o.updatePass(m.pass),Ue(m.derivedCommands.shadows.castCommands[a],e,n,h.passState)}}}}}function Qe(e,t,r){var i=e._context,o=t.viewport;o.x=0,o.y=0,o.width=i.drawingBufferWidth,o.height=i.drawingBufferHeight;var a=e._frameState,s=a.camera,l=a.mode,u=a.passes.depth;if(e._useWebVR&&l!==_e.SCENE2D){rt(e,t,r),u||tt(e),Ne(e),u||(je(e),Xe(e)),o.x=0,o.y=0,o.width=.5*i.drawingBufferWidth,o.height=i.drawingBufferHeight;var c=J.clone(s,e._cameraVR),h=s.frustum.near,p=h*d(e.focalLength,5),f=d(e.eyeSeparation,p/30),m=n.multiplyByScalar(c.right,.5*f,It);s.frustum.aspectRatio=o.width/o.height;var g=.5*f*h/p;n.add(c.position,m,s.position),s.frustum.xOffset=g,He(e,t),o.x=t.viewport.width,n.subtract(c.position,m,s.position),s.frustum.xOffset=-g,He(e,t),J.clone(c,s)}else l!==_e.SCENE2D||e._mapMode2D===ce.ROTATE?Ke(!0,e,t,r):(rt(e,t,r),Ze(e,t))}function Ze(t,r){var i=t.context,o=t.frameState,a=t.camera,s=r.viewport,l=e.clone(s,Bt);r.viewport=l;var u=Ot,c=Mt;t.mapProjection.project(u,c);var d=n.clone(a.position,Rt),h=A.clone(a.transform,Nt),p=a.frustum.clone();a._setTransform(A.IDENTITY);var f=A.computeViewportTransformation(l,0,1,Lt),m=a.frustum.projectionMatrix,g=a.positionWC.y,_=n.fromElements(E.sign(g)*c.x-g,0,-a.positionWC.x,kt),v=F.pointToGLWindowCoordinates(m,f,_,Ft);v.x=Math.floor(v.x);var y=l.x,b=l.width;if(0===g||v.x<=y||v.x>=y+b)Ke(!0,t,r);else if(Math.abs(y+.5*b-v.x)<1)l.width=v.x-l.x,a.position.x*=E.sign(a.position.x),a.frustum.right=0,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Ke(!0,t,r),l.x=v.x,a.position.x=-a.position.x,a.frustum.right=-a.frustum.left,a.frustum.left=0,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Ke(!1,t,r);else if(v.x>y+.5*b){l.width=v.x-y;var C=a.frustum.right;a.frustum.right=c.x-g,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Ke(!0,t,r),l.x=v.x,l.width=y+b-v.x,a.position.x=-a.position.x,a.frustum.left=-a.frustum.right,a.frustum.right=C-2*a.frustum.right,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Ke(!1,t,r)}else{l.x=v.x,l.width=y+b-v.x;var S=a.frustum.left;a.frustum.left=-c.x-g,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Ke(!0,t,r),l.x=y,l.width=v.x-y,a.position.x=-a.position.x,a.frustum.right=-a.frustum.left, +a.frustum.left=S-2*a.frustum.left,o.cullingVolume=a.frustum.computeCullingVolume(a.positionWC,a.directionWC,a.upWC),i.uniformState.update(o),Ke(!1,t,r)}a._setTransform(h),n.clone(d,a.position),a.frustum=p.clone(),r.viewport=s}function Ke(e,t,r,i){var n=t.frameState.passes.depth;e||n||(t.frameState.commandList.length=0),n||tt(t),Ne(t),e&&(h(i)&&rt(t,r,i),n||(je(t),Xe(t))),He(t,r)}function Je(e,t){var r=e._frameState,i=e._environmentState,n=r.passes.render,o=e.skyAtmosphere,a=e.globe;if(!n||e._mode!==_e.SCENE2D&&r.camera.frustum instanceof D)i.skyAtmosphereCommand=void 0,i.skyBoxCommand=void 0,i.sunDrawCommand=void 0,i.sunComputeCommand=void 0,i.moonCommand=void 0;else{h(o)&&h(a)&&(o.setDynamicAtmosphereColor(a.enableLighting),i.isReadyForAtmosphere=i.isReadyForAtmosphere||a._surface._tilesToRender.length>0),i.skyAtmosphereCommand=h(o)?o.update(r):void 0,i.skyBoxCommand=h(e.skyBox)?e.skyBox.update(r):void 0;var s=h(e.sun)?e.sun.update(r,t):void 0;i.sunDrawCommand=h(s)?s.drawCommand:void 0,i.sunComputeCommand=h(s)?s.computeCommand:void 0,i.moonCommand=h(e.moon)?e.moon.update(r):void 0}var l=i.clearGlobeDepth=h(a)&&(!a.depthTestAgainstTerrain||e.mode===_e.SCENE2D);(i.useDepthPlane=l&&e.mode===_e.SCENE3D)&&e._depthPlane.update(r);for(var u=r.mode===_e.SCENE3D?r.occluder:void 0,c=r.cullingVolume,d=wt.planes,p=0;p<5;++p)d[p]=c.planes[p];c=wt,i.isSkyAtmosphereVisible=h(i.skyAtmosphereCommand)&&i.isReadyForAtmosphere,i.isSunVisible=Le(i.sunDrawCommand,c,u),i.isMoonVisible=Le(i.moonCommand,c,u)}function $e(e){var t=e._frameState;e.debugShowFrustumPlanes!==e._debugShowFrustumPlanes&&(e.debugShowFrustumPlanes?e._debugFrustumPlanes=new ee({camera:e.camera,updateOnChange:!1}):e._debugFrustumPlanes=e._debugFrustumPlanes&&e._debugFrustumPlanes.destroy(),e._debugShowFrustumPlanes=e.debugShowFrustumPlanes),h(e._debugFrustumPlanes)&&e._debugFrustumPlanes.update(t)}function et(e){var t=e._frameState,r=t.shadowMaps,i=r.length,n=i>0&&!t.passes.pick&&e.mode===_e.SCENE3D;if(n!==t.shadowHints.shadowsEnabled&&(++t.shadowHints.lastDirtyTime,t.shadowHints.shadowsEnabled=n),n){for(var o=0;o<i;++o)if(r[o]!==t.shadowHints.shadowMaps[o]){++t.shadowHints.lastDirtyTime;break}t.shadowHints.shadowMaps.length=0,t.shadowHints.lightShadowMaps.length=0;for(var a=0;a<i;++a){var s=r[a];s.update(t),t.shadowHints.shadowMaps.push(s),s.fromLightSource&&t.shadowHints.lightShadowMaps.push(s),s.dirty&&(++t.shadowHints.lastDirtyTime,s.dirty=!1)}}}function tt(e){var t=e._frameState;e._groundPrimitives.update(t),e._primitives.update(t),$e(e),et(e),e._globe&&e._globe.render(t)}function rt(e,t,r){var i=e._context,n=e._environmentState,o=e._frameState.passes,a=o.pick,l=e._useWebVR&&e.mode!==_e.SCENE2D;n.originalFramebuffer=t.framebuffer,h(e.sun)&&e.sunBloom!==e._sunBloom?(e.sunBloom&&!l?e._sunPostProcess=new Se:h(e._sunPostProcess)&&(e._sunPostProcess=e._sunPostProcess.destroy()),e._sunBloom=e.sunBloom):!h(e.sun)&&h(e._sunPostProcess)&&(e._sunPostProcess=e._sunPostProcess.destroy(),e._sunBloom=!1);var u=e._clearColorCommand;s.clone(r,u.color),u.execute(i,t);var c=n.useGlobeDepthFramebuffer=!a&&h(e._globeDepth);c&&(e._globeDepth.update(i,t),e._globeDepth.clear(i,t,r));var d=n.useOIT=!a&&h(e._oit)&&e._oit.isSupported();d&&(e._oit.update(i,t,e._globeDepth.framebuffer),e._oit.clear(i,t,r),n.useOIT=e._oit.isSupported());var p=n.useFXAA=!a&&e.fxaa;if(p&&(e._fxaa.update(i,t),e._fxaa.clear(i,t,r)),n.isSunVisible&&e.sunBloom&&!l?t.framebuffer=e._sunPostProcess.update(t):c?t.framebuffer=e._globeDepth.framebuffer:p&&(t.framebuffer=e._fxaa.getColorFramebuffer()),h(t.framebuffer)&&u.execute(i,t),n.useInvertClassification=!a&&h(t.framebuffer)&&e.invertClassification){var f;if(1===e.frameState.invertClassificationColor.alpha&&(n.useGlobeDepthFramebuffer?f=e._globeDepth.framebuffer:n.useFXAA&&(f=e._fxaa.getColorFramebuffer())),e._invertClassification.previousFramebuffer=f,e._invertClassification.update(i),e._invertClassification.clear(i,t),e.frameState.invertClassificationColor.alpha<1&&d){var m=e._invertClassification.unclassifiedCommand,g=m.derivedCommands;g.oit=e._oit.createDerivedCommands(m,i,g.oit)}}}function it(e,t){var r=e._context,i=e._environmentState,n=i.useGlobeDepthFramebuffer;if(e.debugShowGlobeDepth&&n){Ge(e,e.debugShowDepthFrustum-1).executeDebugGlobeDepth(r,t)}if(e.debugShowPickDepth&&n){We(e,e.debugShowDepthFrustum-1).executeDebugPickDepth(r,t)}var o=i.useOIT,a=i.useFXAA;o&&(t.framebuffer=a?e._fxaa.getColorFramebuffer():void 0,e._oit.execute(r,t)),a&&(!o&&n&&(t.framebuffer=e._fxaa.getColorFramebuffer(),e._globeDepth.executeCopyColor(r,t)),t.framebuffer=i.originalFramebuffer,e._fxaa.execute(r,t)),o||a||!n||(t.framebuffer=i.originalFramebuffer,e._globeDepth.executeCopyColor(r,t))}function nt(e){for(var t=e._frameState.afterRender,r=0,i=t.length;r<i;++r)t[r](),e.requestRender();t.length=0}function ot(e){var t=e._camera;return xe(t,e._cameraClone,E.EPSILON15)?(e._cameraStartFired&&C()-e._cameraMovedTime>e.cameraEventWaitTime&&(t.moveEnd.raiseEvent(),e._cameraStartFired=!1),!1):(e._cameraStartFired||(t.moveStart.raiseEvent(),e._cameraStartFired=!0),e._cameraMovedTime=C(),J.clone(t,e._cameraClone),!0)}function at(e,t){if(e.debugShowFramesPerSecond){if(!h(e._performanceDisplay)){var r=document.createElement("div");r.className="cesium-performanceDisplay-defaultContainer";e._canvas.parentNode.appendChild(r);var i=new he({container:r});e._performanceDisplay=i,e._performanceContainer=r}e._performanceDisplay.throttled=e.requestRenderMode,e._performanceDisplay.update(t)}else h(e._performanceDisplay)&&(e._performanceDisplay=e._performanceDisplay&&e._performanceDisplay.destroy(),e._performanceContainer.parentNode.removeChild(e._performanceContainer))}function st(e){var t=e._frameState;h(e.globe)&&e.globe.update(t),t.creditDisplay.update()}function lt(e,t){e._pickPositionCacheDirty=!0;var r=e.context,i=r.uniformState,o=e._frameState;Oe(e,E.incrementWrap(o.frameNumber,15e6,1),t),o.passes.render=!0;var a=d(e.backgroundColor,s.BLACK);o.backgroundColor=a,o.creditDisplay.beginFrame(),e.fog.update(o),i.update(o);var l=e.shadowMap;h(l)&&l.enabled&&(n.negate(i.sunDirectionWC,e._sunCamera.direction),o.shadowMaps.push(l)),e._computeCommandList.length=0,e._overlayCommandList.length=0;var u=e._passState;u.framebuffer=void 0,u.blendingEnabled=void 0,u.scissorTest=void 0,h(e.globe)&&e.globe.beginFrame(o),Je(e,u),Qe(e,u,a),it(e,u),qe(e,u),h(e.globe)&&e.globe.endFrame(o),o.creditDisplay.endFrame(),r.endFrame()}function ut(e,t,r){try{r(e,t)}catch(t){if(e._renderError.raiseEvent(e,t),e.rethrowRenderErrors)throw t}}function ct(e,t,r,i){var o=e._camera,a=o.frustum;h(a._offCenterFrustum)&&(a=a._offCenterFrustum);var s=e._passState.viewport,l=2*(t.x-s.x)/s.width-1;l*=.5*(a.right-a.left);var u=2*(s.height-t.y-s.y)/s.height-1;u*=.5*(a.top-a.bottom);var c=A.clone(o.transform,Wt);o._setTransform(A.IDENTITY);var d=n.clone(o.position,Vt);n.multiplyByScalar(o.right,l,zt),n.add(zt,d,d),n.multiplyByScalar(o.up,u,zt),n.add(zt,d,d),o._setTransform(c),e.mode===_e.SCENE2D&&n.fromElements(d.z,d.x,d.y,d);var p=a.getPixelDimensions(s.width,s.height,1,Gt),f=Ut;return f.right=.5*p.x,f.left=-f.right,f.top=.5*p.y,f.bottom=-f.top,f.near=a.near,f.far=a.far,f.computeCullingVolume(d,o.directionWC,o.upWC)}function dt(e,t,r,i){var n=e._camera,o=n.frustum,a=o.near,s=Math.tan(.5*o.fovy),l=o.aspectRatio*s,u=e._passState.viewport,c=2*(t.x-u.x)/u.width-1,d=2*(u.height-t.y-u.y)/u.height-1,h=c*a*l,p=d*a*s,f=o.getPixelDimensions(u.width,u.height,1,Gt),m=f.x*r*.5,g=f.y*i*.5,_=Ht;return _.top=p+g,_.bottom=p-g,_.right=h+m,_.left=h-m,_.near=a,_.far=o.far,_.computeCullingVolume(n.positionWC,n.directionWC,n.upWC)}function ht(e,t,r,i){var n=e.camera.frustum;return n instanceof D||n instanceof I?ct(e,t,r,i):dt(e,t,r,i)}function pt(e,t){var r=e.shaderCache.getDerivedShaderProgram(t,"depthOnly");if(!h(r)){for(var i=t._attributeLocations,n=t.fragmentShaderSource,o=!1,a=n.sources,s=a.length,l=0;l<s;++l)if(Zt.test(a[l])||Kt.test(a[l])){o=!0;break}o||(n=new Q({sources:["void main() { gl_FragColor = vec4(1.0); }"]})),r=e.shaderCache.createDerivedShaderProgram(t,"depthOnly",{vertexShaderSource:t.vertexShaderSource,fragmentShaderSource:n,attributeLocations:i})}return r}function ft(e,t){var r=e._depthOnlyRenderStateCache,i=r[t.id];if(!h(i)){var n=Y.getState(t);n.depthMask=!0,n.colorMask={red:!1,green:!1,blue:!1,alpha:!1},i=Y.fromCache(n),r[t.id]=i}return i}function mt(e,t,r,i){h(i)||(i={});var n,o;return h(i.depthOnlyCommand)&&(n=i.depthOnlyCommand.shaderProgram,o=i.depthOnlyCommand.renderState),i.depthOnlyCommand=G.shallowClone(t,i.depthOnlyCommand),h(n)&&i.shaderProgramId===t.shaderProgram.id?(i.depthOnlyCommand.shaderProgram=n,i.depthOnlyCommand.renderState=o):(i.depthOnlyCommand.shaderProgram=pt(r,t.shaderProgram),i.depthOnlyCommand.renderState=ft(e,t.renderState),i.shaderProgramId=t.shaderProgram.id),i}function gt(t,r){var i=t._context,n=t._frameState;Ie(n.passes),n.passes.pick=!0,n.passes.depth=!0,n.cullingVolume=ht(t,r,1,1);var o=t._pickDepthPassState;h(o)||(o=t._pickDepthPassState=new j(i),o.scissorTest={enabled:!0,rectangle:new e},o.viewport=new e);var a=i.drawingBufferWidth,s=i.drawingBufferHeight,l=t._pickDepthFramebuffer,u=t._pickDepthFramebufferWidth,c=t._pickDepthFramebufferHeight;h(l)&&u===a&&c===s||(t._pickDepthFramebuffer=t._pickDepthFramebuffer&&t._pickDepthFramebuffer.destroy(),l=t._pickDepthFramebuffer=new W({context:i,depthStencilTexture:new Z({context:i,width:a,height:s,pixelFormat:R.DEPTH_STENCIL,pixelDatatype:q.UNSIGNED_INT_24_8})}),t._pickDepthFramebufferWidth=a,t._pickDepthFramebufferHeight=s),o.framebuffer=l,o.viewport.width=a,o.viewport.height=s,o.scissorTest.rectangle.x=r.x,o.scissorTest.rectangle.y=s-r.y,o.scissorTest.rectangle.width=1,o.scissorTest.rectangle.height=1,Je(t,o),Qe(t,o,Xt),it(t,o),i.endFrame()}var _t=function(e){return function(){e.frameState.afterRender.push(function(){e.requestRender()})}},vt=.9999;p(Te.prototype,{canvas:{get:function(){return this._canvas}},drawingBufferHeight:{get:function(){return this._context.drawingBufferHeight}},drawingBufferWidth:{get:function(){return this._context.drawingBufferWidth}},maximumAliasedLineWidth:{get:function(){return z.maximumAliasedLineWidth}},maximumCubeMapSize:{get:function(){return z.maximumCubeMapSize}},pickPositionSupported:{get:function(){return this._context.depthTexture}},globe:{get:function(){return this._globe},set:function(e){this._globe=this._globe&&this._globe.destroy(),this._globe=e,Ee(this,e)}},primitives:{get:function(){return this._primitives}},groundPrimitives:{get:function(){return this._groundPrimitives}},camera:{get:function(){return this._camera}},screenSpaceCameraController:{get:function(){return this._screenSpaceCameraController}},mapProjection:{get:function(){return this._mapProjection}},frameState:{get:function(){return this._frameState}},tweens:{get:function(){return this._tweens}},imageryLayers:{get:function(){if(h(this.globe))return this.globe.imageryLayers}},terrainProvider:{get:function(){if(h(this.globe))return this.globe.terrainProvider},set:function(e){h(this.globe)&&(this.globe.terrainProvider=e)}},terrainProviderChanged:{get:function(){if(h(this.globe))return this.globe.terrainProviderChanged}},preUpdate:{get:function(){return this._preUpdate}},postUpdate:{get:function(){return this._postUpdate}},renderError:{get:function(){return this._renderError}},preRender:{get:function(){return this._preRender}},postRender:{get:function(){return this._postRender}},lastRenderTime:{get:function(){return this._lastRenderTime}},context:{get:function(){return this._context}},debugFrustumStatistics:{get:function(){return this._debugFrustumStatistics}},scene3DOnly:{get:function(){return this._frameState.scene3DOnly}},orderIndependentTranslucency:{get:function(){return h(this._oit)}},id:{get:function(){return this._id}},mode:{get:function(){return this._mode},set:function(e){e===_e.SCENE2D?this.morphTo2D(0):e===_e.SCENE3D?this.morphTo3D(0):e===_e.COLUMBUS_VIEW&&this.morphToColumbusView(0),this._mode=e}},numberOfFrustums:{get:function(){return this._frustumCommandsList.length}},terrainExaggeration:{get:function(){return this._terrainExaggeration}},useWebVR:{get:function(){return this._useWebVR},set:function(e){this._useWebVR=e,this._useWebVR?(this._frameState.creditDisplay.container.style.visibility="hidden",this._cameraVR=new J(this),h(this._deviceOrientationCameraController)||(this._deviceOrientationCameraController=new re(this)),this._aspectRatioVR=this._camera.frustum.aspectRatio):(this._frameState.creditDisplay.container.style.visibility="visible",this._cameraVR=void 0,this._deviceOrientationCameraController=this._deviceOrientationCameraController&&!this._deviceOrientationCameraController.isDestroyed()&&this._deviceOrientationCameraController.destroy(),this._camera.frustum.aspectRatio=this._aspectRatioVR,this._camera.frustum.xOffset=0)}},mapMode2D:{get:function(){return this._mapMode2D}},imagerySplitPosition:{get:function(){return this._frameState.imagerySplitPosition},set:function(e){this._frameState.imagerySplitPosition=e}},minimumDisableDepthTestDistance:{get:function(){return this._minimumDisableDepthTestDistance},set:function(e){this._minimumDisableDepthTestDistance=e}}}),Te.prototype.getCompressedTextureFormatSupported=function(e){var t=this.context;return("WEBGL_compressed_texture_s3tc"===e||"s3tc"===e)&&t.s3tc||("WEBGL_compressed_texture_pvrtc"===e||"pvrtc"===e)&&t.pvrtc||("WEBGL_compressed_texture_etc1"===e||"etc1"===e)&&t.etc1};var yt,bt=new n,Ct=new n,St=new t,wt=new c,Tt=new w,Et=new A(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1);Et=A.inverseTransformation(Et,Et);var At=new O,xt=new M,Pt=new D,Dt=new I,It=new n,Ot=new a(Math.PI,E.PI_OVER_TWO),Mt=new n,Rt=new n,Lt=new A,Nt=new A,kt=new n,Ft=new n,Bt=new e;Te.prototype.initializeFrame=function(){120==this._shaderFrameCount++&&(this._shaderFrameCount=0,this._context.shaderCache.destroyReleasedShaderPrograms()),this._tweens.update(),this._screenSpaceCameraController.update(),h(this._deviceOrientationCameraController)&&this._deviceOrientationCameraController.update(),this._camera.update(this._mode),this._camera._updateCameraChanged()},Te.prototype.render=function(e){h(e)||(e=T.now()),this._jobScheduler.resetBudgets(),this._preUpdate.raiseEvent(this,e),ut(this,e,st),this._postUpdate.raiseEvent(this,e);var t=ot(this),r=!this.requestRenderMode||this._renderRequested||t||this.mode===_e.MORPHING;if(!r&&h(this.maximumRenderTimeChange)&&h(this._lastRenderTime)){var i=Math.abs(T.secondsDifference(this._lastRenderTime,e));r=r||i>this.maximumRenderTimeChange}r&&(this._lastRenderTime=T.clone(e,this._lastRenderTime),this._renderRequested=!1,this._preRender.raiseEvent(this,e),ut(this,e,lt),this._postRender.raiseEvent(this,e),L.update()),at(this,r),nt(this)},Te.prototype.forceRender=function(e){this._renderRequested=!0,this.render(e)},Te.prototype.requestRender=function(){this._renderRequested=!0},Te.prototype.clampLineWidth=function(e){return Math.max(z.minimumAliasedLineWidth,Math.min(e,z.maximumAliasedLineWidth))};var Ut=new I,Vt=new n,zt=new n,Gt=new i,Wt=new A,Ht=new M,jt=3,qt=3,Yt=new e(0,0,jt,qt),Xt=new s(0,0,0,0),Qt=new i;Te.prototype.pick=function(e,t,r){jt=d(t,3),qt=d(r,jt);var i=this._context,n=i.uniformState,o=this._frameState,a=ve.transformWindowToDrawingBuffer(this,e,Qt);h(this._pickFramebuffer)||(this._pickFramebuffer=i.createPickFramebuffer()),this._jobScheduler.disableThisFrame(),Oe(this,o.frameNumber,o.time),o.cullingVolume=ht(this,a,jt,qt),o.invertClassification=!1,o.passes.pick=!0,n.update(o),Yt.x=a.x-.5*(jt-1),Yt.y=this.drawingBufferHeight-a.y-.5*(qt-1),Yt.width=jt,Yt.height=qt;var s=this._pickFramebuffer.begin(Yt);Je(this,s),Qe(this,s,Xt),it(this,s);var l=this._pickFramebuffer.end(Yt);return i.endFrame(),nt(this),l};var Zt=/\bgl_FragDepthEXT\b/,Kt=/\bdiscard\b/,Jt=new o,$t=new o(1,1/255,1/65025,1/16581375);Te.prototype.pickPositionWorldCoordinates=function(e,t){if(this.useDepthPicking){var r=e.toString();if(this._pickPositionCacheDirty)this._pickPositionCache={},this._pickPositionCacheDirty=!1;else if(this._pickPositionCache.hasOwnProperty(r))return n.clone(this._pickPositionCache[r],t);var i=this._context,a=i.uniformState,s=ve.transformWindowToDrawingBuffer(this,e,Qt);this.pickTranslucentDepth&>(this,s),s.y=this.drawingBufferHeight-s.y;var l,u=this._camera;l=h(u.frustum.fov)?u.frustum.clone(At):h(u.frustum.infiniteProjectionMatrix)?u.frustum.clone(xt):h(u.frustum.width)?u.frustum.clone(Pt):u.frustum.clone(Dt);for(var c=this.numberOfFrustums,d=0;d<c;++d){var p=We(this,d),f=i.readPixels({x:s.x,y:s.y,width:1,height:1,framebuffer:p.framebuffer}),m=o.unpack(f,0,Jt);o.divideByScalar(m,255,m);var g=o.dot(m,$t);if(g>0&&g<1){var _,v=this._frustumCommandsList[d];return this.mode===_e.SCENE2D?(_=u.position.z,u.position.z=_-v.near+1,l.far=Math.max(1,v.far-v.near),l.near=1,a.update(this.frameState),a.updateFrustum(l)):(l.near=v.near*(0!==d?vt:1),l.far=v.far,a.updateFrustum(l)),t=ve.drawingBufferToWgs84Coordinates(this,s,g,t),this.mode===_e.SCENE2D&&(u.position.z=_,a.update(this.frameState)),this._pickPositionCache[r]=n.clone(t),t}}this._pickPositionCache[r]=void 0}};var er=new a;return Te.prototype.pickPosition=function(e,t){if(t=this.pickPositionWorldCoordinates(e,t),h(t)&&this.mode!==_e.SCENE3D){n.fromElements(t.y,t.z,t.x,t);var r=this.mapProjection,i=r.ellipsoid,o=r.unproject(t,er);i.cartographicToCartesian(o,t)}return t},Te.prototype.drillPick=function(e,t){var r,i,n=[],o=[],a=[];h(t)||(t=Number.MAX_VALUE);for(var s=this.pick(e);h(s)&&h(s.primitive)&&(n.push(s),!(0>=--t));){var l=s.primitive,u=!1;"function"==typeof l.getGeometryInstanceAttributes&&h(s.id)&&(i=l.getGeometryInstanceAttributes(s.id),h(i)&&h(i.show)&&(u=!0,i.show=N.toValue(!1,i.show),a.push(i))),u||(l.show=!1,o.push(l)),s=this.pick(e)}for(r=0;r<o.length;++r)o[r].show=!0;for(r=0;r<a.length;++r)i=a[r],i.show=N.toValue(!0,i.show);return n},Te.prototype.cartesianToCanvasCoordinates=function(e,t){return ve.wgs84ToWindowCoordinates(this,e,t)},Te.prototype.completeMorph=function(){this._transitioner.completeMorph()},Te.prototype.morphTo2D=function(e){var t,r=this.globe;t=h(r)?r.ellipsoid:this.mapProjection.ellipsoid,e=d(e,2),this._transitioner.morphTo2D(e,t)},Te.prototype.morphToColumbusView=function(e){var t,r=this.globe;t=h(r)?r.ellipsoid:this.mapProjection.ellipsoid,e=d(e,2),this._transitioner.morphToColumbusView(e,t)},Te.prototype.morphTo3D=function(e){var t,r=this.globe;t=h(r)?r.ellipsoid:this.mapProjection.ellipsoid,e=d(e,2),this._transitioner.morphTo3D(e,t)},Te.prototype.isDestroyed=function(){return!1},Te.prototype.destroy=function(){this._tweens.removeAll(),this._computeEngine=this._computeEngine&&this._computeEngine.destroy(),this._screenSpaceCameraController=this._screenSpaceCameraController&&this._screenSpaceCameraController.destroy(),this._deviceOrientationCameraController=this._deviceOrientationCameraController&&!this._deviceOrientationCameraController.isDestroyed()&&this._deviceOrientationCameraController.destroy(),this._pickFramebuffer=this._pickFramebuffer&&this._pickFramebuffer.destroy(),this._pickDepthFramebuffer=this._pickDepthFramebuffer&&this._pickDepthFramebuffer.destroy(),this._primitives=this._primitives&&this._primitives.destroy(),this._groundPrimitives=this._groundPrimitives&&this._groundPrimitives.destroy(),this._globe=this._globe&&this._globe.destroy(),this.skyBox=this.skyBox&&this.skyBox.destroy(),this.skyAtmosphere=this.skyAtmosphere&&this.skyAtmosphere.destroy(),this._debugSphere=this._debugSphere&&this._debugSphere.destroy(),this.sun=this.sun&&this.sun.destroy(),this._sunPostProcess=this._sunPostProcess&&this._sunPostProcess.destroy(),this._depthPlane=this._depthPlane&&this._depthPlane.destroy(),this._transitioner.destroy(),this._debugFrustumPlanes=this._debugFrustumPlanes&&this._debugFrustumPlanes.destroy(),this._brdfLutGenerator=this._brdfLutGenerator&&this._brdfLutGenerator.destroy(),h(this._globeDepth)&&this._globeDepth.destroy(),this._removeCreditContainer&&this._canvas.parentNode.removeChild(this._creditContainer),h(this._oit)&&this._oit.destroy(),this._fxaa.destroy(),this._context=this._context&&this._context.destroy(),this._frameState.creditDisplay.destroy(),h(this._performanceDisplay)&&(this._performanceDisplay=this._performanceDisplay&&this._performanceDisplay.destroy(),this._performanceContainer.parentNode.removeChild(this._performanceContainer)),this._removeRequestListenerCallback(),this._removeTaskProcessorListenerCallback();for(var e=0;e<this._removeGlobeCallbacks.length;++e)this._removeGlobeCallbacks[e]();return this._removeGlobeCallbacks.length=0,f(this)},Te}),define("Shaders/SkyAtmosphereFS",[],function(){"use strict";return"#ifdef COLOR_CORRECT\nuniform vec3 u_hsbShift;\n#endif\nuniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\nconst float g = -0.95;\nconst float g2 = g * g;\nvarying vec3 v_rayleighColor;\nvarying vec3 v_mieColor;\nvarying vec3 v_toCamera;\nvarying vec3 v_positionEC;\nvoid main (void)\n{\nfloat cosAngle = dot(czm_sunDirectionWC, normalize(v_toCamera)) / length(v_toCamera);\nfloat rayleighPhase = 0.75 * (1.0 + cosAngle * cosAngle);\nfloat miePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cosAngle * cosAngle) / pow(1.0 + g2 - 2.0 * g * cosAngle, 1.5);\nconst float exposure = 2.0;\nvec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor;\nrgb = vec3(1.0) - exp(-exposure * rgb);\nfloat l = czm_luminance(rgb);\n#ifdef COLOR_CORRECT\nvec3 hsb = czm_RGBToHSB(rgb);\nhsb.x += u_hsbShift.x;\nhsb.y = clamp(hsb.y + u_hsbShift.y, 0.0, 1.0);\nhsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0;\nrgb = czm_HSBToRGB(hsb);\nl = min(l, czm_luminance(rgb));\n#endif\nfloat atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0);\nfloat nightAlpha = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), 0.0, 1.0) : 1.0;\natmosphereAlpha *= pow(nightAlpha, 0.5);\ngl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime));\n}\n"}),define("Shaders/SkyAtmosphereVS",[],function(){"use strict";return"attribute vec4 position;\nuniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\nconst float Kr = 0.0025;\nconst float Kr4PI = Kr * 4.0 * czm_pi;\nconst float Km = 0.0015;\nconst float Km4PI = Km * 4.0 * czm_pi;\nconst float ESun = 15.0;\nconst float KmESun = Km * ESun;\nconst float KrESun = Kr * ESun;\nconst vec3 InvWavelength = vec3(\n5.60204474633241,\n9.473284437923038,\n19.643802610477206);\nconst float rayleighScaleDepth = 0.25;\nconst int nSamples = 2;\nconst float fSamples = 2.0;\nvarying vec3 v_rayleighColor;\nvarying vec3 v_mieColor;\nvarying vec3 v_toCamera;\nfloat scale(float cosAngle)\n{\nfloat x = 1.0 - cosAngle;\nreturn rayleighScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\n}\nvoid main(void)\n{\nfloat cameraHeight = u_cameraAndRadiiAndDynamicAtmosphereColor.x;\nfloat outerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.y;\nfloat innerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.z;\nvec3 positionV3 = position.xyz;\nvec3 ray = positionV3 - czm_viewerPositionWC;\nfloat far = length(ray);\nray /= far;\nfloat atmosphereScale = 1.0 / (outerRadius - innerRadius);\n#ifdef SKY_FROM_SPACE\nfloat B = 2.0 * dot(czm_viewerPositionWC, ray);\nfloat C = cameraHeight * cameraHeight - outerRadius * outerRadius;\nfloat det = max(0.0, B*B - 4.0 * C);\nfloat near = 0.5 * (-B - sqrt(det));\nvec3 start = czm_viewerPositionWC + ray * near;\nfar -= near;\nfloat startAngle = dot(ray, start) / outerRadius;\nfloat startDepth = exp(-1.0 / rayleighScaleDepth );\nfloat startOffset = startDepth*scale(startAngle);\n#else // SKY_FROM_ATMOSPHERE\nvec3 start = czm_viewerPositionWC;\nfloat height = length(start);\nfloat depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - cameraHeight));\nfloat startAngle = dot(ray, start) / height;\nfloat startOffset = depth*scale(startAngle);\n#endif\nfloat sampleLength = far / fSamples;\nfloat scaledLength = sampleLength * atmosphereScale;\nvec3 sampleRay = ray * sampleLength;\nvec3 samplePoint = start + sampleRay * 0.5;\nvec3 frontColor = vec3(0.0, 0.0, 0.0);\nvec3 lightDir = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? czm_sunPositionWC - czm_viewerPositionWC : czm_viewerPositionWC;\nlightDir = normalize(lightDir);\nfor(int i=0; i<nSamples; i++)\n{\nfloat height = length(samplePoint);\nfloat depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - height));\nfloat fLightAngle = dot(lightDir, samplePoint) / height;\nfloat fCameraAngle = dot(ray, samplePoint) / height;\nfloat fScatter = (startOffset + depth*(scale(fLightAngle) - scale(fCameraAngle)));\nvec3 attenuate = exp(-fScatter * (InvWavelength * Kr4PI + Km4PI));\nfrontColor += attenuate * (depth * scaledLength);\nsamplePoint += sampleRay;\n}\nv_mieColor = frontColor * KmESun;\nv_rayleighColor = frontColor * (InvWavelength * KrESun);\nv_toCamera = czm_viewerPositionWC - positionV3;\ngl_Position = czm_modelViewProjection * position;\n}\n"}),define("Scene/SkyAtmosphere",["../Core/Cartesian3","../Core/Cartesian4","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/Ellipsoid","../Core/EllipsoidGeometry","../Core/GeometryPipeline","../Core/Math","../Core/VertexFormat","../Renderer/BufferUsage","../Renderer/DrawCommand","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/ShaderSource","../Renderer/VertexArray","../Shaders/SkyAtmosphereFS","../Shaders/SkyAtmosphereVS","./BlendingState","./CullFace","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C){"use strict";function S(i){i=r(i,a.WGS84),this.show=!0,this._ellipsoid=i,this._command=new h({owner:this}),this._spSkyFromSpace=void 0,this._spSkyFromAtmosphere=void 0,this._spSkyFromSpaceColorCorrect=void 0,this._spSkyFromAtmosphereColorCorrect=void 0,this.hueShift=0,this.saturationShift=0,this.brightnessShift=0,this._hueSaturationBrightness=new e;var n=new t;n.w=0,n.y=e.maximumComponent(e.multiplyByScalar(i.radii,1.025,new e)),n.z=i.maximumRadius,this._cameraAndRadiiAndDynamicAtmosphereColor=n;var o=this;this._command.uniformMap={u_cameraAndRadiiAndDynamicAtmosphereColor:function(){return o._cameraAndRadiiAndDynamicAtmosphereColor},u_hsbShift:function(){return o._hueSaturationBrightness.x=o.hueShift,o._hueSaturationBrightness.y=o.saturationShift,o._hueSaturationBrightness.z=o.brightnessShift,o._hueSaturationBrightness}}}function w(e){return!(u.equalsEpsilon(e.hueShift,0,u.EPSILON7)&&u.equalsEpsilon(e.saturationShift,0,u.EPSILON7)&&u.equalsEpsilon(e.brightnessShift,0,u.EPSILON7))}return n(S.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),S.prototype.setDynamicAtmosphereColor=function(e){this._cameraAndRadiiAndDynamicAtmosphereColor.w=e?1:0},S.prototype.update=function(t){if(this.show){var r=t.mode;if((r===C.SCENE3D||r===C.MORPHING)&&t.passes.render){var n=this._command;if(!i(n.vertexArray)){var o=t.context,a=s.createGeometry(new s({radii:e.multiplyByScalar(this._ellipsoid.radii,1.025,new e),slicePartitions:256,stackPartitions:256,vertexFormat:c.POSITION_ONLY}));n.vertexArray=g.fromGeometry({context:o,geometry:a,attributeLocations:l.createAttributeLocations(a),bufferUsage:d.STATIC_DRAW}),n.renderState=p.fromCache({cull:{enabled:!0,face:b.FRONT},blending:y.ALPHA_BLEND});var u=new m({defines:["SKY_FROM_SPACE"],sources:[v]});this._spSkyFromSpace=f.fromCache({context:o,vertexShaderSource:u,fragmentShaderSource:_}),u=new m({defines:["SKY_FROM_ATMOSPHERE"],sources:[v]}),this._spSkyFromAtmosphere=f.fromCache({context:o,vertexShaderSource:u,fragmentShaderSource:_})}var h=w(this);if(h&&(!i(this._spSkyFromSpaceColorCorrect)||!i(this._spSkyFromAtmosphereColorCorrect))){var S=t.context,T=new m({defines:["SKY_FROM_SPACE"],sources:[v]}),E=new m({defines:["COLOR_CORRECT"],sources:[_]});this._spSkyFromSpaceColorCorrect=f.fromCache({context:S,vertexShaderSource:T,fragmentShaderSource:E}),T=new m({defines:["SKY_FROM_ATMOSPHERE"],sources:[v]}),this._spSkyFromAtmosphereColorCorrect=f.fromCache({context:S,vertexShaderSource:T,fragmentShaderSource:E})}var A=t.camera.positionWC,x=e.magnitude(A);return this._cameraAndRadiiAndDynamicAtmosphereColor.x=x,x>this._cameraAndRadiiAndDynamicAtmosphereColor.y?n.shaderProgram=h?this._spSkyFromSpaceColorCorrect:this._spSkyFromSpace:n.shaderProgram=h?this._spSkyFromAtmosphereColorCorrect:this._spSkyFromAtmosphere,n}}},S.prototype.isDestroyed=function(){return!1},S.prototype.destroy=function(){var e=this._command;return e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),this._spSkyFromSpace=this._spSkyFromSpace&&this._spSkyFromSpace.destroy(),this._spSkyFromAtmosphere=this._spSkyFromAtmosphere&&this._spSkyFromAtmosphere.destroy(),this._spSkyFromSpaceColorCorrect=this._spSkyFromSpaceColorCorrect&&this._spSkyFromSpaceColorCorrect.destroy(),this._spSkyFromAtmosphereColorCorrect=this._spSkyFromAtmosphereColorCorrect&&this._spSkyFromAtmosphereColorCorrect.destroy(),o(this)},S}),define("Shaders/SkyBoxFS",[],function(){"use strict";return"uniform samplerCube u_cubeMap;\nvarying vec3 v_texCoord;\nvoid main()\n{\nvec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb;\ngl_FragColor = vec4(rgb, czm_morphTime);\n}\n"}),define("Shaders/SkyBoxVS",[],function(){"use strict";return"attribute vec3 position;\nvarying vec3 v_texCoord;\nvoid main()\n{\nvec3 p = czm_viewRotation * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\ngl_Position = czm_projection * vec4(p, 1.0);\nv_texCoord = position.xyz;\n}\n"}),define("Scene/SkyBox",["../Core/BoxGeometry","../Core/Cartesian3","../Core/defaultValue","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Core/GeometryPipeline","../Core/Matrix4","../Core/VertexFormat","../Renderer/BufferUsage","../Renderer/CubeMap","../Renderer/DrawCommand","../Renderer/loadCubeMap","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/VertexArray","../Shaders/SkyBoxFS","../Shaders/SkyBoxVS","./BlendingState","./SceneMode"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y){"use strict";function b(e){this.sources=e.sources,this._sources=void 0,this.show=r(e.show,!0),this._command=new d({modelMatrix:s.clone(s.IDENTITY),owner:this}),this._cubeMap=void 0}return b.prototype.update=function(r){var n=this;if(this.show&&(r.mode===y.SCENE3D||r.mode===y.MORPHING)&&r.passes.render){var o=r.context;if(this._sources!==this.sources){this._sources=this.sources;var s=this.sources;"string"==typeof s.positiveX?h(o,this._sources).then(function(e){n._cubeMap=n._cubeMap&&n._cubeMap.destroy(),n._cubeMap=e}):(this._cubeMap=this._cubeMap&&this._cubeMap.destroy(),this._cubeMap=new c({context:o,source:s}))}var d=this._command;if(!i(d.vertexArray)){d.uniformMap={u_cubeMap:function(){return n._cubeMap}};var b=e.createGeometry(e.fromDimensions({dimensions:new t(2,2,2),vertexFormat:l.POSITION_ONLY})),C=a.createAttributeLocations(b);d.vertexArray=m.fromGeometry({context:o,geometry:b,attributeLocations:C,bufferUsage:u.STATIC_DRAW}),d.shaderProgram=f.fromCache({context:o,vertexShaderSource:_,fragmentShaderSource:g,attributeLocations:C}),d.renderState=p.fromCache({blending:v.ALPHA_BLEND})}if(i(this._cubeMap))return d}},b.prototype.isDestroyed=function(){return!1},b.prototype.destroy=function(){var e=this._command;return e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),e.shaderProgram=e.shaderProgram&&e.shaderProgram.destroy(),this._cubeMap=this._cubeMap&&this._cubeMap.destroy(),n(this)},b}),define("Scene/SphereEmitter",["../Core/Cartesian3","../Core/Check","../Core/defaultValue","../Core/defineProperties","../Core/Math"],function(e,t,r,i,n){"use strict";function o(e){e=r(e,1),this._radius=r(e,1)}return i(o.prototype,{radius:{get:function(){return this._radius},set:function(e){this._radius=e}}}),o.prototype.emit=function(t){ +var r=n.randomBetween(0,n.TWO_PI),i=n.randomBetween(0,n.PI),o=n.randomBetween(0,this._radius),a=o*Math.cos(r)*Math.sin(i),s=o*Math.sin(r)*Math.sin(i),l=o*Math.cos(i);t.position=e.fromElements(a,s,l,t.position),t.velocity=e.normalize(t.position,t.velocity)},o}),define("Scene/StyleExpression",["../Core/DeveloperError"],function(e){"use strict";function t(){}return t.prototype.evaluate=function(t,r,i){e.throwInstantiationError()},t.prototype.evaluateColor=function(t,r,i){e.throwInstantiationError()},t.prototype.getShaderFunction=function(t,r,i,n){e.throwInstantiationError()},t}),define("Shaders/SunFS",[],function(){"use strict";return"uniform sampler2D u_texture;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\ngl_FragColor = texture2D(u_texture, v_textureCoordinates);\n}\n"}),define("Shaders/SunTextureFS",[],function(){"use strict";return"uniform float u_glowLengthTS;\nuniform float u_radiusTS;\nvarying vec2 v_textureCoordinates;\nvec2 rotate(vec2 p, vec2 direction)\n{\nreturn vec2(p.x * direction.x - p.y * direction.y, p.x * direction.y + p.y * direction.x);\n}\nvec4 addBurst(vec2 position, vec2 direction)\n{\nvec2 rotatedPosition = rotate(position, direction) * vec2(25.0, 0.75);\nfloat radius = length(rotatedPosition);\nfloat burst = 1.0 - smoothstep(0.0, 0.55, radius);\nreturn vec4(burst);\n}\nvoid main()\n{\nvec2 position = v_textureCoordinates - vec2(0.5);\nfloat radius = length(position);\nfloat surface = step(radius, u_radiusTS);\nvec4 color = vec4(1.0, 1.0, surface + 0.2, surface);\nfloat glow = 1.0 - smoothstep(0.0, 0.55, radius);\ncolor.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75;\nvec4 burst = vec4(0.0);\nburst += 0.4 * addBurst(position, vec2(0.38942, 0.92106));\nburst += 0.4 * addBurst(position, vec2(0.99235, 0.12348));\nburst += 0.4 * addBurst(position, vec2(0.60327, -0.79754));\nburst += 0.3 * addBurst(position, vec2(0.31457, 0.94924));\nburst += 0.3 * addBurst(position, vec2(0.97931, 0.20239));\nburst += 0.3 * addBurst(position, vec2(0.66507, -0.74678));\ncolor += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15;\ngl_FragColor = clamp(color, vec4(0.0), vec4(1.0));\n}\n"}),define("Shaders/SunVS",[],function(){"use strict";return"attribute vec2 direction;\nuniform float u_size;\nvarying vec2 v_textureCoordinates;\nvoid main()\n{\nvec4 position;\nif (czm_morphTime == 1.0)\n{\nposition = vec4(czm_sunPositionWC, 1.0);\n}\nelse\n{\nposition = vec4(czm_sunPositionColumbusView.zxy, 1.0);\n}\nvec4 positionEC = czm_view * position;\nvec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\nvec2 halfSize = vec2(u_size * 0.5);\nhalfSize *= ((direction * 2.0) - 1.0);\ngl_Position = czm_viewportOrthographic * vec4(positionWC.xy + halfSize, -positionWC.z, 1.0);\nv_textureCoordinates = direction;\n}\n"}),define("Scene/Sun",["../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartesian4","../Core/ComponentDatatype","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/IndexDatatype","../Core/Math","../Core/Matrix4","../Core/PixelFormat","../Core/PrimitiveType","../Renderer/Buffer","../Renderer/BufferUsage","../Renderer/ComputeCommand","../Renderer/DrawCommand","../Renderer/RenderState","../Renderer/ShaderProgram","../Renderer/Texture","../Renderer/VertexArray","../Shaders/SunFS","../Shaders/SunTextureFS","../Shaders/SunVS","./BlendingState","./SceneMode","./SceneTransforms"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A){"use strict";function x(){this.show=!0,this._drawCommand=new g({primitiveType:h.TRIANGLES,boundingVolume:new e,owner:this}),this._commands={drawCommand:this._drawCommand,computeCommand:void 0},this._boundingVolume=new e,this._boundingVolume2D=new e,this._texture=void 0,this._drawingBufferWidth=void 0,this._drawingBufferHeight=void 0,this._radiusTS=void 0,this._size=void 0,this.glowFactor=1,this._glowFactorDirty=!1;var t=this;this._uniformMap={u_texture:function(){return t._texture},u_size:function(){return t._size}}}a(x.prototype,{glowFactor:{get:function(){return this._glowFactor},set:function(e){e=Math.max(e,0),this._glowFactor=e,this._glowFactorDirty=!0}}});var P=new t,D=new t,I=new i,O=new i;return x.prototype.update=function(i,a){if(this.show){var s=i.mode;if(s!==E.SCENE2D&&s!==E.MORPHING&&i.passes.render){var h=i.context,g=a.viewport.width,x=a.viewport.height;if(!o(this._texture)||g!==this._drawingBufferWidth||x!==this._drawingBufferHeight||this._glowFactorDirty){this._texture=this._texture&&this._texture.destroy(),this._drawingBufferWidth=g,this._drawingBufferHeight=x,this._glowFactorDirty=!1;var M=Math.max(g,x);M=Math.pow(2,Math.ceil(Math.log(M)/Math.log(2))-2),M=Math.max(1,M),this._texture=new y({context:h,width:M,height:M,pixelFormat:d.RGBA}),this._glowLengthTS=5*this._glowFactor,this._radiusTS=1/(1+2*this._glowLengthTS)*.5;var R=this,L={u_glowLengthTS:function(){return R._glowLengthTS},u_radiusTS:function(){return R._radiusTS}};this._commands.computeCommand=new m({fragmentShaderSource:S,outputTexture:this._texture,uniformMap:L,persists:!1,owner:this,postExecute:function(){R._commands.computeCommand=void 0}})}var N=this._drawCommand;if(!o(N.vertexArray)){var k={direction:0},F=new Uint8Array(8);F[0]=0,F[1]=0,F[2]=255,F[3]=0,F[4]=255,F[5]=255,F[6]=0,F[7]=255;var B=p.createVertexBuffer({context:h,typedArray:F,usage:f.STATIC_DRAW}),U=[{index:k.direction,vertexBuffer:B,componentsPerAttribute:2,normalize:!0,componentDatatype:n.UNSIGNED_BYTE}],V=p.createIndexBuffer({context:h,typedArray:new Uint16Array([0,1,2,0,2,3]),usage:f.STATIC_DRAW,indexDatatype:l.UNSIGNED_SHORT});N.vertexArray=new b({context:h,attributes:U,indexBuffer:V}),N.shaderProgram=v.fromCache({context:h,vertexShaderSource:w,fragmentShaderSource:C,attributeLocations:k}),N.renderState=_.fromCache({blending:T.ALPHA_BLEND}),N.uniformMap=this._uniformMap}var z=h.uniformState.sunPositionWC,G=h.uniformState.sunPositionColumbusView,W=this._boundingVolume,H=this._boundingVolume2D;r.clone(z,W.center),H.center.x=G.z,H.center.y=G.x,H.center.z=G.y,W.radius=u.SOLAR_RADIUS+u.SOLAR_RADIUS*this._glowLengthTS,H.radius=W.radius,s===E.SCENE3D?e.clone(W,N.boundingVolume):s===E.COLUMBUS_VIEW&&e.clone(H,N.boundingVolume);var j=A.computeActualWgs84Position(i,z,O),q=r.magnitude(r.subtract(j,i.camera.position,O)),Y=h.uniformState.projection,X=I;X.x=0,X.y=0,X.z=-q,X.w=1;var Q=c.multiplyByVector(Y,X,O),Z=A.clipToGLWindowCoordinates(a.viewport,Q,P);X.x=u.SOLAR_RADIUS;var K=c.multiplyByVector(Y,X,O),J=A.clipToGLWindowCoordinates(a.viewport,K,D);return this._size=Math.ceil(t.magnitude(t.subtract(J,Z,O))),this._size=2*this._size*(1+2*this._glowLengthTS),this._commands}}},x.prototype.isDestroyed=function(){return!1},x.prototype.destroy=function(){var e=this._drawCommand;return e.vertexArray=e.vertexArray&&e.vertexArray.destroy(),e.shaderProgram=e.shaderProgram&&e.shaderProgram.destroy(),this._texture=this._texture&&this._texture.destroy(),s(this)},x}),define("Scene/TileBoundingVolume",["../Core/DeveloperError"],function(e){"use strict";function t(){}return t.prototype.boundingVolume=void 0,t.prototype.boundingSphere=void 0,t.prototype.distanceToCamera=function(t){e.throwInstantiationError()},t.prototype.intersectPlane=function(t){e.throwInstantiationError()},t.prototype.createDebugVolume=function(t){e.throwInstantiationError()},t}),define("Scene/TileCoordinatesImageryProvider",["../Core/Color","../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/Event","../Core/GeographicTilingScheme","../ThirdParty/when"],function(e,t,r,i,n,o,a){"use strict";function s(i){i=t(i,t.EMPTY_OBJECT),this._tilingScheme=r(i.tilingScheme)?i.tilingScheme:new o({ellipsoid:i.ellipsoid}),this._color=t(i.color,e.YELLOW),this._errorEvent=new n,this._tileWidth=t(i.tileWidth,256),this._tileHeight=t(i.tileHeight,256),this._readyPromise=a.resolve(!0)}return i(s.prototype,{proxy:{get:function(){}},tileWidth:{get:function(){return this._tileWidth}},tileHeight:{get:function(){return this._tileHeight}},maximumLevel:{get:function(){}},minimumLevel:{get:function(){}},tilingScheme:{get:function(){return this._tilingScheme}},rectangle:{get:function(){return this._tilingScheme.rectangle}},tileDiscardPolicy:{get:function(){}},errorEvent:{get:function(){return this._errorEvent}},ready:{get:function(){return!0}},readyPromise:{get:function(){return this._readyPromise}},credit:{get:function(){}},hasAlphaChannel:{get:function(){return!0}}}),s.prototype.getTileCredits=function(e,t,r){},s.prototype.requestImage=function(e,t,r,i){var n=document.createElement("canvas");n.width=256,n.height=256;var o=n.getContext("2d"),a=this._color.toCssColorString();o.strokeStyle=a,o.lineWidth=2,o.strokeRect(1,1,255,255);var s="L"+r+"X"+e+"Y"+t;return o.font="bold 25px Arial",o.textAlign="center",o.fillStyle="black",o.fillText(s,127,127),o.fillStyle=a,o.fillText(s,124,124),n},s.prototype.pickFeatures=function(e,t,r,i,n){},s}),define("Scene/TileDiscardPolicy",["../Core/DeveloperError"],function(e){"use strict";function t(t){e.throwInstantiationError()}return t.prototype.isReady=e.throwInstantiationError,t.prototype.shouldDiscardImage=e.throwInstantiationError,t}),define("Scene/TileState",["../Core/freezeObject"],function(e){"use strict";return e({START:0,LOADING:1,READY:2,UPSAMPLED_ONLY:3})}),define("Shaders/ViewportQuadFS",[],function(){"use strict";return"varying vec2 v_textureCoordinates;\nvoid main()\n{\nczm_materialInput materialInput;\nmaterialInput.s = v_textureCoordinates.s;\nmaterialInput.st = v_textureCoordinates;\nmaterialInput.str = vec3(v_textureCoordinates, 0.0);\nmaterialInput.normalEC = vec3(0.0, 0.0, -1.0);\nczm_material material = czm_getMaterial(materialInput);\ngl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n}\n"}),define("Scene/ViewportQuad",["../Core/BoundingRectangle","../Core/Color","../Core/defined","../Core/destroyObject","../Core/DeveloperError","../Renderer/Pass","../Renderer/RenderState","../Renderer/ShaderSource","../Shaders/ViewportQuadFS","./BlendingState","./Material"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(i,n){this.show=!0,r(i)||(i=new e),this.rectangle=e.clone(i),r(n)||(n=c.fromType(c.ColorType,{color:new t(1,1,1,1)})),this.material=n,this._material=void 0,this._overlayCommand=void 0,this._rs=void 0}return d.prototype.update=function(t){if(this.show){var i=this._rs;r(i)&&e.equals(i.viewport,this.rectangle)||(this._rs=a.fromCache({blending:u.ALPHA_BLEND,viewport:this.rectangle}));if(t.passes.render){var n=t.context;if(this._material!==this.material||!r(this._overlayCommand)){this._material=this.material,r(this._overlayCommand)&&this._overlayCommand.shaderProgram.destroy();var c=new s({sources:[this._material.shaderSource,l]});this._overlayCommand=n.createViewportQuadCommand(c,{renderState:this._rs,uniformMap:this._material._uniforms,owner:this}),this._overlayCommand.pass=o.OVERLAY}this._material.update(n),this._overlayCommand.uniformMap=this._material._uniforms,t.commandList.push(this._overlayCommand)}}},d.prototype.isDestroyed=function(){return!1},d.prototype.destroy=function(){return r(this._overlayCommand)&&(this._overlayCommand.shaderProgram=this._overlayCommand.shaderProgram&&this._overlayCommand.shaderProgram.destroy()),i(this)},d}),define("ThirdParty/crunch",[],function(){function globalEval(e){eval.call(null,e)}function assert(e,t){e||abort("Assertion failed: "+t)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(e){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}function setValue(e,t,r,i){switch(r=r||"i8","*"===r.charAt(r.length-1)&&(r="i32"),r){case"i1":case"i8":HEAP8[e>>0]=t;break;case"i16":HEAP16[e>>1]=t;break;case"i32":HEAP32[e>>2]=t;break;case"i64":tempI64=[t>>>0,(tempDouble=t,+Math_abs(tempDouble)>=1?tempDouble>0?(0|Math_min(+Math_floor(tempDouble/4294967296),4294967295))>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[e>>2]=tempI64[0],HEAP32[e+4>>2]=tempI64[1];break;case"float":HEAPF32[e>>2]=t;break;case"double":HEAPF64[e>>3]=t;break;default:abort("invalid type for setValue: "+r)}}function getValue(e,t,r){switch(t=t||"i8","*"===t.charAt(t.length-1)&&(t="i32"),t){case"i1":case"i8":return HEAP8[e>>0];case"i16":return HEAP16[e>>1];case"i32":case"i64":return HEAP32[e>>2];case"float":return HEAPF32[e>>2];case"double":return HEAPF64[e>>3];default:abort("invalid type for setValue: "+t)}return null}function allocate(e,t,r,i){var n,o;"number"==typeof e?(n=!0,o=e):(n=!1,o=e.length);var a,s="string"==typeof t?t:null;if(a=r==ALLOC_NONE?i:["function"==typeof _malloc?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][void 0===r?ALLOC_STATIC:r](Math.max(o,s?1:t.length)),n){var l,i=a;for(assert(0==(3&a)),l=a+(-4&o);i<l;i+=4)HEAP32[i>>2]=0;for(l=a+o;i<l;)HEAP8[i++>>0]=0;return a}if("i8"===s)return e.subarray||e.slice?HEAPU8.set(e,a):HEAPU8.set(new Uint8Array(e),a),a;for(var u,c,d,h=0;h<o;){var p=e[h];"function"==typeof p&&(p=Runtime.getFunctionIndex(p)),u=s||t[h],0!==u?("i64"==u&&(u="i32"),setValue(a+h,p,u),d!==u&&(c=Runtime.getNativeTypeSize(u),d=u),h+=c):h++}return a}function getMemory(e){return staticSealed?runtimeInitialized?_malloc(e):Runtime.dynamicAlloc(e):Runtime.staticAlloc(e)}function Pointer_stringify(e,t){if(0===t||!e)return"";for(var r,i=0,n=0;;){if(r=HEAPU8[e+n>>0],i|=r,0==r&&!t)break;if(n++,t&&n==t)break}t||(t=n);var o="";if(i<128){for(var a;t>0;)a=String.fromCharCode.apply(String,HEAPU8.subarray(e,e+Math.min(t,1024))),o=o?o+a:a,e+=1024,t-=1024;return o}return Module.UTF8ToString(e)}function AsciiToString(e){for(var t="";;){var r=HEAP8[e++>>0];if(!r)return t;t+=String.fromCharCode(r)}}function stringToAscii(e,t){return writeAsciiToMemory(e,t,!1)}function UTF8ArrayToString(e,t){for(var r=t;e[r];)++r;if(r-t>16&&e.subarray&&UTF8Decoder)return UTF8Decoder.decode(e.subarray(t,r));for(var i,n,o,a,s,l,u="";;){if(!(i=e[t++]))return u;if(128&i)if(n=63&e[t++],192!=(224&i))if(o=63&e[t++],224==(240&i)?i=(15&i)<<12|n<<6|o:(a=63&e[t++],240==(248&i)?i=(7&i)<<18|n<<12|o<<6|a:(s=63&e[t++],248==(252&i)?i=(3&i)<<24|n<<18|o<<12|a<<6|s:(l=63&e[t++],i=(1&i)<<30|n<<24|o<<18|a<<12|s<<6|l))),i<65536)u+=String.fromCharCode(i);else{var c=i-65536;u+=String.fromCharCode(55296|c>>10,56320|1023&c)}else u+=String.fromCharCode((31&i)<<6|n);else u+=String.fromCharCode(i)}}function UTF8ToString(e){return UTF8ArrayToString(HEAPU8,e)}function stringToUTF8Array(e,t,r,i){if(!(i>0))return 0;for(var n=r,o=r+i-1,a=0;a<e.length;++a){var s=e.charCodeAt(a);if(s>=55296&&s<=57343&&(s=65536+((1023&s)<<10)|1023&e.charCodeAt(++a)),s<=127){if(r>=o)break;t[r++]=s}else if(s<=2047){if(r+1>=o)break;t[r++]=192|s>>6,t[r++]=128|63&s}else if(s<=65535){if(r+2>=o)break;t[r++]=224|s>>12,t[r++]=128|s>>6&63,t[r++]=128|63&s}else if(s<=2097151){if(r+3>=o)break;t[r++]=240|s>>18,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}else if(s<=67108863){if(r+4>=o)break;t[r++]=248|s>>24,t[r++]=128|s>>18&63,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}else{if(r+5>=o)break;t[r++]=252|s>>30,t[r++]=128|s>>24&63,t[r++]=128|s>>18&63,t[r++]=128|s>>12&63,t[r++]=128|s>>6&63,t[r++]=128|63&s}}return t[r]=0,r-n}function stringToUTF8(e,t,r){return stringToUTF8Array(e,HEAPU8,t,r)}function lengthBytesUTF8(e){for(var t=0,r=0;r<e.length;++r){var i=e.charCodeAt(r);i>=55296&&i<=57343&&(i=65536+((1023&i)<<10)|1023&e.charCodeAt(++r)),i<=127?++t:t+=i<=2047?2:i<=65535?3:i<=2097151?4:i<=67108863?5:6}return t}function demangle(e){var t=Module.___cxa_demangle||Module.__cxa_demangle;if(t){try{var r=e.substr(1),i=lengthBytesUTF8(r)+1,n=_malloc(i);stringToUTF8(r,n,i);var o=_malloc(4),a=t(n,0,0,o);if(0===getValue(o,"i32")&&a)return Pointer_stringify(a)}catch(e){}finally{n&&_free(n),o&&_free(o),a&&_free(a)}return e}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),e}function demangleAll(e){var t=/__Z[\w\d_]+/g;return e.replace(t,function(e){var t=demangle(e);return e===t?e:e+" ["+t+"]"})}function jsStackTrace(){var e=new Error;if(!e.stack){try{throw new Error(0)}catch(t){e=t}if(!e.stack)return"(no stack trace available)"}return e.stack.toString()}function stackTrace(){var e=jsStackTrace();return Module.extraStackTrace&&(e+="\n"+Module.extraStackTrace()),demangleAll(e)}function alignUp(e,t){return e%t>0&&(e+=t-e%t),e}function updateGlobalBuffer(e){Module.buffer=buffer=e}function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){var e=Module.usingWasm?WASM_PAGE_SIZE:ASMJS_PAGE_SIZE,t=2147483648-e;if(HEAP32[DYNAMICTOP_PTR>>2]>t)return!1;var r=TOTAL_MEMORY;for(TOTAL_MEMORY=Math.max(TOTAL_MEMORY,MIN_TOTAL_MEMORY);TOTAL_MEMORY<HEAP32[DYNAMICTOP_PTR>>2];)TOTAL_MEMORY=TOTAL_MEMORY<=536870912?alignUp(2*TOTAL_MEMORY,e):Math.min(alignUp((3*TOTAL_MEMORY+2147483648)/4,e),t);var i=Module.reallocBuffer(TOTAL_MEMORY);return i&&i.byteLength==TOTAL_MEMORY?(updateGlobalBuffer(i),updateGlobalBufferViews(),!0):(TOTAL_MEMORY=r,!1)}function getTotalMemory(){return TOTAL_MEMORY}function callRuntimeCallbacks(e){for(;e.length>0;){var t=e.shift();if("function"!=typeof t){var r=t.func;"number"==typeof r?void 0===t.arg?Module.dynCall_v(r):Module.dynCall_vi(r,t.arg):r(void 0===t.arg?null:t.arg)}else t()}}function preRun(){if(Module.preRun)for("function"==typeof Module.preRun&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for("function"==typeof Module.postRun&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(e){__ATPRERUN__.unshift(e)}function addOnInit(e){__ATINIT__.unshift(e)}function addOnPreMain(e){__ATMAIN__.unshift(e)}function addOnExit(e){__ATEXIT__.unshift(e)}function addOnPostRun(e){__ATPOSTRUN__.unshift(e)}function intArrayFromString(e,t,r){var i=r>0?r:lengthBytesUTF8(e)+1,n=new Array(i),o=stringToUTF8Array(e,n,0,n.length);return t&&(n.length=o),n}function intArrayToString(e){for(var t=[],r=0;r<e.length;r++){var i=e[r];i>255&&(i&=255),t.push(String.fromCharCode(i))}return t.join("")}function writeStringToMemory(e,t,r){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var i,n;r&&(n=t+lengthBytesUTF8(e),i=HEAP8[n]),stringToUTF8(e,t,1/0),r&&(HEAP8[n]=i)}function writeArrayToMemory(e,t){HEAP8.set(e,t)}function writeAsciiToMemory(e,t,r){for(var i=0;i<e.length;++i)HEAP8[t++>>0]=e.charCodeAt(i);r||(HEAP8[t>>0]=0)}function addRunDependency(e){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}function removeRunDependency(e){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),0==runDependencies&&(null!==runDependencyWatcher&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var t=dependenciesFulfilled;dependenciesFulfilled=null,t()}}function _abort(){Module.abort()}function __ZSt18uncaught_exceptionv(){return!!__ZSt18uncaught_exceptionv.uncaught_exception}function ___cxa_begin_catch(e){var t=EXCEPTIONS.infos[e];return t&&!t.caught&&(t.caught=!0,__ZSt18uncaught_exceptionv.uncaught_exception--),t&&(t.rethrown=!1),EXCEPTIONS.caught.push(e),EXCEPTIONS.addRef(EXCEPTIONS.deAdjust(e)),e}function _pthread_once(e,t){_pthread_once.seen||(_pthread_once.seen={}),e in _pthread_once.seen||(Module.dynCall_v(t),_pthread_once.seen[e]=1)}function _emscripten_memcpy_big(e,t,r){return HEAPU8.set(HEAPU8.subarray(t,t+r),e),e}function ___syscall6(e,t){SYSCALLS.varargs=t;try{var r=SYSCALLS.getStreamFromFD();return FS.close(r),0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function _pthread_getspecific(e){return PTHREAD_SPECIFIC[e]||0}function ___setErrNo(e){return Module.___errno_location&&(HEAP32[Module.___errno_location()>>2]=e),e}function _pthread_key_create(e,t){return 0==e?ERRNO_CODES.EINVAL:(HEAP32[e>>2]=PTHREAD_SPECIFIC_NEXT_KEY,PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY]=0,PTHREAD_SPECIFIC_NEXT_KEY++,0)}function ___resumeException(e){throw EXCEPTIONS.last||(EXCEPTIONS.last=e),e+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."}function ___cxa_find_matching_catch(){var e=EXCEPTIONS.last;if(!e)return 0|(Runtime.setTempRet0(0),0);var t=EXCEPTIONS.infos[e],r=t.type;if(!r)return 0|(Runtime.setTempRet0(0),e);var i=Array.prototype.slice.call(arguments);Module.___cxa_is_pointer_type(r);___cxa_find_matching_catch.buffer||(___cxa_find_matching_catch.buffer=_malloc(4)),HEAP32[___cxa_find_matching_catch.buffer>>2]=e,e=___cxa_find_matching_catch.buffer;for(var n=0;n<i.length;n++)if(i[n]&&Module.___cxa_can_catch(i[n],r,e))return e=HEAP32[e>>2],t.adjusted=e,0|(Runtime.setTempRet0(i[n]),e);return e=HEAP32[e>>2],0|(Runtime.setTempRet0(r),e)}function ___gxx_personality_v0(){}function _pthread_setspecific(e,t){return e in PTHREAD_SPECIFIC?(PTHREAD_SPECIFIC[e]=t,0):ERRNO_CODES.EINVAL}function ___syscall140(e,t){SYSCALLS.varargs=t;try{var r=SYSCALLS.getStreamFromFD(),i=(SYSCALLS.get(),SYSCALLS.get()),n=SYSCALLS.get(),o=SYSCALLS.get(),a=i;return FS.llseek(r,a,o),HEAP32[n>>2]=r.position,r.getdents&&0===a&&0===o&&(r.getdents=null),0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function ___syscall146(e,t){SYSCALLS.varargs=t;try{var r=SYSCALLS.get(),i=SYSCALLS.get(),n=SYSCALLS.get(),o=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(e,t){var r=___syscall146.buffers[e];assert(r),0===t||10===t?((1===e?Module.print:Module.printErr)(UTF8ArrayToString(r,0)),r.length=0):r.push(t)});for(var a=0;a<n;a++){for(var s=HEAP32[i+8*a>>2],l=HEAP32[i+(8*a+4)>>2],u=0;u<l;u++)___syscall146.printChar(r,HEAPU8[s+u]);o+=l}return o}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function ___syscall54(e,t){SYSCALLS.varargs=t;try{return 0}catch(e){return"undefined"!=typeof FS&&e instanceof FS.ErrnoError||abort(e),-e.errno}}function invoke_iiii(e,t,r,i){try{return Module.dynCall_iiii(e,t,r,i)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viiiii(e,t,r,i,n,o){try{Module.dynCall_viiiii(e,t,r,i,n,o)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_vi(e,t){try{Module.dynCall_vi(e,t)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_ii(e,t){try{return Module.dynCall_ii(e,t)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viii(e,t,r,i){try{Module.dynCall_viii(e,t,r,i)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_v(e){try{Module.dynCall_v(e)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viiiiii(e,t,r,i,n,o,a){try{Module.dynCall_viiiiii(e,t,r,i,n,o,a)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function invoke_viiii(e,t,r,i,n){try{Module.dynCall_viiii(e,t,r,i,n)}catch(e){if("number"!=typeof e&&"longjmp"!==e)throw e;Module.setThrew(1,0)}}function ExitStatus(e){this.name="ExitStatus",this.message="Program terminated with exit("+e+")",this.status=e}function run(e){function t(){Module.calledRun||(Module.calledRun=!0,ABORT||(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(e),postRun()))}e=e||Module.arguments,null===preloadStartTime&&(preloadStartTime=Date.now()),runDependencies>0||(preRun(),runDependencies>0||Module.calledRun||(Module.setStatus?(Module.setStatus("Running..."),setTimeout(function(){setTimeout(function(){Module.setStatus("")},1),t()},1)):t()))}function exit(e,t){t&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=e,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(e)),ENVIRONMENT_IS_NODE&&process.exit(e),Module.quit(e,new ExitStatus(e)))}function abort(e){Module.onAbort&&Module.onAbort(e),void 0!==e?(Module.print(e),Module.printErr(e),e=JSON.stringify(e)):e="",ABORT=!0,EXITSTATUS=1;var t="abort("+e+") at "+stackTrace()+"\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";throw abortDecorators&&abortDecorators.forEach(function(r){t=r(t,e)}),t}var Module;Module||(Module=(void 0!==Module?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1;if(Module.ENVIRONMENT)if("WEB"===Module.ENVIRONMENT)ENVIRONMENT_IS_WEB=!0;else if("WORKER"===Module.ENVIRONMENT)ENVIRONMENT_IS_WORKER=!0;else if("NODE"===Module.ENVIRONMENT)ENVIRONMENT_IS_NODE=!0;else{if("SHELL"!==Module.ENVIRONMENT)throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");ENVIRONMENT_IS_SHELL=!0}else ENVIRONMENT_IS_WEB="object"==typeof window,ENVIRONMENT_IS_WORKER="function"==typeof importScripts,ENVIRONMENT_IS_NODE="object"==typeof process&&"function"==typeof require&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn);var nodeFS,nodePath;Module.read=function(e,t){nodeFS||(nodeFS=require("fs")),nodePath||(nodePath=require("path")),e=nodePath.normalize(e);var r=nodeFS.readFileSync(e);return t?r:r.toString()},Module.readBinary=function(e){var t=Module.read(e,!0);return t.buffer||(t=new Uint8Array(t)),assert(t.buffer),t},Module.load=function(e){globalEval(read(e))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),"undefined"!=typeof module&&(module.exports=Module),process.on("uncaughtException",function(e){if(!(e instanceof ExitStatus))throw e}),Module.inspect=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),"undefined"!=typeof printErr&&(Module.printErr=printErr),"undefined"!=typeof read?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(e){if("function"==typeof readbuffer)return new Uint8Array(readbuffer(e));var t=read(e,"binary");return assert("object"==typeof t),t},"undefined"!=typeof scriptArgs?Module.arguments=scriptArgs:void 0!==arguments&&(Module.arguments=arguments),"function"==typeof quit&&(Module.quit=function(e,t){quit(e)});else{if(!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER)throw"Unknown runtime environment. Where are we?";if(Module.read=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.send(null),t.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null),new Uint8Array(t.response)}),Module.readAsync=function(e,t,r){var i=new XMLHttpRequest;i.open("GET",e,!0),i.responseType="arraybuffer",i.onload=function(){200==i.status||0==i.status&&i.response?t(i.response):r()},i.onerror=r,i.send(null)},void 0!==arguments&&(Module.arguments=arguments),"undefined"!=typeof console)Module.print||(Module.print=function(e){console.log(e)}),Module.printErr||(Module.printErr=function(e){console.warn(e)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&"undefined"!=typeof dump?function(e){dump(e)}:function(e){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),void 0===Module.setWindowTitle&&(Module.setWindowTitle=function(e){document.title=e})}!Module.load&&Module.read&&(Module.load=function(e){globalEval(Module.read(e))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(e,t){throw t}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[];for(var key in moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(e){return tempRet0=e,e},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(e){STACKTOP=e},getNativeTypeSize:function(e){switch(e){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:if("*"===e[e.length-1])return Runtime.QUANTUM_SIZE;if("i"===e[0]){var t=parseInt(e.substr(1));return assert(t%8==0),t/8}return 0}},getNativeFieldSize:function(e){return Math.max(Runtime.getNativeTypeSize(e),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(e,t){return"double"===t||"i64"===t?7&e&&(assert(4==(7&e)),e+=4):assert(0==(3&e)),e},getAlignSize:function(e,t,r){return r||"i64"!=e&&"double"!=e?e?Math.min(t||(e?Runtime.getNativeFieldSize(e):0),Runtime.QUANTUM_SIZE):Math.min(t,8):8},dynCall:function(e,t,r){return r&&r.length?Module["dynCall_"+e].apply(null,[t].concat(r)):Module["dynCall_"+e].call(null,t)},functionPointers:[],addFunction:function(e){for(var t=0;t<Runtime.functionPointers.length;t++)if(!Runtime.functionPointers[t])return Runtime.functionPointers[t]=e,2*(1+t);throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."},removeFunction:function(e){Runtime.functionPointers[(e-2)/2]=null},warnOnce:function(e){Runtime.warnOnce.shown||(Runtime.warnOnce.shown={}),Runtime.warnOnce.shown[e]||(Runtime.warnOnce.shown[e]=1,Module.printErr(e))},funcWrappers:{},getFuncWrapper:function(e,t){assert(t),Runtime.funcWrappers[t]||(Runtime.funcWrappers[t]={});var r=Runtime.funcWrappers[t];return r[e]||(1===t.length?r[e]=function(){return Runtime.dynCall(t,e)}:2===t.length?r[e]=function(r){return Runtime.dynCall(t,e,[r])}:r[e]=function(){return Runtime.dynCall(t,e,Array.prototype.slice.call(arguments))}),r[e]},getCompilerSetting:function(e){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"},stackAlloc:function(e){var t=STACKTOP;return STACKTOP=STACKTOP+e|0,STACKTOP=STACKTOP+15&-16,t},staticAlloc:function(e){var t=STATICTOP;return STATICTOP=STATICTOP+e|0,STATICTOP=STATICTOP+15&-16,t},dynamicAlloc:function(e){var t=HEAP32[DYNAMICTOP_PTR>>2],r=-16&(t+e+15|0);if(HEAP32[DYNAMICTOP_PTR>>2]=r,r>=TOTAL_MEMORY){if(!enlargeMemory())return HEAP32[DYNAMICTOP_PTR>>2]=t,0}return t},alignMemory:function(e,t){return e=Math.ceil(e/(t||16))*(t||16)},makeBigInt:function(e,t,r){return r?+(e>>>0)+4294967296*+(t>>>0):+(e>>>0)+4294967296*+(0|t)},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0} +;Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0,cwrap,ccall;!function(){function parseJSFunc(e){var t=e.toString().match(sourceRegex).slice(1);return{arguments:t[0],body:t[1],returnValue:t[2]}}function ensureJSsource(){if(!JSsource){JSsource={};for(var e in JSfuncs)JSfuncs.hasOwnProperty(e)&&(JSsource[e]=parseJSFunc(JSfuncs[e]))}}var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(e){var t=Runtime.stackAlloc(e.length);return writeArrayToMemory(e,t),t},stringToC:function(e){var t=0;if(null!==e&&void 0!==e&&0!==e){var r=1+(e.length<<2);t=Runtime.stackAlloc(r),stringToUTF8(e,t,r)}return t}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(e,t,r,i,n){var o=getCFunc(e),a=[],s=0;if(i)for(var l=0;l<i.length;l++){var u=toC[r[l]];u?(0===s&&(s=Runtime.stackSave()),a[l]=u(i[l])):a[l]=i[l]}var c=o.apply(null,a);if("string"===t&&(c=Pointer_stringify(c)),0!==s){if(n&&n.async)return void EmterpreterAsync.asyncFinalizers.push(function(){Runtime.stackRestore(s)});Runtime.stackRestore(s)}return c};var sourceRegex=/^function\s*[a-zA-Z$_0-9]*\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/,JSsource=null;cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident),numericArgs=argTypes.every(function(e){return"number"===e}),numericRet="string"!==returnType;if(numericRet&&numericArgs)return cfunc;var argNames=argTypes.map(function(e,t){return"$"+t}),funcstr="(function("+argNames.join(",")+") {",nargs=argTypes.length;if(!numericArgs){ensureJSsource(),funcstr+="var stack = "+JSsource.stackSave.body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if("number"!==type){var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";",funcstr+=convertCode.body+";",funcstr+=arg+"=("+convertCode.returnValue+");"}}}var cfuncname=parseJSFunc(function(){return cfunc}).returnValue;if(funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");",!numericRet){var strgfy=parseJSFunc(function(){return Pointer_stringify}).returnValue;funcstr+="ret = "+strgfy+"(ret);"}return numericArgs||(ensureJSsource(),funcstr+=JSsource.stackRestore.body.replace("()","(stack)")+";"),funcstr+="return ret})",eval(funcstr)}}(),Module.ccall=ccall,Module.cwrap=cwrap,Module.setValue=setValue,Module.getValue=getValue;var ALLOC_NORMAL=0,ALLOC_STACK=1,ALLOC_STATIC=2,ALLOC_DYNAMIC=3,ALLOC_NONE=4;Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE,Module.allocate=allocate,Module.getMemory=getMemory,Module.Pointer_stringify=Pointer_stringify,Module.AsciiToString=AsciiToString,Module.stringToAscii=stringToAscii;var UTF8Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;Module.UTF8ArrayToString=UTF8ArrayToString,Module.UTF8ToString=UTF8ToString,Module.stringToUTF8Array=stringToUTF8Array,Module.stringToUTF8=stringToUTF8,Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0;Module.stackTrace=stackTrace;var WASM_PAGE_SIZE=65536,ASMJS_PAGE_SIZE=16777216,MIN_TOTAL_MEMORY=16777216,HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64,STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1,Module.reallocBuffer||(Module.reallocBuffer=function(e){var t;try{if(ArrayBuffer.transfer)t=ArrayBuffer.transfer(buffer,e);else{var r=HEAP8;t=new ArrayBuffer(e);new Int8Array(t).set(r)}}catch(e){return!1}return!!_emscripten_replace_memory(t)&&t});var byteLength;try{byteLength=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,"byteLength").get),byteLength(new ArrayBuffer(4))}catch(e){byteLength=function(e){return e.byteLength}}var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||16777216;if(TOTAL_MEMORY<TOTAL_STACK&&Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was "+TOTAL_MEMORY+"! (TOTAL_STACK="+TOTAL_STACK+")"),buffer=Module.buffer?Module.buffer:new ArrayBuffer(TOTAL_MEMORY),updateGlobalBufferViews(),HEAP32[0]=1668509029,HEAP16[1]=25459,115!==HEAPU8[2]||99!==HEAPU8[3])throw"Runtime error: expected the system to be little-endian!";Module.HEAP=HEAP,Module.buffer=buffer,Module.HEAP8=HEAP8,Module.HEAP16=HEAP16,Module.HEAP32=HEAP32,Module.HEAPU8=HEAPU8,Module.HEAPU16=HEAPU16,Module.HEAPU32=HEAPU32,Module.HEAPF32=HEAPF32,Module.HEAPF64=HEAPF64;var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;Module.addOnPreRun=addOnPreRun,Module.addOnInit=addOnInit,Module.addOnPreMain=addOnPreMain,Module.addOnExit=addOnExit,Module.addOnPostRun=addOnPostRun,Module.intArrayFromString=intArrayFromString,Module.intArrayToString=intArrayToString,Module.writeStringToMemory=writeStringToMemory,Module.writeArrayToMemory=writeArrayToMemory,Module.writeAsciiToMemory=writeAsciiToMemory,Math.imul&&-5===Math.imul(4294967295,5)||(Math.imul=function(e,t){var r=e>>>16,i=65535&e,n=t>>>16,o=65535&t;return i*o+(r*o+i*n<<16)|0}),Math.imul=Math.imul,Math.clz32||(Math.clz32=function(e){e>>>=0;for(var t=0;t<32;t++)if(e&1<<31-t)return t;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(e){return e<0?Math.ceil(e):Math.floor(e)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;Module.addRunDependency=addRunDependency,Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[];STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+6192,__ATINIT__.push(),allocate([228,2,0,0,81,16,0,0,12,3,0,0,177,16,0,0,32,0,0,0,0,0,0,0,12,3,0,0,94,16,0,0,48,0,0,0,0,0,0,0,228,2,0,0,127,16,0,0,12,3,0,0,140,16,0,0,16,0,0,0,0,0,0,0,12,3,0,0,183,17,0,0,32,0,0,0,0,0,0,0,12,3,0,0,147,17,0,0,72,0,0,0,0,0,0,0,108,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,32,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,1,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,40,20,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,56,0,0,0,1,0,0,0,5,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,37,115,40,37,117,41,58,32,65,115,115,101,114,116,105,111,110,32,102,97,105,108,117,114,101,58,32,34,37,115,34,10,0,109,95,115,105,122,101,32,60,61,32,109,95,99,97,112,97,99,105,116,121,0,46,47,105,110,99,92,99,114,110,95,100,101,99,111,109,112,46,104,0,109,105,110,95,110,101,119,95,99,97,112,97,99,105,116,121,32,60,32,40,48,120,55,70,70,70,48,48,48,48,85,32,47,32,101,108,101,109,101,110,116,95,115,105,122,101,41,0,110,101,119,95,99,97,112,97,99,105,116,121,32,38,38,32,40,110,101,119,95,99,97,112,97,99,105,116,121,32,62,32,109,95,99,97,112,97,99,105,116,121,41,0,110,117,109,95,99,111,100,101,115,91,99,93,0,115,111,114,116,101,100,95,112,111,115,32,60,32,116,111,116,97,108,95,117,115,101,100,95,115,121,109,115,0,112,67,111,100,101,115,105,122,101,115,91,115,121,109,95,105,110,100,101,120,93,32,61,61,32,99,111,100,101,115,105,122,101,0,116,32,60,32,40,49,85,32,60,60,32,116,97,98,108,101,95,98,105,116,115,41,0,109,95,108,111,111,107,117,112,91,116,93,32,61,61,32,99,85,73,78,84,51,50,95,77,65,88,0,99,114,110,100,95,109,97,108,108,111,99,58,32,115,105,122,101,32,116,111,111,32,98,105,103,0,99,114,110,100,95,109,97,108,108,111,99,58,32,111,117,116,32,111,102,32,109,101,109,111,114,121,0,40,40,117,105,110,116,51,50,41,112,95,110,101,119,32,38,32,40,67,82,78,68,95,77,73,78,95,65,76,76,79,67,95,65,76,73,71,78,77,69,78,84,32,45,32,49,41,41,32,61,61,32,48,0,99,114,110,100,95,114,101,97,108,108,111,99,58,32,98,97,100,32,112,116,114,0,99,114,110,100,95,102,114,101,101,58,32,98,97,100,32,112,116,114,0,102,97,108,115,101,0,40,116,111,116,97,108,95,115,121,109,115,32,62,61,32,49,41,32,38,38,32,40,116,111,116,97,108,95,115,121,109,115,32,60,61,32,112,114,101,102,105,120,95,99,111,100,105,110,103,58,58,99,77,97,120,83,117,112,112,111,114,116,101,100,83,121,109,115,41,0,17,18,19,20,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,16,48,0,110,117,109,95,98,105,116,115,32,60,61,32,51,50,85,0,109,95,98,105,116,95,99,111,117,110,116,32,60,61,32,99,66,105,116,66,117,102,83,105,122,101,0,116,32,33,61,32,99,85,73,78,84,51,50,95,77,65,88,0,109,111,100,101,108,46,109,95,99,111,100,101,95,115,105,122,101,115,91,115,121,109,93,32,61,61,32,108,101,110,0,0,2,3,1,0,2,3,4,5,6,7,1,40,108,101,110,32,62,61,32,49,41,32,38,38,32,40,108,101,110,32,60,61,32,99,77,97,120,69,120,112,101,99,116,101,100,67,111,100,101,83,105,122,101,41,0,105,32,60,32,109,95,115,105,122,101,0,110,101,120,116,95,108,101,118,101,108,95,111,102,115,32,62,32,99,117,114,95,108,101,118,101,108,95,111,102,115,0,1,2,2,3,3,3,3,4,0,0,0,0,0,0,1,1,0,1,0,1,0,0,1,2,1,2,0,0,0,1,0,2,1,0,2,0,0,1,2,3,110,117,109,32,38,38,32,40,110,117,109,32,61,61,32,126,110,117,109,95,99,104,101,99,107,41,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,101,120,99,101,112,116,105,111,110,32,111,102,32,116,121,112,101,32,37,115,58,32,37,115,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,101,120,99,101,112,116,105,111,110,32,111,102,32,116,121,112,101,32,37,115,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,102,111,114,101,105,103,110,32,101,120,99,101,112,116,105,111,110,0,116,101,114,109,105,110,97,116,105,110,103,0,117,110,99,97,117,103,104,116,0,83,116,57,101,120,99,101,112,116,105,111,110,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,54,95,95,115,104,105,109,95,116,121,112,101,95,105,110,102,111,69,0,83,116,57,116,121,112,101,95,105,110,102,111,0,78,49,48,95,95,99,120,120,97,98,105,118,49,50,48,95,95,115,105,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,112,116,104,114,101,97,100,95,111,110,99,101,32,102,97,105,108,117,114,101,32,105,110,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,95,102,97,115,116,40,41,0,99,97,110,110,111,116,32,99,114,101,97,116,101,32,112,116,104,114,101,97,100,32,107,101,121,32,102,111,114,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,40,41,0,99,97,110,110,111,116,32,122,101,114,111,32,111,117,116,32,116,104,114,101,97,100,32,118,97,108,117,101,32,102,111,114,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,40,41,0,116,101,114,109,105,110,97,116,101,95,104,97,110,100,108,101,114,32,117,110,101,120,112,101,99,116,101,100,108,121,32,114,101,116,117,114,110,101,100,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,57,95,95,112,111,105,110,116,101,114,95,116,121,112,101,95,105,110,102,111,69,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,112,98,97,115,101,95,116,121,112,101,95,105,110,102,111,69,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:function(e){if(!e||EXCEPTIONS.infos[e])return e;for(var t in EXCEPTIONS.infos){if(EXCEPTIONS.infos[t].adjusted===e)return t}return e},addRef:function(e){if(e){EXCEPTIONS.infos[e].refcount++}},decRef:function(e){if(e){var t=EXCEPTIONS.infos[e];assert(t.refcount>0),t.refcount--,0!==t.refcount||t.rethrown||(t.destructor&&Module.dynCall_vi(t.destructor,e),delete EXCEPTIONS.infos[e],___cxa_free_exception(e))}},clearRef:function(e){if(e){EXCEPTIONS.infos[e].refcount=0}}},SYSCALLS={varargs:0,get:function(e){return SYSCALLS.varargs+=4,HEAP32[SYSCALLS.varargs-4>>2]},getStr:function(){return Pointer_stringify(SYSCALLS.get())},get64:function(){var e=SYSCALLS.get(),t=SYSCALLS.get();return assert(e>=0?0===t:-1===t),e},getZero:function(){assert(0===SYSCALLS.get())}},cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_STATIC),PTHREAD_SPECIFIC={},PTHREAD_SPECIFIC_NEXT_KEY=1,ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};__ATEXIT__.push(function(){var e=Module._fflush;e&&e(0);var t=___syscall146.printChar;if(t){var r=___syscall146.buffers;r[1].length&&t(1,10),r[2].length&&t(2,10)}}),DYNAMICTOP_PTR=allocate(1,"i32",ALLOC_STATIC),STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP),STACK_MAX=STACK_BASE+TOTAL_STACK,DYNAMIC_BASE=Runtime.alignMemory(STACK_MAX),HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE,staticSealed=!0,Module.asmGlobalArg={Math:Math,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:1/0,byteLength:byteLength},Module.asmLibraryArg={abort:abort,assert:assert,enlargeMemory:enlargeMemory,getTotalMemory:getTotalMemory,abortOnCannotGrowMemory:abortOnCannotGrowMemory,invoke_iiii:invoke_iiii,invoke_viiiii:invoke_viiiii,invoke_vi:invoke_vi,invoke_ii:invoke_ii,invoke_viii:invoke_viii,invoke_v:invoke_v,invoke_viiiiii:invoke_viiiiii,invoke_viiii:invoke_viiii,_pthread_getspecific:_pthread_getspecific,___syscall54:___syscall54,_pthread_setspecific:_pthread_setspecific,___gxx_personality_v0:___gxx_personality_v0,___syscall6:___syscall6,___setErrNo:___setErrNo,_abort:_abort,___cxa_begin_catch:___cxa_begin_catch,_pthread_once:_pthread_once,_emscripten_memcpy_big:_emscripten_memcpy_big,_pthread_key_create:_pthread_key_create,___syscall140:___syscall140,___resumeException:___resumeException,___cxa_find_matching_catch:___cxa_find_matching_catch,___syscall146:___syscall146,__ZSt18uncaught_exceptionv:__ZSt18uncaught_exceptionv,DYNAMICTOP_PTR:DYNAMICTOP_PTR,tempDoublePtr:tempDoublePtr,ABORT:ABORT,STACKTOP:STACKTOP,STACK_MAX:STACK_MAX,cttz_i8:cttz_i8};var asm=function(e,t,r){"almost asm";function i(e){return!(16777215&rr(e)||rr(e)<=16777215||rr(e)>2147483648)&&(zt=new Vt(e),Wt=new Gt(e),jt=new Ht(e),Yt=new qt(e),Qt=new Xt(e),Kt=new Zt(e),$t=new Jt(e),tr=new er(e),r=e,!0)}function n(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,C=0;C=or,or=or+16|0,h=C;do{if(e>>>0<245){if(u=e>>>0<11?16:e+11&-8,e=u>>>3,d=0|jt[1144],3&(r=d>>>e)|0)return t=(1&r^1)+e|0,e=4616+(t<<1<<2)|0,r=e+8|0,i=0|jt[r>>2],n=i+8|0,o=0|jt[n>>2],(0|e)==(0|o)?jt[1144]=d&~(1<<t):(jt[o+12>>2]=e,jt[r>>2]=o),b=t<<3,jt[i+4>>2]=3|b,b=i+b+4|0,jt[b>>2]=1|jt[b>>2],b=n,or=C,0|b;if(c=0|jt[1146],u>>>0>c>>>0){if(0|r)return t=2<<e,t=r<<e&(t|0-t),t=(t&0-t)-1|0,a=t>>>12&16,t>>>=a,r=t>>>5&8,t>>>=r,n=t>>>2&4,t>>>=n,e=t>>>1&2,t>>>=e,i=t>>>1&1,i=(r|a|n|e|i)+(t>>>i)|0,t=4616+(i<<1<<2)|0,e=t+8|0,n=0|jt[e>>2],a=n+8|0,r=0|jt[a>>2],(0|t)==(0|r)?(e=d&~(1<<i),jt[1144]=e):(jt[r+12>>2]=t,jt[e>>2]=r,e=d),o=(i<<3)-u|0,jt[n+4>>2]=3|u,i=n+u|0,jt[i+4>>2]=1|o,jt[i+o>>2]=o,0|c&&(n=0|jt[1149],t=c>>>3,r=4616+(t<<1<<2)|0,t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=n,jt[t+12>>2]=n,jt[n+8>>2]=t,jt[n+12>>2]=r),jt[1146]=o,jt[1149]=i,b=a,or=C,0|b;if(s=0|jt[1145]){if(r=(s&0-s)-1|0,a=r>>>12&16,r>>>=a,o=r>>>5&8,r>>>=o,l=r>>>2&4,r>>>=l,i=r>>>1&2,r>>>=i,e=r>>>1&1,e=0|jt[4880+((o|a|l|i|e)+(r>>>e)<<2)>>2],r=(-8&jt[e+4>>2])-u|0,i=0|jt[e+16+((0==(0|jt[e+16>>2])&1)<<2)>>2]){do{a=(-8&jt[i+4>>2])-u|0,l=a>>>0<r>>>0,r=l?a:r,e=l?i:e,i=0|jt[i+16+((0==(0|jt[i+16>>2])&1)<<2)>>2]}while(0!=(0|i));l=e,o=r}else l=e,o=r;if(a=l+u|0,l>>>0<a>>>0){n=0|jt[l+24>>2],t=0|jt[l+12>>2];do{if((0|t)==(0|l)){if(e=l+20|0,!((t=0|jt[e>>2])||(e=l+16|0,t=0|jt[e>>2]))){r=0;break}for(;;)if(r=t+20|0,0|(i=0|jt[r>>2]))t=i,e=r;else{if(r=t+16|0,!(i=0|jt[r>>2]))break;t=i,e=r}jt[e>>2]=0,r=t}else r=0|jt[l+8>>2],jt[r+12>>2]=t,jt[t+8>>2]=r,r=t}while(0);do{if(0|n){if(t=0|jt[l+28>>2],e=4880+(t<<2)|0,(0|l)==(0|jt[e>>2])){if(jt[e>>2]=r,!r){jt[1145]=s&~(1<<t);break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|l)&1)<<2)>>2]=r,!r)break;jt[r+24>>2]=n,t=0|jt[l+16>>2],0|t&&(jt[r+16>>2]=t,jt[t+24>>2]=r),t=0|jt[l+20>>2],0|t&&(jt[r+20>>2]=t,jt[t+24>>2]=r)}}while(0);return o>>>0<16?(b=o+u|0,jt[l+4>>2]=3|b,b=l+b+4|0,jt[b>>2]=1|jt[b>>2]):(jt[l+4>>2]=3|u,jt[a+4>>2]=1|o,jt[a+o>>2]=o,0|c&&(i=0|jt[1149],t=c>>>3,r=4616+(t<<1<<2)|0,t=1<<t,d&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=d|t,t=r,e=r+8|0),jt[e>>2]=i,jt[t+12>>2]=i,jt[i+8>>2]=t,jt[i+12>>2]=r),jt[1146]=o,jt[1149]=a),b=l+8|0,or=C,0|b}d=u}else d=u}else d=u}else if(e>>>0<=4294967231)if(e=e+11|0,u=-8&e,l=0|jt[1145]){i=0-u|0,e>>>=8,e?u>>>0>16777215?s=31:(d=(e+1048320|0)>>>16&8,y=e<<d,c=(y+520192|0)>>>16&4,y<<=c,s=(y+245760|0)>>>16&2,s=14-(c|d|s)+(y<<s>>>15)|0,s=u>>>(s+7|0)&1|s<<1):s=0,r=0|jt[4880+(s<<2)>>2];e:do{if(r)for(e=0,a=u<<(31==(0|s)?0:25-(s>>>1)|0),o=0;;){if((n=(-8&jt[r+4>>2])-u|0)>>>0<i>>>0){if(!n){e=r,i=0,n=r,y=61;break e}e=r,i=n}if(n=0|jt[r+20>>2],r=0|jt[r+16+(a>>>31<<2)>>2],o=0==(0|n)|(0|n)==(0|r)?o:n,n=0==(0|r)){r=o,y=57;break}a<<=1&(1^n)}else r=0,e=0,y=57}while(0);if(57==(0|y)){if(0==(0|r)&0==(0|e)){if(e=2<<s,!(e=l&(e|0-e))){d=u;break}d=(e&0-e)-1|0,a=d>>>12&16,d>>>=a,o=d>>>5&8,d>>>=o,s=d>>>2&4,d>>>=s,c=d>>>1&2,d>>>=c,r=d>>>1&1,e=0,r=0|jt[4880+((o|a|s|c|r)+(d>>>r)<<2)>>2]}r?(n=r,y=61):(s=e,a=i)}if(61==(0|y))for(;;){if(y=0,r=(-8&jt[n+4>>2])-u|0,d=r>>>0<i>>>0,r=d?r:i,e=d?n:e,!(n=0|jt[n+16+((0==(0|jt[n+16>>2])&1)<<2)>>2])){s=e,a=r;break}i=r,y=61}if(0!=(0|s)?a>>>0<((0|jt[1146])-u|0)>>>0:0){if(o=s+u|0,s>>>0>=o>>>0)return b=0,or=C,0|b;n=0|jt[s+24>>2],t=0|jt[s+12>>2];do{if((0|t)==(0|s)){if(e=s+20|0,!((t=0|jt[e>>2])||(e=s+16|0,t=0|jt[e>>2]))){t=0;break}for(;;)if(r=t+20|0,0|(i=0|jt[r>>2]))t=i,e=r;else{if(r=t+16|0,!(i=0|jt[r>>2]))break;t=i,e=r}jt[e>>2]=0}else b=0|jt[s+8>>2],jt[b+12>>2]=t,jt[t+8>>2]=b}while(0);do{if(n){if(e=0|jt[s+28>>2],r=4880+(e<<2)|0,(0|s)==(0|jt[r>>2])){if(jt[r>>2]=t,!t){i=l&~(1<<e),jt[1145]=i;break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|s)&1)<<2)>>2]=t,!t){i=l;break}jt[t+24>>2]=n,e=0|jt[s+16>>2],0|e&&(jt[t+16>>2]=e,jt[e+24>>2]=t),e=0|jt[s+20>>2],e?(jt[t+20>>2]=e,jt[e+24>>2]=t,i=l):i=l}else i=l}while(0);do{if(a>>>0>=16){if(jt[s+4>>2]=3|u,jt[o+4>>2]=1|a,jt[o+a>>2]=a,t=a>>>3,a>>>0<256){r=4616+(t<<1<<2)|0,e=0|jt[1144],t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=o,jt[t+12>>2]=o,jt[o+8>>2]=t,jt[o+12>>2]=r;break}if(t=a>>>8,t?a>>>0>16777215?t=31:(y=(t+1048320|0)>>>16&8,b=t<<y,v=(b+520192|0)>>>16&4,b<<=v,t=(b+245760|0)>>>16&2,t=14-(v|y|t)+(b<<t>>>15)|0,t=a>>>(t+7|0)&1|t<<1):t=0,r=4880+(t<<2)|0,jt[o+28>>2]=t,e=o+16|0,jt[e+4>>2]=0,jt[e>>2]=0,e=1<<t,!(i&e)){jt[1145]=i|e,jt[r>>2]=o,jt[o+24>>2]=r,jt[o+12>>2]=o,jt[o+8>>2]=o;break}for(e=a<<(31==(0|t)?0:25-(t>>>1)|0),r=0|jt[r>>2];;){if((-8&jt[r+4>>2]|0)==(0|a)){y=97;break}if(i=r+16+(e>>>31<<2)|0,!(t=0|jt[i>>2])){y=96;break}e<<=1,r=t}if(96==(0|y)){jt[i>>2]=o,jt[o+24>>2]=r,jt[o+12>>2]=o,jt[o+8>>2]=o;break}if(97==(0|y)){y=r+8|0,b=0|jt[y>>2],jt[b+12>>2]=o,jt[y>>2]=o,jt[o+8>>2]=b,jt[o+12>>2]=r,jt[o+24>>2]=0;break}}else b=a+u|0,jt[s+4>>2]=3|b,b=s+b+4|0,jt[b>>2]=1|jt[b>>2]}while(0);return b=s+8|0,or=C,0|b}d=u}else d=u;else d=-1}while(0);if((r=0|jt[1146])>>>0>=d>>>0)return t=r-d|0,e=0|jt[1149],t>>>0>15?(b=e+d|0,jt[1149]=b,jt[1146]=t,jt[b+4>>2]=1|t,jt[b+t>>2]=t,jt[e+4>>2]=3|d):(jt[1146]=0,jt[1149]=0,jt[e+4>>2]=3|r,b=e+r+4|0,jt[b>>2]=1|jt[b>>2]),b=e+8|0,or=C,0|b;if((a=0|jt[1147])>>>0>d>>>0)return v=a-d|0,jt[1147]=v,b=0|jt[1150],y=b+d|0,jt[1150]=y,jt[y+4>>2]=1|v,jt[b+4>>2]=3|d,b=b+8|0,or=C,0|b;if(0|jt[1262]?e=0|jt[1264]:(jt[1264]=4096,jt[1263]=4096,jt[1265]=-1,jt[1266]=-1,jt[1267]=0,jt[1255]=0,e=-16&h^1431655768,jt[h>>2]=e,jt[1262]=e,e=4096),s=d+48|0,l=d+47|0,o=e+l|0,n=0-e|0,(u=o&n)>>>0<=d>>>0)return b=0,or=C,0|b;if(e=0|jt[1254],0|e?(c=0|jt[1252],(h=c+u|0)>>>0<=c>>>0|h>>>0>e>>>0):0)return b=0,or=C,0|b;e:do{if(4&jt[1255])t=0,y=133;else{r=0|jt[1150];t:do{if(r){for(i=5024;;){if(e=0|jt[i>>2],e>>>0<=r>>>0?(m=i+4|0,(e+(0|jt[m>>2])|0)>>>0>r>>>0):0)break;if(!(e=0|jt[i+8>>2])){y=118;break t}i=e}if((t=o-a&n)>>>0<2147483647)if((0|(e=0|be(0|t)))==((0|jt[i>>2])+(0|jt[m>>2])|0)){if(-1!=(0|e)){a=t,o=e,y=135;break e}}else i=e,y=126;else t=0}else y=118}while(0);do{if(118==(0|y))if(r=0|be(0),-1!=(0|r)?(t=r,p=0|jt[1263],f=p+-1|0,t=(0==(f&t|0)?0:(f+t&0-p)-t|0)+u|0,p=0|jt[1252],f=t+p|0,t>>>0>d>>>0&t>>>0<2147483647):0){if(m=0|jt[1254],0|m?f>>>0<=p>>>0|f>>>0>m>>>0:0){t=0;break}if((0|(e=0|be(0|t)))==(0|r)){a=t,o=r,y=135;break e}i=e,y=126}else t=0}while(0);do{if(126==(0|y)){if(r=0-t|0,!(s>>>0>t>>>0&t>>>0<2147483647&-1!=(0|i))){if(-1==(0|i)){t=0;break}a=t,o=i,y=135;break e}if(e=0|jt[1264],(e=l-t+e&0-e)>>>0>=2147483647){a=t,o=i,y=135;break e}if(-1==(0|be(0|e))){be(0|r),t=0;break}a=e+t|0,o=i,y=135;break e}}while(0);jt[1255]=4|jt[1255],y=133}}while(0);if(!(133==(0|y)?u>>>0<2147483647:0)||(v=0|be(0|u),m=0|be(0),g=m-v|0,_=g>>>0>(d+40|0)>>>0, +-1==(0|v)|1^_|v>>>0<m>>>0&-1!=(0|v)&-1!=(0|m)^1)||(a=_?g:t,o=v,y=135),135==(0|y)){t=(0|jt[1252])+a|0,jt[1252]=t,t>>>0>(0|jt[1253])>>>0&&(jt[1253]=t),l=0|jt[1150];do{if(l){for(t=5024;;){if(e=0|jt[t>>2],r=t+4|0,i=0|jt[r>>2],(0|o)==(e+i|0)){y=145;break}if(!(n=0|jt[t+8>>2]))break;t=n}if((145==(0|y)?0==(8&jt[t+12>>2]|0):0)?l>>>0<o>>>0&l>>>0>=e>>>0:0){jt[r>>2]=i+a,b=l+8|0,b=0==(7&b|0)?0:0-b&7,y=l+b|0,b=(0|jt[1147])+(a-b)|0,jt[1150]=y,jt[1147]=b,jt[y+4>>2]=1|b,jt[y+b+4>>2]=40,jt[1151]=jt[1266];break}for(o>>>0<(0|jt[1148])>>>0&&(jt[1148]=o),r=o+a|0,t=5024;;){if((0|jt[t>>2])==(0|r)){y=153;break}if(!(e=0|jt[t+8>>2]))break;t=e}if(153==(0|y)?0==(8&jt[t+12>>2]|0):0){jt[t>>2]=o,c=t+4|0,jt[c>>2]=(0|jt[c>>2])+a,c=o+8|0,c=o+(0==(7&c|0)?0:0-c&7)|0,t=r+8|0,t=r+(0==(7&t|0)?0:0-t&7)|0,u=c+d|0,s=t-c-d|0,jt[c+4>>2]=3|d;do{if((0|t)!=(0|l)){if((0|t)==(0|jt[1149])){b=(0|jt[1146])+s|0,jt[1146]=b,jt[1149]=u,jt[u+4>>2]=1|b,jt[u+b>>2]=b;break}if(1==(3&(e=0|jt[t+4>>2])|0)){a=-8&e,i=e>>>3;e:do{if(e>>>0<256){if(e=0|jt[t+8>>2],(0|(r=0|jt[t+12>>2]))==(0|e)){jt[1144]=jt[1144]&~(1<<i);break}jt[e+12>>2]=r,jt[r+8>>2]=e;break}o=0|jt[t+24>>2],e=0|jt[t+12>>2];do{if((0|e)==(0|t)){if(i=t+16|0,r=i+4|0,!(e=0|jt[r>>2])){if(!(e=0|jt[i>>2])){e=0;break}r=i}for(;;)if(i=e+20|0,0|(n=0|jt[i>>2]))e=n,r=i;else{if(i=e+16|0,!(n=0|jt[i>>2]))break;e=n,r=i}jt[r>>2]=0}else b=0|jt[t+8>>2],jt[b+12>>2]=e,jt[e+8>>2]=b}while(0);if(!o)break;r=0|jt[t+28>>2],i=4880+(r<<2)|0;do{if((0|t)==(0|jt[i>>2])){if(jt[i>>2]=e,0|e)break;jt[1145]=jt[1145]&~(1<<r);break e}if(jt[o+16+(((0|jt[o+16>>2])!=(0|t)&1)<<2)>>2]=e,!e)break e}while(0);if(jt[e+24>>2]=o,r=t+16|0,i=0|jt[r>>2],0|i&&(jt[e+16>>2]=i,jt[i+24>>2]=e),!(r=0|jt[r+4>>2]))break;jt[e+20>>2]=r,jt[r+24>>2]=e}while(0);t=t+a|0,n=a+s|0}else n=s;if(t=t+4|0,jt[t>>2]=-2&jt[t>>2],jt[u+4>>2]=1|n,jt[u+n>>2]=n,t=n>>>3,n>>>0<256){r=4616+(t<<1<<2)|0,e=0|jt[1144],t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=u,jt[t+12>>2]=u,jt[u+8>>2]=t,jt[u+12>>2]=r;break}t=n>>>8;do{if(t){if(n>>>0>16777215){t=31;break}y=(t+1048320|0)>>>16&8,b=t<<y,v=(b+520192|0)>>>16&4,b<<=v,t=(b+245760|0)>>>16&2,t=14-(v|y|t)+(b<<t>>>15)|0,t=n>>>(t+7|0)&1|t<<1}else t=0}while(0);if(i=4880+(t<<2)|0,jt[u+28>>2]=t,e=u+16|0,jt[e+4>>2]=0,jt[e>>2]=0,e=0|jt[1145],r=1<<t,!(e&r)){jt[1145]=e|r,jt[i>>2]=u,jt[u+24>>2]=i,jt[u+12>>2]=u,jt[u+8>>2]=u;break}for(e=n<<(31==(0|t)?0:25-(t>>>1)|0),r=0|jt[i>>2];;){if((-8&jt[r+4>>2]|0)==(0|n)){y=194;break}if(i=r+16+(e>>>31<<2)|0,!(t=0|jt[i>>2])){y=193;break}e<<=1,r=t}if(193==(0|y)){jt[i>>2]=u,jt[u+24>>2]=r,jt[u+12>>2]=u,jt[u+8>>2]=u;break}if(194==(0|y)){y=r+8|0,b=0|jt[y>>2],jt[b+12>>2]=u,jt[y>>2]=u,jt[u+8>>2]=b,jt[u+12>>2]=r,jt[u+24>>2]=0;break}}else b=(0|jt[1147])+s|0,jt[1147]=b,jt[1150]=u,jt[u+4>>2]=1|b}while(0);return b=c+8|0,or=C,0|b}for(t=5024;;){if(e=0|jt[t>>2],e>>>0<=l>>>0?(b=e+(0|jt[t+4>>2])|0)>>>0>l>>>0:0)break;t=0|jt[t+8>>2]}n=b+-47|0,e=n+8|0,e=n+(0==(7&e|0)?0:0-e&7)|0,n=l+16|0,e=e>>>0<n>>>0?l:e,t=e+8|0,r=o+8|0,r=0==(7&r|0)?0:0-r&7,y=o+r|0,r=a+-40-r|0,jt[1150]=y,jt[1147]=r,jt[y+4>>2]=1|r,jt[y+r+4>>2]=40,jt[1151]=jt[1266],r=e+4|0,jt[r>>2]=27,jt[t>>2]=jt[1256],jt[t+4>>2]=jt[1257],jt[t+8>>2]=jt[1258],jt[t+12>>2]=jt[1259],jt[1256]=o,jt[1257]=a,jt[1259]=0,jt[1258]=t,t=e+24|0;do{y=t,t=t+4|0,jt[t>>2]=7}while((y+8|0)>>>0<b>>>0);if((0|e)!=(0|l)){if(o=e-l|0,jt[r>>2]=-2&jt[r>>2],jt[l+4>>2]=1|o,jt[e>>2]=o,t=o>>>3,o>>>0<256){r=4616+(t<<1<<2)|0,e=0|jt[1144],t=1<<t,e&t?(e=r+8|0,t=0|jt[e>>2]):(jt[1144]=e|t,t=r,e=r+8|0),jt[e>>2]=l,jt[t+12>>2]=l,jt[l+8>>2]=t,jt[l+12>>2]=r;break}if(t=o>>>8,t?o>>>0>16777215?r=31:(y=(t+1048320|0)>>>16&8,b=t<<y,v=(b+520192|0)>>>16&4,b<<=v,r=(b+245760|0)>>>16&2,r=14-(v|y|r)+(b<<r>>>15)|0,r=o>>>(r+7|0)&1|r<<1):r=0,i=4880+(r<<2)|0,jt[l+28>>2]=r,jt[l+20>>2]=0,jt[n>>2]=0,t=0|jt[1145],e=1<<r,!(t&e)){jt[1145]=t|e,jt[i>>2]=l,jt[l+24>>2]=i,jt[l+12>>2]=l,jt[l+8>>2]=l;break}for(e=o<<(31==(0|r)?0:25-(r>>>1)|0),r=0|jt[i>>2];;){if((-8&jt[r+4>>2]|0)==(0|o)){y=216;break}if(i=r+16+(e>>>31<<2)|0,!(t=0|jt[i>>2])){y=215;break}e<<=1,r=t}if(215==(0|y)){jt[i>>2]=l,jt[l+24>>2]=r,jt[l+12>>2]=l,jt[l+8>>2]=l;break}if(216==(0|y)){y=r+8|0,b=0|jt[y>>2],jt[b+12>>2]=l,jt[y>>2]=l,jt[l+8>>2]=b,jt[l+12>>2]=r,jt[l+24>>2]=0;break}}}else{b=0|jt[1148],0==(0|b)|o>>>0<b>>>0&&(jt[1148]=o),jt[1256]=o,jt[1257]=a,jt[1259]=0,jt[1153]=jt[1262],jt[1152]=-1,t=0;do{b=4616+(t<<1<<2)|0,jt[b+12>>2]=b,jt[b+8>>2]=b,t=t+1|0}while(32!=(0|t));b=o+8|0,b=0==(7&b|0)?0:0-b&7,y=o+b|0,b=a+-40-b|0,jt[1150]=y,jt[1147]=b,jt[y+4>>2]=1|b,jt[y+b+4>>2]=40,jt[1151]=jt[1266]}}while(0);if((t=0|jt[1147])>>>0>d>>>0)return v=t-d|0,jt[1147]=v,b=0|jt[1150],y=b+d|0,jt[1150]=y,jt[y+4>>2]=1|v,jt[b+4>>2]=3|d,b=b+8|0,or=C,0|b}return b=0|Et(),jt[b>>2]=12,b=0,or=C,0|b}function o(e,t,r,i,n,o){e|=0,t=+t,r|=0,i|=0,n|=0,o|=0;var a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,C=0,S=0,w=0,T=0,E=0,A=0,x=0,P=0;P=or,or=or+560|0,l=P+8|0,g=P,x=P+524|0,A=x,u=P+512|0,jt[g>>2]=0,E=u+12|0,Ze(t),(0|cr)<0?(t=-t,w=1,S=2087):(w=0!=(2049&n|0)&1,S=0==(2048&n|0)?0==(1&n|0)?2088:2093:2090),Ze(t),T=2146435072&cr;do{if(T>>>0<2146435072|2146435072==(0|T)&!1){if(p=2*+wt(t,g),a=0!=p,a&&(jt[g>>2]=(0|jt[g>>2])-1),97==(0|(v=32|o))){f=32&o,h=0==(0|f)?S:S+9|0,d=2|w,a=12-i|0;do{if(!(i>>>0>11|0==(0|a))){t=8;do{a=a+-1|0,t*=16}while(0!=(0|a));if(45==(0|zt[h>>0])){t=-(t+(-p-t));break}t=p+t-t;break}t=p}while(0);s=0|jt[g>>2],a=(0|s)<0?0-s|0:s,a=0|ue(a,((0|a)<0)<<31>>31,E),(0|a)==(0|E)&&(a=u+11|0,zt[a>>0]=48),zt[a+-1>>0]=43+(s>>31&2),c=a+-2|0,zt[c>>0]=o+15,u=(0|i)<1,l=0==(8&n|0),a=x;do{T=~~t,s=a+1|0,zt[a>>0]=Yt[2122+T>>0]|f,t=16*(t-+(0|T)),1!=(s-A|0)||l&u&0==t?a=s:(zt[s>>0]=46,a=a+2|0)}while(0!=t);T=a-A|0,A=E-c|0,E=0!=(0|i)&(T+-2|0)<(0|i)?i+2|0:T,a=A+d+E|0,fe(e,32,r,a,n),it(e,h,d),fe(e,48,r,a,65536^n),it(e,x,T),fe(e,48,E-T|0,0,0),it(e,c,A),fe(e,32,r,a,8192^n);break}s=(0|i)<0?6:i,a?(a=(0|jt[g>>2])-28|0,jt[g>>2]=a,t=268435456*p):(t=p,a=0|jt[g>>2]),T=(0|a)<0?l:l+288|0,l=T;do{b=~~t>>>0,jt[l>>2]=b,l=l+4|0,t=1e9*(t-+(b>>>0))}while(0!=t);if((0|a)>0)for(u=T,d=l;;){if(c=(0|a)<29?a:29,(a=d+-4|0)>>>0>=u>>>0){l=0;do{y=0|We(0|jt[a>>2],0,0|c),y=0|Ke(0|y,0|cr,0|l,0),b=cr,_=0|Oe(0|y,0|b,1e9,0),jt[a>>2]=_,l=0|ct(0|y,0|b,1e9,0),a=a+-4|0}while(a>>>0>=u>>>0);l&&(u=u+-4|0,jt[u>>2]=l)}for(l=d;;){if(l>>>0<=u>>>0)break;if(a=l+-4|0,0|jt[a>>2])break;l=a}if(a=(0|jt[g>>2])-c|0,jt[g>>2]=a,!((0|a)>0))break;d=l}else u=T;if((0|a)<0){i=1+((s+25|0)/9|0)|0,m=102==(0|v);do{if(f=0-a|0,f=(0|f)<9?f:9,u>>>0<l>>>0){c=(1<<f)-1|0,d=1e9>>>f,h=0,a=u;do{b=0|jt[a>>2],jt[a>>2]=(b>>>f)+h,h=0|dr(b&c,d),a=a+4|0}while(a>>>0<l>>>0);a=0==(0|jt[u>>2])?u+4|0:u,h?(jt[l>>2]=h,u=a,a=l+4|0):(u=a,a=l)}else u=0==(0|jt[u>>2])?u+4|0:u,a=l;l=m?T:u,l=(a-l>>2|0)>(0|i)?l+(i<<2)|0:a,a=(0|jt[g>>2])+f|0,jt[g>>2]=a}while((0|a)<0);a=u,i=l}else a=u,i=l;if(b=T,a>>>0<i>>>0){if(l=9*(b-a>>2)|0,(c=0|jt[a>>2])>>>0>=10){u=10;do{u=10*u|0,l=l+1|0}while(c>>>0>=u>>>0)}}else l=0;if(m=103==(0|v),_=0!=(0|s),(0|(u=s-(102!=(0|v)?l:0)+((_&m)<<31>>31)|0))<((9*(i-b>>2)|0)-9|0)){if(u=u+9216|0,f=T+4+(((0|u)/9|0)-1024<<2)|0,(0|(u=1+((0|u)%9|0)|0))<9){c=10;do{c=10*c|0,u=u+1|0}while(9!=(0|u))}else c=10;if(d=0|jt[f>>2],h=(d>>>0)%(c>>>0)|0,(u=(f+4|0)==(0|i))&0==(0|h))u=f;else if(p=0==(1&((d>>>0)/(c>>>0)|0)|0)?9007199254740992:9007199254740994,y=(0|c)/2|0,t=h>>>0<y>>>0?.5:u&(0|h)==(0|y)?1:1.5,w&&(y=45==(0|zt[S>>0]),t=y?-t:t,p=y?-p:p),u=d-h|0,jt[f>>2]=u,p+t!=p){if(y=u+c|0,jt[f>>2]=y,y>>>0>999999999)for(l=f;;){if(u=l+-4|0,jt[l>>2]=0,u>>>0<a>>>0&&(a=a+-4|0,jt[a>>2]=0),y=1+(0|jt[u>>2])|0,jt[u>>2]=y,!(y>>>0>999999999))break;l=u}else u=f;if(l=9*(b-a>>2)|0,(d=0|jt[a>>2])>>>0>=10){c=10;do{c=10*c|0,l=l+1|0}while(d>>>0>=c>>>0)}}else u=f;u=u+4|0,u=i>>>0>u>>>0?u:i,y=a}else u=i,y=a;for(v=u;;){if(v>>>0<=y>>>0){g=0;break}if(a=v+-4|0,0|jt[a>>2]){g=1;break}v=a}i=0-l|0;do{if(m){if(a=(1&(1^_))+s|0,(0|a)>(0|l)&(0|l)>-5?(c=o+-1|0,s=a+-1-l|0):(c=o+-2|0,s=a+-1|0),!(a=8&n)){if(g?0!=(0|(C=0|jt[v+-4>>2])):0)if((C>>>0)%10|0)u=0;else{u=0,a=10;do{a=10*a|0,u=u+1|0}while(!(0|(C>>>0)%(a>>>0)))}else u=9;if(a=(9*(v-b>>2)|0)-9|0,102==(32|c)){f=a-u|0,f=(0|f)>0?f:0,s=(0|s)<(0|f)?s:f,f=0;break}f=a+l-u|0,f=(0|f)>0?f:0,s=(0|s)<(0|f)?s:f,f=0;break}f=a}else c=o,f=8&n}while(0);if(m=s|f,d=0!=(0|m)&1,h=102==(32|c))_=0,a=(0|l)>0?l:0;else{if(a=(0|l)<0?i:l,a=0|ue(a,((0|a)<0)<<31>>31,E),((u=E)-a|0)<2)do{a=a+-1|0,zt[a>>0]=48}while((u-a|0)<2);zt[a+-1>>0]=43+(l>>31&2),a=a+-2|0,zt[a>>0]=c,_=a,a=u-a|0}if(a=w+1+s+d+a|0,fe(e,32,r,a,n),it(e,S,w),fe(e,48,r,a,65536^n),h){c=y>>>0>T>>>0?T:y,f=x+9|0,d=f,h=x+8|0,u=c;do{if(l=0|ue(0|jt[u>>2],0,f),(0|u)==(0|c))(0|l)==(0|f)&&(zt[h>>0]=48,l=h);else if(l>>>0>x>>>0){ee(0|x,48,l-A|0);do{l=l+-1|0}while(l>>>0>x>>>0)}it(e,l,d-l|0),u=u+4|0}while(u>>>0<=T>>>0);if(0|m&&it(e,2138,1),u>>>0<v>>>0&(0|s)>0)for(;;){if((l=0|ue(0|jt[u>>2],0,f))>>>0>x>>>0){ee(0|x,48,l-A|0);do{l=l+-1|0}while(l>>>0>x>>>0)}if(it(e,l,(0|s)<9?s:9),u=u+4|0,l=s+-9|0,!(u>>>0<v>>>0&(0|s)>9)){s=l;break}s=l}fe(e,48,s+9|0,9,0)}else{if(m=g?v:y+4|0,(0|s)>-1){g=x+9|0,f=0==(0|f),i=g,d=0-A|0,h=x+8|0,c=y;do{l=0|ue(0|jt[c>>2],0,g),(0|l)==(0|g)&&(zt[h>>0]=48,l=h);do{if((0|c)==(0|y)){if(u=l+1|0,it(e,l,1),f&(0|s)<1){l=u;break}it(e,2138,1),l=u}else{if(l>>>0<=x>>>0)break;ee(0|x,48,l+d|0);do{l=l+-1|0}while(l>>>0>x>>>0)}}while(0);A=i-l|0,it(e,l,(0|s)>(0|A)?A:s),s=s-A|0,c=c+4|0}while(c>>>0<m>>>0&(0|s)>-1)}fe(e,48,s+18|0,18,0),it(e,_,E-_|0)}fe(e,32,r,a,8192^n)}else x=0!=(32&o|0),a=w+3|0,fe(e,32,r,a,-65537&n),it(e,S,w),it(e,t!=t|!1?x?2114:2118:x?2106:2110,3),fe(e,32,r,a,8192^n)}while(0);return or=P,0|((0|a)<(0|r)?r:a)}function a(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,C=0,S=0,T=0,E=0,A=0,x=0,P=0,D=0;D=or,or=or+64|0,E=D+16|0,A=D,S=D+24|0,x=D+8|0,P=D+20|0,jt[E>>2]=t,y=0!=(0|e),b=S+40|0,C=b,S=S+39|0,T=x+4|0,s=0,a=0,d=0;e:for(;;){do{if((0|a)>-1){if((0|s)>(2147483647-a|0)){a=0|Et(),jt[a>>2]=75,a=-1;break}a=s+a|0;break}}while(0);if(!((s=0|zt[t>>0])<<24>>24)){v=87;break}l=t;t:for(;;){switch(s<<24>>24){case 37:s=l,v=9;break t;case 0:s=l;break t}_=l+1|0,jt[E>>2]=_,s=0|zt[_>>0],l=_}t:do{if(9==(0|v))for(;;){if(v=0,37!=(0|zt[l+1>>0]))break t;if(s=s+1|0,l=l+2|0,jt[E>>2]=l,37!=(0|zt[l>>0]))break;v=9}}while(0);if(s=s-t|0,y&&it(e,t,s),0|s)t=l;else{u=l+1|0,s=(0|zt[u>>0])-48|0,s>>>0<10?(_=36==(0|zt[l+2>>0]),g=_?s:-1,d=_?1:d,u=_?l+3|0:u):g=-1,jt[E>>2]=u,s=0|zt[u>>0],l=(s<<24>>24)-32|0;t:do{if(l>>>0<32)for(c=0,h=s;;){if(!(75913&(s=1<<l))){s=h;break t}if(c|=s,u=u+1|0,jt[E>>2]=u,s=0|zt[u>>0],(l=(s<<24>>24)-32|0)>>>0>=32)break;h=s}else c=0}while(0);if(s<<24>>24==42){if(l=u+1|0,s=(0|zt[l>>0])-48|0,s>>>0<10?36==(0|zt[u+2>>0]):0)jt[n+(s<<2)>>2]=10,s=0|jt[i+((0|zt[l>>0])-48<<3)>>2],d=1,u=u+3|0;else{if(0|d){a=-1;break}y?(d=3+(0|jt[r>>2])&-4,s=0|jt[d>>2],jt[r>>2]=d+4,d=0,u=l):(s=0,d=0,u=l)}jt[E>>2]=u,_=(0|s)<0,s=_?0-s|0:s,c=_?8192|c:c}else{if((0|(s=0|Te(E)))<0){a=-1;break}u=0|jt[E>>2]}do{if(46==(0|zt[u>>0])){if(42!=(0|zt[u+1>>0])){jt[E>>2]=u+1,l=0|Te(E),u=0|jt[E>>2];break}if(h=u+2|0,l=(0|zt[h>>0])-48|0,l>>>0<10?36==(0|zt[u+3>>0]):0){jt[n+(l<<2)>>2]=10,l=0|jt[i+((0|zt[h>>0])-48<<3)>>2],u=u+4|0,jt[E>>2]=u;break}if(0|d){a=-1;break e}y?(_=3+(0|jt[r>>2])&-4,l=0|jt[_>>2],jt[r>>2]=_+4):l=0,jt[E>>2]=h,u=h}else l=-1}while(0);for(m=0;;){if(((0|zt[u>>0])-65|0)>>>0>57){a=-1;break e}if(_=u+1|0,jt[E>>2]=_,h=0|zt[(0|zt[u>>0])-65+(1606+(58*m|0))>>0],!(((p=255&h)+-1|0)>>>0<8))break;m=p,u=_}if(!(h<<24>>24)){a=-1;break}f=(0|g)>-1;do{if(h<<24>>24==19){if(f){a=-1;break e}v=49}else{if(f){jt[n+(g<<2)>>2]=p,f=i+(g<<3)|0,g=0|jt[f+4>>2],v=A,jt[v>>2]=jt[f>>2],jt[v+4>>2]=g,v=49;break}if(!y){a=0;break e}w(A,p,r)}}while(0);if(49!=(0|v)||(v=0,y)){u=0|zt[u>>0],u=0!=(0|m)&3==(15&u|0)?-33&u:u,f=-65537&c,g=0==(8192&c|0)?c:f;t:do{switch(0|u){case 110:switch((255&m)<<24>>24){case 0:case 1:jt[jt[A>>2]>>2]=a,s=0,t=_;continue e;case 2:s=0|jt[A>>2],jt[s>>2]=a,jt[s+4>>2]=((0|a)<0)<<31>>31,s=0,t=_;continue e;case 3:Wt[jt[A>>2]>>1]=a,s=0,t=_;continue e;case 4:zt[jt[A>>2]>>0]=a,s=0,t=_;continue e;case 6:jt[jt[A>>2]>>2]=a,s=0,t=_;continue e;case 7:s=0|jt[A>>2],jt[s>>2]=a,jt[s+4>>2]=((0|a)<0)<<31>>31,s=0,t=_;continue e;default:s=0,t=_;continue e}case 112:u=120,l=l>>>0>8?l:8,t=8|g,v=61;break;case 88:case 120:t=g,v=61;break;case 111:u=A,t=0|jt[u>>2],u=0|jt[u+4>>2],p=0|De(t,u,b),f=C-p|0,c=0,h=2070,l=0==(8&g|0)|(0|l)>(0|f)?l:f+1|0,f=g,v=67;break;case 105:case 100:if(u=A,t=0|jt[u>>2],(0|(u=0|jt[u+4>>2]))<0){t=0|Ye(0,0,0|t,0|u),u=cr,c=A,jt[c>>2]=t,jt[c+4>>2]=u,c=1,h=2070,v=66;break t}c=0!=(2049&g|0)&1,h=0==(2048&g|0)?0==(1&g|0)?2070:2072:2071,v=66;break t;case 117:u=A,c=0,h=2070,t=0|jt[u>>2],u=0|jt[u+4>>2],v=66;break;case 99:zt[S>>0]=jt[A>>2],t=S,c=0,h=2070,p=b,u=1,l=f;break;case 109:u=0|Et(),u=0|at(0|jt[u>>2]),v=71;break;case 115:u=0|jt[A>>2],u=0|u?u:2080,v=71;break;case 67:jt[x>>2]=jt[A>>2],jt[T>>2]=0,jt[A>>2]=x,p=-1,u=x,v=75;break;case 83:t=0|jt[A>>2],l?(p=l,u=t,v=75):(fe(e,32,s,0,g),t=0,v=84);break;case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:s=0|o(e,+tr[A>>3],s,l,g,u),t=_;continue e;default:c=0,h=2070,p=b,u=l,l=g}}while(0);t:do{if(61==(0|v))g=A,m=0|jt[g>>2],g=0|jt[g+4>>2],p=0|Ee(m,g,b,32&u),h=0==(8&t|0)|0==(0|m)&0==(0|g),c=h?0:2,h=h?2070:2070+(u>>4)|0,f=t,t=m,u=g,v=67;else if(66==(0|v))p=0|ue(t,u,b),f=g,v=67;else if(71==(0|v))v=0,g=0|z(u,0,l),m=0==(0|g),t=u,c=0,h=2070,p=m?u+l|0:g,u=m?l:g-u|0,l=f;else if(75==(0|v)){for(v=0,h=u,t=0,l=0;;){if(!(c=0|jt[h>>2]))break;if((0|(l=0|st(P,c)))<0|l>>>0>(p-t|0)>>>0)break;if(t=l+t|0,!(p>>>0>t>>>0))break;h=h+4|0}if((0|l)<0){a=-1;break e}if(fe(e,32,s,t,g),t)for(c=0;;){if(!(l=0|jt[u>>2])){v=84;break t}if(l=0|st(P,l),(0|(c=l+c|0))>(0|t)){v=84;break t}if(it(e,P,l),c>>>0>=t>>>0){v=84;break}u=u+4|0}else t=0,v=84}}while(0);if(67==(0|v))v=0,u=0!=(0|t)|0!=(0|u),g=0!=(0|l)|u,u=C-p+(1&(1^u))|0,t=g?p:b,p=b,u=g?(0|l)>(0|u)?l:u:l,l=(0|l)>-1?-65537&f:f;else if(84==(0|v)){v=0,fe(e,32,s,t,8192^g),s=(0|s)>(0|t)?s:t,t=_;continue}m=p-t|0,f=(0|u)<(0|m)?m:u,g=f+c|0,s=(0|s)<(0|g)?g:s,fe(e,32,s,g,l),it(e,h,c),fe(e,48,s,g,65536^l),fe(e,48,f,m,0),it(e,t,m),fe(e,32,s,g,8192^l),t=_}else s=0,t=_}}e:do{if(87==(0|v)&&!e)if(d){for(a=1;;){if(!(t=0|jt[n+(a<<2)>>2]))break;if(w(i+(a<<3)|0,t,r),(0|(a=a+1|0))>=10){a=1;break e}}for(;;){if(0|jt[n+(a<<2)>>2]){a=-1;break e}if((0|(a=a+1|0))>=10){a=1;break}}}else a=0}while(0);return or=D,0|a}function s(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,A=0,x=0,P=0;if(P=or,or=or+704|0,w=P+144|0,S=P+128|0,b=P+112|0,y=P+96|0,v=P+80|0,_=P+64|0,g=P+48|0,T=P+32|0,c=P+16|0,s=P,h=P+184|0,x=P+160|0,!(p=0|H(e,14)))return Z(t),x=1,or=P,0|x;if(f=t+4|0,m=t+8|0,(0|(r=0|jt[m>>2]))!=(0|p)){if(r>>>0<=p>>>0){do{if((0|jt[t+12>>2])>>>0<p>>>0){if(0|E(f,p,(r+1|0)==(0|p),1,0)){r=0|jt[m>>2];break}return zt[t+16>>0]=1,x=0,or=P,0|x}}while(0);ee((0|jt[f>>2])+r|0,0,p-r|0)}jt[m>>2]=p}if(ee(0|jt[f>>2],0,0|p),d=e+20|0,(0|(r=0|jt[d>>2]))<5){o=e+4|0,a=e+8|0,n=e+16|0;do{i=0|jt[o>>2],(0|i)==(0|jt[a>>2])?i=0:(jt[o>>2]=i+1,i=0|Yt[i>>0]),r=r+8|0,jt[d>>2]=r,(0|r)>=33&&(jt[s>>2]=866,jt[s+4>>2]=3208,jt[s+8>>2]=1366,Ve(h,812,s),he(h),r=0|jt[d>>2]),i=i<<32-r|jt[n>>2],jt[n>>2]=i}while((0|r)<5)}else i=e+16|0,n=i,i=0|jt[i>>2];if(u=i>>>27,jt[n>>2]=i<<5,jt[d>>2]=r+-5,(u+-1|0)>>>0>20)return x=0,or=P,0|x;jt[x+20>>2]=0,jt[x>>2]=0,jt[x+4>>2]=0,jt[x+8>>2]=0,jt[x+12>>2]=0,zt[x+16>>0]=0,r=x+4|0,i=x+8|0;e:do{if(0|E(r,21,0,1,0)){o=0|jt[i>>2],l=0|jt[r>>2],ee(l+o|0,0,21-o|0),jt[i>>2]=21,o=e+4|0,a=e+8|0,s=e+16|0,n=0;do{if((0|(r=0|jt[d>>2]))<3)do{i=0|jt[o>>2],(0|i)==(0|jt[a>>2])?i=0:(jt[o>>2]=i+1,i=0|Yt[i>>0]),r=r+8|0,jt[d>>2]=r,(0|r)>=33&&(jt[c>>2]=866,jt[c+4>>2]=3208,jt[c+8>>2]=1366,Ve(h,812,c),he(h),r=0|jt[d>>2]),i=i<<32-r|jt[s>>2],jt[s>>2]=i}while((0|r)<3);else i=0|jt[s>>2];jt[s>>2]=i<<3,jt[d>>2]=r+-3,zt[l+(0|Yt[1327+n>>0])>>0]=i>>>29,n=n+1|0}while((0|n)!=(0|u));if(0|k(x)){s=e+4|0,l=e+8|0,u=e+16|0,r=0;t:do{a=p-r|0,n=0|C(e,x);r:do{if(n>>>0<17)(0|jt[m>>2])>>>0<=r>>>0&&(jt[T>>2]=866,jt[T+4>>2]=910,jt[T+8>>2]=1497,Ve(h,812,T),he(h)),zt[(0|jt[f>>2])+r>>0]=n,r=r+1|0;else switch(0|n){case 17:if((0|(i=0|jt[d>>2]))<3)do{n=0|jt[s>>2],(0|n)==(0|jt[l>>2])?n=0:(jt[s>>2]=n+1,n=0|Yt[n>>0]),i=i+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[g>>2]=866,jt[g+4>>2]=3208,jt[g+8>>2]=1366,Ve(h,812,g),he(h),i=0|jt[d>>2]),n=n<<32-i|jt[u>>2],jt[u>>2]=n}while((0|i)<3);else n=0|jt[u>>2];if(jt[u>>2]=n<<3,jt[d>>2]=i+-3,n=3+(n>>>29)|0,i=n>>>0>a>>>0){r=0;break e}r=(i?0:n)+r|0;break r;case 18:if((0|(i=0|jt[d>>2]))<7)do{n=0|jt[s>>2],(0|n)==(0|jt[l>>2])?n=0:(jt[s>>2]=n+1,n=0|Yt[n>>0]),i=i+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[_>>2]=866,jt[_+4>>2]=3208,jt[_+8>>2]=1366,Ve(h,812,_),he(h),i=0|jt[d>>2]),n=n<<32-i|jt[u>>2],jt[u>>2]=n}while((0|i)<7);else n=0|jt[u>>2];if(jt[u>>2]=n<<7,jt[d>>2]=i+-7,n=11+(n>>>25)|0,i=n>>>0>a>>>0){r=0;break e}r=(i?0:n)+r|0;break r;default:if((n+-19|0)>>>0>=2){A=81;break t}if(i=0|jt[d>>2],19==(0|n)){if((0|i)<2)for(n=i;;){if(i=0|jt[s>>2],(0|i)==(0|jt[l>>2])?o=0:(jt[s>>2]=i+1,o=0|Yt[i>>0]),i=n+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[v>>2]=866,jt[v+4>>2]=3208,jt[v+8>>2]=1366,Ve(h,812,v),he(h),i=0|jt[d>>2]),n=o<<32-i|jt[u>>2],jt[u>>2]=n,!((0|i)<2))break;n=i}else n=0|jt[u>>2];jt[u>>2]=n<<2,n>>>=30,o=3,i=i+-2|0}else{if((0|i)<6)do{n=0|jt[s>>2],(0|n)==(0|jt[l>>2])?n=0:(jt[s>>2]=n+1,n=0|Yt[n>>0]),i=i+8|0,jt[d>>2]=i,(0|i)>=33&&(jt[y>>2]=866,jt[y+4>>2]=3208,jt[y+8>>2]=1366,Ve(h,812,y),he(h),i=0|jt[d>>2]),n=n<<32-i|jt[u>>2],jt[u>>2]=n}while((0|i)<6);else n=0|jt[u>>2];jt[u>>2]=n<<6,n>>>=26,o=7,i=i+-6|0}if(jt[d>>2]=i,n=n+o|0,0==(0|r)|n>>>0>a>>>0){r=0;break e}if(i=r+-1|0,(0|jt[m>>2])>>>0<=i>>>0&&(jt[b>>2]=866,jt[b+4>>2]=910,jt[b+8>>2]=1497,Ve(h,812,b),he(h)),!((o=0|zt[(0|jt[f>>2])+i>>0])<<24>>24)){r=0;break e}if(i=n+r|0,r>>>0>=i>>>0)break r;do{(0|jt[m>>2])>>>0<=r>>>0&&(jt[S>>2]=866,jt[S+4>>2]=910,jt[S+8>>2]=1497,Ve(h,812,S),he(h)),zt[(0|jt[f>>2])+r>>0]=o,r=r+1|0}while((0|r)!=(0|i));r=i}}while(0)}while(p>>>0>r>>>0);if(81==(0|A)){jt[w>>2]=866,jt[w+4>>2]=3149,jt[w+8>>2]=1348,Ve(h,812,w),he(h),r=0;break}r=(0|p)==(0|r)?0|k(t):0}else r=0}else zt[x+16>>0]=1,r=0}while(0);return X(x),x=r,or=P,0|x}function l(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,C=0,S=0,w=0,T=0,E=0,A=0,x=0,P=0,D=0,I=0,O=0;if(O=or,or=or+880|0,D=O+144|0,P=O+128|0,x=O+112|0,A=O+96|0,S=O+80|0,_=O+64|0,m=O+48|0,g=O+32|0,d=O+16|0,c=O,T=O+360|0,E=O+296|0,I=O+224|0,f=O+156|0,0==(0|t)|i>>>0>11)return I=0,or=O,0|I;jt[e>>2]=t,n=I,o=n+68|0;do{jt[n>>2]=0,n=n+4|0}while((0|n)<(0|o));n=0;do{w=0|zt[r+n>>0],o=I+((255&w)<<2)|0,w<<24>>24&&(jt[o>>2]=1+(0|jt[o>>2])),n=n+1|0}while((0|n)!=(0|t));for(o=0,a=0,s=0,l=-1,u=1;;){if(n=0|jt[I+(u<<2)>>2],n?(h=u+-1|0,jt[E+(h<<2)>>2]=o,o=n+o|0,w=16-u|0,jt[e+28+(h<<2)>>2]=1+(o+-1<<w|(1<<w)-1),jt[e+96+(h<<2)>>2]=a,jt[f+(u<<2)>>2]=a,h=n+a|0,s=s>>>0>u>>>0?s:u,l=l>>>0<u>>>0?l:u):(jt[e+28+(u+-1<<2)>>2]=0,h=a),17==(0|(u=u+1|0)))break;o<<=1,a=h}jt[e+4>>2]=h,o=e+172|0;do{if(h>>>0>(0|jt[o>>2])>>>0){n=h+-1|0,n&h?(n|=n>>>16,n|=n>>>8,n|=n>>>4,n|=n>>>2,n=1+(n>>>1|n)|0,n=n>>>0>t>>>0?t:n):n=h,jt[o>>2]=n,a=e+176|0,n=0|jt[a>>2];do{if(0|n){if(w=0|jt[n+-4>>2],n=n+-8|0,(0!=(0|w)?(0|w)==(0|~jt[n>>2]):0)||(jt[c>>2]=866,jt[c+4>>2]=651,jt[c+8>>2]=1579,Ve(T,812,c),he(T)),7&n){jt[d>>2]=866,jt[d+4>>2]=2506,jt[d+8>>2]=1232,Ve(T,812,d),he(T);break}oe(n,0,0,1,0);break}}while(0);if(n=0|jt[o>>2],n=0|n?n:1,o=0|Q(8+(n<<1)|0,0)){jt[o+4>>2]=n,jt[o>>2]=~n,jt[a>>2]=o+8,p=24;break}jt[a>>2]=0,i=0;break}p=24}while(0);e:do{if(24==(0|p)){w=e+24|0,zt[w>>0]=l,zt[e+25>>0]=s,a=e+176|0,o=0;do{C=0|zt[r+o>>0],n=255&C,C<<24>>24&&(0|jt[I+(n<<2)>>2]||(jt[g>>2]=866,jt[g+4>>2]=2276,jt[g+8>>2]=977,Ve(T,812,g),he(T)),C=f+(n<<2)|0,n=0|jt[C>>2],jt[C>>2]=n+1,n>>>0>=h>>>0&&(jt[m>>2]=866,jt[m+4>>2]=2280,jt[m+8>>2]=990,Ve(T,812,m),he(T)),Wt[(0|jt[a>>2])+(n<<1)>>1]=o),o=o+1|0}while((0|o)!=(0|t));if(b=(0|Yt[w>>0])>>>0<i>>>0?i:0,C=e+8|0,jt[C>>2]=b,y=0!=(0|b)){v=1<<b,n=e+164|0;do{if(v>>>0>(0|jt[n>>2])>>>0){jt[n>>2]=v,a=e+168|0,n=0|jt[a>>2];do{if(0|n){if(g=0|jt[n+-4>>2],n=n+-8|0,(0!=(0|g)?(0|g)==(0|~jt[n>>2]):0)||(jt[_>>2]=866,jt[_+4>>2]=651,jt[_+8>>2]=1579,Ve(T,812,_),he(T)),7&n){jt[S>>2]=866,jt[S+4>>2]=2506,jt[S+8>>2]=1232,Ve(T,812,S),he(T);break}oe(n,0,0,1,0);break}}while(0);if(n=v<<2,o=0|Q(n+8|0,0)){S=o+8|0,jt[o+4>>2]=v,jt[o>>2]=~v,jt[a>>2]=S,o=S;break}jt[a>>2]=0,i=0;break e}o=e+168|0,n=v<<2,a=o,o=0|jt[o>>2]}while(0);ee(0|o,-1,0|n),m=e+176|0,f=1;do{if(0|jt[I+(f<<2)>>2]&&(g=b-f|0,_=1<<g,n=f+-1|0,o=0|jt[E+(n<<2)>>2],n>>>0>=16&&(jt[A>>2]=866,jt[A+4>>2]=1960,jt[A+8>>2]=1453,Ve(T,812,A),he(T)),t=0|jt[e+28+(n<<2)>>2],t=0==(0|t)?-1:(t+-1|0)>>>(16-f|0),o>>>0<=t>>>0)){h=(0|jt[e+96+(n<<2)>>2])-o|0,p=f<<16;do{n=0|Qt[(0|jt[m>>2])+(h+o<<1)>>1],(0|Yt[r+n>>0])!=(0|f)&&(jt[x>>2]=866,jt[x+4>>2]=2322,jt[x+8>>2]=1019,Ve(T,812,x),he(T)),d=o<<g,u=n|p,l=0;do{c=l+d|0,c>>>0>=v>>>0&&(jt[P>>2]=866,jt[P+4>>2]=2328,jt[P+8>>2]=1053,Ve(T,812,P),he(T)),n=0|jt[a>>2],-1!=(0|jt[n+(c<<2)>>2])&&(jt[D>>2]=866,jt[D+4>>2]=2330,jt[D+8>>2]=1076,Ve(T,812,D),he(T),n=0|jt[a>>2]),jt[n+(c<<2)>>2]=u,l=l+1|0}while(l>>>0<_>>>0);o=o+1|0}while(o>>>0<=t>>>0)}f=f+1|0}while(b>>>0>=f>>>0)}n=e+96|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E>>2]),n=e+100|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+4>>2]),n=e+104|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+8>>2]),n=e+108|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+12>>2]),n=e+112|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+16>>2]),n=e+116|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+20>>2]),n=e+120|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+24>>2]),n=e+124|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+28>>2]),n=e+128|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+32>>2]),n=e+132|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+36>>2]),n=e+136|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+40>>2]),n=e+140|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+44>>2]),n=e+144|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+48>>2]),n=e+148|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+52>>2]),n=e+152|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+56>>2]),n=e+156|0,jt[n>>2]=(0|jt[n>>2])-(0|jt[E+60>>2]),n=e+16|0,jt[n>>2]=0,o=e+20|0,jt[o>>2]=Yt[w>>0];t:do{if(y){do{if(!i)break t;D=i,i=i+-1|0}while(!(0|jt[I+(D<<2)>>2]));if(jt[n>>2]=jt[e+28+(i<<2)>>2],i=b+1|0,jt[o>>2]=i,i>>>0<=s>>>0){for(;;){if(0|jt[I+(i<<2)>>2])break;if((i=i+1|0)>>>0>s>>>0)break t}jt[o>>2]=i}}}while(0);jt[e+92>>2]=-1,jt[e+160>>2]=1048575,jt[e+12>>2]=32-(0|jt[C>>2]),i=1}}while(0);return I=i,or=O,0|I}function u(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,E=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,L=0,N=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,W=0,H=0,j=0,q=0,Y=0,X=0,Q=0,Z=0,K=0,J=0,$=0,ee=0,te=0,re=0,ie=0,ne=0;if(re=or,or=or+656|0,ee=re+112|0,J=re+96|0,K=re+80|0,Z=re+64|0,Q=re+48|0,te=re+32|0,$=re+16|0,X=re,q=re+144|0,Y=re+128|0,k=e+240|0,F=0|jt[k>>2],B=e+256|0,U=0|jt[B>>2],j=0|zt[17+(0|jt[e+88>>2])>>0],V=255&j,z=i>>>2,!(j<<24>>24))return or=re,1;G=0==(0|s),W=a+-1|0,H=W<<4,j=s+-1|0,I=0!=(1&o|0),O=i<<1,M=e+92|0,R=e+116|0,L=e+140|0,N=e+236|0,D=0!=(1&n|0),P=e+188|0,T=e+252|0,E=z+1|0,A=z+2|0,x=z+3|0,w=0,o=0,r=0,n=1;do{if(!G)for(b=0|jt[t+(w<<2)>>2],S=0;;){if(v=1&S,u=0==(0|v),_=(v<<5^32)-16|0,v=(v<<1^2)-1|0,g=u?a:-1,l=u?0:W,e=(0|S)==(0|j),y=I&e,(0|l)!=(0|g))for(m=I&e^1,f=u?b:b+H|0;;){1==(0|n)&&(n=512|C(M,R)),p=7&n,n>>>=3,u=0|Yt[1539+p>>0],e=0;do{c=(0|C(M,L))+r|0,d=c-F|0,h=d>>31,r=h&c|d&~h,(0|jt[k>>2])>>>0<=r>>>0&&(jt[X>>2]=866,jt[X+4>>2]=910,jt[X+8>>2]=1497,Ve(q,812,X),he(q)),jt[Y+(e<<2)>>2]=jt[(0|jt[N>>2])+(r<<2)>>2],e=e+1|0}while(e>>>0<u>>>0);if(h=D&(0|l)==(0|W),y|h){d=0;do{e=f+(0|dr(d,i))|0,c=0==(0|d)|m,u=d<<1,ne=(0|C(M,P))+o|0,ie=ne-U|0,o=ie>>31,o=o&ne|ie&~o;do{if(h){if(!c){ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o;break}jt[e>>2]=jt[Y+((0|Yt[1547+(p<<2)+u>>0])<<2)>>2],(0|jt[B>>2])>>>0<=o>>>0&&(jt[J>>2]=866,jt[J+4>>2]=910,jt[J+8>>2]=1497,Ve(q,812,J),he(q)),jt[e+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o}else c&&(jt[e>>2]=jt[Y+((0|Yt[1547+(p<<2)+u>>0])<<2)>>2],(0|jt[B>>2])>>>0<=o>>>0&&(jt[K>>2]=866,jt[K+4>>2]=910,jt[K+8>>2]=1497,Ve(q,812,K),he(q)),jt[e+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2]),e=e+8|0,ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,c&&(jt[e>>2]=jt[Y+((0|Yt[1547+(p<<2)+(1|u)>>0])<<2)>>2],(0|jt[B>>2])>>>0<=o>>>0&&(jt[ee>>2]=866,jt[ee+4>>2]=910,jt[ee+8>>2]=1497,Ve(q,812,ee),he(q)),jt[e+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2])}while(0);d=d+1|0}while(2!=(0|d))}else jt[f>>2]=jt[Y+((0|Yt[1547+(p<<2)>>0])<<2)>>2],ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[$>>2]=866,jt[$+4>>2]=910,jt[$+8>>2]=1497,Ve(q,812,$),he(q)),jt[f+4>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],jt[f+8>>2]=jt[Y+((0|Yt[1547+(p<<2)+1>>0])<<2)>>2],ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[te>>2]=866,jt[te+4>>2]=910,jt[te+8>>2]=1497,Ve(q,812,te),he(q)),jt[f+12>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],jt[f+(z<<2)>>2]=jt[Y+((0|Yt[1547+(p<<2)+2>>0])<<2)>>2],ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[Q>>2]=866,jt[Q+4>>2]=910,jt[Q+8>>2]=1497,Ve(q,812,Q),he(q)),jt[f+(E<<2)>>2]=jt[(0|jt[T>>2])+(o<<2)>>2],jt[f+(A<<2)>>2]=jt[Y+((0|Yt[1547+(p<<2)+3>>0])<<2)>>2],ie=(0|C(M,P))+o|0,ne=ie-U|0,o=ne>>31,o=o&ie|ne&~o,(0|jt[B>>2])>>>0<=o>>>0&&(jt[Z>>2]=866,jt[Z+4>>2]=910,jt[Z+8>>2]=1497,Ve(q,812,Z),he(q)),jt[f+(x<<2)>>2]=jt[(0|jt[T>>2])+(o<<2)>>2];if((0|(l=v+l|0))==(0|g))break;f=f+_|0}if((0|(S=S+1|0))==(0|s))break;b=b+O|0}w=w+1|0}while((0|w)!=(0|V));return or=re,1}function c(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,E=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,L=0,N=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,W=0,H=0,j=0,q=0,Y=0,X=0,Q=0,Z=0,K=0,J=0,$=0,ee=0,te=0,re=0,ie=0,ne=0,oe=0,ae=0;if(ae=or,or=or+640|0,ie=ae+80|0,re=ae+64|0,te=ae+48|0,oe=ae+32|0,ne=ae+16|0,ee=ae,J=ae+128|0,$=ae+112|0,F=ae+96|0,B=e+272|0,U=0|jt[B>>2],K=0|jt[e+88>>2],V=(0|Yt[K+63>>0])<<8|0|Yt[K+64>>0],K=0|zt[K+17>>0],z=255&K,!(K<<24>>24))return or=ae,1;G=0==(0|s),W=a+-1|0,H=W<<5,j=s+-1|0,q=i<<1,Y=e+92|0,X=e+116|0,Q=e+164|0,Z=e+268|0,K=e+212|0,k=0==(1&n|0),N=0==(1&o|0),L=e+288|0,R=e+284|0,M=0,e=0,o=0,n=0,r=0,l=1;do{if(!G)for(I=0|jt[t+(M<<2)>>2],O=0;;){if(D=1&O,c=0==(0|D),P=(D<<6^64)-32|0,D=(D<<1^2)-1|0,A=c?a:-1,(0|(u=c?0:W))!=(0|A))for(x=N|(0|O)!=(0|j),E=c?I:I+H|0;;){1==(0|l)&&(l=512|C(Y,X)),T=7&l,l>>>=3,d=0|Yt[1539+T>>0],c=0;do{b=(0|C(Y,Q))+r|0,S=b-U|0,w=S>>31,r=w&b|S&~w,(0|jt[B>>2])>>>0<=r>>>0&&(jt[ee>>2]=866,jt[ee+4>>2]=910,jt[ee+8>>2]=1497,Ve(J,812,ee),he(J)),jt[$+(c<<2)>>2]=Qt[(0|jt[Z>>2])+(r<<1)>>1],c=c+1|0}while(c>>>0<d>>>0);c=0;do{b=(0|C(Y,Q))+o|0,S=b-U|0,w=S>>31,o=w&b|S&~w,(0|jt[B>>2])>>>0<=o>>>0&&(jt[ne>>2]=866,jt[ne+4>>2]=910,jt[ne+8>>2]=1497,Ve(J,812,ne),he(J)),jt[F+(c<<2)>>2]=Qt[(0|jt[Z>>2])+(o<<1)>>1],c=c+1|0}while(c>>>0<d>>>0);for(w=k|(0|u)!=(0|W),b=0,S=E;;){if(_=x|0==(0|b),v=b<<1,w)for(m=0,g=S;;){if(y=(0|C(Y,K))+n|0,f=y-V|0,n=f>>31,n=n&y|f&~n,f=(0|C(Y,K))+e|0,y=f-V|0,e=y>>31,e=e&f|y&~e,_&&(f=0|Yt[m+v+(1547+(T<<2))>>0],d=3*n|0,c=0|jt[L>>2],c>>>0<=d>>>0&&(jt[oe>>2]=866,jt[oe+4>>2]=910,jt[oe+8>>2]=1497,Ve(J,812,oe),he(J),c=0|jt[L>>2]),h=0|jt[R>>2],d=h+(d<<1)|0,p=3*e|0,c>>>0>p>>>0?c=h:(jt[te>>2]=866,jt[te+4>>2]=910,jt[te+8>>2]=1497,Ve(J,812,te),he(J),c=0|jt[R>>2]),y=c+(p<<1)|0,jt[g>>2]=(0|Qt[d>>1])<<16|jt[$+(f<<2)>>2],jt[g+4>>2]=(0|Qt[d+4>>1])<<16|0|Qt[d+2>>1],jt[g+8>>2]=(0|Qt[y>>1])<<16|jt[F+(f<<2)>>2],jt[g+12>>2]=(0|Qt[y+4>>1])<<16|0|Qt[y+2>>1]),2==(0|(m=m+1|0)))break;g=g+16|0}else for(y=1^_,_=1547+(T<<2)+v|0,m=0,g=S;;){if(v=(0|C(Y,K))+n|0,f=v-V|0,n=f>>31,n=n&v|f&~n,f=(0|C(Y,K))+e|0,v=f-V|0,e=v>>31,e=e&f|v&~e,0!=(0|m)|y||(f=0|Yt[_>>0],d=3*n|0,c=0|jt[L>>2],c>>>0<=d>>>0&&(jt[re>>2]=866,jt[re+4>>2]=910,jt[re+8>>2]=1497,Ve(J,812,re),he(J),c=0|jt[L>>2]),h=0|jt[R>>2],d=h+(d<<1)|0,p=3*e|0,c>>>0>p>>>0?c=h:(jt[ie>>2]=866,jt[ie+4>>2]=910,jt[ie+8>>2]=1497,Ve(J,812,ie),he(J),c=0|jt[R>>2]),v=c+(p<<1)|0,jt[g>>2]=(0|Qt[d>>1])<<16|jt[$+(f<<2)>>2],jt[g+4>>2]=(0|Qt[d+4>>1])<<16|0|Qt[d+2>>1],jt[g+8>>2]=(0|Qt[v>>1])<<16|jt[F+(f<<2)>>2],jt[g+12>>2]=(0|Qt[v+4>>1])<<16|0|Qt[v+2>>1]),2==(0|(m=m+1|0)))break;g=g+16|0}if(2==(0|(b=b+1|0)))break;S=S+i|0}if((0|(u=D+u|0))==(0|A))break;E=E+P|0}if((0|(O=O+1|0))==(0|s))break;I=I+q|0}M=M+1|0}while((0|M)!=(0|z));return or=ae,1}function d(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0;if(e){r=e+-8|0,n=0|jt[1148],e=0|jt[e+-4>>2],t=-8&e,l=r+t|0;do{if(1&e)s=r,a=r;else{if(i=0|jt[r>>2],!(3&e))return;if(a=r+(0-i)|0,o=i+t|0,a>>>0<n>>>0)return;if((0|a)==(0|jt[1149])){if(e=l+4|0,3!=(3&(t=0|jt[e>>2])|0)){s=a,t=o;break}return jt[1146]=o,jt[e>>2]=-2&t,jt[a+4>>2]=1|o,void(jt[a+o>>2]=o)}if(r=i>>>3,i>>>0<256){if(e=0|jt[a+8>>2],(0|(t=0|jt[a+12>>2]))==(0|e)){jt[1144]=jt[1144]&~(1<<r),s=a,t=o;break}jt[e+12>>2]=t,jt[t+8>>2]=e,s=a,t=o;break}n=0|jt[a+24>>2],e=0|jt[a+12>>2];do{if((0|e)==(0|a)){if(r=a+16|0,t=r+4|0,!(e=0|jt[t>>2])){if(!(e=0|jt[r>>2])){e=0;break}t=r}for(;;)if(r=e+20|0,0|(i=0|jt[r>>2]))e=i,t=r;else{if(r=e+16|0,!(i=0|jt[r>>2]))break;e=i,t=r}jt[t>>2]=0}else s=0|jt[a+8>>2],jt[s+12>>2]=e,jt[e+8>>2]=s}while(0);if(n){if(t=0|jt[a+28>>2],r=4880+(t<<2)|0,(0|a)==(0|jt[r>>2])){if(jt[r>>2]=e,!e){jt[1145]=jt[1145]&~(1<<t),s=a,t=o;break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|a)&1)<<2)>>2]=e,!e){s=a,t=o;break}jt[e+24>>2]=n,t=a+16|0,r=0|jt[t>>2],0|r&&(jt[e+16>>2]=r,jt[r+24>>2]=e),t=0|jt[t+4>>2],t?(jt[e+20>>2]=t,jt[t+24>>2]=e,s=a,t=o):(s=a,t=o)}else s=a,t=o}}while(0);if(!(a>>>0>=l>>>0)&&(e=l+4|0,1&(i=0|jt[e>>2]))){if(2&i)jt[e>>2]=-2&i,jt[s+4>>2]=1|t,jt[a+t>>2]=t,n=t;else{if(e=0|jt[1149],(0|l)==(0|jt[1150])){if(l=(0|jt[1147])+t|0,jt[1147]=l,jt[1150]=s,jt[s+4>>2]=1|l,(0|s)!=(0|e))return;return jt[1149]=0,void(jt[1146]=0)}if((0|l)==(0|e))return l=(0|jt[1146])+t|0,jt[1146]=l,jt[1149]=a,jt[s+4>>2]=1|l,void(jt[a+l>>2]=l);n=(-8&i)+t|0,r=i>>>3;do{if(i>>>0<256){if(t=0|jt[l+8>>2],(0|(e=0|jt[l+12>>2]))==(0|t)){jt[1144]=jt[1144]&~(1<<r);break}jt[t+12>>2]=e,jt[e+8>>2]=t;break}o=0|jt[l+24>>2],e=0|jt[l+12>>2];do{if((0|e)==(0|l)){if(r=l+16|0,t=r+4|0,!(e=0|jt[t>>2])){if(!(e=0|jt[r>>2])){r=0;break}t=r}for(;;)if(r=e+20|0,0|(i=0|jt[r>>2]))e=i,t=r;else{if(r=e+16|0,!(i=0|jt[r>>2]))break;e=i,t=r}jt[t>>2]=0,r=e}else r=0|jt[l+8>>2],jt[r+12>>2]=e,jt[e+8>>2]=r,r=e}while(0);if(0|o){if(e=0|jt[l+28>>2],t=4880+(e<<2)|0,(0|l)==(0|jt[t>>2])){if(jt[t>>2]=r,!r){jt[1145]=jt[1145]&~(1<<e);break}}else if(jt[o+16+(((0|jt[o+16>>2])!=(0|l)&1)<<2)>>2]=r,!r)break;jt[r+24>>2]=o,e=l+16|0,t=0|jt[e>>2],0|t&&(jt[r+16>>2]=t,jt[t+24>>2]=r),e=0|jt[e+4>>2],0|e&&(jt[r+20>>2]=e,jt[e+24>>2]=r)}}while(0);if(jt[s+4>>2]=1|n,jt[a+n>>2]=n,(0|s)==(0|jt[1149]))return void(jt[1146]=n)}if(e=n>>>3,n>>>0<256)return r=4616+(e<<1<<2)|0,t=0|jt[1144],e=1<<e,t&e?(t=r+8|0,e=0|jt[t>>2]):(jt[1144]=t|e,e=r,t=r+8|0),jt[t>>2]=s,jt[e+12>>2]=s,jt[s+8>>2]=e,void(jt[s+12>>2]=r);e=n>>>8,e?n>>>0>16777215?e=31:(a=(e+1048320|0)>>>16&8,l=e<<a,o=(l+520192|0)>>>16&4,l<<=o,e=(l+245760|0)>>>16&2,e=14-(o|a|e)+(l<<e>>>15)|0,e=n>>>(e+7|0)&1|e<<1):e=0,i=4880+(e<<2)|0,jt[s+28>>2]=e,jt[s+20>>2]=0,jt[s+16>>2]=0,t=0|jt[1145],r=1<<e;do{if(t&r){for(t=n<<(31==(0|e)?0:25-(e>>>1)|0),r=0|jt[i>>2];;){if((-8&jt[r+4>>2]|0)==(0|n)){e=73;break}if(i=r+16+(t>>>31<<2)|0,!(e=0|jt[i>>2])){e=72;break}t<<=1,r=e}if(72==(0|e)){jt[i>>2]=s,jt[s+24>>2]=r,jt[s+12>>2]=s,jt[s+8>>2]=s;break}if(73==(0|e)){a=r+8|0,l=0|jt[a>>2],jt[l+12>>2]=s,jt[a>>2]=s,jt[s+8>>2]=l,jt[s+12>>2]=r,jt[s+24>>2]=0;break}}else jt[1145]=t|r,jt[i>>2]=s,jt[s+24>>2]=i,jt[s+12>>2]=s,jt[s+8>>2]=s}while(0);if(l=(0|jt[1152])-1|0,jt[1152]=l,!l){for(e=5032;;){if(!(e=0|jt[e>>2]))break;e=e+8|0}jt[1152]=-1}}}}function h(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,E=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,L=0,N=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,W=0,H=0,j=0,q=0,Y=0,X=0,Q=0,Z=0,K=0,J=0,$=0,ee=0,te=0,re=0,ie=0,ne=0,oe=0,ae=0,se=0,le=0,ue=0,ce=0,de=0;if(de=or,or=or+640|0,le=de+80|0,se=de+64|0,ae=de+48|0,ce=de+32|0,ue=de+16|0,oe=de,ie=de+128|0,ne=de+112|0,N=de+96|0,k=e+240|0,F=0|jt[k>>2],B=e+256|0,U=0|jt[B>>2],V=e+272|0,z=0|jt[V>>2],re=0|jt[e+88>>2],G=(0|Yt[re+63>>0])<<8|0|Yt[re+64>>0],re=0|zt[re+17>>0],W=255&re,!(re<<24>>24))return or=de,1;H=0==(0|s),j=a+-1|0,q=j<<5,Y=s+-1|0,X=i<<1,Q=e+92|0,Z=e+116|0,K=e+164|0,J=e+268|0,$=e+140|0,ee=e+236|0,te=e+212|0,re=e+188|0,L=0==(1&n|0),R=0==(1&o|0),O=e+288|0,M=e+284|0,I=e+252|0,D=0,e=0,o=0,n=0,r=0,l=1;do{if(!H)for(x=0|jt[t+(D<<2)>>2],P=0;;){if(A=1&P,c=0==(0|A),E=(A<<6^64)-32|0,A=(A<<1^2)-1|0,w=c?a:-1,(0|(u=c?0:j))!=(0|w))for(T=R|(0|P)!=(0|Y),S=c?x:x+q|0;;){ +1==(0|l)&&(l=512|C(Q,Z)),b=7&l,l>>>=3,d=0|Yt[1539+b>>0],c=0;do{_=(0|C(Q,K))+o|0,v=_-z|0,y=v>>31,o=y&_|v&~y,(0|jt[V>>2])>>>0<=o>>>0&&(jt[oe>>2]=866,jt[oe+4>>2]=910,jt[oe+8>>2]=1497,Ve(ie,812,oe),he(ie)),jt[N+(c<<2)>>2]=Qt[(0|jt[J>>2])+(o<<1)>>1],c=c+1|0}while(c>>>0<d>>>0);c=0;do{_=(0|C(Q,$))+r|0,v=_-F|0,y=v>>31,r=y&_|v&~y,(0|jt[k>>2])>>>0<=r>>>0&&(jt[ue>>2]=866,jt[ue+4>>2]=910,jt[ue+8>>2]=1497,Ve(ie,812,ue),he(ie)),jt[ne+(c<<2)>>2]=jt[(0|jt[ee>>2])+(r<<2)>>2],c=c+1|0}while(c>>>0<d>>>0);for(y=L|(0|u)!=(0|j),_=0,v=S;;){if(f=T|0==(0|_),m=_<<1,y)for(h=0,p=v;;){if(g=(0|C(Q,te))+e|0,d=g-G|0,e=d>>31,e=e&g|d&~e,d=(0|C(Q,re))+n|0,g=d-U|0,n=g>>31,n=n&d|g&~n,f&&(c=0|Yt[h+m+(1547+(b<<2))>>0],d=3*e|0,(0|jt[O>>2])>>>0<=d>>>0&&(jt[ce>>2]=866,jt[ce+4>>2]=910,jt[ce+8>>2]=1497,Ve(ie,812,ce),he(ie)),g=(0|jt[M>>2])+(d<<1)|0,jt[p>>2]=(0|Qt[g>>1])<<16|jt[N+(c<<2)>>2],jt[p+4>>2]=(0|Qt[g+4>>1])<<16|0|Qt[g+2>>1],jt[p+8>>2]=jt[ne+(c<<2)>>2],(0|jt[B>>2])>>>0<=n>>>0&&(jt[ae>>2]=866,jt[ae+4>>2]=910,jt[ae+8>>2]=1497,Ve(ie,812,ae),he(ie)),jt[p+12>>2]=jt[(0|jt[I>>2])+(n<<2)>>2]),2==(0|(h=h+1|0)))break;p=p+16|0}else for(g=1^f,f=1547+(b<<2)+m|0,h=0,p=v;;){if(m=(0|C(Q,te))+e|0,d=m-G|0,e=d>>31,e=e&m|d&~e,d=(0|C(Q,re))+n|0,m=d-U|0,n=m>>31,n=n&d|m&~n,0!=(0|h)|g||(c=0|Yt[f>>0],d=3*e|0,(0|jt[O>>2])>>>0<=d>>>0&&(jt[se>>2]=866,jt[se+4>>2]=910,jt[se+8>>2]=1497,Ve(ie,812,se),he(ie)),m=(0|jt[M>>2])+(d<<1)|0,jt[p>>2]=(0|Qt[m>>1])<<16|jt[N+(c<<2)>>2],jt[p+4>>2]=(0|Qt[m+4>>1])<<16|0|Qt[m+2>>1],jt[p+8>>2]=jt[ne+(c<<2)>>2],(0|jt[B>>2])>>>0<=n>>>0&&(jt[le>>2]=866,jt[le+4>>2]=910,jt[le+8>>2]=1497,Ve(ie,812,le),he(ie)),jt[p+12>>2]=jt[(0|jt[I>>2])+(n<<2)>>2]),2==(0|(h=h+1|0)))break;p=p+16|0}if(2==(0|(_=_+1|0)))break;v=v+i|0}if((0|(u=A+u|0))==(0|w))break;S=S+E|0}if((0|(P=P+1|0))==(0|s))break;x=x+X|0}D=D+1|0}while((0|D)!=(0|W));return or=de,1}function p(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;l=e+t|0,r=0|jt[e+4>>2];do{if(1&r)s=e,r=t;else{if(i=0|jt[e>>2],!(3&r))return;if(o=e+(0-i)|0,a=i+t|0,(0|o)==(0|jt[1149])){if(e=l+4|0,3!=(3&(r=0|jt[e>>2])|0)){s=o,r=a;break}return jt[1146]=a,jt[e>>2]=-2&r,jt[o+4>>2]=1|a,void(jt[o+a>>2]=a)}if(t=i>>>3,i>>>0<256){if(e=0|jt[o+8>>2],(0|(r=0|jt[o+12>>2]))==(0|e)){jt[1144]=jt[1144]&~(1<<t),s=o,r=a;break}jt[e+12>>2]=r,jt[r+8>>2]=e,s=o,r=a;break}n=0|jt[o+24>>2],e=0|jt[o+12>>2];do{if((0|e)==(0|o)){if(t=o+16|0,r=t+4|0,!(e=0|jt[r>>2])){if(!(e=0|jt[t>>2])){e=0;break}r=t}for(;;)if(t=e+20|0,0|(i=0|jt[t>>2]))e=i,r=t;else{if(t=e+16|0,!(i=0|jt[t>>2]))break;e=i,r=t}jt[r>>2]=0}else s=0|jt[o+8>>2],jt[s+12>>2]=e,jt[e+8>>2]=s}while(0);if(n){if(r=0|jt[o+28>>2],t=4880+(r<<2)|0,(0|o)==(0|jt[t>>2])){if(jt[t>>2]=e,!e){jt[1145]=jt[1145]&~(1<<r),s=o,r=a;break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|o)&1)<<2)>>2]=e,!e){s=o,r=a;break}jt[e+24>>2]=n,r=o+16|0,t=0|jt[r>>2],0|t&&(jt[e+16>>2]=t,jt[t+24>>2]=e),r=0|jt[r+4>>2],r?(jt[e+20>>2]=r,jt[r+24>>2]=e,s=o,r=a):(s=o,r=a)}else s=o,r=a}}while(0);if(e=l+4|0,2&(i=0|jt[e>>2]))jt[e>>2]=-2&i,jt[s+4>>2]=1|r,jt[s+r>>2]=r;else{if(e=0|jt[1149],(0|l)==(0|jt[1150])){if(l=(0|jt[1147])+r|0,jt[1147]=l,jt[1150]=s,jt[s+4>>2]=1|l,(0|s)!=(0|e))return;return jt[1149]=0,void(jt[1146]=0)}if((0|l)==(0|e))return l=(0|jt[1146])+r|0,jt[1146]=l,jt[1149]=s,jt[s+4>>2]=1|l,void(jt[s+l>>2]=l);o=(-8&i)+r|0,t=i>>>3;do{if(i>>>0<256){if(r=0|jt[l+8>>2],(0|(e=0|jt[l+12>>2]))==(0|r)){jt[1144]=jt[1144]&~(1<<t);break}jt[r+12>>2]=e,jt[e+8>>2]=r;break}n=0|jt[l+24>>2],e=0|jt[l+12>>2];do{if((0|e)==(0|l)){if(t=l+16|0,r=t+4|0,!(e=0|jt[r>>2])){if(!(e=0|jt[t>>2])){t=0;break}r=t}for(;;)if(t=e+20|0,0|(i=0|jt[t>>2]))e=i,r=t;else{if(t=e+16|0,!(i=0|jt[t>>2]))break;e=i,r=t}jt[r>>2]=0,t=e}else t=0|jt[l+8>>2],jt[t+12>>2]=e,jt[e+8>>2]=t,t=e}while(0);if(0|n){if(e=0|jt[l+28>>2],r=4880+(e<<2)|0,(0|l)==(0|jt[r>>2])){if(jt[r>>2]=t,!t){jt[1145]=jt[1145]&~(1<<e);break}}else if(jt[n+16+(((0|jt[n+16>>2])!=(0|l)&1)<<2)>>2]=t,!t)break;jt[t+24>>2]=n,e=l+16|0,r=0|jt[e>>2],0|r&&(jt[t+16>>2]=r,jt[r+24>>2]=t),e=0|jt[e+4>>2],0|e&&(jt[t+20>>2]=e,jt[e+24>>2]=t)}}while(0);if(jt[s+4>>2]=1|o,jt[s+o>>2]=o,(0|s)==(0|jt[1149]))return void(jt[1146]=o);r=o}if(e=r>>>3,r>>>0<256)return t=4616+(e<<1<<2)|0,r=0|jt[1144],e=1<<e,r&e?(r=t+8|0,e=0|jt[r>>2]):(jt[1144]=r|e,e=t,r=t+8|0),jt[r>>2]=s,jt[e+12>>2]=s,jt[s+8>>2]=e,void(jt[s+12>>2]=t);if(e=r>>>8,e?r>>>0>16777215?e=31:(a=(e+1048320|0)>>>16&8,l=e<<a,o=(l+520192|0)>>>16&4,l<<=o,e=(l+245760|0)>>>16&2,e=14-(o|a|e)+(l<<e>>>15)|0,e=r>>>(e+7|0)&1|e<<1):e=0,n=4880+(e<<2)|0,jt[s+28>>2]=e,jt[s+20>>2]=0,jt[s+16>>2]=0,t=0|jt[1145],i=1<<e,!(t&i))return jt[1145]=t|i,jt[n>>2]=s,jt[s+24>>2]=n,jt[s+12>>2]=s,void(jt[s+8>>2]=s);for(t=r<<(31==(0|e)?0:25-(e>>>1)|0),i=0|jt[n>>2];;){if((-8&jt[i+4>>2]|0)==(0|r)){e=69;break}if(n=i+16+(t>>>31<<2)|0,!(e=0|jt[n>>2])){e=68;break}t<<=1,i=e}return 68==(0|e)?(jt[n>>2]=s,jt[s+24>>2]=i,jt[s+12>>2]=s,void(jt[s+8>>2]=s)):69==(0|e)?(a=i+8|0,l=0|jt[a>>2],jt[l+12>>2]=s,jt[a>>2]=s,jt[s+8>>2]=l,jt[s+12>>2]=i,void(jt[s+24>>2]=0)):void 0}function f(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,L=0,N=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,W=0,H=0;if(G=or,or=or+2416|0,a=G,o=G+1904|0,z=G+1880|0,B=G+980|0,U=G+80|0,V=G+16|0,r=0|jt[e+88>>2],k=(0|Yt[r+63>>0])<<8|0|Yt[r+64>>0],F=e+92|0,t=(0|jt[e+4>>2])+((0|Yt[r+58>>0])<<8|(0|Yt[r+57>>0])<<16|0|Yt[r+59>>0])|0,!(r=(0|Yt[r+61>>0])<<8|(0|Yt[r+60>>0])<<16|0|Yt[r+62>>0]))return z=0,or=G,0|z;if(jt[F>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,jt[z+20>>2]=0,jt[z>>2]=0,jt[z+4>>2]=0,jt[z+8>>2]=0,jt[z+12>>2]=0,zt[z+16>>0]=0,0|s(F,z)){for(t=0,r=-7,i=-7;;){if(jt[B+(t<<2)>>2]=i,jt[U+(t<<2)>>2]=r,n=(0|i)>6,225==(0|(t=t+1|0)))break;r=(1&n)+r|0,i=n?-7:i+1|0}t=V,r=t+64|0;do{jt[t>>2]=0,t=t+4|0}while((0|t)<(0|r));n=e+284|0,r=3*k|0,i=e+288|0,t=0|jt[i>>2];e:do{if((0|t)==(0|r))l=13;else{if(t>>>0<=r>>>0){do{if((0|jt[e+292>>2])>>>0<r>>>0){if(0|E(n,r,(t+1|0)==(0|r),2,0)){t=0|jt[i>>2];break}zt[e+296>>0]=1,t=0;break e}}while(0);ee((0|jt[n>>2])+(t<<1)|0,0,r-t<<1|0)}jt[i>>2]=r,l=13}}while(0);do{if(13==(0|l)){if(!k){jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(o,812,a),he(o),t=1;break}for(y=V+4|0,b=V+8|0,S=V+12|0,w=V+16|0,T=V+20|0,A=V+24|0,x=V+28|0,P=V+32|0,D=V+36|0,I=V+40|0,O=V+44|0,M=V+48|0,R=V+52|0,L=V+56|0,N=V+60|0,v=0,t=0|jt[n>>2],r=0|jt[V>>2],i=0|jt[y>>2],n=0|jt[b>>2],e=0|jt[S>>2],o=0|jt[w>>2],a=0|jt[T>>2],l=0|jt[A>>2],u=0|jt[x>>2],c=0|jt[P>>2],d=0|jt[D>>2],h=0|jt[I>>2],p=0|jt[O>>2],f=0,m=0,g=0,_=0;;){if(H=0|C(F,z),r=r+(0|jt[B+(H<<2)>>2])&7,i=i+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),n=n+(0|jt[B+(H<<2)>>2])&7,e=e+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),o=o+(0|jt[B+(H<<2)>>2])&7,a=a+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),l=l+(0|jt[B+(H<<2)>>2])&7,u=u+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),c=c+(0|jt[B+(H<<2)>>2])&7,d=d+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),h=h+(0|jt[B+(H<<2)>>2])&7,p=p+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),f=f+(0|jt[B+(H<<2)>>2])&7,m=m+(0|jt[U+(H<<2)>>2])&7,H=0|C(F,z),g=g+(0|jt[B+(H<<2)>>2])&7,_=_+(0|jt[U+(H<<2)>>2])&7,H=0|Yt[1445+a>>0],Wt[t>>1]=(0|Yt[1445+i>>0])<<3|0|Yt[1445+r>>0]|(0|Yt[1445+n>>0])<<6|(0|Yt[1445+e>>0])<<9|(0|Yt[1445+o>>0])<<12|H<<15,W=0|Yt[1445+h>>0],Wt[t+2>>1]=(0|Yt[1445+l>>0])<<2|H>>>1|(0|Yt[1445+u>>0])<<5|(0|Yt[1445+c>>0])<<8|(0|Yt[1445+d>>0])<<11|W<<14,Wt[t+4>>1]=(0|Yt[1445+p>>0])<<1|W>>>2|(0|Yt[1445+f>>0])<<4|(0|Yt[1445+m>>0])<<7|(0|Yt[1445+g>>0])<<10|(0|Yt[1445+_>>0])<<13,(v=v+1|0)>>>0>=k>>>0)break;t=t+6|0}jt[V>>2]=r,jt[y>>2]=i,jt[b>>2]=n,jt[S>>2]=e,jt[w>>2]=o,jt[T>>2]=a,jt[A>>2]=l,jt[x>>2]=u,jt[P>>2]=c,jt[D>>2]=d,jt[I>>2]=h,jt[O>>2]=p,jt[M>>2]=f,jt[R>>2]=m,jt[L>>2]=g,jt[N>>2]=_,t=1}}while(0)}else t=0;return X(z),H=t,or=G,0|H}function m(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,L=0,N=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0;if(P=or,or=or+1008|0,a=P,o=P+496|0,x=P+472|0,w=P+276|0,T=P+80|0,A=P+16|0,r=0|jt[e+88>>2],b=(0|Yt[r+47>>0])<<8|0|Yt[r+48>>0],S=e+92|0,t=(0|jt[e+4>>2])+((0|Yt[r+42>>0])<<8|(0|Yt[r+41>>0])<<16|0|Yt[r+43>>0])|0,!(r=(0|Yt[r+45>>0])<<8|(0|Yt[r+44>>0])<<16|0|Yt[r+46>>0]))return x=0,or=P,0|x;if(jt[S>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,jt[x+20>>2]=0,jt[x>>2]=0,jt[x+4>>2]=0,jt[x+8>>2]=0,jt[x+12>>2]=0,zt[x+16>>0]=0,0|s(S,x)){for(t=0,r=-3,i=-3;;){if(jt[w+(t<<2)>>2]=i,jt[T+(t<<2)>>2]=r,n=(0|i)>2,49==(0|(t=t+1|0)))break;r=(1&n)+r|0,i=n?-3:i+1|0}t=A,r=t+64|0;do{jt[t>>2]=0,t=t+4|0}while((0|t)<(0|r));i=e+252|0,r=e+256|0,t=0|jt[r>>2];e:do{if((0|t)==(0|b))l=13;else{if(t>>>0<=b>>>0){do{if((0|jt[e+260>>2])>>>0<b>>>0){if(0|E(i,b,(t+1|0)==(0|b),4,0)){t=0|jt[r>>2];break}zt[e+264>>0]=1,t=0;break e}}while(0);ee((0|jt[i>>2])+(t<<2)|0,0,b-t<<2|0)}jt[r>>2]=b,l=13}}while(0);do{if(13==(0|l)){if(!b){jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(o,812,a),he(o),t=1;break}for(e=A+4|0,o=A+8|0,a=A+12|0,l=A+16|0,u=A+20|0,c=A+24|0,d=A+28|0,h=A+32|0,p=A+36|0,f=A+40|0,m=A+44|0,g=A+48|0,_=A+52|0,v=A+56|0,y=A+60|0,n=0,t=0|jt[i>>2],r=0|jt[e>>2],i=0|jt[A>>2];;){if(z=0|C(S,x),i=i+(0|jt[w+(z<<2)>>2])&3,r=r+(0|jt[T+(z<<2)>>2])&3,z=0|C(S,x),G=(0|jt[o>>2])+(0|jt[w+(z<<2)>>2])&3,jt[o>>2]=G,z=(0|jt[a>>2])+(0|jt[T+(z<<2)>>2])&3,jt[a>>2]=z,U=0|C(S,x),V=(0|jt[l>>2])+(0|jt[w+(U<<2)>>2])&3,jt[l>>2]=V,U=(0|jt[u>>2])+(0|jt[T+(U<<2)>>2])&3,jt[u>>2]=U,F=0|C(S,x),B=(0|jt[c>>2])+(0|jt[w+(F<<2)>>2])&3,jt[c>>2]=B,F=(0|jt[d>>2])+(0|jt[T+(F<<2)>>2])&3,jt[d>>2]=F,N=0|C(S,x),k=(0|jt[h>>2])+(0|jt[w+(N<<2)>>2])&3,jt[h>>2]=k,N=(0|jt[p>>2])+(0|jt[T+(N<<2)>>2])&3,jt[p>>2]=N,R=0|C(S,x),L=(0|jt[f>>2])+(0|jt[w+(R<<2)>>2])&3,jt[f>>2]=L,R=(0|jt[m>>2])+(0|jt[T+(R<<2)>>2])&3,jt[m>>2]=R,O=0|C(S,x),M=(0|jt[g>>2])+(0|jt[w+(O<<2)>>2])&3,jt[g>>2]=M,O=(0|jt[_>>2])+(0|jt[T+(O<<2)>>2])&3,jt[_>>2]=O,D=0|C(S,x),I=(0|jt[v>>2])+(0|jt[w+(D<<2)>>2])&3,jt[v>>2]=I,D=(0|jt[y>>2])+(0|jt[T+(D<<2)>>2])&3,jt[y>>2]=D,jt[t>>2]=(0|Yt[1441+r>>0])<<2|0|Yt[1441+i>>0]|(0|Yt[1441+G>>0])<<4|(0|Yt[1441+z>>0])<<6|(0|Yt[1441+V>>0])<<8|(0|Yt[1441+U>>0])<<10|(0|Yt[1441+B>>0])<<12|(0|Yt[1441+F>>0])<<14|(0|Yt[1441+k>>0])<<16|(0|Yt[1441+N>>0])<<18|(0|Yt[1441+L>>0])<<20|(0|Yt[1441+R>>0])<<22|(0|Yt[1441+M>>0])<<24|(0|Yt[1441+O>>0])<<26|(0|Yt[1441+I>>0])<<28|(0|Yt[1441+D>>0])<<30,(n=n+1|0)>>>0>=b>>>0)break;t=t+4|0}jt[A>>2]=i,jt[e>>2]=r,t=1}}while(0)}else t=0;return X(x),G=t,or=P,0|G}function g(e,t,r,i,n,o,a,s){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,s|=0;var l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0,_=0,v=0,y=0,b=0,S=0,w=0,T=0,E=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=0,L=0,N=0,k=0,F=0,B=0,U=0,V=0,z=0,G=0,W=0,H=0,j=0,q=0,Y=0,X=0,Q=0,Z=0;if(Z=or,or=or+592|0,Y=Z+48|0,Q=Z+32|0,X=Z+16|0,q=Z,H=Z+80|0,j=Z+64|0,I=e+272|0,O=0|jt[I>>2],W=0|jt[e+88>>2],M=(0|Yt[W+63>>0])<<8|0|Yt[W+64>>0],W=0|zt[W+17>>0],R=255&W,!(W<<24>>24))return or=Z,1;L=0==(0|s),N=a+-1|0,k=N<<4,F=s+-1|0,B=i<<1,U=e+92|0,V=e+116|0,z=e+164|0,G=e+268|0,W=e+212|0,D=0==(1&n|0),P=0==(1&o|0),x=e+288|0,A=e+284|0,E=0,n=0,r=0,o=1;do{if(!L)for(w=0|jt[t+(E<<2)>>2],T=0;;){if(S=1&T,l=0==(0|S),b=(S<<5^32)-16|0,S=(S<<1^2)-1|0,v=l?a:-1,(0|(e=l?0:N))!=(0|v))for(y=P|(0|T)!=(0|F),_=l?w:w+k|0;;){1==(0|o)&&(o=512|C(U,V)),g=7&o,o>>>=3,u=0|Yt[1539+g>>0],l=0;do{p=(0|C(U,z))+r|0,f=p-O|0,m=f>>31,r=m&p|f&~m,(0|jt[I>>2])>>>0<=r>>>0&&(jt[q>>2]=866,jt[q+4>>2]=910,jt[q+8>>2]=1497,Ve(H,812,q),he(H)),jt[j+(l<<2)>>2]=Qt[(0|jt[G>>2])+(r<<1)>>1],l=l+1|0}while(l>>>0<u>>>0);for(m=D|(0|e)!=(0|N),p=0,f=_;;){if(h=y|0==(0|p),u=p<<1,l=(0|C(U,W))+n|0,c=l-M|0,d=c>>31,d=d&l|c&~d,m?(h&&(n=0|Yt[1547+(g<<2)+u>>0],l=3*d|0,(0|jt[x>>2])>>>0<=l>>>0&&(jt[X>>2]=866,jt[X+4>>2]=910,jt[X+8>>2]=1497,Ve(H,812,X),he(H)),c=(0|jt[A>>2])+(l<<1)|0,jt[f>>2]=(0|Qt[c>>1])<<16|jt[j+(n<<2)>>2],jt[f+4>>2]=(0|Qt[c+4>>1])<<16|0|Qt[c+2>>1]),c=f+8|0,l=(0|C(U,W))+d|0,d=l-M|0,n=d>>31,n=n&l|d&~n,h&&(l=0|Yt[1547+(g<<2)+(1|u)>>0],u=3*n|0,(0|jt[x>>2])>>>0<=u>>>0&&(jt[Y>>2]=866,jt[Y+4>>2]=910,jt[Y+8>>2]=1497,Ve(H,812,Y),he(H)),h=(0|jt[A>>2])+(u<<1)|0,jt[c>>2]=(0|Qt[h>>1])<<16|jt[j+(l<<2)>>2],jt[f+12>>2]=(0|Qt[h+4>>1])<<16|0|Qt[h+2>>1])):(h&&(n=0|Yt[1547+(g<<2)+u>>0],l=3*d|0,(0|jt[x>>2])>>>0<=l>>>0&&(jt[Q>>2]=866,jt[Q+4>>2]=910,jt[Q+8>>2]=1497,Ve(H,812,Q),he(H)),h=(0|jt[A>>2])+(l<<1)|0,jt[f>>2]=(0|Qt[h>>1])<<16|jt[j+(n<<2)>>2],jt[f+4>>2]=(0|Qt[h+4>>1])<<16|0|Qt[h+2>>1]),d=(0|C(U,W))+d|0,h=d-M|0,n=h>>31,n=n&d|h&~n),2==(0|(p=p+1|0)))break;f=f+i|0}if((0|(e=S+e|0))==(0|v))break;_=_+b|0}if((0|(T=T+1|0))==(0|s))break;w=w+B|0}E=E+1|0}while((0|E)!=(0|R));return or=Z,1}function _(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;if(c=e,l=t,u=l,a=r,h=i,s=h,!u)return o=0!=(0|n),s?o?(jt[n>>2]=0|e,jt[n+4>>2]=0&t,h=0,n=0,0|(cr=h,n)):(h=0,n=0,0|(cr=h,n)):(o&&(jt[n>>2]=(c>>>0)%(a>>>0),jt[n+4>>2]=0),h=0,n=(c>>>0)/(a>>>0)>>>0,0|(cr=h,n));o=0==(0|s);do{if(a){if(!o){if((o=(0|hr(0|s))-(0|hr(0|u))|0)>>>0<=31){d=o+1|0,s=31-o|0,t=o-31>>31,a=d,e=c>>>(d>>>0)&t|u<<s,t&=u>>>(d>>>0),o=0,s=c<<s;break}return n?(jt[n>>2]=0|e,jt[n+4>>2]=l|0&t,h=0,n=0,0|(cr=h,n)):(h=0,n=0,0|(cr=h,n))}if((o=a-1|0)&a|0){s=33+(0|hr(0|a))-(0|hr(0|u))|0,f=64-s|0,d=32-s|0,l=d>>31,p=s-32|0,t=p>>31,a=s,e=d-1>>31&u>>>(p>>>0)|(u<<d|c>>>(s>>>0))&t,t&=u>>>(s>>>0),o=c<<f&l,s=(u<<f|c>>>(p>>>0))&l|c<<d&s-33>>31;break}return 0|n&&(jt[n>>2]=o&c,jt[n+4>>2]=0),1==(0|a)?(p=l|0&t,f=0|e,0|(cr=p,f)):(f=0|xe(0|a),p=u>>>(f>>>0)|0,f=u<<32-f|c>>>(f>>>0)|0,0|(cr=p,f))}if(o)return 0|n&&(jt[n>>2]=(u>>>0)%(a>>>0),jt[n+4>>2]=0),p=0,f=(u>>>0)/(a>>>0)>>>0,0|(cr=p,f);if(!c)return 0|n&&(jt[n>>2]=0,jt[n+4>>2]=(u>>>0)%(s>>>0)),p=0,f=(u>>>0)/(s>>>0)>>>0,0|(cr=p,f);if(!((o=s-1|0)&s))return 0|n&&(jt[n>>2]=0|e,jt[n+4>>2]=o&u|0&t),p=0,f=u>>>((0|xe(0|s))>>>0),0|(cr=p,f);if((o=(0|hr(0|s))-(0|hr(0|u))|0)>>>0<=30){t=o+1|0,s=31-o|0,a=t,e=u<<s|c>>>(t>>>0),t=u>>>(t>>>0),o=0,s=c<<s;break}return n?(jt[n>>2]=0|e,jt[n+4>>2]=l|0&t,p=0,f=0,0|(cr=p,f)):(p=0,f=0,0|(cr=p,f))}while(0);if(a){d=0|r,c=h|0&i,u=0|Ke(0|d,0|c,-1,-1),r=cr,l=s,s=0;do{i=l,l=o>>>31|l<<1,o=s|o<<1,i=e<<1|i>>>31|0,h=e>>>31|t<<1|0,Ye(0|u,0|r,0|i,0|h),f=cr,p=f>>31|((0|f)<0?-1:0)<<1,s=1&p,e=0|Ye(0|i,0|h,p&d|0,(((0|f)<0?-1:0)>>31|((0|f)<0?-1:0)<<1)&c|0),t=cr,a=a-1|0}while(0!=(0|a));u=l,l=0}else u=s,l=0,s=0;return a=0,0|n&&(jt[n>>2]=e,jt[n+4>>2]=t),p=(0|o)>>>31|(u|a)<<1|0&(a<<1|o>>>31)|l,f=-2&(o<<1|0)|s,0|(cr=p,f)}function v(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0;if(d=e+4|0,c=0|jt[d>>2],r=-8&c,s=e+r|0,!(3&c))return t>>>0<256?0|(e=0):(r>>>0>=(t+4|0)>>>0?(r-t|0)>>>0<=jt[1264]<<1>>>0:0)?0|e:0|(e=0);if(r>>>0>=t>>>0)return(r=r-t|0)>>>0<=15?0|e:(u=e+t|0,jt[d>>2]=1&c|t|2,jt[u+4>>2]=3|r,d=u+r+4|0,jt[d>>2]=1|jt[d>>2],p(u,r),0|e);if((0|s)==(0|jt[1150]))return u=(0|jt[1147])+r|0,r=u-t|0,i=e+t|0,u>>>0<=t>>>0?0|(e=0):(jt[d>>2]=1&c|t|2,jt[i+4>>2]=1|r,jt[1150]=i,jt[1147]=r,0|e);if((0|s)==(0|jt[1149]))return(n=(0|jt[1146])+r|0)>>>0<t>>>0?0|(e=0):(r=n-t|0,i=1&c,r>>>0>15?(c=e+t|0,u=c+r|0,jt[d>>2]=i|t|2,jt[c+4>>2]=1|r,jt[u>>2]=r,i=u+4|0,jt[i>>2]=-2&jt[i>>2],i=c):(jt[d>>2]=i|n|2,i=e+n+4|0,jt[i>>2]=1|jt[i>>2],i=0,r=0),jt[1146]=r,jt[1149]=i,0|e);if(2&(i=0|jt[s+4>>2])|0)return 0|(e=0);if((l=(-8&i)+r|0)>>>0<t>>>0)return 0|(e=0);u=l-t|0,n=i>>>3;do{if(i>>>0<256){if(i=0|jt[s+8>>2],(0|(r=0|jt[s+12>>2]))==(0|i)){jt[1144]=jt[1144]&~(1<<n);break}jt[i+12>>2]=r,jt[r+8>>2]=i;break}a=0|jt[s+24>>2],r=0|jt[s+12>>2];do{if((0|r)==(0|s)){if(n=s+16|0,i=n+4|0,r=0|jt[i>>2])o=i;else{if(!(r=0|jt[n>>2])){n=0;break}o=n}for(;;)if(n=r+20|0,0|(i=0|jt[n>>2]))r=i,o=n;else{if(i=r+16|0,!(n=0|jt[i>>2]))break;r=n,o=i}jt[o>>2]=0,n=r}else n=0|jt[s+8>>2],jt[n+12>>2]=r,jt[r+8>>2]=n,n=r}while(0);if(0|a){if(r=0|jt[s+28>>2],i=4880+(r<<2)|0,(0|s)==(0|jt[i>>2])){if(jt[i>>2]=n,!n){jt[1145]=jt[1145]&~(1<<r);break}}else if(jt[a+16+(((0|jt[a+16>>2])!=(0|s)&1)<<2)>>2]=n,!n)break;jt[n+24>>2]=a,r=s+16|0,i=0|jt[r>>2],0|i&&(jt[n+16>>2]=i,jt[i+24>>2]=n),r=0|jt[r+4>>2],0|r&&(jt[n+20>>2]=r,jt[r+24>>2]=n)}}while(0);return r=1&c,u>>>0<16?(jt[d>>2]=l|r|2,d=e+l+4|0,jt[d>>2]=1|jt[d>>2],0|e):(c=e+t|0,jt[d>>2]=r|t|2,jt[c+4>>2]=3|u,d=c+u+4|0,jt[d>>2]=1|jt[d>>2],p(c,u),0|e)}function y(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0;var a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;switch(f=or,or=or+592|0,p=f+56|0,l=f+40|0,d=f+72|0,c=f,h=f+68|0,jt[c>>2]=40,U(e,t,c),a=(0|jt[c+4>>2])>>>n,s=(0|jt[c+8>>2])>>>n,c=c+32|0,i=0|jt[c+4>>2],0|jt[c>>2]){case 0:i?u=14:c=8;break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:u=i?14:13;break;case 9:case 10:i?u=14:c=8;break;default:u=14}13==(0|u)?c=16:14==(0|u)&&(jt[l>>2]=866,jt[l+4>>2]=2672,jt[l+8>>2]=1251,Ve(d,812,l),he(d),c=0),jt[h>>2]=r,u=0|A(e,t),t=o+n|0;do{if(t>>>0>n>>>0){if(!u){for(i=r;;){if(i=i+(0|dr(0|dr((a+3|0)>>>2,c),(s+3|0)>>>2))|0,(0|(n=n+1|0))==(0|t))break;s>>>=1,a>>>=1}jt[h>>2]=i;break}for(e=s,i=r;;){if(s=0|dr((a+3|0)>>>2,c),l=0|dr(s,(e+3|0)>>>2),(n>>>0>15|l>>>0<8?0:519686845==(0|jt[u>>2]))&&(G(u,h,l,s,n),i=0|jt[h>>2]),i=i+l|0,jt[h>>2]=i,(0|(n=n+1|0))==(0|t))break;e>>>=1,a>>>=1}}}while(0);return u?519686845!=(0|jt[u>>2])?void(or=f):(S(u),7&u?(jt[p>>2]=866,jt[p+4>>2]=2506,jt[p+8>>2]=1232,Ve(d,812,p),he(d),void(or=f)):(oe(u,0,0,1,0),void(or=f))):void(or=f)}function b(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;if(f=or,or=or+576|0,a=f,n=f+64|0,p=f+16|0,i=e+88|0,t=0|jt[i>>2],h=(0|Yt[t+39>>0])<<8|0|Yt[t+40>>0],c=e+236|0,o=e+240|0,(0|(r=0|jt[o>>2]))!=(0|h)){if(r>>>0<=h>>>0){do{if((0|jt[e+244>>2])>>>0<h>>>0){if(0|E(c,h,(r+1|0)==(0|h),4,0)){t=0|jt[o>>2];break}return zt[e+248>>0]=1,p=0,or=f,0|p}t=r}while(0);ee((0|jt[c>>2])+(t<<2)|0,0,h-t<<2|0),t=0|jt[i>>2]}jt[o>>2]=h}if(d=e+92|0,r=(0|jt[e+4>>2])+((0|Yt[t+34>>0])<<8|(0|Yt[t+33>>0])<<16|0|Yt[t+35>>0])|0,!(t=(0|Yt[t+37>>0])<<8|(0|Yt[t+36>>0])<<16|0|Yt[t+38>>0]))return p=0,or=f,0|p;if(jt[d>>2]=r,jt[e+96>>2]=r,jt[e+104>>2]=t,jt[e+100>>2]=r+t,jt[e+108>>2]=0,jt[e+112>>2]=0,l=p+20|0,jt[p>>2]=0,jt[p+4>>2]=0,jt[p+8>>2]=0,jt[p+12>>2]=0,zt[p+16>>0]=0,u=p+24|0,jt[p+44>>2]=0,jt[l>>2]=0,jt[l+4>>2]=0,jt[l+8>>2]=0,jt[l+12>>2]=0,jt[l+16>>2]=0,zt[l+20>>0]=0,0|s(d,p)?0|s(d,u):0)if(0|jt[o>>2]||(jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(n,812,a),he(n)),h)for(a=0,l=0,r=0|jt[c>>2],i=0,e=0,t=0,n=0,o=0;;){if(a=(0|C(d,p))+a&31,o=(0|C(d,u))+o&63,n=(0|C(d,p))+n&31,t=(0|C(d,p))+t|0,e=(0|C(d,u))+e&63,i=(0|C(d,p))+i&31,jt[r>>2]=o<<5|a<<11|n|t<<27|e<<21|i<<16,(l=l+1|0)>>>0>=h>>>0){t=1;break}r=r+4|0,t&=31}else t=1;else t=0;return X(p+24|0),X(p),p=t,or=f,0|p}function C(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0;m=or,or=or+576|0,u=m+48|0,d=m+32|0,c=m+16|0,l=m,p=m+64|0,h=0|jt[t+20>>2],f=e+20|0,s=0|jt[f>>2],(0|s)<24?(a=e+4|0,r=0|jt[a>>2],n=0|jt[e+8>>2],i=r>>>0<n>>>0,(0|s)<16?(i?(o=(0|Yt[r>>0])<<8,r=r+1|0):o=0,r>>>0<n>>>0?(n=0|Yt[r>>0],r=r+1|0):n=0,jt[a>>2]=r,jt[f>>2]=s+16,i=16,r=n|o):(i?(jt[a>>2]=r+1,r=0|Yt[r>>0]):r=0,jt[f>>2]=s+8,i=24),a=e+16|0,n=jt[a>>2]|r<<i-s,jt[a>>2]=n):(n=e+16|0,a=n,n=0|jt[n>>2]),o=1+(n>>>16)|0;do{if(!(o>>>0<=(0|jt[h+16>>2])>>>0)){for(i=0|jt[h+20>>2];;){if(r=i+-1|0,!(o>>>0>(0|jt[h+28+(r<<2)>>2])>>>0))break;i=i+1|0}if((r=(n>>>(32-i|0))+(0|jt[h+96+(r<<2)>>2])|0)>>>0<(0|jt[t>>2])>>>0){r=0|Qt[(0|jt[h+176>>2])+(r<<1)>>1];break}return jt[u>>2]=866,jt[u+4>>2]=3275,jt[u+8>>2]=1348,Ve(p,812,u),he(p),f=0,or=m,0|f}i=0|jt[(0|jt[h+168>>2])+(n>>>(32-(0|jt[h+8>>2])|0)<<2)>>2],-1==(0|i)&&(jt[l>>2]=866,jt[l+4>>2]=3253,jt[l+8>>2]=1393,Ve(p,812,l),he(p)),r=65535&i,i>>>=16,(0|jt[t+8>>2])>>>0<=r>>>0&&(jt[c>>2]=866,jt[c+4>>2]=909,jt[c+8>>2]=1497,Ve(p,812,c),he(p)),(0|Yt[(0|jt[t+4>>2])+r>>0])!=(0|i)&&(jt[d>>2]=866,jt[d+4>>2]=3257,jt[d+8>>2]=1410,Ve(p,812,d),he(p))}while(0);return jt[a>>2]=jt[a>>2]<<i,jt[f>>2]=(0|jt[f>>2])-i,f=r,or=m,0|f}function S(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0;if(l=or,or=or+576|0,s=l+48|0,o=l+32|0,n=l+16|0,i=l,a=l+64|0,jt[e>>2]=0,t=e+284|0,r=0|jt[t>>2],0|r&&(7&r?(jt[i>>2]=866,jt[i+4>>2]=2506,jt[i+8>>2]=1232,Ve(a,812,i),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+288>>2]=0,jt[e+292>>2]=0),zt[e+296>>0]=0,t=e+268|0,r=0|jt[t>>2],0|r&&(7&r?(jt[n>>2]=866,jt[n+4>>2]=2506,jt[n+8>>2]=1232,Ve(a,812,n),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+272>>2]=0,jt[e+276>>2]=0),zt[e+280>>0]=0,t=e+252|0,r=0|jt[t>>2],0|r&&(7&r?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1232,Ve(a,812,o),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+256>>2]=0,jt[e+260>>2]=0),zt[e+264>>0]=0,t=e+236|0,!(r=0|jt[t>>2]))return s=e+248|0,zt[s>>0]=0,s=e+212|0,X(s),s=e+188|0,X(s),s=e+164|0,X(s),s=e+140|0,X(s),s=e+116|0,X(s),void(or=l);7&r?(jt[s>>2]=866,jt[s+4>>2]=2506,jt[s+8>>2]=1232,Ve(a,812,s),he(a)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+240>>2]=0,jt[e+244>>2]=0,s=e+248|0,zt[s>>0]=0,s=e+212|0,X(s),s=e+188|0,X(s),s=e+164|0,X(s),s=e+140|0,X(s),s=e+116|0,X(s),or=l}function w(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0;e:do{if(t>>>0<=20)switch(0|t){case 9:i=3+(0|jt[r>>2])&-4,t=0|jt[i>>2],jt[r>>2]=i+4,jt[e>>2]=t;break e;case 10:i=3+(0|jt[r>>2])&-4,t=0|jt[i>>2],jt[r>>2]=i+4,i=e,jt[i>>2]=t,jt[i+4>>2]=((0|t)<0)<<31>>31;break e;case 11:i=3+(0|jt[r>>2])&-4,t=0|jt[i>>2],jt[r>>2]=i+4,i=e,jt[i>>2]=t,jt[i+4>>2]=0;break e;case 12:i=7+(0|jt[r>>2])&-8,t=i,n=0|jt[t>>2],t=0|jt[t+4>>2],jt[r>>2]=i+8,i=e,jt[i>>2]=n,jt[i+4>>2]=t;break e;case 13:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,i=(65535&i)<<16>>16,n=e,jt[n>>2]=i,jt[n+4>>2]=((0|i)<0)<<31>>31;break e;case 14:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,n=e,jt[n>>2]=65535&i,jt[n+4>>2]=0;break e;case 15:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,i=(255&i)<<24>>24,n=e,jt[n>>2]=i,jt[n+4>>2]=((0|i)<0)<<31>>31;break e;case 16:n=3+(0|jt[r>>2])&-4,i=0|jt[n>>2],jt[r>>2]=n+4,n=e,jt[n>>2]=255&i,jt[n+4>>2]=0;break e;case 17:case 18:n=7+(0|jt[r>>2])&-8,o=+tr[n>>3],jt[r>>2]=n+8,tr[e>>3]=o;break e;default:break e}}while(0)}function T(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,l=0,u=0,c=0;if(c=or,or=or+560|0,n=c,i=c+40|0,u=c+16|0,r=0|jt[e+88>>2],a=(0|Yt[r+55>>0])<<8|0|Yt[r+56>>0],l=e+92|0,t=(0|jt[e+4>>2])+((0|Yt[r+50>>0])<<8|(0|Yt[r+49>>0])<<16|0|Yt[r+51>>0])|0,!(r=(0|Yt[r+53>>0])<<8|(0|Yt[r+52>>0])<<16|0|Yt[r+54>>0]))return u=0,or=c,0|u;jt[l>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,jt[u+20>>2]=0,jt[u>>2]=0,jt[u+4>>2]=0,jt[u+8>>2]=0,jt[u+12>>2]=0,zt[u+16>>0]=0;e:do{if(0|s(l,u)){if(o=e+268|0,r=e+272|0,(0|(t=0|jt[r>>2]))!=(0|a)){if(t>>>0<=a>>>0){do{if((0|jt[e+276>>2])>>>0<a>>>0){if(0|E(o,a,(t+1|0)==(0|a),2,0)){t=0|jt[r>>2];break}zt[e+280>>0]=1,t=0;break e}}while(0);ee((0|jt[o>>2])+(t<<1)|0,0,a-t<<1|0)}jt[r>>2]=a}if(!a){jt[n>>2]=866,jt[n+4>>2]=910,jt[n+8>>2]=1497,Ve(i,812,n),he(i),t=1;break}for(r=0,e=0,i=0,t=0|jt[o>>2];;){if(o=0|C(l,u),i=o+i&255,e=(0|C(l,u))+e&255,Wt[t>>1]=e<<8|i,(r=r+1|0)>>>0>=a>>>0){t=1;break}t=t+2|0}}else t=0}while(0);return X(u),u=t,or=c,0|u}function E(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0;if(f=or,or=or+576|0,d=f+48|0,l=f+32|0,a=f+16|0,o=f,c=f+64|0,h=f+60|0,u=e+4|0,p=e+8|0,(0|jt[u>>2])>>>0>(0|jt[p>>2])>>>0&&(jt[o>>2]=866,jt[o+4>>2]=2123,jt[o+8>>2]=845,Ve(c,812,o),he(c)),(2147418112/(i>>>0)|0)>>>0<=t>>>0&&(jt[a>>2]=866,jt[a+4>>2]=2124,jt[a+8>>2]=885,Ve(c,812,a),he(c)),(o=0|jt[p>>2])>>>0>=t>>>0)return p=1,or=f,0|p;if((r?0!=((s=t+-1|0)&t|0):0)?(t=s>>>16|s,t|=t>>>8,t|=t>>>4,t|=t>>>2,t=1+(t>>>1|t)|0,t?r=9:(t=0,r=10)):r=9,9==(0|r)&&t>>>0<=o>>>0&&(r=10),10==(0|r)&&(jt[l>>2]=866,jt[l+4>>2]=2133,jt[l+8>>2]=933,Ve(c,812,l),he(c)),s=0|dr(t,i),n)if(a=0|Q(s,h)){Mr[0&n](a,0|jt[e>>2],0|jt[u>>2]),o=0|jt[e>>2];do{if(0|o){if(7&o){jt[d>>2]=866,jt[d+4>>2]=2506,jt[d+8>>2]=1232,Ve(c,812,d),he(c);break}oe(o,0,0,1,0);break}}while(0);jt[e>>2]=a,r=20}else t=0;else o=0|J(0|jt[e>>2],s,h,1),o?(jt[e>>2]=o,r=20):t=0;return 20==(0|r)&&(o=0|jt[h>>2],o>>>0>s>>>0&&(t=(o>>>0)/(i>>>0)|0),jt[p>>2]=t,t=1),p=t,or=f,0|p}function A(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0;if(h=or,or=or+528|0,c=h,s=h+16|0,0==(0|e)|t>>>0<62)return p=0,or=h,0|p;if(!(l=0|Q(300,0)))return p=0,or=h,0|p;jt[l>>2]=519686845,jt[l+4>>2]=0,jt[l+8>>2]=0,u=l+88|0,r=l+136|0,i=l+160|0,n=l+184|0,o=l+208|0,a=l+232|0,d=l+252|0,jt[d>>2]=0,jt[d+4>>2]=0,jt[d+8>>2]=0,zt[d+12>>0]=0,d=l+268|0,jt[d>>2]=0,jt[d+4>>2]=0,jt[d+8>>2]=0,zt[d+12>>0]=0,d=l+284|0,jt[d>>2]=0,jt[d+4>>2]=0,jt[d+8>>2]=0,zt[d+12>>0]=0,d=u,p=d+44|0;do{jt[d>>2]=0,d=d+4|0}while((0|d)<(0|p));return zt[u+44>>0]=0,jt[r>>2]=0,jt[r+4>>2]=0,jt[r+8>>2]=0,jt[r+12>>2]=0,jt[r+16>>2]=0,zt[r+20>>0]=0,jt[i>>2]=0,jt[i+4>>2]=0,jt[i+8>>2]=0,jt[i+12>>2]=0,jt[i+16>>2]=0,zt[i+20>>0]=0,jt[n>>2]=0,jt[n+4>>2]=0,jt[n+8>>2]=0,jt[n+12>>2]=0,jt[n+16>>2]=0,zt[n+20>>0]=0,jt[o>>2]=0,jt[o+4>>2]=0,jt[o+8>>2]=0,jt[o+12>>2]=0,jt[o+16>>2]=0,zt[o+20>>0]=0,jt[a>>2]=0,jt[a+4>>2]=0,jt[a+8>>2]=0,jt[a+12>>2]=0,zt[a+16>>0]=0,0|W(l,e,t)?(p=l,or=h,0|p):(S(l),7&l?(jt[c>>2]=866,jt[c+4>>2]=2506,jt[c+8>>2]=1232,Ve(s,812,c),he(s),p=0,or=h,0|p):(oe(l,0,0,1,0),p=0,or=h,0|p))}function x(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0,l=0;switch(s=or,or=or+576|0,o=s+40|0,n=s+56|0,l=s,jt[l>>2]=40,U(e,t,l),i=(3+((0|jt[l+4>>2])>>>r)|0)>>>2,t=(3+((0|jt[l+8>>2])>>>r)|0)>>>2,r=l+32|0,e=0|jt[r+4>>2],0|jt[r>>2]){case 0:e?a=14:e=8;break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:a=e?14:13;break;case 9:case 10:e?a=14:e=8;break;default:a=14}return 13==(0|a)?e=16:14==(0|a)&&(jt[o>>2]=866,jt[o+4>>2]=2672,jt[o+8>>2]=1251,Ve(n,812,o),he(n),e=0),l=0|dr(0|dr(t,i),e),or=s,0|l}function P(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0;switch(n=or,or=or+576|0,i=n+40|0,r=n+56|0,o=n,jt[o>>2]=40,U(e,t,o),t=o+32|0,e=0|jt[t+4>>2],0|jt[t>>2]){case 0:if(!e)return o=8,or=n,0|o;e=14;break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:e=e?14:13;break;case 9:case 10:if(!e)return o=8,or=n,0|o;e=14;break;default:e=14}return 13==(0|e)?(o=16,or=n,0|o):14==(0|e)?(jt[i>>2]=866,jt[i+4>>2]=2672,jt[i+8>>2]=1251,Ve(r,812,i),he(r),o=0,or=n,0|o):0}function D(e,t,r,i,n,o,a){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0;var s=0,l=0,d=0,p=0;if(p=0|jt[e+88>>2],l=(Yt[p+12>>0]<<8|Yt[p+13>>0])>>>a,d=(Yt[p+14>>0]<<8|Yt[p+15>>0])>>>a,l=((l>>>0>1?l:1)+3|0)>>>2,d=((d>>>0>1?d:1)+3|0)>>>2,p=p+18|0,a=0|zt[p>>0],a=0|dr(l,a<<24>>24==0|a<<24>>24==9?8:16),o){if(!(0==(3&o|0)&a>>>0<=o>>>0))return 0|(n=0);a=o}if((0|dr(a,d))>>>0>n>>>0)return 0|(n=0);if(o=(l+1|0)>>>1,s=(d+1|0)>>>1,!r)return 0|(n=0);switch(jt[e+92>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,0|zt[p>>0]){case 0:if(!(0|u(e,i,n,a,l,d,o,s)))return 0|(n=0);break;case 4:case 6:case 5:case 3:case 2:if(!(0|h(e,i,n,a,l,d,o,s)))return 0|(n=0);break;case 9:if(!(0|g(e,i,n,a,l,d,o,s)))return 0|(n=0);break;case 8:case 7:if(!(0|c(e,i,n,a,l,d,o,s)))return 0|(n=0);break;default:return 0|(n=0)}return 0|(n=1)}function I(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0;if((0|r)>=8192)return 0|Tr(0|e,0|t,0|r);if(o=0|e,n=e+r|0,(3&e)==(3&t)){for(;3&e;){if(!r)return 0|o;zt[e>>0]=0|zt[t>>0],e=e+1|0,t=t+1|0,r=r-1|0}for(r=-4&n|0,i=r-64|0;(0|e)<=(0|i);)jt[e>>2]=jt[t>>2],jt[e+4>>2]=jt[t+4>>2],jt[e+8>>2]=jt[t+8>>2],jt[e+12>>2]=jt[t+12>>2],jt[e+16>>2]=jt[t+16>>2],jt[e+20>>2]=jt[t+20>>2],jt[e+24>>2]=jt[t+24>>2],jt[e+28>>2]=jt[t+28>>2],jt[e+32>>2]=jt[t+32>>2],jt[e+36>>2]=jt[t+36>>2],jt[e+40>>2]=jt[t+40>>2],jt[e+44>>2]=jt[t+44>>2],jt[e+48>>2]=jt[t+48>>2],jt[e+52>>2]=jt[t+52>>2],jt[e+56>>2]=jt[t+56>>2],jt[e+60>>2]=jt[t+60>>2],e=e+64|0,t=t+64|0;for(;(0|e)<(0|r);)jt[e>>2]=jt[t>>2],e=e+4|0,t=t+4|0}else for(r=n-4|0;(0|e)<(0|r);)zt[e>>0]=0|zt[t>>0],zt[e+1>>0]=0|zt[t+1>>0],zt[e+2>>0]=0|zt[t+2>>0],zt[e+3>>0]=0|zt[t+3>>0],e=e+4|0,t=t+4|0;for(;(0|e)<(0|n);)zt[e>>0]=0|zt[t>>0],e=e+1|0,t=t+1|0;return 0|o}function O(e){e|=0;var t=0,r=0,i=0,n=0;if(n=e+92|0,i=e+88|0,r=0|jt[i>>2],t=(0|jt[e+4>>2])+((0|Yt[r+68>>0])<<8|(0|Yt[r+67>>0])<<16|0|Yt[r+69>>0])|0,!(r=(0|Yt[r+65>>0])<<8|0|Yt[r+66>>0]))return 0|(n=0);if(jt[n>>2]=t,jt[e+96>>2]=t,jt[e+104>>2]=r,jt[e+100>>2]=t+r,jt[e+108>>2]=0,jt[e+112>>2]=0,!(0|s(n,e+116|0)))return 0|(n=0);t=0|jt[i>>2];do{if((0|Yt[t+39>>0])<<8|0|Yt[t+40>>0]){if(!(0|s(n,e+140|0)))return 0|(n=0);if(0|s(n,e+188|0)){t=0|jt[i>>2];break}return 0|(n=0)}if(!((0|Yt[t+55>>0])<<8|0|Yt[t+56>>0]))return 0|(n=0)}while(0);if((0|Yt[t+55>>0])<<8|0|Yt[t+56>>0]|0){if(!(0|s(n,e+164|0)))return 0|(n=0);if(!(0|s(n,e+212|0)))return 0|(n=0)}return 0|(n=1)}function M(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0;d=or,or=or+48|0,u=d+16|0,o=d,n=d+32|0,s=e+28|0,i=0|jt[s>>2],jt[n>>2]=i,l=e+20|0,i=(0|jt[l>>2])-i|0,jt[n+4>>2]=i,jt[n+8>>2]=t,jt[n+12>>2]=r,i=i+r|0,a=e+60|0,jt[o>>2]=jt[a>>2],jt[o+4>>2]=n,jt[o+8>>2]=2,o=0|$e(0|xr(146,0|o));e:do{if((0|i)!=(0|o)){for(t=2;;){if((0|o)<0)break;if(i=i-o|0,p=0|jt[n+4>>2],h=o>>>0>p>>>0,n=h?n+8|0:n,t=(h<<31>>31)+t|0,p=o-(h?p:0)|0,jt[n>>2]=(0|jt[n>>2])+p,h=n+4|0,jt[h>>2]=(0|jt[h>>2])-p,jt[u>>2]=jt[a>>2],jt[u+4>>2]=n,jt[u+8>>2]=t,o=0|$e(0|xr(146,0|u)),(0|i)==(0|o)){c=3;break e}}jt[e+16>>2]=0,jt[s>>2]=0,jt[l>>2]=0,jt[e>>2]=32|jt[e>>2],r=2==(0|t)?0:r-(0|jt[n+4>>2])|0}else c=3}while(0);return 3==(0|c)&&(p=0|jt[e+44>>2],jt[e+16>>2]=p+(0|jt[e+48>>2]),jt[s>>2]=p,jt[l>>2]=p),or=d,0|r}function R(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0;do{if(0|lt(e,0|jt[t+8>>2],n))Pe(0,t,r,i);else{if(o=e+8|0,!(0|lt(e,0|jt[t>>2],n))){s=0|jt[o>>2],Dr[3&jt[24+(0|jt[s>>2])>>2]](s,t,r,i,n);break}if(e=t+32|0,(0|jt[t+16>>2])!=(0|r)?(a=t+20|0,(0|jt[a>>2])!=(0|r)):0){if(jt[e>>2]=i,i=t+44|0,4==(0|jt[i>>2]))break;e=t+52|0,zt[e>>0]=0,l=t+53|0,zt[l>>0]=0,o=0|jt[o>>2],Lr[3&jt[20+(0|jt[o>>2])>>2]](o,t,r,r,1,n),0|zt[l>>0]?0|zt[e>>0]?e=3:(e=3,s=11):(e=4,s=11),11==(0|s)&&(jt[a>>2]=r,l=t+40|0,jt[l>>2]=1+(0|jt[l>>2]),(1==(0|jt[t+36>>2])?2==(0|jt[t+24>>2]):0)&&(zt[t+54>>0]=1)),jt[i>>2]=e;break}1==(0|i)&&(jt[e>>2]=1)}}while(0)}function L(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,s=0,l=0,u=0,c=0,d=0,h=0,p=0,f=0,m=0,g=0;g=or,or=or+224|0,d=g+120|0,h=g+80|0,f=g,m=g+136|0,i=h,n=i+40|0;do{jt[i>>2]=0,i=i+4|0}while((0|i)<(0|n));return jt[d>>2]=jt[r>>2],(0|a(0,t,d,f,h))<0?r=-1:(p=(0|jt[e+76>>2])>-1?0|Nt(e):0,r=0|jt[e>>2],c=32&r,(0|zt[e+74>>0])<1&&(jt[e>>2]=-33&r),i=e+48|0,0|jt[i>>2]?r=0|a(e,t,d,f,h):(n=e+44|0,o=0|jt[n>>2],jt[n>>2]=m,s=e+28|0,jt[s>>2]=m,l=e+20|0,jt[l>>2]=m,jt[i>>2]=80,u=e+16|0,jt[u>>2]=m+80,r=0|a(e,t,d,f,h),o&&(Pr[7&jt[e+36>>2]](e,0,0),r=0==(0|jt[l>>2])?-1:r,jt[n>>2]=o,jt[i>>2]=0,jt[u>>2]=0,jt[s>>2]=0,jt[l>>2]=0)),i=0|jt[e>>2],jt[e>>2]=i|c,0|p&&Lt(e),r=0==(32&i|0)?r:-1),or=g,0|r}function N(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0;h=or,or=or+64|0,c=h,u=0|jt[e>>2],d=e+(0|jt[u+-8>>2])|0,u=0|jt[u+-4>>2],jt[c>>2]=r,jt[c+4>>2]=e,jt[c+8>>2]=t,jt[c+12>>2]=i,e=c+16|0,t=c+20|0,i=c+24|0,n=c+28|0,o=c+32|0,a=c+40|0,s=e,l=s+36|0;do{jt[s>>2]=0,s=s+4|0}while((0|s)<(0|l));Wt[e+36>>1]=0,zt[e+38>>0]=0;e:do{if(0|lt(u,r,0))jt[c+48>>2]=1,Lr[3&jt[20+(0|jt[u>>2])>>2]](u,c,d,d,1,0),e=1==(0|jt[i>>2])?d:0;else{switch(Dr[3&jt[24+(0|jt[u>>2])>>2]](u,c,d,1,0),0|jt[c+36>>2]){case 0:e=1==(0|jt[a>>2])&1==(0|jt[n>>2])&1==(0|jt[o>>2])?0|jt[t>>2]:0;break e;case 1:break;default:e=0;break e}if(1!=(0|jt[i>>2])?!(0==(0|jt[a>>2])&1==(0|jt[n>>2])&1==(0|jt[o>>2])):0){e=0;break}e=0|jt[e>>2]}}while(0);return or=h,0|e}function k(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,u=0;if(u=or,or=or+544|0,a=u+16|0,t=u,n=u+32|0,o=e+8|0,r=0|jt[o>>2],(r+-1|0)>>>0>=8192&&(jt[t>>2]=866,jt[t+4>>2]=3006,jt[t+8>>2]=1257,Ve(n,812,t),he(n)),jt[e>>2]=r,i=e+20|0,t=0|jt[i>>2],t?s=r:(t=0|Q(180,0),t?(s=t+164|0,jt[s>>2]=0,jt[s+4>>2]=0,jt[s+8>>2]=0,jt[s+12>>2]=0):t=0,jt[i>>2]=t,s=0|jt[e>>2]),0|jt[o>>2]?a=s:(jt[a>>2]=866,jt[a+4>>2]=910,jt[a+8>>2]=1497,Ve(n,812,a),he(n),a=0|jt[e>>2]),n=0|jt[e+4>>2],!(a>>>0>16))return e=0,e=0|l(t,s,n,e),or=u,0|e;for(r=a,i=0;;){if(o=i+1|0,!(r>>>0>3))break;r>>>=1,i=o}return e=i+2+(32!=(0|o)&1<<o>>>0<a>>>0&1)|0,e=255&(e>>>0<11?e:11),e=0|l(t,s,n,e),or=u,0|e}function F(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0,l=0,u=0,c=0,d=0,h=0;h=1794895138+(0|jt[e>>2])|0,o=0|ut(0|jt[e+8>>2],h),i=0|ut(0|jt[e+12>>2],h),n=0|ut(0|jt[e+16>>2],h);e:do{if((o>>>0<t>>>2>>>0?(d=t-(o<<2)|0,i>>>0<d>>>0&n>>>0<d>>>0):0)?0==(3&(n|i)|0):0){for(d=i>>>2,c=n>>>2,u=0;;){if(s=o>>>1,l=u+s|0,a=l<<1,n=a+d|0,i=0|ut(0|jt[e+(n<<2)>>2],h),!((n=0|ut(0|jt[e+(n+1<<2)>>2],h))>>>0<t>>>0&i>>>0<(t-n|0)>>>0)){i=0;break e}if(0|zt[e+(n+i)>>0]){i=0;break e}if(!(i=0|ve(r,e+n|0)))break;if(i=(0|i)<0,1==(0|o)){i=0;break e}u=i?u:l,o=i?s:o-s|0}i=a+c|0,n=0|ut(0|jt[e+(i<<2)>>2],h),i=0|ut(0|jt[e+(i+1<<2)>>2],h),i=i>>>0<t>>>0&n>>>0<(t-i|0)>>>0&&0==(0|zt[e+(i+n)>>0])?e+i|0:0}else i=0}while(0);return 0|i}function B(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0,s=0,l=0;s=or,or=or+576|0,o=s+48|0,a=s+32|0,i=s+16|0,r=s,n=s+64|0,t=0|jt[e+168>>2];do{ +if(0|t){if(l=0|jt[t+-4>>2],t=t+-8|0,(0!=(0|l)?(0|l)==(0|~jt[t>>2]):0)||(jt[r>>2]=866,jt[r+4>>2]=651,jt[r+8>>2]=1579,Ve(n,812,r),he(n)),7&t){jt[i>>2]=866,jt[i+4>>2]=2506,jt[i+8>>2]=1232,Ve(n,812,i),he(n);break}oe(t,0,0,1,0);break}}while(0);return(t=0|jt[e+176>>2])?(l=0|jt[t+-4>>2],t=t+-8|0,(0!=(0|l)?(0|l)==(0|~jt[t>>2]):0)||(jt[a>>2]=866,jt[a+4>>2]=651,jt[a+8>>2]=1579,Ve(n,812,a),he(n)),7&t?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1232,Ve(n,812,o),he(n),void(or=s)):(oe(t,0,0,1,0),void(or=s))):void(or=s)}function U(e,t,r){e|=0,t|=0,r|=0;var i=0;return 0!=(0|e)&t>>>0>73&0!=(0|r)?40!=(0|jt[r>>2])?0|(r=0):18552!=((0|Yt[e>>0])<<8|0|Yt[e+1>>0]|0)?0|(r=0):((0|Yt[e+2>>0])<<8|0|Yt[e+3>>0])>>>0<74?0|(r=0):((0|Yt[e+7>>0])<<16|(0|Yt[e+6>>0])<<24|(0|Yt[e+8>>0])<<8|0|Yt[e+9>>0])>>>0>t>>>0?0|(r=0):(jt[r+4>>2]=(0|Yt[e+12>>0])<<8|0|Yt[e+13>>0],jt[r+8>>2]=(0|Yt[e+14>>0])<<8|0|Yt[e+15>>0],jt[r+12>>2]=Yt[e+16>>0],jt[r+16>>2]=Yt[e+17>>0],t=e+18|0,i=r+32|0,jt[i>>2]=Yt[t>>0],jt[i+4>>2]=0,t=0|zt[t>>0],jt[r+20>>2]=t<<24>>24==0|t<<24>>24==9?8:16,jt[r+24>>2]=(0|Yt[e+26>>0])<<16|(0|Yt[e+25>>0])<<24|(0|Yt[e+27>>0])<<8|0|Yt[e+28>>0],jt[r+28>>2]=(0|Yt[e+30>>0])<<16|(0|Yt[e+29>>0])<<24|(0|Yt[e+31>>0])<<8|0|Yt[e+32>>0],0|(r=1)):0|(r=0)}function V(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0;if(u=or,or=or+544|0,s=u+16|0,r=u,a=u+32|0,t>>>0>=33&&(jt[r>>2]=866,jt[r+4>>2]=3199,jt[r+8>>2]=1350,Ve(a,812,r),he(a)),l=e+20|0,(0|(r=0|jt[l>>2]))>=(0|t))return n=e+16|0,o=n,n=0|jt[n>>2],a=r,s=32-t|0,s=n>>>s,n<<=t,jt[o>>2]=n,t=a-t|0,jt[l>>2]=t,or=u,0|s;n=e+4|0,o=e+8|0,i=e+16|0;do{e=0|jt[n>>2],(0|e)==(0|jt[o>>2])?e=0:(jt[n>>2]=e+1,e=0|Yt[e>>0]),r=r+8|0,jt[l>>2]=r,(0|r)>=33&&(jt[s>>2]=866,jt[s+4>>2]=3208,jt[s+8>>2]=1366,Ve(a,812,s),he(a),r=0|jt[l>>2]),e=e<<32-r|jt[i>>2],jt[i>>2]=e}while((0|r)<(0|t));return s=32-t|0,s=e>>>s,a=e<<t,jt[i>>2]=a,t=r-t|0,jt[l>>2]=t,or=u,0|s}function z(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0;o=255&t,i=0!=(0|r);e:do{if(i&0!=(3&e|0))for(n=255&t;;){if((0|zt[e>>0])==n<<24>>24){a=6;break e}if(e=e+1|0,r=r+-1|0,!((i=0!=(0|r))&0!=(3&e|0))){a=5;break}}else a=5}while(0);5==(0|a)&&(i?a=6:r=0);e:do{if(6==(0|a)&&(n=255&t,(0|zt[e>>0])!=n<<24>>24)){i=0|dr(o,16843009);t:do{if(r>>>0>3)for(;;){if((-2139062144&(o=jt[e>>2]^i)^-2139062144)&o+-16843009|0)break;if(e=e+4|0,(r=r+-4|0)>>>0<=3){a=11;break t}}else a=11}while(0);if(11==(0|a)&&!r){r=0;break}for(;;){if((0|zt[e>>0])==n<<24>>24)break e;if(e=e+1|0,!(r=r+-1|0)){r=0;break}}}}while(0);return 0|(0|r?e:0)}function G(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0,u=0,c=0;return c=or,or=or+528|0,u=c,l=c+16|0,a=0|jt[e+88>>2],s=(0|Yt[a+70+(n<<2)+1>>0])<<16|(0|Yt[a+70+(n<<2)>>0])<<24|(0|Yt[a+70+(n<<2)+2>>0])<<8|0|Yt[a+70+(n<<2)+3>>0],o=n+1|0,(o=o>>>0<(0|Yt[a+16>>0])>>>0?(0|Yt[a+70+(o<<2)+1>>0])<<16|(0|Yt[a+70+(o<<2)>>0])<<24|(0|Yt[a+70+(o<<2)+2>>0])<<8|0|Yt[a+70+(o<<2)+3>>0]:0|jt[e+8>>2])>>>0>s>>>0?(l=e+4|0,l=0|jt[l>>2],l=l+s|0,u=o-s|0,u=0|D(e,l,u,t,r,i,n),or=c,0|u):(jt[u>>2]=866,jt[u+4>>2]=3694,jt[u+8>>2]=1508,Ve(l,812,u),he(l),l=e+4|0,l=0|jt[l>>2],l=l+s|0,u=o-s|0,u=0|D(e,l,u,t,r,i,n),or=c,0|u)}function W(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;if(((0==(0|t)|r>>>0<74?0:18552==((0|Yt[t>>0])<<8|0|Yt[t+1>>0]|0))?((0|Yt[t+2>>0])<<8|0|Yt[t+3>>0])>>>0>=74:0)?((0|Yt[t+7>>0])<<16|(0|Yt[t+6>>0])<<24|(0|Yt[t+8>>0])<<8|0|Yt[t+9>>0])>>>0<=r>>>0:0){if(i=e+88|0,jt[i>>2]=t,jt[e+4>>2]=t,jt[e+8>>2]=r,!(0|O(e)))return 0|(n=0);if(t=0|jt[i>>2],(0|Yt[t+39>>0])<<8|0|Yt[t+40>>0]?(0|b(e)?0|m(e):0)&&(t=0|jt[i>>2],n=11):n=11,11==(0|n)){if(!((0|Yt[t+55>>0])<<8|0|Yt[t+56>>0]))return 0|(n=1);if(0|T(e)?0|f(e):0)return 0|(n=1)}return 0|(n=0)}return jt[e+88>>2]=0,0|(n=0)}function H(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0,u=0;if(u=or,or=or+528|0,a=u,o=u+16|0,!t)return l=0,or=u,0|l;if(t>>>0<=16)return l=0|V(e,t),or=u,0|l;if(s=0|V(e,t+-16|0),l=e+20|0,(0|(t=0|jt[l>>2]))<16){i=e+4|0,n=e+8|0,r=e+16|0;do{e=0|jt[i>>2],(0|e)==(0|jt[n>>2])?e=0:(jt[i>>2]=e+1,e=0|Yt[e>>0]),t=t+8|0,jt[l>>2]=t,(0|t)>=33&&(jt[a>>2]=866,jt[a+4>>2]=3208,jt[a+8>>2]=1366,Ve(o,812,a),he(o),t=0|jt[l>>2]),e=e<<32-t|jt[r>>2],jt[r>>2]=e}while((0|t)<16)}else e=e+16|0,r=e,e=0|jt[e>>2];return jt[r>>2]=e<<16,jt[l>>2]=t+-16,l=e>>>16|s<<16,or=u,0|l}function j(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0,s=0;i=r+16|0,n=0|jt[i>>2],n?o=5:0|_e(r)?i=0:(n=0|jt[i>>2],o=5);e:do{if(5==(0|o)){if(s=r+20|0,a=0|jt[s>>2],i=a,(n-a|0)>>>0<t>>>0){i=0|Pr[7&jt[r+36>>2]](r,e,t);break}t:do{if((0|zt[r+75>>0])>-1){for(a=t;;){if(!a){o=0,n=e;break t}if(n=a+-1|0,10==(0|zt[e+n>>0]))break;a=n}if((i=0|Pr[7&jt[r+36>>2]](r,e,a))>>>0<a>>>0)break e;o=a,n=e+a|0,t=t-a|0,i=0|jt[s>>2]}else o=0,n=e}while(0);I(0|i,0|n,0|t),jt[s>>2]=(0|jt[s>>2])+t,i=o+t|0}}while(0);return 0|i}function q(e,t,r){e|=0,t|=0,r|=0;do{if(e){if(t>>>0<128){zt[e>>0]=t,e=1;break}if(r=188+(0|xt())|0,!(0|jt[jt[r>>2]>>2])){if(57216==(-128&t|0)){zt[e>>0]=t,e=1;break}e=0|Et(),jt[e>>2]=84,e=-1;break}if(t>>>0<2048){zt[e>>0]=t>>>6|192,zt[e+1>>0]=63&t|128,e=2;break}if(t>>>0<55296|57344==(-8192&t|0)){zt[e>>0]=t>>>12|224,zt[e+1>>0]=t>>>6&63|128,zt[e+2>>0]=63&t|128,e=3;break}if((t+-65536|0)>>>0<1048576){zt[e>>0]=t>>>18|240,zt[e+1>>0]=t>>>12&63|128,zt[e+2>>0]=t>>>6&63|128,zt[e+3>>0]=63&t|128,e=4;break}e=0|Et(),jt[e>>2]=84,e=-1;break}e=1}while(0);return 0|e}function Y(){var e=0,t=0,r=0,i=0,n=0,o=0,a=0,s=0;n=or,or=or+48|0,a=n+32|0,r=n+24|0,s=n+16|0,o=n,n=n+36|0,e=0|ke(),(0|e?0|(i=0|jt[e>>2]):0)&&(e=i+48|0,t=0|jt[e>>2],e=0|jt[e+4>>2],1126902528==(-256&t|0)&1129074247==(0|e)||(jt[r>>2]=4168,je(4118,r)),e=1126902529==(0|t)&1129074247==(0|e)?0|jt[i+44>>2]:i+80|0,jt[n>>2]=e,i=0|jt[i>>2],e=0|jt[i+4>>2],0|Pr[7&jt[16+(0|jt[2])>>2]](8,i,n)?(s=0|jt[n>>2],s=0|Or[1&jt[8+(0|jt[s>>2])>>2]](s),jt[o>>2]=4168,jt[o+4>>2]=e,jt[o+8>>2]=s,je(4032,o)):(jt[s>>2]=4168,jt[s+4>>2]=e,je(4077,s))),je(4156,a)}function X(e){e|=0;var t=0,r=0,i=0,n=0,o=0;o=or,or=or+544|0,n=o+16|0,r=o,i=o+32|0,t=0|jt[e+20>>2];do{if(0|t){if(B(t),7&t){jt[r>>2]=866,jt[r+4>>2]=2506,jt[r+8>>2]=1232,Ve(i,812,r),he(i);break}oe(t,0,0,1,0);break}}while(0);if(t=e+4|0,!(r=0|jt[t>>2]))return n=e+16|0,zt[n>>0]=0,void(or=o);7&r?(jt[n>>2]=866,jt[n+4>>2]=2506,jt[n+8>>2]=1232,Ve(i,812,n),he(i)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+8>>2]=0,jt[e+12>>2]=0,n=e+16|0,zt[n>>0]=0,or=o}function Q(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;return l=or,or=or+560|0,s=l+32|0,a=l+16|0,r=l,o=l+48|0,n=l+44|0,i=e+3&-4,(i=0|i?i:4)>>>0>2147418112?(jt[r>>2]=866,jt[r+4>>2]=2506,jt[r+8>>2]=1103,Ve(o,812,r),he(o),s=0,or=l,0|s):(jt[n>>2]=i,e=0|oe(0,i,n,1,0),r=0|jt[n>>2],0|t&&(jt[t>>2]=r),0==(0|e)|r>>>0<i>>>0?(jt[a>>2]=866,jt[a+4>>2]=2506,jt[a+8>>2]=1129,Ve(o,812,a),he(o),e=0):7&e&&(jt[s>>2]=866,jt[s+4>>2]=2533,jt[s+8>>2]=1156,Ve(o,812,s),he(o)),s=e,or=l,0|s)}function Z(e){e|=0;var t=0,r=0,i=0,n=0,o=0,a=0;if(a=or,or=or+544|0,o=a+16|0,i=a,n=a+32|0,jt[e>>2]=0,t=e+4|0,r=0|jt[t>>2],0|r&&(7&r?(jt[i>>2]=866,jt[i+4>>2]=2506,jt[i+8>>2]=1232,Ve(n,812,i),he(n)):oe(r,0,0,1,0),jt[t>>2]=0,jt[e+8>>2]=0,jt[e+12>>2]=0),zt[e+16>>0]=0,e=e+20|0,!(t=0|jt[e>>2]))return void(or=a);B(t),7&t?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1232,Ve(n,812,o),he(n)):oe(t,0,0,1,0),jt[e>>2]=0,or=a}function K(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0,c=0;c=or,or=or+128|0,n=c+124|0,u=c,o=u,a=604,s=o+124|0;do{jt[o>>2]=jt[a>>2],o=o+4|0,a=a+4|0}while((0|o)<(0|s));return(t+-1|0)>>>0>2147483646?t?(t=0|Et(),jt[t>>2]=75,t=-1):(e=n,t=1,l=4):l=4,4==(0|l)&&(l=-2-e|0,l=t>>>0>l>>>0?l:t,jt[u+48>>2]=l,n=u+20|0,jt[n>>2]=e,jt[u+44>>2]=e,t=e+l|0,e=u+16|0,jt[e>>2]=t,jt[u+28>>2]=t,t=0|L(u,r,i),l&&(u=0|jt[n>>2],zt[u+(((0|u)==(0|jt[e>>2]))<<31>>31)>>0]=0)),or=c,0|t}function J(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0,s=0,l=0,u=0;return u=or,or=or+560|0,l=u+32|0,o=u+16|0,n=u,a=u+48|0,s=u+44|0,7&e|0?(jt[n>>2]=866,jt[n+4>>2]=2506,jt[n+8>>2]=1210,Ve(a,812,n),he(a),l=0,or=u,0|l):t>>>0>2147418112?(jt[o>>2]=866,jt[o+4>>2]=2506,jt[o+8>>2]=1103,Ve(a,812,o),he(a),l=0,or=u,0|l):(jt[s>>2]=t,e=0|oe(e,t,s,i,0),0|r&&(jt[r>>2]=jt[s>>2]),7&e|0&&(jt[l>>2]=866,jt[l+4>>2]=2558,jt[l+8>>2]=1156,Ve(a,812,l),he(a)),l=e,or=u,0|l)}function $(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0;do{if(0|lt(e,0|jt[t+8>>2],n))Pe(0,t,r,i);else if(0|lt(e,0|jt[t>>2],n)){if(e=t+32|0,(0|jt[t+16>>2])!=(0|r)?(o=t+20|0,(0|jt[o>>2])!=(0|r)):0){jt[e>>2]=i,jt[o>>2]=r,i=t+40|0,jt[i>>2]=1+(0|jt[i>>2]),(1==(0|jt[t+36>>2])?2==(0|jt[t+24>>2]):0)&&(zt[t+54>>0]=1),jt[t+44>>2]=4;break}1==(0|i)&&(jt[e>>2]=1)}}while(0)}function ee(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0;if(o=e+r|0,t&=255,(0|r)>=67){for(;3&e;)zt[e>>0]=t,e=e+1|0;for(i=-4&o|0,n=i-64|0,a=t|t<<8|t<<16|t<<24;(0|e)<=(0|n);)jt[e>>2]=a,jt[e+4>>2]=a,jt[e+8>>2]=a,jt[e+12>>2]=a,jt[e+16>>2]=a,jt[e+20>>2]=a,jt[e+24>>2]=a,jt[e+28>>2]=a,jt[e+32>>2]=a,jt[e+36>>2]=a,jt[e+40>>2]=a,jt[e+44>>2]=a,jt[e+48>>2]=a,jt[e+52>>2]=a,jt[e+56>>2]=a,jt[e+60>>2]=a,e=e+64|0;for(;(0|e)<(0|i);)jt[e>>2]=a,e=e+4|0}for(;(0|e)<(0|o);)zt[e>>0]=t,e=e+1|0;return o-r|0}function te(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0,s=0,l=0;zt[t+53>>0]=1;do{if((0|jt[t+4>>2])==(0|i)){if(zt[t+52>>0]=1,i=t+16|0,o=0|jt[i>>2],s=t+54|0,l=t+48|0,a=t+24|0,e=t+36|0,!o){if(jt[i>>2]=r,jt[a>>2]=n,jt[e>>2]=1,!(1==(0|jt[l>>2])&1==(0|n)))break;zt[s>>0]=1;break}if((0|o)!=(0|r)){jt[e>>2]=1+(0|jt[e>>2]),zt[s>>0]=1;break}e=0|jt[a>>2],2==(0|e)&&(jt[a>>2]=n,e=n),1==(0|jt[l>>2])&1==(0|e)&&(zt[s>>0]=1)}}while(0)}function re(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0,a=0;if(a=or,or=or+64|0,n=a,0|lt(e,t,0))t=1;else if(0!=(0|t)?0!=(0|(o=0|N(t,32,16,0))):0){t=n+4|0,i=t+52|0;do{jt[t>>2]=0,t=t+4|0}while((0|t)<(0|i));jt[n>>2]=o,jt[n+8>>2]=e,jt[n+12>>2]=-1,jt[n+48>>2]=1,Nr[3&jt[28+(0|jt[o>>2])>>2]](o,n,0|jt[r>>2],1),1==(0|jt[n+24>>2])?(jt[r>>2]=jt[n+16>>2],t=1):t=0}else t=0;return or=a,0|t}function ie(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;l=or,or=or+16|0,a=l,s=255&t,zt[a>>0]=s,i=e+16|0,n=0|jt[i>>2],n?o=4:0|_e(e)?r=-1:(n=0|jt[i>>2],o=4);do{if(4==(0|o)){if(o=e+20|0,i=0|jt[o>>2],i>>>0<n>>>0?(0|(r=255&t))!=(0|zt[e+75>>0]):0){jt[o>>2]=i+1,zt[i>>0]=s;break}r=1==(0|Pr[7&jt[e+36>>2]](e,a,1))?0|Yt[a>>0]:-1}}while(0);return or=l,0|r}function ne(e,t){e|=0,t|=0;var r=0,i=0,n=0,o=0,a=0,s=0,l=0;s=255&e,r=255&e,((0|jt[t+76>>2])>=0?0!=(0|Nt(t)):0)?(((0|r)!=(0|zt[t+75>>0])?(o=t+20|0,(a=0|jt[o>>2])>>>0<(0|jt[t+16>>2])>>>0):0)?(jt[o>>2]=a+1,zt[a>>0]=s):r=0|ie(t,e),Lt(t)):l=3;do{if(3==(0|l)){if((0|r)!=(0|zt[t+75>>0])?(i=t+20|0,(n=0|jt[i>>2])>>>0<(0|jt[t+16>>2])>>>0):0){jt[i>>2]=n+1,zt[n>>0]=s;break}r=0|ie(t,e)}}while(0);return 0|r}function oe(e,t,r,i,o){e|=0,t|=0,r|=0,i|=0,o|=0;do{if(e){if(!t){if(d(e),!r){t=0;break}jt[r>>2]=0,t=0;break}i?(t=0|ce(e,t),e=0==(0|t)?e:t):t=0,r&&(o=0|Ue(e),jt[r>>2]=o)}else t=0|n(t),r&&(e=t?0|Ue(t):0,jt[r>>2]=e)}while(0);return 0|t}function ae(e){e|=0;var t=0,r=0,i=0;i=e;e:do{if(3&i)for(t=i;;){if(!(0|zt[e>>0])){e=t;break e}if(e=e+1|0,!(3&(t=e))){r=4;break}}else r=4}while(0);if(4==(0|r)){for(;;){if((-2139062144&(t=0|jt[e>>2])^-2139062144)&t+-16843009)break;e=e+4|0}if((255&t)<<24>>24)do{e=e+1|0}while(0!=(0|zt[e>>0]))}return e-i|0}function se(e,t){e=+e,t|=0;var r=0,i=0,n=0;switch(tr[nr>>3]=e,r=0|jt[nr>>2],i=0|jt[nr+4>>2],2047&(n=0|He(0|r,0|i,52))){case 0:0!=e?(e=+se(0x10000000000000000*e,t),r=(0|jt[t>>2])-64|0):r=0,jt[t>>2]=r;break;case 2047:break;default:jt[t>>2]=(2047&n)-1022,jt[nr>>2]=r,jt[nr+4>>2]=-2146435073&i|1071644672,e=+tr[nr>>3]}return+e}function le(e,t){e|=0,t|=0;var r=0,i=0;for(i=0;;){if((0|Yt[2140+i>>0])==(0|e)){e=2;break}if(87==(0|(r=i+1|0))){r=2228,i=87,e=5;break}i=r}if(2==(0|e)&&(i?(r=2228,e=5):r=2228),5==(0|e))for(;;){do{e=r,r=r+1|0}while(0!=(0|zt[e>>0]));if(!(i=i+-1|0))break;e=5}return 0|bt(r,0|jt[t+20>>2])}function ue(e,t,r){e|=0,t|=0,r|=0;var i=0;if(t>>>0>0|0==(0|t)&e>>>0>4294967295){for(;;){if(i=0|Oe(0|e,0|t,10,0),r=r+-1|0,zt[r>>0]=255&i|48,i=e,e=0|ct(0|e,0|t,10,0),!(t>>>0>9|9==(0|t)&i>>>0>4294967295))break;t=cr}t=e}else t=e;if(t)for(;;){if(r=r+-1|0,zt[r>>0]=48|(t>>>0)%10,t>>>0<10)break;t=(t>>>0)/10|0}return 0|r}function ce(e,t){e|=0,t|=0;var r=0,i=0;return e?t>>>0>4294967231?(t=0|Et(),jt[t>>2]=12,0|(t=0)):0|(r=0|v(e+-8|0,t>>>0<11?16:t+11&-8))?0|(t=r+8|0):(r=0|n(t))?(i=0|jt[e+-4>>2],i=(-8&i)-(0==(3&i|0)?8:4)|0,I(0|r,0|e,0|(i>>>0<t>>>0?i:t)),d(e),0|(t=r)):0|(t=0):0|(t=0|n(t))}function de(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0,a=0;e=t+16|0,n=0|jt[e>>2],o=t+36|0,a=t+24|0;do{if(n){if((0|n)!=(0|r)){jt[o>>2]=1+(0|jt[o>>2]),jt[a>>2]=2,zt[t+54>>0]=1;break}2==(0|jt[a>>2])&&(jt[a>>2]=i)}else jt[e>>2]=r,jt[a>>2]=i,jt[o>>2]=1}while(0)}function he(e){e|=0;var t=0,r=0,i=0,n=0;i=0|jt[119],n=(0|jt[i+76>>2])>-1?0|Nt(i):0;do{if((0|rt(e,i))<0)e=1;else{if(10!=(0|zt[i+75>>0])?(t=i+20|0,(r=0|jt[t>>2])>>>0<(0|jt[i+16>>2])>>>0):0){jt[t>>2]=r+1,zt[r>>0]=10,e=0;break}e=(0|ie(i,10))<0}}while(0);return 0|n&&Lt(i),e<<31>>31|0}function pe(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,0|lt(e,0|jt[t+8>>2],o)?te(0,t,r,i,n):(e=0|jt[e+8>>2],Lr[3&jt[20+(0|jt[e>>2])>>2]](e,t,r,i,n,o))}function fe(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0;var o=0,a=0;if(a=or,or=or+256|0,o=a,(0|r)>(0|i)&0==(73728&n|0)){if(n=r-i|0,ee(0|o,0|t,0|(n>>>0<256?n:256)),n>>>0>255){t=r-i|0;do{it(e,o,256),n=n+-256|0}while(n>>>0>255);n=255&t}it(e,o,n)}or=a}function me(e,t,r,i){e|=0,t|=0,r|=0,i|=0,0|lt(e,0|jt[t+8>>2],0)?de(0,t,r,i):(e=0|jt[e+8>>2],Nr[3&jt[28+(0|jt[e>>2])>>2]](e,t,r,i))}function ge(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0,o=0;return n=or,or=or+32|0,o=n,i=n+20|0,jt[o>>2]=jt[e+60>>2],jt[o+4>>2]=0,jt[o+8>>2]=t,jt[o+12>>2]=i,jt[o+16>>2]=r,(0|$e(0|Ar(140,0|o)))<0?(jt[i>>2]=-1,e=-1):e=0|jt[i>>2],or=n,0|e}function _e(e){e|=0;var t=0,r=0;return t=e+74|0,r=0|zt[t>>0],zt[t>>0]=r+255|r,t=0|jt[e>>2],8&t?(jt[e>>2]=32|t,e=-1):(jt[e+8>>2]=0,jt[e+4>>2]=0,r=0|jt[e+44>>2],jt[e+28>>2]=r,jt[e+20>>2]=r,jt[e+16>>2]=r+(0|jt[e+48>>2]),e=0),0|e}function ve(e,t){e|=0,t|=0;var r=0,i=0;if(r=0|zt[e>>0],i=0|zt[t>>0],r<<24>>24==0?1:r<<24>>24!=i<<24>>24)e=i;else{do{e=e+1|0,t=t+1|0,r=0|zt[e>>0],i=0|zt[t>>0]}while(!(r<<24>>24==0?1:r<<24>>24!=i<<24>>24));e=i}return(255&r)-(255&e)|0}function ye(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return n=or,or=or+32|0,i=n,jt[e+36>>2]=1,(0==(64&jt[e>>2]|0)?(jt[i>>2]=jt[e+60>>2],jt[i+4>>2]=21523,jt[i+8>>2]=n+16,0|vr(54,0|i)):0)&&(zt[e+75>>0]=-1),i=0|M(e,t,r),or=n,0|i}function be(e){e|=0;var t=0,r=0;return r=e+15&-16|0,t=0|jt[ir>>2],e=t+r|0,(0|r)>0&(0|e)<(0|t)|(0|e)<0?(gr(),Cr(12),-1):(jt[ir>>2]=e,((0|e)>(0|mr())?0==(0|fr()):0)?(jt[ir>>2]=t,Cr(12),-1):0|t)}function Ce(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0;return n=0|dr(r,t),r=0==(0|t)?0:r,(0|jt[i+76>>2])>-1?(o=0==(0|Nt(i)),e=0|j(e,n,i),o||Lt(i)):e=0|j(e,n,i),(0|e)!=(0|n)&&(r=(e>>>0)/(t>>>0)|0),0|r}function Se(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,0|lt(e,0|jt[t+8>>2],o)&&te(0,t,r,i,n)}function we(e,t,r,i){e|=0,t|=0,r|=0,i|=0,0|lt(e,0|jt[t+8>>2],0)&&de(0,t,r,i)}function Te(e){e|=0;var t=0,r=0,i=0;if(r=0|jt[e>>2],(i=(0|zt[r>>0])-48|0)>>>0<10){t=0;do{t=i+(10*t|0)|0,r=r+1|0,jt[e>>2]=r,i=(0|zt[r>>0])-48|0}while(i>>>0<10)}else t=0;return 0|t}function Ee(e,t,r,i){if(e|=0,t|=0,r|=0,i|=0,!(0==(0|e)&0==(0|t)))do{r=r+-1|0,zt[r>>0]=0|Yt[2122+(15&e)>>0]|i,e=0|He(0|e,0|t,4),t=cr}while(!(0==(0|e)&0==(0|t)));return 0|r}function Ae(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return n=or,or=or+16|0,i=n,jt[i>>2]=jt[r>>2],e=0|Pr[7&jt[16+(0|jt[e>>2])>>2]](e,t,i),e&&(jt[r>>2]=jt[i>>2]),or=n,1&e|0}function xe(e){e|=0;var t=0;return(0|(t=0|zt[sr+(255&e)>>0]))<8?0|t:(0|(t=0|zt[sr+(e>>8&255)>>0]))<8?t+8|0:(t=0|zt[sr+(e>>16&255)>>0],(0|t)<8?t+16|0:24+(0|zt[sr+(e>>>24)>>0])|0)}function Pe(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0;((0|jt[t+4>>2])==(0|r)?(n=t+28|0,1!=(0|jt[n>>2])):0)&&(jt[n>>2]=i)}function De(e,t,r){if(e|=0,t|=0,r|=0,!(0==(0|e)&0==(0|t)))do{r=r+-1|0,zt[r>>0]=7&e|48,e=0|He(0|e,0|t,3),t=cr}while(!(0==(0|e)&0==(0|t)));return 0|r}function Ie(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return i=e+20|0,n=0|jt[i>>2],e=(0|jt[e+16>>2])-n|0,e=e>>>0>r>>>0?r:e,I(0|n,0|t,0|e),jt[i>>2]=(0|jt[i>>2])+e,0|r}function Oe(e,t,r,i){e|=0,t|=0,r|=0,i|=0;var n=0,o=0;return o=or,or=or+16|0,n=0|o,_(e,t,r,i,n),or=o,0|(cr=0|jt[n+4>>2],0|jt[n>>2])}function Me(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+32>>2]}function Re(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+12>>2]}function Le(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+8>>2]}function Ne(e,t){e|=0,t|=0;var r=0,i=0;return i=or,or=or+48|0,r=i,jt[r>>2]=40,U(e,t,r),or=i,0|jt[r+4>>2]}function ke(){var e=0,t=0;return e=or,or=or+16|0,0|wr(5136,2)?(je(4307,e),0):(t=0|_r(0|jt[1285]),or=e,0|t)}function Fe(e){e|=0;var t=0,r=0;return t=or,or=or+16|0,r=t,e=0|Ot(0|jt[e+60>>2]),jt[r>>2]=e,e=0|$e(0|br(6,0|r)),or=t,0|e}function Be(e){e|=0;var t=0;if(t=or,or=or+16|0,d(e),!(0|yr(0|jt[1285],0)))return void(or=t);je(4406,t)}function Ue(e){e|=0;var t=0;return e?(t=0|jt[e+-4>>2],e=3&t,0|(1==(0|e)?0:(-8&t)-(0==(0|e)?8:4)|0)):0}function Ve(e,t,r){e|=0,t|=0,r|=0;var i=0,n=0;return i=or,or=or+16|0,n=i,jt[n>>2]=r,r=0|ft(e,t,n),or=i,0|r}function ze(e,t,r,i,n,o,a){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,a|=0,Lr[3&e](0|t,0|r,0|i,0|n,0|o,0|a)}function Ge(){var e=0;if(e=or,or=or+16|0,!(0|Er(5140,6)))return void(or=e);je(4356,e)}function We(e,t,r){return e|=0,t|=0,(0|(r|=0))<32?(cr=t<<r|(e&(1<<r)-1<<32-r)>>>32-r,e<<r):(cr=e<<r-32,0)}function He(e,t,r){return e|=0,t|=0,(0|(r|=0))<32?(cr=t>>>r,e>>>r|(t&(1<<r)-1)<<32-r):(cr=0,t>>>r-32|0)}function je(e,t){e|=0,t|=0;var r=0;r=or,or=or+16|0,jt[r>>2]=t,t=0|jt[26],L(t,e,r),ne(10,t),Sr()}function qe(){}function Ye(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,i=t-i-(r>>>0>e>>>0|0)>>>0,0|(cr=i,e-r>>>0|0)}function Xe(e,t){return e|=0,t|=0,t=t?0|F(0|jt[t>>2],0|jt[t+4>>2],e):0,0|(0|t?t:e)}function Qe(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,Dr[3&e](0|t,0|r,0|i,0|n,0|o)}function Ze(e){e=+e;var t=0;return tr[nr>>3]=e,t=0|jt[nr>>2],cr=0|jt[nr+4>>2],0|t}function Ke(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,r=e+r>>>0,0|(cr=t+i+(r>>>0<e>>>0|0)>>>0,0|r)}function Je(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0,Nr[3&e](0|t,0|r,0|i,0|n)}function $e(e){e|=0;var t=0;return e>>>0>4294963200&&(t=0|Et(),jt[t>>2]=0-e,e=-1),0|e}function et(e){return e|=0,1&(e=e?0!=(0|N(e,32,88,0)):0)|0}function tt(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,0|Pr[7&e](0|t,0|r,0|i)}function rt(e,t){e|=0,t|=0;var r=0;return r=0|ae(e),((0|Ce(e,1,r,t))!=(0|r))<<31>>31|0}function it(e,t,r){e|=0,t|=0,r|=0,32&jt[e>>2]||j(t,r,e)}function nt(e,t,r,i){e|=0,t|=0,r|=0,i|=0,Mr[0&e](0|t,0|r,0|i)}function ot(e){e|=0;var t=0;return t=or,or=or+e|0,or=or+15&-16,0|t}function at(e){e|=0;var t=0;return t=188+(0|xt())|0,0|le(e,0|jt[t>>2])}function st(e,t){return e|=0,t|=0,0|(e=e?0|q(e,t,0):0)}function lt(e,t,r){return e|=0,t|=0,r|=0,(0|e)==(0|t)|0}function ut(e,t){e|=0,t|=0;var r=0;return r=0|dt(0|e),0|(0==(0|t)?e:r)}function ct(e,t,r,i){return e|=0,t|=0,r|=0,i|=0,0|_(e,t,r,i,0)}function dt(e){return(255&(e|=0))<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>>24|0}function ht(e,t,r,i,n,o){e|=0,t|=0,r|=0,i|=0,n|=0,o|=0,pr(6)}function pt(e,t){e|=0,t|=0,lr||(lr=e,ur=t)}function ft(e,t,r){return e|=0,t|=0,r|=0,0|K(e,2147483647,t,r)}function mt(e,t,r,i,n){e|=0,t|=0,r|=0,i|=0,n|=0,pr(1)}function gt(e){e|=0,Lt(e),Dt(e)}function _t(e,t){return e|=0,t|=0,0|Or[1&e](0|t)}function vt(e,t){e|=0,t|=0,or=e,ar=t}function yt(e,t,r,i){e|=0,t|=0,r|=0,i|=0,pr(7)}function bt(e,t){return e|=0,t|=0,0|Xe(e,t)}function Ct(e,t){e|=0,t|=0,Ir[7&e](0|t)}function St(e,t,r){return e|=0,t|=0,r|=0,pr(0),0}function wt(e,t){return e=+e,t|=0,+ +se(e,t)}function Tt(e,t,r){e|=0,t|=0,r|=0,pr(4)}function Et(){return 64+(0|xt())|0}function At(e){e|=0,Rr[3&e]()}function xt(){return 232}function Pt(e){e|=0,or=e}function Dt(e){e|=0,d(e)}function It(e){e|=0,cr=e}function Ot(e){return 0|(e|=0)}function Mt(){return 5072}function Rt(e){return e|=0,pr(3),0}function Lt(e){e|=0}function Nt(e){return e|=0,0}function kt(){return 0|cr}function Ft(){return 0|or}function Bt(e){e|=0,pr(2)}function Ut(){pr(5)}var Vt=e.Int8Array,zt=new Vt(r),Gt=e.Int16Array,Wt=new Gt(r),Ht=e.Int32Array,jt=new Ht(r),qt=e.Uint8Array,Yt=new qt(r),Xt=e.Uint16Array,Qt=new Xt(r),Zt=e.Uint32Array,Kt=new Zt(r),Jt=e.Float32Array,$t=new Jt(r),er=e.Float64Array,tr=new er(r),rr=e.byteLength,ir=0|t.DYNAMICTOP_PTR,nr=0|t.tempDoublePtr,or=(t.ABORT,0|t.STACKTOP),ar=0|t.STACK_MAX,sr=0|t.cttz_i8,lr=0,ur=0,cr=(e.NaN,e.Infinity,0),dr=(e.Math.floor,e.Math.abs,e.Math.sqrt,e.Math.pow,e.Math.cos,e.Math.sin,e.Math.tan,e.Math.acos,e.Math.asin,e.Math.atan,e.Math.atan2,e.Math.exp,e.Math.log,e.Math.ceil,e.Math.imul),hr=(e.Math.min,e.Math.max,e.Math.clz32),pr=t.abort,fr=(t.assert,t.enlargeMemory),mr=t.getTotalMemory,gr=t.abortOnCannotGrowMemory,_r=(t.invoke_iiii,t.invoke_viiiii,t.invoke_vi,t.invoke_ii,t.invoke_viii,t.invoke_v,t.invoke_viiiiii,t.invoke_viiii,t._pthread_getspecific),vr=t.___syscall54,yr=t._pthread_setspecific,br=(t.___gxx_personality_v0,t.___syscall6),Cr=t.___setErrNo,Sr=t._abort,wr=(t.___cxa_begin_catch,t._pthread_once),Tr=t._emscripten_memcpy_big,Er=t._pthread_key_create,Ar=t.___syscall140,xr=(t.___resumeException,t.___cxa_find_matching_catch,t.___syscall146),Pr=(t.__ZSt18uncaught_exceptionv,[St,M,ge,ye,Ie,re,St,St]),Dr=[mt,$,R,mt],Ir=[Bt,Lt,gt,Lt,Lt,gt,Be,Bt],Or=[Rt,Fe],Mr=[Tt],Rr=[Ut,Y,Ge,Ut],Lr=[ht,Se,pe,ht],Nr=[yt,we,me,yt];return{stackSave:Ft,_i64Subtract:Ye,_crn_get_bytes_per_block:P,setThrew:pt,dynCall_viii:nt,_bitshift64Lshr:He,_bitshift64Shl:We,dynCall_viiii:Je,setTempRet0:It,_crn_decompress:y,_memset:ee,_sbrk:be,_memcpy:I,stackAlloc:ot,_crn_get_height:Le,dynCall_vi:Ct,getTempRet0:kt,_crn_get_levels:Re,_crn_get_uncompressed_size:x,_i64Add:Ke,dynCall_iiii:tt,_emscripten_get_global_libc:Mt,dynCall_ii:_t,___udivdi3:ct,_llvm_bswap_i32:dt,dynCall_viiiii:Qe,___cxa_can_catch:Ae,_free:d,runPostSets:qe,dynCall_viiiiii:ze,establishStackSpace:vt,___uremdi3:Oe,___cxa_is_pointer_type:et,stackRestore:Pt,_malloc:n,_emscripten_replace_memory:i,dynCall_v:At,_crn_get_width:Ne,_crn_get_dxt_format:Me}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),stackSave=Module.stackSave=asm.stackSave,getTempRet0=Module.getTempRet0=asm.getTempRet0,_memset=Module._memset=asm._memset,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,setTempRet0=Module.setTempRet0=asm.setTempRet0,_crn_decompress=Module._crn_decompress=asm._crn_decompress,_crn_get_bytes_per_block=Module._crn_get_bytes_per_block=asm._crn_get_bytes_per_block,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,_crn_get_height=Module._crn_get_height=asm._crn_get_height,_i64Subtract=Module._i64Subtract=asm._i64Subtract,_crn_get_levels=Module._crn_get_levels=asm._crn_get_levels,_crn_get_uncompressed_size=Module._crn_get_uncompressed_size=asm._crn_get_uncompressed_size,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,___udivdi3=Module.___udivdi3=asm.___udivdi3,_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,___cxa_can_catch=Module.___cxa_can_catch=asm.___cxa_can_catch,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,___uremdi3=Module.___uremdi3=asm.___uremdi3,___cxa_is_pointer_type=Module.___cxa_is_pointer_type=asm.___cxa_is_pointer_type,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,_emscripten_replace_memory=Module._emscripten_replace_memory=asm._emscripten_replace_memory,_crn_get_width=Module._crn_get_width=asm._crn_get_width,_crn_get_dxt_format=Module._crn_get_dxt_format=asm._crn_get_dxt_format,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii;Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm,ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var initialStackTop,preloadStartTime=null,calledMain=!1;dependenciesFulfilled=function e(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=e)},Module.callMain=Module.callMain=function(e){function t(){for(var e=0;e<3;e++)i.push(0)}e=e||[],ensureInitRuntime();var r=e.length+1,i=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];t();for(var n=0;n<r-1;n+=1)i.push(allocate(intArrayFromString(e[n]),"i8",ALLOC_NORMAL)),t();i.push(0),i=allocate(i,"i32",ALLOC_NORMAL);try{exit(Module._main(r,i,0),!0)}catch(e){if(e instanceof ExitStatus)return;if("SimulateInfiniteLoop"==e)return void(Module.noExitRuntime=!0);var o=e;e&&"object"==typeof e&&e.stack&&(o=[e,e.stack]),Module.printErr("exception thrown: "+o),Module.quit(1,e)}finally{calledMain=!0}},Module.run=Module.run=run,Module.exit=Module.exit=exit;var abortDecorators=[];if(Module.abort=Module.abort=abort,Module.preInit)for("function"==typeof Module.preInit&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;return Module.noInitialRun&&(shouldRunNow=!1),Module.noExitRuntime=!0,run(),Module}),define("ThirdParty/GltfPipeline/findAccessorMinMax",["./getAccessorByteStride","./numberOfComponentsForType","../../Core/arrayFill","../../Core/ComponentDatatype","../../Core/defined"],function(e,t,r,i,n){"use strict";function o(o,a){var s=o.bufferViews,l=o.buffers,u=a.bufferView,c=t(a.type),d=r(new Array(c),Number.POSITIVE_INFINITY),h=r(new Array(c),Number.NEGATIVE_INFINITY);if(n(u)&&n(s)&&s.hasOwnProperty(u)){var p=s[u],f=p.buffer;if(n(f)&&n(l)&&l.hasOwnProperty(f))for(var m=l[f],g=m.extras._pipeline.source,_=a.count,v=e(o,a),y=a.byteOffset+p.byteOffset,b=a.componentType,C=0;C<_;C++){for(var S=i.createArrayBufferView(b,g.buffer,y+g.byteOffset,c),w=0;w<c;w++){var T=S[w];d[w]=Math.min(d[w],T),h[w]=Math.max(h[w],T)}y+=v}}return{min:d,max:h}}return o}),define("ThirdParty/GltfPipeline/getJointCountForMaterials",["./ForEach","../../Core/defined"],function(e,t){"use strict";function r(r){var i=r.meshes,n={},o={};return e.node(r,function(e){t(e.skin)&&(t(o[e.skin])||(o[e.skin]=[]),o[e.skin].push(e))}),e.skin(r,function(r,a){for(var s=r.joints.length,l=function(e){n[e.material]=s},u=o[a],c=u.length,d=0;d<c;d++){var h=u[d],p=h.mesh;if(t(p)){var f=i[p];e.meshPrimitive(f,l)}}}),n}return r}),define("ThirdParty/GltfPipeline/removePipelineExtras",["../../Core/defined"],function(e){"use strict";function t(r){if(e(r)&&"object"==typeof r){e(r.extras)&&e(r.extras._pipeline)&&(delete r.extras._pipeline,0===Object.keys(r.extras).length&&delete r.extras);for(var i in r)r.hasOwnProperty(i)&&t(r[i])}return r}return t}),function(){!function(e){var t=this||(0,eval)("this"),r=t.document,i=t.navigator,n=t.jQuery,o=t.JSON;!function(e){"function"==typeof define&&define.amd?define("ThirdParty/knockout-3.4.2",["exports","require"],e):e("object"==typeof exports&&"object"==typeof module?module.exports||exports:t.ko={})}(function(a,s){function l(e,t){return(null===e||typeof e in g)&&e===t}function u(t,r){var i;return function(){i||(i=m.a.setTimeout(function(){i=e,t()},r))}}function c(e,t){var r;return function(){clearTimeout(r),r=m.a.setTimeout(e,t)}}function d(e,t){t&&t!==_?"beforeChange"===t?this.Ob(e):this.Ja(e,t):this.Pb(e)}function h(e,t){null!==t&&t.k&&t.k()}function p(e,t){var r=this.Mc,i=r[S];i.T||(this.ob&&this.Oa[t]?(r.Sb(t,e,this.Oa[t]),this.Oa[t]=null,--this.ob):i.s[t]||r.Sb(t,e,i.t?{$:e}:r.yc(e)),e.Ha&&e.Hc())}function f(e,t,r,i){m.d[e]={init:function(e,n,o,a,s){var l,u;return m.m(function(){var o=n(),a=m.a.c(o),a=!r!=!a,c=!u;(c||t||a!==l)&&(c&&m.xa.Ca()&&(u=m.a.wa(m.f.childNodes(e),!0)),a?(c||m.f.fa(e,m.a.wa(u)),m.hb(i?i(s,o):s,e)):m.f.za(e),l=a)},null,{i:e}),{controlsDescendantBindings:!0}}},m.h.va[e]=!1,m.f.aa[e]=!0}var m=void 0!==a?a:{};m.b=function(e,t){for(var r=e.split("."),i=m,n=0;n<r.length-1;n++)i=i[r[n]];i[r[r.length-1]]=t},m.H=function(e,t,r){e[t]=r},m.version="3.4.2",m.b("version",m.version),m.options={deferUpdates:!1,useOnlyNativeEvents:!1},m.a=function(){function a(e,t){for(var r in e)e.hasOwnProperty(r)&&t(r,e[r])}function s(e,t){if(t)for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function l(e,t){return e.__proto__=t,e}function u(e,t,r,i){var n=e[t].match(_)||[];m.a.r(r.match(_),function(e){m.a.ra(n,e,i)}),e[t]=n.join(" ")}var c={__proto__:[]}instanceof Array,d="function"==typeof Symbol,h={},p={};h[i&&/Firefox\/2/i.test(i.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"],h.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" "),a(h,function(e,t){if(t.length)for(var r=0,i=t.length;r<i;r++)p[t[r]]=e});var f={propertychange:!0},g=r&&function(){for(var t=3,i=r.createElement("div"),n=i.getElementsByTagName("i");i.innerHTML="\x3c!--[if gt IE "+ ++t+"]><i></i><![endif]--\x3e",n[0];);return 4<t?t:e}(),_=/\S+/g;return{gc:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],r:function(e,t){for(var r=0,i=e.length;r<i;r++)t(e[r],r)},o:function(e,t){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(e,t);for(var r=0,i=e.length;r<i;r++)if(e[r]===t)return r;return-1},Vb:function(e,t,r){for(var i=0,n=e.length;i<n;i++)if(t.call(r,e[i],i))return e[i];return null},Na:function(e,t){var r=m.a.o(e,t);0<r?e.splice(r,1):0===r&&e.shift()},Wb:function(e){e=e||[];for(var t=[],r=0,i=e.length;r<i;r++)0>m.a.o(t,e[r])&&t.push(e[r]);return t},ib:function(e,t){e=e||[];for(var r=[],i=0,n=e.length;i<n;i++)r.push(t(e[i],i));return r},Ma:function(e,t){e=e||[];for(var r=[],i=0,n=e.length;i<n;i++)t(e[i],i)&&r.push(e[i]);return r},ta:function(e,t){if(t instanceof Array)e.push.apply(e,t);else for(var r=0,i=t.length;r<i;r++)e.push(t[r]);return e},ra:function(e,t,r){var i=m.a.o(m.a.Bb(e),t);0>i?r&&e.push(t):r||e.splice(i,1)},la:c,extend:s,$a:l,ab:c?l:s,D:a,Ea:function(e,t){if(!e)return e;var r,i={};for(r in e)e.hasOwnProperty(r)&&(i[r]=t(e[r],r,e));return i},rb:function(e){for(;e.firstChild;)m.removeNode(e.firstChild)},nc:function(e){e=m.a.W(e);for(var t=(e[0]&&e[0].ownerDocument||r).createElement("div"),i=0,n=e.length;i<n;i++)t.appendChild(m.ba(e[i]));return t},wa:function(e,t){for(var r=0,i=e.length,n=[];r<i;r++){var o=e[r].cloneNode(!0);n.push(t?m.ba(o):o)}return n},fa:function(e,t){if(m.a.rb(e),t)for(var r=0,i=t.length;r<i;r++)e.appendChild(t[r])},uc:function(e,t){var r=e.nodeType?[e]:e;if(0<r.length){for(var i=r[0],n=i.parentNode,o=0,a=t.length;o<a;o++)n.insertBefore(t[o],i);for(o=0,a=r.length;o<a;o++)m.removeNode(r[o])}},Ba:function(e,t){if(e.length){for(t=8===t.nodeType&&t.parentNode||t;e.length&&e[0].parentNode!==t;)e.splice(0,1);for(;1<e.length&&e[e.length-1].parentNode!==t;)e.length--;if(1<e.length){var r=e[0],i=e[e.length-1];for(e.length=0;r!==i;)e.push(r),r=r.nextSibling;e.push(i)}}return e},wc:function(e,t){7>g?e.setAttribute("selected",t):e.selected=t},cb:function(t){return null===t||t===e?"":t.trim?t.trim():t.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},sd:function(e,t){return e=e||"",!(t.length>e.length)&&e.substring(0,t.length)===t},Rc:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(3===e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},qb:function(e){return m.a.Rc(e,e.ownerDocument.documentElement)},Tb:function(e){return!!m.a.Vb(e,m.a.qb)},A:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},Zb:function(e){return m.onError?function(){try{return e.apply(this,arguments)}catch(e){throw m.onError&&m.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(m.a.Zb(e),t)},dc:function(e){setTimeout(function(){throw m.onError&&m.onError(e),e},0)},q:function(e,t,r){var i=m.a.Zb(r);if(r=g&&f[t], +m.options.useOnlyNativeEvents||r||!n)if(r||"function"!=typeof e.addEventListener){if(void 0===e.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");var o=function(t){i.call(e,t)},a="on"+t;e.attachEvent(a,o),m.a.G.qa(e,function(){e.detachEvent(a,o)})}else e.addEventListener(t,i,!1);else n(e).bind(t,i)},Fa:function(e,i){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var o;if("input"===m.a.A(e)&&e.type&&"click"==i.toLowerCase()?(o=e.type,o="checkbox"==o||"radio"==o):o=!1,m.options.useOnlyNativeEvents||!n||o)if("function"==typeof r.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");o=r.createEvent(p[i]||"HTMLEvents"),o.initEvent(i,!0,!0,t,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(o)}else if(o&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+i)}else n(e).trigger(i)},c:function(e){return m.I(e)?e():e},Bb:function(e){return m.I(e)?e.p():e},fb:function(e,t,r){var i;t&&("object"==typeof e.classList?(i=e.classList[r?"add":"remove"],m.a.r(t.match(_),function(t){i.call(e.classList,t)})):"string"==typeof e.className.baseVal?u(e.className,"baseVal",t,r):u(e,"className",t,r))},bb:function(t,r){var i=m.a.c(r);null!==i&&i!==e||(i="");var n=m.f.firstChild(t);!n||3!=n.nodeType||m.f.nextSibling(n)?m.f.fa(t,[t.ownerDocument.createTextNode(i)]):n.data=i,m.a.Wc(t)},vc:function(e,t){if(e.name=t,7>=g)try{e.mergeAttributes(r.createElement("<input name='"+e.name+"'/>"),!1)}catch(e){}},Wc:function(e){9<=g&&(e=1==e.nodeType?e:e.parentNode,e.style&&(e.style.zoom=e.style.zoom))},Sc:function(e){if(g){var t=e.style.width;e.style.width=0,e.style.width=t}},nd:function(e,t){e=m.a.c(e),t=m.a.c(t);for(var r=[],i=e;i<=t;i++)r.push(i);return r},W:function(e){for(var t=[],r=0,i=e.length;r<i;r++)t.push(e[r]);return t},bc:function(e){return d?Symbol(e):e},xd:6===g,yd:7===g,C:g,ic:function(e,t){for(var r=m.a.W(e.getElementsByTagName("input")).concat(m.a.W(e.getElementsByTagName("textarea"))),i="string"==typeof t?function(e){return e.name===t}:function(e){return t.test(e.name)},n=[],o=r.length-1;0<=o;o--)i(r[o])&&n.push(r[o]);return n},kd:function(e){return"string"==typeof e&&(e=m.a.cb(e))?o&&o.parse?o.parse(e):new Function("return "+e)():null},Gb:function(e,t,r){if(!o||!o.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");return o.stringify(m.a.c(e),t,r)},ld:function(e,t,i){i=i||{};var n=i.params||{},o=i.includeFields||this.gc,s=e;if("object"==typeof e&&"form"===m.a.A(e))for(var s=e.action,l=o.length-1;0<=l;l--)for(var u=m.a.ic(e,o[l]),c=u.length-1;0<=c;c--)n[u[c].name]=u[c].value;t=m.a.c(t);var d=r.createElement("form");d.style.display="none",d.action=s,d.method="post";for(var h in t)e=r.createElement("input"),e.type="hidden",e.name=h,e.value=m.a.Gb(m.a.c(t[h])),d.appendChild(e);a(n,function(e,t){var i=r.createElement("input");i.type="hidden",i.name=e,i.value=t,d.appendChild(i)}),r.body.appendChild(d),i.submitter?i.submitter(d):d.submit(),setTimeout(function(){d.parentNode.removeChild(d)},0)}}}(),m.b("utils",m.a),m.b("utils.arrayForEach",m.a.r),m.b("utils.arrayFirst",m.a.Vb),m.b("utils.arrayFilter",m.a.Ma),m.b("utils.arrayGetDistinctValues",m.a.Wb),m.b("utils.arrayIndexOf",m.a.o),m.b("utils.arrayMap",m.a.ib),m.b("utils.arrayPushAll",m.a.ta),m.b("utils.arrayRemoveItem",m.a.Na),m.b("utils.extend",m.a.extend),m.b("utils.fieldsIncludedWithJsonPost",m.a.gc),m.b("utils.getFormFields",m.a.ic),m.b("utils.peekObservable",m.a.Bb),m.b("utils.postJson",m.a.ld),m.b("utils.parseJson",m.a.kd),m.b("utils.registerEventHandler",m.a.q),m.b("utils.stringifyJson",m.a.Gb),m.b("utils.range",m.a.nd),m.b("utils.toggleDomNodeCssClass",m.a.fb),m.b("utils.triggerEvent",m.a.Fa),m.b("utils.unwrapObservable",m.a.c),m.b("utils.objectForEach",m.a.D),m.b("utils.addOrRemoveItem",m.a.ra),m.b("utils.setTextContent",m.a.bb),m.b("unwrap",m.a.c),Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if(1===arguments.length)return function(){return t.apply(e,arguments)};var r=Array.prototype.slice.call(arguments,1);return function(){var i=r.slice(0);return i.push.apply(i,arguments),t.apply(e,i)}}),m.a.e=new function(){function t(t,o){var a=t[i];if(!a||"null"===a||!n[a]){if(!o)return e;a=t[i]="ko"+r++,n[a]={}}return n[a]}var r=0,i="__ko__"+(new Date).getTime(),n={};return{get:function(r,i){var n=t(r,!1);return n===e?e:n[i]},set:function(r,i,n){n===e&&t(r,!1)===e||(t(r,!0)[i]=n)},clear:function(e){var t=e[i];return!!t&&(delete n[t],e[i]=null,!0)},J:function(){return r+++i}}},m.b("utils.domData",m.a.e),m.b("utils.domData.clear",m.a.e.clear),m.a.G=new function(){function t(t,r){var n=m.a.e.get(t,i);return n===e&&r&&(n=[],m.a.e.set(t,i,n)),n}function r(e){var i=t(e,!1);if(i)for(var i=i.slice(0),n=0;n<i.length;n++)i[n](e);if(m.a.e.clear(e),m.a.G.cleanExternalData(e),a[e.nodeType])for(i=e.firstChild;e=i;)i=e.nextSibling,8===e.nodeType&&r(e)}var i=m.a.e.J(),o={1:!0,8:!0,9:!0},a={1:!0,9:!0};return{qa:function(e,r){if("function"!=typeof r)throw Error("Callback must be a function");t(e,!0).push(r)},tc:function(r,n){var o=t(r,!1);o&&(m.a.Na(o,n),0==o.length&&m.a.e.set(r,i,e))},ba:function(e){if(o[e.nodeType]&&(r(e),a[e.nodeType])){var t=[];m.a.ta(t,e.getElementsByTagName("*"));for(var i=0,n=t.length;i<n;i++)r(t[i])}return e},removeNode:function(e){m.ba(e),e.parentNode&&e.parentNode.removeChild(e)},cleanExternalData:function(e){n&&"function"==typeof n.cleanData&&n.cleanData([e])}}},m.ba=m.a.G.ba,m.removeNode=m.a.G.removeNode,m.b("cleanNode",m.ba),m.b("removeNode",m.removeNode),m.b("utils.domNodeDisposal",m.a.G),m.b("utils.domNodeDisposal.addDisposeCallback",m.a.G.qa),m.b("utils.domNodeDisposal.removeDisposeCallback",m.a.G.tc),function(){var i=[0,"",""],o=[1,"<table>","</table>"],a=[3,"<table><tbody><tr>","</tr></tbody></table>"],s=[1,"<select multiple='multiple'>","</select>"],l={thead:o,tbody:o,tfoot:o,tr:[2,"<table><tbody>","</tbody></table>"],td:a,th:a,option:s,optgroup:s},u=8>=m.a.C;m.a.na=function(e,o){var a;if(n){if(n.parseHTML)a=n.parseHTML(e,o)||[];else if((a=n.clean([e],o))&&a[0]){for(var s=a[0];s.parentNode&&11!==s.parentNode.nodeType;)s=s.parentNode;s.parentNode&&s.parentNode.removeChild(s)}}else{(a=o)||(a=r);var c,s=a.parentWindow||a.defaultView||t,d=m.a.cb(e).toLowerCase(),h=a.createElement("div");for(c=(d=d.match(/^<([a-z]+)[ >]/))&&l[d[1]]||i,d=c[0],c="ignored<div>"+c[1]+e+c[2]+"</div>","function"==typeof s.innerShiv?h.appendChild(s.innerShiv(c)):(u&&a.appendChild(h),h.innerHTML=c,u&&h.parentNode.removeChild(h));d--;)h=h.lastChild;a=m.a.W(h.lastChild.childNodes)}return a},m.a.Eb=function(t,r){if(m.a.rb(t),null!==(r=m.a.c(r))&&r!==e)if("string"!=typeof r&&(r=r.toString()),n)n(t).html(r);else for(var i=m.a.na(r,t.ownerDocument),o=0;o<i.length;o++)t.appendChild(i[o])}}(),m.b("utils.parseHtmlFragment",m.a.na),m.b("utils.setHtml",m.a.Eb),m.N=function(){function t(e,r){if(e)if(8==e.nodeType){var i=m.N.pc(e.nodeValue);null!=i&&r.push({Qc:e,hd:i})}else if(1==e.nodeType)for(var i=0,n=e.childNodes,o=n.length;i<o;i++)t(n[i],r)}var r={};return{yb:function(e){if("function"!=typeof e)throw Error("You can only pass a function to ko.memoization.memoize()");var t=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);return r[t]=e,"\x3c!--[ko_memo:"+t+"]--\x3e"},Bc:function(t,i){var n=r[t];if(n===e)throw Error("Couldn't find any memo with ID "+t+". Perhaps it's already been unmemoized.");try{return n.apply(null,i||[]),!0}finally{delete r[t]}},Cc:function(e,r){var i=[];t(e,i);for(var n=0,o=i.length;n<o;n++){var a=i[n].Qc,s=[a];r&&m.a.ta(s,r),m.N.Bc(i[n].hd,s),a.nodeValue="",a.parentNode&&a.parentNode.removeChild(a)}},pc:function(e){return(e=e.match(/^\[ko_memo\:(.*?)\]$/))?e[1]:null}}}(),m.b("memoization",m.N),m.b("memoization.memoize",m.N.yb),m.b("memoization.unmemoize",m.N.Bc),m.b("memoization.parseMemoText",m.N.pc),m.b("memoization.unmemoizeDomNodeAndDescendants",m.N.Cc),m.Z=function(){function e(){if(o)for(var e,t=o,r=0;s<o;)if(e=n[s++]){if(s>t){if(5e3<=++r){s=o,m.a.dc(Error("'Too much recursion' after processing "+r+" task groups."));break}t=o}try{e()}catch(e){m.a.dc(e)}}}function i(){e(),s=o=n.length=0}var n=[],o=0,a=1,s=0;return{scheduler:t.MutationObserver?function(e){var t=r.createElement("div");return new MutationObserver(e).observe(t,{attributes:!0}),function(){t.classList.toggle("foo")}}(i):r&&"onreadystatechange"in r.createElement("script")?function(e){var t=r.createElement("script");t.onreadystatechange=function(){t.onreadystatechange=null,r.documentElement.removeChild(t),t=null,e()},r.documentElement.appendChild(t)}:function(e){setTimeout(e,0)},Za:function(e){return o||m.Z.scheduler(i),n[o++]=e,a++},cancel:function(e){(e-=a-o)>=s&&e<o&&(n[e]=null)},resetForTesting:function(){var e=o-s;return s=o=n.length=0,e},rd:e}}(),m.b("tasks",m.Z),m.b("tasks.schedule",m.Z.Za),m.b("tasks.runEarly",m.Z.rd),m.Aa={throttle:function(e,t){e.throttleEvaluation=t;var r=null;return m.B({read:e,write:function(i){clearTimeout(r),r=m.a.setTimeout(function(){e(i)},t)}})},rateLimit:function(e,t){var r,i,n;"number"==typeof t?r=t:(r=t.timeout,i=t.method),e.gb=!1,n="notifyWhenChangesStop"==i?c:u,e.Wa(function(e){return n(e,r)})},deferred:function(t,r){if(!0!==r)throw Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled.");t.gb||(t.gb=!0,t.Wa(function(r){var i,n=!1;return function(){if(!n){m.Z.cancel(i),i=m.Z.Za(r);try{n=!0,t.notifySubscribers(e,"dirty")}finally{n=!1}}}}))},notify:function(e,t){e.equalityComparer="always"==t?null:l}};var g={undefined:1,boolean:1,number:1,string:1};m.b("extenders",m.Aa),m.zc=function(e,t,r){this.$=e,this.jb=t,this.Pc=r,this.T=!1,m.H(this,"dispose",this.k)},m.zc.prototype.k=function(){this.T=!0,this.Pc()},m.K=function(){m.a.ab(this,v),v.ub(this)};var _="change",v={ub:function(e){e.F={change:[]},e.Qb=1},Y:function(e,t,r){var i=this;r=r||_;var n=new m.zc(i,t?e.bind(t):e,function(){m.a.Na(i.F[r],n),i.Ka&&i.Ka(r)});return i.ua&&i.ua(r),i.F[r]||(i.F[r]=[]),i.F[r].push(n),n},notifySubscribers:function(e,t){if(t=t||_,t===_&&this.Kb(),this.Ra(t)){var r=t===_&&this.Fc||this.F[t].slice(0);try{m.l.Xb();for(var i,n=0;i=r[n];++n)i.T||i.jb(e)}finally{m.l.end()}}},Pa:function(){return this.Qb},Zc:function(e){return this.Pa()!==e},Kb:function(){++this.Qb},Wa:function(e){var t,r,i,n,o=this,a=m.I(o);o.Ja||(o.Ja=o.notifySubscribers,o.notifySubscribers=d);var s=e(function(){o.Ha=!1,a&&n===o&&(n=o.Mb?o.Mb():o());var e=r||o.Ua(i,n);r=t=!1,e&&o.Ja(i=n)});o.Pb=function(e){o.Fc=o.F[_].slice(0),o.Ha=t=!0,n=e,s()},o.Ob=function(e){t||(i=e,o.Ja(e,"beforeChange"))},o.Hc=function(){o.Ua(i,o.p(!0))&&(r=!0)}},Ra:function(e){return this.F[e]&&this.F[e].length},Xc:function(e){if(e)return this.F[e]&&this.F[e].length||0;var t=0;return m.a.D(this.F,function(e,r){"dirty"!==e&&(t+=r.length)}),t},Ua:function(e,t){return!this.equalityComparer||!this.equalityComparer(e,t)},extend:function(e){var t=this;return e&&m.a.D(e,function(e,r){var i=m.Aa[e];"function"==typeof i&&(t=i(t,r)||t)}),t}};m.H(v,"subscribe",v.Y),m.H(v,"extend",v.extend),m.H(v,"getSubscriptionsCount",v.Xc),m.a.la&&m.a.$a(v,Function.prototype),m.K.fn=v,m.lc=function(e){return null!=e&&"function"==typeof e.Y&&"function"==typeof e.notifySubscribers},m.b("subscribable",m.K),m.b("isSubscribable",m.lc),m.xa=m.l=function(){function e(e){i.push(r),r=e}function t(){r=i.pop()}var r,i=[],n=0;return{Xb:e,end:t,sc:function(e){if(r){if(!m.lc(e))throw Error("Only subscribable things can act as dependencies");r.jb.call(r.Lc,e,e.Gc||(e.Gc=++n))}},w:function(r,i,n){try{return e(),r.apply(i,n||[])}finally{t()}},Ca:function(){if(r)return r.m.Ca()},Va:function(){if(r)return r.Va}}}(),m.b("computedContext",m.xa),m.b("computedContext.getDependenciesCount",m.xa.Ca),m.b("computedContext.isInitial",m.xa.Va),m.b("ignoreDependencies",m.wd=m.l.w);var y=m.a.bc("_latestValue");m.O=function(e){function t(){return 0<arguments.length?(t.Ua(t[y],arguments[0])&&(t.ia(),t[y]=arguments[0],t.ha()),this):(m.l.sc(t),t[y])}return t[y]=e,m.a.la||m.a.extend(t,m.K.fn),m.K.fn.ub(t),m.a.ab(t,b),m.options.deferUpdates&&m.Aa.deferred(t,!0),t};var b={equalityComparer:l,p:function(){return this[y]},ha:function(){this.notifySubscribers(this[y])},ia:function(){this.notifySubscribers(this[y],"beforeChange")}};m.a.la&&m.a.$a(b,m.K.fn);var C=m.O.md="__ko_proto__";b[C]=m.O,m.Qa=function(t,r){return null!==t&&t!==e&&t[C]!==e&&(t[C]===r||m.Qa(t[C],r))},m.I=function(e){return m.Qa(e,m.O)},m.Da=function(e){return!!("function"==typeof e&&e[C]===m.O||"function"==typeof e&&e[C]===m.B&&e.$c)},m.b("observable",m.O),m.b("isObservable",m.I),m.b("isWriteableObservable",m.Da),m.b("isWritableObservable",m.Da),m.b("observable.fn",b),m.H(b,"peek",b.p),m.H(b,"valueHasMutated",b.ha),m.H(b,"valueWillMutate",b.ia),m.ma=function(e){if("object"!=typeof(e=e||[])||!("length"in e))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");return e=m.O(e),m.a.ab(e,m.ma.fn),e.extend({trackArrayChanges:!0})},m.ma.fn={remove:function(e){for(var t=this.p(),r=[],i="function"!=typeof e||m.I(e)?function(t){return t===e}:e,n=0;n<t.length;n++){var o=t[n];i(o)&&(0===r.length&&this.ia(),r.push(o),t.splice(n,1),n--)}return r.length&&this.ha(),r},removeAll:function(t){if(t===e){var r=this.p(),i=r.slice(0);return this.ia(),r.splice(0,r.length),this.ha(),i}return t?this.remove(function(e){return 0<=m.a.o(t,e)}):[]},destroy:function(e){var t=this.p(),r="function"!=typeof e||m.I(e)?function(t){return t===e}:e;this.ia();for(var i=t.length-1;0<=i;i--)r(t[i])&&(t[i]._destroy=!0);this.ha()},destroyAll:function(t){return t===e?this.destroy(function(){return!0}):t?this.destroy(function(e){return 0<=m.a.o(t,e)}):[]},indexOf:function(e){var t=this();return m.a.o(t,e)},replace:function(e,t){var r=this.indexOf(e);0<=r&&(this.ia(),this.p()[r]=t,this.ha())}},m.a.la&&m.a.$a(m.ma.fn,m.O.fn),m.a.r("pop push reverse shift sort splice unshift".split(" "),function(e){m.ma.fn[e]=function(){var t=this.p();this.ia(),this.Yb(t,e,arguments);var r=t[e].apply(t,arguments);return this.ha(),r===t?this:r}}),m.a.r(["slice"],function(e){m.ma.fn[e]=function(){var t=this();return t[e].apply(t,arguments)}}),m.b("observableArray",m.ma),m.Aa.trackArrayChanges=function(t,r){function i(){if(!a){a=!0,o=t.notifySubscribers,t.notifySubscribers=function(e,t){return t&&t!==_||++l,o.apply(this,arguments)};var e=[].concat(t.p()||[]);s=null,n=t.Y(function(r){if(r=[].concat(r||[]),t.Ra("arrayChange")){var i;(!s||1<l)&&(s=m.a.lb(e,r,t.kb)),i=s}e=r,s=null,l=0,i&&i.length&&t.notifySubscribers(i,"arrayChange")})}}if(t.kb={},r&&"object"==typeof r&&m.a.extend(t.kb,r),t.kb.sparse=!0,!t.Yb){var n,o,a=!1,s=null,l=0,u=t.ua,c=t.Ka;t.ua=function(e){u&&u.call(t,e),"arrayChange"===e&&i()},t.Ka=function(r){c&&c.call(t,r),"arrayChange"!==r||t.Ra("arrayChange")||(o&&(t.notifySubscribers=o,o=e),n.k(),a=!1)},t.Yb=function(e,t,r){function i(e,t,r){return n[n.length]={status:e,value:t,index:r}}if(a&&!l){var n=[],o=e.length,u=r.length,c=0;switch(t){case"push":c=o;case"unshift":for(t=0;t<u;t++)i("added",r[t],c+t);break;case"pop":c=o-1;case"shift":o&&i("deleted",e[c],c);break;case"splice":t=Math.min(Math.max(0,0>r[0]?o+r[0]:r[0]),o);for(var o=1===u?o:Math.min(t+(r[1]||0),o),u=t+u-2,c=Math.max(o,u),d=[],h=[],p=2;t<c;++t,++p)t<o&&h.push(i("deleted",e[t],t)),t<u&&d.push(i("added",r[p],t));m.a.hc(h,d);break;default:return}s=n}}}};var S=m.a.bc("_state");m.m=m.B=function(t,r,i){function n(){if(0<arguments.length){if("function"!=typeof o)throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");return o.apply(a.sb,arguments),this}return m.l.sc(n),(a.V||a.t&&n.Sa())&&n.U(),a.M}if("object"==typeof t?i=t:(i=i||{},t&&(i.read=t)),"function"!=typeof i.read)throw Error("Pass a function that returns the value of the ko.computed");var o=i.write,a={M:e,da:!0,V:!0,Ta:!1,Hb:!1,T:!1,Ya:!1,t:!1,od:i.read,sb:r||i.owner,i:i.disposeWhenNodeIsRemoved||i.i||null,ya:i.disposeWhen||i.ya,pb:null,s:{},L:0,fc:null};return n[S]=a,n.$c="function"==typeof o,m.a.la||m.a.extend(n,m.K.fn),m.K.fn.ub(n),m.a.ab(n,w),i.pure?(a.Ya=!0,a.t=!0,m.a.extend(n,T)):i.deferEvaluation&&m.a.extend(n,E),m.options.deferUpdates&&m.Aa.deferred(n,!0),a.i&&(a.Hb=!0,a.i.nodeType||(a.i=null)),a.t||i.deferEvaluation||n.U(),a.i&&n.ca()&&m.a.G.qa(a.i,a.pb=function(){n.k()}),n};var w={equalityComparer:l,Ca:function(){return this[S].L},Sb:function(e,t,r){if(this[S].Ya&&t===this)throw Error("A 'pure' computed must not be called recursively");this[S].s[e]=r,r.Ia=this[S].L++,r.pa=t.Pa()},Sa:function(){var e,t,r=this[S].s;for(e in r)if(r.hasOwnProperty(e)&&(t=r[e],this.oa&&t.$.Ha||t.$.Zc(t.pa)))return!0},gd:function(){this.oa&&!this[S].Ta&&this.oa(!1)},ca:function(){var e=this[S];return e.V||0<e.L},qd:function(){this.Ha?this[S].V&&(this[S].da=!0):this.ec()},yc:function(e){if(e.gb&&!this[S].i){var t=e.Y(this.gd,this,"dirty"),r=e.Y(this.qd,this);return{$:e,k:function(){t.k(),r.k()}}}return e.Y(this.ec,this)},ec:function(){var e=this,t=e.throttleEvaluation;t&&0<=t?(clearTimeout(this[S].fc),this[S].fc=m.a.setTimeout(function(){e.U(!0)},t)):e.oa?e.oa(!0):e.U(!0)},U:function(e){var t=this[S],r=t.ya,i=!1;if(!t.Ta&&!t.T){if(t.i&&!m.a.qb(t.i)||r&&r()){if(!t.Hb)return void this.k()}else t.Hb=!1;t.Ta=!0;try{i=this.Vc(e)}finally{t.Ta=!1}return t.L||this.k(),i}},Vc:function(t){var r=this[S],i=!1,n=r.Ya?e:!r.L,o={Mc:this,Oa:r.s,ob:r.L};return m.l.Xb({Lc:o,jb:p,m:this,Va:n}),r.s={},r.L=0,o=this.Uc(r,o),this.Ua(r.M,o)&&(r.t||this.notifySubscribers(r.M,"beforeChange"),r.M=o,r.t?this.Kb():t&&this.notifySubscribers(r.M),i=!0),n&&this.notifySubscribers(r.M,"awake"),i},Uc:function(e,t){try{var r=e.od;return e.sb?r.call(e.sb):r()}finally{m.l.end(),t.ob&&!e.t&&m.a.D(t.Oa,h),e.da=e.V=!1}},p:function(e){var t=this[S];return(t.V&&(e||!t.L)||t.t&&this.Sa())&&this.U(),t.M},Wa:function(e){m.K.fn.Wa.call(this,e),this.Mb=function(){return this[S].da?this.U():this[S].V=!1,this[S].M},this.oa=function(e){this.Ob(this[S].M),this[S].V=!0,e&&(this[S].da=!0),this.Pb(this)}},k:function(){var e=this[S];!e.t&&e.s&&m.a.D(e.s,function(e,t){t.k&&t.k()}),e.i&&e.pb&&m.a.G.tc(e.i,e.pb),e.s=null,e.L=0,e.T=!0,e.da=!1,e.V=!1,e.t=!1,e.i=null}},T={ua:function(e){var t=this,r=t[S];if(!r.T&&r.t&&"change"==e){if(r.t=!1,r.da||t.Sa())r.s=null,r.L=0,t.U()&&t.Kb();else{var i=[];m.a.D(r.s,function(e,t){i[t.Ia]=e}),m.a.r(i,function(e,i){var n=r.s[e],o=t.yc(n.$);o.Ia=i,o.pa=n.pa,r.s[e]=o})}r.T||t.notifySubscribers(r.M,"awake")}},Ka:function(t){var r=this[S];r.T||"change"!=t||this.Ra("change")||(m.a.D(r.s,function(e,t){t.k&&(r.s[e]={$:t.$,Ia:t.Ia,pa:t.pa},t.k())}),r.t=!0,this.notifySubscribers(e,"asleep"))},Pa:function(){var e=this[S];return e.t&&(e.da||this.Sa())&&this.U(),m.K.fn.Pa.call(this)}},E={ua:function(e){"change"!=e&&"beforeChange"!=e||this.p()}};m.a.la&&m.a.$a(w,m.K.fn);var A=m.O.md;m.m[A]=m.O,w[A]=m.m,m.bd=function(e){return m.Qa(e,m.m)},m.cd=function(e){return m.Qa(e,m.m)&&e[S]&&e[S].Ya},m.b("computed",m.m),m.b("dependentObservable",m.m),m.b("isComputed",m.bd),m.b("isPureComputed",m.cd),m.b("computed.fn",w),m.H(w,"peek",w.p),m.H(w,"dispose",w.k),m.H(w,"isActive",w.ca),m.H(w,"getDependenciesCount",w.Ca),m.rc=function(e,t){return"function"==typeof e?m.m(e,t,{pure:!0}):(e=m.a.extend({},e),e.pure=!0,m.m(e,t))},m.b("pureComputed",m.rc),function(){function t(n,o,a){if(a=a||new i,"object"!=typeof(n=o(n))||null===n||n===e||n instanceof RegExp||n instanceof Date||n instanceof String||n instanceof Number||n instanceof Boolean)return n;var s=n instanceof Array?[]:{};return a.save(n,s),r(n,function(r){var i=o(n[r]);switch(typeof i){case"boolean":case"number":case"string":case"function":s[r]=i;break;case"object":case"undefined":var l=a.get(i);s[r]=l!==e?l:t(i,o,a)}}),s}function r(e,t){if(e instanceof Array){for(var r=0;r<e.length;r++)t(r);"function"==typeof e.toJSON&&t("toJSON")}else for(r in e)t(r)}function i(){this.keys=[],this.Lb=[]}m.Ac=function(e){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return t(e,function(e){for(var t=0;m.I(e)&&10>t;t++)e=e();return e})},m.toJSON=function(e,t,r){return e=m.Ac(e),m.a.Gb(e,t,r)},i.prototype={save:function(e,t){var r=m.a.o(this.keys,e);0<=r?this.Lb[r]=t:(this.keys.push(e),this.Lb.push(t))},get:function(t){return t=m.a.o(this.keys,t),0<=t?this.Lb[t]:e}}}(),m.b("toJS",m.Ac),m.b("toJSON",m.toJSON),function(){m.j={u:function(t){switch(m.a.A(t)){case"option":return!0===t.__ko__hasDomDataOptionValue__?m.a.e.get(t,m.d.options.zb):7>=m.a.C?t.getAttributeNode("value")&&t.getAttributeNode("value").specified?t.value:t.text:t.value;case"select":return 0<=t.selectedIndex?m.j.u(t.options[t.selectedIndex]):e;default:return t.value}},ja:function(t,r,i){switch(m.a.A(t)){case"option":switch(typeof r){case"string":m.a.e.set(t,m.d.options.zb,e),"__ko__hasDomDataOptionValue__"in t&&delete t.__ko__hasDomDataOptionValue__,t.value=r;break;default:m.a.e.set(t,m.d.options.zb,r),t.__ko__hasDomDataOptionValue__=!0,t.value="number"==typeof r?r:""}break;case"select":""!==r&&null!==r||(r=e);for(var n,o=-1,a=0,s=t.options.length;a<s;++a)if((n=m.j.u(t.options[a]))==r||""==n&&r===e){o=a;break}(i||0<=o||r===e&&1<t.size)&&(t.selectedIndex=o);break;default:null!==r&&r!==e||(r=""),t.value=r}}}}(),m.b("selectExtensions",m.j),m.b("selectExtensions.readValue",m.j.u),m.b("selectExtensions.writeValue",m.j.ja),m.h=function(){function e(e){e=m.a.cb(e),123===e.charCodeAt(0)&&(e=e.slice(1,-1));var t,r=[],a=e.match(i),s=[],l=0;if(a){a.push(",");for(var u,c=0;u=a[c];++c){var d=u.charCodeAt(0);if(44===d){if(0>=l){r.push(t&&s.length?{key:t,value:s.join("")}:{unknown:t||s.join("")}),t=l=0,s=[];continue}}else if(58===d){if(!l&&!t&&1===s.length){t=s.pop();continue}}else 47===d&&c&&1<u.length?(d=a[c-1].match(n))&&!o[d[0]]&&(e=e.substr(e.indexOf(u)+1),a=e.match(i),a.push(","),c=-1,u="/"):40===d||123===d||91===d?++l:41===d||125===d||93===d?--l:t||s.length||34!==d&&39!==d||(u=u.slice(1,-1));s.push(u)}}return r}var t=["true","false","null","undefined"],r=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,i=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),n=/[\])"'A-Za-z0-9_$]+$/,o={in:1,return:1,typeof:1},a={};return{va:[],ga:a,Ab:e,Xa:function(i,n){function o(e,i){var n;if(!c){var d=m.getBindingHandler(e);if(d&&d.preprocess&&!(i=d.preprocess(i,e,o)))return;(d=a[e])&&(n=i,0<=m.a.o(t,n)?n=!1:(d=n.match(r),n=null!==d&&(d[1]?"Object("+d[1]+")"+d[2]:n)),d=n),d&&l.push("'"+e+"':function(_z){"+n+"=_z}")}u&&(i="function(){return "+i+" }"),s.push("'"+e+"':"+i)}n=n||{};var s=[],l=[],u=n.valueAccessors,c=n.bindingParams,d="string"==typeof i?e(i):i;return m.a.r(d,function(e){o(e.key||e.unknown,e.value)}),l.length&&o("_ko_property_writers","{"+l.join(",")+" }"),s.join(",")},fd:function(e,t){for(var r=0;r<e.length;r++)if(e[r].key==t)return!0;return!1},Ga:function(e,t,r,i,n){e&&m.I(e)?!m.Da(e)||n&&e.p()===i||e(i):(e=t.get("_ko_property_writers"))&&e[r]&&e[r](i)}}}(),m.b("expressionRewriting",m.h),m.b("expressionRewriting.bindingRewriteValidators",m.h.va),m.b("expressionRewriting.parseObjectLiteral",m.h.Ab),m.b("expressionRewriting.preProcessBindings",m.h.Xa),m.b("expressionRewriting._twoWayBindings",m.h.ga),m.b("jsonExpressionRewriting",m.h),m.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",m.h.Xa),function(){function e(e){return 8==e.nodeType&&a.test(o?e.text:e.nodeValue)}function t(e){return 8==e.nodeType&&s.test(o?e.text:e.nodeValue)}function i(r,i){for(var n=r,o=1,a=[];n=n.nextSibling;){if(t(n)&&0===--o)return a;a.push(n),e(n)&&o++}if(!i)throw Error("Cannot find closing comment tag to match: "+r.nodeValue);return null}function n(e,t){var r=i(e,t);return r?0<r.length?r[r.length-1].nextSibling:e.nextSibling:null}var o=r&&"\x3c!--test--\x3e"===r.createComment("test").text,a=o?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,s=o?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,l={ul:!0,ol:!0};m.f={aa:{},childNodes:function(t){return e(t)?i(t):t.childNodes},za:function(t){if(e(t)){t=m.f.childNodes(t);for(var r=0,i=t.length;r<i;r++)m.removeNode(t[r])}else m.a.rb(t)},fa:function(t,r){if(e(t)){m.f.za(t);for(var i=t.nextSibling,n=0,o=r.length;n<o;n++)i.parentNode.insertBefore(r[n],i)}else m.a.fa(t,r)},qc:function(t,r){e(t)?t.parentNode.insertBefore(r,t.nextSibling):t.firstChild?t.insertBefore(r,t.firstChild):t.appendChild(r)},kc:function(t,r,i){i?e(t)?t.parentNode.insertBefore(r,i.nextSibling):i.nextSibling?t.insertBefore(r,i.nextSibling):t.appendChild(r):m.f.qc(t,r)},firstChild:function(r){return e(r)?!r.nextSibling||t(r.nextSibling)?null:r.nextSibling:r.firstChild},nextSibling:function(r){return e(r)&&(r=n(r)),r.nextSibling&&t(r.nextSibling)?null:r.nextSibling},Yc:e,vd:function(e){return(e=(o?e.text:e.nodeValue).match(a))?e[1]:null},oc:function(r){if(l[m.a.A(r)]){var i=r.firstChild;if(i)do{if(1===i.nodeType){var o;o=i.firstChild;var a=null;if(o)do{if(a)a.push(o);else if(e(o)){var s=n(o,!0);s?o=s:a=[o]}else t(o)&&(a=[o])}while(o=o.nextSibling);if(o=a)for(a=i.nextSibling,s=0;s<o.length;s++)a?r.insertBefore(o[s],a):r.appendChild(o[s])}}while(i=i.nextSibling)}}}}(),m.b("virtualElements",m.f),m.b("virtualElements.allowedBindings",m.f.aa),m.b("virtualElements.emptyNode",m.f.za),m.b("virtualElements.insertAfter",m.f.kc),m.b("virtualElements.prepend",m.f.qc),m.b("virtualElements.setDomNodeChildren",m.f.fa),function(){m.S=function(){this.Kc={}},m.a.extend(m.S.prototype,{nodeHasBindings:function(e){switch(e.nodeType){case 1:return null!=e.getAttribute("data-bind")||m.g.getComponentNameForNode(e);case 8:return m.f.Yc(e);default:return!1}},getBindings:function(e,t){var r=this.getBindingsString(e,t),r=r?this.parseBindingsString(r,t,e):null;return m.g.Rb(r,e,t,!1)},getBindingAccessors:function(e,t){var r=this.getBindingsString(e,t),r=r?this.parseBindingsString(r,t,e,{valueAccessors:!0}):null;return m.g.Rb(r,e,t,!0)},getBindingsString:function(e){switch(e.nodeType){case 1:return e.getAttribute("data-bind");case 8:return m.f.vd(e);default:return null}},parseBindingsString:function(e,t,r,i){try{var n,o=this.Kc,a=e+(i&&i.valueAccessors||"");if(!(n=o[a])){var s,l="with($context){with($data||{}){return{"+m.h.Xa(e,i)+"}}}";s=new Function("$context","$element",l),n=o[a]=s}return n(t,r)}catch(t){throw t.message="Unable to parse bindings.\nBindings value: "+e+"\nMessage: "+t.message,t}}}),m.S.instance=new m.S}(),m.b("bindingProvider",m.S),function(){function r(e){return function(){return e}}function i(e){return e()}function o(e){return m.a.Ea(m.l.w(e),function(t,r){return function(){return e()[r]}})}function a(e,t,i){return"function"==typeof e?o(e.bind(null,t,i)):m.a.Ea(e,r)}function s(e,t){return o(this.getBindings.bind(this,e,t))}function l(e,t,r){var i,n=m.f.firstChild(t),o=m.S.instance,a=o.preprocessNode;if(a){for(;i=n;)n=m.f.nextSibling(i),a.call(o,i);n=m.f.firstChild(t)}for(;i=n;)n=m.f.nextSibling(i),u(e,i,r)}function u(e,t,r){var i=!0,n=1===t.nodeType;n&&m.f.oc(t),(n&&r||m.S.instance.nodeHasBindings(t))&&(i=d(t,null,e,r).shouldBindDescendants),i&&!p[m.a.A(t)]&&l(e,t,!n)}function c(e){var t=[],r={},i=[];return m.a.D(e,function n(o){if(!r[o]){var a=m.getBindingHandler(o);a&&(a.after&&(i.push(o),m.a.r(a.after,function(t){if(e[t]){if(-1!==m.a.o(i,t))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+i.join(", "));n(t)}}),i.length--),t.push({key:o,jc:a})),r[o]=!0}}),t}function d(t,r,n,o){var a=m.a.e.get(t,f);if(!r){if(a)throw Error("You cannot apply bindings multiple times to the same element.");m.a.e.set(t,f,!0)}!a&&o&&m.xc(t,n);var l;if(r&&"function"!=typeof r)l=r;else{var u=m.S.instance,d=u.getBindingAccessors||s,h=m.B(function(){return(l=r?r(n,t):d.call(u,t,n))&&n.Q&&n.Q(),l},null,{i:t});l&&h.ca()||(h=null)}var p;if(l){var g=h?function(e){return function(){return i(h()[e])}}:function(e){return l[e]},_=function(){return m.a.Ea(h?h():l,i)};_.get=function(e){return l[e]&&i(g(e))},_.has=function(e){return e in l},o=c(l),m.a.r(o,function(r){var i=r.jc.init,o=r.jc.update,a=r.key;if(8===t.nodeType&&!m.f.aa[a])throw Error("The binding '"+a+"' cannot be used with virtual elements");try{"function"==typeof i&&m.l.w(function(){var r=i(t,g(a),_,n.$data,n);if(r&&r.controlsDescendantBindings){if(p!==e)throw Error("Multiple bindings ("+p+" and "+a+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");p=a}}),"function"==typeof o&&m.B(function(){o(t,g(a),_,n.$data,n)},null,{i:t})}catch(e){throw e.message='Unable to process binding "'+a+": "+l[a]+'"\nMessage: '+e.message,e}})}return{shouldBindDescendants:p===e}}function h(e){return e&&e instanceof m.R?e:new m.R(e)}m.d={};var p={script:!0,textarea:!0,template:!0};m.getBindingHandler=function(e){return m.d[e]},m.R=function(t,r,i,n,o){function a(){var e=d?t():t,o=m.a.c(e);return r?(r.Q&&r.Q(),m.a.extend(c,r),c.Q=u):(c.$parents=[],c.$root=o,c.ko=m),c.$rawData=e,c.$data=o,i&&(c[i]=o),n&&n(c,r,o),c.$data}function s(){return l&&!m.a.Tb(l)}var l,u,c=this,d="function"==typeof t&&!m.I(t);o&&o.exportDependencies?a():(u=m.B(a,null,{ya:s,i:!0}),u.ca()&&(c.Q=u,u.equalityComparer=null,l=[],u.Dc=function(t){l.push(t),m.a.G.qa(t,function(t){m.a.Na(l,t),l.length||(u.k(),c.Q=u=e)})}))},m.R.prototype.createChildContext=function(e,t,r,i){return new m.R(e,this,t,function(e,t){e.$parentContext=t,e.$parent=t.$data,e.$parents=(t.$parents||[]).slice(0),e.$parents.unshift(e.$parent),r&&r(e)},i)},m.R.prototype.extend=function(e){return new m.R(this.Q||this.$data,this,null,function(t,r){t.$rawData=r.$rawData,m.a.extend(t,"function"==typeof e?e():e)})},m.R.prototype.ac=function(e,t){return this.createChildContext(e,t,null,{exportDependencies:!0})};var f=m.a.e.J(),g=m.a.e.J();m.xc=function(e,t){if(2!=arguments.length)return m.a.e.get(e,g);m.a.e.set(e,g,t),t.Q&&t.Q.Dc(e)},m.La=function(e,t,r){return 1===e.nodeType&&m.f.oc(e),d(e,t,h(r),!0)},m.Ic=function(e,t,r){return r=h(r),m.La(e,a(t,r,e),r)},m.hb=function(e,t){1!==t.nodeType&&8!==t.nodeType||l(h(e),t,!0)},m.Ub=function(e,r){if(!n&&t.jQuery&&(n=t.jQuery),r&&1!==r.nodeType&&8!==r.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");r=r||t.document.body,u(h(e),r,!0)},m.nb=function(t){switch(t.nodeType){case 1:case 8:var r=m.xc(t);if(r)return r;if(t.parentNode)return m.nb(t.parentNode)}return e},m.Oc=function(t){return(t=m.nb(t))?t.$data:e},m.b("bindingHandlers",m.d),m.b("applyBindings",m.Ub),m.b("applyBindingsToDescendants",m.hb),m.b("applyBindingAccessorsToNode",m.La),m.b("applyBindingsToNode",m.Ic),m.b("contextFor",m.nb),m.b("dataFor",m.Oc)}(),function(e){function t(t,i){var a,s=n.hasOwnProperty(t)?n[t]:e;s?s.Y(i):(s=n[t]=new m.K,s.Y(i),r(t,function(e,r){var i=!(!r||!r.synchronous);o[t]={definition:e,dd:i},delete n[t],a||i?s.notifySubscribers(e):m.Z.Za(function(){s.notifySubscribers(e)})}),a=!0)}function r(e,t){i("getConfig",[e],function(r){r?i("loadComponent",[e,r],function(e){t(e,r)}):t(null,null)})}function i(t,r,n,o){o||(o=m.g.loaders.slice(0));var a=o.shift();if(a){var s=a[t];if(s){var l=!1;if(s.apply(a,r.concat(function(e){l?n(null):null!==e?n(e):i(t,r,n,o)}))!==e&&(l=!0,!a.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.")}else i(t,r,n,o)}else n(null)}var n={},o={};m.g={get:function(r,i){var n=o.hasOwnProperty(r)?o[r]:e;n?n.dd?m.l.w(function(){i(n.definition)}):m.Z.Za(function(){i(n.definition)}):t(r,i)},$b:function(e){delete o[e]},Nb:i},m.g.loaders=[],m.b("components",m.g), +m.b("components.get",m.g.get),m.b("components.clearCachedDefinition",m.g.$b)}(),function(){function e(e,t,r,i){function n(){0==--s&&i(o)}var o={},s=2,l=r.template;r=r.viewModel,l?a(t,l,function(t){m.g.Nb("loadTemplate",[e,t],function(e){o.template=e,n()})}):n(),r?a(t,r,function(t){m.g.Nb("loadViewModel",[e,t],function(e){o[c]=e,n()})}):n()}function i(e,t,r){if("function"==typeof t)r(function(e){return new t(e)});else if("function"==typeof t[c])r(t[c]);else if("instance"in t){var n=t.instance;r(function(){return n})}else"viewModel"in t?i(e,t.viewModel,r):e("Unknown viewModel value: "+t)}function n(e){switch(m.a.A(e)){case"script":return m.a.na(e.text);case"textarea":return m.a.na(e.value);case"template":if(o(e.content))return m.a.wa(e.content.childNodes)}return m.a.wa(e.childNodes)}function o(e){return t.DocumentFragment?e instanceof DocumentFragment:e&&11===e.nodeType}function a(e,r,i){"string"==typeof r.require?s||t.require?(s||t.require)([r.require],i):e("Uses require, but no AMD loader is present"):i(r)}function l(e){return function(t){throw Error("Component '"+e+"': "+t)}}var u={};m.g.register=function(e,t){if(!t)throw Error("Invalid configuration for "+e);if(m.g.wb(e))throw Error("Component "+e+" is already registered");u[e]=t},m.g.wb=function(e){return u.hasOwnProperty(e)},m.g.ud=function(e){delete u[e],m.g.$b(e)},m.g.cc={getConfig:function(e,t){t(u.hasOwnProperty(e)?u[e]:null)},loadComponent:function(t,r,i){var n=l(t);a(n,r,function(r){e(t,n,r,i)})},loadTemplate:function(e,i,a){if(e=l(e),"string"==typeof i)a(m.a.na(i));else if(i instanceof Array)a(i);else if(o(i))a(m.a.W(i.childNodes));else if(i.element)if(i=i.element,t.HTMLElement?i instanceof HTMLElement:i&&i.tagName&&1===i.nodeType)a(n(i));else if("string"==typeof i){var s=r.getElementById(i);s?a(n(s)):e("Cannot find element with ID "+i)}else e("Unknown element type: "+i);else e("Unknown template value: "+i)},loadViewModel:function(e,t,r){i(l(e),t,r)}};var c="createViewModel";m.b("components.register",m.g.register),m.b("components.isRegistered",m.g.wb),m.b("components.unregister",m.g.ud),m.b("components.defaultLoader",m.g.cc),m.g.loaders.push(m.g.cc),m.g.Ec=u}(),function(){function e(e,r){var i=e.getAttribute("params");if(i){var i=t.parseBindingsString(i,r,e,{valueAccessors:!0,bindingParams:!0}),i=m.a.Ea(i,function(t){return m.m(t,null,{i:e})}),n=m.a.Ea(i,function(t){var r=t.p();return t.ca()?m.m({read:function(){return m.a.c(t())},write:m.Da(r)&&function(e){t()(e)},i:e}):r});return n.hasOwnProperty("$raw")||(n.$raw=i),n}return{$raw:{}}}m.g.getComponentNameForNode=function(e){var t=m.a.A(e);if(m.g.wb(t)&&(-1!=t.indexOf("-")||"[object HTMLUnknownElement]"==""+e||8>=m.a.C&&e.tagName===t))return t},m.g.Rb=function(t,r,i,n){if(1===r.nodeType){var o=m.g.getComponentNameForNode(r);if(o){if(t=t||{},t.component)throw Error('Cannot use the "component" binding on a custom element matching a component');var a={name:o,params:e(r,i)};t.component=n?function(){return a}:a}}return t};var t=new m.S;9>m.a.C&&(m.g.register=function(e){return function(t){return r.createElement(t),e.apply(this,arguments)}}(m.g.register),r.createDocumentFragment=function(e){return function(){var t,r=e(),i=m.g.Ec;for(t in i)i.hasOwnProperty(t)&&r.createElement(t);return r}}(r.createDocumentFragment))}(),function(e){function t(e,t,r){if(!(t=t.template))throw Error("Component '"+e+"' has no template");e=m.a.wa(t),m.f.fa(r,e)}function r(e,t,r,i){var n=e.createViewModel;return n?n.call(e,i,{element:t,templateNodes:r}):i}var i=0;m.d.component={init:function(e,n,o,a,s){function l(){var e=u&&u.dispose;"function"==typeof e&&e.call(u),c=u=null}var u,c,d=m.a.W(m.f.childNodes(e));return m.a.G.qa(e,l),m.m(function(){var o,a,h=m.a.c(n());if("string"==typeof h?o=h:(o=m.a.c(h.name),a=m.a.c(h.params)),!o)throw Error("No component name specified");var p=c=++i;m.g.get(o,function(i){if(c===p){if(l(),!i)throw Error("Unknown component '"+o+"'");t(o,i,e);var n=r(i,e,d,a);i=s.createChildContext(n,void 0,function(e){e.$component=n,e.$componentTemplateNodes=d}),u=n,m.hb(i,e)}})},null,{i:e}),{controlsDescendantBindings:!0}}},m.f.aa.component=!0}();var x={class:"className",for:"htmlFor"};m.d.attr={update:function(t,r){var i=m.a.c(r())||{};m.a.D(i,function(r,i){i=m.a.c(i);var n=!1===i||null===i||i===e;n&&t.removeAttribute(r),8>=m.a.C&&r in x?(r=x[r],n?t.removeAttribute(r):t[r]=i):n||t.setAttribute(r,i.toString()),"name"===r&&m.a.vc(t,n?"":i.toString())})}},function(){m.d.checked={after:["value","attr"],init:function(t,r,i){function n(){var e=t.checked,n=p?a():e;if(!m.xa.Va()&&(!l||e)){var o=m.l.w(r);if(c){var s=d?o.p():o;h!==n?(e&&(m.a.ra(s,n,!0),m.a.ra(s,h,!1)),h=n):m.a.ra(s,n,e),d&&m.Da(o)&&o(s)}else m.h.Ga(o,i,"checked",n,!0)}}function o(){var e=m.a.c(r());t.checked=c?0<=m.a.o(e,a()):s?e:a()===e}var a=m.rc(function(){return i.has("checkedValue")?m.a.c(i.get("checkedValue")):i.has("value")?m.a.c(i.get("value")):t.value}),s="checkbox"==t.type,l="radio"==t.type;if(s||l){var u=r(),c=s&&m.a.c(u)instanceof Array,d=!(c&&u.push&&u.splice),h=c?a():e,p=l||c;l&&!t.name&&m.d.uniqueName.init(t,function(){return!0}),m.m(n,null,{i:t}),m.a.q(t,"click",n),m.m(o,null,{i:t}),u=e}}},m.h.ga.checked=!0,m.d.checkedValue={update:function(e,t){e.value=m.a.c(t())}}}(),m.d.css={update:function(e,t){var r=m.a.c(t());null!==r&&"object"==typeof r?m.a.D(r,function(t,r){r=m.a.c(r),m.a.fb(e,t,r)}):(r=m.a.cb(String(r||"")),m.a.fb(e,e.__ko__cssValue,!1),e.__ko__cssValue=r,m.a.fb(e,r,!0))}},m.d.enable={update:function(e,t){var r=m.a.c(t());r&&e.disabled?e.removeAttribute("disabled"):r||e.disabled||(e.disabled=!0)}},m.d.disable={update:function(e,t){m.d.enable.update(e,function(){return!m.a.c(t())})}},m.d.event={init:function(e,t,r,i,n){var o=t()||{};m.a.D(o,function(o){"string"==typeof o&&m.a.q(e,o,function(e){var a,s=t()[o];if(s){try{var l=m.a.W(arguments);i=n.$data,l.unshift(i),a=s.apply(i,l)}finally{!0!==a&&(e.preventDefault?e.preventDefault():e.returnValue=!1)}!1===r.get(o+"Bubble")&&(e.cancelBubble=!0,e.stopPropagation&&e.stopPropagation())}})})}},m.d.foreach={mc:function(e){return function(){var t=e(),r=m.a.Bb(t);return r&&"number"!=typeof r.length?(m.a.c(t),{foreach:r.data,as:r.as,includeDestroyed:r.includeDestroyed,afterAdd:r.afterAdd,beforeRemove:r.beforeRemove,afterRender:r.afterRender,beforeMove:r.beforeMove,afterMove:r.afterMove,templateEngine:m.X.vb}):{foreach:t,templateEngine:m.X.vb}}},init:function(e,t){return m.d.template.init(e,m.d.foreach.mc(t))},update:function(e,t,r,i,n){return m.d.template.update(e,m.d.foreach.mc(t),r,i,n)}},m.h.va.foreach=!1,m.f.aa.foreach=!0,m.d.hasfocus={init:function(e,t,r){function i(i){e.__ko_hasfocusUpdating=!0;var n=e.ownerDocument;if("activeElement"in n){var o;try{o=n.activeElement}catch(e){o=n.body}i=o===e}n=t(),m.h.Ga(n,r,"hasfocus",i,!0),e.__ko_hasfocusLastValue=i,e.__ko_hasfocusUpdating=!1}var n=i.bind(null,!0),o=i.bind(null,!1);m.a.q(e,"focus",n),m.a.q(e,"focusin",n),m.a.q(e,"blur",o),m.a.q(e,"focusout",o)},update:function(e,t){var r=!!m.a.c(t());e.__ko_hasfocusUpdating||e.__ko_hasfocusLastValue===r||(r?e.focus():e.blur(),!r&&e.__ko_hasfocusLastValue&&e.ownerDocument.body.focus(),m.l.w(m.a.Fa,null,[e,r?"focusin":"focusout"]))}},m.h.ga.hasfocus=!0,m.d.hasFocus=m.d.hasfocus,m.h.ga.hasFocus=!0,m.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(e,t){m.a.Eb(e,t())}},f("if"),f("ifnot",!1,!0),f("with",!0,!1,function(e,t){return e.ac(t)});var P={};m.d.options={init:function(e){if("select"!==m.a.A(e))throw Error("options binding applies only to SELECT elements");for(;0<e.length;)e.remove(0);return{controlsDescendantBindings:!0}},update:function(t,r,i){function n(){return m.a.Ma(t.options,function(e){return e.selected})}function o(e,t,r){var i=typeof t;return"function"==i?t(e):"string"==i?e[t]:r}function a(e,r){if(f&&c)m.j.ja(t,m.a.c(i.get("value")),!0);else if(p.length){var n=0<=m.a.o(p,m.j.u(r[0]));m.a.wc(r[0],n),f&&!n&&m.l.w(m.a.Fa,null,[t,"change"])}}var s=t.multiple,l=0!=t.length&&s?t.scrollTop:null,u=m.a.c(r()),c=i.get("valueAllowUnset")&&i.has("value"),d=i.get("optionsIncludeDestroyed");r={};var h,p=[];c||(s?p=m.a.ib(n(),m.j.u):0<=t.selectedIndex&&p.push(m.j.u(t.options[t.selectedIndex]))),u&&(void 0===u.length&&(u=[u]),h=m.a.Ma(u,function(t){return d||t===e||null===t||!m.a.c(t._destroy)}),i.has("optionsCaption")&&null!==(u=m.a.c(i.get("optionsCaption")))&&u!==e&&h.unshift(P));var f=!1;r.beforeRemove=function(e){t.removeChild(e)},u=a,i.has("optionsAfterRender")&&"function"==typeof i.get("optionsAfterRender")&&(u=function(t,r){a(0,r),m.l.w(i.get("optionsAfterRender"),null,[r[0],t!==P?t:e])}),m.a.Db(t,h,function(r,n,a){return a.length&&(p=!c&&a[0].selected?[m.j.u(a[0])]:[],f=!0),n=t.ownerDocument.createElement("option"),r===P?(m.a.bb(n,i.get("optionsCaption")),m.j.ja(n,e)):(a=o(r,i.get("optionsValue"),r),m.j.ja(n,m.a.c(a)),r=o(r,i.get("optionsText"),a),m.a.bb(n,r)),[n]},r,u),m.l.w(function(){c?m.j.ja(t,m.a.c(i.get("value")),!0):(s?p.length&&n().length<p.length:p.length&&0<=t.selectedIndex?m.j.u(t.options[t.selectedIndex])!==p[0]:p.length||0<=t.selectedIndex)&&m.a.Fa(t,"change")}),m.a.Sc(t),l&&20<Math.abs(l-t.scrollTop)&&(t.scrollTop=l)}},m.d.options.zb=m.a.e.J(),m.d.selectedOptions={after:["options","foreach"],init:function(e,t,r){m.a.q(e,"change",function(){var i=t(),n=[];m.a.r(e.getElementsByTagName("option"),function(e){e.selected&&n.push(m.j.u(e))}),m.h.Ga(i,r,"selectedOptions",n)})},update:function(e,t){if("select"!=m.a.A(e))throw Error("values binding applies only to SELECT elements");var r=m.a.c(t()),i=e.scrollTop;r&&"number"==typeof r.length&&m.a.r(e.getElementsByTagName("option"),function(e){var t=0<=m.a.o(r,m.j.u(e));e.selected!=t&&m.a.wc(e,t)}),e.scrollTop=i}},m.h.ga.selectedOptions=!0,m.d.style={update:function(t,r){var i=m.a.c(r()||{});m.a.D(i,function(r,i){i=m.a.c(i),null!==i&&i!==e&&!1!==i||(i=""),t.style[r]=i})}},m.d.submit={init:function(e,t,r,i,n){if("function"!=typeof t())throw Error("The value for a submit binding must be a function");m.a.q(e,"submit",function(r){var i,o=t();try{i=o.call(n.$data,e)}finally{!0!==i&&(r.preventDefault?r.preventDefault():r.returnValue=!1)}})}},m.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(e,t){m.a.bb(e,t())}},m.f.aa.text=!0,function(){if(t&&t.navigator)var r=function(e){if(e)return parseFloat(e[1])},i=t.opera&&t.opera.version&&parseInt(t.opera.version()),n=t.navigator.userAgent,o=r(n.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),a=r(n.match(/Firefox\/([^ ]*)/));if(10>m.a.C)var s=m.a.e.J(),l=m.a.e.J(),u=function(e){var t=this.activeElement;(t=t&&m.a.e.get(t,l))&&t(e)},c=function(e,t){var r=e.ownerDocument;m.a.e.get(r,s)||(m.a.e.set(r,s,!0),m.a.q(r,"selectionchange",u)),m.a.e.set(e,l,t)};m.d.textInput={init:function(t,r,n){function s(e,r){m.a.q(t,e,r)}function l(){var i=m.a.c(r());null!==i&&i!==e||(i=""),p!==e&&i===p?m.a.setTimeout(l,4):t.value!==i&&(f=i,t.value=i)}function u(){h||(p=t.value,h=m.a.setTimeout(d,4))}function d(){clearTimeout(h),p=h=e;var i=t.value;f!==i&&(f=i,m.h.Ga(r(),n,"textInput",i))}var h,p,f=t.value,g=9==m.a.C?u:d;10>m.a.C?(s("propertychange",function(e){"value"===e.propertyName&&g(e)}),8==m.a.C&&(s("keyup",d),s("keydown",d)),8<=m.a.C&&(c(t,g),s("dragend",u))):(s("input",d),5>o&&"textarea"===m.a.A(t)?(s("keydown",u),s("paste",u),s("cut",u)):11>i?s("keydown",u):4>a&&(s("DOMAutoComplete",d),s("dragdrop",d),s("drop",d))),s("change",d),m.m(l,null,{i:t})}},m.h.ga.textInput=!0,m.d.textinput={preprocess:function(e,t,r){r("textInput",e)}}}(),m.d.uniqueName={init:function(e,t){if(t()){var r="ko_unique_"+ ++m.d.uniqueName.Nc;m.a.vc(e,r)}}},m.d.uniqueName.Nc=0,m.d.value={after:["options","foreach"],init:function(e,t,r){if("input"!=e.tagName.toLowerCase()||"checkbox"!=e.type&&"radio"!=e.type){var i=["change"],n=r.get("valueUpdate"),o=!1,a=null;n&&("string"==typeof n&&(n=[n]),m.a.ta(i,n),i=m.a.Wb(i));var s=function(){a=null,o=!1;var i=t(),n=m.j.u(e);m.h.Ga(i,r,"value",n)};!m.a.C||"input"!=e.tagName.toLowerCase()||"text"!=e.type||"off"==e.autocomplete||e.form&&"off"==e.form.autocomplete||-1!=m.a.o(i,"propertychange")||(m.a.q(e,"propertychange",function(){o=!0}),m.a.q(e,"focus",function(){o=!1}),m.a.q(e,"blur",function(){o&&s()})),m.a.r(i,function(t){var r=s;m.a.sd(t,"after")&&(r=function(){a=m.j.u(e),m.a.setTimeout(s,0)},t=t.substring(5)),m.a.q(e,t,r)});var l=function(){var i=m.a.c(t()),n=m.j.u(e);if(null!==a&&i===a)m.a.setTimeout(l,0);else if(i!==n)if("select"===m.a.A(e)){var o=r.get("valueAllowUnset"),n=function(){m.j.ja(e,i,o)};n(),o||i===m.j.u(e)?m.a.setTimeout(n,0):m.l.w(m.a.Fa,null,[e,"change"])}else m.j.ja(e,i)};m.m(l,null,{i:e})}else m.La(e,{checkedValue:t})},update:function(){}},m.h.ga.value=!0,m.d.visible={update:function(e,t){var r=m.a.c(t()),i="none"!=e.style.display;r&&!i?e.style.display="":!r&&i&&(e.style.display="none")}},function(e){m.d[e]={init:function(t,r,i,n,o){return m.d.event.init.call(this,t,function(){var t={};return t[e]=r(),t},i,n,o)}}}("click"),m.P=function(){},m.P.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource")},m.P.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock")},m.P.prototype.makeTemplateSource=function(e,t){if("string"==typeof e){t=t||r;var i=t.getElementById(e);if(!i)throw Error("Cannot find template with ID "+e);return new m.v.n(i)}if(1==e.nodeType||8==e.nodeType)return new m.v.sa(e);throw Error("Unknown template type: "+e)},m.P.prototype.renderTemplate=function(e,t,r,i){return e=this.makeTemplateSource(e,i),this.renderTemplateSource(e,t,r,i)},m.P.prototype.isTemplateRewritten=function(e,t){return!1===this.allowTemplateRewriting||this.makeTemplateSource(e,t).data("isRewritten")},m.P.prototype.rewriteTemplate=function(e,t,r){e=this.makeTemplateSource(e,r),t=t(e.text()),e.text(t),e.data("isRewritten",!0)},m.b("templateEngine",m.P),m.Ib=function(){function e(e,t,r,i){e=m.h.Ab(e);for(var n=m.h.va,o=0;o<e.length;o++){var a=e[o].key;if(n.hasOwnProperty(a)){var s=n[a];if("function"==typeof s){if(a=s(e[o].value))throw Error(a)}else if(!s)throw Error("This template engine does not support the '"+a+"' binding within its templates")}}return r="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+m.h.Xa(e,{valueAccessors:!0})+" } })()},'"+r.toLowerCase()+"')",i.createJavaScriptEvaluatorBlock(r)+t}var t=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'|[^>]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,r=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Tc:function(e,t,r){t.isTemplateRewritten(e,r)||t.rewriteTemplate(e,function(e){return m.Ib.jd(e,t)},r)},jd:function(i,n){return i.replace(t,function(t,r,i,o,a){return e(a,r,i,n)}).replace(r,function(t,r){return e(r,"\x3c!-- ko --\x3e","#comment",n)})},Jc:function(e,t){return m.N.yb(function(r,i){var n=r.nextSibling;n&&n.nodeName.toLowerCase()===t&&m.La(n,e,i)})}}}(),m.b("__tr_ambtns",m.Ib.Jc),function(){m.v={},m.v.n=function(e){if(this.n=e){var t=m.a.A(e);this.eb="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},m.v.n.prototype.text=function(){var e=1===this.eb?"text":2===this.eb?"value":"innerHTML";if(0==arguments.length)return this.n[e];var t=arguments[0];"innerHTML"===e?m.a.Eb(this.n,t):this.n[e]=t};var t=m.a.e.J()+"_";m.v.n.prototype.data=function(e){if(1===arguments.length)return m.a.e.get(this.n,t+e);m.a.e.set(this.n,t+e,arguments[1])};var r=m.a.e.J();m.v.n.prototype.nodes=function(){var t=this.n;if(0==arguments.length)return(m.a.e.get(t,r)||{}).mb||(3===this.eb?t.content:4===this.eb?t:e);m.a.e.set(t,r,{mb:arguments[0]})},m.v.sa=function(e){this.n=e},m.v.sa.prototype=new m.v.n,m.v.sa.prototype.text=function(){if(0==arguments.length){var t=m.a.e.get(this.n,r)||{};return t.Jb===e&&t.mb&&(t.Jb=t.mb.innerHTML),t.Jb}m.a.e.set(this.n,r,{Jb:arguments[0]})},m.b("templateSources",m.v),m.b("templateSources.domElement",m.v.n),m.b("templateSources.anonymousTemplate",m.v.sa)}(),function(){function t(e,t,r){var i;for(t=m.f.nextSibling(t);e&&(i=e)!==t;)e=m.f.nextSibling(i),r(i,e)}function r(e,r){if(e.length){var i=e[0],n=e[e.length-1],o=i.parentNode,a=m.S.instance,s=a.preprocessNode;if(s){if(t(i,n,function(e,t){var r=e.previousSibling,o=s.call(a,e);o&&(e===i&&(i=o[0]||t),e===n&&(n=o[o.length-1]||r))}),e.length=0,!i)return;i===n?e.push(i):(e.push(i,n),m.a.Ba(e,o))}t(i,n,function(e){1!==e.nodeType&&8!==e.nodeType||m.Ub(r,e)}),t(i,n,function(e){1!==e.nodeType&&8!==e.nodeType||m.N.Cc(e,[r])}),m.a.Ba(e,o)}}function i(e){return e.nodeType?e:0<e.length?e[0]:null}function n(e,t,n,o,s){s=s||{};var l=(e&&i(e)||n||{}).ownerDocument,u=s.templateEngine||a;if(m.Ib.Tc(n,u,l),n=u.renderTemplate(n,o,s,l),"number"!=typeof n.length||0<n.length&&"number"!=typeof n[0].nodeType)throw Error("Template engine must return an array of DOM nodes");switch(l=!1,t){case"replaceChildren":m.f.fa(e,n),l=!0;break;case"replaceNode":m.a.uc(e,n),l=!0;break;case"ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+t)}return l&&(r(n,o),s.afterRender&&m.l.w(s.afterRender,null,[n,o.$data])),n}function o(e,t,r){return m.I(e)?e():"function"==typeof e?e(t,r):e}var a;m.Fb=function(t){if(t!=e&&!(t instanceof m.P))throw Error("templateEngine must inherit from ko.templateEngine");a=t},m.Cb=function(t,r,s,l,u){if(s=s||{},(s.templateEngine||a)==e)throw Error("Set a template engine before calling renderTemplate");if(u=u||"replaceChildren",l){var c=i(l);return m.B(function(){var e=r&&r instanceof m.R?r:new m.R(r,null,null,null,{exportDependencies:!0}),a=o(t,e.$data,e),e=n(l,u,a,e,s);"replaceNode"==u&&(l=e,c=i(l))},null,{ya:function(){return!c||!m.a.qb(c)},i:c&&"replaceNode"==u?c.parentNode:c})}return m.N.yb(function(e){m.Cb(t,r,s,e,"replaceNode")})},m.pd=function(t,i,a,s,l){function u(e,t){r(t,d),a.afterRender&&a.afterRender(t,e),d=null}function c(e,r){return d=l.createChildContext(e,a.as,function(e){e.$index=r}),n(null,"ignoreTargetNode",o(t,e,d),d,a)}var d;return m.B(function(){var t=m.a.c(i)||[];void 0===t.length&&(t=[t]),t=m.a.Ma(t,function(t){return a.includeDestroyed||t===e||null===t||!m.a.c(t._destroy)}),m.l.w(m.a.Db,null,[s,t,c,a,u])},null,{i:s})};var s=m.a.e.J();m.d.template={init:function(e,t){var r=m.a.c(t());if("string"==typeof r||r.name)m.f.za(e);else{if("nodes"in r){if(r=r.nodes||[],m.I(r))throw Error('The "nodes" option must be a plain, non-observable array.')}else r=m.f.childNodes(e);r=m.a.nc(r),new m.v.sa(e).nodes(r)}return{controlsDescendantBindings:!0}},update:function(t,r,i,n,o){var a=r();r=m.a.c(a),i=!0,n=null,"string"==typeof r?r={}:(a=r.name,"if"in r&&(i=m.a.c(r.if)),i&&"ifnot"in r&&(i=!m.a.c(r.ifnot))),"foreach"in r?n=m.pd(a||t,i&&r.foreach||[],r,t,o):i?(o="data"in r?o.ac(r.data,r.as):o,n=m.Cb(a||t,o,r,t)):m.f.za(t),o=n,(r=m.a.e.get(t,s))&&"function"==typeof r.k&&r.k(),m.a.e.set(t,s,o&&o.ca()?o:e)}},m.h.va.template=function(e){return e=m.h.Ab(e),1==e.length&&e[0].unknown||m.h.fd(e,"name")?null:"This template engine does not support anonymous templates nested within its templates"},m.f.aa.template=!0}(),m.b("setTemplateEngine",m.Fb),m.b("renderTemplate",m.Cb),m.a.hc=function(e,t,r){if(e.length&&t.length){var i,n,o,a,s;for(i=n=0;(!r||i<r)&&(a=e[n]);++n){for(o=0;s=t[o];++o)if(a.value===s.value){a.moved=s.index,s.moved=a.index,t.splice(o,1),i=o=0;break}i+=o}}},m.a.lb=function(){function e(e,t,r,i,n){var o,a,s,l,u,c=Math.min,d=Math.max,h=[],p=e.length,f=t.length,g=f-p||1,_=p+f+1;for(o=0;o<=p;o++)for(l=s,h.push(s=[]),u=c(f,o+g),a=d(0,o-1);a<=u;a++)s[a]=a?o?e[o-1]===t[a-1]?l[a-1]:c(l[a]||_,s[a-1]||_)+1:a+1:o+1;for(c=[],d=[],g=[],o=p,a=f;o||a;)f=h[o][a]-1,a&&f===h[o][a-1]?d.push(c[c.length]={status:r,value:t[--a],index:a}):o&&f===h[o-1][a]?g.push(c[c.length]={status:i,value:e[--o],index:o}):(--a,--o,n.sparse||c.push({status:"retained",value:t[a]}));return m.a.hc(g,d,!n.dontLimitMoves&&10*p),c.reverse()}return function(t,r,i){return i="boolean"==typeof i?{dontLimitMoves:i}:i||{},t=t||[],r=r||[],t.length<r.length?e(t,r,"added","deleted",i):e(r,t,"deleted","added",i)}}(),m.b("utils.compareArrays",m.a.lb),function(){function t(t,r,i,n,o){var a=[],s=m.B(function(){var e=r(i,o,m.a.Ba(a,t))||[];0<a.length&&(m.a.uc(a,e),n&&m.l.w(n,null,[i,e,o])),a.length=0,m.a.ta(a,e)},null,{i:t,ya:function(){return!m.a.Tb(a)}});return{ea:a,B:s.ca()?s:e}}var r=m.a.e.J(),i=m.a.e.J();m.a.Db=function(n,o,a,s,l){function u(e,t){C=h[t],v!==t&&(T[e]=C),C.tb(v++),m.a.Ba(C.ea,n),g.push(C),b.push(C)}function c(e,t){if(e)for(var r=0,i=t.length;r<i;r++)t[r]&&m.a.r(t[r].ea,function(i){e(i,r,t[r].ka)})}o=o||[],s=s||{};var d=m.a.e.get(n,r)===e,h=m.a.e.get(n,r)||[],p=m.a.ib(h,function(e){return e.ka}),f=m.a.lb(p,o,s.dontLimitMoves),g=[],_=0,v=0,y=[],b=[];o=[];for(var C,S,w,T=[],p=[],E=0;S=f[E];E++)switch(w=S.moved,S.status){case"deleted":w===e&&(C=h[_],C.B&&(C.B.k(),C.B=e),m.a.Ba(C.ea,n).length&&(s.beforeRemove&&(g.push(C),b.push(C),C.ka===i?C=null:o[E]=C),C&&y.push.apply(y,C.ea))),_++;break;case"retained":u(E,_++);break;case"added":w!==e?u(E,w):(C={ka:S.value,tb:m.O(v++)},g.push(C),b.push(C),d||(p[E]=C))}m.a.e.set(n,r,g),c(s.beforeMove,T),m.a.r(y,s.beforeRemove?m.ba:m.removeNode);for(var A,E=0,d=m.f.firstChild(n);C=b[E];E++){for(C.ea||m.a.extend(C,t(n,a,C.ka,l,C.tb)),_=0;f=C.ea[_];d=f.nextSibling,A=f,_++)f!==d&&m.f.kc(n,f,A);!C.ad&&l&&(l(C.ka,C.ea,C.tb),C.ad=!0)}for(c(s.beforeRemove,o),E=0;E<o.length;++E)o[E]&&(o[E].ka=i);c(s.afterMove,T),c(s.afterAdd,p)}}(),m.b("utils.setDomNodeChildrenFromArrayMapping",m.a.Db),m.X=function(){this.allowTemplateRewriting=!1},m.X.prototype=new m.P,m.X.prototype.renderTemplateSource=function(e,t,r,i){return(t=(9>m.a.C?0:e.nodes)?e.nodes():null)?m.a.W(t.cloneNode(!0).childNodes):(e=e.text(),m.a.na(e,i))},m.X.vb=new m.X,m.Fb(m.X.vb),m.b("nativeTemplateEngine",m.X),function(){m.xb=function(){var e=this.ed=function(){if(!n||!n.tmpl)return 0;try{if(0<=n.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(e){}return 1}();this.renderTemplateSource=function(t,i,o,a){if(a=a||r,o=o||{},2>e)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var s=t.data("precompiled");return s||(s=t.text()||"",s=n.template(null,"{{ko_with $item.koBindingContext}}"+s+"{{/ko_with}}"),t.data("precompiled",s)),t=[i.$data],i=n.extend({koBindingContext:i},o.templateOptions),i=n.tmpl(s,t,i),i.appendTo(a.createElement("div")),n.fragments={},i},this.createJavaScriptEvaluatorBlock=function(e){return"{{ko_code ((function() { return "+e+" })()) }}"},this.addTemplate=function(e,t){r.write("<script type='text/html' id='"+e+"'>"+t+"<\/script>")},0<e&&(n.tmpl.tag.ko_code={open:"__.push($1 || '');"},n.tmpl.tag.ko_with={open:"with($1) {",close:"} "})},m.xb.prototype=new m.P;var e=new m.xb;0<e.ed&&m.Fb(e),m.b("jqueryTmplTemplateEngine",m.xb)}()})}()}(),define("ThirdParty/knockout-es5",[],function(){"use strict";function e(e,r){if(!e)throw new Error("When calling ko.track, you must pass an object as the first parameter.");var n=this,o=t(e,!0);return r=r||Object.getOwnPropertyNames(e),r.forEach(function(t){if(t!==d&&t!==h&&!(t in o)){var r=e[t],a=r instanceof Array,s=n.isObservable(r)?r:a?n.observableArray(r):n.observable(r);Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:s,set:n.isWriteableObservable(s)?s:void 0}),o[t]=s,a&&i(n,s)}}),e}function t(e,t){var r=e[d];return!r&&t&&(r={},Object.defineProperty(e,d,{value:r})),r}function r(t,r,i){var n=this,o={owner:t,deferEvaluation:!0};if("function"==typeof i)o.read=i;else{if("value"in i)throw new Error('For ko.defineProperty, you must not specify a "value" for the property. You must provide a "get" function.');if("function"!=typeof i.get)throw new Error('For ko.defineProperty, the third parameter must be either an evaluator function, or an options object containing a function called "get".');o.read=i.get,o.write=i.set}return t[r]=n.computed(o),e.call(n,t,[r]),t}function i(e,t){var r=null;e.computed(function(){r&&(r.dispose(),r=null);var i=t();i instanceof Array&&(r=n(e,t,i))})}function n(e,t,r){return o(e,r).subscribe(t)}function o(e,t){var r=t[h];if(!r){r=new e.subscribable,Object.defineProperty(t,h,{value:r});var i={};a(t,r,i),s(e,t,r,i)}return r}function a(e,t,r){["pop","push","reverse","shift","sort","splice","unshift"].forEach(function(i){var n=e[i];e[i]=function(){var e=n.apply(this,arguments);return!0!==r.pause&&t.notifySubscribers(this),e}})}function s(e,t,r,i){["remove","removeAll","destroy","destroyAll","replace"].forEach(function(n){Object.defineProperty(t,n,{enumerable:!1,value:function(){var o;i.pause=!0;try{o=e.observableArray.fn[n].apply(e.observableArray(t),arguments)}finally{i.pause=!1}return r.notifySubscribers(t),o}})})}function l(e,r){if(!e)return null;var i=t(e,!1);return i&&i[r]||null}function u(e,t){var r=l(e,t);r&&r.valueHasMutated()}function c(t){t.track=e,t.getObservable=l,t.valueHasMutated=u,t.defineProperty=r}var d="__knockoutObservables",h="__knockoutSubscribable";return{attachToKo:c}}),define("Widgets/SvgPathBindingHandler",[],function(){"use strict";var e="http://www.w3.org/2000/svg";return{register:function(t){t.bindingHandlers.cesiumSvgPath={init:function(r,i){var n=document.createElementNS(e,"svg:svg");n.setAttribute("class","cesium-svgPath-svg");var o=document.createElementNS(e,"path");return n.appendChild(o),t.virtualElements.setDomNodeChildren(r,[n]),t.computed({read:function(){var e=t.unwrap(i());o.setAttribute("d",t.unwrap(e.path));var r=t.unwrap(e.width),a=t.unwrap(e.height);n.setAttribute("width",r),n.setAttribute("height",a),n.setAttribute("viewBox","0 0 "+r+" "+a),e.css&&n.setAttribute("class","cesium-svgPath-svg "+t.unwrap(e.css))},disposeWhenNodeIsRemoved:r}),{controlsDescendantBindings:!0}}},t.virtualElements.allowedBindings.cesiumSvgPath=!0}}}),define("ThirdParty/knockout",["./knockout-3.4.2","./knockout-es5","../Widgets/SvgPathBindingHandler"],function(e,t,r){"use strict";return t.attachToKo(e),r.register(e),e}),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("ThirdParty/NoSleep",[],t):"object"==typeof exports?exports.NoSleep=t():e.NoSleep=t()}(this,function(){return function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,i){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var n=function(){function e(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,r,i){return r&&e(t.prototype,r),i&&e(t,i),t}}(),o=r(1),a="undefined"!=typeof navigator&&parseFloat((""+(/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))<10&&!window.MSStream,s=function(){function e(){i(this,e),a?this.noSleepTimer=null:(this.noSleepVideo=document.createElement("video"),this.noSleepVideo.setAttribute("playsinline",""),this.noSleepVideo.setAttribute("src",o),this.noSleepVideo.addEventListener("timeupdate",function(e){this.noSleepVideo.currentTime>.5&&(this.noSleepVideo.currentTime=Math.random())}.bind(this)))}return n(e,[{key:"enable",value:function(){a?(this.disable(),this.noSleepTimer=window.setInterval(function(){window.location.href="/",window.setTimeout(window.stop,0)},15e3)):this.noSleepVideo.play()}},{key:"disable",value:function(){a?this.noSleepTimer&&(window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause()}}]),e}();e.exports=s},function(e,t,r){"use strict" +;e.exports="data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA="}])}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("ThirdParty/pako_inflate",[],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pako=e()}}(function(){return function e(t,r,i){function n(a,s){if(!r[a]){if(!t[a]){var l="function"==typeof require&&require;if(!s&&l)return l(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[a]={exports:{}};t[a][0].call(c.exports,function(e){var r=t[a][1][e];return n(r||e)},c,c.exports,e,t,r,i)}return r[a].exports}for(var o="function"==typeof require&&require,a=0;a<i.length;a++)n(i[a]);return n}({1:[function(e,t,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;r.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)r.hasOwnProperty(i)&&(e[i]=r[i])}}return e},r.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var n={arraySet:function(e,t,r,i,n){if(t.subarray&&e.subarray)return void e.set(t.subarray(r,r+i),n);for(var o=0;o<i;o++)e[n+o]=t[r+o]},flattenChunks:function(e){var t,r,i,n,o,a;for(i=0,t=0,r=e.length;t<r;t++)i+=e[t].length;for(a=new Uint8Array(i),n=0,t=0,r=e.length;t<r;t++)o=e[t],a.set(o,n),n+=o.length;return a}},o={arraySet:function(e,t,r,i,n){for(var o=0;o<i;o++)e[n+o]=t[r+o]},flattenChunks:function(e){return[].concat.apply([],e)}};r.setTyped=function(e){e?(r.Buf8=Uint8Array,r.Buf16=Uint16Array,r.Buf32=Int32Array,r.assign(r,n)):(r.Buf8=Array,r.Buf16=Array,r.Buf32=Array,r.assign(r,o))},r.setTyped(i)},{}],2:[function(e,t,r){"use strict";function i(e,t){if(t<65537&&(e.subarray&&a||!e.subarray&&o))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var r="",i=0;i<t;i++)r+=String.fromCharCode(e[i]);return r}var n=e("./common"),o=!0,a=!0;try{String.fromCharCode.apply(null,[0])}catch(e){o=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(e){a=!1}for(var s=new n.Buf8(256),l=0;l<256;l++)s[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;s[254]=s[254]=1,r.string2buf=function(e){var t,r,i,o,a,s=e.length,l=0;for(o=0;o<s;o++)r=e.charCodeAt(o),55296==(64512&r)&&o+1<s&&56320==(64512&(i=e.charCodeAt(o+1)))&&(r=65536+(r-55296<<10)+(i-56320),o++),l+=r<128?1:r<2048?2:r<65536?3:4;for(t=new n.Buf8(l),a=0,o=0;a<l;o++)r=e.charCodeAt(o),55296==(64512&r)&&o+1<s&&56320==(64512&(i=e.charCodeAt(o+1)))&&(r=65536+(r-55296<<10)+(i-56320),o++),r<128?t[a++]=r:r<2048?(t[a++]=192|r>>>6,t[a++]=128|63&r):r<65536?(t[a++]=224|r>>>12,t[a++]=128|r>>>6&63,t[a++]=128|63&r):(t[a++]=240|r>>>18,t[a++]=128|r>>>12&63,t[a++]=128|r>>>6&63,t[a++]=128|63&r);return t},r.buf2binstring=function(e){return i(e,e.length)},r.binstring2buf=function(e){for(var t=new n.Buf8(e.length),r=0,i=t.length;r<i;r++)t[r]=e.charCodeAt(r);return t},r.buf2string=function(e,t){var r,n,o,a,l=t||e.length,u=new Array(2*l);for(n=0,r=0;r<l;)if((o=e[r++])<128)u[n++]=o;else if((a=s[o])>4)u[n++]=65533,r+=a-1;else{for(o&=2===a?31:3===a?15:7;a>1&&r<l;)o=o<<6|63&e[r++],a--;a>1?u[n++]=65533:o<65536?u[n++]=o:(o-=65536,u[n++]=55296|o>>10&1023,u[n++]=56320|1023&o)}return i(u,n)},r.utf8border=function(e,t){var r;for(t=t||e.length,t>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+s[e[r]]>t?r:t}},{"./common":1}],3:[function(e,t,r){"use strict";function i(e,t,r,i){for(var n=65535&e|0,o=e>>>16&65535|0,a=0;0!==r;){a=r>2e3?2e3:r,r-=a;do{n=n+t[i++]|0,o=o+n|0}while(--a);n%=65521,o%=65521}return n|o<<16|0}t.exports=i},{}],4:[function(e,t,r){"use strict";t.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(e,t,r){"use strict";function i(e,t,r,i){var o=n,a=i+r;e^=-1;for(var s=i;s<a;s++)e=e>>>8^o[255&(e^t[s])];return-1^e}var n=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var i=0;i<8;i++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=i},{}],6:[function(e,t,r){"use strict";function i(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}t.exports=i},{}],7:[function(e,t,r){"use strict";t.exports=function(e,t){var r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A;r=e.state,i=e.next_in,E=e.input,n=i+(e.avail_in-5),o=e.next_out,A=e.output,a=o-(t-e.avail_out),s=o+(e.avail_out-257),l=r.dmax,u=r.wsize,c=r.whave,d=r.wnext,h=r.window,p=r.hold,f=r.bits,m=r.lencode,g=r.distcode,_=(1<<r.lenbits)-1,v=(1<<r.distbits)-1;e:do{f<15&&(p+=E[i++]<<f,f+=8,p+=E[i++]<<f,f+=8),y=m[p&_];t:for(;;){if(b=y>>>24,p>>>=b,f-=b,0===(b=y>>>16&255))A[o++]=65535&y;else{if(!(16&b)){if(0==(64&b)){y=m[(65535&y)+(p&(1<<b)-1)];continue t}if(32&b){r.mode=12;break e}e.msg="invalid literal/length code",r.mode=30;break e}C=65535&y,b&=15,b&&(f<b&&(p+=E[i++]<<f,f+=8),C+=p&(1<<b)-1,p>>>=b,f-=b),f<15&&(p+=E[i++]<<f,f+=8,p+=E[i++]<<f,f+=8),y=g[p&v];r:for(;;){if(b=y>>>24,p>>>=b,f-=b,!(16&(b=y>>>16&255))){if(0==(64&b)){y=g[(65535&y)+(p&(1<<b)-1)];continue r}e.msg="invalid distance code",r.mode=30;break e}if(S=65535&y,b&=15,f<b&&(p+=E[i++]<<f,(f+=8)<b&&(p+=E[i++]<<f,f+=8)),(S+=p&(1<<b)-1)>l){e.msg="invalid distance too far back",r.mode=30;break e}if(p>>>=b,f-=b,b=o-a,S>b){if((b=S-b)>c&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(w=0,T=h,0===d){if(w+=u-b,b<C){C-=b;do{A[o++]=h[w++]}while(--b);w=o-S,T=A}}else if(d<b){if(w+=u+d-b,(b-=d)<C){C-=b;do{A[o++]=h[w++]}while(--b);if(w=0,d<C){b=d,C-=b;do{A[o++]=h[w++]}while(--b);w=o-S,T=A}}}else if(w+=d-b,b<C){C-=b;do{A[o++]=h[w++]}while(--b);w=o-S,T=A}for(;C>2;)A[o++]=T[w++],A[o++]=T[w++],A[o++]=T[w++],C-=3;C&&(A[o++]=T[w++],C>1&&(A[o++]=T[w++]))}else{w=o-S;do{A[o++]=A[w++],A[o++]=A[w++],A[o++]=A[w++],C-=3}while(C>2);C&&(A[o++]=A[w++],C>1&&(A[o++]=A[w++]))}break}}break}}while(i<n&&o<s);C=f>>3,i-=C,f-=C<<3,p&=(1<<f)-1,e.next_in=i,e.next_out=o,e.avail_in=i<n?n-i+5:5-(i-n),e.avail_out=o<s?s-o+257:257-(o-s),r.hold=p,r.bits=f}},{}],8:[function(e,t,r){"use strict";function i(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function n(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new v.Buf16(320),this.work=new v.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function o(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=F,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new v.Buf32(me),t.distcode=t.distdyn=new v.Buf32(ge),t.sane=1,t.back=-1,D):M}function a(e){var t;return e&&e.state?(t=e.state,t.wsize=0,t.whave=0,t.wnext=0,o(e)):M}function s(e,t){var r,i;return e&&e.state?(i=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?M:(null!==i.window&&i.wbits!==t&&(i.window=null),i.wrap=r,i.wbits=t,a(e))):M}function l(e,t){var r,i;return e?(i=new n,e.state=i,i.window=null,r=s(e,t),r!==D&&(e.state=null),r):M}function u(e){return l(e,_e)}function c(e){if(ve){var t;for(g=new v.Buf32(512),_=new v.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(S(T,e.lens,0,288,g,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;S(E,e.lens,0,32,_,0,e.work,{bits:5}),ve=!1}e.lencode=g,e.lenbits=9,e.distcode=_,e.distbits=5}function d(e,t,r,i){var n,o=e.state;return null===o.window&&(o.wsize=1<<o.wbits,o.wnext=0,o.whave=0,o.window=new v.Buf8(o.wsize)),i>=o.wsize?(v.arraySet(o.window,t,r-o.wsize,o.wsize,0),o.wnext=0,o.whave=o.wsize):(n=o.wsize-o.wnext,n>i&&(n=i),v.arraySet(o.window,t,r-i,n,o.wnext),i-=n,i?(v.arraySet(o.window,t,r-i,i,0),o.wnext=i,o.whave=o.wsize):(o.wnext+=n,o.wnext===o.wsize&&(o.wnext=0),o.whave<o.wsize&&(o.whave+=n))),0}function h(e,t){var r,n,o,a,s,l,u,h,p,f,m,g,_,me,ge,_e,ve,ye,be,Ce,Se,we,Te,Ee,Ae=0,xe=new v.Buf8(4),Pe=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!e||!e.state||!e.output||!e.input&&0!==e.avail_in)return M;r=e.state,r.mode===X&&(r.mode=Q),s=e.next_out,o=e.output,u=e.avail_out,a=e.next_in,n=e.input,l=e.avail_in,h=r.hold,p=r.bits,f=l,m=u,we=D;e:for(;;)switch(r.mode){case F:if(0===r.wrap){r.mode=Q;break}for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(2&r.wrap&&35615===h){r.check=0,xe[0]=255&h,xe[1]=h>>>8&255,r.check=b(r.check,xe,2,0),h=0,p=0,r.mode=B;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&h)<<8)+(h>>8))%31){e.msg="incorrect header check",r.mode=he;break}if((15&h)!==k){e.msg="unknown compression method",r.mode=he;break}if(h>>>=4,p-=4,Se=8+(15&h),0===r.wbits)r.wbits=Se;else if(Se>r.wbits){e.msg="invalid window size",r.mode=he;break}r.dmax=1<<Se,e.adler=r.check=1,r.mode=512&h?q:X,h=0,p=0;break;case B:for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(r.flags=h,(255&r.flags)!==k){e.msg="unknown compression method",r.mode=he;break}if(57344&r.flags){e.msg="unknown header flags set",r.mode=he;break}r.head&&(r.head.text=h>>8&1),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,r.check=b(r.check,xe,2,0)),h=0,p=0,r.mode=U;case U:for(;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.head&&(r.head.time=h),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,xe[2]=h>>>16&255,xe[3]=h>>>24&255,r.check=b(r.check,xe,4,0)),h=0,p=0,r.mode=V;case V:for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.head&&(r.head.xflags=255&h,r.head.os=h>>8),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,r.check=b(r.check,xe,2,0)),h=0,p=0,r.mode=z;case z:if(1024&r.flags){for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.length=h,r.head&&(r.head.extra_len=h),512&r.flags&&(xe[0]=255&h,xe[1]=h>>>8&255,r.check=b(r.check,xe,2,0)),h=0,p=0}else r.head&&(r.head.extra=null);r.mode=G;case G:if(1024&r.flags&&(g=r.length,g>l&&(g=l),g&&(r.head&&(Se=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),v.arraySet(r.head.extra,n,a,g,Se)),512&r.flags&&(r.check=b(r.check,n,g,a)),l-=g,a+=g,r.length-=g),r.length))break e;r.length=0,r.mode=W;case W:if(2048&r.flags){if(0===l)break e;g=0;do{Se=n[a+g++],r.head&&Se&&r.length<65536&&(r.head.name+=String.fromCharCode(Se))}while(Se&&g<l);if(512&r.flags&&(r.check=b(r.check,n,g,a)),l-=g,a+=g,Se)break e}else r.head&&(r.head.name=null);r.length=0,r.mode=H;case H:if(4096&r.flags){if(0===l)break e;g=0;do{Se=n[a+g++],r.head&&Se&&r.length<65536&&(r.head.comment+=String.fromCharCode(Se))}while(Se&&g<l);if(512&r.flags&&(r.check=b(r.check,n,g,a)),l-=g,a+=g,Se)break e}else r.head&&(r.head.comment=null);r.mode=j;case j:if(512&r.flags){for(;p<16;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(h!==(65535&r.check)){e.msg="header crc mismatch",r.mode=he;break}h=0,p=0}r.head&&(r.head.hcrc=r.flags>>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=X;break;case q:for(;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}e.adler=r.check=i(h),h=0,p=0,r.mode=Y;case Y:if(0===r.havedict)return e.next_out=s,e.avail_out=u,e.next_in=a,e.avail_in=l,r.hold=h,r.bits=p,O;e.adler=r.check=1,r.mode=X;case X:if(t===x||t===P)break e;case Q:if(r.last){h>>>=7&p,p-=7&p,r.mode=ue;break}for(;p<3;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}switch(r.last=1&h,h>>>=1,p-=1,3&h){case 0:r.mode=Z;break;case 1:if(c(r),r.mode=re,t===P){h>>>=2,p-=2;break e}break;case 2:r.mode=$;break;case 3:e.msg="invalid block type",r.mode=he}h>>>=2,p-=2;break;case Z:for(h>>>=7&p,p-=7&p;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if((65535&h)!=(h>>>16^65535)){e.msg="invalid stored block lengths",r.mode=he;break}if(r.length=65535&h,h=0,p=0,r.mode=K,t===P)break e;case K:r.mode=J;case J:if(g=r.length){if(g>l&&(g=l),g>u&&(g=u),0===g)break e;v.arraySet(o,n,a,g,s),l-=g,a+=g,u-=g,s+=g,r.length-=g;break}r.mode=X;break;case $:for(;p<14;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(r.nlen=257+(31&h),h>>>=5,p-=5,r.ndist=1+(31&h),h>>>=5,p-=5,r.ncode=4+(15&h),h>>>=4,p-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=he;break}r.have=0,r.mode=ee;case ee:for(;r.have<r.ncode;){for(;p<3;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.lens[Pe[r.have++]]=7&h,h>>>=3,p-=3}for(;r.have<19;)r.lens[Pe[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,Te={bits:r.lenbits},we=S(w,r.lens,0,19,r.lencode,0,r.work,Te),r.lenbits=Te.bits,we){e.msg="invalid code lengths set",r.mode=he;break}r.have=0,r.mode=te;case te:for(;r.have<r.nlen+r.ndist;){for(;Ae=r.lencode[h&(1<<r.lenbits)-1],ge=Ae>>>24,_e=Ae>>>16&255,ve=65535&Ae,!(ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(ve<16)h>>>=ge,p-=ge,r.lens[r.have++]=ve;else{if(16===ve){for(Ee=ge+2;p<Ee;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(h>>>=ge,p-=ge,0===r.have){e.msg="invalid bit length repeat",r.mode=he;break}Se=r.lens[r.have-1],g=3+(3&h),h>>>=2,p-=2}else if(17===ve){for(Ee=ge+3;p<Ee;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ge,p-=ge,Se=0,g=3+(7&h),h>>>=3,p-=3}else{for(Ee=ge+7;p<Ee;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ge,p-=ge,Se=0,g=11+(127&h),h>>>=7,p-=7}if(r.have+g>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=he;break}for(;g--;)r.lens[r.have++]=Se}}if(r.mode===he)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=he;break}if(r.lenbits=9,Te={bits:r.lenbits},we=S(T,r.lens,0,r.nlen,r.lencode,0,r.work,Te),r.lenbits=Te.bits,we){e.msg="invalid literal/lengths set",r.mode=he;break}if(r.distbits=6,r.distcode=r.distdyn,Te={bits:r.distbits},we=S(E,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,Te),r.distbits=Te.bits,we){e.msg="invalid distances set",r.mode=he;break}if(r.mode=re,t===P)break e;case re:r.mode=ie;case ie:if(l>=6&&u>=258){e.next_out=s,e.avail_out=u,e.next_in=a,e.avail_in=l,r.hold=h,r.bits=p,C(e,m),s=e.next_out,o=e.output,u=e.avail_out,a=e.next_in,n=e.input,l=e.avail_in,h=r.hold,p=r.bits,r.mode===X&&(r.back=-1);break}for(r.back=0;Ae=r.lencode[h&(1<<r.lenbits)-1],ge=Ae>>>24,_e=Ae>>>16&255,ve=65535&Ae,!(ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(_e&&0==(240&_e)){for(ye=ge,be=_e,Ce=ve;Ae=r.lencode[Ce+((h&(1<<ye+be)-1)>>ye)],ge=Ae>>>24,_e=Ae>>>16&255,ve=65535&Ae,!(ye+ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ye,p-=ye,r.back+=ye}if(h>>>=ge,p-=ge,r.back+=ge,r.length=ve,0===_e){r.mode=le;break}if(32&_e){r.back=-1,r.mode=X;break}if(64&_e){e.msg="invalid literal/length code",r.mode=he;break}r.extra=15&_e,r.mode=ne;case ne:if(r.extra){for(Ee=r.extra;p<Ee;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.length+=h&(1<<r.extra)-1,h>>>=r.extra,p-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=oe;case oe:for(;Ae=r.distcode[h&(1<<r.distbits)-1],ge=Ae>>>24,_e=Ae>>>16&255,ve=65535&Ae,!(ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(0==(240&_e)){for(ye=ge,be=_e,Ce=ve;Ae=r.distcode[Ce+((h&(1<<ye+be)-1)>>ye)],ge=Ae>>>24,_e=Ae>>>16&255,ve=65535&Ae,!(ye+ge<=p);){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}h>>>=ye,p-=ye,r.back+=ye}if(h>>>=ge,p-=ge,r.back+=ge,64&_e){e.msg="invalid distance code",r.mode=he;break}r.offset=ve,r.extra=15&_e,r.mode=ae;case ae:if(r.extra){for(Ee=r.extra;p<Ee;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}r.offset+=h&(1<<r.extra)-1,h>>>=r.extra,p-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=he;break}r.mode=se;case se:if(0===u)break e;if(g=m-u,r.offset>g){if((g=r.offset-g)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=he;break}g>r.wnext?(g-=r.wnext,_=r.wsize-g):_=r.wnext-g,g>r.length&&(g=r.length),me=r.window}else me=o,_=s-r.offset,g=r.length;g>u&&(g=u),u-=g,r.length-=g;do{o[s++]=me[_++]}while(--g);0===r.length&&(r.mode=ie);break;case le:if(0===u)break e;o[s++]=r.length,u--,r.mode=ie;break;case ue:if(r.wrap){for(;p<32;){if(0===l)break e;l--,h|=n[a++]<<p,p+=8}if(m-=u,e.total_out+=m,r.total+=m,m&&(e.adler=r.check=r.flags?b(r.check,o,m,s-m):y(r.check,o,m,s-m)),m=u,(r.flags?h:i(h))!==r.check){e.msg="incorrect data check",r.mode=he;break}h=0,p=0}r.mode=ce;case ce:if(r.wrap&&r.flags){for(;p<32;){if(0===l)break e;l--,h+=n[a++]<<p,p+=8}if(h!==(4294967295&r.total)){e.msg="incorrect length check",r.mode=he;break}h=0,p=0}r.mode=de;case de:we=I;break e;case he:we=R;break e;case pe:return L;case fe:default:return M}return e.next_out=s,e.avail_out=u,e.next_in=a,e.avail_in=l,r.hold=h,r.bits=p,(r.wsize||m!==e.avail_out&&r.mode<he&&(r.mode<ue||t!==A))&&d(e,e.output,e.next_out,m-e.avail_out)?(r.mode=pe,L):(f-=e.avail_in,m-=e.avail_out,e.total_in+=f,e.total_out+=m,r.total+=m,r.wrap&&m&&(e.adler=r.check=r.flags?b(r.check,o,m,e.next_out-m):y(r.check,o,m,e.next_out-m)),e.data_type=r.bits+(r.last?64:0)+(r.mode===X?128:0)+(r.mode===re||r.mode===K?256:0),(0===f&&0===m||t===A)&&we===D&&(we=N),we)}function p(e){if(!e||!e.state)return M;var t=e.state;return t.window&&(t.window=null),e.state=null,D}function f(e,t){var r;return e&&e.state?(r=e.state,0==(2&r.wrap)?M:(r.head=t,t.done=!1,D)):M}function m(e,t){var r,i,n=t.length;return e&&e.state?(r=e.state,0!==r.wrap&&r.mode!==Y?M:r.mode===Y&&(i=1,(i=y(i,t,n,0))!==r.check)?R:d(e,t,n,n)?(r.mode=pe,L):(r.havedict=1,D)):M}var g,_,v=e("../utils/common"),y=e("./adler32"),b=e("./crc32"),C=e("./inffast"),S=e("./inftrees"),w=0,T=1,E=2,A=4,x=5,P=6,D=0,I=1,O=2,M=-2,R=-3,L=-4,N=-5,k=8,F=1,B=2,U=3,V=4,z=5,G=6,W=7,H=8,j=9,q=10,Y=11,X=12,Q=13,Z=14,K=15,J=16,$=17,ee=18,te=19,re=20,ie=21,ne=22,oe=23,ae=24,se=25,le=26,ue=27,ce=28,de=29,he=30,pe=31,fe=32,me=852,ge=592,_e=15,ve=!0;r.inflateReset=a,r.inflateReset2=s,r.inflateResetKeep=o,r.inflateInit=u,r.inflateInit2=l,r.inflate=h,r.inflateEnd=p,r.inflateGetHeader=f,r.inflateSetDictionary=m,r.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":1,"./adler32":3,"./crc32":5,"./inffast":7,"./inftrees":9}],9:[function(e,t,r){"use strict";var i=e("../utils/common"),n=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],o=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],a=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],s=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];t.exports=function(e,t,r,l,u,c,d,h){var p,f,m,g,_,v,y,b,C,S=h.bits,w=0,T=0,E=0,A=0,x=0,P=0,D=0,I=0,O=0,M=0,R=null,L=0,N=new i.Buf16(16),k=new i.Buf16(16),F=null,B=0;for(w=0;w<=15;w++)N[w]=0;for(T=0;T<l;T++)N[t[r+T]]++;for(x=S,A=15;A>=1&&0===N[A];A--);if(x>A&&(x=A),0===A)return u[c++]=20971520,u[c++]=20971520,h.bits=1,0;for(E=1;E<A&&0===N[E];E++);for(x<E&&(x=E),I=1,w=1;w<=15;w++)if(I<<=1,(I-=N[w])<0)return-1;if(I>0&&(0===e||1!==A))return-1;for(k[1]=0,w=1;w<15;w++)k[w+1]=k[w]+N[w];for(T=0;T<l;T++)0!==t[r+T]&&(d[k[t[r+T]]++]=T);if(0===e?(R=F=d,v=19):1===e?(R=n,L-=257,F=o,B-=257,v=256):(R=a,F=s,v=-1),M=0,T=0,w=E,_=c,P=x,D=0,m=-1,O=1<<x,g=O-1,1===e&&O>852||2===e&&O>592)return 1;for(;;){y=w-D,d[T]<v?(b=0,C=d[T]):d[T]>v?(b=F[B+d[T]],C=R[L+d[T]]):(b=96,C=0),p=1<<w-D,f=1<<P,E=f;do{f-=p,u[_+(M>>D)+f]=y<<24|b<<16|C|0}while(0!==f);for(p=1<<w-1;M&p;)p>>=1;if(0!==p?(M&=p-1,M+=p):M=0,T++,0==--N[w]){if(w===A)break;w=t[r+d[T]]}if(w>x&&(M&g)!==m){for(0===D&&(D=x),_+=E,P=w-D,I=1<<P;P+D<A&&!((I-=N[P+D])<=0);)P++,I<<=1;if(O+=1<<P,1===e&&O>852||2===e&&O>592)return 1;m=M&g,u[m]=x<<24|P<<16|_-c|0}}return 0!==M&&(u[_+M]=w-D<<24|64<<16|0),h.bits=x,0}},{"../utils/common":1}],10:[function(e,t,r){"use strict";t.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(e,t,r){"use strict";function i(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}t.exports=i},{}],"/lib/inflate.js":[function(e,t,r){"use strict";function i(e){if(!(this instanceof i))return new i(e);this.options=s.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new d,this.strm.avail_out=0;var r=a.inflateInit2(this.strm,t.windowBits);if(r!==u.Z_OK)throw new Error(c[r]);this.header=new h,a.inflateGetHeader(this.strm,this.header)}function n(e,t){var r=new i(t);if(r.push(e,!0),r.err)throw r.msg||c[r.err];return r.result}function o(e,t){return t=t||{},t.raw=!0,n(e,t)}var a=e("./zlib/inflate"),s=e("./utils/common"),l=e("./utils/strings"),u=e("./zlib/constants"),c=e("./zlib/messages"),d=e("./zlib/zstream"),h=e("./zlib/gzheader"),p=Object.prototype.toString;i.prototype.push=function(e,t){var r,i,n,o,c,d,h=this.strm,f=this.options.chunkSize,m=this.options.dictionary,g=!1;if(this.ended)return!1;i=t===~~t?t:!0===t?u.Z_FINISH:u.Z_NO_FLUSH,"string"==typeof e?h.input=l.binstring2buf(e):"[object ArrayBuffer]"===p.call(e)?h.input=new Uint8Array(e):h.input=e,h.next_in=0,h.avail_in=h.input.length;do{if(0===h.avail_out&&(h.output=new s.Buf8(f),h.next_out=0,h.avail_out=f),r=a.inflate(h,u.Z_NO_FLUSH),r===u.Z_NEED_DICT&&m&&(d="string"==typeof m?l.string2buf(m):"[object ArrayBuffer]"===p.call(m)?new Uint8Array(m):m,r=a.inflateSetDictionary(this.strm,d)),r===u.Z_BUF_ERROR&&!0===g&&(r=u.Z_OK,g=!1),r!==u.Z_STREAM_END&&r!==u.Z_OK)return this.onEnd(r),this.ended=!0,!1;h.next_out&&(0!==h.avail_out&&r!==u.Z_STREAM_END&&(0!==h.avail_in||i!==u.Z_FINISH&&i!==u.Z_SYNC_FLUSH)||("string"===this.options.to?(n=l.utf8border(h.output,h.next_out),o=h.next_out-n,c=l.buf2string(h.output,n),h.next_out=o,h.avail_out=f-o,o&&s.arraySet(h.output,h.output,n,o,0),this.onData(c)):this.onData(s.shrinkBuf(h.output,h.next_out)))),0===h.avail_in&&0===h.avail_out&&(g=!0)}while((h.avail_in>0||0===h.avail_out)&&r!==u.Z_STREAM_END);return r===u.Z_STREAM_END&&(i=u.Z_FINISH),i===u.Z_FINISH?(r=a.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===u.Z_OK):i!==u.Z_SYNC_FLUSH||(this.onEnd(u.Z_OK),h.avail_out=0,!0)},i.prototype.onData=function(e){this.chunks.push(e)},i.prototype.onEnd=function(e){e===u.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=s.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},r.Inflate=i,r.inflate=n,r.inflateRaw=o,r.ungzip=n},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")}),define("Widgets/subscribeAndEvaluate",["../ThirdParty/knockout"],function(e){"use strict";function t(t,r,i,n,o){return i.call(n,t[r]),e.getObservable(t,r).subscribe(i,n,o)}return t}),define("Widgets/Animation/Animation",["../../Core/Color","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../getElement","../subscribeAndEvaluate"],function(e,t,r,i,n,o,a){"use strict";function s(t){return e.fromCssColorString(window.getComputedStyle(t).getPropertyValue("color"))}function l(e){var t=document.createElementNS(v,e.tagName);for(var r in e)if(e.hasOwnProperty(r)&&"tagName"!==r)if("children"===r){var i,n=e.children.length;for(i=0;i<n;++i)t.appendChild(l(e.children[i]))}else 0===r.indexOf("xlink:")?t.setAttributeNS(y,r.substring(6),e[r]):"textContent"===r?t.textContent=e[r]:t.setAttribute(r,e[r]);return t}function u(e,t,r){var i=document.createElementNS(v,"text");i.setAttribute("x",e),i.setAttribute("y",t),i.setAttribute("class","cesium-animation-svgText");var n=document.createElementNS(v,"tspan");return n.textContent=r,i.appendChild(n),i}function c(e,t,r){e.setAttribute("transform","translate(100,100) rotate("+r+")"),t.setAttribute("transform","rotate("+r+")")}function d(e,t){var r=t.alpha,i=1-r;return P.red=e.red*i+t.red*r,P.green=e.green*i+t.green*r,P.blue=e.blue*i+t.blue*r,P.toCssColorString()}function h(e,t,r){return l({tagName:"g",class:"cesium-animation-rectButton",transform:"translate("+e+","+t+")",children:[{tagName:"rect",class:"cesium-animation-buttonGlow",width:32,height:32,rx:2,ry:2},{tagName:"rect",class:"cesium-animation-buttonMain",width:32,height:32,rx:4,ry:4},{tagName:"use",class:"cesium-animation-buttonPath","xlink:href":r},{tagName:"title",textContent:""}]})}function p(e,t,r){return l({tagName:"g",class:"cesium-animation-rectButton",transform:"translate("+e+","+t+")",children:[{tagName:"use",class:"cesium-animation-buttonGlow","xlink:href":"#animation_pathWingButton"},{tagName:"use",class:"cesium-animation-buttonMain","xlink:href":"#animation_pathWingButton"},{tagName:"use",class:"cesium-animation-buttonPath","xlink:href":r},{tagName:"title",textContent:""}]})}function f(e,t){var r=e._viewModel,i=r.shuttleRingDragging;if(!i||_===e)if("mousedown"===t.type||i&&"mousemove"===t.type||"touchstart"===t.type&&1===t.touches.length||i&&"touchmove"===t.type&&1===t.touches.length){ +var n,o,a=e._centerX,s=e._centerY,l=e._svgNode,u=l.getBoundingClientRect();if("touchstart"===t.type||"touchmove"===t.type?(n=t.touches[0].clientX,o=t.touches[0].clientY):(n=t.clientX,o=t.clientY),!i&&(n>u.right||n<u.left||o<u.top||o>u.bottom))return;var c=e._shuttleRingPointer.getBoundingClientRect(),d=n-a-u.left,h=o-s-u.top,p=180*Math.atan2(h,d)/Math.PI+90;p>180&&(p-=360);var f=r.shuttleRingAngle;i||n<c.right&&n>c.left&&o>c.top&&o<c.bottom?(_=e,r.shuttleRingDragging=!0,r.shuttleRingAngle=p):p<f?r.slower():p>f&&r.faster(),t.preventDefault()}else e===_&&(_=void 0),r.shuttleRingDragging=!1}function m(e,t){this._viewModel=t,this.svgElement=e,this._enabled=void 0,this._toggled=void 0;var r=this;this._clickFunction=function(){var e=r._viewModel.command;e.canExecute&&e()},e.addEventListener("click",this._clickFunction,!0),this._subscriptions=[a(t,"toggled",this.setToggled,this),a(t,"tooltip",this.setTooltip,this),a(t.command,"canExecute",this.setEnabled,this)]}function g(e,t){function r(e){f(E,e)}e=o(e),this._viewModel=t,this._container=e,this._centerX=0,this._centerY=0,this._defsElement=void 0,this._svgNode=void 0,this._topG=void 0,this._lastHeight=void 0,this._lastWidth=void 0;var i=document.createElement("style");i.textContent=".cesium-animation-rectButton .cesium-animation-buttonGlow { filter: url(#animation_blurred); }.cesium-animation-rectButton .cesium-animation-buttonMain { fill: url(#animation_buttonNormal); }.cesium-animation-buttonToggled .cesium-animation-buttonMain { fill: url(#animation_buttonToggled); }.cesium-animation-rectButton:hover .cesium-animation-buttonMain { fill: url(#animation_buttonHovered); }.cesium-animation-buttonDisabled .cesium-animation-buttonMain { fill: url(#animation_buttonDisabled); }.cesium-animation-shuttleRingG .cesium-animation-shuttleRingSwoosh { fill: url(#animation_shuttleRingSwooshGradient); }.cesium-animation-shuttleRingG:hover .cesium-animation-shuttleRingSwoosh { fill: url(#animation_shuttleRingSwooshHovered); }.cesium-animation-shuttleRingPointer { fill: url(#animation_shuttleRingPointerGradient); }.cesium-animation-shuttleRingPausePointer { fill: url(#animation_shuttleRingPointerPaused); }.cesium-animation-knobOuter { fill: url(#animation_knobOuter); }.cesium-animation-knobInner { fill: url(#animation_knobInner); }",document.head.insertBefore(i,document.head.childNodes[0]);var n=document.createElement("div");n.className="cesium-animation-theme",n.innerHTML='<div class="cesium-animation-themeNormal"></div><div class="cesium-animation-themeHover"></div><div class="cesium-animation-themeSelect"></div><div class="cesium-animation-themeDisabled"></div><div class="cesium-animation-themeKnob"></div><div class="cesium-animation-themePointer"></div><div class="cesium-animation-themeSwoosh"></div><div class="cesium-animation-themeSwooshHover"></div>',this._theme=n,this._themeNormal=n.childNodes[0],this._themeHover=n.childNodes[1],this._themeSelect=n.childNodes[2],this._themeDisabled=n.childNodes[3],this._themeKnob=n.childNodes[4],this._themePointer=n.childNodes[5],this._themeSwoosh=n.childNodes[6],this._themeSwooshHover=n.childNodes[7];var s=document.createElementNS(v,"svg:svg");this._svgNode=s,s.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink",y);var d=document.createElementNS(v,"g");this._topG=d,this._realtimeSVG=new m(p(3,4,"#animation_pathClock"),t.playRealtimeViewModel),this._playReverseSVG=new m(h(44,99,"#animation_pathPlayReverse"),t.playReverseViewModel),this._playForwardSVG=new m(h(124,99,"#animation_pathPlay"),t.playForwardViewModel),this._pauseSVG=new m(h(84,99,"#animation_pathPause"),t.pauseViewModel);var g=document.createElementNS(v,"g");g.appendChild(this._realtimeSVG.svgElement),g.appendChild(this._playReverseSVG.svgElement),g.appendChild(this._playForwardSVG.svgElement),g.appendChild(this._pauseSVG.svgElement);var _=l({tagName:"circle",class:"cesium-animation-shuttleRingBack",cx:100,cy:100,r:99});this._shuttleRingBackPanel=_;var b=l({tagName:"g",class:"cesium-animation-shuttleRingSwoosh",children:[{tagName:"use",transform:"translate(100,97) scale(-1,1)","xlink:href":"#animation_pathSwooshFX"},{tagName:"use",transform:"translate(100,97)","xlink:href":"#animation_pathSwooshFX"},{tagName:"line",x1:100,y1:8,x2:100,y2:22}]});this._shuttleRingSwooshG=b,this._shuttleRingPointer=l({tagName:"use",class:"cesium-animation-shuttleRingPointer","xlink:href":"#animation_pathPointer"});var C=l({tagName:"g",transform:"translate(100,100)"});this._knobOuter=l({tagName:"circle",class:"cesium-animation-knobOuter",cx:0,cy:0,r:71});var S=l({tagName:"circle",class:"cesium-animation-knobInner",cx:0,cy:0,r:61});this._knobDate=u(0,-24,""),this._knobTime=u(0,-7,""),this._knobStatus=u(0,-41,"");var w=l({tagName:"circle",class:"cesium-animation-blank",cx:0,cy:0,r:61}),T=document.createElementNS(v,"g");T.setAttribute("class","cesium-animation-shuttleRingG"),e.appendChild(n),d.appendChild(T),d.appendChild(C),d.appendChild(g),T.appendChild(_),T.appendChild(b),T.appendChild(this._shuttleRingPointer),C.appendChild(this._knobOuter),C.appendChild(S),C.appendChild(this._knobDate),C.appendChild(this._knobTime),C.appendChild(this._knobStatus),C.appendChild(w),s.appendChild(d),e.appendChild(s);var E=this;this._mouseCallback=r,_.addEventListener("mousedown",r,!0),_.addEventListener("touchstart",r,!0),b.addEventListener("mousedown",r,!0),b.addEventListener("touchstart",r,!0),document.addEventListener("mousemove",r,!0),document.addEventListener("touchmove",r,!0),document.addEventListener("mouseup",r,!0),document.addEventListener("touchend",r,!0),document.addEventListener("touchcancel",r,!0),this._shuttleRingPointer.addEventListener("mousedown",r,!0),this._shuttleRingPointer.addEventListener("touchstart",r,!0),this._knobOuter.addEventListener("mousedown",r,!0),this._knobOuter.addEventListener("touchstart",r,!0);var A,x=this._knobTime.childNodes[0],P=this._knobDate.childNodes[0],D=this._knobStatus.childNodes[0];this._subscriptions=[a(t.pauseViewModel,"toggled",function(e){A!==e&&(A=e,A?E._shuttleRingPointer.setAttribute("class","cesium-animation-shuttleRingPausePointer"):E._shuttleRingPointer.setAttribute("class","cesium-animation-shuttleRingPointer"))}),a(t,"shuttleRingAngle",function(e){c(E._shuttleRingPointer,E._knobOuter,e)}),a(t,"dateLabel",function(e){P.textContent!==e&&(P.textContent=e)}),a(t,"timeLabel",function(e){x.textContent!==e&&(x.textContent=e)}),a(t,"multiplierLabel",function(e){D.textContent!==e&&(D.textContent=e)})],this.applyThemeChanges(),this.resize()}var _,v="http://www.w3.org/2000/svg",y="http://www.w3.org/1999/xlink",b=e.fromCssColorString("rgba(247,250,255,0.384)"),C=e.fromCssColorString("rgba(143,191,255,0.216)"),S=e.fromCssColorString("rgba(153,197,255,0.098)"),w=e.fromCssColorString("rgba(255,255,255,0.086)"),T=e.fromCssColorString("rgba(255,255,255,0.267)"),E=e.fromCssColorString("rgba(255,255,255,0)"),A=e.fromCssColorString("rgba(66,67,68,0.3)"),x=e.fromCssColorString("rgba(0,0,0,0.5)"),P=new e;return m.prototype.destroy=function(){this.svgElement.removeEventListener("click",this._clickFunction,!0);for(var e=this._subscriptions,t=0,r=e.length;t<r;t++)e[t].dispose();i(this)},m.prototype.isDestroyed=function(){return!1},m.prototype.setEnabled=function(e){if(this._enabled!==e){if(this._enabled=e,!e)return void this.svgElement.setAttribute("class","cesium-animation-buttonDisabled");if(this._toggled)return void this.svgElement.setAttribute("class","cesium-animation-rectButton cesium-animation-buttonToggled");this.svgElement.setAttribute("class","cesium-animation-rectButton")}},m.prototype.setToggled=function(e){this._toggled!==e&&(this._toggled=e,this._enabled&&(e?this.svgElement.setAttribute("class","cesium-animation-rectButton cesium-animation-buttonToggled"):this.svgElement.setAttribute("class","cesium-animation-rectButton")))},m.prototype.setTooltip=function(e){this.svgElement.getElementsByTagName("title")[0].textContent=e},r(g.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),g.prototype.isDestroyed=function(){return!1},g.prototype.destroy=function(){t(this._observer)&&(this._observer.disconnect(),this._observer=void 0);var e=this._mouseCallback;this._shuttleRingBackPanel.removeEventListener("mousedown",e,!0),this._shuttleRingBackPanel.removeEventListener("touchstart",e,!0),this._shuttleRingSwooshG.removeEventListener("mousedown",e,!0),this._shuttleRingSwooshG.removeEventListener("touchstart",e,!0),document.removeEventListener("mousemove",e,!0),document.removeEventListener("touchmove",e,!0),document.removeEventListener("mouseup",e,!0),document.removeEventListener("touchend",e,!0),document.removeEventListener("touchcancel",e,!0),this._shuttleRingPointer.removeEventListener("mousedown",e,!0),this._shuttleRingPointer.removeEventListener("touchstart",e,!0),this._knobOuter.removeEventListener("mousedown",e,!0),this._knobOuter.removeEventListener("touchstart",e,!0),this._container.removeChild(this._svgNode),this._container.removeChild(this._theme),this._realtimeSVG.destroy(),this._playReverseSVG.destroy(),this._playForwardSVG.destroy(),this._pauseSVG.destroy();for(var r=this._subscriptions,n=0,o=r.length;n<o;n++)r[n].dispose();return i(this)},g.prototype.resize=function(){var e=this._container.clientWidth,t=this._container.clientHeight;if(e!==this._lastWidth||t!==this._lastHeight){var r=this._svgNode,i=e,n=t;0===e&&0===t?(i=200,n=132):0===e?(n=t,i=t/132*200):0===t&&(i=e,n=e/200*132);var o=i/200,a=n/132;r.style.cssText="width: "+i+"px; height: "+n+"px; position: absolute; bottom: 0; left: 0; overflow: hidden;",r.setAttribute("width",i),r.setAttribute("height",n),r.setAttribute("viewBox","0 0 "+i+" "+n),this._topG.setAttribute("transform","scale("+o+","+a+")"),this._centerX=Math.max(1,100*o),this._centerY=Math.max(1,100*a),this._lastHeight=e,this._lastWidth=t}},g.prototype.applyThemeChanges=function(){if(!document.body.contains(this._container)){if(t(this._observer))return;var e=this;return e._observer=new MutationObserver(function(){document.body.contains(e._container)&&(e._observer.disconnect(),e._observer=void 0,e.applyThemeChanges())}),void e._observer.observe(document,{childList:!0,subtree:!0})}var r=s(this._themeNormal),i=s(this._themeHover),n=s(this._themeSelect),o=s(this._themeDisabled),a=s(this._themeKnob),u=s(this._themePointer),c=s(this._themeSwoosh),h=s(this._themeSwooshHover),p=l({tagName:"defs",children:[{id:"animation_buttonNormal",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(r,b)},{tagName:"stop",offset:"12%","stop-color":d(r,C)},{tagName:"stop",offset:"46%","stop-color":d(r,S)},{tagName:"stop",offset:"81%","stop-color":d(r,w)}]},{id:"animation_buttonHovered",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(i,b)},{tagName:"stop",offset:"12%","stop-color":d(i,C)},{tagName:"stop",offset:"46%","stop-color":d(i,S)},{tagName:"stop",offset:"81%","stop-color":d(i,w)}]},{id:"animation_buttonToggled",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(n,b)},{tagName:"stop",offset:"12%","stop-color":d(n,C)},{tagName:"stop",offset:"46%","stop-color":d(n,S)},{tagName:"stop",offset:"81%","stop-color":d(n,w)}]},{id:"animation_buttonDisabled",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-color":d(o,T)},{tagName:"stop",offset:"75%","stop-color":d(o,E)}]},{id:"animation_blurred",tagName:"filter",width:"200%",height:"200%",x:"-50%",y:"-50%",children:[{tagName:"feGaussianBlur",stdDeviation:4,in:"SourceGraphic"}]},{id:"animation_shuttleRingSwooshGradient",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-opacity":.2,"stop-color":c.toCssColorString()},{tagName:"stop",offset:"85%","stop-opacity":.85,"stop-color":c.toCssColorString()},{tagName:"stop",offset:"95%","stop-opacity":.05,"stop-color":c.toCssColorString()}]},{id:"animation_shuttleRingSwooshHovered",tagName:"linearGradient",x1:"50%",y1:"0%",x2:"50%",y2:"100%",children:[{tagName:"stop",offset:"0%","stop-opacity":.2,"stop-color":h.toCssColorString()},{tagName:"stop",offset:"85%","stop-opacity":.85,"stop-color":h.toCssColorString()},{tagName:"stop",offset:"95%","stop-opacity":.05,"stop-color":h.toCssColorString()}]},{id:"animation_shuttleRingPointerGradient",tagName:"linearGradient",x1:"0%",y1:"50%",x2:"100%",y2:"50%",children:[{tagName:"stop",offset:"0%","stop-color":u.toCssColorString()},{tagName:"stop",offset:"40%","stop-color":u.toCssColorString()},{tagName:"stop",offset:"60%","stop-color":d(u,x)},{tagName:"stop",offset:"100%","stop-color":d(u,x)}]},{id:"animation_shuttleRingPointerPaused",tagName:"linearGradient",x1:"0%",y1:"50%",x2:"100%",y2:"50%",children:[{tagName:"stop",offset:"0%","stop-color":"#CCC"},{tagName:"stop",offset:"40%","stop-color":"#CCC"},{tagName:"stop",offset:"60%","stop-color":"#555"},{tagName:"stop",offset:"100%","stop-color":"#555"}]},{id:"animation_knobOuter",tagName:"linearGradient",x1:"20%",y1:"0%",x2:"90%",y2:"100%",children:[{tagName:"stop",offset:"5%","stop-color":d(a,b)},{tagName:"stop",offset:"60%","stop-color":d(a,A)},{tagName:"stop",offset:"85%","stop-color":d(a,C)}]},{id:"animation_knobInner",tagName:"linearGradient",x1:"20%",y1:"0%",x2:"90%",y2:"100%",children:[{tagName:"stop",offset:"5%","stop-color":d(a,A)},{tagName:"stop",offset:"60%","stop-color":d(a,b)},{tagName:"stop",offset:"85%","stop-color":d(a,w)}]},{id:"animation_pathReset",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M24.316,5.318,9.833,13.682,9.833,5.5,5.5,5.5,5.5,25.5,9.833,25.5,9.833,17.318,24.316,25.682z"},{id:"animation_pathPause",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M13,5.5,7.5,5.5,7.5,25.5,13,25.5zM24.5,5.5,19,5.5,19,25.5,24.5,25.5z"},{id:"animation_pathPlay",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M6.684,25.682L24.316,15.5L6.684,5.318V25.682z"},{id:"animation_pathPlayReverse",tagName:"path",transform:"translate(16,16) scale(-0.85,0.85) translate(-16,-16)",d:"M6.684,25.682L24.316,15.5L6.684,5.318V25.682z"},{id:"animation_pathLoop",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-16)",d:"M24.249,15.499c-0.009,4.832-3.918,8.741-8.75,8.75c-2.515,0-4.768-1.064-6.365-2.763l2.068-1.442l-7.901-3.703l0.744,8.694l2.193-1.529c2.244,2.594,5.562,4.242,9.26,4.242c6.767,0,12.249-5.482,12.249-12.249H24.249zM15.499,6.75c2.516,0,4.769,1.065,6.367,2.764l-2.068,1.443l7.901,3.701l-0.746-8.693l-2.192,1.529c-2.245-2.594-5.562-4.245-9.262-4.245C8.734,3.25,3.25,8.734,3.249,15.499H6.75C6.758,10.668,10.668,6.758,15.499,6.75z"},{id:"animation_pathClock",tagName:"path",transform:"translate(16,16) scale(0.85) translate(-16,-15.5)",d:"M15.5,2.374C8.251,2.375,2.376,8.251,2.374,15.5C2.376,22.748,8.251,28.623,15.5,28.627c7.249-0.004,13.124-5.879,13.125-13.127C28.624,8.251,22.749,2.375,15.5,2.374zM15.5,25.623C9.909,25.615,5.385,21.09,5.375,15.5C5.385,9.909,9.909,5.384,15.5,5.374c5.59,0.01,10.115,4.535,10.124,10.125C25.615,21.09,21.091,25.615,15.5,25.623zM8.625,15.5c-0.001-0.552-0.448-0.999-1.001-1c-0.553,0-1,0.448-1,1c0,0.553,0.449,1,1,1C8.176,16.5,8.624,16.053,8.625,15.5zM8.179,18.572c-0.478,0.277-0.642,0.889-0.365,1.367c0.275,0.479,0.889,0.641,1.365,0.365c0.479-0.275,0.643-0.887,0.367-1.367C9.27,18.461,8.658,18.297,8.179,18.572zM9.18,10.696c-0.479-0.276-1.09-0.112-1.366,0.366s-0.111,1.09,0.365,1.366c0.479,0.276,1.09,0.113,1.367-0.366C9.821,11.584,9.657,10.973,9.18,10.696zM22.822,12.428c0.478-0.275,0.643-0.888,0.366-1.366c-0.275-0.478-0.89-0.642-1.366-0.366c-0.479,0.278-0.642,0.89-0.366,1.367C21.732,12.54,22.344,12.705,22.822,12.428zM12.062,21.455c-0.478-0.275-1.089-0.111-1.366,0.367c-0.275,0.479-0.111,1.09,0.366,1.365c0.478,0.277,1.091,0.111,1.365-0.365C12.704,22.344,12.54,21.732,12.062,21.455zM12.062,9.545c0.479-0.276,0.642-0.888,0.366-1.366c-0.276-0.478-0.888-0.642-1.366-0.366s-0.642,0.888-0.366,1.366C10.973,9.658,11.584,9.822,12.062,9.545zM22.823,18.572c-0.48-0.275-1.092-0.111-1.367,0.365c-0.275,0.479-0.112,1.092,0.367,1.367c0.477,0.275,1.089,0.113,1.365-0.365C23.464,19.461,23.3,18.848,22.823,18.572zM19.938,7.813c-0.477-0.276-1.091-0.111-1.365,0.366c-0.275,0.48-0.111,1.091,0.366,1.367s1.089,0.112,1.366-0.366C20.581,8.702,20.418,8.089,19.938,7.813zM23.378,14.5c-0.554,0.002-1.001,0.45-1.001,1c0.001,0.552,0.448,1,1.001,1c0.551,0,1-0.447,1-1C24.378,14.949,23.929,14.5,23.378,14.5zM15.501,6.624c-0.552,0-1,0.448-1,1l-0.466,7.343l-3.004,1.96c-0.478,0.277-0.642,0.889-0.365,1.365c0.275,0.479,0.889,0.643,1.365,0.367l3.305-1.676C15.39,16.99,15.444,17,15.501,17c0.828,0,1.5-0.671,1.5-1.5l-0.5-7.876C16.501,7.072,16.053,6.624,15.501,6.624zM15.501,22.377c-0.552,0-1,0.447-1,1s0.448,1,1,1s1-0.447,1-1S16.053,22.377,15.501,22.377zM18.939,21.455c-0.479,0.277-0.643,0.889-0.366,1.367c0.275,0.477,0.888,0.643,1.366,0.365c0.478-0.275,0.642-0.889,0.366-1.365C20.028,21.344,19.417,21.18,18.939,21.455z"},{id:"animation_pathWingButton",tagName:"path",d:"m 4.5,0.5 c -2.216,0 -4,1.784 -4,4 l 0,24 c 0,2.216 1.784,4 4,4 l 13.71875,0 C 22.478584,27.272785 27.273681,22.511272 32.5,18.25 l 0,-13.75 c 0,-2.216 -1.784,-4 -4,-4 l -24,0 z"},{id:"animation_pathPointer",tagName:"path",d:"M-15,-65,-15,-55,15,-55,15,-65,0,-95z"},{id:"animation_pathSwooshFX",tagName:"path",d:"m 85,0 c 0,16.617 -4.813944,35.356 -13.131081,48.4508 h 6.099803 c 8.317138,-13.0948 13.13322,-28.5955 13.13322,-45.2124 0,-46.94483 -38.402714,-85.00262 -85.7743869,-85.00262 -1.0218522,0 -2.0373001,0.0241 -3.0506131,0.0589 45.958443,1.59437 82.723058,35.77285 82.723058,81.70532 z"}]});t(this._defsElement)?this._svgNode.replaceChild(p,this._defsElement):this._svgNode.appendChild(p),this._defsElement=p},g}),define("Widgets/createCommand",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../Core/Event","../ThirdParty/knockout"],function(e,t,r,i,n,o){"use strict";function a(t,i){function a(){var e,r={args:arguments,cancel:!1};return s.raiseEvent(r),r.cancel||(e=t.apply(null,arguments),l.raiseEvent(e)),e}i=e(i,!0);var s=new n,l=new n;return a.canExecute=i,o.track(a,["canExecute"]),r(a,{beforeExecute:{value:s},afterExecute:{value:l}}),a}return a}),define("Widgets/ToggleButtonViewModel",["../Core/defaultValue","../Core/defined","../Core/defineProperties","../Core/DeveloperError","../ThirdParty/knockout"],function(e,t,r,i,n){"use strict";function o(t,r){this._command=t,r=e(r,e.EMPTY_OBJECT),this.toggled=e(r.toggled,!1),this.tooltip=e(r.tooltip,""),n.track(this,["toggled","tooltip"])}return r(o.prototype,{command:{get:function(){return this._command}}}),o}),define("Widgets/Animation/AnimationViewModel",["../../Core/binarySearch","../../Core/ClockRange","../../Core/ClockStep","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/JulianDate","../../ThirdParty/knockout","../../ThirdParty/sprintf","../createCommand","../ToggleButtonViewModel"],function(e,t,r,i,n,o,a,s,l,u,c){"use strict";function d(e,t){return e-t}function h(t,r){var i=e(r,t,d);return i<0?~i:i}function p(e,t){if(Math.abs(e)<=_)return e/_;var r,i,n=_,o=v;return e>0?(r=Math.log(t[t.length-1]),i=(r-0)/(o-n),Math.exp(0+i*(e-n))):(r=Math.log(-t[0]),i=(r-0)/(o-n),-Math.exp(0+i*(Math.abs(e)-n)))}function f(e,t,i){if(i.clockStep===r.SYSTEM_CLOCK)return _;if(Math.abs(e)<=1)return e*_;var n=t[t.length-1];e>n?e=n:e<-n&&(e=-n);var o,a,s=_,l=v;return e>0?(o=Math.log(n),a=(o-0)/(l-s),(Math.log(e)-0)/a+s):(o=Math.log(-t[0]),a=(o-0)/(l-s),-((Math.log(Math.abs(e))-0)/a+s))}function m(e){var i=this;this._clockViewModel=e,this._allShuttleRingTicks=[],this._dateFormatter=m.defaultDateFormatter,this._timeFormatter=m.defaultTimeFormatter,this.shuttleRingDragging=!1,this.snapToTicks=!1,s.track(this,["_allShuttleRingTicks","_dateFormatter","_timeFormatter","shuttleRingDragging","snapToTicks"]),this._sortedFilteredPositiveTicks=[],this.setShuttleRingTicks(m.defaultTicks),this.timeLabel=void 0,s.defineProperty(this,"timeLabel",function(){return i._timeFormatter(i._clockViewModel.currentTime,i)}),this.dateLabel=void 0,s.defineProperty(this,"dateLabel",function(){return i._dateFormatter(i._clockViewModel.currentTime,i)}),this.multiplierLabel=void 0,s.defineProperty(this,"multiplierLabel",function(){var e=i._clockViewModel;if(e.clockStep===r.SYSTEM_CLOCK)return"Today";var t=e.multiplier;return t%1==0?t.toFixed(0)+"x":t.toFixed(3).replace(/0{0,3}$/,"")+"x"}),this.shuttleRingAngle=void 0,s.defineProperty(this,"shuttleRingAngle",{get:function(){return f(e.multiplier,i._allShuttleRingTicks,e)},set:function(e){e=Math.max(Math.min(e,v),-v);var t=i._allShuttleRingTicks,n=i._clockViewModel;if(n.clockStep=r.SYSTEM_CLOCK_MULTIPLIER,Math.abs(e)===v)return void(n.multiplier=e>0?t[t.length-1]:t[0]);var o=p(e,t);if(i.snapToTicks)o=t[h(o,t)];else if(0!==o){var a=Math.abs(o);if(a>100){var s=a.toFixed(0).length-2,l=Math.pow(10,s);o=Math.round(o/l)*l|0}else a>_?o=Math.round(o):a>1?o=+o.toFixed(1):a>0&&(o=+o.toFixed(2))}n.multiplier=o}}),this._canAnimate=void 0,s.defineProperty(this,"_canAnimate",function(){var e=i._clockViewModel,r=e.clockRange;if(i.shuttleRingDragging||r===t.UNBOUNDED)return!0;var n=e.multiplier,o=e.currentTime,s=e.startTime,l=!1;if(r===t.LOOP_STOP)l=a.greaterThan(o,s)||o.equals(s)&&n>0;else{var u=e.stopTime;l=a.greaterThan(o,s)&&a.lessThan(o,u)||o.equals(s)&&n>0||o.equals(u)&&n<0}return l||(e.shouldAnimate=!1),l}),this._isSystemTimeAvailable=void 0,s.defineProperty(this,"_isSystemTimeAvailable",function(){var e=i._clockViewModel;if(e.clockRange===t.UNBOUNDED)return!0;var r=e.systemTime;return a.greaterThanOrEquals(r,e.startTime)&&a.lessThanOrEquals(r,e.stopTime)}),this._isAnimating=void 0,s.defineProperty(this,"_isAnimating",function(){return i._clockViewModel.shouldAnimate&&(i._canAnimate||i.shuttleRingDragging)});var n=u(function(){var e=i._clockViewModel;e.shouldAnimate?e.shouldAnimate=!1:i._canAnimate&&(e.shouldAnimate=!0)});this._pauseViewModel=new c(n,{toggled:s.computed(function(){return!i._isAnimating}),tooltip:"Pause"});var o=u(function(){var e=i._clockViewModel,t=e.multiplier;t>0&&(e.multiplier=-t),e.shouldAnimate=!0});this._playReverseViewModel=new c(o,{toggled:s.computed(function(){return i._isAnimating&&e.multiplier<0}),tooltip:"Play Reverse"});var l=u(function(){var e=i._clockViewModel,t=e.multiplier;t<0&&(e.multiplier=-t),e.shouldAnimate=!0});this._playForwardViewModel=new c(l,{toggled:s.computed(function(){return i._isAnimating&&e.multiplier>0&&e.clockStep!==r.SYSTEM_CLOCK}),tooltip:"Play Forward"});var d=u(function(){i._clockViewModel.clockStep=r.SYSTEM_CLOCK},s.getObservable(this,"_isSystemTimeAvailable"));this._playRealtimeViewModel=new c(d,{toggled:s.computed(function(){return e.clockStep===r.SYSTEM_CLOCK}),tooltip:s.computed(function(){return i._isSystemTimeAvailable?"Today (real-time)":"Current time not in range"})}),this._slower=u(function(){var e=i._clockViewModel,t=i._allShuttleRingTicks,r=e.multiplier,n=h(r,t)-1;n>=0&&(e.multiplier=t[n])}),this._faster=u(function(){var e=i._clockViewModel,t=i._allShuttleRingTicks,r=e.multiplier,n=h(r,t)+1;n<t.length&&(e.multiplier=t[n])})}var g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],_=15,v=105;return m.defaultDateFormatter=function(e,t){var r=a.toGregorianDate(e);return g[r.month-1]+" "+r.day+" "+r.year},m.defaultTicks=[.001,.002,.005,.01,.02,.05,.1,.25,.5,1,2,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,21600,43200,86400,172800,345600,604800],m.defaultTimeFormatter=function(e,t){var r=a.toGregorianDate(e),i=Math.round(r.millisecond);return Math.abs(t._clockViewModel.multiplier)<1?l("%02d:%02d:%02d.%03d",r.hour,r.minute,r.second,i):l("%02d:%02d:%02d UTC",r.hour,r.minute,r.second)},m.prototype.getShuttleRingTicks=function(){return this._sortedFilteredPositiveTicks.slice(0)},m.prototype.setShuttleRingTicks=function(e){var t,r,i,n={},o=this._sortedFilteredPositiveTicks;for(o.length=0,t=0,r=e.length;t<r;++t)i=e[t],n.hasOwnProperty(i)||(n[i]=!0,o.push(i));o.sort(d);var a=[];for(r=o.length,t=r-1;t>=0;--t)0!==(i=o[t])&&a.push(-i);Array.prototype.push.apply(a,o),this._allShuttleRingTicks=a},n(m.prototype,{slower:{get:function(){return this._slower}},faster:{get:function(){return this._faster}},clockViewModel:{get:function(){return this._clockViewModel}},pauseViewModel:{get:function(){return this._pauseViewModel}},playReverseViewModel:{get:function(){return this._playReverseViewModel}},playForwardViewModel:{get:function(){return this._playForwardViewModel}},playRealtimeViewModel:{get:function(){return this._playRealtimeViewModel}},dateFormatter:{get:function(){return this._dateFormatter},set:function(e){this._dateFormatter=e}},timeFormatter:{get:function(){return this._timeFormatter},set:function(e){this._timeFormatter=e}}}),m._maxShuttleRingAngle=v,m._realtimeShuttleRingAngle=_,m}),define("Widgets/BaseLayerPicker/BaseLayerPickerViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/EllipsoidTerrainProvider","../../Core/isArray","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s){"use strict";function l(r){r=e(r,e.EMPTY_OBJECT);var i=r.globe,l=e(r.imageryProviderViewModels,[]),u=e(r.terrainProviderViewModels,[]);this._globe=i,this.imageryProviderViewModels=l.slice(0),this.terrainProviderViewModels=u.slice(0),this.dropDownVisible=!1,a.track(this,["imageryProviderViewModels","terrainProviderViewModels","dropDownVisible"]),this.buttonTooltip=void 0,a.defineProperty(this,"buttonTooltip",function(){var e=this.selectedImagery,r=this.selectedTerrain,i=t(e)?e.name:void 0,n=t(r)?r.name:void 0;return t(i)&&t(n)?i+"\n"+n:t(i)?i:n}),this.buttonImageUrl=void 0,a.defineProperty(this,"buttonImageUrl",function(){var e=this.selectedImagery;return t(e)?e.iconUrl:void 0}),this.selectedImagery=void 0;var c=a.observable();this._currentImageryProviders=[],a.defineProperty(this,"selectedImagery",{get:function(){return c()},set:function(e){if(c()===e)return void(this.dropDownVisible=!1);var r,i=this._currentImageryProviders,n=i.length,a=this._globe.imageryLayers;for(r=0;r<n;r++)for(var s=a.length,l=0;l<s;l++){var u=a.get(l);if(u.imageryProvider===i[r]){a.remove(u);break}}if(t(e)){var d=e.creationCommand();if(o(d)){var h=d.length;for(r=h-1;r>=0;r--)a.addImageryProvider(d[r],0);this._currentImageryProviders=d.slice(0)}else this._currentImageryProviders=[d],a.addImageryProvider(d,0)}c(e),this.dropDownVisible=!1}}),this.selectedTerrain=void 0;var d=a.observable();a.defineProperty(this,"selectedTerrain",{get:function(){return d()},set:function(e){if(d()===e)return void(this.dropDownVisible=!1);var r;t(e)&&(r=e.creationCommand()),this._globe.depthTestAgainstTerrain=!(r instanceof n),this._globe.terrainProvider=r,d(e),this.dropDownVisible=!1}});var h=this;this._toggleDropDown=s(function(){h.dropDownVisible=!h.dropDownVisible}),this.selectedImagery=e(r.selectedImageryProviderViewModel,l[0]),this.selectedTerrain=e(r.selectedTerrainProviderViewModel,u[0])}return r(l.prototype,{toggleDropDown:{get:function(){return this._toggleDropDown}},globe:{get:function(){return this._globe}}}),l}),define("Widgets/BaseLayerPicker/BaseLayerPicker",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./BaseLayerPickerViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t){e=a(e);var r=new s(t),i=document.createElement("button");i.type="button",i.className="cesium-button cesium-toolbar-button",i.setAttribute("data-bind","attr: { title: buttonTooltip },click: toggleDropDown"),e.appendChild(i);var l=document.createElement("img");l.setAttribute("draggable","false"),l.className="cesium-baseLayerPicker-selected",l.setAttribute("data-bind","attr: { src: buttonImageUrl }"),i.appendChild(l);var u=document.createElement("div");u.className="cesium-baseLayerPicker-dropDown",u.setAttribute("data-bind",'css: { "cesium-baseLayerPicker-dropDown-visible" : dropDownVisible }'),e.appendChild(u);var c=document.createElement("div");c.className="cesium-baseLayerPicker-sectionTitle",c.setAttribute("data-bind","visible: imageryProviderViewModels.length > 0"),c.innerHTML="Imagery",u.appendChild(c);var d=document.createElement("div");d.className="cesium-baseLayerPicker-choices",d.setAttribute("data-bind","foreach: imageryProviderViewModels"),u.appendChild(d);var h=document.createElement("div");h.className="cesium-baseLayerPicker-item",h.setAttribute("data-bind",'css: { "cesium-baseLayerPicker-selectedItem" : $data === $parent.selectedImagery },attr: { title: tooltip },visible: creationCommand.canExecute,click: function($data) { $parent.selectedImagery = $data; }'),d.appendChild(h);var p=document.createElement("img");p.className="cesium-baseLayerPicker-itemIcon",p.setAttribute("data-bind","attr: { src: iconUrl }"),p.setAttribute("draggable","false"),h.appendChild(p);var f=document.createElement("div");f.className="cesium-baseLayerPicker-itemLabel",f.setAttribute("data-bind","text: name"),h.appendChild(f);var m=document.createElement("div");m.className="cesium-baseLayerPicker-sectionTitle",m.setAttribute("data-bind","visible: terrainProviderViewModels.length > 0"),m.innerHTML="Terrain",u.appendChild(m);var g=document.createElement("div");g.className="cesium-baseLayerPicker-choices",g.setAttribute("data-bind","foreach: terrainProviderViewModels"),u.appendChild(g);var _=document.createElement("div");_.className="cesium-baseLayerPicker-item",_.setAttribute("data-bind",'css: { "cesium-baseLayerPicker-selectedItem" : $data === $parent.selectedTerrain },attr: { title: tooltip },visible: creationCommand.canExecute,click: function($data) { $parent.selectedTerrain = $data; }'),g.appendChild(_);var v=document.createElement("img");v.className="cesium-baseLayerPicker-itemIcon",v.setAttribute("data-bind","attr: { src: iconUrl }"),v.setAttribute("draggable","false"),_.appendChild(v);var y=document.createElement("div");y.className="cesium-baseLayerPicker-itemLabel",y.setAttribute("data-bind","text: name"),_.appendChild(y),o.applyBindings(r,i),o.applyBindings(r,u),this._viewModel=r,this._container=e,this._element=i,this._dropPanel=u,this._closeDropDown=function(e){i.contains(e.target)||u.contains(e.target)||(r.dropDownVisible=!1)},n.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeDropDown,!0):(document.addEventListener("mousedown",this._closeDropDown,!0),document.addEventListener("touchstart",this._closeDropDown,!0))}return t(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return n.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeDropDown,!0):(document.removeEventListener("mousedown",this._closeDropDown,!0),document.removeEventListener("touchstart",this._closeDropDown,!0)),o.cleanNode(this._element),o.cleanNode(this._dropPanel),this._container.removeChild(this._element),this._container.removeChild(this._dropPanel),r(this)},l}),define("Widgets/BaseLayerPicker/ProviderViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n){"use strict";function o(t){var r=t.creationFunction;e(r.canExecute)||(r=n(r)),this._creationCommand=r,this.name=t.name,this.tooltip=t.tooltip,this.iconUrl=t.iconUrl,i.track(this,["name","tooltip","iconUrl"])}return t(o.prototype,{creationCommand:{get:function(){return this._creationCommand}}}),o}), +define("Widgets/BaseLayerPicker/createDefaultImageryProviderViewModels",["../../Core/buildModuleUrl","../../Scene/ArcGisMapServerImageryProvider","../../Scene/BingMapsImageryProvider","../../Scene/BingMapsStyle","../../Scene/createOpenStreetMapImageryProvider","../../Scene/createTileMapServiceImageryProvider","../../Scene/MapboxImageryProvider","../BaseLayerPicker/ProviderViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(){var l=[];return l.push(new s({name:"Bing Maps Aerial",iconUrl:e("Widgets/Images/ImageryProviders/bingAerial.png"),tooltip:"Bing Maps aerial imagery \nhttp://www.bing.com/maps",creationFunction:function(){return new r({url:"https://dev.virtualearth.net",mapStyle:i.AERIAL})}})),l.push(new s({name:"Bing Maps Aerial with Labels",iconUrl:e("Widgets/Images/ImageryProviders/bingAerialLabels.png"),tooltip:"Bing Maps aerial imagery with label overlays \nhttp://www.bing.com/maps",creationFunction:function(){return new r({url:"https://dev.virtualearth.net",mapStyle:i.AERIAL_WITH_LABELS})}})),l.push(new s({name:"Bing Maps Roads",iconUrl:e("Widgets/Images/ImageryProviders/bingRoads.png"),tooltip:"Bing Maps standard road maps\nhttp://www.bing.com/maps",creationFunction:function(){return new r({url:"https://dev.virtualearth.net",mapStyle:i.ROAD})}})),l.push(new s({name:"Mapbox Satellite",tooltip:"Mapbox satellite imagery https://www.mapbox.com/maps/",iconUrl:e("Widgets/Images/ImageryProviders/mapboxSatellite.png"),creationFunction:function(){return new a({mapId:"mapbox.satellite"})}})),l.push(new s({name:"Mapbox Streets",tooltip:"Mapbox streets imagery https://www.mapbox.com/maps/",iconUrl:e("Widgets/Images/ImageryProviders/mapboxTerrain.png"),creationFunction:function(){return new a({mapId:"mapbox.streets"})}})),l.push(new s({name:"Mapbox Streets Classic",tooltip:"Mapbox streets basic imagery https://www.mapbox.com/maps/",iconUrl:e("Widgets/Images/ImageryProviders/mapboxStreets.png"),creationFunction:function(){return new a({mapId:"mapbox.streets-basic"})}})),l.push(new s({name:"ESRI World Imagery",iconUrl:e("Widgets/Images/ImageryProviders/esriWorldImagery.png"),tooltip:"World Imagery provides one meter or better satellite and aerial imagery in many parts of the world and lower resolution satellite imagery worldwide. The map includes NASA Blue Marble: Next Generation 500m resolution imagery at small scales (above 1:1,000,000), i-cubed 15m eSAT imagery at medium-to-large scales (down to 1:70,000) for the world, and USGS 15m Landsat imagery for Antarctica. The map features 0.3m resolution imagery in the continental United States and 0.6m resolution imagery in parts of Western Europe from DigitalGlobe. In other parts of the world, 1 meter resolution imagery is available from GeoEye IKONOS, i-cubed Nationwide Prime, Getmapping, AeroGRID, IGN Spain, and IGP Portugal. Additionally, imagery at different resolutions has been contributed by the GIS User Community.\nhttp://www.esri.com",creationFunction:function(){return new t({url:"https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",enablePickFeatures:!1})}})),l.push(new s({name:"ESRI World Street Map",iconUrl:e("Widgets/Images/ImageryProviders/esriWorldStreetMap.png"),tooltip:"This worldwide street map presents highway-level data for the world. Street-level data includes the United States; much of Canada; Japan; most countries in Europe; Australia and New Zealand; India; parts of South America including Argentina, Brazil, Chile, Colombia, and Venezuela; Ghana; and parts of southern Africa including Botswana, Lesotho, Namibia, South Africa, and Swaziland.\nhttp://www.esri.com",creationFunction:function(){return new t({url:"https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",enablePickFeatures:!1})}})),l.push(new s({name:"ESRI National Geographic",iconUrl:e("Widgets/Images/ImageryProviders/esriNationalGeographic.png"),tooltip:"This web map contains the National Geographic World Map service. This map service is designed to be used as a general reference map for informational and educational purposes as well as a basemap by GIS professionals and other users for creating web maps and web mapping applications.\nhttp://www.esri.com",creationFunction:function(){return new t({url:"https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/",enablePickFeatures:!1})}})),l.push(new s({name:"Open­Street­Map",iconUrl:e("Widgets/Images/ImageryProviders/openStreetMap.png"),tooltip:"OpenStreetMap (OSM) is a collaborative project to create a free editable map of the world.\nhttp://www.openstreetmap.org",creationFunction:function(){return n({url:"https://a.tile.openstreetmap.org/"})}})),l.push(new s({name:"Stamen Watercolor",iconUrl:e("Widgets/Images/ImageryProviders/stamenWatercolor.png"),tooltip:"Reminiscent of hand drawn maps, Stamen watercolor maps apply raster effect area washes and organic edges over a paper texture to add warm pop to any map.\nhttp://maps.stamen.com",creationFunction:function(){return n({url:"https://stamen-tiles.a.ssl.fastly.net/watercolor/",credit:"Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA."})}})),l.push(new s({name:"Stamen Toner",iconUrl:e("Widgets/Images/ImageryProviders/stamenToner.png"),tooltip:"A high contrast black and white map.\nhttp://maps.stamen.com",creationFunction:function(){return n({url:"https://stamen-tiles.a.ssl.fastly.net/toner/",credit:"Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA."})}})),l.push(new s({name:"The Black Marble",iconUrl:e("Widgets/Images/ImageryProviders/blackMarble.png"),tooltip:"The lights of cities and villages trace the outlines of civilization in this global view of the Earth at night as seen by NASA/NOAA's Suomi NPP satellite.",creationFunction:function(){return o({url:"https://cesiumjs.org/blackmarble",flipXY:!0,credit:"Black Marble imagery courtesy NASA Earth Observatory"})}})),l.push(new s({name:"Natural Earth II",iconUrl:e("Widgets/Images/ImageryProviders/naturalEarthII.png"),tooltip:"Natural Earth II, darkened for contrast.\nhttp://www.naturalearthdata.com/",creationFunction:function(){return o({url:e("Assets/Textures/NaturalEarthII")})}})),l}return l}),define("Widgets/BaseLayerPicker/createDefaultTerrainProviderViewModels",["../../Core/buildModuleUrl","../../Core/CesiumTerrainProvider","../../Core/EllipsoidTerrainProvider","../BaseLayerPicker/ProviderViewModel"],function(e,t,r,i){"use strict";function n(){var n=[];return n.push(new i({name:"WGS84 Ellipsoid",iconUrl:e("Widgets/Images/TerrainProviders/Ellipsoid.png"),tooltip:"WGS84 standard ellipsoid, also known as EPSG:4326",creationFunction:function(){return new r}})),n.push(new i({name:"STK World Terrain meshes",iconUrl:e("Widgets/Images/TerrainProviders/STK.png"),tooltip:"High-resolution, mesh-based terrain for the entire globe. Free for use on the Internet. Closed-network options are available.\nhttp://www.agi.com",creationFunction:function(){return new t({url:"https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles",requestWaterMask:!0,requestVertexNormals:!0})}})),n}return n}),define("Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel",["../../Core/Check","../../Core/Color","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/ScreenSpaceEventHandler","../../Core/ScreenSpaceEventType","../../Scene/Cesium3DTileColorBlendMode","../../Scene/Cesium3DTileFeature","../../Scene/Cesium3DTileset","../../Scene/Cesium3DTileStyle","../../Scene/PerformanceDisplay","../../ThirdParty/knockout"],function(e,t,r,i,n,o,a,s,l,u,c,d,h){"use strict";function p(e){return function(t){var i=e._scene.pick(t.position);r(i)&&i.primitive instanceof u&&(e.tileset=i.primitive),e.pickActive=!1}}function f(e,t){t?e._eventHandler.setInputAction(function(t){var i=e._scene.pick(t.endPosition);r(i)&&i.primitive instanceof u&&(e.tileset=i.primitive)},a.MOUSE_MOVE):(e._eventHandler.removeInputAction(a.MOUSE_MOVE),e.picking=e.picking)}function m(e){var t=e/1048576;return t<1?t.toLocaleString(void 0,y):Math.round(t).toLocaleString()}function g(e,t){if(!r(e))return"";var i=e.statistics,n='<ul class="cesium-cesiumInspector-statistics">';return n+="<li><strong>Visited: </strong>"+i.visited.toLocaleString()+"</li><li><strong>Selected: </strong>"+e._selectedTiles.length.toLocaleString()+"</li><li><strong>Commands: </strong>"+i.numberOfCommands.toLocaleString()+"</li>",n+="</ul>",t||(n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Requests: </strong>"+i.numberOfPendingRequests.toLocaleString()+"</li><li><strong>Attempted: </strong>"+i.numberOfAttemptedRequests.toLocaleString()+"</li><li><strong>Processing: </strong>"+i.numberOfTilesProcessing.toLocaleString()+"</li><li><strong>Content Ready: </strong>"+i.numberOfTilesWithContentReady.toLocaleString()+"</li><li><strong>Total: </strong>"+i.numberOfTilesTotal.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Features Selected: </strong>"+i.numberOfFeaturesSelected.toLocaleString()+"</li><li><strong>Features Loaded: </strong>"+i.numberOfFeaturesLoaded.toLocaleString()+"</li><li><strong>Points Selected: </strong>"+i.numberOfPointsSelected.toLocaleString()+"</li><li><strong>Points Loaded: </strong>"+i.numberOfPointsLoaded.toLocaleString()+"</li><li><strong>Triangles Selected: </strong>"+i.numberOfTrianglesSelected.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Tiles styled: </strong>"+i.numberOfTilesStyled.toLocaleString()+"</li><li><strong>Features styled: </strong>"+i.numberOfFeaturesStyled.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Children Union Culled: </strong>"+i.numberOfTilesCulledWithChildrenUnion.toLocaleString()+"</li>",n+="</ul>",n+='<ul class="cesium-cesiumInspector-statistics">',n+="<li><strong>Geometry Memory (MB): </strong>"+m(i.geometryByteLength)+"</li><li><strong>Texture Memory (MB): </strong>"+m(i.texturesByteLength)+"</li><li><strong>Batch Table Memory (MB): </strong>"+m(i.batchTableByteLength)+"</li>",n+="</ul>"),n}function _(e,t){var i=this,n=e.canvas;this._eventHandler=new o(n),this._scene=e,this._performanceContainer=t,this._canvas=n,this._performanceDisplay=new d({container:t}),this._statisticsText="",this._pickStatisticsText="",this._editorError="",this.performance=!1,this.showStatistics=!0,this.showPickStatistics=!0,this.inspectorVisible=!0,this.tilesetVisible=!1,this.displayVisible=!1,this.updateVisible=!1,this.loggingVisible=!1,this.styleVisible=!1,this.tileDebugLabelsVisible=!1,this.optimizationVisible=!1,this.styleString="{}",this._tileset=void 0,this._feature=void 0,this._tile=void 0,h.track(this,["performance","inspectorVisible","_statisticsText","_pickStatisticsText","_editorError","showPickStatistics","showStatistics","tilesetVisible","displayVisible","updateVisible","loggingVisible","styleVisible","optimizationVisible","tileDebugLabelsVisible","styleString","_feature","_tile"]),this._properties=h.observable({}),this.properties=[],h.defineProperty(this,"properties",function(){var e=[],t=i._properties();for(var r in t)t.hasOwnProperty(r)&&e.push(r);return e});var u=h.observable();h.defineProperty(this,"dynamicScreenSpaceError",{get:function(){return u()},set:function(e){u(e),r(i._tileset)&&(i._tileset.dynamicScreenSpaceError=e)}}),this.dynamicScreenSpaceError=!1;var c=h.observable();h.defineProperty(this,"colorBlendMode",{get:function(){return c()},set:function(e){c(e),r(i._tileset)&&(i._tileset.colorBlendMode=e,i._scene.requestRender())}}),this.colorBlendMode=s.HIGHLIGHT;var m=h.observable();h.defineProperty(this,"picking",{get:function(){return m()},set:function(t){m(t),t?i._eventHandler.setInputAction(function(t){var n=e.pick(t.endPosition);if(n instanceof l?(i.feature=n,i.tile=n.content.tile):r(n)&&r(n.content)?(i.feature=void 0,i.tile=n.content.tile):(i.feature=void 0,i.tile=void 0),r(i._tileset)){if(S&&r(n)&&r(n.content)){var o;e.pickPositionSupported&&(o=e.pickPosition(t.endPosition),r(o)&&(i._tileset.debugPickPosition=o)),i._tileset.debugPickedTile=n.content.tile}else i._tileset.debugPickedTile=void 0;i._scene.requestRender()}},a.MOUSE_MOVE):(i.feature=void 0,i.tile=void 0,i._eventHandler.removeInputAction(a.MOUSE_MOVE))}}),this.picking=!0;var g=h.observable();h.defineProperty(this,"colorize",{get:function(){return g()},set:function(e){g(e),r(i._tileset)&&(i._tileset.debugColorizeTiles=e,i._scene.requestRender())}}),this.colorize=!1;var _=h.observable();h.defineProperty(this,"wireframe",{get:function(){return _()},set:function(e){_(e),r(i._tileset)&&(i._tileset.debugWireframe=e,i._scene.requestRender())}}),this.wireframe=!1;var v=h.observable();h.defineProperty(this,"showBoundingVolumes",{get:function(){return v()},set:function(e){v(e),r(i._tileset)&&(i._tileset.debugShowBoundingVolume=e,i._scene.requestRender())}}),this.showBoundingVolumes=!1;var y=h.observable();h.defineProperty(this,"showContentBoundingVolumes",{get:function(){return y()},set:function(e){y(e),r(i._tileset)&&(i._tileset.debugShowContentBoundingVolume=e,i._scene.requestRender())}}),this.showContentBoundingVolumes=!1;var b=h.observable();h.defineProperty(this,"showRequestVolumes",{get:function(){return b()},set:function(e){b(e),r(i._tileset)&&(i._tileset.debugShowViewerRequestVolume=e,i._scene.requestRender())}}),this.showRequestVolumes=!1;var C=h.observable();h.defineProperty(this,"freezeFrame",{get:function(){return C()},set:function(e){C(e),r(i._tileset)&&(i._tileset.debugFreezeFrame=e,i._scene.debugShowFrustumPlanes=e,i._scene.requestRender())}}),this.freezeFrame=!1;var S=h.observable();h.defineProperty(this,"showOnlyPickedTileDebugLabel",{get:function(){return S()},set:function(e){S(e),r(i._tileset)&&(i._tileset.debugPickedTileLabelOnly=e,i._scene.requestRender())}}),this.showOnlyPickedTileDebugLabel=!1;var w=h.observable();h.defineProperty(this,"showGeometricError",{get:function(){return w()},set:function(e){w(e),r(i._tileset)&&(i._tileset.debugShowGeometricError=e,i._scene.requestRender())}}),this.showGeometricError=!1;var T=h.observable();h.defineProperty(this,"showRenderingStatistics",{get:function(){return T()},set:function(e){T(e),r(i._tileset)&&(i._tileset.debugShowRenderingStatistics=e,i._scene.requestRender())}}),this.showRenderingStatistics=!1;var E=h.observable();h.defineProperty(this,"showMemoryUsage",{get:function(){return E()},set:function(e){E(e),r(i._tileset)&&(i._tileset.debugShowMemoryUsage=e,i._scene.requestRender())}}),this.showMemoryUsage=!1;var A=h.observable();h.defineProperty(this,"showUrl",{get:function(){return A()},set:function(e){A(e),r(i._tileset)&&(i._tileset.debugShowUrl=e,i._scene.requestRender())}}),this.showUrl=!1;var x=h.observable();h.defineProperty(this,"maximumScreenSpaceError",{get:function(){return x()},set:function(e){e=Number(e),isNaN(e)||(x(e),r(i._tileset)&&(i._tileset.maximumScreenSpaceError=e))}}),this.maximumScreenSpaceError=16;var P=h.observable();h.defineProperty(this,"dynamicScreenSpaceErrorDensity",{get:function(){return P()},set:function(e){e=Number(e),isNaN(e)||(P(e),r(i._tileset)&&(i._tileset.dynamicScreenSpaceErrorDensity=e))}}),this.dynamicScreenSpaceErrorDensity=.00278,this.dynamicScreenSpaceErrorDensitySliderValue=void 0,h.defineProperty(this,"dynamicScreenSpaceErrorDensitySliderValue",{get:function(){return Math.pow(P(),1/6)},set:function(e){P(Math.pow(e,6))}});var D=h.observable();h.defineProperty(this,"dynamicScreenSpaceErrorFactor",{get:function(){return D()},set:function(e){e=Number(e),isNaN(e)||(D(e),r(i._tileset)&&(i._tileset.dynamicScreenSpaceErrorFactor=e))}}),this.dynamicScreenSpaceErrorFactor=4;var I=p(this),O=h.observable();h.defineProperty(this,"pickActive",{get:function(){return O()},set:function(e){O(e),e?i._eventHandler.setInputAction(I,a.LEFT_CLICK):i._eventHandler.removeInputAction(a.LEFT_CLICK)}});var M=h.observable();h.defineProperty(this,"pointCloudShading",{get:function(){return M()},set:function(e){M(e),r(i._tileset)&&(i._tileset.pointCloudShading.attenuation=e)}}),this.pointCloudShading=!1;var R=h.observable();h.defineProperty(this,"geometricErrorScale",{get:function(){return R()},set:function(e){e=Number(e),isNaN(e)||(R(e),r(i._tileset)&&(i._tileset.pointCloudShading.geometricErrorScale=e))}}),this.geometricErrorScale=1;var L=h.observable();h.defineProperty(this,"maximumAttenuation",{get:function(){return L()},set:function(e){e=Number(e),isNaN(e)||(L(e),r(i._tileset)&&(i._tileset.pointCloudShading.maximumAttenuation=0===e?void 0:e))}}),this.maximumAttenuation=0;var N=h.observable();h.defineProperty(this,"baseResolution",{get:function(){return N()},set:function(e){e=Number(e),isNaN(e)||(N(e),r(i._tileset)&&(i._tileset.pointCloudShading.baseResolution=0===e?void 0:e))}}),this.baseResolution=0;var k=h.observable();h.defineProperty(this,"eyeDomeLighting",{get:function(){return k()},set:function(e){k(e),r(i._tileset)&&(i._tileset.pointCloudShading.eyeDomeLighting=e)}}),this.eyeDomeLighting=!1;var F=h.observable();h.defineProperty(this,"eyeDomeLightingStrength",{get:function(){return F()},set:function(e){e=Number(e),isNaN(e)||(F(e),r(i._tileset)&&(i._tileset.pointCloudShading.eyeDomeLightingStrength=e))}}),this.eyeDomeLightingStrength=1;var B=h.observable();h.defineProperty(this,"eyeDomeLightingRadius",{get:function(){return B()},set:function(e){e=Number(e),isNaN(e)||(B(e),r(i._tileset)&&(i._tileset.pointCloudShading.eyeDomeLightingRadius=e))}}),this.eyeDomeLightingRadius=1,this.pickActive=!1;var U=h.observable();h.defineProperty(this,"skipLevelOfDetail",{get:function(){return U()},set:function(e){U(e),r(i._tileset)&&(i._tileset.skipLevelOfDetail=e)}}),this.skipLevelOfDetail=!0;var V=h.observable();h.defineProperty(this,"skipScreenSpaceErrorFactor",{get:function(){return V()},set:function(e){e=Number(e),isNaN(e)||(V(e),r(i._tileset)&&(i._tileset.skipScreenSpaceErrorFactor=e))}}),this.skipScreenSpaceErrorFactor=16;var z=h.observable();h.defineProperty(this,"baseScreenSpaceError",{get:function(){return z()},set:function(e){e=Number(e),isNaN(e)||(z(e),r(i._tileset)&&(i._tileset.baseScreenSpaceError=e))}}),this.baseScreenSpaceError=1024;var G=h.observable();h.defineProperty(this,"skipLevels",{get:function(){return G()},set:function(e){e=Number(e),isNaN(e)||(G(e),r(i._tileset)&&(i._tileset.skipLevels=e))}}),this.skipLevels=1;var W=h.observable();h.defineProperty(this,"immediatelyLoadDesiredLevelOfDetail",{get:function(){return W()},set:function(e){W(e),r(i._tileset)&&(i._tileset.immediatelyLoadDesiredLevelOfDetail=e)}}),this.immediatelyLoadDesiredLevelOfDetail=!1;var H=h.observable();h.defineProperty(this,"loadSiblings",{get:function(){H()},set:function(e){H(e),r(i._tileset)&&(i._tileset.loadSiblings=e)}}),this.loadSiblings=!1,this._style=void 0,this._shouldStyle=!1,this._definedProperties=["properties","dynamicScreenSpaceError","colorBlendMode","picking","colorize","wireframe","showBoundingVolumes","showContentBoundingVolumes","showRequestVolumes","freezeFrame","maximumScreenSpaceError","dynamicScreenSpaceErrorDensity","baseScreenSpaceError","skipScreenSpaceErrorFactor","skipLevelOfDetail","skipLevels","immediatelyLoadDesiredLevelOfDetail","loadSiblings","dynamicScreenSpaceErrorDensitySliderValue","dynamicScreenSpaceErrorFactor","pickActive","showOnlyPickedTileDebugLabel","showGeometricError","showRenderingStatistics","showMemoryUsage","showUrl","pointCloudShading","geometricErrorScale","maximumAttenuation","baseResolution","eyeDomeLighting","eyeDomeLightingStrength","eyeDomeLightingRadius"],this._removePostRenderEvent=e.postRender.addEventListener(function(){i._update()}),r(this._tileset)||f(this,!0)}function v(e){if(e.featuresLength>0)return!0;var t=e.innerContents;if(r(t)){for(var i=t.length,n=0;n<i;++n)if(!v(t[n]))return!1;return!0}return!1}var y={maximumFractionDigits:3},b=[{text:"Highlight",value:s.HIGHLIGHT},{text:"Replace",value:s.REPLACE},{text:"Mix",value:s.MIX}],C=new t(1,1,0,.4),S=new t,w=new t;return i(_.prototype,{scene:{get:function(){return this._scene}},performanceContainer:{get:function(){return this._performanceContainer}},statisticsText:{get:function(){return this._statisticsText}},pickStatisticsText:{get:function(){return this._pickStatisticsText}},colorBlendModes:{get:function(){return b}},editorError:{get:function(){return this._editorError}},tileset:{get:function(){return this._tileset},set:function(e){if(this._tileset=e,this._style=void 0,this.styleString="{}",this.feature=void 0,this.tile=void 0,r(e)){var t=this;e.readyPromise.then(function(e){t.isDestroyed()||t._properties(e.properties)});for(var i=["colorize","wireframe","showBoundingVolumes","showContentBoundingVolumes","showRequestVolumes","freezeFrame","showOnlyPickedTileDebugLabel","showGeometricError","showRenderingStatistics","showMemoryUsage","showUrl"],n=i.length,o=0;o<n;++o){var a=i[o];this[a]=this[a]}this.maximumScreenSpaceError=e.maximumScreenSpaceError,this.dynamicScreenSpaceError=e.dynamicScreenSpaceError,this.dynamicScreenSpaceErrorDensity=e.dynamicScreenSpaceErrorDensity,this.dynamicScreenSpaceErrorFactor=e.dynamicScreenSpaceErrorFactor,this.colorBlendMode=e.colorBlendMode,this.skipLevelOfDetail=e.skipLevelOfDetail,this.skipScreenSpaceErrorFactor=e.skipScreenSpaceErrorFactor,this.baseScreenSpaceError=e.baseScreenSpaceError,this.skipLevels=e.skipLevels,this.immediatelyLoadDesiredLevelOfDetail=e.immediatelyLoadDesiredLevelOfDetail,this.loadSiblings=e.loadSiblings;var s=e.pointCloudShading;this.pointCloudShading=s.attenuation,this.geometricErrorScale=s.geometricErrorScale,this.maximumAttenuation=s.maximumAttenuation?s.maximumAttenuation:0,this.baseResolution=s.baseResolution?s.baseResolution:0,this.eyeDomeLighting=s.eyeDomeLighting,this.eyeDomeLightingStrength=s.eyeDomeLightingStrength,this.eyeDomeLightingRadius=s.eyeDomeLightingRadius,this._scene.requestRender()}else this._properties({});this._statisticsText=g(e,!1),this._pickStatisticsText=g(e,!0),f(this,!1)}},feature:{get:function(){return this._feature},set:function(e){if(this._feature!==e){var i=this._feature;if(r(i)&&!i.content.isDestroyed()){var n=this._scene.frameState;!this.colorize&&r(this._style)?i.color=r(this._style.color)?this._style.color.evaluateColor(n,i,S):t.WHITE:i.color=w,this._scene.requestRender()}r(e)&&(t.clone(e.color,w),e.color=C,this._scene.requestRender()),this._feature=e}}},tile:{get:function(){return this._tile},set:function(e){if(this._tile!==e){var i=this._tile;!r(i)||i.isDestroyed()||v(i.content)||(i.color=w,this._scene.requestRender()),r(e)&&!v(e.content)&&(t.clone(e.color,w),e.color=C,this._scene.requestRender()),this._tile=e}}}}),_.prototype.togglePickTileset=function(){this.pickActive=!this.pickActive},_.prototype.toggleInspector=function(){this.inspectorVisible=!this.inspectorVisible},_.prototype.toggleTileset=function(){this.tilesetVisible=!this.tilesetVisible},_.prototype.toggleDisplay=function(){this.displayVisible=!this.displayVisible},_.prototype.toggleUpdate=function(){this.updateVisible=!this.updateVisible},_.prototype.toggleLogging=function(){this.loggingVisible=!this.loggingVisible},_.prototype.toggleStyle=function(){this.styleVisible=!this.styleVisible},_.prototype.toggleTileDebugLabels=function(){this.tileDebugLabelsVisible=!this.tileDebugLabelsVisible},_.prototype.toggleOptimization=function(){this.optimizationVisible=!this.optimizationVisible},_.prototype.trimTilesCache=function(){r(this._tileset)&&this._tileset.trimLoadedTiles()},_.prototype.compileStyle=function(){var e=this._tileset;if(r(e)&&this.styleString!==JSON.stringify(e.style)){this._editorError="";try{0===this.styleString.length&&(this.styleString="{}"),this._style=new c(JSON.parse(this.styleString)),this._shouldStyle=!0,this._scene.requestRender()}catch(e){this._editorError=e.toString()}this.feature=this._feature,this.tile=this._tile}},_.prototype.styleEditorKeyPress=function(e,t){if(9===t.keyCode){t.preventDefault();var r,i=t.target,n=i.selectionStart,o=i.selectionEnd,a=o,s=i.value.slice(n,o),l=s.split("\n"),u=l.length;if(t.shiftKey)for(r=0;r<u;++r)" "===l[r][0]&&(" "===l[r][1]?(l[r]=l[r].substr(2),a-=2):(l[r]=l[r].substr(1),a-=1));else for(r=0;r<u;++r)l[r]=" "+l[r],a+=2;var c=l.join("\n");i.value=i.value.slice(0,n)+c+i.value.slice(o),i.selectionStart=n!==o?n:a,i.selectionEnd=a}else!t.ctrlKey||10!==t.keyCode&&13!==t.keyCode||this.compileStyle();return!0},_.prototype._update=function(){var e=this._tileset;if(this.performance&&this._performanceDisplay.update(),r(e)){if(e.isDestroyed())return this.tile=void 0,this.feature=void 0,void(this.tileset=void 0);var t=e.style;this._style!==e.style&&(this._shouldStyle?(e.style=this._style,this._shouldStyle=!1):(this._style=t,this.styleString=JSON.stringify(t.style,null," ")))}this.showStatistics&&(this._statisticsText=g(e,!1),this._pickStatisticsText=g(e,!0))},_.prototype.isDestroyed=function(){return!1},_.prototype.destroy=function(){this._eventHandler.destroy(),this._removePostRenderEvent();var e=this;return this._definedProperties.forEach(function(t){h.getObservable(e,t).dispose()}),n(this)},_.getStatistics=g,_}),define("Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector",["../../Core/Check","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../ThirdParty/knockout","../getElement","./Cesium3DTilesInspectorViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(t,r){e.defined("container",t),e.typeOf.object("scene",r),t=a(t);var i=document.createElement("div"),n=document.createElement("div");n.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : performance, "cesium-cesiumInspector-hide" : !performance}');var l=new s(r,n);this._viewModel=l,this._container=t,this._element=i;var p=document.createElement("div");p.textContent="3D Tiles Inspector",p.className="cesium-cesiumInspector-button",p.setAttribute("data-bind","click: toggleInspector"),i.appendChild(p),i.className="cesium-cesiumInspector cesium-3DTilesInspector",i.setAttribute("data-bind",'css: { "cesium-cesiumInspector-visible" : inspectorVisible, "cesium-cesiumInspector-hidden" : !inspectorVisible}'),t.appendChild(i);var f=document.createElement("div"),m=document.createElement("div"),g=document.createElement("div"),_=document.createElement("div"),v=document.createElement("div"),y=document.createElement("div"),b=document.createElement("div"),C=document.createElement("div");C.className="field-group";var S=document.createElement("label");S.className="field-label",S.appendChild(document.createTextNode("Properties: "));var w=document.createElement("div");w.setAttribute("data-bind","text: properties"),C.appendChild(S),C.appendChild(w),f.appendChild(C),f.appendChild(h("togglePickTileset","Pick Tileset","pickActive")),f.appendChild(h("trimTilesCache","Trim Tiles Cache")),f.appendChild(c("picking","Enable Picking")),m.appendChild(c("colorize","Colorize")),m.appendChild(c("wireframe","Wireframe")),m.appendChild(c("showBoundingVolumes","Bounding Volumes")),m.appendChild(c("showContentBoundingVolumes","Content Volumes")),m.appendChild(c("showRequestVolumes","Request Volumes")),m.appendChild(c("pointCloudShading","Point Cloud Shading"));var T=document.createElement("div");T.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : pointCloudShading, "cesium-cesiumInspector-hide" : !pointCloudShading}'),T.appendChild(d("geometricErrorScale",0,2,.01,"Geometric Error Scale")),T.appendChild(d("maximumAttenuation",0,32,1,"Maximum Attenuation")),T.appendChild(d("baseResolution",0,1,.01,"Base Resolution")),T.appendChild(c("eyeDomeLighting","Eye Dome Lighting (EDL)")),m.appendChild(T);var E=document.createElement("div");E.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : eyeDomeLighting, "cesium-cesiumInspector-hide" : !eyeDomeLighting}'),E.appendChild(d("eyeDomeLightingStrength",0,2,.1,"EDL Strength")),E.appendChild(d("eyeDomeLightingRadius",0,4,.1,"EDL Radius")),T.appendChild(E),g.appendChild(c("freezeFrame","Freeze Frame")),g.appendChild(c("dynamicScreenSpaceError","Dynamic Screen Space Error"));var A=document.createElement("div");A.appendChild(d("maximumScreenSpaceError",0,128,1,"Maximum Screen Space Error")),g.appendChild(A);var x=document.createElement("div");x.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : dynamicScreenSpaceError, "cesium-cesiumInspector-hide" : !dynamicScreenSpaceError}'),x.appendChild(d("dynamicScreenSpaceErrorDensitySliderValue",0,1,.005,"Screen Space Error Density","dynamicScreenSpaceErrorDensity")),x.appendChild(d("dynamicScreenSpaceErrorFactor",1,10,.1,"Screen Space Error Factor")),g.appendChild(x),_.appendChild(c("performance","Performance")),_.appendChild(n),_.appendChild(c("showStatistics","Statistics"));var P=document.createElement("div");P.className="cesium-3dTilesInspector-statistics",P.setAttribute("data-bind","html: statisticsText, visible: showStatistics"),_.appendChild(P),_.appendChild(c("showPickStatistics","Pick Statistics"));var D=document.createElement("div");D.className="cesium-3dTilesInspector-statistics",D.setAttribute("data-bind","html: pickStatisticsText, visible: showPickStatistics"),_.appendChild(D),y.appendChild(document.createTextNode("Color Blend Mode: "));var I=document.createElement("select");I.setAttribute("data-bind",'options: colorBlendModes, optionsText: "text", optionsValue: "value", value: colorBlendMode'),y.appendChild(I);var O=document.createElement("textarea");O.setAttribute("data-bind","textInput: styleString, event: { keydown: styleEditorKeyPress }"),y.className="cesium-cesiumInspector-styleEditor",y.appendChild(O);var M=h("compileStyle","Compile (Ctrl+Enter)");y.appendChild(M);var R=document.createElement("div");R.className="cesium-cesiumInspector-error",R.setAttribute("data-bind","text: editorError"),y.appendChild(R),v.appendChild(c("showOnlyPickedTileDebugLabel","Show Picked Only")),v.appendChild(c("showGeometricError","Geometric Error")),v.appendChild(c("showRenderingStatistics","Rendering Statistics")),v.appendChild(c("showMemoryUsage","Memory Usage (MB)")),v.appendChild(c("showUrl","Url")),b.appendChild(c("skipLevelOfDetail","Skip Tile LODs"));var L=document.createElement("div");L.appendChild(d("skipScreenSpaceErrorFactor",1,50,1,"Skip SSE Factor")),b.appendChild(L);var N=document.createElement("div");N.appendChild(d("baseScreenSpaceError",0,4096,1,"SSE before skipping LOD")),b.appendChild(N);var k=document.createElement("div");k.appendChild(d("skipLevels",0,10,1,"Min. levels to skip")),b.appendChild(k),b.appendChild(c("immediatelyLoadDesiredLevelOfDetail","Load only tiles that meet the max. SSE.")),b.appendChild(c("loadSiblings","Load siblings of visible tiles."));var F=u("Tileset","tilesetVisible","toggleTileset",f),B=u("Display","displayVisible","toggleDisplay",m),U=u("Update","updateVisible","toggleUpdate",g),V=u("Logging","loggingVisible","toggleLogging",_),z=u("Tile Debug Labels","tileDebugLabelsVisible","toggleTileDebugLabels",v),G=u("Style","styleVisible","toggleStyle",y),W=u("Optimization","optimizationVisible","toggleOptimization",b);i.appendChild(F),i.appendChild(B),i.appendChild(U),i.appendChild(V),i.appendChild(z),i.appendChild(G),i.appendChild(W),o.applyBindings(l,i)}function u(e,t,r,i){var n=document.createElement("span");n.className="cesium-cesiumInspector-toggleSwitch",n.setAttribute("data-bind","text: "+t+' ? "-" : "+", click: '+r);var o=document.createElement("div");o.className="cesium-cesiumInspector-sectionHeader",o.appendChild(n),o.appendChild(document.createTextNode(e));var a=document.createElement("div");a.className="cesium-cesiumInspector-section",a.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : '+t+', "cesium-cesiumInspector-hide" : !'+t+"}"),a.appendChild(i);var s=document.createElement("div");return s.className="cesium-cesiumInspector-dropDown",s.appendChild(o),s.appendChild(a),s}function c(e,t){var r=document.createElement("input");r.type="checkbox", +r.setAttribute("data-bind","checked: "+e);var i=document.createElement("div");return i.appendChild(r),i.appendChild(document.createTextNode(t)),i}function d(e,r,i,n,o,a){a=t(a,e);var s=document.createElement("input");s.setAttribute("data-bind","value: "+a),s.type="number";var l=document.createElement("input");l.type="range",l.min=r,l.max=i,l.step=n,l.setAttribute("data-bind",'valueUpdate: "input", value: '+e);var u=document.createElement("div");u.appendChild(l);var c=document.createElement("div");return c.className="cesium-cesiumInspector-slider",c.appendChild(document.createTextNode(o)),c.appendChild(s),c.appendChild(u),c}function h(e,t,i){var n=document.createElement("button");n.type="button",n.textContent=t,n.className="cesium-cesiumInspector-pickButton";var o="click: "+e;return r(i)&&(o+=', css: {"cesium-cesiumInspector-pickButtonHighlight" : '+i+"}"),n.setAttribute("data-bind",o),n}return i(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return o.cleanNode(this._element),this._container.removeChild(this._element),this.viewModel.destroy(),n(this)},l}),define("Widgets/CesiumInspector/CesiumInspectorViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Rectangle","../../Core/ScreenSpaceEventHandler","../../Core/ScreenSpaceEventType","../../Scene/DebugModelMatrixPrimitive","../../Scene/PerformanceDisplay","../../Scene/TileCoordinatesImageryProvider","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(t){var r;if(e(t)){r="Command Statistics";var i=t.commandsInFrustums;for(var n in i)if(i.hasOwnProperty(n)){var o,a=parseInt(n,10);if(7===a)o="1, 2 and 3";else{for(var s=[],l=2;l>=0;l--){var u=Math.pow(2,l);a>=u&&(s.push(l+1),a-=u)}o=s.reverse().join(" and ")}r+="<br>    "+i[n]+" in frustum "+o}r+="<br>Total: "+t.totalCommands}return r}function p(e,t,r){var i=Math.min(r,t);return i=Math.max(i,e)}function f(t,r){function i(t){var r=f._scene.pick({x:t.position.x,y:t.position.y});e(r)&&(f.primitive=e(r.collection)?r.collection:r.primitive),f._scene.requestRender(),f.pickPrimitiveActive=!1}function h(t){var r,i=_.ellipsoid,o=f._scene.camera.pickEllipsoid({x:t.position.x,y:t.position.y},i);if(e(o))for(var a=i.cartesianToCartographic(o),s=_._surface.tileProvider._tilesToRenderByTextureCount,l=0;!r&&l<s.length;++l){var u=s[l];if(e(u))for(var c=0;!r&&c<u.length;++c){var d=u[c];n.contains(d.rectangle,a)&&(r=d)}}f.tile=r,f.pickTileActive=!1}var f=this,m=t.canvas,g=new o(m);this._eventHandler=g,this._scene=t,this._canvas=m,this._primitive=void 0,this._tile=void 0,this._modelMatrixPrimitive=void 0,this._performanceDisplay=void 0,this._performanceContainer=r;var _=this._scene.globe;_.depthTestAgainstTerrain=!0,this.frustums=!1,this.frustumPlanes=!1,this.performance=!1,this.shaderCacheText="",this.primitiveBoundingSphere=!1,this.primitiveReferenceFrame=!1,this.filterPrimitive=!1,this.tileBoundingSphere=!1,this.filterTile=!1,this.wireframe=!1,this.globeDepth=!1,this.pickDepth=!1,this.depthFrustum=1,this._numberOfFrustums=1,this.suspendUpdates=!1,this.tileCoordinates=!1,this.frustumStatisticText=!1,this.tileText="",this.hasPickedPrimitive=!1,this.hasPickedTile=!1,this.pickPrimitiveActive=!1,this.pickTileActive=!1,this.dropDownVisible=!0,this.generalVisible=!0,this.primitivesVisible=!1,this.terrainVisible=!1,this.depthFrustumText="",this.generalSwitchText=c.pureComputed(function(){return f.generalVisible?"-":"+"}),this.primitivesSwitchText=c.pureComputed(function(){return f.primitivesVisible?"-":"+"}),this.terrainSwitchText=c.pureComputed(function(){return f.terrainVisible?"-":"+"}),c.track(this,["frustums","frustumPlanes","performance","shaderCacheText","primitiveBoundingSphere","primitiveReferenceFrame","filterPrimitive","tileBoundingSphere","filterTile","wireframe","globeDepth","pickDepth","depthFrustum","suspendUpdates","tileCoordinates","frustumStatisticText","tileText","hasPickedPrimitive","hasPickedTile","pickPrimitiveActive","pickTileActive","dropDownVisible","generalVisible","primitivesVisible","terrainVisible","depthFrustumText"]),this._toggleDropDown=d(function(){f.dropDownVisible=!f.dropDownVisible}),this._toggleGeneral=d(function(){f.generalVisible=!f.generalVisible}),this._togglePrimitives=d(function(){f.primitivesVisible=!f.primitivesVisible}),this._toggleTerrain=d(function(){f.terrainVisible=!f.terrainVisible}),this._frustumsSubscription=c.getObservable(this,"frustums").subscribe(function(e){f._scene.debugShowFrustums=e,f._scene.requestRender()}),this._frustumPlanesSubscription=c.getObservable(this,"frustumPlanes").subscribe(function(e){f._scene.debugShowFrustumPlanes=e,f._scene.requestRender()}),this._performanceSubscription=c.getObservable(this,"performance").subscribe(function(e){e?f._performanceDisplay=new l({container:f._performanceContainer}):f._performanceContainer.innerHTML=""}),this._showPrimitiveBoundingSphere=d(function(){return f._primitive.debugShowBoundingVolume=f.primitiveBoundingSphere,f._scene.requestRender(),!0}),this._primitiveBoundingSphereSubscription=c.getObservable(this,"primitiveBoundingSphere").subscribe(function(){f._showPrimitiveBoundingSphere()}),this._showPrimitiveReferenceFrame=d(function(){if(f.primitiveReferenceFrame){var t=f._primitive.modelMatrix;f._modelMatrixPrimitive=new s({modelMatrix:t}),f._scene.primitives.add(f._modelMatrixPrimitive)}else e(f._modelMatrixPrimitive)&&(f._scene.primitives.remove(f._modelMatrixPrimitive),f._modelMatrixPrimitive=void 0);return f._scene.requestRender(),!0}),this._primitiveReferenceFrameSubscription=c.getObservable(this,"primitiveReferenceFrame").subscribe(function(){f._showPrimitiveReferenceFrame()}),this._doFilterPrimitive=d(function(){return f.filterPrimitive?f._scene.debugCommandFilter=function(t){return!(!e(f._modelMatrixPrimitive)||t.owner!==f._modelMatrixPrimitive._primitive)||!!e(f._primitive)&&(t.owner===f._primitive||t.owner===f._primitive._billboardCollection||t.owner.primitive===f._primitive)}:f._scene.debugCommandFilter=void 0,!0}),this._filterPrimitiveSubscription=c.getObservable(this,"filterPrimitive").subscribe(function(){f._doFilterPrimitive(),f._scene.requestRender()}),this._wireframeSubscription=c.getObservable(this,"wireframe").subscribe(function(e){_._surface.tileProvider._debug.wireframe=e,f._scene.requestRender()}),this._globeDepthSubscription=c.getObservable(this,"globeDepth").subscribe(function(e){f._scene.debugShowGlobeDepth=e,f._scene.requestRender()}),this._pickDepthSubscription=c.getObservable(this,"pickDepth").subscribe(function(e){f._scene.debugShowPickDepth=e,f._scene.requestRender()}),this._depthFrustumSubscription=c.getObservable(this,"depthFrustum").subscribe(function(e){f._scene.debugShowDepthFrustum=e,f._scene.requestRender()}),this._incrementDepthFrustum=d(function(){var e=f.depthFrustum+1;return f.depthFrustum=p(1,f._numberOfFrustums,e),f._scene.requestRender(),!0}),this._decrementDepthFrustum=d(function(){var e=f.depthFrustum-1;return f.depthFrustum=p(1,f._numberOfFrustums,e),f._scene.requestRender(),!0}),this._suspendUpdatesSubscription=c.getObservable(this,"suspendUpdates").subscribe(function(e){_._surface._debug.suspendLodUpdate=e,e||(f.filterTile=!1)});var v;this._showTileCoordinates=d(function(){return f.tileCoordinates&&!e(v)?v=t.imageryLayers.addImageryProvider(new u({tilingScheme:t.terrainProvider.tilingScheme})):!f.tileCoordinates&&e(v)&&(t.imageryLayers.remove(v),v=void 0),!0}),this._tileCoordinatesSubscription=c.getObservable(this,"tileCoordinates").subscribe(function(){f._showTileCoordinates(),f._scene.requestRender()}),this._tileBoundingSphereSubscription=c.getObservable(this,"tileBoundingSphere").subscribe(function(){f._showTileBoundingSphere(),f._scene.requestRender()}),this._showTileBoundingSphere=d(function(){return f.tileBoundingSphere?_._surface.tileProvider._debug.boundingSphereTile=f._tile:_._surface.tileProvider._debug.boundingSphereTile=void 0,f._scene.requestRender(),!0}),this._doFilterTile=d(function(){return f.filterTile?(f.suspendUpdates=!0,_._surface._tilesToRender=[],e(f._tile)&&f._tile.renderable&&_._surface._tilesToRender.push(f._tile)):f.suspendUpdates=!1,!0}),this._filterTileSubscription=c.getObservable(this,"filterTile").subscribe(function(){f.doFilterTile(),f._scene.requestRender()}),this._pickPrimitive=d(function(){f.pickPrimitiveActive=!f.pickPrimitiveActive}),this._pickPrimitiveActiveSubscription=c.getObservable(this,"pickPrimitiveActive").subscribe(function(e){e?g.setInputAction(i,a.LEFT_CLICK):g.removeInputAction(a.LEFT_CLICK)}),this._pickTile=d(function(){f.pickTileActive=!f.pickTileActive}),this._pickTileActiveSubscription=c.getObservable(this,"pickTileActive").subscribe(function(e){e?g.setInputAction(h,a.LEFT_CLICK):g.removeInputAction(a.LEFT_CLICK)}),this._removePostRenderEvent=t.postRender.addEventListener(function(){f._update()})}return t(f.prototype,{scene:{get:function(){return this._scene}},performanceContainer:{get:function(){return this._performanceContainer}},toggleDropDown:{get:function(){return this._toggleDropDown}},showPrimitiveBoundingSphere:{get:function(){return this._showPrimitiveBoundingSphere}},showPrimitiveReferenceFrame:{get:function(){return this._showPrimitiveReferenceFrame}},doFilterPrimitive:{get:function(){return this._doFilterPrimitive}},incrementDepthFrustum:{get:function(){return this._incrementDepthFrustum}},decrementDepthFrustum:{get:function(){return this._decrementDepthFrustum}},showTileCoordinates:{get:function(){return this._showTileCoordinates}},showTileBoundingSphere:{get:function(){return this._showTileBoundingSphere}},doFilterTile:{get:function(){return this._doFilterTile}},toggleGeneral:{get:function(){return this._toggleGeneral}},togglePrimitives:{get:function(){return this._togglePrimitives}},toggleTerrain:{get:function(){return this._toggleTerrain}},pickPrimitive:{get:function(){return this._pickPrimitive}},pickTile:{get:function(){return this._pickTile}},selectParent:{get:function(){var e=this;return d(function(){e.tile=e.tile.parent})}},selectNW:{get:function(){var e=this;return d(function(){e.tile=e.tile.northwestChild})}},selectNE:{get:function(){var e=this;return d(function(){e.tile=e.tile.northeastChild})}},selectSW:{get:function(){var e=this;return d(function(){e.tile=e.tile.southwestChild})}},selectSE:{get:function(){var e=this;return d(function(){e.tile=e.tile.southeastChild})}},primitive:{get:function(){return this._primitive},set:function(t){var r=this._primitive;t!==r&&(this.hasPickedPrimitive=!0,e(r)&&(r.debugShowBoundingVolume=!1),this._scene.debugCommandFilter=void 0,e(this._modelMatrixPrimitive)&&(this._scene.primitives.remove(this._modelMatrixPrimitive),this._modelMatrixPrimitive=void 0),this._primitive=t,t.show=!1,setTimeout(function(){t.show=!0},50),this.showPrimitiveBoundingSphere(),this.showPrimitiveReferenceFrame(),this.doFilterPrimitive())}},tile:{get:function(){return this._tile},set:function(t){if(e(t)){this.hasPickedTile=!0;if(t!==this._tile){this.tileText="L: "+t.level+" X: "+t.x+" Y: "+t.y,this.tileText+="<br>SW corner: "+t.rectangle.west+", "+t.rectangle.south,this.tileText+="<br>NE corner: "+t.rectangle.east+", "+t.rectangle.north;var r=t.data;e(r)?this.tileText+="<br>Min: "+r.minimumHeight+" Max: "+r.maximumHeight:this.tileText+="<br>(Tile is not loaded)"}this._tile=t,this.showTileBoundingSphere(),this.doFilterTile()}else this.hasPickedTile=!1,this._tile=void 0}}}),f.prototype._update=function(){this.frustums&&(this.frustumStatisticText=h(this._scene.debugFrustumStatistics));var e=this._scene.numberOfFrustums;this._numberOfFrustums=e,this.depthFrustum=p(1,e,this.depthFrustum),this.depthFrustumText=this.depthFrustum+" of "+e,this.performance&&this._performanceDisplay.update(),this.primitiveReferenceFrame&&(this._modelMatrixPrimitive.modelMatrix=this._primitive.modelMatrix),this.shaderCacheText="Cached shaders: "+this._scene.context.shaderCache.numberOfShaders},f.prototype.isDestroyed=function(){return!1},f.prototype.destroy=function(){return this._eventHandler.destroy(),this._removePostRenderEvent(),this._frustumsSubscription.dispose(),this._frustumPlanesSubscription.dispose(),this._performanceSubscription.dispose(),this._primitiveBoundingSphereSubscription.dispose(),this._primitiveReferenceFrameSubscription.dispose(),this._filterPrimitiveSubscription.dispose(),this._wireframeSubscription.dispose(),this._globeDepthSubscription.dispose(),this._pickDepthSubscription.dispose(),this._depthFrustumSubscription.dispose(),this._suspendUpdatesSubscription.dispose(),this._tileCoordinatesSubscription.dispose(),this._tileBoundingSphereSubscription.dispose(),this._filterTileSubscription.dispose(),this._pickPrimitiveActiveSubscription.dispose(),this._pickTileActiveSubscription.dispose(),r(this)},f}),define("Widgets/CesiumInspector/CesiumInspector",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./CesiumInspectorViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){e=o(e);var r=document.createElement("div"),i=new a(t,r);this._viewModel=i,this._container=e;var s=document.createElement("div");this._element=s;var l=document.createElement("div");l.textContent="Cesium Inspector",l.className="cesium-cesiumInspector-button",l.setAttribute("data-bind","click: toggleDropDown"),s.appendChild(l),s.className="cesium-cesiumInspector",s.setAttribute("data-bind",'css: { "cesium-cesiumInspector-visible" : dropDownVisible, "cesium-cesiumInspector-hidden" : !dropDownVisible }'),e.appendChild(this._element);var u=document.createElement("div");this._panel=u,u.className="cesium-cesiumInspector-dropDown",s.appendChild(u);var c=document.createElement("div");c.className="cesium-cesiumInspector-sectionHeader";var d=document.createElement("span");d.className="cesium-cesiumInspector-toggleSwitch",d.setAttribute("data-bind","click: toggleGeneral, text: generalSwitchText"),c.appendChild(d),c.appendChild(document.createTextNode("General")),u.appendChild(c);var h=document.createElement("div");h.className="cesium-cesiumInspector-section",h.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : generalVisible, "cesium-cesiumInspector-hide" : !generalVisible}'),u.appendChild(h);var p=document.createElement("div");h.appendChild(p);var f=document.createElement("div");f.className="cesium-cesiumInspector-frustumStatistics",f.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : frustums, "cesium-cesiumInspector-hide" : !frustums}, html: frustumStatisticText');var m=document.createElement("input");m.type="checkbox",m.setAttribute("data-bind","checked: frustums"),p.appendChild(m),p.appendChild(document.createTextNode("Show Frustums")),p.appendChild(f);var g=document.createElement("div");h.appendChild(g);var _=document.createElement("input");_.type="checkbox",_.setAttribute("data-bind","checked: frustumPlanes"),g.appendChild(_),g.appendChild(document.createTextNode("Show Frustum Planes"));var v=document.createElement("div");h.appendChild(v);var y=document.createElement("input");y.type="checkbox",y.setAttribute("data-bind","checked: performance"),v.appendChild(y),v.appendChild(document.createTextNode("Performance Display")),r.className="cesium-cesiumInspector-performanceDisplay",h.appendChild(r);var b=document.createElement("div");b.className="cesium-cesiumInspector-shaderCache",b.setAttribute("data-bind","html: shaderCacheText"),h.appendChild(b);var C=document.createElement("div");h.appendChild(C);var S=document.createElement("input");S.type="checkbox",S.setAttribute("data-bind","checked: globeDepth"),C.appendChild(S),C.appendChild(document.createTextNode("Show globe depth"));var w=document.createElement("div");C.appendChild(w);var T=document.createElement("div");h.appendChild(T);var E=document.createElement("input");E.type="checkbox",E.setAttribute("data-bind","checked: pickDepth"),T.appendChild(E),T.appendChild(document.createTextNode("Show pick depth"));var A=document.createElement("div");h.appendChild(A);var x=document.createElement("span");x.setAttribute("data-bind",'html: "     Frustum:"'),A.appendChild(x);var P=document.createElement("span");P.setAttribute("data-bind","text: depthFrustumText"),A.appendChild(P);var D=document.createElement("input");D.type="button",D.value="-",D.className="cesium-cesiumInspector-pickButton",D.setAttribute("data-bind","click: decrementDepthFrustum"),A.appendChild(D);var I=document.createElement("input");I.type="button",I.value="+",I.className="cesium-cesiumInspector-pickButton",I.setAttribute("data-bind","click: incrementDepthFrustum"),A.appendChild(I);var O=document.createElement("div");O.className="cesium-cesiumInspector-sectionHeader",d=document.createElement("span"),d.className="cesium-cesiumInspector-toggleSwitch",d.setAttribute("data-bind","click: togglePrimitives, text: primitivesSwitchText"),O.appendChild(d),O.appendChild(document.createTextNode("Primitives")),u.appendChild(O);var M=document.createElement("div");M.className="cesium-cesiumInspector-section",M.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : primitivesVisible, "cesium-cesiumInspector-hide" : !primitivesVisible}'),u.appendChild(M);var R=document.createElement("div");R.className="cesium-cesiumInspector-pickSection",M.appendChild(R);var L=document.createElement("input");L.type="button",L.value="Pick a primitive",L.className="cesium-cesiumInspector-pickButton",L.setAttribute("data-bind",'css: {"cesium-cesiumInspector-pickButtonHighlight" : pickPrimitiveActive}, click: pickPrimitive');var N=document.createElement("div");N.className="cesium-cesiumInspector-center",N.appendChild(L),R.appendChild(N);var k=document.createElement("div");R.appendChild(k);var F=document.createElement("input");F.type="checkbox",F.setAttribute("data-bind","checked: primitiveBoundingSphere, enable: hasPickedPrimitive"),k.appendChild(F),k.appendChild(document.createTextNode("Show bounding sphere"));var B=document.createElement("div");R.appendChild(B);var U=document.createElement("input");U.type="checkbox",U.setAttribute("data-bind","checked: primitiveReferenceFrame, enable: hasPickedPrimitive"),B.appendChild(U),B.appendChild(document.createTextNode("Show reference frame"));var V=document.createElement("div");this._primitiveOnly=V,R.appendChild(V);var z=document.createElement("input");z.type="checkbox",z.setAttribute("data-bind","checked: filterPrimitive, enable: hasPickedPrimitive"),V.appendChild(z),V.appendChild(document.createTextNode("Show only selected"));var G=document.createElement("div");G.className="cesium-cesiumInspector-sectionHeader",d=document.createElement("span"),d.className="cesium-cesiumInspector-toggleSwitch",d.setAttribute("data-bind","click: toggleTerrain, text: terrainSwitchText"),G.appendChild(d),G.appendChild(document.createTextNode("Terrain")),u.appendChild(G);var W=document.createElement("div");W.className="cesium-cesiumInspector-section",W.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : terrainVisible, "cesium-cesiumInspector-hide" : !terrainVisible}'),u.appendChild(W);var H=document.createElement("div");H.className="cesium-cesiumInspector-pickSection",W.appendChild(H);var j=document.createElement("input");j.type="button",j.value="Pick a tile",j.className="cesium-cesiumInspector-pickButton",j.setAttribute("data-bind",'css: {"cesium-cesiumInspector-pickButtonHighlight" : pickTileActive}, click: pickTile'),N=document.createElement("div"),N.appendChild(j),N.className="cesium-cesiumInspector-center",H.appendChild(N);var q=document.createElement("div");H.appendChild(q);var Y=document.createElement("input");Y.type="button",Y.value="Parent",Y.className="cesium-cesiumInspector-pickButton",Y.setAttribute("data-bind","click: selectParent");var X=document.createElement("input");X.type="button",X.value="NW",X.className="cesium-cesiumInspector-pickButton",X.setAttribute("data-bind","click: selectNW");var Q=document.createElement("input");Q.type="button",Q.value="NE",Q.className="cesium-cesiumInspector-pickButton",Q.setAttribute("data-bind","click: selectNE");var Z=document.createElement("input");Z.type="button",Z.value="SW",Z.className="cesium-cesiumInspector-pickButton",Z.setAttribute("data-bind","click: selectSW");var K=document.createElement("input");K.type="button",K.value="SE",K.className="cesium-cesiumInspector-pickButton",K.setAttribute("data-bind","click: selectSE");var J=document.createElement("div");J.className="cesium-cesiumInspector-tileText",q.className="cesium-cesiumInspector-frustumStatistics",q.appendChild(J),q.setAttribute("data-bind",'css: {"cesium-cesiumInspector-show" : hasPickedTile, "cesium-cesiumInspector-hide" : !hasPickedTile}'),J.setAttribute("data-bind","html: tileText");var $=document.createElement("div");$.className="cesium-cesiumInspector-relativeText",$.textContent="Select relative:",q.appendChild($);var ee=document.createElement("table"),te=document.createElement("tr"),re=document.createElement("tr"),ie=document.createElement("td");ie.appendChild(Y);var ne=document.createElement("td");ne.appendChild(X);var oe=document.createElement("td");oe.appendChild(Q),te.appendChild(ie),te.appendChild(ne),te.appendChild(oe);var ae=document.createElement("td"),se=document.createElement("td");se.appendChild(Z);var le=document.createElement("td");le.appendChild(K),re.appendChild(ae),re.appendChild(se),re.appendChild(le),ee.appendChild(te),ee.appendChild(re),q.appendChild(ee);var ue=document.createElement("div");H.appendChild(ue);var ce=document.createElement("input");ce.type="checkbox",ce.setAttribute("data-bind","checked: tileBoundingSphere, enable: hasPickedTile"),ue.appendChild(ce),ue.appendChild(document.createTextNode("Show bounding volume"));var de=document.createElement("div");H.appendChild(de);var he=document.createElement("input");he.type="checkbox",he.setAttribute("data-bind","checked: filterTile, enable: hasPickedTile"),de.appendChild(he),de.appendChild(document.createTextNode("Show only selected"));var pe=document.createElement("div");W.appendChild(pe);var fe=document.createElement("input");fe.type="checkbox",fe.setAttribute("data-bind","checked: wireframe"),pe.appendChild(fe),pe.appendChild(document.createTextNode("Wireframe"));var me=document.createElement("div");W.appendChild(me);var ge=document.createElement("input");ge.type="checkbox",ge.setAttribute("data-bind","checked: suspendUpdates"),me.appendChild(ge),me.appendChild(document.createTextNode("Suspend LOD update"));var _e=document.createElement("div");W.appendChild(_e);var ve=document.createElement("input");ve.type="checkbox",ve.setAttribute("data-bind","checked: tileCoordinates"),_e.appendChild(ve),_e.appendChild(document.createTextNode("Show tile coordinates")),n.applyBindings(i,this._element)}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return n.cleanNode(this._element),this._container.removeChild(this._element),this.viewModel.destroy(),r(this)},s});define("Widgets/CesiumWidget/CesiumWidget",["../../Core/buildModuleUrl","../../Core/Cartesian3","../../Core/Clock","../../Core/Credit","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Ellipsoid","../../Core/FeatureDetection","../../Core/formatError","../../Core/requestAnimationFrame","../../Core/ScreenSpaceEventHandler","../../Scene/BingMapsImageryProvider","../../Scene/Globe","../../Scene/Moon","../../Scene/Scene","../../Scene/SceneMode","../../Scene/ShadowMode","../../Scene/SkyAtmosphere","../../Scene/SkyBox","../../Scene/Sun","../getElement"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w){"use strict";function T(t){return e("Assets/Textures/SkyBox/tycho2t3_80_"+t+".jpg")}function E(e){function t(i){if(!e.isDestroyed())if(e._useDefaultRenderLoop)try{var n=e._targetFrameRate;if(o(n)){var a=1e3/n,s=i-r;s>a&&(e.resize(),e.render(),r=i-s%a),h(t)}else e.resize(),e.render(),h(t)}catch(t){if(e._useDefaultRenderLoop=!1,e._renderLoopRunning=!1,e._showRenderLoopErrors){e.showErrorPanel("An error occurred while rendering. Rendering has stopped.",void 0,t)}}else e._renderLoopRunning=!1}e._renderLoopRunning=!0;var r=0;h(t)}function A(e){var t=e._canvas,r=t.clientWidth,i=t.clientHeight,o=e._resolutionScale;e._supportsImageRenderingPixelated||(o*=n(window.devicePixelRatio,1)),e._canvasWidth=r,e._canvasHeight=i,r*=o,i*=o,t.width=r,t.height=i,e._canRender=0!==r&&0!==i}function x(e){var t=e._canvas,r=t.width,i=t.height;if(0!==r&&0!==i){var n=e._scene.camera.frustum;o(n.aspectRatio)?n.aspectRatio=r/i:(n.top=n.right*(i/r),n.bottom=-n.top)}}function P(e,a){e=w(e),a=n(a,{});var s=document.createElement("div");s.className="cesium-widget",e.appendChild(s);var l=document.createElement("canvas"),d=c.supportsImageRenderingPixelated();this._supportsImageRenderingPixelated=d,d&&(l.style.imageRendering=c.imageRenderingValue()),l.oncontextmenu=function(){return!1},l.onselectstart=function(){return!1},s.appendChild(l);var h=document.createElement("div");h.className="cesium-widget-credits";var E=o(a.creditContainer)?w(a.creditContainer):s;E.appendChild(h);var P=o(a.creditViewport)?w(a.creditViewport):s,I=n(a.showRenderLoopErrors,!0);this._element=s,this._container=e,this._canvas=l,this._canvasWidth=0,this._canvasHeight=0,this._creditViewport=P,this._creditContainer=E,this._innerCreditContainer=h,this._canRender=!1,this._renderLoopRunning=!1,this._showRenderLoopErrors=I,this._resolutionScale=1,this._forceResize=!1,this._clock=o(a.clock)?a.clock:new r,A(this);try{var O=new _({canvas:l,contextOptions:a.contextOptions,creditContainer:h,creditViewport:P,mapProjection:a.mapProjection,orderIndependentTranslucency:a.orderIndependentTranslucency,scene3DOnly:n(a.scene3DOnly,!1),terrainExaggeration:a.terrainExaggeration,shadows:a.shadows,mapMode2D:a.mapMode2D,requestRenderMode:a.requestRenderMode,maximumRenderTimeChange:a.maximumRenderTimeChange});this._scene=O,O.camera.constrainedAxis=t.UNIT_Z,x(this);var M=n(O.mapProjection.ellipsoid,u.WGS84),R=O.frameState.creditDisplay,L=new i({text:"Cesium",imageUrl:D,link:"https://cesiumjs.org/",showOnScreen:!0});R.addDefaultCredit(L);var N=a.globe;o(N)||(N=new m(M)),!1!==N&&(O.globe=N,O.globe.shadows=n(a.terrainShadows,y.RECEIVE_ONLY));var k=a.skyBox;o(k)||(k=new C({sources:{positiveX:T("px"),negativeX:T("mx"),positiveY:T("py"),negativeY:T("my"),positiveZ:T("pz"),negativeZ:T("mz")}})),!1!==k&&(O.skyBox=k,O.sun=new S,O.moon=new g);var F=a.skyAtmosphere;o(F)||(F=new b(M)),!1!==F&&(O.skyAtmosphere=F);var B=!1!==a.globe&&a.imageryProvider;o(B)||(B=new f({url:"https://dev.virtualearth.net"})),!1!==B&&O.imageryLayers.addImageryProvider(B),o(a.terrainProvider)&&!1!==a.globe&&(O.terrainProvider=a.terrainProvider),this._screenSpaceEventHandler=new p(l,!1),o(a.sceneMode)&&(a.sceneMode===v.SCENE2D&&this._scene.morphTo2D(0),a.sceneMode===v.COLUMBUS_VIEW&&this._scene.morphToColumbusView(0)),this._useDefaultRenderLoop=void 0,this.useDefaultRenderLoop=n(a.useDefaultRenderLoop,!0),this._targetFrameRate=void 0,this.targetFrameRate=a.targetFrameRate;var U=this;O.renderError.addEventListener(function(e,t){if(U._useDefaultRenderLoop=!1,U._renderLoopRunning=!1,U._showRenderLoopErrors){U.showErrorPanel("An error occurred while rendering. Rendering has stopped.",void 0,t)}})}catch(e){if(I){this.showErrorPanel("Error constructing CesiumWidget.",'Visit <a href="http://get.webgl.org">http://get.webgl.org</a> to verify that your web browser and hardware support WebGL. Consider trying a different web browser or updating your video drivers. Detailed error information is below:',e)}throw e}} +var D="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAeCAYAAAD5AOomAAAQWUlEQVR42u1beXxOxxpudrEktkbUkriI4lZpq5JbW6pJuFG0qrFeexVRak3TBm3RUgS1hFhrCdKgQWKLrUGQBiVBJMgiq0Qiuyxzn/fzTu74ZPnS9nfrj4zf8/ty5sw7M+c8824zx0svVa3oAfqAAWAIGAHGCoy43oDb6TGqywta9JgsIq4GUAswB+oDDRXU5/ragCm3N6gm+MUkVJ+1kAg1AyyA5oAN8BrQCXiTfzsArwLWgCVQF6jJBOtXk/tikWrMGkiEtgTeAOyBfsAQS0vL8YMHD/aws7ObiuthwAeAA/A20AZozAvCRNHe6vI3k2rCprUp8DoR1qVLF1c/P7+A5OTkhyUlJaKwuETkPSkRBUUlgkpmZmbW2bNnQyZOnLgA7Z2BzkALNtM1qsl9MTSVSLUCugADAwMDTxKZVI7cfCw8DiWK6fselMLtlwSxJyxDPM4vFsXFxSWRkZFRkBsOdAdaAw2qyf37ij77RDMm1a5evXojY2NjH5BW7ruaIab4xotPd8cJV/xO0cKkPXGae97n0kR6TpHIzs7O7d279xdsvoncemwJqn3u/1lbDTnqfYXN6JCUlJS03CfFwt0/4TkiK8IEEBydWiBIy21tbaejr24cWJlpBVT6ShpVFvS10iddZP6MbFkyqpw2Kor6K5P9M33onG1Iv0omsz3Q//79+7HpuUViDsys697KyZy89ynk9Wc/x4u7DwvE48ePs2mRcARtqUTLRjxmDa6rpYWanDqZKHmyzJ+lTFlyUrZGGbIm3GdF49VQcnMjZUwTJW83Ua4NtayQmlEYKW1NlOc11RrLoAxLpqdYUSmnPlOlbk1qa21OZ7ovX758E/lTz1MpOmvp5gvp4qeL6c8sAjLNOQXF4sKFC6Hotw+nSrR46rAfb8hkN+WxVTTlyPplNuNmDArGGgFNgGZloClbHQtua8bj1eW+GnObZspY2nL1WKaOkreraKDk7jXLsEJGXG+u1b4Bz/0VZayyUkO5f2DCc5DvyZL/1inb0ONVU5+1dSBMcHrIvRwNMbqQ6u6fKGSZ4POszFaQDZNc0q9fvzkcjFkzKf/gfJjSo3c40OrBoL+7cvvXeUFYM17l1MuOTbxEV8a/uE8pZ8Ww4bouPJ62bFlyzXmebRg2jLY8jxa8WGopxEiX9jLff1Vp357zfluefyeOPxpp9WHAGl2fn/k1do+Ef/K86lYWs+hzJ7SSbXv06OFGAfAMRLtlBUjkPyfuidMyw3Fi37UM8TMCLFVj6W9qW1BYIg4ePBjEWkukdCTyZsyYMcvX13f7iRMnDv36669B0OxTBKRNx4OCggIPHDiwa+XKld+j7Xv84v/l4+Oz6PLlywHnzp07Su0gdyw4OPgYXQNHzp8/f+TixYuHw8LCDuDeGiaLXqLj6tWrlyLC9ztz5gy1PwEcV3AU89i3detWT2NjYyeWedvLy2va77//7hcREeHfsWPH91HX6/r16/7h4eH+6H+ZVtQvN3ToujXm9wPJYS6+FhYWzggmh4eGhh6hsTHnE/j7eN++fQczWY1Yc6WrIVJb0SLEu9iJ93I0JCTkKMY+PHLkSGe2MLV5TL3ytgxr88pwuHLlyvXY9CcaH6mSR5HwwRuPRWZekTgXnfPcfW0QqfMDk0Qc+nqCnDc+Pj6FNzJoE+PfeDEXhQ6FtD0rKyu9Tp06LpAbBN9/S+hYEJmnck79EazQA5myVTKeyM/Pp7jgI2AAXv4JeW/AgAGzUTdKXj969CiOF04T1jhj/qXrzrgfQ+0KUdq1azdt6tSpntrjxcTEUGroyBrdkLmoy3x0HT9+vIe2zIoVK9y5fT0eU688/2rOJqY/bTRcjsl5hqRPYF5P38nSdJrwMErzezMpX1NfHrELjiQ9fbl56SIjO5leViH6nwwMnjZt2gL5EmWh/Lf4f+U5BtauXbsJshPu3LkTLQl/+PBhVmpqagZ+HxHS0tLSCShpGRkZqXhp12i8RYsWrVP7wr1ctM9E2wy0lch88uRJoWwTFRV1A7JjoVnBss7BwWEJ6ubIa/SRgOt32VybKduvZILtMbd4JraoZcuWC8eMGbNN+7noWTt06DCVXUIL9rtNOdj8uABFW+bbb7/9js34y4o5fo5YI14h7QwNDV1yc3MLAsIfP0PS9kvpmg6Db+wXn6/pKrwOztBcn7mTXWbEPHlPvMguKBFFxYXiq819hZu3k6Y9xpgFjN+xY8cBOcmkpKQ0rh8HDCUieHNjHExgmGwHQomkKbdu3bpP10VFRcU2NjZ7UbcKWATMB74C3IBpSn8jTp48eVb2k5iYSNq4BVjJcl8zFrq5ue3Py8vLB/Kg4USa6+nTp0OkLNwUmfYFckGiTRJZH1YKc3Zp5mye+yQnJydQOyyYImtr65XDhw/3lX2B7BJlgaSxhXiL+6K99z4wwadkG/RRLP/28PBYxpaiES+mcokllW4PczcUz1Twy++ZpSTRrhJtUCSnx4gvNzkL9419xBfevUVIxEHNIEuDUp4j90ZCHjSqUHj+/AnaOmnkmFgyIa6Y8Hk5SScnp6VMwLs82Tc5wOkJv9Tfz89v3f79+73xMPTyJyrEloCI8+PGjTs0adIkX1dXVx+Yuu2ff/75tlmzZm1A+xUDBw6kHHo4/GqQHA8Lt9DT0/OSu7v70SlTpuwdMmTIFhC2tlmzZivQ9geAtOFLgLRoGhbFJSnbrVu3DahbrEXs+4pZrMm/FGj1xaJNlMRaWVmtGTZs2D7ZV3R0dA6sWJG8Riayhd1GNzbNo0nTpWWbP3/+dYXY5fyOLCsjti5Hbh/hwfODbmeVkkS5rCgpFgt2DNaQKjHTy16kZsRpBpp1IKE0uNoSkqapO3llp2YBUFuPLf01Jgf9007UFAQCv8lJmpubf4Y6J478rNgMWfHL6cRBE+1e9SXTKInVpdy7d+8KmbOhQ4d+rasMLRjML5xMLlkSBFShCrEbiXxJLDQymQ8/2rN/lKkJXQ+AdUiSxDZv3nydSuzNmzczQWaEvIZbeESuhhf5mLt375Y+Z0BAQDQW7Dl5PXfu3KW6EGvIfoEisL6Ya+p1aBz5z/N3czQdbQ5w12ieSizhu13DEPHmajYiKDXyPJmiaX8t6pSYs8FB04bM8ObAL2ijIg/9zyCtU4lFBDqJA6p2nE/KPLMVmyRbToGcq0osAq0rrFEu8Eve5IfJhOsiCxN8FXJzjx07FqYQ6426JZJYaGQKu463eO4W/EvXLiqx0Ni1MMV+ig9PR5ut0PosWbd582bKHL50cXHZIOMMGqtJkybrQWZpEDdv3rwfdCHWgCM5yo3s/f39j9G8H2Y/tRKXbgUItw2Oz5EqSfMJWvT0dCefA5PsVPHNTx+VtpkFzb4Ve0ncuHHjLq/I0UhJSv1W27Zt57F/6cpp0Gv8awfz6Lxq1ar5P/7448KxY8eSH/5UNcUffPBBQKdOnTZ37tx5la2t7VI7O7vv33nnnYUwrR6Ojo7TEIm6sFkjckfxwvIAaMyvTE1NPRC4LEFQtAH9+yOVSFYiXvLFC48ePXpF1nXv3n09mWqF2Ie4/oTHeIM19Q2+/iQhISFVIXb1iBEj9irWhCL2pXPmzPlF9aOoW4+gL13W7d69+ywtMASApe1glhez2yqXWJnH1uDVRv5tpMY0PE4Qu4IWlkmoNlb6TRKRcaHiQoS/+Ir9sMTCnYM1q27NmjW+tIqJxMOHDwfISe7bty8YdZ8pZ7r9aZOEruE7F2lFqZ+pwRNI8WG/SGTNZuKm8gIawlrusGDBgi+wsEJ+Q8Fq38W+fg7LkHv4hoKwUaNGlWoFLEwuEatqrL29PQVq86TW5+Tk5LP8aDK9PN4AvnaXPhKBbSEW6bLRo0fvkH3FxsYmcaA3m6JzWR8ZGVlKKmUoHAhORFywSysqfqui4Enbz1JE5nz16tXwrNx0nUh9Gkw5QTPfFbPX93pWo6Hpp6740EqkVOc/lNzTZgM0cKVq9qAdmSlPS5IEHjaN8h7Z5iAKpUt48LsyTYCGPcBc7+L3DvLi2xEREYSbt2/fDkdwci0sLOwwRZfbt29frmhFIdpEgehIkqFfRN9RQAzmkSvbQdvIzLqdOnWqNN+GFaAoeircVYr68rHoohG138KYN+mXji1Rny1NKeKWXDMzM/cJEyZskHIPUMiX0ntp06aNm5riSYsA0+zLpn6Ql5fXRnl/8eLFX7NVsygv3VHNcU3ev+xC23800NlrvqUBUFVBckv3jNZMBNHnSvajr/OEHLDaM3X1lSCjoFGjRmRKhyGoiKziBgWZRWf0kSeqUGbOnOlJmod44Iys+/DDD8kiuMAULlMXXWUFUfkhIhB9LpZ1WBwxHBDSexmIBXFTlcHCeMQuqidh586dK+S91atXu3EkXp83KPQrOt0xZq2loMVh2bJlmmT6+OVt0MT3qkiqk1jsM0LkFWQL0iI2rx2UjXfyo73gPzZCu64iyIhHYJMMJU2RoJ0ikBiOiNBn0KBBY/gB7UNDQ3/B/QTcT1SRmpqaQEA/D3A/HtoXGxcXd07uy3bt2nUQSPKHJkbLthIsnwifGY/5/oZ0gnxwb5ojTPG6jIyMGCySBCz4gTJKnz59+szg4OBAjBEFkuIg+wxQojHXszD983hx9Zw8efI4EBZHgFYHsjnV7JdjfkMw50R+hnikauM4QKJspb23t/dkuAeaR9ySJUuG8Lusw9ZWr7KvEU15N4P2Lt9HZKjZdTkeuk3MRcpSVmT8DKEbe2vaePlPFyX4B8IoHfiYH6AJJ+/m7PRtuL47r9revJfch/92YDK78Hxas0xHDrTeU2R6c8rkWIZcK/5mqx1vondnWUeWUdGL++7EL9SG5Tooc2ihFbH3VPpzVOZgz4ugI6durVjLpNV6lRd5Y/5tx3Puxv3Kzf5G3KaFcpjQvCqfHKmH7Y15An3hqDeRWaZo1+fkIjFjXQ9NKiNNNJFJvpR87JLdI8X95HCNj6CjOtrJ4uituXLUZKwk8pbKCUpr5fSkNZNhxe6hIbeXR3bNFBlttOKX0Izb1mfZhtyXFcu20kFOfmZrwQteHtXJI8AmvKfbUulPLiRrTtvk8WFdPhyw4P4b8DupxZrXgOfXTHnmOvyu5P6x/NxX7nIZVuXA3Yg7asyrxoG+RER4HoMorzj/SY64ijw18OIm4Xd2uTh4fq04f+OASEy7pyGUvrqYPXv2CvYfb/JEzbUOlA342lR5MDNFo+UZam1+MBPlgNuU69X25mXI1lIO6qVsTUXWrAK5GloH49qH3Ophf21l/mZlzL2G1gG9aTkfEJgoHwDU1LpvqIxZ0eG8TuTKM8VWbCKcoYGj1q1btwehegJtPVIuSVEmnd8iQDhtbW3tamxs/CGbs7a8OOooDr68z1QMlQdUH0b7kxX1sxbDSmBQzqcoBpXIGJQjo/1ZSmVzqaivyvozqOB96f+Z78b0lLPFumwabFgDe3K+NpDz0kH8rXEvNrttWUvr6/DRuJ6O+CMyf0a2Ku+pqn390Xt/6QduBopPNFe2zFrJaI2dfmv2XZbsz2op5qL6v3m8oF8vqv9/R/oB+Q1RPf41U3yT0R+x/9Xlryn/BY268qsf3smdAAAAAElFTkSuQmCC";return a(P.prototype,{container:{get:function(){return this._container}},canvas:{get:function(){return this._canvas}},creditContainer:{get:function(){return this._creditContainer}},creditViewport:{get:function(){return this._creditViewport}},scene:{get:function(){return this._scene}},imageryLayers:{get:function(){return this._scene.imageryLayers}},terrainProvider:{get:function(){return this._scene.terrainProvider},set:function(e){this._scene.terrainProvider=e}},camera:{get:function(){return this._scene.camera}},clock:{get:function(){return this._clock}},screenSpaceEventHandler:{get:function(){return this._screenSpaceEventHandler}},targetFrameRate:{get:function(){return this._targetFrameRate},set:function(e){this._targetFrameRate=e}},useDefaultRenderLoop:{get:function(){return this._useDefaultRenderLoop},set:function(e){this._useDefaultRenderLoop!==e&&(this._useDefaultRenderLoop=e,e&&!this._renderLoopRunning&&E(this))}},resolutionScale:{get:function(){return this._resolutionScale},set:function(e){this._resolutionScale=e,this._forceResize=!0}}}),P.prototype.showErrorPanel=function(e,t,r){function i(){u.style.maxHeight=Math.max(Math.round(.9*n.clientHeight-100),30)+"px"}var n=this._element,a=document.createElement("div");a.className="cesium-widget-errorPanel";var s=document.createElement("div");s.className="cesium-widget-errorPanel-content",a.appendChild(s);var l=document.createElement("div");l.className="cesium-widget-errorPanel-header",l.appendChild(document.createTextNode(e)),s.appendChild(l);var u=document.createElement("div");if(u.className="cesium-widget-errorPanel-scroll",s.appendChild(u),i(),o(window.addEventListener)&&window.addEventListener("resize",i,!1),o(t)){var c=document.createElement("div");c.className="cesium-widget-errorPanel-message",c.innerHTML="<p>"+t+"</p>",u.appendChild(c)}var h="(no error details available)";o(r)&&(h=d(r));var p=document.createElement("div");p.className="cesium-widget-errorPanel-message",p.appendChild(document.createTextNode(h)),u.appendChild(p);var f=document.createElement("div");f.className="cesium-widget-errorPanel-buttonPanel",s.appendChild(f);var m=document.createElement("button");m.setAttribute("type","button"),m.className="cesium-button",m.appendChild(document.createTextNode("OK")),m.onclick=function(){o(i)&&o(window.removeEventListener)&&window.removeEventListener("resize",i,!1),n.removeChild(a)},f.appendChild(m),n.appendChild(a),"undefined"!=typeof console&&console.error(e+"\n"+t+"\n"+h)},P.prototype.isDestroyed=function(){return!1},P.prototype.destroy=function(){this._scene=this._scene&&this._scene.destroy(),this._container.removeChild(this._element),this._creditContainer.removeChild(this._innerCreditContainer),s(this)},P.prototype.resize=function(){var e=this._canvas,t=e.clientWidth,r=e.clientHeight;(this._forceResize||this._canvasWidth!==t||this._canvasHeight!==r)&&(this._forceResize=!1,A(this),x(this),this._scene.requestRender())},P.prototype.render=function(){if(this._canRender){this._scene.initializeFrame();var e=this._clock.tick();this._scene.render(e)}else this._clock.tick()},P}),define("Widgets/ClockViewModel",["../Core/Clock","../Core/defined","../Core/defineProperties","../Core/destroyObject","../Core/EventHelper","../Core/JulianDate","../ThirdParty/knockout"],function(e,t,r,i,n,o,a){"use strict";function s(r){t(r)||(r=new e),this._clock=r,this._eventHelper=new n,this._eventHelper.add(r.onTick,this.synchronize,this),this.systemTime=a.observable(o.now()),this.systemTime.equalityComparer=o.equals,this.startTime=a.observable(r.startTime),this.startTime.equalityComparer=o.equals,this.startTime.subscribe(function(e){r.startTime=e,this.synchronize()},this),this.stopTime=a.observable(r.stopTime),this.stopTime.equalityComparer=o.equals,this.stopTime.subscribe(function(e){r.stopTime=e,this.synchronize()},this),this.currentTime=a.observable(r.currentTime),this.currentTime.equalityComparer=o.equals,this.currentTime.subscribe(function(e){r.currentTime=e,this.synchronize()},this),this.multiplier=a.observable(r.multiplier),this.multiplier.subscribe(function(e){r.multiplier=e,this.synchronize()},this),this.clockStep=a.observable(r.clockStep),this.clockStep.subscribe(function(e){r.clockStep=e,this.synchronize()},this),this.clockRange=a.observable(r.clockRange),this.clockRange.subscribe(function(e){r.clockRange=e,this.synchronize()},this),this.canAnimate=a.observable(r.canAnimate),this.canAnimate.subscribe(function(e){r.canAnimate=e,this.synchronize()},this),this.shouldAnimate=a.observable(r.shouldAnimate),this.shouldAnimate.subscribe(function(e){r.shouldAnimate=e,this.synchronize()},this),a.track(this,["systemTime","startTime","stopTime","currentTime","multiplier","clockStep","clockRange","canAnimate","shouldAnimate"])}return r(s.prototype,{clock:{get:function(){return this._clock}}}),s.prototype.synchronize=function(){var e=this._clock;this.systemTime=o.now(),this.startTime=e.startTime,this.stopTime=e.stopTime,this.currentTime=e.currentTime,this.multiplier=e.multiplier,this.clockStep=e.clockStep,this.clockRange=e.clockRange,this.canAnimate=e.canAnimate,this.shouldAnimate=e.shouldAnimate},s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){this._eventHelper.removeAll(),i(this)},s}),define("Widgets/Command",["../Core/DeveloperError"],function(e){"use strict";function t(){this.canExecute=void 0,this.beforeExecute=void 0,this.afterExecute=void 0,e.throwInstantiationError()}return t}),define("Widgets/FullscreenButton/FullscreenButtonViewModel",["../../Core/defaultValue","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Fullscreen","../../ThirdParty/knockout","../createCommand","../getElement"],function(e,t,r,i,n,o,a,s){"use strict";function l(t){var r=this,i=o.observable(n.fullscreen),l=o.observable(n.enabled);this.isFullscreen=void 0,o.defineProperty(this,"isFullscreen",{get:function(){return i()}}),this.isFullscreenEnabled=void 0,o.defineProperty(this,"isFullscreenEnabled",{get:function(){return l()},set:function(e){l(e&&n.enabled)}}),this.tooltip=void 0,o.defineProperty(this,"tooltip",function(){return this.isFullscreenEnabled?i()?"Exit full screen":"Full screen":"Full screen unavailable"}),this._command=a(function(){n.fullscreen?n.exitFullscreen():n.requestFullscreen(r._fullscreenElement)},o.getObservable(this,"isFullscreenEnabled")),this._fullscreenElement=e(s(t),document.body),this._callback=function(){i(n.fullscreen)},document.addEventListener(n.changeEventName,this._callback)}return t(l.prototype,{fullscreenElement:{get:function(){return this._fullscreenElement},set:function(e){this._fullscreenElement=e}},command:{get:function(){return this._command}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){document.removeEventListener(n.changeEventName,this._callback),r(this)},l}),define("Widgets/FullscreenButton/FullscreenButton",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./FullscreenButtonViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){e=o(e);var r=new a(t);r._exitFullScreenPath=u,r._enterFullScreenPath=l;var i=document.createElement("button");i.type="button",i.className="cesium-button cesium-fullscreenButton",i.setAttribute("data-bind","attr: { title: tooltip },click: command,enable: isFullscreenEnabled,cesiumSvgPath: { path: isFullscreen ? _exitFullScreenPath : _enterFullScreenPath, width: 128, height: 128 }"),e.appendChild(i),n.applyBindings(r,i),this._container=e,this._viewModel=r,this._element=i}var l="M 83.96875 17.5625 L 83.96875 17.59375 L 76.65625 24.875 L 97.09375 24.96875 L 76.09375 45.96875 L 81.9375 51.8125 L 102.78125 30.9375 L 102.875 51.15625 L 110.15625 43.875 L 110.1875 17.59375 L 83.96875 17.5625 z M 44.125 17.59375 L 17.90625 17.625 L 17.9375 43.90625 L 25.21875 51.1875 L 25.3125 30.96875 L 46.15625 51.8125 L 52 45.96875 L 31 25 L 51.4375 24.90625 L 44.125 17.59375 z M 46.0625 76.03125 L 25.1875 96.875 L 25.09375 76.65625 L 17.8125 83.9375 L 17.8125 110.21875 L 44 110.25 L 51.3125 102.9375 L 30.90625 102.84375 L 51.875 81.875 L 46.0625 76.03125 z M 82 76.15625 L 76.15625 82 L 97.15625 103 L 76.71875 103.0625 L 84.03125 110.375 L 110.25 110.34375 L 110.21875 84.0625 L 102.9375 76.8125 L 102.84375 97 L 82 76.15625 z",u="M 104.34375 17.5625 L 83.5 38.4375 L 83.40625 18.21875 L 76.125 25.5 L 76.09375 51.78125 L 102.3125 51.8125 L 102.3125 51.78125 L 109.625 44.5 L 89.1875 44.40625 L 110.1875 23.40625 L 104.34375 17.5625 z M 23.75 17.59375 L 17.90625 23.4375 L 38.90625 44.4375 L 18.5 44.53125 L 25.78125 51.8125 L 52 51.78125 L 51.96875 25.53125 L 44.6875 18.25 L 44.625 38.46875 L 23.75 17.59375 z M 25.6875 76.03125 L 18.375 83.3125 L 38.78125 83.40625 L 17.8125 104.40625 L 23.625 110.25 L 44.5 89.375 L 44.59375 109.59375 L 51.875 102.3125 L 51.875 76.0625 L 25.6875 76.03125 z M 102.375 76.15625 L 76.15625 76.1875 L 76.1875 102.4375 L 83.46875 109.71875 L 83.5625 89.53125 L 104.40625 110.375 L 110.25 104.53125 L 89.25 83.53125 L 109.6875 83.46875 L 102.375 76.15625 z";return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this._viewModel.destroy(),n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/Geocoder/GeocoderViewModel",["../../Core/BingMapsGeocoderService","../../Core/CartographicGeocoderService","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/Event","../../Core/Matrix4","../../ThirdParty/knockout","../../ThirdParty/when","../createCommand","../getElement"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(n){i(n.geocoderServices)?this._geocoderServices=n.geocoderServices:this._geocoderServices=[new t,new e({scene:n.scene})],this._viewContainer=n.container,this._scene=n.scene,this._flightDuration=n.flightDuration,this._searchText="",this._isSearchInProgress=!1,this._geocodePromise=void 0,this._complete=new a,this._suggestions=[],this._selectedSuggestion=void 0,this._showSuggestions=!0,this._updateCamera=m,this._adjustSuggestionsScroll=v,this._updateSearchSuggestions=S,this._handleArrowDown=f,this._handleArrowUp=p;var o=this;this._suggestionsVisible=l.pureComputed(function(){var e=l.getObservable(o,"_suggestions"),t=e().length>0,r=l.getObservable(o,"_showSuggestions")();return t&&r}),this._searchCommand=c(function(){if(o._focusTextbox=!1,i(o._selectedSuggestion))return o.activateSuggestion(o._selectedSuggestion),!1;o.hideSuggestions(),o.isSearchInProgress?y(o):_(o,o._geocoderServices)}),this.deselectSuggestion=function(){o._selectedSuggestion=void 0},this.handleKeyDown=function(e,t){var r="ArrowDown"===t.key||"Down"===t.key||40===t.keyCode,i="ArrowUp"===t.key||"Up"===t.key||38===t.keyCode;return(r||i)&&t.preventDefault(),!0},this.handleKeyUp=function(e,t){var r="ArrowDown"===t.key||"Down"===t.key||40===t.keyCode,i="ArrowUp"===t.key||"Up"===t.key||38===t.keyCode,n="Enter"===t.key||13===t.keyCode;return i?p(o):r?f(o):n&&o._searchCommand(),!0},this.activateSuggestion=function(e){o.hideSuggestions(),o._searchText=e.displayName;var t=e.destination;C(o),m(o,t)},this.hideSuggestions=function(){o._showSuggestions=!1,o._selectedSuggestion=void 0},this.showSuggestions=function(){o._showSuggestions=!0},this.handleMouseover=function(e,t){e!==o._selectedSuggestion&&(o._selectedSuggestion=e)},this.keepExpanded=!1,this.autoComplete=r(n.autocomplete,!0),this._focusTextbox=!1,l.track(this,["_searchText","_isSearchInProgress","keepExpanded","_suggestions","_selectedSuggestion","_showSuggestions","_focusTextbox"]);var s=l.getObservable(this,"_searchText");s.extend({rateLimit:{timeout:500}}),this._suggestionSubscription=s.subscribe(function(){S(o)}),this.isSearchInProgress=void 0,l.defineProperty(this,"isSearchInProgress",{get:function(){return this._isSearchInProgress}}),this.searchText=void 0,l.defineProperty(this,"searchText",{get:function(){return this.isSearchInProgress?"Searching...":this._searchText},set:function(e){this._searchText=e}}),this.flightDuration=void 0,l.defineProperty(this,"flightDuration",{get:function(){return this._flightDuration},set:function(e){this._flightDuration=e}})}function p(e){if(0!==e._suggestions.length){var t,r=e._suggestions.indexOf(e._selectedSuggestion);if(-1===r||0===r)return void(e._selectedSuggestion=void 0);t=r-1,e._selectedSuggestion=e._suggestions[t],v(e,t)}}function f(e){if(0!==e._suggestions.length){var t=e._suggestions.length,r=e._suggestions.indexOf(e._selectedSuggestion),i=(r+1)%t;e._selectedSuggestion=e._suggestions[i],v(e,i)}}function m(e,t){e._scene.camera.flyTo({destination:t,complete:function(){e._complete.raiseEvent()},duration:e._flightDuration,endTransform:s.IDENTITY})}function g(e,t,r){return e.then(function(e){return i(e)&&"fulfilled"===e.state&&e.value.length>0?e:t.geocode(r).then(function(e){return{state:"fulfilled",value:e}}).otherwise(function(e){return{state:"rejected",reason:e}})})}function _(e,t){var r=e._searchText;if(b(r))return void e.showSuggestions();e._isSearchInProgress=!0;for(var n=u.resolve(),o=0;o<t.length;o++)n=g(n,t[o],r);e._geocodePromise=n,n.then(function(t){if(!n.cancel){e._isSearchInProgress=!1;var o=t.value;if("fulfilled"===t.state&&i(o)&&o.length>0)return e._searchText=o[0].displayName,void m(e,o[0].destination);e._searchText=r+" (not found)"}})}function v(e,t){var r=d(e._viewContainer),i=r.getElementsByClassName("search-results")[0],n=r.getElementsByTagName("li"),o=n[t];if(0===t)return void(i.scrollTop=0);var a=o.offsetTop;a+o.clientHeight>i.clientHeight?i.scrollTop=a+o.clientHeight:a<i.scrollTop&&(i.scrollTop=a)}function y(e){e._isSearchInProgress=!1,i(e._geocodePromise)&&(e._geocodePromise.cancel=!0,e._geocodePromise=void 0)}function b(e){return/^\s*$/.test(e)}function C(e){l.getObservable(e,"_suggestions").removeAll()}function S(e){if(e.autoComplete){var t=e._searchText;if(C(e),!b(t)){var r=u.resolve([]);e._geocoderServices.forEach(function(e){r=r.then(function(r){return r.length>=5?r:e.geocode(t).then(function(e){return r=r.concat(e)})})}),r.then(function(t){for(var r=e._suggestions,i=0;i<t.length;i++)r.push(t[i])})}}}return n(h.prototype,{complete:{get:function(){return this._complete}},scene:{get:function(){return this._scene}},search:{get:function(){return this._searchCommand}},selectedSuggestion:{get:function(){return this._selectedSuggestion}},suggestions:{get:function(){return this._suggestions}}}),h.prototype.destroy=function(){this._suggestionSubscription.dispose()},h}),define("Widgets/Geocoder/Geocoder",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./GeocoderViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e){var t=a(e.container),r=new s(e);r._startSearchPath=u,r._stopSearchPath=c;var i=document.createElement("form");i.setAttribute("data-bind","submit: search");var l=document.createElement("input");l.type="search",l.className="cesium-geocoder-input",l.setAttribute("placeholder","Enter an address or landmark..."),l.setAttribute("data-bind",'textInput: searchText,disable: isSearchInProgress,event: { keyup: handleKeyUp, keydown: handleKeyDown, mouseover: deselectSuggestion },css: { "cesium-geocoder-input-wide" : keepExpanded || searchText.length > 0 },hasFocus: _focusTextbox'),this._onTextBoxFocus=function(){setTimeout(function(){l.select()},0)},l.addEventListener("focus",this._onTextBoxFocus,!1),i.appendChild(l),this._textBox=l;var d=document.createElement("span");d.className="cesium-geocoder-searchButton",d.setAttribute("data-bind","click: search,cesiumSvgPath: { path: isSearchInProgress ? _stopSearchPath : _startSearchPath, width: 32, height: 32 }"),i.appendChild(d),t.appendChild(i);var h=document.createElement("div");h.className="search-results",h.setAttribute("data-bind","visible: _suggestionsVisible");var p=document.createElement("ul");p.setAttribute("data-bind","foreach: _suggestions");var f=document.createElement("li");p.appendChild(f),f.setAttribute("data-bind","text: $data.displayName, click: $parent.activateSuggestion, event: { mouseover: $parent.handleMouseover}, css: { active: $data === $parent._selectedSuggestion }"),h.appendChild(p),t.appendChild(h),o.applyBindings(r,i),o.applyBindings(r,h),this._container=t,this._searchSuggestionsContainer=h,this._viewModel=r,this._form=i,this._onInputBegin=function(e){t.contains(e.target)||(r._focusTextbox=!1,r.hideSuggestions())},this._onInputEnd=function(e){t.contains(e.target)&&(r._focusTextbox=!0,r.showSuggestions())},n.supportsPointerEvents()?(document.addEventListener("pointerdown",this._onInputBegin,!0),document.addEventListener("pointerup",this._onInputEnd,!0),document.addEventListener("pointercancel",this._onInputEnd,!0)):(document.addEventListener("mousedown",this._onInputBegin,!0),document.addEventListener("mouseup",this._onInputEnd,!0),document.addEventListener("touchstart",this._onInputBegin,!0),document.addEventListener("touchend",this._onInputEnd,!0),document.addEventListener("touchcancel",this._onInputEnd,!0))}var u="M29.772,26.433l-7.126-7.126c0.96-1.583,1.523-3.435,1.524-5.421C24.169,8.093,19.478,3.401,13.688,3.399C7.897,3.401,3.204,8.093,3.204,13.885c0,5.789,4.693,10.481,10.484,10.481c1.987,0,3.839-0.563,5.422-1.523l7.128,7.127L29.772,26.433zM7.203,13.885c0.006-3.582,2.903-6.478,6.484-6.486c3.579,0.008,6.478,2.904,6.484,6.486c-0.007,3.58-2.905,6.476-6.484,6.484C10.106,20.361,7.209,17.465,7.203,13.885z",c="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z";return t(l.prototype,{container:{get:function(){return this._container}},searchSuggestionsContainer:{get:function(){return this._searchSuggestionsContainer}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return n.supportsPointerEvents()?(document.removeEventListener("pointerdown",this._onInputBegin,!0),document.removeEventListener("pointerup",this._onInputEnd,!0)):(document.removeEventListener("mousedown",this._onInputBegin,!0),document.removeEventListener("mouseup",this._onInputEnd,!0),document.removeEventListener("touchstart",this._onInputBegin,!0),document.removeEventListener("touchend",this._onInputEnd,!0)),this._viewModel.destroy(),o.cleanNode(this._form),o.cleanNode(this._searchSuggestionsContainer),this._container.removeChild(this._form),this._container.removeChild(this._searchSuggestionsContainer),this._textBox.removeEventListener("focus",this._onTextBoxFocus,!1),r(this)},l}),define("Widgets/HomeButton/HomeButtonViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n){"use strict";function o(e,t){this._scene=e,this._duration=t;var r=this;this._command=n(function(){r._scene.camera.flyHome(r._duration)}),this.tooltip="View Home",i.track(this,["tooltip"])}return t(o.prototype,{scene:{get:function(){return this._scene}},command:{get:function(){return this._command}},duration:{get:function(){return this._duration},set:function(e){this._duration=e}}}),o}),define("Widgets/HomeButton/HomeButton",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./HomeButtonViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t,r){e=o(e);var i=new a(t,r);i._svgPath="M14,4l-10,8.75h20l-4.25-3.7188v-4.6562h-2.812v2.1875l-2.938-2.5625zm-7.0938,9.906v10.094h14.094v-10.094h-14.094zm2.1876,2.313h3.3122v4.25h-3.3122v-4.25zm5.8442,1.281h3.406v6.438h-3.406v-6.438z";var s=document.createElement("button");s.type="button",s.className="cesium-button cesium-toolbar-button cesium-home-button",s.setAttribute("data-bind","attr: { title: tooltip },click: command,cesiumSvgPath: { path: _svgPath, width: 28, height: 28 }"),e.appendChild(s),n.applyBindings(i,s),this._container=e,this._viewModel=i,this._element=s}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/InfoBox/InfoBoxViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/Event","../../ThirdParty/knockout"],function(e,t,r,i){"use strict";function n(){this._cameraClicked=new r,this._closeClicked=new r,this.maxHeight=500,this.enableCamera=!1,this.isCameraTracking=!1,this.showInfo=!1,this.titleText="",this.description="",i.track(this,["showInfo","titleText","description","maxHeight","enableCamera","isCameraTracking"]),this._loadingIndicatorHtml='<div class="cesium-infoBox-loadingContainer"><span class="cesium-infoBox-loading"></span></div>',this.cameraIconPath=void 0,i.defineProperty(this,"cameraIconPath",{get:function(){return!this.enableCamera||this.isCameraTracking?a:o}}),i.defineProperty(this,"_bodyless",{get:function(){return!e(this.description)||0===this.description.length}})}var o="M 13.84375 7.03125 C 11.412798 7.03125 9.46875 8.975298 9.46875 11.40625 L 9.46875 11.59375 L 2.53125 7.21875 L 2.53125 24.0625 L 9.46875 19.6875 C 9.4853444 22.104033 11.423165 24.0625 13.84375 24.0625 L 25.875 24.0625 C 28.305952 24.0625 30.28125 22.087202 30.28125 19.65625 L 30.28125 11.40625 C 30.28125 8.975298 28.305952 7.03125 25.875 7.03125 L 13.84375 7.03125 z",a="M 27.34375 1.65625 L 5.28125 27.9375 L 8.09375 30.3125 L 30.15625 4.03125 L 27.34375 1.65625 z M 13.84375 7.03125 C 11.412798 7.03125 9.46875 8.975298 9.46875 11.40625 L 9.46875 11.59375 L 2.53125 7.21875 L 2.53125 24.0625 L 9.46875 19.6875 C 9.4724893 20.232036 9.5676108 20.7379 9.75 21.21875 L 21.65625 7.03125 L 13.84375 7.03125 z M 28.21875 7.71875 L 14.53125 24.0625 L 25.875 24.0625 C 28.305952 24.0625 30.28125 22.087202 30.28125 19.65625 L 30.28125 11.40625 C 30.28125 9.8371439 29.456025 8.4902779 28.21875 7.71875 z";return n.prototype.maxHeightOffset=function(e){return this.maxHeight-e+"px"},t(n.prototype,{cameraClicked:{get:function(){return this._cameraClicked}},closeClicked:{get:function(){return this._closeClicked}}}),n}),define("Widgets/InfoBox/InfoBox",["../../Core/buildModuleUrl","../../Core/Check","../../Core/Color","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../ThirdParty/knockout","../getElement","../subscribeAndEvaluate","./InfoBoxViewModel"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t){t=s(t);var n=document.createElement("div");n.className="cesium-infoBox",n.setAttribute("data-bind",'css: { "cesium-infoBox-visible" : showInfo, "cesium-infoBox-bodyless" : _bodyless }'),t.appendChild(n);var o=document.createElement("div");o.className="cesium-infoBox-title",o.setAttribute("data-bind","text: titleText"),n.appendChild(o);var c=document.createElement("button");c.type="button",c.className="cesium-button cesium-infoBox-camera",c.setAttribute("data-bind",'attr: { title: "Focus camera on object" },click: function () { cameraClicked.raiseEvent(this); },enable: enableCamera,cesiumSvgPath: { path: cameraIconPath, width: 32, height: 32 }'),n.appendChild(c);var d=document.createElement("button");d.type="button",d.className="cesium-infoBox-close",d.setAttribute("data-bind","click: function () { closeClicked.raiseEvent(this); }"),d.innerHTML="×",n.appendChild(d);var h=document.createElement("iframe");h.className="cesium-infoBox-iframe",h.setAttribute("sandbox","allow-same-origin allow-popups allow-forms"),h.setAttribute("data-bind","style : { maxHeight : maxHeightOffset(40) }"),h.setAttribute("allowfullscreen",!0),n.appendChild(h);var p=new u;a.applyBindings(p,n),this._container=t,this._element=n,this._frame=h,this._viewModel=p,this._descriptionSubscription=void 0;var f=this;h.addEventListener("load",function(){var t=h.contentDocument,o=t.createElement("link");o.href=e("Widgets/InfoBox/InfoBoxDescription.css"),o.rel="stylesheet",o.type="text/css";var a=t.createElement("div");a.className="cesium-infoBox-description",t.head.appendChild(o),t.body.appendChild(a),f._descriptionSubscription=l(p,"description",function(e){h.style.height="5px",a.innerHTML=e;var t=null,o=a.firstElementChild;if(null!==o&&1===a.childNodes.length){var s=window.getComputedStyle(o);if(null!==s){var l=s["background-color"],u=r.fromCssColorString(l);i(u)&&0!==u.alpha&&(t=s["background-color"])}}n.style["background-color"]=t;var c=a.getBoundingClientRect().height;h.style.height=c+"px"})}),h.setAttribute("src","about:blank")}return n(c.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}},frame:{get:function(){return this._frame}}}),c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){var e=this._container;return a.cleanNode(this._element),e.removeChild(this._element),i(this._descriptionSubscription)&&this._descriptionSubscription.dispose(),o(this)},c}),define("Widgets/NavigationHelpButton/NavigationHelpButtonViewModel",["../../Core/defineProperties","../../ThirdParty/knockout","../createCommand"],function(e,t,r){"use strict";function i(){this.showInstructions=!1;var e=this;this._command=r(function(){e.showInstructions=!e.showInstructions}),this._showClick=r(function(){e._touch=!1}),this._showTouch=r(function(){e._touch=!0}),this._touch=!1,this.tooltip="Navigation Instructions",t.track(this,["tooltip","showInstructions","_touch"])}return e(i.prototype,{command:{get:function(){return this._command}},showClick:{get:function(){return this._showClick}},showTouch:{get:function(){return this._showTouch}}}),i}),define("Widgets/NavigationHelpButton/NavigationHelpButton",["../../Core/buildModuleUrl","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./NavigationHelpButtonViewModel"],function(e,t,r,i,n,o,a,s,l,u){ +"use strict";function c(r){var i=l(r.container),n=new u,o=t(r.instructionsInitiallyVisible,!1);n.showInstructions=o,n._svgPath="M16,1.466C7.973,1.466,1.466,7.973,1.466,16c0,8.027,6.507,14.534,14.534,14.534c8.027,0,14.534-6.507,14.534-14.534C30.534,7.973,24.027,1.466,16,1.466z M17.328,24.371h-2.707v-2.596h2.707V24.371zM17.328,19.003v0.858h-2.707v-1.057c0-3.19,3.63-3.696,3.63-5.963c0-1.034-0.924-1.826-2.134-1.826c-1.254,0-2.354,0.924-2.354,0.924l-1.541-1.915c0,0,1.519-1.584,4.137-1.584c2.487,0,4.796,1.54,4.796,4.136C21.156,16.208,17.328,16.627,17.328,19.003z";var c=document.createElement("span");c.className="cesium-navigationHelpButton-wrapper",i.appendChild(c);var d=document.createElement("button");d.type="button",d.className="cesium-button cesium-toolbar-button cesium-navigation-help-button",d.setAttribute("data-bind","attr: { title: tooltip },click: command,cesiumSvgPath: { path: _svgPath, width: 32, height: 32 }"),c.appendChild(d);var h=document.createElement("div");h.className="cesium-navigation-help",h.setAttribute("data-bind",'css: { "cesium-navigation-help-visible" : showInstructions}'),c.appendChild(h);var p=document.createElement("button");p.type="button",p.className="cesium-navigation-button cesium-navigation-button-left",p.setAttribute("data-bind",'click: showClick, css: {"cesium-navigation-button-selected": !_touch, "cesium-navigation-button-unselected": _touch}');var f=document.createElement("img");f.src=e("Widgets/Images/NavigationHelp/Mouse.svg"),f.className="cesium-navigation-button-icon",f.style.width="25px",f.style.height="25px",p.appendChild(f),p.appendChild(document.createTextNode("Mouse"));var m=document.createElement("button");m.type="button",m.className="cesium-navigation-button cesium-navigation-button-right",m.setAttribute("data-bind",'click: showTouch, css: {"cesium-navigation-button-selected": _touch, "cesium-navigation-button-unselected": !_touch}');var g=document.createElement("img");g.src=e("Widgets/Images/NavigationHelp/Touch.svg"),g.className="cesium-navigation-button-icon",g.style.width="25px",g.style.height="25px",m.appendChild(g),m.appendChild(document.createTextNode("Touch")),h.appendChild(p),h.appendChild(m);var _=document.createElement("div");_.className="cesium-click-navigation-help cesium-navigation-help-instructions",_.setAttribute("data-bind",'css: { "cesium-click-navigation-help-visible" : !_touch}'),_.innerHTML=' <table> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/MouseLeft.svg")+'" width="48" height="48" /></td> <td> <div class="cesium-navigation-help-pan">Pan view</div> <div class="cesium-navigation-help-details">Left click + drag</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/MouseRight.svg")+'" width="48" height="48" /></td> <td> <div class="cesium-navigation-help-zoom">Zoom view</div> <div class="cesium-navigation-help-details">Right click + drag, or</div> <div class="cesium-navigation-help-details">Mouse wheel scroll</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/MouseMiddle.svg")+'" width="48" height="48" /></td> <td> <div class="cesium-navigation-help-rotate">Rotate view</div> <div class="cesium-navigation-help-details">Middle click + drag, or</div> <div class="cesium-navigation-help-details">CTRL + Left/Right click + drag</div> </td> </tr> </table>',h.appendChild(_);var v=document.createElement("div");v.className="cesium-touch-navigation-help cesium-navigation-help-instructions",v.setAttribute("data-bind",'css: { "cesium-touch-navigation-help-visible" : _touch}'),v.innerHTML=' <table> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchDrag.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-pan">Pan view</div> <div class="cesium-navigation-help-details">One finger drag</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchZoom.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-zoom">Zoom view</div> <div class="cesium-navigation-help-details">Two finger pinch</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchTilt.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-rotate">Tilt view</div> <div class="cesium-navigation-help-details">Two finger drag, same direction</div> </td> </tr> <tr> <td><img src="'+e("Widgets/Images/NavigationHelp/TouchRotate.svg")+'" width="70" height="48" /></td> <td> <div class="cesium-navigation-help-tilt">Rotate view</div> <div class="cesium-navigation-help-details">Two finger drag, opposite direction</div> </td> </tr> </table>',h.appendChild(v),s.applyBindings(n,c),this._container=i,this._viewModel=n,this._wrapper=c,this._closeInstructions=function(e){c.contains(e.target)||(n.showInstructions=!1)},a.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeInstructions,!0):(document.addEventListener("mousedown",this._closeInstructions,!0),document.addEventListener("touchstart",this._closeInstructions,!0))}return i(c.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),c.prototype.isDestroyed=function(){return!1},c.prototype.destroy=function(){return a.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeInstructions,!0):(document.removeEventListener("mousedown",this._closeInstructions,!0),document.removeEventListener("touchstart",this._closeInstructions,!0)),s.cleanNode(this._wrapper),this._container.removeChild(this._wrapper),n(this)},c}),define("Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Scene/FrameRateMonitor","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s){"use strict";function l(t){this._scene=t.scene,this.lowFrameRateMessage=e(t.lowFrameRateMessage,"This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers."),this.lowFrameRateMessageDismissed=!1,this.showingLowFrameRateMessage=!1,a.track(this,["lowFrameRateMessage","lowFrameRateMessageDismissed","showingLowFrameRateMessage"]);var r=this;this._dismissMessage=s(function(){r.showingLowFrameRateMessage=!1,r.lowFrameRateMessageDismissed=!0});var i=o.fromScene(t.scene);this._unsubscribeLowFrameRate=i.lowFrameRate.addEventListener(function(){r.lowFrameRateMessageDismissed||(r.showingLowFrameRateMessage=!0)}),this._unsubscribeNominalFrameRate=i.nominalFrameRate.addEventListener(function(){r.showingLowFrameRateMessage=!1})}return r(l.prototype,{scene:{get:function(){return this._scene}},dismissMessage:{get:function(){return this._dismissMessage}}}),l.prototype.destroy=function(){return this._unsubscribeLowFrameRate(),this._unsubscribeNominalFrameRate(),i(this)},l}),define("Widgets/PerformanceWatchdog/PerformanceWatchdog",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./PerformanceWatchdogViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e){var t=o(e.container),r=new a(e),i=document.createElement("div");i.className="cesium-performance-watchdog-message-area",i.setAttribute("data-bind","visible: showingLowFrameRateMessage");var s=document.createElement("button");s.setAttribute("type","button"),s.className="cesium-performance-watchdog-message-dismiss",s.innerHTML="×",s.setAttribute("data-bind","click: dismissMessage"),i.appendChild(s);var l=document.createElement("div");l.className="cesium-performance-watchdog-message",l.setAttribute("data-bind","html: lowFrameRateMessage"),i.appendChild(l),t.appendChild(i),n.applyBindings(r,i),this._container=t,this._viewModel=r,this._element=i}return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this._viewModel.destroy(),n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/ProjectionPicker/ProjectionPickerViewModel",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/EventHelper","../../Core/OrthographicFrustum","../../Scene/SceneMode","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t){this._scene=t,this._orthographic=t.camera.frustum instanceof o,this._flightInProgress=!1,this.dropDownVisible=!1,this.tooltipPerspective="Perspective Projection",this.tooltipOrthographic="Orthographic Projection",this.selectedTooltip=void 0,this.sceneMode=t.mode,s.track(this,["_orthographic","_flightInProgress","sceneMode","dropDownVisible","tooltipPerspective","tooltipOrthographic"]);var r=this;s.defineProperty(this,"selectedTooltip",function(){return r._orthographic?r.tooltipOrthographic:r.tooltipPerspective}),this._toggleDropDown=l(function(){r.sceneMode===a.SCENE2D||r._flightInProgress||(r.dropDownVisible=!r.dropDownVisible)}),this._eventHelper=new n,this._eventHelper.add(t.morphComplete,function(e,t,i,n){r.sceneMode=i,r._orthographic=i===a.SCENE2D||r._scene.camera.frustum instanceof o}),this._eventHelper.add(t.preRender,function(){r._flightInProgress=e(t.camera._currentFlight)}),this._switchToPerspective=l(function(){r.sceneMode!==a.SCENE2D&&(r._scene.camera.switchToPerspectiveFrustum(),r._orthographic=!1,r.dropDownVisible=!1)}),this._switchToOrthographic=l(function(){r.sceneMode!==a.SCENE2D&&(r._scene.camera.switchToOrthographicFrustum(),r._orthographic=!0,r.dropDownVisible=!1)}),this._sceneMode=a}return t(u.prototype,{scene:{get:function(){return this._scene}},toggleDropDown:{get:function(){return this._toggleDropDown}},switchToPerspective:{get:function(){return this._switchToPerspective}},switchToOrthographic:{get:function(){return this._switchToOrthographic}},isOrthographicProjection:{get:function(){return this._orthographic}}}),u.prototype.isDestroyed=function(){return!1},u.prototype.destroy=function(){this._eventHelper.removeAll(),r(this)},u}),define("Widgets/ProjectionPicker/ProjectionPicker",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./ProjectionPickerViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t){e=a(e);var r=new s(t);r._perspectivePath=u,r._orthographicPath=c;var i=document.createElement("span");i.className="cesium-projectionPicker-wrapper cesium-toolbar-button",e.appendChild(i);var l=document.createElement("button");l.type="button",l.className="cesium-button cesium-toolbar-button",l.setAttribute("data-bind",'css: { "cesium-projectionPicker-buttonPerspective": !_orthographic, "cesium-projectionPicker-buttonOrthographic": _orthographic, "cesium-button-disabled" : sceneMode === _sceneMode.SCENE2D || _flightInProgress, "cesium-projectionPicker-selected": dropDownVisible },attr: { title: selectedTooltip },click: toggleDropDown'),l.innerHTML='\x3c!-- ko cesiumSvgPath: { path: _perspectivePath, width: 64, height: 64, css: "cesium-projectionPicker-iconPerspective" } --\x3e\x3c!-- /ko --\x3e\x3c!-- ko cesiumSvgPath: { path: _orthographicPath, width: 64, height: 64, css: "cesium-projectionPicker-iconOrthographic" } --\x3e\x3c!-- /ko --\x3e',i.appendChild(l);var d=document.createElement("button");d.type="button",d.className="cesium-button cesium-toolbar-button cesium-projectionPicker-dropDown-icon",d.setAttribute("data-bind",'css: { "cesium-projectionPicker-visible" : (dropDownVisible && _orthographic), "cesium-projectionPicker-none" : !_orthographic, "cesium-projectionPicker-hidden" : !dropDownVisible },attr: { title: tooltipPerspective },click: switchToPerspective,cesiumSvgPath: { path: _perspectivePath, width: 64, height: 64 }'),i.appendChild(d);var h=document.createElement("button");h.type="button",h.className="cesium-button cesium-toolbar-button cesium-projectionPicker-dropDown-icon",h.setAttribute("data-bind",'css: { "cesium-projectionPicker-visible" : (dropDownVisible && !_orthographic), "cesium-projectionPicker-none" : _orthographic, "cesium-projectionPicker-hidden" : !dropDownVisible},attr: { title: tooltipOrthographic },click: switchToOrthographic,cesiumSvgPath: { path: _orthographicPath, width: 64, height: 64 }'),i.appendChild(h),o.applyBindings(r,i),this._viewModel=r,this._container=e,this._wrapper=i,this._closeDropDown=function(e){i.contains(e.target)||(r.dropDownVisible=!1)},n.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeDropDown,!0):(document.addEventListener("mousedown",this._closeDropDown,!0),document.addEventListener("touchstart",this._closeDropDown,!0))}var u="M 28.15625,10.4375 9.125,13.21875 13.75,43.25 41.75,55.09375 50.8125,37 54.5,11.9375 z m 0.125,3 19.976451,0.394265 L 43.03125,16.875 22.6875,14.28125 z M 50.971746,15.705477 47.90625,36.03125 42.53125,46 44.84375,19.3125 z M 12.625,16.03125 l 29.15625,3.6875 -2.65625,31 L 16.4375,41.125 z",c="m 31.560594,6.5254438 -20.75,12.4687502 0.1875,24.5625 22.28125,11.8125 19.5,-12 0.65625,-0.375 0,-0.75 0.0312,-23.21875 z m 0.0625,3.125 16.65625,9.5000002 -16.125,10.28125 -17.34375,-9.71875 z m 18.96875,11.1875002 0.15625,20.65625 -17.46875,10.59375 0.15625,-20.28125 z m -37.0625,1.25 17.21875,9.625 -0.15625,19.21875 -16.9375,-9 z";return t(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._viewModel.destroy(),n.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeDropDown,!0):(document.removeEventListener("mousedown",this._closeDropDown,!0),document.removeEventListener("touchstart",this._closeDropDown,!0)),o.cleanNode(this._wrapper),this._container.removeChild(this._wrapper),r(this)},l}),define("Widgets/SceneModePicker/SceneModePickerViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/EventHelper","../../Scene/SceneMode","../../ThirdParty/knockout","../createCommand"],function(e,t,r,i,n,o,a,s,l){"use strict";function u(t,r){this._scene=t;var i=this,n=function(e,t,r,n){i.sceneMode=r,i.dropDownVisible=!1};this._eventHelper=new o,this._eventHelper.add(t.morphStart,n),this._duration=e(r,2),this.sceneMode=t.mode,this.dropDownVisible=!1,this.tooltip2D="2D",this.tooltip3D="3D",this.tooltipColumbusView="Columbus View",s.track(this,["sceneMode","dropDownVisible","tooltip2D","tooltip3D","tooltipColumbusView"]),this.selectedTooltip=void 0,s.defineProperty(this,"selectedTooltip",function(){var e=i.sceneMode;return e===a.SCENE2D?i.tooltip2D:e===a.SCENE3D?i.tooltip3D:i.tooltipColumbusView}),this._toggleDropDown=l(function(){i.dropDownVisible=!i.dropDownVisible}),this._morphTo2D=l(function(){t.morphTo2D(i._duration)}),this._morphTo3D=l(function(){t.morphTo3D(i._duration)}),this._morphToColumbusView=l(function(){t.morphToColumbusView(i._duration)}),this._sceneMode=a}return r(u.prototype,{scene:{get:function(){return this._scene}},duration:{get:function(){return this._duration},set:function(e){this._duration=e}},toggleDropDown:{get:function(){return this._toggleDropDown}},morphTo2D:{get:function(){return this._morphTo2D}},morphTo3D:{get:function(){return this._morphTo3D}},morphToColumbusView:{get:function(){return this._morphToColumbusView}}}),u.prototype.isDestroyed=function(){return!1},u.prototype.destroy=function(){this._eventHelper.removeAll(),i(this)},u}),define("Widgets/SceneModePicker/SceneModePicker",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/FeatureDetection","../../ThirdParty/knockout","../getElement","./SceneModePickerViewModel"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t,r){e=a(e);var i=new s(t,r);i._globePath=u,i._flatMapPath=c,i._columbusViewPath=d;var l=document.createElement("span");l.className="cesium-sceneModePicker-wrapper cesium-toolbar-button",e.appendChild(l);var h=document.createElement("button");h.type="button",h.className="cesium-button cesium-toolbar-button",h.setAttribute("data-bind",'css: { "cesium-sceneModePicker-button2D": sceneMode === _sceneMode.SCENE2D, "cesium-sceneModePicker-button3D": sceneMode === _sceneMode.SCENE3D, "cesium-sceneModePicker-buttonColumbusView": sceneMode === _sceneMode.COLUMBUS_VIEW, "cesium-sceneModePicker-selected": dropDownVisible },attr: { title: selectedTooltip },click: toggleDropDown'),h.innerHTML='\x3c!-- ko cesiumSvgPath: { path: _globePath, width: 64, height: 64, css: "cesium-sceneModePicker-slide-svg cesium-sceneModePicker-icon3D" } --\x3e\x3c!-- /ko --\x3e\x3c!-- ko cesiumSvgPath: { path: _flatMapPath, width: 64, height: 64, css: "cesium-sceneModePicker-slide-svg cesium-sceneModePicker-icon2D" } --\x3e\x3c!-- /ko --\x3e\x3c!-- ko cesiumSvgPath: { path: _columbusViewPath, width: 64, height: 64, css: "cesium-sceneModePicker-slide-svg cesium-sceneModePicker-iconColumbusView" } --\x3e\x3c!-- /ko --\x3e',l.appendChild(h);var p=document.createElement("button");p.type="button",p.className="cesium-button cesium-toolbar-button cesium-sceneModePicker-dropDown-icon",p.setAttribute("data-bind",'css: { "cesium-sceneModePicker-visible" : (dropDownVisible && (sceneMode !== _sceneMode.SCENE3D)) || (!dropDownVisible && (sceneMode === _sceneMode.SCENE3D)), "cesium-sceneModePicker-none" : sceneMode === _sceneMode.SCENE3D, "cesium-sceneModePicker-hidden" : !dropDownVisible },attr: { title: tooltip3D },click: morphTo3D,cesiumSvgPath: { path: _globePath, width: 64, height: 64 }'),l.appendChild(p);var f=document.createElement("button");f.type="button",f.className="cesium-button cesium-toolbar-button cesium-sceneModePicker-dropDown-icon",f.setAttribute("data-bind",'css: { "cesium-sceneModePicker-visible" : (dropDownVisible && (sceneMode !== _sceneMode.SCENE2D)), "cesium-sceneModePicker-none" : sceneMode === _sceneMode.SCENE2D, "cesium-sceneModePicker-hidden" : !dropDownVisible },attr: { title: tooltip2D },click: morphTo2D,cesiumSvgPath: { path: _flatMapPath, width: 64, height: 64 }'),l.appendChild(f);var m=document.createElement("button");m.type="button",m.className="cesium-button cesium-toolbar-button cesium-sceneModePicker-dropDown-icon",m.setAttribute("data-bind",'css: { "cesium-sceneModePicker-visible" : (dropDownVisible && (sceneMode !== _sceneMode.COLUMBUS_VIEW)) || (!dropDownVisible && (sceneMode === _sceneMode.COLUMBUS_VIEW)), "cesium-sceneModePicker-none" : sceneMode === _sceneMode.COLUMBUS_VIEW, "cesium-sceneModePicker-hidden" : !dropDownVisible},attr: { title: tooltipColumbusView },click: morphToColumbusView,cesiumSvgPath: { path: _columbusViewPath, width: 64, height: 64 }'),l.appendChild(m),o.applyBindings(i,l),this._viewModel=i,this._container=e,this._wrapper=l,this._closeDropDown=function(e){l.contains(e.target)||(i.dropDownVisible=!1)},n.supportsPointerEvents()?document.addEventListener("pointerdown",this._closeDropDown,!0):(document.addEventListener("mousedown",this._closeDropDown,!0),document.addEventListener("touchstart",this._closeDropDown,!0))}var u="m 32.401392,4.9330437 c -7.087603,0 -14.096095,2.884602 -19.10793,7.8946843 -5.0118352,5.010083 -7.9296167,11.987468 -7.9296167,19.072999 0,7.085531 2.9177815,14.097848 7.9296167,19.107931 4.837653,4.835961 11.541408,7.631372 18.374354,7.82482 0.05712,0.01231 0.454119,0.139729 0.454119,0.139729 l 0.03493,-0.104797 c 0.08246,7.84e-4 0.162033,0.03493 0.244525,0.03493 0.08304,0 0.161515,-0.03414 0.244526,-0.03493 l 0.03493,0.104797 c 0,0 0.309474,-0.129487 0.349323,-0.139729 6.867765,-0.168094 13.582903,-2.965206 18.444218,-7.82482 2.558195,-2.5573 4.551081,-5.638134 5.903547,-8.977584 1.297191,-3.202966 2.02607,-6.661489 2.02607,-10.130347 0,-6.237309 -2.366261,-12.31219 -6.322734,-17.116794 -0.0034,-0.02316 0.0049,-0.04488 0,-0.06986 -0.01733,-0.08745 -0.104529,-0.278855 -0.104797,-0.279458 -5.31e-4,-0.0012 -0.522988,-0.628147 -0.523984,-0.62878 -3.47e-4,-2.2e-4 -0.133444,-0.03532 -0.244525,-0.06987 C 51.944299,13.447603 51.751076,13.104317 51.474391,12.827728 46.462556,7.8176457 39.488996,4.9330437 32.401392,4.9330437 z m -2.130866,3.5281554 0.104797,9.6762289 c -4.111695,-0.08361 -7.109829,-0.423664 -9.257041,-0.943171 1.198093,-2.269271 2.524531,-4.124404 3.91241,-5.414496 2.167498,-2.0147811 3.950145,-2.8540169 5.239834,-3.3185619 z m 2.794579,0 c 1.280302,0.4754953 3.022186,1.3285948 5.065173,3.2486979 1.424667,1.338973 2.788862,3.303645 3.982275,5.728886 -2.29082,0.403367 -5.381258,0.621049 -8.942651,0.698645 L 33.065105,8.4611991 z m 5.728886,0.2445256 c 4.004072,1.1230822 7.793098,3.1481363 10.724195,6.0782083 0.03468,0.03466 0.07033,0.06991 0.104797,0.104797 -0.45375,0.313891 -0.923054,0.663002 -1.956205,1.082899 -0.647388,0.263114 -1.906242,0.477396 -2.829511,0.733577 -1.382296,-2.988132 -3.027146,-5.368585 -4.785716,-7.0213781 -0.422866,-0.397432 -0.835818,-0.6453247 -1.25756,-0.9781032 z m -15.33525,0.7685092 c -0.106753,0.09503 -0.207753,0.145402 -0.31439,0.244526 -1.684973,1.5662541 -3.298068,3.8232211 -4.680919,6.5672591 -0.343797,-0.14942 -1.035052,-0.273198 -1.292493,-0.419186 -0.956528,-0.542427 -1.362964,-1.022024 -1.537018,-1.292493 -0.0241,-0.03745 -0.01868,-0.0401 -0.03493,-0.06986 2.250095,-2.163342 4.948824,-3.869984 7.859752,-5.0302421 z m -9.641296,7.0912431 c 0.464973,0.571618 0.937729,1.169056 1.956205,1.746612 0.349907,0.198425 1.107143,0.335404 1.537018,0.523983 -1.20166,3.172984 -1.998037,7.051901 -2.165798,11.772162 C 14.256557,30.361384 12.934823,30.161483 12.280427,29.90959 10.644437,29.279855 9.6888882,28.674891 9.1714586,28.267775 8.6540289,27.860658 8.6474751,27.778724 8.6474751,27.778724 l -0.069864,0.03493 C 9.3100294,23.691285 11.163248,19.798527 13.817445,16.565477 z m 37.552149,0.523984 c 2.548924,3.289983 4.265057,7.202594 4.890513,11.318043 -0.650428,0.410896 -1.756876,1.001936 -3.563088,1.606882 -1.171552,0.392383 -3.163859,0.759153 -4.960377,1.117832 -0.04367,-4.752703 -0.784809,-8.591423 -1.88634,-11.807094 0.917574,-0.263678 2.170552,-0.486495 2.864443,-0.76851 1.274693,-0.518066 2.003942,-1.001558 2.654849,-1.467153 z m -31.439008,2.619917 c 2.487341,0.672766 5.775813,1.137775 10.479669,1.222628 l 0.104797,10.689263 0,0.03493 0,0.733577 c -5.435005,-0.09059 -9.512219,-0.519044 -12.610536,-1.117831 0.106127,-4.776683 0.879334,-8.55791 2.02607,-11.562569 z m 23.264866,0.31439 c 1.073459,3.067541 1.833795,6.821314 1.816476,11.702298 -3.054474,0.423245 -7.062018,0.648559 -11.702298,0.698644 l 0,-0.838373 -0.104796,-10.654331 c 4.082416,-0.0864 7.404468,-0.403886 9.990618,-0.908238 z M 8.2632205,30.922625 c 0.7558676,0.510548 1.5529563,1.013339 3.0041715,1.57195 0.937518,0.360875 2.612202,0.647642 3.91241,0.978102 0.112814,3.85566 0.703989,7.107756 1.606883,9.920754 -1.147172,-0.324262 -2.644553,-0.640648 -3.423359,-0.978102 -1.516688,-0.657177 -2.386627,-1.287332 -2.864443,-1.71168 -0.477816,-0.424347 -0.489051,-0.489051 -0.489051,-0.489051 L 9.8002387,40.319395 C 8.791691,37.621767 8.1584238,34.769583 8.1584238,31.900727 c 0,-0.330153 0.090589,-0.648169 0.1047967,-0.978102 z m 48.2763445,0.419186 c 0.0047,0.188973 0.06986,0.36991 0.06986,0.558916 0,2.938869 -0.620228,5.873558 -1.676747,8.628261 -0.07435,0.07583 -0.06552,0.07411 -0.454119,0.349323 -0.606965,0.429857 -1.631665,1.042044 -3.318562,1.676747 -1.208528,0.454713 -3.204964,0.850894 -5.135038,1.25756 0.84593,-2.765726 1.41808,-6.005357 1.606883,-9.815957 2.232369,-0.413371 4.483758,-0.840201 5.938479,-1.327425 1.410632,-0.472457 2.153108,-0.89469 2.96924,-1.327425 z m -38.530252,2.864443 c 3.208141,0.56697 7.372279,0.898588 12.575603,0.978103 l 0.174662,9.885821 c -4.392517,-0.06139 -8.106722,-0.320566 -10.863925,-0.803441 -1.051954,-2.664695 -1.692909,-6.043794 -1.88634,-10.060483 z m 26.793022,0.31439 c -0.246298,3.923551 -0.877762,7.263679 -1.816476,9.885822 -2.561957,0.361954 -5.766249,0.560708 -9.431703,0.62878 l -0.174661,-9.815957 c 4.491734,-0.04969 8.334769,-0.293032 11.42284,-0.698645 z M 12.035901,44.860585 c 0.09977,0.04523 0.105535,0.09465 0.209594,0.139729 1.337656,0.579602 3.441099,1.058072 5.589157,1.537018 1.545042,3.399208 3.548524,5.969402 5.589157,7.789888 -3.034411,-1.215537 -5.871615,-3.007978 -8.174142,-5.309699 -1.245911,-1.245475 -2.271794,-2.662961 -3.213766,-4.156936 z m 40.69605,0 c -0.941972,1.493975 -1.967855,2.911461 -3.213765,4.156936 -2.74253,2.741571 -6.244106,4.696717 -9.955686,5.868615 0.261347,-0.241079 0.507495,-0.394491 0.768509,-0.663713 1.674841,-1.727516 3.320792,-4.181056 4.645987,-7.265904 2.962447,-0.503021 5.408965,-1.122293 7.161107,-1.781544 0.284034,-0.106865 0.337297,-0.207323 0.593848,-0.31439 z m -31.404076,2.305527 c 2.645807,0.376448 5.701178,0.649995 9.466635,0.698645 l 0.139729,7.789888 c -1.38739,-0.480844 -3.316218,-1.29837 -5.659022,-3.388427 -1.388822,-1.238993 -2.743668,-3.0113 -3.947342,-5.100106 z m 20.365491,0.104797 c -1.04872,2.041937 -2.174337,3.779068 -3.353494,4.995309 -1.853177,1.911459 -3.425515,2.82679 -4.611055,3.353494 l -0.139729,-7.789887 c 3.13091,-0.05714 5.728238,-0.278725 8.104278,-0.558916 z",c="m 2.9825053,17.550598 0,1.368113 0,26.267766 0,1.368113 1.36811,0 54.9981397,0 1.36811,0 0,-1.368113 0,-26.267766 0,-1.368113 -1.36811,0 -54.9981397,0 -1.36811,0 z m 2.73623,2.736226 10.3292497,0 0,10.466063 -10.3292497,0 0,-10.466063 z m 13.0654697,0 11.69737,0 0,10.466063 -11.69737,0 0,-10.466063 z m 14.43359,0 11.69737,0 0,10.466063 -11.69737,0 0,-10.466063 z m 14.43359,0 10.32926,0 0,10.466063 -10.32926,0 0,-10.466063 z m -41.9326497,13.202288 10.3292497,0 0,10.329252 -10.3292497,0 0,-10.329252 z m 13.0654697,0 11.69737,0 0,10.329252 -11.69737,0 0,-10.329252 z m 14.43359,0 11.69737,0 0,10.329252 -11.69737,0 0,-10.329252 z m 14.43359,0 10.32926,0 0,10.329252 -10.32926,0 0,-10.329252 z",d="m 14.723969,17.675598 -0.340489,0.817175 -11.1680536,26.183638 -0.817175,1.872692 2.076986,0 54.7506996,0 2.07698,0 -0.81717,-1.872692 -11.16805,-26.183638 -0.34049,-0.817175 -0.91933,0 -32.414586,0 -0.919322,0 z m 1.838643,2.723916 6.196908,0 -2.928209,10.418977 -7.729111,0 4.460412,-10.418977 z m 9.02297,0 4.903049,0 0,10.418977 -7.831258,0 2.928209,-10.418977 z m 7.626964,0 5.584031,0 2.62176,10.418977 -8.205791,0 0,-10.418977 z m 8.410081,0 5.51593,0 4.46042,10.418977 -7.38863,0 -2.58772,-10.418977 z m -30.678091,13.142892 8.103649,0 -2.89416,10.282782 -9.6018026,0 4.3923136,-10.282782 z m 10.929711,0 8.614384,0 0,10.282782 -11.508544,0 2.89416,-10.282782 z m 11.338299,0 8.852721,0 2.58772,10.282782 -11.440441,0 0,-10.282782 z m 11.678781,0 7.86531,0 4.39231,10.282782 -9.6699,0 -2.58772,-10.282782 z";return t(l.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){return this._viewModel.destroy(),n.supportsPointerEvents()?document.removeEventListener("pointerdown",this._closeDropDown,!0):(document.removeEventListener("mousedown",this._closeDropDown,!0),document.removeEventListener("touchstart",this._closeDropDown,!0)),o.cleanNode(this._wrapper),this._container.removeChild(this._wrapper),r(this)},l}),define("Widgets/SelectionIndicator/SelectionIndicatorViewModel",["../../Core/Cartesian2","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/EasingFunction","../../Scene/SceneTransforms","../../ThirdParty/knockout"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,i,n){this._scene=e,this._screenPositionX=c,this._screenPositionY=c,this._tweens=e.tweens,this._container=t(n,document.body),this._selectionIndicatorElement=i,this._scale=1,this.position=void 0,this.showSelection=!1,s.track(this,["position","_screenPositionX","_screenPositionY","_scale","showSelection"]),this.isVisible=void 0,s.defineProperty(this,"isVisible",{get:function(){return this.showSelection&&r(this.position)}}),s.defineProperty(this,"_transform",{get:function(){return"scale("+this._scale+")"}}),this.computeScreenSpacePosition=function(t,r){return a.wgs84ToWindowCoordinates(e,t,r)}}var u=new e,c="-1000px";return l.prototype.update=function(){if(this.showSelection&&r(this.position)){var e=this.computeScreenSpacePosition(this.position,u);if(r(e)){var t=this._container,i=t.parentNode.clientWidth,n=t.parentNode.clientHeight,o=this._selectionIndicatorElement.clientWidth,a=.5*o;e.x=Math.min(Math.max(e.x,-o),i+o)-a,e.y=Math.min(Math.max(e.y,-o),n+o)-a,this._screenPositionX=Math.floor(e.x+.25)+"px",this._screenPositionY=Math.floor(e.y+.25)+"px"}else this._screenPositionX=c,this._screenPositionY=c}},l.prototype.animateAppear=function(){this._tweens.addProperty({object:this,property:"_scale",startValue:2,stopValue:1,duration:.8,easingFunction:o.EXPONENTIAL_OUT})},l.prototype.animateDepart=function(){this._tweens.addProperty({object:this,property:"_scale",startValue:this._scale,stopValue:1.5,duration:.8,easingFunction:o.EXPONENTIAL_OUT})},i(l.prototype,{container:{get:function(){return this._container}},selectionIndicatorElement:{get:function(){return this._selectionIndicatorElement}},scene:{get:function(){return this._scene}}}),l}),define("Widgets/SelectionIndicator/SelectionIndicator",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./SelectionIndicatorViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t){e=o(e),this._container=e;var r=document.createElement("div");r.className="cesium-selection-wrapper",r.setAttribute("data-bind",'style: { "top" : _screenPositionY, "left" : _screenPositionX },css: { "cesium-selection-wrapper-visible" : isVisible }'),e.appendChild(r),this._element=r;var i="http://www.w3.org/2000/svg",s=document.createElementNS(i,"svg:svg");s.setAttribute("width",160),s.setAttribute("height",160),s.setAttribute("viewBox","0 0 160 160");var l=document.createElementNS(i,"g");l.setAttribute("transform","translate(80,80)"),s.appendChild(l);var u=document.createElementNS(i,"path");u.setAttribute("data-bind","attr: { transform: _transform }"),u.setAttribute("d","M -34 -34 L -34 -11.25 L -30 -15.25 L -30 -30 L -15.25 -30 L -11.25 -34 L -34 -34 z M 11.25 -34 L 15.25 -30 L 30 -30 L 30 -15.25 L 34 -11.25 L 34 -34 L 11.25 -34 z M -34 11.25 L -34 34 L -11.25 34 L -15.25 30 L -30 30 L -30 15.25 L -34 11.25 z M 34 11.25 L 30 15.25 L 30 30 L 15.25 30 L 11.25 34 L 34 34 L 34 11.25 z"),l.appendChild(u),r.appendChild(s);var c=new a(t,this._element,this._container);this._viewModel=c,n.applyBindings(this._viewModel,this._element)}return t(s.prototype,{container:{ +get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){var e=this._container;return n.cleanNode(this._element),e.removeChild(this._element),r(this)},s}),define("Widgets/Timeline/TimelineHighlightRange",["../../Core/defaultValue","../../Core/JulianDate"],function(e,t){"use strict";function r(t,r,i){this._color=t,this._height=r,this._base=e(i,0)}return r.prototype.getHeight=function(){return this._height},r.prototype.getBase=function(){return this._base},r.prototype.getStartTime=function(){return this._start},r.prototype.getStopTime=function(){return this._stop},r.prototype.setRange=function(e,t){this._start=e,this._stop=t},r.prototype.render=function(e){var r="";if(this._start&&this._stop&&this._color){var i=t.secondsDifference(this._start,e.epochJulian),n=Math.round(e.timeBarWidth*e.getAlpha(i)),o=t.secondsDifference(this._stop,e.epochJulian),a=Math.round(e.timeBarWidth*e.getAlpha(o))-n;n<0&&(a+=n,n=0),n+a>e.timeBarWidth&&(a=e.timeBarWidth-n),a>0&&(r='<span class="cesium-timeline-highlight" style="left: '+n.toString()+"px; width: "+a.toString()+"px; bottom: "+this._base.toString()+"px; height: "+this._height+"px; background-color: "+this._color+';"></span>')}return r},r}),define("Widgets/Timeline/TimelineTrack",["../../Core/Color","../../Core/defined","../../Core/JulianDate"],function(e,t,r){"use strict";function i(t,r,i,n){this.interval=t,this.height=r,this.color=i||new e(.5,.5,.5,1),this.backgroundColor=n||new e(0,0,0,0)}return i.prototype.render=function(e,i){var n=this.interval.start,o=this.interval.stop,a=i.startJulian,s=r.addSeconds(i.startJulian,i.duration,new r);if(r.lessThan(n,a)&&r.greaterThan(o,s))e.fillStyle=this.color.toCssColorString(),e.fillRect(0,i.y,i.timeBarWidth,this.height);else if(r.lessThanOrEquals(n,s)&&r.greaterThanOrEquals(o,a)){var l,u,c;for(l=0;l<i.timeBarWidth;++l){var d=r.addSeconds(i.startJulian,l/i.timeBarWidth*i.duration,new r);!t(u)&&r.greaterThanOrEquals(d,n)?u=l:!t(c)&&r.greaterThanOrEquals(d,o)&&(c=l)}e.fillStyle=this.backgroundColor.toCssColorString(),e.fillRect(0,i.y,i.timeBarWidth,this.height),t(u)&&(t(c)||(c=i.timeBarWidth),e.fillStyle=this.color.toCssColorString(),e.fillRect(u,i.y,Math.max(c-u,1),this.height))}},i}),define("Widgets/Timeline/Timeline",["../../Core/ClockRange","../../Core/defined","../../Core/destroyObject","../../Core/DeveloperError","../../Core/JulianDate","../getElement","./TimelineHighlightRange","./TimelineTrack"],function(e,t,r,i,n,o,a,s){"use strict";function l(e,t){e=o(e),this.container=e;var r=document.createElement("div");r.className="cesium-timeline-main",e.appendChild(r),this._topDiv=r,this._endJulian=void 0,this._epochJulian=void 0,this._lastXPos=void 0,this._scrubElement=void 0,this._startJulian=void 0,this._timeBarSecondsSpan=void 0,this._clock=t,this._scrubJulian=t.currentTime,this._mainTicSpan=-1,this._mouseMode=v.none,this._touchMode=y.none,this._touchState={centerX:0,spanX:0},this._mouseX=0,this._timelineDrag=0,this._timelineDragLocation=void 0,this._lastHeight=void 0,this._lastWidth=void 0,this._topDiv.innerHTML='<div class="cesium-timeline-bar"></div><div class="cesium-timeline-trackContainer"><canvas class="cesium-timeline-tracks" width="10" height="1"></canvas></div><div class="cesium-timeline-needle"></div><span class="cesium-timeline-ruler"></span>',this._timeBarEle=this._topDiv.childNodes[0],this._trackContainer=this._topDiv.childNodes[1],this._trackListEle=this._topDiv.childNodes[1].childNodes[0],this._needleEle=this._topDiv.childNodes[2],this._rulerEle=this._topDiv.childNodes[3],this._context=this._trackListEle.getContext("2d"),this._trackList=[],this._highlightRanges=[],this.zoomTo(t.startTime,t.stopTime),this._onMouseDown=c(this),this._onMouseUp=d(this),this._onMouseMove=h(this),this._onMouseWheel=p(this),this._onTouchStart=f(this),this._onTouchMove=g(this),this._onTouchEnd=m(this);var i=this._timeBarEle;document.addEventListener("mouseup",this._onMouseUp,!1),document.addEventListener("mousemove",this._onMouseMove,!1),i.addEventListener("mousedown",this._onMouseDown,!1),i.addEventListener("DOMMouseScroll",this._onMouseWheel,!1),i.addEventListener("mousewheel",this._onMouseWheel,!1),i.addEventListener("touchstart",this._onTouchStart,!1),i.addEventListener("touchmove",this._onTouchMove,!1),i.addEventListener("touchend",this._onTouchEnd,!1),i.addEventListener("touchcancel",this._onTouchEnd,!1),this._topDiv.oncontextmenu=function(){return!1},t.onTick.addEventListener(this.updateFromClock,this),this.updateFromClock()}function u(e){return e<10?"0"+e.toString():e.toString()}function c(e){return function(t){e._mouseMode!==v.touchOnly&&(0===t.button?(e._mouseMode=v.scrub,e._scrubElement&&(e._scrubElement.style.backgroundPosition="-16px 0"),e._onMouseMove(t)):(e._mouseX=t.clientX,2===t.button?e._mouseMode=v.zoom:e._mouseMode=v.slide)),t.preventDefault()}}function d(e){return function(t){e._mouseMode=v.none,e._scrubElement&&(e._scrubElement.style.backgroundPosition="0 0"),e._timelineDrag=0,e._timelineDragLocation=void 0}}function h(e){return function(t){var r;if(e._mouseMode===v.scrub){t.preventDefault();var i=t.clientX-e._topDiv.getBoundingClientRect().left;i<0?(e._timelineDragLocation=0,e._timelineDrag=-.01*e._timeBarSecondsSpan):i>e._topDiv.clientWidth?(e._timelineDragLocation=e._topDiv.clientWidth,e._timelineDrag=.01*e._timeBarSecondsSpan):(e._timelineDragLocation=void 0,e._setTimeBarTime(i,i*e._timeBarSecondsSpan/e._topDiv.clientWidth))}else if(e._mouseMode===v.slide){if(r=e._mouseX-t.clientX,e._mouseX=t.clientX,0!==r){var o=r*e._timeBarSecondsSpan/e._topDiv.clientWidth;e.zoomTo(n.addSeconds(e._startJulian,o,new n),n.addSeconds(e._endJulian,o,new n))}}else e._mouseMode===v.zoom&&(r=e._mouseX-t.clientX,e._mouseX=t.clientX,0!==r&&e.zoomFrom(Math.pow(1.01,r)))}}function p(e){return function(t){var r=t.wheelDeltaY||t.wheelDelta||-t.detail;_=Math.max(Math.min(Math.abs(r),_),1),r/=_,e.zoomFrom(Math.pow(1.05,-r))}}function f(e){return function(t){var r,i,o=t.touches.length,a=e._topDiv.getBoundingClientRect().left;t.preventDefault(),e._mouseMode=v.touchOnly,1===o?(r=n.secondsDifference(e._scrubJulian,e._startJulian),i=Math.round(r*e._topDiv.clientWidth/e._timeBarSecondsSpan+a),Math.abs(t.touches[0].clientX-i)<50?(e._touchMode=y.scrub,e._scrubElement&&(e._scrubElement.style.backgroundPosition=1===o?"-16px 0":"0 0")):(e._touchMode=y.singleTap,e._touchState.centerX=t.touches[0].clientX-a)):2===o?(e._touchMode=y.slideZoom,e._touchState.centerX=.5*(t.touches[0].clientX+t.touches[1].clientX)-a,e._touchState.spanX=Math.abs(t.touches[0].clientX-t.touches[1].clientX)):e._touchMode=y.ignore}}function m(e){return function(t){var r=t.touches.length,i=e._topDiv.getBoundingClientRect().left;e._touchMode===y.singleTap?(e._touchMode=y.scrub,e._onTouchMove(t)):e._touchMode===y.scrub&&e._onTouchMove(t),e._mouseMode=v.touchOnly,1!==r?e._touchMode=r>0?y.ignore:y.none:e._touchMode===y.slideZoom&&(e._touchState.centerX=t.touches[0].clientX-i),e._scrubElement&&(e._scrubElement.style.backgroundPosition="0 0")}}function g(e){return function(r){var i,o,a,s,l,u,c=1,d=e._topDiv.getBoundingClientRect().left;e._touchMode===y.singleTap&&(e._touchMode=y.slideZoom),e._mouseMode=v.touchOnly,e._touchMode===y.scrub?(r.preventDefault(),1===r.changedTouches.length&&(o=r.changedTouches[0].clientX-d)>=0&&o<=e._topDiv.clientWidth&&e._setTimeBarTime(o,o*e._timeBarSecondsSpan/e._topDiv.clientWidth)):e._touchMode===y.slideZoom&&(a=r.touches.length,2===a?(s=.5*(r.touches[0].clientX+r.touches[1].clientX)-d,l=Math.abs(r.touches[0].clientX-r.touches[1].clientX)):1===a&&(s=r.touches[0].clientX-d,l=0),t(s)&&(l>0&&e._touchState.spanX>0?(c=e._touchState.spanX/l,u=n.addSeconds(e._startJulian,(e._touchState.centerX*e._timeBarSecondsSpan-s*e._timeBarSecondsSpan*c)/e._topDiv.clientWidth,new n)):(i=e._touchState.centerX-s,u=n.addSeconds(e._startJulian,i*e._timeBarSecondsSpan/e._topDiv.clientWidth,new n)),e.zoomTo(u,n.addSeconds(u,e._timeBarSecondsSpan*c,new n)),e._touchState.centerX=s,e._touchState.spanX=l))}}var _=1e12,v={none:0,scrub:1,slide:2,zoom:3,touchOnly:4},y={none:0,scrub:1,slideZoom:2,singleTap:3,ignore:4},b=[.001,.002,.005,.01,.02,.05,.1,.25,.5,1,2,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,21600,43200,86400,172800,345600,604800,1296e3,2592e3,5184e3,7776e3,15552e3,31536e3,63072e3,126144e3,15768e4,31536e4,63072e4,126144e4,15768e5,31536e5,63072e5,126144e5,15768e6,31536e6],C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];return l.prototype.addEventListener=function(e,t,r){this._topDiv.addEventListener(e,t,r)},l.prototype.removeEventListener=function(e,t,r){this._topDiv.removeEventListener(e,t,r)},l.prototype.isDestroyed=function(){return!1},l.prototype.destroy=function(){this._clock.onTick.removeEventListener(this.updateFromClock,this),document.removeEventListener("mouseup",this._onMouseUp,!1),document.removeEventListener("mousemove",this._onMouseMove,!1);var e=this._timeBarEle;e.removeEventListener("mousedown",this._onMouseDown,!1),e.removeEventListener("DOMMouseScroll",this._onMouseWheel,!1),e.removeEventListener("mousewheel",this._onMouseWheel,!1),e.removeEventListener("touchstart",this._onTouchStart,!1),e.removeEventListener("touchmove",this._onTouchMove,!1),e.removeEventListener("touchend",this._onTouchEnd,!1),e.removeEventListener("touchcancel",this._onTouchEnd,!1),this.container.removeChild(this._topDiv),r(this)},l.prototype.addHighlightRange=function(e,t,r){var i=new a(e,t,r);return this._highlightRanges.push(i),this.resize(),i},l.prototype.addTrack=function(e,t,r,i){var n=new s(e,t,r,i);return this._trackList.push(n),this._lastHeight=void 0,this.resize(),n},l.prototype.zoomTo=function(t,r){if(this._startJulian=t,this._endJulian=r,this._timeBarSecondsSpan=n.secondsDifference(r,t),this._clock&&this._clock.clockRange!==e.UNBOUNDED){var i=this._clock.startTime,o=this._clock.stopTime,a=n.secondsDifference(o,i),s=n.secondsDifference(i,this._startJulian),l=n.secondsDifference(o,this._endJulian);this._timeBarSecondsSpan>=a?(this._timeBarSecondsSpan=a,this._startJulian=this._clock.startTime,this._endJulian=this._clock.stopTime):s>0?(this._endJulian=n.addSeconds(this._endJulian,s,new n),this._startJulian=i,this._timeBarSecondsSpan=n.secondsDifference(this._endJulian,this._startJulian)):l<0&&(this._startJulian=n.addSeconds(this._startJulian,l,new n),this._endJulian=o,this._timeBarSecondsSpan=n.secondsDifference(this._endJulian,this._startJulian))}this._makeTics();var u=document.createEvent("Event");u.initEvent("setzoom",!0,!0),u.startJulian=this._startJulian,u.endJulian=this._endJulian,u.epochJulian=this._epochJulian,u.totalSpan=this._timeBarSecondsSpan,u.mainTicSpan=this._mainTicSpan,this._topDiv.dispatchEvent(u)},l.prototype.zoomFrom=function(e){var t=n.secondsDifference(this._scrubJulian,this._startJulian);e>1||t<0||t>this._timeBarSecondsSpan?t=.5*this._timeBarSecondsSpan:t+=t-.5*this._timeBarSecondsSpan;var r=this._timeBarSecondsSpan-t;this.zoomTo(n.addSeconds(this._startJulian,t-t*e,new n),n.addSeconds(this._endJulian,r*e-r,new n))},l.prototype.makeLabel=function(e){var t=n.toGregorianDate(e),r=t.millisecond,i=" UTC";if(r>0&&this._timeBarSecondsSpan<3600){for(i=Math.floor(r).toString();i.length<3;)i="0"+i;i="."+i}return C[t.month-1]+" "+t.day+" "+t.year+" "+u(t.hour)+":"+u(t.minute)+":"+u(t.second)+i},l.prototype.smallestTicInPixels=7,l.prototype._makeTics=function(){function e(e){return Math.floor(y/e)*e}function t(e,t){return Math.ceil(e/t+.5)*t}function r(e){return(e-y)/p}function i(e,t){return e-t*Math.round(e/t)}var o,a=this._timeBarEle,s=n.secondsDifference(this._scrubJulian,this._startJulian),l=Math.round(s*this._topDiv.clientWidth/this._timeBarSecondsSpan),u=l-8,c=this;this._needleEle.style.left=l.toString()+"px";var d="",h=0,p=this._timeBarSecondsSpan;p<.01?(p=.01,this._timeBarSecondsSpan=.01,this._endJulian=n.addSeconds(this._startJulian,.01,new n)):p>31536e6&&(p=31536e6,this._timeBarSecondsSpan=31536e6,this._endJulian=n.addSeconds(this._startJulian,31536e6,new n));var f=this._timeBarEle.clientWidth;f<10&&(f=10);var m,g=this._startJulian,_=Math.min(p/f*1e-5,.4),v=n.toGregorianDate(g);m=p>31536e4?n.fromDate(new Date(Date.UTC(100*Math.floor(v.year/100),0))):p>31536e3?n.fromDate(new Date(Date.UTC(10*Math.floor(v.year/10),0))):p>86400?n.fromDate(new Date(Date.UTC(v.year,0))):n.fromDate(new Date(Date.UTC(v.year,v.month,v.day)));var y=n.secondsDifference(this._startJulian,n.addSeconds(m,_,new n)),C=y+p;this._epochJulian=m,this._rulerEle.innerHTML=this.makeLabel(n.addSeconds(this._endJulian,-.01,new n));var S=this._rulerEle.offsetWidth+20;S<30&&(S=180);var w=h;h-=1e-10;var T={startTime:y,startJulian:g,epochJulian:m,duration:p,timeBarWidth:f,getAlpha:r};this._highlightRanges.forEach(function(e){d+=e.render(T)});var E=0,A=0,x=0,P=S/f;P>1&&(P=1),P*=this._timeBarSecondsSpan;var D,I=-1,O=-1,M=b.length;for(D=0;D<M;++D){var R=b[D];if(++I,E=R,R>P&&R>h)break;O<0&&f*(R/this._timeBarSecondsSpan)>=this.smallestTicInPixels&&(O=I)}if(I>0){for(;I>0;)if(--I,Math.abs(i(E,b[I]))<1e-5){b[I]>=h&&(A=b[I]);break}if(O>=0)for(;O<I;){if(Math.abs(i(A,b[O]))<1e-5&&b[O]>=h){x=b[O];break}++O}}(h=w)>1e-10&&x<1e-5&&Math.abs(h-E)>1e-10&&(x=h,h<=E+1e-10&&(A=0));var L,N=-999999;if(f*(x/this._timeBarSecondsSpan)>=3)for(o=e(x);o<=C;o=t(o,x))d+='<span class="cesium-timeline-ticTiny" style="left: '+Math.round(f*r(o)).toString()+'px;"></span>';if(f*(A/this._timeBarSecondsSpan)>=3)for(o=e(A);o<=C;o=t(o,A))d+='<span class="cesium-timeline-ticSub" style="left: '+Math.round(f*r(o)).toString()+'px;"></span>';if(f*(E/this._timeBarSecondsSpan)>=2){this._mainTicSpan=E,C+=E,o=e(E);for(var k=n.computeTaiMinusUtc(m);o<=C;){var F=n.addSeconds(g,o-y,new n);if(E>2.1){var B=n.computeTaiMinusUtc(F);Math.abs(B-k)>.1&&(o+=B-k,F=n.addSeconds(g,o-y,new n))}var U=Math.round(f*r(o)),V=this.makeLabel(F);this._rulerEle.innerHTML=V,L=this._rulerEle.offsetWidth,L<10&&(L=S);var z=U-(L/2-1);z>N?(N=z+L+5,d+='<span class="cesium-timeline-ticMain" style="left: '+U.toString()+'px;"></span><span class="cesium-timeline-ticLabel" style="left: '+z.toString()+'px;">'+V+"</span>"):d+='<span class="cesium-timeline-ticSub" style="left: '+U.toString()+'px;"></span>',o=t(o,E)}}else this._mainTicSpan=-1;d+='<span class="cesium-timeline-icon16" style="left:'+u+'px;bottom:0;background-position: 0 0;"></span>',a.innerHTML=d,this._scrubElement=a.lastChild,this._context.clearRect(0,0,this._trackListEle.width,this._trackListEle.height),T.y=0,this._trackList.forEach(function(e){e.render(c._context,T),T.y+=e.height})},l.prototype.updateFromClock=function(){this._scrubJulian=this._clock.currentTime;var e=this._scrubElement;if(t(this._scrubElement)){var r=n.secondsDifference(this._scrubJulian,this._startJulian),i=Math.round(r*this._topDiv.clientWidth/this._timeBarSecondsSpan);this._lastXPos!==i&&(this._lastXPos=i,e.style.left=i-8+"px",this._needleEle.style.left=i+"px")}t(this._timelineDragLocation)&&(this._setTimeBarTime(this._timelineDragLocation,this._timelineDragLocation*this._timeBarSecondsSpan/this._topDiv.clientWidth),this.zoomTo(n.addSeconds(this._startJulian,this._timelineDrag,new n),n.addSeconds(this._endJulian,this._timelineDrag,new n)))},l.prototype._setTimeBarTime=function(e,t){if(e=Math.round(e),this._scrubJulian=n.addSeconds(this._startJulian,t,new n),this._scrubElement){var r=e-8;this._scrubElement.style.left=r.toString()+"px",this._needleEle.style.left=e.toString()+"px"}var i=document.createEvent("Event");i.initEvent("settime",!0,!0),i.clientX=e,i.timeSeconds=t,i.timeJulian=this._scrubJulian,i.clock=this._clock,this._topDiv.dispatchEvent(i)},l.prototype.resize=function(){var e=this.container.clientWidth,t=this.container.clientHeight;if(e!==this._lastWidth||t!==this._lastHeight){this._trackContainer.style.height=t+"px";var r=1;this._trackList.forEach(function(e){r+=e.height}),this._trackListEle.style.height=r.toString()+"px",this._trackListEle.width=this._trackListEle.clientWidth,this._trackListEle.height=r,this._makeTics(),this._lastXPos=void 0,this._lastWidth=e,this._lastHeight=t}},l}),define("Widgets/VRButton/VRButtonViewModel",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/EventHelper","../../Core/Fullscreen","../../Core/OrthographicFrustum","../../ThirdParty/knockout","../../ThirdParty/NoSleep","../createCommand","../getElement"],function(e,t,r,i,n,o,a,s,l,u,c,d){"use strict";function h(e){var r=!1,i=window.screen;return t(i)&&(t(i.lockOrientation)?r=i.lockOrientation(e):t(i.mozLockOrientation)?r=i.mozLockOrientation(e):t(i.msLockOrientation)?r=i.msLockOrientation(e):t(i.orientation&&i.orientation.lock)&&(r=i.orientation.lock(e))),r}function p(){var e=window.screen;t(e)&&(t(e.unlockOrientation)?e.unlockOrientation():t(e.mozUnlockOrientation)?e.mozUnlockOrientation():t(e.msUnlockOrientation)?e.msUnlockOrientation():t(e.orientation&&e.orientation.unlock)&&e.orientation.unlock())}function f(e,t,r,i){i()||(r()?(t.useWebVR=!1,e._locked&&(p(),e._locked=!1),e._noSleep.disable(),a.exitFullscreen(),r(!1)):(a.fullscreen||a.requestFullscreen(e._vrElement),e._noSleep.enable(),e._locked||(e._locked=h("landscape")),t.useWebVR=!0,r(!0)))}function m(t,r){var i=this,n=l.observable(a.enabled),h=l.observable(!1);this.isVRMode=void 0,l.defineProperty(this,"isVRMode",{get:function(){return h()}}),this.isVREnabled=void 0,l.defineProperty(this,"isVREnabled",{get:function(){return n()},set:function(e){n(e&&a.enabled)}}),this.tooltip=void 0,l.defineProperty(this,"tooltip",function(){return n()?h()?"Exit VR mode":"Enter VR mode":"VR mode is unavailable"});var m=l.observable(!1);this._isOrthographic=void 0,l.defineProperty(this,"_isOrthographic",{get:function(){return m()}}),this._eventHelper=new o,this._eventHelper.add(t.preRender,function(){m(t.camera.frustum instanceof s)}),this._locked=!1,this._noSleep=new u,this._command=c(function(){f(i,t,h,m)},l.getObservable(this,"isVREnabled")),this._vrElement=e(d(r),document.body),this._callback=function(){!a.fullscreen&&h()&&(t.useWebVR=!1,i._locked&&(p(),i._locked=!1),i._noSleep.disable(),h(!1))},document.addEventListener(a.changeEventName,this._callback)}return r(m.prototype,{vrElement:{get:function(){return this._vrElement},set:function(e){this._vrElement=e}},command:{get:function(){return this._command}}}),m.prototype.isDestroyed=function(){return!1},m.prototype.destroy=function(){this._eventHelper.removeAll(),document.removeEventListener(a.changeEventName,this._callback),i(this)},m}),define("Widgets/VRButton/VRButton",["../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../ThirdParty/knockout","../getElement","./VRButtonViewModel"],function(e,t,r,i,n,o,a){"use strict";function s(e,t,r){e=o(e);var i=new a(t,r);i._exitVRPath=u,i._enterVRPath=l;var s=document.createElement("button");s.type="button",s.className="cesium-button cesium-vrButton",s.setAttribute("data-bind",'css: { "cesium-button-disabled" : _isOrthographic }, attr: { title: tooltip },click: command,enable: isVREnabled,cesiumSvgPath: { path: isVRMode ? _exitVRPath : _enterVRPath, width: 32, height: 32 }'),e.appendChild(s),n.applyBindings(i,s),this._container=e,this._viewModel=i,this._element=s}var l="M 5.3125 6.375 C 4.008126 6.375 2.96875 7.4141499 2.96875 8.71875 L 2.96875 19.5 C 2.96875 20.8043 4.008126 21.875 5.3125 21.875 L 13.65625 21.875 C 13.71832 20.0547 14.845166 18.59375 16.21875 18.59375 C 17.592088 18.59375 18.71881 20.0552 18.78125 21.875 L 27.09375 21.875 C 28.398125 21.875 29.4375 20.8043 29.4375 19.5 L 29.4375 8.71875 C 29.4375 7.4141499 28.398125 6.375 27.09375 6.375 L 5.3125 6.375 z M 9.625 10.4375 C 11.55989 10.4375 13.125 12.03385 13.125 13.96875 C 13.125 15.90365 11.55989 17.46875 9.625 17.46875 C 7.69011 17.46875 6.125 15.90365 6.125 13.96875 C 6.125 12.03385 7.69011 10.4375 9.625 10.4375 z M 22.46875 10.4375 C 24.40364 10.4375 25.96875 12.03385 25.96875 13.96875 C 25.96875 15.90365 24.40364 17.46875 22.46875 17.46875 C 20.53386 17.46875 18.96875 15.90365 18.96875 13.96875 C 18.96875 12.03385 20.53386 10.4375 22.46875 10.4375 z",u="M 25.770585,2.4552065 C 15.72282,13.962707 10.699956,19.704407 8.1768352,22.580207 c -1.261561,1.4379 -1.902282,2.1427 -2.21875,2.5 -0.141624,0.1599 -0.208984,0.2355 -0.25,0.2813 l 0.6875,0.75 c 10e-5,-10e-5 0.679191,0.727 0.6875,0.7187 0.01662,-0.016 0.02451,-0.024 0.03125,-0.031 0.01348,-0.014 0.04013,-0.038 0.0625,-0.062 0.04474,-0.05 0.120921,-0.1315 0.28125,-0.3126 0.320657,-0.3619 0.956139,-1.0921 2.2187499,-2.5312 2.5252219,-2.8781 7.5454589,-8.6169 17.5937499,-20.1250005 l -1.5,-1.3125 z m -20.5624998,3.9063 c -1.304375,0 -2.34375,1.0391 -2.34375,2.3437 l 0,10.8125005 c 0,1.3043 1.039375,2.375 2.34375,2.375 l 2.25,0 c 1.9518039,-2.2246 7.4710958,-8.5584 13.5624998,-15.5312005 l -15.8124998,0 z m 21.1249998,0 c -1.855467,2.1245 -2.114296,2.4005 -3.59375,4.0936995 1.767282,0.1815 3.15625,1.685301 3.15625,3.500001 0,1.9349 -1.56511,3.5 -3.5,3.5 -1.658043,0 -3.043426,-1.1411 -3.40625,-2.6875 -1.089617,1.2461 -2.647139,2.9988 -3.46875,3.9375 0.191501,-0.062 0.388502,-0.094 0.59375,-0.094 1.373338,0 2.50006,1.4614 2.5625,3.2812 l 8.3125,0 c 1.304375,0 2.34375,-1.0707 2.34375,-2.375 l 0,-10.8125005 c 0,-1.3046 -1.039375,-2.3437 -2.34375,-2.3437 l -0.65625,0 z M 9.5518351,10.423906 c 1.9348899,0 3.4999999,1.596401 3.4999999,3.531301 0,1.9349 -1.56511,3.5 -3.4999999,3.5 -1.9348899,0 -3.4999999,-1.5651 -3.4999999,-3.5 0,-1.9349 1.56511,-3.531301 3.4999999,-3.531301 z m 4.2187499,10.312601 c -0.206517,0.2356 -0.844218,0.9428 -1.03125,1.1562 l 0.8125,0 c 0.01392,-0.4081 0.107026,-0.7968 0.21875,-1.1562 z";return t(s.prototype,{container:{get:function(){return this._container}},viewModel:{get:function(){return this._viewModel}}}),s.prototype.isDestroyed=function(){return!1},s.prototype.destroy=function(){return this._viewModel.destroy(),n.cleanNode(this._element),this._container.removeChild(this._element),r(this)},s}),define("Widgets/Viewer/Viewer",["../../Core/BoundingSphere","../../Core/Cartesian3","../../Core/Check","../../Core/Clock","../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/destroyObject","../../Core/DeveloperError","../../Core/Event","../../Core/EventHelper","../../Core/HeadingPitchRange","../../Core/isArray","../../Core/Matrix4","../../Core/Rectangle","../../Core/ScreenSpaceEventType","../../DataSources/BoundingSphereState","../../DataSources/ConstantPositionProperty","../../DataSources/DataSourceCollection","../../DataSources/DataSourceDisplay","../../DataSources/Entity","../../DataSources/EntityView","../../DataSources/Property","../../Scene/Cesium3DTileset","../../Scene/ImageryLayer","../../Scene/SceneMode","../../ThirdParty/knockout","../../ThirdParty/when","../Animation/Animation","../Animation/AnimationViewModel","../BaseLayerPicker/BaseLayerPicker","../BaseLayerPicker/createDefaultImageryProviderViewModels","../BaseLayerPicker/createDefaultTerrainProviderViewModels","../CesiumWidget/CesiumWidget","../ClockViewModel","../FullscreenButton/FullscreenButton","../Geocoder/Geocoder","../getElement","../HomeButton/HomeButton","../InfoBox/InfoBox","../NavigationHelpButton/NavigationHelpButton","../ProjectionPicker/ProjectionPicker","../SceneModePicker/SceneModePicker","../SelectionIndicator/SelectionIndicator","../subscribeAndEvaluate","../Timeline/Timeline","../VRButton/VRButton"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q){"use strict";function Y(e){var t=e.clock;t.currentTime=e.timeJulian,t.shouldAnimate=!1}function X(e,t){var r=e.scene.pick(t.position);if(o(r)){var i=n(r.id,r.primitive.id);if(i instanceof b)return i}if(o(e.scene.globe))return Z(e,t.position)}function Q(e,t,r){if(o(r)){var i=r.clock;o(i)&&(i.getValue(t),o(e)&&(e.updateFromClock(),e.zoomTo(i.startTime,i.stopTime)))}}function Z(e,t){var r=e.scene,i=r.camera.getPickRay(t),n=r.imageryLayers.pickImageryLayerFeatures(i,r);if(o(n)){var a=new b({id:"Loading...",description:"Loading feature information..."});return x(n,function(t){if(e.selectedEntity===a){if(!o(t)||0===t.length)return void(e.selectedEntity=K());var r=t[0],i=new b({id:r.name,description:r.description});if(o(r.position)){var n=e.scene.globe.ellipsoid.cartographicToCartesian(r.position,ae);i.position=new _(n)}e.selectedEntity=i}},function(){e.selectedEntity===a&&(e.selectedEntity=K())}),a}}function K(){return new b({id:"None",description:"No features found."})}function J(e,t){var r=e._geocoder,i=e._homeButton,n=e._sceneModePicker,a=e._projectionPicker,s=e._baseLayerPicker,l=e._animation,u=e._timeline,c=e._fullscreenButton,d=e._infoBox,h=e._selectionIndicator,p=t?"hidden":"visible";if(o(r)&&(r.container.style.visibility=p),o(i)&&(i.container.style.visibility=p),o(n)&&(n.container.style.visibility=p),o(a)&&(a.container.style.visibility=p),o(s)&&(s.container.style.visibility=p),o(l)&&(l.container.style.visibility=p),o(u)&&(u.container.style.visibility=p),o(c)&&c.viewModel.isFullscreenEnabled&&(c.container.style.visibility=p),o(d)&&(d.container.style.visibility=p),o(h)&&(h.container.style.visibility=p),e._container){var f=t||!o(c)?0:c.container.clientWidth;e._vrButton.container.style.right=f+"px",e.forceResize()}}function $(e,t){function r(e){var t=X(l,e);o(t)&&(S.getValueOrUndefined(t.position,l.clock.currentTime)?l.trackedEntity=t:l.zoomTo(t))}function a(e){l.selectedEntity=X(l,e)}e=F(e),t=n(t,n.EMPTY_OBJECT);var s=!(o(t.globe)&&!1===t.globe||o(t.baseLayerPicker)&&!1===t.baseLayerPicker),l=this,d=document.createElement("div");d.className="cesium-viewer",e.appendChild(d);var p=document.createElement("div");p.className="cesium-viewer-cesiumWidgetContainer",d.appendChild(p);var f=document.createElement("div");f.className="cesium-viewer-bottom",d.appendChild(f);var g,_,b=n(t.scene3DOnly,!1),C=!1;o(t.clockViewModel)?(_=t.clockViewModel,g=_.clock):(g=new i,_=new L(g),C=!0),o(t.shouldAnimate)&&(g.shouldAnimate=t.shouldAnimate);var w=new R(p,{terrainProvider:t.terrainProvider,imageryProvider:!s&&t.imageryProvider,clock:g,skyBox:t.skyBox,skyAtmosphere:t.skyAtmosphere,sceneMode:t.sceneMode,mapProjection:t.mapProjection,globe:t.globe,orderIndependentTranslucency:t.orderIndependentTranslucency,contextOptions:t.contextOptions,useDefaultRenderLoop:t.useDefaultRenderLoop,targetFrameRate:t.targetFrameRate,showRenderLoopErrors:t.showRenderLoopErrors,creditContainer:o(t.creditContainer)?t.creditContainer:f,creditViewport:t.creditViewport,scene3DOnly:b,terrainExaggeration:t.terrainExaggeration,shadows:t.shadows,terrainShadows:t.terrainShadows,mapMode2D:t.mapMode2D,requestRenderMode:t.requestRenderMode,maximumRenderTimeChange:t.maximumRenderTimeChange}),T=t.dataSources,E=!1;o(T)||(T=new v,E=!0);var x=new y({scene:w.scene,dataSourceCollection:T}),Q=new c;Q.add(g.onTick,$.prototype._onTick,this),Q.add(w.scene.morphStart,$.prototype._clearTrackedObject,this);var Z;if(!o(t.selectionIndicator)||!1!==t.selectionIndicator){var K=document.createElement("div");K.className="cesium-viewer-selectionIndicatorContainer",d.appendChild(K),Z=new W(K,w.scene)}var ee;if(!o(t.infoBox)||!1!==t.infoBox){var te=document.createElement("div");te.className="cesium-viewer-infoBoxContainer",d.appendChild(te),ee=new U(te);var re=ee.viewModel;Q.add(re.cameraClicked,$.prototype._onInfoBoxCameraClicked,this),Q.add(re.closeClicked,$.prototype._onInfoBoxClockClicked,this)}var ie=document.createElement("div");ie.className="cesium-viewer-toolbar",d.appendChild(ie);var ne;if(!o(t.geocoder)||!1!==t.geocoder){var oe=document.createElement("div");oe.className="cesium-viewer-geocoderContainer",ie.appendChild(oe),ne=new k({container:oe,geocoderServices:o(t.geocoder)?h(t.geocoder)?t.geocoder:[t.geocoder]:void 0,scene:w.scene}),Q.add(ne.viewModel.search.beforeExecute,$.prototype._clearObjects,this)}var ae;o(t.homeButton)&&!1===t.homeButton||(ae=new B(ie,w.scene),o(ne)&&Q.add(ae.viewModel.command.afterExecute,function(){var e=ne.viewModel;e.searchText="",e.isSearchInProgress&&e.search()}),Q.add(ae.viewModel.command.beforeExecute,$.prototype._clearTrackedObject,this));var se;b||o(t.sceneModePicker)&&!1===t.sceneModePicker||(se=new G(ie,w.scene));var le;t.projectionPicker&&(le=new z(ie,w.scene));var ue,ce;if(s){var de=n(t.imageryProviderViewModels,O()),he=n(t.terrainProviderViewModels,M());ue=new I(ie,{globe:w.scene.globe,imageryProviderViewModels:de,selectedImageryProviderViewModel:t.selectedImageryProviderViewModel,terrainProviderViewModels:he,selectedTerrainProviderViewModel:t.selectedTerrainProviderViewModel});ce=ie.getElementsByClassName("cesium-baseLayerPicker-dropDown")[0]}var pe;if(!o(t.navigationHelpButton)||!1!==t.navigationHelpButton){var fe=!0;try{if(o(window.localStorage)){var me=window.localStorage.getItem("cesium-hasSeenNavHelp");o(me)&&Boolean(me)?fe=!1:window.localStorage.setItem("cesium-hasSeenNavHelp","true")}}catch(e){}pe=new V({container:ie,instructionsInitiallyVisible:n(t.navigationInstructionsInitiallyVisible,fe)})}var ge;if(!o(t.animation)||!1!==t.animation){var _e=document.createElement("div");_e.className="cesium-viewer-animationContainer",d.appendChild(_e),ge=new P(_e,new D(_))}var ve;if(!o(t.timeline)||!1!==t.timeline){var ye=document.createElement("div");ye.className="cesium-viewer-timelineContainer",d.appendChild(ye),ve=new j(ye,g),ve.addEventListener("settime",Y,!1),ve.zoomTo(g.startTime,g.stopTime)}var be,Ce,Se;o(t.fullscreenButton)&&!1===t.fullscreenButton||(Se=document.createElement("div"),Se.className="cesium-viewer-fullscreenContainer",d.appendChild(Se),be=new N(Se,t.fullscreenElement),Ce=H(be.viewModel,"isFullscreenEnabled",function(e){Se.style.display=e?"block":"none",o(ve)&&(ve.container.style.right=Se.clientWidth+"px",ve.resize())}));var we,Te,Ee;if(t.vrButton){var Ae=document.createElement("div");Ae.className="cesium-viewer-vrContainer",d.appendChild(Ae),we=new q(Ae,w.scene,t.fullScreenElement),Te=H(we.viewModel,"isVREnabled",function(e){Ae.style.display=e?"block":"none",o(be)&&(Ae.style.right=Se.clientWidth+"px"),o(ve)&&(ve.container.style.right=Ae.clientWidth+"px",ve.resize())}),Ee=H(we.viewModel,"isVRMode",function(e){J(l,e)})}this._baseLayerPickerDropDown=ce,this._fullscreenSubscription=Ce,this._vrSubscription=Te,this._vrModeSubscription=Ee,this._dataSourceChangedListeners={},this._automaticallyTrackDataSourceClocks=n(t.automaticallyTrackDataSourceClocks,!0),this._container=e,this._bottomContainer=f,this._element=d,this._cesiumWidget=w,this._selectionIndicator=Z,this._infoBox=ee,this._dataSourceCollection=T,this._destroyDataSourceCollection=E,this._dataSourceDisplay=x,this._clockViewModel=_,this._destroyClockViewModel=C,this._toolbar=ie,this._homeButton=ae,this._sceneModePicker=se,this._projectionPicker=le,this._baseLayerPicker=ue,this._navigationHelpButton=pe,this._animation=ge,this._timeline=ve,this._fullscreenButton=be,this._vrButton=we,this._geocoder=ne,this._eventHelper=Q,this._lastWidth=0,this._lastHeight=0,this._allowDataSourcesToSuspendAnimation=!0,this._entityView=void 0,this._enableInfoOrSelection=o(ee)||o(Z),this._clockTrackedDataSource=void 0,this._trackedEntity=void 0,this._needTrackedEntityUpdate=!1,this._selectedEntity=void 0,this._clockTrackedDataSource=void 0,this._forceResize=!1,this._zoomIsFlight=!1,this._zoomTarget=void 0,this._zoomPromise=void 0,this._zoomOptions=void 0,this._selectedEntityChanged=new u,this._trackedEntityChanged=new u,A.track(this,["_trackedEntity","_selectedEntity","_clockTrackedDataSource"]),Q.add(T.dataSourceAdded,$.prototype._onDataSourceAdded,this),Q.add(T.dataSourceRemoved,$.prototype._onDataSourceRemoved,this),Q.add(w.scene.postUpdate,$.prototype.resize,this),Q.add(w.scene.postRender,$.prototype._postRender,this);for(var xe=T.length,Pe=0;Pe<xe;Pe++)this._dataSourceAdded(T,T.get(Pe));this._dataSourceAdded(void 0,x.defaultDataSource),Q.add(T.dataSourceAdded,$.prototype._dataSourceAdded,this), +Q.add(T.dataSourceRemoved,$.prototype._dataSourceRemoved,this),w.screenSpaceEventHandler.setInputAction(a,m.LEFT_CLICK),w.screenSpaceEventHandler.setInputAction(r,m.LEFT_DOUBLE_CLICK)}function ee(e,t,r,i){re(e);var a=x.defer();return e._zoomPromise=a,e._zoomIsFlight=i,e._zoomOptions=r,x(t,function(t){if(e._zoomPromise===a){if(t instanceof T)return void t.getViewableRectangle().then(function(t){e._zoomPromise===a&&(e._zoomTarget=t)});if(t instanceof w)return void(e._zoomTarget=t);if(t.isLoading&&o(t.loadingEvent))var r=t.loadingEvent.addEventListener(function(){r(),e._zoomPromise===a&&(e._zoomTarget=t.entities.values.slice(0))});else{if(h(t))return void(e._zoomTarget=t.slice(0));t=n(t.values,t),o(t.entities)&&(t=t.entities.values),h(t)?e._zoomTarget=t.slice(0):e._zoomTarget=[t]}}}),e.scene.requestRender(),a.promise}function te(e){e._zoomPromise=void 0,e._zoomTarget=void 0,e._zoomOptions=void 0}function re(e){var t=e._zoomPromise;o(t)&&(te(e),t.resolve(!1))}function ie(t){var r=t._zoomTarget;if(o(r)&&t.scene.mode!==E.MORPHING){var i,a=t.scene,s=a.camera,l=t._zoomPromise,u=n(t._zoomOptions,{});if(r instanceof w)return r.readyPromise.then(function(){var e=r.boundingSphere;o(u.offset)||(u.offset=new d(0,-.5,e.radius)),i={offset:u.offset,duration:u.duration,maximumHeight:u.maximumHeight,complete:function(){l.resolve(!0)},cancel:function(){l.resolve(!1)}},t._zoomIsFlight?s.flyToBoundingSphere(r.boundingSphere,i):(s.viewBoundingSphere(e,u.offset),s.lookAtTransform(p.IDENTITY),l.resolve(!0)),te(t)});if(r instanceof f)return i={destination:r,duration:u.duration,maximumHeight:u.maximumHeight,complete:function(){l.resolve(!0)},cancel:function(){l.resolve(!1)}},t._zoomIsFlight?s.flyTo(i):(s.setView(i),l.resolve(!0)),void te(t);for(var c=r,h=[],m=0,_=c.length;m<_;m++){var v=t._dataSourceDisplay.getBoundingSphere(c[m],!1,oe);if(v===g.PENDING)return;v!==g.FAILED&&h.push(e.clone(oe))}if(0===h.length)return void re(t);t.trackedEntity=void 0;var y=e.fromBoundingSpheres(h);t._zoomIsFlight?(te(t),s.flyToBoundingSphere(y,{duration:u.duration,maximumHeight:u.maximumHeight,complete:function(){l.resolve(!0)},cancel:function(){l.resolve(!1)},offset:u.offset})):(s.viewBoundingSphere(y,t._zoomOptions.offset),s.lookAtTransform(p.IDENTITY),te(t),l.resolve(!0))}}function ne(e){if(e._needTrackedEntityUpdate){var t=e._trackedEntity,r=e.clock.currentTime,i=S.getValueOrUndefined(t.position,r);if(o(i)){var n=e.scene,a=e._dataSourceDisplay.getBoundingSphere(t,!1,oe);if(a!==g.PENDING){var s=n.mode;s!==E.COLUMBUS_VIEW&&s!==E.SCENE2D||(n.screenSpaceCameraController.enableTranslate=!1),s!==E.COLUMBUS_VIEW&&s!==E.SCENE3D||(n.screenSpaceCameraController.enableTilt=!1);var l=a!==g.FAILED?oe:void 0;e._entityView=new C(t,n,n.mapProjection.ellipsoid),e._entityView.update(r,l),e._needTrackedEntityUpdate=!1}}}}var oe=new e,ae=new t;return a($.prototype,{container:{get:function(){return this._container}},bottomContainer:{get:function(){return this._bottomContainer}},cesiumWidget:{get:function(){return this._cesiumWidget}},selectionIndicator:{get:function(){return this._selectionIndicator}},infoBox:{get:function(){return this._infoBox}},geocoder:{get:function(){return this._geocoder}},homeButton:{get:function(){return this._homeButton}},sceneModePicker:{get:function(){return this._sceneModePicker}},projectionPicker:{get:function(){return this._projectionPicker}},baseLayerPicker:{get:function(){return this._baseLayerPicker}},navigationHelpButton:{get:function(){return this._navigationHelpButton}},animation:{get:function(){return this._animation}},timeline:{get:function(){return this._timeline}},fullscreenButton:{get:function(){return this._fullscreenButton}},vrButton:{get:function(){return this._vrButton}},dataSourceDisplay:{get:function(){return this._dataSourceDisplay}},entities:{get:function(){return this._dataSourceDisplay.defaultDataSource.entities}},dataSources:{get:function(){return this._dataSourceCollection}},canvas:{get:function(){return this._cesiumWidget.canvas}},cesiumLogo:{get:function(){return this._cesiumWidget.cesiumLogo}},scene:{get:function(){return this._cesiumWidget.scene}},shadows:{get:function(){return this.scene.shadowMap.enabled},set:function(e){this.scene.shadowMap.enabled=e}},terrainShadows:{get:function(){return this.scene.globe.shadows},set:function(e){this.scene.globe.shadows=e}},shadowMap:{get:function(){return this.scene.shadowMap}},imageryLayers:{get:function(){return this.scene.imageryLayers}},terrainProvider:{get:function(){return this.scene.terrainProvider},set:function(e){this.scene.terrainProvider=e}},camera:{get:function(){return this.scene.camera}},clock:{get:function(){return this._clockViewModel.clock}},clockViewModel:{get:function(){return this._clockViewModel}},screenSpaceEventHandler:{get:function(){return this._cesiumWidget.screenSpaceEventHandler}},targetFrameRate:{get:function(){return this._cesiumWidget.targetFrameRate},set:function(e){this._cesiumWidget.targetFrameRate=e}},useDefaultRenderLoop:{get:function(){return this._cesiumWidget.useDefaultRenderLoop},set:function(e){this._cesiumWidget.useDefaultRenderLoop=e}},resolutionScale:{get:function(){return this._cesiumWidget.resolutionScale},set:function(e){this._cesiumWidget.resolutionScale=e,this._forceResize=!0}},allowDataSourcesToSuspendAnimation:{get:function(){return this._allowDataSourcesToSuspendAnimation},set:function(e){this._allowDataSourcesToSuspendAnimation=e}},trackedEntity:{get:function(){return this._trackedEntity},set:function(e){if(this._trackedEntity!==e){this._trackedEntity=e,re(this);var t=this.scene,r=t.mode;o(e)&&o(e.position)?this._needTrackedEntityUpdate=!0:(this._needTrackedEntityUpdate=!1,r!==E.COLUMBUS_VIEW&&r!==E.SCENE2D||(t.screenSpaceCameraController.enableTranslate=!0),r!==E.COLUMBUS_VIEW&&r!==E.SCENE3D||(t.screenSpaceCameraController.enableTilt=!0),this._entityView=void 0,this.camera.lookAtTransform(p.IDENTITY)),this._trackedEntityChanged.raiseEvent(e),this.scene.requestRender()}}},selectedEntity:{get:function(){return this._selectedEntity},set:function(e){if(this._selectedEntity!==e){this._selectedEntity=e;var t=o(this._selectionIndicator)?this._selectionIndicator.viewModel:void 0;o(e)?o(t)&&t.animateAppear():o(t)&&t.animateDepart(),this._selectedEntityChanged.raiseEvent(e)}}},selectedEntityChanged:{get:function(){return this._selectedEntityChanged}},trackedEntityChanged:{get:function(){return this._trackedEntityChanged}},clockTrackedDataSource:{get:function(){return this._clockTrackedDataSource},set:function(e){this._clockTrackedDataSource!==e&&(this._clockTrackedDataSource=e,Q(this._timeline,this.clock,e))}}}),$.prototype.extend=function(e,t){e(this,t)},$.prototype.resize=function(){var e=this._cesiumWidget,t=this._container,r=t.clientWidth,i=t.clientHeight,n=o(this._animation),a=o(this._timeline);if(this._forceResize||r!==this._lastWidth||i!==this._lastHeight){e.resize(),this._forceResize=!1;var s=i-125,l=this._baseLayerPickerDropDown;if(o(l)&&(l.style.maxHeight=s+"px"),o(this._geocoder)){this._geocoder.searchSuggestionsContainer.style.maxHeight=s+"px"}o(this._infoBox)&&(this._infoBox.viewModel.maxHeight=s);var u,c=this._timeline,d=0,h=0,p=0;if(n&&"hidden"!==window.getComputedStyle(this._animation.container).visibility){var f=this._lastWidth;u=this._animation.container,r>900?(d=169,f<=900&&(u.style.width="169px",u.style.height="112px",this._animation.resize())):r>=600?(d=136,(f<600||f>900)&&(u.style.width="136px",u.style.height="90px",this._animation.resize())):(d=106,(f>600||0===f)&&(u.style.width="106px",u.style.height="70px",this._animation.resize())),h=d+5}if(a&&"hidden"!==window.getComputedStyle(this._timeline.container).visibility){var m=this._fullscreenButton,g=this._vrButton,_=c.container,v=_.style;p=_.clientHeight+3,v.left=d+"px";var y=0;o(m)&&(y+=m.container.clientWidth),o(g)&&(y+=g.container.clientWidth),v.right=y+"px",c.resize()}this._bottomContainer.style.left=h+"px",this._bottomContainer.style.bottom=p+"px",this._lastWidth=r,this._lastHeight=i}},$.prototype.forceResize=function(){this._lastWidth=0,this.resize()},$.prototype.render=function(){this._cesiumWidget.render()},$.prototype.isDestroyed=function(){return!1},$.prototype.destroy=function(){var e;this.screenSpaceEventHandler.removeInputAction(m.LEFT_CLICK),this.screenSpaceEventHandler.removeInputAction(m.LEFT_DOUBLE_CLICK);var t=this.dataSources,r=t.length;for(e=0;e<r;e++)this._dataSourceRemoved(t,t.get(e));return this._dataSourceRemoved(void 0,this._dataSourceDisplay.defaultDataSource),this._container.removeChild(this._element),this._element.removeChild(this._toolbar),this._eventHelper.removeAll(),o(this._geocoder)&&(this._geocoder=this._geocoder.destroy()),o(this._homeButton)&&(this._homeButton=this._homeButton.destroy()),o(this._sceneModePicker)&&(this._sceneModePicker=this._sceneModePicker.destroy()),o(this._projectionPicker)&&(this._projectionPicker=this._projectionPicker.destroy()),o(this._baseLayerPicker)&&(this._baseLayerPicker=this._baseLayerPicker.destroy()),o(this._animation)&&(this._element.removeChild(this._animation.container),this._animation=this._animation.destroy()),o(this._timeline)&&(this._timeline.removeEventListener("settime",Y,!1),this._element.removeChild(this._timeline.container),this._timeline=this._timeline.destroy()),o(this._fullscreenButton)&&(this._fullscreenSubscription.dispose(),this._element.removeChild(this._fullscreenButton.container),this._fullscreenButton=this._fullscreenButton.destroy()),o(this._vrButton)&&(this._vrSubscription.dispose(),this._vrModeSubscription.dispose(),this._element.removeChild(this._vrButton.container),this._vrButton=this._vrButton.destroy()),o(this._infoBox)&&(this._element.removeChild(this._infoBox.container),this._infoBox=this._infoBox.destroy()),o(this._selectionIndicator)&&(this._element.removeChild(this._selectionIndicator.container),this._selectionIndicator=this._selectionIndicator.destroy()),this._destroyClockViewModel&&(this._clockViewModel=this._clockViewModel.destroy()),this._dataSourceDisplay=this._dataSourceDisplay.destroy(),this._cesiumWidget=this._cesiumWidget.destroy(),this._destroyDataSourceCollection&&(this._dataSourceCollection=this._dataSourceCollection.destroy()),s(this)},$.prototype._dataSourceAdded=function(e,t){t.entities.collectionChanged.addEventListener($.prototype._onEntityCollectionChanged,this)},$.prototype._dataSourceRemoved=function(e,t){var r=t.entities;r.collectionChanged.removeEventListener($.prototype._onEntityCollectionChanged,this),o(this.trackedEntity)&&r.getById(this.trackedEntity.id)===this.trackedEntity&&(this.trackedEntity=void 0),o(this.selectedEntity)&&r.getById(this.selectedEntity.id)===this.selectedEntity&&(this.selectedEntity=void 0)},$.prototype._onTick=function(e){var r=e.currentTime,i=this._dataSourceDisplay.update(r);this._allowDataSourcesToSuspendAnimation&&(this._clockViewModel.canAnimate=i);var a=this._entityView;if(o(a)){var s=this._trackedEntity;this._dataSourceDisplay.getBoundingSphere(s,!1,oe)===g.DONE&&a.update(r,oe)}var l,u=!1,c=this.selectedEntity,d=o(c)&&this._enableInfoOrSelection;if(d&&c.isShowing&&c.isAvailable(r)){this._dataSourceDisplay.getBoundingSphere(c,!0,oe)!==g.FAILED?l=oe.center:o(c.position)&&(l=c.position.getValue(r,l)),u=o(l)}var h=o(this._selectionIndicator)?this._selectionIndicator.viewModel:void 0;o(h)&&(h.position=t.clone(l,h.position),h.showSelection=d&&u,h.update());var p=o(this._infoBox)?this._infoBox.viewModel:void 0;o(p)&&(p.showInfo=d,p.enableCamera=u,p.isCameraTracking=this.trackedEntity===this.selectedEntity,d?(p.titleText=n(c.name,c.id),p.description=S.getValueOrDefault(c.description,r,"")):(p.titleText="",p.description=""))},$.prototype._onEntityCollectionChanged=function(e,t,r){for(var i=r.length,n=0;n<i;n++){var o=r[n];this.trackedEntity===o&&(this.trackedEntity=void 0),this.selectedEntity===o&&(this.selectedEntity=void 0)}},$.prototype._onInfoBoxCameraClicked=function(e){if(e.isCameraTracking&&this.trackedEntity===this.selectedEntity)this.trackedEntity=void 0;else{var t=this.selectedEntity,r=t.position;o(r)?this.trackedEntity=this.selectedEntity:this.zoomTo(this.selectedEntity)}},$.prototype._clearTrackedObject=function(){this.trackedEntity=void 0},$.prototype._onInfoBoxClockClicked=function(e){this.selectedEntity=void 0},$.prototype._clearObjects=function(){this.trackedEntity=void 0,this.selectedEntity=void 0},$.prototype._onDataSourceChanged=function(e){this.clockTrackedDataSource===e&&Q(this.timeline,this.clock,e)},$.prototype._onDataSourceAdded=function(e,t){this._automaticallyTrackDataSourceClocks&&(this.clockTrackedDataSource=t);var r=t.entities.id,i=this._eventHelper.add(t.changedEvent,$.prototype._onDataSourceChanged,this);this._dataSourceChangedListeners[r]=i},$.prototype._onDataSourceRemoved=function(e,t){var r=this.clockTrackedDataSource===t,i=t.entities.id;if(this._dataSourceChangedListeners[i](),this._dataSourceChangedListeners[i]=void 0,r){var n=e.length;this._automaticallyTrackDataSourceClocks&&n>0?this.clockTrackedDataSource=e.get(n-1):this.clockTrackedDataSource=void 0}},$.prototype.zoomTo=function(e,t){return ee(this,e,{offset:t},!1)},$.prototype.flyTo=function(e,t){return ee(this,e,t,!0)},$.prototype._postRender=function(){ie(this),ne(this)},$}),define("Widgets/Viewer/viewerCesium3DTilesInspectorMixin",["../../Core/Check","../../Core/defineProperties","../Cesium3DTilesInspector/Cesium3DTilesInspector"],function(e,t,r){"use strict";function i(e){var i=document.createElement("div");i.className="cesium-viewer-cesium3DTilesInspectorContainer",e.container.appendChild(i);var n=new r(i,e.scene);t(e,{cesium3DTilesInspector:{get:function(){return n}}})}return i}),define("Widgets/Viewer/viewerCesiumInspectorMixin",["../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../CesiumInspector/CesiumInspector"],function(e,t,r,i){"use strict";function n(e){var r=document.createElement("div");r.className="cesium-viewer-cesiumInspectorContainer",e.container.appendChild(r);var n=new i(r,e.scene);t(e,{cesiumInspector:{get:function(){return n}}})}return n}),define("Widgets/Viewer/viewerDragDropMixin",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../../Core/Event","../../Core/wrapFunction","../../DataSources/CzmlDataSource","../../DataSources/GeoJsonDataSource","../../DataSources/KmlDataSource","../getElement"],function(e,t,r,i,n,o,a,s,l,u){"use strict";function c(t,i){function a(e){d(e),g&&(t.entities.removeAll(),t.dataSources.removeAll());for(var r=e.dataTransfer.files,i=r.length,n=0;n<i;n++){var o=r[n],a=new FileReader;a.onload=f(t,o,y,v),a.onerror=m(t,o),a.readAsText(o)}}i=e(i,e.EMPTY_OBJECT);var s=!0,l=e(i.flyToOnDrop,!0),c=new n,g=e(i.clearOnDrop,!0),_=e(i.dropTarget,t.container),v=e(i.clampToGround,!0),y=i.proxy;_=u(_),r(t,{dropTarget:{get:function(){return _},set:function(e){h(_,a),_=e,p(_,a)}},dropEnabled:{get:function(){return s},set:function(e){e!==s&&(e?p(_,a):h(_,a),s=e)}},dropError:{get:function(){return c}},clearOnDrop:{get:function(){return g},set:function(e){g=e}},flyToOnDrop:{get:function(){return l},set:function(e){l=e}},proxy:{get:function(){return y},set:function(e){y=e}},clampToGround:{get:function(){return v},set:function(e){v=e}}}),p(_,a),t.destroy=o(t,t.destroy,function(){t.dropEnabled=!1}),t._handleDrop=a}function d(e){e.stopPropagation(),e.preventDefault()}function h(e,r){var i=e;t(i)&&(i.removeEventListener("drop",r,!1),i.removeEventListener("dragenter",d,!1),i.removeEventListener("dragover",d,!1),i.removeEventListener("dragexit",d,!1))}function p(e,t){e.addEventListener("drop",t,!1),e.addEventListener("dragenter",d,!1),e.addEventListener("dragover",d,!1),e.addEventListener("dragexit",d,!1)}function f(e,r,i,n){var o=e.scene;return function(u){var c=r.name;try{var d;if(/\.czml$/i.test(c))d=a.load(JSON.parse(u.target.result),{sourceUri:c});else if(/\.geojson$/i.test(c)||/\.json$/i.test(c)||/\.topojson$/i.test(c))d=s.load(JSON.parse(u.target.result),{sourceUri:c,clampToGround:n});else{if(!/\.(kml|kmz)$/i.test(c))return void e.dropError.raiseEvent(e,c,"Unrecognized file: "+c);d=l.load(r,{sourceUri:c,proxy:i,camera:o.camera,canvas:o.canvas})}t(d)&&e.dataSources.add(d).then(function(t){e.flyToOnDrop&&e.flyTo(t)}).otherwise(function(t){e.dropError.raiseEvent(e,c,t)})}catch(t){e.dropError.raiseEvent(e,c,t)}}}function m(e,t){return function(r){e.dropError.raiseEvent(e,t.name,r.target.error)}}return c}),define("Widgets/Viewer/viewerPerformanceWatchdogMixin",["../../Core/defaultValue","../../Core/defined","../../Core/defineProperties","../../Core/DeveloperError","../PerformanceWatchdog/PerformanceWatchdog"],function(e,t,r,i,n){"use strict";function o(t,i){i=e(i,e.EMPTY_OBJECT);var o=new n({scene:t.scene,container:t.bottomContainer,lowFrameRateMessage:i.lowFrameRateMessage});r(t,{performanceWatchdog:{get:function(){return o}}})}return o}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,r){"use strict";function i(i){var n,o=[],a={id:void 0,result:void 0,error:void 0};return function(s){var l=s.data;o.length=0,a.id=l.id,a.error=void 0,a.result=void 0;try{a.result=i(l.parameters,o)}catch(e){e instanceof Error?a.error={name:e.name,message:e.message,stack:e.stack}:a.error=e}t(n)||(n=e(self.webkitPostMessage,self.postMessage)),l.canTransferArrayBuffer||(o.length=0);try{n(a,o)}catch(e){a.result=void 0,a.error="postMessage failed with error: "+r(e)+"\n with responseMessage: "+JSON.stringify(a),n(a)}}}return i}), +define("Cesium",["./Core/appendForwardSlash","./Core/arrayFill","./Core/arrayRemoveDuplicates","./Core/arraySlice","./Core/AssociativeArray","./Core/AttributeCompression","./Core/AxisAlignedBoundingBox","./Core/barycentricCoordinates","./Core/binarySearch","./Core/BingMapsApi","./Core/BingMapsGeocoderService","./Core/BoundingRectangle","./Core/BoundingSphere","./Core/BoxGeometry","./Core/BoxOutlineGeometry","./Core/buildModuleUrl","./Core/cancelAnimationFrame","./Core/Cartesian2","./Core/Cartesian3","./Core/Cartesian4","./Core/Cartographic","./Core/CartographicGeocoderService","./Core/CatmullRomSpline","./Core/CesiumTerrainProvider","./Core/Check","./Core/CircleGeometry","./Core/CircleOutlineGeometry","./Core/ClippingPlaneCollection","./Core/Clock","./Core/ClockRange","./Core/ClockStep","./Core/clone","./Core/Color","./Core/ColorGeometryInstanceAttribute","./Core/combine","./Core/ComponentDatatype","./Core/CompressedTextureBuffer","./Core/CornerType","./Core/CorridorGeometry","./Core/CorridorGeometryLibrary","./Core/CorridorOutlineGeometry","./Core/createGuid","./Core/Credit","./Core/CubicRealPolynomial","./Core/CullingVolume","./Core/CylinderGeometry","./Core/CylinderGeometryLibrary","./Core/CylinderOutlineGeometry","./Core/decodeGoogleEarthEnterpriseData","./Core/DefaultProxy","./Core/defaultValue","./Core/defined","./Core/defineProperties","./Core/deprecationWarning","./Core/destroyObject","./Core/DeveloperError","./Core/DistanceDisplayCondition","./Core/DistanceDisplayConditionGeometryInstanceAttribute","./Core/DoublyLinkedList","./Core/EarthOrientationParameters","./Core/EarthOrientationParametersSample","./Core/EasingFunction","./Core/EllipseGeometry","./Core/EllipseGeometryLibrary","./Core/EllipseOutlineGeometry","./Core/Ellipsoid","./Core/EllipsoidalOccluder","./Core/EllipsoidGeodesic","./Core/EllipsoidGeometry","./Core/EllipsoidOutlineGeometry","./Core/EllipsoidTangentPlane","./Core/EllipsoidTerrainProvider","./Core/EncodedCartesian3","./Core/Event","./Core/EventHelper","./Core/ExtrapolationType","./Core/FeatureDetection","./Core/formatError","./Core/freezeObject","./Core/FrustumGeometry","./Core/FrustumOutlineGeometry","./Core/Fullscreen","./Core/GeocoderService","./Core/GeographicProjection","./Core/GeographicTilingScheme","./Core/Geometry","./Core/GeometryAttribute","./Core/GeometryAttributes","./Core/GeometryInstance","./Core/GeometryInstanceAttribute","./Core/GeometryPipeline","./Core/GeometryType","./Core/getAbsoluteUri","./Core/getBaseUri","./Core/getExtensionFromUri","./Core/getFilenameFromUri","./Core/getImagePixels","./Core/getMagic","./Core/getStringFromTypedArray","./Core/getTimestamp","./Core/GoogleEarthEnterpriseMetadata","./Core/GoogleEarthEnterpriseTerrainData","./Core/GoogleEarthEnterpriseTerrainProvider","./Core/GoogleEarthEnterpriseTileInformation","./Core/GregorianDate","./Core/HeadingPitchRange","./Core/HeadingPitchRoll","./Core/Heap","./Core/HeightmapTerrainData","./Core/HeightmapTessellator","./Core/HermitePolynomialApproximation","./Core/HermiteSpline","./Core/Iau2000Orientation","./Core/Iau2006XysData","./Core/Iau2006XysSample","./Core/IauOrientationAxes","./Core/IauOrientationParameters","./Core/IndexDatatype","./Core/InterpolationAlgorithm","./Core/Intersect","./Core/Intersections2D","./Core/IntersectionTests","./Core/Interval","./Core/isArray","./Core/isBitSet","./Core/isBlobUri","./Core/isCrossOriginUrl","./Core/isDataUri","./Core/isLeapYear","./Core/Iso8601","./Core/JulianDate","./Core/KeyboardEventModifier","./Core/LagrangePolynomialApproximation","./Core/LeapSecond","./Core/LinearApproximation","./Core/LinearSpline","./Core/loadArrayBuffer","./Core/loadBlob","./Core/loadCRN","./Core/loadImage","./Core/loadImageFromTypedArray","./Core/loadImageViaBlob","./Core/loadJson","./Core/loadJsonp","./Core/loadKTX","./Core/loadText","./Core/loadWithXhr","./Core/loadXML","./Core/ManagedArray","./Core/MapboxApi","./Core/MapProjection","./Core/Math","./Core/Matrix2","./Core/Matrix3","./Core/Matrix4","./Core/mergeSort","./Core/NearFarScalar","./Core/objectToQuery","./Core/Occluder","./Core/oneTimeWarning","./Core/OrientedBoundingBox","./Core/OrthographicFrustum","./Core/OrthographicOffCenterFrustum","./Core/Packable","./Core/PackableForInterpolation","./Core/parseResponseHeaders","./Core/PerspectiveFrustum","./Core/PerspectiveOffCenterFrustum","./Core/PinBuilder","./Core/PixelFormat","./Core/Plane","./Core/PlaneGeometry","./Core/PlaneOutlineGeometry","./Core/pointInsideTriangle","./Core/PolygonGeometry","./Core/PolygonGeometryLibrary","./Core/PolygonHierarchy","./Core/PolygonOutlineGeometry","./Core/PolygonPipeline","./Core/PolylineGeometry","./Core/PolylinePipeline","./Core/PolylineVolumeGeometry","./Core/PolylineVolumeGeometryLibrary","./Core/PolylineVolumeOutlineGeometry","./Core/PrimitiveType","./Core/QuadraticRealPolynomial","./Core/QuantizedMeshTerrainData","./Core/QuarticRealPolynomial","./Core/Quaternion","./Core/QuaternionSpline","./Core/queryToObject","./Core/Queue","./Core/Ray","./Core/Rectangle","./Core/RectangleGeometry","./Core/RectangleGeometryLibrary","./Core/RectangleOutlineGeometry","./Core/ReferenceFrame","./Core/Request","./Core/requestAnimationFrame","./Core/RequestErrorEvent","./Core/RequestScheduler","./Core/RequestState","./Core/RequestType","./Core/Resource","./Core/RuntimeError","./Core/sampleTerrain","./Core/sampleTerrainMostDetailed","./Core/scaleToGeodeticSurface","./Core/ScreenSpaceEventHandler","./Core/ScreenSpaceEventType","./Core/ShowGeometryInstanceAttribute","./Core/Simon1994PlanetaryPositions","./Core/SimplePolylineGeometry","./Core/SphereGeometry","./Core/SphereOutlineGeometry","./Core/Spherical","./Core/Spline","./Core/subdivideArray","./Core/TaskProcessor","./Core/TerrainData","./Core/TerrainEncoding","./Core/TerrainMesh","./Core/TerrainProvider","./Core/TerrainQuantization","./Core/TileAvailability","./Core/TileProviderError","./Core/TilingScheme","./Core/TimeConstants","./Core/TimeInterval","./Core/TimeIntervalCollection","./Core/TimeStandard","./Core/Tipsify","./Core/Transforms","./Core/TranslationRotationScale","./Core/TridiagonalSystemSolver","./Core/TrustedServers","./Core/VertexFormat","./Core/VideoSynchronizer","./Core/Visibility","./Core/VRTheWorldTerrainProvider","./Core/WallGeometry","./Core/WallGeometryLibrary","./Core/WallOutlineGeometry","./Core/WebGLConstants","./Core/WebMercatorProjection","./Core/WebMercatorTilingScheme","./Core/WeightSpline","./Core/WindingOrder","./Core/wrapFunction","./Core/writeTextToCanvas","./DataSources/BillboardGraphics","./DataSources/BillboardVisualizer","./DataSources/BoundingSphereState","./DataSources/BoxGeometryUpdater","./DataSources/BoxGraphics","./DataSources/CallbackProperty","./DataSources/CheckerboardMaterialProperty","./DataSources/ColorMaterialProperty","./DataSources/CompositeEntityCollection","./DataSources/CompositeMaterialProperty","./DataSources/CompositePositionProperty","./DataSources/CompositeProperty","./DataSources/ConstantPositionProperty","./DataSources/ConstantProperty","./DataSources/CorridorGeometryUpdater","./DataSources/CorridorGraphics","./DataSources/createMaterialPropertyDescriptor","./DataSources/createPropertyDescriptor","./DataSources/createRawPropertyDescriptor","./DataSources/CustomDataSource","./DataSources/CylinderGeometryUpdater","./DataSources/CylinderGraphics","./DataSources/CzmlDataSource","./DataSources/DataSource","./DataSources/DataSourceClock","./DataSources/DataSourceCollection","./DataSources/DataSourceDisplay","./DataSources/dynamicGeometryGetBoundingSphere","./DataSources/DynamicGeometryUpdater","./DataSources/EllipseGeometryUpdater","./DataSources/EllipseGraphics","./DataSources/EllipsoidGeometryUpdater","./DataSources/EllipsoidGraphics","./DataSources/Entity","./DataSources/EntityCluster","./DataSources/EntityCollection","./DataSources/EntityView","./DataSources/GeoJsonDataSource","./DataSources/GeometryUpdater","./DataSources/GeometryVisualizer","./DataSources/GridMaterialProperty","./DataSources/ImageMaterialProperty","./DataSources/KmlCamera","./DataSources/KmlDataSource","./DataSources/KmlLookAt","./DataSources/KmlTour","./DataSources/KmlTourFlyTo","./DataSources/KmlTourWait","./DataSources/LabelGraphics","./DataSources/LabelVisualizer","./DataSources/MaterialProperty","./DataSources/ModelGraphics","./DataSources/ModelVisualizer","./DataSources/NodeTransformationProperty","./DataSources/PathGraphics","./DataSources/PathVisualizer","./DataSources/PlaneGeometryUpdater","./DataSources/PlaneGraphics","./DataSources/PointGraphics","./DataSources/PointVisualizer","./DataSources/PolygonGeometryUpdater","./DataSources/PolygonGraphics","./DataSources/PolylineArrowMaterialProperty","./DataSources/PolylineDashMaterialProperty","./DataSources/PolylineGeometryUpdater","./DataSources/PolylineGlowMaterialProperty","./DataSources/PolylineGraphics","./DataSources/PolylineOutlineMaterialProperty","./DataSources/PolylineVolumeGeometryUpdater","./DataSources/PolylineVolumeGraphics","./DataSources/PositionProperty","./DataSources/PositionPropertyArray","./DataSources/Property","./DataSources/PropertyArray","./DataSources/PropertyBag","./DataSources/RectangleGeometryUpdater","./DataSources/RectangleGraphics","./DataSources/ReferenceProperty","./DataSources/Rotation","./DataSources/SampledPositionProperty","./DataSources/SampledProperty","./DataSources/ScaledPositionProperty","./DataSources/StaticGeometryColorBatch","./DataSources/StaticGeometryPerMaterialBatch","./DataSources/StaticGroundGeometryColorBatch","./DataSources/StaticOutlineGeometryBatch","./DataSources/StripeMaterialProperty","./DataSources/StripeOrientation","./DataSources/TimeIntervalCollectionPositionProperty","./DataSources/TimeIntervalCollectionProperty","./DataSources/VelocityOrientationProperty","./DataSources/VelocityVectorProperty","./DataSources/Visualizer","./DataSources/WallGeometryUpdater","./DataSources/WallGraphics","./Renderer/AutomaticUniforms","./Renderer/Buffer","./Renderer/BufferUsage","./Renderer/ClearCommand","./Renderer/ComputeCommand","./Renderer/ComputeEngine","./Renderer/Context","./Renderer/ContextLimits","./Renderer/createUniform","./Renderer/createUniformArray","./Renderer/CubeMap","./Renderer/CubeMapFace","./Renderer/DrawCommand","./Renderer/Framebuffer","./Renderer/freezeRenderState","./Renderer/loadCubeMap","./Renderer/MipmapHint","./Renderer/modernizeShader","./Renderer/Pass","./Renderer/PassState","./Renderer/PickFramebuffer","./Renderer/PixelDatatype","./Renderer/Renderbuffer","./Renderer/RenderbufferFormat","./Renderer/RenderState","./Renderer/Sampler","./Renderer/ShaderCache","./Renderer/ShaderProgram","./Renderer/ShaderSource","./Renderer/Texture","./Renderer/TextureMagnificationFilter","./Renderer/TextureMinificationFilter","./Renderer/TextureWrap","./Renderer/UniformState","./Renderer/VertexArray","./Renderer/VertexArrayFacade","./Scene/Appearance","./Scene/ArcGisMapServerImageryProvider","./Scene/AttributeType","./Scene/Axis","./Scene/Batched3DModel3DTileContent","./Scene/BatchTable","./Scene/Billboard","./Scene/BillboardCollection","./Scene/BingMapsImageryProvider","./Scene/BingMapsStyle","./Scene/BlendEquation","./Scene/BlendFunction","./Scene/BlendingState","./Scene/BlendOption","./Scene/BoxEmitter","./Scene/BrdfLutGenerator","./Scene/Camera","./Scene/CameraEventAggregator","./Scene/CameraEventType","./Scene/CameraFlightPath","./Scene/Cesium3DTile","./Scene/Cesium3DTileBatchTable","./Scene/Cesium3DTileChildrenVisibility","./Scene/Cesium3DTileColorBlendMode","./Scene/Cesium3DTileContent","./Scene/Cesium3DTileContentFactory","./Scene/Cesium3DTileContentState","./Scene/Cesium3DTileFeature","./Scene/Cesium3DTileFeatureTable","./Scene/Cesium3DTileOptimizationHint","./Scene/Cesium3DTileOptimizations","./Scene/Cesium3DTilePointFeature","./Scene/Cesium3DTileRefine","./Scene/Cesium3DTileset","./Scene/Cesium3DTilesetStatistics","./Scene/Cesium3DTilesetTraversal","./Scene/Cesium3DTileStyle","./Scene/Cesium3DTileStyleEngine","./Scene/CesiumIon","./Scene/CesiumIonResource","./Scene/CircleEmitter","./Scene/ClassificationModel","./Scene/ClassificationPrimitive","./Scene/ClassificationType","./Scene/ColorBlendMode","./Scene/Composite3DTileContent","./Scene/ConditionsExpression","./Scene/ConeEmitter","./Scene/createBillboardPointCallback","./Scene/createOpenStreetMapImageryProvider","./Scene/createTangentSpaceDebugPrimitive","./Scene/createTileMapServiceImageryProvider","./Scene/CreditDisplay","./Scene/CullFace","./Scene/DebugAppearance","./Scene/DebugCameraPrimitive","./Scene/DebugModelMatrixPrimitive","./Scene/DepthFunction","./Scene/DepthPlane","./Scene/DeviceOrientationCameraController","./Scene/DiscardMissingTileImagePolicy","./Scene/EllipsoidPrimitive","./Scene/EllipsoidSurfaceAppearance","./Scene/Empty3DTileContent","./Scene/Expression","./Scene/ExpressionNodeType","./Scene/Fog","./Scene/FrameRateMonitor","./Scene/FrameState","./Scene/FrustumCommands","./Scene/FXAA","./Scene/Geometry3DTileContent","./Scene/getBinaryAccessor","./Scene/GetFeatureInfoFormat","./Scene/Globe","./Scene/GlobeDepth","./Scene/GlobeSurfaceShaderSet","./Scene/GlobeSurfaceTile","./Scene/GlobeSurfaceTileProvider","./Scene/GoogleEarthEnterpriseImageryProvider","./Scene/GoogleEarthEnterpriseMapsProvider","./Scene/GridImageryProvider","./Scene/GroundPrimitive","./Scene/HeightReference","./Scene/HorizontalOrigin","./Scene/Imagery","./Scene/ImageryLayer","./Scene/ImageryLayerCollection","./Scene/ImageryLayerFeatureInfo","./Scene/ImageryProvider","./Scene/ImagerySplitDirection","./Scene/ImageryState","./Scene/Instanced3DModel3DTileContent","./Scene/InvertClassification","./Scene/JobScheduler","./Scene/JobType","./Scene/Label","./Scene/LabelCollection","./Scene/LabelStyle","./Scene/MapboxImageryProvider","./Scene/MapMode2D","./Scene/Material","./Scene/MaterialAppearance","./Scene/Model","./Scene/ModelAnimation","./Scene/ModelAnimationCache","./Scene/ModelAnimationCollection","./Scene/ModelAnimationLoop","./Scene/ModelAnimationState","./Scene/ModelInstance","./Scene/ModelInstanceCollection","./Scene/ModelLoadResources","./Scene/ModelMaterial","./Scene/ModelMesh","./Scene/ModelNode","./Scene/ModelUtility","./Scene/Moon","./Scene/NeverTileDiscardPolicy","./Scene/OIT","./Scene/Particle","./Scene/ParticleBurst","./Scene/ParticleEmitter","./Scene/ParticleSystem","./Scene/PerformanceDisplay","./Scene/PerInstanceColorAppearance","./Scene/PickDepth","./Scene/PointCloud3DTileContent","./Scene/PointCloudEyeDomeLighting","./Scene/PointCloudShading","./Scene/PointPrimitive","./Scene/PointPrimitiveCollection","./Scene/Polyline","./Scene/PolylineCollection","./Scene/PolylineColorAppearance","./Scene/PolylineMaterialAppearance","./Scene/Primitive","./Scene/PrimitiveCollection","./Scene/PrimitivePipeline","./Scene/PrimitiveState","./Scene/QuadtreeOccluders","./Scene/QuadtreePrimitive","./Scene/QuadtreeTile","./Scene/QuadtreeTileLoadState","./Scene/QuadtreeTileProvider","./Scene/Scene","./Scene/SceneMode","./Scene/SceneTransforms","./Scene/SceneTransitioner","./Scene/ScreenSpaceCameraController","./Scene/ShadowMap","./Scene/ShadowMapShader","./Scene/ShadowMode","./Scene/SingleTileImageryProvider","./Scene/SkyAtmosphere","./Scene/SkyBox","./Scene/SphereEmitter","./Scene/StencilFunction","./Scene/StencilOperation","./Scene/StyleExpression","./Scene/Sun","./Scene/SunPostProcess","./Scene/TerrainState","./Scene/TextureAtlas","./Scene/TileBoundingRegion","./Scene/TileBoundingSphere","./Scene/TileBoundingVolume","./Scene/TileCoordinatesImageryProvider","./Scene/TileDiscardPolicy","./Scene/TileImagery","./Scene/TileOrientedBoundingBox","./Scene/TileReplacementQueue","./Scene/Tileset3DTileContent","./Scene/TileState","./Scene/TileTerrain","./Scene/TimeDynamicImagery","./Scene/TweenCollection","./Scene/UrlTemplateImageryProvider","./Scene/Vector3DTileBatch","./Scene/Vector3DTileContent","./Scene/Vector3DTileGeometry","./Scene/Vector3DTilePoints","./Scene/Vector3DTilePolygons","./Scene/Vector3DTilePolylines","./Scene/Vector3DTilePrimitive","./Scene/VerticalOrigin","./Scene/ViewportQuad","./Scene/WebMapServiceImageryProvider","./Scene/WebMapTileServiceImageryProvider","./Shaders/AdjustTranslucentFS","./Shaders/Appearances/AllMaterialAppearanceFS","./Shaders/Appearances/AllMaterialAppearanceVS","./Shaders/Appearances/BasicMaterialAppearanceFS","./Shaders/Appearances/BasicMaterialAppearanceVS","./Shaders/Appearances/EllipsoidSurfaceAppearanceFS","./Shaders/Appearances/EllipsoidSurfaceAppearanceVS","./Shaders/Appearances/PerInstanceColorAppearanceFS","./Shaders/Appearances/PerInstanceColorAppearanceVS","./Shaders/Appearances/PerInstanceFlatColorAppearanceFS","./Shaders/Appearances/PerInstanceFlatColorAppearanceVS","./Shaders/Appearances/PolylineColorAppearanceVS","./Shaders/Appearances/PolylineMaterialAppearanceVS","./Shaders/Appearances/TexturedMaterialAppearanceFS","./Shaders/Appearances/TexturedMaterialAppearanceVS","./Shaders/BillboardCollectionFS","./Shaders/BillboardCollectionVS","./Shaders/BrdfLutGeneratorFS","./Shaders/Builtin/Constants/degreesPerRadian","./Shaders/Builtin/Constants/depthRange","./Shaders/Builtin/Constants/epsilon1","./Shaders/Builtin/Constants/epsilon2","./Shaders/Builtin/Constants/epsilon3","./Shaders/Builtin/Constants/epsilon4","./Shaders/Builtin/Constants/epsilon5","./Shaders/Builtin/Constants/epsilon6","./Shaders/Builtin/Constants/epsilon7","./Shaders/Builtin/Constants/infinity","./Shaders/Builtin/Constants/maxClippingPlanes","./Shaders/Builtin/Constants/oneOverPi","./Shaders/Builtin/Constants/oneOverTwoPi","./Shaders/Builtin/Constants/passCesium3DTile","./Shaders/Builtin/Constants/passCesium3DTileClassification","./Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow","./Shaders/Builtin/Constants/passClassification","./Shaders/Builtin/Constants/passCompute","./Shaders/Builtin/Constants/passEnvironment","./Shaders/Builtin/Constants/passGlobe","./Shaders/Builtin/Constants/passOpaque","./Shaders/Builtin/Constants/passOverlay","./Shaders/Builtin/Constants/passTerrainClassification","./Shaders/Builtin/Constants/passTranslucent","./Shaders/Builtin/Constants/pi","./Shaders/Builtin/Constants/piOverFour","./Shaders/Builtin/Constants/piOverSix","./Shaders/Builtin/Constants/piOverThree","./Shaders/Builtin/Constants/piOverTwo","./Shaders/Builtin/Constants/radiansPerDegree","./Shaders/Builtin/Constants/sceneMode2D","./Shaders/Builtin/Constants/sceneMode3D","./Shaders/Builtin/Constants/sceneModeColumbusView","./Shaders/Builtin/Constants/sceneModeMorphing","./Shaders/Builtin/Constants/solarRadius","./Shaders/Builtin/Constants/threePiOver2","./Shaders/Builtin/Constants/twoPi","./Shaders/Builtin/Constants/webMercatorMaxLatitude","./Shaders/Builtin/CzmBuiltins","./Shaders/Builtin/Functions/alphaWeight","./Shaders/Builtin/Functions/antialias","./Shaders/Builtin/Functions/cascadeColor","./Shaders/Builtin/Functions/cascadeDistance","./Shaders/Builtin/Functions/cascadeMatrix","./Shaders/Builtin/Functions/cascadeWeights","./Shaders/Builtin/Functions/columbusViewMorph","./Shaders/Builtin/Functions/computePosition","./Shaders/Builtin/Functions/cosineAndSine","./Shaders/Builtin/Functions/decompressTextureCoordinates","./Shaders/Builtin/Functions/depthClampFarPlane","./Shaders/Builtin/Functions/discardIfClippedWithIntersect","./Shaders/Builtin/Functions/discardIfClippedWithUnion","./Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates","./Shaders/Builtin/Functions/ellipsoidContainsPoint","./Shaders/Builtin/Functions/ellipsoidNew","./Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates","./Shaders/Builtin/Functions/equalsEpsilon","./Shaders/Builtin/Functions/eyeOffset","./Shaders/Builtin/Functions/eyeToWindowCoordinates","./Shaders/Builtin/Functions/fog","./Shaders/Builtin/Functions/geodeticSurfaceNormal","./Shaders/Builtin/Functions/getDefaultMaterial","./Shaders/Builtin/Functions/getLambertDiffuse","./Shaders/Builtin/Functions/getSpecular","./Shaders/Builtin/Functions/getWaterNoise","./Shaders/Builtin/Functions/getWgs84EllipsoidEC","./Shaders/Builtin/Functions/HSBToRGB","./Shaders/Builtin/Functions/HSLToRGB","./Shaders/Builtin/Functions/hue","./Shaders/Builtin/Functions/isEmpty","./Shaders/Builtin/Functions/isFull","./Shaders/Builtin/Functions/latitudeToWebMercatorFraction","./Shaders/Builtin/Functions/luminance","./Shaders/Builtin/Functions/metersPerPixel","./Shaders/Builtin/Functions/modelToWindowCoordinates","./Shaders/Builtin/Functions/multiplyWithColorBalance","./Shaders/Builtin/Functions/nearFarScalar","./Shaders/Builtin/Functions/octDecode","./Shaders/Builtin/Functions/packDepth","./Shaders/Builtin/Functions/phong","./Shaders/Builtin/Functions/pointAlongRay","./Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval","./Shaders/Builtin/Functions/RGBToHSB","./Shaders/Builtin/Functions/RGBToHSL","./Shaders/Builtin/Functions/RGBToXYZ","./Shaders/Builtin/Functions/saturation","./Shaders/Builtin/Functions/shadowDepthCompare","./Shaders/Builtin/Functions/shadowVisibility","./Shaders/Builtin/Functions/signNotZero","./Shaders/Builtin/Functions/tangentToEyeSpaceMatrix","./Shaders/Builtin/Functions/translateRelativeToEye","./Shaders/Builtin/Functions/translucentPhong","./Shaders/Builtin/Functions/transpose","./Shaders/Builtin/Functions/unpackDepth","./Shaders/Builtin/Functions/windowToEyeCoordinates","./Shaders/Builtin/Functions/writeDepthClampedToFarPlane","./Shaders/Builtin/Functions/XYZToRGB","./Shaders/Builtin/Structs/depthRangeStruct","./Shaders/Builtin/Structs/ellipsoid","./Shaders/Builtin/Structs/material","./Shaders/Builtin/Structs/materialInput","./Shaders/Builtin/Structs/ray","./Shaders/Builtin/Structs/raySegment","./Shaders/Builtin/Structs/shadowParameters","./Shaders/CompositeOITFS","./Shaders/DepthPlaneFS","./Shaders/DepthPlaneVS","./Shaders/EllipsoidFS","./Shaders/EllipsoidVS","./Shaders/GlobeFS","./Shaders/GlobeVS","./Shaders/GroundAtmosphere","./Shaders/Materials/BumpMapMaterial","./Shaders/Materials/CheckerboardMaterial","./Shaders/Materials/DotMaterial","./Shaders/Materials/ElevationContourMaterial","./Shaders/Materials/ElevationRampMaterial","./Shaders/Materials/FadeMaterial","./Shaders/Materials/GridMaterial","./Shaders/Materials/NormalMapMaterial","./Shaders/Materials/PolylineArrowMaterial","./Shaders/Materials/PolylineDashMaterial","./Shaders/Materials/PolylineGlowMaterial","./Shaders/Materials/PolylineOutlineMaterial","./Shaders/Materials/RimLightingMaterial","./Shaders/Materials/SlopeRampMaterial","./Shaders/Materials/StripeMaterial","./Shaders/Materials/Water","./Shaders/PointPrimitiveCollectionFS","./Shaders/PointPrimitiveCollectionVS","./Shaders/PolylineCommon","./Shaders/PolylineFS","./Shaders/PolylineVS","./Shaders/PostProcessFilters/AdditiveBlend","./Shaders/PostProcessFilters/BrightPass","./Shaders/PostProcessFilters/FXAA","./Shaders/PostProcessFilters/GaussianBlur1D","./Shaders/PostProcessFilters/PassThrough","./Shaders/PostProcessFilters/PointCloudEyeDomeLighting","./Shaders/ReprojectWebMercatorFS","./Shaders/ReprojectWebMercatorVS","./Shaders/ShadowVolumeFS","./Shaders/ShadowVolumeVS","./Shaders/SkyAtmosphereFS","./Shaders/SkyAtmosphereVS","./Shaders/SkyBoxFS","./Shaders/SkyBoxVS","./Shaders/SunFS","./Shaders/SunTextureFS","./Shaders/SunVS","./Shaders/Vector3DTilePolylinesVS","./Shaders/ViewportQuadFS","./Shaders/ViewportQuadVS","./ThirdParty/Autolinker","./ThirdParty/crunch","./ThirdParty/earcut-2.1.1","./ThirdParty/GltfPipeline/addDefaults","./ThirdParty/GltfPipeline/addExtensionsRequired","./ThirdParty/GltfPipeline/addExtensionsUsed","./ThirdParty/GltfPipeline/addPipelineExtras","./ThirdParty/GltfPipeline/addToArray","./ThirdParty/GltfPipeline/byteLengthForComponentType","./ThirdParty/GltfPipeline/findAccessorMinMax","./ThirdParty/GltfPipeline/ForEach","./ThirdParty/GltfPipeline/getAccessorByteStride","./ThirdParty/GltfPipeline/getJointCountForMaterials","./ThirdParty/GltfPipeline/glslTypeToWebGLConstant","./ThirdParty/GltfPipeline/numberOfComponentsForType","./ThirdParty/GltfPipeline/parseBinaryGltf","./ThirdParty/GltfPipeline/processModelMaterialsCommon","./ThirdParty/GltfPipeline/processPbrMetallicRoughness","./ThirdParty/GltfPipeline/removeExtensionsRequired","./ThirdParty/GltfPipeline/removeExtensionsUsed","./ThirdParty/GltfPipeline/removePipelineExtras","./ThirdParty/GltfPipeline/techniqueParameterForSemantic","./ThirdParty/GltfPipeline/updateVersion","./ThirdParty/GltfPipeline/webGLConstantToGlslType","./ThirdParty/google-earth-dbroot-parser","./ThirdParty/jsep","./ThirdParty/kdbush","./ThirdParty/knockout-3.4.2","./ThirdParty/knockout-es5","./ThirdParty/knockout","./ThirdParty/measureText","./ThirdParty/mersenne-twister","./ThirdParty/NoSleep","./ThirdParty/pako_inflate","./ThirdParty/protobuf-minimal","./ThirdParty/Shaders/FXAA3_11","./ThirdParty/sprintf","./ThirdParty/topojson","./ThirdParty/Tween","./ThirdParty/Uri","./ThirdParty/when","./ThirdParty/zip","./Widgets/Animation/Animation","./Widgets/Animation/AnimationViewModel","./Widgets/BaseLayerPicker/BaseLayerPicker","./Widgets/BaseLayerPicker/BaseLayerPickerViewModel","./Widgets/BaseLayerPicker/createDefaultImageryProviderViewModels","./Widgets/BaseLayerPicker/createDefaultTerrainProviderViewModels","./Widgets/BaseLayerPicker/ProviderViewModel","./Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector","./Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel","./Widgets/CesiumInspector/CesiumInspector","./Widgets/CesiumInspector/CesiumInspectorViewModel","./Widgets/CesiumWidget/CesiumWidget","./Widgets/ClockViewModel","./Widgets/Command","./Widgets/createCommand","./Widgets/FullscreenButton/FullscreenButton","./Widgets/FullscreenButton/FullscreenButtonViewModel","./Widgets/Geocoder/Geocoder","./Widgets/Geocoder/GeocoderViewModel","./Widgets/getElement","./Widgets/HomeButton/HomeButton","./Widgets/HomeButton/HomeButtonViewModel","./Widgets/InfoBox/InfoBox","./Widgets/InfoBox/InfoBoxViewModel","./Widgets/NavigationHelpButton/NavigationHelpButton","./Widgets/NavigationHelpButton/NavigationHelpButtonViewModel","./Widgets/PerformanceWatchdog/PerformanceWatchdog","./Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel","./Widgets/ProjectionPicker/ProjectionPicker","./Widgets/ProjectionPicker/ProjectionPickerViewModel","./Widgets/SceneModePicker/SceneModePicker","./Widgets/SceneModePicker/SceneModePickerViewModel","./Widgets/SelectionIndicator/SelectionIndicator","./Widgets/SelectionIndicator/SelectionIndicatorViewModel","./Widgets/subscribeAndEvaluate","./Widgets/SvgPathBindingHandler","./Widgets/Timeline/Timeline","./Widgets/Timeline/TimelineHighlightRange","./Widgets/Timeline/TimelineTrack","./Widgets/ToggleButtonViewModel","./Widgets/Viewer/Viewer","./Widgets/Viewer/viewerCesium3DTilesInspectorMixin","./Widgets/Viewer/viewerCesiumInspectorMixin","./Widgets/Viewer/viewerDragDropMixin","./Widgets/Viewer/viewerPerformanceWatchdogMixin","./Widgets/VRButton/VRButton","./Widgets/VRButton/VRButtonViewModel","./Workers/createTaskProcessorWorker"],function(e,t,r,i,n,o,a,s,l,u,c,d,h,p,f,m,g,_,v,y,b,C,S,w,T,E,A,x,P,D,I,O,M,R,L,N,k,F,B,U,V,z,G,W,H,j,q,Y,X,Q,Z,K,J,$,ee,te,re,ie,ne,oe,ae,se,le,ue,ce,de,he,pe,fe,me,ge,_e,ve,ye,be,Ce,Se,we,Te,Ee,Ae,xe,Pe,De,Ie,Oe,Me,Re,Le,Ne,ke,Fe,Be,Ue,Ve,ze,Ge,We,He,je,qe,Ye,Xe,Qe,Ze,Ke,Je,$e,et,tt,rt,it,nt,ot,at,st,lt,ut,ct,dt,ht,pt,ft,mt,gt,_t,vt,yt,bt,Ct,St,wt,Tt,Et,At,xt,Pt,Dt,It,Ot,Mt,Rt,Lt,Nt,kt,Ft,Bt,Ut,Vt,zt,Gt,Wt,Ht,jt,qt,Yt,Xt,Qt,Zt,Kt,Jt,$t,er,tr,rr,ir,nr,or,ar,sr,lr,ur,cr,dr,hr,pr,fr,mr,gr,_r,vr,yr,br,Cr,Sr,wr,Tr,Er,Ar,xr,Pr,Dr,Ir,Or,Mr,Rr,Lr,Nr,kr,Fr,Br,Ur,Vr,zr,Gr,Wr,Hr,jr,qr,Yr,Xr,Qr,Zr,Kr,Jr,$r,ei,ti,ri,ii,ni,oi,ai,si,li,ui,ci,di,hi,pi,fi,mi,gi,_i,vi,yi,bi,Ci,Si,wi,Ti,Ei,Ai,xi,Pi,Di,Ii,Oi,Mi,Ri,Li,Ni,ki,Fi,Bi,Ui,Vi,zi,Gi,Wi,Hi,ji,qi,Yi,Xi,Qi,Zi,Ki,Ji,$i,en,tn,rn,nn,on,an,sn,ln,un,cn,dn,hn,pn,fn,mn,gn,_n,vn,yn,bn,Cn,Sn,wn,Tn,En,An,xn,Pn,Dn,In,On,Mn,Rn,Ln,Nn,kn,Fn,Bn,Un,Vn,zn,Gn,Wn,Hn,jn,qn,Yn,Xn,Qn,Zn,Kn,Jn,$n,eo,to,ro,io,no,oo,ao,so,lo,uo,co,ho,po,fo,mo,go,_o,vo,yo,bo,Co,So,wo,To,Eo,Ao,xo,Po,Do,Io,Oo,Mo,Ro,Lo,No,ko,Fo,Bo,Uo,Vo,zo,Go,Wo,Ho,jo,qo,Yo,Xo,Qo,Zo,Ko,Jo,$o,ea,ta,ra,ia,na,oa,aa,sa,la,ua,ca,da,ha,pa,fa,ma,ga,_a,va,ya,ba,Ca,Sa,wa,Ta,Ea,Aa,xa,Pa,Da,Ia,Oa,Ma,Ra,La,Na,ka,Fa,Ba,Ua,Va,za,Ga,Wa,Ha,ja,qa,Ya,Xa,Qa,Za,Ka,Ja,$a,es,ts,rs,is,ns,os,as,ss,ls,us,cs,ds,hs,ps,fs,ms,gs,_s,vs,ys,bs,Cs,Ss,ws,Ts,Es,As,xs,Ps,Ds,Is,Os,Ms,Rs,Ls,Ns,ks,Fs,Bs,Us,Vs,zs,Gs,Ws,Hs,js,qs,Ys,Xs,Qs,Zs,Ks,Js,$s,el,tl,rl,il,nl,ol,al,sl,ll,ul,cl,dl,hl,pl,fl,ml,gl,_l,vl,yl,bl,Cl,Sl,wl,Tl,El,Al,xl,Pl,Dl,Il,Ol,Ml,Rl,Ll,Nl,kl,Fl,Bl,Ul,Vl,zl,Gl,Wl,Hl,jl,ql,Yl,Xl,Ql,Zl,Kl,Jl,$l,eu,tu,ru,iu,nu,ou,au,su,lu,uu,cu,du,hu,pu,fu,mu,gu,_u,vu,yu,bu,Cu,Su,wu,Tu,Eu,Au,xu,Pu,Du,Iu,Ou,Mu,Ru,Lu,Nu,ku,Fu,Bu,Uu,Vu,zu,Gu,Wu,Hu,ju,qu,Yu,Xu,Qu,Zu,Ku,Ju,$u,ec,tc,rc,ic,nc,oc,ac,sc,lc,uc,cc,dc,hc,pc,fc,mc,gc,_c,vc,yc,bc,Cc,Sc,wc,Tc,Ec,Ac,xc,Pc,Dc,Ic,Oc,Mc,Rc,Lc,Nc,kc,Fc,Bc,Uc,Vc,zc,Gc,Wc,Hc,jc,qc,Yc,Xc,Qc,Zc,Kc,Jc,$c,ed,td,rd,id,nd,od,ad,sd,ld,ud,cd,dd,hd,pd,fd,md,gd,_d,vd,yd,bd,Cd,Sd,wd,Td,Ed,Ad,xd,Pd,Dd,Id,Od,Md,Rd,Ld,Nd,kd,Fd,Bd,Ud,Vd,zd,Gd,Wd,Hd,jd,qd,Yd,Xd,Qd,Zd,Kd,Jd,$d,eh,th,rh,ih,nh,oh,ah,sh,lh,uh,ch,dh,hh,ph,fh,mh,gh,_h,vh,yh,bh,Ch,Sh,wh,Th,Eh,Ah,xh,Ph,Dh,Ih,Oh,Mh,Rh,Lh,Nh,kh,Fh,Bh,Uh,Vh,zh,Gh,Wh,Hh,jh,qh,Yh,Xh,Qh,Zh,Kh,Jh,$h,ep,tp,rp,ip,np,op,ap,sp,lp,up,cp,dp,hp,pp,fp,mp,gp,_p,vp,yp,bp,Cp,Sp,wp,Tp,Ep,Ap,xp,Pp,Dp,Ip,Op,Mp,Rp,Lp,Np,kp,Fp,Bp,Up,Vp,zp,Gp,Wp,Hp,jp,qp,Yp,Xp,Qp,Zp,Kp,Jp,$p,ef,tf,rf,nf,of,af,sf,lf,uf,cf,df,hf,pf,ff,mf,gf,_f,vf,yf,bf,Cf,Sf,wf){"use strict";var Tf={VERSION:"1.42",_shaders:{}};return Tf.appendForwardSlash=e,Tf.arrayFill=t,Tf.arrayRemoveDuplicates=r,Tf.arraySlice=i,Tf.AssociativeArray=n,Tf.AttributeCompression=o,Tf.AxisAlignedBoundingBox=a,Tf.barycentricCoordinates=s,Tf.binarySearch=l,Tf.BingMapsApi=u,Tf.BingMapsGeocoderService=c,Tf.BoundingRectangle=d,Tf.BoundingSphere=h,Tf.BoxGeometry=p,Tf.BoxOutlineGeometry=f,Tf.buildModuleUrl=m,Tf.cancelAnimationFrame=g,Tf.Cartesian2=_,Tf.Cartesian3=v,Tf.Cartesian4=y,Tf.Cartographic=b,Tf.CartographicGeocoderService=C,Tf.CatmullRomSpline=S,Tf.CesiumTerrainProvider=w,Tf.Check=T,Tf.CircleGeometry=E,Tf.CircleOutlineGeometry=A,Tf.ClippingPlaneCollection=x,Tf.Clock=P,Tf.ClockRange=D,Tf.ClockStep=I,Tf.clone=O,Tf.Color=M,Tf.ColorGeometryInstanceAttribute=R,Tf.combine=L,Tf.ComponentDatatype=N,Tf.CompressedTextureBuffer=k,Tf.CornerType=F,Tf.CorridorGeometry=B,Tf.CorridorGeometryLibrary=U,Tf.CorridorOutlineGeometry=V,Tf.createGuid=z,Tf.Credit=G,Tf.CubicRealPolynomial=W,Tf.CullingVolume=H,Tf.CylinderGeometry=j,Tf.CylinderGeometryLibrary=q,Tf.CylinderOutlineGeometry=Y,Tf.decodeGoogleEarthEnterpriseData=X,Tf.DefaultProxy=Q,Tf.defaultValue=Z,Tf.defined=K,Tf.defineProperties=J,Tf.deprecationWarning=$,Tf.destroyObject=ee,Tf.DeveloperError=te,Tf.DistanceDisplayCondition=re,Tf.DistanceDisplayConditionGeometryInstanceAttribute=ie,Tf.DoublyLinkedList=ne,Tf.EarthOrientationParameters=oe,Tf.EarthOrientationParametersSample=ae,Tf.EasingFunction=se,Tf.EllipseGeometry=le,Tf.EllipseGeometryLibrary=ue,Tf.EllipseOutlineGeometry=ce,Tf.Ellipsoid=de,Tf.EllipsoidalOccluder=he,Tf.EllipsoidGeodesic=pe,Tf.EllipsoidGeometry=fe,Tf.EllipsoidOutlineGeometry=me,Tf.EllipsoidTangentPlane=ge,Tf.EllipsoidTerrainProvider=_e,Tf.EncodedCartesian3=ve,Tf.Event=ye,Tf.EventHelper=be,Tf.ExtrapolationType=Ce,Tf.FeatureDetection=Se,Tf.formatError=we,Tf.freezeObject=Te,Tf.FrustumGeometry=Ee,Tf.FrustumOutlineGeometry=Ae,Tf.Fullscreen=xe,Tf.GeocoderService=Pe,Tf.GeographicProjection=De,Tf.GeographicTilingScheme=Ie,Tf.Geometry=Oe,Tf.GeometryAttribute=Me,Tf.GeometryAttributes=Re,Tf.GeometryInstance=Le,Tf.GeometryInstanceAttribute=Ne,Tf.GeometryPipeline=ke,Tf.GeometryType=Fe,Tf.getAbsoluteUri=Be,Tf.getBaseUri=Ue,Tf.getExtensionFromUri=Ve,Tf.getFilenameFromUri=ze,Tf.getImagePixels=Ge,Tf.getMagic=We,Tf.getStringFromTypedArray=He,Tf.getTimestamp=je,Tf.GoogleEarthEnterpriseMetadata=qe,Tf.GoogleEarthEnterpriseTerrainData=Ye,Tf.GoogleEarthEnterpriseTerrainProvider=Xe,Tf.GoogleEarthEnterpriseTileInformation=Qe,Tf.GregorianDate=Ze,Tf.HeadingPitchRange=Ke,Tf.HeadingPitchRoll=Je,Tf.Heap=$e, +Tf.HeightmapTerrainData=et,Tf.HeightmapTessellator=tt,Tf.HermitePolynomialApproximation=rt,Tf.HermiteSpline=it,Tf.Iau2000Orientation=nt,Tf.Iau2006XysData=ot,Tf.Iau2006XysSample=at,Tf.IauOrientationAxes=st,Tf.IauOrientationParameters=lt,Tf.IndexDatatype=ut,Tf.InterpolationAlgorithm=ct,Tf.Intersect=dt,Tf.Intersections2D=ht,Tf.IntersectionTests=pt,Tf.Interval=ft,Tf.isArray=mt,Tf.isBitSet=gt,Tf.isBlobUri=_t,Tf.isCrossOriginUrl=vt,Tf.isDataUri=yt,Tf.isLeapYear=bt,Tf.Iso8601=Ct,Tf.JulianDate=St,Tf.KeyboardEventModifier=wt,Tf.LagrangePolynomialApproximation=Tt,Tf.LeapSecond=Et,Tf.LinearApproximation=At,Tf.LinearSpline=xt,Tf.loadArrayBuffer=Pt,Tf.loadBlob=Dt,Tf.loadCRN=It,Tf.loadImage=Ot,Tf.loadImageFromTypedArray=Mt,Tf.loadImageViaBlob=Rt,Tf.loadJson=Lt,Tf.loadJsonp=Nt,Tf.loadKTX=kt,Tf.loadText=Ft,Tf.loadWithXhr=Bt,Tf.loadXML=Ut,Tf.ManagedArray=Vt,Tf.MapboxApi=zt,Tf.MapProjection=Gt,Tf.Math=Wt,Tf.Matrix2=Ht,Tf.Matrix3=jt,Tf.Matrix4=qt,Tf.mergeSort=Yt,Tf.NearFarScalar=Xt,Tf.objectToQuery=Qt,Tf.Occluder=Zt,Tf.oneTimeWarning=Kt,Tf.OrientedBoundingBox=Jt,Tf.OrthographicFrustum=$t,Tf.OrthographicOffCenterFrustum=er,Tf.Packable=tr,Tf.PackableForInterpolation=rr,Tf.parseResponseHeaders=ir,Tf.PerspectiveFrustum=nr,Tf.PerspectiveOffCenterFrustum=or,Tf.PinBuilder=ar,Tf.PixelFormat=sr,Tf.Plane=lr,Tf.PlaneGeometry=ur,Tf.PlaneOutlineGeometry=cr,Tf.pointInsideTriangle=dr,Tf.PolygonGeometry=hr,Tf.PolygonGeometryLibrary=pr,Tf.PolygonHierarchy=fr,Tf.PolygonOutlineGeometry=mr,Tf.PolygonPipeline=gr,Tf.PolylineGeometry=_r,Tf.PolylinePipeline=vr,Tf.PolylineVolumeGeometry=yr,Tf.PolylineVolumeGeometryLibrary=br,Tf.PolylineVolumeOutlineGeometry=Cr,Tf.PrimitiveType=Sr,Tf.QuadraticRealPolynomial=wr,Tf.QuantizedMeshTerrainData=Tr,Tf.QuarticRealPolynomial=Er,Tf.Quaternion=Ar,Tf.QuaternionSpline=xr,Tf.queryToObject=Pr,Tf.Queue=Dr,Tf.Ray=Ir,Tf.Rectangle=Or,Tf.RectangleGeometry=Mr,Tf.RectangleGeometryLibrary=Rr,Tf.RectangleOutlineGeometry=Lr,Tf.ReferenceFrame=Nr,Tf.Request=kr,Tf.requestAnimationFrame=Fr,Tf.RequestErrorEvent=Br,Tf.RequestScheduler=Ur,Tf.RequestState=Vr,Tf.RequestType=zr,Tf.Resource=Gr,Tf.RuntimeError=Wr,Tf.sampleTerrain=Hr,Tf.sampleTerrainMostDetailed=jr,Tf.scaleToGeodeticSurface=qr,Tf.ScreenSpaceEventHandler=Yr,Tf.ScreenSpaceEventType=Xr,Tf.ShowGeometryInstanceAttribute=Qr,Tf.Simon1994PlanetaryPositions=Zr,Tf.SimplePolylineGeometry=Kr,Tf.SphereGeometry=Jr,Tf.SphereOutlineGeometry=$r,Tf.Spherical=ei,Tf.Spline=ti,Tf.subdivideArray=ri,Tf.TaskProcessor=ii,Tf.TerrainData=ni,Tf.TerrainEncoding=oi,Tf.TerrainMesh=ai,Tf.TerrainProvider=si,Tf.TerrainQuantization=li,Tf.TileAvailability=ui,Tf.TileProviderError=ci,Tf.TilingScheme=di,Tf.TimeConstants=hi,Tf.TimeInterval=pi,Tf.TimeIntervalCollection=fi,Tf.TimeStandard=mi,Tf.Tipsify=gi,Tf.Transforms=_i,Tf.TranslationRotationScale=vi,Tf.TridiagonalSystemSolver=yi,Tf.TrustedServers=bi,Tf.VertexFormat=Ci,Tf.VideoSynchronizer=Si,Tf.Visibility=wi,Tf.VRTheWorldTerrainProvider=Ti,Tf.WallGeometry=Ei,Tf.WallGeometryLibrary=Ai,Tf.WallOutlineGeometry=xi,Tf.WebGLConstants=Pi,Tf.WebMercatorProjection=Di,Tf.WebMercatorTilingScheme=Ii,Tf.WeightSpline=Oi,Tf.WindingOrder=Mi,Tf.wrapFunction=Ri,Tf.writeTextToCanvas=Li,Tf.BillboardGraphics=Ni,Tf.BillboardVisualizer=ki,Tf.BoundingSphereState=Fi,Tf.BoxGeometryUpdater=Bi,Tf.BoxGraphics=Ui,Tf.CallbackProperty=Vi,Tf.CheckerboardMaterialProperty=zi,Tf.ColorMaterialProperty=Gi,Tf.CompositeEntityCollection=Wi,Tf.CompositeMaterialProperty=Hi,Tf.CompositePositionProperty=ji,Tf.CompositeProperty=qi,Tf.ConstantPositionProperty=Yi,Tf.ConstantProperty=Xi,Tf.CorridorGeometryUpdater=Qi,Tf.CorridorGraphics=Zi,Tf.createMaterialPropertyDescriptor=Ki,Tf.createPropertyDescriptor=Ji,Tf.createRawPropertyDescriptor=$i,Tf.CustomDataSource=en,Tf.CylinderGeometryUpdater=tn,Tf.CylinderGraphics=rn,Tf.CzmlDataSource=nn,Tf.DataSource=on,Tf.DataSourceClock=an,Tf.DataSourceCollection=sn,Tf.DataSourceDisplay=ln,Tf.dynamicGeometryGetBoundingSphere=un,Tf.DynamicGeometryUpdater=cn,Tf.EllipseGeometryUpdater=dn,Tf.EllipseGraphics=hn,Tf.EllipsoidGeometryUpdater=pn,Tf.EllipsoidGraphics=fn,Tf.Entity=mn,Tf.EntityCluster=gn,Tf.EntityCollection=_n,Tf.EntityView=vn,Tf.GeoJsonDataSource=yn,Tf.GeometryUpdater=bn,Tf.GeometryVisualizer=Cn,Tf.GridMaterialProperty=Sn,Tf.ImageMaterialProperty=wn,Tf.KmlCamera=Tn,Tf.KmlDataSource=En,Tf.KmlLookAt=An,Tf.KmlTour=xn,Tf.KmlTourFlyTo=Pn,Tf.KmlTourWait=Dn,Tf.LabelGraphics=In,Tf.LabelVisualizer=On,Tf.MaterialProperty=Mn,Tf.ModelGraphics=Rn,Tf.ModelVisualizer=Ln,Tf.NodeTransformationProperty=Nn,Tf.PathGraphics=kn,Tf.PathVisualizer=Fn,Tf.PlaneGeometryUpdater=Bn,Tf.PlaneGraphics=Un,Tf.PointGraphics=Vn,Tf.PointVisualizer=zn,Tf.PolygonGeometryUpdater=Gn,Tf.PolygonGraphics=Wn,Tf.PolylineArrowMaterialProperty=Hn,Tf.PolylineDashMaterialProperty=jn,Tf.PolylineGeometryUpdater=qn,Tf.PolylineGlowMaterialProperty=Yn,Tf.PolylineGraphics=Xn,Tf.PolylineOutlineMaterialProperty=Qn,Tf.PolylineVolumeGeometryUpdater=Zn,Tf.PolylineVolumeGraphics=Kn,Tf.PositionProperty=Jn,Tf.PositionPropertyArray=$n,Tf.Property=eo,Tf.PropertyArray=to,Tf.PropertyBag=ro,Tf.RectangleGeometryUpdater=io,Tf.RectangleGraphics=no,Tf.ReferenceProperty=oo,Tf.Rotation=ao,Tf.SampledPositionProperty=so,Tf.SampledProperty=lo,Tf.ScaledPositionProperty=uo,Tf.StaticGeometryColorBatch=co,Tf.StaticGeometryPerMaterialBatch=ho,Tf.StaticGroundGeometryColorBatch=po,Tf.StaticOutlineGeometryBatch=fo,Tf.StripeMaterialProperty=mo,Tf.StripeOrientation=go,Tf.TimeIntervalCollectionPositionProperty=_o,Tf.TimeIntervalCollectionProperty=vo,Tf.VelocityOrientationProperty=yo,Tf.VelocityVectorProperty=bo,Tf.Visualizer=Co,Tf.WallGeometryUpdater=So,Tf.WallGraphics=wo,Tf.AutomaticUniforms=To,Tf.Buffer=Eo,Tf.BufferUsage=Ao,Tf.ClearCommand=xo,Tf.ComputeCommand=Po,Tf.ComputeEngine=Do,Tf.Context=Io,Tf.ContextLimits=Oo,Tf.createUniform=Mo,Tf.createUniformArray=Ro,Tf.CubeMap=Lo,Tf.CubeMapFace=No,Tf.DrawCommand=ko,Tf.Framebuffer=Fo,Tf.freezeRenderState=Bo,Tf.loadCubeMap=Uo,Tf.MipmapHint=Vo,Tf.modernizeShader=zo,Tf.Pass=Go,Tf.PassState=Wo,Tf.PickFramebuffer=Ho,Tf.PixelDatatype=jo,Tf.Renderbuffer=qo,Tf.RenderbufferFormat=Yo,Tf.RenderState=Xo,Tf.Sampler=Qo,Tf.ShaderCache=Zo,Tf.ShaderProgram=Ko,Tf.ShaderSource=Jo,Tf.Texture=$o,Tf.TextureMagnificationFilter=ea,Tf.TextureMinificationFilter=ta,Tf.TextureWrap=ra,Tf.UniformState=ia,Tf.VertexArray=na,Tf.VertexArrayFacade=oa,Tf.Appearance=aa,Tf.ArcGisMapServerImageryProvider=sa,Tf.AttributeType=la,Tf.Axis=ua,Tf.Batched3DModel3DTileContent=ca,Tf.BatchTable=da,Tf.Billboard=ha,Tf.BillboardCollection=pa,Tf.BingMapsImageryProvider=fa,Tf.BingMapsStyle=ma,Tf.BlendEquation=ga,Tf.BlendFunction=_a,Tf.BlendingState=va,Tf.BlendOption=ya,Tf.BoxEmitter=ba,Tf.BrdfLutGenerator=Ca,Tf.Camera=Sa,Tf.CameraEventAggregator=wa,Tf.CameraEventType=Ta,Tf.CameraFlightPath=Ea,Tf.Cesium3DTile=Aa,Tf.Cesium3DTileBatchTable=xa,Tf.Cesium3DTileChildrenVisibility=Pa,Tf.Cesium3DTileColorBlendMode=Da,Tf.Cesium3DTileContent=Ia,Tf.Cesium3DTileContentFactory=Oa,Tf.Cesium3DTileContentState=Ma,Tf.Cesium3DTileFeature=Ra,Tf.Cesium3DTileFeatureTable=La,Tf.Cesium3DTileOptimizationHint=Na,Tf.Cesium3DTileOptimizations=ka,Tf.Cesium3DTilePointFeature=Fa,Tf.Cesium3DTileRefine=Ba,Tf.Cesium3DTileset=Ua,Tf.Cesium3DTilesetStatistics=Va,Tf.Cesium3DTilesetTraversal=za,Tf.Cesium3DTileStyle=Ga,Tf.Cesium3DTileStyleEngine=Wa,Tf.CesiumIon=Ha,Tf.CesiumIonResource=ja,Tf.CircleEmitter=qa,Tf.ClassificationModel=Ya,Tf.ClassificationPrimitive=Xa,Tf.ClassificationType=Qa,Tf.ColorBlendMode=Za,Tf.Composite3DTileContent=Ka,Tf.ConditionsExpression=Ja,Tf.ConeEmitter=$a,Tf.createBillboardPointCallback=es,Tf.createOpenStreetMapImageryProvider=ts,Tf.createTangentSpaceDebugPrimitive=rs,Tf.createTileMapServiceImageryProvider=is,Tf.CreditDisplay=ns,Tf.CullFace=os,Tf.DebugAppearance=as,Tf.DebugCameraPrimitive=ss,Tf.DebugModelMatrixPrimitive=ls,Tf.DepthFunction=us,Tf.DepthPlane=cs,Tf.DeviceOrientationCameraController=ds,Tf.DiscardMissingTileImagePolicy=hs,Tf.EllipsoidPrimitive=ps,Tf.EllipsoidSurfaceAppearance=fs,Tf.Empty3DTileContent=ms,Tf.Expression=gs,Tf.ExpressionNodeType=_s,Tf.Fog=vs,Tf.FrameRateMonitor=ys,Tf.FrameState=bs,Tf.FrustumCommands=Cs,Tf.FXAA=Ss,Tf.Geometry3DTileContent=ws,Tf.getBinaryAccessor=Ts,Tf.GetFeatureInfoFormat=Es,Tf.Globe=As,Tf.GlobeDepth=xs,Tf.GlobeSurfaceShaderSet=Ps,Tf.GlobeSurfaceTile=Ds,Tf.GlobeSurfaceTileProvider=Is,Tf.GoogleEarthEnterpriseImageryProvider=Os,Tf.GoogleEarthEnterpriseMapsProvider=Ms,Tf.GridImageryProvider=Rs,Tf.GroundPrimitive=Ls,Tf.HeightReference=Ns,Tf.HorizontalOrigin=ks,Tf.Imagery=Fs,Tf.ImageryLayer=Bs,Tf.ImageryLayerCollection=Us,Tf.ImageryLayerFeatureInfo=Vs,Tf.ImageryProvider=zs,Tf.ImagerySplitDirection=Gs,Tf.ImageryState=Ws,Tf.Instanced3DModel3DTileContent=Hs,Tf.InvertClassification=js,Tf.JobScheduler=qs,Tf.JobType=Ys,Tf.Label=Xs,Tf.LabelCollection=Qs,Tf.LabelStyle=Zs,Tf.MapboxImageryProvider=Ks,Tf.MapMode2D=Js,Tf.Material=$s,Tf.MaterialAppearance=el,Tf.Model=tl,Tf.ModelAnimation=rl,Tf.ModelAnimationCache=il,Tf.ModelAnimationCollection=nl,Tf.ModelAnimationLoop=ol,Tf.ModelAnimationState=al,Tf.ModelInstance=sl,Tf.ModelInstanceCollection=ll,Tf.ModelLoadResources=ul,Tf.ModelMaterial=cl,Tf.ModelMesh=dl,Tf.ModelNode=hl,Tf.ModelUtility=pl,Tf.Moon=fl,Tf.NeverTileDiscardPolicy=ml,Tf.OIT=gl,Tf.Particle=_l,Tf.ParticleBurst=vl,Tf.ParticleEmitter=yl,Tf.ParticleSystem=bl,Tf.PerformanceDisplay=Cl,Tf.PerInstanceColorAppearance=Sl,Tf.PickDepth=wl,Tf.PointCloud3DTileContent=Tl,Tf.PointCloudEyeDomeLighting=El,Tf.PointCloudShading=Al,Tf.PointPrimitive=xl,Tf.PointPrimitiveCollection=Pl,Tf.Polyline=Dl,Tf.PolylineCollection=Il,Tf.PolylineColorAppearance=Ol,Tf.PolylineMaterialAppearance=Ml,Tf.Primitive=Rl,Tf.PrimitiveCollection=Ll,Tf.PrimitivePipeline=Nl,Tf.PrimitiveState=kl,Tf.QuadtreeOccluders=Fl,Tf.QuadtreePrimitive=Bl,Tf.QuadtreeTile=Ul,Tf.QuadtreeTileLoadState=Vl,Tf.QuadtreeTileProvider=zl,Tf.Scene=Gl,Tf.SceneMode=Wl,Tf.SceneTransforms=Hl,Tf.SceneTransitioner=jl,Tf.ScreenSpaceCameraController=ql,Tf.ShadowMap=Yl,Tf.ShadowMapShader=Xl,Tf.ShadowMode=Ql,Tf.SingleTileImageryProvider=Zl,Tf.SkyAtmosphere=Kl,Tf.SkyBox=Jl,Tf.SphereEmitter=$l,Tf.StencilFunction=eu,Tf.StencilOperation=tu,Tf.StyleExpression=ru,Tf.Sun=iu,Tf.SunPostProcess=nu,Tf.TerrainState=ou,Tf.TextureAtlas=au,Tf.TileBoundingRegion=su,Tf.TileBoundingSphere=lu,Tf.TileBoundingVolume=uu,Tf.TileCoordinatesImageryProvider=cu,Tf.TileDiscardPolicy=du,Tf.TileImagery=hu,Tf.TileOrientedBoundingBox=pu,Tf.TileReplacementQueue=fu,Tf.Tileset3DTileContent=mu,Tf.TileState=gu,Tf.TileTerrain=_u,Tf.TimeDynamicImagery=vu,Tf.TweenCollection=yu,Tf.UrlTemplateImageryProvider=bu,Tf.Vector3DTileBatch=Cu,Tf.Vector3DTileContent=Su,Tf.Vector3DTileGeometry=wu,Tf.Vector3DTilePoints=Tu,Tf.Vector3DTilePolygons=Eu,Tf.Vector3DTilePolylines=Au,Tf.Vector3DTilePrimitive=xu,Tf.VerticalOrigin=Pu,Tf.ViewportQuad=Du,Tf.WebMapServiceImageryProvider=Iu,Tf.WebMapTileServiceImageryProvider=Ou,Tf._shaders.AdjustTranslucentFS=Mu,Tf._shaders.AllMaterialAppearanceFS=Ru,Tf._shaders.AllMaterialAppearanceVS=Lu,Tf._shaders.BasicMaterialAppearanceFS=Nu,Tf._shaders.BasicMaterialAppearanceVS=ku,Tf._shaders.EllipsoidSurfaceAppearanceFS=Fu,Tf._shaders.EllipsoidSurfaceAppearanceVS=Bu,Tf._shaders.PerInstanceColorAppearanceFS=Uu,Tf._shaders.PerInstanceColorAppearanceVS=Vu,Tf._shaders.PerInstanceFlatColorAppearanceFS=zu,Tf._shaders.PerInstanceFlatColorAppearanceVS=Gu,Tf._shaders.PolylineColorAppearanceVS=Wu,Tf._shaders.PolylineMaterialAppearanceVS=Hu,Tf._shaders.TexturedMaterialAppearanceFS=ju,Tf._shaders.TexturedMaterialAppearanceVS=qu,Tf._shaders.BillboardCollectionFS=Yu,Tf._shaders.BillboardCollectionVS=Xu,Tf._shaders.BrdfLutGeneratorFS=Qu,Tf._shaders.degreesPerRadian=Zu,Tf._shaders.depthRange=Ku,Tf._shaders.epsilon1=Ju,Tf._shaders.epsilon2=$u,Tf._shaders.epsilon3=ec,Tf._shaders.epsilon4=tc,Tf._shaders.epsilon5=rc,Tf._shaders.epsilon6=ic,Tf._shaders.epsilon7=nc,Tf._shaders.infinity=oc,Tf._shaders.maxClippingPlanes=ac,Tf._shaders.oneOverPi=sc,Tf._shaders.oneOverTwoPi=lc,Tf._shaders.passCesium3DTile=uc,Tf._shaders.passCesium3DTileClassification=cc,Tf._shaders.passCesium3DTileClassificationIgnoreShow=dc,Tf._shaders.passClassification=hc,Tf._shaders.passCompute=pc,Tf._shaders.passEnvironment=fc,Tf._shaders.passGlobe=mc,Tf._shaders.passOpaque=gc,Tf._shaders.passOverlay=_c,Tf._shaders.passTerrainClassification=vc,Tf._shaders.passTranslucent=yc,Tf._shaders.pi=bc,Tf._shaders.piOverFour=Cc,Tf._shaders.piOverSix=Sc,Tf._shaders.piOverThree=wc,Tf._shaders.piOverTwo=Tc,Tf._shaders.radiansPerDegree=Ec,Tf._shaders.sceneMode2D=Ac,Tf._shaders.sceneMode3D=xc,Tf._shaders.sceneModeColumbusView=Pc,Tf._shaders.sceneModeMorphing=Dc,Tf._shaders.solarRadius=Ic,Tf._shaders.threePiOver2=Oc,Tf._shaders.twoPi=Mc,Tf._shaders.webMercatorMaxLatitude=Rc,Tf._shaders.CzmBuiltins=Lc,Tf._shaders.alphaWeight=Nc,Tf._shaders.antialias=kc,Tf._shaders.cascadeColor=Fc,Tf._shaders.cascadeDistance=Bc,Tf._shaders.cascadeMatrix=Uc,Tf._shaders.cascadeWeights=Vc,Tf._shaders.columbusViewMorph=zc,Tf._shaders.computePosition=Gc,Tf._shaders.cosineAndSine=Wc,Tf._shaders.decompressTextureCoordinates=Hc,Tf._shaders.depthClampFarPlane=jc,Tf._shaders.discardIfClippedWithIntersect=qc,Tf._shaders.discardIfClippedWithUnion=Yc,Tf._shaders.eastNorthUpToEyeCoordinates=Xc,Tf._shaders.ellipsoidContainsPoint=Qc,Tf._shaders.ellipsoidNew=Zc,Tf._shaders.ellipsoidWgs84TextureCoordinates=Kc,Tf._shaders.equalsEpsilon=Jc,Tf._shaders.eyeOffset=$c,Tf._shaders.eyeToWindowCoordinates=ed,Tf._shaders.fog=td,Tf._shaders.geodeticSurfaceNormal=rd,Tf._shaders.getDefaultMaterial=id,Tf._shaders.getLambertDiffuse=nd,Tf._shaders.getSpecular=od,Tf._shaders.getWaterNoise=ad,Tf._shaders.getWgs84EllipsoidEC=sd,Tf._shaders.HSBToRGB=ld,Tf._shaders.HSLToRGB=ud,Tf._shaders.hue=cd,Tf._shaders.isEmpty=dd,Tf._shaders.isFull=hd,Tf._shaders.latitudeToWebMercatorFraction=pd,Tf._shaders.luminance=fd,Tf._shaders.metersPerPixel=md,Tf._shaders.modelToWindowCoordinates=gd,Tf._shaders.multiplyWithColorBalance=_d,Tf._shaders.nearFarScalar=vd,Tf._shaders.octDecode=yd,Tf._shaders.packDepth=bd,Tf._shaders.phong=Cd,Tf._shaders.pointAlongRay=Sd,Tf._shaders.rayEllipsoidIntersectionInterval=wd,Tf._shaders.RGBToHSB=Td,Tf._shaders.RGBToHSL=Ed,Tf._shaders.RGBToXYZ=Ad,Tf._shaders.saturation=xd,Tf._shaders.shadowDepthCompare=Pd,Tf._shaders.shadowVisibility=Dd,Tf._shaders.signNotZero=Id,Tf._shaders.tangentToEyeSpaceMatrix=Od,Tf._shaders.translateRelativeToEye=Md,Tf._shaders.translucentPhong=Rd,Tf._shaders.transpose=Ld,Tf._shaders.unpackDepth=Nd,Tf._shaders.windowToEyeCoordinates=kd,Tf._shaders.writeDepthClampedToFarPlane=Fd,Tf._shaders.XYZToRGB=Bd,Tf._shaders.depthRangeStruct=Ud,Tf._shaders.ellipsoid=Vd,Tf._shaders.material=zd,Tf._shaders.materialInput=Gd,Tf._shaders.ray=Wd,Tf._shaders.raySegment=Hd,Tf._shaders.shadowParameters=jd,Tf._shaders.CompositeOITFS=qd,Tf._shaders.DepthPlaneFS=Yd,Tf._shaders.DepthPlaneVS=Xd,Tf._shaders.EllipsoidFS=Qd,Tf._shaders.EllipsoidVS=Zd,Tf._shaders.GlobeFS=Kd,Tf._shaders.GlobeVS=Jd,Tf._shaders.GroundAtmosphere=$d,Tf._shaders.BumpMapMaterial=eh,Tf._shaders.CheckerboardMaterial=th,Tf._shaders.DotMaterial=rh,Tf._shaders.ElevationContourMaterial=ih,Tf._shaders.ElevationRampMaterial=nh,Tf._shaders.FadeMaterial=oh,Tf._shaders.GridMaterial=ah,Tf._shaders.NormalMapMaterial=sh,Tf._shaders.PolylineArrowMaterial=lh,Tf._shaders.PolylineDashMaterial=uh,Tf._shaders.PolylineGlowMaterial=ch,Tf._shaders.PolylineOutlineMaterial=dh,Tf._shaders.RimLightingMaterial=hh,Tf._shaders.SlopeRampMaterial=ph,Tf._shaders.StripeMaterial=fh,Tf._shaders.Water=mh,Tf._shaders.PointPrimitiveCollectionFS=gh,Tf._shaders.PointPrimitiveCollectionVS=_h,Tf._shaders.PolylineCommon=vh,Tf._shaders.PolylineFS=yh,Tf._shaders.PolylineVS=bh,Tf._shaders.AdditiveBlend=Ch,Tf._shaders.BrightPass=Sh,Tf._shaders.FXAA=wh,Tf._shaders.GaussianBlur1D=Th,Tf._shaders.PassThrough=Eh,Tf._shaders.PointCloudEyeDomeLighting=Ah,Tf._shaders.ReprojectWebMercatorFS=xh,Tf._shaders.ReprojectWebMercatorVS=Ph,Tf._shaders.ShadowVolumeFS=Dh,Tf._shaders.ShadowVolumeVS=Ih,Tf._shaders.SkyAtmosphereFS=Oh,Tf._shaders.SkyAtmosphereVS=Mh,Tf._shaders.SkyBoxFS=Rh,Tf._shaders.SkyBoxVS=Lh,Tf._shaders.SunFS=Nh,Tf._shaders.SunTextureFS=kh,Tf._shaders.SunVS=Fh,Tf._shaders.Vector3DTilePolylinesVS=Bh,Tf._shaders.ViewportQuadFS=Uh,Tf._shaders.ViewportQuadVS=Vh,Tf.Autolinker=zh,Tf.crunch=Gh,Tf["earcut-2.1.1"]=Wh,Tf.addDefaults=Hh,Tf.addExtensionsRequired=jh,Tf.addExtensionsUsed=qh,Tf.addPipelineExtras=Yh,Tf.addToArray=Xh,Tf.byteLengthForComponentType=Qh,Tf.findAccessorMinMax=Zh,Tf.ForEach=Kh,Tf.getAccessorByteStride=Jh,Tf.getJointCountForMaterials=$h,Tf.glslTypeToWebGLConstant=ep,Tf.numberOfComponentsForType=tp,Tf.parseBinaryGltf=rp,Tf.processModelMaterialsCommon=ip,Tf.processPbrMetallicRoughness=np,Tf.removeExtensionsRequired=op,Tf.removeExtensionsUsed=ap,Tf.removePipelineExtras=sp,Tf.techniqueParameterForSemantic=lp,Tf.updateVersion=up,Tf.webGLConstantToGlslType=cp,Tf["google-earth-dbroot-parser"]=dp,Tf.jsep=hp,Tf.kdbush=pp,Tf["knockout-3.4.2"]=fp,Tf["knockout-es5"]=mp,Tf.knockout=gp,Tf.measureText=_p,Tf["mersenne-twister"]=vp,Tf.NoSleep=yp,Tf.pako_inflate=bp,Tf["protobuf-minimal"]=Cp,Tf.FXAA3_11=Sp,Tf.sprintf=wp,Tf.topojson=Tp,Tf.Tween=Ep,Tf.Uri=Ap,Tf.when=xp,Tf.zip=Pp,Tf.Animation=Dp,Tf.AnimationViewModel=Ip,Tf.BaseLayerPicker=Op,Tf.BaseLayerPickerViewModel=Mp,Tf.createDefaultImageryProviderViewModels=Rp,Tf.createDefaultTerrainProviderViewModels=Lp,Tf.ProviderViewModel=Np,Tf.Cesium3DTilesInspector=kp,Tf.Cesium3DTilesInspectorViewModel=Fp,Tf.CesiumInspector=Bp,Tf.CesiumInspectorViewModel=Up,Tf.CesiumWidget=Vp,Tf.ClockViewModel=zp,Tf.Command=Gp,Tf.createCommand=Wp,Tf.FullscreenButton=Hp,Tf.FullscreenButtonViewModel=jp,Tf.Geocoder=qp,Tf.GeocoderViewModel=Yp,Tf.getElement=Xp,Tf.HomeButton=Qp,Tf.HomeButtonViewModel=Zp,Tf.InfoBox=Kp,Tf.InfoBoxViewModel=Jp,Tf.NavigationHelpButton=$p,Tf.NavigationHelpButtonViewModel=ef,Tf.PerformanceWatchdog=tf,Tf.PerformanceWatchdogViewModel=rf,Tf.ProjectionPicker=nf,Tf.ProjectionPickerViewModel=of,Tf.SceneModePicker=af,Tf.SceneModePickerViewModel=sf,Tf.SelectionIndicator=lf,Tf.SelectionIndicatorViewModel=uf,Tf.subscribeAndEvaluate=cf,Tf.SvgPathBindingHandler=df,Tf.Timeline=hf,Tf.TimelineHighlightRange=pf,Tf.TimelineTrack=ff,Tf.ToggleButtonViewModel=mf,Tf.Viewer=gf,Tf.viewerCesium3DTilesInspectorMixin=_f,Tf.viewerCesiumInspectorMixin=vf,Tf.viewerDragDropMixin=yf,Tf.viewerPerformanceWatchdogMixin=bf,Tf.VRButton=Cf,Tf.VRButtonViewModel=Sf,Tf.createTaskProcessorWorker=wf,Tf}),require(["Cesium"],function(e){"use strict";("undefined"!=typeof window?window:"undefined"!=typeof self?self:{}).Cesium=e},void 0,!0)}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Mouse.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Mouse.svg index 5b8f7d6c..7fae028c 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Mouse.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Mouse.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseLeft.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseLeft.svg index b07a1e82..0c49c15f 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseLeft.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseLeft.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg index b5b038dd..9dd533d5 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseRight.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseRight.svg index 80748f65..2662ad18 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseRight.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/MouseRight.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Touch.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Touch.svg index 3cef2c89..e682b301 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Touch.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/Touch.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchDrag.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchDrag.svg index 22e87d69..f0509e85 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchDrag.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchDrag.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchRotate.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchRotate.svg index 24f551e6..fe968ff4 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchRotate.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchRotate.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchTilt.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchTilt.svg index 85023669..e1206c5d 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchTilt.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchTilt.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchZoom.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchZoom.svg index 0b48a3b3..74e55d7c 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchZoom.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/Images/NavigationHelp/TouchZoom.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/InfoBox/InfoBoxDescription.css b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/InfoBox/InfoBoxDescription.css index 4cfac276..05a9e7b6 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/InfoBox/InfoBoxDescription.css +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/InfoBox/InfoBoxDescription.css @@ -1 +1 @@ -.cesium-svgPath-svg{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;}.cesium-button{display:inline-block;position:relative;background:#303336;border:1px solid #444;color:#edffff;fill:#edffff;border-radius:4px;padding:5px 12px;margin:2px 3px;cursor:pointer;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-button:focus{color:#fff;fill:#fff;border-color:#ea4;outline:none;}.cesium-button:hover{color:#fff;fill:#fff;background:#48b;border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-button:active{color:#000;fill:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-button:disabled,.cesium-button-disabled,.cesium-button-disabled:focus,.cesium-button-disabled:hover,.cesium-button-disabled:active{background:#303336;border-color:#444;color:#646464;fill:#646464;box-shadow:none;cursor:default;}.cesium-button option{background-color:#000;color:#eee;}.cesium-button option:disabled{color:#777;}.cesium-button input,.cesium-button label{cursor:pointer;}.cesium-button input{vertical-align:sub;}.cesium-toolbar-button{box-sizing:border-box;width:32px;height:32px;border-radius:14%;padding:0;vertical-align:middle;z-index:0;}.cesium-performanceDisplay-defaultContainer{position:absolute;top:50px;right:10px;text-align:right;}.cesium-performanceDisplay{background-color:rgba(40,40,40,0.7);padding:7px;border-radius:5px;border:1px solid #444;font:bold 12px sans-serif;}.cesium-performanceDisplay-fps{color:#e52;}.cesium-performanceDisplay-ms{color:#de3;}body{margin:0;padding:0;}.cesium-infoBox-description{font-family:sans-serif;font-size:13px;padding:4px 10px;margin-right:4px;color:#edffff;}.cesium-infoBox-description a:link,.cesium-infoBox-description a:visited,.cesium-infoBox-description a:hover,.cesium-infoBox-description a:active{color:#edffff;}.cesium-infoBox-description table{color:#edffff;}.cesium-infoBox-defaultTable{width:100%;color:#edffff;}.cesium-infoBox-defaultTable tr:nth-child(odd){background-color:rgba(84,84,84,0.8);}.cesium-infoBox-defaultTable tr:nth-child(even){background-color:rgba(84,84,84,0.25);}.cesium-infoBox-defaultTable th{font-weight:normal;padding:3px;vertical-align:middle;text-align:center;}.cesium-infoBox-defaultTable td{padding:3px;vertical-align:middle;text-align:left;}.cesium-infoBox-description-lighter{color:#000000;}.cesium-infoBox-description-lighter a:link,.cesium-infoBox-description-lighter a:visited,.cesium-infoBox-description-lighter a:hover,.cesium-infoBox-description-lighter a:active{color:#000000;}.cesium-infoBox-description-lighter table{color:#000000;}.cesium-infoBox-defaultTable-lighter{width:100%;color:#000000;}.cesium-infoBox-defaultTable-lighter tr:nth-child(odd){background-color:rgba(179,179,179,0.8);}.cesium-infoBox-defaultTable-lighter tr:nth-child(even){background-color:rgba(179,179,179,0.25);}.cesium-infoBox-loadingContainer{margin:5px;text-align:center;}.cesium-infoBox-loading{display:inline-block;background-image:url(../Images/info-loading.gif);width:16px;height:11px;} \ No newline at end of file +.cesium-svgPath-svg{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;}.cesium-button{display:inline-block;position:relative;background:#303336;border:1px solid #444;color:#edffff;fill:#edffff;border-radius:4px;padding:5px 12px;margin:2px 3px;cursor:pointer;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-button:focus{color:#fff;fill:#fff;border-color:#ea4;outline:none;}.cesium-button:hover{color:#fff;fill:#fff;background:#48b;border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-button:active{color:#000;fill:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-button:disabled,.cesium-button-disabled,.cesium-button-disabled:focus,.cesium-button-disabled:hover,.cesium-button-disabled:active{background:#303336;border-color:#444;color:#646464;fill:#646464;box-shadow:none;cursor:default;}.cesium-button option{background-color:#000;color:#eee;}.cesium-button option:disabled{color:#777;}.cesium-button input,.cesium-button label{cursor:pointer;}.cesium-button input{vertical-align:sub;}.cesium-toolbar-button{box-sizing:border-box;width:32px;height:32px;border-radius:14%;padding:0;vertical-align:middle;z-index:0;}.cesium-performanceDisplay-defaultContainer{position:absolute;top:50px;right:10px;text-align:right;}.cesium-performanceDisplay{background-color:rgba(40,40,40,0.7);padding:7px;border-radius:5px;border:1px solid #444;font:bold 12px sans-serif;}.cesium-performanceDisplay-fps{color:#e52;}.cesium-performanceDisplay-throttled{color:#a42;}.cesium-performanceDisplay-ms{color:#de3;}body{margin:0;padding:0;}.cesium-infoBox-description{font-family:sans-serif;font-size:13px;padding:4px 10px;margin-right:4px;color:#edffff;}.cesium-infoBox-description a:link,.cesium-infoBox-description a:visited,.cesium-infoBox-description a:hover,.cesium-infoBox-description a:active{color:#edffff;}.cesium-infoBox-description table{color:#edffff;}.cesium-infoBox-defaultTable{width:100%;color:#edffff;}.cesium-infoBox-defaultTable tr:nth-child(odd){background-color:rgba(84,84,84,0.8);}.cesium-infoBox-defaultTable tr:nth-child(even){background-color:rgba(84,84,84,0.25);}.cesium-infoBox-defaultTable th{font-weight:normal;padding:3px;vertical-align:middle;text-align:center;}.cesium-infoBox-defaultTable td{padding:3px;vertical-align:middle;text-align:left;}.cesium-infoBox-description-lighter{color:#000000;}.cesium-infoBox-description-lighter a:link,.cesium-infoBox-description-lighter a:visited,.cesium-infoBox-description-lighter a:hover,.cesium-infoBox-description-lighter a:active{color:#000000;}.cesium-infoBox-description-lighter table{color:#000000;}.cesium-infoBox-defaultTable-lighter{width:100%;color:#000000;}.cesium-infoBox-defaultTable-lighter tr:nth-child(odd){background-color:rgba(179,179,179,0.8);}.cesium-infoBox-defaultTable-lighter tr:nth-child(even){background-color:rgba(179,179,179,0.25);}.cesium-infoBox-loadingContainer{margin:5px;text-align:center;}.cesium-infoBox-loading{display:inline-block;background-image:url(../Images/info-loading.gif);width:16px;height:11px;} \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/shared.css b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/shared.css index 16fb57fc..5d2a1c44 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/shared.css +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/shared.css @@ -1 +1 @@ -.cesium-svgPath-svg{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;}.cesium-button{display:inline-block;position:relative;background:#303336;border:1px solid #444;color:#edffff;fill:#edffff;border-radius:4px;padding:5px 12px;margin:2px 3px;cursor:pointer;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-button:focus{color:#fff;fill:#fff;border-color:#ea4;outline:none;}.cesium-button:hover{color:#fff;fill:#fff;background:#48b;border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-button:active{color:#000;fill:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-button:disabled,.cesium-button-disabled,.cesium-button-disabled:focus,.cesium-button-disabled:hover,.cesium-button-disabled:active{background:#303336;border-color:#444;color:#646464;fill:#646464;box-shadow:none;cursor:default;}.cesium-button option{background-color:#000;color:#eee;}.cesium-button option:disabled{color:#777;}.cesium-button input,.cesium-button label{cursor:pointer;}.cesium-button input{vertical-align:sub;}.cesium-toolbar-button{box-sizing:border-box;width:32px;height:32px;border-radius:14%;padding:0;vertical-align:middle;z-index:0;}.cesium-performanceDisplay-defaultContainer{position:absolute;top:50px;right:10px;text-align:right;}.cesium-performanceDisplay{background-color:rgba(40,40,40,0.7);padding:7px;border-radius:5px;border:1px solid #444;font:bold 12px sans-serif;}.cesium-performanceDisplay-fps{color:#e52;}.cesium-performanceDisplay-ms{color:#de3;} \ No newline at end of file +.cesium-svgPath-svg{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;}.cesium-button{display:inline-block;position:relative;background:#303336;border:1px solid #444;color:#edffff;fill:#edffff;border-radius:4px;padding:5px 12px;margin:2px 3px;cursor:pointer;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-button:focus{color:#fff;fill:#fff;border-color:#ea4;outline:none;}.cesium-button:hover{color:#fff;fill:#fff;background:#48b;border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-button:active{color:#000;fill:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-button:disabled,.cesium-button-disabled,.cesium-button-disabled:focus,.cesium-button-disabled:hover,.cesium-button-disabled:active{background:#303336;border-color:#444;color:#646464;fill:#646464;box-shadow:none;cursor:default;}.cesium-button option{background-color:#000;color:#eee;}.cesium-button option:disabled{color:#777;}.cesium-button input,.cesium-button label{cursor:pointer;}.cesium-button input{vertical-align:sub;}.cesium-toolbar-button{box-sizing:border-box;width:32px;height:32px;border-radius:14%;padding:0;vertical-align:middle;z-index:0;}.cesium-performanceDisplay-defaultContainer{position:absolute;top:50px;right:10px;text-align:right;}.cesium-performanceDisplay{background-color:rgba(40,40,40,0.7);padding:7px;border-radius:5px;border:1px solid #444;font:bold 12px sans-serif;}.cesium-performanceDisplay-fps{color:#e52;}.cesium-performanceDisplay-throttled{color:#a42;}.cesium-performanceDisplay-ms{color:#de3;} \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/widgets.css b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/widgets.css index 97e5bbb5..4270e458 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/widgets.css +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Widgets/widgets.css @@ -1 +1 @@ -.cesium-svgPath-svg{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;}.cesium-button{display:inline-block;position:relative;background:#303336;border:1px solid #444;color:#edffff;fill:#edffff;border-radius:4px;padding:5px 12px;margin:2px 3px;cursor:pointer;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-button:focus{color:#fff;fill:#fff;border-color:#ea4;outline:none;}.cesium-button:hover{color:#fff;fill:#fff;background:#48b;border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-button:active{color:#000;fill:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-button:disabled,.cesium-button-disabled,.cesium-button-disabled:focus,.cesium-button-disabled:hover,.cesium-button-disabled:active{background:#303336;border-color:#444;color:#646464;fill:#646464;box-shadow:none;cursor:default;}.cesium-button option{background-color:#000;color:#eee;}.cesium-button option:disabled{color:#777;}.cesium-button input,.cesium-button label{cursor:pointer;}.cesium-button input{vertical-align:sub;}.cesium-toolbar-button{box-sizing:border-box;width:32px;height:32px;border-radius:14%;padding:0;vertical-align:middle;z-index:0;}.cesium-performanceDisplay-defaultContainer{position:absolute;top:50px;right:10px;text-align:right;}.cesium-performanceDisplay{background-color:rgba(40,40,40,0.7);padding:7px;border-radius:5px;border:1px solid #444;font:bold 12px sans-serif;}.cesium-performanceDisplay-fps{color:#e52;}.cesium-performanceDisplay-ms{color:#de3;}.cesium-animation-theme{visibility:hidden;display:block;position:absolute;z-index:-100;}.cesium-animation-themeNormal{color:#222;}.cesium-animation-themeHover{color:#4488B0;}.cesium-animation-themeSelect{color:#242;}.cesium-animation-themeDisabled{color:#333;}.cesium-animation-themeKnob{color:#222;}.cesium-animation-themePointer{color:#2E2;}.cesium-animation-themeSwoosh{color:#8AC;}.cesium-animation-themeSwooshHover{color:#AEF;}.cesium-animation-svgText{fill:#edffff;font-family:Sans-Serif;font-size:15px;text-anchor:middle;}.cesium-animation-blank{fill:#000;fill-opacity:0.01;stroke:none;}.cesium-animation-rectButton{cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-animation-rectButton .cesium-animation-buttonGlow{fill:#fff;stroke:none;display:none;}.cesium-animation-rectButton:hover .cesium-animation-buttonGlow{display:block;}.cesium-animation-rectButton .cesium-animation-buttonPath{fill:#edffff;}.cesium-animation-rectButton .cesium-animation-buttonMain{stroke:#444;stroke-width:1.2;}.cesium-animation-rectButton:hover .cesium-animation-buttonMain{stroke:#AEF;}.cesium-animation-rectButton:active .cesium-animation-buttonMain{fill:#ABD6FF;}.cesium-animation-buttonDisabled{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-animation-buttonDisabled .cesium-animation-buttonMain{stroke:#555;}.cesium-animation-buttonDisabled .cesium-animation-buttonPath{fill:#818181;}.cesium-animation-buttonDisabled .cesium-animation-buttonGlow{display:none;}.cesium-animation-buttonToggled .cesium-animation-buttonGlow{display:block;fill:#2E2;}.cesium-animation-buttonToggled .cesium-animation-buttonMain{stroke:#2E2;}.cesium-animation-buttonToggled:hover .cesium-animation-buttonGlow{fill:#fff;}.cesium-animation-buttonToggled:hover .cesium-animation-buttonMain{stroke:#2E2;}.cesium-animation-shuttleRingG{cursor:pointer;}.cesium-animation-shuttleRingPointer{cursor:pointer;}.cesium-animation-shuttleRingPausePointer{cursor:pointer;}.cesium-animation-shuttleRingBack{fill:#181818;fill-opacity:0.8;stroke:#333;stroke-width:1.2;}.cesium-animation-shuttleRingSwoosh line{stroke:#8AC;stroke-width:3;stroke-opacity:0.2;stroke-linecap:round;}.cesium-animation-knobOuter{cursor:pointer;stroke:#444;stroke-width:1.2;}.cesium-animation-knobInner{cursor:pointer;}.cesium-baseLayerPicker-selected{position:absolute;top:0;left:0;width:100%;height:100%;border:none;}.cesium-baseLayerPicker-dropDown{display:block;position:absolute;box-sizing:content-box;top:auto;right:0;width:320px;max-height:500px;margin-top:5px;background-color:rgba(38,38,38,0.75);border:1px solid #444;padding:6px;overflow:auto;border-radius:10px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;transform:translate(0,-20%);visibility:hidden;opacity:0;transition:visibility 0s 0.2s,opacity 0.2s ease-in,transform 0.2s ease-in;}.cesium-baseLayerPicker-dropDown-visible{transform:translate(0,0);visibility:visible;opacity:1;transition:opacity 0.2s ease-out,transform 0.2s ease-out;}.cesium-baseLayerPicker-sectionTitle{display:block;font-family:sans-serif;font-size:16pt;text-align:left;color:#edffff;border-bottom:1px solid #888;margin-bottom:4px;}.cesium-baseLayerPicker-choices{display:block;position:relative;top:auto;right:0;}.cesium-baseLayerPicker-item{display:inline-block;vertical-align:top;margin:2px 5px;width:64px;text-align:center;cursor:pointer;}.cesium-baseLayerPicker-itemLabel{display:block;font-family:sans-serif;font-size:8pt;text-align:center;vertical-align:middle;color:#edffff;cursor:pointer;word-wrap:break-word;}.cesium-baseLayerPicker-item:hover .cesium-baseLayerPicker-itemLabel,.cesium-baseLayerPicker-item:focus .cesium-baseLayerPicker-itemLabel{text-decoration:underline;}.cesium-baseLayerPicker-itemIcon{display:inline-block;position:relative;width:inherit;height:auto;background-size:100% 100%;border:solid 1px #444;border-radius:9px;color:#edffff;margin:0;padding:0;cursor:pointer;box-sizing:border-box;}.cesium-baseLayerPicker-item:hover .cesium-baseLayerPicker-itemIcon{border-color:#fff;box-shadow:0 0 8px #fff,0 0 8px #fff;}.cesium-baseLayerPicker-selectedItem .cesium-baseLayerPicker-itemLabel{color:rgb(189,236,248);}.cesium-baseLayerPicker-selectedItem .cesium-baseLayerPicker-itemIcon{border:double 4px rgb(189,236,248);}.cesium-widget{position:relative;}.cesium-widget,.cesium-widget canvas{width:100%;height:100%;touch-action:none;}.cesium-widget-credits{display:block;position:absolute;bottom:0;left:0;color:#fff;font-size:10px;text-shadow:0px 0px 2px #000000;padding-right:5px;}.cesium-widget-credits a,.cesium-widget-credits a:visited{color:#fff;}.cesium-widget-errorPanel{position:absolute;top:0;right:0;bottom:0;left:0;text-align:center;background:rgba(0,0,0,0.7);z-index:99999;}.cesium-widget-errorPanel:before{display:inline-block;vertical-align:middle;height:100%;content:"";}.cesium-widget-errorPanel-content{width:75%;display:inline-block;text-align:left;vertical-align:middle;border:1px solid #526F82;border-radius:7px;background-color:black;color:white;font-size:10pt;padding:1em;}.cesium-widget-errorPanel-header{font-size:120%;color:#fe4;}.cesium-widget-errorPanel-scroll{overflow:auto;font-family:monospace;white-space:pre-wrap;padding:0;margin:10px 0;}.cesium-widget-errorPanel-buttonPanel{text-align:center;}.cesium-cesiumInspector{border-radius:5px;transition:width ease-in-out 0.25s;background:rgba(48,51,54,0.8);border:1px solid #444;color:#edffff;display:inline-block;position:relative;padding:4px 12px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;}.cesium-cesiumInspector-button{text-align:center;font-size:11pt;}.cesium-cesiumInspector-visible .cesium-cesiumInspector-button{border-bottom:1px solid #aaa;padding-bottom:3px;}.cesium-cesiumInspector input:enabled,.cesium-cesiumInspector-button{cursor:pointer;}.cesium-cesiumInspector-visible{width:185px;height:auto;}.cesium-cesiumInspector-hidden{width:122px;height:17px;}.cesium-cesiumInspector-show{max-height:500px;}.cesium-cesiumInspector-hide{max-height:0;padding:0 !important;overflow:hidden;}.cesium-cesiumInspector-dropDown{margin:5px 0;font-family:sans-serif;font-size:10pt;width:185px;}.cesium-cesiumInspector-frustumStatistics{padding-left:10px;padding:5px;background-color:rgba(80,80,80,0.75);}.cesium-cesiumInspector-pickButton{background-color:rgba(0,0,0,0.3);border:1px solid #444;color:#edffff;border-radius:5px;padding:3px 7px;cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;margin:0 auto;}.cesium-cesiumInspector-pickButton:focus{outline:none;}.cesium-cesiumInspector-pickButton:active,.cesium-cesiumInspector-pickButtonHighlight{color:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-cesiumInspector-center{text-align:center;}.cesium-cesiumInspector-sectionHeader{font-weight:bold;}.cesium-cesiumInspector-pickSection{border:1px solid #aaa;border-radius:5px;padding:3px;margin-bottom:5px;}.cesium-cesiumInspector-section{margin-bottom:10px;transition:max-height 0.25s;}.cesium-cesiumInspector-toggleSwitch{padding:3px;cursor:pointer;}.cesium-cesiumInspector-tileText{padding-bottom:10px;border-bottom:1px solid #aaa;}.cesium-cesiumInspector-relativeText{padding-top:10px;}ul.cesium-cesiumInspector-statistics{margin:0;padding-top:3px;padding-bottom:3px;}ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics{border-top:1px solid #aaa;}.cesium-cesiumInspector-slider{margin-top:5px;}.cesium-cesiumInspector-slider input[type=number]{text-align:left;background-color:#222;outline:none;border:1px solid #444;color:#edffff;width:100px;border-radius:3px;padding:1px;margin-left:10px;cursor:auto;}.cesium-cesiumInspector-slider input[type=number]::-webkit-outer-spin-button,.cesium-cesiumInspector-slider input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}.cesium-cesiumInspector-slider input[type=range]{margin-left:5px;vertical-align:middle;-webkit-appearance:none;background:#ddd;height:3px;}input[type=range]:focus{outline:none;}.cesium-cesiumInspector-slider input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:1px solid #000000;height:10px;width:10px;border-radius:5px;background:#ffffff;cursor:pointer;}.cesium-cesiumInspector-slider input[type=range]::-moz-range-thumb{border:1px solid #000000;height:10px;width:10px;border-radius:5px;background:#ffffff;cursor:pointer;}.cesium-cesiumInspector-slider input[type=range]::-moz-range-thumb{border:1px solid #000000;height:10px;width:10px;border-radius:5px;background:#ffffff;cursor:pointer;}.cesium-cesiumInspector-hide .cesium-cesiumInspector-styleEditor{display:none;}.cesium-cesiumInspector-styleEditor{padding:10px;border-radius:5px;background:rgba(48,51,54,0.8);border:1px solid #444;}.cesium-cesiumInspector-styleEditor textarea{width:100%;height:300px;background:transparent;color:#edffff;border:none;padding:0;white-space:pre;overflow-wrap:normal;overflow-x:auto;}.cesium-3DTilesInspector{width:300px;pointer-events:all;}.cesium-3DTilesInspector-statistics{font-size:11px;}.cesium-3DTilesInspector div,.cesium-3DTilesInspector input[type=range]{width:100%;box-sizing:border-box;}.cesium-cesiumInspector-error{color:#ff9e9e;overflow:auto;}.cesium-3DTilesInspector .cesium-cesiumInspector-section{margin-top:3px;}.cesium-3DTilesInspector .cesium-cesiumInspector-sectionHeader + .cesium-cesiumInspector-show{border-top:1px solid white;}input.cesium-cesiumInspector-url{overflow:hidden;white-space:nowrap;overflow-x:scroll;background-color:transparent;color:white;outline:none;border:none;height:1em;width:100%;}.cesium-cesiumInspector .field-group{display:table;}.cesium-cesiumInspector .field-group > label{display:table-cell;font-weight:bold;}.cesium-cesiumInspector .field-group > .field{display:table-cell;width:100%;}.cesium-button.cesium-fullscreenButton{display:block;width:100%;height:100%;margin:0;border-radius:0;}.cesium-button.cesium-vrButton{display:block;width:100%;height:100%;margin:0;border-radius:0;}.cesium-viewer-geocoderContainer .cesium-geocoder-input{border:solid 1px #444;background-color:rgba(40,40,40,0.7);color:white;display:inline-block;vertical-align:middle;width:0;height:32px;margin:0;padding:0 32px 0 0;border-radius:0;box-sizing:border-box;transition:width ease-in-out 0.25s,background-color 0.2s ease-in-out;-webkit-appearance:none;}.cesium-viewer-geocoderContainer:hover .cesium-geocoder-input{border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-viewer-geocoderContainer .cesium-geocoder-input:focus{border-color:#ea4;background-color:rgba(15,15,15,0.9);box-shadow:none;outline:none;}.cesium-viewer-geocoderContainer:hover .cesium-geocoder-input,.cesium-viewer-geocoderContainer .cesium-geocoder-input:focus,.cesium-viewer-geocoderContainer .cesium-geocoder-input-wide{padding-left:4px;width:250px;}.cesium-viewer-geocoderContainer .search-results{position:absolute;background-color:#000;color:#eee;overflow-y:auto;opacity:0.8;width:100%;}.cesium-viewer-geocoderContainer .search-results ul{list-style-type:none;margin:0;padding:0;}.cesium-viewer-geocoderContainer .search-results ul li{font-size:14px;padding:3px 10px;}.cesium-viewer-geocoderContainer .search-results ul li:hover{cursor:pointer;}.cesium-viewer-geocoderContainer .search-results ul li.active{background:#48b;}.cesium-geocoder-searchButton{background-color:#303336;display:inline-block;position:absolute;cursor:pointer;width:32px;top:1px;right:1px;height:30px;vertical-align:middle;fill:#edffff;}.cesium-geocoder-searchButton:hover{background-color:#48b;}.cesium-infoBox{display:block;position:absolute;top:50px;right:0;width:40%;max-width:480px;background:rgba(38,38,38,0.95);color:#edffff;border:1px solid #444;border-right:none;border-top-left-radius:7px;border-bottom-left-radius:7px;box-shadow:0 0 10px 1px #000;transform:translate(100%,0);visibility:hidden;opacity:0;transition:visibility 0s 0.2s,opacity 0.2s ease-in,transform 0.2s ease-in;}.cesium-infoBox-visible{transform:translate(0,0);visibility:visible;opacity:1;transition:opacity 0.2s ease-out,transform 0.2s ease-out;}.cesium-infoBox-title{display:block;height:20px;padding:5px 30px 5px 25px;background:rgba(84,84,84,1.0);border-top-left-radius:7px;text-align:center;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;box-sizing:content-box;}.cesium-infoBox-bodyless .cesium-infoBox-title{border-bottom-left-radius:7px;}button.cesium-infoBox-camera{display:block;position:absolute;top:4px;left:4px;width:22px;height:22px;background:transparent;border-color:transparent;border-radius:3px;padding:0 5px;margin:0;}button.cesium-infoBox-close{display:block;position:absolute;top:5px;right:5px;height:20px;background:transparent;border:none;border-radius:2px;font-weight:bold;font-size:16px;padding:0 5px;margin:0;color:#edffff;}button.cesium-infoBox-close:focus{background:rgba(238,136,0,0.44);outline:none;}button.cesium-infoBox-close:hover{background:#888;color:#000;}button.cesium-infoBox-close:active{background:#a00;color:#000;}.cesium-infoBox-bodyless .cesium-infoBox-iframe{display:none;}.cesium-infoBox-iframe{border:none;width:100%;width:calc(100% - 2px);}span.cesium-sceneModePicker-wrapper{display:inline-block;position:relative;margin:0 3px;}.cesium-sceneModePicker-visible{visibility:visible;opacity:1;transition:opacity 0.25s linear;}.cesium-sceneModePicker-hidden{visibility:hidden;opacity:0;transition:visibility 0s 0.25s,opacity 0.25s linear;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-none{display:none;}.cesium-sceneModePicker-slide-svg{transition:left 2s;top:0;left:0;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon{box-sizing:border-box;padding:0;margin:3px 0;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button3D,.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-buttonColumbusView,.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button2D{margin:0 0 3px 0;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button3D .cesium-sceneModePicker-icon2D{left:100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button3D .cesium-sceneModePicker-iconColumbusView{left:200%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-buttonColumbusView .cesium-sceneModePicker-icon3D{left:-200%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-buttonColumbusView .cesium-sceneModePicker-icon2D{left:-100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button2D .cesium-sceneModePicker-icon3D{left:-100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button2D .cesium-sceneModePicker-iconColumbusView{left:100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-selected{border-color:#2e2;box-shadow:0 0 8px #fff,0 0 8px #fff;}span.cesium-projectionPicker-wrapper{display:inline-block;position:relative;margin:0 3px;}.cesium-projectionPicker-visible{visibility:visible;opacity:1;transition:opacity 0.25s linear;}.cesium-projectionPicker-hidden{visibility:hidden;opacity:0;transition:visibility 0s 0.25s,opacity 0.25s linear;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-none{display:none;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-dropDown-icon{box-sizing:border-box;padding:0;margin:3px 0;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonPerspective,.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonOrthographic{margin:0 0 3px 0;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonPerspective .cesium-projectionPicker-iconOrthographic{left:100%;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonOrthographic .cesium-projectionPicker-iconPerspective{left:-100%;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-selected{border-color:#2e2;box-shadow:0 0 8px #fff,0 0 8px #fff;}.cesium-performance-watchdog-message-area{position:relative;background-color:yellow;color:black;padding:10px;}.cesium-performance-watchdog-message{margin-right:30px;}.cesium-performance-watchdog-message-dismiss{position:absolute;right:0;margin:0 10px 0 0;}.cesium-navigationHelpButton-wrapper{position:relative;display:inline-block;}.cesium-navigation-help{visibility:hidden;position:absolute;top:38px;right:2px;width:250px;border-radius:10px;transform:scale(0.01);transform-origin:234px -10px;transition:visibility 0s 0.25s,transform 0.25s ease-in;}.cesium-navigation-help-visible{visibility:visible;transform:scale(1);transition:transform 0.25s ease-out;}.cesium-navigation-help-instructions{border:1px solid #444;background-color:rgba(38,38,38,0.75);padding-bottom:5px;border-radius:0 0 10px 10px;}.cesium-click-navigation-help{display:none;}.cesium-touch-navigation-help{display:none;padding-top:5px;}.cesium-click-navigation-help-visible{display:block;}.cesium-touch-navigation-help-visible{display:block;}.cesium-navigation-help-pan{color:#66ccff;font-weight:bold;}.cesium-navigation-help-zoom{color:#65fd00;font-weight:bold;}.cesium-navigation-help-rotate{color:#ffd800;font-weight:bold;}.cesium-navigation-help-tilt{color:#d800d8;font-weight:bold;}.cesium-navigation-help-details{color:#ffffff;}.cesium-navigation-button{color:#fff;background-color:transparent;border-bottom:none;border-top:1px solid #444;border-right:1px solid #444;margin:0;width:50%;cursor:pointer;}.cesium-navigation-button-icon{vertical-align:middle;padding:5px 1px;}.cesium-navigation-button:focus{outline:none;}.cesium-navigation-button-left{border-radius:10px 0 0 0;border-left:1px solid #444;}.cesium-navigation-button-right{border-radius:0 10px 0 0;border-left:none;}.cesium-navigation-button-selected{background-color:rgba(38,38,38,0.75);}.cesium-navigation-button-unselected{background-color:rgba(0,0,0,0.75);}.cesium-navigation-button-unselected:hover{background-color:rgba(76,76,76,0.75);}.cesium-selection-wrapper{position:absolute;width:160px;height:160px;pointer-events:none;visibility:hidden;opacity:0;transition:visibility 0s 0.2s,opacity 0.2s ease-in;}.cesium-selection-wrapper-visible{visibility:visible;opacity:1;transition:opacity 0.2s ease-out;}.cesium-selection-wrapper svg{fill:#2e2;stroke:#000;stroke-width:1.1px;}.cesium-timeline-main{position:relative;left:0;bottom:0;overflow:hidden;border:solid 1px #888;}.cesium-timeline-trackContainer{width:100%;overflow:auto;border-top:solid 1px #888;position:relative;top:0;left:0;}.cesium-timeline-tracks{position:absolute;top:0;left:0;width:100%;}.cesium-timeline-needle{position:absolute;left:0;top:1.7em;bottom:0;width:1px;background:#F00;}.cesium-timeline-bar{position:relative;left:0;top:0;overflow:hidden;cursor:pointer;width:100%;height:1.7em;background:linear-gradient(to bottom,rgba(116,117,119,0.8) 0%,rgba(58,68,82,0.8) 11%,rgba(46,50,56,0.8) 46%,rgba(53,53,53,0.8) 81%,rgba(53,53,53,0.8) 100%);}.cesium-timeline-ruler{visibility:hidden;white-space:nowrap;font-size:80%;z-index:-200;}.cesium-timeline-highlight{position:absolute;bottom:0;left:0;background:#08F;}.cesium-timeline-ticLabel{position:absolute;top:0;left:0;white-space:nowrap;font-size:80%;color:#eee;}.cesium-timeline-ticMain{position:absolute;bottom:0;left:0;width:1px;height:50%;background:#eee;}.cesium-timeline-ticSub{position:absolute;bottom:0;left:0;width:1px;height:33%;background:#aaa;}.cesium-timeline-ticTiny{position:absolute;bottom:0;left:0;width:1px;height:25%;background:#888;}.cesium-timeline-icon16{display:block;position:absolute;width:16px;height:16px;background-image:url(Images/TimelineIcons.png);background-repeat:no-repeat;}.cesium-viewer{font-family:sans-serif;font-size:16px;overflow:hidden;display:block;position:relative;top:0;left:0;width:100%;height:100%;}.cesium-viewer-cesiumWidgetContainer{width:100%;height:100%;}.cesium-viewer-bottom{display:block;position:absolute;bottom:0;left:0;right:0;padding-right:5px;}.cesium-viewer .cesium-widget-credits{display:inline;position:static;bottom:auto;left:auto;padding-right:0;color:#ffffff;font-size:10px;text-shadow:0 0 2px #000000;}.cesium-viewer-timelineContainer{position:absolute;bottom:0;left:169px;right:29px;height:27px;padding:0;margin:0;overflow:hidden;font-size:14px;}.cesium-viewer-animationContainer{position:absolute;bottom:0;left:0;padding:0;width:169px;height:112px;}.cesium-viewer-fullscreenContainer{position:absolute;bottom:0;right:0;padding:0;width:29px;height:29px;overflow:hidden;}.cesium-viewer-vrContainer{position:absolute;bottom:0;right:0;padding:0;width:29px;height:29px;overflow:hidden;}.cesium-viewer-toolbar{display:block;position:absolute;top:5px;right:5px;}.cesium-viewer-cesiumInspectorContainer{display:block;position:absolute;top:50px;right:10px;}.cesium-viewer-geocoderContainer{position:relative;display:inline-block;margin:0 3px;}.cesium-viewer-cesium3DTilesInspectorContainer{display:block;position:absolute;top:50px;right:10px;max-height:100%;padding-bottom:70px;box-sizing:border-box;overflow:auto;} \ No newline at end of file +.cesium-svgPath-svg{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;}.cesium-button{display:inline-block;position:relative;background:#303336;border:1px solid #444;color:#edffff;fill:#edffff;border-radius:4px;padding:5px 12px;margin:2px 3px;cursor:pointer;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-button:focus{color:#fff;fill:#fff;border-color:#ea4;outline:none;}.cesium-button:hover{color:#fff;fill:#fff;background:#48b;border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-button:active{color:#000;fill:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-button:disabled,.cesium-button-disabled,.cesium-button-disabled:focus,.cesium-button-disabled:hover,.cesium-button-disabled:active{background:#303336;border-color:#444;color:#646464;fill:#646464;box-shadow:none;cursor:default;}.cesium-button option{background-color:#000;color:#eee;}.cesium-button option:disabled{color:#777;}.cesium-button input,.cesium-button label{cursor:pointer;}.cesium-button input{vertical-align:sub;}.cesium-toolbar-button{box-sizing:border-box;width:32px;height:32px;border-radius:14%;padding:0;vertical-align:middle;z-index:0;}.cesium-performanceDisplay-defaultContainer{position:absolute;top:50px;right:10px;text-align:right;}.cesium-performanceDisplay{background-color:rgba(40,40,40,0.7);padding:7px;border-radius:5px;border:1px solid #444;font:bold 12px sans-serif;}.cesium-performanceDisplay-fps{color:#e52;}.cesium-performanceDisplay-throttled{color:#a42;}.cesium-performanceDisplay-ms{color:#de3;}.cesium-animation-theme{visibility:hidden;display:block;position:absolute;z-index:-100;}.cesium-animation-themeNormal{color:#222;}.cesium-animation-themeHover{color:#4488B0;}.cesium-animation-themeSelect{color:#242;}.cesium-animation-themeDisabled{color:#333;}.cesium-animation-themeKnob{color:#222;}.cesium-animation-themePointer{color:#2E2;}.cesium-animation-themeSwoosh{color:#8AC;}.cesium-animation-themeSwooshHover{color:#AEF;}.cesium-animation-svgText{fill:#edffff;font-family:Sans-Serif;font-size:15px;text-anchor:middle;}.cesium-animation-blank{fill:#000;fill-opacity:0.01;stroke:none;}.cesium-animation-rectButton{cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-animation-rectButton .cesium-animation-buttonGlow{fill:#fff;stroke:none;display:none;}.cesium-animation-rectButton:hover .cesium-animation-buttonGlow{display:block;}.cesium-animation-rectButton .cesium-animation-buttonPath{fill:#edffff;}.cesium-animation-rectButton .cesium-animation-buttonMain{stroke:#444;stroke-width:1.2;}.cesium-animation-rectButton:hover .cesium-animation-buttonMain{stroke:#AEF;}.cesium-animation-rectButton:active .cesium-animation-buttonMain{fill:#ABD6FF;}.cesium-animation-buttonDisabled{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.cesium-animation-buttonDisabled .cesium-animation-buttonMain{stroke:#555;}.cesium-animation-buttonDisabled .cesium-animation-buttonPath{fill:#818181;}.cesium-animation-buttonDisabled .cesium-animation-buttonGlow{display:none;}.cesium-animation-buttonToggled .cesium-animation-buttonGlow{display:block;fill:#2E2;}.cesium-animation-buttonToggled .cesium-animation-buttonMain{stroke:#2E2;}.cesium-animation-buttonToggled:hover .cesium-animation-buttonGlow{fill:#fff;}.cesium-animation-buttonToggled:hover .cesium-animation-buttonMain{stroke:#2E2;}.cesium-animation-shuttleRingG{cursor:pointer;}.cesium-animation-shuttleRingPointer{cursor:pointer;}.cesium-animation-shuttleRingPausePointer{cursor:pointer;}.cesium-animation-shuttleRingBack{fill:#181818;fill-opacity:0.8;stroke:#333;stroke-width:1.2;}.cesium-animation-shuttleRingSwoosh line{stroke:#8AC;stroke-width:3;stroke-opacity:0.2;stroke-linecap:round;}.cesium-animation-knobOuter{cursor:pointer;stroke:#444;stroke-width:1.2;}.cesium-animation-knobInner{cursor:pointer;}.cesium-baseLayerPicker-selected{position:absolute;top:0;left:0;width:100%;height:100%;border:none;}.cesium-baseLayerPicker-dropDown{display:block;position:absolute;box-sizing:content-box;top:auto;right:0;width:320px;max-height:500px;margin-top:5px;background-color:rgba(38,38,38,0.75);border:1px solid #444;padding:6px;overflow:auto;border-radius:10px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;transform:translate(0,-20%);visibility:hidden;opacity:0;transition:visibility 0s 0.2s,opacity 0.2s ease-in,transform 0.2s ease-in;}.cesium-baseLayerPicker-dropDown-visible{transform:translate(0,0);visibility:visible;opacity:1;transition:opacity 0.2s ease-out,transform 0.2s ease-out;}.cesium-baseLayerPicker-sectionTitle{display:block;font-family:sans-serif;font-size:16pt;text-align:left;color:#edffff;border-bottom:1px solid #888;margin-bottom:4px;}.cesium-baseLayerPicker-choices{display:block;position:relative;top:auto;right:0;}.cesium-baseLayerPicker-item{display:inline-block;vertical-align:top;margin:2px 5px;width:64px;text-align:center;cursor:pointer;}.cesium-baseLayerPicker-itemLabel{display:block;font-family:sans-serif;font-size:8pt;text-align:center;vertical-align:middle;color:#edffff;cursor:pointer;word-wrap:break-word;}.cesium-baseLayerPicker-item:hover .cesium-baseLayerPicker-itemLabel,.cesium-baseLayerPicker-item:focus .cesium-baseLayerPicker-itemLabel{text-decoration:underline;}.cesium-baseLayerPicker-itemIcon{display:inline-block;position:relative;width:inherit;height:auto;background-size:100% 100%;border:solid 1px #444;border-radius:9px;color:#edffff;margin:0;padding:0;cursor:pointer;box-sizing:border-box;}.cesium-baseLayerPicker-item:hover .cesium-baseLayerPicker-itemIcon{border-color:#fff;box-shadow:0 0 8px #fff,0 0 8px #fff;}.cesium-baseLayerPicker-selectedItem .cesium-baseLayerPicker-itemLabel{color:rgb(189,236,248);}.cesium-baseLayerPicker-selectedItem .cesium-baseLayerPicker-itemIcon{border:double 4px rgb(189,236,248);}.cesium-widget{position:relative;}.cesium-widget,.cesium-widget canvas{width:100%;height:100%;touch-action:none;}.cesium-widget-credits{display:block;position:absolute;bottom:0;left:0;color:#fff;font-size:10px;text-shadow:0px 0px 2px #000000;padding-right:5px;}.cesium-widget-credits a,.cesium-widget-credits a:visited{color:#fff;}.cesium-widget-errorPanel{position:absolute;top:0;right:0;bottom:0;left:0;text-align:center;background:rgba(0,0,0,0.7);z-index:99999;}.cesium-widget-errorPanel:before{display:inline-block;vertical-align:middle;height:100%;content:"";}.cesium-widget-errorPanel-content{width:75%;display:inline-block;text-align:left;vertical-align:middle;border:1px solid #526F82;border-radius:7px;background-color:black;color:white;font-size:10pt;padding:1em;}.cesium-widget-errorPanel-header{font-size:120%;color:#fe4;}.cesium-widget-errorPanel-scroll{overflow:auto;font-family:monospace;white-space:pre-wrap;padding:0;margin:10px 0;}.cesium-widget-errorPanel-buttonPanel{text-align:center;}.cesium-cesiumInspector{border-radius:5px;transition:width ease-in-out 0.25s;background:rgba(48,51,54,0.8);border:1px solid #444;color:#edffff;display:inline-block;position:relative;padding:4px 12px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;}.cesium-cesiumInspector-button{text-align:center;font-size:11pt;}.cesium-cesiumInspector-visible .cesium-cesiumInspector-button{border-bottom:1px solid #aaa;padding-bottom:3px;}.cesium-cesiumInspector input:enabled,.cesium-cesiumInspector-button{cursor:pointer;}.cesium-cesiumInspector-visible{width:185px;height:auto;}.cesium-cesiumInspector-hidden{width:122px;height:17px;}.cesium-cesiumInspector-show{max-height:500px;}.cesium-cesiumInspector-hide{max-height:0;padding:0 !important;overflow:hidden;}.cesium-cesiumInspector-dropDown{margin:5px 0;font-family:sans-serif;font-size:10pt;width:185px;}.cesium-cesiumInspector-frustumStatistics{padding-left:10px;padding:5px;background-color:rgba(80,80,80,0.75);}.cesium-cesiumInspector-pickButton{background-color:rgba(0,0,0,0.3);border:1px solid #444;color:#edffff;border-radius:5px;padding:3px 7px;cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;margin:0 auto;}.cesium-cesiumInspector-pickButton:focus{outline:none;}.cesium-cesiumInspector-pickButton:active,.cesium-cesiumInspector-pickButtonHighlight{color:#000;background:#adf;border-color:#fff;box-shadow:0 0 8px #fff;}.cesium-cesiumInspector-center{text-align:center;}.cesium-cesiumInspector-sectionHeader{font-weight:bold;}.cesium-cesiumInspector-pickSection{border:1px solid #aaa;border-radius:5px;padding:3px;margin-bottom:5px;}.cesium-cesiumInspector-section{margin-bottom:10px;transition:max-height 0.25s;}.cesium-cesiumInspector-toggleSwitch{padding:3px;cursor:pointer;}.cesium-cesiumInspector-tileText{padding-bottom:10px;border-bottom:1px solid #aaa;}.cesium-cesiumInspector-relativeText{padding-top:10px;}ul.cesium-cesiumInspector-statistics{margin:0;padding-top:3px;padding-bottom:3px;}ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics{border-top:1px solid #aaa;}.cesium-cesiumInspector-slider{margin-top:5px;}.cesium-cesiumInspector-slider input[type=number]{text-align:left;background-color:#222;outline:none;border:1px solid #444;color:#edffff;width:100px;border-radius:3px;padding:1px;margin-left:10px;cursor:auto;}.cesium-cesiumInspector-slider input[type=number]::-webkit-outer-spin-button,.cesium-cesiumInspector-slider input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}.cesium-cesiumInspector-slider input[type=range]{margin-left:5px;vertical-align:middle;-webkit-appearance:none;background:#ddd;height:3px;}input[type=range]:focus{outline:none;}.cesium-cesiumInspector-slider input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:1px solid #000000;height:10px;width:10px;border-radius:5px;background:#ffffff;cursor:pointer;}.cesium-cesiumInspector-slider input[type=range]::-moz-range-thumb{border:1px solid #000000;height:10px;width:10px;border-radius:5px;background:#ffffff;cursor:pointer;}.cesium-cesiumInspector-slider input[type=range]::-moz-range-thumb{border:1px solid #000000;height:10px;width:10px;border-radius:5px;background:#ffffff;cursor:pointer;}.cesium-cesiumInspector-hide .cesium-cesiumInspector-styleEditor{display:none;}.cesium-cesiumInspector-styleEditor{padding:10px;border-radius:5px;background:rgba(48,51,54,0.8);border:1px solid #444;}.cesium-cesiumInspector-styleEditor textarea{width:100%;height:300px;background:transparent;color:#edffff;border:none;padding:0;white-space:pre;overflow-wrap:normal;overflow-x:auto;}.cesium-3DTilesInspector{width:300px;pointer-events:all;}.cesium-3DTilesInspector-statistics{font-size:11px;}.cesium-3DTilesInspector div,.cesium-3DTilesInspector input[type=range]{width:100%;box-sizing:border-box;}.cesium-cesiumInspector-error{color:#ff9e9e;overflow:auto;}.cesium-3DTilesInspector .cesium-cesiumInspector-section{margin-top:3px;}.cesium-3DTilesInspector .cesium-cesiumInspector-sectionHeader + .cesium-cesiumInspector-show{border-top:1px solid white;}input.cesium-cesiumInspector-url{overflow:hidden;white-space:nowrap;overflow-x:scroll;background-color:transparent;color:white;outline:none;border:none;height:1em;width:100%;}.cesium-cesiumInspector .field-group{display:table;}.cesium-cesiumInspector .field-group > label{display:table-cell;font-weight:bold;}.cesium-cesiumInspector .field-group > .field{display:table-cell;width:100%;}.cesium-button.cesium-fullscreenButton{display:block;width:100%;height:100%;margin:0;border-radius:0;}.cesium-button.cesium-vrButton{display:block;width:100%;height:100%;margin:0;border-radius:0;}.cesium-viewer-geocoderContainer .cesium-geocoder-input{border:solid 1px #444;background-color:rgba(40,40,40,0.7);color:white;display:inline-block;vertical-align:middle;width:0;height:32px;margin:0;padding:0 32px 0 0;border-radius:0;box-sizing:border-box;transition:width ease-in-out 0.25s,background-color 0.2s ease-in-out;-webkit-appearance:none;}.cesium-viewer-geocoderContainer:hover .cesium-geocoder-input{border-color:#aef;box-shadow:0 0 8px #fff;}.cesium-viewer-geocoderContainer .cesium-geocoder-input:focus{border-color:#ea4;background-color:rgba(15,15,15,0.9);box-shadow:none;outline:none;}.cesium-viewer-geocoderContainer:hover .cesium-geocoder-input,.cesium-viewer-geocoderContainer .cesium-geocoder-input:focus,.cesium-viewer-geocoderContainer .cesium-geocoder-input-wide{padding-left:4px;width:250px;}.cesium-viewer-geocoderContainer .search-results{position:absolute;background-color:#000;color:#eee;overflow-y:auto;opacity:0.8;width:100%;}.cesium-viewer-geocoderContainer .search-results ul{list-style-type:none;margin:0;padding:0;}.cesium-viewer-geocoderContainer .search-results ul li{font-size:14px;padding:3px 10px;}.cesium-viewer-geocoderContainer .search-results ul li:hover{cursor:pointer;}.cesium-viewer-geocoderContainer .search-results ul li.active{background:#48b;}.cesium-geocoder-searchButton{background-color:#303336;display:inline-block;position:absolute;cursor:pointer;width:32px;top:1px;right:1px;height:30px;vertical-align:middle;fill:#edffff;}.cesium-geocoder-searchButton:hover{background-color:#48b;}.cesium-infoBox{display:block;position:absolute;top:50px;right:0;width:40%;max-width:480px;background:rgba(38,38,38,0.95);color:#edffff;border:1px solid #444;border-right:none;border-top-left-radius:7px;border-bottom-left-radius:7px;box-shadow:0 0 10px 1px #000;transform:translate(100%,0);visibility:hidden;opacity:0;transition:visibility 0s 0.2s,opacity 0.2s ease-in,transform 0.2s ease-in;}.cesium-infoBox-visible{transform:translate(0,0);visibility:visible;opacity:1;transition:opacity 0.2s ease-out,transform 0.2s ease-out;}.cesium-infoBox-title{display:block;height:20px;padding:5px 30px 5px 25px;background:rgba(84,84,84,1.0);border-top-left-radius:7px;text-align:center;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;box-sizing:content-box;}.cesium-infoBox-bodyless .cesium-infoBox-title{border-bottom-left-radius:7px;}button.cesium-infoBox-camera{display:block;position:absolute;top:4px;left:4px;width:22px;height:22px;background:transparent;border-color:transparent;border-radius:3px;padding:0 5px;margin:0;}button.cesium-infoBox-close{display:block;position:absolute;top:5px;right:5px;height:20px;background:transparent;border:none;border-radius:2px;font-weight:bold;font-size:16px;padding:0 5px;margin:0;color:#edffff;}button.cesium-infoBox-close:focus{background:rgba(238,136,0,0.44);outline:none;}button.cesium-infoBox-close:hover{background:#888;color:#000;}button.cesium-infoBox-close:active{background:#a00;color:#000;}.cesium-infoBox-bodyless .cesium-infoBox-iframe{display:none;}.cesium-infoBox-iframe{border:none;width:100%;width:calc(100% - 2px);}span.cesium-sceneModePicker-wrapper{display:inline-block;position:relative;margin:0 3px;}.cesium-sceneModePicker-visible{visibility:visible;opacity:1;transition:opacity 0.25s linear;}.cesium-sceneModePicker-hidden{visibility:hidden;opacity:0;transition:visibility 0s 0.25s,opacity 0.25s linear;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-none{display:none;}.cesium-sceneModePicker-slide-svg{transition:left 2s;top:0;left:0;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon{box-sizing:border-box;padding:0;margin:3px 0;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button3D,.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-buttonColumbusView,.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button2D{margin:0 0 3px 0;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button3D .cesium-sceneModePicker-icon2D{left:100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button3D .cesium-sceneModePicker-iconColumbusView{left:200%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-buttonColumbusView .cesium-sceneModePicker-icon3D{left:-200%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-buttonColumbusView .cesium-sceneModePicker-icon2D{left:-100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button2D .cesium-sceneModePicker-icon3D{left:-100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-button2D .cesium-sceneModePicker-iconColumbusView{left:100%;}.cesium-sceneModePicker-wrapper .cesium-sceneModePicker-selected{border-color:#2e2;box-shadow:0 0 8px #fff,0 0 8px #fff;}span.cesium-projectionPicker-wrapper{display:inline-block;position:relative;margin:0 3px;}.cesium-projectionPicker-visible{visibility:visible;opacity:1;transition:opacity 0.25s linear;}.cesium-projectionPicker-hidden{visibility:hidden;opacity:0;transition:visibility 0s 0.25s,opacity 0.25s linear;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-none{display:none;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-dropDown-icon{box-sizing:border-box;padding:0;margin:3px 0;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonPerspective,.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonOrthographic{margin:0 0 3px 0;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonPerspective .cesium-projectionPicker-iconOrthographic{left:100%;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-buttonOrthographic .cesium-projectionPicker-iconPerspective{left:-100%;}.cesium-projectionPicker-wrapper .cesium-projectionPicker-selected{border-color:#2e2;box-shadow:0 0 8px #fff,0 0 8px #fff;}.cesium-performance-watchdog-message-area{position:relative;background-color:yellow;color:black;padding:10px;}.cesium-performance-watchdog-message{margin-right:30px;}.cesium-performance-watchdog-message-dismiss{position:absolute;right:0;margin:0 10px 0 0;}.cesium-navigationHelpButton-wrapper{position:relative;display:inline-block;}.cesium-navigation-help{visibility:hidden;position:absolute;top:38px;right:2px;width:250px;border-radius:10px;transform:scale(0.01);transform-origin:234px -10px;transition:visibility 0s 0.25s,transform 0.25s ease-in;}.cesium-navigation-help-visible{visibility:visible;transform:scale(1);transition:transform 0.25s ease-out;}.cesium-navigation-help-instructions{border:1px solid #444;background-color:rgba(38,38,38,0.75);padding-bottom:5px;border-radius:0 0 10px 10px;}.cesium-click-navigation-help{display:none;}.cesium-touch-navigation-help{display:none;padding-top:5px;}.cesium-click-navigation-help-visible{display:block;}.cesium-touch-navigation-help-visible{display:block;}.cesium-navigation-help-pan{color:#66ccff;font-weight:bold;}.cesium-navigation-help-zoom{color:#65fd00;font-weight:bold;}.cesium-navigation-help-rotate{color:#ffd800;font-weight:bold;}.cesium-navigation-help-tilt{color:#d800d8;font-weight:bold;}.cesium-navigation-help-details{color:#ffffff;}.cesium-navigation-button{color:#fff;background-color:transparent;border-bottom:none;border-top:1px solid #444;border-right:1px solid #444;margin:0;width:50%;cursor:pointer;}.cesium-navigation-button-icon{vertical-align:middle;padding:5px 1px;}.cesium-navigation-button:focus{outline:none;}.cesium-navigation-button-left{border-radius:10px 0 0 0;border-left:1px solid #444;}.cesium-navigation-button-right{border-radius:0 10px 0 0;border-left:none;}.cesium-navigation-button-selected{background-color:rgba(38,38,38,0.75);}.cesium-navigation-button-unselected{background-color:rgba(0,0,0,0.75);}.cesium-navigation-button-unselected:hover{background-color:rgba(76,76,76,0.75);}.cesium-selection-wrapper{position:absolute;width:160px;height:160px;pointer-events:none;visibility:hidden;opacity:0;transition:visibility 0s 0.2s,opacity 0.2s ease-in;}.cesium-selection-wrapper-visible{visibility:visible;opacity:1;transition:opacity 0.2s ease-out;}.cesium-selection-wrapper svg{fill:#2e2;stroke:#000;stroke-width:1.1px;}.cesium-timeline-main{position:relative;left:0;bottom:0;overflow:hidden;border:solid 1px #888;}.cesium-timeline-trackContainer{width:100%;overflow:auto;border-top:solid 1px #888;position:relative;top:0;left:0;}.cesium-timeline-tracks{position:absolute;top:0;left:0;width:100%;}.cesium-timeline-needle{position:absolute;left:0;top:1.7em;bottom:0;width:1px;background:#F00;}.cesium-timeline-bar{position:relative;left:0;top:0;overflow:hidden;cursor:pointer;width:100%;height:1.7em;background:linear-gradient(to bottom,rgba(116,117,119,0.8) 0%,rgba(58,68,82,0.8) 11%,rgba(46,50,56,0.8) 46%,rgba(53,53,53,0.8) 81%,rgba(53,53,53,0.8) 100%);}.cesium-timeline-ruler{visibility:hidden;white-space:nowrap;font-size:80%;z-index:-200;}.cesium-timeline-highlight{position:absolute;bottom:0;left:0;background:#08F;}.cesium-timeline-ticLabel{position:absolute;top:0;left:0;white-space:nowrap;font-size:80%;color:#eee;}.cesium-timeline-ticMain{position:absolute;bottom:0;left:0;width:1px;height:50%;background:#eee;}.cesium-timeline-ticSub{position:absolute;bottom:0;left:0;width:1px;height:33%;background:#aaa;}.cesium-timeline-ticTiny{position:absolute;bottom:0;left:0;width:1px;height:25%;background:#888;}.cesium-timeline-icon16{display:block;position:absolute;width:16px;height:16px;background-image:url(Images/TimelineIcons.png);background-repeat:no-repeat;}.cesium-viewer{font-family:sans-serif;font-size:16px;overflow:hidden;display:block;position:relative;top:0;left:0;width:100%;height:100%;}.cesium-viewer-cesiumWidgetContainer{width:100%;height:100%;}.cesium-viewer-bottom{display:block;position:absolute;bottom:0;left:0;right:0;padding-right:5px;}.cesium-viewer .cesium-widget-credits{display:inline;position:static;bottom:auto;left:auto;padding-right:0;color:#ffffff;font-size:10px;text-shadow:0 0 2px #000000;}.cesium-viewer-timelineContainer{position:absolute;bottom:0;left:169px;right:29px;height:27px;padding:0;margin:0;overflow:hidden;font-size:14px;}.cesium-viewer-animationContainer{position:absolute;bottom:0;left:0;padding:0;width:169px;height:112px;}.cesium-viewer-fullscreenContainer{position:absolute;bottom:0;right:0;padding:0;width:29px;height:29px;overflow:hidden;}.cesium-viewer-vrContainer{position:absolute;bottom:0;right:0;padding:0;width:29px;height:29px;overflow:hidden;}.cesium-viewer-toolbar{display:block;position:absolute;top:5px;right:5px;}.cesium-viewer-cesiumInspectorContainer{display:block;position:absolute;top:50px;right:10px;}.cesium-viewer-geocoderContainer{position:relative;display:inline-block;margin:0 3px;}.cesium-viewer-cesium3DTilesInspectorContainer{display:block;position:absolute;top:50px;right:10px;max-height:100%;padding-bottom:70px;box-sizing:border-box;overflow:auto;} \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/combineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/combineGeometry.js index 1d11a68a..c518cf77 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/combineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/combineGeometry.js @@ -55,8 +55,8 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,i){if(a.typeOf.number(e,n),a.typeOf.number(r,i),n!==i)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var i=Math.abs(e-r);return i<=a||i<=n*Math.max(Math.abs(e),Math.abs(r))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var r=i[t-1],n=t;n<=e;n++)i.push(r*n);return i[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(i),n},o.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var E=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)},o.cross=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-n*s,E=n*u-a*o;return r.x=c,r.y=l,r.z=E,r},o.fromDegrees=function(e,t,r,n,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,r,n,a)};var f=new o,h=new o,d=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,a,i,u){a=t(a,0);var s=r(i)?i.radiiSquared:d,c=Math.cos(n);f.x=c*Math.cos(e),f.y=c*Math.sin(e),f.z=Math.sin(n),f=o.normalize(f,f),o.multiplyComponents(s,f,h);var l=Math.sqrt(o.dot(f,h));return h=o.divideByScalar(h,l,h),f=o.multiplyByScalar(f,a,f),r(u)||(u=new o),o.add(h,f,u)},o.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,c){var l=r.x,E=r.y,f=r.z,h=a.x,d=a.y,_=a.z,p=l*l*h*h,m=E*E*d*d,T=f*f*_*_,y=p+m+T,R=Math.sqrt(1/y),A=e.multiplyByScalar(r,R,i);if(y<s)return isFinite(R)?e.clone(A,c):void 0;var v=u.x,S=u.y,N=u.z,I=o;I.x=A.x*v*2,I.y=A.y*S*2,I.z=A.z*N*2;var M,O,g,C,w,P,x,L,U,b,F,D=(1-R)*e.magnitude(r)/(.5*e.magnitude(I)),B=0;do{D-=B,g=1/(1+D*v),C=1/(1+D*S),w=1/(1+D*N),P=g*g,x=C*C,L=w*w,U=P*g,b=x*C,F=L*w,M=p*P+m*x+T*L-1,O=p*U*v+m*b*S+T*F*N;B=M/(-2*O)}while(Math.abs(M)>n.EPSILON12);return t(c)?(c.x=l*g,c.y=E*C,c.z=f*w,c):new e(l*g,E*C,f*w)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,i){return a=r(a,0),n(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,E=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,r,a){var d=n(r)?r.oneOverRadii:E,_=n(r)?r.oneOverRadiiSquared:f,p=n(r)?r._centerToleranceSquared:h,m=o(t,d,_,p,c);if(n(m)){var T=e.multiplyComponents(m,_,s);T=e.normalize(T,T);var y=e.subtract(t,m,l),R=Math.atan2(T.y,T.x),A=Math.asin(T.z),v=i.sign(e.dot(y,t))*e.magnitude(y);return n(a)?(a.longitude=R,a.latitude=A,a.height=v,a):new u(R,A,v)}},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t,r,a,i){r=n(r,0),a=n(a,0),i=n(i,0),t._radii=new e(r,a,i),t._radiiSquared=new e(r*r,a*a,i*i),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(r,a,i),t._maximumRadius=Math.max(r,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function E(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}i(E.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),E.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new E(n.x,n.y,n.z)}},E.fromCartesian3=function(e,t){return a(t)||(t=new E),a(e)?(l(t,e.x,e.y,e.z),t):t},E.WGS84=u(new E(6378137,6378137,6356752.314245179)),E.UNIT_SPHERE=u(new E(1,1,1)),E.MOON=u(new E(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),E.prototype.clone=function(e){return E.clone(this,e)},E.packedLength=e.packedLength,E.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},E.unpack=function(t,r,a){r=n(r,0);var i=e.unpack(t,r);return E.fromCartesian3(i,a)},E.prototype.geocentricSurfaceNormal=e.normalize,E.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(i);return a(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},E.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var f=new e,h=new e;E.prototype.cartographicToCartesian=function(t,r){var n=f,i=h;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,i);var o=Math.sqrt(e.dot(n,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(i,n,r)},E.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var d=new e,_=new e,p=new e;return E.prototype.cartesianToCartographic=function(r,n){var i=this.scaleToGeodeticSurface(r,_);if(a(i)){var o=this.geodeticSurfaceNormal(i,d),u=e.subtract(r,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),E=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=c,n.latitude=l,n.height=E,n):new t(c,l,E)}},E.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},E.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},E.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},E.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},E.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},E.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},E.prototype.toString=function(){return this._radii.toString()},E.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,i){r=n(r,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-r))return i},E}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,i,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a,i,o,u,s,c){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(i,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(_[r],d[r])];t+=2*n*n}return Math.sqrt(t)}function E(e,t){for(var r=u.EPSILON15,n=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(_[i],d[i])]);o>n&&(a=i,n=o)}var c=1,l=0,E=d[a],f=_[a];if(Math.abs(e[s.getElementIndex(f,E)])>r){var h,p=e[s.getElementIndex(f,f)],m=e[s.getElementIndex(E,E)],T=e[s.getElementIndex(f,E)],y=(p-m)/2/T;h=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(E,E)]=t[s.getElementIndex(f,f)]=c,t[s.getElementIndex(f,E)]=l,t[s.getElementIndex(E,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,E=e.z*e.z,f=e.z*e.w,h=e.w*e.w,d=r-u-E+h,_=2*(a-f),p=2*(i+l),m=2*(a+f),T=-r+u-E+h,y=2*(c-o),R=2*(i-l),A=2*(c+o),v=-r-u+E+h;return n(t)?(t[0]=d,t[1]=m,t[2]=R,t[3]=_,t[4]=T,t[5]=A,t[6]=p,t[7]=y,t[8]=v,t):new s(d,_,p,m,T,y,R,A,v)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*a,E=-i*u+c*o*a,f=c*u+i*o*a,h=r*u,d=i*a+c*o*u,_=-c*a+i*o*u,p=-o,m=c*r,T=i*r;return n(t)?(t[0]=l,t[1]=h,t[2]=p,t[3]=E,t[4]=d,t[5]=m,t[6]=f,t[7]=_,t[8]=T,t):new s(l,E,f,h,d,_,p,m,T)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],i=e[n+1],o=e[n+2];return r.x=a,r.y=i,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],i=e[t+6];return r.x=n,r.y=a,r.z=i,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var f=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),r};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],E=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=i,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=E,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[3]*a+e[6]*i,u=e[1]*n+e[4]*a+e[7]*i,s=e[2]*n+e[5]*a+e[8]*i;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var d=[1,0,0],_=[2,2,1],p=new s,m=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,i=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),h=r*c(f);i<10&&l(f)>h;)E(f,p),s.transpose(p,m),s.multiply(f,p,f),s.multiply(m,f,f),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*n-r*c)+u*(r*o-i*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],E=e[8],f=s.determinant(e);t[0]=o*E-l*u,t[1]=l*a-n*E,t[2]=n*u-o*a,t[3]=c*u-i*E,t[4]=r*E-c*a,t[5]=i*a-r*u,t[6]=i*l-c*o,t[7]=c*n-r*l,t[8]=r*o-i*n;var h=1/f;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}o.fromElements=function(e,t,n,a,i){return r(i)?(i.x=e,i.y=t,i.z=n,i.w=a,i):new o(e,t,n,a)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)&&i.equalsEpsilon(e.w,t.w,n,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t,r,a,i,o,u,s,c,l,E,f,h,d,_,p){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(c,0),this[3]=n(h,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(d,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(E,0),this[11]=n(_,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(p,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,i){return r=n(r,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=r.x,i[13]=r.y,i[14]=r.z,i[15]=1,i):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var i=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,E=t.x*t.z,f=t.x*t.w,h=t.y*t.y,d=t.y*t.z,_=t.y*t.w,p=t.z*t.z,m=t.z*t.w,T=t.w*t.w,y=s-h-p+T,R=2*(c-m),A=2*(E+_),v=2*(c+m),S=-s+h-p+T,N=2*(d-f),I=2*(E-_),M=2*(d+f),O=-s-h+p+T;return n[0]=y*i,n[1]=v*i,n[2]=I*i,n[3]=0,n[4]=R*o,n[5]=S*o,n[6]=M*o,n[7]=0,n[8]=A*u,n[9]=N*u,n[10]=O*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var E=new e,f=new e,h=new e;l.fromCamera=function(t,r){var n=t.position,i=t.direction,o=t.up;e.normalize(i,E),e.normalize(e.cross(E,o,f),f),e.normalize(e.cross(f,E,h),h);var u=f.x,s=f.y,c=f.z,d=E.x,_=E.y,p=E.z,m=h.x,T=h.y,y=h.z,R=n.x,A=n.y,v=n.z,S=u*-R+s*-A+c*-v,N=m*-R+T*-A+y*-v,I=d*R+_*A+p*v;return a(r)?(r[0]=u,r[1]=m,r[2]=-d,r[3]=0,r[4]=s,r[5]=T,r[6]=-_,r[7]=0,r[8]=c,r[9]=y,r[10]=-p,r[11]=0,r[12]=S,r[13]=N,r[14]=I,r[15]=1,r):new l(u,s,c,S,m,T,y,N,-d,-_,-p,I,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,i,o){var u=1/(t-e),s=1/(n-r),c=1/(i-a),l=-(t+e)*u,E=-(n+r)*s,f=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=E,o[14]=f,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,a,i,o){var u=2*a/(t-e),s=2*a/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),E=-(i+a)/(i-a),f=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=E,o[11]=-1,o[12]=0,o[13]=0,o[14]=f,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,i){var o=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var i=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,E=.5*(r-t),f=c,h=l,d=E,_=i+c,p=o+l,m=t+E;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=d,a[11]=0,a[12]=_,a[13]=p,a[14]=m,a[15]=1,a},l.computeView=function(t,r,n,a,i){return i[0]=a.x,i[1]=n.x,i[2]=-r.x,i[3]=0,i[4]=a.y,i[5]=n.y,i[6]=-r.y,i[7]=0,i[8]=a.z,i[9]=n.z,i[10]=-r.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(n,t),i[14]=e.dot(r,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],i=e[n+1],o=e[n+2],u=e[n+3];return r.x=a,r.y=i,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return r.x=n,r.y=a,r.z=i,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var d=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],d)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],d)),r};var _=new e;l.getMaximumScale=function(t){return l.getScale(t,_),e.maximumComponent(_)},l.multiply=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],E=e[8],f=e[9],h=e[10],d=e[11],_=e[12],p=e[13],m=e[14],T=e[15],y=t[0],R=t[1],A=t[2],v=t[3],S=t[4],N=t[5],I=t[6],M=t[7],O=t[8],g=t[9],C=t[10],w=t[11],P=t[12],x=t[13],L=t[14],U=t[15],b=n*y+u*R+E*A+_*v,F=a*y+s*R+f*A+p*v,D=i*y+c*R+h*A+m*v,B=o*y+l*R+d*A+T*v,z=n*S+u*N+E*I+_*M,G=a*S+s*N+f*I+p*M,V=i*S+c*N+h*I+m*M,q=o*S+l*N+d*I+T*M,X=n*O+u*g+E*C+_*w,H=a*O+s*g+f*C+p*w,W=i*O+c*g+h*C+m*w,k=o*O+l*g+d*C+T*w,Y=n*P+u*x+E*L+_*U,Z=a*P+s*x+f*L+p*U,K=i*P+c*x+h*L+m*U,j=o*P+l*x+d*L+T*U;return r[0]=b,r[1]=F,r[2]=D,r[3]=B,r[4]=z,r[5]=G,r[6]=V,r[7]=q,r[8]=X,r[9]=H,r[10]=W,r[11]=k,r[12]=Y,r[13]=Z,r[14]=K,r[15]=j,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=e[12],h=e[13],d=e[14],_=t[0],p=t[1],m=t[2],T=t[4],y=t[5],R=t[6],A=t[8],v=t[9],S=t[10],N=t[12],I=t[13],M=t[14],O=n*_+o*p+c*m,g=a*_+u*p+l*m,C=i*_+s*p+E*m,w=n*T+o*y+c*R,P=a*T+u*y+l*R,x=i*T+s*y+E*R,L=n*A+o*v+c*S,U=a*A+u*v+l*S,b=i*A+s*v+E*S,F=n*N+o*I+c*M+f,D=a*N+u*I+l*M+h,B=i*N+s*I+E*M+d;return r[0]=O,r[1]=g,r[2]=C,r[3]=0,r[4]=w,r[5]=P,r[6]=x,r[7]=0,r[8]=L,r[9]=U,r[10]=b,r[11]=0,r[12]=F,r[13]=D,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=t[0],h=t[1],d=t[2],_=t[3],p=t[4],m=t[5],T=t[6],y=t[7],R=t[8],A=n*f+o*h+c*d,v=a*f+u*h+l*d,S=i*f+s*h+E*d,N=n*_+o*p+c*m,I=a*_+u*p+l*m,M=i*_+s*p+E*m,O=n*T+o*y+c*R,g=a*T+u*y+l*R,C=i*T+s*y+E*R;return r[0]=A,r[1]=v,r[2]=S,r[3]=0,r[4]=N,r[5]=I,r[6]=M,r[7]=0,r[8]=O,r[9]=g,r[10]=C,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=n*e[0]+a*e[4]+i*e[8]+e[12],u=n*e[1]+a*e[5]+i*e[9]+e[13],s=n*e[2]+a*e[6]+i*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var p=new e;l.multiplyByUniformScale=function(e,t,r){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,i=t.z;return 1===n&&1===a&&1===i?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=i*e[8],r[9]=i*e[9],r[10]=i*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*n+e[4]*a+e[8]*i+e[12]*o,s=e[1]*n+e[5]*a+e[9]*i+e[13]*o,c=e[2]*n+e[6]*a+e[10]*i+e[14]*o,l=e[3]*n+e[7]*a+e[11]*i+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i,u=e[1]*n+e[5]*a+e[9]*i,s=e[2]*n+e[6]*a+e[10]*i;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i+e[12],u=e[1]*n+e[5]*a+e[9]*i+e[13],s=e[2]*n+e[6]*a+e[10]*i+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var m=new s,T=new s,y=new t,R=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,m),T,u.EPSILON7)&&t.equals(l.getRow(e,3,y),R))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],i=e[8],o=e[12],E=e[1],f=e[5],h=e[9],d=e[13],_=e[2],p=e[6],A=e[10],v=e[14],S=e[3],N=e[7],I=e[11],M=e[15],O=A*M,g=v*I,C=p*M,w=v*N,P=p*I,x=A*N,L=_*M,U=v*S,b=_*I,F=A*S,D=_*N,B=p*S,z=O*f+w*h+P*d-(g*f+C*h+x*d),G=g*E+L*h+F*d-(O*E+U*h+b*d),V=C*E+U*f+D*d-(w*E+L*f+B*d),q=x*E+b*f+B*h-(P*E+F*f+D*h),X=g*a+C*i+x*o-(O*a+w*i+P*o),H=O*n+U*i+b*o-(g*n+L*i+F*o),W=w*n+L*a+B*o-(C*n+U*a+D*o),k=P*n+F*a+D*i-(x*n+b*a+B*i);O=i*d,g=o*h,C=a*d,w=o*f,P=a*h,x=i*f,L=n*d,U=o*E,b=n*h,F=i*E,D=n*f,B=a*E;var Y=O*N+w*I+P*M-(g*N+C*I+x*M),Z=g*S+L*I+F*M-(O*S+U*I+b*M),K=C*S+U*N+D*M-(w*S+L*N+B*M),j=x*S+b*N+B*I-(P*S+F*N+D*I),Q=C*A+x*v+g*p-(P*v+O*p+w*A),J=b*v+O*_+U*A-(L*A+F*v+g*_),$=L*p+B*v+w*_-(D*v+C*_+U*p),ee=D*A+P*_+F*p-(b*p+B*A+x*_),te=n*z+a*G+i*V+o*q;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=G*te,r[2]=V*te,r[3]=q*te,r[4]=X*te,r[5]=H*te,r[6]=W*te,r[7]=k*te,r[8]=Y*te,r[9]=Z*te,r[10]=K*te,r[11]=j*te,r[12]=Q*te,r[13]=J*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],E=e[12],f=e[13],h=e[14],d=-r*E-n*f-a*h,_=-i*E-o*f-u*h,p=-s*E-c*f-l*h;return t[0]=r,t[1]=i,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=d,t[13]=_,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),i=u.toRadians(r(i,0)),n(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(a,0),o.north=r(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,E=0,f=e.length;E<f;E++){var h=e[E];r=Math.min(r,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,d),o=Math.max(o,d)}return a-r>o-i&&(r=i,a=o,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=a,t.north=l,t):new s(r,c,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,E=-Number.MAX_VALUE,f=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0,_=e.length;d<_;d++){var p=t.cartesianToCartographic(e[d]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),f=Math.min(f,p.latitude),h=Math.max(h,p.latitude);var m=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,m),E=Math.max(E,m)}return c-o>E-l&&(o=l,c=E,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(a)?(a.west=o,a.south=f,a.east=c,a.north=h,a):new s(o,f,c,h)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),E=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&E<=l)){var f=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(f>=h))return n(r)?(r.west=l,r.south=f,r.east=E,r.north=h,r):new s(l,f,E,h)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return n(r)?(r.west=a,r.south=i,r.east=o,r.north=u,r):new s(a,i,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),E=u.convertLongitudeRange(Math.max(a,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=E,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<i||u.equalsEpsilon(r,i,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=r(t,i.WGS84),a=r(a,0),n(o)||(o=[]);var l=0,E=e.north,f=e.south,h=e.east,d=e.west,_=c;_.height=a,_.longitude=d,_.latitude=E,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.longitude=h,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.latitude=f,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.longitude=d,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.latitude=E<0?E:f>0?f:0;for(var p=1;p<8;++p)_.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,_)&&(o[l]=t.cartographicToCartesian(_,o[l]),l++);return 0===_.latitude&&(_.longitude=d,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.longitude=h,o[l]=t.cartographicToCartesian(_,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,i,o,u,s,c,l,E){"use strict";function f(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var h=new e,d=new e,_=new e,p=new e,m=new e,T=new e,y=new e,R=new e,A=new e,v=new e,S=new e,N=new e;f.fromPoints=function(t,r){if(a(r)||(r=new f),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],y),o=e.clone(i,h),u=e.clone(i,d),s=e.clone(i,_),c=e.clone(i,p),l=e.clone(i,m),E=e.clone(i,T),I=t.length;for(n=1;n<I;n++){e.clone(t[n],i);var M=i.x,O=i.y,g=i.z;M<o.x&&e.clone(i,o),M>c.x&&e.clone(i,c),O<u.y&&e.clone(i,u),O>l.y&&e.clone(i,l),g<s.z&&e.clone(i,s),g>E.z&&e.clone(i,E)}var C=e.magnitudeSquared(e.subtract(c,o,R)),w=e.magnitudeSquared(e.subtract(l,u,R)),P=e.magnitudeSquared(e.subtract(E,s,R)),x=o,L=c,U=C;w>U&&(U=w,x=u,L=l),P>U&&(U=P,x=s,L=E);var b=A;b.x=.5*(x.x+L.x),b.y=.5*(x.y+L.y),b.z=.5*(x.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,R)),D=Math.sqrt(F),B=v;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=E.z;var G=e.multiplyByScalar(e.add(B,z,R),.5,N),V=0;for(n=0;n<I;n++){e.clone(t[n],i);var q=e.magnitude(e.subtract(i,G,R));q>V&&(V=q);var X=e.magnitudeSquared(e.subtract(i,b,R));if(X>F){var H=Math.sqrt(X);D=.5*(D+H),F=D*D;var W=H-D;b.x=(D*b.x+W*i.x)/H,b.y=(D*b.y+W*i.y)/H,b.z=(D*b.z+W*i.z)/H}}return D<V?(e.clone(b,r.center),r.radius=D):(e.clone(G,r.center),r.radius=V),r};var I=new o,M=new e,O=new e,g=new t,C=new t;f.fromRectangle2D=function(e,t,r){return f.fromRectangleWithHeights2D(e,t,0,0,r)},f.fromRectangleWithHeights2D=function(t,r,i,o,u){if(a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=n(r,I),E.southwest(t,g),g.height=i,E.northeast(t,C),C.height=o;var s=r.project(g,M),c=r.project(C,O),l=c.x-s.x,h=c.y-s.y,d=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+d*d);var _=u.center;return _.x=s.x+.5*l,_.y=s.y+.5*h,_.z=s.z+.5*d,u};var w=[];f.fromRectangle3D=function(t,r,o,u){if(r=n(r,i.WGS84),o=n(o,0),a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=E.subsample(t,r,o,w);return f.fromPoints(s,u)},f.fromVertices=function(t,r,i,o){if(a(o)||(o=new f),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=n(r,e.ZERO),i=n(i,3);var u=y;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,h),l=e.clone(u,d),E=e.clone(u,_),I=e.clone(u,p),M=e.clone(u,m),O=e.clone(u,T),g=t.length;for(s=0;s<g;s+=i){var C=t[s]+r.x,w=t[s+1]+r.y,P=t[s+2]+r.z;u.x=C,u.y=w,u.z=P,C<c.x&&e.clone(u,c),C>I.x&&e.clone(u,I),w<l.y&&e.clone(u,l),w>M.y&&e.clone(u,M),P<E.z&&e.clone(u,E),P>O.z&&e.clone(u,O)}var x=e.magnitudeSquared(e.subtract(I,c,R)),L=e.magnitudeSquared(e.subtract(M,l,R)),U=e.magnitudeSquared(e.subtract(O,E,R)),b=c,F=I,D=x;L>D&&(D=L,b=l,F=M),U>D&&(D=U,b=E,F=O);var B=A;B.x=.5*(b.x+F.x),B.y=.5*(b.y+F.y),B.z=.5*(b.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,R)),G=Math.sqrt(z),V=v;V.x=c.x,V.y=l.y,V.z=E.z;var q=S;q.x=I.x,q.y=M.y,q.z=O.z;var X=e.multiplyByScalar(e.add(V,q,R),.5,N),H=0;for(s=0;s<g;s+=i){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var W=e.magnitude(e.subtract(u,X,R));W>H&&(H=W);var k=e.magnitudeSquared(e.subtract(u,B,R));if(k>z){var Y=Math.sqrt(k);G=.5*(G+Y),z=G*G;var Z=Y-G;B.x=(G*B.x+Z*u.x)/Y,B.y=(G*B.y+Z*u.y)/Y,B.z=(G*B.z+Z*u.z)/Y}}return G<H?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=H),o},f.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new f),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=y;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,h),s=e.clone(i,d),c=e.clone(i,_),l=e.clone(i,p),E=e.clone(i,m),I=e.clone(i,T),M=t.length;for(o=0;o<M;o+=3){var O=t[o]+r[o],g=t[o+1]+r[o+1],C=t[o+2]+r[o+2];i.x=O,i.y=g,i.z=C,O<u.x&&e.clone(i,u),O>l.x&&e.clone(i,l),g<s.y&&e.clone(i,s),g>E.y&&e.clone(i,E),C<c.z&&e.clone(i,c),C>I.z&&e.clone(i,I)}var w=e.magnitudeSquared(e.subtract(l,u,R)),P=e.magnitudeSquared(e.subtract(E,s,R)),x=e.magnitudeSquared(e.subtract(I,c,R)),L=u,U=l,b=w;P>b&&(b=P,L=s,U=E),x>b&&(b=x,L=c,U=I);var F=A;F.x=.5*(L.x+U.x),F.y=.5*(L.y+U.y),F.z=.5*(L.z+U.z);var D=e.magnitudeSquared(e.subtract(U,F,R)),B=Math.sqrt(D),z=v;z.x=u.x,z.y=s.y,z.z=c.z;var G=S;G.x=l.x,G.y=E.y,G.z=I.z;var V=e.multiplyByScalar(e.add(z,G,R),.5,N),q=0;for(o=0;o<M;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(i,V,R));X>q&&(q=X);var H=e.magnitudeSquared(e.subtract(i,F,R));if(H>D){var W=Math.sqrt(H);B=.5*(B+W),D=B*B;var k=W-B;F.x=(B*F.x+k*i.x)/W,F.y=(B*F.y+k*i.y)/W,F.z=(B*F.z+k*i.z)/W}}return B<q?(e.clone(F,n.center),n.radius=B):(e.clone(V,n.center),n.radius=q),n},f.fromCornerPoints=function(t,r,n){a(n)||(n=new f);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},f.fromEllipsoid=function(t,r){return a(r)||(r=new f),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var P=new e;f.fromBoundingSpheres=function(t,r){if(a(r)||(r=new f),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return f.clone(t[0],r);if(2===n)return f.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=f.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,P)+c.radius)}return r.radius=s,r};var x=new e,L=new e,U=new e;f.fromOrientedBoundingBox=function(t,r){a(r)||(r=new f);var n=t.halfAxes,i=c.getColumn(n,0,x),o=c.getColumn(n,1,L),u=c.getColumn(n,2,U);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},f.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new f(t.center,t.radius)},f.packedLength=4,f.pack=function(e,t,r){r=n(r,0);var a=e.center;return t[r++]=a.x,t[r++]=a.y,t[r++]=a.z,t[r]=e.radius,t},f.unpack=function(e,t,r){t=n(t,0),a(r)||(r=new f);var i=r.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],r.radius=e[t],r};var b=new e,F=new e;f.union=function(t,r,n){a(n)||(n=new f);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,b),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var E=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+E)/l,F);return e.add(h,i,h),e.clone(h,n.center),n.radius=E,n};var D=new e;f.expand=function(t,r,n){n=f.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,D));return a>n.radius&&(n.radius=a),n},f.intersectPlane=function(t,r){var n=t.center,a=t.radius,i=r.normal,o=e.dot(i,n)+r.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},f.transform=function(e,t,r){return a(r)||(r=new f),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=l.getMaximumScale(t)*e.radius,r};var B=new e;f.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,B);return e.magnitudeSquared(n)-t.radius*t.radius},f.transformWithoutScale=function(e,t,r){return a(r)||(r=new f),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var z=new e;f.computePlaneDistances=function(t,r,n,i){a(i)||(i=new s);var o=e.subtract(t.center,r,z),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var G=new e,V=new e,q=new e,X=new e,H=new e,W=new t,k=new Array(8),Y=0;Y<8;++Y)k[Y]=new e;var Z=new o;return f.projectTo2D=function(t,r,a){r=n(r,Z);var i=r.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,G),c=e.cross(e.UNIT_Z,s,V);e.normalize(c,c);var l=e.cross(s,c,q);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var E=e.negate(l,H),h=e.negate(c,X),d=k,_=d[0];e.add(s,l,_),e.add(_,c,_),_=d[1],e.add(s,l,_),e.add(_,h,_),_=d[2],e.add(s,E,_),e.add(_,h,_),_=d[3],e.add(s,E,_),e.add(_,c,_),e.negate(s,s),_=d[4],e.add(s,l,_),e.add(_,c,_),_=d[5],e.add(s,l,_),e.add(_,h,_),_=d[6],e.add(s,E,_),e.add(_,h,_),_=d[7],e.add(s,E,_),e.add(_,c,_);for(var p=d.length,m=0;m<p;++m){var T=d[m];e.add(o,T,T);var y=i.cartesianToCartographic(T,W);r.project(y,T)}a=f.fromPoints(d,a),o=a.center;var R=o.x,A=o.y,v=o.z;return o.x=v,o.y=R,o.z=A,a},f.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},f.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},f.prototype.intersectPlane=function(e){return f.intersectPlane(this,e)},f.prototype.distanceSquaredTo=function(e){return f.distanceSquaredTo(this,e)},f.prototype.computePlaneDistances=function(e,t,r){return f.computePlaneDistances(this,e,t,r)},f.prototype.isOccluded=function(e){return f.isOccluded(this,e)},f.prototype.equals=function(e){return f.equals(this,e)},f.prototype.clone=function(e){return f.clone(this,e)},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(A)&&(A=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,v=n(e[1]))}return A}function i(){return a()&&v}function o(){if(!t(S)&&(S=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=n(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(I)){I=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(I=!0,M=n(e[1]),M.isNightly=!!e[2])}return I}function c(){return s()&&M}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0, -g=n(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,g=n(e[1]))}return O}function E(){return l()&&g}function f(){if(!t(C)){C=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,w=n(e[1]))}return C}function h(){return f()&&w}function d(){if(!t(P)){P=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(P=!0,x=n(e[1]))}return P}function _(){return t(L)||(L=/Windows/i.test(R.appVersion)),L}function p(){return d()&&x}function m(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),U}function T(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;F=t(r)&&""!==r,F&&(b=r)}return F}function y(){return T()?b:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,v,S,N,I,M,O,g,C,w,P,x,L,U,b,F,D={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:E,isEdge:f,edgeVersion:h,isFirefox:d,firefoxVersion:p,isWindows:_,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:m,supportsImageRenderingPixelated:T,imageRenderingValue:y};return D.supportsFullscreen=function(){return r.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,i){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,a);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case o.SHORT:return new Int16Array(r,n,a);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case o.INT:return new Int32Array(r,n,a);case o.UNSIGNED_INT:return new Uint32Array(r,n,a);case o.FLOAT:return new Float32Array(r,n,a);case o.DOUBLE:return new Float64Array(r,n,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var a=0;a<n;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var a=0;a<n;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var E=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,r,n,a){"use strict";var i={};i.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,r){return i.octDecodeInRange(e,t,255,r)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),a=256*(r-n);return i.octDecode(n,a,t)},i.octPack=function(e,t,r,n){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(r,o);return n.x=65536*s.x+a,n.y=65536*s.y+u,n},i.octUnpack=function(e,t,r,n){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,r),i.octDecode(o,s,n)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},i}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function a(r,a,s,c,l){n(l)||(l=new t);var E,f,h,d,_,p,m,T;n(a.z)?(E=t.subtract(s,a,i),f=t.subtract(c,a,o),h=t.subtract(r,a,u),d=t.dot(E,E),_=t.dot(E,f),p=t.dot(E,h),m=t.dot(f,f),T=t.dot(f,h)):(E=e.subtract(s,a,i),f=e.subtract(c,a,o),h=e.subtract(r,a,u),d=e.dot(E,E),_=e.dot(E,f),p=e.dot(E,h),m=e.dot(f,f),T=e.dot(f,h));var y=1/(d*m-_*_);return l.y=(m*p-_*T)*y,l.z=(d*T-_*p)*y,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var a={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var i=t.high,o=t.low;return n.encode(e.x,a),i.x=a.high,o.x=a.low,n.encode(e.y,a),i.y=a.high,o.y=a.low,n.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,i);var a=i.high,o=i.low;t[r]=a.x,t[r+1]=a.y,t[r+2]=a.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var i;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-n/e,i<0?[i,0]:[0,i];var c=n*n,l=4*e*a,E=r(c,-l,t.EPSILON14);if(E<0)return[];var f=-.5*r(n,t.sign(n)*Math.sqrt(E),t.EPSILON14);return n>0?[f/e,a/f]:[a/f,f/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,i,o=e,u=t/3,s=r/3,c=n,l=o*s,E=u*c,f=u*u,h=s*s,d=o*s-f,_=o*c-u*s,p=u*c-h,m=4*d*p-_*_;if(m<0){var T,y,R;f*E>=l*h?(T=o,y=d,R=-2*u*d+o*_):(T=c,y=p,R=-c*_+2*s*p);var A=R<0?-1:1,v=-A*Math.abs(T)*Math.sqrt(-m);i=-R+v;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),I=i===v?-N:-y/N;return a=y<=0?N+I:-R/(N*N+I*I+y),f*E>=l*h?[(a-u)/o]:[-c/(a+s)]}var M=d,O=-2*u*d+o*_,g=p,C=-c*_+2*s*p,w=Math.sqrt(m),P=Math.sqrt(3)/2,x=Math.abs(Math.atan2(o*w,-O)/3);a=2*Math.sqrt(-M);var L=Math.cos(x);i=a*L;var U=a*(-L/2-P*Math.sin(x)),b=i+U>2*u?i-u:U-u,F=o,D=b/F;x=Math.abs(Math.atan2(c*w,-C)/3),a=2*Math.sqrt(-g),L=Math.cos(x),i=a*L,U=a*(-L/2-P*Math.sin(x));var B=-c,z=i+U<2*s?i+s:U+s,G=B/z,V=F*z,q=-b*z-F*B,X=b*B,H=(s*q-u*X)/(-u*q+s*V);return D<=H?D<=G?H<=G?[D,H,G]:[D,G,H]:[G,D,H]:D<=G?[H,D,G]:H<=G?[H,G,D]:[G,H,D]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,i=t*t,o=r*r;return 18*e*t*r*n+i*o-27*a*(n*n)-4*(e*o*r+i*t*n)},n.computeRealRoots=function(e,n,a,i){var o,u;if(0===e)return t.computeRealRoots(n,a,i);if(0===n){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,a,i)}return 0===a?0===i?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,i):0===i?(o=t.computeRealRoots(e,n,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,a,i)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,E=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(E.length>0){var f=-t/4,h=E[E.length-1];if(Math.abs(h)<r.EPSILON14){var d=n.computeRealRoots(1,s,l);if(2===d.length){var _,p=d[0],m=d[1];if(p>=0&&m>=0){var T=Math.sqrt(p),y=Math.sqrt(m);return[f-y,f-T,f+T,f+y]}if(p>=0&&m<0)return _=Math.sqrt(p),[f-_,f+_];if(p<0&&m>=0)return _=Math.sqrt(m),[f-_,f+_]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,v=(s+h+c/R)/2,S=n.computeRealRoots(1,R,A),N=n.computeRealRoots(1,-R,v);return 0!==S.length?(S[0]+=f,S[1]+=f,0!==N.length?(N[0]+=f,N[1]+=f,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=f,N[1]+=f,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,E=i*t+s-4*o,f=c*o-i*a*t+u,h=e.computeRealRoots(1,l,E,f);if(h.length>0){var d,_,p=h[0],m=a-p,T=m*m,y=t/2,R=m/2,A=T-4*o,v=T+4*Math.abs(o),S=c-4*p,N=c+4*Math.abs(p);if(p<0||A*N<S*v){var I=Math.sqrt(S);d=I/2,_=0===I?0:(t*R-i)/I}else{var M=Math.sqrt(A);d=0===M?0:(t*R-i)/M,_=M/2}var O,g;0===y&&0===d?(O=0,g=0):r.sign(y)===r.sign(d)?(O=y+d,g=p/O):(g=y-d,O=p/g);var C,w;0===R&&0===_?(C=0,w=0):r.sign(R)===r.sign(_)?(C=R+_,w=o/C):(w=R-_,C=o/w);var P=n.computeRealRoots(1,O,C),x=n.computeRealRoots(1,g,w);if(0!==P.length)return 0!==x.length?P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>x[0]&&P[0]<x[1]?[x[0],P[0],x[1],P[1]]:[P[0],x[0],P[1],x[1]]:P;if(0!==x.length)return x}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=r*r,l=c*r,E=n*n,f=E*n,h=a*a;return u*c*E-4*s*f-4*e*l*E+18*e*t*r*f-27*i*E*E+256*o*(h*a)+a*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*E+144*i*r*E)+h*(144*e*u*r-27*u*u-128*i*c-192*i*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,E=u/t,f=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=E<0?h+1:h,h+=f<0?h+1:h){case 0:return a(c,l,E,f);case 1:case 2:return i(c,l,E,f);case 3:case 4:return a(c,l,E,f);case 5:return i(c,l,E,f);case 6:case 7:return a(c,l,E,f);case 8:return i(c,l,E,f);case 9:case 10:return a(c,l,E,f);case 11:return i(c,l,E,f);case 12:case 13:case 14:case 15:return a(c,l,E,f);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,i,o,u,s,c,l){"use strict";function E(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function f(t,r,a){n(a)||(a=new i);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,T),f=e.dot(u,u),h=2*e.dot(u,l),d=e.magnitudeSquared(l)-c,_=E(f,h,d,v);if(n(_))return a.start=_.root0,a.stop=_.root1,a}function h(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function d(t,r,n,a,i){ -var l,E=a*a,f=i*i,d=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,_=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),p=t[u.COLUMN0ROW0]*E+t[u.COLUMN2ROW2]*f+a*r.x+n,m=f*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),T=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),y=[];if(0===T&&0===m){if(l=s.computeRealRoots(d,_,p),0===l.length)return y;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(y.push(new e(a,i*R,i*-A)),y.push(new e(a,i*R,i*A)),2===l.length){var v=l[1],S=Math.sqrt(Math.max(1-v*v,0));y.push(new e(a,i*v,i*-S)),y.push(new e(a,i*v,i*S))}return y}var N=T*T,I=m*m,M=d*d,O=T*m,g=M+I,C=2*(_*d+O),w=2*p*d+_*_-I+N,P=2*(p*_-O),x=p*p-N;if(0===g&&0===C&&0===w&&0===P)return y;l=c.computeRealRoots(g,C,w,P,x);var L=l.length;if(0===L)return y;for(var U=0;U<L;++U){var b,F=l[U],D=F*F,B=Math.max(1-D,0),z=Math.sqrt(B);b=o.sign(d)===o.sign(p)?h(d*D+p,_*F,o.EPSILON12):o.sign(p)===o.sign(_*F)?h(d*D,_*F+p,o.EPSILON12):h(d*D+_*F,p,o.EPSILON12);var G=h(m*F,T,o.EPSILON15),V=b*G;V<0?y.push(new e(a,i*F,i*z)):V>0?y.push(new e(a,i*F,i*-z)):0!==z?(y.push(new e(a,i*F,i*-z)),y.push(new e(a,i*F,i*z)),++U):y.push(new e(a,i*F,i*z))}return y}var _={};_.rayPlane=function(t,r,a){n(a)||(a=new e);var i=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,m=new e,T=new e,y=new e,R=new e;_.rayTriangleParametric=function(t,n,a,i,u){u=r(u,!1);var s,c,l,E,f,h=t.origin,d=t.direction,_=e.subtract(a,n,p),A=e.subtract(i,n,m),v=e.cross(d,A,T),S=e.dot(_,v);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,n,y),(l=e.dot(s,v))<0||l>S)return;if(c=e.cross(s,_,R),(E=e.dot(d,c))<0||l+E>S)return;f=e.dot(A,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,n,y),(l=e.dot(s,v)*N)<0||l>1)return;if(c=e.cross(s,_,R),(E=e.dot(d,c)*N)<0||l+E>1)return;f=e.dot(A,c)*N}return f},_.rayTriangle=function(t,r,a,i,o,u){var s=_.rayTriangleParametric(t,r,a,i,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;_.lineSegmentTriangle=function(t,r,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=_.rayTriangleParametric(c,a,i,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var v={root0:0,root1:0};_.raySphere=function(e,t,r){if(r=f(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;_.lineSegmentSphere=function(t,r,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=f(o,a,i),!(!n(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,I=new e;_.rayEllipsoid=function(t,r){var n,a,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),E=e.multiplyComponents(c,t.direction,I),f=e.magnitudeSquared(l),h=e.dot(l,E);if(f>1){if(h>=0)return;var d=h*h;if(n=f-1,a=e.magnitudeSquared(E),o=a*n,d<o)return;if(d>o){u=h*h-o,s=-h+Math.sqrt(u);var _=s/a,p=n/s;return _<p?new i(_,p):{start:p,stop:_}}var m=Math.sqrt(n/a);return new i(m,m)}return f<1?(n=f-1,a=e.magnitudeSquared(E),o=a*n,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(E),new i(0,-h/a)):void 0};var M=new e,O=new e,g=new e,C=new e,w=new e,P=new u,x=new u,L=new u,U=new u,b=new u,F=new u,D=new u,B=new e,z=new e,G=new t;_.grazingAltitudeLocation=function(t,r){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,M);if(e.dot(i,s)>=0)return a}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(i,M),E=e.normalize(l,l),f=e.mostOrthogonalAxis(l,C),h=e.normalize(e.cross(f,E,O),O),_=e.normalize(e.cross(E,h,g),g),p=P;p[0]=E.x,p[1]=E.y,p[2]=E.z,p[3]=h.x,p[4]=h.y,p[5]=h.z,p[6]=_.x,p[7]=_.y,p[8]=_.z;var m=u.transpose(p,x),T=u.fromScale(r.radii,L),y=u.fromScale(r.oneOverRadii,U),R=b;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,v,S=u.multiply(u.multiply(m,y,F),R,F),N=u.multiply(u.multiply(S,T,D),p,D),I=u.multiplyByVector(S,a,w),V=d(N,e.negate(I,M),0,0,1),q=V.length;if(q>0){for(var X=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,W=0;W<q;++W){A=u.multiplyByVector(T,u.multiplyByVector(p,V[W],B),B);var k=e.normalize(e.subtract(A,a,C),C),Y=e.dot(k,i);Y>H&&(H=Y,X=e.clone(A,X))}var Z=r.cartesianToCartographic(X,G);return H=o.clamp(H,0,1),v=e.magnitude(e.subtract(X,a,C))*Math.sqrt(1-H*H),v=c?-v:v,Z.height=v,r.cartographicToCartesian(Z,new e)}};var V=new e;return _.lineSegmentPlane=function(t,r,a,i){n(i)||(i=new e);var u=e.subtract(r,t,V),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),E=-(a.distance+l)/c;if(!(E<0||E>1))return e.multiplyByScalar(u,E,i),e.add(t,i,i),i}},_.trianglePlaneIntersection=function(t,r,n,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,r)+o<0,c=e.dot(i,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var E,f;if(1!==l&&2!==l||(E=new e,f=new e),1===l){if(u)return _.lineSegmentPlane(t,r,a,E),_.lineSegmentPlane(t,n,a,f),{positions:[t,r,n,E,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return _.lineSegmentPlane(r,n,a,E),_.lineSegmentPlane(r,t,a,f),{positions:[t,r,n,E,f],indices:[1,3,4,2,0,4,2,4,3]};if(c)return _.lineSegmentPlane(n,t,a,E),_.lineSegmentPlane(n,r,a,f),{positions:[t,r,n,E,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return _.lineSegmentPlane(r,t,a,E),_.lineSegmentPlane(n,t,a,f),{positions:[t,r,n,E,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return _.lineSegmentPlane(n,r,a,E),_.lineSegmentPlane(t,r,a,f),{positions:[t,r,n,E,f],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return _.lineSegmentPlane(t,n,a,E),_.lineSegmentPlane(r,n,a,f),{positions:[t,r,n,E,f],indices:[0,1,4,0,4,3,2,3,4]}}},_}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,i,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var i=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=i,a):new u(n,i)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),i=t.w;return r(n)?(e.clone(a,n.normal),n.distance=i,n):new u(a,i)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(r,c,c),u.fromPointNormal(c,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,a=r.maximumIndex,i=e(r.cacheSize,24),o=n.length;if(!t(a)){a=0;for(var u=0,s=n[u];u<o;)s>a&&(a=s),++u,s=n[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var E=i+1,f=0;f<o;++f)E-c[n[f]]>i&&(c[n[f]]=E,++E);return(E-i+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<n;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}r=e(r,e.EMPTY_OBJECT);var a,i=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=i.length,c=0,l=0,E=i[l],f=s;if(t(o))c=o+1;else{for(;l<f;)E>c&&(c=E),++l,E=i[l];if(-1===c)return 0;++c}var h,d=[];for(h=0;h<c;h++)d[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var _=0;l<f;)d[i[l]].vertexTriangles.push(_),++d[i[l]].numLiveTriangles,d[i[l+1]].vertexTriangles.push(_),++d[i[l+1]].numLiveTriangles,d[i[l+2]].vertexTriangles.push(_),++d[i[l+2]].numLiveTriangles,++_,l+=3;var p=0,m=u+1;a=1;var T,y,R=[],A=[],v=0,S=[],N=s/3,I=[];for(h=0;h<N;h++)I[h]=!1;for(var M,O;-1!==p;){R=[],y=d[p],O=y.vertexTriangles.length;for(var g=0;g<O;++g)if(_=y.vertexTriangles[g],!I[_]){I[_]=!0,l=_+_+_;for(var C=0;C<3;++C)M=i[l],R.push(M),A.push(M),S[v]=M,++v,T=d[M],--T.numLiveTriangles,m-T.timeStamp>u&&(T.timeStamp=m,++m),++l}p=function(e,t,r,a,i,o,u){for(var s,c=-1,l=-1,E=0;E<r.length;){var f=r[E];a[f].numLiveTriangles&&(s=0,i-a[f].timeStamp+2*a[f].numLiveTriangles<=t&&(s=i-a[f].timeStamp),(s>l||-1===l)&&(l=s,c=f)),++E}return-1===c?n(a,o,e,u):c}(i,u,R,d,m,A,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h,d,_,p,m,T,y,R,A,v,S,N){"use strict";function I(e,t,r,n,a){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=a,e[t++]=a,e[t]=r}function M(e){for(var t=e.length,r=t/3*6,n=p.createTypedArray(t,r),a=0,i=0;i<t;i+=3,a+=6)I(n,a,e[i],e[i+1],e[i+2]);return n}function O(e){var t=e.length;if(t>=3){var r=6*(t-2),n=p.createTypedArray(t,r);I(n,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)I(n,a,e[i-1],e[i],e[i-2]);return n}return new Uint16Array}function g(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=p.createTypedArray(t,r),a=e[0],i=0,o=1;o<t;++o,i+=6)I(n,i,a,e[o],e[o+1]);return n}return new Uint16Array}function C(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new d({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function w(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var a=t[n],i=0;i<a.componentsPerAttribute;++i)e[n].values.push(a.values[r*a.componentsPerAttribute+i])}function P(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),A.multiplyByPoint(e,ie,ie),a.pack(ie,r,i)}function x(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,r,i)}function L(e,t){var r,n=e.length,a={},i=e[0][t].attributes;for(r in i)if(i.hasOwnProperty(r)&&c(i[r])&&c(i[r].values)){for(var o=i[r],s=o.values.length,l=!0,E=1;E<n;++E){var f=e[E][t].attributes[r];if(!c(f)||o.componentDatatype!==f.componentDatatype||o.componentsPerAttribute!==f.componentsPerAttribute||o.normalize!==f.normalize){l=!1;break}s+=f.values.length}l&&(a[r]=new d({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function U(e,t){var n,i,o,u,s,l,E,f=e.length,d=(e[0].modelMatrix,c(e[0][t].indices)),_=e[0][t].primitiveType,m=L(e,t);for(n in m)if(m.hasOwnProperty(n))for(s=m[n].values,u=0,i=0;i<f;++i)for(l=e[i][t].attributes[n].values,E=l.length,o=0;o<E;++o)s[u++]=l[o];var T;if(d){var y=0;for(i=0;i<f;++i)y+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:m,primitiveType:S.POINTS})),A=p.createTypedArray(R,y),v=0,N=0;for(i=0;i<f;++i){var I=e[i][t].indices,M=I.length;for(u=0;u<M;++u)A[v++]=N+I[u];N+=h.computeNumberOfVertices(e[i][t])}T=A}var O,g=new a,C=0;for(i=0;i<f;++i){if(O=e[i][t].boundingSphere,!c(O)){g=void 0;break}a.add(O.center,g,g)}if(c(g))for(a.divideByScalar(g,f,g),i=0;i<f;++i){O=e[i][t].boundingSphere;var w=a.magnitude(a.subtract(O.center,g,se))+O.radius;w>C&&(C=w)}return new h({attributes:m,indices:T,primitiveType:_,boundingSphere:c(g)?new r(g,C):void 0})}function b(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function F(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,a=3;a<t;++a)r[n++]=a-1,r[n++]=0,r[n++]=a;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function D(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,a=3;a<t-1;a+=2)r[n++]=a,r[n++]=a-1,r[n++]=a+1,a+2<t&&(r[n++]=a,r[n++]=a+1,r[n++]=a+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return e.indices=r,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function V(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return F(e);case S.TRIANGLE_STRIP:return D(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function q(e,t){Math.abs(e.y)<y.EPSILON6&&(e.y=t?-y.EPSILON6:y.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return q(e,e.y<0),q(t,t.y<0),void q(r,r.y<0);var n,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(r.y);n=a>i?a>o?y.sign(e.y):y.sign(r.y):i>o?y.sign(t.y):y.sign(r.y);var u=n<0;q(e,u),q(t,u),q(r,u)}function H(e,t,r,n){a.add(e,a.multiplyByScalar(a.subtract(t,e,Ae),e.y/(e.y-t.y),Ae),r),a.clone(r,n),q(r,!0),q(n,!1)}function W(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,a=t.y<0,i=r.y<0,o=0;o+=n?1:0,o+=a?1:0,o+=i?1:0;var u=Me.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?a?i||(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Me.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=ve,s[4]=Se,s[5]=Ne,s[6]=Ie,s.length=7),Me}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var a in n)if(n.hasOwnProperty(a)&&c(n[a])&&c(n[a].values)){var i=n[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=p.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var a=t[n];r[n]=new d({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:r,indices:[],primitiveType:e.primitiveType})}function Z(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function K(e,r,i,o,u,s,l,E,f,h,d,_){if(c(s)||c(l)||c(E)||c(f)||c(h)){var p=a.fromArray(u,3*e,Oe),m=a.fromArray(u,3*r,ge),T=a.fromArray(u,3*i,Ce),y=t(o,p,m,T,we);if(c(s)){var R=a.fromArray(s,3*e,Oe),A=a.fromArray(s,3*r,ge),v=a.fromArray(s,3*i,Ce);a.multiplyByScalar(R,y.x,R),a.multiplyByScalar(A,y.y,A),a.multiplyByScalar(v,y.z,v);var S=a.add(R,A,R);a.add(S,v,S),a.normalize(S,S),a.pack(S,d.normal.values,3*_)}if(c(h)){var N=a.fromArray(h,3*e,Oe),I=a.fromArray(h,3*r,ge),M=a.fromArray(h,3*i,Ce);a.multiplyByScalar(N,y.x,N),a.multiplyByScalar(I,y.y,I),a.multiplyByScalar(M,y.z,M);var O;a.equals(N,a.ZERO)&&a.equals(I,a.ZERO)&&a.equals(M,a.ZERO)?(O=Oe,O.x=0,O.y=0,O.z=0):(O=a.add(N,I,N),a.add(O,M,O),a.normalize(O,O)),a.pack(O,d.extrudeDirection.values,3*_)}if(c(l)){var g=a.fromArray(l,3*e,Oe),C=a.fromArray(l,3*r,ge),w=a.fromArray(l,3*i,Ce);a.multiplyByScalar(g,y.x,g),a.multiplyByScalar(C,y.y,C),a.multiplyByScalar(w,y.z,w);var P=a.add(g,C,g);a.add(P,w,P),a.normalize(P,P),a.pack(P,d.tangent.values,3*_)}if(c(E)){var x=a.fromArray(E,3*e,Oe),L=a.fromArray(E,3*r,ge),U=a.fromArray(E,3*i,Ce);a.multiplyByScalar(x,y.x,x),a.multiplyByScalar(L,y.y,L),a.multiplyByScalar(U,y.z,U);var b=a.add(x,L,x);a.add(b,U,b),a.normalize(b,b),a.pack(b,d.bitangent.values,3*_)}if(c(f)){var F=n.fromArray(f,2*e,Pe),D=n.fromArray(f,2*r,xe),B=n.fromArray(f,2*i,Le);n.multiplyByScalar(F,y.x,F),n.multiplyByScalar(D,y.y,D),n.multiplyByScalar(B,y.z,B);var z=n.add(F,D,F);n.add(z,B,z),n.pack(z,d.st.values,2*_)}}}function j(e,t,r,n,a,i){var o=e.position.values.length/3;if(-1!==a){var u=n[a],s=r[u];return-1===s?(r[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function Q(e){var t,r,n,i,o,u=e.geometry,s=u.attributes,l=s.position.values,E=c(s.normal)?s.normal.values:void 0,f=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,d=c(s.st)?s.st.values:void 0,_=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,p=u.indices,m=Y(u),T=Y(u),y=[];y.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<y.length;++o)y[o]=-1,R[o]=-1;var A=p.length;for(o=0;o<A;o+=3){var v=p[o],S=p[o+1],N=p[o+2],I=a.fromArray(l,3*v),M=a.fromArray(l,3*S),O=a.fromArray(l,3*N),g=W(I,M,O);if(c(g)&&g.positions.length>3)for(var C=g.positions,w=g.indices,P=w.length,x=0;x<P;++x){var L=w[x],U=C[L];U.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,p,L<3?o+L:-1,U),K(v,S,N,U,l,E,h,f,d,_,t,i)}else c(g)&&(I=g.positions[0],M=g.positions[1],O=g.positions[2]),I.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,p,o,I),K(v,S,N,I,l,E,h,f,d,_,t,i),i=j(t,r,n,p,o+1,M),K(v,S,N,M,l,E,h,f,d,_,t,i),i=j(t,r,n,p,o+2,O),K(v,S,N,O,l,E,h,f,d,_,t,i)}Z(e,T,m)}function J(e){var t,r=e.geometry,n=r.attributes,i=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,E=[];E.length=i.length/3;var f=[];for(f.length=i.length/3,t=0;t<E.length;++t)E[t]=-1,f[t]=-1;for(t=0;t<l;t+=2){var h=o[t],d=o[t+1],_=a.fromArray(i,3*h,Oe),p=a.fromArray(i,3*d,ge);Math.abs(_.y)<y.EPSILON6&&(_.y<0?_.y=-y.EPSILON6:_.y=y.EPSILON6),Math.abs(p.y)<y.EPSILON6&&(p.y<0?p.y=-y.EPSILON6:p.y=y.EPSILON6);var m=u.attributes,R=u.indices,A=f,v=s.attributes,S=s.indices,N=E,I=T.lineSegmentPlane(_,p,Ue,Ce);if(c(I)){var M=a.multiplyByScalar(a.UNIT_Y,5*y.EPSILON9,be);_.y<0&&(a.negate(M,M),m=s.attributes,R=s.indices,A=E,v=u.attributes,S=u.indices,N=f);var O=a.add(I,M,Fe);j(m,R,A,o,t,_),j(m,R,A,o,-1,O),a.negate(M,M),a.add(I,M,O),j(v,S,N,o,-1,O),j(v,S,N,o,t+1,p)}else{var g,C,w;_.y<0?(g=s.attributes,C=s.indices,w=E):(g=u.attributes,C=u.indices,w=f),j(g,C,w,o,t,_),j(g,C,w,o,t+1,p)}}Z(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,i=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=a.unpack(r,u,ze);if(!(s.x>0)){var c=a.unpack(n,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):a.pack(s,n,u));var l=a.unpack(i,u,Ve);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=r[u+3],i[u+1]=r[u+4],i[u+2]=r[u+5]):a.pack(s,i,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,E=s.prevPosition.values,f=s.nextPosition.values,h=s.expandAndWidth.values,d=c(s.st)?s.st.values:void 0,_=c(s.color)?s.color.values:void 0,p=Y(u),m=Y(u),R=!1,A=l.length/3;for(t=0;t<A;t+=4){var v=t,S=t+2,N=a.fromArray(l,3*v,ze),I=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<Ye)for(N.y=Ye*(I.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,r=3*v;r<3*v+12;r+=3)E[r]=l[3*t],E[r+1]=l[3*t+1],E[r+2]=l[3*t+2];if(Math.abs(I.y)<Ye)for(I.y=Ye*(N.y<0?-1:1),l[3*(t+2)+1]=I.y,l[3*(t+3)+1]=I.y,r=3*v;r<3*v+12;r+=3)f[r]=l[3*(t+2)],f[r+1]=l[3*(t+2)+1],f[r+2]=l[3*(t+2)+2];var M=p.attributes,O=p.indices,g=m.attributes,C=m.indices,w=T.lineSegmentPlane(N,I,Ue,qe);if(c(w)){R=!0;var P=a.multiplyByScalar(a.UNIT_Y,ke,Xe);N.y<0&&(a.negate(P,P),M=m.attributes,O=m.indices,g=p.attributes,C=p.indices);var x=a.add(w,P,He);M.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.position.values.push(x.x,x.y,x.z),M.position.values.push(x.x,x.y,x.z),M.prevPosition.values.push(E[3*v],E[3*v+1],E[3*v+2]),M.prevPosition.values.push(E[3*v+3],E[3*v+4],E[3*v+5]),M.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),a.negate(P,P),a.add(w,P,x),g.position.values.push(x.x,x.y,x.z),g.position.values.push(x.x,x.y,x.z),g.position.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.nextPosition.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.nextPosition.values.push(f[3*S],f[3*S+1],f[3*S+2]),g.nextPosition.values.push(f[3*S+3],f[3*S+4],f[3*S+5]);var L=n.fromArray(h,2*v,De),U=Math.abs(L.y);M.expandAndWidth.values.push(-1,U,1,U),M.expandAndWidth.values.push(-1,-U,1,-U),g.expandAndWidth.values.push(-1,U,1,U),g.expandAndWidth.values.push(-1,-U,1,-U);var b=a.magnitudeSquared(a.subtract(w,N,Ve));if(b/=a.magnitudeSquared(a.subtract(I,N,Ve)),c(_)){var F=i.fromArray(_,4*v,We),D=i.fromArray(_,4*S,We),B=y.lerp(F.x,D.x,b),z=y.lerp(F.y,D.y,b),G=y.lerp(F.z,D.z,b),V=y.lerp(F.w,D.w,b);for(r=4*v;r<4*v+8;++r)M.color.values.push(_[r]);for(M.color.values.push(B,z,G,V),M.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),r=4*S;r<4*S+8;++r)g.color.values.push(_[r])}if(c(d)){var q=n.fromArray(d,2*v,De),X=n.fromArray(d,2*(t+3),Be),H=y.lerp(q.x,X.x,b);for(r=2*v;r<2*v+4;++r)M.st.values.push(d[r]);for(M.st.values.push(H,q.y),M.st.values.push(H,X.y),g.st.values.push(H,q.y),g.st.values.push(H,X.y),r=2*S;r<2*S+4;++r)g.st.values.push(d[r])}o=M.position.values.length/3-4,O.push(o,o+2,o+1),O.push(o+1,o+2,o+3),o=g.position.values.length/3-4,C.push(o,o+2,o+1),C.push(o+1,o+2,o+3)}else{var W,k;for(N.y<0?(W=m.attributes,k=m.indices):(W=p.attributes,k=p.indices),W.position.values.push(N.x,N.y,N.z),W.position.values.push(N.x,N.y,N.z),W.position.values.push(I.x,I.y,I.z),W.position.values.push(I.x,I.y,I.z),r=3*t;r<3*t+12;++r)W.prevPosition.values.push(E[r]),W.nextPosition.values.push(f[r]);for(r=2*t;r<2*t+8;++r)W.expandAndWidth.values.push(h[r]),c(d)&&W.st.values.push(d[r]);if(c(_))for(r=4*t;r<4*t+16;++r)W.color.values.push(_[r]);o=W.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}R&&($(m),$(p)),Z(e,m,p)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=M(t);break;case S.TRIANGLE_STRIP:e.indices=O(t);break;case S.TRIANGLE_FAN:e.indices=g(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),E=0,f=0;f<o;f+=3)l[E++]=a[f],l[E++]=a[f+1],l[E++]=a[f+2],l[E++]=a[f]+i[f]*n,l[E++]=a[f+1]+i[f+1]*n,l[E++]=a[f+2]+i[f+2]*n;var _,p=e.boundingSphere;return c(p)&&(_=new r(p.center,p.radius+n)),new h({attributes:{position:new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:_})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,a={},i=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(a[u]=i++)}for(var s in n)n.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),a=0;a<t;a++)n[a]=-1;for(var i,o=r,s=o.length,l=p.createTypedArray(t,s),E=0,f=0,d=0;E<s;)i=n[o[E]],-1!==i?l[f]=i:(i=o[E],n[i]=d,l[f]=d,++d),++E,++f;e.indices=l;var _=e.attributes;for(var m in _)if(_.hasOwnProperty(m)&&c(_[m])&&c(_[m].values)){for(var T=_[m],y=T.values,R=0,A=T.componentsPerAttribute,v=u.createTypedArray(T.componentDatatype,d*A);R<t;){var S=n[R];if(-1!==S)for(var N=0;N<A;N++)v[A*S+N]=y[A*R+N];++R}T.values=v}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,a=0,i=0;i<n;i++)r[i]>a&&(a=r[i]);e.indices=N.tipsify({indices:r,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=h.computeNumberOfVertices(e);if(c(e.indices)&&r>=y.SIXTY_FOUR_KILOBYTES){var n,a=[],i=[],o=0,u=C(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var E=0;E<l;E+=n){for(var f=0;f<n;++f){var d=s[E+f],_=a[d];c(_)||(_=o++,a[d]=_,w(u,e.attributes,d)),i.push(_)}o+n>=y.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=C(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new a,ne=new o;te.projectTo2D=function(e,t,r,n,i){var o=e.attributes[t];i=c(i)?i:new f;for(var s=i.ellipsoid,l=o.values,E=new Float64Array(l.length),h=0,_=0;_<l.length;_+=3){var p=a.fromArray(l,_,re),m=s.cartesianToCartographic(p,ne),T=i.project(m,re);E[h++]=T.x,E[h++]=T.y,E[h++]=T.z}return e.attributes[r]=o,e.attributes[n]=new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:E}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)E.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var f=a.componentsPerAttribute;return e.attributes[r]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:s}),e.attributes[n]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:c}),delete e.attributes[t],e};var ie=new a,oe=new A,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(A.equals(t,A.IDENTITY))return e;var n=e.geometry.attributes;P(t,n.position),P(t,n.prevPosition),P(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(A.inverse(t,oe),A.transpose(oe,oe),A.getRotation(oe,ue),x(ue,n.normal),x(ue,n.tangent),x(ue,n.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=r.transform(a,t,a)),e.modelMatrix=A.clone(A.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,a=0;a<n;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&r.push(i)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,Ee=new a,fe=new a;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,i=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),E=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var f=0;for(t=0;t<s;t+=3){var h=r[t],_=r[t+1],p=r[t+2],m=3*h,T=3*_,R=3*p;le.x=i[m],le.y=i[m+1],le.z=i[m+2],Ee.x=i[T],Ee.y=i[T+1],Ee.z=i[T+2],fe.x=i[R],fe.y=i[R+1],fe.z=i[R+2],c[h].count++,c[_].count++,c[p].count++,a.subtract(Ee,le,Ee),a.subtract(fe,le,fe),l[f]=a.cross(Ee,fe,new a),f++}var A=0;for(t=0;t<o;t++)c[t].indexOffset+=A,A+=c[t].count;f=0;var v;for(t=0;t<s;t+=3){v=c[r[t]];var S=v.indexOffset+v.currentCount;E[S]=f,v.currentCount++,v=c[r[t+1]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,v=c[r[t+2]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,f++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var I=3*t;if(v=c[t],a.clone(a.ZERO,ce),v.count>0){for(f=0;f<v.count;f++)a.add(ce,l[E[v.indexOffset+f]],ce);a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&a.clone(l[E[v.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[I]=ce.x,N[I+1]=ce.y,N[I+2]=ce.z}return e.attributes.normal=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,de=new a,_e=new a;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var E,f,h;for(t=0;t<c;t+=3){var _=r[t],p=r[t+1],m=r[t+2];E=3*_,f=3*p,h=3*m;var T=2*_,y=2*p,R=2*m,A=n[E],v=n[E+1],S=n[E+2],N=o[T],I=o[T+1],M=o[y+1]-I,O=o[R+1]-I,g=1/((o[y]-N)*O-(o[R]-N)*M),C=(O*(n[f]-A)-M*(n[h]-A))*g,w=(O*(n[f+1]-v)-M*(n[h+1]-v))*g,P=(O*(n[f+2]-S)-M*(n[h+2]-S))*g;l[E]+=C,l[E+1]+=w,l[E+2]+=P,l[f]+=C,l[f+1]+=w,l[f+2]+=P,l[h]+=C,l[h+1]+=w,l[h+2]+=P}var x=new Float32Array(3*s),L=new Float32Array(3*s);for(t=0;t<s;t++){E=3*t,f=E+1,h=E+2;var U=a.fromArray(i,E,he),b=a.fromArray(l,E,_e),F=a.dot(U,b);a.multiplyByScalar(U,F,de),a.normalize(a.subtract(b,de,b),b),x[E]=b.x,x[f]=b.y,x[h]=b.z,a.normalize(a.cross(U,b,b),b),L[E]=b.x,L[f]=b.y,L[h]=b.z}return e.attributes.tangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:x}),e.attributes.bitangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:L}),e};var pe=new n,me=new a,Te=new a,ye=new a,Re=new n;te.compressVertices=function(t){var r,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),E=0;for(r=0;r<i;++r)a.fromArray(s,3*r,me),a.equals(me,a.ZERO)?E+=2:(Re=e.octEncodeInRange(me,65535,Re),l[E++]=Re.x,l[E++]=Re.y);return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var f=t.attributes.normal,h=t.attributes.st,_=c(f),p=c(h);if(!_&&!p)return t;var m,T,y,R,A=t.attributes.tangent,v=t.attributes.bitangent,S=c(A),N=c(v);_&&(m=f.values),p&&(T=h.values),S&&(y=A.values),N&&(R=v.values),i=(_?m.length:T.length)/(_?3:2);var I=i,M=p&&_?2:1;M+=S||N?1:0,I*=M;var O=new Float32Array(I),g=0;for(r=0;r<i;++r){p&&(n.fromArray(T,2*r,pe),O[g++]=e.compressTextureCoordinates(pe));var C=3*r;_&&c(y)&&c(R)?(a.fromArray(m,C,me),a.fromArray(y,C,Te),a.fromArray(R,C,ye),e.octPack(me,Te,ye,pe),O[g++]=pe.x,O[g++]=pe.y):(_&&(a.fromArray(m,C,me),O[g++]=e.octEncodeFloat(me)),S&&(a.fromArray(y,C,me),O[g++]=e.octEncodeFloat(me)),N&&(a.fromArray(R,C,me),O[g++]=e.octEncodeFloat(me)))}return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:M,values:O}),_&&delete t.attributes.normal,p&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Ae=new a,ve=new a,Se=new a,Ne=new a,Ie=new a,Me={positions:new Array(7),indices:new Array(9)},Oe=new a,ge=new a,Ce=new a,we=new a,Pe=new n,xe=new n,Le=new n,Ue=v.fromPointNormal(a.ZERO,a.UNIT_Y),be=new a,Fe=new a,De=new n,Be=new n,ze=new a,Ge=new a,Ve=new a,qe=new a,Xe=new a,He=new a,We=new i,ke=5*y.EPSILON9,Ye=y.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,v.ORIGIN_ZX_PLANE)!==m.INTERSECTING)return e}if(t.geometryType!==_.NONE)switch(t.geometryType){case _.POLYLINES:ee(e);break;case _.TRIANGLES:Q(e);break;case _.LINES:J(e)}else V(t),t.primitiveType===S.TRIANGLES?Q(e):t.primitiveType===S.LINES&&J(e);return e},te}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude) -;var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},s.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},s}),define("Scene/PrimitivePipeline",["../Core/BoundingSphere","../Core/ComponentDatatype","../Core/defined","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/GeographicProjection","../Core/Geometry","../Core/GeometryAttribute","../Core/GeometryAttributes","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Matrix4","../Core/WebMercatorProjection"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h){"use strict";function d(e,t,n){var a,i=!n,o=e.length;if(!i&&o>1){var u=e[0].modelMatrix;for(a=1;a<o;++a)if(!f.equals(u,e[a].modelMatrix)){i=!0;break}}if(i)for(a=0;a<o;++a)r(e[a].geometry)&&l.transformToWorldCoordinates(e[a]);else f.multiplyTransformation(t,e[0].modelMatrix,t)}function _(e,r){var n=e.attributes,a=n.position,i=a.values.length/a.componentsPerAttribute;n.batchId=new s({componentDatatype:t.FLOAT,componentsPerAttribute:1,values:new Float32Array(i)});for(var o=n.batchId.values,u=0;u<i;++u)o[u]=r}function p(e){for(var t=e.length,n=0;n<t;++n){var a=e[n];r(a.geometry)?_(a.geometry,n):r(a.westHemisphereGeometry)&&r(a.eastHemisphereGeometry)&&(_(a.westHemisphereGeometry,n),_(a.eastHemisphereGeometry,n))}}function m(n){var a,i,o=n.instances,u=n.projection,s=n.elementIndexUintSupported,c=n.scene3DOnly,E=n.vertexCacheOptimize,f=n.compressVertices,h=n.modelMatrix,_=o.length;for(a=0;a<_;++a)if(r(o[a].geometry)){o[a].geometry.primitiveType;break}if(d(o,h,c),!c)for(a=0;a<_;++a)r(o[a].geometry)&&l.splitLongitude(o[a]);if(p(o),E)for(a=0;a<_;++a){var m=o[a];r(m.geometry)?(l.reorderForPostVertexCache(m.geometry),l.reorderForPreVertexCache(m.geometry)):r(m.westHemisphereGeometry)&&r(m.eastHemisphereGeometry)&&(l.reorderForPostVertexCache(m.westHemisphereGeometry),l.reorderForPreVertexCache(m.westHemisphereGeometry),l.reorderForPostVertexCache(m.eastHemisphereGeometry),l.reorderForPreVertexCache(m.eastHemisphereGeometry))}var T=l.combineInstances(o);for(_=T.length,a=0;a<_;++a){i=T[a];var y,R=i.attributes;if(c)for(y in R)R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE&&l.encodeAttribute(i,y,y+"3DHigh",y+"3DLow");else for(y in R)if(R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE){var A=y+"3D",v=y+"2D";l.projectTo2D(i,y,A,v,u),r(i.boundingSphere)&&"position"===y&&(i.boundingSphereCV=e.fromVertices(i.attributes.position2D.values)),l.encodeAttribute(i,A,A+"High",A+"Low"),l.encodeAttribute(i,v,v+"High",v+"Low")}f&&l.compressVertices(i)}if(!s){var S=[];for(_=T.length,a=0;a<_;++a)i=T[a],S=S.concat(l.fitToUnsignedShortIndices(i));T=S}return T}function T(e,t,n,a){var i,o,u,s=a.length-1;if(s>=0){var c=a[s];i=c.offset+c.count,u=c.index,o=n[u].indices.length}else i=0,u=0,o=n[u].indices.length;for(var l=e.length,E=0;E<l;++E){var f=e[E],h=f[t];if(r(h)){var d=h.indices.length;i+d>o&&(i=0,o=n[++u].indices.length),a.push({index:u,offset:i,count:d}),i+=d}}}function y(e,t){var r=[];return T(e,"geometry",t,r),T(e,"westHemisphereGeometry",t,r),T(e,"eastHemisphereGeometry",t,r),r}function R(e,t){var n=e.attributes;for(var a in n)if(n.hasOwnProperty(a)){var i=n[a];r(i)&&r(i.values)&&t.push(i.values.buffer)}r(e.indices)&&t.push(e.indices.buffer)}function A(e,t){for(var r=e.length,n=0;n<r;++n)R(e[n],t)}function v(t){for(var n=1,a=t.length,i=0;i<a;i++){var o=t[i];if(++n,r(o)){var u=o.attributes;n+=6+2*e.packedLength+(r(o.indices)?o.indices.length:0);for(var s in u)if(u.hasOwnProperty(s)&&r(u[s])){var c=u[s];n+=5+c.values.length}}}return n}function S(e,t){var r=e.length,n=new Float64Array(1+16*r),a=0;n[a++]=r;for(var i=0;i<r;i++){var o=e[i];f.pack(o.modelMatrix,n,a),a+=f.packedLength}return t.push(n.buffer),n}function N(e){for(var t=e,r=new Array(t[0]),n=0,a=1;a<t.length;){var i=f.unpack(t,a);a+=f.packedLength,r[n++]={modelMatrix:i}}return r}function I(t){var n=t.length,a=1+(e.packedLength+1)*n,i=new Float32Array(a),o=0;i[o++]=n;for(var u=0;u<n;++u){var s=t[u];r(s)?(i[o++]=1,e.pack(t[u],i,o)):i[o++]=0,o+=e.packedLength}return i}function M(t){for(var r=new Array(t[0]),n=0,a=1;a<t.length;)1===t[a++]&&(r[n]=e.unpack(t,a)),++n,a+=e.packedLength;return r}if(!i.supportsTypedArrays())return{};var O={};return O.combineGeometry=function(t){var n,a,i,o=t.instances,u=o.length;u>0&&(n=m(t),n.length>0&&(a=l.createAttributeLocations(n[0]),t.createPickOffsets&&(i=y(o,n))));for(var s=new Array(u),c=new Array(u),E=0;E<u;++E){var f=o[E],h=f.geometry;r(h)&&(s[E]=h.boundingSphere,c[E]=h.boundingSphereCV);var d=f.eastHemisphereGeometry,_=f.westHemisphereGeometry;r(d)&&r(_)&&(r(d.boundingSphere)&&r(_.boundingSphere)&&(s[E]=e.union(d.boundingSphere,_.boundingSphere)),r(d.boundingSphereCV)&&r(_.boundingSphereCV)&&(c[E]=e.union(d.boundingSphereCV,_.boundingSphereCV)))}return{geometries:n,modelMatrix:t.modelMatrix,attributeLocations:a,pickOffsets:i,boundingSpheres:s,boundingSpheresCV:c}},O.packCreateGeometryResults=function(t,n){var a=new Float64Array(v(t)),i=[],o={},u=t.length,s=0;a[s++]=u;for(var c=0;c<u;c++){var l=t[c],E=r(l);if(a[s++]=E?1:0,E){a[s++]=l.primitiveType,a[s++]=l.geometryType;var f=r(l.boundingSphere)?1:0;a[s++]=f,f&&e.pack(l.boundingSphere,a,s),s+=e.packedLength;var h=r(l.boundingSphereCV)?1:0;a[s++]=h,h&&e.pack(l.boundingSphereCV,a,s),s+=e.packedLength;var d=l.attributes,_=[];for(var p in d)d.hasOwnProperty(p)&&r(d[p])&&(_.push(p),r(o[p])||(o[p]=i.length,i.push(p)));a[s++]=_.length;for(var m=0;m<_.length;m++){var T=_[m],y=d[T];a[s++]=o[T],a[s++]=y.componentDatatype,a[s++]=y.componentsPerAttribute,a[s++]=y.normalize?1:0,a[s++]=y.values.length,a.set(y.values,s),s+=y.values.length}var R=r(l.indices)?l.indices.length:0;a[s++]=R,R>0&&(a.set(l.indices,s),s+=R)}}return n.push(a.buffer),{stringTable:i,packedData:a}},O.unpackCreateGeometryResults=function(r){for(var n,a=r.stringTable,i=r.packedData,o=new Array(i[0]),l=0,f=1;f<i.length;){if(1===i[f++]){var h,d,_=i[f++],p=i[f++];1===i[f++]&&(h=e.unpack(i,f)),f+=e.packedLength;1===i[f++]&&(d=e.unpack(i,f)),f+=e.packedLength;var m,T,y,R=new c,A=i[f++];for(n=0;n<A;n++){var v=a[i[f++]],S=i[f++];y=i[f++];var N=0!==i[f++];m=i[f++],T=t.createTypedArray(S,m);for(var I=0;I<m;I++)T[I]=i[f++];R[v]=new s({componentDatatype:S,componentsPerAttribute:y,normalize:N,values:T})}var M;if((m=i[f++])>0){var O=T.length/y;for(M=E.createTypedArray(O,m),n=0;n<m;n++)M[n]=i[f++]}o[l++]=new u({primitiveType:_,geometryType:p,boundingSphere:h,boundingSphereCV:d,indices:M,attributes:R})}else o[l++]=void 0}return o},O.packCombineGeometryParameters=function(e,t){for(var r=e.createGeometryResults,n=r.length,a=0;a<n;a++)t.push(r[a].packedData.buffer);return{createGeometryResults:e.createGeometryResults,packedInstances:S(e.instances,t),ellipsoid:e.ellipsoid,isGeographic:e.projection instanceof o,elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e.createPickOffsets}},O.unpackCombineGeometryParameters=function(e){for(var t=N(e.packedInstances),r=e.createGeometryResults,n=r.length,i=0,u=0;u<n;u++)for(var s=O.unpackCreateGeometryResults(r[u]),c=s.length,l=0;l<c;l++){var E=s[l],d=t[i];d.geometry=E,++i}var _=a.clone(e.ellipsoid);return{instances:t,ellipsoid:_,projection:e.isGeographic?new o(_):new h(_),elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:f.clone(e.modelMatrix),createPickOffsets:e.createPickOffsets}},O.packCombineGeometryResults=function(e,t){r(e.geometries)&&A(e.geometries,t);var n=I(e.boundingSpheres),a=I(e.boundingSpheresCV);return t.push(n.buffer,a.buffer),{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:n,boundingSpheresCV:a}},O.unpackCombineGeometryResults=function(e){return{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:M(e.boundingSpheres),boundingSpheresCV:M(e.boundingSpheresCV)}},O}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var r,n=t.name,a=t.message;r=e(n)&&e(a)?n+": "+a:t.toString();var i=t.stack;return e(i)&&(r+="\n"+i),r}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,r){"use strict";function n(n){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=n(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+r(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return n}),define("Workers/combineGeometry",["../Scene/PrimitivePipeline","./createTaskProcessorWorker"],function(e,t){"use strict";function r(t,r){var n=e.unpackCombineGeometryParameters(t),a=e.combineGeometry(n);return e.packCombineGeometryResults(a,r)}return t(r)})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,i){if(a.typeOf.number(e,n),a.typeOf.number(r,i),n!==i)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var i=Math.abs(e-r);return i<=a||i<=n*Math.max(Math.abs(e),Math.abs(r))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var r=i[t-1],n=t;n<=e;n++)i.push(r*n);return i[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(i),n},o.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var E=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)},o.cross=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-n*s,E=n*u-a*o;return r.x=c,r.y=l,r.z=E,r},o.fromDegrees=function(e,t,r,n,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,r,n,a)};var f=new o,h=new o,d=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,a,i,u){a=t(a,0);var s=r(i)?i.radiiSquared:d,c=Math.cos(n);f.x=c*Math.cos(e),f.y=c*Math.sin(e),f.z=Math.sin(n),f=o.normalize(f,f),o.multiplyComponents(s,f,h);var l=Math.sqrt(o.dot(f,h));return h=o.divideByScalar(h,l,h),f=o.multiplyByScalar(f,a,f),r(u)||(u=new o),o.add(h,f,u)},o.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,c){var l=r.x,E=r.y,f=r.z,h=a.x,d=a.y,p=a.z,_=l*l*h*h,m=E*E*d*d,T=f*f*p*p,y=_+m+T,R=Math.sqrt(1/y),A=e.multiplyByScalar(r,R,i);if(y<s)return isFinite(R)?e.clone(A,c):void 0;var v=u.x,S=u.y,N=u.z,I=o;I.x=A.x*v*2,I.y=A.y*S*2,I.z=A.z*N*2;var M,O,g,C,w,P,x,L,U,b,F,D=(1-R)*e.magnitude(r)/(.5*e.magnitude(I)),B=0;do{D-=B,g=1/(1+D*v),C=1/(1+D*S),w=1/(1+D*N),P=g*g,x=C*C,L=w*w,U=P*g,b=x*C,F=L*w,M=_*P+m*x+T*L-1,O=_*U*v+m*b*S+T*F*N;B=M/(-2*O)}while(Math.abs(M)>n.EPSILON12);return t(c)?(c.x=l*g,c.y=E*C,c.z=f*w,c):new e(l*g,E*C,f*w)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,i){return a=r(a,0),n(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,E=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,r,a){var d=n(r)?r.oneOverRadii:E,p=n(r)?r.oneOverRadiiSquared:f,_=n(r)?r._centerToleranceSquared:h,m=o(t,d,p,_,c);if(n(m)){var T=e.multiplyComponents(m,p,s);T=e.normalize(T,T);var y=e.subtract(t,m,l),R=Math.atan2(T.y,T.x),A=Math.asin(T.z),v=i.sign(e.dot(y,t))*e.magnitude(y);return n(a)?(a.longitude=R,a.latitude=A,a.height=v,a):new u(R,A,v)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t,r,a,i){r=n(r,0),a=n(a,0),i=n(i,0),t._radii=new e(r,a,i),t._radiiSquared=new e(r*r,a*a,i*i),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(r,a,i),t._maximumRadius=Math.max(r,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function E(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}i(E.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),E.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new E(n.x,n.y,n.z)}},E.fromCartesian3=function(e,t){return a(t)||(t=new E),a(e)?(l(t,e.x,e.y,e.z),t):t},E.WGS84=u(new E(6378137,6378137,6356752.314245179)),E.UNIT_SPHERE=u(new E(1,1,1)),E.MOON=u(new E(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),E.prototype.clone=function(e){return E.clone(this,e)},E.packedLength=e.packedLength,E.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},E.unpack=function(t,r,a){r=n(r,0);var i=e.unpack(t,r);return E.fromCartesian3(i,a)},E.prototype.geocentricSurfaceNormal=e.normalize,E.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(i);return a(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},E.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var f=new e,h=new e;E.prototype.cartographicToCartesian=function(t,r){var n=f,i=h;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,i);var o=Math.sqrt(e.dot(n,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(i,n,r)},E.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var d=new e,p=new e,_=new e;return E.prototype.cartesianToCartographic=function(r,n){var i=this.scaleToGeodeticSurface(r,p);if(a(i)){var o=this.geodeticSurfaceNormal(i,d),u=e.subtract(r,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),E=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=c,n.latitude=l,n.height=E,n):new t(c,l,E)}},E.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},E.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},E.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},E.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},E.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},E.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},E.prototype.toString=function(){return this._radii.toString()},E.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,i){r=n(r,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-r))return i},E}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,i,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a,i,o,u,s,c){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(i,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(p[r],d[r])];t+=2*n*n}return Math.sqrt(t)}function E(e,t){for(var r=u.EPSILON15,n=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(p[i],d[i])]);o>n&&(a=i,n=o)}var c=1,l=0,E=d[a],f=p[a];if(Math.abs(e[s.getElementIndex(f,E)])>r){var h,_=e[s.getElementIndex(f,f)],m=e[s.getElementIndex(E,E)],T=e[s.getElementIndex(f,E)],y=(_-m)/2/T;h=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(E,E)]=t[s.getElementIndex(f,f)]=c,t[s.getElementIndex(f,E)]=l,t[s.getElementIndex(E,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,E=e.z*e.z,f=e.z*e.w,h=e.w*e.w,d=r-u-E+h,p=2*(a-f),_=2*(i+l),m=2*(a+f),T=-r+u-E+h,y=2*(c-o),R=2*(i-l),A=2*(c+o),v=-r-u+E+h;return n(t)?(t[0]=d,t[1]=m,t[2]=R,t[3]=p,t[4]=T,t[5]=A,t[6]=_,t[7]=y,t[8]=v,t):new s(d,p,_,m,T,y,R,A,v)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*a,E=-i*u+c*o*a,f=c*u+i*o*a,h=r*u,d=i*a+c*o*u,p=-c*a+i*o*u,_=-o,m=c*r,T=i*r;return n(t)?(t[0]=l,t[1]=h,t[2]=_,t[3]=E,t[4]=d,t[5]=m,t[6]=f,t[7]=p,t[8]=T,t):new s(l,E,f,h,d,p,_,m,T)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],i=e[n+1],o=e[n+2];return r.x=a,r.y=i,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],i=e[t+6];return r.x=n,r.y=a,r.z=i,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var f=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),r};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],E=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=i,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=E,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[3]*a+e[6]*i,u=e[1]*n+e[4]*a+e[7]*i,s=e[2]*n+e[5]*a+e[8]*i;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var d=[1,0,0],p=[2,2,1],_=new s,m=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,i=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),h=r*c(f);i<10&&l(f)>h;)E(f,_),s.transpose(_,m),s.multiply(f,_,f),s.multiply(m,f,f),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*n-r*c)+u*(r*o-i*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],E=e[8],f=s.determinant(e);t[0]=o*E-l*u,t[1]=l*a-n*E,t[2]=n*u-o*a,t[3]=c*u-i*E,t[4]=r*E-c*a,t[5]=i*a-r*u,t[6]=i*l-c*o,t[7]=c*n-r*l,t[8]=r*o-i*n;var h=1/f;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}o.fromElements=function(e,t,n,a,i){return r(i)?(i.x=e,i.y=t,i.z=n,i.w=a,i):new o(e,t,n,a)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)&&i.equalsEpsilon(e.w,t.w,n,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t,r,a,i,o,u,s,c,l,E,f,h,d,p,_){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(c,0),this[3]=n(h,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(d,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(E,0),this[11]=n(p,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(_,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,i){return r=n(r,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=r.x,i[13]=r.y,i[14]=r.z,i[15]=1,i):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var i=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,E=t.x*t.z,f=t.x*t.w,h=t.y*t.y,d=t.y*t.z,p=t.y*t.w,_=t.z*t.z,m=t.z*t.w,T=t.w*t.w,y=s-h-_+T,R=2*(c-m),A=2*(E+p),v=2*(c+m),S=-s+h-_+T,N=2*(d-f),I=2*(E-p),M=2*(d+f),O=-s-h+_+T;return n[0]=y*i,n[1]=v*i,n[2]=I*i,n[3]=0,n[4]=R*o,n[5]=S*o,n[6]=M*o,n[7]=0,n[8]=A*u,n[9]=N*u,n[10]=O*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var E=new e,f=new e,h=new e;l.fromCamera=function(t,r){var n=t.position,i=t.direction,o=t.up;e.normalize(i,E),e.normalize(e.cross(E,o,f),f),e.normalize(e.cross(f,E,h),h);var u=f.x,s=f.y,c=f.z,d=E.x,p=E.y,_=E.z,m=h.x,T=h.y,y=h.z,R=n.x,A=n.y,v=n.z,S=u*-R+s*-A+c*-v,N=m*-R+T*-A+y*-v,I=d*R+p*A+_*v;return a(r)?(r[0]=u,r[1]=m,r[2]=-d,r[3]=0,r[4]=s,r[5]=T,r[6]=-p,r[7]=0,r[8]=c,r[9]=y,r[10]=-_,r[11]=0,r[12]=S,r[13]=N,r[14]=I,r[15]=1,r):new l(u,s,c,S,m,T,y,N,-d,-p,-_,I,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,i,o){var u=1/(t-e),s=1/(n-r),c=1/(i-a),l=-(t+e)*u,E=-(n+r)*s,f=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=E,o[14]=f,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,a,i,o){var u=2*a/(t-e),s=2*a/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),E=-(i+a)/(i-a),f=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=E,o[11]=-1,o[12]=0,o[13]=0,o[14]=f,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,i){var o=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var i=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,E=.5*(r-t),f=c,h=l,d=E,p=i+c,_=o+l,m=t+E;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=d,a[11]=0,a[12]=p,a[13]=_,a[14]=m,a[15]=1,a},l.computeView=function(t,r,n,a,i){return i[0]=a.x,i[1]=n.x,i[2]=-r.x,i[3]=0,i[4]=a.y,i[5]=n.y,i[6]=-r.y,i[7]=0,i[8]=a.z,i[9]=n.z,i[10]=-r.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(n,t),i[14]=e.dot(r,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],i=e[n+1],o=e[n+2],u=e[n+3];return r.x=a,r.y=i,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return r.x=n,r.y=a,r.z=i,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var d=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],d)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],d)),r};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],E=e[8],f=e[9],h=e[10],d=e[11],p=e[12],_=e[13],m=e[14],T=e[15],y=t[0],R=t[1],A=t[2],v=t[3],S=t[4],N=t[5],I=t[6],M=t[7],O=t[8],g=t[9],C=t[10],w=t[11],P=t[12],x=t[13],L=t[14],U=t[15],b=n*y+u*R+E*A+p*v,F=a*y+s*R+f*A+_*v,D=i*y+c*R+h*A+m*v,B=o*y+l*R+d*A+T*v,z=n*S+u*N+E*I+p*M,G=a*S+s*N+f*I+_*M,V=i*S+c*N+h*I+m*M,q=o*S+l*N+d*I+T*M,X=n*O+u*g+E*C+p*w,H=a*O+s*g+f*C+_*w,W=i*O+c*g+h*C+m*w,k=o*O+l*g+d*C+T*w,Y=n*P+u*x+E*L+p*U,Z=a*P+s*x+f*L+_*U,K=i*P+c*x+h*L+m*U,j=o*P+l*x+d*L+T*U;return r[0]=b,r[1]=F,r[2]=D,r[3]=B,r[4]=z,r[5]=G,r[6]=V,r[7]=q,r[8]=X,r[9]=H,r[10]=W,r[11]=k,r[12]=Y,r[13]=Z,r[14]=K,r[15]=j,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=e[12],h=e[13],d=e[14],p=t[0],_=t[1],m=t[2],T=t[4],y=t[5],R=t[6],A=t[8],v=t[9],S=t[10],N=t[12],I=t[13],M=t[14],O=n*p+o*_+c*m,g=a*p+u*_+l*m,C=i*p+s*_+E*m,w=n*T+o*y+c*R,P=a*T+u*y+l*R,x=i*T+s*y+E*R,L=n*A+o*v+c*S,U=a*A+u*v+l*S,b=i*A+s*v+E*S,F=n*N+o*I+c*M+f,D=a*N+u*I+l*M+h,B=i*N+s*I+E*M+d;return r[0]=O,r[1]=g,r[2]=C,r[3]=0,r[4]=w,r[5]=P,r[6]=x,r[7]=0,r[8]=L,r[9]=U,r[10]=b,r[11]=0,r[12]=F,r[13]=D,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=t[0],h=t[1],d=t[2],p=t[3],_=t[4],m=t[5],T=t[6],y=t[7],R=t[8],A=n*f+o*h+c*d,v=a*f+u*h+l*d,S=i*f+s*h+E*d,N=n*p+o*_+c*m,I=a*p+u*_+l*m,M=i*p+s*_+E*m,O=n*T+o*y+c*R,g=a*T+u*y+l*R,C=i*T+s*y+E*R;return r[0]=A,r[1]=v,r[2]=S,r[3]=0,r[4]=N,r[5]=I,r[6]=M,r[7]=0,r[8]=O,r[9]=g,r[10]=C,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=n*e[0]+a*e[4]+i*e[8]+e[12],u=n*e[1]+a*e[5]+i*e[9]+e[13],s=n*e[2]+a*e[6]+i*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var _=new e;l.multiplyByUniformScale=function(e,t,r){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,i=t.z;return 1===n&&1===a&&1===i?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=i*e[8],r[9]=i*e[9],r[10]=i*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*n+e[4]*a+e[8]*i+e[12]*o,s=e[1]*n+e[5]*a+e[9]*i+e[13]*o,c=e[2]*n+e[6]*a+e[10]*i+e[14]*o,l=e[3]*n+e[7]*a+e[11]*i+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i,u=e[1]*n+e[5]*a+e[9]*i,s=e[2]*n+e[6]*a+e[10]*i;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i+e[12],u=e[1]*n+e[5]*a+e[9]*i+e[13],s=e[2]*n+e[6]*a+e[10]*i+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var m=new s,T=new s,y=new t,R=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,m),T,u.EPSILON7)&&t.equals(l.getRow(e,3,y),R))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],i=e[8],o=e[12],E=e[1],f=e[5],h=e[9],d=e[13],p=e[2],_=e[6],A=e[10],v=e[14],S=e[3],N=e[7],I=e[11],M=e[15],O=A*M,g=v*I,C=_*M,w=v*N,P=_*I,x=A*N,L=p*M,U=v*S,b=p*I,F=A*S,D=p*N,B=_*S,z=O*f+w*h+P*d-(g*f+C*h+x*d),G=g*E+L*h+F*d-(O*E+U*h+b*d),V=C*E+U*f+D*d-(w*E+L*f+B*d),q=x*E+b*f+B*h-(P*E+F*f+D*h),X=g*a+C*i+x*o-(O*a+w*i+P*o),H=O*n+U*i+b*o-(g*n+L*i+F*o),W=w*n+L*a+B*o-(C*n+U*a+D*o),k=P*n+F*a+D*i-(x*n+b*a+B*i);O=i*d,g=o*h,C=a*d,w=o*f,P=a*h,x=i*f,L=n*d,U=o*E,b=n*h,F=i*E,D=n*f,B=a*E;var Y=O*N+w*I+P*M-(g*N+C*I+x*M),Z=g*S+L*I+F*M-(O*S+U*I+b*M),K=C*S+U*N+D*M-(w*S+L*N+B*M),j=x*S+b*N+B*I-(P*S+F*N+D*I),Q=C*A+x*v+g*_-(P*v+O*_+w*A),J=b*v+O*p+U*A-(L*A+F*v+g*p),$=L*_+B*v+w*p-(D*v+C*p+U*_),ee=D*A+P*p+F*_-(b*_+B*A+x*p),te=n*z+a*G+i*V+o*q;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=G*te,r[2]=V*te,r[3]=q*te,r[4]=X*te,r[5]=H*te,r[6]=W*te,r[7]=k*te,r[8]=Y*te,r[9]=Z*te,r[10]=K*te,r[11]=j*te,r[12]=Q*te,r[13]=J*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],E=e[12],f=e[13],h=e[14],d=-r*E-n*f-a*h,p=-i*E-o*f-u*h,_=-s*E-c*f-l*h;return t[0]=r,t[1]=i,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=d,t[13]=p,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),i=u.toRadians(r(i,0)),n(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(a,0),o.north=r(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,E=0,f=e.length;E<f;E++){var h=e[E];r=Math.min(r,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,d),o=Math.max(o,d)}return a-r>o-i&&(r=i,a=o,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=a,t.north=l,t):new s(r,c,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,E=-Number.MAX_VALUE,f=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0,p=e.length;d<p;d++){var _=t.cartesianToCartographic(e[d]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),f=Math.min(f,_.latitude),h=Math.max(h,_.latitude);var m=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,m),E=Math.max(E,m)}return c-o>E-l&&(o=l,c=E,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(a)?(a.west=o,a.south=f,a.east=c,a.north=h,a):new s(o,f,c,h)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),E=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&E<=l)){var f=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(f>=h))return n(r)?(r.west=l,r.south=f,r.east=E,r.north=h,r):new s(l,f,E,h)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return n(r)?(r.west=a,r.south=i,r.east=o,r.north=u,r):new s(a,i,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),E=u.convertLongitudeRange(Math.max(a,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=E,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<i||u.equalsEpsilon(r,i,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=r(t,i.WGS84),a=r(a,0),n(o)||(o=[]);var l=0,E=e.north,f=e.south,h=e.east,d=e.west,p=c;p.height=a,p.longitude=d,p.latitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=f,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=E<0?E:f>0?f:0;for(var _=1;_<8;++_)p.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,p)&&(o[l]=t.cartographicToCartesian(p,o[l]),l++);return 0===p.latitude&&(p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,i,o,u,s,c,l,E,f){"use strict";function h(t,r){this.center=e.clone(a(t,e.ZERO)),this.radius=a(r,0)}var d=new e,p=new e,_=new e,m=new e,T=new e,y=new e,R=new e,A=new e,v=new e,S=new e,N=new e,I=new e,M=4/3*r.PI;h.fromPoints=function(t,r){if(i(r)||(r=new h),!i(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,a=e.clone(t[0],R),o=e.clone(a,d),u=e.clone(a,p),s=e.clone(a,_),c=e.clone(a,m),l=e.clone(a,T),E=e.clone(a,y),f=t.length;for(n=1;n<f;n++){e.clone(t[n],a);var M=a.x,O=a.y,g=a.z;M<o.x&&e.clone(a,o),M>c.x&&e.clone(a,c),O<u.y&&e.clone(a,u),O>l.y&&e.clone(a,l),g<s.z&&e.clone(a,s),g>E.z&&e.clone(a,E)}var C=e.magnitudeSquared(e.subtract(c,o,A)),w=e.magnitudeSquared(e.subtract(l,u,A)),P=e.magnitudeSquared(e.subtract(E,s,A)),x=o,L=c,U=C;w>U&&(U=w,x=u,L=l),P>U&&(U=P,x=s,L=E);var b=v;b.x=.5*(x.x+L.x),b.y=.5*(x.y+L.y),b.z=.5*(x.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,A)),D=Math.sqrt(F),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=E.z;var G=e.multiplyByScalar(e.add(B,z,A),.5,I),V=0;for(n=0;n<f;n++){e.clone(t[n],a);var q=e.magnitude(e.subtract(a,G,A));q>V&&(V=q);var X=e.magnitudeSquared(e.subtract(a,b,A));if(X>F){var H=Math.sqrt(X);D=.5*(D+H),F=D*D;var W=H-D;b.x=(D*b.x+W*a.x)/H,b.y=(D*b.y+W*a.y)/H,b.z=(D*b.z+W*a.z)/H}}return D<V?(e.clone(b,r.center),r.radius=D):(e.clone(G,r.center),r.radius=V),r};var O=new u,g=new e,C=new e,w=new t,P=new t;h.fromRectangle2D=function(e,t,r){return h.fromRectangleWithHeights2D(e,t,0,0,r)},h.fromRectangleWithHeights2D=function(t,r,n,o,u){if(i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=a(r,O),f.southwest(t,w),w.height=n,f.northeast(t,P),P.height=o;var s=r.project(w,g),c=r.project(P,C),l=c.x-s.x,E=c.y-s.y,d=c.z-s.z;u.radius=.5*Math.sqrt(l*l+E*E+d*d);var p=u.center;return p.x=s.x+.5*l,p.y=s.y+.5*E,p.z=s.z+.5*d,u};var x=[];h.fromRectangle3D=function(t,r,n,u){if(r=a(r,o.WGS84),n=a(n,0),i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,r,n,x);return h.fromPoints(s,u)},h.fromVertices=function(t,r,n,o){if(i(o)||(o=new h),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=a(r,e.ZERO),n=a(n,3);var u=R;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,d),l=e.clone(u,p),E=e.clone(u,_),f=e.clone(u,m),M=e.clone(u,T),O=e.clone(u,y),g=t.length;for(s=0;s<g;s+=n){var C=t[s]+r.x,w=t[s+1]+r.y,P=t[s+2]+r.z;u.x=C,u.y=w,u.z=P,C<c.x&&e.clone(u,c),C>f.x&&e.clone(u,f),w<l.y&&e.clone(u,l),w>M.y&&e.clone(u,M),P<E.z&&e.clone(u,E),P>O.z&&e.clone(u,O)}var x=e.magnitudeSquared(e.subtract(f,c,A)),L=e.magnitudeSquared(e.subtract(M,l,A)),U=e.magnitudeSquared(e.subtract(O,E,A)),b=c,F=f,D=x;L>D&&(D=L,b=l,F=M),U>D&&(D=U,b=E,F=O);var B=v;B.x=.5*(b.x+F.x),B.y=.5*(b.y+F.y),B.z=.5*(b.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,A)),G=Math.sqrt(z),V=S;V.x=c.x,V.y=l.y,V.z=E.z;var q=N;q.x=f.x,q.y=M.y,q.z=O.z;var X=e.multiplyByScalar(e.add(V,q,A),.5,I),H=0;for(s=0;s<g;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var W=e.magnitude(e.subtract(u,X,A));W>H&&(H=W);var k=e.magnitudeSquared(e.subtract(u,B,A));if(k>z){var Y=Math.sqrt(k);G=.5*(G+Y),z=G*G;var Z=Y-G;B.x=(G*B.x+Z*u.x)/Y,B.y=(G*B.y+Z*u.y)/Y,B.z=(G*B.z+Z*u.z)/Y}}return G<H?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=H),o},h.fromEncodedCartesianVertices=function(t,r,n){if(i(n)||(n=new h),!i(t)||!i(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var a=R;a.x=t[0]+r[0],a.y=t[1]+r[1],a.z=t[2]+r[2];var o,u=e.clone(a,d),s=e.clone(a,p),c=e.clone(a,_),l=e.clone(a,m),E=e.clone(a,T),f=e.clone(a,y),M=t.length;for(o=0;o<M;o+=3){var O=t[o]+r[o],g=t[o+1]+r[o+1],C=t[o+2]+r[o+2];a.x=O,a.y=g,a.z=C,O<u.x&&e.clone(a,u),O>l.x&&e.clone(a,l),g<s.y&&e.clone(a,s),g>E.y&&e.clone(a,E),C<c.z&&e.clone(a,c),C>f.z&&e.clone(a,f)}var w=e.magnitudeSquared(e.subtract(l,u,A)),P=e.magnitudeSquared(e.subtract(E,s,A)),x=e.magnitudeSquared(e.subtract(f,c,A)),L=u,U=l,b=w;P>b&&(b=P,L=s,U=E),x>b&&(b=x,L=c,U=f);var F=v;F.x=.5*(L.x+U.x),F.y=.5*(L.y+U.y),F.z=.5*(L.z+U.z);var D=e.magnitudeSquared(e.subtract(U,F,A)),B=Math.sqrt(D),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var G=N;G.x=l.x,G.y=E.y,G.z=f.z;var V=e.multiplyByScalar(e.add(z,G,A),.5,I),q=0;for(o=0;o<M;o+=3){a.x=t[o]+r[o],a.y=t[o+1]+r[o+1],a.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(a,V,A));X>q&&(q=X);var H=e.magnitudeSquared(e.subtract(a,F,A));if(H>D){var W=Math.sqrt(H);B=.5*(B+W),D=B*B;var k=W-B;F.x=(B*F.x+k*a.x)/W,F.y=(B*F.y+k*a.y)/W,F.z=(B*F.z+k*a.z)/W}}return B<q?(e.clone(F,n.center),n.radius=B):(e.clone(V,n.center),n.radius=q),n},h.fromCornerPoints=function(t,r,n){i(n)||(n=new h);var a=n.center;return e.add(t,r,a),e.multiplyByScalar(a,.5,a),n.radius=e.distance(a,r),n},h.fromEllipsoid=function(t,r){return i(r)||(r=new h),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var L=new e;h.fromBoundingSpheres=function(t,r){if(i(r)||(r=new h),!i(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return h.clone(t[0],r);if(2===n)return h.union(t[0],t[1],r);var a,o=[];for(a=0;a<n;a++)o.push(t[a].center);r=h.fromPoints(o,r);var u=r.center,s=r.radius;for(a=0;a<n;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,L)+c.radius)}return r.radius=s,r};var U=new e,b=new e,F=new e;h.fromOrientedBoundingBox=function(t,r){i(r)||(r=new h);var n=t.halfAxes,a=l.getColumn(n,0,U),o=l.getColumn(n,1,b),u=l.getColumn(n,2,F);return e.add(a,o,a),e.add(a,u,a),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(a),r},h.clone=function(t,r){if(i(t))return i(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,r){r=a(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},h.unpack=function(e,t,r){t=a(t,0),i(r)||(r=new h);var n=r.center;return n.x=e[t++],n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var D=new e,B=new e;h.union=function(t,r,n){i(n)||(n=new h);var a=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,a,D),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var E=.5*(o+l+s),f=e.multiplyByScalar(c,(-o+E)/l,B);return e.add(f,a,f),e.clone(f,n.center),n.radius=E,n};var z=new e;h.expand=function(t,r,n){n=h.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,z));return a>n.radius&&(n.radius=a),n},h.intersectPlane=function(t,r){var n=t.center,a=t.radius,i=r.normal,o=e.dot(i,n)+r.distance;return o<-a?s.OUTSIDE:o<a?s.INTERSECTING:s.INSIDE},h.transform=function(e,t,r){return i(r)||(r=new h),r.center=E.multiplyByPoint(t,e.center,r.center),r.radius=E.getMaximumScale(t)*e.radius,r};var G=new e;h.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,G);return e.magnitudeSquared(n)-t.radius*t.radius},h.transformWithoutScale=function(e,t,r){return i(r)||(r=new h),r.center=E.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var V=new e;h.computePlaneDistances=function(t,r,n,a){i(a)||(a=new c);var o=e.subtract(t.center,r,V),u=e.dot(n,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var q=new e,X=new e,H=new e,W=new e,k=new e,Y=new t,Z=new Array(8),K=0;K<8;++K)Z[K]=new e;var j=new u;return h.projectTo2D=function(t,r,n){r=a(r,j);var i=r.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,H);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var E=e.negate(l,k),f=e.negate(c,W),d=Z,p=d[0];e.add(s,l,p),e.add(p,c,p),p=d[1],e.add(s,l,p),e.add(p,f,p),p=d[2],e.add(s,E,p),e.add(p,f,p),p=d[3],e.add(s,E,p),e.add(p,c,p),e.negate(s,s),p=d[4],e.add(s,l,p),e.add(p,c,p),p=d[5],e.add(s,l,p),e.add(p,f,p),p=d[6],e.add(s,E,p),e.add(p,f,p),p=d[7],e.add(s,E,p),e.add(p,c,p);for(var _=d.length,m=0;m<_;++m){var T=d[m];e.add(o,T,T);var y=i.cartesianToCartographic(T,Y);r.project(y,T)}n=h.fromPoints(d,n),o=n.center;var R=o.x,A=o.y,v=o.z;return o.x=v,o.y=R,o.z=A,n},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,r){return t===r||i(t)&&i(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,r){return h.computePlaneDistances(this,e,t,r)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h.prototype.volume=function(){var e=this.radius;return M*e*e*e},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(A)&&(A=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,v=n(e[1]))}return A}function i(){return a()&&v}function o(){if(!t(S)&&(S=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=n(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(I)){I=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(I=!0, +M=n(e[1]),M.isNightly=!!e[2])}return I}function c(){return s()&&M}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,g=n(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,g=n(e[1]))}return O}function E(){return l()&&g}function f(){if(!t(C)){C=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,w=n(e[1]))}return C}function h(){return f()&&w}function d(){if(!t(P)){P=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(P=!0,x=n(e[1]))}return P}function p(){return t(L)||(L=/Windows/i.test(R.appVersion)),L}function _(){return d()&&x}function m(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),U}function T(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;F=t(r)&&""!==r,F&&(b=r)}return F}function y(){return T()?b:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,v,S,N,I,M,O,g,C,w,P,x,L,U,b,F,D={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:E,isEdge:f,edgeVersion:h,isFirefox:d,firefoxVersion:_,isWindows:p,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:m,supportsImageRenderingPixelated:T,imageRenderingValue:y};return D.supportsFullscreen=function(){return r.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,i){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,a);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case o.SHORT:return new Int16Array(r,n,a);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case o.INT:return new Int32Array(r,n,a);case o.UNSIGNED_INT:return new Uint32Array(r,n,a);case o.FLOAT:return new Float32Array(r,n,a);case o.DOUBLE:return new Float64Array(r,n,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var a=0;a<n;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var a=0;a<n;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var E=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,a,i){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,a=r.y;r.x=(1-Math.abs(a))*i.signNotZero(n),r.y=(1-Math.abs(n))*i.signNotZero(a)}return r.x=i.toSNorm(r.x,t),r.y=i.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,a){if(a.x=i.fromSNorm(e,n),a.y=i.fromSNorm(r,n),a.z=1-(Math.abs(a.x)+Math.abs(a.y)),a.z<0){var o=a.x;a.x=(1-Math.abs(a.y))*i.signNotZero(o),a.y=(1-Math.abs(o))*i.signNotZero(a.y)}return t.normalize(a,a)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),a=256*(r-n);return u.octDecode(n,a,t)},u.octPack=function(e,t,r,n){var a=u.octEncodeFloat(e),i=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+a,n.y=65536*o.y+i,n},u.octUnpack=function(e,t,r,n){var a=e.x/65536,i=Math.floor(a),o=65536*(a-i);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(i,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var a=e.length,i=0,u=0,s=0,c=0;c<a;++c)i+=o(e[c]),u+=o(t[c]),e[c]=i,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function a(r,a,s,c,l){n(l)||(l=new t);var E,f,h,d,p,_,m,T;n(a.z)?(E=t.subtract(s,a,i),f=t.subtract(c,a,o),h=t.subtract(r,a,u),d=t.dot(E,E),p=t.dot(E,f),_=t.dot(E,h),m=t.dot(f,f),T=t.dot(f,h)):(E=e.subtract(s,a,i),f=e.subtract(c,a,o),h=e.subtract(r,a,u),d=e.dot(E,E),p=e.dot(E,f),_=e.dot(E,h),m=e.dot(f,f),T=e.dot(f,h));var y=1/(d*m-p*p);return l.y=(m*_-p*T)*y,l.z=(d*T-p*_)*y,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var a={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var i=t.high,o=t.low;return n.encode(e.x,a),i.x=a.high,o.x=a.low,n.encode(e.y,a),i.y=a.high,o.y=a.low,n.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,i);var a=i.high,o=i.low;t[r]=a.x,t[r+1]=a.y,t[r+2]=a.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var i;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-n/e,i<0?[i,0]:[0,i];var c=n*n,l=4*e*a,E=r(c,-l,t.EPSILON14);if(E<0)return[];var f=-.5*r(n,t.sign(n)*Math.sqrt(E),t.EPSILON14);return n>0?[f/e,a/f]:[a/f,f/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,i,o=e,u=t/3,s=r/3,c=n,l=o*s,E=u*c,f=u*u,h=s*s,d=o*s-f,p=o*c-u*s,_=u*c-h,m=4*d*_-p*p;if(m<0){var T,y,R;f*E>=l*h?(T=o,y=d,R=-2*u*d+o*p):(T=c,y=_,R=-c*p+2*s*_);var A=R<0?-1:1,v=-A*Math.abs(T)*Math.sqrt(-m);i=-R+v;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),I=i===v?-N:-y/N;return a=y<=0?N+I:-R/(N*N+I*I+y),f*E>=l*h?[(a-u)/o]:[-c/(a+s)]}var M=d,O=-2*u*d+o*p,g=_,C=-c*p+2*s*_,w=Math.sqrt(m),P=Math.sqrt(3)/2,x=Math.abs(Math.atan2(o*w,-O)/3);a=2*Math.sqrt(-M);var L=Math.cos(x);i=a*L;var U=a*(-L/2-P*Math.sin(x)),b=i+U>2*u?i-u:U-u,F=o,D=b/F;x=Math.abs(Math.atan2(c*w,-C)/3),a=2*Math.sqrt(-g),L=Math.cos(x),i=a*L,U=a*(-L/2-P*Math.sin(x));var B=-c,z=i+U<2*s?i+s:U+s,G=B/z,V=F*z,q=-b*z-F*B,X=b*B,H=(s*q-u*X)/(-u*q+s*V);return D<=H?D<=G?H<=G?[D,H,G]:[D,G,H]:[G,D,H]:D<=G?[H,D,G]:H<=G?[H,G,D]:[G,H,D]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,i=t*t,o=r*r;return 18*e*t*r*n+i*o-27*a*(n*n)-4*(e*o*r+i*t*n)},n.computeRealRoots=function(e,n,a,i){var o,u;if(0===e)return t.computeRealRoots(n,a,i);if(0===n){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,a,i)}return 0===a?0===i?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,i):0===i?(o=t.computeRealRoots(e,n,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,a,i)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,E=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(E.length>0){var f=-t/4,h=E[E.length-1];if(Math.abs(h)<r.EPSILON14){var d=n.computeRealRoots(1,s,l);if(2===d.length){var p,_=d[0],m=d[1];if(_>=0&&m>=0){var T=Math.sqrt(_),y=Math.sqrt(m);return[f-y,f-T,f+T,f+y]}if(_>=0&&m<0)return p=Math.sqrt(_),[f-p,f+p];if(_<0&&m>=0)return p=Math.sqrt(m),[f-p,f+p]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,v=(s+h+c/R)/2,S=n.computeRealRoots(1,R,A),N=n.computeRealRoots(1,-R,v);return 0!==S.length?(S[0]+=f,S[1]+=f,0!==N.length?(N[0]+=f,N[1]+=f,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=f,N[1]+=f,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,E=i*t+s-4*o,f=c*o-i*a*t+u,h=e.computeRealRoots(1,l,E,f);if(h.length>0){var d,p,_=h[0],m=a-_,T=m*m,y=t/2,R=m/2,A=T-4*o,v=T+4*Math.abs(o),S=c-4*_,N=c+4*Math.abs(_);if(_<0||A*N<S*v){var I=Math.sqrt(S);d=I/2,p=0===I?0:(t*R-i)/I}else{var M=Math.sqrt(A);d=0===M?0:(t*R-i)/M,p=M/2}var O,g;0===y&&0===d?(O=0,g=0):r.sign(y)===r.sign(d)?(O=y+d,g=_/O):(g=y-d,O=_/g);var C,w;0===R&&0===p?(C=0,w=0):r.sign(R)===r.sign(p)?(C=R+p,w=o/C):(w=R-p,C=o/w);var P=n.computeRealRoots(1,O,C),x=n.computeRealRoots(1,g,w);if(0!==P.length)return 0!==x.length?P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>x[0]&&P[0]<x[1]?[x[0],P[0],x[1],P[1]]:[P[0],x[0],P[1],x[1]]:P;if(0!==x.length)return x}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=r*r,l=c*r,E=n*n,f=E*n,h=a*a;return u*c*E-4*s*f-4*e*l*E+18*e*t*r*f-27*i*E*E+256*o*(h*a)+a*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*E+144*i*r*E)+h*(144*e*u*r-27*u*u-128*i*c-192*i*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,E=u/t,f=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=E<0?h+1:h,h+=f<0?h+1:h){case 0:return a(c,l,E,f);case 1:case 2:return i(c,l,E,f);case 3:case 4:return a(c,l,E,f);case 5:return i(c,l,E,f);case 6:case 7:return a(c,l,E,f);case 8:return i(c,l,E,f);case 9:case 10:return a(c,l,E,f);case 11:return i(c,l,E,f);case 12:case 13:case 14:case 15:return a(c,l,E,f);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,i,o,u,s,c,l){"use strict";function E(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function f(t,r,a){n(a)||(a=new i);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,T),f=e.dot(u,u),h=2*e.dot(u,l),d=e.magnitudeSquared(l)-c,p=E(f,h,d,v);if(n(p))return a.start=p.root0, +a.stop=p.root1,a}function h(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function d(t,r,n,a,i){var l,E=a*a,f=i*i,d=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,p=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),_=t[u.COLUMN0ROW0]*E+t[u.COLUMN2ROW2]*f+a*r.x+n,m=f*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),T=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),y=[];if(0===T&&0===m){if(l=s.computeRealRoots(d,p,_),0===l.length)return y;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(y.push(new e(a,i*R,i*-A)),y.push(new e(a,i*R,i*A)),2===l.length){var v=l[1],S=Math.sqrt(Math.max(1-v*v,0));y.push(new e(a,i*v,i*-S)),y.push(new e(a,i*v,i*S))}return y}var N=T*T,I=m*m,M=d*d,O=T*m,g=M+I,C=2*(p*d+O),w=2*_*d+p*p-I+N,P=2*(_*p-O),x=_*_-N;if(0===g&&0===C&&0===w&&0===P)return y;l=c.computeRealRoots(g,C,w,P,x);var L=l.length;if(0===L)return y;for(var U=0;U<L;++U){var b,F=l[U],D=F*F,B=Math.max(1-D,0),z=Math.sqrt(B);b=o.sign(d)===o.sign(_)?h(d*D+_,p*F,o.EPSILON12):o.sign(_)===o.sign(p*F)?h(d*D,p*F+_,o.EPSILON12):h(d*D+p*F,_,o.EPSILON12);var G=h(m*F,T,o.EPSILON15),V=b*G;V<0?y.push(new e(a,i*F,i*z)):V>0?y.push(new e(a,i*F,i*-z)):0!==z?(y.push(new e(a,i*F,i*-z)),y.push(new e(a,i*F,i*z)),++U):y.push(new e(a,i*F,i*z))}return y}var p={};p.rayPlane=function(t,r,a){n(a)||(a=new e);var i=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,m=new e,T=new e,y=new e,R=new e;p.rayTriangleParametric=function(t,n,a,i,u){u=r(u,!1);var s,c,l,E,f,h=t.origin,d=t.direction,p=e.subtract(a,n,_),A=e.subtract(i,n,m),v=e.cross(d,A,T),S=e.dot(p,v);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,n,y),(l=e.dot(s,v))<0||l>S)return;if(c=e.cross(s,p,R),(E=e.dot(d,c))<0||l+E>S)return;f=e.dot(A,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,n,y),(l=e.dot(s,v)*N)<0||l>1)return;if(c=e.cross(s,p,R),(E=e.dot(d,c)*N)<0||l+E>1)return;f=e.dot(A,c)*N}return f},p.rayTriangle=function(t,r,a,i,o,u){var s=p.rayTriangleParametric(t,r,a,i,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;p.lineSegmentTriangle=function(t,r,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=p.rayTriangleParametric(c,a,i,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var v={root0:0,root1:0};p.raySphere=function(e,t,r){if(r=f(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;p.lineSegmentSphere=function(t,r,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=f(o,a,i),!(!n(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,I=new e;p.rayEllipsoid=function(t,r){var n,a,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),E=e.multiplyComponents(c,t.direction,I),f=e.magnitudeSquared(l),h=e.dot(l,E);if(f>1){if(h>=0)return;var d=h*h;if(n=f-1,a=e.magnitudeSquared(E),o=a*n,d<o)return;if(d>o){u=h*h-o,s=-h+Math.sqrt(u);var p=s/a,_=n/s;return p<_?new i(p,_):{start:_,stop:p}}var m=Math.sqrt(n/a);return new i(m,m)}return f<1?(n=f-1,a=e.magnitudeSquared(E),o=a*n,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(E),new i(0,-h/a)):void 0};var M=new e,O=new e,g=new e,C=new e,w=new e,P=new u,x=new u,L=new u,U=new u,b=new u,F=new u,D=new u,B=new e,z=new e,G=new t;p.grazingAltitudeLocation=function(t,r){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,M);if(e.dot(i,s)>=0)return a}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(i,M),E=e.normalize(l,l),f=e.mostOrthogonalAxis(l,C),h=e.normalize(e.cross(f,E,O),O),p=e.normalize(e.cross(E,h,g),g),_=P;_[0]=E.x,_[1]=E.y,_[2]=E.z,_[3]=h.x,_[4]=h.y,_[5]=h.z,_[6]=p.x,_[7]=p.y,_[8]=p.z;var m=u.transpose(_,x),T=u.fromScale(r.radii,L),y=u.fromScale(r.oneOverRadii,U),R=b;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,v,S=u.multiply(u.multiply(m,y,F),R,F),N=u.multiply(u.multiply(S,T,D),_,D),I=u.multiplyByVector(S,a,w),V=d(N,e.negate(I,M),0,0,1),q=V.length;if(q>0){for(var X=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,W=0;W<q;++W){A=u.multiplyByVector(T,u.multiplyByVector(_,V[W],B),B);var k=e.normalize(e.subtract(A,a,C),C),Y=e.dot(k,i);Y>H&&(H=Y,X=e.clone(A,X))}var Z=r.cartesianToCartographic(X,G);return H=o.clamp(H,0,1),v=e.magnitude(e.subtract(X,a,C))*Math.sqrt(1-H*H),v=c?-v:v,Z.height=v,r.cartographicToCartesian(Z,new e)}};var V=new e;return p.lineSegmentPlane=function(t,r,a,i){n(i)||(i=new e);var u=e.subtract(r,t,V),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),E=-(a.distance+l)/c;if(!(E<0||E>1))return e.multiplyByScalar(u,E,i),e.add(t,i,i),i}},p.trianglePlaneIntersection=function(t,r,n,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,r)+o<0,c=e.dot(i,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var E,f;if(1!==l&&2!==l||(E=new e,f=new e),1===l){if(u)return p.lineSegmentPlane(t,r,a,E),p.lineSegmentPlane(t,n,a,f),{positions:[t,r,n,E,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return p.lineSegmentPlane(r,n,a,E),p.lineSegmentPlane(r,t,a,f),{positions:[t,r,n,E,f],indices:[1,3,4,2,0,4,2,4,3]};if(c)return p.lineSegmentPlane(n,t,a,E),p.lineSegmentPlane(n,r,a,f),{positions:[t,r,n,E,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return p.lineSegmentPlane(r,t,a,E),p.lineSegmentPlane(n,t,a,f),{positions:[t,r,n,E,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return p.lineSegmentPlane(n,r,a,E),p.lineSegmentPlane(t,r,a,f),{positions:[t,r,n,E,f],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return p.lineSegmentPlane(t,n,a,E),p.lineSegmentPlane(r,n,a,f),{positions:[t,r,n,E,f],indices:[0,1,4,0,4,3,2,3,4]}}},p}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,i,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var i=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=i,a):new u(n,i)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),i=t.w;return r(n)?(e.clone(a,n.normal),n.distance=i,n):new u(a,i)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,a){r(a)||(a=new e);var i=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,i,c);return e.subtract(n,o,a)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,a=r.maximumIndex,i=e(r.cacheSize,24),o=n.length;if(!t(a)){a=0;for(var u=0,s=n[u];u<o;)s>a&&(a=s),++u,s=n[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var E=i+1,f=0;f<o;++f)E-c[n[f]]>i&&(c[n[f]]=E,++E);return(E-i+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<n;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}r=e(r,e.EMPTY_OBJECT);var a,i=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=i.length,c=0,l=0,E=i[l],f=s;if(t(o))c=o+1;else{for(;l<f;)E>c&&(c=E),++l,E=i[l];if(-1===c)return 0;++c}var h,d=[];for(h=0;h<c;h++)d[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var p=0;l<f;)d[i[l]].vertexTriangles.push(p),++d[i[l]].numLiveTriangles,d[i[l+1]].vertexTriangles.push(p),++d[i[l+1]].numLiveTriangles,d[i[l+2]].vertexTriangles.push(p),++d[i[l+2]].numLiveTriangles,++p,l+=3;var _=0,m=u+1;a=1;var T,y,R=[],A=[],v=0,S=[],N=s/3,I=[];for(h=0;h<N;h++)I[h]=!1;for(var M,O;-1!==_;){R=[],y=d[_],O=y.vertexTriangles.length;for(var g=0;g<O;++g)if(p=y.vertexTriangles[g],!I[p]){I[p]=!0,l=p+p+p;for(var C=0;C<3;++C)M=i[l],R.push(M),A.push(M),S[v]=M,++v,T=d[M],--T.numLiveTriangles,m-T.timeStamp>u&&(T.timeStamp=m,++m),++l}_=function(e,t,r,a,i,o,u){for(var s,c=-1,l=-1,E=0;E<r.length;){var f=r[E];a[f].numLiveTriangles&&(s=0,i-a[f].timeStamp+2*a[f].numLiveTriangles<=t&&(s=i-a[f].timeStamp),(s>l||-1===l)&&(l=s,c=f)),++E}return-1===c?n(a,o,e,u):c}(i,u,R,d,m,A,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h,d,p,_,m,T,y,R,A,v,S,N){"use strict";function I(e,t,r,n,a){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=a,e[t++]=a,e[t]=r}function M(e){for(var t=e.length,r=t/3*6,n=_.createTypedArray(t,r),a=0,i=0;i<t;i+=3,a+=6)I(n,a,e[i],e[i+1],e[i+2]);return n}function O(e){var t=e.length;if(t>=3){var r=6*(t-2),n=_.createTypedArray(t,r);I(n,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)I(n,a,e[i-1],e[i],e[i-2]);return n}return new Uint16Array}function g(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=_.createTypedArray(t,r),a=e[0],i=0,o=1;o<t;++o,i+=6)I(n,i,a,e[o],e[o+1]);return n}return new Uint16Array}function C(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new d({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function w(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var a=t[n],i=0;i<a.componentsPerAttribute;++i)e[n].values.push(a.values[r*a.componentsPerAttribute+i])}function P(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),A.multiplyByPoint(e,ie,ie),a.pack(ie,r,i)}function x(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,r,i)}function L(e,t){var r,n=e.length,a={},i=e[0][t].attributes;for(r in i)if(i.hasOwnProperty(r)&&c(i[r])&&c(i[r].values)){for(var o=i[r],s=o.values.length,l=!0,E=1;E<n;++E){var f=e[E][t].attributes[r];if(!c(f)||o.componentDatatype!==f.componentDatatype||o.componentsPerAttribute!==f.componentsPerAttribute||o.normalize!==f.normalize){l=!1;break}s+=f.values.length}l&&(a[r]=new d({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function U(e,t){var n,i,o,u,s,l,E,f=e.length,d=(e[0].modelMatrix,c(e[0][t].indices)),p=e[0][t].primitiveType,m=L(e,t);for(n in m)if(m.hasOwnProperty(n))for(s=m[n].values,u=0,i=0;i<f;++i)for(l=e[i][t].attributes[n].values,E=l.length,o=0;o<E;++o)s[u++]=l[o];var T;if(d){var y=0;for(i=0;i<f;++i)y+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:m,primitiveType:S.POINTS})),A=_.createTypedArray(R,y),v=0,N=0;for(i=0;i<f;++i){var I=e[i][t].indices,M=I.length;for(u=0;u<M;++u)A[v++]=N+I[u];N+=h.computeNumberOfVertices(e[i][t])}T=A}var O,g=new a,C=0;for(i=0;i<f;++i){if(O=e[i][t].boundingSphere,!c(O)){g=void 0;break}a.add(O.center,g,g)}if(c(g))for(a.divideByScalar(g,f,g),i=0;i<f;++i){O=e[i][t].boundingSphere;var w=a.magnitude(a.subtract(O.center,g,se))+O.radius;w>C&&(C=w)}return new h({attributes:m,indices:T,primitiveType:p,boundingSphere:c(g)?new r(g,C):void 0})}function b(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function F(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,a=3;a<t;++a)r[n++]=a-1,r[n++]=0,r[n++]=a;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function D(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,a=3;a<t-1;a+=2)r[n++]=a,r[n++]=a-1,r[n++]=a+1,a+2<t&&(r[n++]=a,r[n++]=a+1,r[n++]=a+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return e.indices=r,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function V(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return F(e);case S.TRIANGLE_STRIP:return D(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function q(e,t){Math.abs(e.y)<y.EPSILON6&&(e.y=t?-y.EPSILON6:y.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return q(e,e.y<0),q(t,t.y<0),void q(r,r.y<0);var n,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(r.y);n=a>i?a>o?y.sign(e.y):y.sign(r.y):i>o?y.sign(t.y):y.sign(r.y);var u=n<0;q(e,u),q(t,u),q(r,u)}function H(e,t,r,n){a.add(e,a.multiplyByScalar(a.subtract(t,e,Ae),e.y/(e.y-t.y),Ae),r),a.clone(r,n),q(r,!0),q(n,!1)}function W(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,a=t.y<0,i=r.y<0,o=0;o+=n?1:0,o+=a?1:0,o+=i?1:0;var u=Me.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?a?i||(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Me.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=ve,s[4]=Se,s[5]=Ne,s[6]=Ie,s.length=7),Me}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var a in n)if(n.hasOwnProperty(a)&&c(n[a])&&c(n[a].values)){var i=n[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=_.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var a=t[n];r[n]=new d({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:r,indices:[],primitiveType:e.primitiveType})}function Z(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function K(e,r,i,o,u,s,l,E,f,h,d,p){if(c(s)||c(l)||c(E)||c(f)||c(h)){var _=a.fromArray(u,3*e,Oe),m=a.fromArray(u,3*r,ge),T=a.fromArray(u,3*i,Ce),y=t(o,_,m,T,we);if(c(s)){var R=a.fromArray(s,3*e,Oe),A=a.fromArray(s,3*r,ge),v=a.fromArray(s,3*i,Ce);a.multiplyByScalar(R,y.x,R),a.multiplyByScalar(A,y.y,A),a.multiplyByScalar(v,y.z,v);var S=a.add(R,A,R);a.add(S,v,S),a.normalize(S,S),a.pack(S,d.normal.values,3*p)}if(c(h)){var N=a.fromArray(h,3*e,Oe),I=a.fromArray(h,3*r,ge),M=a.fromArray(h,3*i,Ce);a.multiplyByScalar(N,y.x,N),a.multiplyByScalar(I,y.y,I),a.multiplyByScalar(M,y.z,M);var O;a.equals(N,a.ZERO)&&a.equals(I,a.ZERO)&&a.equals(M,a.ZERO)?(O=Oe,O.x=0,O.y=0,O.z=0):(O=a.add(N,I,N),a.add(O,M,O),a.normalize(O,O)),a.pack(O,d.extrudeDirection.values,3*p)}if(c(l)){var g=a.fromArray(l,3*e,Oe),C=a.fromArray(l,3*r,ge),w=a.fromArray(l,3*i,Ce);a.multiplyByScalar(g,y.x,g),a.multiplyByScalar(C,y.y,C),a.multiplyByScalar(w,y.z,w);var P=a.add(g,C,g);a.add(P,w,P),a.normalize(P,P),a.pack(P,d.tangent.values,3*p)}if(c(E)){var x=a.fromArray(E,3*e,Oe),L=a.fromArray(E,3*r,ge),U=a.fromArray(E,3*i,Ce);a.multiplyByScalar(x,y.x,x),a.multiplyByScalar(L,y.y,L),a.multiplyByScalar(U,y.z,U);var b=a.add(x,L,x);a.add(b,U,b),a.normalize(b,b),a.pack(b,d.bitangent.values,3*p)}if(c(f)){var F=n.fromArray(f,2*e,Pe),D=n.fromArray(f,2*r,xe),B=n.fromArray(f,2*i,Le);n.multiplyByScalar(F,y.x,F),n.multiplyByScalar(D,y.y,D),n.multiplyByScalar(B,y.z,B);var z=n.add(F,D,F);n.add(z,B,z),n.pack(z,d.st.values,2*p)}}}function j(e,t,r,n,a,i){var o=e.position.values.length/3;if(-1!==a){var u=n[a],s=r[u];return-1===s?(r[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function Q(e){var t,r,n,i,o,u=e.geometry,s=u.attributes,l=s.position.values,E=c(s.normal)?s.normal.values:void 0,f=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,d=c(s.st)?s.st.values:void 0,p=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,_=u.indices,m=Y(u),T=Y(u),y=[];y.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<y.length;++o)y[o]=-1,R[o]=-1;var A=_.length;for(o=0;o<A;o+=3){var v=_[o],S=_[o+1],N=_[o+2],I=a.fromArray(l,3*v),M=a.fromArray(l,3*S),O=a.fromArray(l,3*N),g=W(I,M,O);if(c(g)&&g.positions.length>3)for(var C=g.positions,w=g.indices,P=w.length,x=0;x<P;++x){var L=w[x],U=C[L];U.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,_,L<3?o+L:-1,U),K(v,S,N,U,l,E,h,f,d,p,t,i)}else c(g)&&(I=g.positions[0],M=g.positions[1],O=g.positions[2]),I.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,_,o,I),K(v,S,N,I,l,E,h,f,d,p,t,i),i=j(t,r,n,_,o+1,M),K(v,S,N,M,l,E,h,f,d,p,t,i),i=j(t,r,n,_,o+2,O),K(v,S,N,O,l,E,h,f,d,p,t,i)}Z(e,T,m)}function J(e){var t,r=e.geometry,n=r.attributes,i=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,E=[];E.length=i.length/3;var f=[];for(f.length=i.length/3,t=0;t<E.length;++t)E[t]=-1,f[t]=-1;for(t=0;t<l;t+=2){var h=o[t],d=o[t+1],p=a.fromArray(i,3*h,Oe),_=a.fromArray(i,3*d,ge);Math.abs(p.y)<y.EPSILON6&&(p.y<0?p.y=-y.EPSILON6:p.y=y.EPSILON6),Math.abs(_.y)<y.EPSILON6&&(_.y<0?_.y=-y.EPSILON6:_.y=y.EPSILON6);var m=u.attributes,R=u.indices,A=f,v=s.attributes,S=s.indices,N=E,I=T.lineSegmentPlane(p,_,Ue,Ce);if(c(I)){var M=a.multiplyByScalar(a.UNIT_Y,5*y.EPSILON9,be);p.y<0&&(a.negate(M,M),m=s.attributes,R=s.indices,A=E,v=u.attributes,S=u.indices,N=f);var O=a.add(I,M,Fe);j(m,R,A,o,t,p),j(m,R,A,o,-1,O),a.negate(M,M),a.add(I,M,O),j(v,S,N,o,-1,O),j(v,S,N,o,t+1,_)}else{var g,C,w;p.y<0?(g=s.attributes,C=s.indices,w=E):(g=u.attributes,C=u.indices,w=f),j(g,C,w,o,t,p),j(g,C,w,o,t+1,_)}}Z(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,i=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=a.unpack(r,u,ze);if(!(s.x>0)){var c=a.unpack(n,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):a.pack(s,n,u));var l=a.unpack(i,u,Ve);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=r[u+3],i[u+1]=r[u+4],i[u+2]=r[u+5]):a.pack(s,i,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,E=s.prevPosition.values,f=s.nextPosition.values,h=s.expandAndWidth.values,d=c(s.st)?s.st.values:void 0,p=c(s.color)?s.color.values:void 0,_=Y(u),m=Y(u),R=!1,A=l.length/3;for(t=0;t<A;t+=4){var v=t,S=t+2,N=a.fromArray(l,3*v,ze),I=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<Ye)for(N.y=Ye*(I.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,r=3*v;r<3*v+12;r+=3)E[r]=l[3*t],E[r+1]=l[3*t+1],E[r+2]=l[3*t+2];if(Math.abs(I.y)<Ye)for(I.y=Ye*(N.y<0?-1:1),l[3*(t+2)+1]=I.y,l[3*(t+3)+1]=I.y,r=3*v;r<3*v+12;r+=3)f[r]=l[3*(t+2)],f[r+1]=l[3*(t+2)+1],f[r+2]=l[3*(t+2)+2];var M=_.attributes,O=_.indices,g=m.attributes,C=m.indices,w=T.lineSegmentPlane(N,I,Ue,qe);if(c(w)){R=!0;var P=a.multiplyByScalar(a.UNIT_Y,ke,Xe);N.y<0&&(a.negate(P,P),M=m.attributes,O=m.indices,g=_.attributes,C=_.indices);var x=a.add(w,P,He);M.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.position.values.push(x.x,x.y,x.z),M.position.values.push(x.x,x.y,x.z),M.prevPosition.values.push(E[3*v],E[3*v+1],E[3*v+2]),M.prevPosition.values.push(E[3*v+3],E[3*v+4],E[3*v+5]),M.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),a.negate(P,P),a.add(w,P,x),g.position.values.push(x.x,x.y,x.z),g.position.values.push(x.x,x.y,x.z),g.position.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.nextPosition.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.nextPosition.values.push(f[3*S],f[3*S+1],f[3*S+2]),g.nextPosition.values.push(f[3*S+3],f[3*S+4],f[3*S+5]);var L=n.fromArray(h,2*v,De),U=Math.abs(L.y);M.expandAndWidth.values.push(-1,U,1,U),M.expandAndWidth.values.push(-1,-U,1,-U),g.expandAndWidth.values.push(-1,U,1,U),g.expandAndWidth.values.push(-1,-U,1,-U);var b=a.magnitudeSquared(a.subtract(w,N,Ve));if(b/=a.magnitudeSquared(a.subtract(I,N,Ve)),c(p)){var F=i.fromArray(p,4*v,We),D=i.fromArray(p,4*S,We),B=y.lerp(F.x,D.x,b),z=y.lerp(F.y,D.y,b),G=y.lerp(F.z,D.z,b),V=y.lerp(F.w,D.w,b);for(r=4*v;r<4*v+8;++r)M.color.values.push(p[r]);for(M.color.values.push(B,z,G,V),M.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),r=4*S;r<4*S+8;++r)g.color.values.push(p[r])}if(c(d)){var q=n.fromArray(d,2*v,De),X=n.fromArray(d,2*(t+3),Be),H=y.lerp(q.x,X.x,b);for(r=2*v;r<2*v+4;++r)M.st.values.push(d[r]);for(M.st.values.push(H,q.y),M.st.values.push(H,X.y),g.st.values.push(H,q.y),g.st.values.push(H,X.y),r=2*S;r<2*S+4;++r)g.st.values.push(d[r])}o=M.position.values.length/3-4,O.push(o,o+2,o+1),O.push(o+1,o+2,o+3),o=g.position.values.length/3-4,C.push(o,o+2,o+1),C.push(o+1,o+2,o+3)}else{var W,k;for(N.y<0?(W=m.attributes,k=m.indices):(W=_.attributes,k=_.indices),W.position.values.push(N.x,N.y,N.z),W.position.values.push(N.x,N.y,N.z),W.position.values.push(I.x,I.y,I.z),W.position.values.push(I.x,I.y,I.z),r=3*t;r<3*t+12;++r)W.prevPosition.values.push(E[r]),W.nextPosition.values.push(f[r]);for(r=2*t;r<2*t+8;++r)W.expandAndWidth.values.push(h[r]),c(d)&&W.st.values.push(d[r]);if(c(p))for(r=4*t;r<4*t+16;++r)W.color.values.push(p[r]);o=W.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}R&&($(m),$(_)),Z(e,m,_)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=M(t);break;case S.TRIANGLE_STRIP:e.indices=O(t);break;case S.TRIANGLE_FAN:e.indices=g(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),E=0,f=0;f<o;f+=3)l[E++]=a[f],l[E++]=a[f+1],l[E++]=a[f+2],l[E++]=a[f]+i[f]*n,l[E++]=a[f+1]+i[f+1]*n,l[E++]=a[f+2]+i[f+2]*n;var p,_=e.boundingSphere;return c(_)&&(p=new r(_.center,_.radius+n)),new h({attributes:{position:new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:p})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,a={},i=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(a[u]=i++)}for(var s in n)n.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),a=0;a<t;a++)n[a]=-1;for(var i,o=r,s=o.length,l=_.createTypedArray(t,s),E=0,f=0,d=0;E<s;)i=n[o[E]],-1!==i?l[f]=i:(i=o[E],n[i]=d,l[f]=d,++d),++E,++f;e.indices=l;var p=e.attributes;for(var m in p)if(p.hasOwnProperty(m)&&c(p[m])&&c(p[m].values)){for(var T=p[m],y=T.values,R=0,A=T.componentsPerAttribute,v=u.createTypedArray(T.componentDatatype,d*A);R<t;){var S=n[R];if(-1!==S)for(var N=0;N<A;N++)v[A*S+N]=y[A*R+N];++R}T.values=v}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,a=0,i=0;i<n;i++)r[i]>a&&(a=r[i]);e.indices=N.tipsify({indices:r,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=h.computeNumberOfVertices(e);if(c(e.indices)&&r>=y.SIXTY_FOUR_KILOBYTES){var n,a=[],i=[],o=0,u=C(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var E=0;E<l;E+=n){for(var f=0;f<n;++f){var d=s[E+f],p=a[d];c(p)||(p=o++,a[d]=p,w(u,e.attributes,d)),i.push(p)}o+n>=y.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=C(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new a,ne=new o;te.projectTo2D=function(e,t,r,n,i){var o=e.attributes[t];i=c(i)?i:new f;for(var s=i.ellipsoid,l=o.values,E=new Float64Array(l.length),h=0,p=0;p<l.length;p+=3){var _=a.fromArray(l,p,re),m=s.cartesianToCartographic(_,ne),T=i.project(m,re);E[h++]=T.x,E[h++]=T.y,E[h++]=T.z}return e.attributes[r]=o,e.attributes[n]=new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:E}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)E.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var f=a.componentsPerAttribute;return e.attributes[r]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:s}),e.attributes[n]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:c}),delete e.attributes[t],e};var ie=new a,oe=new A,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(A.equals(t,A.IDENTITY))return e;var n=e.geometry.attributes;P(t,n.position),P(t,n.prevPosition),P(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(A.inverse(t,oe),A.transpose(oe,oe),A.getRotation(oe,ue),x(ue,n.normal),x(ue,n.tangent),x(ue,n.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=r.transform(a,t,a)),e.modelMatrix=A.clone(A.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,a=0;a<n;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&r.push(i)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,Ee=new a,fe=new a;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,i=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),E=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var f=0;for(t=0;t<s;t+=3){var h=r[t],p=r[t+1],_=r[t+2],m=3*h,T=3*p,R=3*_;le.x=i[m],le.y=i[m+1],le.z=i[m+2],Ee.x=i[T],Ee.y=i[T+1],Ee.z=i[T+2],fe.x=i[R],fe.y=i[R+1],fe.z=i[R+2],c[h].count++,c[p].count++,c[_].count++,a.subtract(Ee,le,Ee),a.subtract(fe,le,fe),l[f]=a.cross(Ee,fe,new a),f++}var A=0;for(t=0;t<o;t++)c[t].indexOffset+=A,A+=c[t].count;f=0;var v;for(t=0;t<s;t+=3){v=c[r[t]];var S=v.indexOffset+v.currentCount;E[S]=f,v.currentCount++,v=c[r[t+1]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,v=c[r[t+2]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,f++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var I=3*t;if(v=c[t],a.clone(a.ZERO,ce),v.count>0){for(f=0;f<v.count;f++)a.add(ce,l[E[v.indexOffset+f]],ce);a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&a.clone(l[E[v.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[I]=ce.x,N[I+1]=ce.y,N[I+2]=ce.z}return e.attributes.normal=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,de=new a,pe=new a;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var E,f,h;for(t=0;t<c;t+=3){var p=r[t],_=r[t+1],m=r[t+2];E=3*p,f=3*_,h=3*m;var T=2*p,y=2*_,R=2*m,A=n[E],v=n[E+1],S=n[E+2],N=o[T],I=o[T+1],M=o[y+1]-I,O=o[R+1]-I,g=1/((o[y]-N)*O-(o[R]-N)*M),C=(O*(n[f]-A)-M*(n[h]-A))*g,w=(O*(n[f+1]-v)-M*(n[h+1]-v))*g,P=(O*(n[f+2]-S)-M*(n[h+2]-S))*g;l[E]+=C,l[E+1]+=w,l[E+2]+=P,l[f]+=C,l[f+1]+=w,l[f+2]+=P,l[h]+=C,l[h+1]+=w,l[h+2]+=P}var x=new Float32Array(3*s),L=new Float32Array(3*s);for(t=0;t<s;t++){E=3*t,f=E+1,h=E+2;var U=a.fromArray(i,E,he),b=a.fromArray(l,E,pe),F=a.dot(U,b);a.multiplyByScalar(U,F,de),a.normalize(a.subtract(b,de,b),b),x[E]=b.x,x[f]=b.y,x[h]=b.z,a.normalize(a.cross(U,b,b),b),L[E]=b.x,L[f]=b.y,L[h]=b.z}return e.attributes.tangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:x}),e.attributes.bitangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:L}),e};var _e=new n,me=new a,Te=new a,ye=new a,Re=new n;te.compressVertices=function(t){var r,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),E=0;for(r=0;r<i;++r)a.fromArray(s,3*r,me),a.equals(me,a.ZERO)?E+=2:(Re=e.octEncodeInRange(me,65535,Re),l[E++]=Re.x,l[E++]=Re.y);return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var f=t.attributes.normal,h=t.attributes.st,p=c(f),_=c(h);if(!p&&!_)return t;var m,T,y,R,A=t.attributes.tangent,v=t.attributes.bitangent,S=c(A),N=c(v);p&&(m=f.values),_&&(T=h.values),S&&(y=A.values),N&&(R=v.values),i=(p?m.length:T.length)/(p?3:2);var I=i,M=_&&p?2:1;M+=S||N?1:0,I*=M;var O=new Float32Array(I),g=0;for(r=0;r<i;++r){_&&(n.fromArray(T,2*r,_e),O[g++]=e.compressTextureCoordinates(_e));var C=3*r;p&&c(y)&&c(R)?(a.fromArray(m,C,me),a.fromArray(y,C,Te),a.fromArray(R,C,ye),e.octPack(me,Te,ye,_e),O[g++]=_e.x,O[g++]=_e.y):(p&&(a.fromArray(m,C,me),O[g++]=e.octEncodeFloat(me)),S&&(a.fromArray(y,C,me),O[g++]=e.octEncodeFloat(me)),N&&(a.fromArray(R,C,me),O[g++]=e.octEncodeFloat(me)))}return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:M,values:O}),p&&delete t.attributes.normal,_&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Ae=new a,ve=new a,Se=new a,Ne=new a,Ie=new a,Me={positions:new Array(7),indices:new Array(9)},Oe=new a,ge=new a,Ce=new a,we=new a,Pe=new n,xe=new n,Le=new n,Ue=v.fromPointNormal(a.ZERO,a.UNIT_Y),be=new a,Fe=new a,De=new n,Be=new n,ze=new a,Ge=new a,Ve=new a,qe=new a,Xe=new a,He=new a,We=new i,ke=5*y.EPSILON9,Ye=y.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,v.ORIGIN_ZX_PLANE)!==m.INTERSECTING)return e}if(t.geometryType!==p.NONE)switch(t.geometryType){case p.POLYLINES:ee(e);break;case p.TRIANGLES:Q(e);break;case p.LINES:J(e)}else V(t),t.primitiveType===S.TRIANGLES?Q(e):t.primitiveType===S.LINES&&J(e);return e},te}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius, +this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},s.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},s}),define("Scene/PrimitivePipeline",["../Core/BoundingSphere","../Core/ComponentDatatype","../Core/defined","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/GeographicProjection","../Core/Geometry","../Core/GeometryAttribute","../Core/GeometryAttributes","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Matrix4","../Core/WebMercatorProjection"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h){"use strict";function d(e,t,n){var a,i=!n,o=e.length;if(!i&&o>1){var u=e[0].modelMatrix;for(a=1;a<o;++a)if(!f.equals(u,e[a].modelMatrix)){i=!0;break}}if(i)for(a=0;a<o;++a)r(e[a].geometry)&&l.transformToWorldCoordinates(e[a]);else f.multiplyTransformation(t,e[0].modelMatrix,t)}function p(e,r){var n=e.attributes,a=n.position,i=a.values.length/a.componentsPerAttribute;n.batchId=new s({componentDatatype:t.FLOAT,componentsPerAttribute:1,values:new Float32Array(i)});for(var o=n.batchId.values,u=0;u<i;++u)o[u]=r}function _(e){for(var t=e.length,n=0;n<t;++n){var a=e[n];r(a.geometry)?p(a.geometry,n):r(a.westHemisphereGeometry)&&r(a.eastHemisphereGeometry)&&(p(a.westHemisphereGeometry,n),p(a.eastHemisphereGeometry,n))}}function m(n){var a,i,o=n.instances,u=n.projection,s=n.elementIndexUintSupported,c=n.scene3DOnly,E=n.vertexCacheOptimize,f=n.compressVertices,h=n.modelMatrix,p=o.length;for(a=0;a<p;++a)if(r(o[a].geometry)){o[a].geometry.primitiveType;break}if(d(o,h,c),!c)for(a=0;a<p;++a)r(o[a].geometry)&&l.splitLongitude(o[a]);if(_(o),E)for(a=0;a<p;++a){var m=o[a];r(m.geometry)?(l.reorderForPostVertexCache(m.geometry),l.reorderForPreVertexCache(m.geometry)):r(m.westHemisphereGeometry)&&r(m.eastHemisphereGeometry)&&(l.reorderForPostVertexCache(m.westHemisphereGeometry),l.reorderForPreVertexCache(m.westHemisphereGeometry),l.reorderForPostVertexCache(m.eastHemisphereGeometry),l.reorderForPreVertexCache(m.eastHemisphereGeometry))}var T=l.combineInstances(o);for(p=T.length,a=0;a<p;++a){i=T[a];var y,R=i.attributes;if(c)for(y in R)R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE&&l.encodeAttribute(i,y,y+"3DHigh",y+"3DLow");else for(y in R)if(R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE){var A=y+"3D",v=y+"2D";l.projectTo2D(i,y,A,v,u),r(i.boundingSphere)&&"position"===y&&(i.boundingSphereCV=e.fromVertices(i.attributes.position2D.values)),l.encodeAttribute(i,A,A+"High",A+"Low"),l.encodeAttribute(i,v,v+"High",v+"Low")}f&&l.compressVertices(i)}if(!s){var S=[];for(p=T.length,a=0;a<p;++a)i=T[a],S=S.concat(l.fitToUnsignedShortIndices(i));T=S}return T}function T(e,t,n,a){var i,o,u,s=a.length-1;if(s>=0){var c=a[s];i=c.offset+c.count,u=c.index,o=n[u].indices.length}else i=0,u=0,o=n[u].indices.length;for(var l=e.length,E=0;E<l;++E){var f=e[E],h=f[t];if(r(h)){var d=h.indices.length;i+d>o&&(i=0,o=n[++u].indices.length),a.push({index:u,offset:i,count:d}),i+=d}}}function y(e,t){var r=[];return T(e,"geometry",t,r),T(e,"westHemisphereGeometry",t,r),T(e,"eastHemisphereGeometry",t,r),r}function R(e,t){var n=e.attributes;for(var a in n)if(n.hasOwnProperty(a)){var i=n[a];r(i)&&r(i.values)&&t.push(i.values.buffer)}r(e.indices)&&t.push(e.indices.buffer)}function A(e,t){for(var r=e.length,n=0;n<r;++n)R(e[n],t)}function v(t){for(var n=1,a=t.length,i=0;i<a;i++){var o=t[i];if(++n,r(o)){var u=o.attributes;n+=6+2*e.packedLength+(r(o.indices)?o.indices.length:0);for(var s in u)if(u.hasOwnProperty(s)&&r(u[s])){var c=u[s];n+=5+c.values.length}}}return n}function S(e,t){var r=e.length,n=new Float64Array(1+16*r),a=0;n[a++]=r;for(var i=0;i<r;i++){var o=e[i];f.pack(o.modelMatrix,n,a),a+=f.packedLength}return t.push(n.buffer),n}function N(e){for(var t=e,r=new Array(t[0]),n=0,a=1;a<t.length;){var i=f.unpack(t,a);a+=f.packedLength,r[n++]={modelMatrix:i}}return r}function I(t){var n=t.length,a=1+(e.packedLength+1)*n,i=new Float32Array(a),o=0;i[o++]=n;for(var u=0;u<n;++u){var s=t[u];r(s)?(i[o++]=1,e.pack(t[u],i,o)):i[o++]=0,o+=e.packedLength}return i}function M(t){for(var r=new Array(t[0]),n=0,a=1;a<t.length;)1===t[a++]&&(r[n]=e.unpack(t,a)),++n,a+=e.packedLength;return r}if(!i.supportsTypedArrays())return{};var O={};return O.combineGeometry=function(t){var n,a,i,o=t.instances,u=o.length;u>0&&(n=m(t),n.length>0&&(a=l.createAttributeLocations(n[0]),t.createPickOffsets&&(i=y(o,n))));for(var s=new Array(u),c=new Array(u),E=0;E<u;++E){var f=o[E],h=f.geometry;r(h)&&(s[E]=h.boundingSphere,c[E]=h.boundingSphereCV);var d=f.eastHemisphereGeometry,p=f.westHemisphereGeometry;r(d)&&r(p)&&(r(d.boundingSphere)&&r(p.boundingSphere)&&(s[E]=e.union(d.boundingSphere,p.boundingSphere)),r(d.boundingSphereCV)&&r(p.boundingSphereCV)&&(c[E]=e.union(d.boundingSphereCV,p.boundingSphereCV)))}return{geometries:n,modelMatrix:t.modelMatrix,attributeLocations:a,pickOffsets:i,boundingSpheres:s,boundingSpheresCV:c}},O.packCreateGeometryResults=function(t,n){var a=new Float64Array(v(t)),i=[],o={},u=t.length,s=0;a[s++]=u;for(var c=0;c<u;c++){var l=t[c],E=r(l);if(a[s++]=E?1:0,E){a[s++]=l.primitiveType,a[s++]=l.geometryType;var f=r(l.boundingSphere)?1:0;a[s++]=f,f&&e.pack(l.boundingSphere,a,s),s+=e.packedLength;var h=r(l.boundingSphereCV)?1:0;a[s++]=h,h&&e.pack(l.boundingSphereCV,a,s),s+=e.packedLength;var d=l.attributes,p=[];for(var _ in d)d.hasOwnProperty(_)&&r(d[_])&&(p.push(_),r(o[_])||(o[_]=i.length,i.push(_)));a[s++]=p.length;for(var m=0;m<p.length;m++){var T=p[m],y=d[T];a[s++]=o[T],a[s++]=y.componentDatatype,a[s++]=y.componentsPerAttribute,a[s++]=y.normalize?1:0,a[s++]=y.values.length,a.set(y.values,s),s+=y.values.length}var R=r(l.indices)?l.indices.length:0;a[s++]=R,R>0&&(a.set(l.indices,s),s+=R)}}return n.push(a.buffer),{stringTable:i,packedData:a}},O.unpackCreateGeometryResults=function(r){for(var n,a=r.stringTable,i=r.packedData,o=new Array(i[0]),l=0,f=1;f<i.length;){if(1===i[f++]){var h,d,p=i[f++],_=i[f++];1===i[f++]&&(h=e.unpack(i,f)),f+=e.packedLength;1===i[f++]&&(d=e.unpack(i,f)),f+=e.packedLength;var m,T,y,R=new c,A=i[f++];for(n=0;n<A;n++){var v=a[i[f++]],S=i[f++];y=i[f++];var N=0!==i[f++];m=i[f++],T=t.createTypedArray(S,m);for(var I=0;I<m;I++)T[I]=i[f++];R[v]=new s({componentDatatype:S,componentsPerAttribute:y,normalize:N,values:T})}var M;if((m=i[f++])>0){var O=T.length/y;for(M=E.createTypedArray(O,m),n=0;n<m;n++)M[n]=i[f++]}o[l++]=new u({primitiveType:p,geometryType:_,boundingSphere:h,boundingSphereCV:d,indices:M,attributes:R})}else o[l++]=void 0}return o},O.packCombineGeometryParameters=function(e,t){for(var r=e.createGeometryResults,n=r.length,a=0;a<n;a++)t.push(r[a].packedData.buffer);return{createGeometryResults:e.createGeometryResults,packedInstances:S(e.instances,t),ellipsoid:e.ellipsoid,isGeographic:e.projection instanceof o,elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e.createPickOffsets}},O.unpackCombineGeometryParameters=function(e){for(var t=N(e.packedInstances),r=e.createGeometryResults,n=r.length,i=0,u=0;u<n;u++)for(var s=O.unpackCreateGeometryResults(r[u]),c=s.length,l=0;l<c;l++){var E=s[l],d=t[i];d.geometry=E,++i}var p=a.clone(e.ellipsoid);return{instances:t,ellipsoid:p,projection:e.isGeographic?new o(p):new h(p),elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:f.clone(e.modelMatrix),createPickOffsets:e.createPickOffsets}},O.packCombineGeometryResults=function(e,t){r(e.geometries)&&A(e.geometries,t);var n=I(e.boundingSpheres),a=I(e.boundingSpheresCV);return t.push(n.buffer,a.buffer),{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:n,boundingSpheresCV:a}},O.unpackCombineGeometryResults=function(e){return{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:M(e.boundingSpheres),boundingSpheresCV:M(e.boundingSpheresCV)}},O}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var r,n=t.name,a=t.message;r=e(n)&&e(a)?n+": "+a:t.toString();var i=t.stack;return e(i)&&(r+="\n"+i),r}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,r){"use strict";function n(n){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=n(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+r(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return n}),define("Workers/combineGeometry",["../Scene/PrimitivePipeline","./createTaskProcessorWorker"],function(e,t){"use strict";function r(t,r){var n=e.unpackCombineGeometryParameters(t),a=e.combineGeometry(n);return e.packCombineGeometryResults(a,r)}return t(r)})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxGeometry.js index 87c20a53..722ff0fc 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(e),T.y=s*Math.sin(e),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var m=u.x,O=u.y,M=u.z,y=o;y.x=S.x*m*2,y.y=S.y*O*2,y.z=S.z*M*2;var p,C,U,L,F,P,w,g,x,D,B,v=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{v-=z,U=1/(1+v*m),L=1/(1+v*O),F=1/(1+v*M),P=U*U,w=L*L,g=F*F,x=P*U,D=w*L,B=g*F,p=f*P+h*w+N*g-1,C=f*x*m+h*D*O+N*B*M;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*L,s.z=T*F,s):new e(c*U,_*L,T*F)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),T=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),m=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=m,i):new u(I,S,m)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var T=new e,R=new e;_.prototype.cartographicToCartesian=function(t,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(e[E.getElementIndex(T,_)])>n){var R,f=e[E.getElementIndex(T,T)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(T,T)]=s,t[E.getElementIndex(T,_)]=c,t[E.getElementIndex(_,T)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,T=e.z*e.w,R=e.w*e.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),m=-n-u+_+R;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=m,t):new E(l,A,f,h,N,d,I,S,m)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=R,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=T,t[7]=A,t[8]=N,t):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],T)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),T=t.diagonal=E.clone(e,t.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],T=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(t,R,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,T=t.x*t.w,R=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),m=2*(s+h),O=-E+R-f+N,M=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=m*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=M*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,T=new e,R=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,T),T),e.normalize(e.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,m=r.z,O=u*-I+E*-S+s*-m,M=h*-I+N*-S+d*-m,y=l*I+A*S+f*m;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=M,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,M,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),T=s,R=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],T=e[9],R=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],m=t[3],O=t[4],M=t[5],y=t[6],p=t[7],C=t[8],U=t[9],L=t[10],F=t[11],P=t[12],w=t[13],g=t[14],x=t[15],D=r*d+u*I+_*S+A*m,B=i*d+E*I+T*S+f*m,v=a*d+s*I+R*S+h*m,z=o*d+c*I+l*S+N*m,G=r*O+u*M+_*y+A*p,b=i*O+E*M+T*y+f*p,X=a*O+s*M+R*y+h*p,V=o*O+c*M+l*y+N*p,q=r*C+u*U+_*L+A*F,H=i*C+E*U+T*L+f*F,W=a*C+s*U+R*L+h*F,Y=o*C+c*U+l*L+N*F,k=r*P+u*w+_*g+A*x,K=i*P+E*w+T*g+f*x,Z=a*P+s*w+R*g+h*x,j=o*P+c*w+l*g+N*x;return n[0]=D,n[1]=B,n[2]=v,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=e[12],R=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],m=t[9],O=t[10],M=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,L=a*A+E*f+_*h,F=r*N+o*d+s*I,P=i*N+u*d+c*I,w=a*N+E*d+_*I,g=r*S+o*m+s*O,x=i*S+u*m+c*O,D=a*S+E*m+_*O,B=r*M+o*y+s*p+T,v=i*M+u*y+c*p+R,z=a*M+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=F,n[5]=P,n[6]=w,n[7]=0,n[8]=g,n[9]=x,n[10]=D,n[11]=0,n[12]=B,n[13]=v,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=t[0],R=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*T+o*R+s*l,m=i*T+u*R+c*l,O=a*T+E*R+_*l,M=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=m,n[2]=O,n[3]=0,n[4]=M,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],T=e[5],R=e[9],l=e[13],A=e[2],f=e[6],S=e[10],m=e[14],O=e[3],M=e[7],y=e[11],p=e[15],C=S*p,U=m*y,L=f*p,F=m*M,P=f*y,w=S*M,g=A*p,x=m*O,D=A*y,B=S*O,v=A*M,z=f*O,G=C*T+F*R+P*l-(U*T+L*R+w*l),b=U*_+g*R+B*l-(C*_+x*R+D*l),X=L*_+x*T+v*l-(F*_+g*T+z*l),V=w*_+D*T+z*R-(P*_+B*T+v*R),q=U*i+L*a+w*o-(C*i+F*a+P*o),H=C*r+x*a+D*o-(U*r+g*a+B*o),W=F*r+g*i+z*o-(L*r+x*i+v*o),Y=P*r+B*i+v*a-(w*r+D*i+z*a);C=a*l,U=o*R,L=i*l,F=o*T,P=i*R,w=a*T,g=r*l,x=o*_,D=r*R,B=a*_,v=r*T,z=i*_;var k=C*M+F*y+P*p-(U*M+L*y+w*p),K=U*O+g*y+B*p-(C*O+x*y+D*p),Z=L*O+x*M+v*p-(F*O+g*M+z*p),j=w*O+D*M+z*y-(P*O+B*M+v*y),Q=L*S+w*m+U*f-(P*m+C*f+F*S),J=D*m+C*A+x*S-(g*S+B*m+U*A),$=g*f+z*m+F*A-(v*m+L*A+x*f),ee=v*S+P*A+B*f-(D*f+z*S+w*A),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=q*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],T=e[13],R=e[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=e.length;_<T;_++){var R=e[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var T=Math.max(e.south,t.south),R=Math.min(e.north,t.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,T=e.south,R=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function T(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var R=new e,l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,m=new e,O=new e,M=new e;T.fromPoints=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],d),o=e.clone(a,R),u=e.clone(a,l),E=e.clone(a,A),s=e.clone(a,f),c=e.clone(a,h),_=e.clone(a,N),y=t.length;for(r=1;r<y;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var L=e.magnitudeSquared(e.subtract(s,o,I)),F=e.magnitudeSquared(e.subtract(c,u,I)),P=e.magnitudeSquared(e.subtract(_,E,I)),w=o,g=s,x=L;F>x&&(x=F,w=u,g=c),P>x&&(x=P,w=E,g=_);var D=S;D.x=.5*(w.x+g.x),D.y=.5*(w.y+g.y),D.z=.5*(w.z+g.z);var B=e.magnitudeSquared(e.subtract(g,D,I)),v=Math.sqrt(B),z=m;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,I),.5,M),X=0;for(r=0;r<y;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,I));V>X&&(X=V);var q=e.magnitudeSquared(e.subtract(a,D,I));if(q>B){var H=Math.sqrt(q);v=.5*(v+H),B=v*v;var W=H-v;D.x=(v*D.x+W*a.x)/H,D.y=(v*D.y+W*a.y)/H,D.z=(v*D.z+W*a.z)/H}}return v<X?(e.clone(D,n.center),n.radius=v):(e.clone(b,n.center),n.radius=X),n};var y=new o,p=new e,C=new e,U=new t,L=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(t,U),U.height=a,_.northeast(t,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*R,A.z=E.z+.5*l,u};var F=[];T.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,F);return T.fromPoints(E,u)},T.fromVertices=function(t,n,a,o){if(i(o)||(o=new T),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=d;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,R),c=e.clone(u,l),_=e.clone(u,A),y=e.clone(u,f),p=e.clone(u,h),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=a){var L=t[E]+n.x,F=t[E+1]+n.y,P=t[E+2]+n.z;u.x=L,u.y=F,u.z=P,L<s.x&&e.clone(u,s),L>y.x&&e.clone(u,y),F<c.y&&e.clone(u,c),F>p.y&&e.clone(u,p),P<_.z&&e.clone(u,_),P>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(y,s,I)),g=e.magnitudeSquared(e.subtract(p,c,I)),x=e.magnitudeSquared(e.subtract(C,_,I)),D=s,B=y,v=w;g>v&&(v=g,D=c,B=p),x>v&&(v=x,D=_,B=C);var z=S;z.x=.5*(D.x+B.x),z.y=.5*(D.y+B.y),z.z=.5*(D.z+B.z);var G=e.magnitudeSquared(e.subtract(B,z,I)),b=Math.sqrt(G),X=m;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var q=e.multiplyByScalar(e.add(X,V,I),.5,M),H=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,q,I));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new T),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=d;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,R),E=e.clone(a,l),s=e.clone(a,A),c=e.clone(a,f),_=e.clone(a,h),y=e.clone(a,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],L=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),L<s.z&&e.clone(a,s),L>y.z&&e.clone(a,y)}var F=e.magnitudeSquared(e.subtract(c,u,I)),P=e.magnitudeSquared(e.subtract(_,E,I)),w=e.magnitudeSquared(e.subtract(y,s,I)),g=u,x=c,D=F;P>D&&(D=P,g=E,x=_),w>D&&(D=w,g=s,x=y);var B=S;B.x=.5*(g.x+x.x),B.y=.5*(g.y+x.y),B.z=.5*(g.z+x.z);var v=e.magnitudeSquared(e.subtract(x,B,I)),z=Math.sqrt(v),G=m;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=e.multiplyByScalar(e.add(G,b,I),.5,M),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var q=e.magnitude(e.subtract(a,X,I));q>V&&(V=q);var H=e.magnitudeSquared(e.subtract(a,B,I));if(H>v){var W=Math.sqrt(H);z=.5*(z+W),v=z*z;var Y=W-z;B.x=(z*B.x+Y*a.x)/W,B.y=(z*B.y+Y*a.y)/W,B.z=(z*B.z+Y*a.z)/W}}return z<V?(e.clone(B,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){i(r)||(r=new T);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},T.fromEllipsoid=function(t,n){return i(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var P=new e;T.fromBoundingSpheres=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,P)+s.radius)}return n.radius=E,n};var w=new e,g=new e,x=new e;T.fromOrientedBoundingBox=function(t,n){i(n)||(n=new T);var r=t.halfAxes,a=s.getColumn(r,0,w),o=s.getColumn(r,1,g),u=s.getColumn(r,2,x);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},T.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new T);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var D=new e,B=new e;T.union=function(t,n,r){i(r)||(r=new T);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,D),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,B);return e.add(R,a,R),e.clone(R,r.center),r.radius=_,r};var v=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,v));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},T.transform=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;T.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,q=new e,H=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return T.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,H),R=e.negate(s,q),l=Y,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,R,A),A=l[2],e.add(E,_,A),e.add(A,R,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,R,A),A=l[6],e.add(E,_,A),e.add(A,R,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,W);n.project(d,N)}i=T.fromPoints(l,i),o=i.center;var I=o.x,S=o.y,m=o.z;return o.x=m,o.y=I,o.z=S,i},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!T())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,m=r(e[1]))}return S}function a(){return i()&&m}function o(){if(!t(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,M=r(e[1]))}return O}function u(){return o()&&M}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0,p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function T(){if(!t(L)){L=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,F=r(e[1]))}return L}function R(){return T()&&F}function l(){if(!t(P)){P=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(P=!0,w=r(e[1]))}return P}function A(){return t(g)||(g=/Windows/i.test(I.appVersion)),g}function f(){return l()&&w}function h(){return t(x)||(x="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),x}function N(){if(!t(B)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;B=t(n)&&""!==n,B&&(D=n)}return B}function d(){return N()?D:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,m,O,M,y,p,C,U,L,F,P,w,g,x,D,B,v={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return v.supportsFullscreen=function(){return n.supportsFullscreen()},v.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},v.supportsWebWorkers=function(){return"undefined"!=typeof Worker},v}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},i.unpack=function(n,r,a){return r=e(r,0),t(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(e,n){if(t(e))return t(n)||(n=new i),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},i}),define("Core/BoxGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType","./VertexFormat"],function(e,t,n,r,i,a,o,u,E,s,c){"use strict";function _(e){e=i(e,i.EMPTY_OBJECT);var n=e.minimum,r=e.maximum,a=i(e.vertexFormat,c.DEFAULT);this._minimum=t.clone(n),this._maximum=t.clone(r),this._vertexFormat=a,this._workerName="createBoxGeometry"}var T=new t;_.fromDimensions=function(e){e=i(e,i.EMPTY_OBJECT);var n=e.dimensions,r=t.multiplyByScalar(n,.5,new t);return new _({minimum:t.negate(r,new t),maximum:r,vertexFormat:e.vertexFormat})},_.fromAxisAlignedBoundingBox=function(e){return new _({minimum:e.minimum,maximum:e.maximum})},_.packedLength=2*t.packedLength+c.packedLength,_.pack=function(e,n,r){return r=i(r,0),t.pack(e._minimum,n,r),t.pack(e._maximum,n,r+t.packedLength),c.pack(e._vertexFormat,n,r+2*t.packedLength),n};var R=new t,l=new t,A=new c,f={minimum:R,maximum:l,vertexFormat:A};return _.unpack=function(e,n,r){n=i(n,0);var o=t.unpack(e,n,R),u=t.unpack(e,n+t.packedLength,l),E=c.unpack(e,n+2*t.packedLength,A);return a(r)?(r._minimum=t.clone(o,r._minimum),r._maximum=t.clone(u,r._maximum),r._vertexFormat=c.clone(E,r._vertexFormat),r):new _(f)},_.createGeometry=function(n){var i=n._minimum,a=n._maximum,c=n._vertexFormat;if(!t.equals(i,a)){var _,R,l=new E;if(c.position&&(c.st||c.normal||c.tangent||c.bitangent)){if(c.position&&(R=new Float64Array(72),R[0]=i.x,R[1]=i.y,R[2]=a.z,R[3]=a.x,R[4]=i.y,R[5]=a.z,R[6]=a.x,R[7]=a.y,R[8]=a.z,R[9]=i.x,R[10]=a.y,R[11]=a.z,R[12]=i.x,R[13]=i.y,R[14]=i.z,R[15]=a.x,R[16]=i.y,R[17]=i.z,R[18]=a.x,R[19]=a.y,R[20]=i.z,R[21]=i.x,R[22]=a.y,R[23]=i.z,R[24]=a.x,R[25]=i.y,R[26]=i.z,R[27]=a.x,R[28]=a.y,R[29]=i.z,R[30]=a.x,R[31]=a.y,R[32]=a.z,R[33]=a.x,R[34]=i.y,R[35]=a.z,R[36]=i.x,R[37]=i.y,R[38]=i.z,R[39]=i.x,R[40]=a.y,R[41]=i.z,R[42]=i.x,R[43]=a.y,R[44]=a.z,R[45]=i.x,R[46]=i.y,R[47]=a.z,R[48]=i.x,R[49]=a.y,R[50]=i.z,R[51]=a.x,R[52]=a.y,R[53]=i.z,R[54]=a.x,R[55]=a.y,R[56]=a.z,R[57]=i.x,R[58]=a.y,R[59]=a.z,R[60]=i.x,R[61]=i.y,R[62]=i.z,R[63]=a.x,R[64]=i.y,R[65]=i.z,R[66]=a.x,R[67]=i.y,R[68]=a.z,R[69]=i.x,R[70]=i.y,R[71]=a.z,l.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:R})),c.normal){var A=new Float32Array(72);A[0]=0,A[1]=0,A[2]=1,A[3]=0,A[4]=0,A[5]=1,A[6]=0,A[7]=0,A[8]=1,A[9]=0,A[10]=0,A[11]=1,A[12]=0,A[13]=0,A[14]=-1,A[15]=0,A[16]=0,A[17]=-1,A[18]=0,A[19]=0,A[20]=-1,A[21]=0,A[22]=0,A[23]=-1,A[24]=1,A[25]=0,A[26]=0,A[27]=1,A[28]=0,A[29]=0,A[30]=1,A[31]=0,A[32]=0,A[33]=1,A[34]=0,A[35]=0,A[36]=-1,A[37]=0,A[38]=0,A[39]=-1,A[40]=0,A[41]=0,A[42]=-1,A[43]=0,A[44]=0,A[45]=-1,A[46]=0,A[47]=0,A[48]=0,A[49]=1,A[50]=0,A[51]=0,A[52]=1,A[53]=0,A[54]=0,A[55]=1,A[56]=0,A[57]=0,A[58]=1,A[59]=0,A[60]=0,A[61]=-1,A[62]=0,A[63]=0,A[64]=-1,A[65]=0,A[66]=0,A[67]=-1,A[68]=0,A[69]=0,A[70]=-1,A[71]=0,l.normal=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:A})}if(c.st){var f=new Float32Array(48);f[0]=0,f[1]=0,f[2]=1,f[3]=0,f[4]=1,f[5]=1,f[6]=0,f[7]=1,f[8]=1,f[9]=0,f[10]=0,f[11]=0,f[12]=0,f[13]=1,f[14]=1,f[15]=1,f[16]=0,f[17]=0,f[18]=1,f[19]=0,f[20]=1,f[21]=1,f[22]=0,f[23]=1,f[24]=1,f[25]=0,f[26]=0,f[27]=0,f[28]=0,f[29]=1,f[30]=1,f[31]=1,f[32]=1,f[33]=0,f[34]=0,f[35]=0,f[36]=0,f[37]=1,f[38]=1,f[39]=1,f[40]=0,f[41]=0,f[42]=1,f[43]=0,f[44]=1,f[45]=1,f[46]=0,f[47]=1,l.st=new u({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:f})}if(c.tangent){var h=new Float32Array(72);h[0]=1,h[1]=0,h[2]=0,h[3]=1,h[4]=0,h[5]=0,h[6]=1,h[7]=0,h[8]=0,h[9]=1,h[10]=0,h[11]=0,h[12]=-1,h[13]=0,h[14]=0,h[15]=-1,h[16]=0,h[17]=0,h[18]=-1,h[19]=0,h[20]=0,h[21]=-1,h[22]=0,h[23]=0,h[24]=0,h[25]=1,h[26]=0,h[27]=0,h[28]=1,h[29]=0,h[30]=0,h[31]=1,h[32]=0,h[33]=0,h[34]=1,h[35]=0,h[36]=0,h[37]=-1,h[38]=0,h[39]=0,h[40]=-1,h[41]=0,h[42]=0,h[43]=-1,h[44]=0,h[45]=0,h[46]=-1,h[47]=0,h[48]=-1,h[49]=0,h[50]=0,h[51]=-1,h[52]=0,h[53]=0,h[54]=-1,h[55]=0,h[56]=0,h[57]=-1,h[58]=0,h[59]=0,h[60]=1,h[61]=0,h[62]=0,h[63]=1,h[64]=0,h[65]=0,h[66]=1,h[67]=0,h[68]=0,h[69]=1,h[70]=0,h[71]=0,l.tangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:h})}if(c.bitangent){var N=new Float32Array(72);N[0]=0,N[1]=1,N[2]=0,N[3]=0,N[4]=1,N[5]=0,N[6]=0,N[7]=1,N[8]=0,N[9]=0,N[10]=1,N[11]=0,N[12]=0,N[13]=1,N[14]=0,N[15]=0,N[16]=1,N[17]=0,N[18]=0,N[19]=1,N[20]=0,N[21]=0,N[22]=1,N[23]=0,N[24]=0,N[25]=0,N[26]=1,N[27]=0,N[28]=0,N[29]=1,N[30]=0,N[31]=0,N[32]=1,N[33]=0,N[34]=0,N[35]=1,N[36]=0,N[37]=0,N[38]=1,N[39]=0,N[40]=0,N[41]=1,N[42]=0,N[43]=0,N[44]=1,N[45]=0,N[46]=0,N[47]=1,N[48]=0,N[49]=0,N[50]=1,N[51]=0,N[52]=0,N[53]=1,N[54]=0,N[55]=0,N[56]=1,N[57]=0,N[58]=0,N[59]=1,N[60]=0,N[61]=0,N[62]=1,N[63]=0,N[64]=0,N[65]=1,N[66]=0,N[67]=0,N[68]=1,N[69]=0,N[70]=0,N[71]=1,l.bitangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:N})}_=new Uint16Array(36),_[0]=0,_[1]=1,_[2]=2,_[3]=0,_[4]=2,_[5]=3,_[6]=6,_[7]=5,_[8]=4,_[9]=7,_[10]=6,_[11]=4,_[12]=8,_[13]=9,_[14]=10,_[15]=8,_[16]=10,_[17]=11,_[18]=14,_[19]=13,_[20]=12,_[21]=15,_[22]=14,_[23]=12,_[24]=18,_[25]=17,_[26]=16,_[27]=19,_[28]=18,_[29]=16,_[30]=20,_[31]=21,_[32]=22,_[33]=20,_[34]=22,_[35]=23}else R=new Float64Array(24),R[0]=i.x,R[1]=i.y,R[2]=i.z,R[3]=a.x,R[4]=i.y,R[5]=i.z,R[6]=a.x,R[7]=a.y,R[8]=i.z,R[9]=i.x,R[10]=a.y,R[11]=i.z,R[12]=i.x,R[13]=i.y,R[14]=a.z,R[15]=a.x,R[16]=i.y,R[17]=a.z,R[18]=a.x,R[19]=a.y,R[20]=a.z,R[21]=i.x,R[22]=a.y,R[23]=a.z,l.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:R}),_=new Uint16Array(36),_[0]=4,_[1]=5,_[2]=6,_[3]=4,_[4]=6,_[5]=7,_[6]=1,_[7]=0,_[8]=3,_[9]=1,_[10]=3,_[11]=2,_[12]=1,_[13]=6,_[14]=5,_[15]=1,_[16]=2,_[17]=6,_[18]=2,_[19]=3,_[20]=7,_[21]=2,_[22]=7,_[23]=6,_[24]=3,_[25]=0,_[26]=4,_[27]=3,_[28]=4,_[29]=7,_[30]=0,_[31]=1,_[32]=5,_[33]=0,_[34]=5,_[35]=4;var d=t.subtract(a,i,T),I=.5*t.magnitude(d);return new o({attributes:l,indices:_,primitiveType:s.TRIANGLES,boundingSphere:new e(t.ZERO,I)})}},_}),define("Workers/createBoxGeometry",["../Core/BoxGeometry","../Core/defined"],function(e,t){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,E=e.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],E=t[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],E=t[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],E=t[a+1],s=t[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],E=t[a+1],s=t[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var m=u.x,O=u.y,M=u.z,y=o;y.x=S.x*m*2,y.y=S.y*O*2,y.z=S.z*M*2;var p,C,U,L,F,P,w,g,x,D,v,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*m),L=1/(1+B*O),F=1/(1+B*M),P=U*U,w=L*L,g=F*F,x=P*U,D=w*L,v=g*F,p=f*P+h*w+N*g-1,C=f*x*m+h*D*O+N*v*M;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*F,s):new t(c*U,_*L,T*F)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(e,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(e,l,A,f,s);if(r(h)){var N=t.multiplyComponents(h,A,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),m=a.sign(t.dot(d,e))*t.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=m,i):new u(I,S,m)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,E,s){"use strict";function c(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,A=new t,f=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=t.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function E(t,e,r,i,a,o,u,E,s){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(A[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,f=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),m=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=I,e[3]=A,e[4]=N,e[5]=S,e[6]=f,e[7]=d,e[8]=m,e):new E(l,A,f,h,N,d,I,S,m)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(e)?(e[0]=c,e[1]=R,e[2]=f,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=A,e[8]=N,e):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,E=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*i-r*_,e[2]=r*u-o*i,e[3]=s*u-a*_,e[4]=n*_-s*i,e[5]=a*i-n*u,e[6]=a*c-s*o,e[7]=s*r-n*c,e[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,E,s){"use strict";function c(t,e,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,A=e.y*e.w,f=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),m=2*(s+h),O=-E+R-f+N,M=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=m*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=M*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,m=r.z,O=u*-I+E*-S+s*-m,M=h*-I+N*-S+d*-m,y=l*I+A*S+f*m;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=M,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,M,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),E=1/(r-n),s=1/(a-i),c=-(e+t)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),E=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,A=a+s,f=o+c,h=e+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},c.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var A=new t;c.getMaximumScale=function(e){return c.getScale(e,A),t.maximumComponent(A)},c.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],A=t[12],f=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],m=e[3],O=e[4],M=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],F=e[11],P=e[12],w=e[13],g=e[14],x=e[15],D=r*d+u*I+_*S+A*m,v=i*d+E*I+T*S+f*m,B=a*d+s*I+R*S+h*m,z=o*d+c*I+l*S+N*m,G=r*O+u*M+_*y+A*p,b=i*O+E*M+T*y+f*p,X=a*O+s*M+R*y+h*p,V=o*O+c*M+l*y+N*p,q=r*C+u*U+_*L+A*F,H=i*C+E*U+T*L+f*F,W=a*C+s*U+R*L+h*F,Y=o*C+c*U+l*L+N*F,k=r*P+u*w+_*g+A*x,K=i*P+E*w+T*g+f*x,Z=a*P+s*w+R*g+h*x,j=o*P+c*w+l*g+N*x;return n[0]=D,n[1]=v,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],A=e[0],f=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],m=e[9],O=e[10],M=e[12],y=e[13],p=e[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,L=a*A+E*f+_*h,F=r*N+o*d+s*I,P=i*N+u*d+c*I,w=a*N+E*d+_*I,g=r*S+o*m+s*O,x=i*S+u*m+c*O,D=a*S+E*m+_*O,v=r*M+o*y+s*p+T,B=i*M+u*y+c*p+R,z=a*M+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=F,n[5]=P,n[6]=w,n[7]=0,n[8]=g,n[9]=x,n[10]=D,n[11]=0,n[12]=v,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],A=e[3],f=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*R+s*l,m=i*T+u*R+c*l,O=a*T+E*R+_*l,M=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=m,n[2]=O,n[3]=0,n[4]=M,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],E=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var f=new t;c.multiplyByUniformScale=function(t,e,n){return f.x=e,f.y=e,f.z=e,c.multiplyByScale(t,f,n)},c.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,E=t[1]*r+t[5]*i+t[9]*a+t[13]*o,s=t[2]*r+t[6]*i+t[10]*a+t[14]*o,c=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,E=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],E=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],A=t[2],f=t[6],S=t[10],m=t[14],O=t[3],M=t[7],y=t[11],p=t[15],C=S*p,U=m*y,L=f*p,F=m*M,P=f*y,w=S*M,g=A*p,x=m*O,D=A*y,v=S*O,B=A*M,z=f*O,G=C*T+F*R+P*l-(U*T+L*R+w*l),b=U*_+g*R+v*l-(C*_+x*R+D*l),X=L*_+x*T+B*l-(F*_+g*T+z*l),V=w*_+D*T+z*R-(P*_+v*T+B*R),q=U*i+L*a+w*o-(C*i+F*a+P*o),H=C*r+x*a+D*o-(U*r+g*a+v*o),W=F*r+g*i+z*o-(L*r+x*i+B*o),Y=P*r+v*i+B*a-(w*r+D*i+z*a);C=a*l,U=o*R,L=i*l,F=o*T,P=i*R,w=a*T,g=r*l,x=o*_,D=r*R,v=a*_,B=r*T,z=i*_;var k=C*M+F*y+P*p-(U*M+L*y+w*p),K=U*O+g*y+v*p-(C*O+x*y+D*p),Z=L*O+x*M+B*p-(F*O+g*M+z*p),j=w*O+D*M+z*y-(P*O+v*M+B*y),Q=L*S+w*m+U*f-(P*m+C*f+F*S),J=D*m+C*A+x*S-(g*S+v*m+U*A),$=g*f+z*m+F*A-(B*m+L*A+x*f),tt=B*S+P*A+v*f-(D*f+z*S+w*A),et=r*G+i*b+a*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return e[0]=n,e[1]=a,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=i,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=A,e[14]=f,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function E(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new E(t,e,i,a)},E.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new E(t,e,i,a)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=i,e.north=c,e):new E(n,s,i,c)},E.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=t.length;l<A;l++){var f=e.cartesianToCartographic(t[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,s=e.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var i=t.east,a=t.west,o=e.east,s=e.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(t,A)&&(o[c]=e.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e,n){this.center=t.clone(i(e,t.ZERO)),this.radius=i(n,0)}var l=new t,A=new t,f=new t,h=new t,N=new t,d=new t,I=new t,S=new t,m=new t,O=new t,M=new t,y=new t,p=4/3*n.PI;R.fromPoints=function(e,n){if(a(n)||(n=new R),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],I),o=t.clone(i,l),u=t.clone(i,A),E=t.clone(i,f),s=t.clone(i,h),c=t.clone(i,N),_=t.clone(i,d),T=e.length;for(r=1;r<T;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var L=t.magnitudeSquared(t.subtract(s,o,S)),F=t.magnitudeSquared(t.subtract(c,u,S)),P=t.magnitudeSquared(t.subtract(_,E,S)),w=o,g=s,x=L;F>x&&(x=F,w=u,g=c),P>x&&(x=P,w=E,g=_);var D=m;D.x=.5*(w.x+g.x),D.y=.5*(w.y+g.y),D.z=.5*(w.z+g.z);var v=t.magnitudeSquared(t.subtract(g,D,S)),B=Math.sqrt(v),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=M;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,S));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(i,D,S));if(q>v){var H=Math.sqrt(q);B=.5*(B+H),v=B*B;var W=H-B;D.x=(B*D.x+W*i.x)/H,D.y=(B*D.y+W*i.y)/H,D.z=(B*D.z+W*i.z)/H}}return B<X?(t.clone(D,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,L=new t,F=new e,P=new e;R.fromRectangle2D=function(t,e,n){return R.fromRectangleWithHeights2D(t,e,0,0,n)},R.fromRectangleWithHeights2D=function(e,n,r,o,u){if(a(u)||(u=new R),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=i(n,C),T.southwest(e,F),F.height=r,T.northeast(e,P),P.height=o;var E=n.project(F,U),s=n.project(P,L),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*_,A.z=E.z+.5*l,u};var w=[];R.fromRectangle3D=function(e,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new R),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,w);return R.fromPoints(E,u)},R.fromVertices=function(e,n,r,o){if(a(o)||(o=new R),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=i(n,t.ZERO),r=i(r,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,l),c=t.clone(u,A),_=t.clone(u,f),T=t.clone(u,h),p=t.clone(u,N),C=t.clone(u,d),U=e.length;for(E=0;E<U;E+=r){var L=e[E]+n.x,F=e[E+1]+n.y,P=e[E+2]+n.z;u.x=L,u.y=F,u.z=P,L<s.x&&t.clone(u,s),L>T.x&&t.clone(u,T),F<c.y&&t.clone(u,c),F>p.y&&t.clone(u,p),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(T,s,S)),g=t.magnitudeSquared(t.subtract(p,c,S)),x=t.magnitudeSquared(t.subtract(C,_,S)),D=s,v=T,B=w;g>B&&(B=g,D=c,v=p),x>B&&(B=x,D=_,v=C);var z=m;z.x=.5*(D.x+v.x),z.y=.5*(D.y+v.y),z.z=.5*(D.z+v.z);var G=t.magnitudeSquared(t.subtract(v,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=M;V.x=T.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,S));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},R.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new R),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=I;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,l),E=t.clone(i,A),s=t.clone(i,f),c=t.clone(i,h),_=t.clone(i,N),T=t.clone(i,d),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),L<s.z&&t.clone(i,s),L>T.z&&t.clone(i,T)}var F=t.magnitudeSquared(t.subtract(c,u,S)),P=t.magnitudeSquared(t.subtract(_,E,S)),w=t.magnitudeSquared(t.subtract(T,s,S)),g=u,x=c,D=F;P>D&&(D=P,g=E,x=_),w>D&&(D=w,g=s,x=T);var v=m;v.x=.5*(g.x+x.x),v.y=.5*(g.y+x.y),v.z=.5*(g.z+x.z);var B=t.magnitudeSquared(t.subtract(x,v,S)),z=Math.sqrt(B),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=M;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,X,S));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(i,v,S));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;v.x=(z*v.x+Y*i.x)/W,v.y=(z*v.y+Y*i.y)/W,v.z=(z*v.z+Y*i.z)/W}}return z<V?(t.clone(v,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(e,n,r){a(r)||(r=new R);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},R.fromEllipsoid=function(e,n){return a(n)||(n=new R),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var g=new t;R.fromBoundingSpheres=function(e,n){if(a(n)||(n=new R),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return R.clone(e[0],n);if(2===r)return R.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,g)+s.radius)}return n.radius=E,n};var x=new t,D=new t,v=new t;R.fromOrientedBoundingBox=function(e,n){a(n)||(n=new R);var r=e.halfAxes,i=c.getColumn(r,0,x),o=c.getColumn(r,1,D),u=c.getColumn(r,2,v);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},R.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new R(e.center,e.radius)},R.packedLength=4,R.pack=function(t,e,n){n=i(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},R.unpack=function(t,e,n){e=i(e,0),a(n)||(n=new R);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var B=new t,z=new t;R.union=function(e,n,r){a(r)||(r=new R);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,B),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,i,T),t.clone(T,r.center),r.radius=_,r};var G=new t;R.expand=function(e,n,r){r=R.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},R.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},R.transform=function(t,e,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;R.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},R.transformWithoutScale=function(t,e,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;R.computePlaneDistances=function(e,n,r,i){a(i)||(i=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var V=new t,q=new t,H=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return R.projectTo2D=function(e,n,r){n=i(n,j);var a=n.ellipsoid,o=e.center,u=e.radius,E=a.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,q);t.normalize(s,s);var c=t.cross(E,s,H);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),l=K,A=l[0];t.add(E,c,A),t.add(A,s,A),A=l[1],t.add(E,c,A),t.add(A,T,A),A=l[2],t.add(E,_,A),t.add(A,T,A),A=l[3],t.add(E,_,A),t.add(A,s,A),t.negate(E,E),A=l[4],t.add(E,c,A),t.add(A,s,A),A=l[5],t.add(E,c,A),t.add(A,T,A),A=l[6],t.add(E,_,A),t.add(A,T,A),A=l[7],t.add(E,_,A),t.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];t.add(o,N,N);var d=a.cartesianToCartographic(N,k);n.project(d,N)}r=R.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,m=o.z;return o.x=m,o.y=I,o.z=S,r},R.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},R.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},R.prototype.intersectPlane=function(t){return R.intersectPlane(this,t)},R.prototype.distanceSquaredTo=function(t){return R.distanceSquaredTo(this,t)},R.prototype.computePlaneDistances=function(t,e,n){return R.computePlaneDistances(this,t,e,n)},R.prototype.isOccluded=function(t){return R.isOccluded(this,t)},R.prototype.equals=function(t){return R.equals(this,t)},R.prototype.clone=function(t){return R.clone(this,t)},R.prototype.volume=function(){var t=this.radius;return p*t*t*t},R}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,m=r(t[1]))}return S}function a(){return i()&&m}function o(){if(!e(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,M=r(t[1]))}return O}function u(){return o()&&M}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0, +p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(L=!0,F=r(t[1]))}return L}function R(){return T()&&F}function l(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(P=!0,w=r(t[1]))}return P}function A(){return e(g)||(g=/Windows/i.test(I.appVersion)),g}function f(){return l()&&w}function h(){return e(x)||(x="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),x}function N(){if(!e(v)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;v=e(n)&&""!==n,v&&(D=n)}return v}function d(){return N()?D:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,m,O,M,y,p,C,U,L,F,P,w,g,x,D,v,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},i.unpack=function(n,r,a){return r=t(r,0),e(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(t,n){if(e(t))return e(n)||(n=new i),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},i}),define("Core/BoxGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType","./VertexFormat"],function(t,e,n,r,i,a,o,u,E,s,c){"use strict";function _(t){t=i(t,i.EMPTY_OBJECT);var n=t.minimum,r=t.maximum,a=i(t.vertexFormat,c.DEFAULT);this._minimum=e.clone(n),this._maximum=e.clone(r),this._vertexFormat=a,this._workerName="createBoxGeometry"}var T=new e;_.fromDimensions=function(t){t=i(t,i.EMPTY_OBJECT);var n=t.dimensions,r=e.multiplyByScalar(n,.5,new e);return new _({minimum:e.negate(r,new e),maximum:r,vertexFormat:t.vertexFormat})},_.fromAxisAlignedBoundingBox=function(t){return new _({minimum:t.minimum,maximum:t.maximum})},_.packedLength=2*e.packedLength+c.packedLength,_.pack=function(t,n,r){return r=i(r,0),e.pack(t._minimum,n,r),e.pack(t._maximum,n,r+e.packedLength),c.pack(t._vertexFormat,n,r+2*e.packedLength),n};var R=new e,l=new e,A=new c,f={minimum:R,maximum:l,vertexFormat:A};_.unpack=function(t,n,r){n=i(n,0);var o=e.unpack(t,n,R),u=e.unpack(t,n+e.packedLength,l),E=c.unpack(t,n+2*e.packedLength,A);return a(r)?(r._minimum=e.clone(o,r._minimum),r._maximum=e.clone(u,r._maximum),r._vertexFormat=c.clone(E,r._vertexFormat),r):new _(f)},_.createGeometry=function(n){var i=n._minimum,a=n._maximum,c=n._vertexFormat;if(!e.equals(i,a)){var _,R,l=new E;if(c.position&&(c.st||c.normal||c.tangent||c.bitangent)){if(c.position&&(R=new Float64Array(72),R[0]=i.x,R[1]=i.y,R[2]=a.z,R[3]=a.x,R[4]=i.y,R[5]=a.z,R[6]=a.x,R[7]=a.y,R[8]=a.z,R[9]=i.x,R[10]=a.y,R[11]=a.z,R[12]=i.x,R[13]=i.y,R[14]=i.z,R[15]=a.x,R[16]=i.y,R[17]=i.z,R[18]=a.x,R[19]=a.y,R[20]=i.z,R[21]=i.x,R[22]=a.y,R[23]=i.z,R[24]=a.x,R[25]=i.y,R[26]=i.z,R[27]=a.x,R[28]=a.y,R[29]=i.z,R[30]=a.x,R[31]=a.y,R[32]=a.z,R[33]=a.x,R[34]=i.y,R[35]=a.z,R[36]=i.x,R[37]=i.y,R[38]=i.z,R[39]=i.x,R[40]=a.y,R[41]=i.z,R[42]=i.x,R[43]=a.y,R[44]=a.z,R[45]=i.x,R[46]=i.y,R[47]=a.z,R[48]=i.x,R[49]=a.y,R[50]=i.z,R[51]=a.x,R[52]=a.y,R[53]=i.z,R[54]=a.x,R[55]=a.y,R[56]=a.z,R[57]=i.x,R[58]=a.y,R[59]=a.z,R[60]=i.x,R[61]=i.y,R[62]=i.z,R[63]=a.x,R[64]=i.y,R[65]=i.z,R[66]=a.x,R[67]=i.y,R[68]=a.z,R[69]=i.x,R[70]=i.y,R[71]=a.z,l.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:R})),c.normal){var A=new Float32Array(72);A[0]=0,A[1]=0,A[2]=1,A[3]=0,A[4]=0,A[5]=1,A[6]=0,A[7]=0,A[8]=1,A[9]=0,A[10]=0,A[11]=1,A[12]=0,A[13]=0,A[14]=-1,A[15]=0,A[16]=0,A[17]=-1,A[18]=0,A[19]=0,A[20]=-1,A[21]=0,A[22]=0,A[23]=-1,A[24]=1,A[25]=0,A[26]=0,A[27]=1,A[28]=0,A[29]=0,A[30]=1,A[31]=0,A[32]=0,A[33]=1,A[34]=0,A[35]=0,A[36]=-1,A[37]=0,A[38]=0,A[39]=-1,A[40]=0,A[41]=0,A[42]=-1,A[43]=0,A[44]=0,A[45]=-1,A[46]=0,A[47]=0,A[48]=0,A[49]=1,A[50]=0,A[51]=0,A[52]=1,A[53]=0,A[54]=0,A[55]=1,A[56]=0,A[57]=0,A[58]=1,A[59]=0,A[60]=0,A[61]=-1,A[62]=0,A[63]=0,A[64]=-1,A[65]=0,A[66]=0,A[67]=-1,A[68]=0,A[69]=0,A[70]=-1,A[71]=0,l.normal=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:A})}if(c.st){var f=new Float32Array(48);f[0]=0,f[1]=0,f[2]=1,f[3]=0,f[4]=1,f[5]=1,f[6]=0,f[7]=1,f[8]=1,f[9]=0,f[10]=0,f[11]=0,f[12]=0,f[13]=1,f[14]=1,f[15]=1,f[16]=0,f[17]=0,f[18]=1,f[19]=0,f[20]=1,f[21]=1,f[22]=0,f[23]=1,f[24]=1,f[25]=0,f[26]=0,f[27]=0,f[28]=0,f[29]=1,f[30]=1,f[31]=1,f[32]=1,f[33]=0,f[34]=0,f[35]=0,f[36]=0,f[37]=1,f[38]=1,f[39]=1,f[40]=0,f[41]=0,f[42]=1,f[43]=0,f[44]=1,f[45]=1,f[46]=0,f[47]=1,l.st=new u({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:f})}if(c.tangent){var h=new Float32Array(72);h[0]=1,h[1]=0,h[2]=0,h[3]=1,h[4]=0,h[5]=0,h[6]=1,h[7]=0,h[8]=0,h[9]=1,h[10]=0,h[11]=0,h[12]=-1,h[13]=0,h[14]=0,h[15]=-1,h[16]=0,h[17]=0,h[18]=-1,h[19]=0,h[20]=0,h[21]=-1,h[22]=0,h[23]=0,h[24]=0,h[25]=1,h[26]=0,h[27]=0,h[28]=1,h[29]=0,h[30]=0,h[31]=1,h[32]=0,h[33]=0,h[34]=1,h[35]=0,h[36]=0,h[37]=-1,h[38]=0,h[39]=0,h[40]=-1,h[41]=0,h[42]=0,h[43]=-1,h[44]=0,h[45]=0,h[46]=-1,h[47]=0,h[48]=-1,h[49]=0,h[50]=0,h[51]=-1,h[52]=0,h[53]=0,h[54]=-1,h[55]=0,h[56]=0,h[57]=-1,h[58]=0,h[59]=0,h[60]=1,h[61]=0,h[62]=0,h[63]=1,h[64]=0,h[65]=0,h[66]=1,h[67]=0,h[68]=0,h[69]=1,h[70]=0,h[71]=0,l.tangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:h})}if(c.bitangent){var N=new Float32Array(72);N[0]=0,N[1]=1,N[2]=0,N[3]=0,N[4]=1,N[5]=0,N[6]=0,N[7]=1,N[8]=0,N[9]=0,N[10]=1,N[11]=0,N[12]=0,N[13]=1,N[14]=0,N[15]=0,N[16]=1,N[17]=0,N[18]=0,N[19]=1,N[20]=0,N[21]=0,N[22]=1,N[23]=0,N[24]=0,N[25]=0,N[26]=1,N[27]=0,N[28]=0,N[29]=1,N[30]=0,N[31]=0,N[32]=1,N[33]=0,N[34]=0,N[35]=1,N[36]=0,N[37]=0,N[38]=1,N[39]=0,N[40]=0,N[41]=1,N[42]=0,N[43]=0,N[44]=1,N[45]=0,N[46]=0,N[47]=1,N[48]=0,N[49]=0,N[50]=1,N[51]=0,N[52]=0,N[53]=1,N[54]=0,N[55]=0,N[56]=1,N[57]=0,N[58]=0,N[59]=1,N[60]=0,N[61]=0,N[62]=1,N[63]=0,N[64]=0,N[65]=1,N[66]=0,N[67]=0,N[68]=1,N[69]=0,N[70]=0,N[71]=1,l.bitangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:N})}_=new Uint16Array(36),_[0]=0,_[1]=1,_[2]=2,_[3]=0,_[4]=2,_[5]=3,_[6]=6,_[7]=5,_[8]=4,_[9]=7,_[10]=6,_[11]=4,_[12]=8,_[13]=9,_[14]=10,_[15]=8,_[16]=10,_[17]=11,_[18]=14,_[19]=13,_[20]=12,_[21]=15,_[22]=14,_[23]=12,_[24]=18,_[25]=17,_[26]=16,_[27]=19,_[28]=18,_[29]=16,_[30]=20,_[31]=21,_[32]=22,_[33]=20,_[34]=22,_[35]=23}else R=new Float64Array(24),R[0]=i.x,R[1]=i.y,R[2]=i.z,R[3]=a.x,R[4]=i.y,R[5]=i.z,R[6]=a.x,R[7]=a.y,R[8]=i.z,R[9]=i.x,R[10]=a.y,R[11]=i.z,R[12]=i.x,R[13]=i.y,R[14]=a.z,R[15]=a.x,R[16]=i.y,R[17]=a.z,R[18]=a.x,R[19]=a.y,R[20]=a.z,R[21]=i.x,R[22]=a.y,R[23]=a.z,l.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:R}),_=new Uint16Array(36),_[0]=4,_[1]=5,_[2]=6,_[3]=4,_[4]=6,_[5]=7,_[6]=1,_[7]=0,_[8]=3,_[9]=1,_[10]=3,_[11]=2,_[12]=1,_[13]=6,_[14]=5,_[15]=1,_[16]=2,_[17]=6,_[18]=2,_[19]=3,_[20]=7,_[21]=2,_[22]=7,_[23]=6,_[24]=3,_[25]=0,_[26]=4,_[27]=3,_[28]=4,_[29]=7,_[30]=0,_[31]=1,_[32]=5,_[33]=0,_[34]=5,_[35]=4;var d=e.subtract(a,i,T),I=.5*e.magnitude(d);return new o({attributes:l,indices:_,primitiveType:s.TRIANGLES,boundingSphere:new t(e.ZERO,I)})}};var h;return _.getUnitBox=function(){return a(h)||(h=_.createGeometry(_.fromDimensions({dimensions:new e(1,1,1),vertexFormat:c.POSITION_ONLY}))),h},_}),define("Workers/createBoxGeometry",["../Core/BoxGeometry","../Core/defined"],function(t,e){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxOutlineGeometry.js index 66d4f419..f8c47341 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createBoxOutlineGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(e),T.y=s*Math.sin(e),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,B,g,D,v,x=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{x-=z,U=1/(1+x*M),L=1/(1+x*O),P=1/(1+x*m),F=U*U,w=L*L,B=P*P,g=F*U,D=w*L,v=B*P,p=f*F+h*w+N*B-1,C=f*g*M+h*D*O+N*v*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*L,s.z=T*P,s):new e(c*U,_*L,T*P)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),T=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var T=new e,R=new e;_.prototype.cartographicToCartesian=function(t,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(e[E.getElementIndex(T,_)])>n){var R,f=e[E.getElementIndex(T,T)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(T,T)]=s,t[E.getElementIndex(T,_)]=c,t[E.getElementIndex(_,T)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,T=e.z*e.w,R=e.w*e.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=M,t):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=R,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=T,t[7]=A,t[8]=N,t):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],T)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),T=t.diagonal=E.clone(e,t.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],T=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(t,R,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,T=t.x*t.w,R=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,T=new e,R=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,T),T),e.normalize(e.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),T=s,R=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],T=e[9],R=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],L=t[10],P=t[11],F=t[12],w=t[13],B=t[14],g=t[15],D=r*d+u*I+_*S+A*M,v=i*d+E*I+T*S+f*M,x=a*d+s*I+R*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+A*p,b=i*O+E*m+T*y+f*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+A*P,H=i*C+E*U+T*L+f*P,W=a*C+s*U+R*L+h*P,Y=o*C+c*U+l*L+N*P,k=r*F+u*w+_*B+A*g,K=i*F+E*w+T*B+f*g,Z=a*F+s*w+R*B+h*g,j=o*F+c*w+l*B+N*g;return n[0]=D,n[1]=v,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=e[12],R=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,L=a*A+E*f+_*h,P=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,B=r*S+o*M+s*O,g=i*S+u*M+c*O,D=a*S+E*M+_*O,v=r*m+o*y+s*p+T,x=i*m+u*y+c*p+R,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=B,n[9]=g,n[10]=D,n[11]=0,n[12]=v,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=t[0],R=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],T=e[5],R=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,L=f*p,P=M*m,F=f*y,w=S*m,B=A*p,g=M*O,D=A*y,v=S*O,x=A*m,z=f*O,G=C*T+P*R+F*l-(U*T+L*R+w*l),b=U*_+B*R+v*l-(C*_+g*R+D*l),X=L*_+g*T+x*l-(P*_+B*T+z*l),V=w*_+D*T+z*R-(F*_+v*T+x*R),q=U*i+L*a+w*o-(C*i+P*a+F*o),H=C*r+g*a+D*o-(U*r+B*a+v*o),W=P*r+B*i+z*o-(L*r+g*i+x*o),Y=F*r+v*i+x*a-(w*r+D*i+z*a);C=a*l,U=o*R,L=i*l,P=o*T,F=i*R,w=a*T,B=r*l,g=o*_,D=r*R,v=a*_,x=r*T,z=i*_;var k=C*m+P*y+F*p-(U*m+L*y+w*p),K=U*O+B*y+v*p-(C*O+g*y+D*p),Z=L*O+g*m+x*p-(P*O+B*m+z*p),j=w*O+D*m+z*y-(F*O+v*m+x*y),Q=L*S+w*M+U*f-(F*M+C*f+P*S),J=D*M+C*A+g*S-(B*S+v*M+U*A),$=B*f+z*M+P*A-(x*M+L*A+g*f),ee=x*S+F*A+v*f-(D*f+z*S+w*A),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=q*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],T=e[13],R=e[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=e.length;_<T;_++){var R=e[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var T=Math.max(e.south,t.south),R=Math.min(e.north,t.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,T=e.south,R=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function T(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var R=new e,l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e;T.fromPoints=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],d),o=e.clone(a,R),u=e.clone(a,l),E=e.clone(a,A),s=e.clone(a,f),c=e.clone(a,h),_=e.clone(a,N),y=t.length;for(r=1;r<y;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var L=e.magnitudeSquared(e.subtract(s,o,I)),P=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),w=o,B=s,g=L;P>g&&(g=P,w=u,B=c),F>g&&(g=F,w=E,B=_);var D=S;D.x=.5*(w.x+B.x),D.y=.5*(w.y+B.y),D.z=.5*(w.z+B.z);var v=e.magnitudeSquared(e.subtract(B,D,I)),x=Math.sqrt(v),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,I),.5,m),X=0;for(r=0;r<y;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,I));V>X&&(X=V);var q=e.magnitudeSquared(e.subtract(a,D,I));if(q>v){var H=Math.sqrt(q);x=.5*(x+H),v=x*x;var W=H-x;D.x=(x*D.x+W*a.x)/H,D.y=(x*D.y+W*a.y)/H,D.z=(x*D.z+W*a.z)/H}}return x<X?(e.clone(D,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var y=new o,p=new e,C=new e,U=new t,L=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(t,U),U.height=a,_.northeast(t,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*R,A.z=E.z+.5*l,u};var P=[];T.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,P);return T.fromPoints(E,u)},T.fromVertices=function(t,n,a,o){if(i(o)||(o=new T),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=d;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,R),c=e.clone(u,l),_=e.clone(u,A),y=e.clone(u,f),p=e.clone(u,h),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=a){var L=t[E]+n.x,P=t[E+1]+n.y,F=t[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&e.clone(u,s),L>y.x&&e.clone(u,y),P<c.y&&e.clone(u,c),P>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(y,s,I)),B=e.magnitudeSquared(e.subtract(p,c,I)),g=e.magnitudeSquared(e.subtract(C,_,I)),D=s,v=y,x=w;B>x&&(x=B,D=c,v=p),g>x&&(x=g,D=_,v=C);var z=S;z.x=.5*(D.x+v.x),z.y=.5*(D.y+v.y),z.z=.5*(D.z+v.z);var G=e.magnitudeSquared(e.subtract(v,z,I)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var q=e.multiplyByScalar(e.add(X,V,I),.5,m),H=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,q,I));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new T),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=d;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,R),E=e.clone(a,l),s=e.clone(a,A),c=e.clone(a,f),_=e.clone(a,h),y=e.clone(a,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],L=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),L<s.z&&e.clone(a,s),L>y.z&&e.clone(a,y)}var P=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),w=e.magnitudeSquared(e.subtract(y,s,I)),B=u,g=c,D=P;F>D&&(D=F,B=E,g=_),w>D&&(D=w,B=s,g=y);var v=S;v.x=.5*(B.x+g.x),v.y=.5*(B.y+g.y),v.z=.5*(B.z+g.z);var x=e.magnitudeSquared(e.subtract(g,v,I)),z=Math.sqrt(x),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=e.multiplyByScalar(e.add(G,b,I),.5,m),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var q=e.magnitude(e.subtract(a,X,I));q>V&&(V=q);var H=e.magnitudeSquared(e.subtract(a,v,I));if(H>x){var W=Math.sqrt(H);z=.5*(z+W),x=z*z;var Y=W-z;v.x=(z*v.x+Y*a.x)/W,v.y=(z*v.y+Y*a.y)/W,v.z=(z*v.z+Y*a.z)/W}}return z<V?(e.clone(v,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){i(r)||(r=new T);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},T.fromEllipsoid=function(t,n){return i(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var F=new e;T.fromBoundingSpheres=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var w=new e,B=new e,g=new e;T.fromOrientedBoundingBox=function(t,n){i(n)||(n=new T);var r=t.halfAxes,a=s.getColumn(r,0,w),o=s.getColumn(r,1,B),u=s.getColumn(r,2,g);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},T.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new T);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var D=new e,v=new e;T.union=function(t,n,r){i(r)||(r=new T);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,D),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,v);return e.add(R,a,R),e.clone(R,r.center),r.radius=_,r};var x=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,x));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},T.transform=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;T.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,q=new e,H=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return T.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,H),R=e.negate(s,q),l=Y,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,R,A),A=l[2],e.add(E,_,A),e.add(A,R,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,R,A),A=l[6],e.add(E,_,A),e.add(A,R,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,W);n.project(d,N)}i=T.fromPoints(l,i),o=i.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,i},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!T())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0,p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function T(){if(!t(L)){L=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,P=r(e[1]))}return L}function R(){return T()&&P}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function A(){return t(B)||(B=/Windows/i.test(I.appVersion)),B}function f(){return l()&&w}function h(){return t(g)||(g="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),g}function N(){if(!t(v)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;v=t(n)&&""!==n,v&&(D=n)}return v}function d(){return N()?D:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,B,g,D,v,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/BoxOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e){e=i(e,i.EMPTY_OBJECT);var n=e.minimum,r=e.maximum;this._min=t.clone(n),this._max=t.clone(r),this._workerName="createBoxOutlineGeometry"}var _=new t;c.fromDimensions=function(e){e=i(e,i.EMPTY_OBJECT);var n=e.dimensions,r=t.multiplyByScalar(n,.5,new t);return new c({minimum:t.negate(r,new t),maximum:r})},c.fromAxisAlignedBoundingBox=function(e){return new c({minimum:e.minimum,maximum:e.maximum})},c.packedLength=2*t.packedLength,c.pack=function(e,n,r){return r=i(r,0),t.pack(e._min,n,r),t.pack(e._max,n,r+t.packedLength),n};var T=new t,R=new t,l={minimum:T,maximum:R};return c.unpack=function(e,n,r){n=i(n,0);var o=t.unpack(e,n,T),u=t.unpack(e,n+t.packedLength,R);return a(r)?(r._min=t.clone(o,r._min),r._max=t.clone(u,r._max),r):new c(l)},c.createGeometry=function(n){var i=n._min,a=n._max;if(!t.equals(i,a)){var c=new E,T=new Uint16Array(24),R=new Float64Array(24);R[0]=i.x,R[1]=i.y,R[2]=i.z,R[3]=a.x,R[4]=i.y,R[5]=i.z,R[6]=a.x,R[7]=a.y,R[8]=i.z,R[9]=i.x,R[10]=a.y,R[11]=i.z,R[12]=i.x,R[13]=i.y,R[14]=a.z,R[15]=a.x,R[16]=i.y,R[17]=a.z,R[18]=a.x,R[19]=a.y,R[20]=a.z,R[21]=i.x,R[22]=a.y,R[23]=a.z,c.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:R}),T[0]=4,T[1]=5,T[2]=5,T[3]=6,T[4]=6,T[5]=7,T[6]=7,T[7]=4,T[8]=0,T[9]=1,T[10]=1,T[11]=2,T[12]=2,T[13]=3,T[14]=3,T[15]=0,T[16]=0,T[17]=4,T[18]=1,T[19]=5,T[20]=2,T[21]=6,T[22]=3,T[23]=7;var l=t.subtract(a,i,_),A=.5*t.magnitude(l);return new o({attributes:c,indices:T,primitiveType:s.LINES,boundingSphere:new e(t.ZERO,A)})}},c}),define("Workers/createBoxOutlineGeometry",["../Core/BoxOutlineGeometry","../Core/defined"],function(e,t){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var R=new o,T=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);R.x=s*Math.cos(e),R.y=s*Math.sin(e),R.z=Math.sin(r),R=o.normalize(R,R),o.multiplyComponents(E,R,T);var c=Math.sqrt(o.dot(R,T));return T=o.divideByScalar(T,c,T),R=o.multiplyByScalar(R,i,R),n(u)||(u=new o),o.add(T,R,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,R=n.z,T=i.x,l=i.y,A=i.z,f=c*c*T*T,h=_*_*l*l,N=R*R*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,B,g,D,v,x=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{x-=z,U=1/(1+x*M),L=1/(1+x*O),P=1/(1+x*m),F=U*U,w=L*L,B=P*P,g=F*U,D=w*L,v=B*P,p=f*F+h*w+N*B-1,C=f*g*M+h*D*O+N*v*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*L,s.z=R*P,s):new e(c*U,_*L,R*P)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),R=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:R,f=r(n)?n._centerToleranceSquared:T,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var R=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=R,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],R=A[i];if(Math.abs(e[E.getElementIndex(R,_)])>n){var T,f=e[E.getElementIndex(R,R)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(R,_)],d=(f-h)/2/N;T=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+T*T),c=T*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(R,R)]=s,t[E.getElementIndex(R,_)]=c,t[E.getElementIndex(_,R)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,R=e.z*e.w,T=e.w*e.w,l=n-u-_+T,A=2*(i-R),f=2*(a+c),h=2*(i+R),N=-n+u-_+T,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+T;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=M,t):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,R=s*u+a*o*i,T=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=R,t[7]=A,t[8]=N,t):new E(c,_,R,T,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var R=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],R)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],R)),n};var T=new e;E.getMaximumScale=function(t){return E.getScale(t,T),e.maximumComponent(T)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),R=t.diagonal=E.clone(e,t.diagonal),T=n*s(R);a<10&&c(R)>T;)_(R,f),E.transpose(f,h),E.multiply(R,f,R),E.multiply(h,R,R),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],R=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var T=1/R;return E.multiplyByScalar(t,T,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,R,T,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(R,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,R=t.x*t.w,T=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-T-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+T-f+N,m=2*(l-R),y=2*(_-A),p=2*(l+R),C=-E-T+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,R=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,R),R),e.normalize(e.cross(R,_,T),T);var u=R.x,E=R.y,s=R.z,l=_.x,A=_.y,f=_.z,h=T.x,N=T.y,d=T.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,R=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=R,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),R=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=R,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),R=s,T=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=R,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],R=e[9],T=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],L=t[10],P=t[11],F=t[12],w=t[13],B=t[14],g=t[15],D=r*d+u*I+_*S+A*M,v=i*d+E*I+R*S+f*M,x=a*d+s*I+T*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+A*p,b=i*O+E*m+R*y+f*p,X=a*O+s*m+T*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+A*P,H=i*C+E*U+R*L+f*P,W=a*C+s*U+T*L+h*P,Y=o*C+c*U+l*L+N*P,k=r*F+u*w+_*B+A*g,K=i*F+E*w+R*B+f*g,Z=a*F+s*w+T*B+h*g,j=o*F+c*w+l*B+N*g;return n[0]=D,n[1]=v,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],R=e[12],T=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,L=a*A+E*f+_*h,P=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,B=r*S+o*M+s*O,g=i*S+u*M+c*O,D=a*S+E*M+_*O,v=r*m+o*y+s*p+R,x=i*m+u*y+c*p+T,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=B,n[9]=g,n[10]=D,n[11]=0,n[12]=v,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],R=t[0],T=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*R+o*T+s*l,M=i*R+u*T+c*l,O=a*R+E*T+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],R=e[5],T=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,L=f*p,P=M*m,F=f*y,w=S*m,B=A*p,g=M*O,D=A*y,v=S*O,x=A*m,z=f*O,G=C*R+P*T+F*l-(U*R+L*T+w*l),b=U*_+B*T+v*l-(C*_+g*T+D*l),X=L*_+g*R+x*l-(P*_+B*R+z*l),V=w*_+D*R+z*T-(F*_+v*R+x*T),q=U*i+L*a+w*o-(C*i+P*a+F*o),H=C*r+g*a+D*o-(U*r+B*a+v*o),W=P*r+B*i+z*o-(L*r+g*i+x*o),Y=F*r+v*i+x*a-(w*r+D*i+z*a);C=a*l,U=o*T,L=i*l,P=o*R,F=i*T,w=a*R,B=r*l,g=o*_,D=r*T,v=a*_,x=r*R,z=i*_;var k=C*m+P*y+F*p-(U*m+L*y+w*p),K=U*O+B*y+v*p-(C*O+g*y+D*p),Z=L*O+g*m+x*p-(P*O+B*m+z*p),j=w*O+D*m+z*y-(F*O+v*m+x*y),Q=L*S+w*M+U*f-(F*M+C*f+P*S),J=D*M+C*A+g*S-(B*S+v*M+U*A),$=B*f+z*M+P*A-(x*M+L*A+g*f),ee=x*S+F*A+v*f-(D*f+z*S+w*A),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=q*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],R=e[13],T=e[14],l=-n*_-r*R-i*T,A=-a*_-o*R-u*T,f=-E*_-s*R-c*T;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,R=e.length;_<R;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),s=Math.min(s,T.latitude),c=Math.max(c,T.latitude);var l=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=Number.MAX_VALUE,T=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),R=Math.min(R,f.latitude),T=Math.max(T,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=R,i.east=s,i.north=T,i):new E(o,R,s,T)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var R=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(R>=T))return r(n)?(n.west=c,n.south=R,n.east=_,n.north=T,n):new E(c,R,_,T)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,R=e.south,T=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:R>0?R:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_,R){"use strict";function T(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e,y=new e,p=4/3*n.PI;T.fromPoints=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],I),o=e.clone(i,l),u=e.clone(i,A),E=e.clone(i,f),s=e.clone(i,h),c=e.clone(i,N),_=e.clone(i,d),R=t.length;for(r=1;r<R;r++){e.clone(t[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&e.clone(i,o),p>s.x&&e.clone(i,s),C<u.y&&e.clone(i,u),C>c.y&&e.clone(i,c),U<E.z&&e.clone(i,E),U>_.z&&e.clone(i,_)}var L=e.magnitudeSquared(e.subtract(s,o,S)),P=e.magnitudeSquared(e.subtract(c,u,S)),F=e.magnitudeSquared(e.subtract(_,E,S)),w=o,B=s,g=L;P>g&&(g=P,w=u,B=c),F>g&&(g=F,w=E,B=_);var D=M;D.x=.5*(w.x+B.x),D.y=.5*(w.y+B.y),D.z=.5*(w.z+B.z);var v=e.magnitudeSquared(e.subtract(B,D,S)),x=Math.sqrt(v),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=m;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,S),.5,y),X=0;for(r=0;r<R;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,b,S));V>X&&(X=V);var q=e.magnitudeSquared(e.subtract(i,D,S));if(q>v){var H=Math.sqrt(q);x=.5*(x+H),v=x*x;var W=H-x;D.x=(x*D.x+W*i.x)/H,D.y=(x*D.y+W*i.y)/H,D.z=(x*D.z+W*i.z)/H}}return x<X?(e.clone(D,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var C=new u,U=new e,L=new e,P=new t,F=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,C),R.southwest(t,P),P.height=r,R.northeast(t,F),F.height=o;var E=n.project(P,U),s=n.project(F,L),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*_,A.z=E.z+.5*l,u};var w=[];T.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=R.subsample(t,n,r,w);return T.fromPoints(E,u)},T.fromVertices=function(t,n,r,o){if(a(o)||(o=new T),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=I;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,l),c=e.clone(u,A),_=e.clone(u,f),R=e.clone(u,h),p=e.clone(u,N),C=e.clone(u,d),U=t.length;for(E=0;E<U;E+=r){var L=t[E]+n.x,P=t[E+1]+n.y,F=t[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&e.clone(u,s),L>R.x&&e.clone(u,R),P<c.y&&e.clone(u,c),P>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(R,s,S)),B=e.magnitudeSquared(e.subtract(p,c,S)),g=e.magnitudeSquared(e.subtract(C,_,S)),D=s,v=R,x=w;B>x&&(x=B,D=c,v=p),g>x&&(x=g,D=_,v=C);var z=M;z.x=.5*(D.x+v.x),z.y=.5*(D.y+v.y),z.z=.5*(D.z+v.z);var G=e.magnitudeSquared(e.subtract(v,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=R.x,V.y=p.y,V.z=C.z;var q=e.multiplyByScalar(e.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,q,S));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new T),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=I;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,l),E=e.clone(i,A),s=e.clone(i,f),c=e.clone(i,h),_=e.clone(i,N),R=e.clone(i,d),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],L=t[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&e.clone(i,u),C>c.x&&e.clone(i,c),U<E.y&&e.clone(i,E),U>_.y&&e.clone(i,_),L<s.z&&e.clone(i,s),L>R.z&&e.clone(i,R)}var P=e.magnitudeSquared(e.subtract(c,u,S)),F=e.magnitudeSquared(e.subtract(_,E,S)),w=e.magnitudeSquared(e.subtract(R,s,S)),B=u,g=c,D=P;F>D&&(D=F,B=E,g=_),w>D&&(D=w,B=s,g=R);var v=M;v.x=.5*(B.x+g.x),v.y=.5*(B.y+g.y),v.z=.5*(B.z+g.z);var x=e.magnitudeSquared(e.subtract(g,v,S)),z=Math.sqrt(x),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=R.z;var X=e.multiplyByScalar(e.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var q=e.magnitude(e.subtract(i,X,S));q>V&&(V=q);var H=e.magnitudeSquared(e.subtract(i,v,S));if(H>x){var W=Math.sqrt(H);z=.5*(z+W),x=z*z;var Y=W-z;v.x=(z*v.x+Y*i.x)/W,v.y=(z*v.y+Y*i.y)/W,v.z=(z*v.z+Y*i.z)/W}}return z<V?(e.clone(v,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){a(r)||(r=new T);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},T.fromEllipsoid=function(t,n){return a(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var B=new e;T.fromBoundingSpheres=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=t[i];E=Math.max(E,e.distance(u,s.center,B)+s.radius)}return n.radius=E,n};var g=new e,D=new e,v=new e;T.fromOrientedBoundingBox=function(t,n){a(n)||(n=new T);var r=t.halfAxes,i=c.getColumn(r,0,g),o=c.getColumn(r,1,D),u=c.getColumn(r,2,v);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},T.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new T);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var x=new e,z=new e;T.union=function(t,n,r){a(r)||(r=new T);var i=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,i,x),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,z);return e.add(R,i,R),e.clone(R,r.center),r.radius=_,r};var G=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},T.transform=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=_.getMaximumScale(t)*e.radius,n};var b=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var X=new e;T.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,X),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,q=new e,H=new e,W=new e,Y=new e,k=new t,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new e;var j=new u;return T.projectTo2D=function(t,n,r){n=i(n,j);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,V),s=e.cross(e.UNIT_Z,E,q);e.normalize(s,s);var c=e.cross(E,s,H);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,Y),R=e.negate(s,W),l=K,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,R,A),A=l[2],e.add(E,_,A),e.add(A,R,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,R,A),A=l[6],e.add(E,_,A),e.add(A,R,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,k);n.project(d,N)}r=T.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T.prototype.volume=function(){var e=this.radius;return p*e*e*e},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!R())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!R()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0, +p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function R(){if(!t(L)){L=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,P=r(e[1]))}return L}function T(){return R()&&P}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function A(){return t(B)||(B=/Windows/i.test(I.appVersion)),B}function f(){return l()&&w}function h(){return t(g)||(g="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),g}function N(){if(!t(v)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;v=t(n)&&""!==n,v&&(D=n)}return v}function d(){return N()?D:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,B,g,D,v,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:R,edgeVersion:T,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/BoxOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e){e=i(e,i.EMPTY_OBJECT);var n=e.minimum,r=e.maximum;this._min=t.clone(n),this._max=t.clone(r),this._workerName="createBoxOutlineGeometry"}var _=new t;c.fromDimensions=function(e){e=i(e,i.EMPTY_OBJECT);var n=e.dimensions,r=t.multiplyByScalar(n,.5,new t);return new c({minimum:t.negate(r,new t),maximum:r})},c.fromAxisAlignedBoundingBox=function(e){return new c({minimum:e.minimum,maximum:e.maximum})},c.packedLength=2*t.packedLength,c.pack=function(e,n,r){return r=i(r,0),t.pack(e._min,n,r),t.pack(e._max,n,r+t.packedLength),n};var R=new t,T=new t,l={minimum:R,maximum:T};return c.unpack=function(e,n,r){n=i(n,0);var o=t.unpack(e,n,R),u=t.unpack(e,n+t.packedLength,T);return a(r)?(r._min=t.clone(o,r._min),r._max=t.clone(u,r._max),r):new c(l)},c.createGeometry=function(n){var i=n._min,a=n._max;if(!t.equals(i,a)){var c=new E,R=new Uint16Array(24),T=new Float64Array(24);T[0]=i.x,T[1]=i.y,T[2]=i.z,T[3]=a.x,T[4]=i.y,T[5]=i.z,T[6]=a.x,T[7]=a.y,T[8]=i.z,T[9]=i.x,T[10]=a.y,T[11]=i.z,T[12]=i.x,T[13]=i.y,T[14]=a.z,T[15]=a.x,T[16]=i.y,T[17]=a.z,T[18]=a.x,T[19]=a.y,T[20]=a.z,T[21]=i.x,T[22]=a.y,T[23]=a.z,c.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:T}),R[0]=4,R[1]=5,R[2]=5,R[3]=6,R[4]=6,R[5]=7,R[6]=7,R[7]=4,R[8]=0,R[9]=1,R[10]=1,R[11]=2,R[12]=2,R[13]=3,R[14]=3,R[15]=0,R[16]=0,R[17]=4,R[18]=1,R[19]=5,R[20]=2,R[21]=6,R[22]=3,R[23]=7;var l=t.subtract(a,i,_),A=.5*t.magnitude(l);return new o({attributes:c,indices:R,primitiveType:s.LINES,boundingSphere:new e(t.ZERO,A)})}},c}),define("Workers/createBoxOutlineGeometry",["../Core/BoxOutlineGeometry","../Core/defined"],function(e,t){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleGeometry.js index b5f973e5..0414bb98 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleGeometry.js @@ -222,10 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,i){if(a.typeOf.number(e,n),a.typeOf.number(r,i),n!==i)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var i=Math.abs(e-r);return i<=a||i<=n*Math.max(Math.abs(e),Math.abs(r))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var r=i[t-1],n=t;n<=e;n++)i.push(r*n);return i[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(i),n},o.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)},o.cross=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-n*s,f=n*u-a*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,r,n,a)};var d=new o,h=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,a,i,u){a=t(a,0);var s=r(i)?i.radiiSquared:E,c=Math.cos(n);d.x=c*Math.cos(e),d.y=c*Math.sin(e),d.z=Math.sin(n),d=o.normalize(d,d),o.multiplyComponents(s,d,h);var l=Math.sqrt(o.dot(d,h));return h=o.divideByScalar(h,l,h),d=o.multiplyByScalar(d,a,d),r(u)||(u=new o),o.add(h,d,u)},o.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,c){var l=r.x,f=r.y,d=r.z,h=a.x,E=a.y,m=a.z,p=l*l*h*h,y=f*f*E*E,_=d*d*m*m,T=p+y+_,R=Math.sqrt(1/T),v=e.multiplyByScalar(r,R,i);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,N=u.z,g=o;g.x=v.x*A*2,g.y=v.y*S*2,g.z=v.z*N*2;var O,I,w,M,x,C,P,D,L,U,b,F=(1-R)*e.magnitude(r)/(.5*e.magnitude(g)),B=0;do{F-=B,w=1/(1+F*A),M=1/(1+F*S),x=1/(1+F*N),C=w*w,P=M*M,D=x*x,L=C*w,U=P*M,b=D*x,O=p*C+y*P+_*D-1,I=p*L*A+y*U*S+_*b*N;B=O/(-2*I)}while(Math.abs(O)>n.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=d*x,c):new e(l*w,f*M,d*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,i){return a=r(a,0),n(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),d=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,r,a){var E=n(r)?r.oneOverRadii:f,m=n(r)?r.oneOverRadiiSquared:d,p=n(r)?r._centerToleranceSquared:h,y=o(t,E,m,p,c);if(n(y)){var _=e.multiplyComponents(y,m,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),R=Math.atan2(_.y,_.x),v=Math.asin(_.z),A=i.sign(e.dot(T,t))*e.magnitude(T);return n(a)?(a.longitude=R,a.latitude=v,a.height=A,a):new u(R,v,A)}},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t,r,a,i){r=n(r,0),a=n(a,0),i=n(i,0),t._radii=new e(r,a,i),t._radiiSquared=new e(r*r,a*a,i*i),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(r,a,i),t._maximumRadius=Math.max(r,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},f.unpack=function(t,r,a){r=n(r,0);var i=e.unpack(t,r);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(i);return a(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var d=new e,h=new e;f.prototype.cartographicToCartesian=function(t,r){var n=d,i=h;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,i);var o=Math.sqrt(e.dot(n,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(i,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(r,n){var i=this.scaleToGeodeticSurface(r,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(r,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,i){r=n(r,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-r))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,i,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a,i,o,u,s,c){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(i,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(m[r],E[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>n&&(a=i,n=o)}var c=1,l=0,f=E[a],d=m[a];if(Math.abs(e[s.getElementIndex(d,f)])>r){var h,p=e[s.getElementIndex(d,d)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(d,f)],T=(p-y)/2/_;h=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(d,d)]=c,t[s.getElementIndex(d,f)]=l,t[s.getElementIndex(f,d)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,d=e.z*e.w,h=e.w*e.w,E=r-u-f+h,m=2*(a-d),p=2*(i+l),y=2*(a+d),_=-r+u-f+h,T=2*(c-o),R=2*(i-l),v=2*(c+o),A=-r-u+f+h;return n(t)?(t[0]=E,t[1]=y,t[2]=R,t[3]=m,t[4]=_,t[5]=v,t[6]=p,t[7]=T,t[8]=A,t):new s(E,m,p,y,_,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*a,f=-i*u+c*o*a,d=c*u+i*o*a,h=r*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,y=c*r,_=i*r;return n(t)?(t[0]=l,t[1]=h,t[2]=p,t[3]=f,t[4]=E,t[5]=y,t[6]=d,t[7]=m,t[8]=_,t):new s(l,f,d,h,E,m,p,y,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],i=e[n+1],o=e[n+2];return r.x=a,r.y=i,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],i=e[t+6];return r.x=n,r.y=a,r.z=i,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var d=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],d)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],d)),r};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=i,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[3]*a+e[6]*i,u=e[1]*n+e[4]*a+e[7]*i,s=e[2]*n+e[5]*a+e[8]*i;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,i=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),d=t.diagonal=s.clone(e,t.diagonal),h=r*c(d);i<10&&l(d)>h;)f(d,p),s.transpose(p,y),s.multiply(d,p,d),s.multiply(y,d,d),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*n-r*c)+u*(r*o-i*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],d=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-n*f,t[2]=n*u-o*a,t[3]=c*u-i*f,t[4]=r*f-c*a,t[5]=i*a-r*u,t[6]=i*l-c*o,t[7]=c*n-r*l,t[8]=r*o-i*n;var h=1/d;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}o.fromElements=function(e,t,n,a,i){return r(i)?(i.x=e,i.y=t,i.z=n,i.w=a,i):new o(e,t,n,a)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)&&i.equalsEpsilon(e.w,t.w,n,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t,r,a,i,o,u,s,c,l,f,d,h,E,m,p){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(c,0),this[3]=n(h,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(E,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(m,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(d,0),this[15]=n(p,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,i){return r=n(r,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=r.x,i[13]=r.y,i[14]=r.z,i[15]=1,i):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var i=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,d=t.x*t.w,h=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-h-p+_,R=2*(c-y),v=2*(f+m),A=2*(c+y),S=-s+h-p+_,N=2*(E-d),g=2*(f-m),O=2*(E+d),I=-s-h+p+_;return n[0]=T*i,n[1]=A*i,n[2]=g*i,n[3]=0,n[4]=R*o,n[5]=S*o,n[6]=O*o,n[7]=0,n[8]=v*u,n[9]=N*u,n[10]=I*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,d=new e,h=new e;l.fromCamera=function(t,r){var n=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,d),d),e.normalize(e.cross(d,f,h),h);var u=d.x,s=d.y,c=d.z,E=f.x,m=f.y,p=f.z,y=h.x,_=h.y,T=h.z,R=n.x,v=n.y,A=n.z,S=u*-R+s*-v+c*-A,N=y*-R+_*-v+T*-A,g=E*R+m*v+p*A;return a(r)?(r[0]=u,r[1]=y,r[2]=-E,r[3]=0,r[4]=s,r[5]=_,r[6]=-m,r[7]=0,r[8]=c,r[9]=T,r[10]=-p,r[11]=0,r[12]=S,r[13]=N,r[14]=g,r[15]=1,r):new l(u,s,c,S,y,_,T,N,-E,-m,-p,g,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,i,o){var u=1/(t-e),s=1/(n-r),c=1/(i-a),l=-(t+e)*u,f=-(n+r)*s,d=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=d,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,a,i,o){var u=2*a/(t-e),s=2*a/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(i+a)/(i-a),d=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=d,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,i){var o=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var i=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),d=c,h=l,E=f,m=i+c,p=o+l,y=t+f;return a[0]=d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=y,a[15]=1,a},l.computeView=function(t,r,n,a,i){return i[0]=a.x,i[1]=n.x,i[2]=-r.x,i[3]=0,i[4]=a.y,i[5]=n.y,i[6]=-r.y,i[7]=0,i[8]=a.z,i[9]=n.z,i[10]=-r.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(n,t),i[14]=e.dot(r,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],i=e[n+1],o=e[n+2],u=e[n+3];return r.x=a,r.y=i,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return r.x=n,r.y=a,r.z=i,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var E=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),r};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],d=e[9],h=e[10],E=e[11],m=e[12],p=e[13],y=e[14],_=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],N=t[5],g=t[6],O=t[7],I=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],D=t[14],L=t[15],U=n*T+u*R+f*v+m*A,b=a*T+s*R+d*v+p*A,F=i*T+c*R+h*v+y*A,B=o*T+l*R+E*v+_*A,z=n*S+u*N+f*g+m*O,G=a*S+s*N+d*g+p*O,q=i*S+c*N+h*g+y*O,V=o*S+l*N+E*g+_*O,X=n*I+u*w+f*M+m*x,W=a*I+s*w+d*M+p*x,H=i*I+c*w+h*M+y*x,Y=o*I+l*w+E*M+_*x,k=n*C+u*P+f*D+m*L,j=a*C+s*P+d*D+p*L,Z=i*C+c*P+h*D+y*L,K=o*C+l*P+E*D+_*L;return r[0]=U,r[1]=b,r[2]=F,r[3]=B,r[4]=z,r[5]=G,r[6]=q,r[7]=V,r[8]=X,r[9]=W,r[10]=H,r[11]=Y,r[12]=k,r[13]=j,r[14]=Z,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=e[12],h=e[13],E=e[14],m=t[0],p=t[1],y=t[2],_=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],N=t[12],g=t[13],O=t[14],I=n*m+o*p+c*y,w=a*m+u*p+l*y,M=i*m+s*p+f*y,x=n*_+o*T+c*R,C=a*_+u*T+l*R,P=i*_+s*T+f*R,D=n*v+o*A+c*S,L=a*v+u*A+l*S,U=i*v+s*A+f*S,b=n*N+o*g+c*O+d,F=a*N+u*g+l*O+h,B=i*N+s*g+f*O+E;return r[0]=I,r[1]=w,r[2]=M,r[3]=0,r[4]=x,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=L,r[10]=U,r[11]=0,r[12]=b,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=t[0],h=t[1],E=t[2],m=t[3],p=t[4],y=t[5],_=t[6],T=t[7],R=t[8],v=n*d+o*h+c*E,A=a*d+u*h+l*E,S=i*d+s*h+f*E,N=n*m+o*p+c*y,g=a*m+u*p+l*y,O=i*m+s*p+f*y,I=n*_+o*T+c*R,w=a*_+u*T+l*R,M=i*_+s*T+f*R;return r[0]=v,r[1]=A,r[2]=S,r[3]=0,r[4]=N,r[5]=g,r[6]=O,r[7]=0,r[8]=I,r[9]=w,r[10]=M,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=n*e[0]+a*e[4]+i*e[8]+e[12],u=n*e[1]+a*e[5]+i*e[9]+e[13],s=n*e[2]+a*e[6]+i*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var p=new e;l.multiplyByUniformScale=function(e,t,r){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,i=t.z;return 1===n&&1===a&&1===i?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=i*e[8],r[9]=i*e[9],r[10]=i*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*n+e[4]*a+e[8]*i+e[12]*o,s=e[1]*n+e[5]*a+e[9]*i+e[13]*o,c=e[2]*n+e[6]*a+e[10]*i+e[14]*o,l=e[3]*n+e[7]*a+e[11]*i+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i,u=e[1]*n+e[5]*a+e[9]*i,s=e[2]*n+e[6]*a+e[10]*i;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i+e[12],u=e[1]*n+e[5]*a+e[9]*i+e[13],s=e[2]*n+e[6]*a+e[10]*i+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],i=e[8],o=e[12],f=e[1],d=e[5],h=e[9],E=e[13],m=e[2],p=e[6],v=e[10],A=e[14],S=e[3],N=e[7],g=e[11],O=e[15],I=v*O,w=A*g,M=p*O,x=A*N,C=p*g,P=v*N,D=m*O,L=A*S,U=m*g,b=v*S,F=m*N,B=p*S,z=I*d+x*h+C*E-(w*d+M*h+P*E),G=w*f+D*h+b*E-(I*f+L*h+U*E),q=M*f+L*d+F*E-(x*f+D*d+B*E),V=P*f+U*d+B*h-(C*f+b*d+F*h),X=w*a+M*i+P*o-(I*a+x*i+C*o),W=I*n+L*i+U*o-(w*n+D*i+b*o),H=x*n+D*a+B*o-(M*n+L*a+F*o),Y=C*n+b*a+F*i-(P*n+U*a+B*i);I=i*E,w=o*h,M=a*E,x=o*d,C=a*h,P=i*d,D=n*E,L=o*f,U=n*h,b=i*f,F=n*d,B=a*f;var k=I*N+x*g+C*O-(w*N+M*g+P*O),j=w*S+D*g+b*O-(I*S+L*g+U*O),Z=M*S+L*N+F*O-(x*S+D*N+B*O),K=P*S+U*N+B*g-(C*S+b*N+F*g),J=M*v+P*A+w*p-(C*A+I*p+x*v),Q=U*A+I*m+L*v-(D*v+b*A+w*m),$=D*p+B*A+x*m-(F*A+M*m+L*p),ee=F*v+C*m+b*p-(U*p+B*v+P*m),te=n*z+a*G+i*q+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=G*te,r[2]=q*te,r[3]=V*te,r[4]=X*te,r[5]=W*te,r[6]=H*te,r[7]=Y*te,r[8]=k*te,r[9]=j*te,r[10]=Z*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],d=e[13],h=e[14],E=-r*f-n*d-a*h,m=-i*f-o*d-u*h,p=-s*f-c*d-l*h;return t[0]=r,t[1]=i,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),i=u.toRadians(r(i,0)),n(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(a,0),o.north=r(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,d=e.length;f<d;f++){var h=e[f];r=Math.min(r,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var E=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-r>o-i&&(r=i,a=o,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=a,t.north=l,t):new s(r,c,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,d=Number.MAX_VALUE,h=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),d=Math.min(d,p.latitude),h=Math.max(h,p.latitude);var y=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(a)?(a.west=o,a.south=d,a.east=c,a.north=h,a):new s(o,d,c,h)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var d=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(d>=h))return n(r)?(r.west=l,r.south=d,r.east=f,r.north=h,r):new s(l,d,f,h)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return n(r)?(r.west=a,r.south=i,r.east=o,r.north=u,r):new s(a,i,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<i||u.equalsEpsilon(r,i,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=r(t,i.WGS84),a=r(a,0),n(o)||(o=[]);var l=0,f=e.north,d=e.south,h=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:d>0?d:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,i,o,u,s,c,l,f){"use strict";function d(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var h=new e,E=new e,m=new e,p=new e,y=new e,_=new e,T=new e,R=new e,v=new e,A=new e,S=new e,N=new e;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],T),o=e.clone(i,h),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,y),f=e.clone(i,_),g=t.length;for(n=1;n<g;n++){e.clone(t[n],i);var O=i.x,I=i.y,w=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,L=M;x>L&&(L=x,P=u,D=l),C>L&&(L=C,P=s,D=f);var U=v;U.x=.5*(P.x+D.x),U.y=.5*(P.y+D.y),U.z=.5*(P.z+D.z);var b=e.magnitudeSquared(e.subtract(D,U,R)),F=Math.sqrt(b),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var G=e.multiplyByScalar(e.add(B,z,R),.5,N),q=0;for(n=0;n<g;n++){e.clone(t[n],i);var V=e.magnitude(e.subtract(i,G,R));V>q&&(q=V);var X=e.magnitudeSquared(e.subtract(i,U,R));if(X>b){var W=Math.sqrt(X);F=.5*(F+W),b=F*F;var H=W-F;U.x=(F*U.x+H*i.x)/W,U.y=(F*U.y+H*i.y)/W,U.z=(F*U.z+H*i.z)/W}}return F<q?(e.clone(U,r.center),r.radius=F):(e.clone(G,r.center),r.radius=q),r};var g=new o,O=new e,I=new e,w=new t,M=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,i,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=n(r,g),f.southwest(t,w),w.height=i,f.northeast(t,M),M.height=o;var s=r.project(w,O),c=r.project(M,I),l=c.x-s.x,h=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*h,m.z=s.z+.5*E,u};var x=[];d.fromRectangle3D=function(t,r,o,u){if(r=n(r,i.WGS84),o=n(o,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,r,o,x);return d.fromPoints(s,u)},d.fromVertices=function(t,r,i,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=n(r,e.ZERO),i=n(i,3);var u=T;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,h),l=e.clone(u,E),f=e.clone(u,m),g=e.clone(u,p),O=e.clone(u,y),I=e.clone(u,_),w=t.length;for(s=0;s<w;s+=i){var M=t[s]+r.x,x=t[s+1]+r.y,C=t[s+2]+r.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>g.x&&e.clone(u,g),x<l.y&&e.clone(u,l),x>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(g,c,R)),D=e.magnitudeSquared(e.subtract(O,l,R)),L=e.magnitudeSquared(e.subtract(I,f,R)),U=c,b=g,F=P;D>F&&(F=D,U=l,b=O),L>F&&(F=L,U=f,b=I);var B=v;B.x=.5*(U.x+b.x),B.y=.5*(U.y+b.y),B.z=.5*(U.z+b.z);var z=e.magnitudeSquared(e.subtract(b,B,R)),G=Math.sqrt(z),q=A;q.x=c.x,q.y=l.y,q.z=f.z;var V=S;V.x=g.x,V.y=O.y,V.z=I.z;var X=e.multiplyByScalar(e.add(q,V,R),.5,N),W=0;for(s=0;s<w;s+=i){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,X,R));H>W&&(W=H);var Y=e.magnitudeSquared(e.subtract(u,B,R));if(Y>z){var k=Math.sqrt(Y);G=.5*(G+k),z=G*G;var j=k-G;B.x=(G*B.x+j*u.x)/k,B.y=(G*B.y+j*u.y)/k,B.z=(G*B.z+j*u.z)/k}}return G<W?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=W),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=T;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,h),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,p),f=e.clone(i,y),g=e.clone(i,_),O=t.length;for(o=0;o<O;o+=3){var I=t[o]+r[o],w=t[o+1]+r[o+1],M=t[o+2]+r[o+2];i.x=I,i.y=w,i.z=M,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>g.z&&e.clone(i,g)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(g,c,R)),D=u,L=l,U=x;C>U&&(U=C,D=s,L=f),P>U&&(U=P,D=c,L=g);var b=v;b.x=.5*(D.x+L.x),b.y=.5*(D.y+L.y),b.z=.5*(D.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,R)),B=Math.sqrt(F),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var G=S;G.x=l.x,G.y=f.y,G.z=g.z;var q=e.multiplyByScalar(e.add(z,G,R),.5,N),V=0;for(o=0;o<O;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(i,q,R));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(i,b,R));if(W>F){var H=Math.sqrt(W);B=.5*(B+H),F=B*B;var Y=H-B;b.x=(B*b.x+Y*i.x)/H,b.y=(B*b.y+Y*i.y)/H,b.z=(B*b.z+Y*i.z)/H}}return B<V?(e.clone(b,n.center),n.radius=B):(e.clone(q,n.center),n.radius=V),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var C=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return r.radius=s,r};var P=new e,D=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=c.getColumn(n,0,P),o=c.getColumn(n,1,D),u=c.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=n(r,0);var a=e.center;return t[r++]=a.x,t[r++]=a.y,t[r++]=a.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=n(t,0),a(r)||(r=new d);var i=r.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],r.radius=e[t],r};var U=new e,b=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,U),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var F=new e;d.expand=function(t,r,n){n=d.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,F));return a>n.radius&&(n.radius=a),n},d.intersectPlane=function(t,r){var n=t.center,a=t.radius,i=r.normal,o=e.dot(i,n)+r.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=l.getMaximumScale(t)*e.radius,r};var B=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,B);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var z=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new s);var o=e.subtract(t.center,r,z),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var G=new e,q=new e,V=new e,X=new e,W=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var j=new o;return d.projectTo2D=function(t,r,a){r=n(r,j);var i=r.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,G),c=e.cross(e.UNIT_Z,s,q);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,W),h=e.negate(c,X),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,y=0;y<p;++y){var _=E[y];e.add(o,_,_);var T=i.cartesianToCartographic(_,H);r.project(T,_)}a=d.fromPoints(E,a),o=a.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,a},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var a=0;a<n;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var a=0;a<n;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}), -define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(v)&&(v=!1,!d())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=n(e[1]))}return v}function i(){return a()&&A}function o(){if(!t(S)&&(S=!1,!a()&&!d()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=n(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(g)){g=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(g=!0,O=n(e[1]),O.isNightly=!!e[2])}return g}function c(){return s()&&O}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=n(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=n(e[1]))}return I}function f(){return l()&&w}function d(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(M=!0,x=n(e[1]))}return M}function h(){return d()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(R.appVersion)),D}function p(){return E()&&P}function y(){return t(L)||(L="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),L}function _(){if(!t(b)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;b=t(r)&&""!==r,b&&(U=r)}return b}function T(){return _()?U:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,N,g,O,I,w,M,x,C,P,D,L,U,b,F={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:d,edgeVersion:h,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,i){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,a);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case o.SHORT:return new Int16Array(r,n,a);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case o.INT:return new Int32Array(r,n,a);case o.UNSIGNED_INT:return new Uint32Array(r,n,a);case o.FLOAT:return new Float32Array(r,n,a);case o.DOUBLE:return new Float64Array(r,n,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(a,0)}var c=new e;s.fromAxisAngle=function(t,r,a){var i=r/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,d=Math.cos(i);return n(a)?(a.x=u,a.y=l,a.z=f,a.w=d,a):new s(u,l,f,d)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,a,i,o,c,d=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=d+h+E;if(m>0)r=Math.sqrt(m+1),c=.5*r,r=.5/r,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var p=l,y=0;h>d&&(y=1),E>d&&E>h&&(y=2);var _=p[y],T=p[_];r=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var R=f;R[y]=.5*r,r=.5/r,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*r,R[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*r,R[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*r,a=-R[0],i=-R[1],o=-R[2]}return n(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var d=new s,h=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,r){return m=s.fromAxisAngle(e.UNIT_X,t.roll,d),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(E,m,E),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,d),s.multiply(h,r,r)};var p=new e,y=new e,_=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,R),s.conjugate(R,R);for(var a=0,i=r-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),_),s.multiply(_,R,_),_.w<0&&s.negate(_,_),s.computeAxis(_,p);var u=s.computeAngle(_);n[o]=p.x*u,n[o+1]=p.y*u,n[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,r,a,i,o){n(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(r,4*i,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,a=e.y*r,i=e.z*r,o=e.w*r;return t.x=n,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+a*c-i*s,d=o*s-n*c+a*l+i*u,h=o*c+n*s-a*u+i*l,E=o*l-n*u-a*s-i*c;return r.x=f,r.y=d,r.z=h,r.w=E,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,r,n){return v=s.multiplyByScalar(t,r,v),n=s.multiplyByScalar(e,1-r,n),s.add(v,n,n)};var A=new s,S=new s,N=new s;s.slerp=function(e,t,r,n){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=A=s.negate(t,A)),1-a<o.EPSILON6)return s.lerp(e,i,r,n);var u=Math.acos(a);return S=s.multiplyByScalar(e,Math.sin((1-r)*u),S),N=s.multiplyByScalar(i,Math.sin(r*u),N),n=s.add(S,N,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),a=0;return 0!==n&&(a=n/Math.sin(n)),e.multiplyByScalar(t,a,r)},s.exp=function(t,r){var n=e.magnitude(t),a=0;return 0!==n&&(a=Math.sin(n)/n),r.x=t.x*a,r.y=t.y*a,r.z=t.z*a,r.w=Math.cos(n),r};var g=new e,O=new e,I=new s,w=new s;s.computeInnerQuadrangle=function(t,r,n,a){var i=s.conjugate(r,I);s.multiply(i,n,w);var o=s.log(w,g);s.multiply(i,t,w);var u=s.log(w,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(r,I,a)},s.squad=function(e,t,r,n,a,i){var o=s.slerp(e,t,a,I),u=s.slerp(r,n,a,w);return s.slerp(o,u,2*a*(1-a),i)};for(var M=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=a.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var b=U+1,F=2*b+1;C[U]=1/(b*F),P[U]=b/F}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,r,n){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,L[f]=(C[f]*l-P[f])*o;var d=a*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),h=u*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),E=s.multiplyByScalar(e,h,M);return s.multiplyByScalar(t,d,n),s.add(E,n,n)},s.fastSquad=function(e,t,r,n,a,i){var o=s.fastSlerp(e,t,a,I),u=s.fastSlerp(r,n,a,w);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,r,n){"use strict";function a(t,a,i,l,f,d,h,E,m,p){var y=t+a;e.multiplyByScalar(l,Math.cos(y),o),e.multiplyByScalar(i,Math.sin(y),u),e.add(o,u,o);var _=Math.cos(t);_*=_;var T=Math.sin(t);T*=T;var R=d/Math.sqrt(h*_+f*T),v=R/E;return n.fromAxisAngle(o,v,s),r.fromQuaternion(s,c),r.multiplyByVector(c,m,p),e.normalize(p,p),e.multiplyByScalar(p,E,p),p}var i={},o=new e,u=new e,s=new n,c=new r,l=new e,f=new e,d=new e,h=new e;i.raisePositionsToHeight=function(t,r,n){for(var a=r.ellipsoid,i=r.height,o=r.extrudedHeight,u=n?t.length/3*2:t.length/3,s=new Float64Array(3*u),c=t.length,E=n?c:0,m=0;m<c;m+=3){var p=m+1,y=m+2,_=e.fromArray(t,m,l);a.scaleToGeodeticSurface(_,_);var T=e.clone(_,f),R=a.geodeticSurfaceNormal(_,h),v=e.multiplyByScalar(R,i,d);e.add(_,v,_),n&&(e.multiplyByScalar(R,o,v),e.add(T,v,T),s[m+E]=T.x,s[p+E]=T.y,s[y+E]=T.z),s[m]=_.x,s[p]=_.y,s[y]=_.z}return s};var E=new e,m=new e,p=new e;return i.computeEllipsePositions=function(r,n,i){var o=r.semiMinorAxis,u=r.semiMajorAxis,s=r.rotation,c=r.center,h=8*r.granularity,y=o*o,_=u*u,T=u*o,R=e.magnitude(c),v=e.normalize(c,E),A=e.cross(e.UNIT_Z,c,m);A=e.normalize(A,A);var S=e.cross(v,A,p),N=1+Math.ceil(t.PI_OVER_TWO/h),g=t.PI_OVER_TWO/(N-1),O=t.PI_OVER_TWO-N*g;O<0&&(N-=Math.ceil(Math.abs(O)/g));var I,w,M,x,C,P=N*(N+2)*2,D=n?new Array(3*P):void 0,L=0,U=l,b=f,F=4*N*3,B=F-1,z=0,G=i?new Array(F):void 0;for(O=t.PI_OVER_TWO,U=a(O,s,S,A,y,T,_,R,v,U),n&&(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z),i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x),O=t.PI_OVER_TWO-g,I=1;I<N+1;++I){if(U=a(O,s,S,A,y,T,_,R,v,U),b=a(Math.PI-O,s,S,A,y,T,_,R,v,b),n){for(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z,M=2*I+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(U,b,x,d),D[L++]=C.x,D[L++]=C.y,D[L++]=C.z;D[L++]=b.x,D[L++]=b.y,D[L++]=b.z}i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x,G[z++]=b.x,G[z++]=b.y,G[z++]=b.z),O=t.PI_OVER_TWO-(I+1)*g}for(I=N;I>1;--I){if(O=t.PI_OVER_TWO-(I-1)*g,U=a(-O,s,S,A,y,T,_,R,v,U),b=a(O+Math.PI,s,S,A,y,T,_,R,v,b),n){for(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z,M=2*(I-1)+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(U,b,x,d),D[L++]=C.x,D[L++]=C.y,D[L++]=C.z;D[L++]=b.x,D[L++]=b.y,D[L++]=b.z}i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x,G[z++]=b.x,G[z++]=b.y,G[z++]=b.z)}O=t.PI_OVER_TWO,U=a(-O,s,S,A,y,T,_,R,v,U);var q={};return n&&(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z,q.positions=D,q.numPts=N),i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x,q.outerPositions=G),q},i}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return a}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,r,n,a){"use strict";var i={};i.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,r){return i.octDecodeInRange(e,t,255,r)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),a=256*(r-n);return i.octDecode(n,a,t)},i.octPack=function(e,t,r,n){ -var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(r,o);return n.x=65536*s.x+a,n.y=65536*s.y+u,n},i.octUnpack=function(e,t,r,n){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,r),i.octDecode(o,s,n)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},i}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function a(r,a,s,c,l){n(l)||(l=new t);var f,d,h,E,m,p,y,_;n(a.z)?(f=t.subtract(s,a,i),d=t.subtract(c,a,o),h=t.subtract(r,a,u),E=t.dot(f,f),m=t.dot(f,d),p=t.dot(f,h),y=t.dot(d,d),_=t.dot(d,h)):(f=e.subtract(s,a,i),d=e.subtract(c,a,o),h=e.subtract(r,a,u),E=e.dot(f,f),m=e.dot(f,d),p=e.dot(f,h),y=e.dot(d,d),_=e.dot(d,h));var T=1/(E*y-m*m);return l.y=(y*p-m*_)*T,l.z=(E*_-m*p)*T,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var a={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var i=t.high,o=t.low;return n.encode(e.x,a),i.x=a.high,o.x=a.low,n.encode(e.y,a),i.y=a.high,o.y=a.low,n.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,i);var a=i.high,o=i.low;t[r]=a.x,t[r+1]=a.y,t[r+2]=a.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var i;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-n/e,i<0?[i,0]:[0,i];var c=n*n,l=4*e*a,f=r(c,-l,t.EPSILON14);if(f<0)return[];var d=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[d/e,a/d]:[a/d,d/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,i,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,d=u*u,h=s*s,E=o*s-d,m=o*c-u*s,p=u*c-h,y=4*E*p-m*m;if(y<0){var _,T,R;d*f>=l*h?(_=o,T=E,R=-2*u*E+o*m):(_=c,T=p,R=-c*m+2*s*p);var v=R<0?-1:1,A=-v*Math.abs(_)*Math.sqrt(-y);i=-R+A;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),g=i===A?-N:-T/N;return a=T<=0?N+g:-R/(N*N+g*g+T),d*f>=l*h?[(a-u)/o]:[-c/(a+s)]}var O=E,I=-2*u*E+o*m,w=p,M=-c*m+2*s*p,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-I)/3);a=2*Math.sqrt(-O);var D=Math.cos(P);i=a*D;var L=a*(-D/2-C*Math.sin(P)),U=i+L>2*u?i-u:L-u,b=o,F=U/b;P=Math.abs(Math.atan2(c*x,-M)/3),a=2*Math.sqrt(-w),D=Math.cos(P),i=a*D,L=a*(-D/2-C*Math.sin(P));var B=-c,z=i+L<2*s?i+s:L+s,G=B/z,q=b*z,V=-U*z-b*B,X=U*B,W=(s*V-u*X)/(-u*V+s*q);return F<=W?F<=G?W<=G?[F,W,G]:[F,G,W]:[G,F,W]:F<=G?[W,F,G]:W<=G?[W,G,F]:[G,W,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,i=t*t,o=r*r;return 18*e*t*r*n+i*o-27*a*(n*n)-4*(e*o*r+i*t*n)},n.computeRealRoots=function(e,n,a,i){var o,u;if(0===e)return t.computeRealRoots(n,a,i);if(0===n){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,a,i)}return 0===a?0===i?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,i):0===i?(o=t.computeRealRoots(e,n,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,a,i)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var d=-t/4,h=f[f.length-1];if(Math.abs(h)<r.EPSILON14){var E=n.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],y=E[1];if(p>=0&&y>=0){var _=Math.sqrt(p),T=Math.sqrt(y);return[d-T,d-_,d+_,d+T]}if(p>=0&&y<0)return m=Math.sqrt(p),[d-m,d+m];if(p<0&&y>=0)return m=Math.sqrt(y),[d-m,d+m]}return[]}if(h>0){var R=Math.sqrt(h),v=(s+h-c/R)/2,A=(s+h+c/R)/2,S=n.computeRealRoots(1,R,v),N=n.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=d,S[1]+=d,0!==N.length?(N[0]+=d,N[1]+=d,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=d,N[1]+=d,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,d=c*o-i*a*t+u,h=e.computeRealRoots(1,l,f,d);if(h.length>0){var E,m,p=h[0],y=a-p,_=y*y,T=t/2,R=y/2,v=_-4*o,A=_+4*Math.abs(o),S=c-4*p,N=c+4*Math.abs(p);if(p<0||v*N<S*A){var g=Math.sqrt(S);E=g/2,m=0===g?0:(t*R-i)/g}else{var O=Math.sqrt(v);E=0===O?0:(t*R-i)/O,m=O/2}var I,w;0===T&&0===E?(I=0,w=0):r.sign(T)===r.sign(E)?(I=T+E,w=p/I):(w=T-E,I=p/w);var M,x;0===R&&0===m?(M=0,x=0):r.sign(R)===r.sign(m)?(M=R+m,x=o/M):(x=R-m,M=o/x);var C=n.computeRealRoots(1,I,M),P=n.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,d=f*n,h=a*a;return u*c*f-4*s*d-4*e*l*f+18*e*t*r*d-27*i*f*f+256*o*(h*a)+a*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*i*r*f)+h*(144*e*u*r-27*u*u-128*i*c-192*i*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,d=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=f<0?h+1:h,h+=d<0?h+1:h){case 0:return a(c,l,f,d);case 1:case 2:return i(c,l,f,d);case 3:case 4:return a(c,l,f,d);case 5:return i(c,l,f,d);case 6:case 7:return a(c,l,f,d);case 8:return i(c,l,f,d);case 9:case 10:return a(c,l,f,d);case 11:return i(c,l,f,d);case 12:case 13:case 14:case 15:return a(c,l,f,d);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,i,o,u,s,c,l){"use strict";function f(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function d(t,r,a){n(a)||(a=new i);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),d=e.dot(u,u),h=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(d,h,E,A);if(n(m))return a.start=m.root0,a.stop=m.root1,a}function h(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function E(t,r,n,a,i){var l,f=a*a,d=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*d,m=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*d+a*r.x+n,y=d*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-v)),T.push(new e(a,i*R,i*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(a,i*A,i*-S)),T.push(new e(a,i*A,i*S))}return T}var N=_*_,g=y*y,O=E*E,I=_*y,w=O+g,M=2*(m*E+I),x=2*p*E+m*m-g+N,C=2*(p*m-I),P=p*p-N;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var D=l.length;if(0===D)return T;for(var L=0;L<D;++L){var U,b=l[L],F=b*b,B=Math.max(1-F,0),z=Math.sqrt(B);U=o.sign(E)===o.sign(p)?h(E*F+p,m*b,o.EPSILON12):o.sign(p)===o.sign(m*b)?h(E*F,m*b+p,o.EPSILON12):h(E*F+m*b,p,o.EPSILON12);var G=h(y*b,_,o.EPSILON15),q=U*G;q<0?T.push(new e(a,i*b,i*z)):q>0?T.push(new e(a,i*b,i*-z)):0!==z?(T.push(new e(a,i*b,i*-z)),T.push(new e(a,i*b,i*z)),++L):T.push(new e(a,i*b,i*z))}return T}var m={};m.rayPlane=function(t,r,a){n(a)||(a=new e);var i=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,y=new e,_=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,n,a,i,u){u=r(u,!1);var s,c,l,f,d,h=t.origin,E=t.direction,m=e.subtract(a,n,p),v=e.subtract(i,n,y),A=e.cross(E,v,_),S=e.dot(m,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,n,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>S)return;d=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,n,T),(l=e.dot(s,A)*N)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*N)<0||l+f>1)return;d=e.dot(v,c)*N}return d},m.rayTriangle=function(t,r,a,i,o,u){var s=m.rayTriangleParametric(t,r,a,i,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;m.lineSegmentTriangle=function(t,r,a,i,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=d(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;m.lineSegmentSphere=function(t,r,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=d(o,a,i),!(!n(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,g=new e;m.rayEllipsoid=function(t,r){var n,a,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),f=e.multiplyComponents(c,t.direction,g),d=e.magnitudeSquared(l),h=e.dot(l,f);if(d>1){if(h>=0)return;var E=h*h;if(n=d-1,a=e.magnitudeSquared(f),o=a*n,E<o)return;if(E>o){u=h*h-o,s=-h+Math.sqrt(u);var m=s/a,p=n/s;return m<p?new i(m,p):{start:p,stop:m}}var y=Math.sqrt(n/a);return new i(y,y)}return d<1?(n=d-1,a=e.magnitudeSquared(f),o=a*n,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(f),new i(0,-h/a)):void 0};var O=new e,I=new e,w=new e,M=new e,x=new e,C=new u,P=new u,D=new u,L=new u,U=new u,b=new u,F=new u,B=new e,z=new e,G=new t;m.grazingAltitudeLocation=function(t,r){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),d=e.mostOrthogonalAxis(l,M),h=e.normalize(e.cross(d,f,I),I),m=e.normalize(e.cross(f,h,w),w),p=C;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=h.x,p[4]=h.y,p[5]=h.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var y=u.transpose(p,P),_=u.fromScale(r.radii,D),T=u.fromScale(r.oneOverRadii,L),R=U;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var v,A,S=u.multiply(u.multiply(y,T,b),R,b),N=u.multiply(u.multiply(S,_,F),p,F),g=u.multiplyByVector(S,a,x),q=E(N,e.negate(g,O),0,0,1),V=q.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(_,u.multiplyByVector(p,q[H],B),B);var Y=e.normalize(e.subtract(v,a,M),M),k=e.dot(Y,i);k>W&&(W=k,X=e.clone(v,X))}var j=r.cartesianToCartographic(X,G);return W=o.clamp(W,0,1),A=e.magnitude(e.subtract(X,a,M))*Math.sqrt(1-W*W),A=c?-A:A,j.height=A,r.cartographicToCartesian(j,new e)}};var q=new e;return m.lineSegmentPlane=function(t,r,a,i){n(i)||(i=new e);var u=e.subtract(r,t,q),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,r,n,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,r)+o<0,c=e.dot(i,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,d;if(1!==l&&2!==l||(f=new e,d=new e),1===l){if(u)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(t,n,a,d),{positions:[t,r,n,f,d],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(r,t,a,d),{positions:[t,r,n,f,d],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(n,r,a,d),{positions:[t,r,n,f,d],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(n,t,a,d),{positions:[t,r,n,f,d],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(t,r,a,d),{positions:[t,r,n,f,d],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(r,n,a,d),{positions:[t,r,n,f,d],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,i,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var i=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=i,a):new u(n,i)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),i=t.w;return r(n)?(e.clone(a,n.normal),n.distance=i,n):new u(a,i)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(r,c,c),u.fromPointNormal(c,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,a=r.maximumIndex,i=e(r.cacheSize,24),o=n.length;if(!t(a)){a=0;for(var u=0,s=n[u];u<o;)s>a&&(a=s),++u,s=n[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var f=i+1,d=0;d<o;++d)f-c[n[d]]>i&&(c[n[d]]=f,++f);return(f-i+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<n;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}r=e(r,e.EMPTY_OBJECT);var a,i=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=i.length,c=0,l=0,f=i[l],d=s;if(t(o))c=o+1;else{for(;l<d;)f>c&&(c=f),++l,f=i[l];if(-1===c)return 0;++c}var h,E=[];for(h=0;h<c;h++)E[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<d;)E[i[l]].vertexTriangles.push(m),++E[i[l]].numLiveTriangles,E[i[l+1]].vertexTriangles.push(m),++E[i[l+1]].numLiveTriangles,E[i[l+2]].vertexTriangles.push(m),++E[i[l+2]].numLiveTriangles,++m,l+=3;var p=0,y=u+1;a=1;var _,T,R=[],v=[],A=0,S=[],N=s/3,g=[];for(h=0;h<N;h++)g[h]=!1;for(var O,I;-1!==p;){R=[],T=E[p],I=T.vertexTriangles.length;for(var w=0;w<I;++w)if(m=T.vertexTriangles[w],!g[m]){g[m]=!0,l=m+m+m;for(var M=0;M<3;++M)O=i[l],R.push(O),v.push(O),S[A]=O,++A,_=E[O],--_.numLiveTriangles,y-_.timeStamp>u&&(_.timeStamp=y,++y),++l}p=function(e,t,r,a,i,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var d=r[f];a[d].numLiveTriangles&&(s=0,i-a[d].timeStamp+2*a[d].numLiveTriangles<=t&&(s=i-a[d].timeStamp),(s>l||-1===l)&&(l=s,c=d)),++f}return-1===c?n(a,o,e,u):c}(i,u,R,E,y,v,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,a,i,o,u,s,c,l,f,d,h,E,m,p,y,_,T,R,v,A,S,N){"use strict";function g(e,t,r,n,a){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=a,e[t++]=a,e[t]=r}function O(e){for(var t=e.length,r=t/3*6,n=p.createTypedArray(t,r),a=0,i=0;i<t;i+=3,a+=6)g(n,a,e[i],e[i+1],e[i+2]);return n}function I(e){var t=e.length;if(t>=3){var r=6*(t-2),n=p.createTypedArray(t,r);g(n,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)g(n,a,e[i-1],e[i],e[i-2]);return n}return new Uint16Array}function w(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=p.createTypedArray(t,r),a=e[0],i=0,o=1;o<t;++o,i+=6)g(n,i,a,e[o],e[o+1]);return n}return new Uint16Array}function M(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new E({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function x(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var a=t[n],i=0;i<a.componentsPerAttribute;++i)e[n].values.push(a.values[r*a.componentsPerAttribute+i])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),v.multiplyByPoint(e,ie,ie),a.pack(ie,r,i)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,r,i)}function D(e,t){var r,n=e.length,a={},i=e[0][t].attributes;for(r in i)if(i.hasOwnProperty(r)&&c(i[r])&&c(i[r].values)){for(var o=i[r],s=o.values.length,l=!0,f=1;f<n;++f){var d=e[f][t].attributes[r];if(!c(d)||o.componentDatatype!==d.componentDatatype||o.componentsPerAttribute!==d.componentsPerAttribute||o.normalize!==d.normalize){l=!1;break}s+=d.values.length}l&&(a[r]=new E({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function L(e,t){var n,i,o,u,s,l,f,d=e.length,E=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,y=D(e,t);for(n in y)if(y.hasOwnProperty(n))for(s=y[n].values,u=0,i=0;i<d;++i)for(l=e[i][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(E){var T=0;for(i=0;i<d;++i)T+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:y,primitiveType:S.POINTS})),v=p.createTypedArray(R,T),A=0,N=0;for(i=0;i<d;++i){var g=e[i][t].indices,O=g.length;for(u=0;u<O;++u)v[A++]=N+g[u];N+=h.computeNumberOfVertices(e[i][t])}_=v}var I,w=new a,M=0;for(i=0;i<d;++i){if(I=e[i][t].boundingSphere,!c(I)){w=void 0;break}a.add(I.center,w,w)}if(c(w))for(a.divideByScalar(w,d,w),i=0;i<d;++i){I=e[i][t].boundingSphere;var x=a.magnitude(a.subtract(I.center,w,se))+I.radius;x>M&&(M=x)}return new h({attributes:y,indices:_,primitiveType:m,boundingSphere:c(w)?new r(w,M):void 0})}function U(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function b(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,a=3;a<t;++a)r[n++]=a-1,r[n++]=0,r[n++]=a;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function F(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,a=3;a<t-1;a+=2)r[n++]=a,r[n++]=a-1,r[n++]=a+1,a+2<t&&(r[n++]=a,r[n++]=a+1,r[n++]=a+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return e.indices=r,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function q(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return b(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return U(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<T.EPSILON6&&(e.y=t?-T.EPSILON6:T.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return V(e,e.y<0),V(t,t.y<0),void V(r,r.y<0);var n,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(r.y);n=a>i?a>o?T.sign(e.y):T.sign(r.y):i>o?T.sign(t.y):T.sign(r.y);var u=n<0;V(e,u),V(t,u),V(r,u)}function W(e,t,r,n){a.add(e,a.multiplyByScalar(a.subtract(t,e,ve),e.y/(e.y-t.y),ve),r),a.clone(r,n),V(r,!0),V(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,a=t.y<0,i=r.y<0,o=0;o+=n?1:0,o+=a?1:0,o+=i?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(W(e,t,Ae,Ne),W(e,r,Se,ge),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(W(t,r,Ae,Ne),W(t,e,Se,ge),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(W(r,e,Ae,Ne),W(r,t,Se,ge),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?a?i||(W(r,e,Ae,Ne),W(r,t,Se,ge),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(W(t,r,Ae,Ne),W(t,e,Se,ge),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(W(e,t,Ae,Ne),W(e,r,Se,ge),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=Ne,s[6]=ge,s.length=7),Oe}}function Y(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var a in n)if(n.hasOwnProperty(a)&&c(n[a])&&c(n[a].values)){var i=n[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=p.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function k(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var a=t[n];r[n]=new E({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:r,indices:[],primitiveType:e.primitiveType})}function j(e,t,r){var n=c(e.geometry.boundingSphere);t=Y(t,n),r=Y(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Z(e,r,i,o,u,s,l,f,d,h,E,m){if(c(s)||c(l)||c(f)||c(d)||c(h)){var p=a.fromArray(u,3*e,Ie),y=a.fromArray(u,3*r,we),_=a.fromArray(u,3*i,Me),T=t(o,p,y,_,xe);if(c(s)){var R=a.fromArray(s,3*e,Ie),v=a.fromArray(s,3*r,we),A=a.fromArray(s,3*i,Me);a.multiplyByScalar(R,T.x,R),a.multiplyByScalar(v,T.y,v),a.multiplyByScalar(A,T.z,A);var S=a.add(R,v,R);a.add(S,A,S),a.normalize(S,S),a.pack(S,E.normal.values,3*m)}if(c(h)){var N=a.fromArray(h,3*e,Ie),g=a.fromArray(h,3*r,we),O=a.fromArray(h,3*i,Me);a.multiplyByScalar(N,T.x,N),a.multiplyByScalar(g,T.y,g),a.multiplyByScalar(O,T.z,O);var I;a.equals(N,a.ZERO)&&a.equals(g,a.ZERO)&&a.equals(O,a.ZERO)?(I=Ie,I.x=0,I.y=0,I.z=0):(I=a.add(N,g,N),a.add(I,O,I),a.normalize(I,I)),a.pack(I,E.extrudeDirection.values,3*m)}if(c(l)){var w=a.fromArray(l,3*e,Ie),M=a.fromArray(l,3*r,we),x=a.fromArray(l,3*i,Me);a.multiplyByScalar(w,T.x,w),a.multiplyByScalar(M,T.y,M),a.multiplyByScalar(x,T.z,x);var C=a.add(w,M,w);a.add(C,x,C),a.normalize(C,C),a.pack(C,E.tangent.values,3*m)}if(c(f)){var P=a.fromArray(f,3*e,Ie),D=a.fromArray(f,3*r,we),L=a.fromArray(f,3*i,Me);a.multiplyByScalar(P,T.x,P),a.multiplyByScalar(D,T.y,D),a.multiplyByScalar(L,T.z,L);var U=a.add(P,D,P);a.add(U,L,U),a.normalize(U,U),a.pack(U,E.bitangent.values,3*m)}if(c(d)){var b=n.fromArray(d,2*e,Ce),F=n.fromArray(d,2*r,Pe),B=n.fromArray(d,2*i,De);n.multiplyByScalar(b,T.x,b),n.multiplyByScalar(F,T.y,F),n.multiplyByScalar(B,T.z,B);var z=n.add(b,F,b);n.add(z,B,z),n.pack(z,E.st.values,2*m)}}}function K(e,t,r,n,a,i){var o=e.position.values.length/3;if(-1!==a){var u=n[a],s=r[u];return-1===s?(r[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function J(e){var t,r,n,i,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,d=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,E=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,p=u.indices,y=k(u),_=k(u),T=[];T.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<T.length;++o)T[o]=-1,R[o]=-1;var v=p.length;for(o=0;o<v;o+=3){var A=p[o],S=p[o+1],N=p[o+2],g=a.fromArray(l,3*A),O=a.fromArray(l,3*S),I=a.fromArray(l,3*N),w=H(g,O,I);if(c(w)&&w.positions.length>3)for(var M=w.positions,x=w.indices,C=x.length,P=0;P<C;++P){var D=x[P],L=M[D];L.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=R),i=K(t,r,n,p,D<3?o+D:-1,L),Z(A,S,N,L,l,f,h,d,E,m,t,i)}else c(w)&&(g=w.positions[0],O=w.positions[1],I=w.positions[2]),g.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=R),i=K(t,r,n,p,o,g),Z(A,S,N,g,l,f,h,d,E,m,t,i),i=K(t,r,n,p,o+1,O),Z(A,S,N,O,l,f,h,d,E,m,t,i),i=K(t,r,n,p,o+2,I),Z(A,S,N,I,l,f,h,d,E,m,t,i)}j(e,_,y)}function Q(e){var t,r=e.geometry,n=r.attributes,i=n.position.values,o=r.indices,u=k(r),s=k(r),l=o.length,f=[];f.length=i.length/3;var d=[];for(d.length=i.length/3,t=0;t<f.length;++t)f[t]=-1,d[t]=-1;for(t=0;t<l;t+=2){var h=o[t],E=o[t+1],m=a.fromArray(i,3*h,Ie),p=a.fromArray(i,3*E,we);Math.abs(m.y)<T.EPSILON6&&(m.y<0?m.y=-T.EPSILON6:m.y=T.EPSILON6),Math.abs(p.y)<T.EPSILON6&&(p.y<0?p.y=-T.EPSILON6:p.y=T.EPSILON6);var y=u.attributes,R=u.indices,v=d,A=s.attributes,S=s.indices,N=f,g=_.lineSegmentPlane(m,p,Le,Me);if(c(g)){var O=a.multiplyByScalar(a.UNIT_Y,5*T.EPSILON9,Ue);m.y<0&&(a.negate(O,O),y=s.attributes,R=s.indices,v=f,A=u.attributes,S=u.indices,N=d);var I=a.add(g,O,be);K(y,R,v,o,t,m),K(y,R,v,o,-1,I),a.negate(O,O),a.add(g,O,I),K(A,S,N,o,-1,I),K(A,S,N,o,t+1,p)}else{var w,M,x;m.y<0?(w=s.attributes,M=s.indices,x=f):(w=u.attributes,M=u.indices,x=d),K(w,M,x,o,t,m),K(w,M,x,o,t+1,p)}}j(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,i=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=a.unpack(r,u,ze);if(!(s.x>0)){var c=a.unpack(n,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):a.pack(s,n,u));var l=a.unpack(i,u,qe);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=r[u+3],i[u+1]=r[u+4],i[u+2]=r[u+5]):a.pack(s,i,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,d=s.nextPosition.values,h=s.expandAndWidth.values,E=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,p=k(u),y=k(u),R=!1,v=l.length/3;for(t=0;t<v;t+=4){var A=t,S=t+2,N=a.fromArray(l,3*A,ze),g=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<ke)for(N.y=ke*(g.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(g.y)<ke)for(g.y=ke*(N.y<0?-1:1),l[3*(t+2)+1]=g.y,l[3*(t+3)+1]=g.y,r=3*A;r<3*A+12;r+=3)d[r]=l[3*(t+2)],d[r+1]=l[3*(t+2)+1],d[r+2]=l[3*(t+2)+2];var O=p.attributes,I=p.indices,w=y.attributes,M=y.indices,x=_.lineSegmentPlane(N,g,Le,Ve);if(c(x)){R=!0;var C=a.multiplyByScalar(a.UNIT_Y,Ye,Xe);N.y<0&&(a.negate(C,C),O=y.attributes,I=y.indices,w=p.attributes,M=p.indices);var P=a.add(x,C,We);O.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),O.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),O.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),a.negate(C,C),a.add(x,C,P),w.position.values.push(P.x,P.y,P.z),w.position.values.push(P.x,P.y,P.z),w.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.nextPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),w.nextPosition.values.push(d[3*S],d[3*S+1],d[3*S+2]),w.nextPosition.values.push(d[3*S+3],d[3*S+4],d[3*S+5]);var D=n.fromArray(h,2*A,Fe),L=Math.abs(D.y);O.expandAndWidth.values.push(-1,L,1,L),O.expandAndWidth.values.push(-1,-L,1,-L),w.expandAndWidth.values.push(-1,L,1,L),w.expandAndWidth.values.push(-1,-L,1,-L);var U=a.magnitudeSquared(a.subtract(x,N,qe));if(U/=a.magnitudeSquared(a.subtract(g,N,qe)),c(m)){var b=i.fromArray(m,4*A,He),F=i.fromArray(m,4*S,He),B=T.lerp(b.x,F.x,U),z=T.lerp(b.y,F.y,U),G=T.lerp(b.z,F.z,U),q=T.lerp(b.w,F.w,U);for(r=4*A;r<4*A+8;++r)O.color.values.push(m[r]);for(O.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),w.color.values.push(B,z,G,q),w.color.values.push(B,z,G,q),r=4*S;r<4*S+8;++r)w.color.values.push(m[r])}if(c(E)){var V=n.fromArray(E,2*A,Fe),X=n.fromArray(E,2*(t+3),Be),W=T.lerp(V.x,X.x,U);for(r=2*A;r<2*A+4;++r)O.st.values.push(E[r]);for(O.st.values.push(W,V.y),O.st.values.push(W,X.y),w.st.values.push(W,V.y),w.st.values.push(W,X.y),r=2*S;r<2*S+4;++r)w.st.values.push(E[r])}o=O.position.values.length/3-4,I.push(o,o+2,o+1),I.push(o+1,o+2,o+3),o=w.position.values.length/3-4,M.push(o,o+2,o+1),M.push(o+1,o+2,o+3)}else{var H,Y;for(N.y<0?(H=y.attributes,Y=y.indices):(H=p.attributes,Y=p.indices),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(d[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(h[r]),c(E)&&H.st.values.push(E[r]);if(c(m))for(r=4*t;r<4*t+16;++r)H.color.values.push(m[r]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}R&&($(y),$(p)),j(e,y,p)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=O(t);break;case S.TRIANGLE_STRIP:e.indices=I(t);break;case S.TRIANGLE_FAN:e.indices=w(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),f=0,d=0;d<o;d+=3)l[f++]=a[d],l[f++]=a[d+1],l[f++]=a[d+2],l[f++]=a[d]+i[d]*n,l[f++]=a[d+1]+i[d+1]*n,l[f++]=a[d+2]+i[d+2]*n;var m,p=e.boundingSphere;return c(p)&&(m=new r(p.center,p.radius+n)),new h({attributes:{position:new E({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){ -var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,a={},i=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(a[u]=i++)}for(var s in n)n.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),a=0;a<t;a++)n[a]=-1;for(var i,o=r,s=o.length,l=p.createTypedArray(t,s),f=0,d=0,E=0;f<s;)i=n[o[f]],-1!==i?l[d]=i:(i=o[f],n[i]=E,l[d]=E,++E),++f,++d;e.indices=l;var m=e.attributes;for(var y in m)if(m.hasOwnProperty(y)&&c(m[y])&&c(m[y].values)){for(var _=m[y],T=_.values,R=0,v=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,E*v);R<t;){var S=n[R];if(-1!==S)for(var N=0;N<v;N++)A[v*S+N]=T[v*R+N];++R}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,a=0,i=0;i<n;i++)r[i]>a&&(a=r[i]);e.indices=N.tipsify({indices:r,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=h.computeNumberOfVertices(e);if(c(e.indices)&&r>=T.SIXTY_FOUR_KILOBYTES){var n,a=[],i=[],o=0,u=M(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var d=0;d<n;++d){var E=s[f+d],m=a[E];c(m)||(m=o++,a[E]=m,x(u,e.attributes,E)),i.push(m)}o+n>=T.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=M(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new a,ne=new o;te.projectTo2D=function(e,t,r,n,i){var o=e.attributes[t];i=c(i)?i:new d;for(var s=i.ellipsoid,l=o.values,f=new Float64Array(l.length),h=0,m=0;m<l.length;m+=3){var p=a.fromArray(l,m,re),y=s.cartesianToCartographic(p,ne),_=i.project(y,re);f[h++]=_.x,f[h++]=_.y,f[h++]=_.z}return e.attributes[r]=o,e.attributes[n]=new E({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var d=a.componentsPerAttribute;return e.attributes[r]=new E({componentDatatype:u.FLOAT,componentsPerAttribute:d,values:s}),e.attributes[n]=new E({componentDatatype:u.FLOAT,componentsPerAttribute:d,values:c}),delete e.attributes[t],e};var ie=new a,oe=new v,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(v.equals(t,v.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(v.inverse(t,oe),v.transpose(oe,oe),v.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=r.transform(a,t,a)),e.modelMatrix=v.clone(v.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,a=0;a<n;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&r.push(i)}var o=[];return t.length>0&&o.push(L(t,"geometry")),r.length>0&&(o.push(L(r,"westHemisphereGeometry")),o.push(L(r,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,fe=new a,de=new a;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,i=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var d=0;for(t=0;t<s;t+=3){var h=r[t],m=r[t+1],p=r[t+2],y=3*h,_=3*m,R=3*p;le.x=i[y],le.y=i[y+1],le.z=i[y+2],fe.x=i[_],fe.y=i[_+1],fe.z=i[_+2],de.x=i[R],de.y=i[R+1],de.z=i[R+2],c[h].count++,c[m].count++,c[p].count++,a.subtract(fe,le,fe),a.subtract(de,le,de),l[d]=a.cross(fe,de,new a),d++}var v=0;for(t=0;t<o;t++)c[t].indexOffset+=v,v+=c[t].count;d=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var S=A.indexOffset+A.currentCount;f[S]=d,A.currentCount++,A=c[r[t+1]],S=A.indexOffset+A.currentCount,f[S]=d,A.currentCount++,A=c[r[t+2]],S=A.indexOffset+A.currentCount,f[S]=d,A.currentCount++,d++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var g=3*t;if(A=c[t],a.clone(a.ZERO,ce),A.count>0){for(d=0;d<A.count;d++)a.add(ce,l[f[A.indexOffset+d]],ce);a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&a.clone(l[f[A.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[g]=ce.x,N[g+1]=ce.y,N[g+2]=ce.z}return e.attributes.normal=new E({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,Ee=new a,me=new a;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,d,h;for(t=0;t<c;t+=3){var m=r[t],p=r[t+1],y=r[t+2];f=3*m,d=3*p,h=3*y;var _=2*m,T=2*p,R=2*y,v=n[f],A=n[f+1],S=n[f+2],N=o[_],g=o[_+1],O=o[T+1]-g,I=o[R+1]-g,w=1/((o[T]-N)*I-(o[R]-N)*O),M=(I*(n[d]-v)-O*(n[h]-v))*w,x=(I*(n[d+1]-A)-O*(n[h+1]-A))*w,C=(I*(n[d+2]-S)-O*(n[h+2]-S))*w;l[f]+=M,l[f+1]+=x,l[f+2]+=C,l[d]+=M,l[d+1]+=x,l[d+2]+=C,l[h]+=M,l[h+1]+=x,l[h+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,d=f+1,h=f+2;var L=a.fromArray(i,f,he),U=a.fromArray(l,f,me),b=a.dot(L,U);a.multiplyByScalar(L,b,Ee),a.normalize(a.subtract(U,Ee,U),U),P[f]=U.x,P[d]=U.y,P[h]=U.z,a.normalize(a.cross(L,U,U),U),D[f]=U.x,D[d]=U.y,D[h]=U.z}return e.attributes.tangent=new E({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new E({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var pe=new n,ye=new a,_e=new a,Te=new a,Re=new n;te.compressVertices=function(t){var r,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),f=0;for(r=0;r<i;++r)a.fromArray(s,3*r,ye),a.equals(ye,a.ZERO)?f+=2:(Re=e.octEncodeInRange(ye,65535,Re),l[f++]=Re.x,l[f++]=Re.y);return t.attributes.compressedAttributes=new E({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var d=t.attributes.normal,h=t.attributes.st,m=c(d),p=c(h);if(!m&&!p)return t;var y,_,T,R,v=t.attributes.tangent,A=t.attributes.bitangent,S=c(v),N=c(A);m&&(y=d.values),p&&(_=h.values),S&&(T=v.values),N&&(R=A.values),i=(m?y.length:_.length)/(m?3:2);var g=i,O=p&&m?2:1;O+=S||N?1:0,g*=O;var I=new Float32Array(g),w=0;for(r=0;r<i;++r){p&&(n.fromArray(_,2*r,pe),I[w++]=e.compressTextureCoordinates(pe));var M=3*r;m&&c(T)&&c(R)?(a.fromArray(y,M,ye),a.fromArray(T,M,_e),a.fromArray(R,M,Te),e.octPack(ye,_e,Te,pe),I[w++]=pe.x,I[w++]=pe.y):(m&&(a.fromArray(y,M,ye),I[w++]=e.octEncodeFloat(ye)),S&&(a.fromArray(T,M,ye),I[w++]=e.octEncodeFloat(ye)),N&&(a.fromArray(R,M,ye),I[w++]=e.octEncodeFloat(ye)))}return t.attributes.compressedAttributes=new E({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:I}),m&&delete t.attributes.normal,p&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var ve=new a,Ae=new a,Se=new a,Ne=new a,ge=new a,Oe={positions:new Array(7),indices:new Array(9)},Ie=new a,we=new a,Me=new a,xe=new a,Ce=new n,Pe=new n,De=new n,Le=A.fromPointNormal(a.ZERO,a.UNIT_Y),Ue=new a,be=new a,Fe=new n,Be=new n,ze=new a,Ge=new a,qe=new a,Ve=new a,Xe=new a,We=new a,He=new i,Ye=5*T.EPSILON9,ke=T.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==y.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else q(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,a){return t(e).then(r,n,a)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=a(e),t}function r(t){return e(t,i)}function n(e){this.then=e}function a(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return i(e)}})}function i(e){return new n(function(r,n){try{return n?t(n(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,r){return d(e,t,r)}function r(e){return E(e)}function a(e){return E(i(e))}function u(e){return h(e)}var s,c,l,f,d,h,E;return c=new n(e),s={then:e,resolve:r,reject:a,progress:u,promise:c,resolver:{resolve:r,reject:a,progress:u}},l=[],f=[],d=function(e,t,r){var n,a;return n=o(),a="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,a)}),f.push(a),n.promise},h=function(e){return m(f,e),e},E=function(e){return e=t(e),d=e.then,E=t,h=y,m(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,a,i){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,d,h,E,m,p,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,d=[],h=o(),c)for(p=h.progress,m=function(e){d.push(e),--l||(E=m=y,h.reject(d))},E=function(e){f.push(e),--c||(E=m=y,h.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,p);else h.resolve(f);return h.then(n,a,i)})}function c(e,t,r,n){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,r,n)}function l(e,t,r,n){return p(1,arguments),d(e,_).then(t,r,n)}function f(){return d(arguments,_)}function d(t,r){return e(t,function(t){var n,a,i,u,s,c;if(i=a=t.length>>>0,n=[],c=o(),i)for(u=function(t,a){e(t,r).then(function(e){n[a]=e,--i||c.resolve(n)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(n);return c.promise})}function h(t,r){var n=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,n[0]=function(t,n,i){return e(t,function(t){return e(n,function(e){return r(t,e,i,a)})})},T.apply(t,n)})}function E(t,r,n){var a=arguments.length>2;return e(t,function(e){return e=a?n:e,r.resolve(e),e},function(e){return r.reject(e),i(e)},r.progress)}function m(e,t){for(var r,n=0;r=e[n++];)r(t)}function p(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function y(){}function _(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=d,e.reduce=h,e.any=c,e.some=s,e.chain=E,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,r,n,a,i;if(i=0,t=Object(this),a=t.length>>>0,r=arguments,r.length<=1)for(;;){if(i in t){n=t[i++];break}if(++i>=a)throw new TypeError}else n=r[1];for(;i<a;++i)i in t&&(n=e(n,t[i],i,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,a,i=0,o=e.length-1;i<=o;)if(n=~~((i+o)/2),(a=r(e[n],t))<0)i=n+1;else{if(!(a>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],a=function(e,t,r,n){r||(r=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+a:a+e},i=function(e,t,r,n,i,o){var u=n-e.length;return u>0&&(e=r||!i?a(e,n,o,r):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+a(c.toString(t),u||0,"0",!1),i(e,r,n,o,s)},u=function(e,t,r,n,a,o){return null!=n&&(e=e.slice(0,n)),i(e,"",t,r,a,o)},s=function(e,n,s,c,l,f,d){var h,E,m,p,y;if("%%"==e)return"%";for(var _=!1,T="",R=!1,v=!1,A=" ",S=s.length,N=0;s&&N<S;N++)switch(s.charAt(N)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(N+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(d)>-1?6:"d"==d?0:void 0,y=n?t[n.slice(0,-1)]:t[r++],d){case"s":return u(String(y),_,c,f,R,A);case"c":return u(String.fromCharCode(+y),_,c,f,R);case"b":return o(y,2,v,_,c,f,R);case"o":return o(y,8,v,_,c,f,R);case"x":return o(y,16,v,_,c,f,R);case"X":return o(y,16,v,_,c,f,R).toUpperCase();case"u":return o(y,10,v,_,c,f,R);case"i":case"d":return h=+y||0,h=Math.round(h-h%1),E=h<0?"-":T,y=E+a(String(Math.abs(h)),f,"0",!1),i(y,E,_,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return h=+y,E=h<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(d.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(d)%2],y=E+Math.abs(h)[m](f),i(y,E,_,c,R)[p]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,a,i,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var a=r[n].offset;if(n>0){m.secondsDifference(r[n].julianDate,e)>a&&(n--,a=r[n].offset)}m.addSeconds(e,a,e)}function d(e,r){_.julianDate=e;var n=m.leapSeconds,a=t(n,_,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-n[0].offset,r);if(a>=n.length)return m.addSeconds(e,-n[a-1].offset,r);var i=m.secondsDifference(n[a].julianDate,e);return 0===i?m.addSeconds(e,-n[a].offset,r):i<=1?void 0:m.addSeconds(e,-n[--a].offset,r)}function h(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function E(e,t,r,n,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=i+(n*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,h(a,t,this),n===c.UTC&&f(this)}var p=new i,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,N=/([Z+\-])?(\d{2})?:?(\d{2})?$/,g=/^(\d{2})(\.\d+)?/.source+N.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+N.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+N.source;m.fromGregorianDate=function(e,t){var r=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(h(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromDate=function(e,t){var r=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(h(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,a,i,u=e.split("T"),s=1,l=1,d=0,p=0,_=0,N=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(R)))r=+u[1],s=+u[2];else if(null!==(u=w.match(T)))r=+u[1];else{var x;if(null!==(u=w.match(v)))r=+u[1],x=+u[2],i=o(r);else if(null!==(u=w.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));x=7*C+P-D.getUTCDay()-3}a=new Date(Date.UTC(r,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(r);var L;if(n(M)){u=M.match(I),null!==u?(d=+u[1],p=+u[2],_=+u[3],N=1e3*+(u[4]||0),L=5):(u=M.match(O),null!==u?(d=+u[1],p=+u[2],_=60*+(u[3]||0),L=4):null!==(u=M.match(g))&&(d=+u[1],p=60*+(u[2]||0),L=3));var U=u[L],b=+u[L+1],F=+(u[L+2]||0);switch(U){case"+":d-=b,p-=F;break;case"-":d+=b,p+=F;break;case"Z":break;default:p+=new Date(Date.UTC(r,s-1,l,d,p)).getTimezoneOffset()}}var B=60===_;for(B&&_--;p>=60;)p-=60,d++;for(;d>=24;)d-=24,l++;for(a=i&&2===s?29:y[s-1];l>a;)l-=a,s++,s>12&&(s-=12,r++),a=i&&2===s?29:y[s-1];for(;p<0;)p+=60,d--;for(;d<0;)d+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),a=i&&2===s?29:y[s-1],l+=a;var z=E(r,s,l,d,p,_,N);return n(t)?(h(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var w=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var r=!1,a=d(e,w);n(a)||(m.addSeconds(e,-1,w),a=d(w,w),r=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var h=80*c/2447|0,E=c-(2447*h/80|0)|0;c=h/11|0;var p=h+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(v+=1),n(t)?(t.year=y,t.month=p,t.day=E,t.hour=_,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=r,t):new i(y,p,E,_,R,v,A,r)},m.toDate=function(e){var t=m.toGregorianDate(e,p),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var a,i=m.toGregorianDate(t,p);return n(r)||0===i.millisecond?n(r)&&0!==r?(a=(.01*i.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},m.addSeconds=function(e,t,r){return h(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return h(e.dayNumber,n,r)},m.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return h(e.dayNumber,n,r)},m.addDays=function(e,t,r){return h(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var a=new r.constructor;for(var i in r)if(r.hasOwnProperty(i)){var o=r[i];n&&(o=t(o,n)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,r){"use strict";function n(n){n=e(n,e.EMPTY_OBJECT);var a=e(n.throttleByServer,!1),i=a||e(n.throttle,!1);this.url=n.url,this.requestFunction=n.requestFunction,this.cancelFunction=n.cancelFunction,this.priorityFunction=n.priorityFunction,this.priority=e(n.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(n.type,r.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return n.prototype.cancel=function(){this.cancelled=!0},n}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var a=r[n],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(a[c],a[e])<0?c:e,s<r&&n(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,n=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return r(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return i(r,e,--this._length),this.heapify(e),n}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<l.maximumRequestsPerServer}function h(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function p(e){var t=h(e);return e.state=s.ACTIVE,S.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function y(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function _(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),_())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},v=20,A=new i({comparator:c});A.maximumLength=v,A.reserve(v);var S=[],N={},g="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return v},set:function(e){if(e<v)for(;A.length>e;){var t=A.pop();y(t)}v=e,A.maximumLength=e,A.reserve(e)}}}),l.update=function(){var e,t,r=0,n=S.length;for(e=0;e<n;++e)t=S[e],t.cancelled&&y(t),t.state===s.ACTIVE?r>0&&(S[e-r]=t):++r;S.length-=r;var a=A.internalArray,i=A.length;for(e=0;e<i;++e)f(a[e]);A.resort();for(var o=Math.max(l.maximumRequests-S.length,0),u=0;u<o&&A.length>0;)t=A.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(p(t),++u):y(t);T()},l.getServerKey=function(t){var r=new e(t).resolve(g);r.normalize();var a=r.authority;/:/.test(a)||(a=a+":"+("https"===r.scheme?"443":"80"));var i=N[a];return n(i)||(N[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return p(e);if(!(S.length>=l.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){f(e);var t=A.insert(e);if(n(t)){if(t===e)return;y(t)}return h(e)}},l.clearForSpecs=function(){for(;A.length>0;){y(A.pop())}for(var e=S.length,t=0;t<e;++t)y(S[t]);S.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return N[e]},l.requestHeap=A,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var a=n.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=n.getScheme() -;if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,r){var n=e.toLowerCase()+":"+r;t(i[n])||(i[n]=!0)},a.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(i[n])&&delete i[n]},a.contains=function(e){var r=n(e);return!(!t(r)||!t(i[r]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t){t=r(t,r.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=r(t.method,"GET"),c=t.data,f=t.headers,d=t.overrideMimeType;a=r(a,t.url);var h=n(t.request)?t.request:new i;return h.url=a,h.requestFunction=function(){var t=e.defer(),r=l.load(a,o,s,c,f,t,d);return n(r)&&n(r.abort)&&(h.cancelFunction=function(){r.abort()}),t.promise},u.request(h)}function f(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function d(e,t){for(var r=f(e,t),n=new ArrayBuffer(r.length),a=new Uint8Array(n),i=0;i<r.length;i++)a[i]=r.charCodeAt(i);return n}function h(e,t){t=r(t,"");var n=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return d(a,i);case"blob":var o=d(a,i);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(f(a,i),n);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,r,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(h(f,t));var d=new XMLHttpRequest;if(c.contains(e)&&(d.withCredentials=!0),n(l)&&n(d.overrideMimeType)&&d.overrideMimeType(l),d.open(r,e,!0),n(i))for(var m in i)i.hasOwnProperty(m)&&d.setRequestHeader(m,i[m]);n(t)&&(d.responseType=t);var p=!1;return"string"==typeof e&&(p=0===e.indexOf("file://")),d.onload=function(){if((d.status<200||d.status>=300)&&(!p||0!==d.status))return void u.reject(new o(d.status,d.response,d.getAllResponseHeaders()));var e=d.response,r=d.responseType;if(204===d.status)u.resolve();else if(!n(e)||n(t)&&r!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===r||"document"===r)&&n(d.responseXML)&&d.responseXML.hasChildNodes()?u.resolve(d.responseXML):""!==r&&"text"!==r||!n(d.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(d.responseText);else u.resolve(e)},d.onerror=function(e){u.reject(new o)},d.send(a),d},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,r,n){return e({url:t,headers:r,request:n})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,r,n){"use strict";function a(r,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=n(r,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,a,i,o,u,s,c,l,f){"use strict";function d(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))E(this,t.data);else if(n(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function h(e,t){return o.compare(e.julianDate,t)}function E(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=r.columnNames.indexOf("modifiedJulianDateUtc"),i=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),d=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||d<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=r.samples,y=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=d,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,R=0,v=p.length;R<v;R+=e._columnCount){var A=p[R+a],S=p[R+m],N=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,g=new o(N,S,f.TAI);if(y.push(g),T){if(S!==_&&n(_)){var O=o.leapSeconds,I=t(O,g,h);if(I<0){var w=new u(g,S);O.splice(~I,0,w)}}_=S}}}function m(e,t,r,n,a){var i=r*n;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,r){return t+e*(r-t)}function y(e,t,r,n,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||n.equals(c))return m(e,r,a,s,u),u;if(n.equals(l))return m(e,r,i,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),d=a*s,h=i*s,E=r[d+e._ut1MinusUtcSecondsColumn],y=r[h+e._ut1MinusUtcSecondsColumn],_=y-E;if(_>.5||_<-.5){var T=r[d+e._taiMinusUtcSecondsColumn],R=r[h+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(n)?E=y:y-=R-T)}return u.xPoleWander=p(f,r[d+e._xPoleWanderRadiansColumn],r[h+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,r[d+e._yPoleWanderRadiansColumn],r[h+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,r[d+e._xCelestialPoleOffsetRadiansColumn],r[h+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,r[d+e._yCelestialPoleOffsetRadiansColumn],r[h+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,y),u}return d.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),d.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},d.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new a(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var i=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=i[u],d=i[u+1],h=o.lessThanOrEquals(f,e),E=!n(d),m=E||o.greaterThanOrEquals(d,e);if(h&&m)return s=u,!E&&d.equals(e)&&++s,l=s+1,y(this,i,this._samples,e,s,l,r),r}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,i,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},d}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=t(n,document.location.href);var a=new e(n);return new e(r).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(n,a,i){if(i=t(i,!0),n instanceof e||(n=new e(n)),a instanceof e||(a=new e(a)),"data"===n.scheme)return n.toString();if("data"===a.scheme)return a.toString();r(a.authority)&&!r(a.scheme)&&("undefined"!=typeof document&&r(document.location)&&r(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=n.scheme);var o=n;a.isAbsolute()&&(o=a);var u="";r(o.scheme)&&(u+=o.scheme+":"),r(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===n?i?n.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):n.path+a.path:a.path;var s=r(n.query),c=r(a.query);s&&c?u+="?"+n.query+"&"+a.query:s&&!c?u+="?"+n.query:!s&&c&&(u+="?"+a.query);var l=r(a.fragment);return r(n.fragment)&&!l?u+="#"+n.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,r,n,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),a=E.exec(n);if(null!==a)return a[1]}}function u(){if(t(f))return f;var r;return r="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(n(r))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(d)||(d=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(h)||(h=document.createElement("a"));var r=d(e);return h.href=r,h.href=h.href,h.href}var f,d,h,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){n[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(n[s]*=s-c);n[s]=1/n[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,i.daysDifference(n,e._sampleZeroDateTT)}function l(r,a){if(r._chunkDownloadsInProgress[a])return r._chunkDownloadsInProgress[a];var i=e.defer();r._chunkDownloadsInProgress[a]=i;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){r._chunkDownloadsInProgress[a]=!1;for(var t=r._samples,n=e.samples,o=a*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,r,n,a){var i=c(this,t,r),o=c(this,n,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,d=s/this._samplesPerXysFile|0,h=[],E=f;E<=d;++E)h.push(l(this,E));return e.all(h)},s.prototype.computeXysRadians=function(e,t,r){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var d=!1,h=this._samples;if(n(h[3*s])||(l(this,s/this._samplesPerXysFile|0),d=!0),n(h[3*f])||(l(this,f/this._samplesPerXysFile|0),d=!0),!d){n(r)?(r.x=0,r.y=0,r.s=0):r=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)y[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=y[m]);T[E]*=_[E];var v=3*(s+E);r.x+=T[E]*h[v++],r.y+=T[E]*h[v++],r.s+=T[E]*h[v]}return r}}}},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,a,i,o,u,s,c,l,f,d,h,E,m,p,y,_,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},N={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},g=new r,O=new r,I=new r;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,a=v[e][t],i=e+t;return u(S[i])?n=S[i]:(n=function(n,i,s){if(u(s)||(s=new y),m.equalsEpsilon(n.x,0,m.EPSILON14)&&m.equalsEpsilon(n.y,0,m.EPSILON14)){var c=m.sign(n.z);r.unpack(A[e],0,g),"east"!==e&&"west"!==e&&r.multiplyByScalar(g,c,g),r.unpack(A[t],0,O),"east"!==t&&"west"!==t&&r.multiplyByScalar(O,c,O),r.unpack(A[a],0,I),"east"!==a&&"west"!==a&&r.multiplyByScalar(I,c,I)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(n,N.up);var l=N.up,d=N.east;d.x=-n.y,d.y=n.x,d.z=0,r.normalize(d,N.east),r.cross(l,d,N.north),r.multiplyByScalar(N.up,-1,N.down),r.multiplyByScalar(N.east,-1,N.west),r.multiplyByScalar(N.north,-1,N.south),g=N[e],O=N[t],I=N[a]}return s[0]=g.x,s[1]=g.y,s[2]=g.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},S[i]=n),n},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var w=new _,M=new r(1,1,1),x=new y;R.headingPitchRollToFixedFrame=function(e,t,n,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=y.fromTranslationQuaternionRotationScale(r.ZERO,u,M,x);return i=a(e,n,i),y.multiply(i,s,i)};var C=new y,P=new p;R.headingPitchRollQuaternion=function(e,t,r,n,a){var i=R.headingPitchRollToFixedFrame(e,t,r,n,C),o=y.getRotation(i,P);return _.fromRotationMatrix(o,a)};var D=m.TWO_PI/86400,L=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){L=E.addSeconds(e,-E.computeTaiMinusUtc(e),L);var r,n=L.dayNumber,a=L.secondsOfDay,i=n-2451545;r=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,d=Math.cos(f),h=Math.sin(f);return u(t)?(t[0]=d,t[1]=-h,t[2]=0,t[3]=h,t[4]=d,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(d,h,0,-h,d,0,0,0,1)},R.iau2006XysData=new d,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(r,n,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var r=R.computeFixedToIcrfMatrix(e,t);if(u(r))return p.transpose(r,t)};var U=new h(0,0,0),b=new l(0,0,0,0,0,0),F=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var r=R.earthOrientationParameters.compute(e,b);if(u(r)){var n=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(n,a,U);if(u(i)){var o=i.x+r.xPoleOffset,s=i.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,B),d=p.multiply(l,f,F),h=e.dayNumber,y=e.secondsOfDay-E.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=h-2451545,v=y/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(_+v);A=A%1*m.TWO_PI;var S=p.fromRotationZ(A,B),N=p.multiply(d,S,F),g=Math.cos(r.xPoleWander),O=Math.cos(r.yPoleWander),I=Math.sin(r.xPoleWander),w=Math.sin(r.yPoleWander),M=n-2451545+a/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),D=B;return D[0]=g*C,D[1]=g*P,D[2]=I,D[3]=-O*P+w*I*C,D[4]=O*C+w*I*P,D[5]=-w*g,D[6]=-w*P-O*I*C,D[7]=w*C-O*I*P,D[8]=O*g,p.multiply(N,D,t)}}};var z=new n;R.pointToWindowCoordinates=function(e,t,r,n){return n=R.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},R.pointToGLWindowCoordinates=function(e,r,a,i){u(i)||(i=new t);var o=z;return y.multiplyByVector(e,n.fromElements(a.x,a.y,a.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(r,o,o),t.fromCartesian4(o,i)};var G=new r,q=new r,V=new r;R.rotationMatrixFromPositionVelocity=function(e,t,n,a){var i=o(n,f.WGS84).geodeticSurfaceNormal(e,G),s=r.cross(t,i,q);r.equalsEpsilon(s,r.ZERO,m.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,V);return r.cross(t,c,s),r.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var X=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),W=new a,H=new r,Y=new r,k=new p,j=new y,Z=new y;return R.basisTo2D=function(e,t,n){var a=y.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,W),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,n);return y.multiply(X,f,n),y.setTranslation(n,u,n),n},R.wgs84To2DModelMatrix=function(e,t,n){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=y.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,W),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(X,o,n),y.multiply(c,n,n),n},R}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,n){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=n(new a({position:!0})),a.POSITION_AND_NORMAL=n(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=n(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=n(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=n(new a({position:!0,color:!0})),a.ALL=n(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,r,n){return n=e(n,0),r[n++]=t.position?1:0,r[n++]=t.normal?1:0,r[n++]=t.st?1:0,r[n++]=t.tangent?1:0,r[n++]=t.bitangent?1:0,r[n]=t.color?1:0,r},a.unpack=function(r,n,i){return n=e(n,0),t(i)||(i=new a),i.position=1===r[n++],i.normal=1===r[n++],i.st=1===r[n++],i.tangent=1===r[n++],i.bitangent=1===r[n++],i.color=1===r[n],i},a.clone=function(e,r){if(t(e))return t(r)||(r=new a),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},a}),define("Core/EllipseGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./Matrix4","./PrimitiveType","./Quaternion","./Rectangle","./Transforms","./VertexFormat"],function(e,t,r,n,a,i,o,u,s,c,l,f,d,h,E,m,p,y,_,T,R,v,A,S,N,g){"use strict";function O(e,n,i){var o=n.vertexFormat,u=n.center,s=n.semiMajorAxis,l=n.semiMinorAxis,d=n.ellipsoid,m=n.stRotation,p=i?e.length/3*2:e.length/3,y=n.shadowVolume,_=o.st?new Float32Array(2*p):void 0,R=o.normal?new Float32Array(3*p):void 0,v=o.tangent?new Float32Array(3*p):void 0,S=o.bitangent?new Float32Array(3*p):void 0,N=y?new Float32Array(3*p):void 0,g=0,O=q,I=V,w=X,M=new f(d),x=M.project(d.cartesianToCartographic(u,W),H),C=d.scaleToGeodeticSurface(u,L);d.geodeticSurfaceNormal(C,C);for(var P=A.fromAxisAngle(C,m,G),D=T.fromQuaternion(P,z),F=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Y),j=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,k),Z=e.length,K=i?Z:0,J=K/3*2,Q=0;Q<Z;Q+=3){var $=Q+1,ee=Q+2,te=r.fromArray(e,Q,L);if(o.st){var re=T.multiplyByVector(D,te,U),ne=M.project(d.cartesianToCartographic(re,W),b);r.subtract(ne,x,ne),B.x=(ne.x+s)/(2*s),B.y=(ne.y+l)/(2*l),F.x=Math.min(B.x,F.x),F.y=Math.min(B.y,F.y),j.x=Math.max(B.x,j.x),j.y=Math.max(B.y,j.y),i&&(_[g+J]=B.x,_[g+1+J]=B.y),_[g++]=B.x,_[g++]=B.y}(o.normal||o.tangent||o.bitangent||y)&&(O=d.geodeticSurfaceNormal(te,O),y&&(N[Q+K]=-O.x,N[$+K]=-O.y,N[ee+K]=-O.z),(o.normal||o.tangent||o.bitangent)&&((o.tangent||o.bitangent)&&(I=r.normalize(r.cross(r.UNIT_Z,O,I),I),T.multiplyByVector(D,I,I)),o.normal&&(R[Q]=O.x,R[$]=O.y,R[ee]=O.z,i&&(R[Q+K]=-O.x,R[$+K]=-O.y,R[ee+K]=-O.z)),o.tangent&&(v[Q]=I.x,v[$]=I.y,v[ee]=I.z,i&&(v[Q+K]=-I.x,v[$+K]=-I.y,v[ee+K]=-I.z)),o.bitangent&&(w=r.normalize(r.cross(O,I,w),w),S[Q]=w.x,S[$]=w.y,S[ee]=w.z,i&&(S[Q+K]=w.x,S[$+K]=w.y,S[ee+K]=w.z))))}if(o.st){Z=_.length;for(var ae=0;ae<Z;ae+=2)_[ae]=(_[ae]-F.x)/(j.x-F.x),_[ae+1]=(_[ae+1]-F.y)/(j.y-F.y)}var ie=new E;if(o.position){var oe=c.raisePositionsToHeight(e,n,i);ie.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:oe})}return o.st&&(ie.st=new h({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:_})),o.normal&&(ie.normal=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:R})),o.tangent&&(ie.tangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:v})),o.bitangent&&(ie.bitangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:S})),y&&(ie.extrudeDirection=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:N})),ie}function I(e){var t,r,n,a,i,o=new Array(e*(e+1)*12-6),u=0;for(t=0,n=1,a=0;a<3;a++)o[u++]=n++,o[u++]=t,o[u++]=n;for(a=2;a<e+1;++a){for(n=a*(a+1)-1,t=(a-1)*a-1,o[u++]=n++,o[u++]=t,o[u++]=n,r=2*a,i=0;i<r-1;++i)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=n++,o[u++]=t,o[u++]=n}for(r=2*e,++n,++t,a=0;a<r-1;++a)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;for(o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t++,o[u++]=t,++t,a=e-1;a>1;--a){for(o[u++]=t++,o[u++]=t,o[u++]=n,r=2*a,i=0;i<r-1;++i)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=t++,o[u++]=t++,o[u++]=n++}for(a=0;a<3;a++)o[u++]=t++,o[u++]=t,o[u++]=n;return o}function w(t){var n=t.center;j=r.multiplyByScalar(t.ellipsoid.geodeticSurfaceNormal(n,j),t.height,j),j=r.add(n,j,j);var a=new e(j,t.semiMajorAxis),i=c.computeEllipsePositions(t,!0,!1),o=i.positions,u=i.numPts,s=O(o,t,!1),l=I(u);return l=y.createTypedArray(o.length/3,l),{boundingSphere:a,attributes:s,indices:l}}function M(e,n){var i=n.vertexFormat,o=n.center,u=n.semiMajorAxis,s=n.semiMinorAxis,c=n.ellipsoid,l=n.height,d=n.extrudedHeight,m=n.stRotation,p=e.length/3*2,y=new Float64Array(3*p),_=i.st?new Float32Array(2*p):void 0,R=i.normal?new Float32Array(3*p):void 0,v=i.tangent?new Float32Array(3*p):void 0,S=i.bitangent?new Float32Array(3*p):void 0,N=n.shadowVolume,g=N?new Float32Array(3*p):void 0,O=0,I=q,w=V,M=X,x=new f(c),C=x.project(c.cartesianToCartographic(o,W),H),P=c.scaleToGeodeticSurface(o,L);c.geodeticSurfaceNormal(P,P);for(var D=A.fromAxisAngle(P,m,G),j=T.fromQuaternion(D,z),Z=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Y),K=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,k),J=e.length,Q=J/3*2,$=0;$<J;$+=3){var ee,te=$+1,re=$+2,ne=r.fromArray(e,$,L);if(i.st){var ae=T.multiplyByVector(j,ne,U),ie=x.project(c.cartesianToCartographic(ae,W),b);r.subtract(ie,C,ie),B.x=(ie.x+u)/(2*u),B.y=(ie.y+s)/(2*s),Z.x=Math.min(B.x,Z.x),Z.y=Math.min(B.y,Z.y),K.x=Math.max(B.x,K.x),K.y=Math.max(B.y,K.y),_[O+Q]=B.x,_[O+1+Q]=B.y,_[O++]=B.x,_[O++]=B.y}ne=c.scaleToGeodeticSurface(ne,ne),ee=r.clone(ne,U),I=c.geodeticSurfaceNormal(ne,I),N&&(g[$+J]=-I.x,g[te+J]=-I.y,g[re+J]=-I.z);var oe=r.multiplyByScalar(I,l,F);if(ne=r.add(ne,oe,ne),oe=r.multiplyByScalar(I,d,oe),ee=r.add(ee,oe,ee),i.position&&(y[$+J]=ee.x,y[te+J]=ee.y,y[re+J]=ee.z,y[$]=ne.x,y[te]=ne.y,y[re]=ne.z),i.normal||i.tangent||i.bitangent){M=r.clone(I,M);var ue=r.fromArray(e,($+3)%J,F);r.subtract(ue,ne,ue);var se=r.subtract(ee,ne,b);I=r.normalize(r.cross(se,ue,I),I),i.normal&&(R[$]=I.x,R[te]=I.y,R[re]=I.z,R[$+J]=I.x,R[te+J]=I.y,R[re+J]=I.z),i.tangent&&(w=r.normalize(r.cross(M,I,w),w),v[$]=w.x,v[te]=w.y,v[re]=w.z,v[$+J]=w.x,v[$+1+J]=w.y,v[$+2+J]=w.z),i.bitangent&&(S[$]=M.x,S[te]=M.y,S[re]=M.z,S[$+J]=M.x,S[te+J]=M.y,S[re+J]=M.z)}}if(i.st){J=_.length;for(var ce=0;ce<J;ce+=2)_[ce]=(_[ce]-Z.x)/(K.x-Z.x),_[ce+1]=(_[ce+1]-Z.y)/(K.y-Z.y)}var le=new E;return i.position&&(le.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:y})),i.st&&(le.st=new h({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:_})),i.normal&&(le.normal=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:R})),i.tangent&&(le.tangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:v})),i.bitangent&&(le.bitangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:S})),N&&(le.extrudeDirection=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:g})),le}function x(e){for(var t=e.length/3,r=y.createTypedArray(t,6*t),n=0,a=0;a<t;a++){var i=a,o=a+t,u=(i+1)%t,s=u+t;r[n++]=i,r[n++]=o,r[n++]=u,r[n++]=u,r[n++]=o,r[n++]=s}return r}function C(t){var n=t.center,a=t.ellipsoid,i=t.semiMajorAxis,o=r.multiplyByScalar(a.geodeticSurfaceNormal(n,L),t.height,L);Z.center=r.add(n,o,Z.center),Z.radius=i,o=r.multiplyByScalar(a.geodeticSurfaceNormal(n,o),t.extrudedHeight,o),K.center=r.add(n,o,K.center),K.radius=i;var u=c.computeEllipsePositions(t,!0,!0),s=u.positions,l=u.numPts,f=u.outerPositions,h=e.union(Z,K),E=O(s,t,!0),_=I(l),T=_.length;_.length=2*T;for(var R=s.length/3,A=0;A<T;A+=3)_[A+T]=_[A+2]+R,_[A+1+T]=_[A+1]+R,_[A+2+T]=_[A]+R;var S=y.createTypedArray(2*R/3,_),N=new d({attributes:E,indices:S,primitiveType:v.TRIANGLES}),g=M(f,t);_=x(f);var w=y.createTypedArray(2*f.length/3,_),C=new d({attributes:g,indices:w,primitiveType:v.TRIANGLES}),P=p.combineInstances([new m({geometry:N}),new m({geometry:C})]);return{boundingSphere:h,attributes:P[0].attributes,indices:P[0].indices}}function P(e,t,n,a,i){N.eastNorthUpToFixedFrame(e,t,J),R.inverseTransformation(J,Q);var o;for(o=0;o<4;++o)r.clone(r.ZERO,ee[o]);for(ee[0].x+=n,ee[1].x-=n,ee[2].y+=a,ee[3].y-=a,T.fromRotationZ(i,$),o=0;o<4;++o)T.multiplyByVector($,ee[o],ee[o]),R.multiplyByPoint(J,ee[o],ee[o]),t.cartesianToCartographic(ee[o],te[o]);return S.fromCartographicArray(te)}function D(e){e=i(e,i.EMPTY_OBJECT);var t=e.center,n=i(e.ellipsoid,l.WGS84),a=e.semiMajorAxis,u=e.semiMinorAxis,s=i(e.granularity,_.RADIANS_PER_DEGREE),c=i(e.height,0),f=e.extrudedHeight,d=o(f)&&Math.abs(c-f)>1,h=i(e.vertexFormat,g.DEFAULT);this._center=r.clone(t),this._semiMajorAxis=a,this._semiMinorAxis=u,this._ellipsoid=l.clone(n),this._rotation=i(e.rotation,0),this._stRotation=i(e.stRotation,0),this._height=c,this._granularity=s,this._vertexFormat=g.clone(h),this._extrudedHeight=i(f,c),this._extrude=d,this._shadowVolume=i(e.shadowVolume,!1),this._workerName="createEllipseGeometry",this._rectangle=P(this._center,this._ellipsoid,a,u,this._rotation)}var L=new r,U=new r,b=new r,F=new r,B=new t,z=new T,G=new A,q=new r,V=new r,X=new r,W=new n,H=new r,Y=new t,k=new t,j=new r,Z=new e,K=new e,J=new R,Q=new R,$=new T,ee=[new r,new r,new r,new r],te=[new n,new n,new n,new n];D.packedLength=r.packedLength+l.packedLength+g.packedLength+S.packedLength+9,D.pack=function(e,t,n){return n=i(n,0),r.pack(e._center,t,n),n+=r.packedLength,l.pack(e._ellipsoid,t,n),n+=l.packedLength,g.pack(e._vertexFormat,t,n),n+=g.packedLength,S.pack(e._rectangle,t,n),n+=S.packedLength,t[n++]=e._semiMajorAxis,t[n++]=e._semiMinorAxis,t[n++]=e._rotation,t[n++]=e._stRotation,t[n++]=e._height,t[n++]=e._granularity,t[n++]=e._extrudedHeight,t[n++]=e._extrude?1:0,t[n]=e._shadowVolume?1:0,t};var re=new r,ne=new l,ae=new g,ie=new S,oe={center:re,ellipsoid:ne,vertexFormat:ae,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,stRotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,shadowVolume:void 0};return D.unpack=function(e,t,n){t=i(t,0);var a=r.unpack(e,t,re);t+=r.packedLength;var u=l.unpack(e,t,ne);t+=l.packedLength;var s=g.unpack(e,t,ae);t+=g.packedLength;var c=S.unpack(e,t,ie);t+=S.packedLength;var f=e[t++],d=e[t++],h=e[t++],E=e[t++],m=e[t++],p=e[t++],y=e[t++],_=1===e[t++],T=1===e[t];return o(n)?(n._center=r.clone(a,n._center),n._ellipsoid=l.clone(u,n._ellipsoid),n._vertexFormat=g.clone(s,n._vertexFormat),n._semiMajorAxis=f,n._semiMinorAxis=d,n._rotation=h,n._stRotation=E,n._height=m,n._granularity=p,n._extrudedHeight=y,n._extrude=_,n._shadowVolume=T,n._rectangle=S.clone(c),n):(oe.height=m,oe.extrudedHeight=y,oe.granularity=p,oe.stRotation=E,oe.rotation=h,oe.semiMajorAxis=f,oe.semiMinorAxis=d,oe.shadowVolume=T,new D(oe))},D.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,vertexFormat:e._vertexFormat,stRotation:e._stRotation};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),r.shadowVolume=e._shadowVolume,t=C(r)):t=w(r),new d({attributes:t.attributes,indices:t.indices,primitiveType:v.TRIANGLES,boundingSphere:t.boundingSphere})}},D.createShadowVolume=function(e,t,r){var n=e._granularity,a=e._ellipsoid,i=t(n,a),o=r(n,a);return new D({center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:a,rotation:e._rotation,stRotation:e._stRotation,granularity:n,extrudedHeight:i,height:o,vertexFormat:g.POSITION_ONLY,shadowVolume:!0})},u(D.prototype,{rectangle:{get:function(){return this._rectangle}}}),D}),define("Core/CircleGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./EllipseGeometry","./Ellipsoid","./VertexFormat"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT);var t=e.radius,n={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,vertexFormat:e.vertexFormat,stRotation:e.stRotation,shadowVolume:e.shadowVolume};this._ellipseGeometry=new i(n),this._workerName="createCircleGeometry"}s.packedLength=i.packedLength,s.pack=function(e,t,r){return i.pack(e._ellipseGeometry,t,r)};var c=new i({center:new e,semiMajorAxis:1,semiMinorAxis:1}),l={center:new e,radius:void 0,ellipsoid:o.clone(o.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0, -vertexFormat:new u,stRotation:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0,shadowVolume:void 0};return s.unpack=function(t,r,a){var f=i.unpack(t,r,c);return l.center=e.clone(f._center,l.center),l.ellipsoid=o.clone(f._ellipsoid,l.ellipsoid),l.height=f._height,l.extrudedHeight=f._extrudedHeight,l.granularity=f._granularity,l.vertexFormat=u.clone(f._vertexFormat,l.vertexFormat),l.stRotation=f._stRotation,l.shadowVolume=f._shadowVolume,n(a)?(l.semiMajorAxis=f._semiMajorAxis,l.semiMinorAxis=f._semiMinorAxis,a._ellipseGeometry=new i(l),a):(l.radius=f._semiMajorAxis,new s(l))},s.createGeometry=function(e){return i.createGeometry(e._ellipseGeometry)},s.createShadowVolume=function(e,t,r){var n=e._ellipseGeometry._granularity,a=e._ellipseGeometry._ellipsoid,i=t(n,a),o=r(n,a);return new s({center:e._ellipseGeometry._center,radius:e._ellipseGeometry._semiMajorAxis,ellipsoid:a,stRotation:e._ellipseGeometry._stRotation,granularity:n,extrudedHeight:i,height:o,vertexFormat:u.POSITION_ONLY,shadowVolume:!0})},a(s.prototype,{rectangle:{get:function(){return this._ellipseGeometry.rectangle}}}),s}),define("Workers/createCircleGeometry",["../Core/Cartesian3","../Core/CircleGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,r,n){"use strict";function a(a,i){return r(i)&&(a=t.unpack(a,i)),a._ellipseGeometry._center=e.clone(a._ellipseGeometry._center),a._ellipseGeometry._ellipsoid=n.clone(a._ellipseGeometry._ellipsoid),t.createGeometry(a)}return a})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(n,i){if(!e(i))throw new t(r(n))},i.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},i.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},i.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},i.typeOf.number.lessThan=function(e,r,n){if(i.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},i.typeOf.number.lessThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},i.typeOf.number.greaterThan=function(e,r,n){if(i.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},i.typeOf.number.greaterThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},i.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},i.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},i.typeOf.number.equals=function(e,r,n,a){if(i.typeOf.number(e,n),i.typeOf.number(r,a),n!==a)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*i.clamp(e,-1,1)+.5)*r)},i.fromSNorm=function(e,r){return r=t(r,255),i.clamp(e,0,r)/r*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,r){return(1-r)*e+r*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,r,n,i){i=t(i,n);var a=Math.abs(e-r);return a<=i||a<=n*Math.max(Math.abs(e),Math.abs(r))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var r=a[t-1],n=t;n<=e;n++)a.push(r*n);return a[e]},i.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return n.x=s*Math.cos(i),n.y=s*Math.sin(i),n.z=u*Math.cos(a),n},o.fromElements=function(e,t,n,i){return r(i)?(i.x=e,i.y=t,i.z=n,i):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var i=0;i<n;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var i=0;i<n;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)},o.cross=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-n*s,f=n*u-i*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,r,n,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,i,a,u){i=t(i,0);var s=r(a)?a.radiiSquared:p,c=Math.cos(n);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(n),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),r(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function i(r,i,u,s,c){var l=r.x,f=r.y,h=r.z,d=i.x,p=i.y,m=i.z,E=l*l*d*d,y=f*f*p*p,_=h*h*m*m,T=E+y+_,v=Math.sqrt(1/T),R=e.multiplyByScalar(r,v,a);if(T<s)return isFinite(v)?e.clone(R,c):void 0;var A=u.x,S=u.y,g=u.z,N=o;N.x=R.x*A*2,N.y=R.y*S*2,N.z=R.z*g*2;var I,O,w,M,x,C,P,D,U,b,L,F=(1-v)*e.magnitude(r)/(.5*e.magnitude(N)),B=0;do{F-=B,w=1/(1+F*A),M=1/(1+F*S),x=1/(1+F*g),C=w*w,P=M*M,D=x*x,U=C*w,b=P*M,L=D*x,I=E*C+y*P+_*D-1,O=E*U*A+y*b*S+_*L*g;B=I/(-2*O)}while(Math.abs(I)>n.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=h*x,c):new e(l*w,f*M,h*x)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,i,a){return i=r(i,0),n(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,r,n){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,r,i){var p=n(r)?r.oneOverRadii:f,m=n(r)?r.oneOverRadiiSquared:h,E=n(r)?r._centerToleranceSquared:d,y=o(t,p,m,E,c);if(n(y)){var _=e.multiplyComponents(y,m,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),v=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=a.sign(e.dot(T,t))*e.magnitude(T);return n(i)?(i.longitude=v,i.latitude=R,i.height=A,i):new u(v,R,A)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t,r,i,a){r=n(r,0),i=n(i,0),a=n(a,0),t._radii=new e(r,i,a),t._radiiSquared=new e(r*r,i*i,a*a),t._radiiToTheFourth=new e(r*r*r*r,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===r?0:1/r,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(r,i,a),t._maximumRadius=Math.max(r,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(i(t)){var n=t._radii;return i(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,i){return i=n(i,0),e.pack(t._radii,r,i),r},f.unpack=function(t,r,i){r=n(r,0);var a=e.unpack(t,r);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(a);return i(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return i(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,r){var n=h,a=d;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,a);var o=Math.sqrt(e.dot(n,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(n,t.height,n),i(r)||(r=new e),e.add(a,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var p=new e,m=new e,E=new e;return f.prototype.cartesianToCartographic=function(r,n){var a=this.scaleToGeodeticSurface(r,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(r,a,E),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return i(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){i(r)||(r=new e);var n=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,a){r=n(r,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-r))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,i,a,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return n(r)?(r.x=a,r.y=o,r.z=u,r):new e(a,o,u)},u.prototype.unproject=function(e,r){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return n(r)?(r.longitude=a,r.latitude=o,r.height=u,r):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i,a,o,u,s,c){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(a,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(m[r],p[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],p[a])]);o>n&&(i=a,n=o)}var c=1,l=0,f=p[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>r){var d,E=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],T=(E-y)/2/_;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=r-u-f+d,m=2*(i-h),E=2*(a+l),y=2*(i+h),_=-r+u-f+d,T=2*(c-o),v=2*(a-l),R=2*(c+o),A=-r-u+f+d;return n(t)?(t[0]=p,t[1]=y,t[2]=v,t[3]=m,t[4]=_,t[5]=R,t[6]=E,t[7]=T,t[8]=A,t):new s(p,m,E,y,_,T,v,R,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=r*u,p=a*i+c*o*u,m=-c*i+a*o*u,E=-o,y=c*r,_=a*r;return n(t)?(t[0]=l,t[1]=d,t[2]=E,t[3]=f,t[4]=p,t[5]=y,t[6]=h,t[7]=m,t[8]=_,t):new s(l,f,h,d,p,m,E,y,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=i,t[6]=0,t[7]=-i,t[8]=r,t):new s(1,0,0,0,r,-i,0,i,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=r,t):new s(r,0,i,0,1,0,-i,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=i,t[2]=0,t[3]=-i,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-i,0,i,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,i=e[n],a=e[n+1],o=e[n+2];return r.x=i,r.y=a,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var i=3*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],i=e[t+3],a=e[t+6];return r.x=n,r.y=i,r.z=a,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var h=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=i,r[2]=a,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[3]*i+e[6]*a,u=e[1]*n+e[4]*i+e[7]*a,s=e[2]*n+e[5]*i+e[8]*a;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],m=[2,2,1],E=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,i=0,a=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=r*c(h);a<10&&l(h)>d;)f(h,E),s.transpose(E,y),s.multiply(h,E,h),s.multiply(y,h,h),s.multiply(o,E,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*n-r*c)+u*(r*o-a*n)},s.inverse=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-n*f,t[2]=n*u-o*i,t[3]=c*u-a*f,t[4]=r*f-c*i,t[5]=a*i-r*u,t[6]=a*l-c*o,t[7]=c*n-r*l,t[8]=r*o-a*n;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n,i){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(i,0)}o.fromElements=function(e,t,n,i,a){return r(a)?(a.x=e,a.y=t,a.z=n,a.w=i,a):new o(e,t,n,i)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n++],i.w=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var i=0;i<n;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var i=0;i<n;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)&&a.equalsEpsilon(e.w,t.w,n,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t,r,i,a,o,u,s,c,l,f,h,d,p,m,E){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(c,0),this[3]=n(d,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(p,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(m,0),this[12]=n(i,0),this[13]=n(s,0),this[14]=n(h,0),this[15]=n(E,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,a){return r=n(r,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=r.x,a[13]=r.y,a[14]=r.z,a[15]=1,a):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){i(n)||(n=new l);var a=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,m=t.y*t.w,E=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-d-E+_,v=2*(c-y),R=2*(f+m),A=2*(c+y),S=-s+d-E+_,g=2*(p-h),N=2*(f-m),I=2*(p+h),O=-s-d+E+_;return n[0]=T*a,n[1]=A*a,n[2]=N*a,n[3]=0,n[4]=v*o,n[5]=S*o,n[6]=I*o,n[7]=0,n[8]=R*u,n[9]=g*u,n[10]=O*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,r){var n=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,m=f.y,E=f.z,y=d.x,_=d.y,T=d.z,v=n.x,R=n.y,A=n.z,S=u*-v+s*-R+c*-A,g=y*-v+_*-R+T*-A,N=p*v+m*R+E*A;return i(r)?(r[0]=u,r[1]=y,r[2]=-p,r[3]=0,r[4]=s,r[5]=_,r[6]=-m,r[7]=0,r[8]=c,r[9]=T,r[10]=-E,r[11]=0,r[12]=S,r[13]=g,r[14]=N,r[15]=1,r):new l(u,s,c,S,y,_,T,g,-p,-m,-E,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,r,n,i,a,o){var u=1/(t-e),s=1/(n-r),c=1/(a-i),l=-(t+e)*u,f=-(n+r)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,i,a,o){var u=2*i/(t-e),s=2*i/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,i,a){var o=2*i/(t-e),u=2*i/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,r,i){e=n(e,n.EMPTY_OBJECT);var a=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),h=c,d=l,p=f,m=a+c,E=o+l,y=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=m,i[13]=E,i[14]=y,i[15]=1,i},l.computeView=function(t,r,n,i,a){return a[0]=i.x,a[1]=n.x,a[2]=-r.x,a[3]=0,a[4]=i.y,a[5]=n.y,a[6]=-r.y,a[7]=0,a[8]=i.z,a[9]=n.z,a[10]=-r.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(n,t),a[14]=e.dot(r,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3];return r.x=i,r.y=a,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var i=4*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n[i+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return r.x=n,r.y=i,r.z=a,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var p=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),r};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],m=e[12],E=e[13],y=e[14],_=e[15],T=t[0],v=t[1],R=t[2],A=t[3],S=t[4],g=t[5],N=t[6],I=t[7],O=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],D=t[14],U=t[15],b=n*T+u*v+f*R+m*A,L=i*T+s*v+h*R+E*A,F=a*T+c*v+d*R+y*A,B=o*T+l*v+p*R+_*A,z=n*S+u*g+f*N+m*I,q=i*S+s*g+h*N+E*I,G=a*S+c*g+d*N+y*I,V=o*S+l*g+p*N+_*I,X=n*O+u*w+f*M+m*x,W=i*O+s*w+h*M+E*x,H=a*O+c*w+d*M+y*x,k=o*O+l*w+p*M+_*x,Y=n*C+u*P+f*D+m*U,j=i*C+s*P+h*D+E*U,Z=a*C+c*P+d*D+y*U,K=o*C+l*P+p*D+_*U;return r[0]=b,r[1]=L,r[2]=F,r[3]=B,r[4]=z,r[5]=q,r[6]=G,r[7]=V,r[8]=X,r[9]=W,r[10]=H,r[11]=k,r[12]=Y,r[13]=j,r[14]=Z,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],m=t[0],E=t[1],y=t[2],_=t[4],T=t[5],v=t[6],R=t[8],A=t[9],S=t[10],g=t[12],N=t[13],I=t[14],O=n*m+o*E+c*y,w=i*m+u*E+l*y,M=a*m+s*E+f*y,x=n*_+o*T+c*v,C=i*_+u*T+l*v,P=a*_+s*T+f*v,D=n*R+o*A+c*S,U=i*R+u*A+l*S,b=a*R+s*A+f*S,L=n*g+o*N+c*I+h,F=i*g+u*N+l*I+d,B=a*g+s*N+f*I+p;return r[0]=O,r[1]=w,r[2]=M,r[3]=0,r[4]=x,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=U,r[10]=b,r[11]=0,r[12]=L,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],m=t[3],E=t[4],y=t[5],_=t[6],T=t[7],v=t[8],R=n*h+o*d+c*p,A=i*h+u*d+l*p,S=a*h+s*d+f*p,g=n*m+o*E+c*y,N=i*m+u*E+l*y,I=a*m+s*E+f*y,O=n*_+o*T+c*v,w=i*_+u*T+l*v,M=a*_+s*T+f*v;return r[0]=R,r[1]=A,r[2]=S,r[3]=0,r[4]=g,r[5]=N,r[6]=I,r[7]=0,r[8]=O,r[9]=w,r[10]=M,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=n*e[0]+i*e[4]+a*e[8]+e[12],u=n*e[1]+i*e[5]+a*e[9]+e[13],s=n*e[2]+i*e[6]+a*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var E=new e;l.multiplyByUniformScale=function(e,t,r){return E.x=t,E.y=t,E.z=t,l.multiplyByScale(e,E,r)},l.multiplyByScale=function(e,t,r){var n=t.x,i=t.y,a=t.z;return 1===n&&1===i&&1===a?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=i*e[4],r[5]=i*e[5],r[6]=i*e[6],r[7]=0,r[8]=a*e[8],r[9]=a*e[9],r[10]=a*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*n+e[4]*i+e[8]*a+e[12]*o,s=e[1]*n+e[5]*i+e[9]*a+e[13]*o,c=e[2]*n+e[6]*i+e[10]*a+e[14]*o,l=e[3]*n+e[7]*i+e[11]*a+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a,u=e[1]*n+e[5]*i+e[9]*a,s=e[2]*n+e[6]*i+e[10]*a;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a+e[12],u=e[1]*n+e[5]*i+e[9]*a+e[13],s=e[2]*n+e[6]*i+e[10]*a+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,v=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),v))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],m=e[2],E=e[6],R=e[10],A=e[14],S=e[3],g=e[7],N=e[11],I=e[15],O=R*I,w=A*N,M=E*I,x=A*g,C=E*N,P=R*g,D=m*I,U=A*S,b=m*N,L=R*S,F=m*g,B=E*S,z=O*h+x*d+C*p-(w*h+M*d+P*p),q=w*f+D*d+L*p-(O*f+U*d+b*p),G=M*f+U*h+F*p-(x*f+D*h+B*p),V=P*f+b*h+B*d-(C*f+L*h+F*d),X=w*i+M*a+P*o-(O*i+x*a+C*o),W=O*n+U*a+b*o-(w*n+D*a+L*o),H=x*n+D*i+B*o-(M*n+U*i+F*o),k=C*n+L*i+F*a-(P*n+b*i+B*a);O=a*p,w=o*d,M=i*p,x=o*h,C=i*d,P=a*h,D=n*p,U=o*f,b=n*d,L=a*f,F=n*h,B=i*f;var Y=O*g+x*N+C*I-(w*g+M*N+P*I),j=w*S+D*N+L*I-(O*S+U*N+b*I),Z=M*S+U*g+F*I-(x*S+D*g+B*I),K=P*S+b*g+B*N-(C*S+L*g+F*N),J=M*R+P*A+w*E-(C*A+O*E+x*R),Q=b*A+O*m+U*R-(D*R+L*A+w*m),$=D*E+B*A+x*m-(F*A+M*m+U*E),ee=F*R+C*m+L*E-(b*E+B*R+P*m),te=n*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=q*te,r[2]=G*te,r[3]=V*te,r[4]=X*te,r[5]=W*te,r[6]=H*te,r[7]=k*te,r[8]=Y*te,r[9]=j*te,r[10]=Z*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-r*f-n*h-i*d,m=-a*f-o*h-u*d,E=-s*f-c*h-l*d;return t[0]=r,t[1]=a,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=m,t[14]=E,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),i=u.toRadians(r(i,0)),a=u.toRadians(r(a,0)),n(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(i,0),o.north=r(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];r=Math.min(r,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-r>o-a&&(r=a,i=o,i>u.PI&&(i-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=i,t.north=l,t):new s(r,c,i,l)},s.fromCartesianArray=function(e,t,i){t=r(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,m=e.length;p<m;p++){var E=t.cartesianToCartographic(e[p]);o=Math.min(o,E.longitude),c=Math.max(c,E.longitude),h=Math.min(h,E.latitude),d=Math.max(d,E.latitude);var y=E.longitude>=0?E.longitude:E.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return n(r)?(r.west=l,r.south=h,r.east=f,r.north=d,r):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,r){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return n(r)?(r.west=i,r.south=a,r.east=o,r.north=u,r):new s(i,a,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>i||u.equalsEpsilon(r,i,u.EPSILON14))&&(r<a||u.equalsEpsilon(r,a,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=r(t,a.WGS84),i=r(i,0),n(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,m=c;m.height=i,m.longitude=p,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var E=1;E<8;++E)m.longitude=-Math.PI+E*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";function d(t,r){this.center=e.clone(i(t,e.ZERO)),this.radius=i(r,0)}var p=new e,m=new e,E=new e,y=new e,_=new e,T=new e,v=new e,R=new e,A=new e,S=new e,g=new e,N=new e,I=4/3*r.PI;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],v),o=e.clone(i,p),u=e.clone(i,m),s=e.clone(i,E),c=e.clone(i,y),l=e.clone(i,_),f=e.clone(i,T),h=t.length;for(n=1;n<h;n++){e.clone(t[n],i);var I=i.x,O=i.y,w=i.z;I<o.x&&e.clone(i,o),I>c.x&&e.clone(i,c),O<u.y&&e.clone(i,u),O>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,U=M;x>U&&(U=x,P=u,D=l),C>U&&(U=C,P=s,D=f);var b=A;b.x=.5*(P.x+D.x),b.y=.5*(P.y+D.y),b.z=.5*(P.z+D.z);var L=e.magnitudeSquared(e.subtract(D,b,R)),F=Math.sqrt(L),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,R),.5,N),G=0;for(n=0;n<h;n++){e.clone(t[n],i);var V=e.magnitude(e.subtract(i,q,R));V>G&&(G=V);var X=e.magnitudeSquared(e.subtract(i,b,R));if(X>L){var W=Math.sqrt(X);F=.5*(F+W),L=F*F;var H=W-F;b.x=(F*b.x+H*i.x)/W,b.y=(F*b.y+H*i.y)/W,b.z=(F*b.z+H*i.z)/W}}return F<G?(e.clone(b,r.center),r.radius=F):(e.clone(q,r.center),r.radius=G),r};var O=new u,w=new e,M=new e,x=new t,C=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,n,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=i(r,O),h.southwest(t,x),x.height=n,h.northeast(t,C),C.height=o;var s=r.project(x,w),c=r.project(C,M),l=c.x-s.x,f=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+p*p);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*p,u};var P=[];d.fromRectangle3D=function(t,r,n,u){if(r=i(r,o.WGS84),n=i(n,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,r,n,P);return d.fromPoints(s,u)},d.fromVertices=function(t,r,n,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=i(r,e.ZERO),n=i(n,3);var u=v;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,p),l=e.clone(u,m),f=e.clone(u,E),h=e.clone(u,y),I=e.clone(u,_),O=e.clone(u,T),w=t.length;for(s=0;s<w;s+=n){var M=t[s]+r.x,x=t[s+1]+r.y,C=t[s+2]+r.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>h.x&&e.clone(u,h),x<l.y&&e.clone(u,l),x>I.y&&e.clone(u,I),C<f.z&&e.clone(u,f),C>O.z&&e.clone(u,O)}var P=e.magnitudeSquared(e.subtract(h,c,R)),D=e.magnitudeSquared(e.subtract(I,l,R)),U=e.magnitudeSquared(e.subtract(O,f,R)),b=c,L=h,F=P;D>F&&(F=D,b=l,L=I),U>F&&(F=U,b=f,L=O);var B=A;B.x=.5*(b.x+L.x),B.y=.5*(b.y+L.y),B.z=.5*(b.z+L.z);var z=e.magnitudeSquared(e.subtract(L,B,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=I.y,V.z=O.z;var X=e.multiplyByScalar(e.add(G,V,R),.5,N),W=0;for(s=0;s<w;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,X,R));H>W&&(W=H);var k=e.magnitudeSquared(e.subtract(u,B,R));if(k>z){var Y=Math.sqrt(k);q=.5*(q+Y),z=q*q;var j=Y-q;B.x=(q*B.x+j*u.x)/Y,B.y=(q*B.y+j*u.y)/Y,B.z=(q*B.z+j*u.z)/Y}}return q<W?(e.clone(B,o.center),o.radius=q):(e.clone(X,o.center),o.radius=W),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=v;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,p),s=e.clone(i,m),c=e.clone(i,E),l=e.clone(i,y),f=e.clone(i,_),h=e.clone(i,T),I=t.length;for(o=0;o<I;o+=3){var O=t[o]+r[o],w=t[o+1]+r[o+1],M=t[o+2]+r[o+2];i.x=O,i.y=w,i.z=M,O<u.x&&e.clone(i,u),O>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>h.z&&e.clone(i,h)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(h,c,R)),D=u,U=l,b=x;C>b&&(b=C,D=s,U=f),P>b&&(b=P,D=c,U=h);var L=A;L.x=.5*(D.x+U.x),L.y=.5*(D.y+U.y),L.z=.5*(D.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,N),V=0;for(o=0;o<I;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(i,G,R));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(i,L,R));if(W>F){var H=Math.sqrt(W);B=.5*(B+H),F=B*B;var k=H-B;L.x=(B*L.x+k*i.x)/H,L.y=(B*L.y+k*i.y)/H,L.z=(B*L.z+k*i.z)/H}}return B<V?(e.clone(L,n.center),n.radius=B):(e.clone(G,n.center),n.radius=V),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var D=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,D)+c.radius)}return r.radius=s,r};var U=new e,b=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=l.getColumn(n,0,U),o=l.getColumn(n,1,b),u=l.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=i(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=i(t,0),a(r)||(r=new d);var n=r.center;return n.x=e[t++],n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var F=new e,B=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,F),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var z=new e;d.expand=function(t,r,n){n=d.clone(t,n);var i=e.magnitude(e.subtract(r,n.center,z));return i>n.radius&&(n.radius=i),n},d.intersectPlane=function(t,r){var n=t.center,i=t.radius,a=r.normal,o=e.dot(a,n)+r.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=f.getMaximumScale(t)*e.radius,r};var q=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,q);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var G=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new c);var o=e.subtract(t.center,r,G),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,X=new e,W=new e,H=new e,k=new e,Y=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,r,n){r=i(r,K);var a=r.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,k),h=e.negate(c,H),p=j,m=p[0];e.add(s,l,m),e.add(m,c,m),m=p[1],e.add(s,l,m),e.add(m,h,m),m=p[2],e.add(s,f,m),e.add(m,h,m),m=p[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=p[4],e.add(s,l,m),e.add(m,c,m),m=p[5],e.add(s,l,m),e.add(m,h,m),m=p[6],e.add(s,f,m),e.add(m,h,m),m=p[7],e.add(s,f,m),e.add(m,c,m);for(var E=p.length,y=0;y<E;++y){var _=p[y];e.add(o,_,_);var T=a.cartesianToCartographic(_,Y);r.project(T,_)}n=d.fromPoints(p,n),o=n.center;var v=o.x,R=o.y,A=o.z;return o.x=A,o.y=v,o.z=R,n},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return I*e*e*e},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var i=0;i<n;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var i=0;i<n;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)), +o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(n.requestFullscreen=i,r=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(n.requestFullscreen=i,r=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?n.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(n.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?n.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(n.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?n.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(n.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),n.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),n.fullscreenerror=i)}return r},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[n.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(R=!0,A=n(e[1]))}return R}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(v.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(S=!0,g=n(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(v.userAgent);null!==e&&(N=!0,I=n(e[1]),I.isNightly=!!e[2])}return N}function c(){return s()&&I}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===v.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(v.userAgent))&&(O=!0,w=n(e[1])):"Netscape"===v.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(v.userAgent))&&(O=!0,w=n(e[1]))}return O}function f(){return l()&&w}function h(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(M=!0,x=n(e[1]))}return M}function d(){return h()&&x}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(v.appVersion)),D}function E(){return p()&&P}function y(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(v.pointerEnabled)||v.pointerEnabled)),U}function _(){if(!t(L)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;L=t(r)&&""!==r,L&&(b=r)}return L}function T(){return _()?b:void 0}var v;v="undefined"!=typeof navigator?navigator:{};var R,A,S,g,N,I,O,w,M,x,C,P,D,U,b,L,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:E,isWindows:m,hardwareConcurrency:e(v.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,i,a){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,i){switch(n=e(n,0),i=e(i,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,i);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,i);case o.SHORT:return new Int16Array(r,n,i);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,i);case o.INT:return new Int32Array(r,n,i);case o.UNSIGNED_INT:return new Uint32Array(r,n,i);case o.FLOAT:return new Float32Array(r,n,i);case o.DOUBLE:return new Float64Array(r,n,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(i,0)}var c=new e;s.fromAxisAngle=function(t,r,i){var a=r/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return n(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],m=h+d+p;if(m>0)r=Math.sqrt(m+1),c=.5*r,r=.5/r,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var E=l,y=0;d>h&&(y=1),p>h&&p>d&&(y=2);var _=E[y],T=E[_];r=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var v=f;v[y]=.5*r,r=.5/r,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*r,v[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*r,v[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*r,i=-v[0],a=-v[1],o=-v[2]}return n(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,m=new s;s.fromHeadingPitchRoll=function(t,r){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(p,m,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,r,r)};var E=new e,y=new e,_=new s,T=new s,v=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,v),s.conjugate(v,v);for(var i=0,a=r-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,v,_),_.w<0&&s.negate(_,_),s.computeAxis(_,E);var u=s.computeAngle(_);n[o]=E.x*u,n[o+1]=E.y*u,n[o+2]=E.z*u}},s.unpackInterpolationResult=function(t,r,i,a,o){n(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(r,4*a,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,i=e.y*r,a=e.z*r,o=e.w*r;return t.x=n,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+i*c-a*s,h=o*s-n*c+i*l+a*u,d=o*c+n*s-i*u+a*l,p=o*l-n*u-i*s-a*c;return r.x=f,r.y=h,r.z=d,r.w=p,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,r,n){return R=s.multiplyByScalar(t,r,R),n=s.multiplyByScalar(e,1-r,n),s.add(R,n,n)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,r,n){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,r,n);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-r)*u),S),g=s.multiplyByScalar(a,Math.sin(r*u),g),n=s.add(S,g,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),i=0;return 0!==n&&(i=n/Math.sin(n)),e.multiplyByScalar(t,i,r)},s.exp=function(t,r){var n=e.magnitude(t),i=0;return 0!==n&&(i=Math.sin(n)/n),r.x=t.x*i,r.y=t.y*i,r.z=t.z*i,r.w=Math.cos(n),r};var N=new e,I=new e,O=new s,w=new s;s.computeInnerQuadrangle=function(t,r,n,i){var a=s.conjugate(r,O);s.multiply(a,n,w);var o=s.log(w,N);s.multiply(a,t,w);var u=s.log(w,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,O),s.multiply(r,O,i)},s.squad=function(e,t,r,n,i,a){var o=s.slerp(e,t,i,O),u=s.slerp(r,n,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var M=new s,x=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],b=0;b<7;++b){var L=b+1,F=2*L+1;C[b]=1/(L*F),P[b]=L/F}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,r,n){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,U[f]=(C[f]*l-P[f])*o;var h=i*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),p=s.multiplyByScalar(e,d,M);return s.multiplyByScalar(t,h,n),s.add(p,n,n)},s.fastSquad=function(e,t,r,n,i,a){var o=s.fastSlerp(e,t,i,O),u=s.fastSlerp(r,n,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,r,n){"use strict";function i(t,i,a,l,f,h,d,p,m,E){var y=t+i;e.multiplyByScalar(l,Math.cos(y),o),e.multiplyByScalar(a,Math.sin(y),u),e.add(o,u,o);var _=Math.cos(t);_*=_;var T=Math.sin(t);T*=T;var v=h/Math.sqrt(d*_+f*T),R=v/p;return n.fromAxisAngle(o,R,s),r.fromQuaternion(s,c),r.multiplyByVector(c,m,E),e.normalize(E,E),e.multiplyByScalar(E,p,E),E}var a={},o=new e,u=new e,s=new n,c=new r,l=new e,f=new e,h=new e,d=new e;a.raisePositionsToHeight=function(t,r,n){for(var i=r.ellipsoid,a=r.height,o=r.extrudedHeight,u=n?t.length/3*2:t.length/3,s=new Float64Array(3*u),c=t.length,p=n?c:0,m=0;m<c;m+=3){var E=m+1,y=m+2,_=e.fromArray(t,m,l);i.scaleToGeodeticSurface(_,_);var T=e.clone(_,f),v=i.geodeticSurfaceNormal(_,d),R=e.multiplyByScalar(v,a,h);e.add(_,R,_),n&&(e.multiplyByScalar(v,o,R),e.add(T,R,T),s[m+p]=T.x,s[E+p]=T.y,s[y+p]=T.z),s[m]=_.x,s[E]=_.y,s[y]=_.z}return s};var p=new e,m=new e,E=new e;return a.computeEllipsePositions=function(r,n,a){var o=r.semiMinorAxis,u=r.semiMajorAxis,s=r.rotation,c=r.center,d=8*r.granularity,y=o*o,_=u*u,T=u*o,v=e.magnitude(c),R=e.normalize(c,p),A=e.cross(e.UNIT_Z,c,m);A=e.normalize(A,A);var S=e.cross(R,A,E),g=1+Math.ceil(t.PI_OVER_TWO/d),N=t.PI_OVER_TWO/(g-1),I=t.PI_OVER_TWO-g*N;I<0&&(g-=Math.ceil(Math.abs(I)/N));var O,w,M,x,C,P=g*(g+2)*2,D=n?new Array(3*P):void 0,U=0,b=l,L=f,F=4*g*3,B=F-1,z=0,q=a?new Array(F):void 0;for(I=t.PI_OVER_TWO,b=i(I,s,S,A,y,T,_,v,R,b),n&&(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z),a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x),I=t.PI_OVER_TWO-N,O=1;O<g+1;++O){if(b=i(I,s,S,A,y,T,_,v,R,b),L=i(Math.PI-I,s,S,A,y,T,_,v,R,L),n){for(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z,M=2*O+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(b,L,x,h),D[U++]=C.x,D[U++]=C.y,D[U++]=C.z;D[U++]=L.x,D[U++]=L.y,D[U++]=L.z}a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x,q[z++]=L.x,q[z++]=L.y,q[z++]=L.z),I=t.PI_OVER_TWO-(O+1)*N}for(O=g;O>1;--O){if(I=t.PI_OVER_TWO-(O-1)*N,b=i(-I,s,S,A,y,T,_,v,R,b),L=i(I+Math.PI,s,S,A,y,T,_,v,R,L),n){for(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z,M=2*(O-1)+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(b,L,x,h),D[U++]=C.x,D[U++]=C.y,D[U++]=C.z;D[U++]=L.x,D[U++]=L.y,D[U++]=L.z}a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x,q[z++]=L.x,q[z++]=L.y,q[z++]=L.z)}I=t.PI_OVER_TWO,b=i(-I,s,S,A,y,T,_,v,R,b);var G={};return n&&(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z,G.positions=D,G.numPts=g),a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x,G.outerPositions=q),G},a}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var i=e.attributes[n],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return i}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)}, +u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),i=256*(r-n);return u.octDecode(n,i,t)},u.octPack=function(e,t,r,n){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+i,n.y=65536*o.y+a,n},u.octUnpack=function(e,t,r,n){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(a,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function i(r,i,s,c,l){n(l)||(l=new t);var f,h,d,p,m,E,y,_;n(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(r,i,u),p=t.dot(f,f),m=t.dot(f,h),E=t.dot(f,d),y=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(r,i,u),p=e.dot(f,f),m=e.dot(f,h),E=e.dot(f,d),y=e.dot(h,h),_=e.dot(h,d));var T=1/(p*y-m*m);return l.y=(y*E-m*_)*T,l.z=(p*_-m*E)*T,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var i={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var a=t.high,o=t.low;return n.encode(e.x,i),a.x=i.high,o.x=i.low,n.encode(e.y,i),a.y=i.high,o.y=i.low,n.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,a);var i=a.high,o=a.low;t[r]=i.x,t[r+1]=i.y,t[r+2]=i.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,r,i){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,i):new Uint16Array(t,r,i)},r(a)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var i=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(r)))<n?0:i}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,i){var a;if(0===e)return 0===n?[]:[-i/n];if(0===n){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-n/e,a<0?[a,0]:[0,a];var c=n*n,l=4*e*i,f=r(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[h/e,i/h]:[i/h,h/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var i,a,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,m=o*c-u*s,E=u*c-d,y=4*p*E-m*m;if(y<0){var _,T,v;h*f>=l*d?(_=o,T=p,v=-2*u*p+o*m):(_=c,T=E,v=-c*m+2*s*E);var R=v<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-y);a=-v+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),N=a===A?-g:-T/g;return i=T<=0?g+N:-v/(g*g+N*N+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var I=p,O=-2*u*p+o*m,w=E,M=-c*m+2*s*E,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-O)/3);i=2*Math.sqrt(-I);var D=Math.cos(P);a=i*D;var U=i*(-D/2-C*Math.sin(P)),b=a+U>2*u?a-u:U-u,L=o,F=b/L;P=Math.abs(Math.atan2(c*x,-M)/3),i=2*Math.sqrt(-w),D=Math.cos(P),a=i*D,U=i*(-D/2-C*Math.sin(P));var B=-c,z=a+U<2*s?a+s:U+s,q=B/z,G=L*z,V=-b*z-L*B,X=b*B,W=(s*V-u*X)/(-u*V+s*G);return F<=W?F<=q?W<=q?[F,W,q]:[F,q,W]:[q,F,W]:F<=q?[W,F,q]:W<=q?[W,q,F]:[q,W,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var i=e*e,a=t*t,o=r*r;return 18*e*t*r*n+a*o-27*i*(n*n)-4*(e*o*r+a*t*n)},n.computeRealRoots=function(e,n,i,a){var o,u;if(0===e)return t.computeRealRoots(n,i,a);if(0===n){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,i,a)}return 0===i?0===a?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,a):0===a?(o=t.computeRealRoots(e,n,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,i,a)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<r.EPSILON14){var p=n.computeRealRoots(1,s,l);if(2===p.length){var m,E=p[0],y=p[1];if(E>=0&&y>=0){var _=Math.sqrt(E),T=Math.sqrt(y);return[h-T,h-_,h+_,h+T]}if(E>=0&&y<0)return m=Math.sqrt(E),[h-m,h+m];if(E<0&&y>=0)return m=Math.sqrt(y),[h-m,h+m]}return[]}if(d>0){var v=Math.sqrt(d),R=(s+d-c/v)/2,A=(s+d+c/v)/2,S=n.computeRealRoots(1,v,R),g=n.computeRealRoots(1,-v,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,m,E=d[0],y=i-E,_=y*y,T=t/2,v=y/2,R=_-4*o,A=_+4*Math.abs(o),S=c-4*E,g=c+4*Math.abs(E);if(E<0||R*g<S*A){var N=Math.sqrt(S);p=N/2,m=0===N?0:(t*v-a)/N}else{var I=Math.sqrt(R);p=0===I?0:(t*v-a)/I,m=I/2}var O,w;0===T&&0===p?(O=0,w=0):r.sign(T)===r.sign(p)?(O=T+p,w=E/O):(w=T-p,O=E/w);var M,x;0===v&&0===m?(M=0,x=0):r.sign(v)===r.sign(m)?(M=v+m,x=o/M):(x=v-m,M=o/x);var C=n.computeRealRoots(1,O,M),P=n.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,h=f*n,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*r*h-27*a*f*f+256*o*(d*i)+i*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*a*r*f)+d*(144*e*u*r-27*u*u-128*a*c-192*a*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return i.getPoint=function(t,n,i){return r(i)||(i=new e),i=e.multiplyByScalar(t.direction,n,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,i,a,o,u,s,c,l){"use strict";function f(e,t,r,n){var i=t*t-4*e*r;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function h(t,r,i){n(i)||(i=new a);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,m=f(h,d,p,A);if(n(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function p(t,r,n,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),E=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*r.x+n,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(p,m,E),0===l.length)return T;var v=l[0],R=Math.sqrt(Math.max(1-v*v,0));if(T.push(new e(i,a*v,a*-R)),T.push(new e(i,a*v,a*R)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(i,a*A,a*-S)),T.push(new e(i,a*A,a*S))}return T}var g=_*_,N=y*y,I=p*p,O=_*y,w=I+N,M=2*(m*p+O),x=2*E*p+m*m-N+g,C=2*(E*m-O),P=E*E-g;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var D=l.length;if(0===D)return T;for(var U=0;U<D;++U){var b,L=l[U],F=L*L,B=Math.max(1-F,0),z=Math.sqrt(B);b=o.sign(p)===o.sign(E)?d(p*F+E,m*L,o.EPSILON12):o.sign(E)===o.sign(m*L)?d(p*F,m*L+E,o.EPSILON12):d(p*F+m*L,E,o.EPSILON12);var q=d(y*L,_,o.EPSILON15),G=b*q;G<0?T.push(new e(i,a*L,a*z)):G>0?T.push(new e(i,a*L,a*-z)):0!==z?(T.push(new e(i,a*L,a*-z)),T.push(new e(i,a*L,a*z)),++U):T.push(new e(i,a*L,a*z))}return T}var m={};m.rayPlane=function(t,r,i){n(i)||(i=new e);var a=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var E=new e,y=new e,_=new e,T=new e,v=new e;m.rayTriangleParametric=function(t,n,i,a,u){u=r(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,m=e.subtract(i,n,E),R=e.subtract(a,n,y),A=e.cross(p,R,_),S=e.dot(m,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,n,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,m,v),(f=e.dot(p,c))<0||l+f>S)return;h=e.dot(R,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,n,T),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,m,v),(f=e.dot(p,c)*g)<0||l+f>1)return;h=e.dot(R,c)*g}return h},m.rayTriangle=function(t,r,i,a,o,u){var s=m.rayTriangleParametric(t,r,i,a,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;m.lineSegmentTriangle=function(t,r,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=h(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;m.lineSegmentSphere=function(t,r,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!n(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;m.rayEllipsoid=function(t,r){var n,i,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(n=h-1,i=e.magnitudeSquared(f),o=i*n,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,E=n/s;return m<E?new a(m,E):{start:E,stop:m}}var y=Math.sqrt(n/i);return new a(y,y)}return h<1?(n=h-1,i=e.magnitudeSquared(f),o=i*n,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var I=new e,O=new e,w=new e,M=new e,x=new e,C=new u,P=new u,D=new u,U=new u,b=new u,L=new u,F=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,r){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=r.geodeticSurfaceNormal(i,I);if(e.dot(a,s)>=0)return i}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(a,I),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,M),d=e.normalize(e.cross(h,f,O),O),m=e.normalize(e.cross(f,d,w),w),E=C;E[0]=f.x,E[1]=f.y,E[2]=f.z,E[3]=d.x,E[4]=d.y,E[5]=d.z,E[6]=m.x,E[7]=m.y,E[8]=m.z;var y=u.transpose(E,P),_=u.fromScale(r.radii,D),T=u.fromScale(r.oneOverRadii,U),v=b;v[0]=0,v[1]=-a.z,v[2]=a.y,v[3]=a.z,v[4]=0,v[5]=-a.x,v[6]=-a.y,v[7]=a.x,v[8]=0;var R,A,S=u.multiply(u.multiply(y,T,L),v,L),g=u.multiply(u.multiply(S,_,F),E,F),N=u.multiplyByVector(S,i,x),G=p(g,e.negate(N,I),0,0,1),V=G.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){R=u.multiplyByVector(_,u.multiplyByVector(E,G[H],B),B);var k=e.normalize(e.subtract(R,i,M),M),Y=e.dot(k,a);Y>W&&(W=Y,X=e.clone(R,X))}var j=r.cartesianToCartographic(X,q);return W=o.clamp(W,0,1),A=e.magnitude(e.subtract(X,i,M))*Math.sqrt(1-W*W),A=c?-A:A,j.height=A,r.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,r,i,a){n(a)||(a=new e);var u=e.subtract(r,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,r,n,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,r)+o<0,c=e.dot(a,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,r,n,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,r,n,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,r,n,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,r,n,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,r,n,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,r,n,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,i,a,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,i){var a=-e.dot(n,t);return r(i)?(e.clone(n,i.normal),i.distance=a,i):new u(n,a)};var s=new e;u.fromCartesian4=function(t,n){var i=e.fromCartesian4(t,s),a=t.w;return r(n)?(e.clone(i,n.normal),n.distance=a,n):new u(i,a)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,i){r(i)||(i=new e);var a=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(n,o,i)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,i=r.maximumIndex,a=e(r.cacheSize,24),o=n.length;if(!t(i)){i=0;for(var u=0,s=n[u];u<o;)s>i&&(i=s),++u,s=n[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[n[h]]>a&&(c[n[h]]=f,++f);return(f-a+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<n;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}r=e(r,e.EMPTY_OBJECT);var i,a=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<h;)p[a[l]].vertexTriangles.push(m),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(m),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(m),++p[a[l+2]].numLiveTriangles,++m,l+=3;var E=0,y=u+1;i=1;var _,T,v=[],R=[],A=0,S=[],g=s/3,N=[];for(d=0;d<g;d++)N[d]=!1;for(var I,O;-1!==E;){v=[],T=p[E],O=T.vertexTriangles.length;for(var w=0;w<O;++w)if(m=T.vertexTriangles[w],!N[m]){N[m]=!0,l=m+m+m;for(var M=0;M<3;++M)I=a[l],v.push(I),R.push(I),S[A]=I,++A,_=p[I],--_.numLiveTriangles,y-_.timeStamp>u&&(_.timeStamp=y,++y),++l}E=function(e,t,r,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var h=r[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?n(i,o,e,u):c}(a,u,v,p,y,R,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T,v,R,A,S,g){"use strict";function N(e,t,r,n,i){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=i,e[t++]=i,e[t]=r}function I(e){for(var t=e.length,r=t/3*6,n=E.createTypedArray(t,r),i=0,a=0;a<t;a+=3,i+=6)N(n,i,e[a],e[a+1],e[a+2]);return n}function O(e){var t=e.length;if(t>=3){var r=6*(t-2),n=E.createTypedArray(t,r);N(n,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)N(n,i,e[a-1],e[a],e[a-2]);return n}return new Uint16Array}function w(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=E.createTypedArray(t,r),i=e[0],a=0,o=1;o<t;++o,a+=6)N(n,a,i,e[o],e[o+1]);return n}return new Uint16Array}function M(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new p({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function x(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var i=t[n],a=0;a<i.componentsPerAttribute;++a)e[n].values.push(i.values[r*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,r,a)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),v.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,r,a)}function D(e,t){var r,n=e.length,i={},a=e[0][t].attributes;for(r in a)if(a.hasOwnProperty(r)&&c(a[r])&&c(a[r].values)){for(var o=a[r],s=o.values.length,l=!0,f=1;f<n;++f){var h=e[f][t].attributes[r];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(i[r]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function U(e,t){var n,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,y=D(e,t);for(n in y)if(y.hasOwnProperty(n))for(s=y[n].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var T=0;for(a=0;a<h;++a)T+=e[a][t].indices.length;var v=d.computeNumberOfVertices(new d({attributes:y,primitiveType:S.POINTS})),R=E.createTypedArray(v,T),A=0,g=0;for(a=0;a<h;++a){var N=e[a][t].indices,I=N.length;for(u=0;u<I;++u)R[A++]=g+N[u];g+=d.computeNumberOfVertices(e[a][t])}_=R}var O,w=new i,M=0;for(a=0;a<h;++a){if(O=e[a][t].boundingSphere,!c(O)){w=void 0;break}i.add(O.center,w,w)}if(c(w))for(i.divideByScalar(w,h,w),a=0;a<h;++a){O=e[a][t].boundingSphere;var x=i.magnitude(i.subtract(O.center,w,se))+O.radius;x>M&&(M=x)}return new d({attributes:y,indices:_,primitiveType:m,boundingSphere:c(w)?new r(w,M):void 0})}function b(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function L(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,i=3;i<t;++i)r[n++]=i-1,r[n++]=0,r[n++]=i;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,i=3;i<t-1;i+=2)r[n++]=i,r[n++]=i-1,r[n++]=i+1,i+2<t&&(r[n++]=i,r[n++]=i+1,r[n++]=i+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return e.indices=r,e.primitiveType=S.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function G(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return L(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return q(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<T.EPSILON6&&(e.y=t?-T.EPSILON6:T.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return V(e,e.y<0),V(t,t.y<0),void V(r,r.y<0);var n,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(r.y);n=i>a?i>o?T.sign(e.y):T.sign(r.y):a>o?T.sign(t.y):T.sign(r.y);var u=n<0;V(e,u),V(t,u),V(r,u)}function W(e,t,r,n){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),r),i.clone(r,n),V(r,!0),V(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,i=t.y<0,a=r.y<0,o=0;o+=n?1:0,o+=i?1:0,o+=a?1:0;var u=Ie.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(W(e,t,Ae,ge),W(e,r,Se,Ne),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(W(t,r,Ae,ge),W(t,e,Se,Ne),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(W(r,e,Ae,ge),W(r,t,Se,Ne),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?i?a||(W(r,e,Ae,ge),W(r,t,Se,Ne),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(W(t,r,Ae,ge),W(t,e,Se,Ne),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(W(e,t,Ae,ge),W(e,r,Se,Ne),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Ie.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=ge,s[6]=Ne,s.length=7),Ie}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var i in n)if(n.hasOwnProperty(i)&&c(n[i])&&c(n[i].values)){var a=n[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=E.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var i=t[n];r[n]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:r,indices:[],primitiveType:e.primitiveType})}function j(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Z(e,r,a,o,u,s,l,f,h,d,p,m){if(c(s)||c(l)||c(f)||c(h)||c(d)){var E=i.fromArray(u,3*e,Oe),y=i.fromArray(u,3*r,we),_=i.fromArray(u,3*a,Me),T=t(o,E,y,_,xe);if(c(s)){var v=i.fromArray(s,3*e,Oe),R=i.fromArray(s,3*r,we),A=i.fromArray(s,3*a,Me);i.multiplyByScalar(v,T.x,v),i.multiplyByScalar(R,T.y,R),i.multiplyByScalar(A,T.z,A);var S=i.add(v,R,v);i.add(S,A,S),i.normalize(S,S),i.pack(S,p.normal.values,3*m)}if(c(d)){var g=i.fromArray(d,3*e,Oe),N=i.fromArray(d,3*r,we),I=i.fromArray(d,3*a,Me);i.multiplyByScalar(g,T.x,g),i.multiplyByScalar(N,T.y,N),i.multiplyByScalar(I,T.z,I);var O;i.equals(g,i.ZERO)&&i.equals(N,i.ZERO)&&i.equals(I,i.ZERO)?(O=Oe,O.x=0,O.y=0,O.z=0):(O=i.add(g,N,g),i.add(O,I,O),i.normalize(O,O)),i.pack(O,p.extrudeDirection.values,3*m)}if(c(l)){var w=i.fromArray(l,3*e,Oe),M=i.fromArray(l,3*r,we),x=i.fromArray(l,3*a,Me);i.multiplyByScalar(w,T.x,w),i.multiplyByScalar(M,T.y,M),i.multiplyByScalar(x,T.z,x);var C=i.add(w,M,w);i.add(C,x,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*m)}if(c(f)){var P=i.fromArray(f,3*e,Oe),D=i.fromArray(f,3*r,we),U=i.fromArray(f,3*a,Me);i.multiplyByScalar(P,T.x,P),i.multiplyByScalar(D,T.y,D),i.multiplyByScalar(U,T.z,U);var b=i.add(P,D,P);i.add(b,U,b),i.normalize(b,b),i.pack(b,p.bitangent.values,3*m)}if(c(h)){var L=n.fromArray(h,2*e,Ce),F=n.fromArray(h,2*r,Pe),B=n.fromArray(h,2*a,De);n.multiplyByScalar(L,T.x,L),n.multiplyByScalar(F,T.y,F),n.multiplyByScalar(B,T.z,B);var z=n.add(L,F,L);n.add(z,B,z),n.pack(z,p.st.values,2*m)}}}function K(e,t,r,n,i,a){var o=e.position.values.length/3;if(-1!==i){var u=n[i],s=r[u];return-1===s?(r[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,r,n,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,E=u.indices,y=Y(u),_=Y(u),T=[];T.length=l.length/3;var v=[];for(v.length=l.length/3,o=0;o<T.length;++o)T[o]=-1,v[o]=-1;var R=E.length;for(o=0;o<R;o+=3){var A=E[o],S=E[o+1],g=E[o+2],N=i.fromArray(l,3*A),I=i.fromArray(l,3*S),O=i.fromArray(l,3*g),w=H(N,I,O);if(c(w)&&w.positions.length>3)for(var M=w.positions,x=w.indices,C=x.length,P=0;P<C;++P){var D=x[P],U=M[D];U.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=v),a=K(t,r,n,E,D<3?o+D:-1,U),Z(A,S,g,U,l,f,d,h,p,m,t,a)}else c(w)&&(N=w.positions[0],I=w.positions[1],O=w.positions[2]),N.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=v),a=K(t,r,n,E,o,N),Z(A,S,g,N,l,f,d,h,p,m,t,a),a=K(t,r,n,E,o+1,I),Z(A,S,g,I,l,f,d,h,p,m,t,a),a=K(t,r,n,E,o+2,O),Z(A,S,g,O,l,f,d,h,p,m,t,a)}j(e,_,y)}function Q(e){var t,r=e.geometry,n=r.attributes,a=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],m=i.fromArray(a,3*d,Oe),E=i.fromArray(a,3*p,we);Math.abs(m.y)<T.EPSILON6&&(m.y<0?m.y=-T.EPSILON6:m.y=T.EPSILON6),Math.abs(E.y)<T.EPSILON6&&(E.y<0?E.y=-T.EPSILON6:E.y=T.EPSILON6);var y=u.attributes,v=u.indices,R=h,A=s.attributes,S=s.indices,g=f,N=_.lineSegmentPlane(m,E,Ue,Me);if(c(N)){var I=i.multiplyByScalar(i.UNIT_Y,5*T.EPSILON9,be);m.y<0&&(i.negate(I,I),y=s.attributes,v=s.indices,R=f,A=u.attributes,S=u.indices,g=h);var O=i.add(N,I,Le);K(y,v,R,o,t,m),K(y,v,R,o,-1,O),i.negate(I,I),i.add(N,I,O),K(A,S,g,o,-1,O),K(A,S,g,o,t+1,E)}else{var w,M,x;m.y<0?(w=s.attributes,M=s.indices,x=f):(w=u.attributes,M=u.indices,x=h),K(w,M,x,o,t,m),K(w,M,x,o,t+1,E)}}j(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,a=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=i.unpack(r,u,ze);if(!(s.x>0)){var c=i.unpack(n,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):i.pack(s,n,u));var l=i.unpack(a,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=r[u+3],a[u+1]=r[u+4],a[u+2]=r[u+5]):i.pack(s,a,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,E=Y(u),y=Y(u),v=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,S=t+2,g=i.fromArray(l,3*A,ze),N=i.fromArray(l,3*S,qe);if(Math.abs(g.y)<Ye)for(g.y=Ye*(N.y<0?-1:1),l[3*t+1]=g.y,l[3*(t+1)+1]=g.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(N.y)<Ye)for(N.y=Ye*(g.y<0?-1:1),l[3*(t+2)+1]=N.y,l[3*(t+3)+1]=N.y,r=3*A;r<3*A+12;r+=3)h[r]=l[3*(t+2)],h[r+1]=l[3*(t+2)+1],h[r+2]=l[3*(t+2)+2];var I=E.attributes,O=E.indices,w=y.attributes,M=y.indices,x=_.lineSegmentPlane(g,N,Ue,Ve);if(c(x)){v=!0;var C=i.multiplyByScalar(i.UNIT_Y,ke,Xe);g.y<0&&(i.negate(C,C),I=y.attributes,O=y.indices,w=E.attributes,M=E.indices);var P=i.add(x,C,We);I.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),I.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),I.prevPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(x,C,P),w.position.values.push(P.x,P.y,P.z),w.position.values.push(P.x,P.y,P.z),w.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.nextPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),w.nextPosition.values.push(h[3*S],h[3*S+1],h[3*S+2]),w.nextPosition.values.push(h[3*S+3],h[3*S+4],h[3*S+5]);var D=n.fromArray(d,2*A,Fe),U=Math.abs(D.y);I.expandAndWidth.values.push(-1,U,1,U),I.expandAndWidth.values.push(-1,-U,1,-U),w.expandAndWidth.values.push(-1,U,1,U),w.expandAndWidth.values.push(-1,-U,1,-U);var b=i.magnitudeSquared(i.subtract(x,g,Ge));if(b/=i.magnitudeSquared(i.subtract(N,g,Ge)),c(m)){var L=a.fromArray(m,4*A,He),F=a.fromArray(m,4*S,He),B=T.lerp(L.x,F.x,b),z=T.lerp(L.y,F.y,b),q=T.lerp(L.z,F.z,b),G=T.lerp(L.w,F.w,b);for(r=4*A;r<4*A+8;++r)I.color.values.push(m[r]);for(I.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),w.color.values.push(B,z,q,G),w.color.values.push(B,z,q,G),r=4*S;r<4*S+8;++r)w.color.values.push(m[r])}if(c(p)){var V=n.fromArray(p,2*A,Fe),X=n.fromArray(p,2*(t+3),Be),W=T.lerp(V.x,X.x,b);for(r=2*A;r<2*A+4;++r)I.st.values.push(p[r]);for(I.st.values.push(W,V.y),I.st.values.push(W,X.y),w.st.values.push(W,V.y),w.st.values.push(W,X.y),r=2*S;r<2*S+4;++r)w.st.values.push(p[r])}o=I.position.values.length/3-4,O.push(o,o+2,o+1),O.push(o+1,o+2,o+3),o=w.position.values.length/3-4,M.push(o,o+2,o+1),M.push(o+1,o+2,o+3)}else{var H,k;for(g.y<0?(H=y.attributes,k=y.indices):(H=E.attributes,k=E.indices),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(d[r]),c(p)&&H.st.values.push(p[r]);if(c(m))for(r=4*t;r<4*t+16;++r)H.color.values.push(m[r]);o=H.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}v&&($(y),$(E)),j(e,y,E)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=I(t);break;case S.TRIANGLE_STRIP:e.indices=O(t);break;case S.TRIANGLE_FAN:e.indices=w(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4) +;for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*n,l[f++]=i[h+1]+a[h+1]*n,l[f++]=i[h+2]+a[h+2]*n;var m,E=e.boundingSphere;return c(E)&&(m=new r(E.center,E.radius+n)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,i={},a=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(i[u]=a++)}for(var s in n)n.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),i=0;i<t;i++)n[i]=-1;for(var a,o=r,s=o.length,l=E.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=n[o[f]],-1!==a?l[h]=a:(a=o[f],n[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var m=e.attributes;for(var y in m)if(m.hasOwnProperty(y)&&c(m[y])&&c(m[y].values)){for(var _=m[y],T=_.values,v=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);v<t;){var S=n[v];if(-1!==S)for(var g=0;g<R;g++)A[R*S+g]=T[R*v+g];++v}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,i=0,a=0;a<n;a++)r[a]>i&&(i=r[a]);e.indices=g.tipsify({indices:r,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=d.computeNumberOfVertices(e);if(c(e.indices)&&r>=T.SIXTY_FOUR_KILOBYTES){var n,i=[],a=[],o=0,u=M(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var h=0;h<n;++h){var p=s[f+h],m=i[p];c(m)||(m=o++,i[p]=m,x(u,e.attributes,p)),a.push(m)}o+n>=T.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=M(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new i,ne=new o;te.projectTo2D=function(e,t,r,n,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,m=0;m<l.length;m+=3){var E=i.fromArray(l,m,re),y=s.cartesianToCartographic(E,ne),_=a.project(y,re);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[r]=o,e.attributes[n]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new v;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=r.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,i=0;i<n;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&r.push(a)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,a=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=r[t],m=r[t+1],E=r[t+2],y=3*d,_=3*m,v=3*E;le.x=a[y],le.y=a[y+1],le.z=a[y+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[v],he.y=a[v+1],he.z=a[v+2],c[d].count++,c[m].count++,c[E].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var S=A.indexOffset+A.currentCount;f[S]=h,A.currentCount++,A=c[r[t+1]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,A=c[r[t+2]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,h++}var g=new Float32Array(3*o);for(t=0;t<o;t++){var N=3*t;if(A=c[t],i.clone(i.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)i.add(ce,l[f[A.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,T.EPSILON10)&&i.clone(l[f[A.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,T.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),g[N]=ce.x,g[N+1]=ce.y,g[N+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:g}),e};var de=new i,pe=new i,me=new i;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var m=r[t],E=r[t+1],y=r[t+2];f=3*m,h=3*E,d=3*y;var _=2*m,T=2*E,v=2*y,R=n[f],A=n[f+1],S=n[f+2],g=o[_],N=o[_+1],I=o[T+1]-N,O=o[v+1]-N,w=1/((o[T]-g)*O-(o[v]-g)*I),M=(O*(n[h]-R)-I*(n[d]-R))*w,x=(O*(n[h+1]-A)-I*(n[d+1]-A))*w,C=(O*(n[h+2]-S)-I*(n[d+2]-S))*w;l[f]+=M,l[f+1]+=x,l[f+2]+=C,l[h]+=M,l[h+1]+=x,l[h+2]+=C,l[d]+=M,l[d+1]+=x,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var U=i.fromArray(a,f,de),b=i.fromArray(l,f,me),L=i.dot(U,b);i.multiplyByScalar(U,L,pe),i.normalize(i.subtract(b,pe,b),b),P[f]=b.x,P[h]=b.y,P[d]=b.z,i.normalize(i.cross(U,b,b),b),D[f]=b.x,D[h]=b.y,D[d]=b.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var Ee=new n,ye=new i,_e=new i,Te=new i,ve=new n;te.compressVertices=function(t){var r,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(r=0;r<a;++r)i.fromArray(s,3*r,ye),i.equals(ye,i.ZERO)?f+=2:(ve=e.octEncodeInRange(ye,65535,ve),l[f++]=ve.x,l[f++]=ve.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,m=c(h),E=c(d);if(!m&&!E)return t;var y,_,T,v,R=t.attributes.tangent,A=t.attributes.bitangent,S=c(R),g=c(A);m&&(y=h.values),E&&(_=d.values),S&&(T=R.values),g&&(v=A.values),a=(m?y.length:_.length)/(m?3:2);var N=a,I=E&&m?2:1;I+=S||g?1:0,N*=I;var O=new Float32Array(N),w=0;for(r=0;r<a;++r){E&&(n.fromArray(_,2*r,Ee),O[w++]=e.compressTextureCoordinates(Ee));var M=3*r;m&&c(T)&&c(v)?(i.fromArray(y,M,ye),i.fromArray(T,M,_e),i.fromArray(v,M,Te),e.octPack(ye,_e,Te,Ee),O[w++]=Ee.x,O[w++]=Ee.y):(m&&(i.fromArray(y,M,ye),O[w++]=e.octEncodeFloat(ye)),S&&(i.fromArray(T,M,ye),O[w++]=e.octEncodeFloat(ye)),g&&(i.fromArray(v,M,ye),O[w++]=e.octEncodeFloat(ye)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:I,values:O}),m&&delete t.attributes.normal,E&&delete t.attributes.st,g&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Re=new i,Ae=new i,Se=new i,ge=new i,Ne=new i,Ie={positions:new Array(7),indices:new Array(9)},Oe=new i,we=new i,Me=new i,xe=new i,Ce=new n,Pe=new n,De=new n,Ue=A.fromPointNormal(i.ZERO,i.UNIT_Y),be=new i,Le=new i,Fe=new n,Be=new n,ze=new i,qe=new i,Ge=new i,Ve=new i,Xe=new i,We=new i,He=new a,ke=5*T.EPSILON9,Ye=T.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==y.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else G(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,i){return t(e).then(r,n,i)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=i(e),t}function r(t){return e(t,a)}function n(e){this.then=e}function i(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return a(e)}})}function a(e){return new n(function(r,n){try{return n?t(n(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,r){return h(e,t,r)}function r(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new n(e),s={then:e,resolve:r,reject:i,progress:u,promise:c,resolver:{resolve:r,reject:i,progress:u}},l=[],f=[],h=function(e,t,r){var n,i;return n=o(),i="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,i)}),f.push(i),n.promise},d=function(e){return m(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=y,m(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,i,a){return E(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){p(e)}var c,l,f,h,d,p,m,E,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,h=[],d=o(),c)for(E=d.progress,m=function(e){h.push(e),--l||(p=m=y,d.reject(h))},p=function(e){f.push(e),--c||(p=m=y,d.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,E);else d.resolve(f);return d.then(n,i,a)})}function c(e,t,r,n){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,r,n)}function l(e,t,r,n){return E(1,arguments),h(e,_).then(t,r,n)}function f(){return h(arguments,_)}function h(t,r){return e(t,function(t){var n,i,a,u,s,c;if(a=i=t.length>>>0,n=[],c=o(),a)for(u=function(t,i){e(t,r).then(function(e){n[i]=e,--a||c.resolve(n)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(n);return c.promise})}function d(t,r){var n=v.call(arguments,1);return e(t,function(t){var i;return i=t.length,n[0]=function(t,n,a){return e(t,function(t){return e(n,function(e){return r(t,e,a,i)})})},T.apply(t,n)})}function p(t,r,n){var i=arguments.length>2;return e(t,function(e){return e=i?n:e,r.resolve(e),e},function(e){return r.reject(e),a(e)},r.progress)}function m(e,t){for(var r,n=0;r=e[n++];)r(t)}function E(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function y(){}function _(e){return e}var T,v,R;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},v=[].slice,T=[].reduce||function(e){var t,r,n,i,a;if(a=0,t=Object(this),i=t.length>>>0,r=arguments,r.length<=1)for(;;){if(a in t){n=t[a++];break}if(++a>=i)throw new TypeError}else n=r[1];for(;a<i;++a)a in t&&(n=e(n,t[a],a,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,i,a=0,o=e.length-1;a<=o;)if(n=~~((a+o)/2),(i=r(e[n],t))<0)a=n+1;else{if(!(i>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],i=function(e,t,r,n){r||(r=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+i:i+e},a=function(e,t,r,n,a,o){var u=n-e.length;return u>0&&(e=r||!a?i(e,n,o,r):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+i(c.toString(t),u||0,"0",!1),a(e,r,n,o,s)},u=function(e,t,r,n,i,o){return null!=n&&(e=e.slice(0,n)),a(e,"",t,r,i,o)},s=function(e,n,s,c,l,f,h){var d,p,m,E,y;if("%%"==e)return"%";for(var _=!1,T="",v=!1,R=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":v=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=n?t[n.slice(0,-1)]:t[r++],h){case"s":return u(String(y),_,c,f,v,A);case"c":return u(String.fromCharCode(+y),_,c,f,v);case"b":return o(y,2,R,_,c,f,v);case"o":return o(y,8,R,_,c,f,v);case"x":return o(y,16,R,_,c,f,v);case"X":return o(y,16,R,_,c,f,v).toUpperCase();case"u":return o(y,10,R,_,c,f,v);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),p=d<0?"-":T,y=p+i(String(Math.abs(d)),f,"0",!1),a(y,p,_,c,v);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,p=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],E=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=p+Math.abs(d)[m](f),a(y,p,_,c,v)[E]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,i,a,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var i=r[n].offset;if(n>0){m.secondsDifference(r[n].julianDate,e)>i&&(n--,i=r[n].offset)}m.addSeconds(e,i,e)}function h(e,r){_.julianDate=e;var n=m.leapSeconds,i=t(n,_,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-n[0].offset,r);if(i>=n.length)return m.addSeconds(e,-n[i-1].offset,r);var a=m.secondsDifference(n[i].julianDate,e);return 0===a?m.addSeconds(e,-n[i].offset,r):a<=1?void 0:m.addSeconds(e,-n[--i].offset,r)}function d(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function p(e,t,r,n,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=a+(n*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),n===c.UTC&&f(this)}var E=new a,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,v=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;m.fromGregorianDate=function(e,t){var r=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromDate=function(e,t){var r=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,i,a,u=e.split("T"),s=1,l=1,h=0,E=0,_=0,g=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(v)))r=+u[1],s=+u[2];else if(null!==(u=w.match(T)))r=+u[1];else{var x;if(null!==(u=w.match(R)))r=+u[1],x=+u[2],a=o(r);else if(null!==(u=w.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));x=7*C+P-D.getUTCDay()-3}i=new Date(Date.UTC(r,0,1)),i.setUTCDate(x),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(r);var U;if(n(M)){u=M.match(O),null!==u?(h=+u[1],E=+u[2],_=+u[3],g=1e3*+(u[4]||0),U=5):(u=M.match(I),null!==u?(h=+u[1],E=+u[2],_=60*+(u[3]||0),U=4):null!==(u=M.match(N))&&(h=+u[1],E=60*+(u[2]||0),U=3));var b=u[U],L=+u[U+1],F=+(u[U+2]||0);switch(b){case"+":h-=L,E-=F;break;case"-":h+=L,E+=F;break;case"Z":break;default:E+=new Date(Date.UTC(r,s-1,l,h,E)).getTimezoneOffset()}}var B=60===_;for(B&&_--;E>=60;)E-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:y[s-1];l>i;)l-=i,s++,s>12&&(s-=12,r++),i=a&&2===s?29:y[s-1];for(;E<0;)E+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),i=a&&2===s?29:y[s-1],l+=i;var z=p(r,s,l,h,E,_,g);return n(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var w=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var r=!1,i=h(e,w);n(i)||(m.addSeconds(e,-1,w),i=h(w,w),r=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var E=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,v=T/s.SECONDS_PER_MINUTE|0;T-=v*s.SECONDS_PER_MINUTE;var R=0|T,A=(T-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(R+=1),n(t)?(t.year=y,t.month=E,t.day=p,t.hour=_,t.minute=v,t.second=R,t.millisecond=A,t.isLeapSecond=r,t):new a(y,E,p,_,v,R,A,r)},m.toDate=function(e){var t=m.toGregorianDate(e,E),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var i,a=m.toGregorianDate(t,E);return n(r)||0===a.millisecond?n(r)&&0!==r?(i=(.01*a.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},m.addSeconds=function(e,t,r){return d(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,n,r)},m.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,n,r)},m.addDays=function(e,t,r){return d(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var i=new r.constructor;for(var a in r)if(r.hasOwnProperty(a)){var o=r[a];n&&(o=t(o,n)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function r(n,i,a){a=e(a,!1);var o,u,s,c={},l=t(n),f=t(i);if(l)for(o in n)n.hasOwnProperty(o)&&(u=n[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?r(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return r}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){t(i[r])||(i[r]=!0,console.warn(e(n,r)))}var i={};return n.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",n}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,r){"use strict";function n(e,t){r(e,t)}return n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(r,n,i){n=t(n,t(i.baseURI,i.location.href));var a=new e(n);return new e(r).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){var i="",a=r.lastIndexOf("/");return-1!==a&&(i=r.substring(0,a+1)),n?(r=new e(r),t(r.query)&&(i+="?"+r.query),t(r.fragment)&&(i+="#"+r.fragment),i):i}return n}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){var r=new e(t);r.normalize();var n=r.path,i=n.lastIndexOf("/");return-1!==i&&(n=n.substr(i+1)),i=n.lastIndexOf("."),n=-1===i?"":n.substr(i+1)}return n}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(r)||(r=document.createElement("a")),r.href=window.location.href;var n=r.host,i=r.protocol;return r.href=t,r.href=r.href,i!==r.protocol||n!==r.host}var r;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var i=e[n],a=encodeURIComponent(n)+"=";if(r(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return n}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(t){var n={};if(""===t)return n;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=n[s];"string"==typeof l?n[s]=[l,c]:r(l)?l.push(c):n[s]=c}return n}return n}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,n.OTHER),this.serverKey=void 0,this.state=r.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var i=r[n],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function n(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return r(n.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),n.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},n.prototype.removeEventListener=function(e,t){for(var r=this._listeners,n=this._scopes,i=-1,a=0;a<r.length;a++)if(r[a]===e&&n[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),r[i]=void 0,n[i]=void 0):(r.splice(i,1),n.splice(i,1)),!0)},n.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,r=this._listeners,n=this._scopes,a=r.length;for(e=0;e<a;e++){var o=r[e];t(o)&&r[e].apply(n[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];r.splice(s,1),n.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},n}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength}, +set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(i[c],i[e])<0?c:e,s<r&&n(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,n=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return r(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return a(r,e,--this._length),this.heapify(e),n}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function p(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function E(e){return function(t){e.state!==c.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function y(e){var t=p(e);return e.state=c.ACTIVE,g.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(m(e)).otherwise(E(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function T(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function v(){f.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),T())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var g=[],N={},I="undefined"!=typeof document?new e(document.location.href):new e,O=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=O,i(f,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,r=0,n=g.length;for(e=0;e<n;++e)t=g[e],t.cancelled&&_(t),t.state===c.ACTIVE?r>0&&(g[e-r]=t):++r;g.length-=r;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(y(t),++u):_(t);v()},f.getServerKey=function(t){var r=new e(t).resolve(I);r.normalize();var i=r.authority;/:/.test(i)||(i=i+":"+("https"===r.scheme?"443":"80"));var a=N[i];return n(a)||(N[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return O.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return y(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(n(t)){if(t===e)return;_(t)}return p(e)}},f.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=g.length,t=0;t<e;++t)_(g[t]);g.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var i=n.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=n.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])||(a[n]=!0)},i.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])&&delete a[n]},i.contains=function(e){var r=n(e);return!(!t(r)||!t(a[r]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T,v,R,A,S,g,N){"use strict";function I(e,t){var r=e.query;if(!a(r)||0===r.length)return{};var i;if(-1===r.indexOf("=")){var o={};o[r]=void 0,i=o}else i=y(r);t._queryParameters=n(t._queryParameters,i),e.query=void 0}function O(e,t){var r=t._queryParameters,n=Object.keys(r);1!==n.length||a(r[n[0]])?e.query=E(r):e.query=n[0]}function w(e,t){return a(e)?a(e.clone)?e.clone():r(e):t}function M(e){if(e.state===R.ISSUED||e.state===R.ACTIVE)throw new A("The Resource is already being fetched.");e.state=R.UNISSUED,e.deferred=void 0}function x(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=w(e.templateValues,{}),this._queryParameters=w(e.queryParameters,{}),this.headers=w(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var r=e.request;r.url=e.url,r.requestFunction=function(){var r=e.url,n=!1;e.isDataUri||e.isBlobUri||(n=e.isCrossOriginUrl);var i=N.defer();return x._Implementations.createImage(r,n&&t,i),i.promise};var n=v.request(r);if(a(n))return n.otherwise(function(n){return r.state!==R.FAILED?N.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,C(e,t)):N.reject(n)})})}function P(e,t,r){var n={};n[t]=r,e.addQueryParameters(n);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=N.defer();return window[r]=function(e){t.resolve(e);try{delete window[r]}catch(e){window[r]=void 0}},x._Implementations.loadAndExecuteScript(e.url,r,t),t.promise};var o=v.request(i);if(a(o))return o.otherwise(function(n){return i.state!==R.FAILED?N.reject(n):e.retryOnError(n).then(function(a){return a?(i.state=R.UNISSUED,i.deferred=void 0,P(e,t,r)):N.reject(n)})})}function D(e,t){M(e.request);var r=e.request;r.url=e.url,r.requestFunction=function(){var i=t.responseType,o=n(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=x._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(r.cancelFunction=function(){f.abort()}),l.promise};var i=v.request(r);if(a(i))return i.then(function(e){return e}).otherwise(function(n){return r.state!==R.FAILED?N.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,e.fetch(t)):N.reject(n)})})}function U(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function b(e,t){for(var r=U(e,t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return n}function L(e,t){t=i(t,"");var r=e[1],n=!!e[2],a=e[3];switch(t){case"":case"text":return U(n,a);case"arraybuffer":return b(n,a);case"blob":var o=b(n,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(U(n,a),r);case"json":return JSON.parse(U(n,a))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();x.createIfNeeded=function(e,t){if(e instanceof x)return e.clone();if("string"!=typeof e)return e;var r=w(t,{});return r.url=e,new x(r)},o(x,{isBlobSupported:{get:function(){return F}}}),o(x.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);I(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return p(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),x.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var r=new g(this._url);e&&O(r,this);var n=r.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];n=n.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(n=this.proxy.getURL(n)),n},x.prototype.addQueryParameters=function(e,t){this._queryParameters=t?n(this._queryParameters,e):n(e,this._queryParameters)},x.prototype.addTemplateValues=function(e,t){this._templateValues=t?n(this._templateValues,e):n(e,this._templateValues)},x.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var r=new g(e.url);I(r,t),r.fragment=void 0,t._url=r.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=n(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=n(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=n(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},x.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var r=this;return N(t(this,e)).then(function(e){return++r._retryCount,e})},x.prototype.clone=function(e){return a(e)||(e=new x({url:this._url})),e._url=this._url,e._queryParameters=r(this._queryParameters),e._templateValues=r(this._templateValues),e.headers=r(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},x.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},x.prototype.appendForwardSlash=function(){this._url=e(this._url)},x.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},x.fetchArrayBuffer=function(e){return new x(e).fetchArrayBuffer()},x.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},x.fetchBlob=function(e){return new x(e).fetchBlob()},x.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),M(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var r=this.fetchBlob();if(a(r)){var n,o;return r.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return n=new x({url:t}),C(n)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(n.url),e.blob=o,e}).otherwise(function(e){return a(n)&&window.URL.revokeObjectURL(n.url),N.reject(e)})}},x.fetchImage=function(e){return new x(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},x.prototype.fetchText=function(){return this.fetch({responseType:"text"})},x.fetchText=function(e){return new x(e).fetchText()},x.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},x.fetchJson=function(e){return new x(e).fetchJson()},x.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},x.fetchXML=function(e){return new x(e).fetchXML()},x.prototype.fetchJsonp=function(e){e=i(e,"callback"),M(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},x.fetchJsonp=function(e){return new x(e).fetchJsonp(e.callbackParameterName)},x.prototype.fetch=function(e){return e=w(e,i.EMPTY_OBJECT),e.method="GET",D(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return x.fetch=function(e){return new x(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x.prototype.post=function(e,r){return t.defined("data",e),r=w(r,{}),r.method="POST",r.data=e,D(this,r)},x.post=function(e){return new x(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x._Implementations={},x._Implementations.createImage=function(e,t,r){var n=new Image;n.onload=function(){r.resolve(n)},n.onerror=function(e){r.reject(e)},t&&(S.contains(e)?n.crossOrigin="use-credentials":n.crossOrigin=""),n.src=e},x._Implementations.loadWithXhr=function(e,t,r,n,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(L(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(r,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,r=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&r!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===r||"document"===r)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==r&&"text"!==r||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(n),c},x._Implementations.loadAndExecuteScript=function(e,t,r){var n=document.createElement("script");n.async=!0,n.src=e;var i=document.getElementsByTagName("head")[0];n.onload=function(){n.onload=void 0,i.removeChild(n)},n.onerror=function(e){r.reject(e)},i.appendChild(n)},x._DefaultImplementations={},x._DefaultImplementations.createImage=x._Implementations.createImage,x._DefaultImplementations.loadWithXhr=x._Implementations.loadWithXhr,x._DefaultImplementations.loadAndExecuteScript=x._Implementations.loadAndExecuteScript,x.DEFAULT=c(new x({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),x}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))p(this,t.data);else if(n(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){p(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=r.columnNames.indexOf("modifiedJulianDateUtc"),a=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||p<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var E=e._samples=r.samples,y=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,v=0,R=E.length;v<R;v+=e._columnCount){var A=E[v+i],S=E[v+m],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,S,f.TAI);if(y.push(N),T){if(S!==_&&n(_)){var I=o.leapSeconds,O=t(I,N,d);if(O<0){var w=new u(N,S);I.splice(~O,0,w)}}_=S}}}function m(e,t,r,n,i){var a=r*n;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function E(e,t,r){return t+e*(r-t)}function y(e,t,r,n,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||n.equals(c))return m(e,r,i,s,u),u;if(n.equals(l))return m(e,r,a,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=r[h+e._ut1MinusUtcSecondsColumn],y=r[d+e._ut1MinusUtcSecondsColumn],_=y-p;if(_>.5||_<-.5){var T=r[h+e._taiMinusUtcSecondsColumn],v=r[d+e._taiMinusUtcSecondsColumn];T!==v&&(l.equals(n)?p=y:y-=v-T)}return u.xPoleWander=E(f,r[h+e._xPoleWanderRadiansColumn],r[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=E(f,r[h+e._yPoleWanderRadiansColumn],r[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=E(f,r[h+e._xCelestialPoleOffsetRadiansColumn],r[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=E(f,r[h+e._yCelestialPoleOffsetRadiansColumn],r[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=E(f,p,y),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new i(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var a=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!n(h),m=p||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!p&&h.equals(e)&&++s,l=s+1,y(this,a,this._samples,e,s,l,r),r}var E=t(a,e,o.compare,this._dateColumn);return E>=0?(E<a.length-1&&a[E+1].equals(e)&&++E,s=E,l=E):(l=~E,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,a,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,r,n,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),i=d.exec(n);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new n({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var r=f(e);return h.href=r,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=n.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){n[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(n[c]*=c-l);n[c]=1/n[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,a.daysDifference(n,e._sampleZeroDateTT)}function l(r,i){if(r._chunkDownloadsInProgress[i])return r._chunkDownloadsInProgress[i];var a=e.defer();r._chunkDownloadsInProgress[i]=a;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){r._chunkDownloadsInProgress[i]=!1;for(var t=r._samples,n=e.samples,o=i*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,r,n,i){var a=c(this,t,r),o=c(this,n,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,r){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(n(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),n(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){n(r)?(r.x=0,r.y=0,r.s=0):r=new i(0,0,0);var p,m,E=a-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,v=this._xTable;for(p=0;p<=u;++p)y[p]=E-v[p];for(p=0;p<=u;++p){for(T[p]=1,m=0;m<=u;++m)m!==p&&(T[p]*=y[m]);T[p]*=_[p];var R=3*(s+p);r.x+=T[p]*d[R++],r.y+=T[p]*d[R++],r.s+=T[p]*d[R]}return r}}}},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T){"use strict";var v={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},N=new r,I=new r,O=new r;v.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,i=R[e][t],a=e+t;return u(S[a])?n=S[a]:(n=function(n,a,s){if(u(s)||(s=new y),m.equalsEpsilon(n.x,0,m.EPSILON14)&&m.equalsEpsilon(n.y,0,m.EPSILON14)){var c=m.sign(n.z);r.unpack(A[e],0,N),"east"!==e&&"west"!==e&&r.multiplyByScalar(N,c,N),r.unpack(A[t],0,I),"east"!==t&&"west"!==t&&r.multiplyByScalar(I,c,I),r.unpack(A[i],0,O),"east"!==i&&"west"!==i&&r.multiplyByScalar(O,c,O)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(n,g.up);var l=g.up,h=g.east;h.x=-n.y,h.y=n.x,h.z=0,r.normalize(h,g.east),r.cross(l,h,g.north),r.multiplyByScalar(g.up,-1,g.down),r.multiplyByScalar(g.east,-1,g.west),r.multiplyByScalar(g.north,-1,g.south),N=g[e],I=g[t],O=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=I.x,s[5]=I.y,s[6]=I.z,s[7]=0,s[8]=O.x,s[9]=O.y,s[10]=O.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},S[a]=n),n},v.eastNorthUpToFixedFrame=v.localFrameToFixedFrameGenerator("east","north"),v.northEastDownToFixedFrame=v.localFrameToFixedFrameGenerator("north","east"),v.northUpEastToFixedFrame=v.localFrameToFixedFrameGenerator("north","up"),v.northWestUpToFixedFrame=v.localFrameToFixedFrameGenerator("north","west");var w=new _,M=new r(1,1,1),x=new y;v.headingPitchRollToFixedFrame=function(e,t,n,i,a){i=o(i,v.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=y.fromTranslationQuaternionRotationScale(r.ZERO,u,M,x);return a=i(e,n,a),y.multiply(a,s,a)};var C=new y,P=new E;v.headingPitchRollQuaternion=function(e,t,r,n,i){var a=v.headingPitchRollToFixedFrame(e,t,r,n,C),o=y.getRotation(a,P);return _.fromRotationMatrix(o,i)};var D=m.TWO_PI/86400,U=new p;v.computeTemeToPseudoFixedMatrix=function(e,t){U=p.addSeconds(e,-p.computeTaiMinusUtc(e),U);var r,n=U.dayNumber,i=U.secondsOfDay,a=n-2451545;r=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(h,d,0,-d,h,0,0,0,1)},v.iau2006XysData=new h,v.earthOrientationParameters=c.NONE;v.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=v.iau2006XysData.preload(r,n,i,a),u=v.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},v.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new E);var r=v.computeFixedToIcrfMatrix(e,t);if(u(r))return E.transpose(r,t)};var b=new d(0,0,0),L=new l(0,0,0,0,0,0),F=new E,B=new E;v.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new E);var r=v.earthOrientationParameters.compute(e,L);if(u(r)){var n=e.dayNumber,i=e.secondsOfDay+32.184,a=v.iau2006XysData.computeXysRadians(n,i,b);if(u(a)){var o=a.x+r.xPoleOffset,s=a.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=E.fromRotationZ(-a.s,B),h=E.multiply(l,f,F),d=e.dayNumber,y=e.secondsOfDay-p.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=d-2451545,R=y/T.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*m.TWO_PI;var S=E.fromRotationZ(A,B),g=E.multiply(h,S,F),N=Math.cos(r.xPoleWander),I=Math.cos(r.yPoleWander),O=Math.sin(r.xPoleWander),w=Math.sin(r.yPoleWander),M=n-2451545+i/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),D=B;return D[0]=N*C,D[1]=N*P,D[2]=O,D[3]=-I*P+w*O*C,D[4]=I*C+w*O*P,D[5]=-w*N,D[6]=-w*P-I*O*C,D[7]=w*C-I*O*P,D[8]=I*N,E.multiply(g,D,t)}}};var z=new n;v.pointToWindowCoordinates=function(e,t,r,n){return n=v.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},v.pointToGLWindowCoordinates=function(e,r,i,a){u(a)||(a=new t);var o=z;return y.multiplyByVector(e,n.fromElements(i.x,i.y,i.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(r,o,o),t.fromCartesian4(o,a)};var q=new r,G=new r,V=new r;v.rotationMatrixFromPositionVelocity=function(e,t,n,i){var a=o(n,f.WGS84).geodeticSurfaceNormal(e,q),s=r.cross(t,a,G);r.equalsEpsilon(s,r.ZERO,m.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,V);return r.cross(t,c,s),r.negate(s,s),u(i)||(i=new E),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var X=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),W=new i,H=new r,k=new r,Y=new E,j=new y,Z=new y;return v.basisTo2D=function(e,t,n){var i=y.getTranslation(t,k),a=e.ellipsoid,o=a.cartesianToCartographic(i,W),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=v.eastNorthUpToFixedFrame(i,a,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,Y),f=y.multiplyByMatrix3(c,l,n);return y.multiply(X,f,n),y.setTranslation(n,u,n),n},v.wgs84To2DModelMatrix=function(e,t,n){var i=e.ellipsoid,a=v.eastNorthUpToFixedFrame(t,i,j),o=y.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,W),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(X,o,n),y.multiply(c,n,n),n},v}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=n(new i({position:!0})),i.POSITION_AND_NORMAL=n(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=n(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=n(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=n(new i({position:!0,color:!0})),i.ALL=n(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.position?1:0,r[n++]=t.normal?1:0,r[n++]=t.st?1:0,r[n++]=t.tangent?1:0,r[n++]=t.bitangent?1:0,r[n]=t.color?1:0,r},i.unpack=function(r,n,a){return n=e(n,0),t(a)||(a=new i),a.position=1===r[n++],a.normal=1===r[n++],a.st=1===r[n++],a.tangent=1===r[n++],a.bitangent=1===r[n++],a.color=1===r[n],a},i.clone=function(e,r){if(t(e))return t(r)||(r=new i),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},i}), +define("Core/EllipseGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./Matrix4","./PrimitiveType","./Quaternion","./Rectangle","./Transforms","./VertexFormat"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T,v,R,A,S,g,N){"use strict";function I(e,n,a){var o=n.vertexFormat,u=n.center,s=n.semiMajorAxis,l=n.semiMinorAxis,h=n.ellipsoid,m=n.stRotation,E=a?e.length/3*2:e.length/3,y=n.shadowVolume,_=o.st?new Float32Array(2*E):void 0,v=o.normal?new Float32Array(3*E):void 0,R=o.tangent?new Float32Array(3*E):void 0,S=o.bitangent?new Float32Array(3*E):void 0,g=y?new Float32Array(3*E):void 0,N=0,I=G,O=V,w=X,M=new f(h),x=M.project(h.cartesianToCartographic(u,W),H),C=h.scaleToGeodeticSurface(u,U);h.geodeticSurfaceNormal(C,C);for(var P=A.fromAxisAngle(C,m,q),D=T.fromQuaternion(P,z),F=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,k),j=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Y),Z=e.length,K=a?Z:0,J=K/3*2,Q=0;Q<Z;Q+=3){var $=Q+1,ee=Q+2,te=r.fromArray(e,Q,U);if(o.st){var re=T.multiplyByVector(D,te,b),ne=M.project(h.cartesianToCartographic(re,W),L);r.subtract(ne,x,ne),B.x=(ne.x+s)/(2*s),B.y=(ne.y+l)/(2*l),F.x=Math.min(B.x,F.x),F.y=Math.min(B.y,F.y),j.x=Math.max(B.x,j.x),j.y=Math.max(B.y,j.y),a&&(_[N+J]=B.x,_[N+1+J]=B.y),_[N++]=B.x,_[N++]=B.y}(o.normal||o.tangent||o.bitangent||y)&&(I=h.geodeticSurfaceNormal(te,I),y&&(g[Q+K]=-I.x,g[$+K]=-I.y,g[ee+K]=-I.z),(o.normal||o.tangent||o.bitangent)&&((o.tangent||o.bitangent)&&(O=r.normalize(r.cross(r.UNIT_Z,I,O),O),T.multiplyByVector(D,O,O)),o.normal&&(v[Q]=I.x,v[$]=I.y,v[ee]=I.z,a&&(v[Q+K]=-I.x,v[$+K]=-I.y,v[ee+K]=-I.z)),o.tangent&&(R[Q]=O.x,R[$]=O.y,R[ee]=O.z,a&&(R[Q+K]=-O.x,R[$+K]=-O.y,R[ee+K]=-O.z)),o.bitangent&&(w=r.normalize(r.cross(I,O,w),w),S[Q]=w.x,S[$]=w.y,S[ee]=w.z,a&&(S[Q+K]=w.x,S[$+K]=w.y,S[ee+K]=w.z))))}if(o.st){Z=_.length;for(var ie=0;ie<Z;ie+=2)_[ie]=(_[ie]-F.x)/(j.x-F.x),_[ie+1]=(_[ie+1]-F.y)/(j.y-F.y)}var ae=new p;if(o.position){var oe=c.raisePositionsToHeight(e,n,a);ae.position=new d({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:oe})}return o.st&&(ae.st=new d({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:_})),o.normal&&(ae.normal=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:v})),o.tangent&&(ae.tangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:R})),o.bitangent&&(ae.bitangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:S})),y&&(ae.extrudeDirection=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:g})),ae}function O(e){var t,r,n,i,a,o=new Array(e*(e+1)*12-6),u=0;for(t=0,n=1,i=0;i<3;i++)o[u++]=n++,o[u++]=t,o[u++]=n;for(i=2;i<e+1;++i){for(n=i*(i+1)-1,t=(i-1)*i-1,o[u++]=n++,o[u++]=t,o[u++]=n,r=2*i,a=0;a<r-1;++a)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=n++,o[u++]=t,o[u++]=n}for(r=2*e,++n,++t,i=0;i<r-1;++i)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;for(o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t++,o[u++]=t,++t,i=e-1;i>1;--i){for(o[u++]=t++,o[u++]=t,o[u++]=n,r=2*i,a=0;a<r-1;++a)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=t++,o[u++]=t++,o[u++]=n++}for(i=0;i<3;i++)o[u++]=t++,o[u++]=t,o[u++]=n;return o}function w(t){var n=t.center;j=r.multiplyByScalar(t.ellipsoid.geodeticSurfaceNormal(n,j),t.height,j),j=r.add(n,j,j);var i=new e(j,t.semiMajorAxis),a=c.computeEllipsePositions(t,!0,!1),o=a.positions,u=a.numPts,s=I(o,t,!1),l=O(u);return l=y.createTypedArray(o.length/3,l),{boundingSphere:i,attributes:s,indices:l}}function M(e,n){var a=n.vertexFormat,o=n.center,u=n.semiMajorAxis,s=n.semiMinorAxis,c=n.ellipsoid,l=n.height,h=n.extrudedHeight,m=n.stRotation,E=e.length/3*2,y=new Float64Array(3*E),_=a.st?new Float32Array(2*E):void 0,v=a.normal?new Float32Array(3*E):void 0,R=a.tangent?new Float32Array(3*E):void 0,S=a.bitangent?new Float32Array(3*E):void 0,g=n.shadowVolume,N=g?new Float32Array(3*E):void 0,I=0,O=G,w=V,M=X,x=new f(c),C=x.project(c.cartesianToCartographic(o,W),H),P=c.scaleToGeodeticSurface(o,U);c.geodeticSurfaceNormal(P,P);for(var D=A.fromAxisAngle(P,m,q),j=T.fromQuaternion(D,z),Z=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,k),K=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Y),J=e.length,Q=J/3*2,$=0;$<J;$+=3){var ee,te=$+1,re=$+2,ne=r.fromArray(e,$,U);if(a.st){var ie=T.multiplyByVector(j,ne,b),ae=x.project(c.cartesianToCartographic(ie,W),L);r.subtract(ae,C,ae),B.x=(ae.x+u)/(2*u),B.y=(ae.y+s)/(2*s),Z.x=Math.min(B.x,Z.x),Z.y=Math.min(B.y,Z.y),K.x=Math.max(B.x,K.x),K.y=Math.max(B.y,K.y),_[I+Q]=B.x,_[I+1+Q]=B.y,_[I++]=B.x,_[I++]=B.y}ne=c.scaleToGeodeticSurface(ne,ne),ee=r.clone(ne,b),O=c.geodeticSurfaceNormal(ne,O),g&&(N[$+J]=-O.x,N[te+J]=-O.y,N[re+J]=-O.z);var oe=r.multiplyByScalar(O,l,F);if(ne=r.add(ne,oe,ne),oe=r.multiplyByScalar(O,h,oe),ee=r.add(ee,oe,ee),a.position&&(y[$+J]=ee.x,y[te+J]=ee.y,y[re+J]=ee.z,y[$]=ne.x,y[te]=ne.y,y[re]=ne.z),a.normal||a.tangent||a.bitangent){M=r.clone(O,M);var ue=r.fromArray(e,($+3)%J,F);r.subtract(ue,ne,ue);var se=r.subtract(ee,ne,L);O=r.normalize(r.cross(se,ue,O),O),a.normal&&(v[$]=O.x,v[te]=O.y,v[re]=O.z,v[$+J]=O.x,v[te+J]=O.y,v[re+J]=O.z),a.tangent&&(w=r.normalize(r.cross(M,O,w),w),R[$]=w.x,R[te]=w.y,R[re]=w.z,R[$+J]=w.x,R[$+1+J]=w.y,R[$+2+J]=w.z),a.bitangent&&(S[$]=M.x,S[te]=M.y,S[re]=M.z,S[$+J]=M.x,S[te+J]=M.y,S[re+J]=M.z)}}if(a.st){J=_.length;for(var ce=0;ce<J;ce+=2)_[ce]=(_[ce]-Z.x)/(K.x-Z.x),_[ce+1]=(_[ce+1]-Z.y)/(K.y-Z.y)}var le=new p;return a.position&&(le.position=new d({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:y})),a.st&&(le.st=new d({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:_})),a.normal&&(le.normal=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:v})),a.tangent&&(le.tangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:R})),a.bitangent&&(le.bitangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:S})),g&&(le.extrudeDirection=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:N})),le}function x(e){for(var t=e.length/3,r=y.createTypedArray(t,6*t),n=0,i=0;i<t;i++){var a=i,o=i+t,u=(a+1)%t,s=u+t;r[n++]=a,r[n++]=o,r[n++]=u,r[n++]=u,r[n++]=o,r[n++]=s}return r}function C(t){var n=t.center,i=t.ellipsoid,a=t.semiMajorAxis,o=r.multiplyByScalar(i.geodeticSurfaceNormal(n,U),t.height,U);Z.center=r.add(n,o,Z.center),Z.radius=a,o=r.multiplyByScalar(i.geodeticSurfaceNormal(n,o),t.extrudedHeight,o),K.center=r.add(n,o,K.center),K.radius=a;var u=c.computeEllipsePositions(t,!0,!0),s=u.positions,l=u.numPts,f=u.outerPositions,d=e.union(Z,K),p=I(s,t,!0),_=O(l),T=_.length;_.length=2*T;for(var v=s.length/3,A=0;A<T;A+=3)_[A+T]=_[A+2]+v,_[A+1+T]=_[A+1]+v,_[A+2+T]=_[A]+v;var S=y.createTypedArray(2*v/3,_),g=new h({attributes:p,indices:S,primitiveType:R.TRIANGLES}),N=M(f,t);_=x(f);var w=y.createTypedArray(2*f.length/3,_),C=new h({attributes:N,indices:w,primitiveType:R.TRIANGLES}),P=E.combineInstances([new m({geometry:g}),new m({geometry:C})]);return{boundingSphere:d,attributes:P[0].attributes,indices:P[0].indices}}function P(e,t,n,i,a){g.eastNorthUpToFixedFrame(e,t,J),v.inverseTransformation(J,Q);var o;for(o=0;o<4;++o)r.clone(r.ZERO,ee[o]);for(ee[0].x+=n,ee[1].x-=n,ee[2].y+=i,ee[3].y-=i,T.fromRotationZ(a,$),o=0;o<4;++o)T.multiplyByVector($,ee[o],ee[o]),v.multiplyByPoint(J,ee[o],ee[o]),t.cartesianToCartographic(ee[o],te[o]);return S.fromCartographicArray(te)}function D(e){e=a(e,a.EMPTY_OBJECT);var t=e.center,n=a(e.ellipsoid,l.WGS84),i=e.semiMajorAxis,u=e.semiMinorAxis,s=a(e.granularity,_.RADIANS_PER_DEGREE),c=a(e.height,0),f=e.extrudedHeight,h=o(f)&&Math.abs(c-f)>1,d=a(e.vertexFormat,N.DEFAULT);this._center=r.clone(t),this._semiMajorAxis=i,this._semiMinorAxis=u,this._ellipsoid=l.clone(n),this._rotation=a(e.rotation,0),this._stRotation=a(e.stRotation,0),this._height=c,this._granularity=s,this._vertexFormat=N.clone(d),this._extrudedHeight=a(f,c),this._extrude=h,this._shadowVolume=a(e.shadowVolume,!1),this._workerName="createEllipseGeometry",this._rectangle=P(this._center,this._ellipsoid,i,u,this._rotation)}var U=new r,b=new r,L=new r,F=new r,B=new t,z=new T,q=new A,G=new r,V=new r,X=new r,W=new n,H=new r,k=new t,Y=new t,j=new r,Z=new e,K=new e,J=new v,Q=new v,$=new T,ee=[new r,new r,new r,new r],te=[new n,new n,new n,new n];D.packedLength=r.packedLength+l.packedLength+N.packedLength+S.packedLength+9,D.pack=function(e,t,n){return n=a(n,0),r.pack(e._center,t,n),n+=r.packedLength,l.pack(e._ellipsoid,t,n),n+=l.packedLength,N.pack(e._vertexFormat,t,n),n+=N.packedLength,S.pack(e._rectangle,t,n),n+=S.packedLength,t[n++]=e._semiMajorAxis,t[n++]=e._semiMinorAxis,t[n++]=e._rotation,t[n++]=e._stRotation,t[n++]=e._height,t[n++]=e._granularity,t[n++]=e._extrudedHeight,t[n++]=e._extrude?1:0,t[n]=e._shadowVolume?1:0,t};var re=new r,ne=new l,ie=new N,ae=new S,oe={center:re,ellipsoid:ne,vertexFormat:ie,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,stRotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,shadowVolume:void 0};return D.unpack=function(e,t,n){t=a(t,0);var i=r.unpack(e,t,re);t+=r.packedLength;var u=l.unpack(e,t,ne);t+=l.packedLength;var s=N.unpack(e,t,ie);t+=N.packedLength;var c=S.unpack(e,t,ae);t+=S.packedLength;var f=e[t++],h=e[t++],d=e[t++],p=e[t++],m=e[t++],E=e[t++],y=e[t++],_=1===e[t++],T=1===e[t];return o(n)?(n._center=r.clone(i,n._center),n._ellipsoid=l.clone(u,n._ellipsoid),n._vertexFormat=N.clone(s,n._vertexFormat),n._semiMajorAxis=f,n._semiMinorAxis=h,n._rotation=d,n._stRotation=p,n._height=m,n._granularity=E,n._extrudedHeight=y,n._extrude=_,n._shadowVolume=T,n._rectangle=S.clone(c),n):(oe.height=m,oe.extrudedHeight=y,oe.granularity=E,oe.stRotation=p,oe.rotation=d,oe.semiMajorAxis=f,oe.semiMinorAxis=h,oe.shadowVolume=T,new D(oe))},D.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,vertexFormat:e._vertexFormat,stRotation:e._stRotation};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),r.shadowVolume=e._shadowVolume,t=C(r)):t=w(r),new h({attributes:t.attributes,indices:t.indices,primitiveType:R.TRIANGLES,boundingSphere:t.boundingSphere})}},D.createShadowVolume=function(e,t,r){var n=e._granularity,i=e._ellipsoid,a=t(n,i),o=r(n,i);return new D({center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:i,rotation:e._rotation,stRotation:e._stRotation,granularity:n,extrudedHeight:a,height:o,vertexFormat:N.POSITION_ONLY,shadowVolume:!0})},u(D.prototype,{rectangle:{get:function(){return this._rectangle}}}),D}),define("Core/CircleGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./EllipseGeometry","./Ellipsoid","./VertexFormat"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT);var t=e.radius,n={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,vertexFormat:e.vertexFormat,stRotation:e.stRotation,shadowVolume:e.shadowVolume};this._ellipseGeometry=new a(n),this._workerName="createCircleGeometry"}s.packedLength=a.packedLength,s.pack=function(e,t,r){return a.pack(e._ellipseGeometry,t,r)};var c=new a({center:new e,semiMajorAxis:1,semiMinorAxis:1}),l={center:new e,radius:void 0,ellipsoid:o.clone(o.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,vertexFormat:new u,stRotation:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0,shadowVolume:void 0};return s.unpack=function(t,r,i){var f=a.unpack(t,r,c);return l.center=e.clone(f._center,l.center),l.ellipsoid=o.clone(f._ellipsoid,l.ellipsoid),l.height=f._height,l.extrudedHeight=f._extrudedHeight,l.granularity=f._granularity,l.vertexFormat=u.clone(f._vertexFormat,l.vertexFormat),l.stRotation=f._stRotation,l.shadowVolume=f._shadowVolume,n(i)?(l.semiMajorAxis=f._semiMajorAxis,l.semiMinorAxis=f._semiMinorAxis,i._ellipseGeometry=new a(l),i):(l.radius=f._semiMajorAxis,new s(l))},s.createGeometry=function(e){return a.createGeometry(e._ellipseGeometry)},s.createShadowVolume=function(e,t,r){var n=e._ellipseGeometry._granularity,i=e._ellipseGeometry._ellipsoid,a=t(n,i),o=r(n,i);return new s({center:e._ellipseGeometry._center,radius:e._ellipseGeometry._semiMajorAxis,ellipsoid:i,stRotation:e._ellipseGeometry._stRotation,granularity:n,extrudedHeight:a,height:o,vertexFormat:u.POSITION_ONLY,shadowVolume:!0})},i(s.prototype,{rectangle:{get:function(){return this._ellipseGeometry.rectangle}}}),s}),define("Workers/createCircleGeometry",["../Core/Cartesian3","../Core/CircleGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,r,n){"use strict";function i(i,a){return r(a)&&(i=t.unpack(i,a)),i._ellipseGeometry._center=e.clone(i._ellipseGeometry._center),i._ellipseGeometry._ellipsoid=n.clone(i._ellipseGeometry._ellipsoid),t.createGeometry(i)}return i})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleOutlineGeometry.js index a9bebdcf..ba4bc278 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCircleOutlineGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,E),o.normalize(t,c);var n=o.dot(E,c),r=o.magnitude(o.cross(E,c,E));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,E=i*s-a*u,c=a*o-r*s,_=r*u-i*o;return n.x=E,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var l=new o,T=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:R,E=Math.cos(r);l.x=E*Math.cos(e),l.y=E*Math.sin(e),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,T);var c=Math.sqrt(o.dot(l,T));return T=o.divideByScalar(T,c,T),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(T,l,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],E=a/2;r[E]=o.fromDegrees(u,s,0,t,r[E])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],E=a/2;r[E]=o.fromRadians(u,s,0,t,r[E])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],E=e[a+2],c=a/3;r[c]=o.fromDegrees(u,s,E,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],E=e[a+2],c=a/3;r[c]=o.fromRadians(u,s,E,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,E){var c=n.x,_=n.y,l=n.z,T=i.x,R=i.y,f=i.z,A=c*c*T*T,h=_*_*R*R,d=l*l*f*f,N=A+h+d,I=Math.sqrt(1/N),S=e.multiplyByScalar(n,I,a);if(N<s)return isFinite(I)?e.clone(S,E):void 0;var M=u.x,m=u.y,y=u.z,O=o;O.x=S.x*M*2,O.y=S.y*m*2,O.z=S.z*y*2;var p,C,U,g,w,L,x,P,v,F,B,D=(1-I)*e.magnitude(n)/(.5*e.magnitude(O)),z=0;do{D-=z,U=1/(1+D*M),g=1/(1+D*m),w=1/(1+D*y),L=U*U,x=g*g,P=w*w,v=L*U,F=x*g,B=P*w,p=A*L+h*x+d*P-1,C=A*v*M+h*F*m+d*B*y;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(E)?(E.x=c*U,E.y=_*g,E.z=l*w,E):new e(c*U,_*g,l*w)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,E=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),l=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:l,A=r(n)?n._centerToleranceSquared:T,h=o(t,R,f,A,E);if(r(h)){var d=e.multiplyComponents(h,f,s);d=e.normalize(d,d);var N=e.subtract(t,h,c),I=Math.atan2(d.y,d.x),S=Math.asin(d.z),M=a.sign(e.dot(N,t))*e.magnitude(N);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,E){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),E=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=E,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var l=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=l,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var R=new e,f=new e,A=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,f);if(i(a)){var o=this.geodeticSurfaceNormal(a,R),u=e.subtract(n,a,A),E=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=E,r.latitude=c,r.height=_,r):new t(E,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return E(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,E){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(E,0)}function E(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(f[n],R[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(f[a],R[a])]);o>r&&(i=a,r=o)}var E=1,c=0,_=R[i],l=f[i];if(Math.abs(e[s.getElementIndex(l,_)])>n){var T,A=e[s.getElementIndex(l,l)],h=e[s.getElementIndex(_,_)],d=e[s.getElementIndex(l,_)],N=(A-h)/2/d;T=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),E=1/Math.sqrt(1+T*T),c=T*E}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(_,_)]=t[s.getElementIndex(l,l)]=E,t[s.getElementIndex(l,_)]=c,t[s.getElementIndex(_,l)]=-c,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,E=e.y*e.z,c=e.y*e.w,_=e.z*e.z,l=e.z*e.w,T=e.w*e.w,R=n-u-_+T,f=2*(i-l),A=2*(a+c),h=2*(i+l),d=-n+u-_+T,N=2*(E-o),I=2*(a-c),S=2*(E+o),M=-n-u+_+T;return r(t)?(t[0]=R,t[1]=h,t[2]=I,t[3]=f,t[4]=d,t[5]=S,t[6]=A,t[7]=N,t[8]=M,t):new s(R,f,A,h,d,N,I,S,M)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),E=Math.sin(e.roll),c=n*i,_=-a*u+E*o*i,l=E*u+a*o*i,T=n*u,R=a*i+E*o*u,f=-E*i+a*o*u,A=-o,h=E*n,d=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=A,t[3]=_,t[4]=R,t[5]=h,t[6]=l,t[7]=f,t[8]=d,t):new s(c,_,l,T,R,f,A,h,d)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var l=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],l)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],l)),n};var T=new e;s.getMaximumScale=function(t){return s.getScale(t,T),e.maximumComponent(T)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],E=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=E,n[7]=c,n[8]=_,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],E=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=E,t[8]=c,t};var R=[1,0,0],f=[2,2,1],A=new s,h=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),l=t.diagonal=s.clone(e,t.diagonal),T=n*E(l);a<10&&c(l)>T;)_(l,A),s.transpose(A,h),s.multiply(l,A,l),s.multiply(h,l,l),s.multiply(o,A,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],E=e[8];return t*(a*E-s*o)+i*(s*r-n*E)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],E=e[6],c=e[7],_=e[8],l=s.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=E*u-a*_,t[4]=n*_-E*i,t[5]=a*i-n*u,t[6]=a*c-E*o,t[7]=E*r-n*c,t[8]=n*o-a*r;var T=1/l;return s.multiplyByScalar(t,T,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,E){"use strict";function c(e,t,n,i,a,o,u,s,E,c,_,l,T,R,f,A){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(E,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,E=t.x*t.y,_=t.x*t.z,l=t.x*t.w,T=t.y*t.y,R=t.y*t.z,f=t.y*t.w,A=t.z*t.z,h=t.z*t.w,d=t.w*t.w,N=s-T-A+d,I=2*(E-h),S=2*(_+f),M=2*(E+h),m=-s+T-A+d,y=2*(R-l),O=2*(_-f),p=2*(R+l),C=-s-T+A+d;return r[0]=N*a,r[1]=M*a,r[2]=O*a,r[3]=0,r[4]=I*o,r[5]=m*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=y*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(s.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,l=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,l),l),e.normalize(e.cross(l,_,T),T);var u=l.x,s=l.y,E=l.z,R=_.x,f=_.y,A=_.z,h=T.x,d=T.y,N=T.z,I=r.x,S=r.y,M=r.z,m=u*-I+s*-S+E*-M,y=h*-I+d*-S+N*-M,O=R*I+f*S+A*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-R,n[3]=0,n[4]=s,n[5]=d,n[6]=-f,n[7]=0,n[8]=E,n[9]=N,n[10]=-A,n[11]=0,n[12]=m,n[13]=y,n[14]=O,n[15]=1,n):new c(u,s,E,m,h,d,N,y,-R,-f,-A,O,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),E=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=E,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),E=1/(a-i),c=-(t+e)*u,_=-(r+n)*s,l=-(a+i)*E;return u*=2,s*=2,E*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=E,o[11]=0,o[12]=c,o[13]=_,o[14]=l,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),E=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=E,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),E=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=E,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var E=.5*u,c=.5*s,_=.5*(n-t),l=E,T=c,R=_,f=a+E,A=o+c,h=t+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=R,i[11]=0,i[12]=f,i[13]=A,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var R=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],R)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],R)),n};var f=new e;c.getMaximumScale=function(t){return c.getScale(t,f),e.maximumComponent(f)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],E=e[6],c=e[7],_=e[8],l=e[9],T=e[10],R=e[11],f=e[12],A=e[13],h=e[14],d=e[15],N=t[0],I=t[1],S=t[2],M=t[3],m=t[4],y=t[5],O=t[6],p=t[7],C=t[8],U=t[9],g=t[10],w=t[11],L=t[12],x=t[13],P=t[14],v=t[15],F=r*N+u*I+_*S+f*M,B=i*N+s*I+l*S+A*M,D=a*N+E*I+T*S+h*M,z=o*N+c*I+R*S+d*M,G=r*m+u*y+_*O+f*p,b=i*m+s*y+l*O+A*p,V=a*m+E*y+T*O+h*p,X=o*m+c*y+R*O+d*p,H=r*C+u*U+_*g+f*w,q=i*C+s*U+l*g+A*w,W=a*C+E*U+T*g+h*w,Y=o*C+c*U+R*g+d*w,k=r*L+u*x+_*P+f*v,K=i*L+s*x+l*P+A*v,j=a*L+E*x+T*P+h*v,Z=o*L+c*x+R*P+d*v;return n[0]=F,n[1]=B,n[2]=D,n[3]=z,n[4]=G,n[5]=b,n[6]=V,n[7]=X,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=j,n[15]=Z,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],E=e[8],c=e[9],_=e[10],l=e[12],T=e[13],R=e[14],f=t[0],A=t[1],h=t[2],d=t[4],N=t[5],I=t[6],S=t[8],M=t[9],m=t[10],y=t[12],O=t[13],p=t[14],C=r*f+o*A+E*h,U=i*f+u*A+c*h,g=a*f+s*A+_*h,w=r*d+o*N+E*I,L=i*d+u*N+c*I,x=a*d+s*N+_*I,P=r*S+o*M+E*m,v=i*S+u*M+c*m,F=a*S+s*M+_*m,B=r*y+o*O+E*p+l,D=i*y+u*O+c*p+T,z=a*y+s*O+_*p+R;return n[0]=C,n[1]=U,n[2]=g,n[3]=0,n[4]=w,n[5]=L,n[6]=x,n[7]=0,n[8]=P,n[9]=v,n[10]=F,n[11]=0,n[12]=B,n[13]=D,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],E=e[8],c=e[9],_=e[10],l=t[0],T=t[1],R=t[2],f=t[3],A=t[4],h=t[5],d=t[6],N=t[7],I=t[8],S=r*l+o*T+E*R,M=i*l+u*T+c*R,m=a*l+s*T+_*R,y=r*f+o*A+E*h,O=i*f+u*A+c*h,p=a*f+s*A+_*h,C=r*d+o*N+E*I,U=i*d+u*N+c*I,g=a*d+s*N+_*I;return n[0]=S,n[1]=M,n[2]=m,n[3]=0,n[4]=y,n[5]=O,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=g,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var A=new e;c.multiplyByUniformScale=function(e,t,n){return A.x=t,A.y=t,A.z=t,c.multiplyByScale(e,A,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,E=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=E,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new s,d=new s,N=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(s.equalsEpsilon(c.getRotation(e,h),d,u.EPSILON7)&&t.equals(c.getRow(e,3,N),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],l=e[5],T=e[9],R=e[13],f=e[2],A=e[6],S=e[10],M=e[14],m=e[3],y=e[7],O=e[11],p=e[15],C=S*p,U=M*O,g=A*p,w=M*y,L=A*O,x=S*y,P=f*p,v=M*m,F=f*O,B=S*m,D=f*y,z=A*m,G=C*l+w*T+L*R-(U*l+g*T+x*R),b=U*_+P*T+B*R-(C*_+v*T+F*R),V=g*_+v*l+D*R-(w*_+P*l+z*R),X=x*_+F*l+z*T-(L*_+B*l+D*T),H=U*i+g*a+x*o-(C*i+w*a+L*o),q=C*r+v*a+F*o-(U*r+P*a+B*o),W=w*r+P*i+z*o-(g*r+v*i+D*o),Y=L*r+B*i+D*a-(x*r+F*i+z*a);C=a*R,U=o*T,g=i*R,w=o*l,L=i*T,x=a*l,P=r*R,v=o*_,F=r*T,B=a*_,D=r*l,z=i*_;var k=C*y+w*O+L*p-(U*y+g*O+x*p),K=U*m+P*O+B*p-(C*m+v*O+F*p),j=g*m+v*y+D*p-(w*m+P*y+z*p),Z=x*m+F*y+z*O-(L*m+B*y+D*O),Q=g*S+x*M+U*A-(L*M+C*A+w*S),J=F*M+C*f+v*S-(P*S+B*M+U*f),$=P*A+z*M+w*f-(D*M+g*f+v*A),ee=D*S+L*f+B*A-(F*A+z*S+x*f),te=r*G+i*b+a*V+o*X;if(Math.abs(te)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=V*te,n[3]=X*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=j*te,n[11]=Z*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],E=e[9],c=e[10],_=e[12],l=e[13],T=e[14],R=-n*_-r*l-i*T,f=-a*_-o*l-u*T,A=-s*_-E*l-c*T;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=E,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=R,t[13]=f,t[14]=A,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,E=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,l=e.length;_<l;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),E=Math.min(E,T.latitude),c=Math.max(c,T.latitude);var R=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,R),o=Math.max(o,R)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=E,t.east=i,t.north=c,t):new s(n,E,i,c)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,E=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,T=-Number.MAX_VALUE,R=0,f=e.length;R<f;R++){var A=t.cartesianToCartographic(e[R]);o=Math.min(o,A.longitude),E=Math.max(E,A.longitude),l=Math.min(l,A.latitude),T=Math.max(T,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return E-o>_-c&&(o=c,E=_,E>u.PI&&(E-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=E,i.north=T,i):new s(o,l,E,T)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,E=t.west;i<a&&o>0?i+=u.TWO_PI:o<E&&i>0&&(o+=u.TWO_PI),i<a&&E<0?E+=u.TWO_PI:o<E&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,E)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var l=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(l>=T))return r(n)?(n.west=c,n.south=l,n.east=_,n.north=T,n):new s(c,l,_,T)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,E=t.west;i<a&&o>0?i+=u.TWO_PI:o<E&&i>0&&(o+=u.TWO_PI),i<a&&E<0?E+=u.TWO_PI:o<E&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,E)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var E=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,l=e.south,T=e.east,R=e.west,f=E;f.height=i,f.longitude=R,f.latitude=_,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=l,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:l>0?l:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,s.contains(e,f)&&(o[c]=t.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++),o.length=c,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,E,c,_){"use strict";function l(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var T=new e,R=new e,f=new e,A=new e,h=new e,d=new e,N=new e,I=new e,S=new e,M=new e,m=new e,y=new e;l.fromPoints=function(t,n){if(i(n)||(n=new l),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],N),o=e.clone(a,T),u=e.clone(a,R),s=e.clone(a,f),E=e.clone(a,A),c=e.clone(a,h),_=e.clone(a,d),O=t.length;for(r=1;r<O;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>E.x&&e.clone(a,E),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<s.z&&e.clone(a,s),U>_.z&&e.clone(a,_)}var g=e.magnitudeSquared(e.subtract(E,o,I)),w=e.magnitudeSquared(e.subtract(c,u,I)),L=e.magnitudeSquared(e.subtract(_,s,I)),x=o,P=E,v=g;w>v&&(v=w,x=u,P=c),L>v&&(v=L,x=s,P=_);var F=S;F.x=.5*(x.x+P.x),F.y=.5*(x.y+P.y),F.z=.5*(x.z+P.z);var B=e.magnitudeSquared(e.subtract(P,F,I)),D=Math.sqrt(B),z=M;z.x=o.x,z.y=u.y,z.z=s.z;var G=m;G.x=E.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,I),.5,y),V=0;for(r=0;r<O;r++){e.clone(t[r],a);var X=e.magnitude(e.subtract(a,b,I));X>V&&(V=X);var H=e.magnitudeSquared(e.subtract(a,F,I));if(H>B){var q=Math.sqrt(H);D=.5*(D+q),B=D*D;var W=q-D;F.x=(D*F.x+W*a.x)/q,F.y=(D*F.y+W*a.y)/q,F.z=(D*F.z+W*a.z)/q}}return D<V?(e.clone(F,n.center),n.radius=D):(e.clone(b,n.center),n.radius=V),n};var O=new o,p=new e,C=new e,U=new t,g=new t;l.fromRectangle2D=function(e,t,n){return l.fromRectangleWithHeights2D(e,t,0,0,n)},l.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new l),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),_.southwest(t,U),U.height=a,_.northeast(t,g),g.height=o;var s=n.project(U,p),E=n.project(g,C),c=E.x-s.x,T=E.y-s.y,R=E.z-s.z;u.radius=.5*Math.sqrt(c*c+T*T+R*R);var f=u.center;return f.x=s.x+.5*c,f.y=s.y+.5*T,f.z=s.z+.5*R,u};var w=[];l.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new l),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=_.subsample(t,n,o,w);return l.fromPoints(s,u)},l.fromVertices=function(t,n,a,o){if(i(o)||(o=new l),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=N;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,E=e.clone(u,T),c=e.clone(u,R),_=e.clone(u,f),O=e.clone(u,A),p=e.clone(u,h),C=e.clone(u,d),U=t.length;for(s=0;s<U;s+=a){var g=t[s]+n.x,w=t[s+1]+n.y,L=t[s+2]+n.z;u.x=g,u.y=w,u.z=L,g<E.x&&e.clone(u,E),g>O.x&&e.clone(u,O),w<c.y&&e.clone(u,c),w>p.y&&e.clone(u,p),L<_.z&&e.clone(u,_),L>C.z&&e.clone(u,C)}var x=e.magnitudeSquared(e.subtract(O,E,I)),P=e.magnitudeSquared(e.subtract(p,c,I)),v=e.magnitudeSquared(e.subtract(C,_,I)),F=E,B=O,D=x;P>D&&(D=P,F=c,B=p),v>D&&(D=v,F=_,B=C);var z=S;z.x=.5*(F.x+B.x),z.y=.5*(F.y+B.y),z.z=.5*(F.z+B.z);var G=e.magnitudeSquared(e.subtract(B,z,I)),b=Math.sqrt(G),V=M;V.x=E.x,V.y=c.y,V.z=_.z;var X=m;X.x=O.x,X.y=p.y,X.z=C.z;var H=e.multiplyByScalar(e.add(V,X,I),.5,y),q=0;for(s=0;s<U;s+=a){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var W=e.magnitude(e.subtract(u,H,I));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<q?(e.clone(z,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},l.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new l),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=N;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,T),s=e.clone(a,R),E=e.clone(a,f),c=e.clone(a,A),_=e.clone(a,h),O=e.clone(a,d),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],g=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=g,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<s.y&&e.clone(a,s),U>_.y&&e.clone(a,_),g<E.z&&e.clone(a,E),g>O.z&&e.clone(a,O)}var w=e.magnitudeSquared(e.subtract(c,u,I)),L=e.magnitudeSquared(e.subtract(_,s,I)),x=e.magnitudeSquared(e.subtract(O,E,I)),P=u,v=c,F=w;L>F&&(F=L,P=s,v=_),x>F&&(F=x,P=E,v=O);var B=S;B.x=.5*(P.x+v.x),B.y=.5*(P.y+v.y),B.z=.5*(P.z+v.z);var D=e.magnitudeSquared(e.subtract(v,B,I)),z=Math.sqrt(D),G=M;G.x=u.x,G.y=s.y,G.z=E.z;var b=m;b.x=c.x,b.y=_.y,b.z=O.z;var V=e.multiplyByScalar(e.add(G,b,I),.5,y),X=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(a,V,I));H>X&&(X=H);var q=e.magnitudeSquared(e.subtract(a,B,I));if(q>D){var W=Math.sqrt(q);z=.5*(z+W),D=z*z;var Y=W-z;B.x=(z*B.x+Y*a.x)/W,B.y=(z*B.y+Y*a.y)/W,B.z=(z*B.z+Y*a.z)/W}}return z<X?(e.clone(B,r.center),r.radius=z):(e.clone(V,r.center),r.radius=X),r},l.fromCornerPoints=function(t,n,r){i(r)||(r=new l);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},l.fromEllipsoid=function(t,n){return i(n)||(n=new l),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var L=new e;l.fromBoundingSpheres=function(t,n){if(i(n)||(n=new l),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return l.clone(t[0],n);if(2===r)return l.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=l.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var E=t[a];s=Math.max(s,e.distance(u,E.center,L)+E.radius)}return n.radius=s,n};var x=new e,P=new e,v=new e;l.fromOrientedBoundingBox=function(t,n){i(n)||(n=new l);var r=t.halfAxes,a=E.getColumn(r,0,x),o=E.getColumn(r,1,P),u=E.getColumn(r,2,v);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},l.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new l(t.center,t.radius)},l.packedLength=4,l.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},l.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new l);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var F=new e,B=new e;l.union=function(t,n,r){i(r)||(r=new l);var a=t.center,o=t.radius,u=n.center,s=n.radius,E=e.subtract(u,a,F),c=e.magnitude(E);if(o>=c+s)return t.clone(r),r;if(s>=c+o)return n.clone(r),r;var _=.5*(o+c+s),T=e.multiplyByScalar(E,(-o+_)/c,B);return e.add(T,a,T),e.clone(T,r.center),r.radius=_,r};var D=new e;l.expand=function(t,n,r){r=l.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,D));return i>r.radius&&(r.radius=i),r},l.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},l.transform=function(e,t,n){return i(n)||(n=new l),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;l.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},l.transformWithoutScale=function(e,t,n){return i(n)||(n=new l),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;l.computePlaneDistances=function(t,n,r,a){i(a)||(a=new s);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,V=new e,X=new e,H=new e,q=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return l.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,b),E=e.cross(e.UNIT_Z,s,V);e.normalize(E,E);var c=e.cross(s,E,X);e.normalize(c,c),e.multiplyByScalar(s,u,s),e.multiplyByScalar(c,u,c),e.multiplyByScalar(E,u,E);var _=e.negate(c,q),T=e.negate(E,H),R=Y,f=R[0];e.add(s,c,f),e.add(f,E,f),f=R[1],e.add(s,c,f),e.add(f,T,f),f=R[2],e.add(s,_,f),e.add(f,T,f),f=R[3],e.add(s,_,f),e.add(f,E,f),e.negate(s,s),f=R[4],e.add(s,c,f),e.add(f,E,f),f=R[5],e.add(s,c,f),e.add(f,T,f),f=R[6],e.add(s,_,f),e.add(f,T,f),f=R[7],e.add(s,_,f),e.add(f,E,f);for(var A=R.length,h=0;h<A;++h){var d=R[h];e.add(o,d,d);var N=a.cartesianToCartographic(d,W);n.project(N,d)}i=l.fromPoints(R,i),o=i.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,i},l.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},l.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},l.prototype.intersectPlane=function(e){return l.intersectPlane(this,e)},l.prototype.distanceSquaredTo=function(e){return l.distanceSquaredTo(this,e)},l.prototype.computePlaneDistances=function(e,t,n){return l.computePlaneDistances(this,e,t,n)},l.prototype.isOccluded=function(e){return l.isOccluded(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.prototype.clone=function(e){return l.clone(this,e)},l}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!l())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(m)&&(m=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(m=!0,y=r(e[1]))}return m}function u(){return o()&&y}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(O=!0,p=r(e[1]),p.isNightly=!!e[2])}return O}function E(){return s()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function l(){if(!t(g)){g=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(g=!0,w=r(e[1]))}return g}function T(){return l()&&w}function R(){if(!t(L)){L=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,x=r(e[1]))}return L}function f(){return t(P)||(P=/Windows/i.test(I.appVersion)),P}function A(){return R()&&x}function h(){return t(v)||(v="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),v}function d(){if(!t(B)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;B=t(n)&&""!==n,B&&(F=n)}return B}function N(){return d()?F:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,m,y,O,p,C,U,g,w,L,x,P,v,F,B,D={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:c,internetExplorerVersion:_,isEdge:l,edgeVersion:T,isFirefox:R,firefoxVersion:A,isWindows:f,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:d,imageRenderingValue:N};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var E=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);E=e.normalize(t,E);var u=E.x*o,c=E.y*o,_=E.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=c,i.z=_,i.w=l,i):new s(u,c,_,l)};var c=[1,2,0],_=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,E,l=e[u.COLUMN0ROW0],T=e[u.COLUMN1ROW1],R=e[u.COLUMN2ROW2],f=l+T+R;if(f>0)n=Math.sqrt(f+1),E=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var A=c,h=0;T>l&&(h=1),R>l&&R>T&&(h=2);var d=A[h],N=A[d];n=Math.sqrt(e[u.getElementIndex(h,h)]-e[u.getElementIndex(d,d)]-e[u.getElementIndex(N,N)]+1);var I=_;I[h]=.5*n,n=.5/n,E=(e[u.getElementIndex(N,d)]-e[u.getElementIndex(d,N)])*n,I[d]=(e[u.getElementIndex(d,h)]+e[u.getElementIndex(h,d)])*n,I[N]=(e[u.getElementIndex(N,h)]+e[u.getElementIndex(h,N)])*n,i=-I[0],a=-I[1],o=-I[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=E,t):new s(i,a,o,E)};var l=new s,T=new s,R=new s,f=new s;s.fromHeadingPitchRoll=function(t,n){return f=s.fromAxisAngle(e.UNIT_X,t.roll,l),R=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(R,f,R),T=s.fromAxisAngle(e.UNIT_Z,-t.heading,l),s.multiply(T,n,n)};var A=new e,h=new e,d=new s,N=new s,I=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,I),s.conjugate(I,I);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),d),s.multiply(d,I,d),d.w<0&&s.negate(d,d),s.computeAxis(d,A);var u=s.computeAngle(d);r[o]=A.x*u,r[o+1]=A.y*u,r[o+2]=A.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,h);var u=e.magnitude(h);return s.unpack(n,4*a,N),0===u?s.clone(s.IDENTITY,d):s.fromAxisAngle(h,u,d),s.multiply(d,N,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,E=t.z,c=t.w,_=o*u+r*c+i*E-a*s,l=o*s-r*E+i*c+a*u,T=o*E+r*s-i*u+a*c,R=o*c-r*u-i*s-a*E;return n.x=_,n.y=l,n.z=T,n.w=R,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var S=new s;s.lerp=function(e,t,n,r){return S=s.multiplyByScalar(t,n,S),r=s.multiplyByScalar(e,1-n,r),s.add(S,r,r)};var M=new s,m=new s,y=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=M=s.negate(t,M)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return m=s.multiplyByScalar(e,Math.sin((1-n)*u),m),y=s.multiplyByScalar(a,Math.sin(n*u),y),r=s.add(m,y,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,p=new e,C=new s,U=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,C);s.multiply(a,r,U);var o=s.log(U,O);s.multiply(a,t,U);var u=s.log(U,p);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,C),s.multiply(n,C,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,C),u=s.slerp(n,r,i,U);return s.slerp(o,u,2*i*(1-i),a)};for(var g=new s,w=1.9011074535173003,L=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],v=i.supportsTypedArrays()?new Float32Array(8):[],F=0;F<7;++F){var B=F+1,D=2*B+1;L[F]=1/(B*D),x[F]=B/D}return L[7]=w/136,x[7]=8*w/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,E=n*n,c=u*u,_=7;_>=0;--_)P[_]=(L[_]*E-x[_])*o,v[_]=(L[_]*c-x[_])*o;var l=i*n*(1+P[0]*(1+P[1]*(1+P[2]*(1+P[3]*(1+P[4]*(1+P[5]*(1+P[6]*(1+P[7])))))))),T=u*(1+v[0]*(1+v[1]*(1+v[2]*(1+v[3]*(1+v[4]*(1+v[5]*(1+v[6]*(1+v[7])))))))),R=s.multiplyByScalar(e,T,g);return s.multiplyByScalar(t,l,r),s.add(R,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,C),u=s.fastSlerp(n,r,i,U);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,n,r){"use strict";function i(t,i,a,c,_,l,T,R,f,A){var h=t+i;e.multiplyByScalar(c,Math.cos(h),o),e.multiplyByScalar(a,Math.sin(h),u),e.add(o,u,o);var d=Math.cos(t);d*=d;var N=Math.sin(t);N*=N;var I=l/Math.sqrt(T*d+_*N),S=I/R;return r.fromAxisAngle(o,S,s),n.fromQuaternion(s,E),n.multiplyByVector(E,f,A),e.normalize(A,A),e.multiplyByScalar(A,R,A),A}var a={},o=new e,u=new e,s=new r,E=new n,c=new e,_=new e,l=new e,T=new e;a.raisePositionsToHeight=function(t,n,r){for(var i=n.ellipsoid,a=n.height,o=n.extrudedHeight,u=r?t.length/3*2:t.length/3,s=new Float64Array(3*u),E=t.length,R=r?E:0,f=0;f<E;f+=3){var A=f+1,h=f+2,d=e.fromArray(t,f,c);i.scaleToGeodeticSurface(d,d);var N=e.clone(d,_),I=i.geodeticSurfaceNormal(d,T),S=e.multiplyByScalar(I,a,l);e.add(d,S,d),r&&(e.multiplyByScalar(I,o,S),e.add(N,S,N),s[f+R]=N.x,s[A+R]=N.y,s[h+R]=N.z),s[f]=d.x,s[A]=d.y,s[h]=d.z}return s};var R=new e,f=new e,A=new e;return a.computeEllipsePositions=function(n,r,a){var o=n.semiMinorAxis,u=n.semiMajorAxis,s=n.rotation,E=n.center,T=8*n.granularity,h=o*o,d=u*u,N=u*o,I=e.magnitude(E),S=e.normalize(E,R),M=e.cross(e.UNIT_Z,E,f);M=e.normalize(M,M);var m=e.cross(S,M,A),y=1+Math.ceil(t.PI_OVER_TWO/T),O=t.PI_OVER_TWO/(y-1),p=t.PI_OVER_TWO-y*O;p<0&&(y-=Math.ceil(Math.abs(p)/O));var C,U,g,w,L,x=y*(y+2)*2,P=r?new Array(3*x):void 0,v=0,F=c,B=_,D=4*y*3,z=D-1,G=0,b=a?new Array(D):void 0;for(p=t.PI_OVER_TWO,F=i(p,s,m,M,h,N,d,I,S,F),r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x),p=t.PI_OVER_TWO-O,C=1;C<y+1;++C){if(F=i(p,s,m,M,h,N,d,I,S,F),B=i(Math.PI-p,s,m,M,h,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,g=2*C+2,U=1;U<g-1;++U)w=U/(g-1),L=e.lerp(F,B,w,l),P[v++]=L.x,P[v++]=L.y,P[v++]=L.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z),p=t.PI_OVER_TWO-(C+1)*O}for(C=y;C>1;--C){if(p=t.PI_OVER_TWO-(C-1)*O,F=i(-p,s,m,M,h,N,d,I,S,F),B=i(p+Math.PI,s,m,M,h,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,g=2*(C-1)+2,U=1;U<g-1;++U)w=U/(g-1),L=e.lerp(F,B,w,l),P[v++]=L.x,P[v++]=L.y,P[v++]=L.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z)}p=t.PI_OVER_TWO,F=i(-p,s,m,M,h,N,d,I,S,F);var V={};return r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,V.positions=P,V.numPts=y),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,V.outerPositions=b),V},a}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipseOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,s,E,c,_,l,T){"use strict";function R(r){var i=r.center;d=t.multiplyByScalar(r.ellipsoid.geodeticSurfaceNormal(i,d),r.height,d),d=t.add(i,d,d);for(var a=new e(d,r.semiMajorAxis),u=o.computeEllipsePositions(r,!1,!0).outerPositions,s=new c({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(u,r,!1)})}),l=u.length/3,T=_.createTypedArray(l,2*l),R=0,f=0;f<l;++f)T[R++]=f,T[R++]=(f+1)%l;return{boundingSphere:a,attributes:s,indices:T}}function f(i){var a=i.center,u=i.ellipsoid,s=i.semiMajorAxis,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,h),i.height,h);N.center=t.add(a,T,N.center),N.radius=s,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,T),i.extrudedHeight,T),I.center=t.add(a,T,I.center),I.radius=s;var R=o.computeEllipsePositions(i,!1,!0).outerPositions,f=new c({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(R,i,!0)})});R=f.position.values;var A=e.union(N,I),d=R.length/3,S=r(i.numberOfVerticalLines,16);S=l.clamp(S,0,d/2);var M=_.createTypedArray(d,2*d+2*S);d/=2;var m,y=0;for(m=0;m<d;++m)M[y++]=m,M[y++]=(m+1)%d,M[y++]=m+d,M[y++]=(m+1)%d+d;var O;if(S>0){var p=Math.min(S,d);O=Math.round(d/p);var C=Math.min(O*S,d);for(m=0;m<C;m+=O)M[y++]=m,M[y++]=m+d}return{boundingSphere:A,attributes:f,indices:M}}function A(e){e=r(e,r.EMPTY_OBJECT);var n=e.center,a=r(e.ellipsoid,u.WGS84),o=e.semiMajorAxis,s=e.semiMinorAxis,E=r(e.granularity,l.RADIANS_PER_DEGREE),c=r(e.height,0),_=e.extrudedHeight,T=i(_)&&Math.abs(c-_)>1;this._center=t.clone(n),this._semiMajorAxis=o,this._semiMinorAxis=s,this._ellipsoid=u.clone(a),this._rotation=r(e.rotation,0),this._height=c,this._granularity=E,this._extrudedHeight=_,this._extrude=T,this._numberOfVerticalLines=Math.max(r(e.numberOfVerticalLines,16),0),this._workerName="createEllipseOutlineGeometry"}var h=new t,d=new t,N=new e,I=new e;A.packedLength=t.packedLength+u.packedLength+9,A.pack=function(e,n,a){return a=r(a,0),t.pack(e._center,n,a),a+=t.packedLength,u.pack(e._ellipsoid,n,a),a+=u.packedLength,n[a++]=e._semiMajorAxis,n[a++]=e._semiMinorAxis,n[a++]=e._rotation,n[a++]=e._height,n[a++]=e._granularity,n[a++]=i(e._extrudedHeight)?1:0,n[a++]=r(e._extrudedHeight,0),n[a++]=e._extrude?1:0,n[a]=e._numberOfVerticalLines,n};var S=new t,M=new u,m={center:S,ellipsoid:M,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,numberOfVerticalLines:void 0};return A.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,S);n+=t.packedLength;var s=u.unpack(e,n,M);n+=u.packedLength;var E=e[n++],c=e[n++],_=e[n++],l=e[n++],T=e[n++],R=e[n++],f=e[n++],h=1===e[n++],d=e[n];return i(a)?(a._center=t.clone(o,a._center),a._ellipsoid=u.clone(s,a._ellipsoid),a._semiMajorAxis=E,a._semiMinorAxis=c,a._rotation=_,a._height=l,a._granularity=T,a._extrudedHeight=R?f:void 0,a._extrude=h,a._numberOfVerticalLines=d,a):(m.height=l,m.extrudedHeight=R?f:void 0,m.granularity=T,m.rotation=_,m.semiMajorAxis=E,m.semiMinorAxis=c,m.numberOfVerticalLines=d,new A(m))},A.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,n={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height, -extrudedHeight:e._extrudedHeight,granularity:e._granularity,numberOfVerticalLines:e._numberOfVerticalLines};return e._extrude?(n.extrudedHeight=Math.min(e._extrudedHeight,e._height),n.height=Math.max(e._extrudedHeight,e._height),t=f(n)):t=R(n),new s({attributes:t.attributes,indices:t.indices,primitiveType:T.LINES,boundingSphere:t.boundingSphere})}},A}),define("Core/CircleOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipseOutlineGeometry","./Ellipsoid"],function(e,t,n,r,i,a){"use strict";function o(e){e=n(e,n.EMPTY_OBJECT);var t=e.radius,r={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,numberOfVerticalLines:e.numberOfVerticalLines};this._ellipseGeometry=new i(r),this._workerName="createCircleOutlineGeometry"}o.packedLength=i.packedLength,o.pack=function(e,t,n){return i.pack(e._ellipseGeometry,t,n)};var u=new i({center:new e,semiMajorAxis:1,semiMinorAxis:1}),s={center:new e,radius:void 0,ellipsoid:a.clone(a.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,numberOfVerticalLines:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0};return o.unpack=function(t,n,E){var c=i.unpack(t,n,u);return s.center=e.clone(c._center,s.center),s.ellipsoid=a.clone(c._ellipsoid,s.ellipsoid),s.height=c._height,s.extrudedHeight=c._extrudedHeight,s.granularity=c._granularity,s.numberOfVerticalLines=c._numberOfVerticalLines,r(E)?(s.semiMajorAxis=c._semiMajorAxis,s.semiMinorAxis=c._semiMinorAxis,E._ellipseGeometry=new i(s),E):(s.radius=c._semiMajorAxis,new o(s))},o.createGeometry=function(e){return i.createGeometry(e._ellipseGeometry)},o}),define("Workers/createCircleOutlineGeometry",["../Core/Cartesian3","../Core/CircleOutlineGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,n,r){"use strict";function i(i,a){return n(a)&&(i=t.unpack(i,a)),i._ellipseGeometry._center=e.clone(i._ellipseGeometry._center),i._ellipseGeometry._ellipsoid=r.clone(i._ellipseGeometry._ellipsoid),t.createGeometry(i)}return i})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,E),o.normalize(t,c);var n=o.dot(E,c),r=o.magnitude(o.cross(E,c,E));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,E=i*s-a*u,c=a*o-r*s,_=r*u-i*o;return n.x=E,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var l=new o,T=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:R,E=Math.cos(r);l.x=E*Math.cos(e),l.y=E*Math.sin(e),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,T);var c=Math.sqrt(o.dot(l,T));return T=o.divideByScalar(T,c,T),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(T,l,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],E=a/2;r[E]=o.fromDegrees(u,s,0,t,r[E])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],E=a/2;r[E]=o.fromRadians(u,s,0,t,r[E])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],E=e[a+2],c=a/3;r[c]=o.fromDegrees(u,s,E,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],E=e[a+2],c=a/3;r[c]=o.fromRadians(u,s,E,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,E){var c=n.x,_=n.y,l=n.z,T=i.x,R=i.y,f=i.z,h=c*c*T*T,A=_*_*R*R,d=l*l*f*f,N=h+A+d,I=Math.sqrt(1/N),S=e.multiplyByScalar(n,I,a);if(N<s)return isFinite(I)?e.clone(S,E):void 0;var M=u.x,m=u.y,y=u.z,O=o;O.x=S.x*M*2,O.y=S.y*m*2,O.z=S.z*y*2;var p,C,U,g,w,L,x,P,v,F,B,D=(1-I)*e.magnitude(n)/(.5*e.magnitude(O)),z=0;do{D-=z,U=1/(1+D*M),g=1/(1+D*m),w=1/(1+D*y),L=U*U,x=g*g,P=w*w,v=L*U,F=x*g,B=P*w,p=h*L+A*x+d*P-1,C=h*v*M+A*F*m+d*B*y;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(E)?(E.x=c*U,E.y=_*g,E.z=l*w,E):new e(c*U,_*g,l*w)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,E=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),l=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:l,h=r(n)?n._centerToleranceSquared:T,A=o(t,R,f,h,E);if(r(A)){var d=e.multiplyComponents(A,f,s);d=e.normalize(d,d);var N=e.subtract(t,A,c),I=Math.atan2(d.y,d.x),S=Math.asin(d.z),M=a.sign(e.dot(N,t))*e.magnitude(N);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,E){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),E=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=E,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var l=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=l,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var R=new e,f=new e,h=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,f);if(i(a)){var o=this.geodeticSurfaceNormal(a,R),u=e.subtract(n,a,h),E=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=E,r.latitude=c,r.height=_,r):new t(E,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return E(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,E){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(E,0)}function E(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(f[n],R[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(f[a],R[a])]);o>r&&(i=a,r=o)}var E=1,c=0,_=R[i],l=f[i];if(Math.abs(e[s.getElementIndex(l,_)])>n){var T,h=e[s.getElementIndex(l,l)],A=e[s.getElementIndex(_,_)],d=e[s.getElementIndex(l,_)],N=(h-A)/2/d;T=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),E=1/Math.sqrt(1+T*T),c=T*E}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(_,_)]=t[s.getElementIndex(l,l)]=E,t[s.getElementIndex(l,_)]=c,t[s.getElementIndex(_,l)]=-c,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,E=e.y*e.z,c=e.y*e.w,_=e.z*e.z,l=e.z*e.w,T=e.w*e.w,R=n-u-_+T,f=2*(i-l),h=2*(a+c),A=2*(i+l),d=-n+u-_+T,N=2*(E-o),I=2*(a-c),S=2*(E+o),M=-n-u+_+T;return r(t)?(t[0]=R,t[1]=A,t[2]=I,t[3]=f,t[4]=d,t[5]=S,t[6]=h,t[7]=N,t[8]=M,t):new s(R,f,h,A,d,N,I,S,M)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),E=Math.sin(e.roll),c=n*i,_=-a*u+E*o*i,l=E*u+a*o*i,T=n*u,R=a*i+E*o*u,f=-E*i+a*o*u,h=-o,A=E*n,d=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=h,t[3]=_,t[4]=R,t[5]=A,t[6]=l,t[7]=f,t[8]=d,t):new s(c,_,l,T,R,f,h,A,d)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var l=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],l)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],l)),n};var T=new e;s.getMaximumScale=function(t){return s.getScale(t,T),e.maximumComponent(T)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],E=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=E,n[7]=c,n[8]=_,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],E=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=E,t[8]=c,t};var R=[1,0,0],f=[2,2,1],h=new s,A=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),l=t.diagonal=s.clone(e,t.diagonal),T=n*E(l);a<10&&c(l)>T;)_(l,h),s.transpose(h,A),s.multiply(l,h,l),s.multiply(A,l,l),s.multiply(o,h,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],E=e[8];return t*(a*E-s*o)+i*(s*r-n*E)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],E=e[6],c=e[7],_=e[8],l=s.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=E*u-a*_,t[4]=n*_-E*i,t[5]=a*i-n*u,t[6]=a*c-E*o,t[7]=E*r-n*c,t[8]=n*o-a*r;var T=1/l;return s.multiplyByScalar(t,T,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,E){"use strict";function c(e,t,n,i,a,o,u,s,E,c,_,l,T,R,f,h){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(E,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(h,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,E=t.x*t.y,_=t.x*t.z,l=t.x*t.w,T=t.y*t.y,R=t.y*t.z,f=t.y*t.w,h=t.z*t.z,A=t.z*t.w,d=t.w*t.w,N=s-T-h+d,I=2*(E-A),S=2*(_+f),M=2*(E+A),m=-s+T-h+d,y=2*(R-l),O=2*(_-f),p=2*(R+l),C=-s-T+h+d;return r[0]=N*a,r[1]=M*a,r[2]=O*a,r[3]=0,r[4]=I*o,r[5]=m*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=y*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(s.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,l=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,l),l),e.normalize(e.cross(l,_,T),T);var u=l.x,s=l.y,E=l.z,R=_.x,f=_.y,h=_.z,A=T.x,d=T.y,N=T.z,I=r.x,S=r.y,M=r.z,m=u*-I+s*-S+E*-M,y=A*-I+d*-S+N*-M,O=R*I+f*S+h*M;return i(n)?(n[0]=u,n[1]=A,n[2]=-R,n[3]=0,n[4]=s,n[5]=d,n[6]=-f,n[7]=0,n[8]=E,n[9]=N,n[10]=-h,n[11]=0,n[12]=m,n[13]=y,n[14]=O,n[15]=1,n):new c(u,s,E,m,A,d,N,y,-R,-f,-h,O,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),E=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=E,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),E=1/(a-i),c=-(t+e)*u,_=-(r+n)*s,l=-(a+i)*E;return u*=2,s*=2,E*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=E,o[11]=0,o[12]=c,o[13]=_,o[14]=l,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),E=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=E,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),E=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=E,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var E=.5*u,c=.5*s,_=.5*(n-t),l=E,T=c,R=_,f=a+E,h=o+c,A=t+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=R,i[11]=0,i[12]=f,i[13]=h,i[14]=A,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var R=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],R)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],R)),n};var f=new e;c.getMaximumScale=function(t){return c.getScale(t,f),e.maximumComponent(f)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],E=e[6],c=e[7],_=e[8],l=e[9],T=e[10],R=e[11],f=e[12],h=e[13],A=e[14],d=e[15],N=t[0],I=t[1],S=t[2],M=t[3],m=t[4],y=t[5],O=t[6],p=t[7],C=t[8],U=t[9],g=t[10],w=t[11],L=t[12],x=t[13],P=t[14],v=t[15],F=r*N+u*I+_*S+f*M,B=i*N+s*I+l*S+h*M,D=a*N+E*I+T*S+A*M,z=o*N+c*I+R*S+d*M,G=r*m+u*y+_*O+f*p,b=i*m+s*y+l*O+h*p,V=a*m+E*y+T*O+A*p,X=o*m+c*y+R*O+d*p,H=r*C+u*U+_*g+f*w,q=i*C+s*U+l*g+h*w,W=a*C+E*U+T*g+A*w,Y=o*C+c*U+R*g+d*w,k=r*L+u*x+_*P+f*v,K=i*L+s*x+l*P+h*v,j=a*L+E*x+T*P+A*v,Z=o*L+c*x+R*P+d*v;return n[0]=F,n[1]=B,n[2]=D,n[3]=z,n[4]=G,n[5]=b,n[6]=V,n[7]=X,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=j,n[15]=Z,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],E=e[8],c=e[9],_=e[10],l=e[12],T=e[13],R=e[14],f=t[0],h=t[1],A=t[2],d=t[4],N=t[5],I=t[6],S=t[8],M=t[9],m=t[10],y=t[12],O=t[13],p=t[14],C=r*f+o*h+E*A,U=i*f+u*h+c*A,g=a*f+s*h+_*A,w=r*d+o*N+E*I,L=i*d+u*N+c*I,x=a*d+s*N+_*I,P=r*S+o*M+E*m,v=i*S+u*M+c*m,F=a*S+s*M+_*m,B=r*y+o*O+E*p+l,D=i*y+u*O+c*p+T,z=a*y+s*O+_*p+R;return n[0]=C,n[1]=U,n[2]=g,n[3]=0,n[4]=w,n[5]=L,n[6]=x,n[7]=0,n[8]=P,n[9]=v,n[10]=F,n[11]=0,n[12]=B,n[13]=D,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],E=e[8],c=e[9],_=e[10],l=t[0],T=t[1],R=t[2],f=t[3],h=t[4],A=t[5],d=t[6],N=t[7],I=t[8],S=r*l+o*T+E*R,M=i*l+u*T+c*R,m=a*l+s*T+_*R,y=r*f+o*h+E*A,O=i*f+u*h+c*A,p=a*f+s*h+_*A,C=r*d+o*N+E*I,U=i*d+u*N+c*I,g=a*d+s*N+_*I;return n[0]=S,n[1]=M,n[2]=m,n[3]=0,n[4]=y,n[5]=O,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=g,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var h=new e;c.multiplyByUniformScale=function(e,t,n){return h.x=t,h.y=t,h.z=t,c.multiplyByScale(e,h,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,E=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=E,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var A=new s,d=new s,N=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(s.equalsEpsilon(c.getRotation(e,A),d,u.EPSILON7)&&t.equals(c.getRow(e,3,N),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],l=e[5],T=e[9],R=e[13],f=e[2],h=e[6],S=e[10],M=e[14],m=e[3],y=e[7],O=e[11],p=e[15],C=S*p,U=M*O,g=h*p,w=M*y,L=h*O,x=S*y,P=f*p,v=M*m,F=f*O,B=S*m,D=f*y,z=h*m,G=C*l+w*T+L*R-(U*l+g*T+x*R),b=U*_+P*T+B*R-(C*_+v*T+F*R),V=g*_+v*l+D*R-(w*_+P*l+z*R),X=x*_+F*l+z*T-(L*_+B*l+D*T),H=U*i+g*a+x*o-(C*i+w*a+L*o),q=C*r+v*a+F*o-(U*r+P*a+B*o),W=w*r+P*i+z*o-(g*r+v*i+D*o),Y=L*r+B*i+D*a-(x*r+F*i+z*a);C=a*R,U=o*T,g=i*R,w=o*l,L=i*T,x=a*l,P=r*R,v=o*_,F=r*T,B=a*_,D=r*l,z=i*_;var k=C*y+w*O+L*p-(U*y+g*O+x*p),K=U*m+P*O+B*p-(C*m+v*O+F*p),j=g*m+v*y+D*p-(w*m+P*y+z*p),Z=x*m+F*y+z*O-(L*m+B*y+D*O),Q=g*S+x*M+U*h-(L*M+C*h+w*S),J=F*M+C*f+v*S-(P*S+B*M+U*f),$=P*h+z*M+w*f-(D*M+g*f+v*h),ee=D*S+L*f+B*h-(F*h+z*S+x*f),te=r*G+i*b+a*V+o*X;if(Math.abs(te)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=V*te,n[3]=X*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=j*te,n[11]=Z*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],E=e[9],c=e[10],_=e[12],l=e[13],T=e[14],R=-n*_-r*l-i*T,f=-a*_-o*l-u*T,h=-s*_-E*l-c*T;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=E,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=R,t[13]=f,t[14]=h,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,E=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,l=e.length;_<l;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),E=Math.min(E,T.latitude),c=Math.max(c,T.latitude);var R=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,R),o=Math.max(o,R)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=E,t.east=i,t.north=c,t):new s(n,E,i,c)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,E=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,T=-Number.MAX_VALUE,R=0,f=e.length;R<f;R++){var h=t.cartesianToCartographic(e[R]);o=Math.min(o,h.longitude),E=Math.max(E,h.longitude),l=Math.min(l,h.latitude),T=Math.max(T,h.latitude);var A=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;c=Math.min(c,A),_=Math.max(_,A)}return E-o>_-c&&(o=c,E=_,E>u.PI&&(E-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=E,i.north=T,i):new s(o,l,E,T)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,E=t.west;i<a&&o>0?i+=u.TWO_PI:o<E&&i>0&&(o+=u.TWO_PI),i<a&&E<0?E+=u.TWO_PI:o<E&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,E)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var l=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(l>=T))return r(n)?(n.west=c,n.south=l,n.east=_,n.north=T,n):new s(c,l,_,T)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,E=t.west;i<a&&o>0?i+=u.TWO_PI:o<E&&i>0&&(o+=u.TWO_PI),i<a&&E<0?E+=u.TWO_PI:o<E&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,E)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var E=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,l=e.south,T=e.east,R=e.west,f=E;f.height=i,f.longitude=R,f.latitude=_,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=l,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:l>0?l:0;for(var h=1;h<8;++h)f.longitude=-Math.PI+h*u.PI_OVER_TWO,s.contains(e,f)&&(o[c]=t.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++),o.length=c,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,E,c,_,l){"use strict";function T(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var R=new e,f=new e,h=new e,A=new e,d=new e,N=new e,I=new e,S=new e,M=new e,m=new e,y=new e,O=new e,p=4/3*n.PI;T.fromPoints=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],I),o=e.clone(i,R),u=e.clone(i,f),s=e.clone(i,h),E=e.clone(i,A),c=e.clone(i,d),_=e.clone(i,N),l=t.length;for(r=1;r<l;r++){e.clone(t[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&e.clone(i,o),p>E.x&&e.clone(i,E),C<u.y&&e.clone(i,u),C>c.y&&e.clone(i,c),U<s.z&&e.clone(i,s),U>_.z&&e.clone(i,_)}var g=e.magnitudeSquared(e.subtract(E,o,S)),w=e.magnitudeSquared(e.subtract(c,u,S)),L=e.magnitudeSquared(e.subtract(_,s,S)),x=o,P=E,v=g;w>v&&(v=w,x=u,P=c),L>v&&(v=L,x=s,P=_);var F=M;F.x=.5*(x.x+P.x),F.y=.5*(x.y+P.y),F.z=.5*(x.z+P.z);var B=e.magnitudeSquared(e.subtract(P,F,S)),D=Math.sqrt(B),z=m;z.x=o.x,z.y=u.y,z.z=s.z;var G=y;G.x=E.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,S),.5,O),V=0;for(r=0;r<l;r++){e.clone(t[r],i);var X=e.magnitude(e.subtract(i,b,S));X>V&&(V=X);var H=e.magnitudeSquared(e.subtract(i,F,S));if(H>B){var q=Math.sqrt(H);D=.5*(D+q),B=D*D;var W=q-D;F.x=(D*F.x+W*i.x)/q,F.y=(D*F.y+W*i.y)/q,F.z=(D*F.z+W*i.z)/q}}return D<V?(e.clone(F,n.center),n.radius=D):(e.clone(b,n.center),n.radius=V),n};var C=new u,U=new e,g=new e,w=new t,L=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,C),l.southwest(t,w),w.height=r,l.northeast(t,L),L.height=o;var s=n.project(w,U),E=n.project(L,g),c=E.x-s.x,_=E.y-s.y,R=E.z-s.z;u.radius=.5*Math.sqrt(c*c+_*_+R*R);var f=u.center;return f.x=s.x+.5*c,f.y=s.y+.5*_,f.z=s.z+.5*R,u};var x=[];T.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=l.subsample(t,n,r,x);return T.fromPoints(s,u)},T.fromVertices=function(t,n,r,o){if(a(o)||(o=new T),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=I;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,E=e.clone(u,R),c=e.clone(u,f),_=e.clone(u,h),l=e.clone(u,A),p=e.clone(u,d),C=e.clone(u,N),U=t.length;for(s=0;s<U;s+=r){var g=t[s]+n.x,w=t[s+1]+n.y,L=t[s+2]+n.z;u.x=g,u.y=w,u.z=L,g<E.x&&e.clone(u,E),g>l.x&&e.clone(u,l),w<c.y&&e.clone(u,c),w>p.y&&e.clone(u,p),L<_.z&&e.clone(u,_),L>C.z&&e.clone(u,C)}var x=e.magnitudeSquared(e.subtract(l,E,S)),P=e.magnitudeSquared(e.subtract(p,c,S)),v=e.magnitudeSquared(e.subtract(C,_,S)),F=E,B=l,D=x;P>D&&(D=P,F=c,B=p),v>D&&(D=v,F=_,B=C);var z=M;z.x=.5*(F.x+B.x),z.y=.5*(F.y+B.y),z.z=.5*(F.z+B.z);var G=e.magnitudeSquared(e.subtract(B,z,S)),b=Math.sqrt(G),V=m;V.x=E.x,V.y=c.y,V.z=_.z;var X=y;X.x=l.x,X.y=p.y,X.z=C.z;var H=e.multiplyByScalar(e.add(V,X,S),.5,O),q=0;for(s=0;s<U;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var W=e.magnitude(e.subtract(u,H,S));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<q?(e.clone(z,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},T.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new T),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=I;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,R),s=e.clone(i,f),E=e.clone(i,h),c=e.clone(i,A),_=e.clone(i,d),l=e.clone(i,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],g=t[o+2]+n[o+2];i.x=C,i.y=U,i.z=g,C<u.x&&e.clone(i,u),C>c.x&&e.clone(i,c),U<s.y&&e.clone(i,s),U>_.y&&e.clone(i,_),g<E.z&&e.clone(i,E),g>l.z&&e.clone(i,l)}var w=e.magnitudeSquared(e.subtract(c,u,S)),L=e.magnitudeSquared(e.subtract(_,s,S)),x=e.magnitudeSquared(e.subtract(l,E,S)),P=u,v=c,F=w;L>F&&(F=L,P=s,v=_),x>F&&(F=x,P=E,v=l);var B=M;B.x=.5*(P.x+v.x),B.y=.5*(P.y+v.y),B.z=.5*(P.z+v.z);var D=e.magnitudeSquared(e.subtract(v,B,S)),z=Math.sqrt(D),G=m;G.x=u.x,G.y=s.y,G.z=E.z;var b=y;b.x=c.x,b.y=_.y,b.z=l.z;var V=e.multiplyByScalar(e.add(G,b,S),.5,O),X=0;for(o=0;o<p;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(i,V,S));H>X&&(X=H);var q=e.magnitudeSquared(e.subtract(i,B,S));if(q>D){var W=Math.sqrt(q);z=.5*(z+W),D=z*z;var Y=W-z;B.x=(z*B.x+Y*i.x)/W,B.y=(z*B.y+Y*i.y)/W,B.z=(z*B.z+Y*i.z)/W}}return z<X?(e.clone(B,r.center),r.radius=z):(e.clone(V,r.center),r.radius=X),r},T.fromCornerPoints=function(t,n,r){a(r)||(r=new T);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},T.fromEllipsoid=function(t,n){return a(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var P=new e;T.fromBoundingSpheres=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=T.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var E=t[i];s=Math.max(s,e.distance(u,E.center,P)+E.radius)}return n.radius=s,n};var v=new e,F=new e,B=new e;T.fromOrientedBoundingBox=function(t,n){a(n)||(n=new T);var r=t.halfAxes,i=c.getColumn(r,0,v),o=c.getColumn(r,1,F),u=c.getColumn(r,2,B);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},T.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new T);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var D=new e,z=new e;T.union=function(t,n,r){a(r)||(r=new T);var i=t.center,o=t.radius,u=n.center,s=n.radius,E=e.subtract(u,i,D),c=e.magnitude(E);if(o>=c+s)return t.clone(r),r;if(s>=c+o)return n.clone(r),r;var _=.5*(o+c+s),l=e.multiplyByScalar(E,(-o+_)/c,z);return e.add(l,i,l),e.clone(l,r.center),r.radius=_,r};var G=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},T.transform=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=_.getMaximumScale(t)*e.radius,n};var b=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var V=new e;T.computePlaneDistances=function(t,n,r,i){a(i)||(i=new E);var o=e.subtract(t.center,n,V),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var X=new e,H=new e,q=new e,W=new e,Y=new e,k=new t,K=new Array(8),j=0;j<8;++j)K[j]=new e;var Z=new u;return T.projectTo2D=function(t,n,r){n=i(n,Z);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,X),E=e.cross(e.UNIT_Z,s,H);e.normalize(E,E);var c=e.cross(s,E,q);e.normalize(c,c),e.multiplyByScalar(s,u,s),e.multiplyByScalar(c,u,c),e.multiplyByScalar(E,u,E);var _=e.negate(c,Y),l=e.negate(E,W),R=K,f=R[0];e.add(s,c,f),e.add(f,E,f),f=R[1],e.add(s,c,f),e.add(f,l,f),f=R[2],e.add(s,_,f),e.add(f,l,f),f=R[3],e.add(s,_,f),e.add(f,E,f),e.negate(s,s),f=R[4],e.add(s,c,f),e.add(f,E,f),f=R[5],e.add(s,c,f),e.add(f,l,f),f=R[6],e.add(s,_,f),e.add(f,l,f),f=R[7],e.add(s,_,f),e.add(f,E,f);for(var h=R.length,A=0;A<h;++A){var d=R[A];e.add(o,d,d);var N=a.cartesianToCartographic(d,k);n.project(N,d)}r=T.fromPoints(R,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T.prototype.volume=function(){var e=this.radius;return p*e*e*e},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!l())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(m)&&(m=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(m=!0,y=r(e[1]))}return m}function u(){return o()&&y}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(O=!0, +p=r(e[1]),p.isNightly=!!e[2])}return O}function E(){return s()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function l(){if(!t(g)){g=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(g=!0,w=r(e[1]))}return g}function T(){return l()&&w}function R(){if(!t(L)){L=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,x=r(e[1]))}return L}function f(){return t(P)||(P=/Windows/i.test(I.appVersion)),P}function h(){return R()&&x}function A(){return t(v)||(v="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),v}function d(){if(!t(B)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;B=t(n)&&""!==n,B&&(F=n)}return B}function N(){return d()?F:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,m,y,O,p,C,U,g,w,L,x,P,v,F,B,D={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:c,internetExplorerVersion:_,isEdge:l,edgeVersion:T,isFirefox:R,firefoxVersion:h,isWindows:f,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:A,supportsImageRenderingPixelated:d,imageRenderingValue:N};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var E=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);E=e.normalize(t,E);var u=E.x*o,c=E.y*o,_=E.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=c,i.z=_,i.w=l,i):new s(u,c,_,l)};var c=[1,2,0],_=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,E,l=e[u.COLUMN0ROW0],T=e[u.COLUMN1ROW1],R=e[u.COLUMN2ROW2],f=l+T+R;if(f>0)n=Math.sqrt(f+1),E=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var h=c,A=0;T>l&&(A=1),R>l&&R>T&&(A=2);var d=h[A],N=h[d];n=Math.sqrt(e[u.getElementIndex(A,A)]-e[u.getElementIndex(d,d)]-e[u.getElementIndex(N,N)]+1);var I=_;I[A]=.5*n,n=.5/n,E=(e[u.getElementIndex(N,d)]-e[u.getElementIndex(d,N)])*n,I[d]=(e[u.getElementIndex(d,A)]+e[u.getElementIndex(A,d)])*n,I[N]=(e[u.getElementIndex(N,A)]+e[u.getElementIndex(A,N)])*n,i=-I[0],a=-I[1],o=-I[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=E,t):new s(i,a,o,E)};var l=new s,T=new s,R=new s,f=new s;s.fromHeadingPitchRoll=function(t,n){return f=s.fromAxisAngle(e.UNIT_X,t.roll,l),R=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(R,f,R),T=s.fromAxisAngle(e.UNIT_Z,-t.heading,l),s.multiply(T,n,n)};var h=new e,A=new e,d=new s,N=new s,I=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,I),s.conjugate(I,I);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),d),s.multiply(d,I,d),d.w<0&&s.negate(d,d),s.computeAxis(d,h);var u=s.computeAngle(d);r[o]=h.x*u,r[o+1]=h.y*u,r[o+2]=h.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,A);var u=e.magnitude(A);return s.unpack(n,4*a,N),0===u?s.clone(s.IDENTITY,d):s.fromAxisAngle(A,u,d),s.multiply(d,N,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,E=t.z,c=t.w,_=o*u+r*c+i*E-a*s,l=o*s-r*E+i*c+a*u,T=o*E+r*s-i*u+a*c,R=o*c-r*u-i*s-a*E;return n.x=_,n.y=l,n.z=T,n.w=R,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var S=new s;s.lerp=function(e,t,n,r){return S=s.multiplyByScalar(t,n,S),r=s.multiplyByScalar(e,1-n,r),s.add(S,r,r)};var M=new s,m=new s,y=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=M=s.negate(t,M)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return m=s.multiplyByScalar(e,Math.sin((1-n)*u),m),y=s.multiplyByScalar(a,Math.sin(n*u),y),r=s.add(m,y,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,p=new e,C=new s,U=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,C);s.multiply(a,r,U);var o=s.log(U,O);s.multiply(a,t,U);var u=s.log(U,p);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,C),s.multiply(n,C,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,C),u=s.slerp(n,r,i,U);return s.slerp(o,u,2*i*(1-i),a)};for(var g=new s,w=1.9011074535173003,L=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],v=i.supportsTypedArrays()?new Float32Array(8):[],F=0;F<7;++F){var B=F+1,D=2*B+1;L[F]=1/(B*D),x[F]=B/D}return L[7]=w/136,x[7]=8*w/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,E=n*n,c=u*u,_=7;_>=0;--_)P[_]=(L[_]*E-x[_])*o,v[_]=(L[_]*c-x[_])*o;var l=i*n*(1+P[0]*(1+P[1]*(1+P[2]*(1+P[3]*(1+P[4]*(1+P[5]*(1+P[6]*(1+P[7])))))))),T=u*(1+v[0]*(1+v[1]*(1+v[2]*(1+v[3]*(1+v[4]*(1+v[5]*(1+v[6]*(1+v[7])))))))),R=s.multiplyByScalar(e,T,g);return s.multiplyByScalar(t,l,r),s.add(R,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,C),u=s.fastSlerp(n,r,i,U);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,n,r){"use strict";function i(t,i,a,c,_,l,T,R,f,h){var A=t+i;e.multiplyByScalar(c,Math.cos(A),o),e.multiplyByScalar(a,Math.sin(A),u),e.add(o,u,o);var d=Math.cos(t);d*=d;var N=Math.sin(t);N*=N;var I=l/Math.sqrt(T*d+_*N),S=I/R;return r.fromAxisAngle(o,S,s),n.fromQuaternion(s,E),n.multiplyByVector(E,f,h),e.normalize(h,h),e.multiplyByScalar(h,R,h),h}var a={},o=new e,u=new e,s=new r,E=new n,c=new e,_=new e,l=new e,T=new e;a.raisePositionsToHeight=function(t,n,r){for(var i=n.ellipsoid,a=n.height,o=n.extrudedHeight,u=r?t.length/3*2:t.length/3,s=new Float64Array(3*u),E=t.length,R=r?E:0,f=0;f<E;f+=3){var h=f+1,A=f+2,d=e.fromArray(t,f,c);i.scaleToGeodeticSurface(d,d);var N=e.clone(d,_),I=i.geodeticSurfaceNormal(d,T),S=e.multiplyByScalar(I,a,l);e.add(d,S,d),r&&(e.multiplyByScalar(I,o,S),e.add(N,S,N),s[f+R]=N.x,s[h+R]=N.y,s[A+R]=N.z),s[f]=d.x,s[h]=d.y,s[A]=d.z}return s};var R=new e,f=new e,h=new e;return a.computeEllipsePositions=function(n,r,a){var o=n.semiMinorAxis,u=n.semiMajorAxis,s=n.rotation,E=n.center,T=8*n.granularity,A=o*o,d=u*u,N=u*o,I=e.magnitude(E),S=e.normalize(E,R),M=e.cross(e.UNIT_Z,E,f);M=e.normalize(M,M);var m=e.cross(S,M,h),y=1+Math.ceil(t.PI_OVER_TWO/T),O=t.PI_OVER_TWO/(y-1),p=t.PI_OVER_TWO-y*O;p<0&&(y-=Math.ceil(Math.abs(p)/O));var C,U,g,w,L,x=y*(y+2)*2,P=r?new Array(3*x):void 0,v=0,F=c,B=_,D=4*y*3,z=D-1,G=0,b=a?new Array(D):void 0;for(p=t.PI_OVER_TWO,F=i(p,s,m,M,A,N,d,I,S,F),r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x),p=t.PI_OVER_TWO-O,C=1;C<y+1;++C){if(F=i(p,s,m,M,A,N,d,I,S,F),B=i(Math.PI-p,s,m,M,A,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,g=2*C+2,U=1;U<g-1;++U)w=U/(g-1),L=e.lerp(F,B,w,l),P[v++]=L.x,P[v++]=L.y,P[v++]=L.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z),p=t.PI_OVER_TWO-(C+1)*O}for(C=y;C>1;--C){if(p=t.PI_OVER_TWO-(C-1)*O,F=i(-p,s,m,M,A,N,d,I,S,F),B=i(p+Math.PI,s,m,M,A,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,g=2*(C-1)+2,U=1;U<g-1;++U)w=U/(g-1),L=e.lerp(F,B,w,l),P[v++]=L.x,P[v++]=L.y,P[v++]=L.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z)}p=t.PI_OVER_TWO,F=i(-p,s,m,M,A,N,d,I,S,F);var V={};return r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,V.positions=P,V.numPts=y),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,V.outerPositions=b),V},a}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipseOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,s,E,c,_,l,T){"use strict";function R(r){var i=r.center;d=t.multiplyByScalar(r.ellipsoid.geodeticSurfaceNormal(i,d),r.height,d),d=t.add(i,d,d);for(var a=new e(d,r.semiMajorAxis),u=o.computeEllipsePositions(r,!1,!0).outerPositions,s=new c({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(u,r,!1)})}),l=u.length/3,T=_.createTypedArray(l,2*l),R=0,f=0;f<l;++f)T[R++]=f,T[R++]=(f+1)%l;return{boundingSphere:a,attributes:s,indices:T}}function f(i){var a=i.center,u=i.ellipsoid,s=i.semiMajorAxis,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,A),i.height,A);N.center=t.add(a,T,N.center),N.radius=s,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,T),i.extrudedHeight,T),I.center=t.add(a,T,I.center),I.radius=s;var R=o.computeEllipsePositions(i,!1,!0).outerPositions,f=new c({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(R,i,!0)})});R=f.position.values;var h=e.union(N,I),d=R.length/3,S=r(i.numberOfVerticalLines,16);S=l.clamp(S,0,d/2);var M=_.createTypedArray(d,2*d+2*S);d/=2;var m,y=0;for(m=0;m<d;++m)M[y++]=m,M[y++]=(m+1)%d,M[y++]=m+d,M[y++]=(m+1)%d+d;var O;if(S>0){var p=Math.min(S,d);O=Math.round(d/p);var C=Math.min(O*S,d);for(m=0;m<C;m+=O)M[y++]=m,M[y++]=m+d}return{boundingSphere:h,attributes:f,indices:M}}function h(e){e=r(e,r.EMPTY_OBJECT);var n=e.center,a=r(e.ellipsoid,u.WGS84),o=e.semiMajorAxis,s=e.semiMinorAxis,E=r(e.granularity,l.RADIANS_PER_DEGREE),c=r(e.height,0),_=e.extrudedHeight,T=i(_)&&Math.abs(c-_)>1;this._center=t.clone(n),this._semiMajorAxis=o,this._semiMinorAxis=s,this._ellipsoid=u.clone(a),this._rotation=r(e.rotation,0),this._height=c,this._granularity=E,this._extrudedHeight=_,this._extrude=T,this._numberOfVerticalLines=Math.max(r(e.numberOfVerticalLines,16),0),this._workerName="createEllipseOutlineGeometry"}var A=new t,d=new t,N=new e,I=new e;h.packedLength=t.packedLength+u.packedLength+9,h.pack=function(e,n,a){return a=r(a,0),t.pack(e._center,n,a),a+=t.packedLength,u.pack(e._ellipsoid,n,a),a+=u.packedLength,n[a++]=e._semiMajorAxis,n[a++]=e._semiMinorAxis,n[a++]=e._rotation,n[a++]=e._height,n[a++]=e._granularity,n[a++]=i(e._extrudedHeight)?1:0,n[a++]=r(e._extrudedHeight,0),n[a++]=e._extrude?1:0,n[a]=e._numberOfVerticalLines,n};var S=new t,M=new u,m={center:S,ellipsoid:M,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,numberOfVerticalLines:void 0};return h.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,S);n+=t.packedLength;var s=u.unpack(e,n,M);n+=u.packedLength;var E=e[n++],c=e[n++],_=e[n++],l=e[n++],T=e[n++],R=e[n++],f=e[n++],A=1===e[n++],d=e[n];return i(a)?(a._center=t.clone(o,a._center),a._ellipsoid=u.clone(s,a._ellipsoid),a._semiMajorAxis=E,a._semiMinorAxis=c,a._rotation=_,a._height=l,a._granularity=T,a._extrudedHeight=R?f:void 0,a._extrude=A,a._numberOfVerticalLines=d,a):(m.height=l,m.extrudedHeight=R?f:void 0,m.granularity=T,m.rotation=_,m.semiMajorAxis=E,m.semiMinorAxis=c,m.numberOfVerticalLines=d,new h(m))},h.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){ +e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,n={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,numberOfVerticalLines:e._numberOfVerticalLines};return e._extrude?(n.extrudedHeight=Math.min(e._extrudedHeight,e._height),n.height=Math.max(e._extrudedHeight,e._height),t=f(n)):t=R(n),new s({attributes:t.attributes,indices:t.indices,primitiveType:T.LINES,boundingSphere:t.boundingSphere})}},h}),define("Core/CircleOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipseOutlineGeometry","./Ellipsoid"],function(e,t,n,r,i,a){"use strict";function o(e){e=n(e,n.EMPTY_OBJECT);var t=e.radius,r={center:e.center,semiMajorAxis:t,semiMinorAxis:t,ellipsoid:e.ellipsoid,height:e.height,extrudedHeight:e.extrudedHeight,granularity:e.granularity,numberOfVerticalLines:e.numberOfVerticalLines};this._ellipseGeometry=new i(r),this._workerName="createCircleOutlineGeometry"}o.packedLength=i.packedLength,o.pack=function(e,t,n){return i.pack(e._ellipseGeometry,t,n)};var u=new i({center:new e,semiMajorAxis:1,semiMinorAxis:1}),s={center:new e,radius:void 0,ellipsoid:a.clone(a.UNIT_SPHERE),height:void 0,extrudedHeight:void 0,granularity:void 0,numberOfVerticalLines:void 0,semiMajorAxis:void 0,semiMinorAxis:void 0};return o.unpack=function(t,n,E){var c=i.unpack(t,n,u);return s.center=e.clone(c._center,s.center),s.ellipsoid=a.clone(c._ellipsoid,s.ellipsoid),s.height=c._height,s.extrudedHeight=c._extrudedHeight,s.granularity=c._granularity,s.numberOfVerticalLines=c._numberOfVerticalLines,r(E)?(s.semiMajorAxis=c._semiMajorAxis,s.semiMinorAxis=c._semiMinorAxis,E._ellipseGeometry=new i(s),E):(s.radius=c._semiMajorAxis,new o(s))},o.createGeometry=function(e){return i.createGeometry(e._ellipseGeometry)},o}),define("Workers/createCircleOutlineGeometry",["../Core/Cartesian3","../Core/CircleOutlineGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,n,r){"use strict";function i(i,a){return n(a)&&(i=t.unpack(i,a)),i._ellipseGeometry._center=e.clone(i._ellipseGeometry._center),i._ellipseGeometry._ellipsoid=r.clone(i._ellipseGeometry._ellipsoid),t.createGeometry(i)}return i})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorGeometry.js index df7281db..08e14f8d 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorGeometry.js @@ -222,9 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function a(e,r,a){if(n(e)){a=t(a,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,i));++u);if(u===o)return a&&r(e[0],e[e.length-1],i)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,i)||(l.push(c),s=c);return a&&l.length>1&&r(l[0],l[l.length-1],i)&&l.shift(),l}}var i=r.EPSILON10;return a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var d=new o,h=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);d.x=c*Math.cos(e),d.y=c*Math.sin(e),d.z=Math.sin(r),d=o.normalize(d,d),o.multiplyComponents(s,d,h);var l=Math.sqrt(o.dot(d,h));return h=o.divideByScalar(h,l,h),d=o.multiplyByScalar(d,a,d),n(u)||(u=new o),o.add(h,d,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,d=n.z,h=a.x,E=a.y,m=a.z,p=l*l*h*h,_=f*f*E*E,y=d*d*m*m,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var v=u.x,S=u.y,g=u.z,N=o;N.x=A.x*v*2,N.y=A.y*S*2,N.z=A.z*g*2;var O,I,w,M,x,C,P,D,U,L,F,b=(1-R)*e.magnitude(n)/(.5*e.magnitude(N)),B=0;do{b-=B,w=1/(1+b*v),M=1/(1+b*S),x=1/(1+b*g),C=w*w,P=M*M,D=x*x,U=C*w,L=P*M,F=D*x,O=p*C+_*P+y*D-1,I=p*U*v+_*L*S+y*F*g;B=O/(-2*I)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=d*x,c):new e(l*w,f*M,d*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),d=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:d,p=r(n)?n._centerToleranceSquared:h,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),v=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=v,a):new u(R,A,v)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var d=new e,h=new e;f.prototype.cartographicToCartesian=function(t,n){var r=d,i=h;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],d=m[a];if(Math.abs(e[s.getElementIndex(d,f)])>n){var h,p=e[s.getElementIndex(d,d)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(d,f)],T=(p-_)/2/y;h=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(d,d)]=c,t[s.getElementIndex(d,f)]=l,t[s.getElementIndex(f,d)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,d=e.z*e.w,h=e.w*e.w,E=n-u-f+h,m=2*(a-d),p=2*(i+l),_=2*(a+d),y=-n+u-f+h,T=2*(c-o),R=2*(i-l),A=2*(c+o),v=-n-u+f+h;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=v,t):new s(E,m,p,_,y,T,R,A,v)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,d=c*u+i*o*a,h=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,_=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=h,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=d,t[7]=m,t[8]=y,t):new s(l,f,d,h,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var d=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],d)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],d)),n};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),d=t.diagonal=s.clone(e,t.diagonal),h=n*c(d);i<10&&l(d)>h;)f(d,p),s.transpose(p,_),s.multiply(d,p,d),s.multiply(_,d,d),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],d=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var h=1/d;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){ -return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,d,h,E,m,p){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(h,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(d,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,d=t.x*t.w,h=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-h-p+y,R=2*(c-_),A=2*(f+m),v=2*(c+_),S=-s+h-p+y,g=2*(E-d),N=2*(f-m),O=2*(E+d),I=-s-h+p+y;return r[0]=T*i,r[1]=v*i,r[2]=N*i,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=O*o,r[7]=0,r[8]=A*u,r[9]=g*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,d=new e,h=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,d),d),e.normalize(e.cross(d,f,h),h);var u=d.x,s=d.y,c=d.z,E=f.x,m=f.y,p=f.z,_=h.x,y=h.y,T=h.z,R=r.x,A=r.y,v=r.z,S=u*-R+s*-A+c*-v,g=_*-R+y*-A+T*-v,N=E*R+m*A+p*v;return a(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=S,n[13]=g,n[14]=N,n[15]=1,n):new l(u,s,c,S,_,y,T,g,-E,-m,-p,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,d=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=d,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),d=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=d,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),d=c,h=l,E=f,m=i+c,p=o+l,_=t+f;return a[0]=d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=_,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],d=e[9],h=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],v=t[3],S=t[4],g=t[5],N=t[6],O=t[7],I=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],D=t[14],U=t[15],L=r*T+u*R+f*A+m*v,F=a*T+s*R+d*A+p*v,b=i*T+c*R+h*A+_*v,B=o*T+l*R+E*A+y*v,z=r*S+u*g+f*N+m*O,q=a*S+s*g+d*N+p*O,G=i*S+c*g+h*N+_*O,V=o*S+l*g+E*N+y*O,W=r*I+u*w+f*M+m*x,X=a*I+s*w+d*M+p*x,H=i*I+c*w+h*M+_*x,Y=o*I+l*w+E*M+y*x,k=r*C+u*P+f*D+m*U,Z=a*C+s*P+d*D+p*U,j=i*C+c*P+h*D+_*U,K=o*C+l*P+E*D+y*U;return n[0]=L,n[1]=F,n[2]=b,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=e[12],h=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],v=t[9],S=t[10],g=t[12],N=t[13],O=t[14],I=r*m+o*p+c*_,w=a*m+u*p+l*_,M=i*m+s*p+f*_,x=r*y+o*T+c*R,C=a*y+u*T+l*R,P=i*y+s*T+f*R,D=r*A+o*v+c*S,U=a*A+u*v+l*S,L=i*A+s*v+f*S,F=r*g+o*N+c*O+d,b=a*g+u*N+l*O+h,B=i*g+s*N+f*O+E;return n[0]=I,n[1]=w,n[2]=M,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=D,n[9]=U,n[10]=L,n[11]=0,n[12]=F,n[13]=b,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=t[0],h=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*d+o*h+c*E,v=a*d+u*h+l*E,S=i*d+s*h+f*E,g=r*m+o*p+c*_,N=a*m+u*p+l*_,O=i*m+s*p+f*_,I=r*y+o*T+c*R,w=a*y+u*T+l*R,M=i*y+s*T+f*R;return n[0]=A,n[1]=v,n[2]=S,n[3]=0,n[4]=g,n[5]=N,n[6]=O,n[7]=0,n[8]=I,n[9]=w,n[10]=M,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],d=e[5],h=e[9],E=e[13],m=e[2],p=e[6],A=e[10],v=e[14],S=e[3],g=e[7],N=e[11],O=e[15],I=A*O,w=v*N,M=p*O,x=v*g,C=p*N,P=A*g,D=m*O,U=v*S,L=m*N,F=A*S,b=m*g,B=p*S,z=I*d+x*h+C*E-(w*d+M*h+P*E),q=w*f+D*h+F*E-(I*f+U*h+L*E),G=M*f+U*d+b*E-(x*f+D*d+B*E),V=P*f+L*d+B*h-(C*f+F*d+b*h),W=w*a+M*i+P*o-(I*a+x*i+C*o),X=I*r+U*i+L*o-(w*r+D*i+F*o),H=x*r+D*a+B*o-(M*r+U*a+b*o),Y=C*r+F*a+b*i-(P*r+L*a+B*i);I=i*E,w=o*h,M=a*E,x=o*d,C=a*h,P=i*d,D=r*E,U=o*f,L=r*h,F=i*f,b=r*d,B=a*f;var k=I*g+x*N+C*O-(w*g+M*N+P*O),Z=w*S+D*N+F*O-(I*S+U*N+L*O),j=M*S+U*g+b*O-(x*S+D*g+B*O),K=P*S+L*g+B*N-(C*S+F*g+b*N),J=M*A+P*v+w*p-(C*v+I*p+x*A),Q=L*v+I*m+U*A-(D*A+F*v+w*m),$=D*p+B*v+x*m-(b*v+M*m+U*p),ee=b*A+C*m+F*p-(L*p+B*A+P*m),te=r*z+a*q+i*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],d=e[13],h=e[14],E=-n*f-r*d-a*h,m=-i*f-o*d-u*h,p=-s*f-c*d-l*h;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,d=e.length;f<d;f++){var h=e[f];n=Math.min(n,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var E=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,d=Number.MAX_VALUE,h=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),d=Math.min(d,p.latitude),h=Math.max(h,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=d,a.east=c,a.north=h,a):new s(o,d,c,h)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var d=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(d>=h))return r(n)?(n.west=l,n.south=d,n.east=f,n.north=h,n):new s(l,d,f,h)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,d=e.south,h=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:d>0?d:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var h=new e,E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,v=new e,S=new e,g=new e;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,h),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),N=t.length;for(r=1;r<N;r++){e.clone(t[r],i);var O=i.x,I=i.y,w=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,U=M;x>U&&(U=x,P=u,D=l),C>U&&(U=C,P=s,D=f);var L=A;L.x=.5*(P.x+D.x),L.y=.5*(P.y+D.y),L.z=.5*(P.z+D.z);var F=e.magnitudeSquared(e.subtract(D,L,R)),b=Math.sqrt(F),B=v;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,R),.5,g),G=0;for(r=0;r<N;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,R));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,L,R));if(W>F){var X=Math.sqrt(W);b=.5*(b+X),F=b*b;var H=X-b;L.x=(b*L.x+H*i.x)/X,L.y=(b*L.y+H*i.y)/X,L.z=(b*L.z+H*i.z)/X}}return b<G?(e.clone(L,n.center),n.radius=b):(e.clone(q,n.center),n.radius=G),n};var N=new o,O=new e,I=new e,w=new t,M=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,N),f.southwest(t,w),w.height=i,f.northeast(t,M),M.height=o;var s=n.project(w,O),c=n.project(M,I),l=c.x-s.x,h=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*h,m.z=s.z+.5*E,u};var x=[];d.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,x);return d.fromPoints(s,u)},d.fromVertices=function(t,n,i,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,h),l=e.clone(u,E),f=e.clone(u,m),N=e.clone(u,p),O=e.clone(u,_),I=e.clone(u,y),w=t.length;for(s=0;s<w;s+=i){var M=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>N.x&&e.clone(u,N),x<l.y&&e.clone(u,l),x>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(N,c,R)),D=e.magnitudeSquared(e.subtract(O,l,R)),U=e.magnitudeSquared(e.subtract(I,f,R)),L=c,F=N,b=P;D>b&&(b=D,L=l,F=O),U>b&&(b=U,L=f,F=I);var B=A;B.x=.5*(L.x+F.x),B.y=.5*(L.y+F.y),B.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,R)),q=Math.sqrt(z),G=v;G.x=c.x,G.y=l.y,G.z=f.z;var V=S;V.x=N.x,V.y=O.y,V.z=I.z;var W=e.multiplyByScalar(e.add(G,V,R),.5,g),X=0;for(s=0;s<w;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,R));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,B,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;B.x=(q*B.x+Z*u.x)/k,B.y=(q*B.y+Z*u.y)/k,B.z=(q*B.z+Z*u.z)/k}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,h),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,p),f=e.clone(i,_),N=e.clone(i,y),O=t.length;for(o=0;o<O;o+=3){var I=t[o]+n[o],w=t[o+1]+n[o+1],M=t[o+2]+n[o+2];i.x=I,i.y=w,i.z=M,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>N.z&&e.clone(i,N)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(N,c,R)),D=u,U=l,L=x;C>L&&(L=C,D=s,U=f),P>L&&(L=P,D=c,U=N);var F=A;F.x=.5*(D.x+U.x),F.y=.5*(D.y+U.y),F.z=.5*(D.z+U.z);var b=e.magnitudeSquared(e.subtract(U,F,R)),B=Math.sqrt(b),z=v;z.x=u.x,z.y=s.y,z.z=c.z;var q=S;q.x=l.x,q.y=f.y,q.z=N.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,g),V=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,R));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,F,R));if(X>b){var H=Math.sqrt(X);B=.5*(B+H),b=B*B;var Y=H-B;F.x=(B*F.x+Y*i.x)/H,F.y=(B*F.y+Y*i.y)/H,F.z=(B*F.z+Y*i.z)/H}}return B<V?(e.clone(F,r.center),r.radius=B):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,D=new e,U=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,D),u=c.getColumn(r,2,U);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new d);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var b=new e;d.expand=function(t,n,r){r=d.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,b));return a>r.radius&&(r.radius=a),r},d.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var B=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,B);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,V=new e,W=new e,X=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return d.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,X),h=e.negate(c,W),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=i.cartesianToCartographic(y,H);n.project(T,y)}a=d.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,v=o.z;return o.x=v,o.y=R,o.z=A,a},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!d())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,v=r(e[1]))}return A}function i(){return a()&&v}function o(){if(!t(S)&&(S=!1,!a()&&!d()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){ -var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,g=r(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(N=!0,O=r(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=r(e[1]))}return I}function f(){return l()&&w}function d(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(M=!0,x=r(e[1]))}return M}function h(){return d()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(R.appVersion)),D}function p(){return E()&&P}function _(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),U}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,v,S,g,N,O,I,w,M,x,C,P,D,U,L,F,b={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:d,edgeVersion:h,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return b.supportsFullscreen=function(){return n.supportsFullscreen()},b.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},b.supportsWebWorkers=function(){return"undefined"!=typeof Worker},b}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,a=(n-r)/n,i=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,i),f=s*o,d=f*f,h=1-d,E=Math.sqrt(h),m=t/4,p=m*m,_=p*m,y=p*p,T=1+m-3*p/4+5*_/4-175*y/64,R=1-m+15*p/8-35*_/8,A=1-3*m+35*p/4,v=1-5*m,S=T*l-R*Math.sin(2*l)*m/2-A*Math.sin(4*l)*p/16-v*Math.sin(6*l)*_/48-5*Math.sin(8*l)*y/512,g=e._constants;g.a=n,g.b=r,g.f=a,g.cosineHeading=i,g.sineHeading=o,g.tanU=u,g.cosineU=s,g.sineU=c,g.sigma=l,g.sineAlpha=f,g.sineSquaredAlpha=d,g.cosineSquaredAlpha=h,g.cosineAlpha=E,g.u2Over4=m,g.u4Over16=p,g.u6Over64=_,g.u8Over256=y,g.a0=T,g.a1=R,g.a2=A,g.a3=v,g.distanceRatio=S}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,a,i,o){var u=c(e,n);return(1-u)*e*t*(r+u*a*(o+u*i*(2*o*o-1)))}function f(e,t,n,r,a,i,o){var s,c,f,d,h,E=(t-n)/t,m=i-r,p=Math.atan((1-E)*Math.tan(a)),_=Math.atan((1-E)*Math.tan(o)),y=Math.cos(p),T=Math.sin(p),R=Math.cos(_),A=Math.sin(_),v=y*R,S=y*A,g=T*A,N=T*R,O=m,I=u.TWO_PI,w=Math.cos(O),M=Math.sin(O);do{w=Math.cos(O),M=Math.sin(O);var x=S-N*w;f=Math.sqrt(R*R*M*M+x*x),c=g+v*w,s=Math.atan2(f,c);var C;0===f?(C=0,d=1):(C=v*M/f,d=1-C*C),I=O,h=c-2*g/d,isNaN(h)&&(h=0),O=m+l(E,C,d,s,f,c,h)}while(Math.abs(O-I)>u.EPSILON12);var P=d*(t*t-n*n)/(n*n),D=1+P*(4096+P*(P*(320-175*P)-768))/16384,U=P*(256+P*(P*(74-47*P)-128))/1024,L=h*h,F=U*f*(h+U*(c*(2*L-1)-U*h*(4*f*f-3)*(4*L-3)/6)/4),b=n*D*(s-F),B=Math.atan2(R*M,S-N*w),z=Math.atan2(y*M,S*w-N);e._distance=b,e._startHeading=B,e._endHeading=z,e._uSquared=P}function d(n,r,a,i){e.normalize(i.cartographicToCartesian(r,m),E),e.normalize(i.cartographicToCartesian(a,m),m);f(n,i.maximumRadius,i.minimumRadius,r.longitude,r.latitude,a.longitude,a.latitude),n._start=t.clone(r,n._start),n._end=t.clone(a,n._end),n._start.height=0,n._end.height=0,s(n)}function h(e,n,i){var u=r(i,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(n)&&d(this,e,n,u)}var E=new e,m=new e;return i(h.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),h.prototype.setEndPoints=function(e,t){d(this,e,t,this._ellipsoid)},h.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},h.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,i=r.distanceRatio+e/r.b,o=Math.cos(2*i),u=Math.cos(4*i),s=Math.cos(6*i),c=Math.sin(2*i),f=Math.sin(4*i),d=Math.sin(6*i),h=Math.sin(8*i),E=i*i,m=i*E,p=r.u8Over256,_=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*p*o/3+i*(1-_+7*T/4-15*y/4+579*p/64-(T-15*y/4+187*p/16)*o-(5*y/4-115*p/16)*u-29*p*s/16)+(_/2-T+71*y/32-85*p/16)*c+(5*T/16-5*y/4+383*p/96)*f-E*((y-11*p/2)*c+5*p*f/2)+(29*y/96-29*p/16)*d+539*p*h/1536,A=Math.asin(Math.sin(R)*r.cosineAlpha),v=Math.atan(r.a/r.b*Math.tan(A));R-=r.sigma;var S=Math.cos(2*r.sigma+R),g=Math.sin(R),N=Math.cos(R),O=r.cosineU*N,I=r.sineU*g,w=Math.atan2(g*r.sineHeading,O-I*r.cosineHeading),M=w-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,g,N,S);return a(n)?(n.longitude=this._start.longitude+M,n.latitude=v,n.height=0,n):new t(this._start.longitude+M,v,0)},h}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var d=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[d/e,a/d]:[a/d,d/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,d=u*u,h=s*s,E=o*s-d,m=o*c-u*s,p=u*c-h,_=4*E*p-m*m;if(_<0){var y,T,R;d*f>=l*h?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var A=R<0?-1:1,v=-A*Math.abs(y)*Math.sqrt(-_);i=-R+v;var S=i/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),N=i===v?-g:-T/g;return a=T<=0?g+N:-R/(g*g+N*N+T),d*f>=l*h?[(a-u)/o]:[-c/(a+s)]}var O=E,I=-2*u*E+o*m,w=p,M=-c*m+2*s*p,x=Math.sqrt(_),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-I)/3);a=2*Math.sqrt(-O);var D=Math.cos(P);i=a*D;var U=a*(-D/2-C*Math.sin(P)),L=i+U>2*u?i-u:U-u,F=o,b=L/F;P=Math.abs(Math.atan2(c*x,-M)/3),a=2*Math.sqrt(-w),D=Math.cos(P),i=a*D,U=a*(-D/2-C*Math.sin(P));var B=-c,z=i+U<2*s?i+s:U+s,q=B/z,G=F*z,V=-L*z-F*B,W=L*B,X=(s*V-u*W)/(-u*V+s*G);return b<=X?b<=q?X<=q?[b,X,q]:[b,q,X]:[q,b,X]:b<=q?[X,b,q]:X<=q?[X,q,b]:[q,X,b]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var d=-t/4,h=f[f.length-1];if(Math.abs(h)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[d-T,d-y,d+y,d+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[d-m,d+m];if(p<0&&_>=0)return m=Math.sqrt(_),[d-m,d+m]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,v=(s+h+c/R)/2,S=r.computeRealRoots(1,R,A),g=r.computeRealRoots(1,-R,v);return 0!==S.length?(S[0]+=d,S[1]+=d,0!==g.length?(g[0]+=d,g[1]+=d,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=d,g[1]+=d,g):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,d=c*o-i*a*t+u,h=e.computeRealRoots(1,l,f,d);if(h.length>0){var E,m,p=h[0],_=a-p,y=_*_,T=t/2,R=_/2,A=y-4*o,v=y+4*Math.abs(o),S=c-4*p,g=c+4*Math.abs(p);if(p<0||A*g<S*v){var N=Math.sqrt(S);E=N/2,m=0===N?0:(t*R-i)/N}else{var O=Math.sqrt(A);E=0===O?0:(t*R-i)/O,m=O/2}var I,w;0===T&&0===E?(I=0,w=0):n.sign(T)===n.sign(E)?(I=T+E,w=p/I):(w=T-E,I=p/w);var M,x;0===R&&0===m?(M=0,x=0):n.sign(R)===n.sign(m)?(M=R+m,x=o/M):(x=R-m,M=o/x);var C=r.computeRealRoots(1,I,M),P=r.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,d=f*r,h=a*a;return u*c*f-4*s*d-4*e*l*f+18*e*t*n*d-27*i*f*f+256*o*(h*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+h*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,d=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=f<0?h+1:h,h+=d<0?h+1:h){case 0:return a(c,l,f,d);case 1:case 2:return i(c,l,f,d);case 3:case 4:return a(c,l,f,d);case 5:return i(c,l,f,d);case 6:case 7:return a(c,l,f,d);case 8:return i(c,l,f,d);case 9:case 10:return a(c,l,f,d);case 11:return i(c,l,f,d);case 12:case 13:case 14:case 15:return a(c,l,f,d);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function d(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),d=e.dot(u,u),h=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(d,h,E,v);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function h(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,d=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*d,m=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*d+a*n.x+r,_=d*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var v=l[1],S=Math.sqrt(Math.max(1-v*v,0));T.push(new e(a,i*v,i*-S)),T.push(new e(a,i*v,i*S))}return T}var g=y*y,N=_*_,O=E*E,I=y*_,w=O+N,M=2*(m*E+I),x=2*p*E+m*m-N+g,C=2*(p*m-I),P=p*p-g;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var D=l.length;if(0===D)return T;for(var U=0;U<D;++U){var L,F=l[U],b=F*F,B=Math.max(1-b,0),z=Math.sqrt(B);L=o.sign(E)===o.sign(p)?h(E*b+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?h(E*b,m*F+p,o.EPSILON12):h(E*b+m*F,p,o.EPSILON12);var q=h(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++U):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,d,h=t.origin,E=t.direction,m=e.subtract(a,r,p),A=e.subtract(i,r,_),v=e.cross(E,A,y),S=e.dot(m,v);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,r,T),(l=e.dot(s,v))<0||l>S)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>S)return;d=e.dot(A,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(h,r,T),(l=e.dot(s,v)*g)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*g)<0||l+f>1)return;d=e.dot(A,c)*g}return d},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var v={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=d(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;m.lineSegmentSphere=function(t,n,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=d(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var g=new e,N=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),d=e.magnitudeSquared(l),h=e.dot(l,f);if(d>1){if(h>=0)return;var E=h*h;if(r=d-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=h*h-o,s=-h+Math.sqrt(u);var m=s/a,p=r/s;return m<p?new i(m,p):{start:p,stop:m}}var _=Math.sqrt(r/a);return new i(_,_)}return d<1?(r=d-1,a=e.magnitudeSquared(f),o=a*r,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(f),new i(0,-h/a)):void 0};var O=new e,I=new e,w=new e,M=new e,x=new e,C=new u,P=new u,D=new u,U=new u,L=new u,F=new u,b=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),d=e.mostOrthogonalAxis(l,M),h=e.normalize(e.cross(d,f,I),I),m=e.normalize(e.cross(f,h,w),w),p=C;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=h.x,p[4]=h.y,p[5]=h.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,D),T=u.fromScale(n.oneOverRadii,U),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,v,S=u.multiply(u.multiply(_,T,F),R,F),g=u.multiply(u.multiply(S,y,b),p,b),N=u.multiplyByVector(S,a,x),G=E(g,e.negate(N,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],B),B);var Y=e.normalize(e.subtract(A,a,M),M),k=e.dot(Y,i);k>X&&(X=k,W=e.clone(A,W))}var Z=n.cartesianToCartographic(W,q) -;return X=o.clamp(X,0,1),v=e.magnitude(e.subtract(W,a,M))*Math.sqrt(1-X*X),v=c?-v:v,Z.height=v,n.cartographicToCartesian(Z,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,d;if(1!==l&&2!==l||(f=new e,d=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,d),{positions:[t,n,r,f,d],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,d),{positions:[t,n,r,f,d],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,d),{positions:[t,n,r,f,d],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,d),{positions:[t,n,r,f,d],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,d),{positions:[t,n,r,f,d],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,d),{positions:[t,n,r,f,d],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(e,t,n){var r=g;r.length=e;var a;if(t===n){for(a=0;a<e;a++)r[a]=t;return r}var i=n-t,o=i/e;for(a=0;a<e;a++){var u=t+a*o;r[a]=u}return r}function h(t,n,r,a,i,o,u,s){var c=a.scaleToGeodeticSurface(t,w),l=a.scaleToGeodeticSurface(n,M),f=E.numberOfPoints(t,n,r),h=a.cartesianToCartographic(c,N),m=a.cartesianToCartographic(l,O),p=d(f,i,o);x.setEndPoints(h,m);var _=x.surfaceDistance/f,y=s;h.height=i;var T=a.cartographicToCartesian(h,I);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var A=x.interpolateUsingSurfaceDistance(R*_,O);A.height=p[R],T=a.cartographicToCartesian(A,I),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var a=e.distance(t,n);return Math.ceil(a/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),a=0;a<n;a++){var i=e[a];r[a]=t.cartesianToCartographic(i,m).height}return r};var p=new l,_=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,A=new f(e.UNIT_X,0),v=new e,S=new e,g=[],N=new t,O=new t,I=new e,w=new e,M=new e,x=new o;return E.wrapLongitude=function(t,a){var i=[],o=[];if(r(t)&&t.length>0){a=n(a,l.IDENTITY);var s=l.inverseTransformation(a,p),c=l.multiplyByPoint(s,e.ZERO,_),d=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),h=f.fromPointNormal(c,d,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,A),g=1;i.push(e.clone(t[0]));for(var N=i[0],O=t.length,I=1;I<O;++I){var w=t[I];if(f.getPointDistance(m,N)<0||f.getPointDistance(m,w)<0){var M=u.lineSegmentPlane(N,w,h,v);if(r(M)){var x=e.multiplyByScalar(d,5e-9,S);f.getPointDistance(h,N)<0&&e.negate(x,x),i.push(e.add(M,x,new e)),o.push(g+1),e.negate(x,x),i.push(e.add(M,x,new e)),g=1}}i.push(e.clone(t[I])),g++,N=w}o.push(g)}return{positions:i,lengths:o}},E.generateArc=function(t){r(t)||(t={});var a=t.positions,o=a.length,u=n(t.ellipsoid,i.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var d=u.scaleToGeodeticSurface(a[0],w);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(d,I);e.multiplyByScalar(m,l,m),e.add(d,m,d)}return[d.x,d.y,d.z]}var p=t.minDistance;if(!r(p)){var _=n(t.granularity,c.RADIANS_PER_DEGREE);p=c.chordLength(_,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(a[y],a[y+1],p);var R=3*(T+1),A=new Array(R),v=0;for(y=0;y<o-1;y++){v=h(a[y],a[y+1],p,u,f?l[y]:l,f?l[y+1]:l,A,v)}g.length=0;var S=a[o-1],O=u.cartesianToCartographic(S,N);O.height=f?l[o-1]:l;var M=u.cartographicToCartesian(O,I);return e.pack(M,A,R-3),A},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,a=new Array(r),i=0;i<r;i++)a[i]=e.unpack(n,3*i);return a},E}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,d=1;d<f;d++){var h=t[d],E=h.x,m=h.y,p=h.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=a,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return d(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return h(e)}var s,c,l,f,d,h,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],d=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},h=function(e){return m(f,e),e},E=function(e){return e=t(e),d=e.then,E=t,h=_,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,d,h,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,d=[],h=o(),c)for(p=h.progress,m=function(e){d.push(e),--l||(E=m=_,h.reject(d))},E=function(e){f.push(e),--c||(E=m=_,h.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else h.resolve(f);return h.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return p(1,arguments),d(e,y).then(t,n,r)}function f(){return d(arguments,y)}function d(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function h(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=d,e.reduce=h,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,d){var h,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,v=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":v=s.charAt(g+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(d)>-1?6:"d"==d?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],d){case"s":return u(String(_),y,c,f,R,v);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return h=+_||0,h=Math.round(h-h%1),E=h<0?"-":T,_=E+a(String(Math.abs(h)),f,"0",!1),i(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return h=+_,E=h<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(d.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(d)%2],_=E+Math.abs(h)[m](f),i(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function d(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function h(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,h(a,t,this),r===c.UTC&&f(this)}var p=new i,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,v=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(h(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(h(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,d=0,p=0,y=0,g=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(R)))n=+u[1],s=+u[2];else if(null!==(u=w.match(T)))n=+u[1];else{var x;if(null!==(u=w.match(A)))n=+u[1],x=+u[2],i=o(n);else if(null!==(u=w.match(v))){n=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(n,0,4));x=7*C+P-D.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var U;if(r(M)){u=M.match(I),null!==u?(d=+u[1],p=+u[2],y=+u[3],g=1e3*+(u[4]||0),U=5):(u=M.match(O),null!==u?(d=+u[1],p=+u[2],y=60*+(u[3]||0),U=4):null!==(u=M.match(N))&&(d=+u[1],p=60*+(u[2]||0),U=3));var L=u[U],F=+u[U+1],b=+(u[U+2]||0);switch(L){case"+":d-=F,p-=b;break;case"-":d+=F,p+=b;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,d,p)).getTimezoneOffset()}}var B=60===y;for(B&&y--;p>=60;)p-=60,d++;for(;d>=24;)d-=24,l++;for(a=i&&2===s?29:_[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:_[s-1];for(;p<0;)p+=60,d--;for(;d<0;)d+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:_[s-1],l+=a;var z=E(n,s,l,d,p,y,g);return r(t)?(h(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var w=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=d(e,w);r(a)||(m.addSeconds(e,-1,w),a=d(w,w),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var h=80*c/2447|0,E=c-(2447*h/80|0)|0;c=h/11|0;var p=h+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,v=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=v,t.isLeapSecond=n,t):new i(_,p,E,y,R,A,v,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,p);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return h(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return h(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return h(e.dayNumber,r,n)},m.addDays=function(e,t,n){return h(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return g[e]<l.maximumRequestsPerServer}function h(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--g[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--g[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function p(e){var t=h(e);return e.state=s.ACTIVE,S.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++g[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function _(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--g[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,v=new i({comparator:c});v.maximumLength=A,v.reserve(A) -;var S=[],g={},N="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;v.length>e;){var t=v.pop();_(t)}A=e,v.maximumLength=e,v.reserve(e)}}}),l.update=function(){var e,t,n=0,r=S.length;for(e=0;e<r;++e)t=S[e],t.cancelled&&_(t),t.state===s.ACTIVE?n>0&&(S[e-n]=t):++n;S.length-=n;var a=v.internalArray,i=v.length;for(e=0;e<i;++e)f(a[e]);v.resort();for(var o=Math.max(l.maximumRequests-S.length,0),u=0;u<o&&v.length>0;)t=v.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(p(t),++u):_(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(N);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=g[a];return r(i)||(g[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return p(e);if(!(S.length>=l.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){f(e);var t=v.insert(e);if(r(t)){if(t===e)return;_(t)}return h(e)}},l.clearForSpecs=function(){for(;v.length>0;){_(v.pop())}for(var e=S.length,t=0;t<e;++t)_(S[t]);S.length=0,g={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return g[e]},l.requestHeap=v,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,d=t.overrideMimeType;a=n(a,t.url);var h=r(t.request)?t.request:new i;return h.url=a,h.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,d);return r(n)&&r(n.abort)&&(h.cancelFunction=function(){n.abort()}),t.promise},u.request(h)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function d(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function h(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return d(a,i);case"blob":var o=d(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(h(f,t));var d=new XMLHttpRequest;if(c.contains(e)&&(d.withCredentials=!0),r(l)&&r(d.overrideMimeType)&&d.overrideMimeType(l),d.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&d.setRequestHeader(m,i[m]);r(t)&&(d.responseType=t);var p=!1;return"string"==typeof e&&(p=0===e.indexOf("file://")),d.onload=function(){if((d.status<200||d.status>=300)&&(!p||0!==d.status))return void u.reject(new o(d.status,d.response,d.getAllResponseHeaders()));var e=d.response,n=d.responseType;if(204===d.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(d.responseXML)&&d.responseXML.hasChildNodes()?u.resolve(d.responseXML):""!==n&&"text"!==n||!r(d.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(d.responseText);else u.resolve(e)},d.onerror=function(e){u.reject(new o)},d.send(a),d},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function h(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),d=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||d<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=d,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var v=p[R+a],S=p[R+m],g=v+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,S,f.TAI);if(_.push(N),T){if(S!==y&&r(y)){var O=o.leapSeconds,I=t(O,N,h);if(I<0){var w=new u(N,S);O.splice(~I,0,w)}}y=S}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),d=a*s,h=i*s,E=n[d+e._ut1MinusUtcSecondsColumn],_=n[h+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[d+e._taiMinusUtcSecondsColumn],R=n[h+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[d+e._xPoleWanderRadiansColumn],n[h+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[d+e._yPoleWanderRadiansColumn],n[h+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[d+e._xCelestialPoleOffsetRadiansColumn],n[h+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[d+e._yCelestialPoleOffsetRadiansColumn],n[h+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return d.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),d.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},d.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],d=i[u+1],h=o.lessThanOrEquals(f,e),E=!r(d),m=E||o.greaterThanOrEquals(d,e);if(h&&m)return s=u,!E&&d.equals(e)&&++s,l=s+1,_(this,i,this._samples,e,s,l,n),n}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},d}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(d)||(d=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(h)||(h=document.createElement("a"));var n=d(e);return h.href=n,h.href=h.href,h.href}var f,d,h,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,d=s/this._samplesPerXysFile|0,h=[],E=f;E<=d;++E)h.push(l(this,E));return e.all(h)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var d=!1,h=this._samples;if(r(h[3*s])||(l(this,s/this._samplesPerXysFile|0),d=!0),r(h[3*f])||(l(this,f/this._samplesPerXysFile|0),d=!0),!d){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*h[A++],n.y+=T[E]*h[A++],n.s+=T[E]*h[A]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,d=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=d,a):new s(u,l,f,d)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,d=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=d+h+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;h>d&&(_=1),E>d&&E>h&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var d=new s,h=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,d),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,d),s.multiply(h,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,d=o*s-r*c+a*l+i*u,h=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=d,n.z=h,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var v=new s,S=new s,g=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=v=s.negate(t,v)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),g=s.multiplyByScalar(i,Math.sin(n*u),g),r=s.add(S,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var N=new e,O=new e,I=new s,w=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,I);s.multiply(i,r,w);var o=s.log(w,N);s.multiply(i,t,w);var u=s.log(w,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,I),u=s.slerp(n,r,a,w);return s.slerp(o,u,2*a*(1-a),i)};for(var M=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,b=2*F+1;C[L]=1/(F*b),P[L]=F/b}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,U[f]=(C[f]*l-P[f])*o;var d=a*n*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),h=u*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),E=s.multiplyByScalar(e,h,M);return s.multiplyByScalar(t,d,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,I),u=s.fastSlerp(n,r,a,w);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E,m,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},v={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,O=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(S[i])?r=S[i]:(r=function(r,i,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(v[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(v[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(v[a],0,I),"east"!==a&&"west"!==a&&n.multiplyByScalar(I,c,I)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,g.up);var l=g.up,d=g.east;d.x=-r.y,d.y=r.x,d.z=0,n.normalize(d,g.east),n.cross(l,d,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),N=g[e],O=g[t],I=g[a]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},S[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var w=new y,M=new n(1,1,1),x=new _;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,w),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,M,x);return i=a(e,r,i),_.multiply(i,s,i)};var C=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=_.getRotation(i,P);return y.fromRotationMatrix(o,a)};var D=m.TWO_PI/86400,U=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){U=E.addSeconds(e,-E.computeTaiMinusUtc(e),U);var n,r=U.dayNumber,a=U.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,d=Math.cos(f),h=Math.sin(f);return u(t)?(t[0]=d,t[1]=-h,t[2]=0,t[3]=h,t[4]=d,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(d,h,0,-h,d,0,0,0,1)},R.iau2006XysData=new d,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new h(0,0,0),F=new l(0,0,0,0,0,0),b=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=b;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,B),d=p.multiply(l,f,b),h=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=h-2451545,A=_/T.SECONDS_PER_DAY,v=.779057273264+A+.00273781191135448*(y+A);v=v%1*m.TWO_PI;var S=p.fromRotationZ(v,B),g=p.multiply(d,S,b),N=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),w=Math.sin(n.yPoleWander),M=r-2451545+a/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),D=B;return D[0]=N*C,D[1]=N*P,D[2]=I,D[3]=-O*P+w*I*C,D[4]=O*C+w*I*P,D[5]=-w*N,D[6]=-w*P-O*I*C,D[7]=w*C-O*I*P,D[8]=O*N,p.multiply(g,D,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return _.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var W=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new p,Z=new _,j=new _;return R.basisTo2D=function(e,t,r){var a=_.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,Z),c=_.inverseTransformation(s,j),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(W,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,Z),o=_.inverseTransformation(i,j),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,Z);return _.multiply(W,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=h.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new d,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=_;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=_;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var d=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(d,c,d),a.scaleToGeocentricSurface(d,d)}return t},E}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var a=e[r];D=t.cartesianToCartographic(a,D),n[r]=D.height,e[r]=t.scaleToGeodeticSurface(a,a)}return n}function h(e,n,r,a){var i,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/a),l=new Array(c);if(n===r){for(i=0;i<c;i++)l[i]=n;return l.push(r),l}var f=r-n,d=f/c;for(i=1;i<c;i++){var h=n+i*d;l[i]=h}return l[0]=n,l.push(r),l}function E(n,r,a,o){var u=new i(a,o),s=u.projectPointOntoPlane(t.add(a,n,U),U),c=u.projectPointOntoPlane(t.add(a,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function m(e,n,r,a,i,o,c,l){var d=G,h=V;b=f.eastNorthUpToFixedFrame(e,i,b),d=s.multiplyByPointAsVector(b,F,d),d=t.normalize(d,d);var m=E(d,n,e,i);z=u.fromRotationZ(m,z),W.z=o,b=s.multiplyTransformation(b,s.fromRotationTranslation(z,W,B),b);var p=q;p[0]=c;for(var _=0;_<l;_++)for(var y=0;y<r.length;y+=3)h=t.fromArray(r,y,h),h=u.multiplyByVector(p,h,h),h=s.multiplyByPoint(b,h,h),a.push(h.x,h.y,h.z);return a}function p(e,n,r,a,i,o,u){for(var s=0;s<e.length;s+=3){a=m(t.fromArray(e,s,X),n,r,a,i,o[s/3],u,1)}return a}function _(e,t){var n=e.length,r=new Array(6*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-i,l=u.y-o;r[a++]=c,r[a++]=0,r[a++]=l,r[a++]=c,r[a++]=0,r[a++]=l}return u=e[0],r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o,r}function y(e,t){for(var n=e.length,r=new Array(3*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[a++]=e[u].x-i,r[a++]=0,r[a++]=e[u].y-o;return r}function T(e,n,r,i,s,c,f,d,h,E){var p,_=t.angleBetween(t.subtract(n,e,x),t.subtract(r,e,C)),y=i===a.BEVELED?0:Math.ceil(_/o.toRadians(5));p=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,x),_/(y+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,_/(y+1),H),k);var T,R;if(n=t.clone(n,Y),y>0)for(var A=E?2:1,v=0;v<y;v++)n=u.multiplyByVector(p,n,n),T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,d,f,c,h,1,A);else T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,d,f,c,h,1,1),r=t.clone(r,Y),T=t.subtract(r,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(r,C),f=m(R,T,d,f,c,h,1,1);return f}var R=[new t,new t],A=new t,v=new t,S=new t,g=new t,N=new t,O=new t,I=new t,w=new t,M=new t,x=new t,C=new t,P={},D=new r,U=new t,L=new t,F=new t(-1,0,0),b=new s,B=new s,z=new u,q=u.IDENTITY.clone(),G=new t,V=new n,W=new t,X=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],a=n-1,i=0;i<n;a=i++){var o=t[a],u=t[i] -;e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,a){var o=new i(r,a),u=o.projectPointOntoPlane(t.add(r,e,U),U),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var Z=new t,j=new t;return P.computePositions=function(e,n,r,i,u){var s=i._ellipsoid,l=d(e,s),f=i._granularity,E=i._cornerType,C=u?_(n,r):y(n,r),D=u?y(n,r):void 0,U=r.height/2,L=r.width/2,F=e.length,b=[],B=u?[]:void 0,z=A,q=v,G=S,V=g,W=N,X=O,H=I,Y=w,k=M,K=e[0],J=e[1];V=s.geodeticSurfaceNormal(K,V),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(B=m(K,Y,D,B,s,Q+U,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<F-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),V=s.geodeticSurfaceNormal(K,V);var ae=t.multiplyByScalar(V,t.dot(z,V),Z);t.subtract(z,ae,ae),t.normalize(ae,ae);var ie=t.multiplyByScalar(V,t.dot(q,V),j);t.subtract(q,ie,ie),t.normalize(ie,ie);if(!o.equalsEpsilon(Math.abs(t.dot(ae,ie)),1,o.EPSILON7)){G=t.cross(G,V,G),G=t.cross(V,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,x))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=h(R,Q+U,$+U,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),b=p(te,Y,C,b,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,L,H),H),E===a.ROUNDED||E===a.BEVELED?T(W,X,H,E,ue,s,b,C,$+U,u):(G=t.negate(G,G),b=m(K,G,C,b,s,$+U,oe,re)),k=t.clone(H,k)):(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,-L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=h(R,Q+U,$+U,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),b=p(te,Y,C,b,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,-L,H),H),E===a.ROUNDED||E===a.BEVELED?T(W,X,H,E,ue,s,b,C,$+U,u):b=m(K,G,C,b,s,$+U,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else b=m(k,Y,C,b,s,Q+U,1,1),k=K;Q=$,$=l[ne+1],K=J}R[0]=t.clone(k,R[0]),R[1]=t.clone(K,R[1]),ee=h(R,Q+U,$+U,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),b=p(te,Y,C,b,s,ee,1),u&&(B=m(K,Y,D,B,s,$+U,1,1)),F=b.length;var se=u?F+B.length:F,ce=new Float64Array(se);return ce.set(b),u&&ce.set(B,F),ce},P}),define("Core/CorridorGeometryLibrary",["./Cartesian3","./CornerType","./defined","./Math","./Matrix3","./PolylinePipeline","./PolylineVolumeGeometryLibrary","./Quaternion"],function(e,t,n,r,a,i,o,u){"use strict";function s(n,i,o,s,c){var l=e.angleBetween(e.subtract(i,n,h),e.subtract(o,n,E)),f=s===t.BEVELED?1:Math.ceil(l/r.toRadians(5))+1,d=3*f,m=new Array(d);m[d-3]=o.x,m[d-2]=o.y,m[d-1]=o.z;var p;p=c?a.fromQuaternion(u.fromAxisAngle(e.negate(n,h),l/f,w),M):a.fromQuaternion(u.fromAxisAngle(n,l/f,w),M);var _=0;i=e.clone(i,h);for(var y=0;y<f;y++)i=a.multiplyByVector(p,i,i),m[_++]=i.x,m[_++]=i.y,m[_++]=i.z;return m}function c(n){var r=y,a=T,i=R,o=n[1];a=e.fromArray(n[1],o.length-3,a),i=e.fromArray(n[0],0,i),r=e.multiplyByScalar(e.add(a,i,r),.5,r);var u=s(r,a,i,t.ROUNDED,!1),c=n.length-1,l=n[c-1];return o=n[c],a=e.fromArray(l,l.length-3,a),i=e.fromArray(o,0,i),r=e.multiplyByScalar(e.add(a,i,r),.5,r),[u,s(r,a,i,t.ROUNDED,!1)]}function l(t,n,r,a){var i=h;return a?i=e.add(t,n,i):(n=e.negate(n,n),i=e.add(t,n,i)),[i.x,i.y,i.z,r.x,r.y,r.z]}function f(t,n,r,a){for(var i=new Array(t.length),o=new Array(t.length),u=e.multiplyByScalar(n,r,h),s=e.negate(u,E),c=0,l=t.length-1,f=0;f<t.length;f+=3){var d=e.fromArray(t,f,m),_=e.add(d,s,p);i[c++]=_.x,i[c++]=_.y,i[c++]=_.z;var y=e.add(d,u,p);o[l--]=y.z,o[l--]=y.y,o[l--]=y.x}return a.push(i,o),a}var d={},h=new e,E=new e,m=new e,p=new e,_=[new e,new e],y=new e,T=new e,R=new e,A=new e,v=new e,S=new e,g=new e,N=new e,O=new e,I=new e,w=new u,M=new a;d.addAttribute=function(e,t,r,a){var i=t.x,o=t.y,u=t.z;n(r)&&(e[r]=i,e[r+1]=o,e[r+2]=u),n(a)&&(e[a]=u,e[a-1]=o,e[a-2]=i)};var x=new e,C=new e;return d.computePositions=function(n){var a=n.granularity,u=n.positions,d=n.ellipsoid,E=n.width/2,m=n.cornerType,p=n.saveAttributes,w=y,M=T,P=R,D=A,U=v,L=S,F=g,b=N,B=O,z=I,q=[],G=p?[]:void 0,V=p?[]:void 0,W=u[0],X=u[1];M=e.normalize(e.subtract(X,W,M),M),w=d.geodeticSurfaceNormal(W,w),D=e.normalize(e.cross(w,M,D),D),p&&(G.push(D.x,D.y,D.z),V.push(w.x,w.y,w.z)),F=e.clone(W,F),W=X,P=e.negate(M,P);var H,Y,k=[],Z=u.length;for(Y=1;Y<Z-1;Y++){w=d.geodeticSurfaceNormal(W,w),X=u[Y+1],M=e.normalize(e.subtract(X,W,M),M),U=e.normalize(e.add(M,P,U),U);var j=e.multiplyByScalar(w,e.dot(M,w),x);e.subtract(M,j,j),e.normalize(j,j);var K=e.multiplyByScalar(w,e.dot(P,w),C);e.subtract(P,K,K),e.normalize(K,K);if(!r.equalsEpsilon(Math.abs(e.dot(j,K)),1,r.EPSILON7)){U=e.cross(U,w,U),U=e.cross(w,U,U),U=e.normalize(U,U);var J=E/Math.max(.25,e.magnitude(e.cross(U,P,h))),Q=o.angleIsGreaterThanPi(M,P,W,d);U=e.multiplyByScalar(U,J,U),Q?(b=e.add(W,U,b),z=e.add(b,e.multiplyByScalar(D,E,z),z),B=e.add(b,e.multiplyByScalar(D,2*E,B),B),_[0]=e.clone(F,_[0]),_[1]=e.clone(z,_[1]),H=i.generateArc({positions:_,granularity:a,ellipsoid:d}),q=f(H,D,E,q),p&&(G.push(D.x,D.y,D.z),V.push(w.x,w.y,w.z)),L=e.clone(B,L),D=e.normalize(e.cross(w,M,D),D),B=e.add(b,e.multiplyByScalar(D,2*E,B),B),F=e.add(b,e.multiplyByScalar(D,E,F),F),m===t.ROUNDED||m===t.BEVELED?k.push({leftPositions:s(b,L,B,m,Q)}):k.push({leftPositions:l(W,e.negate(U,U),B,Q)})):(B=e.add(W,U,B),z=e.add(B,e.negate(e.multiplyByScalar(D,E,z),z),z),b=e.add(B,e.negate(e.multiplyByScalar(D,2*E,b),b),b),_[0]=e.clone(F,_[0]),_[1]=e.clone(z,_[1]),H=i.generateArc({positions:_,granularity:a,ellipsoid:d}),q=f(H,D,E,q),p&&(G.push(D.x,D.y,D.z),V.push(w.x,w.y,w.z)),L=e.clone(b,L),D=e.normalize(e.cross(w,M,D),D),b=e.add(B,e.negate(e.multiplyByScalar(D,2*E,b),b),b),F=e.add(B,e.negate(e.multiplyByScalar(D,E,F),F),F),m===t.ROUNDED||m===t.BEVELED?k.push({rightPositions:s(B,L,b,m,Q)}):k.push({rightPositions:l(W,U,b,Q)})),P=e.negate(M,P)}W=X}w=d.geodeticSurfaceNormal(W,w),_[0]=e.clone(F,_[0]),_[1]=e.clone(W,_[1]),H=i.generateArc({positions:_,granularity:a,ellipsoid:d}),q=f(H,D,E,q),p&&(G.push(D.x,D.y,D.z),V.push(w.x,w.y,w.z));var $;return m===t.ROUNDED&&($=c(q)),{positions:q,corners:k,lefts:G,normals:V,endPositions:$}},d}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,f,d,h,E,m,p;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=d=e[0],f=h=e[1];for(var _=a;_<o;_+=a)E=e[_],m=e[_+1],E<l&&(l=E),m<f&&(f=m),E>d&&(d=E),m>h&&(h=m);p=Math.max(d-l,h-f)}return r(u,c,a,l,f,p),c}function t(e,t,n,r,a){var i,o;if(a===w(e,t,n,r)>0)for(i=t;i<n;i+=r)o=N(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=N(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,h){if(e){!h&&f&&d(e,c,l,f);for(var E,m,p=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?i(e,c,l,f):a(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),O(e),e=m.next,p=m.next;else if((e=m)===p){h?1===h?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===h&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(p(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&y(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(y(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,f=E(u,s,t,n,r),d=E(c,l,t,n,r),h=e.nextZ;h&&h.z<=d;){if(h!==e.prev&&h!==e.next&&p(a.x,a.y,i.x,i.y,o.x,o.y,h.x,h.y)&&y(h.prev,h,h.next)>=0)return!1;h=h.nextZ}for(h=e.prevZ;h&&h.z>=f;){if(h!==e.prev&&h!==e.next&&p(a.x,a.y,i.x,i.y,o.x,o.y,h.x,h.y)&&y(h.prev,h,h.next)>=0)return!1;h=h.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&v(a,i)&&v(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),O(r),O(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&_(s,c)){var l=g(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,f,d,h=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,f=o<u-1?r[o+1]*i:e.length,d=t(e,s,f,i,!1),d===d.next&&(d.steiner=!0),h.push(m(d));for(h.sort(c),o=0;o<h.length;o++)l(h[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=g(t,e);n(r,r.next)}}function f(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,f=n.y,d=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&p(i<f?a:o,i,l,f,i<f?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<d||s===d&&r.x>n.x)&&v(r,e)&&(n=r,d=s),r=r.next;return n}function d(e,t,n,r){var a=e;do{null===a.z&&(a.z=E(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,h(a)}function h(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function p(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!A(e,t)&&v(e,t)&&v(t,e)&&S(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function A(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function v(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function S(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function g(e,t){var n=new I(e.i,e.x,e.y),r=new I(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function N(e,t,n,r){var a=new I(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function w(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(w(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(w(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var d=r[u]*n,h=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[d]-e[E])*(e[h+1]-e[d+1])-(e[d]-e[h])*(e[E+1]-e[d+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,d){"use strict";var h=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?d.COUNTER_CLOCKWISE:d.CLOCKWISE},m.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var p=new n,_=new n,y=new n,T=new n,R=new n,A=new n,v=new n;return m.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var d,h=r.slice(0),E=t.length,m=new Array(3*E),S=0;for(d=0;d<E;d++){var g=t[d];m[S++]=g.x,m[S++]=g.y,m[S++]=g.z}for(var N=[],O={},I=e.maximumRadius,w=l.chordLength(u,I),M=w*w;h.length>0;){var x,C,P=h.pop(),D=h.pop(),U=h.pop(),L=n.fromArray(m,3*U,p),F=n.fromArray(m,3*D,_),b=n.fromArray(m,3*P,y),B=n.multiplyByScalar(n.normalize(L,T),I,T),z=n.multiplyByScalar(n.normalize(F,R),I,R),q=n.multiplyByScalar(n.normalize(b,A),I,A),G=n.magnitudeSquared(n.subtract(B,z,v)),V=n.magnitudeSquared(n.subtract(z,q,v)),W=n.magnitudeSquared(n.subtract(q,B,v)),X=Math.max(G,V,W);X>M?G===X?(x=Math.min(U,D)+" "+Math.max(U,D),d=O[x],o(d)||(C=n.add(L,F,v),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),d=m.length/3-1,O[x]=d),h.push(U,d,P),h.push(d,D,P)):V===X?(x=Math.min(D,P)+" "+Math.max(D,P),d=O[x],o(d)||(C=n.add(F,b,v),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),d=m.length/3-1,O[x]=d),h.push(D,d,U),h.push(d,P,U)):W===X&&(x=Math.min(P,U)+" "+Math.max(P,U),d=O[x],o(d)||(C=n.add(b,L,v),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),d=m.length/3-1,O[x]=d),h.push(P,d,D),h.push(d,U,D)):(N.push(U),N.push(D),N.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:m})},indices:N,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=h,c=E;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},a.unpack=function(n,r,i){return r=e(r,0),t(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(e,n){if(t(e))return t(n)||(n=new a),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},a}),define("Core/CorridorGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Cartographic","./ComponentDatatype","./CornerType","./CorridorGeometryLibrary","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Rectangle","./VertexFormat"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E,m,p,_,y,T,R){"use strict";function A(e,t){for(var n=0;n<e.length;n++)e[n]=t.scaleToGeodeticSurface(e[n],e[n]);return e}function v(e,t,r,a,i,u){var s=e.normals,c=e.tangents,l=e.bitangents,f=n.normalize(n.cross(r,t,F),F);u.normal&&o.addAttribute(s,t,a,i),u.tangent&&o.addAttribute(c,f,a,i),u.bitangent&&o.addAttribute(l,r,a,i)}function S(e,t,r){var i,u,c,l=e.positions,f=e.corners,d=e.endPositions,_=e.lefts,y=e.normals,T=new E,R=0,A=0,S=0;for(u=0;u<l.length;u+=2)c=l[u].length-3,R+=c,S+=2*c,A+=l[u+1].length-3;for(R+=3,A+=3,u=0;u<f.length;u++){i=f[u];var g=f[u].leftPositions;s(g)?(c=g.length,R+=c,S+=c):(c=f[u].rightPositions.length,A+=c,S+=c)}var N,O=s(d);O&&(N=d[0].length-3,R+=N,A+=N,N/=3,S+=6*N);var I,w,M,U,B,z,q=R+A,G=new Float64Array(q),V=t.normal?new Float32Array(q):void 0,W=t.tangent?new Float32Array(q):void 0,X=t.bitangent?new Float32Array(q):void 0,H={normals:V,tangents:W,bitangents:X},Y=0,k=q-1,Z=x,j=C,K=N/2,J=m.createTypedArray(q/3,S),Q=0;if(O){z=P,B=D;var $=d[0];for(Z=n.fromArray(y,0,Z),j=n.fromArray(_,0,j),u=0;u<K;u++)z=n.fromArray($,3*(K-1-u),z),B=n.fromArray($,3*(K+u),B),o.addAttribute(G,B,Y),o.addAttribute(G,z,void 0,k),v(H,Z,j,Y,k,t),w=Y/3,U=w+1,I=(k-2)/3,M=I-1,J[Q++]=I,J[Q++]=w,J[Q++]=M,J[Q++]=M,J[Q++]=w,J[Q++]=U,Y+=3,k-=3}var ee=0,te=0,ne=l[ee++],re=l[ee++];G.set(ne,Y),G.set(re,k-re.length+1),j=n.fromArray(_,te,j);var ae,ie;for(c=re.length-3,u=0;u<c;u+=3)ae=r.geodeticSurfaceNormal(n.fromArray(ne,u,F),F),ie=r.geodeticSurfaceNormal(n.fromArray(re,c-u,b),b),Z=n.normalize(n.add(ae,ie,Z),Z),v(H,Z,j,Y,k,t),w=Y/3,U=w+1,I=(k-2)/3,M=I-1,J[Q++]=I,J[Q++]=w,J[Q++]=M,J[Q++]=M,J[Q++]=w,J[Q++]=U,Y+=3,k-=3;for(ae=r.geodeticSurfaceNormal(n.fromArray(ne,c,F),F),ie=r.geodeticSurfaceNormal(n.fromArray(re,c,b),b),Z=n.normalize(n.add(ae,ie,Z),Z),te+=3,u=0;u<f.length;u++){var oe;i=f[u];var ue,se,ce=i.leftPositions,le=i.rightPositions,fe=L,de=P,he=D;if(Z=n.fromArray(y,te,Z),s(ce)){for(v(H,Z,j,void 0,k,t),k-=3,ue=U,se=M,oe=0;oe<ce.length/3;oe++)fe=n.fromArray(ce,3*oe,fe),J[Q++]=ue,J[Q++]=se-oe-1,J[Q++]=se-oe,o.addAttribute(G,fe,void 0,k),de=n.fromArray(G,3*(se-oe-1),de),he=n.fromArray(G,3*ue,he),j=n.normalize(n.subtract(de,he,j),j),v(H,Z,j,void 0,k,t),k-=3;fe=n.fromArray(G,3*ue,fe),de=n.subtract(n.fromArray(G,3*se,de),fe,de),he=n.subtract(n.fromArray(G,3*(se-oe),he),fe,he),j=n.normalize(n.add(de,he,j),j),v(H,Z,j,Y,void 0,t),Y+=3}else{for(v(H,Z,j,Y,void 0,t),Y+=3,ue=M,se=U,oe=0;oe<le.length/3;oe++)fe=n.fromArray(le,3*oe,fe),J[Q++]=ue,J[Q++]=se+oe,J[Q++]=se+oe+1,o.addAttribute(G,fe,Y),de=n.fromArray(G,3*ue,de),he=n.fromArray(G,3*(se+oe),he),j=n.normalize(n.subtract(de,he,j),j),v(H,Z,j,Y,void 0,t),Y+=3;fe=n.fromArray(G,3*ue,fe),de=n.subtract(n.fromArray(G,3*(se+oe),de),fe,de),he=n.subtract(n.fromArray(G,3*se,he),fe,he),j=n.normalize(n.negate(n.add(he,de,j),j),j),v(H,Z,j,void 0,k,t),k-=3}for(ne=l[ee++],re=l[ee++],ne.splice(0,3),re.splice(re.length-3,3),G.set(ne,Y),G.set(re,k-re.length+1),c=re.length-3,te+=3,j=n.fromArray(_,te,j),oe=0;oe<re.length;oe+=3)ae=r.geodeticSurfaceNormal(n.fromArray(ne,oe,F),F),ie=r.geodeticSurfaceNormal(n.fromArray(re,c-oe,b),b),Z=n.normalize(n.add(ae,ie,Z),Z),v(H,Z,j,Y,k,t),U=Y/3,w=U-1,M=(k-2)/3,I=M+1,J[Q++]=I,J[Q++]=w,J[Q++]=M,J[Q++]=M,J[Q++]=w,J[Q++]=U,Y+=3,k-=3;Y-=3,k+=3}if(Z=n.fromArray(y,y.length-3,Z),v(H,Z,j,Y,k,t),O){Y+=3,k-=3,z=P,B=D;var Ee=d[1];for(u=0;u<K;u++)z=n.fromArray(Ee,3*(N-u-1),z),B=n.fromArray(Ee,3*u,B),o.addAttribute(G,z,void 0,k),o.addAttribute(G,B,Y),v(H,Z,j,Y,k,t),U=Y/3,w=U-1,M=(k-2)/3,I=M+1,J[Q++]=I,J[Q++]=w,J[Q++]=M,J[Q++]=M,J[Q++]=w,J[Q++]=U,Y+=3,k-=3}if(T.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:G}),t.st){var me,pe,_e=new Float32Array(q/3*2),ye=0;if(O){R/=3,A/=3;var Te=Math.PI/(N+1);pe=1/(R-N+1),me=1/(A-N+1);var Re,Ae=N/2;for(u=Ae+1;u<N+1;u++)Re=p.PI_OVER_TWO+Te*u,_e[ye++]=me*(1+Math.cos(Re)),_e[ye++]=.5*(1+Math.sin(Re));for(u=1;u<A-N+1;u++)_e[ye++]=u*me,_e[ye++]=0;for(u=N;u>Ae;u--)Re=p.PI_OVER_TWO-u*Te,_e[ye++]=1-me*(1+Math.cos(Re)),_e[ye++]=.5*(1+Math.sin(Re));for(u=Ae;u>0;u--)Re=p.PI_OVER_TWO-Te*u,_e[ye++]=1-pe*(1+Math.cos(Re)),_e[ye++]=.5*(1+Math.sin(Re));for(u=R-N;u>0;u--)_e[ye++]=u*pe,_e[ye++]=1;for(u=1;u<Ae+1;u++)Re=p.PI_OVER_TWO+Te*u,_e[ye++]=pe*(1+Math.cos(Re)),_e[ye++]=.5*(1+Math.sin(Re))}else{for(R/=3,A/=3,pe=1/(R-1),me=1/(A-1),u=0;u<A;u++)_e[ye++]=u*me,_e[ye++]=0;for(u=R;u>0;u--)_e[ye++]=(u-1)*pe,_e[ye++]=1}T.st=new h({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:_e})}return t.normal&&(T.normal=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:H.normals})),t.tangent&&(T.tangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:H.tangents})),t.bitangent&&(T.bitangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:H.bitangents})),{attributes:T,indices:J}}function g(e,t){if(!(t.normal||t.tangent||t.bitangent||t.st))return e;var r,a,i=e.position.values;(t.normal||t.bitangent)&&(r=e.normal.values,a=e.bitangent.values);var u,s=e.position.values.length/18,c=3*s,l=2*s,f=2*c;if(t.normal||t.bitangent||t.tangent){var d=t.normal?new Float32Array(6*c):void 0,h=t.tangent?new Float32Array(6*c):void 0,E=t.bitangent?new Float32Array(6*c):void 0,m=x,p=C,_=P,y=D,T=U,R=L,A=f;for(u=0;u<c;u+=3){var v=A+f;m=n.fromArray(i,u,m),p=n.fromArray(i,u+c,p),_=n.fromArray(i,(u+3)%c,_),p=n.subtract(p,m,p),_=n.subtract(_,m,_),y=n.normalize(n.cross(p,_,y),y),t.normal&&(o.addAttribute(d,y,v),o.addAttribute(d,y,v+3),o.addAttribute(d,y,A),o.addAttribute(d,y,A+3)),(t.tangent||t.bitangent)&&(R=n.fromArray(r,u,R),t.bitangent&&(o.addAttribute(E,R,v),o.addAttribute(E,R,v+3),o.addAttribute(E,R,A),o.addAttribute(E,R,A+3)),t.tangent&&(T=n.normalize(n.cross(R,y,T),T),o.addAttribute(h,T,v),o.addAttribute(h,T,v+3),o.addAttribute(h,T,A),o.addAttribute(h,T,A+3))),A+=6}if(t.normal){for(d.set(r),u=0;u<c;u+=3)d[u+c]=-r[u],d[u+c+1]=-r[u+1],d[u+c+2]=-r[u+2];e.normal.values=d}else e.normal=void 0;if(t.bitangent?(E.set(a),E.set(a,c),e.bitangent.values=E):e.bitangent=void 0,t.tangent){var S=e.tangent.values;h.set(S),h.set(S,c),e.tangent.values=h}}if(t.st){var g=e.st.values,N=new Float32Array(6*l);N.set(g),N.set(g,l);for(var O=2*l,I=0;I<2;I++){for(N[O++]=g[0],N[O++]=g[1],u=2;u<l;u+=2){var w=g[u],M=g[u+1];N[O++]=w,N[O++]=M,N[O++]=w,N[O++]=M}N[O++]=g[0],N[O++]=g[1]}e.st.values=N}return e}function N(e,t,n){n[t++]=e[0],n[t++]=e[1],n[t++]=e[2];for(var r=3;r<e.length;r+=3){var a=e[r],i=e[r+1],o=e[r+2];n[t++]=a,n[t++]=i,n[t++]=o,n[t++]=a,n[t++]=i,n[t++]=o}return n[t++]=e[0],n[t++]=e[1],n[t++]=e[2],n}function O(e,t){var n=new R({position:t.position,normal:t.normal||t.bitangent||e.shadowVolume,tangent:t.tangent,bitangent:t.normal||t.bitangent,st:t.st}),r=e.ellipsoid,i=o.computePositions(e),u=S(i,n,r),s=e.height,c=e.extrudedHeight,l=u.attributes,f=u.indices,d=l.position.values,E=d.length,p=new Float64Array(6*E),y=new Float64Array(E);y.set(d);var T=new Float64Array(4*E);d=_.scaleToGeodeticHeight(d,s,r),T=N(d,0,T),y=_.scaleToGeodeticHeight(y,c,r),T=N(y,2*E,T),p.set(d),p.set(y,E),p.set(T,2*E),l.position.values=p,l=g(l,t);var A,v=E/3;if(e.shadowVolume){var O=l.normal.values;E=O.length;var I=new Float32Array(6*E);for(A=0;A<E;A++)O[A]=-O[A];I.set(O,E),I=N(O,4*E,I),l.extrudeDirection=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:I}),t.normal||(l.normal=void 0)}var w=f.length,M=v+v,x=m.createTypedArray(p.length/3,2*w+3*M);x.set(f);var C=w;for(A=0;A<w;A+=3){var P=f[A],D=f[A+1],U=f[A+2];x[C++]=U+v,x[C++]=D+v,x[C++]=P+v}var L,F,b,B;for(A=0;A<M;A+=2)L=A+M,F=L+M,b=L+1,B=F+1,x[C++]=L,x[C++]=F,x[C++]=b,x[C++]=b,x[C++]=F,x[C++]=B;return{attributes:l,indices:x}}function I(e,t,r,a,i,o){var u=n.subtract(t,e,B);n.normalize(u,u);var s=r.geodeticSurfaceNormal(e,z),c=n.cross(u,s,B);n.multiplyByScalar(c,a,c);var l=i.latitude,f=i.longitude,d=o.latitude,h=o.longitude;n.add(e,c,z),r.cartesianToCartographic(z,q);var E=q.latitude,m=q.longitude;l=Math.min(l,E),f=Math.min(f,m),d=Math.max(d,E),h=Math.max(h,m),n.subtract(e,c,z),r.cartesianToCartographic(z,q),E=q.latitude,m=q.longitude,l=Math.min(l,E),f=Math.min(f,m),d=Math.max(d,E),h=Math.max(h,m),i.latitude=l,i.longitude=f,o.latitude=d,o.longitude=h}function w(t,r,a,o){t=A(t,r);var u=e(t,n.equalsEpsilon),s=u.length;if(s<2||a<=0)return new T;var c=.5*a;W.latitude=Number.POSITIVE_INFINITY,W.longitude=Number.POSITIVE_INFINITY,X.latitude=Number.NEGATIVE_INFINITY,X.longitude=Number.NEGATIVE_INFINITY;var l,f;if(o===i.ROUNDED){var d=u[0];n.subtract(d,u[1],G),n.normalize(G,G),n.multiplyByScalar(G,c,G),n.add(d,G,V),r.cartesianToCartographic(V,q),l=q.latitude,f=q.longitude,W.latitude=Math.min(W.latitude,l),W.longitude=Math.min(W.longitude,f),X.latitude=Math.max(X.latitude,l),X.longitude=Math.max(X.longitude,f)}for(var h=0;h<s-1;++h)I(u[h],u[h+1],r,c,W,X);var E=u[s-1];n.subtract(E,u[s-2],G),n.normalize(G,G),n.multiplyByScalar(G,c,G),n.add(E,G,V),I(E,V,r,c,W,X),o===i.ROUNDED&&(r.cartesianToCartographic(V,q),l=q.latitude,f=q.longitude,W.latitude=Math.min(W.latitude,l),W.longitude=Math.min(W.longitude,f),X.latitude=Math.max(X.latitude,l),X.longitude=Math.max(X.longitude,f));var m=new T;return m.north=X.latitude,m.south=W.latitude,m.east=X.longitude,m.west=W.longitude,m}function M(e){e=u(e,u.EMPTY_OBJECT);var t=e.positions,r=e.width;this._positions=t,this._ellipsoid=f.clone(u(e.ellipsoid,f.WGS84)),this._vertexFormat=R.clone(u(e.vertexFormat,R.DEFAULT)),this._width=r,this._height=u(e.height,0),this._extrudedHeight=u(e.extrudedHeight,this._height),this._cornerType=u(e.cornerType,i.ROUNDED),this._granularity=u(e.granularity,p.RADIANS_PER_DEGREE),this._shadowVolume=u(e.shadowVolume,!1),this._workerName="createCorridorGeometry",this._rectangle=w(t,this._ellipsoid,r,this._cornerType),this.packedLength=1+t.length*n.packedLength+f.packedLength+R.packedLength+T.packedLength+6}var x=new n,C=new n,P=new n,D=new n,U=new n,L=new n,F=new n,b=new n,B=new n,z=new n,q=new r,G=new n,V=new n,W=new r,X=new r;M.pack=function(e,t,r){r=u(r,0);var a=e._positions,i=a.length;t[r++]=i;for(var o=0;o<i;++o,r+=n.packedLength)n.pack(a[o],t,r);return f.pack(e._ellipsoid,t,r),r+=f.packedLength,R.pack(e._vertexFormat,t,r),r+=R.packedLength,T.pack(e._rectangle,t,r),r+=T.packedLength,t[r++]=e._width,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._cornerType,t[r++]=e._granularity,t[r]=e._shadowVolume?1:0,t};var H=f.clone(f.UNIT_SPHERE),Y=new R,k=new T,Z={positions:void 0,ellipsoid:H,vertexFormat:Y,width:void 0,height:void 0,extrudedHeight:void 0,cornerType:void 0,granularity:void 0,shadowVolume:void 0};return M.unpack=function(e,t,r){t=u(t,0);for(var a=e[t++],i=new Array(a),o=0;o<a;++o,t+=n.packedLength)i[o]=n.unpack(e,t);var c=f.unpack(e,t,H);t+=f.packedLength;var l=R.unpack(e,t,Y);t+=R.packedLength;var d=T.unpack(e,t,k);t+=T.packedLength;var h=e[t++],E=e[t++],m=e[t++],p=e[t++],_=e[t++],y=1===e[t];return s(r)?(r._positions=i,r._ellipsoid=f.clone(c,r._ellipsoid),r._vertexFormat=R.clone(l,r._vertexFormat),r._width=h,r._height=E,r._extrudedHeight=m,r._cornerType=p,r._granularity=_,r._rectangle=T.clone(d),r._shadowVolume=y,r):(Z.positions=i,Z.width=h,Z.height=E,Z.extrudedHeight=m,Z.cornerType=p,Z.granularity=_,Z.shadowVolume=y,new M(Z))},M.createGeometry=function(r){var a=r._positions,i=r._height,u=r._width,s=r._extrudedHeight,c=i!==s,l=r._ellipsoid;a=A(a,l);var f=e(a,n.equalsEpsilon);if(!(f.length<2||u<=0)){var h,E=r._vertexFormat,m={ellipsoid:l,positions:f,width:u,cornerType:r._cornerType,granularity:r._granularity,saveAttributes:!0};if(c){var p=Math.max(i,s);s=Math.min(i,s),i=p,m.height=i,m.extrudedHeight=s,m.shadowVolume=r._shadowVolume,h=O(m,E)}else{h=S(o.computePositions(m),E,l),h.attributes.position.values=_.scaleToGeodeticHeight(h.attributes.position.values,i,l)}var T=h.attributes,R=t.fromVertices(T.position.values,void 0,3);return E.position||(h.attributes.position.values=void 0),new d({attributes:T,indices:h.indices,primitiveType:y.TRIANGLES,boundingSphere:R})}},M.createShadowVolume=function(e,t,n){var r=e._granularity,a=e._ellipsoid,i=t(r,a),o=n(r,a);return new M({positions:e._positions,width:e._width,cornerType:e._cornerType,ellipsoid:a,granularity:r,extrudedHeight:i,height:o,vertexFormat:R.POSITION_ONLY,shadowVolume:!0})},c(M.prototype,{rectangle:{get:function(){return this._rectangle}}}),M}),define("Workers/createCorridorGeometry",["../Core/CorridorGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,n){"use strict";function r(r,a){return t(a)&&(r=e.unpack(r,a)),r._ellipsoid=n.clone(r._ellipsoid),e.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function a(e,r,a){if(n(e)){a=t(a,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,i));++u);if(u===o)return a&&r(e[0],e[e.length-1],i)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,i)||(l.push(c),s=c);return a&&l.length>1&&r(l[0],l[l.length-1],i)&&l.shift(),l}}var i=r.EPSILON10;return a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,p=l*l*d*d,y=f*f*E*E,_=h*h*m*m,T=p+y+_,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,g=u.y,S=u.z,N=o;N.x=v.x*A*2,N.y=v.y*g*2,N.z=v.z*S*2;var O,w,I,M,x,C,P,U,D,L,b,F=(1-R)*e.magnitude(n)/(.5*e.magnitude(N)),B=0;do{F-=B,I=1/(1+F*A),M=1/(1+F*g),x=1/(1+F*S),C=I*I,P=M*M,U=x*x,D=C*I,L=P*M,b=U*x,O=p*C+y*P+_*U-1,w=p*D*A+y*L*g+_*b*S;B=O/(-2*w)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*I,c.y=f*M,c.z=h*x,c):new e(l*I,f*M,h*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,y=o(t,E,m,p,c);if(r(y)){var _=e.multiplyComponents(y,m,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),R=Math.atan2(_.y,_.x),v=Math.asin(_.z),A=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=v,a.height=A,a):new u(R,v,A)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],T=(p-y)/2/_;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),p=2*(i+l),y=2*(a+h),_=-n+u-f+d,T=2*(c-o),R=2*(i-l),v=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=E,t[1]=y,t[2]=R,t[3]=m,t[4]=_,t[5]=v,t[6]=p,t[7]=T,t[8]=A,t):new s(E,m,p,y,_,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,y=c*n,_=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=y,t[6]=h,t[7]=m,t[8]=_,t):new s(l,f,h,d,E,m,p,y,_)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,p),s.transpose(p,y),s.multiply(h,p,h),s.multiply(y,h,h),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)), +o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-d-p+_,R=2*(c-y),v=2*(f+m),A=2*(c+y),g=-s+d-p+_,S=2*(E-h),N=2*(f-m),O=2*(E+h),w=-s-d+p+_;return r[0]=T*i,r[1]=A*i,r[2]=N*i,r[3]=0,r[4]=R*o,r[5]=g*o,r[6]=O*o,r[7]=0,r[8]=v*u,r[9]=S*u,r[10]=w*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,y=d.x,_=d.y,T=d.z,R=r.x,v=r.y,A=r.z,g=u*-R+s*-v+c*-A,S=y*-R+_*-v+T*-A,N=E*R+m*v+p*A;return a(n)?(n[0]=u,n[1]=y,n[2]=-E,n[3]=0,n[4]=s,n[5]=_,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=g,n[13]=S,n[14]=N,n[15]=1,n):new l(u,s,c,g,y,_,T,S,-E,-m,-p,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,p=o+l,y=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=y,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],y=e[14],_=e[15],T=t[0],R=t[1],v=t[2],A=t[3],g=t[4],S=t[5],N=t[6],O=t[7],w=t[8],I=t[9],M=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*v+m*A,b=a*T+s*R+h*v+p*A,F=i*T+c*R+d*v+y*A,B=o*T+l*R+E*v+_*A,z=r*g+u*S+f*N+m*O,q=a*g+s*S+h*N+p*O,G=i*g+c*S+d*N+y*O,V=o*g+l*S+E*N+_*O,W=r*w+u*I+f*M+m*x,X=a*w+s*I+h*M+p*x,H=i*w+c*I+d*M+y*x,Y=o*w+l*I+E*M+_*x,k=r*C+u*P+f*U+m*D,j=a*C+s*P+h*U+p*D,Z=i*C+c*P+d*U+y*D,K=o*C+l*P+E*U+_*D;return n[0]=L,n[1]=b,n[2]=F,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],y=t[2],_=t[4],T=t[5],R=t[6],v=t[8],A=t[9],g=t[10],S=t[12],N=t[13],O=t[14],w=r*m+o*p+c*y,I=a*m+u*p+l*y,M=i*m+s*p+f*y,x=r*_+o*T+c*R,C=a*_+u*T+l*R,P=i*_+s*T+f*R,U=r*v+o*A+c*g,D=a*v+u*A+l*g,L=i*v+s*A+f*g,b=r*S+o*N+c*O+h,F=a*S+u*N+l*O+d,B=i*S+s*N+f*O+E;return n[0]=w,n[1]=I,n[2]=M,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=b,n[13]=F,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],y=t[5],_=t[6],T=t[7],R=t[8],v=r*h+o*d+c*E,A=a*h+u*d+l*E,g=i*h+s*d+f*E,S=r*m+o*p+c*y,N=a*m+u*p+l*y,O=i*m+s*p+f*y,w=r*_+o*T+c*R,I=a*_+u*T+l*R,M=i*_+s*T+f*R;return n[0]=v,n[1]=A,n[2]=g,n[3]=0,n[4]=S,n[5]=N,n[6]=O,n[7]=0,n[8]=w,n[9]=I,n[10]=M,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],v=e[10],A=e[14],g=e[3],S=e[7],N=e[11],O=e[15],w=v*O,I=A*N,M=p*O,x=A*S,C=p*N,P=v*S,U=m*O,D=A*g,L=m*N,b=v*g,F=m*S,B=p*g,z=w*h+x*d+C*E-(I*h+M*d+P*E),q=I*f+U*d+b*E-(w*f+D*d+L*E),G=M*f+D*h+F*E-(x*f+U*h+B*E),V=P*f+L*h+B*d-(C*f+b*h+F*d),W=I*a+M*i+P*o-(w*a+x*i+C*o),X=w*r+D*i+L*o-(I*r+U*i+b*o),H=x*r+U*a+B*o-(M*r+D*a+F*o),Y=C*r+b*a+F*i-(P*r+L*a+B*i);w=i*E,I=o*d,M=a*E,x=o*h,C=a*d,P=i*h,U=r*E,D=o*f,L=r*d,b=i*f,F=r*h,B=a*f;var k=w*S+x*N+C*O-(I*S+M*N+P*O),j=I*g+U*N+b*O-(w*g+D*N+L*O),Z=M*g+D*S+F*O-(x*g+U*S+B*O),K=P*g+L*S+B*N-(C*g+b*S+F*N),J=M*v+P*A+I*p-(C*A+w*p+x*v),Q=L*A+w*m+D*v-(U*v+b*A+I*m),$=U*p+B*A+x*m-(F*A+M*m+D*p),ee=F*v+C*m+b*p-(L*p+B*v+P*m),te=r*z+a*q+i*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var y=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(a(t,e.ZERO)),this.radius=a(n,0)}var E=new e,m=new e,p=new e,y=new e,_=new e,T=new e,R=new e,v=new e,A=new e,g=new e,S=new e,N=new e,O=4/3*n.PI;d.fromPoints=function(t,n){if(i(n)||(n=new d),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],R),o=e.clone(a,E),u=e.clone(a,m),s=e.clone(a,p),c=e.clone(a,y),l=e.clone(a,_),f=e.clone(a,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],a);var O=a.x,w=a.y,I=a.z;O<o.x&&e.clone(a,o),O>c.x&&e.clone(a,c),w<u.y&&e.clone(a,u),w>l.y&&e.clone(a,l),I<s.z&&e.clone(a,s),I>f.z&&e.clone(a,f)}var M=e.magnitudeSquared(e.subtract(c,o,v)),x=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(f,s,v)),P=o,U=c,D=M;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var b=e.magnitudeSquared(e.subtract(U,L,v)),F=Math.sqrt(b),B=g;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,v),.5,N),G=0;for(r=0;r<h;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,q,v));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(a,L,v));if(W>b){var X=Math.sqrt(W);F=.5*(F+X),b=F*F;var H=X-F;L.x=(F*L.x+H*a.x)/X,L.y=(F*L.y+H*a.y)/X,L.z=(F*L.z+H*a.z)/X}}return F<G?(e.clone(L,n.center),n.radius=F):(e.clone(q,n.center),n.radius=G),n};var w=new u,I=new e,M=new e,x=new t,C=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(i(u)||(u=new d),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=a(n,w),h.southwest(t,x),x.height=r,h.northeast(t,C),C.height=o;var s=n.project(x,I),c=n.project(C,M),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new d),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(i(o)||(o=new d),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=a(n,e.ZERO),r=a(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,m),f=e.clone(u,p),h=e.clone(u,y),O=e.clone(u,_),w=e.clone(u,T),I=t.length;for(s=0;s<I;s+=r){var M=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>h.x&&e.clone(u,h),x<l.y&&e.clone(u,l),x>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>w.z&&e.clone(u,w)}var P=e.magnitudeSquared(e.subtract(h,c,v)),U=e.magnitudeSquared(e.subtract(O,l,v)),D=e.magnitudeSquared(e.subtract(w,f,v)),L=c,b=h,F=P;U>F&&(F=U,L=l,b=O),D>F&&(F=D,L=f,b=w);var B=A;B.x=.5*(L.x+b.x),B.y=.5*(L.y+b.y),B.z=.5*(L.z+b.z);var z=e.magnitudeSquared(e.subtract(b,B,v)),q=Math.sqrt(z),G=g;G.x=c.x,G.y=l.y,G.z=f.z;var V=S;V.x=h.x,V.y=O.y,V.z=w.z;var W=e.multiplyByScalar(e.add(G,V,v),.5,N),X=0;for(s=0;s<I;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,v));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,B,v));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;B.x=(q*B.x+j*u.x)/k,B.y=(q*B.y+j*u.y)/k,B.z=(q*B.z+j*u.z)/k}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new d),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=R;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,E),s=e.clone(a,m),c=e.clone(a,p),l=e.clone(a,y),f=e.clone(a,_),h=e.clone(a,T),O=t.length;for(o=0;o<O;o+=3){var w=t[o]+n[o],I=t[o+1]+n[o+1],M=t[o+2]+n[o+2];a.x=w,a.y=I,a.z=M,w<u.x&&e.clone(a,u),w>l.x&&e.clone(a,l),I<s.y&&e.clone(a,s),I>f.y&&e.clone(a,f),M<c.z&&e.clone(a,c),M>h.z&&e.clone(a,h)}var x=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(f,s,v)),P=e.magnitudeSquared(e.subtract(h,c,v)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=h);var b=A;b.x=.5*(U.x+D.x),b.y=.5*(U.y+D.y),b.z=.5*(U.z+D.z);var F=e.magnitudeSquared(e.subtract(D,b,v)),B=Math.sqrt(F),z=g;z.x=u.x,z.y=s.y,z.z=c.z;var q=S;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,v),.5,N),V=0;for(o=0;o<O;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(a,G,v));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(a,b,v));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var Y=H-B;b.x=(B*b.x+Y*a.x)/H,b.y=(B*b.y+Y*a.y)/H,b.z=(B*b.z+Y*a.z)/H}}return B<V?(e.clone(b,r.center),r.radius=B):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){i(r)||(r=new d);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},d.fromEllipsoid=function(t,n){return i(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(i(n)||(n=new d),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,b=new e;d.fromOrientedBoundingBox=function(t,n){i(n)||(n=new d);var r=t.halfAxes,a=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,b);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},d.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=a(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=a(t,0),i(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var F=new e,B=new e;d.union=function(t,n,r){i(r)||(r=new d);var a=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,a,F),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,a,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,z));return a>r.radius&&(r.radius=a),r},d.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?s.OUTSIDE:o<a?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return i(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return i(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,a){i(a)||(a=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var V=new e,W=new e,X=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=a(n,K);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,y=0;y<p;++y){var _=E[y];e.add(o,_,_);var T=i.cartesianToCartographic(_,k);n.project(T,_)}r=d.fromPoints(E,r),o=r.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return O*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){ +for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(v)&&(v=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function i(){return a()&&A}function o(){if(!t(g)&&(g=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(g=!0,S=r(e[1]))}return g}function u(){return o()&&S}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(N=!0,O=r(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(w)){w=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(w=!0,I=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(w=!0,I=r(e[1]))}return w}function f(){return l()&&I}function h(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(M=!0,x=r(e[1]))}return M}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function y(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function _(){if(!t(b)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;b=t(n)&&""!==n,b&&(L=n)}return b}function T(){return _()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,g,S,N,O,w,I,M,x,C,P,U,D,L,b,F={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return F.supportsFullscreen=function(){return n.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,a=(n-r)/n,i=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,i),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,p=m*m,y=p*m,_=p*p,T=1+m-3*p/4+5*y/4-175*_/64,R=1-m+15*p/8-35*y/8,v=1-3*m+35*p/4,A=1-5*m,g=T*l-R*Math.sin(2*l)*m/2-v*Math.sin(4*l)*p/16-A*Math.sin(6*l)*y/48-5*Math.sin(8*l)*_/512,S=e._constants;S.a=n,S.b=r,S.f=a,S.cosineHeading=i,S.sineHeading=o,S.tanU=u,S.cosineU=s,S.sineU=c,S.sigma=l,S.sineAlpha=f,S.sineSquaredAlpha=h,S.cosineSquaredAlpha=d,S.cosineAlpha=E,S.u2Over4=m,S.u4Over16=p,S.u6Over64=y,S.u8Over256=_,S.a0=T,S.a1=R,S.a2=v,S.a3=A,S.distanceRatio=g}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,a,i,o){var u=c(e,n);return(1-u)*e*t*(r+u*a*(o+u*i*(2*o*o-1)))}function f(e,t,n,r,a,i,o){var s,c,f,h,d,E=(t-n)/t,m=i-r,p=Math.atan((1-E)*Math.tan(a)),y=Math.atan((1-E)*Math.tan(o)),_=Math.cos(p),T=Math.sin(p),R=Math.cos(y),v=Math.sin(y),A=_*R,g=_*v,S=T*v,N=T*R,O=m,w=u.TWO_PI,I=Math.cos(O),M=Math.sin(O);do{I=Math.cos(O),M=Math.sin(O);var x=g-N*I;f=Math.sqrt(R*R*M*M+x*x),c=S+A*I,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=A*M/f,h=1-C*C),w=O,d=c-2*S/h,isNaN(d)&&(d=0),O=m+l(E,C,h,s,f,c,d)}while(Math.abs(O-w)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,b=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),F=n*U*(s-b),B=Math.atan2(R*M,g-N*I),z=Math.atan2(_*M,g*I-N);e._distance=F,e._startHeading=B,e._endHeading=z,e._uSquared=P}function h(n,r,a,i){e.normalize(i.cartographicToCartesian(r,m),E),e.normalize(i.cartographicToCartesian(a,m),m);f(n,i.maximumRadius,i.minimumRadius,r.longitude,r.latitude,a.longitude,a.latitude),n._start=t.clone(r,n._start),n._end=t.clone(a,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,i){var u=r(i,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(n)&&h(this,e,n,u)}var E=new e,m=new e;return i(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,i=r.distanceRatio+e/r.b,o=Math.cos(2*i),u=Math.cos(4*i),s=Math.cos(6*i),c=Math.sin(2*i),f=Math.sin(4*i),h=Math.sin(6*i),d=Math.sin(8*i),E=i*i,m=i*E,p=r.u8Over256,y=r.u2Over4,_=r.u6Over64,T=r.u4Over16,R=2*m*p*o/3+i*(1-y+7*T/4-15*_/4+579*p/64-(T-15*_/4+187*p/16)*o-(5*_/4-115*p/16)*u-29*p*s/16)+(y/2-T+71*_/32-85*p/16)*c+(5*T/16-5*_/4+383*p/96)*f-E*((_-11*p/2)*c+5*p*f/2)+(29*_/96-29*p/16)*h+539*p*d/1536,v=Math.asin(Math.sin(R)*r.cosineAlpha),A=Math.atan(r.a/r.b*Math.tan(v));R-=r.sigma;var g=Math.cos(2*r.sigma+R),S=Math.sin(R),N=Math.cos(R),O=r.cosineU*N,w=r.sineU*S,I=Math.atan2(S*r.sineHeading,O-w*r.cosineHeading),M=I-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,S,N,g);return a(n)?(n.longitude=this._start.longitude+M,n.latitude=A,n.height=0,n):new t(this._start.longitude+M,A,0)},d}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,y=4*E*p-m*m;if(y<0){var _,T,R;h*f>=l*d?(_=o,T=E,R=-2*u*E+o*m):(_=c,T=p,R=-c*m+2*s*p);var v=R<0?-1:1,A=-v*Math.abs(_)*Math.sqrt(-y);i=-R+A;var g=i/2,S=g<0?-Math.pow(-g,1/3):Math.pow(g,1/3),N=i===A?-S:-T/S;return a=T<=0?S+N:-R/(S*S+N*N+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var O=E,w=-2*u*E+o*m,I=p,M=-c*m+2*s*p,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-w)/3);a=2*Math.sqrt(-O);var U=Math.cos(P);i=a*U;var D=a*(-U/2-C*Math.sin(P)),L=i+D>2*u?i-u:D-u,b=o,F=L/b;P=Math.abs(Math.atan2(c*x,-M)/3),a=2*Math.sqrt(-I),U=Math.cos(P),i=a*U,D=a*(-U/2-C*Math.sin(P));var B=-c,z=i+D<2*s?i+s:D+s,q=B/z,G=b*z,V=-L*z-b*B,W=L*B,X=(s*V-u*W)/(-u*V+s*G);return F<=X?F<=q?X<=q?[F,X,q]:[F,q,X]:[q,F,X]:F<=q?[X,F,q]:X<=q?[X,q,F]:[q,X,F]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],y=E[1];if(p>=0&&y>=0){var _=Math.sqrt(p),T=Math.sqrt(y);return[h-T,h-_,h+_,h+T]}if(p>=0&&y<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&y>=0)return m=Math.sqrt(y),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),v=(s+d-c/R)/2,A=(s+d+c/R)/2,g=r.computeRealRoots(1,R,v),S=r.computeRealRoots(1,-R,A);return 0!==g.length?(g[0]+=h,g[1]+=h,0!==S.length?(S[0]+=h,S[1]+=h,g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>S[0]&&g[0]<S[1]?[S[0],g[0],S[1],g[1]]:[g[0],S[0],g[1],S[1]]):g):0!==S.length?(S[0]+=h,S[1]+=h,S):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],y=a-p,_=y*y,T=t/2,R=y/2,v=_-4*o,A=_+4*Math.abs(o),g=c-4*p,S=c+4*Math.abs(p);if(p<0||v*S<g*A){var N=Math.sqrt(g);E=N/2,m=0===N?0:(t*R-i)/N}else{var O=Math.sqrt(v);E=0===O?0:(t*R-i)/O,m=O/2}var w,I;0===T&&0===E?(w=0,I=0):n.sign(T)===n.sign(E)?(w=T+E,I=p/w):(I=T-E,w=p/I);var M,x;0===R&&0===m?(M=0,x=0):n.sign(R)===n.sign(m)?(M=R+m,x=o/M):(x=R-m,M=o/x);var C=r.computeRealRoots(1,w,M),P=r.computeRealRoots(1,I,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,A);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-v)),T.push(new e(a,i*R,i*v)),2===l.length){var A=l[1],g=Math.sqrt(Math.max(1-A*A,0));T.push(new e(a,i*A,i*-g)),T.push(new e(a,i*A,i*g))}return T}var S=_*_,N=y*y,O=E*E,w=_*y,I=O+N,M=2*(m*E+w),x=2*p*E+m*m-N+S,C=2*(p*m-w),P=p*p-S;if(0===I&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(I,M,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,b=l[D],F=b*b,B=Math.max(1-F,0),z=Math.sqrt(B);L=o.sign(E)===o.sign(p)?d(E*F+p,m*b,o.EPSILON12):o.sign(p)===o.sign(m*b)?d(E*F,m*b+p,o.EPSILON12):d(E*F+m*b,p,o.EPSILON12);var q=d(y*b,_,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*b,i*z)):G>0?T.push(new e(a,i*b,i*-z)):0!==z?(T.push(new e(a,i*b,i*-z)),T.push(new e(a,i*b,i*z)),++D):T.push(new e(a,i*b,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,y=new e,_=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,p),v=e.subtract(i,r,y),A=e.cross(E,v,_),g=e.dot(m,A);if(u){if(g<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,A))<0||l>g)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>g)return;h=e.dot(v,c)/g}else{if(Math.abs(g)<o.EPSILON6)return;var S=1/g;if(s=e.subtract(d,r,T),(l=e.dot(s,A)*S)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*S)<0||l+f>1)return;h=e.dot(v,c)*S}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var g=new l;m.lineSegmentSphere=function(t,n,a,i){var o=g;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var S=new e,N=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,S),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,p=r/s;return m<p?new i(m,p):{start:p,stop:m}}var y=Math.sqrt(r/a);return new i(y,y)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var O=new e,w=new e,I=new e,M=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,b=new u,F=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,M),d=e.normalize(e.cross(h,f,w),w),m=e.normalize(e.cross(f,d,I),I),p=C;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var y=u.transpose(p,P),_=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0 +;var v,A,g=u.multiply(u.multiply(y,T,b),R,b),S=u.multiply(u.multiply(g,_,F),p,F),N=u.multiplyByVector(g,a,x),G=E(S,e.negate(N,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(_,u.multiplyByVector(p,G[H],B),B);var Y=e.normalize(e.subtract(v,a,M),M),k=e.dot(Y,i);k>X&&(X=k,W=e.clone(v,W))}var j=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(W,a,M))*Math.sqrt(1-X*X),A=c?-A:A,j.height=A,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,a){n(a)||(a=new e);var i=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,i,c);return e.subtract(r,o,a)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=S;r.length=e;var a;if(t===n){for(a=0;a<e;a++)r[a]=t;return r}var i=n-t,o=i/e;for(a=0;a<e;a++){var u=t+a*o;r[a]=u}return r}function d(t,n,r,a,i,o,u,s){var c=a.scaleToGeodeticSurface(t,I),l=a.scaleToGeodeticSurface(n,M),f=E.numberOfPoints(t,n,r),d=a.cartesianToCartographic(c,N),m=a.cartesianToCartographic(l,O),p=h(f,i,o);x.setEndPoints(d,m);var y=x.surfaceDistance/f,_=s;d.height=i;var T=a.cartographicToCartesian(d,w);e.pack(T,u,_),_+=3;for(var R=1;R<f;R++){var v=x.interpolateUsingSurfaceDistance(R*y,O);v.height=p[R],T=a.cartographicToCartesian(v,w),e.pack(T,u,_),_+=3}return _}var E={};E.numberOfPoints=function(t,n,r){var a=e.distance(t,n);return Math.ceil(a/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),a=0;a<n;a++){var i=e[a];r[a]=t.cartesianToCartographic(i,m).height}return r};var p=new l,y=new e,_=new e,T=new f(e.UNIT_X,0),R=new e,v=new f(e.UNIT_X,0),A=new e,g=new e,S=[],N=new t,O=new t,w=new e,I=new e,M=new e,x=new o;return E.wrapLongitude=function(t,a){var i=[],o=[];if(r(t)&&t.length>0){a=n(a,l.IDENTITY);var s=l.inverseTransformation(a,p),c=l.multiplyByPoint(s,e.ZERO,y),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,_),_),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,v),S=1;i.push(e.clone(t[0]));for(var N=i[0],O=t.length,w=1;w<O;++w){var I=t[w];if(f.getPointDistance(m,N)<0||f.getPointDistance(m,I)<0){var M=u.lineSegmentPlane(N,I,d,A);if(r(M)){var x=e.multiplyByScalar(h,5e-9,g);f.getPointDistance(d,N)<0&&e.negate(x,x),i.push(e.add(M,x,new e)),o.push(S+1),e.negate(x,x),i.push(e.add(M,x,new e)),S=1}}i.push(e.clone(t[w])),S++,N=I}o.push(S)}return{positions:i,lengths:o}},E.generateArc=function(t){r(t)||(t={});var a=t.positions,o=a.length,u=n(t.ellipsoid,i.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(a[0],I);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,w);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var p=t.minDistance;if(!r(p)){var y=n(t.granularity,c.RADIANS_PER_DEGREE);p=c.chordLength(y,u.maximumRadius)}var _,T=0;for(_=0;_<o-1;_++)T+=E.numberOfPoints(a[_],a[_+1],p);var R=3*(T+1),v=new Array(R),A=0;for(_=0;_<o-1;_++){A=d(a[_],a[_+1],p,u,f?l[_]:l,f?l[_+1]:l,v,A)}S.length=0;var g=a[o-1],O=u.cartesianToCartographic(g,N);O.height=f?l[o-1]:l;var M=u.cartographicToCartesian(O,w);return e.pack(M,v,R-3),v},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,a=new Array(r),i=0;i<r;i++)a[i]=e.unpack(n,3*i);return a},E}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var y=n.minimum;y.x=a,y.y=o,y.z=u;var _=n.maximum;_.x=s,_.y=c,_.z=l;var T=e.add(y,_,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=y,m(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(n,_)),f=[],l=_-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=y,d.reject(h))},E=function(e){f.push(e),--c||(E=m=y,d.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,_).then(t,n,r)}function f(){return h(arguments,_)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function y(){}function _(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,y;if("%%"==e)return"%";for(var _=!1,T="",R=!1,v=!1,A=" ",g=s.length,S=0;s&&S<g;S++)switch(s.charAt(S)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(S+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(y),_,c,f,R,A);case"c":return u(String.fromCharCode(+y),_,c,f,R);case"b":return o(y,2,v,_,c,f,R);case"o":return o(y,8,v,_,c,f,R);case"x":return o(y,16,v,_,c,f,R);case"X":return o(y,16,v,_,c,f,R).toUpperCase();case"u":return o(y,10,v,_,c,f,R);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),E=d<0?"-":T,y=E+a(String(Math.abs(d)),f,"0",!1),i(y,E,_,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=E+Math.abs(d)[m](f),i(y,E,_,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var n=m.leapSeconds,r=t(n,_,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){_.julianDate=e;var r=m.leapSeconds,a=t(r,_,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var p=new i,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,g=/^(\d{4})-?(\d{2})-?(\d{2})$/,S=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+S.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+S.source,w=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+S.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,p=0,_=0,S=0,I=u[0],M=u[1];if(null!==(u=I.match(g)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(R)))n=+u[1],s=+u[2];else if(null!==(u=I.match(T)))n=+u[1];else{var x;if(null!==(u=I.match(v)))n=+u[1],x=+u[2],i=o(n);else if(null!==(u=I.match(A))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(M)){u=M.match(w),null!==u?(h=+u[1],p=+u[2],_=+u[3],S=1e3*+(u[4]||0),D=5):(u=M.match(O),null!==u?(h=+u[1],p=+u[2],_=60*+(u[3]||0),D=4):null!==(u=M.match(N))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],b=+u[D+1],F=+(u[D+2]||0);switch(L){case"+":h-=b,p-=F;break;case"-":h+=b,p+=F;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var B=60===_;for(B&&_--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:y[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:y[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:y[s-1],l+=a;var z=E(n,s,l,h,p,_,S);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var I=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,I);r(a)||(m.addSeconds(e,-1,I),a=h(I,I),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),n&&(v+=1),r(t)?(t.year=y,t.month=p,t.day=E,t.hour=_,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=n,t):new i(y,p,E,_,R,v,A,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,p);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var n=m.leapSeconds,r=t(n,_,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,a,i){i=e(i,!1);var o,u,s,c={},l=t(r),f=t(a);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&i&&"object"==typeof u&&a.hasOwnProperty(o)?(s=a[o],c[o]="object"==typeof s?n(u,s,i):u):c[o]=u);if(f)for(o in a)a.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=a[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(a[n])||(a[n]=!0,console.warn(e(r,n)))}var a={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(e,t){return a._implementation(e,t,document)}return a._implementation=function(n,r,a){r=t(r,t(a.baseURI,a.location.href));var i=new e(r);return new e(n).resolve(i).toString()},a}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var a="",i=n.lastIndexOf("/");return-1!==i&&(a=n.substring(0,i+1)),r?(n=new e(n),t(n.query)&&(a+="?"+n.query),t(n.fragment)&&(a+="#"+n.fragment),a):a}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,a=r.lastIndexOf("/");return-1!==a&&(r=r.substr(a+1)),a=r.lastIndexOf("."),r=-1===a?"":r.substr(a+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,a=n.protocol;return n.href=t,n.href=n.href,a!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var a=e[r],i=encodeURIComponent(r)+"=";if(n(a))for(var o=0,u=a.length;o<u;++o)t+=i+encodeURIComponent(a[o])+"&";else t+=i+encodeURIComponent(a)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var a=t.replace(/\+/g,"%20").split(/[&;]/),i=0,o=a.length;i<o;++i){var u=a[i].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT);var a=e(t.throttleByServer,!1),i=a||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return a.prototype.cancel=function(){this.cancelled=!0},a.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new a(this)},a}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict" +;function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function a(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,a=-1,i=0;i<n.length;i++)if(n[i]===e&&r[i]===t){a=i;break}return-1!==a&&(this._insideRaiseEvent?(this._toRemove.push(a),n[a]=void 0,r[a]=void 0):(n.splice(a,1),r.splice(a,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,i=n.length;for(e=0;e<i;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((i=u.length)>0){for(u.sort(a),e=0;e<i;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--v.numberOfActiveRequests,--N[e.serverKey],w.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){return function(t){e.state!==c.CANCELLED&&(++v.numberOfFailedRequests,--v.numberOfActiveRequests,--N[e.serverKey],w.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function y(e){var t=E(e);return e.state=c.ACTIVE,S.push(e),++v.numberOfActiveRequests,++v.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(m(e)).otherwise(p(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++v.numberOfCancelledRequests,e.deferred.reject(),t&&(--v.numberOfActiveRequests,--N[e.serverKey],++v.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){v.numberOfAttemptedRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(v.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+v.numberOfAttemptedRequests),v.numberOfActiveRequests>0&&console.log("Number of active requests: "+v.numberOfActiveRequests),v.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+v.numberOfCancelledRequests),v.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+v.numberOfCancelledActiveRequests),v.numberOfFailedRequests>0&&console.log("Number of failed requests: "+v.numberOfFailedRequests),T())}var v={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,g=new o({comparator:l});g.maximumLength=A,g.reserve(A);var S=[],N={},O="undefined"!=typeof document?new e(document.location.href):new e,w=new i;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=w,a(f,{statistics:{get:function(){return v}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;g.length>e;){var t=g.pop();_(t)}A=e,g.maximumLength=e,g.reserve(e)}}}),f.update=function(){var e,t,n=0,r=S.length;for(e=0;e<r;++e)t=S[e],t.cancelled&&_(t),t.state===c.ACTIVE?n>0&&(S[e-n]=t):++n;S.length-=n;var a=g.internalArray,i=g.length;for(e=0;e<i;++e)h(a[e]);g.resort();for(var o=Math.max(f.maximumRequests-S.length,0),u=0;u<o&&g.length>0;)t=g.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(y(t),++u):_(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=N[a];return r(i)||(N[a]=0),a},f.request=function(e){if(s(e.url)||u(e.url))return w.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++v.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return y(e);if(!(S.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=g.insert(e);if(r(t)){if(t===e)return;_(t)}return E(e)}},f.clearForSpecs=function(){for(;g.length>0;){_(g.pop())}for(var e=S.length,t=0;t<e;++t)_(S[t]);S.length=0,N={},v.numberOfAttemptedRequests=0,v.numberOfActiveRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0,v.numberOfFailedRequests=0,v.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=g,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,y,_,T,R,v,A,g,S,N){"use strict";function O(e,t){var n=e.query;if(!i(n)||0===n.length)return{};var a;if(-1===n.indexOf("=")){var o={};o[n]=void 0,a=o}else a=y(n);t._queryParameters=r(t._queryParameters,a),e.query=void 0}function w(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||i(n[r[0]])?e.query=p(n):e.query=r[0]}function I(e,t){return i(e)?i(e.clone)?e.clone():n(e):t}function M(e){if(e.state===v.ISSUED||e.state===v.ACTIVE)throw new A("The Resource is already being fetched.");e.state=v.UNISSUED,e.deferred=void 0}function x(e){e=a(e,a.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=I(e.templateValues,{}),this._queryParameters=I(e.queryParameters,{}),this.headers=I(e.headers,{}),this.request=a(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=a(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var a=N.defer();return x._Implementations.createImage(n,r&&t,a),a.promise};var r=R.request(n);if(i(r))return r.otherwise(function(r){return n.state!==v.FAILED?N.reject(r):e.retryOnError(r).then(function(a){return a?(n.state=v.UNISSUED,n.deferred=void 0,C(e,t)):N.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var a=e.request;a.url=e.url,a.requestFunction=function(){var t=N.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},x._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(a);if(i(o))return o.otherwise(function(r){return a.state!==v.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(a.state=v.UNISSUED,a.deferred=void 0,P(e,t,n)):N.reject(r)})})}function U(e,t){M(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var a=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=x._Implementations.loadWithXhr(e.url,a,s,c,o,l,u);return i(f)&&i(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var a=R.request(n);if(i(a))return a.then(function(e){return e}).otherwise(function(r){return n.state!==v.FAILED?N.reject(r):e.retryOnError(r).then(function(a){return a?(n.state=v.UNISSUED,n.deferred=void 0,e.fetch(t)):N.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function b(e,t){t=a(t,"");var n=e[1],r=!!e[2],i=e[3];switch(t){case"":case"text":return D(r,i);case"arraybuffer":return L(r,i);case"blob":var o=L(r,i);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,i),n);case"json":return JSON.parse(D(r,i))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();x.createIfNeeded=function(e,t){if(e instanceof x)return e.clone();if("string"!=typeof e)return e;var n=I(t,{});return n.url=e,new x(n)},o(x,{isBlobSupported:{get:function(){return F}}}),o(x.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new S(e);O(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),x.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new S(this._url);e&&w(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),a=this._templateValues,o=Object.keys(a);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=a[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&i(this.proxy)&&(r=this.proxy.getURL(r)),r},x.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},x.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},x.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,i(e.url)){var n=new S(e.url);O(n,t),n.fragment=void 0,t._url=n.resolve(new S(l(this._url))).toString()}return i(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),i(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),i(e.headers)&&(t.headers=r(e.headers,t.headers)),i(e.proxy)&&(t.proxy=e.proxy),i(e.request)?t.request=e.request:t.request=this.request.clone(),i(e.retryCallback)&&(t.retryCallback=e.retryCallback),i(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},x.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var n=this;return N(t(this,e)).then(function(e){return++n._retryCount,e})},x.prototype.clone=function(e){return i(e)||(e=new x({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},x.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},x.prototype.appendForwardSlash=function(){this._url=e(this._url)},x.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},x.fetchArrayBuffer=function(e){return new x(e).fetchArrayBuffer()},x.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},x.fetchBlob=function(e){return new x(e).fetchBlob()},x.prototype.fetchImage=function(e,t){if(i(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=a(e,!1),t=a(t,!0),M(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var n=this.fetchBlob();if(i(n)){var r,o;return n.then(function(e){if(i(e)){o=e;var t=window.URL.createObjectURL(e);return r=new x({url:t}),C(r)}}).then(function(e){if(i(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return i(r)&&window.URL.revokeObjectURL(r.url),N.reject(e)})}},x.fetchImage=function(e){return new x(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},x.prototype.fetchText=function(){return this.fetch({responseType:"text"})},x.fetchText=function(e){return new x(e).fetchText()},x.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(i(e))return e.then(function(e){if(i(e))return JSON.parse(e)})},x.fetchJson=function(e){return new x(e).fetchJson()},x.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},x.fetchXML=function(e){return new x(e).fetchXML()},x.prototype.fetchJsonp=function(e){e=a(e,"callback"),M(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(i(window[t]));return P(this,e,t)},x.fetchJsonp=function(e){return new x(e).fetchJsonp(e.callbackParameterName)},x.prototype.fetch=function(e){return e=I(e,a.EMPTY_OBJECT),e.method="GET",U(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return x.fetch=function(e){return new x(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x.prototype.post=function(e,n){return t.defined("data",e),n=I(n,{}),n.method="POST",n.data=e,U(this,n)},x.post=function(e){return new x(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x._Implementations={},x._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(g.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},x._Implementations.loadWithXhr=function(e,t,n,r,a,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(b(s,t));var c=new XMLHttpRequest;if(g.contains(e)&&(c.withCredentials=!0),i(u)&&i(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),i(a))for(var l in a)a.hasOwnProperty(l)&&c.setRequestHeader(l,a[l]);i(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!i(e)||i(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&i(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!i(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},x._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var a=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,a.removeChild(r)},r.onerror=function(e){n.reject(e)},a.appendChild(r)},x._DefaultImplementations={},x._DefaultImplementations.createImage=x._Implementations.createImage,x._DefaultImplementations.loadWithXhr=x._Implementations.loadWithXhr,x._DefaultImplementations.loadAndExecuteScript=x._Implementations.loadAndExecuteScript,x.DEFAULT=c(new x({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),x}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=s.createIfNeeded(t.url),i=this;this._downloadPromise=e(a.fetchJson(),function(e){E(i,e)},function(){i._dataError="An error occurred while retrieving the EOP data from the URL "+a.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,y=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,R=0,v=p.length;R<v;R+=e._columnCount){var A=p[R+a],g=p[R+m],S=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(S,g,f.TAI);if(y.push(N),T){if(g!==_&&r(_)){var O=o.leapSeconds,w=t(O,N,d);if(w<0){var I=new u(N,g);O.splice(~w,0,I)}}_=g}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function y(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],y=n[d+e._ut1MinusUtcSecondsColumn],_=y-E;if(_>.5||_<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=y:y-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,y),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,y(this,i,this._samples,e,s,l,n),n}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,a){"use strict";function i(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=d.exec(r);if(null!==a)return a[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:i(),l=new r({url:e})}function u(e){return a.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(a.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,a[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:a}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)y[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=y[m]);T[E]*=_[E];var v=3*(s+E);n.x+=T[E]*d[v++],n.y+=T[E]*d[v++],n.s+=T[E]*d[v]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,y=0;d>h&&(y=1),E>h&&E>d&&(y=2);var _=p[y],T=p[_];n=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var R=f;R[y]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*n,R[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*n,R[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,y=new e,_=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),_),s.multiply(_,R,_),_.w<0&&s.negate(_,_),s.computeAxis(_,p);var u=s.computeAngle(_);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,g=new s,S=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=A=s.negate(t,A)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return g=s.multiplyByScalar(e,Math.sin((1-n)*u),g),S=s.multiplyByScalar(i,Math.sin(n*u),S),r=s.add(g,S,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var N=new e,O=new e,w=new s,I=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,w);s.multiply(i,r,I);var o=s.log(I,N);s.multiply(i,t,I);var u=s.log(I,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,w),s.multiply(n,w,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,w),u=s.slerp(n,r,a,I);return s.slerp(o,u,2*a*(1-a),i)};for(var M=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var b=L+1,F=2*b+1;C[L]=1/(b*F),P[L]=b/F}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,M);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,w),u=s.fastSlerp(n,r,a,I);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){ +return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,y,_,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},g={},S={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,O=new n,w=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=v[e][t],i=e+t;return u(g[i])?r=g[i]:(r=function(r,i,s){if(u(s)||(s=new y),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(A[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(A[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(A[a],0,w),"east"!==a&&"west"!==a&&n.multiplyByScalar(w,c,w)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,S.up);var l=S.up,h=S.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,S.east),n.cross(l,h,S.north),n.multiplyByScalar(S.up,-1,S.down),n.multiplyByScalar(S.east,-1,S.west),n.multiplyByScalar(S.north,-1,S.south),N=S[e],O=S[t],w=S[a]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=w.x,s[9]=w.y,s[10]=w.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},g[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var I=new _,M=new n(1,1,1),x=new y;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,I),s=y.fromTranslationQuaternionRotationScale(n.ZERO,u,M,x);return i=a(e,r,i),y.multiply(i,s,i)};var C=new y,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=y.getRotation(i,P);return _.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),b=new l(0,0,0,0,0,0),F=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,b);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,B),h=p.multiply(l,f,F),d=e.dayNumber,y=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,_=d-2451545,v=y/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(_+v);A=A%1*m.TWO_PI;var g=p.fromRotationZ(A,B),S=p.multiply(h,g,F),N=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),w=Math.sin(n.xPoleWander),I=Math.sin(n.yPoleWander),M=r-2451545+a/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=B;return U[0]=N*C,U[1]=N*P,U[2]=w,U[3]=-O*P+I*w*C,U[4]=O*C+I*w*P,U[5]=-I*N,U[6]=-I*P-O*w*C,U[7]=I*C-O*w*P,U[8]=O*N,p.multiply(S,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return y.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var W=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new p,j=new y,Z=new y;return R.basisTo2D=function(e,t,r){var a=y.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,r);return y.multiply(W,f,r),y.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=y.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(W,o,r),y.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var y=new h,_=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=y;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,_);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,_)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=y;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,_);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,_));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var a=e[r];U=t.cartesianToCartographic(a,U),n[r]=U.height,e[r]=t.scaleToGeodeticSurface(a,a)}return n}function d(e,n,r,a){var i,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/a),l=new Array(c);if(n===r){for(i=0;i<c;i++)l[i]=n;return l.push(r),l}var f=r-n,h=f/c;for(i=1;i<c;i++){var d=n+i*h;l[i]=d}return l[0]=n,l.push(r),l}function E(n,r,a,o){var u=new i(a,o),s=u.projectPointOntoPlane(t.add(a,n,D),D),c=u.projectPointOntoPlane(t.add(a,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function m(e,n,r,a,i,o,c,l){var h=G,d=V;F=f.eastNorthUpToFixedFrame(e,i,F),h=s.multiplyByPointAsVector(F,b,h),h=t.normalize(h,h);var m=E(h,n,e,i);z=u.fromRotationZ(m,z),W.z=o,F=s.multiplyTransformation(F,s.fromRotationTranslation(z,W,B),F);var p=q;p[0]=c;for(var y=0;y<l;y++)for(var _=0;_<r.length;_+=3)d=t.fromArray(r,_,d),d=u.multiplyByVector(p,d,d),d=s.multiplyByPoint(F,d,d),a.push(d.x,d.y,d.z);return a}function p(e,n,r,a,i,o,u){for(var s=0;s<e.length;s+=3){a=m(t.fromArray(e,s,X),n,r,a,i,o[s/3],u,1)}return a}function y(e,t){var n=e.length,r=new Array(6*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-i,l=u.y-o;r[a++]=c,r[a++]=0,r[a++]=l,r[a++]=c,r[a++]=0,r[a++]=l}return u=e[0],r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o,r}function _(e,t){for(var n=e.length,r=new Array(3*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[a++]=e[u].x-i,r[a++]=0,r[a++]=e[u].y-o;return r}function T(e,n,r,i,s,c,f,h,d,E){var p,y=t.angleBetween(t.subtract(n,e,x),t.subtract(r,e,C)),_=i===a.BEVELED?0:Math.ceil(y/o.toRadians(5));p=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,x),y/(_+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,y/(_+1),H),k);var T,R;if(n=t.clone(n,Y),_>0)for(var v=E?2:1,A=0;A<_;A++)n=u.multiplyByVector(p,n,n),T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,h,f,c,d,1,v);else T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,h,f,c,d,1,1),r=t.clone(r,Y),T=t.subtract(r,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(r,C),f=m(R,T,h,f,c,d,1,1);return f}var R=[new t,new t],v=new t,A=new t,g=new t,S=new t,N=new t,O=new t,w=new t,I=new t,M=new t,x=new t,C=new t,P={},U=new r,D=new t,L=new t,b=new t(-1,0,0),F=new s,B=new s,z=new u,q=u.IDENTITY.clone(),G=new t,V=new n,W=new t,X=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],a=n-1,i=0;i<n;a=i++){var o=t[a],u=t[i];e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,a){var o=new i(r,a),u=o.projectPointOntoPlane(t.add(r,e,D),D),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var j=new t,Z=new t;return P.computePositions=function(e,n,r,i,u){var s=i._ellipsoid,l=h(e,s),f=i._granularity,E=i._cornerType,C=u?y(n,r):_(n,r),U=u?_(n,r):void 0,D=r.height/2,L=r.width/2,b=e.length,F=[],B=u?[]:void 0,z=v,q=A,G=g,V=S,W=N,X=O,H=w,Y=I,k=M,K=e[0],J=e[1];V=s.geodeticSurfaceNormal(K,V),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(B=m(K,Y,U,B,s,Q+D,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<b-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),V=s.geodeticSurfaceNormal(K,V);var ae=t.multiplyByScalar(V,t.dot(z,V),j);t.subtract(z,ae,ae),t.normalize(ae,ae);var ie=t.multiplyByScalar(V,t.dot(q,V),Z);t.subtract(q,ie,ie),t.normalize(ie,ie);if(!o.equalsEpsilon(Math.abs(t.dot(ae,ie)),1,o.EPSILON7)){G=t.cross(G,V,G),G=t.cross(V,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,x))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),F=p(te,Y,C,F,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,L,H),H),E===a.ROUNDED||E===a.BEVELED?T(W,X,H,E,ue,s,F,C,$+D,u):(G=t.negate(G,G),F=m(K,G,C,F,s,$+D,oe,re)),k=t.clone(H,k)):(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,-L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),F=p(te,Y,C,F,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,-L,H),H),E===a.ROUNDED||E===a.BEVELED?T(W,X,H,E,ue,s,F,C,$+D,u):F=m(K,G,C,F,s,$+D,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else F=m(k,Y,C,F,s,Q+D,1,1),k=K;Q=$,$=l[ne+1],K=J}R[0]=t.clone(k,R[0]),R[1]=t.clone(K,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),F=p(te,Y,C,F,s,ee,1),u&&(B=m(K,Y,U,B,s,$+D,1,1)),b=F.length;var se=u?b+B.length:b,ce=new Float64Array(se);return ce.set(F),u&&ce.set(B,b),ce},P}),define("Core/CorridorGeometryLibrary",["./Cartesian3","./CornerType","./defined","./Math","./Matrix3","./PolylinePipeline","./PolylineVolumeGeometryLibrary","./Quaternion"],function(e,t,n,r,a,i,o,u){"use strict";function s(n,i,o,s,c){var l=e.angleBetween(e.subtract(i,n,d),e.subtract(o,n,E)),f=s===t.BEVELED?1:Math.ceil(l/r.toRadians(5))+1,h=3*f,m=new Array(h);m[h-3]=o.x,m[h-2]=o.y,m[h-1]=o.z;var p;p=c?a.fromQuaternion(u.fromAxisAngle(e.negate(n,d),l/f,I),M):a.fromQuaternion(u.fromAxisAngle(n,l/f,I),M);var y=0;i=e.clone(i,d);for(var _=0;_<f;_++)i=a.multiplyByVector(p,i,i),m[y++]=i.x,m[y++]=i.y,m[y++]=i.z;return m}function c(n){var r=_,a=T,i=R,o=n[1];a=e.fromArray(n[1],o.length-3,a),i=e.fromArray(n[0],0,i),r=e.multiplyByScalar(e.add(a,i,r),.5,r);var u=s(r,a,i,t.ROUNDED,!1),c=n.length-1,l=n[c-1];return o=n[c],a=e.fromArray(l,l.length-3,a),i=e.fromArray(o,0,i),r=e.multiplyByScalar(e.add(a,i,r),.5,r),[u,s(r,a,i,t.ROUNDED,!1)]}function l(t,n,r,a){var i=d;return a?i=e.add(t,n,i):(n=e.negate(n,n),i=e.add(t,n,i)),[i.x,i.y,i.z,r.x,r.y,r.z]}function f(t,n,r,a){for(var i=new Array(t.length),o=new Array(t.length),u=e.multiplyByScalar(n,r,d),s=e.negate(u,E),c=0,l=t.length-1,f=0;f<t.length;f+=3){var h=e.fromArray(t,f,m),y=e.add(h,s,p);i[c++]=y.x,i[c++]=y.y,i[c++]=y.z;var _=e.add(h,u,p);o[l--]=_.z,o[l--]=_.y,o[l--]=_.x}return a.push(i,o),a}var h={},d=new e,E=new e,m=new e,p=new e,y=[new e,new e],_=new e,T=new e,R=new e,v=new e,A=new e,g=new e,S=new e,N=new e,O=new e,w=new e,I=new u,M=new a;h.addAttribute=function(e,t,r,a){var i=t.x,o=t.y,u=t.z;n(r)&&(e[r]=i,e[r+1]=o,e[r+2]=u),n(a)&&(e[a]=u,e[a-1]=o,e[a-2]=i)};var x=new e,C=new e;return h.computePositions=function(n){var a=n.granularity,u=n.positions,h=n.ellipsoid,E=n.width/2,m=n.cornerType,p=n.saveAttributes,I=_,M=T,P=R,U=v,D=A,L=g,b=S,F=N,B=O,z=w,q=[],G=p?[]:void 0,V=p?[]:void 0,W=u[0],X=u[1];M=e.normalize(e.subtract(X,W,M),M),I=h.geodeticSurfaceNormal(W,I),U=e.normalize(e.cross(I,M,U),U),p&&(G.push(U.x,U.y,U.z),V.push(I.x,I.y,I.z)),b=e.clone(W,b),W=X,P=e.negate(M,P);var H,Y,k=[],j=u.length;for(Y=1;Y<j-1;Y++){I=h.geodeticSurfaceNormal(W,I),X=u[Y+1],M=e.normalize(e.subtract(X,W,M),M),D=e.normalize(e.add(M,P,D),D);var Z=e.multiplyByScalar(I,e.dot(M,I),x);e.subtract(M,Z,Z),e.normalize(Z,Z);var K=e.multiplyByScalar(I,e.dot(P,I),C);e.subtract(P,K,K),e.normalize(K,K);if(!r.equalsEpsilon(Math.abs(e.dot(Z,K)),1,r.EPSILON7)){D=e.cross(D,I,D),D=e.cross(I,D,D),D=e.normalize(D,D);var J=E/Math.max(.25,e.magnitude(e.cross(D,P,d))),Q=o.angleIsGreaterThanPi(M,P,W,h);D=e.multiplyByScalar(D,J,D),Q?(F=e.add(W,D,F),z=e.add(F,e.multiplyByScalar(U,E,z),z),B=e.add(F,e.multiplyByScalar(U,2*E,B),B),y[0]=e.clone(b,y[0]),y[1]=e.clone(z,y[1]),H=i.generateArc({positions:y,granularity:a,ellipsoid:h}),q=f(H,U,E,q),p&&(G.push(U.x,U.y,U.z),V.push(I.x,I.y,I.z)),L=e.clone(B,L),U=e.normalize(e.cross(I,M,U),U),B=e.add(F,e.multiplyByScalar(U,2*E,B),B),b=e.add(F,e.multiplyByScalar(U,E,b),b),m===t.ROUNDED||m===t.BEVELED?k.push({leftPositions:s(F,L,B,m,Q)}):k.push({leftPositions:l(W,e.negate(D,D),B,Q)})):(B=e.add(W,D,B),z=e.add(B,e.negate(e.multiplyByScalar(U,E,z),z),z),F=e.add(B,e.negate(e.multiplyByScalar(U,2*E,F),F),F),y[0]=e.clone(b,y[0]),y[1]=e.clone(z,y[1]),H=i.generateArc({positions:y,granularity:a,ellipsoid:h}),q=f(H,U,E,q),p&&(G.push(U.x,U.y,U.z),V.push(I.x,I.y,I.z)),L=e.clone(F,L),U=e.normalize(e.cross(I,M,U),U),F=e.add(B,e.negate(e.multiplyByScalar(U,2*E,F),F),F),b=e.add(B,e.negate(e.multiplyByScalar(U,E,b),b),b),m===t.ROUNDED||m===t.BEVELED?k.push({rightPositions:s(B,L,F,m,Q)}):k.push({rightPositions:l(W,D,F,Q)})),P=e.negate(M,P)}W=X}I=h.geodeticSurfaceNormal(W,I),y[0]=e.clone(b,y[0]),y[1]=e.clone(W,y[1]),H=i.generateArc({positions:y,granularity:a,ellipsoid:h}),q=f(H,U,E,q),p&&(G.push(U.x,U.y,U.z),V.push(I.x,I.y,I.z));var $;return m===t.ROUNDED&&($=c(q)),{positions:q,corners:k,lefts:G,normals:V,endPositions:$}},h}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,f,h,d,E,m,p;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=h=e[0],f=d=e[1];for(var y=a;y<o;y+=a)E=e[y],m=e[y+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);p=Math.max(h-l,d-f)}return r(u,c,a,l,f,p),c}function t(e,t,n,r,a){var i,o;if(a===I(e,t,n,r)>0)for(i=t;i<n;i+=r)o=N(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=N(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==_(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,p=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?i(e,c,l,f):a(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),O(e),e=m.next,p=m.next;else if((e=m)===p){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(_(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(p(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&_(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(_(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&p(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&p(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&A(a,i)&&A(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),O(r),O(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&y(s,c)){var l=S(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,f=o<u-1?r[o+1]*i:e.length,h=t(e,s,f,i,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=S(t,e);n(r,r.next)}}function f(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&p(i<f?a:o,i,l,f,i<f?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var a=e;do{null===a.z&&(a.z=E(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,d(a)}function d(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function p(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function y(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&g(e,t)}function _(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||_(e,t,n)>0!=_(e,t,r)>0&&_(n,r,e)>0!=_(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function g(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function S(e,t){var n=new w(e.i,e.x,e.y),r=new w(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function N(e,t,n,r){var a=new w(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function w(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function I(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(I(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(I(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var p=new n,y=new n,_=new n,T=new n,R=new n,v=new n,A=new n;return m.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),g=0;for(h=0;h<E;h++){var S=t[h];m[g++]=S.x,m[g++]=S.y,m[g++]=S.z}for(var N=[],O={},w=e.maximumRadius,I=l.chordLength(u,w),M=I*I;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,p),b=n.fromArray(m,3*U,y),F=n.fromArray(m,3*P,_),B=n.multiplyByScalar(n.normalize(L,T),w,T),z=n.multiplyByScalar(n.normalize(b,R),w,R),q=n.multiplyByScalar(n.normalize(F,v),w,v),G=n.magnitudeSquared(n.subtract(B,z,A)),V=n.magnitudeSquared(n.subtract(z,q,A)),W=n.magnitudeSquared(n.subtract(q,B,A)),X=Math.max(G,V,W);X>M?G===X?(x=Math.min(D,U)+" "+Math.max(D,U),h=O[x],o(h)||(C=n.add(L,b,A),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[x]=h),d.push(D,h,P),d.push(h,U,P)):V===X?(x=Math.min(U,P)+" "+Math.max(U,P),h=O[x],o(h)||(C=n.add(b,F,A),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[x]=h),d.push(U,h,D),d.push(h,P,D)):W===X&&(x=Math.min(P,D)+" "+Math.max(P,D),h=O[x],o(h)||(C=n.add(F,L,A),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[x]=h),d.push(P,h,U),d.push(h,D,U)):(N.push(D),N.push(U),N.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:m})},indices:N,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=d,c=E;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},a.unpack=function(n,r,i){return r=e(r,0),t(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(e,n){if(t(e))return t(n)||(n=new a),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},a}),define("Core/CorridorGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Cartographic","./ComponentDatatype","./CornerType","./CorridorGeometryLibrary","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Rectangle","./VertexFormat"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,y,_,T,R){"use strict";function v(e,t){for(var n=0;n<e.length;n++)e[n]=t.scaleToGeodeticSurface(e[n],e[n]);return e}function A(e,t,r,a,i,u){var s=e.normals,c=e.tangents,l=e.bitangents,f=n.normalize(n.cross(r,t,b),b);u.normal&&o.addAttribute(s,t,a,i),u.tangent&&o.addAttribute(c,f,a,i),u.bitangent&&o.addAttribute(l,r,a,i)}function g(e,t,r){var i,u,c,l=e.positions,f=e.corners,h=e.endPositions,y=e.lefts,_=e.normals,T=new E,R=0,v=0,g=0;for(u=0;u<l.length;u+=2)c=l[u].length-3,R+=c,g+=2*c,v+=l[u+1].length-3;for(R+=3,v+=3,u=0;u<f.length;u++){i=f[u];var S=f[u].leftPositions;s(S)?(c=S.length,R+=c,g+=c):(c=f[u].rightPositions.length,v+=c,g+=c)}var N,O=s(h);O&&(N=h[0].length-3,R+=N,v+=N,N/=3,g+=6*N);var w,I,M,D,B,z,q=R+v,G=new Float64Array(q),V=t.normal?new Float32Array(q):void 0,W=t.tangent?new Float32Array(q):void 0,X=t.bitangent?new Float32Array(q):void 0,H={normals:V,tangents:W,bitangents:X},Y=0,k=q-1,j=x,Z=C,K=N/2,J=m.createTypedArray(q/3,g),Q=0;if(O){z=P,B=U;var $=h[0];for(j=n.fromArray(_,0,j),Z=n.fromArray(y,0,Z),u=0;u<K;u++)z=n.fromArray($,3*(K-1-u),z),B=n.fromArray($,3*(K+u),B),o.addAttribute(G,B,Y),o.addAttribute(G,z,void 0,k),A(H,j,Z,Y,k,t),I=Y/3,D=I+1,w=(k-2)/3,M=w-1,J[Q++]=w,J[Q++]=I,J[Q++]=M,J[Q++]=M,J[Q++]=I,J[Q++]=D,Y+=3,k-=3}var ee=0,te=0,ne=l[ee++],re=l[ee++];G.set(ne,Y),G.set(re,k-re.length+1),Z=n.fromArray(y,te,Z);var ae,ie;for(c=re.length-3,u=0;u<c;u+=3)ae=r.geodeticSurfaceNormal(n.fromArray(ne,u,b),b),ie=r.geodeticSurfaceNormal(n.fromArray(re,c-u,F),F),j=n.normalize(n.add(ae,ie,j),j),A(H,j,Z,Y,k,t),I=Y/3,D=I+1,w=(k-2)/3,M=w-1,J[Q++]=w,J[Q++]=I,J[Q++]=M,J[Q++]=M,J[Q++]=I,J[Q++]=D,Y+=3,k-=3;for(ae=r.geodeticSurfaceNormal(n.fromArray(ne,c,b),b), +ie=r.geodeticSurfaceNormal(n.fromArray(re,c,F),F),j=n.normalize(n.add(ae,ie,j),j),te+=3,u=0;u<f.length;u++){var oe;i=f[u];var ue,se,ce=i.leftPositions,le=i.rightPositions,fe=L,he=P,de=U;if(j=n.fromArray(_,te,j),s(ce)){for(A(H,j,Z,void 0,k,t),k-=3,ue=D,se=M,oe=0;oe<ce.length/3;oe++)fe=n.fromArray(ce,3*oe,fe),J[Q++]=ue,J[Q++]=se-oe-1,J[Q++]=se-oe,o.addAttribute(G,fe,void 0,k),he=n.fromArray(G,3*(se-oe-1),he),de=n.fromArray(G,3*ue,de),Z=n.normalize(n.subtract(he,de,Z),Z),A(H,j,Z,void 0,k,t),k-=3;fe=n.fromArray(G,3*ue,fe),he=n.subtract(n.fromArray(G,3*se,he),fe,he),de=n.subtract(n.fromArray(G,3*(se-oe),de),fe,de),Z=n.normalize(n.add(he,de,Z),Z),A(H,j,Z,Y,void 0,t),Y+=3}else{for(A(H,j,Z,Y,void 0,t),Y+=3,ue=M,se=D,oe=0;oe<le.length/3;oe++)fe=n.fromArray(le,3*oe,fe),J[Q++]=ue,J[Q++]=se+oe,J[Q++]=se+oe+1,o.addAttribute(G,fe,Y),he=n.fromArray(G,3*ue,he),de=n.fromArray(G,3*(se+oe),de),Z=n.normalize(n.subtract(he,de,Z),Z),A(H,j,Z,Y,void 0,t),Y+=3;fe=n.fromArray(G,3*ue,fe),he=n.subtract(n.fromArray(G,3*(se+oe),he),fe,he),de=n.subtract(n.fromArray(G,3*se,de),fe,de),Z=n.normalize(n.negate(n.add(de,he,Z),Z),Z),A(H,j,Z,void 0,k,t),k-=3}for(ne=l[ee++],re=l[ee++],ne.splice(0,3),re.splice(re.length-3,3),G.set(ne,Y),G.set(re,k-re.length+1),c=re.length-3,te+=3,Z=n.fromArray(y,te,Z),oe=0;oe<re.length;oe+=3)ae=r.geodeticSurfaceNormal(n.fromArray(ne,oe,b),b),ie=r.geodeticSurfaceNormal(n.fromArray(re,c-oe,F),F),j=n.normalize(n.add(ae,ie,j),j),A(H,j,Z,Y,k,t),D=Y/3,I=D-1,M=(k-2)/3,w=M+1,J[Q++]=w,J[Q++]=I,J[Q++]=M,J[Q++]=M,J[Q++]=I,J[Q++]=D,Y+=3,k-=3;Y-=3,k+=3}if(j=n.fromArray(_,_.length-3,j),A(H,j,Z,Y,k,t),O){Y+=3,k-=3,z=P,B=U;var Ee=h[1];for(u=0;u<K;u++)z=n.fromArray(Ee,3*(N-u-1),z),B=n.fromArray(Ee,3*u,B),o.addAttribute(G,z,void 0,k),o.addAttribute(G,B,Y),A(H,j,Z,Y,k,t),D=Y/3,I=D-1,M=(k-2)/3,w=M+1,J[Q++]=w,J[Q++]=I,J[Q++]=M,J[Q++]=M,J[Q++]=I,J[Q++]=D,Y+=3,k-=3}if(T.position=new d({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:G}),t.st){var me,pe,ye=new Float32Array(q/3*2),_e=0;if(O){R/=3,v/=3;var Te=Math.PI/(N+1);pe=1/(R-N+1),me=1/(v-N+1);var Re,ve=N/2;for(u=ve+1;u<N+1;u++)Re=p.PI_OVER_TWO+Te*u,ye[_e++]=me*(1+Math.cos(Re)),ye[_e++]=.5*(1+Math.sin(Re));for(u=1;u<v-N+1;u++)ye[_e++]=u*me,ye[_e++]=0;for(u=N;u>ve;u--)Re=p.PI_OVER_TWO-u*Te,ye[_e++]=1-me*(1+Math.cos(Re)),ye[_e++]=.5*(1+Math.sin(Re));for(u=ve;u>0;u--)Re=p.PI_OVER_TWO-Te*u,ye[_e++]=1-pe*(1+Math.cos(Re)),ye[_e++]=.5*(1+Math.sin(Re));for(u=R-N;u>0;u--)ye[_e++]=u*pe,ye[_e++]=1;for(u=1;u<ve+1;u++)Re=p.PI_OVER_TWO+Te*u,ye[_e++]=pe*(1+Math.cos(Re)),ye[_e++]=.5*(1+Math.sin(Re))}else{for(R/=3,v/=3,pe=1/(R-1),me=1/(v-1),u=0;u<v;u++)ye[_e++]=u*me,ye[_e++]=0;for(u=R;u>0;u--)ye[_e++]=(u-1)*pe,ye[_e++]=1}T.st=new d({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:ye})}return t.normal&&(T.normal=new d({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:H.normals})),t.tangent&&(T.tangent=new d({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:H.tangents})),t.bitangent&&(T.bitangent=new d({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:H.bitangents})),{attributes:T,indices:J}}function S(e,t){if(!(t.normal||t.tangent||t.bitangent||t.st))return e;var r,a,i=e.position.values;(t.normal||t.bitangent)&&(r=e.normal.values,a=e.bitangent.values);var u,s=e.position.values.length/18,c=3*s,l=2*s,f=2*c;if(t.normal||t.bitangent||t.tangent){var h=t.normal?new Float32Array(6*c):void 0,d=t.tangent?new Float32Array(6*c):void 0,E=t.bitangent?new Float32Array(6*c):void 0,m=x,p=C,y=P,_=U,T=D,R=L,v=f;for(u=0;u<c;u+=3){var A=v+f;m=n.fromArray(i,u,m),p=n.fromArray(i,u+c,p),y=n.fromArray(i,(u+3)%c,y),p=n.subtract(p,m,p),y=n.subtract(y,m,y),_=n.normalize(n.cross(p,y,_),_),t.normal&&(o.addAttribute(h,_,A),o.addAttribute(h,_,A+3),o.addAttribute(h,_,v),o.addAttribute(h,_,v+3)),(t.tangent||t.bitangent)&&(R=n.fromArray(r,u,R),t.bitangent&&(o.addAttribute(E,R,A),o.addAttribute(E,R,A+3),o.addAttribute(E,R,v),o.addAttribute(E,R,v+3)),t.tangent&&(T=n.normalize(n.cross(R,_,T),T),o.addAttribute(d,T,A),o.addAttribute(d,T,A+3),o.addAttribute(d,T,v),o.addAttribute(d,T,v+3))),v+=6}if(t.normal){for(h.set(r),u=0;u<c;u+=3)h[u+c]=-r[u],h[u+c+1]=-r[u+1],h[u+c+2]=-r[u+2];e.normal.values=h}else e.normal=void 0;if(t.bitangent?(E.set(a),E.set(a,c),e.bitangent.values=E):e.bitangent=void 0,t.tangent){var g=e.tangent.values;d.set(g),d.set(g,c),e.tangent.values=d}}if(t.st){var S=e.st.values,N=new Float32Array(6*l);N.set(S),N.set(S,l);for(var O=2*l,w=0;w<2;w++){for(N[O++]=S[0],N[O++]=S[1],u=2;u<l;u+=2){var I=S[u],M=S[u+1];N[O++]=I,N[O++]=M,N[O++]=I,N[O++]=M}N[O++]=S[0],N[O++]=S[1]}e.st.values=N}return e}function N(e,t,n){n[t++]=e[0],n[t++]=e[1],n[t++]=e[2];for(var r=3;r<e.length;r+=3){var a=e[r],i=e[r+1],o=e[r+2];n[t++]=a,n[t++]=i,n[t++]=o,n[t++]=a,n[t++]=i,n[t++]=o}return n[t++]=e[0],n[t++]=e[1],n[t++]=e[2],n}function O(e,t){var n=new R({position:t.position,normal:t.normal||t.bitangent||e.shadowVolume,tangent:t.tangent,bitangent:t.normal||t.bitangent,st:t.st}),r=e.ellipsoid,i=o.computePositions(e),u=g(i,n,r),s=e.height,c=e.extrudedHeight,l=u.attributes,f=u.indices,h=l.position.values,E=h.length,p=new Float64Array(6*E),_=new Float64Array(E);_.set(h);var T=new Float64Array(4*E);h=y.scaleToGeodeticHeight(h,s,r),T=N(h,0,T),_=y.scaleToGeodeticHeight(_,c,r),T=N(_,2*E,T),p.set(h),p.set(_,E),p.set(T,2*E),l.position.values=p,l=S(l,t);var v,A=E/3;if(e.shadowVolume){var O=l.normal.values;E=O.length;var w=new Float32Array(6*E);for(v=0;v<E;v++)O[v]=-O[v];w.set(O,E),w=N(O,4*E,w),l.extrudeDirection=new d({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:w}),t.normal||(l.normal=void 0)}var I=f.length,M=A+A,x=m.createTypedArray(p.length/3,2*I+3*M);x.set(f);var C=I;for(v=0;v<I;v+=3){var P=f[v],U=f[v+1],D=f[v+2];x[C++]=D+A,x[C++]=U+A,x[C++]=P+A}var L,b,F,B;for(v=0;v<M;v+=2)L=v+M,b=L+M,F=L+1,B=b+1,x[C++]=L,x[C++]=b,x[C++]=F,x[C++]=F,x[C++]=b,x[C++]=B;return{attributes:l,indices:x}}function w(e,t,r,a,i,o){var u=n.subtract(t,e,B);n.normalize(u,u);var s=r.geodeticSurfaceNormal(e,z),c=n.cross(u,s,B);n.multiplyByScalar(c,a,c);var l=i.latitude,f=i.longitude,h=o.latitude,d=o.longitude;n.add(e,c,z),r.cartesianToCartographic(z,q);var E=q.latitude,m=q.longitude;l=Math.min(l,E),f=Math.min(f,m),h=Math.max(h,E),d=Math.max(d,m),n.subtract(e,c,z),r.cartesianToCartographic(z,q),E=q.latitude,m=q.longitude,l=Math.min(l,E),f=Math.min(f,m),h=Math.max(h,E),d=Math.max(d,m),i.latitude=l,i.longitude=f,o.latitude=h,o.longitude=d}function I(t,r,a,o){t=v(t,r);var u=e(t,n.equalsEpsilon),s=u.length;if(s<2||a<=0)return new T;var c=.5*a;W.latitude=Number.POSITIVE_INFINITY,W.longitude=Number.POSITIVE_INFINITY,X.latitude=Number.NEGATIVE_INFINITY,X.longitude=Number.NEGATIVE_INFINITY;var l,f;if(o===i.ROUNDED){var h=u[0];n.subtract(h,u[1],G),n.normalize(G,G),n.multiplyByScalar(G,c,G),n.add(h,G,V),r.cartesianToCartographic(V,q),l=q.latitude,f=q.longitude,W.latitude=Math.min(W.latitude,l),W.longitude=Math.min(W.longitude,f),X.latitude=Math.max(X.latitude,l),X.longitude=Math.max(X.longitude,f)}for(var d=0;d<s-1;++d)w(u[d],u[d+1],r,c,W,X);var E=u[s-1];n.subtract(E,u[s-2],G),n.normalize(G,G),n.multiplyByScalar(G,c,G),n.add(E,G,V),w(E,V,r,c,W,X),o===i.ROUNDED&&(r.cartesianToCartographic(V,q),l=q.latitude,f=q.longitude,W.latitude=Math.min(W.latitude,l),W.longitude=Math.min(W.longitude,f),X.latitude=Math.max(X.latitude,l),X.longitude=Math.max(X.longitude,f));var m=new T;return m.north=X.latitude,m.south=W.latitude,m.east=X.longitude,m.west=W.longitude,m}function M(e){e=u(e,u.EMPTY_OBJECT);var t=e.positions,r=e.width;this._positions=t,this._ellipsoid=f.clone(u(e.ellipsoid,f.WGS84)),this._vertexFormat=R.clone(u(e.vertexFormat,R.DEFAULT)),this._width=r,this._height=u(e.height,0),this._extrudedHeight=u(e.extrudedHeight,this._height),this._cornerType=u(e.cornerType,i.ROUNDED),this._granularity=u(e.granularity,p.RADIANS_PER_DEGREE),this._shadowVolume=u(e.shadowVolume,!1),this._workerName="createCorridorGeometry",this._rectangle=I(t,this._ellipsoid,r,this._cornerType),this.packedLength=1+t.length*n.packedLength+f.packedLength+R.packedLength+T.packedLength+6}var x=new n,C=new n,P=new n,U=new n,D=new n,L=new n,b=new n,F=new n,B=new n,z=new n,q=new r,G=new n,V=new n,W=new r,X=new r;M.pack=function(e,t,r){r=u(r,0);var a=e._positions,i=a.length;t[r++]=i;for(var o=0;o<i;++o,r+=n.packedLength)n.pack(a[o],t,r);return f.pack(e._ellipsoid,t,r),r+=f.packedLength,R.pack(e._vertexFormat,t,r),r+=R.packedLength,T.pack(e._rectangle,t,r),r+=T.packedLength,t[r++]=e._width,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._cornerType,t[r++]=e._granularity,t[r]=e._shadowVolume?1:0,t};var H=f.clone(f.UNIT_SPHERE),Y=new R,k=new T,j={positions:void 0,ellipsoid:H,vertexFormat:Y,width:void 0,height:void 0,extrudedHeight:void 0,cornerType:void 0,granularity:void 0,shadowVolume:void 0};return M.unpack=function(e,t,r){t=u(t,0);for(var a=e[t++],i=new Array(a),o=0;o<a;++o,t+=n.packedLength)i[o]=n.unpack(e,t);var c=f.unpack(e,t,H);t+=f.packedLength;var l=R.unpack(e,t,Y);t+=R.packedLength;var h=T.unpack(e,t,k);t+=T.packedLength;var d=e[t++],E=e[t++],m=e[t++],p=e[t++],y=e[t++],_=1===e[t];return s(r)?(r._positions=i,r._ellipsoid=f.clone(c,r._ellipsoid),r._vertexFormat=R.clone(l,r._vertexFormat),r._width=d,r._height=E,r._extrudedHeight=m,r._cornerType=p,r._granularity=y,r._rectangle=T.clone(h),r._shadowVolume=_,r):(j.positions=i,j.width=d,j.height=E,j.extrudedHeight=m,j.cornerType=p,j.granularity=y,j.shadowVolume=_,new M(j))},M.createGeometry=function(r){var a=r._positions,i=r._height,u=r._width,s=r._extrudedHeight,c=i!==s,l=r._ellipsoid;a=v(a,l);var f=e(a,n.equalsEpsilon);if(!(f.length<2||u<=0)){var d,E=r._vertexFormat,m={ellipsoid:l,positions:f,width:u,cornerType:r._cornerType,granularity:r._granularity,saveAttributes:!0};if(c){var p=Math.max(i,s);s=Math.min(i,s),i=p,m.height=i,m.extrudedHeight=s,m.shadowVolume=r._shadowVolume,d=O(m,E)}else{d=g(o.computePositions(m),E,l),d.attributes.position.values=y.scaleToGeodeticHeight(d.attributes.position.values,i,l)}var T=d.attributes,R=t.fromVertices(T.position.values,void 0,3);return E.position||(d.attributes.position.values=void 0),new h({attributes:T,indices:d.indices,primitiveType:_.TRIANGLES,boundingSphere:R})}},M.createShadowVolume=function(e,t,n){var r=e._granularity,a=e._ellipsoid,i=t(r,a),o=n(r,a);return new M({positions:e._positions,width:e._width,cornerType:e._cornerType,ellipsoid:a,granularity:r,extrudedHeight:i,height:o,vertexFormat:R.POSITION_ONLY,shadowVolume:!0})},c(M.prototype,{rectangle:{get:function(){return this._rectangle}}}),M}),define("Workers/createCorridorGeometry",["../Core/CorridorGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,n){"use strict";function r(r,a){return t(a)&&(r=e.unpack(r,a)),r._ellipsoid=n.clone(r._ellipsoid),e.createGeometry(r)}return r})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorOutlineGeometry.js index 420e3310..573aebde 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCorridorOutlineGeometry.js @@ -222,9 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function a(e,r,a){if(n(e)){a=t(a,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,i));++u);if(u===o)return a&&r(e[0],e[e.length-1],i)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,i)||(l.push(c),s=c);return a&&l.length>1&&r(l[0],l[l.length-1],i)&&l.shift(),l}}var i=r.EPSILON10;return a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,p=l*l*d*d,_=f*f*E*E,y=h*h*m*m,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,N=u.z,g=o;g.x=A.x*S*2,g.y=A.y*v*2,g.z=A.z*N*2;var O,M,I,w,x,C,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(g)),b=0;do{B-=b,I=1/(1+B*S),w=1/(1+B*v),x=1/(1+B*N),C=I*I,P=w*w,U=x*x,D=C*I,L=P*w,F=U*x,O=p*C+_*P+y*U-1,M=p*D*S+_*L*v+y*F*N;b=O/(-2*M)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*I,c.y=f*w,c.z=h*x,c):new e(l*I,f*w,h*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),p=2*(i+l),_=2*(a+h),y=-n+u-f+d,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=S,t):new s(E,m,p,_,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,_=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){ -return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),A=2*(f+m),S=2*(c+_),v=-s+d-p+y,N=2*(E-h),g=2*(f-m),O=2*(E+h),M=-s-d+p+y;return r[0]=T*i,r[1]=S*i,r[2]=g*i,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=O*o,r[7]=0,r[8]=A*u,r[9]=N*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,N=_*-R+y*-A+T*-S,g=E*R+m*A+p*S;return a(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=v,n[13]=N,n[14]=g,n[15]=1,n):new l(u,s,c,v,_,y,T,N,-E,-m,-p,g,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,p=o+l,_=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=_,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],N=t[5],g=t[6],O=t[7],M=t[8],I=t[9],w=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+h*A+p*S,B=i*T+c*R+d*A+_*S,b=o*T+l*R+E*A+y*S,z=r*v+u*N+f*g+m*O,q=a*v+s*N+h*g+p*O,G=i*v+c*N+d*g+_*O,W=o*v+l*N+E*g+y*O,X=r*M+u*I+f*w+m*x,V=a*M+s*I+h*w+p*x,H=i*M+c*I+d*w+_*x,Y=o*M+l*I+E*w+y*x,k=r*C+u*P+f*U+m*D,Z=a*C+s*P+h*U+p*D,j=i*C+c*P+d*U+_*D,K=o*C+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=X,n[9]=V,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],N=t[12],g=t[13],O=t[14],M=r*m+o*p+c*_,I=a*m+u*p+l*_,w=i*m+s*p+f*_,x=r*y+o*T+c*R,C=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*v,D=a*A+u*S+l*v,L=i*A+s*S+f*v,F=r*N+o*g+c*O+h,B=a*N+u*g+l*O+d,b=i*N+s*g+f*O+E;return n[0]=M,n[1]=I,n[2]=w,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=a*h+u*d+l*E,v=i*h+s*d+f*E,N=r*m+o*p+c*_,g=a*m+u*p+l*_,O=i*m+s*p+f*_,M=r*y+o*T+c*R,I=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=N,n[5]=g,n[6]=O,n[7]=0,n[8]=M,n[9]=I,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],A=e[10],S=e[14],v=e[3],N=e[7],g=e[11],O=e[15],M=A*O,I=S*g,w=p*O,x=S*N,C=p*g,P=A*N,U=m*O,D=S*v,L=m*g,F=A*v,B=m*N,b=p*v,z=M*h+x*d+C*E-(I*h+w*d+P*E),q=I*f+U*d+F*E-(M*f+D*d+L*E),G=w*f+D*h+B*E-(x*f+U*h+b*E),W=P*f+L*h+b*d-(C*f+F*h+B*d),X=I*a+w*i+P*o-(M*a+x*i+C*o),V=M*r+D*i+L*o-(I*r+U*i+F*o),H=x*r+U*a+b*o-(w*r+D*a+B*o),Y=C*r+F*a+B*i-(P*r+L*a+b*i);M=i*E,I=o*d,w=a*E,x=o*h,C=a*d,P=i*h,U=r*E,D=o*f,L=r*d,F=i*f,B=r*h,b=a*f;var k=M*N+x*g+C*O-(I*N+w*g+P*O),Z=I*v+U*g+F*O-(M*v+D*g+L*O),j=w*v+D*N+B*O-(x*v+U*N+b*O),K=P*v+L*N+b*g-(C*v+F*N+B*g),J=w*A+P*S+I*p-(C*S+M*p+x*A),Q=L*S+M*m+D*A-(U*A+F*S+I*m),$=U*p+b*S+x*m-(B*S+w*m+D*p),ee=B*A+C*m+F*p-(L*p+b*A+P*m),te=r*z+a*q+i*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=X*te,n[5]=V*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,N=new e;h.fromPoints=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,d),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),g=t.length;for(r=1;r<g;r++){e.clone(t[r],i);var O=i.x,M=i.y,I=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),M<u.y&&e.clone(i,u),M>l.y&&e.clone(i,l),I<s.z&&e.clone(i,s),I>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=v;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,N),G=0;for(r=0;r<g;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var X=e.magnitudeSquared(e.subtract(i,L,R));if(X>F){var V=Math.sqrt(X);B=.5*(B+V),F=B*B;var H=V-B;L.x=(B*L.x+H*i.x)/V,L.y=(B*L.y+H*i.y)/V,L.z=(B*L.z+H*i.z)/V}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var g=new o,O=new e,M=new e,I=new t,w=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,g),f.southwest(t,I),I.height=i,f.northeast(t,w),w.height=o;var s=n.project(I,O),c=n.project(w,M),l=c.x-s.x,d=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*E,u};var x=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,x);return h.fromPoints(s,u)},h.fromVertices=function(t,n,i,o){if(a(o)||(o=new h),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,E),f=e.clone(u,m),g=e.clone(u,p),O=e.clone(u,_),M=e.clone(u,y),I=t.length;for(s=0;s<I;s+=i){var w=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=w,u.y=x,u.z=C,w<c.x&&e.clone(u,c),w>g.x&&e.clone(u,g),x<l.y&&e.clone(u,l),x>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(g,c,R)),U=e.magnitudeSquared(e.subtract(O,l,R)),D=e.magnitudeSquared(e.subtract(M,f,R)),L=c,F=g,B=P;U>B&&(B=U,L=l,F=O),D>B&&(B=D,L=f,F=M);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=v;W.x=g.x,W.y=O.y,W.z=M.z;var X=e.multiplyByScalar(e.add(G,W,R),.5,N),V=0;for(s=0;s<I;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,R));H>V&&(V=H);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;b.x=(q*b.x+Z*u.x)/k,b.y=(q*b.y+Z*u.y)/k,b.z=(q*b.z+Z*u.z)/k}}return q<V?(e.clone(b,o.center),o.radius=q):(e.clone(X,o.center),o.radius=V),o},h.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new h),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,d),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,p),f=e.clone(i,_),g=e.clone(i,y),O=t.length;for(o=0;o<O;o+=3){var M=t[o]+n[o],I=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=M,i.y=I,i.z=w,M<u.x&&e.clone(i,u),M>l.x&&e.clone(i,l),I<s.y&&e.clone(i,s),I>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>g.z&&e.clone(i,g)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(g,c,R)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=g);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=v;q.x=l.x,q.y=f.y,q.z=g.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,N),W=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,G,R));X>W&&(W=X);var V=e.magnitudeSquared(e.subtract(i,F,R));if(V>B){var H=Math.sqrt(V);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},h.fromCornerPoints=function(t,n,r){a(r)||(r=new h);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},h.fromEllipsoid=function(t,n){return a(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;h.fromBoundingSpheres=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;h.fromOrientedBoundingBox=function(t,n){a(n)||(n=new h);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},h.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new h);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;h.union=function(t,n,r){a(r)||(r=new h);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(d,i,d),e.clone(d,r.center),r.radius=f,r};var B=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,W=new e,X=new e,V=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,V),d=e.negate(c,X),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,d,m),m=E[2],e.add(s,f,m),e.add(m,d,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,d,m),m=E[6],e.add(s,f,m),e.add(m,d,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=i.cartesianToCartographic(y,H);n.project(T,y)}a=h.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(v)&&(v=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){ -var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,N=r(e[1]))}return v}function u(){return o()&&N}function s(){if(!t(g)){g=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(g=!0,O=r(e[1]),O.isNightly=!!e[2])}return g}function c(){return s()&&O}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,I=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,I=r(e[1]))}return M}function f(){return l()&&I}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,x=r(e[1]))}return w}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,N,g,O,M,I,w,x,C,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,a=(n-r)/n,i=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,i),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,p=m*m,_=p*m,y=p*p,T=1+m-3*p/4+5*_/4-175*y/64,R=1-m+15*p/8-35*_/8,A=1-3*m+35*p/4,S=1-5*m,v=T*l-R*Math.sin(2*l)*m/2-A*Math.sin(4*l)*p/16-S*Math.sin(6*l)*_/48-5*Math.sin(8*l)*y/512,N=e._constants;N.a=n,N.b=r,N.f=a,N.cosineHeading=i,N.sineHeading=o,N.tanU=u,N.cosineU=s,N.sineU=c,N.sigma=l,N.sineAlpha=f,N.sineSquaredAlpha=h,N.cosineSquaredAlpha=d,N.cosineAlpha=E,N.u2Over4=m,N.u4Over16=p,N.u6Over64=_,N.u8Over256=y,N.a0=T,N.a1=R,N.a2=A,N.a3=S,N.distanceRatio=v}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,a,i,o){var u=c(e,n);return(1-u)*e*t*(r+u*a*(o+u*i*(2*o*o-1)))}function f(e,t,n,r,a,i,o){var s,c,f,h,d,E=(t-n)/t,m=i-r,p=Math.atan((1-E)*Math.tan(a)),_=Math.atan((1-E)*Math.tan(o)),y=Math.cos(p),T=Math.sin(p),R=Math.cos(_),A=Math.sin(_),S=y*R,v=y*A,N=T*A,g=T*R,O=m,M=u.TWO_PI,I=Math.cos(O),w=Math.sin(O);do{I=Math.cos(O),w=Math.sin(O);var x=v-g*I;f=Math.sqrt(R*R*w*w+x*x),c=N+S*I,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=S*w/f,h=1-C*C),M=O,d=c-2*N/h,isNaN(d)&&(d=0),O=m+l(E,C,h,s,f,c,d)}while(Math.abs(O-M)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),B=n*U*(s-F),b=Math.atan2(R*w,v-g*I),z=Math.atan2(y*w,v*I-g);e._distance=B,e._startHeading=b,e._endHeading=z,e._uSquared=P}function h(n,r,a,i){e.normalize(i.cartographicToCartesian(r,m),E),e.normalize(i.cartographicToCartesian(a,m),m);f(n,i.maximumRadius,i.minimumRadius,r.longitude,r.latitude,a.longitude,a.latitude),n._start=t.clone(r,n._start),n._end=t.clone(a,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,i){var u=r(i,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(n)&&h(this,e,n,u)}var E=new e,m=new e;return i(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,i=r.distanceRatio+e/r.b,o=Math.cos(2*i),u=Math.cos(4*i),s=Math.cos(6*i),c=Math.sin(2*i),f=Math.sin(4*i),h=Math.sin(6*i),d=Math.sin(8*i),E=i*i,m=i*E,p=r.u8Over256,_=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*p*o/3+i*(1-_+7*T/4-15*y/4+579*p/64-(T-15*y/4+187*p/16)*o-(5*y/4-115*p/16)*u-29*p*s/16)+(_/2-T+71*y/32-85*p/16)*c+(5*T/16-5*y/4+383*p/96)*f-E*((y-11*p/2)*c+5*p*f/2)+(29*y/96-29*p/16)*h+539*p*d/1536,A=Math.asin(Math.sin(R)*r.cosineAlpha),S=Math.atan(r.a/r.b*Math.tan(A));R-=r.sigma;var v=Math.cos(2*r.sigma+R),N=Math.sin(R),g=Math.cos(R),O=r.cosineU*g,M=r.sineU*N,I=Math.atan2(N*r.sineHeading,O-M*r.cosineHeading),w=I-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,N,g,v);return a(n)?(n.longitude=this._start.longitude+w,n.latitude=S,n.height=0,n):new t(this._start.longitude+w,S,0)},d}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,_=4*E*p-m*m;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-_);i=-R+S;var v=i/2,N=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),g=i===S?-N:-T/N;return a=T<=0?N+g:-R/(N*N+g*g+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var O=E,M=-2*u*E+o*m,I=p,w=-c*m+2*s*p,x=Math.sqrt(_),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-M)/3);a=2*Math.sqrt(-O);var U=Math.cos(P);i=a*U;var D=a*(-U/2-C*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*x,-w)/3),a=2*Math.sqrt(-I),U=Math.cos(P),i=a*U,D=a*(-U/2-C*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,X=L*b,V=(s*W-u*X)/(-u*W+s*G);return B<=V?B<=q?V<=q?[B,V,q]:[B,q,V]:[q,B,V]:B<=q?[V,B,q]:V<=q?[V,q,B]:[q,V,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),N=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==N.length?(N[0]+=h,N[1]+=h,v[1]<=N[0]?[v[0],v[1],N[0],N[1]]:N[1]<=v[0]?[N[0],N[1],v[0],v[1]]:v[0]>=N[0]&&v[1]<=N[1]?[N[0],v[0],v[1],N[1]]:N[0]>=v[0]&&N[1]<=v[1]?[v[0],N[0],N[1],v[1]]:v[0]>N[0]&&v[0]<N[1]?[N[0],v[0],N[1],v[1]]:[v[0],N[0],v[1],N[1]]):v):0!==N.length?(N[0]+=h,N[1]+=h,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],_=a-p,y=_*_,T=t/2,R=_/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*p,N=c+4*Math.abs(p);if(p<0||A*N<v*S){var g=Math.sqrt(v);E=g/2,m=0===g?0:(t*R-i)/g}else{var O=Math.sqrt(A);E=0===O?0:(t*R-i)/O,m=O/2}var M,I;0===T&&0===E?(M=0,I=0):n.sign(T)===n.sign(E)?(M=T+E,I=p/M):(I=T-E,M=p/I);var w,x;0===R&&0===m?(w=0,x=0):n.sign(R)===n.sign(m)?(w=R+m,x=o/w):(x=R-m,w=o/x);var C=r.computeRealRoots(1,M,w),P=r.computeRealRoots(1,I,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-v)),T.push(new e(a,i*S,i*v))}return T}var N=y*y,g=_*_,O=E*E,M=y*_,I=O+g,w=2*(m*E+M),x=2*p*E+m*m-g+N,C=2*(p*m-M),P=p*p-N;if(0===I&&0===w&&0===x&&0===C)return T;l=c.computeRealRoots(I,w,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(p)?d(E*B+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?d(E*B,m*F+p,o.EPSILON12):d(E*B+m*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,p),A=e.subtract(i,r,_),S=e.cross(E,A,y),v=e.dot(m,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var N=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*N)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*N)<0||l+f>1)return;h=e.dot(A,c)*N}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;m.lineSegmentSphere=function(t,n,a,i){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,g=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),f=e.multiplyComponents(c,t.direction,g),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,p=r/s;return m<p?new i(m,p):{start:p,stop:m}}var _=Math.sqrt(r/a);return new i(_,_)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var O=new e,M=new e,I=new e,w=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,M),M),m=e.normalize(e.cross(f,d,I),I),p=C;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,v=u.multiply(u.multiply(_,T,F),R,F),N=u.multiply(u.multiply(v,y,B),p,B),g=u.multiplyByVector(v,a,x),G=E(N,e.negate(g,O),0,0,1),W=G.length;if(W>0){for(var X=e.clone(e.ZERO,z),V=Number.NEGATIVE_INFINITY,H=0;H<W;++H){A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>V&&(V=k,X=e.clone(A,X))}var Z=n.cartesianToCartographic(X,q) -;return V=o.clamp(V,0,1),S=e.magnitude(e.subtract(X,a,w))*Math.sqrt(1-V*V),S=c?-S:S,Z.height=S,n.cartographicToCartesian(Z,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=N;r.length=e;var a;if(t===n){for(a=0;a<e;a++)r[a]=t;return r}var i=n-t,o=i/e;for(a=0;a<e;a++){var u=t+a*o;r[a]=u}return r}function d(t,n,r,a,i,o,u,s){var c=a.scaleToGeodeticSurface(t,I),l=a.scaleToGeodeticSurface(n,w),f=E.numberOfPoints(t,n,r),d=a.cartesianToCartographic(c,g),m=a.cartesianToCartographic(l,O),p=h(f,i,o);x.setEndPoints(d,m);var _=x.surfaceDistance/f,y=s;d.height=i;var T=a.cartographicToCartesian(d,M);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var A=x.interpolateUsingSurfaceDistance(R*_,O);A.height=p[R],T=a.cartographicToCartesian(A,M),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var a=e.distance(t,n);return Math.ceil(a/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),a=0;a<n;a++){var i=e[a];r[a]=t.cartesianToCartographic(i,m).height}return r};var p=new l,_=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,A=new f(e.UNIT_X,0),S=new e,v=new e,N=[],g=new t,O=new t,M=new e,I=new e,w=new e,x=new o;return E.wrapLongitude=function(t,a){var i=[],o=[];if(r(t)&&t.length>0){a=n(a,l.IDENTITY);var s=l.inverseTransformation(a,p),c=l.multiplyByPoint(s,e.ZERO,_),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,A),N=1;i.push(e.clone(t[0]));for(var g=i[0],O=t.length,M=1;M<O;++M){var I=t[M];if(f.getPointDistance(m,g)<0||f.getPointDistance(m,I)<0){var w=u.lineSegmentPlane(g,I,d,S);if(r(w)){var x=e.multiplyByScalar(h,5e-9,v);f.getPointDistance(d,g)<0&&e.negate(x,x),i.push(e.add(w,x,new e)),o.push(N+1),e.negate(x,x),i.push(e.add(w,x,new e)),N=1}}i.push(e.clone(t[M])),N++,g=I}o.push(N)}return{positions:i,lengths:o}},E.generateArc=function(t){r(t)||(t={});var a=t.positions,o=a.length,u=n(t.ellipsoid,i.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(a[0],I);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,M);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var p=t.minDistance;if(!r(p)){var _=n(t.granularity,c.RADIANS_PER_DEGREE);p=c.chordLength(_,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(a[y],a[y+1],p);var R=3*(T+1),A=new Array(R),S=0;for(y=0;y<o-1;y++){S=d(a[y],a[y+1],p,u,f?l[y]:l,f?l[y+1]:l,A,S)}N.length=0;var v=a[o-1],O=u.cartesianToCartographic(v,g);O.height=f?l[o-1]:l;var w=u.cartographicToCartesian(O,M);return e.pack(w,A,R-3),A},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,a=new Array(r),i=0;i<r;i++)a[i]=e.unpack(n,3*i);return a},E}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=a,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=_,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=_,d.reject(h))},E=function(e){f.push(e),--c||(E=m=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,N=0;s&&N<v;N++)switch(s.charAt(N)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(N+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,S);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),E=d<0?"-":T,_=E+a(String(Math.abs(d)),f,"0",!1),i(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=E+Math.abs(d)[m](f),i(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var p=new i,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,N=/([Z+\-])?(\d{2})?:?(\d{2})?$/,g=/^(\d{2})(\.\d+)?/.source+N.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+N.source,M=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+N.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,N=0,I=u[0],w=u[1];if(null!==(u=I.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(R)))n=+u[1],s=+u[2];else if(null!==(u=I.match(T)))n=+u[1];else{var x;if(null!==(u=I.match(A)))n=+u[1],x=+u[2],i=o(n);else if(null!==(u=I.match(S))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(M),null!==u?(h=+u[1],p=+u[2],y=+u[3],N=1e3*+(u[4]||0),D=5):(u=w.match(O),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(g))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,p-=B;break;case"-":h+=F,p+=B;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var b=60===y;for(b&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:_[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:_[s-1],l+=a;var z=E(n,s,l,h,p,y,N);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var I=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,I);r(a)||(m.addSeconds(e,-1,I),a=h(I,I),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(_,p,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,p);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return N[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function p(e){var t=d(e);return e.state=s.ACTIVE,v.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function _(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A) -;var v=[],N={},g="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=v.length;for(e=0;e<r;++e)t=v[e],t.cancelled&&_(t),t.state===s.ACTIVE?n>0&&(v[e-n]=t):++n;v.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-v.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||h(t.serverKey)?(p(t),++u):_(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(g);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=N[a];return r(i)||(N[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return p(e);if(!(v.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;_(t)}return d(e)}},l.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=v.length,t=0;t<e;++t)_(v[t]);v.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return N[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;a=n(a,t.url);var d=r(t.request)?t.request:new i;return d.url=a,d.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function d(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return h(a,i);case"blob":var o=h(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&h.setRequestHeader(m,i[m]);r(t)&&(h.responseType=t);var p=!1;return"string"==typeof e&&(p=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!p||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(a),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var S=p[R+a],v=p[R+m],N=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,g=new o(N,v,f.TAI);if(_.push(g),T){if(v!==y&&r(y)){var O=o.leapSeconds,M=t(O,g,d);if(M<0){var I=new u(g,v);O.splice(~M,0,I)}}y=v}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,_(this,i,this._samples,e,s,l,n),n}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),E>h&&E>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,N=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),N=s.multiplyByScalar(i,Math.sin(n*u),N),r=s.add(v,N,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var g=new e,O=new e,M=new s,I=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,M);s.multiply(i,r,I);var o=s.log(I,g);s.multiply(i,t,I);var u=s.log(I,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,M),u=s.slerp(n,r,a,I);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;C[L]=1/(F*B),P[L]=F/B}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,M),u=s.fastSlerp(n,r,a,I);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},N={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},g=new n,O=new n,M=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(v[i])?r=v[i]:(r=function(r,i,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,g),"east"!==e&&"west"!==e&&n.multiplyByScalar(g,c,g),n.unpack(S[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(S[a],0,M),"east"!==a&&"west"!==a&&n.multiplyByScalar(M,c,M)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,N.up);var l=N.up,h=N.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,N.east),n.cross(l,h,N.north),n.multiplyByScalar(N.up,-1,N.down),n.multiplyByScalar(N.east,-1,N.west),n.multiplyByScalar(N.north,-1,N.south),g=N[e],O=N[t],M=N[a]}return s[0]=g.x,s[1]=g.y,s[2]=g.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=M.x,s[9]=M.y,s[10]=M.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var I=new y,w=new n(1,1,1),x=new _;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,I),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,x);return i=a(e,r,i),_.multiply(i,s,i)};var C=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=_.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new p,b=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,b),h=p.multiply(l,f,B),d=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=_/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var v=p.fromRotationZ(S,b),N=p.multiply(h,v,B),g=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),M=Math.sin(n.xPoleWander),I=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var x=-47e-6*w*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=b;return U[0]=g*C,U[1]=g*P,U[2]=M,U[3]=-O*P+I*M*C,U[4]=O*C+I*M*P,U[5]=-I*g,U[6]=-I*P-O*M*C,U[7]=I*C-O*M*P,U[8]=O*g,p.multiply(N,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return _.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var X=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),V=new a,H=new n,Y=new n,k=new p,Z=new _,j=new _;return R.basisTo2D=function(e,t,r){var a=_.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,V),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,Z),c=_.inverseTransformation(s,j),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(X,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,Z),o=_.inverseTransformation(i,j),u=a.cartesianToCartographic(t,V),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,Z);return _.multiply(X,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=_;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=_;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var a=e[r];U=t.cartesianToCartographic(a,U),n[r]=U.height,e[r]=t.scaleToGeodeticSurface(a,a)}return n}function d(e,n,r,a){var i,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/a),l=new Array(c);if(n===r){for(i=0;i<c;i++)l[i]=n;return l.push(r),l}var f=r-n,h=f/c;for(i=1;i<c;i++){var d=n+i*h;l[i]=d}return l[0]=n,l.push(r),l}function E(n,r,a,o){var u=new i(a,o),s=u.projectPointOntoPlane(t.add(a,n,D),D),c=u.projectPointOntoPlane(t.add(a,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function m(e,n,r,a,i,o,c,l){var h=G,d=W;B=f.eastNorthUpToFixedFrame(e,i,B),h=s.multiplyByPointAsVector(B,F,h),h=t.normalize(h,h);var m=E(h,n,e,i);z=u.fromRotationZ(m,z),X.z=o,B=s.multiplyTransformation(B,s.fromRotationTranslation(z,X,b),B);var p=q;p[0]=c;for(var _=0;_<l;_++)for(var y=0;y<r.length;y+=3)d=t.fromArray(r,y,d),d=u.multiplyByVector(p,d,d),d=s.multiplyByPoint(B,d,d),a.push(d.x,d.y,d.z);return a}function p(e,n,r,a,i,o,u){for(var s=0;s<e.length;s+=3){a=m(t.fromArray(e,s,V),n,r,a,i,o[s/3],u,1)}return a}function _(e,t){var n=e.length,r=new Array(6*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-i,l=u.y-o;r[a++]=c,r[a++]=0,r[a++]=l,r[a++]=c,r[a++]=0,r[a++]=l}return u=e[0],r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o,r}function y(e,t){for(var n=e.length,r=new Array(3*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[a++]=e[u].x-i,r[a++]=0,r[a++]=e[u].y-o;return r}function T(e,n,r,i,s,c,f,h,d,E){var p,_=t.angleBetween(t.subtract(n,e,x),t.subtract(r,e,C)),y=i===a.BEVELED?0:Math.ceil(_/o.toRadians(5));p=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,x),_/(y+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,_/(y+1),H),k);var T,R;if(n=t.clone(n,Y),y>0)for(var A=E?2:1,S=0;S<y;S++)n=u.multiplyByVector(p,n,n),T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,h,f,c,d,1,A);else T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,h,f,c,d,1,1),r=t.clone(r,Y),T=t.subtract(r,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(r,C),f=m(R,T,h,f,c,d,1,1);return f}var R=[new t,new t],A=new t,S=new t,v=new t,N=new t,g=new t,O=new t,M=new t,I=new t,w=new t,x=new t,C=new t,P={},U=new r,D=new t,L=new t,F=new t(-1,0,0),B=new s,b=new s,z=new u,q=u.IDENTITY.clone(),G=new t,W=new n,X=new t,V=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],a=n-1,i=0;i<n;a=i++){var o=t[a],u=t[i] -;e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,a){var o=new i(r,a),u=o.projectPointOntoPlane(t.add(r,e,D),D),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var Z=new t,j=new t;return P.computePositions=function(e,n,r,i,u){var s=i._ellipsoid,l=h(e,s),f=i._granularity,E=i._cornerType,C=u?_(n,r):y(n,r),U=u?y(n,r):void 0,D=r.height/2,L=r.width/2,F=e.length,B=[],b=u?[]:void 0,z=A,q=S,G=v,W=N,X=g,V=O,H=M,Y=I,k=w,K=e[0],J=e[1];W=s.geodeticSurfaceNormal(K,W),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(W,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(b=m(K,Y,U,b,s,Q+D,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<F-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),W=s.geodeticSurfaceNormal(K,W);var ae=t.multiplyByScalar(W,t.dot(z,W),Z);t.subtract(z,ae,ae),t.normalize(ae,ae);var ie=t.multiplyByScalar(W,t.dot(q,W),j);t.subtract(q,ie,ie),t.normalize(ie,ie);if(!o.equalsEpsilon(Math.abs(t.dot(ae,ie)),1,o.EPSILON7)){G=t.cross(G,W,G),G=t.cross(W,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,x))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(X=t.add(K,t.multiplyByScalar(G,oe*L,G),X),V=t.add(X,t.multiplyByScalar(Y,L,V),V),R[0]=t.clone(k,R[0]),R[1]=t.clone(V,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=p(te,Y,C,B,s,ee,1),Y=t.cross(W,z,Y),Y=t.normalize(Y,Y),H=t.add(X,t.multiplyByScalar(Y,L,H),H),E===a.ROUNDED||E===a.BEVELED?T(X,V,H,E,ue,s,B,C,$+D,u):(G=t.negate(G,G),B=m(K,G,C,B,s,$+D,oe,re)),k=t.clone(H,k)):(X=t.add(K,t.multiplyByScalar(G,oe*L,G),X),V=t.add(X,t.multiplyByScalar(Y,-L,V),V),R[0]=t.clone(k,R[0]),R[1]=t.clone(V,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=p(te,Y,C,B,s,ee,1),Y=t.cross(W,z,Y),Y=t.normalize(Y,Y),H=t.add(X,t.multiplyByScalar(Y,-L,H),H),E===a.ROUNDED||E===a.BEVELED?T(X,V,H,E,ue,s,B,C,$+D,u):B=m(K,G,C,B,s,$+D,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else B=m(k,Y,C,B,s,Q+D,1,1),k=K;Q=$,$=l[ne+1],K=J}R[0]=t.clone(k,R[0]),R[1]=t.clone(K,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=p(te,Y,C,B,s,ee,1),u&&(b=m(K,Y,U,b,s,$+D,1,1)),F=B.length;var se=u?F+b.length:F,ce=new Float64Array(se);return ce.set(B),u&&ce.set(b,F),ce},P}),define("Core/CorridorGeometryLibrary",["./Cartesian3","./CornerType","./defined","./Math","./Matrix3","./PolylinePipeline","./PolylineVolumeGeometryLibrary","./Quaternion"],function(e,t,n,r,a,i,o,u){"use strict";function s(n,i,o,s,c){var l=e.angleBetween(e.subtract(i,n,d),e.subtract(o,n,E)),f=s===t.BEVELED?1:Math.ceil(l/r.toRadians(5))+1,h=3*f,m=new Array(h);m[h-3]=o.x,m[h-2]=o.y,m[h-1]=o.z;var p;p=c?a.fromQuaternion(u.fromAxisAngle(e.negate(n,d),l/f,I),w):a.fromQuaternion(u.fromAxisAngle(n,l/f,I),w);var _=0;i=e.clone(i,d);for(var y=0;y<f;y++)i=a.multiplyByVector(p,i,i),m[_++]=i.x,m[_++]=i.y,m[_++]=i.z;return m}function c(n){var r=y,a=T,i=R,o=n[1];a=e.fromArray(n[1],o.length-3,a),i=e.fromArray(n[0],0,i),r=e.multiplyByScalar(e.add(a,i,r),.5,r);var u=s(r,a,i,t.ROUNDED,!1),c=n.length-1,l=n[c-1];return o=n[c],a=e.fromArray(l,l.length-3,a),i=e.fromArray(o,0,i),r=e.multiplyByScalar(e.add(a,i,r),.5,r),[u,s(r,a,i,t.ROUNDED,!1)]}function l(t,n,r,a){var i=d;return a?i=e.add(t,n,i):(n=e.negate(n,n),i=e.add(t,n,i)),[i.x,i.y,i.z,r.x,r.y,r.z]}function f(t,n,r,a){for(var i=new Array(t.length),o=new Array(t.length),u=e.multiplyByScalar(n,r,d),s=e.negate(u,E),c=0,l=t.length-1,f=0;f<t.length;f+=3){var h=e.fromArray(t,f,m),_=e.add(h,s,p);i[c++]=_.x,i[c++]=_.y,i[c++]=_.z;var y=e.add(h,u,p);o[l--]=y.z,o[l--]=y.y,o[l--]=y.x}return a.push(i,o),a}var h={},d=new e,E=new e,m=new e,p=new e,_=[new e,new e],y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,N=new e,g=new e,O=new e,M=new e,I=new u,w=new a;h.addAttribute=function(e,t,r,a){var i=t.x,o=t.y,u=t.z;n(r)&&(e[r]=i,e[r+1]=o,e[r+2]=u),n(a)&&(e[a]=u,e[a-1]=o,e[a-2]=i)};var x=new e,C=new e;return h.computePositions=function(n){var a=n.granularity,u=n.positions,h=n.ellipsoid,E=n.width/2,m=n.cornerType,p=n.saveAttributes,I=y,w=T,P=R,U=A,D=S,L=v,F=N,B=g,b=O,z=M,q=[],G=p?[]:void 0,W=p?[]:void 0,X=u[0],V=u[1];w=e.normalize(e.subtract(V,X,w),w),I=h.geodeticSurfaceNormal(X,I),U=e.normalize(e.cross(I,w,U),U),p&&(G.push(U.x,U.y,U.z),W.push(I.x,I.y,I.z)),F=e.clone(X,F),X=V,P=e.negate(w,P);var H,Y,k=[],Z=u.length;for(Y=1;Y<Z-1;Y++){I=h.geodeticSurfaceNormal(X,I),V=u[Y+1],w=e.normalize(e.subtract(V,X,w),w),D=e.normalize(e.add(w,P,D),D);var j=e.multiplyByScalar(I,e.dot(w,I),x);e.subtract(w,j,j),e.normalize(j,j);var K=e.multiplyByScalar(I,e.dot(P,I),C);e.subtract(P,K,K),e.normalize(K,K);if(!r.equalsEpsilon(Math.abs(e.dot(j,K)),1,r.EPSILON7)){D=e.cross(D,I,D),D=e.cross(I,D,D),D=e.normalize(D,D);var J=E/Math.max(.25,e.magnitude(e.cross(D,P,d))),Q=o.angleIsGreaterThanPi(w,P,X,h);D=e.multiplyByScalar(D,J,D),Q?(B=e.add(X,D,B),z=e.add(B,e.multiplyByScalar(U,E,z),z),b=e.add(B,e.multiplyByScalar(U,2*E,b),b),_[0]=e.clone(F,_[0]),_[1]=e.clone(z,_[1]),H=i.generateArc({positions:_,granularity:a,ellipsoid:h}),q=f(H,U,E,q),p&&(G.push(U.x,U.y,U.z),W.push(I.x,I.y,I.z)),L=e.clone(b,L),U=e.normalize(e.cross(I,w,U),U),b=e.add(B,e.multiplyByScalar(U,2*E,b),b),F=e.add(B,e.multiplyByScalar(U,E,F),F),m===t.ROUNDED||m===t.BEVELED?k.push({leftPositions:s(B,L,b,m,Q)}):k.push({leftPositions:l(X,e.negate(D,D),b,Q)})):(b=e.add(X,D,b),z=e.add(b,e.negate(e.multiplyByScalar(U,E,z),z),z),B=e.add(b,e.negate(e.multiplyByScalar(U,2*E,B),B),B),_[0]=e.clone(F,_[0]),_[1]=e.clone(z,_[1]),H=i.generateArc({positions:_,granularity:a,ellipsoid:h}),q=f(H,U,E,q),p&&(G.push(U.x,U.y,U.z),W.push(I.x,I.y,I.z)),L=e.clone(B,L),U=e.normalize(e.cross(I,w,U),U),B=e.add(b,e.negate(e.multiplyByScalar(U,2*E,B),B),B),F=e.add(b,e.negate(e.multiplyByScalar(U,E,F),F),F),m===t.ROUNDED||m===t.BEVELED?k.push({rightPositions:s(b,L,B,m,Q)}):k.push({rightPositions:l(X,D,B,Q)})),P=e.negate(w,P)}X=V}I=h.geodeticSurfaceNormal(X,I),_[0]=e.clone(F,_[0]),_[1]=e.clone(X,_[1]),H=i.generateArc({positions:_,granularity:a,ellipsoid:h}),q=f(H,U,E,q),p&&(G.push(U.x,U.y,U.z),W.push(I.x,I.y,I.z));var $;return m===t.ROUNDED&&($=c(q)),{positions:q,corners:k,lefts:G,normals:W,endPositions:$}},h}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,f,h,d,E,m,p;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=h=e[0],f=d=e[1];for(var _=a;_<o;_+=a)E=e[_],m=e[_+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);p=Math.max(h-l,d-f)}return r(u,c,a,l,f,p),c}function t(e,t,n,r,a){var i,o;if(a===I(e,t,n,r)>0)for(i=t;i<n;i+=r)o=g(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=g(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,p=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?i(e,c,l,f):a(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),O(e),e=m.next,p=m.next;else if((e=m)===p){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(p(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&y(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(y(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&p(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&p(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&S(a,i)&&S(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),O(r),O(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&_(s,c)){var l=N(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,f=o<u-1?r[o+1]*i:e.length,h=t(e,s,f,i,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=N(t,e);n(r,r.next)}}function f(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&p(i<f?a:o,i,l,f,i<f?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<h||s===h&&r.x>n.x)&&S(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var a=e;do{null===a.z&&(a.z=E(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,d(a)}function d(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function p(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!A(e,t)&&S(e,t)&&S(t,e)&&v(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function A(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function S(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function v(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function N(e,t){var n=new M(e.i,e.x,e.y),r=new M(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function g(e,t,n,r){var a=new M(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function M(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function I(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(I(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(I(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var p=new n,_=new n,y=new n,T=new n,R=new n,A=new n,S=new n;return m.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),v=0;for(h=0;h<E;h++){var N=t[h];m[v++]=N.x,m[v++]=N.y,m[v++]=N.z}for(var g=[],O={},M=e.maximumRadius,I=l.chordLength(u,M),w=I*I;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,p),F=n.fromArray(m,3*U,_),B=n.fromArray(m,3*P,y),b=n.multiplyByScalar(n.normalize(L,T),M,T),z=n.multiplyByScalar(n.normalize(F,R),M,R),q=n.multiplyByScalar(n.normalize(B,A),M,A),G=n.magnitudeSquared(n.subtract(b,z,S)),W=n.magnitudeSquared(n.subtract(z,q,S)),X=n.magnitudeSquared(n.subtract(q,b,S)),V=Math.max(G,W,X);V>w?G===V?(x=Math.min(D,U)+" "+Math.max(D,U),h=O[x],o(h)||(C=n.add(L,F,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[x]=h),d.push(D,h,P),d.push(h,U,P)):W===V?(x=Math.min(U,P)+" "+Math.max(U,P),h=O[x],o(h)||(C=n.add(F,B,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[x]=h),d.push(U,h,D),d.push(h,P,D)):X===V&&(x=Math.min(P,D)+" "+Math.max(P,D),h=O[x],o(h)||(C=n.add(B,L,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[x]=h),d.push(P,h,U),d.push(h,D,U)):(g.push(D),g.push(U),g.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:m})},indices:g,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=d,c=E;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/CorridorOutlineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./CornerType","./CorridorGeometryLibrary","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p){"use strict";function _(e,t){for(var n=0;n<e.length;n++)e[n]=t.scaleToGeodeticSurface(e[n],e[n]);return e}function y(e,t){var r,u,c,l=[],E=e.positions,m=e.corners,p=e.endPositions,_=new h,y=0,T=0,R=0;for(u=0;u<E.length;u+=2)c=E[u].length-3,y+=c,R+=c/3*4,T+=E[u+1].length-3;for(y+=3,T+=3,u=0;u<m.length;u++){r=m[u];var N=m[u].leftPositions;s(N)?(c=N.length,y+=c,R+=c/3*2):(c=m[u].rightPositions.length,T+=c,R+=c/3*2)}var g,O=s(p);O&&(g=p[0].length-3,y+=g,T+=g,g/=3,R+=4*g);var M,I,w,x,C,P,U=y+T,D=new Float64Array(U),L=0,F=U-1,B=g/2,b=d.createTypedArray(U/3,R+4),z=0;if(b[z++]=L/3,b[z++]=(F-2)/3,O){l.push(L/3),P=A,C=S;var q=p[0];for(u=0;u<B;u++)P=n.fromArray(q,3*(B-1-u),P),C=n.fromArray(q,3*(B+u),C),o.addAttribute(D,C,L),o.addAttribute(D,P,void 0,F),I=L/3,x=I+1,M=(F-2)/3,w=M-1,b[z++]=M,b[z++]=w,b[z++]=I,b[z++]=x,L+=3,F-=3}var G=0,W=E[G++],X=E[G++];for(D.set(W,L),D.set(X,F-X.length+1),c=X.length-3,l.push(L/3,(F-2)/3),u=0;u<c;u+=3)I=L/3,x=I+1,M=(F-2)/3,w=M-1,b[z++]=M,b[z++]=w,b[z++]=I,b[z++]=x,L+=3,F-=3;for(u=0;u<m.length;u++){var V;r=m[u];var H,Y=r.leftPositions,k=r.rightPositions,Z=v;if(s(Y)){for(F-=3,H=w,l.push(x),V=0;V<Y.length/3;V++)Z=n.fromArray(Y,3*V,Z),b[z++]=H-V-1,b[z++]=H-V,o.addAttribute(D,Z,void 0,F),F-=3;l.push(H-Math.floor(Y.length/6)),t===i.BEVELED&&l.push((F-2)/3+1),L+=3}else{for(L+=3,H=x,l.push(w),V=0;V<k.length/3;V++)Z=n.fromArray(k,3*V,Z),b[z++]=H+V,b[z++]=H+V+1,o.addAttribute(D,Z,L),L+=3;l.push(H+Math.floor(k.length/6)),t===i.BEVELED&&l.push(L/3-1),F-=3}for(W=E[G++],X=E[G++],W.splice(0,3),X.splice(X.length-3,3),D.set(W,L),D.set(X,F-X.length+1),c=X.length-3,V=0;V<X.length;V+=3)x=L/3,I=x-1,w=(F-2)/3,M=w+1,b[z++]=M,b[z++]=w,b[z++]=I,b[z++]=x,L+=3,F-=3;L-=3,F+=3,l.push(L/3,(F-2)/3)}if(O){L+=3,F-=3,P=A,C=S;var j=p[1];for(u=0;u<B;u++)P=n.fromArray(j,3*(g-u-1),P),C=n.fromArray(j,3*u,C),o.addAttribute(D,P,void 0,F),o.addAttribute(D,C,L),x=L/3,I=x-1,w=(F-2)/3,M=w+1,b[z++]=M,b[z++]=w,b[z++]=I,b[z++]=x,L+=3,F-=3;l.push(L/3)}else l.push(L/3,(F-2)/3);return b[z++]=L/3,b[z++]=(F-2)/3,_.position=new f({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:D}),{attributes:_,indices:b,wallIndices:l}}function T(e){var t=e.ellipsoid,n=o.computePositions(e),r=y(n,e.cornerType),a=r.wallIndices,i=e.height,u=e.extrudedHeight,s=r.attributes,c=r.indices,l=s.position.values,f=l.length,h=new Float64Array(f);h.set(l);var E=new Float64Array(2*f);l=m.scaleToGeodeticHeight(l,i,t),h=m.scaleToGeodeticHeight(h,u,t),E.set(l),E.set(h,f),s.position.values=E,f/=3;var p,_=c.length,T=d.createTypedArray(E.length/3,2*(_+a.length));T.set(c);var R=_;for(p=0;p<_;p+=2){var A=c[p],S=c[p+1];T[R++]=A+f,T[R++]=S+f}var v,N;for(p=0;p<a.length;p++)v=a[p],N=v+f,T[R++]=v,T[R++]=N;return{attributes:s,indices:T}}function R(e){e=u(e,u.EMPTY_OBJECT);var t=e.positions,r=e.width;this._positions=t,this._ellipsoid=c.clone(u(e.ellipsoid,c.WGS84)),this._width=r,this._height=u(e.height,0),this._extrudedHeight=u(e.extrudedHeight,this._height),this._cornerType=u(e.cornerType,i.ROUNDED),this._granularity=u(e.granularity,E.RADIANS_PER_DEGREE),this._workerName="createCorridorOutlineGeometry",this.packedLength=1+t.length*n.packedLength+c.packedLength+5}var A=new n,S=new n,v=new n;R.pack=function(e,t,r){r=u(r,0);var a=e._positions,i=a.length;t[r++]=i;for(var o=0;o<i;++o,r+=n.packedLength)n.pack(a[o],t,r);return c.pack(e._ellipsoid,t,r),r+=c.packedLength,t[r++]=e._width,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._cornerType,t[r]=e._granularity,t};var N=c.clone(c.UNIT_SPHERE),g={positions:void 0,ellipsoid:N,width:void 0,height:void 0,extrudedHeight:void 0,cornerType:void 0,granularity:void 0};return R.unpack=function(e,t,r){t=u(t,0);for(var a=e[t++],i=new Array(a),o=0;o<a;++o,t+=n.packedLength)i[o]=n.unpack(e,t);var l=c.unpack(e,t,N);t+=c.packedLength;var f=e[t++],h=e[t++],d=e[t++],E=e[t++],m=e[t];return s(r)?(r._positions=i,r._ellipsoid=c.clone(l,r._ellipsoid),r._width=f,r._height=h,r._extrudedHeight=d,r._cornerType=E,r._granularity=m,r):(g.positions=i,g.width=f,g.height=h,g.extrudedHeight=d,g.cornerType=E,g.granularity=m,new R(g))},R.createGeometry=function(r){var a=r._positions,i=r._height,u=r._width,s=r._extrudedHeight,c=i!==s,f=r._ellipsoid;a=_(a,f);var h=e(a,n.equalsEpsilon);if(!(h.length<2||u<=0)){var d,E={ellipsoid:f,positions:h,width:u,cornerType:r._cornerType,granularity:r._granularity,saveAttributes:!1};if(c){var R=Math.max(i,s);s=Math.min(i,s),i=R,E.height=i,E.extrudedHeight=s,d=T(E)}else{d=y(o.computePositions(E),E.cornerType),d.attributes.position.values=m.scaleToGeodeticHeight(d.attributes.position.values,i,f)}var A=d.attributes,S=t.fromVertices(A.position.values,void 0,3);return new l({attributes:A,indices:d.indices,primitiveType:p.LINES,boundingSphere:S})}},R}),define("Workers/createCorridorOutlineGeometry",["../Core/CorridorOutlineGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,n){"use strict";function r(r,a){return t(a)&&(r=e.unpack(r,a)),r._ellipsoid=n.clone(r._ellipsoid),e.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function i(e,r,i){if(n(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,a));++u);if(u===o)return i&&r(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&r(l[0],l[l.length-1],a)&&l.shift(),l}}var a=r.EPSILON10;return i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,E=i.y,p=i.z,m=l*l*d*d,y=f*f*E*E,_=h*h*p*p,T=m+y+_,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,g=u.z,N=o;N.x=v.x*A*2,N.y=v.y*S*2,N.z=v.z*g*2;var O,I,w,M,x,C,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(N)),b=0;do{B-=b,w=1/(1+B*A),M=1/(1+B*S),x=1/(1+B*g),C=w*w,P=M*M,U=x*x,D=C*w,L=P*M,F=U*x,O=m*C+y*P+_*U-1,I=m*D*A+y*L*S+_*F*g;b=O/(-2*I)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=h*x,c):new e(l*w,f*M,h*x)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var E=r(n)?n.oneOverRadii:f,p=r(n)?n.oneOverRadiiSquared:h,m=r(n)?n._centerToleranceSquared:d,y=o(t,E,p,m,c);if(r(y)){var _=e.multiplyComponents(y,p,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),R=Math.atan2(_.y,_.x),v=Math.asin(_.z),A=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=v,i.height=A,i):new u(R,v,A)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,p=new e,m=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,p);if(i(a)){var o=this.geodeticSurfaceNormal(a,E),u=e.subtract(n,a,m),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(p[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(p[a],E[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=E[i],h=p[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,m=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],T=(m-y)/2/_;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,p=2*(i-h),m=2*(a+l),y=2*(i+h),_=-n+u-f+d,T=2*(c-o),R=2*(a-l),v=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=E,t[1]=y,t[2]=R,t[3]=p,t[4]=_,t[5]=v,t[6]=m,t[7]=T,t[8]=A,t):new s(E,p,m,y,_,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,E=a*i+c*o*u,p=-c*i+a*o*u,m=-o,y=c*n,_=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=m,t[3]=f,t[4]=E,t[5]=y,t[6]=h,t[7]=p,t[8]=_,t):new s(l,f,h,d,E,p,m,y,_)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],p=[2,2,1],m=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,m),s.transpose(m,y),s.multiply(h,m,h),s.multiply(y,h,h),s.multiply(o,m,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)), +o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,E,p,m){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(p,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(m,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,p=t.y*t.w,m=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-d-m+_,R=2*(c-y),v=2*(f+p),A=2*(c+y),S=-s+d-m+_,g=2*(E-h),N=2*(f-p),O=2*(E+h),I=-s-d+m+_;return r[0]=T*a,r[1]=A*a,r[2]=N*a,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=O*o,r[7]=0,r[8]=v*u,r[9]=g*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,p=f.y,m=f.z,y=d.x,_=d.y,T=d.z,R=r.x,v=r.y,A=r.z,S=u*-R+s*-v+c*-A,g=y*-R+_*-v+T*-A,N=E*R+p*v+m*A;return i(n)?(n[0]=u,n[1]=y,n[2]=-E,n[3]=0,n[4]=s,n[5]=_,n[6]=-p,n[7]=0,n[8]=c,n[9]=T,n[10]=-m,n[11]=0,n[12]=S,n[13]=g,n[14]=N,n[15]=1,n):new l(u,s,c,S,y,_,T,g,-E,-p,-m,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,p=a+c,m=o+l,y=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=p,i[13]=m,i[14]=y,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],p=e[12],m=e[13],y=e[14],_=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],g=t[5],N=t[6],O=t[7],I=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*v+p*A,F=i*T+s*R+h*v+m*A,B=a*T+c*R+d*v+y*A,b=o*T+l*R+E*v+_*A,z=r*S+u*g+f*N+p*O,q=i*S+s*g+h*N+m*O,G=a*S+c*g+d*N+y*O,V=o*S+l*g+E*N+_*O,W=r*I+u*w+f*M+p*x,X=i*I+s*w+h*M+m*x,H=a*I+c*w+d*M+y*x,Y=o*I+l*w+E*M+_*x,k=r*C+u*P+f*U+p*D,j=i*C+s*P+h*U+m*D,Z=a*C+c*P+d*U+y*D,K=o*C+l*P+E*U+_*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],p=t[0],m=t[1],y=t[2],_=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],g=t[12],N=t[13],O=t[14],I=r*p+o*m+c*y,w=i*p+u*m+l*y,M=a*p+s*m+f*y,x=r*_+o*T+c*R,C=i*_+u*T+l*R,P=a*_+s*T+f*R,U=r*v+o*A+c*S,D=i*v+u*A+l*S,L=a*v+s*A+f*S,F=r*g+o*N+c*O+h,B=i*g+u*N+l*O+d,b=a*g+s*N+f*O+E;return n[0]=I,n[1]=w,n[2]=M,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],p=t[3],m=t[4],y=t[5],_=t[6],T=t[7],R=t[8],v=r*h+o*d+c*E,A=i*h+u*d+l*E,S=a*h+s*d+f*E,g=r*p+o*m+c*y,N=i*p+u*m+l*y,O=a*p+s*m+f*y,I=r*_+o*T+c*R,w=i*_+u*T+l*R,M=a*_+s*T+f*R;return n[0]=v,n[1]=A,n[2]=S,n[3]=0,n[4]=g,n[5]=N,n[6]=O,n[7]=0,n[8]=I,n[9]=w,n[10]=M,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var m=new e;l.multiplyByUniformScale=function(e,t,n){return m.x=t,m.y=t,m.z=t,l.multiplyByScale(e,m,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],p=e[2],m=e[6],v=e[10],A=e[14],S=e[3],g=e[7],N=e[11],O=e[15],I=v*O,w=A*N,M=m*O,x=A*g,C=m*N,P=v*g,U=p*O,D=A*S,L=p*N,F=v*S,B=p*g,b=m*S,z=I*h+x*d+C*E-(w*h+M*d+P*E),q=w*f+U*d+F*E-(I*f+D*d+L*E),G=M*f+D*h+B*E-(x*f+U*h+b*E),V=P*f+L*h+b*d-(C*f+F*h+B*d),W=w*i+M*a+P*o-(I*i+x*a+C*o),X=I*r+D*a+L*o-(w*r+U*a+F*o),H=x*r+U*i+b*o-(M*r+D*i+B*o),Y=C*r+F*i+B*a-(P*r+L*i+b*a);I=a*E,w=o*d,M=i*E,x=o*h,C=i*d,P=a*h,U=r*E,D=o*f,L=r*d,F=a*f,B=r*h,b=i*f;var k=I*g+x*N+C*O-(w*g+M*N+P*O),j=w*S+U*N+F*O-(I*S+D*N+L*O),Z=M*S+D*g+B*O-(x*S+U*g+b*O),K=P*S+L*g+b*N-(C*S+F*g+B*N),J=M*v+P*A+w*m-(C*A+I*m+x*v),Q=L*A+I*p+D*v-(U*v+F*A+w*p),$=U*m+b*A+x*p-(B*A+M*p+D*m),ee=B*v+C*p+F*m-(L*m+b*v+P*p),te=r*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-i*d,p=-a*f-o*h-u*d,m=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=p,t[14]=m,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,E),o=Math.max(o,E)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,p=e.length;E<p;E++){var m=t.cartesianToCartographic(e[E]);o=Math.min(o,m.longitude),c=Math.max(c,m.longitude),h=Math.min(h,m.latitude),d=Math.max(d,m.latitude);var y=m.longitude>=0?m.longitude:m.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,p=c;p.height=i,p.longitude=E,p.latitude=f,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=f<0?f:h>0?h:0;for(var m=1;m<8;++m)p.longitude=-Math.PI+m*u.PI_OVER_TWO,s.contains(e,p)&&(o[l]=t.cartographicToCartesian(p,o[l]),l++);return 0===p.latitude&&(p.longitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var E=new e,p=new e,m=new e,y=new e,_=new e,T=new e,R=new e,v=new e,A=new e,S=new e,g=new e,N=new e,O=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,E),u=e.clone(i,p),s=e.clone(i,m),c=e.clone(i,y),l=e.clone(i,_),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var O=i.x,I=i.y,w=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,v)),x=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(f,s,v)),P=o,U=c,D=M;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,v)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,v),.5,N),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,v));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,L,v));if(W>F){var X=Math.sqrt(W);B=.5*(B+X),F=B*B;var H=X-B;L.x=(B*L.x+H*i.x)/X,L.y=(B*L.y+H*i.y)/X,L.z=(B*L.z+H*i.z)/X}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var I=new u,w=new e,M=new e,x=new t,C=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,I),h.southwest(t,x),x.height=r,h.northeast(t,C),C.height=o;var s=n.project(x,w),c=n.project(C,M),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var p=u.center;return p.x=s.x+.5*l,p.y=s.y+.5*f,p.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,p),f=e.clone(u,m),h=e.clone(u,y),O=e.clone(u,_),I=e.clone(u,T),w=t.length;for(s=0;s<w;s+=r){var M=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>h.x&&e.clone(u,h),x<l.y&&e.clone(u,l),x>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(h,c,v)),U=e.magnitudeSquared(e.subtract(O,l,v)),D=e.magnitudeSquared(e.subtract(I,f,v)),L=c,F=h,B=P;U>B&&(B=U,L=l,F=O),D>B&&(B=D,L=f,F=I);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,v)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=O.y,V.z=I.z;var W=e.multiplyByScalar(e.add(G,V,v),.5,N),X=0;for(s=0;s<w;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,v));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,b,v));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;b.x=(q*b.x+j*u.x)/k,b.y=(q*b.y+j*u.y)/k,b.z=(q*b.z+j*u.z)/k}}return q<X?(e.clone(b,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,E),s=e.clone(i,p),c=e.clone(i,m),l=e.clone(i,y),f=e.clone(i,_),h=e.clone(i,T),O=t.length;for(o=0;o<O;o+=3){var I=t[o]+n[o],w=t[o+1]+n[o+1],M=t[o+2]+n[o+2];i.x=I,i.y=w,i.z=M,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>h.z&&e.clone(i,h)}var x=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(f,s,v)),P=e.magnitudeSquared(e.subtract(h,c,v)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,v)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,v),.5,N),V=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,v));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,F,v));if(X>B){var H=Math.sqrt(X);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<V?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var B=new e,b=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,B),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,W=new e,X=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,p=E[0];e.add(s,l,p),e.add(p,c,p),p=E[1],e.add(s,l,p),e.add(p,h,p),p=E[2],e.add(s,f,p),e.add(p,h,p),p=E[3],e.add(s,f,p),e.add(p,c,p),e.negate(s,s),p=E[4],e.add(s,l,p),e.add(p,c,p),p=E[5],e.add(s,l,p),e.add(p,h,p),p=E[6],e.add(s,f,p),e.add(p,h,p),p=E[7],e.add(s,f,p),e.add(p,c,p);for(var m=E.length,y=0;y<m;++y){var _=E[y];e.add(o,_,_);var T=a.cartesianToCartographic(_,k);n.project(T,_)}r=d.fromPoints(E,r),o=r.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return O*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){ +for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(v)&&(v=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,g=r(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(N=!0,O=r(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=r(e[1]))}return I}function f(){return l()&&w}function h(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(M=!0,x=r(e[1]))}return M}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function p(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function m(){return E()&&P}function y(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function _(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return _()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,g,N,O,I,w,M,x,C,P,U,D,L,F,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:m,isWindows:p,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,i=(n-r)/n,a=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-i)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,a),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),p=t/4,m=p*p,y=m*p,_=m*m,T=1+p-3*m/4+5*y/4-175*_/64,R=1-p+15*m/8-35*y/8,v=1-3*p+35*m/4,A=1-5*p,S=T*l-R*Math.sin(2*l)*p/2-v*Math.sin(4*l)*m/16-A*Math.sin(6*l)*y/48-5*Math.sin(8*l)*_/512,g=e._constants;g.a=n,g.b=r,g.f=i,g.cosineHeading=a,g.sineHeading=o,g.tanU=u,g.cosineU=s,g.sineU=c,g.sigma=l,g.sineAlpha=f,g.sineSquaredAlpha=h,g.cosineSquaredAlpha=d,g.cosineAlpha=E,g.u2Over4=p,g.u4Over16=m,g.u6Over64=y,g.u8Over256=_,g.a0=T,g.a1=R,g.a2=v,g.a3=A,g.distanceRatio=S}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,i,a,o){var u=c(e,n);return(1-u)*e*t*(r+u*i*(o+u*a*(2*o*o-1)))}function f(e,t,n,r,i,a,o){var s,c,f,h,d,E=(t-n)/t,p=a-r,m=Math.atan((1-E)*Math.tan(i)),y=Math.atan((1-E)*Math.tan(o)),_=Math.cos(m),T=Math.sin(m),R=Math.cos(y),v=Math.sin(y),A=_*R,S=_*v,g=T*v,N=T*R,O=p,I=u.TWO_PI,w=Math.cos(O),M=Math.sin(O);do{w=Math.cos(O),M=Math.sin(O);var x=S-N*w;f=Math.sqrt(R*R*M*M+x*x),c=g+A*w,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=A*M/f,h=1-C*C),I=O,d=c-2*g/h,isNaN(d)&&(d=0),O=p+l(E,C,h,s,f,c,d)}while(Math.abs(O-I)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),B=n*U*(s-F),b=Math.atan2(R*M,S-N*w),z=Math.atan2(_*M,S*w-N);e._distance=B,e._startHeading=b,e._endHeading=z,e._uSquared=P}function h(n,r,i,a){e.normalize(a.cartographicToCartesian(r,p),E),e.normalize(a.cartographicToCartesian(i,p),p);f(n,a.maximumRadius,a.minimumRadius,r.longitude,r.latitude,i.longitude,i.latitude),n._start=t.clone(r,n._start),n._end=t.clone(i,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,a){var u=r(a,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,i(e)&&i(n)&&h(this,e,n,u)}var E=new e,p=new e;return a(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,a=r.distanceRatio+e/r.b,o=Math.cos(2*a),u=Math.cos(4*a),s=Math.cos(6*a),c=Math.sin(2*a),f=Math.sin(4*a),h=Math.sin(6*a),d=Math.sin(8*a),E=a*a,p=a*E,m=r.u8Over256,y=r.u2Over4,_=r.u6Over64,T=r.u4Over16,R=2*p*m*o/3+a*(1-y+7*T/4-15*_/4+579*m/64-(T-15*_/4+187*m/16)*o-(5*_/4-115*m/16)*u-29*m*s/16)+(y/2-T+71*_/32-85*m/16)*c+(5*T/16-5*_/4+383*m/96)*f-E*((_-11*m/2)*c+5*m*f/2)+(29*_/96-29*m/16)*h+539*m*d/1536,v=Math.asin(Math.sin(R)*r.cosineAlpha),A=Math.atan(r.a/r.b*Math.tan(v));R-=r.sigma;var S=Math.cos(2*r.sigma+R),g=Math.sin(R),N=Math.cos(R),O=r.cosineU*N,I=r.sineU*g,w=Math.atan2(g*r.sineHeading,O-I*r.cosineHeading),M=w-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,g,N,S);return i(n)?(n.longitude=this._start.longitude+M,n.latitude=A,n.height=0,n):new t(this._start.longitude+M,A,0)},d}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,p=o*c-u*s,m=u*c-d,y=4*E*m-p*p;if(y<0){var _,T,R;h*f>=l*d?(_=o,T=E,R=-2*u*E+o*p):(_=c,T=m,R=-c*p+2*s*m);var v=R<0?-1:1,A=-v*Math.abs(_)*Math.sqrt(-y);a=-R+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),N=a===A?-g:-T/g;return i=T<=0?g+N:-R/(g*g+N*N+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var O=E,I=-2*u*E+o*p,w=m,M=-c*p+2*s*m,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-I)/3);i=2*Math.sqrt(-O);var U=Math.cos(P);a=i*U;var D=i*(-U/2-C*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*x,-M)/3),i=2*Math.sqrt(-w),U=Math.cos(P),a=i*U,D=i*(-U/2-C*Math.sin(P));var b=-c,z=a+D<2*s?a+s:D+s,q=b/z,G=F*z,V=-L*z-F*b,W=L*b,X=(s*V-u*W)/(-u*V+s*G);return B<=X?B<=q?X<=q?[B,X,q]:[B,q,X]:[q,B,X]:B<=q?[X,B,q]:X<=q?[X,q,B]:[q,X,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var p,m=E[0],y=E[1];if(m>=0&&y>=0){var _=Math.sqrt(m),T=Math.sqrt(y);return[h-T,h-_,h+_,h+T]}if(m>=0&&y<0)return p=Math.sqrt(m),[h-p,h+p];if(m<0&&y>=0)return p=Math.sqrt(y),[h-p,h+p]}return[]}if(d>0){var R=Math.sqrt(d),v=(s+d-c/R)/2,A=(s+d+c/R)/2,S=r.computeRealRoots(1,R,v),g=r.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,p,m=d[0],y=i-m,_=y*y,T=t/2,R=y/2,v=_-4*o,A=_+4*Math.abs(o),S=c-4*m,g=c+4*Math.abs(m);if(m<0||v*g<S*A){var N=Math.sqrt(S);E=N/2,p=0===N?0:(t*R-a)/N}else{var O=Math.sqrt(v);E=0===O?0:(t*R-a)/O,p=O/2}var I,w;0===T&&0===E?(I=0,w=0):n.sign(T)===n.sign(E)?(I=T+E,w=m/I):(w=T-E,I=m/w);var M,x;0===R&&0===p?(M=0,x=0):n.sign(R)===n.sign(p)?(M=R+p,x=o/M):(x=R-p,M=o/x);var C=r.computeRealRoots(1,I,M),P=r.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,p=f(h,d,E,A);if(r(p))return i.start=p.root0,i.stop=p.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,i,a){var l,f=i*i,h=a*a,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,p=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),m=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(E,p,m),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-v)),T.push(new e(i,a*R,a*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(i,a*A,a*-S)),T.push(new e(i,a*A,a*S))}return T}var g=_*_,N=y*y,O=E*E,I=_*y,w=O+N,M=2*(p*E+I),x=2*m*E+p*p-N+g,C=2*(m*p-I),P=m*m-g;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(m)?d(E*B+m,p*F,o.EPSILON12):o.sign(m)===o.sign(p*F)?d(E*B,p*F+m,o.EPSILON12):d(E*B+p*F,m,o.EPSILON12);var q=d(y*F,_,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var p={};p.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var m=new e,y=new e,_=new e,T=new e,R=new e;p.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,p=e.subtract(i,r,m),v=e.subtract(a,r,y),A=e.cross(E,v,_),S=e.dot(p,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,p,R),(f=e.dot(E,c))<0||l+f>S)return;h=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,r,T),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,p,R),(f=e.dot(E,c)*g)<0||l+f>1)return;h=e.dot(v,c)*g}return h},p.rayTriangle=function(t,n,i,a,o,u){var s=p.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;p.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=p.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};p.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;p.lineSegmentSphere=function(t,n,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;p.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var p=s/i,m=r/s;return p<m?new a(p,m):{start:m,stop:p}}var y=Math.sqrt(r/i);return new a(y,y)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var O=new e,I=new e,w=new e,M=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;p.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,O);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,M),d=e.normalize(e.cross(h,f,I),I),p=e.normalize(e.cross(f,d,w),w),m=C;m[0]=f.x,m[1]=f.y,m[2]=f.z,m[3]=d.x,m[4]=d.y,m[5]=d.z,m[6]=p.x,m[7]=p.y,m[8]=p.z;var y=u.transpose(m,P),_=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0 +;var v,A,S=u.multiply(u.multiply(y,T,F),R,F),g=u.multiply(u.multiply(S,_,B),m,B),N=u.multiplyByVector(S,i,x),G=E(g,e.negate(N,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(_,u.multiplyByVector(m,G[H],b),b);var Y=e.normalize(e.subtract(v,i,M),M),k=e.dot(Y,a);k>X&&(X=k,W=e.clone(v,W))}var j=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(W,i,M))*Math.sqrt(1-X*X),A=c?-A:A,j.height=A,n.cartographicToCartesian(j,new e)}};var G=new e;return p.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},p.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return p.lineSegmentPlane(t,n,i,f),p.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return p.lineSegmentPlane(n,r,i,f),p.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return p.lineSegmentPlane(r,t,i,f),p.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return p.lineSegmentPlane(n,t,i,f),p.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return p.lineSegmentPlane(r,n,i,f),p.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return p.lineSegmentPlane(t,r,i,f),p.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},p}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=g;r.length=e;var i;if(t===n){for(i=0;i<e;i++)r[i]=t;return r}var a=n-t,o=a/e;for(i=0;i<e;i++){var u=t+i*o;r[i]=u}return r}function d(t,n,r,i,a,o,u,s){var c=i.scaleToGeodeticSurface(t,w),l=i.scaleToGeodeticSurface(n,M),f=E.numberOfPoints(t,n,r),d=i.cartesianToCartographic(c,N),p=i.cartesianToCartographic(l,O),m=h(f,a,o);x.setEndPoints(d,p);var y=x.surfaceDistance/f,_=s;d.height=a;var T=i.cartographicToCartesian(d,I);e.pack(T,u,_),_+=3;for(var R=1;R<f;R++){var v=x.interpolateUsingSurfaceDistance(R*y,O);v.height=m[R],T=i.cartographicToCartesian(v,I),e.pack(T,u,_),_+=3}return _}var E={};E.numberOfPoints=function(t,n,r){var i=e.distance(t,n);return Math.ceil(i/r)};var p=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),i=0;i<n;i++){var a=e[i];r[i]=t.cartesianToCartographic(a,p).height}return r};var m=new l,y=new e,_=new e,T=new f(e.UNIT_X,0),R=new e,v=new f(e.UNIT_X,0),A=new e,S=new e,g=[],N=new t,O=new t,I=new e,w=new e,M=new e,x=new o;return E.wrapLongitude=function(t,i){var a=[],o=[];if(r(t)&&t.length>0){i=n(i,l.IDENTITY);var s=l.inverseTransformation(i,m),c=l.multiplyByPoint(s,e.ZERO,y),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,_),_),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),p=f.fromPointNormal(c,E,v),g=1;a.push(e.clone(t[0]));for(var N=a[0],O=t.length,I=1;I<O;++I){var w=t[I];if(f.getPointDistance(p,N)<0||f.getPointDistance(p,w)<0){var M=u.lineSegmentPlane(N,w,d,A);if(r(M)){var x=e.multiplyByScalar(h,5e-9,S);f.getPointDistance(d,N)<0&&e.negate(x,x),a.push(e.add(M,x,new e)),o.push(g+1),e.negate(x,x),a.push(e.add(M,x,new e)),g=1}}a.push(e.clone(t[I])),g++,N=w}o.push(g)}return{positions:a,lengths:o}},E.generateArc=function(t){r(t)||(t={});var i=t.positions,o=i.length,u=n(t.ellipsoid,a.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(i[0],w);if(0!==(l=f?l[0]:l)){var p=u.geodeticSurfaceNormal(h,I);e.multiplyByScalar(p,l,p),e.add(h,p,h)}return[h.x,h.y,h.z]}var m=t.minDistance;if(!r(m)){var y=n(t.granularity,c.RADIANS_PER_DEGREE);m=c.chordLength(y,u.maximumRadius)}var _,T=0;for(_=0;_<o-1;_++)T+=E.numberOfPoints(i[_],i[_+1],m);var R=3*(T+1),v=new Array(R),A=0;for(_=0;_<o-1;_++){A=d(i[_],i[_+1],m,u,f?l[_]:l,f?l[_+1]:l,v,A)}g.length=0;var S=i[o-1],O=u.cartesianToCartographic(S,N);O.height=f?l[o-1]:l;var M=u.cartographicToCartesian(O,I);return e.pack(M,v,R-3),v},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,i=new Array(r),a=0;a<r;a++)i[a]=e.unpack(n,3*a);return i},E}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,p=d.y,m=d.z;i=Math.min(E,i),s=Math.max(E,s),o=Math.min(p,o),c=Math.max(p,c),u=Math.min(m,u),l=Math.max(m,l)}var y=n.minimum;y.x=i,y.y=o,y.z=u;var _=n.maximum;_.x=s,_.y=c,_.z=l;var T=e.add(y,_,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function i(e){return E(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return p(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=y,p(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return m(2,arguments),e(t,function(t){function u(e){p(e)}function s(e){E(e)}var c,l,f,h,d,E,p,m,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(n,_)),f=[],l=_-c+1,h=[],d=o(),c)for(m=d.progress,p=function(e){h.push(e),--l||(E=p=y,d.reject(h))},E=function(e){f.push(e),--c||(E=p=y,d.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,m);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return m(1,arguments),h(e,_).then(t,n,r)}function f(){return h(arguments,_)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function E(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function p(e,t){for(var n,r=0;n=e[r++];)n(t)}function m(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function y(){}function _(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,E,p,m,y;if("%%"==e)return"%";for(var _=!1,T="",R=!1,v=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(y),_,c,f,R,A);case"c":return u(String.fromCharCode(+y),_,c,f,R);case"b":return o(y,2,v,_,c,f,R);case"o":return o(y,8,v,_,c,f,R);case"x":return o(y,16,v,_,c,f,R);case"X":return o(y,16,v,_,c,f,R).toUpperCase();case"u":return o(y,10,v,_,c,f,R);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),E=d<0?"-":T,y=E+i(String(Math.abs(d)),f,"0",!1),a(y,E,_,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,E=d<0?"-":T,p=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],m=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=E+Math.abs(d)[p](f),a(y,E,_,c,R)[m]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return p.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var n=p.leapSeconds,r=t(n,_,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){p.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}p.addSeconds(e,i,e)}function h(e,n){_.julianDate=e;var r=p.leapSeconds,i=t(r,_,l);if(i<0&&(i=~i),0===i)return p.addSeconds(e,-r[0].offset,n);if(i>=r.length)return p.addSeconds(e,-r[i-1].offset,n);var a=p.secondsDifference(r[i].julianDate,e);return 0===a?p.addSeconds(e,-r[i].offset,n):a<=1?void 0:p.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function p(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var m=new a,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;p.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new p(n[0],n[1],c.UTC)},p.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new p(n[0],n[1],c.UTC)},p.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,m=0,_=0,g=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(R)))n=+u[1],s=+u[2];else if(null!==(u=w.match(T)))n=+u[1];else{var x;if(null!==(u=w.match(v)))n=+u[1],x=+u[2],a=o(n);else if(null!==(u=w.match(A))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(x),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(M)){u=M.match(I),null!==u?(h=+u[1],m=+u[2],_=+u[3],g=1e3*+(u[4]||0),D=5):(u=M.match(O),null!==u?(h=+u[1],m=+u[2],_=60*+(u[3]||0),D=4):null!==(u=M.match(N))&&(h=+u[1],m=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,m-=B;break;case"-":h+=F,m+=B;break;case"Z":break;default:m+=new Date(Date.UTC(n,s-1,l,h,m)).getTimezoneOffset()}}var b=60===_;for(b&&_--;m>=60;)m-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:y[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:y[s-1];for(;m<0;)m+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:y[s-1],l+=i;var z=E(n,s,l,h,m,_,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new p(z[0],z[1],c.UTC),b&&p.addSeconds(t,1,t),t},p.now=function(e){return p.fromDate(new Date,e)};var w=new p(0,0,c.TAI);return p.toGregorianDate=function(e,t){var n=!1,i=h(e,w);r(i)||(p.addSeconds(e,-1,w),i=h(w,w),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var m=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),n&&(v+=1),r(t)?(t.year=y,t.month=m,t.day=E,t.hour=_,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=n,t):new a(y,m,E,_,R,v,A,n)},p.toDate=function(e){var t=p.toGregorianDate(e,m),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},p.toIso8601=function(t,n){var i,a=p.toGregorianDate(t,m);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},p.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new p(e.dayNumber,e.secondsOfDay,c.TAI)},p.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},p.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},p.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(p.secondsDifference(e,t))<=n},p.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},p.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},p.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},p.computeTaiMinusUtc=function(e){_.julianDate=e;var n=p.leapSeconds,r=t(n,_,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},p.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},p.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},p.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},p.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},p.lessThan=function(e,t){return p.compare(e,t)<0},p.lessThanOrEquals=function(e,t){return p.compare(e,t)<=0},p.greaterThan=function(e,t){return p.compare(e,t)>0},p.greaterThanOrEquals=function(e,t){return p.compare(e,t)>=0},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p.prototype.equalsEpsilon=function(e,t){return p.equalsEpsilon(this,e,t)},p.prototype.toString=function(){return p.toIso8601(this)},p.leapSeconds=[new u(new p(2441317,43210,c.TAI),10),new u(new p(2441499,43211,c.TAI),11),new u(new p(2441683,43212,c.TAI),12),new u(new p(2442048,43213,c.TAI),13),new u(new p(2442413,43214,c.TAI),14),new u(new p(2442778,43215,c.TAI),15),new u(new p(2443144,43216,c.TAI),16),new u(new p(2443509,43217,c.TAI),17),new u(new p(2443874,43218,c.TAI),18),new u(new p(2444239,43219,c.TAI),19),new u(new p(2444786,43220,c.TAI),20),new u(new p(2445151,43221,c.TAI),21),new u(new p(2445516,43222,c.TAI),22),new u(new p(2446247,43223,c.TAI),23),new u(new p(2447161,43224,c.TAI),24),new u(new p(2447892,43225,c.TAI),25),new u(new p(2448257,43226,c.TAI),26),new u(new p(2448804,43227,c.TAI),27),new u(new p(2449169,43228,c.TAI),28),new u(new p(2449534,43229,c.TAI),29),new u(new p(2450083,43230,c.TAI),30),new u(new p(2450630,43231,c.TAI),31),new u(new p(2451179,43232,c.TAI),32),new u(new p(2453736,43233,c.TAI),33),new u(new p(2454832,43234,c.TAI),34),new u(new p(2456109,43235,c.TAI),35),new u(new p(2457204,43236,c.TAI),36),new u(new p(2457754,43237,c.TAI),37)],p}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict" +;function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function p(e){return function(t){e.state!==c.CANCELLED&&(--v.numberOfActiveRequests,--N[e.serverKey],I.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==c.CANCELLED&&(++v.numberOfFailedRequests,--v.numberOfActiveRequests,--N[e.serverKey],I.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function y(e){var t=E(e);return e.state=c.ACTIVE,g.push(e),++v.numberOfActiveRequests,++v.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(p(e)).otherwise(m(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++v.numberOfCancelledRequests,e.deferred.reject(),t&&(--v.numberOfActiveRequests,--N[e.serverKey],++v.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){v.numberOfAttemptedRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(v.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+v.numberOfAttemptedRequests),v.numberOfActiveRequests>0&&console.log("Number of active requests: "+v.numberOfActiveRequests),v.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+v.numberOfCancelledRequests),v.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+v.numberOfCancelledActiveRequests),v.numberOfFailedRequests>0&&console.log("Number of failed requests: "+v.numberOfFailedRequests),T())}var v={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var g=[],N={},O="undefined"!=typeof document?new e(document.location.href):new e,I=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=I,i(f,{statistics:{get:function(){return v}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&_(t),t.state===c.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(y(t),++u):_(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=N[i];return r(a)||(N[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return I.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++v.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return y(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(r(t)){if(t===e)return;_(t)}return E(e)}},f.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=g.length,t=0;t<e;++t)_(g[t]);g.length=0,N={},v.numberOfAttemptedRequests=0,v.numberOfActiveRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0,v.numberOfFailedRequests=0,v.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,p,m,y,_,T,R,v,A,S,g,N){"use strict";function O(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=y(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function I(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=m(n):e.query=r[0]}function w(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function M(e){if(e.state===v.ISSUED||e.state===v.ACTIVE)throw new A("The Resource is already being fetched.");e.state=v.UNISSUED,e.deferred=void 0}function x(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=w(e.templateValues,{}),this._queryParameters=w(e.queryParameters,{}),this.headers=w(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=N.defer();return x._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==v.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,C(e,t)):N.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=N.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},x._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==v.FAILED?N.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=v.UNISSUED,i.deferred=void 0,P(e,t,n)):N.reject(r)})})}function U(e,t){M(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=x._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==v.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,e.fetch(t)):N.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var B=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();x.createIfNeeded=function(e,t){if(e instanceof x)return e.clone();if("string"!=typeof e)return e;var n=w(t,{});return n.url=e,new x(n)},o(x,{isBlobSupported:{get:function(){return B}}}),o(x.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);O(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return p(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),x.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new g(this._url);e&&I(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},x.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},x.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},x.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new g(e.url);O(n,t),n.fragment=void 0,t._url=n.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},x.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var n=this;return N(t(this,e)).then(function(e){return++n._retryCount,e})},x.prototype.clone=function(e){return a(e)||(e=new x({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},x.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},x.prototype.appendForwardSlash=function(){this._url=e(this._url)},x.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},x.fetchArrayBuffer=function(e){return new x(e).fetchArrayBuffer()},x.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},x.fetchBlob=function(e){return new x(e).fetchBlob()},x.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),M(this.request),!B||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new x({url:t}),C(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),N.reject(e)})}},x.fetchImage=function(e){return new x(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},x.prototype.fetchText=function(){return this.fetch({responseType:"text"})},x.fetchText=function(e){return new x(e).fetchText()},x.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},x.fetchJson=function(e){return new x(e).fetchJson()},x.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},x.fetchXML=function(e){return new x(e).fetchXML()},x.prototype.fetchJsonp=function(e){e=i(e,"callback"),M(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},x.fetchJsonp=function(e){return new x(e).fetchJsonp(e.callbackParameterName)},x.prototype.fetch=function(e){return e=w(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var b=/^data:(.*?)(;base64)?,(.*)$/;return x.fetch=function(e){return new x(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x.prototype.post=function(e,n){return t.defined("data",e),n=w(n,{}),n.method="POST",n.data=e,U(this,n)},x.post=function(e){return new x(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x._Implementations={},x._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(S.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},x._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=b.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},x._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},x._DefaultImplementations={},x._DefaultImplementations.createImage=x._Implementations.createImage,x._DefaultImplementations.loadWithXhr=x._Implementations.loadWithXhr,x._DefaultImplementations.loadAndExecuteScript=x._Implementations.loadAndExecuteScript,x.DEFAULT=c(new x({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),x}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),p=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||E<0||p<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var m=e._samples=n.samples,y=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=p,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,R=0,v=m.length;R<v;R+=e._columnCount){var A=m[R+i],S=m[R+p],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,S,f.TAI);if(y.push(N),T){if(S!==_&&r(_)){var O=o.leapSeconds,I=t(O,N,d);if(I<0){var w=new u(N,S);O.splice(~I,0,w)}}_=S}}}function p(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function m(e,t,n){return t+e*(n-t)}function y(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return p(e,n,i,s,u),u;if(r.equals(l))return p(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,E=n[h+e._ut1MinusUtcSecondsColumn],y=n[d+e._ut1MinusUtcSecondsColumn],_=y-E;if(_>.5||_<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=y:y-=R-T)}return u.xPoleWander=m(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=m(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=m(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=m(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=m(f,E,y),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),p=E||o.greaterThanOrEquals(h,e);if(d&&p)return s=u,!E&&h.equals(e)&&++s,l=s+1,y(this,a,this._samples,e,s,l,n),n}var m=t(a,e,o.compare,this._dateColumn);return m>=0?(m<a.length-1&&a[m+1].equals(e)&&++m,s=m,l=m):(l=~m,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var E,p,m=a-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)y[E]=m-R[E];for(E=0;E<=u;++E){for(T[E]=1,p=0;p<=u;++p)p!==E&&(T[E]*=y[p]);T[E]*=_[E];var v=3*(s+E);n.x+=T[E]*d[v++],n.y+=T[E]*d[v++],n.s+=T[E]*d[v]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],p=h+d+E;if(p>0)n=Math.sqrt(p+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var m=l,y=0;d>h&&(y=1),E>h&&E>d&&(y=2);var _=m[y],T=m[_];n=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var R=f;R[y]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*n,R[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*n,R[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,E=new s,p=new s;s.fromHeadingPitchRoll=function(t,n){return p=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,p,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var m=new e,y=new e,_=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,R,_),_.w<0&&s.negate(_,_),s.computeAxis(_,m);var u=s.computeAngle(_);r[o]=m.x*u,r[o+1]=m.y*u,r[o+2]=m.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,E=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),g=s.multiplyByScalar(a,Math.sin(n*u),g),r=s.add(S,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var N=new e,O=new e,I=new s,w=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,I);s.multiply(a,r,w);var o=s.log(w,N);s.multiply(a,t,w);var u=s.log(w,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,I),u=s.slerp(n,r,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var M=new s,x=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;C[L]=1/(F*B),P[L]=F/B}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,M);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,I),u=s.fastSlerp(n,r,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){ +return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,p,m,y,_,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,O=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=v[e][t],a=e+t;return u(S[a])?r=S[a]:(r=function(r,a,s){if(u(s)||(s=new y),p.equalsEpsilon(r.x,0,p.EPSILON14)&&p.equalsEpsilon(r.y,0,p.EPSILON14)){var c=p.sign(r.z);n.unpack(A[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(A[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(A[i],0,I),"east"!==i&&"west"!==i&&n.multiplyByScalar(I,c,I)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),N=g[e],O=g[t],I=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},S[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var w=new _,M=new n(1,1,1),x=new y;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=y.fromTranslationQuaternionRotationScale(n.ZERO,u,M,x);return a=i(e,r,a),y.multiply(a,s,a)};var C=new y,P=new m;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=y.getRotation(a,P);return _.fromRotationMatrix(o,i)};var U=p.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%p.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new m(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new m);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return m.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new m,b=new m;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new m);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=m.fromRotationZ(-a.s,b),h=m.multiply(l,f,B),d=e.dayNumber,y=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,_=d-2451545,v=y/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(_+v);A=A%1*p.TWO_PI;var S=m.fromRotationZ(A,b),g=m.multiply(h,S,B),N=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),w=Math.sin(n.yPoleWander),M=r-2451545+i/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*p.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=b;return U[0]=N*C,U[1]=N*P,U[2]=I,U[3]=-O*P+w*I*C,U[4]=O*C+w*I*P,U[5]=-w*N,U[6]=-w*P-O*I*C,U[7]=w*C-O*I*P,U[8]=O*N,m.multiply(g,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return y.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,p.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new m),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new n,Y=new n,k=new m,j=new y,Z=new y;return R.basisTo2D=function(e,t,r){var i=y.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,r);return y.multiply(W,f,r),y.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=y.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(W,o,r),y.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,p)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,p));var a=n.fromCartesian4(l.getColumn(r,2,p));this._plane=f.fromPointNormal(e,a)}var p=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var m=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,m).center,n)};var y=new h,_=new n;E.prototype.projectPointOntoPlane=function(e,r){var i=y;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=y;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var i=e[r];U=t.cartesianToCartographic(i,U),n[r]=U.height,e[r]=t.scaleToGeodeticSurface(i,i)}return n}function d(e,n,r,i){var a,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/i),l=new Array(c);if(n===r){for(a=0;a<c;a++)l[a]=n;return l.push(r),l}var f=r-n,h=f/c;for(a=1;a<c;a++){var d=n+a*h;l[a]=d}return l[0]=n,l.push(r),l}function E(n,r,i,o){var u=new a(i,o),s=u.projectPointOntoPlane(t.add(i,n,D),D),c=u.projectPointOntoPlane(t.add(i,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function p(e,n,r,i,a,o,c,l){var h=G,d=V;B=f.eastNorthUpToFixedFrame(e,a,B),h=s.multiplyByPointAsVector(B,F,h),h=t.normalize(h,h);var p=E(h,n,e,a);z=u.fromRotationZ(p,z),W.z=o,B=s.multiplyTransformation(B,s.fromRotationTranslation(z,W,b),B);var m=q;m[0]=c;for(var y=0;y<l;y++)for(var _=0;_<r.length;_+=3)d=t.fromArray(r,_,d),d=u.multiplyByVector(m,d,d),d=s.multiplyByPoint(B,d,d),i.push(d.x,d.y,d.z);return i}function m(e,n,r,i,a,o,u){for(var s=0;s<e.length;s+=3){i=p(t.fromArray(e,s,X),n,r,i,a,o[s/3],u,1)}return i}function y(e,t){var n=e.length,r=new Array(6*n),i=0,a=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[i++]=u.x-a,r[i++]=0,r[i++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-a,l=u.y-o;r[i++]=c,r[i++]=0,r[i++]=l,r[i++]=c,r[i++]=0,r[i++]=l}return u=e[0],r[i++]=u.x-a,r[i++]=0,r[i++]=u.y-o,r}function _(e,t){for(var n=e.length,r=new Array(3*n),i=0,a=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[i++]=e[u].x-a,r[i++]=0,r[i++]=e[u].y-o;return r}function T(e,n,r,a,s,c,f,h,d,E){var m,y=t.angleBetween(t.subtract(n,e,x),t.subtract(r,e,C)),_=a===i.BEVELED?0:Math.ceil(y/o.toRadians(5));m=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,x),y/(_+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,y/(_+1),H),k);var T,R;if(n=t.clone(n,Y),_>0)for(var v=E?2:1,A=0;A<_;A++)n=u.multiplyByVector(m,n,n),T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=p(R,T,h,f,c,d,1,v);else T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=p(R,T,h,f,c,d,1,1),r=t.clone(r,Y),T=t.subtract(r,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(r,C),f=p(R,T,h,f,c,d,1,1);return f}var R=[new t,new t],v=new t,A=new t,S=new t,g=new t,N=new t,O=new t,I=new t,w=new t,M=new t,x=new t,C=new t,P={},U=new r,D=new t,L=new t,F=new t(-1,0,0),B=new s,b=new s,z=new u,q=u.IDENTITY.clone(),G=new t,V=new n,W=new t,X=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],i=n-1,a=0;a<n;i=a++){var o=t[i],u=t[a];e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,i){var o=new a(r,i),u=o.projectPointOntoPlane(t.add(r,e,D),D),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var j=new t,Z=new t;return P.computePositions=function(e,n,r,a,u){var s=a._ellipsoid,l=h(e,s),f=a._granularity,E=a._cornerType,C=u?y(n,r):_(n,r),U=u?_(n,r):void 0,D=r.height/2,L=r.width/2,F=e.length,B=[],b=u?[]:void 0,z=v,q=A,G=S,V=g,W=N,X=O,H=I,Y=w,k=M,K=e[0],J=e[1];V=s.geodeticSurfaceNormal(K,V),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(b=p(K,Y,U,b,s,Q+D,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<F-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),V=s.geodeticSurfaceNormal(K,V);var ie=t.multiplyByScalar(V,t.dot(z,V),j);t.subtract(z,ie,ie),t.normalize(ie,ie);var ae=t.multiplyByScalar(V,t.dot(q,V),Z);t.subtract(q,ae,ae),t.normalize(ae,ae);if(!o.equalsEpsilon(Math.abs(t.dot(ie,ae)),1,o.EPSILON7)){G=t.cross(G,V,G),G=t.cross(V,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,x))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=m(te,Y,C,B,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,L,H),H),E===i.ROUNDED||E===i.BEVELED?T(W,X,H,E,ue,s,B,C,$+D,u):(G=t.negate(G,G),B=p(K,G,C,B,s,$+D,oe,re)),k=t.clone(H,k)):(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,-L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=m(te,Y,C,B,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,-L,H),H),E===i.ROUNDED||E===i.BEVELED?T(W,X,H,E,ue,s,B,C,$+D,u):B=p(K,G,C,B,s,$+D,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else B=p(k,Y,C,B,s,Q+D,1,1),k=K;Q=$,$=l[ne+1],K=J}R[0]=t.clone(k,R[0]),R[1]=t.clone(K,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=m(te,Y,C,B,s,ee,1),u&&(b=p(K,Y,U,b,s,$+D,1,1)),F=B.length;var se=u?F+b.length:F,ce=new Float64Array(se);return ce.set(B),u&&ce.set(b,F),ce},P}),define("Core/CorridorGeometryLibrary",["./Cartesian3","./CornerType","./defined","./Math","./Matrix3","./PolylinePipeline","./PolylineVolumeGeometryLibrary","./Quaternion"],function(e,t,n,r,i,a,o,u){"use strict";function s(n,a,o,s,c){var l=e.angleBetween(e.subtract(a,n,d),e.subtract(o,n,E)),f=s===t.BEVELED?1:Math.ceil(l/r.toRadians(5))+1,h=3*f,p=new Array(h);p[h-3]=o.x,p[h-2]=o.y,p[h-1]=o.z;var m;m=c?i.fromQuaternion(u.fromAxisAngle(e.negate(n,d),l/f,w),M):i.fromQuaternion(u.fromAxisAngle(n,l/f,w),M);var y=0;a=e.clone(a,d);for(var _=0;_<f;_++)a=i.multiplyByVector(m,a,a),p[y++]=a.x,p[y++]=a.y,p[y++]=a.z;return p}function c(n){var r=_,i=T,a=R,o=n[1];i=e.fromArray(n[1],o.length-3,i),a=e.fromArray(n[0],0,a),r=e.multiplyByScalar(e.add(i,a,r),.5,r);var u=s(r,i,a,t.ROUNDED,!1),c=n.length-1,l=n[c-1];return o=n[c],i=e.fromArray(l,l.length-3,i),a=e.fromArray(o,0,a),r=e.multiplyByScalar(e.add(i,a,r),.5,r),[u,s(r,i,a,t.ROUNDED,!1)]}function l(t,n,r,i){var a=d;return i?a=e.add(t,n,a):(n=e.negate(n,n),a=e.add(t,n,a)),[a.x,a.y,a.z,r.x,r.y,r.z]}function f(t,n,r,i){for(var a=new Array(t.length),o=new Array(t.length),u=e.multiplyByScalar(n,r,d),s=e.negate(u,E),c=0,l=t.length-1,f=0;f<t.length;f+=3){var h=e.fromArray(t,f,p),y=e.add(h,s,m);a[c++]=y.x,a[c++]=y.y,a[c++]=y.z;var _=e.add(h,u,m);o[l--]=_.z,o[l--]=_.y,o[l--]=_.x}return i.push(a,o),i}var h={},d=new e,E=new e,p=new e,m=new e,y=[new e,new e],_=new e,T=new e,R=new e,v=new e,A=new e,S=new e,g=new e,N=new e,O=new e,I=new e,w=new u,M=new i;h.addAttribute=function(e,t,r,i){var a=t.x,o=t.y,u=t.z;n(r)&&(e[r]=a,e[r+1]=o,e[r+2]=u),n(i)&&(e[i]=u,e[i-1]=o,e[i-2]=a)};var x=new e,C=new e;return h.computePositions=function(n){var i=n.granularity,u=n.positions,h=n.ellipsoid,E=n.width/2,p=n.cornerType,m=n.saveAttributes,w=_,M=T,P=R,U=v,D=A,L=S,F=g,B=N,b=O,z=I,q=[],G=m?[]:void 0,V=m?[]:void 0,W=u[0],X=u[1];M=e.normalize(e.subtract(X,W,M),M),w=h.geodeticSurfaceNormal(W,w),U=e.normalize(e.cross(w,M,U),U),m&&(G.push(U.x,U.y,U.z),V.push(w.x,w.y,w.z)),F=e.clone(W,F),W=X,P=e.negate(M,P);var H,Y,k=[],j=u.length;for(Y=1;Y<j-1;Y++){w=h.geodeticSurfaceNormal(W,w),X=u[Y+1],M=e.normalize(e.subtract(X,W,M),M),D=e.normalize(e.add(M,P,D),D);var Z=e.multiplyByScalar(w,e.dot(M,w),x);e.subtract(M,Z,Z),e.normalize(Z,Z);var K=e.multiplyByScalar(w,e.dot(P,w),C);e.subtract(P,K,K),e.normalize(K,K);if(!r.equalsEpsilon(Math.abs(e.dot(Z,K)),1,r.EPSILON7)){D=e.cross(D,w,D),D=e.cross(w,D,D),D=e.normalize(D,D);var J=E/Math.max(.25,e.magnitude(e.cross(D,P,d))),Q=o.angleIsGreaterThanPi(M,P,W,h);D=e.multiplyByScalar(D,J,D),Q?(B=e.add(W,D,B),z=e.add(B,e.multiplyByScalar(U,E,z),z),b=e.add(B,e.multiplyByScalar(U,2*E,b),b),y[0]=e.clone(F,y[0]),y[1]=e.clone(z,y[1]),H=a.generateArc({positions:y,granularity:i,ellipsoid:h}),q=f(H,U,E,q),m&&(G.push(U.x,U.y,U.z),V.push(w.x,w.y,w.z)),L=e.clone(b,L),U=e.normalize(e.cross(w,M,U),U),b=e.add(B,e.multiplyByScalar(U,2*E,b),b),F=e.add(B,e.multiplyByScalar(U,E,F),F),p===t.ROUNDED||p===t.BEVELED?k.push({leftPositions:s(B,L,b,p,Q)}):k.push({leftPositions:l(W,e.negate(D,D),b,Q)})):(b=e.add(W,D,b),z=e.add(b,e.negate(e.multiplyByScalar(U,E,z),z),z),B=e.add(b,e.negate(e.multiplyByScalar(U,2*E,B),B),B),y[0]=e.clone(F,y[0]),y[1]=e.clone(z,y[1]),H=a.generateArc({positions:y,granularity:i,ellipsoid:h}),q=f(H,U,E,q),m&&(G.push(U.x,U.y,U.z),V.push(w.x,w.y,w.z)),L=e.clone(B,L),U=e.normalize(e.cross(w,M,U),U),B=e.add(b,e.negate(e.multiplyByScalar(U,2*E,B),B),B),F=e.add(b,e.negate(e.multiplyByScalar(U,E,F),F),F),p===t.ROUNDED||p===t.BEVELED?k.push({rightPositions:s(b,L,B,p,Q)}):k.push({rightPositions:l(W,D,B,Q)})),P=e.negate(M,P)}W=X}w=h.geodeticSurfaceNormal(W,w),y[0]=e.clone(F,y[0]),y[1]=e.clone(W,y[1]),H=a.generateArc({positions:y,granularity:i,ellipsoid:h}),q=f(H,U,E,q),m&&(G.push(U.x,U.y,U.z),V.push(w.x,w.y,w.z));var $;return p===t.ROUNDED&&($=c(q)),{positions:q,corners:k,lefts:G,normals:V,endPositions:$}},h}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,E,p,m;if(a&&(u=s(e,n,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var y=i;y<o;y+=i)E=e[y],p=e[y+1],E<l&&(l=E),p<f&&(f=p),E>h&&(h=E),p>d&&(d=p);m=Math.max(h-l,d-f)}return r(u,c,i,l,f,m),c}function t(e,t,n,r,i){var a,o;if(i===w(e,t,n,r)>0)for(a=t;a<n;a+=r)o=N(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=N(a,e[a],e[a+1],o);return o&&T(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==_(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,p,m=e;e.prev!==e.next;)if(E=e.prev,p=e.next,f?a(e,c,l,f):i(e))t.push(E.i/s),t.push(e.i/s),t.push(p.i/s),O(e),e=p.next,m=p.next;else if((e=p)===m){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(_(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(m(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!T(i,a)&&R(i,r,r.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),O(r),O(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&y(s,c)){var l=g(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,i,a,o,u),void r(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,f=o<u-1?r[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(p(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=g(t,e);n(r,r.next)}}function f(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=l&&m(a<f?i:o,a,l,f,a<f?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var i=e;do{null===i.z&&(i.z=E(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function p(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function m(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function y(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function _(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||_(e,t,n)>0!=_(e,t,r)>0&&_(n,r,e)>0!=_(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function S(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function g(e,t){var n=new I(e.i,e.x,e.y),r=new I(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function N(e,t,n,r){var i=new I(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function w(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(w(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(w(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,p={};p.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},p.computeWindingOrder2D=function(e){return p.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},p.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var m=new n,y=new n,_=new n,T=new n,R=new n,v=new n,A=new n;return p.computeSubdivision=function(e,t,r,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,p=new Array(3*E),S=0;for(h=0;h<E;h++){var g=t[h];p[S++]=g.x,p[S++]=g.y,p[S++]=g.z}for(var N=[],O={},I=e.maximumRadius,w=l.chordLength(u,I),M=w*w;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(p,3*D,m),F=n.fromArray(p,3*U,y),B=n.fromArray(p,3*P,_),b=n.multiplyByScalar(n.normalize(L,T),I,T),z=n.multiplyByScalar(n.normalize(F,R),I,R),q=n.multiplyByScalar(n.normalize(B,v),I,v),G=n.magnitudeSquared(n.subtract(b,z,A)),V=n.magnitudeSquared(n.subtract(z,q,A)),W=n.magnitudeSquared(n.subtract(q,b,A)),X=Math.max(G,V,W);X>M?G===X?(x=Math.min(D,U)+" "+Math.max(D,U),h=O[x],o(h)||(C=n.add(L,F,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),h=p.length/3-1,O[x]=h),d.push(D,h,P),d.push(h,U,P)):V===X?(x=Math.min(U,P)+" "+Math.max(U,P),h=O[x],o(h)||(C=n.add(F,B,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),h=p.length/3-1,O[x]=h),d.push(U,h,D),d.push(h,P,D)):W===X&&(x=Math.min(P,D)+" "+Math.max(P,D),h=O[x],o(h)||(C=n.add(B,L,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),h=p.length/3-1,O[x]=h),d.push(P,h,U),d.push(h,D,U)):(N.push(D),N.push(U),N.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:p})},indices:N,primitiveType:f.TRIANGLES})},p.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=d,c=E;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},p}),define("Core/CorridorOutlineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./CornerType","./CorridorGeometryLibrary","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,p,m){"use strict";function y(e,t){for(var n=0;n<e.length;n++)e[n]=t.scaleToGeodeticSurface(e[n],e[n]);return e}function _(e,t){var r,u,c,l=[],E=e.positions,p=e.corners,m=e.endPositions,y=new h,_=0,T=0,R=0;for(u=0;u<E.length;u+=2)c=E[u].length-3,_+=c,R+=c/3*4,T+=E[u+1].length-3;for(_+=3,T+=3,u=0;u<p.length;u++){r=p[u];var g=p[u].leftPositions;s(g)?(c=g.length,_+=c,R+=c/3*2):(c=p[u].rightPositions.length,T+=c,R+=c/3*2)}var N,O=s(m);O&&(N=m[0].length-3,_+=N,T+=N,N/=3,R+=4*N);var I,w,M,x,C,P,U=_+T,D=new Float64Array(U),L=0,F=U-1,B=N/2,b=d.createTypedArray(U/3,R+4),z=0;if(b[z++]=L/3,b[z++]=(F-2)/3,O){l.push(L/3),P=v,C=A;var q=m[0];for(u=0;u<B;u++)P=n.fromArray(q,3*(B-1-u),P),C=n.fromArray(q,3*(B+u),C),o.addAttribute(D,C,L),o.addAttribute(D,P,void 0,F),w=L/3,x=w+1,I=(F-2)/3,M=I-1,b[z++]=I,b[z++]=M,b[z++]=w,b[z++]=x,L+=3,F-=3}var G=0,V=E[G++],W=E[G++];for(D.set(V,L),D.set(W,F-W.length+1),c=W.length-3,l.push(L/3,(F-2)/3),u=0;u<c;u+=3)w=L/3,x=w+1,I=(F-2)/3,M=I-1,b[z++]=I,b[z++]=M,b[z++]=w,b[z++]=x,L+=3,F-=3;for(u=0;u<p.length;u++){var X;r=p[u];var H,Y=r.leftPositions,k=r.rightPositions,j=S;if(s(Y)){for(F-=3,H=M,l.push(x),X=0;X<Y.length/3;X++)j=n.fromArray(Y,3*X,j),b[z++]=H-X-1,b[z++]=H-X,o.addAttribute(D,j,void 0,F),F-=3;l.push(H-Math.floor(Y.length/6)),t===a.BEVELED&&l.push((F-2)/3+1),L+=3}else{for(L+=3,H=x,l.push(M),X=0;X<k.length/3;X++)j=n.fromArray(k,3*X,j),b[z++]=H+X,b[z++]=H+X+1,o.addAttribute(D,j,L),L+=3;l.push(H+Math.floor(k.length/6)),t===a.BEVELED&&l.push(L/3-1),F-=3}for(V=E[G++],W=E[G++],V.splice(0,3),W.splice(W.length-3,3),D.set(V,L),D.set(W,F-W.length+1),c=W.length-3,X=0;X<W.length;X+=3)x=L/3,w=x-1,M=(F-2)/3,I=M+1,b[z++]=I,b[z++]=M,b[z++]=w,b[z++]=x,L+=3,F-=3;L-=3,F+=3,l.push(L/3,(F-2)/3)}if(O){L+=3,F-=3,P=v,C=A;var Z=m[1];for(u=0;u<B;u++)P=n.fromArray(Z,3*(N-u-1),P),C=n.fromArray(Z,3*u,C),o.addAttribute(D,P,void 0,F),o.addAttribute(D,C,L),x=L/3,w=x-1,M=(F-2)/3,I=M+1,b[z++]=I,b[z++]=M,b[z++]=w,b[z++]=x,L+=3,F-=3;l.push(L/3)}else l.push(L/3,(F-2)/3);return b[z++]=L/3,b[z++]=(F-2)/3,y.position=new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:D}),{attributes:y,indices:b,wallIndices:l}}function T(e){var t=e.ellipsoid,n=o.computePositions(e),r=_(n,e.cornerType),i=r.wallIndices,a=e.height,u=e.extrudedHeight,s=r.attributes,c=r.indices,l=s.position.values,f=l.length,h=new Float64Array(f);h.set(l);var E=new Float64Array(2*f);l=p.scaleToGeodeticHeight(l,a,t),h=p.scaleToGeodeticHeight(h,u,t),E.set(l),E.set(h,f),s.position.values=E,f/=3;var m,y=c.length,T=d.createTypedArray(E.length/3,2*(y+i.length));T.set(c);var R=y;for(m=0;m<y;m+=2){var v=c[m],A=c[m+1];T[R++]=v+f,T[R++]=A+f}var S,g;for(m=0;m<i.length;m++)S=i[m],g=S+f,T[R++]=S,T[R++]=g;return{attributes:s,indices:T}}function R(e){e=u(e,u.EMPTY_OBJECT);var t=e.positions,r=e.width;this._positions=t,this._ellipsoid=c.clone(u(e.ellipsoid,c.WGS84)),this._width=r,this._height=u(e.height,0),this._extrudedHeight=u(e.extrudedHeight,this._height),this._cornerType=u(e.cornerType,a.ROUNDED), +this._granularity=u(e.granularity,E.RADIANS_PER_DEGREE),this._workerName="createCorridorOutlineGeometry",this.packedLength=1+t.length*n.packedLength+c.packedLength+5}var v=new n,A=new n,S=new n;R.pack=function(e,t,r){r=u(r,0);var i=e._positions,a=i.length;t[r++]=a;for(var o=0;o<a;++o,r+=n.packedLength)n.pack(i[o],t,r);return c.pack(e._ellipsoid,t,r),r+=c.packedLength,t[r++]=e._width,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._cornerType,t[r]=e._granularity,t};var g=c.clone(c.UNIT_SPHERE),N={positions:void 0,ellipsoid:g,width:void 0,height:void 0,extrudedHeight:void 0,cornerType:void 0,granularity:void 0};return R.unpack=function(e,t,r){t=u(t,0);for(var i=e[t++],a=new Array(i),o=0;o<i;++o,t+=n.packedLength)a[o]=n.unpack(e,t);var l=c.unpack(e,t,g);t+=c.packedLength;var f=e[t++],h=e[t++],d=e[t++],E=e[t++],p=e[t];return s(r)?(r._positions=a,r._ellipsoid=c.clone(l,r._ellipsoid),r._width=f,r._height=h,r._extrudedHeight=d,r._cornerType=E,r._granularity=p,r):(N.positions=a,N.width=f,N.height=h,N.extrudedHeight=d,N.cornerType=E,N.granularity=p,new R(N))},R.createGeometry=function(r){var i=r._positions,a=r._height,u=r._width,s=r._extrudedHeight,c=a!==s,f=r._ellipsoid;i=y(i,f);var h=e(i,n.equalsEpsilon);if(!(h.length<2||u<=0)){var d,E={ellipsoid:f,positions:h,width:u,cornerType:r._cornerType,granularity:r._granularity,saveAttributes:!1};if(c){var R=Math.max(a,s);s=Math.min(a,s),a=R,E.height=a,E.extrudedHeight=s,d=T(E)}else{d=_(o.computePositions(E),E.cornerType),d.attributes.position.values=p.scaleToGeodeticHeight(d.attributes.position.values,a,f)}var v=d.attributes,A=t.fromVertices(v.position.values,void 0,3);return new l({attributes:v,indices:d.indices,primitiveType:m.LINES,boundingSphere:A})}},R}),define("Workers/createCorridorOutlineGeometry",["../Core/CorridorOutlineGeometry","../Core/defined","../Core/Ellipsoid"],function(e,t,n){"use strict";function r(r,i){return t(i)&&(r=e.unpack(r,i)),r._ellipsoid=n.clone(r._ellipsoid),e.createGeometry(r)}return r})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderGeometry.js index 56c95704..14a73d08 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,R=a.x,l=a.y,f=a.z,A=c*c*R*R,h=_*_*l*l,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,i);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var m=u.x,O=u.y,M=u.z,y=o;y.x=S.x*m*2,y.y=S.y*O*2,y.z=S.z*M*2;var p,C,U,L,F,P,g,w,v,x,D,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*m),L=1/(1+B*O),F=1/(1+B*M),P=U*U,g=L*L,w=F*F,v=P*U,x=g*L,D=w*F,p=A*P+h*g+N*w-1,C=A*v*m+h*x*O+N*D*M;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*F,s):new t(c*U,_*L,T*F)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=i.EPSILON1;return u.fromCartesian=function(e,n,a){var l=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:R,h=o(e,l,f,A,s);if(r(h)){var N=t.multiplyComponents(h,f,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),m=i.sign(t.dot(d,e))*t.magnitude(d);return r(a)?(a.longitude=I,a.latitude=S,a.height=m,a):new u(I,S,m)}},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,f);if(a(i)){var o=this.geodeticSurfaceNormal(i,l),u=t.subtract(n,i,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(f[i],l[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=l[a],T=f[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(A-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,f=2*(a-T),A=2*(i+c),h=2*(a+T),N=-n+u-_+R,d=2*(s-o),I=2*(i-c),S=2*(s+o),m=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=I,e[3]=f,e[4]=N,e[5]=S,e[6]=A,e[7]=d,e[8]=m,e):new E(l,f,A,h,N,d,I,S,m)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,R=n*u,l=i*a+s*o*u,f=-s*a+i*o*u,A=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=R,e[2]=A,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=f,e[8]=N,e):new E(c,_,T,R,l,f,A,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);i<10&&c(T)>R;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){ -var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,R,l,f,A){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-R-A+N,I=2*(s-h),S=2*(_+f),m=2*(s+h),O=-E+R-A+N,M=2*(l-T),y=2*(_-f),p=2*(l+T),C=-E-R+A+N;return r[0]=d*i,r[1]=m*i,r[2]=y*i,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=M*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,f=_.y,A=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,m=r.z,O=u*-I+E*-S+s*-m,M=h*-I+N*-S+d*-m,y=l*I+f*S+A*m;return a(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=O,n[13]=M,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,M,-l,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,f=i+s,A=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=R,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=l,a[11]=0,a[12]=f,a[13]=A,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],f=t[12],A=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],m=e[3],O=e[4],M=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],F=e[11],P=e[12],g=e[13],w=e[14],v=e[15],x=r*d+u*I+_*S+f*m,D=a*d+E*I+T*S+A*m,B=i*d+s*I+R*S+h*m,z=o*d+c*I+l*S+N*m,G=r*O+u*M+_*y+f*p,b=a*O+E*M+T*y+A*p,X=i*O+s*M+R*y+h*p,V=o*O+c*M+l*y+N*p,q=r*C+u*U+_*L+f*F,H=a*C+E*U+T*L+A*F,W=i*C+s*U+R*L+h*F,Y=o*C+c*U+l*L+N*F,k=r*P+u*g+_*w+f*v,K=a*P+E*g+T*w+A*v,Z=i*P+s*g+R*w+h*v,j=o*P+c*g+l*w+N*v;return n[0]=x,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],f=e[0],A=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],m=e[9],O=e[10],M=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=a*f+u*A+c*h,L=i*f+E*A+_*h,F=r*N+o*d+s*I,P=a*N+u*d+c*I,g=i*N+E*d+_*I,w=r*S+o*m+s*O,v=a*S+u*m+c*O,x=i*S+E*m+_*O,D=r*M+o*y+s*p+T,B=a*M+u*y+c*p+R,z=i*M+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=F,n[5]=P,n[6]=g,n[7]=0,n[8]=w,n[9]=v,n[10]=x,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],f=e[3],A=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*R+s*l,m=a*T+u*R+c*l,O=i*T+E*R+_*l,M=r*f+o*A+s*h,y=a*f+u*A+c*h,p=i*f+E*A+_*h,C=r*N+o*d+s*I,U=a*N+u*d+c*I,L=i*N+E*d+_*I;return n[0]=S,n[1]=m,n[2]=O,n[3]=0,n[4]=M,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],f=t[2],A=t[6],S=t[10],m=t[14],O=t[3],M=t[7],y=t[11],p=t[15],C=S*p,U=m*y,L=A*p,F=m*M,P=A*y,g=S*M,w=f*p,v=m*O,x=f*y,D=S*O,B=f*M,z=A*O,G=C*T+F*R+P*l-(U*T+L*R+g*l),b=U*_+w*R+D*l-(C*_+v*R+x*l),X=L*_+v*T+B*l-(F*_+w*T+z*l),V=g*_+x*T+z*R-(P*_+D*T+B*R),q=U*a+L*i+g*o-(C*a+F*i+P*o),H=C*r+v*i+x*o-(U*r+w*i+D*o),W=F*r+w*a+z*o-(L*r+v*a+B*o),Y=P*r+D*a+B*i-(g*r+x*a+z*i);C=i*l,U=o*R,L=a*l,F=o*T,P=a*R,g=i*T,w=r*l,v=o*_,x=r*R,D=i*_,B=r*T,z=a*_;var k=C*M+F*y+P*p-(U*M+L*y+g*p),K=U*O+w*y+D*p-(C*O+v*y+x*p),Z=L*O+v*M+B*p-(F*O+w*M+z*p),j=g*O+x*M+z*y-(P*O+D*M+B*y),Q=L*S+g*m+U*A-(P*m+C*A+F*S),J=x*m+C*f+v*S-(w*S+D*m+U*f),$=w*A+z*m+F*f-(B*m+L*f+v*A),tt=B*S+P*f+D*A-(x*A+z*S+g*f),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-a*R,f=-i*_-o*T-u*R,A=-E*_-s*T-c*R;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),a=Math.max(a,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;i=Math.min(i,l),o=Math.max(o,l)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,f=t.length;l<f;l++){var A=e.cartesianToCartographic(t[l]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),R=Math.max(R,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=R,a):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,f=s;f.height=a,f.longitude=l,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_){"use strict";function T(e,n){this.center=t.clone(r(e,t.ZERO)),this.radius=r(n,0)}var R=new t,l=new t,f=new t,A=new t,h=new t,N=new t,d=new t,I=new t,S=new t,m=new t,O=new t,M=new t;T.fromPoints=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],d),o=t.clone(i,R),u=t.clone(i,l),E=t.clone(i,f),s=t.clone(i,A),c=t.clone(i,h),_=t.clone(i,N),y=e.length;for(r=1;r<y;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var L=t.magnitudeSquared(t.subtract(s,o,I)),F=t.magnitudeSquared(t.subtract(c,u,I)),P=t.magnitudeSquared(t.subtract(_,E,I)),g=o,w=s,v=L;F>v&&(v=F,g=u,w=c),P>v&&(v=P,g=E,w=_);var x=S;x.x=.5*(g.x+w.x),x.y=.5*(g.y+w.y),x.z=.5*(g.z+w.z);var D=t.magnitudeSquared(t.subtract(w,x,I)),B=Math.sqrt(D),z=m;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,I),.5,M),X=0;for(r=0;r<y;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,I));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(i,x,I));if(q>D){var H=Math.sqrt(q);B=.5*(B+H),D=B*B;var W=H-B;x.x=(B*x.x+W*i.x)/H,x.y=(B*x.y+W*i.y)/H,x.z=(B*x.z+W*i.z)/H}}return B<X?(t.clone(x,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var y=new o,p=new t,C=new t,U=new e,L=new e;T.fromRectangle2D=function(t,e,n){return T.fromRectangleWithHeights2D(t,e,0,0,n)},T.fromRectangleWithHeights2D=function(e,n,i,o,u){if(a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(e,U),U.height=i,_.northeast(e,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*R,f.z=E.z+.5*l,u};var F=[];T.fromRectangle3D=function(e,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=_.subsample(e,n,o,F);return T.fromPoints(E,u)},T.fromVertices=function(e,n,i,o){if(a(o)||(o=new T),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=r(n,t.ZERO),i=r(i,3);var u=d;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,R),c=t.clone(u,l),_=t.clone(u,f),y=t.clone(u,A),p=t.clone(u,h),C=t.clone(u,N),U=e.length;for(E=0;E<U;E+=i){var L=e[E]+n.x,F=e[E+1]+n.y,P=e[E+2]+n.z;u.x=L,u.y=F,u.z=P,L<s.x&&t.clone(u,s),L>y.x&&t.clone(u,y),F<c.y&&t.clone(u,c),F>p.y&&t.clone(u,p),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var g=t.magnitudeSquared(t.subtract(y,s,I)),w=t.magnitudeSquared(t.subtract(p,c,I)),v=t.magnitudeSquared(t.subtract(C,_,I)),x=s,D=y,B=g;w>B&&(B=w,x=c,D=p),v>B&&(B=v,x=_,D=C);var z=S;z.x=.5*(x.x+D.x),z.y=.5*(x.y+D.y),z.z=.5*(x.z+D.z);var G=t.magnitudeSquared(t.subtract(D,z,I)),b=Math.sqrt(G),X=m;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,I),.5,M),H=0;for(E=0;E<U;E+=i){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,I));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new T),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=d;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,R),E=t.clone(i,l),s=t.clone(i,f),c=t.clone(i,A),_=t.clone(i,h),y=t.clone(i,N),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),L<s.z&&t.clone(i,s),L>y.z&&t.clone(i,y)}var F=t.magnitudeSquared(t.subtract(c,u,I)),P=t.magnitudeSquared(t.subtract(_,E,I)),g=t.magnitudeSquared(t.subtract(y,s,I)),w=u,v=c,x=F;P>x&&(x=P,w=E,v=_),g>x&&(x=g,w=s,v=y);var D=S;D.x=.5*(w.x+v.x),D.y=.5*(w.y+v.y),D.z=.5*(w.z+v.z);var B=t.magnitudeSquared(t.subtract(v,D,I)),z=Math.sqrt(B),G=m;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=t.multiplyByScalar(t.add(G,b,I),.5,M),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,X,I));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(i,D,I));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*i.x)/W,D.y=(z*D.y+Y*i.y)/W,D.z=(z*D.z+Y*i.z)/W}}return z<V?(t.clone(D,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(e,n,r){a(r)||(r=new T);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},T.fromEllipsoid=function(e,n){return a(n)||(n=new T),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var P=new t;T.fromBoundingSpheres=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return T.clone(e[0],n);if(2===r)return T.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,P)+s.radius)}return n.radius=E,n};var g=new t,w=new t,v=new t;T.fromOrientedBoundingBox=function(e,n){a(n)||(n=new T);var r=e.halfAxes,i=s.getColumn(r,0,g),o=s.getColumn(r,1,w),u=s.getColumn(r,2,v);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},T.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new T(e.center,e.radius)},T.packedLength=4,T.pack=function(t,e,n){n=r(n,0);var a=t.center;return e[n++]=a.x,e[n++]=a.y,e[n++]=a.z,e[n]=t.radius,e},T.unpack=function(t,e,n){e=r(e,0),a(n)||(n=new T);var i=n.center;return i.x=t[e++],i.y=t[e++],i.z=t[e++],n.radius=t[e],n};var x=new t,D=new t;T.union=function(e,n,r){a(r)||(r=new T);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,x),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=t.multiplyByScalar(s,(-o+_)/c,D);return t.add(R,i,R),t.clone(R,r.center),r.radius=_,r};var B=new t;T.expand=function(e,n,r){r=T.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},T.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},T.transform=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=c.getMaximumScale(e)*t.radius,n};var z=new t;T.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,z);return t.magnitudeSquared(r)-e.radius*e.radius},T.transformWithoutScale=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var G=new t;T.computePlaneDistances=function(e,n,r,i){a(i)||(i=new E);var o=t.subtract(e.center,n,G),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var b=new t,X=new t,V=new t,q=new t,H=new t,W=new e,Y=new Array(8),k=0;k<8;++k)Y[k]=new t;var K=new o;return T.projectTo2D=function(e,n,a){n=r(n,K);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,b),s=t.cross(t.UNIT_Z,E,X);t.normalize(s,s);var c=t.cross(E,s,V);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,H),R=t.negate(s,q),l=Y,f=l[0];t.add(E,c,f),t.add(f,s,f),f=l[1],t.add(E,c,f),t.add(f,R,f),f=l[2],t.add(E,_,f),t.add(f,R,f),f=l[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=l[4],t.add(E,c,f),t.add(f,s,f),f=l[5],t.add(E,c,f),t.add(f,R,f),f=l[6],t.add(E,_,f),t.add(f,R,f),f=l[7],t.add(E,_,f),t.add(f,s,f);for(var A=l.length,h=0;h<A;++h){var N=l[h];t.add(o,N,N);var d=i.cartesianToCartographic(N,W);n.project(d,N)}a=T.fromPoints(l,a),o=a.center;var I=o.x,S=o.y,m=o.z;return o.x=m,o.y=I,o.z=S,a},T.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},T.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},T.prototype.intersectPlane=function(t){return T.intersectPlane(this,t)},T.prototype.distanceSquaredTo=function(t){return T.distanceSquaredTo(this,t)},T.prototype.computePlaneDistances=function(t,e,n){return T.computePlaneDistances(this,t,e,n)},T.prototype.isOccluded=function(t){return T.isOccluded(this,t)},T.prototype.equals=function(t){return T.equals(this,t)},T.prototype.clone=function(t){return T.clone(this,t)},T}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var a=0;a<r;++a)o.pack(t[a],e,2*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),i.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}), -define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,m=r(t[1]))}return S}function i(){return a()&&m}function o(){if(!e(O)&&(O=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,M=r(t[1]))}return O}function u(){return o()&&M}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(L=!0,F=r(t[1]))}return L}function R(){return T()&&F}function l(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(P=!0,g=r(t[1]))}return P}function f(){return e(w)||(w=/Windows/i.test(I.appVersion)),w}function A(){return l()&&g}function h(){return e(v)||(v="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),v}function N(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(x=n)}return D}function d(){return N()?x:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,m,O,M,y,p,C,U,L,F,P,g,w,v,x,D,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CylinderGeometryLibrary",["./Math"],function(t){"use strict";var e={};return e.computePositions=function(e,n,r,a,i){var o,u=.5*e,E=-u,s=a+a,c=i?2*s:s,_=new Float64Array(3*c),T=0,R=0,l=i?3*s:0,f=i?3*(s+a):3*a;for(o=0;o<a;o++){var A=o/a*t.TWO_PI,h=Math.cos(A),N=Math.sin(A),d=h*r,I=N*r,S=h*n,m=N*n;_[R+l]=d,_[R+l+1]=I,_[R+l+2]=E,_[R+f]=S,_[R+f+1]=m,_[R+f+2]=u,R+=3,i&&(_[T++]=d,_[T++]=I,_[T++]=E,_[T++]=S,_[T++]=m,_[T++]=u)}return _},e}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(t){switch(t){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(e){return t(e)&&(e===i.UNSIGNED_BYTE||e===i.UNSIGNED_SHORT||e===i.UNSIGNED_INT)},i.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},i.createTypedArrayFromArrayBuffer=function(t,e,n,a){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,a):new Uint16Array(e,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/CylinderGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CylinderGeometryLibrary","./defaultValue","./defined","./DeveloperError","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c,_,T,R,l){"use strict";function f(t){t=i(t,i.EMPTY_OBJECT);var e=t.length,n=t.topRadius,r=t.bottomRadius,a=i(t.vertexFormat,l.DEFAULT),o=i(t.slices,128);this._length=e,this._topRadius=n,this._bottomRadius=r,this._vertexFormat=l.clone(a),this._slices=o,this._workerName="createCylinderGeometry"}var A=new e,h=new n,N=new n,d=new n,I=new n;f.packedLength=l.packedLength+4,f.pack=function(t,e,n){return n=i(n,0),l.pack(t._vertexFormat,e,n),n+=l.packedLength,e[n++]=t._length,e[n++]=t._topRadius,e[n++]=t._bottomRadius,e[n]=t._slices,e};var S=new l,m={vertexFormat:S,length:void 0,topRadius:void 0,bottomRadius:void 0,slices:void 0};return f.unpack=function(t,e,n){e=i(e,0);var r=l.unpack(t,e,S);e+=l.packedLength;var a=t[e++],u=t[e++],E=t[e++],s=t[e];return o(n)?(n._vertexFormat=l.clone(r,n._vertexFormat),n._length=a,n._topRadius=u,n._bottomRadius=E,n._slices=s,n):(m.length=a,m.topRadius=u,m.bottomRadius=E,m.slices=s,new f(m))},f.createGeometry=function(i){var o=i._length,u=i._topRadius,l=i._bottomRadius,f=i._vertexFormat,S=i._slices;if(!(o<=0||u<0||l<0||0===u&&0===l)){var m,O=S+S,M=S+O,y=O+O,p=a.computePositions(o,u,l,S,!0),C=f.st?new Float32Array(2*y):void 0,U=f.normal?new Float32Array(3*y):void 0,L=f.tangent?new Float32Array(3*y):void 0,F=f.bitangent?new Float32Array(3*y):void 0,P=f.normal||f.tangent||f.bitangent;if(P){var g=f.tangent||f.bitangent,w=0,v=0,x=0,D=h;D.z=0;var B=d,z=N;for(m=0;m<S;m++){var G=m/S*T.TWO_PI,b=Math.cos(G),X=Math.sin(G);P&&(D.x=b,D.y=X,g&&(B=n.normalize(n.cross(n.UNIT_Z,D,B),B)),f.normal&&(U[w++]=b,U[w++]=X,U[w++]=0,U[w++]=b,U[w++]=X,U[w++]=0),f.tangent&&(L[v++]=B.x,L[v++]=B.y,L[v++]=B.z,L[v++]=B.x,L[v++]=B.y,L[v++]=B.z),f.bitangent&&(z=n.normalize(n.cross(D,B,z),z),F[x++]=z.x,F[x++]=z.y,F[x++]=z.z,F[x++]=z.x,F[x++]=z.y,F[x++]=z.z))}for(m=0;m<S;m++)f.normal&&(U[w++]=0,U[w++]=0,U[w++]=-1),f.tangent&&(L[v++]=1,L[v++]=0,L[v++]=0),f.bitangent&&(F[x++]=0,F[x++]=-1,F[x++]=0);for(m=0;m<S;m++)f.normal&&(U[w++]=0,U[w++]=0,U[w++]=1),f.tangent&&(L[v++]=1,L[v++]=0,L[v++]=0),f.bitangent&&(F[x++]=0,F[x++]=1,F[x++]=0)}var V=12*S-12,q=_.createTypedArray(y,V),H=0,W=0;for(m=0;m<S-1;m++)q[H++]=W,q[H++]=W+2,q[H++]=W+3,q[H++]=W,q[H++]=W+3,q[H++]=W+1,W+=2;for(q[H++]=O-2,q[H++]=0,q[H++]=1,q[H++]=O-2,q[H++]=1,q[H++]=O-1,m=1;m<S-1;m++)q[H++]=O+m+1,q[H++]=O+m,q[H++]=O;for(m=1;m<S-1;m++)q[H++]=M,q[H++]=M+m,q[H++]=M+m+1;var Y=0;if(f.st){var k=Math.max(u,l);for(m=0;m<y;m++){var K=n.fromArray(p,3*m,I);C[Y++]=(K.x+k)/(2*k),C[Y++]=(K.y+k)/(2*k)}}var Z=new c;f.position&&(Z.position=new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:p})),f.normal&&(Z.normal=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:U})),f.tangent&&(Z.tangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:L})),f.bitangent&&(Z.bitangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:F})),f.st&&(Z.st=new s({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:C})),A.x=.5*o,A.y=Math.max(l,u);var j=new t(n.ZERO,e.magnitude(A));return new E({attributes:Z,indices:q,primitiveType:R.TRIANGLES,boundingSphere:j})}},f}),define("Workers/createCylinderGeometry",["../Core/CylinderGeometry","../Core/defined"],function(t,e){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,R=a.x,l=a.y,f=a.z,A=c*c*R*R,h=_*_*l*l,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,i);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var m=u.x,O=u.y,M=u.z,y=o;y.x=S.x*m*2,y.y=S.y*O*2,y.z=S.z*M*2;var p,C,U,L,F,P,g,w,v,x,D,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*m),L=1/(1+B*O),F=1/(1+B*M),P=U*U,g=L*L,w=F*F,v=P*U,x=g*L,D=w*F,p=A*P+h*g+N*w-1,C=A*v*m+h*x*O+N*D*M;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*F,s):new t(c*U,_*L,T*F)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=i.EPSILON1;return u.fromCartesian=function(e,n,a){var l=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:R,h=o(e,l,f,A,s);if(r(h)){var N=t.multiplyComponents(h,f,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),m=i.sign(t.dot(d,e))*t.magnitude(d);return r(a)?(a.longitude=I,a.latitude=S,a.height=m,a):new u(I,S,m)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,f);if(a(i)){var o=this.geodeticSurfaceNormal(i,l),u=t.subtract(n,i,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(f[i],l[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=l[a],T=f[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(A-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,f=2*(a-T),A=2*(i+c),h=2*(a+T),N=-n+u-_+R,d=2*(s-o),I=2*(i-c),S=2*(s+o),m=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=I,e[3]=f,e[4]=N,e[5]=S,e[6]=A,e[7]=d,e[8]=m,e):new E(l,f,A,h,N,d,I,S,m)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,R=n*u,l=i*a+s*o*u,f=-s*a+i*o*u,A=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=R,e[2]=A,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=f,e[8]=N,e):new E(c,_,T,R,l,f,A,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);i<10&&c(T)>R;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,R,l,f,A){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-R-A+N,I=2*(s-h),S=2*(_+f),m=2*(s+h),O=-E+R-A+N,M=2*(l-T),y=2*(_-f),p=2*(l+T),C=-E-R+A+N;return r[0]=d*i,r[1]=m*i,r[2]=y*i,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=M*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,f=_.y,A=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,m=r.z,O=u*-I+E*-S+s*-m,M=h*-I+N*-S+d*-m,y=l*I+f*S+A*m;return a(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=O,n[13]=M,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,M,-l,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,f=i+s,A=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=R,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=l,a[11]=0,a[12]=f,a[13]=A,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],f=t[12],A=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],m=e[3],O=e[4],M=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],F=e[11],P=e[12],g=e[13],w=e[14],v=e[15],x=r*d+u*I+_*S+f*m,D=a*d+E*I+T*S+A*m,B=i*d+s*I+R*S+h*m,z=o*d+c*I+l*S+N*m,G=r*O+u*M+_*y+f*p,b=a*O+E*M+T*y+A*p,X=i*O+s*M+R*y+h*p,V=o*O+c*M+l*y+N*p,q=r*C+u*U+_*L+f*F,H=a*C+E*U+T*L+A*F,W=i*C+s*U+R*L+h*F,Y=o*C+c*U+l*L+N*F,k=r*P+u*g+_*w+f*v,K=a*P+E*g+T*w+A*v,Z=i*P+s*g+R*w+h*v,j=o*P+c*g+l*w+N*v;return n[0]=x,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],f=e[0],A=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],m=e[9],O=e[10],M=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=a*f+u*A+c*h,L=i*f+E*A+_*h,F=r*N+o*d+s*I,P=a*N+u*d+c*I,g=i*N+E*d+_*I,w=r*S+o*m+s*O,v=a*S+u*m+c*O,x=i*S+E*m+_*O,D=r*M+o*y+s*p+T,B=a*M+u*y+c*p+R,z=i*M+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=F,n[5]=P,n[6]=g,n[7]=0,n[8]=w,n[9]=v,n[10]=x,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],f=e[3],A=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*R+s*l,m=a*T+u*R+c*l,O=i*T+E*R+_*l,M=r*f+o*A+s*h,y=a*f+u*A+c*h,p=i*f+E*A+_*h,C=r*N+o*d+s*I,U=a*N+u*d+c*I,L=i*N+E*d+_*I;return n[0]=S,n[1]=m,n[2]=O,n[3]=0,n[4]=M,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],f=t[2],A=t[6],S=t[10],m=t[14],O=t[3],M=t[7],y=t[11],p=t[15],C=S*p,U=m*y,L=A*p,F=m*M,P=A*y,g=S*M,w=f*p,v=m*O,x=f*y,D=S*O,B=f*M,z=A*O,G=C*T+F*R+P*l-(U*T+L*R+g*l),b=U*_+w*R+D*l-(C*_+v*R+x*l),X=L*_+v*T+B*l-(F*_+w*T+z*l),V=g*_+x*T+z*R-(P*_+D*T+B*R),q=U*a+L*i+g*o-(C*a+F*i+P*o),H=C*r+v*i+x*o-(U*r+w*i+D*o),W=F*r+w*a+z*o-(L*r+v*a+B*o),Y=P*r+D*a+B*i-(g*r+x*a+z*i);C=i*l,U=o*R,L=a*l,F=o*T,P=a*R,g=i*T,w=r*l,v=o*_,x=r*R,D=i*_,B=r*T,z=a*_;var k=C*M+F*y+P*p-(U*M+L*y+g*p),K=U*O+w*y+D*p-(C*O+v*y+x*p),Z=L*O+v*M+B*p-(F*O+w*M+z*p),j=g*O+x*M+z*y-(P*O+D*M+B*y),Q=L*S+g*m+U*A-(P*m+C*A+F*S),J=x*m+C*f+v*S-(w*S+D*m+U*f),$=w*A+z*m+F*f-(B*m+L*f+v*A),tt=B*S+P*f+D*A-(x*A+z*S+g*f),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-a*R,f=-i*_-o*T-u*R,A=-E*_-s*T-c*R;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),a=Math.max(a,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;i=Math.min(i,l),o=Math.max(o,l)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,f=t.length;l<f;l++){var A=e.cartesianToCartographic(t[l]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),R=Math.max(R,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=R,a):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,f=s;f.height=a,f.longitude=l,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_,T){"use strict";function R(e,n){this.center=t.clone(a(e,t.ZERO)),this.radius=a(n,0)}var l=new t,f=new t,A=new t,h=new t,N=new t,d=new t,I=new t,S=new t,m=new t,O=new t,M=new t,y=new t,p=4/3*n.PI;R.fromPoints=function(e,n){if(i(n)||(n=new R),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,a=t.clone(e[0],I),o=t.clone(a,l),u=t.clone(a,f),E=t.clone(a,A),s=t.clone(a,h),c=t.clone(a,N),_=t.clone(a,d),T=e.length;for(r=1;r<T;r++){t.clone(e[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&t.clone(a,o),p>s.x&&t.clone(a,s),C<u.y&&t.clone(a,u),C>c.y&&t.clone(a,c),U<E.z&&t.clone(a,E),U>_.z&&t.clone(a,_)}var L=t.magnitudeSquared(t.subtract(s,o,S)),F=t.magnitudeSquared(t.subtract(c,u,S)),P=t.magnitudeSquared(t.subtract(_,E,S)),g=o,w=s,v=L;F>v&&(v=F,g=u,w=c),P>v&&(v=P,g=E,w=_);var x=m;x.x=.5*(g.x+w.x),x.y=.5*(g.y+w.y),x.z=.5*(g.z+w.z);var D=t.magnitudeSquared(t.subtract(w,x,S)),B=Math.sqrt(D),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=M;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],a);var V=t.magnitude(t.subtract(a,b,S));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(a,x,S));if(q>D){var H=Math.sqrt(q);B=.5*(B+H),D=B*B;var W=H-B;x.x=(B*x.x+W*a.x)/H,x.y=(B*x.y+W*a.y)/H,x.z=(B*x.z+W*a.z)/H}}return B<X?(t.clone(x,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,L=new t,F=new e,P=new e;R.fromRectangle2D=function(t,e,n){return R.fromRectangleWithHeights2D(t,e,0,0,n)},R.fromRectangleWithHeights2D=function(e,n,r,o,u){if(i(u)||(u=new R),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=a(n,C),T.southwest(e,F),F.height=r,T.northeast(e,P),P.height=o;var E=n.project(F,U),s=n.project(P,L),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*_,f.z=E.z+.5*l,u};var g=[];R.fromRectangle3D=function(e,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new R),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,g);return R.fromPoints(E,u)},R.fromVertices=function(e,n,r,o){if(i(o)||(o=new R),!i(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=a(n,t.ZERO),r=a(r,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,l),c=t.clone(u,f),_=t.clone(u,A),T=t.clone(u,h),p=t.clone(u,N),C=t.clone(u,d),U=e.length;for(E=0;E<U;E+=r){var L=e[E]+n.x,F=e[E+1]+n.y,P=e[E+2]+n.z;u.x=L,u.y=F,u.z=P,L<s.x&&t.clone(u,s),L>T.x&&t.clone(u,T),F<c.y&&t.clone(u,c),F>p.y&&t.clone(u,p),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var g=t.magnitudeSquared(t.subtract(T,s,S)),w=t.magnitudeSquared(t.subtract(p,c,S)),v=t.magnitudeSquared(t.subtract(C,_,S)),x=s,D=T,B=g;w>B&&(B=w,x=c,D=p),v>B&&(B=v,x=_,D=C);var z=m;z.x=.5*(x.x+D.x),z.y=.5*(x.y+D.y),z.z=.5*(x.z+D.z);var G=t.magnitudeSquared(t.subtract(D,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=M;V.x=T.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,S));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},R.fromEncodedCartesianVertices=function(e,n,r){if(i(r)||(r=new R),!i(e)||!i(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var a=I;a.x=e[0]+n[0],a.y=e[1]+n[1],a.z=e[2]+n[2];var o,u=t.clone(a,l),E=t.clone(a,f),s=t.clone(a,A),c=t.clone(a,h),_=t.clone(a,N),T=t.clone(a,d),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&t.clone(a,u),C>c.x&&t.clone(a,c),U<E.y&&t.clone(a,E),U>_.y&&t.clone(a,_),L<s.z&&t.clone(a,s),L>T.z&&t.clone(a,T)}var F=t.magnitudeSquared(t.subtract(c,u,S)),P=t.magnitudeSquared(t.subtract(_,E,S)),g=t.magnitudeSquared(t.subtract(T,s,S)),w=u,v=c,x=F;P>x&&(x=P,w=E,v=_),g>x&&(x=g,w=s,v=T);var D=m;D.x=.5*(w.x+v.x),D.y=.5*(w.y+v.y),D.z=.5*(w.z+v.z);var B=t.magnitudeSquared(t.subtract(v,D,S)),z=Math.sqrt(B),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=M;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){a.x=e[o]+n[o],a.y=e[o+1]+n[o+1],a.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(a,X,S));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(a,D,S));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*a.x)/W,D.y=(z*D.y+Y*a.y)/W,D.z=(z*D.z+Y*a.z)/W}}return z<V?(t.clone(D,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(e,n,r){i(r)||(r=new R);var a=r.center;return t.add(e,n,a),t.multiplyByScalar(a,.5,a),r.radius=t.distance(a,n),r},R.fromEllipsoid=function(e,n){return i(n)||(n=new R),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var w=new t;R.fromBoundingSpheres=function(e,n){if(i(n)||(n=new R),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return R.clone(e[0],n);if(2===r)return R.union(e[0],e[1],n);var a,o=[];for(a=0;a<r;a++)o.push(e[a].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=e[a];E=Math.max(E,t.distance(u,s.center,w)+s.radius)}return n.radius=E,n};var v=new t,x=new t,D=new t;R.fromOrientedBoundingBox=function(e,n){i(n)||(n=new R);var r=e.halfAxes,a=c.getColumn(r,0,v),o=c.getColumn(r,1,x),u=c.getColumn(r,2,D);return t.add(a,o,a),t.add(a,u,a),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(a),n},R.clone=function(e,n){if(i(e))return i(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new R(e.center,e.radius)},R.packedLength=4,R.pack=function(t,e,n){n=a(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},R.unpack=function(t,e,n){e=a(e,0),i(n)||(n=new R);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var B=new t,z=new t;R.union=function(e,n,r){i(r)||(r=new R);var a=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,a,B),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,a,T),t.clone(T,r.center),r.radius=_,r};var G=new t;R.expand=function(e,n,r){r=R.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,G));return a>r.radius&&(r.radius=a),r},R.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?E.OUTSIDE:o<a?E.INTERSECTING:E.INSIDE},R.transform=function(t,e,n){return i(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;R.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},R.transformWithoutScale=function(t,e,n){return i(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;R.computePlaneDistances=function(e,n,r,a){i(a)||(a=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var V=new t,q=new t,H=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return R.projectTo2D=function(e,n,r){n=a(n,j);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,q);t.normalize(s,s);var c=t.cross(E,s,H);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),l=K,f=l[0];t.add(E,c,f),t.add(f,s,f),f=l[1],t.add(E,c,f),t.add(f,T,f),f=l[2],t.add(E,_,f),t.add(f,T,f),f=l[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=l[4],t.add(E,c,f),t.add(f,s,f),f=l[5],t.add(E,c,f),t.add(f,T,f),f=l[6],t.add(E,_,f),t.add(f,T,f),f=l[7],t.add(E,_,f),t.add(f,s,f);for(var A=l.length,h=0;h<A;++h){var N=l[h];t.add(o,N,N);var d=i.cartesianToCartographic(N,k);n.project(d,N)}r=R.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,m=o.z;return o.x=m,o.y=I,o.z=S,r},R.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},R.equals=function(e,n){return e===n||i(e)&&i(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},R.prototype.intersectPlane=function(t){return R.intersectPlane(this,t)},R.prototype.distanceSquaredTo=function(t){return R.distanceSquaredTo(this,t)},R.prototype.computePlaneDistances=function(t,e,n){return R.computePlaneDistances(this,t,e,n)},R.prototype.isOccluded=function(t){return R.isOccluded(this,t)},R.prototype.equals=function(t){return R.equals(this,t)},R.prototype.clone=function(t){return R.clone(this,t)},R.prototype.volume=function(){var t=this.radius;return p*t*t*t},R}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var a=0;a<r;++a)o.pack(t[a],e,2*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),i.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)), +o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,m=r(t[1]))}return S}function i(){return a()&&m}function o(){if(!e(O)&&(O=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,M=r(t[1]))}return O}function u(){return o()&&M}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(L=!0,F=r(t[1]))}return L}function R(){return T()&&F}function l(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(P=!0,g=r(t[1]))}return P}function f(){return e(w)||(w=/Windows/i.test(I.appVersion)),w}function A(){return l()&&g}function h(){return e(v)||(v="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),v}function N(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(x=n)}return D}function d(){return N()?x:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,m,O,M,y,p,C,U,L,F,P,g,w,v,x,D,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CylinderGeometryLibrary",["./Math"],function(t){"use strict";var e={};return e.computePositions=function(e,n,r,a,i){var o,u=.5*e,E=-u,s=a+a,c=i?2*s:s,_=new Float64Array(3*c),T=0,R=0,l=i?3*s:0,f=i?3*(s+a):3*a;for(o=0;o<a;o++){var A=o/a*t.TWO_PI,h=Math.cos(A),N=Math.sin(A),d=h*r,I=N*r,S=h*n,m=N*n;_[R+l]=d,_[R+l+1]=I,_[R+l+2]=E,_[R+f]=S,_[R+f+1]=m,_[R+f+2]=u,R+=3,i&&(_[T++]=d,_[T++]=I,_[T++]=E,_[T++]=S,_[T++]=m,_[T++]=u)}return _},e}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(t){switch(t){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(e){return t(e)&&(e===i.UNSIGNED_BYTE||e===i.UNSIGNED_SHORT||e===i.UNSIGNED_INT)},i.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},i.createTypedArrayFromArrayBuffer=function(t,e,n,a){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,a):new Uint16Array(e,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/CylinderGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CylinderGeometryLibrary","./defaultValue","./defined","./DeveloperError","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c,_,T,R,l){"use strict";function f(t){t=i(t,i.EMPTY_OBJECT);var e=t.length,n=t.topRadius,r=t.bottomRadius,a=i(t.vertexFormat,l.DEFAULT),o=i(t.slices,128);this._length=e,this._topRadius=n,this._bottomRadius=r,this._vertexFormat=l.clone(a),this._slices=o,this._workerName="createCylinderGeometry"}var A=new e,h=new n,N=new n,d=new n,I=new n;f.packedLength=l.packedLength+4,f.pack=function(t,e,n){return n=i(n,0),l.pack(t._vertexFormat,e,n),n+=l.packedLength,e[n++]=t._length,e[n++]=t._topRadius,e[n++]=t._bottomRadius,e[n]=t._slices,e};var S=new l,m={vertexFormat:S,length:void 0,topRadius:void 0,bottomRadius:void 0,slices:void 0};f.unpack=function(t,e,n){e=i(e,0);var r=l.unpack(t,e,S);e+=l.packedLength;var a=t[e++],u=t[e++],E=t[e++],s=t[e];return o(n)?(n._vertexFormat=l.clone(r,n._vertexFormat),n._length=a,n._topRadius=u,n._bottomRadius=E,n._slices=s,n):(m.length=a,m.topRadius=u,m.bottomRadius=E,m.slices=s,new f(m))},f.createGeometry=function(i){var o=i._length,u=i._topRadius,l=i._bottomRadius,f=i._vertexFormat,S=i._slices;if(!(o<=0||u<0||l<0||0===u&&0===l)){var m,O=S+S,M=S+O,y=O+O,p=a.computePositions(o,u,l,S,!0),C=f.st?new Float32Array(2*y):void 0,U=f.normal?new Float32Array(3*y):void 0,L=f.tangent?new Float32Array(3*y):void 0,F=f.bitangent?new Float32Array(3*y):void 0,P=f.normal||f.tangent||f.bitangent;if(P){var g=f.tangent||f.bitangent,w=0,v=0,x=0,D=h;D.z=0;var B=d,z=N;for(m=0;m<S;m++){var G=m/S*T.TWO_PI,b=Math.cos(G),X=Math.sin(G);P&&(D.x=b,D.y=X,g&&(B=n.normalize(n.cross(n.UNIT_Z,D,B),B)),f.normal&&(U[w++]=b,U[w++]=X,U[w++]=0,U[w++]=b,U[w++]=X,U[w++]=0),f.tangent&&(L[v++]=B.x,L[v++]=B.y,L[v++]=B.z,L[v++]=B.x,L[v++]=B.y,L[v++]=B.z),f.bitangent&&(z=n.normalize(n.cross(D,B,z),z),F[x++]=z.x,F[x++]=z.y,F[x++]=z.z,F[x++]=z.x,F[x++]=z.y,F[x++]=z.z))}for(m=0;m<S;m++)f.normal&&(U[w++]=0,U[w++]=0,U[w++]=-1),f.tangent&&(L[v++]=1,L[v++]=0,L[v++]=0),f.bitangent&&(F[x++]=0,F[x++]=-1,F[x++]=0);for(m=0;m<S;m++)f.normal&&(U[w++]=0,U[w++]=0,U[w++]=1),f.tangent&&(L[v++]=1,L[v++]=0,L[v++]=0),f.bitangent&&(F[x++]=0,F[x++]=1,F[x++]=0)}var V=12*S-12,q=_.createTypedArray(y,V),H=0,W=0;for(m=0;m<S-1;m++)q[H++]=W,q[H++]=W+2,q[H++]=W+3,q[H++]=W,q[H++]=W+3,q[H++]=W+1,W+=2;for(q[H++]=O-2,q[H++]=0,q[H++]=1,q[H++]=O-2,q[H++]=1,q[H++]=O-1,m=1;m<S-1;m++)q[H++]=O+m+1,q[H++]=O+m,q[H++]=O;for(m=1;m<S-1;m++)q[H++]=M,q[H++]=M+m,q[H++]=M+m+1;var Y=0;if(f.st){var k=Math.max(u,l);for(m=0;m<y;m++){var K=n.fromArray(p,3*m,I);C[Y++]=(K.x+k)/(2*k),C[Y++]=(K.y+k)/(2*k)}}var Z=new c;f.position&&(Z.position=new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:p})),f.normal&&(Z.normal=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:U})),f.tangent&&(Z.tangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:L})),f.bitangent&&(Z.bitangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:F})),f.st&&(Z.st=new s({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:C})),A.x=.5*o,A.y=Math.max(l,u);var j=new t(n.ZERO,e.magnitude(A));return new E({attributes:Z,indices:q,primitiveType:R.TRIANGLES,boundingSphere:j})}};var O;return f.getUnitCylinder=function(){return o(O)||(O=f.createGeometry(new f({topRadius:1,bottomRadius:1,length:1,vertexFormat:l.POSITION_ONLY}))),O},f}),define("Workers/createCylinderGeometry",["../Core/CylinderGeometry","../Core/defined"],function(t,e){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderOutlineGeometry.js index fae94a55..0e02f8cc 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createCylinderOutlineGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(e),T.y=s*Math.sin(e),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,f=i.z,A=c*c*R*R,h=_*_*l*l,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,x,g,B,D,v=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{v-=z,U=1/(1+v*M),L=1/(1+v*O),P=1/(1+v*m),F=U*U,w=L*L,x=P*P,g=F*U,B=w*L,D=x*P,p=A*F+h*w+N*x-1,C=A*g*M+h*B*O+N*D*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*L,s.z=T*P,s):new e(c*U,_*L,T*P)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),T=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:R,h=o(t,l,f,A,s);if(r(h)){var N=e.multiplyComponents(h,f,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var T=new e,R=new e;_.prototype.cartographicToCartesian=function(t,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,f=new e,A=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,f);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(f[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(f[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=f[i];if(Math.abs(e[E.getElementIndex(T,_)])>n){var R,A=e[E.getElementIndex(T,T)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(T,_)],d=(A-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(T,T)]=s,t[E.getElementIndex(T,_)]=c,t[E.getElementIndex(_,T)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,T=e.z*e.w,R=e.w*e.w,l=n-u-_+R,f=2*(i-T),A=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=f,t[4]=N,t[5]=S,t[6]=A,t[7]=d,t[8]=M,t):new E(l,f,A,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,f=-s*i+a*o*u,A=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=R,t[2]=A,t[3]=_,t[4]=l,t[5]=h,t[6]=T,t[7]=f,t[8]=N,t):new E(c,_,T,R,l,f,A,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],T)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),T=t.diagonal=E.clone(e,t.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],T=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(t,R,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,T,R,l,f,A){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,T=t.x*t.w,R=t.y*t.y,l=t.y*t.z,f=t.y*t.w,A=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-R-A+N,I=2*(s-h),S=2*(_+f),M=2*(s+h),O=-E+R-A+N,m=2*(l-T),y=2*(_-f),p=2*(l+T),C=-E-R+A+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,T=new e,R=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,T),T),e.normalize(e.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,f=_.y,A=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+f*S+A*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),T=s,R=c,l=_,f=a+s,A=o+c,h=t+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=f,i[13]=A,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var f=new e;c.getMaximumScale=function(t){return c.getScale(t,f),e.maximumComponent(f)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],T=e[9],R=e[10],l=e[11],f=e[12],A=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],L=t[10],P=t[11],F=t[12],w=t[13],x=t[14],g=t[15],B=r*d+u*I+_*S+f*M,D=i*d+E*I+T*S+A*M,v=a*d+s*I+R*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+f*p,b=i*O+E*m+T*y+A*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+f*P,H=i*C+E*U+T*L+A*P,W=a*C+s*U+R*L+h*P,Y=o*C+c*U+l*L+N*P,k=r*F+u*w+_*x+f*g,K=i*F+E*w+T*x+A*g,Z=a*F+s*w+R*x+h*g,j=o*F+c*w+l*x+N*g;return n[0]=B,n[1]=D,n[2]=v,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=e[12],R=e[13],l=e[14],f=t[0],A=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*f+o*A+s*h,U=i*f+u*A+c*h,L=a*f+E*A+_*h,P=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,x=r*S+o*M+s*O,g=i*S+u*M+c*O,B=a*S+E*M+_*O,D=r*m+o*y+s*p+T,v=i*m+u*y+c*p+R,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=x,n[9]=g,n[10]=B,n[11]=0,n[12]=D,n[13]=v,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=t[0],R=t[1],l=t[2],f=t[3],A=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*f+o*A+s*h,y=i*f+u*A+c*h,p=a*f+E*A+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var A=new e;c.multiplyByUniformScale=function(e,t,n){return A.x=t,A.y=t,A.z=t,c.multiplyByScale(e,A,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],T=e[5],R=e[9],l=e[13],f=e[2],A=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,L=A*p,P=M*m,F=A*y,w=S*m,x=f*p,g=M*O,B=f*y,D=S*O,v=f*m,z=A*O,G=C*T+P*R+F*l-(U*T+L*R+w*l),b=U*_+x*R+D*l-(C*_+g*R+B*l),X=L*_+g*T+v*l-(P*_+x*T+z*l),V=w*_+B*T+z*R-(F*_+D*T+v*R),q=U*i+L*a+w*o-(C*i+P*a+F*o),H=C*r+g*a+B*o-(U*r+x*a+D*o),W=P*r+x*i+z*o-(L*r+g*i+v*o),Y=F*r+D*i+v*a-(w*r+B*i+z*a);C=a*l,U=o*R,L=i*l,P=o*T,F=i*R,w=a*T,x=r*l,g=o*_,B=r*R,D=a*_,v=r*T,z=i*_;var k=C*m+P*y+F*p-(U*m+L*y+w*p),K=U*O+x*y+D*p-(C*O+g*y+B*p),Z=L*O+g*m+v*p-(P*O+x*m+z*p),j=w*O+B*m+z*y-(F*O+D*m+v*y),Q=L*S+w*M+U*A-(F*M+C*A+P*S),J=B*M+C*f+g*S-(x*S+D*M+U*f),$=x*A+z*M+P*f-(v*M+L*f+g*A),ee=v*S+F*f+D*A-(B*A+z*S+w*f),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=q*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],T=e[13],R=e[14],l=-n*_-r*T-i*R,f=-a*_-o*T-u*R,A=-E*_-s*T-c*R;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=f,t[14]=A,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=e.length;_<T;_++){var R=e[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,f=e.length;l<f;l++){var A=t.cartesianToCartographic(e[l]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),R=Math.max(R,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var T=Math.max(e.south,t.south),R=Math.min(e.north,t.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,T=e.south,R=e.east,l=e.west,f=s;f.height=i,f.longitude=l,f.latitude=_,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(e,f)&&(o[c]=t.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=l,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function T(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var R=new e,l=new e,f=new e,A=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e;T.fromPoints=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],d),o=e.clone(a,R),u=e.clone(a,l),E=e.clone(a,f),s=e.clone(a,A),c=e.clone(a,h),_=e.clone(a,N),y=t.length;for(r=1;r<y;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var L=e.magnitudeSquared(e.subtract(s,o,I)),P=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),w=o,x=s,g=L;P>g&&(g=P,w=u,x=c),F>g&&(g=F,w=E,x=_);var B=S;B.x=.5*(w.x+x.x),B.y=.5*(w.y+x.y),B.z=.5*(w.z+x.z);var D=e.magnitudeSquared(e.subtract(x,B,I)),v=Math.sqrt(D),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,I),.5,m),X=0;for(r=0;r<y;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,I));V>X&&(X=V);var q=e.magnitudeSquared(e.subtract(a,B,I));if(q>D){var H=Math.sqrt(q);v=.5*(v+H),D=v*v;var W=H-v;B.x=(v*B.x+W*a.x)/H,B.y=(v*B.y+W*a.y)/H,B.z=(v*B.z+W*a.z)/H}}return v<X?(e.clone(B,n.center),n.radius=v):(e.clone(b,n.center),n.radius=X),n};var y=new o,p=new e,C=new e,U=new t,L=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(t,U),U.height=a,_.northeast(t,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*R,f.z=E.z+.5*l,u};var P=[];T.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,P);return T.fromPoints(E,u)},T.fromVertices=function(t,n,a,o){if(i(o)||(o=new T),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=d;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,R),c=e.clone(u,l),_=e.clone(u,f),y=e.clone(u,A),p=e.clone(u,h),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=a){var L=t[E]+n.x,P=t[E+1]+n.y,F=t[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&e.clone(u,s),L>y.x&&e.clone(u,y),P<c.y&&e.clone(u,c),P>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(y,s,I)),x=e.magnitudeSquared(e.subtract(p,c,I)),g=e.magnitudeSquared(e.subtract(C,_,I)),B=s,D=y,v=w;x>v&&(v=x,B=c,D=p),g>v&&(v=g,B=_,D=C);var z=S;z.x=.5*(B.x+D.x),z.y=.5*(B.y+D.y),z.z=.5*(B.z+D.z);var G=e.magnitudeSquared(e.subtract(D,z,I)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var q=e.multiplyByScalar(e.add(X,V,I),.5,m),H=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,q,I));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new T),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=d;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,R),E=e.clone(a,l),s=e.clone(a,f),c=e.clone(a,A),_=e.clone(a,h),y=e.clone(a,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],L=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),L<s.z&&e.clone(a,s),L>y.z&&e.clone(a,y)}var P=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),w=e.magnitudeSquared(e.subtract(y,s,I)),x=u,g=c,B=P;F>B&&(B=F,x=E,g=_),w>B&&(B=w,x=s,g=y);var D=S;D.x=.5*(x.x+g.x),D.y=.5*(x.y+g.y),D.z=.5*(x.z+g.z);var v=e.magnitudeSquared(e.subtract(g,D,I)),z=Math.sqrt(v),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=e.multiplyByScalar(e.add(G,b,I),.5,m),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var q=e.magnitude(e.subtract(a,X,I));q>V&&(V=q);var H=e.magnitudeSquared(e.subtract(a,D,I));if(H>v){var W=Math.sqrt(H);z=.5*(z+W),v=z*z;var Y=W-z;D.x=(z*D.x+Y*a.x)/W,D.y=(z*D.y+Y*a.y)/W,D.z=(z*D.z+Y*a.z)/W}}return z<V?(e.clone(D,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){i(r)||(r=new T);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},T.fromEllipsoid=function(t,n){return i(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var F=new e;T.fromBoundingSpheres=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var w=new e,x=new e,g=new e;T.fromOrientedBoundingBox=function(t,n){i(n)||(n=new T);var r=t.halfAxes,a=s.getColumn(r,0,w),o=s.getColumn(r,1,x),u=s.getColumn(r,2,g);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},T.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new T);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var B=new e,D=new e;T.union=function(t,n,r){i(r)||(r=new T);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,B),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,D);return e.add(R,a,R),e.clone(R,r.center),r.radius=_,r};var v=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,v));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},T.transform=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;T.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,q=new e,H=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return T.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,H),R=e.negate(s,q),l=Y,f=l[0];e.add(E,c,f),e.add(f,s,f),f=l[1],e.add(E,c,f),e.add(f,R,f),f=l[2],e.add(E,_,f),e.add(f,R,f),f=l[3],e.add(E,_,f),e.add(f,s,f),e.negate(E,E),f=l[4],e.add(E,c,f),e.add(f,s,f),f=l[5],e.add(E,c,f),e.add(f,R,f),f=l[6],e.add(E,_,f),e.add(f,R,f),f=l[7],e.add(E,_,f),e.add(f,s,f);for(var A=l.length,h=0;h<A;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,W);n.project(d,N)}i=T.fromPoints(l,i),o=i.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,i},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){return o.normalize(e,s),o.normalize(t,c),a.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}), -define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!T())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0,p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function T(){if(!t(L)){L=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,P=r(e[1]))}return L}function R(){return T()&&P}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function f(){return t(x)||(x=/Windows/i.test(I.appVersion)),x}function A(){return l()&&w}function h(){return t(g)||(g="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),g}function N(){if(!t(D)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;D=t(n)&&""!==n,D&&(B=n)}return D}function d(){return N()?B:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,x,g,B,D,v={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:A,isWindows:f,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return v.supportsFullscreen=function(){return n.supportsFullscreen()},v.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},v.supportsWebWorkers=function(){return"undefined"!=typeof Worker},v}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/CylinderGeometryLibrary",["./Math"],function(e){"use strict";var t={};return t.computePositions=function(t,n,r,i,a){var o,u=.5*t,E=-u,s=i+i,c=a?2*s:s,_=new Float64Array(3*c),T=0,R=0,l=a?3*s:0,f=a?3*(s+i):3*i;for(o=0;o<i;o++){var A=o/i*e.TWO_PI,h=Math.cos(A),N=Math.sin(A),d=h*r,I=N*r,S=h*n,M=N*n;_[R+l]=d,_[R+l+1]=I,_[R+l+2]=E,_[R+f]=S,_[R+f+1]=M,_[R+f+2]=u,R+=3,a&&(_[T++]=d,_[T++]=I,_[T++]=E,_[T++]=S,_[T++]=M,_[T++]=u)}return _},t}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/CylinderOutlineGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./CylinderGeometryLibrary","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e){e=o(e,o.EMPTY_OBJECT);var t=e.length,n=e.topRadius,r=e.bottomRadius,i=o(e.slices,128),a=Math.max(o(e.numberOfVerticalLines,16),0);this._length=t,this._topRadius=n,this._bottomRadius=r,this._slices=i,this._numberOfVerticalLines=a,this._workerName="createCylinderOutlineGeometry"}var l=new t;R.packedLength=5,R.pack=function(e,t,n){return n=o(n,0),t[n++]=e._length,t[n++]=e._topRadius,t[n++]=e._bottomRadius,t[n++]=e._slices,t[n]=e._numberOfVerticalLines,t};var f={length:void 0,topRadius:void 0,bottomRadius:void 0,slices:void 0,numberOfVerticalLines:void 0};return R.unpack=function(e,t,n){t=o(t,0);var r=e[t++],i=e[t++],a=e[t++],E=e[t++],s=e[t];return u(n)?(n._length=r,n._topRadius=i,n._bottomRadius=a,n._slices=E,n._numberOfVerticalLines=s,n):(f.length=r,f.topRadius=i,f.bottomRadius=a,f.slices=E,f.numberOfVerticalLines=s,new R(f))},R.createGeometry=function(r){var o=r._length,u=r._topRadius,R=r._bottomRadius,f=r._slices,A=r._numberOfVerticalLines;if(!(o<=0||u<0||R<0||0===u&&0===R)){var h,N=2*f,d=a.computePositions(o,u,R,f,!1),I=2*f;if(A>0){var S=Math.min(A,f);h=Math.round(f/S),I+=S}var M,O=_.createTypedArray(N,2*I),m=0;for(M=0;M<f-1;M++)O[m++]=M,O[m++]=M+1,O[m++]=M+f,O[m++]=M+1+f;if(O[m++]=f-1,O[m++]=0,O[m++]=f+f-1,O[m++]=f,A>0)for(M=0;M<f;M+=h)O[m++]=M,O[m++]=M+f;var y=new c;y.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:d}),l.x=.5*o,l.y=Math.max(R,u);var p=new e(n.ZERO,t.magnitude(l));return new E({attributes:y,indices:O,primitiveType:T.LINES,boundingSphere:p})}},R}),define("Workers/createCylinderOutlineGeometry",["../Core/CylinderOutlineGeometry","../Core/defined"],function(e,t){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,E=e.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],E=t[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],E=t[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],E=t[a+1],s=t[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],E=t[a+1],s=t[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,f=i.z,A=c*c*R*R,h=_*_*l*l,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,g,x,v,B,D=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{D-=z,U=1/(1+D*M),L=1/(1+D*O),P=1/(1+D*m),F=U*U,w=L*L,g=P*P,x=F*U,v=w*L,B=g*P,p=A*F+h*w+N*g-1,C=A*x*M+h*v*O+N*B*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*P,s):new t(c*U,_*L,T*P)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(e,n,i){var l=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:R,h=o(e,l,f,A,s);if(r(h)){var N=t.multiplyComponents(h,f,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(t.dot(d,e))*t.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,E,s){"use strict";function c(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,f);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=t.subtract(n,a,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function E(t,e,r,i,a,o,u,E,s){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[E.getElementIndex(f[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=f[i];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(A-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,f=2*(i-T),A=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=I,e[3]=f,e[4]=N,e[5]=S,e[6]=A,e[7]=d,e[8]=M,e):new E(l,f,A,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,f=-s*i+a*o*u,A=-o,h=s*n,N=a*n;return r(e)?(e[0]=c,e[1]=R,e[2]=A,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=f,e[8]=N,e):new E(c,_,T,R,l,f,A,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,E=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++i>2&&(++a,i=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*i-r*_,e[2]=r*u-o*i,e[3]=s*u-a*_,e[4]=n*_-s*i,e[5]=a*i-n*u,e[6]=a*c-s*o,e[7]=s*r-n*c,e[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,E,s){"use strict";function c(t,e,n,i,a,o,u,E,s,c,_,T,R,l,f,A){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-R-A+N,I=2*(s-h),S=2*(_+f),M=2*(s+h),O=-E+R-A+N,m=2*(l-T),y=2*(_-f),p=2*(l+T),C=-E-R+A+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,f=_.y,A=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+f*S+A*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),E=1/(r-n),s=1/(a-i),c=-(e+t)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),E=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,f=a+s,A=o+c,h=e+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=f,i[13]=A,i[14]=h,i[15]=1,i},c.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},c.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],f=t[12],A=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],M=e[3],O=e[4],m=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],P=e[11],F=e[12],w=e[13],g=e[14],x=e[15],v=r*d+u*I+_*S+f*M,B=i*d+E*I+T*S+A*M,D=a*d+s*I+R*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+f*p,b=i*O+E*m+T*y+A*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+f*P,H=i*C+E*U+T*L+A*P,W=a*C+s*U+R*L+h*P,Y=o*C+c*U+l*L+N*P,k=r*F+u*w+_*g+f*x,K=i*F+E*w+T*g+A*x,Z=a*F+s*w+R*g+h*x,j=o*F+c*w+l*g+N*x;return n[0]=v,n[1]=B,n[2]=D,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],f=e[0],A=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],M=e[9],O=e[10],m=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=i*f+u*A+c*h,L=a*f+E*A+_*h,P=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,g=r*S+o*M+s*O,x=i*S+u*M+c*O,v=a*S+E*M+_*O,B=r*m+o*y+s*p+T,D=i*m+u*y+c*p+R,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=g,n[9]=x,n[10]=v,n[11]=0,n[12]=B,n[13]=D,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],f=e[3],A=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*f+o*A+s*h,y=i*f+u*A+c*h,p=a*f+E*A+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],E=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,E=t[1]*r+t[5]*i+t[9]*a+t[13]*o,s=t[2]*r+t[6]*i+t[10]*a+t[14]*o,c=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,E=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],E=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],f=t[2],A=t[6],S=t[10],M=t[14],O=t[3],m=t[7],y=t[11],p=t[15],C=S*p,U=M*y,L=A*p,P=M*m,F=A*y,w=S*m,g=f*p,x=M*O,v=f*y,B=S*O,D=f*m,z=A*O,G=C*T+P*R+F*l-(U*T+L*R+w*l),b=U*_+g*R+B*l-(C*_+x*R+v*l),X=L*_+x*T+D*l-(P*_+g*T+z*l),V=w*_+v*T+z*R-(F*_+B*T+D*R),q=U*i+L*a+w*o-(C*i+P*a+F*o),H=C*r+x*a+v*o-(U*r+g*a+B*o),W=P*r+g*i+z*o-(L*r+x*i+D*o),Y=F*r+B*i+D*a-(w*r+v*i+z*a);C=a*l,U=o*R,L=i*l,P=o*T,F=i*R,w=a*T,g=r*l,x=o*_,v=r*R,B=a*_,D=r*T,z=i*_;var k=C*m+P*y+F*p-(U*m+L*y+w*p),K=U*O+g*y+B*p-(C*O+x*y+v*p),Z=L*O+x*m+D*p-(P*O+g*m+z*p),j=w*O+v*m+z*y-(F*O+B*m+D*y),Q=L*S+w*M+U*A-(F*M+C*A+P*S),J=v*M+C*f+x*S-(g*S+B*M+U*f),$=g*A+z*M+P*f-(D*M+L*f+x*A),tt=D*S+F*f+B*A-(v*A+z*S+w*f),et=r*G+i*b+a*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-i*R,f=-a*_-o*T-u*R,A=-E*_-s*T-c*R;return e[0]=n,e[1]=a,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=i,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function E(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new E(t,e,i,a)},E.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new E(t,e,i,a)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=i,e.north=c,e):new E(n,s,i,c)},E.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,f=t.length;l<f;l++){var A=e.cartesianToCartographic(t[l]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),R=Math.max(R,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,s=e.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var i=t.east,a=t.west,o=e.east,s=e.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,f=s;f.height=i,f.longitude=l,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e,n){this.center=t.clone(i(e,t.ZERO)),this.radius=i(n,0)}var l=new t,f=new t,A=new t,h=new t,N=new t,d=new t,I=new t,S=new t,M=new t,O=new t,m=new t,y=new t,p=4/3*n.PI;R.fromPoints=function(e,n){if(a(n)||(n=new R),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],I),o=t.clone(i,l),u=t.clone(i,f),E=t.clone(i,A),s=t.clone(i,h),c=t.clone(i,N),_=t.clone(i,d),T=e.length;for(r=1;r<T;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var L=t.magnitudeSquared(t.subtract(s,o,S)),P=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),w=o,g=s,x=L;P>x&&(x=P,w=u,g=c),F>x&&(x=F,w=E,g=_);var v=M;v.x=.5*(w.x+g.x),v.y=.5*(w.y+g.y),v.z=.5*(w.z+g.z);var B=t.magnitudeSquared(t.subtract(g,v,S)),D=Math.sqrt(B),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=m;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,S));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(i,v,S));if(q>B){var H=Math.sqrt(q);D=.5*(D+H),B=D*D;var W=H-D;v.x=(D*v.x+W*i.x)/H,v.y=(D*v.y+W*i.y)/H,v.z=(D*v.z+W*i.z)/H}}return D<X?(t.clone(v,n.center),n.radius=D):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,L=new t,P=new e,F=new e;R.fromRectangle2D=function(t,e,n){return R.fromRectangleWithHeights2D(t,e,0,0,n)},R.fromRectangleWithHeights2D=function(e,n,r,o,u){if(a(u)||(u=new R),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=i(n,C),T.southwest(e,P),P.height=r,T.northeast(e,F),F.height=o;var E=n.project(P,U),s=n.project(F,L),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*_,f.z=E.z+.5*l,u};var w=[];R.fromRectangle3D=function(e,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new R),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,w);return R.fromPoints(E,u)},R.fromVertices=function(e,n,r,o){if(a(o)||(o=new R),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=i(n,t.ZERO),r=i(r,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,l),c=t.clone(u,f),_=t.clone(u,A),T=t.clone(u,h),p=t.clone(u,N),C=t.clone(u,d),U=e.length;for(E=0;E<U;E+=r){var L=e[E]+n.x,P=e[E+1]+n.y,F=e[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&t.clone(u,s),L>T.x&&t.clone(u,T),P<c.y&&t.clone(u,c),P>p.y&&t.clone(u,p),F<_.z&&t.clone(u,_),F>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(T,s,S)),g=t.magnitudeSquared(t.subtract(p,c,S)),x=t.magnitudeSquared(t.subtract(C,_,S)),v=s,B=T,D=w;g>D&&(D=g,v=c,B=p),x>D&&(D=x,v=_,B=C);var z=M;z.x=.5*(v.x+B.x),z.y=.5*(v.y+B.y),z.z=.5*(v.z+B.z);var G=t.magnitudeSquared(t.subtract(B,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=T.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,S));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},R.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new R),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=I;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,l),E=t.clone(i,f),s=t.clone(i,A),c=t.clone(i,h),_=t.clone(i,N),T=t.clone(i,d),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),L<s.z&&t.clone(i,s),L>T.z&&t.clone(i,T)}var P=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),w=t.magnitudeSquared(t.subtract(T,s,S)),g=u,x=c,v=P;F>v&&(v=F,g=E,x=_),w>v&&(v=w,g=s,x=T);var B=M;B.x=.5*(g.x+x.x),B.y=.5*(g.y+x.y),B.z=.5*(g.z+x.z);var D=t.magnitudeSquared(t.subtract(x,B,S)),z=Math.sqrt(D),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,X,S));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(i,B,S));if(H>D){var W=Math.sqrt(H);z=.5*(z+W),D=z*z;var Y=W-z;B.x=(z*B.x+Y*i.x)/W,B.y=(z*B.y+Y*i.y)/W,B.z=(z*B.z+Y*i.z)/W}}return z<V?(t.clone(B,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(e,n,r){a(r)||(r=new R);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},R.fromEllipsoid=function(e,n){return a(n)||(n=new R),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var g=new t;R.fromBoundingSpheres=function(e,n){if(a(n)||(n=new R),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return R.clone(e[0],n);if(2===r)return R.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,g)+s.radius)}return n.radius=E,n};var x=new t,v=new t,B=new t;R.fromOrientedBoundingBox=function(e,n){a(n)||(n=new R);var r=e.halfAxes,i=c.getColumn(r,0,x),o=c.getColumn(r,1,v),u=c.getColumn(r,2,B);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},R.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new R(e.center,e.radius)},R.packedLength=4,R.pack=function(t,e,n){n=i(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},R.unpack=function(t,e,n){e=i(e,0),a(n)||(n=new R);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var D=new t,z=new t;R.union=function(e,n,r){a(r)||(r=new R);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,D),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,i,T),t.clone(T,r.center),r.radius=_,r};var G=new t;R.expand=function(e,n,r){r=R.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},R.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},R.transform=function(t,e,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;R.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},R.transformWithoutScale=function(t,e,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;R.computePlaneDistances=function(e,n,r,i){a(i)||(i=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var V=new t,q=new t,H=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return R.projectTo2D=function(e,n,r){n=i(n,j);var a=n.ellipsoid,o=e.center,u=e.radius,E=a.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,q);t.normalize(s,s);var c=t.cross(E,s,H);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),l=K,f=l[0];t.add(E,c,f),t.add(f,s,f),f=l[1],t.add(E,c,f),t.add(f,T,f),f=l[2],t.add(E,_,f),t.add(f,T,f),f=l[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=l[4],t.add(E,c,f),t.add(f,s,f),f=l[5],t.add(E,c,f),t.add(f,T,f),f=l[6],t.add(E,_,f),t.add(f,T,f),f=l[7],t.add(E,_,f),t.add(f,s,f);for(var A=l.length,h=0;h<A;++h){var N=l[h];t.add(o,N,N);var d=a.cartesianToCartographic(N,k);n.project(d,N)}r=R.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},R.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},R.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},R.prototype.intersectPlane=function(t){return R.intersectPlane(this,t)},R.prototype.distanceSquaredTo=function(t){return R.distanceSquaredTo(this,t)},R.prototype.computePlaneDistances=function(t,e,n){return R.computePlaneDistances(this,t,e,n)},R.prototype.isOccluded=function(t){return R.isOccluded(this,t)},R.prototype.equals=function(t){return R.equals(this,t)},R.prototype.clone=function(t){return R.clone(this,t)},R.prototype.volume=function(){var t=this.radius;return p*t*t*t},R}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var i=0;i<r;++i)o.pack(t[i],e,2*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),a.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)), +o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,M=r(t[1]))}return S}function a(){return i()&&M}function o(){if(!e(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,m=r(t[1]))}return O}function u(){return o()&&m}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(L=!0,P=r(t[1]))}return L}function R(){return T()&&P}function l(){if(!e(F)){F=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(F=!0,w=r(t[1]))}return F}function f(){return e(g)||(g=/Windows/i.test(I.appVersion)),g}function A(){return l()&&w}function h(){return e(x)||(x="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),x}function N(){if(!e(B)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;B=e(n)&&""!==n,B&&(v=n)}return B}function d(){return N()?v:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,g,x,v,B,D={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/CylinderGeometryLibrary",["./Math"],function(t){"use strict";var e={};return e.computePositions=function(e,n,r,i,a){var o,u=.5*e,E=-u,s=i+i,c=a?2*s:s,_=new Float64Array(3*c),T=0,R=0,l=a?3*s:0,f=a?3*(s+i):3*i;for(o=0;o<i;o++){var A=o/i*t.TWO_PI,h=Math.cos(A),N=Math.sin(A),d=h*r,I=N*r,S=h*n,M=N*n;_[R+l]=d,_[R+l+1]=I,_[R+l+2]=E,_[R+f]=S,_[R+f+1]=M,_[R+f+2]=u,R+=3,a&&(_[T++]=d,_[T++]=I,_[T++]=E,_[T++]=S,_[T++]=M,_[T++]=u)}return _},e}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(t){switch(t){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(e){return t(e)&&(e===a.UNSIGNED_BYTE||e===a.UNSIGNED_SHORT||e===a.UNSIGNED_INT)},a.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},a.createTypedArrayFromArrayBuffer=function(t,e,n,i){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,i):new Uint16Array(e,n,i)},n(a)}),define("Core/CylinderOutlineGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./CylinderGeometryLibrary","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./PrimitiveType"],function(t,e,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(t){t=o(t,o.EMPTY_OBJECT);var e=t.length,n=t.topRadius,r=t.bottomRadius,i=o(t.slices,128),a=Math.max(o(t.numberOfVerticalLines,16),0);this._length=e,this._topRadius=n,this._bottomRadius=r,this._slices=i,this._numberOfVerticalLines=a,this._workerName="createCylinderOutlineGeometry"}var l=new e;R.packedLength=5,R.pack=function(t,e,n){return n=o(n,0),e[n++]=t._length,e[n++]=t._topRadius,e[n++]=t._bottomRadius,e[n++]=t._slices,e[n]=t._numberOfVerticalLines,e};var f={length:void 0,topRadius:void 0,bottomRadius:void 0,slices:void 0,numberOfVerticalLines:void 0};return R.unpack=function(t,e,n){e=o(e,0);var r=t[e++],i=t[e++],a=t[e++],E=t[e++],s=t[e];return u(n)?(n._length=r,n._topRadius=i,n._bottomRadius=a,n._slices=E,n._numberOfVerticalLines=s,n):(f.length=r,f.topRadius=i,f.bottomRadius=a,f.slices=E,f.numberOfVerticalLines=s,new R(f))},R.createGeometry=function(r){var o=r._length,u=r._topRadius,R=r._bottomRadius,f=r._slices,A=r._numberOfVerticalLines;if(!(o<=0||u<0||R<0||0===u&&0===R)){var h,N=2*f,d=a.computePositions(o,u,R,f,!1),I=2*f;if(A>0){var S=Math.min(A,f);h=Math.round(f/S),I+=S}var M,O=_.createTypedArray(N,2*I),m=0;for(M=0;M<f-1;M++)O[m++]=M,O[m++]=M+1,O[m++]=M+f,O[m++]=M+1+f;if(O[m++]=f-1,O[m++]=0,O[m++]=f+f-1,O[m++]=f,A>0)for(M=0;M<f;M+=h)O[m++]=M,O[m++]=M+f;var y=new c;y.position=new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:d}),l.x=.5*o,l.y=Math.max(R,u);var p=new t(n.ZERO,e.magnitude(l));return new E({attributes:y,indices:O,primitiveType:T.LINES,boundingSphere:p})}},R}),define("Workers/createCylinderOutlineGeometry",["../Core/CylinderOutlineGeometry","../Core/defined"],function(t,e){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseGeometry.js index aad05475..4f9a61e5 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseGeometry.js @@ -222,9 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,i){if(a.typeOf.number(e,n),a.typeOf.number(r,i),n!==i)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var i=Math.abs(e-r);return i<=a||i<=n*Math.max(Math.abs(e),Math.abs(r))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var r=i[t-1],n=t;n<=e;n++)i.push(r*n);return i[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(i),n},o.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)},o.cross=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-n*s,f=n*u-a*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,r,n,a)};var d=new o,h=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,a,i,u){a=t(a,0);var s=r(i)?i.radiiSquared:E,c=Math.cos(n);d.x=c*Math.cos(e),d.y=c*Math.sin(e),d.z=Math.sin(n),d=o.normalize(d,d),o.multiplyComponents(s,d,h);var l=Math.sqrt(o.dot(d,h));return h=o.divideByScalar(h,l,h),d=o.multiplyByScalar(d,a,d),r(u)||(u=new o),o.add(h,d,u)},o.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,c){var l=r.x,f=r.y,d=r.z,h=a.x,E=a.y,m=a.z,p=l*l*h*h,y=f*f*E*E,_=d*d*m*m,T=p+y+_,R=Math.sqrt(1/T),v=e.multiplyByScalar(r,R,i);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,N=u.z,I=o;I.x=v.x*A*2,I.y=v.y*S*2,I.z=v.z*N*2;var O,g,w,M,x,C,P,D,L,U,b,F=(1-R)*e.magnitude(r)/(.5*e.magnitude(I)),B=0;do{F-=B,w=1/(1+F*A),M=1/(1+F*S),x=1/(1+F*N),C=w*w,P=M*M,D=x*x,L=C*w,U=P*M,b=D*x,O=p*C+y*P+_*D-1,g=p*L*A+y*U*S+_*b*N;B=O/(-2*g)}while(Math.abs(O)>n.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=d*x,c):new e(l*w,f*M,d*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,i){return a=r(a,0),n(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),d=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,r,a){var E=n(r)?r.oneOverRadii:f,m=n(r)?r.oneOverRadiiSquared:d,p=n(r)?r._centerToleranceSquared:h,y=o(t,E,m,p,c);if(n(y)){var _=e.multiplyComponents(y,m,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),R=Math.atan2(_.y,_.x),v=Math.asin(_.z),A=i.sign(e.dot(T,t))*e.magnitude(T);return n(a)?(a.longitude=R,a.latitude=v,a.height=A,a):new u(R,v,A)}},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t,r,a,i){r=n(r,0),a=n(a,0),i=n(i,0),t._radii=new e(r,a,i),t._radiiSquared=new e(r*r,a*a,i*i),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(r,a,i),t._maximumRadius=Math.max(r,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},f.unpack=function(t,r,a){r=n(r,0);var i=e.unpack(t,r);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(i);return a(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var d=new e,h=new e;f.prototype.cartographicToCartesian=function(t,r){var n=d,i=h;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,i);var o=Math.sqrt(e.dot(n,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(i,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(r,n){var i=this.scaleToGeodeticSurface(r,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(r,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,i){r=n(r,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-r))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,i,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a,i,o,u,s,c){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(i,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(m[r],E[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>n&&(a=i,n=o)}var c=1,l=0,f=E[a],d=m[a];if(Math.abs(e[s.getElementIndex(d,f)])>r){var h,p=e[s.getElementIndex(d,d)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(d,f)],T=(p-y)/2/_;h=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(d,d)]=c,t[s.getElementIndex(d,f)]=l,t[s.getElementIndex(f,d)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,d=e.z*e.w,h=e.w*e.w,E=r-u-f+h,m=2*(a-d),p=2*(i+l),y=2*(a+d),_=-r+u-f+h,T=2*(c-o),R=2*(i-l),v=2*(c+o),A=-r-u+f+h;return n(t)?(t[0]=E,t[1]=y,t[2]=R,t[3]=m,t[4]=_,t[5]=v,t[6]=p,t[7]=T,t[8]=A,t):new s(E,m,p,y,_,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*a,f=-i*u+c*o*a,d=c*u+i*o*a,h=r*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,y=c*r,_=i*r;return n(t)?(t[0]=l,t[1]=h,t[2]=p,t[3]=f,t[4]=E,t[5]=y,t[6]=d,t[7]=m,t[8]=_,t):new s(l,f,d,h,E,m,p,y,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],i=e[n+1],o=e[n+2];return r.x=a,r.y=i,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],i=e[t+6];return r.x=n,r.y=a,r.z=i,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var d=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],d)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],d)),r};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=i,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[3]*a+e[6]*i,u=e[1]*n+e[4]*a+e[7]*i,s=e[2]*n+e[5]*a+e[8]*i;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,i=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),d=t.diagonal=s.clone(e,t.diagonal),h=r*c(d);i<10&&l(d)>h;)f(d,p),s.transpose(p,y),s.multiply(d,p,d),s.multiply(y,d,d),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*n-r*c)+u*(r*o-i*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],d=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-n*f,t[2]=n*u-o*a,t[3]=c*u-i*f,t[4]=r*f-c*a,t[5]=i*a-r*u,t[6]=i*l-c*o,t[7]=c*n-r*l,t[8]=r*o-i*n;var h=1/d;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}o.fromElements=function(e,t,n,a,i){return r(i)?(i.x=e,i.y=t,i.z=n,i.w=a,i):new o(e,t,n,a)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)&&i.equalsEpsilon(e.w,t.w,n,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t,r,a,i,o,u,s,c,l,f,d,h,E,m,p){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(c,0),this[3]=n(h,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(E,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(m,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(d,0),this[15]=n(p,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,i){return r=n(r,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=r.x,i[13]=r.y,i[14]=r.z,i[15]=1,i):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var i=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,d=t.x*t.w,h=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-h-p+_,R=2*(c-y),v=2*(f+m),A=2*(c+y),S=-s+h-p+_,N=2*(E-d),I=2*(f-m),O=2*(E+d),g=-s-h+p+_;return n[0]=T*i,n[1]=A*i,n[2]=I*i,n[3]=0,n[4]=R*o,n[5]=S*o,n[6]=O*o,n[7]=0,n[8]=v*u,n[9]=N*u,n[10]=g*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,d=new e,h=new e;l.fromCamera=function(t,r){var n=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,d),d),e.normalize(e.cross(d,f,h),h);var u=d.x,s=d.y,c=d.z,E=f.x,m=f.y,p=f.z,y=h.x,_=h.y,T=h.z,R=n.x,v=n.y,A=n.z,S=u*-R+s*-v+c*-A,N=y*-R+_*-v+T*-A,I=E*R+m*v+p*A;return a(r)?(r[0]=u,r[1]=y,r[2]=-E,r[3]=0,r[4]=s,r[5]=_,r[6]=-m,r[7]=0,r[8]=c,r[9]=T,r[10]=-p,r[11]=0,r[12]=S,r[13]=N,r[14]=I,r[15]=1,r):new l(u,s,c,S,y,_,T,N,-E,-m,-p,I,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,i,o){var u=1/(t-e),s=1/(n-r),c=1/(i-a),l=-(t+e)*u,f=-(n+r)*s,d=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=d,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,a,i,o){var u=2*a/(t-e),s=2*a/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(i+a)/(i-a),d=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=d,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,i){var o=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var i=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),d=c,h=l,E=f,m=i+c,p=o+l,y=t+f;return a[0]=d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=y,a[15]=1,a},l.computeView=function(t,r,n,a,i){return i[0]=a.x,i[1]=n.x,i[2]=-r.x,i[3]=0,i[4]=a.y,i[5]=n.y,i[6]=-r.y,i[7]=0,i[8]=a.z,i[9]=n.z,i[10]=-r.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(n,t),i[14]=e.dot(r,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],i=e[n+1],o=e[n+2],u=e[n+3];return r.x=a,r.y=i,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return r.x=n,r.y=a,r.z=i,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var E=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),r};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],d=e[9],h=e[10],E=e[11],m=e[12],p=e[13],y=e[14],_=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],N=t[5],I=t[6],O=t[7],g=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],D=t[14],L=t[15],U=n*T+u*R+f*v+m*A,b=a*T+s*R+d*v+p*A,F=i*T+c*R+h*v+y*A,B=o*T+l*R+E*v+_*A,z=n*S+u*N+f*I+m*O,G=a*S+s*N+d*I+p*O,q=i*S+c*N+h*I+y*O,V=o*S+l*N+E*I+_*O,X=n*g+u*w+f*M+m*x,W=a*g+s*w+d*M+p*x,H=i*g+c*w+h*M+y*x,Y=o*g+l*w+E*M+_*x,k=n*C+u*P+f*D+m*L,j=a*C+s*P+d*D+p*L,Z=i*C+c*P+h*D+y*L,K=o*C+l*P+E*D+_*L;return r[0]=U,r[1]=b,r[2]=F,r[3]=B,r[4]=z,r[5]=G,r[6]=q,r[7]=V,r[8]=X,r[9]=W,r[10]=H,r[11]=Y,r[12]=k,r[13]=j,r[14]=Z,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=e[12],h=e[13],E=e[14],m=t[0],p=t[1],y=t[2],_=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],N=t[12],I=t[13],O=t[14],g=n*m+o*p+c*y,w=a*m+u*p+l*y,M=i*m+s*p+f*y,x=n*_+o*T+c*R,C=a*_+u*T+l*R,P=i*_+s*T+f*R,D=n*v+o*A+c*S,L=a*v+u*A+l*S,U=i*v+s*A+f*S,b=n*N+o*I+c*O+d,F=a*N+u*I+l*O+h,B=i*N+s*I+f*O+E;return r[0]=g,r[1]=w,r[2]=M,r[3]=0,r[4]=x,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=L,r[10]=U,r[11]=0,r[12]=b,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=t[0],h=t[1],E=t[2],m=t[3],p=t[4],y=t[5],_=t[6],T=t[7],R=t[8],v=n*d+o*h+c*E,A=a*d+u*h+l*E,S=i*d+s*h+f*E,N=n*m+o*p+c*y,I=a*m+u*p+l*y,O=i*m+s*p+f*y,g=n*_+o*T+c*R,w=a*_+u*T+l*R,M=i*_+s*T+f*R;return r[0]=v,r[1]=A,r[2]=S,r[3]=0,r[4]=N,r[5]=I,r[6]=O,r[7]=0,r[8]=g,r[9]=w,r[10]=M,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=n*e[0]+a*e[4]+i*e[8]+e[12],u=n*e[1]+a*e[5]+i*e[9]+e[13],s=n*e[2]+a*e[6]+i*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var p=new e;l.multiplyByUniformScale=function(e,t,r){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,i=t.z;return 1===n&&1===a&&1===i?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=i*e[8],r[9]=i*e[9],r[10]=i*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*n+e[4]*a+e[8]*i+e[12]*o,s=e[1]*n+e[5]*a+e[9]*i+e[13]*o,c=e[2]*n+e[6]*a+e[10]*i+e[14]*o,l=e[3]*n+e[7]*a+e[11]*i+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i,u=e[1]*n+e[5]*a+e[9]*i,s=e[2]*n+e[6]*a+e[10]*i;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i+e[12],u=e[1]*n+e[5]*a+e[9]*i+e[13],s=e[2]*n+e[6]*a+e[10]*i+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],i=e[8],o=e[12],f=e[1],d=e[5],h=e[9],E=e[13],m=e[2],p=e[6],v=e[10],A=e[14],S=e[3],N=e[7],I=e[11],O=e[15],g=v*O,w=A*I,M=p*O,x=A*N,C=p*I,P=v*N,D=m*O,L=A*S,U=m*I,b=v*S,F=m*N,B=p*S,z=g*d+x*h+C*E-(w*d+M*h+P*E),G=w*f+D*h+b*E-(g*f+L*h+U*E),q=M*f+L*d+F*E-(x*f+D*d+B*E),V=P*f+U*d+B*h-(C*f+b*d+F*h),X=w*a+M*i+P*o-(g*a+x*i+C*o),W=g*n+L*i+U*o-(w*n+D*i+b*o),H=x*n+D*a+B*o-(M*n+L*a+F*o),Y=C*n+b*a+F*i-(P*n+U*a+B*i);g=i*E,w=o*h,M=a*E,x=o*d,C=a*h,P=i*d,D=n*E,L=o*f,U=n*h,b=i*f,F=n*d,B=a*f;var k=g*N+x*I+C*O-(w*N+M*I+P*O),j=w*S+D*I+b*O-(g*S+L*I+U*O),Z=M*S+L*N+F*O-(x*S+D*N+B*O),K=P*S+U*N+B*I-(C*S+b*N+F*I),J=M*v+P*A+w*p-(C*A+g*p+x*v),Q=U*A+g*m+L*v-(D*v+b*A+w*m),$=D*p+B*A+x*m-(F*A+M*m+L*p),ee=F*v+C*m+b*p-(U*p+B*v+P*m),te=n*z+a*G+i*q+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=G*te,r[2]=q*te,r[3]=V*te,r[4]=X*te,r[5]=W*te,r[6]=H*te,r[7]=Y*te,r[8]=k*te,r[9]=j*te,r[10]=Z*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],d=e[13],h=e[14],E=-r*f-n*d-a*h,m=-i*f-o*d-u*h,p=-s*f-c*d-l*h;return t[0]=r,t[1]=i,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),i=u.toRadians(r(i,0)),n(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(a,0),o.north=r(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,d=e.length;f<d;f++){var h=e[f];r=Math.min(r,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var E=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-r>o-i&&(r=i,a=o,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=a,t.north=l,t):new s(r,c,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,d=Number.MAX_VALUE,h=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),d=Math.min(d,p.latitude),h=Math.max(h,p.latitude);var y=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(a)?(a.west=o,a.south=d,a.east=c,a.north=h,a):new s(o,d,c,h)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var d=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(d>=h))return n(r)?(r.west=l,r.south=d,r.east=f,r.north=h,r):new s(l,d,f,h)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return n(r)?(r.west=a,r.south=i,r.east=o,r.north=u,r):new s(a,i,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<i||u.equalsEpsilon(r,i,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=r(t,i.WGS84),a=r(a,0),n(o)||(o=[]);var l=0,f=e.north,d=e.south,h=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:d>0?d:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,i,o,u,s,c,l,f){"use strict";function d(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var h=new e,E=new e,m=new e,p=new e,y=new e,_=new e,T=new e,R=new e,v=new e,A=new e,S=new e,N=new e;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],T),o=e.clone(i,h),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,y),f=e.clone(i,_),I=t.length;for(n=1;n<I;n++){e.clone(t[n],i);var O=i.x,g=i.y,w=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),g<u.y&&e.clone(i,u),g>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,L=M;x>L&&(L=x,P=u,D=l),C>L&&(L=C,P=s,D=f);var U=v;U.x=.5*(P.x+D.x),U.y=.5*(P.y+D.y),U.z=.5*(P.z+D.z);var b=e.magnitudeSquared(e.subtract(D,U,R)),F=Math.sqrt(b),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var G=e.multiplyByScalar(e.add(B,z,R),.5,N),q=0;for(n=0;n<I;n++){e.clone(t[n],i);var V=e.magnitude(e.subtract(i,G,R));V>q&&(q=V);var X=e.magnitudeSquared(e.subtract(i,U,R));if(X>b){var W=Math.sqrt(X);F=.5*(F+W),b=F*F;var H=W-F;U.x=(F*U.x+H*i.x)/W,U.y=(F*U.y+H*i.y)/W,U.z=(F*U.z+H*i.z)/W}}return F<q?(e.clone(U,r.center),r.radius=F):(e.clone(G,r.center),r.radius=q),r};var I=new o,O=new e,g=new e,w=new t,M=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,i,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=n(r,I),f.southwest(t,w),w.height=i,f.northeast(t,M),M.height=o;var s=r.project(w,O),c=r.project(M,g),l=c.x-s.x,h=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*h,m.z=s.z+.5*E,u};var x=[];d.fromRectangle3D=function(t,r,o,u){if(r=n(r,i.WGS84),o=n(o,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,r,o,x);return d.fromPoints(s,u)},d.fromVertices=function(t,r,i,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=n(r,e.ZERO),i=n(i,3);var u=T;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,h),l=e.clone(u,E),f=e.clone(u,m),I=e.clone(u,p),O=e.clone(u,y),g=e.clone(u,_),w=t.length;for(s=0;s<w;s+=i){var M=t[s]+r.x,x=t[s+1]+r.y,C=t[s+2]+r.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>I.x&&e.clone(u,I),x<l.y&&e.clone(u,l),x>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>g.z&&e.clone(u,g)}var P=e.magnitudeSquared(e.subtract(I,c,R)),D=e.magnitudeSquared(e.subtract(O,l,R)),L=e.magnitudeSquared(e.subtract(g,f,R)),U=c,b=I,F=P;D>F&&(F=D,U=l,b=O),L>F&&(F=L,U=f,b=g);var B=v;B.x=.5*(U.x+b.x),B.y=.5*(U.y+b.y),B.z=.5*(U.z+b.z);var z=e.magnitudeSquared(e.subtract(b,B,R)),G=Math.sqrt(z),q=A;q.x=c.x,q.y=l.y,q.z=f.z;var V=S;V.x=I.x,V.y=O.y,V.z=g.z;var X=e.multiplyByScalar(e.add(q,V,R),.5,N),W=0;for(s=0;s<w;s+=i){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,X,R));H>W&&(W=H);var Y=e.magnitudeSquared(e.subtract(u,B,R));if(Y>z){var k=Math.sqrt(Y);G=.5*(G+k),z=G*G;var j=k-G;B.x=(G*B.x+j*u.x)/k,B.y=(G*B.y+j*u.y)/k,B.z=(G*B.z+j*u.z)/k}}return G<W?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=W),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=T;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,h),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,p),f=e.clone(i,y),I=e.clone(i,_),O=t.length;for(o=0;o<O;o+=3){var g=t[o]+r[o],w=t[o+1]+r[o+1],M=t[o+2]+r[o+2];i.x=g,i.y=w,i.z=M,g<u.x&&e.clone(i,u),g>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>I.z&&e.clone(i,I)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(I,c,R)),D=u,L=l,U=x;C>U&&(U=C,D=s,L=f),P>U&&(U=P,D=c,L=I);var b=v;b.x=.5*(D.x+L.x),b.y=.5*(D.y+L.y),b.z=.5*(D.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,R)),B=Math.sqrt(F),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var G=S;G.x=l.x,G.y=f.y,G.z=I.z;var q=e.multiplyByScalar(e.add(z,G,R),.5,N),V=0;for(o=0;o<O;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(i,q,R));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(i,b,R));if(W>F){var H=Math.sqrt(W);B=.5*(B+H),F=B*B;var Y=H-B;b.x=(B*b.x+Y*i.x)/H,b.y=(B*b.y+Y*i.y)/H,b.z=(B*b.z+Y*i.z)/H}}return B<V?(e.clone(b,n.center),n.radius=B):(e.clone(q,n.center),n.radius=V),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var C=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return r.radius=s,r};var P=new e,D=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=c.getColumn(n,0,P),o=c.getColumn(n,1,D),u=c.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=n(r,0);var a=e.center;return t[r++]=a.x,t[r++]=a.y,t[r++]=a.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=n(t,0),a(r)||(r=new d);var i=r.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],r.radius=e[t],r};var U=new e,b=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,U),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var F=new e;d.expand=function(t,r,n){n=d.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,F));return a>n.radius&&(n.radius=a),n},d.intersectPlane=function(t,r){var n=t.center,a=t.radius,i=r.normal,o=e.dot(i,n)+r.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=l.getMaximumScale(t)*e.radius,r};var B=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,B);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var z=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new s);var o=e.subtract(t.center,r,z),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var G=new e,q=new e,V=new e,X=new e,W=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var j=new o;return d.projectTo2D=function(t,r,a){r=n(r,j);var i=r.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,G),c=e.cross(e.UNIT_Z,s,q);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,W),h=e.negate(c,X),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,y=0;y<p;++y){var _=E[y];e.add(o,_,_);var T=i.cartesianToCartographic(_,H);r.project(T,_)}a=d.fromPoints(E,a),o=a.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,a},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var a=0;a<n;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var a=0;a<n;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}), -define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(v)&&(v=!1,!d())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=n(e[1]))}return v}function i(){return a()&&A}function o(){if(!t(S)&&(S=!1,!a()&&!d()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=n(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(I)){I=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(I=!0,O=n(e[1]),O.isNightly=!!e[2])}return I}function c(){return s()&&O}function l(){if(!t(g)){g=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(g=!0,w=n(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(g=!0,w=n(e[1]))}return g}function f(){return l()&&w}function d(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(M=!0,x=n(e[1]))}return M}function h(){return d()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(R.appVersion)),D}function p(){return E()&&P}function y(){return t(L)||(L="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),L}function _(){if(!t(b)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;b=t(r)&&""!==r,b&&(U=r)}return b}function T(){return _()?U:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,N,I,O,g,w,M,x,C,P,D,L,U,b,F={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:d,edgeVersion:h,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,i){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,a);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case o.SHORT:return new Int16Array(r,n,a);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case o.INT:return new Int32Array(r,n,a);case o.UNSIGNED_INT:return new Uint32Array(r,n,a);case o.FLOAT:return new Float32Array(r,n,a);case o.DOUBLE:return new Float64Array(r,n,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(a,0)}var c=new e;s.fromAxisAngle=function(t,r,a){var i=r/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,d=Math.cos(i);return n(a)?(a.x=u,a.y=l,a.z=f,a.w=d,a):new s(u,l,f,d)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,a,i,o,c,d=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=d+h+E;if(m>0)r=Math.sqrt(m+1),c=.5*r,r=.5/r,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var p=l,y=0;h>d&&(y=1),E>d&&E>h&&(y=2);var _=p[y],T=p[_];r=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var R=f;R[y]=.5*r,r=.5/r,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*r,R[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*r,R[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*r,a=-R[0],i=-R[1],o=-R[2]}return n(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var d=new s,h=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,r){return m=s.fromAxisAngle(e.UNIT_X,t.roll,d),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(E,m,E),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,d),s.multiply(h,r,r)};var p=new e,y=new e,_=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,R),s.conjugate(R,R);for(var a=0,i=r-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),_),s.multiply(_,R,_),_.w<0&&s.negate(_,_),s.computeAxis(_,p);var u=s.computeAngle(_);n[o]=p.x*u,n[o+1]=p.y*u,n[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,r,a,i,o){n(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(r,4*i,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,a=e.y*r,i=e.z*r,o=e.w*r;return t.x=n,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+a*c-i*s,d=o*s-n*c+a*l+i*u,h=o*c+n*s-a*u+i*l,E=o*l-n*u-a*s-i*c;return r.x=f,r.y=d,r.z=h,r.w=E,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,r,n){return v=s.multiplyByScalar(t,r,v),n=s.multiplyByScalar(e,1-r,n),s.add(v,n,n)};var A=new s,S=new s,N=new s;s.slerp=function(e,t,r,n){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=A=s.negate(t,A)),1-a<o.EPSILON6)return s.lerp(e,i,r,n);var u=Math.acos(a);return S=s.multiplyByScalar(e,Math.sin((1-r)*u),S),N=s.multiplyByScalar(i,Math.sin(r*u),N),n=s.add(S,N,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),a=0;return 0!==n&&(a=n/Math.sin(n)),e.multiplyByScalar(t,a,r)},s.exp=function(t,r){var n=e.magnitude(t),a=0;return 0!==n&&(a=Math.sin(n)/n),r.x=t.x*a,r.y=t.y*a,r.z=t.z*a,r.w=Math.cos(n),r};var I=new e,O=new e,g=new s,w=new s;s.computeInnerQuadrangle=function(t,r,n,a){var i=s.conjugate(r,g);s.multiply(i,n,w);var o=s.log(w,I);s.multiply(i,t,w);var u=s.log(w,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,g),s.multiply(r,g,a)},s.squad=function(e,t,r,n,a,i){var o=s.slerp(e,t,a,g),u=s.slerp(r,n,a,w);return s.slerp(o,u,2*a*(1-a),i)};for(var M=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=a.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var b=U+1,F=2*b+1;C[U]=1/(b*F),P[U]=b/F}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,r,n){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,L[f]=(C[f]*l-P[f])*o;var d=a*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),h=u*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),E=s.multiplyByScalar(e,h,M);return s.multiplyByScalar(t,d,n),s.add(E,n,n)},s.fastSquad=function(e,t,r,n,a,i){var o=s.fastSlerp(e,t,a,g),u=s.fastSlerp(r,n,a,w);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,r,n){"use strict";function a(t,a,i,l,f,d,h,E,m,p){var y=t+a;e.multiplyByScalar(l,Math.cos(y),o),e.multiplyByScalar(i,Math.sin(y),u),e.add(o,u,o);var _=Math.cos(t);_*=_;var T=Math.sin(t);T*=T;var R=d/Math.sqrt(h*_+f*T),v=R/E;return n.fromAxisAngle(o,v,s),r.fromQuaternion(s,c),r.multiplyByVector(c,m,p),e.normalize(p,p),e.multiplyByScalar(p,E,p),p}var i={},o=new e,u=new e,s=new n,c=new r,l=new e,f=new e,d=new e,h=new e;i.raisePositionsToHeight=function(t,r,n){for(var a=r.ellipsoid,i=r.height,o=r.extrudedHeight,u=n?t.length/3*2:t.length/3,s=new Float64Array(3*u),c=t.length,E=n?c:0,m=0;m<c;m+=3){var p=m+1,y=m+2,_=e.fromArray(t,m,l);a.scaleToGeodeticSurface(_,_);var T=e.clone(_,f),R=a.geodeticSurfaceNormal(_,h),v=e.multiplyByScalar(R,i,d);e.add(_,v,_),n&&(e.multiplyByScalar(R,o,v),e.add(T,v,T),s[m+E]=T.x,s[p+E]=T.y,s[y+E]=T.z),s[m]=_.x,s[p]=_.y,s[y]=_.z}return s};var E=new e,m=new e,p=new e;return i.computeEllipsePositions=function(r,n,i){var o=r.semiMinorAxis,u=r.semiMajorAxis,s=r.rotation,c=r.center,h=8*r.granularity,y=o*o,_=u*u,T=u*o,R=e.magnitude(c),v=e.normalize(c,E),A=e.cross(e.UNIT_Z,c,m);A=e.normalize(A,A);var S=e.cross(v,A,p),N=1+Math.ceil(t.PI_OVER_TWO/h),I=t.PI_OVER_TWO/(N-1),O=t.PI_OVER_TWO-N*I;O<0&&(N-=Math.ceil(Math.abs(O)/I));var g,w,M,x,C,P=N*(N+2)*2,D=n?new Array(3*P):void 0,L=0,U=l,b=f,F=4*N*3,B=F-1,z=0,G=i?new Array(F):void 0;for(O=t.PI_OVER_TWO,U=a(O,s,S,A,y,T,_,R,v,U),n&&(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z),i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x),O=t.PI_OVER_TWO-I,g=1;g<N+1;++g){if(U=a(O,s,S,A,y,T,_,R,v,U),b=a(Math.PI-O,s,S,A,y,T,_,R,v,b),n){for(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z,M=2*g+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(U,b,x,d),D[L++]=C.x,D[L++]=C.y,D[L++]=C.z;D[L++]=b.x,D[L++]=b.y,D[L++]=b.z}i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x,G[z++]=b.x,G[z++]=b.y,G[z++]=b.z),O=t.PI_OVER_TWO-(g+1)*I}for(g=N;g>1;--g){if(O=t.PI_OVER_TWO-(g-1)*I,U=a(-O,s,S,A,y,T,_,R,v,U),b=a(O+Math.PI,s,S,A,y,T,_,R,v,b),n){for(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z,M=2*(g-1)+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(U,b,x,d),D[L++]=C.x,D[L++]=C.y,D[L++]=C.z;D[L++]=b.x,D[L++]=b.y,D[L++]=b.z}i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x,G[z++]=b.x,G[z++]=b.y,G[z++]=b.z)}O=t.PI_OVER_TWO,U=a(-O,s,S,A,y,T,_,R,v,U);var q={};return n&&(D[L++]=U.x,D[L++]=U.y,D[L++]=U.z,q.positions=D,q.numPts=N),i&&(G[B--]=U.z,G[B--]=U.y,G[B--]=U.x,q.outerPositions=G),q},i}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return a}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,r,n,a){"use strict";var i={};i.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,r){return i.octDecodeInRange(e,t,255,r)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),a=256*(r-n);return i.octDecode(n,a,t)},i.octPack=function(e,t,r,n){ -var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(r,o);return n.x=65536*s.x+a,n.y=65536*s.y+u,n},i.octUnpack=function(e,t,r,n){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,r),i.octDecode(o,s,n)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},i}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function a(r,a,s,c,l){n(l)||(l=new t);var f,d,h,E,m,p,y,_;n(a.z)?(f=t.subtract(s,a,i),d=t.subtract(c,a,o),h=t.subtract(r,a,u),E=t.dot(f,f),m=t.dot(f,d),p=t.dot(f,h),y=t.dot(d,d),_=t.dot(d,h)):(f=e.subtract(s,a,i),d=e.subtract(c,a,o),h=e.subtract(r,a,u),E=e.dot(f,f),m=e.dot(f,d),p=e.dot(f,h),y=e.dot(d,d),_=e.dot(d,h));var T=1/(E*y-m*m);return l.y=(y*p-m*_)*T,l.z=(E*_-m*p)*T,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var a={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var i=t.high,o=t.low;return n.encode(e.x,a),i.x=a.high,o.x=a.low,n.encode(e.y,a),i.y=a.high,o.y=a.low,n.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,i);var a=i.high,o=i.low;t[r]=a.x,t[r+1]=a.y,t[r+2]=a.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var i;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-n/e,i<0?[i,0]:[0,i];var c=n*n,l=4*e*a,f=r(c,-l,t.EPSILON14);if(f<0)return[];var d=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[d/e,a/d]:[a/d,d/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,i,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,d=u*u,h=s*s,E=o*s-d,m=o*c-u*s,p=u*c-h,y=4*E*p-m*m;if(y<0){var _,T,R;d*f>=l*h?(_=o,T=E,R=-2*u*E+o*m):(_=c,T=p,R=-c*m+2*s*p);var v=R<0?-1:1,A=-v*Math.abs(_)*Math.sqrt(-y);i=-R+A;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),I=i===A?-N:-T/N;return a=T<=0?N+I:-R/(N*N+I*I+T),d*f>=l*h?[(a-u)/o]:[-c/(a+s)]}var O=E,g=-2*u*E+o*m,w=p,M=-c*m+2*s*p,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-g)/3);a=2*Math.sqrt(-O);var D=Math.cos(P);i=a*D;var L=a*(-D/2-C*Math.sin(P)),U=i+L>2*u?i-u:L-u,b=o,F=U/b;P=Math.abs(Math.atan2(c*x,-M)/3),a=2*Math.sqrt(-w),D=Math.cos(P),i=a*D,L=a*(-D/2-C*Math.sin(P));var B=-c,z=i+L<2*s?i+s:L+s,G=B/z,q=b*z,V=-U*z-b*B,X=U*B,W=(s*V-u*X)/(-u*V+s*q);return F<=W?F<=G?W<=G?[F,W,G]:[F,G,W]:[G,F,W]:F<=G?[W,F,G]:W<=G?[W,G,F]:[G,W,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,i=t*t,o=r*r;return 18*e*t*r*n+i*o-27*a*(n*n)-4*(e*o*r+i*t*n)},n.computeRealRoots=function(e,n,a,i){var o,u;if(0===e)return t.computeRealRoots(n,a,i);if(0===n){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,a,i)}return 0===a?0===i?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,i):0===i?(o=t.computeRealRoots(e,n,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,a,i)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var d=-t/4,h=f[f.length-1];if(Math.abs(h)<r.EPSILON14){var E=n.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],y=E[1];if(p>=0&&y>=0){var _=Math.sqrt(p),T=Math.sqrt(y);return[d-T,d-_,d+_,d+T]}if(p>=0&&y<0)return m=Math.sqrt(p),[d-m,d+m];if(p<0&&y>=0)return m=Math.sqrt(y),[d-m,d+m]}return[]}if(h>0){var R=Math.sqrt(h),v=(s+h-c/R)/2,A=(s+h+c/R)/2,S=n.computeRealRoots(1,R,v),N=n.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=d,S[1]+=d,0!==N.length?(N[0]+=d,N[1]+=d,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=d,N[1]+=d,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,d=c*o-i*a*t+u,h=e.computeRealRoots(1,l,f,d);if(h.length>0){var E,m,p=h[0],y=a-p,_=y*y,T=t/2,R=y/2,v=_-4*o,A=_+4*Math.abs(o),S=c-4*p,N=c+4*Math.abs(p);if(p<0||v*N<S*A){var I=Math.sqrt(S);E=I/2,m=0===I?0:(t*R-i)/I}else{var O=Math.sqrt(v);E=0===O?0:(t*R-i)/O,m=O/2}var g,w;0===T&&0===E?(g=0,w=0):r.sign(T)===r.sign(E)?(g=T+E,w=p/g):(w=T-E,g=p/w);var M,x;0===R&&0===m?(M=0,x=0):r.sign(R)===r.sign(m)?(M=R+m,x=o/M):(x=R-m,M=o/x);var C=n.computeRealRoots(1,g,M),P=n.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,d=f*n,h=a*a;return u*c*f-4*s*d-4*e*l*f+18*e*t*r*d-27*i*f*f+256*o*(h*a)+a*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*i*r*f)+h*(144*e*u*r-27*u*u-128*i*c-192*i*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,d=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=f<0?h+1:h,h+=d<0?h+1:h){case 0:return a(c,l,f,d);case 1:case 2:return i(c,l,f,d);case 3:case 4:return a(c,l,f,d);case 5:return i(c,l,f,d);case 6:case 7:return a(c,l,f,d);case 8:return i(c,l,f,d);case 9:case 10:return a(c,l,f,d);case 11:return i(c,l,f,d);case 12:case 13:case 14:case 15:return a(c,l,f,d);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,i,o,u,s,c,l){"use strict";function f(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function d(t,r,a){n(a)||(a=new i);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),d=e.dot(u,u),h=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(d,h,E,A);if(n(m))return a.start=m.root0,a.stop=m.root1,a}function h(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function E(t,r,n,a,i){var l,f=a*a,d=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*d,m=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*d+a*r.x+n,y=d*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-v)),T.push(new e(a,i*R,i*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(a,i*A,i*-S)),T.push(new e(a,i*A,i*S))}return T}var N=_*_,I=y*y,O=E*E,g=_*y,w=O+I,M=2*(m*E+g),x=2*p*E+m*m-I+N,C=2*(p*m-g),P=p*p-N;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var D=l.length;if(0===D)return T;for(var L=0;L<D;++L){var U,b=l[L],F=b*b,B=Math.max(1-F,0),z=Math.sqrt(B);U=o.sign(E)===o.sign(p)?h(E*F+p,m*b,o.EPSILON12):o.sign(p)===o.sign(m*b)?h(E*F,m*b+p,o.EPSILON12):h(E*F+m*b,p,o.EPSILON12);var G=h(y*b,_,o.EPSILON15),q=U*G;q<0?T.push(new e(a,i*b,i*z)):q>0?T.push(new e(a,i*b,i*-z)):0!==z?(T.push(new e(a,i*b,i*-z)),T.push(new e(a,i*b,i*z)),++L):T.push(new e(a,i*b,i*z))}return T}var m={};m.rayPlane=function(t,r,a){n(a)||(a=new e);var i=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,y=new e,_=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,n,a,i,u){u=r(u,!1);var s,c,l,f,d,h=t.origin,E=t.direction,m=e.subtract(a,n,p),v=e.subtract(i,n,y),A=e.cross(E,v,_),S=e.dot(m,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,n,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>S)return;d=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,n,T),(l=e.dot(s,A)*N)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*N)<0||l+f>1)return;d=e.dot(v,c)*N}return d},m.rayTriangle=function(t,r,a,i,o,u){var s=m.rayTriangleParametric(t,r,a,i,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;m.lineSegmentTriangle=function(t,r,a,i,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=d(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;m.lineSegmentSphere=function(t,r,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=d(o,a,i),!(!n(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,I=new e;m.rayEllipsoid=function(t,r){var n,a,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),f=e.multiplyComponents(c,t.direction,I),d=e.magnitudeSquared(l),h=e.dot(l,f);if(d>1){if(h>=0)return;var E=h*h;if(n=d-1,a=e.magnitudeSquared(f),o=a*n,E<o)return;if(E>o){u=h*h-o,s=-h+Math.sqrt(u);var m=s/a,p=n/s;return m<p?new i(m,p):{start:p,stop:m}}var y=Math.sqrt(n/a);return new i(y,y)}return d<1?(n=d-1,a=e.magnitudeSquared(f),o=a*n,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(f),new i(0,-h/a)):void 0};var O=new e,g=new e,w=new e,M=new e,x=new e,C=new u,P=new u,D=new u,L=new u,U=new u,b=new u,F=new u,B=new e,z=new e,G=new t;m.grazingAltitudeLocation=function(t,r){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),d=e.mostOrthogonalAxis(l,M),h=e.normalize(e.cross(d,f,g),g),m=e.normalize(e.cross(f,h,w),w),p=C;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=h.x,p[4]=h.y,p[5]=h.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var y=u.transpose(p,P),_=u.fromScale(r.radii,D),T=u.fromScale(r.oneOverRadii,L),R=U;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var v,A,S=u.multiply(u.multiply(y,T,b),R,b),N=u.multiply(u.multiply(S,_,F),p,F),I=u.multiplyByVector(S,a,x),q=E(N,e.negate(I,O),0,0,1),V=q.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(_,u.multiplyByVector(p,q[H],B),B);var Y=e.normalize(e.subtract(v,a,M),M),k=e.dot(Y,i);k>W&&(W=k,X=e.clone(v,X))}var j=r.cartesianToCartographic(X,G);return W=o.clamp(W,0,1),A=e.magnitude(e.subtract(X,a,M))*Math.sqrt(1-W*W),A=c?-A:A,j.height=A,r.cartographicToCartesian(j,new e)}};var q=new e;return m.lineSegmentPlane=function(t,r,a,i){n(i)||(i=new e);var u=e.subtract(r,t,q),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,r,n,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,r)+o<0,c=e.dot(i,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,d;if(1!==l&&2!==l||(f=new e,d=new e),1===l){if(u)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(t,n,a,d),{positions:[t,r,n,f,d],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(r,t,a,d),{positions:[t,r,n,f,d],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(n,r,a,d),{positions:[t,r,n,f,d],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(n,t,a,d),{positions:[t,r,n,f,d],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(t,r,a,d),{positions:[t,r,n,f,d],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(r,n,a,d),{positions:[t,r,n,f,d],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,i,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var i=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=i,a):new u(n,i)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),i=t.w;return r(n)?(e.clone(a,n.normal),n.distance=i,n):new u(a,i)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(r,c,c),u.fromPointNormal(c,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,a=r.maximumIndex,i=e(r.cacheSize,24),o=n.length;if(!t(a)){a=0;for(var u=0,s=n[u];u<o;)s>a&&(a=s),++u,s=n[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var f=i+1,d=0;d<o;++d)f-c[n[d]]>i&&(c[n[d]]=f,++f);return(f-i+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<n;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}r=e(r,e.EMPTY_OBJECT);var a,i=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=i.length,c=0,l=0,f=i[l],d=s;if(t(o))c=o+1;else{for(;l<d;)f>c&&(c=f),++l,f=i[l];if(-1===c)return 0;++c}var h,E=[];for(h=0;h<c;h++)E[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<d;)E[i[l]].vertexTriangles.push(m),++E[i[l]].numLiveTriangles,E[i[l+1]].vertexTriangles.push(m),++E[i[l+1]].numLiveTriangles,E[i[l+2]].vertexTriangles.push(m),++E[i[l+2]].numLiveTriangles,++m,l+=3;var p=0,y=u+1;a=1;var _,T,R=[],v=[],A=0,S=[],N=s/3,I=[];for(h=0;h<N;h++)I[h]=!1;for(var O,g;-1!==p;){R=[],T=E[p],g=T.vertexTriangles.length;for(var w=0;w<g;++w)if(m=T.vertexTriangles[w],!I[m]){I[m]=!0,l=m+m+m;for(var M=0;M<3;++M)O=i[l],R.push(O),v.push(O),S[A]=O,++A,_=E[O],--_.numLiveTriangles,y-_.timeStamp>u&&(_.timeStamp=y,++y),++l}p=function(e,t,r,a,i,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var d=r[f];a[d].numLiveTriangles&&(s=0,i-a[d].timeStamp+2*a[d].numLiveTriangles<=t&&(s=i-a[d].timeStamp),(s>l||-1===l)&&(l=s,c=d)),++f}return-1===c?n(a,o,e,u):c}(i,u,R,E,y,v,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,a,i,o,u,s,c,l,f,d,h,E,m,p,y,_,T,R,v,A,S,N){"use strict";function I(e,t,r,n,a){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=a,e[t++]=a,e[t]=r}function O(e){for(var t=e.length,r=t/3*6,n=p.createTypedArray(t,r),a=0,i=0;i<t;i+=3,a+=6)I(n,a,e[i],e[i+1],e[i+2]);return n}function g(e){var t=e.length;if(t>=3){var r=6*(t-2),n=p.createTypedArray(t,r);I(n,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)I(n,a,e[i-1],e[i],e[i-2]);return n}return new Uint16Array}function w(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=p.createTypedArray(t,r),a=e[0],i=0,o=1;o<t;++o,i+=6)I(n,i,a,e[o],e[o+1]);return n}return new Uint16Array}function M(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new E({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function x(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var a=t[n],i=0;i<a.componentsPerAttribute;++i)e[n].values.push(a.values[r*a.componentsPerAttribute+i])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),v.multiplyByPoint(e,ie,ie),a.pack(ie,r,i)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,r,i)}function D(e,t){var r,n=e.length,a={},i=e[0][t].attributes;for(r in i)if(i.hasOwnProperty(r)&&c(i[r])&&c(i[r].values)){for(var o=i[r],s=o.values.length,l=!0,f=1;f<n;++f){var d=e[f][t].attributes[r];if(!c(d)||o.componentDatatype!==d.componentDatatype||o.componentsPerAttribute!==d.componentsPerAttribute||o.normalize!==d.normalize){l=!1;break}s+=d.values.length}l&&(a[r]=new E({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function L(e,t){var n,i,o,u,s,l,f,d=e.length,E=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,y=D(e,t);for(n in y)if(y.hasOwnProperty(n))for(s=y[n].values,u=0,i=0;i<d;++i)for(l=e[i][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(E){var T=0;for(i=0;i<d;++i)T+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:y,primitiveType:S.POINTS})),v=p.createTypedArray(R,T),A=0,N=0;for(i=0;i<d;++i){var I=e[i][t].indices,O=I.length;for(u=0;u<O;++u)v[A++]=N+I[u];N+=h.computeNumberOfVertices(e[i][t])}_=v}var g,w=new a,M=0;for(i=0;i<d;++i){if(g=e[i][t].boundingSphere,!c(g)){w=void 0;break}a.add(g.center,w,w)}if(c(w))for(a.divideByScalar(w,d,w),i=0;i<d;++i){g=e[i][t].boundingSphere;var x=a.magnitude(a.subtract(g.center,w,se))+g.radius;x>M&&(M=x)}return new h({attributes:y,indices:_,primitiveType:m,boundingSphere:c(w)?new r(w,M):void 0})}function U(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function b(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,a=3;a<t;++a)r[n++]=a-1,r[n++]=0,r[n++]=a;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function F(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,a=3;a<t-1;a+=2)r[n++]=a,r[n++]=a-1,r[n++]=a+1,a+2<t&&(r[n++]=a,r[n++]=a+1,r[n++]=a+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return e.indices=r,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function q(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return b(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return U(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<T.EPSILON6&&(e.y=t?-T.EPSILON6:T.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return V(e,e.y<0),V(t,t.y<0),void V(r,r.y<0);var n,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(r.y);n=a>i?a>o?T.sign(e.y):T.sign(r.y):i>o?T.sign(t.y):T.sign(r.y);var u=n<0;V(e,u),V(t,u),V(r,u)}function W(e,t,r,n){a.add(e,a.multiplyByScalar(a.subtract(t,e,ve),e.y/(e.y-t.y),ve),r),a.clone(r,n),V(r,!0),V(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,a=t.y<0,i=r.y<0,o=0;o+=n?1:0,o+=a?1:0,o+=i?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(W(e,t,Ae,Ne),W(e,r,Se,Ie),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(W(t,r,Ae,Ne),W(t,e,Se,Ie),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(W(r,e,Ae,Ne),W(r,t,Se,Ie),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?a?i||(W(r,e,Ae,Ne),W(r,t,Se,Ie),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(W(t,r,Ae,Ne),W(t,e,Se,Ie),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(W(e,t,Ae,Ne),W(e,r,Se,Ie),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=Ne,s[6]=Ie,s.length=7),Oe}}function Y(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var a in n)if(n.hasOwnProperty(a)&&c(n[a])&&c(n[a].values)){var i=n[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=p.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function k(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var a=t[n];r[n]=new E({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:r,indices:[],primitiveType:e.primitiveType})}function j(e,t,r){var n=c(e.geometry.boundingSphere);t=Y(t,n),r=Y(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Z(e,r,i,o,u,s,l,f,d,h,E,m){if(c(s)||c(l)||c(f)||c(d)||c(h)){var p=a.fromArray(u,3*e,ge),y=a.fromArray(u,3*r,we),_=a.fromArray(u,3*i,Me),T=t(o,p,y,_,xe);if(c(s)){var R=a.fromArray(s,3*e,ge),v=a.fromArray(s,3*r,we),A=a.fromArray(s,3*i,Me);a.multiplyByScalar(R,T.x,R),a.multiplyByScalar(v,T.y,v),a.multiplyByScalar(A,T.z,A);var S=a.add(R,v,R);a.add(S,A,S),a.normalize(S,S),a.pack(S,E.normal.values,3*m)}if(c(h)){var N=a.fromArray(h,3*e,ge),I=a.fromArray(h,3*r,we),O=a.fromArray(h,3*i,Me);a.multiplyByScalar(N,T.x,N),a.multiplyByScalar(I,T.y,I),a.multiplyByScalar(O,T.z,O);var g;a.equals(N,a.ZERO)&&a.equals(I,a.ZERO)&&a.equals(O,a.ZERO)?(g=ge,g.x=0,g.y=0,g.z=0):(g=a.add(N,I,N),a.add(g,O,g),a.normalize(g,g)),a.pack(g,E.extrudeDirection.values,3*m)}if(c(l)){var w=a.fromArray(l,3*e,ge),M=a.fromArray(l,3*r,we),x=a.fromArray(l,3*i,Me);a.multiplyByScalar(w,T.x,w),a.multiplyByScalar(M,T.y,M),a.multiplyByScalar(x,T.z,x);var C=a.add(w,M,w);a.add(C,x,C),a.normalize(C,C),a.pack(C,E.tangent.values,3*m)}if(c(f)){var P=a.fromArray(f,3*e,ge),D=a.fromArray(f,3*r,we),L=a.fromArray(f,3*i,Me);a.multiplyByScalar(P,T.x,P),a.multiplyByScalar(D,T.y,D),a.multiplyByScalar(L,T.z,L);var U=a.add(P,D,P);a.add(U,L,U),a.normalize(U,U),a.pack(U,E.bitangent.values,3*m)}if(c(d)){var b=n.fromArray(d,2*e,Ce),F=n.fromArray(d,2*r,Pe),B=n.fromArray(d,2*i,De);n.multiplyByScalar(b,T.x,b),n.multiplyByScalar(F,T.y,F),n.multiplyByScalar(B,T.z,B);var z=n.add(b,F,b);n.add(z,B,z),n.pack(z,E.st.values,2*m)}}}function K(e,t,r,n,a,i){var o=e.position.values.length/3;if(-1!==a){var u=n[a],s=r[u];return-1===s?(r[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function J(e){var t,r,n,i,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,d=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,E=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,p=u.indices,y=k(u),_=k(u),T=[];T.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<T.length;++o)T[o]=-1,R[o]=-1;var v=p.length;for(o=0;o<v;o+=3){var A=p[o],S=p[o+1],N=p[o+2],I=a.fromArray(l,3*A),O=a.fromArray(l,3*S),g=a.fromArray(l,3*N),w=H(I,O,g);if(c(w)&&w.positions.length>3)for(var M=w.positions,x=w.indices,C=x.length,P=0;P<C;++P){var D=x[P],L=M[D];L.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=R),i=K(t,r,n,p,D<3?o+D:-1,L),Z(A,S,N,L,l,f,h,d,E,m,t,i)}else c(w)&&(I=w.positions[0],O=w.positions[1],g=w.positions[2]),I.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=R),i=K(t,r,n,p,o,I),Z(A,S,N,I,l,f,h,d,E,m,t,i),i=K(t,r,n,p,o+1,O),Z(A,S,N,O,l,f,h,d,E,m,t,i),i=K(t,r,n,p,o+2,g),Z(A,S,N,g,l,f,h,d,E,m,t,i)}j(e,_,y)}function Q(e){var t,r=e.geometry,n=r.attributes,i=n.position.values,o=r.indices,u=k(r),s=k(r),l=o.length,f=[];f.length=i.length/3;var d=[];for(d.length=i.length/3,t=0;t<f.length;++t)f[t]=-1,d[t]=-1;for(t=0;t<l;t+=2){var h=o[t],E=o[t+1],m=a.fromArray(i,3*h,ge),p=a.fromArray(i,3*E,we);Math.abs(m.y)<T.EPSILON6&&(m.y<0?m.y=-T.EPSILON6:m.y=T.EPSILON6),Math.abs(p.y)<T.EPSILON6&&(p.y<0?p.y=-T.EPSILON6:p.y=T.EPSILON6);var y=u.attributes,R=u.indices,v=d,A=s.attributes,S=s.indices,N=f,I=_.lineSegmentPlane(m,p,Le,Me);if(c(I)){var O=a.multiplyByScalar(a.UNIT_Y,5*T.EPSILON9,Ue);m.y<0&&(a.negate(O,O),y=s.attributes,R=s.indices,v=f,A=u.attributes,S=u.indices,N=d);var g=a.add(I,O,be);K(y,R,v,o,t,m),K(y,R,v,o,-1,g),a.negate(O,O),a.add(I,O,g),K(A,S,N,o,-1,g),K(A,S,N,o,t+1,p)}else{var w,M,x;m.y<0?(w=s.attributes,M=s.indices,x=f):(w=u.attributes,M=u.indices,x=d),K(w,M,x,o,t,m),K(w,M,x,o,t+1,p)}}j(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,i=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=a.unpack(r,u,ze);if(!(s.x>0)){var c=a.unpack(n,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):a.pack(s,n,u));var l=a.unpack(i,u,qe);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=r[u+3],i[u+1]=r[u+4],i[u+2]=r[u+5]):a.pack(s,i,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,d=s.nextPosition.values,h=s.expandAndWidth.values,E=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,p=k(u),y=k(u),R=!1,v=l.length/3;for(t=0;t<v;t+=4){var A=t,S=t+2,N=a.fromArray(l,3*A,ze),I=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<ke)for(N.y=ke*(I.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(I.y)<ke)for(I.y=ke*(N.y<0?-1:1),l[3*(t+2)+1]=I.y,l[3*(t+3)+1]=I.y,r=3*A;r<3*A+12;r+=3)d[r]=l[3*(t+2)],d[r+1]=l[3*(t+2)+1],d[r+2]=l[3*(t+2)+2];var O=p.attributes,g=p.indices,w=y.attributes,M=y.indices,x=_.lineSegmentPlane(N,I,Le,Ve);if(c(x)){R=!0;var C=a.multiplyByScalar(a.UNIT_Y,Ye,Xe);N.y<0&&(a.negate(C,C),O=y.attributes,g=y.indices,w=p.attributes,M=p.indices);var P=a.add(x,C,We);O.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),O.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),O.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),a.negate(C,C),a.add(x,C,P),w.position.values.push(P.x,P.y,P.z),w.position.values.push(P.x,P.y,P.z),w.position.values.push(I.x,I.y,I.z,I.x,I.y,I.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.nextPosition.values.push(I.x,I.y,I.z,I.x,I.y,I.z),w.nextPosition.values.push(d[3*S],d[3*S+1],d[3*S+2]),w.nextPosition.values.push(d[3*S+3],d[3*S+4],d[3*S+5]);var D=n.fromArray(h,2*A,Fe),L=Math.abs(D.y);O.expandAndWidth.values.push(-1,L,1,L),O.expandAndWidth.values.push(-1,-L,1,-L),w.expandAndWidth.values.push(-1,L,1,L),w.expandAndWidth.values.push(-1,-L,1,-L);var U=a.magnitudeSquared(a.subtract(x,N,qe));if(U/=a.magnitudeSquared(a.subtract(I,N,qe)),c(m)){var b=i.fromArray(m,4*A,He),F=i.fromArray(m,4*S,He),B=T.lerp(b.x,F.x,U),z=T.lerp(b.y,F.y,U),G=T.lerp(b.z,F.z,U),q=T.lerp(b.w,F.w,U);for(r=4*A;r<4*A+8;++r)O.color.values.push(m[r]);for(O.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),w.color.values.push(B,z,G,q),w.color.values.push(B,z,G,q),r=4*S;r<4*S+8;++r)w.color.values.push(m[r])}if(c(E)){var V=n.fromArray(E,2*A,Fe),X=n.fromArray(E,2*(t+3),Be),W=T.lerp(V.x,X.x,U);for(r=2*A;r<2*A+4;++r)O.st.values.push(E[r]);for(O.st.values.push(W,V.y),O.st.values.push(W,X.y),w.st.values.push(W,V.y),w.st.values.push(W,X.y),r=2*S;r<2*S+4;++r)w.st.values.push(E[r])}o=O.position.values.length/3-4,g.push(o,o+2,o+1),g.push(o+1,o+2,o+3),o=w.position.values.length/3-4,M.push(o,o+2,o+1),M.push(o+1,o+2,o+3)}else{var H,Y;for(N.y<0?(H=y.attributes,Y=y.indices):(H=p.attributes,Y=p.indices),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(I.x,I.y,I.z),H.position.values.push(I.x,I.y,I.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(d[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(h[r]),c(E)&&H.st.values.push(E[r]);if(c(m))for(r=4*t;r<4*t+16;++r)H.color.values.push(m[r]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}R&&($(y),$(p)),j(e,y,p)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=O(t);break;case S.TRIANGLE_STRIP:e.indices=g(t);break;case S.TRIANGLE_FAN:e.indices=w(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),f=0,d=0;d<o;d+=3)l[f++]=a[d],l[f++]=a[d+1],l[f++]=a[d+2],l[f++]=a[d]+i[d]*n,l[f++]=a[d+1]+i[d+1]*n,l[f++]=a[d+2]+i[d+2]*n;var m,p=e.boundingSphere;return c(p)&&(m=new r(p.center,p.radius+n)),new h({attributes:{position:new E({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){ -var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,a={},i=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(a[u]=i++)}for(var s in n)n.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),a=0;a<t;a++)n[a]=-1;for(var i,o=r,s=o.length,l=p.createTypedArray(t,s),f=0,d=0,E=0;f<s;)i=n[o[f]],-1!==i?l[d]=i:(i=o[f],n[i]=E,l[d]=E,++E),++f,++d;e.indices=l;var m=e.attributes;for(var y in m)if(m.hasOwnProperty(y)&&c(m[y])&&c(m[y].values)){for(var _=m[y],T=_.values,R=0,v=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,E*v);R<t;){var S=n[R];if(-1!==S)for(var N=0;N<v;N++)A[v*S+N]=T[v*R+N];++R}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,a=0,i=0;i<n;i++)r[i]>a&&(a=r[i]);e.indices=N.tipsify({indices:r,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=h.computeNumberOfVertices(e);if(c(e.indices)&&r>=T.SIXTY_FOUR_KILOBYTES){var n,a=[],i=[],o=0,u=M(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var d=0;d<n;++d){var E=s[f+d],m=a[E];c(m)||(m=o++,a[E]=m,x(u,e.attributes,E)),i.push(m)}o+n>=T.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=M(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new a,ne=new o;te.projectTo2D=function(e,t,r,n,i){var o=e.attributes[t];i=c(i)?i:new d;for(var s=i.ellipsoid,l=o.values,f=new Float64Array(l.length),h=0,m=0;m<l.length;m+=3){var p=a.fromArray(l,m,re),y=s.cartesianToCartographic(p,ne),_=i.project(y,re);f[h++]=_.x,f[h++]=_.y,f[h++]=_.z}return e.attributes[r]=o,e.attributes[n]=new E({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var d=a.componentsPerAttribute;return e.attributes[r]=new E({componentDatatype:u.FLOAT,componentsPerAttribute:d,values:s}),e.attributes[n]=new E({componentDatatype:u.FLOAT,componentsPerAttribute:d,values:c}),delete e.attributes[t],e};var ie=new a,oe=new v,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(v.equals(t,v.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(v.inverse(t,oe),v.transpose(oe,oe),v.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=r.transform(a,t,a)),e.modelMatrix=v.clone(v.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,a=0;a<n;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&r.push(i)}var o=[];return t.length>0&&o.push(L(t,"geometry")),r.length>0&&(o.push(L(r,"westHemisphereGeometry")),o.push(L(r,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,fe=new a,de=new a;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,i=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var d=0;for(t=0;t<s;t+=3){var h=r[t],m=r[t+1],p=r[t+2],y=3*h,_=3*m,R=3*p;le.x=i[y],le.y=i[y+1],le.z=i[y+2],fe.x=i[_],fe.y=i[_+1],fe.z=i[_+2],de.x=i[R],de.y=i[R+1],de.z=i[R+2],c[h].count++,c[m].count++,c[p].count++,a.subtract(fe,le,fe),a.subtract(de,le,de),l[d]=a.cross(fe,de,new a),d++}var v=0;for(t=0;t<o;t++)c[t].indexOffset+=v,v+=c[t].count;d=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var S=A.indexOffset+A.currentCount;f[S]=d,A.currentCount++,A=c[r[t+1]],S=A.indexOffset+A.currentCount,f[S]=d,A.currentCount++,A=c[r[t+2]],S=A.indexOffset+A.currentCount,f[S]=d,A.currentCount++,d++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var I=3*t;if(A=c[t],a.clone(a.ZERO,ce),A.count>0){for(d=0;d<A.count;d++)a.add(ce,l[f[A.indexOffset+d]],ce);a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&a.clone(l[f[A.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[I]=ce.x,N[I+1]=ce.y,N[I+2]=ce.z}return e.attributes.normal=new E({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,Ee=new a,me=new a;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,d,h;for(t=0;t<c;t+=3){var m=r[t],p=r[t+1],y=r[t+2];f=3*m,d=3*p,h=3*y;var _=2*m,T=2*p,R=2*y,v=n[f],A=n[f+1],S=n[f+2],N=o[_],I=o[_+1],O=o[T+1]-I,g=o[R+1]-I,w=1/((o[T]-N)*g-(o[R]-N)*O),M=(g*(n[d]-v)-O*(n[h]-v))*w,x=(g*(n[d+1]-A)-O*(n[h+1]-A))*w,C=(g*(n[d+2]-S)-O*(n[h+2]-S))*w;l[f]+=M,l[f+1]+=x,l[f+2]+=C,l[d]+=M,l[d+1]+=x,l[d+2]+=C,l[h]+=M,l[h+1]+=x,l[h+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,d=f+1,h=f+2;var L=a.fromArray(i,f,he),U=a.fromArray(l,f,me),b=a.dot(L,U);a.multiplyByScalar(L,b,Ee),a.normalize(a.subtract(U,Ee,U),U),P[f]=U.x,P[d]=U.y,P[h]=U.z,a.normalize(a.cross(L,U,U),U),D[f]=U.x,D[d]=U.y,D[h]=U.z}return e.attributes.tangent=new E({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new E({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var pe=new n,ye=new a,_e=new a,Te=new a,Re=new n;te.compressVertices=function(t){var r,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),f=0;for(r=0;r<i;++r)a.fromArray(s,3*r,ye),a.equals(ye,a.ZERO)?f+=2:(Re=e.octEncodeInRange(ye,65535,Re),l[f++]=Re.x,l[f++]=Re.y);return t.attributes.compressedAttributes=new E({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var d=t.attributes.normal,h=t.attributes.st,m=c(d),p=c(h);if(!m&&!p)return t;var y,_,T,R,v=t.attributes.tangent,A=t.attributes.bitangent,S=c(v),N=c(A);m&&(y=d.values),p&&(_=h.values),S&&(T=v.values),N&&(R=A.values),i=(m?y.length:_.length)/(m?3:2);var I=i,O=p&&m?2:1;O+=S||N?1:0,I*=O;var g=new Float32Array(I),w=0;for(r=0;r<i;++r){p&&(n.fromArray(_,2*r,pe),g[w++]=e.compressTextureCoordinates(pe));var M=3*r;m&&c(T)&&c(R)?(a.fromArray(y,M,ye),a.fromArray(T,M,_e),a.fromArray(R,M,Te),e.octPack(ye,_e,Te,pe),g[w++]=pe.x,g[w++]=pe.y):(m&&(a.fromArray(y,M,ye),g[w++]=e.octEncodeFloat(ye)),S&&(a.fromArray(T,M,ye),g[w++]=e.octEncodeFloat(ye)),N&&(a.fromArray(R,M,ye),g[w++]=e.octEncodeFloat(ye)))}return t.attributes.compressedAttributes=new E({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:g}),m&&delete t.attributes.normal,p&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var ve=new a,Ae=new a,Se=new a,Ne=new a,Ie=new a,Oe={positions:new Array(7),indices:new Array(9)},ge=new a,we=new a,Me=new a,xe=new a,Ce=new n,Pe=new n,De=new n,Le=A.fromPointNormal(a.ZERO,a.UNIT_Y),Ue=new a,be=new a,Fe=new n,Be=new n,ze=new a,Ge=new a,qe=new a,Ve=new a,Xe=new a,We=new a,He=new i,Ye=5*T.EPSILON9,ke=T.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==y.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else q(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,a){return t(e).then(r,n,a)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=a(e),t}function r(t){return e(t,i)}function n(e){this.then=e}function a(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return i(e)}})}function i(e){return new n(function(r,n){try{return n?t(n(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,r){return d(e,t,r)}function r(e){return E(e)}function a(e){return E(i(e))}function u(e){return h(e)}var s,c,l,f,d,h,E;return c=new n(e),s={then:e,resolve:r,reject:a,progress:u,promise:c,resolver:{resolve:r,reject:a,progress:u}},l=[],f=[],d=function(e,t,r){var n,a;return n=o(),a="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,a)}),f.push(a),n.promise},h=function(e){return m(f,e),e},E=function(e){return e=t(e),d=e.then,E=t,h=y,m(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,a,i){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,d,h,E,m,p,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,d=[],h=o(),c)for(p=h.progress,m=function(e){d.push(e),--l||(E=m=y,h.reject(d))},E=function(e){f.push(e),--c||(E=m=y,h.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,p);else h.resolve(f);return h.then(n,a,i)})}function c(e,t,r,n){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,r,n)}function l(e,t,r,n){return p(1,arguments),d(e,_).then(t,r,n)}function f(){return d(arguments,_)}function d(t,r){return e(t,function(t){var n,a,i,u,s,c;if(i=a=t.length>>>0,n=[],c=o(),i)for(u=function(t,a){e(t,r).then(function(e){n[a]=e,--i||c.resolve(n)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(n);return c.promise})}function h(t,r){var n=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,n[0]=function(t,n,i){return e(t,function(t){return e(n,function(e){return r(t,e,i,a)})})},T.apply(t,n)})}function E(t,r,n){var a=arguments.length>2;return e(t,function(e){return e=a?n:e,r.resolve(e),e},function(e){return r.reject(e),i(e)},r.progress)}function m(e,t){for(var r,n=0;r=e[n++];)r(t)}function p(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function y(){}function _(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=d,e.reduce=h,e.any=c,e.some=s,e.chain=E,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,r,n,a,i;if(i=0,t=Object(this),a=t.length>>>0,r=arguments,r.length<=1)for(;;){if(i in t){n=t[i++];break}if(++i>=a)throw new TypeError}else n=r[1];for(;i<a;++i)i in t&&(n=e(n,t[i],i,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,a,i=0,o=e.length-1;i<=o;)if(n=~~((i+o)/2),(a=r(e[n],t))<0)i=n+1;else{if(!(a>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],a=function(e,t,r,n){r||(r=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+a:a+e},i=function(e,t,r,n,i,o){var u=n-e.length;return u>0&&(e=r||!i?a(e,n,o,r):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+a(c.toString(t),u||0,"0",!1),i(e,r,n,o,s)},u=function(e,t,r,n,a,o){return null!=n&&(e=e.slice(0,n)),i(e,"",t,r,a,o)},s=function(e,n,s,c,l,f,d){var h,E,m,p,y;if("%%"==e)return"%";for(var _=!1,T="",R=!1,v=!1,A=" ",S=s.length,N=0;s&&N<S;N++)switch(s.charAt(N)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(N+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(d)>-1?6:"d"==d?0:void 0,y=n?t[n.slice(0,-1)]:t[r++],d){case"s":return u(String(y),_,c,f,R,A);case"c":return u(String.fromCharCode(+y),_,c,f,R);case"b":return o(y,2,v,_,c,f,R);case"o":return o(y,8,v,_,c,f,R);case"x":return o(y,16,v,_,c,f,R);case"X":return o(y,16,v,_,c,f,R).toUpperCase();case"u":return o(y,10,v,_,c,f,R);case"i":case"d":return h=+y||0,h=Math.round(h-h%1),E=h<0?"-":T,y=E+a(String(Math.abs(h)),f,"0",!1),i(y,E,_,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return h=+y,E=h<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(d.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(d)%2],y=E+Math.abs(h)[m](f),i(y,E,_,c,R)[p]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,a,i,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var a=r[n].offset;if(n>0){m.secondsDifference(r[n].julianDate,e)>a&&(n--,a=r[n].offset)}m.addSeconds(e,a,e)}function d(e,r){_.julianDate=e;var n=m.leapSeconds,a=t(n,_,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-n[0].offset,r);if(a>=n.length)return m.addSeconds(e,-n[a-1].offset,r);var i=m.secondsDifference(n[a].julianDate,e);return 0===i?m.addSeconds(e,-n[a].offset,r):i<=1?void 0:m.addSeconds(e,-n[--a].offset,r)}function h(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function E(e,t,r,n,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=i+(n*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,h(a,t,this),n===c.UTC&&f(this)}var p=new i,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,N=/([Z+\-])?(\d{2})?:?(\d{2})?$/,I=/^(\d{2})(\.\d+)?/.source+N.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+N.source,g=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+N.source;m.fromGregorianDate=function(e,t){var r=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(h(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromDate=function(e,t){var r=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(h(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,a,i,u=e.split("T"),s=1,l=1,d=0,p=0,_=0,N=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(R)))r=+u[1],s=+u[2];else if(null!==(u=w.match(T)))r=+u[1];else{var x;if(null!==(u=w.match(v)))r=+u[1],x=+u[2],i=o(r);else if(null!==(u=w.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));x=7*C+P-D.getUTCDay()-3}a=new Date(Date.UTC(r,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(r);var L;if(n(M)){u=M.match(g),null!==u?(d=+u[1],p=+u[2],_=+u[3],N=1e3*+(u[4]||0),L=5):(u=M.match(O),null!==u?(d=+u[1],p=+u[2],_=60*+(u[3]||0),L=4):null!==(u=M.match(I))&&(d=+u[1],p=60*+(u[2]||0),L=3));var U=u[L],b=+u[L+1],F=+(u[L+2]||0);switch(U){case"+":d-=b,p-=F;break;case"-":d+=b,p+=F;break;case"Z":break;default:p+=new Date(Date.UTC(r,s-1,l,d,p)).getTimezoneOffset()}}var B=60===_;for(B&&_--;p>=60;)p-=60,d++;for(;d>=24;)d-=24,l++;for(a=i&&2===s?29:y[s-1];l>a;)l-=a,s++,s>12&&(s-=12,r++),a=i&&2===s?29:y[s-1];for(;p<0;)p+=60,d--;for(;d<0;)d+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),a=i&&2===s?29:y[s-1],l+=a;var z=E(r,s,l,d,p,_,N);return n(t)?(h(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var w=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var r=!1,a=d(e,w);n(a)||(m.addSeconds(e,-1,w),a=d(w,w),r=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var h=80*c/2447|0,E=c-(2447*h/80|0)|0;c=h/11|0;var p=h+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(v+=1),n(t)?(t.year=y,t.month=p,t.day=E,t.hour=_,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=r,t):new i(y,p,E,_,R,v,A,r)},m.toDate=function(e){var t=m.toGregorianDate(e,p),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var a,i=m.toGregorianDate(t,p);return n(r)||0===i.millisecond?n(r)&&0!==r?(a=(.01*i.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},m.addSeconds=function(e,t,r){return h(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return h(e.dayNumber,n,r)},m.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return h(e.dayNumber,n,r)},m.addDays=function(e,t,r){return h(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var a=new r.constructor;for(var i in r)if(r.hasOwnProperty(i)){var o=r[i];n&&(o=t(o,n)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,r){"use strict";function n(n){n=e(n,e.EMPTY_OBJECT);var a=e(n.throttleByServer,!1),i=a||e(n.throttle,!1);this.url=n.url,this.requestFunction=n.requestFunction,this.cancelFunction=n.cancelFunction,this.priorityFunction=n.priorityFunction,this.priority=e(n.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(n.type,r.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return n.prototype.cancel=function(){this.cancelled=!0},n}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var a=r[n],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(a[c],a[e])<0?c:e,s<r&&n(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,n=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return r(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return i(r,e,--this._length),this.heapify(e),n}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<l.maximumRequestsPerServer}function h(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function p(e){var t=h(e);return e.state=s.ACTIVE,S.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function y(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function _(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),_())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},v=20,A=new i({comparator:c});A.maximumLength=v,A.reserve(v);var S=[],N={},I="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return v},set:function(e){if(e<v)for(;A.length>e;){var t=A.pop();y(t)}v=e,A.maximumLength=e,A.reserve(e)}}}),l.update=function(){var e,t,r=0,n=S.length;for(e=0;e<n;++e)t=S[e],t.cancelled&&y(t),t.state===s.ACTIVE?r>0&&(S[e-r]=t):++r;S.length-=r;var a=A.internalArray,i=A.length;for(e=0;e<i;++e)f(a[e]);A.resort();for(var o=Math.max(l.maximumRequests-S.length,0),u=0;u<o&&A.length>0;)t=A.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(p(t),++u):y(t);T()},l.getServerKey=function(t){var r=new e(t).resolve(I);r.normalize();var a=r.authority;/:/.test(a)||(a=a+":"+("https"===r.scheme?"443":"80"));var i=N[a];return n(i)||(N[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return p(e);if(!(S.length>=l.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){f(e);var t=A.insert(e);if(n(t)){if(t===e)return;y(t)}return h(e)}},l.clearForSpecs=function(){for(;A.length>0;){y(A.pop())}for(var e=S.length,t=0;t<e;++t)y(S[t]);S.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return N[e]},l.requestHeap=A,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var a=n.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=n.getScheme() -;if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,r){var n=e.toLowerCase()+":"+r;t(i[n])||(i[n]=!0)},a.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(i[n])&&delete i[n]},a.contains=function(e){var r=n(e);return!(!t(r)||!t(i[r]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t){t=r(t,r.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=r(t.method,"GET"),c=t.data,f=t.headers,d=t.overrideMimeType;a=r(a,t.url);var h=n(t.request)?t.request:new i;return h.url=a,h.requestFunction=function(){var t=e.defer(),r=l.load(a,o,s,c,f,t,d);return n(r)&&n(r.abort)&&(h.cancelFunction=function(){r.abort()}),t.promise},u.request(h)}function f(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function d(e,t){for(var r=f(e,t),n=new ArrayBuffer(r.length),a=new Uint8Array(n),i=0;i<r.length;i++)a[i]=r.charCodeAt(i);return n}function h(e,t){t=r(t,"");var n=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return d(a,i);case"blob":var o=d(a,i);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(f(a,i),n);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,r,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(h(f,t));var d=new XMLHttpRequest;if(c.contains(e)&&(d.withCredentials=!0),n(l)&&n(d.overrideMimeType)&&d.overrideMimeType(l),d.open(r,e,!0),n(i))for(var m in i)i.hasOwnProperty(m)&&d.setRequestHeader(m,i[m]);n(t)&&(d.responseType=t);var p=!1;return"string"==typeof e&&(p=0===e.indexOf("file://")),d.onload=function(){if((d.status<200||d.status>=300)&&(!p||0!==d.status))return void u.reject(new o(d.status,d.response,d.getAllResponseHeaders()));var e=d.response,r=d.responseType;if(204===d.status)u.resolve();else if(!n(e)||n(t)&&r!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===r||"document"===r)&&n(d.responseXML)&&d.responseXML.hasChildNodes()?u.resolve(d.responseXML):""!==r&&"text"!==r||!n(d.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(d.responseText);else u.resolve(e)},d.onerror=function(e){u.reject(new o)},d.send(a),d},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,r,n){return e({url:t,headers:r,request:n})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,r,n){"use strict";function a(r,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=n(r,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,a,i,o,u,s,c,l,f){"use strict";function d(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))E(this,t.data);else if(n(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function h(e,t){return o.compare(e.julianDate,t)}function E(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=r.columnNames.indexOf("modifiedJulianDateUtc"),i=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),d=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||d<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=r.samples,y=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=d,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,R=0,v=p.length;R<v;R+=e._columnCount){var A=p[R+a],S=p[R+m],N=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,I=new o(N,S,f.TAI);if(y.push(I),T){if(S!==_&&n(_)){var O=o.leapSeconds,g=t(O,I,h);if(g<0){var w=new u(I,S);O.splice(~g,0,w)}}_=S}}}function m(e,t,r,n,a){var i=r*n;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,r){return t+e*(r-t)}function y(e,t,r,n,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||n.equals(c))return m(e,r,a,s,u),u;if(n.equals(l))return m(e,r,i,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),d=a*s,h=i*s,E=r[d+e._ut1MinusUtcSecondsColumn],y=r[h+e._ut1MinusUtcSecondsColumn],_=y-E;if(_>.5||_<-.5){var T=r[d+e._taiMinusUtcSecondsColumn],R=r[h+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(n)?E=y:y-=R-T)}return u.xPoleWander=p(f,r[d+e._xPoleWanderRadiansColumn],r[h+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,r[d+e._yPoleWanderRadiansColumn],r[h+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,r[d+e._xCelestialPoleOffsetRadiansColumn],r[h+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,r[d+e._yCelestialPoleOffsetRadiansColumn],r[h+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,y),u}return d.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),d.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},d.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new a(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var i=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=i[u],d=i[u+1],h=o.lessThanOrEquals(f,e),E=!n(d),m=E||o.greaterThanOrEquals(d,e);if(h&&m)return s=u,!E&&d.equals(e)&&++s,l=s+1,y(this,i,this._samples,e,s,l,r),r}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,i,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},d}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=t(n,document.location.href);var a=new e(n);return new e(r).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(n,a,i){if(i=t(i,!0),n instanceof e||(n=new e(n)),a instanceof e||(a=new e(a)),"data"===n.scheme)return n.toString();if("data"===a.scheme)return a.toString();r(a.authority)&&!r(a.scheme)&&("undefined"!=typeof document&&r(document.location)&&r(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=n.scheme);var o=n;a.isAbsolute()&&(o=a);var u="";r(o.scheme)&&(u+=o.scheme+":"),r(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===n?i?n.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):n.path+a.path:a.path;var s=r(n.query),c=r(a.query);s&&c?u+="?"+n.query+"&"+a.query:s&&!c?u+="?"+n.query:!s&&c&&(u+="?"+a.query);var l=r(a.fragment);return r(n.fragment)&&!l?u+="#"+n.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,r,n,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),a=E.exec(n);if(null!==a)return a[1]}}function u(){if(t(f))return f;var r;return r="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(n(r))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(d)||(d=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(h)||(h=document.createElement("a"));var r=d(e);return h.href=r,h.href=h.href,h.href}var f,d,h,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){n[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(n[s]*=s-c);n[s]=1/n[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,i.daysDifference(n,e._sampleZeroDateTT)}function l(r,a){if(r._chunkDownloadsInProgress[a])return r._chunkDownloadsInProgress[a];var i=e.defer();r._chunkDownloadsInProgress[a]=i;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){r._chunkDownloadsInProgress[a]=!1;for(var t=r._samples,n=e.samples,o=a*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,r,n,a){var i=c(this,t,r),o=c(this,n,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,d=s/this._samplesPerXysFile|0,h=[],E=f;E<=d;++E)h.push(l(this,E));return e.all(h)},s.prototype.computeXysRadians=function(e,t,r){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var d=!1,h=this._samples;if(n(h[3*s])||(l(this,s/this._samplesPerXysFile|0),d=!0),n(h[3*f])||(l(this,f/this._samplesPerXysFile|0),d=!0),!d){n(r)?(r.x=0,r.y=0,r.s=0):r=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)y[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=y[m]);T[E]*=_[E];var v=3*(s+E);r.x+=T[E]*h[v++],r.y+=T[E]*h[v++],r.s+=T[E]*h[v]}return r}}}},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,a,i,o,u,s,c,l,f,d,h,E,m,p,y,_,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},N={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},I=new r,O=new r,g=new r;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,a=v[e][t],i=e+t;return u(S[i])?n=S[i]:(n=function(n,i,s){if(u(s)||(s=new y),m.equalsEpsilon(n.x,0,m.EPSILON14)&&m.equalsEpsilon(n.y,0,m.EPSILON14)){var c=m.sign(n.z);r.unpack(A[e],0,I),"east"!==e&&"west"!==e&&r.multiplyByScalar(I,c,I),r.unpack(A[t],0,O),"east"!==t&&"west"!==t&&r.multiplyByScalar(O,c,O),r.unpack(A[a],0,g),"east"!==a&&"west"!==a&&r.multiplyByScalar(g,c,g)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(n,N.up);var l=N.up,d=N.east;d.x=-n.y,d.y=n.x,d.z=0,r.normalize(d,N.east),r.cross(l,d,N.north),r.multiplyByScalar(N.up,-1,N.down),r.multiplyByScalar(N.east,-1,N.west),r.multiplyByScalar(N.north,-1,N.south),I=N[e],O=N[t],g=N[a]}return s[0]=I.x,s[1]=I.y,s[2]=I.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=g.x,s[9]=g.y,s[10]=g.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},S[i]=n),n},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var w=new _,M=new r(1,1,1),x=new y;R.headingPitchRollToFixedFrame=function(e,t,n,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=y.fromTranslationQuaternionRotationScale(r.ZERO,u,M,x);return i=a(e,n,i),y.multiply(i,s,i)};var C=new y,P=new p;R.headingPitchRollQuaternion=function(e,t,r,n,a){var i=R.headingPitchRollToFixedFrame(e,t,r,n,C),o=y.getRotation(i,P);return _.fromRotationMatrix(o,a)};var D=m.TWO_PI/86400,L=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){L=E.addSeconds(e,-E.computeTaiMinusUtc(e),L);var r,n=L.dayNumber,a=L.secondsOfDay,i=n-2451545;r=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,d=Math.cos(f),h=Math.sin(f);return u(t)?(t[0]=d,t[1]=-h,t[2]=0,t[3]=h,t[4]=d,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(d,h,0,-h,d,0,0,0,1)},R.iau2006XysData=new d,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(r,n,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var r=R.computeFixedToIcrfMatrix(e,t);if(u(r))return p.transpose(r,t)};var U=new h(0,0,0),b=new l(0,0,0,0,0,0),F=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var r=R.earthOrientationParameters.compute(e,b);if(u(r)){var n=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(n,a,U);if(u(i)){var o=i.x+r.xPoleOffset,s=i.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,B),d=p.multiply(l,f,F),h=e.dayNumber,y=e.secondsOfDay-E.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=h-2451545,v=y/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(_+v);A=A%1*m.TWO_PI;var S=p.fromRotationZ(A,B),N=p.multiply(d,S,F),I=Math.cos(r.xPoleWander),O=Math.cos(r.yPoleWander),g=Math.sin(r.xPoleWander),w=Math.sin(r.yPoleWander),M=n-2451545+a/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),D=B;return D[0]=I*C,D[1]=I*P,D[2]=g,D[3]=-O*P+w*g*C,D[4]=O*C+w*g*P,D[5]=-w*I,D[6]=-w*P-O*g*C,D[7]=w*C-O*g*P,D[8]=O*I,p.multiply(N,D,t)}}};var z=new n;R.pointToWindowCoordinates=function(e,t,r,n){return n=R.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},R.pointToGLWindowCoordinates=function(e,r,a,i){u(i)||(i=new t);var o=z;return y.multiplyByVector(e,n.fromElements(a.x,a.y,a.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(r,o,o),t.fromCartesian4(o,i)};var G=new r,q=new r,V=new r;R.rotationMatrixFromPositionVelocity=function(e,t,n,a){var i=o(n,f.WGS84).geodeticSurfaceNormal(e,G),s=r.cross(t,i,q);r.equalsEpsilon(s,r.ZERO,m.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,V);return r.cross(t,c,s),r.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var X=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),W=new a,H=new r,Y=new r,k=new p,j=new y,Z=new y;return R.basisTo2D=function(e,t,n){var a=y.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,W),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,n);return y.multiply(X,f,n),y.setTranslation(n,u,n),n},R.wgs84To2DModelMatrix=function(e,t,n){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=y.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,W),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(X,o,n),y.multiply(c,n,n),n},R}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,n){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=n(new a({position:!0})),a.POSITION_AND_NORMAL=n(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=n(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=n(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=n(new a({position:!0,color:!0})),a.ALL=n(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,r,n){return n=e(n,0),r[n++]=t.position?1:0,r[n++]=t.normal?1:0,r[n++]=t.st?1:0,r[n++]=t.tangent?1:0,r[n++]=t.bitangent?1:0,r[n]=t.color?1:0,r},a.unpack=function(r,n,i){return n=e(n,0),t(i)||(i=new a),i.position=1===r[n++],i.normal=1===r[n++],i.st=1===r[n++],i.tangent=1===r[n++],i.bitangent=1===r[n++],i.color=1===r[n],i},a.clone=function(e,r){if(t(e))return t(r)||(r=new a),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},a}),define("Core/EllipseGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./Matrix4","./PrimitiveType","./Quaternion","./Rectangle","./Transforms","./VertexFormat"],function(e,t,r,n,a,i,o,u,s,c,l,f,d,h,E,m,p,y,_,T,R,v,A,S,N,I){"use strict";function O(e,n,i){var o=n.vertexFormat,u=n.center,s=n.semiMajorAxis,l=n.semiMinorAxis,d=n.ellipsoid,m=n.stRotation,p=i?e.length/3*2:e.length/3,y=n.shadowVolume,_=o.st?new Float32Array(2*p):void 0,R=o.normal?new Float32Array(3*p):void 0,v=o.tangent?new Float32Array(3*p):void 0,S=o.bitangent?new Float32Array(3*p):void 0,N=y?new Float32Array(3*p):void 0,I=0,O=q,g=V,w=X,M=new f(d),x=M.project(d.cartesianToCartographic(u,W),H),C=d.scaleToGeodeticSurface(u,L);d.geodeticSurfaceNormal(C,C);for(var P=A.fromAxisAngle(C,m,G),D=T.fromQuaternion(P,z),F=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Y),j=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,k),Z=e.length,K=i?Z:0,J=K/3*2,Q=0;Q<Z;Q+=3){var $=Q+1,ee=Q+2,te=r.fromArray(e,Q,L);if(o.st){var re=T.multiplyByVector(D,te,U),ne=M.project(d.cartesianToCartographic(re,W),b);r.subtract(ne,x,ne),B.x=(ne.x+s)/(2*s),B.y=(ne.y+l)/(2*l),F.x=Math.min(B.x,F.x),F.y=Math.min(B.y,F.y),j.x=Math.max(B.x,j.x),j.y=Math.max(B.y,j.y),i&&(_[I+J]=B.x,_[I+1+J]=B.y),_[I++]=B.x,_[I++]=B.y}(o.normal||o.tangent||o.bitangent||y)&&(O=d.geodeticSurfaceNormal(te,O),y&&(N[Q+K]=-O.x,N[$+K]=-O.y,N[ee+K]=-O.z),(o.normal||o.tangent||o.bitangent)&&((o.tangent||o.bitangent)&&(g=r.normalize(r.cross(r.UNIT_Z,O,g),g),T.multiplyByVector(D,g,g)),o.normal&&(R[Q]=O.x,R[$]=O.y,R[ee]=O.z,i&&(R[Q+K]=-O.x,R[$+K]=-O.y,R[ee+K]=-O.z)),o.tangent&&(v[Q]=g.x,v[$]=g.y,v[ee]=g.z,i&&(v[Q+K]=-g.x,v[$+K]=-g.y,v[ee+K]=-g.z)),o.bitangent&&(w=r.normalize(r.cross(O,g,w),w),S[Q]=w.x,S[$]=w.y,S[ee]=w.z,i&&(S[Q+K]=w.x,S[$+K]=w.y,S[ee+K]=w.z))))}if(o.st){Z=_.length;for(var ae=0;ae<Z;ae+=2)_[ae]=(_[ae]-F.x)/(j.x-F.x),_[ae+1]=(_[ae+1]-F.y)/(j.y-F.y)}var ie=new E;if(o.position){var oe=c.raisePositionsToHeight(e,n,i);ie.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:oe})}return o.st&&(ie.st=new h({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:_})),o.normal&&(ie.normal=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:R})),o.tangent&&(ie.tangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:v})),o.bitangent&&(ie.bitangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:S})),y&&(ie.extrudeDirection=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:N})),ie}function g(e){var t,r,n,a,i,o=new Array(e*(e+1)*12-6),u=0;for(t=0,n=1,a=0;a<3;a++)o[u++]=n++,o[u++]=t,o[u++]=n;for(a=2;a<e+1;++a){for(n=a*(a+1)-1,t=(a-1)*a-1,o[u++]=n++,o[u++]=t,o[u++]=n,r=2*a,i=0;i<r-1;++i)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=n++,o[u++]=t,o[u++]=n}for(r=2*e,++n,++t,a=0;a<r-1;++a)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;for(o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t++,o[u++]=t,++t,a=e-1;a>1;--a){for(o[u++]=t++,o[u++]=t,o[u++]=n,r=2*a,i=0;i<r-1;++i)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=t++,o[u++]=t++,o[u++]=n++}for(a=0;a<3;a++)o[u++]=t++,o[u++]=t,o[u++]=n;return o}function w(t){var n=t.center;j=r.multiplyByScalar(t.ellipsoid.geodeticSurfaceNormal(n,j),t.height,j),j=r.add(n,j,j);var a=new e(j,t.semiMajorAxis),i=c.computeEllipsePositions(t,!0,!1),o=i.positions,u=i.numPts,s=O(o,t,!1),l=g(u);return l=y.createTypedArray(o.length/3,l),{boundingSphere:a,attributes:s,indices:l}}function M(e,n){var i=n.vertexFormat,o=n.center,u=n.semiMajorAxis,s=n.semiMinorAxis,c=n.ellipsoid,l=n.height,d=n.extrudedHeight,m=n.stRotation,p=e.length/3*2,y=new Float64Array(3*p),_=i.st?new Float32Array(2*p):void 0,R=i.normal?new Float32Array(3*p):void 0,v=i.tangent?new Float32Array(3*p):void 0,S=i.bitangent?new Float32Array(3*p):void 0,N=n.shadowVolume,I=N?new Float32Array(3*p):void 0,O=0,g=q,w=V,M=X,x=new f(c),C=x.project(c.cartesianToCartographic(o,W),H),P=c.scaleToGeodeticSurface(o,L);c.geodeticSurfaceNormal(P,P);for(var D=A.fromAxisAngle(P,m,G),j=T.fromQuaternion(D,z),Z=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Y),K=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,k),J=e.length,Q=J/3*2,$=0;$<J;$+=3){var ee,te=$+1,re=$+2,ne=r.fromArray(e,$,L);if(i.st){var ae=T.multiplyByVector(j,ne,U),ie=x.project(c.cartesianToCartographic(ae,W),b);r.subtract(ie,C,ie),B.x=(ie.x+u)/(2*u),B.y=(ie.y+s)/(2*s),Z.x=Math.min(B.x,Z.x),Z.y=Math.min(B.y,Z.y),K.x=Math.max(B.x,K.x),K.y=Math.max(B.y,K.y),_[O+Q]=B.x,_[O+1+Q]=B.y,_[O++]=B.x,_[O++]=B.y}ne=c.scaleToGeodeticSurface(ne,ne),ee=r.clone(ne,U),g=c.geodeticSurfaceNormal(ne,g),N&&(I[$+J]=-g.x,I[te+J]=-g.y,I[re+J]=-g.z);var oe=r.multiplyByScalar(g,l,F);if(ne=r.add(ne,oe,ne),oe=r.multiplyByScalar(g,d,oe),ee=r.add(ee,oe,ee),i.position&&(y[$+J]=ee.x,y[te+J]=ee.y,y[re+J]=ee.z,y[$]=ne.x,y[te]=ne.y,y[re]=ne.z),i.normal||i.tangent||i.bitangent){M=r.clone(g,M);var ue=r.fromArray(e,($+3)%J,F);r.subtract(ue,ne,ue);var se=r.subtract(ee,ne,b);g=r.normalize(r.cross(se,ue,g),g),i.normal&&(R[$]=g.x,R[te]=g.y,R[re]=g.z,R[$+J]=g.x,R[te+J]=g.y,R[re+J]=g.z),i.tangent&&(w=r.normalize(r.cross(M,g,w),w),v[$]=w.x,v[te]=w.y,v[re]=w.z,v[$+J]=w.x,v[$+1+J]=w.y,v[$+2+J]=w.z),i.bitangent&&(S[$]=M.x,S[te]=M.y,S[re]=M.z,S[$+J]=M.x,S[te+J]=M.y,S[re+J]=M.z)}}if(i.st){J=_.length;for(var ce=0;ce<J;ce+=2)_[ce]=(_[ce]-Z.x)/(K.x-Z.x),_[ce+1]=(_[ce+1]-Z.y)/(K.y-Z.y)}var le=new E;return i.position&&(le.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:y})),i.st&&(le.st=new h({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:_})),i.normal&&(le.normal=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:R})),i.tangent&&(le.tangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:v})),i.bitangent&&(le.bitangent=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:S})),N&&(le.extrudeDirection=new h({componentDatatype:a.FLOAT,componentsPerAttribute:3,values:I})),le}function x(e){for(var t=e.length/3,r=y.createTypedArray(t,6*t),n=0,a=0;a<t;a++){var i=a,o=a+t,u=(i+1)%t,s=u+t;r[n++]=i,r[n++]=o,r[n++]=u,r[n++]=u,r[n++]=o,r[n++]=s}return r}function C(t){var n=t.center,a=t.ellipsoid,i=t.semiMajorAxis,o=r.multiplyByScalar(a.geodeticSurfaceNormal(n,L),t.height,L);Z.center=r.add(n,o,Z.center),Z.radius=i,o=r.multiplyByScalar(a.geodeticSurfaceNormal(n,o),t.extrudedHeight,o),K.center=r.add(n,o,K.center),K.radius=i;var u=c.computeEllipsePositions(t,!0,!0),s=u.positions,l=u.numPts,f=u.outerPositions,h=e.union(Z,K),E=O(s,t,!0),_=g(l),T=_.length;_.length=2*T;for(var R=s.length/3,A=0;A<T;A+=3)_[A+T]=_[A+2]+R,_[A+1+T]=_[A+1]+R,_[A+2+T]=_[A]+R;var S=y.createTypedArray(2*R/3,_),N=new d({attributes:E,indices:S,primitiveType:v.TRIANGLES}),I=M(f,t);_=x(f);var w=y.createTypedArray(2*f.length/3,_),C=new d({attributes:I,indices:w,primitiveType:v.TRIANGLES}),P=p.combineInstances([new m({geometry:N}),new m({geometry:C})]);return{boundingSphere:h,attributes:P[0].attributes,indices:P[0].indices}}function P(e,t,n,a,i){N.eastNorthUpToFixedFrame(e,t,J),R.inverseTransformation(J,Q);var o;for(o=0;o<4;++o)r.clone(r.ZERO,ee[o]);for(ee[0].x+=n,ee[1].x-=n,ee[2].y+=a,ee[3].y-=a,T.fromRotationZ(i,$),o=0;o<4;++o)T.multiplyByVector($,ee[o],ee[o]),R.multiplyByPoint(J,ee[o],ee[o]),t.cartesianToCartographic(ee[o],te[o]);return S.fromCartographicArray(te)}function D(e){e=i(e,i.EMPTY_OBJECT);var t=e.center,n=i(e.ellipsoid,l.WGS84),a=e.semiMajorAxis,u=e.semiMinorAxis,s=i(e.granularity,_.RADIANS_PER_DEGREE),c=i(e.height,0),f=e.extrudedHeight,d=o(f)&&Math.abs(c-f)>1,h=i(e.vertexFormat,I.DEFAULT);this._center=r.clone(t),this._semiMajorAxis=a,this._semiMinorAxis=u,this._ellipsoid=l.clone(n),this._rotation=i(e.rotation,0),this._stRotation=i(e.stRotation,0),this._height=c,this._granularity=s,this._vertexFormat=I.clone(h),this._extrudedHeight=i(f,c),this._extrude=d,this._shadowVolume=i(e.shadowVolume,!1),this._workerName="createEllipseGeometry",this._rectangle=P(this._center,this._ellipsoid,a,u,this._rotation)}var L=new r,U=new r,b=new r,F=new r,B=new t,z=new T,G=new A,q=new r,V=new r,X=new r,W=new n,H=new r,Y=new t,k=new t,j=new r,Z=new e,K=new e,J=new R,Q=new R,$=new T,ee=[new r,new r,new r,new r],te=[new n,new n,new n,new n];D.packedLength=r.packedLength+l.packedLength+I.packedLength+S.packedLength+9,D.pack=function(e,t,n){return n=i(n,0),r.pack(e._center,t,n),n+=r.packedLength,l.pack(e._ellipsoid,t,n),n+=l.packedLength,I.pack(e._vertexFormat,t,n),n+=I.packedLength,S.pack(e._rectangle,t,n),n+=S.packedLength,t[n++]=e._semiMajorAxis,t[n++]=e._semiMinorAxis,t[n++]=e._rotation,t[n++]=e._stRotation,t[n++]=e._height,t[n++]=e._granularity,t[n++]=e._extrudedHeight,t[n++]=e._extrude?1:0,t[n]=e._shadowVolume?1:0,t};var re=new r,ne=new l,ae=new I,ie=new S,oe={center:re,ellipsoid:ne,vertexFormat:ae,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,stRotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,shadowVolume:void 0};return D.unpack=function(e,t,n){t=i(t,0);var a=r.unpack(e,t,re);t+=r.packedLength;var u=l.unpack(e,t,ne);t+=l.packedLength;var s=I.unpack(e,t,ae);t+=I.packedLength;var c=S.unpack(e,t,ie);t+=S.packedLength;var f=e[t++],d=e[t++],h=e[t++],E=e[t++],m=e[t++],p=e[t++],y=e[t++],_=1===e[t++],T=1===e[t];return o(n)?(n._center=r.clone(a,n._center),n._ellipsoid=l.clone(u,n._ellipsoid),n._vertexFormat=I.clone(s,n._vertexFormat),n._semiMajorAxis=f,n._semiMinorAxis=d,n._rotation=h,n._stRotation=E,n._height=m,n._granularity=p,n._extrudedHeight=y,n._extrude=_,n._shadowVolume=T,n._rectangle=S.clone(c),n):(oe.height=m,oe.extrudedHeight=y,oe.granularity=p,oe.stRotation=E,oe.rotation=h,oe.semiMajorAxis=f,oe.semiMinorAxis=d,oe.shadowVolume=T,new D(oe))},D.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,vertexFormat:e._vertexFormat,stRotation:e._stRotation};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),r.shadowVolume=e._shadowVolume,t=C(r)):t=w(r),new d({attributes:t.attributes,indices:t.indices,primitiveType:v.TRIANGLES,boundingSphere:t.boundingSphere})}},D.createShadowVolume=function(e,t,r){var n=e._granularity,a=e._ellipsoid,i=t(n,a),o=r(n,a);return new D({center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:a,rotation:e._rotation,stRotation:e._stRotation,granularity:n,extrudedHeight:i,height:o,vertexFormat:I.POSITION_ONLY,shadowVolume:!0})},u(D.prototype,{rectangle:{get:function(){return this._rectangle}}}),D}),define("Workers/createEllipseGeometry",["../Core/Cartesian3","../Core/defined","../Core/EllipseGeometry","../Core/Ellipsoid"],function(e,t,r,n){"use strict";function a(a,i){return t(i)&&(a=r.unpack(a,i)),a._center=e.clone(a._center),a._ellipsoid=n.clone(a._ellipsoid),r.createGeometry(a)}return a})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(n,i){if(!e(i))throw new t(r(n))},i.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},i.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},i.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},i.typeOf.number.lessThan=function(e,r,n){if(i.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},i.typeOf.number.lessThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},i.typeOf.number.greaterThan=function(e,r,n){if(i.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},i.typeOf.number.greaterThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},i.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},i.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},i.typeOf.number.equals=function(e,r,n,a){if(i.typeOf.number(e,n),i.typeOf.number(r,a),n!==a)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*i.clamp(e,-1,1)+.5)*r)},i.fromSNorm=function(e,r){return r=t(r,255),i.clamp(e,0,r)/r*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,r){return(1-r)*e+r*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,r,n,i){i=t(i,n);var a=Math.abs(e-r);return a<=i||a<=n*Math.max(Math.abs(e),Math.abs(r))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var r=a[t-1],n=t;n<=e;n++)a.push(r*n);return a[e]},i.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return n.x=s*Math.cos(i),n.y=s*Math.sin(i),n.z=u*Math.cos(a),n},o.fromElements=function(e,t,n,i){return r(i)?(i.x=e,i.y=t,i.z=n,i):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var i=0;i<n;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var i=0;i<n;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)},o.cross=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-n*s,f=n*u-i*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,r,n,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,i,a,u){i=t(i,0);var s=r(a)?a.radiiSquared:p,c=Math.cos(n);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(n),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),r(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function i(r,i,u,s,c){var l=r.x,f=r.y,h=r.z,d=i.x,p=i.y,m=i.z,E=l*l*d*d,y=f*f*p*p,_=h*h*m*m,T=E+y+_,v=Math.sqrt(1/T),R=e.multiplyByScalar(r,v,a);if(T<s)return isFinite(v)?e.clone(R,c):void 0;var A=u.x,S=u.y,g=u.z,N=o;N.x=R.x*A*2,N.y=R.y*S*2,N.z=R.z*g*2;var I,O,w,M,x,C,P,D,U,b,L,F=(1-v)*e.magnitude(r)/(.5*e.magnitude(N)),B=0;do{F-=B,w=1/(1+F*A),M=1/(1+F*S),x=1/(1+F*g),C=w*w,P=M*M,D=x*x,U=C*w,b=P*M,L=D*x,I=E*C+y*P+_*D-1,O=E*U*A+y*b*S+_*L*g;B=I/(-2*O)}while(Math.abs(I)>n.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=h*x,c):new e(l*w,f*M,h*x)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,i,a){return i=r(i,0),n(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,r,n){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,r,i){var p=n(r)?r.oneOverRadii:f,m=n(r)?r.oneOverRadiiSquared:h,E=n(r)?r._centerToleranceSquared:d,y=o(t,p,m,E,c);if(n(y)){var _=e.multiplyComponents(y,m,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),v=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=a.sign(e.dot(T,t))*e.magnitude(T);return n(i)?(i.longitude=v,i.latitude=R,i.height=A,i):new u(v,R,A)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t,r,i,a){r=n(r,0),i=n(i,0),a=n(a,0),t._radii=new e(r,i,a),t._radiiSquared=new e(r*r,i*i,a*a),t._radiiToTheFourth=new e(r*r*r*r,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===r?0:1/r,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(r,i,a),t._maximumRadius=Math.max(r,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(i(t)){var n=t._radii;return i(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,i){return i=n(i,0),e.pack(t._radii,r,i),r},f.unpack=function(t,r,i){r=n(r,0);var a=e.unpack(t,r);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(a);return i(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return i(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,r){var n=h,a=d;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,a);var o=Math.sqrt(e.dot(n,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(n,t.height,n),i(r)||(r=new e),e.add(a,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var p=new e,m=new e,E=new e;return f.prototype.cartesianToCartographic=function(r,n){var a=this.scaleToGeodeticSurface(r,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(r,a,E),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return i(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){i(r)||(r=new e);var n=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,a){r=n(r,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-r))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,i,a,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return n(r)?(r.x=a,r.y=o,r.z=u,r):new e(a,o,u)},u.prototype.unproject=function(e,r){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return n(r)?(r.longitude=a,r.latitude=o,r.height=u,r):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i,a,o,u,s,c){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(a,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(m[r],p[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],p[a])]);o>n&&(i=a,n=o)}var c=1,l=0,f=p[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>r){var d,E=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],T=(E-y)/2/_;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=r-u-f+d,m=2*(i-h),E=2*(a+l),y=2*(i+h),_=-r+u-f+d,T=2*(c-o),v=2*(a-l),R=2*(c+o),A=-r-u+f+d;return n(t)?(t[0]=p,t[1]=y,t[2]=v,t[3]=m,t[4]=_,t[5]=R,t[6]=E,t[7]=T,t[8]=A,t):new s(p,m,E,y,_,T,v,R,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=r*u,p=a*i+c*o*u,m=-c*i+a*o*u,E=-o,y=c*r,_=a*r;return n(t)?(t[0]=l,t[1]=d,t[2]=E,t[3]=f,t[4]=p,t[5]=y,t[6]=h,t[7]=m,t[8]=_,t):new s(l,f,h,d,p,m,E,y,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=i,t[6]=0,t[7]=-i,t[8]=r,t):new s(1,0,0,0,r,-i,0,i,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=r,t):new s(r,0,i,0,1,0,-i,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=i,t[2]=0,t[3]=-i,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-i,0,i,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,i=e[n],a=e[n+1],o=e[n+2];return r.x=i,r.y=a,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var i=3*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],i=e[t+3],a=e[t+6];return r.x=n,r.y=i,r.z=a,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var h=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=i,r[2]=a,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[3]*i+e[6]*a,u=e[1]*n+e[4]*i+e[7]*a,s=e[2]*n+e[5]*i+e[8]*a;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],m=[2,2,1],E=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,i=0,a=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=r*c(h);a<10&&l(h)>d;)f(h,E),s.transpose(E,y),s.multiply(h,E,h),s.multiply(y,h,h),s.multiply(o,E,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*n-r*c)+u*(r*o-a*n)},s.inverse=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-n*f,t[2]=n*u-o*i,t[3]=c*u-a*f,t[4]=r*f-c*i,t[5]=a*i-r*u,t[6]=a*l-c*o,t[7]=c*n-r*l,t[8]=r*o-a*n;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n,i){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(i,0)}o.fromElements=function(e,t,n,i,a){return r(a)?(a.x=e,a.y=t,a.z=n,a.w=i,a):new o(e,t,n,i)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n++],i.w=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var i=0;i<n;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var i=0;i<n;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)&&a.equalsEpsilon(e.w,t.w,n,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t,r,i,a,o,u,s,c,l,f,h,d,p,m,E){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(c,0),this[3]=n(d,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(p,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(m,0),this[12]=n(i,0),this[13]=n(s,0),this[14]=n(h,0),this[15]=n(E,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,a){return r=n(r,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=r.x,a[13]=r.y,a[14]=r.z,a[15]=1,a):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){i(n)||(n=new l);var a=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,m=t.y*t.w,E=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-d-E+_,v=2*(c-y),R=2*(f+m),A=2*(c+y),S=-s+d-E+_,g=2*(p-h),N=2*(f-m),I=2*(p+h),O=-s-d+E+_;return n[0]=T*a,n[1]=A*a,n[2]=N*a,n[3]=0,n[4]=v*o,n[5]=S*o,n[6]=I*o,n[7]=0,n[8]=R*u,n[9]=g*u,n[10]=O*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,r){var n=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,m=f.y,E=f.z,y=d.x,_=d.y,T=d.z,v=n.x,R=n.y,A=n.z,S=u*-v+s*-R+c*-A,g=y*-v+_*-R+T*-A,N=p*v+m*R+E*A;return i(r)?(r[0]=u,r[1]=y,r[2]=-p,r[3]=0,r[4]=s,r[5]=_,r[6]=-m,r[7]=0,r[8]=c,r[9]=T,r[10]=-E,r[11]=0,r[12]=S,r[13]=g,r[14]=N,r[15]=1,r):new l(u,s,c,S,y,_,T,g,-p,-m,-E,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,r,n,i,a,o){var u=1/(t-e),s=1/(n-r),c=1/(a-i),l=-(t+e)*u,f=-(n+r)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,i,a,o){var u=2*i/(t-e),s=2*i/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,i,a){var o=2*i/(t-e),u=2*i/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,r,i){e=n(e,n.EMPTY_OBJECT);var a=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),h=c,d=l,p=f,m=a+c,E=o+l,y=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=m,i[13]=E,i[14]=y,i[15]=1,i},l.computeView=function(t,r,n,i,a){return a[0]=i.x,a[1]=n.x,a[2]=-r.x,a[3]=0,a[4]=i.y,a[5]=n.y,a[6]=-r.y,a[7]=0,a[8]=i.z,a[9]=n.z,a[10]=-r.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(n,t),a[14]=e.dot(r,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3];return r.x=i,r.y=a,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var i=4*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n[i+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return r.x=n,r.y=i,r.z=a,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var p=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),r};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],m=e[12],E=e[13],y=e[14],_=e[15],T=t[0],v=t[1],R=t[2],A=t[3],S=t[4],g=t[5],N=t[6],I=t[7],O=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],D=t[14],U=t[15],b=n*T+u*v+f*R+m*A,L=i*T+s*v+h*R+E*A,F=a*T+c*v+d*R+y*A,B=o*T+l*v+p*R+_*A,z=n*S+u*g+f*N+m*I,q=i*S+s*g+h*N+E*I,G=a*S+c*g+d*N+y*I,V=o*S+l*g+p*N+_*I,X=n*O+u*w+f*M+m*x,W=i*O+s*w+h*M+E*x,H=a*O+c*w+d*M+y*x,Y=o*O+l*w+p*M+_*x,k=n*C+u*P+f*D+m*U,j=i*C+s*P+h*D+E*U,Z=a*C+c*P+d*D+y*U,K=o*C+l*P+p*D+_*U;return r[0]=b,r[1]=L,r[2]=F,r[3]=B,r[4]=z,r[5]=q,r[6]=G,r[7]=V,r[8]=X,r[9]=W,r[10]=H,r[11]=Y,r[12]=k,r[13]=j,r[14]=Z,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],m=t[0],E=t[1],y=t[2],_=t[4],T=t[5],v=t[6],R=t[8],A=t[9],S=t[10],g=t[12],N=t[13],I=t[14],O=n*m+o*E+c*y,w=i*m+u*E+l*y,M=a*m+s*E+f*y,x=n*_+o*T+c*v,C=i*_+u*T+l*v,P=a*_+s*T+f*v,D=n*R+o*A+c*S,U=i*R+u*A+l*S,b=a*R+s*A+f*S,L=n*g+o*N+c*I+h,F=i*g+u*N+l*I+d,B=a*g+s*N+f*I+p;return r[0]=O,r[1]=w,r[2]=M,r[3]=0,r[4]=x,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=U,r[10]=b,r[11]=0,r[12]=L,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],m=t[3],E=t[4],y=t[5],_=t[6],T=t[7],v=t[8],R=n*h+o*d+c*p,A=i*h+u*d+l*p,S=a*h+s*d+f*p,g=n*m+o*E+c*y,N=i*m+u*E+l*y,I=a*m+s*E+f*y,O=n*_+o*T+c*v,w=i*_+u*T+l*v,M=a*_+s*T+f*v;return r[0]=R,r[1]=A,r[2]=S,r[3]=0,r[4]=g,r[5]=N,r[6]=I,r[7]=0,r[8]=O,r[9]=w,r[10]=M,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=n*e[0]+i*e[4]+a*e[8]+e[12],u=n*e[1]+i*e[5]+a*e[9]+e[13],s=n*e[2]+i*e[6]+a*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var E=new e;l.multiplyByUniformScale=function(e,t,r){return E.x=t,E.y=t,E.z=t,l.multiplyByScale(e,E,r)},l.multiplyByScale=function(e,t,r){var n=t.x,i=t.y,a=t.z;return 1===n&&1===i&&1===a?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=i*e[4],r[5]=i*e[5],r[6]=i*e[6],r[7]=0,r[8]=a*e[8],r[9]=a*e[9],r[10]=a*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*n+e[4]*i+e[8]*a+e[12]*o,s=e[1]*n+e[5]*i+e[9]*a+e[13]*o,c=e[2]*n+e[6]*i+e[10]*a+e[14]*o,l=e[3]*n+e[7]*i+e[11]*a+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a,u=e[1]*n+e[5]*i+e[9]*a,s=e[2]*n+e[6]*i+e[10]*a;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a+e[12],u=e[1]*n+e[5]*i+e[9]*a+e[13],s=e[2]*n+e[6]*i+e[10]*a+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,v=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),v))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],m=e[2],E=e[6],R=e[10],A=e[14],S=e[3],g=e[7],N=e[11],I=e[15],O=R*I,w=A*N,M=E*I,x=A*g,C=E*N,P=R*g,D=m*I,U=A*S,b=m*N,L=R*S,F=m*g,B=E*S,z=O*h+x*d+C*p-(w*h+M*d+P*p),q=w*f+D*d+L*p-(O*f+U*d+b*p),G=M*f+U*h+F*p-(x*f+D*h+B*p),V=P*f+b*h+B*d-(C*f+L*h+F*d),X=w*i+M*a+P*o-(O*i+x*a+C*o),W=O*n+U*a+b*o-(w*n+D*a+L*o),H=x*n+D*i+B*o-(M*n+U*i+F*o),Y=C*n+L*i+F*a-(P*n+b*i+B*a);O=a*p,w=o*d,M=i*p,x=o*h,C=i*d,P=a*h,D=n*p,U=o*f,b=n*d,L=a*f,F=n*h,B=i*f;var k=O*g+x*N+C*I-(w*g+M*N+P*I),j=w*S+D*N+L*I-(O*S+U*N+b*I),Z=M*S+U*g+F*I-(x*S+D*g+B*I),K=P*S+b*g+B*N-(C*S+L*g+F*N),J=M*R+P*A+w*E-(C*A+O*E+x*R),Q=b*A+O*m+U*R-(D*R+L*A+w*m),$=D*E+B*A+x*m-(F*A+M*m+U*E),ee=F*R+C*m+L*E-(b*E+B*R+P*m),te=n*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=q*te,r[2]=G*te,r[3]=V*te,r[4]=X*te,r[5]=W*te,r[6]=H*te,r[7]=Y*te,r[8]=k*te,r[9]=j*te,r[10]=Z*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-r*f-n*h-i*d,m=-a*f-o*h-u*d,E=-s*f-c*h-l*d;return t[0]=r,t[1]=a,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=m,t[14]=E,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),i=u.toRadians(r(i,0)),a=u.toRadians(r(a,0)),n(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(i,0),o.north=r(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];r=Math.min(r,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-r>o-a&&(r=a,i=o,i>u.PI&&(i-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=i,t.north=l,t):new s(r,c,i,l)},s.fromCartesianArray=function(e,t,i){t=r(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,m=e.length;p<m;p++){var E=t.cartesianToCartographic(e[p]);o=Math.min(o,E.longitude),c=Math.max(c,E.longitude),h=Math.min(h,E.latitude),d=Math.max(d,E.latitude);var y=E.longitude>=0?E.longitude:E.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return n(r)?(r.west=l,r.south=h,r.east=f,r.north=d,r):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,r){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return n(r)?(r.west=i,r.south=a,r.east=o,r.north=u,r):new s(i,a,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>i||u.equalsEpsilon(r,i,u.EPSILON14))&&(r<a||u.equalsEpsilon(r,a,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=r(t,a.WGS84),i=r(i,0),n(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,m=c;m.height=i,m.longitude=p,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var E=1;E<8;++E)m.longitude=-Math.PI+E*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";function d(t,r){this.center=e.clone(i(t,e.ZERO)),this.radius=i(r,0)}var p=new e,m=new e,E=new e,y=new e,_=new e,T=new e,v=new e,R=new e,A=new e,S=new e,g=new e,N=new e,I=4/3*r.PI;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],v),o=e.clone(i,p),u=e.clone(i,m),s=e.clone(i,E),c=e.clone(i,y),l=e.clone(i,_),f=e.clone(i,T),h=t.length;for(n=1;n<h;n++){e.clone(t[n],i);var I=i.x,O=i.y,w=i.z;I<o.x&&e.clone(i,o),I>c.x&&e.clone(i,c),O<u.y&&e.clone(i,u),O>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,U=M;x>U&&(U=x,P=u,D=l),C>U&&(U=C,P=s,D=f);var b=A;b.x=.5*(P.x+D.x),b.y=.5*(P.y+D.y),b.z=.5*(P.z+D.z);var L=e.magnitudeSquared(e.subtract(D,b,R)),F=Math.sqrt(L),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,R),.5,N),G=0;for(n=0;n<h;n++){e.clone(t[n],i);var V=e.magnitude(e.subtract(i,q,R));V>G&&(G=V);var X=e.magnitudeSquared(e.subtract(i,b,R));if(X>L){var W=Math.sqrt(X);F=.5*(F+W),L=F*F;var H=W-F;b.x=(F*b.x+H*i.x)/W,b.y=(F*b.y+H*i.y)/W,b.z=(F*b.z+H*i.z)/W}}return F<G?(e.clone(b,r.center),r.radius=F):(e.clone(q,r.center),r.radius=G),r};var O=new u,w=new e,M=new e,x=new t,C=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,n,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=i(r,O),h.southwest(t,x),x.height=n,h.northeast(t,C),C.height=o;var s=r.project(x,w),c=r.project(C,M),l=c.x-s.x,f=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+p*p);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*p,u};var P=[];d.fromRectangle3D=function(t,r,n,u){if(r=i(r,o.WGS84),n=i(n,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,r,n,P);return d.fromPoints(s,u)},d.fromVertices=function(t,r,n,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=i(r,e.ZERO),n=i(n,3);var u=v;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,p),l=e.clone(u,m),f=e.clone(u,E),h=e.clone(u,y),I=e.clone(u,_),O=e.clone(u,T),w=t.length;for(s=0;s<w;s+=n){var M=t[s]+r.x,x=t[s+1]+r.y,C=t[s+2]+r.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>h.x&&e.clone(u,h),x<l.y&&e.clone(u,l),x>I.y&&e.clone(u,I),C<f.z&&e.clone(u,f),C>O.z&&e.clone(u,O)}var P=e.magnitudeSquared(e.subtract(h,c,R)),D=e.magnitudeSquared(e.subtract(I,l,R)),U=e.magnitudeSquared(e.subtract(O,f,R)),b=c,L=h,F=P;D>F&&(F=D,b=l,L=I),U>F&&(F=U,b=f,L=O);var B=A;B.x=.5*(b.x+L.x),B.y=.5*(b.y+L.y),B.z=.5*(b.z+L.z);var z=e.magnitudeSquared(e.subtract(L,B,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=I.y,V.z=O.z;var X=e.multiplyByScalar(e.add(G,V,R),.5,N),W=0;for(s=0;s<w;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,X,R));H>W&&(W=H);var Y=e.magnitudeSquared(e.subtract(u,B,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;B.x=(q*B.x+j*u.x)/k,B.y=(q*B.y+j*u.y)/k,B.z=(q*B.z+j*u.z)/k}}return q<W?(e.clone(B,o.center),o.radius=q):(e.clone(X,o.center),o.radius=W),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=v;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,p),s=e.clone(i,m),c=e.clone(i,E),l=e.clone(i,y),f=e.clone(i,_),h=e.clone(i,T),I=t.length;for(o=0;o<I;o+=3){var O=t[o]+r[o],w=t[o+1]+r[o+1],M=t[o+2]+r[o+2];i.x=O,i.y=w,i.z=M,O<u.x&&e.clone(i,u),O>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>h.z&&e.clone(i,h)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(h,c,R)),D=u,U=l,b=x;C>b&&(b=C,D=s,U=f),P>b&&(b=P,D=c,U=h);var L=A;L.x=.5*(D.x+U.x),L.y=.5*(D.y+U.y),L.z=.5*(D.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,N),V=0;for(o=0;o<I;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(i,G,R));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(i,L,R));if(W>F){var H=Math.sqrt(W);B=.5*(B+H),F=B*B;var Y=H-B;L.x=(B*L.x+Y*i.x)/H,L.y=(B*L.y+Y*i.y)/H,L.z=(B*L.z+Y*i.z)/H}}return B<V?(e.clone(L,n.center),n.radius=B):(e.clone(G,n.center),n.radius=V),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var D=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,D)+c.radius)}return r.radius=s,r};var U=new e,b=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=l.getColumn(n,0,U),o=l.getColumn(n,1,b),u=l.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=i(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=i(t,0),a(r)||(r=new d);var n=r.center;return n.x=e[t++],n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var F=new e,B=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,F),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var z=new e;d.expand=function(t,r,n){n=d.clone(t,n);var i=e.magnitude(e.subtract(r,n.center,z));return i>n.radius&&(n.radius=i),n},d.intersectPlane=function(t,r){var n=t.center,i=t.radius,a=r.normal,o=e.dot(a,n)+r.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=f.getMaximumScale(t)*e.radius,r};var q=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,q);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var G=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new c);var o=e.subtract(t.center,r,G),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,X=new e,W=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,r,n){r=i(r,K);var a=r.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),p=j,m=p[0];e.add(s,l,m),e.add(m,c,m),m=p[1],e.add(s,l,m),e.add(m,h,m),m=p[2],e.add(s,f,m),e.add(m,h,m),m=p[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=p[4],e.add(s,l,m),e.add(m,c,m),m=p[5],e.add(s,l,m),e.add(m,h,m),m=p[6],e.add(s,f,m),e.add(m,h,m),m=p[7],e.add(s,f,m),e.add(m,c,m);for(var E=p.length,y=0;y<E;++y){var _=p[y];e.add(o,_,_);var T=a.cartesianToCartographic(_,k);r.project(T,_)}n=d.fromPoints(p,n),o=n.center;var v=o.x,R=o.y,A=o.z;return o.x=A,o.y=v,o.z=R,n},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return I*e*e*e},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var i=0;i<n;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var i=0;i<n;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)), +o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(n.requestFullscreen=i,r=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(n.requestFullscreen=i,r=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?n.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(n.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?n.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(n.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?n.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(n.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),n.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),n.fullscreenerror=i)}return r},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[n.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(R=!0,A=n(e[1]))}return R}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(v.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(S=!0,g=n(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(v.userAgent);null!==e&&(N=!0,I=n(e[1]),I.isNightly=!!e[2])}return N}function c(){return s()&&I}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===v.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(v.userAgent))&&(O=!0,w=n(e[1])):"Netscape"===v.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(v.userAgent))&&(O=!0,w=n(e[1]))}return O}function f(){return l()&&w}function h(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(M=!0,x=n(e[1]))}return M}function d(){return h()&&x}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(v.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(v.appVersion)),D}function E(){return p()&&P}function y(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(v.pointerEnabled)||v.pointerEnabled)),U}function _(){if(!t(L)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;L=t(r)&&""!==r,L&&(b=r)}return L}function T(){return _()?b:void 0}var v;v="undefined"!=typeof navigator?navigator:{};var R,A,S,g,N,I,O,w,M,x,C,P,D,U,b,L,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:E,isWindows:m,hardwareConcurrency:e(v.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,i,a){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,i){switch(n=e(n,0),i=e(i,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,i);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,i);case o.SHORT:return new Int16Array(r,n,i);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,i);case o.INT:return new Int32Array(r,n,i);case o.UNSIGNED_INT:return new Uint32Array(r,n,i);case o.FLOAT:return new Float32Array(r,n,i);case o.DOUBLE:return new Float64Array(r,n,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(i,0)}var c=new e;s.fromAxisAngle=function(t,r,i){var a=r/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return n(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],m=h+d+p;if(m>0)r=Math.sqrt(m+1),c=.5*r,r=.5/r,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var E=l,y=0;d>h&&(y=1),p>h&&p>d&&(y=2);var _=E[y],T=E[_];r=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var v=f;v[y]=.5*r,r=.5/r,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*r,v[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*r,v[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*r,i=-v[0],a=-v[1],o=-v[2]}return n(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,m=new s;s.fromHeadingPitchRoll=function(t,r){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(p,m,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,r,r)};var E=new e,y=new e,_=new s,T=new s,v=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,v),s.conjugate(v,v);for(var i=0,a=r-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,v,_),_.w<0&&s.negate(_,_),s.computeAxis(_,E);var u=s.computeAngle(_);n[o]=E.x*u,n[o+1]=E.y*u,n[o+2]=E.z*u}},s.unpackInterpolationResult=function(t,r,i,a,o){n(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(r,4*a,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,i=e.y*r,a=e.z*r,o=e.w*r;return t.x=n,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+i*c-a*s,h=o*s-n*c+i*l+a*u,d=o*c+n*s-i*u+a*l,p=o*l-n*u-i*s-a*c;return r.x=f,r.y=h,r.z=d,r.w=p,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,r,n){return R=s.multiplyByScalar(t,r,R),n=s.multiplyByScalar(e,1-r,n),s.add(R,n,n)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,r,n){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,r,n);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-r)*u),S),g=s.multiplyByScalar(a,Math.sin(r*u),g),n=s.add(S,g,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),i=0;return 0!==n&&(i=n/Math.sin(n)),e.multiplyByScalar(t,i,r)},s.exp=function(t,r){var n=e.magnitude(t),i=0;return 0!==n&&(i=Math.sin(n)/n),r.x=t.x*i,r.y=t.y*i,r.z=t.z*i,r.w=Math.cos(n),r};var N=new e,I=new e,O=new s,w=new s;s.computeInnerQuadrangle=function(t,r,n,i){var a=s.conjugate(r,O);s.multiply(a,n,w);var o=s.log(w,N);s.multiply(a,t,w);var u=s.log(w,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,O),s.multiply(r,O,i)},s.squad=function(e,t,r,n,i,a){var o=s.slerp(e,t,i,O),u=s.slerp(r,n,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var M=new s,x=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],b=0;b<7;++b){var L=b+1,F=2*L+1;C[b]=1/(L*F),P[b]=L/F}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,r,n){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,U[f]=(C[f]*l-P[f])*o;var h=i*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),p=s.multiplyByScalar(e,d,M);return s.multiplyByScalar(t,h,n),s.add(p,n,n)},s.fastSquad=function(e,t,r,n,i,a){var o=s.fastSlerp(e,t,i,O),u=s.fastSlerp(r,n,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,r,n){"use strict";function i(t,i,a,l,f,h,d,p,m,E){var y=t+i;e.multiplyByScalar(l,Math.cos(y),o),e.multiplyByScalar(a,Math.sin(y),u),e.add(o,u,o);var _=Math.cos(t);_*=_;var T=Math.sin(t);T*=T;var v=h/Math.sqrt(d*_+f*T),R=v/p;return n.fromAxisAngle(o,R,s),r.fromQuaternion(s,c),r.multiplyByVector(c,m,E),e.normalize(E,E),e.multiplyByScalar(E,p,E),E}var a={},o=new e,u=new e,s=new n,c=new r,l=new e,f=new e,h=new e,d=new e;a.raisePositionsToHeight=function(t,r,n){for(var i=r.ellipsoid,a=r.height,o=r.extrudedHeight,u=n?t.length/3*2:t.length/3,s=new Float64Array(3*u),c=t.length,p=n?c:0,m=0;m<c;m+=3){var E=m+1,y=m+2,_=e.fromArray(t,m,l);i.scaleToGeodeticSurface(_,_);var T=e.clone(_,f),v=i.geodeticSurfaceNormal(_,d),R=e.multiplyByScalar(v,a,h);e.add(_,R,_),n&&(e.multiplyByScalar(v,o,R),e.add(T,R,T),s[m+p]=T.x,s[E+p]=T.y,s[y+p]=T.z),s[m]=_.x,s[E]=_.y,s[y]=_.z}return s};var p=new e,m=new e,E=new e;return a.computeEllipsePositions=function(r,n,a){var o=r.semiMinorAxis,u=r.semiMajorAxis,s=r.rotation,c=r.center,d=8*r.granularity,y=o*o,_=u*u,T=u*o,v=e.magnitude(c),R=e.normalize(c,p),A=e.cross(e.UNIT_Z,c,m);A=e.normalize(A,A);var S=e.cross(R,A,E),g=1+Math.ceil(t.PI_OVER_TWO/d),N=t.PI_OVER_TWO/(g-1),I=t.PI_OVER_TWO-g*N;I<0&&(g-=Math.ceil(Math.abs(I)/N));var O,w,M,x,C,P=g*(g+2)*2,D=n?new Array(3*P):void 0,U=0,b=l,L=f,F=4*g*3,B=F-1,z=0,q=a?new Array(F):void 0;for(I=t.PI_OVER_TWO,b=i(I,s,S,A,y,T,_,v,R,b),n&&(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z),a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x),I=t.PI_OVER_TWO-N,O=1;O<g+1;++O){if(b=i(I,s,S,A,y,T,_,v,R,b),L=i(Math.PI-I,s,S,A,y,T,_,v,R,L),n){for(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z,M=2*O+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(b,L,x,h),D[U++]=C.x,D[U++]=C.y,D[U++]=C.z;D[U++]=L.x,D[U++]=L.y,D[U++]=L.z}a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x,q[z++]=L.x,q[z++]=L.y,q[z++]=L.z),I=t.PI_OVER_TWO-(O+1)*N}for(O=g;O>1;--O){if(I=t.PI_OVER_TWO-(O-1)*N,b=i(-I,s,S,A,y,T,_,v,R,b),L=i(I+Math.PI,s,S,A,y,T,_,v,R,L),n){for(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z,M=2*(O-1)+2,w=1;w<M-1;++w)x=w/(M-1),C=e.lerp(b,L,x,h),D[U++]=C.x,D[U++]=C.y,D[U++]=C.z;D[U++]=L.x,D[U++]=L.y,D[U++]=L.z}a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x,q[z++]=L.x,q[z++]=L.y,q[z++]=L.z)}I=t.PI_OVER_TWO,b=i(-I,s,S,A,y,T,_,v,R,b);var G={};return n&&(D[U++]=b.x,D[U++]=b.y,D[U++]=b.z,G.positions=D,G.numPts=g),a&&(q[B--]=b.z,q[B--]=b.y,q[B--]=b.x,G.outerPositions=q),G},a}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var i=e.attributes[n],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return i}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)}, +u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),i=256*(r-n);return u.octDecode(n,i,t)},u.octPack=function(e,t,r,n){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+i,n.y=65536*o.y+a,n},u.octUnpack=function(e,t,r,n){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(a,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function i(r,i,s,c,l){n(l)||(l=new t);var f,h,d,p,m,E,y,_;n(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(r,i,u),p=t.dot(f,f),m=t.dot(f,h),E=t.dot(f,d),y=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(r,i,u),p=e.dot(f,f),m=e.dot(f,h),E=e.dot(f,d),y=e.dot(h,h),_=e.dot(h,d));var T=1/(p*y-m*m);return l.y=(y*E-m*_)*T,l.z=(p*_-m*E)*T,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var i={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var a=t.high,o=t.low;return n.encode(e.x,i),a.x=i.high,o.x=i.low,n.encode(e.y,i),a.y=i.high,o.y=i.low,n.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,a);var i=a.high,o=a.low;t[r]=i.x,t[r+1]=i.y,t[r+2]=i.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,r,i){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,i):new Uint16Array(t,r,i)},r(a)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var i=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(r)))<n?0:i}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,i){var a;if(0===e)return 0===n?[]:[-i/n];if(0===n){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-n/e,a<0?[a,0]:[0,a];var c=n*n,l=4*e*i,f=r(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[h/e,i/h]:[i/h,h/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var i,a,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,m=o*c-u*s,E=u*c-d,y=4*p*E-m*m;if(y<0){var _,T,v;h*f>=l*d?(_=o,T=p,v=-2*u*p+o*m):(_=c,T=E,v=-c*m+2*s*E);var R=v<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-y);a=-v+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),N=a===A?-g:-T/g;return i=T<=0?g+N:-v/(g*g+N*N+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var I=p,O=-2*u*p+o*m,w=E,M=-c*m+2*s*E,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-O)/3);i=2*Math.sqrt(-I);var D=Math.cos(P);a=i*D;var U=i*(-D/2-C*Math.sin(P)),b=a+U>2*u?a-u:U-u,L=o,F=b/L;P=Math.abs(Math.atan2(c*x,-M)/3),i=2*Math.sqrt(-w),D=Math.cos(P),a=i*D,U=i*(-D/2-C*Math.sin(P));var B=-c,z=a+U<2*s?a+s:U+s,q=B/z,G=L*z,V=-b*z-L*B,X=b*B,W=(s*V-u*X)/(-u*V+s*G);return F<=W?F<=q?W<=q?[F,W,q]:[F,q,W]:[q,F,W]:F<=q?[W,F,q]:W<=q?[W,q,F]:[q,W,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var i=e*e,a=t*t,o=r*r;return 18*e*t*r*n+a*o-27*i*(n*n)-4*(e*o*r+a*t*n)},n.computeRealRoots=function(e,n,i,a){var o,u;if(0===e)return t.computeRealRoots(n,i,a);if(0===n){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,i,a)}return 0===i?0===a?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,a):0===a?(o=t.computeRealRoots(e,n,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,i,a)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<r.EPSILON14){var p=n.computeRealRoots(1,s,l);if(2===p.length){var m,E=p[0],y=p[1];if(E>=0&&y>=0){var _=Math.sqrt(E),T=Math.sqrt(y);return[h-T,h-_,h+_,h+T]}if(E>=0&&y<0)return m=Math.sqrt(E),[h-m,h+m];if(E<0&&y>=0)return m=Math.sqrt(y),[h-m,h+m]}return[]}if(d>0){var v=Math.sqrt(d),R=(s+d-c/v)/2,A=(s+d+c/v)/2,S=n.computeRealRoots(1,v,R),g=n.computeRealRoots(1,-v,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,m,E=d[0],y=i-E,_=y*y,T=t/2,v=y/2,R=_-4*o,A=_+4*Math.abs(o),S=c-4*E,g=c+4*Math.abs(E);if(E<0||R*g<S*A){var N=Math.sqrt(S);p=N/2,m=0===N?0:(t*v-a)/N}else{var I=Math.sqrt(R);p=0===I?0:(t*v-a)/I,m=I/2}var O,w;0===T&&0===p?(O=0,w=0):r.sign(T)===r.sign(p)?(O=T+p,w=E/O):(w=T-p,O=E/w);var M,x;0===v&&0===m?(M=0,x=0):r.sign(v)===r.sign(m)?(M=v+m,x=o/M):(x=v-m,M=o/x);var C=n.computeRealRoots(1,O,M),P=n.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,h=f*n,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*r*h-27*a*f*f+256*o*(d*i)+i*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*a*r*f)+d*(144*e*u*r-27*u*u-128*a*c-192*a*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return i.getPoint=function(t,n,i){return r(i)||(i=new e),i=e.multiplyByScalar(t.direction,n,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,i,a,o,u,s,c,l){"use strict";function f(e,t,r,n){var i=t*t-4*e*r;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function h(t,r,i){n(i)||(i=new a);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,m=f(h,d,p,A);if(n(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function p(t,r,n,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),E=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*r.x+n,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(p,m,E),0===l.length)return T;var v=l[0],R=Math.sqrt(Math.max(1-v*v,0));if(T.push(new e(i,a*v,a*-R)),T.push(new e(i,a*v,a*R)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(i,a*A,a*-S)),T.push(new e(i,a*A,a*S))}return T}var g=_*_,N=y*y,I=p*p,O=_*y,w=I+N,M=2*(m*p+O),x=2*E*p+m*m-N+g,C=2*(E*m-O),P=E*E-g;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var D=l.length;if(0===D)return T;for(var U=0;U<D;++U){var b,L=l[U],F=L*L,B=Math.max(1-F,0),z=Math.sqrt(B);b=o.sign(p)===o.sign(E)?d(p*F+E,m*L,o.EPSILON12):o.sign(E)===o.sign(m*L)?d(p*F,m*L+E,o.EPSILON12):d(p*F+m*L,E,o.EPSILON12);var q=d(y*L,_,o.EPSILON15),G=b*q;G<0?T.push(new e(i,a*L,a*z)):G>0?T.push(new e(i,a*L,a*-z)):0!==z?(T.push(new e(i,a*L,a*-z)),T.push(new e(i,a*L,a*z)),++U):T.push(new e(i,a*L,a*z))}return T}var m={};m.rayPlane=function(t,r,i){n(i)||(i=new e);var a=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var E=new e,y=new e,_=new e,T=new e,v=new e;m.rayTriangleParametric=function(t,n,i,a,u){u=r(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,m=e.subtract(i,n,E),R=e.subtract(a,n,y),A=e.cross(p,R,_),S=e.dot(m,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,n,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,m,v),(f=e.dot(p,c))<0||l+f>S)return;h=e.dot(R,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,n,T),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,m,v),(f=e.dot(p,c)*g)<0||l+f>1)return;h=e.dot(R,c)*g}return h},m.rayTriangle=function(t,r,i,a,o,u){var s=m.rayTriangleParametric(t,r,i,a,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;m.lineSegmentTriangle=function(t,r,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=h(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;m.lineSegmentSphere=function(t,r,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!n(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;m.rayEllipsoid=function(t,r){var n,i,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(n=h-1,i=e.magnitudeSquared(f),o=i*n,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,E=n/s;return m<E?new a(m,E):{start:E,stop:m}}var y=Math.sqrt(n/i);return new a(y,y)}return h<1?(n=h-1,i=e.magnitudeSquared(f),o=i*n,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var I=new e,O=new e,w=new e,M=new e,x=new e,C=new u,P=new u,D=new u,U=new u,b=new u,L=new u,F=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,r){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=r.geodeticSurfaceNormal(i,I);if(e.dot(a,s)>=0)return i}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(a,I),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,M),d=e.normalize(e.cross(h,f,O),O),m=e.normalize(e.cross(f,d,w),w),E=C;E[0]=f.x,E[1]=f.y,E[2]=f.z,E[3]=d.x,E[4]=d.y,E[5]=d.z,E[6]=m.x,E[7]=m.y,E[8]=m.z;var y=u.transpose(E,P),_=u.fromScale(r.radii,D),T=u.fromScale(r.oneOverRadii,U),v=b;v[0]=0,v[1]=-a.z,v[2]=a.y,v[3]=a.z,v[4]=0,v[5]=-a.x,v[6]=-a.y,v[7]=a.x,v[8]=0;var R,A,S=u.multiply(u.multiply(y,T,L),v,L),g=u.multiply(u.multiply(S,_,F),E,F),N=u.multiplyByVector(S,i,x),G=p(g,e.negate(N,I),0,0,1),V=G.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){R=u.multiplyByVector(_,u.multiplyByVector(E,G[H],B),B);var Y=e.normalize(e.subtract(R,i,M),M),k=e.dot(Y,a);k>W&&(W=k,X=e.clone(R,X))}var j=r.cartesianToCartographic(X,q);return W=o.clamp(W,0,1),A=e.magnitude(e.subtract(X,i,M))*Math.sqrt(1-W*W),A=c?-A:A,j.height=A,r.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,r,i,a){n(a)||(a=new e);var u=e.subtract(r,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,r,n,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,r)+o<0,c=e.dot(a,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,r,n,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,r,n,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,r,n,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,r,n,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,r,n,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,r,n,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,i,a,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,i){var a=-e.dot(n,t);return r(i)?(e.clone(n,i.normal),i.distance=a,i):new u(n,a)};var s=new e;u.fromCartesian4=function(t,n){var i=e.fromCartesian4(t,s),a=t.w;return r(n)?(e.clone(i,n.normal),n.distance=a,n):new u(i,a)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,i){r(i)||(i=new e);var a=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(n,o,i)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,i=r.maximumIndex,a=e(r.cacheSize,24),o=n.length;if(!t(i)){i=0;for(var u=0,s=n[u];u<o;)s>i&&(i=s),++u,s=n[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[n[h]]>a&&(c[n[h]]=f,++f);return(f-a+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<n;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}r=e(r,e.EMPTY_OBJECT);var i,a=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<h;)p[a[l]].vertexTriangles.push(m),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(m),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(m),++p[a[l+2]].numLiveTriangles,++m,l+=3;var E=0,y=u+1;i=1;var _,T,v=[],R=[],A=0,S=[],g=s/3,N=[];for(d=0;d<g;d++)N[d]=!1;for(var I,O;-1!==E;){v=[],T=p[E],O=T.vertexTriangles.length;for(var w=0;w<O;++w)if(m=T.vertexTriangles[w],!N[m]){N[m]=!0,l=m+m+m;for(var M=0;M<3;++M)I=a[l],v.push(I),R.push(I),S[A]=I,++A,_=p[I],--_.numLiveTriangles,y-_.timeStamp>u&&(_.timeStamp=y,++y),++l}E=function(e,t,r,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var h=r[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?n(i,o,e,u):c}(a,u,v,p,y,R,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T,v,R,A,S,g){"use strict";function N(e,t,r,n,i){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=i,e[t++]=i,e[t]=r}function I(e){for(var t=e.length,r=t/3*6,n=E.createTypedArray(t,r),i=0,a=0;a<t;a+=3,i+=6)N(n,i,e[a],e[a+1],e[a+2]);return n}function O(e){var t=e.length;if(t>=3){var r=6*(t-2),n=E.createTypedArray(t,r);N(n,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)N(n,i,e[a-1],e[a],e[a-2]);return n}return new Uint16Array}function w(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=E.createTypedArray(t,r),i=e[0],a=0,o=1;o<t;++o,a+=6)N(n,a,i,e[o],e[o+1]);return n}return new Uint16Array}function M(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new p({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function x(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var i=t[n],a=0;a<i.componentsPerAttribute;++a)e[n].values.push(i.values[r*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,r,a)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),v.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,r,a)}function D(e,t){var r,n=e.length,i={},a=e[0][t].attributes;for(r in a)if(a.hasOwnProperty(r)&&c(a[r])&&c(a[r].values)){for(var o=a[r],s=o.values.length,l=!0,f=1;f<n;++f){var h=e[f][t].attributes[r];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(i[r]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function U(e,t){var n,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,y=D(e,t);for(n in y)if(y.hasOwnProperty(n))for(s=y[n].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var T=0;for(a=0;a<h;++a)T+=e[a][t].indices.length;var v=d.computeNumberOfVertices(new d({attributes:y,primitiveType:S.POINTS})),R=E.createTypedArray(v,T),A=0,g=0;for(a=0;a<h;++a){var N=e[a][t].indices,I=N.length;for(u=0;u<I;++u)R[A++]=g+N[u];g+=d.computeNumberOfVertices(e[a][t])}_=R}var O,w=new i,M=0;for(a=0;a<h;++a){if(O=e[a][t].boundingSphere,!c(O)){w=void 0;break}i.add(O.center,w,w)}if(c(w))for(i.divideByScalar(w,h,w),a=0;a<h;++a){O=e[a][t].boundingSphere;var x=i.magnitude(i.subtract(O.center,w,se))+O.radius;x>M&&(M=x)}return new d({attributes:y,indices:_,primitiveType:m,boundingSphere:c(w)?new r(w,M):void 0})}function b(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function L(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,i=3;i<t;++i)r[n++]=i-1,r[n++]=0,r[n++]=i;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,i=3;i<t-1;i+=2)r[n++]=i,r[n++]=i-1,r[n++]=i+1,i+2<t&&(r[n++]=i,r[n++]=i+1,r[n++]=i+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return e.indices=r,e.primitiveType=S.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),r=E.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function G(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return L(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return q(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<T.EPSILON6&&(e.y=t?-T.EPSILON6:T.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return V(e,e.y<0),V(t,t.y<0),void V(r,r.y<0);var n,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(r.y);n=i>a?i>o?T.sign(e.y):T.sign(r.y):a>o?T.sign(t.y):T.sign(r.y);var u=n<0;V(e,u),V(t,u),V(r,u)}function W(e,t,r,n){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),r),i.clone(r,n),V(r,!0),V(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,i=t.y<0,a=r.y<0,o=0;o+=n?1:0,o+=i?1:0,o+=a?1:0;var u=Ie.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(W(e,t,Ae,ge),W(e,r,Se,Ne),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(W(t,r,Ae,ge),W(t,e,Se,Ne),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(W(r,e,Ae,ge),W(r,t,Se,Ne),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?i?a||(W(r,e,Ae,ge),W(r,t,Se,Ne),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(W(t,r,Ae,ge),W(t,e,Se,Ne),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(W(e,t,Ae,ge),W(e,r,Se,Ne),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Ie.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=ge,s[6]=Ne,s.length=7),Ie}}function Y(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var i in n)if(n.hasOwnProperty(i)&&c(n[i])&&c(n[i].values)){var a=n[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=E.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function k(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var i=t[n];r[n]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:r,indices:[],primitiveType:e.primitiveType})}function j(e,t,r){var n=c(e.geometry.boundingSphere);t=Y(t,n),r=Y(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Z(e,r,a,o,u,s,l,f,h,d,p,m){if(c(s)||c(l)||c(f)||c(h)||c(d)){var E=i.fromArray(u,3*e,Oe),y=i.fromArray(u,3*r,we),_=i.fromArray(u,3*a,Me),T=t(o,E,y,_,xe);if(c(s)){var v=i.fromArray(s,3*e,Oe),R=i.fromArray(s,3*r,we),A=i.fromArray(s,3*a,Me);i.multiplyByScalar(v,T.x,v),i.multiplyByScalar(R,T.y,R),i.multiplyByScalar(A,T.z,A);var S=i.add(v,R,v);i.add(S,A,S),i.normalize(S,S),i.pack(S,p.normal.values,3*m)}if(c(d)){var g=i.fromArray(d,3*e,Oe),N=i.fromArray(d,3*r,we),I=i.fromArray(d,3*a,Me);i.multiplyByScalar(g,T.x,g),i.multiplyByScalar(N,T.y,N),i.multiplyByScalar(I,T.z,I);var O;i.equals(g,i.ZERO)&&i.equals(N,i.ZERO)&&i.equals(I,i.ZERO)?(O=Oe,O.x=0,O.y=0,O.z=0):(O=i.add(g,N,g),i.add(O,I,O),i.normalize(O,O)),i.pack(O,p.extrudeDirection.values,3*m)}if(c(l)){var w=i.fromArray(l,3*e,Oe),M=i.fromArray(l,3*r,we),x=i.fromArray(l,3*a,Me);i.multiplyByScalar(w,T.x,w),i.multiplyByScalar(M,T.y,M),i.multiplyByScalar(x,T.z,x);var C=i.add(w,M,w);i.add(C,x,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*m)}if(c(f)){var P=i.fromArray(f,3*e,Oe),D=i.fromArray(f,3*r,we),U=i.fromArray(f,3*a,Me);i.multiplyByScalar(P,T.x,P),i.multiplyByScalar(D,T.y,D),i.multiplyByScalar(U,T.z,U);var b=i.add(P,D,P);i.add(b,U,b),i.normalize(b,b),i.pack(b,p.bitangent.values,3*m)}if(c(h)){var L=n.fromArray(h,2*e,Ce),F=n.fromArray(h,2*r,Pe),B=n.fromArray(h,2*a,De);n.multiplyByScalar(L,T.x,L),n.multiplyByScalar(F,T.y,F),n.multiplyByScalar(B,T.z,B);var z=n.add(L,F,L);n.add(z,B,z),n.pack(z,p.st.values,2*m)}}}function K(e,t,r,n,i,a){var o=e.position.values.length/3;if(-1!==i){var u=n[i],s=r[u];return-1===s?(r[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,r,n,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,E=u.indices,y=k(u),_=k(u),T=[];T.length=l.length/3;var v=[];for(v.length=l.length/3,o=0;o<T.length;++o)T[o]=-1,v[o]=-1;var R=E.length;for(o=0;o<R;o+=3){var A=E[o],S=E[o+1],g=E[o+2],N=i.fromArray(l,3*A),I=i.fromArray(l,3*S),O=i.fromArray(l,3*g),w=H(N,I,O);if(c(w)&&w.positions.length>3)for(var M=w.positions,x=w.indices,C=x.length,P=0;P<C;++P){var D=x[P],U=M[D];U.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=v),a=K(t,r,n,E,D<3?o+D:-1,U),Z(A,S,g,U,l,f,d,h,p,m,t,a)}else c(w)&&(N=w.positions[0],I=w.positions[1],O=w.positions[2]),N.y<0?(t=_.attributes,r=_.indices,n=T):(t=y.attributes,r=y.indices,n=v),a=K(t,r,n,E,o,N),Z(A,S,g,N,l,f,d,h,p,m,t,a),a=K(t,r,n,E,o+1,I),Z(A,S,g,I,l,f,d,h,p,m,t,a),a=K(t,r,n,E,o+2,O),Z(A,S,g,O,l,f,d,h,p,m,t,a)}j(e,_,y)}function Q(e){var t,r=e.geometry,n=r.attributes,a=n.position.values,o=r.indices,u=k(r),s=k(r),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],m=i.fromArray(a,3*d,Oe),E=i.fromArray(a,3*p,we);Math.abs(m.y)<T.EPSILON6&&(m.y<0?m.y=-T.EPSILON6:m.y=T.EPSILON6),Math.abs(E.y)<T.EPSILON6&&(E.y<0?E.y=-T.EPSILON6:E.y=T.EPSILON6);var y=u.attributes,v=u.indices,R=h,A=s.attributes,S=s.indices,g=f,N=_.lineSegmentPlane(m,E,Ue,Me);if(c(N)){var I=i.multiplyByScalar(i.UNIT_Y,5*T.EPSILON9,be);m.y<0&&(i.negate(I,I),y=s.attributes,v=s.indices,R=f,A=u.attributes,S=u.indices,g=h);var O=i.add(N,I,Le);K(y,v,R,o,t,m),K(y,v,R,o,-1,O),i.negate(I,I),i.add(N,I,O),K(A,S,g,o,-1,O),K(A,S,g,o,t+1,E)}else{var w,M,x;m.y<0?(w=s.attributes,M=s.indices,x=f):(w=u.attributes,M=u.indices,x=h),K(w,M,x,o,t,m),K(w,M,x,o,t+1,E)}}j(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,a=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=i.unpack(r,u,ze);if(!(s.x>0)){var c=i.unpack(n,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):i.pack(s,n,u));var l=i.unpack(a,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=r[u+3],a[u+1]=r[u+4],a[u+2]=r[u+5]):i.pack(s,a,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,E=k(u),y=k(u),v=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,S=t+2,g=i.fromArray(l,3*A,ze),N=i.fromArray(l,3*S,qe);if(Math.abs(g.y)<ke)for(g.y=ke*(N.y<0?-1:1),l[3*t+1]=g.y,l[3*(t+1)+1]=g.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(N.y)<ke)for(N.y=ke*(g.y<0?-1:1),l[3*(t+2)+1]=N.y,l[3*(t+3)+1]=N.y,r=3*A;r<3*A+12;r+=3)h[r]=l[3*(t+2)],h[r+1]=l[3*(t+2)+1],h[r+2]=l[3*(t+2)+2];var I=E.attributes,O=E.indices,w=y.attributes,M=y.indices,x=_.lineSegmentPlane(g,N,Ue,Ve);if(c(x)){v=!0;var C=i.multiplyByScalar(i.UNIT_Y,Ye,Xe);g.y<0&&(i.negate(C,C),I=y.attributes,O=y.indices,w=E.attributes,M=E.indices);var P=i.add(x,C,We);I.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),I.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),I.prevPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(x,C,P),w.position.values.push(P.x,P.y,P.z),w.position.values.push(P.x,P.y,P.z),w.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.nextPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),w.nextPosition.values.push(h[3*S],h[3*S+1],h[3*S+2]),w.nextPosition.values.push(h[3*S+3],h[3*S+4],h[3*S+5]);var D=n.fromArray(d,2*A,Fe),U=Math.abs(D.y);I.expandAndWidth.values.push(-1,U,1,U),I.expandAndWidth.values.push(-1,-U,1,-U),w.expandAndWidth.values.push(-1,U,1,U),w.expandAndWidth.values.push(-1,-U,1,-U);var b=i.magnitudeSquared(i.subtract(x,g,Ge));if(b/=i.magnitudeSquared(i.subtract(N,g,Ge)),c(m)){var L=a.fromArray(m,4*A,He),F=a.fromArray(m,4*S,He),B=T.lerp(L.x,F.x,b),z=T.lerp(L.y,F.y,b),q=T.lerp(L.z,F.z,b),G=T.lerp(L.w,F.w,b);for(r=4*A;r<4*A+8;++r)I.color.values.push(m[r]);for(I.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),w.color.values.push(B,z,q,G),w.color.values.push(B,z,q,G),r=4*S;r<4*S+8;++r)w.color.values.push(m[r])}if(c(p)){var V=n.fromArray(p,2*A,Fe),X=n.fromArray(p,2*(t+3),Be),W=T.lerp(V.x,X.x,b);for(r=2*A;r<2*A+4;++r)I.st.values.push(p[r]);for(I.st.values.push(W,V.y),I.st.values.push(W,X.y),w.st.values.push(W,V.y),w.st.values.push(W,X.y),r=2*S;r<2*S+4;++r)w.st.values.push(p[r])}o=I.position.values.length/3-4,O.push(o,o+2,o+1),O.push(o+1,o+2,o+3),o=w.position.values.length/3-4,M.push(o,o+2,o+1),M.push(o+1,o+2,o+3)}else{var H,Y;for(g.y<0?(H=y.attributes,Y=y.indices):(H=E.attributes,Y=E.indices),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(d[r]),c(p)&&H.st.values.push(p[r]);if(c(m))for(r=4*t;r<4*t+16;++r)H.color.values.push(m[r]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}v&&($(y),$(E)),j(e,y,E)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=I(t);break;case S.TRIANGLE_STRIP:e.indices=O(t);break;case S.TRIANGLE_FAN:e.indices=w(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4) +;for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*n,l[f++]=i[h+1]+a[h+1]*n,l[f++]=i[h+2]+a[h+2]*n;var m,E=e.boundingSphere;return c(E)&&(m=new r(E.center,E.radius+n)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,i={},a=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(i[u]=a++)}for(var s in n)n.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),i=0;i<t;i++)n[i]=-1;for(var a,o=r,s=o.length,l=E.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=n[o[f]],-1!==a?l[h]=a:(a=o[f],n[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var m=e.attributes;for(var y in m)if(m.hasOwnProperty(y)&&c(m[y])&&c(m[y].values)){for(var _=m[y],T=_.values,v=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);v<t;){var S=n[v];if(-1!==S)for(var g=0;g<R;g++)A[R*S+g]=T[R*v+g];++v}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,i=0,a=0;a<n;a++)r[a]>i&&(i=r[a]);e.indices=g.tipsify({indices:r,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=d.computeNumberOfVertices(e);if(c(e.indices)&&r>=T.SIXTY_FOUR_KILOBYTES){var n,i=[],a=[],o=0,u=M(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var h=0;h<n;++h){var p=s[f+h],m=i[p];c(m)||(m=o++,i[p]=m,x(u,e.attributes,p)),a.push(m)}o+n>=T.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=M(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new i,ne=new o;te.projectTo2D=function(e,t,r,n,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,m=0;m<l.length;m+=3){var E=i.fromArray(l,m,re),y=s.cartesianToCartographic(E,ne),_=a.project(y,re);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[r]=o,e.attributes[n]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new v;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=r.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,i=0;i<n;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&r.push(a)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,a=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=r[t],m=r[t+1],E=r[t+2],y=3*d,_=3*m,v=3*E;le.x=a[y],le.y=a[y+1],le.z=a[y+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[v],he.y=a[v+1],he.z=a[v+2],c[d].count++,c[m].count++,c[E].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var S=A.indexOffset+A.currentCount;f[S]=h,A.currentCount++,A=c[r[t+1]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,A=c[r[t+2]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,h++}var g=new Float32Array(3*o);for(t=0;t<o;t++){var N=3*t;if(A=c[t],i.clone(i.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)i.add(ce,l[f[A.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,T.EPSILON10)&&i.clone(l[f[A.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,T.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),g[N]=ce.x,g[N+1]=ce.y,g[N+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:g}),e};var de=new i,pe=new i,me=new i;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var m=r[t],E=r[t+1],y=r[t+2];f=3*m,h=3*E,d=3*y;var _=2*m,T=2*E,v=2*y,R=n[f],A=n[f+1],S=n[f+2],g=o[_],N=o[_+1],I=o[T+1]-N,O=o[v+1]-N,w=1/((o[T]-g)*O-(o[v]-g)*I),M=(O*(n[h]-R)-I*(n[d]-R))*w,x=(O*(n[h+1]-A)-I*(n[d+1]-A))*w,C=(O*(n[h+2]-S)-I*(n[d+2]-S))*w;l[f]+=M,l[f+1]+=x,l[f+2]+=C,l[h]+=M,l[h+1]+=x,l[h+2]+=C,l[d]+=M,l[d+1]+=x,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var U=i.fromArray(a,f,de),b=i.fromArray(l,f,me),L=i.dot(U,b);i.multiplyByScalar(U,L,pe),i.normalize(i.subtract(b,pe,b),b),P[f]=b.x,P[h]=b.y,P[d]=b.z,i.normalize(i.cross(U,b,b),b),D[f]=b.x,D[h]=b.y,D[d]=b.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var Ee=new n,ye=new i,_e=new i,Te=new i,ve=new n;te.compressVertices=function(t){var r,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(r=0;r<a;++r)i.fromArray(s,3*r,ye),i.equals(ye,i.ZERO)?f+=2:(ve=e.octEncodeInRange(ye,65535,ve),l[f++]=ve.x,l[f++]=ve.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,m=c(h),E=c(d);if(!m&&!E)return t;var y,_,T,v,R=t.attributes.tangent,A=t.attributes.bitangent,S=c(R),g=c(A);m&&(y=h.values),E&&(_=d.values),S&&(T=R.values),g&&(v=A.values),a=(m?y.length:_.length)/(m?3:2);var N=a,I=E&&m?2:1;I+=S||g?1:0,N*=I;var O=new Float32Array(N),w=0;for(r=0;r<a;++r){E&&(n.fromArray(_,2*r,Ee),O[w++]=e.compressTextureCoordinates(Ee));var M=3*r;m&&c(T)&&c(v)?(i.fromArray(y,M,ye),i.fromArray(T,M,_e),i.fromArray(v,M,Te),e.octPack(ye,_e,Te,Ee),O[w++]=Ee.x,O[w++]=Ee.y):(m&&(i.fromArray(y,M,ye),O[w++]=e.octEncodeFloat(ye)),S&&(i.fromArray(T,M,ye),O[w++]=e.octEncodeFloat(ye)),g&&(i.fromArray(v,M,ye),O[w++]=e.octEncodeFloat(ye)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:I,values:O}),m&&delete t.attributes.normal,E&&delete t.attributes.st,g&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Re=new i,Ae=new i,Se=new i,ge=new i,Ne=new i,Ie={positions:new Array(7),indices:new Array(9)},Oe=new i,we=new i,Me=new i,xe=new i,Ce=new n,Pe=new n,De=new n,Ue=A.fromPointNormal(i.ZERO,i.UNIT_Y),be=new i,Le=new i,Fe=new n,Be=new n,ze=new i,qe=new i,Ge=new i,Ve=new i,Xe=new i,We=new i,He=new a,Ye=5*T.EPSILON9,ke=T.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==y.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else G(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,i){return t(e).then(r,n,i)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=i(e),t}function r(t){return e(t,a)}function n(e){this.then=e}function i(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return a(e)}})}function a(e){return new n(function(r,n){try{return n?t(n(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,r){return h(e,t,r)}function r(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new n(e),s={then:e,resolve:r,reject:i,progress:u,promise:c,resolver:{resolve:r,reject:i,progress:u}},l=[],f=[],h=function(e,t,r){var n,i;return n=o(),i="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,i)}),f.push(i),n.promise},d=function(e){return m(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=y,m(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,i,a){return E(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){p(e)}var c,l,f,h,d,p,m,E,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,h=[],d=o(),c)for(E=d.progress,m=function(e){h.push(e),--l||(p=m=y,d.reject(h))},p=function(e){f.push(e),--c||(p=m=y,d.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,E);else d.resolve(f);return d.then(n,i,a)})}function c(e,t,r,n){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,r,n)}function l(e,t,r,n){return E(1,arguments),h(e,_).then(t,r,n)}function f(){return h(arguments,_)}function h(t,r){return e(t,function(t){var n,i,a,u,s,c;if(a=i=t.length>>>0,n=[],c=o(),a)for(u=function(t,i){e(t,r).then(function(e){n[i]=e,--a||c.resolve(n)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(n);return c.promise})}function d(t,r){var n=v.call(arguments,1);return e(t,function(t){var i;return i=t.length,n[0]=function(t,n,a){return e(t,function(t){return e(n,function(e){return r(t,e,a,i)})})},T.apply(t,n)})}function p(t,r,n){var i=arguments.length>2;return e(t,function(e){return e=i?n:e,r.resolve(e),e},function(e){return r.reject(e),a(e)},r.progress)}function m(e,t){for(var r,n=0;r=e[n++];)r(t)}function E(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function y(){}function _(e){return e}var T,v,R;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},v=[].slice,T=[].reduce||function(e){var t,r,n,i,a;if(a=0,t=Object(this),i=t.length>>>0,r=arguments,r.length<=1)for(;;){if(a in t){n=t[a++];break}if(++a>=i)throw new TypeError}else n=r[1];for(;a<i;++a)a in t&&(n=e(n,t[a],a,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,i,a=0,o=e.length-1;a<=o;)if(n=~~((a+o)/2),(i=r(e[n],t))<0)a=n+1;else{if(!(i>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],i=function(e,t,r,n){r||(r=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+i:i+e},a=function(e,t,r,n,a,o){var u=n-e.length;return u>0&&(e=r||!a?i(e,n,o,r):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+i(c.toString(t),u||0,"0",!1),a(e,r,n,o,s)},u=function(e,t,r,n,i,o){return null!=n&&(e=e.slice(0,n)),a(e,"",t,r,i,o)},s=function(e,n,s,c,l,f,h){var d,p,m,E,y;if("%%"==e)return"%";for(var _=!1,T="",v=!1,R=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":v=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=n?t[n.slice(0,-1)]:t[r++],h){case"s":return u(String(y),_,c,f,v,A);case"c":return u(String.fromCharCode(+y),_,c,f,v);case"b":return o(y,2,R,_,c,f,v);case"o":return o(y,8,R,_,c,f,v);case"x":return o(y,16,R,_,c,f,v);case"X":return o(y,16,R,_,c,f,v).toUpperCase();case"u":return o(y,10,R,_,c,f,v);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),p=d<0?"-":T,y=p+i(String(Math.abs(d)),f,"0",!1),a(y,p,_,c,v);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,p=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],E=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=p+Math.abs(d)[m](f),a(y,p,_,c,v)[E]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,i,a,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var i=r[n].offset;if(n>0){m.secondsDifference(r[n].julianDate,e)>i&&(n--,i=r[n].offset)}m.addSeconds(e,i,e)}function h(e,r){_.julianDate=e;var n=m.leapSeconds,i=t(n,_,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-n[0].offset,r);if(i>=n.length)return m.addSeconds(e,-n[i-1].offset,r);var a=m.secondsDifference(n[i].julianDate,e);return 0===a?m.addSeconds(e,-n[i].offset,r):a<=1?void 0:m.addSeconds(e,-n[--i].offset,r)}function d(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function p(e,t,r,n,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=a+(n*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),n===c.UTC&&f(this)}var E=new a,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,v=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;m.fromGregorianDate=function(e,t){var r=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromDate=function(e,t){var r=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,i,a,u=e.split("T"),s=1,l=1,h=0,E=0,_=0,g=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(v)))r=+u[1],s=+u[2];else if(null!==(u=w.match(T)))r=+u[1];else{var x;if(null!==(u=w.match(R)))r=+u[1],x=+u[2],a=o(r);else if(null!==(u=w.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));x=7*C+P-D.getUTCDay()-3}i=new Date(Date.UTC(r,0,1)),i.setUTCDate(x),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(r);var U;if(n(M)){u=M.match(O),null!==u?(h=+u[1],E=+u[2],_=+u[3],g=1e3*+(u[4]||0),U=5):(u=M.match(I),null!==u?(h=+u[1],E=+u[2],_=60*+(u[3]||0),U=4):null!==(u=M.match(N))&&(h=+u[1],E=60*+(u[2]||0),U=3));var b=u[U],L=+u[U+1],F=+(u[U+2]||0);switch(b){case"+":h-=L,E-=F;break;case"-":h+=L,E+=F;break;case"Z":break;default:E+=new Date(Date.UTC(r,s-1,l,h,E)).getTimezoneOffset()}}var B=60===_;for(B&&_--;E>=60;)E-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:y[s-1];l>i;)l-=i,s++,s>12&&(s-=12,r++),i=a&&2===s?29:y[s-1];for(;E<0;)E+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),i=a&&2===s?29:y[s-1],l+=i;var z=p(r,s,l,h,E,_,g);return n(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var w=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var r=!1,i=h(e,w);n(i)||(m.addSeconds(e,-1,w),i=h(w,w),r=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var E=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,v=T/s.SECONDS_PER_MINUTE|0;T-=v*s.SECONDS_PER_MINUTE;var R=0|T,A=(T-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(R+=1),n(t)?(t.year=y,t.month=E,t.day=p,t.hour=_,t.minute=v,t.second=R,t.millisecond=A,t.isLeapSecond=r,t):new a(y,E,p,_,v,R,A,r)},m.toDate=function(e){var t=m.toGregorianDate(e,E),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var i,a=m.toGregorianDate(t,E);return n(r)||0===a.millisecond?n(r)&&0!==r?(i=(.01*a.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},m.addSeconds=function(e,t,r){return d(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,n,r)},m.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,n,r)},m.addDays=function(e,t,r){return d(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var i=new r.constructor;for(var a in r)if(r.hasOwnProperty(a)){var o=r[a];n&&(o=t(o,n)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function r(n,i,a){a=e(a,!1);var o,u,s,c={},l=t(n),f=t(i);if(l)for(o in n)n.hasOwnProperty(o)&&(u=n[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?r(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return r}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){t(i[r])||(i[r]=!0,console.warn(e(n,r)))}var i={};return n.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",n}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,r){"use strict";function n(e,t){r(e,t)}return n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(r,n,i){n=t(n,t(i.baseURI,i.location.href));var a=new e(n);return new e(r).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){var i="",a=r.lastIndexOf("/");return-1!==a&&(i=r.substring(0,a+1)),n?(r=new e(r),t(r.query)&&(i+="?"+r.query),t(r.fragment)&&(i+="#"+r.fragment),i):i}return n}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){var r=new e(t);r.normalize();var n=r.path,i=n.lastIndexOf("/");return-1!==i&&(n=n.substr(i+1)),i=n.lastIndexOf("."),n=-1===i?"":n.substr(i+1)}return n}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(r)||(r=document.createElement("a")),r.href=window.location.href;var n=r.host,i=r.protocol;return r.href=t,r.href=r.href,i!==r.protocol||n!==r.host}var r;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var i=e[n],a=encodeURIComponent(n)+"=";if(r(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return n}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(t){var n={};if(""===t)return n;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=n[s];"string"==typeof l?n[s]=[l,c]:r(l)?l.push(c):n[s]=c}return n}return n}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,n.OTHER),this.serverKey=void 0,this.state=r.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var i=r[n],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function n(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return r(n.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),n.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},n.prototype.removeEventListener=function(e,t){for(var r=this._listeners,n=this._scopes,i=-1,a=0;a<r.length;a++)if(r[a]===e&&n[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),r[i]=void 0,n[i]=void 0):(r.splice(i,1),n.splice(i,1)),!0)},n.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,r=this._listeners,n=this._scopes,a=r.length;for(e=0;e<a;e++){var o=r[e];t(o)&&r[e].apply(n[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];r.splice(s,1),n.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},n}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength}, +set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(i[c],i[e])<0?c:e,s<r&&n(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,n=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return r(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return a(r,e,--this._length),this.heapify(e),n}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function p(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function E(e){return function(t){e.state!==c.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function y(e){var t=p(e);return e.state=c.ACTIVE,g.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(m(e)).otherwise(E(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function T(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function v(){f.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),T())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var g=[],N={},I="undefined"!=typeof document?new e(document.location.href):new e,O=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=O,i(f,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,r=0,n=g.length;for(e=0;e<n;++e)t=g[e],t.cancelled&&_(t),t.state===c.ACTIVE?r>0&&(g[e-r]=t):++r;g.length-=r;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(y(t),++u):_(t);v()},f.getServerKey=function(t){var r=new e(t).resolve(I);r.normalize();var i=r.authority;/:/.test(i)||(i=i+":"+("https"===r.scheme?"443":"80"));var a=N[i];return n(a)||(N[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return O.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return y(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(n(t)){if(t===e)return;_(t)}return p(e)}},f.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=g.length,t=0;t<e;++t)_(g[t]);g.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var i=n.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=n.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])||(a[n]=!0)},i.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])&&delete a[n]},i.contains=function(e){var r=n(e);return!(!t(r)||!t(a[r]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T,v,R,A,S,g,N){"use strict";function I(e,t){var r=e.query;if(!a(r)||0===r.length)return{};var i;if(-1===r.indexOf("=")){var o={};o[r]=void 0,i=o}else i=y(r);t._queryParameters=n(t._queryParameters,i),e.query=void 0}function O(e,t){var r=t._queryParameters,n=Object.keys(r);1!==n.length||a(r[n[0]])?e.query=E(r):e.query=n[0]}function w(e,t){return a(e)?a(e.clone)?e.clone():r(e):t}function M(e){if(e.state===R.ISSUED||e.state===R.ACTIVE)throw new A("The Resource is already being fetched.");e.state=R.UNISSUED,e.deferred=void 0}function x(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=w(e.templateValues,{}),this._queryParameters=w(e.queryParameters,{}),this.headers=w(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var r=e.request;r.url=e.url,r.requestFunction=function(){var r=e.url,n=!1;e.isDataUri||e.isBlobUri||(n=e.isCrossOriginUrl);var i=N.defer();return x._Implementations.createImage(r,n&&t,i),i.promise};var n=v.request(r);if(a(n))return n.otherwise(function(n){return r.state!==R.FAILED?N.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,C(e,t)):N.reject(n)})})}function P(e,t,r){var n={};n[t]=r,e.addQueryParameters(n);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=N.defer();return window[r]=function(e){t.resolve(e);try{delete window[r]}catch(e){window[r]=void 0}},x._Implementations.loadAndExecuteScript(e.url,r,t),t.promise};var o=v.request(i);if(a(o))return o.otherwise(function(n){return i.state!==R.FAILED?N.reject(n):e.retryOnError(n).then(function(a){return a?(i.state=R.UNISSUED,i.deferred=void 0,P(e,t,r)):N.reject(n)})})}function D(e,t){M(e.request);var r=e.request;r.url=e.url,r.requestFunction=function(){var i=t.responseType,o=n(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=x._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(r.cancelFunction=function(){f.abort()}),l.promise};var i=v.request(r);if(a(i))return i.then(function(e){return e}).otherwise(function(n){return r.state!==R.FAILED?N.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,e.fetch(t)):N.reject(n)})})}function U(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function b(e,t){for(var r=U(e,t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return n}function L(e,t){t=i(t,"");var r=e[1],n=!!e[2],a=e[3];switch(t){case"":case"text":return U(n,a);case"arraybuffer":return b(n,a);case"blob":var o=b(n,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(U(n,a),r);case"json":return JSON.parse(U(n,a))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();x.createIfNeeded=function(e,t){if(e instanceof x)return e.clone();if("string"!=typeof e)return e;var r=w(t,{});return r.url=e,new x(r)},o(x,{isBlobSupported:{get:function(){return F}}}),o(x.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);I(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return p(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),x.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var r=new g(this._url);e&&O(r,this);var n=r.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];n=n.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(n=this.proxy.getURL(n)),n},x.prototype.addQueryParameters=function(e,t){this._queryParameters=t?n(this._queryParameters,e):n(e,this._queryParameters)},x.prototype.addTemplateValues=function(e,t){this._templateValues=t?n(this._templateValues,e):n(e,this._templateValues)},x.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var r=new g(e.url);I(r,t),r.fragment=void 0,t._url=r.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=n(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=n(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=n(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},x.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var r=this;return N(t(this,e)).then(function(e){return++r._retryCount,e})},x.prototype.clone=function(e){return a(e)||(e=new x({url:this._url})),e._url=this._url,e._queryParameters=r(this._queryParameters),e._templateValues=r(this._templateValues),e.headers=r(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},x.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},x.prototype.appendForwardSlash=function(){this._url=e(this._url)},x.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},x.fetchArrayBuffer=function(e){return new x(e).fetchArrayBuffer()},x.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},x.fetchBlob=function(e){return new x(e).fetchBlob()},x.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),M(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var r=this.fetchBlob();if(a(r)){var n,o;return r.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return n=new x({url:t}),C(n)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(n.url),e.blob=o,e}).otherwise(function(e){return a(n)&&window.URL.revokeObjectURL(n.url),N.reject(e)})}},x.fetchImage=function(e){return new x(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},x.prototype.fetchText=function(){return this.fetch({responseType:"text"})},x.fetchText=function(e){return new x(e).fetchText()},x.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},x.fetchJson=function(e){return new x(e).fetchJson()},x.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},x.fetchXML=function(e){return new x(e).fetchXML()},x.prototype.fetchJsonp=function(e){e=i(e,"callback"),M(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},x.fetchJsonp=function(e){return new x(e).fetchJsonp(e.callbackParameterName)},x.prototype.fetch=function(e){return e=w(e,i.EMPTY_OBJECT),e.method="GET",D(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return x.fetch=function(e){return new x(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x.prototype.post=function(e,r){return t.defined("data",e),r=w(r,{}),r.method="POST",r.data=e,D(this,r)},x.post=function(e){return new x(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x._Implementations={},x._Implementations.createImage=function(e,t,r){var n=new Image;n.onload=function(){r.resolve(n)},n.onerror=function(e){r.reject(e)},t&&(S.contains(e)?n.crossOrigin="use-credentials":n.crossOrigin=""),n.src=e},x._Implementations.loadWithXhr=function(e,t,r,n,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(L(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(r,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,r=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&r!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===r||"document"===r)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==r&&"text"!==r||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(n),c},x._Implementations.loadAndExecuteScript=function(e,t,r){var n=document.createElement("script");n.async=!0,n.src=e;var i=document.getElementsByTagName("head")[0];n.onload=function(){n.onload=void 0,i.removeChild(n)},n.onerror=function(e){r.reject(e)},i.appendChild(n)},x._DefaultImplementations={},x._DefaultImplementations.createImage=x._Implementations.createImage,x._DefaultImplementations.loadWithXhr=x._Implementations.loadWithXhr,x._DefaultImplementations.loadAndExecuteScript=x._Implementations.loadAndExecuteScript,x.DEFAULT=c(new x({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),x}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))p(this,t.data);else if(n(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){p(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=r.columnNames.indexOf("modifiedJulianDateUtc"),a=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||p<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var E=e._samples=r.samples,y=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,v=0,R=E.length;v<R;v+=e._columnCount){var A=E[v+i],S=E[v+m],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,S,f.TAI);if(y.push(N),T){if(S!==_&&n(_)){var I=o.leapSeconds,O=t(I,N,d);if(O<0){var w=new u(N,S);I.splice(~O,0,w)}}_=S}}}function m(e,t,r,n,i){var a=r*n;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function E(e,t,r){return t+e*(r-t)}function y(e,t,r,n,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||n.equals(c))return m(e,r,i,s,u),u;if(n.equals(l))return m(e,r,a,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=r[h+e._ut1MinusUtcSecondsColumn],y=r[d+e._ut1MinusUtcSecondsColumn],_=y-p;if(_>.5||_<-.5){var T=r[h+e._taiMinusUtcSecondsColumn],v=r[d+e._taiMinusUtcSecondsColumn];T!==v&&(l.equals(n)?p=y:y-=v-T)}return u.xPoleWander=E(f,r[h+e._xPoleWanderRadiansColumn],r[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=E(f,r[h+e._yPoleWanderRadiansColumn],r[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=E(f,r[h+e._xCelestialPoleOffsetRadiansColumn],r[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=E(f,r[h+e._yCelestialPoleOffsetRadiansColumn],r[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=E(f,p,y),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new i(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var a=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!n(h),m=p||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!p&&h.equals(e)&&++s,l=s+1,y(this,a,this._samples,e,s,l,r),r}var E=t(a,e,o.compare,this._dateColumn);return E>=0?(E<a.length-1&&a[E+1].equals(e)&&++E,s=E,l=E):(l=~E,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,a,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,r,n,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),i=d.exec(n);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new n({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var r=f(e);return h.href=r,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=n.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){n[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(n[c]*=c-l);n[c]=1/n[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,a.daysDifference(n,e._sampleZeroDateTT)}function l(r,i){if(r._chunkDownloadsInProgress[i])return r._chunkDownloadsInProgress[i];var a=e.defer();r._chunkDownloadsInProgress[i]=a;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){r._chunkDownloadsInProgress[i]=!1;for(var t=r._samples,n=e.samples,o=i*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,r,n,i){var a=c(this,t,r),o=c(this,n,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,r){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(n(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),n(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){n(r)?(r.x=0,r.y=0,r.s=0):r=new i(0,0,0);var p,m,E=a-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,v=this._xTable;for(p=0;p<=u;++p)y[p]=E-v[p];for(p=0;p<=u;++p){for(T[p]=1,m=0;m<=u;++m)m!==p&&(T[p]*=y[m]);T[p]*=_[p];var R=3*(s+p);r.x+=T[p]*d[R++],r.y+=T[p]*d[R++],r.s+=T[p]*d[R]}return r}}}},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T){"use strict";var v={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},N=new r,I=new r,O=new r;v.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,i=R[e][t],a=e+t;return u(S[a])?n=S[a]:(n=function(n,a,s){if(u(s)||(s=new y),m.equalsEpsilon(n.x,0,m.EPSILON14)&&m.equalsEpsilon(n.y,0,m.EPSILON14)){var c=m.sign(n.z);r.unpack(A[e],0,N),"east"!==e&&"west"!==e&&r.multiplyByScalar(N,c,N),r.unpack(A[t],0,I),"east"!==t&&"west"!==t&&r.multiplyByScalar(I,c,I),r.unpack(A[i],0,O),"east"!==i&&"west"!==i&&r.multiplyByScalar(O,c,O)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(n,g.up);var l=g.up,h=g.east;h.x=-n.y,h.y=n.x,h.z=0,r.normalize(h,g.east),r.cross(l,h,g.north),r.multiplyByScalar(g.up,-1,g.down),r.multiplyByScalar(g.east,-1,g.west),r.multiplyByScalar(g.north,-1,g.south),N=g[e],I=g[t],O=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=I.x,s[5]=I.y,s[6]=I.z,s[7]=0,s[8]=O.x,s[9]=O.y,s[10]=O.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},S[a]=n),n},v.eastNorthUpToFixedFrame=v.localFrameToFixedFrameGenerator("east","north"),v.northEastDownToFixedFrame=v.localFrameToFixedFrameGenerator("north","east"),v.northUpEastToFixedFrame=v.localFrameToFixedFrameGenerator("north","up"),v.northWestUpToFixedFrame=v.localFrameToFixedFrameGenerator("north","west");var w=new _,M=new r(1,1,1),x=new y;v.headingPitchRollToFixedFrame=function(e,t,n,i,a){i=o(i,v.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=y.fromTranslationQuaternionRotationScale(r.ZERO,u,M,x);return a=i(e,n,a),y.multiply(a,s,a)};var C=new y,P=new E;v.headingPitchRollQuaternion=function(e,t,r,n,i){var a=v.headingPitchRollToFixedFrame(e,t,r,n,C),o=y.getRotation(a,P);return _.fromRotationMatrix(o,i)};var D=m.TWO_PI/86400,U=new p;v.computeTemeToPseudoFixedMatrix=function(e,t){U=p.addSeconds(e,-p.computeTaiMinusUtc(e),U);var r,n=U.dayNumber,i=U.secondsOfDay,a=n-2451545;r=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(h,d,0,-d,h,0,0,0,1)},v.iau2006XysData=new h,v.earthOrientationParameters=c.NONE;v.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=v.iau2006XysData.preload(r,n,i,a),u=v.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},v.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new E);var r=v.computeFixedToIcrfMatrix(e,t);if(u(r))return E.transpose(r,t)};var b=new d(0,0,0),L=new l(0,0,0,0,0,0),F=new E,B=new E;v.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new E);var r=v.earthOrientationParameters.compute(e,L);if(u(r)){var n=e.dayNumber,i=e.secondsOfDay+32.184,a=v.iau2006XysData.computeXysRadians(n,i,b);if(u(a)){var o=a.x+r.xPoleOffset,s=a.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=E.fromRotationZ(-a.s,B),h=E.multiply(l,f,F),d=e.dayNumber,y=e.secondsOfDay-p.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=d-2451545,R=y/T.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*m.TWO_PI;var S=E.fromRotationZ(A,B),g=E.multiply(h,S,F),N=Math.cos(r.xPoleWander),I=Math.cos(r.yPoleWander),O=Math.sin(r.xPoleWander),w=Math.sin(r.yPoleWander),M=n-2451545+i/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),D=B;return D[0]=N*C,D[1]=N*P,D[2]=O,D[3]=-I*P+w*O*C,D[4]=I*C+w*O*P,D[5]=-w*N,D[6]=-w*P-I*O*C,D[7]=w*C-I*O*P,D[8]=I*N,E.multiply(g,D,t)}}};var z=new n;v.pointToWindowCoordinates=function(e,t,r,n){return n=v.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},v.pointToGLWindowCoordinates=function(e,r,i,a){u(a)||(a=new t);var o=z;return y.multiplyByVector(e,n.fromElements(i.x,i.y,i.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(r,o,o),t.fromCartesian4(o,a)};var q=new r,G=new r,V=new r;v.rotationMatrixFromPositionVelocity=function(e,t,n,i){var a=o(n,f.WGS84).geodeticSurfaceNormal(e,q),s=r.cross(t,a,G);r.equalsEpsilon(s,r.ZERO,m.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,V);return r.cross(t,c,s),r.negate(s,s),u(i)||(i=new E),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var X=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),W=new i,H=new r,Y=new r,k=new E,j=new y,Z=new y;return v.basisTo2D=function(e,t,n){var i=y.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,W),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=v.eastNorthUpToFixedFrame(i,a,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,n);return y.multiply(X,f,n),y.setTranslation(n,u,n),n},v.wgs84To2DModelMatrix=function(e,t,n){var i=e.ellipsoid,a=v.eastNorthUpToFixedFrame(t,i,j),o=y.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,W),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(X,o,n),y.multiply(c,n,n),n},v}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=n(new i({position:!0})),i.POSITION_AND_NORMAL=n(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=n(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=n(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=n(new i({position:!0,color:!0})),i.ALL=n(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.position?1:0,r[n++]=t.normal?1:0,r[n++]=t.st?1:0,r[n++]=t.tangent?1:0,r[n++]=t.bitangent?1:0,r[n]=t.color?1:0,r},i.unpack=function(r,n,a){return n=e(n,0),t(a)||(a=new i),a.position=1===r[n++],a.normal=1===r[n++],a.st=1===r[n++],a.tangent=1===r[n++],a.bitangent=1===r[n++],a.color=1===r[n],a},i.clone=function(e,r){if(t(e))return t(r)||(r=new i),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},i}), +define("Core/EllipseGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./Matrix4","./PrimitiveType","./Quaternion","./Rectangle","./Transforms","./VertexFormat"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,E,y,_,T,v,R,A,S,g,N){"use strict";function I(e,n,a){var o=n.vertexFormat,u=n.center,s=n.semiMajorAxis,l=n.semiMinorAxis,h=n.ellipsoid,m=n.stRotation,E=a?e.length/3*2:e.length/3,y=n.shadowVolume,_=o.st?new Float32Array(2*E):void 0,v=o.normal?new Float32Array(3*E):void 0,R=o.tangent?new Float32Array(3*E):void 0,S=o.bitangent?new Float32Array(3*E):void 0,g=y?new Float32Array(3*E):void 0,N=0,I=G,O=V,w=X,M=new f(h),x=M.project(h.cartesianToCartographic(u,W),H),C=h.scaleToGeodeticSurface(u,U);h.geodeticSurfaceNormal(C,C);for(var P=A.fromAxisAngle(C,m,q),D=T.fromQuaternion(P,z),F=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Y),j=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,k),Z=e.length,K=a?Z:0,J=K/3*2,Q=0;Q<Z;Q+=3){var $=Q+1,ee=Q+2,te=r.fromArray(e,Q,U);if(o.st){var re=T.multiplyByVector(D,te,b),ne=M.project(h.cartesianToCartographic(re,W),L);r.subtract(ne,x,ne),B.x=(ne.x+s)/(2*s),B.y=(ne.y+l)/(2*l),F.x=Math.min(B.x,F.x),F.y=Math.min(B.y,F.y),j.x=Math.max(B.x,j.x),j.y=Math.max(B.y,j.y),a&&(_[N+J]=B.x,_[N+1+J]=B.y),_[N++]=B.x,_[N++]=B.y}(o.normal||o.tangent||o.bitangent||y)&&(I=h.geodeticSurfaceNormal(te,I),y&&(g[Q+K]=-I.x,g[$+K]=-I.y,g[ee+K]=-I.z),(o.normal||o.tangent||o.bitangent)&&((o.tangent||o.bitangent)&&(O=r.normalize(r.cross(r.UNIT_Z,I,O),O),T.multiplyByVector(D,O,O)),o.normal&&(v[Q]=I.x,v[$]=I.y,v[ee]=I.z,a&&(v[Q+K]=-I.x,v[$+K]=-I.y,v[ee+K]=-I.z)),o.tangent&&(R[Q]=O.x,R[$]=O.y,R[ee]=O.z,a&&(R[Q+K]=-O.x,R[$+K]=-O.y,R[ee+K]=-O.z)),o.bitangent&&(w=r.normalize(r.cross(I,O,w),w),S[Q]=w.x,S[$]=w.y,S[ee]=w.z,a&&(S[Q+K]=w.x,S[$+K]=w.y,S[ee+K]=w.z))))}if(o.st){Z=_.length;for(var ie=0;ie<Z;ie+=2)_[ie]=(_[ie]-F.x)/(j.x-F.x),_[ie+1]=(_[ie+1]-F.y)/(j.y-F.y)}var ae=new p;if(o.position){var oe=c.raisePositionsToHeight(e,n,a);ae.position=new d({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:oe})}return o.st&&(ae.st=new d({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:_})),o.normal&&(ae.normal=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:v})),o.tangent&&(ae.tangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:R})),o.bitangent&&(ae.bitangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:S})),y&&(ae.extrudeDirection=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:g})),ae}function O(e){var t,r,n,i,a,o=new Array(e*(e+1)*12-6),u=0;for(t=0,n=1,i=0;i<3;i++)o[u++]=n++,o[u++]=t,o[u++]=n;for(i=2;i<e+1;++i){for(n=i*(i+1)-1,t=(i-1)*i-1,o[u++]=n++,o[u++]=t,o[u++]=n,r=2*i,a=0;a<r-1;++a)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=n++,o[u++]=t,o[u++]=n}for(r=2*e,++n,++t,i=0;i<r-1;++i)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;for(o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t++,o[u++]=t,++t,i=e-1;i>1;--i){for(o[u++]=t++,o[u++]=t,o[u++]=n,r=2*i,a=0;a<r-1;++a)o[u++]=n,o[u++]=t++,o[u++]=t,o[u++]=n++,o[u++]=t,o[u++]=n;o[u++]=t++,o[u++]=t++,o[u++]=n++}for(i=0;i<3;i++)o[u++]=t++,o[u++]=t,o[u++]=n;return o}function w(t){var n=t.center;j=r.multiplyByScalar(t.ellipsoid.geodeticSurfaceNormal(n,j),t.height,j),j=r.add(n,j,j);var i=new e(j,t.semiMajorAxis),a=c.computeEllipsePositions(t,!0,!1),o=a.positions,u=a.numPts,s=I(o,t,!1),l=O(u);return l=y.createTypedArray(o.length/3,l),{boundingSphere:i,attributes:s,indices:l}}function M(e,n){var a=n.vertexFormat,o=n.center,u=n.semiMajorAxis,s=n.semiMinorAxis,c=n.ellipsoid,l=n.height,h=n.extrudedHeight,m=n.stRotation,E=e.length/3*2,y=new Float64Array(3*E),_=a.st?new Float32Array(2*E):void 0,v=a.normal?new Float32Array(3*E):void 0,R=a.tangent?new Float32Array(3*E):void 0,S=a.bitangent?new Float32Array(3*E):void 0,g=n.shadowVolume,N=g?new Float32Array(3*E):void 0,I=0,O=G,w=V,M=X,x=new f(c),C=x.project(c.cartesianToCartographic(o,W),H),P=c.scaleToGeodeticSurface(o,U);c.geodeticSurfaceNormal(P,P);for(var D=A.fromAxisAngle(P,m,q),j=T.fromQuaternion(D,z),Z=t.fromElements(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Y),K=t.fromElements(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,k),J=e.length,Q=J/3*2,$=0;$<J;$+=3){var ee,te=$+1,re=$+2,ne=r.fromArray(e,$,U);if(a.st){var ie=T.multiplyByVector(j,ne,b),ae=x.project(c.cartesianToCartographic(ie,W),L);r.subtract(ae,C,ae),B.x=(ae.x+u)/(2*u),B.y=(ae.y+s)/(2*s),Z.x=Math.min(B.x,Z.x),Z.y=Math.min(B.y,Z.y),K.x=Math.max(B.x,K.x),K.y=Math.max(B.y,K.y),_[I+Q]=B.x,_[I+1+Q]=B.y,_[I++]=B.x,_[I++]=B.y}ne=c.scaleToGeodeticSurface(ne,ne),ee=r.clone(ne,b),O=c.geodeticSurfaceNormal(ne,O),g&&(N[$+J]=-O.x,N[te+J]=-O.y,N[re+J]=-O.z);var oe=r.multiplyByScalar(O,l,F);if(ne=r.add(ne,oe,ne),oe=r.multiplyByScalar(O,h,oe),ee=r.add(ee,oe,ee),a.position&&(y[$+J]=ee.x,y[te+J]=ee.y,y[re+J]=ee.z,y[$]=ne.x,y[te]=ne.y,y[re]=ne.z),a.normal||a.tangent||a.bitangent){M=r.clone(O,M);var ue=r.fromArray(e,($+3)%J,F);r.subtract(ue,ne,ue);var se=r.subtract(ee,ne,L);O=r.normalize(r.cross(se,ue,O),O),a.normal&&(v[$]=O.x,v[te]=O.y,v[re]=O.z,v[$+J]=O.x,v[te+J]=O.y,v[re+J]=O.z),a.tangent&&(w=r.normalize(r.cross(M,O,w),w),R[$]=w.x,R[te]=w.y,R[re]=w.z,R[$+J]=w.x,R[$+1+J]=w.y,R[$+2+J]=w.z),a.bitangent&&(S[$]=M.x,S[te]=M.y,S[re]=M.z,S[$+J]=M.x,S[te+J]=M.y,S[re+J]=M.z)}}if(a.st){J=_.length;for(var ce=0;ce<J;ce+=2)_[ce]=(_[ce]-Z.x)/(K.x-Z.x),_[ce+1]=(_[ce+1]-Z.y)/(K.y-Z.y)}var le=new p;return a.position&&(le.position=new d({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:y})),a.st&&(le.st=new d({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:_})),a.normal&&(le.normal=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:v})),a.tangent&&(le.tangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:R})),a.bitangent&&(le.bitangent=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:S})),g&&(le.extrudeDirection=new d({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:N})),le}function x(e){for(var t=e.length/3,r=y.createTypedArray(t,6*t),n=0,i=0;i<t;i++){var a=i,o=i+t,u=(a+1)%t,s=u+t;r[n++]=a,r[n++]=o,r[n++]=u,r[n++]=u,r[n++]=o,r[n++]=s}return r}function C(t){var n=t.center,i=t.ellipsoid,a=t.semiMajorAxis,o=r.multiplyByScalar(i.geodeticSurfaceNormal(n,U),t.height,U);Z.center=r.add(n,o,Z.center),Z.radius=a,o=r.multiplyByScalar(i.geodeticSurfaceNormal(n,o),t.extrudedHeight,o),K.center=r.add(n,o,K.center),K.radius=a;var u=c.computeEllipsePositions(t,!0,!0),s=u.positions,l=u.numPts,f=u.outerPositions,d=e.union(Z,K),p=I(s,t,!0),_=O(l),T=_.length;_.length=2*T;for(var v=s.length/3,A=0;A<T;A+=3)_[A+T]=_[A+2]+v,_[A+1+T]=_[A+1]+v,_[A+2+T]=_[A]+v;var S=y.createTypedArray(2*v/3,_),g=new h({attributes:p,indices:S,primitiveType:R.TRIANGLES}),N=M(f,t);_=x(f);var w=y.createTypedArray(2*f.length/3,_),C=new h({attributes:N,indices:w,primitiveType:R.TRIANGLES}),P=E.combineInstances([new m({geometry:g}),new m({geometry:C})]);return{boundingSphere:d,attributes:P[0].attributes,indices:P[0].indices}}function P(e,t,n,i,a){g.eastNorthUpToFixedFrame(e,t,J),v.inverseTransformation(J,Q);var o;for(o=0;o<4;++o)r.clone(r.ZERO,ee[o]);for(ee[0].x+=n,ee[1].x-=n,ee[2].y+=i,ee[3].y-=i,T.fromRotationZ(a,$),o=0;o<4;++o)T.multiplyByVector($,ee[o],ee[o]),v.multiplyByPoint(J,ee[o],ee[o]),t.cartesianToCartographic(ee[o],te[o]);return S.fromCartographicArray(te)}function D(e){e=a(e,a.EMPTY_OBJECT);var t=e.center,n=a(e.ellipsoid,l.WGS84),i=e.semiMajorAxis,u=e.semiMinorAxis,s=a(e.granularity,_.RADIANS_PER_DEGREE),c=a(e.height,0),f=e.extrudedHeight,h=o(f)&&Math.abs(c-f)>1,d=a(e.vertexFormat,N.DEFAULT);this._center=r.clone(t),this._semiMajorAxis=i,this._semiMinorAxis=u,this._ellipsoid=l.clone(n),this._rotation=a(e.rotation,0),this._stRotation=a(e.stRotation,0),this._height=c,this._granularity=s,this._vertexFormat=N.clone(d),this._extrudedHeight=a(f,c),this._extrude=h,this._shadowVolume=a(e.shadowVolume,!1),this._workerName="createEllipseGeometry",this._rectangle=P(this._center,this._ellipsoid,i,u,this._rotation)}var U=new r,b=new r,L=new r,F=new r,B=new t,z=new T,q=new A,G=new r,V=new r,X=new r,W=new n,H=new r,Y=new t,k=new t,j=new r,Z=new e,K=new e,J=new v,Q=new v,$=new T,ee=[new r,new r,new r,new r],te=[new n,new n,new n,new n];D.packedLength=r.packedLength+l.packedLength+N.packedLength+S.packedLength+9,D.pack=function(e,t,n){return n=a(n,0),r.pack(e._center,t,n),n+=r.packedLength,l.pack(e._ellipsoid,t,n),n+=l.packedLength,N.pack(e._vertexFormat,t,n),n+=N.packedLength,S.pack(e._rectangle,t,n),n+=S.packedLength,t[n++]=e._semiMajorAxis,t[n++]=e._semiMinorAxis,t[n++]=e._rotation,t[n++]=e._stRotation,t[n++]=e._height,t[n++]=e._granularity,t[n++]=e._extrudedHeight,t[n++]=e._extrude?1:0,t[n]=e._shadowVolume?1:0,t};var re=new r,ne=new l,ie=new N,ae=new S,oe={center:re,ellipsoid:ne,vertexFormat:ie,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,stRotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,shadowVolume:void 0};return D.unpack=function(e,t,n){t=a(t,0);var i=r.unpack(e,t,re);t+=r.packedLength;var u=l.unpack(e,t,ne);t+=l.packedLength;var s=N.unpack(e,t,ie);t+=N.packedLength;var c=S.unpack(e,t,ae);t+=S.packedLength;var f=e[t++],h=e[t++],d=e[t++],p=e[t++],m=e[t++],E=e[t++],y=e[t++],_=1===e[t++],T=1===e[t];return o(n)?(n._center=r.clone(i,n._center),n._ellipsoid=l.clone(u,n._ellipsoid),n._vertexFormat=N.clone(s,n._vertexFormat),n._semiMajorAxis=f,n._semiMinorAxis=h,n._rotation=d,n._stRotation=p,n._height=m,n._granularity=E,n._extrudedHeight=y,n._extrude=_,n._shadowVolume=T,n._rectangle=S.clone(c),n):(oe.height=m,oe.extrudedHeight=y,oe.granularity=E,oe.stRotation=p,oe.rotation=d,oe.semiMajorAxis=f,oe.semiMinorAxis=h,oe.shadowVolume=T,new D(oe))},D.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,r={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,vertexFormat:e._vertexFormat,stRotation:e._stRotation};return e._extrude?(r.extrudedHeight=Math.min(e._extrudedHeight,e._height),r.height=Math.max(e._extrudedHeight,e._height),r.shadowVolume=e._shadowVolume,t=C(r)):t=w(r),new h({attributes:t.attributes,indices:t.indices,primitiveType:R.TRIANGLES,boundingSphere:t.boundingSphere})}},D.createShadowVolume=function(e,t,r){var n=e._granularity,i=e._ellipsoid,a=t(n,i),o=r(n,i);return new D({center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:i,rotation:e._rotation,stRotation:e._stRotation,granularity:n,extrudedHeight:a,height:o,vertexFormat:N.POSITION_ONLY,shadowVolume:!0})},u(D.prototype,{rectangle:{get:function(){return this._rectangle}}}),D}),define("Workers/createEllipseGeometry",["../Core/Cartesian3","../Core/defined","../Core/EllipseGeometry","../Core/Ellipsoid"],function(e,t,r,n){"use strict";function i(i,a){return t(a)&&(i=r.unpack(i,a)),i._center=e.clone(i._center),i._ellipsoid=n.clone(i._ellipsoid),r.createGeometry(i)}return i})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseOutlineGeometry.js index b5fde92f..cebc38a4 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipseOutlineGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var l=new o,T=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:R,s=Math.cos(r);l.x=s*Math.cos(e),l.y=s*Math.sin(e),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(E,l,T);var c=Math.sqrt(o.dot(l,T));return T=o.divideByScalar(T,c,T),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(T,l,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,l=n.z,T=i.x,R=i.y,f=i.z,A=c*c*T*T,h=_*_*R*R,d=l*l*f*f,N=A+h+d,I=Math.sqrt(1/N),S=e.multiplyByScalar(n,I,a);if(N<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,y=u.y,m=u.z,O=o;O.x=S.x*M*2,O.y=S.y*y*2,O.z=S.z*m*2;var p,C,U,w,L,g,x,P,v,F,B,D=(1-I)*e.magnitude(n)/(.5*e.magnitude(O)),z=0;do{D-=z,U=1/(1+D*M),w=1/(1+D*y),L=1/(1+D*m),g=U*U,x=w*w,P=L*L,v=g*U,F=x*w,B=P*L,p=A*g+h*x+d*P-1,C=A*v*M+h*F*y+d*B*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*w,s.z=l*L,s):new e(c*U,_*w,l*L)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),l=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:l,A=r(n)?n._centerToleranceSquared:T,h=o(t,R,f,A,s);if(r(h)){var d=e.multiplyComponents(h,f,E);d=e.normalize(d,d);var N=e.subtract(t,h,c),I=Math.atan2(d.y,d.x),S=Math.asin(d.z),M=a.sign(e.dot(N,t))*e.magnitude(N);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var l=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=l,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var R=new e,f=new e,A=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,f);if(i(a)){var o=this.geodeticSurfaceNormal(a,R),u=e.subtract(n,a,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(f[n],R[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(f[a],R[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=R[i],l=f[i];if(Math.abs(e[E.getElementIndex(l,_)])>n){var T,A=e[E.getElementIndex(l,l)],h=e[E.getElementIndex(_,_)],d=e[E.getElementIndex(l,_)],N=(A-h)/2/d;T=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),s=1/Math.sqrt(1+T*T),c=T*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(l,l)]=s,t[E.getElementIndex(l,_)]=c,t[E.getElementIndex(_,l)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,l=e.z*e.w,T=e.w*e.w,R=n-u-_+T,f=2*(i-l),A=2*(a+c),h=2*(i+l),d=-n+u-_+T,N=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+T;return r(t)?(t[0]=R,t[1]=h,t[2]=I,t[3]=f,t[4]=d,t[5]=S,t[6]=A,t[7]=N,t[8]=M,t):new E(R,f,A,h,d,N,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,l=s*u+a*o*i,T=n*u,R=a*i+s*o*u,f=-s*i+a*o*u,A=-o,h=s*n,d=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=A,t[3]=_,t[4]=R,t[5]=h,t[6]=l,t[7]=f,t[8]=d,t):new E(c,_,l,T,R,f,A,h,d)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var l=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],l)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],l)),n};var T=new e;E.getMaximumScale=function(t){return E.getScale(t,T),e.maximumComponent(T)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var R=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),l=t.diagonal=E.clone(e,t.diagonal),T=n*s(l);a<10&&c(l)>T;)_(l,A),E.transpose(A,h),E.multiply(l,A,l),E.multiply(h,l,l),E.multiply(o,A,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],l=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var T=1/l;return E.multiplyByScalar(t,T,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,l,T,R,f,A){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(l,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,l=t.x*t.w,T=t.y*t.y,R=t.y*t.z,f=t.y*t.w,A=t.z*t.z,h=t.z*t.w,d=t.w*t.w,N=E-T-A+d,I=2*(s-h),S=2*(_+f),M=2*(s+h),y=-E+T-A+d,m=2*(R-l),O=2*(_-f),p=2*(R+l),C=-E-T+A+d;return r[0]=N*a,r[1]=M*a,r[2]=O*a,r[3]=0,r[4]=I*o,r[5]=y*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,l=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,l),l),e.normalize(e.cross(l,_,T),T);var u=l.x,E=l.y,s=l.z,R=_.x,f=_.y,A=_.z,h=T.x,d=T.y,N=T.z,I=r.x,S=r.y,M=r.z,y=u*-I+E*-S+s*-M,m=h*-I+d*-S+N*-M,O=R*I+f*S+A*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-R,n[3]=0,n[4]=E,n[5]=d,n[6]=-f,n[7]=0,n[8]=s,n[9]=N,n[10]=-A,n[11]=0,n[12]=y,n[13]=m,n[14]=O,n[15]=1,n):new c(u,E,s,y,h,d,N,m,-R,-f,-A,O,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,l=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=l,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),l=s,T=c,R=_,f=a+s,A=o+c,h=t+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=R,i[11]=0,i[12]=f,i[13]=A,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var R=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],R)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],R)),n};var f=new e;c.getMaximumScale=function(t){return c.getScale(t,f),e.maximumComponent(f)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],l=e[9],T=e[10],R=e[11],f=e[12],A=e[13],h=e[14],d=e[15],N=t[0],I=t[1],S=t[2],M=t[3],y=t[4],m=t[5],O=t[6],p=t[7],C=t[8],U=t[9],w=t[10],L=t[11],g=t[12],x=t[13],P=t[14],v=t[15],F=r*N+u*I+_*S+f*M,B=i*N+E*I+l*S+A*M,D=a*N+s*I+T*S+h*M,z=o*N+c*I+R*S+d*M,G=r*y+u*m+_*O+f*p,b=i*y+E*m+l*O+A*p,X=a*y+s*m+T*O+h*p,V=o*y+c*m+R*O+d*p,H=r*C+u*U+_*w+f*L,q=i*C+E*U+l*w+A*L,W=a*C+s*U+T*w+h*L,Y=o*C+c*U+R*w+d*L,k=r*g+u*x+_*P+f*v,K=i*g+E*x+l*P+A*v,Z=a*g+s*x+T*P+h*v,j=o*g+c*x+R*P+d*v;return n[0]=F,n[1]=B,n[2]=D,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],l=e[12],T=e[13],R=e[14],f=t[0],A=t[1],h=t[2],d=t[4],N=t[5],I=t[6],S=t[8],M=t[9],y=t[10],m=t[12],O=t[13],p=t[14],C=r*f+o*A+s*h,U=i*f+u*A+c*h,w=a*f+E*A+_*h,L=r*d+o*N+s*I,g=i*d+u*N+c*I,x=a*d+E*N+_*I,P=r*S+o*M+s*y,v=i*S+u*M+c*y,F=a*S+E*M+_*y,B=r*m+o*O+s*p+l,D=i*m+u*O+c*p+T,z=a*m+E*O+_*p+R;return n[0]=C,n[1]=U,n[2]=w,n[3]=0,n[4]=L,n[5]=g,n[6]=x,n[7]=0,n[8]=P,n[9]=v,n[10]=F,n[11]=0,n[12]=B,n[13]=D,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],l=t[0],T=t[1],R=t[2],f=t[3],A=t[4],h=t[5],d=t[6],N=t[7],I=t[8],S=r*l+o*T+s*R,M=i*l+u*T+c*R,y=a*l+E*T+_*R,m=r*f+o*A+s*h,O=i*f+u*A+c*h,p=a*f+E*A+_*h,C=r*d+o*N+s*I,U=i*d+u*N+c*I,w=a*d+E*N+_*I;return n[0]=S,n[1]=M,n[2]=y,n[3]=0,n[4]=m,n[5]=O,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var A=new e;c.multiplyByUniformScale=function(e,t,n){return A.x=t,A.y=t,A.z=t,c.multiplyByScale(e,A,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,d=new E,N=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),d,u.EPSILON7)&&t.equals(c.getRow(e,3,N),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],l=e[5],T=e[9],R=e[13],f=e[2],A=e[6],S=e[10],M=e[14],y=e[3],m=e[7],O=e[11],p=e[15],C=S*p,U=M*O,w=A*p,L=M*m,g=A*O,x=S*m,P=f*p,v=M*y,F=f*O,B=S*y,D=f*m,z=A*y,G=C*l+L*T+g*R-(U*l+w*T+x*R),b=U*_+P*T+B*R-(C*_+v*T+F*R),X=w*_+v*l+D*R-(L*_+P*l+z*R),V=x*_+F*l+z*T-(g*_+B*l+D*T),H=U*i+w*a+x*o-(C*i+L*a+g*o),q=C*r+v*a+F*o-(U*r+P*a+B*o),W=L*r+P*i+z*o-(w*r+v*i+D*o),Y=g*r+B*i+D*a-(x*r+F*i+z*a);C=a*R,U=o*T,w=i*R,L=o*l,g=i*T,x=a*l,P=r*R,v=o*_,F=r*T,B=a*_,D=r*l,z=i*_;var k=C*m+L*O+g*p-(U*m+w*O+x*p),K=U*y+P*O+B*p-(C*y+v*O+F*p),Z=w*y+v*m+D*p-(L*y+P*m+z*p),j=x*y+F*m+z*O-(g*y+B*m+D*O),Q=w*S+x*M+U*A-(g*M+C*A+L*S),J=F*M+C*f+v*S-(P*S+B*M+U*f),$=P*A+z*M+L*f-(D*M+w*f+v*A),ee=D*S+g*f+B*A-(F*A+z*S+x*f),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],l=e[13],T=e[14],R=-n*_-r*l-i*T,f=-a*_-o*l-u*T,A=-E*_-s*l-c*T;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=R,t[13]=f,t[14]=A,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,l=e.length;_<l;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),s=Math.min(s,T.latitude),c=Math.max(c,T.latitude);var R=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,R),o=Math.max(o,R)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,T=-Number.MAX_VALUE,R=0,f=e.length;R<f;R++){var A=t.cartesianToCartographic(e[R]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),l=Math.min(l,A.latitude),T=Math.max(T,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=s,i.north=T,i):new E(o,l,s,T)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var l=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(l>=T))return r(n)?(n.west=c,n.south=l,n.east=_,n.north=T,n):new E(c,l,_,T)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,l=e.south,T=e.east,R=e.west,f=s;f.height=i,f.longitude=R,f.latitude=_,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=l,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:l>0?l:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(e,f)&&(o[c]=t.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function l(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var T=new e,R=new e,f=new e,A=new e,h=new e,d=new e,N=new e,I=new e,S=new e,M=new e,y=new e,m=new e;l.fromPoints=function(t,n){if(i(n)||(n=new l),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],N),o=e.clone(a,T),u=e.clone(a,R),E=e.clone(a,f),s=e.clone(a,A),c=e.clone(a,h),_=e.clone(a,d),O=t.length;for(r=1;r<O;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var w=e.magnitudeSquared(e.subtract(s,o,I)),L=e.magnitudeSquared(e.subtract(c,u,I)),g=e.magnitudeSquared(e.subtract(_,E,I)),x=o,P=s,v=w;L>v&&(v=L,x=u,P=c),g>v&&(v=g,x=E,P=_);var F=S;F.x=.5*(x.x+P.x),F.y=.5*(x.y+P.y),F.z=.5*(x.z+P.z);var B=e.magnitudeSquared(e.subtract(P,F,I)),D=Math.sqrt(B),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=y;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,I),.5,m),X=0;for(r=0;r<O;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,I));V>X&&(X=V);var H=e.magnitudeSquared(e.subtract(a,F,I));if(H>B){var q=Math.sqrt(H);D=.5*(D+q),B=D*D;var W=q-D;F.x=(D*F.x+W*a.x)/q,F.y=(D*F.y+W*a.y)/q,F.z=(D*F.z+W*a.z)/q}}return D<X?(e.clone(F,n.center),n.radius=D):(e.clone(b,n.center),n.radius=X),n};var O=new o,p=new e,C=new e,U=new t,w=new t;l.fromRectangle2D=function(e,t,n){return l.fromRectangleWithHeights2D(e,t,0,0,n)},l.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new l),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),_.southwest(t,U),U.height=a,_.northeast(t,w),w.height=o;var E=n.project(U,p),s=n.project(w,C),c=s.x-E.x,T=s.y-E.y,R=s.z-E.z;u.radius=.5*Math.sqrt(c*c+T*T+R*R);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*T,f.z=E.z+.5*R,u};var L=[];l.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new l),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,L);return l.fromPoints(E,u)},l.fromVertices=function(t,n,a,o){if(i(o)||(o=new l),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=N;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,T),c=e.clone(u,R),_=e.clone(u,f),O=e.clone(u,A),p=e.clone(u,h),C=e.clone(u,d),U=t.length;for(E=0;E<U;E+=a){var w=t[E]+n.x,L=t[E+1]+n.y,g=t[E+2]+n.z;u.x=w,u.y=L,u.z=g,w<s.x&&e.clone(u,s),w>O.x&&e.clone(u,O),L<c.y&&e.clone(u,c),L>p.y&&e.clone(u,p),g<_.z&&e.clone(u,_),g>C.z&&e.clone(u,C)}var x=e.magnitudeSquared(e.subtract(O,s,I)),P=e.magnitudeSquared(e.subtract(p,c,I)),v=e.magnitudeSquared(e.subtract(C,_,I)),F=s,B=O,D=x;P>D&&(D=P,F=c,B=p),v>D&&(D=v,F=_,B=C);var z=S;z.x=.5*(F.x+B.x),z.y=.5*(F.y+B.y),z.z=.5*(F.z+B.z);var G=e.magnitudeSquared(e.subtract(B,z,I)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=y;V.x=O.x,V.y=p.y,V.z=C.z;var H=e.multiplyByScalar(e.add(X,V,I),.5,m),q=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,H,I));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<q?(e.clone(z,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},l.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new l),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=N;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,T),E=e.clone(a,R),s=e.clone(a,f),c=e.clone(a,A),_=e.clone(a,h),O=e.clone(a,d),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],w=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=w,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),w<s.z&&e.clone(a,s),w>O.z&&e.clone(a,O)}var L=e.magnitudeSquared(e.subtract(c,u,I)),g=e.magnitudeSquared(e.subtract(_,E,I)),x=e.magnitudeSquared(e.subtract(O,s,I)),P=u,v=c,F=L;g>F&&(F=g,P=E,v=_),x>F&&(F=x,P=s,v=O);var B=S;B.x=.5*(P.x+v.x),B.y=.5*(P.y+v.y),B.z=.5*(P.z+v.z);var D=e.magnitudeSquared(e.subtract(v,B,I)),z=Math.sqrt(D),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=y;b.x=c.x,b.y=_.y,b.z=O.z;var X=e.multiplyByScalar(e.add(G,b,I),.5,m),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(a,X,I));H>V&&(V=H);var q=e.magnitudeSquared(e.subtract(a,B,I));if(q>D){var W=Math.sqrt(q);z=.5*(z+W),D=z*z;var Y=W-z;B.x=(z*B.x+Y*a.x)/W,B.y=(z*B.y+Y*a.y)/W,B.z=(z*B.z+Y*a.z)/W}}return z<V?(e.clone(B,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},l.fromCornerPoints=function(t,n,r){i(r)||(r=new l);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},l.fromEllipsoid=function(t,n){return i(n)||(n=new l),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var g=new e;l.fromBoundingSpheres=function(t,n){if(i(n)||(n=new l),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return l.clone(t[0],n);if(2===r)return l.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=l.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,g)+s.radius)}return n.radius=E,n};var x=new e,P=new e,v=new e;l.fromOrientedBoundingBox=function(t,n){i(n)||(n=new l);var r=t.halfAxes,a=s.getColumn(r,0,x),o=s.getColumn(r,1,P),u=s.getColumn(r,2,v);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},l.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new l(t.center,t.radius)},l.packedLength=4,l.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},l.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new l);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var F=new e,B=new e;l.union=function(t,n,r){i(r)||(r=new l);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,F),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=e.multiplyByScalar(s,(-o+_)/c,B);return e.add(T,a,T),e.clone(T,r.center),r.radius=_,r};var D=new e;l.expand=function(t,n,r){r=l.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,D));return i>r.radius&&(r.radius=i),r},l.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},l.transform=function(e,t,n){return i(n)||(n=new l),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;l.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},l.transformWithoutScale=function(e,t,n){return i(n)||(n=new l),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;l.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,H=new e,q=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return l.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,q),T=e.negate(s,H),R=Y,f=R[0];e.add(E,c,f),e.add(f,s,f),f=R[1],e.add(E,c,f),e.add(f,T,f),f=R[2],e.add(E,_,f),e.add(f,T,f),f=R[3],e.add(E,_,f),e.add(f,s,f),e.negate(E,E),f=R[4],e.add(E,c,f),e.add(f,s,f),f=R[5],e.add(E,c,f),e.add(f,T,f),f=R[6],e.add(E,_,f),e.add(f,T,f),f=R[7],e.add(E,_,f),e.add(f,s,f);for(var A=R.length,h=0;h<A;++h){var d=R[h];e.add(o,d,d);var N=a.cartesianToCartographic(d,W);n.project(N,d)}i=l.fromPoints(R,i),o=i.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,i},l.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},l.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},l.prototype.intersectPlane=function(e){return l.intersectPlane(this,e)},l.prototype.distanceSquaredTo=function(e){return l.distanceSquaredTo(this,e)},l.prototype.computePlaneDistances=function(e,t,n){return l.computePlaneDistances(this,e,t,n)},l.prototype.isOccluded=function(e){return l.isOccluded(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.prototype.clone=function(e){return l.clone(this,e)},l}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!l())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(y)&&(y=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(y=!0,m=r(e[1]))}return y}function u(){return o()&&m}function E(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(O=!0,p=r(e[1]),p.isNightly=!!e[2])}return O}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function l(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(w=!0,L=r(e[1]))}return w}function T(){return l()&&L}function R(){if(!t(g)){g=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(g=!0,x=r(e[1]))}return g}function f(){return t(P)||(P=/Windows/i.test(I.appVersion)),P}function A(){return R()&&x}function h(){return t(v)||(v="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),v}function d(){if(!t(B)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;B=t(n)&&""!==n,B&&(F=n)}return B}function N(){return d()?F:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,y,m,O,p,C,U,w,L,g,x,P,v,F,B,D={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:l,edgeVersion:T,isFirefox:R,firefoxVersion:A,isWindows:f,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:d,imageRenderingValue:N};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var s=new e;E.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);s=e.normalize(t,s);var u=s.x*o,c=s.y*o,_=s.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=c,i.z=_,i.w=l,i):new E(u,c,_,l)};var c=[1,2,0],_=new Array(3);E.fromRotationMatrix=function(e,t){var n,i,a,o,s,l=e[u.COLUMN0ROW0],T=e[u.COLUMN1ROW1],R=e[u.COLUMN2ROW2],f=l+T+R;if(f>0)n=Math.sqrt(f+1),s=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var A=c,h=0;T>l&&(h=1),R>l&&R>T&&(h=2);var d=A[h],N=A[d];n=Math.sqrt(e[u.getElementIndex(h,h)]-e[u.getElementIndex(d,d)]-e[u.getElementIndex(N,N)]+1);var I=_;I[h]=.5*n,n=.5/n,s=(e[u.getElementIndex(N,d)]-e[u.getElementIndex(d,N)])*n,I[d]=(e[u.getElementIndex(d,h)]+e[u.getElementIndex(h,d)])*n,I[N]=(e[u.getElementIndex(N,h)]+e[u.getElementIndex(h,N)])*n,i=-I[0],a=-I[1],o=-I[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=s,t):new E(i,a,o,s)};var l=new E,T=new E,R=new E,f=new E;E.fromHeadingPitchRoll=function(t,n){return f=E.fromAxisAngle(e.UNIT_X,t.roll,l),R=E.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=E.multiply(R,f,R),T=E.fromAxisAngle(e.UNIT_Z,-t.heading,l),E.multiply(T,n,n)};var A=new e,h=new e,d=new E,N=new E,I=new E;E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},E.packedInterpolationLength=3,E.convertPackedArrayForInterpolation=function(e,t,n,r){E.unpack(e,4*n,I),E.conjugate(I,I);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;E.unpack(e,4*(t+i),d),E.multiply(d,I,d),d.w<0&&E.negate(d,d),E.computeAxis(d,A);var u=E.computeAngle(d);r[o]=A.x*u,r[o+1]=A.y*u,r[o+2]=A.z*u}},E.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new E),e.fromArray(t,0,h);var u=e.magnitude(h);return E.unpack(n,4*a,N),0===u?E.clone(E.IDENTITY,d):E.fromAxisAngle(h,u,d),E.multiply(d,N,o)},E.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new E(e.x,e.y,e.z,e.w)},E.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},E.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},E.magnitude=function(e){return Math.sqrt(E.magnitudeSquared(e))},E.normalize=function(e,t){var n=1/E.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},E.inverse=function(e,t){var n=E.magnitudeSquared(e);return t=E.conjugate(e,t),E.multiplyByScalar(t,1/n,t)},E.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},E.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},E.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},E.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},E.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,E=t.y,s=t.z,c=t.w,_=o*u+r*c+i*s-a*E,l=o*E-r*s+i*c+a*u,T=o*s+r*E-i*u+a*c,R=o*c-r*u-i*E-a*s;return n.x=_,n.y=l,n.z=T,n.w=R,n},E.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},E.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},E.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},E.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var S=new E;E.lerp=function(e,t,n,r){return S=E.multiplyByScalar(t,n,S),r=E.multiplyByScalar(e,1-n,r),E.add(S,r,r)};var M=new E,y=new E,m=new E;E.slerp=function(e,t,n,r){var i=E.dot(e,t),a=t;if(i<0&&(i=-i,a=M=E.negate(t,M)),1-i<o.EPSILON6)return E.lerp(e,a,n,r);var u=Math.acos(i);return y=E.multiplyByScalar(e,Math.sin((1-n)*u),y),m=E.multiplyByScalar(a,Math.sin(n*u),m),r=E.add(y,m,r),E.multiplyByScalar(r,1/Math.sin(u),r)},E.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},E.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,p=new e,C=new E,U=new E;E.computeInnerQuadrangle=function(t,n,r,i){var a=E.conjugate(n,C);E.multiply(a,r,U);var o=E.log(U,O);E.multiply(a,t,U);var u=E.log(U,p);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),E.exp(o,C),E.multiply(n,C,i)},E.squad=function(e,t,n,r,i,a){var o=E.slerp(e,t,i,C),u=E.slerp(n,r,i,U);return E.slerp(o,u,2*i*(1-i),a)};for(var w=new E,L=1.9011074535173003,g=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],v=i.supportsTypedArrays()?new Float32Array(8):[],F=0;F<7;++F){var B=F+1,D=2*B+1;g[F]=1/(B*D),x[F]=B/D}return g[7]=L/136,x[7]=8*L/17,E.fastSlerp=function(e,t,n,r){var i,a=E.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,s=n*n,c=u*u,_=7;_>=0;--_)P[_]=(g[_]*s-x[_])*o,v[_]=(g[_]*c-x[_])*o;var l=i*n*(1+P[0]*(1+P[1]*(1+P[2]*(1+P[3]*(1+P[4]*(1+P[5]*(1+P[6]*(1+P[7])))))))),T=u*(1+v[0]*(1+v[1]*(1+v[2]*(1+v[3]*(1+v[4]*(1+v[5]*(1+v[6]*(1+v[7])))))))),R=E.multiplyByScalar(e,T,w);return E.multiplyByScalar(t,l,r),E.add(R,r,r)},E.fastSquad=function(e,t,n,r,i,a){var o=E.fastSlerp(e,t,i,C),u=E.fastSlerp(n,r,i,U);return E.fastSlerp(o,u,2*i*(1-i),a)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},E.ZERO=a(new E(0,0,0,0)),E.IDENTITY=a(new E(0,0,0,1)),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},E}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,n,r){"use strict";function i(t,i,a,c,_,l,T,R,f,A){var h=t+i;e.multiplyByScalar(c,Math.cos(h),o),e.multiplyByScalar(a,Math.sin(h),u),e.add(o,u,o);var d=Math.cos(t);d*=d;var N=Math.sin(t);N*=N;var I=l/Math.sqrt(T*d+_*N),S=I/R;return r.fromAxisAngle(o,S,E),n.fromQuaternion(E,s),n.multiplyByVector(s,f,A),e.normalize(A,A),e.multiplyByScalar(A,R,A),A}var a={},o=new e,u=new e,E=new r,s=new n,c=new e,_=new e,l=new e,T=new e;a.raisePositionsToHeight=function(t,n,r){for(var i=n.ellipsoid,a=n.height,o=n.extrudedHeight,u=r?t.length/3*2:t.length/3,E=new Float64Array(3*u),s=t.length,R=r?s:0,f=0;f<s;f+=3){var A=f+1,h=f+2,d=e.fromArray(t,f,c);i.scaleToGeodeticSurface(d,d);var N=e.clone(d,_),I=i.geodeticSurfaceNormal(d,T),S=e.multiplyByScalar(I,a,l);e.add(d,S,d),r&&(e.multiplyByScalar(I,o,S),e.add(N,S,N),E[f+R]=N.x,E[A+R]=N.y,E[h+R]=N.z),E[f]=d.x,E[A]=d.y,E[h]=d.z}return E};var R=new e,f=new e,A=new e;return a.computeEllipsePositions=function(n,r,a){var o=n.semiMinorAxis,u=n.semiMajorAxis,E=n.rotation,s=n.center,T=8*n.granularity,h=o*o,d=u*u,N=u*o,I=e.magnitude(s),S=e.normalize(s,R),M=e.cross(e.UNIT_Z,s,f);M=e.normalize(M,M);var y=e.cross(S,M,A),m=1+Math.ceil(t.PI_OVER_TWO/T),O=t.PI_OVER_TWO/(m-1),p=t.PI_OVER_TWO-m*O;p<0&&(m-=Math.ceil(Math.abs(p)/O));var C,U,w,L,g,x=m*(m+2)*2,P=r?new Array(3*x):void 0,v=0,F=c,B=_,D=4*m*3,z=D-1,G=0,b=a?new Array(D):void 0;for(p=t.PI_OVER_TWO,F=i(p,E,y,M,h,N,d,I,S,F),r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x),p=t.PI_OVER_TWO-O,C=1;C<m+1;++C){if(F=i(p,E,y,M,h,N,d,I,S,F),B=i(Math.PI-p,E,y,M,h,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,w=2*C+2,U=1;U<w-1;++U)L=U/(w-1),g=e.lerp(F,B,L,l),P[v++]=g.x,P[v++]=g.y,P[v++]=g.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z),p=t.PI_OVER_TWO-(C+1)*O}for(C=m;C>1;--C){if(p=t.PI_OVER_TWO-(C-1)*O,F=i(-p,E,y,M,h,N,d,I,S,F),B=i(p+Math.PI,E,y,M,h,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,w=2*(C-1)+2,U=1;U<w-1;++U)L=U/(w-1),g=e.lerp(F,B,L,l),P[v++]=g.x,P[v++]=g.y,P[v++]=g.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z)}p=t.PI_OVER_TWO,F=i(-p,E,y,M,h,N,d,I,S,F);var X={};return r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,X.positions=P,X.numPts=m),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,X.outerPositions=b),X},a}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipseOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s,c,_,l,T){"use strict";function R(r){var i=r.center;d=t.multiplyByScalar(r.ellipsoid.geodeticSurfaceNormal(i,d),r.height,d),d=t.add(i,d,d);for(var a=new e(d,r.semiMajorAxis),u=o.computeEllipsePositions(r,!1,!0).outerPositions,E=new c({position:new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(u,r,!1)})}),l=u.length/3,T=_.createTypedArray(l,2*l),R=0,f=0;f<l;++f)T[R++]=f,T[R++]=(f+1)%l;return{boundingSphere:a,attributes:E,indices:T}}function f(i){var a=i.center,u=i.ellipsoid,E=i.semiMajorAxis,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,h),i.height,h);N.center=t.add(a,T,N.center),N.radius=E,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,T),i.extrudedHeight,T),I.center=t.add(a,T,I.center),I.radius=E;var R=o.computeEllipsePositions(i,!1,!0).outerPositions,f=new c({position:new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(R,i,!0)})});R=f.position.values;var A=e.union(N,I),d=R.length/3,S=r(i.numberOfVerticalLines,16);S=l.clamp(S,0,d/2);var M=_.createTypedArray(d,2*d+2*S);d/=2;var y,m=0;for(y=0;y<d;++y)M[m++]=y,M[m++]=(y+1)%d,M[m++]=y+d,M[m++]=(y+1)%d+d;var O;if(S>0){var p=Math.min(S,d);O=Math.round(d/p);var C=Math.min(O*S,d);for(y=0;y<C;y+=O)M[m++]=y,M[m++]=y+d}return{boundingSphere:A,attributes:f,indices:M}}function A(e){e=r(e,r.EMPTY_OBJECT);var n=e.center,a=r(e.ellipsoid,u.WGS84),o=e.semiMajorAxis,E=e.semiMinorAxis,s=r(e.granularity,l.RADIANS_PER_DEGREE),c=r(e.height,0),_=e.extrudedHeight,T=i(_)&&Math.abs(c-_)>1;this._center=t.clone(n),this._semiMajorAxis=o,this._semiMinorAxis=E,this._ellipsoid=u.clone(a),this._rotation=r(e.rotation,0),this._height=c,this._granularity=s,this._extrudedHeight=_,this._extrude=T,this._numberOfVerticalLines=Math.max(r(e.numberOfVerticalLines,16),0),this._workerName="createEllipseOutlineGeometry"}var h=new t,d=new t,N=new e,I=new e;A.packedLength=t.packedLength+u.packedLength+9,A.pack=function(e,n,a){return a=r(a,0),t.pack(e._center,n,a),a+=t.packedLength,u.pack(e._ellipsoid,n,a),a+=u.packedLength,n[a++]=e._semiMajorAxis,n[a++]=e._semiMinorAxis,n[a++]=e._rotation,n[a++]=e._height,n[a++]=e._granularity,n[a++]=i(e._extrudedHeight)?1:0,n[a++]=r(e._extrudedHeight,0),n[a++]=e._extrude?1:0,n[a]=e._numberOfVerticalLines,n};var S=new t,M=new u,y={center:S,ellipsoid:M,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,numberOfVerticalLines:void 0};return A.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,S);n+=t.packedLength;var E=u.unpack(e,n,M);n+=u.packedLength;var s=e[n++],c=e[n++],_=e[n++],l=e[n++],T=e[n++],R=e[n++],f=e[n++],h=1===e[n++],d=e[n];return i(a)?(a._center=t.clone(o,a._center),a._ellipsoid=u.clone(E,a._ellipsoid),a._semiMajorAxis=s,a._semiMinorAxis=c,a._rotation=_,a._height=l,a._granularity=T,a._extrudedHeight=R?f:void 0,a._extrude=h,a._numberOfVerticalLines=d,a):(y.height=l,y.extrudedHeight=R?f:void 0,y.granularity=T,y.rotation=_,y.semiMajorAxis=s,y.semiMinorAxis=c,y.numberOfVerticalLines=d,new A(y))},A.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,n={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height, -extrudedHeight:e._extrudedHeight,granularity:e._granularity,numberOfVerticalLines:e._numberOfVerticalLines};return e._extrude?(n.extrudedHeight=Math.min(e._extrudedHeight,e._height),n.height=Math.max(e._extrudedHeight,e._height),t=f(n)):t=R(n),new E({attributes:t.attributes,indices:t.indices,primitiveType:T.LINES,boundingSphere:t.boundingSphere})}},A}),define("Workers/createEllipseOutlineGeometry",["../Core/Cartesian3","../Core/defined","../Core/EllipseOutlineGeometry","../Core/Ellipsoid"],function(e,t,n,r){"use strict";function i(i,a){return t(a)&&(i=n.unpack(i,a)),i._center=e.clone(i._center),i._ellipsoid=r.clone(i._ellipsoid),n.createGeometry(i)}return i})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var l=new o,T=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:R,s=Math.cos(r);l.x=s*Math.cos(e),l.y=s*Math.sin(e),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(E,l,T);var c=Math.sqrt(o.dot(l,T));return T=o.divideByScalar(T,c,T),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(T,l,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,l=n.z,T=i.x,R=i.y,f=i.z,A=c*c*T*T,h=_*_*R*R,d=l*l*f*f,N=A+h+d,I=Math.sqrt(1/N),S=e.multiplyByScalar(n,I,a);if(N<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,y=u.y,m=u.z,O=o;O.x=S.x*M*2,O.y=S.y*y*2,O.z=S.z*m*2;var p,C,U,w,L,g,x,P,v,F,B,D=(1-I)*e.magnitude(n)/(.5*e.magnitude(O)),z=0;do{D-=z,U=1/(1+D*M),w=1/(1+D*y),L=1/(1+D*m),g=U*U,x=w*w,P=L*L,v=g*U,F=x*w,B=P*L,p=A*g+h*x+d*P-1,C=A*v*M+h*F*y+d*B*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*w,s.z=l*L,s):new e(c*U,_*w,l*L)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),l=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:l,A=r(n)?n._centerToleranceSquared:T,h=o(t,R,f,A,s);if(r(h)){var d=e.multiplyComponents(h,f,E);d=e.normalize(d,d);var N=e.subtract(t,h,c),I=Math.atan2(d.y,d.x),S=Math.asin(d.z),M=a.sign(e.dot(N,t))*e.magnitude(N);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var l=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=l,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var R=new e,f=new e,A=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,f);if(i(a)){var o=this.geodeticSurfaceNormal(a,R),u=e.subtract(n,a,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(f[n],R[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(f[a],R[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=R[i],l=f[i];if(Math.abs(e[E.getElementIndex(l,_)])>n){var T,A=e[E.getElementIndex(l,l)],h=e[E.getElementIndex(_,_)],d=e[E.getElementIndex(l,_)],N=(A-h)/2/d;T=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),s=1/Math.sqrt(1+T*T),c=T*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(l,l)]=s,t[E.getElementIndex(l,_)]=c,t[E.getElementIndex(_,l)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,l=e.z*e.w,T=e.w*e.w,R=n-u-_+T,f=2*(i-l),A=2*(a+c),h=2*(i+l),d=-n+u-_+T,N=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+T;return r(t)?(t[0]=R,t[1]=h,t[2]=I,t[3]=f,t[4]=d,t[5]=S,t[6]=A,t[7]=N,t[8]=M,t):new E(R,f,A,h,d,N,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,l=s*u+a*o*i,T=n*u,R=a*i+s*o*u,f=-s*i+a*o*u,A=-o,h=s*n,d=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=A,t[3]=_,t[4]=R,t[5]=h,t[6]=l,t[7]=f,t[8]=d,t):new E(c,_,l,T,R,f,A,h,d)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var l=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],l)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],l)),n};var T=new e;E.getMaximumScale=function(t){return E.getScale(t,T),e.maximumComponent(T)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var R=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),l=t.diagonal=E.clone(e,t.diagonal),T=n*s(l);a<10&&c(l)>T;)_(l,A),E.transpose(A,h),E.multiply(l,A,l),E.multiply(h,l,l),E.multiply(o,A,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],l=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var T=1/l;return E.multiplyByScalar(t,T,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,l,T,R,f,A){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(l,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,l=t.x*t.w,T=t.y*t.y,R=t.y*t.z,f=t.y*t.w,A=t.z*t.z,h=t.z*t.w,d=t.w*t.w,N=E-T-A+d,I=2*(s-h),S=2*(_+f),M=2*(s+h),y=-E+T-A+d,m=2*(R-l),O=2*(_-f),p=2*(R+l),C=-E-T+A+d;return r[0]=N*a,r[1]=M*a,r[2]=O*a,r[3]=0,r[4]=I*o,r[5]=y*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,l=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,l),l),e.normalize(e.cross(l,_,T),T);var u=l.x,E=l.y,s=l.z,R=_.x,f=_.y,A=_.z,h=T.x,d=T.y,N=T.z,I=r.x,S=r.y,M=r.z,y=u*-I+E*-S+s*-M,m=h*-I+d*-S+N*-M,O=R*I+f*S+A*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-R,n[3]=0,n[4]=E,n[5]=d,n[6]=-f,n[7]=0,n[8]=s,n[9]=N,n[10]=-A,n[11]=0,n[12]=y,n[13]=m,n[14]=O,n[15]=1,n):new c(u,E,s,y,h,d,N,m,-R,-f,-A,O,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,l=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=l,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),l=s,T=c,R=_,f=a+s,A=o+c,h=t+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=R,i[11]=0,i[12]=f,i[13]=A,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var R=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],R)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],R)),n};var f=new e;c.getMaximumScale=function(t){return c.getScale(t,f),e.maximumComponent(f)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],l=e[9],T=e[10],R=e[11],f=e[12],A=e[13],h=e[14],d=e[15],N=t[0],I=t[1],S=t[2],M=t[3],y=t[4],m=t[5],O=t[6],p=t[7],C=t[8],U=t[9],w=t[10],L=t[11],g=t[12],x=t[13],P=t[14],v=t[15],F=r*N+u*I+_*S+f*M,B=i*N+E*I+l*S+A*M,D=a*N+s*I+T*S+h*M,z=o*N+c*I+R*S+d*M,G=r*y+u*m+_*O+f*p,b=i*y+E*m+l*O+A*p,X=a*y+s*m+T*O+h*p,V=o*y+c*m+R*O+d*p,H=r*C+u*U+_*w+f*L,q=i*C+E*U+l*w+A*L,W=a*C+s*U+T*w+h*L,Y=o*C+c*U+R*w+d*L,k=r*g+u*x+_*P+f*v,K=i*g+E*x+l*P+A*v,Z=a*g+s*x+T*P+h*v,j=o*g+c*x+R*P+d*v;return n[0]=F,n[1]=B,n[2]=D,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],l=e[12],T=e[13],R=e[14],f=t[0],A=t[1],h=t[2],d=t[4],N=t[5],I=t[6],S=t[8],M=t[9],y=t[10],m=t[12],O=t[13],p=t[14],C=r*f+o*A+s*h,U=i*f+u*A+c*h,w=a*f+E*A+_*h,L=r*d+o*N+s*I,g=i*d+u*N+c*I,x=a*d+E*N+_*I,P=r*S+o*M+s*y,v=i*S+u*M+c*y,F=a*S+E*M+_*y,B=r*m+o*O+s*p+l,D=i*m+u*O+c*p+T,z=a*m+E*O+_*p+R;return n[0]=C,n[1]=U,n[2]=w,n[3]=0,n[4]=L,n[5]=g,n[6]=x,n[7]=0,n[8]=P,n[9]=v,n[10]=F,n[11]=0,n[12]=B,n[13]=D,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],l=t[0],T=t[1],R=t[2],f=t[3],A=t[4],h=t[5],d=t[6],N=t[7],I=t[8],S=r*l+o*T+s*R,M=i*l+u*T+c*R,y=a*l+E*T+_*R,m=r*f+o*A+s*h,O=i*f+u*A+c*h,p=a*f+E*A+_*h,C=r*d+o*N+s*I,U=i*d+u*N+c*I,w=a*d+E*N+_*I;return n[0]=S,n[1]=M,n[2]=y,n[3]=0,n[4]=m,n[5]=O,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var A=new e;c.multiplyByUniformScale=function(e,t,n){return A.x=t,A.y=t,A.z=t,c.multiplyByScale(e,A,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,d=new E,N=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),d,u.EPSILON7)&&t.equals(c.getRow(e,3,N),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],l=e[5],T=e[9],R=e[13],f=e[2],A=e[6],S=e[10],M=e[14],y=e[3],m=e[7],O=e[11],p=e[15],C=S*p,U=M*O,w=A*p,L=M*m,g=A*O,x=S*m,P=f*p,v=M*y,F=f*O,B=S*y,D=f*m,z=A*y,G=C*l+L*T+g*R-(U*l+w*T+x*R),b=U*_+P*T+B*R-(C*_+v*T+F*R),X=w*_+v*l+D*R-(L*_+P*l+z*R),V=x*_+F*l+z*T-(g*_+B*l+D*T),H=U*i+w*a+x*o-(C*i+L*a+g*o),q=C*r+v*a+F*o-(U*r+P*a+B*o),W=L*r+P*i+z*o-(w*r+v*i+D*o),Y=g*r+B*i+D*a-(x*r+F*i+z*a);C=a*R,U=o*T,w=i*R,L=o*l,g=i*T,x=a*l,P=r*R,v=o*_,F=r*T,B=a*_,D=r*l,z=i*_;var k=C*m+L*O+g*p-(U*m+w*O+x*p),K=U*y+P*O+B*p-(C*y+v*O+F*p),Z=w*y+v*m+D*p-(L*y+P*m+z*p),j=x*y+F*m+z*O-(g*y+B*m+D*O),Q=w*S+x*M+U*A-(g*M+C*A+L*S),J=F*M+C*f+v*S-(P*S+B*M+U*f),$=P*A+z*M+L*f-(D*M+w*f+v*A),ee=D*S+g*f+B*A-(F*A+z*S+x*f),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],l=e[13],T=e[14],R=-n*_-r*l-i*T,f=-a*_-o*l-u*T,A=-E*_-s*l-c*T;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=R,t[13]=f,t[14]=A,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,l=e.length;_<l;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),s=Math.min(s,T.latitude),c=Math.max(c,T.latitude);var R=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,R),o=Math.max(o,R)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,T=-Number.MAX_VALUE,R=0,f=e.length;R<f;R++){var A=t.cartesianToCartographic(e[R]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),l=Math.min(l,A.latitude),T=Math.max(T,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=s,i.north=T,i):new E(o,l,s,T)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var l=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(l>=T))return r(n)?(n.west=c,n.south=l,n.east=_,n.north=T,n):new E(c,l,_,T)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,l=e.south,T=e.east,R=e.west,f=s;f.height=i,f.longitude=R,f.latitude=_,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=l,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:l>0?l:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(e,f)&&(o[c]=t.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=t.cartographicToCartesian(f,o[c]),c++,f.longitude=T,o[c]=t.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_,l){"use strict";function T(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var R=new e,f=new e,A=new e,h=new e,d=new e,N=new e,I=new e,S=new e,M=new e,y=new e,m=new e,O=new e,p=4/3*n.PI;T.fromPoints=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],I),o=e.clone(i,R),u=e.clone(i,f),E=e.clone(i,A),s=e.clone(i,h),c=e.clone(i,d),_=e.clone(i,N),l=t.length;for(r=1;r<l;r++){e.clone(t[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&e.clone(i,o),p>s.x&&e.clone(i,s),C<u.y&&e.clone(i,u),C>c.y&&e.clone(i,c),U<E.z&&e.clone(i,E),U>_.z&&e.clone(i,_)}var w=e.magnitudeSquared(e.subtract(s,o,S)),L=e.magnitudeSquared(e.subtract(c,u,S)),g=e.magnitudeSquared(e.subtract(_,E,S)),x=o,P=s,v=w;L>v&&(v=L,x=u,P=c),g>v&&(v=g,x=E,P=_);var F=M;F.x=.5*(x.x+P.x),F.y=.5*(x.y+P.y),F.z=.5*(x.z+P.z);var B=e.magnitudeSquared(e.subtract(P,F,S)),D=Math.sqrt(B),z=y;z.x=o.x,z.y=u.y,z.z=E.z;var G=m;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,S),.5,O),X=0;for(r=0;r<l;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,b,S));V>X&&(X=V);var H=e.magnitudeSquared(e.subtract(i,F,S));if(H>B){var q=Math.sqrt(H);D=.5*(D+q),B=D*D;var W=q-D;F.x=(D*F.x+W*i.x)/q,F.y=(D*F.y+W*i.y)/q,F.z=(D*F.z+W*i.z)/q}}return D<X?(e.clone(F,n.center),n.radius=D):(e.clone(b,n.center),n.radius=X),n};var C=new u,U=new e,w=new e,L=new t,g=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,C),l.southwest(t,L),L.height=r,l.northeast(t,g),g.height=o;var E=n.project(L,U),s=n.project(g,w),c=s.x-E.x,_=s.y-E.y,R=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+R*R);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*_,f.z=E.z+.5*R,u};var x=[];T.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=l.subsample(t,n,r,x);return T.fromPoints(E,u)},T.fromVertices=function(t,n,r,o){if(a(o)||(o=new T),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=I;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,R),c=e.clone(u,f),_=e.clone(u,A),l=e.clone(u,h),p=e.clone(u,d),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=r){var w=t[E]+n.x,L=t[E+1]+n.y,g=t[E+2]+n.z;u.x=w,u.y=L,u.z=g,w<s.x&&e.clone(u,s),w>l.x&&e.clone(u,l),L<c.y&&e.clone(u,c),L>p.y&&e.clone(u,p),g<_.z&&e.clone(u,_),g>C.z&&e.clone(u,C)}var x=e.magnitudeSquared(e.subtract(l,s,S)),P=e.magnitudeSquared(e.subtract(p,c,S)),v=e.magnitudeSquared(e.subtract(C,_,S)),F=s,B=l,D=x;P>D&&(D=P,F=c,B=p),v>D&&(D=v,F=_,B=C);var z=M;z.x=.5*(F.x+B.x),z.y=.5*(F.y+B.y),z.z=.5*(F.z+B.z);var G=e.magnitudeSquared(e.subtract(B,z,S)),b=Math.sqrt(G),X=y;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=l.x,V.y=p.y,V.z=C.z;var H=e.multiplyByScalar(e.add(X,V,S),.5,O),q=0;for(E=0;E<U;E+=r){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,H,S));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<q?(e.clone(z,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},T.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new T),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=I;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,R),E=e.clone(i,f),s=e.clone(i,A),c=e.clone(i,h),_=e.clone(i,d),l=e.clone(i,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=C,i.y=U,i.z=w,C<u.x&&e.clone(i,u),C>c.x&&e.clone(i,c),U<E.y&&e.clone(i,E),U>_.y&&e.clone(i,_),w<s.z&&e.clone(i,s),w>l.z&&e.clone(i,l)}var L=e.magnitudeSquared(e.subtract(c,u,S)),g=e.magnitudeSquared(e.subtract(_,E,S)),x=e.magnitudeSquared(e.subtract(l,s,S)),P=u,v=c,F=L;g>F&&(F=g,P=E,v=_),x>F&&(F=x,P=s,v=l);var B=M;B.x=.5*(P.x+v.x),B.y=.5*(P.y+v.y),B.z=.5*(P.z+v.z);var D=e.magnitudeSquared(e.subtract(v,B,S)),z=Math.sqrt(D),G=y;G.x=u.x,G.y=E.y,G.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=l.z;var X=e.multiplyByScalar(e.add(G,b,S),.5,O),V=0;for(o=0;o<p;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(i,X,S));H>V&&(V=H);var q=e.magnitudeSquared(e.subtract(i,B,S));if(q>D){var W=Math.sqrt(q);z=.5*(z+W),D=z*z;var Y=W-z;B.x=(z*B.x+Y*i.x)/W,B.y=(z*B.y+Y*i.y)/W,B.z=(z*B.z+Y*i.z)/W}}return z<V?(e.clone(B,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){a(r)||(r=new T);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},T.fromEllipsoid=function(t,n){return a(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var P=new e;T.fromBoundingSpheres=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=t[i];E=Math.max(E,e.distance(u,s.center,P)+s.radius)}return n.radius=E,n};var v=new e,F=new e,B=new e;T.fromOrientedBoundingBox=function(t,n){a(n)||(n=new T);var r=t.halfAxes,i=c.getColumn(r,0,v),o=c.getColumn(r,1,F),u=c.getColumn(r,2,B);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},T.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new T);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var D=new e,z=new e;T.union=function(t,n,r){a(r)||(r=new T);var i=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,i,D),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),l=e.multiplyByScalar(s,(-o+_)/c,z);return e.add(l,i,l),e.clone(l,r.center),r.radius=_,r};var G=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},T.transform=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=_.getMaximumScale(t)*e.radius,n};var b=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var X=new e;T.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,X),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,H=new e,q=new e,W=new e,Y=new e,k=new t,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new e;var j=new u;return T.projectTo2D=function(t,n,r){n=i(n,j);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,V),s=e.cross(e.UNIT_Z,E,H);e.normalize(s,s);var c=e.cross(E,s,q);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,Y),l=e.negate(s,W),R=K,f=R[0];e.add(E,c,f),e.add(f,s,f),f=R[1],e.add(E,c,f),e.add(f,l,f),f=R[2],e.add(E,_,f),e.add(f,l,f),f=R[3],e.add(E,_,f),e.add(f,s,f),e.negate(E,E),f=R[4],e.add(E,c,f),e.add(f,s,f),f=R[5],e.add(E,c,f),e.add(f,l,f),f=R[6],e.add(E,_,f),e.add(f,l,f),f=R[7],e.add(E,_,f),e.add(f,s,f);for(var A=R.length,h=0;h<A;++h){var d=R[h];e.add(o,d,d);var N=a.cartesianToCartographic(d,k);n.project(N,d)}r=T.fromPoints(R,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T.prototype.volume=function(){var e=this.radius;return p*e*e*e},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!l())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(y)&&(y=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(y=!0,m=r(e[1]))}return y}function u(){return o()&&m}function E(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(O=!0, +p=r(e[1]),p.isNightly=!!e[2])}return O}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function l(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(w=!0,L=r(e[1]))}return w}function T(){return l()&&L}function R(){if(!t(g)){g=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(g=!0,x=r(e[1]))}return g}function f(){return t(P)||(P=/Windows/i.test(I.appVersion)),P}function A(){return R()&&x}function h(){return t(v)||(v="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),v}function d(){if(!t(B)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;B=t(n)&&""!==n,B&&(F=n)}return B}function N(){return d()?F:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,y,m,O,p,C,U,w,L,g,x,P,v,F,B,D={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:l,edgeVersion:T,isFirefox:R,firefoxVersion:A,isWindows:f,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:d,imageRenderingValue:N};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var s=new e;E.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);s=e.normalize(t,s);var u=s.x*o,c=s.y*o,_=s.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=c,i.z=_,i.w=l,i):new E(u,c,_,l)};var c=[1,2,0],_=new Array(3);E.fromRotationMatrix=function(e,t){var n,i,a,o,s,l=e[u.COLUMN0ROW0],T=e[u.COLUMN1ROW1],R=e[u.COLUMN2ROW2],f=l+T+R;if(f>0)n=Math.sqrt(f+1),s=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var A=c,h=0;T>l&&(h=1),R>l&&R>T&&(h=2);var d=A[h],N=A[d];n=Math.sqrt(e[u.getElementIndex(h,h)]-e[u.getElementIndex(d,d)]-e[u.getElementIndex(N,N)]+1);var I=_;I[h]=.5*n,n=.5/n,s=(e[u.getElementIndex(N,d)]-e[u.getElementIndex(d,N)])*n,I[d]=(e[u.getElementIndex(d,h)]+e[u.getElementIndex(h,d)])*n,I[N]=(e[u.getElementIndex(N,h)]+e[u.getElementIndex(h,N)])*n,i=-I[0],a=-I[1],o=-I[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=s,t):new E(i,a,o,s)};var l=new E,T=new E,R=new E,f=new E;E.fromHeadingPitchRoll=function(t,n){return f=E.fromAxisAngle(e.UNIT_X,t.roll,l),R=E.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=E.multiply(R,f,R),T=E.fromAxisAngle(e.UNIT_Z,-t.heading,l),E.multiply(T,n,n)};var A=new e,h=new e,d=new E,N=new E,I=new E;E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},E.packedInterpolationLength=3,E.convertPackedArrayForInterpolation=function(e,t,n,r){E.unpack(e,4*n,I),E.conjugate(I,I);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;E.unpack(e,4*(t+i),d),E.multiply(d,I,d),d.w<0&&E.negate(d,d),E.computeAxis(d,A);var u=E.computeAngle(d);r[o]=A.x*u,r[o+1]=A.y*u,r[o+2]=A.z*u}},E.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new E),e.fromArray(t,0,h);var u=e.magnitude(h);return E.unpack(n,4*a,N),0===u?E.clone(E.IDENTITY,d):E.fromAxisAngle(h,u,d),E.multiply(d,N,o)},E.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new E(e.x,e.y,e.z,e.w)},E.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},E.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},E.magnitude=function(e){return Math.sqrt(E.magnitudeSquared(e))},E.normalize=function(e,t){var n=1/E.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},E.inverse=function(e,t){var n=E.magnitudeSquared(e);return t=E.conjugate(e,t),E.multiplyByScalar(t,1/n,t)},E.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},E.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},E.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},E.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},E.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,E=t.y,s=t.z,c=t.w,_=o*u+r*c+i*s-a*E,l=o*E-r*s+i*c+a*u,T=o*s+r*E-i*u+a*c,R=o*c-r*u-i*E-a*s;return n.x=_,n.y=l,n.z=T,n.w=R,n},E.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},E.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},E.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},E.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var S=new E;E.lerp=function(e,t,n,r){return S=E.multiplyByScalar(t,n,S),r=E.multiplyByScalar(e,1-n,r),E.add(S,r,r)};var M=new E,y=new E,m=new E;E.slerp=function(e,t,n,r){var i=E.dot(e,t),a=t;if(i<0&&(i=-i,a=M=E.negate(t,M)),1-i<o.EPSILON6)return E.lerp(e,a,n,r);var u=Math.acos(i);return y=E.multiplyByScalar(e,Math.sin((1-n)*u),y),m=E.multiplyByScalar(a,Math.sin(n*u),m),r=E.add(y,m,r),E.multiplyByScalar(r,1/Math.sin(u),r)},E.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},E.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,p=new e,C=new E,U=new E;E.computeInnerQuadrangle=function(t,n,r,i){var a=E.conjugate(n,C);E.multiply(a,r,U);var o=E.log(U,O);E.multiply(a,t,U);var u=E.log(U,p);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),E.exp(o,C),E.multiply(n,C,i)},E.squad=function(e,t,n,r,i,a){var o=E.slerp(e,t,i,C),u=E.slerp(n,r,i,U);return E.slerp(o,u,2*i*(1-i),a)};for(var w=new E,L=1.9011074535173003,g=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],v=i.supportsTypedArrays()?new Float32Array(8):[],F=0;F<7;++F){var B=F+1,D=2*B+1;g[F]=1/(B*D),x[F]=B/D}return g[7]=L/136,x[7]=8*L/17,E.fastSlerp=function(e,t,n,r){var i,a=E.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,s=n*n,c=u*u,_=7;_>=0;--_)P[_]=(g[_]*s-x[_])*o,v[_]=(g[_]*c-x[_])*o;var l=i*n*(1+P[0]*(1+P[1]*(1+P[2]*(1+P[3]*(1+P[4]*(1+P[5]*(1+P[6]*(1+P[7])))))))),T=u*(1+v[0]*(1+v[1]*(1+v[2]*(1+v[3]*(1+v[4]*(1+v[5]*(1+v[6]*(1+v[7])))))))),R=E.multiplyByScalar(e,T,w);return E.multiplyByScalar(t,l,r),E.add(R,r,r)},E.fastSquad=function(e,t,n,r,i,a){var o=E.fastSlerp(e,t,i,C),u=E.fastSlerp(n,r,i,U);return E.fastSlerp(o,u,2*i*(1-i),a)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},E.ZERO=a(new E(0,0,0,0)),E.IDENTITY=a(new E(0,0,0,1)),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},E}),define("Core/EllipseGeometryLibrary",["./Cartesian3","./Math","./Matrix3","./Quaternion"],function(e,t,n,r){"use strict";function i(t,i,a,c,_,l,T,R,f,A){var h=t+i;e.multiplyByScalar(c,Math.cos(h),o),e.multiplyByScalar(a,Math.sin(h),u),e.add(o,u,o);var d=Math.cos(t);d*=d;var N=Math.sin(t);N*=N;var I=l/Math.sqrt(T*d+_*N),S=I/R;return r.fromAxisAngle(o,S,E),n.fromQuaternion(E,s),n.multiplyByVector(s,f,A),e.normalize(A,A),e.multiplyByScalar(A,R,A),A}var a={},o=new e,u=new e,E=new r,s=new n,c=new e,_=new e,l=new e,T=new e;a.raisePositionsToHeight=function(t,n,r){for(var i=n.ellipsoid,a=n.height,o=n.extrudedHeight,u=r?t.length/3*2:t.length/3,E=new Float64Array(3*u),s=t.length,R=r?s:0,f=0;f<s;f+=3){var A=f+1,h=f+2,d=e.fromArray(t,f,c);i.scaleToGeodeticSurface(d,d);var N=e.clone(d,_),I=i.geodeticSurfaceNormal(d,T),S=e.multiplyByScalar(I,a,l);e.add(d,S,d),r&&(e.multiplyByScalar(I,o,S),e.add(N,S,N),E[f+R]=N.x,E[A+R]=N.y,E[h+R]=N.z),E[f]=d.x,E[A]=d.y,E[h]=d.z}return E};var R=new e,f=new e,A=new e;return a.computeEllipsePositions=function(n,r,a){var o=n.semiMinorAxis,u=n.semiMajorAxis,E=n.rotation,s=n.center,T=8*n.granularity,h=o*o,d=u*u,N=u*o,I=e.magnitude(s),S=e.normalize(s,R),M=e.cross(e.UNIT_Z,s,f);M=e.normalize(M,M);var y=e.cross(S,M,A),m=1+Math.ceil(t.PI_OVER_TWO/T),O=t.PI_OVER_TWO/(m-1),p=t.PI_OVER_TWO-m*O;p<0&&(m-=Math.ceil(Math.abs(p)/O));var C,U,w,L,g,x=m*(m+2)*2,P=r?new Array(3*x):void 0,v=0,F=c,B=_,D=4*m*3,z=D-1,G=0,b=a?new Array(D):void 0;for(p=t.PI_OVER_TWO,F=i(p,E,y,M,h,N,d,I,S,F),r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x),p=t.PI_OVER_TWO-O,C=1;C<m+1;++C){if(F=i(p,E,y,M,h,N,d,I,S,F),B=i(Math.PI-p,E,y,M,h,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,w=2*C+2,U=1;U<w-1;++U)L=U/(w-1),g=e.lerp(F,B,L,l),P[v++]=g.x,P[v++]=g.y,P[v++]=g.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z),p=t.PI_OVER_TWO-(C+1)*O}for(C=m;C>1;--C){if(p=t.PI_OVER_TWO-(C-1)*O,F=i(-p,E,y,M,h,N,d,I,S,F),B=i(p+Math.PI,E,y,M,h,N,d,I,S,B),r){for(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,w=2*(C-1)+2,U=1;U<w-1;++U)L=U/(w-1),g=e.lerp(F,B,L,l),P[v++]=g.x,P[v++]=g.y,P[v++]=g.z;P[v++]=B.x,P[v++]=B.y,P[v++]=B.z}a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,b[G++]=B.x,b[G++]=B.y,b[G++]=B.z)}p=t.PI_OVER_TWO,F=i(-p,E,y,M,h,N,d,I,S,F);var X={};return r&&(P[v++]=F.x,P[v++]=F.y,P[v++]=F.z,X.positions=P,X.numPts=m),a&&(b[z--]=F.z,b[z--]=F.y,b[z--]=F.x,X.outerPositions=b),X},a}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipseOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EllipseGeometryLibrary","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s,c,_,l,T){"use strict";function R(r){var i=r.center;d=t.multiplyByScalar(r.ellipsoid.geodeticSurfaceNormal(i,d),r.height,d),d=t.add(i,d,d);for(var a=new e(d,r.semiMajorAxis),u=o.computeEllipsePositions(r,!1,!0).outerPositions,E=new c({position:new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(u,r,!1)})}),l=u.length/3,T=_.createTypedArray(l,2*l),R=0,f=0;f<l;++f)T[R++]=f,T[R++]=(f+1)%l;return{boundingSphere:a,attributes:E,indices:T}}function f(i){var a=i.center,u=i.ellipsoid,E=i.semiMajorAxis,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,h),i.height,h);N.center=t.add(a,T,N.center),N.radius=E,T=t.multiplyByScalar(u.geodeticSurfaceNormal(a,T),i.extrudedHeight,T),I.center=t.add(a,T,I.center),I.radius=E;var R=o.computeEllipsePositions(i,!1,!0).outerPositions,f=new c({position:new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:o.raisePositionsToHeight(R,i,!0)})});R=f.position.values;var A=e.union(N,I),d=R.length/3,S=r(i.numberOfVerticalLines,16);S=l.clamp(S,0,d/2);var M=_.createTypedArray(d,2*d+2*S);d/=2;var y,m=0;for(y=0;y<d;++y)M[m++]=y,M[m++]=(y+1)%d,M[m++]=y+d,M[m++]=(y+1)%d+d;var O;if(S>0){var p=Math.min(S,d);O=Math.round(d/p);var C=Math.min(O*S,d);for(y=0;y<C;y+=O)M[m++]=y,M[m++]=y+d}return{boundingSphere:A,attributes:f,indices:M}}function A(e){e=r(e,r.EMPTY_OBJECT);var n=e.center,a=r(e.ellipsoid,u.WGS84),o=e.semiMajorAxis,E=e.semiMinorAxis,s=r(e.granularity,l.RADIANS_PER_DEGREE),c=r(e.height,0),_=e.extrudedHeight,T=i(_)&&Math.abs(c-_)>1;this._center=t.clone(n),this._semiMajorAxis=o,this._semiMinorAxis=E,this._ellipsoid=u.clone(a),this._rotation=r(e.rotation,0),this._height=c,this._granularity=s,this._extrudedHeight=_,this._extrude=T,this._numberOfVerticalLines=Math.max(r(e.numberOfVerticalLines,16),0),this._workerName="createEllipseOutlineGeometry"}var h=new t,d=new t,N=new e,I=new e;A.packedLength=t.packedLength+u.packedLength+9,A.pack=function(e,n,a){return a=r(a,0),t.pack(e._center,n,a),a+=t.packedLength,u.pack(e._ellipsoid,n,a),a+=u.packedLength,n[a++]=e._semiMajorAxis,n[a++]=e._semiMinorAxis,n[a++]=e._rotation,n[a++]=e._height,n[a++]=e._granularity,n[a++]=i(e._extrudedHeight)?1:0,n[a++]=r(e._extrudedHeight,0),n[a++]=e._extrude?1:0,n[a]=e._numberOfVerticalLines,n};var S=new t,M=new u,y={center:S,ellipsoid:M,semiMajorAxis:void 0,semiMinorAxis:void 0,rotation:void 0,height:void 0,granularity:void 0,extrudedHeight:void 0,numberOfVerticalLines:void 0};return A.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,S);n+=t.packedLength;var E=u.unpack(e,n,M);n+=u.packedLength;var s=e[n++],c=e[n++],_=e[n++],l=e[n++],T=e[n++],R=e[n++],f=e[n++],h=1===e[n++],d=e[n];return i(a)?(a._center=t.clone(o,a._center),a._ellipsoid=u.clone(E,a._ellipsoid),a._semiMajorAxis=s,a._semiMinorAxis=c,a._rotation=_,a._height=l,a._granularity=T,a._extrudedHeight=R?f:void 0,a._extrude=h,a._numberOfVerticalLines=d,a):(y.height=l,y.extrudedHeight=R?f:void 0,y.granularity=T,y.rotation=_,y.semiMajorAxis=s,y.semiMinorAxis=c,y.numberOfVerticalLines=d,new A(y))},A.createGeometry=function(e){if(!(e._semiMajorAxis<=0||e._semiMinorAxis<=0)){ +e._center=e._ellipsoid.scaleToGeodeticSurface(e._center,e._center);var t,n={center:e._center,semiMajorAxis:e._semiMajorAxis,semiMinorAxis:e._semiMinorAxis,ellipsoid:e._ellipsoid,rotation:e._rotation,height:e._height,extrudedHeight:e._extrudedHeight,granularity:e._granularity,numberOfVerticalLines:e._numberOfVerticalLines};return e._extrude?(n.extrudedHeight=Math.min(e._extrudedHeight,e._height),n.height=Math.max(e._extrudedHeight,e._height),t=f(n)):t=R(n),new E({attributes:t.attributes,indices:t.indices,primitiveType:T.LINES,boundingSphere:t.boundingSphere})}},A}),define("Workers/createEllipseOutlineGeometry",["../Core/Cartesian3","../Core/defined","../Core/EllipseOutlineGeometry","../Core/Ellipsoid"],function(e,t,n,r){"use strict";function i(i,a){return t(a)&&(i=n.unpack(i,a)),i._center=e.clone(i._center),i._ellipsoid=r.clone(i._ellipsoid),n.createGeometry(i)}return i})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidGeometry.js index 514c4b1e..4081bae1 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,R=a.x,l=a.y,f=a.z,A=c*c*R*R,h=_*_*l*l,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,i);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,g,v,x,D,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*M),L=1/(1+B*O),P=1/(1+B*m),F=U*U,w=L*L,g=P*P,v=F*U,x=w*L,D=g*P,p=A*F+h*w+N*g-1,C=A*v*M+h*x*O+N*D*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*P,s):new t(c*U,_*L,T*P)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=i.EPSILON1;return u.fromCartesian=function(e,n,a){var l=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:R,h=o(e,l,f,A,s);if(r(h)){var N=t.multiplyComponents(h,f,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=i.sign(t.dot(d,e))*t.magnitude(d);return r(a)?(a.longitude=I,a.latitude=S,a.height=M,a):new u(I,S,M)}},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,f);if(a(i)){var o=this.geodeticSurfaceNormal(i,l),u=t.subtract(n,i,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(f[i],l[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=l[a],T=f[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(A-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,f=2*(a-T),A=2*(i+c),h=2*(a+T),N=-n+u-_+R,d=2*(s-o),I=2*(i-c),S=2*(s+o),M=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=I,e[3]=f,e[4]=N,e[5]=S,e[6]=A,e[7]=d,e[8]=M,e):new E(l,f,A,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,R=n*u,l=i*a+s*o*u,f=-s*a+i*o*u,A=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=R,e[2]=A,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=f,e[8]=N,e):new E(c,_,T,R,l,f,A,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);i<10&&c(T)>R;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){ -var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,R,l,f,A){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-R-A+N,I=2*(s-h),S=2*(_+f),M=2*(s+h),O=-E+R-A+N,m=2*(l-T),y=2*(_-f),p=2*(l+T),C=-E-R+A+N;return r[0]=d*i,r[1]=M*i,r[2]=y*i,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,f=_.y,A=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+f*S+A*M;return a(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,f=i+s,A=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=R,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=l,a[11]=0,a[12]=f,a[13]=A,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],f=t[12],A=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],M=e[3],O=e[4],m=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],P=e[11],F=e[12],w=e[13],g=e[14],v=e[15],x=r*d+u*I+_*S+f*M,D=a*d+E*I+T*S+A*M,B=i*d+s*I+R*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+f*p,b=a*O+E*m+T*y+A*p,X=i*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+f*P,H=a*C+E*U+T*L+A*P,W=i*C+s*U+R*L+h*P,Y=o*C+c*U+l*L+N*P,k=r*F+u*w+_*g+f*v,K=a*F+E*w+T*g+A*v,Z=i*F+s*w+R*g+h*v,j=o*F+c*w+l*g+N*v;return n[0]=x,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],f=e[0],A=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],M=e[9],O=e[10],m=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=a*f+u*A+c*h,L=i*f+E*A+_*h,P=r*N+o*d+s*I,F=a*N+u*d+c*I,w=i*N+E*d+_*I,g=r*S+o*M+s*O,v=a*S+u*M+c*O,x=i*S+E*M+_*O,D=r*m+o*y+s*p+T,B=a*m+u*y+c*p+R,z=i*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=g,n[9]=v,n[10]=x,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],f=e[3],A=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*R+s*l,M=a*T+u*R+c*l,O=i*T+E*R+_*l,m=r*f+o*A+s*h,y=a*f+u*A+c*h,p=i*f+E*A+_*h,C=r*N+o*d+s*I,U=a*N+u*d+c*I,L=i*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],f=t[2],A=t[6],S=t[10],M=t[14],O=t[3],m=t[7],y=t[11],p=t[15],C=S*p,U=M*y,L=A*p,P=M*m,F=A*y,w=S*m,g=f*p,v=M*O,x=f*y,D=S*O,B=f*m,z=A*O,G=C*T+P*R+F*l-(U*T+L*R+w*l),b=U*_+g*R+D*l-(C*_+v*R+x*l),X=L*_+v*T+B*l-(P*_+g*T+z*l),V=w*_+x*T+z*R-(F*_+D*T+B*R),q=U*a+L*i+w*o-(C*a+P*i+F*o),H=C*r+v*i+x*o-(U*r+g*i+D*o),W=P*r+g*a+z*o-(L*r+v*a+B*o),Y=F*r+D*a+B*i-(w*r+x*a+z*i);C=i*l,U=o*R,L=a*l,P=o*T,F=a*R,w=i*T,g=r*l,v=o*_,x=r*R,D=i*_,B=r*T,z=a*_;var k=C*m+P*y+F*p-(U*m+L*y+w*p),K=U*O+g*y+D*p-(C*O+v*y+x*p),Z=L*O+v*m+B*p-(P*O+g*m+z*p),j=w*O+x*m+z*y-(F*O+D*m+B*y),Q=L*S+w*M+U*A-(F*M+C*A+P*S),J=x*M+C*f+v*S-(g*S+D*M+U*f),$=g*A+z*M+P*f-(B*M+L*f+v*A),tt=B*S+F*f+D*A-(x*A+z*S+w*f),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-a*R,f=-i*_-o*T-u*R,A=-E*_-s*T-c*R;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),a=Math.max(a,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;i=Math.min(i,l),o=Math.max(o,l)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,f=t.length;l<f;l++){var A=e.cartesianToCartographic(t[l]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),R=Math.max(R,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=R,a):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,f=s;f.height=a,f.longitude=l,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_){"use strict";function T(e,n){this.center=t.clone(r(e,t.ZERO)),this.radius=r(n,0)}var R=new t,l=new t,f=new t,A=new t,h=new t,N=new t,d=new t,I=new t,S=new t,M=new t,O=new t,m=new t;T.fromPoints=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],d),o=t.clone(i,R),u=t.clone(i,l),E=t.clone(i,f),s=t.clone(i,A),c=t.clone(i,h),_=t.clone(i,N),y=e.length;for(r=1;r<y;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var L=t.magnitudeSquared(t.subtract(s,o,I)),P=t.magnitudeSquared(t.subtract(c,u,I)),F=t.magnitudeSquared(t.subtract(_,E,I)),w=o,g=s,v=L;P>v&&(v=P,w=u,g=c),F>v&&(v=F,w=E,g=_);var x=S;x.x=.5*(w.x+g.x),x.y=.5*(w.y+g.y),x.z=.5*(w.z+g.z);var D=t.magnitudeSquared(t.subtract(g,x,I)),B=Math.sqrt(D),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,I),.5,m),X=0;for(r=0;r<y;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,I));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(i,x,I));if(q>D){var H=Math.sqrt(q);B=.5*(B+H),D=B*B;var W=H-B;x.x=(B*x.x+W*i.x)/H,x.y=(B*x.y+W*i.y)/H,x.z=(B*x.z+W*i.z)/H}}return B<X?(t.clone(x,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var y=new o,p=new t,C=new t,U=new e,L=new e;T.fromRectangle2D=function(t,e,n){return T.fromRectangleWithHeights2D(t,e,0,0,n)},T.fromRectangleWithHeights2D=function(e,n,i,o,u){if(a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(e,U),U.height=i,_.northeast(e,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*R,f.z=E.z+.5*l,u};var P=[];T.fromRectangle3D=function(e,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=_.subsample(e,n,o,P);return T.fromPoints(E,u)},T.fromVertices=function(e,n,i,o){if(a(o)||(o=new T),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=r(n,t.ZERO),i=r(i,3);var u=d;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,R),c=t.clone(u,l),_=t.clone(u,f),y=t.clone(u,A),p=t.clone(u,h),C=t.clone(u,N),U=e.length;for(E=0;E<U;E+=i){var L=e[E]+n.x,P=e[E+1]+n.y,F=e[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&t.clone(u,s),L>y.x&&t.clone(u,y),P<c.y&&t.clone(u,c),P>p.y&&t.clone(u,p),F<_.z&&t.clone(u,_),F>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(y,s,I)),g=t.magnitudeSquared(t.subtract(p,c,I)),v=t.magnitudeSquared(t.subtract(C,_,I)),x=s,D=y,B=w;g>B&&(B=g,x=c,D=p),v>B&&(B=v,x=_,D=C);var z=S;z.x=.5*(x.x+D.x),z.y=.5*(x.y+D.y),z.z=.5*(x.z+D.z);var G=t.magnitudeSquared(t.subtract(D,z,I)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,I),.5,m),H=0;for(E=0;E<U;E+=i){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,I));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new T),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=d;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,R),E=t.clone(i,l),s=t.clone(i,f),c=t.clone(i,A),_=t.clone(i,h),y=t.clone(i,N),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),L<s.z&&t.clone(i,s),L>y.z&&t.clone(i,y)}var P=t.magnitudeSquared(t.subtract(c,u,I)),F=t.magnitudeSquared(t.subtract(_,E,I)),w=t.magnitudeSquared(t.subtract(y,s,I)),g=u,v=c,x=P;F>x&&(x=F,g=E,v=_),w>x&&(x=w,g=s,v=y);var D=S;D.x=.5*(g.x+v.x),D.y=.5*(g.y+v.y),D.z=.5*(g.z+v.z);var B=t.magnitudeSquared(t.subtract(v,D,I)),z=Math.sqrt(B),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=t.multiplyByScalar(t.add(G,b,I),.5,m),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,X,I));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(i,D,I));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*i.x)/W,D.y=(z*D.y+Y*i.y)/W,D.z=(z*D.z+Y*i.z)/W}}return z<V?(t.clone(D,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(e,n,r){a(r)||(r=new T);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},T.fromEllipsoid=function(e,n){return a(n)||(n=new T),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var F=new t;T.fromBoundingSpheres=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return T.clone(e[0],n);if(2===r)return T.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var w=new t,g=new t,v=new t;T.fromOrientedBoundingBox=function(e,n){a(n)||(n=new T);var r=e.halfAxes,i=s.getColumn(r,0,w),o=s.getColumn(r,1,g),u=s.getColumn(r,2,v);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},T.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new T(e.center,e.radius)},T.packedLength=4,T.pack=function(t,e,n){n=r(n,0);var a=t.center;return e[n++]=a.x,e[n++]=a.y,e[n++]=a.z,e[n]=t.radius,e},T.unpack=function(t,e,n){e=r(e,0),a(n)||(n=new T);var i=n.center;return i.x=t[e++],i.y=t[e++],i.z=t[e++],n.radius=t[e],n};var x=new t,D=new t;T.union=function(e,n,r){a(r)||(r=new T);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,x),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=t.multiplyByScalar(s,(-o+_)/c,D);return t.add(R,i,R),t.clone(R,r.center),r.radius=_,r};var B=new t;T.expand=function(e,n,r){r=T.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},T.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},T.transform=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=c.getMaximumScale(e)*t.radius,n};var z=new t;T.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,z);return t.magnitudeSquared(r)-e.radius*e.radius},T.transformWithoutScale=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var G=new t;T.computePlaneDistances=function(e,n,r,i){a(i)||(i=new E);var o=t.subtract(e.center,n,G),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var b=new t,X=new t,V=new t,q=new t,H=new t,W=new e,Y=new Array(8),k=0;k<8;++k)Y[k]=new t;var K=new o;return T.projectTo2D=function(e,n,a){n=r(n,K);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,b),s=t.cross(t.UNIT_Z,E,X);t.normalize(s,s);var c=t.cross(E,s,V);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,H),R=t.negate(s,q),l=Y,f=l[0];t.add(E,c,f),t.add(f,s,f),f=l[1],t.add(E,c,f),t.add(f,R,f),f=l[2],t.add(E,_,f),t.add(f,R,f),f=l[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=l[4],t.add(E,c,f),t.add(f,s,f),f=l[5],t.add(E,c,f),t.add(f,R,f),f=l[6],t.add(E,_,f),t.add(f,R,f),f=l[7],t.add(E,_,f),t.add(f,s,f);for(var A=l.length,h=0;h<A;++h){var N=l[h];t.add(o,N,N);var d=i.cartesianToCartographic(N,W);n.project(d,N)}a=T.fromPoints(l,a),o=a.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,a},T.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},T.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},T.prototype.intersectPlane=function(t){return T.intersectPlane(this,t)},T.prototype.distanceSquaredTo=function(t){return T.distanceSquaredTo(this,t)},T.prototype.computePlaneDistances=function(t,e,n){return T.computePlaneDistances(this,t,e,n)},T.prototype.isOccluded=function(t){return T.isOccluded(this,t)},T.prototype.equals=function(t){return T.equals(this,t)},T.prototype.clone=function(t){return T.clone(this,t)},T}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var a=0;a<r;++a)o.pack(t[a],e,2*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),i.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}), -define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,M=r(t[1]))}return S}function i(){return a()&&M}function o(){if(!e(O)&&(O=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,m=r(t[1]))}return O}function u(){return o()&&m}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(L=!0,P=r(t[1]))}return L}function R(){return T()&&P}function l(){if(!e(F)){F=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(F=!0,w=r(t[1]))}return F}function f(){return e(g)||(g=/Windows/i.test(I.appVersion)),g}function A(){return l()&&w}function h(){return e(v)||(v="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),v}function N(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(x=n)}return D}function d(){return N()?x:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,g,v,x,D,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(t){switch(t){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(e){return t(e)&&(e===i.UNSIGNED_BYTE||e===i.UNSIGNED_SHORT||e===i.UNSIGNED_INT)},i.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},i.createTypedArrayFromArrayBuffer=function(t,e,n,a){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,a):new Uint16Array(e,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/EllipsoidGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c,_,T,R,l){"use strict";function f(t){t=a(t,a.EMPTY_OBJECT);var e=a(t.radii,S),r=Math.round(a(t.stackPartitions,64)),i=Math.round(a(t.slicePartitions,64)),o=a(t.vertexFormat,l.DEFAULT);this._radii=n.clone(e),this._stackPartitions=r,this._slicePartitions=i,this._vertexFormat=l.clone(o),this._workerName="createEllipsoidGeometry"}var A=new n,h=new n,N=new n,d=new n,I=new n,S=new n(1,1,1),M=Math.cos,O=Math.sin;f.packedLength=n.packedLength+l.packedLength+2,f.pack=function(t,e,r){return r=a(r,0),n.pack(t._radii,e,r),r+=n.packedLength,l.pack(t._vertexFormat,e,r),r+=l.packedLength,e[r++]=t._stackPartitions,e[r]=t._slicePartitions,e};var m=new n,y=new l,p={radii:m,vertexFormat:y,stackPartitions:void 0,slicePartitions:void 0};return f.unpack=function(t,e,r){e=a(e,0);var o=n.unpack(t,e,m);e+=n.packedLength;var u=l.unpack(t,e,y);e+=l.packedLength;var E=t[e++],s=t[e];return i(r)?(r._radii=n.clone(o,r._radii),r._vertexFormat=l.clone(u,r._vertexFormat),r._stackPartitions=E,r._slicePartitions=s,r):(p.stackPartitions=E,p.slicePartitions=s,new f(p))},f.createGeometry=function(a){var i=a._radii;if(!(i.x<=0||i.y<=0||i.z<=0)){var o,l,f=u.fromCartesian3(i),S=a._vertexFormat,m=a._slicePartitions+1,y=a._stackPartitions+1,p=y*m,C=new Float64Array(3*p),U=6*(m-1)*(y-2),L=_.createTypedArray(p,U),P=S.normal?new Float32Array(3*p):void 0,F=S.tangent?new Float32Array(3*p):void 0,w=S.bitangent?new Float32Array(3*p):void 0,g=S.st?new Float32Array(2*p):void 0,v=new Array(m),x=new Array(m),D=0;for(o=0;o<m;o++){var B=T.TWO_PI*o/(m-1);v[o]=M(B),x[o]=O(B),C[D++]=0,C[D++]=0,C[D++]=i.z}for(o=1;o<y-1;o++){var z=Math.PI*o/(y-1),G=O(z),b=i.x*G,X=i.y*G,V=i.z*M(z);for(l=0;l<m;l++)C[D++]=v[l]*b,C[D++]=x[l]*X,C[D++]=V}for(o=0;o<m;o++)C[D++]=0,C[D++]=0,C[D++]=-i.z;var q=new c;S.position&&(q.position=new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:C}));var H=0,W=0,Y=0,k=0;if(S.st||S.normal||S.tangent||S.bitangent){for(o=0;o<p;o++){var K=n.fromArray(C,3*o,A),Z=f.geodeticSurfaceNormal(K,h);if(S.st){var j=e.negate(Z,I);e.magnitude(j)<T.EPSILON6&&(D=3*(o+m*Math.floor(.5*y)),D>C.length&&(D=3*(o-m*Math.floor(.5*y))),n.fromArray(C,D,j),f.geodeticSurfaceNormal(j,j),e.negate(j,j)),g[H++]=Math.atan2(j.y,j.x)/T.TWO_PI+.5,g[H++]=Math.asin(Z.z)/Math.PI+.5}if(S.normal&&(P[W++]=Z.x,P[W++]=Z.y,P[W++]=Z.z),S.tangent||S.bitangent){var Q=N;if(o<m||o>p-m-1?(n.cross(n.UNIT_X,Z,Q),n.normalize(Q,Q)):(n.cross(n.UNIT_Z,Z,Q),n.normalize(Q,Q)),S.tangent&&(F[Y++]=Q.x,F[Y++]=Q.y,F[Y++]=Q.z),S.bitangent){var J=n.cross(Z,Q,d);n.normalize(J,J),w[k++]=J.x,w[k++]=J.y,w[k++]=J.z}}}S.st&&(q.st=new s({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:g})),S.normal&&(q.normal=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:P})),S.tangent&&(q.tangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:F})),S.bitangent&&(q.bitangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:w}))}for(D=0,l=0;l<m-1;l++)L[D++]=m+l,L[D++]=m+l+1,L[D++]=l+1;var $,tt;for(o=1;o<y-2;o++)for($=o*m,tt=(o+1)*m,l=0;l<m-1;l++)L[D++]=tt+l,L[D++]=tt+l+1,L[D++]=$+l+1,L[D++]=tt+l,L[D++]=$+l+1,L[D++]=$+l;for(o=y-2,$=o*m,tt=(o+1)*m,l=0;l<m-1;l++)L[D++]=tt+l,L[D++]=$+l+1,L[D++]=$+l;return new E({attributes:q,indices:L,primitiveType:R.TRIANGLES,boundingSphere:t.fromEllipsoid(f)})}},f}),define("Workers/createEllipsoidGeometry",["../Core/defined","../Core/EllipsoidGeometry"],function(t,e){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,l=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:R,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,l);var c=Math.sqrt(o.dot(T,l));return l=o.divideByScalar(l,c,l),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(l,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,l=a.x,R=a.y,f=a.z,A=c*c*l*l,h=_*_*R*R,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,i);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var O=u.x,m=u.y,M=u.z,y=o;y.x=S.x*O*2,y.y=S.y*m*2,y.z=S.z*M*2;var p,C,U,L,P,F,g,w,v,x,D,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*O),L=1/(1+B*m),P=1/(1+B*M),F=U*U,g=L*L,w=P*P,v=F*U,x=g*L,D=w*P,p=A*F+h*g+N*w-1,C=A*v*O+h*x*m+N*D*M;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*P,s):new t(c*U,_*L,T*P)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),l=i.EPSILON1;return u.fromCartesian=function(e,n,a){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:l,h=o(e,R,f,A,s);if(r(h)){var N=t.multiplyComponents(h,f,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),O=i.sign(t.dot(d,e))*t.magnitude(d);return r(a)?(a.longitude=I,a.latitude=S,a.height=O,a):new u(I,S,O)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,l=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=l;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var R=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,f);if(a(i)){var o=this.geodeticSurfaceNormal(i,R),u=t.subtract(n,i,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],R[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(f[i],R[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=R[a],T=f[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var l,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(A-h)/2/N;l=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+l*l),c=l*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,l=t.w*t.w,R=n-u-_+l,f=2*(a-T),A=2*(i+c),h=2*(a+T),N=-n+u-_+l,d=2*(s-o),I=2*(i-c),S=2*(s+o),O=-n-u+_+l;return r(e)?(e[0]=R,e[1]=h,e[2]=I,e[3]=f,e[4]=N,e[5]=S,e[6]=A,e[7]=d,e[8]=O,e):new E(R,f,A,h,N,d,I,S,O)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,l=n*u,R=i*a+s*o*u,f=-s*a+i*o*u,A=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=l,e[2]=A,e[3]=_,e[4]=R,e[5]=h,e[6]=T,e[7]=f,e[8]=N,e):new E(c,_,T,l,R,f,A,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var l=new t;E.getMaximumScale=function(e){return E.getScale(e,l),t.maximumComponent(l)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var R=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),l=n*s(T);i<10&&c(T)>l;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var l=1/T;return E.multiplyByScalar(e,l,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,l,R,f,A){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(l,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,l=e.y*e.y,R=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-l-A+N,I=2*(s-h),S=2*(_+f),O=2*(s+h),m=-E+l-A+N,M=2*(R-T),y=2*(_-f),p=2*(R+T),C=-E-l+A+N;return r[0]=d*i,r[1]=O*i,r[2]=y*i,r[3]=0,r[4]=I*o,r[5]=m*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=M*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,l=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,l),l);var u=T.x,E=T.y,s=T.z,R=_.x,f=_.y,A=_.z,h=l.x,N=l.y,d=l.z,I=r.x,S=r.y,O=r.z,m=u*-I+E*-S+s*-O,M=h*-I+N*-S+d*-O,y=R*I+f*S+A*O;return a(n)?(n[0]=u,n[1]=h,n[2]=-R,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=m,n[13]=M,n[14]=y,n[15]=1,n):new c(u,E,s,m,h,N,d,M,-R,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,l=c,R=_,f=i+s,A=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=l,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=f,a[13]=A,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var R=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],R)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],R)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],R)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],l=t[10],R=t[11],f=t[12],A=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],O=e[3],m=e[4],M=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],P=e[11],F=e[12],g=e[13],w=e[14],v=e[15],x=r*d+u*I+_*S+f*O,D=a*d+E*I+T*S+A*O,B=i*d+s*I+l*S+h*O,z=o*d+c*I+R*S+N*O,G=r*m+u*M+_*y+f*p,b=a*m+E*M+T*y+A*p,X=i*m+s*M+l*y+h*p,V=o*m+c*M+R*y+N*p,q=r*C+u*U+_*L+f*P,H=a*C+E*U+T*L+A*P,W=i*C+s*U+l*L+h*P,Y=o*C+c*U+R*L+N*P,k=r*F+u*g+_*w+f*v,K=a*F+E*g+T*w+A*v,Z=i*F+s*g+l*w+h*v,j=o*F+c*g+R*w+N*v;return n[0]=x,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],l=t[13],R=t[14],f=e[0],A=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],O=e[9],m=e[10],M=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=a*f+u*A+c*h,L=i*f+E*A+_*h,P=r*N+o*d+s*I,F=a*N+u*d+c*I,g=i*N+E*d+_*I,w=r*S+o*O+s*m,v=a*S+u*O+c*m,x=i*S+E*O+_*m,D=r*M+o*y+s*p+T,B=a*M+u*y+c*p+l,z=i*M+E*y+_*p+R;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=g,n[7]=0,n[8]=w,n[9]=v,n[10]=x,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],l=e[1],R=e[2],f=e[3],A=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*l+s*R,O=a*T+u*l+c*R,m=i*T+E*l+_*R,M=r*f+o*A+s*h,y=a*f+u*A+c*h,p=i*f+E*A+_*h,C=r*N+o*d+s*I,U=a*N+u*d+c*I,L=i*N+E*d+_*I;return n[0]=S,n[1]=O,n[2]=m,n[3]=0,n[4]=M,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],l=t[9],R=t[13],f=t[2],A=t[6],S=t[10],O=t[14],m=t[3],M=t[7],y=t[11],p=t[15],C=S*p,U=O*y,L=A*p,P=O*M,F=A*y,g=S*M,w=f*p,v=O*m,x=f*y,D=S*m,B=f*M,z=A*m,G=C*T+P*l+F*R-(U*T+L*l+g*R),b=U*_+w*l+D*R-(C*_+v*l+x*R),X=L*_+v*T+B*R-(P*_+w*T+z*R),V=g*_+x*T+z*l-(F*_+D*T+B*l),q=U*a+L*i+g*o-(C*a+P*i+F*o),H=C*r+v*i+x*o-(U*r+w*i+D*o),W=P*r+w*a+z*o-(L*r+v*a+B*o),Y=F*r+D*a+B*i-(g*r+x*a+z*i);C=i*R,U=o*l,L=a*R,P=o*T,F=a*l,g=i*T,w=r*R,v=o*_,x=r*l,D=i*_,B=r*T,z=a*_;var k=C*M+P*y+F*p-(U*M+L*y+g*p),K=U*m+w*y+D*p-(C*m+v*y+x*p),Z=L*m+v*M+B*p-(P*m+w*M+z*p),j=g*m+x*M+z*y-(F*m+D*M+B*y),Q=L*S+g*O+U*A-(F*O+C*A+P*S),J=x*O+C*f+v*S-(w*S+D*O+U*f),$=w*A+z*O+P*f-(B*O+L*f+v*A),tt=B*S+F*f+D*A-(x*A+z*S+g*f),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],l=t[14],R=-n*_-r*T-a*l,f=-i*_-o*T-u*l,A=-E*_-s*T-c*l;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=R,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var l=t[_];n=Math.min(n,l.longitude),a=Math.max(a,l.longitude),s=Math.min(s,l.latitude),c=Math.max(c,l.latitude);var R=l.longitude>=0?l.longitude:l.longitude+u.TWO_PI;i=Math.min(i,R),o=Math.max(o,R)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,l=-Number.MAX_VALUE,R=0,f=t.length;R<f;R++){var A=e.cartesianToCartographic(t[R]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),l=Math.max(l,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=l,a):new E(o,T,s,l)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),l=Math.min(t.north,e.north);if(!(T>=l))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=l,n):new E(c,T,_,l)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,l=t.east,R=t.west,f=s;f.height=a,f.longitude=R,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_,T){"use strict";function l(e,n){this.center=t.clone(a(e,t.ZERO)),this.radius=a(n,0)}var R=new t,f=new t,A=new t,h=new t,N=new t,d=new t,I=new t,S=new t,O=new t,m=new t,M=new t,y=new t,p=4/3*n.PI;l.fromPoints=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,a=t.clone(e[0],I),o=t.clone(a,R),u=t.clone(a,f),E=t.clone(a,A),s=t.clone(a,h),c=t.clone(a,N),_=t.clone(a,d),T=e.length;for(r=1;r<T;r++){t.clone(e[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&t.clone(a,o),p>s.x&&t.clone(a,s),C<u.y&&t.clone(a,u),C>c.y&&t.clone(a,c),U<E.z&&t.clone(a,E),U>_.z&&t.clone(a,_)}var L=t.magnitudeSquared(t.subtract(s,o,S)),P=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),g=o,w=s,v=L;P>v&&(v=P,g=u,w=c),F>v&&(v=F,g=E,w=_);var x=O;x.x=.5*(g.x+w.x),x.y=.5*(g.y+w.y),x.z=.5*(g.z+w.z);var D=t.magnitudeSquared(t.subtract(w,x,S)),B=Math.sqrt(D),z=m;z.x=o.x,z.y=u.y,z.z=E.z;var G=M;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],a);var V=t.magnitude(t.subtract(a,b,S));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(a,x,S));if(q>D){var H=Math.sqrt(q);B=.5*(B+H),D=B*B;var W=H-B;x.x=(B*x.x+W*a.x)/H,x.y=(B*x.y+W*a.y)/H,x.z=(B*x.z+W*a.z)/H}}return B<X?(t.clone(x,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,L=new t,P=new e,F=new e;l.fromRectangle2D=function(t,e,n){return l.fromRectangleWithHeights2D(t,e,0,0,n)},l.fromRectangleWithHeights2D=function(e,n,r,o,u){if(i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=a(n,C),T.southwest(e,P),P.height=r,T.northeast(e,F),F.height=o;var E=n.project(P,U),s=n.project(F,L),c=s.x-E.x,_=s.y-E.y,R=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+R*R);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*_,f.z=E.z+.5*R,u};var g=[];l.fromRectangle3D=function(e,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,g);return l.fromPoints(E,u)},l.fromVertices=function(e,n,r,o){if(i(o)||(o=new l),!i(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=a(n,t.ZERO),r=a(r,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,R),c=t.clone(u,f),_=t.clone(u,A),T=t.clone(u,h),p=t.clone(u,N),C=t.clone(u,d),U=e.length;for(E=0;E<U;E+=r){var L=e[E]+n.x,P=e[E+1]+n.y,F=e[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&t.clone(u,s),L>T.x&&t.clone(u,T),P<c.y&&t.clone(u,c),P>p.y&&t.clone(u,p),F<_.z&&t.clone(u,_),F>C.z&&t.clone(u,C)}var g=t.magnitudeSquared(t.subtract(T,s,S)),w=t.magnitudeSquared(t.subtract(p,c,S)),v=t.magnitudeSquared(t.subtract(C,_,S)),x=s,D=T,B=g;w>B&&(B=w,x=c,D=p),v>B&&(B=v,x=_,D=C);var z=O;z.x=.5*(x.x+D.x),z.y=.5*(x.y+D.y),z.z=.5*(x.z+D.z);var G=t.magnitudeSquared(t.subtract(D,z,S)),b=Math.sqrt(G),X=m;X.x=s.x,X.y=c.y,X.z=_.z;var V=M;V.x=T.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,S));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},l.fromEncodedCartesianVertices=function(e,n,r){if(i(r)||(r=new l),!i(e)||!i(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var a=I;a.x=e[0]+n[0],a.y=e[1]+n[1],a.z=e[2]+n[2];var o,u=t.clone(a,R),E=t.clone(a,f),s=t.clone(a,A),c=t.clone(a,h),_=t.clone(a,N),T=t.clone(a,d),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&t.clone(a,u),C>c.x&&t.clone(a,c),U<E.y&&t.clone(a,E),U>_.y&&t.clone(a,_),L<s.z&&t.clone(a,s),L>T.z&&t.clone(a,T)}var P=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),g=t.magnitudeSquared(t.subtract(T,s,S)),w=u,v=c,x=P;F>x&&(x=F,w=E,v=_),g>x&&(x=g,w=s,v=T);var D=O;D.x=.5*(w.x+v.x),D.y=.5*(w.y+v.y),D.z=.5*(w.z+v.z);var B=t.magnitudeSquared(t.subtract(v,D,S)),z=Math.sqrt(B),G=m;G.x=u.x,G.y=E.y,G.z=s.z;var b=M;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){a.x=e[o]+n[o],a.y=e[o+1]+n[o+1],a.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(a,X,S));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(a,D,S));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*a.x)/W,D.y=(z*D.y+Y*a.y)/W,D.z=(z*D.z+Y*a.z)/W}}return z<V?(t.clone(D,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},l.fromCornerPoints=function(e,n,r){i(r)||(r=new l);var a=r.center;return t.add(e,n,a),t.multiplyByScalar(a,.5,a),r.radius=t.distance(a,n),r},l.fromEllipsoid=function(e,n){return i(n)||(n=new l),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var w=new t;l.fromBoundingSpheres=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return l.clone(e[0],n);if(2===r)return l.union(e[0],e[1],n);var a,o=[];for(a=0;a<r;a++)o.push(e[a].center);n=l.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=e[a];E=Math.max(E,t.distance(u,s.center,w)+s.radius)}return n.radius=E,n};var v=new t,x=new t,D=new t;l.fromOrientedBoundingBox=function(e,n){i(n)||(n=new l);var r=e.halfAxes,a=c.getColumn(r,0,v),o=c.getColumn(r,1,x),u=c.getColumn(r,2,D);return t.add(a,o,a),t.add(a,u,a),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(a),n},l.clone=function(e,n){if(i(e))return i(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new l(e.center,e.radius)},l.packedLength=4,l.pack=function(t,e,n){n=a(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},l.unpack=function(t,e,n){e=a(e,0),i(n)||(n=new l);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var B=new t,z=new t;l.union=function(e,n,r){i(r)||(r=new l);var a=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,a,B),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,a,T),t.clone(T,r.center),r.radius=_,r};var G=new t;l.expand=function(e,n,r){r=l.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,G));return a>r.radius&&(r.radius=a),r},l.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?E.OUTSIDE:o<a?E.INTERSECTING:E.INSIDE},l.transform=function(t,e,n){return i(n)||(n=new l),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;l.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},l.transformWithoutScale=function(t,e,n){return i(n)||(n=new l),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;l.computePlaneDistances=function(e,n,r,a){i(a)||(a=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var V=new t,q=new t,H=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return l.projectTo2D=function(e,n,r){n=a(n,j);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,q);t.normalize(s,s);var c=t.cross(E,s,H);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),R=K,f=R[0];t.add(E,c,f),t.add(f,s,f),f=R[1],t.add(E,c,f),t.add(f,T,f),f=R[2],t.add(E,_,f),t.add(f,T,f),f=R[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=R[4],t.add(E,c,f),t.add(f,s,f),f=R[5],t.add(E,c,f),t.add(f,T,f),f=R[6],t.add(E,_,f),t.add(f,T,f),f=R[7],t.add(E,_,f),t.add(f,s,f);for(var A=R.length,h=0;h<A;++h){var N=R[h];t.add(o,N,N);var d=i.cartesianToCartographic(N,k);n.project(d,N)}r=l.fromPoints(R,r),o=r.center;var I=o.x,S=o.y,O=o.z;return o.x=O,o.y=I,o.z=S,r},l.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},l.equals=function(e,n){return e===n||i(e)&&i(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},l.prototype.intersectPlane=function(t){return l.intersectPlane(this,t)},l.prototype.distanceSquaredTo=function(t){return l.distanceSquaredTo(this,t)},l.prototype.computePlaneDistances=function(t,e,n){return l.computePlaneDistances(this,t,e,n)},l.prototype.isOccluded=function(t){return l.isOccluded(this,t)},l.prototype.equals=function(t){return l.equals(this,t)},l.prototype.clone=function(t){return l.clone(this,t)},l.prototype.volume=function(){var t=this.radius;return p*t*t*t},l}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var a=0;a<r;++a)o.pack(t[a],e,2*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),i.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)), +o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,O=r(t[1]))}return S}function i(){return a()&&O}function o(){if(!e(m)&&(m=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(m=!0,M=r(t[1]))}return m}function u(){return o()&&M}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(L=!0,P=r(t[1]))}return L}function l(){return T()&&P}function R(){if(!e(F)){F=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(F=!0,g=r(t[1]))}return F}function f(){return e(w)||(w=/Windows/i.test(I.appVersion)),w}function A(){return R()&&g}function h(){return e(v)||(v="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),v}function N(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(x=n)}return D}function d(){return N()?x:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,O,m,M,y,p,C,U,L,P,F,g,w,v,x,D,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:l,isFirefox:R,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(t){switch(t){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(e){return t(e)&&(e===i.UNSIGNED_BYTE||e===i.UNSIGNED_SHORT||e===i.UNSIGNED_INT)},i.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},i.createTypedArrayFromArrayBuffer=function(t,e,n,a){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,a):new Uint16Array(e,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/EllipsoidGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c,_,T,l,R){"use strict";function f(t){t=a(t,a.EMPTY_OBJECT);var e=a(t.radii,S),r=Math.round(a(t.stackPartitions,64)),i=Math.round(a(t.slicePartitions,64)),o=a(t.vertexFormat,R.DEFAULT);this._radii=n.clone(e),this._stackPartitions=r,this._slicePartitions=i,this._vertexFormat=R.clone(o),this._workerName="createEllipsoidGeometry"}var A=new n,h=new n,N=new n,d=new n,I=new n,S=new n(1,1,1),O=Math.cos,m=Math.sin;f.packedLength=n.packedLength+R.packedLength+2,f.pack=function(t,e,r){return r=a(r,0),n.pack(t._radii,e,r),r+=n.packedLength,R.pack(t._vertexFormat,e,r),r+=R.packedLength,e[r++]=t._stackPartitions,e[r]=t._slicePartitions,e};var M=new n,y=new R,p={radii:M,vertexFormat:y,stackPartitions:void 0,slicePartitions:void 0};f.unpack=function(t,e,r){e=a(e,0);var o=n.unpack(t,e,M);e+=n.packedLength;var u=R.unpack(t,e,y);e+=R.packedLength;var E=t[e++],s=t[e];return i(r)?(r._radii=n.clone(o,r._radii),r._vertexFormat=R.clone(u,r._vertexFormat),r._stackPartitions=E,r._slicePartitions=s,r):(p.stackPartitions=E,p.slicePartitions=s,new f(p))},f.createGeometry=function(a){var i=a._radii;if(!(i.x<=0||i.y<=0||i.z<=0)){var o,R,f=u.fromCartesian3(i),S=a._vertexFormat,M=a._slicePartitions+1,y=a._stackPartitions+1,p=y*M,C=new Float64Array(3*p),U=6*(M-1)*(y-2),L=_.createTypedArray(p,U),P=S.normal?new Float32Array(3*p):void 0,F=S.tangent?new Float32Array(3*p):void 0,g=S.bitangent?new Float32Array(3*p):void 0,w=S.st?new Float32Array(2*p):void 0,v=new Array(M),x=new Array(M),D=0;for(o=0;o<M;o++){var B=T.TWO_PI*o/(M-1);v[o]=O(B),x[o]=m(B),C[D++]=0,C[D++]=0,C[D++]=i.z}for(o=1;o<y-1;o++){var z=Math.PI*o/(y-1),G=m(z),b=i.x*G,X=i.y*G,V=i.z*O(z);for(R=0;R<M;R++)C[D++]=v[R]*b,C[D++]=x[R]*X,C[D++]=V}for(o=0;o<M;o++)C[D++]=0,C[D++]=0,C[D++]=-i.z;var q=new c;S.position&&(q.position=new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:C}));var H=0,W=0,Y=0,k=0;if(S.st||S.normal||S.tangent||S.bitangent){for(o=0;o<p;o++){var K=n.fromArray(C,3*o,A),Z=f.geodeticSurfaceNormal(K,h);if(S.st){var j=e.negate(Z,I);e.magnitude(j)<T.EPSILON6&&(D=3*(o+M*Math.floor(.5*y)),D>C.length&&(D=3*(o-M*Math.floor(.5*y))),n.fromArray(C,D,j),f.geodeticSurfaceNormal(j,j),e.negate(j,j)),w[H++]=Math.atan2(j.y,j.x)/T.TWO_PI+.5,w[H++]=Math.asin(Z.z)/Math.PI+.5}if(S.normal&&(P[W++]=Z.x,P[W++]=Z.y,P[W++]=Z.z),S.tangent||S.bitangent){var Q=N;if(o<M||o>p-M-1?(n.cross(n.UNIT_X,Z,Q),n.normalize(Q,Q)):(n.cross(n.UNIT_Z,Z,Q),n.normalize(Q,Q)),S.tangent&&(F[Y++]=Q.x,F[Y++]=Q.y,F[Y++]=Q.z),S.bitangent){var J=n.cross(Z,Q,d);n.normalize(J,J),g[k++]=J.x,g[k++]=J.y,g[k++]=J.z}}}S.st&&(q.st=new s({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:w})),S.normal&&(q.normal=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:P})),S.tangent&&(q.tangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:F})),S.bitangent&&(q.bitangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:g}))}for(D=0,R=0;R<M-1;R++)L[D++]=M+R,L[D++]=M+R+1,L[D++]=R+1;var $,tt;for(o=1;o<y-2;o++)for($=o*M,tt=(o+1)*M,R=0;R<M-1;R++)L[D++]=tt+R,L[D++]=tt+R+1,L[D++]=$+R+1,L[D++]=tt+R,L[D++]=$+R+1,L[D++]=$+R;for(o=y-2,$=o*M,tt=(o+1)*M,R=0;R<M-1;R++)L[D++]=tt+R,L[D++]=$+R+1,L[D++]=$+R;return new E({attributes:q,indices:L,primitiveType:l.TRIANGLES,boundingSphere:t.fromEllipsoid(f)})}};var C;return f.getUnitEllipsoid=function(){return i(C)||(C=f.createGeometry(new f({radii:new n(1,1,1),vertexFormat:R.POSITION_ONLY}))),C},f}),define("Workers/createEllipsoidGeometry",["../Core/defined","../Core/EllipsoidGeometry"],function(t,e){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidOutlineGeometry.js index 3a31528a..1884c9fd 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createEllipsoidOutlineGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(e),T.y=s*Math.sin(e),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,P,L,F,D,w,B,v,g,x=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{x-=z,U=1/(1+x*M),P=1/(1+x*O),L=1/(1+x*m),F=U*U,D=P*P,w=L*L,B=F*U,v=D*P,g=w*L,p=f*F+h*D+N*w-1,C=f*B*M+h*v*O+N*g*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*P,s.z=T*L,s):new e(c*U,_*P,T*L)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),T=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var T=new e,R=new e;_.prototype.cartographicToCartesian=function(t,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(e[E.getElementIndex(T,_)])>n){var R,f=e[E.getElementIndex(T,T)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(T,T)]=s,t[E.getElementIndex(T,_)]=c,t[E.getElementIndex(_,T)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,T=e.z*e.w,R=e.w*e.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=M,t):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=R,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=T,t[7]=A,t[8]=N,t):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],T)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),T=t.diagonal=E.clone(e,t.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],T=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(t,R,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,T=t.x*t.w,R=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,T=new e,R=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,T),T),e.normalize(e.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),T=s,R=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],T=e[9],R=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],P=t[10],L=t[11],F=t[12],D=t[13],w=t[14],B=t[15],v=r*d+u*I+_*S+A*M,g=i*d+E*I+T*S+f*M,x=a*d+s*I+R*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+A*p,b=i*O+E*m+T*y+f*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,H=r*C+u*U+_*P+A*L,q=i*C+E*U+T*P+f*L,W=a*C+s*U+R*P+h*L,Y=o*C+c*U+l*P+N*L,k=r*F+u*D+_*w+A*B,K=i*F+E*D+T*w+f*B,Z=a*F+s*D+R*w+h*B,j=o*F+c*D+l*w+N*B;return n[0]=v,n[1]=g,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=e[12],R=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,P=a*A+E*f+_*h,L=r*N+o*d+s*I,F=i*N+u*d+c*I,D=a*N+E*d+_*I,w=r*S+o*M+s*O,B=i*S+u*M+c*O,v=a*S+E*M+_*O,g=r*m+o*y+s*p+T,x=i*m+u*y+c*p+R,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=P,n[3]=0,n[4]=L,n[5]=F,n[6]=D,n[7]=0,n[8]=w,n[9]=B,n[10]=v,n[11]=0,n[12]=g,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=t[0],R=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,P=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=P,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],T=e[5],R=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,P=f*p,L=M*m,F=f*y,D=S*m,w=A*p,B=M*O,v=A*y,g=S*O,x=A*m,z=f*O,G=C*T+L*R+F*l-(U*T+P*R+D*l),b=U*_+w*R+g*l-(C*_+B*R+v*l),X=P*_+B*T+x*l-(L*_+w*T+z*l),V=D*_+v*T+z*R-(F*_+g*T+x*R),H=U*i+P*a+D*o-(C*i+L*a+F*o),q=C*r+B*a+v*o-(U*r+w*a+g*o),W=L*r+w*i+z*o-(P*r+B*i+x*o),Y=F*r+g*i+x*a-(D*r+v*i+z*a);C=a*l,U=o*R,P=i*l,L=o*T,F=i*R,D=a*T,w=r*l,B=o*_,v=r*R,g=a*_,x=r*T,z=i*_;var k=C*m+L*y+F*p-(U*m+P*y+D*p),K=U*O+w*y+g*p-(C*O+B*y+v*p),Z=P*O+B*m+x*p-(L*O+w*m+z*p),j=D*O+v*m+z*y-(F*O+g*m+x*y),Q=P*S+D*M+U*f-(F*M+C*f+L*S),J=v*M+C*A+B*S-(w*S+g*M+U*A),$=w*f+z*M+L*A-(x*M+P*A+B*f),ee=x*S+F*A+g*f-(v*f+z*S+D*A),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],T=e[13],R=e[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=e.length;_<T;_++){var R=e[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var T=Math.max(e.south,t.south),R=Math.min(e.north,t.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,T=e.south,R=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function T(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var R=new e,l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e;T.fromPoints=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],d),o=e.clone(a,R),u=e.clone(a,l),E=e.clone(a,A),s=e.clone(a,f),c=e.clone(a,h),_=e.clone(a,N),y=t.length;for(r=1;r<y;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var P=e.magnitudeSquared(e.subtract(s,o,I)),L=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),D=o,w=s,B=P;L>B&&(B=L,D=u,w=c),F>B&&(B=F,D=E,w=_);var v=S;v.x=.5*(D.x+w.x),v.y=.5*(D.y+w.y),v.z=.5*(D.z+w.z);var g=e.magnitudeSquared(e.subtract(w,v,I)),x=Math.sqrt(g),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,I),.5,m),X=0;for(r=0;r<y;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,I));V>X&&(X=V);var H=e.magnitudeSquared(e.subtract(a,v,I));if(H>g){var q=Math.sqrt(H);x=.5*(x+q),g=x*x;var W=q-x;v.x=(x*v.x+W*a.x)/q,v.y=(x*v.y+W*a.y)/q,v.z=(x*v.z+W*a.z)/q}}return x<X?(e.clone(v,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var y=new o,p=new e,C=new e,U=new t,P=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(t,U),U.height=a,_.northeast(t,P),P.height=o;var E=n.project(U,p),s=n.project(P,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*R,A.z=E.z+.5*l,u};var L=[];T.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,L);return T.fromPoints(E,u)},T.fromVertices=function(t,n,a,o){if(i(o)||(o=new T),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=d;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,R),c=e.clone(u,l),_=e.clone(u,A),y=e.clone(u,f),p=e.clone(u,h),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=a){var P=t[E]+n.x,L=t[E+1]+n.y,F=t[E+2]+n.z;u.x=P,u.y=L,u.z=F,P<s.x&&e.clone(u,s),P>y.x&&e.clone(u,y),L<c.y&&e.clone(u,c),L>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var D=e.magnitudeSquared(e.subtract(y,s,I)),w=e.magnitudeSquared(e.subtract(p,c,I)),B=e.magnitudeSquared(e.subtract(C,_,I)),v=s,g=y,x=D;w>x&&(x=w,v=c,g=p),B>x&&(x=B,v=_,g=C);var z=S;z.x=.5*(v.x+g.x),z.y=.5*(v.y+g.y),z.z=.5*(v.z+g.z);var G=e.magnitudeSquared(e.subtract(g,z,I)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var H=e.multiplyByScalar(e.add(X,V,I),.5,m),q=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,H,I));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<q?(e.clone(z,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},T.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new T),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=d;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,R),E=e.clone(a,l),s=e.clone(a,A),c=e.clone(a,f),_=e.clone(a,h),y=e.clone(a,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],P=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=P,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),P<s.z&&e.clone(a,s),P>y.z&&e.clone(a,y)}var L=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),D=e.magnitudeSquared(e.subtract(y,s,I)),w=u,B=c,v=L;F>v&&(v=F,w=E,B=_),D>v&&(v=D,w=s,B=y);var g=S;g.x=.5*(w.x+B.x),g.y=.5*(w.y+B.y),g.z=.5*(w.z+B.z);var x=e.magnitudeSquared(e.subtract(B,g,I)),z=Math.sqrt(x),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=e.multiplyByScalar(e.add(G,b,I),.5,m),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(a,X,I));H>V&&(V=H);var q=e.magnitudeSquared(e.subtract(a,g,I));if(q>x){var W=Math.sqrt(q);z=.5*(z+W),x=z*z;var Y=W-z;g.x=(z*g.x+Y*a.x)/W,g.y=(z*g.y+Y*a.y)/W,g.z=(z*g.z+Y*a.z)/W}}return z<V?(e.clone(g,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){i(r)||(r=new T);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},T.fromEllipsoid=function(t,n){return i(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var F=new e;T.fromBoundingSpheres=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var D=new e,w=new e,B=new e;T.fromOrientedBoundingBox=function(t,n){i(n)||(n=new T);var r=t.halfAxes,a=s.getColumn(r,0,D),o=s.getColumn(r,1,w),u=s.getColumn(r,2,B);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},T.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new T);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var v=new e,g=new e;T.union=function(t,n,r){i(r)||(r=new T);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,v),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,g);return e.add(R,a,R),e.clone(R,r.center),r.radius=_,r};var x=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,x));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},T.transform=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;T.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,H=new e,q=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return T.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,q),R=e.negate(s,H),l=Y,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,R,A),A=l[2],e.add(E,_,A),e.add(A,R,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,R,A),A=l[6],e.add(E,_,A),e.add(A,R,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,W);n.project(d,N)}i=T.fromPoints(l,i),o=i.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,i},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!T())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0,p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function T(){if(!t(P)){P=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(P=!0,L=r(e[1]))}return P}function R(){return T()&&L}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,D=r(e[1]))}return F}function A(){return t(w)||(w=/Windows/i.test(I.appVersion)),w}function f(){return l()&&D}function h(){return t(B)||(B="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),B}function N(){if(!t(g)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;g=t(n)&&""!==n,g&&(v=n)}return g}function d(){return N()?v:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,P,L,F,D,w,B,v,g,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipsoidOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e){e=r(e,r.EMPTY_OBJECT);var n=r(e.radii,l),i=Math.round(r(e.stackPartitions,10)),a=Math.round(r(e.slicePartitions,8)),o=Math.round(r(e.subdivisions,128));this._radii=t.clone(n),this._stackPartitions=i,this._slicePartitions=a,this._subdivisions=o,this._workerName="createEllipsoidOutlineGeometry"}var l=new t(1,1,1),A=Math.cos,f=Math.sin;R.packedLength=t.packedLength+3,R.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),i+=t.packedLength,n[i++]=e._stackPartitions,n[i++]=e._slicePartitions,n[i]=e._subdivisions,n};var h=new t,N={radii:h,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return R.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,h);n+=t.packedLength;var u=e[n++],E=e[n++],s=e[n++];return i(a)?(a._radii=t.clone(o,a._radii),a._stackPartitions=u,a._slicePartitions=E,a._subdivisions=s,a):(N.stackPartitions=u,N.slicePartitions=E,N.subdivisions=s,new R(N))},R.createGeometry=function(t){var r=t._radii;if(!(r.x<=0||r.y<=0||r.z<=0)){var i,a,R,l,h,N,d=o.fromCartesian3(r),I=t._stackPartitions,S=t._slicePartitions,M=t._subdivisions,O=M*(I+S-1),m=O-S+2,y=new Float64Array(3*m),p=c.createTypedArray(m,2*O),C=0,U=new Array(M),P=new Array(M);for(i=0;i<M;i++)R=_.TWO_PI*i/M,U[i]=A(R),P[i]=f(R);for(i=1;i<I;i++)for(l=Math.PI*i/I,h=A(l),N=f(l),a=0;a<M;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(U.length=S,P.length=S,i=0;i<S;i++)R=_.TWO_PI*i/S,U[i]=A(R),P[i]=f(R);for(y[C++]=0,y[C++]=0,y[C++]=r.z,i=1;i<M;i++)for(l=Math.PI*i/M,h=A(l),N=f(l),a=0;a<S;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(y[C++]=0,y[C++]=0,y[C++]=-r.z,C=0,i=0;i<I-1;++i){var L=i*M;for(a=0;a<M-1;++a)p[C++]=L+a,p[C++]=L+a+1;p[C++]=L+M-1,p[C++]=L}var F=M*(I-1);for(a=1;a<S+1;++a)p[C++]=F,p[C++]=F+a;for(i=0;i<M-2;++i){var D=i*S+1+F,w=(i+1)*S+1+F;for(a=0;a<S-1;++a)p[C++]=w+a,p[C++]=D+a;p[C++]=w+S-1,p[C++]=D+S-1}var B=y.length/3-1;for(a=B-1;a>B-S-1;--a)p[C++]=B,p[C++]=a;var v=new s({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:y})});return new u({attributes:v,indices:p,primitiveType:T.LINES,boundingSphere:e.fromEllipsoid(d)})}},R}),define("Workers/createEllipsoidOutlineGeometry",["../Core/defined","../Core/EllipsoidOutlineGeometry"],function(e,t){"use strict";return function(n,r){return e(n.buffer,r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,E=e.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],E=t[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],E=t[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],E=t[a+1],s=t[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],E=t[a+1],s=t[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,P,L,F,D,w,B,v,g,x=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{x-=z,U=1/(1+x*M),P=1/(1+x*O),L=1/(1+x*m),F=U*U,D=P*P,w=L*L,B=F*U,v=D*P,g=w*L,p=f*F+h*D+N*w-1,C=f*B*M+h*v*O+N*g*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*P,s.z=T*L,s):new t(c*U,_*P,T*L)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(e,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(e,l,A,f,s);if(r(h)){var N=t.multiplyComponents(h,A,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(t.dot(d,e))*t.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,E,s){"use strict";function c(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,A=new t,f=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=t.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function E(t,e,r,i,a,o,u,E,s){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(A[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,f=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=I,e[3]=A,e[4]=N,e[5]=S,e[6]=f,e[7]=d,e[8]=M,e):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(e)?(e[0]=c,e[1]=R,e[2]=f,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=A,e[8]=N,e):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,E=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*i-r*_,e[2]=r*u-o*i,e[3]=s*u-a*_,e[4]=n*_-s*i,e[5]=a*i-n*u,e[6]=a*c-s*o,e[7]=s*r-n*c,e[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,E,s){"use strict";function c(t,e,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,A=e.y*e.w,f=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),E=1/(r-n),s=1/(a-i),c=-(e+t)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),E=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,A=a+s,f=o+c,h=e+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},c.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var A=new t;c.getMaximumScale=function(e){return c.getScale(e,A),t.maximumComponent(A)},c.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],A=t[12],f=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],M=e[3],O=e[4],m=e[5],y=e[6],p=e[7],C=e[8],U=e[9],P=e[10],L=e[11],F=e[12],D=e[13],w=e[14],B=e[15],v=r*d+u*I+_*S+A*M,g=i*d+E*I+T*S+f*M,x=a*d+s*I+R*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+A*p,b=i*O+E*m+T*y+f*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,H=r*C+u*U+_*P+A*L,q=i*C+E*U+T*P+f*L,W=a*C+s*U+R*P+h*L,Y=o*C+c*U+l*P+N*L,k=r*F+u*D+_*w+A*B,K=i*F+E*D+T*w+f*B,Z=a*F+s*D+R*w+h*B,j=o*F+c*D+l*w+N*B;return n[0]=v,n[1]=g,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],A=e[0],f=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],M=e[9],O=e[10],m=e[12],y=e[13],p=e[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,P=a*A+E*f+_*h,L=r*N+o*d+s*I,F=i*N+u*d+c*I,D=a*N+E*d+_*I,w=r*S+o*M+s*O,B=i*S+u*M+c*O,v=a*S+E*M+_*O,g=r*m+o*y+s*p+T,x=i*m+u*y+c*p+R,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=P,n[3]=0,n[4]=L,n[5]=F,n[6]=D,n[7]=0,n[8]=w,n[9]=B,n[10]=v,n[11]=0,n[12]=g,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],A=e[3],f=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,P=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=P,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],E=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var f=new t;c.multiplyByUniformScale=function(t,e,n){return f.x=e,f.y=e,f.z=e,c.multiplyByScale(t,f,n)},c.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,E=t[1]*r+t[5]*i+t[9]*a+t[13]*o,s=t[2]*r+t[6]*i+t[10]*a+t[14]*o,c=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,E=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],E=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],A=t[2],f=t[6],S=t[10],M=t[14],O=t[3],m=t[7],y=t[11],p=t[15],C=S*p,U=M*y,P=f*p,L=M*m,F=f*y,D=S*m,w=A*p,B=M*O,v=A*y,g=S*O,x=A*m,z=f*O,G=C*T+L*R+F*l-(U*T+P*R+D*l),b=U*_+w*R+g*l-(C*_+B*R+v*l),X=P*_+B*T+x*l-(L*_+w*T+z*l),V=D*_+v*T+z*R-(F*_+g*T+x*R),H=U*i+P*a+D*o-(C*i+L*a+F*o),q=C*r+B*a+v*o-(U*r+w*a+g*o),W=L*r+w*i+z*o-(P*r+B*i+x*o),Y=F*r+g*i+x*a-(D*r+v*i+z*a);C=a*l,U=o*R,P=i*l,L=o*T,F=i*R,D=a*T,w=r*l,B=o*_,v=r*R,g=a*_,x=r*T,z=i*_;var k=C*m+L*y+F*p-(U*m+P*y+D*p),K=U*O+w*y+g*p-(C*O+B*y+v*p),Z=P*O+B*m+x*p-(L*O+w*m+z*p),j=D*O+v*m+z*y-(F*O+g*m+x*y),Q=P*S+D*M+U*f-(F*M+C*f+L*S),J=v*M+C*A+B*S-(w*S+g*M+U*A),$=w*f+z*M+L*A-(x*M+P*A+B*f),tt=x*S+F*A+g*f-(v*f+z*S+D*A),et=r*G+i*b+a*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=H*et,n[5]=q*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return e[0]=n,e[1]=a,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=i,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=A,e[14]=f,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function E(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new E),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new E(t,e,i,a)},E.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new E(t,e,i,a)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=i,e.north=c,e):new E(n,s,i,c)},E.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=t.length;l<A;l++){var f=e.cartesianToCartographic(t[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,s=e.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var i=t.east,a=t.west,o=e.east,s=e.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(t,A)&&(o[c]=e.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e,n){this.center=t.clone(i(e,t.ZERO)),this.radius=i(n,0)}var l=new t,A=new t,f=new t,h=new t,N=new t,d=new t,I=new t,S=new t,M=new t,O=new t,m=new t,y=new t,p=4/3*n.PI;R.fromPoints=function(e,n){if(a(n)||(n=new R),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],I),o=t.clone(i,l),u=t.clone(i,A),E=t.clone(i,f),s=t.clone(i,h),c=t.clone(i,N),_=t.clone(i,d),T=e.length;for(r=1;r<T;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var P=t.magnitudeSquared(t.subtract(s,o,S)),L=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),D=o,w=s,B=P;L>B&&(B=L,D=u,w=c),F>B&&(B=F,D=E,w=_);var v=M;v.x=.5*(D.x+w.x),v.y=.5*(D.y+w.y),v.z=.5*(D.z+w.z);var g=t.magnitudeSquared(t.subtract(w,v,S)),x=Math.sqrt(g),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=m;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,S));V>X&&(X=V);var H=t.magnitudeSquared(t.subtract(i,v,S));if(H>g){var q=Math.sqrt(H);x=.5*(x+q),g=x*x;var W=q-x;v.x=(x*v.x+W*i.x)/q,v.y=(x*v.y+W*i.y)/q,v.z=(x*v.z+W*i.z)/q}}return x<X?(t.clone(v,n.center),n.radius=x):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,P=new t,L=new e,F=new e;R.fromRectangle2D=function(t,e,n){return R.fromRectangleWithHeights2D(t,e,0,0,n)},R.fromRectangleWithHeights2D=function(e,n,r,o,u){if(a(u)||(u=new R),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=i(n,C),T.southwest(e,L),L.height=r,T.northeast(e,F),F.height=o;var E=n.project(L,U),s=n.project(F,P),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*_,A.z=E.z+.5*l,u};var D=[];R.fromRectangle3D=function(e,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new R),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,D);return R.fromPoints(E,u)},R.fromVertices=function(e,n,r,o){if(a(o)||(o=new R),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=i(n,t.ZERO),r=i(r,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,l),c=t.clone(u,A),_=t.clone(u,f),T=t.clone(u,h),p=t.clone(u,N),C=t.clone(u,d),U=e.length;for(E=0;E<U;E+=r){var P=e[E]+n.x,L=e[E+1]+n.y,F=e[E+2]+n.z;u.x=P,u.y=L,u.z=F,P<s.x&&t.clone(u,s),P>T.x&&t.clone(u,T),L<c.y&&t.clone(u,c),L>p.y&&t.clone(u,p),F<_.z&&t.clone(u,_),F>C.z&&t.clone(u,C)}var D=t.magnitudeSquared(t.subtract(T,s,S)),w=t.magnitudeSquared(t.subtract(p,c,S)),B=t.magnitudeSquared(t.subtract(C,_,S)),v=s,g=T,x=D;w>x&&(x=w,v=c,g=p),B>x&&(x=B,v=_,g=C);var z=M;z.x=.5*(v.x+g.x),z.y=.5*(v.y+g.y),z.z=.5*(v.z+g.z);var G=t.magnitudeSquared(t.subtract(g,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=T.x,V.y=p.y,V.z=C.z;var H=t.multiplyByScalar(t.add(X,V,S),.5,y),q=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,H,S));W>q&&(q=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<q?(t.clone(z,o.center),o.radius=b):(t.clone(H,o.center),o.radius=q),o},R.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new R),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=I;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,l),E=t.clone(i,A),s=t.clone(i,f),c=t.clone(i,h),_=t.clone(i,N),T=t.clone(i,d),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],P=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=P,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),P<s.z&&t.clone(i,s),P>T.z&&t.clone(i,T)}var L=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),D=t.magnitudeSquared(t.subtract(T,s,S)),w=u,B=c,v=L;F>v&&(v=F,w=E,B=_),D>v&&(v=D,w=s,B=T);var g=M;g.x=.5*(w.x+B.x),g.y=.5*(w.y+B.y),g.z=.5*(w.z+B.z);var x=t.magnitudeSquared(t.subtract(B,g,S)),z=Math.sqrt(x),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var H=t.magnitude(t.subtract(i,X,S));H>V&&(V=H);var q=t.magnitudeSquared(t.subtract(i,g,S));if(q>x){var W=Math.sqrt(q);z=.5*(z+W),x=z*z;var Y=W-z;g.x=(z*g.x+Y*i.x)/W,g.y=(z*g.y+Y*i.y)/W,g.z=(z*g.z+Y*i.z)/W}}return z<V?(t.clone(g,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(e,n,r){a(r)||(r=new R);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},R.fromEllipsoid=function(e,n){return a(n)||(n=new R),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var w=new t;R.fromBoundingSpheres=function(e,n){if(a(n)||(n=new R),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return R.clone(e[0],n);if(2===r)return R.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,w)+s.radius)}return n.radius=E,n};var B=new t,v=new t,g=new t;R.fromOrientedBoundingBox=function(e,n){a(n)||(n=new R);var r=e.halfAxes,i=c.getColumn(r,0,B),o=c.getColumn(r,1,v),u=c.getColumn(r,2,g);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},R.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new R(e.center,e.radius)},R.packedLength=4,R.pack=function(t,e,n){n=i(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},R.unpack=function(t,e,n){e=i(e,0),a(n)||(n=new R);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var x=new t,z=new t;R.union=function(e,n,r){a(r)||(r=new R);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,x),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,i,T),t.clone(T,r.center),r.radius=_,r};var G=new t;R.expand=function(e,n,r){r=R.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},R.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},R.transform=function(t,e,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;R.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},R.transformWithoutScale=function(t,e,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;R.computePlaneDistances=function(e,n,r,i){a(i)||(i=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var V=new t,H=new t,q=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return R.projectTo2D=function(e,n,r){n=i(n,j);var a=n.ellipsoid,o=e.center,u=e.radius,E=a.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,H);t.normalize(s,s);var c=t.cross(E,s,q);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),l=K,A=l[0];t.add(E,c,A),t.add(A,s,A),A=l[1],t.add(E,c,A),t.add(A,T,A),A=l[2],t.add(E,_,A),t.add(A,T,A),A=l[3],t.add(E,_,A),t.add(A,s,A),t.negate(E,E),A=l[4],t.add(E,c,A),t.add(A,s,A),A=l[5],t.add(E,c,A),t.add(A,T,A),A=l[6],t.add(E,_,A),t.add(A,T,A),A=l[7],t.add(E,_,A),t.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];t.add(o,N,N);var d=a.cartesianToCartographic(N,k);n.project(d,N)}r=R.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},R.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},R.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},R.prototype.intersectPlane=function(t){return R.intersectPlane(this,t)},R.prototype.distanceSquaredTo=function(t){return R.distanceSquaredTo(this,t)},R.prototype.computePlaneDistances=function(t,e,n){return R.computePlaneDistances(this,t,e,n)},R.prototype.isOccluded=function(t){return R.isOccluded(this,t)},R.prototype.equals=function(t){return R.equals(this,t)},R.prototype.clone=function(t){return R.clone(this,t)},R.prototype.volume=function(){var t=this.radius;return p*t*t*t},R}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,M=r(t[1]))}return S}function a(){return i()&&M}function o(){if(!e(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,m=r(t[1]))}return O}function u(){return o()&&m}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0, +p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(P)){P=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(P=!0,L=r(t[1]))}return P}function R(){return T()&&L}function l(){if(!e(F)){F=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(F=!0,D=r(t[1]))}return F}function A(){return e(w)||(w=/Windows/i.test(I.appVersion)),w}function f(){return l()&&D}function h(){return e(B)||(B="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),B}function N(){if(!e(g)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;g=e(n)&&""!==n,g&&(v=n)}return g}function d(){return N()?v:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,P,L,F,D,w,B,v,g,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(t){switch(t){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(e){return t(e)&&(e===a.UNSIGNED_BYTE||e===a.UNSIGNED_SHORT||e===a.UNSIGNED_INT)},a.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},a.createTypedArrayFromArrayBuffer=function(t,e,n,i){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,i):new Uint16Array(e,n,i)},n(a)}),define("Core/EllipsoidOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(t,e,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(t){t=r(t,r.EMPTY_OBJECT);var n=r(t.radii,l),i=Math.round(r(t.stackPartitions,10)),a=Math.round(r(t.slicePartitions,8)),o=Math.round(r(t.subdivisions,128));this._radii=e.clone(n),this._stackPartitions=i,this._slicePartitions=a,this._subdivisions=o,this._workerName="createEllipsoidOutlineGeometry"}var l=new e(1,1,1),A=Math.cos,f=Math.sin;R.packedLength=e.packedLength+3,R.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),i+=e.packedLength,n[i++]=t._stackPartitions,n[i++]=t._slicePartitions,n[i]=t._subdivisions,n};var h=new e,N={radii:h,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return R.unpack=function(t,n,a){n=r(n,0);var o=e.unpack(t,n,h);n+=e.packedLength;var u=t[n++],E=t[n++],s=t[n++];return i(a)?(a._radii=e.clone(o,a._radii),a._stackPartitions=u,a._slicePartitions=E,a._subdivisions=s,a):(N.stackPartitions=u,N.slicePartitions=E,N.subdivisions=s,new R(N))},R.createGeometry=function(e){var r=e._radii;if(!(r.x<=0||r.y<=0||r.z<=0)){var i,a,R,l,h,N,d=o.fromCartesian3(r),I=e._stackPartitions,S=e._slicePartitions,M=e._subdivisions,O=M*(I+S-1),m=O-S+2,y=new Float64Array(3*m),p=c.createTypedArray(m,2*O),C=0,U=new Array(M),P=new Array(M);for(i=0;i<M;i++)R=_.TWO_PI*i/M,U[i]=A(R),P[i]=f(R);for(i=1;i<I;i++)for(l=Math.PI*i/I,h=A(l),N=f(l),a=0;a<M;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(U.length=S,P.length=S,i=0;i<S;i++)R=_.TWO_PI*i/S,U[i]=A(R),P[i]=f(R);for(y[C++]=0,y[C++]=0,y[C++]=r.z,i=1;i<M;i++)for(l=Math.PI*i/M,h=A(l),N=f(l),a=0;a<S;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(y[C++]=0,y[C++]=0,y[C++]=-r.z,C=0,i=0;i<I-1;++i){var L=i*M;for(a=0;a<M-1;++a)p[C++]=L+a,p[C++]=L+a+1;p[C++]=L+M-1,p[C++]=L}var F=M*(I-1);for(a=1;a<S+1;++a)p[C++]=F,p[C++]=F+a;for(i=0;i<M-2;++i){var D=i*S+1+F,w=(i+1)*S+1+F;for(a=0;a<S-1;++a)p[C++]=w+a,p[C++]=D+a;p[C++]=w+S-1,p[C++]=D+S-1}var B=y.length/3-1;for(a=B-1;a>B-S-1;--a)p[C++]=B,p[C++]=a;var v=new s({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:y})});return new u({attributes:v,indices:p,primitiveType:T.LINES,boundingSphere:t.fromEllipsoid(d)})}},R}),define("Workers/createEllipsoidOutlineGeometry",["../Core/defined","../Core/EllipsoidOutlineGeometry"],function(t,e){"use strict";return function(n,r){return t(n.buffer,r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumGeometry.js index 56a640ea..956ae2eb 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o,E=new o;o.angleBetween=function(t,e){o.normalize(t,c),o.normalize(e,E);var n=o.dot(c,E),r=o.magnitude(o.cross(c,E,c));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,s=e.z,c=i*s-a*u,E=a*o-r*s,_=r*u-i*o;return n.x=c,n.y=E,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var l=new o,f=new o,h=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var s=n(a)?a.radiiSquared:h,c=Math.cos(r);l.x=c*Math.cos(t),l.y=c*Math.sin(t),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,f);var E=Math.sqrt(o.dot(l,f));return f=o.divideByScalar(f,E,f),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(f,l,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,e,r[c])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,e,r[c])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromDegrees(u,s,c,e,r[E])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromRadians(u,s,c,e,r[E])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,s,c){var E=n.x,_=n.y,l=n.z,f=i.x,h=i.y,T=i.z,R=E*E*f*f,d=_*_*h*h,A=l*l*T*T,p=R+d+A,m=Math.sqrt(1/p),N=t.multiplyByScalar(n,m,a);if(p<s)return isFinite(m)?t.clone(N,c):void 0;var I=u.x,y=u.y,S=u.z,O=o;O.x=N.x*I*2,O.y=N.y*y*2,O.z=N.z*S*2;var M,C,w,v,g,P,F,x,L,U,D,B=(1-m)*t.magnitude(n)/(.5*t.magnitude(O)),z=0;do{B-=z,w=1/(1+B*I),v=1/(1+B*y),g=1/(1+B*S),P=w*w,F=v*v,x=g*g,L=P*w,U=F*v,D=x*g,M=R*P+d*F+A*x-1,C=R*L*I+d*U*y+A*D*S;z=M/(-2*C)}while(Math.abs(M)>r.EPSILON12);return e(c)?(c.x=E*w,c.y=_*v,c.z=l*g,c):new t(E*w,_*v,l*g)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var s=new t,c=new t,E=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),l=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),f=a.EPSILON1;return u.fromCartesian=function(e,n,i){var h=r(n)?n.oneOverRadii:_,T=r(n)?n.oneOverRadiiSquared:l,R=r(n)?n._centerToleranceSquared:f,d=o(e,h,T,R,c);if(r(d)){var A=t.multiplyComponents(d,T,s);A=t.normalize(A,A);var p=t.subtract(e,d,E),m=Math.atan2(A.y,A.x),N=Math.asin(A.z),I=a.sign(t.dot(p,e))*t.magnitude(p);return r(i)?(i.longitude=m,i.latitude=N,i.height=I,i):new u(m,N,I)}},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,E(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(E(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=s,n.z=c,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var l=new t,f=new t;_.prototype.cartographicToCartesian=function(e,n){var r=l,a=f;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var h=new t,T=new t,R=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,T);if(i(a)){var o=this.geodeticSurfaceNormal(a,h),u=t.subtract(n,a,R),c=Math.atan2(o.y,o.x),E=Math.asin(o.z),_=s.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=c,r.latitude=E,r.height=_,r):new e(c,E,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return c(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,s,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i,a,o,u,s,c){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function E(t){for(var e=0,n=0;n<3;++n){var r=t[s.getElementIndex(T[n],h[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[s.getElementIndex(T[a],h[a])]);o>r&&(i=a,r=o)}var c=1,E=0,_=h[i],l=T[i];if(Math.abs(t[s.getElementIndex(l,_)])>n){var f,R=t[s.getElementIndex(l,l)],d=t[s.getElementIndex(_,_)],A=t[s.getElementIndex(l,_)],p=(R-d)/2/A;f=p<0?-1/(-p+Math.sqrt(1+p*p)):1/(p+Math.sqrt(1+p*p)),c=1/Math.sqrt(1+f*f),E=f*c}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(_,_)]=e[s.getElementIndex(l,l)]=c,e[s.getElementIndex(l,_)]=E,e[s.getElementIndex(_,l)]=-E,e}s.packedLength=9,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},s.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,c=t.y*t.z,E=t.y*t.w,_=t.z*t.z,l=t.z*t.w,f=t.w*t.w,h=n-u-_+f,T=2*(i-l),R=2*(a+E),d=2*(i+l),A=-n+u-_+f,p=2*(c-o),m=2*(a-E),N=2*(c+o),I=-n-u+_+f;return r(e)?(e[0]=h,e[1]=d,e[2]=m,e[3]=T,e[4]=A,e[5]=N,e[6]=R,e[7]=p,e[8]=I,e):new s(h,T,R,d,A,p,m,N,I)},s.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),c=Math.sin(t.roll),E=n*i,_=-a*u+c*o*i,l=c*u+a*o*i,f=n*u,h=a*i+c*o*u,T=-c*i+a*o*u,R=-o,d=c*n,A=a*n;return r(e)?(e[0]=E,e[1]=f,e[2]=R,e[3]=_,e[4]=h,e[5]=d,e[6]=l,e[7]=T,e[8]=A,e):new s(E,_,l,f,h,T,R,d,A)},s.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(t,e,n,r){r=s.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(t,e,n,r){return r=s.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var l=new t;s.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],l)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],l)),n};var f=new t;s.getMaximumScale=function(e){return s.getScale(e,f),t.maximumComponent(f)},s.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],c=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],E=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=E,n[8]=_,n},s.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},s.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},s.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,s=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},s.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],s=t[2],c=t[5],E=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=s,e[7]=c,e[8]=E,e};var h=[1,0,0],T=[2,2,1],R=new s,d=new s;return s.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=s.clone(s.IDENTITY,e.unitary),l=e.diagonal=s.clone(t,e.diagonal),f=n*c(l);a<10&&E(l)>f;)_(l,R),s.transpose(R,d),s.multiply(l,R,l),s.multiply(d,l,l),s.multiply(o,R,o),++i>2&&(++a,i=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],s=t[5],c=t[8];return e*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],c=t[6],E=t[7],_=t[8],l=s.determinant(t);e[0]=o*_-E*u,e[1]=E*i-r*_,e[2]=r*u-o*i,e[3]=c*u-a*_,e[4]=n*_-c*i,e[5]=a*i-n*u,e[6]=a*E-c*o,e[7]=c*r-n*E,e[8]=n*o-a*r;var f=1/l;return s.multiplyByScalar(e,f,e)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,c);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){ -var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(t,e,n,i,a,o,u,s,c,E,_,l,f,h,T,R){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(f,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(E,0),this[7]=r(h,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(T,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(R,0)}E.packedLength=16,E.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},E.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new E),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},E.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new E(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},E.fromArray=E.unpack,E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},E.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new E(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},E.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new E);var a=n.x,o=n.y,u=n.z,s=e.x*e.x,c=e.x*e.y,_=e.x*e.z,l=e.x*e.w,f=e.y*e.y,h=e.y*e.z,T=e.y*e.w,R=e.z*e.z,d=e.z*e.w,A=e.w*e.w,p=s-f-R+A,m=2*(c-d),N=2*(_+T),I=2*(c+d),y=-s+f-R+A,S=2*(h-l),O=2*(_-T),M=2*(h+l),C=-s-f+R+A;return r[0]=p*a,r[1]=I*a,r[2]=O*a,r[3]=0,r[4]=m*o,r[5]=y*o,r[6]=M*o,r[7]=0,r[8]=N*u,r[9]=S*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},E.fromTranslationRotationScale=function(t,e){return E.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},E.fromTranslation=function(t,e){return E.fromRotationTranslation(s.IDENTITY,t,e)},E.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},E.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,l=new t,f=new t;E.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,l),l),t.normalize(t.cross(l,_,f),f);var u=l.x,s=l.y,c=l.z,h=_.x,T=_.y,R=_.z,d=f.x,A=f.y,p=f.z,m=r.x,N=r.y,I=r.z,y=u*-m+s*-N+c*-I,S=d*-m+A*-N+p*-I,O=h*m+T*N+R*I;return i(n)?(n[0]=u,n[1]=d,n[2]=-h,n[3]=0,n[4]=s,n[5]=A,n[6]=-T,n[7]=0,n[8]=c,n[9]=p,n[10]=-R,n[11]=0,n[12]=y,n[13]=S,n[14]=O,n[15]=1,n):new E(u,s,c,y,d,A,p,S,-h,-T,-R,O,0,0,0,1)},E.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},E.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),s=1/(r-n),c=1/(a-i),E=-(e+t)*u,_=-(r+n)*s,l=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=E,o[13]=_,o[14]=l,o[15]=1,o},E.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),s=2*i/(r-n),c=(e+t)/(e-t),E=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=E,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},E.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),E=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},E.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),s=r(t.height,0);e=r(e,0),n=r(n,1);var c=.5*u,E=.5*s,_=.5*(n-e),l=c,f=E,h=_,T=a+c,R=o+E,d=e+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=f,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=h,i[11]=0,i[12]=T,i[13]=R,i[14]=d,i[15]=1,i},E.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},E.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},E.getElementIndex=function(t,e){return 4*t+e},E.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},E.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},E.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var h=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],h)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],h)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],h)),n};var T=new t;E.getMaximumScale=function(e){return E.getScale(e,T),t.maximumComponent(T)},E.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],s=t[5],c=t[6],E=t[7],_=t[8],l=t[9],f=t[10],h=t[11],T=t[12],R=t[13],d=t[14],A=t[15],p=e[0],m=e[1],N=e[2],I=e[3],y=e[4],S=e[5],O=e[6],M=e[7],C=e[8],w=e[9],v=e[10],g=e[11],P=e[12],F=e[13],x=e[14],L=e[15],U=r*p+u*m+_*N+T*I,D=i*p+s*m+l*N+R*I,B=a*p+c*m+f*N+d*I,z=o*p+E*m+h*N+A*I,b=r*y+u*S+_*O+T*M,G=i*y+s*S+l*O+R*M,V=a*y+c*S+f*O+d*M,X=o*y+E*S+h*O+A*M,q=r*C+u*w+_*v+T*g,W=i*C+s*w+l*v+R*g,H=a*C+c*w+f*v+d*g,Y=o*C+E*w+h*v+A*g,k=r*P+u*F+_*x+T*L,K=i*P+s*F+l*x+R*L,Z=a*P+c*F+f*x+d*L,j=o*P+E*F+h*x+A*L;return n[0]=U,n[1]=D,n[2]=B,n[3]=z,n[4]=b,n[5]=G,n[6]=V,n[7]=X,n[8]=q,n[9]=W,n[10]=H,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},E.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=t[12],f=t[13],h=t[14],T=e[0],R=e[1],d=e[2],A=e[4],p=e[5],m=e[6],N=e[8],I=e[9],y=e[10],S=e[12],O=e[13],M=e[14],C=r*T+o*R+c*d,w=i*T+u*R+E*d,v=a*T+s*R+_*d,g=r*A+o*p+c*m,P=i*A+u*p+E*m,F=a*A+s*p+_*m,x=r*N+o*I+c*y,L=i*N+u*I+E*y,U=a*N+s*I+_*y,D=r*S+o*O+c*M+l,B=i*S+u*O+E*M+f,z=a*S+s*O+_*M+h;return n[0]=C,n[1]=w,n[2]=v,n[3]=0,n[4]=g,n[5]=P,n[6]=F,n[7]=0,n[8]=x,n[9]=L,n[10]=U,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},E.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=e[0],f=e[1],h=e[2],T=e[3],R=e[4],d=e[5],A=e[6],p=e[7],m=e[8],N=r*l+o*f+c*h,I=i*l+u*f+E*h,y=a*l+s*f+_*h,S=r*T+o*R+c*d,O=i*T+u*R+E*d,M=a*T+s*R+_*d,C=r*A+o*p+c*m,w=i*A+u*p+E*m,v=a*A+s*p+_*m;return n[0]=N,n[1]=I,n[2]=y,n[3]=0,n[4]=S,n[5]=O,n[6]=M,n[7]=0,n[8]=C,n[9]=w,n[10]=v,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},E.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],s=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=s,n[15]=t[15],n};var R=new t;E.multiplyByUniformScale=function(t,e,n){return R.x=e,R.y=e,R.z=e,E.multiplyByScale(t,R,n)},E.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?E.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,s=t[1]*r+t[5]*i+t[9]*a+t[13]*o,c=t[2]*r+t[6]*i+t[10]*a+t[14]*o,E=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=s,n.z=c,n.w=E,n},E.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,s=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=s,n},E.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],s=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=s,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},E.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},E.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},E.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},E.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},E.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var d=new s,A=new s,p=new e,m=new e(0,0,0,1);return E.inverse=function(t,n){if(s.equalsEpsilon(E.getRotation(t,d),A,u.EPSILON7)&&e.equals(E.getRow(t,3,p),m))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],l=t[5],f=t[9],h=t[13],T=t[2],R=t[6],N=t[10],I=t[14],y=t[3],S=t[7],O=t[11],M=t[15],C=N*M,w=I*O,v=R*M,g=I*S,P=R*O,F=N*S,x=T*M,L=I*y,U=T*O,D=N*y,B=T*S,z=R*y,b=C*l+g*f+P*h-(w*l+v*f+F*h),G=w*_+x*f+D*h-(C*_+L*f+U*h),V=v*_+L*l+B*h-(g*_+x*l+z*h),X=F*_+U*l+z*f-(P*_+D*l+B*f),q=w*i+v*a+F*o-(C*i+g*a+P*o),W=C*r+L*a+U*o-(w*r+x*a+D*o),H=g*r+x*i+z*o-(v*r+L*i+B*o),Y=P*r+D*i+B*a-(F*r+U*i+z*a);C=a*h,w=o*f,v=i*h,g=o*l,P=i*f,F=a*l,x=r*h,L=o*_,U=r*f,D=a*_,B=r*l,z=i*_;var k=C*S+g*O+P*M-(w*S+v*O+F*M),K=w*y+x*O+D*M-(C*y+L*O+U*M),Z=v*y+L*S+B*M-(g*y+x*S+z*M),j=F*y+U*S+z*O-(P*y+D*S+B*O),Q=v*N+F*I+w*R-(P*I+C*R+g*N),J=U*I+C*T+L*N-(x*N+D*I+w*T),$=x*R+z*I+g*T-(B*I+v*T+L*R),tt=B*N+P*T+D*R-(U*R+z*N+F*T),et=r*b+i*G+a*V+o*X;if(Math.abs(et)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=b*et,n[1]=G*et,n[2]=V*et,n[3]=X*et,n[4]=q*et,n[5]=W*et,n[6]=H*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},E.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],s=t[8],c=t[9],E=t[10],_=t[12],l=t[13],f=t[14],h=-n*_-r*l-i*f,T=-a*_-o*l-u*f,R=-s*_-c*l-E*f;return e[0]=n,e[1]=a,e[2]=s,e[3]=0,e[4]=r,e[5]=o,e[6]=c,e[7]=0,e[8]=i,e[9]=u,e[10]=E,e[11]=0,e[12]=h,e[13]=T,e[14]=R,e[15]=1,e},E.IDENTITY=o(new E(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN0ROW3=3,E.COLUMN1ROW0=4,E.COLUMN1ROW1=5,E.COLUMN1ROW2=6,E.COLUMN1ROW3=7,E.COLUMN2ROW0=8,E.COLUMN2ROW1=9,E.COLUMN2ROW2=10,E.COLUMN2ROW3=11,E.COLUMN3ROW0=12,E.COLUMN3ROW1=13,E.COLUMN3ROW2=14,E.COLUMN3ROW3=15,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},E}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},s.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new s(t,e,i,a)},s.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new s(t,e,i,a)},s.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,E=-Number.MAX_VALUE,_=0,l=t.length;_<l;_++){var f=t[_];n=Math.min(n,f.longitude),i=Math.max(i,f.longitude),c=Math.min(c,f.latitude),E=Math.max(E,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;a=Math.min(a,h),o=Math.max(o,h)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=c,e.east=i,e.north=E,e):new s(n,c,i,E)},s.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,E=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=0,T=t.length;h<T;h++){var R=e.cartesianToCartographic(t[h]);o=Math.min(o,R.longitude),c=Math.max(c,R.longitude),l=Math.min(l,R.latitude),f=Math.max(f,R.latitude);var d=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;E=Math.min(E,d),_=Math.max(_,d)}return c-o>_-E&&(o=E,c=_,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=c,i.north=f,i):new s(o,l,c,f)},s.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},s.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},s.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},s.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},s.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new t(o,s)},s.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.negativePiToPi(Math.max(a,c)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=E)){var l=Math.max(t.south,e.south),f=Math.min(t.north,e.north);if(!(l>=f))return r(n)?(n.west=E,n.south=l,n.east=_,n.north=f,n):new s(E,l,_,f)}},s.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(t,e,n){r(n)||(n=new s);var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.convertLongitudeRange(Math.min(a,c)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=E,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},s.expand=function(t,e,n){return r(n)||(n=new s),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},s.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var c=new t;return s.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var E=0,_=t.north,l=t.south,f=t.east,h=t.west,T=c;T.height=i,T.longitude=h,T.latitude=_,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=l,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=_<0?_:l>0?l:0;for(var R=1;R<8;++R)T.longitude=-Math.PI+R*u.PI_OVER_TWO,s.contains(t,T)&&(o[E]=e.cartographicToCartesian(T,o[E]),E++);return 0===T.latitude&&(T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++),o.length=E,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,s,c,E,_){"use strict";function l(e,n){this.center=t.clone(r(e,t.ZERO)),this.radius=r(n,0)}var f=new t,h=new t,T=new t,R=new t,d=new t,A=new t,p=new t,m=new t,N=new t,I=new t,y=new t,S=new t;l.fromPoints=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,a=t.clone(e[0],p),o=t.clone(a,f),u=t.clone(a,h),s=t.clone(a,T),c=t.clone(a,R),E=t.clone(a,d),_=t.clone(a,A),O=e.length;for(r=1;r<O;r++){t.clone(e[r],a);var M=a.x,C=a.y,w=a.z;M<o.x&&t.clone(a,o),M>c.x&&t.clone(a,c),C<u.y&&t.clone(a,u),C>E.y&&t.clone(a,E),w<s.z&&t.clone(a,s),w>_.z&&t.clone(a,_)}var v=t.magnitudeSquared(t.subtract(c,o,m)),g=t.magnitudeSquared(t.subtract(E,u,m)),P=t.magnitudeSquared(t.subtract(_,s,m)),F=o,x=c,L=v;g>L&&(L=g,F=u,x=E),P>L&&(L=P,F=s,x=_);var U=N;U.x=.5*(F.x+x.x),U.y=.5*(F.y+x.y),U.z=.5*(F.z+x.z);var D=t.magnitudeSquared(t.subtract(x,U,m)),B=Math.sqrt(D),z=I;z.x=o.x,z.y=u.y,z.z=s.z;var b=y;b.x=c.x,b.y=E.y,b.z=_.z;var G=t.multiplyByScalar(t.add(z,b,m),.5,S),V=0;for(r=0;r<O;r++){t.clone(e[r],a);var X=t.magnitude(t.subtract(a,G,m));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(a,U,m));if(q>D){var W=Math.sqrt(q);B=.5*(B+W),D=B*B;var H=W-B;U.x=(B*U.x+H*a.x)/W,U.y=(B*U.y+H*a.y)/W,U.z=(B*U.z+H*a.z)/W}}return B<V?(t.clone(U,n.center),n.radius=B):(t.clone(G,n.center),n.radius=V),n};var O=new o,M=new t,C=new t,w=new e,v=new e;l.fromRectangle2D=function(t,e,n){return l.fromRectangleWithHeights2D(t,e,0,0,n)},l.fromRectangleWithHeights2D=function(e,n,a,o,u){if(i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=r(n,O),_.southwest(e,w),w.height=a,_.northeast(e,v),v.height=o;var s=n.project(w,M),c=n.project(v,C),E=c.x-s.x,f=c.y-s.y,h=c.z-s.z;u.radius=.5*Math.sqrt(E*E+f*f+h*h);var T=u.center;return T.x=s.x+.5*E,T.y=s.y+.5*f,T.z=s.z+.5*h,u};var g=[];l.fromRectangle3D=function(e,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=_.subsample(e,n,o,g);return l.fromPoints(s,u)},l.fromVertices=function(e,n,a,o){if(i(o)||(o=new l),!i(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=r(n,t.ZERO),a=r(a,3);var u=p;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var s,c=t.clone(u,f),E=t.clone(u,h),_=t.clone(u,T),O=t.clone(u,R),M=t.clone(u,d),C=t.clone(u,A),w=e.length;for(s=0;s<w;s+=a){var v=e[s]+n.x,g=e[s+1]+n.y,P=e[s+2]+n.z;u.x=v,u.y=g,u.z=P,v<c.x&&t.clone(u,c),v>O.x&&t.clone(u,O),g<E.y&&t.clone(u,E),g>M.y&&t.clone(u,M),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var F=t.magnitudeSquared(t.subtract(O,c,m)),x=t.magnitudeSquared(t.subtract(M,E,m)),L=t.magnitudeSquared(t.subtract(C,_,m)),U=c,D=O,B=F;x>B&&(B=x,U=E,D=M),L>B&&(B=L,U=_,D=C);var z=N;z.x=.5*(U.x+D.x),z.y=.5*(U.y+D.y),z.z=.5*(U.z+D.z);var b=t.magnitudeSquared(t.subtract(D,z,m)),G=Math.sqrt(b),V=I;V.x=c.x,V.y=E.y,V.z=_.z;var X=y;X.x=O.x,X.y=M.y,X.z=C.z;var q=t.multiplyByScalar(t.add(V,X,m),.5,S),W=0;for(s=0;s<w;s+=a){u.x=e[s]+n.x,u.y=e[s+1]+n.y,u.z=e[s+2]+n.z;var H=t.magnitude(t.subtract(u,q,m));H>W&&(W=H);var Y=t.magnitudeSquared(t.subtract(u,z,m));if(Y>b){var k=Math.sqrt(Y);G=.5*(G+k),b=G*G;var K=k-G;z.x=(G*z.x+K*u.x)/k,z.y=(G*z.y+K*u.y)/k,z.z=(G*z.z+K*u.z)/k}}return G<W?(t.clone(z,o.center),o.radius=G):(t.clone(q,o.center),o.radius=W),o},l.fromEncodedCartesianVertices=function(e,n,r){if(i(r)||(r=new l),!i(e)||!i(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var a=p;a.x=e[0]+n[0],a.y=e[1]+n[1],a.z=e[2]+n[2];var o,u=t.clone(a,f),s=t.clone(a,h),c=t.clone(a,T),E=t.clone(a,R),_=t.clone(a,d),O=t.clone(a,A),M=e.length;for(o=0;o<M;o+=3){var C=e[o]+n[o],w=e[o+1]+n[o+1],v=e[o+2]+n[o+2];a.x=C,a.y=w,a.z=v,C<u.x&&t.clone(a,u),C>E.x&&t.clone(a,E),w<s.y&&t.clone(a,s),w>_.y&&t.clone(a,_),v<c.z&&t.clone(a,c),v>O.z&&t.clone(a,O)}var g=t.magnitudeSquared(t.subtract(E,u,m)),P=t.magnitudeSquared(t.subtract(_,s,m)),F=t.magnitudeSquared(t.subtract(O,c,m)),x=u,L=E,U=g;P>U&&(U=P,x=s,L=_),F>U&&(U=F,x=c,L=O);var D=N;D.x=.5*(x.x+L.x),D.y=.5*(x.y+L.y),D.z=.5*(x.z+L.z);var B=t.magnitudeSquared(t.subtract(L,D,m)),z=Math.sqrt(B),b=I;b.x=u.x,b.y=s.y,b.z=c.z;var G=y;G.x=E.x,G.y=_.y,G.z=O.z;var V=t.multiplyByScalar(t.add(b,G,m),.5,S),X=0;for(o=0;o<M;o+=3){a.x=e[o]+n[o],a.y=e[o+1]+n[o+1],a.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(a,V,m));q>X&&(X=q);var W=t.magnitudeSquared(t.subtract(a,D,m));if(W>B){var H=Math.sqrt(W);z=.5*(z+H),B=z*z;var Y=H-z;D.x=(z*D.x+Y*a.x)/H,D.y=(z*D.y+Y*a.y)/H,D.z=(z*D.z+Y*a.z)/H}}return z<X?(t.clone(D,r.center),r.radius=z):(t.clone(V,r.center),r.radius=X),r},l.fromCornerPoints=function(e,n,r){i(r)||(r=new l);var a=r.center;return t.add(e,n,a),t.multiplyByScalar(a,.5,a),r.radius=t.distance(a,n),r},l.fromEllipsoid=function(e,n){return i(n)||(n=new l),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var P=new t;l.fromBoundingSpheres=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return l.clone(e[0],n);if(2===r)return l.union(e[0],e[1],n);var a,o=[];for(a=0;a<r;a++)o.push(e[a].center);n=l.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=e[a];s=Math.max(s,t.distance(u,c.center,P)+c.radius)}return n.radius=s,n};var F=new t,x=new t,L=new t;l.fromOrientedBoundingBox=function(e,n){i(n)||(n=new l);var r=e.halfAxes,a=c.getColumn(r,0,F),o=c.getColumn(r,1,x),u=c.getColumn(r,2,L);return t.add(a,o,a),t.add(a,u,a),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(a),n},l.clone=function(e,n){if(i(e))return i(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new l(e.center,e.radius)},l.packedLength=4,l.pack=function(t,e,n){n=r(n,0);var i=t.center;return e[n++]=i.x,e[n++]=i.y,e[n++]=i.z,e[n]=t.radius,e},l.unpack=function(t,e,n){e=r(e,0),i(n)||(n=new l);var a=n.center;return a.x=t[e++],a.y=t[e++],a.z=t[e++],n.radius=t[e],n};var U=new t,D=new t;l.union=function(e,n,r){i(r)||(r=new l);var a=e.center,o=e.radius,u=n.center,s=n.radius,c=t.subtract(u,a,U),E=t.magnitude(c);if(o>=E+s)return e.clone(r),r;if(s>=E+o)return n.clone(r),r;var _=.5*(o+E+s),f=t.multiplyByScalar(c,(-o+_)/E,D);return t.add(f,a,f),t.clone(f,r.center),r.radius=_,r};var B=new t;l.expand=function(e,n,r){r=l.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,B));return i>r.radius&&(r.radius=i),r},l.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},l.transform=function(t,e,n){return i(n)||(n=new l),n.center=E.multiplyByPoint(e,t.center,n.center),n.radius=E.getMaximumScale(e)*t.radius,n};var z=new t;l.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,z);return t.magnitudeSquared(r)-e.radius*e.radius},l.transformWithoutScale=function(t,e,n){return i(n)||(n=new l),n.center=E.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var b=new t;l.computePlaneDistances=function(e,n,r,a){i(a)||(a=new s);var o=t.subtract(e.center,n,b),u=t.dot(r,o);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var G=new t,V=new t,X=new t,q=new t,W=new t,H=new e,Y=new Array(8),k=0;k<8;++k)Y[k]=new t;var K=new o;return l.projectTo2D=function(e,n,i){n=r(n,K);var a=n.ellipsoid,o=e.center,u=e.radius,s=a.geodeticSurfaceNormal(o,G),c=t.cross(t.UNIT_Z,s,V);t.normalize(c,c);var E=t.cross(s,c,X);t.normalize(E,E),t.multiplyByScalar(s,u,s),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c);var _=t.negate(E,W),f=t.negate(c,q),h=Y,T=h[0];t.add(s,E,T),t.add(T,c,T),T=h[1],t.add(s,E,T),t.add(T,f,T),T=h[2],t.add(s,_,T),t.add(T,f,T),T=h[3],t.add(s,_,T),t.add(T,c,T),t.negate(s,s),T=h[4],t.add(s,E,T),t.add(T,c,T),T=h[5],t.add(s,E,T),t.add(T,f,T),T=h[6],t.add(s,_,T),t.add(T,f,T),T=h[7],t.add(s,_,T),t.add(T,c,T);for(var R=h.length,d=0;d<R;++d){var A=h[d];t.add(o,A,A);var p=a.cartesianToCartographic(A,H);n.project(p,A)}i=l.fromPoints(h,i),o=i.center;var m=o.x,N=o.y,I=o.z;return o.x=I,o.y=m,o.z=N,i},l.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},l.equals=function(e,n){return e===n||i(e)&&i(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},l.prototype.intersectPlane=function(t){return l.intersectPlane(this,t)},l.prototype.distanceSquaredTo=function(t){return l.distanceSquaredTo(this,t)},l.prototype.computePlaneDistances=function(t,e,n){return l.computePlaneDistances(this,t,e,n)},l.prototype.isOccluded=function(t){return l.isOccluded(this,t)},l.prototype.equals=function(t){return l.equals(this,t)},l.prototype.clone=function(t){return l.clone(this,t)},l}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(N)&&(N=!1,!l())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(N=!0,I=r(t[1]))}return N}function a(){return i()&&I}function o(){if(!e(y)&&(y=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(y=!0,S=r(t[1]))}return y}function u(){return o()&&S}function s(){if(!e(O)){O=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(O=!0,M=r(t[1]),M.isNightly=!!t[2])}return O}function c(){return s()&&M}function E(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(C=!0, -w=r(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(C=!0,w=r(t[1]))}return C}function _(){return E()&&w}function l(){if(!e(v)){v=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(v=!0,g=r(t[1]))}return v}function f(){return l()&&g}function h(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(P=!0,F=r(t[1]))}return P}function T(){return e(x)||(x=/Windows/i.test(m.appVersion)),x}function R(){return h()&&F}function d(){return e(L)||(L="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),L}function A(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(U=n)}return D}function p(){return A()?U:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var N,I,y,S,O,M,C,w,v,g,P,F,x,L,U,D,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:E,internetExplorerVersion:_,isEdge:l,edgeVersion:f,isFirefox:h,firefoxVersion:R,isWindows:T,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:d,supportsImageRenderingPixelated:A,imageRenderingValue:p};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,n,r,i,a,o){"use strict";function u(e,n){this.normal=t.clone(e),this.distance=n}u.fromPointNormal=function(e,r,i){var a=-t.dot(r,e);return n(i)?(t.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new t;u.fromCartesian4=function(e,r){var i=t.fromCartesian4(e,s),a=e.w;return n(r)?(t.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(e,n){return t.dot(e.normal,n)+e.distance};var c=new t;return u.transform=function(e,n,r){return o.multiplyByPointAsVector(n,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(e,r){return n(r)?(t.clone(e.normal,r.normal),r.distance=e.distance,r):new u(e.normal,e.distance)},u.equals=function(e,n){return e.distance===n.distance&&t.equals(e.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(t.UNIT_Y,0)),u}),define("Core/CullingVolume",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./DeveloperError","./Intersect","./Plane"],function(t,e,n,r,i,a,o){"use strict";function u(t){this.planes=n(t,[])}var s=[new t,new t,new t];t.clone(t.UNIT_X,s[0]),t.clone(t.UNIT_Y,s[1]),t.clone(t.UNIT_Z,s[2]);var c=new t,E=new t,_=new o(new t(1,0,0),0);return u.fromBoundingSphere=function(n,i){r(i)||(i=new u);var a=s.length,o=i.planes;o.length=2*a;for(var _=n.center,l=n.radius,f=0,h=0;h<a;++h){var T=s[h],R=o[f],d=o[f+1];r(R)||(R=o[f]=new e),r(d)||(d=o[f+1]=new e),t.multiplyByScalar(T,-l,c),t.add(_,c,c),R.x=T.x,R.y=T.y,R.z=T.z,R.w=-t.dot(T,c),t.multiplyByScalar(T,l,c),t.add(_,c,c),d.x=-T.x,d.y=-T.y,d.z=-T.z,d.w=-t.dot(t.negate(T,E),c),f+=2}return i},u.prototype.computeVisibility=function(t){for(var e=this.planes,n=!1,r=0,i=e.length;r<i;++r){var u=t.intersectPlane(o.fromCartesian4(e[r],_));if(u===a.OUTSIDE)return a.OUTSIDE;u===a.INTERSECTING&&(n=!0)}return n?a.INTERSECTING:a.INSIDE},u.prototype.computeVisibilityWithPlaneMask=function(t,e){if(e===u.MASK_OUTSIDE||e===u.MASK_INSIDE)return e;for(var n=u.MASK_INSIDE,r=this.planes,i=0,s=r.length;i<s;++i){var c=i<31?1<<i:0;if(!(i<31&&0==(e&c))){var E=t.intersectPlane(o.fromCartesian4(r[i],_));if(E===a.OUTSIDE)return u.MASK_OUTSIDE;E===a.INTERSECTING&&(n|=c)}}return n},u.MASK_OUTSIDE=4294967295,u.MASK_INSIDE=0,u.MASK_INDETERMINATE=2147483647,u}),define("Core/OrthographicOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._orthographicMatrix=new u}function c(t){t.top===t._top&&t.bottom===t._bottom&&t.left===t._left&&t.right===t._right&&t.near===t._near&&t.far===t._far||(t._left=t.left,t._right=t.right,t._top=t.top,t._bottom=t.bottom,t._near=t.near,t._far=t.far,t._orthographicMatrix=u.computeOrthographicOffCenter(t.left,t.right,t.bottom,t.top,t.near,t.far,t._orthographicMatrix))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._orthographicMatrix}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E);t.normalize(d,d);var A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(d,h,p),t.add(A,p,p);var m=o[0];return i(m)||(m=o[0]=new e),m.x=d.x,m.y=d.y,m.z=d.z,m.w=-t.dot(d,p),t.multiplyByScalar(d,c,p),t.add(A,p,p),m=o[1],i(m)||(m=o[1]=new e),m.x=-d.x,m.y=-d.y,m.z=-d.z,m.w=-t.dot(t.negate(d,f),p),t.multiplyByScalar(a,s,p),t.add(A,p,p),m=o[2],i(m)||(m=o[2]=new e),m.x=a.x,m.y=a.y,m.z=a.z,m.w=-t.dot(a,p),t.multiplyByScalar(a,u,p),t.add(A,p,p),m=o[3],i(m)||(m=o[3]=new e),m.x=-a.x,m.y=-a.y,m.z=-a.z,m.w=-t.dot(t.negate(a,f),p),m=o[4],i(m)||(m=o[4]=new e),m.x=r.x,m.y=r.y,m.z=r.z,m.w=-t.dot(r,A),t.multiplyByScalar(r,R,p),t.add(n,p,p),m=o[5],i(m)||(m=o[5]=new e),m.x=-r.x,m.y=-r.y,m.z=-r.z,m.w=-t.dot(t.negate(r,f),p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=this.right-this.left,a=this.top-this.bottom,o=i/t,u=a/e;return r.x=o,r.y=u,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.left=this.left,t.right=this.right,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/OrthographicFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./OrthographicOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.width=t.width,this._width=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far}function u(t){var e=t._offCenterFrustum;if(t.width!==t._width||t.aspectRatio!==t._aspectRatio||t.near!==t._near||t.far!==t._far){t._aspectRatio=t.aspectRatio,t._width=t.width,t._near=t.near,t._far=t.far;var n=1/t.aspectRatio;e.right=.5*t.width,e.left=-e.right,e.top=n*e.right,e.bottom=-e.top,e.near=t.near,e.far=t.far}}return o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.width,n[r++]=t.aspectRatio,n[r++]=t.near,n[r]=t.far,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.width=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.width=this.width,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._width=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.width===t.width&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/PerspectiveOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._perspectiveMatrix=new u,this._infinitePerspective=new u}function c(t){var e=t.top,n=t.bottom,r=t.right,i=t.left,a=t.near,o=t.far;e===t._top&&n===t._bottom&&i===t._left&&r===t._right&&a===t._near&&o===t._far||(t._left=i,t._right=r,t._top=e,t._bottom=n,t._near=a,t._far=o,t._perspectiveMatrix=u.computePerspectiveOffCenter(i,r,n,e,a,o,t._perspectiveMatrix),t._infinitePerspective=u.computeInfinitePerspectiveOffCenter(i,r,n,e,a,t._infinitePerspective))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._perspectiveMatrix}},infiniteProjectionMatrix:{get:function(){return c(this),this._infinitePerspective}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E),A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(r,R,p),t.add(n,p,p);var m=f;t.multiplyByScalar(d,h,m),t.add(A,m,m),t.subtract(m,n,m),t.normalize(m,m),t.cross(m,a,m),t.normalize(m,m);var N=o[0];return i(N)||(N=o[0]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(d,c,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(a,m,m),t.normalize(m,m),N=o[1],i(N)||(N=o[1]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,s,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(d,m,m),t.normalize(m,m),N=o[2],i(N)||(N=o[2]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,u,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(m,d,m),t.normalize(m,m),N=o[3],i(N)||(N=o[3]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),N=o[4],i(N)||(N=o[4]=new e),N.x=r.x,N.y=r.y,N.z=r.z,N.w=-t.dot(r,A),t.negate(r,m),N=o[5],i(N)||(N=o[5]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=1/this.near,a=this.top*i,o=2*n*a/e;a=this.right*i;var u=2*n*a/t;return r.x=u,r.y=o,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.right=this.right,t.left=this.left,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/PerspectiveFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./PerspectiveOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.fov=t.fov,this._fov=void 0,this._fovy=void 0,this._sseDenominator=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far,this.xOffset=e(t.xOffset,0),this._xOffset=this.xOffset,this.yOffset=e(t.yOffset,0),this._yOffset=this.yOffset}function u(t){var e=t._offCenterFrustum;t.fov===t._fov&&t.aspectRatio===t._aspectRatio&&t.near===t._near&&t.far===t._far&&t.xOffset===t._xOffset&&t.yOffset===t._yOffset||(t._aspectRatio=t.aspectRatio,t._fov=t.fov,t._fovy=t.aspectRatio<=1?t.fov:2*Math.atan(Math.tan(.5*t.fov)/t.aspectRatio),t._near=t.near,t._far=t.far,t._sseDenominator=2*Math.tan(.5*t._fovy),t._xOffset=t.xOffset,t._yOffset=t.yOffset,e.top=t.near*Math.tan(.5*t._fovy),e.bottom=-e.top,e.right=t.aspectRatio*e.top,e.left=-e.right,e.near=t.near,e.far=t.far,e.right+=t.xOffset,e.left+=t.xOffset,e.top+=t.yOffset,e.bottom+=t.yOffset)}return o.packedLength=6,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.fov,n[r++]=t.aspectRatio,n[r++]=t.near,n[r++]=t.far,n[r++]=t.xOffset,n[r]=t.yOffset,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.fov=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r++],i.xOffset=t[r++],i.yOffset=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}},infiniteProjectionMatrix:{get:function(){return u(this),this._offCenterFrustum.infiniteProjectionMatrix}},fovy:{get:function(){return u(this),this._fovy}},sseDenominator:{get:function(){return u(this),this._sseDenominator}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.fov=this.fov,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._fov=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.fov===t.fov&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.x=n(t,0),this.y=n(e,0),this.z=n(r,0),this.w=n(i,0)}var c=new t;s.fromAxisAngle=function(e,n,i){var a=n/2,o=Math.sin(a);c=t.normalize(e,c);var u=c.x*o,E=c.y*o,_=c.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=E,i.z=_,i.w=l,i):new s(u,E,_,l)};var E=[1,2,0],_=new Array(3);s.fromRotationMatrix=function(t,e){var n,i,a,o,c,l=t[u.COLUMN0ROW0],f=t[u.COLUMN1ROW1],h=t[u.COLUMN2ROW2],T=l+f+h;if(T>0)n=Math.sqrt(T+1),c=.5*n,n=.5/n,i=(t[u.COLUMN1ROW2]-t[u.COLUMN2ROW1])*n,a=(t[u.COLUMN2ROW0]-t[u.COLUMN0ROW2])*n,o=(t[u.COLUMN0ROW1]-t[u.COLUMN1ROW0])*n;else{var R=E,d=0;f>l&&(d=1),h>l&&h>f&&(d=2);var A=R[d],p=R[A] -;n=Math.sqrt(t[u.getElementIndex(d,d)]-t[u.getElementIndex(A,A)]-t[u.getElementIndex(p,p)]+1);var m=_;m[d]=.5*n,n=.5/n,c=(t[u.getElementIndex(p,A)]-t[u.getElementIndex(A,p)])*n,m[A]=(t[u.getElementIndex(A,d)]+t[u.getElementIndex(d,A)])*n,m[p]=(t[u.getElementIndex(p,d)]+t[u.getElementIndex(d,p)])*n,i=-m[0],a=-m[1],o=-m[2]}return r(e)?(e.x=i,e.y=a,e.z=o,e.w=c,e):new s(i,a,o,c)};var l=new s,f=new s,h=new s,T=new s;s.fromHeadingPitchRoll=function(e,n){return T=s.fromAxisAngle(t.UNIT_X,e.roll,l),h=s.fromAxisAngle(t.UNIT_Y,-e.pitch,n),n=s.multiply(h,T,h),f=s.fromAxisAngle(t.UNIT_Z,-e.heading,l),s.multiply(f,n,n)};var R=new t,d=new t,A=new s,p=new s,m=new s;s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.x,e[r++]=t.y,e[r++]=t.z,e[r]=t.w,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.x=t[e],i.y=t[e+1],i.z=t[e+2],i.w=t[e+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(t,e,n,r){s.unpack(t,4*n,m),s.conjugate(m,m);for(var i=0,a=n-e+1;i<a;i++){var o=3*i;s.unpack(t,4*(e+i),A),s.multiply(A,m,A),A.w<0&&s.negate(A,A),s.computeAxis(A,R);var u=s.computeAngle(A);r[o]=R.x*u,r[o+1]=R.y*u,r[o+2]=R.z*u}},s.unpackInterpolationResult=function(e,n,i,a,o){r(o)||(o=new s),t.fromArray(e,0,d);var u=t.magnitude(d);return s.unpack(n,4*a,p),0===u?s.clone(s.IDENTITY,A):s.fromAxisAngle(d,u,A),s.multiply(A,p,o)},s.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new s(t.x,t.y,t.z,t.w)},s.conjugate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=t.w,e},s.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},s.magnitude=function(t){return Math.sqrt(s.magnitudeSquared(t))},s.normalize=function(t,e){var n=1/s.magnitude(t),r=t.x*n,i=t.y*n,a=t.z*n,o=t.w*n;return e.x=r,e.y=i,e.z=a,e.w=o,e},s.inverse=function(t,e){var n=s.magnitudeSquared(t);return e=s.conjugate(t,e),s.multiplyByScalar(e,1/n,e)},s.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},s.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},s.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},s.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},s.multiply=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e.x,s=e.y,c=e.z,E=e.w,_=o*u+r*E+i*c-a*s,l=o*s-r*c+i*E+a*u,f=o*c+r*s-i*u+a*E,h=o*E-r*u-i*s-a*c;return n.x=_,n.y=l,n.z=f,n.w=h,n},s.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},s.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},s.computeAxis=function(t,e){var n=t.w;if(Math.abs(n-1)<o.EPSILON6)return e.x=e.y=e.z=0,e;var r=1/Math.sqrt(1-n*n);return e.x=t.x*r,e.y=t.y*r,e.z=t.z*r,e},s.computeAngle=function(t){return Math.abs(t.w-1)<o.EPSILON6?0:2*Math.acos(t.w)};var N=new s;s.lerp=function(t,e,n,r){return N=s.multiplyByScalar(e,n,N),r=s.multiplyByScalar(t,1-n,r),s.add(N,r,r)};var I=new s,y=new s,S=new s;s.slerp=function(t,e,n,r){var i=s.dot(t,e),a=e;if(i<0&&(i=-i,a=I=s.negate(e,I)),1-i<o.EPSILON6)return s.lerp(t,a,n,r);var u=Math.acos(i);return y=s.multiplyByScalar(t,Math.sin((1-n)*u),y),S=s.multiplyByScalar(a,Math.sin(n*u),S),r=s.add(y,S,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(e,n){var r=o.acosClamped(e.w),i=0;return 0!==r&&(i=r/Math.sin(r)),t.multiplyByScalar(e,i,n)},s.exp=function(e,n){var r=t.magnitude(e),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=e.x*i,n.y=e.y*i,n.z=e.z*i,n.w=Math.cos(r),n};var O=new t,M=new t,C=new s,w=new s;s.computeInnerQuadrangle=function(e,n,r,i){var a=s.conjugate(n,C);s.multiply(a,r,w);var o=s.log(w,O);s.multiply(a,e,w);var u=s.log(w,M);return t.add(o,u,o),t.multiplyByScalar(o,.25,o),t.negate(o,o),s.exp(o,C),s.multiply(n,C,i)},s.squad=function(t,e,n,r,i,a){var o=s.slerp(t,e,i,C),u=s.slerp(n,r,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var v=new s,g=1.9011074535173003,P=i.supportsTypedArrays()?new Float32Array(8):[],F=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],L=i.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var D=U+1,B=2*D+1;P[U]=1/(D*B),F[U]=D/B}return P[7]=g/136,F[7]=8*g/17,s.fastSlerp=function(t,e,n,r){var i,a=s.dot(t,e);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,E=u*u,_=7;_>=0;--_)x[_]=(P[_]*c-F[_])*o,L[_]=(P[_]*E-F[_])*o;var l=i*n*(1+x[0]*(1+x[1]*(1+x[2]*(1+x[3]*(1+x[4]*(1+x[5]*(1+x[6]*(1+x[7])))))))),f=u*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),h=s.multiplyByScalar(t,f,v);return s.multiplyByScalar(e,l,r),s.add(h,r,r)},s.fastSquad=function(t,e,n,r,i,a){var o=s.fastSlerp(t,e,i,C),u=s.fastSlerp(n,r,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.x-e.x)<=n&&Math.abs(t.y-e.y)<=n&&Math.abs(t.z-e.z)<=n&&Math.abs(t.w-e.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},i.unpack=function(n,r,a){return r=t(r,0),e(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(t,n){if(e(t))return e(n)||(n=new i),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},i}),define("Core/FrustumGeometry",["./BoundingSphere","./Cartesian3","./Cartesian4","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./Matrix3","./Matrix4","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion","./VertexFormat"],function(t,e,n,r,i,a,o,u,s,c,E,_,l,f,h,T,R){"use strict";function d(t){var n,r,i=t.frustum,o=t.orientation,u=t.origin,s=a(t.vertexFormat,R.DEFAULT),c=a(t._drawNearPlane,!0);i instanceof f?(n=p,r=f.packedLength):i instanceof l&&(n=m,r=l.packedLength),this._frustumType=n,this._frustum=i.clone(),this._origin=e.clone(u),this._orientation=T.clone(o),this._drawNearPlane=c,this._vertexFormat=s,this._workerName="createFrustumGeometry",this.packedLength=2+r+e.packedLength+T.packedLength+R.packedLength}function A(t,e,n,r,i,a,u,s){for(var c=t/3*2,E=0;E<4;++E)o(e)&&(e[t]=a.x,e[t+1]=a.y,e[t+2]=a.z),o(n)&&(n[t]=u.x,n[t+1]=u.y,n[t+2]=u.z),o(r)&&(r[t]=s.x,r[t+1]=s.y,r[t+2]=s.z),t+=3;i[c]=0,i[c+1]=0,i[c+2]=1,i[c+3]=0,i[c+4]=1,i[c+5]=1,i[c+6]=0,i[c+7]=1}var p=0,m=1;d.pack=function(t,n,r){r=a(r,0);var i=t._frustumType,o=t._frustum;return n[r++]=i,i===p?(f.pack(o,n,r),r+=f.packedLength):(l.pack(o,n,r),r+=l.packedLength),e.pack(t._origin,n,r),r+=e.packedLength,T.pack(t._orientation,n,r),r+=T.packedLength,R.pack(t._vertexFormat,n,r),r+=R.packedLength,n[r]=t._drawNearPlane?1:0,n};var N=new f,I=new l,y=new T,S=new e,O=new R;d.unpack=function(t,n,r){n=a(n,0);var i,u=t[n++];u===p?(i=f.unpack(t,n,N),n+=f.packedLength):(i=l.unpack(t,n,I),n+=l.packedLength);var s=e.unpack(t,n,S);n+=e.packedLength;var c=T.unpack(t,n,y);n+=T.packedLength;var E=R.unpack(t,n,O);n+=R.packedLength;var _=1===t[n];if(!o(r))return new d({frustum:i,origin:s,orientation:c,vertexFormat:E,_drawNearPlane:_});var h=u===r._frustumType?r._frustum:void 0;return r._frustum=i.clone(h),r._frustumType=u,r._origin=e.clone(s,r._origin),r._orientation=T.clone(c,r._orientation),r._vertexFormat=R.clone(E,r._vertexFormat),r._drawNearPlane=_,r};var M=new E,C=new _,w=new _,v=new e,g=new e,P=new e,F=new e,x=new e,L=new e,U=new Array(3),D=new Array(4);D[0]=new n(-1,-1,1,1),D[1]=new n(1,-1,1,1),D[2]=new n(1,1,1,1),D[3]=new n(-1,1,1,1);for(var B=new Array(4),z=0;z<4;++z)B[z]=new n;return d._computeNearFarPlanes=function(t,r,i,u,s,c,l,f){var h=E.fromQuaternion(r,M),T=a(c,v),R=a(l,g),d=a(f,P);T=E.getColumn(h,0,T),R=E.getColumn(h,1,R),d=E.getColumn(h,2,d),e.normalize(T,T),e.normalize(R,R),e.normalize(d,d),e.negate(T,T);var A,m,N=_.computeView(t,d,R,T,C);if(i===p){var I=u.projectionMatrix,y=_.multiply(I,N,w);m=_.inverse(y,w)}else A=_.inverseTransformation(N,w);o(m)?(U[0]=u.near,U[1]=u.far):(U[0]=0,U[1]=u.near,U[2]=u.far);for(var S=0;S<2;++S)for(var O=0;O<4;++O){var F=n.clone(D[O],B[O]);if(o(m)){F=_.multiplyByVector(m,F,F);var x=1/F.w;e.multiplyByScalar(F,x,F),e.subtract(F,t,F),e.normalize(F,F);var L=e.dot(d,F);e.multiplyByScalar(F,U[S]/L,F),e.add(F,t,F)}else{o(u._offCenterFrustum)&&(u=u._offCenterFrustum);var z=U[S],b=U[S+1];F.x=.5*(F.x*(u.right-u.left)+u.left+u.right),F.y=.5*(F.y*(u.top-u.bottom)+u.bottom+u.top),F.z=.5*(F.z*(z-b)-z-b),F.w=1,_.multiplyByVector(A,F,F)}s[12*S+3*O]=F.x,s[12*S+3*O+1]=F.y,s[12*S+3*O+2]=F.z}},d.createGeometry=function(n){var r=n._frustumType,a=n._frustum,E=n._origin,_=n._orientation,l=n._drawNearPlane,f=n._vertexFormat,T=l?6:5,R=new Float64Array(72);d._computeNearFarPlanes(E,_,r,a,R);var p=24;R[p]=R[12],R[p+1]=R[13],R[p+2]=R[14],R[p+3]=R[0],R[p+4]=R[1],R[p+5]=R[2],R[p+6]=R[9],R[p+7]=R[10],R[p+8]=R[11],R[p+9]=R[21],R[p+10]=R[22],R[p+11]=R[23],p+=12,R[p]=R[15],R[p+1]=R[16],R[p+2]=R[17],R[p+3]=R[3],R[p+4]=R[4],R[p+5]=R[5],R[p+6]=R[0],R[p+7]=R[1],R[p+8]=R[2],R[p+9]=R[12],R[p+10]=R[13],R[p+11]=R[14],p+=12,R[p]=R[3],R[p+1]=R[4],R[p+2]=R[5],R[p+3]=R[15],R[p+4]=R[16],R[p+5]=R[17],R[p+6]=R[18],R[p+7]=R[19],R[p+8]=R[20],R[p+9]=R[6],R[p+10]=R[7],R[p+11]=R[8],p+=12,R[p]=R[6],R[p+1]=R[7],R[p+2]=R[8],R[p+3]=R[18],R[p+4]=R[19],R[p+5]=R[20],R[p+6]=R[21],R[p+7]=R[22],R[p+8]=R[23],R[p+9]=R[9],R[p+10]=R[10],R[p+11]=R[11],l||(R=R.subarray(12));var m=new c({position:new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:R})});if(o(f.normal)||o(f.tangent)||o(f.bitangent)||o(f.st)){var N=o(f.normal)?new Float32Array(12*T):void 0,I=o(f.tangent)?new Float32Array(12*T):void 0,y=o(f.bitangent)?new Float32Array(12*T):void 0,S=o(f.st)?new Float32Array(8*T):void 0,O=v,M=g,C=P,w=e.negate(O,F),U=e.negate(M,x),D=e.negate(C,L);p=0,l&&(A(p,N,I,y,S,D,O,M),p+=12),A(p,N,I,y,S,C,w,M),p+=12,A(p,N,I,y,S,w,D,M),p+=12,A(p,N,I,y,S,U,D,w),p+=12,A(p,N,I,y,S,O,C,M),p+=12,A(p,N,I,y,S,M,C,w),o(N)&&(m.normal=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:N})),o(I)&&(m.tangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),o(y)&&(m.bitangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:y})),o(S)&&(m.st=new s({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:S}))}for(var B=new Uint16Array(6*T),z=0;z<T;++z){var b=6*z,G=4*z;B[b]=G,B[b+1]=G+1,B[b+2]=G+2,B[b+3]=G,B[b+4]=G+2,B[b+5]=G+3}return new u({attributes:m,indices:B,primitiveType:h.TRIANGLES,boundingSphere:t.fromVertices(R)})},d}),define("Workers/createFrustumGeometry",["../Core/defined","../Core/FrustumGeometry"],function(t,e){"use strict";function n(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}return n})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o,E=new o;o.angleBetween=function(t,e){o.normalize(t,c),o.normalize(e,E);var n=o.dot(c,E),r=o.magnitude(o.cross(c,E,c));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,s=e.z,c=i*s-a*u,E=a*o-r*s,_=r*u-i*o;return n.x=c,n.y=E,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var l=new o,f=new o,h=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var s=n(a)?a.radiiSquared:h,c=Math.cos(r);l.x=c*Math.cos(t),l.y=c*Math.sin(t),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,f);var E=Math.sqrt(o.dot(l,f));return f=o.divideByScalar(f,E,f),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(f,l,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,e,r[c])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,e,r[c])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromDegrees(u,s,c,e,r[E])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromRadians(u,s,c,e,r[E])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,s,c){var E=n.x,_=n.y,l=n.z,f=i.x,h=i.y,T=i.z,R=E*E*f*f,d=_*_*h*h,A=l*l*T*T,p=R+d+A,m=Math.sqrt(1/p),N=t.multiplyByScalar(n,m,a);if(p<s)return isFinite(m)?t.clone(N,c):void 0;var y=u.x,I=u.y,S=u.z,O=o;O.x=N.x*y*2,O.y=N.y*I*2,O.z=N.z*S*2;var M,C,w,v,g,P,F,x,L,U,D,B=(1-m)*t.magnitude(n)/(.5*t.magnitude(O)),z=0;do{B-=z,w=1/(1+B*y),v=1/(1+B*I),g=1/(1+B*S),P=w*w,F=v*v,x=g*g,L=P*w,U=F*v,D=x*g,M=R*P+d*F+A*x-1,C=R*L*y+d*U*I+A*D*S;z=M/(-2*C)}while(Math.abs(M)>r.EPSILON12);return e(c)?(c.x=E*w,c.y=_*v,c.z=l*g,c):new t(E*w,_*v,l*g)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var s=new t,c=new t,E=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),l=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),f=a.EPSILON1;return u.fromCartesian=function(e,n,i){var h=r(n)?n.oneOverRadii:_,T=r(n)?n.oneOverRadiiSquared:l,R=r(n)?n._centerToleranceSquared:f,d=o(e,h,T,R,c);if(r(d)){var A=t.multiplyComponents(d,T,s);A=t.normalize(A,A);var p=t.subtract(e,d,E),m=Math.atan2(A.y,A.x),N=Math.asin(A.z),y=a.sign(t.dot(p,e))*t.magnitude(p);return r(i)?(i.longitude=m,i.latitude=N,i.height=y,i):new u(m,N,y)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,E(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(E(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=s,n.z=c,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var l=new t,f=new t;_.prototype.cartographicToCartesian=function(e,n){var r=l,a=f;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var h=new t,T=new t,R=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,T);if(i(a)){var o=this.geodeticSurfaceNormal(a,h),u=t.subtract(n,a,R),c=Math.atan2(o.y,o.x),E=Math.asin(o.z),_=s.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=c,r.latitude=E,r.height=_,r):new e(c,E,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return c(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,s,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i,a,o,u,s,c){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function E(t){for(var e=0,n=0;n<3;++n){var r=t[s.getElementIndex(T[n],h[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[s.getElementIndex(T[a],h[a])]);o>r&&(i=a,r=o)}var c=1,E=0,_=h[i],l=T[i];if(Math.abs(t[s.getElementIndex(l,_)])>n){var f,R=t[s.getElementIndex(l,l)],d=t[s.getElementIndex(_,_)],A=t[s.getElementIndex(l,_)],p=(R-d)/2/A;f=p<0?-1/(-p+Math.sqrt(1+p*p)):1/(p+Math.sqrt(1+p*p)),c=1/Math.sqrt(1+f*f),E=f*c}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(_,_)]=e[s.getElementIndex(l,l)]=c,e[s.getElementIndex(l,_)]=E,e[s.getElementIndex(_,l)]=-E,e}s.packedLength=9,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},s.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,c=t.y*t.z,E=t.y*t.w,_=t.z*t.z,l=t.z*t.w,f=t.w*t.w,h=n-u-_+f,T=2*(i-l),R=2*(a+E),d=2*(i+l),A=-n+u-_+f,p=2*(c-o),m=2*(a-E),N=2*(c+o),y=-n-u+_+f;return r(e)?(e[0]=h,e[1]=d,e[2]=m,e[3]=T,e[4]=A,e[5]=N,e[6]=R,e[7]=p,e[8]=y,e):new s(h,T,R,d,A,p,m,N,y)},s.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),c=Math.sin(t.roll),E=n*i,_=-a*u+c*o*i,l=c*u+a*o*i,f=n*u,h=a*i+c*o*u,T=-c*i+a*o*u,R=-o,d=c*n,A=a*n;return r(e)?(e[0]=E,e[1]=f,e[2]=R,e[3]=_,e[4]=h,e[5]=d,e[6]=l,e[7]=T,e[8]=A,e):new s(E,_,l,f,h,T,R,d,A)},s.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(t,e,n,r){r=s.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(t,e,n,r){return r=s.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var l=new t;s.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],l)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],l)),n};var f=new t;s.getMaximumScale=function(e){return s.getScale(e,f),t.maximumComponent(f)},s.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],c=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],E=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=E,n[8]=_,n},s.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},s.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},s.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,s=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},s.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],s=t[2],c=t[5],E=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=s,e[7]=c,e[8]=E,e};var h=[1,0,0],T=[2,2,1],R=new s,d=new s;return s.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=s.clone(s.IDENTITY,e.unitary),l=e.diagonal=s.clone(t,e.diagonal),f=n*c(l);a<10&&E(l)>f;)_(l,R),s.transpose(R,d),s.multiply(l,R,l),s.multiply(d,l,l),s.multiply(o,R,o),++i>2&&(++a,i=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],s=t[5],c=t[8];return e*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],c=t[6],E=t[7],_=t[8],l=s.determinant(t);e[0]=o*_-E*u,e[1]=E*i-r*_,e[2]=r*u-o*i,e[3]=c*u-a*_,e[4]=n*_-c*i,e[5]=a*i-n*u,e[6]=a*E-c*o,e[7]=c*r-n*E,e[8]=n*o-a*r;var f=1/l;return s.multiplyByScalar(e,f,e)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,c);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(t,e,n,i,a,o,u,s,c,E,_,l,f,h,T,R){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(f,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(E,0),this[7]=r(h,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(T,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(R,0)}E.packedLength=16,E.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},E.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new E),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},E.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new E(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},E.fromArray=E.unpack,E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},E.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new E(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},E.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new E);var a=n.x,o=n.y,u=n.z,s=e.x*e.x,c=e.x*e.y,_=e.x*e.z,l=e.x*e.w,f=e.y*e.y,h=e.y*e.z,T=e.y*e.w,R=e.z*e.z,d=e.z*e.w,A=e.w*e.w,p=s-f-R+A,m=2*(c-d),N=2*(_+T),y=2*(c+d),I=-s+f-R+A,S=2*(h-l),O=2*(_-T),M=2*(h+l),C=-s-f+R+A;return r[0]=p*a,r[1]=y*a,r[2]=O*a,r[3]=0,r[4]=m*o,r[5]=I*o,r[6]=M*o,r[7]=0,r[8]=N*u,r[9]=S*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},E.fromTranslationRotationScale=function(t,e){return E.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},E.fromTranslation=function(t,e){return E.fromRotationTranslation(s.IDENTITY,t,e)},E.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},E.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,l=new t,f=new t;E.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,l),l),t.normalize(t.cross(l,_,f),f);var u=l.x,s=l.y,c=l.z,h=_.x,T=_.y,R=_.z,d=f.x,A=f.y,p=f.z,m=r.x,N=r.y,y=r.z,I=u*-m+s*-N+c*-y,S=d*-m+A*-N+p*-y,O=h*m+T*N+R*y;return i(n)?(n[0]=u,n[1]=d,n[2]=-h,n[3]=0,n[4]=s,n[5]=A,n[6]=-T,n[7]=0,n[8]=c,n[9]=p,n[10]=-R,n[11]=0,n[12]=I,n[13]=S,n[14]=O,n[15]=1,n):new E(u,s,c,I,d,A,p,S,-h,-T,-R,O,0,0,0,1)},E.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},E.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),s=1/(r-n),c=1/(a-i),E=-(e+t)*u,_=-(r+n)*s,l=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=E,o[13]=_,o[14]=l,o[15]=1,o},E.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),s=2*i/(r-n),c=(e+t)/(e-t),E=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=E,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},E.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),E=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},E.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),s=r(t.height,0);e=r(e,0),n=r(n,1);var c=.5*u,E=.5*s,_=.5*(n-e),l=c,f=E,h=_,T=a+c,R=o+E,d=e+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=f,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=h,i[11]=0,i[12]=T,i[13]=R,i[14]=d,i[15]=1,i},E.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},E.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},E.getElementIndex=function(t,e){return 4*t+e},E.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},E.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},E.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var h=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],h)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],h)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],h)),n};var T=new t;E.getMaximumScale=function(e){return E.getScale(e,T),t.maximumComponent(T)},E.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],s=t[5],c=t[6],E=t[7],_=t[8],l=t[9],f=t[10],h=t[11],T=t[12],R=t[13],d=t[14],A=t[15],p=e[0],m=e[1],N=e[2],y=e[3],I=e[4],S=e[5],O=e[6],M=e[7],C=e[8],w=e[9],v=e[10],g=e[11],P=e[12],F=e[13],x=e[14],L=e[15],U=r*p+u*m+_*N+T*y,D=i*p+s*m+l*N+R*y,B=a*p+c*m+f*N+d*y,z=o*p+E*m+h*N+A*y,b=r*I+u*S+_*O+T*M,G=i*I+s*S+l*O+R*M,V=a*I+c*S+f*O+d*M,X=o*I+E*S+h*O+A*M,q=r*C+u*w+_*v+T*g,W=i*C+s*w+l*v+R*g,H=a*C+c*w+f*v+d*g,Y=o*C+E*w+h*v+A*g,k=r*P+u*F+_*x+T*L,K=i*P+s*F+l*x+R*L,Z=a*P+c*F+f*x+d*L,j=o*P+E*F+h*x+A*L;return n[0]=U,n[1]=D,n[2]=B,n[3]=z,n[4]=b,n[5]=G,n[6]=V,n[7]=X,n[8]=q,n[9]=W,n[10]=H,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},E.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=t[12],f=t[13],h=t[14],T=e[0],R=e[1],d=e[2],A=e[4],p=e[5],m=e[6],N=e[8],y=e[9],I=e[10],S=e[12],O=e[13],M=e[14],C=r*T+o*R+c*d,w=i*T+u*R+E*d,v=a*T+s*R+_*d,g=r*A+o*p+c*m,P=i*A+u*p+E*m,F=a*A+s*p+_*m,x=r*N+o*y+c*I,L=i*N+u*y+E*I,U=a*N+s*y+_*I,D=r*S+o*O+c*M+l,B=i*S+u*O+E*M+f,z=a*S+s*O+_*M+h;return n[0]=C,n[1]=w,n[2]=v,n[3]=0,n[4]=g,n[5]=P,n[6]=F,n[7]=0,n[8]=x,n[9]=L,n[10]=U,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},E.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=e[0],f=e[1],h=e[2],T=e[3],R=e[4],d=e[5],A=e[6],p=e[7],m=e[8],N=r*l+o*f+c*h,y=i*l+u*f+E*h,I=a*l+s*f+_*h,S=r*T+o*R+c*d,O=i*T+u*R+E*d,M=a*T+s*R+_*d,C=r*A+o*p+c*m,w=i*A+u*p+E*m,v=a*A+s*p+_*m;return n[0]=N,n[1]=y,n[2]=I,n[3]=0,n[4]=S,n[5]=O,n[6]=M,n[7]=0,n[8]=C,n[9]=w,n[10]=v,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},E.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],s=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=s,n[15]=t[15],n};var R=new t;E.multiplyByUniformScale=function(t,e,n){return R.x=e,R.y=e,R.z=e,E.multiplyByScale(t,R,n)},E.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?E.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,s=t[1]*r+t[5]*i+t[9]*a+t[13]*o,c=t[2]*r+t[6]*i+t[10]*a+t[14]*o,E=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=s,n.z=c,n.w=E,n},E.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,s=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=s,n},E.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],s=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=s,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},E.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},E.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},E.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},E.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},E.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var d=new s,A=new s,p=new e,m=new e(0,0,0,1);return E.inverse=function(t,n){if(s.equalsEpsilon(E.getRotation(t,d),A,u.EPSILON7)&&e.equals(E.getRow(t,3,p),m))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],l=t[5],f=t[9],h=t[13],T=t[2],R=t[6],N=t[10],y=t[14],I=t[3],S=t[7],O=t[11],M=t[15],C=N*M,w=y*O,v=R*M,g=y*S,P=R*O,F=N*S,x=T*M,L=y*I,U=T*O,D=N*I,B=T*S,z=R*I,b=C*l+g*f+P*h-(w*l+v*f+F*h),G=w*_+x*f+D*h-(C*_+L*f+U*h),V=v*_+L*l+B*h-(g*_+x*l+z*h),X=F*_+U*l+z*f-(P*_+D*l+B*f),q=w*i+v*a+F*o-(C*i+g*a+P*o),W=C*r+L*a+U*o-(w*r+x*a+D*o),H=g*r+x*i+z*o-(v*r+L*i+B*o),Y=P*r+D*i+B*a-(F*r+U*i+z*a);C=a*h,w=o*f,v=i*h,g=o*l,P=i*f,F=a*l,x=r*h,L=o*_,U=r*f,D=a*_,B=r*l,z=i*_;var k=C*S+g*O+P*M-(w*S+v*O+F*M),K=w*I+x*O+D*M-(C*I+L*O+U*M),Z=v*I+L*S+B*M-(g*I+x*S+z*M),j=F*I+U*S+z*O-(P*I+D*S+B*O),Q=v*N+F*y+w*R-(P*y+C*R+g*N),J=U*y+C*T+L*N-(x*N+D*y+w*T),$=x*R+z*y+g*T-(B*y+v*T+L*R),tt=B*N+P*T+D*R-(U*R+z*N+F*T),et=r*b+i*G+a*V+o*X;if(Math.abs(et)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=b*et,n[1]=G*et,n[2]=V*et,n[3]=X*et,n[4]=q*et,n[5]=W*et,n[6]=H*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},E.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],s=t[8],c=t[9],E=t[10],_=t[12],l=t[13],f=t[14],h=-n*_-r*l-i*f,T=-a*_-o*l-u*f,R=-s*_-c*l-E*f;return e[0]=n,e[1]=a,e[2]=s,e[3]=0,e[4]=r,e[5]=o,e[6]=c,e[7]=0,e[8]=i,e[9]=u,e[10]=E,e[11]=0,e[12]=h,e[13]=T,e[14]=R,e[15]=1,e},E.IDENTITY=o(new E(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN0ROW3=3,E.COLUMN1ROW0=4,E.COLUMN1ROW1=5,E.COLUMN1ROW2=6,E.COLUMN1ROW3=7,E.COLUMN2ROW0=8,E.COLUMN2ROW1=9,E.COLUMN2ROW2=10,E.COLUMN2ROW3=11,E.COLUMN3ROW0=12,E.COLUMN3ROW1=13,E.COLUMN3ROW2=14,E.COLUMN3ROW3=15,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},E}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},s.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new s(t,e,i,a)},s.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new s(t,e,i,a)},s.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,E=-Number.MAX_VALUE,_=0,l=t.length;_<l;_++){var f=t[_];n=Math.min(n,f.longitude),i=Math.max(i,f.longitude),c=Math.min(c,f.latitude),E=Math.max(E,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;a=Math.min(a,h),o=Math.max(o,h)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=c,e.east=i,e.north=E,e):new s(n,c,i,E)},s.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,E=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=0,T=t.length;h<T;h++){var R=e.cartesianToCartographic(t[h]);o=Math.min(o,R.longitude),c=Math.max(c,R.longitude),l=Math.min(l,R.latitude),f=Math.max(f,R.latitude);var d=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;E=Math.min(E,d),_=Math.max(_,d)}return c-o>_-E&&(o=E,c=_,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=c,i.north=f,i):new s(o,l,c,f)},s.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},s.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},s.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},s.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},s.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new t(o,s)},s.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.negativePiToPi(Math.max(a,c)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=E)){var l=Math.max(t.south,e.south),f=Math.min(t.north,e.north);if(!(l>=f))return r(n)?(n.west=E,n.south=l,n.east=_,n.north=f,n):new s(E,l,_,f)}},s.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(t,e,n){r(n)||(n=new s);var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.convertLongitudeRange(Math.min(a,c)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=E,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},s.expand=function(t,e,n){return r(n)||(n=new s),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},s.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var c=new t;return s.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var E=0,_=t.north,l=t.south,f=t.east,h=t.west,T=c;T.height=i,T.longitude=h,T.latitude=_,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=l,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=_<0?_:l>0?l:0;for(var R=1;R<8;++R)T.longitude=-Math.PI+R*u.PI_OVER_TWO,s.contains(t,T)&&(o[E]=e.cartographicToCartesian(T,o[E]),E++);return 0===T.latitude&&(T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++),o.length=E,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,s,c,E,_,l){"use strict";function f(e,n){this.center=t.clone(i(e,t.ZERO)),this.radius=i(n,0)}var h=new t,T=new t,R=new t,d=new t,A=new t,p=new t,m=new t,N=new t,y=new t,I=new t,S=new t,O=new t,M=4/3*n.PI;f.fromPoints=function(e,n){if(a(n)||(n=new f),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],m),o=t.clone(i,h),u=t.clone(i,T),s=t.clone(i,R),c=t.clone(i,d),E=t.clone(i,A),_=t.clone(i,p),l=e.length;for(r=1;r<l;r++){t.clone(e[r],i);var M=i.x,C=i.y,w=i.z;M<o.x&&t.clone(i,o),M>c.x&&t.clone(i,c),C<u.y&&t.clone(i,u),C>E.y&&t.clone(i,E),w<s.z&&t.clone(i,s),w>_.z&&t.clone(i,_)}var v=t.magnitudeSquared(t.subtract(c,o,N)),g=t.magnitudeSquared(t.subtract(E,u,N)),P=t.magnitudeSquared(t.subtract(_,s,N)),F=o,x=c,L=v;g>L&&(L=g,F=u,x=E),P>L&&(L=P,F=s,x=_);var U=y;U.x=.5*(F.x+x.x),U.y=.5*(F.y+x.y),U.z=.5*(F.z+x.z);var D=t.magnitudeSquared(t.subtract(x,U,N)),B=Math.sqrt(D),z=I;z.x=o.x,z.y=u.y,z.z=s.z;var b=S;b.x=c.x,b.y=E.y,b.z=_.z;var G=t.multiplyByScalar(t.add(z,b,N),.5,O),V=0;for(r=0;r<l;r++){t.clone(e[r],i);var X=t.magnitude(t.subtract(i,G,N));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(i,U,N));if(q>D){var W=Math.sqrt(q);B=.5*(B+W),D=B*B;var H=W-B;U.x=(B*U.x+H*i.x)/W,U.y=(B*U.y+H*i.y)/W,U.z=(B*U.z+H*i.z)/W}}return B<V?(t.clone(U,n.center),n.radius=B):(t.clone(G,n.center),n.radius=V),n};var C=new u,w=new t,v=new t,g=new e,P=new e;f.fromRectangle2D=function(t,e,n){return f.fromRectangleWithHeights2D(t,e,0,0,n)},f.fromRectangleWithHeights2D=function(e,n,r,o,u){if(a(u)||(u=new f),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=i(n,C),l.southwest(e,g),g.height=r,l.northeast(e,P),P.height=o;var s=n.project(g,w),c=n.project(P,v),E=c.x-s.x,_=c.y-s.y,h=c.z-s.z;u.radius=.5*Math.sqrt(E*E+_*_+h*h);var T=u.center;return T.x=s.x+.5*E,T.y=s.y+.5*_,T.z=s.z+.5*h,u};var F=[];f.fromRectangle3D=function(e,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new f),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=l.subsample(e,n,r,F);return f.fromPoints(s,u)},f.fromVertices=function(e,n,r,o){if(a(o)||(o=new f),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=i(n,t.ZERO),r=i(r,3);var u=m;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var s,c=t.clone(u,h),E=t.clone(u,T),_=t.clone(u,R),l=t.clone(u,d),M=t.clone(u,A),C=t.clone(u,p),w=e.length;for(s=0;s<w;s+=r){var v=e[s]+n.x,g=e[s+1]+n.y,P=e[s+2]+n.z;u.x=v,u.y=g,u.z=P,v<c.x&&t.clone(u,c),v>l.x&&t.clone(u,l),g<E.y&&t.clone(u,E),g>M.y&&t.clone(u,M),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var F=t.magnitudeSquared(t.subtract(l,c,N)),x=t.magnitudeSquared(t.subtract(M,E,N)),L=t.magnitudeSquared(t.subtract(C,_,N)),U=c,D=l,B=F;x>B&&(B=x,U=E,D=M),L>B&&(B=L,U=_,D=C);var z=y;z.x=.5*(U.x+D.x),z.y=.5*(U.y+D.y),z.z=.5*(U.z+D.z);var b=t.magnitudeSquared(t.subtract(D,z,N)),G=Math.sqrt(b),V=I;V.x=c.x,V.y=E.y,V.z=_.z;var X=S;X.x=l.x,X.y=M.y,X.z=C.z;var q=t.multiplyByScalar(t.add(V,X,N),.5,O),W=0;for(s=0;s<w;s+=r){u.x=e[s]+n.x,u.y=e[s+1]+n.y,u.z=e[s+2]+n.z;var H=t.magnitude(t.subtract(u,q,N));H>W&&(W=H);var Y=t.magnitudeSquared(t.subtract(u,z,N));if(Y>b){var k=Math.sqrt(Y);G=.5*(G+k),b=G*G;var K=k-G;z.x=(G*z.x+K*u.x)/k,z.y=(G*z.y+K*u.y)/k,z.z=(G*z.z+K*u.z)/k}}return G<W?(t.clone(z,o.center),o.radius=G):(t.clone(q,o.center),o.radius=W),o},f.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new f),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=m;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,h),s=t.clone(i,T),c=t.clone(i,R),E=t.clone(i,d),_=t.clone(i,A),l=t.clone(i,p),M=e.length;for(o=0;o<M;o+=3){var C=e[o]+n[o],w=e[o+1]+n[o+1],v=e[o+2]+n[o+2];i.x=C,i.y=w,i.z=v,C<u.x&&t.clone(i,u),C>E.x&&t.clone(i,E),w<s.y&&t.clone(i,s),w>_.y&&t.clone(i,_),v<c.z&&t.clone(i,c),v>l.z&&t.clone(i,l)}var g=t.magnitudeSquared(t.subtract(E,u,N)),P=t.magnitudeSquared(t.subtract(_,s,N)),F=t.magnitudeSquared(t.subtract(l,c,N)),x=u,L=E,U=g;P>U&&(U=P,x=s,L=_),F>U&&(U=F,x=c,L=l);var D=y;D.x=.5*(x.x+L.x),D.y=.5*(x.y+L.y),D.z=.5*(x.z+L.z);var B=t.magnitudeSquared(t.subtract(L,D,N)),z=Math.sqrt(B),b=I;b.x=u.x,b.y=s.y,b.z=c.z;var G=S;G.x=E.x,G.y=_.y,G.z=l.z;var V=t.multiplyByScalar(t.add(b,G,N),.5,O),X=0;for(o=0;o<M;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,V,N));q>X&&(X=q);var W=t.magnitudeSquared(t.subtract(i,D,N));if(W>B){var H=Math.sqrt(W);z=.5*(z+H),B=z*z;var Y=H-z;D.x=(z*D.x+Y*i.x)/H,D.y=(z*D.y+Y*i.y)/H,D.z=(z*D.z+Y*i.z)/H}}return z<X?(t.clone(D,r.center),r.radius=z):(t.clone(V,r.center),r.radius=X),r},f.fromCornerPoints=function(e,n,r){a(r)||(r=new f);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},f.fromEllipsoid=function(e,n){return a(n)||(n=new f),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var x=new t;f.fromBoundingSpheres=function(e,n){if(a(n)||(n=new f),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return f.clone(e[0],n);if(2===r)return f.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=f.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=e[i];s=Math.max(s,t.distance(u,c.center,x)+c.radius)}return n.radius=s,n};var L=new t,U=new t,D=new t;f.fromOrientedBoundingBox=function(e,n){a(n)||(n=new f);var r=e.halfAxes,i=E.getColumn(r,0,L),o=E.getColumn(r,1,U),u=E.getColumn(r,2,D);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},f.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new f(e.center,e.radius)},f.packedLength=4,f.pack=function(t,e,n){n=i(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},f.unpack=function(t,e,n){e=i(e,0),a(n)||(n=new f);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var B=new t,z=new t;f.union=function(e,n,r){a(r)||(r=new f);var i=e.center,o=e.radius,u=n.center,s=n.radius,c=t.subtract(u,i,B),E=t.magnitude(c);if(o>=E+s)return e.clone(r),r;if(s>=E+o)return n.clone(r),r;var _=.5*(o+E+s),l=t.multiplyByScalar(c,(-o+_)/E,z);return t.add(l,i,l),t.clone(l,r.center),r.radius=_,r};var b=new t;f.expand=function(e,n,r){r=f.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,b));return i>r.radius&&(r.radius=i),r},f.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},f.transform=function(t,e,n){return a(n)||(n=new f),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var G=new t;f.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,G);return t.magnitudeSquared(r)-e.radius*e.radius},f.transformWithoutScale=function(t,e,n){return a(n)||(n=new f),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var V=new t;f.computePlaneDistances=function(e,n,r,i){a(i)||(i=new c);var o=t.subtract(e.center,n,V),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var X=new t,q=new t,W=new t,H=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return f.projectTo2D=function(e,n,r){n=i(n,j);var a=n.ellipsoid,o=e.center,u=e.radius,s=a.geodeticSurfaceNormal(o,X),c=t.cross(t.UNIT_Z,s,q);t.normalize(c,c);var E=t.cross(s,c,W);t.normalize(E,E),t.multiplyByScalar(s,u,s),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c);var _=t.negate(E,Y),l=t.negate(c,H),h=K,T=h[0];t.add(s,E,T),t.add(T,c,T),T=h[1],t.add(s,E,T),t.add(T,l,T),T=h[2],t.add(s,_,T),t.add(T,l,T),T=h[3],t.add(s,_,T),t.add(T,c,T),t.negate(s,s),T=h[4],t.add(s,E,T),t.add(T,c,T),T=h[5],t.add(s,E,T),t.add(T,l,T),T=h[6],t.add(s,_,T),t.add(T,l,T),T=h[7],t.add(s,_,T),t.add(T,c,T);for(var R=h.length,d=0;d<R;++d){var A=h[d];t.add(o,A,A);var p=a.cartesianToCartographic(A,k);n.project(p,A)}r=f.fromPoints(h,r),o=r.center;var m=o.x,N=o.y,y=o.z;return o.x=y,o.y=m,o.z=N,r},f.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},f.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},f.prototype.intersectPlane=function(t){return f.intersectPlane(this,t)},f.prototype.distanceSquaredTo=function(t){return f.distanceSquaredTo(this,t)},f.prototype.computePlaneDistances=function(t,e,n){return f.computePlaneDistances(this,t,e,n)},f.prototype.isOccluded=function(t){return f.isOccluded(this,t)},f.prototype.equals=function(t){return f.equals(this,t)},f.prototype.clone=function(t){return f.clone(this,t)},f.prototype.volume=function(){var t=this.radius;return M*t*t*t},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(N)&&(N=!1,!l())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(N=!0,y=r(t[1]))}return N}function a(){return i()&&y}function o(){if(!e(I)&&(I=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(I=!0,S=r(t[1]))}return I}function u(){return o()&&S}function s(){if(!e(O)){O=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(O=!0, +M=r(t[1]),M.isNightly=!!t[2])}return O}function c(){return s()&&M}function E(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(C=!0,w=r(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(C=!0,w=r(t[1]))}return C}function _(){return E()&&w}function l(){if(!e(v)){v=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(v=!0,g=r(t[1]))}return v}function f(){return l()&&g}function h(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(P=!0,F=r(t[1]))}return P}function T(){return e(x)||(x=/Windows/i.test(m.appVersion)),x}function R(){return h()&&F}function d(){return e(L)||(L="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),L}function A(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(U=n)}return D}function p(){return A()?U:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var N,y,I,S,O,M,C,w,v,g,P,F,x,L,U,D,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:E,internetExplorerVersion:_,isEdge:l,edgeVersion:f,isFirefox:h,firefoxVersion:R,isWindows:T,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:d,supportsImageRenderingPixelated:A,imageRenderingValue:p};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,n,r,i,a,o){"use strict";function u(e,n){this.normal=t.clone(e),this.distance=n}u.fromPointNormal=function(e,r,i){var a=-t.dot(r,e);return n(i)?(t.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new t;u.fromCartesian4=function(e,r){var i=t.fromCartesian4(e,s),a=e.w;return n(r)?(t.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(e,n){return t.dot(e.normal,n)+e.distance};var c=new t;u.projectPointOntoPlane=function(e,r,i){n(i)||(i=new t);var a=u.getPointDistance(e,r),o=t.multiplyByScalar(e.normal,a,c);return t.subtract(r,o,i)};var E=new t;return u.transform=function(e,n,r){return o.multiplyByPointAsVector(n,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,E),o.multiplyByPoint(n,E,E),u.fromPointNormal(E,s,r)},u.clone=function(e,r){return n(r)?(t.clone(e.normal,r.normal),r.distance=e.distance,r):new u(e.normal,e.distance)},u.equals=function(e,n){return e.distance===n.distance&&t.equals(e.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(t.UNIT_Y,0)),u}),define("Core/CullingVolume",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./DeveloperError","./Intersect","./Plane"],function(t,e,n,r,i,a,o){"use strict";function u(t){this.planes=n(t,[])}var s=[new t,new t,new t];t.clone(t.UNIT_X,s[0]),t.clone(t.UNIT_Y,s[1]),t.clone(t.UNIT_Z,s[2]);var c=new t,E=new t,_=new o(new t(1,0,0),0);return u.fromBoundingSphere=function(n,i){r(i)||(i=new u);var a=s.length,o=i.planes;o.length=2*a;for(var _=n.center,l=n.radius,f=0,h=0;h<a;++h){var T=s[h],R=o[f],d=o[f+1];r(R)||(R=o[f]=new e),r(d)||(d=o[f+1]=new e),t.multiplyByScalar(T,-l,c),t.add(_,c,c),R.x=T.x,R.y=T.y,R.z=T.z,R.w=-t.dot(T,c),t.multiplyByScalar(T,l,c),t.add(_,c,c),d.x=-T.x,d.y=-T.y,d.z=-T.z,d.w=-t.dot(t.negate(T,E),c),f+=2}return i},u.prototype.computeVisibility=function(t){for(var e=this.planes,n=!1,r=0,i=e.length;r<i;++r){var u=t.intersectPlane(o.fromCartesian4(e[r],_));if(u===a.OUTSIDE)return a.OUTSIDE;u===a.INTERSECTING&&(n=!0)}return n?a.INTERSECTING:a.INSIDE},u.prototype.computeVisibilityWithPlaneMask=function(t,e){if(e===u.MASK_OUTSIDE||e===u.MASK_INSIDE)return e;for(var n=u.MASK_INSIDE,r=this.planes,i=0,s=r.length;i<s;++i){var c=i<31?1<<i:0;if(!(i<31&&0==(e&c))){var E=t.intersectPlane(o.fromCartesian4(r[i],_));if(E===a.OUTSIDE)return u.MASK_OUTSIDE;E===a.INTERSECTING&&(n|=c)}}return n},u.MASK_OUTSIDE=4294967295,u.MASK_INSIDE=0,u.MASK_INDETERMINATE=2147483647,u}),define("Core/OrthographicOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._orthographicMatrix=new u}function c(t){t.top===t._top&&t.bottom===t._bottom&&t.left===t._left&&t.right===t._right&&t.near===t._near&&t.far===t._far||(t._left=t.left,t._right=t.right,t._top=t.top,t._bottom=t.bottom,t._near=t.near,t._far=t.far,t._orthographicMatrix=u.computeOrthographicOffCenter(t.left,t.right,t.bottom,t.top,t.near,t.far,t._orthographicMatrix))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._orthographicMatrix}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E);t.normalize(d,d);var A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(d,h,p),t.add(A,p,p);var m=o[0];return i(m)||(m=o[0]=new e),m.x=d.x,m.y=d.y,m.z=d.z,m.w=-t.dot(d,p),t.multiplyByScalar(d,c,p),t.add(A,p,p),m=o[1],i(m)||(m=o[1]=new e),m.x=-d.x,m.y=-d.y,m.z=-d.z,m.w=-t.dot(t.negate(d,f),p),t.multiplyByScalar(a,s,p),t.add(A,p,p),m=o[2],i(m)||(m=o[2]=new e),m.x=a.x,m.y=a.y,m.z=a.z,m.w=-t.dot(a,p),t.multiplyByScalar(a,u,p),t.add(A,p,p),m=o[3],i(m)||(m=o[3]=new e),m.x=-a.x,m.y=-a.y,m.z=-a.z,m.w=-t.dot(t.negate(a,f),p),m=o[4],i(m)||(m=o[4]=new e),m.x=r.x,m.y=r.y,m.z=r.z,m.w=-t.dot(r,A),t.multiplyByScalar(r,R,p),t.add(n,p,p),m=o[5],i(m)||(m=o[5]=new e),m.x=-r.x,m.y=-r.y,m.z=-r.z,m.w=-t.dot(t.negate(r,f),p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=this.right-this.left,a=this.top-this.bottom,o=i/t,u=a/e;return r.x=o,r.y=u,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.left=this.left,t.right=this.right,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/OrthographicFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./OrthographicOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.width=t.width,this._width=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far}function u(t){var e=t._offCenterFrustum;if(t.width!==t._width||t.aspectRatio!==t._aspectRatio||t.near!==t._near||t.far!==t._far){t._aspectRatio=t.aspectRatio,t._width=t.width,t._near=t.near,t._far=t.far;var n=1/t.aspectRatio;e.right=.5*t.width,e.left=-e.right,e.top=n*e.right,e.bottom=-e.top,e.near=t.near,e.far=t.far}}return o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.width,n[r++]=t.aspectRatio,n[r++]=t.near,n[r]=t.far,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.width=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.width=this.width,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._width=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.width===t.width&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/PerspectiveOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._perspectiveMatrix=new u,this._infinitePerspective=new u}function c(t){var e=t.top,n=t.bottom,r=t.right,i=t.left,a=t.near,o=t.far;e===t._top&&n===t._bottom&&i===t._left&&r===t._right&&a===t._near&&o===t._far||(t._left=i,t._right=r,t._top=e,t._bottom=n,t._near=a,t._far=o,t._perspectiveMatrix=u.computePerspectiveOffCenter(i,r,n,e,a,o,t._perspectiveMatrix),t._infinitePerspective=u.computeInfinitePerspectiveOffCenter(i,r,n,e,a,t._infinitePerspective))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._perspectiveMatrix}},infiniteProjectionMatrix:{get:function(){return c(this),this._infinitePerspective}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E),A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(r,R,p),t.add(n,p,p);var m=f;t.multiplyByScalar(d,h,m),t.add(A,m,m),t.subtract(m,n,m),t.normalize(m,m),t.cross(m,a,m),t.normalize(m,m);var N=o[0];return i(N)||(N=o[0]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(d,c,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(a,m,m),t.normalize(m,m),N=o[1],i(N)||(N=o[1]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,s,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(d,m,m),t.normalize(m,m),N=o[2],i(N)||(N=o[2]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,u,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(m,d,m),t.normalize(m,m),N=o[3],i(N)||(N=o[3]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),N=o[4],i(N)||(N=o[4]=new e),N.x=r.x,N.y=r.y,N.z=r.z,N.w=-t.dot(r,A),t.negate(r,m),N=o[5],i(N)||(N=o[5]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=1/this.near,a=this.top*i,o=2*n*a/e;a=this.right*i;var u=2*n*a/t;return r.x=u,r.y=o,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.right=this.right,t.left=this.left,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/PerspectiveFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./PerspectiveOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.fov=t.fov,this._fov=void 0,this._fovy=void 0,this._sseDenominator=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far,this.xOffset=e(t.xOffset,0),this._xOffset=this.xOffset,this.yOffset=e(t.yOffset,0),this._yOffset=this.yOffset}function u(t){var e=t._offCenterFrustum;t.fov===t._fov&&t.aspectRatio===t._aspectRatio&&t.near===t._near&&t.far===t._far&&t.xOffset===t._xOffset&&t.yOffset===t._yOffset||(t._aspectRatio=t.aspectRatio,t._fov=t.fov,t._fovy=t.aspectRatio<=1?t.fov:2*Math.atan(Math.tan(.5*t.fov)/t.aspectRatio),t._near=t.near,t._far=t.far,t._sseDenominator=2*Math.tan(.5*t._fovy),t._xOffset=t.xOffset,t._yOffset=t.yOffset,e.top=t.near*Math.tan(.5*t._fovy),e.bottom=-e.top,e.right=t.aspectRatio*e.top,e.left=-e.right,e.near=t.near,e.far=t.far,e.right+=t.xOffset,e.left+=t.xOffset,e.top+=t.yOffset,e.bottom+=t.yOffset)}return o.packedLength=6,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.fov,n[r++]=t.aspectRatio,n[r++]=t.near,n[r++]=t.far,n[r++]=t.xOffset,n[r]=t.yOffset,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.fov=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r++],i.xOffset=t[r++],i.yOffset=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}},infiniteProjectionMatrix:{get:function(){return u(this),this._offCenterFrustum.infiniteProjectionMatrix}},fovy:{get:function(){return u(this),this._fovy}},sseDenominator:{get:function(){return u(this),this._sseDenominator}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.fov=this.fov,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._fov=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.fov===t.fov&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.x=n(t,0),this.y=n(e,0),this.z=n(r,0),this.w=n(i,0)}var c=new t;s.fromAxisAngle=function(e,n,i){var a=n/2,o=Math.sin(a);c=t.normalize(e,c);var u=c.x*o,E=c.y*o,_=c.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=E,i.z=_,i.w=l,i):new s(u,E,_,l)};var E=[1,2,0],_=new Array(3) +;s.fromRotationMatrix=function(t,e){var n,i,a,o,c,l=t[u.COLUMN0ROW0],f=t[u.COLUMN1ROW1],h=t[u.COLUMN2ROW2],T=l+f+h;if(T>0)n=Math.sqrt(T+1),c=.5*n,n=.5/n,i=(t[u.COLUMN1ROW2]-t[u.COLUMN2ROW1])*n,a=(t[u.COLUMN2ROW0]-t[u.COLUMN0ROW2])*n,o=(t[u.COLUMN0ROW1]-t[u.COLUMN1ROW0])*n;else{var R=E,d=0;f>l&&(d=1),h>l&&h>f&&(d=2);var A=R[d],p=R[A];n=Math.sqrt(t[u.getElementIndex(d,d)]-t[u.getElementIndex(A,A)]-t[u.getElementIndex(p,p)]+1);var m=_;m[d]=.5*n,n=.5/n,c=(t[u.getElementIndex(p,A)]-t[u.getElementIndex(A,p)])*n,m[A]=(t[u.getElementIndex(A,d)]+t[u.getElementIndex(d,A)])*n,m[p]=(t[u.getElementIndex(p,d)]+t[u.getElementIndex(d,p)])*n,i=-m[0],a=-m[1],o=-m[2]}return r(e)?(e.x=i,e.y=a,e.z=o,e.w=c,e):new s(i,a,o,c)};var l=new s,f=new s,h=new s,T=new s;s.fromHeadingPitchRoll=function(e,n){return T=s.fromAxisAngle(t.UNIT_X,e.roll,l),h=s.fromAxisAngle(t.UNIT_Y,-e.pitch,n),n=s.multiply(h,T,h),f=s.fromAxisAngle(t.UNIT_Z,-e.heading,l),s.multiply(f,n,n)};var R=new t,d=new t,A=new s,p=new s,m=new s;s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.x,e[r++]=t.y,e[r++]=t.z,e[r]=t.w,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.x=t[e],i.y=t[e+1],i.z=t[e+2],i.w=t[e+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(t,e,n,r){s.unpack(t,4*n,m),s.conjugate(m,m);for(var i=0,a=n-e+1;i<a;i++){var o=3*i;s.unpack(t,4*(e+i),A),s.multiply(A,m,A),A.w<0&&s.negate(A,A),s.computeAxis(A,R);var u=s.computeAngle(A);r[o]=R.x*u,r[o+1]=R.y*u,r[o+2]=R.z*u}},s.unpackInterpolationResult=function(e,n,i,a,o){r(o)||(o=new s),t.fromArray(e,0,d);var u=t.magnitude(d);return s.unpack(n,4*a,p),0===u?s.clone(s.IDENTITY,A):s.fromAxisAngle(d,u,A),s.multiply(A,p,o)},s.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new s(t.x,t.y,t.z,t.w)},s.conjugate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=t.w,e},s.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},s.magnitude=function(t){return Math.sqrt(s.magnitudeSquared(t))},s.normalize=function(t,e){var n=1/s.magnitude(t),r=t.x*n,i=t.y*n,a=t.z*n,o=t.w*n;return e.x=r,e.y=i,e.z=a,e.w=o,e},s.inverse=function(t,e){var n=s.magnitudeSquared(t);return e=s.conjugate(t,e),s.multiplyByScalar(e,1/n,e)},s.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},s.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},s.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},s.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},s.multiply=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e.x,s=e.y,c=e.z,E=e.w,_=o*u+r*E+i*c-a*s,l=o*s-r*c+i*E+a*u,f=o*c+r*s-i*u+a*E,h=o*E-r*u-i*s-a*c;return n.x=_,n.y=l,n.z=f,n.w=h,n},s.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},s.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},s.computeAxis=function(t,e){var n=t.w;if(Math.abs(n-1)<o.EPSILON6)return e.x=e.y=e.z=0,e;var r=1/Math.sqrt(1-n*n);return e.x=t.x*r,e.y=t.y*r,e.z=t.z*r,e},s.computeAngle=function(t){return Math.abs(t.w-1)<o.EPSILON6?0:2*Math.acos(t.w)};var N=new s;s.lerp=function(t,e,n,r){return N=s.multiplyByScalar(e,n,N),r=s.multiplyByScalar(t,1-n,r),s.add(N,r,r)};var y=new s,I=new s,S=new s;s.slerp=function(t,e,n,r){var i=s.dot(t,e),a=e;if(i<0&&(i=-i,a=y=s.negate(e,y)),1-i<o.EPSILON6)return s.lerp(t,a,n,r);var u=Math.acos(i);return I=s.multiplyByScalar(t,Math.sin((1-n)*u),I),S=s.multiplyByScalar(a,Math.sin(n*u),S),r=s.add(I,S,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(e,n){var r=o.acosClamped(e.w),i=0;return 0!==r&&(i=r/Math.sin(r)),t.multiplyByScalar(e,i,n)},s.exp=function(e,n){var r=t.magnitude(e),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=e.x*i,n.y=e.y*i,n.z=e.z*i,n.w=Math.cos(r),n};var O=new t,M=new t,C=new s,w=new s;s.computeInnerQuadrangle=function(e,n,r,i){var a=s.conjugate(n,C);s.multiply(a,r,w);var o=s.log(w,O);s.multiply(a,e,w);var u=s.log(w,M);return t.add(o,u,o),t.multiplyByScalar(o,.25,o),t.negate(o,o),s.exp(o,C),s.multiply(n,C,i)},s.squad=function(t,e,n,r,i,a){var o=s.slerp(t,e,i,C),u=s.slerp(n,r,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var v=new s,g=1.9011074535173003,P=i.supportsTypedArrays()?new Float32Array(8):[],F=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],L=i.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var D=U+1,B=2*D+1;P[U]=1/(D*B),F[U]=D/B}return P[7]=g/136,F[7]=8*g/17,s.fastSlerp=function(t,e,n,r){var i,a=s.dot(t,e);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,E=u*u,_=7;_>=0;--_)x[_]=(P[_]*c-F[_])*o,L[_]=(P[_]*E-F[_])*o;var l=i*n*(1+x[0]*(1+x[1]*(1+x[2]*(1+x[3]*(1+x[4]*(1+x[5]*(1+x[6]*(1+x[7])))))))),f=u*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),h=s.multiplyByScalar(t,f,v);return s.multiplyByScalar(e,l,r),s.add(h,r,r)},s.fastSquad=function(t,e,n,r,i,a){var o=s.fastSlerp(t,e,i,C),u=s.fastSlerp(n,r,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.x-e.x)<=n&&Math.abs(t.y-e.y)<=n&&Math.abs(t.z-e.z)<=n&&Math.abs(t.w-e.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},i.unpack=function(n,r,a){return r=t(r,0),e(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(t,n){if(e(t))return e(n)||(n=new i),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},i}),define("Core/FrustumGeometry",["./BoundingSphere","./Cartesian3","./Cartesian4","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./Matrix3","./Matrix4","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion","./VertexFormat"],function(t,e,n,r,i,a,o,u,s,c,E,_,l,f,h,T,R){"use strict";function d(t){var n,r,i=t.frustum,o=t.orientation,u=t.origin,s=a(t.vertexFormat,R.DEFAULT),c=a(t._drawNearPlane,!0);i instanceof f?(n=p,r=f.packedLength):i instanceof l&&(n=m,r=l.packedLength),this._frustumType=n,this._frustum=i.clone(),this._origin=e.clone(u),this._orientation=T.clone(o),this._drawNearPlane=c,this._vertexFormat=s,this._workerName="createFrustumGeometry",this.packedLength=2+r+e.packedLength+T.packedLength+R.packedLength}function A(t,e,n,r,i,a,u,s){for(var c=t/3*2,E=0;E<4;++E)o(e)&&(e[t]=a.x,e[t+1]=a.y,e[t+2]=a.z),o(n)&&(n[t]=u.x,n[t+1]=u.y,n[t+2]=u.z),o(r)&&(r[t]=s.x,r[t+1]=s.y,r[t+2]=s.z),t+=3;i[c]=0,i[c+1]=0,i[c+2]=1,i[c+3]=0,i[c+4]=1,i[c+5]=1,i[c+6]=0,i[c+7]=1}var p=0,m=1;d.pack=function(t,n,r){r=a(r,0);var i=t._frustumType,o=t._frustum;return n[r++]=i,i===p?(f.pack(o,n,r),r+=f.packedLength):(l.pack(o,n,r),r+=l.packedLength),e.pack(t._origin,n,r),r+=e.packedLength,T.pack(t._orientation,n,r),r+=T.packedLength,R.pack(t._vertexFormat,n,r),r+=R.packedLength,n[r]=t._drawNearPlane?1:0,n};var N=new f,y=new l,I=new T,S=new e,O=new R;d.unpack=function(t,n,r){n=a(n,0);var i,u=t[n++];u===p?(i=f.unpack(t,n,N),n+=f.packedLength):(i=l.unpack(t,n,y),n+=l.packedLength);var s=e.unpack(t,n,S);n+=e.packedLength;var c=T.unpack(t,n,I);n+=T.packedLength;var E=R.unpack(t,n,O);n+=R.packedLength;var _=1===t[n];if(!o(r))return new d({frustum:i,origin:s,orientation:c,vertexFormat:E,_drawNearPlane:_});var h=u===r._frustumType?r._frustum:void 0;return r._frustum=i.clone(h),r._frustumType=u,r._origin=e.clone(s,r._origin),r._orientation=T.clone(c,r._orientation),r._vertexFormat=R.clone(E,r._vertexFormat),r._drawNearPlane=_,r};var M=new E,C=new _,w=new _,v=new e,g=new e,P=new e,F=new e,x=new e,L=new e,U=new Array(3),D=new Array(4);D[0]=new n(-1,-1,1,1),D[1]=new n(1,-1,1,1),D[2]=new n(1,1,1,1),D[3]=new n(-1,1,1,1);for(var B=new Array(4),z=0;z<4;++z)B[z]=new n;return d._computeNearFarPlanes=function(t,r,i,u,s,c,l,f){var h=E.fromQuaternion(r,M),T=a(c,v),R=a(l,g),d=a(f,P);T=E.getColumn(h,0,T),R=E.getColumn(h,1,R),d=E.getColumn(h,2,d),e.normalize(T,T),e.normalize(R,R),e.normalize(d,d),e.negate(T,T);var A,m,N=_.computeView(t,d,R,T,C);if(i===p){var y=u.projectionMatrix,I=_.multiply(y,N,w);m=_.inverse(I,w)}else A=_.inverseTransformation(N,w);o(m)?(U[0]=u.near,U[1]=u.far):(U[0]=0,U[1]=u.near,U[2]=u.far);for(var S=0;S<2;++S)for(var O=0;O<4;++O){var F=n.clone(D[O],B[O]);if(o(m)){F=_.multiplyByVector(m,F,F);var x=1/F.w;e.multiplyByScalar(F,x,F),e.subtract(F,t,F),e.normalize(F,F);var L=e.dot(d,F);e.multiplyByScalar(F,U[S]/L,F),e.add(F,t,F)}else{o(u._offCenterFrustum)&&(u=u._offCenterFrustum);var z=U[S],b=U[S+1];F.x=.5*(F.x*(u.right-u.left)+u.left+u.right),F.y=.5*(F.y*(u.top-u.bottom)+u.bottom+u.top),F.z=.5*(F.z*(z-b)-z-b),F.w=1,_.multiplyByVector(A,F,F)}s[12*S+3*O]=F.x,s[12*S+3*O+1]=F.y,s[12*S+3*O+2]=F.z}},d.createGeometry=function(n){var r=n._frustumType,a=n._frustum,E=n._origin,_=n._orientation,l=n._drawNearPlane,f=n._vertexFormat,T=l?6:5,R=new Float64Array(72);d._computeNearFarPlanes(E,_,r,a,R);var p=24;R[p]=R[12],R[p+1]=R[13],R[p+2]=R[14],R[p+3]=R[0],R[p+4]=R[1],R[p+5]=R[2],R[p+6]=R[9],R[p+7]=R[10],R[p+8]=R[11],R[p+9]=R[21],R[p+10]=R[22],R[p+11]=R[23],p+=12,R[p]=R[15],R[p+1]=R[16],R[p+2]=R[17],R[p+3]=R[3],R[p+4]=R[4],R[p+5]=R[5],R[p+6]=R[0],R[p+7]=R[1],R[p+8]=R[2],R[p+9]=R[12],R[p+10]=R[13],R[p+11]=R[14],p+=12,R[p]=R[3],R[p+1]=R[4],R[p+2]=R[5],R[p+3]=R[15],R[p+4]=R[16],R[p+5]=R[17],R[p+6]=R[18],R[p+7]=R[19],R[p+8]=R[20],R[p+9]=R[6],R[p+10]=R[7],R[p+11]=R[8],p+=12,R[p]=R[6],R[p+1]=R[7],R[p+2]=R[8],R[p+3]=R[18],R[p+4]=R[19],R[p+5]=R[20],R[p+6]=R[21],R[p+7]=R[22],R[p+8]=R[23],R[p+9]=R[9],R[p+10]=R[10],R[p+11]=R[11],l||(R=R.subarray(12));var m=new c({position:new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:R})});if(o(f.normal)||o(f.tangent)||o(f.bitangent)||o(f.st)){var N=o(f.normal)?new Float32Array(12*T):void 0,y=o(f.tangent)?new Float32Array(12*T):void 0,I=o(f.bitangent)?new Float32Array(12*T):void 0,S=o(f.st)?new Float32Array(8*T):void 0,O=v,M=g,C=P,w=e.negate(O,F),U=e.negate(M,x),D=e.negate(C,L);p=0,l&&(A(p,N,y,I,S,D,O,M),p+=12),A(p,N,y,I,S,C,w,M),p+=12,A(p,N,y,I,S,w,D,M),p+=12,A(p,N,y,I,S,U,D,w),p+=12,A(p,N,y,I,S,O,C,M),p+=12,A(p,N,y,I,S,M,C,w),o(N)&&(m.normal=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:N})),o(y)&&(m.tangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:y})),o(I)&&(m.bitangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),o(S)&&(m.st=new s({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:S}))}for(var B=new Uint16Array(6*T),z=0;z<T;++z){var b=6*z,G=4*z;B[b]=G,B[b+1]=G+1,B[b+2]=G+2,B[b+3]=G,B[b+4]=G+2,B[b+5]=G+3}return new u({attributes:m,indices:B,primitiveType:h.TRIANGLES,boundingSphere:t.fromVertices(R)})},d}),define("Workers/createFrustumGeometry",["../Core/defined","../Core/FrustumGeometry"],function(t,e){"use strict";function n(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumOutlineGeometry.js index a46b45d7..4565b36a 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createFrustumOutlineGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o,E=new o;o.angleBetween=function(t,e){o.normalize(t,c),o.normalize(e,E);var n=o.dot(c,E),r=o.magnitude(o.cross(c,E,c));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,s=e.z,c=i*s-a*u,E=a*o-r*s,_=r*u-i*o;return n.x=c,n.y=E,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var l=new o,f=new o,h=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var s=n(a)?a.radiiSquared:h,c=Math.cos(r);l.x=c*Math.cos(t),l.y=c*Math.sin(t),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,f);var E=Math.sqrt(o.dot(l,f));return f=o.divideByScalar(f,E,f),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(f,l,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,e,r[c])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,e,r[c])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromDegrees(u,s,c,e,r[E])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromRadians(u,s,c,e,r[E])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,s,c){var E=n.x,_=n.y,l=n.z,f=i.x,h=i.y,T=i.z,R=E*E*f*f,d=_*_*h*h,A=l*l*T*T,p=R+d+A,m=Math.sqrt(1/p),N=t.multiplyByScalar(n,m,a);if(p<s)return isFinite(m)?t.clone(N,c):void 0;var y=u.x,I=u.y,S=u.z,O=o;O.x=N.x*y*2,O.y=N.y*I*2,O.z=N.z*S*2;var M,w,C,g,v,L,P,F,x,U,D,B=(1-m)*t.magnitude(n)/(.5*t.magnitude(O)),z=0;do{B-=z,C=1/(1+B*y),g=1/(1+B*I),v=1/(1+B*S),L=C*C,P=g*g,F=v*v,x=L*C,U=P*g,D=F*v,M=R*L+d*P+A*F-1,w=R*x*y+d*U*I+A*D*S;z=M/(-2*w)}while(Math.abs(M)>r.EPSILON12);return e(c)?(c.x=E*C,c.y=_*g,c.z=l*v,c):new t(E*C,_*g,l*v)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var s=new t,c=new t,E=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),l=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),f=a.EPSILON1;return u.fromCartesian=function(e,n,i){var h=r(n)?n.oneOverRadii:_,T=r(n)?n.oneOverRadiiSquared:l,R=r(n)?n._centerToleranceSquared:f,d=o(e,h,T,R,c);if(r(d)){var A=t.multiplyComponents(d,T,s);A=t.normalize(A,A);var p=t.subtract(e,d,E),m=Math.atan2(A.y,A.x),N=Math.asin(A.z),y=a.sign(t.dot(p,e))*t.magnitude(p);return r(i)?(i.longitude=m,i.latitude=N,i.height=y,i):new u(m,N,y)}},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,E(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(E(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=s,n.z=c,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var l=new t,f=new t;_.prototype.cartographicToCartesian=function(e,n){var r=l,a=f;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var h=new t,T=new t,R=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,T);if(i(a)){var o=this.geodeticSurfaceNormal(a,h),u=t.subtract(n,a,R),c=Math.atan2(o.y,o.x),E=Math.asin(o.z),_=s.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=c,r.latitude=E,r.height=_,r):new e(c,E,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return c(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,s,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i,a,o,u,s,c){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function E(t){for(var e=0,n=0;n<3;++n){var r=t[s.getElementIndex(T[n],h[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[s.getElementIndex(T[a],h[a])]);o>r&&(i=a,r=o)}var c=1,E=0,_=h[i],l=T[i];if(Math.abs(t[s.getElementIndex(l,_)])>n){var f,R=t[s.getElementIndex(l,l)],d=t[s.getElementIndex(_,_)],A=t[s.getElementIndex(l,_)],p=(R-d)/2/A;f=p<0?-1/(-p+Math.sqrt(1+p*p)):1/(p+Math.sqrt(1+p*p)),c=1/Math.sqrt(1+f*f),E=f*c}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(_,_)]=e[s.getElementIndex(l,l)]=c,e[s.getElementIndex(l,_)]=E,e[s.getElementIndex(_,l)]=-E,e}s.packedLength=9,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},s.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,c=t.y*t.z,E=t.y*t.w,_=t.z*t.z,l=t.z*t.w,f=t.w*t.w,h=n-u-_+f,T=2*(i-l),R=2*(a+E),d=2*(i+l),A=-n+u-_+f,p=2*(c-o),m=2*(a-E),N=2*(c+o),y=-n-u+_+f;return r(e)?(e[0]=h,e[1]=d,e[2]=m,e[3]=T,e[4]=A,e[5]=N,e[6]=R,e[7]=p,e[8]=y,e):new s(h,T,R,d,A,p,m,N,y)},s.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),c=Math.sin(t.roll),E=n*i,_=-a*u+c*o*i,l=c*u+a*o*i,f=n*u,h=a*i+c*o*u,T=-c*i+a*o*u,R=-o,d=c*n,A=a*n;return r(e)?(e[0]=E,e[1]=f,e[2]=R,e[3]=_,e[4]=h,e[5]=d,e[6]=l,e[7]=T,e[8]=A,e):new s(E,_,l,f,h,T,R,d,A)},s.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(t,e,n,r){r=s.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(t,e,n,r){return r=s.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var l=new t;s.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],l)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],l)),n};var f=new t;s.getMaximumScale=function(e){return s.getScale(e,f),t.maximumComponent(f)},s.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],c=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],E=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=E,n[8]=_,n},s.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},s.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},s.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,s=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},s.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],s=t[2],c=t[5],E=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=s,e[7]=c,e[8]=E,e};var h=[1,0,0],T=[2,2,1],R=new s,d=new s;return s.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=s.clone(s.IDENTITY,e.unitary),l=e.diagonal=s.clone(t,e.diagonal),f=n*c(l);a<10&&E(l)>f;)_(l,R),s.transpose(R,d),s.multiply(l,R,l),s.multiply(d,l,l),s.multiply(o,R,o),++i>2&&(++a,i=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],s=t[5],c=t[8];return e*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],c=t[6],E=t[7],_=t[8],l=s.determinant(t);e[0]=o*_-E*u,e[1]=E*i-r*_,e[2]=r*u-o*i,e[3]=c*u-a*_,e[4]=n*_-c*i,e[5]=a*i-n*u,e[6]=a*E-c*o,e[7]=c*r-n*E,e[8]=n*o-a*r;var f=1/l;return s.multiplyByScalar(e,f,e)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,c);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){ -var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(t,e,n,i,a,o,u,s,c,E,_,l,f,h,T,R){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(f,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(E,0),this[7]=r(h,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(T,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(R,0)}E.packedLength=16,E.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},E.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new E),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},E.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new E(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},E.fromArray=E.unpack,E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},E.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new E(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},E.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new E);var a=n.x,o=n.y,u=n.z,s=e.x*e.x,c=e.x*e.y,_=e.x*e.z,l=e.x*e.w,f=e.y*e.y,h=e.y*e.z,T=e.y*e.w,R=e.z*e.z,d=e.z*e.w,A=e.w*e.w,p=s-f-R+A,m=2*(c-d),N=2*(_+T),y=2*(c+d),I=-s+f-R+A,S=2*(h-l),O=2*(_-T),M=2*(h+l),w=-s-f+R+A;return r[0]=p*a,r[1]=y*a,r[2]=O*a,r[3]=0,r[4]=m*o,r[5]=I*o,r[6]=M*o,r[7]=0,r[8]=N*u,r[9]=S*u,r[10]=w*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},E.fromTranslationRotationScale=function(t,e){return E.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},E.fromTranslation=function(t,e){return E.fromRotationTranslation(s.IDENTITY,t,e)},E.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},E.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,l=new t,f=new t;E.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,l),l),t.normalize(t.cross(l,_,f),f);var u=l.x,s=l.y,c=l.z,h=_.x,T=_.y,R=_.z,d=f.x,A=f.y,p=f.z,m=r.x,N=r.y,y=r.z,I=u*-m+s*-N+c*-y,S=d*-m+A*-N+p*-y,O=h*m+T*N+R*y;return i(n)?(n[0]=u,n[1]=d,n[2]=-h,n[3]=0,n[4]=s,n[5]=A,n[6]=-T,n[7]=0,n[8]=c,n[9]=p,n[10]=-R,n[11]=0,n[12]=I,n[13]=S,n[14]=O,n[15]=1,n):new E(u,s,c,I,d,A,p,S,-h,-T,-R,O,0,0,0,1)},E.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},E.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),s=1/(r-n),c=1/(a-i),E=-(e+t)*u,_=-(r+n)*s,l=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=E,o[13]=_,o[14]=l,o[15]=1,o},E.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),s=2*i/(r-n),c=(e+t)/(e-t),E=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=E,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},E.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),E=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},E.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),s=r(t.height,0);e=r(e,0),n=r(n,1);var c=.5*u,E=.5*s,_=.5*(n-e),l=c,f=E,h=_,T=a+c,R=o+E,d=e+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=f,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=h,i[11]=0,i[12]=T,i[13]=R,i[14]=d,i[15]=1,i},E.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},E.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},E.getElementIndex=function(t,e){return 4*t+e},E.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},E.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},E.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var h=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],h)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],h)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],h)),n};var T=new t;E.getMaximumScale=function(e){return E.getScale(e,T),t.maximumComponent(T)},E.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],s=t[5],c=t[6],E=t[7],_=t[8],l=t[9],f=t[10],h=t[11],T=t[12],R=t[13],d=t[14],A=t[15],p=e[0],m=e[1],N=e[2],y=e[3],I=e[4],S=e[5],O=e[6],M=e[7],w=e[8],C=e[9],g=e[10],v=e[11],L=e[12],P=e[13],F=e[14],x=e[15],U=r*p+u*m+_*N+T*y,D=i*p+s*m+l*N+R*y,B=a*p+c*m+f*N+d*y,z=o*p+E*m+h*N+A*y,b=r*I+u*S+_*O+T*M,G=i*I+s*S+l*O+R*M,V=a*I+c*S+f*O+d*M,X=o*I+E*S+h*O+A*M,q=r*w+u*C+_*g+T*v,W=i*w+s*C+l*g+R*v,H=a*w+c*C+f*g+d*v,k=o*w+E*C+h*g+A*v,Y=r*L+u*P+_*F+T*x,K=i*L+s*P+l*F+R*x,Z=a*L+c*P+f*F+d*x,j=o*L+E*P+h*F+A*x;return n[0]=U,n[1]=D,n[2]=B,n[3]=z,n[4]=b,n[5]=G,n[6]=V,n[7]=X,n[8]=q,n[9]=W,n[10]=H,n[11]=k,n[12]=Y,n[13]=K,n[14]=Z,n[15]=j,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},E.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=t[12],f=t[13],h=t[14],T=e[0],R=e[1],d=e[2],A=e[4],p=e[5],m=e[6],N=e[8],y=e[9],I=e[10],S=e[12],O=e[13],M=e[14],w=r*T+o*R+c*d,C=i*T+u*R+E*d,g=a*T+s*R+_*d,v=r*A+o*p+c*m,L=i*A+u*p+E*m,P=a*A+s*p+_*m,F=r*N+o*y+c*I,x=i*N+u*y+E*I,U=a*N+s*y+_*I,D=r*S+o*O+c*M+l,B=i*S+u*O+E*M+f,z=a*S+s*O+_*M+h;return n[0]=w,n[1]=C,n[2]=g,n[3]=0,n[4]=v,n[5]=L,n[6]=P,n[7]=0,n[8]=F,n[9]=x,n[10]=U,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},E.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=e[0],f=e[1],h=e[2],T=e[3],R=e[4],d=e[5],A=e[6],p=e[7],m=e[8],N=r*l+o*f+c*h,y=i*l+u*f+E*h,I=a*l+s*f+_*h,S=r*T+o*R+c*d,O=i*T+u*R+E*d,M=a*T+s*R+_*d,w=r*A+o*p+c*m,C=i*A+u*p+E*m,g=a*A+s*p+_*m;return n[0]=N,n[1]=y,n[2]=I,n[3]=0,n[4]=S,n[5]=O,n[6]=M,n[7]=0,n[8]=w,n[9]=C,n[10]=g,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},E.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],s=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=s,n[15]=t[15],n};var R=new t;E.multiplyByUniformScale=function(t,e,n){return R.x=e,R.y=e,R.z=e,E.multiplyByScale(t,R,n)},E.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?E.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,s=t[1]*r+t[5]*i+t[9]*a+t[13]*o,c=t[2]*r+t[6]*i+t[10]*a+t[14]*o,E=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=s,n.z=c,n.w=E,n},E.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,s=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=s,n},E.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],s=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=s,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},E.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},E.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},E.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},E.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},E.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var d=new s,A=new s,p=new e,m=new e(0,0,0,1);return E.inverse=function(t,n){if(s.equalsEpsilon(E.getRotation(t,d),A,u.EPSILON7)&&e.equals(E.getRow(t,3,p),m))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],l=t[5],f=t[9],h=t[13],T=t[2],R=t[6],N=t[10],y=t[14],I=t[3],S=t[7],O=t[11],M=t[15],w=N*M,C=y*O,g=R*M,v=y*S,L=R*O,P=N*S,F=T*M,x=y*I,U=T*O,D=N*I,B=T*S,z=R*I,b=w*l+v*f+L*h-(C*l+g*f+P*h),G=C*_+F*f+D*h-(w*_+x*f+U*h),V=g*_+x*l+B*h-(v*_+F*l+z*h),X=P*_+U*l+z*f-(L*_+D*l+B*f),q=C*i+g*a+P*o-(w*i+v*a+L*o),W=w*r+x*a+U*o-(C*r+F*a+D*o),H=v*r+F*i+z*o-(g*r+x*i+B*o),k=L*r+D*i+B*a-(P*r+U*i+z*a);w=a*h,C=o*f,g=i*h,v=o*l,L=i*f,P=a*l,F=r*h,x=o*_,U=r*f,D=a*_,B=r*l,z=i*_;var Y=w*S+v*O+L*M-(C*S+g*O+P*M),K=C*I+F*O+D*M-(w*I+x*O+U*M),Z=g*I+x*S+B*M-(v*I+F*S+z*M),j=P*I+U*S+z*O-(L*I+D*S+B*O),Q=g*N+P*y+C*R-(L*y+w*R+v*N),J=U*y+w*T+x*N-(F*N+D*y+C*T),$=F*R+z*y+v*T-(B*y+g*T+x*R),tt=B*N+L*T+D*R-(U*R+z*N+P*T),et=r*b+i*G+a*V+o*X;if(Math.abs(et)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=b*et,n[1]=G*et,n[2]=V*et,n[3]=X*et,n[4]=q*et,n[5]=W*et,n[6]=H*et,n[7]=k*et,n[8]=Y*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},E.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],s=t[8],c=t[9],E=t[10],_=t[12],l=t[13],f=t[14],h=-n*_-r*l-i*f,T=-a*_-o*l-u*f,R=-s*_-c*l-E*f;return e[0]=n,e[1]=a,e[2]=s,e[3]=0,e[4]=r,e[5]=o,e[6]=c,e[7]=0,e[8]=i,e[9]=u,e[10]=E,e[11]=0,e[12]=h,e[13]=T,e[14]=R,e[15]=1,e},E.IDENTITY=o(new E(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN0ROW3=3,E.COLUMN1ROW0=4,E.COLUMN1ROW1=5,E.COLUMN1ROW2=6,E.COLUMN1ROW3=7,E.COLUMN2ROW0=8,E.COLUMN2ROW1=9,E.COLUMN2ROW2=10,E.COLUMN2ROW3=11,E.COLUMN3ROW0=12,E.COLUMN3ROW1=13,E.COLUMN3ROW2=14,E.COLUMN3ROW3=15,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},E}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},s.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new s(t,e,i,a)},s.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new s(t,e,i,a)},s.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,E=-Number.MAX_VALUE,_=0,l=t.length;_<l;_++){var f=t[_];n=Math.min(n,f.longitude),i=Math.max(i,f.longitude),c=Math.min(c,f.latitude),E=Math.max(E,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;a=Math.min(a,h),o=Math.max(o,h)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=c,e.east=i,e.north=E,e):new s(n,c,i,E)},s.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,E=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=0,T=t.length;h<T;h++){var R=e.cartesianToCartographic(t[h]);o=Math.min(o,R.longitude),c=Math.max(c,R.longitude),l=Math.min(l,R.latitude),f=Math.max(f,R.latitude);var d=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;E=Math.min(E,d),_=Math.max(_,d)}return c-o>_-E&&(o=E,c=_,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=c,i.north=f,i):new s(o,l,c,f)},s.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},s.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},s.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},s.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},s.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new t(o,s)},s.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.negativePiToPi(Math.max(a,c)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=E)){var l=Math.max(t.south,e.south),f=Math.min(t.north,e.north);if(!(l>=f))return r(n)?(n.west=E,n.south=l,n.east=_,n.north=f,n):new s(E,l,_,f)}},s.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(t,e,n){r(n)||(n=new s);var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.convertLongitudeRange(Math.min(a,c)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=E,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},s.expand=function(t,e,n){return r(n)||(n=new s),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},s.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var c=new t;return s.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var E=0,_=t.north,l=t.south,f=t.east,h=t.west,T=c;T.height=i,T.longitude=h,T.latitude=_,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=l,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=_<0?_:l>0?l:0;for(var R=1;R<8;++R)T.longitude=-Math.PI+R*u.PI_OVER_TWO,s.contains(t,T)&&(o[E]=e.cartographicToCartesian(T,o[E]),E++);return 0===T.latitude&&(T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++),o.length=E,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,s,c,E,_){"use strict";function l(e,n){this.center=t.clone(r(e,t.ZERO)),this.radius=r(n,0)}var f=new t,h=new t,T=new t,R=new t,d=new t,A=new t,p=new t,m=new t,N=new t,y=new t,I=new t,S=new t;l.fromPoints=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,a=t.clone(e[0],p),o=t.clone(a,f),u=t.clone(a,h),s=t.clone(a,T),c=t.clone(a,R),E=t.clone(a,d),_=t.clone(a,A),O=e.length;for(r=1;r<O;r++){t.clone(e[r],a);var M=a.x,w=a.y,C=a.z;M<o.x&&t.clone(a,o),M>c.x&&t.clone(a,c),w<u.y&&t.clone(a,u),w>E.y&&t.clone(a,E),C<s.z&&t.clone(a,s),C>_.z&&t.clone(a,_)}var g=t.magnitudeSquared(t.subtract(c,o,m)),v=t.magnitudeSquared(t.subtract(E,u,m)),L=t.magnitudeSquared(t.subtract(_,s,m)),P=o,F=c,x=g;v>x&&(x=v,P=u,F=E),L>x&&(x=L,P=s,F=_);var U=N;U.x=.5*(P.x+F.x),U.y=.5*(P.y+F.y),U.z=.5*(P.z+F.z);var D=t.magnitudeSquared(t.subtract(F,U,m)),B=Math.sqrt(D),z=y;z.x=o.x,z.y=u.y,z.z=s.z;var b=I;b.x=c.x,b.y=E.y,b.z=_.z;var G=t.multiplyByScalar(t.add(z,b,m),.5,S),V=0;for(r=0;r<O;r++){t.clone(e[r],a);var X=t.magnitude(t.subtract(a,G,m));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(a,U,m));if(q>D){var W=Math.sqrt(q);B=.5*(B+W),D=B*B;var H=W-B;U.x=(B*U.x+H*a.x)/W,U.y=(B*U.y+H*a.y)/W,U.z=(B*U.z+H*a.z)/W}}return B<V?(t.clone(U,n.center),n.radius=B):(t.clone(G,n.center),n.radius=V),n};var O=new o,M=new t,w=new t,C=new e,g=new e;l.fromRectangle2D=function(t,e,n){return l.fromRectangleWithHeights2D(t,e,0,0,n)},l.fromRectangleWithHeights2D=function(e,n,a,o,u){if(i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=r(n,O),_.southwest(e,C),C.height=a,_.northeast(e,g),g.height=o;var s=n.project(C,M),c=n.project(g,w),E=c.x-s.x,f=c.y-s.y,h=c.z-s.z;u.radius=.5*Math.sqrt(E*E+f*f+h*h);var T=u.center;return T.x=s.x+.5*E,T.y=s.y+.5*f,T.z=s.z+.5*h,u};var v=[];l.fromRectangle3D=function(e,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=_.subsample(e,n,o,v);return l.fromPoints(s,u)},l.fromVertices=function(e,n,a,o){if(i(o)||(o=new l),!i(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=r(n,t.ZERO),a=r(a,3);var u=p;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var s,c=t.clone(u,f),E=t.clone(u,h),_=t.clone(u,T),O=t.clone(u,R),M=t.clone(u,d),w=t.clone(u,A),C=e.length;for(s=0;s<C;s+=a){var g=e[s]+n.x,v=e[s+1]+n.y,L=e[s+2]+n.z;u.x=g,u.y=v,u.z=L,g<c.x&&t.clone(u,c),g>O.x&&t.clone(u,O),v<E.y&&t.clone(u,E),v>M.y&&t.clone(u,M),L<_.z&&t.clone(u,_),L>w.z&&t.clone(u,w)}var P=t.magnitudeSquared(t.subtract(O,c,m)),F=t.magnitudeSquared(t.subtract(M,E,m)),x=t.magnitudeSquared(t.subtract(w,_,m)),U=c,D=O,B=P;F>B&&(B=F,U=E,D=M),x>B&&(B=x,U=_,D=w);var z=N;z.x=.5*(U.x+D.x),z.y=.5*(U.y+D.y),z.z=.5*(U.z+D.z);var b=t.magnitudeSquared(t.subtract(D,z,m)),G=Math.sqrt(b),V=y;V.x=c.x,V.y=E.y,V.z=_.z;var X=I;X.x=O.x,X.y=M.y,X.z=w.z;var q=t.multiplyByScalar(t.add(V,X,m),.5,S),W=0;for(s=0;s<C;s+=a){u.x=e[s]+n.x,u.y=e[s+1]+n.y,u.z=e[s+2]+n.z;var H=t.magnitude(t.subtract(u,q,m));H>W&&(W=H);var k=t.magnitudeSquared(t.subtract(u,z,m));if(k>b){var Y=Math.sqrt(k);G=.5*(G+Y),b=G*G;var K=Y-G;z.x=(G*z.x+K*u.x)/Y,z.y=(G*z.y+K*u.y)/Y,z.z=(G*z.z+K*u.z)/Y}}return G<W?(t.clone(z,o.center),o.radius=G):(t.clone(q,o.center),o.radius=W),o},l.fromEncodedCartesianVertices=function(e,n,r){if(i(r)||(r=new l),!i(e)||!i(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var a=p;a.x=e[0]+n[0],a.y=e[1]+n[1],a.z=e[2]+n[2];var o,u=t.clone(a,f),s=t.clone(a,h),c=t.clone(a,T),E=t.clone(a,R),_=t.clone(a,d),O=t.clone(a,A),M=e.length;for(o=0;o<M;o+=3){var w=e[o]+n[o],C=e[o+1]+n[o+1],g=e[o+2]+n[o+2];a.x=w,a.y=C,a.z=g,w<u.x&&t.clone(a,u),w>E.x&&t.clone(a,E),C<s.y&&t.clone(a,s),C>_.y&&t.clone(a,_),g<c.z&&t.clone(a,c),g>O.z&&t.clone(a,O)}var v=t.magnitudeSquared(t.subtract(E,u,m)),L=t.magnitudeSquared(t.subtract(_,s,m)),P=t.magnitudeSquared(t.subtract(O,c,m)),F=u,x=E,U=v;L>U&&(U=L,F=s,x=_),P>U&&(U=P,F=c,x=O);var D=N;D.x=.5*(F.x+x.x),D.y=.5*(F.y+x.y),D.z=.5*(F.z+x.z);var B=t.magnitudeSquared(t.subtract(x,D,m)),z=Math.sqrt(B),b=y;b.x=u.x,b.y=s.y,b.z=c.z;var G=I;G.x=E.x,G.y=_.y,G.z=O.z;var V=t.multiplyByScalar(t.add(b,G,m),.5,S),X=0;for(o=0;o<M;o+=3){a.x=e[o]+n[o],a.y=e[o+1]+n[o+1],a.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(a,V,m));q>X&&(X=q);var W=t.magnitudeSquared(t.subtract(a,D,m));if(W>B){var H=Math.sqrt(W);z=.5*(z+H),B=z*z;var k=H-z;D.x=(z*D.x+k*a.x)/H,D.y=(z*D.y+k*a.y)/H,D.z=(z*D.z+k*a.z)/H}}return z<X?(t.clone(D,r.center),r.radius=z):(t.clone(V,r.center),r.radius=X),r},l.fromCornerPoints=function(e,n,r){i(r)||(r=new l);var a=r.center;return t.add(e,n,a),t.multiplyByScalar(a,.5,a),r.radius=t.distance(a,n),r},l.fromEllipsoid=function(e,n){return i(n)||(n=new l),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var L=new t;l.fromBoundingSpheres=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return l.clone(e[0],n);if(2===r)return l.union(e[0],e[1],n);var a,o=[];for(a=0;a<r;a++)o.push(e[a].center);n=l.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=e[a];s=Math.max(s,t.distance(u,c.center,L)+c.radius)}return n.radius=s,n};var P=new t,F=new t,x=new t;l.fromOrientedBoundingBox=function(e,n){i(n)||(n=new l);var r=e.halfAxes,a=c.getColumn(r,0,P),o=c.getColumn(r,1,F),u=c.getColumn(r,2,x);return t.add(a,o,a),t.add(a,u,a),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(a),n},l.clone=function(e,n){if(i(e))return i(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new l(e.center,e.radius)},l.packedLength=4,l.pack=function(t,e,n){n=r(n,0);var i=t.center;return e[n++]=i.x,e[n++]=i.y,e[n++]=i.z,e[n]=t.radius,e},l.unpack=function(t,e,n){e=r(e,0),i(n)||(n=new l);var a=n.center;return a.x=t[e++],a.y=t[e++],a.z=t[e++],n.radius=t[e],n};var U=new t,D=new t;l.union=function(e,n,r){i(r)||(r=new l);var a=e.center,o=e.radius,u=n.center,s=n.radius,c=t.subtract(u,a,U),E=t.magnitude(c);if(o>=E+s)return e.clone(r),r;if(s>=E+o)return n.clone(r),r;var _=.5*(o+E+s),f=t.multiplyByScalar(c,(-o+_)/E,D);return t.add(f,a,f),t.clone(f,r.center),r.radius=_,r};var B=new t;l.expand=function(e,n,r){r=l.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,B));return i>r.radius&&(r.radius=i),r},l.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},l.transform=function(t,e,n){return i(n)||(n=new l),n.center=E.multiplyByPoint(e,t.center,n.center),n.radius=E.getMaximumScale(e)*t.radius,n};var z=new t;l.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,z);return t.magnitudeSquared(r)-e.radius*e.radius},l.transformWithoutScale=function(t,e,n){return i(n)||(n=new l),n.center=E.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var b=new t;l.computePlaneDistances=function(e,n,r,a){i(a)||(a=new s);var o=t.subtract(e.center,n,b),u=t.dot(r,o);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var G=new t,V=new t,X=new t,q=new t,W=new t,H=new e,k=new Array(8),Y=0;Y<8;++Y)k[Y]=new t;var K=new o;return l.projectTo2D=function(e,n,i){n=r(n,K);var a=n.ellipsoid,o=e.center,u=e.radius,s=a.geodeticSurfaceNormal(o,G),c=t.cross(t.UNIT_Z,s,V);t.normalize(c,c);var E=t.cross(s,c,X);t.normalize(E,E),t.multiplyByScalar(s,u,s),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c);var _=t.negate(E,W),f=t.negate(c,q),h=k,T=h[0];t.add(s,E,T),t.add(T,c,T),T=h[1],t.add(s,E,T),t.add(T,f,T),T=h[2],t.add(s,_,T),t.add(T,f,T),T=h[3],t.add(s,_,T),t.add(T,c,T),t.negate(s,s),T=h[4],t.add(s,E,T),t.add(T,c,T),T=h[5],t.add(s,E,T),t.add(T,f,T),T=h[6],t.add(s,_,T),t.add(T,f,T),T=h[7],t.add(s,_,T),t.add(T,c,T);for(var R=h.length,d=0;d<R;++d){var A=h[d];t.add(o,A,A);var p=a.cartesianToCartographic(A,H);n.project(p,A)}i=l.fromPoints(h,i),o=i.center;var m=o.x,N=o.y,y=o.z;return o.x=y,o.y=m,o.z=N,i},l.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},l.equals=function(e,n){return e===n||i(e)&&i(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},l.prototype.intersectPlane=function(t){return l.intersectPlane(this,t)},l.prototype.distanceSquaredTo=function(t){return l.distanceSquaredTo(this,t)},l.prototype.computePlaneDistances=function(t,e,n){return l.computePlaneDistances(this,t,e,n)},l.prototype.isOccluded=function(t){return l.isOccluded(this,t)},l.prototype.equals=function(t){return l.equals(this,t)},l.prototype.clone=function(t){return l.clone(this,t)},l}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(N)&&(N=!1,!l())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(N=!0,y=r(t[1]))}return N}function a(){return i()&&y}function o(){if(!e(I)&&(I=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(I=!0,S=r(t[1]))}return I}function u(){return o()&&S}function s(){if(!e(O)){O=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(O=!0,M=r(t[1]),M.isNightly=!!t[2])}return O}function c(){return s()&&M}function E(){if(!e(w)){w=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(w=!0, -C=r(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(w=!0,C=r(t[1]))}return w}function _(){return E()&&C}function l(){if(!e(g)){g=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(g=!0,v=r(t[1]))}return g}function f(){return l()&&v}function h(){if(!e(L)){L=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(L=!0,P=r(t[1]))}return L}function T(){return e(F)||(F=/Windows/i.test(m.appVersion)),F}function R(){return h()&&P}function d(){return e(x)||(x="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),x}function A(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(U=n)}return D}function p(){return A()?U:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var N,y,I,S,O,M,w,C,g,v,L,P,F,x,U,D,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:E,internetExplorerVersion:_,isEdge:l,edgeVersion:f,isFirefox:h,firefoxVersion:R,isWindows:T,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:d,supportsImageRenderingPixelated:A,imageRenderingValue:p};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,n,r,i,a,o){"use strict";function u(e,n){this.normal=t.clone(e),this.distance=n}u.fromPointNormal=function(e,r,i){var a=-t.dot(r,e);return n(i)?(t.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new t;u.fromCartesian4=function(e,r){var i=t.fromCartesian4(e,s),a=e.w;return n(r)?(t.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(e,n){return t.dot(e.normal,n)+e.distance};var c=new t;return u.transform=function(e,n,r){return o.multiplyByPointAsVector(n,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(e,r){return n(r)?(t.clone(e.normal,r.normal),r.distance=e.distance,r):new u(e.normal,e.distance)},u.equals=function(e,n){return e.distance===n.distance&&t.equals(e.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(t.UNIT_Y,0)),u}),define("Core/CullingVolume",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./DeveloperError","./Intersect","./Plane"],function(t,e,n,r,i,a,o){"use strict";function u(t){this.planes=n(t,[])}var s=[new t,new t,new t];t.clone(t.UNIT_X,s[0]),t.clone(t.UNIT_Y,s[1]),t.clone(t.UNIT_Z,s[2]);var c=new t,E=new t,_=new o(new t(1,0,0),0);return u.fromBoundingSphere=function(n,i){r(i)||(i=new u);var a=s.length,o=i.planes;o.length=2*a;for(var _=n.center,l=n.radius,f=0,h=0;h<a;++h){var T=s[h],R=o[f],d=o[f+1];r(R)||(R=o[f]=new e),r(d)||(d=o[f+1]=new e),t.multiplyByScalar(T,-l,c),t.add(_,c,c),R.x=T.x,R.y=T.y,R.z=T.z,R.w=-t.dot(T,c),t.multiplyByScalar(T,l,c),t.add(_,c,c),d.x=-T.x,d.y=-T.y,d.z=-T.z,d.w=-t.dot(t.negate(T,E),c),f+=2}return i},u.prototype.computeVisibility=function(t){for(var e=this.planes,n=!1,r=0,i=e.length;r<i;++r){var u=t.intersectPlane(o.fromCartesian4(e[r],_));if(u===a.OUTSIDE)return a.OUTSIDE;u===a.INTERSECTING&&(n=!0)}return n?a.INTERSECTING:a.INSIDE},u.prototype.computeVisibilityWithPlaneMask=function(t,e){if(e===u.MASK_OUTSIDE||e===u.MASK_INSIDE)return e;for(var n=u.MASK_INSIDE,r=this.planes,i=0,s=r.length;i<s;++i){var c=i<31?1<<i:0;if(!(i<31&&0==(e&c))){var E=t.intersectPlane(o.fromCartesian4(r[i],_));if(E===a.OUTSIDE)return u.MASK_OUTSIDE;E===a.INTERSECTING&&(n|=c)}}return n},u.MASK_OUTSIDE=4294967295,u.MASK_INSIDE=0,u.MASK_INDETERMINATE=2147483647,u}),define("Core/OrthographicOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._orthographicMatrix=new u}function c(t){t.top===t._top&&t.bottom===t._bottom&&t.left===t._left&&t.right===t._right&&t.near===t._near&&t.far===t._far||(t._left=t.left,t._right=t.right,t._top=t.top,t._bottom=t.bottom,t._near=t.near,t._far=t.far,t._orthographicMatrix=u.computeOrthographicOffCenter(t.left,t.right,t.bottom,t.top,t.near,t.far,t._orthographicMatrix))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._orthographicMatrix}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E);t.normalize(d,d);var A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(d,h,p),t.add(A,p,p);var m=o[0];return i(m)||(m=o[0]=new e),m.x=d.x,m.y=d.y,m.z=d.z,m.w=-t.dot(d,p),t.multiplyByScalar(d,c,p),t.add(A,p,p),m=o[1],i(m)||(m=o[1]=new e),m.x=-d.x,m.y=-d.y,m.z=-d.z,m.w=-t.dot(t.negate(d,f),p),t.multiplyByScalar(a,s,p),t.add(A,p,p),m=o[2],i(m)||(m=o[2]=new e),m.x=a.x,m.y=a.y,m.z=a.z,m.w=-t.dot(a,p),t.multiplyByScalar(a,u,p),t.add(A,p,p),m=o[3],i(m)||(m=o[3]=new e),m.x=-a.x,m.y=-a.y,m.z=-a.z,m.w=-t.dot(t.negate(a,f),p),m=o[4],i(m)||(m=o[4]=new e),m.x=r.x,m.y=r.y,m.z=r.z,m.w=-t.dot(r,A),t.multiplyByScalar(r,R,p),t.add(n,p,p),m=o[5],i(m)||(m=o[5]=new e),m.x=-r.x,m.y=-r.y,m.z=-r.z,m.w=-t.dot(t.negate(r,f),p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=this.right-this.left,a=this.top-this.bottom,o=i/t,u=a/e;return r.x=o,r.y=u,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.left=this.left,t.right=this.right,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/OrthographicFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./OrthographicOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.width=t.width,this._width=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far}function u(t){var e=t._offCenterFrustum;if(t.width!==t._width||t.aspectRatio!==t._aspectRatio||t.near!==t._near||t.far!==t._far){t._aspectRatio=t.aspectRatio,t._width=t.width,t._near=t.near,t._far=t.far;var n=1/t.aspectRatio;e.right=.5*t.width,e.left=-e.right,e.top=n*e.right,e.bottom=-e.top,e.near=t.near,e.far=t.far}}return o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.width,n[r++]=t.aspectRatio,n[r++]=t.near,n[r]=t.far,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.width=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.width=this.width,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._width=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.width===t.width&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/PerspectiveOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._perspectiveMatrix=new u,this._infinitePerspective=new u}function c(t){var e=t.top,n=t.bottom,r=t.right,i=t.left,a=t.near,o=t.far;e===t._top&&n===t._bottom&&i===t._left&&r===t._right&&a===t._near&&o===t._far||(t._left=i,t._right=r,t._top=e,t._bottom=n,t._near=a,t._far=o,t._perspectiveMatrix=u.computePerspectiveOffCenter(i,r,n,e,a,o,t._perspectiveMatrix),t._infinitePerspective=u.computeInfinitePerspectiveOffCenter(i,r,n,e,a,t._infinitePerspective))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._perspectiveMatrix}},infiniteProjectionMatrix:{get:function(){return c(this),this._infinitePerspective}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E),A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(r,R,p),t.add(n,p,p);var m=f;t.multiplyByScalar(d,h,m),t.add(A,m,m),t.subtract(m,n,m),t.normalize(m,m),t.cross(m,a,m),t.normalize(m,m);var N=o[0];return i(N)||(N=o[0]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(d,c,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(a,m,m),t.normalize(m,m),N=o[1],i(N)||(N=o[1]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,s,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(d,m,m),t.normalize(m,m),N=o[2],i(N)||(N=o[2]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,u,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(m,d,m),t.normalize(m,m),N=o[3],i(N)||(N=o[3]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),N=o[4],i(N)||(N=o[4]=new e),N.x=r.x,N.y=r.y,N.z=r.z,N.w=-t.dot(r,A),t.negate(r,m),N=o[5],i(N)||(N=o[5]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=1/this.near,a=this.top*i,o=2*n*a/e;a=this.right*i;var u=2*n*a/t;return r.x=u,r.y=o,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.right=this.right,t.left=this.left,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/PerspectiveFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./PerspectiveOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.fov=t.fov,this._fov=void 0,this._fovy=void 0,this._sseDenominator=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far,this.xOffset=e(t.xOffset,0),this._xOffset=this.xOffset,this.yOffset=e(t.yOffset,0),this._yOffset=this.yOffset}function u(t){var e=t._offCenterFrustum;t.fov===t._fov&&t.aspectRatio===t._aspectRatio&&t.near===t._near&&t.far===t._far&&t.xOffset===t._xOffset&&t.yOffset===t._yOffset||(t._aspectRatio=t.aspectRatio,t._fov=t.fov,t._fovy=t.aspectRatio<=1?t.fov:2*Math.atan(Math.tan(.5*t.fov)/t.aspectRatio),t._near=t.near,t._far=t.far,t._sseDenominator=2*Math.tan(.5*t._fovy),t._xOffset=t.xOffset,t._yOffset=t.yOffset,e.top=t.near*Math.tan(.5*t._fovy),e.bottom=-e.top,e.right=t.aspectRatio*e.top,e.left=-e.right,e.near=t.near,e.far=t.far,e.right+=t.xOffset,e.left+=t.xOffset,e.top+=t.yOffset,e.bottom+=t.yOffset)}return o.packedLength=6,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.fov,n[r++]=t.aspectRatio,n[r++]=t.near,n[r++]=t.far,n[r++]=t.xOffset,n[r]=t.yOffset,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.fov=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r++],i.xOffset=t[r++],i.yOffset=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}},infiniteProjectionMatrix:{get:function(){return u(this),this._offCenterFrustum.infiniteProjectionMatrix}},fovy:{get:function(){return u(this),this._fovy}},sseDenominator:{get:function(){return u(this),this._sseDenominator}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.fov=this.fov,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._fov=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.fov===t.fov&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.x=n(t,0),this.y=n(e,0),this.z=n(r,0),this.w=n(i,0)}var c=new t;s.fromAxisAngle=function(e,n,i){var a=n/2,o=Math.sin(a);c=t.normalize(e,c);var u=c.x*o,E=c.y*o,_=c.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=E,i.z=_,i.w=l,i):new s(u,E,_,l)};var E=[1,2,0],_=new Array(3);s.fromRotationMatrix=function(t,e){var n,i,a,o,c,l=t[u.COLUMN0ROW0],f=t[u.COLUMN1ROW1],h=t[u.COLUMN2ROW2],T=l+f+h;if(T>0)n=Math.sqrt(T+1),c=.5*n,n=.5/n,i=(t[u.COLUMN1ROW2]-t[u.COLUMN2ROW1])*n,a=(t[u.COLUMN2ROW0]-t[u.COLUMN0ROW2])*n,o=(t[u.COLUMN0ROW1]-t[u.COLUMN1ROW0])*n;else{var R=E,d=0;f>l&&(d=1),h>l&&h>f&&(d=2);var A=R[d],p=R[A] -;n=Math.sqrt(t[u.getElementIndex(d,d)]-t[u.getElementIndex(A,A)]-t[u.getElementIndex(p,p)]+1);var m=_;m[d]=.5*n,n=.5/n,c=(t[u.getElementIndex(p,A)]-t[u.getElementIndex(A,p)])*n,m[A]=(t[u.getElementIndex(A,d)]+t[u.getElementIndex(d,A)])*n,m[p]=(t[u.getElementIndex(p,d)]+t[u.getElementIndex(d,p)])*n,i=-m[0],a=-m[1],o=-m[2]}return r(e)?(e.x=i,e.y=a,e.z=o,e.w=c,e):new s(i,a,o,c)};var l=new s,f=new s,h=new s,T=new s;s.fromHeadingPitchRoll=function(e,n){return T=s.fromAxisAngle(t.UNIT_X,e.roll,l),h=s.fromAxisAngle(t.UNIT_Y,-e.pitch,n),n=s.multiply(h,T,h),f=s.fromAxisAngle(t.UNIT_Z,-e.heading,l),s.multiply(f,n,n)};var R=new t,d=new t,A=new s,p=new s,m=new s;s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.x,e[r++]=t.y,e[r++]=t.z,e[r]=t.w,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.x=t[e],i.y=t[e+1],i.z=t[e+2],i.w=t[e+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(t,e,n,r){s.unpack(t,4*n,m),s.conjugate(m,m);for(var i=0,a=n-e+1;i<a;i++){var o=3*i;s.unpack(t,4*(e+i),A),s.multiply(A,m,A),A.w<0&&s.negate(A,A),s.computeAxis(A,R);var u=s.computeAngle(A);r[o]=R.x*u,r[o+1]=R.y*u,r[o+2]=R.z*u}},s.unpackInterpolationResult=function(e,n,i,a,o){r(o)||(o=new s),t.fromArray(e,0,d);var u=t.magnitude(d);return s.unpack(n,4*a,p),0===u?s.clone(s.IDENTITY,A):s.fromAxisAngle(d,u,A),s.multiply(A,p,o)},s.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new s(t.x,t.y,t.z,t.w)},s.conjugate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=t.w,e},s.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},s.magnitude=function(t){return Math.sqrt(s.magnitudeSquared(t))},s.normalize=function(t,e){var n=1/s.magnitude(t),r=t.x*n,i=t.y*n,a=t.z*n,o=t.w*n;return e.x=r,e.y=i,e.z=a,e.w=o,e},s.inverse=function(t,e){var n=s.magnitudeSquared(t);return e=s.conjugate(t,e),s.multiplyByScalar(e,1/n,e)},s.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},s.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},s.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},s.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},s.multiply=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e.x,s=e.y,c=e.z,E=e.w,_=o*u+r*E+i*c-a*s,l=o*s-r*c+i*E+a*u,f=o*c+r*s-i*u+a*E,h=o*E-r*u-i*s-a*c;return n.x=_,n.y=l,n.z=f,n.w=h,n},s.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},s.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},s.computeAxis=function(t,e){var n=t.w;if(Math.abs(n-1)<o.EPSILON6)return e.x=e.y=e.z=0,e;var r=1/Math.sqrt(1-n*n);return e.x=t.x*r,e.y=t.y*r,e.z=t.z*r,e},s.computeAngle=function(t){return Math.abs(t.w-1)<o.EPSILON6?0:2*Math.acos(t.w)};var N=new s;s.lerp=function(t,e,n,r){return N=s.multiplyByScalar(e,n,N),r=s.multiplyByScalar(t,1-n,r),s.add(N,r,r)};var y=new s,I=new s,S=new s;s.slerp=function(t,e,n,r){var i=s.dot(t,e),a=e;if(i<0&&(i=-i,a=y=s.negate(e,y)),1-i<o.EPSILON6)return s.lerp(t,a,n,r);var u=Math.acos(i);return I=s.multiplyByScalar(t,Math.sin((1-n)*u),I),S=s.multiplyByScalar(a,Math.sin(n*u),S),r=s.add(I,S,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(e,n){var r=o.acosClamped(e.w),i=0;return 0!==r&&(i=r/Math.sin(r)),t.multiplyByScalar(e,i,n)},s.exp=function(e,n){var r=t.magnitude(e),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=e.x*i,n.y=e.y*i,n.z=e.z*i,n.w=Math.cos(r),n};var O=new t,M=new t,w=new s,C=new s;s.computeInnerQuadrangle=function(e,n,r,i){var a=s.conjugate(n,w);s.multiply(a,r,C);var o=s.log(C,O);s.multiply(a,e,C);var u=s.log(C,M);return t.add(o,u,o),t.multiplyByScalar(o,.25,o),t.negate(o,o),s.exp(o,w),s.multiply(n,w,i)},s.squad=function(t,e,n,r,i,a){var o=s.slerp(t,e,i,w),u=s.slerp(n,r,i,C);return s.slerp(o,u,2*i*(1-i),a)};for(var g=new s,v=1.9011074535173003,L=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],F=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var D=U+1,B=2*D+1;L[U]=1/(D*B),P[U]=D/B}return L[7]=v/136,P[7]=8*v/17,s.fastSlerp=function(t,e,n,r){var i,a=s.dot(t,e);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,E=u*u,_=7;_>=0;--_)F[_]=(L[_]*c-P[_])*o,x[_]=(L[_]*E-P[_])*o;var l=i*n*(1+F[0]*(1+F[1]*(1+F[2]*(1+F[3]*(1+F[4]*(1+F[5]*(1+F[6]*(1+F[7])))))))),f=u*(1+x[0]*(1+x[1]*(1+x[2]*(1+x[3]*(1+x[4]*(1+x[5]*(1+x[6]*(1+x[7])))))))),h=s.multiplyByScalar(t,f,g);return s.multiplyByScalar(e,l,r),s.add(h,r,r)},s.fastSquad=function(t,e,n,r,i,a){var o=s.fastSlerp(t,e,i,w),u=s.fastSlerp(n,r,i,C);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.x-e.x)<=n&&Math.abs(t.y-e.y)<=n&&Math.abs(t.z-e.z)<=n&&Math.abs(t.w-e.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},i.unpack=function(n,r,a){return r=t(r,0),e(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(t,n){if(e(t))return e(n)||(n=new i),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},i}),define("Core/FrustumGeometry",["./BoundingSphere","./Cartesian3","./Cartesian4","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./Matrix3","./Matrix4","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion","./VertexFormat"],function(t,e,n,r,i,a,o,u,s,c,E,_,l,f,h,T,R){"use strict";function d(t){var n,r,i=t.frustum,o=t.orientation,u=t.origin,s=a(t.vertexFormat,R.DEFAULT),c=a(t._drawNearPlane,!0);i instanceof f?(n=p,r=f.packedLength):i instanceof l&&(n=m,r=l.packedLength),this._frustumType=n,this._frustum=i.clone(),this._origin=e.clone(u),this._orientation=T.clone(o),this._drawNearPlane=c,this._vertexFormat=s,this._workerName="createFrustumGeometry",this.packedLength=2+r+e.packedLength+T.packedLength+R.packedLength}function A(t,e,n,r,i,a,u,s){for(var c=t/3*2,E=0;E<4;++E)o(e)&&(e[t]=a.x,e[t+1]=a.y,e[t+2]=a.z),o(n)&&(n[t]=u.x,n[t+1]=u.y,n[t+2]=u.z),o(r)&&(r[t]=s.x,r[t+1]=s.y,r[t+2]=s.z),t+=3;i[c]=0,i[c+1]=0,i[c+2]=1,i[c+3]=0,i[c+4]=1,i[c+5]=1,i[c+6]=0,i[c+7]=1}var p=0,m=1;d.pack=function(t,n,r){r=a(r,0);var i=t._frustumType,o=t._frustum;return n[r++]=i,i===p?(f.pack(o,n,r),r+=f.packedLength):(l.pack(o,n,r),r+=l.packedLength),e.pack(t._origin,n,r),r+=e.packedLength,T.pack(t._orientation,n,r),r+=T.packedLength,R.pack(t._vertexFormat,n,r),r+=R.packedLength,n[r]=t._drawNearPlane?1:0,n};var N=new f,y=new l,I=new T,S=new e,O=new R;d.unpack=function(t,n,r){n=a(n,0);var i,u=t[n++];u===p?(i=f.unpack(t,n,N),n+=f.packedLength):(i=l.unpack(t,n,y),n+=l.packedLength);var s=e.unpack(t,n,S);n+=e.packedLength;var c=T.unpack(t,n,I);n+=T.packedLength;var E=R.unpack(t,n,O);n+=R.packedLength;var _=1===t[n];if(!o(r))return new d({frustum:i,origin:s,orientation:c,vertexFormat:E,_drawNearPlane:_});var h=u===r._frustumType?r._frustum:void 0;return r._frustum=i.clone(h),r._frustumType=u,r._origin=e.clone(s,r._origin),r._orientation=T.clone(c,r._orientation),r._vertexFormat=R.clone(E,r._vertexFormat),r._drawNearPlane=_,r};var M=new E,w=new _,C=new _,g=new e,v=new e,L=new e,P=new e,F=new e,x=new e,U=new Array(3),D=new Array(4);D[0]=new n(-1,-1,1,1),D[1]=new n(1,-1,1,1),D[2]=new n(1,1,1,1),D[3]=new n(-1,1,1,1);for(var B=new Array(4),z=0;z<4;++z)B[z]=new n;return d._computeNearFarPlanes=function(t,r,i,u,s,c,l,f){var h=E.fromQuaternion(r,M),T=a(c,g),R=a(l,v),d=a(f,L);T=E.getColumn(h,0,T),R=E.getColumn(h,1,R),d=E.getColumn(h,2,d),e.normalize(T,T),e.normalize(R,R),e.normalize(d,d),e.negate(T,T);var A,m,N=_.computeView(t,d,R,T,w);if(i===p){var y=u.projectionMatrix,I=_.multiply(y,N,C);m=_.inverse(I,C)}else A=_.inverseTransformation(N,C);o(m)?(U[0]=u.near,U[1]=u.far):(U[0]=0,U[1]=u.near,U[2]=u.far);for(var S=0;S<2;++S)for(var O=0;O<4;++O){var P=n.clone(D[O],B[O]);if(o(m)){P=_.multiplyByVector(m,P,P);var F=1/P.w;e.multiplyByScalar(P,F,P),e.subtract(P,t,P),e.normalize(P,P);var x=e.dot(d,P);e.multiplyByScalar(P,U[S]/x,P),e.add(P,t,P)}else{o(u._offCenterFrustum)&&(u=u._offCenterFrustum);var z=U[S],b=U[S+1];P.x=.5*(P.x*(u.right-u.left)+u.left+u.right),P.y=.5*(P.y*(u.top-u.bottom)+u.bottom+u.top),P.z=.5*(P.z*(z-b)-z-b),P.w=1,_.multiplyByVector(A,P,P)}s[12*S+3*O]=P.x,s[12*S+3*O+1]=P.y,s[12*S+3*O+2]=P.z}},d.createGeometry=function(n){var r=n._frustumType,a=n._frustum,E=n._origin,_=n._orientation,l=n._drawNearPlane,f=n._vertexFormat,T=l?6:5,R=new Float64Array(72);d._computeNearFarPlanes(E,_,r,a,R);var p=24;R[p]=R[12],R[p+1]=R[13],R[p+2]=R[14],R[p+3]=R[0],R[p+4]=R[1],R[p+5]=R[2],R[p+6]=R[9],R[p+7]=R[10],R[p+8]=R[11],R[p+9]=R[21],R[p+10]=R[22],R[p+11]=R[23],p+=12,R[p]=R[15],R[p+1]=R[16],R[p+2]=R[17],R[p+3]=R[3],R[p+4]=R[4],R[p+5]=R[5],R[p+6]=R[0],R[p+7]=R[1],R[p+8]=R[2],R[p+9]=R[12],R[p+10]=R[13],R[p+11]=R[14],p+=12,R[p]=R[3],R[p+1]=R[4],R[p+2]=R[5],R[p+3]=R[15],R[p+4]=R[16],R[p+5]=R[17],R[p+6]=R[18],R[p+7]=R[19],R[p+8]=R[20],R[p+9]=R[6],R[p+10]=R[7],R[p+11]=R[8],p+=12,R[p]=R[6],R[p+1]=R[7],R[p+2]=R[8],R[p+3]=R[18],R[p+4]=R[19],R[p+5]=R[20],R[p+6]=R[21],R[p+7]=R[22],R[p+8]=R[23],R[p+9]=R[9],R[p+10]=R[10],R[p+11]=R[11],l||(R=R.subarray(12));var m=new c({position:new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:R})});if(o(f.normal)||o(f.tangent)||o(f.bitangent)||o(f.st)){var N=o(f.normal)?new Float32Array(12*T):void 0,y=o(f.tangent)?new Float32Array(12*T):void 0,I=o(f.bitangent)?new Float32Array(12*T):void 0,S=o(f.st)?new Float32Array(8*T):void 0,O=g,M=v,w=L,C=e.negate(O,P),U=e.negate(M,F),D=e.negate(w,x);p=0,l&&(A(p,N,y,I,S,D,O,M),p+=12),A(p,N,y,I,S,w,C,M),p+=12,A(p,N,y,I,S,C,D,M),p+=12,A(p,N,y,I,S,U,D,C),p+=12,A(p,N,y,I,S,O,w,M),p+=12,A(p,N,y,I,S,M,w,C),o(N)&&(m.normal=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:N})),o(y)&&(m.tangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:y})),o(I)&&(m.bitangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),o(S)&&(m.st=new s({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:S}))}for(var B=new Uint16Array(6*T),z=0;z<T;++z){var b=6*z,G=4*z;B[b]=G,B[b+1]=G+1,B[b+2]=G+2,B[b+3]=G,B[b+4]=G+2,B[b+5]=G+3}return new u({attributes:m,indices:B,primitiveType:h.TRIANGLES,boundingSphere:t.fromVertices(R)})},d}),define("Core/FrustumOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./FrustumGeometry","./Geometry","./GeometryAttribute","./GeometryAttributes","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion"],function(t,e,n,r,i,a,o,u,s,c,E,_,l,f){"use strict";function h(t){var n,r,a=t.frustum,o=t.orientation,u=t.origin,s=i(t._drawNearPlane,!0);a instanceof _?(n=T,r=_.packedLength):a instanceof E&&(n=R,r=E.packedLength),this._frustumType=n,this._frustum=a.clone(),this._origin=e.clone(u),this._orientation=f.clone(o),this._drawNearPlane=s,this._workerName="createFrustumOutlineGeometry",this.packedLength=2+r+e.packedLength+f.packedLength}var T=0,R=1;h.pack=function(t,n,r){r=i(r,0);var a=t._frustumType,o=t._frustum;return n[r++]=a,a===T?(_.pack(o,n,r),r+=_.packedLength):(E.pack(o,n,r),r+=E.packedLength),e.pack(t._origin,n,r),r+=e.packedLength,f.pack(t._orientation,n,r),r+=f.packedLength,n[r]=t._drawNearPlane?1:0,n};var d=new _,A=new E,p=new f,m=new e;return h.unpack=function(t,n,r){n=i(n,0);var o,u=t[n++];u===T?(o=_.unpack(t,n,d),n+=_.packedLength):(o=E.unpack(t,n,A),n+=E.packedLength);var s=e.unpack(t,n,m);n+=e.packedLength;var c=f.unpack(t,n,p);n+=f.packedLength;var l=1===t[n];if(!a(r))return new h({frustum:o,origin:s,orientation:c,_drawNearPlane:l});var R=u===r._frustumType?r._frustum:void 0;return r._frustum=o.clone(R),r._frustumType=u,r._origin=e.clone(s,r._origin),r._orientation=f.clone(c,r._orientation),r._drawNearPlane=l,r},h.createGeometry=function(e){var n=e._frustumType,i=e._frustum,a=e._origin,E=e._orientation,_=e._drawNearPlane,f=new Float64Array(24);o._computeNearFarPlanes(a,E,n,i,f);for(var h,T,R=new c({position:new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:f})}),d=_?2:1,A=new Uint16Array(8*(d+1)),p=_?0:1;p<2;++p)h=_?8*p:0,T=4*p,A[h]=T,A[h+1]=T+1,A[h+2]=T+1,A[h+3]=T+2,A[h+4]=T+2,A[h+5]=T+3,A[h+6]=T+3,A[h+7]=T;for(p=0;p<2;++p)h=8*(d+p),T=4*p,A[h]=T,A[h+1]=T+4,A[h+2]=T+1,A[h+3]=T+5,A[h+4]=T+2,A[h+5]=T+6,A[h+6]=T+3,A[h+7]=T+7;return new u({attributes:R,indices:A,primitiveType:l.LINES,boundingSphere:t.fromVertices(f)})},h}),define("Workers/createFrustumOutlineGeometry",["../Core/defined","../Core/FrustumOutlineGeometry"],function(t,e){"use strict";function n(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}return n})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var i={};return i.typeOf={},i.defined=function(r,i){if(!t(i))throw new e(n(r))},i.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},i.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},i.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},i.typeOf.number.lessThan=function(t,n,r){if(i.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(t,n,r){if(i.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(t,n,r){if(i.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},i.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},i.typeOf.number.equals=function(t,n,r,a){if(i.typeOf.number(t,r),i.typeOf.number(n,a),r!==a)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(t){return t>0?1:t<0?-1:0},i.signNotZero=function(t){return t<0?-1:1},i.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*i.clamp(t,-1,1)+.5)*n)},i.fromSNorm=function(t,n){return n=e(n,255),i.clamp(t,0,n)/n*2-1},i.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},i.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},i.lerp=function(t,e,n){return(1-n)*t+n*e},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(t){return t*i.RADIANS_PER_DEGREE},i.toDegrees=function(t){return t*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(t){var e=i.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},i.clampToLatitudeRange=function(t){return i.clamp(t,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(t){return i.zeroToTwoPi(t+i.PI)-i.PI},i.zeroToTwoPi=function(t){var e=i.mod(t,i.TWO_PI);return Math.abs(e)<i.EPSILON14&&Math.abs(t)>i.EPSILON14?i.TWO_PI:e},i.mod=function(t,e){return(t%e+e)%e},i.equalsEpsilon=function(t,n,r,i){i=e(i,r);var a=Math.abs(t-n);return a<=i||a<=r*Math.max(Math.abs(t),Math.abs(n))};var a=[1];i.factorial=function(t){var e=a.length;if(t>=e)for(var n=a[e-1],r=e;r<=t;r++)a.push(n*r);return a[t]},i.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},i.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},i.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},i.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return i.setRandomNumberSeed=function(e){o=new t(e)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(t,e){return i.nextRandomNumber()*(e-t)+t},i.acosClamped=function(t){return Math.acos(i.clamp(t,-1,1))},i.asinClamped=function(t){return Math.asin(i.clamp(t,-1,1))},i.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},i.logBase=function(t,e){return Math.log(t)/Math.log(e)},i.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var i=t.clock,a=t.cone,u=e(t.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(t,e,r,i){return n(i)?(i.x=t,i.y=e,i.z=r,i):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var i=0;i<r;++i)o.pack(t[i],e,3*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o,E=new o;o.angleBetween=function(t,e){o.normalize(t,c),o.normalize(e,E);var n=o.dot(c,E),r=o.magnitude(o.cross(c,E,c));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)},o.cross=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=e.x,u=e.y,s=e.z,c=i*s-a*u,E=a*o-r*s,_=r*u-i*o;return n.x=c,n.y=E,n.z=_,n},o.fromDegrees=function(t,e,n,r,i){return t=a.toRadians(t),e=a.toRadians(e),o.fromRadians(t,e,n,r,i)};var l=new o,f=new o,h=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,i,a,u){i=e(i,0);var s=n(a)?a.radiiSquared:h,c=Math.cos(r);l.x=c*Math.cos(t),l.y=c*Math.sin(t),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,f);var E=Math.sqrt(o.dot(l,f));return f=o.divideByScalar(f,E,f),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(f,l,u)},o.fromDegreesArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,e,r[c])}return r},o.fromRadiansArray=function(t,e,r){var i=t.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=t[a],s=t[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,e,r[c])}return r},o.fromDegreesArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromDegrees(u,s,c,e,r[E])}return r},o.fromRadiansArrayHeights=function(t,e,r){var i=t.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=t[a],s=t[a+1],c=t[a+2],E=a/3;r[E]=o.fromRadians(u,s,c,e,r[E])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function i(n,i,u,s,c){var E=n.x,_=n.y,l=n.z,f=i.x,h=i.y,T=i.z,R=E*E*f*f,d=_*_*h*h,A=l*l*T*T,p=R+d+A,m=Math.sqrt(1/p),N=t.multiplyByScalar(n,m,a);if(p<s)return isFinite(m)?t.clone(N,c):void 0;var y=u.x,I=u.y,S=u.z,O=o;O.x=N.x*y*2,O.y=N.y*I*2,O.z=N.z*S*2;var M,w,C,g,v,P,L,F,x,U,D,B=(1-m)*t.magnitude(n)/(.5*t.magnitude(O)),z=0;do{B-=z,C=1/(1+B*y),g=1/(1+B*I),v=1/(1+B*S),P=C*C,L=g*g,F=v*v,x=P*C,U=L*g,D=F*v,M=R*P+d*L+A*F-1,w=R*x*y+d*U*I+A*D*S;z=M/(-2*w)}while(Math.abs(M)>r.EPSILON12);return e(c)?(c.x=E*C,c.y=_*g,c.z=l*v,c):new t(E*C,_*g,l*v)}var a=new t,o=new t;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,i,a){return i=n(i,0),r(a)?(a.longitude=t,a.latitude=e,a.height=i,a):new u(t,e,i)},u.fromDegrees=function(t,e,n,r){return t=a.toRadians(t),e=a.toRadians(e),u.fromRadians(t,e,n,r)};var s=new t,c=new t,E=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),l=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),f=a.EPSILON1;return u.fromCartesian=function(e,n,i){var h=r(n)?n.oneOverRadii:_,T=r(n)?n.oneOverRadiiSquared:l,R=r(n)?n._centerToleranceSquared:f,d=o(e,h,T,R,c);if(r(d)){var A=t.multiplyComponents(d,T,s);A=t.normalize(A,A);var p=t.subtract(e,d,E),m=Math.atan2(A.y,A.x),N=Math.asin(A.z),y=a.sign(t.dot(p,e))*t.magnitude(p);return r(i)?(i.longitude=m,i.latitude=N,i.height=y,i):new u(m,N,y)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(e,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),e._radii=new t(n,i,a),e._radiiSquared=new t(n*n,i*i,a*a),e._radiiToTheFourth=new t(n*n*n*n,i*i*i*i,a*a*a*a),e._oneOverRadii=new t(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),e._minimumRadius=Math.min(n,i,a),e._maximumRadius=Math.max(n,i,a),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,E(this,t,e,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(i(e)){var r=e._radii;return i(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return i(e)||(e=new _),i(t)?(E(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),n},_.unpack=function(e,n,i){n=r(n,0);var a=t.unpack(e,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,a=e.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new t),n.x=u,n.y=s,n.z=c,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return i(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var l=new t,f=new t;_.prototype.cartographicToCartesian=function(e,n){var r=l,a=f;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(t.dot(r,a));return t.divideByScalar(a,o,a),t.multiplyByScalar(r,e.height,r),i(n)||(n=new t),t.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var h=new t,T=new t,R=new t;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,T);if(i(a)){var o=this.geodeticSurfaceNormal(a,h),u=t.subtract(n,a,R),c=Math.atan2(o.y,o.x),E=Math.asin(o.z),_=s.sign(t.dot(u,n))*t.magnitude(u);return i(r)?(r.longitude=c,r.latitude=E,r.height=_,r):new e(c,E,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;i(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return c(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){i(n)||(n=new t);var r=e.x,a=e.y,o=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return t.multiplyByScalar(e,s,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return i(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||i(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new t),a.x=0,a.y=0,a.z=e.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,i,a,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var i=this._semimajorAxis,a=e.longitude*i,o=e.latitude*i,u=e.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new t(a,o,u)},u.prototype.unproject=function(t,n){var i=this._oneOverSemimajorAxis,a=t.x*i,o=t.y*i,u=t.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new e(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i,a,o,u,s,c){this[0]=n(t,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function E(t){for(var e=0,n=0;n<3;++n){var r=t[s.getElementIndex(T[n],h[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(t[s.getElementIndex(T[a],h[a])]);o>r&&(i=a,r=o)}var c=1,E=0,_=h[i],l=T[i];if(Math.abs(t[s.getElementIndex(l,_)])>n){var f,R=t[s.getElementIndex(l,l)],d=t[s.getElementIndex(_,_)],A=t[s.getElementIndex(l,_)],p=(R-d)/2/A;f=p<0?-1/(-p+Math.sqrt(1+p*p)):1/(p+Math.sqrt(1+p*p)),c=1/Math.sqrt(1+f*f),E=f*c}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(_,_)]=e[s.getElementIndex(l,l)]=c,e[s.getElementIndex(l,_)]=E,e[s.getElementIndex(_,l)]=-E,e}s.packedLength=9,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e++],i[1]=t[e++],i[2]=t[e++],i[3]=t[e++],i[4]=t[e++],i[5]=t[e++],i[6]=t[e++],i[7]=t[e++],i[8]=t[e++],i},s.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i[0]=t[e],i[1]=t[e+1],i[2]=t[e+2],i[3]=t[e+3],i[4]=t[e+4],i[5]=t[e+5],i[6]=t[e+6],i[7]=t[e+7],i[8]=t[e+8],i},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var n=t.x*t.x,i=t.x*t.y,a=t.x*t.z,o=t.x*t.w,u=t.y*t.y,c=t.y*t.z,E=t.y*t.w,_=t.z*t.z,l=t.z*t.w,f=t.w*t.w,h=n-u-_+f,T=2*(i-l),R=2*(a+E),d=2*(i+l),A=-n+u-_+f,p=2*(c-o),m=2*(a-E),N=2*(c+o),y=-n-u+_+f;return r(e)?(e[0]=h,e[1]=d,e[2]=m,e[3]=T,e[4]=A,e[5]=N,e[6]=R,e[7]=p,e[8]=y,e):new s(h,T,R,d,A,p,m,N,y)},s.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),i=Math.cos(-t.heading),a=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),c=Math.sin(t.roll),E=n*i,_=-a*u+c*o*i,l=c*u+a*o*i,f=n*u,h=a*i+c*o*u,T=-c*i+a*o*u,R=-o,d=c*n,A=a*n;return r(e)?(e[0]=E,e[1]=f,e[2]=R,e[3]=_,e[4]=h,e[5]=d,e[6]=l,e[7]=T,e[8]=A,e):new s(E,_,l,f,h,T,R,d,A)},s.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=i,e[6]=0,e[7]=-i,e[8]=n,e):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-i,e[3]=0,e[4]=1,e[5]=0,e[6]=i,e[7]=0,e[8]=n,e):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(t,e){var n=Math.cos(t),i=Math.sin(t);return r(e)?(e[0]=n,e[1]=i,e[2]=0,e[3]=-i,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,n){var r=3*e,i=t[r],a=t[r+1],o=t[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(t,e,n,r){r=s.clone(t,r);var i=3*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(t,e,n){var r=t[e],i=t[e+3],a=t[e+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(t,e,n,r){return r=s.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var l=new t;s.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],l)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],l)),n};var f=new t;s.getMaximumScale=function(e){return s.getScale(e,f),t.maximumComponent(f)},s.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],i=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],a=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],c=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],E=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=E,n[8]=_,n},s.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},s.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},s.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[3]*i+t[6]*a,u=t[1]*r+t[4]*i+t[7]*a,s=t[2]*r+t[5]*i+t[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},s.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var n=t[0],r=t[3],i=t[6],a=t[1],o=t[4],u=t[7],s=t[2],c=t[5],E=t[8];return e[0]=n,e[1]=r,e[2]=i,e[3]=a,e[4]=o,e[5]=u,e[6]=s,e[7]=c,e[8]=E,e};var h=[1,0,0],T=[2,2,1],R=new s,d=new s;return s.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,i=0,a=0;r(e)||(e={});for(var o=e.unitary=s.clone(s.IDENTITY,e.unitary),l=e.diagonal=s.clone(t,e.diagonal),f=n*c(l);a<10&&E(l)>f;)_(l,R),s.transpose(R,d),s.multiply(l,R,l),s.multiply(d,l,l),s.multiply(o,R,o),++i>2&&(++a,i=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],n=t[3],r=t[6],i=t[1],a=t[4],o=t[7],u=t[2],s=t[5],c=t[8];return e*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[3],o=t[4],u=t[5],c=t[6],E=t[7],_=t[8],l=s.determinant(t);e[0]=o*_-E*u,e[1]=E*i-r*_,e[2]=r*u-o*i,e[3]=c*u-a*_,e[4]=n*_-c*i,e[5]=a*i-n*u,e[6]=a*E-c*o,e[7]=c*r-n*E,e[8]=n*o-a*r;var f=1/l;return s.multiplyByScalar(e,f,e)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,i,a){"use strict";function o(t,n,r,i){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(i,0)}o.fromElements=function(t,e,r,i,a){return n(a)?(a.x=t,a.y=e,a.z=r,a.w=i,a):new o(t,e,r,i)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.x=t[r++],i.y=t[r++],i.z=t[r++],i.w=t[r],i},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var i=0;i<r;++i)o.pack(t[i],e,4*i);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;e[a]=o.unpack(t,i,e[a])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,s),r=o.multiplyByScalar(t,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,c);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,i){return t===e||n(t)&&n(e)&&a.equalsEpsilon(t.x,e.x,r,i)&&a.equalsEpsilon(t.y,e.y,r,i)&&a.equalsEpsilon(t.z,e.z,r,i)&&a.equalsEpsilon(t.w,e.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,i,a,o,u,s,c){"use strict";function E(t,e,n,i,a,o,u,s,c,E,_,l,f,h,T,R){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(f,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(E,0),this[7]=r(h,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(T,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(R,0)}E.packedLength=16,E.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},E.unpack=function(t,e,n){return e=r(e,0),i(n)||(n=new E),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},E.clone=function(t,e){if(i(t))return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new E(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},E.fromArray=E.unpack,E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},E.fromRotationTranslation=function(e,n,a){return n=r(n,t.ZERO),i(a)?(a[0]=e[0],a[1]=e[1],a[2]=e[2],a[3]=0,a[4]=e[3],a[5]=e[4],a[6]=e[5],a[7]=0,a[8]=e[6],a[9]=e[7],a[10]=e[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new E(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},E.fromTranslationQuaternionRotationScale=function(t,e,n,r){i(r)||(r=new E);var a=n.x,o=n.y,u=n.z,s=e.x*e.x,c=e.x*e.y,_=e.x*e.z,l=e.x*e.w,f=e.y*e.y,h=e.y*e.z,T=e.y*e.w,R=e.z*e.z,d=e.z*e.w,A=e.w*e.w,p=s-f-R+A,m=2*(c-d),N=2*(_+T),y=2*(c+d),I=-s+f-R+A,S=2*(h-l),O=2*(_-T),M=2*(h+l),w=-s-f+R+A;return r[0]=p*a,r[1]=y*a,r[2]=O*a,r[3]=0,r[4]=m*o,r[5]=I*o,r[6]=M*o,r[7]=0,r[8]=N*u,r[9]=S*u,r[10]=w*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},E.fromTranslationRotationScale=function(t,e){return E.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},E.fromTranslation=function(t,e){return E.fromRotationTranslation(s.IDENTITY,t,e)},E.fromScale=function(t,e){return i(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},E.fromUniformScale=function(t,e){return i(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new E(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,l=new t,f=new t;E.fromCamera=function(e,n){var r=e.position,a=e.direction,o=e.up;t.normalize(a,_),t.normalize(t.cross(_,o,l),l),t.normalize(t.cross(l,_,f),f);var u=l.x,s=l.y,c=l.z,h=_.x,T=_.y,R=_.z,d=f.x,A=f.y,p=f.z,m=r.x,N=r.y,y=r.z,I=u*-m+s*-N+c*-y,S=d*-m+A*-N+p*-y,O=h*m+T*N+R*y;return i(n)?(n[0]=u,n[1]=d,n[2]=-h,n[3]=0,n[4]=s,n[5]=A,n[6]=-T,n[7]=0,n[8]=c,n[9]=p,n[10]=-R,n[11]=0,n[12]=I,n[13]=S,n[14]=O,n[15]=1,n):new E(u,s,c,I,d,A,p,S,-h,-T,-R,O,0,0,0,1)},E.computePerspectiveFieldOfView=function(t,e,n,r,i){var a=Math.tan(.5*t),o=1/a,u=o/e,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},E.computeOrthographicOffCenter=function(t,e,n,r,i,a,o){var u=1/(e-t),s=1/(r-n),c=1/(a-i),E=-(e+t)*u,_=-(r+n)*s,l=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=E,o[13]=_,o[14]=l,o[15]=1,o},E.computePerspectiveOffCenter=function(t,e,n,r,i,a,o){var u=2*i/(e-t),s=2*i/(r-n),c=(e+t)/(e-t),E=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=E,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},E.computeInfinitePerspectiveOffCenter=function(t,e,n,r,i,a){var o=2*i/(e-t),u=2*i/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),E=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},E.computeViewportTransformation=function(t,e,n,i){t=r(t,r.EMPTY_OBJECT);var a=r(t.x,0),o=r(t.y,0),u=r(t.width,0),s=r(t.height,0);e=r(e,0),n=r(n,1);var c=.5*u,E=.5*s,_=.5*(n-e),l=c,f=E,h=_,T=a+c,R=o+E,d=e+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=f,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=h,i[11]=0,i[12]=T,i[13]=R,i[14]=d,i[15]=1,i},E.computeView=function(e,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-t.dot(i,e),a[13]=-t.dot(r,e),a[14]=t.dot(n,e),a[15]=1,a},E.toArray=function(t,e){return i(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},E.getElementIndex=function(t,e){return 4*t+e},E.getColumn=function(t,e,n){var r=4*e,i=t[r],a=t[r+1],o=t[r+2],u=t[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var i=4*e;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},E.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},E.getRow=function(t,e,n){var r=t[e],i=t[e+4],a=t[e+8],o=t[e+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var h=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],h)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],h)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],h)),n};var T=new t;E.getMaximumScale=function(e){return E.getScale(e,T),t.maximumComponent(T)},E.multiply=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[3],u=t[4],s=t[5],c=t[6],E=t[7],_=t[8],l=t[9],f=t[10],h=t[11],T=t[12],R=t[13],d=t[14],A=t[15],p=e[0],m=e[1],N=e[2],y=e[3],I=e[4],S=e[5],O=e[6],M=e[7],w=e[8],C=e[9],g=e[10],v=e[11],P=e[12],L=e[13],F=e[14],x=e[15],U=r*p+u*m+_*N+T*y,D=i*p+s*m+l*N+R*y,B=a*p+c*m+f*N+d*y,z=o*p+E*m+h*N+A*y,b=r*I+u*S+_*O+T*M,G=i*I+s*S+l*O+R*M,V=a*I+c*S+f*O+d*M,X=o*I+E*S+h*O+A*M,q=r*w+u*C+_*g+T*v,W=i*w+s*C+l*g+R*v,H=a*w+c*C+f*g+d*v,k=o*w+E*C+h*g+A*v,Y=r*P+u*L+_*F+T*x,K=i*P+s*L+l*F+R*x,Z=a*P+c*L+f*F+d*x,j=o*P+E*L+h*F+A*x;return n[0]=U,n[1]=D,n[2]=B,n[3]=z,n[4]=b,n[5]=G,n[6]=V,n[7]=X,n[8]=q,n[9]=W,n[10]=H,n[11]=k,n[12]=Y,n[13]=K,n[14]=Z,n[15]=j,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},E.multiplyTransformation=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=t[12],f=t[13],h=t[14],T=e[0],R=e[1],d=e[2],A=e[4],p=e[5],m=e[6],N=e[8],y=e[9],I=e[10],S=e[12],O=e[13],M=e[14],w=r*T+o*R+c*d,C=i*T+u*R+E*d,g=a*T+s*R+_*d,v=r*A+o*p+c*m,P=i*A+u*p+E*m,L=a*A+s*p+_*m,F=r*N+o*y+c*I,x=i*N+u*y+E*I,U=a*N+s*y+_*I,D=r*S+o*O+c*M+l,B=i*S+u*O+E*M+f,z=a*S+s*O+_*M+h;return n[0]=w,n[1]=C,n[2]=g,n[3]=0,n[4]=v,n[5]=P,n[6]=L,n[7]=0,n[8]=F,n[9]=x,n[10]=U,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},E.multiplyByMatrix3=function(t,e,n){var r=t[0],i=t[1],a=t[2],o=t[4],u=t[5],s=t[6],c=t[8],E=t[9],_=t[10],l=e[0],f=e[1],h=e[2],T=e[3],R=e[4],d=e[5],A=e[6],p=e[7],m=e[8],N=r*l+o*f+c*h,y=i*l+u*f+E*h,I=a*l+s*f+_*h,S=r*T+o*R+c*d,O=i*T+u*R+E*d,M=a*T+s*R+_*d,w=r*A+o*p+c*m,C=i*A+u*p+E*m,g=a*A+s*p+_*m;return n[0]=N,n[1]=y,n[2]=I,n[3]=0,n[4]=S,n[5]=O,n[6]=M,n[7]=0,n[8]=w,n[9]=C,n[10]=g,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},E.multiplyByTranslation=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=r*t[0]+i*t[4]+a*t[8]+t[12],u=r*t[1]+i*t[5]+a*t[9]+t[13],s=r*t[2]+i*t[6]+a*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=s,n[15]=t[15],n};var R=new t;E.multiplyByUniformScale=function(t,e,n){return R.x=e,R.y=e,R.z=e,E.multiplyByScale(t,R,n)},E.multiplyByScale=function(t,e,n){var r=e.x,i=e.y,a=e.z;return 1===r&&1===i&&1===a?E.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=i*t[4],n[5]=i*t[5],n[6]=i*t[6],n[7]=0,n[8]=a*t[8],n[9]=a*t[9],n[10]=a*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},E.multiplyByVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t[0]*r+t[4]*i+t[8]*a+t[12]*o,s=t[1]*r+t[5]*i+t[9]*a+t[13]*o,c=t[2]*r+t[6]*i+t[10]*a+t[14]*o,E=t[3]*r+t[7]*i+t[11]*a+t[15]*o;return n.x=u,n.y=s,n.z=c,n.w=E,n},E.multiplyByPointAsVector=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a,u=t[1]*r+t[5]*i+t[9]*a,s=t[2]*r+t[6]*i+t[10]*a;return n.x=o,n.y=u,n.z=s,n},E.multiplyByPoint=function(t,e,n){var r=e.x,i=e.y,a=e.z,o=t[0]*r+t[4]*i+t[8]*a+t[12],u=t[1]*r+t[5]*i+t[9]*a+t[13],s=t[2]*r+t[6]*i+t[10]*a+t[14];return n.x=o,n.y=u,n.z=s,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},E.transpose=function(t,e){var n=t[1],r=t[2],i=t[3],a=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=a,e[10]=t[10],e[11]=t[14],e[12]=i,e[13]=o,e[14]=u,e[15]=t[15],e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},E.equals=function(t,e){return t===e||i(t)&&i(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},E.equalsEpsilon=function(t,e,n){return t===e||i(t)&&i(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},E.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},E.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var d=new s,A=new s,p=new e,m=new e(0,0,0,1);return E.inverse=function(t,n){if(s.equalsEpsilon(E.getRotation(t,d),A,u.EPSILON7)&&e.equals(E.getRow(t,3,p),m))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],i=t[4],a=t[8],o=t[12],_=t[1],l=t[5],f=t[9],h=t[13],T=t[2],R=t[6],N=t[10],y=t[14],I=t[3],S=t[7],O=t[11],M=t[15],w=N*M,C=y*O,g=R*M,v=y*S,P=R*O,L=N*S,F=T*M,x=y*I,U=T*O,D=N*I,B=T*S,z=R*I,b=w*l+v*f+P*h-(C*l+g*f+L*h),G=C*_+F*f+D*h-(w*_+x*f+U*h),V=g*_+x*l+B*h-(v*_+F*l+z*h),X=L*_+U*l+z*f-(P*_+D*l+B*f),q=C*i+g*a+L*o-(w*i+v*a+P*o),W=w*r+x*a+U*o-(C*r+F*a+D*o),H=v*r+F*i+z*o-(g*r+x*i+B*o),k=P*r+D*i+B*a-(L*r+U*i+z*a);w=a*h,C=o*f,g=i*h,v=o*l,P=i*f,L=a*l,F=r*h,x=o*_,U=r*f,D=a*_,B=r*l,z=i*_;var Y=w*S+v*O+P*M-(C*S+g*O+L*M),K=C*I+F*O+D*M-(w*I+x*O+U*M),Z=g*I+x*S+B*M-(v*I+F*S+z*M),j=L*I+U*S+z*O-(P*I+D*S+B*O),Q=g*N+L*y+C*R-(P*y+w*R+v*N),J=U*y+w*T+x*N-(F*N+D*y+C*T),$=F*R+z*y+v*T-(B*y+g*T+x*R),tt=B*N+P*T+D*R-(U*R+z*N+L*T),et=r*b+i*G+a*V+o*X;if(Math.abs(et)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=b*et,n[1]=G*et,n[2]=V*et,n[3]=X*et,n[4]=q*et,n[5]=W*et,n[6]=H*et,n[7]=k*et,n[8]=Y*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},E.inverseTransformation=function(t,e){var n=t[0],r=t[1],i=t[2],a=t[4],o=t[5],u=t[6],s=t[8],c=t[9],E=t[10],_=t[12],l=t[13],f=t[14],h=-n*_-r*l-i*f,T=-a*_-o*l-u*f,R=-s*_-c*l-E*f;return e[0]=n,e[1]=a,e[2]=s,e[3]=0,e[4]=r,e[5]=o,e[6]=c,e[7]=0,e[8]=i,e[9]=u,e[10]=E,e[11]=0,e[12]=h,e[13]=T,e[14]=R,e[15]=1,e},E.IDENTITY=o(new E(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN0ROW3=3,E.COLUMN1ROW0=4,E.COLUMN1ROW1=5,E.COLUMN1ROW2=6,E.COLUMN1ROW3=7,E.COLUMN2ROW0=8,E.COLUMN2ROW1=9,E.COLUMN2ROW2=10,E.COLUMN2ROW3=11,E.COLUMN3ROW0=12,E.COLUMN3ROW1=13,E.COLUMN3ROW2=14,E.COLUMN3ROW3=15,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},E}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.west=t[e++],i.south=t[e++],i.east=t[e++],i.north=t[e],i},s.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,i,a,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=t,o.south=e,o.east=i,o.north=a,o):new s(t,e,i,a)},s.fromRadians=function(t,e,i,a,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(i,0),o.north=n(a,0),o):new s(t,e,i,a)},s.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,E=-Number.MAX_VALUE,_=0,l=t.length;_<l;_++){var f=t[_];n=Math.min(n,f.longitude),i=Math.max(i,f.longitude),c=Math.min(c,f.latitude),E=Math.max(E,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;a=Math.min(a,h),o=Math.max(o,h)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=c,e.east=i,e.north=E,e):new s(n,c,i,E)},s.fromCartesianArray=function(t,e,i){e=n(e,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,E=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=0,T=t.length;h<T;h++){var R=e.cartesianToCartographic(t[h]);o=Math.min(o,R.longitude),c=Math.max(c,R.longitude),l=Math.min(l,R.latitude),f=Math.max(f,R.latitude);var d=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;E=Math.min(E,d),_=Math.max(_,d)}return c-o>_-E&&(o=E,c=_,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=c,i.north=f,i):new s(o,l,c,f)},s.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},s.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},s.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},s.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},s.center=function(e,n){var i=e.east,a=e.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new t(o,s)},s.intersection=function(t,e,n){var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.negativePiToPi(Math.max(a,c)),_=u.negativePiToPi(Math.min(i,o));if(!((t.west<t.east||e.west<e.east)&&_<=E)){var l=Math.max(t.south,e.south),f=Math.min(t.north,e.north);if(!(l>=f))return r(n)?(n.west=E,n.south=l,n.east=_,n.north=f,n):new s(E,l,_,f)}},s.simpleIntersection=function(t,e,n){var i=Math.max(t.west,e.west),a=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(t,e,n){r(n)||(n=new s);var i=t.east,a=t.west,o=e.east,c=e.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.convertLongitudeRange(Math.min(a,c)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=E,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},s.expand=function(t,e,n){return r(n)||(n=new s),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},s.contains=function(t,e){var n=e.longitude,r=e.latitude,i=t.west,a=t.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=t.south&&r<=t.north};var c=new t;return s.subsample=function(t,e,i,o){e=n(e,a.WGS84),i=n(i,0),r(o)||(o=[]);var E=0,_=t.north,l=t.south,f=t.east,h=t.west,T=c;T.height=i,T.longitude=h,T.latitude=_,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=l,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.latitude=_<0?_:l>0?l:0;for(var R=1;R<8;++R)T.longitude=-Math.PI+R*u.PI_OVER_TWO,s.contains(t,T)&&(o[E]=e.cartographicToCartesian(T,o[E]),E++);return 0===T.latitude&&(T.longitude=h,o[E]=e.cartographicToCartesian(T,o[E]),E++,T.longitude=f,o[E]=e.cartographicToCartesian(T,o[E]),E++),o.length=E,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,i,a,o,u,s,c,E,_,l){"use strict";function f(e,n){this.center=t.clone(i(e,t.ZERO)),this.radius=i(n,0)}var h=new t,T=new t,R=new t,d=new t,A=new t,p=new t,m=new t,N=new t,y=new t,I=new t,S=new t,O=new t,M=4/3*n.PI;f.fromPoints=function(e,n){if(a(n)||(n=new f),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],m),o=t.clone(i,h),u=t.clone(i,T),s=t.clone(i,R),c=t.clone(i,d),E=t.clone(i,A),_=t.clone(i,p),l=e.length;for(r=1;r<l;r++){t.clone(e[r],i);var M=i.x,w=i.y,C=i.z;M<o.x&&t.clone(i,o),M>c.x&&t.clone(i,c),w<u.y&&t.clone(i,u),w>E.y&&t.clone(i,E),C<s.z&&t.clone(i,s),C>_.z&&t.clone(i,_)}var g=t.magnitudeSquared(t.subtract(c,o,N)),v=t.magnitudeSquared(t.subtract(E,u,N)),P=t.magnitudeSquared(t.subtract(_,s,N)),L=o,F=c,x=g;v>x&&(x=v,L=u,F=E),P>x&&(x=P,L=s,F=_);var U=y;U.x=.5*(L.x+F.x),U.y=.5*(L.y+F.y),U.z=.5*(L.z+F.z);var D=t.magnitudeSquared(t.subtract(F,U,N)),B=Math.sqrt(D),z=I;z.x=o.x,z.y=u.y,z.z=s.z;var b=S;b.x=c.x,b.y=E.y,b.z=_.z;var G=t.multiplyByScalar(t.add(z,b,N),.5,O),V=0;for(r=0;r<l;r++){t.clone(e[r],i);var X=t.magnitude(t.subtract(i,G,N));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(i,U,N));if(q>D){var W=Math.sqrt(q);B=.5*(B+W),D=B*B;var H=W-B;U.x=(B*U.x+H*i.x)/W,U.y=(B*U.y+H*i.y)/W,U.z=(B*U.z+H*i.z)/W}}return B<V?(t.clone(U,n.center),n.radius=B):(t.clone(G,n.center),n.radius=V),n};var w=new u,C=new t,g=new t,v=new e,P=new e;f.fromRectangle2D=function(t,e,n){return f.fromRectangleWithHeights2D(t,e,0,0,n)},f.fromRectangleWithHeights2D=function(e,n,r,o,u){if(a(u)||(u=new f),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=i(n,w),l.southwest(e,v),v.height=r,l.northeast(e,P),P.height=o;var s=n.project(v,C),c=n.project(P,g),E=c.x-s.x,_=c.y-s.y,h=c.z-s.z;u.radius=.5*Math.sqrt(E*E+_*_+h*h);var T=u.center;return T.x=s.x+.5*E,T.y=s.y+.5*_,T.z=s.z+.5*h,u};var L=[];f.fromRectangle3D=function(e,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new f),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=l.subsample(e,n,r,L);return f.fromPoints(s,u)},f.fromVertices=function(e,n,r,o){if(a(o)||(o=new f),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=i(n,t.ZERO),r=i(r,3);var u=m;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var s,c=t.clone(u,h),E=t.clone(u,T),_=t.clone(u,R),l=t.clone(u,d),M=t.clone(u,A),w=t.clone(u,p),C=e.length;for(s=0;s<C;s+=r){var g=e[s]+n.x,v=e[s+1]+n.y,P=e[s+2]+n.z;u.x=g,u.y=v,u.z=P,g<c.x&&t.clone(u,c),g>l.x&&t.clone(u,l),v<E.y&&t.clone(u,E),v>M.y&&t.clone(u,M),P<_.z&&t.clone(u,_),P>w.z&&t.clone(u,w)}var L=t.magnitudeSquared(t.subtract(l,c,N)),F=t.magnitudeSquared(t.subtract(M,E,N)),x=t.magnitudeSquared(t.subtract(w,_,N)),U=c,D=l,B=L;F>B&&(B=F,U=E,D=M),x>B&&(B=x,U=_,D=w);var z=y;z.x=.5*(U.x+D.x),z.y=.5*(U.y+D.y),z.z=.5*(U.z+D.z);var b=t.magnitudeSquared(t.subtract(D,z,N)),G=Math.sqrt(b),V=I;V.x=c.x,V.y=E.y,V.z=_.z;var X=S;X.x=l.x,X.y=M.y,X.z=w.z;var q=t.multiplyByScalar(t.add(V,X,N),.5,O),W=0;for(s=0;s<C;s+=r){u.x=e[s]+n.x,u.y=e[s+1]+n.y,u.z=e[s+2]+n.z;var H=t.magnitude(t.subtract(u,q,N));H>W&&(W=H);var k=t.magnitudeSquared(t.subtract(u,z,N));if(k>b){var Y=Math.sqrt(k);G=.5*(G+Y),b=G*G;var K=Y-G;z.x=(G*z.x+K*u.x)/Y,z.y=(G*z.y+K*u.y)/Y,z.z=(G*z.z+K*u.z)/Y}}return G<W?(t.clone(z,o.center),o.radius=G):(t.clone(q,o.center),o.radius=W),o},f.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new f),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=m;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,h),s=t.clone(i,T),c=t.clone(i,R),E=t.clone(i,d),_=t.clone(i,A),l=t.clone(i,p),M=e.length;for(o=0;o<M;o+=3){var w=e[o]+n[o],C=e[o+1]+n[o+1],g=e[o+2]+n[o+2];i.x=w,i.y=C,i.z=g,w<u.x&&t.clone(i,u),w>E.x&&t.clone(i,E),C<s.y&&t.clone(i,s),C>_.y&&t.clone(i,_),g<c.z&&t.clone(i,c),g>l.z&&t.clone(i,l)}var v=t.magnitudeSquared(t.subtract(E,u,N)),P=t.magnitudeSquared(t.subtract(_,s,N)),L=t.magnitudeSquared(t.subtract(l,c,N)),F=u,x=E,U=v;P>U&&(U=P,F=s,x=_),L>U&&(U=L,F=c,x=l);var D=y;D.x=.5*(F.x+x.x),D.y=.5*(F.y+x.y),D.z=.5*(F.z+x.z);var B=t.magnitudeSquared(t.subtract(x,D,N)),z=Math.sqrt(B),b=I;b.x=u.x,b.y=s.y,b.z=c.z;var G=S;G.x=E.x,G.y=_.y,G.z=l.z;var V=t.multiplyByScalar(t.add(b,G,N),.5,O),X=0;for(o=0;o<M;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,V,N));q>X&&(X=q);var W=t.magnitudeSquared(t.subtract(i,D,N));if(W>B){var H=Math.sqrt(W);z=.5*(z+H),B=z*z;var k=H-z;D.x=(z*D.x+k*i.x)/H,D.y=(z*D.y+k*i.y)/H,D.z=(z*D.z+k*i.z)/H}}return z<X?(t.clone(D,r.center),r.radius=z):(t.clone(V,r.center),r.radius=X),r},f.fromCornerPoints=function(e,n,r){a(r)||(r=new f);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},f.fromEllipsoid=function(e,n){return a(n)||(n=new f),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var F=new t;f.fromBoundingSpheres=function(e,n){if(a(n)||(n=new f),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return f.clone(e[0],n);if(2===r)return f.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=f.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=e[i];s=Math.max(s,t.distance(u,c.center,F)+c.radius)}return n.radius=s,n};var x=new t,U=new t,D=new t;f.fromOrientedBoundingBox=function(e,n){a(n)||(n=new f);var r=e.halfAxes,i=E.getColumn(r,0,x),o=E.getColumn(r,1,U),u=E.getColumn(r,2,D);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},f.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new f(e.center,e.radius)},f.packedLength=4,f.pack=function(t,e,n){n=i(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},f.unpack=function(t,e,n){e=i(e,0),a(n)||(n=new f);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var B=new t,z=new t;f.union=function(e,n,r){a(r)||(r=new f);var i=e.center,o=e.radius,u=n.center,s=n.radius,c=t.subtract(u,i,B),E=t.magnitude(c);if(o>=E+s)return e.clone(r),r;if(s>=E+o)return n.clone(r),r;var _=.5*(o+E+s),l=t.multiplyByScalar(c,(-o+_)/E,z);return t.add(l,i,l),t.clone(l,r.center),r.radius=_,r};var b=new t;f.expand=function(e,n,r){r=f.clone(e,r);var i=t.magnitude(t.subtract(n,r.center,b));return i>r.radius&&(r.radius=i),r},f.intersectPlane=function(e,n){var r=e.center,i=e.radius,a=n.normal,o=t.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},f.transform=function(t,e,n){return a(n)||(n=new f),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var G=new t;f.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,G);return t.magnitudeSquared(r)-e.radius*e.radius},f.transformWithoutScale=function(t,e,n){return a(n)||(n=new f),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var V=new t;f.computePlaneDistances=function(e,n,r,i){a(i)||(i=new c);var o=t.subtract(e.center,n,V),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var X=new t,q=new t,W=new t,H=new t,k=new t,Y=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return f.projectTo2D=function(e,n,r){n=i(n,j);var a=n.ellipsoid,o=e.center,u=e.radius,s=a.geodeticSurfaceNormal(o,X),c=t.cross(t.UNIT_Z,s,q);t.normalize(c,c);var E=t.cross(s,c,W);t.normalize(E,E),t.multiplyByScalar(s,u,s),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c);var _=t.negate(E,k),l=t.negate(c,H),h=K,T=h[0];t.add(s,E,T),t.add(T,c,T),T=h[1],t.add(s,E,T),t.add(T,l,T),T=h[2],t.add(s,_,T),t.add(T,l,T),T=h[3],t.add(s,_,T),t.add(T,c,T),t.negate(s,s),T=h[4],t.add(s,E,T),t.add(T,c,T),T=h[5],t.add(s,E,T),t.add(T,l,T),T=h[6],t.add(s,_,T),t.add(T,l,T),T=h[7],t.add(s,_,T),t.add(T,c,T);for(var R=h.length,d=0;d<R;++d){var A=h[d];t.add(o,A,A);var p=a.cartesianToCartographic(A,Y);n.project(p,A)}r=f.fromPoints(h,r),o=r.center;var m=o.x,N=o.y,y=o.z;return o.x=y,o.y=m,o.z=N,r},f.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},f.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},f.prototype.intersectPlane=function(t){return f.intersectPlane(this,t)},f.prototype.distanceSquaredTo=function(t){return f.distanceSquaredTo(this,t)},f.prototype.computePlaneDistances=function(t,e,n){return f.computePlaneDistances(this,t,e,n)},f.prototype.isOccluded=function(t){return f.isOccluded(this,t)},f.prototype.equals=function(t){return f.equals(this,t)},f.prototype.clone=function(t){return f.clone(this,t)},f.prototype.volume=function(){var t=this.radius;return M*t*t*t},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return e(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof e[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof e[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(t,e){i.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function i(){if(!e(N)&&(N=!1,!l())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(N=!0,y=r(t[1]))}return N}function a(){return i()&&y}function o(){if(!e(I)&&(I=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(I=!0,S=r(t[1]))}return I}function u(){return o()&&S}function s(){if(!e(O)){O=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(O=!0, +M=r(t[1]),M.isNightly=!!t[2])}return O}function c(){return s()&&M}function E(){if(!e(w)){w=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(w=!0,C=r(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(w=!0,C=r(t[1]))}return w}function _(){return E()&&C}function l(){if(!e(g)){g=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(g=!0,v=r(t[1]))}return g}function f(){return l()&&v}function h(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(P=!0,L=r(t[1]))}return P}function T(){return e(F)||(F=/Windows/i.test(m.appVersion)),F}function R(){return h()&&L}function d(){return e(x)||(x="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),x}function A(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(U=n)}return D}function p(){return A()?U:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var N,y,I,S,O,M,w,C,g,v,P,L,F,x,U,D,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:E,internetExplorerVersion:_,isEdge:l,edgeVersion:f,isFirefox:h,firefoxVersion:R,isWindows:T,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:d,supportsImageRenderingPixelated:A,imageRenderingValue:p};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,i){switch(r=t(r,0),i=t(i,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,a.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,i.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var i=t.attributes[r],a=i.values.length/i.componentsPerAttribute;e=a}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,n,r,i,a,o){"use strict";function u(e,n){this.normal=t.clone(e),this.distance=n}u.fromPointNormal=function(e,r,i){var a=-t.dot(r,e);return n(i)?(t.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new t;u.fromCartesian4=function(e,r){var i=t.fromCartesian4(e,s),a=e.w;return n(r)?(t.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(e,n){return t.dot(e.normal,n)+e.distance};var c=new t;u.projectPointOntoPlane=function(e,r,i){n(i)||(i=new t);var a=u.getPointDistance(e,r),o=t.multiplyByScalar(e.normal,a,c);return t.subtract(r,o,i)};var E=new t;return u.transform=function(e,n,r){return o.multiplyByPointAsVector(n,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,E),o.multiplyByPoint(n,E,E),u.fromPointNormal(E,s,r)},u.clone=function(e,r){return n(r)?(t.clone(e.normal,r.normal),r.distance=e.distance,r):new u(e.normal,e.distance)},u.equals=function(e,n){return e.distance===n.distance&&t.equals(e.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(t.UNIT_Y,0)),u}),define("Core/CullingVolume",["./Cartesian3","./Cartesian4","./defaultValue","./defined","./DeveloperError","./Intersect","./Plane"],function(t,e,n,r,i,a,o){"use strict";function u(t){this.planes=n(t,[])}var s=[new t,new t,new t];t.clone(t.UNIT_X,s[0]),t.clone(t.UNIT_Y,s[1]),t.clone(t.UNIT_Z,s[2]);var c=new t,E=new t,_=new o(new t(1,0,0),0);return u.fromBoundingSphere=function(n,i){r(i)||(i=new u);var a=s.length,o=i.planes;o.length=2*a;for(var _=n.center,l=n.radius,f=0,h=0;h<a;++h){var T=s[h],R=o[f],d=o[f+1];r(R)||(R=o[f]=new e),r(d)||(d=o[f+1]=new e),t.multiplyByScalar(T,-l,c),t.add(_,c,c),R.x=T.x,R.y=T.y,R.z=T.z,R.w=-t.dot(T,c),t.multiplyByScalar(T,l,c),t.add(_,c,c),d.x=-T.x,d.y=-T.y,d.z=-T.z,d.w=-t.dot(t.negate(T,E),c),f+=2}return i},u.prototype.computeVisibility=function(t){for(var e=this.planes,n=!1,r=0,i=e.length;r<i;++r){var u=t.intersectPlane(o.fromCartesian4(e[r],_));if(u===a.OUTSIDE)return a.OUTSIDE;u===a.INTERSECTING&&(n=!0)}return n?a.INTERSECTING:a.INSIDE},u.prototype.computeVisibilityWithPlaneMask=function(t,e){if(e===u.MASK_OUTSIDE||e===u.MASK_INSIDE)return e;for(var n=u.MASK_INSIDE,r=this.planes,i=0,s=r.length;i<s;++i){var c=i<31?1<<i:0;if(!(i<31&&0==(e&c))){var E=t.intersectPlane(o.fromCartesian4(r[i],_));if(E===a.OUTSIDE)return u.MASK_OUTSIDE;E===a.INTERSECTING&&(n|=c)}}return n},u.MASK_OUTSIDE=4294967295,u.MASK_INSIDE=0,u.MASK_INDETERMINATE=2147483647,u}),define("Core/OrthographicOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._orthographicMatrix=new u}function c(t){t.top===t._top&&t.bottom===t._bottom&&t.left===t._left&&t.right===t._right&&t.near===t._near&&t.far===t._far||(t._left=t.left,t._right=t.right,t._top=t.top,t._bottom=t.bottom,t._near=t.near,t._far=t.far,t._orthographicMatrix=u.computeOrthographicOffCenter(t.left,t.right,t.bottom,t.top,t.near,t.far,t._orthographicMatrix))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._orthographicMatrix}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E);t.normalize(d,d);var A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(d,h,p),t.add(A,p,p);var m=o[0];return i(m)||(m=o[0]=new e),m.x=d.x,m.y=d.y,m.z=d.z,m.w=-t.dot(d,p),t.multiplyByScalar(d,c,p),t.add(A,p,p),m=o[1],i(m)||(m=o[1]=new e),m.x=-d.x,m.y=-d.y,m.z=-d.z,m.w=-t.dot(t.negate(d,f),p),t.multiplyByScalar(a,s,p),t.add(A,p,p),m=o[2],i(m)||(m=o[2]=new e),m.x=a.x,m.y=a.y,m.z=a.z,m.w=-t.dot(a,p),t.multiplyByScalar(a,u,p),t.add(A,p,p),m=o[3],i(m)||(m=o[3]=new e),m.x=-a.x,m.y=-a.y,m.z=-a.z,m.w=-t.dot(t.negate(a,f),p),m=o[4],i(m)||(m=o[4]=new e),m.x=r.x,m.y=r.y,m.z=r.z,m.w=-t.dot(r,A),t.multiplyByScalar(r,R,p),t.add(n,p,p),m=o[5],i(m)||(m=o[5]=new e),m.x=-r.x,m.y=-r.y,m.z=-r.z,m.w=-t.dot(t.negate(r,f),p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=this.right-this.left,a=this.top-this.bottom,o=i/t,u=a/e;return r.x=o,r.y=u,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.left=this.left,t.right=this.right,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/OrthographicFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./OrthographicOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.width=t.width,this._width=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far}function u(t){var e=t._offCenterFrustum;if(t.width!==t._width||t.aspectRatio!==t._aspectRatio||t.near!==t._near||t.far!==t._far){t._aspectRatio=t.aspectRatio,t._width=t.width,t._near=t.near,t._far=t.far;var n=1/t.aspectRatio;e.right=.5*t.width,e.left=-e.right,e.top=n*e.right,e.bottom=-e.top,e.near=t.near,e.far=t.far}}return o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.width,n[r++]=t.aspectRatio,n[r++]=t.near,n[r]=t.far,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.width=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.width=this.width,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._width=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.width===t.width&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/PerspectiveOffCenterFrustum",["./Cartesian3","./Cartesian4","./CullingVolume","./defaultValue","./defined","./defineProperties","./DeveloperError","./Matrix4"],function(t,e,n,r,i,a,o,u){"use strict";function s(t){t=r(t,r.EMPTY_OBJECT),this.left=t.left,this._left=void 0,this.right=t.right,this._right=void 0,this.top=t.top,this._top=void 0,this.bottom=t.bottom,this._bottom=void 0,this.near=r(t.near,1),this._near=this.near,this.far=r(t.far,5e8),this._far=this.far,this._cullingVolume=new n,this._perspectiveMatrix=new u,this._infinitePerspective=new u}function c(t){var e=t.top,n=t.bottom,r=t.right,i=t.left,a=t.near,o=t.far;e===t._top&&n===t._bottom&&i===t._left&&r===t._right&&a===t._near&&o===t._far||(t._left=i,t._right=r,t._top=e,t._bottom=n,t._near=a,t._far=o,t._perspectiveMatrix=u.computePerspectiveOffCenter(i,r,n,e,a,o,t._perspectiveMatrix),t._infinitePerspective=u.computeInfinitePerspectiveOffCenter(i,r,n,e,a,t._infinitePerspective))}a(s.prototype,{projectionMatrix:{get:function(){return c(this),this._perspectiveMatrix}},infiniteProjectionMatrix:{get:function(){return c(this),this._infinitePerspective}}});var E=new t,_=new t,l=new t,f=new t;return s.prototype.computeCullingVolume=function(n,r,a){var o=this._cullingVolume.planes,u=this.top,s=this.bottom,c=this.right,h=this.left,T=this.near,R=this.far,d=t.cross(r,a,E),A=_;t.multiplyByScalar(r,T,A),t.add(n,A,A);var p=l;t.multiplyByScalar(r,R,p),t.add(n,p,p);var m=f;t.multiplyByScalar(d,h,m),t.add(A,m,m),t.subtract(m,n,m),t.normalize(m,m),t.cross(m,a,m),t.normalize(m,m);var N=o[0];return i(N)||(N=o[0]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(d,c,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(a,m,m),t.normalize(m,m),N=o[1],i(N)||(N=o[1]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,s,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(d,m,m),t.normalize(m,m),N=o[2],i(N)||(N=o[2]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),t.multiplyByScalar(a,u,m),t.add(A,m,m),t.subtract(m,n,m),t.cross(m,d,m),t.normalize(m,m),N=o[3],i(N)||(N=o[3]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,n),N=o[4],i(N)||(N=o[4]=new e),N.x=r.x,N.y=r.y,N.z=r.z,N.w=-t.dot(r,A),t.negate(r,m),N=o[5],i(N)||(N=o[5]=new e),N.x=m.x,N.y=m.y,N.z=m.z,N.w=-t.dot(m,p),this._cullingVolume},s.prototype.getPixelDimensions=function(t,e,n,r){c(this);var i=1/this.near,a=this.top*i,o=2*n*a/e;a=this.right*i;var u=2*n*a/t;return r.x=u,r.y=o,r},s.prototype.clone=function(t){return i(t)||(t=new s),t.right=this.right,t.left=this.left,t.top=this.top,t.bottom=this.bottom,t.near=this.near,t.far=this.far,t._left=void 0,t._right=void 0,t._top=void 0,t._bottom=void 0,t._near=void 0,t._far=void 0,t},s.prototype.equals=function(t){return i(t)&&this.right===t.right&&this.left===t.left&&this.top===t.top&&this.bottom===t.bottom&&this.near===t.near&&this.far===t.far},s}),define("Core/PerspectiveFrustum",["./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./PerspectiveOffCenterFrustum"],function(t,e,n,r,i,a){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this._offCenterFrustum=new a,this.fov=t.fov,this._fov=void 0,this._fovy=void 0,this._sseDenominator=void 0,this.aspectRatio=t.aspectRatio,this._aspectRatio=void 0,this.near=e(t.near,1),this._near=this.near,this.far=e(t.far,5e8),this._far=this.far,this.xOffset=e(t.xOffset,0),this._xOffset=this.xOffset,this.yOffset=e(t.yOffset,0),this._yOffset=this.yOffset}function u(t){var e=t._offCenterFrustum;t.fov===t._fov&&t.aspectRatio===t._aspectRatio&&t.near===t._near&&t.far===t._far&&t.xOffset===t._xOffset&&t.yOffset===t._yOffset||(t._aspectRatio=t.aspectRatio,t._fov=t.fov,t._fovy=t.aspectRatio<=1?t.fov:2*Math.atan(Math.tan(.5*t.fov)/t.aspectRatio),t._near=t.near,t._far=t.far,t._sseDenominator=2*Math.tan(.5*t._fovy),t._xOffset=t.xOffset,t._yOffset=t.yOffset,e.top=t.near*Math.tan(.5*t._fovy),e.bottom=-e.top,e.right=t.aspectRatio*e.top,e.left=-e.right,e.near=t.near,e.far=t.far,e.right+=t.xOffset,e.left+=t.xOffset,e.top+=t.yOffset,e.bottom+=t.yOffset)}return o.packedLength=6,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.fov,n[r++]=t.aspectRatio,n[r++]=t.near,n[r++]=t.far,n[r++]=t.xOffset,n[r]=t.yOffset,n},o.unpack=function(t,r,i){return r=e(r,0),n(i)||(i=new o),i.fov=t[r++],i.aspectRatio=t[r++],i.near=t[r++],i.far=t[r++],i.xOffset=t[r++],i.yOffset=t[r],i},r(o.prototype,{projectionMatrix:{get:function(){return u(this),this._offCenterFrustum.projectionMatrix}},infiniteProjectionMatrix:{get:function(){return u(this),this._offCenterFrustum.infiniteProjectionMatrix}},fovy:{get:function(){return u(this),this._fovy}},sseDenominator:{get:function(){return u(this),this._sseDenominator}}}),o.prototype.computeCullingVolume=function(t,e,n){return u(this),this._offCenterFrustum.computeCullingVolume(t,e,n)},o.prototype.getPixelDimensions=function(t,e,n,r){return u(this),this._offCenterFrustum.getPixelDimensions(t,e,n,r)},o.prototype.clone=function(t){return n(t)||(t=new o),t.aspectRatio=this.aspectRatio,t.fov=this.fov,t.near=this.near,t.far=this.far,t._aspectRatio=void 0,t._fov=void 0,t._near=void 0,t._far=void 0,this._offCenterFrustum.clone(t._offCenterFrustum),t},o.prototype.equals=function(t){return!!n(t)&&(u(this),u(t),this.fov===t.fov&&this.aspectRatio===t.aspectRatio&&this.near===t.near&&this.far===t.far&&this._offCenterFrustum.equals(t._offCenterFrustum))},o}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(t,e,n,r,i,a,o,u){"use strict";function s(t,e,r,i){this.x=n(t,0),this.y=n(e,0),this.z=n(r,0),this.w=n(i,0)}var c=new t;s.fromAxisAngle=function(e,n,i){var a=n/2,o=Math.sin(a);c=t.normalize(e,c);var u=c.x*o,E=c.y*o,_=c.z*o,l=Math.cos(a);return r(i)?(i.x=u,i.y=E,i.z=_,i.w=l,i):new s(u,E,_,l)};var E=[1,2,0],_=new Array(3) +;s.fromRotationMatrix=function(t,e){var n,i,a,o,c,l=t[u.COLUMN0ROW0],f=t[u.COLUMN1ROW1],h=t[u.COLUMN2ROW2],T=l+f+h;if(T>0)n=Math.sqrt(T+1),c=.5*n,n=.5/n,i=(t[u.COLUMN1ROW2]-t[u.COLUMN2ROW1])*n,a=(t[u.COLUMN2ROW0]-t[u.COLUMN0ROW2])*n,o=(t[u.COLUMN0ROW1]-t[u.COLUMN1ROW0])*n;else{var R=E,d=0;f>l&&(d=1),h>l&&h>f&&(d=2);var A=R[d],p=R[A];n=Math.sqrt(t[u.getElementIndex(d,d)]-t[u.getElementIndex(A,A)]-t[u.getElementIndex(p,p)]+1);var m=_;m[d]=.5*n,n=.5/n,c=(t[u.getElementIndex(p,A)]-t[u.getElementIndex(A,p)])*n,m[A]=(t[u.getElementIndex(A,d)]+t[u.getElementIndex(d,A)])*n,m[p]=(t[u.getElementIndex(p,d)]+t[u.getElementIndex(d,p)])*n,i=-m[0],a=-m[1],o=-m[2]}return r(e)?(e.x=i,e.y=a,e.z=o,e.w=c,e):new s(i,a,o,c)};var l=new s,f=new s,h=new s,T=new s;s.fromHeadingPitchRoll=function(e,n){return T=s.fromAxisAngle(t.UNIT_X,e.roll,l),h=s.fromAxisAngle(t.UNIT_Y,-e.pitch,n),n=s.multiply(h,T,h),f=s.fromAxisAngle(t.UNIT_Z,-e.heading,l),s.multiply(f,n,n)};var R=new t,d=new t,A=new s,p=new s,m=new s;s.packedLength=4,s.pack=function(t,e,r){return r=n(r,0),e[r++]=t.x,e[r++]=t.y,e[r++]=t.z,e[r]=t.w,e},s.unpack=function(t,e,i){return e=n(e,0),r(i)||(i=new s),i.x=t[e],i.y=t[e+1],i.z=t[e+2],i.w=t[e+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(t,e,n,r){s.unpack(t,4*n,m),s.conjugate(m,m);for(var i=0,a=n-e+1;i<a;i++){var o=3*i;s.unpack(t,4*(e+i),A),s.multiply(A,m,A),A.w<0&&s.negate(A,A),s.computeAxis(A,R);var u=s.computeAngle(A);r[o]=R.x*u,r[o+1]=R.y*u,r[o+2]=R.z*u}},s.unpackInterpolationResult=function(e,n,i,a,o){r(o)||(o=new s),t.fromArray(e,0,d);var u=t.magnitude(d);return s.unpack(n,4*a,p),0===u?s.clone(s.IDENTITY,A):s.fromAxisAngle(d,u,A),s.multiply(A,p,o)},s.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new s(t.x,t.y,t.z,t.w)},s.conjugate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=t.w,e},s.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},s.magnitude=function(t){return Math.sqrt(s.magnitudeSquared(t))},s.normalize=function(t,e){var n=1/s.magnitude(t),r=t.x*n,i=t.y*n,a=t.z*n,o=t.w*n;return e.x=r,e.y=i,e.z=a,e.w=o,e},s.inverse=function(t,e){var n=s.magnitudeSquared(t);return e=s.conjugate(t,e),s.multiplyByScalar(e,1/n,e)},s.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},s.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},s.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},s.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},s.multiply=function(t,e,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e.x,s=e.y,c=e.z,E=e.w,_=o*u+r*E+i*c-a*s,l=o*s-r*c+i*E+a*u,f=o*c+r*s-i*u+a*E,h=o*E-r*u-i*s-a*c;return n.x=_,n.y=l,n.z=f,n.w=h,n},s.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},s.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},s.computeAxis=function(t,e){var n=t.w;if(Math.abs(n-1)<o.EPSILON6)return e.x=e.y=e.z=0,e;var r=1/Math.sqrt(1-n*n);return e.x=t.x*r,e.y=t.y*r,e.z=t.z*r,e},s.computeAngle=function(t){return Math.abs(t.w-1)<o.EPSILON6?0:2*Math.acos(t.w)};var N=new s;s.lerp=function(t,e,n,r){return N=s.multiplyByScalar(e,n,N),r=s.multiplyByScalar(t,1-n,r),s.add(N,r,r)};var y=new s,I=new s,S=new s;s.slerp=function(t,e,n,r){var i=s.dot(t,e),a=e;if(i<0&&(i=-i,a=y=s.negate(e,y)),1-i<o.EPSILON6)return s.lerp(t,a,n,r);var u=Math.acos(i);return I=s.multiplyByScalar(t,Math.sin((1-n)*u),I),S=s.multiplyByScalar(a,Math.sin(n*u),S),r=s.add(I,S,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(e,n){var r=o.acosClamped(e.w),i=0;return 0!==r&&(i=r/Math.sin(r)),t.multiplyByScalar(e,i,n)},s.exp=function(e,n){var r=t.magnitude(e),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=e.x*i,n.y=e.y*i,n.z=e.z*i,n.w=Math.cos(r),n};var O=new t,M=new t,w=new s,C=new s;s.computeInnerQuadrangle=function(e,n,r,i){var a=s.conjugate(n,w);s.multiply(a,r,C);var o=s.log(C,O);s.multiply(a,e,C);var u=s.log(C,M);return t.add(o,u,o),t.multiplyByScalar(o,.25,o),t.negate(o,o),s.exp(o,w),s.multiply(n,w,i)},s.squad=function(t,e,n,r,i,a){var o=s.slerp(t,e,i,w),u=s.slerp(n,r,i,C);return s.slerp(o,u,2*i*(1-i),a)};for(var g=new s,v=1.9011074535173003,P=i.supportsTypedArrays()?new Float32Array(8):[],L=i.supportsTypedArrays()?new Float32Array(8):[],F=i.supportsTypedArrays()?new Float32Array(8):[],x=i.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var D=U+1,B=2*D+1;P[U]=1/(D*B),L[U]=D/B}return P[7]=v/136,L[7]=8*v/17,s.fastSlerp=function(t,e,n,r){var i,a=s.dot(t,e);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,E=u*u,_=7;_>=0;--_)F[_]=(P[_]*c-L[_])*o,x[_]=(P[_]*E-L[_])*o;var l=i*n*(1+F[0]*(1+F[1]*(1+F[2]*(1+F[3]*(1+F[4]*(1+F[5]*(1+F[6]*(1+F[7])))))))),f=u*(1+x[0]*(1+x[1]*(1+x[2]*(1+x[3]*(1+x[4]*(1+x[5]*(1+x[6]*(1+x[7])))))))),h=s.multiplyByScalar(t,f,g);return s.multiplyByScalar(e,l,r),s.add(h,r,r)},s.fastSquad=function(t,e,n,r,i,a){var o=s.fastSlerp(t,e,i,w),u=s.fastSlerp(n,r,i,C);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},s.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.x-e.x)<=n&&Math.abs(t.y-e.y)<=n&&Math.abs(t.z-e.z)<=n&&Math.abs(t.w-e.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},i.unpack=function(n,r,a){return r=t(r,0),e(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(t,n){if(e(t))return e(n)||(n=new i),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},i}),define("Core/FrustumGeometry",["./BoundingSphere","./Cartesian3","./Cartesian4","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./Matrix3","./Matrix4","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion","./VertexFormat"],function(t,e,n,r,i,a,o,u,s,c,E,_,l,f,h,T,R){"use strict";function d(t){var n,r,i=t.frustum,o=t.orientation,u=t.origin,s=a(t.vertexFormat,R.DEFAULT),c=a(t._drawNearPlane,!0);i instanceof f?(n=p,r=f.packedLength):i instanceof l&&(n=m,r=l.packedLength),this._frustumType=n,this._frustum=i.clone(),this._origin=e.clone(u),this._orientation=T.clone(o),this._drawNearPlane=c,this._vertexFormat=s,this._workerName="createFrustumGeometry",this.packedLength=2+r+e.packedLength+T.packedLength+R.packedLength}function A(t,e,n,r,i,a,u,s){for(var c=t/3*2,E=0;E<4;++E)o(e)&&(e[t]=a.x,e[t+1]=a.y,e[t+2]=a.z),o(n)&&(n[t]=u.x,n[t+1]=u.y,n[t+2]=u.z),o(r)&&(r[t]=s.x,r[t+1]=s.y,r[t+2]=s.z),t+=3;i[c]=0,i[c+1]=0,i[c+2]=1,i[c+3]=0,i[c+4]=1,i[c+5]=1,i[c+6]=0,i[c+7]=1}var p=0,m=1;d.pack=function(t,n,r){r=a(r,0);var i=t._frustumType,o=t._frustum;return n[r++]=i,i===p?(f.pack(o,n,r),r+=f.packedLength):(l.pack(o,n,r),r+=l.packedLength),e.pack(t._origin,n,r),r+=e.packedLength,T.pack(t._orientation,n,r),r+=T.packedLength,R.pack(t._vertexFormat,n,r),r+=R.packedLength,n[r]=t._drawNearPlane?1:0,n};var N=new f,y=new l,I=new T,S=new e,O=new R;d.unpack=function(t,n,r){n=a(n,0);var i,u=t[n++];u===p?(i=f.unpack(t,n,N),n+=f.packedLength):(i=l.unpack(t,n,y),n+=l.packedLength);var s=e.unpack(t,n,S);n+=e.packedLength;var c=T.unpack(t,n,I);n+=T.packedLength;var E=R.unpack(t,n,O);n+=R.packedLength;var _=1===t[n];if(!o(r))return new d({frustum:i,origin:s,orientation:c,vertexFormat:E,_drawNearPlane:_});var h=u===r._frustumType?r._frustum:void 0;return r._frustum=i.clone(h),r._frustumType=u,r._origin=e.clone(s,r._origin),r._orientation=T.clone(c,r._orientation),r._vertexFormat=R.clone(E,r._vertexFormat),r._drawNearPlane=_,r};var M=new E,w=new _,C=new _,g=new e,v=new e,P=new e,L=new e,F=new e,x=new e,U=new Array(3),D=new Array(4);D[0]=new n(-1,-1,1,1),D[1]=new n(1,-1,1,1),D[2]=new n(1,1,1,1),D[3]=new n(-1,1,1,1);for(var B=new Array(4),z=0;z<4;++z)B[z]=new n;return d._computeNearFarPlanes=function(t,r,i,u,s,c,l,f){var h=E.fromQuaternion(r,M),T=a(c,g),R=a(l,v),d=a(f,P);T=E.getColumn(h,0,T),R=E.getColumn(h,1,R),d=E.getColumn(h,2,d),e.normalize(T,T),e.normalize(R,R),e.normalize(d,d),e.negate(T,T);var A,m,N=_.computeView(t,d,R,T,w);if(i===p){var y=u.projectionMatrix,I=_.multiply(y,N,C);m=_.inverse(I,C)}else A=_.inverseTransformation(N,C);o(m)?(U[0]=u.near,U[1]=u.far):(U[0]=0,U[1]=u.near,U[2]=u.far);for(var S=0;S<2;++S)for(var O=0;O<4;++O){var L=n.clone(D[O],B[O]);if(o(m)){L=_.multiplyByVector(m,L,L);var F=1/L.w;e.multiplyByScalar(L,F,L),e.subtract(L,t,L),e.normalize(L,L);var x=e.dot(d,L);e.multiplyByScalar(L,U[S]/x,L),e.add(L,t,L)}else{o(u._offCenterFrustum)&&(u=u._offCenterFrustum);var z=U[S],b=U[S+1];L.x=.5*(L.x*(u.right-u.left)+u.left+u.right),L.y=.5*(L.y*(u.top-u.bottom)+u.bottom+u.top),L.z=.5*(L.z*(z-b)-z-b),L.w=1,_.multiplyByVector(A,L,L)}s[12*S+3*O]=L.x,s[12*S+3*O+1]=L.y,s[12*S+3*O+2]=L.z}},d.createGeometry=function(n){var r=n._frustumType,a=n._frustum,E=n._origin,_=n._orientation,l=n._drawNearPlane,f=n._vertexFormat,T=l?6:5,R=new Float64Array(72);d._computeNearFarPlanes(E,_,r,a,R);var p=24;R[p]=R[12],R[p+1]=R[13],R[p+2]=R[14],R[p+3]=R[0],R[p+4]=R[1],R[p+5]=R[2],R[p+6]=R[9],R[p+7]=R[10],R[p+8]=R[11],R[p+9]=R[21],R[p+10]=R[22],R[p+11]=R[23],p+=12,R[p]=R[15],R[p+1]=R[16],R[p+2]=R[17],R[p+3]=R[3],R[p+4]=R[4],R[p+5]=R[5],R[p+6]=R[0],R[p+7]=R[1],R[p+8]=R[2],R[p+9]=R[12],R[p+10]=R[13],R[p+11]=R[14],p+=12,R[p]=R[3],R[p+1]=R[4],R[p+2]=R[5],R[p+3]=R[15],R[p+4]=R[16],R[p+5]=R[17],R[p+6]=R[18],R[p+7]=R[19],R[p+8]=R[20],R[p+9]=R[6],R[p+10]=R[7],R[p+11]=R[8],p+=12,R[p]=R[6],R[p+1]=R[7],R[p+2]=R[8],R[p+3]=R[18],R[p+4]=R[19],R[p+5]=R[20],R[p+6]=R[21],R[p+7]=R[22],R[p+8]=R[23],R[p+9]=R[9],R[p+10]=R[10],R[p+11]=R[11],l||(R=R.subarray(12));var m=new c({position:new s({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:R})});if(o(f.normal)||o(f.tangent)||o(f.bitangent)||o(f.st)){var N=o(f.normal)?new Float32Array(12*T):void 0,y=o(f.tangent)?new Float32Array(12*T):void 0,I=o(f.bitangent)?new Float32Array(12*T):void 0,S=o(f.st)?new Float32Array(8*T):void 0,O=g,M=v,w=P,C=e.negate(O,L),U=e.negate(M,F),D=e.negate(w,x);p=0,l&&(A(p,N,y,I,S,D,O,M),p+=12),A(p,N,y,I,S,w,C,M),p+=12,A(p,N,y,I,S,C,D,M),p+=12,A(p,N,y,I,S,U,D,C),p+=12,A(p,N,y,I,S,O,w,M),p+=12,A(p,N,y,I,S,M,w,C),o(N)&&(m.normal=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:N})),o(y)&&(m.tangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:y})),o(I)&&(m.bitangent=new s({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:I})),o(S)&&(m.st=new s({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:S}))}for(var B=new Uint16Array(6*T),z=0;z<T;++z){var b=6*z,G=4*z;B[b]=G,B[b+1]=G+1,B[b+2]=G+2,B[b+3]=G,B[b+4]=G+2,B[b+5]=G+3}return new u({attributes:m,indices:B,primitiveType:h.TRIANGLES,boundingSphere:t.fromVertices(R)})},d}),define("Core/FrustumOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./FrustumGeometry","./Geometry","./GeometryAttribute","./GeometryAttributes","./OrthographicFrustum","./PerspectiveFrustum","./PrimitiveType","./Quaternion"],function(t,e,n,r,i,a,o,u,s,c,E,_,l,f){"use strict";function h(t){var n,r,a=t.frustum,o=t.orientation,u=t.origin,s=i(t._drawNearPlane,!0);a instanceof _?(n=T,r=_.packedLength):a instanceof E&&(n=R,r=E.packedLength),this._frustumType=n,this._frustum=a.clone(),this._origin=e.clone(u),this._orientation=f.clone(o),this._drawNearPlane=s,this._workerName="createFrustumOutlineGeometry",this.packedLength=2+r+e.packedLength+f.packedLength}var T=0,R=1;h.pack=function(t,n,r){r=i(r,0);var a=t._frustumType,o=t._frustum;return n[r++]=a,a===T?(_.pack(o,n,r),r+=_.packedLength):(E.pack(o,n,r),r+=E.packedLength),e.pack(t._origin,n,r),r+=e.packedLength,f.pack(t._orientation,n,r),r+=f.packedLength,n[r]=t._drawNearPlane?1:0,n};var d=new _,A=new E,p=new f,m=new e;return h.unpack=function(t,n,r){n=i(n,0);var o,u=t[n++];u===T?(o=_.unpack(t,n,d),n+=_.packedLength):(o=E.unpack(t,n,A),n+=E.packedLength);var s=e.unpack(t,n,m);n+=e.packedLength;var c=f.unpack(t,n,p);n+=f.packedLength;var l=1===t[n];if(!a(r))return new h({frustum:o,origin:s,orientation:c,_drawNearPlane:l});var R=u===r._frustumType?r._frustum:void 0;return r._frustum=o.clone(R),r._frustumType=u,r._origin=e.clone(s,r._origin),r._orientation=f.clone(c,r._orientation),r._drawNearPlane=l,r},h.createGeometry=function(e){var n=e._frustumType,i=e._frustum,a=e._origin,E=e._orientation,_=e._drawNearPlane,f=new Float64Array(24);o._computeNearFarPlanes(a,E,n,i,f);for(var h,T,R=new c({position:new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:f})}),d=_?2:1,A=new Uint16Array(8*(d+1)),p=_?0:1;p<2;++p)h=_?8*p:0,T=4*p,A[h]=T,A[h+1]=T+1,A[h+2]=T+1,A[h+3]=T+2,A[h+4]=T+2,A[h+5]=T+3,A[h+6]=T+3,A[h+7]=T;for(p=0;p<2;++p)h=8*(d+p),T=4*p,A[h]=T,A[h+1]=T+4,A[h+2]=T+1,A[h+3]=T+5,A[h+4]=T+2,A[h+5]=T+6,A[h+6]=T+3,A[h+7]=T+7;return new u({attributes:R,indices:A,primitiveType:l.LINES,boundingSphere:t.fromVertices(f)})},h}),define("Workers/createFrustumOutlineGeometry",["../Core/defined","../Core/FrustumOutlineGeometry"],function(t,e){"use strict";function n(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createGeometry.js index 72f672c8..6083e890 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createGeometry.js @@ -55,8 +55,8 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,i){if(a.typeOf.number(e,n),a.typeOf.number(r,i),n!==i)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var i=Math.abs(e-r);return i<=a||i<=n*Math.max(Math.abs(e),Math.abs(r))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var r=i[t-1],n=t;n<=e;n++)i.push(r*n);return i[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(i),n},o.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var E=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)},o.cross=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-n*s,E=n*u-a*o;return r.x=c,r.y=l,r.z=E,r},o.fromDegrees=function(e,t,r,n,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,r,n,a)};var f=new o,h=new o,d=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,a,i,u){a=t(a,0);var s=r(i)?i.radiiSquared:d,c=Math.cos(n);f.x=c*Math.cos(e),f.y=c*Math.sin(e),f.z=Math.sin(n),f=o.normalize(f,f),o.multiplyComponents(s,f,h);var l=Math.sqrt(o.dot(f,h));return h=o.divideByScalar(h,l,h),f=o.multiplyByScalar(f,a,f),r(u)||(u=new o),o.add(h,f,u)},o.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,c){var l=r.x,E=r.y,f=r.z,h=a.x,d=a.y,_=a.z,p=l*l*h*h,m=E*E*d*d,T=f*f*_*_,y=p+m+T,R=Math.sqrt(1/y),A=e.multiplyByScalar(r,R,i);if(y<s)return isFinite(R)?e.clone(A,c):void 0;var v=u.x,S=u.y,N=u.z,I=o;I.x=A.x*v*2,I.y=A.y*S*2,I.z=A.z*N*2;var M,O,g,C,w,P,x,L,U,b,F,D=(1-R)*e.magnitude(r)/(.5*e.magnitude(I)),B=0;do{D-=B,g=1/(1+D*v),C=1/(1+D*S),w=1/(1+D*N),P=g*g,x=C*C,L=w*w,U=P*g,b=x*C,F=L*w,M=p*P+m*x+T*L-1,O=p*U*v+m*b*S+T*F*N;B=M/(-2*O)}while(Math.abs(M)>n.EPSILON12);return t(c)?(c.x=l*g,c.y=E*C,c.z=f*w,c):new e(l*g,E*C,f*w)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,i){return a=r(a,0),n(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,E=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,r,a){var d=n(r)?r.oneOverRadii:E,_=n(r)?r.oneOverRadiiSquared:f,p=n(r)?r._centerToleranceSquared:h,m=o(t,d,_,p,c);if(n(m)){var T=e.multiplyComponents(m,_,s);T=e.normalize(T,T);var y=e.subtract(t,m,l),R=Math.atan2(T.y,T.x),A=Math.asin(T.z),v=i.sign(e.dot(y,t))*e.magnitude(y);return n(a)?(a.longitude=R,a.latitude=A,a.height=v,a):new u(R,A,v)}},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t,r,a,i){r=n(r,0),a=n(a,0),i=n(i,0),t._radii=new e(r,a,i),t._radiiSquared=new e(r*r,a*a,i*i),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(r,a,i),t._maximumRadius=Math.max(r,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function E(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}i(E.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),E.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new E(n.x,n.y,n.z)}},E.fromCartesian3=function(e,t){return a(t)||(t=new E),a(e)?(l(t,e.x,e.y,e.z),t):t},E.WGS84=u(new E(6378137,6378137,6356752.314245179)),E.UNIT_SPHERE=u(new E(1,1,1)),E.MOON=u(new E(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),E.prototype.clone=function(e){return E.clone(this,e)},E.packedLength=e.packedLength,E.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},E.unpack=function(t,r,a){r=n(r,0);var i=e.unpack(t,r);return E.fromCartesian3(i,a)},E.prototype.geocentricSurfaceNormal=e.normalize,E.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(i);return a(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},E.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var f=new e,h=new e;E.prototype.cartographicToCartesian=function(t,r){var n=f,i=h;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,i);var o=Math.sqrt(e.dot(n,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(i,n,r)},E.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var d=new e,_=new e,p=new e;return E.prototype.cartesianToCartographic=function(r,n){var i=this.scaleToGeodeticSurface(r,_);if(a(i)){var o=this.geodeticSurfaceNormal(i,d),u=e.subtract(r,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),E=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=c,n.latitude=l,n.height=E,n):new t(c,l,E)}},E.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},E.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},E.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},E.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},E.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},E.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},E.prototype.toString=function(){return this._radii.toString()},E.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,i){r=n(r,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-r))return i},E}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,i,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a,i,o,u,s,c){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(i,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(_[r],d[r])];t+=2*n*n}return Math.sqrt(t)}function E(e,t){for(var r=u.EPSILON15,n=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(_[i],d[i])]);o>n&&(a=i,n=o)}var c=1,l=0,E=d[a],f=_[a];if(Math.abs(e[s.getElementIndex(f,E)])>r){var h,p=e[s.getElementIndex(f,f)],m=e[s.getElementIndex(E,E)],T=e[s.getElementIndex(f,E)],y=(p-m)/2/T;h=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(E,E)]=t[s.getElementIndex(f,f)]=c,t[s.getElementIndex(f,E)]=l,t[s.getElementIndex(E,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,E=e.z*e.z,f=e.z*e.w,h=e.w*e.w,d=r-u-E+h,_=2*(a-f),p=2*(i+l),m=2*(a+f),T=-r+u-E+h,y=2*(c-o),R=2*(i-l),A=2*(c+o),v=-r-u+E+h;return n(t)?(t[0]=d,t[1]=m,t[2]=R,t[3]=_,t[4]=T,t[5]=A,t[6]=p,t[7]=y,t[8]=v,t):new s(d,_,p,m,T,y,R,A,v)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*a,E=-i*u+c*o*a,f=c*u+i*o*a,h=r*u,d=i*a+c*o*u,_=-c*a+i*o*u,p=-o,m=c*r,T=i*r;return n(t)?(t[0]=l,t[1]=h,t[2]=p,t[3]=E,t[4]=d,t[5]=m,t[6]=f,t[7]=_,t[8]=T,t):new s(l,E,f,h,d,_,p,m,T)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],i=e[n+1],o=e[n+2];return r.x=a,r.y=i,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],i=e[t+6];return r.x=n,r.y=a,r.z=i,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var f=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),r};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],E=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=i,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=E,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[3]*a+e[6]*i,u=e[1]*n+e[4]*a+e[7]*i,s=e[2]*n+e[5]*a+e[8]*i;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var d=[1,0,0],_=[2,2,1],p=new s,m=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,i=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),h=r*c(f);i<10&&l(f)>h;)E(f,p),s.transpose(p,m),s.multiply(f,p,f),s.multiply(m,f,f),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*n-r*c)+u*(r*o-i*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],E=e[8],f=s.determinant(e);t[0]=o*E-l*u,t[1]=l*a-n*E,t[2]=n*u-o*a,t[3]=c*u-i*E,t[4]=r*E-c*a,t[5]=i*a-r*u,t[6]=i*l-c*o,t[7]=c*n-r*l,t[8]=r*o-i*n;var h=1/f;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}o.fromElements=function(e,t,n,a,i){return r(i)?(i.x=e,i.y=t,i.z=n,i.w=a,i):new o(e,t,n,a)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)&&i.equalsEpsilon(e.w,t.w,n,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t,r,a,i,o,u,s,c,l,E,f,h,d,_,p){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(c,0),this[3]=n(h,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(d,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(E,0),this[11]=n(_,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(p,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,i){return r=n(r,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=r.x,i[13]=r.y,i[14]=r.z,i[15]=1,i):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var i=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,E=t.x*t.z,f=t.x*t.w,h=t.y*t.y,d=t.y*t.z,_=t.y*t.w,p=t.z*t.z,m=t.z*t.w,T=t.w*t.w,y=s-h-p+T,R=2*(c-m),A=2*(E+_),v=2*(c+m),S=-s+h-p+T,N=2*(d-f),I=2*(E-_),M=2*(d+f),O=-s-h+p+T;return n[0]=y*i,n[1]=v*i,n[2]=I*i,n[3]=0,n[4]=R*o,n[5]=S*o,n[6]=M*o,n[7]=0,n[8]=A*u,n[9]=N*u,n[10]=O*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var E=new e,f=new e,h=new e;l.fromCamera=function(t,r){var n=t.position,i=t.direction,o=t.up;e.normalize(i,E),e.normalize(e.cross(E,o,f),f),e.normalize(e.cross(f,E,h),h);var u=f.x,s=f.y,c=f.z,d=E.x,_=E.y,p=E.z,m=h.x,T=h.y,y=h.z,R=n.x,A=n.y,v=n.z,S=u*-R+s*-A+c*-v,N=m*-R+T*-A+y*-v,I=d*R+_*A+p*v;return a(r)?(r[0]=u,r[1]=m,r[2]=-d,r[3]=0,r[4]=s,r[5]=T,r[6]=-_,r[7]=0,r[8]=c,r[9]=y,r[10]=-p,r[11]=0,r[12]=S,r[13]=N,r[14]=I,r[15]=1,r):new l(u,s,c,S,m,T,y,N,-d,-_,-p,I,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,i,o){var u=1/(t-e),s=1/(n-r),c=1/(i-a),l=-(t+e)*u,E=-(n+r)*s,f=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=E,o[14]=f,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,a,i,o){var u=2*a/(t-e),s=2*a/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),E=-(i+a)/(i-a),f=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=E,o[11]=-1,o[12]=0,o[13]=0,o[14]=f,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,i){var o=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var i=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,E=.5*(r-t),f=c,h=l,d=E,_=i+c,p=o+l,m=t+E;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=d,a[11]=0,a[12]=_,a[13]=p,a[14]=m,a[15]=1,a},l.computeView=function(t,r,n,a,i){return i[0]=a.x,i[1]=n.x,i[2]=-r.x,i[3]=0,i[4]=a.y,i[5]=n.y,i[6]=-r.y,i[7]=0,i[8]=a.z,i[9]=n.z,i[10]=-r.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(n,t),i[14]=e.dot(r,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],i=e[n+1],o=e[n+2],u=e[n+3];return r.x=a,r.y=i,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return r.x=n,r.y=a,r.z=i,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var d=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],d)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],d)),r};var _=new e;l.getMaximumScale=function(t){return l.getScale(t,_),e.maximumComponent(_)},l.multiply=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],E=e[8],f=e[9],h=e[10],d=e[11],_=e[12],p=e[13],m=e[14],T=e[15],y=t[0],R=t[1],A=t[2],v=t[3],S=t[4],N=t[5],I=t[6],M=t[7],O=t[8],g=t[9],C=t[10],w=t[11],P=t[12],x=t[13],L=t[14],U=t[15],b=n*y+u*R+E*A+_*v,F=a*y+s*R+f*A+p*v,D=i*y+c*R+h*A+m*v,B=o*y+l*R+d*A+T*v,z=n*S+u*N+E*I+_*M,G=a*S+s*N+f*I+p*M,V=i*S+c*N+h*I+m*M,q=o*S+l*N+d*I+T*M,X=n*O+u*g+E*C+_*w,H=a*O+s*g+f*C+p*w,W=i*O+c*g+h*C+m*w,k=o*O+l*g+d*C+T*w,Y=n*P+u*x+E*L+_*U,Z=a*P+s*x+f*L+p*U,K=i*P+c*x+h*L+m*U,j=o*P+l*x+d*L+T*U;return r[0]=b,r[1]=F,r[2]=D,r[3]=B,r[4]=z,r[5]=G,r[6]=V,r[7]=q,r[8]=X,r[9]=H,r[10]=W,r[11]=k,r[12]=Y,r[13]=Z,r[14]=K,r[15]=j,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=e[12],h=e[13],d=e[14],_=t[0],p=t[1],m=t[2],T=t[4],y=t[5],R=t[6],A=t[8],v=t[9],S=t[10],N=t[12],I=t[13],M=t[14],O=n*_+o*p+c*m,g=a*_+u*p+l*m,C=i*_+s*p+E*m,w=n*T+o*y+c*R,P=a*T+u*y+l*R,x=i*T+s*y+E*R,L=n*A+o*v+c*S,U=a*A+u*v+l*S,b=i*A+s*v+E*S,F=n*N+o*I+c*M+f,D=a*N+u*I+l*M+h,B=i*N+s*I+E*M+d;return r[0]=O,r[1]=g,r[2]=C,r[3]=0,r[4]=w,r[5]=P,r[6]=x,r[7]=0,r[8]=L,r[9]=U,r[10]=b,r[11]=0,r[12]=F,r[13]=D,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=t[0],h=t[1],d=t[2],_=t[3],p=t[4],m=t[5],T=t[6],y=t[7],R=t[8],A=n*f+o*h+c*d,v=a*f+u*h+l*d,S=i*f+s*h+E*d,N=n*_+o*p+c*m,I=a*_+u*p+l*m,M=i*_+s*p+E*m,O=n*T+o*y+c*R,g=a*T+u*y+l*R,C=i*T+s*y+E*R;return r[0]=A,r[1]=v,r[2]=S,r[3]=0,r[4]=N,r[5]=I,r[6]=M,r[7]=0,r[8]=O,r[9]=g,r[10]=C,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=n*e[0]+a*e[4]+i*e[8]+e[12],u=n*e[1]+a*e[5]+i*e[9]+e[13],s=n*e[2]+a*e[6]+i*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var p=new e;l.multiplyByUniformScale=function(e,t,r){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,i=t.z;return 1===n&&1===a&&1===i?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=i*e[8],r[9]=i*e[9],r[10]=i*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*n+e[4]*a+e[8]*i+e[12]*o,s=e[1]*n+e[5]*a+e[9]*i+e[13]*o,c=e[2]*n+e[6]*a+e[10]*i+e[14]*o,l=e[3]*n+e[7]*a+e[11]*i+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i,u=e[1]*n+e[5]*a+e[9]*i,s=e[2]*n+e[6]*a+e[10]*i;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i+e[12],u=e[1]*n+e[5]*a+e[9]*i+e[13],s=e[2]*n+e[6]*a+e[10]*i+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var m=new s,T=new s,y=new t,R=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,m),T,u.EPSILON7)&&t.equals(l.getRow(e,3,y),R))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],i=e[8],o=e[12],E=e[1],f=e[5],h=e[9],d=e[13],_=e[2],p=e[6],A=e[10],v=e[14],S=e[3],N=e[7],I=e[11],M=e[15],O=A*M,g=v*I,C=p*M,w=v*N,P=p*I,x=A*N,L=_*M,U=v*S,b=_*I,F=A*S,D=_*N,B=p*S,z=O*f+w*h+P*d-(g*f+C*h+x*d),G=g*E+L*h+F*d-(O*E+U*h+b*d),V=C*E+U*f+D*d-(w*E+L*f+B*d),q=x*E+b*f+B*h-(P*E+F*f+D*h),X=g*a+C*i+x*o-(O*a+w*i+P*o),H=O*n+U*i+b*o-(g*n+L*i+F*o),W=w*n+L*a+B*o-(C*n+U*a+D*o),k=P*n+F*a+D*i-(x*n+b*a+B*i);O=i*d,g=o*h,C=a*d,w=o*f,P=a*h,x=i*f,L=n*d,U=o*E,b=n*h,F=i*E,D=n*f,B=a*E;var Y=O*N+w*I+P*M-(g*N+C*I+x*M),Z=g*S+L*I+F*M-(O*S+U*I+b*M),K=C*S+U*N+D*M-(w*S+L*N+B*M),j=x*S+b*N+B*I-(P*S+F*N+D*I),Q=C*A+x*v+g*p-(P*v+O*p+w*A),J=b*v+O*_+U*A-(L*A+F*v+g*_),$=L*p+B*v+w*_-(D*v+C*_+U*p),ee=D*A+P*_+F*p-(b*p+B*A+x*_),te=n*z+a*G+i*V+o*q;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=G*te,r[2]=V*te,r[3]=q*te,r[4]=X*te,r[5]=H*te,r[6]=W*te,r[7]=k*te,r[8]=Y*te,r[9]=Z*te,r[10]=K*te,r[11]=j*te,r[12]=Q*te,r[13]=J*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],E=e[12],f=e[13],h=e[14],d=-r*E-n*f-a*h,_=-i*E-o*f-u*h,p=-s*E-c*f-l*h;return t[0]=r,t[1]=i,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=d,t[13]=_,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),i=u.toRadians(r(i,0)),n(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(a,0),o.north=r(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,E=0,f=e.length;E<f;E++){var h=e[E];r=Math.min(r,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,d),o=Math.max(o,d)}return a-r>o-i&&(r=i,a=o,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=a,t.north=l,t):new s(r,c,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,E=-Number.MAX_VALUE,f=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0,_=e.length;d<_;d++){var p=t.cartesianToCartographic(e[d]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),f=Math.min(f,p.latitude),h=Math.max(h,p.latitude);var m=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,m),E=Math.max(E,m)}return c-o>E-l&&(o=l,c=E,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(a)?(a.west=o,a.south=f,a.east=c,a.north=h,a):new s(o,f,c,h)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),E=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&E<=l)){var f=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(f>=h))return n(r)?(r.west=l,r.south=f,r.east=E,r.north=h,r):new s(l,f,E,h)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return n(r)?(r.west=a,r.south=i,r.east=o,r.north=u,r):new s(a,i,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),E=u.convertLongitudeRange(Math.max(a,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=E,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<i||u.equalsEpsilon(r,i,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=r(t,i.WGS84),a=r(a,0),n(o)||(o=[]);var l=0,E=e.north,f=e.south,h=e.east,d=e.west,_=c;_.height=a,_.longitude=d,_.latitude=E,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.longitude=h,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.latitude=f,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.longitude=d,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.latitude=E<0?E:f>0?f:0;for(var p=1;p<8;++p)_.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,_)&&(o[l]=t.cartographicToCartesian(_,o[l]),l++);return 0===_.latitude&&(_.longitude=d,o[l]=t.cartographicToCartesian(_,o[l]),l++,_.longitude=h,o[l]=t.cartographicToCartesian(_,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,i,o,u,s,c,l,E){"use strict";function f(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var h=new e,d=new e,_=new e,p=new e,m=new e,T=new e,y=new e,R=new e,A=new e,v=new e,S=new e,N=new e;f.fromPoints=function(t,r){if(a(r)||(r=new f),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],y),o=e.clone(i,h),u=e.clone(i,d),s=e.clone(i,_),c=e.clone(i,p),l=e.clone(i,m),E=e.clone(i,T),I=t.length;for(n=1;n<I;n++){e.clone(t[n],i);var M=i.x,O=i.y,g=i.z;M<o.x&&e.clone(i,o),M>c.x&&e.clone(i,c),O<u.y&&e.clone(i,u),O>l.y&&e.clone(i,l),g<s.z&&e.clone(i,s),g>E.z&&e.clone(i,E)}var C=e.magnitudeSquared(e.subtract(c,o,R)),w=e.magnitudeSquared(e.subtract(l,u,R)),P=e.magnitudeSquared(e.subtract(E,s,R)),x=o,L=c,U=C;w>U&&(U=w,x=u,L=l),P>U&&(U=P,x=s,L=E);var b=A;b.x=.5*(x.x+L.x),b.y=.5*(x.y+L.y),b.z=.5*(x.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,R)),D=Math.sqrt(F),B=v;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=E.z;var G=e.multiplyByScalar(e.add(B,z,R),.5,N),V=0;for(n=0;n<I;n++){e.clone(t[n],i);var q=e.magnitude(e.subtract(i,G,R));q>V&&(V=q);var X=e.magnitudeSquared(e.subtract(i,b,R));if(X>F){var H=Math.sqrt(X);D=.5*(D+H),F=D*D;var W=H-D;b.x=(D*b.x+W*i.x)/H,b.y=(D*b.y+W*i.y)/H,b.z=(D*b.z+W*i.z)/H}}return D<V?(e.clone(b,r.center),r.radius=D):(e.clone(G,r.center),r.radius=V),r};var I=new o,M=new e,O=new e,g=new t,C=new t;f.fromRectangle2D=function(e,t,r){return f.fromRectangleWithHeights2D(e,t,0,0,r)},f.fromRectangleWithHeights2D=function(t,r,i,o,u){if(a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=n(r,I),E.southwest(t,g),g.height=i,E.northeast(t,C),C.height=o;var s=r.project(g,M),c=r.project(C,O),l=c.x-s.x,h=c.y-s.y,d=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+d*d);var _=u.center;return _.x=s.x+.5*l,_.y=s.y+.5*h,_.z=s.z+.5*d,u};var w=[];f.fromRectangle3D=function(t,r,o,u){if(r=n(r,i.WGS84),o=n(o,0),a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=E.subsample(t,r,o,w);return f.fromPoints(s,u)},f.fromVertices=function(t,r,i,o){if(a(o)||(o=new f),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=n(r,e.ZERO),i=n(i,3);var u=y;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,h),l=e.clone(u,d),E=e.clone(u,_),I=e.clone(u,p),M=e.clone(u,m),O=e.clone(u,T),g=t.length;for(s=0;s<g;s+=i){var C=t[s]+r.x,w=t[s+1]+r.y,P=t[s+2]+r.z;u.x=C,u.y=w,u.z=P,C<c.x&&e.clone(u,c),C>I.x&&e.clone(u,I),w<l.y&&e.clone(u,l),w>M.y&&e.clone(u,M),P<E.z&&e.clone(u,E),P>O.z&&e.clone(u,O)}var x=e.magnitudeSquared(e.subtract(I,c,R)),L=e.magnitudeSquared(e.subtract(M,l,R)),U=e.magnitudeSquared(e.subtract(O,E,R)),b=c,F=I,D=x;L>D&&(D=L,b=l,F=M),U>D&&(D=U,b=E,F=O);var B=A;B.x=.5*(b.x+F.x),B.y=.5*(b.y+F.y),B.z=.5*(b.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,R)),G=Math.sqrt(z),V=v;V.x=c.x,V.y=l.y,V.z=E.z;var q=S;q.x=I.x,q.y=M.y,q.z=O.z;var X=e.multiplyByScalar(e.add(V,q,R),.5,N),H=0;for(s=0;s<g;s+=i){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var W=e.magnitude(e.subtract(u,X,R));W>H&&(H=W);var k=e.magnitudeSquared(e.subtract(u,B,R));if(k>z){var Y=Math.sqrt(k);G=.5*(G+Y),z=G*G;var Z=Y-G;B.x=(G*B.x+Z*u.x)/Y,B.y=(G*B.y+Z*u.y)/Y,B.z=(G*B.z+Z*u.z)/Y}}return G<H?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=H),o},f.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new f),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=y;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,h),s=e.clone(i,d),c=e.clone(i,_),l=e.clone(i,p),E=e.clone(i,m),I=e.clone(i,T),M=t.length;for(o=0;o<M;o+=3){var O=t[o]+r[o],g=t[o+1]+r[o+1],C=t[o+2]+r[o+2];i.x=O,i.y=g,i.z=C,O<u.x&&e.clone(i,u),O>l.x&&e.clone(i,l),g<s.y&&e.clone(i,s),g>E.y&&e.clone(i,E),C<c.z&&e.clone(i,c),C>I.z&&e.clone(i,I)}var w=e.magnitudeSquared(e.subtract(l,u,R)),P=e.magnitudeSquared(e.subtract(E,s,R)),x=e.magnitudeSquared(e.subtract(I,c,R)),L=u,U=l,b=w;P>b&&(b=P,L=s,U=E),x>b&&(b=x,L=c,U=I);var F=A;F.x=.5*(L.x+U.x),F.y=.5*(L.y+U.y),F.z=.5*(L.z+U.z);var D=e.magnitudeSquared(e.subtract(U,F,R)),B=Math.sqrt(D),z=v;z.x=u.x,z.y=s.y,z.z=c.z;var G=S;G.x=l.x,G.y=E.y,G.z=I.z;var V=e.multiplyByScalar(e.add(z,G,R),.5,N),q=0;for(o=0;o<M;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(i,V,R));X>q&&(q=X);var H=e.magnitudeSquared(e.subtract(i,F,R));if(H>D){var W=Math.sqrt(H);B=.5*(B+W),D=B*B;var k=W-B;F.x=(B*F.x+k*i.x)/W,F.y=(B*F.y+k*i.y)/W,F.z=(B*F.z+k*i.z)/W}}return B<q?(e.clone(F,n.center),n.radius=B):(e.clone(V,n.center),n.radius=q),n},f.fromCornerPoints=function(t,r,n){a(n)||(n=new f);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},f.fromEllipsoid=function(t,r){return a(r)||(r=new f),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var P=new e;f.fromBoundingSpheres=function(t,r){if(a(r)||(r=new f),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return f.clone(t[0],r);if(2===n)return f.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=f.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,P)+c.radius)}return r.radius=s,r};var x=new e,L=new e,U=new e;f.fromOrientedBoundingBox=function(t,r){a(r)||(r=new f);var n=t.halfAxes,i=c.getColumn(n,0,x),o=c.getColumn(n,1,L),u=c.getColumn(n,2,U);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},f.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new f(t.center,t.radius)},f.packedLength=4,f.pack=function(e,t,r){r=n(r,0);var a=e.center;return t[r++]=a.x,t[r++]=a.y,t[r++]=a.z,t[r]=e.radius,t},f.unpack=function(e,t,r){t=n(t,0),a(r)||(r=new f);var i=r.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],r.radius=e[t],r};var b=new e,F=new e;f.union=function(t,r,n){a(n)||(n=new f);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,b),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var E=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+E)/l,F);return e.add(h,i,h),e.clone(h,n.center),n.radius=E,n};var D=new e;f.expand=function(t,r,n){n=f.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,D));return a>n.radius&&(n.radius=a),n},f.intersectPlane=function(t,r){var n=t.center,a=t.radius,i=r.normal,o=e.dot(i,n)+r.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},f.transform=function(e,t,r){return a(r)||(r=new f),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=l.getMaximumScale(t)*e.radius,r};var B=new e;f.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,B);return e.magnitudeSquared(n)-t.radius*t.radius},f.transformWithoutScale=function(e,t,r){return a(r)||(r=new f),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var z=new e;f.computePlaneDistances=function(t,r,n,i){a(i)||(i=new s);var o=e.subtract(t.center,r,z),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var G=new e,V=new e,q=new e,X=new e,H=new e,W=new t,k=new Array(8),Y=0;Y<8;++Y)k[Y]=new e;var Z=new o;return f.projectTo2D=function(t,r,a){r=n(r,Z);var i=r.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,G),c=e.cross(e.UNIT_Z,s,V);e.normalize(c,c);var l=e.cross(s,c,q);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var E=e.negate(l,H),h=e.negate(c,X),d=k,_=d[0];e.add(s,l,_),e.add(_,c,_),_=d[1],e.add(s,l,_),e.add(_,h,_),_=d[2],e.add(s,E,_),e.add(_,h,_),_=d[3],e.add(s,E,_),e.add(_,c,_),e.negate(s,s),_=d[4],e.add(s,l,_),e.add(_,c,_),_=d[5],e.add(s,l,_),e.add(_,h,_),_=d[6],e.add(s,E,_),e.add(_,h,_),_=d[7],e.add(s,E,_),e.add(_,c,_);for(var p=d.length,m=0;m<p;++m){var T=d[m];e.add(o,T,T);var y=i.cartesianToCartographic(T,W);r.project(y,T)}a=f.fromPoints(d,a),o=a.center;var R=o.x,A=o.y,v=o.z;return o.x=v,o.y=R,o.z=A,a},f.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},f.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},f.prototype.intersectPlane=function(e){return f.intersectPlane(this,e)},f.prototype.distanceSquaredTo=function(e){return f.distanceSquaredTo(this,e)},f.prototype.computePlaneDistances=function(e,t,r){return f.computePlaneDistances(this,e,t,r)},f.prototype.isOccluded=function(e){return f.isOccluded(this,e)},f.prototype.equals=function(e){return f.equals(this,e)},f.prototype.clone=function(e){return f.clone(this,e)},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(A)&&(A=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,v=n(e[1]))}return A}function i(){return a()&&v}function o(){if(!t(S)&&(S=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=n(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(I)){I=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(I=!0,M=n(e[1]),M.isNightly=!!e[2])}return I}function c(){return s()&&M}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0, -g=n(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,g=n(e[1]))}return O}function E(){return l()&&g}function f(){if(!t(C)){C=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,w=n(e[1]))}return C}function h(){return f()&&w}function d(){if(!t(P)){P=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(P=!0,x=n(e[1]))}return P}function _(){return t(L)||(L=/Windows/i.test(R.appVersion)),L}function p(){return d()&&x}function m(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),U}function T(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;F=t(r)&&""!==r,F&&(b=r)}return F}function y(){return T()?b:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,v,S,N,I,M,O,g,C,w,P,x,L,U,b,F,D={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:E,isEdge:f,edgeVersion:h,isFirefox:d,firefoxVersion:p,isWindows:_,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:m,supportsImageRenderingPixelated:T,imageRenderingValue:y};return D.supportsFullscreen=function(){return r.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,i){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,a);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case o.SHORT:return new Int16Array(r,n,a);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case o.INT:return new Int32Array(r,n,a);case o.UNSIGNED_INT:return new Uint32Array(r,n,a);case o.FLOAT:return new Float32Array(r,n,a);case o.DOUBLE:return new Float64Array(r,n,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var a=0;a<n;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var a=0;a<n;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var E=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,r,n,a){"use strict";var i={};i.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,r){return i.octDecodeInRange(e,t,255,r)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),a=256*(r-n);return i.octDecode(n,a,t)},i.octPack=function(e,t,r,n){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(r,o);return n.x=65536*s.x+a,n.y=65536*s.y+u,n},i.octUnpack=function(e,t,r,n){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,r),i.octDecode(o,s,n)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},i}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function a(r,a,s,c,l){n(l)||(l=new t);var E,f,h,d,_,p,m,T;n(a.z)?(E=t.subtract(s,a,i),f=t.subtract(c,a,o),h=t.subtract(r,a,u),d=t.dot(E,E),_=t.dot(E,f),p=t.dot(E,h),m=t.dot(f,f),T=t.dot(f,h)):(E=e.subtract(s,a,i),f=e.subtract(c,a,o),h=e.subtract(r,a,u),d=e.dot(E,E),_=e.dot(E,f),p=e.dot(E,h),m=e.dot(f,f),T=e.dot(f,h));var y=1/(d*m-_*_);return l.y=(m*p-_*T)*y,l.z=(d*T-_*p)*y,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var a={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var i=t.high,o=t.low;return n.encode(e.x,a),i.x=a.high,o.x=a.low,n.encode(e.y,a),i.y=a.high,o.y=a.low,n.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,i);var a=i.high,o=i.low;t[r]=a.x,t[r+1]=a.y,t[r+2]=a.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var i;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-n/e,i<0?[i,0]:[0,i];var c=n*n,l=4*e*a,E=r(c,-l,t.EPSILON14);if(E<0)return[];var f=-.5*r(n,t.sign(n)*Math.sqrt(E),t.EPSILON14);return n>0?[f/e,a/f]:[a/f,f/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,i,o=e,u=t/3,s=r/3,c=n,l=o*s,E=u*c,f=u*u,h=s*s,d=o*s-f,_=o*c-u*s,p=u*c-h,m=4*d*p-_*_;if(m<0){var T,y,R;f*E>=l*h?(T=o,y=d,R=-2*u*d+o*_):(T=c,y=p,R=-c*_+2*s*p);var A=R<0?-1:1,v=-A*Math.abs(T)*Math.sqrt(-m);i=-R+v;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),I=i===v?-N:-y/N;return a=y<=0?N+I:-R/(N*N+I*I+y),f*E>=l*h?[(a-u)/o]:[-c/(a+s)]}var M=d,O=-2*u*d+o*_,g=p,C=-c*_+2*s*p,w=Math.sqrt(m),P=Math.sqrt(3)/2,x=Math.abs(Math.atan2(o*w,-O)/3);a=2*Math.sqrt(-M);var L=Math.cos(x);i=a*L;var U=a*(-L/2-P*Math.sin(x)),b=i+U>2*u?i-u:U-u,F=o,D=b/F;x=Math.abs(Math.atan2(c*w,-C)/3),a=2*Math.sqrt(-g),L=Math.cos(x),i=a*L,U=a*(-L/2-P*Math.sin(x));var B=-c,z=i+U<2*s?i+s:U+s,G=B/z,V=F*z,q=-b*z-F*B,X=b*B,H=(s*q-u*X)/(-u*q+s*V);return D<=H?D<=G?H<=G?[D,H,G]:[D,G,H]:[G,D,H]:D<=G?[H,D,G]:H<=G?[H,G,D]:[G,H,D]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,i=t*t,o=r*r;return 18*e*t*r*n+i*o-27*a*(n*n)-4*(e*o*r+i*t*n)},n.computeRealRoots=function(e,n,a,i){var o,u;if(0===e)return t.computeRealRoots(n,a,i);if(0===n){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,a,i)}return 0===a?0===i?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,i):0===i?(o=t.computeRealRoots(e,n,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,a,i)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,E=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(E.length>0){var f=-t/4,h=E[E.length-1];if(Math.abs(h)<r.EPSILON14){var d=n.computeRealRoots(1,s,l);if(2===d.length){var _,p=d[0],m=d[1];if(p>=0&&m>=0){var T=Math.sqrt(p),y=Math.sqrt(m);return[f-y,f-T,f+T,f+y]}if(p>=0&&m<0)return _=Math.sqrt(p),[f-_,f+_];if(p<0&&m>=0)return _=Math.sqrt(m),[f-_,f+_]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,v=(s+h+c/R)/2,S=n.computeRealRoots(1,R,A),N=n.computeRealRoots(1,-R,v);return 0!==S.length?(S[0]+=f,S[1]+=f,0!==N.length?(N[0]+=f,N[1]+=f,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=f,N[1]+=f,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,E=i*t+s-4*o,f=c*o-i*a*t+u,h=e.computeRealRoots(1,l,E,f);if(h.length>0){var d,_,p=h[0],m=a-p,T=m*m,y=t/2,R=m/2,A=T-4*o,v=T+4*Math.abs(o),S=c-4*p,N=c+4*Math.abs(p);if(p<0||A*N<S*v){var I=Math.sqrt(S);d=I/2,_=0===I?0:(t*R-i)/I}else{var M=Math.sqrt(A);d=0===M?0:(t*R-i)/M,_=M/2}var O,g;0===y&&0===d?(O=0,g=0):r.sign(y)===r.sign(d)?(O=y+d,g=p/O):(g=y-d,O=p/g);var C,w;0===R&&0===_?(C=0,w=0):r.sign(R)===r.sign(_)?(C=R+_,w=o/C):(w=R-_,C=o/w);var P=n.computeRealRoots(1,O,C),x=n.computeRealRoots(1,g,w);if(0!==P.length)return 0!==x.length?P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>x[0]&&P[0]<x[1]?[x[0],P[0],x[1],P[1]]:[P[0],x[0],P[1],x[1]]:P;if(0!==x.length)return x}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=r*r,l=c*r,E=n*n,f=E*n,h=a*a;return u*c*E-4*s*f-4*e*l*E+18*e*t*r*f-27*i*E*E+256*o*(h*a)+a*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*E+144*i*r*E)+h*(144*e*u*r-27*u*u-128*i*c-192*i*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,E=u/t,f=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=E<0?h+1:h,h+=f<0?h+1:h){case 0:return a(c,l,E,f);case 1:case 2:return i(c,l,E,f);case 3:case 4:return a(c,l,E,f);case 5:return i(c,l,E,f);case 6:case 7:return a(c,l,E,f);case 8:return i(c,l,E,f);case 9:case 10:return a(c,l,E,f);case 11:return i(c,l,E,f);case 12:case 13:case 14:case 15:return a(c,l,E,f);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,i,o,u,s,c,l){"use strict";function E(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function f(t,r,a){n(a)||(a=new i);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,T),f=e.dot(u,u),h=2*e.dot(u,l),d=e.magnitudeSquared(l)-c,_=E(f,h,d,v);if(n(_))return a.start=_.root0,a.stop=_.root1,a}function h(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function d(t,r,n,a,i){ -var l,E=a*a,f=i*i,d=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,_=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),p=t[u.COLUMN0ROW0]*E+t[u.COLUMN2ROW2]*f+a*r.x+n,m=f*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),T=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),y=[];if(0===T&&0===m){if(l=s.computeRealRoots(d,_,p),0===l.length)return y;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(y.push(new e(a,i*R,i*-A)),y.push(new e(a,i*R,i*A)),2===l.length){var v=l[1],S=Math.sqrt(Math.max(1-v*v,0));y.push(new e(a,i*v,i*-S)),y.push(new e(a,i*v,i*S))}return y}var N=T*T,I=m*m,M=d*d,O=T*m,g=M+I,C=2*(_*d+O),w=2*p*d+_*_-I+N,P=2*(p*_-O),x=p*p-N;if(0===g&&0===C&&0===w&&0===P)return y;l=c.computeRealRoots(g,C,w,P,x);var L=l.length;if(0===L)return y;for(var U=0;U<L;++U){var b,F=l[U],D=F*F,B=Math.max(1-D,0),z=Math.sqrt(B);b=o.sign(d)===o.sign(p)?h(d*D+p,_*F,o.EPSILON12):o.sign(p)===o.sign(_*F)?h(d*D,_*F+p,o.EPSILON12):h(d*D+_*F,p,o.EPSILON12);var G=h(m*F,T,o.EPSILON15),V=b*G;V<0?y.push(new e(a,i*F,i*z)):V>0?y.push(new e(a,i*F,i*-z)):0!==z?(y.push(new e(a,i*F,i*-z)),y.push(new e(a,i*F,i*z)),++U):y.push(new e(a,i*F,i*z))}return y}var _={};_.rayPlane=function(t,r,a){n(a)||(a=new e);var i=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,m=new e,T=new e,y=new e,R=new e;_.rayTriangleParametric=function(t,n,a,i,u){u=r(u,!1);var s,c,l,E,f,h=t.origin,d=t.direction,_=e.subtract(a,n,p),A=e.subtract(i,n,m),v=e.cross(d,A,T),S=e.dot(_,v);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,n,y),(l=e.dot(s,v))<0||l>S)return;if(c=e.cross(s,_,R),(E=e.dot(d,c))<0||l+E>S)return;f=e.dot(A,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,n,y),(l=e.dot(s,v)*N)<0||l>1)return;if(c=e.cross(s,_,R),(E=e.dot(d,c)*N)<0||l+E>1)return;f=e.dot(A,c)*N}return f},_.rayTriangle=function(t,r,a,i,o,u){var s=_.rayTriangleParametric(t,r,a,i,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;_.lineSegmentTriangle=function(t,r,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=_.rayTriangleParametric(c,a,i,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var v={root0:0,root1:0};_.raySphere=function(e,t,r){if(r=f(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;_.lineSegmentSphere=function(t,r,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=f(o,a,i),!(!n(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,I=new e;_.rayEllipsoid=function(t,r){var n,a,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),E=e.multiplyComponents(c,t.direction,I),f=e.magnitudeSquared(l),h=e.dot(l,E);if(f>1){if(h>=0)return;var d=h*h;if(n=f-1,a=e.magnitudeSquared(E),o=a*n,d<o)return;if(d>o){u=h*h-o,s=-h+Math.sqrt(u);var _=s/a,p=n/s;return _<p?new i(_,p):{start:p,stop:_}}var m=Math.sqrt(n/a);return new i(m,m)}return f<1?(n=f-1,a=e.magnitudeSquared(E),o=a*n,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(E),new i(0,-h/a)):void 0};var M=new e,O=new e,g=new e,C=new e,w=new e,P=new u,x=new u,L=new u,U=new u,b=new u,F=new u,D=new u,B=new e,z=new e,G=new t;_.grazingAltitudeLocation=function(t,r){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,M);if(e.dot(i,s)>=0)return a}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(i,M),E=e.normalize(l,l),f=e.mostOrthogonalAxis(l,C),h=e.normalize(e.cross(f,E,O),O),_=e.normalize(e.cross(E,h,g),g),p=P;p[0]=E.x,p[1]=E.y,p[2]=E.z,p[3]=h.x,p[4]=h.y,p[5]=h.z,p[6]=_.x,p[7]=_.y,p[8]=_.z;var m=u.transpose(p,x),T=u.fromScale(r.radii,L),y=u.fromScale(r.oneOverRadii,U),R=b;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,v,S=u.multiply(u.multiply(m,y,F),R,F),N=u.multiply(u.multiply(S,T,D),p,D),I=u.multiplyByVector(S,a,w),V=d(N,e.negate(I,M),0,0,1),q=V.length;if(q>0){for(var X=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,W=0;W<q;++W){A=u.multiplyByVector(T,u.multiplyByVector(p,V[W],B),B);var k=e.normalize(e.subtract(A,a,C),C),Y=e.dot(k,i);Y>H&&(H=Y,X=e.clone(A,X))}var Z=r.cartesianToCartographic(X,G);return H=o.clamp(H,0,1),v=e.magnitude(e.subtract(X,a,C))*Math.sqrt(1-H*H),v=c?-v:v,Z.height=v,r.cartographicToCartesian(Z,new e)}};var V=new e;return _.lineSegmentPlane=function(t,r,a,i){n(i)||(i=new e);var u=e.subtract(r,t,V),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),E=-(a.distance+l)/c;if(!(E<0||E>1))return e.multiplyByScalar(u,E,i),e.add(t,i,i),i}},_.trianglePlaneIntersection=function(t,r,n,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,r)+o<0,c=e.dot(i,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var E,f;if(1!==l&&2!==l||(E=new e,f=new e),1===l){if(u)return _.lineSegmentPlane(t,r,a,E),_.lineSegmentPlane(t,n,a,f),{positions:[t,r,n,E,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return _.lineSegmentPlane(r,n,a,E),_.lineSegmentPlane(r,t,a,f),{positions:[t,r,n,E,f],indices:[1,3,4,2,0,4,2,4,3]};if(c)return _.lineSegmentPlane(n,t,a,E),_.lineSegmentPlane(n,r,a,f),{positions:[t,r,n,E,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return _.lineSegmentPlane(r,t,a,E),_.lineSegmentPlane(n,t,a,f),{positions:[t,r,n,E,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return _.lineSegmentPlane(n,r,a,E),_.lineSegmentPlane(t,r,a,f),{positions:[t,r,n,E,f],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return _.lineSegmentPlane(t,n,a,E),_.lineSegmentPlane(r,n,a,f),{positions:[t,r,n,E,f],indices:[0,1,4,0,4,3,2,3,4]}}},_}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,i,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var i=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=i,a):new u(n,i)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),i=t.w;return r(n)?(e.clone(a,n.normal),n.distance=i,n):new u(a,i)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(r,c,c),u.fromPointNormal(c,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,a=r.maximumIndex,i=e(r.cacheSize,24),o=n.length;if(!t(a)){a=0;for(var u=0,s=n[u];u<o;)s>a&&(a=s),++u,s=n[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var E=i+1,f=0;f<o;++f)E-c[n[f]]>i&&(c[n[f]]=E,++E);return(E-i+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<n;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}r=e(r,e.EMPTY_OBJECT);var a,i=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=i.length,c=0,l=0,E=i[l],f=s;if(t(o))c=o+1;else{for(;l<f;)E>c&&(c=E),++l,E=i[l];if(-1===c)return 0;++c}var h,d=[];for(h=0;h<c;h++)d[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var _=0;l<f;)d[i[l]].vertexTriangles.push(_),++d[i[l]].numLiveTriangles,d[i[l+1]].vertexTriangles.push(_),++d[i[l+1]].numLiveTriangles,d[i[l+2]].vertexTriangles.push(_),++d[i[l+2]].numLiveTriangles,++_,l+=3;var p=0,m=u+1;a=1;var T,y,R=[],A=[],v=0,S=[],N=s/3,I=[];for(h=0;h<N;h++)I[h]=!1;for(var M,O;-1!==p;){R=[],y=d[p],O=y.vertexTriangles.length;for(var g=0;g<O;++g)if(_=y.vertexTriangles[g],!I[_]){I[_]=!0,l=_+_+_;for(var C=0;C<3;++C)M=i[l],R.push(M),A.push(M),S[v]=M,++v,T=d[M],--T.numLiveTriangles,m-T.timeStamp>u&&(T.timeStamp=m,++m),++l}p=function(e,t,r,a,i,o,u){for(var s,c=-1,l=-1,E=0;E<r.length;){var f=r[E];a[f].numLiveTriangles&&(s=0,i-a[f].timeStamp+2*a[f].numLiveTriangles<=t&&(s=i-a[f].timeStamp),(s>l||-1===l)&&(l=s,c=f)),++E}return-1===c?n(a,o,e,u):c}(i,u,R,d,m,A,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h,d,_,p,m,T,y,R,A,v,S,N){"use strict";function I(e,t,r,n,a){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=a,e[t++]=a,e[t]=r}function M(e){for(var t=e.length,r=t/3*6,n=p.createTypedArray(t,r),a=0,i=0;i<t;i+=3,a+=6)I(n,a,e[i],e[i+1],e[i+2]);return n}function O(e){var t=e.length;if(t>=3){var r=6*(t-2),n=p.createTypedArray(t,r);I(n,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)I(n,a,e[i-1],e[i],e[i-2]);return n}return new Uint16Array}function g(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=p.createTypedArray(t,r),a=e[0],i=0,o=1;o<t;++o,i+=6)I(n,i,a,e[o],e[o+1]);return n}return new Uint16Array}function C(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new d({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function w(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var a=t[n],i=0;i<a.componentsPerAttribute;++i)e[n].values.push(a.values[r*a.componentsPerAttribute+i])}function P(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),A.multiplyByPoint(e,ie,ie),a.pack(ie,r,i)}function x(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,r,i)}function L(e,t){var r,n=e.length,a={},i=e[0][t].attributes;for(r in i)if(i.hasOwnProperty(r)&&c(i[r])&&c(i[r].values)){for(var o=i[r],s=o.values.length,l=!0,E=1;E<n;++E){var f=e[E][t].attributes[r];if(!c(f)||o.componentDatatype!==f.componentDatatype||o.componentsPerAttribute!==f.componentsPerAttribute||o.normalize!==f.normalize){l=!1;break}s+=f.values.length}l&&(a[r]=new d({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function U(e,t){var n,i,o,u,s,l,E,f=e.length,d=(e[0].modelMatrix,c(e[0][t].indices)),_=e[0][t].primitiveType,m=L(e,t);for(n in m)if(m.hasOwnProperty(n))for(s=m[n].values,u=0,i=0;i<f;++i)for(l=e[i][t].attributes[n].values,E=l.length,o=0;o<E;++o)s[u++]=l[o];var T;if(d){var y=0;for(i=0;i<f;++i)y+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:m,primitiveType:S.POINTS})),A=p.createTypedArray(R,y),v=0,N=0;for(i=0;i<f;++i){var I=e[i][t].indices,M=I.length;for(u=0;u<M;++u)A[v++]=N+I[u];N+=h.computeNumberOfVertices(e[i][t])}T=A}var O,g=new a,C=0;for(i=0;i<f;++i){if(O=e[i][t].boundingSphere,!c(O)){g=void 0;break}a.add(O.center,g,g)}if(c(g))for(a.divideByScalar(g,f,g),i=0;i<f;++i){O=e[i][t].boundingSphere;var w=a.magnitude(a.subtract(O.center,g,se))+O.radius;w>C&&(C=w)}return new h({attributes:m,indices:T,primitiveType:_,boundingSphere:c(g)?new r(g,C):void 0})}function b(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function F(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,a=3;a<t;++a)r[n++]=a-1,r[n++]=0,r[n++]=a;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function D(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,a=3;a<t-1;a+=2)r[n++]=a,r[n++]=a-1,r[n++]=a+1,a+2<t&&(r[n++]=a,r[n++]=a+1,r[n++]=a+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return e.indices=r,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),r=p.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function V(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return F(e);case S.TRIANGLE_STRIP:return D(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function q(e,t){Math.abs(e.y)<y.EPSILON6&&(e.y=t?-y.EPSILON6:y.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return q(e,e.y<0),q(t,t.y<0),void q(r,r.y<0);var n,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(r.y);n=a>i?a>o?y.sign(e.y):y.sign(r.y):i>o?y.sign(t.y):y.sign(r.y);var u=n<0;q(e,u),q(t,u),q(r,u)}function H(e,t,r,n){a.add(e,a.multiplyByScalar(a.subtract(t,e,Ae),e.y/(e.y-t.y),Ae),r),a.clone(r,n),q(r,!0),q(n,!1)}function W(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,a=t.y<0,i=r.y<0,o=0;o+=n?1:0,o+=a?1:0,o+=i?1:0;var u=Me.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?a?i||(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Me.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=ve,s[4]=Se,s[5]=Ne,s[6]=Ie,s.length=7),Me}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var a in n)if(n.hasOwnProperty(a)&&c(n[a])&&c(n[a].values)){var i=n[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=p.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var a=t[n];r[n]=new d({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:r,indices:[],primitiveType:e.primitiveType})}function Z(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function K(e,r,i,o,u,s,l,E,f,h,d,_){if(c(s)||c(l)||c(E)||c(f)||c(h)){var p=a.fromArray(u,3*e,Oe),m=a.fromArray(u,3*r,ge),T=a.fromArray(u,3*i,Ce),y=t(o,p,m,T,we);if(c(s)){var R=a.fromArray(s,3*e,Oe),A=a.fromArray(s,3*r,ge),v=a.fromArray(s,3*i,Ce);a.multiplyByScalar(R,y.x,R),a.multiplyByScalar(A,y.y,A),a.multiplyByScalar(v,y.z,v);var S=a.add(R,A,R);a.add(S,v,S),a.normalize(S,S),a.pack(S,d.normal.values,3*_)}if(c(h)){var N=a.fromArray(h,3*e,Oe),I=a.fromArray(h,3*r,ge),M=a.fromArray(h,3*i,Ce);a.multiplyByScalar(N,y.x,N),a.multiplyByScalar(I,y.y,I),a.multiplyByScalar(M,y.z,M);var O;a.equals(N,a.ZERO)&&a.equals(I,a.ZERO)&&a.equals(M,a.ZERO)?(O=Oe,O.x=0,O.y=0,O.z=0):(O=a.add(N,I,N),a.add(O,M,O),a.normalize(O,O)),a.pack(O,d.extrudeDirection.values,3*_)}if(c(l)){var g=a.fromArray(l,3*e,Oe),C=a.fromArray(l,3*r,ge),w=a.fromArray(l,3*i,Ce);a.multiplyByScalar(g,y.x,g),a.multiplyByScalar(C,y.y,C),a.multiplyByScalar(w,y.z,w);var P=a.add(g,C,g);a.add(P,w,P),a.normalize(P,P),a.pack(P,d.tangent.values,3*_)}if(c(E)){var x=a.fromArray(E,3*e,Oe),L=a.fromArray(E,3*r,ge),U=a.fromArray(E,3*i,Ce);a.multiplyByScalar(x,y.x,x),a.multiplyByScalar(L,y.y,L),a.multiplyByScalar(U,y.z,U);var b=a.add(x,L,x);a.add(b,U,b),a.normalize(b,b),a.pack(b,d.bitangent.values,3*_)}if(c(f)){var F=n.fromArray(f,2*e,Pe),D=n.fromArray(f,2*r,xe),B=n.fromArray(f,2*i,Le);n.multiplyByScalar(F,y.x,F),n.multiplyByScalar(D,y.y,D),n.multiplyByScalar(B,y.z,B);var z=n.add(F,D,F);n.add(z,B,z),n.pack(z,d.st.values,2*_)}}}function j(e,t,r,n,a,i){var o=e.position.values.length/3;if(-1!==a){var u=n[a],s=r[u];return-1===s?(r[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function Q(e){var t,r,n,i,o,u=e.geometry,s=u.attributes,l=s.position.values,E=c(s.normal)?s.normal.values:void 0,f=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,d=c(s.st)?s.st.values:void 0,_=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,p=u.indices,m=Y(u),T=Y(u),y=[];y.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<y.length;++o)y[o]=-1,R[o]=-1;var A=p.length;for(o=0;o<A;o+=3){var v=p[o],S=p[o+1],N=p[o+2],I=a.fromArray(l,3*v),M=a.fromArray(l,3*S),O=a.fromArray(l,3*N),g=W(I,M,O);if(c(g)&&g.positions.length>3)for(var C=g.positions,w=g.indices,P=w.length,x=0;x<P;++x){var L=w[x],U=C[L];U.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,p,L<3?o+L:-1,U),K(v,S,N,U,l,E,h,f,d,_,t,i)}else c(g)&&(I=g.positions[0],M=g.positions[1],O=g.positions[2]),I.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,p,o,I),K(v,S,N,I,l,E,h,f,d,_,t,i),i=j(t,r,n,p,o+1,M),K(v,S,N,M,l,E,h,f,d,_,t,i),i=j(t,r,n,p,o+2,O),K(v,S,N,O,l,E,h,f,d,_,t,i)}Z(e,T,m)}function J(e){var t,r=e.geometry,n=r.attributes,i=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,E=[];E.length=i.length/3;var f=[];for(f.length=i.length/3,t=0;t<E.length;++t)E[t]=-1,f[t]=-1;for(t=0;t<l;t+=2){var h=o[t],d=o[t+1],_=a.fromArray(i,3*h,Oe),p=a.fromArray(i,3*d,ge);Math.abs(_.y)<y.EPSILON6&&(_.y<0?_.y=-y.EPSILON6:_.y=y.EPSILON6),Math.abs(p.y)<y.EPSILON6&&(p.y<0?p.y=-y.EPSILON6:p.y=y.EPSILON6);var m=u.attributes,R=u.indices,A=f,v=s.attributes,S=s.indices,N=E,I=T.lineSegmentPlane(_,p,Ue,Ce);if(c(I)){var M=a.multiplyByScalar(a.UNIT_Y,5*y.EPSILON9,be);_.y<0&&(a.negate(M,M),m=s.attributes,R=s.indices,A=E,v=u.attributes,S=u.indices,N=f);var O=a.add(I,M,Fe);j(m,R,A,o,t,_),j(m,R,A,o,-1,O),a.negate(M,M),a.add(I,M,O),j(v,S,N,o,-1,O),j(v,S,N,o,t+1,p)}else{var g,C,w;_.y<0?(g=s.attributes,C=s.indices,w=E):(g=u.attributes,C=u.indices,w=f),j(g,C,w,o,t,_),j(g,C,w,o,t+1,p)}}Z(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,i=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=a.unpack(r,u,ze);if(!(s.x>0)){var c=a.unpack(n,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):a.pack(s,n,u));var l=a.unpack(i,u,Ve);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=r[u+3],i[u+1]=r[u+4],i[u+2]=r[u+5]):a.pack(s,i,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,E=s.prevPosition.values,f=s.nextPosition.values,h=s.expandAndWidth.values,d=c(s.st)?s.st.values:void 0,_=c(s.color)?s.color.values:void 0,p=Y(u),m=Y(u),R=!1,A=l.length/3;for(t=0;t<A;t+=4){var v=t,S=t+2,N=a.fromArray(l,3*v,ze),I=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<Ye)for(N.y=Ye*(I.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,r=3*v;r<3*v+12;r+=3)E[r]=l[3*t],E[r+1]=l[3*t+1],E[r+2]=l[3*t+2];if(Math.abs(I.y)<Ye)for(I.y=Ye*(N.y<0?-1:1),l[3*(t+2)+1]=I.y,l[3*(t+3)+1]=I.y,r=3*v;r<3*v+12;r+=3)f[r]=l[3*(t+2)],f[r+1]=l[3*(t+2)+1],f[r+2]=l[3*(t+2)+2];var M=p.attributes,O=p.indices,g=m.attributes,C=m.indices,w=T.lineSegmentPlane(N,I,Ue,qe);if(c(w)){R=!0;var P=a.multiplyByScalar(a.UNIT_Y,ke,Xe);N.y<0&&(a.negate(P,P),M=m.attributes,O=m.indices,g=p.attributes,C=p.indices);var x=a.add(w,P,He);M.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.position.values.push(x.x,x.y,x.z),M.position.values.push(x.x,x.y,x.z),M.prevPosition.values.push(E[3*v],E[3*v+1],E[3*v+2]),M.prevPosition.values.push(E[3*v+3],E[3*v+4],E[3*v+5]),M.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),a.negate(P,P),a.add(w,P,x),g.position.values.push(x.x,x.y,x.z),g.position.values.push(x.x,x.y,x.z),g.position.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.nextPosition.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.nextPosition.values.push(f[3*S],f[3*S+1],f[3*S+2]),g.nextPosition.values.push(f[3*S+3],f[3*S+4],f[3*S+5]);var L=n.fromArray(h,2*v,De),U=Math.abs(L.y);M.expandAndWidth.values.push(-1,U,1,U),M.expandAndWidth.values.push(-1,-U,1,-U),g.expandAndWidth.values.push(-1,U,1,U),g.expandAndWidth.values.push(-1,-U,1,-U);var b=a.magnitudeSquared(a.subtract(w,N,Ve));if(b/=a.magnitudeSquared(a.subtract(I,N,Ve)),c(_)){var F=i.fromArray(_,4*v,We),D=i.fromArray(_,4*S,We),B=y.lerp(F.x,D.x,b),z=y.lerp(F.y,D.y,b),G=y.lerp(F.z,D.z,b),V=y.lerp(F.w,D.w,b);for(r=4*v;r<4*v+8;++r)M.color.values.push(_[r]);for(M.color.values.push(B,z,G,V),M.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),r=4*S;r<4*S+8;++r)g.color.values.push(_[r])}if(c(d)){var q=n.fromArray(d,2*v,De),X=n.fromArray(d,2*(t+3),Be),H=y.lerp(q.x,X.x,b);for(r=2*v;r<2*v+4;++r)M.st.values.push(d[r]);for(M.st.values.push(H,q.y),M.st.values.push(H,X.y),g.st.values.push(H,q.y),g.st.values.push(H,X.y),r=2*S;r<2*S+4;++r)g.st.values.push(d[r])}o=M.position.values.length/3-4,O.push(o,o+2,o+1),O.push(o+1,o+2,o+3),o=g.position.values.length/3-4,C.push(o,o+2,o+1),C.push(o+1,o+2,o+3)}else{var W,k;for(N.y<0?(W=m.attributes,k=m.indices):(W=p.attributes,k=p.indices),W.position.values.push(N.x,N.y,N.z),W.position.values.push(N.x,N.y,N.z),W.position.values.push(I.x,I.y,I.z),W.position.values.push(I.x,I.y,I.z),r=3*t;r<3*t+12;++r)W.prevPosition.values.push(E[r]),W.nextPosition.values.push(f[r]);for(r=2*t;r<2*t+8;++r)W.expandAndWidth.values.push(h[r]),c(d)&&W.st.values.push(d[r]);if(c(_))for(r=4*t;r<4*t+16;++r)W.color.values.push(_[r]);o=W.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}R&&($(m),$(p)),Z(e,m,p)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=M(t);break;case S.TRIANGLE_STRIP:e.indices=O(t);break;case S.TRIANGLE_FAN:e.indices=g(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),E=0,f=0;f<o;f+=3)l[E++]=a[f],l[E++]=a[f+1],l[E++]=a[f+2],l[E++]=a[f]+i[f]*n,l[E++]=a[f+1]+i[f+1]*n,l[E++]=a[f+2]+i[f+2]*n;var _,p=e.boundingSphere;return c(p)&&(_=new r(p.center,p.radius+n)),new h({attributes:{position:new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:_})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,a={},i=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(a[u]=i++)}for(var s in n)n.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),a=0;a<t;a++)n[a]=-1;for(var i,o=r,s=o.length,l=p.createTypedArray(t,s),E=0,f=0,d=0;E<s;)i=n[o[E]],-1!==i?l[f]=i:(i=o[E],n[i]=d,l[f]=d,++d),++E,++f;e.indices=l;var _=e.attributes;for(var m in _)if(_.hasOwnProperty(m)&&c(_[m])&&c(_[m].values)){for(var T=_[m],y=T.values,R=0,A=T.componentsPerAttribute,v=u.createTypedArray(T.componentDatatype,d*A);R<t;){var S=n[R];if(-1!==S)for(var N=0;N<A;N++)v[A*S+N]=y[A*R+N];++R}T.values=v}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,a=0,i=0;i<n;i++)r[i]>a&&(a=r[i]);e.indices=N.tipsify({indices:r,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=h.computeNumberOfVertices(e);if(c(e.indices)&&r>=y.SIXTY_FOUR_KILOBYTES){var n,a=[],i=[],o=0,u=C(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var E=0;E<l;E+=n){for(var f=0;f<n;++f){var d=s[E+f],_=a[d];c(_)||(_=o++,a[d]=_,w(u,e.attributes,d)),i.push(_)}o+n>=y.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=C(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new a,ne=new o;te.projectTo2D=function(e,t,r,n,i){var o=e.attributes[t];i=c(i)?i:new f;for(var s=i.ellipsoid,l=o.values,E=new Float64Array(l.length),h=0,_=0;_<l.length;_+=3){var p=a.fromArray(l,_,re),m=s.cartesianToCartographic(p,ne),T=i.project(m,re);E[h++]=T.x,E[h++]=T.y,E[h++]=T.z}return e.attributes[r]=o,e.attributes[n]=new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:E}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)E.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var f=a.componentsPerAttribute;return e.attributes[r]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:s}),e.attributes[n]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:c}),delete e.attributes[t],e};var ie=new a,oe=new A,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(A.equals(t,A.IDENTITY))return e;var n=e.geometry.attributes;P(t,n.position),P(t,n.prevPosition),P(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(A.inverse(t,oe),A.transpose(oe,oe),A.getRotation(oe,ue),x(ue,n.normal),x(ue,n.tangent),x(ue,n.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=r.transform(a,t,a)),e.modelMatrix=A.clone(A.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,a=0;a<n;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&r.push(i)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,Ee=new a,fe=new a;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,i=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),E=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var f=0;for(t=0;t<s;t+=3){var h=r[t],_=r[t+1],p=r[t+2],m=3*h,T=3*_,R=3*p;le.x=i[m],le.y=i[m+1],le.z=i[m+2],Ee.x=i[T],Ee.y=i[T+1],Ee.z=i[T+2],fe.x=i[R],fe.y=i[R+1],fe.z=i[R+2],c[h].count++,c[_].count++,c[p].count++,a.subtract(Ee,le,Ee),a.subtract(fe,le,fe),l[f]=a.cross(Ee,fe,new a),f++}var A=0;for(t=0;t<o;t++)c[t].indexOffset+=A,A+=c[t].count;f=0;var v;for(t=0;t<s;t+=3){v=c[r[t]];var S=v.indexOffset+v.currentCount;E[S]=f,v.currentCount++,v=c[r[t+1]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,v=c[r[t+2]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,f++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var I=3*t;if(v=c[t],a.clone(a.ZERO,ce),v.count>0){for(f=0;f<v.count;f++)a.add(ce,l[E[v.indexOffset+f]],ce);a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&a.clone(l[E[v.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[I]=ce.x,N[I+1]=ce.y,N[I+2]=ce.z}return e.attributes.normal=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,de=new a,_e=new a;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var E,f,h;for(t=0;t<c;t+=3){var _=r[t],p=r[t+1],m=r[t+2];E=3*_,f=3*p,h=3*m;var T=2*_,y=2*p,R=2*m,A=n[E],v=n[E+1],S=n[E+2],N=o[T],I=o[T+1],M=o[y+1]-I,O=o[R+1]-I,g=1/((o[y]-N)*O-(o[R]-N)*M),C=(O*(n[f]-A)-M*(n[h]-A))*g,w=(O*(n[f+1]-v)-M*(n[h+1]-v))*g,P=(O*(n[f+2]-S)-M*(n[h+2]-S))*g;l[E]+=C,l[E+1]+=w,l[E+2]+=P,l[f]+=C,l[f+1]+=w,l[f+2]+=P,l[h]+=C,l[h+1]+=w,l[h+2]+=P}var x=new Float32Array(3*s),L=new Float32Array(3*s);for(t=0;t<s;t++){E=3*t,f=E+1,h=E+2;var U=a.fromArray(i,E,he),b=a.fromArray(l,E,_e),F=a.dot(U,b);a.multiplyByScalar(U,F,de),a.normalize(a.subtract(b,de,b),b),x[E]=b.x,x[f]=b.y,x[h]=b.z,a.normalize(a.cross(U,b,b),b),L[E]=b.x,L[f]=b.y,L[h]=b.z}return e.attributes.tangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:x}),e.attributes.bitangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:L}),e};var pe=new n,me=new a,Te=new a,ye=new a,Re=new n;te.compressVertices=function(t){var r,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),E=0;for(r=0;r<i;++r)a.fromArray(s,3*r,me),a.equals(me,a.ZERO)?E+=2:(Re=e.octEncodeInRange(me,65535,Re),l[E++]=Re.x,l[E++]=Re.y);return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var f=t.attributes.normal,h=t.attributes.st,_=c(f),p=c(h);if(!_&&!p)return t;var m,T,y,R,A=t.attributes.tangent,v=t.attributes.bitangent,S=c(A),N=c(v);_&&(m=f.values),p&&(T=h.values),S&&(y=A.values),N&&(R=v.values),i=(_?m.length:T.length)/(_?3:2);var I=i,M=p&&_?2:1;M+=S||N?1:0,I*=M;var O=new Float32Array(I),g=0;for(r=0;r<i;++r){p&&(n.fromArray(T,2*r,pe),O[g++]=e.compressTextureCoordinates(pe));var C=3*r;_&&c(y)&&c(R)?(a.fromArray(m,C,me),a.fromArray(y,C,Te),a.fromArray(R,C,ye),e.octPack(me,Te,ye,pe),O[g++]=pe.x,O[g++]=pe.y):(_&&(a.fromArray(m,C,me),O[g++]=e.octEncodeFloat(me)),S&&(a.fromArray(y,C,me),O[g++]=e.octEncodeFloat(me)),N&&(a.fromArray(R,C,me),O[g++]=e.octEncodeFloat(me)))}return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:M,values:O}),_&&delete t.attributes.normal,p&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Ae=new a,ve=new a,Se=new a,Ne=new a,Ie=new a,Me={positions:new Array(7),indices:new Array(9)},Oe=new a,ge=new a,Ce=new a,we=new a,Pe=new n,xe=new n,Le=new n,Ue=v.fromPointNormal(a.ZERO,a.UNIT_Y),be=new a,Fe=new a,De=new n,Be=new n,ze=new a,Ge=new a,Ve=new a,qe=new a,Xe=new a,He=new a,We=new i,ke=5*y.EPSILON9,Ye=y.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,v.ORIGIN_ZX_PLANE)!==m.INTERSECTING)return e}if(t.geometryType!==_.NONE)switch(t.geometryType){case _.POLYLINES:ee(e);break;case _.TRIANGLES:Q(e);break;case _.LINES:J(e)}else V(t),t.primitiveType===S.TRIANGLES?Q(e):t.primitiveType===S.LINES&&J(e);return e},te}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude) -;var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},s.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},s}),define("Scene/PrimitivePipeline",["../Core/BoundingSphere","../Core/ComponentDatatype","../Core/defined","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/GeographicProjection","../Core/Geometry","../Core/GeometryAttribute","../Core/GeometryAttributes","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Matrix4","../Core/WebMercatorProjection"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h){"use strict";function d(e,t,n){var a,i=!n,o=e.length;if(!i&&o>1){var u=e[0].modelMatrix;for(a=1;a<o;++a)if(!f.equals(u,e[a].modelMatrix)){i=!0;break}}if(i)for(a=0;a<o;++a)r(e[a].geometry)&&l.transformToWorldCoordinates(e[a]);else f.multiplyTransformation(t,e[0].modelMatrix,t)}function _(e,r){var n=e.attributes,a=n.position,i=a.values.length/a.componentsPerAttribute;n.batchId=new s({componentDatatype:t.FLOAT,componentsPerAttribute:1,values:new Float32Array(i)});for(var o=n.batchId.values,u=0;u<i;++u)o[u]=r}function p(e){for(var t=e.length,n=0;n<t;++n){var a=e[n];r(a.geometry)?_(a.geometry,n):r(a.westHemisphereGeometry)&&r(a.eastHemisphereGeometry)&&(_(a.westHemisphereGeometry,n),_(a.eastHemisphereGeometry,n))}}function m(n){var a,i,o=n.instances,u=n.projection,s=n.elementIndexUintSupported,c=n.scene3DOnly,E=n.vertexCacheOptimize,f=n.compressVertices,h=n.modelMatrix,_=o.length;for(a=0;a<_;++a)if(r(o[a].geometry)){o[a].geometry.primitiveType;break}if(d(o,h,c),!c)for(a=0;a<_;++a)r(o[a].geometry)&&l.splitLongitude(o[a]);if(p(o),E)for(a=0;a<_;++a){var m=o[a];r(m.geometry)?(l.reorderForPostVertexCache(m.geometry),l.reorderForPreVertexCache(m.geometry)):r(m.westHemisphereGeometry)&&r(m.eastHemisphereGeometry)&&(l.reorderForPostVertexCache(m.westHemisphereGeometry),l.reorderForPreVertexCache(m.westHemisphereGeometry),l.reorderForPostVertexCache(m.eastHemisphereGeometry),l.reorderForPreVertexCache(m.eastHemisphereGeometry))}var T=l.combineInstances(o);for(_=T.length,a=0;a<_;++a){i=T[a];var y,R=i.attributes;if(c)for(y in R)R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE&&l.encodeAttribute(i,y,y+"3DHigh",y+"3DLow");else for(y in R)if(R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE){var A=y+"3D",v=y+"2D";l.projectTo2D(i,y,A,v,u),r(i.boundingSphere)&&"position"===y&&(i.boundingSphereCV=e.fromVertices(i.attributes.position2D.values)),l.encodeAttribute(i,A,A+"High",A+"Low"),l.encodeAttribute(i,v,v+"High",v+"Low")}f&&l.compressVertices(i)}if(!s){var S=[];for(_=T.length,a=0;a<_;++a)i=T[a],S=S.concat(l.fitToUnsignedShortIndices(i));T=S}return T}function T(e,t,n,a){var i,o,u,s=a.length-1;if(s>=0){var c=a[s];i=c.offset+c.count,u=c.index,o=n[u].indices.length}else i=0,u=0,o=n[u].indices.length;for(var l=e.length,E=0;E<l;++E){var f=e[E],h=f[t];if(r(h)){var d=h.indices.length;i+d>o&&(i=0,o=n[++u].indices.length),a.push({index:u,offset:i,count:d}),i+=d}}}function y(e,t){var r=[];return T(e,"geometry",t,r),T(e,"westHemisphereGeometry",t,r),T(e,"eastHemisphereGeometry",t,r),r}function R(e,t){var n=e.attributes;for(var a in n)if(n.hasOwnProperty(a)){var i=n[a];r(i)&&r(i.values)&&t.push(i.values.buffer)}r(e.indices)&&t.push(e.indices.buffer)}function A(e,t){for(var r=e.length,n=0;n<r;++n)R(e[n],t)}function v(t){for(var n=1,a=t.length,i=0;i<a;i++){var o=t[i];if(++n,r(o)){var u=o.attributes;n+=6+2*e.packedLength+(r(o.indices)?o.indices.length:0);for(var s in u)if(u.hasOwnProperty(s)&&r(u[s])){var c=u[s];n+=5+c.values.length}}}return n}function S(e,t){var r=e.length,n=new Float64Array(1+16*r),a=0;n[a++]=r;for(var i=0;i<r;i++){var o=e[i];f.pack(o.modelMatrix,n,a),a+=f.packedLength}return t.push(n.buffer),n}function N(e){for(var t=e,r=new Array(t[0]),n=0,a=1;a<t.length;){var i=f.unpack(t,a);a+=f.packedLength,r[n++]={modelMatrix:i}}return r}function I(t){var n=t.length,a=1+(e.packedLength+1)*n,i=new Float32Array(a),o=0;i[o++]=n;for(var u=0;u<n;++u){var s=t[u];r(s)?(i[o++]=1,e.pack(t[u],i,o)):i[o++]=0,o+=e.packedLength}return i}function M(t){for(var r=new Array(t[0]),n=0,a=1;a<t.length;)1===t[a++]&&(r[n]=e.unpack(t,a)),++n,a+=e.packedLength;return r}if(!i.supportsTypedArrays())return{};var O={};return O.combineGeometry=function(t){var n,a,i,o=t.instances,u=o.length;u>0&&(n=m(t),n.length>0&&(a=l.createAttributeLocations(n[0]),t.createPickOffsets&&(i=y(o,n))));for(var s=new Array(u),c=new Array(u),E=0;E<u;++E){var f=o[E],h=f.geometry;r(h)&&(s[E]=h.boundingSphere,c[E]=h.boundingSphereCV);var d=f.eastHemisphereGeometry,_=f.westHemisphereGeometry;r(d)&&r(_)&&(r(d.boundingSphere)&&r(_.boundingSphere)&&(s[E]=e.union(d.boundingSphere,_.boundingSphere)),r(d.boundingSphereCV)&&r(_.boundingSphereCV)&&(c[E]=e.union(d.boundingSphereCV,_.boundingSphereCV)))}return{geometries:n,modelMatrix:t.modelMatrix,attributeLocations:a,pickOffsets:i,boundingSpheres:s,boundingSpheresCV:c}},O.packCreateGeometryResults=function(t,n){var a=new Float64Array(v(t)),i=[],o={},u=t.length,s=0;a[s++]=u;for(var c=0;c<u;c++){var l=t[c],E=r(l);if(a[s++]=E?1:0,E){a[s++]=l.primitiveType,a[s++]=l.geometryType;var f=r(l.boundingSphere)?1:0;a[s++]=f,f&&e.pack(l.boundingSphere,a,s),s+=e.packedLength;var h=r(l.boundingSphereCV)?1:0;a[s++]=h,h&&e.pack(l.boundingSphereCV,a,s),s+=e.packedLength;var d=l.attributes,_=[];for(var p in d)d.hasOwnProperty(p)&&r(d[p])&&(_.push(p),r(o[p])||(o[p]=i.length,i.push(p)));a[s++]=_.length;for(var m=0;m<_.length;m++){var T=_[m],y=d[T];a[s++]=o[T],a[s++]=y.componentDatatype,a[s++]=y.componentsPerAttribute,a[s++]=y.normalize?1:0,a[s++]=y.values.length,a.set(y.values,s),s+=y.values.length}var R=r(l.indices)?l.indices.length:0;a[s++]=R,R>0&&(a.set(l.indices,s),s+=R)}}return n.push(a.buffer),{stringTable:i,packedData:a}},O.unpackCreateGeometryResults=function(r){for(var n,a=r.stringTable,i=r.packedData,o=new Array(i[0]),l=0,f=1;f<i.length;){if(1===i[f++]){var h,d,_=i[f++],p=i[f++];1===i[f++]&&(h=e.unpack(i,f)),f+=e.packedLength;1===i[f++]&&(d=e.unpack(i,f)),f+=e.packedLength;var m,T,y,R=new c,A=i[f++];for(n=0;n<A;n++){var v=a[i[f++]],S=i[f++];y=i[f++];var N=0!==i[f++];m=i[f++],T=t.createTypedArray(S,m);for(var I=0;I<m;I++)T[I]=i[f++];R[v]=new s({componentDatatype:S,componentsPerAttribute:y,normalize:N,values:T})}var M;if((m=i[f++])>0){var O=T.length/y;for(M=E.createTypedArray(O,m),n=0;n<m;n++)M[n]=i[f++]}o[l++]=new u({primitiveType:_,geometryType:p,boundingSphere:h,boundingSphereCV:d,indices:M,attributes:R})}else o[l++]=void 0}return o},O.packCombineGeometryParameters=function(e,t){for(var r=e.createGeometryResults,n=r.length,a=0;a<n;a++)t.push(r[a].packedData.buffer);return{createGeometryResults:e.createGeometryResults,packedInstances:S(e.instances,t),ellipsoid:e.ellipsoid,isGeographic:e.projection instanceof o,elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e.createPickOffsets}},O.unpackCombineGeometryParameters=function(e){for(var t=N(e.packedInstances),r=e.createGeometryResults,n=r.length,i=0,u=0;u<n;u++)for(var s=O.unpackCreateGeometryResults(r[u]),c=s.length,l=0;l<c;l++){var E=s[l],d=t[i];d.geometry=E,++i}var _=a.clone(e.ellipsoid);return{instances:t,ellipsoid:_,projection:e.isGeographic?new o(_):new h(_),elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:f.clone(e.modelMatrix),createPickOffsets:e.createPickOffsets}},O.packCombineGeometryResults=function(e,t){r(e.geometries)&&A(e.geometries,t);var n=I(e.boundingSpheres),a=I(e.boundingSpheresCV);return t.push(n.buffer,a.buffer),{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:n,boundingSpheresCV:a}},O.unpackCombineGeometryResults=function(e){return{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:M(e.boundingSpheres),boundingSpheresCV:M(e.boundingSpheresCV)}},O}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var r,n=t.name,a=t.message;r=e(n)&&e(a)?n+": "+a:t.toString();var i=t.stack;return e(i)&&(r+="\n"+i),r}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,r){"use strict";function n(n){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=n(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+r(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return n}),define("Workers/createGeometry",["../Core/defined","../Scene/PrimitivePipeline","./createTaskProcessorWorker","require"],function(e,t,r,n){"use strict";function a(t){var r=o[t];return e(r)||("object"==typeof exports?o[r]=r=n("Workers/"+t):n(["./"+t],function(e){r=e,o[r]=e})),r}function i(r,n){for(var i=r.subTasks,o=i.length,u=new Array(o),s=0;s<o;s++){var c=i[s],l=c.geometry,E=c.moduleName;if(e(E)){var f=a(E);u[s]=f(l,c.offset)}else u[s]=l}return t.packCreateGeometryResults(u,n)}var o={};return r(i)})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,i){if(a.typeOf.number(e,n),a.typeOf.number(r,i),n!==i)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var i=Math.abs(e-r);return i<=a||i<=n*Math.max(Math.abs(e),Math.abs(r))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var r=i[t-1],n=t;n<=e;n++)i.push(r*n);return i[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(i),n},o.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var E=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)},o.cross=function(e,t,r){var n=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-n*s,E=n*u-a*o;return r.x=c,r.y=l,r.z=E,r},o.fromDegrees=function(e,t,r,n,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,r,n,a)};var f=new o,h=new o,d=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,a,i,u){a=t(a,0);var s=r(i)?i.radiiSquared:d,c=Math.cos(n);f.x=c*Math.cos(e),f.y=c*Math.sin(e),f.z=Math.sin(n),f=o.normalize(f,f),o.multiplyComponents(s,f,h);var l=Math.sqrt(o.dot(f,h));return h=o.divideByScalar(h,l,h),f=o.multiplyByScalar(f,a,f),r(u)||(u=new o),o.add(h,f,u)},o.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,c){var l=r.x,E=r.y,f=r.z,h=a.x,d=a.y,p=a.z,_=l*l*h*h,m=E*E*d*d,T=f*f*p*p,y=_+m+T,R=Math.sqrt(1/y),A=e.multiplyByScalar(r,R,i);if(y<s)return isFinite(R)?e.clone(A,c):void 0;var v=u.x,S=u.y,N=u.z,I=o;I.x=A.x*v*2,I.y=A.y*S*2,I.z=A.z*N*2;var M,O,g,C,w,P,x,L,U,b,F,D=(1-R)*e.magnitude(r)/(.5*e.magnitude(I)),B=0;do{D-=B,g=1/(1+D*v),C=1/(1+D*S),w=1/(1+D*N),P=g*g,x=C*C,L=w*w,U=P*g,b=x*C,F=L*w,M=_*P+m*x+T*L-1,O=_*U*v+m*b*S+T*F*N;B=M/(-2*O)}while(Math.abs(M)>n.EPSILON12);return t(c)?(c.x=l*g,c.y=E*C,c.z=f*w,c):new e(l*g,E*C,f*w)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,i){return a=r(a,0),n(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,E=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,r,a){var d=n(r)?r.oneOverRadii:E,p=n(r)?r.oneOverRadiiSquared:f,_=n(r)?r._centerToleranceSquared:h,m=o(t,d,p,_,c);if(n(m)){var T=e.multiplyComponents(m,p,s);T=e.normalize(T,T);var y=e.subtract(t,m,l),R=Math.atan2(T.y,T.x),A=Math.asin(T.z),v=i.sign(e.dot(y,t))*e.magnitude(y);return n(a)?(a.longitude=R,a.latitude=A,a.height=v,a):new u(R,A,v)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(t,r,a,i){r=n(r,0),a=n(a,0),i=n(i,0),t._radii=new e(r,a,i),t._radiiSquared=new e(r*r,a*a,i*i),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(r,a,i),t._maximumRadius=Math.max(r,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function E(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}i(E.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),E.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new E(n.x,n.y,n.z)}},E.fromCartesian3=function(e,t){return a(t)||(t=new E),a(e)?(l(t,e.x,e.y,e.z),t):t},E.WGS84=u(new E(6378137,6378137,6356752.314245179)),E.UNIT_SPHERE=u(new E(1,1,1)),E.MOON=u(new E(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),E.prototype.clone=function(e){return E.clone(this,e)},E.packedLength=e.packedLength,E.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},E.unpack=function(t,r,a){r=n(r,0);var i=e.unpack(t,r);return E.fromCartesian3(i,a)},E.prototype.geocentricSurfaceNormal=e.normalize,E.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(i);return a(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},E.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var f=new e,h=new e;E.prototype.cartographicToCartesian=function(t,r){var n=f,i=h;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,i);var o=Math.sqrt(e.dot(n,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(i,n,r)},E.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var d=new e,p=new e,_=new e;return E.prototype.cartesianToCartographic=function(r,n){var i=this.scaleToGeodeticSurface(r,p);if(a(i)){var o=this.geodeticSurfaceNormal(i,d),u=e.subtract(r,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),E=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=c,n.latitude=l,n.height=E,n):new t(c,l,E)}},E.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},E.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},E.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},E.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},E.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},E.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},E.prototype.toString=function(){return this._radii.toString()},E.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,i){r=n(r,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-r))return i},E}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,i,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a,i,o,u,s,c){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(i,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(p[r],d[r])];t+=2*n*n}return Math.sqrt(t)}function E(e,t){for(var r=u.EPSILON15,n=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(p[i],d[i])]);o>n&&(a=i,n=o)}var c=1,l=0,E=d[a],f=p[a];if(Math.abs(e[s.getElementIndex(f,E)])>r){var h,_=e[s.getElementIndex(f,f)],m=e[s.getElementIndex(E,E)],T=e[s.getElementIndex(f,E)],y=(_-m)/2/T;h=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(E,E)]=t[s.getElementIndex(f,f)]=c,t[s.getElementIndex(f,E)]=l,t[s.getElementIndex(E,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,E=e.z*e.z,f=e.z*e.w,h=e.w*e.w,d=r-u-E+h,p=2*(a-f),_=2*(i+l),m=2*(a+f),T=-r+u-E+h,y=2*(c-o),R=2*(i-l),A=2*(c+o),v=-r-u+E+h;return n(t)?(t[0]=d,t[1]=m,t[2]=R,t[3]=p,t[4]=T,t[5]=A,t[6]=_,t[7]=y,t[8]=v,t):new s(d,p,_,m,T,y,R,A,v)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*a,E=-i*u+c*o*a,f=c*u+i*o*a,h=r*u,d=i*a+c*o*u,p=-c*a+i*o*u,_=-o,m=c*r,T=i*r;return n(t)?(t[0]=l,t[1]=h,t[2]=_,t[3]=E,t[4]=d,t[5]=m,t[6]=f,t[7]=p,t[8]=T,t):new s(l,E,f,h,d,p,_,m,T)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],i=e[n+1],o=e[n+2];return r.x=a,r.y=i,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],i=e[t+6];return r.x=n,r.y=a,r.z=i,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var f=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),r};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],E=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=i,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=E,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[3]*a+e[6]*i,u=e[1]*n+e[4]*a+e[7]*i,s=e[2]*n+e[5]*a+e[8]*i;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var d=[1,0,0],p=[2,2,1],_=new s,m=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,i=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),h=r*c(f);i<10&&l(f)>h;)E(f,_),s.transpose(_,m),s.multiply(f,_,f),s.multiply(m,f,f),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*n-r*c)+u*(r*o-i*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],E=e[8],f=s.determinant(e);t[0]=o*E-l*u,t[1]=l*a-n*E,t[2]=n*u-o*a,t[3]=c*u-i*E,t[4]=r*E-c*a,t[5]=i*a-r*u,t[6]=i*l-c*o,t[7]=c*n-r*l,t[8]=r*o-i*n;var h=1/f;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}o.fromElements=function(e,t,n,a,i){return r(i)?(i.x=e,i.y=t,i.z=n,i.w=a,i):new o(e,t,n,a)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)&&i.equalsEpsilon(e.z,t.z,n,a)&&i.equalsEpsilon(e.w,t.w,n,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,i,o,u,s,c){"use strict";function l(e,t,r,a,i,o,u,s,c,l,E,f,h,d,p,_){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(c,0),this[3]=n(h,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(d,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(E,0),this[11]=n(p,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(_,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,i){return r=n(r,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=r.x,i[13]=r.y,i[14]=r.z,i[15]=1,i):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var i=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,E=t.x*t.z,f=t.x*t.w,h=t.y*t.y,d=t.y*t.z,p=t.y*t.w,_=t.z*t.z,m=t.z*t.w,T=t.w*t.w,y=s-h-_+T,R=2*(c-m),A=2*(E+p),v=2*(c+m),S=-s+h-_+T,N=2*(d-f),I=2*(E-p),M=2*(d+f),O=-s-h+_+T;return n[0]=y*i,n[1]=v*i,n[2]=I*i,n[3]=0,n[4]=R*o,n[5]=S*o,n[6]=M*o,n[7]=0,n[8]=A*u,n[9]=N*u,n[10]=O*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var E=new e,f=new e,h=new e;l.fromCamera=function(t,r){var n=t.position,i=t.direction,o=t.up;e.normalize(i,E),e.normalize(e.cross(E,o,f),f),e.normalize(e.cross(f,E,h),h);var u=f.x,s=f.y,c=f.z,d=E.x,p=E.y,_=E.z,m=h.x,T=h.y,y=h.z,R=n.x,A=n.y,v=n.z,S=u*-R+s*-A+c*-v,N=m*-R+T*-A+y*-v,I=d*R+p*A+_*v;return a(r)?(r[0]=u,r[1]=m,r[2]=-d,r[3]=0,r[4]=s,r[5]=T,r[6]=-p,r[7]=0,r[8]=c,r[9]=y,r[10]=-_,r[11]=0,r[12]=S,r[13]=N,r[14]=I,r[15]=1,r):new l(u,s,c,S,m,T,y,N,-d,-p,-_,I,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,i,o){var u=1/(t-e),s=1/(n-r),c=1/(i-a),l=-(t+e)*u,E=-(n+r)*s,f=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=E,o[14]=f,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,a,i,o){var u=2*a/(t-e),s=2*a/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),E=-(i+a)/(i-a),f=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=E,o[11]=-1,o[12]=0,o[13]=0,o[14]=f,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,i){var o=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var i=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,E=.5*(r-t),f=c,h=l,d=E,p=i+c,_=o+l,m=t+E;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=d,a[11]=0,a[12]=p,a[13]=_,a[14]=m,a[15]=1,a},l.computeView=function(t,r,n,a,i){return i[0]=a.x,i[1]=n.x,i[2]=-r.x,i[3]=0,i[4]=a.y,i[5]=n.y,i[6]=-r.y,i[7]=0,i[8]=a.z,i[9]=n.z,i[10]=-r.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(n,t),i[14]=e.dot(r,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],i=e[n+1],o=e[n+2],u=e[n+3];return r.x=a,r.y=i,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return r.x=n,r.y=a,r.z=i,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var d=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],d)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],d)),r};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],E=e[8],f=e[9],h=e[10],d=e[11],p=e[12],_=e[13],m=e[14],T=e[15],y=t[0],R=t[1],A=t[2],v=t[3],S=t[4],N=t[5],I=t[6],M=t[7],O=t[8],g=t[9],C=t[10],w=t[11],P=t[12],x=t[13],L=t[14],U=t[15],b=n*y+u*R+E*A+p*v,F=a*y+s*R+f*A+_*v,D=i*y+c*R+h*A+m*v,B=o*y+l*R+d*A+T*v,z=n*S+u*N+E*I+p*M,G=a*S+s*N+f*I+_*M,V=i*S+c*N+h*I+m*M,q=o*S+l*N+d*I+T*M,X=n*O+u*g+E*C+p*w,H=a*O+s*g+f*C+_*w,W=i*O+c*g+h*C+m*w,k=o*O+l*g+d*C+T*w,Y=n*P+u*x+E*L+p*U,Z=a*P+s*x+f*L+_*U,K=i*P+c*x+h*L+m*U,j=o*P+l*x+d*L+T*U;return r[0]=b,r[1]=F,r[2]=D,r[3]=B,r[4]=z,r[5]=G,r[6]=V,r[7]=q,r[8]=X,r[9]=H,r[10]=W,r[11]=k,r[12]=Y,r[13]=Z,r[14]=K,r[15]=j,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=e[12],h=e[13],d=e[14],p=t[0],_=t[1],m=t[2],T=t[4],y=t[5],R=t[6],A=t[8],v=t[9],S=t[10],N=t[12],I=t[13],M=t[14],O=n*p+o*_+c*m,g=a*p+u*_+l*m,C=i*p+s*_+E*m,w=n*T+o*y+c*R,P=a*T+u*y+l*R,x=i*T+s*y+E*R,L=n*A+o*v+c*S,U=a*A+u*v+l*S,b=i*A+s*v+E*S,F=n*N+o*I+c*M+f,D=a*N+u*I+l*M+h,B=i*N+s*I+E*M+d;return r[0]=O,r[1]=g,r[2]=C,r[3]=0,r[4]=w,r[5]=P,r[6]=x,r[7]=0,r[8]=L,r[9]=U,r[10]=b,r[11]=0,r[12]=F,r[13]=D,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=t[0],h=t[1],d=t[2],p=t[3],_=t[4],m=t[5],T=t[6],y=t[7],R=t[8],A=n*f+o*h+c*d,v=a*f+u*h+l*d,S=i*f+s*h+E*d,N=n*p+o*_+c*m,I=a*p+u*_+l*m,M=i*p+s*_+E*m,O=n*T+o*y+c*R,g=a*T+u*y+l*R,C=i*T+s*y+E*R;return r[0]=A,r[1]=v,r[2]=S,r[3]=0,r[4]=N,r[5]=I,r[6]=M,r[7]=0,r[8]=O,r[9]=g,r[10]=C,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=n*e[0]+a*e[4]+i*e[8]+e[12],u=n*e[1]+a*e[5]+i*e[9]+e[13],s=n*e[2]+a*e[6]+i*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var _=new e;l.multiplyByUniformScale=function(e,t,r){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,i=t.z;return 1===n&&1===a&&1===i?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=i*e[8],r[9]=i*e[9],r[10]=i*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*n+e[4]*a+e[8]*i+e[12]*o,s=e[1]*n+e[5]*a+e[9]*i+e[13]*o,c=e[2]*n+e[6]*a+e[10]*i+e[14]*o,l=e[3]*n+e[7]*a+e[11]*i+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i,u=e[1]*n+e[5]*a+e[9]*i,s=e[2]*n+e[6]*a+e[10]*i;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,i=t.z,o=e[0]*n+e[4]*a+e[8]*i+e[12],u=e[1]*n+e[5]*a+e[9]*i+e[13],s=e[2]*n+e[6]*a+e[10]*i+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var m=new s,T=new s,y=new t,R=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,m),T,u.EPSILON7)&&t.equals(l.getRow(e,3,y),R))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],i=e[8],o=e[12],E=e[1],f=e[5],h=e[9],d=e[13],p=e[2],_=e[6],A=e[10],v=e[14],S=e[3],N=e[7],I=e[11],M=e[15],O=A*M,g=v*I,C=_*M,w=v*N,P=_*I,x=A*N,L=p*M,U=v*S,b=p*I,F=A*S,D=p*N,B=_*S,z=O*f+w*h+P*d-(g*f+C*h+x*d),G=g*E+L*h+F*d-(O*E+U*h+b*d),V=C*E+U*f+D*d-(w*E+L*f+B*d),q=x*E+b*f+B*h-(P*E+F*f+D*h),X=g*a+C*i+x*o-(O*a+w*i+P*o),H=O*n+U*i+b*o-(g*n+L*i+F*o),W=w*n+L*a+B*o-(C*n+U*a+D*o),k=P*n+F*a+D*i-(x*n+b*a+B*i);O=i*d,g=o*h,C=a*d,w=o*f,P=a*h,x=i*f,L=n*d,U=o*E,b=n*h,F=i*E,D=n*f,B=a*E;var Y=O*N+w*I+P*M-(g*N+C*I+x*M),Z=g*S+L*I+F*M-(O*S+U*I+b*M),K=C*S+U*N+D*M-(w*S+L*N+B*M),j=x*S+b*N+B*I-(P*S+F*N+D*I),Q=C*A+x*v+g*_-(P*v+O*_+w*A),J=b*v+O*p+U*A-(L*A+F*v+g*p),$=L*_+B*v+w*p-(D*v+C*p+U*_),ee=D*A+P*p+F*_-(b*_+B*A+x*p),te=n*z+a*G+i*V+o*q;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=G*te,r[2]=V*te,r[3]=q*te,r[4]=X*te,r[5]=H*te,r[6]=W*te,r[7]=k*te,r[8]=Y*te,r[9]=Z*te,r[10]=K*te,r[11]=j*te,r[12]=Q*te,r[13]=J*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],E=e[12],f=e[13],h=e[14],d=-r*E-n*f-a*h,p=-i*E-o*f-u*h,_=-s*E-c*f-l*h;return t[0]=r,t[1]=i,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=d,t[13]=p,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),i=u.toRadians(r(i,0)),n(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(a,0),o.north=r(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,E=0,f=e.length;E<f;E++){var h=e[E];r=Math.min(r,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,d),o=Math.max(o,d)}return a-r>o-i&&(r=i,a=o,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=a,t.north=l,t):new s(r,c,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,E=-Number.MAX_VALUE,f=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0,p=e.length;d<p;d++){var _=t.cartesianToCartographic(e[d]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),f=Math.min(f,_.latitude),h=Math.max(h,_.latitude);var m=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,m),E=Math.max(E,m)}return c-o>E-l&&(o=l,c=E,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(a)?(a.west=o,a.south=f,a.east=c,a.north=h,a):new s(o,f,c,h)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),E=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&E<=l)){var f=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(f>=h))return n(r)?(r.west=l,r.south=f,r.east=E,r.north=h,r):new s(l,f,E,h)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return n(r)?(r.west=a,r.south=i,r.east=o,r.north=u,r):new s(a,i,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),E=u.convertLongitudeRange(Math.max(a,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=E,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<i||u.equalsEpsilon(r,i,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=r(t,i.WGS84),a=r(a,0),n(o)||(o=[]);var l=0,E=e.north,f=e.south,h=e.east,d=e.west,p=c;p.height=a,p.longitude=d,p.latitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=f,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=E<0?E:f>0?f:0;for(var _=1;_<8;++_)p.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,p)&&(o[l]=t.cartographicToCartesian(p,o[l]),l++);return 0===p.latitude&&(p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,i,o,u,s,c,l,E,f){"use strict";function h(t,r){this.center=e.clone(a(t,e.ZERO)),this.radius=a(r,0)}var d=new e,p=new e,_=new e,m=new e,T=new e,y=new e,R=new e,A=new e,v=new e,S=new e,N=new e,I=new e,M=4/3*r.PI;h.fromPoints=function(t,r){if(i(r)||(r=new h),!i(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,a=e.clone(t[0],R),o=e.clone(a,d),u=e.clone(a,p),s=e.clone(a,_),c=e.clone(a,m),l=e.clone(a,T),E=e.clone(a,y),f=t.length;for(n=1;n<f;n++){e.clone(t[n],a);var M=a.x,O=a.y,g=a.z;M<o.x&&e.clone(a,o),M>c.x&&e.clone(a,c),O<u.y&&e.clone(a,u),O>l.y&&e.clone(a,l),g<s.z&&e.clone(a,s),g>E.z&&e.clone(a,E)}var C=e.magnitudeSquared(e.subtract(c,o,A)),w=e.magnitudeSquared(e.subtract(l,u,A)),P=e.magnitudeSquared(e.subtract(E,s,A)),x=o,L=c,U=C;w>U&&(U=w,x=u,L=l),P>U&&(U=P,x=s,L=E);var b=v;b.x=.5*(x.x+L.x),b.y=.5*(x.y+L.y),b.z=.5*(x.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,A)),D=Math.sqrt(F),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=E.z;var G=e.multiplyByScalar(e.add(B,z,A),.5,I),V=0;for(n=0;n<f;n++){e.clone(t[n],a);var q=e.magnitude(e.subtract(a,G,A));q>V&&(V=q);var X=e.magnitudeSquared(e.subtract(a,b,A));if(X>F){var H=Math.sqrt(X);D=.5*(D+H),F=D*D;var W=H-D;b.x=(D*b.x+W*a.x)/H,b.y=(D*b.y+W*a.y)/H,b.z=(D*b.z+W*a.z)/H}}return D<V?(e.clone(b,r.center),r.radius=D):(e.clone(G,r.center),r.radius=V),r};var O=new u,g=new e,C=new e,w=new t,P=new t;h.fromRectangle2D=function(e,t,r){return h.fromRectangleWithHeights2D(e,t,0,0,r)},h.fromRectangleWithHeights2D=function(t,r,n,o,u){if(i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=a(r,O),f.southwest(t,w),w.height=n,f.northeast(t,P),P.height=o;var s=r.project(w,g),c=r.project(P,C),l=c.x-s.x,E=c.y-s.y,d=c.z-s.z;u.radius=.5*Math.sqrt(l*l+E*E+d*d);var p=u.center;return p.x=s.x+.5*l,p.y=s.y+.5*E,p.z=s.z+.5*d,u};var x=[];h.fromRectangle3D=function(t,r,n,u){if(r=a(r,o.WGS84),n=a(n,0),i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,r,n,x);return h.fromPoints(s,u)},h.fromVertices=function(t,r,n,o){if(i(o)||(o=new h),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=a(r,e.ZERO),n=a(n,3);var u=R;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,d),l=e.clone(u,p),E=e.clone(u,_),f=e.clone(u,m),M=e.clone(u,T),O=e.clone(u,y),g=t.length;for(s=0;s<g;s+=n){var C=t[s]+r.x,w=t[s+1]+r.y,P=t[s+2]+r.z;u.x=C,u.y=w,u.z=P,C<c.x&&e.clone(u,c),C>f.x&&e.clone(u,f),w<l.y&&e.clone(u,l),w>M.y&&e.clone(u,M),P<E.z&&e.clone(u,E),P>O.z&&e.clone(u,O)}var x=e.magnitudeSquared(e.subtract(f,c,A)),L=e.magnitudeSquared(e.subtract(M,l,A)),U=e.magnitudeSquared(e.subtract(O,E,A)),b=c,F=f,D=x;L>D&&(D=L,b=l,F=M),U>D&&(D=U,b=E,F=O);var B=v;B.x=.5*(b.x+F.x),B.y=.5*(b.y+F.y),B.z=.5*(b.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,A)),G=Math.sqrt(z),V=S;V.x=c.x,V.y=l.y,V.z=E.z;var q=N;q.x=f.x,q.y=M.y,q.z=O.z;var X=e.multiplyByScalar(e.add(V,q,A),.5,I),H=0;for(s=0;s<g;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var W=e.magnitude(e.subtract(u,X,A));W>H&&(H=W);var k=e.magnitudeSquared(e.subtract(u,B,A));if(k>z){var Y=Math.sqrt(k);G=.5*(G+Y),z=G*G;var Z=Y-G;B.x=(G*B.x+Z*u.x)/Y,B.y=(G*B.y+Z*u.y)/Y,B.z=(G*B.z+Z*u.z)/Y}}return G<H?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=H),o},h.fromEncodedCartesianVertices=function(t,r,n){if(i(n)||(n=new h),!i(t)||!i(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var a=R;a.x=t[0]+r[0],a.y=t[1]+r[1],a.z=t[2]+r[2];var o,u=e.clone(a,d),s=e.clone(a,p),c=e.clone(a,_),l=e.clone(a,m),E=e.clone(a,T),f=e.clone(a,y),M=t.length;for(o=0;o<M;o+=3){var O=t[o]+r[o],g=t[o+1]+r[o+1],C=t[o+2]+r[o+2];a.x=O,a.y=g,a.z=C,O<u.x&&e.clone(a,u),O>l.x&&e.clone(a,l),g<s.y&&e.clone(a,s),g>E.y&&e.clone(a,E),C<c.z&&e.clone(a,c),C>f.z&&e.clone(a,f)}var w=e.magnitudeSquared(e.subtract(l,u,A)),P=e.magnitudeSquared(e.subtract(E,s,A)),x=e.magnitudeSquared(e.subtract(f,c,A)),L=u,U=l,b=w;P>b&&(b=P,L=s,U=E),x>b&&(b=x,L=c,U=f);var F=v;F.x=.5*(L.x+U.x),F.y=.5*(L.y+U.y),F.z=.5*(L.z+U.z);var D=e.magnitudeSquared(e.subtract(U,F,A)),B=Math.sqrt(D),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var G=N;G.x=l.x,G.y=E.y,G.z=f.z;var V=e.multiplyByScalar(e.add(z,G,A),.5,I),q=0;for(o=0;o<M;o+=3){a.x=t[o]+r[o],a.y=t[o+1]+r[o+1],a.z=t[o+2]+r[o+2];var X=e.magnitude(e.subtract(a,V,A));X>q&&(q=X);var H=e.magnitudeSquared(e.subtract(a,F,A));if(H>D){var W=Math.sqrt(H);B=.5*(B+W),D=B*B;var k=W-B;F.x=(B*F.x+k*a.x)/W,F.y=(B*F.y+k*a.y)/W,F.z=(B*F.z+k*a.z)/W}}return B<q?(e.clone(F,n.center),n.radius=B):(e.clone(V,n.center),n.radius=q),n},h.fromCornerPoints=function(t,r,n){i(n)||(n=new h);var a=n.center;return e.add(t,r,a),e.multiplyByScalar(a,.5,a),n.radius=e.distance(a,r),n},h.fromEllipsoid=function(t,r){return i(r)||(r=new h),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var L=new e;h.fromBoundingSpheres=function(t,r){if(i(r)||(r=new h),!i(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return h.clone(t[0],r);if(2===n)return h.union(t[0],t[1],r);var a,o=[];for(a=0;a<n;a++)o.push(t[a].center);r=h.fromPoints(o,r);var u=r.center,s=r.radius;for(a=0;a<n;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,L)+c.radius)}return r.radius=s,r};var U=new e,b=new e,F=new e;h.fromOrientedBoundingBox=function(t,r){i(r)||(r=new h);var n=t.halfAxes,a=l.getColumn(n,0,U),o=l.getColumn(n,1,b),u=l.getColumn(n,2,F);return e.add(a,o,a),e.add(a,u,a),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(a),r},h.clone=function(t,r){if(i(t))return i(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,r){r=a(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},h.unpack=function(e,t,r){t=a(t,0),i(r)||(r=new h);var n=r.center;return n.x=e[t++],n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var D=new e,B=new e;h.union=function(t,r,n){i(n)||(n=new h);var a=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,a,D),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var E=.5*(o+l+s),f=e.multiplyByScalar(c,(-o+E)/l,B);return e.add(f,a,f),e.clone(f,n.center),n.radius=E,n};var z=new e;h.expand=function(t,r,n){n=h.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,z));return a>n.radius&&(n.radius=a),n},h.intersectPlane=function(t,r){var n=t.center,a=t.radius,i=r.normal,o=e.dot(i,n)+r.distance;return o<-a?s.OUTSIDE:o<a?s.INTERSECTING:s.INSIDE},h.transform=function(e,t,r){return i(r)||(r=new h),r.center=E.multiplyByPoint(t,e.center,r.center),r.radius=E.getMaximumScale(t)*e.radius,r};var G=new e;h.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,G);return e.magnitudeSquared(n)-t.radius*t.radius},h.transformWithoutScale=function(e,t,r){return i(r)||(r=new h),r.center=E.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var V=new e;h.computePlaneDistances=function(t,r,n,a){i(a)||(a=new c);var o=e.subtract(t.center,r,V),u=e.dot(n,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var q=new e,X=new e,H=new e,W=new e,k=new e,Y=new t,Z=new Array(8),K=0;K<8;++K)Z[K]=new e;var j=new u;return h.projectTo2D=function(t,r,n){r=a(r,j);var i=r.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,H);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var E=e.negate(l,k),f=e.negate(c,W),d=Z,p=d[0];e.add(s,l,p),e.add(p,c,p),p=d[1],e.add(s,l,p),e.add(p,f,p),p=d[2],e.add(s,E,p),e.add(p,f,p),p=d[3],e.add(s,E,p),e.add(p,c,p),e.negate(s,s),p=d[4],e.add(s,l,p),e.add(p,c,p),p=d[5],e.add(s,l,p),e.add(p,f,p),p=d[6],e.add(s,E,p),e.add(p,f,p),p=d[7],e.add(s,E,p),e.add(p,c,p);for(var _=d.length,m=0;m<_;++m){var T=d[m];e.add(o,T,T);var y=i.cartesianToCartographic(T,Y);r.project(y,T)}n=h.fromPoints(d,n),o=n.center;var R=o.x,A=o.y,v=o.z;return o.x=v,o.y=R,o.z=A,n},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,r){return t===r||i(t)&&i(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,r){return h.computePlaneDistances(this,e,t,r)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h.prototype.volume=function(){var e=this.radius;return M*e*e*e},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(A)&&(A=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,v=n(e[1]))}return A}function i(){return a()&&v}function o(){if(!t(S)&&(S=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=n(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(I)){I=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(I=!0, +M=n(e[1]),M.isNightly=!!e[2])}return I}function c(){return s()&&M}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,g=n(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,g=n(e[1]))}return O}function E(){return l()&&g}function f(){if(!t(C)){C=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,w=n(e[1]))}return C}function h(){return f()&&w}function d(){if(!t(P)){P=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(P=!0,x=n(e[1]))}return P}function p(){return t(L)||(L=/Windows/i.test(R.appVersion)),L}function _(){return d()&&x}function m(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),U}function T(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;F=t(r)&&""!==r,F&&(b=r)}return F}function y(){return T()?b:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,v,S,N,I,M,O,g,C,w,P,x,L,U,b,F,D={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:E,isEdge:f,edgeVersion:h,isFirefox:d,firefoxVersion:_,isWindows:p,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:m,supportsImageRenderingPixelated:T,imageRenderingValue:y};return D.supportsFullscreen=function(){return r.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,i){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,a);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case o.SHORT:return new Int16Array(r,n,a);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case o.INT:return new Int32Array(r,n,a);case o.UNSIGNED_INT:return new Uint32Array(r,n,a);case o.FLOAT:return new Float32Array(r,n,a);case o.DOUBLE:return new Float64Array(r,n,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,i){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new o),a.x=e[n++],a.y=e[n],a},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var a=0;a<n;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var a=0;a<n;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var E=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,E);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&i.equalsEpsilon(e.x,t.x,n,a)&&i.equalsEpsilon(e.y,t.y,n,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,a,i){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,a=r.y;r.x=(1-Math.abs(a))*i.signNotZero(n),r.y=(1-Math.abs(n))*i.signNotZero(a)}return r.x=i.toSNorm(r.x,t),r.y=i.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,a){if(a.x=i.fromSNorm(e,n),a.y=i.fromSNorm(r,n),a.z=1-(Math.abs(a.x)+Math.abs(a.y)),a.z<0){var o=a.x;a.x=(1-Math.abs(a.y))*i.signNotZero(o),a.y=(1-Math.abs(o))*i.signNotZero(a.y)}return t.normalize(a,a)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),a=256*(r-n);return u.octDecode(n,a,t)},u.octPack=function(e,t,r,n){var a=u.octEncodeFloat(e),i=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+a,n.y=65536*o.y+i,n},u.octUnpack=function(e,t,r,n){var a=e.x/65536,i=Math.floor(a),o=65536*(a-i);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(i,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var a=e.length,i=0,u=0,s=0,c=0;c<a;++c)i+=o(e[c]),u+=o(t[c]),e[c]=i,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function a(r,a,s,c,l){n(l)||(l=new t);var E,f,h,d,p,_,m,T;n(a.z)?(E=t.subtract(s,a,i),f=t.subtract(c,a,o),h=t.subtract(r,a,u),d=t.dot(E,E),p=t.dot(E,f),_=t.dot(E,h),m=t.dot(f,f),T=t.dot(f,h)):(E=e.subtract(s,a,i),f=e.subtract(c,a,o),h=e.subtract(r,a,u),d=e.dot(E,E),p=e.dot(E,f),_=e.dot(E,h),m=e.dot(f,f),T=e.dot(f,h));var y=1/(d*m-p*p);return l.y=(m*_-p*T)*y,l.z=(d*T-p*_)*y,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var a={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var i=t.high,o=t.low;return n.encode(e.x,a),i.x=a.high,o.x=a.low,n.encode(e.y,a),i.y=a.high,o.y=a.low,n.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,i);var a=i.high,o=i.low;t[r]=a.x,t[r+1]=a.y,t[r+2]=a.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var i;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-n/e,i<0?[i,0]:[0,i];var c=n*n,l=4*e*a,E=r(c,-l,t.EPSILON14);if(E<0)return[];var f=-.5*r(n,t.sign(n)*Math.sqrt(E),t.EPSILON14);return n>0?[f/e,a/f]:[a/f,f/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,i,o=e,u=t/3,s=r/3,c=n,l=o*s,E=u*c,f=u*u,h=s*s,d=o*s-f,p=o*c-u*s,_=u*c-h,m=4*d*_-p*p;if(m<0){var T,y,R;f*E>=l*h?(T=o,y=d,R=-2*u*d+o*p):(T=c,y=_,R=-c*p+2*s*_);var A=R<0?-1:1,v=-A*Math.abs(T)*Math.sqrt(-m);i=-R+v;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),I=i===v?-N:-y/N;return a=y<=0?N+I:-R/(N*N+I*I+y),f*E>=l*h?[(a-u)/o]:[-c/(a+s)]}var M=d,O=-2*u*d+o*p,g=_,C=-c*p+2*s*_,w=Math.sqrt(m),P=Math.sqrt(3)/2,x=Math.abs(Math.atan2(o*w,-O)/3);a=2*Math.sqrt(-M);var L=Math.cos(x);i=a*L;var U=a*(-L/2-P*Math.sin(x)),b=i+U>2*u?i-u:U-u,F=o,D=b/F;x=Math.abs(Math.atan2(c*w,-C)/3),a=2*Math.sqrt(-g),L=Math.cos(x),i=a*L,U=a*(-L/2-P*Math.sin(x));var B=-c,z=i+U<2*s?i+s:U+s,G=B/z,V=F*z,q=-b*z-F*B,X=b*B,H=(s*q-u*X)/(-u*q+s*V);return D<=H?D<=G?H<=G?[D,H,G]:[D,G,H]:[G,D,H]:D<=G?[H,D,G]:H<=G?[H,G,D]:[G,H,D]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,i=t*t,o=r*r;return 18*e*t*r*n+i*o-27*a*(n*n)-4*(e*o*r+i*t*n)},n.computeRealRoots=function(e,n,a,i){var o,u;if(0===e)return t.computeRealRoots(n,a,i);if(0===n){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,a,i)}return 0===a?0===i?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,i):0===i?(o=t.computeRealRoots(e,n,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,a,i)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,E=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(E.length>0){var f=-t/4,h=E[E.length-1];if(Math.abs(h)<r.EPSILON14){var d=n.computeRealRoots(1,s,l);if(2===d.length){var p,_=d[0],m=d[1];if(_>=0&&m>=0){var T=Math.sqrt(_),y=Math.sqrt(m);return[f-y,f-T,f+T,f+y]}if(_>=0&&m<0)return p=Math.sqrt(_),[f-p,f+p];if(_<0&&m>=0)return p=Math.sqrt(m),[f-p,f+p]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,v=(s+h+c/R)/2,S=n.computeRealRoots(1,R,A),N=n.computeRealRoots(1,-R,v);return 0!==S.length?(S[0]+=f,S[1]+=f,0!==N.length?(N[0]+=f,N[1]+=f,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=f,N[1]+=f,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,E=i*t+s-4*o,f=c*o-i*a*t+u,h=e.computeRealRoots(1,l,E,f);if(h.length>0){var d,p,_=h[0],m=a-_,T=m*m,y=t/2,R=m/2,A=T-4*o,v=T+4*Math.abs(o),S=c-4*_,N=c+4*Math.abs(_);if(_<0||A*N<S*v){var I=Math.sqrt(S);d=I/2,p=0===I?0:(t*R-i)/I}else{var M=Math.sqrt(A);d=0===M?0:(t*R-i)/M,p=M/2}var O,g;0===y&&0===d?(O=0,g=0):r.sign(y)===r.sign(d)?(O=y+d,g=_/O):(g=y-d,O=_/g);var C,w;0===R&&0===p?(C=0,w=0):r.sign(R)===r.sign(p)?(C=R+p,w=o/C):(w=R-p,C=o/w);var P=n.computeRealRoots(1,O,C),x=n.computeRealRoots(1,g,w);if(0!==P.length)return 0!==x.length?P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>x[0]&&P[0]<x[1]?[x[0],P[0],x[1],P[1]]:[P[0],x[0],P[1],x[1]]:P;if(0!==x.length)return x}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=r*r,l=c*r,E=n*n,f=E*n,h=a*a;return u*c*E-4*s*f-4*e*l*E+18*e*t*r*f-27*i*E*E+256*o*(h*a)+a*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*E+144*i*r*E)+h*(144*e*u*r-27*u*u-128*i*c-192*i*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,E=u/t,f=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=E<0?h+1:h,h+=f<0?h+1:h){case 0:return a(c,l,E,f);case 1:case 2:return i(c,l,E,f);case 3:case 4:return a(c,l,E,f);case 5:return i(c,l,E,f);case 6:case 7:return a(c,l,E,f);case 8:return i(c,l,E,f);case 9:case 10:return a(c,l,E,f);case 11:return i(c,l,E,f);case 12:case 13:case 14:case 15:return a(c,l,E,f);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,i,o,u,s,c,l){"use strict";function E(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function f(t,r,a){n(a)||(a=new i);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,T),f=e.dot(u,u),h=2*e.dot(u,l),d=e.magnitudeSquared(l)-c,p=E(f,h,d,v);if(n(p))return a.start=p.root0, +a.stop=p.root1,a}function h(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function d(t,r,n,a,i){var l,E=a*a,f=i*i,d=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,p=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),_=t[u.COLUMN0ROW0]*E+t[u.COLUMN2ROW2]*f+a*r.x+n,m=f*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),T=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),y=[];if(0===T&&0===m){if(l=s.computeRealRoots(d,p,_),0===l.length)return y;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(y.push(new e(a,i*R,i*-A)),y.push(new e(a,i*R,i*A)),2===l.length){var v=l[1],S=Math.sqrt(Math.max(1-v*v,0));y.push(new e(a,i*v,i*-S)),y.push(new e(a,i*v,i*S))}return y}var N=T*T,I=m*m,M=d*d,O=T*m,g=M+I,C=2*(p*d+O),w=2*_*d+p*p-I+N,P=2*(_*p-O),x=_*_-N;if(0===g&&0===C&&0===w&&0===P)return y;l=c.computeRealRoots(g,C,w,P,x);var L=l.length;if(0===L)return y;for(var U=0;U<L;++U){var b,F=l[U],D=F*F,B=Math.max(1-D,0),z=Math.sqrt(B);b=o.sign(d)===o.sign(_)?h(d*D+_,p*F,o.EPSILON12):o.sign(_)===o.sign(p*F)?h(d*D,p*F+_,o.EPSILON12):h(d*D+p*F,_,o.EPSILON12);var G=h(m*F,T,o.EPSILON15),V=b*G;V<0?y.push(new e(a,i*F,i*z)):V>0?y.push(new e(a,i*F,i*-z)):0!==z?(y.push(new e(a,i*F,i*-z)),y.push(new e(a,i*F,i*z)),++U):y.push(new e(a,i*F,i*z))}return y}var p={};p.rayPlane=function(t,r,a){n(a)||(a=new e);var i=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,m=new e,T=new e,y=new e,R=new e;p.rayTriangleParametric=function(t,n,a,i,u){u=r(u,!1);var s,c,l,E,f,h=t.origin,d=t.direction,p=e.subtract(a,n,_),A=e.subtract(i,n,m),v=e.cross(d,A,T),S=e.dot(p,v);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,n,y),(l=e.dot(s,v))<0||l>S)return;if(c=e.cross(s,p,R),(E=e.dot(d,c))<0||l+E>S)return;f=e.dot(A,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,n,y),(l=e.dot(s,v)*N)<0||l>1)return;if(c=e.cross(s,p,R),(E=e.dot(d,c)*N)<0||l+E>1)return;f=e.dot(A,c)*N}return f},p.rayTriangle=function(t,r,a,i,o,u){var s=p.rayTriangleParametric(t,r,a,i,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;p.lineSegmentTriangle=function(t,r,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=p.rayTriangleParametric(c,a,i,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var v={root0:0,root1:0};p.raySphere=function(e,t,r){if(r=f(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;p.lineSegmentSphere=function(t,r,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=f(o,a,i),!(!n(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,I=new e;p.rayEllipsoid=function(t,r){var n,a,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),E=e.multiplyComponents(c,t.direction,I),f=e.magnitudeSquared(l),h=e.dot(l,E);if(f>1){if(h>=0)return;var d=h*h;if(n=f-1,a=e.magnitudeSquared(E),o=a*n,d<o)return;if(d>o){u=h*h-o,s=-h+Math.sqrt(u);var p=s/a,_=n/s;return p<_?new i(p,_):{start:_,stop:p}}var m=Math.sqrt(n/a);return new i(m,m)}return f<1?(n=f-1,a=e.magnitudeSquared(E),o=a*n,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(E),new i(0,-h/a)):void 0};var M=new e,O=new e,g=new e,C=new e,w=new e,P=new u,x=new u,L=new u,U=new u,b=new u,F=new u,D=new u,B=new e,z=new e,G=new t;p.grazingAltitudeLocation=function(t,r){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,M);if(e.dot(i,s)>=0)return a}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(i,M),E=e.normalize(l,l),f=e.mostOrthogonalAxis(l,C),h=e.normalize(e.cross(f,E,O),O),p=e.normalize(e.cross(E,h,g),g),_=P;_[0]=E.x,_[1]=E.y,_[2]=E.z,_[3]=h.x,_[4]=h.y,_[5]=h.z,_[6]=p.x,_[7]=p.y,_[8]=p.z;var m=u.transpose(_,x),T=u.fromScale(r.radii,L),y=u.fromScale(r.oneOverRadii,U),R=b;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,v,S=u.multiply(u.multiply(m,y,F),R,F),N=u.multiply(u.multiply(S,T,D),_,D),I=u.multiplyByVector(S,a,w),V=d(N,e.negate(I,M),0,0,1),q=V.length;if(q>0){for(var X=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,W=0;W<q;++W){A=u.multiplyByVector(T,u.multiplyByVector(_,V[W],B),B);var k=e.normalize(e.subtract(A,a,C),C),Y=e.dot(k,i);Y>H&&(H=Y,X=e.clone(A,X))}var Z=r.cartesianToCartographic(X,G);return H=o.clamp(H,0,1),v=e.magnitude(e.subtract(X,a,C))*Math.sqrt(1-H*H),v=c?-v:v,Z.height=v,r.cartographicToCartesian(Z,new e)}};var V=new e;return p.lineSegmentPlane=function(t,r,a,i){n(i)||(i=new e);var u=e.subtract(r,t,V),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),E=-(a.distance+l)/c;if(!(E<0||E>1))return e.multiplyByScalar(u,E,i),e.add(t,i,i),i}},p.trianglePlaneIntersection=function(t,r,n,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,r)+o<0,c=e.dot(i,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var E,f;if(1!==l&&2!==l||(E=new e,f=new e),1===l){if(u)return p.lineSegmentPlane(t,r,a,E),p.lineSegmentPlane(t,n,a,f),{positions:[t,r,n,E,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return p.lineSegmentPlane(r,n,a,E),p.lineSegmentPlane(r,t,a,f),{positions:[t,r,n,E,f],indices:[1,3,4,2,0,4,2,4,3]};if(c)return p.lineSegmentPlane(n,t,a,E),p.lineSegmentPlane(n,r,a,f),{positions:[t,r,n,E,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return p.lineSegmentPlane(r,t,a,E),p.lineSegmentPlane(n,t,a,f),{positions:[t,r,n,E,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return p.lineSegmentPlane(n,r,a,E),p.lineSegmentPlane(t,r,a,f),{positions:[t,r,n,E,f],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return p.lineSegmentPlane(t,n,a,E),p.lineSegmentPlane(r,n,a,f),{positions:[t,r,n,E,f],indices:[0,1,4,0,4,3,2,3,4]}}},p}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,i,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var i=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=i,a):new u(n,i)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),i=t.w;return r(n)?(e.clone(a,n.normal),n.distance=i,n):new u(a,i)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,a){r(a)||(a=new e);var i=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,i,c);return e.subtract(n,o,a)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,a=r.maximumIndex,i=e(r.cacheSize,24),o=n.length;if(!t(a)){a=0;for(var u=0,s=n[u];u<o;)s>a&&(a=s),++u,s=n[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var E=i+1,f=0;f<o;++f)E-c[n[f]]>i&&(c[n[f]]=E,++E);return(E-i+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<n;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}r=e(r,e.EMPTY_OBJECT);var a,i=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=i.length,c=0,l=0,E=i[l],f=s;if(t(o))c=o+1;else{for(;l<f;)E>c&&(c=E),++l,E=i[l];if(-1===c)return 0;++c}var h,d=[];for(h=0;h<c;h++)d[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var p=0;l<f;)d[i[l]].vertexTriangles.push(p),++d[i[l]].numLiveTriangles,d[i[l+1]].vertexTriangles.push(p),++d[i[l+1]].numLiveTriangles,d[i[l+2]].vertexTriangles.push(p),++d[i[l+2]].numLiveTriangles,++p,l+=3;var _=0,m=u+1;a=1;var T,y,R=[],A=[],v=0,S=[],N=s/3,I=[];for(h=0;h<N;h++)I[h]=!1;for(var M,O;-1!==_;){R=[],y=d[_],O=y.vertexTriangles.length;for(var g=0;g<O;++g)if(p=y.vertexTriangles[g],!I[p]){I[p]=!0,l=p+p+p;for(var C=0;C<3;++C)M=i[l],R.push(M),A.push(M),S[v]=M,++v,T=d[M],--T.numLiveTriangles,m-T.timeStamp>u&&(T.timeStamp=m,++m),++l}_=function(e,t,r,a,i,o,u){for(var s,c=-1,l=-1,E=0;E<r.length;){var f=r[E];a[f].numLiveTriangles&&(s=0,i-a[f].timeStamp+2*a[f].numLiveTriangles<=t&&(s=i-a[f].timeStamp),(s>l||-1===l)&&(l=s,c=f)),++E}return-1===c?n(a,o,e,u):c}(i,u,R,d,m,A,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h,d,p,_,m,T,y,R,A,v,S,N){"use strict";function I(e,t,r,n,a){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=a,e[t++]=a,e[t]=r}function M(e){for(var t=e.length,r=t/3*6,n=_.createTypedArray(t,r),a=0,i=0;i<t;i+=3,a+=6)I(n,a,e[i],e[i+1],e[i+2]);return n}function O(e){var t=e.length;if(t>=3){var r=6*(t-2),n=_.createTypedArray(t,r);I(n,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)I(n,a,e[i-1],e[i],e[i-2]);return n}return new Uint16Array}function g(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=_.createTypedArray(t,r),a=e[0],i=0,o=1;o<t;++o,i+=6)I(n,i,a,e[o],e[o+1]);return n}return new Uint16Array}function C(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new d({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function w(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var a=t[n],i=0;i<a.componentsPerAttribute;++i)e[n].values.push(a.values[r*a.componentsPerAttribute+i])}function P(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),A.multiplyByPoint(e,ie,ie),a.pack(ie,r,i)}function x(e,t){if(c(t))for(var r=t.values,n=r.length,i=0;i<n;i+=3)a.unpack(r,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,r,i)}function L(e,t){var r,n=e.length,a={},i=e[0][t].attributes;for(r in i)if(i.hasOwnProperty(r)&&c(i[r])&&c(i[r].values)){for(var o=i[r],s=o.values.length,l=!0,E=1;E<n;++E){var f=e[E][t].attributes[r];if(!c(f)||o.componentDatatype!==f.componentDatatype||o.componentsPerAttribute!==f.componentsPerAttribute||o.normalize!==f.normalize){l=!1;break}s+=f.values.length}l&&(a[r]=new d({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function U(e,t){var n,i,o,u,s,l,E,f=e.length,d=(e[0].modelMatrix,c(e[0][t].indices)),p=e[0][t].primitiveType,m=L(e,t);for(n in m)if(m.hasOwnProperty(n))for(s=m[n].values,u=0,i=0;i<f;++i)for(l=e[i][t].attributes[n].values,E=l.length,o=0;o<E;++o)s[u++]=l[o];var T;if(d){var y=0;for(i=0;i<f;++i)y+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:m,primitiveType:S.POINTS})),A=_.createTypedArray(R,y),v=0,N=0;for(i=0;i<f;++i){var I=e[i][t].indices,M=I.length;for(u=0;u<M;++u)A[v++]=N+I[u];N+=h.computeNumberOfVertices(e[i][t])}T=A}var O,g=new a,C=0;for(i=0;i<f;++i){if(O=e[i][t].boundingSphere,!c(O)){g=void 0;break}a.add(O.center,g,g)}if(c(g))for(a.divideByScalar(g,f,g),i=0;i<f;++i){O=e[i][t].boundingSphere;var w=a.magnitude(a.subtract(O.center,g,se))+O.radius;w>C&&(C=w)}return new h({attributes:m,indices:T,primitiveType:p,boundingSphere:c(g)?new r(g,C):void 0})}function b(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function F(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,a=3;a<t;++a)r[n++]=a-1,r[n++]=0,r[n++]=a;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function D(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,a=3;a<t-1;a+=2)r[n++]=a,r[n++]=a-1,r[n++]=a+1,a+2<t&&(r[n++]=a,r[n++]=a+1,r[n++]=a+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return e.indices=r,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),r=_.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,a=2;a<t;++a)r[n++]=a-1,r[n++]=a;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function V(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return F(e);case S.TRIANGLE_STRIP:return D(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function q(e,t){Math.abs(e.y)<y.EPSILON6&&(e.y=t?-y.EPSILON6:y.EPSILON6)}function X(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return q(e,e.y<0),q(t,t.y<0),void q(r,r.y<0);var n,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(r.y);n=a>i?a>o?y.sign(e.y):y.sign(r.y):i>o?y.sign(t.y):y.sign(r.y);var u=n<0;q(e,u),q(t,u),q(r,u)}function H(e,t,r,n){a.add(e,a.multiplyByScalar(a.subtract(t,e,Ae),e.y/(e.y-t.y),Ae),r),a.clone(r,n),q(r,!0),q(n,!1)}function W(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){X(e,t,r);var n=e.y<0,a=t.y<0,i=r.y<0,o=0;o+=n?1:0,o+=a?1:0,o+=i?1:0;var u=Me.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?a?i||(H(r,e,ve,Ne),H(r,t,Se,Ie),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(H(t,r,ve,Ne),H(t,e,Se,Ie),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(H(e,t,ve,Ne),H(e,r,Se,Ie),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Me.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=ve,s[4]=Se,s[5]=Ne,s[6]=Ie,s.length=7),Me}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var a in n)if(n.hasOwnProperty(a)&&c(n[a])&&c(n[a].values)){var i=n[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=_.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var a=t[n];r[n]=new d({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:r,indices:[],primitiveType:e.primitiveType})}function Z(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function K(e,r,i,o,u,s,l,E,f,h,d,p){if(c(s)||c(l)||c(E)||c(f)||c(h)){var _=a.fromArray(u,3*e,Oe),m=a.fromArray(u,3*r,ge),T=a.fromArray(u,3*i,Ce),y=t(o,_,m,T,we);if(c(s)){var R=a.fromArray(s,3*e,Oe),A=a.fromArray(s,3*r,ge),v=a.fromArray(s,3*i,Ce);a.multiplyByScalar(R,y.x,R),a.multiplyByScalar(A,y.y,A),a.multiplyByScalar(v,y.z,v);var S=a.add(R,A,R);a.add(S,v,S),a.normalize(S,S),a.pack(S,d.normal.values,3*p)}if(c(h)){var N=a.fromArray(h,3*e,Oe),I=a.fromArray(h,3*r,ge),M=a.fromArray(h,3*i,Ce);a.multiplyByScalar(N,y.x,N),a.multiplyByScalar(I,y.y,I),a.multiplyByScalar(M,y.z,M);var O;a.equals(N,a.ZERO)&&a.equals(I,a.ZERO)&&a.equals(M,a.ZERO)?(O=Oe,O.x=0,O.y=0,O.z=0):(O=a.add(N,I,N),a.add(O,M,O),a.normalize(O,O)),a.pack(O,d.extrudeDirection.values,3*p)}if(c(l)){var g=a.fromArray(l,3*e,Oe),C=a.fromArray(l,3*r,ge),w=a.fromArray(l,3*i,Ce);a.multiplyByScalar(g,y.x,g),a.multiplyByScalar(C,y.y,C),a.multiplyByScalar(w,y.z,w);var P=a.add(g,C,g);a.add(P,w,P),a.normalize(P,P),a.pack(P,d.tangent.values,3*p)}if(c(E)){var x=a.fromArray(E,3*e,Oe),L=a.fromArray(E,3*r,ge),U=a.fromArray(E,3*i,Ce);a.multiplyByScalar(x,y.x,x),a.multiplyByScalar(L,y.y,L),a.multiplyByScalar(U,y.z,U);var b=a.add(x,L,x);a.add(b,U,b),a.normalize(b,b),a.pack(b,d.bitangent.values,3*p)}if(c(f)){var F=n.fromArray(f,2*e,Pe),D=n.fromArray(f,2*r,xe),B=n.fromArray(f,2*i,Le);n.multiplyByScalar(F,y.x,F),n.multiplyByScalar(D,y.y,D),n.multiplyByScalar(B,y.z,B);var z=n.add(F,D,F);n.add(z,B,z),n.pack(z,d.st.values,2*p)}}}function j(e,t,r,n,a,i){var o=e.position.values.length/3;if(-1!==a){var u=n[a],s=r[u];return-1===s?(r[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function Q(e){var t,r,n,i,o,u=e.geometry,s=u.attributes,l=s.position.values,E=c(s.normal)?s.normal.values:void 0,f=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,d=c(s.st)?s.st.values:void 0,p=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,_=u.indices,m=Y(u),T=Y(u),y=[];y.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<y.length;++o)y[o]=-1,R[o]=-1;var A=_.length;for(o=0;o<A;o+=3){var v=_[o],S=_[o+1],N=_[o+2],I=a.fromArray(l,3*v),M=a.fromArray(l,3*S),O=a.fromArray(l,3*N),g=W(I,M,O);if(c(g)&&g.positions.length>3)for(var C=g.positions,w=g.indices,P=w.length,x=0;x<P;++x){var L=w[x],U=C[L];U.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,_,L<3?o+L:-1,U),K(v,S,N,U,l,E,h,f,d,p,t,i)}else c(g)&&(I=g.positions[0],M=g.positions[1],O=g.positions[2]),I.y<0?(t=T.attributes,r=T.indices,n=y):(t=m.attributes,r=m.indices,n=R),i=j(t,r,n,_,o,I),K(v,S,N,I,l,E,h,f,d,p,t,i),i=j(t,r,n,_,o+1,M),K(v,S,N,M,l,E,h,f,d,p,t,i),i=j(t,r,n,_,o+2,O),K(v,S,N,O,l,E,h,f,d,p,t,i)}Z(e,T,m)}function J(e){var t,r=e.geometry,n=r.attributes,i=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,E=[];E.length=i.length/3;var f=[];for(f.length=i.length/3,t=0;t<E.length;++t)E[t]=-1,f[t]=-1;for(t=0;t<l;t+=2){var h=o[t],d=o[t+1],p=a.fromArray(i,3*h,Oe),_=a.fromArray(i,3*d,ge);Math.abs(p.y)<y.EPSILON6&&(p.y<0?p.y=-y.EPSILON6:p.y=y.EPSILON6),Math.abs(_.y)<y.EPSILON6&&(_.y<0?_.y=-y.EPSILON6:_.y=y.EPSILON6);var m=u.attributes,R=u.indices,A=f,v=s.attributes,S=s.indices,N=E,I=T.lineSegmentPlane(p,_,Ue,Ce);if(c(I)){var M=a.multiplyByScalar(a.UNIT_Y,5*y.EPSILON9,be);p.y<0&&(a.negate(M,M),m=s.attributes,R=s.indices,A=E,v=u.attributes,S=u.indices,N=f);var O=a.add(I,M,Fe);j(m,R,A,o,t,p),j(m,R,A,o,-1,O),a.negate(M,M),a.add(I,M,O),j(v,S,N,o,-1,O),j(v,S,N,o,t+1,_)}else{var g,C,w;p.y<0?(g=s.attributes,C=s.indices,w=E):(g=u.attributes,C=u.indices,w=f),j(g,C,w,o,t,p),j(g,C,w,o,t+1,_)}}Z(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,i=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=a.unpack(r,u,ze);if(!(s.x>0)){var c=a.unpack(n,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):a.pack(s,n,u));var l=a.unpack(i,u,Ve);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=r[u+3],i[u+1]=r[u+4],i[u+2]=r[u+5]):a.pack(s,i,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,E=s.prevPosition.values,f=s.nextPosition.values,h=s.expandAndWidth.values,d=c(s.st)?s.st.values:void 0,p=c(s.color)?s.color.values:void 0,_=Y(u),m=Y(u),R=!1,A=l.length/3;for(t=0;t<A;t+=4){var v=t,S=t+2,N=a.fromArray(l,3*v,ze),I=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<Ye)for(N.y=Ye*(I.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,r=3*v;r<3*v+12;r+=3)E[r]=l[3*t],E[r+1]=l[3*t+1],E[r+2]=l[3*t+2];if(Math.abs(I.y)<Ye)for(I.y=Ye*(N.y<0?-1:1),l[3*(t+2)+1]=I.y,l[3*(t+3)+1]=I.y,r=3*v;r<3*v+12;r+=3)f[r]=l[3*(t+2)],f[r+1]=l[3*(t+2)+1],f[r+2]=l[3*(t+2)+2];var M=_.attributes,O=_.indices,g=m.attributes,C=m.indices,w=T.lineSegmentPlane(N,I,Ue,qe);if(c(w)){R=!0;var P=a.multiplyByScalar(a.UNIT_Y,ke,Xe);N.y<0&&(a.negate(P,P),M=m.attributes,O=m.indices,g=_.attributes,C=_.indices);var x=a.add(w,P,He);M.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.position.values.push(x.x,x.y,x.z),M.position.values.push(x.x,x.y,x.z),M.prevPosition.values.push(E[3*v],E[3*v+1],E[3*v+2]),M.prevPosition.values.push(E[3*v+3],E[3*v+4],E[3*v+5]),M.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),M.nextPosition.values.push(x.x,x.y,x.z),a.negate(P,P),a.add(w,P,x),g.position.values.push(x.x,x.y,x.z),g.position.values.push(x.x,x.y,x.z),g.position.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.prevPosition.values.push(x.x,x.y,x.z),g.nextPosition.values.push(I.x,I.y,I.z,I.x,I.y,I.z),g.nextPosition.values.push(f[3*S],f[3*S+1],f[3*S+2]),g.nextPosition.values.push(f[3*S+3],f[3*S+4],f[3*S+5]);var L=n.fromArray(h,2*v,De),U=Math.abs(L.y);M.expandAndWidth.values.push(-1,U,1,U),M.expandAndWidth.values.push(-1,-U,1,-U),g.expandAndWidth.values.push(-1,U,1,U),g.expandAndWidth.values.push(-1,-U,1,-U);var b=a.magnitudeSquared(a.subtract(w,N,Ve));if(b/=a.magnitudeSquared(a.subtract(I,N,Ve)),c(p)){var F=i.fromArray(p,4*v,We),D=i.fromArray(p,4*S,We),B=y.lerp(F.x,D.x,b),z=y.lerp(F.y,D.y,b),G=y.lerp(F.z,D.z,b),V=y.lerp(F.w,D.w,b);for(r=4*v;r<4*v+8;++r)M.color.values.push(p[r]);for(M.color.values.push(B,z,G,V),M.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),g.color.values.push(B,z,G,V),r=4*S;r<4*S+8;++r)g.color.values.push(p[r])}if(c(d)){var q=n.fromArray(d,2*v,De),X=n.fromArray(d,2*(t+3),Be),H=y.lerp(q.x,X.x,b);for(r=2*v;r<2*v+4;++r)M.st.values.push(d[r]);for(M.st.values.push(H,q.y),M.st.values.push(H,X.y),g.st.values.push(H,q.y),g.st.values.push(H,X.y),r=2*S;r<2*S+4;++r)g.st.values.push(d[r])}o=M.position.values.length/3-4,O.push(o,o+2,o+1),O.push(o+1,o+2,o+3),o=g.position.values.length/3-4,C.push(o,o+2,o+1),C.push(o+1,o+2,o+3)}else{var W,k;for(N.y<0?(W=m.attributes,k=m.indices):(W=_.attributes,k=_.indices),W.position.values.push(N.x,N.y,N.z),W.position.values.push(N.x,N.y,N.z),W.position.values.push(I.x,I.y,I.z),W.position.values.push(I.x,I.y,I.z),r=3*t;r<3*t+12;++r)W.prevPosition.values.push(E[r]),W.nextPosition.values.push(f[r]);for(r=2*t;r<2*t+8;++r)W.expandAndWidth.values.push(h[r]),c(d)&&W.st.values.push(d[r]);if(c(p))for(r=4*t;r<4*t+16;++r)W.color.values.push(p[r]);o=W.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}R&&($(m),$(_)),Z(e,m,_)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=M(t);break;case S.TRIANGLE_STRIP:e.indices=O(t);break;case S.TRIANGLE_FAN:e.indices=g(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),E=0,f=0;f<o;f+=3)l[E++]=a[f],l[E++]=a[f+1],l[E++]=a[f+2],l[E++]=a[f]+i[f]*n,l[E++]=a[f+1]+i[f+1]*n,l[E++]=a[f+2]+i[f+2]*n;var p,_=e.boundingSphere;return c(_)&&(p=new r(_.center,_.radius+n)),new h({attributes:{position:new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:p})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,a={},i=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(a[u]=i++)}for(var s in n)n.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),a=0;a<t;a++)n[a]=-1;for(var i,o=r,s=o.length,l=_.createTypedArray(t,s),E=0,f=0,d=0;E<s;)i=n[o[E]],-1!==i?l[f]=i:(i=o[E],n[i]=d,l[f]=d,++d),++E,++f;e.indices=l;var p=e.attributes;for(var m in p)if(p.hasOwnProperty(m)&&c(p[m])&&c(p[m].values)){for(var T=p[m],y=T.values,R=0,A=T.componentsPerAttribute,v=u.createTypedArray(T.componentDatatype,d*A);R<t;){var S=n[R];if(-1!==S)for(var N=0;N<A;N++)v[A*S+N]=y[A*R+N];++R}T.values=v}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,a=0,i=0;i<n;i++)r[i]>a&&(a=r[i]);e.indices=N.tipsify({indices:r,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=h.computeNumberOfVertices(e);if(c(e.indices)&&r>=y.SIXTY_FOUR_KILOBYTES){var n,a=[],i=[],o=0,u=C(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var E=0;E<l;E+=n){for(var f=0;f<n;++f){var d=s[E+f],p=a[d];c(p)||(p=o++,a[d]=p,w(u,e.attributes,d)),i.push(p)}o+n>=y.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=C(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new a,ne=new o;te.projectTo2D=function(e,t,r,n,i){var o=e.attributes[t];i=c(i)?i:new f;for(var s=i.ellipsoid,l=o.values,E=new Float64Array(l.length),h=0,p=0;p<l.length;p+=3){var _=a.fromArray(l,p,re),m=s.cartesianToCartographic(_,ne),T=i.project(m,re);E[h++]=T.x,E[h++]=T.y,E[h++]=T.z}return e.attributes[r]=o,e.attributes[n]=new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:E}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)E.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var f=a.componentsPerAttribute;return e.attributes[r]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:s}),e.attributes[n]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:c}),delete e.attributes[t],e};var ie=new a,oe=new A,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(A.equals(t,A.IDENTITY))return e;var n=e.geometry.attributes;P(t,n.position),P(t,n.prevPosition),P(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(A.inverse(t,oe),A.transpose(oe,oe),A.getRotation(oe,ue),x(ue,n.normal),x(ue,n.tangent),x(ue,n.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=r.transform(a,t,a)),e.modelMatrix=A.clone(A.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,a=0;a<n;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&r.push(i)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,Ee=new a,fe=new a;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,i=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),E=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var f=0;for(t=0;t<s;t+=3){var h=r[t],p=r[t+1],_=r[t+2],m=3*h,T=3*p,R=3*_;le.x=i[m],le.y=i[m+1],le.z=i[m+2],Ee.x=i[T],Ee.y=i[T+1],Ee.z=i[T+2],fe.x=i[R],fe.y=i[R+1],fe.z=i[R+2],c[h].count++,c[p].count++,c[_].count++,a.subtract(Ee,le,Ee),a.subtract(fe,le,fe),l[f]=a.cross(Ee,fe,new a),f++}var A=0;for(t=0;t<o;t++)c[t].indexOffset+=A,A+=c[t].count;f=0;var v;for(t=0;t<s;t+=3){v=c[r[t]];var S=v.indexOffset+v.currentCount;E[S]=f,v.currentCount++,v=c[r[t+1]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,v=c[r[t+2]],S=v.indexOffset+v.currentCount,E[S]=f,v.currentCount++,f++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var I=3*t;if(v=c[t],a.clone(a.ZERO,ce),v.count>0){for(f=0;f<v.count;f++)a.add(ce,l[E[v.indexOffset+f]],ce);a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&a.clone(l[E[v.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,y.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[I]=ce.x,N[I+1]=ce.y,N[I+2]=ce.z}return e.attributes.normal=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,de=new a,pe=new a;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var E,f,h;for(t=0;t<c;t+=3){var p=r[t],_=r[t+1],m=r[t+2];E=3*p,f=3*_,h=3*m;var T=2*p,y=2*_,R=2*m,A=n[E],v=n[E+1],S=n[E+2],N=o[T],I=o[T+1],M=o[y+1]-I,O=o[R+1]-I,g=1/((o[y]-N)*O-(o[R]-N)*M),C=(O*(n[f]-A)-M*(n[h]-A))*g,w=(O*(n[f+1]-v)-M*(n[h+1]-v))*g,P=(O*(n[f+2]-S)-M*(n[h+2]-S))*g;l[E]+=C,l[E+1]+=w,l[E+2]+=P,l[f]+=C,l[f+1]+=w,l[f+2]+=P,l[h]+=C,l[h+1]+=w,l[h+2]+=P}var x=new Float32Array(3*s),L=new Float32Array(3*s);for(t=0;t<s;t++){E=3*t,f=E+1,h=E+2;var U=a.fromArray(i,E,he),b=a.fromArray(l,E,pe),F=a.dot(U,b);a.multiplyByScalar(U,F,de),a.normalize(a.subtract(b,de,b),b),x[E]=b.x,x[f]=b.y,x[h]=b.z,a.normalize(a.cross(U,b,b),b),L[E]=b.x,L[f]=b.y,L[h]=b.z}return e.attributes.tangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:x}),e.attributes.bitangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:L}),e};var _e=new n,me=new a,Te=new a,ye=new a,Re=new n;te.compressVertices=function(t){var r,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),E=0;for(r=0;r<i;++r)a.fromArray(s,3*r,me),a.equals(me,a.ZERO)?E+=2:(Re=e.octEncodeInRange(me,65535,Re),l[E++]=Re.x,l[E++]=Re.y);return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var f=t.attributes.normal,h=t.attributes.st,p=c(f),_=c(h);if(!p&&!_)return t;var m,T,y,R,A=t.attributes.tangent,v=t.attributes.bitangent,S=c(A),N=c(v);p&&(m=f.values),_&&(T=h.values),S&&(y=A.values),N&&(R=v.values),i=(p?m.length:T.length)/(p?3:2);var I=i,M=_&&p?2:1;M+=S||N?1:0,I*=M;var O=new Float32Array(I),g=0;for(r=0;r<i;++r){_&&(n.fromArray(T,2*r,_e),O[g++]=e.compressTextureCoordinates(_e));var C=3*r;p&&c(y)&&c(R)?(a.fromArray(m,C,me),a.fromArray(y,C,Te),a.fromArray(R,C,ye),e.octPack(me,Te,ye,_e),O[g++]=_e.x,O[g++]=_e.y):(p&&(a.fromArray(m,C,me),O[g++]=e.octEncodeFloat(me)),S&&(a.fromArray(y,C,me),O[g++]=e.octEncodeFloat(me)),N&&(a.fromArray(R,C,me),O[g++]=e.octEncodeFloat(me)))}return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:M,values:O}),p&&delete t.attributes.normal,_&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Ae=new a,ve=new a,Se=new a,Ne=new a,Ie=new a,Me={positions:new Array(7),indices:new Array(9)},Oe=new a,ge=new a,Ce=new a,we=new a,Pe=new n,xe=new n,Le=new n,Ue=v.fromPointNormal(a.ZERO,a.UNIT_Y),be=new a,Fe=new a,De=new n,Be=new n,ze=new a,Ge=new a,Ve=new a,qe=new a,Xe=new a,He=new a,We=new i,ke=5*y.EPSILON9,Ye=y.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,v.ORIGIN_ZX_PLANE)!==m.INTERSECTING)return e}if(t.geometryType!==p.NONE)switch(t.geometryType){case p.POLYLINES:ee(e);break;case p.TRIANGLES:Q(e);break;case p.LINES:J(e)}else V(t),t.primitiveType===S.TRIANGLES?Q(e):t.primitiveType===S.LINES&&J(e);return e},te}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,r,n,a,i,o,u){"use strict";function s(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius, +this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,r){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return n(r)?(r.x=i,r.y=o,r.z=u,r):new e(i,o,u)},s.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return n(r)?(r.longitude=i,r.latitude=o,r.height=u,r):new t(i,o,u)},s}),define("Scene/PrimitivePipeline",["../Core/BoundingSphere","../Core/ComponentDatatype","../Core/defined","../Core/DeveloperError","../Core/Ellipsoid","../Core/FeatureDetection","../Core/GeographicProjection","../Core/Geometry","../Core/GeometryAttribute","../Core/GeometryAttributes","../Core/GeometryPipeline","../Core/IndexDatatype","../Core/Matrix4","../Core/WebMercatorProjection"],function(e,t,r,n,a,i,o,u,s,c,l,E,f,h){"use strict";function d(e,t,n){var a,i=!n,o=e.length;if(!i&&o>1){var u=e[0].modelMatrix;for(a=1;a<o;++a)if(!f.equals(u,e[a].modelMatrix)){i=!0;break}}if(i)for(a=0;a<o;++a)r(e[a].geometry)&&l.transformToWorldCoordinates(e[a]);else f.multiplyTransformation(t,e[0].modelMatrix,t)}function p(e,r){var n=e.attributes,a=n.position,i=a.values.length/a.componentsPerAttribute;n.batchId=new s({componentDatatype:t.FLOAT,componentsPerAttribute:1,values:new Float32Array(i)});for(var o=n.batchId.values,u=0;u<i;++u)o[u]=r}function _(e){for(var t=e.length,n=0;n<t;++n){var a=e[n];r(a.geometry)?p(a.geometry,n):r(a.westHemisphereGeometry)&&r(a.eastHemisphereGeometry)&&(p(a.westHemisphereGeometry,n),p(a.eastHemisphereGeometry,n))}}function m(n){var a,i,o=n.instances,u=n.projection,s=n.elementIndexUintSupported,c=n.scene3DOnly,E=n.vertexCacheOptimize,f=n.compressVertices,h=n.modelMatrix,p=o.length;for(a=0;a<p;++a)if(r(o[a].geometry)){o[a].geometry.primitiveType;break}if(d(o,h,c),!c)for(a=0;a<p;++a)r(o[a].geometry)&&l.splitLongitude(o[a]);if(_(o),E)for(a=0;a<p;++a){var m=o[a];r(m.geometry)?(l.reorderForPostVertexCache(m.geometry),l.reorderForPreVertexCache(m.geometry)):r(m.westHemisphereGeometry)&&r(m.eastHemisphereGeometry)&&(l.reorderForPostVertexCache(m.westHemisphereGeometry),l.reorderForPreVertexCache(m.westHemisphereGeometry),l.reorderForPostVertexCache(m.eastHemisphereGeometry),l.reorderForPreVertexCache(m.eastHemisphereGeometry))}var T=l.combineInstances(o);for(p=T.length,a=0;a<p;++a){i=T[a];var y,R=i.attributes;if(c)for(y in R)R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE&&l.encodeAttribute(i,y,y+"3DHigh",y+"3DLow");else for(y in R)if(R.hasOwnProperty(y)&&R[y].componentDatatype===t.DOUBLE){var A=y+"3D",v=y+"2D";l.projectTo2D(i,y,A,v,u),r(i.boundingSphere)&&"position"===y&&(i.boundingSphereCV=e.fromVertices(i.attributes.position2D.values)),l.encodeAttribute(i,A,A+"High",A+"Low"),l.encodeAttribute(i,v,v+"High",v+"Low")}f&&l.compressVertices(i)}if(!s){var S=[];for(p=T.length,a=0;a<p;++a)i=T[a],S=S.concat(l.fitToUnsignedShortIndices(i));T=S}return T}function T(e,t,n,a){var i,o,u,s=a.length-1;if(s>=0){var c=a[s];i=c.offset+c.count,u=c.index,o=n[u].indices.length}else i=0,u=0,o=n[u].indices.length;for(var l=e.length,E=0;E<l;++E){var f=e[E],h=f[t];if(r(h)){var d=h.indices.length;i+d>o&&(i=0,o=n[++u].indices.length),a.push({index:u,offset:i,count:d}),i+=d}}}function y(e,t){var r=[];return T(e,"geometry",t,r),T(e,"westHemisphereGeometry",t,r),T(e,"eastHemisphereGeometry",t,r),r}function R(e,t){var n=e.attributes;for(var a in n)if(n.hasOwnProperty(a)){var i=n[a];r(i)&&r(i.values)&&t.push(i.values.buffer)}r(e.indices)&&t.push(e.indices.buffer)}function A(e,t){for(var r=e.length,n=0;n<r;++n)R(e[n],t)}function v(t){for(var n=1,a=t.length,i=0;i<a;i++){var o=t[i];if(++n,r(o)){var u=o.attributes;n+=6+2*e.packedLength+(r(o.indices)?o.indices.length:0);for(var s in u)if(u.hasOwnProperty(s)&&r(u[s])){var c=u[s];n+=5+c.values.length}}}return n}function S(e,t){var r=e.length,n=new Float64Array(1+16*r),a=0;n[a++]=r;for(var i=0;i<r;i++){var o=e[i];f.pack(o.modelMatrix,n,a),a+=f.packedLength}return t.push(n.buffer),n}function N(e){for(var t=e,r=new Array(t[0]),n=0,a=1;a<t.length;){var i=f.unpack(t,a);a+=f.packedLength,r[n++]={modelMatrix:i}}return r}function I(t){var n=t.length,a=1+(e.packedLength+1)*n,i=new Float32Array(a),o=0;i[o++]=n;for(var u=0;u<n;++u){var s=t[u];r(s)?(i[o++]=1,e.pack(t[u],i,o)):i[o++]=0,o+=e.packedLength}return i}function M(t){for(var r=new Array(t[0]),n=0,a=1;a<t.length;)1===t[a++]&&(r[n]=e.unpack(t,a)),++n,a+=e.packedLength;return r}if(!i.supportsTypedArrays())return{};var O={};return O.combineGeometry=function(t){var n,a,i,o=t.instances,u=o.length;u>0&&(n=m(t),n.length>0&&(a=l.createAttributeLocations(n[0]),t.createPickOffsets&&(i=y(o,n))));for(var s=new Array(u),c=new Array(u),E=0;E<u;++E){var f=o[E],h=f.geometry;r(h)&&(s[E]=h.boundingSphere,c[E]=h.boundingSphereCV);var d=f.eastHemisphereGeometry,p=f.westHemisphereGeometry;r(d)&&r(p)&&(r(d.boundingSphere)&&r(p.boundingSphere)&&(s[E]=e.union(d.boundingSphere,p.boundingSphere)),r(d.boundingSphereCV)&&r(p.boundingSphereCV)&&(c[E]=e.union(d.boundingSphereCV,p.boundingSphereCV)))}return{geometries:n,modelMatrix:t.modelMatrix,attributeLocations:a,pickOffsets:i,boundingSpheres:s,boundingSpheresCV:c}},O.packCreateGeometryResults=function(t,n){var a=new Float64Array(v(t)),i=[],o={},u=t.length,s=0;a[s++]=u;for(var c=0;c<u;c++){var l=t[c],E=r(l);if(a[s++]=E?1:0,E){a[s++]=l.primitiveType,a[s++]=l.geometryType;var f=r(l.boundingSphere)?1:0;a[s++]=f,f&&e.pack(l.boundingSphere,a,s),s+=e.packedLength;var h=r(l.boundingSphereCV)?1:0;a[s++]=h,h&&e.pack(l.boundingSphereCV,a,s),s+=e.packedLength;var d=l.attributes,p=[];for(var _ in d)d.hasOwnProperty(_)&&r(d[_])&&(p.push(_),r(o[_])||(o[_]=i.length,i.push(_)));a[s++]=p.length;for(var m=0;m<p.length;m++){var T=p[m],y=d[T];a[s++]=o[T],a[s++]=y.componentDatatype,a[s++]=y.componentsPerAttribute,a[s++]=y.normalize?1:0,a[s++]=y.values.length,a.set(y.values,s),s+=y.values.length}var R=r(l.indices)?l.indices.length:0;a[s++]=R,R>0&&(a.set(l.indices,s),s+=R)}}return n.push(a.buffer),{stringTable:i,packedData:a}},O.unpackCreateGeometryResults=function(r){for(var n,a=r.stringTable,i=r.packedData,o=new Array(i[0]),l=0,f=1;f<i.length;){if(1===i[f++]){var h,d,p=i[f++],_=i[f++];1===i[f++]&&(h=e.unpack(i,f)),f+=e.packedLength;1===i[f++]&&(d=e.unpack(i,f)),f+=e.packedLength;var m,T,y,R=new c,A=i[f++];for(n=0;n<A;n++){var v=a[i[f++]],S=i[f++];y=i[f++];var N=0!==i[f++];m=i[f++],T=t.createTypedArray(S,m);for(var I=0;I<m;I++)T[I]=i[f++];R[v]=new s({componentDatatype:S,componentsPerAttribute:y,normalize:N,values:T})}var M;if((m=i[f++])>0){var O=T.length/y;for(M=E.createTypedArray(O,m),n=0;n<m;n++)M[n]=i[f++]}o[l++]=new u({primitiveType:p,geometryType:_,boundingSphere:h,boundingSphereCV:d,indices:M,attributes:R})}else o[l++]=void 0}return o},O.packCombineGeometryParameters=function(e,t){for(var r=e.createGeometryResults,n=r.length,a=0;a<n;a++)t.push(r[a].packedData.buffer);return{createGeometryResults:e.createGeometryResults,packedInstances:S(e.instances,t),ellipsoid:e.ellipsoid,isGeographic:e.projection instanceof o,elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:e.modelMatrix,createPickOffsets:e.createPickOffsets}},O.unpackCombineGeometryParameters=function(e){for(var t=N(e.packedInstances),r=e.createGeometryResults,n=r.length,i=0,u=0;u<n;u++)for(var s=O.unpackCreateGeometryResults(r[u]),c=s.length,l=0;l<c;l++){var E=s[l],d=t[i];d.geometry=E,++i}var p=a.clone(e.ellipsoid);return{instances:t,ellipsoid:p,projection:e.isGeographic?new o(p):new h(p),elementIndexUintSupported:e.elementIndexUintSupported,scene3DOnly:e.scene3DOnly,vertexCacheOptimize:e.vertexCacheOptimize,compressVertices:e.compressVertices,modelMatrix:f.clone(e.modelMatrix),createPickOffsets:e.createPickOffsets}},O.packCombineGeometryResults=function(e,t){r(e.geometries)&&A(e.geometries,t);var n=I(e.boundingSpheres),a=I(e.boundingSpheresCV);return t.push(n.buffer,a.buffer),{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:n,boundingSpheresCV:a}},O.unpackCombineGeometryResults=function(e){return{geometries:e.geometries,attributeLocations:e.attributeLocations,modelMatrix:e.modelMatrix,pickOffsets:e.pickOffsets,boundingSpheres:M(e.boundingSpheres),boundingSpheresCV:M(e.boundingSpheresCV)}},O}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var r,n=t.name,a=t.message;r=e(n)&&e(a)?n+": "+a:t.toString();var i=t.stack;return e(i)&&(r+="\n"+i),r}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,r){"use strict";function n(n){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=n(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+r(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return n}),define("Workers/createGeometry",["../Core/defined","../Scene/PrimitivePipeline","./createTaskProcessorWorker","require"],function(e,t,r,n){"use strict";function a(t){var r=o[t];return e(r)||("object"==typeof exports?o[r]=r=n("Workers/"+t):n(["./"+t],function(e){r=e,o[r]=e})),r}function i(r,n){for(var i=r.subTasks,o=i.length,u=new Array(o),s=0;s<o;s++){var c=i[s],l=c.geometry,E=c.moduleName;if(e(E)){var f=a(E);u[s]=f(l,c.offset)}else u[s]=l}return t.packCreateGeometryResults(u,n)}var o={};return r(i)})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneGeometry.js index 505ead47..7bab1fbd 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,R=a.x,l=a.y,A=a.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,I=f+h+N,d=Math.sqrt(1/I),S=t.multiplyByScalar(n,d,i);if(I<E)return isFinite(d)?t.clone(S,s):void 0;var O=u.x,M=u.y,m=u.z,y=o;y.x=S.x*O*2,y.y=S.y*M*2,y.z=S.z*m*2;var p,C,U,L,F,P,w,g,D,v,B,x=(1-d)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{x-=z,U=1/(1+x*O),L=1/(1+x*M),F=1/(1+x*m),P=U*U,w=L*L,g=F*F,D=P*U,v=w*L,B=g*F,p=f*P+h*w+N*g-1,C=f*D*O+h*v*M+N*B*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*F,s):new t(c*U,_*L,T*F)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=i.EPSILON1;return u.fromCartesian=function(e,n,a){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(e,l,A,f,s);if(r(h)){var N=t.multiplyComponents(h,A,E);N=t.normalize(N,N);var I=t.subtract(e,h,c),d=Math.atan2(N.y,N.x),S=Math.asin(N.z),O=i.sign(t.dot(I,e))*t.magnitude(I);return r(a)?(a.longitude=d,a.latitude=S,a.height=O,a):new u(d,S,O)}},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,A=new t,f=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,A);if(a(i)){var o=this.geodeticSurfaceNormal(i,l),u=t.subtract(n,i,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(A[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(A[i],l[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=l[a],T=A[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,f=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],I=(f-h)/2/N;R=I<0?-1/(-I+Math.sqrt(1+I*I)):1/(I+Math.sqrt(1+I*I)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,A=2*(a-T),f=2*(i+c),h=2*(a+T),N=-n+u-_+R,I=2*(s-o),d=2*(i-c),S=2*(s+o),O=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=d,e[3]=A,e[4]=N,e[5]=S,e[6]=f,e[7]=I,e[8]=O,e):new E(l,A,f,h,N,I,d,S,O)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,R=n*u,l=i*a+s*o*u,A=-s*a+i*o*u,f=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=R,e[2]=f,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=A,e[8]=N,e):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);i<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){ -var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,A=e.y*e.w,f=e.z*e.z,h=e.z*e.w,N=e.w*e.w,I=E-R-f+N,d=2*(s-h),S=2*(_+A),O=2*(s+h),M=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=I*i,r[1]=O*i,r[2]=y*i,r[3]=0,r[4]=d*o,r[5]=M*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,I=R.z,d=r.x,S=r.y,O=r.z,M=u*-d+E*-S+s*-O,m=h*-d+N*-S+I*-O,y=l*d+A*S+f*O;return a(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=I,n[10]=-f,n[11]=0,n[12]=M,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,M,h,N,I,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,A=i+s,f=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=R,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=l,a[11]=0,a[12]=A,a[13]=f,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var A=new t;c.getMaximumScale=function(e){return c.getScale(e,A),t.maximumComponent(A)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],A=t[12],f=t[13],h=t[14],N=t[15],I=e[0],d=e[1],S=e[2],O=e[3],M=e[4],m=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],F=e[11],P=e[12],w=e[13],g=e[14],D=e[15],v=r*I+u*d+_*S+A*O,B=a*I+E*d+T*S+f*O,x=i*I+s*d+R*S+h*O,z=o*I+c*d+l*S+N*O,G=r*M+u*m+_*y+A*p,b=a*M+E*m+T*y+f*p,X=i*M+s*m+R*y+h*p,V=o*M+c*m+l*y+N*p,q=r*C+u*U+_*L+A*F,H=a*C+E*U+T*L+f*F,W=i*C+s*U+R*L+h*F,Y=o*C+c*U+l*L+N*F,k=r*P+u*w+_*g+A*D,K=a*P+E*w+T*g+f*D,Z=i*P+s*w+R*g+h*D,j=o*P+c*w+l*g+N*D;return n[0]=v,n[1]=B,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],A=e[0],f=e[1],h=e[2],N=e[4],I=e[5],d=e[6],S=e[8],O=e[9],M=e[10],m=e[12],y=e[13],p=e[14],C=r*A+o*f+s*h,U=a*A+u*f+c*h,L=i*A+E*f+_*h,F=r*N+o*I+s*d,P=a*N+u*I+c*d,w=i*N+E*I+_*d,g=r*S+o*O+s*M,D=a*S+u*O+c*M,v=i*S+E*O+_*M,B=r*m+o*y+s*p+T,x=a*m+u*y+c*p+R,z=i*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=F,n[5]=P,n[6]=w,n[7]=0,n[8]=g,n[9]=D,n[10]=v,n[11]=0,n[12]=B,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],A=e[3],f=e[4],h=e[5],N=e[6],I=e[7],d=e[8],S=r*T+o*R+s*l,O=a*T+u*R+c*l,M=i*T+E*R+_*l,m=r*A+o*f+s*h,y=a*A+u*f+c*h,p=i*A+E*f+_*h,C=r*N+o*I+s*d,U=a*N+u*I+c*d,L=i*N+E*I+_*d;return n[0]=S,n[1]=O,n[2]=M,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var f=new t;c.multiplyByUniformScale=function(t,e,n){return f.x=e,f.y=e,f.z=e,c.multiplyByScale(t,f,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,I=new e,d=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,I),d))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],A=t[2],f=t[6],S=t[10],O=t[14],M=t[3],m=t[7],y=t[11],p=t[15],C=S*p,U=O*y,L=f*p,F=O*m,P=f*y,w=S*m,g=A*p,D=O*M,v=A*y,B=S*M,x=A*m,z=f*M,G=C*T+F*R+P*l-(U*T+L*R+w*l),b=U*_+g*R+B*l-(C*_+D*R+v*l),X=L*_+D*T+x*l-(F*_+g*T+z*l),V=w*_+v*T+z*R-(P*_+B*T+x*R),q=U*a+L*i+w*o-(C*a+F*i+P*o),H=C*r+D*i+v*o-(U*r+g*i+B*o),W=F*r+g*a+z*o-(L*r+D*a+x*o),Y=P*r+B*a+x*i-(w*r+v*a+z*i);C=i*l,U=o*R,L=a*l,F=o*T,P=a*R,w=i*T,g=r*l,D=o*_,v=r*R,B=i*_,x=r*T,z=a*_;var k=C*m+F*y+P*p-(U*m+L*y+w*p),K=U*M+g*y+B*p-(C*M+D*y+v*p),Z=L*M+D*m+x*p-(F*M+g*m+z*p),j=w*M+v*m+z*y-(P*M+B*m+x*y),Q=L*S+w*O+U*f-(P*O+C*f+F*S),J=v*O+C*A+D*S-(g*S+B*O+U*A),$=g*f+z*O+F*A-(x*O+L*A+D*f),tt=x*S+P*A+B*f-(v*f+z*S+w*A),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-a*R,A=-i*_-o*T-u*R,f=-E*_-s*T-c*R;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=A,e[14]=f,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),a=Math.max(a,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;i=Math.min(i,l),o=Math.max(o,l)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=t.length;l<A;l++){var f=e.cartesianToCartographic(t[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=R,a):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,A=s;A.height=a,A.longitude=l,A.latitude=_,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(t,A)&&(o[c]=e.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_){"use strict";function T(e,n){this.center=t.clone(r(e,t.ZERO)),this.radius=r(n,0)}var R=new t,l=new t,A=new t,f=new t,h=new t,N=new t,I=new t,d=new t,S=new t,O=new t,M=new t,m=new t;T.fromPoints=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],I),o=t.clone(i,R),u=t.clone(i,l),E=t.clone(i,A),s=t.clone(i,f),c=t.clone(i,h),_=t.clone(i,N),y=e.length;for(r=1;r<y;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var L=t.magnitudeSquared(t.subtract(s,o,d)),F=t.magnitudeSquared(t.subtract(c,u,d)),P=t.magnitudeSquared(t.subtract(_,E,d)),w=o,g=s,D=L;F>D&&(D=F,w=u,g=c),P>D&&(D=P,w=E,g=_);var v=S;v.x=.5*(w.x+g.x),v.y=.5*(w.y+g.y),v.z=.5*(w.z+g.z);var B=t.magnitudeSquared(t.subtract(g,v,d)),x=Math.sqrt(B),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=M;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,d),.5,m),X=0;for(r=0;r<y;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,d));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(i,v,d));if(q>B){var H=Math.sqrt(q);x=.5*(x+H),B=x*x;var W=H-x;v.x=(x*v.x+W*i.x)/H,v.y=(x*v.y+W*i.y)/H,v.z=(x*v.z+W*i.z)/H}}return x<X?(t.clone(v,n.center),n.radius=x):(t.clone(b,n.center),n.radius=X),n};var y=new o,p=new t,C=new t,U=new e,L=new e;T.fromRectangle2D=function(t,e,n){return T.fromRectangleWithHeights2D(t,e,0,0,n)},T.fromRectangleWithHeights2D=function(e,n,i,o,u){if(a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(e,U),U.height=i,_.northeast(e,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*R,A.z=E.z+.5*l,u};var F=[];T.fromRectangle3D=function(e,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=_.subsample(e,n,o,F);return T.fromPoints(E,u)},T.fromVertices=function(e,n,i,o){if(a(o)||(o=new T),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=r(n,t.ZERO),i=r(i,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,R),c=t.clone(u,l),_=t.clone(u,A),y=t.clone(u,f),p=t.clone(u,h),C=t.clone(u,N),U=e.length;for(E=0;E<U;E+=i){var L=e[E]+n.x,F=e[E+1]+n.y,P=e[E+2]+n.z;u.x=L,u.y=F,u.z=P,L<s.x&&t.clone(u,s),L>y.x&&t.clone(u,y),F<c.y&&t.clone(u,c),F>p.y&&t.clone(u,p),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(y,s,d)),g=t.magnitudeSquared(t.subtract(p,c,d)),D=t.magnitudeSquared(t.subtract(C,_,d)),v=s,B=y,x=w;g>x&&(x=g,v=c,B=p),D>x&&(x=D,v=_,B=C);var z=S;z.x=.5*(v.x+B.x),z.y=.5*(v.y+B.y),z.z=.5*(v.z+B.z);var G=t.magnitudeSquared(t.subtract(B,z,d)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=M;V.x=y.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,d),.5,m),H=0;for(E=0;E<U;E+=i){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,d));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,d));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new T),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=I;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,R),E=t.clone(i,l),s=t.clone(i,A),c=t.clone(i,f),_=t.clone(i,h),y=t.clone(i,N),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),L<s.z&&t.clone(i,s),L>y.z&&t.clone(i,y)}var F=t.magnitudeSquared(t.subtract(c,u,d)),P=t.magnitudeSquared(t.subtract(_,E,d)),w=t.magnitudeSquared(t.subtract(y,s,d)),g=u,D=c,v=F;P>v&&(v=P,g=E,D=_),w>v&&(v=w,g=s,D=y);var B=S;B.x=.5*(g.x+D.x),B.y=.5*(g.y+D.y),B.z=.5*(g.z+D.z);var x=t.magnitudeSquared(t.subtract(D,B,d)),z=Math.sqrt(x),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=M;b.x=c.x,b.y=_.y,b.z=y.z;var X=t.multiplyByScalar(t.add(G,b,d),.5,m),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,X,d));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(i,B,d));if(H>x){var W=Math.sqrt(H);z=.5*(z+W),x=z*z;var Y=W-z;B.x=(z*B.x+Y*i.x)/W,B.y=(z*B.y+Y*i.y)/W,B.z=(z*B.z+Y*i.z)/W}}return z<V?(t.clone(B,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(e,n,r){a(r)||(r=new T);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},T.fromEllipsoid=function(e,n){return a(n)||(n=new T),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var P=new t;T.fromBoundingSpheres=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return T.clone(e[0],n);if(2===r)return T.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,P)+s.radius)}return n.radius=E,n};var w=new t,g=new t,D=new t;T.fromOrientedBoundingBox=function(e,n){a(n)||(n=new T);var r=e.halfAxes,i=s.getColumn(r,0,w),o=s.getColumn(r,1,g),u=s.getColumn(r,2,D);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},T.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new T(e.center,e.radius)},T.packedLength=4,T.pack=function(t,e,n){n=r(n,0);var a=t.center;return e[n++]=a.x,e[n++]=a.y,e[n++]=a.z,e[n]=t.radius,e},T.unpack=function(t,e,n){e=r(e,0),a(n)||(n=new T);var i=n.center;return i.x=t[e++],i.y=t[e++],i.z=t[e++],n.radius=t[e],n};var v=new t,B=new t;T.union=function(e,n,r){a(r)||(r=new T);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,v),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=t.multiplyByScalar(s,(-o+_)/c,B);return t.add(R,i,R),t.clone(R,r.center),r.radius=_,r};var x=new t;T.expand=function(e,n,r){r=T.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,x));return a>r.radius&&(r.radius=a),r},T.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},T.transform=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=c.getMaximumScale(e)*t.radius,n};var z=new t;T.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,z);return t.magnitudeSquared(r)-e.radius*e.radius},T.transformWithoutScale=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var G=new t;T.computePlaneDistances=function(e,n,r,i){a(i)||(i=new E);var o=t.subtract(e.center,n,G),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var b=new t,X=new t,V=new t,q=new t,H=new t,W=new e,Y=new Array(8),k=0;k<8;++k)Y[k]=new t;var K=new o;return T.projectTo2D=function(e,n,a){n=r(n,K);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,b),s=t.cross(t.UNIT_Z,E,X);t.normalize(s,s);var c=t.cross(E,s,V);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,H),R=t.negate(s,q),l=Y,A=l[0];t.add(E,c,A),t.add(A,s,A),A=l[1],t.add(E,c,A),t.add(A,R,A),A=l[2],t.add(E,_,A),t.add(A,R,A),A=l[3],t.add(E,_,A),t.add(A,s,A),t.negate(E,E),A=l[4],t.add(E,c,A),t.add(A,s,A),A=l[5],t.add(E,c,A),t.add(A,R,A),A=l[6],t.add(E,_,A),t.add(A,R,A),A=l[7],t.add(E,_,A),t.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];t.add(o,N,N);var I=i.cartesianToCartographic(N,W);n.project(I,N)}a=T.fromPoints(l,a),o=a.center;var d=o.x,S=o.y,O=o.z;return o.x=O,o.y=d,o.z=S,a},T.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},T.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},T.prototype.intersectPlane=function(t){return T.intersectPlane(this,t)},T.prototype.distanceSquaredTo=function(t){return T.distanceSquaredTo(this,t)},T.prototype.computePlaneDistances=function(t,e,n){return T.computePlaneDistances(this,t,e,n)},T.prototype.isOccluded=function(t){return T.isOccluded(this,t)},T.prototype.equals=function(t){return T.equals(this,t)},T.prototype.clone=function(t){return T.clone(this,t)},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(S=!0,O=r(t[1]))}return S}function i(){return a()&&O}function o(){if(!e(M)&&(M=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(d.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(M=!0,m=r(t[1]))}return M}function u(){return o()&&m}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(d.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===d.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(d.userAgent))&&(C=!0, -U=r(t[1])):"Netscape"===d.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(d.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(L=!0,F=r(t[1]))}return L}function R(){return T()&&F}function l(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(P=!0,w=r(t[1]))}return P}function A(){return e(g)||(g=/Windows/i.test(d.appVersion)),g}function f(){return l()&&w}function h(){return e(D)||(D="undefined"!=typeof PointerEvent&&(!e(d.pointerEnabled)||d.pointerEnabled)),D}function N(){if(!e(B)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;B=e(n)&&""!==n,B&&(v=n)}return B}function I(){return N()?v:void 0}var d;d="undefined"!=typeof navigator?navigator:{};var S,O,M,m,y,p,C,U,L,F,P,w,g,D,v,B,x={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:t(d.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:I};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/PlaneGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c){"use strict";function _(t){t=a(t,a.EMPTY_OBJECT);var e=a(t.vertexFormat,c.DEFAULT);this._vertexFormat=e,this._workerName="createPlaneGeometry"}_.packedLength=c.packedLength,_.pack=function(t,e,n){return n=a(n,0),c.pack(t._vertexFormat,e,n),e};var T=new c,R={vertexFormat:T};_.unpack=function(t,e,n){e=a(e,0);var r=c.unpack(t,e,T);return i(n)?(n._vertexFormat=c.clone(r,n._vertexFormat),n):new _(R)};var l=new e(-.5,-.5,0),A=new e(.5,.5,0);return _.createGeometry=function(n){var a,i,c=n._vertexFormat,_=new E;if(c.position){if(i=new Float64Array(12),i[0]=l.x,i[1]=l.y,i[2]=0,i[3]=A.x,i[4]=l.y,i[5]=0,i[6]=A.x,i[7]=A.y,i[8]=0,i[9]=l.x,i[10]=A.y,i[11]=0,_.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:i}),c.normal){var T=new Float32Array(12);T[0]=0,T[1]=0,T[2]=1,T[3]=0,T[4]=0,T[5]=1,T[6]=0,T[7]=0,T[8]=1,T[9]=0,T[10]=0,T[11]=1,_.normal=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:T})}if(c.st){var R=new Float32Array(8);R[0]=0,R[1]=0,R[2]=1,R[3]=0,R[4]=1,R[5]=1,R[6]=0,R[7]=1,_.st=new u({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:R})}if(c.tangent){var f=new Float32Array(12);f[0]=1,f[1]=0,f[2]=0,f[3]=1,f[4]=0,f[5]=0,f[6]=1,f[7]=0,f[8]=0,f[9]=1,f[10]=0,f[11]=0,_.tangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:f})}if(c.bitangent){var h=new Float32Array(12);h[0]=0,h[1]=1,h[2]=0,h[3]=0,h[4]=1,h[5]=0,h[6]=0,h[7]=1,h[8]=0,h[9]=0,h[10]=1,h[11]=0,_.bitangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:h})}a=new Uint16Array(6),a[0]=0,a[1]=1,a[2]=2,a[3]=0,a[4]=2,a[5]=3}return new o({attributes:_,indices:a,primitiveType:s.TRIANGLES,boundingSphere:new t(e.ZERO,Math.sqrt(2))})},_}),define("Workers/createPlaneGeometry",["../Core/PlaneGeometry","../Core/defined"],function(t,e){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,R=a.x,l=a.y,A=a.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,I=f+h+N,d=Math.sqrt(1/I),S=t.multiplyByScalar(n,d,i);if(I<E)return isFinite(d)?t.clone(S,s):void 0;var O=u.x,M=u.y,m=u.z,y=o;y.x=S.x*O*2,y.y=S.y*M*2,y.z=S.z*m*2;var p,C,U,L,F,P,w,g,D,v,B,x=(1-d)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{x-=z,U=1/(1+x*O),L=1/(1+x*M),F=1/(1+x*m),P=U*U,w=L*L,g=F*F,D=P*U,v=w*L,B=g*F,p=f*P+h*w+N*g-1,C=f*D*O+h*v*M+N*B*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*L,s.z=T*F,s):new t(c*U,_*L,T*F)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),R=i.EPSILON1;return u.fromCartesian=function(e,n,a){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(e,l,A,f,s);if(r(h)){var N=t.multiplyComponents(h,A,E);N=t.normalize(N,N);var I=t.subtract(e,h,c),d=Math.atan2(N.y,N.x),S=Math.asin(N.z),O=i.sign(t.dot(I,e))*t.magnitude(I);return r(a)?(a.longitude=d,a.latitude=S,a.height=O,a):new u(d,S,O)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,R=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=R;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var l=new t,A=new t,f=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,A);if(a(i)){var o=this.geodeticSurfaceNormal(i,l),u=t.subtract(n,i,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(A[n],l[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(A[i],l[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=l[a],T=A[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var R,f=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],I=(f-h)/2/N;R=I<0?-1/(-I+Math.sqrt(1+I*I)):1/(I+Math.sqrt(1+I*I)),s=1/Math.sqrt(1+R*R),c=R*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,R=t.w*t.w,l=n-u-_+R,A=2*(a-T),f=2*(i+c),h=2*(a+T),N=-n+u-_+R,I=2*(s-o),d=2*(i-c),S=2*(s+o),O=-n-u+_+R;return r(e)?(e[0]=l,e[1]=h,e[2]=d,e[3]=A,e[4]=N,e[5]=S,e[6]=f,e[7]=I,e[8]=O,e):new E(l,A,f,h,N,I,d,S,O)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,R=n*u,l=i*a+s*o*u,A=-s*a+i*o*u,f=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=R,e[2]=f,e[3]=_,e[4]=l,e[5]=h,e[6]=T,e[7]=A,e[8]=N,e):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var R=new t;E.getMaximumScale=function(e){return E.getScale(e,R),t.maximumComponent(R)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),R=n*s(T);i<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var R=1/T;return E.multiplyByScalar(e,R,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,R=e.y*e.y,l=e.y*e.z,A=e.y*e.w,f=e.z*e.z,h=e.z*e.w,N=e.w*e.w,I=E-R-f+N,d=2*(s-h),S=2*(_+A),O=2*(s+h),M=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=I*i,r[1]=O*i,r[2]=y*i,r[3]=0,r[4]=d*o,r[5]=M*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,R=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,I=R.z,d=r.x,S=r.y,O=r.z,M=u*-d+E*-S+s*-O,m=h*-d+N*-S+I*-O,y=l*d+A*S+f*O;return a(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=I,n[10]=-f,n[11]=0,n[12]=M,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,M,h,N,I,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,R=c,l=_,A=i+s,f=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=R,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=l,a[11]=0,a[12]=A,a[13]=f,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var l=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],l)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],l)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],l)),n};var A=new t;c.getMaximumScale=function(e){return c.getScale(e,A),t.maximumComponent(A)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],R=t[10],l=t[11],A=t[12],f=t[13],h=t[14],N=t[15],I=e[0],d=e[1],S=e[2],O=e[3],M=e[4],m=e[5],y=e[6],p=e[7],C=e[8],U=e[9],L=e[10],F=e[11],P=e[12],w=e[13],g=e[14],D=e[15],v=r*I+u*d+_*S+A*O,B=a*I+E*d+T*S+f*O,x=i*I+s*d+R*S+h*O,z=o*I+c*d+l*S+N*O,G=r*M+u*m+_*y+A*p,b=a*M+E*m+T*y+f*p,X=i*M+s*m+R*y+h*p,V=o*M+c*m+l*y+N*p,q=r*C+u*U+_*L+A*F,H=a*C+E*U+T*L+f*F,W=i*C+s*U+R*L+h*F,Y=o*C+c*U+l*L+N*F,k=r*P+u*w+_*g+A*D,K=a*P+E*w+T*g+f*D,Z=i*P+s*w+R*g+h*D,j=o*P+c*w+l*g+N*D;return n[0]=v,n[1]=B,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],R=t[13],l=t[14],A=e[0],f=e[1],h=e[2],N=e[4],I=e[5],d=e[6],S=e[8],O=e[9],M=e[10],m=e[12],y=e[13],p=e[14],C=r*A+o*f+s*h,U=a*A+u*f+c*h,L=i*A+E*f+_*h,F=r*N+o*I+s*d,P=a*N+u*I+c*d,w=i*N+E*I+_*d,g=r*S+o*O+s*M,D=a*S+u*O+c*M,v=i*S+E*O+_*M,B=r*m+o*y+s*p+T,x=a*m+u*y+c*p+R,z=i*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=F,n[5]=P,n[6]=w,n[7]=0,n[8]=g,n[9]=D,n[10]=v,n[11]=0,n[12]=B,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],R=e[1],l=e[2],A=e[3],f=e[4],h=e[5],N=e[6],I=e[7],d=e[8],S=r*T+o*R+s*l,O=a*T+u*R+c*l,M=i*T+E*R+_*l,m=r*A+o*f+s*h,y=a*A+u*f+c*h,p=i*A+E*f+_*h,C=r*N+o*I+s*d,U=a*N+u*I+c*d,L=i*N+E*I+_*d;return n[0]=S,n[1]=O,n[2]=M,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var f=new t;c.multiplyByUniformScale=function(t,e,n){return f.x=e,f.y=e,f.z=e,c.multiplyByScale(t,f,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,I=new e,d=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,I),d))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],R=t[9],l=t[13],A=t[2],f=t[6],S=t[10],O=t[14],M=t[3],m=t[7],y=t[11],p=t[15],C=S*p,U=O*y,L=f*p,F=O*m,P=f*y,w=S*m,g=A*p,D=O*M,v=A*y,B=S*M,x=A*m,z=f*M,G=C*T+F*R+P*l-(U*T+L*R+w*l),b=U*_+g*R+B*l-(C*_+D*R+v*l),X=L*_+D*T+x*l-(F*_+g*T+z*l),V=w*_+v*T+z*R-(P*_+B*T+x*R),q=U*a+L*i+w*o-(C*a+F*i+P*o),H=C*r+D*i+v*o-(U*r+g*i+B*o),W=F*r+g*a+z*o-(L*r+D*a+x*o),Y=P*r+B*a+x*i-(w*r+v*a+z*i);C=i*l,U=o*R,L=a*l,F=o*T,P=a*R,w=i*T,g=r*l,D=o*_,v=r*R,B=i*_,x=r*T,z=a*_;var k=C*m+F*y+P*p-(U*m+L*y+w*p),K=U*M+g*y+B*p-(C*M+D*y+v*p),Z=L*M+D*m+x*p-(F*M+g*m+z*p),j=w*M+v*m+z*y-(P*M+B*m+x*y),Q=L*S+w*O+U*f-(P*O+C*f+F*S),J=v*O+C*A+D*S-(g*S+B*O+U*A),$=g*f+z*O+F*A-(x*O+L*A+D*f),tt=x*S+P*A+B*f-(v*f+z*S+w*A),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],R=t[14],l=-n*_-r*T-a*R,A=-i*_-o*T-u*R,f=-E*_-s*T-c*R;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=l,e[13]=A,e[14]=f,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var R=t[_];n=Math.min(n,R.longitude),a=Math.max(a,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;i=Math.min(i,l),o=Math.max(o,l)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=t.length;l<A;l++){var f=e.cartesianToCartographic(t[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=R,a):new E(o,T,s,R)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),R=Math.min(t.north,e.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,R=t.east,l=t.west,A=s;A.height=a,A.longitude=l,A.latitude=_,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(t,A)&&(o[c]=e.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=e.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=e.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_,T){"use strict";function R(e,n){this.center=t.clone(a(e,t.ZERO)),this.radius=a(n,0)}var l=new t,A=new t,f=new t,h=new t,N=new t,I=new t,d=new t,S=new t,O=new t,M=new t,m=new t,y=new t,p=4/3*n.PI;R.fromPoints=function(e,n){if(i(n)||(n=new R),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,a=t.clone(e[0],d),o=t.clone(a,l),u=t.clone(a,A),E=t.clone(a,f),s=t.clone(a,h),c=t.clone(a,N),_=t.clone(a,I),T=e.length;for(r=1;r<T;r++){t.clone(e[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&t.clone(a,o),p>s.x&&t.clone(a,s),C<u.y&&t.clone(a,u),C>c.y&&t.clone(a,c),U<E.z&&t.clone(a,E),U>_.z&&t.clone(a,_)}var L=t.magnitudeSquared(t.subtract(s,o,S)),F=t.magnitudeSquared(t.subtract(c,u,S)),P=t.magnitudeSquared(t.subtract(_,E,S)),w=o,g=s,D=L;F>D&&(D=F,w=u,g=c),P>D&&(D=P,w=E,g=_);var v=O;v.x=.5*(w.x+g.x),v.y=.5*(w.y+g.y),v.z=.5*(w.z+g.z);var B=t.magnitudeSquared(t.subtract(g,v,S)),x=Math.sqrt(B),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=m;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],a);var V=t.magnitude(t.subtract(a,b,S));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(a,v,S));if(q>B){var H=Math.sqrt(q);x=.5*(x+H),B=x*x;var W=H-x;v.x=(x*v.x+W*a.x)/H,v.y=(x*v.y+W*a.y)/H,v.z=(x*v.z+W*a.z)/H}}return x<X?(t.clone(v,n.center),n.radius=x):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,L=new t,F=new e,P=new e;R.fromRectangle2D=function(t,e,n){return R.fromRectangleWithHeights2D(t,e,0,0,n)},R.fromRectangleWithHeights2D=function(e,n,r,o,u){if(i(u)||(u=new R),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=a(n,C),T.southwest(e,F),F.height=r,T.northeast(e,P),P.height=o;var E=n.project(F,U),s=n.project(P,L),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*_,A.z=E.z+.5*l,u};var w=[];R.fromRectangle3D=function(e,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new R),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,w);return R.fromPoints(E,u)},R.fromVertices=function(e,n,r,o){if(i(o)||(o=new R),!i(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=a(n,t.ZERO),r=a(r,3);var u=d;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,l),c=t.clone(u,A),_=t.clone(u,f),T=t.clone(u,h),p=t.clone(u,N),C=t.clone(u,I),U=e.length;for(E=0;E<U;E+=r){var L=e[E]+n.x,F=e[E+1]+n.y,P=e[E+2]+n.z;u.x=L,u.y=F,u.z=P,L<s.x&&t.clone(u,s),L>T.x&&t.clone(u,T),F<c.y&&t.clone(u,c),F>p.y&&t.clone(u,p),P<_.z&&t.clone(u,_),P>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(T,s,S)),g=t.magnitudeSquared(t.subtract(p,c,S)),D=t.magnitudeSquared(t.subtract(C,_,S)),v=s,B=T,x=w;g>x&&(x=g,v=c,B=p),D>x&&(x=D,v=_,B=C);var z=O;z.x=.5*(v.x+B.x),z.y=.5*(v.y+B.y),z.z=.5*(v.z+B.z);var G=t.magnitudeSquared(t.subtract(B,z,S)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=T.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,S));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},R.fromEncodedCartesianVertices=function(e,n,r){if(i(r)||(r=new R),!i(e)||!i(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var a=d;a.x=e[0]+n[0],a.y=e[1]+n[1],a.z=e[2]+n[2];var o,u=t.clone(a,l),E=t.clone(a,A),s=t.clone(a,f),c=t.clone(a,h),_=t.clone(a,N),T=t.clone(a,I),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],L=e[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&t.clone(a,u),C>c.x&&t.clone(a,c),U<E.y&&t.clone(a,E),U>_.y&&t.clone(a,_),L<s.z&&t.clone(a,s),L>T.z&&t.clone(a,T)}var F=t.magnitudeSquared(t.subtract(c,u,S)),P=t.magnitudeSquared(t.subtract(_,E,S)),w=t.magnitudeSquared(t.subtract(T,s,S)),g=u,D=c,v=F;P>v&&(v=P,g=E,D=_),w>v&&(v=w,g=s,D=T);var B=O;B.x=.5*(g.x+D.x),B.y=.5*(g.y+D.y),B.z=.5*(g.z+D.z);var x=t.magnitudeSquared(t.subtract(D,B,S)),z=Math.sqrt(x),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){a.x=e[o]+n[o],a.y=e[o+1]+n[o+1],a.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(a,X,S));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(a,B,S));if(H>x){var W=Math.sqrt(H);z=.5*(z+W),x=z*z;var Y=W-z;B.x=(z*B.x+Y*a.x)/W,B.y=(z*B.y+Y*a.y)/W,B.z=(z*B.z+Y*a.z)/W}}return z<V?(t.clone(B,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(e,n,r){i(r)||(r=new R);var a=r.center;return t.add(e,n,a),t.multiplyByScalar(a,.5,a),r.radius=t.distance(a,n),r},R.fromEllipsoid=function(e,n){return i(n)||(n=new R),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var g=new t;R.fromBoundingSpheres=function(e,n){if(i(n)||(n=new R),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return R.clone(e[0],n);if(2===r)return R.union(e[0],e[1],n);var a,o=[];for(a=0;a<r;a++)o.push(e[a].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=e[a];E=Math.max(E,t.distance(u,s.center,g)+s.radius)}return n.radius=E,n};var D=new t,v=new t,B=new t;R.fromOrientedBoundingBox=function(e,n){i(n)||(n=new R);var r=e.halfAxes,a=c.getColumn(r,0,D),o=c.getColumn(r,1,v),u=c.getColumn(r,2,B);return t.add(a,o,a),t.add(a,u,a),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(a),n},R.clone=function(e,n){if(i(e))return i(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new R(e.center,e.radius)},R.packedLength=4,R.pack=function(t,e,n){n=a(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},R.unpack=function(t,e,n){e=a(e,0),i(n)||(n=new R);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var x=new t,z=new t;R.union=function(e,n,r){i(r)||(r=new R);var a=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,a,x),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,a,T),t.clone(T,r.center),r.radius=_,r};var G=new t;R.expand=function(e,n,r){r=R.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,G));return a>r.radius&&(r.radius=a),r},R.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?E.OUTSIDE:o<a?E.INTERSECTING:E.INSIDE},R.transform=function(t,e,n){return i(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;R.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},R.transformWithoutScale=function(t,e,n){return i(n)||(n=new R),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;R.computePlaneDistances=function(e,n,r,a){i(a)||(a=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var V=new t,q=new t,H=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return R.projectTo2D=function(e,n,r){n=a(n,j);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,q);t.normalize(s,s);var c=t.cross(E,s,H);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),l=K,A=l[0];t.add(E,c,A),t.add(A,s,A),A=l[1],t.add(E,c,A),t.add(A,T,A),A=l[2],t.add(E,_,A),t.add(A,T,A),A=l[3],t.add(E,_,A),t.add(A,s,A),t.negate(E,E),A=l[4],t.add(E,c,A),t.add(A,s,A),A=l[5],t.add(E,c,A),t.add(A,T,A),A=l[6],t.add(E,_,A),t.add(A,T,A),A=l[7],t.add(E,_,A),t.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];t.add(o,N,N);var I=i.cartesianToCartographic(N,k);n.project(I,N)}r=R.fromPoints(l,r),o=r.center;var d=o.x,S=o.y,O=o.z;return o.x=O,o.y=d,o.z=S,r},R.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},R.equals=function(e,n){return e===n||i(e)&&i(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},R.prototype.intersectPlane=function(t){return R.intersectPlane(this,t)},R.prototype.distanceSquaredTo=function(t){return R.distanceSquaredTo(this,t)},R.prototype.computePlaneDistances=function(t,e,n){return R.computePlaneDistances(this,t,e,n)},R.prototype.isOccluded=function(t){return R.isOccluded(this,t)},R.prototype.equals=function(t){return R.equals(this,t)},R.prototype.clone=function(t){return R.clone(this,t)},R.prototype.volume=function(){var t=this.radius;return p*t*t*t},R}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(S=!0,O=r(t[1]))}return S}function i(){return a()&&O}function o(){if(!e(M)&&(M=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(d.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(M=!0,m=r(t[1]))}return M}function u(){return o()&&m}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(d.userAgent);null!==t&&(y=!0, +p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===d.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(d.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===d.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(d.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(L)){L=!1;var t=/ Edge\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(L=!0,F=r(t[1]))}return L}function R(){return T()&&F}function l(){if(!e(P)){P=!1;var t=/Firefox\/([\.0-9]+)/.exec(d.userAgent);null!==t&&(P=!0,w=r(t[1]))}return P}function A(){return e(g)||(g=/Windows/i.test(d.appVersion)),g}function f(){return l()&&w}function h(){return e(D)||(D="undefined"!=typeof PointerEvent&&(!e(d.pointerEnabled)||d.pointerEnabled)),D}function N(){if(!e(B)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;B=e(n)&&""!==n,B&&(v=n)}return B}function I(){return N()?v:void 0}var d;d="undefined"!=typeof navigator?navigator:{};var S,O,M,m,y,p,C,U,L,F,P,w,g,D,v,B,x={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:t(d.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:I};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/PlaneGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c){"use strict";function _(t){t=a(t,a.EMPTY_OBJECT);var e=a(t.vertexFormat,c.DEFAULT);this._vertexFormat=e,this._workerName="createPlaneGeometry"}_.packedLength=c.packedLength,_.pack=function(t,e,n){return n=a(n,0),c.pack(t._vertexFormat,e,n),e};var T=new c,R={vertexFormat:T};_.unpack=function(t,e,n){e=a(e,0);var r=c.unpack(t,e,T);return i(n)?(n._vertexFormat=c.clone(r,n._vertexFormat),n):new _(R)};var l=new e(-.5,-.5,0),A=new e(.5,.5,0);return _.createGeometry=function(n){var a,i,c=n._vertexFormat,_=new E;if(c.position){if(i=new Float64Array(12),i[0]=l.x,i[1]=l.y,i[2]=0,i[3]=A.x,i[4]=l.y,i[5]=0,i[6]=A.x,i[7]=A.y,i[8]=0,i[9]=l.x,i[10]=A.y,i[11]=0,_.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:i}),c.normal){var T=new Float32Array(12);T[0]=0,T[1]=0,T[2]=1,T[3]=0,T[4]=0,T[5]=1,T[6]=0,T[7]=0,T[8]=1,T[9]=0,T[10]=0,T[11]=1,_.normal=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:T})}if(c.st){var R=new Float32Array(8);R[0]=0,R[1]=0,R[2]=1,R[3]=0,R[4]=1,R[5]=1,R[6]=0,R[7]=1,_.st=new u({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:R})}if(c.tangent){var f=new Float32Array(12);f[0]=1,f[1]=0,f[2]=0,f[3]=1,f[4]=0,f[5]=0,f[6]=1,f[7]=0,f[8]=0,f[9]=1,f[10]=0,f[11]=0,_.tangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:f})}if(c.bitangent){var h=new Float32Array(12);h[0]=0,h[1]=1,h[2]=0,h[3]=0,h[4]=1,h[5]=0,h[6]=0,h[7]=1,h[8]=0,h[9]=0,h[10]=1,h[11]=0,_.bitangent=new u({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:h})}a=new Uint16Array(6),a[0]=0,a[1]=1,a[2]=2,a[3]=0,a[4]=2,a[5]=3}return new o({attributes:_,indices:a,primitiveType:s.TRIANGLES,boundingSphere:new t(e.ZERO,Math.sqrt(2))})},_}),define("Workers/createPlaneGeometry",["../Core/PlaneGeometry","../Core/defined"],function(t,e){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneOutlineGeometry.js index d035c454..bb53d2e4 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPlaneOutlineGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var R=new o,T=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);R.x=s*Math.cos(e),R.y=s*Math.sin(e),R.z=Math.sin(r),R=o.normalize(R,R),o.multiplyComponents(E,R,T);var c=Math.sqrt(o.dot(R,T));return T=o.divideByScalar(T,c,T),R=o.multiplyByScalar(R,i,R),n(u)||(u=new o),o.add(T,R,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,R=n.z,T=i.x,l=i.y,A=i.z,f=c*c*T*T,h=_*_*l*l,N=R*R*A*A,I=f+h+N,d=Math.sqrt(1/I),S=e.multiplyByScalar(n,d,a);if(I<E)return isFinite(d)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,D,B,g,v,x=(1-d)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{x-=z,U=1/(1+x*M),L=1/(1+x*O),P=1/(1+x*m),F=U*U,w=L*L,D=P*P,B=F*U,g=w*L,v=D*P,p=f*F+h*w+N*D-1,C=f*B*M+h*g*O+N*v*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*L,s.z=R*P,s):new e(c*U,_*L,R*P)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),R=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:R,f=r(n)?n._centerToleranceSquared:T,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var I=e.subtract(t,h,c),d=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(I,t))*e.magnitude(I);return r(i)?(i.longitude=d,i.latitude=S,i.height=M,i):new u(d,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var R=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=R,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],R=A[i];if(Math.abs(e[E.getElementIndex(R,_)])>n){var T,f=e[E.getElementIndex(R,R)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(R,_)],I=(f-h)/2/N;T=I<0?-1/(-I+Math.sqrt(1+I*I)):1/(I+Math.sqrt(1+I*I)),s=1/Math.sqrt(1+T*T),c=T*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(R,R)]=s,t[E.getElementIndex(R,_)]=c,t[E.getElementIndex(_,R)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,R=e.z*e.w,T=e.w*e.w,l=n-u-_+T,A=2*(i-R),f=2*(a+c),h=2*(i+R),N=-n+u-_+T,I=2*(s-o),d=2*(a-c),S=2*(s+o),M=-n-u+_+T;return r(t)?(t[0]=l,t[1]=h,t[2]=d,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=I,t[8]=M,t):new E(l,A,f,h,N,I,d,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,R=s*u+a*o*i,T=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=R,t[7]=A,t[8]=N,t):new E(c,_,R,T,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var R=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],R)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],R)),n};var T=new e;E.getMaximumScale=function(t){return E.getScale(t,T),e.maximumComponent(T)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),R=t.diagonal=E.clone(e,t.diagonal),T=n*s(R);a<10&&c(R)>T;)_(R,f),E.transpose(f,h),E.multiply(R,f,R),E.multiply(h,R,R),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],R=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var T=1/R;return E.multiplyByScalar(t,T,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,R,T,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(R,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,R=t.x*t.w,T=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,I=E-T-f+N,d=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+T-f+N,m=2*(l-R),y=2*(_-A),p=2*(l+R),C=-E-T+f+N;return r[0]=I*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=d*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,R=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,R),R),e.normalize(e.cross(R,_,T),T);var u=R.x,E=R.y,s=R.z,l=_.x,A=_.y,f=_.z,h=T.x,N=T.y,I=T.z,d=r.x,S=r.y,M=r.z,O=u*-d+E*-S+s*-M,m=h*-d+N*-S+I*-M,y=l*d+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=I,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,I,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,R=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=R,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),R=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=R,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),R=s,T=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=R,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],R=e[9],T=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],I=t[0],d=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],L=t[10],P=t[11],F=t[12],w=t[13],D=t[14],B=t[15],g=r*I+u*d+_*S+A*M,v=i*I+E*d+R*S+f*M,x=a*I+s*d+T*S+h*M,z=o*I+c*d+l*S+N*M,G=r*O+u*m+_*y+A*p,b=i*O+E*m+R*y+f*p,X=a*O+s*m+T*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+A*P,H=i*C+E*U+R*L+f*P,W=a*C+s*U+T*L+h*P,Y=o*C+c*U+l*L+N*P,K=r*F+u*w+_*D+A*B,k=i*F+E*w+R*D+f*B,Z=a*F+s*w+T*D+h*B,j=o*F+c*w+l*D+N*B;return n[0]=g,n[1]=v,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=K,n[13]=k,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],R=e[12],T=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],I=t[5],d=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,L=a*A+E*f+_*h,P=r*N+o*I+s*d,F=i*N+u*I+c*d,w=a*N+E*I+_*d,D=r*S+o*M+s*O,B=i*S+u*M+c*O,g=a*S+E*M+_*O,v=r*m+o*y+s*p+R,x=i*m+u*y+c*p+T,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=D,n[9]=B,n[10]=g,n[11]=0,n[12]=v,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],R=t[0],T=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],I=t[7],d=t[8],S=r*R+o*T+s*l,M=i*R+u*T+c*l,O=a*R+E*T+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*I+s*d,U=i*N+u*I+c*d,L=a*N+E*I+_*d;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,I=new t,d=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,I),d))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],R=e[5],T=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,L=f*p,P=M*m,F=f*y,w=S*m,D=A*p,B=M*O,g=A*y,v=S*O,x=A*m,z=f*O,G=C*R+P*T+F*l-(U*R+L*T+w*l),b=U*_+D*T+v*l-(C*_+B*T+g*l),X=L*_+B*R+x*l-(P*_+D*R+z*l),V=w*_+g*R+z*T-(F*_+v*R+x*T),q=U*i+L*a+w*o-(C*i+P*a+F*o),H=C*r+B*a+g*o-(U*r+D*a+v*o),W=P*r+D*i+z*o-(L*r+B*i+x*o),Y=F*r+v*i+x*a-(w*r+g*i+z*a);C=a*l,U=o*T,L=i*l,P=o*R,F=i*T,w=a*R,D=r*l,B=o*_,g=r*T,v=a*_,x=r*R,z=i*_;var K=C*m+P*y+F*p-(U*m+L*y+w*p),k=U*O+D*y+v*p-(C*O+B*y+g*p),Z=L*O+B*m+x*p-(P*O+D*m+z*p),j=w*O+g*m+z*y-(F*O+v*m+x*y),Q=L*S+w*M+U*f-(F*M+C*f+P*S),J=g*M+C*A+B*S-(D*S+v*M+U*A),$=D*f+z*M+P*A-(x*M+L*A+B*f),ee=x*S+F*A+v*f-(g*f+z*S+w*A),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=q*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=K*te,n[9]=k*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],R=e[13],T=e[14],l=-n*_-r*R-i*T,A=-a*_-o*R-u*T,f=-E*_-s*R-c*T;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,R=e.length;_<R;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),s=Math.min(s,T.latitude),c=Math.max(c,T.latitude);var l=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=Number.MAX_VALUE,T=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),R=Math.min(R,f.latitude),T=Math.max(T,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=R,i.east=s,i.north=T,i):new E(o,R,s,T)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var R=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(R>=T))return r(n)?(n.west=c,n.south=R,n.east=_,n.north=T,n):new E(c,R,_,T)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,R=e.south,T=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:R>0?R:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function R(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var T=new e,l=new e,A=new e,f=new e,h=new e,N=new e,I=new e,d=new e,S=new e,M=new e,O=new e,m=new e;R.fromPoints=function(t,n){if(i(n)||(n=new R),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],I),o=e.clone(a,T),u=e.clone(a,l),E=e.clone(a,A),s=e.clone(a,f),c=e.clone(a,h),_=e.clone(a,N),y=t.length;for(r=1;r<y;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var L=e.magnitudeSquared(e.subtract(s,o,d)),P=e.magnitudeSquared(e.subtract(c,u,d)),F=e.magnitudeSquared(e.subtract(_,E,d)),w=o,D=s,B=L;P>B&&(B=P,w=u,D=c),F>B&&(B=F,w=E,D=_);var g=S;g.x=.5*(w.x+D.x),g.y=.5*(w.y+D.y),g.z=.5*(w.z+D.z);var v=e.magnitudeSquared(e.subtract(D,g,d)),x=Math.sqrt(v),z=M;z.x=o.x,z.y=u.y,z.z=E.z;var G=O;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,d),.5,m),X=0;for(r=0;r<y;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,d));V>X&&(X=V);var q=e.magnitudeSquared(e.subtract(a,g,d));if(q>v){var H=Math.sqrt(q);x=.5*(x+H),v=x*x;var W=H-x;g.x=(x*g.x+W*a.x)/H,g.y=(x*g.y+W*a.y)/H,g.z=(x*g.z+W*a.z)/H}}return x<X?(e.clone(g,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var y=new o,p=new e,C=new e,U=new t,L=new t;R.fromRectangle2D=function(e,t,n){return R.fromRectangleWithHeights2D(e,t,0,0,n)},R.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new R),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(t,U),U.height=a,_.northeast(t,L),L.height=o;var E=n.project(U,p),s=n.project(L,C),c=s.x-E.x,T=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+T*T+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*T,A.z=E.z+.5*l,u};var P=[];R.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new R),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,P);return R.fromPoints(E,u)},R.fromVertices=function(t,n,a,o){if(i(o)||(o=new R),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=I;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,T),c=e.clone(u,l),_=e.clone(u,A),y=e.clone(u,f),p=e.clone(u,h),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=a){var L=t[E]+n.x,P=t[E+1]+n.y,F=t[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&e.clone(u,s),L>y.x&&e.clone(u,y),P<c.y&&e.clone(u,c),P>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(y,s,d)),D=e.magnitudeSquared(e.subtract(p,c,d)),B=e.magnitudeSquared(e.subtract(C,_,d)),g=s,v=y,x=w;D>x&&(x=D,g=c,v=p),B>x&&(x=B,g=_,v=C);var z=S;z.x=.5*(g.x+v.x),z.y=.5*(g.y+v.y),z.z=.5*(g.z+v.z);var G=e.magnitudeSquared(e.subtract(v,z,d)),b=Math.sqrt(G),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var q=e.multiplyByScalar(e.add(X,V,d),.5,m),H=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,q,d));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,d));if(Y>G){var K=Math.sqrt(Y);b=.5*(b+K),G=b*b;var k=K-b;z.x=(b*z.x+k*u.x)/K,z.y=(b*z.y+k*u.y)/K,z.z=(b*z.z+k*u.z)/K}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(q,o.center),o.radius=H),o},R.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new R),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=I;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,T),E=e.clone(a,l),s=e.clone(a,A),c=e.clone(a,f),_=e.clone(a,h),y=e.clone(a,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],L=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=L,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),L<s.z&&e.clone(a,s),L>y.z&&e.clone(a,y)}var P=e.magnitudeSquared(e.subtract(c,u,d)),F=e.magnitudeSquared(e.subtract(_,E,d)),w=e.magnitudeSquared(e.subtract(y,s,d)),D=u,B=c,g=P;F>g&&(g=F,D=E,B=_),w>g&&(g=w,D=s,B=y);var v=S;v.x=.5*(D.x+B.x),v.y=.5*(D.y+B.y),v.z=.5*(D.z+B.z);var x=e.magnitudeSquared(e.subtract(B,v,d)),z=Math.sqrt(x),G=M;G.x=u.x,G.y=E.y,G.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=e.multiplyByScalar(e.add(G,b,d),.5,m),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var q=e.magnitude(e.subtract(a,X,d));q>V&&(V=q);var H=e.magnitudeSquared(e.subtract(a,v,d));if(H>x){var W=Math.sqrt(H);z=.5*(z+W),x=z*z;var Y=W-z;v.x=(z*v.x+Y*a.x)/W,v.y=(z*v.y+Y*a.y)/W,v.z=(z*v.z+Y*a.z)/W}}return z<V?(e.clone(v,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(t,n,r){i(r)||(r=new R);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},R.fromEllipsoid=function(t,n){return i(n)||(n=new R),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var F=new e;R.fromBoundingSpheres=function(t,n){if(i(n)||(n=new R),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return R.clone(t[0],n);if(2===r)return R.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var w=new e,D=new e,B=new e;R.fromOrientedBoundingBox=function(t,n){i(n)||(n=new R);var r=t.halfAxes,a=s.getColumn(r,0,w),o=s.getColumn(r,1,D),u=s.getColumn(r,2,B);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},R.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new R(t.center,t.radius)},R.packedLength=4,R.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},R.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new R);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var g=new e,v=new e;R.union=function(t,n,r){i(r)||(r=new R);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,g),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=e.multiplyByScalar(s,(-o+_)/c,v);return e.add(T,a,T),e.clone(T,r.center),r.radius=_,r};var x=new e;R.expand=function(t,n,r){r=R.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,x));return i>r.radius&&(r.radius=i),r},R.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},R.transform=function(e,t,n){return i(n)||(n=new R),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;R.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},R.transformWithoutScale=function(e,t,n){return i(n)||(n=new R),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;R.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,q=new e,H=new e,W=new t,Y=new Array(8),K=0;K<8;++K)Y[K]=new e;var k=new o;return R.projectTo2D=function(t,n,i){n=r(n,k);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,H),T=e.negate(s,q),l=Y,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,T,A),A=l[2],e.add(E,_,A),e.add(A,T,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,T,A),A=l[6],e.add(E,_,A),e.add(A,T,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var I=a.cartesianToCartographic(N,W);n.project(I,N)}i=R.fromPoints(l,i),o=i.center;var d=o.x,S=o.y,M=o.z;return o.x=M,o.y=d,o.z=S,i},R.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},R.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},R.prototype.intersectPlane=function(e){return R.intersectPlane(this,e)},R.prototype.distanceSquaredTo=function(e){return R.distanceSquaredTo(this,e)},R.prototype.computePlaneDistances=function(e,t,n){return R.computePlaneDistances(this,e,t,n)},R.prototype.isOccluded=function(e){return R.isOccluded(this,e)},R.prototype.equals=function(e){return R.equals(this,e)},R.prototype.clone=function(e){return R.clone(this,e)},R}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!R())){var e=/ Chrome\/([\.0-9]+)/.exec(d.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!R()&&/ Safari\/[\.0-9]+/.test(d.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(d.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(d.userAgent);null!==e&&(y=!0,p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===d.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(d.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===d.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(d.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function R(){if(!t(L)){L=!1;var e=/ Edge\/([\.0-9]+)/.exec(d.userAgent);null!==e&&(L=!0,P=r(e[1]))}return L}function T(){return R()&&P}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(d.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function A(){return t(D)||(D=/Windows/i.test(d.appVersion)),D}function f(){return l()&&w}function h(){return t(B)||(B="undefined"!=typeof PointerEvent&&(!t(d.pointerEnabled)||d.pointerEnabled)),B}function N(){if(!t(v)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;v=t(n)&&""!==n,v&&(g=n)}return v}function I(){return N()?g:void 0}var d;d="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,D,B,g,v,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:R,edgeVersion:T,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(d.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:I};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/PlaneOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(){this._workerName="createPlaneOutlineGeometry"}c.packedLength=0,c.pack=function(e,t){return t},c.unpack=function(e,t,n){return a(n)?n:new c};var _=new t(-.5,-.5,0),R=new t(.5,.5,0);return c.createGeometry=function(){var n=new E,i=new Uint16Array(8),a=new Float64Array(12);return a[0]=_.x,a[1]=_.y,a[2]=_.z,a[3]=R.x,a[4]=_.y,a[5]=_.z,a[6]=R.x,a[7]=R.y,a[8]=_.z,a[9]=_.x,a[10]=R.y,a[11]=_.z,n.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:a}),i[0]=0,i[1]=1,i[2]=1,i[3]=2,i[4]=2,i[5]=3,i[6]=3,i[7]=0,new o({attributes:n,indices:i,primitiveType:s.LINES,boundingSphere:new e(t.ZERO,Math.sqrt(2))})},c}),define("Workers/createPlaneOutlineGeometry",["../Core/PlaneOutlineGeometry","../Core/defined"],function(e,t){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var R=new o,T=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);R.x=s*Math.cos(e),R.y=s*Math.sin(e),R.z=Math.sin(r),R=o.normalize(R,R),o.multiplyComponents(E,R,T);var c=Math.sqrt(o.dot(R,T));return T=o.divideByScalar(T,c,T),R=o.multiplyByScalar(R,i,R),n(u)||(u=new o),o.add(T,R,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,R=n.z,T=i.x,l=i.y,A=i.z,f=c*c*T*T,h=_*_*l*l,N=R*R*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,L,P,F,w,D,B,g,v,x=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),z=0;do{x-=z,U=1/(1+x*M),L=1/(1+x*O),P=1/(1+x*m),F=U*U,w=L*L,D=P*P,B=F*U,g=w*L,v=D*P,p=f*F+h*w+N*D-1,C=f*B*M+h*g*O+N*v*m;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*L,s.z=R*P,s):new e(c*U,_*L,R*P)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),R=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),T=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:R,f=r(n)?n._centerToleranceSquared:T,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var R=new e,T=new e;_.prototype.cartographicToCartesian=function(t,n){var r=R,a=T;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],R=A[i];if(Math.abs(e[E.getElementIndex(R,_)])>n){var T,f=e[E.getElementIndex(R,R)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(R,_)],d=(f-h)/2/N;T=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+T*T),c=T*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(R,R)]=s,t[E.getElementIndex(R,_)]=c,t[E.getElementIndex(_,R)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,R=e.z*e.w,T=e.w*e.w,l=n-u-_+T,A=2*(i-R),f=2*(a+c),h=2*(i+R),N=-n+u-_+T,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+T;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=M,t):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,R=s*u+a*o*i,T=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=T,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=R,t[7]=A,t[8]=N,t):new E(c,_,R,T,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var R=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],R)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],R)),n};var T=new e;E.getMaximumScale=function(t){return E.getScale(t,T),e.maximumComponent(T)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),R=t.diagonal=E.clone(e,t.diagonal),T=n*s(R);a<10&&c(R)>T;)_(R,f),E.transpose(f,h),E.multiply(R,f,R),E.multiply(h,R,R),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],R=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var T=1/R;return E.multiplyByScalar(t,T,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,R,T,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(T,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(R,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,R=t.x*t.w,T=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-T-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+T-f+N,m=2*(l-R),y=2*(_-A),p=2*(l+R),C=-E-T+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,R=new e,T=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,R),R),e.normalize(e.cross(R,_,T),T);var u=R.x,E=R.y,s=R.z,l=_.x,A=_.y,f=_.z,h=T.x,N=T.y,d=T.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,R=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=R,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),R=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=R,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),R=s,T=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=R,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=T,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],R=e[9],T=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],L=t[10],P=t[11],F=t[12],w=t[13],D=t[14],B=t[15],g=r*d+u*I+_*S+A*M,v=i*d+E*I+R*S+f*M,x=a*d+s*I+T*S+h*M,z=o*d+c*I+l*S+N*M,G=r*O+u*m+_*y+A*p,b=i*O+E*m+R*y+f*p,X=a*O+s*m+T*y+h*p,V=o*O+c*m+l*y+N*p,q=r*C+u*U+_*L+A*P,H=i*C+E*U+R*L+f*P,W=a*C+s*U+T*L+h*P,Y=o*C+c*U+l*L+N*P,K=r*F+u*w+_*D+A*B,k=i*F+E*w+R*D+f*B,Z=a*F+s*w+T*D+h*B,j=o*F+c*w+l*D+N*B;return n[0]=g,n[1]=v,n[2]=x,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=K,n[13]=k,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],R=e[12],T=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,L=a*A+E*f+_*h,P=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,D=r*S+o*M+s*O,B=i*S+u*M+c*O,g=a*S+E*M+_*O,v=r*m+o*y+s*p+R,x=i*m+u*y+c*p+T,z=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=L,n[3]=0,n[4]=P,n[5]=F,n[6]=w,n[7]=0,n[8]=D,n[9]=B,n[10]=g,n[11]=0,n[12]=v,n[13]=x,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],R=t[0],T=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*R+o*T+s*l,M=i*R+u*T+c*l,O=a*R+E*T+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,L=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=L,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],R=e[5],T=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,L=f*p,P=M*m,F=f*y,w=S*m,D=A*p,B=M*O,g=A*y,v=S*O,x=A*m,z=f*O,G=C*R+P*T+F*l-(U*R+L*T+w*l),b=U*_+D*T+v*l-(C*_+B*T+g*l),X=L*_+B*R+x*l-(P*_+D*R+z*l),V=w*_+g*R+z*T-(F*_+v*R+x*T),q=U*i+L*a+w*o-(C*i+P*a+F*o),H=C*r+B*a+g*o-(U*r+D*a+v*o),W=P*r+D*i+z*o-(L*r+B*i+x*o),Y=F*r+v*i+x*a-(w*r+g*i+z*a);C=a*l,U=o*T,L=i*l,P=o*R,F=i*T,w=a*R,D=r*l,B=o*_,g=r*T,v=a*_,x=r*R,z=i*_;var K=C*m+P*y+F*p-(U*m+L*y+w*p),k=U*O+D*y+v*p-(C*O+B*y+g*p),Z=L*O+B*m+x*p-(P*O+D*m+z*p),j=w*O+g*m+z*y-(F*O+v*m+x*y),Q=L*S+w*M+U*f-(F*M+C*f+P*S),J=g*M+C*A+B*S-(D*S+v*M+U*A),$=D*f+z*M+P*A-(x*M+L*A+B*f),ee=x*S+F*A+v*f-(g*f+z*S+w*A),te=r*G+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=q*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=K*te,n[9]=k*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],R=e[13],T=e[14],l=-n*_-r*R-i*T,A=-a*_-o*R-u*T,f=-E*_-s*R-c*T;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,R=e.length;_<R;_++){var T=e[_];n=Math.min(n,T.longitude),i=Math.max(i,T.longitude),s=Math.min(s,T.latitude),c=Math.max(c,T.latitude);var l=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=Number.MAX_VALUE,T=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),R=Math.min(R,f.latitude),T=Math.max(T,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=R,i.east=s,i.north=T,i):new E(o,R,s,T)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var R=Math.max(e.south,t.south),T=Math.min(e.north,t.north);if(!(R>=T))return r(n)?(n.west=c,n.south=R,n.east=_,n.north=T,n):new E(c,R,_,T)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,R=e.south,T=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:R>0?R:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_,R){"use strict";function T(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e,y=new e,p=4/3*n.PI;T.fromPoints=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],I),o=e.clone(i,l),u=e.clone(i,A),E=e.clone(i,f),s=e.clone(i,h),c=e.clone(i,N),_=e.clone(i,d),R=t.length;for(r=1;r<R;r++){e.clone(t[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&e.clone(i,o),p>s.x&&e.clone(i,s),C<u.y&&e.clone(i,u),C>c.y&&e.clone(i,c),U<E.z&&e.clone(i,E),U>_.z&&e.clone(i,_)}var L=e.magnitudeSquared(e.subtract(s,o,S)),P=e.magnitudeSquared(e.subtract(c,u,S)),F=e.magnitudeSquared(e.subtract(_,E,S)),w=o,D=s,B=L;P>B&&(B=P,w=u,D=c),F>B&&(B=F,w=E,D=_);var g=M;g.x=.5*(w.x+D.x),g.y=.5*(w.y+D.y),g.z=.5*(w.z+D.z);var v=e.magnitudeSquared(e.subtract(D,g,S)),x=Math.sqrt(v),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=m;G.x=s.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,S),.5,y),X=0;for(r=0;r<R;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,b,S));V>X&&(X=V);var q=e.magnitudeSquared(e.subtract(i,g,S));if(q>v){var H=Math.sqrt(q);x=.5*(x+H),v=x*x;var W=H-x;g.x=(x*g.x+W*i.x)/H,g.y=(x*g.y+W*i.y)/H,g.z=(x*g.z+W*i.z)/H}}return x<X?(e.clone(g,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var C=new u,U=new e,L=new e,P=new t,F=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,C),R.southwest(t,P),P.height=r,R.northeast(t,F),F.height=o;var E=n.project(P,U),s=n.project(F,L),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*_,A.z=E.z+.5*l,u};var w=[];T.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new T),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=R.subsample(t,n,r,w);return T.fromPoints(E,u)},T.fromVertices=function(t,n,r,o){if(a(o)||(o=new T),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=I;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,l),c=e.clone(u,A),_=e.clone(u,f),R=e.clone(u,h),p=e.clone(u,N),C=e.clone(u,d),U=t.length;for(E=0;E<U;E+=r){var L=t[E]+n.x,P=t[E+1]+n.y,F=t[E+2]+n.z;u.x=L,u.y=P,u.z=F,L<s.x&&e.clone(u,s),L>R.x&&e.clone(u,R),P<c.y&&e.clone(u,c),P>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(R,s,S)),D=e.magnitudeSquared(e.subtract(p,c,S)),B=e.magnitudeSquared(e.subtract(C,_,S)),g=s,v=R,x=w;D>x&&(x=D,g=c,v=p),B>x&&(x=B,g=_,v=C);var z=M;z.x=.5*(g.x+v.x),z.y=.5*(g.y+v.y),z.z=.5*(g.z+v.z);var G=e.magnitudeSquared(e.subtract(v,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=R.x,V.y=p.y,V.z=C.z;var q=e.multiplyByScalar(e.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,q,S));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,S));if(Y>G){var K=Math.sqrt(Y);b=.5*(b+K),G=b*b;var k=K-b;z.x=(b*z.x+k*u.x)/K,z.y=(b*z.y+k*u.y)/K,z.z=(b*z.z+k*u.z)/K}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new T),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=I;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,l),E=e.clone(i,A),s=e.clone(i,f),c=e.clone(i,h),_=e.clone(i,N),R=e.clone(i,d),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],L=t[o+2]+n[o+2];i.x=C,i.y=U,i.z=L,C<u.x&&e.clone(i,u),C>c.x&&e.clone(i,c),U<E.y&&e.clone(i,E),U>_.y&&e.clone(i,_),L<s.z&&e.clone(i,s),L>R.z&&e.clone(i,R)}var P=e.magnitudeSquared(e.subtract(c,u,S)),F=e.magnitudeSquared(e.subtract(_,E,S)),w=e.magnitudeSquared(e.subtract(R,s,S)),D=u,B=c,g=P;F>g&&(g=F,D=E,B=_),w>g&&(g=w,D=s,B=R);var v=M;v.x=.5*(D.x+B.x),v.y=.5*(D.y+B.y),v.z=.5*(D.z+B.z);var x=e.magnitudeSquared(e.subtract(B,v,S)),z=Math.sqrt(x),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=R.z;var X=e.multiplyByScalar(e.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var q=e.magnitude(e.subtract(i,X,S));q>V&&(V=q);var H=e.magnitudeSquared(e.subtract(i,v,S));if(H>x){var W=Math.sqrt(H);z=.5*(z+W),x=z*z;var Y=W-z;v.x=(z*v.x+Y*i.x)/W,v.y=(z*v.y+Y*i.y)/W,v.z=(z*v.z+Y*i.z)/W}}return z<V?(e.clone(v,r.center),r.radius=z):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){a(r)||(r=new T);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},T.fromEllipsoid=function(t,n){return a(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var D=new e;T.fromBoundingSpheres=function(t,n){if(a(n)||(n=new T),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=t[i];E=Math.max(E,e.distance(u,s.center,D)+s.radius)}return n.radius=E,n};var B=new e,g=new e,v=new e;T.fromOrientedBoundingBox=function(t,n){a(n)||(n=new T);var r=t.halfAxes,i=c.getColumn(r,0,B),o=c.getColumn(r,1,g),u=c.getColumn(r,2,v);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},T.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new T);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var x=new e,z=new e;T.union=function(t,n,r){a(r)||(r=new T);var i=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,i,x),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,z);return e.add(R,i,R),e.clone(R,r.center),r.radius=_,r};var G=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},T.transform=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=_.getMaximumScale(t)*e.radius,n};var b=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return a(n)||(n=new T),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var X=new e;T.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,X),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,q=new e,H=new e,W=new e,Y=new e,K=new t,k=new Array(8),Z=0;Z<8;++Z)k[Z]=new e;var j=new u;return T.projectTo2D=function(t,n,r){n=i(n,j);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,V),s=e.cross(e.UNIT_Z,E,q);e.normalize(s,s);var c=e.cross(E,s,H);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,Y),R=e.negate(s,W),l=k,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,R,A),A=l[2],e.add(E,_,A),e.add(A,R,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,R,A),A=l[6],e.add(E,_,A),e.add(A,R,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,K);n.project(d,N)}r=T.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T.prototype.volume=function(){var e=this.radius;return p*e*e*e},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!R())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!R()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0, +p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function R(){if(!t(L)){L=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(L=!0,P=r(e[1]))}return L}function T(){return R()&&P}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function A(){return t(D)||(D=/Windows/i.test(I.appVersion)),D}function f(){return l()&&w}function h(){return t(B)||(B="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),B}function N(){if(!t(v)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;v=t(n)&&""!==n,v&&(g=n)}return v}function d(){return N()?g:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,L,P,F,w,D,B,g,v,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:R,edgeVersion:T,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/PlaneOutlineGeometry",["./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Geometry","./GeometryAttribute","./GeometryAttributes","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(){this._workerName="createPlaneOutlineGeometry"}c.packedLength=0,c.pack=function(e,t){return t},c.unpack=function(e,t,n){return a(n)?n:new c};var _=new t(-.5,-.5,0),R=new t(.5,.5,0);return c.createGeometry=function(){var n=new E,i=new Uint16Array(8),a=new Float64Array(12);return a[0]=_.x,a[1]=_.y,a[2]=_.z,a[3]=R.x,a[4]=_.y,a[5]=_.z,a[6]=R.x,a[7]=R.y,a[8]=_.z,a[9]=_.x,a[10]=R.y,a[11]=_.z,n.position=new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:a}),i[0]=0,i[1]=1,i[2]=1,i[3]=2,i[4]=2,i[5]=3,i[6]=3,i[7]=0,new o({attributes:n,indices:i,primitiveType:s.LINES,boundingSphere:new e(t.ZERO,Math.sqrt(2))})},c}),define("Workers/createPlaneOutlineGeometry",["../Core/PlaneOutlineGeometry","../Core/defined"],function(e,t){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonGeometry.js index 91284a28..71755af0 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonGeometry.js @@ -222,10 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:p,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,p=i.y,m=i.z,y=l*l*d*d,E=f*f*p*p,_=h*h*m*m,v=y+E+_,T=Math.sqrt(1/v),R=e.multiplyByScalar(n,T,a);if(v<s)return isFinite(T)?e.clone(R,c):void 0;var A=u.x,g=u.y,S=u.z,N=o;N.x=R.x*A*2,N.y=R.y*g*2,N.z=R.z*S*2;var O,x,w,I,M,C,P,D,L,b,U,F=(1-T)*e.magnitude(n)/(.5*e.magnitude(N)),B=0;do{F-=B,w=1/(1+F*A),I=1/(1+F*g),M=1/(1+F*S),C=w*w,P=I*I,D=M*M,L=C*w,b=P*I,U=D*M,O=y*C+E*P+_*D-1,x=y*L*A+E*b*g+_*U*S;B=O/(-2*x)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*w,c.y=f*I,c.z=h*M,c):new e(l*w,f*I,h*M)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var p=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,y=r(n)?n._centerToleranceSquared:d,E=o(t,p,m,y,c);if(r(E)){var _=e.multiplyComponents(E,m,s);_=e.normalize(_,_);var v=e.subtract(t,E,l),T=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=a.sign(e.dot(v,t))*e.magnitude(v);return r(i)?(i.longitude=T,i.latitude=R,i.height=A,i):new u(T,R,A)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var p=new e,m=new e,y=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(n,a,y),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,m=e.length;p<m;p++){var y=t.cartesianToCartographic(e[p]);o=Math.min(o,y.longitude),c=Math.max(c,y.longitude),h=Math.min(h,y.latitude),d=Math.max(d,y.latitude);var E=y.longitude>=0?y.longitude:y.longitude+u.TWO_PI;l=Math.min(l,E),f=Math.max(f,E)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,m=c;m.height=i,m.longitude=p,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var y=1;y<8;++y)m.longitude=-Math.PI+y*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.width=r(n,0),this.height=r(i,0)}s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.width,t[n]=e.height,t},s.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new s),n.x=e[t++],n.y=e[t++],n.width=e[t++],n.height=e[t],n},s.fromPoints=function(e,t){if(i(t)||(t=new s),!i(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var n=e.length,r=e[0].x,a=e[0].y,o=e[0].x,u=e[0].y,c=1;c<n;c++){var l=e[c],f=l.x,h=l.y;r=Math.min(f,r),o=Math.max(f,o),a=Math.min(h,a),u=Math.max(h,u)}return t.x=r,t.y=a,t.width=o-r,t.height=u-a,t};var c=new a,l=new t,f=new t;return s.fromRectangle=function(t,n,a){if(i(a)||(a=new s),!i(t))return a.x=0,a.y=0,a.width=0,a.height=0,a;n=r(n,c);var o=n.project(u.southwest(t,l)),h=n.project(u.northeast(t,f));return e.subtract(h,o,h),a.x=o.x,a.y=o.y,a.width=h.x,a.height=h.y,a},s.clone=function(e,t){if(i(e))return i(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new s(e.x,e.y,e.width,e.height)},s.union=function(e,t,n){i(n)||(n=new s);var r=Math.min(e.x,t.x),a=Math.min(e.y,t.y),o=Math.max(e.x+e.width,t.x+t.width),u=Math.max(e.y+e.height,t.y+t.height);return n.x=r,n.y=a,n.width=o-r,n.height=u-a,n},s.expand=function(e,t,n){n=s.clone(e,n);var r=t.x-n.x,i=t.y-n.y;return r>n.width?n.width=r:r<0&&(n.width-=r,n.x=t.x),i>n.height?n.height=i:i<0&&(n.height-=i,n.y=t.y),n},s.intersect=function(e,t){var n=e.x,r=e.y,i=t.x,a=t.y;return n>i+t.width||n+e.width<i||r+e.height<a||r>a+t.height?o.OUTSIDE:o.INTERSECTING},s.equals=function(e,t){return e===t||i(e)&&i(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.intersect=function(e){return s.intersect(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],p[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],p[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=p[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,y=e[s.getElementIndex(h,h)],E=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],v=(y-E)/2/_;d=v<0?-1/(-v+Math.sqrt(1+v*v)):1/(v+Math.sqrt(1+v*v)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i}, -s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=n-u-f+d,m=2*(i-h),y=2*(a+l),E=2*(i+h),_=-n+u-f+d,v=2*(c-o),T=2*(a-l),R=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=p,t[1]=E,t[2]=T,t[3]=m,t[4]=_,t[5]=R,t[6]=y,t[7]=v,t[8]=A,t):new s(p,m,y,E,_,v,T,R,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,p=a*i+c*o*u,m=-c*i+a*o*u,y=-o,E=c*n,_=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=y,t[3]=f,t[4]=p,t[5]=E,t[6]=h,t[7]=m,t[8]=_,t):new s(l,f,h,d,p,m,y,E,_)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],m=[2,2,1],y=new s,E=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,y),s.transpose(y,E),s.multiply(h,y,h),s.multiply(E,h,h),s.multiply(o,y,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,p,m,y){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(p,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(y,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,m=t.y*t.w,y=t.z*t.z,E=t.z*t.w,_=t.w*t.w,v=s-d-y+_,T=2*(c-E),R=2*(f+m),A=2*(c+E),g=-s+d-y+_,S=2*(p-h),N=2*(f-m),O=2*(p+h),x=-s-d+y+_;return r[0]=v*a,r[1]=A*a,r[2]=N*a,r[3]=0,r[4]=T*o,r[5]=g*o,r[6]=O*o,r[7]=0,r[8]=R*u,r[9]=S*u,r[10]=x*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,m=f.y,y=f.z,E=d.x,_=d.y,v=d.z,T=r.x,R=r.y,A=r.z,g=u*-T+s*-R+c*-A,S=E*-T+_*-R+v*-A,N=p*T+m*R+y*A;return i(n)?(n[0]=u,n[1]=E,n[2]=-p,n[3]=0,n[4]=s,n[5]=_,n[6]=-m,n[7]=0,n[8]=c,n[9]=v,n[10]=-y,n[11]=0,n[12]=g,n[13]=S,n[14]=N,n[15]=1,n):new l(u,s,c,g,E,_,v,S,-p,-m,-y,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,p=f,m=a+c,y=o+l,E=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=m,i[13]=y,i[14]=E,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var p=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],m=e[12],y=e[13],E=e[14],_=e[15],v=t[0],T=t[1],R=t[2],A=t[3],g=t[4],S=t[5],N=t[6],O=t[7],x=t[8],w=t[9],I=t[10],M=t[11],C=t[12],P=t[13],D=t[14],L=t[15],b=r*v+u*T+f*R+m*A,U=i*v+s*T+h*R+y*A,F=a*v+c*T+d*R+E*A,B=o*v+l*T+p*R+_*A,z=r*g+u*S+f*N+m*O,G=i*g+s*S+h*N+y*O,q=a*g+c*S+d*N+E*O,V=o*g+l*S+p*N+_*O,W=r*x+u*w+f*I+m*M,H=i*x+s*w+h*I+y*M,X=a*x+c*w+d*I+E*M,k=o*x+l*w+p*I+_*M,Y=r*C+u*P+f*D+m*L,Z=i*C+s*P+h*D+y*L,j=a*C+c*P+d*D+E*L,K=o*C+l*P+p*D+_*L;return n[0]=b,n[1]=U,n[2]=F,n[3]=B,n[4]=z,n[5]=G,n[6]=q,n[7]=V,n[8]=W,n[9]=H,n[10]=X,n[11]=k,n[12]=Y,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],m=t[0],y=t[1],E=t[2],_=t[4],v=t[5],T=t[6],R=t[8],A=t[9],g=t[10],S=t[12],N=t[13],O=t[14],x=r*m+o*y+c*E,w=i*m+u*y+l*E,I=a*m+s*y+f*E,M=r*_+o*v+c*T,C=i*_+u*v+l*T,P=a*_+s*v+f*T,D=r*R+o*A+c*g,L=i*R+u*A+l*g,b=a*R+s*A+f*g,U=r*S+o*N+c*O+h,F=i*S+u*N+l*O+d,B=a*S+s*N+f*O+p;return n[0]=x,n[1]=w,n[2]=I,n[3]=0,n[4]=M,n[5]=C,n[6]=P,n[7]=0,n[8]=D,n[9]=L,n[10]=b,n[11]=0,n[12]=U,n[13]=F,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],m=t[3],y=t[4],E=t[5],_=t[6],v=t[7],T=t[8],R=r*h+o*d+c*p,A=i*h+u*d+l*p,g=a*h+s*d+f*p,S=r*m+o*y+c*E,N=i*m+u*y+l*E,O=a*m+s*y+f*E,x=r*_+o*v+c*T,w=i*_+u*v+l*T,I=a*_+s*v+f*T;return n[0]=R,n[1]=A,n[2]=g,n[3]=0,n[4]=S,n[5]=N,n[6]=O,n[7]=0,n[8]=x,n[9]=w,n[10]=I,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var y=new e;l.multiplyByUniformScale=function(e,t,n){return y.x=t,y.y=t,y.z=t,l.multiplyByScale(e,y,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var E=new s,_=new s,v=new t,T=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,E),_,u.EPSILON7)&&t.equals(l.getRow(e,3,v),T))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],m=e[2],y=e[6],R=e[10],A=e[14],g=e[3],S=e[7],N=e[11],O=e[15],x=R*O,w=A*N,I=y*O,M=A*S,C=y*N,P=R*S,D=m*O,L=A*g,b=m*N,U=R*g,F=m*S,B=y*g,z=x*h+M*d+C*p-(w*h+I*d+P*p),G=w*f+D*d+U*p-(x*f+L*d+b*p),q=I*f+L*h+F*p-(M*f+D*h+B*p),V=P*f+b*h+B*d-(C*f+U*h+F*d),W=w*i+I*a+P*o-(x*i+M*a+C*o),H=x*r+L*a+b*o-(w*r+D*a+U*o),X=M*r+D*i+B*o-(I*r+L*i+F*o),k=C*r+U*i+F*a-(P*r+b*i+B*a);x=a*p,w=o*d,I=i*p,M=o*h,C=i*d,P=a*h,D=r*p,L=o*f,b=r*d,U=a*f,F=r*h,B=i*f;var Y=x*S+M*N+C*O-(w*S+I*N+P*O),Z=w*g+D*N+U*O-(x*g+L*N+b*O),j=I*g+L*S+F*O-(M*g+D*S+B*O),K=P*g+b*S+B*N-(C*g+U*S+F*N),J=I*R+P*A+w*y-(C*A+x*y+M*R),Q=b*A+x*m+L*R-(D*R+U*A+w*m),$=D*y+B*A+M*m-(F*A+I*m+L*y),ee=F*R+C*m+U*y-(b*y+B*R+P*m),te=r*z+i*G+a*q+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=G*te,n[2]=q*te,n[3]=V*te,n[4]=W*te,n[5]=H*te,n[6]=X*te,n[7]=k*te,n[8]=Y*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-n*f-r*h-i*d,m=-a*f-o*h-u*d,y=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=m,t[14]=y,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,p=new e,m=new e,y=new e,E=new e,_=new e,v=new e,T=new e,R=new e,A=new e,g=new e,S=new e;h.fromPoints=function(t,n){if(i(n)||(n=new h),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],v),o=e.clone(a,d),u=e.clone(a,p),s=e.clone(a,m),c=e.clone(a,y),l=e.clone(a,E),f=e.clone(a,_),N=t.length;for(r=1;r<N;r++){e.clone(t[r],a);var O=a.x,x=a.y,w=a.z;O<o.x&&e.clone(a,o),O>c.x&&e.clone(a,c),x<u.y&&e.clone(a,u),x>l.y&&e.clone(a,l),w<s.z&&e.clone(a,s),w>f.z&&e.clone(a,f)}var I=e.magnitudeSquared(e.subtract(c,o,T)),M=e.magnitudeSquared(e.subtract(l,u,T)),C=e.magnitudeSquared(e.subtract(f,s,T)),P=o,D=c,L=I;M>L&&(L=M,P=u,D=l),C>L&&(L=C,P=s,D=f);var b=R;b.x=.5*(P.x+D.x),b.y=.5*(P.y+D.y),b.z=.5*(P.z+D.z);var U=e.magnitudeSquared(e.subtract(D,b,T)),F=Math.sqrt(U),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var G=e.multiplyByScalar(e.add(B,z,T),.5,S),q=0;for(r=0;r<N;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,G,T));V>q&&(q=V);var W=e.magnitudeSquared(e.subtract(a,b,T));if(W>U){var H=Math.sqrt(W);F=.5*(F+H),U=F*F;var X=H-F;b.x=(F*b.x+X*a.x)/H,b.y=(F*b.y+X*a.y)/H,b.z=(F*b.z+X*a.z)/H}}return F<q?(e.clone(b,n.center),n.radius=F):(e.clone(G,n.center),n.radius=q),n};var N=new o,O=new e,x=new e,w=new t,I=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,N),f.southwest(t,w),w.height=a,f.northeast(t,I),I.height=o;var s=n.project(w,O),c=n.project(I,x),l=c.x-s.x,d=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+p*p);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*p,u};var M=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,M);return h.fromPoints(s,u)},h.fromVertices=function(t,n,a,o){if(i(o)||(o=new h),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=v;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,p),f=e.clone(u,m),N=e.clone(u,y),O=e.clone(u,E),x=e.clone(u,_),w=t.length;for(s=0;s<w;s+=a){var I=t[s]+n.x,M=t[s+1]+n.y,C=t[s+2]+n.z;u.x=I,u.y=M,u.z=C,I<c.x&&e.clone(u,c),I>N.x&&e.clone(u,N),M<l.y&&e.clone(u,l),M>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>x.z&&e.clone(u,x)}var P=e.magnitudeSquared(e.subtract(N,c,T)),D=e.magnitudeSquared(e.subtract(O,l,T)),L=e.magnitudeSquared(e.subtract(x,f,T)),b=c,U=N,F=P;D>F&&(F=D,b=l,U=O),L>F&&(F=L,b=f,U=x);var B=R;B.x=.5*(b.x+U.x),B.y=.5*(b.y+U.y),B.z=.5*(b.z+U.z);var z=e.magnitudeSquared(e.subtract(U,B,T)),G=Math.sqrt(z),q=A;q.x=c.x,q.y=l.y,q.z=f.z;var V=g;V.x=N.x,V.y=O.y,V.z=x.z;var W=e.multiplyByScalar(e.add(q,V,T),.5,S),H=0;for(s=0;s<w;s+=a){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var X=e.magnitude(e.subtract(u,W,T));X>H&&(H=X);var k=e.magnitudeSquared(e.subtract(u,B,T));if(k>z){var Y=Math.sqrt(k);G=.5*(G+Y),z=G*G;var Z=Y-G;B.x=(G*B.x+Z*u.x)/Y,B.y=(G*B.y+Z*u.y)/Y,B.z=(G*B.z+Z*u.z)/Y}}return G<H?(e.clone(B,o.center),o.radius=G):(e.clone(W,o.center),o.radius=H),o},h.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new h),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=v;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,d),s=e.clone(a,p),c=e.clone(a,m),l=e.clone(a,y),f=e.clone(a,E),N=e.clone(a,_),O=t.length;for(o=0;o<O;o+=3){var x=t[o]+n[o],w=t[o+1]+n[o+1],I=t[o+2]+n[o+2];a.x=x,a.y=w,a.z=I,x<u.x&&e.clone(a,u),x>l.x&&e.clone(a,l),w<s.y&&e.clone(a,s),w>f.y&&e.clone(a,f),I<c.z&&e.clone(a,c),I>N.z&&e.clone(a,N)}var M=e.magnitudeSquared(e.subtract(l,u,T)),C=e.magnitudeSquared(e.subtract(f,s,T)),P=e.magnitudeSquared(e.subtract(N,c,T)),D=u,L=l,b=M;C>b&&(b=C,D=s,L=f),P>b&&(b=P,D=c,L=N);var U=R;U.x=.5*(D.x+L.x),U.y=.5*(D.y+L.y),U.z=.5*(D.z+L.z);var F=e.magnitudeSquared(e.subtract(L,U,T)),B=Math.sqrt(F),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var G=g;G.x=l.x,G.y=f.y,G.z=N.z;var q=e.multiplyByScalar(e.add(z,G,T),.5,S),V=0;for(o=0;o<O;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(a,q,T));W>V&&(V=W);var H=e.magnitudeSquared(e.subtract(a,U,T));if(H>F){var X=Math.sqrt(H);B=.5*(B+X),F=B*B;var k=X-B;U.x=(B*U.x+k*a.x)/X,U.y=(B*U.y+k*a.y)/X,U.z=(B*U.z+k*a.z)/X}}return B<V?(e.clone(U,r.center),r.radius=B):(e.clone(q,r.center),r.radius=V),r},h.fromCornerPoints=function(t,n,r){i(r)||(r=new h);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},h.fromEllipsoid=function(t,n){return i(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;h.fromBoundingSpheres=function(t,n){if(i(n)||(n=new h),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,D=new e,L=new e;h.fromOrientedBoundingBox=function(t,n){i(n)||(n=new h);var r=t.halfAxes,a=c.getColumn(r,0,P),o=c.getColumn(r,1,D),u=c.getColumn(r,2,L);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},h.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new h);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var b=new e,U=new e;h.union=function(t,n,r){i(r)||(r=new h);var a=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,a,b),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,U);return e.add(d,a,d),e.clone(d,r.center),r.radius=f,r};var F=new e;h.expand=function(t,n,r){r=h.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,F));return i>r.radius&&(r.radius=i),r},h.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){ -return i(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var B=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,B);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return i(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,a){i(a)||(a=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var G=new e,q=new e,V=new e,W=new e,H=new e,X=new t,k=new Array(8),Y=0;Y<8;++Y)k[Y]=new e;var Z=new o;return h.projectTo2D=function(t,n,i){n=r(n,Z);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,G),c=e.cross(e.UNIT_Z,s,q);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,H),d=e.negate(c,W),p=k,m=p[0];e.add(s,l,m),e.add(m,c,m),m=p[1],e.add(s,l,m),e.add(m,d,m),m=p[2],e.add(s,f,m),e.add(m,d,m),m=p[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=p[4],e.add(s,l,m),e.add(m,c,m),m=p[5],e.add(s,l,m),e.add(m,d,m),m=p[6],e.add(s,f,m),e.add(m,d,m),m=p[7],e.add(s,f,m),e.add(m,c,m);for(var y=p.length,E=0;E<y;++E){var _=p[E];e.add(o,_,_);var v=a.cartesianToCartographic(_,X);n.project(v,_)}i=h.fromPoints(p,i),o=i.center;var T=o.x,R=o.y,A=o.z;return o.x=A,o.y=T,o.z=R,i},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(R=!0,A=r(e[1]))}return R}function a(){return i()&&A}function o(){if(!t(g)&&(g=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(T.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(g=!0,S=r(e[1]))}return g}function u(){return o()&&S}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(T.userAgent);null!==e&&(N=!0,O=r(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(x)){x=!1;var e;"Microsoft Internet Explorer"===T.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(x=!0,w=r(e[1])):"Netscape"===T.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(x=!0,w=r(e[1]))}return x}function f(){return l()&&w}function h(){if(!t(I)){I=!1;var e=/ Edge\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(I=!0,M=r(e[1]))}return I}function d(){return h()&&M}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(T.appVersion)),D}function y(){return p()&&P}function E(){return t(L)||(L="undefined"!=typeof PointerEvent&&(!t(T.pointerEnabled)||T.pointerEnabled)),L}function _(){if(!t(U)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;U=t(n)&&""!==n,U&&(b=n)}return U}function v(){return _()?b:void 0}var T;T="undefined"!=typeof navigator?navigator:{};var R,A,g,S,N,O,x,w,I,M,C,P,D,L,b,U,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:y,isWindows:m,hardwareConcurrency:e(T.hardwareConcurrency,3),supportsPointerEvents:E,supportsImageRenderingPixelated:_,imageRenderingValue:v};return F.supportsFullscreen=function(){return n.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],p=d.x,m=d.y,y=d.z;i=Math.min(p,i),s=Math.max(p,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(y,u),l=Math.max(y,l)}var E=n.minimum;E.x=i,E.y=o,E.z=u;var _=n.maximum;_.x=s,_.y=c,_.z=l;var v=e.add(E,_,n.center);return e.multiplyByScalar(v,.5,v),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,m=o*c-u*s,y=u*c-d,E=4*p*y-m*m;if(E<0){var _,v,T;h*f>=l*d?(_=o,v=p,T=-2*u*p+o*m):(_=c,v=y,T=-c*m+2*s*y);var R=T<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-E);a=-T+A;var g=a/2,S=g<0?-Math.pow(-g,1/3):Math.pow(g,1/3),N=a===A?-S:-v/S;return i=v<=0?S+N:-T/(S*S+N*N+v),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var O=p,x=-2*u*p+o*m,w=y,I=-c*m+2*s*y,M=Math.sqrt(E),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*M,-x)/3);i=2*Math.sqrt(-O);var D=Math.cos(P);a=i*D;var L=i*(-D/2-C*Math.sin(P)),b=a+L>2*u?a-u:L-u,U=o,F=b/U;P=Math.abs(Math.atan2(c*M,-I)/3),i=2*Math.sqrt(-w),D=Math.cos(P),a=i*D,L=i*(-D/2-C*Math.sin(P));var B=-c,z=a+L<2*s?a+s:L+s,G=B/z,q=U*z,V=-b*z-U*B,W=b*B,H=(s*V-u*W)/(-u*V+s*q);return F<=H?F<=G?H<=G?[F,H,G]:[F,G,H]:[G,F,H]:F<=G?[H,F,G]:H<=G?[H,G,F]:[G,H,F]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var p=r.computeRealRoots(1,s,l);if(2===p.length){var m,y=p[0],E=p[1];if(y>=0&&E>=0){var _=Math.sqrt(y),v=Math.sqrt(E);return[h-v,h-_,h+_,h+v]}if(y>=0&&E<0)return m=Math.sqrt(y),[h-m,h+m];if(y<0&&E>=0)return m=Math.sqrt(E),[h-m,h+m]}return[]}if(d>0){var T=Math.sqrt(d),R=(s+d-c/T)/2,A=(s+d+c/T)/2,g=r.computeRealRoots(1,T,R),S=r.computeRealRoots(1,-T,A);return 0!==g.length?(g[0]+=h,g[1]+=h,0!==S.length?(S[0]+=h,S[1]+=h,g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>S[0]&&g[0]<S[1]?[S[0],g[0],S[1],g[1]]:[g[0],S[0],g[1],S[1]]):g):0!==S.length?(S[0]+=h,S[1]+=h,S):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,m,y=d[0],E=i-y,_=E*E,v=t/2,T=E/2,R=_-4*o,A=_+4*Math.abs(o),g=c-4*y,S=c+4*Math.abs(y);if(y<0||R*S<g*A){var N=Math.sqrt(g);p=N/2,m=0===N?0:(t*T-a)/N}else{var O=Math.sqrt(R);p=0===O?0:(t*T-a)/O,m=O/2}var x,w;0===v&&0===p?(x=0,w=0):n.sign(v)===n.sign(p)?(x=v+p,w=y/x):(w=v-p,x=y/w);var I,M;0===T&&0===m?(I=0,M=0):n.sign(T)===n.sign(m)?(I=T+m,M=o/I):(M=T-m,I=o/M);var C=r.computeRealRoots(1,x,I),P=r.computeRealRoots(1,w,M);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,m=f(h,d,p,A);if(r(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function p(t,n,r,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),y=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,E=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),v=[];if(0===_&&0===E){if(l=s.computeRealRoots(p,m,y),0===l.length)return v;var T=l[0],R=Math.sqrt(Math.max(1-T*T,0));if(v.push(new e(i,a*T,a*-R)),v.push(new e(i,a*T,a*R)),2===l.length){var A=l[1],g=Math.sqrt(Math.max(1-A*A,0));v.push(new e(i,a*A,a*-g)),v.push(new e(i,a*A,a*g))}return v}var S=_*_,N=E*E,O=p*p,x=_*E,w=O+N,I=2*(m*p+x),M=2*y*p+m*m-N+S,C=2*(y*m-x),P=y*y-S;if(0===w&&0===I&&0===M&&0===C)return v;l=c.computeRealRoots(w,I,M,C,P);var D=l.length;if(0===D)return v;for(var L=0;L<D;++L){var b,U=l[L],F=U*U,B=Math.max(1-F,0),z=Math.sqrt(B);b=o.sign(p)===o.sign(y)?d(p*F+y,m*U,o.EPSILON12):o.sign(y)===o.sign(m*U)?d(p*F,m*U+y,o.EPSILON12):d(p*F+m*U,y,o.EPSILON12);var G=d(E*U,_,o.EPSILON15),q=b*G;q<0?v.push(new e(i,a*U,a*z)):q>0?v.push(new e(i,a*U,a*-z)):0!==z?(v.push(new e(i,a*U,a*-z)),v.push(new e(i,a*U,a*z)),++L):v.push(new e(i,a*U,a*z))}return v}var m={};m.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var y=new e,E=new e,_=new e,v=new e,T=new e;m.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,m=e.subtract(i,r,y),R=e.subtract(a,r,E),A=e.cross(p,R,_),g=e.dot(m,A);if(u){if(g<o.EPSILON6)return;if(s=e.subtract(d,r,v),(l=e.dot(s,A))<0||l>g)return;if(c=e.cross(s,m,T),(f=e.dot(p,c))<0||l+f>g)return;h=e.dot(R,c)/g}else{if(Math.abs(g)<o.EPSILON6)return;var S=1/g;if(s=e.subtract(d,r,v),(l=e.dot(s,A)*S)<0||l>1)return;if(c=e.cross(s,m,T),(f=e.dot(p,c)*S)<0||l+f>1)return;h=e.dot(R,c)*S}return h},m.rayTriangle=function(t,n,i,a,o,u){var s=m.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e), -e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;m.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var g=new l;m.lineSegmentSphere=function(t,n,i,a){var o=g;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var S=new e,N=new e;m.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,S),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,y=r/s;return m<y?new a(m,y):{start:y,stop:m}}var E=Math.sqrt(r/i);return new a(E,E)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var O=new e,x=new e,w=new e,I=new e,M=new e,C=new u,P=new u,D=new u,L=new u,b=new u,U=new u,F=new u,B=new e,z=new e,G=new t;m.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,O);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,I),d=e.normalize(e.cross(h,f,x),x),m=e.normalize(e.cross(f,d,w),w),y=C;y[0]=f.x,y[1]=f.y,y[2]=f.z,y[3]=d.x,y[4]=d.y,y[5]=d.z,y[6]=m.x,y[7]=m.y,y[8]=m.z;var E=u.transpose(y,P),_=u.fromScale(n.radii,D),v=u.fromScale(n.oneOverRadii,L),T=b;T[0]=0,T[1]=-a.z,T[2]=a.y,T[3]=a.z,T[4]=0,T[5]=-a.x,T[6]=-a.y,T[7]=a.x,T[8]=0;var R,A,g=u.multiply(u.multiply(E,v,U),T,U),S=u.multiply(u.multiply(g,_,F),y,F),N=u.multiplyByVector(g,i,M),q=p(S,e.negate(N,O),0,0,1),V=q.length;if(V>0){for(var W=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,X=0;X<V;++X){R=u.multiplyByVector(_,u.multiplyByVector(y,q[X],B),B);var k=e.normalize(e.subtract(R,i,I),I),Y=e.dot(k,a);Y>H&&(H=Y,W=e.clone(R,W))}var Z=n.cartesianToCartographic(W,G);return H=o.clamp(H,0,1),A=e.magnitude(e.subtract(W,i,I))*Math.sqrt(1-H*H),A=c?-A:A,Z.height=A,n.cartographicToCartesian(Z,new e)}};var q=new e;return m.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,q),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return m(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=E,m(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return y(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){p(e)}var c,l,f,h,d,p,m,y,_,v;if(_=t.length>>>0,c=Math.max(0,Math.min(n,_)),f=[],l=_-c+1,h=[],d=o(),c)for(y=d.progress,m=function(e){h.push(e),--l||(p=m=E,d.reject(h))},p=function(e){f.push(e),--c||(p=m=E,d.resolve(f))},v=0;v<_;++v)v in t&&e(t[v],s,u,y);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return y(1,arguments),h(e,_).then(t,n,r)}function f(){return h(arguments,_)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=T.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},v.apply(t,r)})}function p(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function y(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function E(){}function _(e){return e}var v,T,R;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},T=[].slice,v=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,p,m,y,E;if("%%"==e)return"%";for(var _=!1,v="",T=!1,R=!1,A=" ",g=s.length,S=0;s&&S<g;S++)switch(s.charAt(S)){case" ":v=" ";break;case"+":v="+";break;case"-":_=!0;break;case"'":A=s.charAt(S+1);break;case"0":T=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,E=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(E),_,c,f,T,A);case"c":return u(String.fromCharCode(+E),_,c,f,T);case"b":return o(E,2,R,_,c,f,T);case"o":return o(E,8,R,_,c,f,T);case"x":return o(E,16,R,_,c,f,T);case"X":return o(E,16,R,_,c,f,T).toUpperCase();case"u":return o(E,10,R,_,c,f,T);case"i":case"d":return d=+E||0,d=Math.round(d-d%1),p=d<0?"-":v,E=p+i(String(Math.abs(d)),f,"0",!1),a(E,p,_,c,T);case"e":case"E":case"f":case"F":case"g":case"G":return d=+E,p=d<0?"-":v,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],y=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],E=p+Math.abs(d)[m](f),a(E,p,_,c,T)[y]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var n=m.leapSeconds,r=t(n,_,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}m.addSeconds(e,i,e)}function h(e,n){_.julianDate=e;var r=m.leapSeconds,i=t(r,_,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-r[0].offset,n);if(i>=r.length)return m.addSeconds(e,-r[i-1].offset,n);var a=m.secondsDifference(r[i].julianDate,e);return 0===a?m.addSeconds(e,-r[i].offset,n):a<=1?void 0:m.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function p(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var y=new a,E=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,v=/^(\d{4})$/,T=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,g=/^(\d{4})-?(\d{2})-?(\d{2})$/,S=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+S.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+S.source,x=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+S.source;m.fromGregorianDate=function(e,t){var n=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,y=0,_=0,S=0,w=u[0],I=u[1];if(null!==(u=w.match(g)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(T)))n=+u[1],s=+u[2];else if(null!==(u=w.match(v)))n=+u[1];else{var M;if(null!==(u=w.match(R)))n=+u[1],M=+u[2],a=o(n);else if(null!==(u=w.match(A))){n=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(n,0,4));M=7*C+P-D.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(M),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var L;if(r(I)){u=I.match(x),null!==u?(h=+u[1],y=+u[2],_=+u[3],S=1e3*+(u[4]||0),L=5):(u=I.match(O),null!==u?(h=+u[1],y=+u[2],_=60*+(u[3]||0),L=4):null!==(u=I.match(N))&&(h=+u[1],y=60*+(u[2]||0),L=3));var b=u[L],U=+u[L+1],F=+(u[L+2]||0);switch(b){case"+":h-=U,y-=F;break;case"-":h+=U,y+=F;break;case"Z":break;default:y+=new Date(Date.UTC(n,s-1,l,h,y)).getTimezoneOffset()}}var B=60===_;for(B&&_--;y>=60;)y-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:E[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:E[s-1];for(;y<0;)y+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:E[s-1],l+=i;var z=p(n,s,l,h,y,_,S);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var w=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,i=h(e,w);r(i)||(m.addSeconds(e,-1,w),i=h(w,w),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var y=d+2-12*c|0,E=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,v=u-_*s.SECONDS_PER_HOUR,T=v/s.SECONDS_PER_MINUTE|0;v-=T*s.SECONDS_PER_MINUTE;var R=0|v,A=(v-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),n&&(R+=1),r(t)?(t.year=E,t.month=y,t.day=p,t.hour=_,t.minute=T,t.second=R,t.millisecond=A,t.isLeapSecond=n,t):new a(E,y,p,_,T,R,A,n)},m.toDate=function(e){var t=m.toGregorianDate(e,y),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var i,a=m.toGregorianDate(t,y);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var n=m.leapSeconds,r=t(n,_,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.throttleByServer,!1),a=i||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return S[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function p(e){return function(t){e.state!==s.CANCELLED&&(--T.numberOfActiveRequests,--S[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++T.numberOfFailedRequests,--T.numberOfActiveRequests,--S[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function y(e){var t=d(e);return e.state=s.ACTIVE,g.push(e),++T.numberOfActiveRequests,++T.numberOfActiveRequestsEver,++S[e.serverKey],e.requestFunction().then(p(e)).otherwise(m(e)),t}function E(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++T.numberOfCancelledRequests,e.deferred.reject(),t&&(--T.numberOfActiveRequests,--S[e.serverKey],++T.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function _(){T.numberOfAttemptedRequests=0,T.numberOfCancelledRequests=0,T.numberOfCancelledActiveRequests=0}function v(){l.debugShowStatistics&&(T.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+T.numberOfAttemptedRequests),T.numberOfActiveRequests>0&&console.log("Number of active requests: "+T.numberOfActiveRequests),T.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+T.numberOfCancelledRequests),T.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+T.numberOfCancelledActiveRequests),T.numberOfFailedRequests>0&&console.log("Number of failed requests: "+T.numberOfFailedRequests),_())}var T={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},R=20,A=new a({comparator:c});A.maximumLength=R,A.reserve(R);var g=[],S={},N="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,i(l,{statistics:{get:function(){return T}},priorityHeapLength:{get:function(){return R},set:function(e){if(e<R)for(;A.length>e;){var t=A.pop();E(t)}R=e,A.maximumLength=e,A.reserve(e)}}}),l.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&E(t),t.state===s.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=A.internalArray,a=A.length;for(e=0;e<a;++e)f(i[e]);A.resort();for(var o=Math.max(l.maximumRequests-g.length,0),u=0;u<o&&A.length>0;)t=A.pop(),t.cancelled?E(t):!t.throttleByServer||h(t.serverKey)?(y(t),++u):E(t);v()},l.getServerKey=function(t){var n=new e(t).resolve(N);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=S[i];return r(a)||(S[i]=0),i},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++T.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return y(e);if(!(g.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=A.insert(e);if(r(t)){if(t===e)return;E(t)}return d(e)}},l.clearForSpecs=function(){for(;A.length>0;){E(A.pop())}for(var e=g.length,t=0;t<e;++t)E(g[t]);g.length=0,S={},T.numberOfAttemptedRequests=0,T.numberOfActiveRequests=0,T.numberOfCancelledRequests=0,T.numberOfCancelledActiveRequests=0,T.numberOfFailedRequests=0,T.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return S[e]},l.requestHeap=A,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var i=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;i=n(i,t.url);var d=r(t.request)?t.request:new a;return d.url=i,d.requestFunction=function(){var t=e.defer(),n=l.load(i,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function d(e,t){t=n(t,"");var r=e[1],i=!!e[2],a=e[3];switch(t){case"":case"text":return f(i,a);case"arraybuffer":return h(i,a);case"blob":var o=h(i,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(i,a),r);case"json":return JSON.parse(f(i,a))}}var p=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,i,a,u,l){var f=p.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(a))for(var m in a)a.hasOwnProperty(m)&&h.setRequestHeader(m,a[m]);r(t)&&(h.responseType=t);var y=!1;return"string"==typeof e&&(y=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!y||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(i),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function i(n,i,o){t(i)?t(i.Accept)||(i=e(i),i.Accept=a.Accept):i=a;var u=r(n,i,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var a={Accept:"application/json,*/*;q=0.01"};return i}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1, -this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))p(this,t.data);else if(r(t.url)){var i=this;this._downloadPromise=e(s(t.url),function(e){p(i,e)},function(){i._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||p<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var y=e._samples=n.samples,E=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var _,v=e._addNewLeapSeconds,T=0,R=y.length;T<R;T+=e._columnCount){var A=y[T+i],g=y[T+m],S=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(S,g,f.TAI);if(E.push(N),v){if(g!==_&&r(_)){var O=o.leapSeconds,x=t(O,N,d);if(x<0){var w=new u(N,g);O.splice(~x,0,w)}}_=g}}}function m(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function y(e,t,n){return t+e*(n-t)}function E(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return m(e,n,i,s,u),u;if(r.equals(l))return m(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=n[h+e._ut1MinusUtcSecondsColumn],E=n[d+e._ut1MinusUtcSecondsColumn],_=E-p;if(_>.5||_<-.5){var v=n[h+e._taiMinusUtcSecondsColumn],T=n[d+e._taiMinusUtcSecondsColumn];v!==T&&(l.equals(r)?p=E:E-=T-v)}return u.xPoleWander=y(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=y(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=y(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=y(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=y(f,p,E),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!r(h),m=p||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!p&&h.equals(e)&&++s,l=s+1,E(this,a,this._samples,e,s,l,n),n}var y=t(a,e,o.compare,this._dateColumn);return y>=0?(y<a.length-1&&a[y+1].equals(e)&&++y,s=y,l=y):(l=~y,(s=l-1)<0&&(s=0)),this._lastIndex=s,E(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=t(r,document.location.href);var i=new e(r);return new e(n).resolve(i).toString()}return i}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(r,i,a){if(a=t(a,!0),r instanceof e||(r=new e(r)),i instanceof e||(i=new e(i)),"data"===r.scheme)return r.toString();if("data"===i.scheme)return i.toString();n(i.authority)&&!n(i.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?i.scheme=new e(document.location.href).scheme:i.scheme=r.scheme);var o=r;i.isAbsolute()&&(o=i);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?a?r.path.replace(/\/?$/,"/")+i.path.replace(/^\/?/g,""):r.path+i.path:i.path;var s=n(r.query),c=n(i.query);s&&c?u+="?"+r.query+"&"+i.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+i.query);var l=n(i.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+i.fragment),u}return i}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,i,a){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=p.exec(r);if(null!==i)return i[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return a.toUrl("../"+e)}function c(e){return i(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(a.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,p=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=p,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,i[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",i):t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var p,m,y=a-s*this._stepSizeDays,E=this._work,_=this._denominators,v=this._coef,T=this._xTable;for(p=0;p<=u;++p)E[p]=y-T[p];for(p=0;p<=u;++p){for(v[p]=1,m=0;m<=u;++m)m!==p&&(v[p]*=E[m]);v[p]*=_[p];var R=3*(s+p);n.x+=v[p]*d[R++],n.y+=v[p]*d[R++],n.s+=v[p]*d[R]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],m=h+d+p;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var y=l,E=0;d>h&&(E=1),p>h&&p>d&&(E=2);var _=y[E],v=y[_];n=Math.sqrt(e[u.getElementIndex(E,E)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(v,v)]+1);var T=f;T[E]=.5*n,n=.5/n,c=(e[u.getElementIndex(v,_)]-e[u.getElementIndex(_,v)])*n,T[_]=(e[u.getElementIndex(_,E)]+e[u.getElementIndex(E,_)])*n,T[v]=(e[u.getElementIndex(v,E)]+e[u.getElementIndex(E,v)])*n,i=-T[0],a=-T[1],o=-T[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(p,m,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var y=new e,E=new e,_=new s,v=new s,T=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,T),s.conjugate(T,T);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,T,_),_.w<0&&s.negate(_,_),s.computeAxis(_,y);var u=s.computeAngle(_);r[o]=y.x*u,r[o+1]=y.y*u,r[o+2]=y.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,E);var u=e.magnitude(E);return s.unpack(n,4*a,v),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(E,u,_),s.multiply(_,v,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,p=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=p,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,n,r){return R=s.multiplyByScalar(t,n,R),r=s.multiplyByScalar(e,1-n,r),s.add(R,r,r)};var A=new s,g=new s,S=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return g=s.multiplyByScalar(e,Math.sin((1-n)*u),g),S=s.multiplyByScalar(a,Math.sin(n*u),S),r=s.add(g,S,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var N=new e,O=new e,x=new s,w=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,x);s.multiply(a,r,w);var o=s.log(w,N);s.multiply(a,t,w);var u=s.log(w,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,x),s.multiply(n,x,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,x),u=s.slerp(n,r,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var I=new s,M=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=i.supportsTypedArrays()?new Float32Array(8):[],b=0;b<7;++b){var U=b+1,F=2*U+1;C[b]=1/(U*F),P[b]=U/F}return C[7]=M/136,P[7]=8*M/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,L[f]=(C[f]*l-P[f])*o;var h=i*n*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),p=s.multiplyByScalar(e,d,I);return s.multiplyByScalar(t,h,r),s.add(p,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,x),u=s.fastSlerp(n,r,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v){"use strict";var T={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},g={},S={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,O=new n,x=new n;T.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=R[e][t],a=e+t;return u(g[a])?r=g[a]:(r=function(r,a,s){if(u(s)||(s=new E),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(A[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(A[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(A[i],0,x),"east"!==i&&"west"!==i&&n.multiplyByScalar(x,c,x)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,S.up);var l=S.up,h=S.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,S.east),n.cross(l,h,S.north),n.multiplyByScalar(S.up,-1,S.down),n.multiplyByScalar(S.east,-1,S.west),n.multiplyByScalar(S.north,-1,S.south),N=S[e],O=S[t],x=S[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=x.x,s[9]=x.y,s[10]=x.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},g[a]=r),r},T.eastNorthUpToFixedFrame=T.localFrameToFixedFrameGenerator("east","north"),T.northEastDownToFixedFrame=T.localFrameToFixedFrameGenerator("north","east"),T.northUpEastToFixedFrame=T.localFrameToFixedFrameGenerator("north","up"),T.northWestUpToFixedFrame=T.localFrameToFixedFrameGenerator("north","west");var w=new _,I=new n(1,1,1),M=new E;T.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,T.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=E.fromTranslationQuaternionRotationScale(n.ZERO,u,I,M);return a=i(e,r,a),E.multiply(a,s,a)};var C=new E,P=new y;T.headingPitchRollQuaternion=function(e,t,n,r,i){var a=T.headingPitchRollToFixedFrame(e,t,n,r,C),o=E.getRotation(a,P);return _.fromRotationMatrix(o,i)};var D=m.TWO_PI/86400,L=new p;T.computeTemeToPseudoFixedMatrix=function(e,t){L=p.addSeconds(e,-p.computeTaiMinusUtc(e),L);var n,r=L.dayNumber,i=L.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/v.DAYS_PER_JULIAN_CENTURY:(a-.5)/v.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*v.SECONDS_PER_DAY)%v.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new y(h,d,0,-d,h,0,0,0,1)},T.iau2006XysData=new h,T.earthOrientationParameters=c.NONE;T.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=T.iau2006XysData.preload(n,r,i,a),u=T.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},T.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new y);var n=T.computeFixedToIcrfMatrix(e,t);if(u(n))return y.transpose(n,t)};var b=new d(0,0,0),U=new l(0,0,0,0,0,0),F=new y,B=new y;T.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new y);var n=T.earthOrientationParameters.compute(e,U);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=T.iau2006XysData.computeXysRadians(r,i,b);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=y.fromRotationZ(-a.s,B),h=y.multiply(l,f,F),d=e.dayNumber,E=e.secondsOfDay-p.computeTaiMinusUtc(e)+n.ut1MinusUtc,_=d-2451545,R=E/v.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*m.TWO_PI;var g=y.fromRotationZ(A,B),S=y.multiply(h,g,F),N=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),x=Math.sin(n.xPoleWander),w=Math.sin(n.yPoleWander),I=r-2451545+i/v.SECONDS_PER_DAY;I/=36525;var M=-47e-6*I*m.RADIANS_PER_DEGREE/3600,C=Math.cos(M),P=Math.sin(M),D=B;return D[0]=N*C,D[1]=N*P,D[2]=x,D[3]=-O*P+w*x*C,D[4]=O*C+w*x*P,D[5]=-w*N,D[6]=-w*P-O*x*C,D[7]=w*C-O*x*P,D[8]=O*N,y.multiply(S,D,t)}}};var z=new r;T.pointToWindowCoordinates=function(e,t,n,r){return r=T.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},T.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return E.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),E.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var G=new n,q=new n,V=new n;T.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,G),s=n.cross(t,a,q);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new y),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new E(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),H=new i,X=new n,k=new n,Y=new y,Z=new E,j=new E;return T.basisTo2D=function(e,t,r){var i=E.getTranslation(t,k),a=e.ellipsoid,o=a.cartesianToCartographic(i,H),u=e.project(o,X);n.fromElements(u.z,u.x,u.y,u);var s=T.eastNorthUpToFixedFrame(i,a,Z),c=E.inverseTransformation(s,j),l=E.getRotation(t,Y),f=E.multiplyByMatrix3(c,l,r);return E.multiply(W,f,r),E.setTranslation(r,u,r),r},T.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=T.eastNorthUpToFixedFrame(t,i,Z),o=E.inverseTransformation(a,j),u=i.cartesianToCartographic(t,H),s=e.project(u,X);n.fromElements(s.z,s.x,s.y,s);var c=E.fromTranslation(s,Z);return E.multiply(W,o,r),E.multiply(c,r,r),r},T}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function p(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var a=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,a)}var m=new r;o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var y=new e;p.fromPoints=function(t,n){return new p(e.fromPoints(t,y).center,n)};var E=new h,_=new n;p.prototype.projectPointOntoPlane=function(e,r){var i=E;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},p.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},p.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=E;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},p.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var v=new n;return p.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=v,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},p}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=r.clone(e(t.modelMatrix,r.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return i}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,i){"use strict";var a={};a.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,a=n.y;n.x=(1-Math.abs(a))*i.signNotZero(r),n.y=(1-Math.abs(r))*i.signNotZero(a)}return n.x=i.toSNorm(n.x,t),n.y=i.toSNorm(n.y,t),n},a.octEncode=function(e,t){return a.octEncodeInRange(e,255,t)},a.octDecodeInRange=function(e,n,r,a){if(a.x=i.fromSNorm(e,r),a.y=i.fromSNorm(n,r),a.z=1-(Math.abs(a.x)+Math.abs(a.y)),a.z<0){var o=a.x;a.x=(1-Math.abs(a.y))*i.signNotZero(o),a.y=(1-Math.abs(o))*i.signNotZero(a.y)}return t.normalize(a,a)},a.octDecode=function(e,t,n){return a.octDecodeInRange(e,t,255,n)},a.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return a.octEncodeFloat=function(e){return a.octEncode(e,o),a.octPackFloat(o)},a.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),i=256*(n-r);return a.octDecode(r,i,t)},a.octPack=function(e,t,n,r){var i=a.octEncodeFloat(e),u=a.octEncodeFloat(t),s=a.octEncode(n,o);return r.x=65536*s.x+i,r.y=65536*s.y+u,r},a.octUnpack=function(e,t,n,r){var i=e.x/65536,o=Math.floor(i),u=65536*(i-o);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);a.octDecodeFloat(u,t),a.octDecodeFloat(c,n),a.octDecode(o,s,r)},a.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},a.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},a}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,n,r){"use strict";function i(n,i,s,c,l){r(l)||(l=new t);var f,h,d,p,m,y,E,_;r(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(n,i,u),p=t.dot(f,f),m=t.dot(f,h),y=t.dot(f,d),E=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(n,i,u),p=e.dot(f,f),m=e.dot(f,h),y=e.dot(f,d),E=e.dot(h,h),_=e.dot(h,d));var v=1/(p*E-m*m);return l.y=(E*y-m*_)*v,l.z=(p*_-m*y)*v,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,n){"use strict";function r(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}r.encode=function(e,t){n(t)||(t={high:0,low:0});var r;return e>=0?(r=65536*Math.floor(e/65536),t.high=r,t.low=e-r):(r=65536*Math.floor(-e/65536),t.high=-r,t.low=e+r),t};var i={high:0,low:0};r.fromCartesian=function(e,t){n(t)||(t=new r);var a=t.high,o=t.low;return r.encode(e.x,i),a.x=i.high,o.x=i.low,r.encode(e.y,i),a.y=i.high,o.y=i.low,r.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new r;return r.writeElements=function(e,t,n){r.fromCartesian(e,a);var i=a.high,o=a.low;t[n]=i.x,t[n+1]=i.y,t[n+2]=i.z,t[n+3]=o.x,t[n+4]=o.y,t[n+5]=o.z},r}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";var r={};return r.calculateACMR=function(n){n=e(n,e.EMPTY_OBJECT);var r=n.indices,i=n.maximumIndex,a=e(n.cacheSize,24),o=r.length;if(!t(i)){i=0;for(var u=0,s=r[u];u<o;)s>i&&(i=s),++u,s=r[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[r[h]]>a&&(c[r[h]]=f,++f);return(f-a+1)/(o/3)},r.tipsify=function(n){function r(e,t,n,r){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<r;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}n=e(n,e.EMPTY_OBJECT);var i,a=n.indices,o=n.maximumIndex,u=e(n.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<h;)p[a[l]].vertexTriangles.push(m),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(m),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(m),++p[a[l+2]].numLiveTriangles,++m,l+=3;var y=0,E=u+1;i=1;var _,v,T=[],R=[],A=0,g=[],S=s/3,N=[];for(d=0;d<S;d++)N[d]=!1;for(var O,x;-1!==y;){T=[],v=p[y],x=v.vertexTriangles.length;for(var w=0;w<x;++w)if(m=v.vertexTriangles[w],!N[m]){N[m]=!0,l=m+m+m;for(var I=0;I<3;++I)O=a[l],T.push(O),R.push(O),g[A]=O,++A,_=p[O],--_.numLiveTriangles,E-_.timeStamp>u&&(_.timeStamp=E,++E),++l}y=function(e,t,n,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<n.length;){var h=n[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?r(i,o,e,u):c}(a,u,T,p,E,R,c)}return g},r}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,A,g,S){"use strict";function N(e,t,n,r,i){e[t++]=n,e[t++]=r,e[t++]=r,e[t++]=i,e[t++]=i,e[t]=n}function O(e){for(var t=e.length,n=t/3*6,r=y.createTypedArray(t,n),i=0,a=0;a<t;a+=3,i+=6)N(r,i,e[a],e[a+1],e[a+2]);return r}function x(e){var t=e.length;if(t>=3){var n=6*(t-2),r=y.createTypedArray(t,n);N(r,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)N(r,i,e[a-1],e[a],e[a-2]);return r}return new Uint16Array}function w(e){ -if(e.length>0){for(var t=e.length-1,n=6*(t-1),r=y.createTypedArray(t,n),i=e[0],a=0,o=1;o<t;++o,a+=6)N(r,a,i,e[o],e[o+1]);return r}return new Uint16Array}function I(e){var t={};for(var n in e)if(e.hasOwnProperty(n)&&c(e[n])&&c(e[n].values)){var r=e[n];t[n]=new p({componentDatatype:r.componentDatatype,componentsPerAttribute:r.componentsPerAttribute,normalize:r.normalize,values:[]})}return t}function M(e,t,n){for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values))for(var i=t[r],a=0;a<i.componentsPerAttribute;++a)e[r].values.push(i.values[n*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var n=t.values,r=n.length,a=0;a<r;a+=3)i.unpack(n,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,n,a)}function P(e,t){if(c(t))for(var n=t.values,r=n.length,a=0;a<r;a+=3)i.unpack(n,a,ae),T.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,n,a)}function D(e,t){var n,r=e.length,i={},a=e[0][t].attributes;for(n in a)if(a.hasOwnProperty(n)&&c(a[n])&&c(a[n].values)){for(var o=a[n],s=o.values.length,l=!0,f=1;f<r;++f){var h=e[f][t].attributes[n];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(i[n]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function L(e,t){var r,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,E=D(e,t);for(r in E)if(E.hasOwnProperty(r))for(s=E[r].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[r].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var v=0;for(a=0;a<h;++a)v+=e[a][t].indices.length;var T=d.computeNumberOfVertices(new d({attributes:E,primitiveType:g.POINTS})),R=y.createTypedArray(T,v),A=0,S=0;for(a=0;a<h;++a){var N=e[a][t].indices,O=N.length;for(u=0;u<O;++u)R[A++]=S+N[u];S+=d.computeNumberOfVertices(e[a][t])}_=R}var x,w=new i,I=0;for(a=0;a<h;++a){if(x=e[a][t].boundingSphere,!c(x)){w=void 0;break}i.add(x.center,w,w)}if(c(w))for(i.divideByScalar(w,h,w),a=0;a<h;++a){x=e[a][t].boundingSphere;var M=i.magnitude(i.subtract(x.center,w,se))+x.radius;M>I&&(I=M)}return new d({attributes:E,indices:_,primitiveType:m,boundingSphere:c(w)?new n(w,I):void 0})}function b(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),n=y.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function U(e){var t=d.computeNumberOfVertices(e),n=y.createTypedArray(t,3*(t-2));n[0]=1,n[1]=0,n[2]=2;for(var r=3,i=3;i<t;++i)n[r++]=i-1,n[r++]=0,n[r++]=i;return e.indices=n,e.primitiveType=g.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),n=y.createTypedArray(t,3*(t-2));n[0]=0,n[1]=1,n[2]=2,t>3&&(n[3]=0,n[4]=2,n[5]=3);for(var r=6,i=3;i<t-1;i+=2)n[r++]=i,n[r++]=i-1,n[r++]=i+1,i+2<t&&(n[r++]=i,n[r++]=i+1,n[r++]=i+2);return e.indices=n,e.primitiveType=g.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),n=y.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function z(e){var t=d.computeNumberOfVertices(e),n=y.createTypedArray(t,2*(t-1));n[0]=0,n[1]=1;for(var r=2,i=2;i<t;++i)n[r++]=i-1,n[r++]=i;return e.indices=n,e.primitiveType=g.LINES,e}function G(e){var t=d.computeNumberOfVertices(e),n=y.createTypedArray(t,2*t);n[0]=0,n[1]=1;for(var r=2,i=2;i<t;++i)n[r++]=i-1,n[r++]=i;return n[r++]=t-1,n[r]=0,e.indices=n,e.primitiveType=g.LINES,e}function q(e){switch(e.primitiveType){case g.TRIANGLE_FAN:return U(e);case g.TRIANGLE_STRIP:return F(e);case g.TRIANGLES:return b(e);case g.LINE_STRIP:return z(e);case g.LINE_LOOP:return G(e);case g.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<v.EPSILON6&&(e.y=t?-v.EPSILON6:v.EPSILON6)}function W(e,t,n){if(0!==e.y&&0!==t.y&&0!==n.y)return V(e,e.y<0),V(t,t.y<0),void V(n,n.y<0);var r,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(n.y);r=i>a?i>o?v.sign(e.y):v.sign(n.y):a>o?v.sign(t.y):v.sign(n.y);var u=r<0;V(e,u),V(t,u),V(n,u)}function H(e,t,n,r){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),n),i.clone(n,r),V(n,!0),V(r,!1)}function X(e,t,n){if(!(e.x>=0||t.x>=0||n.x>=0)){W(e,t,n);var r=e.y<0,i=t.y<0,a=n.y<0,o=0;o+=r?1:0,o+=i?1:0,o+=a?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,r?(H(e,t,Ae,Se),H(e,n,ge,Ne),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(H(t,n,Ae,Se),H(t,e,ge,Ne),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(H(n,e,Ae,Se),H(n,t,ge,Ne),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,r?i?a||(H(n,e,Ae,Se),H(n,t,ge,Ne),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(H(t,n,Ae,Se),H(t,e,ge,Ne),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(H(e,t,Ae,Se),H(e,n,ge,Ne),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=n,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=ge,s[5]=Se,s[6]=Ne,s.length=7),Oe}}function k(e,t){var r=e.attributes;if(0!==r.position.values.length){for(var i in r)if(r.hasOwnProperty(i)&&c(r[i])&&c(r[i].values)){var a=r[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=y.createTypedArray(o,e.indices),t&&(e.boundingSphere=n.fromVertices(r.position.values)),e}}function Y(e){var t=e.attributes,n={};for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values)){var i=t[r];n[r]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:n,indices:[],primitiveType:e.primitiveType})}function Z(e,t,n){var r=c(e.geometry.boundingSphere);t=k(t,r),n=k(n,r),c(n)&&!c(t)?e.geometry=n:!c(n)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=n,e.geometry=void 0)}function j(e,n,a,o,u,s,l,f,h,d,p,m){if(c(s)||c(l)||c(f)||c(h)||c(d)){var y=i.fromArray(u,3*e,xe),E=i.fromArray(u,3*n,we),_=i.fromArray(u,3*a,Ie),v=t(o,y,E,_,Me);if(c(s)){var T=i.fromArray(s,3*e,xe),R=i.fromArray(s,3*n,we),A=i.fromArray(s,3*a,Ie);i.multiplyByScalar(T,v.x,T),i.multiplyByScalar(R,v.y,R),i.multiplyByScalar(A,v.z,A);var g=i.add(T,R,T);i.add(g,A,g),i.normalize(g,g),i.pack(g,p.normal.values,3*m)}if(c(d)){var S=i.fromArray(d,3*e,xe),N=i.fromArray(d,3*n,we),O=i.fromArray(d,3*a,Ie);i.multiplyByScalar(S,v.x,S),i.multiplyByScalar(N,v.y,N),i.multiplyByScalar(O,v.z,O);var x;i.equals(S,i.ZERO)&&i.equals(N,i.ZERO)&&i.equals(O,i.ZERO)?(x=xe,x.x=0,x.y=0,x.z=0):(x=i.add(S,N,S),i.add(x,O,x),i.normalize(x,x)),i.pack(x,p.extrudeDirection.values,3*m)}if(c(l)){var w=i.fromArray(l,3*e,xe),I=i.fromArray(l,3*n,we),M=i.fromArray(l,3*a,Ie);i.multiplyByScalar(w,v.x,w),i.multiplyByScalar(I,v.y,I),i.multiplyByScalar(M,v.z,M);var C=i.add(w,I,w);i.add(C,M,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*m)}if(c(f)){var P=i.fromArray(f,3*e,xe),D=i.fromArray(f,3*n,we),L=i.fromArray(f,3*a,Ie);i.multiplyByScalar(P,v.x,P),i.multiplyByScalar(D,v.y,D),i.multiplyByScalar(L,v.z,L);var b=i.add(P,D,P);i.add(b,L,b),i.normalize(b,b),i.pack(b,p.bitangent.values,3*m)}if(c(h)){var U=r.fromArray(h,2*e,Ce),F=r.fromArray(h,2*n,Pe),B=r.fromArray(h,2*a,De);r.multiplyByScalar(U,v.x,U),r.multiplyByScalar(F,v.y,F),r.multiplyByScalar(B,v.z,B);var z=r.add(U,F,U);r.add(z,B,z),r.pack(z,p.st.values,2*m)}}}function K(e,t,n,r,i,a){var o=e.position.values.length/3;if(-1!==i){var u=r[i],s=n[u];return-1===s?(n[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,n,r,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,y=u.indices,E=Y(u),_=Y(u),v=[];v.length=l.length/3;var T=[];for(T.length=l.length/3,o=0;o<v.length;++o)v[o]=-1,T[o]=-1;var R=y.length;for(o=0;o<R;o+=3){var A=y[o],g=y[o+1],S=y[o+2],N=i.fromArray(l,3*A),O=i.fromArray(l,3*g),x=i.fromArray(l,3*S),w=X(N,O,x);if(c(w)&&w.positions.length>3)for(var I=w.positions,M=w.indices,C=M.length,P=0;P<C;++P){var D=M[P],L=I[D];L.y<0?(t=_.attributes,n=_.indices,r=v):(t=E.attributes,n=E.indices,r=T),a=K(t,n,r,y,D<3?o+D:-1,L),j(A,g,S,L,l,f,d,h,p,m,t,a)}else c(w)&&(N=w.positions[0],O=w.positions[1],x=w.positions[2]),N.y<0?(t=_.attributes,n=_.indices,r=v):(t=E.attributes,n=E.indices,r=T),a=K(t,n,r,y,o,N),j(A,g,S,N,l,f,d,h,p,m,t,a),a=K(t,n,r,y,o+1,O),j(A,g,S,O,l,f,d,h,p,m,t,a),a=K(t,n,r,y,o+2,x),j(A,g,S,x,l,f,d,h,p,m,t,a)}Z(e,_,E)}function Q(e){var t,n=e.geometry,r=n.attributes,a=r.position.values,o=n.indices,u=Y(n),s=Y(n),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],m=i.fromArray(a,3*d,xe),y=i.fromArray(a,3*p,we);Math.abs(m.y)<v.EPSILON6&&(m.y<0?m.y=-v.EPSILON6:m.y=v.EPSILON6),Math.abs(y.y)<v.EPSILON6&&(y.y<0?y.y=-v.EPSILON6:y.y=v.EPSILON6);var E=u.attributes,T=u.indices,R=h,A=s.attributes,g=s.indices,S=f,N=_.lineSegmentPlane(m,y,Le,Ie);if(c(N)){var O=i.multiplyByScalar(i.UNIT_Y,5*v.EPSILON9,be);m.y<0&&(i.negate(O,O),E=s.attributes,T=s.indices,R=f,A=u.attributes,g=u.indices,S=h);var x=i.add(N,O,Ue);K(E,T,R,o,t,m),K(E,T,R,o,-1,x),i.negate(O,O),i.add(N,O,x),K(A,g,S,o,-1,x),K(A,g,S,o,t+1,y)}else{var w,I,M;m.y<0?(w=s.attributes,I=s.indices,M=f):(w=u.attributes,I=u.indices,M=h),K(w,I,M,o,t,m),K(w,I,M,o,t+1,y)}}Z(e,s,u)}function $(e){for(var t=e.attributes,n=t.position.values,r=t.prevPosition.values,a=t.nextPosition.values,o=n.length,u=0;u<o;u+=3){var s=i.unpack(n,u,ze);if(!(s.x>0)){var c=i.unpack(r,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(r[u]=n[u-3],r[u+1]=n[u-2],r[u+2]=n[u-1]):i.pack(s,r,u));var l=i.unpack(a,u,qe);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=n[u+3],a[u+1]=n[u+4],a[u+2]=n[u+5]):i.pack(s,a,u))}}}function ee(e){var t,n,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,y=Y(u),E=Y(u),T=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,g=t+2,S=i.fromArray(l,3*A,ze),N=i.fromArray(l,3*g,Ge);if(Math.abs(S.y)<Ye)for(S.y=Ye*(N.y<0?-1:1),l[3*t+1]=S.y,l[3*(t+1)+1]=S.y,n=3*A;n<3*A+12;n+=3)f[n]=l[3*t],f[n+1]=l[3*t+1],f[n+2]=l[3*t+2];if(Math.abs(N.y)<Ye)for(N.y=Ye*(S.y<0?-1:1),l[3*(t+2)+1]=N.y,l[3*(t+3)+1]=N.y,n=3*A;n<3*A+12;n+=3)h[n]=l[3*(t+2)],h[n+1]=l[3*(t+2)+1],h[n+2]=l[3*(t+2)+2];var O=y.attributes,x=y.indices,w=E.attributes,I=E.indices,M=_.lineSegmentPlane(S,N,Le,Ve);if(c(M)){T=!0;var C=i.multiplyByScalar(i.UNIT_Y,ke,We);S.y<0&&(i.negate(C,C),O=E.attributes,x=E.indices,w=y.attributes,I=y.indices);var P=i.add(M,C,He);O.position.values.push(S.x,S.y,S.z,S.x,S.y,S.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),O.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),O.prevPosition.values.push(S.x,S.y,S.z,S.x,S.y,S.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(M,C,P),w.position.values.push(P.x,P.y,P.z),w.position.values.push(P.x,P.y,P.z),w.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.nextPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),w.nextPosition.values.push(h[3*g],h[3*g+1],h[3*g+2]),w.nextPosition.values.push(h[3*g+3],h[3*g+4],h[3*g+5]);var D=r.fromArray(d,2*A,Fe),L=Math.abs(D.y);O.expandAndWidth.values.push(-1,L,1,L),O.expandAndWidth.values.push(-1,-L,1,-L),w.expandAndWidth.values.push(-1,L,1,L),w.expandAndWidth.values.push(-1,-L,1,-L);var b=i.magnitudeSquared(i.subtract(M,S,qe));if(b/=i.magnitudeSquared(i.subtract(N,S,qe)),c(m)){var U=a.fromArray(m,4*A,Xe),F=a.fromArray(m,4*g,Xe),B=v.lerp(U.x,F.x,b),z=v.lerp(U.y,F.y,b),G=v.lerp(U.z,F.z,b),q=v.lerp(U.w,F.w,b);for(n=4*A;n<4*A+8;++n)O.color.values.push(m[n]);for(O.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),w.color.values.push(B,z,G,q),w.color.values.push(B,z,G,q),n=4*g;n<4*g+8;++n)w.color.values.push(m[n])}if(c(p)){var V=r.fromArray(p,2*A,Fe),W=r.fromArray(p,2*(t+3),Be),H=v.lerp(V.x,W.x,b);for(n=2*A;n<2*A+4;++n)O.st.values.push(p[n]);for(O.st.values.push(H,V.y),O.st.values.push(H,W.y),w.st.values.push(H,V.y),w.st.values.push(H,W.y),n=2*g;n<2*g+4;++n)w.st.values.push(p[n])}o=O.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3),o=w.position.values.length/3-4,I.push(o,o+2,o+1),I.push(o+1,o+2,o+3)}else{var X,k;for(S.y<0?(X=E.attributes,k=E.indices):(X=y.attributes,k=y.indices),X.position.values.push(S.x,S.y,S.z),X.position.values.push(S.x,S.y,S.z),X.position.values.push(N.x,N.y,N.z),X.position.values.push(N.x,N.y,N.z),n=3*t;n<3*t+12;++n)X.prevPosition.values.push(f[n]),X.nextPosition.values.push(h[n]);for(n=2*t;n<2*t+8;++n)X.expandAndWidth.values.push(d[n]),c(p)&&X.st.values.push(p[n]);if(c(m))for(n=4*t;n<4*t+16;++n)X.color.values.push(m[n]);o=X.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}T&&($(E),$(y)),Z(e,E,y)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case g.TRIANGLES:e.indices=O(t);break;case g.TRIANGLE_STRIP:e.indices=x(t);break;case g.TRIANGLE_FAN:e.indices=w(t)}e.primitiveType=g.LINES}return e},te.createLineSegmentsForVectors=function(e,t,r){t=s(t,"normal"),r=s(r,1e4);for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*r,l[f++]=i[h+1]+a[h+1]*r,l[f++]=i[h+2]+a[h+2]*r;var m,y=e.boundingSphere;return c(y)&&(m=new n(y.center,y.radius+r)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:g.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){var t,n=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],r=e.attributes,i={},a=0,o=n.length;for(t=0;t<o;++t){var u=n[t];c(r[u])&&(i[u]=a++)}for(var s in r)r.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),n=e.indices;if(c(n)){for(var r=new Int32Array(t),i=0;i<t;i++)r[i]=-1;for(var a,o=n,s=o.length,l=y.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=r[o[f]],-1!==a?l[h]=a:(a=o[f],r[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var m=e.attributes;for(var E in m)if(m.hasOwnProperty(E)&&c(m[E])&&c(m[E].values)){for(var _=m[E],v=_.values,T=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);T<t;){var g=r[T];if(-1!==g)for(var S=0;S<R;S++)A[R*g+S]=v[R*T+S];++T}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var n=e.indices;if(e.primitiveType===g.TRIANGLES&&c(n)){for(var r=n.length,i=0,a=0;a<r;a++)n[a]>i&&(i=n[a]);e.indices=S.tipsify({indices:n,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],n=d.computeNumberOfVertices(e);if(c(e.indices)&&n>=v.SIXTY_FOUR_KILOBYTES){var r,i=[],a=[],o=0,u=I(e.attributes),s=e.indices,l=s.length;e.primitiveType===g.TRIANGLES?r=3:e.primitiveType===g.LINES?r=2:e.primitiveType===g.POINTS&&(r=1);for(var f=0;f<l;f+=r){for(var h=0;h<r;++h){var p=s[f+h],m=i[p];c(m)||(m=o++,i[p]=m,M(u,e.attributes,p)),a.push(m)}o+r>=v.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=I(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var ne=new i,re=new o;te.projectTo2D=function(e,t,n,r,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,m=0;m<l.length;m+=3){var y=i.fromArray(l,m,ne),E=s.cartesianToCartographic(y,re),_=a.project(E,ne);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[n]=o,e.attributes[r]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,n,r){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new T;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var r=e.geometry.attributes;C(t,r.position),C(t,r.prevPosition),C(t,r.nextPosition),(c(r.normal)||c(r.tangent)||c(r.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,r.normal),P(ue,r.tangent),P(ue,r.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=n.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],n=[],r=e.length,i=0;i<r;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&n.push(a)}var o=[];return t.length>0&&o.push(L(t,"geometry")),n.length>0&&(o.push(L(n,"westHemisphereGeometry")),o.push(L(n,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,n=e.indices,r=e.attributes,a=r.position.values,o=r.position.values.length/3,s=n.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=n[t],m=n[t+1],y=n[t+2],E=3*d,_=3*m,T=3*y;le.x=a[E],le.y=a[E+1],le.z=a[E+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[T],he.y=a[T+1],he.z=a[T+2],c[d].count++,c[m].count++,c[y].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[n[t]];var g=A.indexOffset+A.currentCount;f[g]=h,A.currentCount++,A=c[n[t+1]],g=A.indexOffset+A.currentCount,f[g]=h,A.currentCount++,A=c[n[t+2]],g=A.indexOffset+A.currentCount,f[g]=h,A.currentCount++,h++}var S=new Float32Array(3*o);for(t=0;t<o;t++){var N=3*t;if(A=c[t],i.clone(i.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)i.add(ce,l[f[A.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&i.clone(l[f[A.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),S[N]=ce.x,S[N+1]=ce.y,S[N+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:S}),e};var de=new i,pe=new i,me=new i;te.computeTangentAndBitangent=function(e){var t,n=(e.attributes,e.indices),r=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=n.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var m=n[t],y=n[t+1],E=n[t+2];f=3*m,h=3*y,d=3*E;var _=2*m,v=2*y,T=2*E,R=r[f],A=r[f+1],g=r[f+2],S=o[_],N=o[_+1],O=o[v+1]-N,x=o[T+1]-N,w=1/((o[v]-S)*x-(o[T]-S)*O),I=(x*(r[h]-R)-O*(r[d]-R))*w,M=(x*(r[h+1]-A)-O*(r[d+1]-A))*w,C=(x*(r[h+2]-g)-O*(r[d+2]-g))*w;l[f]+=I,l[f+1]+=M,l[f+2]+=C,l[h]+=I,l[h+1]+=M,l[h+2]+=C,l[d]+=I,l[d+1]+=M,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var L=i.fromArray(a,f,de),b=i.fromArray(l,f,me),U=i.dot(L,b);i.multiplyByScalar(L,U,pe),i.normalize(i.subtract(b,pe,b),b),P[f]=b.x,P[h]=b.y,P[d]=b.z,i.normalize(i.cross(L,b,b),b),D[f]=b.x,D[h]=b.y,D[d]=b.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var ye=new r,Ee=new i,_e=new i,ve=new i,Te=new r;te.compressVertices=function(t){var n,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(n=0;n<a;++n)i.fromArray(s,3*n,Ee),i.equals(Ee,i.ZERO)?f+=2:(Te=e.octEncodeInRange(Ee,65535,Te),l[f++]=Te.x,l[f++]=Te.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,m=c(h),y=c(d);if(!m&&!y)return t;var E,_,v,T,R=t.attributes.tangent,A=t.attributes.bitangent,g=c(R),S=c(A);m&&(E=h.values),y&&(_=d.values),g&&(v=R.values),S&&(T=A.values),a=(m?E.length:_.length)/(m?3:2);var N=a,O=y&&m?2:1;O+=g||S?1:0,N*=O;var x=new Float32Array(N),w=0;for(n=0;n<a;++n){y&&(r.fromArray(_,2*n,ye),x[w++]=e.compressTextureCoordinates(ye));var I=3*n;m&&c(v)&&c(T)?(i.fromArray(E,I,Ee),i.fromArray(v,I,_e),i.fromArray(T,I,ve),e.octPack(Ee,_e,ve,ye),x[w++]=ye.x,x[w++]=ye.y):(m&&(i.fromArray(E,I,Ee),x[w++]=e.octEncodeFloat(Ee)),g&&(i.fromArray(v,I,Ee),x[w++]=e.octEncodeFloat(Ee)),S&&(i.fromArray(T,I,Ee),x[w++]=e.octEncodeFloat(Ee)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:x}),m&&delete t.attributes.normal,y&&delete t.attributes.st,S&&delete t.attributes.bitangent,g&&delete t.attributes.tangent,t};var Re=new i,Ae=new i,ge=new i,Se=new i,Ne=new i,Oe={positions:new Array(7),indices:new Array(9)},xe=new i,we=new i,Ie=new i,Me=new i,Ce=new r,Pe=new r,De=new r,Le=A.fromPointNormal(i.ZERO,i.UNIT_Y),be=new i,Ue=new i,Fe=new r,Be=new r,ze=new i,Ge=new i,qe=new i,Ve=new i,We=new i,He=new i,Xe=new a,ke=5*v.EPSILON9,Ye=v.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,r=t.boundingSphere;if(c(r)){if(r.center.x-r.radius>0||n.intersectPlane(r,A.ORIGIN_ZX_PLANE)!==E.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else q(t),t.primitiveType===g.TRIANGLES?J(e):t.primitiveType===g.LINES&&Q(e);return e},te}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function i(e,r,i){if(n(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,a));++u);if(u===o)return i&&r(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&r(l[0],l[l.length-1],a)&&l.shift(),l}}var a=r.EPSILON10;return i}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,p,m,y;if(a&&(u=s(e,n,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var E=i;E<o;E+=i)p=e[E],m=e[E+1],p<l&&(l=p),m<f&&(f=m),p>h&&(h=p),m>d&&(d=m);y=Math.max(h-l,d-f)}return r(u,c,i,l,f,y),c}function t(e,t,n,r,i){var a,o;if(i===w(e,t,n,r)>0)for(a=t;a<n;a+=r)o=N(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=N(a,e[a],e[a+1],o);return o&&v(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!v(r,r.next)&&0!==_(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var p,m,y=e;e.prev!==e.next;)if(p=e.prev,m=e.next,f?a(e,c,l,f):i(e))t.push(p.i/s),t.push(e.i/s),t.push(m.i/s),O(e),e=m.next,y=m.next;else if((e=m)===y){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(_(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(y(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=p(u,s,t,n,r),h=p(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&y(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&y(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!v(i,a)&&T(i,r,r.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),O(r),O(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&E(s,c)){var l=S(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,i,a,o,u),void r(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,f=o<u-1?r[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=S(t,e);n(r,r.next)}}function f(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=l&&y(a<f?i:o,a,l,f,a<f?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var i=e;do{null===i.z&&(i.z=p(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function p(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function y(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function E(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!R(e,t)&&A(e,t)&&A(t,e)&&g(e,t)}function _(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function v(e,t){return e.x===t.x&&e.y===t.y}function T(e,t,n,r){return!!(v(e,t)&&v(n,r)||v(e,r)&&v(n,t))||_(e,t,n)>0!=_(e,t,r)>0&&_(n,r,e)>0!=_(n,r,t)>0}function R(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&T(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function g(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function S(e,t){var n=new x(e.i,e.x,e.y),r=new x(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function N(e,t,n,r){var i=new x(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function x(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function w(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(w(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(w(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,p=r[u+2]*n;f+=Math.abs((e[h]-e[p])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[p+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";var d=new n,p=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var y=new n,E=new n,_=new n,v=new n,T=new n,R=new n,A=new n;return m.computeSubdivision=function(e,t,r,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),p=t.length,m=new Array(3*p),g=0;for(h=0;h<p;h++){var S=t[h];m[g++]=S.x,m[g++]=S.y,m[g++]=S.z}for(var N=[],O={},x=e.maximumRadius,w=l.chordLength(u,x),I=w*w;d.length>0;){var M,C,P=d.pop(),D=d.pop(),L=d.pop(),b=n.fromArray(m,3*L,y),U=n.fromArray(m,3*D,E),F=n.fromArray(m,3*P,_),B=n.multiplyByScalar(n.normalize(b,v),x,v),z=n.multiplyByScalar(n.normalize(U,T),x,T),G=n.multiplyByScalar(n.normalize(F,R),x,R),q=n.magnitudeSquared(n.subtract(B,z,A)),V=n.magnitudeSquared(n.subtract(z,G,A)),W=n.magnitudeSquared(n.subtract(G,B,A)),H=Math.max(q,V,W);H>I?q===H?(M=Math.min(L,D)+" "+Math.max(L,D),h=O[M],o(h)||(C=n.add(b,U,A),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(L,h,P),d.push(h,D,P)):V===H?(M=Math.min(D,P)+" "+Math.max(D,P),h=O[M],o(h)||(C=n.add(U,F,A),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(D,h,L),d.push(h,P,L)):W===H&&(M=Math.min(P,L)+" "+Math.max(P,L),h=O[M],o(h)||(C=n.add(F,b,A),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(P,h,D),d.push(h,L,D)):(N.push(L),N.push(D),N.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:m})},indices:N,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=d,c=p;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/Queue",["./defineProperties"],function(e){"use strict";function t(){this._array=[],this._offset=0,this._length=0}return e(t.prototype,{length:{get:function(){return this._length}}}),t.prototype.enqueue=function(e){this._array.push(e),this._length++},t.prototype.dequeue=function(){if(0!==this._length){var e=this._array,t=this._offset,n=e[t];return e[t]=void 0,t++,t>10&&2*t>e.length&&(this._array=e.slice(t),t=0),this._offset=t,this._length--,n}},t.prototype.peek=function(){if(0!==this._length)return this._array[this._offset]},t.prototype.contains=function(e){return-1!==this._array.indexOf(e)},t.prototype.clear=function(){this._array.length=this._offset=this._length=0},t.prototype.sort=function(e){this._offset>0&&(this._array=this._array.slice(this._offset),this._offset=0),this._array.sort(e)},t}), -define("Core/PolygonGeometryLibrary",["./arrayRemoveDuplicates","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,p,m){"use strict";function y(e,n,r,i){return t.subtract(n,e,_),t.multiplyByScalar(_,r/i,_),t.add(e,_,_),[_.x,_.y,_.z]}var E={};E.computeHierarchyPackedLength=function(e){for(var n=0,r=[e];r.length>0;){var a=r.pop();if(i(a)){n+=2;var o=a.positions,u=a.holes;if(i(o)&&(n+=o.length*t.packedLength),i(u))for(var s=u.length,c=0;c<s;++c)r.push(u[c])}}return n},E.packPolygonHierarchy=function(e,n,r){for(var a=[e];a.length>0;){var o=a.pop();if(i(o)){var u=o.positions,s=o.holes;if(n[r++]=i(u)?u.length:0,n[r++]=i(s)?s.length:0,i(u))for(var c=u.length,l=0;l<c;++l,r+=3)t.pack(u[l],n,r);if(i(s))for(var f=s.length,h=0;h<f;++h)a.push(s[h])}}return r},E.unpackPolygonHierarchy=function(e,n){for(var r=e[n++],i=e[n++],a=new Array(r),o=i>0?new Array(i):void 0,u=0;u<r;++u,n+=t.packedLength)a[u]=t.unpack(e,n);for(var s=0;s<i;++s)o[s]=E.unpackPolygonHierarchy(e,n),n=o[s].startingIndex,delete o[s].startingIndex;return{positions:a,holes:o,startingIndex:n}};var _=new t;E.subdivideLineCount=function(e,n,r){var i=t.distance(e,n),a=i/r,o=Math.max(0,Math.ceil(Math.log(a)/Math.log(2)));return Math.pow(2,o)},E.subdivideLine=function(e,n,r,a){var o=E.subdivideLineCount(e,n,r),u=t.distance(e,n),s=u/o;i(a)||(a=[]);var c=a;c.length=3*o;for(var l=0,f=0;f<o;f++){var h=y(e,n,f*s,u);c[l++]=h[0],c[l++]=h[1],c[l++]=h[2]}return c};var v=new t,T=new t,R=new t,A=new t;E.scaleToGeodeticHeightExtruded=function(e,n,o,u,s){u=r(u,a.WGS84);var c=v,l=T,f=R,h=A;if(i(e)&&i(e.attributes)&&i(e.attributes.position))for(var d=e.attributes.position.values,p=d.length/2,m=0;m<p;m+=3)t.fromArray(d,m,f),u.geodeticSurfaceNormal(f,c),h=u.scaleToGeodeticSurface(f,h),l=t.multiplyByScalar(c,o,l),l=t.add(h,l,l),d[m+p]=l.x,d[m+1+p]=l.y,d[m+2+p]=l.z,s&&(h=t.clone(f,h)),l=t.multiplyByScalar(c,n,l),l=t.add(h,l,l),d[m]=l.x,d[m+1]=l.y,d[m+2]=l.z;return e},E.polygonsFromHierarchy=function(n,r,a,o){var u=[],s=[],c=new p;for(c.enqueue(n);0!==c.length;){var l=c.dequeue(),f=l.positions,d=l.holes;if(f=e(f,t.equalsEpsilon,!0),!(f.length<3)){var y=a.projectPointsOntoPlane(f),E=[],_=h.computeWindingOrder2D(y);_===m.CLOCKWISE&&(y.reverse(),f=f.slice().reverse());var v,T,R=f.slice(),A=i(d)?d.length:0,g=[];for(v=0;v<A;v++){var S=d[v],N=e(S.positions,t.equalsEpsilon,!0);if(!(N.length<3)){var O=a.projectPointsOntoPlane(N);_=h.computeWindingOrder2D(O),_===m.CLOCKWISE&&(O.reverse(),N=N.slice().reverse()),g.push(N),E.push(R.length),R=R.concat(N),y=y.concat(O);var x=0;for(i(S.holes)&&(x=S.holes.length),T=0;T<x;T++)c.enqueue(S.holes[T])}}if(!r){for(v=0;v<f.length;v++)o.scaleToGeodeticSurface(f[v],f[v]);for(v=0;v<g.length;v++){var w=g[v];for(T=0;T<w.length;++T)o.scaleToGeodeticSurface(w[T],w[T])}}u.push({outerRing:f,holes:g}),s.push({positions:R,positions2D:y,holes:E})}}return{hierarchy:u,polygons:s}},E.createGeometryFromPositions=function(e,t,r,i,a){var s=h.triangulate(t.positions2D,t.holes);s.length<3&&(s=[0,1,2]);var l=t.positions;if(i){for(var f=l.length,p=new Array(3*f),m=0,y=0;y<f;y++){var E=l[y];p[m++]=E.x,p[m++]=E.y,p[m++]=E.z}var _=new o({attributes:{position:new u({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:p})},indices:s,primitiveType:d.TRIANGLES});return a.normal?c.computeNormal(_):_}return h.computeSubdivision(e,l,s,r)};var g=[],S=new t,N=new t;return E.computeWallGeometry=function(e,r,i,a){var c,h,p,m,y,_=e.length,v=0;if(a)for(h=3*_*2,c=new Array(2*h),p=0;p<_;p++)m=e[p],y=e[(p+1)%_],c[v]=c[v+h]=m.x,++v,c[v]=c[v+h]=m.y,++v,c[v]=c[v+h]=m.z,++v,c[v]=c[v+h]=y.x,++v,c[v]=c[v+h]=y.y,++v,c[v]=c[v+h]=y.z,++v;else{var T=f.chordLength(i,r.maximumRadius),R=0;for(p=0;p<_;p++)R+=E.subdivideLineCount(e[p],e[(p+1)%_],T);for(h=3*(R+_),c=new Array(2*h),p=0;p<_;p++){m=e[p],y=e[(p+1)%_];for(var A=E.subdivideLine(m,y,T,g),O=A.length,x=0;x<O;++x,++v)c[v]=A[x],c[v+h]=A[x];c[v]=y.x,c[v+h]=y.x,++v,c[v]=y.y,c[v+h]=y.y,++v,c[v]=y.z,c[v+h]=y.z,++v}}_=c.length;var w=l.createTypedArray(_/3,_-6*e.length),I=0;for(_/=6,p=0;p<_;p++){var M=p,C=M+1,P=M+_,D=P+1;m=t.fromArray(c,3*M,S),y=t.fromArray(c,3*C,N),t.equalsEpsilon(m,y,f.EPSILON14)||(w[I++]=M,w[I++]=P,w[I++]=C,w[I++]=C,w[I++]=P,w[I++]=D)}return new o({attributes:new s({position:new u({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:c})}),indices:w,primitiveType:d.TRIANGLES})},E}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},i.unpack=function(n,r,a){return r=e(r,0),t(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(e,n){if(t(e))return t(n)||(n=new i),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},i}),define("Core/PolygonGeometry",["./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Geometry","./GeometryAttribute","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./PolygonGeometryLibrary","./PolygonPipeline","./Quaternion","./Rectangle","./VertexFormat","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,A,g,S,N){"use strict";function O(e,t,n,i){for(var a=A.fromAxisAngle(e._plane.normal,n,D),o=v.fromQuaternion(a,L),u=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.POSITIVE_INFINITY,f=Number.NEGATIVE_INFINITY,h=t.length,d=0;d<h;++d){var p=r.clone(t[d],P);v.multiplyByVector(o,p,p);var m=e.projectPointOntoPlane(p,C);s(m)&&(u=Math.min(u,m.x),c=Math.max(c,m.x),l=Math.min(l,m.y),f=Math.max(f,m.y))}return i.x=u,i.y=l,i.width=c-u,i.height=f-l,i}function x(e,t,n,r){var i=r.cartesianToCartographic(e,b),a=i.height,o=r.cartesianToCartographic(t,U);o.height=a,r.cartographicToCartesian(o,t);var u=r.cartesianToCartographic(n,U);u.height=a-100,r.cartographicToCartesian(u,n)}function w(e){var t=e.vertexFormat,i=e.geometry,a=e.shadowVolume;if(t.st||t.normal||t.tangent||t.bitangent||a){var u=e.boundingRectangle,s=e.tangentPlane,c=e.ellipsoid,l=e.stRotation,f=e.wall,h=e.top||f,d=e.bottom||f,m=e.perPositionHeight,y=Y;y.x=u.x,y.y=u.y;var E,T=i.attributes.position.values,R=T.length,g=t.st?new Float32Array(R/3*2):void 0;t.normal&&(E=m&&h&&!f?i.attributes.normal.values:new Float32Array(R));var S=t.tangent?new Float32Array(R):void 0,N=t.bitangent?new Float32Array(R):void 0,O=a?new Float32Array(R):void 0,w=0,I=0,M=z,C=G,P=q,D=!0,L=A.fromAxisAngle(s._plane.normal,l,K),b=v.fromQuaternion(L,J),U=0,F=0;h&&d&&(U=R/2,F=R/3,R/=2);for(var Q=0;Q<R;Q+=3){var $=r.fromArray(T,Q,j);if(t.st){var ee=v.multiplyByVector(b,$,B);ee=c.scaleToGeodeticSurface(ee,ee);var te=s.projectPointOntoPlane(ee,Z);n.subtract(te,y,te);var ne=_.clamp(te.x/u.width,0,1),re=_.clamp(te.y/u.height,0,1);d&&(g[w+F]=ne,g[w+1+F]=re),h&&(g[w]=ne,g[w+1]=re),w+=2}if(t.normal||t.tangent||t.bitangent||a){var ie=I+1,ae=I+2;if(f){if(Q+3<R){var oe=r.fromArray(T,Q+3,V);if(D){var ue=r.fromArray(T,Q+R,W);m&&x($,oe,ue,c),r.subtract(oe,$,oe),r.subtract(ue,$,ue),M=r.normalize(r.cross(ue,oe,M),M),D=!1}r.equalsEpsilon(oe,$,_.EPSILON10)&&(D=!0)}(t.tangent||t.bitangent)&&(P=c.geodeticSurfaceNormal($,P),t.tangent&&(C=r.normalize(r.cross(P,M,C),C)))}else M=c.geodeticSurfaceNormal($,M),(t.tangent||t.bitangent)&&(m&&(H=r.fromArray(E,I,H),X=r.cross(r.UNIT_Z,H,X),X=r.normalize(v.multiplyByVector(b,X,X),X),t.bitangent&&(k=r.normalize(r.cross(H,X,k),k))),C=r.cross(r.UNIT_Z,M,C),C=r.normalize(v.multiplyByVector(b,C,C),C),t.bitangent&&(P=r.normalize(r.cross(M,C,P),P)));t.normal&&(e.wall?(E[I+U]=M.x,E[ie+U]=M.y,E[ae+U]=M.z):d&&(E[I+U]=-M.x,E[ie+U]=-M.y,E[ae+U]=-M.z),(h&&!m||f)&&(E[I]=M.x,E[ie]=M.y,E[ae]=M.z)),a&&(f&&(M=c.geodeticSurfaceNormal($,M)),O[I+U]=-M.x,O[ie+U]=-M.y,O[ae+U]=-M.z),t.tangent&&(e.wall?(S[I+U]=C.x,S[ie+U]=C.y,S[ae+U]=C.z):d&&(S[I+U]=-C.x,S[ie+U]=-C.y,S[ae+U]=-C.z),h&&(m?(S[I]=X.x,S[ie]=X.y,S[ae]=X.z):(S[I]=C.x,S[ie]=C.y,S[ae]=C.z))),t.bitangent&&(d&&(N[I+U]=P.x,N[ie+U]=P.y,N[ae+U]=P.z),h&&(m?(N[I]=k.x,N[ie]=k.y,N[ae]=k.z):(N[I]=P.x,N[ie]=P.y,N[ae]=P.z))),I+=3}}t.st&&(i.attributes.st=new p({componentDatatype:o.FLOAT,componentsPerAttribute:2,values:g})),t.normal&&(i.attributes.normal=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:E})),t.tangent&&(i.attributes.tangent=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:S})),t.bitangent&&(i.attributes.bitangent=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:N})),a&&(i.attributes.extrudeDirection=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:O}))}return i}function I(e,t,n,r,i,a,o,u){var s,c={walls:[]};if(a||o){var l,f,d=T.createGeometryFromPositions(e,t,n,i,u),p=d.attributes.position.values,y=d.indices;if(a&&o){var _=p.concat(p);l=_.length/3,f=E.createTypedArray(l,2*y.length),f.set(y);var v=y.length,A=l/2;for(s=0;s<v;s+=3){var g=f[s]+A,S=f[s+1]+A,O=f[s+2]+A;f[s+v]=O,f[s+1+v]=S,f[s+2+v]=g}if(d.attributes.position.values=_,i){var x=d.attributes.normal.values;d.attributes.normal.values=new Float32Array(_.length),d.attributes.normal.values.set(x)}d.indices=f}else if(o){for(l=p.length/3,f=E.createTypedArray(l,y.length),s=0;s<y.length;s+=3)f[s]=y[s+2],f[s+1]=y[s+1],f[s+2]=y[s];d.indices=f}c.topAndBottom=new m({geometry:d})}var w=r.outerRing,I=h.fromPoints(w,e),M=I.projectPointsOntoPlane(w,Q),C=R.computeWindingOrder2D(M);C===N.CLOCKWISE&&(w=w.slice().reverse());var P=T.computeWallGeometry(w,e,n,i);c.walls.push(new m({geometry:P}));var D=r.holes;for(s=0;s<D.length;s++){var L=D[s];I=h.fromPoints(L,e),M=I.projectPointsOntoPlane(L,Q),C=R.computeWindingOrder2D(M),C===N.COUNTER_CLOCKWISE&&(L=L.slice().reverse()),P=T.computeWallGeometry(L,e,n),c.walls.push(new m({geometry:P}))}return c}function M(e){var t=e.polygonHierarchy,n=u(e.vertexFormat,S.DEFAULT),r=u(e.ellipsoid,f.WGS84),i=u(e.granularity,_.RADIANS_PER_DEGREE),a=u(e.stRotation,0),o=u(e.height,0),c=u(e.perPositionHeight,!1),l=e.extrudedHeight,h=s(l);if(!c&&h)if(_.equalsEpsilon(o,l,_.EPSILON10))l=void 0,h=!1;else{var d=l;l=Math.min(d,o),o=Math.max(d,o)}this._vertexFormat=S.clone(n),this._ellipsoid=f.clone(r),this._granularity=i,this._stRotation=a,this._height=o,this._extrudedHeight=u(l,0),this._extrude=h,this._closeTop=u(e.closeTop,!0),this._closeBottom=u(e.closeBottom,!0),this._polygonHierarchy=t,this._perPositionHeight=c,this._shadowVolume=u(e.shadowVolume,!1),this._workerName="createPolygonGeometry";var p=t.positions;!s(p)||p.length<3?this._rectangle=new g:this._rectangle=g.fromCartesianArray(p,r),this.packedLength=T.computeHierarchyPackedLength(t)+f.packedLength+S.packedLength+g.packedLength+10}var C=new n,P=new r,D=new A,L=new v,b=new i,U=new i,F=new e,B=new r,z=new r,G=new r,q=new r,V=new r,W=new r,H=new r,X=new r,k=new r,Y=new n,Z=new n,j=new r,K=new A,J=new v,Q=[];M.fromPositions=function(e){return e=u(e,u.EMPTY_OBJECT),new M({polygonHierarchy:{positions:e.positions},height:e.height,extrudedHeight:e.extrudedHeight,vertexFormat:e.vertexFormat,stRotation:e.stRotation,ellipsoid:e.ellipsoid,granularity:e.granularity,perPositionHeight:e.perPositionHeight,closeTop:e.closeTop,closeBottom:e.closeBottom})},M.pack=function(e,t,n){return n=u(n,0),n=T.packPolygonHierarchy(e._polygonHierarchy,t,n),f.pack(e._ellipsoid,t,n),n+=f.packedLength,S.pack(e._vertexFormat,t,n),n+=S.packedLength,g.pack(e._rectangle,t,n),n+=g.packedLength,t[n++]=e._height,t[n++]=e._extrudedHeight,t[n++]=e._granularity,t[n++]=e._stRotation,t[n++]=e._extrude?1:0,t[n++]=e._perPositionHeight?1:0,t[n++]=e._closeTop?1:0,t[n++]=e._closeBottom?1:0,t[n++]=e._shadowVolume?1:0,t[n]=e.packedLength,t};var $=f.clone(f.UNIT_SPHERE),ee=new S,te=new g,ne={polygonHierarchy:{}};return M.unpack=function(e,t,n){t=u(t,0);var r=T.unpackPolygonHierarchy(e,t);t=r.startingIndex,delete r.startingIndex;var i=f.unpack(e,t,$);t+=f.packedLength;var a=S.unpack(e,t,ee);t+=S.packedLength;var o=g.unpack(e,t,te);t+=g.packedLength;var c=e[t++],l=e[t++],h=e[t++],d=e[t++],p=1===e[t++],m=1===e[t++],y=1===e[t++],E=1===e[t++],_=1===e[t++],v=e[t];return s(n)||(n=new M(ne)),n._polygonHierarchy=r,n._ellipsoid=f.clone(i,n._ellipsoid),n._vertexFormat=S.clone(a,n._vertexFormat),n._height=c,n._extrudedHeight=l,n._granularity=h,n._stRotation=d,n._extrude=p,n._perPositionHeight=m,n._closeTop=y,n._closeBottom=E,n._rectangle=g.clone(o),n._shadowVolume=_,n.packedLength=v,n},M.createGeometry=function(e){var n=e._vertexFormat,r=e._ellipsoid,i=e._granularity,a=e._stRotation,o=e._height,u=e._extrudedHeight,s=e._extrude,c=e._polygonHierarchy,l=e._perPositionHeight,f=e._closeTop,p=e._closeBottom,_=c.positions;if(!(_.length<3)){var v=h.fromPoints(_,r),A=T.polygonsFromHierarchy(c,l,v,r),g=A.hierarchy,S=A.polygons;if(0!==g.length){_=g[0].outerRing;var N,x,M=O(v,_,a,F),C=[],P={perPositionHeight:l,vertexFormat:n,geometry:void 0,tangentPlane:v,boundingRectangle:M,ellipsoid:r,stRotation:a,bottom:!1,top:!0,wall:!1};if(s)for(P.top=f,P.bottom=p,P.shadowVolume=e._shadowVolume,x=0;x<S.length;x++){N=I(r,S[x],i,g[x],l,f,p,n);var D;f&&p?(D=N.topAndBottom,P.geometry=T.scaleToGeodeticHeightExtruded(D.geometry,o,u,r,l)):f?(D=N.topAndBottom,D.geometry.attributes.position.values=R.scaleToGeodeticHeight(D.geometry.attributes.position.values,o,r,!l),P.geometry=D.geometry):p&&(D=N.topAndBottom,D.geometry.attributes.position.values=R.scaleToGeodeticHeight(D.geometry.attributes.position.values,u,r,!0),P.geometry=D.geometry),(f||p)&&(P.wall=!1,D.geometry=w(P),C.push(D));var L=N.walls;P.wall=!0;for(var b=0;b<L.length;b++){var U=L[b];P.geometry=T.scaleToGeodeticHeightExtruded(U.geometry,o,u,r,l),U.geometry=w(P),C.push(U)}}else for(x=0;x<S.length;x++)N=new m({geometry:T.createGeometryFromPositions(r,S[x],i,l,n)}),N.geometry.attributes.position.values=R.scaleToGeodeticHeight(N.geometry.attributes.position.values,o,r,!l),P.geometry=N.geometry,N.geometry=w(P),C.push(N);N=y.combineInstances(C)[0],N.attributes.position.values=new Float64Array(N.attributes.position.values),N.indices=E.createTypedArray(N.attributes.position.values.length/3,N.indices);var B=N.attributes,z=t.fromVertices(B.position.values);return n.position||delete B.position,new d({attributes:B,indices:N.indices,primitiveType:N.primitiveType,boundingSphere:z})}}},M.createShadowVolume=function(e,t,n){var r=e._granularity,i=e._ellipsoid,a=t(r,i),o=n(r,i);return new M({polygonHierarchy:e._polygonHierarchy,ellipsoid:i,stRotation:e._stRotation,granularity:r,perPositionHeight:!1,extrudedHeight:a,height:o,vertexFormat:S.POSITION_ONLY,shadowVolume:!0})},c(M.prototype,{rectangle:{get:function(){return this._rectangle}}}),M}),define("Workers/createPolygonGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolygonGeometry"],function(e,t,n){"use strict";function r(r,i){return e(i)&&(r=n.unpack(r,i)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(n,i){if(!e(i))throw new t(r(n))},i.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},i.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},i.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},i.typeOf.number.lessThan=function(e,r,n){if(i.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},i.typeOf.number.lessThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},i.typeOf.number.greaterThan=function(e,r,n){if(i.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},i.typeOf.number.greaterThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},i.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},i.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},i.typeOf.number.equals=function(e,r,n,a){if(i.typeOf.number(e,n),i.typeOf.number(r,a),n!==a)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*i.clamp(e,-1,1)+.5)*r)},i.fromSNorm=function(e,r){return r=t(r,255),i.clamp(e,0,r)/r*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,r){return(1-r)*e+r*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,r,n,i){i=t(i,n);var a=Math.abs(e-r);return a<=i||a<=n*Math.max(Math.abs(e),Math.abs(r))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var r=a[t-1],n=t;n<=e;n++)a.push(r*n);return a[e]},i.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return n.x=s*Math.cos(i),n.y=s*Math.sin(i),n.z=u*Math.cos(a),n},o.fromElements=function(e,t,n,i){return r(i)?(i.x=e,i.y=t,i.z=n,i):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var i=0;i<n;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var i=0;i<n;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)},o.cross=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-n*s,f=n*u-i*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,r,n,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,i,a,u){i=t(i,0);var s=r(a)?a.radiiSquared:p,c=Math.cos(n);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(n),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),r(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function i(r,i,u,s,c){var l=r.x,f=r.y,h=r.z,d=i.x,p=i.y,m=i.z,y=l*l*d*d,E=f*f*p*p,_=h*h*m*m,v=y+E+_,T=Math.sqrt(1/v),R=e.multiplyByScalar(r,T,a);if(v<s)return isFinite(T)?e.clone(R,c):void 0;var g=u.x,A=u.y,S=u.z,w=o;w.x=R.x*g*2,w.y=R.y*A*2,w.z=R.z*S*2;var O,N,I,x,M,C,P,b,D,U,L,F=(1-T)*e.magnitude(r)/(.5*e.magnitude(w)),B=0;do{F-=B,I=1/(1+F*g),x=1/(1+F*A),M=1/(1+F*S),C=I*I,P=x*x,b=M*M,D=C*I,U=P*x,L=b*M,O=y*C+E*P+_*b-1,N=y*D*g+E*U*A+_*L*S;B=O/(-2*N)}while(Math.abs(O)>n.EPSILON12);return t(c)?(c.x=l*I,c.y=f*x,c.z=h*M,c):new e(l*I,f*x,h*M)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,i,a){return i=r(i,0),n(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,r,n){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,r,i){var p=n(r)?r.oneOverRadii:f,m=n(r)?r.oneOverRadiiSquared:h,y=n(r)?r._centerToleranceSquared:d,E=o(t,p,m,y,c);if(n(E)){var _=e.multiplyComponents(E,m,s);_=e.normalize(_,_);var v=e.subtract(t,E,l),T=Math.atan2(_.y,_.x),R=Math.asin(_.z),g=a.sign(e.dot(v,t))*e.magnitude(v);return n(i)?(i.longitude=T,i.latitude=R,i.height=g,i):new u(T,R,g)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t,r,i,a){r=n(r,0),i=n(i,0),a=n(a,0),t._radii=new e(r,i,a),t._radiiSquared=new e(r*r,i*i,a*a),t._radiiToTheFourth=new e(r*r*r*r,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===r?0:1/r,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(r,i,a),t._maximumRadius=Math.max(r,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(i(t)){var n=t._radii;return i(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,i){return i=n(i,0),e.pack(t._radii,r,i),r},f.unpack=function(t,r,i){r=n(r,0);var a=e.unpack(t,r);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(a);return i(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return i(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,r){var n=h,a=d;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,a);var o=Math.sqrt(e.dot(n,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(n,t.height,n),i(r)||(r=new e),e.add(a,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var p=new e,m=new e,y=new e;return f.prototype.cartesianToCartographic=function(r,n){var a=this.scaleToGeodeticSurface(r,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(r,a,y),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return i(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){i(r)||(r=new e);var n=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,a){r=n(r,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-r))return a},f}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var i=0;i<n;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var i=0;i<n;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,i,a,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return n(r)?(r.x=a,r.y=o,r.z=u,r):new e(a,o,u)},u.prototype.unproject=function(e,r){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return n(r)?(r.longitude=a,r.latitude=o,r.height=u,r):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),i=u.toRadians(r(i,0)),a=u.toRadians(r(a,0)),n(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(i,0),o.north=r(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];r=Math.min(r,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-r>o-a&&(r=a,i=o,i>u.PI&&(i-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=i,t.north=l,t):new s(r,c,i,l)},s.fromCartesianArray=function(e,t,i){t=r(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,m=e.length;p<m;p++){var y=t.cartesianToCartographic(e[p]);o=Math.min(o,y.longitude),c=Math.max(c,y.longitude),h=Math.min(h,y.latitude),d=Math.max(d,y.latitude);var E=y.longitude>=0?y.longitude:y.longitude+u.TWO_PI;l=Math.min(l,E),f=Math.max(f,E)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return n(r)?(r.west=l,r.south=h,r.east=f,r.north=d,r):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,r){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return n(r)?(r.west=i,r.south=a,r.east=o,r.north=u,r):new s(i,a,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>i||u.equalsEpsilon(r,i,u.EPSILON14))&&(r<a||u.equalsEpsilon(r,a,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=r(t,a.WGS84),i=r(i,0),n(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,m=c;m.height=i,m.longitude=p,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var y=1;y<8;++y)m.longitude=-Math.PI+y*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.width=n(r,0),this.height=n(i,0)}s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.width,t[r]=e.height,t},s.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new s),r.x=e[t++],r.y=e[t++],r.width=e[t++],r.height=e[t],r},s.fromPoints=function(e,t){if(i(t)||(t=new s),!i(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var r=e.length,n=e[0].x,a=e[0].y,o=e[0].x,u=e[0].y,c=1;c<r;c++){var l=e[c],f=l.x,h=l.y;n=Math.min(f,n),o=Math.max(f,o),a=Math.min(h,a),u=Math.max(h,u)}return t.x=n,t.y=a,t.width=o-n,t.height=u-a,t};var c=new a,l=new t,f=new t;return s.fromRectangle=function(t,r,a){if(i(a)||(a=new s),!i(t))return a.x=0,a.y=0,a.width=0,a.height=0,a;r=n(r,c);var o=r.project(u.southwest(t,l)),h=r.project(u.northeast(t,f));return e.subtract(h,o,h),a.x=o.x,a.y=o.y,a.width=h.x,a.height=h.y,a},s.clone=function(e,t){if(i(e))return i(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new s(e.x,e.y,e.width,e.height)},s.union=function(e,t,r){i(r)||(r=new s);var n=Math.min(e.x,t.x),a=Math.min(e.y,t.y),o=Math.max(e.x+e.width,t.x+t.width),u=Math.max(e.y+e.height,t.y+t.height);return r.x=n,r.y=a,r.width=o-n,r.height=u-a,r},s.expand=function(e,t,r){r=s.clone(e,r);var n=t.x-r.x,i=t.y-r.y;return n>r.width?r.width=n:n<0&&(r.width-=n,r.x=t.x),i>r.height?r.height=i:i<0&&(r.height-=i,r.y=t.y),r},s.intersect=function(e,t){var r=e.x,n=e.y,i=t.x,a=t.y;return r>i+t.width||r+e.width<i||n+e.height<a||n>a+t.height?o.OUTSIDE:o.INTERSECTING},s.equals=function(e,t){return e===t||i(e)&&i(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.intersect=function(e){return s.intersect(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i,a,o,u,s,c){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(a,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(m[r],p[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],p[a])]);o>n&&(i=a,n=o)}var c=1,l=0,f=p[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>r){var d,y=e[s.getElementIndex(h,h)],E=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],v=(y-E)/2/_;d=v<0?-1/(-v+Math.sqrt(1+v*v)):1/(v+Math.sqrt(1+v*v)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8], +t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=r-u-f+d,m=2*(i-h),y=2*(a+l),E=2*(i+h),_=-r+u-f+d,v=2*(c-o),T=2*(a-l),R=2*(c+o),g=-r-u+f+d;return n(t)?(t[0]=p,t[1]=E,t[2]=T,t[3]=m,t[4]=_,t[5]=R,t[6]=y,t[7]=v,t[8]=g,t):new s(p,m,y,E,_,v,T,R,g)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=r*u,p=a*i+c*o*u,m=-c*i+a*o*u,y=-o,E=c*r,_=a*r;return n(t)?(t[0]=l,t[1]=d,t[2]=y,t[3]=f,t[4]=p,t[5]=E,t[6]=h,t[7]=m,t[8]=_,t):new s(l,f,h,d,p,m,y,E,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=i,t[6]=0,t[7]=-i,t[8]=r,t):new s(1,0,0,0,r,-i,0,i,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=r,t):new s(r,0,i,0,1,0,-i,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=i,t[2]=0,t[3]=-i,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-i,0,i,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,i=e[n],a=e[n+1],o=e[n+2];return r.x=i,r.y=a,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var i=3*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],i=e[t+3],a=e[t+6];return r.x=n,r.y=i,r.z=a,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var h=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=i,r[2]=a,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[3]*i+e[6]*a,u=e[1]*n+e[4]*i+e[7]*a,s=e[2]*n+e[5]*i+e[8]*a;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],m=[2,2,1],y=new s,E=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,i=0,a=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=r*c(h);a<10&&l(h)>d;)f(h,y),s.transpose(y,E),s.multiply(h,y,h),s.multiply(E,h,h),s.multiply(o,y,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*n-r*c)+u*(r*o-a*n)},s.inverse=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-n*f,t[2]=n*u-o*i,t[3]=c*u-a*f,t[4]=r*f-c*i,t[5]=a*i-r*u,t[6]=a*l-c*o,t[7]=c*n-r*l,t[8]=r*o-a*n;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n,i){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(i,0)}o.fromElements=function(e,t,n,i,a){return r(a)?(a.x=e,a.y=t,a.z=n,a.w=i,a):new o(e,t,n,i)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n++],i.w=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var i=0;i<n;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var i=0;i<n;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)&&a.equalsEpsilon(e.w,t.w,n,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t,r,i,a,o,u,s,c,l,f,h,d,p,m,y){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(c,0),this[3]=n(d,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(p,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(m,0),this[12]=n(i,0),this[13]=n(s,0),this[14]=n(h,0),this[15]=n(y,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,a){return r=n(r,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=r.x,a[13]=r.y,a[14]=r.z,a[15]=1,a):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){i(n)||(n=new l);var a=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,m=t.y*t.w,y=t.z*t.z,E=t.z*t.w,_=t.w*t.w,v=s-d-y+_,T=2*(c-E),R=2*(f+m),g=2*(c+E),A=-s+d-y+_,S=2*(p-h),w=2*(f-m),O=2*(p+h),N=-s-d+y+_;return n[0]=v*a,n[1]=g*a,n[2]=w*a,n[3]=0,n[4]=T*o,n[5]=A*o,n[6]=O*o,n[7]=0,n[8]=R*u,n[9]=S*u,n[10]=N*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,r){var n=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,m=f.y,y=f.z,E=d.x,_=d.y,v=d.z,T=n.x,R=n.y,g=n.z,A=u*-T+s*-R+c*-g,S=E*-T+_*-R+v*-g,w=p*T+m*R+y*g;return i(r)?(r[0]=u,r[1]=E,r[2]=-p,r[3]=0,r[4]=s,r[5]=_,r[6]=-m,r[7]=0,r[8]=c,r[9]=v,r[10]=-y,r[11]=0,r[12]=A,r[13]=S,r[14]=w,r[15]=1,r):new l(u,s,c,A,E,_,v,S,-p,-m,-y,w,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,r,n,i,a,o){var u=1/(t-e),s=1/(n-r),c=1/(a-i),l=-(t+e)*u,f=-(n+r)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,i,a,o){var u=2*i/(t-e),s=2*i/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,i,a){var o=2*i/(t-e),u=2*i/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,r,i){e=n(e,n.EMPTY_OBJECT);var a=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),h=c,d=l,p=f,m=a+c,y=o+l,E=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=m,i[13]=y,i[14]=E,i[15]=1,i},l.computeView=function(t,r,n,i,a){return a[0]=i.x,a[1]=n.x,a[2]=-r.x,a[3]=0,a[4]=i.y,a[5]=n.y,a[6]=-r.y,a[7]=0,a[8]=i.z,a[9]=n.z,a[10]=-r.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(n,t),a[14]=e.dot(r,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3];return r.x=i,r.y=a,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var i=4*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n[i+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return r.x=n,r.y=i,r.z=a,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var p=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),r};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],m=e[12],y=e[13],E=e[14],_=e[15],v=t[0],T=t[1],R=t[2],g=t[3],A=t[4],S=t[5],w=t[6],O=t[7],N=t[8],I=t[9],x=t[10],M=t[11],C=t[12],P=t[13],b=t[14],D=t[15],U=n*v+u*T+f*R+m*g,L=i*v+s*T+h*R+y*g,F=a*v+c*T+d*R+E*g,B=o*v+l*T+p*R+_*g,z=n*A+u*S+f*w+m*O,q=i*A+s*S+h*w+y*O,G=a*A+c*S+d*w+E*O,V=o*A+l*S+p*w+_*O,W=n*N+u*I+f*x+m*M,H=i*N+s*I+h*x+y*M,X=a*N+c*I+d*x+E*M,k=o*N+l*I+p*x+_*M,Y=n*C+u*P+f*b+m*D,j=i*C+s*P+h*b+y*D,Z=a*C+c*P+d*b+E*D,K=o*C+l*P+p*b+_*D;return r[0]=U,r[1]=L,r[2]=F,r[3]=B,r[4]=z,r[5]=q,r[6]=G,r[7]=V,r[8]=W,r[9]=H,r[10]=X,r[11]=k,r[12]=Y,r[13]=j,r[14]=Z,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],m=t[0],y=t[1],E=t[2],_=t[4],v=t[5],T=t[6],R=t[8],g=t[9],A=t[10],S=t[12],w=t[13],O=t[14],N=n*m+o*y+c*E,I=i*m+u*y+l*E,x=a*m+s*y+f*E,M=n*_+o*v+c*T,C=i*_+u*v+l*T,P=a*_+s*v+f*T,b=n*R+o*g+c*A,D=i*R+u*g+l*A,U=a*R+s*g+f*A,L=n*S+o*w+c*O+h,F=i*S+u*w+l*O+d,B=a*S+s*w+f*O+p;return r[0]=N,r[1]=I,r[2]=x,r[3]=0,r[4]=M,r[5]=C,r[6]=P,r[7]=0,r[8]=b,r[9]=D,r[10]=U,r[11]=0,r[12]=L,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],m=t[3],y=t[4],E=t[5],_=t[6],v=t[7],T=t[8],R=n*h+o*d+c*p,g=i*h+u*d+l*p,A=a*h+s*d+f*p,S=n*m+o*y+c*E,w=i*m+u*y+l*E,O=a*m+s*y+f*E,N=n*_+o*v+c*T,I=i*_+u*v+l*T,x=a*_+s*v+f*T;return r[0]=R,r[1]=g,r[2]=A,r[3]=0,r[4]=S,r[5]=w,r[6]=O,r[7]=0,r[8]=N,r[9]=I,r[10]=x,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=n*e[0]+i*e[4]+a*e[8]+e[12],u=n*e[1]+i*e[5]+a*e[9]+e[13],s=n*e[2]+i*e[6]+a*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var y=new e;l.multiplyByUniformScale=function(e,t,r){return y.x=t,y.y=t,y.z=t,l.multiplyByScale(e,y,r)},l.multiplyByScale=function(e,t,r){var n=t.x,i=t.y,a=t.z;return 1===n&&1===i&&1===a?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=i*e[4],r[5]=i*e[5],r[6]=i*e[6],r[7]=0,r[8]=a*e[8],r[9]=a*e[9],r[10]=a*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*n+e[4]*i+e[8]*a+e[12]*o,s=e[1]*n+e[5]*i+e[9]*a+e[13]*o,c=e[2]*n+e[6]*i+e[10]*a+e[14]*o,l=e[3]*n+e[7]*i+e[11]*a+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a,u=e[1]*n+e[5]*i+e[9]*a,s=e[2]*n+e[6]*i+e[10]*a;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a+e[12],u=e[1]*n+e[5]*i+e[9]*a+e[13],s=e[2]*n+e[6]*i+e[10]*a+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var E=new s,_=new s,v=new t,T=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,E),_,u.EPSILON7)&&t.equals(l.getRow(e,3,v),T))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],m=e[2],y=e[6],R=e[10],g=e[14],A=e[3],S=e[7],w=e[11],O=e[15],N=R*O,I=g*w,x=y*O,M=g*S,C=y*w,P=R*S,b=m*O,D=g*A,U=m*w,L=R*A,F=m*S,B=y*A,z=N*h+M*d+C*p-(I*h+x*d+P*p),q=I*f+b*d+L*p-(N*f+D*d+U*p),G=x*f+D*h+F*p-(M*f+b*h+B*p),V=P*f+U*h+B*d-(C*f+L*h+F*d),W=I*i+x*a+P*o-(N*i+M*a+C*o),H=N*n+D*a+U*o-(I*n+b*a+L*o),X=M*n+b*i+B*o-(x*n+D*i+F*o),k=C*n+L*i+F*a-(P*n+U*i+B*a);N=a*p,I=o*d,x=i*p,M=o*h,C=i*d,P=a*h,b=n*p,D=o*f,U=n*d,L=a*f,F=n*h,B=i*f;var Y=N*S+M*w+C*O-(I*S+x*w+P*O),j=I*A+b*w+L*O-(N*A+D*w+U*O),Z=x*A+D*S+F*O-(M*A+b*S+B*O),K=P*A+U*S+B*w-(C*A+L*S+F*w),J=x*R+P*g+I*y-(C*g+N*y+M*R),Q=U*g+N*m+D*R-(b*R+L*g+I*m),$=b*y+B*g+M*m-(F*g+x*m+D*y),ee=F*R+C*m+L*y-(U*y+B*R+P*m),te=n*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=q*te,r[2]=G*te,r[3]=V*te,r[4]=W*te,r[5]=H*te,r[6]=X*te,r[7]=k*te,r[8]=Y*te,r[9]=j*te,r[10]=Z*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-r*f-n*h-i*d,m=-a*f-o*h-u*d,y=-s*f-c*h-l*d;return t[0]=r,t[1]=a,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=m,t[14]=y,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";function d(t,r){this.center=e.clone(i(t,e.ZERO)),this.radius=i(r,0)}var p=new e,m=new e,y=new e,E=new e,_=new e,v=new e,T=new e,R=new e,g=new e,A=new e,S=new e,w=new e,O=4/3*r.PI;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],T),o=e.clone(i,p),u=e.clone(i,m),s=e.clone(i,y),c=e.clone(i,E),l=e.clone(i,_),f=e.clone(i,v),h=t.length;for(n=1;n<h;n++){e.clone(t[n],i);var O=i.x,N=i.y,I=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),N<u.y&&e.clone(i,u),N>l.y&&e.clone(i,l),I<s.z&&e.clone(i,s),I>f.z&&e.clone(i,f)}var x=e.magnitudeSquared(e.subtract(c,o,R)),M=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,b=c,D=x;M>D&&(D=M,P=u,b=l),C>D&&(D=C,P=s,b=f);var U=g;U.x=.5*(P.x+b.x),U.y=.5*(P.y+b.y),U.z=.5*(P.z+b.z);var L=e.magnitudeSquared(e.subtract(b,U,R)),F=Math.sqrt(L),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,R),.5,w),G=0;for(n=0;n<h;n++){e.clone(t[n],i);var V=e.magnitude(e.subtract(i,q,R));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,U,R));if(W>L){var H=Math.sqrt(W);F=.5*(F+H),L=F*F;var X=H-F;U.x=(F*U.x+X*i.x)/H,U.y=(F*U.y+X*i.y)/H,U.z=(F*U.z+X*i.z)/H}}return F<G?(e.clone(U,r.center),r.radius=F):(e.clone(q,r.center),r.radius=G),r};var N=new u,I=new e,x=new e,M=new t,C=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,n,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=i(r,N),h.southwest(t,M),M.height=n,h.northeast(t,C),C.height=o;var s=r.project(M,I),c=r.project(C,x),l=c.x-s.x,f=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+p*p);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*p,u};var P=[];d.fromRectangle3D=function(t,r,n,u){if(r=i(r,o.WGS84),n=i(n,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,r,n,P);return d.fromPoints(s,u)},d.fromVertices=function(t,r,n,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=i(r,e.ZERO),n=i(n,3);var u=T;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,p),l=e.clone(u,m),f=e.clone(u,y),h=e.clone(u,E),O=e.clone(u,_),N=e.clone(u,v),I=t.length;for(s=0;s<I;s+=n){var x=t[s]+r.x,M=t[s+1]+r.y,C=t[s+2]+r.z;u.x=x,u.y=M,u.z=C,x<c.x&&e.clone(u,c),x>h.x&&e.clone(u,h),M<l.y&&e.clone(u,l),M>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>N.z&&e.clone(u,N)}var P=e.magnitudeSquared(e.subtract(h,c,R)),b=e.magnitudeSquared(e.subtract(O,l,R)),D=e.magnitudeSquared(e.subtract(N,f,R)),U=c,L=h,F=P;b>F&&(F=b,U=l,L=O),D>F&&(F=D,U=f,L=N);var B=g;B.x=.5*(U.x+L.x),B.y=.5*(U.y+L.y),B.z=.5*(U.z+L.z);var z=e.magnitudeSquared(e.subtract(L,B,R)),q=Math.sqrt(z),G=A;G.x=c.x,G.y=l.y,G.z=f.z;var V=S;V.x=h.x,V.y=O.y,V.z=N.z;var W=e.multiplyByScalar(e.add(G,V,R),.5,w),H=0;for(s=0;s<I;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var X=e.magnitude(e.subtract(u,W,R));X>H&&(H=X);var k=e.magnitudeSquared(e.subtract(u,B,R));if(k>z){var Y=Math.sqrt(k);q=.5*(q+Y),z=q*q;var j=Y-q;B.x=(q*B.x+j*u.x)/Y,B.y=(q*B.y+j*u.y)/Y,B.z=(q*B.z+j*u.z)/Y}}return q<H?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=H),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=T;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,p),s=e.clone(i,m),c=e.clone(i,y),l=e.clone(i,E),f=e.clone(i,_),h=e.clone(i,v),O=t.length;for(o=0;o<O;o+=3){var N=t[o]+r[o],I=t[o+1]+r[o+1],x=t[o+2]+r[o+2];i.x=N,i.y=I,i.z=x,N<u.x&&e.clone(i,u),N>l.x&&e.clone(i,l),I<s.y&&e.clone(i,s),I>f.y&&e.clone(i,f),x<c.z&&e.clone(i,c),x>h.z&&e.clone(i,h)}var M=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(h,c,R)),b=u,D=l,U=M;C>U&&(U=C,b=s,D=f),P>U&&(U=P,b=c,D=h);var L=g;L.x=.5*(b.x+D.x),L.y=.5*(b.y+D.y),L.z=.5*(b.z+D.z);var F=e.magnitudeSquared(e.subtract(D,L,R)),B=Math.sqrt(F),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var q=S;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,w),V=0;for(o=0;o<O;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var W=e.magnitude(e.subtract(i,G,R));W>V&&(V=W);var H=e.magnitudeSquared(e.subtract(i,L,R));if(H>F){var X=Math.sqrt(H);B=.5*(B+X),F=B*B;var k=X-B;L.x=(B*L.x+k*i.x)/X,L.y=(B*L.y+k*i.y)/X,L.z=(B*L.z+k*i.z)/X}}return B<V?(e.clone(L,n.center),n.radius=B):(e.clone(G,n.center),n.radius=V),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var b=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,b)+c.radius)}return r.radius=s,r};var D=new e,U=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=l.getColumn(n,0,D),o=l.getColumn(n,1,U),u=l.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=i(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=i(t,0),a(r)||(r=new d);var n=r.center;return n.x=e[t++],n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var F=new e,B=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,F),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var z=new e;d.expand=function(t,r,n){n=d.clone(t,n) +;var i=e.magnitude(e.subtract(r,n.center,z));return i>n.radius&&(n.radius=i),n},d.intersectPlane=function(t,r){var n=t.center,i=t.radius,a=r.normal,o=e.dot(a,n)+r.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=f.getMaximumScale(t)*e.radius,r};var q=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,q);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var G=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new c);var o=e.subtract(t.center,r,G),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,W=new e,H=new e,X=new e,k=new e,Y=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,r,n){r=i(r,K);var a=r.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,H);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,k),h=e.negate(c,X),p=j,m=p[0];e.add(s,l,m),e.add(m,c,m),m=p[1],e.add(s,l,m),e.add(m,h,m),m=p[2],e.add(s,f,m),e.add(m,h,m),m=p[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=p[4],e.add(s,l,m),e.add(m,c,m),m=p[5],e.add(s,l,m),e.add(m,h,m),m=p[6],e.add(s,f,m),e.add(m,h,m),m=p[7],e.add(s,f,m),e.add(m,c,m);for(var y=p.length,E=0;E<y;++E){var _=p[E];e.add(o,_,_);var v=a.cartesianToCartographic(_,Y);r.project(v,_)}n=d.fromPoints(p,n),o=n.center;var T=o.x,R=o.y,g=o.z;return o.x=g,o.y=T,o.z=R,n},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return O*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(n.requestFullscreen=i,r=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(n.requestFullscreen=i,r=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?n.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(n.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?n.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(n.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?n.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(n.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),n.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),n.fullscreenerror=i)}return r},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[n.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(R=!0,g=n(e[1]))}return R}function a(){return i()&&g}function o(){if(!t(A)&&(A=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(T.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(A=!0,S=n(e[1]))}return A}function u(){return o()&&S}function s(){if(!t(w)){w=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(T.userAgent);null!==e&&(w=!0,O=n(e[1]),O.isNightly=!!e[2])}return w}function c(){return s()&&O}function l(){if(!t(N)){N=!1;var e;"Microsoft Internet Explorer"===T.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(N=!0,I=n(e[1])):"Netscape"===T.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(N=!0,I=n(e[1]))}return N}function f(){return l()&&I}function h(){if(!t(x)){x=!1;var e=/ Edge\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(x=!0,M=n(e[1]))}return x}function d(){return h()&&M}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function m(){return t(b)||(b=/Windows/i.test(T.appVersion)),b}function y(){return p()&&P}function E(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(T.pointerEnabled)||T.pointerEnabled)),D}function _(){if(!t(L)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;L=t(r)&&""!==r,L&&(U=r)}return L}function v(){return _()?U:void 0}var T;T="undefined"!=typeof navigator?navigator:{};var R,g,A,S,w,O,N,I,x,M,C,P,b,D,U,L,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:y,isWindows:m,hardwareConcurrency:e(T.hardwareConcurrency,3),supportsPointerEvents:E,supportsImageRenderingPixelated:_,imageRenderingValue:v};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,i,a){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,i){switch(n=e(n,0),i=e(i,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,i);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,i);case o.SHORT:return new Int16Array(r,n,i);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,i);case o.INT:return new Int32Array(r,n,i);case o.UNSIGNED_INT:return new Uint32Array(r,n,i);case o.FLOAT:return new Float32Array(r,n,i);case o.DOUBLE:return new Float64Array(r,n,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,r,n,i){"use strict";function a(t,i,a){this.minimum=e.clone(r(t,e.ZERO)),this.maximum=e.clone(r(i,e.ZERO)),n(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,r){if(n(r)||(r=new a),!n(t)||0===t.length)return r.minimum=e.clone(e.ZERO,r.minimum),r.maximum=e.clone(e.ZERO,r.maximum),r.center=e.clone(e.ZERO,r.center),r;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],p=d.x,m=d.y,y=d.z;i=Math.min(p,i),s=Math.max(p,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(y,u),l=Math.max(y,l)}var E=r.minimum;E.x=i,E.y=o,E.z=u;var _=r.maximum;_.x=s,_.y=c,_.z=l;var v=e.add(E,_,r.center);return e.multiplyByScalar(v,.5,v),r},a.clone=function(t,r){if(n(t))return n(r)?(r.minimum=e.clone(t.minimum,r.minimum),r.maximum=e.clone(t.maximum,r.maximum),r.center=e.clone(t.center,r.center),r):new a(t.minimum,t.maximum)},a.equals=function(t,r){return t===r||n(t)&&n(r)&&e.equals(t.center,r.center)&&e.equals(t.minimum,r.minimum)&&e.equals(t.maximum,r.maximum)};var o=new e;return a.intersectPlane=function(t,r){o=e.subtract(t.maximum,t.minimum,o);var n=e.multiplyByScalar(o,.5,o),a=r.normal,u=n.x*Math.abs(a.x)+n.y*Math.abs(a.y)+n.z*Math.abs(a.z),s=e.dot(t.center,a)+r.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var i=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(r)))<n?0:i}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,i){var a;if(0===e)return 0===n?[]:[-i/n];if(0===n){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-n/e,a<0?[a,0]:[0,a];var c=n*n,l=4*e*i,f=r(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[h/e,i/h]:[i/h,h/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var i,a,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,m=o*c-u*s,y=u*c-d,E=4*p*y-m*m;if(E<0){var _,v,T;h*f>=l*d?(_=o,v=p,T=-2*u*p+o*m):(_=c,v=y,T=-c*m+2*s*y);var R=T<0?-1:1,g=-R*Math.abs(_)*Math.sqrt(-E);a=-T+g;var A=a/2,S=A<0?-Math.pow(-A,1/3):Math.pow(A,1/3),w=a===g?-S:-v/S;return i=v<=0?S+w:-T/(S*S+w*w+v),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var O=p,N=-2*u*p+o*m,I=y,x=-c*m+2*s*y,M=Math.sqrt(E),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*M,-N)/3);i=2*Math.sqrt(-O);var b=Math.cos(P);a=i*b;var D=i*(-b/2-C*Math.sin(P)),U=a+D>2*u?a-u:D-u,L=o,F=U/L;P=Math.abs(Math.atan2(c*M,-x)/3),i=2*Math.sqrt(-I),b=Math.cos(P),a=i*b,D=i*(-b/2-C*Math.sin(P));var B=-c,z=a+D<2*s?a+s:D+s,q=B/z,G=L*z,V=-U*z-L*B,W=U*B,H=(s*V-u*W)/(-u*V+s*G);return F<=H?F<=q?H<=q?[F,H,q]:[F,q,H]:[q,F,H]:F<=q?[H,F,q]:H<=q?[H,q,F]:[q,H,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var i=e*e,a=t*t,o=r*r;return 18*e*t*r*n+a*o-27*i*(n*n)-4*(e*o*r+a*t*n)},n.computeRealRoots=function(e,n,i,a){var o,u;if(0===e)return t.computeRealRoots(n,i,a);if(0===n){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,i,a)}return 0===i?0===a?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,a):0===a?(o=t.computeRealRoots(e,n,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,i,a)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<r.EPSILON14){var p=n.computeRealRoots(1,s,l);if(2===p.length){var m,y=p[0],E=p[1];if(y>=0&&E>=0){var _=Math.sqrt(y),v=Math.sqrt(E);return[h-v,h-_,h+_,h+v]}if(y>=0&&E<0)return m=Math.sqrt(y),[h-m,h+m];if(y<0&&E>=0)return m=Math.sqrt(E),[h-m,h+m]}return[]}if(d>0){var T=Math.sqrt(d),R=(s+d-c/T)/2,g=(s+d+c/T)/2,A=n.computeRealRoots(1,T,R),S=n.computeRealRoots(1,-T,g);return 0!==A.length?(A[0]+=h,A[1]+=h,0!==S.length?(S[0]+=h,S[1]+=h,A[1]<=S[0]?[A[0],A[1],S[0],S[1]]:S[1]<=A[0]?[S[0],S[1],A[0],A[1]]:A[0]>=S[0]&&A[1]<=S[1]?[S[0],A[0],A[1],S[1]]:S[0]>=A[0]&&S[1]<=A[1]?[A[0],S[0],S[1],A[1]]:A[0]>S[0]&&A[0]<S[1]?[S[0],A[0],S[1],A[1]]:[A[0],S[0],A[1],S[1]]):A):0!==S.length?(S[0]+=h,S[1]+=h,S):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,m,y=d[0],E=i-y,_=E*E,v=t/2,T=E/2,R=_-4*o,g=_+4*Math.abs(o),A=c-4*y,S=c+4*Math.abs(y);if(y<0||R*S<A*g){var w=Math.sqrt(A);p=w/2,m=0===w?0:(t*T-a)/w}else{var O=Math.sqrt(R);p=0===O?0:(t*T-a)/O,m=O/2}var N,I;0===v&&0===p?(N=0,I=0):r.sign(v)===r.sign(p)?(N=v+p,I=y/N):(I=v-p,N=y/I);var x,M;0===T&&0===m?(x=0,M=0):r.sign(T)===r.sign(m)?(x=T+m,M=o/x):(M=T-m,x=o/M);var C=n.computeRealRoots(1,N,x),P=n.computeRealRoots(1,I,M);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,h=f*n,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*r*h-27*a*f*f+256*o*(d*i)+i*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*a*r*f)+d*(144*e*u*r-27*u*u-128*a*c-192*a*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return i.getPoint=function(t,n,i){return r(i)||(i=new e),i=e.multiplyByScalar(t.direction,n,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,i,a,o,u,s,c,l){"use strict";function f(e,t,r,n){var i=t*t-4*e*r;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function h(t,r,i){n(i)||(i=new a);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,m=f(h,d,p,g);if(n(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function p(t,r,n,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),y=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*r.x+n,E=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),v=[];if(0===_&&0===E){if(l=s.computeRealRoots(p,m,y),0===l.length)return v;var T=l[0],R=Math.sqrt(Math.max(1-T*T,0));if(v.push(new e(i,a*T,a*-R)),v.push(new e(i,a*T,a*R)),2===l.length){var g=l[1],A=Math.sqrt(Math.max(1-g*g,0));v.push(new e(i,a*g,a*-A)),v.push(new e(i,a*g,a*A))}return v}var S=_*_,w=E*E,O=p*p,N=_*E,I=O+w,x=2*(m*p+N),M=2*y*p+m*m-w+S,C=2*(y*m-N),P=y*y-S;if(0===I&&0===x&&0===M&&0===C)return v;l=c.computeRealRoots(I,x,M,C,P);var b=l.length;if(0===b)return v;for(var D=0;D<b;++D){var U,L=l[D],F=L*L,B=Math.max(1-F,0),z=Math.sqrt(B);U=o.sign(p)===o.sign(y)?d(p*F+y,m*L,o.EPSILON12):o.sign(y)===o.sign(m*L)?d(p*F,m*L+y,o.EPSILON12):d(p*F+m*L,y,o.EPSILON12);var q=d(E*L,_,o.EPSILON15),G=U*q;G<0?v.push(new e(i,a*L,a*z)):G>0?v.push(new e(i,a*L,a*-z)):0!==z?(v.push(new e(i,a*L,a*-z)),v.push(new e(i,a*L,a*z)),++D):v.push(new e(i,a*L,a*z))}return v}var m={};m.rayPlane=function(t,r,i){n(i)||(i=new e);var a=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var y=new e,E=new e,_=new e,v=new e,T=new e;m.rayTriangleParametric=function(t,n,i,a,u){u=r(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,m=e.subtract(i,n,y),R=e.subtract(a,n,E),g=e.cross(p,R,_),A=e.dot(m,g);if(u){if(A<o.EPSILON6)return;if(s=e.subtract(d,n,v),(l=e.dot(s,g))<0||l>A)return;if(c=e.cross(s,m,T),(f=e.dot(p,c))<0||l+f>A)return;h=e.dot(R,c)/A}else{ +if(Math.abs(A)<o.EPSILON6)return;var S=1/A;if(s=e.subtract(d,n,v),(l=e.dot(s,g)*S)<0||l>1)return;if(c=e.cross(s,m,T),(f=e.dot(p,c)*S)<0||l+f>1)return;h=e.dot(R,c)*S}return h},m.rayTriangle=function(t,r,i,a,o,u){var s=m.rayTriangleParametric(t,r,i,a,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;m.lineSegmentTriangle=function(t,r,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var g={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=h(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var A=new l;m.lineSegmentSphere=function(t,r,i,a){var o=A;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!n(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var S=new e,w=new e;m.rayEllipsoid=function(t,r){var n,i,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,S),f=e.multiplyComponents(c,t.direction,w),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(n=h-1,i=e.magnitudeSquared(f),o=i*n,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,y=n/s;return m<y?new a(m,y):{start:y,stop:m}}var E=Math.sqrt(n/i);return new a(E,E)}return h<1?(n=h-1,i=e.magnitudeSquared(f),o=i*n,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var O=new e,N=new e,I=new e,x=new e,M=new e,C=new u,P=new u,b=new u,D=new u,U=new u,L=new u,F=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,r){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=r.geodeticSurfaceNormal(i,O);if(e.dot(a,s)>=0)return i}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(a,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,x),d=e.normalize(e.cross(h,f,N),N),m=e.normalize(e.cross(f,d,I),I),y=C;y[0]=f.x,y[1]=f.y,y[2]=f.z,y[3]=d.x,y[4]=d.y,y[5]=d.z,y[6]=m.x,y[7]=m.y,y[8]=m.z;var E=u.transpose(y,P),_=u.fromScale(r.radii,b),v=u.fromScale(r.oneOverRadii,D),T=U;T[0]=0,T[1]=-a.z,T[2]=a.y,T[3]=a.z,T[4]=0,T[5]=-a.x,T[6]=-a.y,T[7]=a.x,T[8]=0;var R,g,A=u.multiply(u.multiply(E,v,L),T,L),S=u.multiply(u.multiply(A,_,F),y,F),w=u.multiplyByVector(A,i,M),G=p(S,e.negate(w,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,X=0;X<V;++X){R=u.multiplyByVector(_,u.multiplyByVector(y,G[X],B),B);var k=e.normalize(e.subtract(R,i,x),x),Y=e.dot(k,a);Y>H&&(H=Y,W=e.clone(R,W))}var j=r.cartesianToCartographic(W,q);return H=o.clamp(H,0,1),g=e.magnitude(e.subtract(W,i,x))*Math.sqrt(1-H*H),g=c?-g:g,j.height=g,r.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,r,i,a){n(a)||(a=new e);var u=e.subtract(r,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,r,n,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,r)+o<0,c=e.dot(a,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,r,n,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,r,n,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,r,n,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,r,n,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,r,n,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,r,n,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,i,a,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,i){var a=-e.dot(n,t);return r(i)?(e.clone(n,i.normal),i.distance=a,i):new u(n,a)};var s=new e;u.fromCartesian4=function(t,n){var i=e.fromCartesian4(t,s),a=t.w;return r(n)?(e.clone(i,n.normal),n.distance=a,n):new u(i,a)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,i){r(i)||(i=new e);var a=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(n,o,i)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,i){return t(e).then(r,n,i)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=i(e),t}function r(t){return e(t,a)}function n(e){this.then=e}function i(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return a(e)}})}function a(e){return new n(function(r,n){try{return n?t(n(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,r){return h(e,t,r)}function r(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new n(e),s={then:e,resolve:r,reject:i,progress:u,promise:c,resolver:{resolve:r,reject:i,progress:u}},l=[],f=[],h=function(e,t,r){var n,i;return n=o(),i="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,i)}),f.push(i),n.promise},d=function(e){return m(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=E,m(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,i,a){return y(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){p(e)}var c,l,f,h,d,p,m,y,_,v;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,h=[],d=o(),c)for(y=d.progress,m=function(e){h.push(e),--l||(p=m=E,d.reject(h))},p=function(e){f.push(e),--c||(p=m=E,d.resolve(f))},v=0;v<_;++v)v in t&&e(t[v],s,u,y);else d.resolve(f);return d.then(n,i,a)})}function c(e,t,r,n){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,r,n)}function l(e,t,r,n){return y(1,arguments),h(e,_).then(t,r,n)}function f(){return h(arguments,_)}function h(t,r){return e(t,function(t){var n,i,a,u,s,c;if(a=i=t.length>>>0,n=[],c=o(),a)for(u=function(t,i){e(t,r).then(function(e){n[i]=e,--a||c.resolve(n)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(n);return c.promise})}function d(t,r){var n=T.call(arguments,1);return e(t,function(t){var i;return i=t.length,n[0]=function(t,n,a){return e(t,function(t){return e(n,function(e){return r(t,e,a,i)})})},v.apply(t,n)})}function p(t,r,n){var i=arguments.length>2;return e(t,function(e){return e=i?n:e,r.resolve(e),e},function(e){return r.reject(e),a(e)},r.progress)}function m(e,t){for(var r,n=0;r=e[n++];)r(t)}function y(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function E(){}function _(e){return e}var v,T,R;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},T=[].slice,v=[].reduce||function(e){var t,r,n,i,a;if(a=0,t=Object(this),i=t.length>>>0,r=arguments,r.length<=1)for(;;){if(a in t){n=t[a++];break}if(++a>=i)throw new TypeError}else n=r[1];for(;a<i;++a)a in t&&(n=e(n,t[a],a,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,i,a=0,o=e.length-1;a<=o;)if(n=~~((a+o)/2),(i=r(e[n],t))<0)a=n+1;else{if(!(i>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],i=function(e,t,r,n){r||(r=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+i:i+e},a=function(e,t,r,n,a,o){var u=n-e.length;return u>0&&(e=r||!a?i(e,n,o,r):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+i(c.toString(t),u||0,"0",!1),a(e,r,n,o,s)},u=function(e,t,r,n,i,o){return null!=n&&(e=e.slice(0,n)),a(e,"",t,r,i,o)},s=function(e,n,s,c,l,f,h){var d,p,m,y,E;if("%%"==e)return"%";for(var _=!1,v="",T=!1,R=!1,g=" ",A=s.length,S=0;s&&S<A;S++)switch(s.charAt(S)){case" ":v=" ";break;case"+":v="+";break;case"-":_=!0;break;case"'":g=s.charAt(S+1);break;case"0":T=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,E=n?t[n.slice(0,-1)]:t[r++],h){case"s":return u(String(E),_,c,f,T,g);case"c":return u(String.fromCharCode(+E),_,c,f,T);case"b":return o(E,2,R,_,c,f,T);case"o":return o(E,8,R,_,c,f,T);case"x":return o(E,16,R,_,c,f,T);case"X":return o(E,16,R,_,c,f,T).toUpperCase();case"u":return o(E,10,R,_,c,f,T);case"i":case"d":return d=+E||0,d=Math.round(d-d%1),p=d<0?"-":v,E=p+i(String(Math.abs(d)),f,"0",!1),a(E,p,_,c,T);case"e":case"E":case"f":case"F":case"g":case"G":return d=+E,p=d<0?"-":v,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],y=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],E=p+Math.abs(d)[m](f),a(E,p,_,c,T)[y]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,i,a,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var i=r[n].offset;if(n>0){m.secondsDifference(r[n].julianDate,e)>i&&(n--,i=r[n].offset)}m.addSeconds(e,i,e)}function h(e,r){_.julianDate=e;var n=m.leapSeconds,i=t(n,_,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-n[0].offset,r);if(i>=n.length)return m.addSeconds(e,-n[i-1].offset,r);var a=m.secondsDifference(n[i].julianDate,e);return 0===a?m.addSeconds(e,-n[i].offset,r):a<=1?void 0:m.addSeconds(e,-n[--i].offset,r)}function d(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function p(e,t,r,n,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=a+(n*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),n===c.UTC&&f(this)}var y=new a,E=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,v=/^(\d{4})$/,T=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,g=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,A=/^(\d{4})-?(\d{2})-?(\d{2})$/,S=/([Z+\-])?(\d{2})?:?(\d{2})?$/,w=/^(\d{2})(\.\d+)?/.source+S.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+S.source,N=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+S.source;m.fromGregorianDate=function(e,t){var r=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromDate=function(e,t){var r=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,i,a,u=e.split("T"),s=1,l=1,h=0,y=0,_=0,S=0,I=u[0],x=u[1];if(null!==(u=I.match(A)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(T)))r=+u[1],s=+u[2];else if(null!==(u=I.match(v)))r=+u[1];else{var M;if(null!==(u=I.match(R)))r=+u[1],M=+u[2],a=o(r);else if(null!==(u=I.match(g))){r=+u[1];var C=+u[2],P=+u[3]||0,b=new Date(Date.UTC(r,0,4));M=7*C+P-b.getUTCDay()-3}i=new Date(Date.UTC(r,0,1)),i.setUTCDate(M),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(r);var D;if(n(x)){u=x.match(N),null!==u?(h=+u[1],y=+u[2],_=+u[3],S=1e3*+(u[4]||0),D=5):(u=x.match(O),null!==u?(h=+u[1],y=+u[2],_=60*+(u[3]||0),D=4):null!==(u=x.match(w))&&(h=+u[1],y=60*+(u[2]||0),D=3));var U=u[D],L=+u[D+1],F=+(u[D+2]||0);switch(U){case"+":h-=L,y-=F;break;case"-":h+=L,y+=F;break;case"Z":break;default:y+=new Date(Date.UTC(r,s-1,l,h,y)).getTimezoneOffset()}}var B=60===_;for(B&&_--;y>=60;)y-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:E[s-1];l>i;)l-=i,s++,s>12&&(s-=12,r++),i=a&&2===s?29:E[s-1];for(;y<0;)y+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),i=a&&2===s?29:E[s-1],l+=i;var z=p(r,s,l,h,y,_,S);return n(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var I=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var r=!1,i=h(e,I);n(i)||(m.addSeconds(e,-1,I),i=h(I,I),r=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var y=d+2-12*c|0,E=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,v=u-_*s.SECONDS_PER_HOUR,T=v/s.SECONDS_PER_MINUTE|0;v-=T*s.SECONDS_PER_MINUTE;var R=0|v,g=(v-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(R+=1),n(t)?(t.year=E,t.month=y,t.day=p,t.hour=_,t.minute=T,t.second=R,t.millisecond=g,t.isLeapSecond=r,t):new a(E,y,p,_,T,R,g,r)},m.toDate=function(e){var t=m.toGregorianDate(e,y),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var i,a=m.toGregorianDate(t,y);return n(r)||0===a.millisecond?n(r)&&0!==r?(i=(.01*a.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},m.addSeconds=function(e,t,r){return d(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,n,r)},m.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,n,r)},m.addDays=function(e,t,r){return d(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var i=new r.constructor;for(var a in r)if(r.hasOwnProperty(a)){var o=r[a];n&&(o=t(o,n)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function r(n,i,a){a=e(a,!1);var o,u,s,c={},l=t(n),f=t(i);if(l)for(o in n)n.hasOwnProperty(o)&&(u=n[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?r(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return r}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){t(i[r])||(i[r]=!0,console.warn(e(n,r)))}var i={};return n.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",n}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,r){"use strict";function n(e,t){r(e,t)}return n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(r,n,i){n=t(n,t(i.baseURI,i.location.href));var a=new e(n);return new e(r).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){var i="",a=r.lastIndexOf("/");return-1!==a&&(i=r.substring(0,a+1)),n?(r=new e(r),t(r.query)&&(i+="?"+r.query),t(r.fragment)&&(i+="#"+r.fragment),i):i}return n}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){var r=new e(t);r.normalize();var n=r.path,i=n.lastIndexOf("/");return-1!==i&&(n=n.substr(i+1)),i=n.lastIndexOf("."),n=-1===i?"":n.substr(i+1)}return n}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(r)||(r=document.createElement("a")),r.href=window.location.href;var n=r.host,i=r.protocol;return r.href=t,r.href=r.href,i!==r.protocol||n!==r.host}var r;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var i=e[n],a=encodeURIComponent(n)+"=";if(r(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return n}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(t){var n={};if(""===t)return n;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=n[s];"string"==typeof l?n[s]=[l,c]:r(l)?l.push(c):n[s]=c}return n}return n}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,n.OTHER),this.serverKey=void 0,this.state=r.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var i=r[n],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function n(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return r(n.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),n.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},n.prototype.removeEventListener=function(e,t){for(var r=this._listeners,n=this._scopes,i=-1,a=0;a<r.length;a++)if(r[a]===e&&n[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),r[i]=void 0,n[i]=void 0):(r.splice(i,1),n.splice(i,1)),!0)},n.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,r=this._listeners,n=this._scopes,a=r.length;for(e=0;e<a;e++){var o=r[e];t(o)&&r[e].apply(n[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];r.splice(s,1),n.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},n}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(i[c],i[e])<0?c:e,s<r&&n(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,n=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return r(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return a(r,e,--this._length),this.heapify(e),n}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return w[e]<f.maximumRequestsPerServer}function p(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--R.numberOfActiveRequests,--w[e.serverKey],N.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function y(e){return function(t){e.state!==c.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--w[e.serverKey],N.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function E(e){var t=p(e);return e.state=c.ACTIVE,S.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++w[e.serverKey],e.requestFunction().then(m(e)).otherwise(y(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--w[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function v(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){f.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),v())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},g=20,A=new o({comparator:l});A.maximumLength=g,A.reserve(g);var S=[],w={},O="undefined"!=typeof document?new e(document.location.href):new e,N=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=N,i(f,{statistics:{get:function(){ +return R}},priorityHeapLength:{get:function(){return g},set:function(e){if(e<g)for(;A.length>e;){var t=A.pop();_(t)}g=e,A.maximumLength=e,A.reserve(e)}}}),f.update=function(){var e,t,r=0,n=S.length;for(e=0;e<n;++e)t=S[e],t.cancelled&&_(t),t.state===c.ACTIVE?r>0&&(S[e-r]=t):++r;S.length-=r;var i=A.internalArray,a=A.length;for(e=0;e<a;++e)h(i[e]);A.resort();for(var o=Math.max(f.maximumRequests-S.length,0),u=0;u<o&&A.length>0;)t=A.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(E(t),++u):_(t);T()},f.getServerKey=function(t){var r=new e(t).resolve(O);r.normalize();var i=r.authority;/:/.test(i)||(i=i+":"+("https"===r.scheme?"443":"80"));var a=w[i];return n(a)||(w[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return N.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return E(e);if(!(S.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=A.insert(e);if(n(t)){if(t===e)return;_(t)}return p(e)}},f.clearForSpecs=function(){for(;A.length>0;){_(A.pop())}for(var e=S.length,t=0;t<e;++t)_(S[t]);S.length=0,w={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return w[e]},f.requestHeap=A,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var i=n.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=n.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])||(a[n]=!0)},i.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])&&delete a[n]},i.contains=function(e){var r=n(e);return!(!t(r)||!t(a[r]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,g,A,S,w){"use strict";function O(e,t){var r=e.query;if(!a(r)||0===r.length)return{};var i;if(-1===r.indexOf("=")){var o={};o[r]=void 0,i=o}else i=E(r);t._queryParameters=n(t._queryParameters,i),e.query=void 0}function N(e,t){var r=t._queryParameters,n=Object.keys(r);1!==n.length||a(r[n[0]])?e.query=y(r):e.query=n[0]}function I(e,t){return a(e)?a(e.clone)?e.clone():r(e):t}function x(e){if(e.state===R.ISSUED||e.state===R.ACTIVE)throw new g("The Resource is already being fetched.");e.state=R.UNISSUED,e.deferred=void 0}function M(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=I(e.templateValues,{}),this._queryParameters=I(e.queryParameters,{}),this.headers=I(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var r=e.request;r.url=e.url,r.requestFunction=function(){var r=e.url,n=!1;e.isDataUri||e.isBlobUri||(n=e.isCrossOriginUrl);var i=w.defer();return M._Implementations.createImage(r,n&&t,i),i.promise};var n=T.request(r);if(a(n))return n.otherwise(function(n){return r.state!==R.FAILED?w.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,C(e,t)):w.reject(n)})})}function P(e,t,r){var n={};n[t]=r,e.addQueryParameters(n);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=w.defer();return window[r]=function(e){t.resolve(e);try{delete window[r]}catch(e){window[r]=void 0}},M._Implementations.loadAndExecuteScript(e.url,r,t),t.promise};var o=T.request(i);if(a(o))return o.otherwise(function(n){return i.state!==R.FAILED?w.reject(n):e.retryOnError(n).then(function(a){return a?(i.state=R.UNISSUED,i.deferred=void 0,P(e,t,r)):w.reject(n)})})}function b(e,t){x(e.request);var r=e.request;r.url=e.url,r.requestFunction=function(){var i=t.responseType,o=n(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=w.defer(),f=M._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(r.cancelFunction=function(){f.abort()}),l.promise};var i=T.request(r);if(a(i))return i.then(function(e){return e}).otherwise(function(n){return r.state!==R.FAILED?w.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,e.fetch(t)):w.reject(n)})})}function D(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function U(e,t){for(var r=D(e,t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return n}function L(e,t){t=i(t,"");var r=e[1],n=!!e[2],a=e[3];switch(t){case"":case"text":return D(n,a);case"arraybuffer":return U(n,a);case"blob":var o=U(n,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(D(n,a),r);case"json":return JSON.parse(D(n,a))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();M.createIfNeeded=function(e,t){if(e instanceof M)return e.clone();if("string"!=typeof e)return e;var r=I(t,{});return r.url=e,new M(r)},o(M,{isBlobSupported:{get:function(){return F}}}),o(M.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new S(e);O(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return p(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),M.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var r=new S(this._url);e&&N(r,this);var n=r.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];n=n.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(n=this.proxy.getURL(n)),n},M.prototype.addQueryParameters=function(e,t){this._queryParameters=t?n(this._queryParameters,e):n(e,this._queryParameters)},M.prototype.addTemplateValues=function(e,t){this._templateValues=t?n(this._templateValues,e):n(e,this._templateValues)},M.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var r=new S(e.url);O(r,t),r.fragment=void 0,t._url=r.resolve(new S(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=n(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=n(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=n(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},M.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return w(!1);var r=this;return w(t(this,e)).then(function(e){return++r._retryCount,e})},M.prototype.clone=function(e){return a(e)||(e=new M({url:this._url})),e._url=this._url,e._queryParameters=r(this._queryParameters),e._templateValues=r(this._templateValues),e.headers=r(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},M.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},M.prototype.appendForwardSlash=function(){this._url=e(this._url)},M.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},M.fetchArrayBuffer=function(e){return new M(e).fetchArrayBuffer()},M.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},M.fetchBlob=function(e){return new M(e).fetchBlob()},M.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),x(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var r=this.fetchBlob();if(a(r)){var n,o;return r.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return n=new M({url:t}),C(n)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(n.url),e.blob=o,e}).otherwise(function(e){return a(n)&&window.URL.revokeObjectURL(n.url),w.reject(e)})}},M.fetchImage=function(e){return new M(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},M.prototype.fetchText=function(){return this.fetch({responseType:"text"})},M.fetchText=function(e){return new M(e).fetchText()},M.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},M.fetchJson=function(e){return new M(e).fetchJson()},M.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},M.fetchXML=function(e){return new M(e).fetchXML()},M.prototype.fetchJsonp=function(e){e=i(e,"callback"),x(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},M.fetchJsonp=function(e){return new M(e).fetchJsonp(e.callbackParameterName)},M.prototype.fetch=function(e){return e=I(e,i.EMPTY_OBJECT),e.method="GET",b(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return M.fetch=function(e){return new M(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},M.prototype.post=function(e,r){return t.defined("data",e),r=I(r,{}),r.method="POST",r.data=e,b(this,r)},M.post=function(e){return new M(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},M._Implementations={},M._Implementations.createImage=function(e,t,r){var n=new Image;n.onload=function(){r.resolve(n)},n.onerror=function(e){r.reject(e)},t&&(A.contains(e)?n.crossOrigin="use-credentials":n.crossOrigin=""),n.src=e},M._Implementations.loadWithXhr=function(e,t,r,n,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(L(s,t));var c=new XMLHttpRequest;if(A.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(r,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new v(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,r=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&r!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===r||"document"===r)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==r&&"text"!==r||!a(c.responseText)?o.reject(new g("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new v)},c.send(n),c},M._Implementations.loadAndExecuteScript=function(e,t,r){var n=document.createElement("script");n.async=!0,n.src=e;var i=document.getElementsByTagName("head")[0];n.onload=function(){n.onload=void 0,i.removeChild(n)},n.onerror=function(e){r.reject(e)},i.appendChild(n)},M._DefaultImplementations={},M._DefaultImplementations.createImage=M._Implementations.createImage,M._DefaultImplementations.loadWithXhr=M._Implementations.loadWithXhr,M._DefaultImplementations.loadAndExecuteScript=M._Implementations.loadAndExecuteScript,M.DEFAULT=c(new M({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),M}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))p(this,t.data);else if(n(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){p(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=r.columnNames.indexOf("modifiedJulianDateUtc"),a=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||p<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var y=e._samples=r.samples,E=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,v=e._addNewLeapSeconds,T=0,R=y.length;T<R;T+=e._columnCount){var g=y[T+i],A=y[T+m],S=g+l.MODIFIED_JULIAN_DATE_DIFFERENCE,w=new o(S,A,f.TAI);if(E.push(w),v){if(A!==_&&n(_)){var O=o.leapSeconds,N=t(O,w,d);if(N<0){var I=new u(w,A);O.splice(~N,0,I)}}_=A}}}function m(e,t,r,n,i){var a=r*n;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function y(e,t,r){return t+e*(r-t)}function E(e,t,r,n,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||n.equals(c))return m(e,r,i,s,u),u;if(n.equals(l))return m(e,r,a,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=r[h+e._ut1MinusUtcSecondsColumn],E=r[d+e._ut1MinusUtcSecondsColumn],_=E-p;if(_>.5||_<-.5){var v=r[h+e._taiMinusUtcSecondsColumn],T=r[d+e._taiMinusUtcSecondsColumn];v!==T&&(l.equals(n)?p=E:E-=T-v)}return u.xPoleWander=y(f,r[h+e._xPoleWanderRadiansColumn],r[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=y(f,r[h+e._yPoleWanderRadiansColumn],r[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=y(f,r[h+e._xCelestialPoleOffsetRadiansColumn],r[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=y(f,r[h+e._yCelestialPoleOffsetRadiansColumn],r[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=y(f,p,E),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new i(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var a=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!n(h),m=p||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!p&&h.equals(e)&&++s,l=s+1,E(this,a,this._samples,e,s,l,r),r}var y=t(a,e,o.compare,this._dateColumn);return y>=0?(y<a.length-1&&a[y+1].equals(e)&&++y,s=y,l=y):(l=~y,(s=l-1)<0&&(s=0)),this._lastIndex=s,E(this,a,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,r,n,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),i=d.exec(n);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new n({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var r=f(e);return h.href=r,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=n.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){n[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(n[c]*=c-l);n[c]=1/n[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,a.daysDifference(n,e._sampleZeroDateTT)}function l(r,i){if(r._chunkDownloadsInProgress[i])return r._chunkDownloadsInProgress[i];var a=e.defer();r._chunkDownloadsInProgress[i]=a;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){r._chunkDownloadsInProgress[i]=!1;for(var t=r._samples,n=e.samples,o=i*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,r,n,i){var a=c(this,t,r),o=c(this,n,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,r){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(n(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),n(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){n(r)?(r.x=0,r.y=0,r.s=0):r=new i(0,0,0);var p,m,y=a-s*this._stepSizeDays,E=this._work,_=this._denominators,v=this._coef,T=this._xTable;for(p=0;p<=u;++p)E[p]=y-T[p];for(p=0;p<=u;++p){for(v[p]=1,m=0;m<=u;++m)m!==p&&(v[p]*=E[m]);v[p]*=_[p];var R=3*(s+p);r.x+=v[p]*d[R++],r.y+=v[p]*d[R++],r.s+=v[p]*d[R]}return r}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(i,0)}var c=new e;s.fromAxisAngle=function(t,r,i){var a=r/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return n(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],m=h+d+p;if(m>0)r=Math.sqrt(m+1),c=.5*r,r=.5/r,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var y=l,E=0;d>h&&(E=1),p>h&&p>d&&(E=2);var _=y[E],v=y[_];r=Math.sqrt(e[u.getElementIndex(E,E)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(v,v)]+1);var T=f;T[E]=.5*r,r=.5/r,c=(e[u.getElementIndex(v,_)]-e[u.getElementIndex(_,v)])*r,T[_]=(e[u.getElementIndex(_,E)]+e[u.getElementIndex(E,_)])*r,T[v]=(e[u.getElementIndex(v,E)]+e[u.getElementIndex(E,v)])*r,i=-T[0],a=-T[1],o=-T[2]}return n(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,m=new s;s.fromHeadingPitchRoll=function(t,r){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(p,m,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,r,r)};var y=new e,E=new e,_=new s,v=new s,T=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,T),s.conjugate(T,T);for(var i=0,a=r-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,T,_),_.w<0&&s.negate(_,_),s.computeAxis(_,y);var u=s.computeAngle(_);n[o]=y.x*u,n[o+1]=y.y*u,n[o+2]=y.z*u}},s.unpackInterpolationResult=function(t,r,i,a,o){n(o)||(o=new s),e.fromArray(t,0,E);var u=e.magnitude(E);return s.unpack(r,4*a,v),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(E,u,_),s.multiply(_,v,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,i=e.y*r,a=e.z*r,o=e.w*r;return t.x=n,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+i*c-a*s,h=o*s-n*c+i*l+a*u,d=o*c+n*s-i*u+a*l,p=o*l-n*u-i*s-a*c;return r.x=f,r.y=h,r.z=d,r.w=p,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,r,n){return R=s.multiplyByScalar(t,r,R),n=s.multiplyByScalar(e,1-r,n),s.add(R,n,n)};var g=new s,A=new s,S=new s;s.slerp=function(e,t,r,n){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=g=s.negate(t,g)),1-i<o.EPSILON6)return s.lerp(e,a,r,n);var u=Math.acos(i);return A=s.multiplyByScalar(e,Math.sin((1-r)*u),A),S=s.multiplyByScalar(a,Math.sin(r*u),S),n=s.add(A,S,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),i=0;return 0!==n&&(i=n/Math.sin(n)),e.multiplyByScalar(t,i,r)},s.exp=function(t,r){var n=e.magnitude(t),i=0;return 0!==n&&(i=Math.sin(n)/n),r.x=t.x*i,r.y=t.y*i,r.z=t.z*i,r.w=Math.cos(n),r};var w=new e,O=new e,N=new s,I=new s;s.computeInnerQuadrangle=function(t,r,n,i){var a=s.conjugate(r,N);s.multiply(a,n,I);var o=s.log(I,w);s.multiply(a,t,I);var u=s.log(I,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,N),s.multiply(r,N,i)},s.squad=function(e,t,r,n,i,a){var o=s.slerp(e,t,i,N),u=s.slerp(r,n,i,I);return s.slerp(o,u,2*i*(1-i),a)};for(var x=new s,M=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],b=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var L=U+1,F=2*L+1;C[U]=1/(L*F),P[U]=L/F}return C[7]=M/136,P[7]=8*M/17,s.fastSlerp=function(e,t,r,n){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)b[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=i*r*(1+b[0]*(1+b[1]*(1+b[2]*(1+b[3]*(1+b[4]*(1+b[5]*(1+b[6]*(1+b[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),p=s.multiplyByScalar(e,d,x);return s.multiplyByScalar(t,h,n),s.add(p,n,n)},s.fastSquad=function(e,t,r,n,i,a){var o=s.fastSlerp(e,t,i,N),u=s.fastSlerp(r,n,i,I);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v){"use strict";var T={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},g={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},A={},S={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},w=new r,O=new r,N=new r;T.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,i=R[e][t],a=e+t;return u(A[a])?n=A[a]:(n=function(n,a,s){if(u(s)||(s=new E),m.equalsEpsilon(n.x,0,m.EPSILON14)&&m.equalsEpsilon(n.y,0,m.EPSILON14)){var c=m.sign(n.z);r.unpack(g[e],0,w),"east"!==e&&"west"!==e&&r.multiplyByScalar(w,c,w),r.unpack(g[t],0,O),"east"!==t&&"west"!==t&&r.multiplyByScalar(O,c,O),r.unpack(g[i],0,N),"east"!==i&&"west"!==i&&r.multiplyByScalar(N,c,N)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(n,S.up);var l=S.up,h=S.east;h.x=-n.y,h.y=n.x,h.z=0,r.normalize(h,S.east),r.cross(l,h,S.north),r.multiplyByScalar(S.up,-1,S.down),r.multiplyByScalar(S.east,-1,S.west),r.multiplyByScalar(S.north,-1,S.south),w=S[e],O=S[t],N=S[i]}return s[0]=w.x,s[1]=w.y,s[2]=w.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=N.x,s[9]=N.y,s[10]=N.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},A[a]=n),n},T.eastNorthUpToFixedFrame=T.localFrameToFixedFrameGenerator("east","north"),T.northEastDownToFixedFrame=T.localFrameToFixedFrameGenerator("north","east"),T.northUpEastToFixedFrame=T.localFrameToFixedFrameGenerator("north","up"),T.northWestUpToFixedFrame=T.localFrameToFixedFrameGenerator("north","west");var I=new _,x=new r(1,1,1),M=new E;T.headingPitchRollToFixedFrame=function(e,t,n,i,a){i=o(i,T.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,I),s=E.fromTranslationQuaternionRotationScale(r.ZERO,u,x,M);return a=i(e,n,a),E.multiply(a,s,a)};var C=new E,P=new y;T.headingPitchRollQuaternion=function(e,t,r,n,i){var a=T.headingPitchRollToFixedFrame(e,t,r,n,C),o=E.getRotation(a,P);return _.fromRotationMatrix(o,i)};var b=m.TWO_PI/86400,D=new p;T.computeTemeToPseudoFixedMatrix=function(e,t){D=p.addSeconds(e,-p.computeTaiMinusUtc(e),D);var r,n=D.dayNumber,i=D.secondsOfDay,a=n-2451545;r=i>=43200?(a+.5)/v.DAYS_PER_JULIAN_CENTURY:(a-.5)/v.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*b%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(i+.5*v.SECONDS_PER_DAY)%v.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new y(h,d,0,-d,h,0,0,0,1)},T.iau2006XysData=new h,T.earthOrientationParameters=c.NONE;T.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=T.iau2006XysData.preload(r,n,i,a),u=T.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},T.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new y);var r=T.computeFixedToIcrfMatrix(e,t);if(u(r))return y.transpose(r,t)};var U=new d(0,0,0),L=new l(0,0,0,0,0,0),F=new y,B=new y;T.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new y);var r=T.earthOrientationParameters.compute(e,L);if(u(r)){var n=e.dayNumber,i=e.secondsOfDay+32.184,a=T.iau2006XysData.computeXysRadians(n,i,U);if(u(a)){var o=a.x+r.xPoleOffset,s=a.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=y.fromRotationZ(-a.s,B),h=y.multiply(l,f,F),d=e.dayNumber,E=e.secondsOfDay-p.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=d-2451545,R=E/v.SECONDS_PER_DAY,g=.779057273264+R+.00273781191135448*(_+R);g=g%1*m.TWO_PI;var A=y.fromRotationZ(g,B),S=y.multiply(h,A,F),w=Math.cos(r.xPoleWander),O=Math.cos(r.yPoleWander),N=Math.sin(r.xPoleWander),I=Math.sin(r.yPoleWander),x=n-2451545+i/v.SECONDS_PER_DAY;x/=36525;var M=-47e-6*x*m.RADIANS_PER_DEGREE/3600,C=Math.cos(M),P=Math.sin(M),b=B;return b[0]=w*C,b[1]=w*P,b[2]=N,b[3]=-O*P+I*N*C,b[4]=O*C+I*N*P,b[5]=-I*w,b[6]=-I*P-O*N*C,b[7]=I*C-O*N*P,b[8]=O*w,y.multiply(S,b,t)}}};var z=new n;T.pointToWindowCoordinates=function(e,t,r,n){return n=T.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},T.pointToGLWindowCoordinates=function(e,r,i,a){u(a)||(a=new t);var o=z;return E.multiplyByVector(e,n.fromElements(i.x,i.y,i.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),E.multiplyByVector(r,o,o),t.fromCartesian4(o,a)} +;var q=new r,G=new r,V=new r;T.rotationMatrixFromPositionVelocity=function(e,t,n,i){var a=o(n,f.WGS84).geodeticSurfaceNormal(e,q),s=r.cross(t,a,G);r.equalsEpsilon(s,r.ZERO,m.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,V);return r.cross(t,c,s),r.negate(s,s),u(i)||(i=new y),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new E(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),H=new i,X=new r,k=new r,Y=new y,j=new E,Z=new E;return T.basisTo2D=function(e,t,n){var i=E.getTranslation(t,k),a=e.ellipsoid,o=a.cartesianToCartographic(i,H),u=e.project(o,X);r.fromElements(u.z,u.x,u.y,u);var s=T.eastNorthUpToFixedFrame(i,a,j),c=E.inverseTransformation(s,Z),l=E.getRotation(t,Y),f=E.multiplyByMatrix3(c,l,n);return E.multiply(W,f,n),E.setTranslation(n,u,n),n},T.wgs84To2DModelMatrix=function(e,t,n){var i=e.ellipsoid,a=T.eastNorthUpToFixedFrame(t,i,j),o=E.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,H),s=e.project(u,X);r.fromElements(s.z,s.x,s.y,s);var c=E.fromTranslation(s,j);return E.multiply(W,o,n),E.multiply(c,n,n),n},T}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d){"use strict";function p(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var n=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=r.fromCartesian4(l.getColumn(n,0,m)),this._yAxis=r.fromCartesian4(l.getColumn(n,1,m));var a=r.fromCartesian4(l.getColumn(n,2,m));this._plane=f.fromPointNormal(e,a)}var m=new n;o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var y=new e;p.fromPoints=function(t,r){return new p(e.fromPoints(t,y).center,r)};var E=new h,_=new r;p.prototype.projectPointOntoPlane=function(e,n){var i=E;i.origin=e,r.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return a(n)?(n.x=s,n.y=l,n):new t(s,l)}},p.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var r=0,n=e.length,i=0;i<n;i++){var o=this.projectPointOntoPlane(e[i],t[r]);a(o)&&(t[r]=o,r++)}return t.length=r,t},p.prototype.projectPointToNearestOnPlane=function(e,n){a(n)||(n=new t);var i=E;i.origin=e,r.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return n.x=s,n.y=l,n},p.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var r=e.length;t.length=r;for(var n=0;n<r;n++)t[n]=this.projectPointToNearestOnPlane(e[n],t[n]);return t};var v=new r;return p.prototype.projectPointsOntoEllipsoid=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=v,l=0;l<n;++l){var f=e[l];r.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new r);var h=r.add(o,c,t[l]);r.multiplyByScalar(s,f.y,c),r.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},p}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var i=e.attributes[n],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return i}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),i=256*(r-n);return u.octDecode(n,i,t)},u.octPack=function(e,t,r,n){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+i,n.y=65536*o.y+a,n},u.octUnpack=function(e,t,r,n){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(a,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function i(r,i,s,c,l){n(l)||(l=new t);var f,h,d,p,m,y,E,_;n(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(r,i,u),p=t.dot(f,f),m=t.dot(f,h),y=t.dot(f,d),E=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(r,i,u),p=e.dot(f,f),m=e.dot(f,h),y=e.dot(f,d),E=e.dot(h,h),_=e.dot(h,d));var v=1/(p*E-m*m);return l.y=(E*y-m*_)*v,l.z=(p*_-m*y)*v,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var i={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var a=t.high,o=t.low;return n.encode(e.x,i),a.x=i.high,o.x=i.low,n.encode(e.y,i),a.y=i.high,o.y=i.low,n.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,a);var i=a.high,o=a.low;t[r]=i.x,t[r+1]=i.y,t[r+2]=i.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,r,i){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,i):new Uint16Array(t,r,i)},r(a)}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,i=r.maximumIndex,a=e(r.cacheSize,24),o=n.length;if(!t(i)){i=0;for(var u=0,s=n[u];u<o;)s>i&&(i=s),++u,s=n[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[n[h]]>a&&(c[n[h]]=f,++f);return(f-a+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<n;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}r=e(r,e.EMPTY_OBJECT);var i,a=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<h;)p[a[l]].vertexTriangles.push(m),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(m),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(m),++p[a[l+2]].numLiveTriangles,++m,l+=3;var y=0,E=u+1;i=1;var _,v,T=[],R=[],g=0,A=[],S=s/3,w=[];for(d=0;d<S;d++)w[d]=!1;for(var O,N;-1!==y;){T=[],v=p[y],N=v.vertexTriangles.length;for(var I=0;I<N;++I)if(m=v.vertexTriangles[I],!w[m]){w[m]=!0,l=m+m+m;for(var x=0;x<3;++x)O=a[l],T.push(O),R.push(O),A[g]=O,++g,_=p[O],--_.numLiveTriangles,E-_.timeStamp>u&&(_.timeStamp=E,++E),++l}y=function(e,t,r,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var h=r[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?n(i,o,e,u):c}(a,u,T,p,E,R,c)}return A},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,g,A,S){"use strict";function w(e,t,r,n,i){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=i,e[t++]=i,e[t]=r}function O(e){for(var t=e.length,r=t/3*6,n=y.createTypedArray(t,r),i=0,a=0;a<t;a+=3,i+=6)w(n,i,e[a],e[a+1],e[a+2]);return n}function N(e){var t=e.length;if(t>=3){var r=6*(t-2),n=y.createTypedArray(t,r);w(n,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)w(n,i,e[a-1],e[a],e[a-2]);return n}return new Uint16Array}function I(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=y.createTypedArray(t,r),i=e[0],a=0,o=1;o<t;++o,a+=6)w(n,a,i,e[o],e[o+1]);return n}return new Uint16Array}function x(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new p({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function M(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var i=t[n],a=0;a<i.componentsPerAttribute;++a)e[n].values.push(i.values[r*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,r,a)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),T.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,r,a)}function b(e,t){var r,n=e.length,i={},a=e[0][t].attributes;for(r in a)if(a.hasOwnProperty(r)&&c(a[r])&&c(a[r].values)){for(var o=a[r],s=o.values.length,l=!0,f=1;f<n;++f){var h=e[f][t].attributes[r];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(i[r]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function D(e,t){var n,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,E=b(e,t);for(n in E)if(E.hasOwnProperty(n))for(s=E[n].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var v=0;for(a=0;a<h;++a)v+=e[a][t].indices.length;var T=d.computeNumberOfVertices(new d({attributes:E,primitiveType:A.POINTS})),R=y.createTypedArray(T,v),g=0,S=0;for(a=0;a<h;++a){var w=e[a][t].indices,O=w.length;for(u=0;u<O;++u)R[g++]=S+w[u];S+=d.computeNumberOfVertices(e[a][t])}_=R}var N,I=new i,x=0;for(a=0;a<h;++a){if(N=e[a][t].boundingSphere,!c(N)){I=void 0;break}i.add(N.center,I,I)}if(c(I))for(i.divideByScalar(I,h,I),a=0;a<h;++a){N=e[a][t].boundingSphere;var M=i.magnitude(i.subtract(N.center,I,se))+N.radius;M>x&&(x=M)}return new d({attributes:E,indices:_,primitiveType:m,boundingSphere:c(I)?new r(I,x):void 0})}function U(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function L(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,i=3;i<t;++i)r[n++]=i-1,r[n++]=0,r[n++]=i;return e.indices=r,e.primitiveType=A.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,i=3;i<t-1;i+=2)r[n++]=i,r[n++]=i-1,r[n++]=i+1,i+2<t&&(r[n++]=i,r[n++]=i+1,r[n++]=i+2);return e.indices=r,e.primitiveType=A.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return e.indices=r,e.primitiveType=A.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=A.LINES,e}function G(e){switch(e.primitiveType){case A.TRIANGLE_FAN:return L(e);case A.TRIANGLE_STRIP:return F(e);case A.TRIANGLES:return U(e);case A.LINE_STRIP:return z(e);case A.LINE_LOOP:return q(e);case A.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<v.EPSILON6&&(e.y=t?-v.EPSILON6:v.EPSILON6)}function W(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return V(e,e.y<0),V(t,t.y<0),void V(r,r.y<0);var n,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(r.y);n=i>a?i>o?v.sign(e.y):v.sign(r.y):a>o?v.sign(t.y):v.sign(r.y);var u=n<0;V(e,u),V(t,u),V(r,u)}function H(e,t,r,n){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),r),i.clone(r,n),V(r,!0),V(n,!1)}function X(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){W(e,t,r);var n=e.y<0,i=t.y<0,a=r.y<0,o=0;o+=n?1:0,o+=i?1:0,o+=a?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(H(e,t,ge,Se),H(e,r,Ae,we),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(H(t,r,ge,Se),H(t,e,Ae,we),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(H(r,e,ge,Se),H(r,t,Ae,we),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?i?a||(H(r,e,ge,Se),H(r,t,Ae,we),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(H(t,r,ge,Se),H(t,e,Ae,we),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(H(e,t,ge,Se),H(e,r,Ae,we),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=ge,s[4]=Ae,s[5]=Se,s[6]=we,s.length=7),Oe}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var i in n)if(n.hasOwnProperty(i)&&c(n[i])&&c(n[i].values)){var a=n[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=y.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var i=t[n];r[n]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:r,indices:[],primitiveType:e.primitiveType})}function j(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Z(e,r,a,o,u,s,l,f,h,d,p,m){if(c(s)||c(l)||c(f)||c(h)||c(d)){var y=i.fromArray(u,3*e,Ne),E=i.fromArray(u,3*r,Ie),_=i.fromArray(u,3*a,xe),v=t(o,y,E,_,Me);if(c(s)){var T=i.fromArray(s,3*e,Ne),R=i.fromArray(s,3*r,Ie),g=i.fromArray(s,3*a,xe);i.multiplyByScalar(T,v.x,T),i.multiplyByScalar(R,v.y,R),i.multiplyByScalar(g,v.z,g);var A=i.add(T,R,T);i.add(A,g,A),i.normalize(A,A),i.pack(A,p.normal.values,3*m)}if(c(d)){var S=i.fromArray(d,3*e,Ne),w=i.fromArray(d,3*r,Ie),O=i.fromArray(d,3*a,xe);i.multiplyByScalar(S,v.x,S),i.multiplyByScalar(w,v.y,w),i.multiplyByScalar(O,v.z,O);var N;i.equals(S,i.ZERO)&&i.equals(w,i.ZERO)&&i.equals(O,i.ZERO)?(N=Ne,N.x=0,N.y=0,N.z=0):(N=i.add(S,w,S),i.add(N,O,N),i.normalize(N,N)),i.pack(N,p.extrudeDirection.values,3*m)}if(c(l)){var I=i.fromArray(l,3*e,Ne),x=i.fromArray(l,3*r,Ie),M=i.fromArray(l,3*a,xe);i.multiplyByScalar(I,v.x,I),i.multiplyByScalar(x,v.y,x),i.multiplyByScalar(M,v.z,M);var C=i.add(I,x,I);i.add(C,M,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*m)}if(c(f)){var P=i.fromArray(f,3*e,Ne),b=i.fromArray(f,3*r,Ie),D=i.fromArray(f,3*a,xe);i.multiplyByScalar(P,v.x,P),i.multiplyByScalar(b,v.y,b),i.multiplyByScalar(D,v.z,D);var U=i.add(P,b,P);i.add(U,D,U),i.normalize(U,U),i.pack(U,p.bitangent.values,3*m)}if(c(h)){var L=n.fromArray(h,2*e,Ce),F=n.fromArray(h,2*r,Pe),B=n.fromArray(h,2*a,be);n.multiplyByScalar(L,v.x,L),n.multiplyByScalar(F,v.y,F),n.multiplyByScalar(B,v.z,B);var z=n.add(L,F,L);n.add(z,B,z),n.pack(z,p.st.values,2*m)}}}function K(e,t,r,n,i,a){var o=e.position.values.length/3;if(-1!==i){var u=n[i],s=r[u];return-1===s?(r[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,r,n,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,y=u.indices,E=Y(u),_=Y(u),v=[];v.length=l.length/3;var T=[];for(T.length=l.length/3,o=0;o<v.length;++o)v[o]=-1,T[o]=-1;var R=y.length;for(o=0;o<R;o+=3){var g=y[o],A=y[o+1],S=y[o+2],w=i.fromArray(l,3*g),O=i.fromArray(l,3*A),N=i.fromArray(l,3*S),I=X(w,O,N);if(c(I)&&I.positions.length>3)for(var x=I.positions,M=I.indices,C=M.length,P=0;P<C;++P){var b=M[P],D=x[b];D.y<0?(t=_.attributes,r=_.indices,n=v):(t=E.attributes,r=E.indices,n=T),a=K(t,r,n,y,b<3?o+b:-1,D),Z(g,A,S,D,l,f,d,h,p,m,t,a)}else c(I)&&(w=I.positions[0],O=I.positions[1],N=I.positions[2]),w.y<0?(t=_.attributes,r=_.indices,n=v):(t=E.attributes,r=E.indices,n=T),a=K(t,r,n,y,o,w),Z(g,A,S,w,l,f,d,h,p,m,t,a),a=K(t,r,n,y,o+1,O),Z(g,A,S,O,l,f,d,h,p,m,t,a),a=K(t,r,n,y,o+2,N),Z(g,A,S,N,l,f,d,h,p,m,t,a)}j(e,_,E)}function Q(e){var t,r=e.geometry,n=r.attributes,a=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],m=i.fromArray(a,3*d,Ne),y=i.fromArray(a,3*p,Ie);Math.abs(m.y)<v.EPSILON6&&(m.y<0?m.y=-v.EPSILON6:m.y=v.EPSILON6),Math.abs(y.y)<v.EPSILON6&&(y.y<0?y.y=-v.EPSILON6:y.y=v.EPSILON6);var E=u.attributes,T=u.indices,R=h,g=s.attributes,A=s.indices,S=f,w=_.lineSegmentPlane(m,y,De,xe);if(c(w)){var O=i.multiplyByScalar(i.UNIT_Y,5*v.EPSILON9,Ue);m.y<0&&(i.negate(O,O),E=s.attributes,T=s.indices,R=f,g=u.attributes,A=u.indices,S=h);var N=i.add(w,O,Le);K(E,T,R,o,t,m),K(E,T,R,o,-1,N),i.negate(O,O),i.add(w,O,N),K(g,A,S,o,-1,N),K(g,A,S,o,t+1,y)}else{var I,x,M;m.y<0?(I=s.attributes,x=s.indices,M=f):(I=u.attributes,x=u.indices,M=h),K(I,x,M,o,t,m),K(I,x,M,o,t+1,y)}}j(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,a=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=i.unpack(r,u,ze);if(!(s.x>0)){var c=i.unpack(n,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):i.pack(s,n,u));var l=i.unpack(a,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=r[u+3],a[u+1]=r[u+4],a[u+2]=r[u+5]):i.pack(s,a,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,y=Y(u),E=Y(u),T=!1,R=l.length/3;for(t=0;t<R;t+=4){var g=t,A=t+2,S=i.fromArray(l,3*g,ze),w=i.fromArray(l,3*A,qe);if(Math.abs(S.y)<Ye)for(S.y=Ye*(w.y<0?-1:1),l[3*t+1]=S.y,l[3*(t+1)+1]=S.y,r=3*g;r<3*g+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(w.y)<Ye)for(w.y=Ye*(S.y<0?-1:1),l[3*(t+2)+1]=w.y,l[3*(t+3)+1]=w.y,r=3*g;r<3*g+12;r+=3)h[r]=l[3*(t+2)],h[r+1]=l[3*(t+2)+1],h[r+2]=l[3*(t+2)+2];var O=y.attributes,N=y.indices,I=E.attributes,x=E.indices,M=_.lineSegmentPlane(S,w,De,Ve);if(c(M)){T=!0;var C=i.multiplyByScalar(i.UNIT_Y,ke,We);S.y<0&&(i.negate(C,C),O=E.attributes,N=E.indices,I=y.attributes,x=y.indices);var P=i.add(M,C,He);O.position.values.push(S.x,S.y,S.z,S.x,S.y,S.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*g],f[3*g+1],f[3*g+2]),O.prevPosition.values.push(f[3*g+3],f[3*g+4],f[3*g+5]),O.prevPosition.values.push(S.x,S.y,S.z,S.x,S.y,S.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(M,C,P),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(w.x,w.y,w.z,w.x,w.y,w.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(w.x,w.y,w.z,w.x,w.y,w.z),I.nextPosition.values.push(h[3*A],h[3*A+1],h[3*A+2]),I.nextPosition.values.push(h[3*A+3],h[3*A+4],h[3*A+5]);var b=n.fromArray(d,2*g,Fe),D=Math.abs(b.y);O.expandAndWidth.values.push(-1,D,1,D),O.expandAndWidth.values.push(-1,-D,1,-D),I.expandAndWidth.values.push(-1,D,1,D),I.expandAndWidth.values.push(-1,-D,1,-D);var U=i.magnitudeSquared(i.subtract(M,S,Ge));if(U/=i.magnitudeSquared(i.subtract(w,S,Ge)),c(m)){var L=a.fromArray(m,4*g,Xe),F=a.fromArray(m,4*A,Xe),B=v.lerp(L.x,F.x,U),z=v.lerp(L.y,F.y,U),q=v.lerp(L.z,F.z,U),G=v.lerp(L.w,F.w,U);for(r=4*g;r<4*g+8;++r)O.color.values.push(m[r]);for(O.color.values.push(B,z,q,G),O.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),r=4*A;r<4*A+8;++r)I.color.values.push(m[r])}if(c(p)){var V=n.fromArray(p,2*g,Fe),W=n.fromArray(p,2*(t+3),Be),H=v.lerp(V.x,W.x,U);for(r=2*g;r<2*g+4;++r)O.st.values.push(p[r]);for(O.st.values.push(H,V.y),O.st.values.push(H,W.y),I.st.values.push(H,V.y),I.st.values.push(H,W.y),r=2*A;r<2*A+4;++r)I.st.values.push(p[r])}o=O.position.values.length/3-4,N.push(o,o+2,o+1),N.push(o+1,o+2,o+3),o=I.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3)}else{var X,k;for(S.y<0?(X=E.attributes,k=E.indices):(X=y.attributes,k=y.indices),X.position.values.push(S.x,S.y,S.z),X.position.values.push(S.x,S.y,S.z),X.position.values.push(w.x,w.y,w.z),X.position.values.push(w.x,w.y,w.z),r=3*t;r<3*t+12;++r)X.prevPosition.values.push(f[r]),X.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)X.expandAndWidth.values.push(d[r]),c(p)&&X.st.values.push(p[r]);if(c(m))for(r=4*t;r<4*t+16;++r)X.color.values.push(m[r]);o=X.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}T&&($(E),$(y)),j(e,E,y)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case A.TRIANGLES:e.indices=O(t);break;case A.TRIANGLE_STRIP:e.indices=N(t);break;case A.TRIANGLE_FAN:e.indices=I(t)}e.primitiveType=A.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*n,l[f++]=i[h+1]+a[h+1]*n,l[f++]=i[h+2]+a[h+2]*n;var m,y=e.boundingSphere;return c(y)&&(m=new r(y.center,y.radius+n)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:A.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,i={},a=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(i[u]=a++)}for(var s in n)n.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),i=0;i<t;i++)n[i]=-1;for(var a,o=r,s=o.length,l=y.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=n[o[f]],-1!==a?l[h]=a:(a=o[f],n[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var m=e.attributes;for(var E in m)if(m.hasOwnProperty(E)&&c(m[E])&&c(m[E].values)){for(var _=m[E],v=_.values,T=0,R=_.componentsPerAttribute,g=u.createTypedArray(_.componentDatatype,p*R);T<t;){var A=n[T];if(-1!==A)for(var S=0;S<R;S++)g[R*A+S]=v[R*T+S];++T}_.values=g}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===A.TRIANGLES&&c(r)){for(var n=r.length,i=0,a=0;a<n;a++)r[a]>i&&(i=r[a]);e.indices=S.tipsify({indices:r,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=d.computeNumberOfVertices(e);if(c(e.indices)&&r>=v.SIXTY_FOUR_KILOBYTES){var n,i=[],a=[],o=0,u=x(e.attributes),s=e.indices,l=s.length;e.primitiveType===A.TRIANGLES?n=3:e.primitiveType===A.LINES?n=2:e.primitiveType===A.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var h=0;h<n;++h){var p=s[f+h],m=i[p];c(m)||(m=o++,i[p]=m,M(u,e.attributes,p)),a.push(m)}o+n>=v.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=x(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new i,ne=new o;te.projectTo2D=function(e,t,r,n,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,m=0;m<l.length;m+=3){var y=i.fromArray(l,m,re),E=s.cartesianToCartographic(y,ne),_=a.project(E,re);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[r]=o,e.attributes[n]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new T;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=r.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,i=0;i<n;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&r.push(a)}var o=[];return t.length>0&&o.push(D(t,"geometry")),r.length>0&&(o.push(D(r,"westHemisphereGeometry")),o.push(D(r,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,a=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=r[t],m=r[t+1],y=r[t+2],E=3*d,_=3*m,T=3*y;le.x=a[E],le.y=a[E+1],le.z=a[E+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[T],he.y=a[T+1],he.z=a[T+2],c[d].count++,c[m].count++,c[y].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var g;for(t=0;t<s;t+=3){g=c[r[t]];var A=g.indexOffset+g.currentCount;f[A]=h,g.currentCount++,g=c[r[t+1]],A=g.indexOffset+g.currentCount,f[A]=h,g.currentCount++,g=c[r[t+2]],A=g.indexOffset+g.currentCount,f[A]=h,g.currentCount++,h++}var S=new Float32Array(3*o);for(t=0;t<o;t++){var w=3*t;if(g=c[t],i.clone(i.ZERO,ce),g.count>0){for(h=0;h<g.count;h++)i.add(ce,l[f[g.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&i.clone(l[f[g.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),S[w]=ce.x,S[w+1]=ce.y,S[w+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:S}),e};var de=new i,pe=new i,me=new i;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var m=r[t],y=r[t+1],E=r[t+2];f=3*m,h=3*y,d=3*E;var _=2*m,v=2*y,T=2*E,R=n[f],g=n[f+1],A=n[f+2],S=o[_],w=o[_+1],O=o[v+1]-w,N=o[T+1]-w,I=1/((o[v]-S)*N-(o[T]-S)*O),x=(N*(n[h]-R)-O*(n[d]-R))*I,M=(N*(n[h+1]-g)-O*(n[d+1]-g))*I,C=(N*(n[h+2]-A)-O*(n[d+2]-A))*I;l[f]+=x,l[f+1]+=M,l[f+2]+=C,l[h]+=x,l[h+1]+=M,l[h+2]+=C,l[d]+=x,l[d+1]+=M,l[d+2]+=C}var P=new Float32Array(3*s),b=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var D=i.fromArray(a,f,de),U=i.fromArray(l,f,me),L=i.dot(D,U);i.multiplyByScalar(D,L,pe),i.normalize(i.subtract(U,pe,U),U),P[f]=U.x,P[h]=U.y,P[d]=U.z,i.normalize(i.cross(D,U,U),U),b[f]=U.x,b[h]=U.y,b[d]=U.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:b}),e};var ye=new n,Ee=new i,_e=new i,ve=new i,Te=new n;te.compressVertices=function(t){var r,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(r=0;r<a;++r)i.fromArray(s,3*r,Ee),i.equals(Ee,i.ZERO)?f+=2:(Te=e.octEncodeInRange(Ee,65535,Te),l[f++]=Te.x, +l[f++]=Te.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,m=c(h),y=c(d);if(!m&&!y)return t;var E,_,v,T,R=t.attributes.tangent,g=t.attributes.bitangent,A=c(R),S=c(g);m&&(E=h.values),y&&(_=d.values),A&&(v=R.values),S&&(T=g.values),a=(m?E.length:_.length)/(m?3:2);var w=a,O=y&&m?2:1;O+=A||S?1:0,w*=O;var N=new Float32Array(w),I=0;for(r=0;r<a;++r){y&&(n.fromArray(_,2*r,ye),N[I++]=e.compressTextureCoordinates(ye));var x=3*r;m&&c(v)&&c(T)?(i.fromArray(E,x,Ee),i.fromArray(v,x,_e),i.fromArray(T,x,ve),e.octPack(Ee,_e,ve,ye),N[I++]=ye.x,N[I++]=ye.y):(m&&(i.fromArray(E,x,Ee),N[I++]=e.octEncodeFloat(Ee)),A&&(i.fromArray(v,x,Ee),N[I++]=e.octEncodeFloat(Ee)),S&&(i.fromArray(T,x,Ee),N[I++]=e.octEncodeFloat(Ee)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:N}),m&&delete t.attributes.normal,y&&delete t.attributes.st,S&&delete t.attributes.bitangent,A&&delete t.attributes.tangent,t};var Re=new i,ge=new i,Ae=new i,Se=new i,we=new i,Oe={positions:new Array(7),indices:new Array(9)},Ne=new i,Ie=new i,xe=new i,Me=new i,Ce=new n,Pe=new n,be=new n,De=g.fromPointNormal(i.ZERO,i.UNIT_Y),Ue=new i,Le=new i,Fe=new n,Be=new n,ze=new i,qe=new i,Ge=new i,Ve=new i,We=new i,He=new i,Xe=new a,ke=5*v.EPSILON9,Ye=v.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,g.ORIGIN_ZX_PLANE)!==E.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else G(t),t.primitiveType===A.TRIANGLES?J(e):t.primitiveType===A.LINES&&Q(e);return e},te}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,r,n){"use strict";function i(e,n,i){if(r(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!n(s,c,a));++u);if(u===o)return i&&n(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],n(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&n(l[0],l[l.length-1],a)&&l.shift(),l}}var a=n.EPSILON10;return i}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,r,i){i=i||2;var a=r&&r.length,o=a?r[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,p,m,y;if(a&&(u=s(e,r,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var E=i;E<o;E+=i)p=e[E],m=e[E+1],p<l&&(l=p),m<f&&(f=m),p>h&&(h=p),m>d&&(d=m);y=Math.max(h-l,d-f)}return n(u,c,i,l,f,y),c}function t(e,t,r,n,i){var a,o;if(i===I(e,t,r,n)>0)for(a=t;a<r;a+=n)o=w(a,e[a],e[a+1],o);else for(a=r-n;a>=t;a-=n)o=w(a,e[a],e[a+1],o);return o&&v(o,o.next)&&(O(o),o=o.next),o}function r(e,t){if(!e)return e;t||(t=e);var r,n=e;do{if(r=!1,n.steiner||!v(n,n.next)&&0!==_(n.prev,n,n.next))n=n.next;else{if(O(n),(n=t=n.prev)===n.next)return null;r=!0}}while(r||n!==t);return t}function n(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var p,m,y=e;e.prev!==e.next;)if(p=e.prev,m=e.next,f?a(e,c,l,f):i(e))t.push(p.i/s),t.push(e.i/s),t.push(m.i/s),O(e),e=m.next,y=m.next;else if((e=m)===y){d?1===d?(e=o(e,t,s),n(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):n(r(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,r=e,n=e.next;if(_(t,r,n)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(y(t.x,t.y,r.x,r.y,n.x,n.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,r,n){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=p(u,s,t,r,n),h=p(c,l,t,r,n),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&y(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&y(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,r){var n=e;do{var i=n.prev,a=n.next.next;!v(i,a)&&T(i,n,n.next,a)&&g(i,a)&&g(a,i)&&(t.push(i.i/r),t.push(n.i/r),t.push(a.i/r),O(n),O(n.next),n=e=a),n=n.next}while(n!==e);return n}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&E(s,c)){var l=S(s,c);return s=r(s,s.next),l=r(l,l.next),n(s,t,i,a,o,u),void n(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,n,i,a){var o,u,s,f,h,d=[];for(o=0,u=n.length;o<u;o++)s=n[o]*a,f=o<u-1?n[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=r(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var n=S(t,e);r(n,n.next)}}function f(e,t){var r,n=t,i=e.x,a=e.y,o=-1/0;do{if(a<=n.y&&a>=n.next.y){var u=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(u<=i&&u>o){if(o=u,u===i){if(a===n.y)return n;if(a===n.next.y)return n.next}r=n.x<n.next.x?n:n.next}}n=n.next}while(n!==t);if(!r)return null;if(i===o)return r.prev;var s,c=r,l=r.x,f=r.y,h=1/0;for(n=r.next;n!==c;)i>=n.x&&n.x>=l&&y(a<f?i:o,a,l,f,a<f?o:i,a,n.x,n.y)&&((s=Math.abs(a-n.y)/(i-n.x))<h||s===h&&n.x>r.x)&&g(n,e)&&(r=n,h=s),n=n.next;return r}function h(e,t,r,n){var i=e;do{null===i.z&&(i.z=p(i.x,i.y,t,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,r,n,i,a,o,u,s,c=1;do{for(r=e,e=null,a=null,o=0;r;){for(o++,n=r,u=0,t=0;t<c&&(u++,n=n.nextZ);t++);for(s=c;u>0||s>0&&n;)0===u?(i=n,n=n.nextZ,s--):0!==s&&n?r.z<=n.z?(i=r,r=r.nextZ,u--):(i=n,n=n.nextZ,s--):(i=r,r=r.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;r=n}a.nextZ=null,c*=2}while(o>1);return e}function p(e,t,r,n,i){return e=32767*(e-r)/i,t=32767*(t-n)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,r=e;do{t.x<r.x&&(r=t),t=t.next}while(t!==e);return r}function y(e,t,r,n,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(n-u)-(r-o)*(t-u)>=0&&(r-o)*(a-u)-(i-o)*(n-u)>=0}function E(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!R(e,t)&&g(e,t)&&g(t,e)&&A(e,t)}function _(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function v(e,t){return e.x===t.x&&e.y===t.y}function T(e,t,r,n){return!!(v(e,t)&&v(r,n)||v(e,n)&&v(r,t))||_(e,t,r)>0!=_(e,t,n)>0&&_(r,n,e)>0!=_(r,n,t)>0}function R(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&T(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function g(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function A(e,t){var r=e,n=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{r.y>a!=r.next.y>a&&i<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==e);return n}function S(e,t){var r=new N(e.i,e.x,e.y),n=new N(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,r.next=i,i.prev=r,n.next=r,r.prev=n,a.next=n,n.prev=a,n}function w(e,t,r,n){var i=new N(e,t,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function N(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function I(e,t,r,n){for(var i=0,a=t,o=r-n;a<r;a+=n)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,r,n){var i=t&&t.length,a=i?t[0]*r:e.length,o=Math.abs(I(e,0,a,r));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*r,l=u<s-1?t[u+1]*r:e.length;o-=Math.abs(I(e,c,l,r))}var f=0;for(u=0;u<n.length;u+=3){var h=n[u]*r,d=n[u+1]*r,p=n[u+2]*r;f+=Math.abs((e[h]-e[p])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[p+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,r={vertices:[],holes:[],dimensions:t},n=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)r.vertices.push(e[i][a][o]);i>0&&(n+=e[i-1].length,r.holes.push(n))}return r},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===r.CLOCKWISE||e===r.COUNTER_CLOCKWISE}};return e(r)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";var d=new r,p=new r,m={};m.computeArea2D=function(e){for(var t=e.length,r=0,n=t-1,i=0;i<t;n=i++){var a=e[n],o=e[i];r+=a.x*o.y-o.x*a.y}return.5*r},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(r,n){var i=t.packArray(r);return e(i,n,2)};var y=new r,E=new r,_=new r,v=new r,T=new r,R=new r,g=new r;return m.computeSubdivision=function(e,t,n,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=n.slice(0),p=t.length,m=new Array(3*p),A=0;for(h=0;h<p;h++){var S=t[h];m[A++]=S.x,m[A++]=S.y,m[A++]=S.z}for(var w=[],O={},N=e.maximumRadius,I=l.chordLength(u,N),x=I*I;d.length>0;){var M,C,P=d.pop(),b=d.pop(),D=d.pop(),U=r.fromArray(m,3*D,y),L=r.fromArray(m,3*b,E),F=r.fromArray(m,3*P,_),B=r.multiplyByScalar(r.normalize(U,v),N,v),z=r.multiplyByScalar(r.normalize(L,T),N,T),q=r.multiplyByScalar(r.normalize(F,R),N,R),G=r.magnitudeSquared(r.subtract(B,z,g)),V=r.magnitudeSquared(r.subtract(z,q,g)),W=r.magnitudeSquared(r.subtract(q,B,g)),H=Math.max(G,V,W);H>x?G===H?(M=Math.min(D,b)+" "+Math.max(D,b),h=O[M],o(h)||(C=r.add(U,L,g),r.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(D,h,P),d.push(h,b,P)):V===H?(M=Math.min(b,P)+" "+Math.max(b,P),h=O[M],o(h)||(C=r.add(L,F,g),r.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(b,h,D),d.push(h,P,D)):W===H&&(M=Math.min(P,D)+" "+Math.max(P,D),h=O[M],o(h)||(C=r.add(F,U,g),r.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(P,h,b),d.push(h,D,b)):(w.push(D),w.push(b),w.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:m})},indices:w,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,n,i){n=a(n,u.WGS84);var s=d,c=p;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)r.fromArray(e,f,c),i&&(c=n.scaleToGeodeticSurface(c,c)),0!==t&&(s=n.geodeticSurfaceNormal(c,s),r.multiplyByScalar(s,t,s),r.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/Queue",["./defineProperties"],function(e){"use strict";function t(){this._array=[],this._offset=0,this._length=0}return e(t.prototype,{length:{get:function(){return this._length}}}),t.prototype.enqueue=function(e){this._array.push(e),this._length++},t.prototype.dequeue=function(){if(0!==this._length){var e=this._array,t=this._offset,r=e[t];return e[t]=void 0,t++,t>10&&2*t>e.length&&(this._array=e.slice(t),t=0),this._offset=t,this._length--,r}},t.prototype.peek=function(){if(0!==this._length)return this._array[this._offset]},t.prototype.contains=function(e){return-1!==this._array.indexOf(e)},t.prototype.clear=function(){this._array.length=this._offset=this._length=0},t.prototype.sort=function(e){this._offset>0&&(this._array=this._array.slice(this._offset),this._offset=0),this._array.sort(e)},t}),define("Core/PolygonGeometryLibrary",["./arrayRemoveDuplicates","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m){"use strict";function y(e,r,n,i){return t.subtract(r,e,_),t.multiplyByScalar(_,n/i,_),t.add(e,_,_),[_.x,_.y,_.z]}var E={};E.computeHierarchyPackedLength=function(e){for(var r=0,n=[e];n.length>0;){var a=n.pop();if(i(a)){r+=2;var o=a.positions,u=a.holes;if(i(o)&&(r+=o.length*t.packedLength),i(u))for(var s=u.length,c=0;c<s;++c)n.push(u[c])}}return r},E.packPolygonHierarchy=function(e,r,n){for(var a=[e];a.length>0;){var o=a.pop();if(i(o)){var u=o.positions,s=o.holes;if(r[n++]=i(u)?u.length:0,r[n++]=i(s)?s.length:0,i(u))for(var c=u.length,l=0;l<c;++l,n+=3)t.pack(u[l],r,n);if(i(s))for(var f=s.length,h=0;h<f;++h)a.push(s[h])}}return n},E.unpackPolygonHierarchy=function(e,r){for(var n=e[r++],i=e[r++],a=new Array(n),o=i>0?new Array(i):void 0,u=0;u<n;++u,r+=t.packedLength)a[u]=t.unpack(e,r);for(var s=0;s<i;++s)o[s]=E.unpackPolygonHierarchy(e,r),r=o[s].startingIndex,delete o[s].startingIndex;return{positions:a,holes:o,startingIndex:r}};var _=new t;E.subdivideLineCount=function(e,r,n){var i=t.distance(e,r),a=i/n,o=Math.max(0,Math.ceil(Math.log(a)/Math.log(2)));return Math.pow(2,o)},E.subdivideLine=function(e,r,n,a){var o=E.subdivideLineCount(e,r,n),u=t.distance(e,r),s=u/o;i(a)||(a=[]);var c=a;c.length=3*o;for(var l=0,f=0;f<o;f++){var h=y(e,r,f*s,u);c[l++]=h[0],c[l++]=h[1],c[l++]=h[2]}return c};var v=new t,T=new t,R=new t,g=new t;E.scaleToGeodeticHeightExtruded=function(e,r,o,u,s){u=n(u,a.WGS84);var c=v,l=T,f=R,h=g;if(i(e)&&i(e.attributes)&&i(e.attributes.position))for(var d=e.attributes.position.values,p=d.length/2,m=0;m<p;m+=3)t.fromArray(d,m,f),u.geodeticSurfaceNormal(f,c),h=u.scaleToGeodeticSurface(f,h),l=t.multiplyByScalar(c,o,l),l=t.add(h,l,l),d[m+p]=l.x,d[m+1+p]=l.y,d[m+2+p]=l.z,s&&(h=t.clone(f,h)),l=t.multiplyByScalar(c,r,l),l=t.add(h,l,l),d[m]=l.x,d[m+1]=l.y,d[m+2]=l.z;return e},E.polygonsFromHierarchy=function(r,n,a,o){var u=[],s=[],c=new p;for(c.enqueue(r);0!==c.length;){var l=c.dequeue(),f=l.positions,d=l.holes;if(f=e(f,t.equalsEpsilon,!0),!(f.length<3)){var y=a.projectPointsOntoPlane(f),E=[],_=h.computeWindingOrder2D(y);_===m.CLOCKWISE&&(y.reverse(),f=f.slice().reverse());var v,T,R=f.slice(),g=i(d)?d.length:0,A=[];for(v=0;v<g;v++){var S=d[v],w=e(S.positions,t.equalsEpsilon,!0);if(!(w.length<3)){var O=a.projectPointsOntoPlane(w);_=h.computeWindingOrder2D(O),_===m.CLOCKWISE&&(O.reverse(),w=w.slice().reverse()),A.push(w),E.push(R.length),R=R.concat(w),y=y.concat(O);var N=0;for(i(S.holes)&&(N=S.holes.length),T=0;T<N;T++)c.enqueue(S.holes[T])}}if(!n){for(v=0;v<f.length;v++)o.scaleToGeodeticSurface(f[v],f[v]);for(v=0;v<A.length;v++){var I=A[v];for(T=0;T<I.length;++T)o.scaleToGeodeticSurface(I[T],I[T])}}u.push({outerRing:f,holes:A}),s.push({positions:R,positions2D:y,holes:E})}}return{hierarchy:u,polygons:s}},E.createGeometryFromPositions=function(e,t,n,i,a){var s=h.triangulate(t.positions2D,t.holes);s.length<3&&(s=[0,1,2]);var l=t.positions;if(i){for(var f=l.length,p=new Array(3*f),m=0,y=0;y<f;y++){var E=l[y];p[m++]=E.x,p[m++]=E.y,p[m++]=E.z}var _=new o({attributes:{position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:p})},indices:s,primitiveType:d.TRIANGLES});return a.normal?c.computeNormal(_):_}return h.computeSubdivision(e,l,s,n)};var A=[],S=new t,w=new t;return E.computeWallGeometry=function(e,n,i,a){var c,h,p,m,y,_=e.length,v=0;if(a)for(h=3*_*2,c=new Array(2*h),p=0;p<_;p++)m=e[p],y=e[(p+1)%_],c[v]=c[v+h]=m.x,++v,c[v]=c[v+h]=m.y,++v,c[v]=c[v+h]=m.z,++v,c[v]=c[v+h]=y.x,++v,c[v]=c[v+h]=y.y,++v,c[v]=c[v+h]=y.z,++v;else{var T=f.chordLength(i,n.maximumRadius),R=0;for(p=0;p<_;p++)R+=E.subdivideLineCount(e[p],e[(p+1)%_],T);for(h=3*(R+_),c=new Array(2*h),p=0;p<_;p++){m=e[p],y=e[(p+1)%_];for(var g=E.subdivideLine(m,y,T,A),O=g.length,N=0;N<O;++N,++v)c[v]=g[N],c[v+h]=g[N];c[v]=y.x,c[v+h]=y.x,++v,c[v]=y.y,c[v+h]=y.y,++v,c[v]=y.z,c[v+h]=y.z,++v}}_=c.length;var I=l.createTypedArray(_/3,_-6*e.length),x=0;for(_/=6,p=0;p<_;p++){var M=p,C=M+1,P=M+_,b=P+1;m=t.fromArray(c,3*M,S),y=t.fromArray(c,3*C,w),t.equalsEpsilon(m,y,f.EPSILON14)||(I[x++]=M,I[x++]=P,I[x++]=C,I[x++]=C,I[x++]=P,I[x++]=b)}return new o({attributes:new s({position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:c})}),indices:I,primitiveType:d.TRIANGLES})},E}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=n(new i({position:!0})),i.POSITION_AND_NORMAL=n(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=n(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=n(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=n(new i({position:!0,color:!0})),i.ALL=n(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.position?1:0,r[n++]=t.normal?1:0,r[n++]=t.st?1:0,r[n++]=t.tangent?1:0,r[n++]=t.bitangent?1:0,r[n]=t.color?1:0,r},i.unpack=function(r,n,a){return n=e(n,0),t(a)||(a=new i),a.position=1===r[n++],a.normal=1===r[n++],a.st=1===r[n++],a.tangent=1===r[n++],a.bitangent=1===r[n++],a.color=1===r[n],a},i.clone=function(e,r){if(t(e))return t(r)||(r=new i),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},i}),define("Core/PolygonGeometry",["./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Geometry","./GeometryAttribute","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./PolygonGeometryLibrary","./PolygonPipeline","./Quaternion","./Rectangle","./VertexFormat","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,g,A,S,w){"use strict";function O(e,t,r,i){for(var a=g.fromAxisAngle(e._plane.normal,r,b),o=v.fromQuaternion(a,D),u=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY,l=Number.POSITIVE_INFINITY,f=Number.NEGATIVE_INFINITY,h=t.length,d=0;d<h;++d){var p=n.clone(t[d],P);v.multiplyByVector(o,p,p);var m=e.projectPointOntoPlane(p,C);s(m)&&(u=Math.min(u,m.x),c=Math.max(c,m.x),l=Math.min(l,m.y),f=Math.max(f,m.y))}return i.x=u,i.y=l,i.width=c-u,i.height=f-l,i}function N(e,t,r,n){var i=n.cartesianToCartographic(e,U),a=i.height,o=n.cartesianToCartographic(t,L);o.height=a,n.cartographicToCartesian(o,t);var u=n.cartesianToCartographic(r,L);u.height=a-100,n.cartographicToCartesian(u,r)}function I(e){var t=e.vertexFormat,i=e.geometry,a=e.shadowVolume;if(t.st||t.normal||t.tangent||t.bitangent||a){var u=e.boundingRectangle,s=e.tangentPlane,c=e.ellipsoid,l=e.stRotation,f=e.wall,h=e.top||f,d=e.bottom||f,m=e.perPositionHeight,y=Y;y.x=u.x,y.y=u.y;var E,T=i.attributes.position.values,R=T.length,A=t.st?new Float32Array(R/3*2):void 0;t.normal&&(E=m&&h&&!f?i.attributes.normal.values:new Float32Array(R));var S=t.tangent?new Float32Array(R):void 0,w=t.bitangent?new Float32Array(R):void 0,O=a?new Float32Array(R):void 0,I=0,x=0,M=z,C=q,P=G,b=!0,D=g.fromAxisAngle(s._plane.normal,l,K),U=v.fromQuaternion(D,J),L=0,F=0;h&&d&&(L=R/2,F=R/3,R/=2);for(var Q=0;Q<R;Q+=3){var $=n.fromArray(T,Q,Z);if(t.st){var ee=v.multiplyByVector(U,$,B);ee=c.scaleToGeodeticSurface(ee,ee);var te=s.projectPointOntoPlane(ee,j);r.subtract(te,y,te);var re=_.clamp(te.x/u.width,0,1),ne=_.clamp(te.y/u.height,0,1);d&&(A[I+F]=re,A[I+1+F]=ne),h&&(A[I]=re,A[I+1]=ne),I+=2}if(t.normal||t.tangent||t.bitangent||a){var ie=x+1,ae=x+2;if(f){if(Q+3<R){var oe=n.fromArray(T,Q+3,V);if(b){var ue=n.fromArray(T,Q+R,W);m&&N($,oe,ue,c),n.subtract(oe,$,oe),n.subtract(ue,$,ue),M=n.normalize(n.cross(ue,oe,M),M),b=!1}n.equalsEpsilon(oe,$,_.EPSILON10)&&(b=!0)}(t.tangent||t.bitangent)&&(P=c.geodeticSurfaceNormal($,P),t.tangent&&(C=n.normalize(n.cross(P,M,C),C)))}else M=c.geodeticSurfaceNormal($,M),(t.tangent||t.bitangent)&&(m&&(H=n.fromArray(E,x,H),X=n.cross(n.UNIT_Z,H,X),X=n.normalize(v.multiplyByVector(U,X,X),X),t.bitangent&&(k=n.normalize(n.cross(H,X,k),k))),C=n.cross(n.UNIT_Z,M,C),C=n.normalize(v.multiplyByVector(U,C,C),C),t.bitangent&&(P=n.normalize(n.cross(M,C,P),P)));t.normal&&(e.wall?(E[x+L]=M.x,E[ie+L]=M.y,E[ae+L]=M.z):d&&(E[x+L]=-M.x,E[ie+L]=-M.y,E[ae+L]=-M.z),(h&&!m||f)&&(E[x]=M.x,E[ie]=M.y,E[ae]=M.z)),a&&(f&&(M=c.geodeticSurfaceNormal($,M)),O[x+L]=-M.x,O[ie+L]=-M.y,O[ae+L]=-M.z),t.tangent&&(e.wall?(S[x+L]=C.x,S[ie+L]=C.y,S[ae+L]=C.z):d&&(S[x+L]=-C.x,S[ie+L]=-C.y,S[ae+L]=-C.z),h&&(m?(S[x]=X.x,S[ie]=X.y,S[ae]=X.z):(S[x]=C.x,S[ie]=C.y,S[ae]=C.z))),t.bitangent&&(d&&(w[x+L]=P.x,w[ie+L]=P.y,w[ae+L]=P.z),h&&(m?(w[x]=k.x,w[ie]=k.y,w[ae]=k.z):(w[x]=P.x,w[ie]=P.y,w[ae]=P.z))),x+=3}}t.st&&(i.attributes.st=new p({componentDatatype:o.FLOAT,componentsPerAttribute:2,values:A})),t.normal&&(i.attributes.normal=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:E})),t.tangent&&(i.attributes.tangent=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:S})),t.bitangent&&(i.attributes.bitangent=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:w})),a&&(i.attributes.extrudeDirection=new p({componentDatatype:o.FLOAT,componentsPerAttribute:3,values:O}))}return i}function x(e,t,r,n,i,a,o,u){var s,c={walls:[]};if(a||o){var l,f,d=T.createGeometryFromPositions(e,t,r,i,u),p=d.attributes.position.values,y=d.indices;if(a&&o){var _=p.concat(p);l=_.length/3,f=E.createTypedArray(l,2*y.length),f.set(y);var v=y.length,g=l/2;for(s=0;s<v;s+=3){var A=f[s]+g,S=f[s+1]+g,O=f[s+2]+g;f[s+v]=O,f[s+1+v]=S,f[s+2+v]=A}if(d.attributes.position.values=_,i){var N=d.attributes.normal.values;d.attributes.normal.values=new Float32Array(_.length),d.attributes.normal.values.set(N)}d.indices=f}else if(o){for(l=p.length/3,f=E.createTypedArray(l,y.length),s=0;s<y.length;s+=3)f[s]=y[s+2],f[s+1]=y[s+1],f[s+2]=y[s];d.indices=f}c.topAndBottom=new m({geometry:d})}var I=n.outerRing,x=h.fromPoints(I,e),M=x.projectPointsOntoPlane(I,Q),C=R.computeWindingOrder2D(M);C===w.CLOCKWISE&&(I=I.slice().reverse());var P=T.computeWallGeometry(I,e,r,i);c.walls.push(new m({geometry:P}));var b=n.holes;for(s=0;s<b.length;s++){var D=b[s];x=h.fromPoints(D,e),M=x.projectPointsOntoPlane(D,Q),C=R.computeWindingOrder2D(M),C===w.COUNTER_CLOCKWISE&&(D=D.slice().reverse()),P=T.computeWallGeometry(D,e,r),c.walls.push(new m({geometry:P}))}return c}function M(e){var t=e.polygonHierarchy,r=u(e.vertexFormat,S.DEFAULT),n=u(e.ellipsoid,f.WGS84),i=u(e.granularity,_.RADIANS_PER_DEGREE),a=u(e.stRotation,0),o=u(e.height,0),c=u(e.perPositionHeight,!1),l=e.extrudedHeight,h=s(l);if(!c&&h)if(_.equalsEpsilon(o,l,_.EPSILON10))l=void 0,h=!1;else{var d=l;l=Math.min(d,o),o=Math.max(d,o)}this._vertexFormat=S.clone(r),this._ellipsoid=f.clone(n),this._granularity=i,this._stRotation=a,this._height=o,this._extrudedHeight=u(l,0),this._extrude=h,this._closeTop=u(e.closeTop,!0),this._closeBottom=u(e.closeBottom,!0),this._polygonHierarchy=t,this._perPositionHeight=c,this._shadowVolume=u(e.shadowVolume,!1),this._workerName="createPolygonGeometry";var p=t.positions;!s(p)||p.length<3?this._rectangle=new A:this._rectangle=A.fromCartesianArray(p,n),this.packedLength=T.computeHierarchyPackedLength(t)+f.packedLength+S.packedLength+A.packedLength+10}var C=new r,P=new n,b=new g,D=new v,U=new i,L=new i,F=new e,B=new n,z=new n,q=new n,G=new n,V=new n,W=new n,H=new n,X=new n,k=new n,Y=new r,j=new r,Z=new n,K=new g,J=new v,Q=[];M.fromPositions=function(e){return e=u(e,u.EMPTY_OBJECT),new M({polygonHierarchy:{positions:e.positions},height:e.height,extrudedHeight:e.extrudedHeight,vertexFormat:e.vertexFormat,stRotation:e.stRotation,ellipsoid:e.ellipsoid,granularity:e.granularity,perPositionHeight:e.perPositionHeight,closeTop:e.closeTop,closeBottom:e.closeBottom})},M.pack=function(e,t,r){return r=u(r,0),r=T.packPolygonHierarchy(e._polygonHierarchy,t,r),f.pack(e._ellipsoid,t,r),r+=f.packedLength,S.pack(e._vertexFormat,t,r),r+=S.packedLength,A.pack(e._rectangle,t,r),r+=A.packedLength,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._granularity,t[r++]=e._stRotation,t[r++]=e._extrude?1:0,t[r++]=e._perPositionHeight?1:0,t[r++]=e._closeTop?1:0,t[r++]=e._closeBottom?1:0,t[r++]=e._shadowVolume?1:0,t[r]=e.packedLength,t};var $=f.clone(f.UNIT_SPHERE),ee=new S,te=new A,re={polygonHierarchy:{}};return M.unpack=function(e,t,r){t=u(t,0);var n=T.unpackPolygonHierarchy(e,t);t=n.startingIndex,delete n.startingIndex;var i=f.unpack(e,t,$);t+=f.packedLength;var a=S.unpack(e,t,ee);t+=S.packedLength;var o=A.unpack(e,t,te);t+=A.packedLength;var c=e[t++],l=e[t++],h=e[t++],d=e[t++],p=1===e[t++],m=1===e[t++],y=1===e[t++],E=1===e[t++],_=1===e[t++],v=e[t];return s(r)||(r=new M(re)),r._polygonHierarchy=n,r._ellipsoid=f.clone(i,r._ellipsoid),r._vertexFormat=S.clone(a,r._vertexFormat),r._height=c,r._extrudedHeight=l,r._granularity=h,r._stRotation=d,r._extrude=p,r._perPositionHeight=m,r._closeTop=y,r._closeBottom=E,r._rectangle=A.clone(o),r._shadowVolume=_,r.packedLength=v,r},M.createGeometry=function(e){var r=e._vertexFormat,n=e._ellipsoid,i=e._granularity,a=e._stRotation,o=e._height,u=e._extrudedHeight,s=e._extrude,c=e._polygonHierarchy,l=e._perPositionHeight,f=e._closeTop,p=e._closeBottom,_=c.positions;if(!(_.length<3)){var v=h.fromPoints(_,n),g=T.polygonsFromHierarchy(c,l,v,n),A=g.hierarchy,S=g.polygons;if(0!==A.length){_=A[0].outerRing;var w,N,M=O(v,_,a,F),C=[],P={perPositionHeight:l,vertexFormat:r,geometry:void 0,tangentPlane:v,boundingRectangle:M,ellipsoid:n,stRotation:a,bottom:!1,top:!0,wall:!1};if(s)for(P.top=f,P.bottom=p,P.shadowVolume=e._shadowVolume,N=0;N<S.length;N++){w=x(n,S[N],i,A[N],l,f,p,r);var b;f&&p?(b=w.topAndBottom,P.geometry=T.scaleToGeodeticHeightExtruded(b.geometry,o,u,n,l)):f?(b=w.topAndBottom,b.geometry.attributes.position.values=R.scaleToGeodeticHeight(b.geometry.attributes.position.values,o,n,!l),P.geometry=b.geometry):p&&(b=w.topAndBottom,b.geometry.attributes.position.values=R.scaleToGeodeticHeight(b.geometry.attributes.position.values,u,n,!0),P.geometry=b.geometry),(f||p)&&(P.wall=!1,b.geometry=I(P),C.push(b));var D=w.walls;P.wall=!0;for(var U=0;U<D.length;U++){var L=D[U];P.geometry=T.scaleToGeodeticHeightExtruded(L.geometry,o,u,n,l),L.geometry=I(P),C.push(L)}}else for(N=0;N<S.length;N++)w=new m({geometry:T.createGeometryFromPositions(n,S[N],i,l,r)}),w.geometry.attributes.position.values=R.scaleToGeodeticHeight(w.geometry.attributes.position.values,o,n,!l),P.geometry=w.geometry,w.geometry=I(P),C.push(w);w=y.combineInstances(C)[0],w.attributes.position.values=new Float64Array(w.attributes.position.values),w.indices=E.createTypedArray(w.attributes.position.values.length/3,w.indices);var B=w.attributes,z=t.fromVertices(B.position.values);return r.position||delete B.position,new d({attributes:B,indices:w.indices,primitiveType:w.primitiveType,boundingSphere:z})}}},M.createShadowVolume=function(e,t,r){var n=e._granularity,i=e._ellipsoid,a=t(n,i),o=r(n,i);return new M({polygonHierarchy:e._polygonHierarchy,ellipsoid:i,stRotation:e._stRotation,granularity:n,perPositionHeight:!1,extrudedHeight:a,height:o,vertexFormat:S.POSITION_ONLY,shadowVolume:!0})},c(M.prototype,{rectangle:{get:function(){return this._rectangle}}}),M}),define("Workers/createPolygonGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolygonGeometry"],function(e,t,r){"use strict";function n(n,i){return e(i)&&(n=r.unpack(n,i)),n._ellipsoid=t.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonOutlineGeometry.js index 6ee76e20..31b3bfc1 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolygonOutlineGeometry.js @@ -222,10 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(n,i){if(!e(i))throw new t(r(n))},i.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},i.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},i.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},i.typeOf.number.lessThan=function(e,r,n){if(i.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},i.typeOf.number.lessThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},i.typeOf.number.greaterThan=function(e,r,n){if(i.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},i.typeOf.number.greaterThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},i.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},i.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},i.typeOf.number.equals=function(e,r,n,a){if(i.typeOf.number(e,n),i.typeOf.number(r,a),n!==a)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*i.clamp(e,-1,1)+.5)*r)},i.fromSNorm=function(e,r){return r=t(r,255),i.clamp(e,0,r)/r*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,r){return(1-r)*e+r*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,r,n,i){i=t(i,n);var a=Math.abs(e-r);return a<=i||a<=n*Math.max(Math.abs(e),Math.abs(r))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var r=a[t-1],n=t;n<=e;n++)a.push(r*n);return a[e]},i.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return n.x=s*Math.cos(i),n.y=s*Math.sin(i),n.z=u*Math.cos(a),n},o.fromElements=function(e,t,n,i){return r(i)?(i.x=e,i.y=t,i.z=n,i):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var i=0;i<n;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var i=0;i<n;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)},o.cross=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-n*s,f=n*u-i*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,r,n,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,i,a,u){i=t(i,0);var s=r(a)?a.radiiSquared:p,c=Math.cos(n);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(n),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),r(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function i(r,i,u,s,c){var l=r.x,f=r.y,h=r.z,d=i.x,p=i.y,E=i.z,m=l*l*d*d,y=f*f*p*p,_=h*h*E*E,v=m+y+_,T=Math.sqrt(1/v),R=e.multiplyByScalar(r,T,a);if(v<s)return isFinite(T)?e.clone(R,c):void 0;var A=u.x,S=u.y,g=u.z,N=o;N.x=R.x*A*2,N.y=R.y*S*2,N.z=R.z*g*2;var O,I,x,w,M,C,P,D,L,U,b,F=(1-T)*e.magnitude(r)/(.5*e.magnitude(N)),B=0;do{F-=B,x=1/(1+F*A),w=1/(1+F*S),M=1/(1+F*g),C=x*x,P=w*w,D=M*M,L=C*x,U=P*w,b=D*M,O=m*C+y*P+_*D-1,I=m*L*A+y*U*S+_*b*g;B=O/(-2*I)}while(Math.abs(O)>n.EPSILON12);return t(c)?(c.x=l*x,c.y=f*w,c.z=h*M,c):new e(l*x,f*w,h*M)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,i,a){return i=r(i,0),n(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,r,n){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,r,i){var p=n(r)?r.oneOverRadii:f,E=n(r)?r.oneOverRadiiSquared:h,m=n(r)?r._centerToleranceSquared:d,y=o(t,p,E,m,c);if(n(y)){var _=e.multiplyComponents(y,E,s);_=e.normalize(_,_);var v=e.subtract(t,y,l),T=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=a.sign(e.dot(v,t))*e.magnitude(v);return n(i)?(i.longitude=T,i.latitude=R,i.height=A,i):new u(T,R,A)}},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t,r,i,a){r=n(r,0),i=n(i,0),a=n(a,0),t._radii=new e(r,i,a),t._radiiSquared=new e(r*r,i*i,a*a),t._radiiToTheFourth=new e(r*r*r*r,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===r?0:1/r,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(r,i,a),t._maximumRadius=Math.max(r,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(i(t)){var n=t._radii;return i(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,i){return i=n(i,0),e.pack(t._radii,r,i),r},f.unpack=function(t,r,i){r=n(r,0);var a=e.unpack(t,r);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(a);return i(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return i(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,r){var n=h,a=d;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,a);var o=Math.sqrt(e.dot(n,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(n,t.height,n),i(r)||(r=new e),e.add(a,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var p=new e,E=new e,m=new e;return f.prototype.cartesianToCartographic=function(r,n){var a=this.scaleToGeodeticSurface(r,E);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(r,a,m),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return i(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){i(r)||(r=new e);var n=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,a){r=n(r,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-r))return a},f}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,r,n){"use strict";function i(e,n,i){if(r(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!n(s,c,a));++u);if(u===o)return i&&n(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],n(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&n(l[0],l[l.length-1],a)&&l.shift(),l}}var a=n.EPSILON10;return i}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,i,a,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return n(r)?(r.x=a,r.y=o,r.z=u,r):new e(a,o,u)},u.prototype.unproject=function(e,r){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return n(r)?(r.longitude=a,r.latitude=o,r.height=u,r):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i,a,o,u,s,c){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(a,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(E[r],p[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(E[a],p[a])]);o>n&&(i=a,n=o)}var c=1,l=0,f=p[i],h=E[i];if(Math.abs(e[s.getElementIndex(h,f)])>r){var d,m=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],v=(m-y)/2/_;d=v<0?-1/(-v+Math.sqrt(1+v*v)):1/(v+Math.sqrt(1+v*v)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=r-u-f+d,E=2*(i-h),m=2*(a+l),y=2*(i+h),_=-r+u-f+d,v=2*(c-o),T=2*(a-l),R=2*(c+o),A=-r-u+f+d;return n(t)?(t[0]=p,t[1]=y,t[2]=T,t[3]=E,t[4]=_,t[5]=R,t[6]=m,t[7]=v,t[8]=A,t):new s(p,E,m,y,_,v,T,R,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=r*u,p=a*i+c*o*u,E=-c*i+a*o*u,m=-o,y=c*r,_=a*r;return n(t)?(t[0]=l,t[1]=d,t[2]=m,t[3]=f,t[4]=p,t[5]=y,t[6]=h,t[7]=E,t[8]=_,t):new s(l,f,h,d,p,E,m,y,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=i,t[6]=0,t[7]=-i,t[8]=r,t):new s(1,0,0,0,r,-i,0,i,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=r,t):new s(r,0,i,0,1,0,-i,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=i,t[2]=0,t[3]=-i,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-i,0,i,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,i=e[n],a=e[n+1],o=e[n+2];return r.x=i,r.y=a,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var i=3*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],i=e[t+3],a=e[t+6];return r.x=n,r.y=i,r.z=a,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var h=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=i,r[2]=a,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[3]*i+e[6]*a,u=e[1]*n+e[4]*i+e[7]*a,s=e[2]*n+e[5]*i+e[8]*a;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],E=[2,2,1],m=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,i=0,a=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=r*c(h);a<10&&l(h)>d;)f(h,m),s.transpose(m,y),s.multiply(h,m,h),s.multiply(y,h,h),s.multiply(o,m,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*n-r*c)+u*(r*o-a*n)},s.inverse=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-n*f,t[2]=n*u-o*i,t[3]=c*u-a*f,t[4]=r*f-c*i,t[5]=a*i-r*u,t[6]=a*l-c*o,t[7]=c*n-r*l,t[8]=r*o-a*n;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n,i){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(i,0)}o.fromElements=function(e,t,n,i,a){return r(a)?(a.x=e,a.y=t,a.z=n,a.w=i,a):new o(e,t,n,i)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n++],i.w=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var i=0;i<n;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var i=0;i<n;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)&&a.equalsEpsilon(e.w,t.w,n,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){ -return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t,r,i,a,o,u,s,c,l,f,h,d,p,E,m){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(c,0),this[3]=n(d,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(p,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(E,0),this[12]=n(i,0),this[13]=n(s,0),this[14]=n(h,0),this[15]=n(m,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,a){return r=n(r,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=r.x,a[13]=r.y,a[14]=r.z,a[15]=1,a):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){i(n)||(n=new l);var a=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,E=t.y*t.w,m=t.z*t.z,y=t.z*t.w,_=t.w*t.w,v=s-d-m+_,T=2*(c-y),R=2*(f+E),A=2*(c+y),S=-s+d-m+_,g=2*(p-h),N=2*(f-E),O=2*(p+h),I=-s-d+m+_;return n[0]=v*a,n[1]=A*a,n[2]=N*a,n[3]=0,n[4]=T*o,n[5]=S*o,n[6]=O*o,n[7]=0,n[8]=R*u,n[9]=g*u,n[10]=I*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,r){var n=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,E=f.y,m=f.z,y=d.x,_=d.y,v=d.z,T=n.x,R=n.y,A=n.z,S=u*-T+s*-R+c*-A,g=y*-T+_*-R+v*-A,N=p*T+E*R+m*A;return i(r)?(r[0]=u,r[1]=y,r[2]=-p,r[3]=0,r[4]=s,r[5]=_,r[6]=-E,r[7]=0,r[8]=c,r[9]=v,r[10]=-m,r[11]=0,r[12]=S,r[13]=g,r[14]=N,r[15]=1,r):new l(u,s,c,S,y,_,v,g,-p,-E,-m,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,r,n,i,a,o){var u=1/(t-e),s=1/(n-r),c=1/(a-i),l=-(t+e)*u,f=-(n+r)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,i,a,o){var u=2*i/(t-e),s=2*i/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,i,a){var o=2*i/(t-e),u=2*i/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,r,i){e=n(e,n.EMPTY_OBJECT);var a=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),h=c,d=l,p=f,E=a+c,m=o+l,y=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=E,i[13]=m,i[14]=y,i[15]=1,i},l.computeView=function(t,r,n,i,a){return a[0]=i.x,a[1]=n.x,a[2]=-r.x,a[3]=0,a[4]=i.y,a[5]=n.y,a[6]=-r.y,a[7]=0,a[8]=i.z,a[9]=n.z,a[10]=-r.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(n,t),a[14]=e.dot(r,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3];return r.x=i,r.y=a,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var i=4*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n[i+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return r.x=n,r.y=i,r.z=a,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var p=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),r};var E=new e;l.getMaximumScale=function(t){return l.getScale(t,E),e.maximumComponent(E)},l.multiply=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],E=e[12],m=e[13],y=e[14],_=e[15],v=t[0],T=t[1],R=t[2],A=t[3],S=t[4],g=t[5],N=t[6],O=t[7],I=t[8],x=t[9],w=t[10],M=t[11],C=t[12],P=t[13],D=t[14],L=t[15],U=n*v+u*T+f*R+E*A,b=i*v+s*T+h*R+m*A,F=a*v+c*T+d*R+y*A,B=o*v+l*T+p*R+_*A,z=n*S+u*g+f*N+E*O,q=i*S+s*g+h*N+m*O,G=a*S+c*g+d*N+y*O,W=o*S+l*g+p*N+_*O,V=n*I+u*x+f*w+E*M,X=i*I+s*x+h*w+m*M,H=a*I+c*x+d*w+y*M,Y=o*I+l*x+p*w+_*M,k=n*C+u*P+f*D+E*L,Z=i*C+s*P+h*D+m*L,j=a*C+c*P+d*D+y*L,K=o*C+l*P+p*D+_*L;return r[0]=U,r[1]=b,r[2]=F,r[3]=B,r[4]=z,r[5]=q,r[6]=G,r[7]=W,r[8]=V,r[9]=X,r[10]=H,r[11]=Y,r[12]=k,r[13]=Z,r[14]=j,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],E=t[0],m=t[1],y=t[2],_=t[4],v=t[5],T=t[6],R=t[8],A=t[9],S=t[10],g=t[12],N=t[13],O=t[14],I=n*E+o*m+c*y,x=i*E+u*m+l*y,w=a*E+s*m+f*y,M=n*_+o*v+c*T,C=i*_+u*v+l*T,P=a*_+s*v+f*T,D=n*R+o*A+c*S,L=i*R+u*A+l*S,U=a*R+s*A+f*S,b=n*g+o*N+c*O+h,F=i*g+u*N+l*O+d,B=a*g+s*N+f*O+p;return r[0]=I,r[1]=x,r[2]=w,r[3]=0,r[4]=M,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=L,r[10]=U,r[11]=0,r[12]=b,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],E=t[3],m=t[4],y=t[5],_=t[6],v=t[7],T=t[8],R=n*h+o*d+c*p,A=i*h+u*d+l*p,S=a*h+s*d+f*p,g=n*E+o*m+c*y,N=i*E+u*m+l*y,O=a*E+s*m+f*y,I=n*_+o*v+c*T,x=i*_+u*v+l*T,w=a*_+s*v+f*T;return r[0]=R,r[1]=A,r[2]=S,r[3]=0,r[4]=g,r[5]=N,r[6]=O,r[7]=0,r[8]=I,r[9]=x,r[10]=w,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=n*e[0]+i*e[4]+a*e[8]+e[12],u=n*e[1]+i*e[5]+a*e[9]+e[13],s=n*e[2]+i*e[6]+a*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var m=new e;l.multiplyByUniformScale=function(e,t,r){return m.x=t,m.y=t,m.z=t,l.multiplyByScale(e,m,r)},l.multiplyByScale=function(e,t,r){var n=t.x,i=t.y,a=t.z;return 1===n&&1===i&&1===a?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=i*e[4],r[5]=i*e[5],r[6]=i*e[6],r[7]=0,r[8]=a*e[8],r[9]=a*e[9],r[10]=a*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*n+e[4]*i+e[8]*a+e[12]*o,s=e[1]*n+e[5]*i+e[9]*a+e[13]*o,c=e[2]*n+e[6]*i+e[10]*a+e[14]*o,l=e[3]*n+e[7]*i+e[11]*a+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a,u=e[1]*n+e[5]*i+e[9]*a,s=e[2]*n+e[6]*i+e[10]*a;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a+e[12],u=e[1]*n+e[5]*i+e[9]*a+e[13],s=e[2]*n+e[6]*i+e[10]*a+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,v=new t,T=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,v),T))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],E=e[2],m=e[6],R=e[10],A=e[14],S=e[3],g=e[7],N=e[11],O=e[15],I=R*O,x=A*N,w=m*O,M=A*g,C=m*N,P=R*g,D=E*O,L=A*S,U=E*N,b=R*S,F=E*g,B=m*S,z=I*h+M*d+C*p-(x*h+w*d+P*p),q=x*f+D*d+b*p-(I*f+L*d+U*p),G=w*f+L*h+F*p-(M*f+D*h+B*p),W=P*f+U*h+B*d-(C*f+b*h+F*d),V=x*i+w*a+P*o-(I*i+M*a+C*o),X=I*n+L*a+U*o-(x*n+D*a+b*o),H=M*n+D*i+B*o-(w*n+L*i+F*o),Y=C*n+b*i+F*a-(P*n+U*i+B*a);I=a*p,x=o*d,w=i*p,M=o*h,C=i*d,P=a*h,D=n*p,L=o*f,U=n*d,b=a*f,F=n*h,B=i*f;var k=I*g+M*N+C*O-(x*g+w*N+P*O),Z=x*S+D*N+b*O-(I*S+L*N+U*O),j=w*S+L*g+F*O-(M*S+D*g+B*O),K=P*S+U*g+B*N-(C*S+b*g+F*N),J=w*R+P*A+x*m-(C*A+I*m+M*R),Q=U*A+I*E+L*R-(D*R+b*A+x*E),$=D*m+B*A+M*E-(F*A+w*E+L*m),ee=F*R+C*E+b*m-(U*m+B*R+P*E),te=n*z+i*q+a*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=q*te,r[2]=G*te,r[3]=W*te,r[4]=V*te,r[5]=X*te,r[6]=H*te,r[7]=Y*te,r[8]=k*te,r[9]=Z*te,r[10]=j*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-r*f-n*h-i*d,E=-a*f-o*h-u*d,m=-s*f-c*h-l*d;return t[0]=r,t[1]=a,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=E,t[14]=m,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),i=u.toRadians(r(i,0)),a=u.toRadians(r(a,0)),n(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(i,0),o.north=r(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];r=Math.min(r,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-r>o-a&&(r=a,i=o,i>u.PI&&(i-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=i,t.north=l,t):new s(r,c,i,l)},s.fromCartesianArray=function(e,t,i){t=r(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,E=e.length;p<E;p++){var m=t.cartesianToCartographic(e[p]);o=Math.min(o,m.longitude),c=Math.max(c,m.longitude),h=Math.min(h,m.latitude),d=Math.max(d,m.latitude);var y=m.longitude>=0?m.longitude:m.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return n(r)?(r.west=l,r.south=h,r.east=f,r.north=d,r):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,r){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return n(r)?(r.west=i,r.south=a,r.east=o,r.north=u,r):new s(i,a,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>i||u.equalsEpsilon(r,i,u.EPSILON14))&&(r<a||u.equalsEpsilon(r,a,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=r(t,a.WGS84),i=r(i,0),n(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,E=c;E.height=i,E.longitude=p,E.latitude=f,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=h,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=p,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=f<0?f:h>0?h:0;for(var m=1;m<8;++m)E.longitude=-Math.PI+m*u.PI_OVER_TWO,s.contains(e,E)&&(o[l]=t.cartographicToCartesian(E,o[l]),l++);return 0===E.latitude&&(E.longitude=p,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var d=new e,p=new e,E=new e,m=new e,y=new e,_=new e,v=new e,T=new e,R=new e,A=new e,S=new e,g=new e;h.fromPoints=function(t,r){if(i(r)||(r=new h),!i(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,a=e.clone(t[0],v),o=e.clone(a,d),u=e.clone(a,p),s=e.clone(a,E),c=e.clone(a,m),l=e.clone(a,y),f=e.clone(a,_),N=t.length;for(n=1;n<N;n++){e.clone(t[n],a);var O=a.x,I=a.y,x=a.z;O<o.x&&e.clone(a,o),O>c.x&&e.clone(a,c),I<u.y&&e.clone(a,u),I>l.y&&e.clone(a,l),x<s.z&&e.clone(a,s),x>f.z&&e.clone(a,f)}var w=e.magnitudeSquared(e.subtract(c,o,T)),M=e.magnitudeSquared(e.subtract(l,u,T)),C=e.magnitudeSquared(e.subtract(f,s,T)),P=o,D=c,L=w;M>L&&(L=M,P=u,D=l),C>L&&(L=C,P=s,D=f);var U=R;U.x=.5*(P.x+D.x),U.y=.5*(P.y+D.y),U.z=.5*(P.z+D.z);var b=e.magnitudeSquared(e.subtract(D,U,T)),F=Math.sqrt(b),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,T),.5,g),G=0;for(n=0;n<N;n++){e.clone(t[n],a);var W=e.magnitude(e.subtract(a,q,T));W>G&&(G=W);var V=e.magnitudeSquared(e.subtract(a,U,T));if(V>b){var X=Math.sqrt(V);F=.5*(F+X),b=F*F;var H=X-F;U.x=(F*U.x+H*a.x)/X,U.y=(F*U.y+H*a.y)/X,U.z=(F*U.z+H*a.z)/X}}return F<G?(e.clone(U,r.center),r.radius=F):(e.clone(q,r.center),r.radius=G),r};var N=new o,O=new e,I=new e,x=new t,w=new t;h.fromRectangle2D=function(e,t,r){return h.fromRectangleWithHeights2D(e,t,0,0,r)},h.fromRectangleWithHeights2D=function(t,r,a,o,u){if(i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=n(r,N),f.southwest(t,x),x.height=a,f.northeast(t,w),w.height=o;var s=r.project(x,O),c=r.project(w,I),l=c.x-s.x,d=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+p*p);var E=u.center;return E.x=s.x+.5*l,E.y=s.y+.5*d,E.z=s.z+.5*p,u};var M=[];h.fromRectangle3D=function(t,r,o,u){if(r=n(r,a.WGS84),o=n(o,0),i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,r,o,M);return h.fromPoints(s,u)},h.fromVertices=function(t,r,a,o){if(i(o)||(o=new h),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=n(r,e.ZERO),a=n(a,3);var u=v;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,d),l=e.clone(u,p),f=e.clone(u,E),N=e.clone(u,m),O=e.clone(u,y),I=e.clone(u,_),x=t.length;for(s=0;s<x;s+=a){var w=t[s]+r.x,M=t[s+1]+r.y,C=t[s+2]+r.z;u.x=w,u.y=M,u.z=C,w<c.x&&e.clone(u,c),w>N.x&&e.clone(u,N),M<l.y&&e.clone(u,l),M>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(N,c,T)),D=e.magnitudeSquared(e.subtract(O,l,T)),L=e.magnitudeSquared(e.subtract(I,f,T)),U=c,b=N,F=P;D>F&&(F=D,U=l,b=O),L>F&&(F=L,U=f,b=I);var B=R;B.x=.5*(U.x+b.x),B.y=.5*(U.y+b.y),B.z=.5*(U.z+b.z);var z=e.magnitudeSquared(e.subtract(b,B,T)),q=Math.sqrt(z),G=A;G.x=c.x,G.y=l.y,G.z=f.z;var W=S;W.x=N.x,W.y=O.y,W.z=I.z;var V=e.multiplyByScalar(e.add(G,W,T),.5,g),X=0;for(s=0;s<x;s+=a){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,V,T));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,B,T));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;B.x=(q*B.x+Z*u.x)/k,B.y=(q*B.y+Z*u.y)/k,B.z=(q*B.z+Z*u.z)/k}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(V,o.center),o.radius=X),o},h.fromEncodedCartesianVertices=function(t,r,n){if(i(n)||(n=new h),!i(t)||!i(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var a=v;a.x=t[0]+r[0],a.y=t[1]+r[1],a.z=t[2]+r[2];var o,u=e.clone(a,d),s=e.clone(a,p),c=e.clone(a,E),l=e.clone(a,m),f=e.clone(a,y),N=e.clone(a,_),O=t.length;for(o=0;o<O;o+=3){var I=t[o]+r[o],x=t[o+1]+r[o+1],w=t[o+2]+r[o+2];a.x=I,a.y=x,a.z=w,I<u.x&&e.clone(a,u),I>l.x&&e.clone(a,l),x<s.y&&e.clone(a,s),x>f.y&&e.clone(a,f),w<c.z&&e.clone(a,c),w>N.z&&e.clone(a,N)}var M=e.magnitudeSquared(e.subtract(l,u,T)),C=e.magnitudeSquared(e.subtract(f,s,T)),P=e.magnitudeSquared(e.subtract(N,c,T)),D=u,L=l,U=M;C>U&&(U=C,D=s,L=f),P>U&&(U=P,D=c,L=N);var b=R;b.x=.5*(D.x+L.x),b.y=.5*(D.y+L.y),b.z=.5*(D.z+L.z);var F=e.magnitudeSquared(e.subtract(L,b,T)),B=Math.sqrt(F),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var q=S;q.x=l.x,q.y=f.y,q.z=N.z;var G=e.multiplyByScalar(e.add(z,q,T),.5,g),W=0;for(o=0;o<O;o+=3){a.x=t[o]+r[o],a.y=t[o+1]+r[o+1],a.z=t[o+2]+r[o+2];var V=e.magnitude(e.subtract(a,G,T));V>W&&(W=V);var X=e.magnitudeSquared(e.subtract(a,b,T));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var Y=H-B;b.x=(B*b.x+Y*a.x)/H,b.y=(B*b.y+Y*a.y)/H,b.z=(B*b.z+Y*a.z)/H}}return B<W?(e.clone(b,n.center),n.radius=B):(e.clone(G,n.center),n.radius=W),n},h.fromCornerPoints=function(t,r,n){i(n)||(n=new h);var a=n.center;return e.add(t,r,a),e.multiplyByScalar(a,.5,a),n.radius=e.distance(a,r),n},h.fromEllipsoid=function(t,r){return i(r)||(r=new h),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var C=new e;h.fromBoundingSpheres=function(t,r){if(i(r)||(r=new h),!i(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return h.clone(t[0],r);if(2===n)return h.union(t[0],t[1],r);var a,o=[];for(a=0;a<n;a++)o.push(t[a].center);r=h.fromPoints(o,r);var u=r.center,s=r.radius;for(a=0;a<n;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return r.radius=s,r};var P=new e,D=new e,L=new e;h.fromOrientedBoundingBox=function(t,r){i(r)||(r=new h);var n=t.halfAxes,a=c.getColumn(n,0,P),o=c.getColumn(n,1,D),u=c.getColumn(n,2,L);return e.add(a,o,a),e.add(a,u,a),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(a),r},h.clone=function(t,r){if(i(t))return i(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,r){r=n(r,0);var i=e.center;return t[r++]=i.x,t[r++]=i.y,t[r++]=i.z,t[r]=e.radius,t},h.unpack=function(e,t,r){t=n(t,0),i(r)||(r=new h);var a=r.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],r.radius=e[t],r};var U=new e,b=new e;h.union=function(t,r,n){i(n)||(n=new h);var a=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,a,U),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(d,a,d),e.clone(d,n.center),n.radius=f,n};var F=new e;h.expand=function(t,r,n){n=h.clone(t,n);var i=e.magnitude(e.subtract(r,n.center,F));return i>n.radius&&(n.radius=i),n},h.intersectPlane=function(t,r){var n=t.center,i=t.radius,a=r.normal,o=e.dot(a,n)+r.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,r){return i(r)||(r=new h),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=l.getMaximumScale(t)*e.radius,r};var B=new e;h.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,B);return e.magnitudeSquared(n)-t.radius*t.radius},h.transformWithoutScale=function(e,t,r){return i(r)||(r=new h),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var z=new e;h.computePlaneDistances=function(t,r,n,a){i(a)||(a=new s);var o=e.subtract(t.center,r,z),u=e.dot(n,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var q=new e,G=new e,W=new e,V=new e,X=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,r,i){r=n(r,Z);var a=r.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,X),d=e.negate(c,V),p=Y,E=p[0];e.add(s,l,E),e.add(E,c,E),E=p[1],e.add(s,l,E),e.add(E,d,E),E=p[2],e.add(s,f,E),e.add(E,d,E),E=p[3],e.add(s,f,E),e.add(E,c,E),e.negate(s,s),E=p[4],e.add(s,l,E),e.add(E,c,E),E=p[5],e.add(s,l,E),e.add(E,d,E),E=p[6],e.add(s,f,E),e.add(E,d,E),E=p[7],e.add(s,f,E),e.add(E,c,E);for(var m=p.length,y=0;y<m;++y){var _=p[y];e.add(o,_,_);var v=a.cartesianToCartographic(_,H);r.project(v,_)}i=h.fromPoints(p,i),o=i.center;var T=o.x,R=o.y,A=o.z;return o.x=A,o.y=T,o.z=R,i},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,r){return t===r||i(t)&&i(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,r){return h.computePlaneDistances(this,e,t,r)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(n.requestFullscreen=i,r=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(n.requestFullscreen=i,r=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?n.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(n.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?n.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(n.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?n.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(n.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),n.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),n.fullscreenerror=i)}return r},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[n.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(R=!0,A=n(e[1]))}return R}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(T.userAgent))){ -var e=/ Version\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(S=!0,g=n(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(T.userAgent);null!==e&&(N=!0,O=n(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===T.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(I=!0,x=n(e[1])):"Netscape"===T.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(I=!0,x=n(e[1]))}return I}function f(){return l()&&x}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(w=!0,M=n(e[1]))}return w}function d(){return h()&&M}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function E(){return t(D)||(D=/Windows/i.test(T.appVersion)),D}function m(){return p()&&P}function y(){return t(L)||(L="undefined"!=typeof PointerEvent&&(!t(T.pointerEnabled)||T.pointerEnabled)),L}function _(){if(!t(b)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;b=t(r)&&""!==r,b&&(U=r)}return b}function v(){return _()?U:void 0}var T;T="undefined"!=typeof navigator?navigator:{};var R,A,S,g,N,O,I,x,w,M,C,P,D,L,U,b,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:m,isWindows:E,hardwareConcurrency:e(T.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:v};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,i,a){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,i){switch(n=e(n,0),i=e(i,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,i);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,i);case o.SHORT:return new Int16Array(r,n,i);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,i);case o.INT:return new Int32Array(r,n,i);case o.UNSIGNED_INT:return new Uint32Array(r,n,i);case o.FLOAT:return new Float32Array(r,n,i);case o.DOUBLE:return new Float64Array(r,n,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,r,n,i){"use strict";function a(t,i,a){this.minimum=e.clone(r(t,e.ZERO)),this.maximum=e.clone(r(i,e.ZERO)),n(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,r){if(n(r)||(r=new a),!n(t)||0===t.length)return r.minimum=e.clone(e.ZERO,r.minimum),r.maximum=e.clone(e.ZERO,r.maximum),r.center=e.clone(e.ZERO,r.center),r;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],p=d.x,E=d.y,m=d.z;i=Math.min(p,i),s=Math.max(p,s),o=Math.min(E,o),c=Math.max(E,c),u=Math.min(m,u),l=Math.max(m,l)}var y=r.minimum;y.x=i,y.y=o,y.z=u;var _=r.maximum;_.x=s,_.y=c,_.z=l;var v=e.add(y,_,r.center);return e.multiplyByScalar(v,.5,v),r},a.clone=function(t,r){if(n(t))return n(r)?(r.minimum=e.clone(t.minimum,r.minimum),r.maximum=e.clone(t.maximum,r.maximum),r.center=e.clone(t.center,r.center),r):new a(t.minimum,t.maximum)},a.equals=function(t,r){return t===r||n(t)&&n(r)&&e.equals(t.center,r.center)&&e.equals(t.minimum,r.minimum)&&e.equals(t.maximum,r.maximum)};var o=new e;return a.intersectPlane=function(t,r){o=e.subtract(t.maximum,t.minimum,o);var n=e.multiplyByScalar(o,.5,o),a=r.normal,u=n.x*Math.abs(a.x)+n.y*Math.abs(a.y)+n.z*Math.abs(a.z),s=e.dot(t.center,a)+r.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var i=0;i<n;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var i=0;i<n;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var i=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(r)))<n?0:i}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,i){var a;if(0===e)return 0===n?[]:[-i/n];if(0===n){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-n/e,a<0?[a,0]:[0,a];var c=n*n,l=4*e*i,f=r(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[h/e,i/h]:[i/h,h/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var i,a,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,E=o*c-u*s,m=u*c-d,y=4*p*m-E*E;if(y<0){var _,v,T;h*f>=l*d?(_=o,v=p,T=-2*u*p+o*E):(_=c,v=m,T=-c*E+2*s*m);var R=T<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-y);a=-T+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),N=a===A?-g:-v/g;return i=v<=0?g+N:-T/(g*g+N*N+v),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var O=p,I=-2*u*p+o*E,x=m,w=-c*E+2*s*m,M=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*M,-I)/3);i=2*Math.sqrt(-O);var D=Math.cos(P);a=i*D;var L=i*(-D/2-C*Math.sin(P)),U=a+L>2*u?a-u:L-u,b=o,F=U/b;P=Math.abs(Math.atan2(c*M,-w)/3),i=2*Math.sqrt(-x),D=Math.cos(P),a=i*D,L=i*(-D/2-C*Math.sin(P));var B=-c,z=a+L<2*s?a+s:L+s,q=B/z,G=b*z,W=-U*z-b*B,V=U*B,X=(s*W-u*V)/(-u*W+s*G);return F<=X?F<=q?X<=q?[F,X,q]:[F,q,X]:[q,F,X]:F<=q?[X,F,q]:X<=q?[X,q,F]:[q,X,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var i=e*e,a=t*t,o=r*r;return 18*e*t*r*n+a*o-27*i*(n*n)-4*(e*o*r+a*t*n)},n.computeRealRoots=function(e,n,i,a){var o,u;if(0===e)return t.computeRealRoots(n,i,a);if(0===n){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,i,a)}return 0===i?0===a?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,a):0===a?(o=t.computeRealRoots(e,n,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,i,a)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<r.EPSILON14){var p=n.computeRealRoots(1,s,l);if(2===p.length){var E,m=p[0],y=p[1];if(m>=0&&y>=0){var _=Math.sqrt(m),v=Math.sqrt(y);return[h-v,h-_,h+_,h+v]}if(m>=0&&y<0)return E=Math.sqrt(m),[h-E,h+E];if(m<0&&y>=0)return E=Math.sqrt(y),[h-E,h+E]}return[]}if(d>0){var T=Math.sqrt(d),R=(s+d-c/T)/2,A=(s+d+c/T)/2,S=n.computeRealRoots(1,T,R),g=n.computeRealRoots(1,-T,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,E,m=d[0],y=i-m,_=y*y,v=t/2,T=y/2,R=_-4*o,A=_+4*Math.abs(o),S=c-4*m,g=c+4*Math.abs(m);if(m<0||R*g<S*A){var N=Math.sqrt(S);p=N/2,E=0===N?0:(t*T-a)/N}else{var O=Math.sqrt(R);p=0===O?0:(t*T-a)/O,E=O/2}var I,x;0===v&&0===p?(I=0,x=0):r.sign(v)===r.sign(p)?(I=v+p,x=m/I):(x=v-p,I=m/x);var w,M;0===T&&0===E?(w=0,M=0):r.sign(T)===r.sign(E)?(w=T+E,M=o/w):(M=T-E,w=o/M);var C=n.computeRealRoots(1,I,w),P=n.computeRealRoots(1,x,M);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,h=f*n,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*r*h-27*a*f*f+256*o*(d*i)+i*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*a*r*f)+d*(144*e*u*r-27*u*u-128*a*c-192*a*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return i.getPoint=function(t,n,i){return r(i)||(i=new e),i=e.multiplyByScalar(t.direction,n,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,i,a,o,u,s,c,l){"use strict";function f(e,t,r,n){var i=t*t-4*e*r;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function h(t,r,i){n(i)||(i=new a);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,E=f(h,d,p,A);if(n(E))return i.start=E.root0,i.stop=E.root1,i}function d(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function p(t,r,n,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,E=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),m=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*r.x+n,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),v=[];if(0===_&&0===y){if(l=s.computeRealRoots(p,E,m),0===l.length)return v;var T=l[0],R=Math.sqrt(Math.max(1-T*T,0));if(v.push(new e(i,a*T,a*-R)),v.push(new e(i,a*T,a*R)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));v.push(new e(i,a*A,a*-S)),v.push(new e(i,a*A,a*S))}return v}var g=_*_,N=y*y,O=p*p,I=_*y,x=O+N,w=2*(E*p+I),M=2*m*p+E*E-N+g,C=2*(m*E-I),P=m*m-g;if(0===x&&0===w&&0===M&&0===C)return v;l=c.computeRealRoots(x,w,M,C,P);var D=l.length;if(0===D)return v;for(var L=0;L<D;++L){var U,b=l[L],F=b*b,B=Math.max(1-F,0),z=Math.sqrt(B);U=o.sign(p)===o.sign(m)?d(p*F+m,E*b,o.EPSILON12):o.sign(m)===o.sign(E*b)?d(p*F,E*b+m,o.EPSILON12):d(p*F+E*b,m,o.EPSILON12);var q=d(y*b,_,o.EPSILON15),G=U*q;G<0?v.push(new e(i,a*b,a*z)):G>0?v.push(new e(i,a*b,a*-z)):0!==z?(v.push(new e(i,a*b,a*-z)),v.push(new e(i,a*b,a*z)),++L):v.push(new e(i,a*b,a*z))}return v}var E={};E.rayPlane=function(t,r,i){n(i)||(i=new e);var a=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var m=new e,y=new e,_=new e,v=new e,T=new e;E.rayTriangleParametric=function(t,n,i,a,u){u=r(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,E=e.subtract(i,n,m),R=e.subtract(a,n,y),A=e.cross(p,R,_),S=e.dot(E,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,n,v),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,E,T),(f=e.dot(p,c))<0||l+f>S)return;h=e.dot(R,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,n,v),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,E,T),(f=e.dot(p,c)*g)<0||l+f>1)return;h=e.dot(R,c)*g}return h},E.rayTriangle=function(t,r,i,a,o,u){var s=E.rayTriangleParametric(t,r,i,a,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;E.lineSegmentTriangle=function(t,r,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=E.rayTriangleParametric(c,i,a,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};E.raySphere=function(e,t,r){if(r=h(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;E.lineSegmentSphere=function(t,r,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!n(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;E.rayEllipsoid=function(t,r){var n,i,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(n=h-1,i=e.magnitudeSquared(f),o=i*n,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var E=s/i,m=n/s;return E<m?new a(E,m):{start:m,stop:E}}var y=Math.sqrt(n/i);return new a(y,y)}return h<1?(n=h-1,i=e.magnitudeSquared(f),o=i*n,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var O=new e,I=new e,x=new e,w=new e,M=new e,C=new u,P=new u,D=new u,L=new u,U=new u,b=new u,F=new u,B=new e,z=new e,q=new t;E.grazingAltitudeLocation=function(t,r){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=r.geodeticSurfaceNormal(i,O);if(e.dot(a,s)>=0)return i} -var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(a,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,I),I),E=e.normalize(e.cross(f,d,x),x),m=C;m[0]=f.x,m[1]=f.y,m[2]=f.z,m[3]=d.x,m[4]=d.y,m[5]=d.z,m[6]=E.x,m[7]=E.y,m[8]=E.z;var y=u.transpose(m,P),_=u.fromScale(r.radii,D),v=u.fromScale(r.oneOverRadii,L),T=U;T[0]=0,T[1]=-a.z,T[2]=a.y,T[3]=a.z,T[4]=0,T[5]=-a.x,T[6]=-a.y,T[7]=a.x,T[8]=0;var R,A,S=u.multiply(u.multiply(y,v,b),T,b),g=u.multiply(u.multiply(S,_,F),m,F),N=u.multiplyByVector(S,i,M),G=p(g,e.negate(N,O),0,0,1),W=G.length;if(W>0){for(var V=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<W;++H){R=u.multiplyByVector(_,u.multiplyByVector(m,G[H],B),B);var Y=e.normalize(e.subtract(R,i,w),w),k=e.dot(Y,a);k>X&&(X=k,V=e.clone(R,V))}var Z=r.cartesianToCartographic(V,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(V,i,w))*Math.sqrt(1-X*X),A=c?-A:A,Z.height=A,r.cartographicToCartesian(Z,new e)}};var G=new e;return E.lineSegmentPlane=function(t,r,i,a){n(a)||(a=new e);var u=e.subtract(r,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},E.trianglePlaneIntersection=function(t,r,n,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,r)+o<0,c=e.dot(a,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return E.lineSegmentPlane(t,r,i,f),E.lineSegmentPlane(t,n,i,h),{positions:[t,r,n,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return E.lineSegmentPlane(r,n,i,f),E.lineSegmentPlane(r,t,i,h),{positions:[t,r,n,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return E.lineSegmentPlane(n,t,i,f),E.lineSegmentPlane(n,r,i,h),{positions:[t,r,n,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return E.lineSegmentPlane(r,t,i,f),E.lineSegmentPlane(n,t,i,h),{positions:[t,r,n,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return E.lineSegmentPlane(n,r,i,f),E.lineSegmentPlane(t,r,i,h),{positions:[t,r,n,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return E.lineSegmentPlane(t,n,i,f),E.lineSegmentPlane(r,n,i,h),{positions:[t,r,n,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},E}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,i,a,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,i){var a=-e.dot(n,t);return r(i)?(e.clone(n,i.normal),i.distance=a,i):new u(n,a)};var s=new e;u.fromCartesian4=function(t,n){var i=e.fromCartesian4(t,s),a=t.w;return r(n)?(e.clone(i,n.normal),n.distance=a,n):new u(i,a)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(r,c,c),u.fromPointNormal(c,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,i){return t(e).then(r,n,i)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=i(e),t}function r(t){return e(t,a)}function n(e){this.then=e}function i(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return a(e)}})}function a(e){return new n(function(r,n){try{return n?t(n(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,r){return h(e,t,r)}function r(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new n(e),s={then:e,resolve:r,reject:i,progress:u,promise:c,resolver:{resolve:r,reject:i,progress:u}},l=[],f=[],h=function(e,t,r){var n,i;return n=o(),i="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,i)}),f.push(i),n.promise},d=function(e){return E(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=y,E(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,i,a){return m(2,arguments),e(t,function(t){function u(e){E(e)}function s(e){p(e)}var c,l,f,h,d,p,E,m,_,v;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,h=[],d=o(),c)for(m=d.progress,E=function(e){h.push(e),--l||(p=E=y,d.reject(h))},p=function(e){f.push(e),--c||(p=E=y,d.resolve(f))},v=0;v<_;++v)v in t&&e(t[v],s,u,m);else d.resolve(f);return d.then(n,i,a)})}function c(e,t,r,n){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,r,n)}function l(e,t,r,n){return m(1,arguments),h(e,_).then(t,r,n)}function f(){return h(arguments,_)}function h(t,r){return e(t,function(t){var n,i,a,u,s,c;if(a=i=t.length>>>0,n=[],c=o(),a)for(u=function(t,i){e(t,r).then(function(e){n[i]=e,--a||c.resolve(n)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(n);return c.promise})}function d(t,r){var n=T.call(arguments,1);return e(t,function(t){var i;return i=t.length,n[0]=function(t,n,a){return e(t,function(t){return e(n,function(e){return r(t,e,a,i)})})},v.apply(t,n)})}function p(t,r,n){var i=arguments.length>2;return e(t,function(e){return e=i?n:e,r.resolve(e),e},function(e){return r.reject(e),a(e)},r.progress)}function E(e,t){for(var r,n=0;r=e[n++];)r(t)}function m(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function y(){}function _(e){return e}var v,T,R;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},T=[].slice,v=[].reduce||function(e){var t,r,n,i,a;if(a=0,t=Object(this),i=t.length>>>0,r=arguments,r.length<=1)for(;;){if(a in t){n=t[a++];break}if(++a>=i)throw new TypeError}else n=r[1];for(;a<i;++a)a in t&&(n=e(n,t[a],a,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,i,a=0,o=e.length-1;a<=o;)if(n=~~((a+o)/2),(i=r(e[n],t))<0)a=n+1;else{if(!(i>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],i=function(e,t,r,n){r||(r=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+i:i+e},a=function(e,t,r,n,a,o){var u=n-e.length;return u>0&&(e=r||!a?i(e,n,o,r):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+i(c.toString(t),u||0,"0",!1),a(e,r,n,o,s)},u=function(e,t,r,n,i,o){return null!=n&&(e=e.slice(0,n)),a(e,"",t,r,i,o)},s=function(e,n,s,c,l,f,h){var d,p,E,m,y;if("%%"==e)return"%";for(var _=!1,v="",T=!1,R=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":v=" ";break;case"+":v="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":T=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=n?t[n.slice(0,-1)]:t[r++],h){case"s":return u(String(y),_,c,f,T,A);case"c":return u(String.fromCharCode(+y),_,c,f,T);case"b":return o(y,2,R,_,c,f,T);case"o":return o(y,8,R,_,c,f,T);case"x":return o(y,16,R,_,c,f,T);case"X":return o(y,16,R,_,c,f,T).toUpperCase();case"u":return o(y,10,R,_,c,f,T);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),p=d<0?"-":v,y=p+i(String(Math.abs(d)),f,"0",!1),a(y,p,_,c,T);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,p=d<0?"-":v,E=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],m=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=p+Math.abs(d)[E](f),a(y,p,_,c,T)[m]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,i,a,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return E.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=E.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var i=r[n].offset;if(n>0){E.secondsDifference(r[n].julianDate,e)>i&&(n--,i=r[n].offset)}E.addSeconds(e,i,e)}function h(e,r){_.julianDate=e;var n=E.leapSeconds,i=t(n,_,l);if(i<0&&(i=~i),0===i)return E.addSeconds(e,-n[0].offset,r);if(i>=n.length)return E.addSeconds(e,-n[i-1].offset,r);var a=E.secondsDifference(n[i].julianDate,e);return 0===a?E.addSeconds(e,-n[i].offset,r):a<=1?void 0:E.addSeconds(e,-n[--i].offset,r)}function d(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function p(e,t,r,n,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=a+(n*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function E(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),n===c.UTC&&f(this)}var m=new a,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,v=/^(\d{4})$/,T=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;E.fromGregorianDate=function(e,t){var r=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(d(r[0],r[1],t),f(t),t):new E(r[0],r[1],c.UTC)},E.fromDate=function(e,t){var r=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(d(r[0],r[1],t),f(t),t):new E(r[0],r[1],c.UTC)},E.fromIso8601=function(e,t){e=e.replace(",",".");var r,i,a,u=e.split("T"),s=1,l=1,h=0,m=0,_=0,g=0,x=u[0],w=u[1];if(null!==(u=x.match(S)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=x.match(T)))r=+u[1],s=+u[2];else if(null!==(u=x.match(v)))r=+u[1];else{var M;if(null!==(u=x.match(R)))r=+u[1],M=+u[2],a=o(r);else if(null!==(u=x.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));M=7*C+P-D.getUTCDay()-3}i=new Date(Date.UTC(r,0,1)),i.setUTCDate(M),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(r);var L;if(n(w)){u=w.match(I),null!==u?(h=+u[1],m=+u[2],_=+u[3],g=1e3*+(u[4]||0),L=5):(u=w.match(O),null!==u?(h=+u[1],m=+u[2],_=60*+(u[3]||0),L=4):null!==(u=w.match(N))&&(h=+u[1],m=60*+(u[2]||0),L=3));var U=u[L],b=+u[L+1],F=+(u[L+2]||0);switch(U){case"+":h-=b,m-=F;break;case"-":h+=b,m+=F;break;case"Z":break;default:m+=new Date(Date.UTC(r,s-1,l,h,m)).getTimezoneOffset()}}var B=60===_;for(B&&_--;m>=60;)m-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:y[s-1];l>i;)l-=i,s++,s>12&&(s-=12,r++),i=a&&2===s?29:y[s-1];for(;m<0;)m+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),i=a&&2===s?29:y[s-1],l+=i;var z=p(r,s,l,h,m,_,g);return n(t)?(d(z[0],z[1],t),f(t)):t=new E(z[0],z[1],c.UTC),B&&E.addSeconds(t,1,t),t},E.now=function(e){return E.fromDate(new Date,e)};var x=new E(0,0,c.TAI);return E.toGregorianDate=function(e,t){var r=!1,i=h(e,x);n(i)||(E.addSeconds(e,-1,x),i=h(x,x),r=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var m=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,v=u-_*s.SECONDS_PER_HOUR,T=v/s.SECONDS_PER_MINUTE|0;v-=T*s.SECONDS_PER_MINUTE;var R=0|v,A=(v-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(R+=1),n(t)?(t.year=y,t.month=m,t.day=p,t.hour=_,t.minute=T,t.second=R,t.millisecond=A,t.isLeapSecond=r,t):new a(y,m,p,_,T,R,A,r)},E.toDate=function(e){var t=E.toGregorianDate(e,m),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},E.toIso8601=function(t,r){var i,a=E.toGregorianDate(t,m);return n(r)||0===a.millisecond?n(r)&&0!==r?(i=(.01*a.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},E.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new E(e.dayNumber,e.secondsOfDay,c.TAI)},E.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},E.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},E.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(E.secondsDifference(e,t))<=r},E.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},E.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},E.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},E.computeTaiMinusUtc=function(e){_.julianDate=e;var r=E.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},E.addSeconds=function(e,t,r){return d(e.dayNumber,e.secondsOfDay+t,r)},E.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,n,r)},E.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,n,r)},E.addDays=function(e,t,r){return d(e.dayNumber+t,e.secondsOfDay,r)},E.lessThan=function(e,t){return E.compare(e,t)<0},E.lessThanOrEquals=function(e,t){return E.compare(e,t)<=0},E.greaterThan=function(e,t){return E.compare(e,t)>0},E.greaterThanOrEquals=function(e,t){return E.compare(e,t)>=0},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return E.toIso8601(this)},E.leapSeconds=[new u(new E(2441317,43210,c.TAI),10),new u(new E(2441499,43211,c.TAI),11),new u(new E(2441683,43212,c.TAI),12),new u(new E(2442048,43213,c.TAI),13),new u(new E(2442413,43214,c.TAI),14),new u(new E(2442778,43215,c.TAI),15),new u(new E(2443144,43216,c.TAI),16),new u(new E(2443509,43217,c.TAI),17),new u(new E(2443874,43218,c.TAI),18),new u(new E(2444239,43219,c.TAI),19),new u(new E(2444786,43220,c.TAI),20),new u(new E(2445151,43221,c.TAI),21),new u(new E(2445516,43222,c.TAI),22),new u(new E(2446247,43223,c.TAI),23),new u(new E(2447161,43224,c.TAI),24),new u(new E(2447892,43225,c.TAI),25),new u(new E(2448257,43226,c.TAI),26),new u(new E(2448804,43227,c.TAI),27),new u(new E(2449169,43228,c.TAI),28),new u(new E(2449534,43229,c.TAI),29),new u(new E(2450083,43230,c.TAI),30),new u(new E(2450630,43231,c.TAI),31),new u(new E(2451179,43232,c.TAI),32),new u(new E(2453736,43233,c.TAI),33),new u(new E(2454832,43234,c.TAI),34),new u(new E(2456109,43235,c.TAI),35),new u(new E(2457204,43236,c.TAI),36),new u(new E(2457754,43237,c.TAI),37)],E}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var i=new r.constructor;for(var a in r)if(r.hasOwnProperty(a)){var o=r[a];n&&(o=t(o,n)),i[a]=o}return i}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,r){"use strict";function n(n){n=e(n,e.EMPTY_OBJECT);var i=e(n.throttleByServer,!1),a=i||e(n.throttle,!1);this.url=n.url,this.requestFunction=n.requestFunction,this.cancelFunction=n.cancelFunction,this.priorityFunction=n.priorityFunction,this.priority=e(n.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(n.type,r.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return n.prototype.cancel=function(){this.cancelled=!0},n}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var i=r[n],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(i[c],i[e])<0?c:e,s<r&&n(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,n=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return r(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return a(r,e,--this._length),this.heapify(e),n}},i}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,i,a,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return g[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function p(e){return function(t){e.state!==s.CANCELLED&&(--T.numberOfActiveRequests,--g[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function E(e){return function(t){e.state!==s.CANCELLED&&(++T.numberOfFailedRequests,--T.numberOfActiveRequests,--g[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function m(e){var t=d(e);return e.state=s.ACTIVE,S.push(e),++T.numberOfActiveRequests,++T.numberOfActiveRequestsEver,++g[e.serverKey],e.requestFunction().then(p(e)).otherwise(E(e)),t}function y(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++T.numberOfCancelledRequests,e.deferred.reject(),t&&(--T.numberOfActiveRequests,--g[e.serverKey],++T.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function _(){T.numberOfAttemptedRequests=0,T.numberOfCancelledRequests=0,T.numberOfCancelledActiveRequests=0}function v(){l.debugShowStatistics&&(T.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+T.numberOfAttemptedRequests),T.numberOfActiveRequests>0&&console.log("Number of active requests: "+T.numberOfActiveRequests),T.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+T.numberOfCancelledRequests),T.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+T.numberOfCancelledActiveRequests),T.numberOfFailedRequests>0&&console.log("Number of failed requests: "+T.numberOfFailedRequests),_())}var T={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},R=20,A=new a({comparator:c});A.maximumLength=R,A.reserve(R);var S=[],g={},N="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,i(l,{statistics:{get:function(){return T}},priorityHeapLength:{get:function(){return R},set:function(e){if(e<R)for(;A.length>e;){var t=A.pop();y(t)}R=e,A.maximumLength=e,A.reserve(e)}}}),l.update=function(){var e,t,r=0,n=S.length;for(e=0;e<n;++e)t=S[e],t.cancelled&&y(t),t.state===s.ACTIVE?r>0&&(S[e-r]=t):++r;S.length-=r;var i=A.internalArray,a=A.length;for(e=0;e<a;++e)f(i[e]);A.resort();for(var o=Math.max(l.maximumRequests-S.length,0),u=0;u<o&&A.length>0;)t=A.pop(),t.cancelled?y(t):!t.throttleByServer||h(t.serverKey)?(m(t),++u):y(t);v()},l.getServerKey=function(t){var r=new e(t).resolve(N);r.normalize();var i=r.authority;/:/.test(i)||(i=i+":"+("https"===r.scheme?"443":"80"));var a=g[i];return n(a)||(g[i]=0),i},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++T.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return m(e);if(!(S.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=A.insert(e);if(n(t)){if(t===e)return;y(t)}return d(e)}},l.clearForSpecs=function(){for(;A.length>0;){y(A.pop())}for(var e=S.length,t=0;t<e;++t)y(S[t]);S.length=0,g={},T.numberOfAttemptedRequests=0,T.numberOfActiveRequests=0,T.numberOfCancelledRequests=0,T.numberOfCancelledActiveRequests=0,T.numberOfFailedRequests=0,T.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return g[e]},l.requestHeap=A,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var i=n.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=n.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])||(a[n]=!0)},i.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])&&delete a[n]},i.contains=function(e){var r=n(e);return!(!t(r)||!t(a[r]))},i.clear=function(){a={}},i}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t){t=r(t,r.EMPTY_OBJECT);var i=t.url,o=t.responseType,s=r(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;i=r(i,t.url);var d=n(t.request)?t.request:new a;return d.url=i,d.requestFunction=function(){var t=e.defer(),r=l.load(i,o,s,c,f,t,h);return n(r)&&n(r.abort)&&(d.cancelFunction=function(){r.abort()}),t.promise},u.request(d)}function f(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function h(e,t){for(var r=f(e,t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return n}function d(e,t){t=r(t,"");var n=e[1],i=!!e[2],a=e[3];switch(t){case"":case"text":return f(i,a);case"arraybuffer":return h(i,a);case"blob":var o=h(i,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(f(i,a),n);case"json":return JSON.parse(f(i,a))}}var p=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,r,i,a,u,l){var f=p.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),n(l)&&n(h.overrideMimeType)&&h.overrideMimeType(l),h.open(r,e,!0),n(a))for(var E in a)a.hasOwnProperty(E)&&h.setRequestHeader(E,a[E]);n(t)&&(h.responseType=t);var m=!1;return"string"==typeof e&&(m=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!m||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,r=h.responseType;if(204===h.status)u.resolve();else if(!n(e)||n(t)&&r!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===r||"document"===r)&&n(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==r&&"text"!==r||!n(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(i),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,r,n){return e({url:t,headers:r,request:n})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,r,n){"use strict";function i(r,i,o){t(i)?t(i.Accept)||(i=e(i),i.Accept=a.Accept):i=a;var u=n(r,i,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var a={Accept:"application/json,*/*;q=0.01"};return i}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))p(this,t.data);else if(n(t.url)){var i=this;this._downloadPromise=e(s(t.url),function(e){p(i,e)},function(){i._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=r.columnNames.indexOf("modifiedJulianDateUtc"),a=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),E=r.columnNames.indexOf("taiMinusUtcSeconds") -;if(i<0||a<0||s<0||c<0||h<0||p<0||E<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var m=e._samples=r.samples,y=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=E,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,v=e._addNewLeapSeconds,T=0,R=m.length;T<R;T+=e._columnCount){var A=m[T+i],S=m[T+E],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,S,f.TAI);if(y.push(N),v){if(S!==_&&n(_)){var O=o.leapSeconds,I=t(O,N,d);if(I<0){var x=new u(N,S);O.splice(~I,0,x)}}_=S}}}function E(e,t,r,n,i){var a=r*n;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function m(e,t,r){return t+e*(r-t)}function y(e,t,r,n,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||n.equals(c))return E(e,r,i,s,u),u;if(n.equals(l))return E(e,r,a,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=r[h+e._ut1MinusUtcSecondsColumn],y=r[d+e._ut1MinusUtcSecondsColumn],_=y-p;if(_>.5||_<-.5){var v=r[h+e._taiMinusUtcSecondsColumn],T=r[d+e._taiMinusUtcSecondsColumn];v!==T&&(l.equals(n)?p=y:y-=T-v)}return u.xPoleWander=m(f,r[h+e._xPoleWanderRadiansColumn],r[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=m(f,r[h+e._yPoleWanderRadiansColumn],r[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=m(f,r[h+e._xCelestialPoleOffsetRadiansColumn],r[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=m(f,r[h+e._yCelestialPoleOffsetRadiansColumn],r[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=m(f,p,y),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new i(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var a=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!n(h),E=p||o.greaterThanOrEquals(h,e);if(d&&E)return s=u,!p&&h.equals(e)&&++s,l=s+1,y(this,a,this._samples,e,s,l,r),r}var m=t(a,e,o.compare,this._dateColumn);return m>=0?(m<a.length-1&&a[m+1].equals(e)&&++m,s=m,l=m):(l=~m,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,a,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=t(n,document.location.href);var i=new e(n);return new e(r).resolve(i).toString()}return i}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(n,i,a){if(a=t(a,!0),n instanceof e||(n=new e(n)),i instanceof e||(i=new e(i)),"data"===n.scheme)return n.toString();if("data"===i.scheme)return i.toString();r(i.authority)&&!r(i.scheme)&&("undefined"!=typeof document&&r(document.location)&&r(document.location.href)?i.scheme=new e(document.location.href).scheme:i.scheme=n.scheme);var o=n;i.isAbsolute()&&(o=i);var u="";r(o.scheme)&&(u+=o.scheme+":"),r(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===n?a?n.path.replace(/\/?$/,"/")+i.path.replace(/^\/?/g,""):n.path+i.path:i.path;var s=r(n.query),c=r(i.query);s&&c?u+="?"+n.query+"&"+i.query:s&&!c?u+="?"+n.query:!s&&c&&(u+="?"+i.query);var l=r(i.fragment);return r(n.fragment)&&!l?u+="#"+n.fragment:l&&(u+="#"+i.fragment),u}return i}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,r,n,i,a){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),i=p.exec(n);if(null!==i)return i[1]}}function u(){if(t(f))return f;var r;return r="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(n(r))}function s(e){return a.toUrl("../"+e)}function c(e){return i(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(a.toUrl)?s:c),t(d)||(d=document.createElement("a"));var r=h(e);return d.href=r,d.href=d.href,d.href}var f,h,d,p=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=p,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){n[s]=o,i[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(n[s]*=s-c);n[s]=1/n[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,a.daysDifference(n,e._sampleZeroDateTT)}function l(r,i){if(r._chunkDownloadsInProgress[i])return r._chunkDownloadsInProgress[i];var a=e.defer();r._chunkDownloadsInProgress[i]=a;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.replace("{0}",i):t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json"),e(o(u),function(e){r._chunkDownloadsInProgress[i]=!1;for(var t=r._samples,n=e.samples,o=i*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,r,n,i){var a=c(this,t,r),o=c(this,n,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,r){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(n(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),n(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){n(r)?(r.x=0,r.y=0,r.s=0):r=new i(0,0,0);var p,E,m=a-s*this._stepSizeDays,y=this._work,_=this._denominators,v=this._coef,T=this._xTable;for(p=0;p<=u;++p)y[p]=m-T[p];for(p=0;p<=u;++p){for(v[p]=1,E=0;E<=u;++E)E!==p&&(v[p]*=y[E]);v[p]*=_[p];var R=3*(s+p);r.x+=v[p]*d[R++],r.y+=v[p]*d[R++],r.s+=v[p]*d[R]}return r}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(i,0)}var c=new e;s.fromAxisAngle=function(t,r,i){var a=r/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return n(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],E=h+d+p;if(E>0)r=Math.sqrt(E+1),c=.5*r,r=.5/r,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var m=l,y=0;d>h&&(y=1),p>h&&p>d&&(y=2);var _=m[y],v=m[_];r=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(v,v)]+1);var T=f;T[y]=.5*r,r=.5/r,c=(e[u.getElementIndex(v,_)]-e[u.getElementIndex(_,v)])*r,T[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*r,T[v]=(e[u.getElementIndex(v,y)]+e[u.getElementIndex(y,v)])*r,i=-T[0],a=-T[1],o=-T[2]}return n(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,E=new s;s.fromHeadingPitchRoll=function(t,r){return E=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(p,E,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,r,r)};var m=new e,y=new e,_=new s,v=new s,T=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,T),s.conjugate(T,T);for(var i=0,a=r-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,T,_),_.w<0&&s.negate(_,_),s.computeAxis(_,m);var u=s.computeAngle(_);n[o]=m.x*u,n[o+1]=m.y*u,n[o+2]=m.z*u}},s.unpackInterpolationResult=function(t,r,i,a,o){n(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(r,4*a,v),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,v,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,i=e.y*r,a=e.z*r,o=e.w*r;return t.x=n,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+i*c-a*s,h=o*s-n*c+i*l+a*u,d=o*c+n*s-i*u+a*l,p=o*l-n*u-i*s-a*c;return r.x=f,r.y=h,r.z=d,r.w=p,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,r,n){return R=s.multiplyByScalar(t,r,R),n=s.multiplyByScalar(e,1-r,n),s.add(R,n,n)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,r,n){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,r,n);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-r)*u),S),g=s.multiplyByScalar(a,Math.sin(r*u),g),n=s.add(S,g,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),i=0;return 0!==n&&(i=n/Math.sin(n)),e.multiplyByScalar(t,i,r)},s.exp=function(t,r){var n=e.magnitude(t),i=0;return 0!==n&&(i=Math.sin(n)/n),r.x=t.x*i,r.y=t.y*i,r.z=t.z*i,r.w=Math.cos(n),r};var N=new e,O=new e,I=new s,x=new s;s.computeInnerQuadrangle=function(t,r,n,i){var a=s.conjugate(r,I);s.multiply(a,n,x);var o=s.log(x,N);s.multiply(a,t,x);var u=s.log(x,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(r,I,i)},s.squad=function(e,t,r,n,i,a){var o=s.slerp(e,t,i,I),u=s.slerp(r,n,i,x);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,M=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=i.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var b=U+1,F=2*b+1;C[U]=1/(b*F),P[U]=b/F}return C[7]=M/136,P[7]=8*M/17,s.fastSlerp=function(e,t,r,n){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,L[f]=(C[f]*l-P[f])*o;var h=i*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),p=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,n),s.add(p,n,n)},s.fastSquad=function(e,t,r,n,i,a){var o=s.fastSlerp(e,t,i,I),u=s.fastSlerp(r,n,i,x);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,E,m,y,_,v){"use strict";var T={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},N=new r,O=new r,I=new r;T.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,i=R[e][t],a=e+t;return u(S[a])?n=S[a]:(n=function(n,a,s){if(u(s)||(s=new y),E.equalsEpsilon(n.x,0,E.EPSILON14)&&E.equalsEpsilon(n.y,0,E.EPSILON14)){var c=E.sign(n.z);r.unpack(A[e],0,N),"east"!==e&&"west"!==e&&r.multiplyByScalar(N,c,N),r.unpack(A[t],0,O),"east"!==t&&"west"!==t&&r.multiplyByScalar(O,c,O),r.unpack(A[i],0,I),"east"!==i&&"west"!==i&&r.multiplyByScalar(I,c,I)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(n,g.up);var l=g.up,h=g.east;h.x=-n.y,h.y=n.x,h.z=0,r.normalize(h,g.east),r.cross(l,h,g.north),r.multiplyByScalar(g.up,-1,g.down),r.multiplyByScalar(g.east,-1,g.west),r.multiplyByScalar(g.north,-1,g.south),N=g[e],O=g[t],I=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},S[a]=n),n},T.eastNorthUpToFixedFrame=T.localFrameToFixedFrameGenerator("east","north"),T.northEastDownToFixedFrame=T.localFrameToFixedFrameGenerator("north","east"),T.northUpEastToFixedFrame=T.localFrameToFixedFrameGenerator("north","up"),T.northWestUpToFixedFrame=T.localFrameToFixedFrameGenerator("north","west");var x=new _,w=new r(1,1,1),M=new y;T.headingPitchRollToFixedFrame=function(e,t,n,i,a){i=o(i,T.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,x),s=y.fromTranslationQuaternionRotationScale(r.ZERO,u,w,M);return a=i(e,n,a),y.multiply(a,s,a)};var C=new y,P=new m;T.headingPitchRollQuaternion=function(e,t,r,n,i){var a=T.headingPitchRollToFixedFrame(e,t,r,n,C),o=y.getRotation(a,P);return _.fromRotationMatrix(o,i)};var D=E.TWO_PI/86400,L=new p;T.computeTemeToPseudoFixedMatrix=function(e,t){L=p.addSeconds(e,-p.computeTaiMinusUtc(e),L);var r,n=L.dayNumber,i=L.secondsOfDay,a=n-2451545;r=i>=43200?(a+.5)/v.DAYS_PER_JULIAN_CENTURY:(a-.5)/v.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%E.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(i+.5*v.SECONDS_PER_DAY)%v.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new m(h,d,0,-d,h,0,0,0,1)},T.iau2006XysData=new h,T.earthOrientationParameters=c.NONE;T.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=T.iau2006XysData.preload(r,n,i,a),u=T.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},T.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new m);var r=T.computeFixedToIcrfMatrix(e,t);if(u(r))return m.transpose(r,t)};var U=new d(0,0,0),b=new l(0,0,0,0,0,0),F=new m,B=new m;T.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new m);var r=T.earthOrientationParameters.compute(e,b);if(u(r)){var n=e.dayNumber,i=e.secondsOfDay+32.184,a=T.iau2006XysData.computeXysRadians(n,i,U);if(u(a)){var o=a.x+r.xPoleOffset,s=a.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=m.fromRotationZ(-a.s,B),h=m.multiply(l,f,F),d=e.dayNumber,y=e.secondsOfDay-p.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=d-2451545,R=y/v.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*E.TWO_PI;var S=m.fromRotationZ(A,B),g=m.multiply(h,S,F),N=Math.cos(r.xPoleWander),O=Math.cos(r.yPoleWander),I=Math.sin(r.xPoleWander),x=Math.sin(r.yPoleWander),w=n-2451545+i/v.SECONDS_PER_DAY;w/=36525;var M=-47e-6*w*E.RADIANS_PER_DEGREE/3600,C=Math.cos(M),P=Math.sin(M),D=B;return D[0]=N*C,D[1]=N*P,D[2]=I,D[3]=-O*P+x*I*C,D[4]=O*C+x*I*P,D[5]=-x*N,D[6]=-x*P-O*I*C,D[7]=x*C-O*I*P,D[8]=O*N,m.multiply(g,D,t)}}};var z=new n;T.pointToWindowCoordinates=function(e,t,r,n){return n=T.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},T.pointToGLWindowCoordinates=function(e,r,i,a){u(a)||(a=new t);var o=z;return y.multiplyByVector(e,n.fromElements(i.x,i.y,i.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(r,o,o),t.fromCartesian4(o,a)};var q=new r,G=new r,W=new r;T.rotationMatrixFromPositionVelocity=function(e,t,n,i){var a=o(n,f.WGS84).geodeticSurfaceNormal(e,q),s=r.cross(t,a,G);r.equalsEpsilon(s,r.ZERO,E.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,W);return r.cross(t,c,s),r.negate(s,s),u(i)||(i=new m),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var V=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new r,Y=new r,k=new m,Z=new y,j=new y;return T.basisTo2D=function(e,t,n){var i=y.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=T.eastNorthUpToFixedFrame(i,a,Z),c=y.inverseTransformation(s,j),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,n);return y.multiply(V,f,n),y.setTranslation(n,u,n),n},T.wgs84To2DModelMatrix=function(e,t,n){var i=e.ellipsoid,a=T.eastNorthUpToFixedFrame(t,i,Z),o=y.inverseTransformation(a,j),u=i.cartesianToCartographic(t,X),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,Z);return y.multiply(V,o,n),y.multiply(c,n,n),n},T}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d){"use strict";function p(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var n=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=r.fromCartesian4(l.getColumn(n,0,E)),this._yAxis=r.fromCartesian4(l.getColumn(n,1,E));var a=r.fromCartesian4(l.getColumn(n,2,E));this._plane=f.fromPointNormal(e,a)}var E=new n;o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var m=new e;p.fromPoints=function(t,r){return new p(e.fromPoints(t,m).center,r)};var y=new h,_=new r;p.prototype.projectPointOntoPlane=function(e,n){var i=y;i.origin=e,r.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return a(n)?(n.x=s,n.y=l,n):new t(s,l)}},p.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var r=0,n=e.length,i=0;i<n;i++){var o=this.projectPointOntoPlane(e[i],t[r]);a(o)&&(t[r]=o,r++)}return t.length=r,t},p.prototype.projectPointToNearestOnPlane=function(e,n){a(n)||(n=new t);var i=y;i.origin=e,r.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return n.x=s,n.y=l,n},p.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var r=e.length;t.length=r;for(var n=0;n<r;n++)t[n]=this.projectPointToNearestOnPlane(e[n],t[n]);return t};var v=new r;return p.prototype.projectPointsOntoEllipsoid=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=v,l=0;l<n;++l){var f=e[l];r.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new r);var h=r.add(o,c,t[l]);r.multiplyByScalar(s,f.y,c),r.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},p}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var i=e.attributes[n],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return i}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,r,n,i){"use strict";var a={};a.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,a=r.y;r.x=(1-Math.abs(a))*i.signNotZero(n),r.y=(1-Math.abs(n))*i.signNotZero(a)}return r.x=i.toSNorm(r.x,t),r.y=i.toSNorm(r.y,t),r},a.octEncode=function(e,t){return a.octEncodeInRange(e,255,t)},a.octDecodeInRange=function(e,r,n,a){if(a.x=i.fromSNorm(e,n),a.y=i.fromSNorm(r,n),a.z=1-(Math.abs(a.x)+Math.abs(a.y)),a.z<0){var o=a.x;a.x=(1-Math.abs(a.y))*i.signNotZero(o),a.y=(1-Math.abs(o))*i.signNotZero(a.y)}return t.normalize(a,a)},a.octDecode=function(e,t,r){return a.octDecodeInRange(e,t,255,r)},a.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return a.octEncodeFloat=function(e){return a.octEncode(e,o),a.octPackFloat(o)},a.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),i=256*(r-n);return a.octDecode(n,i,t)},a.octPack=function(e,t,r,n){var i=a.octEncodeFloat(e),u=a.octEncodeFloat(t),s=a.octEncode(r,o);return n.x=65536*s.x+i,n.y=65536*s.y+u,n},a.octUnpack=function(e,t,r,n){var i=e.x/65536,o=Math.floor(i),u=65536*(i-o);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);a.octDecodeFloat(u,t),a.octDecodeFloat(c,r),a.octDecode(o,s,n)},a.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},a.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},a}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function i(r,i,s,c,l){n(l)||(l=new t);var f,h,d,p,E,m,y,_;n(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(r,i,u),p=t.dot(f,f),E=t.dot(f,h),m=t.dot(f,d),y=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(r,i,u),p=e.dot(f,f),E=e.dot(f,h),m=e.dot(f,d),y=e.dot(h,h),_=e.dot(h,d));var v=1/(p*y-E*E);return l.y=(y*m-E*_)*v,l.z=(p*_-E*m)*v,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var i={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var a=t.high,o=t.low;return n.encode(e.x,i),a.x=i.high,o.x=i.low,n.encode(e.y,i),a.y=i.high,o.y=i.low,n.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,a);var i=a.high,o=a.low;t[r]=i.x,t[r+1]=i.y,t[r+2]=i.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,r,i){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,i):new Uint16Array(t,r,i)},r(a)}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,i=r.maximumIndex,a=e(r.cacheSize,24),o=n.length;if(!t(i)){i=0;for(var u=0,s=n[u];u<o;)s>i&&(i=s),++u,s=n[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[n[h]]>a&&(c[n[h]]=f,++f);return(f-a+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<n;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}r=e(r,e.EMPTY_OBJECT);var i,a=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var E=0;l<h;)p[a[l]].vertexTriangles.push(E),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(E),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(E),++p[a[l+2]].numLiveTriangles,++E,l+=3;var m=0,y=u+1;i=1;var _,v,T=[],R=[],A=0,S=[],g=s/3,N=[];for(d=0;d<g;d++)N[d]=!1;for(var O,I;-1!==m;){T=[],v=p[m],I=v.vertexTriangles.length;for(var x=0;x<I;++x)if(E=v.vertexTriangles[x],!N[E]){N[E]=!0,l=E+E+E;for(var w=0;w<3;++w)O=a[l],T.push(O),R.push(O),S[A]=O,++A,_=p[O],--_.numLiveTriangles,y-_.timeStamp>u&&(_.timeStamp=y,++y),++l}m=function(e,t,r,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var h=r[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?n(i,o,e,u):c}(a,u,T,p,y,R,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,E,m,y,_,v,T,R,A,S,g){"use strict";function N(e,t,r,n,i){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=i,e[t++]=i,e[t]=r}function O(e){for(var t=e.length,r=t/3*6,n=m.createTypedArray(t,r),i=0,a=0;a<t;a+=3,i+=6)N(n,i,e[a],e[a+1],e[a+2]);return n}function I(e){var t=e.length;if(t>=3){var r=6*(t-2),n=m.createTypedArray(t,r);N(n,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)N(n,i,e[a-1],e[a],e[a-2]);return n}return new Uint16Array}function x(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=m.createTypedArray(t,r),i=e[0],a=0,o=1;o<t;++o,a+=6)N(n,a,i,e[o],e[o+1]);return n}return new Uint16Array}function w(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new p({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function M(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var i=t[n],a=0;a<i.componentsPerAttribute;++a)e[n].values.push(i.values[r*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,r,a)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),T.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,r,a)}function D(e,t){var r,n=e.length,i={},a=e[0][t].attributes;for(r in a)if(a.hasOwnProperty(r)&&c(a[r])&&c(a[r].values)){for(var o=a[r],s=o.values.length,l=!0,f=1;f<n;++f){var h=e[f][t].attributes[r];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break} -s+=h.values.length}l&&(i[r]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function L(e,t){var n,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),E=e[0][t].primitiveType,y=D(e,t);for(n in y)if(y.hasOwnProperty(n))for(s=y[n].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var v=0;for(a=0;a<h;++a)v+=e[a][t].indices.length;var T=d.computeNumberOfVertices(new d({attributes:y,primitiveType:S.POINTS})),R=m.createTypedArray(T,v),A=0,g=0;for(a=0;a<h;++a){var N=e[a][t].indices,O=N.length;for(u=0;u<O;++u)R[A++]=g+N[u];g+=d.computeNumberOfVertices(e[a][t])}_=R}var I,x=new i,w=0;for(a=0;a<h;++a){if(I=e[a][t].boundingSphere,!c(I)){x=void 0;break}i.add(I.center,x,x)}if(c(x))for(i.divideByScalar(x,h,x),a=0;a<h;++a){I=e[a][t].boundingSphere;var M=i.magnitude(i.subtract(I.center,x,se))+I.radius;M>w&&(w=M)}return new d({attributes:y,indices:_,primitiveType:E,boundingSphere:c(x)?new r(x,w):void 0})}function U(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function b(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,i=3;i<t;++i)r[n++]=i-1,r[n++]=0,r[n++]=i;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,i=3;i<t-1;i+=2)r[n++]=i,r[n++]=i-1,r[n++]=i+1,i+2<t&&(r[n++]=i,r[n++]=i+1,r[n++]=i+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return e.indices=r,e.primitiveType=S.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function G(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return b(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return U(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return q(e);case S.LINES:return B(e)}return e}function W(e,t){Math.abs(e.y)<v.EPSILON6&&(e.y=t?-v.EPSILON6:v.EPSILON6)}function V(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return W(e,e.y<0),W(t,t.y<0),void W(r,r.y<0);var n,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(r.y);n=i>a?i>o?v.sign(e.y):v.sign(r.y):a>o?v.sign(t.y):v.sign(r.y);var u=n<0;W(e,u),W(t,u),W(r,u)}function X(e,t,r,n){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),r),i.clone(r,n),W(r,!0),W(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){V(e,t,r);var n=e.y<0,i=t.y<0,a=r.y<0,o=0;o+=n?1:0,o+=i?1:0,o+=a?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(X(e,t,Ae,ge),X(e,r,Se,Ne),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(X(t,r,Ae,ge),X(t,e,Se,Ne),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(X(r,e,Ae,ge),X(r,t,Se,Ne),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?i?a||(X(r,e,Ae,ge),X(r,t,Se,Ne),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(X(t,r,Ae,ge),X(t,e,Se,Ne),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(X(e,t,Ae,ge),X(e,r,Se,Ne),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=ge,s[6]=Ne,s.length=7),Oe}}function Y(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var i in n)if(n.hasOwnProperty(i)&&c(n[i])&&c(n[i].values)){var a=n[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=m.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function k(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var i=t[n];r[n]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:r,indices:[],primitiveType:e.primitiveType})}function Z(e,t,r){var n=c(e.geometry.boundingSphere);t=Y(t,n),r=Y(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function j(e,r,a,o,u,s,l,f,h,d,p,E){if(c(s)||c(l)||c(f)||c(h)||c(d)){var m=i.fromArray(u,3*e,Ie),y=i.fromArray(u,3*r,xe),_=i.fromArray(u,3*a,we),v=t(o,m,y,_,Me);if(c(s)){var T=i.fromArray(s,3*e,Ie),R=i.fromArray(s,3*r,xe),A=i.fromArray(s,3*a,we);i.multiplyByScalar(T,v.x,T),i.multiplyByScalar(R,v.y,R),i.multiplyByScalar(A,v.z,A);var S=i.add(T,R,T);i.add(S,A,S),i.normalize(S,S),i.pack(S,p.normal.values,3*E)}if(c(d)){var g=i.fromArray(d,3*e,Ie),N=i.fromArray(d,3*r,xe),O=i.fromArray(d,3*a,we);i.multiplyByScalar(g,v.x,g),i.multiplyByScalar(N,v.y,N),i.multiplyByScalar(O,v.z,O);var I;i.equals(g,i.ZERO)&&i.equals(N,i.ZERO)&&i.equals(O,i.ZERO)?(I=Ie,I.x=0,I.y=0,I.z=0):(I=i.add(g,N,g),i.add(I,O,I),i.normalize(I,I)),i.pack(I,p.extrudeDirection.values,3*E)}if(c(l)){var x=i.fromArray(l,3*e,Ie),w=i.fromArray(l,3*r,xe),M=i.fromArray(l,3*a,we);i.multiplyByScalar(x,v.x,x),i.multiplyByScalar(w,v.y,w),i.multiplyByScalar(M,v.z,M);var C=i.add(x,w,x);i.add(C,M,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*E)}if(c(f)){var P=i.fromArray(f,3*e,Ie),D=i.fromArray(f,3*r,xe),L=i.fromArray(f,3*a,we);i.multiplyByScalar(P,v.x,P),i.multiplyByScalar(D,v.y,D),i.multiplyByScalar(L,v.z,L);var U=i.add(P,D,P);i.add(U,L,U),i.normalize(U,U),i.pack(U,p.bitangent.values,3*E)}if(c(h)){var b=n.fromArray(h,2*e,Ce),F=n.fromArray(h,2*r,Pe),B=n.fromArray(h,2*a,De);n.multiplyByScalar(b,v.x,b),n.multiplyByScalar(F,v.y,F),n.multiplyByScalar(B,v.z,B);var z=n.add(b,F,b);n.add(z,B,z),n.pack(z,p.st.values,2*E)}}}function K(e,t,r,n,i,a){var o=e.position.values.length/3;if(-1!==i){var u=n[i],s=r[u];return-1===s?(r[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,r,n,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,E=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,m=u.indices,y=k(u),_=k(u),v=[];v.length=l.length/3;var T=[];for(T.length=l.length/3,o=0;o<v.length;++o)v[o]=-1,T[o]=-1;var R=m.length;for(o=0;o<R;o+=3){var A=m[o],S=m[o+1],g=m[o+2],N=i.fromArray(l,3*A),O=i.fromArray(l,3*S),I=i.fromArray(l,3*g),x=H(N,O,I);if(c(x)&&x.positions.length>3)for(var w=x.positions,M=x.indices,C=M.length,P=0;P<C;++P){var D=M[P],L=w[D];L.y<0?(t=_.attributes,r=_.indices,n=v):(t=y.attributes,r=y.indices,n=T),a=K(t,r,n,m,D<3?o+D:-1,L),j(A,S,g,L,l,f,d,h,p,E,t,a)}else c(x)&&(N=x.positions[0],O=x.positions[1],I=x.positions[2]),N.y<0?(t=_.attributes,r=_.indices,n=v):(t=y.attributes,r=y.indices,n=T),a=K(t,r,n,m,o,N),j(A,S,g,N,l,f,d,h,p,E,t,a),a=K(t,r,n,m,o+1,O),j(A,S,g,O,l,f,d,h,p,E,t,a),a=K(t,r,n,m,o+2,I),j(A,S,g,I,l,f,d,h,p,E,t,a)}Z(e,_,y)}function Q(e){var t,r=e.geometry,n=r.attributes,a=n.position.values,o=r.indices,u=k(r),s=k(r),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],E=i.fromArray(a,3*d,Ie),m=i.fromArray(a,3*p,xe);Math.abs(E.y)<v.EPSILON6&&(E.y<0?E.y=-v.EPSILON6:E.y=v.EPSILON6),Math.abs(m.y)<v.EPSILON6&&(m.y<0?m.y=-v.EPSILON6:m.y=v.EPSILON6);var y=u.attributes,T=u.indices,R=h,A=s.attributes,S=s.indices,g=f,N=_.lineSegmentPlane(E,m,Le,we);if(c(N)){var O=i.multiplyByScalar(i.UNIT_Y,5*v.EPSILON9,Ue);E.y<0&&(i.negate(O,O),y=s.attributes,T=s.indices,R=f,A=u.attributes,S=u.indices,g=h);var I=i.add(N,O,be);K(y,T,R,o,t,E),K(y,T,R,o,-1,I),i.negate(O,O),i.add(N,O,I),K(A,S,g,o,-1,I),K(A,S,g,o,t+1,m)}else{var x,w,M;E.y<0?(x=s.attributes,w=s.indices,M=f):(x=u.attributes,w=u.indices,M=h),K(x,w,M,o,t,E),K(x,w,M,o,t+1,m)}}Z(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,a=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=i.unpack(r,u,ze);if(!(s.x>0)){var c=i.unpack(n,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):i.pack(s,n,u));var l=i.unpack(a,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=r[u+3],a[u+1]=r[u+4],a[u+2]=r[u+5]):i.pack(s,a,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,E=c(s.color)?s.color.values:void 0,m=k(u),y=k(u),T=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,S=t+2,g=i.fromArray(l,3*A,ze),N=i.fromArray(l,3*S,qe);if(Math.abs(g.y)<ke)for(g.y=ke*(N.y<0?-1:1),l[3*t+1]=g.y,l[3*(t+1)+1]=g.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(N.y)<ke)for(N.y=ke*(g.y<0?-1:1),l[3*(t+2)+1]=N.y,l[3*(t+3)+1]=N.y,r=3*A;r<3*A+12;r+=3)h[r]=l[3*(t+2)],h[r+1]=l[3*(t+2)+1],h[r+2]=l[3*(t+2)+2];var O=m.attributes,I=m.indices,x=y.attributes,w=y.indices,M=_.lineSegmentPlane(g,N,Le,We);if(c(M)){T=!0;var C=i.multiplyByScalar(i.UNIT_Y,Ye,Ve);g.y<0&&(i.negate(C,C),O=y.attributes,I=y.indices,x=m.attributes,w=m.indices);var P=i.add(M,C,Xe);O.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),O.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),O.prevPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(M,C,P),x.position.values.push(P.x,P.y,P.z),x.position.values.push(P.x,P.y,P.z),x.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),x.prevPosition.values.push(P.x,P.y,P.z),x.prevPosition.values.push(P.x,P.y,P.z),x.prevPosition.values.push(P.x,P.y,P.z),x.prevPosition.values.push(P.x,P.y,P.z),x.nextPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),x.nextPosition.values.push(h[3*S],h[3*S+1],h[3*S+2]),x.nextPosition.values.push(h[3*S+3],h[3*S+4],h[3*S+5]);var D=n.fromArray(d,2*A,Fe),L=Math.abs(D.y);O.expandAndWidth.values.push(-1,L,1,L),O.expandAndWidth.values.push(-1,-L,1,-L),x.expandAndWidth.values.push(-1,L,1,L),x.expandAndWidth.values.push(-1,-L,1,-L);var U=i.magnitudeSquared(i.subtract(M,g,Ge));if(U/=i.magnitudeSquared(i.subtract(N,g,Ge)),c(E)){var b=a.fromArray(E,4*A,He),F=a.fromArray(E,4*S,He),B=v.lerp(b.x,F.x,U),z=v.lerp(b.y,F.y,U),q=v.lerp(b.z,F.z,U),G=v.lerp(b.w,F.w,U);for(r=4*A;r<4*A+8;++r)O.color.values.push(E[r]);for(O.color.values.push(B,z,q,G),O.color.values.push(B,z,q,G),x.color.values.push(B,z,q,G),x.color.values.push(B,z,q,G),r=4*S;r<4*S+8;++r)x.color.values.push(E[r])}if(c(p)){var W=n.fromArray(p,2*A,Fe),V=n.fromArray(p,2*(t+3),Be),X=v.lerp(W.x,V.x,U);for(r=2*A;r<2*A+4;++r)O.st.values.push(p[r]);for(O.st.values.push(X,W.y),O.st.values.push(X,V.y),x.st.values.push(X,W.y),x.st.values.push(X,V.y),r=2*S;r<2*S+4;++r)x.st.values.push(p[r])}o=O.position.values.length/3-4,I.push(o,o+2,o+1),I.push(o+1,o+2,o+3),o=x.position.values.length/3-4,w.push(o,o+2,o+1),w.push(o+1,o+2,o+3)}else{var H,Y;for(g.y<0?(H=y.attributes,Y=y.indices):(H=m.attributes,Y=m.indices),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(d[r]),c(p)&&H.st.values.push(p[r]);if(c(E))for(r=4*t;r<4*t+16;++r)H.color.values.push(E[r]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}T&&($(y),$(m)),Z(e,y,m)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=O(t);break;case S.TRIANGLE_STRIP:e.indices=I(t);break;case S.TRIANGLE_FAN:e.indices=x(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*n,l[f++]=i[h+1]+a[h+1]*n,l[f++]=i[h+2]+a[h+2]*n;var E,m=e.boundingSphere;return c(m)&&(E=new r(m.center,m.radius+n)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:E})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,i={},a=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(i[u]=a++)}for(var s in n)n.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),i=0;i<t;i++)n[i]=-1;for(var a,o=r,s=o.length,l=m.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=n[o[f]],-1!==a?l[h]=a:(a=o[f],n[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var E=e.attributes;for(var y in E)if(E.hasOwnProperty(y)&&c(E[y])&&c(E[y].values)){for(var _=E[y],v=_.values,T=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);T<t;){var S=n[T];if(-1!==S)for(var g=0;g<R;g++)A[R*S+g]=v[R*T+g];++T}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,i=0,a=0;a<n;a++)r[a]>i&&(i=r[a]);e.indices=g.tipsify({indices:r,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=d.computeNumberOfVertices(e);if(c(e.indices)&&r>=v.SIXTY_FOUR_KILOBYTES){var n,i=[],a=[],o=0,u=w(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var h=0;h<n;++h){var p=s[f+h],E=i[p];c(E)||(E=o++,i[p]=E,M(u,e.attributes,p)),a.push(E)}o+n>=v.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=w(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new i,ne=new o;te.projectTo2D=function(e,t,r,n,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,E=0;E<l.length;E+=3){var m=i.fromArray(l,E,re),y=s.cartesianToCartographic(m,ne),_=a.project(y,re);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[r]=o,e.attributes[n]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new T;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=r.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,i=0;i<n;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&r.push(a)}var o=[];return t.length>0&&o.push(L(t,"geometry")),r.length>0&&(o.push(L(r,"westHemisphereGeometry")),o.push(L(r,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,a=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=r[t],E=r[t+1],m=r[t+2],y=3*d,_=3*E,T=3*m;le.x=a[y],le.y=a[y+1],le.z=a[y+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[T],he.y=a[T+1],he.z=a[T+2],c[d].count++,c[E].count++,c[m].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var S=A.indexOffset+A.currentCount;f[S]=h,A.currentCount++,A=c[r[t+1]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,A=c[r[t+2]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,h++}var g=new Float32Array(3*o);for(t=0;t<o;t++){var N=3*t;if(A=c[t],i.clone(i.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)i.add(ce,l[f[A.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&i.clone(l[f[A.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),g[N]=ce.x,g[N+1]=ce.y,g[N+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:g}),e};var de=new i,pe=new i,Ee=new i;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var E=r[t],m=r[t+1],y=r[t+2];f=3*E,h=3*m,d=3*y;var _=2*E,v=2*m,T=2*y,R=n[f],A=n[f+1],S=n[f+2],g=o[_],N=o[_+1],O=o[v+1]-N,I=o[T+1]-N,x=1/((o[v]-g)*I-(o[T]-g)*O),w=(I*(n[h]-R)-O*(n[d]-R))*x,M=(I*(n[h+1]-A)-O*(n[d+1]-A))*x,C=(I*(n[h+2]-S)-O*(n[d+2]-S))*x;l[f]+=w,l[f+1]+=M,l[f+2]+=C,l[h]+=w,l[h+1]+=M,l[h+2]+=C,l[d]+=w,l[d+1]+=M,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var L=i.fromArray(a,f,de),U=i.fromArray(l,f,Ee),b=i.dot(L,U);i.multiplyByScalar(L,b,pe),i.normalize(i.subtract(U,pe,U),U),P[f]=U.x,P[h]=U.y,P[d]=U.z,i.normalize(i.cross(L,U,U),U),D[f]=U.x,D[h]=U.y,D[d]=U.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var me=new n,ye=new i,_e=new i,ve=new i,Te=new n;te.compressVertices=function(t){var r,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(r=0;r<a;++r)i.fromArray(s,3*r,ye),i.equals(ye,i.ZERO)?f+=2:(Te=e.octEncodeInRange(ye,65535,Te),l[f++]=Te.x,l[f++]=Te.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,E=c(h),m=c(d);if(!E&&!m)return t;var y,_,v,T,R=t.attributes.tangent,A=t.attributes.bitangent,S=c(R),g=c(A);E&&(y=h.values),m&&(_=d.values),S&&(v=R.values),g&&(T=A.values),a=(E?y.length:_.length)/(E?3:2);var N=a,O=m&&E?2:1;O+=S||g?1:0,N*=O;var I=new Float32Array(N),x=0;for(r=0;r<a;++r){m&&(n.fromArray(_,2*r,me),I[x++]=e.compressTextureCoordinates(me));var w=3*r;E&&c(v)&&c(T)?(i.fromArray(y,w,ye),i.fromArray(v,w,_e),i.fromArray(T,w,ve),e.octPack(ye,_e,ve,me),I[x++]=me.x,I[x++]=me.y):(E&&(i.fromArray(y,w,ye),I[x++]=e.octEncodeFloat(ye)),S&&(i.fromArray(v,w,ye),I[x++]=e.octEncodeFloat(ye)),g&&(i.fromArray(T,w,ye),I[x++]=e.octEncodeFloat(ye)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:I}),E&&delete t.attributes.normal,m&&delete t.attributes.st,g&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Re=new i,Ae=new i,Se=new i,ge=new i,Ne=new i,Oe={positions:new Array(7),indices:new Array(9)},Ie=new i,xe=new i,we=new i,Me=new i,Ce=new n,Pe=new n,De=new n,Le=A.fromPointNormal(i.ZERO,i.UNIT_Y),Ue=new i,be=new i,Fe=new n,Be=new n,ze=new i,qe=new i,Ge=new i,We=new i,Ve=new i,Xe=new i,He=new a,Ye=5*v.EPSILON9,ke=v.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==y.INTERSECTING)return e}if(t.geometryType!==E.NONE)switch(t.geometryType){case E.POLYLINES:ee(e);break;case E.TRIANGLES:J(e);break;case E.LINES:Q(e)}else G(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,r,i){i=i||2;var a=r&&r.length,o=a?r[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,p,E,m;if(a&&(u=s(e,r,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var y=i;y<o;y+=i)p=e[y],E=e[y+1],p<l&&(l=p),E<f&&(f=E),p>h&&(h=p),E>d&&(d=E);m=Math.max(h-l,d-f)}return n(u,c,i,l,f,m),c}function t(e,t,r,n,i){var a,o;if(i===x(e,t,r,n)>0)for(a=t;a<r;a+=n)o=N(a,e[a],e[a+1],o);else for(a=r-n;a>=t;a-=n)o=N(a,e[a],e[a+1],o);return o&&v(o,o.next)&&(O(o),o=o.next),o}function r(e,t){if(!e)return e;t||(t=e);var r,n=e;do{if(r=!1,n.steiner||!v(n,n.next)&&0!==_(n.prev,n,n.next))n=n.next;else{if(O(n),(n=t=n.prev)===n.next)return null;r=!0}}while(r||n!==t);return t}function n(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var p,E,m=e;e.prev!==e.next;)if(p=e.prev,E=e.next,f?a(e,c,l,f):i(e))t.push(p.i/s),t.push(e.i/s),t.push(E.i/s),O(e),e=E.next,m=E.next;else if((e=E)===m){d?1===d?(e=o(e,t,s),n(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):n(r(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,r=e,n=e.next;if(_(t,r,n)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(m(t.x,t.y,r.x,r.y,n.x,n.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,r,n){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=p(u,s,t,r,n),h=p(c,l,t,r,n),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,r){var n=e;do{var i=n.prev,a=n.next.next;!v(i,a)&&T(i,n,n.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/r),t.push(n.i/r),t.push(a.i/r),O(n),O(n.next),n=e=a),n=n.next}while(n!==e);return n}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&y(s,c)){var l=g(s,c);return s=r(s,s.next),l=r(l,l.next),n(s,t,i,a,o,u),void n(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,n,i,a){var o,u,s,f,h,d=[];for(o=0,u=n.length;o<u;o++)s=n[o]*a,f=o<u-1?n[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(E(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=r(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var n=g(t,e);r(n,n.next)}}function f(e,t){var r,n=t,i=e.x,a=e.y,o=-1/0;do{if(a<=n.y&&a>=n.next.y){var u=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(u<=i&&u>o){if(o=u,u===i){if(a===n.y)return n;if(a===n.next.y)return n.next}r=n.x<n.next.x?n:n.next}}n=n.next}while(n!==t);if(!r)return null;if(i===o)return r.prev;var s,c=r,l=r.x,f=r.y,h=1/0;for(n=r.next;n!==c;)i>=n.x&&n.x>=l&&m(a<f?i:o,a,l,f,a<f?o:i,a,n.x,n.y)&&((s=Math.abs(a-n.y)/(i-n.x))<h||s===h&&n.x>r.x)&&A(n,e)&&(r=n,h=s),n=n.next;return r}function h(e,t,r,n){var i=e;do{null===i.z&&(i.z=p(i.x,i.y,t,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,r,n,i,a,o,u,s,c=1;do{for(r=e,e=null,a=null,o=0;r;){for(o++,n=r,u=0,t=0;t<c&&(u++,n=n.nextZ);t++);for(s=c;u>0||s>0&&n;)0===u?(i=n,n=n.nextZ,s--):0!==s&&n?r.z<=n.z?(i=r,r=r.nextZ,u--):(i=n,n=n.nextZ,s--):(i=r,r=r.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;r=n}a.nextZ=null,c*=2}while(o>1);return e}function p(e,t,r,n,i){return e=32767*(e-r)/i,t=32767*(t-n)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function E(e){var t=e,r=e;do{t.x<r.x&&(r=t),t=t.next}while(t!==e);return r}function m(e,t,r,n,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(n-u)-(r-o)*(t-u)>=0&&(r-o)*(a-u)-(i-o)*(n-u)>=0}function y(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!R(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function _(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function v(e,t){return e.x===t.x&&e.y===t.y}function T(e,t,r,n){return!!(v(e,t)&&v(r,n)||v(e,n)&&v(r,t))||_(e,t,r)>0!=_(e,t,n)>0&&_(r,n,e)>0!=_(r,n,t)>0}function R(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&T(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function S(e,t){var r=e,n=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{r.y>a!=r.next.y>a&&i<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==e);return n}function g(e,t){var r=new I(e.i,e.x,e.y),n=new I(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,r.next=i,i.prev=r,n.next=r,r.prev=n,a.next=n,n.prev=a,n}function N(e,t,r,n){var i=new I(e,t,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function x(e,t,r,n){for(var i=0,a=t,o=r-n;a<r;a+=n)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,r,n){var i=t&&t.length,a=i?t[0]*r:e.length,o=Math.abs(x(e,0,a,r));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*r,l=u<s-1?t[u+1]*r:e.length;o-=Math.abs(x(e,c,l,r))}var f=0;for(u=0;u<n.length;u+=3){var h=n[u]*r,d=n[u+1]*r,p=n[u+2]*r;f+=Math.abs((e[h]-e[p])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[p+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,r={vertices:[],holes:[],dimensions:t},n=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)r.vertices.push(e[i][a][o]);i>0&&(n+=e[i-1].length,r.holes.push(n))}return r},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===r.CLOCKWISE||e===r.COUNTER_CLOCKWISE}};return e(r)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";var d=new r,p=new r,E={};E.computeArea2D=function(e){for(var t=e.length,r=0,n=t-1,i=0;i<t;n=i++){var a=e[n],o=e[i];r+=a.x*o.y-o.x*a.y}return.5*r},E.computeWindingOrder2D=function(e){return E.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},E.triangulate=function(r,n){var i=t.packArray(r);return e(i,n,2)};var m=new r,y=new r,_=new r,v=new r,T=new r,R=new r,A=new r;return E.computeSubdivision=function(e,t,n,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=n.slice(0),p=t.length,E=new Array(3*p),S=0;for(h=0;h<p;h++){var g=t[h];E[S++]=g.x,E[S++]=g.y,E[S++]=g.z}for(var N=[],O={},I=e.maximumRadius,x=l.chordLength(u,I),w=x*x;d.length>0;){var M,C,P=d.pop(),D=d.pop(),L=d.pop(),U=r.fromArray(E,3*L,m),b=r.fromArray(E,3*D,y),F=r.fromArray(E,3*P,_),B=r.multiplyByScalar(r.normalize(U,v),I,v),z=r.multiplyByScalar(r.normalize(b,T),I,T),q=r.multiplyByScalar(r.normalize(F,R),I,R),G=r.magnitudeSquared(r.subtract(B,z,A)),W=r.magnitudeSquared(r.subtract(z,q,A)),V=r.magnitudeSquared(r.subtract(q,B,A)),X=Math.max(G,W,V);X>w?G===X?(M=Math.min(L,D)+" "+Math.max(L,D),h=O[M],o(h)||(C=r.add(U,b,A),r.multiplyByScalar(C,.5,C),E.push(C.x,C.y,C.z),h=E.length/3-1,O[M]=h),d.push(L,h,P),d.push(h,D,P)):W===X?(M=Math.min(D,P)+" "+Math.max(D,P),h=O[M],o(h)||(C=r.add(b,F,A),r.multiplyByScalar(C,.5,C),E.push(C.x,C.y,C.z),h=E.length/3-1,O[M]=h),d.push(D,h,L),d.push(h,P,L)):V===X&&(M=Math.min(P,L)+" "+Math.max(P,L),h=O[M],o(h)||(C=r.add(F,U,A),r.multiplyByScalar(C,.5,C),E.push(C.x,C.y,C.z),h=E.length/3-1,O[M]=h),d.push(P,h,D),d.push(h,L,D)):(N.push(L),N.push(D),N.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:E})},indices:N,primitiveType:f.TRIANGLES})},E.scaleToGeodeticHeight=function(e,t,n,i){n=a(n,u.WGS84);var s=d,c=p;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)r.fromArray(e,f,c),i&&(c=n.scaleToGeodeticSurface(c,c)),0!==t&&(s=n.geodeticSurfaceNormal(c,s),r.multiplyByScalar(s,t,s),r.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},E}),define("Core/Queue",["./defineProperties"],function(e){"use strict";function t(){this._array=[],this._offset=0,this._length=0}return e(t.prototype,{length:{get:function(){return this._length}}}),t.prototype.enqueue=function(e){this._array.push(e),this._length++},t.prototype.dequeue=function(){if(0!==this._length){var e=this._array,t=this._offset,r=e[t];return e[t]=void 0,t++,t>10&&2*t>e.length&&(this._array=e.slice(t),t=0),this._offset=t,this._length--,r}},t.prototype.peek=function(){if(0!==this._length)return this._array[this._offset]},t.prototype.contains=function(e){return-1!==this._array.indexOf(e)},t.prototype.clear=function(){this._array.length=this._offset=this._length=0},t.prototype.sort=function(e){this._offset>0&&(this._array=this._array.slice(this._offset),this._offset=0),this._array.sort(e)},t}),define("Core/PolygonGeometryLibrary",["./arrayRemoveDuplicates","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,E){"use strict";function m(e,r,n,i){return t.subtract(r,e,_),t.multiplyByScalar(_,n/i,_),t.add(e,_,_),[_.x,_.y,_.z]}var y={};y.computeHierarchyPackedLength=function(e){for(var r=0,n=[e];n.length>0;){var a=n.pop();if(i(a)){r+=2;var o=a.positions,u=a.holes;if(i(o)&&(r+=o.length*t.packedLength),i(u))for(var s=u.length,c=0;c<s;++c)n.push(u[c])}}return r},y.packPolygonHierarchy=function(e,r,n){for(var a=[e];a.length>0;){var o=a.pop();if(i(o)){var u=o.positions,s=o.holes;if(r[n++]=i(u)?u.length:0,r[n++]=i(s)?s.length:0,i(u))for(var c=u.length,l=0;l<c;++l,n+=3)t.pack(u[l],r,n);if(i(s))for(var f=s.length,h=0;h<f;++h)a.push(s[h])}}return n},y.unpackPolygonHierarchy=function(e,r){for(var n=e[r++],i=e[r++],a=new Array(n),o=i>0?new Array(i):void 0,u=0;u<n;++u,r+=t.packedLength)a[u]=t.unpack(e,r);for(var s=0;s<i;++s)o[s]=y.unpackPolygonHierarchy(e,r),r=o[s].startingIndex,delete o[s].startingIndex;return{positions:a,holes:o,startingIndex:r}};var _=new t;y.subdivideLineCount=function(e,r,n){var i=t.distance(e,r),a=i/n,o=Math.max(0,Math.ceil(Math.log(a)/Math.log(2)));return Math.pow(2,o)},y.subdivideLine=function(e,r,n,a){var o=y.subdivideLineCount(e,r,n),u=t.distance(e,r),s=u/o;i(a)||(a=[]);var c=a;c.length=3*o;for(var l=0,f=0;f<o;f++){var h=m(e,r,f*s,u);c[l++]=h[0],c[l++]=h[1],c[l++]=h[2]}return c};var v=new t,T=new t,R=new t,A=new t;y.scaleToGeodeticHeightExtruded=function(e,r,o,u,s){u=n(u,a.WGS84);var c=v,l=T,f=R,h=A;if(i(e)&&i(e.attributes)&&i(e.attributes.position))for(var d=e.attributes.position.values,p=d.length/2,E=0;E<p;E+=3)t.fromArray(d,E,f),u.geodeticSurfaceNormal(f,c),h=u.scaleToGeodeticSurface(f,h),l=t.multiplyByScalar(c,o,l),l=t.add(h,l,l),d[E+p]=l.x,d[E+1+p]=l.y,d[E+2+p]=l.z,s&&(h=t.clone(f,h)), -l=t.multiplyByScalar(c,r,l),l=t.add(h,l,l),d[E]=l.x,d[E+1]=l.y,d[E+2]=l.z;return e},y.polygonsFromHierarchy=function(r,n,a,o){var u=[],s=[],c=new p;for(c.enqueue(r);0!==c.length;){var l=c.dequeue(),f=l.positions,d=l.holes;if(f=e(f,t.equalsEpsilon,!0),!(f.length<3)){var m=a.projectPointsOntoPlane(f),y=[],_=h.computeWindingOrder2D(m);_===E.CLOCKWISE&&(m.reverse(),f=f.slice().reverse());var v,T,R=f.slice(),A=i(d)?d.length:0,S=[];for(v=0;v<A;v++){var g=d[v],N=e(g.positions,t.equalsEpsilon,!0);if(!(N.length<3)){var O=a.projectPointsOntoPlane(N);_=h.computeWindingOrder2D(O),_===E.CLOCKWISE&&(O.reverse(),N=N.slice().reverse()),S.push(N),y.push(R.length),R=R.concat(N),m=m.concat(O);var I=0;for(i(g.holes)&&(I=g.holes.length),T=0;T<I;T++)c.enqueue(g.holes[T])}}if(!n){for(v=0;v<f.length;v++)o.scaleToGeodeticSurface(f[v],f[v]);for(v=0;v<S.length;v++){var x=S[v];for(T=0;T<x.length;++T)o.scaleToGeodeticSurface(x[T],x[T])}}u.push({outerRing:f,holes:S}),s.push({positions:R,positions2D:m,holes:y})}}return{hierarchy:u,polygons:s}},y.createGeometryFromPositions=function(e,t,n,i,a){var s=h.triangulate(t.positions2D,t.holes);s.length<3&&(s=[0,1,2]);var l=t.positions;if(i){for(var f=l.length,p=new Array(3*f),E=0,m=0;m<f;m++){var y=l[m];p[E++]=y.x,p[E++]=y.y,p[E++]=y.z}var _=new o({attributes:{position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:p})},indices:s,primitiveType:d.TRIANGLES});return a.normal?c.computeNormal(_):_}return h.computeSubdivision(e,l,s,n)};var S=[],g=new t,N=new t;return y.computeWallGeometry=function(e,n,i,a){var c,h,p,E,m,_=e.length,v=0;if(a)for(h=3*_*2,c=new Array(2*h),p=0;p<_;p++)E=e[p],m=e[(p+1)%_],c[v]=c[v+h]=E.x,++v,c[v]=c[v+h]=E.y,++v,c[v]=c[v+h]=E.z,++v,c[v]=c[v+h]=m.x,++v,c[v]=c[v+h]=m.y,++v,c[v]=c[v+h]=m.z,++v;else{var T=f.chordLength(i,n.maximumRadius),R=0;for(p=0;p<_;p++)R+=y.subdivideLineCount(e[p],e[(p+1)%_],T);for(h=3*(R+_),c=new Array(2*h),p=0;p<_;p++){E=e[p],m=e[(p+1)%_];for(var A=y.subdivideLine(E,m,T,S),O=A.length,I=0;I<O;++I,++v)c[v]=A[I],c[v+h]=A[I];c[v]=m.x,c[v+h]=m.x,++v,c[v]=m.y,c[v+h]=m.y,++v,c[v]=m.z,c[v+h]=m.z,++v}}_=c.length;var x=l.createTypedArray(_/3,_-6*e.length),w=0;for(_/=6,p=0;p<_;p++){var M=p,C=M+1,P=M+_,D=P+1;E=t.fromArray(c,3*M,g),m=t.fromArray(c,3*C,N),t.equalsEpsilon(E,m,f.EPSILON14)||(x[w++]=M,x[w++]=P,x[w++]=C,x[w++]=C,x[w++]=P,x[w++]=D)}return new o({attributes:new s({position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:c})}),indices:x,primitiveType:d.TRIANGLES})},y}),define("Core/PolygonOutlineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./PolygonGeometryLibrary","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,E,m,y,_,v,T,R){"use strict";function A(e,t,r,n){var a=c.fromPoints(t,e),o=a.projectPointsOntoPlane(t,N);_.computeWindingOrder2D(o)===R.CLOCKWISE&&(o.reverse(),t=t.slice().reverse());var u,s,p=t.length,m=0;if(n)for(u=new Float64Array(2*p*3),s=0;s<p;s++){var T=t[s],A=t[(s+1)%p];u[m++]=T.x,u[m++]=T.y,u[m++]=T.z,u[m++]=A.x,u[m++]=A.y,u[m++]=A.z}else{var S=0;for(s=0;s<p;s++)S+=y.subdivideLineCount(t[s],t[(s+1)%p],r);for(u=new Float64Array(3*S),s=0;s<p;s++)for(var g=y.subdivideLine(t[s],t[(s+1)%p],r,O),I=g.length,x=0;x<I;++x)u[m++]=g[x]}p=u.length/3;var w=2*p,M=E.createTypedArray(p,w);for(m=0,s=0;s<p-1;s++)M[m++]=s,M[m++]=s+1;return M[m++]=p-1,M[m++]=0,new d({geometry:new l({attributes:new h({position:new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:u})}),indices:M,primitiveType:v.LINES})})}function S(e,t,r,n){var a=c.fromPoints(t,e),o=a.projectPointsOntoPlane(t,N);_.computeWindingOrder2D(o)===R.CLOCKWISE&&(o.reverse(),t=t.slice().reverse());var u,s,p=t.length,m=new Array(p),T=0;if(n)for(u=new Float64Array(2*p*3*2),s=0;s<p;++s){m[s]=T/3;var A=t[s],S=t[(s+1)%p];u[T++]=A.x,u[T++]=A.y,u[T++]=A.z,u[T++]=S.x,u[T++]=S.y,u[T++]=S.z}else{var g=0;for(s=0;s<p;s++)g+=y.subdivideLineCount(t[s],t[(s+1)%p],r);for(u=new Float64Array(3*g*2),s=0;s<p;++s){m[s]=T/3;for(var I=y.subdivideLine(t[s],t[(s+1)%p],r,O),x=I.length,w=0;w<x;++w)u[T++]=I[w]}}p=u.length/6;var M=m.length,C=2*(2*p+M),P=E.createTypedArray(p,C);for(T=0,s=0;s<p;++s)P[T++]=s,P[T++]=(s+1)%p,P[T++]=s+p,P[T++]=(s+1)%p+p;for(s=0;s<M;s++){var D=m[s];P[T++]=D,P[T++]=D+p}return new d({geometry:new l({attributes:new h({position:new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:u})}),indices:P,primitiveType:v.LINES})})}function g(e){var t=e.polygonHierarchy,r=a(e.ellipsoid,s.WGS84),n=a(e.granularity,m.RADIANS_PER_DEGREE),i=a(e.height,0),u=a(e.perPositionHeight,!1),c=e.extrudedHeight,l=o(c);if(l&&!u){var f=c;c=Math.min(f,i),i=Math.max(f,i)}this._ellipsoid=s.clone(r),this._granularity=n,this._height=i,this._extrudedHeight=a(c,0),this._extrude=l,this._polygonHierarchy=t,this._perPositionHeight=u,this._workerName="createPolygonOutlineGeometry",this.packedLength=y.computeHierarchyPackedLength(t)+s.packedLength+6}var N=[],O=[];g.pack=function(e,t,r){return r=a(r,0),r=y.packPolygonHierarchy(e._polygonHierarchy,t,r),s.pack(e._ellipsoid,t,r),r+=s.packedLength,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._granularity,t[r++]=e._extrude?1:0,t[r++]=e._perPositionHeight?1:0,t[r++]=e.packedLength,t};var I=s.clone(s.UNIT_SPHERE),x={polygonHierarchy:{}};return g.unpack=function(e,t,r){t=a(t,0);var n=y.unpackPolygonHierarchy(e,t);t=n.startingIndex,delete n.startingIndex;var i=s.unpack(e,t,I);t+=s.packedLength;var u=e[t++],c=e[t++],l=e[t++],f=1===e[t++],h=1===e[t++],d=e[t++];return o(r)||(r=new g(x)),r._polygonHierarchy=n,r._ellipsoid=s.clone(i,r._ellipsoid),r._height=u,r._extrudedHeight=c,r._granularity=l,r._extrude=f,r._perPositionHeight=h,r.packedLength=d,r},g.fromPositions=function(e){return e=a(e,a.EMPTY_OBJECT),new g({polygonHierarchy:{positions:e.positions},height:e.height,extrudedHeight:e.extrudedHeight,ellipsoid:e.ellipsoid,granularity:e.granularity,perPositionHeight:e.perPositionHeight})},g.createGeometry=function(n){var i=n._ellipsoid,a=n._granularity,u=n._height,s=n._extrudedHeight,c=n._extrude,f=n._polygonHierarchy,h=n._perPositionHeight,d=[],E=new T;E.enqueue(f);for(var v;0!==E.length;){var R=E.dequeue(),g=R.positions;if(g=e(g,r.equalsEpsilon,!0),!(g.length<3)){var N=R.holes?R.holes.length:0;for(v=0;v<N;v++){var O=R.holes[v];if(O.positions=e(O.positions,r.equalsEpsilon,!0),!(O.positions.length<3)){d.push(O.positions);var I=0;o(O.holes)&&(I=O.holes.length);for(var x=0;x<I;x++)E.enqueue(O.holes[x])}}d.push(g)}}if(0!==d.length){var w,M=[],C=m.chordLength(a,i.maximumRadius);if(c)for(v=0;v<d.length;v++)w=S(i,d[v],C,h),w.geometry=y.scaleToGeodeticHeightExtruded(w.geometry,u,s,i,h),M.push(w);else for(v=0;v<d.length;v++)w=A(i,d[v],C,h),w.geometry.attributes.position.values=_.scaleToGeodeticHeight(w.geometry.attributes.position.values,u,i,!h),M.push(w);w=p.combineInstances(M)[0];var P=t.fromVertices(w.attributes.position.values);return new l({attributes:w.attributes,indices:w.indices,primitiveType:w.primitiveType,boundingSphere:P})}},g}),define("Workers/createPolygonOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolygonOutlineGeometry"],function(e,t,r){"use strict";function n(n,i){return e(i)&&(n=r.unpack(n,i)),n._ellipsoid=t.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(n,i){if(!e(i))throw new t(r(n))},i.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},i.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},i.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},i.typeOf.number.lessThan=function(e,r,n){if(i.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},i.typeOf.number.lessThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},i.typeOf.number.greaterThan=function(e,r,n){if(i.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},i.typeOf.number.greaterThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},i.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},i.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},i.typeOf.number.equals=function(e,r,n,a){if(i.typeOf.number(e,n),i.typeOf.number(r,a),n!==a)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*i.clamp(e,-1,1)+.5)*r)},i.fromSNorm=function(e,r){return r=t(r,255),i.clamp(e,0,r)/r*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,r){return(1-r)*e+r*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,r,n,i){i=t(i,n);var a=Math.abs(e-r);return a<=i||a<=n*Math.max(Math.abs(e),Math.abs(r))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var r=a[t-1],n=t;n<=e;n++)a.push(r*n);return a[e]},i.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return n.x=s*Math.cos(i),n.y=s*Math.sin(i),n.z=u*Math.cos(a),n},o.fromElements=function(e,t,n,i){return r(i)?(i.x=e,i.y=t,i.z=n,i):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var i=0;i<n;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var i=0;i<n;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)},o.cross=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-n*s,f=n*u-i*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,r,n,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,i,a,u){i=t(i,0);var s=r(a)?a.radiiSquared:p,c=Math.cos(n);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(n),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),r(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function i(r,i,u,s,c){var l=r.x,f=r.y,h=r.z,d=i.x,p=i.y,y=i.z,m=l*l*d*d,E=f*f*p*p,_=h*h*y*y,v=m+E+_,T=Math.sqrt(1/v),R=e.multiplyByScalar(r,T,a);if(v<s)return isFinite(T)?e.clone(R,c):void 0;var A=u.x,S=u.y,g=u.z,O=o;O.x=R.x*A*2,O.y=R.y*S*2,O.z=R.z*g*2;var N,I,w,x,M,C,P,D,U,b,L,F=(1-T)*e.magnitude(r)/(.5*e.magnitude(O)),B=0;do{F-=B,w=1/(1+F*A),x=1/(1+F*S),M=1/(1+F*g),C=w*w,P=x*x,D=M*M,U=C*w,b=P*x,L=D*M,N=m*C+E*P+_*D-1,I=m*U*A+E*b*S+_*L*g;B=N/(-2*I)}while(Math.abs(N)>n.EPSILON12);return t(c)?(c.x=l*w,c.y=f*x,c.z=h*M,c):new e(l*w,f*x,h*M)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,i,a){return i=r(i,0),n(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,r,n){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,r,i){var p=n(r)?r.oneOverRadii:f,y=n(r)?r.oneOverRadiiSquared:h,m=n(r)?r._centerToleranceSquared:d,E=o(t,p,y,m,c);if(n(E)){var _=e.multiplyComponents(E,y,s);_=e.normalize(_,_);var v=e.subtract(t,E,l),T=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=a.sign(e.dot(v,t))*e.magnitude(v);return n(i)?(i.longitude=T,i.latitude=R,i.height=A,i):new u(T,R,A)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t,r,i,a){r=n(r,0),i=n(i,0),a=n(a,0),t._radii=new e(r,i,a),t._radiiSquared=new e(r*r,i*i,a*a),t._radiiToTheFourth=new e(r*r*r*r,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===r?0:1/r,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(r,i,a),t._maximumRadius=Math.max(r,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(i(t)){var n=t._radii;return i(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,i){return i=n(i,0),e.pack(t._radii,r,i),r},f.unpack=function(t,r,i){r=n(r,0);var a=e.unpack(t,r);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(a);return i(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return i(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,r){var n=h,a=d;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,a);var o=Math.sqrt(e.dot(n,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(n,t.height,n),i(r)||(r=new e),e.add(a,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var p=new e,y=new e,m=new e;return f.prototype.cartesianToCartographic=function(r,n){var a=this.scaleToGeodeticSurface(r,y);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(r,a,m),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return i(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){i(r)||(r=new e);var n=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,a){r=n(r,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-r))return a},f}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,r,n){"use strict";function i(e,n,i){if(r(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!n(s,c,a));++u);if(u===o)return i&&n(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],n(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&n(l[0],l[l.length-1],a)&&l.shift(),l}}var a=n.EPSILON10;return i}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,i,a,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return n(r)?(r.x=a,r.y=o,r.z=u,r):new e(a,o,u)},u.prototype.unproject=function(e,r){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return n(r)?(r.longitude=a,r.latitude=o,r.height=u,r):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i,a,o,u,s,c){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(a,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(y[r],p[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(y[a],p[a])]);o>n&&(i=a,n=o)}var c=1,l=0,f=p[i],h=y[i];if(Math.abs(e[s.getElementIndex(h,f)])>r){var d,m=e[s.getElementIndex(h,h)],E=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],v=(m-E)/2/_;d=v<0?-1/(-v+Math.sqrt(1+v*v)):1/(v+Math.sqrt(1+v*v)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=r-u-f+d,y=2*(i-h),m=2*(a+l),E=2*(i+h),_=-r+u-f+d,v=2*(c-o),T=2*(a-l),R=2*(c+o),A=-r-u+f+d;return n(t)?(t[0]=p,t[1]=E,t[2]=T,t[3]=y,t[4]=_,t[5]=R,t[6]=m,t[7]=v,t[8]=A,t):new s(p,y,m,E,_,v,T,R,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=r*u,p=a*i+c*o*u,y=-c*i+a*o*u,m=-o,E=c*r,_=a*r;return n(t)?(t[0]=l,t[1]=d,t[2]=m,t[3]=f,t[4]=p,t[5]=E,t[6]=h,t[7]=y,t[8]=_,t):new s(l,f,h,d,p,y,m,E,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=i,t[6]=0,t[7]=-i,t[8]=r,t):new s(1,0,0,0,r,-i,0,i,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=r,t):new s(r,0,i,0,1,0,-i,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=i,t[2]=0,t[3]=-i,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-i,0,i,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,i=e[n],a=e[n+1],o=e[n+2];return r.x=i,r.y=a,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var i=3*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],i=e[t+3],a=e[t+6];return r.x=n,r.y=i,r.z=a,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var h=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=i,r[2]=a,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[3]*i+e[6]*a,u=e[1]*n+e[4]*i+e[7]*a,s=e[2]*n+e[5]*i+e[8]*a;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],y=[2,2,1],m=new s,E=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,i=0,a=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=r*c(h);a<10&&l(h)>d;)f(h,m),s.transpose(m,E),s.multiply(h,m,h),s.multiply(E,h,h),s.multiply(o,m,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*n-r*c)+u*(r*o-a*n)},s.inverse=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-n*f,t[2]=n*u-o*i,t[3]=c*u-a*f,t[4]=r*f-c*i,t[5]=a*i-r*u,t[6]=a*l-c*o,t[7]=c*n-r*l,t[8]=r*o-a*n;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n,i){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(i,0)}o.fromElements=function(e,t,n,i,a){return r(a)?(a.x=e,a.y=t,a.z=n,a.w=i,a):new o(e,t,n,i)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n++],i.w=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var i=0;i<n;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var i=0;i<n;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)&&a.equalsEpsilon(e.w,t.w,n,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)), +o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t,r,i,a,o,u,s,c,l,f,h,d,p,y,m){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(c,0),this[3]=n(d,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(p,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(y,0),this[12]=n(i,0),this[13]=n(s,0),this[14]=n(h,0),this[15]=n(m,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,a){return r=n(r,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=r.x,a[13]=r.y,a[14]=r.z,a[15]=1,a):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){i(n)||(n=new l);var a=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,y=t.y*t.w,m=t.z*t.z,E=t.z*t.w,_=t.w*t.w,v=s-d-m+_,T=2*(c-E),R=2*(f+y),A=2*(c+E),S=-s+d-m+_,g=2*(p-h),O=2*(f-y),N=2*(p+h),I=-s-d+m+_;return n[0]=v*a,n[1]=A*a,n[2]=O*a,n[3]=0,n[4]=T*o,n[5]=S*o,n[6]=N*o,n[7]=0,n[8]=R*u,n[9]=g*u,n[10]=I*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,r){var n=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,y=f.y,m=f.z,E=d.x,_=d.y,v=d.z,T=n.x,R=n.y,A=n.z,S=u*-T+s*-R+c*-A,g=E*-T+_*-R+v*-A,O=p*T+y*R+m*A;return i(r)?(r[0]=u,r[1]=E,r[2]=-p,r[3]=0,r[4]=s,r[5]=_,r[6]=-y,r[7]=0,r[8]=c,r[9]=v,r[10]=-m,r[11]=0,r[12]=S,r[13]=g,r[14]=O,r[15]=1,r):new l(u,s,c,S,E,_,v,g,-p,-y,-m,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,r,n,i,a,o){var u=1/(t-e),s=1/(n-r),c=1/(a-i),l=-(t+e)*u,f=-(n+r)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,i,a,o){var u=2*i/(t-e),s=2*i/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,i,a){var o=2*i/(t-e),u=2*i/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,r,i){e=n(e,n.EMPTY_OBJECT);var a=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),h=c,d=l,p=f,y=a+c,m=o+l,E=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=y,i[13]=m,i[14]=E,i[15]=1,i},l.computeView=function(t,r,n,i,a){return a[0]=i.x,a[1]=n.x,a[2]=-r.x,a[3]=0,a[4]=i.y,a[5]=n.y,a[6]=-r.y,a[7]=0,a[8]=i.z,a[9]=n.z,a[10]=-r.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(n,t),a[14]=e.dot(r,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3];return r.x=i,r.y=a,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var i=4*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n[i+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return r.x=n,r.y=i,r.z=a,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var p=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),r};var y=new e;l.getMaximumScale=function(t){return l.getScale(t,y),e.maximumComponent(y)},l.multiply=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],y=e[12],m=e[13],E=e[14],_=e[15],v=t[0],T=t[1],R=t[2],A=t[3],S=t[4],g=t[5],O=t[6],N=t[7],I=t[8],w=t[9],x=t[10],M=t[11],C=t[12],P=t[13],D=t[14],U=t[15],b=n*v+u*T+f*R+y*A,L=i*v+s*T+h*R+m*A,F=a*v+c*T+d*R+E*A,B=o*v+l*T+p*R+_*A,z=n*S+u*g+f*O+y*N,q=i*S+s*g+h*O+m*N,G=a*S+c*g+d*O+E*N,W=o*S+l*g+p*O+_*N,V=n*I+u*w+f*x+y*M,X=i*I+s*w+h*x+m*M,H=a*I+c*w+d*x+E*M,k=o*I+l*w+p*x+_*M,Y=n*C+u*P+f*D+y*U,Z=i*C+s*P+h*D+m*U,j=a*C+c*P+d*D+E*U,K=o*C+l*P+p*D+_*U;return r[0]=b,r[1]=L,r[2]=F,r[3]=B,r[4]=z,r[5]=q,r[6]=G,r[7]=W,r[8]=V,r[9]=X,r[10]=H,r[11]=k,r[12]=Y,r[13]=Z,r[14]=j,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],y=t[0],m=t[1],E=t[2],_=t[4],v=t[5],T=t[6],R=t[8],A=t[9],S=t[10],g=t[12],O=t[13],N=t[14],I=n*y+o*m+c*E,w=i*y+u*m+l*E,x=a*y+s*m+f*E,M=n*_+o*v+c*T,C=i*_+u*v+l*T,P=a*_+s*v+f*T,D=n*R+o*A+c*S,U=i*R+u*A+l*S,b=a*R+s*A+f*S,L=n*g+o*O+c*N+h,F=i*g+u*O+l*N+d,B=a*g+s*O+f*N+p;return r[0]=I,r[1]=w,r[2]=x,r[3]=0,r[4]=M,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=U,r[10]=b,r[11]=0,r[12]=L,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],y=t[3],m=t[4],E=t[5],_=t[6],v=t[7],T=t[8],R=n*h+o*d+c*p,A=i*h+u*d+l*p,S=a*h+s*d+f*p,g=n*y+o*m+c*E,O=i*y+u*m+l*E,N=a*y+s*m+f*E,I=n*_+o*v+c*T,w=i*_+u*v+l*T,x=a*_+s*v+f*T;return r[0]=R,r[1]=A,r[2]=S,r[3]=0,r[4]=g,r[5]=O,r[6]=N,r[7]=0,r[8]=I,r[9]=w,r[10]=x,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=n*e[0]+i*e[4]+a*e[8]+e[12],u=n*e[1]+i*e[5]+a*e[9]+e[13],s=n*e[2]+i*e[6]+a*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var m=new e;l.multiplyByUniformScale=function(e,t,r){return m.x=t,m.y=t,m.z=t,l.multiplyByScale(e,m,r)},l.multiplyByScale=function(e,t,r){var n=t.x,i=t.y,a=t.z;return 1===n&&1===i&&1===a?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=i*e[4],r[5]=i*e[5],r[6]=i*e[6],r[7]=0,r[8]=a*e[8],r[9]=a*e[9],r[10]=a*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*n+e[4]*i+e[8]*a+e[12]*o,s=e[1]*n+e[5]*i+e[9]*a+e[13]*o,c=e[2]*n+e[6]*i+e[10]*a+e[14]*o,l=e[3]*n+e[7]*i+e[11]*a+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a,u=e[1]*n+e[5]*i+e[9]*a,s=e[2]*n+e[6]*i+e[10]*a;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a+e[12],u=e[1]*n+e[5]*i+e[9]*a+e[13],s=e[2]*n+e[6]*i+e[10]*a+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var E=new s,_=new s,v=new t,T=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,E),_,u.EPSILON7)&&t.equals(l.getRow(e,3,v),T))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],y=e[2],m=e[6],R=e[10],A=e[14],S=e[3],g=e[7],O=e[11],N=e[15],I=R*N,w=A*O,x=m*N,M=A*g,C=m*O,P=R*g,D=y*N,U=A*S,b=y*O,L=R*S,F=y*g,B=m*S,z=I*h+M*d+C*p-(w*h+x*d+P*p),q=w*f+D*d+L*p-(I*f+U*d+b*p),G=x*f+U*h+F*p-(M*f+D*h+B*p),W=P*f+b*h+B*d-(C*f+L*h+F*d),V=w*i+x*a+P*o-(I*i+M*a+C*o),X=I*n+U*a+b*o-(w*n+D*a+L*o),H=M*n+D*i+B*o-(x*n+U*i+F*o),k=C*n+L*i+F*a-(P*n+b*i+B*a);I=a*p,w=o*d,x=i*p,M=o*h,C=i*d,P=a*h,D=n*p,U=o*f,b=n*d,L=a*f,F=n*h,B=i*f;var Y=I*g+M*O+C*N-(w*g+x*O+P*N),Z=w*S+D*O+L*N-(I*S+U*O+b*N),j=x*S+U*g+F*N-(M*S+D*g+B*N),K=P*S+b*g+B*O-(C*S+L*g+F*O),J=x*R+P*A+w*m-(C*A+I*m+M*R),Q=b*A+I*y+U*R-(D*R+L*A+w*y),$=D*m+B*A+M*y-(F*A+x*y+U*m),ee=F*R+C*y+L*m-(b*m+B*R+P*y),te=n*z+i*q+a*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=q*te,r[2]=G*te,r[3]=W*te,r[4]=V*te,r[5]=X*te,r[6]=H*te,r[7]=k*te,r[8]=Y*te,r[9]=Z*te,r[10]=j*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-r*f-n*h-i*d,y=-a*f-o*h-u*d,m=-s*f-c*h-l*d;return t[0]=r,t[1]=a,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=y,t[14]=m,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),i=u.toRadians(r(i,0)),a=u.toRadians(r(a,0)),n(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(i,0),o.north=r(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];r=Math.min(r,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-r>o-a&&(r=a,i=o,i>u.PI&&(i-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=i,t.north=l,t):new s(r,c,i,l)},s.fromCartesianArray=function(e,t,i){t=r(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,y=e.length;p<y;p++){var m=t.cartesianToCartographic(e[p]);o=Math.min(o,m.longitude),c=Math.max(c,m.longitude),h=Math.min(h,m.latitude),d=Math.max(d,m.latitude);var E=m.longitude>=0?m.longitude:m.longitude+u.TWO_PI;l=Math.min(l,E),f=Math.max(f,E)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return n(r)?(r.west=l,r.south=h,r.east=f,r.north=d,r):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,r){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return n(r)?(r.west=i,r.south=a,r.east=o,r.north=u,r):new s(i,a,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>i||u.equalsEpsilon(r,i,u.EPSILON14))&&(r<a||u.equalsEpsilon(r,a,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=r(t,a.WGS84),i=r(i,0),n(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,y=c;y.height=i,y.longitude=p,y.latitude=f,o[l]=t.cartographicToCartesian(y,o[l]),l++,y.longitude=d,o[l]=t.cartographicToCartesian(y,o[l]),l++,y.latitude=h,o[l]=t.cartographicToCartesian(y,o[l]),l++,y.longitude=p,o[l]=t.cartographicToCartesian(y,o[l]),l++,y.latitude=f<0?f:h>0?h:0;for(var m=1;m<8;++m)y.longitude=-Math.PI+m*u.PI_OVER_TWO,s.contains(e,y)&&(o[l]=t.cartographicToCartesian(y,o[l]),l++);return 0===y.latitude&&(y.longitude=p,o[l]=t.cartographicToCartesian(y,o[l]),l++,y.longitude=d,o[l]=t.cartographicToCartesian(y,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";function d(t,r){this.center=e.clone(i(t,e.ZERO)),this.radius=i(r,0)}var p=new e,y=new e,m=new e,E=new e,_=new e,v=new e,T=new e,R=new e,A=new e,S=new e,g=new e,O=new e,N=4/3*r.PI;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],T),o=e.clone(i,p),u=e.clone(i,y),s=e.clone(i,m),c=e.clone(i,E),l=e.clone(i,_),f=e.clone(i,v),h=t.length;for(n=1;n<h;n++){e.clone(t[n],i);var N=i.x,I=i.y,w=i.z;N<o.x&&e.clone(i,o),N>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var x=e.magnitudeSquared(e.subtract(c,o,R)),M=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,U=x;M>U&&(U=M,P=u,D=l),C>U&&(U=C,P=s,D=f);var b=A;b.x=.5*(P.x+D.x),b.y=.5*(P.y+D.y),b.z=.5*(P.z+D.z);var L=e.magnitudeSquared(e.subtract(D,b,R)),F=Math.sqrt(L),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,R),.5,O),G=0;for(n=0;n<h;n++){e.clone(t[n],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var V=e.magnitudeSquared(e.subtract(i,b,R));if(V>L){var X=Math.sqrt(V);F=.5*(F+X),L=F*F;var H=X-F;b.x=(F*b.x+H*i.x)/X,b.y=(F*b.y+H*i.y)/X,b.z=(F*b.z+H*i.z)/X}}return F<G?(e.clone(b,r.center),r.radius=F):(e.clone(q,r.center),r.radius=G),r};var I=new u,w=new e,x=new e,M=new t,C=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,n,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=i(r,I),h.southwest(t,M),M.height=n,h.northeast(t,C),C.height=o;var s=r.project(M,w),c=r.project(C,x),l=c.x-s.x,f=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+p*p);var y=u.center;return y.x=s.x+.5*l,y.y=s.y+.5*f,y.z=s.z+.5*p,u};var P=[];d.fromRectangle3D=function(t,r,n,u){if(r=i(r,o.WGS84),n=i(n,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,r,n,P);return d.fromPoints(s,u)},d.fromVertices=function(t,r,n,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=i(r,e.ZERO),n=i(n,3);var u=T;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,p),l=e.clone(u,y),f=e.clone(u,m),h=e.clone(u,E),N=e.clone(u,_),I=e.clone(u,v),w=t.length;for(s=0;s<w;s+=n){var x=t[s]+r.x,M=t[s+1]+r.y,C=t[s+2]+r.z;u.x=x,u.y=M,u.z=C,x<c.x&&e.clone(u,c),x>h.x&&e.clone(u,h),M<l.y&&e.clone(u,l),M>N.y&&e.clone(u,N),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(h,c,R)),D=e.magnitudeSquared(e.subtract(N,l,R)),U=e.magnitudeSquared(e.subtract(I,f,R)),b=c,L=h,F=P;D>F&&(F=D,b=l,L=N),U>F&&(F=U,b=f,L=I);var B=A;B.x=.5*(b.x+L.x),B.y=.5*(b.y+L.y),B.z=.5*(b.z+L.z);var z=e.magnitudeSquared(e.subtract(L,B,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=g;W.x=h.x,W.y=N.y,W.z=I.z;var V=e.multiplyByScalar(e.add(G,W,R),.5,O),X=0;for(s=0;s<w;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,V,R));H>X&&(X=H);var k=e.magnitudeSquared(e.subtract(u,B,R));if(k>z){var Y=Math.sqrt(k);q=.5*(q+Y),z=q*q;var Z=Y-q;B.x=(q*B.x+Z*u.x)/Y,B.y=(q*B.y+Z*u.y)/Y,B.z=(q*B.z+Z*u.z)/Y}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(V,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=T;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,p),s=e.clone(i,y),c=e.clone(i,m),l=e.clone(i,E),f=e.clone(i,_),h=e.clone(i,v),N=t.length;for(o=0;o<N;o+=3){var I=t[o]+r[o],w=t[o+1]+r[o+1],x=t[o+2]+r[o+2];i.x=I,i.y=w,i.z=x,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),x<c.z&&e.clone(i,c),x>h.z&&e.clone(i,h)}var M=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(h,c,R)),D=u,U=l,b=M;C>b&&(b=C,D=s,U=f),P>b&&(b=P,D=c,U=h);var L=A;L.x=.5*(D.x+U.x),L.y=.5*(D.y+U.y),L.z=.5*(D.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,O),W=0;for(o=0;o<N;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var V=e.magnitude(e.subtract(i,G,R));V>W&&(W=V);var X=e.magnitudeSquared(e.subtract(i,L,R));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var k=H-B;L.x=(B*L.x+k*i.x)/H,L.y=(B*L.y+k*i.y)/H,L.z=(B*L.z+k*i.z)/H}}return B<W?(e.clone(L,n.center),n.radius=B):(e.clone(G,n.center),n.radius=W),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var D=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,D)+c.radius)}return r.radius=s,r};var U=new e,b=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=l.getColumn(n,0,U),o=l.getColumn(n,1,b),u=l.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=i(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=i(t,0),a(r)||(r=new d);var n=r.center;return n.x=e[t++],n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var F=new e,B=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,F),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var z=new e;d.expand=function(t,r,n){n=d.clone(t,n);var i=e.magnitude(e.subtract(r,n.center,z));return i>n.radius&&(n.radius=i),n},d.intersectPlane=function(t,r){var n=t.center,i=t.radius,a=r.normal,o=e.dot(a,n)+r.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=f.getMaximumScale(t)*e.radius,r};var q=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,q);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var G=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new c);var o=e.subtract(t.center,r,G),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var W=new e,V=new e,X=new e,H=new e,k=new e,Y=new t,Z=new Array(8),j=0;j<8;++j)Z[j]=new e;var K=new u;return d.projectTo2D=function(t,r,n){r=i(r,K);var a=r.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,W),c=e.cross(e.UNIT_Z,s,V);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,k),h=e.negate(c,H),p=Z,y=p[0];e.add(s,l,y),e.add(y,c,y),y=p[1],e.add(s,l,y),e.add(y,h,y),y=p[2],e.add(s,f,y),e.add(y,h,y),y=p[3],e.add(s,f,y),e.add(y,c,y),e.negate(s,s),y=p[4],e.add(s,l,y),e.add(y,c,y),y=p[5],e.add(s,l,y),e.add(y,h,y),y=p[6],e.add(s,f,y),e.add(y,h,y),y=p[7],e.add(s,f,y),e.add(y,c,y);for(var m=p.length,E=0;E<m;++E){var _=p[E];e.add(o,_,_);var v=a.cartesianToCartographic(_,Y);r.project(v,_)}n=d.fromPoints(p,n),o=n.center;var T=o.x,R=o.y,A=o.z;return o.x=A,o.y=T,o.z=R,n},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return N*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(n.requestFullscreen=i,r=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(n.requestFullscreen=i,r=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?n.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(n.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?n.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(n.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?n.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(n.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),n.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),n.fullscreenerror=i)}return r},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[n.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){ +for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(R=!0,A=n(e[1]))}return R}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(T.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(S=!0,g=n(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(T.userAgent);null!==e&&(O=!0,N=n(e[1]),N.isNightly=!!e[2])}return O}function c(){return s()&&N}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===T.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(I=!0,w=n(e[1])):"Netscape"===T.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(I=!0,w=n(e[1]))}return I}function f(){return l()&&w}function h(){if(!t(x)){x=!1;var e=/ Edge\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(x=!0,M=n(e[1]))}return x}function d(){return h()&&M}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function y(){return t(D)||(D=/Windows/i.test(T.appVersion)),D}function m(){return p()&&P}function E(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(T.pointerEnabled)||T.pointerEnabled)),U}function _(){if(!t(L)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;L=t(r)&&""!==r,L&&(b=r)}return L}function v(){return _()?b:void 0}var T;T="undefined"!=typeof navigator?navigator:{};var R,A,S,g,O,N,I,w,x,M,C,P,D,U,b,L,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:m,isWindows:y,hardwareConcurrency:e(T.hardwareConcurrency,3),supportsPointerEvents:E,supportsImageRenderingPixelated:_,imageRenderingValue:v};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,i,a){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,i){switch(n=e(n,0),i=e(i,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,i);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,i);case o.SHORT:return new Int16Array(r,n,i);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,i);case o.INT:return new Int32Array(r,n,i);case o.UNSIGNED_INT:return new Uint32Array(r,n,i);case o.FLOAT:return new Float32Array(r,n,i);case o.DOUBLE:return new Float64Array(r,n,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,r,n,i){"use strict";function a(t,i,a){this.minimum=e.clone(r(t,e.ZERO)),this.maximum=e.clone(r(i,e.ZERO)),n(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,r){if(n(r)||(r=new a),!n(t)||0===t.length)return r.minimum=e.clone(e.ZERO,r.minimum),r.maximum=e.clone(e.ZERO,r.maximum),r.center=e.clone(e.ZERO,r.center),r;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],p=d.x,y=d.y,m=d.z;i=Math.min(p,i),s=Math.max(p,s),o=Math.min(y,o),c=Math.max(y,c),u=Math.min(m,u),l=Math.max(m,l)}var E=r.minimum;E.x=i,E.y=o,E.z=u;var _=r.maximum;_.x=s,_.y=c,_.z=l;var v=e.add(E,_,r.center);return e.multiplyByScalar(v,.5,v),r},a.clone=function(t,r){if(n(t))return n(r)?(r.minimum=e.clone(t.minimum,r.minimum),r.maximum=e.clone(t.maximum,r.maximum),r.center=e.clone(t.center,r.center),r):new a(t.minimum,t.maximum)},a.equals=function(t,r){return t===r||n(t)&&n(r)&&e.equals(t.center,r.center)&&e.equals(t.minimum,r.minimum)&&e.equals(t.maximum,r.maximum)};var o=new e;return a.intersectPlane=function(t,r){o=e.subtract(t.maximum,t.minimum,o);var n=e.multiplyByScalar(o,.5,o),a=r.normal,u=n.x*Math.abs(a.x)+n.y*Math.abs(a.y)+n.z*Math.abs(a.z),s=e.dot(t.center,a)+r.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var i=0;i<n;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var i=0;i<n;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var i=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(r)))<n?0:i}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,i){var a;if(0===e)return 0===n?[]:[-i/n];if(0===n){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-n/e,a<0?[a,0]:[0,a];var c=n*n,l=4*e*i,f=r(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[h/e,i/h]:[i/h,h/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var i,a,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,y=o*c-u*s,m=u*c-d,E=4*p*m-y*y;if(E<0){var _,v,T;h*f>=l*d?(_=o,v=p,T=-2*u*p+o*y):(_=c,v=m,T=-c*y+2*s*m);var R=T<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-E);a=-T+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),O=a===A?-g:-v/g;return i=v<=0?g+O:-T/(g*g+O*O+v),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var N=p,I=-2*u*p+o*y,w=m,x=-c*y+2*s*m,M=Math.sqrt(E),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*M,-I)/3);i=2*Math.sqrt(-N);var D=Math.cos(P);a=i*D;var U=i*(-D/2-C*Math.sin(P)),b=a+U>2*u?a-u:U-u,L=o,F=b/L;P=Math.abs(Math.atan2(c*M,-x)/3),i=2*Math.sqrt(-w),D=Math.cos(P),a=i*D,U=i*(-D/2-C*Math.sin(P));var B=-c,z=a+U<2*s?a+s:U+s,q=B/z,G=L*z,W=-b*z-L*B,V=b*B,X=(s*W-u*V)/(-u*W+s*G);return F<=X?F<=q?X<=q?[F,X,q]:[F,q,X]:[q,F,X]:F<=q?[X,F,q]:X<=q?[X,q,F]:[q,X,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var i=e*e,a=t*t,o=r*r;return 18*e*t*r*n+a*o-27*i*(n*n)-4*(e*o*r+a*t*n)},n.computeRealRoots=function(e,n,i,a){var o,u;if(0===e)return t.computeRealRoots(n,i,a);if(0===n){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,i,a)}return 0===i?0===a?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,a):0===a?(o=t.computeRealRoots(e,n,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,i,a)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<r.EPSILON14){var p=n.computeRealRoots(1,s,l);if(2===p.length){var y,m=p[0],E=p[1];if(m>=0&&E>=0){var _=Math.sqrt(m),v=Math.sqrt(E);return[h-v,h-_,h+_,h+v]}if(m>=0&&E<0)return y=Math.sqrt(m),[h-y,h+y];if(m<0&&E>=0)return y=Math.sqrt(E),[h-y,h+y]}return[]}if(d>0){var T=Math.sqrt(d),R=(s+d-c/T)/2,A=(s+d+c/T)/2,S=n.computeRealRoots(1,T,R),g=n.computeRealRoots(1,-T,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,y,m=d[0],E=i-m,_=E*E,v=t/2,T=E/2,R=_-4*o,A=_+4*Math.abs(o),S=c-4*m,g=c+4*Math.abs(m);if(m<0||R*g<S*A){var O=Math.sqrt(S);p=O/2,y=0===O?0:(t*T-a)/O}else{var N=Math.sqrt(R);p=0===N?0:(t*T-a)/N,y=N/2}var I,w;0===v&&0===p?(I=0,w=0):r.sign(v)===r.sign(p)?(I=v+p,w=m/I):(w=v-p,I=m/w);var x,M;0===T&&0===y?(x=0,M=0):r.sign(T)===r.sign(y)?(x=T+y,M=o/x):(M=T-y,x=o/M);var C=n.computeRealRoots(1,I,x),P=n.computeRealRoots(1,w,M);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,h=f*n,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*r*h-27*a*f*f+256*o*(d*i)+i*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*a*r*f)+d*(144*e*u*r-27*u*u-128*a*c-192*a*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return i.getPoint=function(t,n,i){return r(i)||(i=new e),i=e.multiplyByScalar(t.direction,n,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,i,a,o,u,s,c,l){"use strict";function f(e,t,r,n){var i=t*t-4*e*r;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function h(t,r,i){n(i)||(i=new a);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,y=f(h,d,p,A);if(n(y))return i.start=y.root0,i.stop=y.root1,i}function d(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function p(t,r,n,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,y=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),m=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*r.x+n,E=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),v=[];if(0===_&&0===E){if(l=s.computeRealRoots(p,y,m),0===l.length)return v;var T=l[0],R=Math.sqrt(Math.max(1-T*T,0));if(v.push(new e(i,a*T,a*-R)),v.push(new e(i,a*T,a*R)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));v.push(new e(i,a*A,a*-S)),v.push(new e(i,a*A,a*S))}return v}var g=_*_,O=E*E,N=p*p,I=_*E,w=N+O,x=2*(y*p+I),M=2*m*p+y*y-O+g,C=2*(m*y-I),P=m*m-g;if(0===w&&0===x&&0===M&&0===C)return v;l=c.computeRealRoots(w,x,M,C,P);var D=l.length;if(0===D)return v;for(var U=0;U<D;++U){var b,L=l[U],F=L*L,B=Math.max(1-F,0),z=Math.sqrt(B);b=o.sign(p)===o.sign(m)?d(p*F+m,y*L,o.EPSILON12):o.sign(m)===o.sign(y*L)?d(p*F,y*L+m,o.EPSILON12):d(p*F+y*L,m,o.EPSILON12);var q=d(E*L,_,o.EPSILON15),G=b*q;G<0?v.push(new e(i,a*L,a*z)):G>0?v.push(new e(i,a*L,a*-z)):0!==z?(v.push(new e(i,a*L,a*-z)),v.push(new e(i,a*L,a*z)),++U):v.push(new e(i,a*L,a*z))}return v}var y={};y.rayPlane=function(t,r,i){n(i)||(i=new e);var a=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var m=new e,E=new e,_=new e,v=new e,T=new e;y.rayTriangleParametric=function(t,n,i,a,u){u=r(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,y=e.subtract(i,n,m),R=e.subtract(a,n,E),A=e.cross(p,R,_),S=e.dot(y,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,n,v),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,y,T),(f=e.dot(p,c))<0||l+f>S)return;h=e.dot(R,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,n,v),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,y,T),(f=e.dot(p,c)*g)<0||l+f>1)return;h=e.dot(R,c)*g}return h},y.rayTriangle=function(t,r,i,a,o,u){var s=y.rayTriangleParametric(t,r,i,a,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;y.lineSegmentTriangle=function(t,r,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=y.rayTriangleParametric(c,i,a,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};y.raySphere=function(e,t,r){if(r=h(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var S=new l;y.lineSegmentSphere=function(t,r,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!n(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,O=new e;y.rayEllipsoid=function(t,r){var n,i,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,O),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(n=h-1,i=e.magnitudeSquared(f),o=i*n,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var y=s/i,m=n/s;return y<m?new a(y,m):{start:m,stop:y}}var E=Math.sqrt(n/i);return new a(E,E)}return h<1?(n=h-1,i=e.magnitudeSquared(f),o=i*n,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f), +new a(0,-d/i)):void 0};var N=new e,I=new e,w=new e,x=new e,M=new e,C=new u,P=new u,D=new u,U=new u,b=new u,L=new u,F=new u,B=new e,z=new e,q=new t;y.grazingAltitudeLocation=function(t,r){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=r.geodeticSurfaceNormal(i,N);if(e.dot(a,s)>=0)return i}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(a,N),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,x),d=e.normalize(e.cross(h,f,I),I),y=e.normalize(e.cross(f,d,w),w),m=C;m[0]=f.x,m[1]=f.y,m[2]=f.z,m[3]=d.x,m[4]=d.y,m[5]=d.z,m[6]=y.x,m[7]=y.y,m[8]=y.z;var E=u.transpose(m,P),_=u.fromScale(r.radii,D),v=u.fromScale(r.oneOverRadii,U),T=b;T[0]=0,T[1]=-a.z,T[2]=a.y,T[3]=a.z,T[4]=0,T[5]=-a.x,T[6]=-a.y,T[7]=a.x,T[8]=0;var R,A,S=u.multiply(u.multiply(E,v,L),T,L),g=u.multiply(u.multiply(S,_,F),m,F),O=u.multiplyByVector(S,i,M),G=p(g,e.negate(O,N),0,0,1),W=G.length;if(W>0){for(var V=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<W;++H){R=u.multiplyByVector(_,u.multiplyByVector(m,G[H],B),B);var k=e.normalize(e.subtract(R,i,x),x),Y=e.dot(k,a);Y>X&&(X=Y,V=e.clone(R,V))}var Z=r.cartesianToCartographic(V,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(V,i,x))*Math.sqrt(1-X*X),A=c?-A:A,Z.height=A,r.cartographicToCartesian(Z,new e)}};var G=new e;return y.lineSegmentPlane=function(t,r,i,a){n(a)||(a=new e);var u=e.subtract(r,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},y.trianglePlaneIntersection=function(t,r,n,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,r)+o<0,c=e.dot(a,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return y.lineSegmentPlane(t,r,i,f),y.lineSegmentPlane(t,n,i,h),{positions:[t,r,n,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return y.lineSegmentPlane(r,n,i,f),y.lineSegmentPlane(r,t,i,h),{positions:[t,r,n,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return y.lineSegmentPlane(n,t,i,f),y.lineSegmentPlane(n,r,i,h),{positions:[t,r,n,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return y.lineSegmentPlane(r,t,i,f),y.lineSegmentPlane(n,t,i,h),{positions:[t,r,n,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return y.lineSegmentPlane(n,r,i,f),y.lineSegmentPlane(t,r,i,h),{positions:[t,r,n,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return y.lineSegmentPlane(t,n,i,f),y.lineSegmentPlane(r,n,i,h),{positions:[t,r,n,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},y}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,i,a,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,i){var a=-e.dot(n,t);return r(i)?(e.clone(n,i.normal),i.distance=a,i):new u(n,a)};var s=new e;u.fromCartesian4=function(t,n){var i=e.fromCartesian4(t,s),a=t.w;return r(n)?(e.clone(i,n.normal),n.distance=a,n):new u(i,a)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,i){r(i)||(i=new e);var a=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(n,o,i)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,i){return t(e).then(r,n,i)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=i(e),t}function r(t){return e(t,a)}function n(e){this.then=e}function i(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return a(e)}})}function a(e){return new n(function(r,n){try{return n?t(n(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,r){return h(e,t,r)}function r(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new n(e),s={then:e,resolve:r,reject:i,progress:u,promise:c,resolver:{resolve:r,reject:i,progress:u}},l=[],f=[],h=function(e,t,r){var n,i;return n=o(),i="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,i)}),f.push(i),n.promise},d=function(e){return y(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=E,y(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,i,a){return m(2,arguments),e(t,function(t){function u(e){y(e)}function s(e){p(e)}var c,l,f,h,d,p,y,m,_,v;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,h=[],d=o(),c)for(m=d.progress,y=function(e){h.push(e),--l||(p=y=E,d.reject(h))},p=function(e){f.push(e),--c||(p=y=E,d.resolve(f))},v=0;v<_;++v)v in t&&e(t[v],s,u,m);else d.resolve(f);return d.then(n,i,a)})}function c(e,t,r,n){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,r,n)}function l(e,t,r,n){return m(1,arguments),h(e,_).then(t,r,n)}function f(){return h(arguments,_)}function h(t,r){return e(t,function(t){var n,i,a,u,s,c;if(a=i=t.length>>>0,n=[],c=o(),a)for(u=function(t,i){e(t,r).then(function(e){n[i]=e,--a||c.resolve(n)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(n);return c.promise})}function d(t,r){var n=T.call(arguments,1);return e(t,function(t){var i;return i=t.length,n[0]=function(t,n,a){return e(t,function(t){return e(n,function(e){return r(t,e,a,i)})})},v.apply(t,n)})}function p(t,r,n){var i=arguments.length>2;return e(t,function(e){return e=i?n:e,r.resolve(e),e},function(e){return r.reject(e),a(e)},r.progress)}function y(e,t){for(var r,n=0;r=e[n++];)r(t)}function m(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function E(){}function _(e){return e}var v,T,R;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},T=[].slice,v=[].reduce||function(e){var t,r,n,i,a;if(a=0,t=Object(this),i=t.length>>>0,r=arguments,r.length<=1)for(;;){if(a in t){n=t[a++];break}if(++a>=i)throw new TypeError}else n=r[1];for(;a<i;++a)a in t&&(n=e(n,t[a],a,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,i,a=0,o=e.length-1;a<=o;)if(n=~~((a+o)/2),(i=r(e[n],t))<0)a=n+1;else{if(!(i>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],i=function(e,t,r,n){r||(r=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+i:i+e},a=function(e,t,r,n,a,o){var u=n-e.length;return u>0&&(e=r||!a?i(e,n,o,r):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+i(c.toString(t),u||0,"0",!1),a(e,r,n,o,s)},u=function(e,t,r,n,i,o){return null!=n&&(e=e.slice(0,n)),a(e,"",t,r,i,o)},s=function(e,n,s,c,l,f,h){var d,p,y,m,E;if("%%"==e)return"%";for(var _=!1,v="",T=!1,R=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":v=" ";break;case"+":v="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":T=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,E=n?t[n.slice(0,-1)]:t[r++],h){case"s":return u(String(E),_,c,f,T,A);case"c":return u(String.fromCharCode(+E),_,c,f,T);case"b":return o(E,2,R,_,c,f,T);case"o":return o(E,8,R,_,c,f,T);case"x":return o(E,16,R,_,c,f,T);case"X":return o(E,16,R,_,c,f,T).toUpperCase();case"u":return o(E,10,R,_,c,f,T);case"i":case"d":return d=+E||0,d=Math.round(d-d%1),p=d<0?"-":v,E=p+i(String(Math.abs(d)),f,"0",!1),a(E,p,_,c,T);case"e":case"E":case"f":case"F":case"g":case"G":return d=+E,p=d<0?"-":v,y=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],m=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],E=p+Math.abs(d)[y](f),a(E,p,_,c,T)[m]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,i,a,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return y.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=y.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var i=r[n].offset;if(n>0){y.secondsDifference(r[n].julianDate,e)>i&&(n--,i=r[n].offset)}y.addSeconds(e,i,e)}function h(e,r){_.julianDate=e;var n=y.leapSeconds,i=t(n,_,l);if(i<0&&(i=~i),0===i)return y.addSeconds(e,-n[0].offset,r);if(i>=n.length)return y.addSeconds(e,-n[i-1].offset,r);var a=y.secondsDifference(n[i].julianDate,e);return 0===a?y.addSeconds(e,-n[i].offset,r):a<=1?void 0:y.addSeconds(e,-n[--i].offset,r)}function d(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function p(e,t,r,n,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=a+(n*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function y(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),n===c.UTC&&f(this)}var m=new a,E=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,v=/^(\d{4})$/,T=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+g.source,N=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;y.fromGregorianDate=function(e,t){var r=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(d(r[0],r[1],t),f(t),t):new y(r[0],r[1],c.UTC)},y.fromDate=function(e,t){var r=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(d(r[0],r[1],t),f(t),t):new y(r[0],r[1],c.UTC)},y.fromIso8601=function(e,t){e=e.replace(",",".");var r,i,a,u=e.split("T"),s=1,l=1,h=0,m=0,_=0,g=0,w=u[0],x=u[1];if(null!==(u=w.match(S)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(T)))r=+u[1],s=+u[2];else if(null!==(u=w.match(v)))r=+u[1];else{var M;if(null!==(u=w.match(R)))r=+u[1],M=+u[2],a=o(r);else if(null!==(u=w.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));M=7*C+P-D.getUTCDay()-3}i=new Date(Date.UTC(r,0,1)),i.setUTCDate(M),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(r);var U;if(n(x)){u=x.match(I),null!==u?(h=+u[1],m=+u[2],_=+u[3],g=1e3*+(u[4]||0),U=5):(u=x.match(N),null!==u?(h=+u[1],m=+u[2],_=60*+(u[3]||0),U=4):null!==(u=x.match(O))&&(h=+u[1],m=60*+(u[2]||0),U=3));var b=u[U],L=+u[U+1],F=+(u[U+2]||0);switch(b){case"+":h-=L,m-=F;break;case"-":h+=L,m+=F;break;case"Z":break;default:m+=new Date(Date.UTC(r,s-1,l,h,m)).getTimezoneOffset()}}var B=60===_;for(B&&_--;m>=60;)m-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:E[s-1];l>i;)l-=i,s++,s>12&&(s-=12,r++),i=a&&2===s?29:E[s-1];for(;m<0;)m+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),i=a&&2===s?29:E[s-1],l+=i;var z=p(r,s,l,h,m,_,g);return n(t)?(d(z[0],z[1],t),f(t)):t=new y(z[0],z[1],c.UTC),B&&y.addSeconds(t,1,t),t},y.now=function(e){return y.fromDate(new Date,e)};var w=new y(0,0,c.TAI);return y.toGregorianDate=function(e,t){var r=!1,i=h(e,w);n(i)||(y.addSeconds(e,-1,w),i=h(w,w),r=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var m=d+2-12*c|0,E=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,v=u-_*s.SECONDS_PER_HOUR,T=v/s.SECONDS_PER_MINUTE|0;v-=T*s.SECONDS_PER_MINUTE;var R=0|v,A=(v-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(R+=1),n(t)?(t.year=E,t.month=m,t.day=p,t.hour=_,t.minute=T,t.second=R,t.millisecond=A,t.isLeapSecond=r,t):new a(E,m,p,_,T,R,A,r)},y.toDate=function(e){var t=y.toGregorianDate(e,m),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},y.toIso8601=function(t,r){var i,a=y.toGregorianDate(t,m);return n(r)||0===a.millisecond?n(r)&&0!==r?(i=(.01*a.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},y.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new y(e.dayNumber,e.secondsOfDay,c.TAI)},y.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},y.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},y.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(y.secondsDifference(e,t))<=r},y.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},y.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},y.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},y.computeTaiMinusUtc=function(e){_.julianDate=e;var r=y.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},y.addSeconds=function(e,t,r){return d(e.dayNumber,e.secondsOfDay+t,r)},y.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,n,r)},y.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,n,r)},y.addDays=function(e,t,r){return d(e.dayNumber+t,e.secondsOfDay,r)},y.lessThan=function(e,t){return y.compare(e,t)<0},y.lessThanOrEquals=function(e,t){return y.compare(e,t)<=0},y.greaterThan=function(e,t){return y.compare(e,t)>0},y.greaterThanOrEquals=function(e,t){return y.compare(e,t)>=0},y.prototype.clone=function(e){return y.clone(this,e)},y.prototype.equals=function(e){return y.equals(this,e)},y.prototype.equalsEpsilon=function(e,t){return y.equalsEpsilon(this,e,t)},y.prototype.toString=function(){return y.toIso8601(this)},y.leapSeconds=[new u(new y(2441317,43210,c.TAI),10),new u(new y(2441499,43211,c.TAI),11),new u(new y(2441683,43212,c.TAI),12),new u(new y(2442048,43213,c.TAI),13),new u(new y(2442413,43214,c.TAI),14),new u(new y(2442778,43215,c.TAI),15),new u(new y(2443144,43216,c.TAI),16),new u(new y(2443509,43217,c.TAI),17),new u(new y(2443874,43218,c.TAI),18),new u(new y(2444239,43219,c.TAI),19),new u(new y(2444786,43220,c.TAI),20),new u(new y(2445151,43221,c.TAI),21),new u(new y(2445516,43222,c.TAI),22),new u(new y(2446247,43223,c.TAI),23),new u(new y(2447161,43224,c.TAI),24),new u(new y(2447892,43225,c.TAI),25),new u(new y(2448257,43226,c.TAI),26),new u(new y(2448804,43227,c.TAI),27),new u(new y(2449169,43228,c.TAI),28),new u(new y(2449534,43229,c.TAI),29),new u(new y(2450083,43230,c.TAI),30),new u(new y(2450630,43231,c.TAI),31),new u(new y(2451179,43232,c.TAI),32),new u(new y(2453736,43233,c.TAI),33),new u(new y(2454832,43234,c.TAI),34),new u(new y(2456109,43235,c.TAI),35),new u(new y(2457204,43236,c.TAI),36),new u(new y(2457754,43237,c.TAI),37)],y}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var i=new r.constructor;for(var a in r)if(r.hasOwnProperty(a)){var o=r[a];n&&(o=t(o,n)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function r(n,i,a){a=e(a,!1);var o,u,s,c={},l=t(n),f=t(i);if(l)for(o in n)n.hasOwnProperty(o)&&(u=n[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?r(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return r}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){t(i[r])||(i[r]=!0,console.warn(e(n,r)))}var i={};return n.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",n}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,r){"use strict";function n(e,t){r(e,t)}return n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(r,n,i){n=t(n,t(i.baseURI,i.location.href));var a=new e(n);return new e(r).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){var i="",a=r.lastIndexOf("/");return-1!==a&&(i=r.substring(0,a+1)),n?(r=new e(r),t(r.query)&&(i+="?"+r.query),t(r.fragment)&&(i+="#"+r.fragment),i):i}return n}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){var r=new e(t);r.normalize();var n=r.path,i=n.lastIndexOf("/");return-1!==i&&(n=n.substr(i+1)),i=n.lastIndexOf("."),n=-1===i?"":n.substr(i+1)}return n}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(r)||(r=document.createElement("a")),r.href=window.location.href;var n=r.host,i=r.protocol;return r.href=t,r.href=r.href,i!==r.protocol||n!==r.host}var r;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var i=e[n],a=encodeURIComponent(n)+"=";if(r(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return n}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(t){var n={};if(""===t)return n;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=n[s];"string"==typeof l?n[s]=[l,c]:r(l)?l.push(c):n[s]=c}return n}return n}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,n.OTHER),this.serverKey=void 0,this.state=r.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var i=r[n],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function n(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return r(n.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),n.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},n.prototype.removeEventListener=function(e,t){for(var r=this._listeners,n=this._scopes,i=-1,a=0;a<r.length;a++)if(r[a]===e&&n[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),r[i]=void 0,n[i]=void 0):(r.splice(i,1),n.splice(i,1)),!0)},n.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,r=this._listeners,n=this._scopes,a=r.length;for(e=0;e<a;e++){var o=r[e];t(o)&&r[e].apply(n[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];r.splice(s,1),n.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},n}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(i[c],i[e])<0?c:e,s<r&&n(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,n=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return r(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return a(r,e,--this._length),this.heapify(e),n}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return O[e]<f.maximumRequestsPerServer}function p(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function y(e){return function(t){e.state!==c.CANCELLED&&(--R.numberOfActiveRequests,--O[e.serverKey],I.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==c.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--O[e.serverKey],I.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function E(e){var t=p(e);return e.state=c.ACTIVE,g.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++O[e.serverKey],e.requestFunction().then(y(e)).otherwise(m(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--O[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function v(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){f.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),v())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var g=[],O={},N="undefined"!=typeof document?new e(document.location.href):new e,I=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=I,i(f,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,r=0,n=g.length;for(e=0;e<n;++e)t=g[e],t.cancelled&&_(t),t.state===c.ACTIVE?r>0&&(g[e-r]=t):++r;g.length-=r;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(E(t),++u):_(t);T()},f.getServerKey=function(t){var r=new e(t).resolve(N);r.normalize();var i=r.authority;/:/.test(i)||(i=i+":"+("https"===r.scheme?"443":"80"));var a=O[i];return n(a)||(O[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return I.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return E(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(n(t)){if(t===e)return;_(t)}return p(e)}},f.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=g.length,t=0;t<e;++t)_(g[t]);g.length=0,O={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return O[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict" +;function n(r){var n=new e(r);n.normalize();var i=n.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=n.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])||(a[n]=!0)},i.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])&&delete a[n]},i.contains=function(e){var r=n(e);return!(!t(r)||!t(a[r]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,y,m,E,_,v,T,R,A,S,g,O){"use strict";function N(e,t){var r=e.query;if(!a(r)||0===r.length)return{};var i;if(-1===r.indexOf("=")){var o={};o[r]=void 0,i=o}else i=E(r);t._queryParameters=n(t._queryParameters,i),e.query=void 0}function I(e,t){var r=t._queryParameters,n=Object.keys(r);1!==n.length||a(r[n[0]])?e.query=m(r):e.query=n[0]}function w(e,t){return a(e)?a(e.clone)?e.clone():r(e):t}function x(e){if(e.state===R.ISSUED||e.state===R.ACTIVE)throw new A("The Resource is already being fetched.");e.state=R.UNISSUED,e.deferred=void 0}function M(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=w(e.templateValues,{}),this._queryParameters=w(e.queryParameters,{}),this.headers=w(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var r=e.request;r.url=e.url,r.requestFunction=function(){var r=e.url,n=!1;e.isDataUri||e.isBlobUri||(n=e.isCrossOriginUrl);var i=O.defer();return M._Implementations.createImage(r,n&&t,i),i.promise};var n=T.request(r);if(a(n))return n.otherwise(function(n){return r.state!==R.FAILED?O.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,C(e,t)):O.reject(n)})})}function P(e,t,r){var n={};n[t]=r,e.addQueryParameters(n);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=O.defer();return window[r]=function(e){t.resolve(e);try{delete window[r]}catch(e){window[r]=void 0}},M._Implementations.loadAndExecuteScript(e.url,r,t),t.promise};var o=T.request(i);if(a(o))return o.otherwise(function(n){return i.state!==R.FAILED?O.reject(n):e.retryOnError(n).then(function(a){return a?(i.state=R.UNISSUED,i.deferred=void 0,P(e,t,r)):O.reject(n)})})}function D(e,t){x(e.request);var r=e.request;r.url=e.url,r.requestFunction=function(){var i=t.responseType,o=n(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=O.defer(),f=M._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(r.cancelFunction=function(){f.abort()}),l.promise};var i=T.request(r);if(a(i))return i.then(function(e){return e}).otherwise(function(n){return r.state!==R.FAILED?O.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,e.fetch(t)):O.reject(n)})})}function U(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function b(e,t){for(var r=U(e,t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return n}function L(e,t){t=i(t,"");var r=e[1],n=!!e[2],a=e[3];switch(t){case"":case"text":return U(n,a);case"arraybuffer":return b(n,a);case"blob":var o=b(n,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(U(n,a),r);case"json":return JSON.parse(U(n,a))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();M.createIfNeeded=function(e,t){if(e instanceof M)return e.clone();if("string"!=typeof e)return e;var r=w(t,{});return r.url=e,new M(r)},o(M,{isBlobSupported:{get:function(){return F}}}),o(M.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);N(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return y(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return p(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),M.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var r=new g(this._url);e&&I(r,this);var n=r.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];n=n.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(n=this.proxy.getURL(n)),n},M.prototype.addQueryParameters=function(e,t){this._queryParameters=t?n(this._queryParameters,e):n(e,this._queryParameters)},M.prototype.addTemplateValues=function(e,t){this._templateValues=t?n(this._templateValues,e):n(e,this._templateValues)},M.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var r=new g(e.url);N(r,t),r.fragment=void 0,t._url=r.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=n(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=n(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=n(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},M.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return O(!1);var r=this;return O(t(this,e)).then(function(e){return++r._retryCount,e})},M.prototype.clone=function(e){return a(e)||(e=new M({url:this._url})),e._url=this._url,e._queryParameters=r(this._queryParameters),e._templateValues=r(this._templateValues),e.headers=r(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},M.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},M.prototype.appendForwardSlash=function(){this._url=e(this._url)},M.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},M.fetchArrayBuffer=function(e){return new M(e).fetchArrayBuffer()},M.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},M.fetchBlob=function(e){return new M(e).fetchBlob()},M.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),x(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var r=this.fetchBlob();if(a(r)){var n,o;return r.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return n=new M({url:t}),C(n)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(n.url),e.blob=o,e}).otherwise(function(e){return a(n)&&window.URL.revokeObjectURL(n.url),O.reject(e)})}},M.fetchImage=function(e){return new M(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},M.prototype.fetchText=function(){return this.fetch({responseType:"text"})},M.fetchText=function(e){return new M(e).fetchText()},M.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},M.fetchJson=function(e){return new M(e).fetchJson()},M.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},M.fetchXML=function(e){return new M(e).fetchXML()},M.prototype.fetchJsonp=function(e){e=i(e,"callback"),x(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},M.fetchJsonp=function(e){return new M(e).fetchJsonp(e.callbackParameterName)},M.prototype.fetch=function(e){return e=w(e,i.EMPTY_OBJECT),e.method="GET",D(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return M.fetch=function(e){return new M(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},M.prototype.post=function(e,r){return t.defined("data",e),r=w(r,{}),r.method="POST",r.data=e,D(this,r)},M.post=function(e){return new M(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},M._Implementations={},M._Implementations.createImage=function(e,t,r){var n=new Image;n.onload=function(){r.resolve(n)},n.onerror=function(e){r.reject(e)},t&&(S.contains(e)?n.crossOrigin="use-credentials":n.crossOrigin=""),n.src=e},M._Implementations.loadWithXhr=function(e,t,r,n,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(L(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(r,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new v(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,r=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&r!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===r||"document"===r)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==r&&"text"!==r||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new v)},c.send(n),c},M._Implementations.loadAndExecuteScript=function(e,t,r){var n=document.createElement("script");n.async=!0,n.src=e;var i=document.getElementsByTagName("head")[0];n.onload=function(){n.onload=void 0,i.removeChild(n)},n.onerror=function(e){r.reject(e)},i.appendChild(n)},M._DefaultImplementations={},M._DefaultImplementations.createImage=M._Implementations.createImage,M._DefaultImplementations.loadWithXhr=M._Implementations.loadWithXhr,M._DefaultImplementations.loadAndExecuteScript=M._Implementations.loadAndExecuteScript,M.DEFAULT=c(new M({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),M}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))p(this,t.data);else if(n(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){p(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=r.columnNames.indexOf("modifiedJulianDateUtc"),a=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),y=r.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||p<0||y<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var m=e._samples=r.samples,E=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=y,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,v=e._addNewLeapSeconds,T=0,R=m.length;T<R;T+=e._columnCount){var A=m[T+i],S=m[T+y],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(g,S,f.TAI);if(E.push(O),v){if(S!==_&&n(_)){var N=o.leapSeconds,I=t(N,O,d);if(I<0){var w=new u(O,S);N.splice(~I,0,w)}}_=S}}}function y(e,t,r,n,i){var a=r*n;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function m(e,t,r){return t+e*(r-t)}function E(e,t,r,n,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||n.equals(c))return y(e,r,i,s,u),u;if(n.equals(l))return y(e,r,a,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=r[h+e._ut1MinusUtcSecondsColumn],E=r[d+e._ut1MinusUtcSecondsColumn],_=E-p;if(_>.5||_<-.5){var v=r[h+e._taiMinusUtcSecondsColumn],T=r[d+e._taiMinusUtcSecondsColumn];v!==T&&(l.equals(n)?p=E:E-=T-v)}return u.xPoleWander=m(f,r[h+e._xPoleWanderRadiansColumn],r[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=m(f,r[h+e._yPoleWanderRadiansColumn],r[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=m(f,r[h+e._xCelestialPoleOffsetRadiansColumn],r[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=m(f,r[h+e._yCelestialPoleOffsetRadiansColumn],r[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=m(f,p,E),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new i(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var a=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!n(h),y=p||o.greaterThanOrEquals(h,e);if(d&&y)return s=u,!p&&h.equals(e)&&++s,l=s+1,E(this,a,this._samples,e,s,l,r),r}var m=t(a,e,o.compare,this._dateColumn);return m>=0?(m<a.length-1&&a[m+1].equals(e)&&++m,s=m,l=m):(l=~m,(s=l-1)<0&&(s=0)),this._lastIndex=s,E(this,a,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,r,n,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),i=d.exec(n);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new n({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var r=f(e);return h.href=r,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=n.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){n[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(n[c]*=c-l);n[c]=1/n[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,a.daysDifference(n,e._sampleZeroDateTT)}function l(r,i){if(r._chunkDownloadsInProgress[i])return r._chunkDownloadsInProgress[i];var a=e.defer();r._chunkDownloadsInProgress[i]=a;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){r._chunkDownloadsInProgress[i]=!1;for(var t=r._samples,n=e.samples,o=i*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,r,n,i){var a=c(this,t,r),o=c(this,n,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,r){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(n(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),n(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){n(r)?(r.x=0,r.y=0,r.s=0):r=new i(0,0,0);var p,y,m=a-s*this._stepSizeDays,E=this._work,_=this._denominators,v=this._coef,T=this._xTable;for(p=0;p<=u;++p)E[p]=m-T[p];for(p=0;p<=u;++p){for(v[p]=1,y=0;y<=u;++y)y!==p&&(v[p]*=E[y]);v[p]*=_[p];var R=3*(s+p);r.x+=v[p]*d[R++],r.y+=v[p]*d[R++],r.s+=v[p]*d[R]}return r}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(i,0)}var c=new e;s.fromAxisAngle=function(t,r,i){var a=r/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return n(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],y=h+d+p;if(y>0)r=Math.sqrt(y+1),c=.5*r,r=.5/r,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var m=l,E=0;d>h&&(E=1),p>h&&p>d&&(E=2);var _=m[E],v=m[_];r=Math.sqrt(e[u.getElementIndex(E,E)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(v,v)]+1);var T=f;T[E]=.5*r,r=.5/r,c=(e[u.getElementIndex(v,_)]-e[u.getElementIndex(_,v)])*r,T[_]=(e[u.getElementIndex(_,E)]+e[u.getElementIndex(E,_)])*r,T[v]=(e[u.getElementIndex(v,E)]+e[u.getElementIndex(E,v)])*r,i=-T[0],a=-T[1],o=-T[2]}return n(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,y=new s;s.fromHeadingPitchRoll=function(t,r){return y=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(p,y,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,r,r)};var m=new e,E=new e,_=new s,v=new s,T=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,T),s.conjugate(T,T);for(var i=0,a=r-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,T,_),_.w<0&&s.negate(_,_),s.computeAxis(_,m);var u=s.computeAngle(_);n[o]=m.x*u,n[o+1]=m.y*u,n[o+2]=m.z*u}},s.unpackInterpolationResult=function(t,r,i,a,o){n(o)||(o=new s),e.fromArray(t,0,E);var u=e.magnitude(E);return s.unpack(r,4*a,v),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(E,u,_),s.multiply(_,v,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,i=e.y*r,a=e.z*r,o=e.w*r;return t.x=n,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+i*c-a*s,h=o*s-n*c+i*l+a*u,d=o*c+n*s-i*u+a*l,p=o*l-n*u-i*s-a*c;return r.x=f,r.y=h,r.z=d,r.w=p,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,r,n){return R=s.multiplyByScalar(t,r,R),n=s.multiplyByScalar(e,1-r,n),s.add(R,n,n)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,r,n){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,r,n);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-r)*u),S),g=s.multiplyByScalar(a,Math.sin(r*u),g),n=s.add(S,g,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),i=0;return 0!==n&&(i=n/Math.sin(n)),e.multiplyByScalar(t,i,r)},s.exp=function(t,r){var n=e.magnitude(t),i=0;return 0!==n&&(i=Math.sin(n)/n),r.x=t.x*i,r.y=t.y*i,r.z=t.z*i,r.w=Math.cos(n),r};var O=new e,N=new e,I=new s,w=new s;s.computeInnerQuadrangle=function(t,r,n,i){var a=s.conjugate(r,I);s.multiply(a,n,w);var o=s.log(w,O);s.multiply(a,t,w);var u=s.log(w,N);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(r,I,i)},s.squad=function(e,t,r,n,i,a){var o=s.slerp(e,t,i,I),u=s.slerp(r,n,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var x=new s,M=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],b=0;b<7;++b){var L=b+1,F=2*L+1;C[b]=1/(L*F),P[b]=L/F}return C[7]=M/136,P[7]=8*M/17,s.fastSlerp=function(e,t,r,n){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,U[f]=(C[f]*l-P[f])*o;var h=i*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),p=s.multiplyByScalar(e,d,x);return s.multiplyByScalar(t,h,n),s.add(p,n,n)},s.fastSquad=function(e,t,r,n,i,a){var o=s.fastSlerp(e,t,i,I),u=s.fastSlerp(r,n,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,y,m,E,_,v){"use strict";var T={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},O=new r,N=new r,I=new r;T.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,i=R[e][t],a=e+t;return u(S[a])?n=S[a]:(n=function(n,a,s){if(u(s)||(s=new E),y.equalsEpsilon(n.x,0,y.EPSILON14)&&y.equalsEpsilon(n.y,0,y.EPSILON14)){var c=y.sign(n.z);r.unpack(A[e],0,O),"east"!==e&&"west"!==e&&r.multiplyByScalar(O,c,O),r.unpack(A[t],0,N),"east"!==t&&"west"!==t&&r.multiplyByScalar(N,c,N),r.unpack(A[i],0,I),"east"!==i&&"west"!==i&&r.multiplyByScalar(I,c,I)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(n,g.up);var l=g.up,h=g.east;h.x=-n.y,h.y=n.x,h.z=0,r.normalize(h,g.east),r.cross(l,h,g.north),r.multiplyByScalar(g.up,-1,g.down),r.multiplyByScalar(g.east,-1,g.west),r.multiplyByScalar(g.north,-1,g.south),O=g[e],N=g[t],I=g[i]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=N.x,s[5]=N.y,s[6]=N.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},S[a]=n),n},T.eastNorthUpToFixedFrame=T.localFrameToFixedFrameGenerator("east","north"),T.northEastDownToFixedFrame=T.localFrameToFixedFrameGenerator("north","east"),T.northUpEastToFixedFrame=T.localFrameToFixedFrameGenerator("north","up"),T.northWestUpToFixedFrame=T.localFrameToFixedFrameGenerator("north","west");var w=new _,x=new r(1,1,1),M=new E;T.headingPitchRollToFixedFrame=function(e,t,n,i,a){i=o(i,T.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=E.fromTranslationQuaternionRotationScale(r.ZERO,u,x,M);return a=i(e,n,a),E.multiply(a,s,a)};var C=new E,P=new m;T.headingPitchRollQuaternion=function(e,t,r,n,i){var a=T.headingPitchRollToFixedFrame(e,t,r,n,C),o=E.getRotation(a,P);return _.fromRotationMatrix(o,i)};var D=y.TWO_PI/86400,U=new p;T.computeTemeToPseudoFixedMatrix=function(e,t){U=p.addSeconds(e,-p.computeTaiMinusUtc(e),U);var r,n=U.dayNumber,i=U.secondsOfDay,a=n-2451545;r=i>=43200?(a+.5)/v.DAYS_PER_JULIAN_CENTURY:(a-.5)/v.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%y.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(i+.5*v.SECONDS_PER_DAY)%v.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new m(h,d,0,-d,h,0,0,0,1)},T.iau2006XysData=new h,T.earthOrientationParameters=c.NONE;T.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=T.iau2006XysData.preload(r,n,i,a),u=T.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},T.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new m);var r=T.computeFixedToIcrfMatrix(e,t);if(u(r))return m.transpose(r,t)};var b=new d(0,0,0),L=new l(0,0,0,0,0,0),F=new m,B=new m;T.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new m);var r=T.earthOrientationParameters.compute(e,L);if(u(r)){var n=e.dayNumber,i=e.secondsOfDay+32.184,a=T.iau2006XysData.computeXysRadians(n,i,b);if(u(a)){var o=a.x+r.xPoleOffset,s=a.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=m.fromRotationZ(-a.s,B),h=m.multiply(l,f,F),d=e.dayNumber,E=e.secondsOfDay-p.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=d-2451545,R=E/v.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*y.TWO_PI;var S=m.fromRotationZ(A,B),g=m.multiply(h,S,F),O=Math.cos(r.xPoleWander),N=Math.cos(r.yPoleWander),I=Math.sin(r.xPoleWander),w=Math.sin(r.yPoleWander),x=n-2451545+i/v.SECONDS_PER_DAY;x/=36525;var M=-47e-6*x*y.RADIANS_PER_DEGREE/3600,C=Math.cos(M),P=Math.sin(M),D=B;return D[0]=O*C,D[1]=O*P,D[2]=I,D[3]=-N*P+w*I*C,D[4]=N*C+w*I*P,D[5]=-w*O,D[6]=-w*P-N*I*C,D[7]=w*C-N*I*P,D[8]=N*O,m.multiply(g,D,t)}}};var z=new n;T.pointToWindowCoordinates=function(e,t,r,n){return n=T.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},T.pointToGLWindowCoordinates=function(e,r,i,a){u(a)||(a=new t);var o=z;return E.multiplyByVector(e,n.fromElements(i.x,i.y,i.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),E.multiplyByVector(r,o,o),t.fromCartesian4(o,a)};var q=new r,G=new r,W=new r;T.rotationMatrixFromPositionVelocity=function(e,t,n,i){var a=o(n,f.WGS84).geodeticSurfaceNormal(e,q),s=r.cross(t,a,G);r.equalsEpsilon(s,r.ZERO,y.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,W);return r.cross(t,c,s),r.negate(s,s),u(i)||(i=new m),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var V=new E(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new r,k=new r,Y=new m,Z=new E,j=new E;return T.basisTo2D=function(e,t,n){var i=E.getTranslation(t,k),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=T.eastNorthUpToFixedFrame(i,a,Z),c=E.inverseTransformation(s,j),l=E.getRotation(t,Y),f=E.multiplyByMatrix3(c,l,n);return E.multiply(V,f,n),E.setTranslation(n,u,n),n},T.wgs84To2DModelMatrix=function(e,t,n){var i=e.ellipsoid,a=T.eastNorthUpToFixedFrame(t,i,Z),o=E.inverseTransformation(a,j),u=i.cartesianToCartographic(t,X),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=E.fromTranslation(s,Z);return E.multiply(V,o,n),E.multiply(c,n,n),n},T}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d){"use strict";function p(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var n=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=r.fromCartesian4(l.getColumn(n,0,y)), +this._yAxis=r.fromCartesian4(l.getColumn(n,1,y));var a=r.fromCartesian4(l.getColumn(n,2,y));this._plane=f.fromPointNormal(e,a)}var y=new n;o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var m=new e;p.fromPoints=function(t,r){return new p(e.fromPoints(t,m).center,r)};var E=new h,_=new r;p.prototype.projectPointOntoPlane=function(e,n){var i=E;i.origin=e,r.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return a(n)?(n.x=s,n.y=l,n):new t(s,l)}},p.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var r=0,n=e.length,i=0;i<n;i++){var o=this.projectPointOntoPlane(e[i],t[r]);a(o)&&(t[r]=o,r++)}return t.length=r,t},p.prototype.projectPointToNearestOnPlane=function(e,n){a(n)||(n=new t);var i=E;i.origin=e,r.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return n.x=s,n.y=l,n},p.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var r=e.length;t.length=r;for(var n=0;n<r;n++)t[n]=this.projectPointToNearestOnPlane(e[n],t[n]);return t};var v=new r;return p.prototype.projectPointsOntoEllipsoid=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=v,l=0;l<n;++l){var f=e[l];r.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new r);var h=r.add(o,c,t[l]);r.multiplyByScalar(s,f.y,c),r.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},p}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var i=e.attributes[n],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=n.clone(e(t.modelMatrix,n.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return i}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),i=256*(r-n);return u.octDecode(n,i,t)},u.octPack=function(e,t,r,n){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+i,n.y=65536*o.y+a,n},u.octUnpack=function(e,t,r,n){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(a,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function i(r,i,s,c,l){n(l)||(l=new t);var f,h,d,p,y,m,E,_;n(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(r,i,u),p=t.dot(f,f),y=t.dot(f,h),m=t.dot(f,d),E=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(r,i,u),p=e.dot(f,f),y=e.dot(f,h),m=e.dot(f,d),E=e.dot(h,h),_=e.dot(h,d));var v=1/(p*E-y*y);return l.y=(E*m-y*_)*v,l.z=(p*_-y*m)*v,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var i={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var a=t.high,o=t.low;return n.encode(e.x,i),a.x=i.high,o.x=i.low,n.encode(e.y,i),a.y=i.high,o.y=i.low,n.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,a);var i=a.high,o=a.low;t[r]=i.x,t[r+1]=i.y,t[r+2]=i.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,r,i){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,i):new Uint16Array(t,r,i)},r(a)}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,i=r.maximumIndex,a=e(r.cacheSize,24),o=n.length;if(!t(i)){i=0;for(var u=0,s=n[u];u<o;)s>i&&(i=s),++u,s=n[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[n[h]]>a&&(c[n[h]]=f,++f);return(f-a+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<n;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}r=e(r,e.EMPTY_OBJECT);var i,a=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var y=0;l<h;)p[a[l]].vertexTriangles.push(y),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(y),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(y),++p[a[l+2]].numLiveTriangles,++y,l+=3;var m=0,E=u+1;i=1;var _,v,T=[],R=[],A=0,S=[],g=s/3,O=[];for(d=0;d<g;d++)O[d]=!1;for(var N,I;-1!==m;){T=[],v=p[m],I=v.vertexTriangles.length;for(var w=0;w<I;++w)if(y=v.vertexTriangles[w],!O[y]){O[y]=!0,l=y+y+y;for(var x=0;x<3;++x)N=a[l],T.push(N),R.push(N),S[A]=N,++A,_=p[N],--_.numLiveTriangles,E-_.timeStamp>u&&(_.timeStamp=E,++E),++l}m=function(e,t,r,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var h=r[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?n(i,o,e,u):c}(a,u,T,p,E,R,c)}return S},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,y,m,E,_,v,T,R,A,S,g){"use strict";function O(e,t,r,n,i){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=i,e[t++]=i,e[t]=r}function N(e){for(var t=e.length,r=t/3*6,n=m.createTypedArray(t,r),i=0,a=0;a<t;a+=3,i+=6)O(n,i,e[a],e[a+1],e[a+2]);return n}function I(e){var t=e.length;if(t>=3){var r=6*(t-2),n=m.createTypedArray(t,r);O(n,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)O(n,i,e[a-1],e[a],e[a-2]);return n}return new Uint16Array}function w(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=m.createTypedArray(t,r),i=e[0],a=0,o=1;o<t;++o,a+=6)O(n,a,i,e[o],e[o+1]);return n}return new Uint16Array}function x(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new p({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function M(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var i=t[n],a=0;a<i.componentsPerAttribute;++a)e[n].values.push(i.values[r*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,r,a)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),T.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,r,a)}function D(e,t){var r,n=e.length,i={},a=e[0][t].attributes;for(r in a)if(a.hasOwnProperty(r)&&c(a[r])&&c(a[r].values)){for(var o=a[r],s=o.values.length,l=!0,f=1;f<n;++f){var h=e[f][t].attributes[r];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(i[r]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function U(e,t){var n,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),y=e[0][t].primitiveType,E=D(e,t);for(n in E)if(E.hasOwnProperty(n))for(s=E[n].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var v=0;for(a=0;a<h;++a)v+=e[a][t].indices.length;var T=d.computeNumberOfVertices(new d({attributes:E,primitiveType:S.POINTS})),R=m.createTypedArray(T,v),A=0,g=0;for(a=0;a<h;++a){var O=e[a][t].indices,N=O.length;for(u=0;u<N;++u)R[A++]=g+O[u];g+=d.computeNumberOfVertices(e[a][t])}_=R}var I,w=new i,x=0;for(a=0;a<h;++a){if(I=e[a][t].boundingSphere,!c(I)){w=void 0;break}i.add(I.center,w,w)}if(c(w))for(i.divideByScalar(w,h,w),a=0;a<h;++a){I=e[a][t].boundingSphere;var M=i.magnitude(i.subtract(I.center,w,se))+I.radius;M>x&&(x=M)}return new d({attributes:E,indices:_,primitiveType:y,boundingSphere:c(w)?new r(w,x):void 0})}function b(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function L(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,i=3;i<t;++i)r[n++]=i-1,r[n++]=0,r[n++]=i;return e.indices=r,e.primitiveType=S.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,i=3;i<t-1;i+=2)r[n++]=i,r[n++]=i-1,r[n++]=i+1,i+2<t&&(r[n++]=i,r[n++]=i+1,r[n++]=i+2);return e.indices=r,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return e.indices=r,e.primitiveType=S.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),r=m.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=S.LINES,e}function G(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return L(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return b(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return q(e);case S.LINES:return B(e)}return e}function W(e,t){Math.abs(e.y)<v.EPSILON6&&(e.y=t?-v.EPSILON6:v.EPSILON6)}function V(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return W(e,e.y<0),W(t,t.y<0),void W(r,r.y<0);var n,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(r.y);n=i>a?i>o?v.sign(e.y):v.sign(r.y):a>o?v.sign(t.y):v.sign(r.y);var u=n<0;W(e,u),W(t,u),W(r,u)}function X(e,t,r,n){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),r),i.clone(r,n),W(r,!0),W(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){V(e,t,r);var n=e.y<0,i=t.y<0,a=r.y<0,o=0;o+=n?1:0,o+=i?1:0,o+=a?1:0;var u=Ne.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(X(e,t,Ae,ge),X(e,r,Se,Oe),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(X(t,r,Ae,ge),X(t,e,Se,Oe),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(X(r,e,Ae,ge),X(r,t,Se,Oe),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?i?a||(X(r,e,Ae,ge),X(r,t,Se,Oe),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(X(t,r,Ae,ge),X(t,e,Se,Oe),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(X(e,t,Ae,ge),X(e,r,Se,Oe),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Ne.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=ge,s[6]=Oe,s.length=7),Ne}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var i in n)if(n.hasOwnProperty(i)&&c(n[i])&&c(n[i].values)){var a=n[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=m.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var i=t[n];r[n]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:r,indices:[],primitiveType:e.primitiveType})}function Z(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function j(e,r,a,o,u,s,l,f,h,d,p,y){if(c(s)||c(l)||c(f)||c(h)||c(d)){var m=i.fromArray(u,3*e,Ie),E=i.fromArray(u,3*r,we),_=i.fromArray(u,3*a,xe),v=t(o,m,E,_,Me);if(c(s)){var T=i.fromArray(s,3*e,Ie),R=i.fromArray(s,3*r,we),A=i.fromArray(s,3*a,xe);i.multiplyByScalar(T,v.x,T),i.multiplyByScalar(R,v.y,R),i.multiplyByScalar(A,v.z,A);var S=i.add(T,R,T);i.add(S,A,S),i.normalize(S,S),i.pack(S,p.normal.values,3*y)}if(c(d)){var g=i.fromArray(d,3*e,Ie),O=i.fromArray(d,3*r,we),N=i.fromArray(d,3*a,xe);i.multiplyByScalar(g,v.x,g),i.multiplyByScalar(O,v.y,O),i.multiplyByScalar(N,v.z,N);var I;i.equals(g,i.ZERO)&&i.equals(O,i.ZERO)&&i.equals(N,i.ZERO)?(I=Ie,I.x=0,I.y=0,I.z=0):(I=i.add(g,O,g),i.add(I,N,I),i.normalize(I,I)),i.pack(I,p.extrudeDirection.values,3*y)}if(c(l)){var w=i.fromArray(l,3*e,Ie),x=i.fromArray(l,3*r,we),M=i.fromArray(l,3*a,xe);i.multiplyByScalar(w,v.x,w),i.multiplyByScalar(x,v.y,x),i.multiplyByScalar(M,v.z,M);var C=i.add(w,x,w);i.add(C,M,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*y)}if(c(f)){var P=i.fromArray(f,3*e,Ie),D=i.fromArray(f,3*r,we),U=i.fromArray(f,3*a,xe);i.multiplyByScalar(P,v.x,P),i.multiplyByScalar(D,v.y,D),i.multiplyByScalar(U,v.z,U);var b=i.add(P,D,P);i.add(b,U,b),i.normalize(b,b),i.pack(b,p.bitangent.values,3*y)}if(c(h)){var L=n.fromArray(h,2*e,Ce),F=n.fromArray(h,2*r,Pe),B=n.fromArray(h,2*a,De);n.multiplyByScalar(L,v.x,L),n.multiplyByScalar(F,v.y,F),n.multiplyByScalar(B,v.z,B);var z=n.add(L,F,L);n.add(z,B,z),n.pack(z,p.st.values,2*y)}}}function K(e,t,r,n,i,a){var o=e.position.values.length/3;if(-1!==i){var u=n[i],s=r[u];return-1===s?(r[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,r,n,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,y=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,m=u.indices,E=Y(u),_=Y(u),v=[];v.length=l.length/3;var T=[];for(T.length=l.length/3,o=0;o<v.length;++o)v[o]=-1,T[o]=-1;var R=m.length;for(o=0;o<R;o+=3){var A=m[o],S=m[o+1],g=m[o+2],O=i.fromArray(l,3*A),N=i.fromArray(l,3*S),I=i.fromArray(l,3*g),w=H(O,N,I);if(c(w)&&w.positions.length>3)for(var x=w.positions,M=w.indices,C=M.length,P=0;P<C;++P){var D=M[P],U=x[D];U.y<0?(t=_.attributes,r=_.indices,n=v):(t=E.attributes,r=E.indices,n=T),a=K(t,r,n,m,D<3?o+D:-1,U),j(A,S,g,U,l,f,d,h,p,y,t,a)}else c(w)&&(O=w.positions[0],N=w.positions[1],I=w.positions[2]),O.y<0?(t=_.attributes,r=_.indices,n=v):(t=E.attributes,r=E.indices,n=T),a=K(t,r,n,m,o,O),j(A,S,g,O,l,f,d,h,p,y,t,a),a=K(t,r,n,m,o+1,N),j(A,S,g,N,l,f,d,h,p,y,t,a),a=K(t,r,n,m,o+2,I),j(A,S,g,I,l,f,d,h,p,y,t,a)}Z(e,_,E)}function Q(e){var t,r=e.geometry,n=r.attributes,a=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],y=i.fromArray(a,3*d,Ie),m=i.fromArray(a,3*p,we);Math.abs(y.y)<v.EPSILON6&&(y.y<0?y.y=-v.EPSILON6:y.y=v.EPSILON6),Math.abs(m.y)<v.EPSILON6&&(m.y<0?m.y=-v.EPSILON6:m.y=v.EPSILON6);var E=u.attributes,T=u.indices,R=h,A=s.attributes,S=s.indices,g=f,O=_.lineSegmentPlane(y,m,Ue,xe);if(c(O)){var N=i.multiplyByScalar(i.UNIT_Y,5*v.EPSILON9,be);y.y<0&&(i.negate(N,N),E=s.attributes,T=s.indices,R=f,A=u.attributes,S=u.indices,g=h);var I=i.add(O,N,Le);K(E,T,R,o,t,y),K(E,T,R,o,-1,I),i.negate(N,N),i.add(O,N,I),K(A,S,g,o,-1,I),K(A,S,g,o,t+1,m)}else{var w,x,M;y.y<0?(w=s.attributes,x=s.indices,M=f):(w=u.attributes,x=u.indices,M=h),K(w,x,M,o,t,y),K(w,x,M,o,t+1,m)}}Z(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,a=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=i.unpack(r,u,ze);if(!(s.x>0)){var c=i.unpack(n,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):i.pack(s,n,u));var l=i.unpack(a,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=r[u+3],a[u+1]=r[u+4],a[u+2]=r[u+5]):i.pack(s,a,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,y=c(s.color)?s.color.values:void 0,m=Y(u),E=Y(u),T=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,S=t+2,g=i.fromArray(l,3*A,ze),O=i.fromArray(l,3*S,qe);if(Math.abs(g.y)<Ye)for(g.y=Ye*(O.y<0?-1:1),l[3*t+1]=g.y,l[3*(t+1)+1]=g.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(O.y)<Ye)for(O.y=Ye*(g.y<0?-1:1),l[3*(t+2)+1]=O.y,l[3*(t+3)+1]=O.y,r=3*A;r<3*A+12;r+=3)h[r]=l[3*(t+2)],h[r+1]=l[3*(t+2)+1],h[r+2]=l[3*(t+2)+2];var N=m.attributes,I=m.indices,w=E.attributes,x=E.indices,M=_.lineSegmentPlane(g,O,Ue,We);if(c(M)){T=!0;var C=i.multiplyByScalar(i.UNIT_Y,ke,Ve);g.y<0&&(i.negate(C,C),N=E.attributes,I=E.indices,w=m.attributes,x=m.indices);var P=i.add(M,C,Xe);N.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),N.position.values.push(P.x,P.y,P.z),N.position.values.push(P.x,P.y,P.z),N.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),N.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),N.prevPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),N.nextPosition.values.push(P.x,P.y,P.z),N.nextPosition.values.push(P.x,P.y,P.z),N.nextPosition.values.push(P.x,P.y,P.z),N.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(M,C,P),w.position.values.push(P.x,P.y,P.z),w.position.values.push(P.x,P.y,P.z),w.position.values.push(O.x,O.y,O.z,O.x,O.y,O.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.prevPosition.values.push(P.x,P.y,P.z),w.nextPosition.values.push(O.x,O.y,O.z,O.x,O.y,O.z),w.nextPosition.values.push(h[3*S],h[3*S+1],h[3*S+2]),w.nextPosition.values.push(h[3*S+3],h[3*S+4],h[3*S+5]);var D=n.fromArray(d,2*A,Fe),U=Math.abs(D.y);N.expandAndWidth.values.push(-1,U,1,U),N.expandAndWidth.values.push(-1,-U,1,-U),w.expandAndWidth.values.push(-1,U,1,U),w.expandAndWidth.values.push(-1,-U,1,-U);var b=i.magnitudeSquared(i.subtract(M,g,Ge));if(b/=i.magnitudeSquared(i.subtract(O,g,Ge)),c(y)){var L=a.fromArray(y,4*A,He),F=a.fromArray(y,4*S,He),B=v.lerp(L.x,F.x,b),z=v.lerp(L.y,F.y,b),q=v.lerp(L.z,F.z,b),G=v.lerp(L.w,F.w,b);for(r=4*A;r<4*A+8;++r)N.color.values.push(y[r]);for(N.color.values.push(B,z,q,G),N.color.values.push(B,z,q,G),w.color.values.push(B,z,q,G),w.color.values.push(B,z,q,G),r=4*S;r<4*S+8;++r)w.color.values.push(y[r])}if(c(p)){var W=n.fromArray(p,2*A,Fe),V=n.fromArray(p,2*(t+3),Be),X=v.lerp(W.x,V.x,b);for(r=2*A;r<2*A+4;++r)N.st.values.push(p[r]);for(N.st.values.push(X,W.y),N.st.values.push(X,V.y),w.st.values.push(X,W.y),w.st.values.push(X,V.y),r=2*S;r<2*S+4;++r)w.st.values.push(p[r])}o=N.position.values.length/3-4,I.push(o,o+2,o+1),I.push(o+1,o+2,o+3),o=w.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3)}else{var H,k;for(g.y<0?(H=E.attributes,k=E.indices):(H=m.attributes,k=m.indices),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(O.x,O.y,O.z),H.position.values.push(O.x,O.y,O.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(d[r]),c(p)&&H.st.values.push(p[r]);if(c(y))for(r=4*t;r<4*t+16;++r)H.color.values.push(y[r]);o=H.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}T&&($(E),$(m)),Z(e,E,m)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=N(t);break;case S.TRIANGLE_STRIP:e.indices=I(t);break;case S.TRIANGLE_FAN:e.indices=w(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*n,l[f++]=i[h+1]+a[h+1]*n,l[f++]=i[h+2]+a[h+2]*n;var y,m=e.boundingSphere;return c(m)&&(y=new r(m.center,m.radius+n)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:y})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,i={},a=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(i[u]=a++)}for(var s in n)n.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),i=0;i<t;i++)n[i]=-1;for(var a,o=r,s=o.length,l=m.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=n[o[f]],-1!==a?l[h]=a:(a=o[f],n[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var y=e.attributes;for(var E in y)if(y.hasOwnProperty(E)&&c(y[E])&&c(y[E].values)){for(var _=y[E],v=_.values,T=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);T<t;){var S=n[T];if(-1!==S)for(var g=0;g<R;g++)A[R*S+g]=v[R*T+g];++T}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===S.TRIANGLES&&c(r)){for(var n=r.length,i=0,a=0;a<n;a++)r[a]>i&&(i=r[a]);e.indices=g.tipsify({indices:r,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=d.computeNumberOfVertices(e);if(c(e.indices)&&r>=v.SIXTY_FOUR_KILOBYTES){var n,i=[],a=[],o=0,u=x(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?n=3:e.primitiveType===S.LINES?n=2:e.primitiveType===S.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var h=0;h<n;++h){var p=s[f+h],y=i[p];c(y)||(y=o++,i[p]=y,M(u,e.attributes,p)),a.push(y)}o+n>=v.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=x(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new i,ne=new o;te.projectTo2D=function(e,t,r,n,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,y=0;y<l.length;y+=3){var m=i.fromArray(l,y,re),E=s.cartesianToCartographic(m,ne),_=a.project(E,re);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[r]=o,e.attributes[n]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new T;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=r.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,i=0;i<n;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&r.push(a)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,a=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=r[t],y=r[t+1],m=r[t+2],E=3*d,_=3*y,T=3*m;le.x=a[E],le.y=a[E+1],le.z=a[E+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[T],he.y=a[T+1],he.z=a[T+2],c[d].count++,c[y].count++,c[m].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var S=A.indexOffset+A.currentCount;f[S]=h,A.currentCount++,A=c[r[t+1]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,A=c[r[t+2]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,h++}var g=new Float32Array(3*o);for(t=0;t<o;t++){var O=3*t;if(A=c[t],i.clone(i.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)i.add(ce,l[f[A.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&i.clone(l[f[A.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),g[O]=ce.x,g[O+1]=ce.y,g[O+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:g}),e};var de=new i,pe=new i,ye=new i;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var y=r[t],m=r[t+1],E=r[t+2];f=3*y,h=3*m,d=3*E;var _=2*y,v=2*m,T=2*E,R=n[f],A=n[f+1],S=n[f+2],g=o[_],O=o[_+1],N=o[v+1]-O,I=o[T+1]-O,w=1/((o[v]-g)*I-(o[T]-g)*N),x=(I*(n[h]-R)-N*(n[d]-R))*w,M=(I*(n[h+1]-A)-N*(n[d+1]-A))*w,C=(I*(n[h+2]-S)-N*(n[d+2]-S))*w;l[f]+=x,l[f+1]+=M,l[f+2]+=C,l[h]+=x,l[h+1]+=M,l[h+2]+=C,l[d]+=x,l[d+1]+=M,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var U=i.fromArray(a,f,de),b=i.fromArray(l,f,ye),L=i.dot(U,b);i.multiplyByScalar(U,L,pe),i.normalize(i.subtract(b,pe,b),b),P[f]=b.x,P[h]=b.y,P[d]=b.z,i.normalize(i.cross(U,b,b),b),D[f]=b.x,D[h]=b.y,D[d]=b.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var me=new n,Ee=new i,_e=new i,ve=new i,Te=new n;te.compressVertices=function(t){var r,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(r=0;r<a;++r)i.fromArray(s,3*r,Ee),i.equals(Ee,i.ZERO)?f+=2:(Te=e.octEncodeInRange(Ee,65535,Te),l[f++]=Te.x,l[f++]=Te.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,y=c(h),m=c(d);if(!y&&!m)return t;var E,_,v,T,R=t.attributes.tangent,A=t.attributes.bitangent,S=c(R),g=c(A);y&&(E=h.values),m&&(_=d.values),S&&(v=R.values),g&&(T=A.values),a=(y?E.length:_.length)/(y?3:2);var O=a,N=m&&y?2:1;N+=S||g?1:0,O*=N;var I=new Float32Array(O),w=0;for(r=0;r<a;++r){m&&(n.fromArray(_,2*r,me),I[w++]=e.compressTextureCoordinates(me));var x=3*r;y&&c(v)&&c(T)?(i.fromArray(E,x,Ee),i.fromArray(v,x,_e),i.fromArray(T,x,ve),e.octPack(Ee,_e,ve,me),I[w++]=me.x,I[w++]=me.y):(y&&(i.fromArray(E,x,Ee),I[w++]=e.octEncodeFloat(Ee)),S&&(i.fromArray(v,x,Ee),I[w++]=e.octEncodeFloat(Ee)),g&&(i.fromArray(T,x,Ee),I[w++]=e.octEncodeFloat(Ee)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:N,values:I}),y&&delete t.attributes.normal,m&&delete t.attributes.st,g&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Re=new i,Ae=new i,Se=new i,ge=new i,Oe=new i,Ne={positions:new Array(7),indices:new Array(9) +},Ie=new i,we=new i,xe=new i,Me=new i,Ce=new n,Pe=new n,De=new n,Ue=A.fromPointNormal(i.ZERO,i.UNIT_Y),be=new i,Le=new i,Fe=new n,Be=new n,ze=new i,qe=new i,Ge=new i,We=new i,Ve=new i,Xe=new i,He=new a,ke=5*v.EPSILON9,Ye=v.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==E.INTERSECTING)return e}if(t.geometryType!==y.NONE)switch(t.geometryType){case y.POLYLINES:ee(e);break;case y.TRIANGLES:J(e);break;case y.LINES:Q(e)}else G(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,r,i){i=i||2;var a=r&&r.length,o=a?r[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,p,y,m;if(a&&(u=s(e,r,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var E=i;E<o;E+=i)p=e[E],y=e[E+1],p<l&&(l=p),y<f&&(f=y),p>h&&(h=p),y>d&&(d=y);m=Math.max(h-l,d-f)}return n(u,c,i,l,f,m),c}function t(e,t,r,n,i){var a,o;if(i===w(e,t,r,n)>0)for(a=t;a<r;a+=n)o=O(a,e[a],e[a+1],o);else for(a=r-n;a>=t;a-=n)o=O(a,e[a],e[a+1],o);return o&&v(o,o.next)&&(N(o),o=o.next),o}function r(e,t){if(!e)return e;t||(t=e);var r,n=e;do{if(r=!1,n.steiner||!v(n,n.next)&&0!==_(n.prev,n,n.next))n=n.next;else{if(N(n),(n=t=n.prev)===n.next)return null;r=!0}}while(r||n!==t);return t}function n(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var p,y,m=e;e.prev!==e.next;)if(p=e.prev,y=e.next,f?a(e,c,l,f):i(e))t.push(p.i/s),t.push(e.i/s),t.push(y.i/s),N(e),e=y.next,m=y.next;else if((e=y)===m){d?1===d?(e=o(e,t,s),n(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):n(r(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,r=e,n=e.next;if(_(t,r,n)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(m(t.x,t.y,r.x,r.y,n.x,n.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,r,n){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=p(u,s,t,r,n),h=p(c,l,t,r,n),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,r){var n=e;do{var i=n.prev,a=n.next.next;!v(i,a)&&T(i,n,n.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/r),t.push(n.i/r),t.push(a.i/r),N(n),N(n.next),n=e=a),n=n.next}while(n!==e);return n}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&E(s,c)){var l=g(s,c);return s=r(s,s.next),l=r(l,l.next),n(s,t,i,a,o,u),void n(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,n,i,a){var o,u,s,f,h,d=[];for(o=0,u=n.length;o<u;o++)s=n[o]*a,f=o<u-1?n[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(y(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=r(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var n=g(t,e);r(n,n.next)}}function f(e,t){var r,n=t,i=e.x,a=e.y,o=-1/0;do{if(a<=n.y&&a>=n.next.y){var u=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(u<=i&&u>o){if(o=u,u===i){if(a===n.y)return n;if(a===n.next.y)return n.next}r=n.x<n.next.x?n:n.next}}n=n.next}while(n!==t);if(!r)return null;if(i===o)return r.prev;var s,c=r,l=r.x,f=r.y,h=1/0;for(n=r.next;n!==c;)i>=n.x&&n.x>=l&&m(a<f?i:o,a,l,f,a<f?o:i,a,n.x,n.y)&&((s=Math.abs(a-n.y)/(i-n.x))<h||s===h&&n.x>r.x)&&A(n,e)&&(r=n,h=s),n=n.next;return r}function h(e,t,r,n){var i=e;do{null===i.z&&(i.z=p(i.x,i.y,t,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,r,n,i,a,o,u,s,c=1;do{for(r=e,e=null,a=null,o=0;r;){for(o++,n=r,u=0,t=0;t<c&&(u++,n=n.nextZ);t++);for(s=c;u>0||s>0&&n;)0===u?(i=n,n=n.nextZ,s--):0!==s&&n?r.z<=n.z?(i=r,r=r.nextZ,u--):(i=n,n=n.nextZ,s--):(i=r,r=r.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;r=n}a.nextZ=null,c*=2}while(o>1);return e}function p(e,t,r,n,i){return e=32767*(e-r)/i,t=32767*(t-n)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function y(e){var t=e,r=e;do{t.x<r.x&&(r=t),t=t.next}while(t!==e);return r}function m(e,t,r,n,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(n-u)-(r-o)*(t-u)>=0&&(r-o)*(a-u)-(i-o)*(n-u)>=0}function E(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!R(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function _(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function v(e,t){return e.x===t.x&&e.y===t.y}function T(e,t,r,n){return!!(v(e,t)&&v(r,n)||v(e,n)&&v(r,t))||_(e,t,r)>0!=_(e,t,n)>0&&_(r,n,e)>0!=_(r,n,t)>0}function R(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&T(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function S(e,t){var r=e,n=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{r.y>a!=r.next.y>a&&i<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==e);return n}function g(e,t){var r=new I(e.i,e.x,e.y),n=new I(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,r.next=i,i.prev=r,n.next=r,r.prev=n,a.next=n,n.prev=a,n}function O(e,t,r,n){var i=new I(e,t,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function N(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function w(e,t,r,n){for(var i=0,a=t,o=r-n;a<r;a+=n)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,r,n){var i=t&&t.length,a=i?t[0]*r:e.length,o=Math.abs(w(e,0,a,r));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*r,l=u<s-1?t[u+1]*r:e.length;o-=Math.abs(w(e,c,l,r))}var f=0;for(u=0;u<n.length;u+=3){var h=n[u]*r,d=n[u+1]*r,p=n[u+2]*r;f+=Math.abs((e[h]-e[p])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[p+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,r={vertices:[],holes:[],dimensions:t},n=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)r.vertices.push(e[i][a][o]);i>0&&(n+=e[i-1].length,r.holes.push(n))}return r},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===r.CLOCKWISE||e===r.COUNTER_CLOCKWISE}};return e(r)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";var d=new r,p=new r,y={};y.computeArea2D=function(e){for(var t=e.length,r=0,n=t-1,i=0;i<t;n=i++){var a=e[n],o=e[i];r+=a.x*o.y-o.x*a.y}return.5*r},y.computeWindingOrder2D=function(e){return y.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},y.triangulate=function(r,n){var i=t.packArray(r);return e(i,n,2)};var m=new r,E=new r,_=new r,v=new r,T=new r,R=new r,A=new r;return y.computeSubdivision=function(e,t,n,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=n.slice(0),p=t.length,y=new Array(3*p),S=0;for(h=0;h<p;h++){var g=t[h];y[S++]=g.x,y[S++]=g.y,y[S++]=g.z}for(var O=[],N={},I=e.maximumRadius,w=l.chordLength(u,I),x=w*w;d.length>0;){var M,C,P=d.pop(),D=d.pop(),U=d.pop(),b=r.fromArray(y,3*U,m),L=r.fromArray(y,3*D,E),F=r.fromArray(y,3*P,_),B=r.multiplyByScalar(r.normalize(b,v),I,v),z=r.multiplyByScalar(r.normalize(L,T),I,T),q=r.multiplyByScalar(r.normalize(F,R),I,R),G=r.magnitudeSquared(r.subtract(B,z,A)),W=r.magnitudeSquared(r.subtract(z,q,A)),V=r.magnitudeSquared(r.subtract(q,B,A)),X=Math.max(G,W,V);X>x?G===X?(M=Math.min(U,D)+" "+Math.max(U,D),h=N[M],o(h)||(C=r.add(b,L,A),r.multiplyByScalar(C,.5,C),y.push(C.x,C.y,C.z),h=y.length/3-1,N[M]=h),d.push(U,h,P),d.push(h,D,P)):W===X?(M=Math.min(D,P)+" "+Math.max(D,P),h=N[M],o(h)||(C=r.add(L,F,A),r.multiplyByScalar(C,.5,C),y.push(C.x,C.y,C.z),h=y.length/3-1,N[M]=h),d.push(D,h,U),d.push(h,P,U)):V===X&&(M=Math.min(P,U)+" "+Math.max(P,U),h=N[M],o(h)||(C=r.add(F,b,A),r.multiplyByScalar(C,.5,C),y.push(C.x,C.y,C.z),h=y.length/3-1,N[M]=h),d.push(P,h,D),d.push(h,U,D)):(O.push(U),O.push(D),O.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:y})},indices:O,primitiveType:f.TRIANGLES})},y.scaleToGeodeticHeight=function(e,t,n,i){n=a(n,u.WGS84);var s=d,c=p;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)r.fromArray(e,f,c),i&&(c=n.scaleToGeodeticSurface(c,c)),0!==t&&(s=n.geodeticSurfaceNormal(c,s),r.multiplyByScalar(s,t,s),r.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},y}),define("Core/Queue",["./defineProperties"],function(e){"use strict";function t(){this._array=[],this._offset=0,this._length=0}return e(t.prototype,{length:{get:function(){return this._length}}}),t.prototype.enqueue=function(e){this._array.push(e),this._length++},t.prototype.dequeue=function(){if(0!==this._length){var e=this._array,t=this._offset,r=e[t];return e[t]=void 0,t++,t>10&&2*t>e.length&&(this._array=e.slice(t),t=0),this._offset=t,this._length--,r}},t.prototype.peek=function(){if(0!==this._length)return this._array[this._offset]},t.prototype.contains=function(e){return-1!==this._array.indexOf(e)},t.prototype.clear=function(){this._array.length=this._offset=this._length=0},t.prototype.sort=function(e){this._offset>0&&(this._array=this._array.slice(this._offset),this._offset=0),this._array.sort(e)},t}),define("Core/PolygonGeometryLibrary",["./arrayRemoveDuplicates","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,y){"use strict";function m(e,r,n,i){return t.subtract(r,e,_),t.multiplyByScalar(_,n/i,_),t.add(e,_,_),[_.x,_.y,_.z]}var E={};E.computeHierarchyPackedLength=function(e){for(var r=0,n=[e];n.length>0;){var a=n.pop();if(i(a)){r+=2;var o=a.positions,u=a.holes;if(i(o)&&(r+=o.length*t.packedLength),i(u))for(var s=u.length,c=0;c<s;++c)n.push(u[c])}}return r},E.packPolygonHierarchy=function(e,r,n){for(var a=[e];a.length>0;){var o=a.pop();if(i(o)){var u=o.positions,s=o.holes;if(r[n++]=i(u)?u.length:0,r[n++]=i(s)?s.length:0,i(u))for(var c=u.length,l=0;l<c;++l,n+=3)t.pack(u[l],r,n);if(i(s))for(var f=s.length,h=0;h<f;++h)a.push(s[h])}}return n},E.unpackPolygonHierarchy=function(e,r){for(var n=e[r++],i=e[r++],a=new Array(n),o=i>0?new Array(i):void 0,u=0;u<n;++u,r+=t.packedLength)a[u]=t.unpack(e,r);for(var s=0;s<i;++s)o[s]=E.unpackPolygonHierarchy(e,r),r=o[s].startingIndex,delete o[s].startingIndex;return{positions:a,holes:o,startingIndex:r}};var _=new t;E.subdivideLineCount=function(e,r,n){var i=t.distance(e,r),a=i/n,o=Math.max(0,Math.ceil(Math.log(a)/Math.log(2)));return Math.pow(2,o)},E.subdivideLine=function(e,r,n,a){var o=E.subdivideLineCount(e,r,n),u=t.distance(e,r),s=u/o;i(a)||(a=[]);var c=a;c.length=3*o;for(var l=0,f=0;f<o;f++){var h=m(e,r,f*s,u);c[l++]=h[0],c[l++]=h[1],c[l++]=h[2]}return c};var v=new t,T=new t,R=new t,A=new t;E.scaleToGeodeticHeightExtruded=function(e,r,o,u,s){u=n(u,a.WGS84);var c=v,l=T,f=R,h=A;if(i(e)&&i(e.attributes)&&i(e.attributes.position))for(var d=e.attributes.position.values,p=d.length/2,y=0;y<p;y+=3)t.fromArray(d,y,f),u.geodeticSurfaceNormal(f,c),h=u.scaleToGeodeticSurface(f,h),l=t.multiplyByScalar(c,o,l),l=t.add(h,l,l),d[y+p]=l.x,d[y+1+p]=l.y,d[y+2+p]=l.z,s&&(h=t.clone(f,h)),l=t.multiplyByScalar(c,r,l),l=t.add(h,l,l),d[y]=l.x,d[y+1]=l.y,d[y+2]=l.z;return e},E.polygonsFromHierarchy=function(r,n,a,o){var u=[],s=[],c=new p;for(c.enqueue(r);0!==c.length;){var l=c.dequeue(),f=l.positions,d=l.holes;if(f=e(f,t.equalsEpsilon,!0),!(f.length<3)){var m=a.projectPointsOntoPlane(f),E=[],_=h.computeWindingOrder2D(m);_===y.CLOCKWISE&&(m.reverse(),f=f.slice().reverse());var v,T,R=f.slice(),A=i(d)?d.length:0,S=[];for(v=0;v<A;v++){var g=d[v],O=e(g.positions,t.equalsEpsilon,!0);if(!(O.length<3)){var N=a.projectPointsOntoPlane(O);_=h.computeWindingOrder2D(N),_===y.CLOCKWISE&&(N.reverse(),O=O.slice().reverse()),S.push(O),E.push(R.length),R=R.concat(O),m=m.concat(N);var I=0;for(i(g.holes)&&(I=g.holes.length),T=0;T<I;T++)c.enqueue(g.holes[T])}}if(!n){for(v=0;v<f.length;v++)o.scaleToGeodeticSurface(f[v],f[v]);for(v=0;v<S.length;v++){var w=S[v];for(T=0;T<w.length;++T)o.scaleToGeodeticSurface(w[T],w[T])}}u.push({outerRing:f,holes:S}),s.push({positions:R,positions2D:m,holes:E})}}return{hierarchy:u,polygons:s}},E.createGeometryFromPositions=function(e,t,n,i,a){var s=h.triangulate(t.positions2D,t.holes);s.length<3&&(s=[0,1,2]);var l=t.positions;if(i){for(var f=l.length,p=new Array(3*f),y=0,m=0;m<f;m++){var E=l[m];p[y++]=E.x,p[y++]=E.y,p[y++]=E.z}var _=new o({attributes:{position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:p})},indices:s,primitiveType:d.TRIANGLES});return a.normal?c.computeNormal(_):_}return h.computeSubdivision(e,l,s,n)};var S=[],g=new t,O=new t;return E.computeWallGeometry=function(e,n,i,a){var c,h,p,y,m,_=e.length,v=0;if(a)for(h=3*_*2,c=new Array(2*h),p=0;p<_;p++)y=e[p],m=e[(p+1)%_],c[v]=c[v+h]=y.x,++v,c[v]=c[v+h]=y.y,++v,c[v]=c[v+h]=y.z,++v,c[v]=c[v+h]=m.x,++v,c[v]=c[v+h]=m.y,++v,c[v]=c[v+h]=m.z,++v;else{var T=f.chordLength(i,n.maximumRadius),R=0;for(p=0;p<_;p++)R+=E.subdivideLineCount(e[p],e[(p+1)%_],T);for(h=3*(R+_),c=new Array(2*h),p=0;p<_;p++){y=e[p],m=e[(p+1)%_];for(var A=E.subdivideLine(y,m,T,S),N=A.length,I=0;I<N;++I,++v)c[v]=A[I],c[v+h]=A[I];c[v]=m.x,c[v+h]=m.x,++v,c[v]=m.y,c[v+h]=m.y,++v,c[v]=m.z,c[v+h]=m.z,++v}}_=c.length;var w=l.createTypedArray(_/3,_-6*e.length),x=0;for(_/=6,p=0;p<_;p++){var M=p,C=M+1,P=M+_,D=P+1;y=t.fromArray(c,3*M,g),m=t.fromArray(c,3*C,O),t.equalsEpsilon(y,m,f.EPSILON14)||(w[x++]=M,w[x++]=P,w[x++]=C,w[x++]=C,w[x++]=P,w[x++]=D)}return new o({attributes:new s({position:new u({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:c})}),indices:w,primitiveType:d.TRIANGLES})},E}),define("Core/PolygonOutlineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./PolygonGeometryLibrary","./PolygonPipeline","./PrimitiveType","./Queue","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,y,m,E,_,v,T,R){"use strict";function A(e,t,r,n){var a=c.fromPoints(t,e),o=a.projectPointsOntoPlane(t,O);_.computeWindingOrder2D(o)===R.CLOCKWISE&&(o.reverse(),t=t.slice().reverse());var u,s,p=t.length,m=0;if(n)for(u=new Float64Array(2*p*3),s=0;s<p;s++){var T=t[s],A=t[(s+1)%p];u[m++]=T.x,u[m++]=T.y,u[m++]=T.z,u[m++]=A.x,u[m++]=A.y,u[m++]=A.z}else{var S=0;for(s=0;s<p;s++)S+=E.subdivideLineCount(t[s],t[(s+1)%p],r);for(u=new Float64Array(3*S),s=0;s<p;s++)for(var g=E.subdivideLine(t[s],t[(s+1)%p],r,N),I=g.length,w=0;w<I;++w)u[m++]=g[w]}p=u.length/3;var x=2*p,M=y.createTypedArray(p,x);for(m=0,s=0;s<p-1;s++)M[m++]=s,M[m++]=s+1;return M[m++]=p-1,M[m++]=0,new d({geometry:new l({attributes:new h({position:new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:u})}),indices:M,primitiveType:v.LINES})})}function S(e,t,r,n){var a=c.fromPoints(t,e),o=a.projectPointsOntoPlane(t,O);_.computeWindingOrder2D(o)===R.CLOCKWISE&&(o.reverse(),t=t.slice().reverse());var u,s,p=t.length,m=new Array(p),T=0;if(n)for(u=new Float64Array(2*p*3*2),s=0;s<p;++s){m[s]=T/3;var A=t[s],S=t[(s+1)%p];u[T++]=A.x,u[T++]=A.y,u[T++]=A.z,u[T++]=S.x,u[T++]=S.y,u[T++]=S.z}else{var g=0;for(s=0;s<p;s++)g+=E.subdivideLineCount(t[s],t[(s+1)%p],r);for(u=new Float64Array(3*g*2),s=0;s<p;++s){m[s]=T/3;for(var I=E.subdivideLine(t[s],t[(s+1)%p],r,N),w=I.length,x=0;x<w;++x)u[T++]=I[x]}}p=u.length/6;var M=m.length,C=2*(2*p+M),P=y.createTypedArray(p,C);for(T=0,s=0;s<p;++s)P[T++]=s,P[T++]=(s+1)%p,P[T++]=s+p,P[T++]=(s+1)%p+p;for(s=0;s<M;s++){var D=m[s];P[T++]=D,P[T++]=D+p}return new d({geometry:new l({attributes:new h({position:new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:u})}),indices:P,primitiveType:v.LINES})})}function g(e){var t=e.polygonHierarchy,r=a(e.ellipsoid,s.WGS84),n=a(e.granularity,m.RADIANS_PER_DEGREE),i=a(e.height,0),u=a(e.perPositionHeight,!1),c=e.extrudedHeight,l=o(c);if(l&&!u){var f=c;c=Math.min(f,i),i=Math.max(f,i)}this._ellipsoid=s.clone(r),this._granularity=n,this._height=i,this._extrudedHeight=a(c,0),this._extrude=l,this._polygonHierarchy=t,this._perPositionHeight=u,this._workerName="createPolygonOutlineGeometry",this.packedLength=E.computeHierarchyPackedLength(t)+s.packedLength+6}var O=[],N=[];g.pack=function(e,t,r){return r=a(r,0),r=E.packPolygonHierarchy(e._polygonHierarchy,t,r),s.pack(e._ellipsoid,t,r),r+=s.packedLength,t[r++]=e._height,t[r++]=e._extrudedHeight,t[r++]=e._granularity,t[r++]=e._extrude?1:0,t[r++]=e._perPositionHeight?1:0,t[r++]=e.packedLength,t};var I=s.clone(s.UNIT_SPHERE),w={polygonHierarchy:{}};return g.unpack=function(e,t,r){t=a(t,0);var n=E.unpackPolygonHierarchy(e,t);t=n.startingIndex,delete n.startingIndex;var i=s.unpack(e,t,I);t+=s.packedLength;var u=e[t++],c=e[t++],l=e[t++],f=1===e[t++],h=1===e[t++],d=e[t++];return o(r)||(r=new g(w)),r._polygonHierarchy=n,r._ellipsoid=s.clone(i,r._ellipsoid),r._height=u,r._extrudedHeight=c,r._granularity=l,r._extrude=f,r._perPositionHeight=h,r.packedLength=d,r},g.fromPositions=function(e){return e=a(e,a.EMPTY_OBJECT),new g({polygonHierarchy:{positions:e.positions},height:e.height,extrudedHeight:e.extrudedHeight,ellipsoid:e.ellipsoid,granularity:e.granularity,perPositionHeight:e.perPositionHeight})},g.createGeometry=function(n){var i=n._ellipsoid,a=n._granularity,u=n._height,s=n._extrudedHeight,c=n._extrude,f=n._polygonHierarchy,h=n._perPositionHeight,d=[],y=new T;y.enqueue(f);for(var v;0!==y.length;){var R=y.dequeue(),g=R.positions;if(g=e(g,r.equalsEpsilon,!0),!(g.length<3)){var O=R.holes?R.holes.length:0;for(v=0;v<O;v++){var N=R.holes[v];if(N.positions=e(N.positions,r.equalsEpsilon,!0),!(N.positions.length<3)){d.push(N.positions);var I=0;o(N.holes)&&(I=N.holes.length);for(var w=0;w<I;w++)y.enqueue(N.holes[w])}}d.push(g)}}if(0!==d.length){var x,M=[],C=m.chordLength(a,i.maximumRadius);if(c)for(v=0;v<d.length;v++)x=S(i,d[v],C,h),x.geometry=E.scaleToGeodeticHeightExtruded(x.geometry,u,s,i,h),M.push(x);else for(v=0;v<d.length;v++)x=A(i,d[v],C,h),x.geometry.attributes.position.values=_.scaleToGeodeticHeight(x.geometry.attributes.position.values,u,i,!h),M.push(x);x=p.combineInstances(M)[0];var P=t.fromVertices(x.attributes.position.values);return new l({attributes:x.attributes,indices:x.indices,primitiveType:x.primitiveType,boundingSphere:P})}},g}),define("Workers/createPolygonOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolygonOutlineGeometry"],function(e,t,r){"use strict";function n(n,i){return e(i)&&(n=r.unpack(n,i)),n._ellipsoid=t.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineGeometry.js index a3e7652f..5ac8f0f2 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function r(t){return t+" is required, actual value was undefined"}function n(t,e,r){return"Expected "+r+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(n,a){if(!t(a))throw new e(r(n))},a.typeOf.func=function(t,r){if("function"!=typeof r)throw new e(n(typeof r,"function",t))},a.typeOf.string=function(t,r){if("string"!=typeof r)throw new e(n(typeof r,"string",t))},a.typeOf.number=function(t,r){if("number"!=typeof r)throw new e(n(typeof r,"number",t))},a.typeOf.number.lessThan=function(t,r,n){if(a.typeOf.number(t,r),r>=n)throw new e("Expected "+t+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(t,r,n){if(a.typeOf.number(t,r),r>n)throw new e("Expected "+t+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(t,r,n){if(a.typeOf.number(t,r),r<=n)throw new e("Expected "+t+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(t,r,n){if(a.typeOf.number(t,r),r<n)throw new e("Expected "+t+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(t,r){if("object"!=typeof r)throw new e(n(typeof r,"object",t))},a.typeOf.bool=function(t,r){if("boolean"!=typeof r)throw new e(n(typeof r,"boolean",t))},a.typeOf.number.equals=function(t,r,n,o){if(a.typeOf.number(t,n),a.typeOf.number(r,o),n!==o)throw new e(t+" must be equal to "+r+", the actual values are "+n+" and "+o)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)t=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^t>>>1^e[1&t];for(;r<this.N-1;r++)t=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,r){return r=e(r,255),Math.round((.5*a.clamp(t,-1,1)+.5)*r)},a.fromSNorm=function(t,r){return r=e(r,255),a.clamp(t,0,r)/r*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,r){return(1-r)*t+r*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,r=t-Math.floor(t/e)*e;return r<-Math.PI?r+e:r>=Math.PI?r-e:r},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,r,n,a){a=e(a,n);var o=Math.abs(t-r);return o<=a||o<=n*Math.max(Math.abs(t),Math.abs(r))};var o=[1];a.factorial=function(t){var e=o.length;if(t>=e)for(var r=o[e-1],n=e;n<=t;n++)o.push(r*n);return o[t]},a.incrementWrap=function(t,r,n){return n=e(n,0),++t,t>r&&(t=n),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,r){return t<e?e:t>r?r:t};var i=new t;return a.setRandomNumberSeed=function(e){i=new t(e)},a.nextRandomNumber=function(){return i.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var r=t*e;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,r,n){this.x=e(t,0),this.y=e(r,0),this.z=e(n,0)}i.fromSpherical=function(t,n){r(n)||(n=new i);var a=t.clock,o=t.cone,u=e(t.magnitude,1),s=u*Math.sin(o);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(o),n},i.fromElements=function(t,e,n,a){return r(a)?(a.x=t,a.y=e,a.z=n,a):new i(t,e,n)},i.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new i(t.x,t.y,t.z)},i.fromCartesian4=i.clone,i.packedLength=3,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.x,r[n++]=t.y,r[n]=t.z,r},i.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new i),a.x=t[n++],a.y=t[n++],a.z=t[n],a},i.packArray=function(t,e){var n=t.length;r(e)?e.length=3*n:e=new Array(3*n);for(var a=0;a<n;++a)i.pack(t[a],e,3*a);return e},i.unpackArray=function(t,e){var n=t.length;r(e)?e.length=n/3:e=new Array(n/3);for(var a=0;a<n;a+=3){var o=a/3;e[o]=i.unpack(t,a,e[o])}return e},i.fromArray=i.unpack,i.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},i.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},i.minimumByComponent=function(t,e,r){return r.x=Math.min(t.x,e.x),r.y=Math.min(t.y,e.y),r.z=Math.min(t.z,e.z),r},i.maximumByComponent=function(t,e,r){return r.x=Math.max(t.x,e.x),r.y=Math.max(t.y,e.y),r.z=Math.max(t.z,e.z),r},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},i.magnitude=function(t){return Math.sqrt(i.magnitudeSquared(t))};var u=new i;i.distance=function(t,e){return i.subtract(t,e,u),i.magnitude(u)},i.distanceSquared=function(t,e){return i.subtract(t,e,u),i.magnitudeSquared(u)},i.normalize=function(t,e){var r=i.magnitude(t);return e.x=t.x/r,e.y=t.y/r,e.z=t.z/r,e},i.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},i.multiplyComponents=function(t,e,r){return r.x=t.x*e.x,r.y=t.y*e.y,r.z=t.z*e.z,r},i.divideComponents=function(t,e,r){return r.x=t.x/e.x,r.y=t.y/e.y,r.z=t.z/e.z,r},i.add=function(t,e,r){return r.x=t.x+e.x,r.y=t.y+e.y,r.z=t.z+e.z,r},i.subtract=function(t,e,r){return r.x=t.x-e.x,r.y=t.y-e.y,r.z=t.z-e.z,r},i.multiplyByScalar=function(t,e,r){return r.x=t.x*e,r.y=t.y*e,r.z=t.z*e,r},i.divideByScalar=function(t,e,r){return r.x=t.x/e,r.y=t.y/e,r.z=t.z/e,r},i.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},i.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new i;i.lerp=function(t,e,r,n){return i.multiplyByScalar(e,r,s),n=i.multiplyByScalar(t,1-r,n),i.add(s,n,n)};var E=new i,c=new i;i.angleBetween=function(t,e){i.normalize(t,E),i.normalize(e,c);var r=i.dot(E,c),n=i.magnitude(i.cross(E,c,E));return Math.atan2(n,r)};var l=new i;i.mostOrthogonalAxis=function(t,e){var r=i.normalize(t,l);return i.abs(r,r),e=r.x<=r.y?r.x<=r.z?i.clone(i.UNIT_X,e):i.clone(i.UNIT_Z,e):r.y<=r.z?i.clone(i.UNIT_Y,e):i.clone(i.UNIT_Z,e)},i.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},i.equalsArray=function(t,e,r){return t.x===e[r]&&t.y===e[r+1]&&t.z===e[r+2]},i.equalsEpsilon=function(t,e,n,a){return t===e||r(t)&&r(e)&&o.equalsEpsilon(t.x,e.x,n,a)&&o.equalsEpsilon(t.y,e.y,n,a)&&o.equalsEpsilon(t.z,e.z,n,a)},i.cross=function(t,e,r){var n=t.x,a=t.y,o=t.z,i=e.x,u=e.y,s=e.z,E=a*s-o*u,c=o*i-n*s,l=n*u-a*i;return r.x=E,r.y=c,r.z=l,r},i.fromDegrees=function(t,e,r,n,a){return t=o.toRadians(t),e=o.toRadians(e),i.fromRadians(t,e,r,n,a)};var f=new i,_=new i,R=new i(40680631590769,40680631590769,40408299984661.445);return i.fromRadians=function(t,n,a,o,u){a=e(a,0);var s=r(o)?o.radiiSquared:R,E=Math.cos(n);f.x=E*Math.cos(t),f.y=E*Math.sin(t),f.z=Math.sin(n),f=i.normalize(f,f),i.multiplyComponents(s,f,_);var c=Math.sqrt(i.dot(f,_));return _=i.divideByScalar(_,c,_),f=i.multiplyByScalar(f,a,f),r(u)||(u=new i),i.add(_,f,u)},i.fromDegreesArray=function(t,e,n){var a=t.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=t[o],s=t[o+1],E=o/2;n[E]=i.fromDegrees(u,s,0,e,n[E])}return n},i.fromRadiansArray=function(t,e,n){var a=t.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=t[o],s=t[o+1],E=o/2;n[E]=i.fromRadians(u,s,0,e,n[E])}return n},i.fromDegreesArrayHeights=function(t,e,n){var a=t.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=t[o],s=t[o+1],E=t[o+2],c=o/3;n[c]=i.fromDegrees(u,s,E,e,n[c])}return n},i.fromRadiansArrayHeights=function(t,e,n){var a=t.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=t[o],s=t[o+1],E=t[o+2],c=o/3;n[c]=i.fromRadians(u,s,E,e,n[c])}return n},i.ZERO=a(new i(0,0,0)),i.UNIT_X=a(new i(1,0,0)),i.UNIT_Y=a(new i(0,1,0)),i.UNIT_Z=a(new i(0,0,1)),i.prototype.clone=function(t){return i.clone(this,t)},i.prototype.equals=function(t){return i.equals(this,t)},i.prototype.equalsEpsilon=function(t,e,r){return i.equalsEpsilon(this,t,e,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,r,n){"use strict";function a(r,a,u,s,E){var c=r.x,l=r.y,f=r.z,_=a.x,R=a.y,h=a.z,T=c*c*_*_,A=l*l*R*R,d=f*f*h*h,S=T+A+d,m=Math.sqrt(1/S),N=t.multiplyByScalar(r,m,o);if(S<s)return isFinite(m)?t.clone(N,E):void 0;var C=u.x,I=u.y,p=u.z,M=i;M.x=N.x*C*2,M.y=N.y*I*2,M.z=N.z*p*2;var O,g,y,F,L,v,U,P,D,w,B,x=(1-m)*t.magnitude(r)/(.5*t.magnitude(M)),G=0;do{x-=G,y=1/(1+x*C),F=1/(1+x*I),L=1/(1+x*p),v=y*y,U=F*F,P=L*L,D=v*y,w=U*F,B=P*L,O=T*v+A*U+d*P-1,g=T*D*C+A*w*I+d*B*p;G=O/(-2*g)}while(Math.abs(O)>n.EPSILON12);return e(E)?(E.x=c*y,E.y=l*F,E.z=f*L,E):new t(c*y,l*F,f*L)}var o=new t,i=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,r,n,a,o,i){"use strict";function u(t,e,n){this.longitude=r(t,0),this.latitude=r(e,0),this.height=r(n,0)}u.fromRadians=function(t,e,a,o){return a=r(a,0),n(o)?(o.longitude=t,o.latitude=e,o.height=a,o):new u(t,e,a)},u.fromDegrees=function(t,e,r,n){return t=o.toRadians(t),e=o.toRadians(e),u.fromRadians(t,e,r,n)};var s=new t,E=new t,c=new t,l=new t(1/6378137,1/6378137,1/6356752.314245179),f=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),_=o.EPSILON1;return u.fromCartesian=function(e,r,a){var R=n(r)?r.oneOverRadii:l,h=n(r)?r.oneOverRadiiSquared:f,T=n(r)?r._centerToleranceSquared:_,A=i(e,R,h,T,E);if(n(A)){var d=t.multiplyComponents(A,h,s);d=t.normalize(d,d);var S=t.subtract(e,A,c),m=Math.atan2(d.y,d.x),N=Math.asin(d.z),C=o.sign(t.dot(S,e))*t.magnitude(S);return n(a)?(a.longitude=m,a.latitude=N,a.height=C,a):new u(m,N,C)}},u.clone=function(t,e){if(n(t))return n(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||n(t)&&n(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,r){return t===e||n(t)&&n(e)&&Math.abs(t.longitude-e.longitude)<=r&&Math.abs(t.latitude-e.latitude)<=r&&Math.abs(t.height-e.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),r=Object.defineProperties;return e&&t(r)||(r=function(t){return t}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,r,n,a,o,i,u,s,E){"use strict";function c(e,r,a,o){r=n(r,0),a=n(a,0),o=n(o,0),e._radii=new t(r,a,o),e._radiiSquared=new t(r*r,a*a,o*o),e._radiiToTheFourth=new t(r*r*r*r,a*a*a*a,o*o*o*o),e._oneOverRadii=new t(0===r?0:1/r,0===a?0:1/a,0===o?0:1/o),e._oneOverRadiiSquared=new t(0===r?0:1/(r*r),0===a?0:1/(a*a),0===o?0:1/(o*o)),e._minimumRadius=Math.min(r,a,o),e._maximumRadius=Math.max(r,a,o),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function l(t,e,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,r)}o(l.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),l.clone=function(e,r){if(a(e)){var n=e._radii;return a(r)?(t.clone(n,r._radii),t.clone(e._radiiSquared,r._radiiSquared),t.clone(e._radiiToTheFourth,r._radiiToTheFourth),t.clone(e._oneOverRadii,r._oneOverRadii),t.clone(e._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=e._minimumRadius,r._maximumRadius=e._maximumRadius,r._centerToleranceSquared=e._centerToleranceSquared,r):new l(n.x,n.y,n.z)}},l.fromCartesian3=function(t,e){return a(e)||(e=new l),a(t)?(c(e,t.x,t.y,t.z),e):e},l.WGS84=u(new l(6378137,6378137,6356752.314245179)),l.UNIT_SPHERE=u(new l(1,1,1)),l.MOON=u(new l(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),l.prototype.clone=function(t){return l.clone(this,t)},l.packedLength=t.packedLength,l.pack=function(e,r,a){return a=n(a,0),t.pack(e._radii,r,a),r},l.unpack=function(e,r,a){r=n(r,0);var o=t.unpack(e,r);return l.fromCartesian3(o,a)},l.prototype.geocentricSurfaceNormal=t.normalize,l.prototype.geodeticSurfaceNormalCartographic=function(e,r){var n=e.longitude,o=e.latitude,i=Math.cos(o),u=i*Math.cos(n),s=i*Math.sin(n),E=Math.sin(o);return a(r)||(r=new t),r.x=u,r.y=s,r.z=E,t.normalize(r,r)},l.prototype.geodeticSurfaceNormal=function(e,r){return a(r)||(r=new t),r=t.multiplyComponents(e,this._oneOverRadiiSquared,r),t.normalize(r,r)};var f=new t,_=new t;l.prototype.cartographicToCartesian=function(e,r){var n=f,o=_;this.geodeticSurfaceNormalCartographic(e,n),t.multiplyComponents(this._radiiSquared,n,o);var i=Math.sqrt(t.dot(n,o));return t.divideByScalar(o,i,o),t.multiplyByScalar(n,e.height,n),a(r)||(r=new t),t.add(o,n,r)},l.prototype.cartographicArrayToCartesianArray=function(t,e){var r=t.length;a(e)?e.length=r:e=new Array(r);for(var n=0;n<r;n++)e[n]=this.cartographicToCartesian(t[n],e[n]);return e};var R=new t,h=new t,T=new t;return l.prototype.cartesianToCartographic=function(r,n){var o=this.scaleToGeodeticSurface(r,h);if(a(o)){var i=this.geodeticSurfaceNormal(o,R),u=t.subtract(r,o,T),E=Math.atan2(i.y,i.x),c=Math.asin(i.z),l=s.sign(t.dot(u,r))*t.magnitude(u);return a(n)?(n.longitude=E,n.latitude=c,n.height=l,n):new e(E,c,l)}},l.prototype.cartesianArrayToCartographicArray=function(t,e){var r=t.length;a(e)?e.length=r:e=new Array(r);for(var n=0;n<r;++n)e[n]=this.cartesianToCartographic(t[n],e[n]);return e},l.prototype.scaleToGeodeticSurface=function(t,e){return E(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},l.prototype.scaleToGeocentricSurface=function(e,r){a(r)||(r=new t);var n=e.x,o=e.y,i=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+o*o*u.y+i*i*u.z);return t.multiplyByScalar(e,s,r)},l.prototype.transformPositionToScaledSpace=function(e,r){return a(r)||(r=new t),t.multiplyComponents(e,this._oneOverRadii,r)},l.prototype.transformPositionFromScaledSpace=function(e,r){return a(r)||(r=new t),t.multiplyComponents(e,this._radii,r)},l.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},l.prototype.toString=function(){return this._radii.toString()},l.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,r,o){r=n(r,0);var i=this._squaredXOverSquaredZ;if(a(o)||(o=new t),o.x=0,o.y=0,o.z=e.z*(1-i),!(Math.abs(o.z)>=this._radii.z-r))return o},l}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(t,e,r,n){"use strict";function a(t,n,a){if(r(t)){a=e(a,!1);var i=t.length;if(i<2)return t;var u,s,E;for(u=1;u<i&&(s=t[u-1],E=t[u],!n(s,E,o));++u);if(u===i)return a&&n(t[0],t[t.length-1],o)?t.slice(1):t;for(var c=t.slice(0,u);u<i;++u)E=t[u],n(s,E,o)||(c.push(E),s=E);return a&&c.length>1&&n(c[0],c[c.length-1],o)&&c.shift(),c}}var o=n.EPSILON10;return a}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,r,n,a,o,i){"use strict";function u(t){this._ellipsoid=r(t,i.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,r){var a=this._semimajorAxis,o=e.longitude*a,i=e.latitude*a,u=e.height;return n(r)?(r.x=o,r.y=i,r.z=u,r):new t(o,i,u)},u.prototype.unproject=function(t,r){var a=this._oneOverSemimajorAxis,o=t.x*a,i=t.y*a,u=t.z;return n(r)?(r.longitude=o,r.latitude=i,r.height=u,r):new e(o,i,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,r){this.start=t(e,0),this.stop=t(r,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t,e,n,a,o,i,u,s,E){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(e,0),this[4]=r(o,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(i,0),this[8]=r(E,0)}function E(t){for(var e=0,r=0;r<9;++r){var n=t[r];e+=n*n}return Math.sqrt(e)}function c(t){for(var e=0,r=0;r<3;++r){var n=t[s.getElementIndex(h[r],R[r])];e+=2*n*n}return Math.sqrt(e)}function l(t,e){for(var r=u.EPSILON15,n=0,a=1,o=0;o<3;++o){var i=Math.abs(t[s.getElementIndex(h[o],R[o])]);i>n&&(a=o,n=i)}var E=1,c=0,l=R[a],f=h[a];if(Math.abs(t[s.getElementIndex(f,l)])>r){var _,T=t[s.getElementIndex(f,f)],A=t[s.getElementIndex(l,l)],d=t[s.getElementIndex(f,l)],S=(T-A)/2/d;_=S<0?-1/(-S+Math.sqrt(1+S*S)):1/(S+Math.sqrt(1+S*S)),E=1/Math.sqrt(1+_*_),c=_*E}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(l,l)]=e[s.getElementIndex(f,f)]=E,e[s.getElementIndex(f,l)]=c,e[s.getElementIndex(l,f)]=-c,e}s.packedLength=9,s.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e},s.unpack=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},s.clone=function(t,e){if(n(t))return n(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return n(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var r=t.x*t.x,a=t.x*t.y,o=t.x*t.z,i=t.x*t.w,u=t.y*t.y,E=t.y*t.z,c=t.y*t.w,l=t.z*t.z,f=t.z*t.w,_=t.w*t.w,R=r-u-l+_,h=2*(a-f),T=2*(o+c),A=2*(a+f),d=-r+u-l+_,S=2*(E-i),m=2*(o-c),N=2*(E+i),C=-r-u+l+_;return n(e)?(e[0]=R,e[1]=A,e[2]=m,e[3]=h,e[4]=d,e[5]=N,e[6]=T,e[7]=S,e[8]=C,e):new s(R,h,T,A,d,S,m,N,C)},s.fromHeadingPitchRoll=function(t,e){var r=Math.cos(-t.pitch),a=Math.cos(-t.heading),o=Math.cos(t.roll),i=Math.sin(-t.pitch),u=Math.sin(-t.heading),E=Math.sin(t.roll),c=r*a,l=-o*u+E*i*a,f=E*u+o*i*a,_=r*u,R=o*a+E*i*u,h=-E*a+o*i*u,T=-i,A=E*r,d=o*r;return n(e)?(e[0]=c,e[1]=_,e[2]=T,e[3]=l,e[4]=R,e[5]=A,e[6]=f,e[7]=h,e[8]=d,e):new s(c,l,f,_,R,h,T,A,d)},s.fromScale=function(t,e){return n(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return n(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return n(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=r,e[5]=a,e[6]=0,e[7]=-a,e[8]=r,e):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=r,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=r,e):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=r,e[1]=a,e[2]=0,e[3]=-a,e[4]=r,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(t,e){return n(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,r){var n=3*e,a=t[n],o=t[n+1],i=t[n+2];return r.x=a,r.y=o,r.z=i,r},s.setColumn=function(t,e,r,n){n=s.clone(t,n);var a=3*e;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(t,e,r){var n=t[e],a=t[e+3],o=t[e+6];return r.x=n,r.y=a,r.z=o,r},s.setRow=function(t,e,r,n){return n=s.clone(t,n),n[e]=r.x,n[e+3]=r.y,n[e+6]=r.z,n};var f=new t;s.getScale=function(e,r){return r.x=t.magnitude(t.fromElements(e[0],e[1],e[2],f)),r.y=t.magnitude(t.fromElements(e[3],e[4],e[5],f)),r.z=t.magnitude(t.fromElements(e[6],e[7],e[8],f)),r};var _=new t;s.getMaximumScale=function(e){return s.getScale(e,_),t.maximumComponent(_)},s.multiply=function(t,e,r){var n=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],o=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],i=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],E=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],l=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return r[0]=n,r[1]=a,r[2]=o,r[3]=i,r[4]=u,r[5]=s,r[6]=E,r[7]=c,r[8]=l,r},s.add=function(t,e,r){return r[0]=t[0]+e[0],r[1]=t[1]+e[1],r[2]=t[2]+e[2],r[3]=t[3]+e[3],r[4]=t[4]+e[4],r[5]=t[5]+e[5],r[6]=t[6]+e[6],r[7]=t[7]+e[7],r[8]=t[8]+e[8],r},s.subtract=function(t,e,r){return r[0]=t[0]-e[0],r[1]=t[1]-e[1],r[2]=t[2]-e[2],r[3]=t[3]-e[3],r[4]=t[4]-e[4],r[5]=t[5]-e[5],r[6]=t[6]-e[6],r[7]=t[7]-e[7],r[8]=t[8]-e[8],r},s.multiplyByVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[3]*a+t[6]*o,u=t[1]*n+t[4]*a+t[7]*o,s=t[2]*n+t[5]*a+t[8]*o;return r.x=i,r.y=u,r.z=s,r},s.multiplyByScalar=function(t,e,r){return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*e,r[5]=t[5]*e,r[6]=t[6]*e,r[7]=t[7]*e,r[8]=t[8]*e,r},s.multiplyByScale=function(t,e,r){return r[0]=t[0]*e.x,r[1]=t[1]*e.x,r[2]=t[2]*e.x,r[3]=t[3]*e.y,r[4]=t[4]*e.y,r[5]=t[5]*e.y,r[6]=t[6]*e.z,r[7]=t[7]*e.z,r[8]=t[8]*e.z,r},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var r=t[0],n=t[3],a=t[6],o=t[1],i=t[4],u=t[7],s=t[2],E=t[5],c=t[8];return e[0]=r,e[1]=n,e[2]=a,e[3]=o,e[4]=i,e[5]=u,e[6]=s,e[7]=E,e[8]=c,e};var R=[1,0,0],h=[2,2,1],T=new s,A=new s;return s.computeEigenDecomposition=function(t,e){var r=u.EPSILON20,a=0,o=0;n(e)||(e={});for(var i=e.unitary=s.clone(s.IDENTITY,e.unitary),f=e.diagonal=s.clone(t,e.diagonal),_=r*E(f);o<10&&c(f)>_;)l(f,T),s.transpose(T,A),s.multiply(f,T,f),s.multiply(A,f,f),s.multiply(i,T,i),++a>2&&(++o,a=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],r=t[3],n=t[6],a=t[1],o=t[4],i=t[7],u=t[2],s=t[5],E=t[8];return e*(o*E-s*i)+a*(s*n-r*E)+u*(r*i-o*n)},s.inverse=function(t,e){var r=t[0],n=t[1],a=t[2],o=t[3],i=t[4],u=t[5],E=t[6],c=t[7],l=t[8],f=s.determinant(t);e[0]=i*l-c*u,e[1]=c*a-n*l,e[2]=n*u-i*a,e[3]=E*u-o*l,e[4]=r*l-E*a,e[5]=o*a-r*u,e[6]=o*c-E*i,e[7]=E*n-r*c,e[8]=r*i-o*n;var _=1/f;return s.multiplyByScalar(e,_,e)},s.equals=function(t,e){return t===e||n(t)&&n(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,r){return t===e||n(t)&&n(e)&&Math.abs(t[0]-e[0])<=r&&Math.abs(t[1]-e[1])<=r&&Math.abs(t[2]-e[2])<=r&&Math.abs(t[3]-e[3])<=r&&Math.abs(t[4]-e[4])<=r&&Math.abs(t[5]-e[5])<=r&&Math.abs(t[6]-e[6])<=r&&Math.abs(t[7]-e[7])<=r&&Math.abs(t[8]-e[8])<=r},s.IDENTITY=i(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=i(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,r){return t[0]===e[r]&&t[1]===e[r+1]&&t[2]===e[r+2]&&t[3]===e[r+3]&&t[4]===e[r+4]&&t[5]===e[r+5]&&t[6]===e[r+6]&&t[7]===e[r+7]&&t[8]===e[r+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,r,n,a){this.x=e(t,0),this.y=e(r,0),this.z=e(n,0),this.w=e(a,0)}i.fromElements=function(t,e,n,a,o){return r(o)?(o.x=t,o.y=e,o.z=n,o.w=a,o):new i(t,e,n,a)},i.fromColor=function(t,e){return r(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new i(t.red,t.green,t.blue,t.alpha)},i.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new i(t.x,t.y,t.z,t.w)},i.packedLength=4,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.x,r[n++]=t.y,r[n++]=t.z,r[n]=t.w,r},i.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new i),a.x=t[n++],a.y=t[n++],a.z=t[n++],a.w=t[n],a},i.packArray=function(t,e){var n=t.length;r(e)?e.length=4*n:e=new Array(4*n);for(var a=0;a<n;++a)i.pack(t[a],e,4*a);return e},i.unpackArray=function(t,e){var n=t.length;r(e)?e.length=n/4:e=new Array(n/4);for(var a=0;a<n;a+=4){var o=a/4;e[o]=i.unpack(t,a,e[o])}return e},i.fromArray=i.unpack,i.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},i.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},i.minimumByComponent=function(t,e,r){return r.x=Math.min(t.x,e.x),r.y=Math.min(t.y,e.y),r.z=Math.min(t.z,e.z),r.w=Math.min(t.w,e.w),r},i.maximumByComponent=function(t,e,r){return r.x=Math.max(t.x,e.x),r.y=Math.max(t.y,e.y),r.z=Math.max(t.z,e.z),r.w=Math.max(t.w,e.w),r},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},i.magnitude=function(t){return Math.sqrt(i.magnitudeSquared(t))};var u=new i;i.distance=function(t,e){return i.subtract(t,e,u),i.magnitude(u)},i.distanceSquared=function(t,e){return i.subtract(t,e,u),i.magnitudeSquared(u)},i.normalize=function(t,e){var r=i.magnitude(t);return e.x=t.x/r,e.y=t.y/r,e.z=t.z/r,e.w=t.w/r,e},i.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},i.multiplyComponents=function(t,e,r){return r.x=t.x*e.x,r.y=t.y*e.y,r.z=t.z*e.z,r.w=t.w*e.w,r},i.divideComponents=function(t,e,r){return r.x=t.x/e.x,r.y=t.y/e.y,r.z=t.z/e.z,r.w=t.w/e.w,r},i.add=function(t,e,r){return r.x=t.x+e.x,r.y=t.y+e.y,r.z=t.z+e.z,r.w=t.w+e.w,r},i.subtract=function(t,e,r){return r.x=t.x-e.x,r.y=t.y-e.y,r.z=t.z-e.z,r.w=t.w-e.w,r},i.multiplyByScalar=function(t,e,r){return r.x=t.x*e,r.y=t.y*e,r.z=t.z*e,r.w=t.w*e,r},i.divideByScalar=function(t,e,r){return r.x=t.x/e,r.y=t.y/e,r.z=t.z/e,r.w=t.w/e,r},i.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},i.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new i;i.lerp=function(t,e,r,n){return i.multiplyByScalar(e,r,s),n=i.multiplyByScalar(t,1-r,n),i.add(s,n,n)};var E=new i;return i.mostOrthogonalAxis=function(t,e){var r=i.normalize(t,E);return i.abs(r,r),e=r.x<=r.y?r.x<=r.z?r.x<=r.w?i.clone(i.UNIT_X,e):i.clone(i.UNIT_W,e):r.z<=r.w?i.clone(i.UNIT_Z,e):i.clone(i.UNIT_W,e):r.y<=r.z?r.y<=r.w?i.clone(i.UNIT_Y,e):i.clone(i.UNIT_W,e):r.z<=r.w?i.clone(i.UNIT_Z,e):i.clone(i.UNIT_W,e)},i.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},i.equalsArray=function(t,e,r){return t.x===e[r]&&t.y===e[r+1]&&t.z===e[r+2]&&t.w===e[r+3]},i.equalsEpsilon=function(t,e,n,a){return t===e||r(t)&&r(e)&&o.equalsEpsilon(t.x,e.x,n,a)&&o.equalsEpsilon(t.y,e.y,n,a)&&o.equalsEpsilon(t.z,e.z,n,a)&&o.equalsEpsilon(t.w,e.w,n,a)},i.ZERO=a(new i(0,0,0,0)),i.UNIT_X=a(new i(1,0,0,0)),i.UNIT_Y=a(new i(0,1,0,0)),i.UNIT_Z=a(new i(0,0,1,0)),i.UNIT_W=a(new i(0,0,0,1)),i.prototype.clone=function(t){return i.clone(this,t)},i.prototype.equals=function(t){return i.equals(this,t)},i.prototype.equalsEpsilon=function(t,e,r){ -return i.equalsEpsilon(this,t,e,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},i}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,r,n,a,o,i,u,s,E){"use strict";function c(t,e,r,a,o,i,u,s,E,c,l,f,_,R,h,T){this[0]=n(t,0),this[1]=n(o,0),this[2]=n(E,0),this[3]=n(_,0),this[4]=n(e,0),this[5]=n(i,0),this[6]=n(c,0),this[7]=n(R,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(l,0),this[11]=n(h,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(T,0)}c.packedLength=16,c.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e[r++]=t[9],e[r++]=t[10],e[r++]=t[11],e[r++]=t[12],e[r++]=t[13],e[r++]=t[14],e[r]=t[15],e},c.unpack=function(t,e,r){return e=n(e,0),a(r)||(r=new c),r[0]=t[e++],r[1]=t[e++],r[2]=t[e++],r[3]=t[e++],r[4]=t[e++],r[5]=t[e++],r[6]=t[e++],r[7]=t[e++],r[8]=t[e++],r[9]=t[e++],r[10]=t[e++],r[11]=t[e++],r[12]=t[e++],r[13]=t[e++],r[14]=t[e++],r[15]=t[e],r},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,r,o){return r=n(r,t.ZERO),a(o)?(o[0]=e[0],o[1]=e[1],o[2]=e[2],o[3]=0,o[4]=e[3],o[5]=e[4],o[6]=e[5],o[7]=0,o[8]=e[6],o[9]=e[7],o[10]=e[8],o[11]=0,o[12]=r.x,o[13]=r.y,o[14]=r.z,o[15]=1,o):new c(e[0],e[3],e[6],r.x,e[1],e[4],e[7],r.y,e[2],e[5],e[8],r.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,r,n){a(n)||(n=new c);var o=r.x,i=r.y,u=r.z,s=e.x*e.x,E=e.x*e.y,l=e.x*e.z,f=e.x*e.w,_=e.y*e.y,R=e.y*e.z,h=e.y*e.w,T=e.z*e.z,A=e.z*e.w,d=e.w*e.w,S=s-_-T+d,m=2*(E-A),N=2*(l+h),C=2*(E+A),I=-s+_-T+d,p=2*(R-f),M=2*(l-h),O=2*(R+f),g=-s-_+T+d;return n[0]=S*o,n[1]=C*o,n[2]=M*o,n[3]=0,n[4]=m*i,n[5]=I*i,n[6]=O*i,n[7]=0,n[8]=N*u,n[9]=p*u,n[10]=g*u,n[11]=0,n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=1,n},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(s.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var l=new t,f=new t,_=new t;c.fromCamera=function(e,r){var n=e.position,o=e.direction,i=e.up;t.normalize(o,l),t.normalize(t.cross(l,i,f),f),t.normalize(t.cross(f,l,_),_);var u=f.x,s=f.y,E=f.z,R=l.x,h=l.y,T=l.z,A=_.x,d=_.y,S=_.z,m=n.x,N=n.y,C=n.z,I=u*-m+s*-N+E*-C,p=A*-m+d*-N+S*-C,M=R*m+h*N+T*C;return a(r)?(r[0]=u,r[1]=A,r[2]=-R,r[3]=0,r[4]=s,r[5]=d,r[6]=-h,r[7]=0,r[8]=E,r[9]=S,r[10]=-T,r[11]=0,r[12]=I,r[13]=p,r[14]=M,r[15]=1,r):new c(u,s,E,I,A,d,S,p,-R,-h,-T,M,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,r,n,a){var o=Math.tan(.5*t),i=1/o,u=i/e,s=(n+r)/(r-n),E=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=i,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,r,n,a,o,i){var u=1/(e-t),s=1/(n-r),E=1/(o-a),c=-(e+t)*u,l=-(n+r)*s,f=-(o+a)*E;return u*=2,s*=2,E*=-2,i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=c,i[13]=l,i[14]=f,i[15]=1,i},c.computePerspectiveOffCenter=function(t,e,r,n,a,o,i){var u=2*a/(e-t),s=2*a/(n-r),E=(e+t)/(e-t),c=(n+r)/(n-r),l=-(o+a)/(o-a),f=-2*o*a/(o-a);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=E,i[9]=c,i[10]=l,i[11]=-1,i[12]=0,i[13]=0,i[14]=f,i[15]=0,i},c.computeInfinitePerspectiveOffCenter=function(t,e,r,n,a,o){var i=2*a/(e-t),u=2*a/(n-r),s=(e+t)/(e-t),E=(n+r)/(n-r),c=-2*a;return o[0]=i,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=u,o[6]=0,o[7]=0,o[8]=s,o[9]=E,o[10]=-1,o[11]=-1,o[12]=0,o[13]=0,o[14]=c,o[15]=0,o},c.computeViewportTransformation=function(t,e,r,a){t=n(t,n.EMPTY_OBJECT);var o=n(t.x,0),i=n(t.y,0),u=n(t.width,0),s=n(t.height,0);e=n(e,0),r=n(r,1);var E=.5*u,c=.5*s,l=.5*(r-e),f=E,_=c,R=l,h=o+E,T=i+c,A=e+l;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=_,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=h,a[13]=T,a[14]=A,a[15]=1,a},c.computeView=function(e,r,n,a,o){return o[0]=a.x,o[1]=n.x,o[2]=-r.x,o[3]=0,o[4]=a.y,o[5]=n.y,o[6]=-r.y,o[7]=0,o[8]=a.z,o[9]=n.z,o[10]=-r.z,o[11]=0,o[12]=-t.dot(a,e),o[13]=-t.dot(n,e),o[14]=t.dot(r,e),o[15]=1,o},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,r){var n=4*e,a=t[n],o=t[n+1],i=t[n+2],u=t[n+3];return r.x=a,r.y=o,r.z=i,r.w=u,r},c.setColumn=function(t,e,r,n){n=c.clone(t,n);var a=4*e;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},c.setTranslation=function(t,e,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=t[15],r},c.getRow=function(t,e,r){var n=t[e],a=t[e+4],o=t[e+8],i=t[e+12];return r.x=n,r.y=a,r.z=o,r.w=i,r},c.setRow=function(t,e,r,n){return n=c.clone(t,n),n[e]=r.x,n[e+4]=r.y,n[e+8]=r.z,n[e+12]=r.w,n};var R=new t;c.getScale=function(e,r){return r.x=t.magnitude(t.fromElements(e[0],e[1],e[2],R)),r.y=t.magnitude(t.fromElements(e[4],e[5],e[6],R)),r.z=t.magnitude(t.fromElements(e[8],e[9],e[10],R)),r};var h=new t;c.getMaximumScale=function(e){return c.getScale(e,h),t.maximumComponent(h)},c.multiply=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[3],u=t[4],s=t[5],E=t[6],c=t[7],l=t[8],f=t[9],_=t[10],R=t[11],h=t[12],T=t[13],A=t[14],d=t[15],S=e[0],m=e[1],N=e[2],C=e[3],I=e[4],p=e[5],M=e[6],O=e[7],g=e[8],y=e[9],F=e[10],L=e[11],v=e[12],U=e[13],P=e[14],D=e[15],w=n*S+u*m+l*N+h*C,B=a*S+s*m+f*N+T*C,x=o*S+E*m+_*N+A*C,G=i*S+c*m+R*N+d*C,b=n*I+u*p+l*M+h*O,z=a*I+s*p+f*M+T*O,H=o*I+E*p+_*M+A*O,V=i*I+c*p+R*M+d*O,X=n*g+u*y+l*F+h*L,q=a*g+s*y+f*F+T*L,W=o*g+E*y+_*F+A*L,Y=i*g+c*y+R*F+d*L,K=n*v+u*U+l*P+h*D,k=a*v+s*U+f*P+T*D,Z=o*v+E*U+_*P+A*D,j=i*v+c*U+R*P+d*D;return r[0]=w,r[1]=B,r[2]=x,r[3]=G,r[4]=b,r[5]=z,r[6]=H,r[7]=V,r[8]=X,r[9]=q,r[10]=W,r[11]=Y,r[12]=K,r[13]=k,r[14]=Z,r[15]=j,r},c.add=function(t,e,r){return r[0]=t[0]+e[0],r[1]=t[1]+e[1],r[2]=t[2]+e[2],r[3]=t[3]+e[3],r[4]=t[4]+e[4],r[5]=t[5]+e[5],r[6]=t[6]+e[6],r[7]=t[7]+e[7],r[8]=t[8]+e[8],r[9]=t[9]+e[9],r[10]=t[10]+e[10],r[11]=t[11]+e[11],r[12]=t[12]+e[12],r[13]=t[13]+e[13],r[14]=t[14]+e[14],r[15]=t[15]+e[15],r},c.subtract=function(t,e,r){return r[0]=t[0]-e[0],r[1]=t[1]-e[1],r[2]=t[2]-e[2],r[3]=t[3]-e[3],r[4]=t[4]-e[4],r[5]=t[5]-e[5],r[6]=t[6]-e[6],r[7]=t[7]-e[7],r[8]=t[8]-e[8],r[9]=t[9]-e[9],r[10]=t[10]-e[10],r[11]=t[11]-e[11],r[12]=t[12]-e[12],r[13]=t[13]-e[13],r[14]=t[14]-e[14],r[15]=t[15]-e[15],r},c.multiplyTransformation=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[4],u=t[5],s=t[6],E=t[8],c=t[9],l=t[10],f=t[12],_=t[13],R=t[14],h=e[0],T=e[1],A=e[2],d=e[4],S=e[5],m=e[6],N=e[8],C=e[9],I=e[10],p=e[12],M=e[13],O=e[14],g=n*h+i*T+E*A,y=a*h+u*T+c*A,F=o*h+s*T+l*A,L=n*d+i*S+E*m,v=a*d+u*S+c*m,U=o*d+s*S+l*m,P=n*N+i*C+E*I,D=a*N+u*C+c*I,w=o*N+s*C+l*I,B=n*p+i*M+E*O+f,x=a*p+u*M+c*O+_,G=o*p+s*M+l*O+R;return r[0]=g,r[1]=y,r[2]=F,r[3]=0,r[4]=L,r[5]=v,r[6]=U,r[7]=0,r[8]=P,r[9]=D,r[10]=w,r[11]=0,r[12]=B,r[13]=x,r[14]=G,r[15]=1,r},c.multiplyByMatrix3=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[4],u=t[5],s=t[6],E=t[8],c=t[9],l=t[10],f=e[0],_=e[1],R=e[2],h=e[3],T=e[4],A=e[5],d=e[6],S=e[7],m=e[8],N=n*f+i*_+E*R,C=a*f+u*_+c*R,I=o*f+s*_+l*R,p=n*h+i*T+E*A,M=a*h+u*T+c*A,O=o*h+s*T+l*A,g=n*d+i*S+E*m,y=a*d+u*S+c*m,F=o*d+s*S+l*m;return r[0]=N,r[1]=C,r[2]=I,r[3]=0,r[4]=p,r[5]=M,r[6]=O,r[7]=0,r[8]=g,r[9]=y,r[10]=F,r[11]=0,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15],r},c.multiplyByTranslation=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=n*t[0]+a*t[4]+o*t[8]+t[12],u=n*t[1]+a*t[5]+o*t[9]+t[13],s=n*t[2]+a*t[6]+o*t[10]+t[14];return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=i,r[13]=u,r[14]=s,r[15]=t[15],r};var T=new t;c.multiplyByUniformScale=function(t,e,r){return T.x=e,T.y=e,T.z=e,c.multiplyByScale(t,T,r)},c.multiplyByScale=function(t,e,r){var n=e.x,a=e.y,o=e.z;return 1===n&&1===a&&1===o?c.clone(t,r):(r[0]=n*t[0],r[1]=n*t[1],r[2]=n*t[2],r[3]=0,r[4]=a*t[4],r[5]=a*t[5],r[6]=a*t[6],r[7]=0,r[8]=o*t[8],r[9]=o*t[9],r[10]=o*t[10],r[11]=0,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=1,r)},c.multiplyByVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=e.w,u=t[0]*n+t[4]*a+t[8]*o+t[12]*i,s=t[1]*n+t[5]*a+t[9]*o+t[13]*i,E=t[2]*n+t[6]*a+t[10]*o+t[14]*i,c=t[3]*n+t[7]*a+t[11]*o+t[15]*i;return r.x=u,r.y=s,r.z=E,r.w=c,r},c.multiplyByPointAsVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[4]*a+t[8]*o,u=t[1]*n+t[5]*a+t[9]*o,s=t[2]*n+t[6]*a+t[10]*o;return r.x=i,r.y=u,r.z=s,r},c.multiplyByPoint=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[4]*a+t[8]*o+t[12],u=t[1]*n+t[5]*a+t[9]*o+t[13],s=t[2]*n+t[6]*a+t[10]*o+t[14];return r.x=i,r.y=u,r.z=s,r},c.multiplyByScalar=function(t,e,r){return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*e,r[5]=t[5]*e,r[6]=t[6]*e,r[7]=t[7]*e,r[8]=t[8]*e,r[9]=t[9]*e,r[10]=t[10]*e,r[11]=t[11]*e,r[12]=t[12]*e,r[13]=t[13]*e,r[14]=t[14]*e,r[15]=t[15]*e,r},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var r=t[1],n=t[2],a=t[3],o=t[6],i=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=r,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=n,e[9]=o,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=i,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,r){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=r&&Math.abs(t[1]-e[1])<=r&&Math.abs(t[2]-e[2])<=r&&Math.abs(t[3]-e[3])<=r&&Math.abs(t[4]-e[4])<=r&&Math.abs(t[5]-e[5])<=r&&Math.abs(t[6]-e[6])<=r&&Math.abs(t[7]-e[7])<=r&&Math.abs(t[8]-e[8])<=r&&Math.abs(t[9]-e[9])<=r&&Math.abs(t[10]-e[10])<=r&&Math.abs(t[11]-e[11])<=r&&Math.abs(t[12]-e[12])<=r&&Math.abs(t[13]-e[13])<=r&&Math.abs(t[14]-e[14])<=r&&Math.abs(t[15]-e[15])<=r},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var A=new s,d=new s,S=new e,m=new e(0,0,0,1);return c.inverse=function(t,r){if(s.equalsEpsilon(c.getRotation(t,A),d,u.EPSILON7)&&e.equals(c.getRow(t,3,S),m))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-t[12],r[13]=-t[13],r[14]=-t[14],r[15]=1,r;var n=t[0],a=t[4],o=t[8],i=t[12],l=t[1],f=t[5],_=t[9],R=t[13],h=t[2],T=t[6],N=t[10],C=t[14],I=t[3],p=t[7],M=t[11],O=t[15],g=N*O,y=C*M,F=T*O,L=C*p,v=T*M,U=N*p,P=h*O,D=C*I,w=h*M,B=N*I,x=h*p,G=T*I,b=g*f+L*_+v*R-(y*f+F*_+U*R),z=y*l+P*_+B*R-(g*l+D*_+w*R),H=F*l+D*f+x*R-(L*l+P*f+G*R),V=U*l+w*f+G*_-(v*l+B*f+x*_),X=y*a+F*o+U*i-(g*a+L*o+v*i),q=g*n+D*o+w*i-(y*n+P*o+B*i),W=L*n+P*a+G*i-(F*n+D*a+x*i),Y=v*n+B*a+x*o-(U*n+w*a+G*o);g=o*R,y=i*_,F=a*R,L=i*f,v=a*_,U=o*f,P=n*R,D=i*l,w=n*_,B=o*l,x=n*f,G=a*l;var K=g*p+L*M+v*O-(y*p+F*M+U*O),k=y*I+P*M+B*O-(g*I+D*M+w*O),Z=F*I+D*p+x*O-(L*I+P*p+G*O),j=U*I+w*p+G*M-(v*I+B*p+x*M),Q=F*N+U*C+y*T-(v*C+g*T+L*N),J=w*C+g*h+D*N-(P*N+B*C+y*h),$=P*T+G*C+L*h-(x*C+F*h+D*T),tt=x*N+v*h+B*T-(w*T+G*N+U*h),et=n*b+a*z+o*H+i*V;if(Math.abs(et)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return et=1/et,r[0]=b*et,r[1]=z*et,r[2]=H*et,r[3]=V*et,r[4]=X*et,r[5]=q*et,r[6]=W*et,r[7]=Y*et,r[8]=K*et,r[9]=k*et,r[10]=Z*et,r[11]=j*et,r[12]=Q*et,r[13]=J*et,r[14]=$*et,r[15]=tt*et,r},c.inverseTransformation=function(t,e){var r=t[0],n=t[1],a=t[2],o=t[4],i=t[5],u=t[6],s=t[8],E=t[9],c=t[10],l=t[12],f=t[13],_=t[14],R=-r*l-n*f-a*_,h=-o*l-i*f-u*_,T=-s*l-E*f-c*_;return e[0]=r,e[1]=o,e[2]=s,e[3]=0,e[4]=n,e[5]=i,e[6]=E,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=R,e[13]=h,e[14]=T,e[15]=1,e},c.IDENTITY=i(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=i(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,o(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,r){return t[0]===e[r]&&t[1]===e[r+1]&&t[2]===e[r+2]&&t[3]===e[r+3]&&t[4]===e[r+4]&&t[5]===e[r+5]&&t[6]===e[r+6]&&t[7]===e[r+7]&&t[8]===e[r+8]&&t[9]===e[r+9]&&t[10]===e[r+10]&&t[11]===e[r+11]&&t[12]===e[r+12]&&t[13]===e[r+13]&&t[14]===e[r+14]&&t[15]===e[r+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t,e,n,a){this.west=r(t,0),this.south=r(e,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,n){return n=r(n,0),e[n++]=t.west,e[n++]=t.south,e[n++]=t.east,e[n]=t.north,e},s.unpack=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},s.computeWidth=function(t){var e=t.east,r=t.west;return e<r&&(e+=u.TWO_PI),e-r},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,a,o,i){return t=u.toRadians(r(t,0)),e=u.toRadians(r(e,0)),a=u.toRadians(r(a,0)),o=u.toRadians(r(o,0)),n(i)?(i.west=t,i.south=e,i.east=a,i.north=o,i):new s(t,e,a,o)},s.fromRadians=function(t,e,a,o,i){return n(i)?(i.west=r(t,0),i.south=r(e,0),i.east=r(a,0),i.north=r(o,0),i):new s(t,e,a,o)},s.fromCartographicArray=function(t,e){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,o=Number.MAX_VALUE,i=-Number.MAX_VALUE,E=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=0,f=t.length;l<f;l++){var _=t[l];r=Math.min(r,_.longitude),a=Math.max(a,_.longitude),E=Math.min(E,_.latitude),c=Math.max(c,_.latitude);var R=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;o=Math.min(o,R),i=Math.max(i,R)}return a-r>i-o&&(r=o,a=i,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(e)?(e.west=r,e.south=E,e.east=a,e.north=c,e):new s(r,E,a,c)},s.fromCartesianArray=function(t,e,a){e=r(e,o.WGS84);for(var i=Number.MAX_VALUE,E=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=0,h=t.length;R<h;R++){var T=e.cartesianToCartographic(t[R]);i=Math.min(i,T.longitude),E=Math.max(E,T.longitude),f=Math.min(f,T.latitude),_=Math.max(_,T.latitude);var A=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;c=Math.min(c,A),l=Math.max(l,A)}return E-i>l-c&&(i=c,E=l,E>u.PI&&(E-=u.TWO_PI),i>u.PI&&(i-=u.TWO_PI)),n(a)?(a.west=i,a.south=f,a.east=E,a.north=_,a):new s(i,f,E,_)},s.clone=function(t,e){if(n(t))return n(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||n(t)&&n(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return n(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,r){return n(r)?(r.longitude=e.west,r.latitude=e.south,r.height=0,r):new t(e.west,e.south)},s.northwest=function(e,r){return n(r)?(r.longitude=e.west,r.latitude=e.north,r.height=0,r):new t(e.west,e.north)},s.northeast=function(e,r){return n(r)?(r.longitude=e.east,r.latitude=e.north,r.height=0,r):new t(e.east,e.north)},s.southeast=function(e,r){return n(r)?(r.longitude=e.east,r.latitude=e.south,r.height=0,r):new t(e.east,e.south)},s.center=function(e,r){var a=e.east,o=e.west;a<o&&(a+=u.TWO_PI);var i=u.negativePiToPi(.5*(o+a)),s=.5*(e.south+e.north);return n(r)?(r.longitude=i,r.latitude=s,r.height=0,r):new t(i,s)},s.intersection=function(t,e,r){var a=t.east,o=t.west,i=e.east,E=e.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var c=u.negativePiToPi(Math.max(o,E)),l=u.negativePiToPi(Math.min(a,i));if(!((t.west<t.east||e.west<e.east)&&l<=c)){var f=Math.max(t.south,e.south),_=Math.min(t.north,e.north);if(!(f>=_))return n(r)?(r.west=c,r.south=f,r.east=l,r.north=_,r):new s(c,f,l,_)}},s.simpleIntersection=function(t,e,r){var a=Math.max(t.west,e.west),o=Math.max(t.south,e.south),i=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(o>=u||a>=i))return n(r)?(r.west=a,r.south=o,r.east=i,r.north=u,r):new s(a,o,i,u)},s.union=function(t,e,r){n(r)||(r=new s);var a=t.east,o=t.west,i=e.east,E=e.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(o,E)),l=u.convertLongitudeRange(Math.max(a,i));return r.west=c,r.south=Math.min(t.south,e.south),r.east=l,r.north=Math.max(t.north,e.north),r},s.expand=function(t,e,r){return n(r)||(r=new s),r.west=Math.min(t.west,e.longitude),r.south=Math.min(t.south,e.latitude),r.east=Math.max(t.east,e.longitude),r.north=Math.max(t.north,e.latitude),r},s.contains=function(t,e){var r=e.longitude,n=e.latitude,a=t.west,o=t.east;return o<a&&(o+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<o||u.equalsEpsilon(r,o,u.EPSILON14))&&n>=t.south&&n<=t.north};var E=new t;return s.subsample=function(t,e,a,i){e=r(e,o.WGS84),a=r(a,0),n(i)||(i=[]);var c=0,l=t.north,f=t.south,_=t.east,R=t.west,h=E;h.height=a,h.longitude=R,h.latitude=l,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.longitude=_,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.latitude=f,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.longitude=R,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.latitude=l<0?l:f>0?f:0;for(var T=1;T<8;++T)h.longitude=-Math.PI+T*u.PI_OVER_TWO,s.contains(t,h)&&(i[c]=e.cartographicToCartesian(h,i[c]),c++);return 0===h.latitude&&(h.longitude=R,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.longitude=_,i[c]=e.cartographicToCartesian(h,i[c]),c++),i.length=c,i},s.MAX_VALUE=i(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,r,n,a,o,i,u,s,E,c,l){"use strict";function f(e,r){this.center=t.clone(n(e,t.ZERO)),this.radius=n(r,0)}var _=new t,R=new t,h=new t,T=new t,A=new t,d=new t,S=new t,m=new t,N=new t,C=new t,I=new t,p=new t;f.fromPoints=function(e,r){if(a(r)||(r=new f),!a(e)||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var n,o=t.clone(e[0],S),i=t.clone(o,_),u=t.clone(o,R),s=t.clone(o,h),E=t.clone(o,T),c=t.clone(o,A),l=t.clone(o,d),M=e.length;for(n=1;n<M;n++){t.clone(e[n],o);var O=o.x,g=o.y,y=o.z;O<i.x&&t.clone(o,i),O>E.x&&t.clone(o,E),g<u.y&&t.clone(o,u),g>c.y&&t.clone(o,c),y<s.z&&t.clone(o,s),y>l.z&&t.clone(o,l)}var F=t.magnitudeSquared(t.subtract(E,i,m)),L=t.magnitudeSquared(t.subtract(c,u,m)),v=t.magnitudeSquared(t.subtract(l,s,m)),U=i,P=E,D=F;L>D&&(D=L,U=u,P=c),v>D&&(D=v,U=s,P=l);var w=N;w.x=.5*(U.x+P.x),w.y=.5*(U.y+P.y),w.z=.5*(U.z+P.z);var B=t.magnitudeSquared(t.subtract(P,w,m)),x=Math.sqrt(B),G=C;G.x=i.x,G.y=u.y,G.z=s.z;var b=I;b.x=E.x,b.y=c.y,b.z=l.z;var z=t.multiplyByScalar(t.add(G,b,m),.5,p),H=0;for(n=0;n<M;n++){t.clone(e[n],o);var V=t.magnitude(t.subtract(o,z,m));V>H&&(H=V);var X=t.magnitudeSquared(t.subtract(o,w,m));if(X>B){var q=Math.sqrt(X);x=.5*(x+q),B=x*x;var W=q-x;w.x=(x*w.x+W*o.x)/q,w.y=(x*w.y+W*o.y)/q,w.z=(x*w.z+W*o.z)/q}}return x<H?(t.clone(w,r.center),r.radius=x):(t.clone(z,r.center),r.radius=H),r};var M=new i,O=new t,g=new t,y=new e,F=new e;f.fromRectangle2D=function(t,e,r){return f.fromRectangleWithHeights2D(t,e,0,0,r)},f.fromRectangleWithHeights2D=function(e,r,o,i,u){if(a(u)||(u=new f),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;r=n(r,M),l.southwest(e,y),y.height=o,l.northeast(e,F),F.height=i;var s=r.project(y,O),E=r.project(F,g),c=E.x-s.x,_=E.y-s.y,R=E.z-s.z;u.radius=.5*Math.sqrt(c*c+_*_+R*R);var h=u.center;return h.x=s.x+.5*c,h.y=s.y+.5*_,h.z=s.z+.5*R,u};var L=[];f.fromRectangle3D=function(e,r,i,u){if(r=n(r,o.WGS84),i=n(i,0),a(u)||(u=new f),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=l.subsample(e,r,i,L);return f.fromPoints(s,u)},f.fromVertices=function(e,r,o,i){if(a(i)||(i=new f),!a(e)||0===e.length)return i.center=t.clone(t.ZERO,i.center),i.radius=0,i;r=n(r,t.ZERO),o=n(o,3);var u=S;u.x=e[0]+r.x,u.y=e[1]+r.y,u.z=e[2]+r.z;var s,E=t.clone(u,_),c=t.clone(u,R),l=t.clone(u,h),M=t.clone(u,T),O=t.clone(u,A),g=t.clone(u,d),y=e.length;for(s=0;s<y;s+=o){var F=e[s]+r.x,L=e[s+1]+r.y,v=e[s+2]+r.z;u.x=F,u.y=L,u.z=v,F<E.x&&t.clone(u,E),F>M.x&&t.clone(u,M),L<c.y&&t.clone(u,c),L>O.y&&t.clone(u,O),v<l.z&&t.clone(u,l),v>g.z&&t.clone(u,g)}var U=t.magnitudeSquared(t.subtract(M,E,m)),P=t.magnitudeSquared(t.subtract(O,c,m)),D=t.magnitudeSquared(t.subtract(g,l,m)),w=E,B=M,x=U;P>x&&(x=P,w=c,B=O),D>x&&(x=D,w=l,B=g);var G=N;G.x=.5*(w.x+B.x),G.y=.5*(w.y+B.y),G.z=.5*(w.z+B.z);var b=t.magnitudeSquared(t.subtract(B,G,m)),z=Math.sqrt(b),H=C;H.x=E.x,H.y=c.y,H.z=l.z;var V=I;V.x=M.x,V.y=O.y,V.z=g.z;var X=t.multiplyByScalar(t.add(H,V,m),.5,p),q=0;for(s=0;s<y;s+=o){u.x=e[s]+r.x,u.y=e[s+1]+r.y,u.z=e[s+2]+r.z;var W=t.magnitude(t.subtract(u,X,m));W>q&&(q=W);var Y=t.magnitudeSquared(t.subtract(u,G,m));if(Y>b){var K=Math.sqrt(Y);z=.5*(z+K),b=z*z;var k=K-z;G.x=(z*G.x+k*u.x)/K,G.y=(z*G.y+k*u.y)/K,G.z=(z*G.z+k*u.z)/K}}return z<q?(t.clone(G,i.center),i.radius=z):(t.clone(X,i.center),i.radius=q),i},f.fromEncodedCartesianVertices=function(e,r,n){if(a(n)||(n=new f),!a(e)||!a(r)||e.length!==r.length||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var o=S;o.x=e[0]+r[0],o.y=e[1]+r[1],o.z=e[2]+r[2];var i,u=t.clone(o,_),s=t.clone(o,R),E=t.clone(o,h),c=t.clone(o,T),l=t.clone(o,A),M=t.clone(o,d),O=e.length;for(i=0;i<O;i+=3){var g=e[i]+r[i],y=e[i+1]+r[i+1],F=e[i+2]+r[i+2];o.x=g,o.y=y,o.z=F,g<u.x&&t.clone(o,u),g>c.x&&t.clone(o,c),y<s.y&&t.clone(o,s),y>l.y&&t.clone(o,l),F<E.z&&t.clone(o,E),F>M.z&&t.clone(o,M)}var L=t.magnitudeSquared(t.subtract(c,u,m)),v=t.magnitudeSquared(t.subtract(l,s,m)),U=t.magnitudeSquared(t.subtract(M,E,m)),P=u,D=c,w=L;v>w&&(w=v,P=s,D=l),U>w&&(w=U,P=E,D=M);var B=N;B.x=.5*(P.x+D.x),B.y=.5*(P.y+D.y),B.z=.5*(P.z+D.z);var x=t.magnitudeSquared(t.subtract(D,B,m)),G=Math.sqrt(x),b=C;b.x=u.x,b.y=s.y,b.z=E.z;var z=I;z.x=c.x,z.y=l.y,z.z=M.z;var H=t.multiplyByScalar(t.add(b,z,m),.5,p),V=0;for(i=0;i<O;i+=3){o.x=e[i]+r[i],o.y=e[i+1]+r[i+1],o.z=e[i+2]+r[i+2];var X=t.magnitude(t.subtract(o,H,m));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(o,B,m));if(q>x){var W=Math.sqrt(q);G=.5*(G+W),x=G*G;var Y=W-G;B.x=(G*B.x+Y*o.x)/W,B.y=(G*B.y+Y*o.y)/W,B.z=(G*B.z+Y*o.z)/W}}return G<V?(t.clone(B,n.center),n.radius=G):(t.clone(H,n.center),n.radius=V),n},f.fromCornerPoints=function(e,r,n){a(n)||(n=new f);var o=n.center;return t.add(e,r,o),t.multiplyByScalar(o,.5,o),n.radius=t.distance(o,r),n},f.fromEllipsoid=function(e,r){return a(r)||(r=new f),t.clone(t.ZERO,r.center),r.radius=e.maximumRadius,r};var v=new t;f.fromBoundingSpheres=function(e,r){if(a(r)||(r=new f),!a(e)||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var n=e.length;if(1===n)return f.clone(e[0],r);if(2===n)return f.union(e[0],e[1],r);var o,i=[];for(o=0;o<n;o++)i.push(e[o].center);r=f.fromPoints(i,r);var u=r.center,s=r.radius;for(o=0;o<n;o++){var E=e[o];s=Math.max(s,t.distance(u,E.center,v)+E.radius)}return r.radius=s,r};var U=new t,P=new t,D=new t;f.fromOrientedBoundingBox=function(e,r){a(r)||(r=new f);var n=e.halfAxes,o=E.getColumn(n,0,U),i=E.getColumn(n,1,P),u=E.getColumn(n,2,D);return t.add(o,i,o),t.add(o,u,o),r.center=t.clone(e.center,r.center),r.radius=t.magnitude(o),r},f.clone=function(e,r){if(a(e))return a(r)?(r.center=t.clone(e.center,r.center),r.radius=e.radius,r):new f(e.center,e.radius)},f.packedLength=4,f.pack=function(t,e,r){r=n(r,0);var a=t.center;return e[r++]=a.x,e[r++]=a.y,e[r++]=a.z,e[r]=t.radius,e},f.unpack=function(t,e,r){e=n(e,0),a(r)||(r=new f);var o=r.center;return o.x=t[e++],o.y=t[e++],o.z=t[e++],r.radius=t[e],r};var w=new t,B=new t;f.union=function(e,r,n){a(n)||(n=new f);var o=e.center,i=e.radius,u=r.center,s=r.radius,E=t.subtract(u,o,w),c=t.magnitude(E);if(i>=c+s)return e.clone(n),n;if(s>=c+i)return r.clone(n),n;var l=.5*(i+c+s),_=t.multiplyByScalar(E,(-i+l)/c,B);return t.add(_,o,_),t.clone(_,n.center),n.radius=l,n};var x=new t;f.expand=function(e,r,n){n=f.clone(e,n);var a=t.magnitude(t.subtract(r,n.center,x));return a>n.radius&&(n.radius=a),n},f.intersectPlane=function(e,r){var n=e.center,a=e.radius,o=r.normal,i=t.dot(o,n)+r.distance;return i<-a?u.OUTSIDE:i<a?u.INTERSECTING:u.INSIDE},f.transform=function(t,e,r){return a(r)||(r=new f),r.center=c.multiplyByPoint(e,t.center,r.center),r.radius=c.getMaximumScale(e)*t.radius,r};var G=new t;f.distanceSquaredTo=function(e,r){var n=t.subtract(e.center,r,G);return t.magnitudeSquared(n)-e.radius*e.radius},f.transformWithoutScale=function(t,e,r){return a(r)||(r=new f),r.center=c.multiplyByPoint(e,t.center,r.center),r.radius=t.radius,r};var b=new t;f.computePlaneDistances=function(e,r,n,o){a(o)||(o=new s);var i=t.subtract(e.center,r,b),u=t.dot(n,i);return o.start=u-e.radius,o.stop=u+e.radius,o};for(var z=new t,H=new t,V=new t,X=new t,q=new t,W=new e,Y=new Array(8),K=0;K<8;++K)Y[K]=new t;var k=new i;return f.projectTo2D=function(e,r,a){r=n(r,k);var o=r.ellipsoid,i=e.center,u=e.radius,s=o.geodeticSurfaceNormal(i,z),E=t.cross(t.UNIT_Z,s,H);t.normalize(E,E);var c=t.cross(s,E,V);t.normalize(c,c),t.multiplyByScalar(s,u,s),t.multiplyByScalar(c,u,c),t.multiplyByScalar(E,u,E);var l=t.negate(c,q),_=t.negate(E,X),R=Y,h=R[0];t.add(s,c,h),t.add(h,E,h),h=R[1],t.add(s,c,h),t.add(h,_,h),h=R[2],t.add(s,l,h),t.add(h,_,h),h=R[3],t.add(s,l,h),t.add(h,E,h),t.negate(s,s),h=R[4],t.add(s,c,h),t.add(h,E,h),h=R[5],t.add(s,c,h),t.add(h,_,h),h=R[6],t.add(s,l,h),t.add(h,_,h),h=R[7],t.add(s,l,h),t.add(h,E,h);for(var T=R.length,A=0;A<T;++A){var d=R[A];t.add(i,d,d);var S=o.cartesianToCartographic(d,W);r.project(S,d)}a=f.fromPoints(R,a),i=a.center;var m=i.x,N=i.y,C=i.z;return i.x=C,i.y=m,i.z=N,a},f.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},f.equals=function(e,r){return e===r||a(e)&&a(r)&&t.equals(e.center,r.center)&&e.radius===r.radius},f.prototype.intersectPlane=function(t){return f.intersectPlane(this,t)},f.prototype.distanceSquaredTo=function(t){return f.distanceSquaredTo(this,t)},f.prototype.computePlaneDistances=function(t,e,r){return f.computePlaneDistances(this,t,e,r)},f.prototype.isOccluded=function(t){return f.isOccluded(this,t)},f.prototype.equals=function(t){return f.equals(this,t)},f.prototype.clone=function(t){return f.clone(this,t)},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(r))return r;r=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,o=["webkit","moz","o","ms","khtml"],i=0,u=o.length;i<u;++i){var s=o[i];a=s+"RequestFullscreen","function"==typeof e[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof e[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[n.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,r){"use strict";function n(t){for(var e=t.split("."),r=0,n=e.length;r<n;++r)e[r]=parseInt(e[r],10);return e}function a(){if(!e(N)&&(N=!1,!f())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(N=!0,C=n(t[1]))}return N}function o(){return a()&&C}function i(){if(!e(I)&&(I=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){ -var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(I=!0,p=n(t[1]))}return I}function u(){return i()&&p}function s(){if(!e(M)){M=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(M=!0,O=n(t[1]),O.isNightly=!!t[2])}return M}function E(){return s()&&O}function c(){if(!e(g)){g=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(t[1]))}return g}function l(){return c()&&y}function f(){if(!e(F)){F=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(F=!0,L=n(t[1]))}return F}function _(){return f()&&L}function R(){if(!e(v)){v=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(v=!0,U=n(t[1]))}return v}function h(){return e(P)||(P=/Windows/i.test(m.appVersion)),P}function T(){return R()&&U}function A(){return e(D)||(D="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),D}function d(){if(!e(B)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=t.style.imageRendering;B=e(r)&&""!==r,B&&(w=r)}return B}function S(){return d()?w:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var N,C,I,p,M,O,g,y,F,L,v,U,P,D,w,B,x={isChrome:a,chromeVersion:o,isSafari:i,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:c,internetExplorerVersion:l,isEdge:f,edgeVersion:_,isFirefox:R,firefoxVersion:T,isWindows:h,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:A,supportsImageRenderingPixelated:d,imageRenderingValue:S};return x.supportsFullscreen=function(){return r.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/Color",["./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,e,r){return r<0&&(r+=1),r>1&&(r-=1),6*r<1?t+6*(e-t)*r:2*r<1?e:3*r<2?t+(e-t)*(2/3-r)*6:t}function u(t,r,n,a){this.red=e(t,1),this.green=e(r,1),this.blue=e(n,1),this.alpha=e(a,1)}u.fromCartesian4=function(t,e){return r(e)?(e.red=t.x,e.green=t.y,e.blue=t.z,e.alpha=t.w,e):new u(t.x,t.y,t.z,t.w)},u.fromBytes=function(t,n,a,o,i){return t=u.byteToFloat(e(t,255)),n=u.byteToFloat(e(n,255)),a=u.byteToFloat(e(a,255)),o=u.byteToFloat(e(o,255)),r(i)?(i.red=t,i.green=n,i.blue=a,i.alpha=o,i):new u(t,n,a,o)},u.fromAlpha=function(t,e,n){return r(n)?(n.red=t.red,n.green=t.green,n.blue=t.blue,n.alpha=e,n):new u(t.red,t.green,t.blue,e)};var s,E,c;n.supportsTypedArrays()&&(s=new ArrayBuffer(4),E=new Uint32Array(s),c=new Uint8Array(s)),u.fromRgba=function(t,e){return E[0]=t,u.fromBytes(c[0],c[1],c[2],c[3],e)},u.fromHsl=function(t,n,a,o,s){t=e(t,0)%1,n=e(n,0),a=e(a,0),o=e(o,1);var E=a,c=a,l=a;if(0!==n){var f;f=a<.5?a*(1+n):a+n-a*n;var _=2*a-f;E=i(_,f,t+1/3),c=i(_,f,t),l=i(_,f,t-1/3)}return r(s)?(s.red=E,s.green=c,s.blue=l,s.alpha=o,s):new u(E,c,l,o)},u.fromRandom=function(t,n){t=e(t,e.EMPTY_OBJECT);var a=t.red;if(!r(a)){var i=e(t.minimumRed,0),s=e(t.maximumRed,1);a=i+o.nextRandomNumber()*(s-i)}var E=t.green;if(!r(E)){var c=e(t.minimumGreen,0),l=e(t.maximumGreen,1);E=c+o.nextRandomNumber()*(l-c)}var f=t.blue;if(!r(f)){var _=e(t.minimumBlue,0),R=e(t.maximumBlue,1);f=_+o.nextRandomNumber()*(R-_)}var h=t.alpha;if(!r(h)){var T=e(t.minimumAlpha,0),A=e(t.maximumAlpha,1);h=T+o.nextRandomNumber()*(A-T)}return r(n)?(n.red=a,n.green=E,n.blue=f,n.alpha=h,n):new u(a,E,f,h)};var l=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,f=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,_=/^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i,R=/^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i;return u.fromCssColorString=function(t,n){r(n)||(n=new u);var a=u[t.toUpperCase()];if(r(a))return u.clone(a,n),n;var o=l.exec(t);return null!==o?(n.red=parseInt(o[1],16)/15,n.green=parseInt(o[2],16)/15,n.blue=parseInt(o[3],16)/15,n.alpha=1,n):null!==(o=f.exec(t))?(n.red=parseInt(o[1],16)/255,n.green=parseInt(o[2],16)/255,n.blue=parseInt(o[3],16)/255,n.alpha=1,n):null!==(o=_.exec(t))?(n.red=parseFloat(o[1])/("%"===o[1].substr(-1)?100:255),n.green=parseFloat(o[2])/("%"===o[2].substr(-1)?100:255),n.blue=parseFloat(o[3])/("%"===o[3].substr(-1)?100:255),n.alpha=parseFloat(e(o[4],"1.0")),n):null!==(o=R.exec(t))?u.fromHsl(parseFloat(o[1])/360,parseFloat(o[2])/100,parseFloat(o[3])/100,parseFloat(e(o[4],"1.0")),n):n=void 0},u.packedLength=4,u.pack=function(t,r,n){return n=e(n,0),r[n++]=t.red,r[n++]=t.green,r[n++]=t.blue,r[n]=t.alpha,r},u.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new u),a.red=t[n++],a.green=t[n++],a.blue=t[n++],a.alpha=t[n],a},u.byteToFloat=function(t){return t/255},u.floatToByte=function(t){return 1===t?255:256*t|0},u.clone=function(t,e){if(r(t))return r(e)?(e.red=t.red,e.green=t.green,e.blue=t.blue,e.alpha=t.alpha,e):new u(t.red,t.green,t.blue,t.alpha)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.red===e.red&&t.green===e.green&&t.blue===e.blue&&t.alpha===e.alpha},u.equalsArray=function(t,e,r){return t.red===e[r]&&t.green===e[r+1]&&t.blue===e[r+2]&&t.alpha===e[r+3]},u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return this===t||r(t)&&Math.abs(this.red-t.red)<=e&&Math.abs(this.green-t.green)<=e&&Math.abs(this.blue-t.blue)<=e&&Math.abs(this.alpha-t.alpha)<=e},u.prototype.toString=function(){return"("+this.red+", "+this.green+", "+this.blue+", "+this.alpha+")"},u.prototype.toCssColorString=function(){var t=u.floatToByte(this.red),e=u.floatToByte(this.green),r=u.floatToByte(this.blue);return 1===this.alpha?"rgb("+t+","+e+","+r+")":"rgba("+t+","+e+","+r+","+this.alpha+")"},u.prototype.toBytes=function(t){var e=u.floatToByte(this.red),n=u.floatToByte(this.green),a=u.floatToByte(this.blue),o=u.floatToByte(this.alpha);return r(t)?(t[0]=e,t[1]=n,t[2]=a,t[3]=o,t):[e,n,a,o]},u.prototype.toRgba=function(){return c[0]=u.floatToByte(this.red),c[1]=u.floatToByte(this.green),c[2]=u.floatToByte(this.blue),c[3]=u.floatToByte(this.alpha),E[0]},u.prototype.brighten=function(t,e){return t=1-t,e.red=1-(1-this.red)*t,e.green=1-(1-this.green)*t,e.blue=1-(1-this.blue)*t,e.alpha=this.alpha,e},u.prototype.darken=function(t,e){return t=1-t,e.red=this.red*t,e.green=this.green*t,e.blue=this.blue*t,e.alpha=this.alpha,e},u.prototype.withAlpha=function(t,e){return u.fromAlpha(this,t,e)},u.add=function(t,e,r){return r.red=t.red+e.red,r.green=t.green+e.green,r.blue=t.blue+e.blue,r.alpha=t.alpha+e.alpha,r},u.subtract=function(t,e,r){return r.red=t.red-e.red,r.green=t.green-e.green,r.blue=t.blue-e.blue,r.alpha=t.alpha-e.alpha,r},u.multiply=function(t,e,r){return r.red=t.red*e.red,r.green=t.green*e.green,r.blue=t.blue*e.blue,r.alpha=t.alpha*e.alpha,r},u.divide=function(t,e,r){return r.red=t.red/e.red,r.green=t.green/e.green,r.blue=t.blue/e.blue,r.alpha=t.alpha/e.alpha,r},u.mod=function(t,e,r){return r.red=t.red%e.red,r.green=t.green%e.green,r.blue=t.blue%e.blue,r.alpha=t.alpha%e.alpha,r},u.multiplyByScalar=function(t,e,r){return r.red=t.red*e,r.green=t.green*e,r.blue=t.blue*e,r.alpha=t.alpha*e,r},u.divideByScalar=function(t,e,r){return r.red=t.red/e,r.green=t.green/e,r.blue=t.blue/e,r.alpha=t.alpha/e,r},u.ALICEBLUE=a(u.fromCssColorString("#F0F8FF")),u.ANTIQUEWHITE=a(u.fromCssColorString("#FAEBD7")),u.AQUA=a(u.fromCssColorString("#00FFFF")),u.AQUAMARINE=a(u.fromCssColorString("#7FFFD4")),u.AZURE=a(u.fromCssColorString("#F0FFFF")),u.BEIGE=a(u.fromCssColorString("#F5F5DC")),u.BISQUE=a(u.fromCssColorString("#FFE4C4")),u.BLACK=a(u.fromCssColorString("#000000")),u.BLANCHEDALMOND=a(u.fromCssColorString("#FFEBCD")),u.BLUE=a(u.fromCssColorString("#0000FF")),u.BLUEVIOLET=a(u.fromCssColorString("#8A2BE2")),u.BROWN=a(u.fromCssColorString("#A52A2A")),u.BURLYWOOD=a(u.fromCssColorString("#DEB887")),u.CADETBLUE=a(u.fromCssColorString("#5F9EA0")),u.CHARTREUSE=a(u.fromCssColorString("#7FFF00")),u.CHOCOLATE=a(u.fromCssColorString("#D2691E")),u.CORAL=a(u.fromCssColorString("#FF7F50")),u.CORNFLOWERBLUE=a(u.fromCssColorString("#6495ED")),u.CORNSILK=a(u.fromCssColorString("#FFF8DC")),u.CRIMSON=a(u.fromCssColorString("#DC143C")),u.CYAN=a(u.fromCssColorString("#00FFFF")),u.DARKBLUE=a(u.fromCssColorString("#00008B")),u.DARKCYAN=a(u.fromCssColorString("#008B8B")),u.DARKGOLDENROD=a(u.fromCssColorString("#B8860B")),u.DARKGRAY=a(u.fromCssColorString("#A9A9A9")),u.DARKGREEN=a(u.fromCssColorString("#006400")),u.DARKGREY=u.DARKGRAY,u.DARKKHAKI=a(u.fromCssColorString("#BDB76B")),u.DARKMAGENTA=a(u.fromCssColorString("#8B008B")),u.DARKOLIVEGREEN=a(u.fromCssColorString("#556B2F")),u.DARKORANGE=a(u.fromCssColorString("#FF8C00")),u.DARKORCHID=a(u.fromCssColorString("#9932CC")),u.DARKRED=a(u.fromCssColorString("#8B0000")),u.DARKSALMON=a(u.fromCssColorString("#E9967A")),u.DARKSEAGREEN=a(u.fromCssColorString("#8FBC8F")),u.DARKSLATEBLUE=a(u.fromCssColorString("#483D8B")),u.DARKSLATEGRAY=a(u.fromCssColorString("#2F4F4F")),u.DARKSLATEGREY=u.DARKSLATEGRAY,u.DARKTURQUOISE=a(u.fromCssColorString("#00CED1")),u.DARKVIOLET=a(u.fromCssColorString("#9400D3")),u.DEEPPINK=a(u.fromCssColorString("#FF1493")),u.DEEPSKYBLUE=a(u.fromCssColorString("#00BFFF")),u.DIMGRAY=a(u.fromCssColorString("#696969")),u.DIMGREY=u.DIMGRAY,u.DODGERBLUE=a(u.fromCssColorString("#1E90FF")),u.FIREBRICK=a(u.fromCssColorString("#B22222")),u.FLORALWHITE=a(u.fromCssColorString("#FFFAF0")),u.FORESTGREEN=a(u.fromCssColorString("#228B22")),u.FUCHSIA=a(u.fromCssColorString("#FF00FF")),u.GAINSBORO=a(u.fromCssColorString("#DCDCDC")),u.GHOSTWHITE=a(u.fromCssColorString("#F8F8FF")),u.GOLD=a(u.fromCssColorString("#FFD700")),u.GOLDENROD=a(u.fromCssColorString("#DAA520")),u.GRAY=a(u.fromCssColorString("#808080")),u.GREEN=a(u.fromCssColorString("#008000")),u.GREENYELLOW=a(u.fromCssColorString("#ADFF2F")),u.GREY=u.GRAY,u.HONEYDEW=a(u.fromCssColorString("#F0FFF0")),u.HOTPINK=a(u.fromCssColorString("#FF69B4")),u.INDIANRED=a(u.fromCssColorString("#CD5C5C")),u.INDIGO=a(u.fromCssColorString("#4B0082")),u.IVORY=a(u.fromCssColorString("#FFFFF0")),u.KHAKI=a(u.fromCssColorString("#F0E68C")),u.LAVENDER=a(u.fromCssColorString("#E6E6FA")),u.LAVENDAR_BLUSH=a(u.fromCssColorString("#FFF0F5")),u.LAWNGREEN=a(u.fromCssColorString("#7CFC00")),u.LEMONCHIFFON=a(u.fromCssColorString("#FFFACD")),u.LIGHTBLUE=a(u.fromCssColorString("#ADD8E6")),u.LIGHTCORAL=a(u.fromCssColorString("#F08080")),u.LIGHTCYAN=a(u.fromCssColorString("#E0FFFF")),u.LIGHTGOLDENRODYELLOW=a(u.fromCssColorString("#FAFAD2")),u.LIGHTGRAY=a(u.fromCssColorString("#D3D3D3")),u.LIGHTGREEN=a(u.fromCssColorString("#90EE90")),u.LIGHTGREY=u.LIGHTGRAY,u.LIGHTPINK=a(u.fromCssColorString("#FFB6C1")),u.LIGHTSEAGREEN=a(u.fromCssColorString("#20B2AA")),u.LIGHTSKYBLUE=a(u.fromCssColorString("#87CEFA")),u.LIGHTSLATEGRAY=a(u.fromCssColorString("#778899")),u.LIGHTSLATEGREY=u.LIGHTSLATEGRAY,u.LIGHTSTEELBLUE=a(u.fromCssColorString("#B0C4DE")),u.LIGHTYELLOW=a(u.fromCssColorString("#FFFFE0")),u.LIME=a(u.fromCssColorString("#00FF00")),u.LIMEGREEN=a(u.fromCssColorString("#32CD32")),u.LINEN=a(u.fromCssColorString("#FAF0E6")),u.MAGENTA=a(u.fromCssColorString("#FF00FF")),u.MAROON=a(u.fromCssColorString("#800000")),u.MEDIUMAQUAMARINE=a(u.fromCssColorString("#66CDAA")),u.MEDIUMBLUE=a(u.fromCssColorString("#0000CD")),u.MEDIUMORCHID=a(u.fromCssColorString("#BA55D3")),u.MEDIUMPURPLE=a(u.fromCssColorString("#9370DB")),u.MEDIUMSEAGREEN=a(u.fromCssColorString("#3CB371")),u.MEDIUMSLATEBLUE=a(u.fromCssColorString("#7B68EE")),u.MEDIUMSPRINGGREEN=a(u.fromCssColorString("#00FA9A")),u.MEDIUMTURQUOISE=a(u.fromCssColorString("#48D1CC")),u.MEDIUMVIOLETRED=a(u.fromCssColorString("#C71585")),u.MIDNIGHTBLUE=a(u.fromCssColorString("#191970")),u.MINTCREAM=a(u.fromCssColorString("#F5FFFA")),u.MISTYROSE=a(u.fromCssColorString("#FFE4E1")),u.MOCCASIN=a(u.fromCssColorString("#FFE4B5")),u.NAVAJOWHITE=a(u.fromCssColorString("#FFDEAD")),u.NAVY=a(u.fromCssColorString("#000080")),u.OLDLACE=a(u.fromCssColorString("#FDF5E6")),u.OLIVE=a(u.fromCssColorString("#808000")),u.OLIVEDRAB=a(u.fromCssColorString("#6B8E23")),u.ORANGE=a(u.fromCssColorString("#FFA500")),u.ORANGERED=a(u.fromCssColorString("#FF4500")),u.ORCHID=a(u.fromCssColorString("#DA70D6")),u.PALEGOLDENROD=a(u.fromCssColorString("#EEE8AA")),u.PALEGREEN=a(u.fromCssColorString("#98FB98")),u.PALETURQUOISE=a(u.fromCssColorString("#AFEEEE")),u.PALEVIOLETRED=a(u.fromCssColorString("#DB7093")),u.PAPAYAWHIP=a(u.fromCssColorString("#FFEFD5")),u.PEACHPUFF=a(u.fromCssColorString("#FFDAB9")),u.PERU=a(u.fromCssColorString("#CD853F")),u.PINK=a(u.fromCssColorString("#FFC0CB")),u.PLUM=a(u.fromCssColorString("#DDA0DD")),u.POWDERBLUE=a(u.fromCssColorString("#B0E0E6")),u.PURPLE=a(u.fromCssColorString("#800080")),u.RED=a(u.fromCssColorString("#FF0000")),u.ROSYBROWN=a(u.fromCssColorString("#BC8F8F")),u.ROYALBLUE=a(u.fromCssColorString("#4169E1")),u.SADDLEBROWN=a(u.fromCssColorString("#8B4513")),u.SALMON=a(u.fromCssColorString("#FA8072")),u.SANDYBROWN=a(u.fromCssColorString("#F4A460")),u.SEAGREEN=a(u.fromCssColorString("#2E8B57")),u.SEASHELL=a(u.fromCssColorString("#FFF5EE")),u.SIENNA=a(u.fromCssColorString("#A0522D")),u.SILVER=a(u.fromCssColorString("#C0C0C0")),u.SKYBLUE=a(u.fromCssColorString("#87CEEB")),u.SLATEBLUE=a(u.fromCssColorString("#6A5ACD")),u.SLATEGRAY=a(u.fromCssColorString("#708090")),u.SLATEGREY=u.SLATEGRAY,u.SNOW=a(u.fromCssColorString("#FFFAFA")),u.SPRINGGREEN=a(u.fromCssColorString("#00FF7F")),u.STEELBLUE=a(u.fromCssColorString("#4682B4")),u.TAN=a(u.fromCssColorString("#D2B48C")),u.TEAL=a(u.fromCssColorString("#008080")),u.THISTLE=a(u.fromCssColorString("#D8BFD8")),u.TOMATO=a(u.fromCssColorString("#FF6347")),u.TURQUOISE=a(u.fromCssColorString("#40E0D0")),u.VIOLET=a(u.fromCssColorString("#EE82EE")),u.WHEAT=a(u.fromCssColorString("#F5DEB3")),u.WHITE=a(u.fromCssColorString("#FFFFFF")),u.WHITESMOKE=a(u.fromCssColorString("#F5F5F5")),u.YELLOW=a(u.fromCssColorString("#FFFF00")),u.YELLOWGREEN=a(u.fromCssColorString("#9ACD32")),u.TRANSPARENT=a(new u(0,0,0,0)),u}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,r,n,a,o){"use strict";if(!n.supportsTypedArrays())return{};var i={BYTE:o.BYTE,UNSIGNED_BYTE:o.UNSIGNED_BYTE,SHORT:o.SHORT,UNSIGNED_SHORT:o.UNSIGNED_SHORT,INT:o.INT,UNSIGNED_INT:o.UNSIGNED_INT,FLOAT:o.FLOAT,DOUBLE:o.DOUBLE};return i.getSizeInBytes=function(t){switch(t){case i.BYTE:return Int8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.SHORT:return Int16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.INT:return Int32Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case i.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case i.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},i.fromTypedArray=function(t){return t instanceof Int8Array?i.BYTE:t instanceof Uint8Array?i.UNSIGNED_BYTE:t instanceof Int16Array?i.SHORT:t instanceof Uint16Array?i.UNSIGNED_SHORT:t instanceof Int32Array?i.INT:t instanceof Uint32Array?i.UNSIGNED_INT:t instanceof Float32Array?i.FLOAT:t instanceof Float64Array?i.DOUBLE:void 0},i.validate=function(t){return e(t)&&(t===i.BYTE||t===i.UNSIGNED_BYTE||t===i.SHORT||t===i.UNSIGNED_SHORT||t===i.INT||t===i.UNSIGNED_INT||t===i.FLOAT||t===i.DOUBLE)},i.createTypedArray=function(t,e){switch(t){case i.BYTE:return new Int8Array(e);case i.UNSIGNED_BYTE:return new Uint8Array(e);case i.SHORT:return new Int16Array(e);case i.UNSIGNED_SHORT:return new Uint16Array(e);case i.INT:return new Int32Array(e);case i.UNSIGNED_INT:return new Uint32Array(e);case i.FLOAT:return new Float32Array(e);case i.DOUBLE:return new Float64Array(e)}},i.createArrayBufferView=function(e,r,n,a){switch(n=t(n,0),a=t(a,(r.byteLength-n)/i.getSizeInBytes(e)),e){case i.BYTE:return new Int8Array(r,n,a);case i.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case i.SHORT:return new Int16Array(r,n,a);case i.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case i.INT:return new Int32Array(r,n,a);case i.UNSIGNED_INT:return new Uint32Array(r,n,a);case i.FLOAT:return new Float32Array(r,n,a);case i.DOUBLE:return new Float64Array(r,n,a)}},i.fromName=function(t){switch(t){case"BYTE":return i.BYTE;case"UNSIGNED_BYTE":return i.UNSIGNED_BYTE;case"SHORT":return i.SHORT;case"UNSIGNED_SHORT":return i.UNSIGNED_SHORT;case"INT":return i.INT;case"UNSIGNED_INT":return i.UNSIGNED_INT;case"FLOAT":return i.FLOAT;case"DOUBLE":return i.DOUBLE}},a(i)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var r={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===r.POINTS||t===r.LINES||t===r.LINE_LOOP||t===r.LINE_STRIP||t===r.TRIANGLES||t===r.TRIANGLE_STRIP||t===r.TRIANGLE_FAN}};return t(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,r,n,a,o){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,o.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return i.computeNumberOfVertices=function(t){var e=-1;for(var n in t.attributes)if(t.attributes.hasOwnProperty(n)&&r(t.attributes[n])&&r(t.attributes[n].values)){var a=t.attributes[n],o=a.values.length/a.componentsPerAttribute;e=o}return e},i}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,r){"use strict";function n(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,r,n,a){"use strict";var o={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT} -;return o.getSizeInBytes=function(t){switch(t){case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},o.validate=function(e){return t(e)&&(e===o.UNSIGNED_BYTE||e===o.UNSIGNED_SHORT||e===o.UNSIGNED_INT)},o.createTypedArray=function(t,e){return t>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},o.createTypedArrayFromArrayBuffer=function(t,e,r,a){return t>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,r,a):new Uint16Array(e,r,a)},r(o)}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t){var e=t._uSquared,r=t._ellipsoid.maximumRadius,n=t._ellipsoid.minimumRadius,a=(r-n)/r,o=Math.cos(t._startHeading),i=Math.sin(t._startHeading),u=(1-a)*Math.tan(t._start.latitude),s=1/Math.sqrt(1+u*u),E=s*u,c=Math.atan2(u,o),l=s*i,f=l*l,_=1-f,R=Math.sqrt(_),h=e/4,T=h*h,A=T*h,d=T*T,S=1+h-3*T/4+5*A/4-175*d/64,m=1-h+15*T/8-35*A/8,N=1-3*h+35*T/4,C=1-5*h,I=S*c-m*Math.sin(2*c)*h/2-N*Math.sin(4*c)*T/16-C*Math.sin(6*c)*A/48-5*Math.sin(8*c)*d/512,p=t._constants;p.a=r,p.b=n,p.f=a,p.cosineHeading=o,p.sineHeading=i,p.tanU=u,p.cosineU=s,p.sineU=E,p.sigma=c,p.sineAlpha=l,p.sineSquaredAlpha=f,p.cosineSquaredAlpha=_,p.cosineAlpha=R,p.u2Over4=h,p.u4Over16=T,p.u6Over64=A,p.u8Over256=d,p.a0=S,p.a1=m,p.a2=N,p.a3=C,p.distanceRatio=I}function E(t,e){return t*e*(4+t*(4-3*e))/16}function c(t,e,r,n,a,o,i){var u=E(t,r);return(1-u)*t*e*(n+u*a*(i+u*o*(2*i*i-1)))}function l(t,e,r,n,a,o,i){var s,E,l,f,_,R=(e-r)/e,h=o-n,T=Math.atan((1-R)*Math.tan(a)),A=Math.atan((1-R)*Math.tan(i)),d=Math.cos(T),S=Math.sin(T),m=Math.cos(A),N=Math.sin(A),C=d*m,I=d*N,p=S*N,M=S*m,O=h,g=u.TWO_PI,y=Math.cos(O),F=Math.sin(O);do{y=Math.cos(O),F=Math.sin(O);var L=I-M*y;l=Math.sqrt(m*m*F*F+L*L),E=p+C*y,s=Math.atan2(l,E);var v;0===l?(v=0,f=1):(v=C*F/l,f=1-v*v),g=O,_=E-2*p/f,isNaN(_)&&(_=0),O=h+c(R,v,f,s,l,E,_)}while(Math.abs(O-g)>u.EPSILON12);var U=f*(e*e-r*r)/(r*r),P=1+U*(4096+U*(U*(320-175*U)-768))/16384,D=U*(256+U*(U*(74-47*U)-128))/1024,w=_*_,B=D*l*(_+D*(E*(2*w-1)-D*_*(4*l*l-3)*(4*w-3)/6)/4),x=r*P*(s-B),G=Math.atan2(m*F,I-M*y),b=Math.atan2(d*F,I*y-M);t._distance=x,t._startHeading=G,t._endHeading=b,t._uSquared=U}function f(r,n,a,o){t.normalize(o.cartographicToCartesian(n,h),R),t.normalize(o.cartographicToCartesian(a,h),h);l(r,o.maximumRadius,o.minimumRadius,n.longitude,n.latitude,a.longitude,a.latitude),r._start=e.clone(n,r._start),r._end=e.clone(a,r._end),r._start.height=0,r._end.height=0,s(r)}function _(t,r,o){var u=n(o,i.WGS84);this._ellipsoid=u,this._start=new e,this._end=new e,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(t)&&a(r)&&f(this,t,r,u)}var R=new t,h=new t;return o(_.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),_.prototype.setEndPoints=function(t,e){f(this,t,e,this._ellipsoid)},_.prototype.interpolateUsingFraction=function(t,e){return this.interpolateUsingSurfaceDistance(this._distance*t,e)},_.prototype.interpolateUsingSurfaceDistance=function(t,r){var n=this._constants,o=n.distanceRatio+t/n.b,i=Math.cos(2*o),u=Math.cos(4*o),s=Math.cos(6*o),E=Math.sin(2*o),l=Math.sin(4*o),f=Math.sin(6*o),_=Math.sin(8*o),R=o*o,h=o*R,T=n.u8Over256,A=n.u2Over4,d=n.u6Over64,S=n.u4Over16,m=2*h*T*i/3+o*(1-A+7*S/4-15*d/4+579*T/64-(S-15*d/4+187*T/16)*i-(5*d/4-115*T/16)*u-29*T*s/16)+(A/2-S+71*d/32-85*T/16)*E+(5*S/16-5*d/4+383*T/96)*l-R*((d-11*T/2)*E+5*T*l/2)+(29*d/96-29*T/16)*f+539*T*_/1536,N=Math.asin(Math.sin(m)*n.cosineAlpha),C=Math.atan(n.a/n.b*Math.tan(N));m-=n.sigma;var I=Math.cos(2*n.sigma+m),p=Math.sin(m),M=Math.cos(m),O=n.cosineU*M,g=n.sineU*p,y=Math.atan2(p*n.sineHeading,O-g*n.cosineHeading),F=y-c(n.f,n.sineAlpha,n.cosineSquaredAlpha,m,p,M,I);return a(r)?(r.longitude=this._start.longitude+F,r.latitude=C,r.height=0,r):new e(this._start.longitude+F,C,0)},_}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(t,e){"use strict";function r(t,r,n){var a=t+r;return e.sign(t)!==e.sign(r)&&Math.abs(a/Math.max(Math.abs(t),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(t,e,r){return e*e-4*t*r},n.computeRealRoots=function(t,n,a){var o;if(0===t)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var i=Math.abs(a),u=Math.abs(t);if(i<u&&i/u<e.EPSILON14)return[0,0];if(i>u&&u/i<e.EPSILON14)return[];if((o=-a/t)<0)return[];var s=Math.sqrt(o);return[-s,s]}if(0===a)return o=-n/t,o<0?[o,0]:[0,o];var E=n*n,c=4*t*a,l=r(E,-c,e.EPSILON14);if(l<0)return[];var f=-.5*r(n,e.sign(n)*Math.sqrt(l),e.EPSILON14);return n>0?[f/t,a/f]:[a/f,f/t]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(t,e){"use strict";function r(t,e,r,n){var a,o,i=t,u=e/3,s=r/3,E=n,c=i*s,l=u*E,f=u*u,_=s*s,R=i*s-f,h=i*E-u*s,T=u*E-_,A=4*R*T-h*h;if(A<0){var d,S,m;f*l>=c*_?(d=i,S=R,m=-2*u*R+i*h):(d=E,S=T,m=-E*h+2*s*T);var N=m<0?-1:1,C=-N*Math.abs(d)*Math.sqrt(-A);o=-m+C;var I=o/2,p=I<0?-Math.pow(-I,1/3):Math.pow(I,1/3),M=o===C?-p:-S/p;return a=S<=0?p+M:-m/(p*p+M*M+S),f*l>=c*_?[(a-u)/i]:[-E/(a+s)]}var O=R,g=-2*u*R+i*h,y=T,F=-E*h+2*s*T,L=Math.sqrt(A),v=Math.sqrt(3)/2,U=Math.abs(Math.atan2(i*L,-g)/3);a=2*Math.sqrt(-O);var P=Math.cos(U);o=a*P;var D=a*(-P/2-v*Math.sin(U)),w=o+D>2*u?o-u:D-u,B=i,x=w/B;U=Math.abs(Math.atan2(E*L,-F)/3),a=2*Math.sqrt(-y),P=Math.cos(U),o=a*P,D=a*(-P/2-v*Math.sin(U));var G=-E,b=o+D<2*s?o+s:D+s,z=G/b,H=B*b,V=-w*b-B*G,X=w*G,q=(s*V-u*X)/(-u*V+s*H);return x<=q?x<=z?q<=z?[x,q,z]:[x,z,q]:[z,x,q]:x<=z?[q,x,z]:q<=z?[q,z,x]:[z,q,x]}var n={};return n.computeDiscriminant=function(t,e,r,n){var a=t*t,o=e*e,i=r*r;return 18*t*e*r*n+o*i-27*a*(n*n)-4*(t*i*r+o*e*n)},n.computeRealRoots=function(t,n,a,o){var i,u;if(0===t)return e.computeRealRoots(n,a,o);if(0===n){if(0===a){if(0===o)return[0,0,0];u=-o/t;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===o?(i=e.computeRealRoots(t,0,a),0===i.Length?[0]:[i[0],0,i[1]]):r(t,0,a,o)}return 0===a?0===o?(u=-n/t,u<0?[u,0,0]:[0,0,u]):r(t,n,0,o):0===o?(i=e.computeRealRoots(t,n,a),0===i.length?[0]:i[1]<=0?[i[0],i[1],0]:i[0]>=0?[0,i[0],i[1]]:[i[0],0,i[1]]):r(t,n,a,o)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(t,e,r,n){"use strict";function a(e,a,o,i){var u=e*e,s=a-3*u/8,E=o-a*e/2+u*e/8,c=i-o*e/4+a*u/16-3*u*u/256,l=t.computeRealRoots(1,2*s,s*s-4*c,-E*E);if(l.length>0){var f=-e/4,_=l[l.length-1];if(Math.abs(_)<r.EPSILON14){var R=n.computeRealRoots(1,s,c);if(2===R.length){var h,T=R[0],A=R[1];if(T>=0&&A>=0){var d=Math.sqrt(T),S=Math.sqrt(A);return[f-S,f-d,f+d,f+S]}if(T>=0&&A<0)return h=Math.sqrt(T),[f-h,f+h];if(T<0&&A>=0)return h=Math.sqrt(A),[f-h,f+h]}return[]}if(_>0){var m=Math.sqrt(_),N=(s+_-E/m)/2,C=(s+_+E/m)/2,I=n.computeRealRoots(1,m,N),p=n.computeRealRoots(1,-m,C);return 0!==I.length?(I[0]+=f,I[1]+=f,0!==p.length?(p[0]+=f,p[1]+=f,I[1]<=p[0]?[I[0],I[1],p[0],p[1]]:p[1]<=I[0]?[p[0],p[1],I[0],I[1]]:I[0]>=p[0]&&I[1]<=p[1]?[p[0],I[0],I[1],p[1]]:p[0]>=I[0]&&p[1]<=I[1]?[I[0],p[0],p[1],I[1]]:I[0]>p[0]&&I[0]<p[1]?[p[0],I[0],p[1],I[1]]:[I[0],p[0],I[1],p[1]]):I):0!==p.length?(p[0]+=f,p[1]+=f,p):[]}}return[]}function o(e,a,o,i){var u=o*o,s=a*a,E=e*e,c=-2*a,l=o*e+s-4*i,f=E*i-o*a*e+u,_=t.computeRealRoots(1,c,l,f);if(_.length>0){var R,h,T=_[0],A=a-T,d=A*A,S=e/2,m=A/2,N=d-4*i,C=d+4*Math.abs(i),I=E-4*T,p=E+4*Math.abs(T);if(T<0||N*p<I*C){var M=Math.sqrt(I);R=M/2,h=0===M?0:(e*m-o)/M}else{var O=Math.sqrt(N);R=0===O?0:(e*m-o)/O,h=O/2}var g,y;0===S&&0===R?(g=0,y=0):r.sign(S)===r.sign(R)?(g=S+R,y=T/g):(y=S-R,g=T/y);var F,L;0===m&&0===h?(F=0,L=0):r.sign(m)===r.sign(h)?(F=m+h,L=i/F):(L=m-h,F=i/L);var v=n.computeRealRoots(1,g,F),U=n.computeRealRoots(1,y,L);if(0!==v.length)return 0!==U.length?v[1]<=U[0]?[v[0],v[1],U[0],U[1]]:U[1]<=v[0]?[U[0],U[1],v[0],v[1]]:v[0]>=U[0]&&v[1]<=U[1]?[U[0],v[0],v[1],U[1]]:U[0]>=v[0]&&U[1]<=v[1]?[v[0],U[0],U[1],v[1]]:v[0]>U[0]&&v[0]<U[1]?[U[0],v[0],U[1],v[1]]:[v[0],U[0],v[1],U[1]]:v;if(0!==U.length)return U}return[]}var i={};return i.computeDiscriminant=function(t,e,r,n,a){var o=t*t,i=o*t,u=e*e,s=u*e,E=r*r,c=E*r,l=n*n,f=l*n,_=a*a;return u*E*l-4*s*f-4*t*c*l+18*t*e*r*f-27*o*l*l+256*i*(_*a)+a*(18*s*r*n-4*u*c+16*t*E*E-80*t*e*E*n-6*t*u*l+144*o*r*l)+_*(144*t*u*r-27*u*u-128*o*E-192*o*e*n)},i.computeRealRoots=function(e,n,i,u,s){if(Math.abs(e)<r.EPSILON15)return t.computeRealRoots(n,i,u,s);var E=n/e,c=i/e,l=u/e,f=s/e,_=E<0?1:0;switch(_+=c<0?_+1:_,_+=l<0?_+1:_,_+=f<0?_+1:_){case 0:return a(E,c,l,f);case 1:case 2:return o(E,c,l,f);case 3:case 4:return a(E,c,l,f);case 5:return o(E,c,l,f);case 6:case 7:return a(E,c,l,f);case 8:return o(E,c,l,f);case 9:case 10:return a(E,c,l,f);case 11:return o(E,c,l,f);case 12:case 13:case 14:case 15:return a(E,c,l,f);default:return}},i}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(t,e,r,n){"use strict";function a(r,n){n=t.clone(e(n,t.ZERO)),t.equals(n,t.ZERO)||t.normalize(n,n),this.origin=t.clone(e(r,t.ZERO)),this.direction=n}return a.getPoint=function(e,n,a){return r(a)||(a=new t),a=t.multiplyByScalar(e.direction,n,a),t.add(e.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(t,e,r,n,a,o,i,u,s,E,c){"use strict";function l(t,e,r,n){var a=e*e-4*t*r;if(!(a<0)){if(a>0){var o=1/(2*t),i=Math.sqrt(a),u=(-e+i)*o,s=(-e-i)*o;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var E=-e/(2*t);if(0!==E)return n.root0=n.root1=E,n}}function f(e,r,a){n(a)||(a=new o);var i=e.origin,u=e.direction,s=r.center,E=r.radius*r.radius,c=t.subtract(i,s,d),f=t.dot(u,u),_=2*t.dot(u,c),R=t.magnitudeSquared(c)-E,h=l(f,_,R,C);if(n(h))return a.start=h.root0,a.stop=h.root1,a}function _(t,e,r){var n=t+e;return i.sign(t)!==i.sign(e)&&Math.abs(n/Math.max(Math.abs(t),Math.abs(e)))<r?0:n}function R(e,r,n,a,o){var c,l=a*a,f=o*o,R=(e[u.COLUMN1ROW1]-e[u.COLUMN2ROW2])*f,h=o*(a*_(e[u.COLUMN1ROW0],e[u.COLUMN0ROW1],i.EPSILON15)+r.y),T=e[u.COLUMN0ROW0]*l+e[u.COLUMN2ROW2]*f+a*r.x+n,A=f*_(e[u.COLUMN2ROW1],e[u.COLUMN1ROW2],i.EPSILON15),d=o*(a*_(e[u.COLUMN2ROW0],e[u.COLUMN0ROW2])+r.z),S=[];if(0===d&&0===A){if(c=s.computeRealRoots(R,h,T),0===c.length)return S;var m=c[0],N=Math.sqrt(Math.max(1-m*m,0));if(S.push(new t(a,o*m,o*-N)),S.push(new t(a,o*m,o*N)),2===c.length){var C=c[1],I=Math.sqrt(Math.max(1-C*C,0));S.push(new t(a,o*C,o*-I)),S.push(new t(a,o*C,o*I))}return S}var p=d*d,M=A*A,O=R*R,g=d*A,y=O+M,F=2*(h*R+g),L=2*T*R+h*h-M+p,v=2*(T*h-g),U=T*T-p;if(0===y&&0===F&&0===L&&0===v)return S;c=E.computeRealRoots(y,F,L,v,U);var P=c.length;if(0===P)return S;for(var D=0;D<P;++D){var w,B=c[D],x=B*B,G=Math.max(1-x,0),b=Math.sqrt(G);w=i.sign(R)===i.sign(T)?_(R*x+T,h*B,i.EPSILON12):i.sign(T)===i.sign(h*B)?_(R*x,h*B+T,i.EPSILON12):_(R*x+h*B,T,i.EPSILON12);var z=_(A*B,d,i.EPSILON15),H=w*z;H<0?S.push(new t(a,o*B,o*b)):H>0?S.push(new t(a,o*B,o*-b)):0!==b?(S.push(new t(a,o*B,o*-b)),S.push(new t(a,o*B,o*b)),++D):S.push(new t(a,o*B,o*b))}return S}var h={};h.rayPlane=function(e,r,a){n(a)||(a=new t);var o=e.origin,u=e.direction,s=r.normal,E=t.dot(s,u);if(!(Math.abs(E)<i.EPSILON15)){var c=(-r.distance-t.dot(s,o))/E;if(!(c<0))return a=t.multiplyByScalar(u,c,a),t.add(o,a,a)}};var T=new t,A=new t,d=new t,S=new t,m=new t;h.rayTriangleParametric=function(e,n,a,o,u){u=r(u,!1);var s,E,c,l,f,_=e.origin,R=e.direction,h=t.subtract(a,n,T),N=t.subtract(o,n,A),C=t.cross(R,N,d),I=t.dot(h,C);if(u){if(I<i.EPSILON6)return;if(s=t.subtract(_,n,S),(c=t.dot(s,C))<0||c>I)return;if(E=t.cross(s,h,m),(l=t.dot(R,E))<0||c+l>I)return;f=t.dot(N,E)/I}else{if(Math.abs(I)<i.EPSILON6)return;var p=1/I;if(s=t.subtract(_,n,S),(c=t.dot(s,C)*p)<0||c>1)return;if(E=t.cross(s,h,m),(l=t.dot(R,E)*p)<0||c+l>1)return;f=t.dot(N,E)*p}return f},h.rayTriangle=function(e,r,a,o,i,u){var s=h.rayTriangleParametric(e,r,a,o,i);if(n(s)&&!(s<0))return n(u)||(u=new t),t.multiplyByScalar(e.direction,s,u),t.add(e.origin,u,u)};var N=new c;h.lineSegmentTriangle=function(e,r,a,o,i,u,s){var E=N;t.clone(e,E.origin),t.subtract(r,e,E.direction),t.normalize(E.direction,E.direction);var c=h.rayTriangleParametric(E,a,o,i,u);if(!(!n(c)||c<0||c>t.distance(e,r)))return n(s)||(s=new t),t.multiplyByScalar(E.direction,c,s),t.add(E.origin,s,s)};var C={root0:0,root1:0};h.raySphere=function(t,e,r){if(r=f(t,e,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var I=new c;h.lineSegmentSphere=function(e,r,a,o){var i=I;t.clone(e,i.origin);var u=t.subtract(r,e,i.direction),s=t.magnitude(u);if(t.normalize(u,u),o=f(i,a,o),!(!n(o)||o.stop<0||o.start>s))return o.start=Math.max(o.start,0),o.stop=Math.min(o.stop,s),o};var p=new t,M=new t;h.rayEllipsoid=function(e,r){var n,a,i,u,s,E=r.oneOverRadii,c=t.multiplyComponents(E,e.origin,p),l=t.multiplyComponents(E,e.direction,M),f=t.magnitudeSquared(c),_=t.dot(c,l);if(f>1){if(_>=0)return;var R=_*_;if(n=f-1,a=t.magnitudeSquared(l),i=a*n,R<i)return;if(R>i){u=_*_-i,s=-_+Math.sqrt(u);var h=s/a,T=n/s;return h<T?new o(h,T):{start:T,stop:h}}var A=Math.sqrt(n/a);return new o(A,A)}return f<1?(n=f-1,a=t.magnitudeSquared(l),i=a*n,u=_*_-i,s=-_+Math.sqrt(u),new o(0,s/a)):_<0?(a=t.magnitudeSquared(l),new o(0,-_/a)):void 0};var O=new t,g=new t,y=new t,F=new t,L=new t,v=new u,U=new u,P=new u,D=new u,w=new u,B=new u,x=new u,G=new t,b=new t,z=new e;h.grazingAltitudeLocation=function(e,r){var a=e.origin,o=e.direction;if(!t.equals(a,t.ZERO)){var s=r.geodeticSurfaceNormal(a,O);if(t.dot(o,s)>=0)return a}var E=n(this.rayEllipsoid(e,r)),c=r.transformPositionToScaledSpace(o,O),l=t.normalize(c,c),f=t.mostOrthogonalAxis(c,F),_=t.normalize(t.cross(f,l,g),g),h=t.normalize(t.cross(l,_,y),y),T=v;T[0]=l.x,T[1]=l.y,T[2]=l.z,T[3]=_.x,T[4]=_.y,T[5]=_.z,T[6]=h.x,T[7]=h.y,T[8]=h.z;var A=u.transpose(T,U),d=u.fromScale(r.radii,P),S=u.fromScale(r.oneOverRadii,D),m=w;m[0]=0,m[1]=-o.z,m[2]=o.y,m[3]=o.z,m[4]=0,m[5]=-o.x,m[6]=-o.y,m[7]=o.x,m[8]=0;var N,C,I=u.multiply(u.multiply(A,S,B),m,B),p=u.multiply(u.multiply(I,d,x),T,x),M=u.multiplyByVector(I,a,L),H=R(p,t.negate(M,O),0,0,1),V=H.length;if(V>0){for(var X=t.clone(t.ZERO,b),q=Number.NEGATIVE_INFINITY,W=0;W<V;++W){N=u.multiplyByVector(d,u.multiplyByVector(T,H[W],G),G);var Y=t.normalize(t.subtract(N,a,F),F),K=t.dot(Y,o);K>q&&(q=K,X=t.clone(N,X))}var k=r.cartesianToCartographic(X,z);return q=i.clamp(q,0,1),C=t.magnitude(t.subtract(X,a,F))*Math.sqrt(1-q*q),C=E?-C:C,k.height=C,r.cartographicToCartesian(k,new t)}};var H=new t;return h.lineSegmentPlane=function(e,r,a,o){n(o)||(o=new t);var u=t.subtract(r,e,H),s=a.normal,E=t.dot(s,u);if(!(Math.abs(E)<i.EPSILON6)){var c=t.dot(s,e),l=-(a.distance+c)/E;if(!(l<0||l>1))return t.multiplyByScalar(u,l,o),t.add(e,o,o),o}},h.trianglePlaneIntersection=function(e,r,n,a){var o=a.normal,i=a.distance,u=t.dot(o,e)+i<0,s=t.dot(o,r)+i<0,E=t.dot(o,n)+i<0,c=0;c+=u?1:0,c+=s?1:0,c+=E?1:0;var l,f;if(1!==c&&2!==c||(l=new t,f=new t),1===c){if(u)return h.lineSegmentPlane(e,r,a,l),h.lineSegmentPlane(e,n,a,f),{positions:[e,r,n,l,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return h.lineSegmentPlane(r,n,a,l),h.lineSegmentPlane(r,e,a,f),{positions:[e,r,n,l,f],indices:[1,3,4,2,0,4,2,4,3]};if(E)return h.lineSegmentPlane(n,e,a,l),h.lineSegmentPlane(n,r,a,f),{positions:[e,r,n,l,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===c){if(!u)return h.lineSegmentPlane(r,e,a,l),h.lineSegmentPlane(n,e,a,f),{positions:[e,r,n,l,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return h.lineSegmentPlane(n,r,a,l),h.lineSegmentPlane(e,r,a,f),{positions:[e,r,n,l,f],indices:[2,0,4,2,4,3,1,3,4]};if(!E)return h.lineSegmentPlane(e,n,a,l),h.lineSegmentPlane(r,n,a,f),{positions:[e,r,n,l,f],indices:[0,1,4,0,4,3,2,3,4]}}},h}),define("Core/isArray",["./defined"],function(t){"use strict";var e=Array.isArray;return t(e)||(e=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,r,n,a,o,i){"use strict";function u(e,r){this.normal=t.clone(e),this.distance=r}u.fromPointNormal=function(e,n,a){var o=-t.dot(n,e);return r(a)?(t.clone(n,a.normal),a.distance=o,a):new u(n,o)};var s=new t;u.fromCartesian4=function(e,n){var a=t.fromCartesian4(e,s),o=e.w;return r(n)?(t.clone(a,n.normal),n.distance=o,n):new u(a,o)},u.getPointDistance=function(e,r){return t.dot(e.normal,r)+e.distance};var E=new t;return u.transform=function(e,r,n){return i.multiplyByPointAsVector(r,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,E),i.multiplyByPoint(r,E,E),u.fromPointNormal(E,s,n)},u.clone=function(e,n){return r(n)?(t.clone(e.normal,n.normal),n.distance=e.distance,n):new u(e.normal,e.distance)},u.equals=function(e,r){return e.distance===r.distance&&t.equals(e.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(t.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(t,e,r,n,a,o,i,u,s,E,c,l){"use strict";function f(t,e,r){var n=p;n.length=t;var a;if(e===r){for(a=0;a<t;a++)n[a]=e;return n}var o=r-e,i=o/t;for(a=0;a<t;a++){var u=e+a*i;n[a]=u}return n}function _(e,r,n,a,o,i,u,s){var E=a.scaleToGeodeticSurface(e,y),c=a.scaleToGeodeticSurface(r,F),l=R.numberOfPoints(e,r,n),_=a.cartesianToCartographic(E,M),h=a.cartesianToCartographic(c,O),T=f(l,o,i);L.setEndPoints(_,h);var A=L.surfaceDistance/l,d=s;_.height=o;var S=a.cartographicToCartesian(_,g);t.pack(S,u,d),d+=3;for(var m=1;m<l;m++){var N=L.interpolateUsingSurfaceDistance(m*A,O);N.height=T[m],S=a.cartographicToCartesian(N,g),t.pack(S,u,d),d+=3}return d}var R={};R.numberOfPoints=function(e,r,n){var a=t.distance(e,r);return Math.ceil(a/n)};var h=new e;R.extractHeights=function(t,e){for(var r=t.length,n=new Array(r),a=0;a<r;a++){var o=t[a];n[a]=e.cartesianToCartographic(o,h).height}return n};var T=new c,A=new t,d=new t,S=new l(t.UNIT_X,0),m=new t,N=new l(t.UNIT_X,0),C=new t,I=new t,p=[],M=new e,O=new e,g=new t,y=new t,F=new t,L=new i;return R.wrapLongitude=function(e,a){var o=[],i=[];if(n(e)&&e.length>0){a=r(a,c.IDENTITY);var s=c.inverseTransformation(a,T),E=c.multiplyByPoint(s,t.ZERO,A),f=t.normalize(c.multiplyByPointAsVector(s,t.UNIT_Y,d),d),_=l.fromPointNormal(E,f,S),R=t.normalize(c.multiplyByPointAsVector(s,t.UNIT_X,m),m),h=l.fromPointNormal(E,R,N),p=1;o.push(t.clone(e[0]));for(var M=o[0],O=e.length,g=1;g<O;++g){var y=e[g];if(l.getPointDistance(h,M)<0||l.getPointDistance(h,y)<0){var F=u.lineSegmentPlane(M,y,_,C);if(n(F)){var L=t.multiplyByScalar(f,5e-9,I);l.getPointDistance(_,M)<0&&t.negate(L,L),o.push(t.add(F,L,new t)),i.push(p+1),t.negate(L,L),o.push(t.add(F,L,new t)),p=1}}o.push(t.clone(e[g])),p++,M=y}i.push(p)}return{positions:o,lengths:i}},R.generateArc=function(e){n(e)||(e={});var a=e.positions,i=a.length,u=r(e.ellipsoid,o.WGS84),c=r(e.height,0),l=s(c);if(i<1)return[];if(1===i){var f=u.scaleToGeodeticSurface(a[0],y);if(0!==(c=l?c[0]:c)){var h=u.geodeticSurfaceNormal(f,g);t.multiplyByScalar(h,c,h),t.add(f,h,f)}return[f.x,f.y,f.z]}var T=e.minDistance;if(!n(T)){var A=r(e.granularity,E.RADIANS_PER_DEGREE);T=E.chordLength(A,u.maximumRadius)}var d,S=0;for(d=0;d<i-1;d++)S+=R.numberOfPoints(a[d],a[d+1],T);var m=3*(S+1),N=new Array(m),C=0;for(d=0;d<i-1;d++){C=_(a[d],a[d+1],T,u,l?c[d]:c,l?c[d+1]:c,N,C)}p.length=0;var I=a[i-1],O=u.cartesianToCartographic(I,M);O.height=l?c[i-1]:c;var F=u.cartographicToCartesian(O,g);return t.pack(F,N,m-3),N},R.generateCartesianArc=function(e){for(var r=R.generateArc(e),n=r.length/3,a=new Array(n),o=0;o<n;o++)a[o]=t.unpack(r,3*o);return a},R}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,r,n){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=n(new a({position:!0})),a.POSITION_AND_NORMAL=n(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=n(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=n(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=n(new a({position:!0,color:!0})),a.ALL=n(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,r,n){return n=t(n,0),r[n++]=e.position?1:0,r[n++]=e.normal?1:0,r[n++]=e.st?1:0,r[n++]=e.tangent?1:0,r[n++]=e.bitangent?1:0,r[n]=e.color?1:0,r},a.unpack=function(r,n,o){return n=t(n,0),e(o)||(o=new a),o.position=1===r[n++],o.normal=1===r[n++],o.st=1===r[n++],o.tangent=1===r[n++],o.bitangent=1===r[n++],o.color=1===r[n],o},a.clone=function(t,r){if(e(t))return e(r)||(r=new a),r.position=t.position,r.normal=t.normal,r.st=t.st,r.tangent=t.tangent,r.bitangent=t.bitangent,r.color=t.color,r},a}),define("Core/PolylineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryType","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType","./VertexFormat"],function(t,e,r,n,a,o,i,u,s,E,c,l,f,_,R,h,T,A){"use strict";function d(t,e,r,a,o){var i=m;i.length=o;var u,s=r.red,E=r.green,c=r.blue,l=r.alpha,f=a.red,_=a.green,R=a.blue,h=a.alpha;if(n.equals(r,a)){for(u=0;u<o;u++)i[u]=n.clone(r);return i}var T=(f-s)/o,A=(_-E)/o,d=(R-c)/o,S=(h-l)/o;for(u=0;u<o;u++)i[u]=new n(s+u*T,E+u*A,c+u*d,l+u*S);return i}function S(t){t=o(t,o.EMPTY_OBJECT);var e=t.positions,a=t.colors,u=o(t.width,1),E=o(t.colorsPerVertex,!1);this._positions=e,this._colors=a,this._width=u,this._colorsPerVertex=E,this._vertexFormat=A.clone(o(t.vertexFormat,A.DEFAULT)),this._followSurface=o(t.followSurface,!0),this._granularity=o(t.granularity,R.RADIANS_PER_DEGREE),this._ellipsoid=s.clone(o(t.ellipsoid,s.WGS84)),this._workerName="createPolylineGeometry";var c=1+e.length*r.packedLength;c+=i(a)?1+a.length*n.packedLength:1,this.packedLength=c+s.packedLength+A.packedLength+4}var m=[];S.pack=function(t,e,a){a=o(a,0);var u,E=t._positions,c=E.length;for(e[a++]=c,u=0;u<c;++u,a+=r.packedLength)r.pack(E[u],e,a);var l=t._colors;for(c=i(l)?l.length:0,e[a++]=c,u=0;u<c;++u,a+=n.packedLength)n.pack(l[u],e,a);return s.pack(t._ellipsoid,e,a),a+=s.packedLength,A.pack(t._vertexFormat,e,a),a+=A.packedLength,e[a++]=t._width,e[a++]=t._colorsPerVertex?1:0,e[a++]=t._followSurface?1:0,e[a]=t._granularity,e};var N=s.clone(s.UNIT_SPHERE),C=new A,I={positions:void 0,colors:void 0,ellipsoid:N,vertexFormat:C,width:void 0,colorsPerVertex:void 0,followSurface:void 0,granularity:void 0};S.unpack=function(t,e,a){e=o(e,0);var u,E=t[e++],c=new Array(E);for(u=0;u<E;++u,e+=r.packedLength)c[u]=r.unpack(t,e);E=t[e++];var l=E>0?new Array(E):void 0;for(u=0;u<E;++u,e+=n.packedLength)l[u]=n.unpack(t,e);var f=s.unpack(t,e,N);e+=s.packedLength;var _=A.unpack(t,e,C);e+=A.packedLength;var R=t[e++],h=1===t[e++],T=1===t[e++],d=t[e];return i(a)?(a._positions=c,a._colors=l,a._ellipsoid=s.clone(f,a._ellipsoid),a._vertexFormat=A.clone(_,a._vertexFormat),a._width=R,a._colorsPerVertex=h,a._followSurface=T,a._granularity=d,a):(I.positions=c,I.colors=l,I.width=R,I.colorsPerVertex=h,I.followSurface=T,I.granularity=d,new S(I))};var p=new r,M=new r,O=new r,g=new r;return S.createGeometry=function(o){var u,s,A,S=o._width,N=o._vertexFormat,C=o._colors,I=o._colorsPerVertex,y=o._followSurface,F=o._granularity,L=o._ellipsoid,v=t(o._positions,r.equalsEpsilon),U=v.length;if(!(U<2||S<=0)){if(y){var P=h.extractHeights(v,L),D=R.chordLength(F,L.maximumRadius);if(i(C)){var w=1;for(u=0;u<U-1;++u)w+=h.numberOfPoints(v[u],v[u+1],D);var B=new Array(w),x=0;for(u=0;u<U-1;++u){var G=v[u],b=v[u+1],z=C[u],H=h.numberOfPoints(G,b,D);if(I&&u<w){var V=C[u+1],X=d(G,b,z,V,H),q=X.length;for(s=0;s<q;++s)B[x++]=X[s]}else for(s=0;s<H;++s)B[x++]=n.clone(z)}B[x]=n.clone(C[C.length-1]),C=B,m.length=0}v=h.generateCartesianArc({positions:v,minDistance:D,ellipsoid:L,height:P})}U=v.length;var W,Y=4*U-4,K=new Float64Array(3*Y),k=new Float64Array(3*Y),Z=new Float64Array(3*Y),j=new Float32Array(2*Y),Q=N.st?new Float32Array(2*Y):void 0,J=i(C)?new Uint8Array(4*Y):void 0,$=0,tt=0,et=0,rt=0;for(s=0;s<U;++s){0===s?(W=p,r.subtract(v[0],v[1],W),r.add(v[0],W,W)):W=v[s-1],r.clone(W,O),r.clone(v[s],M),s===U-1?(W=p,r.subtract(v[U-1],v[U-2],W),r.add(v[U-1],W,W)):W=v[s+1],r.clone(W,g);var nt,at;i(J)&&(nt=0===s||I?C[s]:C[s-1],s!==U-1&&(at=C[s]));var ot=0===s?2:0,it=s===U-1?2:4;for(A=ot;A<it;++A){r.pack(M,K,$),r.pack(O,k,$),r.pack(g,Z,$),$+=3;var ut=A-2<0?-1:1;if(j[tt++]=A%2*2-1,j[tt++]=ut*S,N.st&&(Q[et++]=s/(U-1),Q[et++]=Math.max(j[tt-2],0)),i(J)){var st=A<2?nt:at;J[rt++]=n.floatToByte(st.red),J[rt++]=n.floatToByte(st.green),J[rt++]=n.floatToByte(st.blue),J[rt++]=n.floatToByte(st.alpha)}}}var Et=new l;Et.position=new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:K}),Et.prevPosition=new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:k}),Et.nextPosition=new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:Z}),Et.expandAndWidth=new c({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:j}),N.st&&(Et.st=new c({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:Q})),i(J)&&(Et.color=new c({componentDatatype:a.UNSIGNED_BYTE,componentsPerAttribute:4,values:J,normalize:!0}));var ct=_.createTypedArray(Y,6*U-6),lt=0,ft=0,_t=U-1;for(s=0;s<_t;++s)ct[ft++]=lt,ct[ft++]=lt+2,ct[ft++]=lt+1,ct[ft++]=lt+1,ct[ft++]=lt+2,ct[ft++]=lt+3,lt+=4;return new E({attributes:Et,indices:ct,primitiveType:T.TRIANGLES,boundingSphere:e.fromPoints(v),geometryType:f.POLYLINES})}},S}),define("Workers/createPolylineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolylineGeometry"],function(t,e,r){"use strict";function n(n,a){return t(a)&&(n=r.unpack(n,a)),n._ellipsoid=e.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function r(t){return t+" is required, actual value was undefined"}function n(t,e,r){return"Expected "+r+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(n,a){if(!t(a))throw new e(r(n))},a.typeOf.func=function(t,r){if("function"!=typeof r)throw new e(n(typeof r,"function",t))},a.typeOf.string=function(t,r){if("string"!=typeof r)throw new e(n(typeof r,"string",t))},a.typeOf.number=function(t,r){if("number"!=typeof r)throw new e(n(typeof r,"number",t))},a.typeOf.number.lessThan=function(t,r,n){if(a.typeOf.number(t,r),r>=n)throw new e("Expected "+t+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(t,r,n){if(a.typeOf.number(t,r),r>n)throw new e("Expected "+t+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(t,r,n){if(a.typeOf.number(t,r),r<=n)throw new e("Expected "+t+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(t,r,n){if(a.typeOf.number(t,r),r<n)throw new e("Expected "+t+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(t,r){if("object"!=typeof r)throw new e(n(typeof r,"object",t))},a.typeOf.bool=function(t,r){if("boolean"!=typeof r)throw new e(n(typeof r,"boolean",t))},a.typeOf.number.equals=function(t,r,n,o){if(a.typeOf.number(t,n),a.typeOf.number(r,o),n!==o)throw new e(t+" must be equal to "+r+", the actual values are "+n+" and "+o)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)t=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^t>>>1^e[1&t];for(;r<this.N-1;r++)t=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,r){return r=e(r,255),Math.round((.5*a.clamp(t,-1,1)+.5)*r)},a.fromSNorm=function(t,r){return r=e(r,255),a.clamp(t,0,r)/r*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,r){return(1-r)*t+r*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,r=t-Math.floor(t/e)*e;return r<-Math.PI?r+e:r>=Math.PI?r-e:r},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,r,n,a){a=e(a,n);var o=Math.abs(t-r);return o<=a||o<=n*Math.max(Math.abs(t),Math.abs(r))};var o=[1];a.factorial=function(t){var e=o.length;if(t>=e)for(var r=o[e-1],n=e;n<=t;n++)o.push(r*n);return o[t]},a.incrementWrap=function(t,r,n){return n=e(n,0),++t,t>r&&(t=n),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,r){return t<e?e:t>r?r:t};var i=new t;return a.setRandomNumberSeed=function(e){i=new t(e)},a.nextRandomNumber=function(){return i.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var r=t*e;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,r,n){this.x=e(t,0),this.y=e(r,0),this.z=e(n,0)}i.fromSpherical=function(t,n){r(n)||(n=new i);var a=t.clock,o=t.cone,u=e(t.magnitude,1),s=u*Math.sin(o);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(o),n},i.fromElements=function(t,e,n,a){return r(a)?(a.x=t,a.y=e,a.z=n,a):new i(t,e,n)},i.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new i(t.x,t.y,t.z)},i.fromCartesian4=i.clone,i.packedLength=3,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.x,r[n++]=t.y,r[n]=t.z,r},i.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new i),a.x=t[n++],a.y=t[n++],a.z=t[n],a},i.packArray=function(t,e){var n=t.length;r(e)?e.length=3*n:e=new Array(3*n);for(var a=0;a<n;++a)i.pack(t[a],e,3*a);return e},i.unpackArray=function(t,e){var n=t.length;r(e)?e.length=n/3:e=new Array(n/3);for(var a=0;a<n;a+=3){var o=a/3;e[o]=i.unpack(t,a,e[o])}return e},i.fromArray=i.unpack,i.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},i.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},i.minimumByComponent=function(t,e,r){return r.x=Math.min(t.x,e.x),r.y=Math.min(t.y,e.y),r.z=Math.min(t.z,e.z),r},i.maximumByComponent=function(t,e,r){return r.x=Math.max(t.x,e.x),r.y=Math.max(t.y,e.y),r.z=Math.max(t.z,e.z),r},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},i.magnitude=function(t){return Math.sqrt(i.magnitudeSquared(t))};var u=new i;i.distance=function(t,e){return i.subtract(t,e,u),i.magnitude(u)},i.distanceSquared=function(t,e){return i.subtract(t,e,u),i.magnitudeSquared(u)},i.normalize=function(t,e){var r=i.magnitude(t);return e.x=t.x/r,e.y=t.y/r,e.z=t.z/r,e},i.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},i.multiplyComponents=function(t,e,r){return r.x=t.x*e.x,r.y=t.y*e.y,r.z=t.z*e.z,r},i.divideComponents=function(t,e,r){return r.x=t.x/e.x,r.y=t.y/e.y,r.z=t.z/e.z,r},i.add=function(t,e,r){return r.x=t.x+e.x,r.y=t.y+e.y,r.z=t.z+e.z,r},i.subtract=function(t,e,r){return r.x=t.x-e.x,r.y=t.y-e.y,r.z=t.z-e.z,r},i.multiplyByScalar=function(t,e,r){return r.x=t.x*e,r.y=t.y*e,r.z=t.z*e,r},i.divideByScalar=function(t,e,r){return r.x=t.x/e,r.y=t.y/e,r.z=t.z/e,r},i.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},i.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new i;i.lerp=function(t,e,r,n){return i.multiplyByScalar(e,r,s),n=i.multiplyByScalar(t,1-r,n),i.add(s,n,n)};var E=new i,c=new i;i.angleBetween=function(t,e){i.normalize(t,E),i.normalize(e,c);var r=i.dot(E,c),n=i.magnitude(i.cross(E,c,E));return Math.atan2(n,r)};var l=new i;i.mostOrthogonalAxis=function(t,e){var r=i.normalize(t,l);return i.abs(r,r),e=r.x<=r.y?r.x<=r.z?i.clone(i.UNIT_X,e):i.clone(i.UNIT_Z,e):r.y<=r.z?i.clone(i.UNIT_Y,e):i.clone(i.UNIT_Z,e)},i.projectVector=function(t,e,r){var n=i.dot(t,e)/i.dot(e,e);return i.multiplyByScalar(e,n,r)},i.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},i.equalsArray=function(t,e,r){return t.x===e[r]&&t.y===e[r+1]&&t.z===e[r+2]},i.equalsEpsilon=function(t,e,n,a){return t===e||r(t)&&r(e)&&o.equalsEpsilon(t.x,e.x,n,a)&&o.equalsEpsilon(t.y,e.y,n,a)&&o.equalsEpsilon(t.z,e.z,n,a)},i.cross=function(t,e,r){var n=t.x,a=t.y,o=t.z,i=e.x,u=e.y,s=e.z,E=a*s-o*u,c=o*i-n*s,l=n*u-a*i;return r.x=E,r.y=c,r.z=l,r},i.fromDegrees=function(t,e,r,n,a){return t=o.toRadians(t),e=o.toRadians(e),i.fromRadians(t,e,r,n,a)};var f=new i,_=new i,R=new i(40680631590769,40680631590769,40408299984661.445);return i.fromRadians=function(t,n,a,o,u){a=e(a,0);var s=r(o)?o.radiiSquared:R,E=Math.cos(n);f.x=E*Math.cos(t),f.y=E*Math.sin(t),f.z=Math.sin(n),f=i.normalize(f,f),i.multiplyComponents(s,f,_);var c=Math.sqrt(i.dot(f,_));return _=i.divideByScalar(_,c,_),f=i.multiplyByScalar(f,a,f),r(u)||(u=new i),i.add(_,f,u)},i.fromDegreesArray=function(t,e,n){var a=t.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=t[o],s=t[o+1],E=o/2;n[E]=i.fromDegrees(u,s,0,e,n[E])}return n},i.fromRadiansArray=function(t,e,n){var a=t.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=t[o],s=t[o+1],E=o/2;n[E]=i.fromRadians(u,s,0,e,n[E])}return n},i.fromDegreesArrayHeights=function(t,e,n){var a=t.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=t[o],s=t[o+1],E=t[o+2],c=o/3;n[c]=i.fromDegrees(u,s,E,e,n[c])}return n},i.fromRadiansArrayHeights=function(t,e,n){var a=t.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=t[o],s=t[o+1],E=t[o+2],c=o/3;n[c]=i.fromRadians(u,s,E,e,n[c])}return n},i.ZERO=a(new i(0,0,0)),i.UNIT_X=a(new i(1,0,0)),i.UNIT_Y=a(new i(0,1,0)),i.UNIT_Z=a(new i(0,0,1)),i.prototype.clone=function(t){return i.clone(this,t)},i.prototype.equals=function(t){return i.equals(this,t)},i.prototype.equalsEpsilon=function(t,e,r){return i.equalsEpsilon(this,t,e,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,r,n){"use strict";function a(r,a,u,s,E){var c=r.x,l=r.y,f=r.z,_=a.x,R=a.y,h=a.z,T=c*c*_*_,A=l*l*R*R,d=f*f*h*h,S=T+A+d,m=Math.sqrt(1/S),N=t.multiplyByScalar(r,m,o);if(S<s)return isFinite(m)?t.clone(N,E):void 0;var C=u.x,I=u.y,p=u.z,M=i;M.x=N.x*C*2,M.y=N.y*I*2,M.z=N.z*p*2;var O,g,y,F,L,v,P,U,D,w,B,x=(1-m)*t.magnitude(r)/(.5*t.magnitude(M)),G=0;do{x-=G,y=1/(1+x*C),F=1/(1+x*I),L=1/(1+x*p),v=y*y,P=F*F,U=L*L,D=v*y,w=P*F,B=U*L,O=T*v+A*P+d*U-1,g=T*D*C+A*w*I+d*B*p;G=O/(-2*g)}while(Math.abs(O)>n.EPSILON12);return e(E)?(E.x=c*y,E.y=l*F,E.z=f*L,E):new t(c*y,l*F,f*L)}var o=new t,i=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,r,n,a,o,i){"use strict";function u(t,e,n){this.longitude=r(t,0),this.latitude=r(e,0),this.height=r(n,0)}u.fromRadians=function(t,e,a,o){return a=r(a,0),n(o)?(o.longitude=t,o.latitude=e,o.height=a,o):new u(t,e,a)},u.fromDegrees=function(t,e,r,n){return t=o.toRadians(t),e=o.toRadians(e),u.fromRadians(t,e,r,n)};var s=new t,E=new t,c=new t,l=new t(1/6378137,1/6378137,1/6356752.314245179),f=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),_=o.EPSILON1;return u.fromCartesian=function(e,r,a){var R=n(r)?r.oneOverRadii:l,h=n(r)?r.oneOverRadiiSquared:f,T=n(r)?r._centerToleranceSquared:_,A=i(e,R,h,T,E);if(n(A)){var d=t.multiplyComponents(A,h,s);d=t.normalize(d,d);var S=t.subtract(e,A,c),m=Math.atan2(d.y,d.x),N=Math.asin(d.z),C=o.sign(t.dot(S,e))*t.magnitude(S);return n(a)?(a.longitude=m,a.latitude=N,a.height=C,a):new u(m,N,C)}},u.toCartesian=function(e,r,n){return t.fromRadians(e.longitude,e.latitude,e.height,r,n)},u.clone=function(t,e){if(n(t))return n(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||n(t)&&n(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,r){return t===e||n(t)&&n(e)&&Math.abs(t.longitude-e.longitude)<=r&&Math.abs(t.latitude-e.latitude)<=r&&Math.abs(t.height-e.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),r=Object.defineProperties;return e&&t(r)||(r=function(t){return t}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,r,n,a,o,i,u,s,E){"use strict";function c(e,r,a,o){r=n(r,0),a=n(a,0),o=n(o,0),e._radii=new t(r,a,o),e._radiiSquared=new t(r*r,a*a,o*o),e._radiiToTheFourth=new t(r*r*r*r,a*a*a*a,o*o*o*o),e._oneOverRadii=new t(0===r?0:1/r,0===a?0:1/a,0===o?0:1/o),e._oneOverRadiiSquared=new t(0===r?0:1/(r*r),0===a?0:1/(a*a),0===o?0:1/(o*o)),e._minimumRadius=Math.min(r,a,o),e._maximumRadius=Math.max(r,a,o),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function l(t,e,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,r)}o(l.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),l.clone=function(e,r){if(a(e)){var n=e._radii;return a(r)?(t.clone(n,r._radii),t.clone(e._radiiSquared,r._radiiSquared),t.clone(e._radiiToTheFourth,r._radiiToTheFourth),t.clone(e._oneOverRadii,r._oneOverRadii),t.clone(e._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=e._minimumRadius,r._maximumRadius=e._maximumRadius,r._centerToleranceSquared=e._centerToleranceSquared,r):new l(n.x,n.y,n.z)}},l.fromCartesian3=function(t,e){return a(e)||(e=new l),a(t)?(c(e,t.x,t.y,t.z),e):e},l.WGS84=u(new l(6378137,6378137,6356752.314245179)),l.UNIT_SPHERE=u(new l(1,1,1)),l.MOON=u(new l(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),l.prototype.clone=function(t){return l.clone(this,t)},l.packedLength=t.packedLength,l.pack=function(e,r,a){return a=n(a,0),t.pack(e._radii,r,a),r},l.unpack=function(e,r,a){r=n(r,0);var o=t.unpack(e,r);return l.fromCartesian3(o,a)},l.prototype.geocentricSurfaceNormal=t.normalize,l.prototype.geodeticSurfaceNormalCartographic=function(e,r){var n=e.longitude,o=e.latitude,i=Math.cos(o),u=i*Math.cos(n),s=i*Math.sin(n),E=Math.sin(o);return a(r)||(r=new t),r.x=u,r.y=s,r.z=E,t.normalize(r,r)},l.prototype.geodeticSurfaceNormal=function(e,r){return a(r)||(r=new t),r=t.multiplyComponents(e,this._oneOverRadiiSquared,r),t.normalize(r,r)};var f=new t,_=new t;l.prototype.cartographicToCartesian=function(e,r){var n=f,o=_;this.geodeticSurfaceNormalCartographic(e,n),t.multiplyComponents(this._radiiSquared,n,o);var i=Math.sqrt(t.dot(n,o));return t.divideByScalar(o,i,o),t.multiplyByScalar(n,e.height,n),a(r)||(r=new t),t.add(o,n,r)},l.prototype.cartographicArrayToCartesianArray=function(t,e){var r=t.length;a(e)?e.length=r:e=new Array(r);for(var n=0;n<r;n++)e[n]=this.cartographicToCartesian(t[n],e[n]);return e};var R=new t,h=new t,T=new t;return l.prototype.cartesianToCartographic=function(r,n){var o=this.scaleToGeodeticSurface(r,h);if(a(o)){var i=this.geodeticSurfaceNormal(o,R),u=t.subtract(r,o,T),E=Math.atan2(i.y,i.x),c=Math.asin(i.z),l=s.sign(t.dot(u,r))*t.magnitude(u);return a(n)?(n.longitude=E,n.latitude=c,n.height=l,n):new e(E,c,l)}},l.prototype.cartesianArrayToCartographicArray=function(t,e){var r=t.length;a(e)?e.length=r:e=new Array(r);for(var n=0;n<r;++n)e[n]=this.cartesianToCartographic(t[n],e[n]);return e},l.prototype.scaleToGeodeticSurface=function(t,e){return E(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},l.prototype.scaleToGeocentricSurface=function(e,r){a(r)||(r=new t);var n=e.x,o=e.y,i=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+o*o*u.y+i*i*u.z);return t.multiplyByScalar(e,s,r)},l.prototype.transformPositionToScaledSpace=function(e,r){return a(r)||(r=new t),t.multiplyComponents(e,this._oneOverRadii,r)},l.prototype.transformPositionFromScaledSpace=function(e,r){return a(r)||(r=new t),t.multiplyComponents(e,this._radii,r)},l.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},l.prototype.toString=function(){return this._radii.toString()},l.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,r,o){r=n(r,0);var i=this._squaredXOverSquaredZ;if(a(o)||(o=new t),o.x=0,o.y=0,o.z=e.z*(1-i),!(Math.abs(o.z)>=this._radii.z-r))return o},l}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(t,e,r,n){"use strict";function a(t,n,a){if(r(t)){a=e(a,!1);var i=t.length;if(i<2)return t;var u,s,E;for(u=1;u<i&&(s=t[u-1],E=t[u],!n(s,E,o));++u);if(u===i)return a&&n(t[0],t[t.length-1],o)?t.slice(1):t;for(var c=t.slice(0,u);u<i;++u)E=t[u],n(s,E,o)||(c.push(E),s=E);return a&&c.length>1&&n(c[0],c[c.length-1],o)&&c.shift(),c}}var o=n.EPSILON10;return a}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,r,n,a,o,i){"use strict";function u(t){this._ellipsoid=r(t,i.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,r){var a=this._semimajorAxis,o=e.longitude*a,i=e.latitude*a,u=e.height;return n(r)?(r.x=o,r.y=i,r.z=u,r):new t(o,i,u)},u.prototype.unproject=function(t,r){var a=this._oneOverSemimajorAxis,o=t.x*a,i=t.y*a,u=t.z;return n(r)?(r.longitude=o,r.latitude=i,r.height=u,r):new e(o,i,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,r){this.start=t(e,0),this.stop=t(r,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t,e,n,a,o,i,u,s,E){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(e,0),this[4]=r(o,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(i,0),this[8]=r(E,0)}function E(t){for(var e=0,r=0;r<9;++r){var n=t[r];e+=n*n}return Math.sqrt(e)}function c(t){for(var e=0,r=0;r<3;++r){var n=t[s.getElementIndex(h[r],R[r])];e+=2*n*n}return Math.sqrt(e)}function l(t,e){for(var r=u.EPSILON15,n=0,a=1,o=0;o<3;++o){var i=Math.abs(t[s.getElementIndex(h[o],R[o])]);i>n&&(a=o,n=i)}var E=1,c=0,l=R[a],f=h[a];if(Math.abs(t[s.getElementIndex(f,l)])>r){var _,T=t[s.getElementIndex(f,f)],A=t[s.getElementIndex(l,l)],d=t[s.getElementIndex(f,l)],S=(T-A)/2/d;_=S<0?-1/(-S+Math.sqrt(1+S*S)):1/(S+Math.sqrt(1+S*S)),E=1/Math.sqrt(1+_*_),c=_*E}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(l,l)]=e[s.getElementIndex(f,f)]=E,e[s.getElementIndex(f,l)]=c,e[s.getElementIndex(l,f)]=-c,e}s.packedLength=9,s.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e},s.unpack=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},s.clone=function(t,e){if(n(t))return n(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return n(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var r=t.x*t.x,a=t.x*t.y,o=t.x*t.z,i=t.x*t.w,u=t.y*t.y,E=t.y*t.z,c=t.y*t.w,l=t.z*t.z,f=t.z*t.w,_=t.w*t.w,R=r-u-l+_,h=2*(a-f),T=2*(o+c),A=2*(a+f),d=-r+u-l+_,S=2*(E-i),m=2*(o-c),N=2*(E+i),C=-r-u+l+_;return n(e)?(e[0]=R,e[1]=A,e[2]=m,e[3]=h,e[4]=d,e[5]=N,e[6]=T,e[7]=S,e[8]=C,e):new s(R,h,T,A,d,S,m,N,C)},s.fromHeadingPitchRoll=function(t,e){var r=Math.cos(-t.pitch),a=Math.cos(-t.heading),o=Math.cos(t.roll),i=Math.sin(-t.pitch),u=Math.sin(-t.heading),E=Math.sin(t.roll),c=r*a,l=-o*u+E*i*a,f=E*u+o*i*a,_=r*u,R=o*a+E*i*u,h=-E*a+o*i*u,T=-i,A=E*r,d=o*r;return n(e)?(e[0]=c,e[1]=_,e[2]=T,e[3]=l,e[4]=R,e[5]=A,e[6]=f,e[7]=h,e[8]=d,e):new s(c,l,f,_,R,h,T,A,d)},s.fromScale=function(t,e){return n(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return n(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return n(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=r,e[5]=a,e[6]=0,e[7]=-a,e[8]=r,e):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=r,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=r,e):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=r,e[1]=a,e[2]=0,e[3]=-a,e[4]=r,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(t,e){return n(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,r){var n=3*e,a=t[n],o=t[n+1],i=t[n+2];return r.x=a,r.y=o,r.z=i,r},s.setColumn=function(t,e,r,n){n=s.clone(t,n);var a=3*e;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(t,e,r){var n=t[e],a=t[e+3],o=t[e+6];return r.x=n,r.y=a,r.z=o,r},s.setRow=function(t,e,r,n){return n=s.clone(t,n),n[e]=r.x,n[e+3]=r.y,n[e+6]=r.z,n};var f=new t;s.getScale=function(e,r){return r.x=t.magnitude(t.fromElements(e[0],e[1],e[2],f)),r.y=t.magnitude(t.fromElements(e[3],e[4],e[5],f)),r.z=t.magnitude(t.fromElements(e[6],e[7],e[8],f)),r};var _=new t;s.getMaximumScale=function(e){return s.getScale(e,_),t.maximumComponent(_)},s.multiply=function(t,e,r){var n=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],o=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],i=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],E=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],l=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return r[0]=n,r[1]=a,r[2]=o,r[3]=i,r[4]=u,r[5]=s,r[6]=E,r[7]=c,r[8]=l,r},s.add=function(t,e,r){return r[0]=t[0]+e[0],r[1]=t[1]+e[1],r[2]=t[2]+e[2],r[3]=t[3]+e[3],r[4]=t[4]+e[4],r[5]=t[5]+e[5],r[6]=t[6]+e[6],r[7]=t[7]+e[7],r[8]=t[8]+e[8],r},s.subtract=function(t,e,r){return r[0]=t[0]-e[0],r[1]=t[1]-e[1],r[2]=t[2]-e[2],r[3]=t[3]-e[3],r[4]=t[4]-e[4],r[5]=t[5]-e[5],r[6]=t[6]-e[6],r[7]=t[7]-e[7],r[8]=t[8]-e[8],r},s.multiplyByVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[3]*a+t[6]*o,u=t[1]*n+t[4]*a+t[7]*o,s=t[2]*n+t[5]*a+t[8]*o;return r.x=i,r.y=u,r.z=s,r},s.multiplyByScalar=function(t,e,r){return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*e,r[5]=t[5]*e,r[6]=t[6]*e,r[7]=t[7]*e,r[8]=t[8]*e,r},s.multiplyByScale=function(t,e,r){return r[0]=t[0]*e.x,r[1]=t[1]*e.x,r[2]=t[2]*e.x,r[3]=t[3]*e.y,r[4]=t[4]*e.y,r[5]=t[5]*e.y,r[6]=t[6]*e.z,r[7]=t[7]*e.z,r[8]=t[8]*e.z,r},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var r=t[0],n=t[3],a=t[6],o=t[1],i=t[4],u=t[7],s=t[2],E=t[5],c=t[8];return e[0]=r,e[1]=n,e[2]=a,e[3]=o,e[4]=i,e[5]=u,e[6]=s,e[7]=E,e[8]=c,e};var R=[1,0,0],h=[2,2,1],T=new s,A=new s;return s.computeEigenDecomposition=function(t,e){var r=u.EPSILON20,a=0,o=0;n(e)||(e={});for(var i=e.unitary=s.clone(s.IDENTITY,e.unitary),f=e.diagonal=s.clone(t,e.diagonal),_=r*E(f);o<10&&c(f)>_;)l(f,T),s.transpose(T,A),s.multiply(f,T,f),s.multiply(A,f,f),s.multiply(i,T,i),++a>2&&(++o,a=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],r=t[3],n=t[6],a=t[1],o=t[4],i=t[7],u=t[2],s=t[5],E=t[8];return e*(o*E-s*i)+a*(s*n-r*E)+u*(r*i-o*n)},s.inverse=function(t,e){var r=t[0],n=t[1],a=t[2],o=t[3],i=t[4],u=t[5],E=t[6],c=t[7],l=t[8],f=s.determinant(t);e[0]=i*l-c*u,e[1]=c*a-n*l,e[2]=n*u-i*a,e[3]=E*u-o*l,e[4]=r*l-E*a,e[5]=o*a-r*u,e[6]=o*c-E*i,e[7]=E*n-r*c,e[8]=r*i-o*n;var _=1/f;return s.multiplyByScalar(e,_,e)},s.equals=function(t,e){return t===e||n(t)&&n(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,r){return t===e||n(t)&&n(e)&&Math.abs(t[0]-e[0])<=r&&Math.abs(t[1]-e[1])<=r&&Math.abs(t[2]-e[2])<=r&&Math.abs(t[3]-e[3])<=r&&Math.abs(t[4]-e[4])<=r&&Math.abs(t[5]-e[5])<=r&&Math.abs(t[6]-e[6])<=r&&Math.abs(t[7]-e[7])<=r&&Math.abs(t[8]-e[8])<=r},s.IDENTITY=i(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=i(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,r){return t[0]===e[r]&&t[1]===e[r+1]&&t[2]===e[r+2]&&t[3]===e[r+3]&&t[4]===e[r+4]&&t[5]===e[r+5]&&t[6]===e[r+6]&&t[7]===e[r+7]&&t[8]===e[r+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,r,n,a){this.x=e(t,0),this.y=e(r,0),this.z=e(n,0),this.w=e(a,0)}i.fromElements=function(t,e,n,a,o){return r(o)?(o.x=t,o.y=e,o.z=n,o.w=a,o):new i(t,e,n,a)},i.fromColor=function(t,e){return r(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new i(t.red,t.green,t.blue,t.alpha)},i.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new i(t.x,t.y,t.z,t.w)},i.packedLength=4,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.x,r[n++]=t.y,r[n++]=t.z,r[n]=t.w,r},i.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new i),a.x=t[n++],a.y=t[n++],a.z=t[n++],a.w=t[n],a},i.packArray=function(t,e){var n=t.length;r(e)?e.length=4*n:e=new Array(4*n);for(var a=0;a<n;++a)i.pack(t[a],e,4*a);return e},i.unpackArray=function(t,e){var n=t.length;r(e)?e.length=n/4:e=new Array(n/4);for(var a=0;a<n;a+=4){var o=a/4;e[o]=i.unpack(t,a,e[o])}return e},i.fromArray=i.unpack,i.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},i.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},i.minimumByComponent=function(t,e,r){return r.x=Math.min(t.x,e.x),r.y=Math.min(t.y,e.y),r.z=Math.min(t.z,e.z),r.w=Math.min(t.w,e.w),r},i.maximumByComponent=function(t,e,r){return r.x=Math.max(t.x,e.x),r.y=Math.max(t.y,e.y),r.z=Math.max(t.z,e.z),r.w=Math.max(t.w,e.w),r},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},i.magnitude=function(t){return Math.sqrt(i.magnitudeSquared(t))};var u=new i;i.distance=function(t,e){return i.subtract(t,e,u),i.magnitude(u)},i.distanceSquared=function(t,e){return i.subtract(t,e,u),i.magnitudeSquared(u)},i.normalize=function(t,e){var r=i.magnitude(t);return e.x=t.x/r,e.y=t.y/r,e.z=t.z/r,e.w=t.w/r,e},i.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},i.multiplyComponents=function(t,e,r){return r.x=t.x*e.x,r.y=t.y*e.y,r.z=t.z*e.z,r.w=t.w*e.w,r},i.divideComponents=function(t,e,r){return r.x=t.x/e.x,r.y=t.y/e.y,r.z=t.z/e.z,r.w=t.w/e.w,r},i.add=function(t,e,r){return r.x=t.x+e.x,r.y=t.y+e.y,r.z=t.z+e.z,r.w=t.w+e.w,r},i.subtract=function(t,e,r){return r.x=t.x-e.x,r.y=t.y-e.y,r.z=t.z-e.z,r.w=t.w-e.w,r},i.multiplyByScalar=function(t,e,r){return r.x=t.x*e,r.y=t.y*e,r.z=t.z*e,r.w=t.w*e,r},i.divideByScalar=function(t,e,r){return r.x=t.x/e,r.y=t.y/e,r.z=t.z/e,r.w=t.w/e,r},i.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},i.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new i;i.lerp=function(t,e,r,n){return i.multiplyByScalar(e,r,s),n=i.multiplyByScalar(t,1-r,n),i.add(s,n,n)};var E=new i;return i.mostOrthogonalAxis=function(t,e){var r=i.normalize(t,E);return i.abs(r,r),e=r.x<=r.y?r.x<=r.z?r.x<=r.w?i.clone(i.UNIT_X,e):i.clone(i.UNIT_W,e):r.z<=r.w?i.clone(i.UNIT_Z,e):i.clone(i.UNIT_W,e):r.y<=r.z?r.y<=r.w?i.clone(i.UNIT_Y,e):i.clone(i.UNIT_W,e):r.z<=r.w?i.clone(i.UNIT_Z,e):i.clone(i.UNIT_W,e)},i.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},i.equalsArray=function(t,e,r){return t.x===e[r]&&t.y===e[r+1]&&t.z===e[r+2]&&t.w===e[r+3]},i.equalsEpsilon=function(t,e,n,a){return t===e||r(t)&&r(e)&&o.equalsEpsilon(t.x,e.x,n,a)&&o.equalsEpsilon(t.y,e.y,n,a)&&o.equalsEpsilon(t.z,e.z,n,a)&&o.equalsEpsilon(t.w,e.w,n,a)},i.ZERO=a(new i(0,0,0,0)),i.UNIT_X=a(new i(1,0,0,0)),i.UNIT_Y=a(new i(0,1,0,0)),i.UNIT_Z=a(new i(0,0,1,0)), +i.UNIT_W=a(new i(0,0,0,1)),i.prototype.clone=function(t){return i.clone(this,t)},i.prototype.equals=function(t){return i.equals(this,t)},i.prototype.equalsEpsilon=function(t,e,r){return i.equalsEpsilon(this,t,e,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},i}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,r,n,a,o,i,u,s,E){"use strict";function c(t,e,r,a,o,i,u,s,E,c,l,f,_,R,h,T){this[0]=n(t,0),this[1]=n(o,0),this[2]=n(E,0),this[3]=n(_,0),this[4]=n(e,0),this[5]=n(i,0),this[6]=n(c,0),this[7]=n(R,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(l,0),this[11]=n(h,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(T,0)}c.packedLength=16,c.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e[r++]=t[9],e[r++]=t[10],e[r++]=t[11],e[r++]=t[12],e[r++]=t[13],e[r++]=t[14],e[r]=t[15],e},c.unpack=function(t,e,r){return e=n(e,0),a(r)||(r=new c),r[0]=t[e++],r[1]=t[e++],r[2]=t[e++],r[3]=t[e++],r[4]=t[e++],r[5]=t[e++],r[6]=t[e++],r[7]=t[e++],r[8]=t[e++],r[9]=t[e++],r[10]=t[e++],r[11]=t[e++],r[12]=t[e++],r[13]=t[e++],r[14]=t[e++],r[15]=t[e],r},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,r,o){return r=n(r,t.ZERO),a(o)?(o[0]=e[0],o[1]=e[1],o[2]=e[2],o[3]=0,o[4]=e[3],o[5]=e[4],o[6]=e[5],o[7]=0,o[8]=e[6],o[9]=e[7],o[10]=e[8],o[11]=0,o[12]=r.x,o[13]=r.y,o[14]=r.z,o[15]=1,o):new c(e[0],e[3],e[6],r.x,e[1],e[4],e[7],r.y,e[2],e[5],e[8],r.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,r,n){a(n)||(n=new c);var o=r.x,i=r.y,u=r.z,s=e.x*e.x,E=e.x*e.y,l=e.x*e.z,f=e.x*e.w,_=e.y*e.y,R=e.y*e.z,h=e.y*e.w,T=e.z*e.z,A=e.z*e.w,d=e.w*e.w,S=s-_-T+d,m=2*(E-A),N=2*(l+h),C=2*(E+A),I=-s+_-T+d,p=2*(R-f),M=2*(l-h),O=2*(R+f),g=-s-_+T+d;return n[0]=S*o,n[1]=C*o,n[2]=M*o,n[3]=0,n[4]=m*i,n[5]=I*i,n[6]=O*i,n[7]=0,n[8]=N*u,n[9]=p*u,n[10]=g*u,n[11]=0,n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=1,n},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(s.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var l=new t,f=new t,_=new t;c.fromCamera=function(e,r){var n=e.position,o=e.direction,i=e.up;t.normalize(o,l),t.normalize(t.cross(l,i,f),f),t.normalize(t.cross(f,l,_),_);var u=f.x,s=f.y,E=f.z,R=l.x,h=l.y,T=l.z,A=_.x,d=_.y,S=_.z,m=n.x,N=n.y,C=n.z,I=u*-m+s*-N+E*-C,p=A*-m+d*-N+S*-C,M=R*m+h*N+T*C;return a(r)?(r[0]=u,r[1]=A,r[2]=-R,r[3]=0,r[4]=s,r[5]=d,r[6]=-h,r[7]=0,r[8]=E,r[9]=S,r[10]=-T,r[11]=0,r[12]=I,r[13]=p,r[14]=M,r[15]=1,r):new c(u,s,E,I,A,d,S,p,-R,-h,-T,M,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,r,n,a){var o=Math.tan(.5*t),i=1/o,u=i/e,s=(n+r)/(r-n),E=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=i,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,r,n,a,o,i){var u=1/(e-t),s=1/(n-r),E=1/(o-a),c=-(e+t)*u,l=-(n+r)*s,f=-(o+a)*E;return u*=2,s*=2,E*=-2,i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=c,i[13]=l,i[14]=f,i[15]=1,i},c.computePerspectiveOffCenter=function(t,e,r,n,a,o,i){var u=2*a/(e-t),s=2*a/(n-r),E=(e+t)/(e-t),c=(n+r)/(n-r),l=-(o+a)/(o-a),f=-2*o*a/(o-a);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=E,i[9]=c,i[10]=l,i[11]=-1,i[12]=0,i[13]=0,i[14]=f,i[15]=0,i},c.computeInfinitePerspectiveOffCenter=function(t,e,r,n,a,o){var i=2*a/(e-t),u=2*a/(n-r),s=(e+t)/(e-t),E=(n+r)/(n-r),c=-2*a;return o[0]=i,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=u,o[6]=0,o[7]=0,o[8]=s,o[9]=E,o[10]=-1,o[11]=-1,o[12]=0,o[13]=0,o[14]=c,o[15]=0,o},c.computeViewportTransformation=function(t,e,r,a){t=n(t,n.EMPTY_OBJECT);var o=n(t.x,0),i=n(t.y,0),u=n(t.width,0),s=n(t.height,0);e=n(e,0),r=n(r,1);var E=.5*u,c=.5*s,l=.5*(r-e),f=E,_=c,R=l,h=o+E,T=i+c,A=e+l;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=_,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=h,a[13]=T,a[14]=A,a[15]=1,a},c.computeView=function(e,r,n,a,o){return o[0]=a.x,o[1]=n.x,o[2]=-r.x,o[3]=0,o[4]=a.y,o[5]=n.y,o[6]=-r.y,o[7]=0,o[8]=a.z,o[9]=n.z,o[10]=-r.z,o[11]=0,o[12]=-t.dot(a,e),o[13]=-t.dot(n,e),o[14]=t.dot(r,e),o[15]=1,o},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,r){var n=4*e,a=t[n],o=t[n+1],i=t[n+2],u=t[n+3];return r.x=a,r.y=o,r.z=i,r.w=u,r},c.setColumn=function(t,e,r,n){n=c.clone(t,n);var a=4*e;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},c.setTranslation=function(t,e,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=t[15],r},c.getRow=function(t,e,r){var n=t[e],a=t[e+4],o=t[e+8],i=t[e+12];return r.x=n,r.y=a,r.z=o,r.w=i,r},c.setRow=function(t,e,r,n){return n=c.clone(t,n),n[e]=r.x,n[e+4]=r.y,n[e+8]=r.z,n[e+12]=r.w,n};var R=new t;c.getScale=function(e,r){return r.x=t.magnitude(t.fromElements(e[0],e[1],e[2],R)),r.y=t.magnitude(t.fromElements(e[4],e[5],e[6],R)),r.z=t.magnitude(t.fromElements(e[8],e[9],e[10],R)),r};var h=new t;c.getMaximumScale=function(e){return c.getScale(e,h),t.maximumComponent(h)},c.multiply=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[3],u=t[4],s=t[5],E=t[6],c=t[7],l=t[8],f=t[9],_=t[10],R=t[11],h=t[12],T=t[13],A=t[14],d=t[15],S=e[0],m=e[1],N=e[2],C=e[3],I=e[4],p=e[5],M=e[6],O=e[7],g=e[8],y=e[9],F=e[10],L=e[11],v=e[12],P=e[13],U=e[14],D=e[15],w=n*S+u*m+l*N+h*C,B=a*S+s*m+f*N+T*C,x=o*S+E*m+_*N+A*C,G=i*S+c*m+R*N+d*C,b=n*I+u*p+l*M+h*O,z=a*I+s*p+f*M+T*O,H=o*I+E*p+_*M+A*O,V=i*I+c*p+R*M+d*O,X=n*g+u*y+l*F+h*L,q=a*g+s*y+f*F+T*L,W=o*g+E*y+_*F+A*L,Y=i*g+c*y+R*F+d*L,K=n*v+u*P+l*U+h*D,k=a*v+s*P+f*U+T*D,Z=o*v+E*P+_*U+A*D,j=i*v+c*P+R*U+d*D;return r[0]=w,r[1]=B,r[2]=x,r[3]=G,r[4]=b,r[5]=z,r[6]=H,r[7]=V,r[8]=X,r[9]=q,r[10]=W,r[11]=Y,r[12]=K,r[13]=k,r[14]=Z,r[15]=j,r},c.add=function(t,e,r){return r[0]=t[0]+e[0],r[1]=t[1]+e[1],r[2]=t[2]+e[2],r[3]=t[3]+e[3],r[4]=t[4]+e[4],r[5]=t[5]+e[5],r[6]=t[6]+e[6],r[7]=t[7]+e[7],r[8]=t[8]+e[8],r[9]=t[9]+e[9],r[10]=t[10]+e[10],r[11]=t[11]+e[11],r[12]=t[12]+e[12],r[13]=t[13]+e[13],r[14]=t[14]+e[14],r[15]=t[15]+e[15],r},c.subtract=function(t,e,r){return r[0]=t[0]-e[0],r[1]=t[1]-e[1],r[2]=t[2]-e[2],r[3]=t[3]-e[3],r[4]=t[4]-e[4],r[5]=t[5]-e[5],r[6]=t[6]-e[6],r[7]=t[7]-e[7],r[8]=t[8]-e[8],r[9]=t[9]-e[9],r[10]=t[10]-e[10],r[11]=t[11]-e[11],r[12]=t[12]-e[12],r[13]=t[13]-e[13],r[14]=t[14]-e[14],r[15]=t[15]-e[15],r},c.multiplyTransformation=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[4],u=t[5],s=t[6],E=t[8],c=t[9],l=t[10],f=t[12],_=t[13],R=t[14],h=e[0],T=e[1],A=e[2],d=e[4],S=e[5],m=e[6],N=e[8],C=e[9],I=e[10],p=e[12],M=e[13],O=e[14],g=n*h+i*T+E*A,y=a*h+u*T+c*A,F=o*h+s*T+l*A,L=n*d+i*S+E*m,v=a*d+u*S+c*m,P=o*d+s*S+l*m,U=n*N+i*C+E*I,D=a*N+u*C+c*I,w=o*N+s*C+l*I,B=n*p+i*M+E*O+f,x=a*p+u*M+c*O+_,G=o*p+s*M+l*O+R;return r[0]=g,r[1]=y,r[2]=F,r[3]=0,r[4]=L,r[5]=v,r[6]=P,r[7]=0,r[8]=U,r[9]=D,r[10]=w,r[11]=0,r[12]=B,r[13]=x,r[14]=G,r[15]=1,r},c.multiplyByMatrix3=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[4],u=t[5],s=t[6],E=t[8],c=t[9],l=t[10],f=e[0],_=e[1],R=e[2],h=e[3],T=e[4],A=e[5],d=e[6],S=e[7],m=e[8],N=n*f+i*_+E*R,C=a*f+u*_+c*R,I=o*f+s*_+l*R,p=n*h+i*T+E*A,M=a*h+u*T+c*A,O=o*h+s*T+l*A,g=n*d+i*S+E*m,y=a*d+u*S+c*m,F=o*d+s*S+l*m;return r[0]=N,r[1]=C,r[2]=I,r[3]=0,r[4]=p,r[5]=M,r[6]=O,r[7]=0,r[8]=g,r[9]=y,r[10]=F,r[11]=0,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15],r},c.multiplyByTranslation=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=n*t[0]+a*t[4]+o*t[8]+t[12],u=n*t[1]+a*t[5]+o*t[9]+t[13],s=n*t[2]+a*t[6]+o*t[10]+t[14];return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=i,r[13]=u,r[14]=s,r[15]=t[15],r};var T=new t;c.multiplyByUniformScale=function(t,e,r){return T.x=e,T.y=e,T.z=e,c.multiplyByScale(t,T,r)},c.multiplyByScale=function(t,e,r){var n=e.x,a=e.y,o=e.z;return 1===n&&1===a&&1===o?c.clone(t,r):(r[0]=n*t[0],r[1]=n*t[1],r[2]=n*t[2],r[3]=0,r[4]=a*t[4],r[5]=a*t[5],r[6]=a*t[6],r[7]=0,r[8]=o*t[8],r[9]=o*t[9],r[10]=o*t[10],r[11]=0,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=1,r)},c.multiplyByVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=e.w,u=t[0]*n+t[4]*a+t[8]*o+t[12]*i,s=t[1]*n+t[5]*a+t[9]*o+t[13]*i,E=t[2]*n+t[6]*a+t[10]*o+t[14]*i,c=t[3]*n+t[7]*a+t[11]*o+t[15]*i;return r.x=u,r.y=s,r.z=E,r.w=c,r},c.multiplyByPointAsVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[4]*a+t[8]*o,u=t[1]*n+t[5]*a+t[9]*o,s=t[2]*n+t[6]*a+t[10]*o;return r.x=i,r.y=u,r.z=s,r},c.multiplyByPoint=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[4]*a+t[8]*o+t[12],u=t[1]*n+t[5]*a+t[9]*o+t[13],s=t[2]*n+t[6]*a+t[10]*o+t[14];return r.x=i,r.y=u,r.z=s,r},c.multiplyByScalar=function(t,e,r){return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*e,r[5]=t[5]*e,r[6]=t[6]*e,r[7]=t[7]*e,r[8]=t[8]*e,r[9]=t[9]*e,r[10]=t[10]*e,r[11]=t[11]*e,r[12]=t[12]*e,r[13]=t[13]*e,r[14]=t[14]*e,r[15]=t[15]*e,r},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var r=t[1],n=t[2],a=t[3],o=t[6],i=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=r,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=n,e[9]=o,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=i,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,r){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=r&&Math.abs(t[1]-e[1])<=r&&Math.abs(t[2]-e[2])<=r&&Math.abs(t[3]-e[3])<=r&&Math.abs(t[4]-e[4])<=r&&Math.abs(t[5]-e[5])<=r&&Math.abs(t[6]-e[6])<=r&&Math.abs(t[7]-e[7])<=r&&Math.abs(t[8]-e[8])<=r&&Math.abs(t[9]-e[9])<=r&&Math.abs(t[10]-e[10])<=r&&Math.abs(t[11]-e[11])<=r&&Math.abs(t[12]-e[12])<=r&&Math.abs(t[13]-e[13])<=r&&Math.abs(t[14]-e[14])<=r&&Math.abs(t[15]-e[15])<=r},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var A=new s,d=new s,S=new e,m=new e(0,0,0,1);return c.inverse=function(t,r){if(s.equalsEpsilon(c.getRotation(t,A),d,u.EPSILON7)&&e.equals(c.getRow(t,3,S),m))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-t[12],r[13]=-t[13],r[14]=-t[14],r[15]=1,r;var n=t[0],a=t[4],o=t[8],i=t[12],l=t[1],f=t[5],_=t[9],R=t[13],h=t[2],T=t[6],N=t[10],C=t[14],I=t[3],p=t[7],M=t[11],O=t[15],g=N*O,y=C*M,F=T*O,L=C*p,v=T*M,P=N*p,U=h*O,D=C*I,w=h*M,B=N*I,x=h*p,G=T*I,b=g*f+L*_+v*R-(y*f+F*_+P*R),z=y*l+U*_+B*R-(g*l+D*_+w*R),H=F*l+D*f+x*R-(L*l+U*f+G*R),V=P*l+w*f+G*_-(v*l+B*f+x*_),X=y*a+F*o+P*i-(g*a+L*o+v*i),q=g*n+D*o+w*i-(y*n+U*o+B*i),W=L*n+U*a+G*i-(F*n+D*a+x*i),Y=v*n+B*a+x*o-(P*n+w*a+G*o);g=o*R,y=i*_,F=a*R,L=i*f,v=a*_,P=o*f,U=n*R,D=i*l,w=n*_,B=o*l,x=n*f,G=a*l;var K=g*p+L*M+v*O-(y*p+F*M+P*O),k=y*I+U*M+B*O-(g*I+D*M+w*O),Z=F*I+D*p+x*O-(L*I+U*p+G*O),j=P*I+w*p+G*M-(v*I+B*p+x*M),Q=F*N+P*C+y*T-(v*C+g*T+L*N),J=w*C+g*h+D*N-(U*N+B*C+y*h),$=U*T+G*C+L*h-(x*C+F*h+D*T),tt=x*N+v*h+B*T-(w*T+G*N+P*h),et=n*b+a*z+o*H+i*V;if(Math.abs(et)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return et=1/et,r[0]=b*et,r[1]=z*et,r[2]=H*et,r[3]=V*et,r[4]=X*et,r[5]=q*et,r[6]=W*et,r[7]=Y*et,r[8]=K*et,r[9]=k*et,r[10]=Z*et,r[11]=j*et,r[12]=Q*et,r[13]=J*et,r[14]=$*et,r[15]=tt*et,r},c.inverseTransformation=function(t,e){var r=t[0],n=t[1],a=t[2],o=t[4],i=t[5],u=t[6],s=t[8],E=t[9],c=t[10],l=t[12],f=t[13],_=t[14],R=-r*l-n*f-a*_,h=-o*l-i*f-u*_,T=-s*l-E*f-c*_;return e[0]=r,e[1]=o,e[2]=s,e[3]=0,e[4]=n,e[5]=i,e[6]=E,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=R,e[13]=h,e[14]=T,e[15]=1,e},c.IDENTITY=i(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=i(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,o(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,r){return t[0]===e[r]&&t[1]===e[r+1]&&t[2]===e[r+2]&&t[3]===e[r+3]&&t[4]===e[r+4]&&t[5]===e[r+5]&&t[6]===e[r+6]&&t[7]===e[r+7]&&t[8]===e[r+8]&&t[9]===e[r+9]&&t[10]===e[r+10]&&t[11]===e[r+11]&&t[12]===e[r+12]&&t[13]===e[r+13]&&t[14]===e[r+14]&&t[15]===e[r+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t,e,n,a){this.west=r(t,0),this.south=r(e,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,n){return n=r(n,0),e[n++]=t.west,e[n++]=t.south,e[n++]=t.east,e[n]=t.north,e},s.unpack=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},s.computeWidth=function(t){var e=t.east,r=t.west;return e<r&&(e+=u.TWO_PI),e-r},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,a,o,i){return t=u.toRadians(r(t,0)),e=u.toRadians(r(e,0)),a=u.toRadians(r(a,0)),o=u.toRadians(r(o,0)),n(i)?(i.west=t,i.south=e,i.east=a,i.north=o,i):new s(t,e,a,o)},s.fromRadians=function(t,e,a,o,i){return n(i)?(i.west=r(t,0),i.south=r(e,0),i.east=r(a,0),i.north=r(o,0),i):new s(t,e,a,o)},s.fromCartographicArray=function(t,e){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,o=Number.MAX_VALUE,i=-Number.MAX_VALUE,E=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=0,f=t.length;l<f;l++){var _=t[l];r=Math.min(r,_.longitude),a=Math.max(a,_.longitude),E=Math.min(E,_.latitude),c=Math.max(c,_.latitude);var R=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;o=Math.min(o,R),i=Math.max(i,R)}return a-r>i-o&&(r=o,a=i,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(e)?(e.west=r,e.south=E,e.east=a,e.north=c,e):new s(r,E,a,c)},s.fromCartesianArray=function(t,e,a){e=r(e,o.WGS84);for(var i=Number.MAX_VALUE,E=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=0,h=t.length;R<h;R++){var T=e.cartesianToCartographic(t[R]);i=Math.min(i,T.longitude),E=Math.max(E,T.longitude),f=Math.min(f,T.latitude),_=Math.max(_,T.latitude);var A=T.longitude>=0?T.longitude:T.longitude+u.TWO_PI;c=Math.min(c,A),l=Math.max(l,A)}return E-i>l-c&&(i=c,E=l,E>u.PI&&(E-=u.TWO_PI),i>u.PI&&(i-=u.TWO_PI)),n(a)?(a.west=i,a.south=f,a.east=E,a.north=_,a):new s(i,f,E,_)},s.clone=function(t,e){if(n(t))return n(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||n(t)&&n(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return n(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,r){return n(r)?(r.longitude=e.west,r.latitude=e.south,r.height=0,r):new t(e.west,e.south)},s.northwest=function(e,r){return n(r)?(r.longitude=e.west,r.latitude=e.north,r.height=0,r):new t(e.west,e.north)},s.northeast=function(e,r){return n(r)?(r.longitude=e.east,r.latitude=e.north,r.height=0,r):new t(e.east,e.north)},s.southeast=function(e,r){return n(r)?(r.longitude=e.east,r.latitude=e.south,r.height=0,r):new t(e.east,e.south)},s.center=function(e,r){var a=e.east,o=e.west;a<o&&(a+=u.TWO_PI);var i=u.negativePiToPi(.5*(o+a)),s=.5*(e.south+e.north);return n(r)?(r.longitude=i,r.latitude=s,r.height=0,r):new t(i,s)},s.intersection=function(t,e,r){var a=t.east,o=t.west,i=e.east,E=e.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var c=u.negativePiToPi(Math.max(o,E)),l=u.negativePiToPi(Math.min(a,i));if(!((t.west<t.east||e.west<e.east)&&l<=c)){var f=Math.max(t.south,e.south),_=Math.min(t.north,e.north);if(!(f>=_))return n(r)?(r.west=c,r.south=f,r.east=l,r.north=_,r):new s(c,f,l,_)}},s.simpleIntersection=function(t,e,r){var a=Math.max(t.west,e.west),o=Math.max(t.south,e.south),i=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(o>=u||a>=i))return n(r)?(r.west=a,r.south=o,r.east=i,r.north=u,r):new s(a,o,i,u)},s.union=function(t,e,r){n(r)||(r=new s);var a=t.east,o=t.west,i=e.east,E=e.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(o,E)),l=u.convertLongitudeRange(Math.max(a,i));return r.west=c,r.south=Math.min(t.south,e.south),r.east=l,r.north=Math.max(t.north,e.north),r},s.expand=function(t,e,r){return n(r)||(r=new s),r.west=Math.min(t.west,e.longitude),r.south=Math.min(t.south,e.latitude),r.east=Math.max(t.east,e.longitude),r.north=Math.max(t.north,e.latitude),r},s.contains=function(t,e){var r=e.longitude,n=e.latitude,a=t.west,o=t.east;return o<a&&(o+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<o||u.equalsEpsilon(r,o,u.EPSILON14))&&n>=t.south&&n<=t.north};var E=new t;return s.subsample=function(t,e,a,i){e=r(e,o.WGS84),a=r(a,0),n(i)||(i=[]);var c=0,l=t.north,f=t.south,_=t.east,R=t.west,h=E;h.height=a,h.longitude=R,h.latitude=l,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.longitude=_,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.latitude=f,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.longitude=R,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.latitude=l<0?l:f>0?f:0;for(var T=1;T<8;++T)h.longitude=-Math.PI+T*u.PI_OVER_TWO,s.contains(t,h)&&(i[c]=e.cartographicToCartesian(h,i[c]),c++);return 0===h.latitude&&(h.longitude=R,i[c]=e.cartographicToCartesian(h,i[c]),c++,h.longitude=_,i[c]=e.cartographicToCartesian(h,i[c]),c++),i.length=c,i},s.MAX_VALUE=i(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,r,n,a,o,i,u,s,E,c,l,f){"use strict";function _(e,r){this.center=t.clone(a(e,t.ZERO)),this.radius=a(r,0)}var R=new t,h=new t,T=new t,A=new t,d=new t,S=new t,m=new t,N=new t,C=new t,I=new t,p=new t,M=new t,O=4/3*r.PI;_.fromPoints=function(e,r){if(o(r)||(r=new _),!o(e)||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var n,a=t.clone(e[0],m),i=t.clone(a,R),u=t.clone(a,h),s=t.clone(a,T),E=t.clone(a,A),c=t.clone(a,d),l=t.clone(a,S),f=e.length;for(n=1;n<f;n++){t.clone(e[n],a);var O=a.x,g=a.y,y=a.z;O<i.x&&t.clone(a,i),O>E.x&&t.clone(a,E),g<u.y&&t.clone(a,u),g>c.y&&t.clone(a,c),y<s.z&&t.clone(a,s),y>l.z&&t.clone(a,l)}var F=t.magnitudeSquared(t.subtract(E,i,N)),L=t.magnitudeSquared(t.subtract(c,u,N)),v=t.magnitudeSquared(t.subtract(l,s,N)),P=i,U=E,D=F;L>D&&(D=L,P=u,U=c),v>D&&(D=v,P=s,U=l);var w=C;w.x=.5*(P.x+U.x),w.y=.5*(P.y+U.y),w.z=.5*(P.z+U.z);var B=t.magnitudeSquared(t.subtract(U,w,N)),x=Math.sqrt(B),G=I;G.x=i.x,G.y=u.y,G.z=s.z;var b=p;b.x=E.x,b.y=c.y,b.z=l.z;var z=t.multiplyByScalar(t.add(G,b,N),.5,M),H=0;for(n=0;n<f;n++){t.clone(e[n],a);var V=t.magnitude(t.subtract(a,z,N));V>H&&(H=V);var X=t.magnitudeSquared(t.subtract(a,w,N));if(X>B){var q=Math.sqrt(X);x=.5*(x+q),B=x*x;var W=q-x;w.x=(x*w.x+W*a.x)/q,w.y=(x*w.y+W*a.y)/q,w.z=(x*w.z+W*a.z)/q}}return x<H?(t.clone(w,r.center),r.radius=x):(t.clone(z,r.center),r.radius=H),r};var g=new u,y=new t,F=new t,L=new e,v=new e;_.fromRectangle2D=function(t,e,r){return _.fromRectangleWithHeights2D(t,e,0,0,r)},_.fromRectangleWithHeights2D=function(e,r,n,i,u){if(o(u)||(u=new _),!o(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;r=a(r,g),f.southwest(e,L),L.height=n,f.northeast(e,v),v.height=i;var s=r.project(L,y),E=r.project(v,F),c=E.x-s.x,l=E.y-s.y,R=E.z-s.z;u.radius=.5*Math.sqrt(c*c+l*l+R*R);var h=u.center;return h.x=s.x+.5*c,h.y=s.y+.5*l,h.z=s.z+.5*R,u};var P=[];_.fromRectangle3D=function(e,r,n,u){if(r=a(r,i.WGS84),n=a(n,0),o(u)||(u=new _),!o(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=f.subsample(e,r,n,P);return _.fromPoints(s,u)},_.fromVertices=function(e,r,n,i){if(o(i)||(i=new _),!o(e)||0===e.length)return i.center=t.clone(t.ZERO,i.center),i.radius=0,i;r=a(r,t.ZERO),n=a(n,3);var u=m;u.x=e[0]+r.x,u.y=e[1]+r.y,u.z=e[2]+r.z;var s,E=t.clone(u,R),c=t.clone(u,h),l=t.clone(u,T),f=t.clone(u,A),O=t.clone(u,d),g=t.clone(u,S),y=e.length;for(s=0;s<y;s+=n){var F=e[s]+r.x,L=e[s+1]+r.y,v=e[s+2]+r.z;u.x=F,u.y=L,u.z=v,F<E.x&&t.clone(u,E),F>f.x&&t.clone(u,f),L<c.y&&t.clone(u,c),L>O.y&&t.clone(u,O),v<l.z&&t.clone(u,l),v>g.z&&t.clone(u,g)}var P=t.magnitudeSquared(t.subtract(f,E,N)),U=t.magnitudeSquared(t.subtract(O,c,N)),D=t.magnitudeSquared(t.subtract(g,l,N)),w=E,B=f,x=P;U>x&&(x=U,w=c,B=O),D>x&&(x=D,w=l,B=g);var G=C;G.x=.5*(w.x+B.x),G.y=.5*(w.y+B.y),G.z=.5*(w.z+B.z);var b=t.magnitudeSquared(t.subtract(B,G,N)),z=Math.sqrt(b),H=I;H.x=E.x,H.y=c.y,H.z=l.z;var V=p;V.x=f.x,V.y=O.y,V.z=g.z;var X=t.multiplyByScalar(t.add(H,V,N),.5,M),q=0;for(s=0;s<y;s+=n){u.x=e[s]+r.x,u.y=e[s+1]+r.y,u.z=e[s+2]+r.z;var W=t.magnitude(t.subtract(u,X,N));W>q&&(q=W);var Y=t.magnitudeSquared(t.subtract(u,G,N));if(Y>b){var K=Math.sqrt(Y);z=.5*(z+K),b=z*z;var k=K-z;G.x=(z*G.x+k*u.x)/K,G.y=(z*G.y+k*u.y)/K,G.z=(z*G.z+k*u.z)/K}}return z<q?(t.clone(G,i.center),i.radius=z):(t.clone(X,i.center),i.radius=q),i},_.fromEncodedCartesianVertices=function(e,r,n){if(o(n)||(n=new _),!o(e)||!o(r)||e.length!==r.length||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var a=m;a.x=e[0]+r[0],a.y=e[1]+r[1],a.z=e[2]+r[2];var i,u=t.clone(a,R),s=t.clone(a,h),E=t.clone(a,T),c=t.clone(a,A),l=t.clone(a,d),f=t.clone(a,S),O=e.length;for(i=0;i<O;i+=3){var g=e[i]+r[i],y=e[i+1]+r[i+1],F=e[i+2]+r[i+2];a.x=g,a.y=y,a.z=F,g<u.x&&t.clone(a,u),g>c.x&&t.clone(a,c),y<s.y&&t.clone(a,s),y>l.y&&t.clone(a,l),F<E.z&&t.clone(a,E),F>f.z&&t.clone(a,f)}var L=t.magnitudeSquared(t.subtract(c,u,N)),v=t.magnitudeSquared(t.subtract(l,s,N)),P=t.magnitudeSquared(t.subtract(f,E,N)),U=u,D=c,w=L;v>w&&(w=v,U=s,D=l),P>w&&(w=P,U=E,D=f);var B=C;B.x=.5*(U.x+D.x),B.y=.5*(U.y+D.y),B.z=.5*(U.z+D.z);var x=t.magnitudeSquared(t.subtract(D,B,N)),G=Math.sqrt(x),b=I;b.x=u.x,b.y=s.y,b.z=E.z;var z=p;z.x=c.x,z.y=l.y,z.z=f.z;var H=t.multiplyByScalar(t.add(b,z,N),.5,M),V=0;for(i=0;i<O;i+=3){a.x=e[i]+r[i],a.y=e[i+1]+r[i+1],a.z=e[i+2]+r[i+2];var X=t.magnitude(t.subtract(a,H,N));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(a,B,N));if(q>x){var W=Math.sqrt(q);G=.5*(G+W),x=G*G;var Y=W-G;B.x=(G*B.x+Y*a.x)/W,B.y=(G*B.y+Y*a.y)/W,B.z=(G*B.z+Y*a.z)/W}}return G<V?(t.clone(B,n.center),n.radius=G):(t.clone(H,n.center),n.radius=V),n},_.fromCornerPoints=function(e,r,n){o(n)||(n=new _);var a=n.center;return t.add(e,r,a),t.multiplyByScalar(a,.5,a),n.radius=t.distance(a,r),n},_.fromEllipsoid=function(e,r){return o(r)||(r=new _),t.clone(t.ZERO,r.center),r.radius=e.maximumRadius,r};var U=new t;_.fromBoundingSpheres=function(e,r){if(o(r)||(r=new _),!o(e)||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var n=e.length;if(1===n)return _.clone(e[0],r);if(2===n)return _.union(e[0],e[1],r);var a,i=[];for(a=0;a<n;a++)i.push(e[a].center);r=_.fromPoints(i,r);var u=r.center,s=r.radius;for(a=0;a<n;a++){var E=e[a];s=Math.max(s,t.distance(u,E.center,U)+E.radius)}return r.radius=s,r};var D=new t,w=new t,B=new t;_.fromOrientedBoundingBox=function(e,r){o(r)||(r=new _);var n=e.halfAxes,a=c.getColumn(n,0,D),i=c.getColumn(n,1,w),u=c.getColumn(n,2,B);return t.add(a,i,a),t.add(a,u,a),r.center=t.clone(e.center,r.center),r.radius=t.magnitude(a),r},_.clone=function(e,r){if(o(e))return o(r)?(r.center=t.clone(e.center,r.center),r.radius=e.radius,r):new _(e.center,e.radius)},_.packedLength=4,_.pack=function(t,e,r){r=a(r,0);var n=t.center;return e[r++]=n.x,e[r++]=n.y,e[r++]=n.z,e[r]=t.radius,e},_.unpack=function(t,e,r){e=a(e,0),o(r)||(r=new _);var n=r.center;return n.x=t[e++],n.y=t[e++],n.z=t[e++],r.radius=t[e],r};var x=new t,G=new t;_.union=function(e,r,n){o(n)||(n=new _);var a=e.center,i=e.radius,u=r.center,s=r.radius,E=t.subtract(u,a,x),c=t.magnitude(E);if(i>=c+s)return e.clone(n),n;if(s>=c+i)return r.clone(n),n;var l=.5*(i+c+s),f=t.multiplyByScalar(E,(-i+l)/c,G);return t.add(f,a,f),t.clone(f,n.center),n.radius=l,n};var b=new t;_.expand=function(e,r,n){n=_.clone(e,n);var a=t.magnitude(t.subtract(r,n.center,b));return a>n.radius&&(n.radius=a),n},_.intersectPlane=function(e,r){var n=e.center,a=e.radius,o=r.normal,i=t.dot(o,n)+r.distance;return i<-a?s.OUTSIDE:i<a?s.INTERSECTING:s.INSIDE},_.transform=function(t,e,r){return o(r)||(r=new _),r.center=l.multiplyByPoint(e,t.center,r.center),r.radius=l.getMaximumScale(e)*t.radius,r};var z=new t;_.distanceSquaredTo=function(e,r){var n=t.subtract(e.center,r,z);return t.magnitudeSquared(n)-e.radius*e.radius},_.transformWithoutScale=function(t,e,r){return o(r)||(r=new _),r.center=l.multiplyByPoint(e,t.center,r.center),r.radius=t.radius,r};var H=new t;_.computePlaneDistances=function(e,r,n,a){o(a)||(a=new E);var i=t.subtract(e.center,r,H),u=t.dot(n,i);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var V=new t,X=new t,q=new t,W=new t,Y=new t,K=new e,k=new Array(8),Z=0;Z<8;++Z)k[Z]=new t;var j=new u;return _.projectTo2D=function(e,r,n){r=a(r,j);var o=r.ellipsoid,i=e.center,u=e.radius,s=o.geodeticSurfaceNormal(i,V),E=t.cross(t.UNIT_Z,s,X);t.normalize(E,E);var c=t.cross(s,E,q);t.normalize(c,c),t.multiplyByScalar(s,u,s),t.multiplyByScalar(c,u,c),t.multiplyByScalar(E,u,E);var l=t.negate(c,Y),f=t.negate(E,W),R=k,h=R[0];t.add(s,c,h),t.add(h,E,h),h=R[1],t.add(s,c,h),t.add(h,f,h),h=R[2],t.add(s,l,h),t.add(h,f,h),h=R[3],t.add(s,l,h),t.add(h,E,h),t.negate(s,s),h=R[4],t.add(s,c,h),t.add(h,E,h),h=R[5],t.add(s,c,h),t.add(h,f,h),h=R[6],t.add(s,l,h),t.add(h,f,h),h=R[7],t.add(s,l,h),t.add(h,E,h);for(var T=R.length,A=0;A<T;++A){var d=R[A];t.add(i,d,d);var S=o.cartesianToCartographic(d,K);r.project(S,d)}n=_.fromPoints(R,n),i=n.center;var m=i.x,N=i.y,C=i.z;return i.x=C,i.y=m,i.z=N,n},_.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},_.equals=function(e,r){return e===r||o(e)&&o(r)&&t.equals(e.center,r.center)&&e.radius===r.radius},_.prototype.intersectPlane=function(t){return _.intersectPlane(this,t)},_.prototype.distanceSquaredTo=function(t){return _.distanceSquaredTo(this,t)},_.prototype.computePlaneDistances=function(t,e,r){return _.computePlaneDistances(this,t,e,r)},_.prototype.isOccluded=function(t){return _.isOccluded(this,t)},_.prototype.equals=function(t){return _.equals(this,t)},_.prototype.clone=function(t){return _.clone(this,t)},_.prototype.volume=function(){var t=this.radius;return O*t*t*t},_}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(r))return r;r=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,o=["webkit","moz","o","ms","khtml"],i=0,u=o.length;i<u;++i){var s=o[i];a=s+"RequestFullscreen","function"==typeof e[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof e[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[n.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,r){"use strict";function n(t){ +for(var e=t.split("."),r=0,n=e.length;r<n;++r)e[r]=parseInt(e[r],10);return e}function a(){if(!e(N)&&(N=!1,!f())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(N=!0,C=n(t[1]))}return N}function o(){return a()&&C}function i(){if(!e(I)&&(I=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(I=!0,p=n(t[1]))}return I}function u(){return i()&&p}function s(){if(!e(M)){M=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(M=!0,O=n(t[1]),O.isNightly=!!t[2])}return M}function E(){return s()&&O}function c(){if(!e(g)){g=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(t[1]))}return g}function l(){return c()&&y}function f(){if(!e(F)){F=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(F=!0,L=n(t[1]))}return F}function _(){return f()&&L}function R(){if(!e(v)){v=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(v=!0,P=n(t[1]))}return v}function h(){return e(U)||(U=/Windows/i.test(m.appVersion)),U}function T(){return R()&&P}function A(){return e(D)||(D="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),D}function d(){if(!e(B)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=t.style.imageRendering;B=e(r)&&""!==r,B&&(w=r)}return B}function S(){return d()?w:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var N,C,I,p,M,O,g,y,F,L,v,P,U,D,w,B,x={isChrome:a,chromeVersion:o,isSafari:i,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:c,internetExplorerVersion:l,isEdge:f,edgeVersion:_,isFirefox:R,firefoxVersion:T,isWindows:h,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:A,supportsImageRenderingPixelated:d,imageRenderingValue:S};return x.supportsFullscreen=function(){return r.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/Color",["./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,e,r){return r<0&&(r+=1),r>1&&(r-=1),6*r<1?t+6*(e-t)*r:2*r<1?e:3*r<2?t+(e-t)*(2/3-r)*6:t}function u(t,r,n,a){this.red=e(t,1),this.green=e(r,1),this.blue=e(n,1),this.alpha=e(a,1)}u.fromCartesian4=function(t,e){return r(e)?(e.red=t.x,e.green=t.y,e.blue=t.z,e.alpha=t.w,e):new u(t.x,t.y,t.z,t.w)},u.fromBytes=function(t,n,a,o,i){return t=u.byteToFloat(e(t,255)),n=u.byteToFloat(e(n,255)),a=u.byteToFloat(e(a,255)),o=u.byteToFloat(e(o,255)),r(i)?(i.red=t,i.green=n,i.blue=a,i.alpha=o,i):new u(t,n,a,o)},u.fromAlpha=function(t,e,n){return r(n)?(n.red=t.red,n.green=t.green,n.blue=t.blue,n.alpha=e,n):new u(t.red,t.green,t.blue,e)};var s,E,c;n.supportsTypedArrays()&&(s=new ArrayBuffer(4),E=new Uint32Array(s),c=new Uint8Array(s)),u.fromRgba=function(t,e){return E[0]=t,u.fromBytes(c[0],c[1],c[2],c[3],e)},u.fromHsl=function(t,n,a,o,s){t=e(t,0)%1,n=e(n,0),a=e(a,0),o=e(o,1);var E=a,c=a,l=a;if(0!==n){var f;f=a<.5?a*(1+n):a+n-a*n;var _=2*a-f;E=i(_,f,t+1/3),c=i(_,f,t),l=i(_,f,t-1/3)}return r(s)?(s.red=E,s.green=c,s.blue=l,s.alpha=o,s):new u(E,c,l,o)},u.fromRandom=function(t,n){t=e(t,e.EMPTY_OBJECT);var a=t.red;if(!r(a)){var i=e(t.minimumRed,0),s=e(t.maximumRed,1);a=i+o.nextRandomNumber()*(s-i)}var E=t.green;if(!r(E)){var c=e(t.minimumGreen,0),l=e(t.maximumGreen,1);E=c+o.nextRandomNumber()*(l-c)}var f=t.blue;if(!r(f)){var _=e(t.minimumBlue,0),R=e(t.maximumBlue,1);f=_+o.nextRandomNumber()*(R-_)}var h=t.alpha;if(!r(h)){var T=e(t.minimumAlpha,0),A=e(t.maximumAlpha,1);h=T+o.nextRandomNumber()*(A-T)}return r(n)?(n.red=a,n.green=E,n.blue=f,n.alpha=h,n):new u(a,E,f,h)};var l=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,f=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,_=/^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i,R=/^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i;return u.fromCssColorString=function(t,n){r(n)||(n=new u);var a=u[t.toUpperCase()];if(r(a))return u.clone(a,n),n;var o=l.exec(t);return null!==o?(n.red=parseInt(o[1],16)/15,n.green=parseInt(o[2],16)/15,n.blue=parseInt(o[3],16)/15,n.alpha=1,n):null!==(o=f.exec(t))?(n.red=parseInt(o[1],16)/255,n.green=parseInt(o[2],16)/255,n.blue=parseInt(o[3],16)/255,n.alpha=1,n):null!==(o=_.exec(t))?(n.red=parseFloat(o[1])/("%"===o[1].substr(-1)?100:255),n.green=parseFloat(o[2])/("%"===o[2].substr(-1)?100:255),n.blue=parseFloat(o[3])/("%"===o[3].substr(-1)?100:255),n.alpha=parseFloat(e(o[4],"1.0")),n):null!==(o=R.exec(t))?u.fromHsl(parseFloat(o[1])/360,parseFloat(o[2])/100,parseFloat(o[3])/100,parseFloat(e(o[4],"1.0")),n):n=void 0},u.packedLength=4,u.pack=function(t,r,n){return n=e(n,0),r[n++]=t.red,r[n++]=t.green,r[n++]=t.blue,r[n]=t.alpha,r},u.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new u),a.red=t[n++],a.green=t[n++],a.blue=t[n++],a.alpha=t[n],a},u.byteToFloat=function(t){return t/255},u.floatToByte=function(t){return 1===t?255:256*t|0},u.clone=function(t,e){if(r(t))return r(e)?(e.red=t.red,e.green=t.green,e.blue=t.blue,e.alpha=t.alpha,e):new u(t.red,t.green,t.blue,t.alpha)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.red===e.red&&t.green===e.green&&t.blue===e.blue&&t.alpha===e.alpha},u.equalsArray=function(t,e,r){return t.red===e[r]&&t.green===e[r+1]&&t.blue===e[r+2]&&t.alpha===e[r+3]},u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return this===t||r(t)&&Math.abs(this.red-t.red)<=e&&Math.abs(this.green-t.green)<=e&&Math.abs(this.blue-t.blue)<=e&&Math.abs(this.alpha-t.alpha)<=e},u.prototype.toString=function(){return"("+this.red+", "+this.green+", "+this.blue+", "+this.alpha+")"},u.prototype.toCssColorString=function(){var t=u.floatToByte(this.red),e=u.floatToByte(this.green),r=u.floatToByte(this.blue);return 1===this.alpha?"rgb("+t+","+e+","+r+")":"rgba("+t+","+e+","+r+","+this.alpha+")"},u.prototype.toBytes=function(t){var e=u.floatToByte(this.red),n=u.floatToByte(this.green),a=u.floatToByte(this.blue),o=u.floatToByte(this.alpha);return r(t)?(t[0]=e,t[1]=n,t[2]=a,t[3]=o,t):[e,n,a,o]},u.prototype.toRgba=function(){return c[0]=u.floatToByte(this.red),c[1]=u.floatToByte(this.green),c[2]=u.floatToByte(this.blue),c[3]=u.floatToByte(this.alpha),E[0]},u.prototype.brighten=function(t,e){return t=1-t,e.red=1-(1-this.red)*t,e.green=1-(1-this.green)*t,e.blue=1-(1-this.blue)*t,e.alpha=this.alpha,e},u.prototype.darken=function(t,e){return t=1-t,e.red=this.red*t,e.green=this.green*t,e.blue=this.blue*t,e.alpha=this.alpha,e},u.prototype.withAlpha=function(t,e){return u.fromAlpha(this,t,e)},u.add=function(t,e,r){return r.red=t.red+e.red,r.green=t.green+e.green,r.blue=t.blue+e.blue,r.alpha=t.alpha+e.alpha,r},u.subtract=function(t,e,r){return r.red=t.red-e.red,r.green=t.green-e.green,r.blue=t.blue-e.blue,r.alpha=t.alpha-e.alpha,r},u.multiply=function(t,e,r){return r.red=t.red*e.red,r.green=t.green*e.green,r.blue=t.blue*e.blue,r.alpha=t.alpha*e.alpha,r},u.divide=function(t,e,r){return r.red=t.red/e.red,r.green=t.green/e.green,r.blue=t.blue/e.blue,r.alpha=t.alpha/e.alpha,r},u.mod=function(t,e,r){return r.red=t.red%e.red,r.green=t.green%e.green,r.blue=t.blue%e.blue,r.alpha=t.alpha%e.alpha,r},u.multiplyByScalar=function(t,e,r){return r.red=t.red*e,r.green=t.green*e,r.blue=t.blue*e,r.alpha=t.alpha*e,r},u.divideByScalar=function(t,e,r){return r.red=t.red/e,r.green=t.green/e,r.blue=t.blue/e,r.alpha=t.alpha/e,r},u.ALICEBLUE=a(u.fromCssColorString("#F0F8FF")),u.ANTIQUEWHITE=a(u.fromCssColorString("#FAEBD7")),u.AQUA=a(u.fromCssColorString("#00FFFF")),u.AQUAMARINE=a(u.fromCssColorString("#7FFFD4")),u.AZURE=a(u.fromCssColorString("#F0FFFF")),u.BEIGE=a(u.fromCssColorString("#F5F5DC")),u.BISQUE=a(u.fromCssColorString("#FFE4C4")),u.BLACK=a(u.fromCssColorString("#000000")),u.BLANCHEDALMOND=a(u.fromCssColorString("#FFEBCD")),u.BLUE=a(u.fromCssColorString("#0000FF")),u.BLUEVIOLET=a(u.fromCssColorString("#8A2BE2")),u.BROWN=a(u.fromCssColorString("#A52A2A")),u.BURLYWOOD=a(u.fromCssColorString("#DEB887")),u.CADETBLUE=a(u.fromCssColorString("#5F9EA0")),u.CHARTREUSE=a(u.fromCssColorString("#7FFF00")),u.CHOCOLATE=a(u.fromCssColorString("#D2691E")),u.CORAL=a(u.fromCssColorString("#FF7F50")),u.CORNFLOWERBLUE=a(u.fromCssColorString("#6495ED")),u.CORNSILK=a(u.fromCssColorString("#FFF8DC")),u.CRIMSON=a(u.fromCssColorString("#DC143C")),u.CYAN=a(u.fromCssColorString("#00FFFF")),u.DARKBLUE=a(u.fromCssColorString("#00008B")),u.DARKCYAN=a(u.fromCssColorString("#008B8B")),u.DARKGOLDENROD=a(u.fromCssColorString("#B8860B")),u.DARKGRAY=a(u.fromCssColorString("#A9A9A9")),u.DARKGREEN=a(u.fromCssColorString("#006400")),u.DARKGREY=u.DARKGRAY,u.DARKKHAKI=a(u.fromCssColorString("#BDB76B")),u.DARKMAGENTA=a(u.fromCssColorString("#8B008B")),u.DARKOLIVEGREEN=a(u.fromCssColorString("#556B2F")),u.DARKORANGE=a(u.fromCssColorString("#FF8C00")),u.DARKORCHID=a(u.fromCssColorString("#9932CC")),u.DARKRED=a(u.fromCssColorString("#8B0000")),u.DARKSALMON=a(u.fromCssColorString("#E9967A")),u.DARKSEAGREEN=a(u.fromCssColorString("#8FBC8F")),u.DARKSLATEBLUE=a(u.fromCssColorString("#483D8B")),u.DARKSLATEGRAY=a(u.fromCssColorString("#2F4F4F")),u.DARKSLATEGREY=u.DARKSLATEGRAY,u.DARKTURQUOISE=a(u.fromCssColorString("#00CED1")),u.DARKVIOLET=a(u.fromCssColorString("#9400D3")),u.DEEPPINK=a(u.fromCssColorString("#FF1493")),u.DEEPSKYBLUE=a(u.fromCssColorString("#00BFFF")),u.DIMGRAY=a(u.fromCssColorString("#696969")),u.DIMGREY=u.DIMGRAY,u.DODGERBLUE=a(u.fromCssColorString("#1E90FF")),u.FIREBRICK=a(u.fromCssColorString("#B22222")),u.FLORALWHITE=a(u.fromCssColorString("#FFFAF0")),u.FORESTGREEN=a(u.fromCssColorString("#228B22")),u.FUCHSIA=a(u.fromCssColorString("#FF00FF")),u.GAINSBORO=a(u.fromCssColorString("#DCDCDC")),u.GHOSTWHITE=a(u.fromCssColorString("#F8F8FF")),u.GOLD=a(u.fromCssColorString("#FFD700")),u.GOLDENROD=a(u.fromCssColorString("#DAA520")),u.GRAY=a(u.fromCssColorString("#808080")),u.GREEN=a(u.fromCssColorString("#008000")),u.GREENYELLOW=a(u.fromCssColorString("#ADFF2F")),u.GREY=u.GRAY,u.HONEYDEW=a(u.fromCssColorString("#F0FFF0")),u.HOTPINK=a(u.fromCssColorString("#FF69B4")),u.INDIANRED=a(u.fromCssColorString("#CD5C5C")),u.INDIGO=a(u.fromCssColorString("#4B0082")),u.IVORY=a(u.fromCssColorString("#FFFFF0")),u.KHAKI=a(u.fromCssColorString("#F0E68C")),u.LAVENDER=a(u.fromCssColorString("#E6E6FA")),u.LAVENDAR_BLUSH=a(u.fromCssColorString("#FFF0F5")),u.LAWNGREEN=a(u.fromCssColorString("#7CFC00")),u.LEMONCHIFFON=a(u.fromCssColorString("#FFFACD")),u.LIGHTBLUE=a(u.fromCssColorString("#ADD8E6")),u.LIGHTCORAL=a(u.fromCssColorString("#F08080")),u.LIGHTCYAN=a(u.fromCssColorString("#E0FFFF")),u.LIGHTGOLDENRODYELLOW=a(u.fromCssColorString("#FAFAD2")),u.LIGHTGRAY=a(u.fromCssColorString("#D3D3D3")),u.LIGHTGREEN=a(u.fromCssColorString("#90EE90")),u.LIGHTGREY=u.LIGHTGRAY,u.LIGHTPINK=a(u.fromCssColorString("#FFB6C1")),u.LIGHTSEAGREEN=a(u.fromCssColorString("#20B2AA")),u.LIGHTSKYBLUE=a(u.fromCssColorString("#87CEFA")),u.LIGHTSLATEGRAY=a(u.fromCssColorString("#778899")),u.LIGHTSLATEGREY=u.LIGHTSLATEGRAY,u.LIGHTSTEELBLUE=a(u.fromCssColorString("#B0C4DE")),u.LIGHTYELLOW=a(u.fromCssColorString("#FFFFE0")),u.LIME=a(u.fromCssColorString("#00FF00")),u.LIMEGREEN=a(u.fromCssColorString("#32CD32")),u.LINEN=a(u.fromCssColorString("#FAF0E6")),u.MAGENTA=a(u.fromCssColorString("#FF00FF")),u.MAROON=a(u.fromCssColorString("#800000")),u.MEDIUMAQUAMARINE=a(u.fromCssColorString("#66CDAA")),u.MEDIUMBLUE=a(u.fromCssColorString("#0000CD")),u.MEDIUMORCHID=a(u.fromCssColorString("#BA55D3")),u.MEDIUMPURPLE=a(u.fromCssColorString("#9370DB")),u.MEDIUMSEAGREEN=a(u.fromCssColorString("#3CB371")),u.MEDIUMSLATEBLUE=a(u.fromCssColorString("#7B68EE")),u.MEDIUMSPRINGGREEN=a(u.fromCssColorString("#00FA9A")),u.MEDIUMTURQUOISE=a(u.fromCssColorString("#48D1CC")),u.MEDIUMVIOLETRED=a(u.fromCssColorString("#C71585")),u.MIDNIGHTBLUE=a(u.fromCssColorString("#191970")),u.MINTCREAM=a(u.fromCssColorString("#F5FFFA")),u.MISTYROSE=a(u.fromCssColorString("#FFE4E1")),u.MOCCASIN=a(u.fromCssColorString("#FFE4B5")),u.NAVAJOWHITE=a(u.fromCssColorString("#FFDEAD")),u.NAVY=a(u.fromCssColorString("#000080")),u.OLDLACE=a(u.fromCssColorString("#FDF5E6")),u.OLIVE=a(u.fromCssColorString("#808000")),u.OLIVEDRAB=a(u.fromCssColorString("#6B8E23")),u.ORANGE=a(u.fromCssColorString("#FFA500")),u.ORANGERED=a(u.fromCssColorString("#FF4500")),u.ORCHID=a(u.fromCssColorString("#DA70D6")),u.PALEGOLDENROD=a(u.fromCssColorString("#EEE8AA")),u.PALEGREEN=a(u.fromCssColorString("#98FB98")),u.PALETURQUOISE=a(u.fromCssColorString("#AFEEEE")),u.PALEVIOLETRED=a(u.fromCssColorString("#DB7093")),u.PAPAYAWHIP=a(u.fromCssColorString("#FFEFD5")),u.PEACHPUFF=a(u.fromCssColorString("#FFDAB9")),u.PERU=a(u.fromCssColorString("#CD853F")),u.PINK=a(u.fromCssColorString("#FFC0CB")),u.PLUM=a(u.fromCssColorString("#DDA0DD")),u.POWDERBLUE=a(u.fromCssColorString("#B0E0E6")),u.PURPLE=a(u.fromCssColorString("#800080")),u.RED=a(u.fromCssColorString("#FF0000")),u.ROSYBROWN=a(u.fromCssColorString("#BC8F8F")),u.ROYALBLUE=a(u.fromCssColorString("#4169E1")),u.SADDLEBROWN=a(u.fromCssColorString("#8B4513")),u.SALMON=a(u.fromCssColorString("#FA8072")),u.SANDYBROWN=a(u.fromCssColorString("#F4A460")),u.SEAGREEN=a(u.fromCssColorString("#2E8B57")),u.SEASHELL=a(u.fromCssColorString("#FFF5EE")),u.SIENNA=a(u.fromCssColorString("#A0522D")),u.SILVER=a(u.fromCssColorString("#C0C0C0")),u.SKYBLUE=a(u.fromCssColorString("#87CEEB")),u.SLATEBLUE=a(u.fromCssColorString("#6A5ACD")),u.SLATEGRAY=a(u.fromCssColorString("#708090")),u.SLATEGREY=u.SLATEGRAY,u.SNOW=a(u.fromCssColorString("#FFFAFA")),u.SPRINGGREEN=a(u.fromCssColorString("#00FF7F")),u.STEELBLUE=a(u.fromCssColorString("#4682B4")),u.TAN=a(u.fromCssColorString("#D2B48C")),u.TEAL=a(u.fromCssColorString("#008080")),u.THISTLE=a(u.fromCssColorString("#D8BFD8")),u.TOMATO=a(u.fromCssColorString("#FF6347")),u.TURQUOISE=a(u.fromCssColorString("#40E0D0")),u.VIOLET=a(u.fromCssColorString("#EE82EE")),u.WHEAT=a(u.fromCssColorString("#F5DEB3")),u.WHITE=a(u.fromCssColorString("#FFFFFF")),u.WHITESMOKE=a(u.fromCssColorString("#F5F5F5")),u.YELLOW=a(u.fromCssColorString("#FFFF00")),u.YELLOWGREEN=a(u.fromCssColorString("#9ACD32")),u.TRANSPARENT=a(new u(0,0,0,0)),u}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,r,n,a,o){"use strict";if(!n.supportsTypedArrays())return{};var i={BYTE:o.BYTE,UNSIGNED_BYTE:o.UNSIGNED_BYTE,SHORT:o.SHORT,UNSIGNED_SHORT:o.UNSIGNED_SHORT,INT:o.INT,UNSIGNED_INT:o.UNSIGNED_INT,FLOAT:o.FLOAT,DOUBLE:o.DOUBLE};return i.getSizeInBytes=function(t){switch(t){case i.BYTE:return Int8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.SHORT:return Int16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.INT:return Int32Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case i.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case i.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},i.fromTypedArray=function(t){return t instanceof Int8Array?i.BYTE:t instanceof Uint8Array?i.UNSIGNED_BYTE:t instanceof Int16Array?i.SHORT:t instanceof Uint16Array?i.UNSIGNED_SHORT:t instanceof Int32Array?i.INT:t instanceof Uint32Array?i.UNSIGNED_INT:t instanceof Float32Array?i.FLOAT:t instanceof Float64Array?i.DOUBLE:void 0},i.validate=function(t){return e(t)&&(t===i.BYTE||t===i.UNSIGNED_BYTE||t===i.SHORT||t===i.UNSIGNED_SHORT||t===i.INT||t===i.UNSIGNED_INT||t===i.FLOAT||t===i.DOUBLE)},i.createTypedArray=function(t,e){switch(t){case i.BYTE:return new Int8Array(e);case i.UNSIGNED_BYTE:return new Uint8Array(e);case i.SHORT:return new Int16Array(e);case i.UNSIGNED_SHORT:return new Uint16Array(e);case i.INT:return new Int32Array(e);case i.UNSIGNED_INT:return new Uint32Array(e);case i.FLOAT:return new Float32Array(e);case i.DOUBLE:return new Float64Array(e)}},i.createArrayBufferView=function(e,r,n,a){switch(n=t(n,0),a=t(a,(r.byteLength-n)/i.getSizeInBytes(e)),e){case i.BYTE:return new Int8Array(r,n,a);case i.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case i.SHORT:return new Int16Array(r,n,a);case i.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case i.INT:return new Int32Array(r,n,a);case i.UNSIGNED_INT:return new Uint32Array(r,n,a);case i.FLOAT:return new Float32Array(r,n,a);case i.DOUBLE:return new Float64Array(r,n,a)}},i.fromName=function(t){switch(t){case"BYTE":return i.BYTE;case"UNSIGNED_BYTE":return i.UNSIGNED_BYTE;case"SHORT":return i.SHORT;case"UNSIGNED_SHORT":return i.UNSIGNED_SHORT;case"INT":return i.INT;case"UNSIGNED_INT":return i.UNSIGNED_INT;case"FLOAT":return i.FLOAT;case"DOUBLE":return i.DOUBLE}},a(i)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var r={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===r.POINTS||t===r.LINES||t===r.LINE_LOOP||t===r.LINE_STRIP||t===r.TRIANGLES||t===r.TRIANGLE_STRIP||t===r.TRIANGLE_FAN}};return t(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,r,n,a,o){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,o.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return i.computeNumberOfVertices=function(t){var e=-1;for(var n in t.attributes)if(t.attributes.hasOwnProperty(n)&&r(t.attributes[n])&&r(t.attributes[n].values)){var a=t.attributes[n],o=a.values.length/a.componentsPerAttribute;e=o}return e},i}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,r){"use strict";function n(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st, +this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,r,n,a){"use strict";var o={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return o.getSizeInBytes=function(t){switch(t){case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},o.validate=function(e){return t(e)&&(e===o.UNSIGNED_BYTE||e===o.UNSIGNED_SHORT||e===o.UNSIGNED_INT)},o.createTypedArray=function(t,e){return t>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},o.createTypedArrayFromArrayBuffer=function(t,e,r,a){return t>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,r,a):new Uint16Array(e,r,a)},r(o)}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t){var e=t._uSquared,r=t._ellipsoid.maximumRadius,n=t._ellipsoid.minimumRadius,a=(r-n)/r,o=Math.cos(t._startHeading),i=Math.sin(t._startHeading),u=(1-a)*Math.tan(t._start.latitude),s=1/Math.sqrt(1+u*u),E=s*u,c=Math.atan2(u,o),l=s*i,f=l*l,_=1-f,R=Math.sqrt(_),h=e/4,T=h*h,A=T*h,d=T*T,S=1+h-3*T/4+5*A/4-175*d/64,m=1-h+15*T/8-35*A/8,N=1-3*h+35*T/4,C=1-5*h,I=S*c-m*Math.sin(2*c)*h/2-N*Math.sin(4*c)*T/16-C*Math.sin(6*c)*A/48-5*Math.sin(8*c)*d/512,p=t._constants;p.a=r,p.b=n,p.f=a,p.cosineHeading=o,p.sineHeading=i,p.tanU=u,p.cosineU=s,p.sineU=E,p.sigma=c,p.sineAlpha=l,p.sineSquaredAlpha=f,p.cosineSquaredAlpha=_,p.cosineAlpha=R,p.u2Over4=h,p.u4Over16=T,p.u6Over64=A,p.u8Over256=d,p.a0=S,p.a1=m,p.a2=N,p.a3=C,p.distanceRatio=I}function E(t,e){return t*e*(4+t*(4-3*e))/16}function c(t,e,r,n,a,o,i){var u=E(t,r);return(1-u)*t*e*(n+u*a*(i+u*o*(2*i*i-1)))}function l(t,e,r,n,a,o,i){var s,E,l,f,_,R=(e-r)/e,h=o-n,T=Math.atan((1-R)*Math.tan(a)),A=Math.atan((1-R)*Math.tan(i)),d=Math.cos(T),S=Math.sin(T),m=Math.cos(A),N=Math.sin(A),C=d*m,I=d*N,p=S*N,M=S*m,O=h,g=u.TWO_PI,y=Math.cos(O),F=Math.sin(O);do{y=Math.cos(O),F=Math.sin(O);var L=I-M*y;l=Math.sqrt(m*m*F*F+L*L),E=p+C*y,s=Math.atan2(l,E);var v;0===l?(v=0,f=1):(v=C*F/l,f=1-v*v),g=O,_=E-2*p/f,isNaN(_)&&(_=0),O=h+c(R,v,f,s,l,E,_)}while(Math.abs(O-g)>u.EPSILON12);var P=f*(e*e-r*r)/(r*r),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,w=_*_,B=D*l*(_+D*(E*(2*w-1)-D*_*(4*l*l-3)*(4*w-3)/6)/4),x=r*U*(s-B),G=Math.atan2(m*F,I-M*y),b=Math.atan2(d*F,I*y-M);t._distance=x,t._startHeading=G,t._endHeading=b,t._uSquared=P}function f(r,n,a,o){t.normalize(o.cartographicToCartesian(n,h),R),t.normalize(o.cartographicToCartesian(a,h),h);l(r,o.maximumRadius,o.minimumRadius,n.longitude,n.latitude,a.longitude,a.latitude),r._start=e.clone(n,r._start),r._end=e.clone(a,r._end),r._start.height=0,r._end.height=0,s(r)}function _(t,r,o){var u=n(o,i.WGS84);this._ellipsoid=u,this._start=new e,this._end=new e,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(t)&&a(r)&&f(this,t,r,u)}var R=new t,h=new t;return o(_.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),_.prototype.setEndPoints=function(t,e){f(this,t,e,this._ellipsoid)},_.prototype.interpolateUsingFraction=function(t,e){return this.interpolateUsingSurfaceDistance(this._distance*t,e)},_.prototype.interpolateUsingSurfaceDistance=function(t,r){var n=this._constants,o=n.distanceRatio+t/n.b,i=Math.cos(2*o),u=Math.cos(4*o),s=Math.cos(6*o),E=Math.sin(2*o),l=Math.sin(4*o),f=Math.sin(6*o),_=Math.sin(8*o),R=o*o,h=o*R,T=n.u8Over256,A=n.u2Over4,d=n.u6Over64,S=n.u4Over16,m=2*h*T*i/3+o*(1-A+7*S/4-15*d/4+579*T/64-(S-15*d/4+187*T/16)*i-(5*d/4-115*T/16)*u-29*T*s/16)+(A/2-S+71*d/32-85*T/16)*E+(5*S/16-5*d/4+383*T/96)*l-R*((d-11*T/2)*E+5*T*l/2)+(29*d/96-29*T/16)*f+539*T*_/1536,N=Math.asin(Math.sin(m)*n.cosineAlpha),C=Math.atan(n.a/n.b*Math.tan(N));m-=n.sigma;var I=Math.cos(2*n.sigma+m),p=Math.sin(m),M=Math.cos(m),O=n.cosineU*M,g=n.sineU*p,y=Math.atan2(p*n.sineHeading,O-g*n.cosineHeading),F=y-c(n.f,n.sineAlpha,n.cosineSquaredAlpha,m,p,M,I);return a(r)?(r.longitude=this._start.longitude+F,r.latitude=C,r.height=0,r):new e(this._start.longitude+F,C,0)},_}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(t,e){"use strict";function r(t,r,n){var a=t+r;return e.sign(t)!==e.sign(r)&&Math.abs(a/Math.max(Math.abs(t),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(t,e,r){return e*e-4*t*r},n.computeRealRoots=function(t,n,a){var o;if(0===t)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var i=Math.abs(a),u=Math.abs(t);if(i<u&&i/u<e.EPSILON14)return[0,0];if(i>u&&u/i<e.EPSILON14)return[];if((o=-a/t)<0)return[];var s=Math.sqrt(o);return[-s,s]}if(0===a)return o=-n/t,o<0?[o,0]:[0,o];var E=n*n,c=4*t*a,l=r(E,-c,e.EPSILON14);if(l<0)return[];var f=-.5*r(n,e.sign(n)*Math.sqrt(l),e.EPSILON14);return n>0?[f/t,a/f]:[a/f,f/t]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(t,e){"use strict";function r(t,e,r,n){var a,o,i=t,u=e/3,s=r/3,E=n,c=i*s,l=u*E,f=u*u,_=s*s,R=i*s-f,h=i*E-u*s,T=u*E-_,A=4*R*T-h*h;if(A<0){var d,S,m;f*l>=c*_?(d=i,S=R,m=-2*u*R+i*h):(d=E,S=T,m=-E*h+2*s*T);var N=m<0?-1:1,C=-N*Math.abs(d)*Math.sqrt(-A);o=-m+C;var I=o/2,p=I<0?-Math.pow(-I,1/3):Math.pow(I,1/3),M=o===C?-p:-S/p;return a=S<=0?p+M:-m/(p*p+M*M+S),f*l>=c*_?[(a-u)/i]:[-E/(a+s)]}var O=R,g=-2*u*R+i*h,y=T,F=-E*h+2*s*T,L=Math.sqrt(A),v=Math.sqrt(3)/2,P=Math.abs(Math.atan2(i*L,-g)/3);a=2*Math.sqrt(-O);var U=Math.cos(P);o=a*U;var D=a*(-U/2-v*Math.sin(P)),w=o+D>2*u?o-u:D-u,B=i,x=w/B;P=Math.abs(Math.atan2(E*L,-F)/3),a=2*Math.sqrt(-y),U=Math.cos(P),o=a*U,D=a*(-U/2-v*Math.sin(P));var G=-E,b=o+D<2*s?o+s:D+s,z=G/b,H=B*b,V=-w*b-B*G,X=w*G,q=(s*V-u*X)/(-u*V+s*H);return x<=q?x<=z?q<=z?[x,q,z]:[x,z,q]:[z,x,q]:x<=z?[q,x,z]:q<=z?[q,z,x]:[z,q,x]}var n={};return n.computeDiscriminant=function(t,e,r,n){var a=t*t,o=e*e,i=r*r;return 18*t*e*r*n+o*i-27*a*(n*n)-4*(t*i*r+o*e*n)},n.computeRealRoots=function(t,n,a,o){var i,u;if(0===t)return e.computeRealRoots(n,a,o);if(0===n){if(0===a){if(0===o)return[0,0,0];u=-o/t;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===o?(i=e.computeRealRoots(t,0,a),0===i.Length?[0]:[i[0],0,i[1]]):r(t,0,a,o)}return 0===a?0===o?(u=-n/t,u<0?[u,0,0]:[0,0,u]):r(t,n,0,o):0===o?(i=e.computeRealRoots(t,n,a),0===i.length?[0]:i[1]<=0?[i[0],i[1],0]:i[0]>=0?[0,i[0],i[1]]:[i[0],0,i[1]]):r(t,n,a,o)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(t,e,r,n){"use strict";function a(e,a,o,i){var u=e*e,s=a-3*u/8,E=o-a*e/2+u*e/8,c=i-o*e/4+a*u/16-3*u*u/256,l=t.computeRealRoots(1,2*s,s*s-4*c,-E*E);if(l.length>0){var f=-e/4,_=l[l.length-1];if(Math.abs(_)<r.EPSILON14){var R=n.computeRealRoots(1,s,c);if(2===R.length){var h,T=R[0],A=R[1];if(T>=0&&A>=0){var d=Math.sqrt(T),S=Math.sqrt(A);return[f-S,f-d,f+d,f+S]}if(T>=0&&A<0)return h=Math.sqrt(T),[f-h,f+h];if(T<0&&A>=0)return h=Math.sqrt(A),[f-h,f+h]}return[]}if(_>0){var m=Math.sqrt(_),N=(s+_-E/m)/2,C=(s+_+E/m)/2,I=n.computeRealRoots(1,m,N),p=n.computeRealRoots(1,-m,C);return 0!==I.length?(I[0]+=f,I[1]+=f,0!==p.length?(p[0]+=f,p[1]+=f,I[1]<=p[0]?[I[0],I[1],p[0],p[1]]:p[1]<=I[0]?[p[0],p[1],I[0],I[1]]:I[0]>=p[0]&&I[1]<=p[1]?[p[0],I[0],I[1],p[1]]:p[0]>=I[0]&&p[1]<=I[1]?[I[0],p[0],p[1],I[1]]:I[0]>p[0]&&I[0]<p[1]?[p[0],I[0],p[1],I[1]]:[I[0],p[0],I[1],p[1]]):I):0!==p.length?(p[0]+=f,p[1]+=f,p):[]}}return[]}function o(e,a,o,i){var u=o*o,s=a*a,E=e*e,c=-2*a,l=o*e+s-4*i,f=E*i-o*a*e+u,_=t.computeRealRoots(1,c,l,f);if(_.length>0){var R,h,T=_[0],A=a-T,d=A*A,S=e/2,m=A/2,N=d-4*i,C=d+4*Math.abs(i),I=E-4*T,p=E+4*Math.abs(T);if(T<0||N*p<I*C){var M=Math.sqrt(I);R=M/2,h=0===M?0:(e*m-o)/M}else{var O=Math.sqrt(N);R=0===O?0:(e*m-o)/O,h=O/2}var g,y;0===S&&0===R?(g=0,y=0):r.sign(S)===r.sign(R)?(g=S+R,y=T/g):(y=S-R,g=T/y);var F,L;0===m&&0===h?(F=0,L=0):r.sign(m)===r.sign(h)?(F=m+h,L=i/F):(L=m-h,F=i/L);var v=n.computeRealRoots(1,g,F),P=n.computeRealRoots(1,y,L);if(0!==v.length)return 0!==P.length?v[1]<=P[0]?[v[0],v[1],P[0],P[1]]:P[1]<=v[0]?[P[0],P[1],v[0],v[1]]:v[0]>=P[0]&&v[1]<=P[1]?[P[0],v[0],v[1],P[1]]:P[0]>=v[0]&&P[1]<=v[1]?[v[0],P[0],P[1],v[1]]:v[0]>P[0]&&v[0]<P[1]?[P[0],v[0],P[1],v[1]]:[v[0],P[0],v[1],P[1]]:v;if(0!==P.length)return P}return[]}var i={};return i.computeDiscriminant=function(t,e,r,n,a){var o=t*t,i=o*t,u=e*e,s=u*e,E=r*r,c=E*r,l=n*n,f=l*n,_=a*a;return u*E*l-4*s*f-4*t*c*l+18*t*e*r*f-27*o*l*l+256*i*(_*a)+a*(18*s*r*n-4*u*c+16*t*E*E-80*t*e*E*n-6*t*u*l+144*o*r*l)+_*(144*t*u*r-27*u*u-128*o*E-192*o*e*n)},i.computeRealRoots=function(e,n,i,u,s){if(Math.abs(e)<r.EPSILON15)return t.computeRealRoots(n,i,u,s);var E=n/e,c=i/e,l=u/e,f=s/e,_=E<0?1:0;switch(_+=c<0?_+1:_,_+=l<0?_+1:_,_+=f<0?_+1:_){case 0:return a(E,c,l,f);case 1:case 2:return o(E,c,l,f);case 3:case 4:return a(E,c,l,f);case 5:return o(E,c,l,f);case 6:case 7:return a(E,c,l,f);case 8:return o(E,c,l,f);case 9:case 10:return a(E,c,l,f);case 11:return o(E,c,l,f);case 12:case 13:case 14:case 15:return a(E,c,l,f);default:return}},i}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(t,e,r,n){"use strict";function a(r,n){n=t.clone(e(n,t.ZERO)),t.equals(n,t.ZERO)||t.normalize(n,n),this.origin=t.clone(e(r,t.ZERO)),this.direction=n}return a.getPoint=function(e,n,a){return r(a)||(a=new t),a=t.multiplyByScalar(e.direction,n,a),t.add(e.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(t,e,r,n,a,o,i,u,s,E,c){"use strict";function l(t,e,r,n){var a=e*e-4*t*r;if(!(a<0)){if(a>0){var o=1/(2*t),i=Math.sqrt(a),u=(-e+i)*o,s=(-e-i)*o;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var E=-e/(2*t);if(0!==E)return n.root0=n.root1=E,n}}function f(e,r,a){n(a)||(a=new o);var i=e.origin,u=e.direction,s=r.center,E=r.radius*r.radius,c=t.subtract(i,s,d),f=t.dot(u,u),_=2*t.dot(u,c),R=t.magnitudeSquared(c)-E,h=l(f,_,R,C);if(n(h))return a.start=h.root0,a.stop=h.root1,a}function _(t,e,r){var n=t+e;return i.sign(t)!==i.sign(e)&&Math.abs(n/Math.max(Math.abs(t),Math.abs(e)))<r?0:n}function R(e,r,n,a,o){var c,l=a*a,f=o*o,R=(e[u.COLUMN1ROW1]-e[u.COLUMN2ROW2])*f,h=o*(a*_(e[u.COLUMN1ROW0],e[u.COLUMN0ROW1],i.EPSILON15)+r.y),T=e[u.COLUMN0ROW0]*l+e[u.COLUMN2ROW2]*f+a*r.x+n,A=f*_(e[u.COLUMN2ROW1],e[u.COLUMN1ROW2],i.EPSILON15),d=o*(a*_(e[u.COLUMN2ROW0],e[u.COLUMN0ROW2])+r.z),S=[];if(0===d&&0===A){if(c=s.computeRealRoots(R,h,T),0===c.length)return S;var m=c[0],N=Math.sqrt(Math.max(1-m*m,0));if(S.push(new t(a,o*m,o*-N)),S.push(new t(a,o*m,o*N)),2===c.length){var C=c[1],I=Math.sqrt(Math.max(1-C*C,0));S.push(new t(a,o*C,o*-I)),S.push(new t(a,o*C,o*I))}return S}var p=d*d,M=A*A,O=R*R,g=d*A,y=O+M,F=2*(h*R+g),L=2*T*R+h*h-M+p,v=2*(T*h-g),P=T*T-p;if(0===y&&0===F&&0===L&&0===v)return S;c=E.computeRealRoots(y,F,L,v,P);var U=c.length;if(0===U)return S;for(var D=0;D<U;++D){var w,B=c[D],x=B*B,G=Math.max(1-x,0),b=Math.sqrt(G);w=i.sign(R)===i.sign(T)?_(R*x+T,h*B,i.EPSILON12):i.sign(T)===i.sign(h*B)?_(R*x,h*B+T,i.EPSILON12):_(R*x+h*B,T,i.EPSILON12);var z=_(A*B,d,i.EPSILON15),H=w*z;H<0?S.push(new t(a,o*B,o*b)):H>0?S.push(new t(a,o*B,o*-b)):0!==b?(S.push(new t(a,o*B,o*-b)),S.push(new t(a,o*B,o*b)),++D):S.push(new t(a,o*B,o*b))}return S}var h={};h.rayPlane=function(e,r,a){n(a)||(a=new t);var o=e.origin,u=e.direction,s=r.normal,E=t.dot(s,u);if(!(Math.abs(E)<i.EPSILON15)){var c=(-r.distance-t.dot(s,o))/E;if(!(c<0))return a=t.multiplyByScalar(u,c,a),t.add(o,a,a)}};var T=new t,A=new t,d=new t,S=new t,m=new t;h.rayTriangleParametric=function(e,n,a,o,u){u=r(u,!1);var s,E,c,l,f,_=e.origin,R=e.direction,h=t.subtract(a,n,T),N=t.subtract(o,n,A),C=t.cross(R,N,d),I=t.dot(h,C);if(u){if(I<i.EPSILON6)return;if(s=t.subtract(_,n,S),(c=t.dot(s,C))<0||c>I)return;if(E=t.cross(s,h,m),(l=t.dot(R,E))<0||c+l>I)return;f=t.dot(N,E)/I}else{if(Math.abs(I)<i.EPSILON6)return;var p=1/I;if(s=t.subtract(_,n,S),(c=t.dot(s,C)*p)<0||c>1)return;if(E=t.cross(s,h,m),(l=t.dot(R,E)*p)<0||c+l>1)return;f=t.dot(N,E)*p}return f},h.rayTriangle=function(e,r,a,o,i,u){var s=h.rayTriangleParametric(e,r,a,o,i);if(n(s)&&!(s<0))return n(u)||(u=new t),t.multiplyByScalar(e.direction,s,u),t.add(e.origin,u,u)};var N=new c;h.lineSegmentTriangle=function(e,r,a,o,i,u,s){var E=N;t.clone(e,E.origin),t.subtract(r,e,E.direction),t.normalize(E.direction,E.direction);var c=h.rayTriangleParametric(E,a,o,i,u);if(!(!n(c)||c<0||c>t.distance(e,r)))return n(s)||(s=new t),t.multiplyByScalar(E.direction,c,s),t.add(E.origin,s,s)};var C={root0:0,root1:0};h.raySphere=function(t,e,r){if(r=f(t,e,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var I=new c;h.lineSegmentSphere=function(e,r,a,o){var i=I;t.clone(e,i.origin);var u=t.subtract(r,e,i.direction),s=t.magnitude(u);if(t.normalize(u,u),o=f(i,a,o),!(!n(o)||o.stop<0||o.start>s))return o.start=Math.max(o.start,0),o.stop=Math.min(o.stop,s),o};var p=new t,M=new t;h.rayEllipsoid=function(e,r){var n,a,i,u,s,E=r.oneOverRadii,c=t.multiplyComponents(E,e.origin,p),l=t.multiplyComponents(E,e.direction,M),f=t.magnitudeSquared(c),_=t.dot(c,l);if(f>1){if(_>=0)return;var R=_*_;if(n=f-1,a=t.magnitudeSquared(l),i=a*n,R<i)return;if(R>i){u=_*_-i,s=-_+Math.sqrt(u);var h=s/a,T=n/s;return h<T?new o(h,T):{start:T,stop:h}}var A=Math.sqrt(n/a);return new o(A,A)}return f<1?(n=f-1,a=t.magnitudeSquared(l),i=a*n,u=_*_-i,s=-_+Math.sqrt(u),new o(0,s/a)):_<0?(a=t.magnitudeSquared(l),new o(0,-_/a)):void 0};var O=new t,g=new t,y=new t,F=new t,L=new t,v=new u,P=new u,U=new u,D=new u,w=new u,B=new u,x=new u,G=new t,b=new t,z=new e;h.grazingAltitudeLocation=function(e,r){var a=e.origin,o=e.direction;if(!t.equals(a,t.ZERO)){var s=r.geodeticSurfaceNormal(a,O);if(t.dot(o,s)>=0)return a}var E=n(this.rayEllipsoid(e,r)),c=r.transformPositionToScaledSpace(o,O),l=t.normalize(c,c),f=t.mostOrthogonalAxis(c,F),_=t.normalize(t.cross(f,l,g),g),h=t.normalize(t.cross(l,_,y),y),T=v;T[0]=l.x,T[1]=l.y,T[2]=l.z,T[3]=_.x,T[4]=_.y,T[5]=_.z,T[6]=h.x,T[7]=h.y,T[8]=h.z;var A=u.transpose(T,P),d=u.fromScale(r.radii,U),S=u.fromScale(r.oneOverRadii,D),m=w;m[0]=0,m[1]=-o.z,m[2]=o.y,m[3]=o.z,m[4]=0,m[5]=-o.x,m[6]=-o.y,m[7]=o.x,m[8]=0;var N,C,I=u.multiply(u.multiply(A,S,B),m,B),p=u.multiply(u.multiply(I,d,x),T,x),M=u.multiplyByVector(I,a,L),H=R(p,t.negate(M,O),0,0,1),V=H.length;if(V>0){for(var X=t.clone(t.ZERO,b),q=Number.NEGATIVE_INFINITY,W=0;W<V;++W){N=u.multiplyByVector(d,u.multiplyByVector(T,H[W],G),G);var Y=t.normalize(t.subtract(N,a,F),F),K=t.dot(Y,o);K>q&&(q=K,X=t.clone(N,X))}var k=r.cartesianToCartographic(X,z);return q=i.clamp(q,0,1),C=t.magnitude(t.subtract(X,a,F))*Math.sqrt(1-q*q),C=E?-C:C,k.height=C,r.cartographicToCartesian(k,new t)}};var H=new t;return h.lineSegmentPlane=function(e,r,a,o){n(o)||(o=new t);var u=t.subtract(r,e,H),s=a.normal,E=t.dot(s,u);if(!(Math.abs(E)<i.EPSILON6)){var c=t.dot(s,e),l=-(a.distance+c)/E;if(!(l<0||l>1))return t.multiplyByScalar(u,l,o),t.add(e,o,o),o}},h.trianglePlaneIntersection=function(e,r,n,a){var o=a.normal,i=a.distance,u=t.dot(o,e)+i<0,s=t.dot(o,r)+i<0,E=t.dot(o,n)+i<0,c=0;c+=u?1:0,c+=s?1:0,c+=E?1:0;var l,f;if(1!==c&&2!==c||(l=new t,f=new t),1===c){if(u)return h.lineSegmentPlane(e,r,a,l),h.lineSegmentPlane(e,n,a,f),{positions:[e,r,n,l,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return h.lineSegmentPlane(r,n,a,l),h.lineSegmentPlane(r,e,a,f),{positions:[e,r,n,l,f],indices:[1,3,4,2,0,4,2,4,3]};if(E)return h.lineSegmentPlane(n,e,a,l),h.lineSegmentPlane(n,r,a,f),{positions:[e,r,n,l,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===c){if(!u)return h.lineSegmentPlane(r,e,a,l),h.lineSegmentPlane(n,e,a,f),{positions:[e,r,n,l,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return h.lineSegmentPlane(n,r,a,l),h.lineSegmentPlane(e,r,a,f),{positions:[e,r,n,l,f],indices:[2,0,4,2,4,3,1,3,4]};if(!E)return h.lineSegmentPlane(e,n,a,l),h.lineSegmentPlane(r,n,a,f),{positions:[e,r,n,l,f],indices:[0,1,4,0,4,3,2,3,4]}}},h}),define("Core/isArray",["./defined"],function(t){"use strict";var e=Array.isArray;return t(e)||(e=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,r,n,a,o,i){"use strict";function u(e,r){this.normal=t.clone(e),this.distance=r}u.fromPointNormal=function(e,n,a){var o=-t.dot(n,e);return r(a)?(t.clone(n,a.normal),a.distance=o,a):new u(n,o)};var s=new t;u.fromCartesian4=function(e,n){var a=t.fromCartesian4(e,s),o=e.w;return r(n)?(t.clone(a,n.normal),n.distance=o,n):new u(a,o)},u.getPointDistance=function(e,r){return t.dot(e.normal,r)+e.distance};var E=new t;u.projectPointOntoPlane=function(e,n,a){r(a)||(a=new t);var o=u.getPointDistance(e,n),i=t.multiplyByScalar(e.normal,o,E);return t.subtract(n,i,a)};var c=new t;return u.transform=function(e,r,n){return i.multiplyByPointAsVector(r,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,c),i.multiplyByPoint(r,c,c),u.fromPointNormal(c,s,n)},u.clone=function(e,n){return r(n)?(t.clone(e.normal,n.normal),n.distance=e.distance,n):new u(e.normal,e.distance)},u.equals=function(e,r){return e.distance===r.distance&&t.equals(e.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(t.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(t,e,r,n,a,o,i,u,s,E,c,l){"use strict";function f(t,e,r){var n=p;n.length=t;var a;if(e===r){for(a=0;a<t;a++)n[a]=e;return n}var o=r-e,i=o/t;for(a=0;a<t;a++){var u=e+a*i;n[a]=u}return n}function _(e,r,n,a,o,i,u,s){var E=a.scaleToGeodeticSurface(e,y),c=a.scaleToGeodeticSurface(r,F),l=R.numberOfPoints(e,r,n),_=a.cartesianToCartographic(E,M),h=a.cartesianToCartographic(c,O),T=f(l,o,i);L.setEndPoints(_,h);var A=L.surfaceDistance/l,d=s;_.height=o;var S=a.cartographicToCartesian(_,g);t.pack(S,u,d),d+=3;for(var m=1;m<l;m++){var N=L.interpolateUsingSurfaceDistance(m*A,O);N.height=T[m],S=a.cartographicToCartesian(N,g),t.pack(S,u,d),d+=3}return d}var R={};R.numberOfPoints=function(e,r,n){var a=t.distance(e,r);return Math.ceil(a/n)};var h=new e;R.extractHeights=function(t,e){for(var r=t.length,n=new Array(r),a=0;a<r;a++){var o=t[a];n[a]=e.cartesianToCartographic(o,h).height}return n};var T=new c,A=new t,d=new t,S=new l(t.UNIT_X,0),m=new t,N=new l(t.UNIT_X,0),C=new t,I=new t,p=[],M=new e,O=new e,g=new t,y=new t,F=new t,L=new i;return R.wrapLongitude=function(e,a){var o=[],i=[];if(n(e)&&e.length>0){a=r(a,c.IDENTITY);var s=c.inverseTransformation(a,T),E=c.multiplyByPoint(s,t.ZERO,A),f=t.normalize(c.multiplyByPointAsVector(s,t.UNIT_Y,d),d),_=l.fromPointNormal(E,f,S),R=t.normalize(c.multiplyByPointAsVector(s,t.UNIT_X,m),m),h=l.fromPointNormal(E,R,N),p=1;o.push(t.clone(e[0]));for(var M=o[0],O=e.length,g=1;g<O;++g){var y=e[g];if(l.getPointDistance(h,M)<0||l.getPointDistance(h,y)<0){var F=u.lineSegmentPlane(M,y,_,C);if(n(F)){var L=t.multiplyByScalar(f,5e-9,I);l.getPointDistance(_,M)<0&&t.negate(L,L),o.push(t.add(F,L,new t)),i.push(p+1),t.negate(L,L),o.push(t.add(F,L,new t)),p=1}}o.push(t.clone(e[g])),p++,M=y}i.push(p)}return{positions:o,lengths:i}},R.generateArc=function(e){n(e)||(e={});var a=e.positions,i=a.length,u=r(e.ellipsoid,o.WGS84),c=r(e.height,0),l=s(c);if(i<1)return[];if(1===i){var f=u.scaleToGeodeticSurface(a[0],y);if(0!==(c=l?c[0]:c)){var h=u.geodeticSurfaceNormal(f,g);t.multiplyByScalar(h,c,h),t.add(f,h,f)}return[f.x,f.y,f.z]}var T=e.minDistance;if(!n(T)){var A=r(e.granularity,E.RADIANS_PER_DEGREE);T=E.chordLength(A,u.maximumRadius)}var d,S=0;for(d=0;d<i-1;d++)S+=R.numberOfPoints(a[d],a[d+1],T);var m=3*(S+1),N=new Array(m),C=0;for(d=0;d<i-1;d++){C=_(a[d],a[d+1],T,u,l?c[d]:c,l?c[d+1]:c,N,C)}p.length=0;var I=a[i-1],O=u.cartesianToCartographic(I,M);O.height=l?c[i-1]:c;var F=u.cartographicToCartesian(O,g);return t.pack(F,N,m-3),N},R.generateCartesianArc=function(e){for(var r=R.generateArc(e),n=r.length/3,a=new Array(n),o=0;o<n;o++)a[o]=t.unpack(r,3*o);return a},R}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,r,n){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=n(new a({position:!0})),a.POSITION_AND_NORMAL=n(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=n(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=n(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=n(new a({position:!0,color:!0})),a.ALL=n(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,r,n){return n=t(n,0),r[n++]=e.position?1:0,r[n++]=e.normal?1:0,r[n++]=e.st?1:0,r[n++]=e.tangent?1:0,r[n++]=e.bitangent?1:0,r[n]=e.color?1:0,r},a.unpack=function(r,n,o){return n=t(n,0),e(o)||(o=new a),o.position=1===r[n++],o.normal=1===r[n++],o.st=1===r[n++],o.tangent=1===r[n++],o.bitangent=1===r[n++],o.color=1===r[n],o},a.clone=function(t,r){if(e(t))return e(r)||(r=new a),r.position=t.position,r.normal=t.normal,r.st=t.st,r.tangent=t.tangent,r.bitangent=t.bitangent,r.color=t.color,r},a}),define("Core/PolylineGeometry",["./arrayRemoveDuplicates","./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryType","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType","./VertexFormat"],function(t,e,r,n,a,o,i,u,s,E,c,l,f,_,R,h,T,A){"use strict";function d(t,e,r,a,o){var i=m;i.length=o;var u,s=r.red,E=r.green,c=r.blue,l=r.alpha,f=a.red,_=a.green,R=a.blue,h=a.alpha;if(n.equals(r,a)){for(u=0;u<o;u++)i[u]=n.clone(r);return i}var T=(f-s)/o,A=(_-E)/o,d=(R-c)/o,S=(h-l)/o;for(u=0;u<o;u++)i[u]=new n(s+u*T,E+u*A,c+u*d,l+u*S);return i}function S(t){t=o(t,o.EMPTY_OBJECT);var e=t.positions,a=t.colors,u=o(t.width,1),E=o(t.colorsPerVertex,!1);this._positions=e,this._colors=a,this._width=u,this._colorsPerVertex=E,this._vertexFormat=A.clone(o(t.vertexFormat,A.DEFAULT)),this._followSurface=o(t.followSurface,!0),this._granularity=o(t.granularity,R.RADIANS_PER_DEGREE),this._ellipsoid=s.clone(o(t.ellipsoid,s.WGS84)),this._workerName="createPolylineGeometry";var c=1+e.length*r.packedLength;c+=i(a)?1+a.length*n.packedLength:1,this.packedLength=c+s.packedLength+A.packedLength+4}var m=[];S.pack=function(t,e,a){a=o(a,0);var u,E=t._positions,c=E.length;for(e[a++]=c,u=0;u<c;++u,a+=r.packedLength)r.pack(E[u],e,a);var l=t._colors;for(c=i(l)?l.length:0,e[a++]=c,u=0;u<c;++u,a+=n.packedLength)n.pack(l[u],e,a);return s.pack(t._ellipsoid,e,a),a+=s.packedLength,A.pack(t._vertexFormat,e,a),a+=A.packedLength,e[a++]=t._width,e[a++]=t._colorsPerVertex?1:0,e[a++]=t._followSurface?1:0,e[a]=t._granularity,e};var N=s.clone(s.UNIT_SPHERE),C=new A,I={positions:void 0,colors:void 0,ellipsoid:N,vertexFormat:C,width:void 0,colorsPerVertex:void 0,followSurface:void 0,granularity:void 0};S.unpack=function(t,e,a){e=o(e,0);var u,E=t[e++],c=new Array(E);for(u=0;u<E;++u,e+=r.packedLength)c[u]=r.unpack(t,e);E=t[e++];var l=E>0?new Array(E):void 0;for(u=0;u<E;++u,e+=n.packedLength)l[u]=n.unpack(t,e);var f=s.unpack(t,e,N);e+=s.packedLength;var _=A.unpack(t,e,C);e+=A.packedLength;var R=t[e++],h=1===t[e++],T=1===t[e++],d=t[e];return i(a)?(a._positions=c,a._colors=l,a._ellipsoid=s.clone(f,a._ellipsoid),a._vertexFormat=A.clone(_,a._vertexFormat),a._width=R,a._colorsPerVertex=h,a._followSurface=T,a._granularity=d,a):(I.positions=c,I.colors=l,I.width=R,I.colorsPerVertex=h,I.followSurface=T,I.granularity=d,new S(I))};var p=new r,M=new r,O=new r,g=new r;return S.createGeometry=function(o){var u,s,A,S=o._width,N=o._vertexFormat,C=o._colors,I=o._colorsPerVertex,y=o._followSurface,F=o._granularity,L=o._ellipsoid,v=t(o._positions,r.equalsEpsilon),P=v.length;if(!(P<2||S<=0)){if(y){var U=h.extractHeights(v,L),D=R.chordLength(F,L.maximumRadius);if(i(C)){var w=1;for(u=0;u<P-1;++u)w+=h.numberOfPoints(v[u],v[u+1],D);var B=new Array(w),x=0;for(u=0;u<P-1;++u){var G=v[u],b=v[u+1],z=C[u],H=h.numberOfPoints(G,b,D);if(I&&u<w){var V=C[u+1],X=d(G,b,z,V,H),q=X.length;for(s=0;s<q;++s)B[x++]=X[s]}else for(s=0;s<H;++s)B[x++]=n.clone(z)}B[x]=n.clone(C[C.length-1]),C=B,m.length=0}v=h.generateCartesianArc({positions:v,minDistance:D,ellipsoid:L,height:U})}P=v.length;var W,Y=4*P-4,K=new Float64Array(3*Y),k=new Float64Array(3*Y),Z=new Float64Array(3*Y),j=new Float32Array(2*Y),Q=N.st?new Float32Array(2*Y):void 0,J=i(C)?new Uint8Array(4*Y):void 0,$=0,tt=0,et=0,rt=0;for(s=0;s<P;++s){0===s?(W=p,r.subtract(v[0],v[1],W),r.add(v[0],W,W)):W=v[s-1],r.clone(W,O),r.clone(v[s],M),s===P-1?(W=p,r.subtract(v[P-1],v[P-2],W),r.add(v[P-1],W,W)):W=v[s+1],r.clone(W,g);var nt,at;i(J)&&(nt=0===s||I?C[s]:C[s-1],s!==P-1&&(at=C[s]));var ot=0===s?2:0,it=s===P-1?2:4;for(A=ot;A<it;++A){r.pack(M,K,$),r.pack(O,k,$),r.pack(g,Z,$),$+=3;var ut=A-2<0?-1:1;if(j[tt++]=A%2*2-1,j[tt++]=ut*S,N.st&&(Q[et++]=s/(P-1),Q[et++]=Math.max(j[tt-2],0)),i(J)){var st=A<2?nt:at;J[rt++]=n.floatToByte(st.red),J[rt++]=n.floatToByte(st.green),J[rt++]=n.floatToByte(st.blue),J[rt++]=n.floatToByte(st.alpha)}}}var Et=new l;Et.position=new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:K}),Et.prevPosition=new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:k}),Et.nextPosition=new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:Z}),Et.expandAndWidth=new c({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:j}),N.st&&(Et.st=new c({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:Q})),i(J)&&(Et.color=new c({componentDatatype:a.UNSIGNED_BYTE,componentsPerAttribute:4,values:J,normalize:!0}));var ct=_.createTypedArray(Y,6*P-6),lt=0,ft=0,_t=P-1;for(s=0;s<_t;++s)ct[ft++]=lt,ct[ft++]=lt+2,ct[ft++]=lt+1,ct[ft++]=lt+1,ct[ft++]=lt+2,ct[ft++]=lt+3,lt+=4;return new E({attributes:Et,indices:ct,primitiveType:T.TRIANGLES,boundingSphere:e.fromPoints(v),geometryType:f.POLYLINES})}},S}),define("Workers/createPolylineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolylineGeometry"],function(t,e,r){"use strict";function n(n,a){return t(a)&&(n=r.unpack(n,a)),n._ellipsoid=e.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeGeometry.js index 68f64b6e..5b82c46d 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeGeometry.js @@ -222,10 +222,10 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:p,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,p=a.y,E=a.z,m=l*l*d*d,y=f*f*p*p,_=h*h*E*E,v=m+y+_,T=Math.sqrt(1/v),R=e.multiplyByScalar(n,T,i);if(v<s)return isFinite(T)?e.clone(R,c):void 0;var A=u.x,S=u.y,g=u.z,N=o;N.x=R.x*A*2,N.y=R.y*S*2,N.z=R.z*g*2;var O,w,I,x,M,C,P,D,U,L,b,F=(1-T)*e.magnitude(n)/(.5*e.magnitude(N)),B=0;do{F-=B,I=1/(1+F*A),x=1/(1+F*S),M=1/(1+F*g),C=I*I,P=x*x,D=M*M,U=C*I,L=P*x,b=D*M,O=m*C+y*P+_*D-1,w=m*U*A+y*L*S+_*b*g;B=O/(-2*w)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*I,c.y=f*x,c.z=h*M,c):new e(l*I,f*x,h*M)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var p=r(n)?n.oneOverRadii:f,E=r(n)?n.oneOverRadiiSquared:h,m=r(n)?n._centerToleranceSquared:d,y=o(t,p,E,m,c);if(r(y)){var _=e.multiplyComponents(y,E,s);_=e.normalize(_,_);var v=e.subtract(t,y,l),T=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=i.sign(e.dot(v,t))*e.magnitude(v);return r(a)?(a.longitude=T,a.latitude=R,a.height=A,a):new u(T,R,A)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var p=new e,E=new e,m=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,E);if(a(i)){var o=this.geodeticSurfaceNormal(i,p),u=e.subtract(n,i,m),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function a(e,r,a){if(n(e)){a=t(a,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,i));++u);if(u===o)return a&&r(e[0],e[e.length-1],i)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,i)||(l.push(c),s=c);return a&&l.length>1&&r(l[0],l[l.length-1],i)&&l.shift(),l}}var i=r.EPSILON10;return a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,p),o=Math.max(o,p)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,E=e.length;p<E;p++){var m=t.cartesianToCartographic(e[p]);o=Math.min(o,m.longitude),c=Math.max(c,m.longitude),h=Math.min(h,m.latitude),d=Math.max(d,m.latitude);var y=m.longitude>=0?m.longitude:m.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,E=c;E.height=a,E.longitude=p,E.latitude=f,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=h,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=p,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=f<0?f:h>0?h:0;for(var m=1;m<8;++m)E.longitude=-Math.PI+m*u.PI_OVER_TWO,s.contains(e,E)&&(o[l]=t.cartographicToCartesian(E,o[l]),l++);return 0===E.latitude&&(E.longitude=p,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,n,a){this.x=r(e,0),this.y=r(t,0),this.width=r(n,0),this.height=r(a,0)}s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.width,t[n]=e.height,t},s.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new s),n.x=e[t++],n.y=e[t++],n.width=e[t++],n.height=e[t],n},s.fromPoints=function(e,t){if(a(t)||(t=new s),!a(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var n=e.length,r=e[0].x,i=e[0].y,o=e[0].x,u=e[0].y,c=1;c<n;c++){var l=e[c],f=l.x,h=l.y;r=Math.min(f,r),o=Math.max(f,o),i=Math.min(h,i),u=Math.max(h,u)}return t.x=r,t.y=i,t.width=o-r,t.height=u-i,t};var c=new i,l=new t,f=new t;return s.fromRectangle=function(t,n,i){if(a(i)||(i=new s),!a(t))return i.x=0,i.y=0,i.width=0,i.height=0,i;n=r(n,c);var o=n.project(u.southwest(t,l)),h=n.project(u.northeast(t,f));return e.subtract(h,o,h),i.x=o.x,i.y=o.y,i.width=h.x,i.height=h.y,i},s.clone=function(e,t){if(a(e))return a(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new s(e.x,e.y,e.width,e.height)},s.union=function(e,t,n){a(n)||(n=new s);var r=Math.min(e.x,t.x),i=Math.min(e.y,t.y),o=Math.max(e.x+e.width,t.x+t.width),u=Math.max(e.y+e.height,t.y+t.height);return n.x=r,n.y=i,n.width=o-r,n.height=u-i,n},s.expand=function(e,t,n){n=s.clone(e,n);var r=t.x-n.x,a=t.y-n.y;return r>n.width?n.width=r:r<0&&(n.width-=r,n.x=t.x),a>n.height?n.height=a:a<0&&(n.height-=a,n.y=t.y),n},s.intersect=function(e,t){var n=e.x,r=e.y,a=t.x,i=t.y;return n>a+t.width||n+e.width<a||r+e.height<i||r>i+t.height?o.OUTSIDE:o.INTERSECTING},s.equals=function(e,t){return e===t||a(e)&&a(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.intersect=function(e){return s.intersect(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(E[n],p[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(E[i],p[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=p[a],h=E[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,m=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],v=(m-y)/2/_;d=v<0?-1/(-v+Math.sqrt(1+v*v)):1/(v+Math.sqrt(1+v*v)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++], -a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=n-u-f+d,E=2*(a-h),m=2*(i+l),y=2*(a+h),_=-n+u-f+d,v=2*(c-o),T=2*(i-l),R=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=p,t[1]=y,t[2]=T,t[3]=E,t[4]=_,t[5]=R,t[6]=m,t[7]=v,t[8]=A,t):new s(p,E,m,y,_,v,T,R,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,p=i*a+c*o*u,E=-c*a+i*o*u,m=-o,y=c*n,_=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=m,t[3]=f,t[4]=p,t[5]=y,t[6]=h,t[7]=E,t[8]=_,t):new s(l,f,h,d,p,E,m,y,_)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],E=[2,2,1],m=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,m),s.transpose(m,y),s.multiply(h,m,h),s.multiply(y,h,h),s.multiply(o,m,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,p,E,m){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(p,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(E,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(m,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,E=t.y*t.w,m=t.z*t.z,y=t.z*t.w,_=t.w*t.w,v=s-d-m+_,T=2*(c-y),R=2*(f+E),A=2*(c+y),S=-s+d-m+_,g=2*(p-h),N=2*(f-E),O=2*(p+h),w=-s-d+m+_;return r[0]=v*i,r[1]=A*i,r[2]=N*i,r[3]=0,r[4]=T*o,r[5]=S*o,r[6]=O*o,r[7]=0,r[8]=R*u,r[9]=g*u,r[10]=w*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,E=f.y,m=f.z,y=d.x,_=d.y,v=d.z,T=r.x,R=r.y,A=r.z,S=u*-T+s*-R+c*-A,g=y*-T+_*-R+v*-A,N=p*T+E*R+m*A;return a(n)?(n[0]=u,n[1]=y,n[2]=-p,n[3]=0,n[4]=s,n[5]=_,n[6]=-E,n[7]=0,n[8]=c,n[9]=v,n[10]=-m,n[11]=0,n[12]=S,n[13]=g,n[14]=N,n[15]=1,n):new l(u,s,c,S,y,_,v,g,-p,-E,-m,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,p=f,E=i+c,m=o+l,y=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=p,a[11]=0,a[12]=E,a[13]=m,a[14]=y,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var p=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),n};var E=new e;l.getMaximumScale=function(t){return l.getScale(t,E),e.maximumComponent(E)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],E=e[12],m=e[13],y=e[14],_=e[15],v=t[0],T=t[1],R=t[2],A=t[3],S=t[4],g=t[5],N=t[6],O=t[7],w=t[8],I=t[9],x=t[10],M=t[11],C=t[12],P=t[13],D=t[14],U=t[15],L=r*v+u*T+f*R+E*A,b=a*v+s*T+h*R+m*A,F=i*v+c*T+d*R+y*A,B=o*v+l*T+p*R+_*A,z=r*S+u*g+f*N+E*O,q=a*S+s*g+h*N+m*O,G=i*S+c*g+d*N+y*O,V=o*S+l*g+p*N+_*O,W=r*w+u*I+f*x+E*M,X=a*w+s*I+h*x+m*M,H=i*w+c*I+d*x+y*M,Y=o*w+l*I+p*x+_*M,k=r*C+u*P+f*D+E*U,Z=a*C+s*P+h*D+m*U,j=i*C+c*P+d*D+y*U,K=o*C+l*P+p*D+_*U;return n[0]=L,n[1]=b,n[2]=F,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],E=t[0],m=t[1],y=t[2],_=t[4],v=t[5],T=t[6],R=t[8],A=t[9],S=t[10],g=t[12],N=t[13],O=t[14],w=r*E+o*m+c*y,I=a*E+u*m+l*y,x=i*E+s*m+f*y,M=r*_+o*v+c*T,C=a*_+u*v+l*T,P=i*_+s*v+f*T,D=r*R+o*A+c*S,U=a*R+u*A+l*S,L=i*R+s*A+f*S,b=r*g+o*N+c*O+h,F=a*g+u*N+l*O+d,B=i*g+s*N+f*O+p;return n[0]=w,n[1]=I,n[2]=x,n[3]=0,n[4]=M,n[5]=C,n[6]=P,n[7]=0,n[8]=D,n[9]=U,n[10]=L,n[11]=0,n[12]=b,n[13]=F,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],E=t[3],m=t[4],y=t[5],_=t[6],v=t[7],T=t[8],R=r*h+o*d+c*p,A=a*h+u*d+l*p,S=i*h+s*d+f*p,g=r*E+o*m+c*y,N=a*E+u*m+l*y,O=i*E+s*m+f*y,w=r*_+o*v+c*T,I=a*_+u*v+l*T,x=i*_+s*v+f*T;return n[0]=R,n[1]=A,n[2]=S,n[3]=0,n[4]=g,n[5]=N,n[6]=O,n[7]=0,n[8]=w,n[9]=I,n[10]=x,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var m=new e;l.multiplyByUniformScale=function(e,t,n){return m.x=t,m.y=t,m.z=t,l.multiplyByScale(e,m,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,v=new t,T=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,v),T))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],E=e[2],m=e[6],R=e[10],A=e[14],S=e[3],g=e[7],N=e[11],O=e[15],w=R*O,I=A*N,x=m*O,M=A*g,C=m*N,P=R*g,D=E*O,U=A*S,L=E*N,b=R*S,F=E*g,B=m*S,z=w*h+M*d+C*p-(I*h+x*d+P*p),q=I*f+D*d+b*p-(w*f+U*d+L*p),G=x*f+U*h+F*p-(M*f+D*h+B*p),V=P*f+L*h+B*d-(C*f+b*h+F*d),W=I*a+x*i+P*o-(w*a+M*i+C*o),X=w*r+U*i+L*o-(I*r+D*i+b*o),H=M*r+D*a+B*o-(x*r+U*a+F*o),Y=C*r+b*a+F*i-(P*r+L*a+B*i);w=i*p,I=o*d,x=a*p,M=o*h,C=a*d,P=i*h,D=r*p,U=o*f,L=r*d,b=i*f,F=r*h,B=a*f;var k=w*g+M*N+C*O-(I*g+x*N+P*O),Z=I*S+D*N+b*O-(w*S+U*N+L*O),j=x*S+U*g+F*O-(M*S+D*g+B*O),K=P*S+L*g+B*N-(C*S+b*g+F*N),J=x*R+P*A+I*m-(C*A+w*m+M*R),Q=L*A+w*E+U*R-(D*R+b*A+I*E),$=D*m+B*A+M*E-(F*A+x*E+U*m),ee=F*R+C*E+b*m-(L*m+B*R+P*E),te=r*z+a*q+i*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-n*f-r*h-a*d,E=-i*f-o*h-u*d,m=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=E,t[14]=m,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,p=new e,E=new e,m=new e,y=new e,_=new e,v=new e,T=new e,R=new e,A=new e,S=new e,g=new e;h.fromPoints=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],v),o=e.clone(i,d),u=e.clone(i,p),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,y),f=e.clone(i,_),N=t.length;for(r=1;r<N;r++){e.clone(t[r],i);var O=i.x,w=i.y,I=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),w<u.y&&e.clone(i,u),w>l.y&&e.clone(i,l),I<s.z&&e.clone(i,s),I>f.z&&e.clone(i,f)}var x=e.magnitudeSquared(e.subtract(c,o,T)),M=e.magnitudeSquared(e.subtract(l,u,T)),C=e.magnitudeSquared(e.subtract(f,s,T)),P=o,D=c,U=x;M>U&&(U=M,P=u,D=l),C>U&&(U=C,P=s,D=f);var L=R;L.x=.5*(P.x+D.x),L.y=.5*(P.y+D.y),L.z=.5*(P.z+D.z);var b=e.magnitudeSquared(e.subtract(D,L,T)),F=Math.sqrt(b),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,T),.5,g),G=0;for(r=0;r<N;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,T));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,L,T));if(W>b){var X=Math.sqrt(W);F=.5*(F+X),b=F*F;var H=X-F;L.x=(F*L.x+H*i.x)/X,L.y=(F*L.y+H*i.y)/X,L.z=(F*L.z+H*i.z)/X}}return F<G?(e.clone(L,n.center),n.radius=F):(e.clone(q,n.center),n.radius=G),n};var N=new o,O=new e,w=new e,I=new t,x=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,N),f.southwest(t,I),I.height=i,f.northeast(t,x),x.height=o;var s=n.project(I,O),c=n.project(x,w),l=c.x-s.x,d=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+p*p);var E=u.center;return E.x=s.x+.5*l,E.y=s.y+.5*d,E.z=s.z+.5*p,u};var M=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,M);return h.fromPoints(s,u)},h.fromVertices=function(t,n,i,o){if(a(o)||(o=new h),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=v;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,p),f=e.clone(u,E),N=e.clone(u,m),O=e.clone(u,y),w=e.clone(u,_),I=t.length;for(s=0;s<I;s+=i){var x=t[s]+n.x,M=t[s+1]+n.y,C=t[s+2]+n.z;u.x=x,u.y=M,u.z=C,x<c.x&&e.clone(u,c),x>N.x&&e.clone(u,N),M<l.y&&e.clone(u,l),M>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>w.z&&e.clone(u,w)}var P=e.magnitudeSquared(e.subtract(N,c,T)),D=e.magnitudeSquared(e.subtract(O,l,T)),U=e.magnitudeSquared(e.subtract(w,f,T)),L=c,b=N,F=P;D>F&&(F=D,L=l,b=O),U>F&&(F=U,L=f,b=w);var B=R;B.x=.5*(L.x+b.x),B.y=.5*(L.y+b.y),B.z=.5*(L.z+b.z);var z=e.magnitudeSquared(e.subtract(b,B,T)),q=Math.sqrt(z),G=A;G.x=c.x,G.y=l.y,G.z=f.z;var V=S;V.x=N.x,V.y=O.y,V.z=w.z;var W=e.multiplyByScalar(e.add(G,V,T),.5,g),X=0;for(s=0;s<I;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,T));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,B,T));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;B.x=(q*B.x+Z*u.x)/k,B.y=(q*B.y+Z*u.y)/k,B.z=(q*B.z+Z*u.z)/k}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},h.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new h),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=v;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,d),s=e.clone(i,p),c=e.clone(i,E),l=e.clone(i,m),f=e.clone(i,y),N=e.clone(i,_),O=t.length;for(o=0;o<O;o+=3){var w=t[o]+n[o],I=t[o+1]+n[o+1],x=t[o+2]+n[o+2];i.x=w,i.y=I,i.z=x,w<u.x&&e.clone(i,u),w>l.x&&e.clone(i,l),I<s.y&&e.clone(i,s),I>f.y&&e.clone(i,f),x<c.z&&e.clone(i,c),x>N.z&&e.clone(i,N)}var M=e.magnitudeSquared(e.subtract(l,u,T)),C=e.magnitudeSquared(e.subtract(f,s,T)),P=e.magnitudeSquared(e.subtract(N,c,T)),D=u,U=l,L=M;C>L&&(L=C,D=s,U=f),P>L&&(L=P,D=c,U=N);var b=R;b.x=.5*(D.x+U.x),b.y=.5*(D.y+U.y),b.z=.5*(D.z+U.z);var F=e.magnitudeSquared(e.subtract(U,b,T)),B=Math.sqrt(F),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var q=S;q.x=l.x,q.y=f.y,q.z=N.z;var G=e.multiplyByScalar(e.add(z,q,T),.5,g),V=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,T));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,b,T));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var Y=H-B;b.x=(B*b.x+Y*i.x)/H,b.y=(B*b.y+Y*i.y)/H,b.z=(B*b.z+Y*i.z)/H}}return B<V?(e.clone(b,r.center),r.radius=B):(e.clone(G,r.center),r.radius=V),r},h.fromCornerPoints=function(t,n,r){a(r)||(r=new h);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},h.fromEllipsoid=function(t,n){return a(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;h.fromBoundingSpheres=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,D=new e,U=new e;h.fromOrientedBoundingBox=function(t,n){a(n)||(n=new h);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,D),u=c.getColumn(r,2,U);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},h.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new h);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,b=new e;h.union=function(t,n,r){a(r)||(r=new h);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r -;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(d,i,d),e.clone(d,r.center),r.radius=f,r};var F=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,F));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var B=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,B);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,V=new e,W=new e,X=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,X),d=e.negate(c,W),p=Y,E=p[0];e.add(s,l,E),e.add(E,c,E),E=p[1],e.add(s,l,E),e.add(E,d,E),E=p[2],e.add(s,f,E),e.add(E,d,E),E=p[3],e.add(s,f,E),e.add(E,c,E),e.negate(s,s),E=p[4],e.add(s,l,E),e.add(E,c,E),E=p[5],e.add(s,l,E),e.add(E,d,E),E=p[6],e.add(s,f,E),e.add(E,d,E),E=p[7],e.add(s,f,E),e.add(E,c,E);for(var m=p.length,y=0;y<m;++y){var _=p[y];e.add(o,_,_);var v=i.cartesianToCartographic(_,H);n.project(v,_)}a=h.fromPoints(p,a),o=a.center;var T=o.x,R=o.y,A=o.z;return o.x=A,o.y=T,o.z=R,a},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(R=!0,A=r(e[1]))}return R}function i(){return a()&&A}function o(){if(!t(S)&&(S=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(T.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(S=!0,g=r(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(T.userAgent);null!==e&&(N=!0,O=r(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(w)){w=!1;var e;"Microsoft Internet Explorer"===T.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(w=!0,I=r(e[1])):"Netscape"===T.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(w=!0,I=r(e[1]))}return w}function f(){return l()&&I}function h(){if(!t(x)){x=!1;var e=/ Edge\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(x=!0,M=r(e[1]))}return x}function d(){return h()&&M}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function E(){return t(D)||(D=/Windows/i.test(T.appVersion)),D}function m(){return p()&&P}function y(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(T.pointerEnabled)||T.pointerEnabled)),U}function _(){if(!t(b)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;b=t(n)&&""!==n,b&&(L=n)}return b}function v(){return _()?L:void 0}var T;T="undefined"!=typeof navigator?navigator:{};var R,A,S,g,N,O,w,I,x,M,C,P,D,U,L,b,F={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:m,isWindows:E,hardwareConcurrency:e(T.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:v};return F.supportsFullscreen=function(){return n.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,a){"use strict";var i={};i.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,n){return i.octDecodeInRange(e,t,255,n)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return i.octDecode(r,a,t)},i.octPack=function(e,t,n,r){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(n,o);return r.x=65536*s.x+a,r.y=65536*s.y+u,r},i.octUnpack=function(e,t,n,r){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,n),i.octDecode(o,s,r)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},i}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,n,r){"use strict";function a(n,a,s,c,l){r(l)||(l=new t);var f,h,d,p,E,m,y,_;r(a.z)?(f=t.subtract(s,a,i),h=t.subtract(c,a,o),d=t.subtract(n,a,u),p=t.dot(f,f),E=t.dot(f,h),m=t.dot(f,d),y=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,a,i),h=e.subtract(c,a,o),d=e.subtract(n,a,u),p=e.dot(f,f),E=e.dot(f,h),m=e.dot(f,d),y=e.dot(h,h),_=e.dot(h,d));var v=1/(p*y-E*E);return l.y=(y*m-E*_)*v,l.z=(p*_-E*m)*v,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,n){"use strict";function r(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}r.encode=function(e,t){n(t)||(t={high:0,low:0});var r;return e>=0?(r=65536*Math.floor(e/65536),t.high=r,t.low=e-r):(r=65536*Math.floor(-e/65536),t.high=-r,t.low=e+r),t};var a={high:0,low:0};r.fromCartesian=function(e,t){n(t)||(t=new r);var i=t.high,o=t.low;return r.encode(e.x,a),i.x=a.high,o.x=a.low,r.encode(e.y,a),i.y=a.high,o.y=a.low,r.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new r;return r.writeElements=function(e,t,n){r.fromCartesian(e,i);var a=i.high,o=i.low;t[n]=a.x,t[n+1]=a.y,t[n+2]=a.z,t[n+3]=o.x,t[n+4]=o.y,t[n+5]=o.z},r}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,E=o*c-u*s,m=u*c-d,y=4*p*m-E*E;if(y<0){var _,v,T;h*f>=l*d?(_=o,v=p,T=-2*u*p+o*E):(_=c,v=m,T=-c*E+2*s*m);var R=T<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-y);i=-T+A;var S=i/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),N=i===A?-g:-v/g;return a=v<=0?g+N:-T/(g*g+N*N+v),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var O=p,w=-2*u*p+o*E,I=m,x=-c*E+2*s*m,M=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*M,-w)/3);a=2*Math.sqrt(-O);var D=Math.cos(P);i=a*D;var U=a*(-D/2-C*Math.sin(P)),L=i+U>2*u?i-u:U-u,b=o,F=L/b;P=Math.abs(Math.atan2(c*M,-x)/3),a=2*Math.sqrt(-I),D=Math.cos(P),i=a*D,U=a*(-D/2-C*Math.sin(P));var B=-c,z=i+U<2*s?i+s:U+s,q=B/z,G=b*z,V=-L*z-b*B,W=L*B,X=(s*V-u*W)/(-u*V+s*G);return F<=X?F<=q?X<=q?[F,X,q]:[F,q,X]:[q,F,X]:F<=q?[X,F,q]:X<=q?[X,q,F]:[q,X,F]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var p=r.computeRealRoots(1,s,l);if(2===p.length){var E,m=p[0],y=p[1];if(m>=0&&y>=0){var _=Math.sqrt(m),v=Math.sqrt(y);return[h-v,h-_,h+_,h+v]}if(m>=0&&y<0)return E=Math.sqrt(m),[h-E,h+E];if(m<0&&y>=0)return E=Math.sqrt(y),[h-E,h+E]}return[]}if(d>0){var T=Math.sqrt(d),R=(s+d-c/T)/2,A=(s+d+c/T)/2,S=r.computeRealRoots(1,T,R),g=r.computeRealRoots(1,-T,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,E,m=d[0],y=a-m,_=y*y,v=t/2,T=y/2,R=_-4*o,A=_+4*Math.abs(o),S=c-4*m,g=c+4*Math.abs(m);if(m<0||R*g<S*A){var N=Math.sqrt(S);p=N/2,E=0===N?0:(t*T-i)/N}else{var O=Math.sqrt(R);p=0===O?0:(t*T-i)/O,E=O/2}var w,I;0===v&&0===p?(w=0,I=0):n.sign(v)===n.sign(p)?(w=v+p,I=m/w):(I=v-p,w=m/I);var x,M;0===T&&0===E?(x=0,M=0):n.sign(T)===n.sign(E)?(x=T+E,M=o/x):(M=T-E,x=o/M) -;var C=r.computeRealRoots(1,w,x),P=r.computeRealRoots(1,I,M);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,E=f(h,d,p,A);if(r(E))return a.start=E.root0,a.stop=E.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function p(t,n,r,a,i){var l,f=a*a,h=i*i,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,E=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),m=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),v=[];if(0===_&&0===y){if(l=s.computeRealRoots(p,E,m),0===l.length)return v;var T=l[0],R=Math.sqrt(Math.max(1-T*T,0));if(v.push(new e(a,i*T,i*-R)),v.push(new e(a,i*T,i*R)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));v.push(new e(a,i*A,i*-S)),v.push(new e(a,i*A,i*S))}return v}var g=_*_,N=y*y,O=p*p,w=_*y,I=O+N,x=2*(E*p+w),M=2*m*p+E*E-N+g,C=2*(m*E-w),P=m*m-g;if(0===I&&0===x&&0===M&&0===C)return v;l=c.computeRealRoots(I,x,M,C,P);var D=l.length;if(0===D)return v;for(var U=0;U<D;++U){var L,b=l[U],F=b*b,B=Math.max(1-F,0),z=Math.sqrt(B);L=o.sign(p)===o.sign(m)?d(p*F+m,E*b,o.EPSILON12):o.sign(m)===o.sign(E*b)?d(p*F,E*b+m,o.EPSILON12):d(p*F+E*b,m,o.EPSILON12);var q=d(y*b,_,o.EPSILON15),G=L*q;G<0?v.push(new e(a,i*b,i*z)):G>0?v.push(new e(a,i*b,i*-z)):0!==z?(v.push(new e(a,i*b,i*-z)),v.push(new e(a,i*b,i*z)),++U):v.push(new e(a,i*b,i*z))}return v}var E={};E.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var m=new e,y=new e,_=new e,v=new e,T=new e;E.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,E=e.subtract(a,r,m),R=e.subtract(i,r,y),A=e.cross(p,R,_),S=e.dot(E,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,r,v),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,E,T),(f=e.dot(p,c))<0||l+f>S)return;h=e.dot(R,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,r,v),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,E,T),(f=e.dot(p,c)*g)<0||l+f>1)return;h=e.dot(R,c)*g}return h},E.rayTriangle=function(t,n,a,i,o,u){var s=E.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;E.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=E.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};E.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;E.lineSegmentSphere=function(t,n,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var g=new e,N=new e;E.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var E=s/a,m=r/s;return E<m?new i(E,m):{start:m,stop:E}}var y=Math.sqrt(r/a);return new i(y,y)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var O=new e,w=new e,I=new e,x=new e,M=new e,C=new u,P=new u,D=new u,U=new u,L=new u,b=new u,F=new u,B=new e,z=new e,q=new t;E.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,x),d=e.normalize(e.cross(h,f,w),w),E=e.normalize(e.cross(f,d,I),I),m=C;m[0]=f.x,m[1]=f.y,m[2]=f.z,m[3]=d.x,m[4]=d.y,m[5]=d.z,m[6]=E.x,m[7]=E.y,m[8]=E.z;var y=u.transpose(m,P),_=u.fromScale(n.radii,D),v=u.fromScale(n.oneOverRadii,U),T=L;T[0]=0,T[1]=-i.z,T[2]=i.y,T[3]=i.z,T[4]=0,T[5]=-i.x,T[6]=-i.y,T[7]=i.x,T[8]=0;var R,A,S=u.multiply(u.multiply(y,v,b),T,b),g=u.multiply(u.multiply(S,_,F),m,F),N=u.multiplyByVector(S,a,M),G=p(g,e.negate(N,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){R=u.multiplyByVector(_,u.multiplyByVector(m,G[H],B),B);var Y=e.normalize(e.subtract(R,a,x),x),k=e.dot(Y,i);k>X&&(X=k,W=e.clone(R,W))}var Z=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(W,a,x))*Math.sqrt(1-X*X),A=c?-A:A,Z.height=A,n.cartographicToCartesian(Z,new e)}};var G=new e;return E.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},E.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return E.lineSegmentPlane(t,n,a,f),E.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return E.lineSegmentPlane(n,r,a,f),E.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return E.lineSegmentPlane(r,t,a,f),E.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return E.lineSegmentPlane(n,t,a,f),E.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return E.lineSegmentPlane(r,n,a,f),E.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return E.lineSegmentPlane(t,r,a,f),E.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},E}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";var r={};return r.calculateACMR=function(n){n=e(n,e.EMPTY_OBJECT);var r=n.indices,a=n.maximumIndex,i=e(n.cacheSize,24),o=r.length;if(!t(a)){a=0;for(var u=0,s=r[u];u<o;)s>a&&(a=s),++u,s=r[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var f=i+1,h=0;h<o;++h)f-c[r[h]]>i&&(c[r[h]]=f,++f);return(f-i+1)/(o/3)},r.tipsify=function(n){function r(e,t,n,r){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<r;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}n=e(n,e.EMPTY_OBJECT);var a,i=n.indices,o=n.maximumIndex,u=e(n.cacheSize,24),s=i.length,c=0,l=0,f=i[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=i[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var E=0;l<h;)p[i[l]].vertexTriangles.push(E),++p[i[l]].numLiveTriangles,p[i[l+1]].vertexTriangles.push(E),++p[i[l+1]].numLiveTriangles,p[i[l+2]].vertexTriangles.push(E),++p[i[l+2]].numLiveTriangles,++E,l+=3;var m=0,y=u+1;a=1;var _,v,T=[],R=[],A=0,S=[],g=s/3,N=[];for(d=0;d<g;d++)N[d]=!1;for(var O,w;-1!==m;){T=[],v=p[m],w=v.vertexTriangles.length;for(var I=0;I<w;++I)if(E=v.vertexTriangles[I],!N[E]){N[E]=!0,l=E+E+E;for(var x=0;x<3;++x)O=i[l],T.push(O),R.push(O),S[A]=O,++A,_=p[O],--_.numLiveTriangles,y-_.timeStamp>u&&(_.timeStamp=y,++y),++l}m=function(e,t,n,a,i,o,u){for(var s,c=-1,l=-1,f=0;f<n.length;){var h=n[f];a[h].numLiveTriangles&&(s=0,i-a[h].timeStamp+2*a[h].numLiveTriangles<=t&&(s=i-a[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?r(a,o,e,u):c}(i,u,T,p,y,R,c)}return S},r}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,p,E,m,y,_,v,T,R,A,S,g){"use strict";function N(e,t,n,r,a){e[t++]=n,e[t++]=r,e[t++]=r,e[t++]=a,e[t++]=a,e[t]=n}function O(e){for(var t=e.length,n=t/3*6,r=m.createTypedArray(t,n),a=0,i=0;i<t;i+=3,a+=6)N(r,a,e[i],e[i+1],e[i+2]);return r}function w(e){var t=e.length;if(t>=3){var n=6*(t-2),r=m.createTypedArray(t,n);N(r,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)N(r,a,e[i-1],e[i],e[i-2]);return r}return new Uint16Array}function I(e){if(e.length>0){for(var t=e.length-1,n=6*(t-1),r=m.createTypedArray(t,n),a=e[0],i=0,o=1;o<t;++o,i+=6)N(r,i,a,e[o],e[o+1]);return r}return new Uint16Array}function x(e){var t={};for(var n in e)if(e.hasOwnProperty(n)&&c(e[n])&&c(e[n].values)){var r=e[n];t[n]=new p({componentDatatype:r.componentDatatype,componentsPerAttribute:r.componentsPerAttribute,normalize:r.normalize,values:[]})}return t}function M(e,t,n){for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values))for(var a=t[r],i=0;i<a.componentsPerAttribute;++i)e[r].values.push(a.values[n*a.componentsPerAttribute+i])}function C(e,t){if(c(t))for(var n=t.values,r=n.length,i=0;i<r;i+=3)a.unpack(n,i,ie),R.multiplyByPoint(e,ie,ie),a.pack(ie,n,i)}function P(e,t){if(c(t))for(var n=t.values,r=n.length,i=0;i<r;i+=3)a.unpack(n,i,ie),T.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,n,i)}function D(e,t){var n,r=e.length,a={},i=e[0][t].attributes;for(n in i)if(i.hasOwnProperty(n)&&c(i[n])&&c(i[n].values)){for(var o=i[n],s=o.values.length,l=!0,f=1;f<r;++f){var h=e[f][t].attributes[n];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(a[n]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function U(e,t){var r,i,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),E=e[0][t].primitiveType,y=D(e,t);for(r in y)if(y.hasOwnProperty(r))for(s=y[r].values,u=0,i=0;i<h;++i)for(l=e[i][t].attributes[r].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var v=0;for(i=0;i<h;++i)v+=e[i][t].indices.length;var T=d.computeNumberOfVertices(new d({attributes:y,primitiveType:S.POINTS})),R=m.createTypedArray(T,v),A=0,g=0;for(i=0;i<h;++i){var N=e[i][t].indices,O=N.length;for(u=0;u<O;++u)R[A++]=g+N[u];g+=d.computeNumberOfVertices(e[i][t])}_=R}var w,I=new a,x=0;for(i=0;i<h;++i){if(w=e[i][t].boundingSphere,!c(w)){I=void 0;break}a.add(w.center,I,I)}if(c(I))for(a.divideByScalar(I,h,I),i=0;i<h;++i){w=e[i][t].boundingSphere;var M=a.magnitude(a.subtract(w.center,I,se))+w.radius;M>x&&(x=M)}return new d({attributes:y,indices:_,primitiveType:E,boundingSphere:c(I)?new n(I,x):void 0})}function L(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),n=m.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function b(e){var t=d.computeNumberOfVertices(e),n=m.createTypedArray(t,3*(t-2));n[0]=1,n[1]=0,n[2]=2;for(var r=3,a=3;a<t;++a)n[r++]=a-1,n[r++]=0,n[r++]=a;return e.indices=n,e.primitiveType=S.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),n=m.createTypedArray(t,3*(t-2));n[0]=0,n[1]=1,n[2]=2,t>3&&(n[3]=0,n[4]=2,n[5]=3);for(var r=6,a=3;a<t-1;a+=2)n[r++]=a,n[r++]=a-1,n[r++]=a+1,a+2<t&&(n[r++]=a,n[r++]=a+1,n[r++]=a+2);return e.indices=n,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),n=m.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function z(e){var t=d.computeNumberOfVertices(e),n=m.createTypedArray(t,2*(t-1));n[0]=0,n[1]=1;for(var r=2,a=2;a<t;++a)n[r++]=a-1,n[r++]=a;return e.indices=n,e.primitiveType=S.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),n=m.createTypedArray(t,2*t);n[0]=0,n[1]=1;for(var r=2,a=2;a<t;++a)n[r++]=a-1,n[r++]=a;return n[r++]=t-1,n[r]=0,e.indices=n,e.primitiveType=S.LINES,e}function G(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return b(e);case S.TRIANGLE_STRIP:return F(e);case S.TRIANGLES:return L(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return q(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<v.EPSILON6&&(e.y=t?-v.EPSILON6:v.EPSILON6)}function W(e,t,n){if(0!==e.y&&0!==t.y&&0!==n.y)return V(e,e.y<0),V(t,t.y<0),void V(n,n.y<0);var r,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(n.y);r=a>i?a>o?v.sign(e.y):v.sign(n.y):i>o?v.sign(t.y):v.sign(n.y);var u=r<0;V(e,u),V(t,u),V(n,u)}function X(e,t,n,r){a.add(e,a.multiplyByScalar(a.subtract(t,e,Re),e.y/(e.y-t.y),Re),n),a.clone(n,r),V(n,!0),V(r,!1)}function H(e,t,n){if(!(e.x>=0||t.x>=0||n.x>=0)){W(e,t,n);var r=e.y<0,a=t.y<0,i=n.y<0,o=0;o+=r?1:0,o+=a?1:0,o+=i?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,r?(X(e,t,Ae,ge),X(e,n,Se,Ne),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(X(t,n,Ae,ge),X(t,e,Se,Ne),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(X(n,e,Ae,ge),X(n,t,Se,Ne),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,r?a?i||(X(n,e,Ae,ge),X(n,t,Se,Ne),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(X(t,n,Ae,ge),X(t,e,Se,Ne),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(X(e,t,Ae,ge),X(e,n,Se,Ne),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=n,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=ge,s[6]=Ne,s.length=7),Oe}}function Y(e,t){var r=e.attributes;if(0!==r.position.values.length){for(var a in r)if(r.hasOwnProperty(a)&&c(r[a])&&c(r[a].values)){var i=r[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=d.computeNumberOfVertices(e);return e.indices=m.createTypedArray(o,e.indices),t&&(e.boundingSphere=n.fromVertices(r.position.values)),e}}function k(e){var t=e.attributes,n={};for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values)){var a=t[r];n[r]=new p({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new d({attributes:n,indices:[],primitiveType:e.primitiveType})}function Z(e,t,n){var r=c(e.geometry.boundingSphere);t=Y(t,r),n=Y(n,r),c(n)&&!c(t)?e.geometry=n:!c(n)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=n,e.geometry=void 0)}function j(e,n,i,o,u,s,l,f,h,d,p,E){if(c(s)||c(l)||c(f)||c(h)||c(d)){var m=a.fromArray(u,3*e,we),y=a.fromArray(u,3*n,Ie),_=a.fromArray(u,3*i,xe),v=t(o,m,y,_,Me);if(c(s)){var T=a.fromArray(s,3*e,we),R=a.fromArray(s,3*n,Ie),A=a.fromArray(s,3*i,xe);a.multiplyByScalar(T,v.x,T),a.multiplyByScalar(R,v.y,R),a.multiplyByScalar(A,v.z,A);var S=a.add(T,R,T);a.add(S,A,S),a.normalize(S,S),a.pack(S,p.normal.values,3*E)}if(c(d)){var g=a.fromArray(d,3*e,we),N=a.fromArray(d,3*n,Ie),O=a.fromArray(d,3*i,xe);a.multiplyByScalar(g,v.x,g),a.multiplyByScalar(N,v.y,N),a.multiplyByScalar(O,v.z,O);var w;a.equals(g,a.ZERO)&&a.equals(N,a.ZERO)&&a.equals(O,a.ZERO)?(w=we,w.x=0,w.y=0,w.z=0):(w=a.add(g,N,g),a.add(w,O,w),a.normalize(w,w)),a.pack(w,p.extrudeDirection.values,3*E)}if(c(l)){var I=a.fromArray(l,3*e,we),x=a.fromArray(l,3*n,Ie),M=a.fromArray(l,3*i,xe);a.multiplyByScalar(I,v.x,I),a.multiplyByScalar(x,v.y,x),a.multiplyByScalar(M,v.z,M);var C=a.add(I,x,I);a.add(C,M,C),a.normalize(C,C),a.pack(C,p.tangent.values,3*E)}if(c(f)){var P=a.fromArray(f,3*e,we),D=a.fromArray(f,3*n,Ie),U=a.fromArray(f,3*i,xe);a.multiplyByScalar(P,v.x,P),a.multiplyByScalar(D,v.y,D),a.multiplyByScalar(U,v.z,U);var L=a.add(P,D,P);a.add(L,U,L),a.normalize(L,L),a.pack(L,p.bitangent.values,3*E)}if(c(h)){var b=r.fromArray(h,2*e,Ce),F=r.fromArray(h,2*n,Pe),B=r.fromArray(h,2*i,De);r.multiplyByScalar(b,v.x,b),r.multiplyByScalar(F,v.y,F),r.multiplyByScalar(B,v.z,B);var z=r.add(b,F,b);r.add(z,B,z),r.pack(z,p.st.values,2*E)}}}function K(e,t,n,r,a,i){var o=e.position.values.length/3;if(-1!==a){var u=r[a],s=n[u];return-1===s?(n[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function J(e){var t,n,r,i,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,E=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,m=u.indices,y=k(u),_=k(u),v=[];v.length=l.length/3;var T=[];for(T.length=l.length/3,o=0;o<v.length;++o)v[o]=-1,T[o]=-1;var R=m.length;for(o=0;o<R;o+=3){var A=m[o],S=m[o+1],g=m[o+2],N=a.fromArray(l,3*A),O=a.fromArray(l,3*S),w=a.fromArray(l,3*g),I=H(N,O,w);if(c(I)&&I.positions.length>3)for(var x=I.positions,M=I.indices,C=M.length,P=0;P<C;++P){var D=M[P],U=x[D];U.y<0?(t=_.attributes,n=_.indices,r=v):(t=y.attributes,n=y.indices,r=T),i=K(t,n,r,m,D<3?o+D:-1,U),j(A,S,g,U,l,f,d,h,p,E,t,i)}else c(I)&&(N=I.positions[0],O=I.positions[1],w=I.positions[2]),N.y<0?(t=_.attributes,n=_.indices,r=v):(t=y.attributes,n=y.indices,r=T),i=K(t,n,r,m,o,N),j(A,S,g,N,l,f,d,h,p,E,t,i),i=K(t,n,r,m,o+1,O),j(A,S,g,O,l,f,d,h,p,E,t,i),i=K(t,n,r,m,o+2,w),j(A,S,g,w,l,f,d,h,p,E,t,i)}Z(e,_,y)}function Q(e){var t,n=e.geometry,r=n.attributes,i=r.position.values,o=n.indices,u=k(n),s=k(n),l=o.length,f=[];f.length=i.length/3;var h=[];for(h.length=i.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],E=a.fromArray(i,3*d,we),m=a.fromArray(i,3*p,Ie);Math.abs(E.y)<v.EPSILON6&&(E.y<0?E.y=-v.EPSILON6:E.y=v.EPSILON6),Math.abs(m.y)<v.EPSILON6&&(m.y<0?m.y=-v.EPSILON6:m.y=v.EPSILON6);var y=u.attributes,T=u.indices,R=h,A=s.attributes,S=s.indices,g=f,N=_.lineSegmentPlane(E,m,Ue,xe);if(c(N)){var O=a.multiplyByScalar(a.UNIT_Y,5*v.EPSILON9,Le);E.y<0&&(a.negate(O,O),y=s.attributes,T=s.indices,R=f,A=u.attributes,S=u.indices,g=h);var w=a.add(N,O,be);K(y,T,R,o,t,E),K(y,T,R,o,-1,w),a.negate(O,O),a.add(N,O,w),K(A,S,g,o,-1,w),K(A,S,g,o,t+1,m)}else{var I,x,M;E.y<0?(I=s.attributes,x=s.indices,M=f):(I=u.attributes,x=u.indices,M=h),K(I,x,M,o,t,E),K(I,x,M,o,t+1,m)}}Z(e,s,u)}function $(e){for(var t=e.attributes,n=t.position.values,r=t.prevPosition.values,i=t.nextPosition.values,o=n.length,u=0;u<o;u+=3){var s=a.unpack(n,u,ze);if(!(s.x>0)){var c=a.unpack(r,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(r[u]=n[u-3],r[u+1]=n[u-2],r[u+2]=n[u-1]):a.pack(s,r,u));var l=a.unpack(i,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=n[u+3],i[u+1]=n[u+4],i[u+2]=n[u+5]):a.pack(s,i,u))}}}function ee(e){var t,n,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,E=c(s.color)?s.color.values:void 0,m=k(u),y=k(u),T=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,S=t+2,g=a.fromArray(l,3*A,ze),N=a.fromArray(l,3*S,qe);if(Math.abs(g.y)<ke)for(g.y=ke*(N.y<0?-1:1),l[3*t+1]=g.y,l[3*(t+1)+1]=g.y,n=3*A;n<3*A+12;n+=3)f[n]=l[3*t],f[n+1]=l[3*t+1],f[n+2]=l[3*t+2];if(Math.abs(N.y)<ke)for(N.y=ke*(g.y<0?-1:1),l[3*(t+2)+1]=N.y,l[3*(t+3)+1]=N.y,n=3*A;n<3*A+12;n+=3)h[n]=l[3*(t+2)],h[n+1]=l[3*(t+2)+1],h[n+2]=l[3*(t+2)+2];var O=m.attributes,w=m.indices,I=y.attributes,x=y.indices,M=_.lineSegmentPlane(g,N,Ue,Ve);if(c(M)){T=!0;var C=a.multiplyByScalar(a.UNIT_Y,Ye,We);g.y<0&&(a.negate(C,C),O=y.attributes,w=y.indices,I=m.attributes,x=m.indices);var P=a.add(M,C,Xe);O.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),O.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),O.prevPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),a.negate(C,C),a.add(M,C,P),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),I.nextPosition.values.push(h[3*S],h[3*S+1],h[3*S+2]),I.nextPosition.values.push(h[3*S+3],h[3*S+4],h[3*S+5]);var D=r.fromArray(d,2*A,Fe),U=Math.abs(D.y);O.expandAndWidth.values.push(-1,U,1,U),O.expandAndWidth.values.push(-1,-U,1,-U),I.expandAndWidth.values.push(-1,U,1,U),I.expandAndWidth.values.push(-1,-U,1,-U);var L=a.magnitudeSquared(a.subtract(M,g,Ge));if(L/=a.magnitudeSquared(a.subtract(N,g,Ge)),c(E)){var b=i.fromArray(E,4*A,He),F=i.fromArray(E,4*S,He),B=v.lerp(b.x,F.x,L),z=v.lerp(b.y,F.y,L),q=v.lerp(b.z,F.z,L),G=v.lerp(b.w,F.w,L);for(n=4*A;n<4*A+8;++n)O.color.values.push(E[n]);for(O.color.values.push(B,z,q,G),O.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),n=4*S;n<4*S+8;++n)I.color.values.push(E[n])}if(c(p)){var V=r.fromArray(p,2*A,Fe),W=r.fromArray(p,2*(t+3),Be),X=v.lerp(V.x,W.x,L);for(n=2*A;n<2*A+4;++n)O.st.values.push(p[n]);for(O.st.values.push(X,V.y),O.st.values.push(X,W.y),I.st.values.push(X,V.y),I.st.values.push(X,W.y),n=2*S;n<2*S+4;++n)I.st.values.push(p[n])}o=O.position.values.length/3-4,w.push(o,o+2,o+1),w.push(o+1,o+2,o+3),o=I.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3)}else{var H,Y;for(g.y<0?(H=y.attributes,Y=y.indices):(H=m.attributes,Y=m.indices),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),n=3*t;n<3*t+12;++n)H.prevPosition.values.push(f[n]),H.nextPosition.values.push(h[n]);for(n=2*t;n<2*t+8;++n)H.expandAndWidth.values.push(d[n]),c(p)&&H.st.values.push(p[n]);if(c(E))for(n=4*t;n<4*t+16;++n)H.color.values.push(E[n]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}T&&($(y),$(m)),Z(e,y,m)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=O(t);break;case S.TRIANGLE_STRIP:e.indices=w(t);break;case S.TRIANGLE_FAN:e.indices=I(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,r){t=s(t,"normal"),r=s(r,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=a[h],l[f++]=a[h+1],l[f++]=a[h+2],l[f++]=a[h]+i[h]*r,l[f++]=a[h+1]+i[h+1]*r,l[f++]=a[h+2]+i[h+2]*r;var E,m=e.boundingSphere;return c(m)&&(E=new n(m.center,m.radius+r)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:E})},te.createAttributeLocations=function(e){var t,n=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],r=e.attributes,a={},i=0,o=n.length;for(t=0;t<o;++t){var u=n[t];c(r[u])&&(a[u]=i++)}for(var s in r)r.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),n=e.indices;if(c(n)){for(var r=new Int32Array(t),a=0;a<t;a++)r[a]=-1;for(var i,o=n,s=o.length,l=m.createTypedArray(t,s),f=0,h=0,p=0;f<s;)i=r[o[f]],-1!==i?l[h]=i:(i=o[f],r[i]=p,l[h]=p,++p),++f,++h;e.indices=l;var E=e.attributes;for(var y in E)if(E.hasOwnProperty(y)&&c(E[y])&&c(E[y].values)){for(var _=E[y],v=_.values,T=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);T<t;){var S=r[T];if(-1!==S)for(var g=0;g<R;g++)A[R*S+g]=v[R*T+g];++T}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var n=e.indices;if(e.primitiveType===S.TRIANGLES&&c(n)){for(var r=n.length,a=0,i=0;i<r;i++)n[i]>a&&(a=n[i]);e.indices=g.tipsify({indices:n,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],n=d.computeNumberOfVertices(e);if(c(e.indices)&&n>=v.SIXTY_FOUR_KILOBYTES){var r,a=[],i=[],o=0,u=x(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?r=3:e.primitiveType===S.LINES?r=2:e.primitiveType===S.POINTS&&(r=1);for(var f=0;f<l;f+=r){for(var h=0;h<r;++h){var p=s[f+h],E=a[p];c(E)||(E=o++,a[p]=E,M(u,e.attributes,p)),i.push(E)}o+r>=v.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=x(e.attributes))}0!==i.length&&t.push(new d({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var ne=new a,re=new o;te.projectTo2D=function(e,t,n,r,i){var o=e.attributes[t];i=c(i)?i:new h;for(var s=i.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,E=0;E<l.length;E+=3){var m=a.fromArray(l,E,ne),y=s.cartesianToCartographic(m,re),_=i.project(y,ne);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[n]=o,e.attributes[r]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,n,r){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var h=a.componentsPerAttribute;return e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ie=new a,oe=new R,ue=new T;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var r=e.geometry.attributes;C(t,r.position),C(t,r.prevPosition),C(t,r.nextPosition),(c(r.normal)||c(r.tangent)||c(r.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,r.normal),P(ue,r.tangent),P(ue,r.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=n.transform(a,t,a)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],n=[],r=e.length,a=0;a<r;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&n.push(i)}var o=[];return t.length>0&&o.push(U(t,"geometry")),n.length>0&&(o.push(U(n,"westHemisphereGeometry")),o.push(U(n,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,fe=new a,he=new a;te.computeNormal=function(e){var t,n=e.indices,r=e.attributes,i=r.position.values,o=r.position.values.length/3,s=n.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=n[t],E=n[t+1],m=n[t+2],y=3*d,_=3*E,T=3*m;le.x=i[y],le.y=i[y+1],le.z=i[y+2],fe.x=i[_],fe.y=i[_+1],fe.z=i[_+2],he.x=i[T],he.y=i[T+1],he.z=i[T+2],c[d].count++,c[E].count++,c[m].count++,a.subtract(fe,le,fe),a.subtract(he,le,he),l[h]=a.cross(fe,he,new a),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[n[t]];var S=A.indexOffset+A.currentCount;f[S]=h,A.currentCount++,A=c[n[t+1]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,A=c[n[t+2]],S=A.indexOffset+A.currentCount,f[S]=h,A.currentCount++,h++}var g=new Float32Array(3*o);for(t=0;t<o;t++){var N=3*t;if(A=c[t],a.clone(a.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)a.add(ce,l[f[A.indexOffset+h]],ce);a.equalsEpsilon(a.ZERO,ce,v.EPSILON10)&&a.clone(l[f[A.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,v.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),g[N]=ce.x,g[N+1]=ce.y,g[N+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:g}),e};var de=new a,pe=new a,Ee=new a;te.computeTangentAndBitangent=function(e){var t,n=(e.attributes,e.indices),r=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=n.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var E=n[t],m=n[t+1],y=n[t+2];f=3*E,h=3*m,d=3*y;var _=2*E,v=2*m,T=2*y,R=r[f],A=r[f+1],S=r[f+2],g=o[_],N=o[_+1],O=o[v+1]-N,w=o[T+1]-N,I=1/((o[v]-g)*w-(o[T]-g)*O),x=(w*(r[h]-R)-O*(r[d]-R))*I,M=(w*(r[h+1]-A)-O*(r[d+1]-A))*I,C=(w*(r[h+2]-S)-O*(r[d+2]-S))*I;l[f]+=x,l[f+1]+=M,l[f+2]+=C,l[h]+=x,l[h+1]+=M,l[h+2]+=C,l[d]+=x,l[d+1]+=M,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var U=a.fromArray(i,f,de),L=a.fromArray(l,f,Ee),b=a.dot(U,L);a.multiplyByScalar(U,b,pe),a.normalize(a.subtract(L,pe,L),L),P[f]=L.x,P[h]=L.y,P[d]=L.z,a.normalize(a.cross(U,L,L),L),D[f]=L.x,D[h]=L.y,D[d]=L.z}return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var me=new r,ye=new a,_e=new a,ve=new a,Te=new r;te.compressVertices=function(t){var n,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),f=0;for(n=0;n<i;++n)a.fromArray(s,3*n,ye),a.equals(ye,a.ZERO)?f+=2:(Te=e.octEncodeInRange(ye,65535,Te),l[f++]=Te.x,l[f++]=Te.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}), -delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,E=c(h),m=c(d);if(!E&&!m)return t;var y,_,v,T,R=t.attributes.tangent,A=t.attributes.bitangent,S=c(R),g=c(A);E&&(y=h.values),m&&(_=d.values),S&&(v=R.values),g&&(T=A.values),i=(E?y.length:_.length)/(E?3:2);var N=i,O=m&&E?2:1;O+=S||g?1:0,N*=O;var w=new Float32Array(N),I=0;for(n=0;n<i;++n){m&&(r.fromArray(_,2*n,me),w[I++]=e.compressTextureCoordinates(me));var x=3*n;E&&c(v)&&c(T)?(a.fromArray(y,x,ye),a.fromArray(v,x,_e),a.fromArray(T,x,ve),e.octPack(ye,_e,ve,me),w[I++]=me.x,w[I++]=me.y):(E&&(a.fromArray(y,x,ye),w[I++]=e.octEncodeFloat(ye)),S&&(a.fromArray(v,x,ye),w[I++]=e.octEncodeFloat(ye)),g&&(a.fromArray(T,x,ye),w[I++]=e.octEncodeFloat(ye)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:w}),E&&delete t.attributes.normal,m&&delete t.attributes.st,g&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var Re=new a,Ae=new a,Se=new a,ge=new a,Ne=new a,Oe={positions:new Array(7),indices:new Array(9)},we=new a,Ie=new a,xe=new a,Me=new a,Ce=new r,Pe=new r,De=new r,Ue=A.fromPointNormal(a.ZERO,a.UNIT_Y),Le=new a,be=new a,Fe=new r,Be=new r,ze=new a,qe=new a,Ge=new a,Ve=new a,We=new a,Xe=new a,He=new i,Ye=5*v.EPSILON9,ke=v.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,r=t.boundingSphere;if(c(r)){if(r.center.x-r.radius>0||n.intersectPlane(r,A.ORIGIN_ZX_PLANE)!==y.INTERSECTING)return e}if(t.geometryType!==E.NONE)switch(t.geometryType){case E.POLYLINES:ee(e);break;case E.TRIANGLES:J(e);break;case E.LINES:Q(e)}else G(t),t.primitiveType===S.TRIANGLES?J(e):t.primitiveType===S.LINES&&Q(e);return e},te}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(a[n])||(a[n]=!0,console.warn(e(r,n)))}var a={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,f,h,d,p,E,m;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=h=e[0],f=d=e[1];for(var y=a;y<o;y+=a)p=e[y],E=e[y+1],p<l&&(l=p),E<f&&(f=E),p>h&&(h=p),E>d&&(d=E);m=Math.max(h-l,d-f)}return r(u,c,a,l,f,m),c}function t(e,t,n,r,a){var i,o;if(a===I(e,t,n,r)>0)for(i=t;i<n;i+=r)o=N(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=N(i,e[i],e[i+1],o);return o&&v(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!v(r,r.next)&&0!==_(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var p,E,m=e;e.prev!==e.next;)if(p=e.prev,E=e.next,f?i(e,c,l,f):a(e))t.push(p.i/s),t.push(e.i/s),t.push(E.i/s),O(e),e=E.next,m=E.next;else if((e=E)===m){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(_(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(m(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&_(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(_(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,f=p(u,s,t,n,r),h=p(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&m(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&m(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!v(a,i)&&T(a,r,r.next,i)&&A(a,i)&&A(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),O(r),O(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&y(s,c)){var l=g(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,f=o<u-1?r[o+1]*i:e.length,h=t(e,s,f,i,!1),h===h.next&&(h.steiner=!0),d.push(E(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=g(t,e);n(r,r.next)}}function f(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&m(i<f?a:o,i,l,f,i<f?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var a=e;do{null===a.z&&(a.z=p(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,d(a)}function d(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function p(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function E(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function m(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function y(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!R(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function _(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function v(e,t){return e.x===t.x&&e.y===t.y}function T(e,t,n,r){return!!(v(e,t)&&v(n,r)||v(e,r)&&v(n,t))||_(e,t,n)>0!=_(e,t,r)>0&&_(n,r,e)>0!=_(n,r,t)>0}function R(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&T(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function S(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function g(e,t){var n=new w(e.i,e.x,e.y),r=new w(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function N(e,t,n,r){var a=new w(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function w(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function I(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(I(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(I(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,p=r[u+2]*n;f+=Math.abs((e[h]-e[p])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[p+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";var d=new n,p=new n,E={};E.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},E.computeWindingOrder2D=function(e){return E.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},E.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var m=new n,y=new n,_=new n,v=new n,T=new n,R=new n,A=new n;return E.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),p=t.length,E=new Array(3*p),S=0;for(h=0;h<p;h++){var g=t[h];E[S++]=g.x,E[S++]=g.y,E[S++]=g.z}for(var N=[],O={},w=e.maximumRadius,I=l.chordLength(u,w),x=I*I;d.length>0;){var M,C,P=d.pop(),D=d.pop(),U=d.pop(),L=n.fromArray(E,3*U,m),b=n.fromArray(E,3*D,y),F=n.fromArray(E,3*P,_),B=n.multiplyByScalar(n.normalize(L,v),w,v),z=n.multiplyByScalar(n.normalize(b,T),w,T),q=n.multiplyByScalar(n.normalize(F,R),w,R),G=n.magnitudeSquared(n.subtract(B,z,A)),V=n.magnitudeSquared(n.subtract(z,q,A)),W=n.magnitudeSquared(n.subtract(q,B,A)),X=Math.max(G,V,W);X>x?G===X?(M=Math.min(U,D)+" "+Math.max(U,D),h=O[M],o(h)||(C=n.add(L,b,A),n.multiplyByScalar(C,.5,C),E.push(C.x,C.y,C.z),h=E.length/3-1,O[M]=h),d.push(U,h,P),d.push(h,D,P)):V===X?(M=Math.min(D,P)+" "+Math.max(D,P),h=O[M],o(h)||(C=n.add(b,F,A),n.multiplyByScalar(C,.5,C),E.push(C.x,C.y,C.z),h=E.length/3-1,O[M]=h),d.push(D,h,U),d.push(h,P,U)):W===X&&(M=Math.min(P,U)+" "+Math.max(P,U),h=O[M],o(h)||(C=n.add(F,L,A),n.multiplyByScalar(C,.5,C),E.push(C.x,C.y,C.z),h=E.length/3-1,O[M]=h),d.push(P,h,D),d.push(h,U,D)):(N.push(U),N.push(D),N.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:E})},indices:N,primitiveType:f.TRIANGLES})},E.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=d,c=p;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},E}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],p=d.x,E=d.y,m=d.z;a=Math.min(p,a),s=Math.max(p,s),o=Math.min(E,o),c=Math.max(E,c),u=Math.min(m,u),l=Math.max(m,l)}var y=n.minimum;y.x=a,y.y=o,y.z=u;var _=n.maximum;_.x=s,_.y=c,_.z=l;var v=e.add(y,_,n.center);return e.multiplyByScalar(v,.5,v),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return p(e)}function a(e){return p(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return E(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=y,E(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return m(2,arguments),e(t,function(t){function u(e){E(e)}function s(e){p(e)}var c,l,f,h,d,p,E,m,_,v;if(_=t.length>>>0,c=Math.max(0,Math.min(n,_)),f=[],l=_-c+1,h=[],d=o(),c)for(m=d.progress,E=function(e){h.push(e),--l||(p=E=y,d.reject(h))},p=function(e){f.push(e),--c||(p=E=y,d.resolve(f))},v=0;v<_;++v)v in t&&e(t[v],s,u,m);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return m(1,arguments),h(e,_).then(t,n,r)}function f(){return h(arguments,_)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=T.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},v.apply(t,r)})}function p(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function E(e,t){for(var n,r=0;n=e[r++];)n(t)}function m(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function y(){}function _(e){return e}var v,T,R;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},T=[].slice,v=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,p,E,m,y;if("%%"==e)return"%";for(var _=!1,v="",T=!1,R=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":v=" ";break;case"+":v="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":T=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(y),_,c,f,T,A);case"c":return u(String.fromCharCode(+y),_,c,f,T);case"b":return o(y,2,R,_,c,f,T);case"o":return o(y,8,R,_,c,f,T);case"x":return o(y,16,R,_,c,f,T);case"X":return o(y,16,R,_,c,f,T).toUpperCase();case"u":return o(y,10,R,_,c,f,T);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),p=d<0?"-":v,y=p+a(String(Math.abs(d)),f,"0",!1),i(y,p,_,c,T);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,p=d<0?"-":v,E=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],m=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=p+Math.abs(d)[E](f),i(y,p,_,c,T)[m]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return E.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var n=E.leapSeconds,r=t(n,_,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){E.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}E.addSeconds(e,a,e)}function h(e,n){_.julianDate=e;var r=E.leapSeconds,a=t(r,_,l);if(a<0&&(a=~a),0===a)return E.addSeconds(e,-r[0].offset,n);if(a>=r.length)return E.addSeconds(e,-r[a-1].offset,n);var i=E.secondsDifference(r[a].julianDate,e);return 0===i?E.addSeconds(e,-r[a].offset,n):i<=1?void 0:E.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function p(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function E(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var m=new i,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,v=/^(\d{4})$/,T=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,w=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;E.fromGregorianDate=function(e,t){var n=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new E(n[0],n[1],c.UTC)},E.fromDate=function(e,t){var n=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new E(n[0],n[1],c.UTC)},E.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,m=0,_=0,g=0,I=u[0],x=u[1];if(null!==(u=I.match(S)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(T)))n=+u[1],s=+u[2];else if(null!==(u=I.match(v)))n=+u[1];else{var M;if(null!==(u=I.match(R)))n=+u[1],M=+u[2],i=o(n);else if(null!==(u=I.match(A))){n=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(n,0,4));M=7*C+P-D.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(M),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var U;if(r(x)){u=x.match(w),null!==u?(h=+u[1],m=+u[2],_=+u[3],g=1e3*+(u[4]||0),U=5):(u=x.match(O),null!==u?(h=+u[1],m=+u[2],_=60*+(u[3]||0),U=4):null!==(u=x.match(N))&&(h=+u[1],m=60*+(u[2]||0),U=3));var L=u[U],b=+u[U+1],F=+(u[U+2]||0);switch(L){case"+":h-=b,m-=F;break;case"-":h+=b,m+=F;break;case"Z":break;default:m+=new Date(Date.UTC(n,s-1,l,h,m)).getTimezoneOffset()}}var B=60===_;for(B&&_--;m>=60;)m-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:y[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:y[s-1];for(;m<0;)m+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:y[s-1],l+=a;var z=p(n,s,l,h,m,_,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new E(z[0],z[1],c.UTC),B&&E.addSeconds(t,1,t),t},E.now=function(e){return E.fromDate(new Date,e)};var I=new E(0,0,c.TAI);return E.toGregorianDate=function(e,t){var n=!1,a=h(e,I);r(a)||(E.addSeconds(e,-1,I),a=h(I,I),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var m=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,v=u-_*s.SECONDS_PER_HOUR,T=v/s.SECONDS_PER_MINUTE|0;v-=T*s.SECONDS_PER_MINUTE;var R=0|v,A=(v-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),n&&(R+=1),r(t)?(t.year=y,t.month=m,t.day=p,t.hour=_,t.minute=T,t.second=R,t.millisecond=A,t.isLeapSecond=n,t):new i(y,m,p,_,T,R,A,n)},E.toDate=function(e){var t=E.toGregorianDate(e,m),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},E.toIso8601=function(t,n){var a,i=E.toGregorianDate(t,m);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},E.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new E(e.dayNumber,e.secondsOfDay,c.TAI)},E.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(E.secondsDifference(e,t))<=n},E.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},E.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},E.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},E.computeTaiMinusUtc=function(e){_.julianDate=e;var n=E.leapSeconds,r=t(n,_,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},E.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},E.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},E.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},E.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},E.lessThan=function(e,t){return E.compare(e,t)<0},E.lessThanOrEquals=function(e,t){return E.compare(e,t)<=0},E.greaterThan=function(e,t){return E.compare(e,t)>0},E.greaterThanOrEquals=function(e,t){return E.compare(e,t)>=0},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return E.toIso8601(this)},E.leapSeconds=[new u(new E(2441317,43210,c.TAI),10),new u(new E(2441499,43211,c.TAI),11),new u(new E(2441683,43212,c.TAI),12),new u(new E(2442048,43213,c.TAI),13),new u(new E(2442413,43214,c.TAI),14),new u(new E(2442778,43215,c.TAI),15),new u(new E(2443144,43216,c.TAI),16),new u(new E(2443509,43217,c.TAI),17),new u(new E(2443874,43218,c.TAI),18),new u(new E(2444239,43219,c.TAI),19),new u(new E(2444786,43220,c.TAI),20),new u(new E(2445151,43221,c.TAI),21),new u(new E(2445516,43222,c.TAI),22),new u(new E(2446247,43223,c.TAI),23),new u(new E(2447161,43224,c.TAI),24),new u(new E(2447892,43225,c.TAI),25),new u(new E(2448257,43226,c.TAI),26),new u(new E(2448804,43227,c.TAI),27),new u(new E(2449169,43228,c.TAI),28),new u(new E(2449534,43229,c.TAI),29),new u(new E(2450083,43230,c.TAI),30),new u(new E(2450630,43231,c.TAI),31),new u(new E(2451179,43232,c.TAI),32),new u(new E(2453736,43233,c.TAI),33),new u(new E(2454832,43234,c.TAI),34),new u(new E(2456109,43235,c.TAI),35),new u(new E(2457204,43236,c.TAI),36),new u(new E(2457754,43237,c.TAI),37)],E}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){ -"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return g[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function p(e){return function(t){e.state!==s.CANCELLED&&(--T.numberOfActiveRequests,--g[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function E(e){return function(t){e.state!==s.CANCELLED&&(++T.numberOfFailedRequests,--T.numberOfActiveRequests,--g[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function m(e){var t=d(e);return e.state=s.ACTIVE,S.push(e),++T.numberOfActiveRequests,++T.numberOfActiveRequestsEver,++g[e.serverKey],e.requestFunction().then(p(e)).otherwise(E(e)),t}function y(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++T.numberOfCancelledRequests,e.deferred.reject(),t&&(--T.numberOfActiveRequests,--g[e.serverKey],++T.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function _(){T.numberOfAttemptedRequests=0,T.numberOfCancelledRequests=0,T.numberOfCancelledActiveRequests=0}function v(){l.debugShowStatistics&&(T.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+T.numberOfAttemptedRequests),T.numberOfActiveRequests>0&&console.log("Number of active requests: "+T.numberOfActiveRequests),T.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+T.numberOfCancelledRequests),T.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+T.numberOfCancelledActiveRequests),T.numberOfFailedRequests>0&&console.log("Number of failed requests: "+T.numberOfFailedRequests),_())}var T={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},R=20,A=new i({comparator:c});A.maximumLength=R,A.reserve(R);var S=[],g={},N="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return T}},priorityHeapLength:{get:function(){return R},set:function(e){if(e<R)for(;A.length>e;){var t=A.pop();y(t)}R=e,A.maximumLength=e,A.reserve(e)}}}),l.update=function(){var e,t,n=0,r=S.length;for(e=0;e<r;++e)t=S[e],t.cancelled&&y(t),t.state===s.ACTIVE?n>0&&(S[e-n]=t):++n;S.length-=n;var a=A.internalArray,i=A.length;for(e=0;e<i;++e)f(a[e]);A.resort();for(var o=Math.max(l.maximumRequests-S.length,0),u=0;u<o&&A.length>0;)t=A.pop(),t.cancelled?y(t):!t.throttleByServer||h(t.serverKey)?(m(t),++u):y(t);v()},l.getServerKey=function(t){var n=new e(t).resolve(N);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=g[a];return r(i)||(g[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++T.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return m(e);if(!(S.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=A.insert(e);if(r(t)){if(t===e)return;y(t)}return d(e)}},l.clearForSpecs=function(){for(;A.length>0;){y(A.pop())}for(var e=S.length,t=0;t<e;++t)y(S[t]);S.length=0,g={},T.numberOfAttemptedRequests=0,T.numberOfActiveRequests=0,T.numberOfCancelledRequests=0,T.numberOfCancelledActiveRequests=0,T.numberOfFailedRequests=0,T.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return g[e]},l.requestHeap=A,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;a=n(a,t.url);var d=r(t.request)?t.request:new i;return d.url=a,d.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function d(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return h(a,i);case"blob":var o=h(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var p=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=p.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(i))for(var E in i)i.hasOwnProperty(E)&&h.setRequestHeader(E,i[E]);r(t)&&(h.responseType=t);var m=!1;return"string"==typeof e&&(m=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!m||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(a),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))p(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){p(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||p<0||E<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var m=e._samples=n.samples,y=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=E,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var _,v=e._addNewLeapSeconds,T=0,R=m.length;T<R;T+=e._columnCount){var A=m[T+a],S=m[T+E],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,S,f.TAI);if(y.push(N),v){if(S!==_&&r(_)){var O=o.leapSeconds,w=t(O,N,d);if(w<0){var I=new u(N,S);O.splice(~w,0,I)}}_=S}}}function E(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function m(e,t,n){return t+e*(n-t)}function y(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return E(e,n,a,s,u),u;if(r.equals(l))return E(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,p=n[h+e._ut1MinusUtcSecondsColumn],y=n[d+e._ut1MinusUtcSecondsColumn],_=y-p;if(_>.5||_<-.5){var v=n[h+e._taiMinusUtcSecondsColumn],T=n[d+e._taiMinusUtcSecondsColumn];v!==T&&(l.equals(r)?p=y:y-=T-v)}return u.xPoleWander=m(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=m(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=m(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=m(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=m(f,p,y),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),p=!r(h),E=p||o.greaterThanOrEquals(h,e);if(d&&E)return s=u,!p&&h.equals(e)&&++s,l=s+1,y(this,i,this._samples,e,s,l,n),n}var m=t(i,e,o.compare,this._dateColumn);return m>=0?(m<i.length-1&&i[m+1].equals(e)&&++m,s=m,l=m):(l=~m,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=p.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,p=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=p,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var p,E,m=i-s*this._stepSizeDays,y=this._work,_=this._denominators,v=this._coef,T=this._xTable;for(p=0;p<=u;++p)y[p]=m-T[p];for(p=0;p<=u;++p){for(v[p]=1,E=0;E<=u;++E)E!==p&&(v[p]*=y[E]);v[p]*=_[p];var R=3*(s+p);n.x+=v[p]*d[R++],n.y+=v[p]*d[R++],n.s+=v[p]*d[R]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],E=h+d+p;if(E>0)n=Math.sqrt(E+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var m=l,y=0;d>h&&(y=1),p>h&&p>d&&(y=2);var _=m[y],v=m[_];n=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(v,v)]+1);var T=f;T[y]=.5*n,n=.5/n,c=(e[u.getElementIndex(v,_)]-e[u.getElementIndex(_,v)])*n,T[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*n,T[v]=(e[u.getElementIndex(v,y)]+e[u.getElementIndex(y,v)])*n,a=-T[0],i=-T[1],o=-T[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,p=new s,E=new s;s.fromHeadingPitchRoll=function(t,n){return E=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(p,E,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var m=new e,y=new e,_=new s,v=new s,T=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,T),s.conjugate(T,T);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),_),s.multiply(_,T,_),_.w<0&&s.negate(_,_),s.computeAxis(_,m);var u=s.computeAngle(_);r[o]=m.x*u,r[o+1]=m.y*u,r[o+2]=m.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(n,4*i,v),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,v,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,p=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=p,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,n,r){return R=s.multiplyByScalar(t,n,R),r=s.multiplyByScalar(e,1-n,r),s.add(R,r,r)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=A=s.negate(t,A)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),g=s.multiplyByScalar(i,Math.sin(n*u),g),r=s.add(S,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var N=new e,O=new e,w=new s,I=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,w);s.multiply(i,r,I);var o=s.log(I,N);s.multiply(i,t,I);var u=s.log(I,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,w),s.multiply(n,w,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,w),u=s.slerp(n,r,a,I);return s.slerp(o,u,2*a*(1-a),i)};for(var x=new s,M=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var b=L+1,F=2*b+1;C[L]=1/(b*F),P[L]=b/F}return C[7]=M/136,P[7]=8*M/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,U[f]=(C[f]*l-P[f])*o;var h=a*n*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),p=s.multiplyByScalar(e,d,x);return s.multiplyByScalar(t,h,r),s.add(p,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,w),u=s.fastSlerp(n,r,a,I);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,p,E,m,y,_,v){"use strict";var T={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,O=new n,w=new n;T.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=R[e][t],i=e+t;return u(S[i])?r=S[i]:(r=function(r,i,s){if(u(s)||(s=new y),E.equalsEpsilon(r.x,0,E.EPSILON14)&&E.equalsEpsilon(r.y,0,E.EPSILON14)){var c=E.sign(r.z);n.unpack(A[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(A[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(A[a],0,w),"east"!==a&&"west"!==a&&n.multiplyByScalar(w,c,w)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),N=g[e],O=g[t],w=g[a]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=w.x,s[9]=w.y,s[10]=w.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},S[i]=r),r},T.eastNorthUpToFixedFrame=T.localFrameToFixedFrameGenerator("east","north"),T.northEastDownToFixedFrame=T.localFrameToFixedFrameGenerator("north","east"),T.northUpEastToFixedFrame=T.localFrameToFixedFrameGenerator("north","up"),T.northWestUpToFixedFrame=T.localFrameToFixedFrameGenerator("north","west");var I=new _,x=new n(1,1,1),M=new y;T.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,T.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,I),s=y.fromTranslationQuaternionRotationScale(n.ZERO,u,x,M);return i=a(e,r,i),y.multiply(i,s,i)};var C=new y,P=new m;T.headingPitchRollQuaternion=function(e,t,n,r,a){var i=T.headingPitchRollToFixedFrame(e,t,n,r,C),o=y.getRotation(i,P);return _.fromRotationMatrix(o,a)};var D=E.TWO_PI/86400,U=new p;T.computeTemeToPseudoFixedMatrix=function(e,t){U=p.addSeconds(e,-p.computeTaiMinusUtc(e),U);var n,r=U.dayNumber,a=U.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/v.DAYS_PER_JULIAN_CENTURY:(i-.5)/v.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*D%E.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*v.SECONDS_PER_DAY)%v.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new m(h,d,0,-d,h,0,0,0,1)},T.iau2006XysData=new h,T.earthOrientationParameters=c.NONE;T.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=T.iau2006XysData.preload(n,r,a,i),u=T.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},T.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new m);var n=T.computeFixedToIcrfMatrix(e,t);if(u(n))return m.transpose(n,t)};var L=new d(0,0,0),b=new l(0,0,0,0,0,0),F=new m,B=new m;T.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new m);var n=T.earthOrientationParameters.compute(e,b);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=T.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=m.fromRotationZ(-i.s,B),h=m.multiply(l,f,F),d=e.dayNumber,y=e.secondsOfDay-p.computeTaiMinusUtc(e)+n.ut1MinusUtc,_=d-2451545,R=y/v.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*E.TWO_PI;var S=m.fromRotationZ(A,B),g=m.multiply(h,S,F),N=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),w=Math.sin(n.xPoleWander),I=Math.sin(n.yPoleWander),x=r-2451545+a/v.SECONDS_PER_DAY;x/=36525;var M=-47e-6*x*E.RADIANS_PER_DEGREE/3600,C=Math.cos(M),P=Math.sin(M),D=B;return D[0]=N*C,D[1]=N*P,D[2]=w,D[3]=-O*P+I*w*C,D[4]=O*C+I*w*P,D[5]=-I*N,D[6]=-I*P-O*w*C,D[7]=I*C-O*w*P,D[8]=O*N,m.multiply(g,D,t)}}};var z=new r;T.pointToWindowCoordinates=function(e,t,n,r){return r=T.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},T.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return y.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,V=new n;T.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,E.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new m),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var W=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new m,Z=new y,j=new y;return T.basisTo2D=function(e,t,r){var a=y.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=T.eastNorthUpToFixedFrame(a,i,Z),c=y.inverseTransformation(s,j),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,r);return y.multiply(W,f,r),y.setTranslation(r,u,r),r},T.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=T.eastNorthUpToFixedFrame(t,a,Z),o=y.inverseTransformation(i,j),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,Z);return y.multiply(W,o,r),y.multiply(c,r,r),r},T}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function p(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,E)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,E));var i=n.fromCartesian4(l.getColumn(r,2,E));this._plane=f.fromPointNormal(e,i)}var E=new r;o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var m=new e;p.fromPoints=function(t,n){return new p(e.fromPoints(t,m).center,n)};var y=new h,_=new n;p.prototype.projectPointOntoPlane=function(e,r){var a=y;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,_);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,_)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},p.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},p.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=y;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,_);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,_));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},p.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var v=new n;return p.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=v,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},p}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,a=(n-r)/n,i=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,i),f=s*o,h=f*f,d=1-h,p=Math.sqrt(d),E=t/4,m=E*E,y=m*E,_=m*m,v=1+E-3*m/4+5*y/4-175*_/64,T=1-E+15*m/8-35*y/8,R=1-3*E+35*m/4,A=1-5*E,S=v*l-T*Math.sin(2*l)*E/2-R*Math.sin(4*l)*m/16-A*Math.sin(6*l)*y/48-5*Math.sin(8*l)*_/512,g=e._constants;g.a=n,g.b=r,g.f=a,g.cosineHeading=i,g.sineHeading=o,g.tanU=u,g.cosineU=s,g.sineU=c,g.sigma=l,g.sineAlpha=f,g.sineSquaredAlpha=h,g.cosineSquaredAlpha=d,g.cosineAlpha=p,g.u2Over4=E,g.u4Over16=m,g.u6Over64=y,g.u8Over256=_,g.a0=v,g.a1=T,g.a2=R,g.a3=A,g.distanceRatio=S} -function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,a,i,o){var u=c(e,n);return(1-u)*e*t*(r+u*a*(o+u*i*(2*o*o-1)))}function f(e,t,n,r,a,i,o){var s,c,f,h,d,p=(t-n)/t,E=i-r,m=Math.atan((1-p)*Math.tan(a)),y=Math.atan((1-p)*Math.tan(o)),_=Math.cos(m),v=Math.sin(m),T=Math.cos(y),R=Math.sin(y),A=_*T,S=_*R,g=v*R,N=v*T,O=E,w=u.TWO_PI,I=Math.cos(O),x=Math.sin(O);do{I=Math.cos(O),x=Math.sin(O);var M=S-N*I;f=Math.sqrt(T*T*x*x+M*M),c=g+A*I,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=A*x/f,h=1-C*C),w=O,d=c-2*g/h,isNaN(d)&&(d=0),O=E+l(p,C,h,s,f,c,d)}while(Math.abs(O-w)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),D=1+P*(4096+P*(P*(320-175*P)-768))/16384,U=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,b=U*f*(d+U*(c*(2*L-1)-U*d*(4*f*f-3)*(4*L-3)/6)/4),F=n*D*(s-b),B=Math.atan2(T*x,S-N*I),z=Math.atan2(_*x,S*I-N);e._distance=F,e._startHeading=B,e._endHeading=z,e._uSquared=P}function h(n,r,a,i){e.normalize(i.cartographicToCartesian(r,E),p),e.normalize(i.cartographicToCartesian(a,E),E);f(n,i.maximumRadius,i.minimumRadius,r.longitude,r.latitude,a.longitude,a.latitude),n._start=t.clone(r,n._start),n._end=t.clone(a,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,i){var u=r(i,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(n)&&h(this,e,n,u)}var p=new e,E=new e;return i(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,i=r.distanceRatio+e/r.b,o=Math.cos(2*i),u=Math.cos(4*i),s=Math.cos(6*i),c=Math.sin(2*i),f=Math.sin(4*i),h=Math.sin(6*i),d=Math.sin(8*i),p=i*i,E=i*p,m=r.u8Over256,y=r.u2Over4,_=r.u6Over64,v=r.u4Over16,T=2*E*m*o/3+i*(1-y+7*v/4-15*_/4+579*m/64-(v-15*_/4+187*m/16)*o-(5*_/4-115*m/16)*u-29*m*s/16)+(y/2-v+71*_/32-85*m/16)*c+(5*v/16-5*_/4+383*m/96)*f-p*((_-11*m/2)*c+5*m*f/2)+(29*_/96-29*m/16)*h+539*m*d/1536,R=Math.asin(Math.sin(T)*r.cosineAlpha),A=Math.atan(r.a/r.b*Math.tan(R));T-=r.sigma;var S=Math.cos(2*r.sigma+T),g=Math.sin(T),N=Math.cos(T),O=r.cosineU*N,w=r.sineU*g,I=Math.atan2(g*r.sineHeading,O-w*r.cosineHeading),x=I-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,T,g,N,S);return a(n)?(n.longitude=this._start.longitude+x,n.latitude=A,n.height=0,n):new t(this._start.longitude+x,A,0)},d}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=g;r.length=e;var a;if(t===n){for(a=0;a<e;a++)r[a]=t;return r}var i=n-t,o=i/e;for(a=0;a<e;a++){var u=t+a*o;r[a]=u}return r}function d(t,n,r,a,i,o,u,s){var c=a.scaleToGeodeticSurface(t,I),l=a.scaleToGeodeticSurface(n,x),f=p.numberOfPoints(t,n,r),d=a.cartesianToCartographic(c,N),E=a.cartesianToCartographic(l,O),m=h(f,i,o);M.setEndPoints(d,E);var y=M.surfaceDistance/f,_=s;d.height=i;var v=a.cartographicToCartesian(d,w);e.pack(v,u,_),_+=3;for(var T=1;T<f;T++){var R=M.interpolateUsingSurfaceDistance(T*y,O);R.height=m[T],v=a.cartographicToCartesian(R,w),e.pack(v,u,_),_+=3}return _}var p={};p.numberOfPoints=function(t,n,r){var a=e.distance(t,n);return Math.ceil(a/r)};var E=new t;p.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),a=0;a<n;a++){var i=e[a];r[a]=t.cartesianToCartographic(i,E).height}return r};var m=new l,y=new e,_=new e,v=new f(e.UNIT_X,0),T=new e,R=new f(e.UNIT_X,0),A=new e,S=new e,g=[],N=new t,O=new t,w=new e,I=new e,x=new e,M=new o;return p.wrapLongitude=function(t,a){var i=[],o=[];if(r(t)&&t.length>0){a=n(a,l.IDENTITY);var s=l.inverseTransformation(a,m),c=l.multiplyByPoint(s,e.ZERO,y),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,_),_),d=f.fromPointNormal(c,h,v),p=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,T),T),E=f.fromPointNormal(c,p,R),g=1;i.push(e.clone(t[0]));for(var N=i[0],O=t.length,w=1;w<O;++w){var I=t[w];if(f.getPointDistance(E,N)<0||f.getPointDistance(E,I)<0){var x=u.lineSegmentPlane(N,I,d,A);if(r(x)){var M=e.multiplyByScalar(h,5e-9,S);f.getPointDistance(d,N)<0&&e.negate(M,M),i.push(e.add(x,M,new e)),o.push(g+1),e.negate(M,M),i.push(e.add(x,M,new e)),g=1}}i.push(e.clone(t[w])),g++,N=I}o.push(g)}return{positions:i,lengths:o}},p.generateArc=function(t){r(t)||(t={});var a=t.positions,o=a.length,u=n(t.ellipsoid,i.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(a[0],I);if(0!==(l=f?l[0]:l)){var E=u.geodeticSurfaceNormal(h,w);e.multiplyByScalar(E,l,E),e.add(h,E,h)}return[h.x,h.y,h.z]}var m=t.minDistance;if(!r(m)){var y=n(t.granularity,c.RADIANS_PER_DEGREE);m=c.chordLength(y,u.maximumRadius)}var _,v=0;for(_=0;_<o-1;_++)v+=p.numberOfPoints(a[_],a[_+1],m);var T=3*(v+1),R=new Array(T),A=0;for(_=0;_<o-1;_++){A=d(a[_],a[_+1],m,u,f?l[_]:l,f?l[_+1]:l,R,A)}g.length=0;var S=a[o-1],O=u.cartesianToCartographic(S,N);O.height=f?l[o-1]:l;var x=u.cartographicToCartesian(O,w);return e.pack(x,R,T-3),R},p.generateCartesianArc=function(t){for(var n=p.generateArc(t),r=n.length/3,a=new Array(r),i=0;i<r;i++)a[i]=e.unpack(n,3*i);return a},p}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var a=e[r];D=t.cartesianToCartographic(a,D),n[r]=D.height,e[r]=t.scaleToGeodeticSurface(a,a)}return n}function d(e,n,r,a){var i,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/a),l=new Array(c);if(n===r){for(i=0;i<c;i++)l[i]=n;return l.push(r),l}var f=r-n,h=f/c;for(i=1;i<c;i++){var d=n+i*h;l[i]=d}return l[0]=n,l.push(r),l}function p(n,r,a,o){var u=new i(a,o),s=u.projectPointOntoPlane(t.add(a,n,U),U),c=u.projectPointOntoPlane(t.add(a,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function E(e,n,r,a,i,o,c,l){var h=G,d=V;F=f.eastNorthUpToFixedFrame(e,i,F),h=s.multiplyByPointAsVector(F,b,h),h=t.normalize(h,h);var E=p(h,n,e,i);z=u.fromRotationZ(E,z),W.z=o,F=s.multiplyTransformation(F,s.fromRotationTranslation(z,W,B),F);var m=q;m[0]=c;for(var y=0;y<l;y++)for(var _=0;_<r.length;_+=3)d=t.fromArray(r,_,d),d=u.multiplyByVector(m,d,d),d=s.multiplyByPoint(F,d,d),a.push(d.x,d.y,d.z);return a}function m(e,n,r,a,i,o,u){for(var s=0;s<e.length;s+=3){a=E(t.fromArray(e,s,X),n,r,a,i,o[s/3],u,1)}return a}function y(e,t){var n=e.length,r=new Array(6*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-i,l=u.y-o;r[a++]=c,r[a++]=0,r[a++]=l,r[a++]=c,r[a++]=0,r[a++]=l}return u=e[0],r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o,r}function _(e,t){for(var n=e.length,r=new Array(3*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[a++]=e[u].x-i,r[a++]=0,r[a++]=e[u].y-o;return r}function v(e,n,r,i,s,c,f,h,d,p){var m,y=t.angleBetween(t.subtract(n,e,M),t.subtract(r,e,C)),_=i===a.BEVELED?0:Math.ceil(y/o.toRadians(5));m=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,M),y/(_+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,y/(_+1),H),k);var v,T;if(n=t.clone(n,Y),_>0)for(var R=p?2:1,A=0;A<_;A++)n=u.multiplyByVector(m,n,n),v=t.subtract(n,e,M),v=t.normalize(v,v),s||(v=t.negate(v,v)),T=c.scaleToGeodeticSurface(n,C),f=E(T,v,h,f,c,d,1,R);else v=t.subtract(n,e,M),v=t.normalize(v,v),s||(v=t.negate(v,v)),T=c.scaleToGeodeticSurface(n,C),f=E(T,v,h,f,c,d,1,1),r=t.clone(r,Y),v=t.subtract(r,e,M),v=t.normalize(v,v),s||(v=t.negate(v,v)),T=c.scaleToGeodeticSurface(r,C),f=E(T,v,h,f,c,d,1,1);return f}var T=[new t,new t],R=new t,A=new t,S=new t,g=new t,N=new t,O=new t,w=new t,I=new t,x=new t,M=new t,C=new t,P={},D=new r,U=new t,L=new t,b=new t(-1,0,0),F=new s,B=new s,z=new u,q=u.IDENTITY.clone(),G=new t,V=new n,W=new t,X=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],a=n-1,i=0;i<n;a=i++){var o=t[a],u=t[i];e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,a){var o=new i(r,a),u=o.projectPointOntoPlane(t.add(r,e,U),U),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var Z=new t,j=new t;return P.computePositions=function(e,n,r,i,u){var s=i._ellipsoid,l=h(e,s),f=i._granularity,p=i._cornerType,C=u?y(n,r):_(n,r),D=u?_(n,r):void 0,U=r.height/2,L=r.width/2,b=e.length,F=[],B=u?[]:void 0,z=R,q=A,G=S,V=g,W=N,X=O,H=w,Y=I,k=x,K=e[0],J=e[1];V=s.geodeticSurfaceNormal(K,V),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(B=E(K,Y,D,B,s,Q+U,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<b-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),V=s.geodeticSurfaceNormal(K,V);var ae=t.multiplyByScalar(V,t.dot(z,V),Z);t.subtract(z,ae,ae),t.normalize(ae,ae);var ie=t.multiplyByScalar(V,t.dot(q,V),j);t.subtract(q,ie,ie),t.normalize(ie,ie);if(!o.equalsEpsilon(Math.abs(t.dot(ae,ie)),1,o.EPSILON7)){G=t.cross(G,V,G),G=t.cross(V,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,M))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,L,X),X),T[0]=t.clone(k,T[0]),T[1]=t.clone(X,T[1]),ee=d(T,Q+U,$+U,f),te=c.generateArc({positions:T,granularity:f,ellipsoid:s}),F=m(te,Y,C,F,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,L,H),H),p===a.ROUNDED||p===a.BEVELED?v(W,X,H,p,ue,s,F,C,$+U,u):(G=t.negate(G,G),F=E(K,G,C,F,s,$+U,oe,re)),k=t.clone(H,k)):(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,-L,X),X),T[0]=t.clone(k,T[0]),T[1]=t.clone(X,T[1]),ee=d(T,Q+U,$+U,f),te=c.generateArc({positions:T,granularity:f,ellipsoid:s}),F=m(te,Y,C,F,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,-L,H),H),p===a.ROUNDED||p===a.BEVELED?v(W,X,H,p,ue,s,F,C,$+U,u):F=E(K,G,C,F,s,$+U,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else F=E(k,Y,C,F,s,Q+U,1,1),k=K;Q=$,$=l[ne+1],K=J}T[0]=t.clone(k,T[0]),T[1]=t.clone(K,T[1]),ee=d(T,Q+U,$+U,f),te=c.generateArc({positions:T,granularity:f,ellipsoid:s}),F=m(te,Y,C,F,s,ee,1),u&&(B=E(K,Y,D,B,s,$+U,1,1)),b=F.length;var se=u?b+B.length:b,ce=new Float64Array(se);return ce.set(F),u&&ce.set(B,b),ce},P}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},a.unpack=function(n,r,i){return r=e(r,0),t(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(e,n){if(t(e))return t(n)||(n=new a),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},a}),define("Core/PolylineVolumeGeometry",["./arrayRemoveDuplicates","./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CornerType","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./oneTimeWarning","./PolygonPipeline","./PolylineVolumeGeometryLibrary","./PrimitiveType","./VertexFormat","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,p,E,m,y,_,v,T,R,A){"use strict";function S(e,t,r,a){var o=new d;a.position&&(o.position=new h({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:e}));var u,s,c,l,m,v,R=t.length,A=e.length/3,S=(A-2*R)/(2*R),g=_.triangulate(t),N=(S-1)*R*6+2*g.length,O=E.createTypedArray(A,N),w=2*R,I=0;for(u=0;u<S-1;u++){for(s=0;s<R-1;s++)c=2*s+u*R*2,v=c+w,l=c+1,m=l+w,O[I++]=l,O[I++]=c,O[I++]=m,O[I++]=m,O[I++]=c,O[I++]=v;c=2*R-2+u*R*2,l=c+1,m=l+w,v=c+w,O[I++]=l,O[I++]=c,O[I++]=m,O[I++]=m,O[I++]=c,O[I++]=v}if(a.st||a.tangent||a.bitangent){var x,M,C=new Float32Array(2*A),P=1/(S-1),D=1/r.height,U=r.height/2,L=0;for(u=0;u<S;u++){for(x=u*P,M=D*(t[0].y+U),C[L++]=x,C[L++]=M,s=1;s<R;s++)M=D*(t[s].y+U),C[L++]=x,C[L++]=M,C[L++]=x,C[L++]=M;M=D*(t[0].y+U),C[L++]=x,C[L++]=M}for(s=0;s<R;s++)x=0,M=D*(t[s].y+U),C[L++]=x,C[L++]=M;for(s=0;s<R;s++)x=(S-1)*P,M=D*(t[s].y+U),C[L++]=x,C[L++]=M;o.st=new h({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:new Float32Array(C)})}var b=A-2*R;for(u=0;u<g.length;u+=3){var F=g[u]+b,B=g[u+1]+b,z=g[u+2]+b;O[I++]=F,O[I++]=B,O[I++]=z,O[I++]=z+R,O[I++]=B+R,O[I++]=F+R}var q=new f({attributes:o,indices:O,boundingSphere:n.fromVertices(e),primitiveType:T.TRIANGLES});if(a.normal&&(q=p.computeNormal(q)),a.tangent||a.bitangent){try{q=p.computeTangentAndBitangent(q)}catch(e){y("polyline-volume-tangent-bitangent","Unable to compute tangents and bitangents for polyline volume geometry")}a.tangent||(q.attributes.tangent=void 0),a.bitangent||(q.attributes.bitangent=void 0),a.st||(q.attributes.st=void 0)}return q}function g(e){e=u(e,u.EMPTY_OBJECT);var t=e.polylinePositions,n=e.shapePositions;this._positions=t,this._shape=n,this._ellipsoid=l.clone(u(e.ellipsoid,l.WGS84)),this._cornerType=u(e.cornerType,o.ROUNDED),this._vertexFormat=R.clone(u(e.vertexFormat,R.DEFAULT)),this._granularity=u(e.granularity,m.RADIANS_PER_DEGREE),this._workerName="createPolylineVolumeGeometry";var i=1+t.length*a.packedLength;i+=1+n.length*r.packedLength,this.packedLength=i+l.packedLength+R.packedLength+2}g.pack=function(e,t,n){n=u(n,0);var i,o=e._positions,s=o.length;for(t[n++]=s,i=0;i<s;++i,n+=a.packedLength)a.pack(o[i],t,n);var c=e._shape;for(s=c.length,t[n++]=s,i=0;i<s;++i,n+=r.packedLength)r.pack(c[i],t,n);return l.pack(e._ellipsoid,t,n),n+=l.packedLength,R.pack(e._vertexFormat,t,n),n+=R.packedLength,t[n++]=e._cornerType,t[n]=e._granularity,t};var N=l.clone(l.UNIT_SPHERE),O=new R,w={polylinePositions:void 0,shapePositions:void 0,ellipsoid:N,vertexFormat:O,cornerType:void 0,granularity:void 0};g.unpack=function(e,t,n){t=u(t,0);var i,o=e[t++],c=new Array(o);for(i=0;i<o;++i,t+=a.packedLength)c[i]=a.unpack(e,t);o=e[t++];var f=new Array(o);for(i=0;i<o;++i,t+=r.packedLength)f[i]=r.unpack(e,t);var h=l.unpack(e,t,N);t+=l.packedLength;var d=R.unpack(e,t,O);t+=R.packedLength;var p=e[t++],E=e[t];return s(n)?(n._positions=c,n._shape=f,n._ellipsoid=l.clone(h,n._ellipsoid),n._vertexFormat=R.clone(d,n._vertexFormat),n._cornerType=p,n._granularity=E,n):(w.polylinePositions=c,w.shapePositions=f,w.cornerType=p,w.granularity=E,new g(w))};var I=new t;return g.createGeometry=function(n){var r=n._positions,i=e(r,a.equalsEpsilon),o=n._shape;if(o=v.removeDuplicatesFromShape(o),!(i.length<2||o.length<3)){_.computeWindingOrder2D(o)===A.CLOCKWISE&&o.reverse();var u=t.fromPoints(o,I);return S(v.computePositions(i,o,u,n,!0),o,u,n._vertexFormat)}},g}),define("Workers/createPolylineVolumeGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolylineVolumeGeometry"],function(e,t,n){"use strict";function r(r,a){return e(a)&&(r=n.unpack(r,a)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(n,i){if(!e(i))throw new t(r(n))},i.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},i.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},i.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},i.typeOf.number.lessThan=function(e,r,n){if(i.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},i.typeOf.number.lessThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},i.typeOf.number.greaterThan=function(e,r,n){if(i.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},i.typeOf.number.greaterThanOrEquals=function(e,r,n){if(i.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},i.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},i.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},i.typeOf.number.equals=function(e,r,n,a){if(i.typeOf.number(e,n),i.typeOf.number(r,a),n!==a)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*i.clamp(e,-1,1)+.5)*r)},i.fromSNorm=function(e,r){return r=t(r,255),i.clamp(e,0,r)/r*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,r){return(1-r)*e+r*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,r,n,i){i=t(i,n);var a=Math.abs(e-r);return a<=i||a<=n*Math.max(Math.abs(e),Math.abs(r))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var r=a[t-1],n=t;n<=e;n++)a.push(r*n);return a[e]},i.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,r){return e<t?t:e>r?r:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}o.fromSpherical=function(e,n){r(n)||(n=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return n.x=s*Math.cos(i),n.y=s*Math.sin(i),n.z=u*Math.cos(a),n},o.fromElements=function(e,t,n,i){return r(i)?(i.x=e,i.y=t,i.z=n,i):new o(e,t,n)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var i=0;i<n;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var i=0;i<n;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var r=o.dot(c,l),n=o.magnitude(o.cross(c,l,c));return Math.atan2(n,r)};var f=new o;o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):r.y<=r.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,r){var n=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,n,r)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)},o.cross=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-n*s,f=n*u-i*o;return r.x=c,r.y=l,r.z=f,r},o.fromDegrees=function(e,t,r,n,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,r,n,i)};var h=new o,d=new o,p=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,n,i,a,u){i=t(i,0);var s=r(a)?a.radiiSquared:p,c=Math.cos(n);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(n),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),r(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromDegrees(u,s,0,t,n[c])}return n},o.fromRadiansArray=function(e,t,n){var i=e.length;r(n)?n.length=i/2:n=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;n[c]=o.fromRadians(u,s,0,t,n[c])}return n},o.fromDegreesArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromDegrees(u,s,c,t,n[l])}return n},o.fromRadiansArrayHeights=function(e,t,n){var i=e.length;r(n)?n.length=i/3:n=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;n[l]=o.fromRadians(u,s,c,t,n[l])}return n},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function i(r,i,u,s,c){var l=r.x,f=r.y,h=r.z,d=i.x,p=i.y,m=i.z,y=l*l*d*d,E=f*f*p*p,_=h*h*m*m,v=y+E+_,T=Math.sqrt(1/v),R=e.multiplyByScalar(r,T,a);if(v<s)return isFinite(T)?e.clone(R,c):void 0;var A=u.x,g=u.y,S=u.z,w=o;w.x=R.x*A*2,w.y=R.y*g*2,w.z=R.z*S*2;var O,N,I,x,M,C,P,D,U,b,L,F=(1-T)*e.magnitude(r)/(.5*e.magnitude(w)),B=0;do{F-=B,I=1/(1+F*A),x=1/(1+F*g),M=1/(1+F*S),C=I*I,P=x*x,D=M*M,U=C*I,b=P*x,L=D*M,O=y*C+E*P+_*D-1,N=y*U*A+E*b*g+_*L*S;B=O/(-2*N)}while(Math.abs(O)>n.EPSILON12);return t(c)?(c.x=l*I,c.y=f*x,c.z=h*M,c):new e(l*I,f*x,h*M)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,i,a){return i=r(i,0),n(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,r,n){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,r,i){var p=n(r)?r.oneOverRadii:f,m=n(r)?r.oneOverRadiiSquared:h,y=n(r)?r._centerToleranceSquared:d,E=o(t,p,m,y,c);if(n(E)){var _=e.multiplyComponents(E,m,s);_=e.normalize(_,_);var v=e.subtract(t,E,l),T=Math.atan2(_.y,_.x),R=Math.asin(_.z),A=a.sign(e.dot(v,t))*e.magnitude(v);return n(i)?(i.longitude=T,i.latitude=R,i.height=A,i):new u(T,R,A)}},u.toCartesian=function(t,r,n){return e.fromRadians(t.longitude,t.latitude,t.height,r,n)},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(t,r,i,a){r=n(r,0),i=n(i,0),a=n(a,0),t._radii=new e(r,i,a),t._radiiSquared=new e(r*r,i*i,a*a),t._radiiToTheFourth=new e(r*r*r*r,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===r?0:1/r,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(r,i,a),t._maximumRadius=Math.max(r,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,r){if(i(t)){var n=t._radii;return i(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new f(n.x,n.y,n.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,r,i){return i=n(i,0),e.pack(t._radii,r,i),r},f.unpack=function(t,r,i){r=n(r,0);var a=e.unpack(t,r);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(n),s=o*Math.sin(n),c=Math.sin(a);return i(r)||(r=new e),r.x=u,r.y=s,r.z=c,e.normalize(r,r)},f.prototype.geodeticSurfaceNormal=function(t,r){return i(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,r){var n=h,a=d;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,a);var o=Math.sqrt(e.dot(n,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(n,t.height,n),i(r)||(r=new e),e.add(a,n,r)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var p=new e,m=new e,y=new e;return f.prototype.cartesianToCartographic=function(r,n){var a=this.scaleToGeodeticSurface(r,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,p),u=e.subtract(r,a,y),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,r))*e.magnitude(u);return i(n)?(n.longitude=c,n.latitude=l,n.height=f,n):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,r){i(r)||(r=new e);var n=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,r)},f.prototype.transformPositionToScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},f.prototype.transformPositionFromScaledSpace=function(t,r){return i(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,a){r=n(r,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-r))return a},f}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,r,n){"use strict";function i(e,n,i){if(r(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!n(s,c,a));++u);if(u===o)return i&&n(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],n(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&n(l[0],l[l.length-1],a)&&l.shift(),l}}var a=n.EPSILON10;return i}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r){this.x=t(e,0),this.y=t(r,0)}o.fromElements=function(e,t,n){return r(n)?(n.x=e,n.y=t,n):new o(e,t)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n]=e.y,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=2*n:t=new Array(2*n);for(var i=0;i<n;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/2:t=new Array(n/2);for(var i=0;i<n;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,f);return o.abs(r,r),t=r.x<=r.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,i,a,o){"use strict";function u(e){this._ellipsoid=r(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return n(r)?(r.x=a,r.y=o,r.z=u,r):new e(a,o,u)},u.prototype.unproject=function(e,r){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return n(r)?(r.longitude=a,r.latitude=o,r.height=u,r):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),i=u.toRadians(r(i,0)),a=u.toRadians(r(a,0)),n(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return n(o)?(o.west=r(e,0),o.south=r(t,0),o.east=r(i,0),o.north=r(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];r=Math.min(r,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var p=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,p),o=Math.max(o,p)}return i-r>o-a&&(r=a,i=o,i>u.PI&&(i-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=c,t.east=i,t.north=l,t):new s(r,c,i,l)},s.fromCartesianArray=function(e,t,i){t=r(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,p=0,m=e.length;p<m;p++){var y=t.cartesianToCartographic(e[p]);o=Math.min(o,y.longitude),c=Math.max(c,y.longitude),h=Math.min(h,y.latitude),d=Math.max(d,y.latitude);var E=y.longitude>=0?y.longitude:y.longitude+u.TWO_PI;l=Math.min(l,E),f=Math.max(f,E)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),n(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return n(r)?(r.longitude=o,r.latitude=s,r.height=0,r):new e(o,s)},s.intersection=function(e,t,r){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return n(r)?(r.west=l,r.south=h,r.east=f,r.north=d,r):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,r){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return n(r)?(r.west=i,r.south=a,r.east=o,r.north=u,r):new s(i,a,o,u)},s.union=function(e,t,r){n(r)||(r=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return r.west=l,r.south=Math.min(e.south,t.south),r.east=f,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>i||u.equalsEpsilon(r,i,u.EPSILON14))&&(r<a||u.equalsEpsilon(r,a,u.EPSILON14))&&n>=e.south&&n<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=r(t,a.WGS84),i=r(i,0),n(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,p=e.west,m=c;m.height=i,m.longitude=p,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var y=1;y<8;++y)m.longitude=-Math.PI+y*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=p,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.width=n(r,0),this.height=n(i,0)}s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.width,t[r]=e.height,t},s.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new s),r.x=e[t++],r.y=e[t++],r.width=e[t++],r.height=e[t],r},s.fromPoints=function(e,t){if(i(t)||(t=new s),!i(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var r=e.length,n=e[0].x,a=e[0].y,o=e[0].x,u=e[0].y,c=1;c<r;c++){var l=e[c],f=l.x,h=l.y;n=Math.min(f,n),o=Math.max(f,o),a=Math.min(h,a),u=Math.max(h,u)}return t.x=n,t.y=a,t.width=o-n,t.height=u-a,t};var c=new a,l=new t,f=new t;return s.fromRectangle=function(t,r,a){if(i(a)||(a=new s),!i(t))return a.x=0,a.y=0,a.width=0,a.height=0,a;r=n(r,c);var o=r.project(u.southwest(t,l)),h=r.project(u.northeast(t,f));return e.subtract(h,o,h),a.x=o.x,a.y=o.y,a.width=h.x,a.height=h.y,a},s.clone=function(e,t){if(i(e))return i(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new s(e.x,e.y,e.width,e.height)},s.union=function(e,t,r){i(r)||(r=new s);var n=Math.min(e.x,t.x),a=Math.min(e.y,t.y),o=Math.max(e.x+e.width,t.x+t.width),u=Math.max(e.y+e.height,t.y+t.height);return r.x=n,r.y=a,r.width=o-n,r.height=u-a,r},s.expand=function(e,t,r){r=s.clone(e,r);var n=t.x-r.x,i=t.y-r.y;return n>r.width?r.width=n:n<0&&(r.width-=n,r.x=t.x),i>r.height?r.height=i:i<0&&(r.height-=i,r.y=t.y),r},s.intersect=function(e,t){var r=e.x,n=e.y,i=t.x,a=t.y;return r>i+t.width||r+e.width<i||n+e.height<a||n>a+t.height?o.OUTSIDE:o.INTERSECTING},s.equals=function(e,t){return e===t||i(e)&&i(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.intersect=function(e){return s.intersect(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i,a,o,u,s,c){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(a,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(o,0),this[8]=r(c,0)}function c(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(m[r],p[r])];t+=2*n*n}return Math.sqrt(t)}function f(e,t){for(var r=u.EPSILON15,n=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],p[a])]);o>n&&(i=a,n=o)}var c=1,l=0,f=p[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>r){var d,y=e[s.getElementIndex(h,h)],E=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],v=(y-E)/2/_;d=v<0?-1/(-v+Math.sqrt(1+v*v)):1/(v+Math.sqrt(1+v*v)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0), +t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,p=r-u-f+d,m=2*(i-h),y=2*(a+l),E=2*(i+h),_=-r+u-f+d,v=2*(c-o),T=2*(a-l),R=2*(c+o),A=-r-u+f+d;return n(t)?(t[0]=p,t[1]=E,t[2]=T,t[3]=m,t[4]=_,t[5]=R,t[6]=y,t[7]=v,t[8]=A,t):new s(p,m,y,E,_,v,T,R,A)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=r*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=r*u,p=a*i+c*o*u,m=-c*i+a*o*u,y=-o,E=c*r,_=a*r;return n(t)?(t[0]=l,t[1]=d,t[2]=y,t[3]=f,t[4]=p,t[5]=E,t[6]=h,t[7]=m,t[8]=_,t):new s(l,f,h,d,p,m,y,E,_)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=i,t[6]=0,t[7]=-i,t[8]=r,t):new s(1,0,0,0,r,-i,0,i,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=r,t):new s(r,0,i,0,1,0,-i,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),i=Math.sin(e);return n(t)?(t[0]=r,t[1]=i,t[2]=0,t[3]=-i,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-i,0,i,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,i=e[n],a=e[n+1],o=e[n+2];return r.x=i,r.y=a,r.z=o,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var i=3*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],i=e[t+3],a=e[t+6];return r.x=n,r.y=i,r.z=a,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var h=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),r};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=i,r[2]=a,r[3]=o,r[4]=u,r[5]=s,r[6]=c,r[7]=l,r[8]=f,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[3]*i+e[6]*a,u=e[1]*n+e[4]*i+e[7]*a,s=e[2]*n+e[5]*i+e[8]*a;return r.x=o,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var p=[1,0,0],m=[2,2,1],y=new s,E=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,i=0,a=0;n(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=r*c(h);a<10&&l(h)>d;)f(h,y),s.transpose(y,E),s.multiply(h,y,h),s.multiply(E,h,h),s.multiply(o,y,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*n-r*c)+u*(r*o-a*n)},s.inverse=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-n*f,t[2]=n*u-o*i,t[3]=c*u-a*f,t[4]=r*f-c*i,t[5]=a*i-r*u,t[6]=a*l-c*o,t[7]=c*n-r*l,t[8]=r*o-a*n;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,i,a){"use strict";function o(e,r,n,i){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(i,0)}o.fromElements=function(e,t,n,i,a){return r(a)?(a.x=e,a.y=t,a.z=n,a.w=i,a):new o(e,t,n,i)},o.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},o.unpack=function(e,n,i){return n=t(n,0),r(i)||(i=new o),i.x=e[n++],i.y=e[n++],i.z=e[n++],i.w=e[n],i},o.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var i=0;i<n;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var i=0;i<n;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},o.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var r=o.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},o.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},o.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},o.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},o.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},o.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,r,n){return o.multiplyByScalar(t,r,s),n=o.multiplyByScalar(e,1-r,n),o.add(s,n,n)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var r=o.normalize(e,c);return o.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):r.y<=r.z?r.y<=r.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):r.z<=r.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},o.equalsEpsilon=function(e,t,n,i){return e===t||r(e)&&r(t)&&a.equalsEpsilon(e.x,t.x,n,i)&&a.equalsEpsilon(e.y,t.y,n,i)&&a.equalsEpsilon(e.z,t.z,n,i)&&a.equalsEpsilon(e.w,t.w,n,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,r){return o.equalsEpsilon(this,e,t,r)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t,r,i,a,o,u,s,c,l,f,h,d,p,m,y){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(c,0),this[3]=n(d,0),this[4]=n(t,0),this[5]=n(o,0),this[6]=n(l,0),this[7]=n(p,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(f,0),this[11]=n(m,0),this[12]=n(i,0),this[13]=n(s,0),this[14]=n(h,0),this[15]=n(y,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),i(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,a){return r=n(r,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=r.x,a[13]=r.y,a[14]=r.z,a[15]=1,a):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){i(n)||(n=new l);var a=r.x,o=r.y,u=r.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,p=t.y*t.z,m=t.y*t.w,y=t.z*t.z,E=t.z*t.w,_=t.w*t.w,v=s-d-y+_,T=2*(c-E),R=2*(f+m),A=2*(c+E),g=-s+d-y+_,S=2*(p-h),w=2*(f-m),O=2*(p+h),N=-s-d+y+_;return n[0]=v*a,n[1]=A*a,n[2]=w*a,n[3]=0,n[4]=T*o,n[5]=g*o,n[6]=O*o,n[7]=0,n[8]=R*u,n[9]=S*u,n[10]=N*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,r){var n=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,p=f.x,m=f.y,y=f.z,E=d.x,_=d.y,v=d.z,T=n.x,R=n.y,A=n.z,g=u*-T+s*-R+c*-A,S=E*-T+_*-R+v*-A,w=p*T+m*R+y*A;return i(r)?(r[0]=u,r[1]=E,r[2]=-p,r[3]=0,r[4]=s,r[5]=_,r[6]=-m,r[7]=0,r[8]=c,r[9]=v,r[10]=-y,r[11]=0,r[12]=g,r[13]=S,r[14]=w,r[15]=1,r):new l(u,s,c,g,E,_,v,S,-p,-m,-y,w,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(n+r)/(r-n),c=2*n*r/(r-n);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,r,n,i,a,o){var u=1/(t-e),s=1/(n-r),c=1/(a-i),l=-(t+e)*u,f=-(n+r)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,r,n,i,a,o){var u=2*i/(t-e),s=2*i/(n-r),c=(t+e)/(t-e),l=(n+r)/(n-r),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,i,a){var o=2*i/(t-e),u=2*i/(n-r),s=(t+e)/(t-e),c=(n+r)/(n-r),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,r,i){e=n(e,n.EMPTY_OBJECT);var a=n(e.x,0),o=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var c=.5*u,l=.5*s,f=.5*(r-t),h=c,d=l,p=f,m=a+c,y=o+l,E=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=p,i[11]=0,i[12]=m,i[13]=y,i[14]=E,i[15]=1,i},l.computeView=function(t,r,n,i,a){return a[0]=i.x,a[1]=n.x,a[2]=-r.x,a[3]=0,a[4]=i.y,a[5]=n.y,a[6]=-r.y,a[7]=0,a[8]=i.z,a[9]=n.z,a[10]=-r.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(n,t),a[14]=e.dot(r,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3];return r.x=i,r.y=a,r.z=o,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var i=4*t;return n[i]=r.x,n[i+1]=r.y,n[i+2]=r.z,n[i+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return r.x=n,r.y=i,r.z=a,r.w=o,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var p=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],p)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],p)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],p)),r};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],p=e[11],m=e[12],y=e[13],E=e[14],_=e[15],v=t[0],T=t[1],R=t[2],A=t[3],g=t[4],S=t[5],w=t[6],O=t[7],N=t[8],I=t[9],x=t[10],M=t[11],C=t[12],P=t[13],D=t[14],U=t[15],b=n*v+u*T+f*R+m*A,L=i*v+s*T+h*R+y*A,F=a*v+c*T+d*R+E*A,B=o*v+l*T+p*R+_*A,z=n*g+u*S+f*w+m*O,q=i*g+s*S+h*w+y*O,G=a*g+c*S+d*w+E*O,V=o*g+l*S+p*w+_*O,W=n*N+u*I+f*x+m*M,X=i*N+s*I+h*x+y*M,H=a*N+c*I+d*x+E*M,k=o*N+l*I+p*x+_*M,Y=n*C+u*P+f*D+m*U,j=i*C+s*P+h*D+y*U,Z=a*C+c*P+d*D+E*U,K=o*C+l*P+p*D+_*U;return r[0]=b,r[1]=L,r[2]=F,r[3]=B,r[4]=z,r[5]=q,r[6]=G,r[7]=V,r[8]=W,r[9]=X,r[10]=H,r[11]=k,r[12]=Y,r[13]=j,r[14]=Z,r[15]=K,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],p=e[14],m=t[0],y=t[1],E=t[2],_=t[4],v=t[5],T=t[6],R=t[8],A=t[9],g=t[10],S=t[12],w=t[13],O=t[14],N=n*m+o*y+c*E,I=i*m+u*y+l*E,x=a*m+s*y+f*E,M=n*_+o*v+c*T,C=i*_+u*v+l*T,P=a*_+s*v+f*T,D=n*R+o*A+c*g,U=i*R+u*A+l*g,b=a*R+s*A+f*g,L=n*S+o*w+c*O+h,F=i*S+u*w+l*O+d,B=a*S+s*w+f*O+p;return r[0]=N,r[1]=I,r[2]=x,r[3]=0,r[4]=M,r[5]=C,r[6]=P,r[7]=0,r[8]=D,r[9]=U,r[10]=b,r[11]=0,r[12]=L,r[13]=F,r[14]=B,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],p=t[2],m=t[3],y=t[4],E=t[5],_=t[6],v=t[7],T=t[8],R=n*h+o*d+c*p,A=i*h+u*d+l*p,g=a*h+s*d+f*p,S=n*m+o*y+c*E,w=i*m+u*y+l*E,O=a*m+s*y+f*E,N=n*_+o*v+c*T,I=i*_+u*v+l*T,x=a*_+s*v+f*T;return r[0]=R,r[1]=A,r[2]=g,r[3]=0,r[4]=S,r[5]=w,r[6]=O,r[7]=0,r[8]=N,r[9]=I,r[10]=x,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=n*e[0]+i*e[4]+a*e[8]+e[12],u=n*e[1]+i*e[5]+a*e[9]+e[13],s=n*e[2]+i*e[6]+a*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=o,r[13]=u,r[14]=s,r[15]=e[15],r};var y=new e;l.multiplyByUniformScale=function(e,t,r){return y.x=t,y.y=t,y.z=t,l.multiplyByScale(e,y,r)},l.multiplyByScale=function(e,t,r){var n=t.x,i=t.y,a=t.z;return 1===n&&1===i&&1===a?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=i*e[4],r[5]=i*e[5],r[6]=i*e[6],r[7]=0,r[8]=a*e[8],r[9]=a*e[9],r[10]=a*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*n+e[4]*i+e[8]*a+e[12]*o,s=e[1]*n+e[5]*i+e[9]*a+e[13]*o,c=e[2]*n+e[6]*i+e[10]*a+e[14]*o,l=e[3]*n+e[7]*i+e[11]*a+e[15]*o;return r.x=u,r.y=s,r.z=c,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a,u=e[1]*n+e[5]*i+e[9]*a,s=e[2]*n+e[6]*i+e[10]*a;return r.x=o,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,i=t.y,a=t.z,o=e[0]*n+e[4]*i+e[8]*a+e[12],u=e[1]*n+e[5]*i+e[9]*a+e[13],s=e[2]*n+e[6]*i+e[10]*a+e[14];return r.x=o,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var E=new s,_=new s,v=new t,T=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,E),_,u.EPSILON7)&&t.equals(l.getRow(e,3,v),T))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],p=e[13],m=e[2],y=e[6],R=e[10],A=e[14],g=e[3],S=e[7],w=e[11],O=e[15],N=R*O,I=A*w,x=y*O,M=A*S,C=y*w,P=R*S,D=m*O,U=A*g,b=m*w,L=R*g,F=m*S,B=y*g,z=N*h+M*d+C*p-(I*h+x*d+P*p),q=I*f+D*d+L*p-(N*f+U*d+b*p),G=x*f+U*h+F*p-(M*f+D*h+B*p),V=P*f+b*h+B*d-(C*f+L*h+F*d),W=I*i+x*a+P*o-(N*i+M*a+C*o),X=N*n+U*a+b*o-(I*n+D*a+L*o),H=M*n+D*i+B*o-(x*n+U*i+F*o),k=C*n+L*i+F*a-(P*n+b*i+B*a);N=a*p,I=o*d,x=i*p,M=o*h,C=i*d,P=a*h,D=n*p,U=o*f,b=n*d,L=a*f,F=n*h,B=i*f;var Y=N*S+M*w+C*O-(I*S+x*w+P*O),j=I*g+D*w+L*O-(N*g+U*w+b*O),Z=x*g+U*S+F*O-(M*g+D*S+B*O),K=P*g+b*S+B*w-(C*g+L*S+F*w),J=x*R+P*A+I*y-(C*A+N*y+M*R),Q=b*A+N*m+U*R-(D*R+L*A+I*m),$=D*y+B*A+M*m-(F*A+x*m+U*y),ee=F*R+C*m+L*y-(b*y+B*R+P*m),te=n*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=z*te,r[1]=q*te,r[2]=G*te,r[3]=V*te,r[4]=W*te,r[5]=X*te,r[6]=H*te,r[7]=k*te,r[8]=Y*te,r[9]=j*te,r[10]=Z*te,r[11]=K*te,r[12]=J*te,r[13]=Q*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],p=-r*f-n*h-i*d,m=-a*f-o*h-u*d,y=-s*f-c*h-l*d;return t[0]=r,t[1]=a,t[2]=s,t[3]=0,t[4]=n,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=p,t[13]=m,t[14]=y,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";function d(t,r){this.center=e.clone(i(t,e.ZERO)),this.radius=i(r,0)}var p=new e,m=new e,y=new e,E=new e,_=new e,v=new e,T=new e,R=new e,A=new e,g=new e,S=new e,w=new e,O=4/3*r.PI;d.fromPoints=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,i=e.clone(t[0],T),o=e.clone(i,p),u=e.clone(i,m),s=e.clone(i,y),c=e.clone(i,E),l=e.clone(i,_),f=e.clone(i,v),h=t.length;for(n=1;n<h;n++){e.clone(t[n],i);var O=i.x,N=i.y,I=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),N<u.y&&e.clone(i,u),N>l.y&&e.clone(i,l),I<s.z&&e.clone(i,s),I>f.z&&e.clone(i,f)}var x=e.magnitudeSquared(e.subtract(c,o,R)),M=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,D=c,U=x;M>U&&(U=M,P=u,D=l),C>U&&(U=C,P=s,D=f);var b=A;b.x=.5*(P.x+D.x),b.y=.5*(P.y+D.y),b.z=.5*(P.z+D.z);var L=e.magnitudeSquared(e.subtract(D,b,R)),F=Math.sqrt(L),B=g;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,R),.5,w),G=0;for(n=0;n<h;n++){e.clone(t[n],i);var V=e.magnitude(e.subtract(i,q,R));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,b,R));if(W>L){var X=Math.sqrt(W);F=.5*(F+X),L=F*F;var H=X-F;b.x=(F*b.x+H*i.x)/X,b.y=(F*b.y+H*i.y)/X,b.z=(F*b.z+H*i.z)/X}}return F<G?(e.clone(b,r.center),r.radius=F):(e.clone(q,r.center),r.radius=G),r};var N=new u,I=new e,x=new e,M=new t,C=new t;d.fromRectangle2D=function(e,t,r){return d.fromRectangleWithHeights2D(e,t,0,0,r)},d.fromRectangleWithHeights2D=function(t,r,n,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=i(r,N),h.southwest(t,M),M.height=n,h.northeast(t,C),C.height=o;var s=r.project(M,I),c=r.project(C,x),l=c.x-s.x,f=c.y-s.y,p=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+p*p);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*p,u};var P=[];d.fromRectangle3D=function(t,r,n,u){if(r=i(r,o.WGS84),n=i(n,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,r,n,P);return d.fromPoints(s,u)},d.fromVertices=function(t,r,n,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;r=i(r,e.ZERO),n=i(n,3);var u=T;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,c=e.clone(u,p),l=e.clone(u,m),f=e.clone(u,y),h=e.clone(u,E),O=e.clone(u,_),N=e.clone(u,v),I=t.length;for(s=0;s<I;s+=n){var x=t[s]+r.x,M=t[s+1]+r.y,C=t[s+2]+r.z;u.x=x,u.y=M,u.z=C,x<c.x&&e.clone(u,c),x>h.x&&e.clone(u,h),M<l.y&&e.clone(u,l),M>O.y&&e.clone(u,O),C<f.z&&e.clone(u,f),C>N.z&&e.clone(u,N)}var P=e.magnitudeSquared(e.subtract(h,c,R)),D=e.magnitudeSquared(e.subtract(O,l,R)),U=e.magnitudeSquared(e.subtract(N,f,R)),b=c,L=h,F=P;D>F&&(F=D,b=l,L=O),U>F&&(F=U,b=f,L=N);var B=A;B.x=.5*(b.x+L.x),B.y=.5*(b.y+L.y),B.z=.5*(b.z+L.z);var z=e.magnitudeSquared(e.subtract(L,B,R)),q=Math.sqrt(z),G=g;G.x=c.x,G.y=l.y,G.z=f.z;var V=S;V.x=h.x,V.y=O.y,V.z=N.z;var W=e.multiplyByScalar(e.add(G,V,R),.5,w),X=0;for(s=0;s<I;s+=n){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var H=e.magnitude(e.subtract(u,W,R));H>X&&(X=H);var k=e.magnitudeSquared(e.subtract(u,B,R));if(k>z){var Y=Math.sqrt(k);q=.5*(q+Y),z=q*q;var j=Y-q;B.x=(q*B.x+j*u.x)/Y,B.y=(q*B.y+j*u.y)/Y,B.z=(q*B.z+j*u.z)/Y}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new d),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var i=T;i.x=t[0]+r[0],i.y=t[1]+r[1],i.z=t[2]+r[2];var o,u=e.clone(i,p),s=e.clone(i,m),c=e.clone(i,y),l=e.clone(i,E),f=e.clone(i,_),h=e.clone(i,v),O=t.length;for(o=0;o<O;o+=3){var N=t[o]+r[o],I=t[o+1]+r[o+1],x=t[o+2]+r[o+2];i.x=N,i.y=I,i.z=x,N<u.x&&e.clone(i,u),N>l.x&&e.clone(i,l),I<s.y&&e.clone(i,s),I>f.y&&e.clone(i,f),x<c.z&&e.clone(i,c),x>h.z&&e.clone(i,h)}var M=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(h,c,R)),D=u,U=l,b=M;C>b&&(b=C,D=s,U=f),P>b&&(b=P,D=c,U=h);var L=A;L.x=.5*(D.x+U.x),L.y=.5*(D.y+U.y),L.z=.5*(D.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),z=g;z.x=u.x,z.y=s.y,z.z=c.z;var q=S;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,w),V=0;for(o=0;o<O;o+=3){i.x=t[o]+r[o],i.y=t[o+1]+r[o+1],i.z=t[o+2]+r[o+2];var W=e.magnitude(e.subtract(i,G,R));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,L,R));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var k=H-B;L.x=(B*L.x+k*i.x)/H,L.y=(B*L.y+k*i.y)/H,L.z=(B*L.z+k*i.z)/H}}return B<V?(e.clone(L,n.center),n.radius=B):(e.clone(G,n.center),n.radius=V),n},d.fromCornerPoints=function(t,r,n){a(n)||(n=new d);var i=n.center;return e.add(t,r,i),e.multiplyByScalar(i,.5,i),n.radius=e.distance(i,r),n},d.fromEllipsoid=function(t,r){return a(r)||(r=new d),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var D=new e;d.fromBoundingSpheres=function(t,r){if(a(r)||(r=new d),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return d.clone(t[0],r);if(2===n)return d.union(t[0],t[1],r);var i,o=[];for(i=0;i<n;i++)o.push(t[i].center);r=d.fromPoints(o,r);var u=r.center,s=r.radius;for(i=0;i<n;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,D)+c.radius)}return r.radius=s,r};var U=new e,b=new e,L=new e;d.fromOrientedBoundingBox=function(t,r){a(r)||(r=new d);var n=t.halfAxes,i=l.getColumn(n,0,U),o=l.getColumn(n,1,b),u=l.getColumn(n,2,L);return e.add(i,o,i),e.add(i,u,i),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(i),r},d.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,r){r=i(r,0);var n=e.center;return t[r++]=n.x,t[r++]=n.y,t[r++]=n.z,t[r]=e.radius,t},d.unpack=function(e,t,r){t=i(t,0),a(r)||(r=new d);var n=r.center;return n.x=e[t++], +n.y=e[t++],n.z=e[t++],r.radius=e[t],r};var F=new e,B=new e;d.union=function(t,r,n){a(n)||(n=new d);var i=t.center,o=t.radius,u=r.center,s=r.radius,c=e.subtract(u,i,F),l=e.magnitude(c);if(o>=l+s)return t.clone(n),n;if(s>=l+o)return r.clone(n),n;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,n.center),n.radius=f,n};var z=new e;d.expand=function(t,r,n){n=d.clone(t,n);var i=e.magnitude(e.subtract(r,n.center,z));return i>n.radius&&(n.radius=i),n},d.intersectPlane=function(t,r){var n=t.center,i=t.radius,a=r.normal,o=e.dot(a,n)+r.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=f.getMaximumScale(t)*e.radius,r};var q=new e;d.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,q);return e.magnitudeSquared(n)-t.radius*t.radius},d.transformWithoutScale=function(e,t,r){return a(r)||(r=new d),r.center=f.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var G=new e;d.computePlaneDistances=function(t,r,n,i){a(i)||(i=new c);var o=e.subtract(t.center,r,G),u=e.dot(n,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,W=new e,X=new e,H=new e,k=new e,Y=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,r,n){r=i(r,K);var a=r.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,k),h=e.negate(c,H),p=j,m=p[0];e.add(s,l,m),e.add(m,c,m),m=p[1],e.add(s,l,m),e.add(m,h,m),m=p[2],e.add(s,f,m),e.add(m,h,m),m=p[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=p[4],e.add(s,l,m),e.add(m,c,m),m=p[5],e.add(s,l,m),e.add(m,h,m),m=p[6],e.add(s,f,m),e.add(m,h,m),m=p[7],e.add(s,f,m),e.add(m,c,m);for(var y=p.length,E=0;E<y;++E){var _=p[E];e.add(o,_,_);var v=a.cartesianToCartographic(_,Y);r.project(v,_)}n=d.fromPoints(p,n),o=n.center;var T=o.x,R=o.y,A=o.z;return o.x=A,o.y=T,o.z=R,n},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,r){return d.computePlaneDistances(this,e,t,r)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return O*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(n.requestFullscreen=i,r=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(n.requestFullscreen=i,r=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?n.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(n.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?n.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(n.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?n.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(n.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),n.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),n.fullscreenerror=i)}return r},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[n.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function i(){if(!t(R)&&(R=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(R=!0,A=n(e[1]))}return R}function a(){return i()&&A}function o(){if(!t(g)&&(g=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(T.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(g=!0,S=n(e[1]))}return g}function u(){return o()&&S}function s(){if(!t(w)){w=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(T.userAgent);null!==e&&(w=!0,O=n(e[1]),O.isNightly=!!e[2])}return w}function c(){return s()&&O}function l(){if(!t(N)){N=!1;var e;"Microsoft Internet Explorer"===T.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(N=!0,I=n(e[1])):"Netscape"===T.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(T.userAgent))&&(N=!0,I=n(e[1]))}return N}function f(){return l()&&I}function h(){if(!t(x)){x=!1;var e=/ Edge\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(x=!0,M=n(e[1]))}return x}function d(){return h()&&M}function p(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(T.userAgent);null!==e&&(C=!0,P=n(e[1]))}return C}function m(){return t(D)||(D=/Windows/i.test(T.appVersion)),D}function y(){return p()&&P}function E(){return t(U)||(U="undefined"!=typeof PointerEvent&&(!t(T.pointerEnabled)||T.pointerEnabled)),U}function _(){if(!t(L)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;L=t(r)&&""!==r,L&&(b=r)}return L}function v(){return _()?b:void 0}var T;T="undefined"!=typeof navigator?navigator:{};var R,A,g,S,w,O,N,I,x,M,C,P,D,U,b,L,F={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:p,firefoxVersion:y,isWindows:m,hardwareConcurrency:e(T.hardwareConcurrency,3),supportsPointerEvents:E,supportsImageRenderingPixelated:_,imageRenderingValue:v};return F.supportsFullscreen=function(){return r.supportsFullscreen()},F.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},F.supportsWebWorkers=function(){return"undefined"!=typeof Worker},F}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,i,a){"use strict";if(!n.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,r,n,i){switch(n=e(n,0),i=e(i,(r.byteLength-n)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(r,n,i);case o.UNSIGNED_BYTE:return new Uint8Array(r,n,i);case o.SHORT:return new Int16Array(r,n,i);case o.UNSIGNED_SHORT:return new Uint16Array(r,n,i);case o.INT:return new Int32Array(r,n,i);case o.UNSIGNED_INT:return new Uint32Array(r,n,i);case o.FLOAT:return new Float32Array(r,n,i);case o.DOUBLE:return new Float64Array(r,n,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var i=e.attributes[n],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,r,n,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,r){if(r.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),r.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var n=r.x,i=r.y;r.x=(1-Math.abs(i))*a.signNotZero(n),r.y=(1-Math.abs(n))*a.signNotZero(i)}return r.x=a.toSNorm(r.x,t),r.y=a.toSNorm(r.y,t),r},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,r,n,i){if(i.x=a.fromSNorm(e,n),i.y=a.fromSNorm(r,n),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,r){return u.octDecodeInRange(e,t,255,r)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var r=e/256,n=Math.floor(r),i=256*(r-n);return u.octDecode(n,i,t)},u.octPack=function(e,t,r,n){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(r,s);return n.x=65536*o.x+i,n.y=65536*o.y+a,n},u.octUnpack=function(e,t,r,n){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,r),u.octDecode(a,s,n)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var r=e/4096,n=Math.floor(r);return t.x=n/4095,t.y=(e-4096*n)/4095,t},u.zigZagDeltaDecode=function(e,t,r){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,n(r)&&(s+=o(r[c]),r[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,r,n){"use strict";function i(r,i,s,c,l){n(l)||(l=new t);var f,h,d,p,m,y,E,_;n(i.z)?(f=t.subtract(s,i,a),h=t.subtract(c,i,o),d=t.subtract(r,i,u),p=t.dot(f,f),m=t.dot(f,h),y=t.dot(f,d),E=t.dot(h,h),_=t.dot(h,d)):(f=e.subtract(s,i,a),h=e.subtract(c,i,o),d=e.subtract(r,i,u),p=e.dot(f,f),m=e.dot(f,h),y=e.dot(f,d),E=e.dot(h,h),_=e.dot(h,d));var v=1/(p*E-m*m);return l.y=(E*y-m*_)*v,l.z=(p*_-m*y)*v,l.x=1-l.y-l.z,l}var a=new t,o=new t,u=new t;return i}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,r){"use strict";function n(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}n.encode=function(e,t){r(t)||(t={high:0,low:0});var n;return e>=0?(n=65536*Math.floor(e/65536),t.high=n,t.low=e-n):(n=65536*Math.floor(-e/65536),t.high=-n,t.low=e+n),t};var i={high:0,low:0};n.fromCartesian=function(e,t){r(t)||(t=new n);var a=t.high,o=t.low;return n.encode(e.x,i),a.x=i.high,o.x=i.low,n.encode(e.y,i),a.y=i.high,o.y=i.low,n.encode(e.z,i),a.z=i.high,o.z=i.low,t};var a=new n;return n.writeElements=function(e,t,r){n.fromCartesian(e,a);var i=a.high,o=a.low;t[r]=i.x,t[r+1]=i.y,t[r+2]=i.z,t[r+3]=o.x,t[r+4]=o.y,t[r+5]=o.z},n}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,r,i){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,i):new Uint16Array(t,r,i)},r(a)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var i=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(r)))<n?0:i}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,i){var a;if(0===e)return 0===n?[]:[-i/n];if(0===n){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-n/e,a<0?[a,0]:[0,a];var c=n*n,l=4*e*i,f=r(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*r(n,t.sign(n)*Math.sqrt(f),t.EPSILON14);return n>0?[h/e,i/h]:[i/h,h/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var i,a,o=e,u=t/3,s=r/3,c=n,l=o*s,f=u*c,h=u*u,d=s*s,p=o*s-h,m=o*c-u*s,y=u*c-d,E=4*p*y-m*m;if(E<0){var _,v,T;h*f>=l*d?(_=o,v=p,T=-2*u*p+o*m):(_=c,v=y,T=-c*m+2*s*y);var R=T<0?-1:1,A=-R*Math.abs(_)*Math.sqrt(-E);a=-T+A;var g=a/2,S=g<0?-Math.pow(-g,1/3):Math.pow(g,1/3),w=a===A?-S:-v/S;return i=v<=0?S+w:-T/(S*S+w*w+v),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var O=p,N=-2*u*p+o*m,I=y,x=-c*m+2*s*y,M=Math.sqrt(E),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*M,-N)/3);i=2*Math.sqrt(-O);var D=Math.cos(P);a=i*D;var U=i*(-D/2-C*Math.sin(P)),b=a+U>2*u?a-u:U-u,L=o,F=b/L;P=Math.abs(Math.atan2(c*M,-x)/3),i=2*Math.sqrt(-I),D=Math.cos(P),a=i*D,U=i*(-D/2-C*Math.sin(P));var B=-c,z=a+U<2*s?a+s:U+s,q=B/z,G=L*z,V=-b*z-L*B,W=b*B,X=(s*V-u*W)/(-u*V+s*G);return F<=X?F<=q?X<=q?[F,X,q]:[F,q,X]:[q,F,X]:F<=q?[X,F,q]:X<=q?[X,q,F]:[q,X,F]}var n={};return n.computeDiscriminant=function(e,t,r,n){var i=e*e,a=t*t,o=r*r;return 18*e*t*r*n+a*o-27*i*(n*n)-4*(e*o*r+a*t*n)},n.computeRealRoots=function(e,n,i,a){var o,u;if(0===e)return t.computeRealRoots(n,i,a);if(0===n){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):r(e,0,i,a)}return 0===i?0===a?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,a):0===a?(o=t.computeRealRoots(e,n,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):r(e,n,i,a)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<r.EPSILON14){var p=n.computeRealRoots(1,s,l);if(2===p.length){var m,y=p[0],E=p[1];if(y>=0&&E>=0){var _=Math.sqrt(y),v=Math.sqrt(E);return[h-v,h-_,h+_,h+v]}if(y>=0&&E<0)return m=Math.sqrt(y),[h-m,h+m];if(y<0&&E>=0)return m=Math.sqrt(E),[h-m,h+m]}return[]}if(d>0){var T=Math.sqrt(d),R=(s+d-c/T)/2,A=(s+d+c/T)/2,g=n.computeRealRoots(1,T,R),S=n.computeRealRoots(1,-T,A);return 0!==g.length?(g[0]+=h,g[1]+=h,0!==S.length?(S[0]+=h,S[1]+=h,g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>S[0]&&g[0]<S[1]?[S[0],g[0],S[1],g[1]]:[g[0],S[0],g[1],S[1]]):g):0!==S.length?(S[0]+=h,S[1]+=h,S):[]}}return[]}function a(t,i,a,o){ +var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var p,m,y=d[0],E=i-y,_=E*E,v=t/2,T=E/2,R=_-4*o,A=_+4*Math.abs(o),g=c-4*y,S=c+4*Math.abs(y);if(y<0||R*S<g*A){var w=Math.sqrt(g);p=w/2,m=0===w?0:(t*T-a)/w}else{var O=Math.sqrt(R);p=0===O?0:(t*T-a)/O,m=O/2}var N,I;0===v&&0===p?(N=0,I=0):r.sign(v)===r.sign(p)?(N=v+p,I=y/N):(I=v-p,N=y/I);var x,M;0===T&&0===m?(x=0,M=0):r.sign(T)===r.sign(m)?(x=T+m,M=o/x):(M=T-m,x=o/M);var C=n.computeRealRoots(1,N,x),P=n.computeRealRoots(1,I,M);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,r,n,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=r*r,l=c*r,f=n*n,h=f*n,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*r*h-27*a*f*f+256*o*(d*i)+i*(18*s*r*n-4*u*l+16*e*c*c-80*e*t*c*n-6*e*u*f+144*a*r*f)+d*(144*e*u*r-27*u*u-128*a*c-192*a*t*n)},o.computeRealRoots=function(t,n,o,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,o,u,s);var c=n/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return i.getPoint=function(t,n,i){return r(i)||(i=new e),i=e.multiplyByScalar(t.direction,n,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,i,a,o,u,s,c,l){"use strict";function f(e,t,r,n){var i=t*t-4*e*r;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var c=-t/(2*e);if(0!==c)return n.root0=n.root1=c,n}}function h(t,r,i){n(i)||(i=new a);var o=t.origin,u=t.direction,s=r.center,c=r.radius*r.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),p=e.magnitudeSquared(l)-c,m=f(h,d,p,A);if(n(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,r){var n=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function p(t,r,n,i,a){var l,f=i*i,h=a*a,p=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+r.y),y=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*r.x+n,E=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),v=[];if(0===_&&0===E){if(l=s.computeRealRoots(p,m,y),0===l.length)return v;var T=l[0],R=Math.sqrt(Math.max(1-T*T,0));if(v.push(new e(i,a*T,a*-R)),v.push(new e(i,a*T,a*R)),2===l.length){var A=l[1],g=Math.sqrt(Math.max(1-A*A,0));v.push(new e(i,a*A,a*-g)),v.push(new e(i,a*A,a*g))}return v}var S=_*_,w=E*E,O=p*p,N=_*E,I=O+w,x=2*(m*p+N),M=2*y*p+m*m-w+S,C=2*(y*m-N),P=y*y-S;if(0===I&&0===x&&0===M&&0===C)return v;l=c.computeRealRoots(I,x,M,C,P);var D=l.length;if(0===D)return v;for(var U=0;U<D;++U){var b,L=l[U],F=L*L,B=Math.max(1-F,0),z=Math.sqrt(B);b=o.sign(p)===o.sign(y)?d(p*F+y,m*L,o.EPSILON12):o.sign(y)===o.sign(m*L)?d(p*F,m*L+y,o.EPSILON12):d(p*F+m*L,y,o.EPSILON12);var q=d(E*L,_,o.EPSILON15),G=b*q;G<0?v.push(new e(i,a*L,a*z)):G>0?v.push(new e(i,a*L,a*-z)):0!==z?(v.push(new e(i,a*L,a*-z)),v.push(new e(i,a*L,a*z)),++U):v.push(new e(i,a*L,a*z))}return v}var m={};m.rayPlane=function(t,r,i){n(i)||(i=new e);var a=t.origin,u=t.direction,s=r.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-r.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var y=new e,E=new e,_=new e,v=new e,T=new e;m.rayTriangleParametric=function(t,n,i,a,u){u=r(u,!1);var s,c,l,f,h,d=t.origin,p=t.direction,m=e.subtract(i,n,y),R=e.subtract(a,n,E),A=e.cross(p,R,_),g=e.dot(m,A);if(u){if(g<o.EPSILON6)return;if(s=e.subtract(d,n,v),(l=e.dot(s,A))<0||l>g)return;if(c=e.cross(s,m,T),(f=e.dot(p,c))<0||l+f>g)return;h=e.dot(R,c)/g}else{if(Math.abs(g)<o.EPSILON6)return;var S=1/g;if(s=e.subtract(d,n,v),(l=e.dot(s,A)*S)<0||l>1)return;if(c=e.cross(s,m,T),(f=e.dot(p,c)*S)<0||l+f>1)return;h=e.dot(R,c)*S}return h},m.rayTriangle=function(t,r,i,a,o,u){var s=m.rayTriangleParametric(t,r,i,a,o);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var R=new l;m.lineSegmentTriangle=function(t,r,i,a,o,u,s){var c=R;e.clone(t,c.origin),e.subtract(r,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,r){if(r=h(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var g=new l;m.lineSegmentSphere=function(t,r,i,a){var o=g;e.clone(t,o.origin);var u=e.subtract(r,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!n(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var S=new e,w=new e;m.rayEllipsoid=function(t,r){var n,i,o,u,s,c=r.oneOverRadii,l=e.multiplyComponents(c,t.origin,S),f=e.multiplyComponents(c,t.direction,w),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var p=d*d;if(n=h-1,i=e.magnitudeSquared(f),o=i*n,p<o)return;if(p>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,y=n/s;return m<y?new a(m,y):{start:y,stop:m}}var E=Math.sqrt(n/i);return new a(E,E)}return h<1?(n=h-1,i=e.magnitudeSquared(f),o=i*n,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var O=new e,N=new e,I=new e,x=new e,M=new e,C=new u,P=new u,D=new u,U=new u,b=new u,L=new u,F=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,r){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=r.geodeticSurfaceNormal(i,O);if(e.dot(a,s)>=0)return i}var c=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(a,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,x),d=e.normalize(e.cross(h,f,N),N),m=e.normalize(e.cross(f,d,I),I),y=C;y[0]=f.x,y[1]=f.y,y[2]=f.z,y[3]=d.x,y[4]=d.y,y[5]=d.z,y[6]=m.x,y[7]=m.y,y[8]=m.z;var E=u.transpose(y,P),_=u.fromScale(r.radii,D),v=u.fromScale(r.oneOverRadii,U),T=b;T[0]=0,T[1]=-a.z,T[2]=a.y,T[3]=a.z,T[4]=0,T[5]=-a.x,T[6]=-a.y,T[7]=a.x,T[8]=0;var R,A,g=u.multiply(u.multiply(E,v,L),T,L),S=u.multiply(u.multiply(g,_,F),y,F),w=u.multiplyByVector(g,i,M),G=p(S,e.negate(w,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){R=u.multiplyByVector(_,u.multiplyByVector(y,G[H],B),B);var k=e.normalize(e.subtract(R,i,x),x),Y=e.dot(k,a);Y>X&&(X=Y,W=e.clone(R,W))}var j=r.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(W,i,x))*Math.sqrt(1-X*X),A=c?-A:A,j.height=A,r.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,r,i,a){n(a)||(a=new e);var u=e.subtract(r,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,r,n,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,r)+o<0,c=e.dot(a,n)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,r,n,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,r,n,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,r,n,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,r,n,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,r,n,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,r,n,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,i,a,o){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,i){var a=-e.dot(n,t);return r(i)?(e.clone(n,i.normal),i.distance=a,i):new u(n,a)};var s=new e;u.fromCartesian4=function(t,n){var i=e.fromCartesian4(t,s),a=t.w;return r(n)?(e.clone(i,n.normal),n.distance=a,n):new u(i,a)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,n,i){r(i)||(i=new e);var a=u.getPointDistance(t,n),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(n,o,i)};var l=new e;return u.transform=function(t,r,n){return o.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";var n={};return n.calculateACMR=function(r){r=e(r,e.EMPTY_OBJECT);var n=r.indices,i=r.maximumIndex,a=e(r.cacheSize,24),o=n.length;if(!t(i)){i=0;for(var u=0,s=n[u];u<o;)s>i&&(i=s),++u,s=n[u]}for(var c=[],l=0;l<i+1;l++)c[l]=0;for(var f=a+1,h=0;h<o;++h)f-c[n[h]]>a&&(c[n[h]]=f,++f);return(f-a+1)/(o/3)},n.tipsify=function(r){function n(e,t,r,n){for(;t.length>=1;){var a=t[t.length-1];if(t.splice(t.length-1,1),e[a].numLiveTriangles>0)return a}for(;i<n;){if(e[i].numLiveTriangles>0)return++i-1;++i}return-1}r=e(r,e.EMPTY_OBJECT);var i,a=r.indices,o=r.maximumIndex,u=e(r.cacheSize,24),s=a.length,c=0,l=0,f=a[l],h=s;if(t(o))c=o+1;else{for(;l<h;)f>c&&(c=f),++l,f=a[l];if(-1===c)return 0;++c}var d,p=[];for(d=0;d<c;d++)p[d]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var m=0;l<h;)p[a[l]].vertexTriangles.push(m),++p[a[l]].numLiveTriangles,p[a[l+1]].vertexTriangles.push(m),++p[a[l+1]].numLiveTriangles,p[a[l+2]].vertexTriangles.push(m),++p[a[l+2]].numLiveTriangles,++m,l+=3;var y=0,E=u+1;i=1;var _,v,T=[],R=[],A=0,g=[],S=s/3,w=[];for(d=0;d<S;d++)w[d]=!1;for(var O,N;-1!==y;){T=[],v=p[y],N=v.vertexTriangles.length;for(var I=0;I<N;++I)if(m=v.vertexTriangles[I],!w[m]){w[m]=!0,l=m+m+m;for(var x=0;x<3;++x)O=a[l],T.push(O),R.push(O),g[A]=O,++A,_=p[O],--_.numLiveTriangles,E-_.timeStamp>u&&(_.timeStamp=E,++E),++l}y=function(e,t,r,i,a,o,u){for(var s,c=-1,l=-1,f=0;f<r.length;){var h=r[f];i[h].numLiveTriangles&&(s=0,a-i[h].timeStamp+2*i[h].numLiveTriangles<=t&&(s=a-i[h].timeStamp),(s>l||-1===l)&&(l=s,c=h)),++f}return-1===c?n(i,o,e,u):c}(a,u,T,p,E,R,c)}return g},n}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,A,g,S){"use strict";function w(e,t,r,n,i){e[t++]=r,e[t++]=n,e[t++]=n,e[t++]=i,e[t++]=i,e[t]=r}function O(e){for(var t=e.length,r=t/3*6,n=y.createTypedArray(t,r),i=0,a=0;a<t;a+=3,i+=6)w(n,i,e[a],e[a+1],e[a+2]);return n}function N(e){var t=e.length;if(t>=3){var r=6*(t-2),n=y.createTypedArray(t,r);w(n,0,e[0],e[1],e[2]);for(var i=6,a=3;a<t;++a,i+=6)w(n,i,e[a-1],e[a],e[a-2]);return n}return new Uint16Array}function I(e){if(e.length>0){for(var t=e.length-1,r=6*(t-1),n=y.createTypedArray(t,r),i=e[0],a=0,o=1;o<t;++o,a+=6)w(n,a,i,e[o],e[o+1]);return n}return new Uint16Array}function x(e){var t={};for(var r in e)if(e.hasOwnProperty(r)&&c(e[r])&&c(e[r].values)){var n=e[r];t[r]=new p({componentDatatype:n.componentDatatype,componentsPerAttribute:n.componentsPerAttribute,normalize:n.normalize,values:[]})}return t}function M(e,t,r){for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values))for(var i=t[n],a=0;a<i.componentsPerAttribute;++a)e[n].values.push(i.values[r*i.componentsPerAttribute+a])}function C(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),R.multiplyByPoint(e,ae,ae),i.pack(ae,r,a)}function P(e,t){if(c(t))for(var r=t.values,n=r.length,a=0;a<n;a+=3)i.unpack(r,a,ae),T.multiplyByVector(e,ae,ae),ae=i.normalize(ae,ae),i.pack(ae,r,a)}function D(e,t){var r,n=e.length,i={},a=e[0][t].attributes;for(r in a)if(a.hasOwnProperty(r)&&c(a[r])&&c(a[r].values)){for(var o=a[r],s=o.values.length,l=!0,f=1;f<n;++f){var h=e[f][t].attributes[r];if(!c(h)||o.componentDatatype!==h.componentDatatype||o.componentsPerAttribute!==h.componentsPerAttribute||o.normalize!==h.normalize){l=!1;break}s+=h.values.length}l&&(i[r]=new p({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return i}function U(e,t){var n,a,o,u,s,l,f,h=e.length,p=(e[0].modelMatrix,c(e[0][t].indices)),m=e[0][t].primitiveType,E=D(e,t);for(n in E)if(E.hasOwnProperty(n))for(s=E[n].values,u=0,a=0;a<h;++a)for(l=e[a][t].attributes[n].values,f=l.length,o=0;o<f;++o)s[u++]=l[o];var _;if(p){var v=0;for(a=0;a<h;++a)v+=e[a][t].indices.length;var T=d.computeNumberOfVertices(new d({attributes:E,primitiveType:g.POINTS})),R=y.createTypedArray(T,v),A=0,S=0;for(a=0;a<h;++a){var w=e[a][t].indices,O=w.length;for(u=0;u<O;++u)R[A++]=S+w[u];S+=d.computeNumberOfVertices(e[a][t])}_=R}var N,I=new i,x=0;for(a=0;a<h;++a){if(N=e[a][t].boundingSphere,!c(N)){I=void 0;break}i.add(N.center,I,I)}if(c(I))for(i.divideByScalar(I,h,I),a=0;a<h;++a){N=e[a][t].boundingSphere;var M=i.magnitude(i.subtract(N.center,I,se))+N.radius;M>x&&(x=M)}return new d({attributes:E,indices:_,primitiveType:m,boundingSphere:c(I)?new r(I,x):void 0})}function b(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function L(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,3*(t-2));r[0]=1,r[1]=0,r[2]=2;for(var n=3,i=3;i<t;++i)r[n++]=i-1,r[n++]=0,r[n++]=i;return e.indices=r,e.primitiveType=g.TRIANGLES,e}function F(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,3*(t-2));r[0]=0,r[1]=1,r[2]=2,t>3&&(r[3]=0,r[4]=2,r[5]=3);for(var n=6,i=3;i<t-1;i+=2)r[n++]=i,r[n++]=i-1,r[n++]=i+1,i+2<t&&(r[n++]=i,r[n++]=i+1,r[n++]=i+2);return e.indices=r,e.primitiveType=g.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,t),n=0;n<t;++n)r[n]=n;return e.indices=r,e}function z(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,2*(t-1));r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return e.indices=r,e.primitiveType=g.LINES,e}function q(e){var t=d.computeNumberOfVertices(e),r=y.createTypedArray(t,2*t);r[0]=0,r[1]=1;for(var n=2,i=2;i<t;++i)r[n++]=i-1,r[n++]=i;return r[n++]=t-1,r[n]=0,e.indices=r,e.primitiveType=g.LINES,e}function G(e){switch(e.primitiveType){case g.TRIANGLE_FAN:return L(e);case g.TRIANGLE_STRIP:return F(e);case g.TRIANGLES:return b(e);case g.LINE_STRIP:return z(e);case g.LINE_LOOP:return q(e);case g.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<v.EPSILON6&&(e.y=t?-v.EPSILON6:v.EPSILON6)}function W(e,t,r){if(0!==e.y&&0!==t.y&&0!==r.y)return V(e,e.y<0),V(t,t.y<0),void V(r,r.y<0);var n,i=Math.abs(e.y),a=Math.abs(t.y),o=Math.abs(r.y);n=i>a?i>o?v.sign(e.y):v.sign(r.y):a>o?v.sign(t.y):v.sign(r.y);var u=n<0;V(e,u),V(t,u),V(r,u)}function X(e,t,r,n){i.add(e,i.multiplyByScalar(i.subtract(t,e,Re),e.y/(e.y-t.y),Re),r),i.clone(r,n),V(r,!0),V(n,!1)}function H(e,t,r){if(!(e.x>=0||t.x>=0||r.x>=0)){W(e,t,r);var n=e.y<0,i=t.y<0,a=r.y<0,o=0;o+=n?1:0,o+=i?1:0,o+=a?1:0;var u=Oe.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,n?(X(e,t,Ae,Se),X(e,r,ge,we),u[0]=0,u[3]=1,u[4]=2,u[6]=1):i?(X(t,r,Ae,Se),X(t,e,ge,we),u[0]=1,u[3]=2,u[4]=0,u[6]=2):a&&(X(r,e,Ae,Se),X(r,t,ge,we),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,n?i?a||(X(r,e,Ae,Se),X(r,t,ge,we),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(X(t,r,Ae,Se),X(t,e,ge,we),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(X(e,t,Ae,Se),X(e,r,ge,we),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Oe.positions;return s[0]=e,s[1]=t,s[2]=r,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=ge,s[5]=Se,s[6]=we,s.length=7),Oe}}function k(e,t){var n=e.attributes;if(0!==n.position.values.length){for(var i in n)if(n.hasOwnProperty(i)&&c(n[i])&&c(n[i].values)){var a=n[i];a.values=u.createTypedArray(a.componentDatatype,a.values)}var o=d.computeNumberOfVertices(e);return e.indices=y.createTypedArray(o,e.indices),t&&(e.boundingSphere=r.fromVertices(n.position.values)),e}}function Y(e){var t=e.attributes,r={};for(var n in t)if(t.hasOwnProperty(n)&&c(t[n])&&c(t[n].values)){var i=t[n];r[n]=new p({componentDatatype:i.componentDatatype,componentsPerAttribute:i.componentsPerAttribute,normalize:i.normalize,values:[]})}return new d({attributes:r,indices:[],primitiveType:e.primitiveType})}function j(e,t,r){var n=c(e.geometry.boundingSphere);t=k(t,n),r=k(r,n),c(r)&&!c(t)?e.geometry=r:!c(r)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=r,e.geometry=void 0)}function Z(e,r,a,o,u,s,l,f,h,d,p,m){if(c(s)||c(l)||c(f)||c(h)||c(d)){var y=i.fromArray(u,3*e,Ne),E=i.fromArray(u,3*r,Ie),_=i.fromArray(u,3*a,xe),v=t(o,y,E,_,Me);if(c(s)){var T=i.fromArray(s,3*e,Ne),R=i.fromArray(s,3*r,Ie),A=i.fromArray(s,3*a,xe);i.multiplyByScalar(T,v.x,T),i.multiplyByScalar(R,v.y,R),i.multiplyByScalar(A,v.z,A);var g=i.add(T,R,T);i.add(g,A,g),i.normalize(g,g),i.pack(g,p.normal.values,3*m)}if(c(d)){var S=i.fromArray(d,3*e,Ne),w=i.fromArray(d,3*r,Ie),O=i.fromArray(d,3*a,xe);i.multiplyByScalar(S,v.x,S),i.multiplyByScalar(w,v.y,w),i.multiplyByScalar(O,v.z,O);var N;i.equals(S,i.ZERO)&&i.equals(w,i.ZERO)&&i.equals(O,i.ZERO)?(N=Ne,N.x=0,N.y=0,N.z=0):(N=i.add(S,w,S),i.add(N,O,N),i.normalize(N,N)),i.pack(N,p.extrudeDirection.values,3*m)}if(c(l)){var I=i.fromArray(l,3*e,Ne),x=i.fromArray(l,3*r,Ie),M=i.fromArray(l,3*a,xe);i.multiplyByScalar(I,v.x,I),i.multiplyByScalar(x,v.y,x),i.multiplyByScalar(M,v.z,M);var C=i.add(I,x,I);i.add(C,M,C),i.normalize(C,C),i.pack(C,p.tangent.values,3*m)}if(c(f)){var P=i.fromArray(f,3*e,Ne),D=i.fromArray(f,3*r,Ie),U=i.fromArray(f,3*a,xe);i.multiplyByScalar(P,v.x,P),i.multiplyByScalar(D,v.y,D),i.multiplyByScalar(U,v.z,U);var b=i.add(P,D,P);i.add(b,U,b),i.normalize(b,b),i.pack(b,p.bitangent.values,3*m)}if(c(h)){var L=n.fromArray(h,2*e,Ce),F=n.fromArray(h,2*r,Pe),B=n.fromArray(h,2*a,De);n.multiplyByScalar(L,v.x,L),n.multiplyByScalar(F,v.y,F),n.multiplyByScalar(B,v.z,B);var z=n.add(L,F,L);n.add(z,B,z),n.pack(z,p.st.values,2*m)}}}function K(e,t,r,n,i,a){var o=e.position.values.length/3;if(-1!==i){var u=n[i],s=r[u];return-1===s?(r[u]=o,e.position.values.push(a.x,a.y,a.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(a.x,a.y,a.z),t.push(o),o}function J(e){var t,r,n,a,o,u=e.geometry,s=u.attributes,l=s.position.values,f=c(s.normal)?s.normal.values:void 0,h=c(s.bitangent)?s.bitangent.values:void 0,d=c(s.tangent)?s.tangent.values:void 0,p=c(s.st)?s.st.values:void 0,m=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,y=u.indices,E=Y(u),_=Y(u),v=[];v.length=l.length/3;var T=[];for(T.length=l.length/3,o=0;o<v.length;++o)v[o]=-1,T[o]=-1;var R=y.length;for(o=0;o<R;o+=3){var A=y[o],g=y[o+1],S=y[o+2],w=i.fromArray(l,3*A),O=i.fromArray(l,3*g),N=i.fromArray(l,3*S),I=H(w,O,N);if(c(I)&&I.positions.length>3)for(var x=I.positions,M=I.indices,C=M.length,P=0;P<C;++P){var D=M[P],U=x[D];U.y<0?(t=_.attributes,r=_.indices,n=v):(t=E.attributes,r=E.indices,n=T),a=K(t,r,n,y,D<3?o+D:-1,U),Z(A,g,S,U,l,f,d,h,p,m,t,a)}else c(I)&&(w=I.positions[0],O=I.positions[1],N=I.positions[2]),w.y<0?(t=_.attributes,r=_.indices,n=v):(t=E.attributes,r=E.indices,n=T),a=K(t,r,n,y,o,w),Z(A,g,S,w,l,f,d,h,p,m,t,a),a=K(t,r,n,y,o+1,O),Z(A,g,S,O,l,f,d,h,p,m,t,a),a=K(t,r,n,y,o+2,N),Z(A,g,S,N,l,f,d,h,p,m,t,a)}j(e,_,E)}function Q(e){var t,r=e.geometry,n=r.attributes,a=n.position.values,o=r.indices,u=Y(r),s=Y(r),l=o.length,f=[];f.length=a.length/3;var h=[];for(h.length=a.length/3,t=0;t<f.length;++t)f[t]=-1,h[t]=-1;for(t=0;t<l;t+=2){var d=o[t],p=o[t+1],m=i.fromArray(a,3*d,Ne),y=i.fromArray(a,3*p,Ie);Math.abs(m.y)<v.EPSILON6&&(m.y<0?m.y=-v.EPSILON6:m.y=v.EPSILON6),Math.abs(y.y)<v.EPSILON6&&(y.y<0?y.y=-v.EPSILON6:y.y=v.EPSILON6);var E=u.attributes,T=u.indices,R=h,A=s.attributes,g=s.indices,S=f,w=_.lineSegmentPlane(m,y,Ue,xe);if(c(w)){var O=i.multiplyByScalar(i.UNIT_Y,5*v.EPSILON9,be);m.y<0&&(i.negate(O,O),E=s.attributes,T=s.indices,R=f,A=u.attributes,g=u.indices,S=h);var N=i.add(w,O,Le);K(E,T,R,o,t,m),K(E,T,R,o,-1,N),i.negate(O,O),i.add(w,O,N),K(A,g,S,o,-1,N),K(A,g,S,o,t+1,y)}else{var I,x,M;m.y<0?(I=s.attributes,x=s.indices,M=f):(I=u.attributes,x=u.indices,M=h),K(I,x,M,o,t,m),K(I,x,M,o,t+1,y)}}j(e,s,u)}function $(e){for(var t=e.attributes,r=t.position.values,n=t.prevPosition.values,a=t.nextPosition.values,o=r.length,u=0;u<o;u+=3){var s=i.unpack(r,u,ze);if(!(s.x>0)){var c=i.unpack(n,u,qe);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(n[u]=r[u-3],n[u+1]=r[u-2],n[u+2]=r[u-1]):i.pack(s,n,u));var l=i.unpack(a,u,Ge);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(a[u]=r[u+3],a[u+1]=r[u+4],a[u+2]=r[u+5]):i.pack(s,a,u))}}}function ee(e){var t,r,o,u=e.geometry,s=u.attributes,l=s.position.values,f=s.prevPosition.values,h=s.nextPosition.values,d=s.expandAndWidth.values,p=c(s.st)?s.st.values:void 0,m=c(s.color)?s.color.values:void 0,y=Y(u),E=Y(u),T=!1,R=l.length/3;for(t=0;t<R;t+=4){var A=t,g=t+2,S=i.fromArray(l,3*A,ze),w=i.fromArray(l,3*g,qe);if(Math.abs(S.y)<Ye)for(S.y=Ye*(w.y<0?-1:1),l[3*t+1]=S.y,l[3*(t+1)+1]=S.y,r=3*A;r<3*A+12;r+=3)f[r]=l[3*t],f[r+1]=l[3*t+1],f[r+2]=l[3*t+2];if(Math.abs(w.y)<Ye)for(w.y=Ye*(S.y<0?-1:1),l[3*(t+2)+1]=w.y,l[3*(t+3)+1]=w.y,r=3*A;r<3*A+12;r+=3)h[r]=l[3*(t+2)],h[r+1]=l[3*(t+2)+1],h[r+2]=l[3*(t+2)+2];var O=y.attributes,N=y.indices,I=E.attributes,x=E.indices,M=_.lineSegmentPlane(S,w,Ue,Ve);if(c(M)){T=!0;var C=i.multiplyByScalar(i.UNIT_Y,ke,We);S.y<0&&(i.negate(C,C),O=E.attributes,N=E.indices,I=y.attributes,x=y.indices);var P=i.add(M,C,Xe);O.position.values.push(S.x,S.y,S.z,S.x,S.y,S.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.prevPosition.values.push(f[3*A],f[3*A+1],f[3*A+2]),O.prevPosition.values.push(f[3*A+3],f[3*A+4],f[3*A+5]),O.prevPosition.values.push(S.x,S.y,S.z,S.x,S.y,S.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(P.x,P.y,P.z),i.negate(C,C),i.add(M,C,P),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(w.x,w.y,w.z,w.x,w.y,w.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.prevPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(w.x,w.y,w.z,w.x,w.y,w.z),I.nextPosition.values.push(h[3*g],h[3*g+1],h[3*g+2]),I.nextPosition.values.push(h[3*g+3],h[3*g+4],h[3*g+5]);var D=n.fromArray(d,2*A,Fe),U=Math.abs(D.y);O.expandAndWidth.values.push(-1,U,1,U),O.expandAndWidth.values.push(-1,-U,1,-U),I.expandAndWidth.values.push(-1,U,1,U),I.expandAndWidth.values.push(-1,-U,1,-U);var b=i.magnitudeSquared(i.subtract(M,S,Ge));if(b/=i.magnitudeSquared(i.subtract(w,S,Ge)),c(m)){var L=a.fromArray(m,4*A,He),F=a.fromArray(m,4*g,He),B=v.lerp(L.x,F.x,b),z=v.lerp(L.y,F.y,b),q=v.lerp(L.z,F.z,b),G=v.lerp(L.w,F.w,b);for(r=4*A;r<4*A+8;++r)O.color.values.push(m[r]);for(O.color.values.push(B,z,q,G),O.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),I.color.values.push(B,z,q,G),r=4*g;r<4*g+8;++r)I.color.values.push(m[r])}if(c(p)){var V=n.fromArray(p,2*A,Fe),W=n.fromArray(p,2*(t+3),Be),X=v.lerp(V.x,W.x,b);for(r=2*A;r<2*A+4;++r)O.st.values.push(p[r]);for(O.st.values.push(X,V.y),O.st.values.push(X,W.y),I.st.values.push(X,V.y),I.st.values.push(X,W.y),r=2*g;r<2*g+4;++r)I.st.values.push(p[r])}o=O.position.values.length/3-4,N.push(o,o+2,o+1),N.push(o+1,o+2,o+3),o=I.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3)}else{var H,k;for(S.y<0?(H=E.attributes,k=E.indices):(H=y.attributes,k=y.indices),H.position.values.push(S.x,S.y,S.z),H.position.values.push(S.x,S.y,S.z),H.position.values.push(w.x,w.y,w.z),H.position.values.push(w.x,w.y,w.z),r=3*t;r<3*t+12;++r)H.prevPosition.values.push(f[r]),H.nextPosition.values.push(h[r]);for(r=2*t;r<2*t+8;++r)H.expandAndWidth.values.push(d[r]),c(p)&&H.st.values.push(p[r]);if(c(m))for(r=4*t;r<4*t+16;++r)H.color.values.push(m[r]);o=H.position.values.length/3-4,k.push(o,o+2,o+1),k.push(o+1,o+2,o+3)}}T&&($(E),$(y)),j(e,E,y)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case g.TRIANGLES:e.indices=O(t);break;case g.TRIANGLE_STRIP:e.indices=N(t);break;case g.TRIANGLE_FAN:e.indices=I(t)}e.primitiveType=g.LINES}return e},te.createLineSegmentsForVectors=function(e,t,n){t=s(t,"normal"),n=s(n,1e4);for(var i=e.attributes.position.values,a=e.attributes[t].values,o=i.length,l=new Float64Array(2*o),f=0,h=0;h<o;h+=3)l[f++]=i[h],l[f++]=i[h+1],l[f++]=i[h+2],l[f++]=i[h]+a[h]*n,l[f++]=i[h+1]+a[h+1]*n,l[f++]=i[h+2]+a[h+2]*n;var m,y=e.boundingSphere;return c(y)&&(m=new r(y.center,y.radius+n)),new d({attributes:{position:new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:g.LINES,boundingSphere:m})},te.createAttributeLocations=function(e){var t,r=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],n=e.attributes,i={},a=0,o=r.length;for(t=0;t<o;++t){var u=r[t];c(n[u])&&(i[u]=a++)}for(var s in n)n.hasOwnProperty(s)&&!c(i[s])&&(i[s]=a++);return i},te.reorderForPreVertexCache=function(e){var t=d.computeNumberOfVertices(e),r=e.indices;if(c(r)){for(var n=new Int32Array(t),i=0;i<t;i++)n[i]=-1;for(var a,o=r,s=o.length,l=y.createTypedArray(t,s),f=0,h=0,p=0;f<s;)a=n[o[f]],-1!==a?l[h]=a:(a=o[f],n[a]=p,l[h]=p,++p),++f,++h;e.indices=l;var m=e.attributes;for(var E in m)if(m.hasOwnProperty(E)&&c(m[E])&&c(m[E].values)){for(var _=m[E],v=_.values,T=0,R=_.componentsPerAttribute,A=u.createTypedArray(_.componentDatatype,p*R);T<t;){var g=n[T];if(-1!==g)for(var S=0;S<R;S++)A[R*g+S]=v[R*T+S];++T}_.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var r=e.indices;if(e.primitiveType===g.TRIANGLES&&c(r)){for(var n=r.length,i=0,a=0;a<n;a++)r[a]>i&&(i=r[a]);e.indices=S.tipsify({indices:r,maximumIndex:i,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],r=d.computeNumberOfVertices(e);if(c(e.indices)&&r>=v.SIXTY_FOUR_KILOBYTES){var n,i=[],a=[],o=0,u=x(e.attributes),s=e.indices,l=s.length;e.primitiveType===g.TRIANGLES?n=3:e.primitiveType===g.LINES?n=2:e.primitiveType===g.POINTS&&(n=1);for(var f=0;f<l;f+=n){for(var h=0;h<n;++h){var p=s[f+h],m=i[p];c(m)||(m=o++,i[p]=m,M(u,e.attributes,p)),a.push(m)}o+n>=v.SIXTY_FOUR_KILOBYTES&&(t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),i=[],a=[],o=0,u=x(e.attributes))}0!==a.length&&t.push(new d({attributes:u,indices:a,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var re=new i,ne=new o;te.projectTo2D=function(e,t,r,n,a){var o=e.attributes[t];a=c(a)?a:new h;for(var s=a.ellipsoid,l=o.values,f=new Float64Array(l.length),d=0,m=0;m<l.length;m+=3){var y=i.fromArray(l,m,re),E=s.cartesianToCartographic(y,ne),_=a.project(E,re);f[d++]=_.x,f[d++]=_.y,f[d++]=_.z}return e.attributes[r]=o,e.attributes[n]=new p({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:f}),delete e.attributes[t],e};var ie={high:0,low:0};te.encodeAttribute=function(e,t,r,n){for(var i=e.attributes[t],a=i.values,o=a.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)f.encode(a[l],ie),s[l]=ie.high,c[l]=ie.low;var h=i.componentsPerAttribute;return e.attributes[r]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:s}),e.attributes[n]=new p({componentDatatype:u.FLOAT,componentsPerAttribute:h,values:c}),delete e.attributes[t],e};var ae=new i,oe=new R,ue=new T;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(R.equals(t,R.IDENTITY))return e;var n=e.geometry.attributes;C(t,n.position),C(t,n.prevPosition),C(t,n.nextPosition),(c(n.normal)||c(n.tangent)||c(n.bitangent))&&(R.inverse(t,oe),R.transpose(oe,oe),R.getRotation(oe,ue),P(ue,n.normal),P(ue,n.tangent),P(ue,n.bitangent));var i=e.geometry.boundingSphere;return c(i)&&(e.geometry.boundingSphere=r.transform(i,t,i)),e.modelMatrix=R.clone(R.IDENTITY),e};var se=new i;te.combineInstances=function(e){for(var t=[],r=[],n=e.length,i=0;i<n;++i){var a=e[i];c(a.geometry)?t.push(a):c(a.westHemisphereGeometry)&&c(a.eastHemisphereGeometry)&&r.push(a)}var o=[];return t.length>0&&o.push(U(t,"geometry")),r.length>0&&(o.push(U(r,"westHemisphereGeometry")),o.push(U(r,"eastHemisphereGeometry"))),o};var ce=new i,le=new i,fe=new i,he=new i;te.computeNormal=function(e){var t,r=e.indices,n=e.attributes,a=n.position.values,o=n.position.values.length/3,s=r.length,c=new Array(o),l=new Array(s/3),f=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var h=0;for(t=0;t<s;t+=3){var d=r[t],m=r[t+1],y=r[t+2],E=3*d,_=3*m,T=3*y;le.x=a[E],le.y=a[E+1],le.z=a[E+2],fe.x=a[_],fe.y=a[_+1],fe.z=a[_+2],he.x=a[T],he.y=a[T+1],he.z=a[T+2],c[d].count++,c[m].count++,c[y].count++,i.subtract(fe,le,fe),i.subtract(he,le,he),l[h]=i.cross(fe,he,new i),h++}var R=0;for(t=0;t<o;t++)c[t].indexOffset+=R,R+=c[t].count;h=0;var A;for(t=0;t<s;t+=3){A=c[r[t]];var g=A.indexOffset+A.currentCount;f[g]=h,A.currentCount++,A=c[r[t+1]],g=A.indexOffset+A.currentCount,f[g]=h,A.currentCount++,A=c[r[t+2]],g=A.indexOffset+A.currentCount,f[g]=h,A.currentCount++,h++}var S=new Float32Array(3*o);for(t=0;t<o;t++){var w=3*t;if(A=c[t],i.clone(i.ZERO,ce),A.count>0){for(h=0;h<A.count;h++)i.add(ce,l[f[A.indexOffset+h]],ce);i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&i.clone(l[f[A.indexOffset]],ce)}i.equalsEpsilon(i.ZERO,ce,v.EPSILON10)&&(ce.z=1),i.normalize(ce,ce),S[w]=ce.x,S[w+1]=ce.y,S[w+2]=ce.z}return e.attributes.normal=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:S}),e};var de=new i,pe=new i,me=new i;te.computeTangentAndBitangent=function(e){var t,r=(e.attributes,e.indices),n=e.attributes.position.values,a=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=r.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var f,h,d;for(t=0;t<c;t+=3){var m=r[t],y=r[t+1],E=r[t+2];f=3*m,h=3*y,d=3*E;var _=2*m,v=2*y,T=2*E,R=n[f],A=n[f+1],g=n[f+2],S=o[_],w=o[_+1],O=o[v+1]-w,N=o[T+1]-w,I=1/((o[v]-S)*N-(o[T]-S)*O),x=(N*(n[h]-R)-O*(n[d]-R))*I,M=(N*(n[h+1]-A)-O*(n[d+1]-A))*I,C=(N*(n[h+2]-g)-O*(n[d+2]-g))*I;l[f]+=x,l[f+1]+=M,l[f+2]+=C,l[h]+=x,l[h+1]+=M,l[h+2]+=C,l[d]+=x,l[d+1]+=M,l[d+2]+=C}var P=new Float32Array(3*s),D=new Float32Array(3*s);for(t=0;t<s;t++){f=3*t,h=f+1,d=f+2;var U=i.fromArray(a,f,de),b=i.fromArray(l,f,me),L=i.dot(U,b);i.multiplyByScalar(U,L,pe),i.normalize(i.subtract(b,pe,b),b),P[f]=b.x,P[h]=b.y,P[d]=b.z,i.normalize(i.cross(U,b,b),b),D[f]=b.x,D[h]=b.y,D[d]=b.z} +return e.attributes.tangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new p({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:D}),e};var ye=new n,Ee=new i,_e=new i,ve=new i,Te=new n;te.compressVertices=function(t){var r,a,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;a=s.length/3;var l=new Float32Array(2*a),f=0;for(r=0;r<a;++r)i.fromArray(s,3*r,Ee),i.equals(Ee,i.ZERO)?f+=2:(Te=e.octEncodeInRange(Ee,65535,Te),l[f++]=Te.x,l[f++]=Te.y);return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var h=t.attributes.normal,d=t.attributes.st,m=c(h),y=c(d);if(!m&&!y)return t;var E,_,v,T,R=t.attributes.tangent,A=t.attributes.bitangent,g=c(R),S=c(A);m&&(E=h.values),y&&(_=d.values),g&&(v=R.values),S&&(T=A.values),a=(m?E.length:_.length)/(m?3:2);var w=a,O=y&&m?2:1;O+=g||S?1:0,w*=O;var N=new Float32Array(w),I=0;for(r=0;r<a;++r){y&&(n.fromArray(_,2*r,ye),N[I++]=e.compressTextureCoordinates(ye));var x=3*r;m&&c(v)&&c(T)?(i.fromArray(E,x,Ee),i.fromArray(v,x,_e),i.fromArray(T,x,ve),e.octPack(Ee,_e,ve,ye),N[I++]=ye.x,N[I++]=ye.y):(m&&(i.fromArray(E,x,Ee),N[I++]=e.octEncodeFloat(Ee)),g&&(i.fromArray(v,x,Ee),N[I++]=e.octEncodeFloat(Ee)),S&&(i.fromArray(T,x,Ee),N[I++]=e.octEncodeFloat(Ee)))}return t.attributes.compressedAttributes=new p({componentDatatype:u.FLOAT,componentsPerAttribute:O,values:N}),m&&delete t.attributes.normal,y&&delete t.attributes.st,S&&delete t.attributes.bitangent,g&&delete t.attributes.tangent,t};var Re=new i,Ae=new i,ge=new i,Se=new i,we=new i,Oe={positions:new Array(7),indices:new Array(9)},Ne=new i,Ie=new i,xe=new i,Me=new i,Ce=new n,Pe=new n,De=new n,Ue=A.fromPointNormal(i.ZERO,i.UNIT_Y),be=new i,Le=new i,Fe=new n,Be=new n,ze=new i,qe=new i,Ge=new i,Ve=new i,We=new i,Xe=new i,He=new a,ke=5*v.EPSILON9,Ye=v.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,n=t.boundingSphere;if(c(n)){if(n.center.x-n.radius>0||r.intersectPlane(n,A.ORIGIN_ZX_PLANE)!==E.INTERSECTING)return e}if(t.geometryType!==m.NONE)switch(t.geometryType){case m.POLYLINES:ee(e);break;case m.TRIANGLES:J(e);break;case m.LINES:Q(e)}else G(t),t.primitiveType===g.TRIANGLES?J(e):t.primitiveType===g.LINES&&Q(e);return e},te}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){t(i[r])||(i[r]=!0,console.warn(e(n,r)))}var i={};return n.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",n}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,r,i){i=i||2;var a=r&&r.length,o=a?r[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,p,m,y;if(a&&(u=s(e,r,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var E=i;E<o;E+=i)p=e[E],m=e[E+1],p<l&&(l=p),m<f&&(f=m),p>h&&(h=p),m>d&&(d=m);y=Math.max(h-l,d-f)}return n(u,c,i,l,f,y),c}function t(e,t,r,n,i){var a,o;if(i===I(e,t,r,n)>0)for(a=t;a<r;a+=n)o=w(a,e[a],e[a+1],o);else for(a=r-n;a>=t;a-=n)o=w(a,e[a],e[a+1],o);return o&&v(o,o.next)&&(O(o),o=o.next),o}function r(e,t){if(!e)return e;t||(t=e);var r,n=e;do{if(r=!1,n.steiner||!v(n,n.next)&&0!==_(n.prev,n,n.next))n=n.next;else{if(O(n),(n=t=n.prev)===n.next)return null;r=!0}}while(r||n!==t);return t}function n(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var p,m,y=e;e.prev!==e.next;)if(p=e.prev,m=e.next,f?a(e,c,l,f):i(e))t.push(p.i/s),t.push(e.i/s),t.push(m.i/s),O(e),e=m.next,y=m.next;else if((e=m)===y){d?1===d?(e=o(e,t,s),n(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):n(r(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,r=e,n=e.next;if(_(t,r,n)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(y(t.x,t.y,r.x,r.y,n.x,n.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,r,n){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=p(u,s,t,r,n),h=p(c,l,t,r,n),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&y(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&y(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,r){var n=e;do{var i=n.prev,a=n.next.next;!v(i,a)&&T(i,n,n.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/r),t.push(n.i/r),t.push(a.i/r),O(n),O(n.next),n=e=a),n=n.next}while(n!==e);return n}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&E(s,c)){var l=S(s,c);return s=r(s,s.next),l=r(l,l.next),n(s,t,i,a,o,u),void n(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,n,i,a){var o,u,s,f,h,d=[];for(o=0,u=n.length;o<u;o++)s=n[o]*a,f=o<u-1?n[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=r(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var n=S(t,e);r(n,n.next)}}function f(e,t){var r,n=t,i=e.x,a=e.y,o=-1/0;do{if(a<=n.y&&a>=n.next.y){var u=n.x+(a-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(u<=i&&u>o){if(o=u,u===i){if(a===n.y)return n;if(a===n.next.y)return n.next}r=n.x<n.next.x?n:n.next}}n=n.next}while(n!==t);if(!r)return null;if(i===o)return r.prev;var s,c=r,l=r.x,f=r.y,h=1/0;for(n=r.next;n!==c;)i>=n.x&&n.x>=l&&y(a<f?i:o,a,l,f,a<f?o:i,a,n.x,n.y)&&((s=Math.abs(a-n.y)/(i-n.x))<h||s===h&&n.x>r.x)&&A(n,e)&&(r=n,h=s),n=n.next;return r}function h(e,t,r,n){var i=e;do{null===i.z&&(i.z=p(i.x,i.y,t,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,r,n,i,a,o,u,s,c=1;do{for(r=e,e=null,a=null,o=0;r;){for(o++,n=r,u=0,t=0;t<c&&(u++,n=n.nextZ);t++);for(s=c;u>0||s>0&&n;)0===u?(i=n,n=n.nextZ,s--):0!==s&&n?r.z<=n.z?(i=r,r=r.nextZ,u--):(i=n,n=n.nextZ,s--):(i=r,r=r.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;r=n}a.nextZ=null,c*=2}while(o>1);return e}function p(e,t,r,n,i){return e=32767*(e-r)/i,t=32767*(t-n)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,r=e;do{t.x<r.x&&(r=t),t=t.next}while(t!==e);return r}function y(e,t,r,n,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(n-u)-(r-o)*(t-u)>=0&&(r-o)*(a-u)-(i-o)*(n-u)>=0}function E(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!R(e,t)&&A(e,t)&&A(t,e)&&g(e,t)}function _(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function v(e,t){return e.x===t.x&&e.y===t.y}function T(e,t,r,n){return!!(v(e,t)&&v(r,n)||v(e,n)&&v(r,t))||_(e,t,r)>0!=_(e,t,n)>0&&_(r,n,e)>0!=_(r,n,t)>0}function R(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&T(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function g(e,t){var r=e,n=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{r.y>a!=r.next.y>a&&i<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==e);return n}function S(e,t){var r=new N(e.i,e.x,e.y),n=new N(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,r.next=i,i.prev=r,n.next=r,r.prev=n,a.next=n,n.prev=a,n}function w(e,t,r,n){var i=new N(e,t,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function N(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function I(e,t,r,n){for(var i=0,a=t,o=r-n;a<r;a+=n)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,r,n){var i=t&&t.length,a=i?t[0]*r:e.length,o=Math.abs(I(e,0,a,r));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*r,l=u<s-1?t[u+1]*r:e.length;o-=Math.abs(I(e,c,l,r))}var f=0;for(u=0;u<n.length;u+=3){var h=n[u]*r,d=n[u+1]*r,p=n[u+2]*r;f+=Math.abs((e[h]-e[p])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[p+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,r={vertices:[],holes:[],dimensions:t},n=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)r.vertices.push(e[i][a][o]);i>0&&(n+=e[i-1].length,r.holes.push(n))}return r},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===r.CLOCKWISE||e===r.COUNTER_CLOCKWISE}};return e(r)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h){"use strict";var d=new r,p=new r,m={};m.computeArea2D=function(e){for(var t=e.length,r=0,n=t-1,i=0;i<t;n=i++){var a=e[n],o=e[i];r+=a.x*o.y-o.x*a.y}return.5*r},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(r,n){var i=t.packArray(r);return e(i,n,2)};var y=new r,E=new r,_=new r,v=new r,T=new r,R=new r,A=new r;return m.computeSubdivision=function(e,t,n,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=n.slice(0),p=t.length,m=new Array(3*p),g=0;for(h=0;h<p;h++){var S=t[h];m[g++]=S.x,m[g++]=S.y,m[g++]=S.z}for(var w=[],O={},N=e.maximumRadius,I=l.chordLength(u,N),x=I*I;d.length>0;){var M,C,P=d.pop(),D=d.pop(),U=d.pop(),b=r.fromArray(m,3*U,y),L=r.fromArray(m,3*D,E),F=r.fromArray(m,3*P,_),B=r.multiplyByScalar(r.normalize(b,v),N,v),z=r.multiplyByScalar(r.normalize(L,T),N,T),q=r.multiplyByScalar(r.normalize(F,R),N,R),G=r.magnitudeSquared(r.subtract(B,z,A)),V=r.magnitudeSquared(r.subtract(z,q,A)),W=r.magnitudeSquared(r.subtract(q,B,A)),X=Math.max(G,V,W);X>x?G===X?(M=Math.min(U,D)+" "+Math.max(U,D),h=O[M],o(h)||(C=r.add(b,L,A),r.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(U,h,P),d.push(h,D,P)):V===X?(M=Math.min(D,P)+" "+Math.max(D,P),h=O[M],o(h)||(C=r.add(L,F,A),r.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(D,h,U),d.push(h,P,U)):W===X&&(M=Math.min(P,U)+" "+Math.max(P,U),h=O[M],o(h)||(C=r.add(F,b,A),r.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,O[M]=h),d.push(P,h,D),d.push(h,U,D)):(w.push(U),w.push(D),w.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:m})},indices:w,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,n,i){n=a(n,u.WGS84);var s=d,c=p;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)r.fromArray(e,f,c),i&&(c=n.scaleToGeodeticSurface(c,c)),0!==t&&(s=n.geodeticSurfaceNormal(c,s),r.multiplyByScalar(s,t,s),r.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,r,n,i){"use strict";function a(t,i,a){this.minimum=e.clone(r(t,e.ZERO)),this.maximum=e.clone(r(i,e.ZERO)),n(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,r){if(n(r)||(r=new a),!n(t)||0===t.length)return r.minimum=e.clone(e.ZERO,r.minimum),r.maximum=e.clone(e.ZERO,r.maximum),r.center=e.clone(e.ZERO,r.center),r;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],p=d.x,m=d.y,y=d.z;i=Math.min(p,i),s=Math.max(p,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(y,u),l=Math.max(y,l)}var E=r.minimum;E.x=i,E.y=o,E.z=u;var _=r.maximum;_.x=s,_.y=c,_.z=l;var v=e.add(E,_,r.center);return e.multiplyByScalar(v,.5,v),r},a.clone=function(t,r){if(n(t))return n(r)?(r.minimum=e.clone(t.minimum,r.minimum),r.maximum=e.clone(t.maximum,r.maximum),r.center=e.clone(t.center,r.center),r):new a(t.minimum,t.maximum)},a.equals=function(t,r){return t===r||n(t)&&n(r)&&e.equals(t.center,r.center)&&e.equals(t.minimum,r.minimum)&&e.equals(t.maximum,r.maximum)};var o=new e;return a.intersectPlane=function(t,r){o=e.subtract(t.maximum,t.minimum,o);var n=e.multiplyByScalar(o,.5,o),a=r.normal,u=n.x*Math.abs(a.x)+n.y*Math.abs(a.y)+n.z*Math.abs(a.z),s=e.dot(t.center,a)+r.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,r,n,i){return t(e).then(r,n,i)}function t(e){var t,r;return e instanceof n?t=e:u(e)?(r=o(),e.then(function(e){r.resolve(e)},function(e){r.reject(e)},function(e){r.progress(e)}),t=r.promise):t=i(e),t}function r(t){return e(t,a)}function n(e){this.then=e}function i(e){return new n(function(r){try{return t(r?r(e):e)}catch(e){return a(e)}})}function a(e){return new n(function(r,n){try{return n?t(n(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,r){return h(e,t,r)}function r(e){return p(e)}function i(e){return p(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,p;return c=new n(e),s={then:e,resolve:r,reject:i,progress:u,promise:c,resolver:{resolve:r,reject:i,progress:u}},l=[],f=[],h=function(e,t,r){var n,i;return n=o(),i="function"==typeof r?function(e){try{n.progress(r(e))}catch(e){n.progress(e)}}:function(e){n.progress(e)},l.push(function(r){r.then(e,t).then(n.resolve,n.reject,i)}),f.push(i),n.promise},d=function(e){return m(f,e),e},p=function(e){return e=t(e),h=e.then,p=t,d=E,m(l,e),f=l=R,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,r,n,i,a){return y(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){p(e)}var c,l,f,h,d,p,m,y,_,v;if(_=t.length>>>0,c=Math.max(0,Math.min(r,_)),f=[],l=_-c+1,h=[],d=o(),c)for(y=d.progress,m=function(e){h.push(e),--l||(p=m=E,d.reject(h))},p=function(e){f.push(e),--c||(p=m=E,d.resolve(f))},v=0;v<_;++v)v in t&&e(t[v],s,u,y);else d.resolve(f);return d.then(n,i,a)})}function c(e,t,r,n){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,r,n)}function l(e,t,r,n){return y(1,arguments),h(e,_).then(t,r,n)}function f(){return h(arguments,_)}function h(t,r){return e(t,function(t){var n,i,a,u,s,c;if(a=i=t.length>>>0,n=[],c=o(),a)for(u=function(t,i){e(t,r).then(function(e){n[i]=e,--a||c.resolve(n)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(n);return c.promise})}function d(t,r){var n=T.call(arguments,1);return e(t,function(t){var i;return i=t.length,n[0]=function(t,n,a){return e(t,function(t){return e(n,function(e){return r(t,e,a,i)})})},v.apply(t,n)})}function p(t,r,n){var i=arguments.length>2;return e(t,function(e){return e=i?n:e,r.resolve(e),e},function(e){return r.reject(e),a(e)},r.progress)}function m(e,t){for(var r,n=0;r=e[n++];)r(t)}function y(e,t){for(var r,n=t.length;n>e;)if(null!=(r=t[--n])&&"function"!=typeof r)throw new Error("arg "+n+" must be a function")}function E(){}function _(e){return e}var v,T,R;return e.defer=o,e.resolve=t,e.reject=r,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=p,e.isPromise=u,n.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(R,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(R,t)})})}},T=[].slice,v=[].reduce||function(e){var t,r,n,i,a;if(a=0,t=Object(this),i=t.length>>>0,r=arguments,r.length<=1)for(;;){if(a in t){n=t[a++];break}if(++a>=i)throw new TypeError}else n=r[1];for(;a<i;++a)a in t&&(n=e(n,t[a],a,t));return n},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,r){for(var n,i,a=0,o=e.length-1;a<=o;)if(n=~~((a+o)/2),(i=r(e[n],t))<0)a=n+1;else{if(!(i>0))return n;o=n-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,r,n,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=r,this.yPoleOffset=n,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,r=0,n=t[r++],i=function(e,t,r,n){r||(r=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(r);return n?e+i:i+e},a=function(e,t,r,n,a,o){var u=n-e.length;return u>0&&(e=r||!a?i(e,n,o,r):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,r,n,o,u,s){var c=e>>>0;return r=r&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=r+i(c.toString(t),u||0,"0",!1),a(e,r,n,o,s)},u=function(e,t,r,n,i,o){return null!=n&&(e=e.slice(0,n)),a(e,"",t,r,i,o)},s=function(e,n,s,c,l,f,h){var d,p,m,y,E;if("%%"==e)return"%";for(var _=!1,v="",T=!1,R=!1,A=" ",g=s.length,S=0;s&&S<g;S++)switch(s.charAt(S)){case" ":v=" ";break;case"+":v="+";break;case"-":_=!0;break;case"'":A=s.charAt(S+1);break;case"0":T=!0;break;case"#":R=!0}if(c=c?"*"==c?+t[r++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[r++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,E=n?t[n.slice(0,-1)]:t[r++],h){case"s":return u(String(E),_,c,f,T,A);case"c":return u(String.fromCharCode(+E),_,c,f,T);case"b":return o(E,2,R,_,c,f,T);case"o":return o(E,8,R,_,c,f,T);case"x":return o(E,16,R,_,c,f,T);case"X":return o(E,16,R,_,c,f,T).toUpperCase();case"u":return o(E,10,R,_,c,f,T);case"i":case"d":return d=+E||0,d=Math.round(d-d%1),p=d<0?"-":v,E=p+i(String(Math.abs(d)),f,"0",!1),a(E,p,_,c,T);case"e":case"E":case"f":case"F":case"g":case"G":return d=+E,p=d<0?"-":v,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],y=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],E=p+Math.abs(d)[m](f),a(E,p,_,c,T)[y]();default:return e}};return n.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,r,n,i,a,o,u){this.year=e,this.month=t,this.day=r,this.hour=n,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);n<0&&(n=~n),n>=r.length&&(n=r.length-1);var i=r[n].offset;if(n>0){m.secondsDifference(r[n].julianDate,e)>i&&(n--,i=r[n].offset)}m.addSeconds(e,i,e)}function h(e,r){_.julianDate=e;var n=m.leapSeconds,i=t(n,_,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-n[0].offset,r);if(i>=n.length)return m.addSeconds(e,-n[i-1].offset,r);var a=m.secondsDifference(n[i].julianDate,e);return 0===a?m.addSeconds(e,-n[i].offset,r):a<=1?void 0:m.addSeconds(e,-n[--i].offset,r)}function d(e,t,r){var n=t/s.SECONDS_PER_DAY|0;return e+=n,t-=s.SECONDS_PER_DAY*n,t<0&&(e--,t+=s.SECONDS_PER_DAY),r.dayNumber=e,r.secondsOfDay=t,r}function p(e,t,r,n,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+r-32075;(n-=12)<0&&(n+=24);var f=a+(n*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,n){this.dayNumber=void 0,this.secondsOfDay=void 0,e=r(e,0),t=r(t,0),n=r(n,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),n===c.UTC&&f(this)}var y=new a,E=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,v=/^(\d{4})$/,T=/^(\d{4})-(\d{2})$/,R=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,g=/^(\d{4})-?(\d{2})-?(\d{2})$/,S=/([Z+\-])?(\d{2})?:?(\d{2})?$/,w=/^(\d{2})(\.\d+)?/.source+S.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+S.source,N=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+S.source;m.fromGregorianDate=function(e,t){var r=p(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromDate=function(e,t){var r=p(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return n(t)?(d(r[0],r[1],t),f(t),t):new m(r[0],r[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var r,i,a,u=e.split("T"),s=1,l=1,h=0,y=0,_=0,S=0,I=u[0],x=u[1];if(null!==(u=I.match(g)))r=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(T)))r=+u[1],s=+u[2];else if(null!==(u=I.match(v)))r=+u[1];else{var M;if(null!==(u=I.match(R)))r=+u[1],M=+u[2],a=o(r);else if(null!==(u=I.match(A))){r=+u[1];var C=+u[2],P=+u[3]||0,D=new Date(Date.UTC(r,0,4));M=7*C+P-D.getUTCDay()-3}i=new Date(Date.UTC(r,0,1)),i.setUTCDate(M),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(r);var U;if(n(x)){u=x.match(N),null!==u?(h=+u[1],y=+u[2],_=+u[3],S=1e3*+(u[4]||0),U=5):(u=x.match(O),null!==u?(h=+u[1],y=+u[2],_=60*+(u[3]||0),U=4):null!==(u=x.match(w))&&(h=+u[1],y=60*+(u[2]||0),U=3));var b=u[U],L=+u[U+1],F=+(u[U+2]||0);switch(b){case"+":h-=L,y-=F;break;case"-":h+=L,y+=F;break;case"Z":break;default:y+=new Date(Date.UTC(r,s-1,l,h,y)).getTimezoneOffset()}}var B=60===_;for(B&&_--;y>=60;)y-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:E[s-1];l>i;)l-=i,s++,s>12&&(s-=12,r++),i=a&&2===s?29:E[s-1];for(;y<0;)y+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,r--),i=a&&2===s?29:E[s-1],l+=i;var z=p(r,s,l,h,y,_,S);return n(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var I=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var r=!1,i=h(e,I);n(i)||(m.addSeconds(e,-1,I),i=h(I,I),r=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,p=c-(2447*d/80|0)|0;c=d/11|0;var y=d+2-12*c|0,E=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,v=u-_*s.SECONDS_PER_HOUR,T=v/s.SECONDS_PER_MINUTE|0;v-=T*s.SECONDS_PER_MINUTE;var R=0|v,A=(v-R)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),r&&(R+=1),n(t)?(t.year=E,t.month=y,t.day=p,t.hour=_,t.minute=T,t.second=R,t.millisecond=A,t.isLeapSecond=r,t):new a(E,y,p,_,T,R,A,r)},m.toDate=function(e){var t=m.toGregorianDate(e,y),r=t.second;return t.isLeapSecond&&(r-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,r,t.millisecond))},m.toIso8601=function(t,r){var i,a=m.toGregorianDate(t,y);return n(r)||0===a.millisecond?n(r)&&0!==r?(i=(.01*a.millisecond).toFixed(r).replace(".","").slice(0,r),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(n(e))return n(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var r=e.dayNumber-t.dayNumber;return 0!==r?r:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||n(e)&&n(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(m.secondsDifference(e,t))<=r},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){_.julianDate=e;var r=m.leapSeconds,n=t(r,_,l);return n<0&&(n=~n,--n<0&&(n=0)),r[n].offset},m.addSeconds=function(e,t,r){return d(e.dayNumber,e.secondsOfDay+t,r)},m.addMinutes=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,n,r)},m.addHours=function(e,t,r){var n=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,n,r)},m.addDays=function(e,t,r){return d(e.dayNumber+t,e.secondsOfDay,r)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(r,n){if(null===r||"object"!=typeof r)return r;n=e(n,!1);var i=new r.constructor;for(var a in r)if(r.hasOwnProperty(a)){var o=r[a];n&&(o=t(o,n)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function r(n,i,a){a=e(a,!1);var o,u,s,c={},l=t(n),f=t(i);if(l)for(o in n)n.hasOwnProperty(o)&&(u=n[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?r(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,r){"use strict";function n(e,t){r(e,t)}return n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var r=n.exec(t);this.scheme=r[1],this.authority=r[2],this.path=r[3],this.query=r[4],this.fragment=r[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function r(e,t,r,n){return(t||"")+r.toLowerCase()+(n||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var n=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,r).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var r=new e;return this.scheme?(r.scheme=this.scheme,r.authority=this.authority,r.path=this.path,r.query=this.query):(r.scheme=t.scheme,this.authority?(r.authority=this.authority,r.path=this.path,r.query=this.query):(r.authority=t.authority,""==this.path?(r.path=t.path,r.query=this.query||t.query):("/"==this.path.charAt(0)?(r.path=this.path,r.removeDotSegments()):(t.authority&&""==t.path?r.path="/"+this.path:r.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,r.removeDotSegments()),r.query=this.query))),r.fragment=this.fragment,r},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),r=[],n=""==t[0];n&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?r.pop():"."!=e&&r.push(e);"."!=e&&".."!=e||r.push(""),n&&r.unshift(""),this.path=r.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(r,n,i){n=t(n,t(i.baseURI,i.location.href));var a=new e(n);return new e(r).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r,n){var i="",a=r.lastIndexOf("/");return-1!==a&&(i=r.substring(0,a+1)),n?(r=new e(r),t(r.query)&&(i+="?"+r.query),t(r.fragment)&&(i+="#"+r.fragment),i):i}return n}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){var r=new e(t);r.normalize();var n=r.path,i=n.lastIndexOf("/");return-1!==i&&(n=n.substr(i+1)),i=n.lastIndexOf("."),n=-1===i?"":n.substr(i+1)}return n}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(r)||(r=document.createElement("a")),r.href=window.location.href;var n=r.host,i=r.protocol;return r.href=t,r.href=r.href,i!==r.protocol||n!==r.host}var r;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return r.test(e)}var r=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var i=e[n],a=encodeURIComponent(n)+"=";if(r(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return n}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,r){"use strict";function n(t){var n={};if(""===t)return n +;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=n[s];"string"==typeof l?n[s]=[l,c]:r(l)?l.push(c):n[s]=c}return n}return n}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,n.OTHER),this.serverKey=void 0,this.state=r.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var r=e.split("\r\n"),n=0;n<r.length;++n){var i=r[n],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function r(e,r,n){this.statusCode=e,this.response=r,this.responseHeaders=n,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return r.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},r}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,r){"use strict";function n(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return r(n.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),n.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var r=this;return function(){r.removeEventListener(e,t)}},n.prototype.removeEventListener=function(e,t){for(var r=this._listeners,n=this._scopes,i=-1,a=0;a<r.length;a++)if(r[a]===e&&n[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),r[i]=void 0,n[i]=void 0):(r.splice(i,1),n.splice(i,1)),!0)},n.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,r=this._listeners,n=this._scopes,a=r.length;for(e=0;e<a;e++){var o=r[e];t(o)&&r[e].apply(n[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];r.splice(s,1),n.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},n}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,r,n){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}return n(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var r=this._length,n=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<r&&n(i[c],i[e])<0?c:e,s<r&&n(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,n=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(n(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return r(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var r=this._array,n=r[e];return a(r,e,--this._length),this.heapify(e),n}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,r,n,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){n(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return w[e]<f.maximumRequestsPerServer}function p(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--R.numberOfActiveRequests,--w[e.serverKey],N.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function y(e){return function(t){e.state!==c.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--w[e.serverKey],N.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function E(e){var t=p(e);return e.state=c.ACTIVE,S.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++w[e.serverKey],e.requestFunction().then(m(e)).otherwise(y(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--w[e.serverKey],++R.numberOfCancelledActiveRequests),n(e.cancelFunction)&&e.cancelFunction()}function v(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){f.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),v())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,g=new o({comparator:l});g.maximumLength=A,g.reserve(A);var S=[],w={},O="undefined"!=typeof document?new e(document.location.href):new e,N=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=N,i(f,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;g.length>e;){var t=g.pop();_(t)}A=e,g.maximumLength=e,g.reserve(e)}}}),f.update=function(){var e,t,r=0,n=S.length;for(e=0;e<n;++e)t=S[e],t.cancelled&&_(t),t.state===c.ACTIVE?r>0&&(S[e-r]=t):++r;S.length-=r;var i=g.internalArray,a=g.length;for(e=0;e<a;++e)h(i[e]);g.resort();for(var o=Math.max(f.maximumRequests-S.length,0),u=0;u<o&&g.length>0;)t=g.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(E(t),++u):_(t);T()},f.getServerKey=function(t){var r=new e(t).resolve(O);r.normalize();var i=r.authority;/:/.test(i)||(i=i+":"+("https"===r.scheme?"443":"80"));var a=w[i];return n(a)||(w[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return N.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,n(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return E(e);if(!(S.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=g.insert(e);if(n(t)){if(t===e)return;_(t)}return p(e)}},f.clearForSpecs=function(){for(;g.length>0;){_(g.pop())}for(var e=S.length,t=0;t<e;++t)_(S[t]);S.length=0,w={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return w[e]},f.requestHeap=g,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(r){var n=new e(r);n.normalize();var i=n.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=n.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])||(a[n]=!0)},i.remove=function(e,r){var n=e.toLowerCase()+":"+r;t(a[n])&&delete a[n]},i.contains=function(e){var r=n(e);return!(!t(r)||!t(a[r]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,A,g,S,w){"use strict";function O(e,t){var r=e.query;if(!a(r)||0===r.length)return{};var i;if(-1===r.indexOf("=")){var o={};o[r]=void 0,i=o}else i=E(r);t._queryParameters=n(t._queryParameters,i),e.query=void 0}function N(e,t){var r=t._queryParameters,n=Object.keys(r);1!==n.length||a(r[n[0]])?e.query=y(r):e.query=n[0]}function I(e,t){return a(e)?a(e.clone)?e.clone():r(e):t}function x(e){if(e.state===R.ISSUED||e.state===R.ACTIVE)throw new A("The Resource is already being fetched.");e.state=R.UNISSUED,e.deferred=void 0}function M(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=I(e.templateValues,{}),this._queryParameters=I(e.queryParameters,{}),this.headers=I(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var r=e.request;r.url=e.url,r.requestFunction=function(){var r=e.url,n=!1;e.isDataUri||e.isBlobUri||(n=e.isCrossOriginUrl);var i=w.defer();return M._Implementations.createImage(r,n&&t,i),i.promise};var n=T.request(r);if(a(n))return n.otherwise(function(n){return r.state!==R.FAILED?w.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,C(e,t)):w.reject(n)})})}function P(e,t,r){var n={};n[t]=r,e.addQueryParameters(n);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=w.defer();return window[r]=function(e){t.resolve(e);try{delete window[r]}catch(e){window[r]=void 0}},M._Implementations.loadAndExecuteScript(e.url,r,t),t.promise};var o=T.request(i);if(a(o))return o.otherwise(function(n){return i.state!==R.FAILED?w.reject(n):e.retryOnError(n).then(function(a){return a?(i.state=R.UNISSUED,i.deferred=void 0,P(e,t,r)):w.reject(n)})})}function D(e,t){x(e.request);var r=e.request;r.url=e.url,r.requestFunction=function(){var i=t.responseType,o=n(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=w.defer(),f=M._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(r.cancelFunction=function(){f.abort()}),l.promise};var i=T.request(r);if(a(i))return i.then(function(e){return e}).otherwise(function(n){return r.state!==R.FAILED?w.reject(n):e.retryOnError(n).then(function(i){return i?(r.state=R.UNISSUED,r.deferred=void 0,e.fetch(t)):w.reject(n)})})}function U(e,t){var r=decodeURIComponent(t);return e?atob(r):r}function b(e,t){for(var r=U(e,t),n=new ArrayBuffer(r.length),i=new Uint8Array(n),a=0;a<r.length;a++)i[a]=r.charCodeAt(a);return n}function L(e,t){t=i(t,"");var r=e[1],n=!!e[2],a=e[3];switch(t){case"":case"text":return U(n,a);case"arraybuffer":return b(n,a);case"blob":var o=b(n,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(U(n,a),r);case"json":return JSON.parse(U(n,a))}}var F=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();M.createIfNeeded=function(e,t){if(e instanceof M)return e.clone();if("string"!=typeof e)return e;var r=I(t,{});return r.url=e,new M(r)},o(M,{isBlobSupported:{get:function(){return F}}}),o(M.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new S(e);O(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return p(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),M.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var r=new S(this._url);e&&N(r,this);var n=r.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];n=n.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(n=this.proxy.getURL(n)),n},M.prototype.addQueryParameters=function(e,t){this._queryParameters=t?n(this._queryParameters,e):n(e,this._queryParameters)},M.prototype.addTemplateValues=function(e,t){this._templateValues=t?n(this._templateValues,e):n(e,this._templateValues)},M.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var r=new S(e.url);O(r,t),r.fragment=void 0,t._url=r.resolve(new S(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=n(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=n(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=n(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},M.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return w(!1);var r=this;return w(t(this,e)).then(function(e){return++r._retryCount,e})},M.prototype.clone=function(e){return a(e)||(e=new M({url:this._url})),e._url=this._url,e._queryParameters=r(this._queryParameters),e._templateValues=r(this._templateValues),e.headers=r(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},M.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},M.prototype.appendForwardSlash=function(){this._url=e(this._url)},M.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},M.fetchArrayBuffer=function(e){return new M(e).fetchArrayBuffer()},M.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},M.fetchBlob=function(e){return new M(e).fetchBlob()},M.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),x(this.request),!F||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var r=this.fetchBlob();if(a(r)){var n,o;return r.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return n=new M({url:t}),C(n)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(n.url),e.blob=o,e}).otherwise(function(e){return a(n)&&window.URL.revokeObjectURL(n.url),w.reject(e)})}},M.fetchImage=function(e){return new M(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},M.prototype.fetchText=function(){return this.fetch({responseType:"text"})},M.fetchText=function(e){return new M(e).fetchText()},M.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},M.fetchJson=function(e){return new M(e).fetchJson()},M.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},M.fetchXML=function(e){return new M(e).fetchXML()},M.prototype.fetchJsonp=function(e){e=i(e,"callback"),x(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},M.fetchJsonp=function(e){return new M(e).fetchJsonp(e.callbackParameterName)},M.prototype.fetch=function(e){return e=I(e,i.EMPTY_OBJECT),e.method="GET",D(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return M.fetch=function(e){return new M(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},M.prototype.post=function(e,r){return t.defined("data",e),r=I(r,{}),r.method="POST",r.data=e,D(this,r)},M.post=function(e){return new M(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},M._Implementations={},M._Implementations.createImage=function(e,t,r){var n=new Image;n.onload=function(){r.resolve(n)},n.onerror=function(e){r.reject(e)},t&&(g.contains(e)?n.crossOrigin="use-credentials":n.crossOrigin=""),n.src=e},M._Implementations.loadWithXhr=function(e,t,r,n,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(L(s,t));var c=new XMLHttpRequest;if(g.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(r,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new v(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,r=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&r!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===r||"document"===r)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==r&&"text"!==r||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new v)},c.send(n),c},M._Implementations.loadAndExecuteScript=function(e,t,r){var n=document.createElement("script");n.async=!0,n.src=e;var i=document.getElementsByTagName("head")[0];n.onload=function(){n.onload=void 0,i.removeChild(n)},n.onerror=function(e){r.reject(e)},i.appendChild(n)},M._DefaultImplementations={},M._DefaultImplementations.createImage=M._Implementations.createImage,M._DefaultImplementations.loadWithXhr=M._Implementations.loadWithXhr,M._DefaultImplementations.loadAndExecuteScript=M._Implementations.loadAndExecuteScript,M.DEFAULT=c(new M({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),M}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=r(t,r.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=r(t.addNewLeapSeconds,!0),n(t.data))p(this,t.data);else if(n(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){p(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else p(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function p(e,r){if(!n(r.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!n(r.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=r.columnNames.indexOf("modifiedJulianDateUtc"),a=r.columnNames.indexOf("xPoleWanderRadians"),s=r.columnNames.indexOf("yPoleWanderRadians"),c=r.columnNames.indexOf("ut1MinusUtcSeconds"),h=r.columnNames.indexOf("xCelestialPoleOffsetRadians"),p=r.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=r.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||p<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var y=e._samples=r.samples,E=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=p,e._taiMinusUtcSecondsColumn=m,e._columnCount=r.columnNames.length,e._lastIndex=void 0;for(var _,v=e._addNewLeapSeconds,T=0,R=y.length;T<R;T+=e._columnCount){var A=y[T+i],g=y[T+m],S=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,w=new o(S,g,f.TAI);if(E.push(w),v){if(g!==_&&n(_)){var O=o.leapSeconds,N=t(O,w,d);if(N<0){var I=new u(w,g);O.splice(~N,0,I)}}_=g}}}function m(e,t,r,n,i){var a=r*n;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function y(e,t,r){return t+e*(r-t)}function E(e,t,r,n,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||n.equals(c))return m(e,r,i,s,u),u;if(n.equals(l))return m(e,r,a,s,u),u;var f=o.secondsDifference(n,c)/o.secondsDifference(l,c),h=i*s,d=a*s,p=r[h+e._ut1MinusUtcSecondsColumn],E=r[d+e._ut1MinusUtcSecondsColumn],_=E-p;if(_>.5||_<-.5){var v=r[h+e._taiMinusUtcSecondsColumn],T=r[d+e._taiMinusUtcSecondsColumn];v!==T&&(l.equals(n)?p=E:E-=T-v)}return u.xPoleWander=y(f,r[h+e._xPoleWanderRadiansColumn],r[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=y(f,r[h+e._yPoleWanderRadiansColumn],r[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=y(f,r[h+e._xCelestialPoleOffsetRadiansColumn],r[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=y(f,r[h+e._yCelestialPoleOffsetRadiansColumn],r[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=y(f,p,E),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return n(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,r){if(n(this._samples)){if(n(r)||(r=new i(0,0,0,0,0)),0===this._samples.length)return r.xPoleWander=0,r.yPoleWander=0,r.xPoleOffset=0,r.yPoleOffset=0,r.ut1MinusUtc=0,r;var a=this._dates,u=this._lastIndex,s=0,l=0;if(n(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),p=!n(h),m=p||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!p&&h.equals(e)&&++s,l=s+1,E(this,a,this._samples,e,s,l,r),r}var y=t(a,e,o.compare,this._dateColumn);return y>=0?(y<a.length-1&&a[y+1].equals(e)&&++y,s=y,l=y):(l=~y,(s=l-1)<0&&(s=0)),this._lastIndex=s,E(this,a,this._samples,e,s,l,r),r}if(n(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,r,n,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,r=e.length;t<r;++t){var n=e[t].getAttribute("src"),i=d.exec(n);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new n({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var r=f(e);return h.href=r,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=n.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,r){this.x=e,this.y=t,this.s=r}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){e=r(e,r.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=r(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=r(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=r(e.stepSizeDays,1),this._samplesPerXysFile=r(e.samplesPerXysFile,1e3),this._totalSamples=r(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,n=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){n[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(n[c]*=c-l);n[c]=1/n[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,r){var n=f;return n.dayNumber=t,n.secondsOfDay=r,a.daysDifference(n,e._sampleZeroDateTT)}function l(r,i){if(r._chunkDownloadsInProgress[i])return r._chunkDownloadsInProgress[i];var a=e.defer();r._chunkDownloadsInProgress[i]=a;var u,s=r._xysFileUrlTemplate;return u=n(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){r._chunkDownloadsInProgress[i]=!1;for(var t=r._samples,n=e.samples,o=i*r._samplesPerXysFile*3,u=0,s=n.length;u<s;++u)t[o+u]=n[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,r,n,i){var a=c(this,t,r),o=c(this,n,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],p=f;p<=h;++p)d.push(l(this,p));return e.all(d)},s.prototype.computeXysRadians=function(e,t,r){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(n(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),n(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){n(r)?(r.x=0,r.y=0,r.s=0):r=new i(0,0,0);var p,m,y=a-s*this._stepSizeDays,E=this._work,_=this._denominators,v=this._coef,T=this._xTable;for(p=0;p<=u;++p)E[p]=y-T[p];for(p=0;p<=u;++p){for(v[p]=1,m=0;m<=u;++m)m!==p&&(v[p]*=E[m]);v[p]*=_[p];var R=3*(s+p);r.x+=v[p]*d[R++],r.y+=v[p]*d[R++],r.s+=v[p]*d[R]}return r}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,r,n,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.z=r(n,0),this.w=r(i,0)}var c=new e;s.fromAxisAngle=function(t,r,i){var a=r/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return n(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var r,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],p=e[u.COLUMN2ROW2],m=h+d+p;if(m>0)r=Math.sqrt(m+1),c=.5*r,r=.5/r,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*r,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*r,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*r;else{var y=l,E=0;d>h&&(E=1),p>h&&p>d&&(E=2);var _=y[E],v=y[_];r=Math.sqrt(e[u.getElementIndex(E,E)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(v,v)]+1);var T=f;T[E]=.5*r,r=.5/r,c=(e[u.getElementIndex(v,_)]-e[u.getElementIndex(_,v)])*r,T[_]=(e[u.getElementIndex(_,E)]+e[u.getElementIndex(E,_)])*r,T[v]=(e[u.getElementIndex(v,E)]+e[u.getElementIndex(E,v)])*r,i=-T[0],a=-T[1],o=-T[2]}return n(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,p=new s,m=new s;s.fromHeadingPitchRoll=function(t,r){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),p=s.fromAxisAngle(e.UNIT_Y,-t.pitch,r),r=s.multiply(p,m,p),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,r,r)};var y=new e,E=new e,_=new s,v=new s,T=new s;s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.z,t[n]=e.w,t},s.unpack=function(e,t,i){return t=r(t,0),n(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,r,n){s.unpack(e,4*r,T),s.conjugate(T,T);for(var i=0,a=r-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,T,_),_.w<0&&s.negate(_,_),s.computeAxis(_,y);var u=s.computeAngle(_);n[o]=y.x*u,n[o+1]=y.y*u,n[o+2]=y.z*u}},s.unpackInterpolationResult=function(t,r,i,a,o){n(o)||(o=new s),e.fromArray(t,0,E);var u=e.magnitude(E);return s.unpack(r,4*a,v),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(E,u,_),s.multiply(_,v,o)},s.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var r=1/s.magnitude(e),n=e.x*r,i=e.y*r,a=e.z*r,o=e.w*r;return t.x=n,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var r=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/r,t)},s.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},s.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,r){var n=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+n*l+i*c-a*s,h=o*s-n*c+i*l+a*u,d=o*c+n*s-i*u+a*l,p=o*l-n*u-i*s-a*c;return r.x=f,r.y=h,r.z=d,r.w=p,r},s.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},s.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},s.computeAxis=function(e,t){var r=e.w;if(Math.abs(r-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var n=1/Math.sqrt(1-r*r);return t.x=e.x*n,t.y=e.y*n,t.z=e.z*n,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var R=new s;s.lerp=function(e,t,r,n){return R=s.multiplyByScalar(t,r,R),n=s.multiplyByScalar(e,1-r,n),s.add(R,n,n)};var A=new s,g=new s,S=new s;s.slerp=function(e,t,r,n){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,r,n);var u=Math.acos(i);return g=s.multiplyByScalar(e,Math.sin((1-r)*u),g),S=s.multiplyByScalar(a,Math.sin(r*u),S),n=s.add(g,S,n),s.multiplyByScalar(n,1/Math.sin(u),n)},s.log=function(t,r){var n=o.acosClamped(t.w),i=0 +;return 0!==n&&(i=n/Math.sin(n)),e.multiplyByScalar(t,i,r)},s.exp=function(t,r){var n=e.magnitude(t),i=0;return 0!==n&&(i=Math.sin(n)/n),r.x=t.x*i,r.y=t.y*i,r.z=t.z*i,r.w=Math.cos(n),r};var w=new e,O=new e,N=new s,I=new s;s.computeInnerQuadrangle=function(t,r,n,i){var a=s.conjugate(r,N);s.multiply(a,n,I);var o=s.log(I,w);s.multiply(a,t,I);var u=s.log(I,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,N),s.multiply(r,N,i)},s.squad=function(e,t,r,n,i,a){var o=s.slerp(e,t,i,N),u=s.slerp(r,n,i,I);return s.slerp(o,u,2*i*(1-i),a)};for(var x=new s,M=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],b=0;b<7;++b){var L=b+1,F=2*L+1;C[b]=1/(L*F),P[b]=L/F}return C[7]=M/136,P[7]=8*M/17,s.fastSlerp=function(e,t,r,n){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-r,c=r*r,l=u*u,f=7;f>=0;--f)D[f]=(C[f]*c-P[f])*o,U[f]=(C[f]*l-P[f])*o;var h=i*r*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),d=u*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),p=s.multiplyByScalar(e,d,x);return s.multiplyByScalar(t,h,n),s.add(p,n,n)},s.fastSquad=function(e,t,r,n,i,a){var o=s.fastSlerp(e,t,i,N),u=s.fastSlerp(r,n,i,I);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.x-t.x)<=r&&Math.abs(e.y-t.y)<=r&&Math.abs(e.z-t.z)<=r&&Math.abs(e.w-t.w)<=r},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v){"use strict";var T={},R={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},g={},S={east:new r,north:new r,up:new r,west:new r,south:new r,down:new r},w=new r,O=new r,N=new r;T.localFrameToFixedFrameGenerator=function(e,t){if(!R.hasOwnProperty(e)||!R[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var n,i=R[e][t],a=e+t;return u(g[a])?n=g[a]:(n=function(n,a,s){if(u(s)||(s=new E),m.equalsEpsilon(n.x,0,m.EPSILON14)&&m.equalsEpsilon(n.y,0,m.EPSILON14)){var c=m.sign(n.z);r.unpack(A[e],0,w),"east"!==e&&"west"!==e&&r.multiplyByScalar(w,c,w),r.unpack(A[t],0,O),"east"!==t&&"west"!==t&&r.multiplyByScalar(O,c,O),r.unpack(A[i],0,N),"east"!==i&&"west"!==i&&r.multiplyByScalar(N,c,N)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(n,S.up);var l=S.up,h=S.east;h.x=-n.y,h.y=n.x,h.z=0,r.normalize(h,S.east),r.cross(l,h,S.north),r.multiplyByScalar(S.up,-1,S.down),r.multiplyByScalar(S.east,-1,S.west),r.multiplyByScalar(S.north,-1,S.south),w=S[e],O=S[t],N=S[i]}return s[0]=w.x,s[1]=w.y,s[2]=w.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=N.x,s[9]=N.y,s[10]=N.z,s[11]=0,s[12]=n.x,s[13]=n.y,s[14]=n.z,s[15]=1,s},g[a]=n),n},T.eastNorthUpToFixedFrame=T.localFrameToFixedFrameGenerator("east","north"),T.northEastDownToFixedFrame=T.localFrameToFixedFrameGenerator("north","east"),T.northUpEastToFixedFrame=T.localFrameToFixedFrameGenerator("north","up"),T.northWestUpToFixedFrame=T.localFrameToFixedFrameGenerator("north","west");var I=new _,x=new r(1,1,1),M=new E;T.headingPitchRollToFixedFrame=function(e,t,n,i,a){i=o(i,T.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,I),s=E.fromTranslationQuaternionRotationScale(r.ZERO,u,x,M);return a=i(e,n,a),E.multiply(a,s,a)};var C=new E,P=new y;T.headingPitchRollQuaternion=function(e,t,r,n,i){var a=T.headingPitchRollToFixedFrame(e,t,r,n,C),o=E.getRotation(a,P);return _.fromRotationMatrix(o,i)};var D=m.TWO_PI/86400,U=new p;T.computeTemeToPseudoFixedMatrix=function(e,t){U=p.addSeconds(e,-p.computeTaiMinusUtc(e),U);var r,n=U.dayNumber,i=U.secondsOfDay,a=n-2451545;r=i>=43200?(a+.5)/v.DAYS_PER_JULIAN_CENTURY:(a-.5)/v.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+r*(8640184.812866+r*(.093104+-62e-7*r)),s=o*D%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(n-2451545.5),l=(i+.5*v.SECONDS_PER_DAY)%v.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new y(h,d,0,-d,h,0,0,0,1)},T.iau2006XysData=new h,T.earthOrientationParameters=c.NONE;T.preloadIcrfFixed=function(t){var r=t.start.dayNumber,n=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=T.iau2006XysData.preload(r,n,i,a),u=T.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},T.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new y);var r=T.computeFixedToIcrfMatrix(e,t);if(u(r))return y.transpose(r,t)};var b=new d(0,0,0),L=new l(0,0,0,0,0,0),F=new y,B=new y;T.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new y);var r=T.earthOrientationParameters.compute(e,L);if(u(r)){var n=e.dayNumber,i=e.secondsOfDay+32.184,a=T.iau2006XysData.computeXysRadians(n,i,b);if(u(a)){var o=a.x+r.xPoleOffset,s=a.y+r.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=F;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=y.fromRotationZ(-a.s,B),h=y.multiply(l,f,F),d=e.dayNumber,E=e.secondsOfDay-p.computeTaiMinusUtc(e)+r.ut1MinusUtc,_=d-2451545,R=E/v.SECONDS_PER_DAY,A=.779057273264+R+.00273781191135448*(_+R);A=A%1*m.TWO_PI;var g=y.fromRotationZ(A,B),S=y.multiply(h,g,F),w=Math.cos(r.xPoleWander),O=Math.cos(r.yPoleWander),N=Math.sin(r.xPoleWander),I=Math.sin(r.yPoleWander),x=n-2451545+i/v.SECONDS_PER_DAY;x/=36525;var M=-47e-6*x*m.RADIANS_PER_DEGREE/3600,C=Math.cos(M),P=Math.sin(M),D=B;return D[0]=w*C,D[1]=w*P,D[2]=N,D[3]=-O*P+I*N*C,D[4]=O*C+I*N*P,D[5]=-I*w,D[6]=-I*P-O*N*C,D[7]=I*C-O*N*P,D[8]=O*w,y.multiply(S,D,t)}}};var z=new n;T.pointToWindowCoordinates=function(e,t,r,n){return n=T.pointToGLWindowCoordinates(e,t,r,n),n.y=2*t[5]-n.y,n},T.pointToGLWindowCoordinates=function(e,r,i,a){u(a)||(a=new t);var o=z;return E.multiplyByVector(e,n.fromElements(i.x,i.y,i.z,1,o),o),n.multiplyByScalar(o,1/o.w,o),E.multiplyByVector(r,o,o),t.fromCartesian4(o,a)};var q=new r,G=new r,V=new r;T.rotationMatrixFromPositionVelocity=function(e,t,n,i){var a=o(n,f.WGS84).geodeticSurfaceNormal(e,q),s=r.cross(t,a,G);r.equalsEpsilon(s,r.ZERO,m.EPSILON6)&&(s=r.clone(r.UNIT_X,s));var c=r.cross(s,t,V);return r.cross(t,c,s),r.negate(s,s),u(i)||(i=new y),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new E(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new r,k=new r,Y=new y,j=new E,Z=new E;return T.basisTo2D=function(e,t,n){var i=E.getTranslation(t,k),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);r.fromElements(u.z,u.x,u.y,u);var s=T.eastNorthUpToFixedFrame(i,a,j),c=E.inverseTransformation(s,Z),l=E.getRotation(t,Y),f=E.multiplyByMatrix3(c,l,n);return E.multiply(W,f,n),E.setTranslation(n,u,n),n},T.wgs84To2DModelMatrix=function(e,t,n){var i=e.ellipsoid,a=T.eastNorthUpToFixedFrame(t,i,j),o=E.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,X),s=e.project(u,H);r.fromElements(s.z,s.x,s.y,s);var c=E.fromTranslation(s,j);return E.multiply(W,o,n),E.multiply(c,n,n),n},T}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d){"use strict";function p(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var n=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=r.fromCartesian4(l.getColumn(n,0,m)),this._yAxis=r.fromCartesian4(l.getColumn(n,1,m));var a=r.fromCartesian4(l.getColumn(n,2,m));this._plane=f.fromPointNormal(e,a)}var m=new n;o(p.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var y=new e;p.fromPoints=function(t,r){return new p(e.fromPoints(t,y).center,r)};var E=new h,_=new r;p.prototype.projectPointOntoPlane=function(e,n){var i=E;i.origin=e,r.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return a(n)?(n.x=s,n.y=l,n):new t(s,l)}},p.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var r=0,n=e.length,i=0;i<n;i++){var o=this.projectPointOntoPlane(e[i],t[r]);a(o)&&(t[r]=o,r++)}return t.length=r,t},p.prototype.projectPointToNearestOnPlane=function(e,n){a(n)||(n=new t);var i=E;i.origin=e,r.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(r.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=r.subtract(o,this._origin,o),s=r.dot(this._xAxis,u),l=r.dot(this._yAxis,u);return n.x=s,n.y=l,n},p.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var r=e.length;t.length=r;for(var n=0;n<r;n++)t[n]=this.projectPointToNearestOnPlane(e[n],t[n]);return t};var v=new r;return p.prototype.projectPointsOntoEllipsoid=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=v,l=0;l<n;++l){var f=e[l];r.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new r);var h=r.add(o,c,t[l]);r.multiplyByScalar(s,f.y,c),r.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},p}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,r,n,i,a,o,u){"use strict";function s(e){var t=e._uSquared,r=e._ellipsoid.maximumRadius,n=e._ellipsoid.minimumRadius,i=(r-n)/r,a=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-i)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,a),f=s*o,h=f*f,d=1-h,p=Math.sqrt(d),m=t/4,y=m*m,E=y*m,_=y*y,v=1+m-3*y/4+5*E/4-175*_/64,T=1-m+15*y/8-35*E/8,R=1-3*m+35*y/4,A=1-5*m,g=v*l-T*Math.sin(2*l)*m/2-R*Math.sin(4*l)*y/16-A*Math.sin(6*l)*E/48-5*Math.sin(8*l)*_/512,S=e._constants;S.a=r,S.b=n,S.f=i,S.cosineHeading=a,S.sineHeading=o,S.tanU=u,S.cosineU=s,S.sineU=c,S.sigma=l,S.sineAlpha=f,S.sineSquaredAlpha=h,S.cosineSquaredAlpha=d,S.cosineAlpha=p,S.u2Over4=m,S.u4Over16=y,S.u6Over64=E,S.u8Over256=_,S.a0=v,S.a1=T,S.a2=R,S.a3=A,S.distanceRatio=g}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,r,n,i,a,o){var u=c(e,r);return(1-u)*e*t*(n+u*i*(o+u*a*(2*o*o-1)))}function f(e,t,r,n,i,a,o){var s,c,f,h,d,p=(t-r)/t,m=a-n,y=Math.atan((1-p)*Math.tan(i)),E=Math.atan((1-p)*Math.tan(o)),_=Math.cos(y),v=Math.sin(y),T=Math.cos(E),R=Math.sin(E),A=_*T,g=_*R,S=v*R,w=v*T,O=m,N=u.TWO_PI,I=Math.cos(O),x=Math.sin(O);do{I=Math.cos(O),x=Math.sin(O);var M=g-w*I;f=Math.sqrt(T*T*x*x+M*M),c=S+A*I,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=A*x/f,h=1-C*C),N=O,d=c-2*S/h,isNaN(d)&&(d=0),O=m+l(p,C,h,s,f,c,d)}while(Math.abs(O-N)>u.EPSILON12);var P=h*(t*t-r*r)/(r*r),D=1+P*(4096+P*(P*(320-175*P)-768))/16384,U=P*(256+P*(P*(74-47*P)-128))/1024,b=d*d,L=U*f*(d+U*(c*(2*b-1)-U*d*(4*f*f-3)*(4*b-3)/6)/4),F=r*D*(s-L),B=Math.atan2(T*x,g-w*I),z=Math.atan2(_*x,g*I-w);e._distance=F,e._startHeading=B,e._endHeading=z,e._uSquared=P}function h(r,n,i,a){e.normalize(a.cartographicToCartesian(n,m),p),e.normalize(a.cartographicToCartesian(i,m),m);f(r,a.maximumRadius,a.minimumRadius,n.longitude,n.latitude,i.longitude,i.latitude),r._start=t.clone(n,r._start),r._end=t.clone(i,r._end),r._start.height=0,r._end.height=0,s(r)}function d(e,r,a){var u=n(a,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,i(e)&&i(r)&&h(this,e,r,u)}var p=new e,m=new e;return a(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,r){var n=this._constants,a=n.distanceRatio+e/n.b,o=Math.cos(2*a),u=Math.cos(4*a),s=Math.cos(6*a),c=Math.sin(2*a),f=Math.sin(4*a),h=Math.sin(6*a),d=Math.sin(8*a),p=a*a,m=a*p,y=n.u8Over256,E=n.u2Over4,_=n.u6Over64,v=n.u4Over16,T=2*m*y*o/3+a*(1-E+7*v/4-15*_/4+579*y/64-(v-15*_/4+187*y/16)*o-(5*_/4-115*y/16)*u-29*y*s/16)+(E/2-v+71*_/32-85*y/16)*c+(5*v/16-5*_/4+383*y/96)*f-p*((_-11*y/2)*c+5*y*f/2)+(29*_/96-29*y/16)*h+539*y*d/1536,R=Math.asin(Math.sin(T)*n.cosineAlpha),A=Math.atan(n.a/n.b*Math.tan(R));T-=n.sigma;var g=Math.cos(2*n.sigma+T),S=Math.sin(T),w=Math.cos(T),O=n.cosineU*w,N=n.sineU*S,I=Math.atan2(S*n.sineHeading,O-N*n.cosineHeading),x=I-l(n.f,n.sineAlpha,n.cosineSquaredAlpha,T,S,w,g);return i(r)?(r.longitude=this._start.longitude+x,r.latitude=A,r.height=0,r):new t(this._start.longitude+x,A,0)},d}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(e,t,r){var n=S;n.length=e;var i;if(t===r){for(i=0;i<e;i++)n[i]=t;return n}var a=r-t,o=a/e;for(i=0;i<e;i++){var u=t+i*o;n[i]=u}return n}function d(t,r,n,i,a,o,u,s){var c=i.scaleToGeodeticSurface(t,I),l=i.scaleToGeodeticSurface(r,x),f=p.numberOfPoints(t,r,n),d=i.cartesianToCartographic(c,w),m=i.cartesianToCartographic(l,O),y=h(f,a,o);M.setEndPoints(d,m);var E=M.surfaceDistance/f,_=s;d.height=a;var v=i.cartographicToCartesian(d,N);e.pack(v,u,_),_+=3;for(var T=1;T<f;T++){var R=M.interpolateUsingSurfaceDistance(T*E,O);R.height=y[T],v=i.cartographicToCartesian(R,N),e.pack(v,u,_),_+=3}return _}var p={};p.numberOfPoints=function(t,r,n){var i=e.distance(t,r);return Math.ceil(i/n)};var m=new t;p.extractHeights=function(e,t){for(var r=e.length,n=new Array(r),i=0;i<r;i++){var a=e[i];n[i]=t.cartesianToCartographic(a,m).height}return n};var y=new l,E=new e,_=new e,v=new f(e.UNIT_X,0),T=new e,R=new f(e.UNIT_X,0),A=new e,g=new e,S=[],w=new t,O=new t,N=new e,I=new e,x=new e,M=new o;return p.wrapLongitude=function(t,i){var a=[],o=[];if(n(t)&&t.length>0){i=r(i,l.IDENTITY);var s=l.inverseTransformation(i,y),c=l.multiplyByPoint(s,e.ZERO,E),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,_),_),d=f.fromPointNormal(c,h,v),p=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,T),T),m=f.fromPointNormal(c,p,R),S=1;a.push(e.clone(t[0]));for(var w=a[0],O=t.length,N=1;N<O;++N){var I=t[N];if(f.getPointDistance(m,w)<0||f.getPointDistance(m,I)<0){var x=u.lineSegmentPlane(w,I,d,A);if(n(x)){var M=e.multiplyByScalar(h,5e-9,g);f.getPointDistance(d,w)<0&&e.negate(M,M),a.push(e.add(x,M,new e)),o.push(S+1),e.negate(M,M),a.push(e.add(x,M,new e)),S=1}}a.push(e.clone(t[N])),S++,w=I}o.push(S)}return{positions:a,lengths:o}},p.generateArc=function(t){n(t)||(t={});var i=t.positions,o=i.length,u=r(t.ellipsoid,a.WGS84),l=r(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(i[0],I);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,N);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var y=t.minDistance;if(!n(y)){var E=r(t.granularity,c.RADIANS_PER_DEGREE);y=c.chordLength(E,u.maximumRadius)}var _,v=0;for(_=0;_<o-1;_++)v+=p.numberOfPoints(i[_],i[_+1],y);var T=3*(v+1),R=new Array(T),A=0;for(_=0;_<o-1;_++){A=d(i[_],i[_+1],y,u,f?l[_]:l,f?l[_+1]:l,R,A)}S.length=0;var g=i[o-1],O=u.cartesianToCartographic(g,w);O.height=f?l[o-1]:l;var x=u.cartographicToCartesian(O,N);return e.pack(x,R,T-3),R},p.generateCartesianArc=function(t){for(var r=p.generateArc(t),n=r.length/3,i=new Array(n),a=0;a<n;a++)i[a]=e.unpack(r,3*a);return i},p}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,r,n,i,a,o,u,s,c,l,f){"use strict";function h(e,t){for(var r=new Array(e.length),n=0;n<e.length;n++){var i=e[n];D=t.cartesianToCartographic(i,D),r[n]=D.height,e[n]=t.scaleToGeodeticSurface(i,i)}return r}function d(e,r,n,i){var a,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/i),l=new Array(c);if(r===n){for(a=0;a<c;a++)l[a]=r;return l.push(n),l}var f=n-r,h=f/c;for(a=1;a<c;a++){var d=r+a*h;l[a]=d}return l[0]=r,l.push(n),l}function p(r,n,i,o){var u=new a(i,o),s=u.projectPointOntoPlane(t.add(i,r,U),U),c=u.projectPointOntoPlane(t.add(i,n,b),b),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function m(e,r,n,i,a,o,c,l){var h=G,d=V;F=f.eastNorthUpToFixedFrame(e,a,F),h=s.multiplyByPointAsVector(F,L,h),h=t.normalize(h,h);var m=p(h,r,e,a);z=u.fromRotationZ(m,z),W.z=o,F=s.multiplyTransformation(F,s.fromRotationTranslation(z,W,B),F);var y=q;y[0]=c;for(var E=0;E<l;E++)for(var _=0;_<n.length;_+=3)d=t.fromArray(n,_,d),d=u.multiplyByVector(y,d,d),d=s.multiplyByPoint(F,d,d),i.push(d.x,d.y,d.z);return i}function y(e,r,n,i,a,o,u){for(var s=0;s<e.length;s+=3){i=m(t.fromArray(e,s,X),r,n,i,a,o[s/3],u,1)}return i}function E(e,t){var r=e.length,n=new Array(6*r),i=0,a=t.x+t.width/2,o=t.y+t.height/2,u=e[0];n[i++]=u.x-a,n[i++]=0,n[i++]=u.y-o;for(var s=1;s<r;s++){u=e[s];var c=u.x-a,l=u.y-o;n[i++]=c,n[i++]=0,n[i++]=l,n[i++]=c,n[i++]=0,n[i++]=l}return u=e[0],n[i++]=u.x-a,n[i++]=0,n[i++]=u.y-o,n}function _(e,t){for(var r=e.length,n=new Array(3*r),i=0,a=t.x+t.width/2,o=t.y+t.height/2,u=0;u<r;u++)n[i++]=e[u].x-a,n[i++]=0,n[i++]=e[u].y-o;return n}function v(e,r,n,a,s,c,f,h,d,p){var y,E=t.angleBetween(t.subtract(r,e,M),t.subtract(n,e,C)),_=a===i.BEVELED?0:Math.ceil(E/o.toRadians(5));y=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,M),E/(_+1),H),Y):u.fromQuaternion(l.fromAxisAngle(e,E/(_+1),H),Y);var v,T;if(r=t.clone(r,k),_>0)for(var R=p?2:1,A=0;A<_;A++)r=u.multiplyByVector(y,r,r),v=t.subtract(r,e,M),v=t.normalize(v,v),s||(v=t.negate(v,v)),T=c.scaleToGeodeticSurface(r,C),f=m(T,v,h,f,c,d,1,R);else v=t.subtract(r,e,M),v=t.normalize(v,v),s||(v=t.negate(v,v)),T=c.scaleToGeodeticSurface(r,C),f=m(T,v,h,f,c,d,1,1),n=t.clone(n,k),v=t.subtract(n,e,M),v=t.normalize(v,v),s||(v=t.negate(v,v)),T=c.scaleToGeodeticSurface(n,C),f=m(T,v,h,f,c,d,1,1);return f}var T=[new t,new t],R=new t,A=new t,g=new t,S=new t,w=new t,O=new t,N=new t,I=new t,x=new t,M=new t,C=new t,P={},D=new n,U=new t,b=new t,L=new t(-1,0,0),F=new s,B=new s,z=new u,q=u.IDENTITY.clone(),G=new t,V=new r,W=new t,X=new t,H=new l,k=new t,Y=new u;P.removeDuplicatesFromShape=function(t){for(var r=t.length,n=[],i=r-1,a=0;a<r;i=a++){var o=t[i],u=t[a];e.equals(o,u)||n.push(u)}return n},P.angleIsGreaterThanPi=function(e,r,n,i){var o=new a(n,i),u=o.projectPointOntoPlane(t.add(n,e,U),U),s=o.projectPointOntoPlane(t.add(n,r,b),b);return s.x*u.y-s.y*u.x>=0};var j=new t,Z=new t;return P.computePositions=function(e,r,n,a,u){var s=a._ellipsoid,l=h(e,s),f=a._granularity,p=a._cornerType,C=u?E(r,n):_(r,n),D=u?_(r,n):void 0,U=n.height/2,b=n.width/2,L=e.length,F=[],B=u?[]:void 0,z=R,q=A,G=g,V=S,W=w,X=O,H=N,k=I,Y=x,K=e[0],J=e[1];V=s.geodeticSurfaceNormal(K,V),z=t.subtract(J,K,z),z=t.normalize(z,z),k=t.cross(V,z,k),k=t.normalize(k,k);var Q=l[0],$=l[1];u&&(B=m(K,k,D,B,s,Q+U,1,1)),Y=t.clone(K,Y),K=J,q=t.negate(z,q);for(var ee,te,re=1;re<L-1;re++){var ne=u?2:1;J=e[re+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),V=s.geodeticSurfaceNormal(K,V);var ie=t.multiplyByScalar(V,t.dot(z,V),j);t.subtract(z,ie,ie),t.normalize(ie,ie);var ae=t.multiplyByScalar(V,t.dot(q,V),Z);t.subtract(q,ae,ae),t.normalize(ae,ae);if(!o.equalsEpsilon(Math.abs(t.dot(ie,ae)),1,o.EPSILON7)){G=t.cross(G,V,G),G=t.cross(V,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,M))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(W=t.add(K,t.multiplyByScalar(G,oe*b,G),W),X=t.add(W,t.multiplyByScalar(k,b,X),X),T[0]=t.clone(Y,T[0]),T[1]=t.clone(X,T[1]),ee=d(T,Q+U,$+U,f),te=c.generateArc({positions:T,granularity:f,ellipsoid:s}),F=y(te,k,C,F,s,ee,1),k=t.cross(V,z,k),k=t.normalize(k,k),H=t.add(W,t.multiplyByScalar(k,b,H),H),p===i.ROUNDED||p===i.BEVELED?v(W,X,H,p,ue,s,F,C,$+U,u):(G=t.negate(G,G),F=m(K,G,C,F,s,$+U,oe,ne)),Y=t.clone(H,Y)):(W=t.add(K,t.multiplyByScalar(G,oe*b,G),W),X=t.add(W,t.multiplyByScalar(k,-b,X),X),T[0]=t.clone(Y,T[0]),T[1]=t.clone(X,T[1]),ee=d(T,Q+U,$+U,f),te=c.generateArc({positions:T,granularity:f,ellipsoid:s}),F=y(te,k,C,F,s,ee,1),k=t.cross(V,z,k),k=t.normalize(k,k),H=t.add(W,t.multiplyByScalar(k,-b,H),H),p===i.ROUNDED||p===i.BEVELED?v(W,X,H,p,ue,s,F,C,$+U,u):F=m(K,G,C,F,s,$+U,oe,ne),Y=t.clone(H,Y)),q=t.negate(z,q)}else F=m(Y,k,C,F,s,Q+U,1,1),Y=K;Q=$,$=l[re+1],K=J}T[0]=t.clone(Y,T[0]),T[1]=t.clone(K,T[1]),ee=d(T,Q+U,$+U,f),te=c.generateArc({positions:T,granularity:f,ellipsoid:s}),F=y(te,k,C,F,s,ee,1),u&&(B=m(K,k,D,B,s,$+U,1,1)),L=F.length;var se=u?L+B.length:L,ce=new Float64Array(se);return ce.set(F),u&&ce.set(B,L),ce},P}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,r,n){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=n(new i({position:!0})),i.POSITION_AND_NORMAL=n(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=n(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=n(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=n(new i({position:!0,color:!0})),i.ALL=n(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.position?1:0,r[n++]=t.normal?1:0,r[n++]=t.st?1:0,r[n++]=t.tangent?1:0,r[n++]=t.bitangent?1:0,r[n]=t.color?1:0,r},i.unpack=function(r,n,a){return n=e(n,0),t(a)||(a=new i),a.position=1===r[n++],a.normal=1===r[n++],a.st=1===r[n++],a.tangent=1===r[n++],a.bitangent=1===r[n++],a.color=1===r[n],a},i.clone=function(e,r){if(t(e))return t(r)||(r=new i),r.position=e.position,r.normal=e.normal,r.st=e.st,r.tangent=e.tangent,r.bitangent=e.bitangent,r.color=e.color,r},i}),define("Core/PolylineVolumeGeometry",["./arrayRemoveDuplicates","./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CornerType","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryPipeline","./IndexDatatype","./Math","./oneTimeWarning","./PolygonPipeline","./PolylineVolumeGeometryLibrary","./PrimitiveType","./VertexFormat","./WindingOrder"],function(e,t,r,n,i,a,o,u,s,c,l,f,h,d,p,m,y,E,_,v,T,R,A){"use strict";function g(e,t,n,i){var o=new d;i.position&&(o.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:e}));var u,s,c,l,y,v,R=t.length,A=e.length/3,g=(A-2*R)/(2*R),S=_.triangulate(t),w=(g-1)*R*6+2*S.length,O=m.createTypedArray(A,w),N=2*R,I=0;for(u=0;u<g-1;u++){for(s=0;s<R-1;s++)c=2*s+u*R*2,v=c+N,l=c+1,y=l+N,O[I++]=l,O[I++]=c,O[I++]=y,O[I++]=y,O[I++]=c,O[I++]=v;c=2*R-2+u*R*2,l=c+1,y=l+N,v=c+N,O[I++]=l,O[I++]=c,O[I++]=y,O[I++]=y,O[I++]=c,O[I++]=v}if(i.st||i.tangent||i.bitangent){var x,M,C=new Float32Array(2*A),P=1/(g-1),D=1/n.height,U=n.height/2,b=0;for(u=0;u<g;u++){for(x=u*P,M=D*(t[0].y+U),C[b++]=x,C[b++]=M,s=1;s<R;s++)M=D*(t[s].y+U),C[b++]=x,C[b++]=M,C[b++]=x,C[b++]=M;M=D*(t[0].y+U),C[b++]=x,C[b++]=M}for(s=0;s<R;s++)x=0,M=D*(t[s].y+U),C[b++]=x,C[b++]=M;for(s=0;s<R;s++)x=(g-1)*P,M=D*(t[s].y+U),C[b++]=x,C[b++]=M;o.st=new h({componentDatatype:a.FLOAT,componentsPerAttribute:2,values:new Float32Array(C)})}var L=A-2*R;for(u=0;u<S.length;u+=3){var F=S[u]+L,B=S[u+1]+L,z=S[u+2]+L;O[I++]=F,O[I++]=B,O[I++]=z,O[I++]=z+R,O[I++]=B+R,O[I++]=F+R}var q=new f({attributes:o,indices:O,boundingSphere:r.fromVertices(e),primitiveType:T.TRIANGLES});if(i.normal&&(q=p.computeNormal(q)),i.tangent||i.bitangent){try{q=p.computeTangentAndBitangent(q)}catch(e){E("polyline-volume-tangent-bitangent","Unable to compute tangents and bitangents for polyline volume geometry")}i.tangent||(q.attributes.tangent=void 0),i.bitangent||(q.attributes.bitangent=void 0),i.st||(q.attributes.st=void 0)}return q}function S(e){e=u(e,u.EMPTY_OBJECT);var t=e.polylinePositions,r=e.shapePositions;this._positions=t,this._shape=r,this._ellipsoid=l.clone(u(e.ellipsoid,l.WGS84)),this._cornerType=u(e.cornerType,o.ROUNDED),this._vertexFormat=R.clone(u(e.vertexFormat,R.DEFAULT)),this._granularity=u(e.granularity,y.RADIANS_PER_DEGREE),this._workerName="createPolylineVolumeGeometry";var a=1+t.length*i.packedLength;a+=1+r.length*n.packedLength,this.packedLength=a+l.packedLength+R.packedLength+2}S.pack=function(e,t,r){r=u(r,0);var a,o=e._positions,s=o.length;for(t[r++]=s,a=0;a<s;++a,r+=i.packedLength)i.pack(o[a],t,r);var c=e._shape;for(s=c.length,t[r++]=s,a=0;a<s;++a,r+=n.packedLength)n.pack(c[a],t,r);return l.pack(e._ellipsoid,t,r),r+=l.packedLength,R.pack(e._vertexFormat,t,r),r+=R.packedLength,t[r++]=e._cornerType,t[r]=e._granularity,t};var w=l.clone(l.UNIT_SPHERE),O=new R,N={polylinePositions:void 0,shapePositions:void 0,ellipsoid:w,vertexFormat:O,cornerType:void 0,granularity:void 0};S.unpack=function(e,t,r){t=u(t,0);var a,o=e[t++],c=new Array(o);for(a=0;a<o;++a,t+=i.packedLength)c[a]=i.unpack(e,t);o=e[t++];var f=new Array(o);for(a=0;a<o;++a,t+=n.packedLength)f[a]=n.unpack(e,t);var h=l.unpack(e,t,w);t+=l.packedLength;var d=R.unpack(e,t,O);t+=R.packedLength;var p=e[t++],m=e[t];return s(r)?(r._positions=c,r._shape=f,r._ellipsoid=l.clone(h,r._ellipsoid),r._vertexFormat=R.clone(d,r._vertexFormat),r._cornerType=p,r._granularity=m,r):(N.polylinePositions=c,N.shapePositions=f,N.cornerType=p,N.granularity=m,new S(N))};var I=new t;return S.createGeometry=function(r){var n=r._positions,a=e(n,i.equalsEpsilon),o=r._shape;if(o=v.removeDuplicatesFromShape(o),!(a.length<2||o.length<3)){_.computeWindingOrder2D(o)===A.CLOCKWISE&&o.reverse();var u=t.fromPoints(o,I);return g(v.computePositions(a,o,u,r,!0),o,u,r._vertexFormat)}},S}),define("Workers/createPolylineVolumeGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolylineVolumeGeometry"],function(e,t,r){"use strict";function n(n,i){return e(i)&&(n=r.unpack(n,i)),n._ellipsoid=t.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeOutlineGeometry.js index 229b25bc..053c71bc 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createPolylineVolumeOutlineGeometry.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,_=l*l*d*d,p=f*f*E*E,y=h*h*m*m,T=_+p+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,N=u.z,O=o;O.x=A.x*S*2,O.y=A.y*v*2,O.z=A.z*N*2;var g,M,I,w,x,C,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),b=0;do{B-=b,I=1/(1+B*S),w=1/(1+B*v),x=1/(1+B*N),C=I*I,P=w*w,U=x*x,D=C*I,L=P*w,F=U*x,g=_*C+p*P+y*U-1,M=_*D*S+p*L*v+y*F*N;b=g/(-2*M)}while(Math.abs(g)>r.EPSILON12);return t(c)?(c.x=l*I,c.y=f*w,c.z=h*x,c):new e(l*I,f*w,h*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,_=r(n)?n._centerToleranceSquared:d,p=o(t,E,m,_,c);if(r(p)){var y=e.multiplyComponents(p,m,s);y=e.normalize(y,y);var T=e.subtract(t,p,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,_=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function a(e,r,a){if(n(e)){a=t(a,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,i));++u);if(u===o)return a&&r(e[0],e[e.length-1],i)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,i)||(l.push(c),s=c);return a&&l.length>1&&r(l[0],l[l.length-1],i)&&l.shift(),l}}var i=r.EPSILON10;return a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var _=t.cartesianToCartographic(e[E]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),h=Math.min(h,_.latitude),d=Math.max(d,_.latitude);var p=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,p),f=Math.max(f,p)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var _=1;_<8;++_)m.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,n,a){this.x=r(e,0),this.y=r(t,0),this.width=r(n,0),this.height=r(a,0)}s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.width,t[n]=e.height,t},s.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new s),n.x=e[t++],n.y=e[t++],n.width=e[t++],n.height=e[t],n},s.fromPoints=function(e,t){if(a(t)||(t=new s),!a(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var n=e.length,r=e[0].x,i=e[0].y,o=e[0].x,u=e[0].y,c=1;c<n;c++){var l=e[c],f=l.x,h=l.y;r=Math.min(f,r),o=Math.max(f,o),i=Math.min(h,i),u=Math.max(h,u)}return t.x=r,t.y=i,t.width=o-r,t.height=u-i,t};var c=new i,l=new t,f=new t;return s.fromRectangle=function(t,n,i){if(a(i)||(i=new s),!a(t))return i.x=0,i.y=0,i.width=0,i.height=0,i;n=r(n,c);var o=n.project(u.southwest(t,l)),h=n.project(u.northeast(t,f));return e.subtract(h,o,h),i.x=o.x,i.y=o.y,i.width=h.x,i.height=h.y,i},s.clone=function(e,t){if(a(e))return a(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new s(e.x,e.y,e.width,e.height)},s.union=function(e,t,n){a(n)||(n=new s);var r=Math.min(e.x,t.x),i=Math.min(e.y,t.y),o=Math.max(e.x+e.width,t.x+t.width),u=Math.max(e.y+e.height,t.y+t.height);return n.x=r,n.y=i,n.width=o-r,n.height=u-i,n},s.expand=function(e,t,n){n=s.clone(e,n);var r=t.x-n.x,a=t.y-n.y;return r>n.width?n.width=r:r<0&&(n.width-=r,n.x=t.x),a>n.height?n.height=a:a<0&&(n.height-=a,n.y=t.y),n},s.intersect=function(e,t){var n=e.x,r=e.y,a=t.x,i=t.y;return n>a+t.width||n+e.width<a||r+e.height<i||r>i+t.height?o.OUTSIDE:o.INTERSECTING},s.equals=function(e,t){return e===t||a(e)&&a(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.intersect=function(e){return s.intersect(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,_=e[s.getElementIndex(h,h)],p=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(_-p)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++], -a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),_=2*(i+l),p=2*(a+h),y=-n+u-f+d,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=p,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=_,t[7]=T,t[8]=S,t):new s(E,m,_,p,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,_=-o,p=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=_,t[3]=f,t[4]=E,t[5]=p,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,_,p,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],_=new s,p=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,_),s.transpose(_,p),s.multiply(h,_,h),s.multiply(p,h,h),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,_){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(_,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,_=t.z*t.z,p=t.z*t.w,y=t.w*t.w,T=s-d-_+y,R=2*(c-p),A=2*(f+m),S=2*(c+p),v=-s+d-_+y,N=2*(E-h),O=2*(f-m),g=2*(E+h),M=-s-d+_+y;return r[0]=T*i,r[1]=S*i,r[2]=O*i,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=g*o,r[7]=0,r[8]=A*u,r[9]=N*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,_=f.z,p=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,N=p*-R+y*-A+T*-S,O=E*R+m*A+_*S;return a(n)?(n[0]=u,n[1]=p,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-_,n[11]=0,n[12]=v,n[13]=N,n[14]=O,n[15]=1,n):new l(u,s,c,v,p,y,T,N,-E,-m,-_,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,_=o+l,p=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=_,a[14]=p,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],_=e[13],p=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],N=t[5],O=t[6],g=t[7],M=t[8],I=t[9],w=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+h*A+_*S,B=i*T+c*R+d*A+p*S,b=o*T+l*R+E*A+y*S,z=r*v+u*N+f*O+m*g,q=a*v+s*N+h*O+_*g,G=i*v+c*N+d*O+p*g,W=o*v+l*N+E*O+y*g,X=r*M+u*I+f*w+m*x,V=a*M+s*I+h*w+_*x,H=i*M+c*I+d*w+p*x,Y=o*M+l*I+E*w+y*x,k=r*C+u*P+f*U+m*D,Z=a*C+s*P+h*U+_*D,j=i*C+c*P+d*U+p*D,K=o*C+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=X,n[9]=V,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],_=t[1],p=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],N=t[12],O=t[13],g=t[14],M=r*m+o*_+c*p,I=a*m+u*_+l*p,w=i*m+s*_+f*p,x=r*y+o*T+c*R,C=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*v,D=a*A+u*S+l*v,L=i*A+s*S+f*v,F=r*N+o*O+c*g+h,B=a*N+u*O+l*g+d,b=i*N+s*O+f*g+E;return n[0]=M,n[1]=I,n[2]=w,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],_=t[4],p=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=a*h+u*d+l*E,v=i*h+s*d+f*E,N=r*m+o*_+c*p,O=a*m+u*_+l*p,g=i*m+s*_+f*p,M=r*y+o*T+c*R,I=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=N,n[5]=O,n[6]=g,n[7]=0,n[8]=M,n[9]=I,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var _=new e;l.multiplyByUniformScale=function(e,t,n){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var p=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,p),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],_=e[6],A=e[10],S=e[14],v=e[3],N=e[7],O=e[11],g=e[15],M=A*g,I=S*O,w=_*g,x=S*N,C=_*O,P=A*N,U=m*g,D=S*v,L=m*O,F=A*v,B=m*N,b=_*v,z=M*h+x*d+C*E-(I*h+w*d+P*E),q=I*f+U*d+F*E-(M*f+D*d+L*E),G=w*f+D*h+B*E-(x*f+U*h+b*E),W=P*f+L*h+b*d-(C*f+F*h+B*d),X=I*a+w*i+P*o-(M*a+x*i+C*o),V=M*r+D*i+L*o-(I*r+U*i+F*o),H=x*r+U*a+b*o-(w*r+D*a+B*o),Y=C*r+F*a+B*i-(P*r+L*a+b*i);M=i*E,I=o*d,w=a*E,x=o*h,C=a*d,P=i*h,U=r*E,D=o*f,L=r*d,F=i*f,B=r*h,b=a*f;var k=M*N+x*O+C*g-(I*N+w*O+P*g),Z=I*v+U*O+F*g-(M*v+D*O+L*g),j=w*v+D*N+B*g-(x*v+U*N+b*g),K=P*v+L*N+b*O-(C*v+F*N+B*O),J=w*A+P*S+I*_-(C*S+M*_+x*A),Q=L*S+M*m+D*A-(U*A+F*S+I*m),$=U*_+b*S+x*m-(B*S+w*m+D*_),ee=B*A+C*m+F*_-(L*_+b*A+P*m),te=r*z+a*q+i*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=X*te,n[5]=V*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,_=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,E=new e,m=new e,_=new e,p=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,N=new e;h.fromPoints=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,d),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,_),l=e.clone(i,p),f=e.clone(i,y),O=t.length;for(r=1;r<O;r++){e.clone(t[r],i);var g=i.x,M=i.y,I=i.z;g<o.x&&e.clone(i,o),g>c.x&&e.clone(i,c),M<u.y&&e.clone(i,u),M>l.y&&e.clone(i,l),I<s.z&&e.clone(i,s),I>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=v;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,N),G=0;for(r=0;r<O;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var X=e.magnitudeSquared(e.subtract(i,L,R));if(X>F){var V=Math.sqrt(X);B=.5*(B+V),F=B*B;var H=V-B;L.x=(B*L.x+H*i.x)/V,L.y=(B*L.y+H*i.y)/V,L.z=(B*L.z+H*i.z)/V}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var O=new o,g=new e,M=new e,I=new t,w=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),f.southwest(t,I),I.height=i,f.northeast(t,w),w.height=o;var s=n.project(I,g),c=n.project(w,M),l=c.x-s.x,d=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*E,u};var x=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,x);return h.fromPoints(s,u)},h.fromVertices=function(t,n,i,o){if(a(o)||(o=new h),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,E),f=e.clone(u,m),O=e.clone(u,_),g=e.clone(u,p),M=e.clone(u,y),I=t.length;for(s=0;s<I;s+=i){var w=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=w,u.y=x,u.z=C,w<c.x&&e.clone(u,c),w>O.x&&e.clone(u,O),x<l.y&&e.clone(u,l),x>g.y&&e.clone(u,g),C<f.z&&e.clone(u,f),C>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(O,c,R)),U=e.magnitudeSquared(e.subtract(g,l,R)),D=e.magnitudeSquared(e.subtract(M,f,R)),L=c,F=O,B=P;U>B&&(B=U,L=l,F=g),D>B&&(B=D,L=f,F=M);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=v;W.x=O.x,W.y=g.y,W.z=M.z;var X=e.multiplyByScalar(e.add(G,W,R),.5,N),V=0;for(s=0;s<I;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,R));H>V&&(V=H);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;b.x=(q*b.x+Z*u.x)/k,b.y=(q*b.y+Z*u.y)/k,b.z=(q*b.z+Z*u.z)/k}}return q<V?(e.clone(b,o.center),o.radius=q):(e.clone(X,o.center),o.radius=V),o},h.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new h),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,d),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,_),f=e.clone(i,p),O=e.clone(i,y),g=t.length;for(o=0;o<g;o+=3){var M=t[o]+n[o],I=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=M,i.y=I,i.z=w,M<u.x&&e.clone(i,u),M>l.x&&e.clone(i,l),I<s.y&&e.clone(i,s),I>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>O.z&&e.clone(i,O)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(O,c,R)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=O);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=v;q.x=l.x,q.y=f.y,q.z=O.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,N),W=0;for(o=0;o<g;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,G,R));X>W&&(W=X);var V=e.magnitudeSquared(e.subtract(i,F,R));if(V>B){var H=Math.sqrt(V);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},h.fromCornerPoints=function(t,n,r){a(r)||(r=new h);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},h.fromEllipsoid=function(t,n){return a(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;h.fromBoundingSpheres=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;h.fromOrientedBoundingBox=function(t,n){a(n)||(n=new h);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},h.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new h);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;h.union=function(t,n,r){a(r)||(r=new h);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r -;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(d,i,d),e.clone(d,r.center),r.radius=f,r};var B=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,W=new e,X=new e,V=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,V),d=e.negate(c,X),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,d,m),m=E[2],e.add(s,f,m),e.add(m,d,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,d,m),m=E[6],e.add(s,f,m),e.add(m,d,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var _=E.length,p=0;p<_;++p){var y=E[p];e.add(o,y,y);var T=i.cartesianToCartographic(y,H);n.project(T,y)}a=h.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(v)&&(v=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,N=r(e[1]))}return v}function u(){return o()&&N}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0,g=r(e[1]),g.isNightly=!!e[2])}return O}function c(){return s()&&g}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,I=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,I=r(e[1]))}return M}function f(){return l()&&I}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,x=r(e[1]))}return w}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function _(){return E()&&P}function p(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,N,O,g,M,I,w,x,C,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:_,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:p,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,f,h,d,E,m,_;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=h=e[0],f=d=e[1];for(var p=a;p<o;p+=a)E=e[p],m=e[p+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);_=Math.max(h-l,d-f)}return r(u,c,a,l,f,_),c}function t(e,t,n,r,a){var i,o;if(a===I(e,t,n,r)>0)for(i=t;i<n;i+=r)o=O(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=O(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(g(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(g(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,_=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?i(e,c,l,f):a(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),g(e),e=m.next,_=m.next;else if((e=m)===_){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(_(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&y(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(y(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&_(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&_(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&S(a,i)&&S(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),g(r),g(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&p(s,c)){var l=N(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,f=o<u-1?r[o+1]*i:e.length,h=t(e,s,f,i,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=N(t,e);n(r,r.next)}}function f(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&_(i<f?a:o,i,l,f,i<f?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<h||s===h&&r.x>n.x)&&S(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var a=e;do{null===a.z&&(a.z=E(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,d(a)}function d(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function _(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function p(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!A(e,t)&&S(e,t)&&S(t,e)&&v(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function A(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function S(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function v(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function N(e,t){var n=new M(e.i,e.x,e.y),r=new M(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function O(e,t,n,r){var a=new M(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function g(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function M(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function I(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(I(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(I(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)} -;var _=new n,p=new n,y=new n,T=new n,R=new n,A=new n,S=new n;return m.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),v=0;for(h=0;h<E;h++){var N=t[h];m[v++]=N.x,m[v++]=N.y,m[v++]=N.z}for(var O=[],g={},M=e.maximumRadius,I=l.chordLength(u,M),w=I*I;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,_),F=n.fromArray(m,3*U,p),B=n.fromArray(m,3*P,y),b=n.multiplyByScalar(n.normalize(L,T),M,T),z=n.multiplyByScalar(n.normalize(F,R),M,R),q=n.multiplyByScalar(n.normalize(B,A),M,A),G=n.magnitudeSquared(n.subtract(b,z,S)),W=n.magnitudeSquared(n.subtract(z,q,S)),X=n.magnitudeSquared(n.subtract(q,b,S)),V=Math.max(G,W,X);V>w?G===V?(x=Math.min(D,U)+" "+Math.max(D,U),h=g[x],o(h)||(C=n.add(L,F,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,g[x]=h),d.push(D,h,P),d.push(h,U,P)):W===V?(x=Math.min(U,P)+" "+Math.max(U,P),h=g[x],o(h)||(C=n.add(F,B,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,g[x]=h),d.push(U,h,D),d.push(h,P,D)):X===V&&(x=Math.min(P,D)+" "+Math.max(P,D),h=g[x],o(h)||(C=n.add(B,L,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,g[x]=h),d.push(P,h,U),d.push(h,D,U)):(O.push(D),O.push(U),O.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:m})},indices:O,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=d,c=E;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,_=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(_,u),l=Math.max(_,l)}var p=n.minimum;p.x=a,p.y=o,p.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(p,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,_=u*c-d,p=4*E*_-m*m;if(p<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=_,R=-c*m+2*s*_);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-p);i=-R+S;var v=i/2,N=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),O=i===S?-N:-T/N;return a=T<=0?N+O:-R/(N*N+O*O+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var g=E,M=-2*u*E+o*m,I=_,w=-c*m+2*s*_,x=Math.sqrt(p),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-M)/3);a=2*Math.sqrt(-g);var U=Math.cos(P);i=a*U;var D=a*(-U/2-C*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*x,-w)/3),a=2*Math.sqrt(-I),U=Math.cos(P),i=a*U,D=a*(-U/2-C*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,X=L*b,V=(s*W-u*X)/(-u*W+s*G);return B<=V?B<=q?V<=q?[B,V,q]:[B,q,V]:[q,B,V]:B<=q?[V,B,q]:V<=q?[V,q,B]:[q,V,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,_=E[0],p=E[1];if(_>=0&&p>=0){var y=Math.sqrt(_),T=Math.sqrt(p);return[h-T,h-y,h+y,h+T]}if(_>=0&&p<0)return m=Math.sqrt(_),[h-m,h+m];if(_<0&&p>=0)return m=Math.sqrt(p),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),N=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==N.length?(N[0]+=h,N[1]+=h,v[1]<=N[0]?[v[0],v[1],N[0],N[1]]:N[1]<=v[0]?[N[0],N[1],v[0],v[1]]:v[0]>=N[0]&&v[1]<=N[1]?[N[0],v[0],v[1],N[1]]:N[0]>=v[0]&&N[1]<=v[1]?[v[0],N[0],N[1],v[1]]:v[0]>N[0]&&v[0]<N[1]?[N[0],v[0],N[1],v[1]]:[v[0],N[0],v[1],N[1]]):v):0!==N.length?(N[0]+=h,N[1]+=h,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,_=d[0],p=a-_,y=p*p,T=t/2,R=p/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*_,N=c+4*Math.abs(_);if(_<0||A*N<v*S){var O=Math.sqrt(v);E=O/2,m=0===O?0:(t*R-i)/O}else{var g=Math.sqrt(A);E=0===g?0:(t*R-i)/g,m=g/2}var M,I;0===T&&0===E?(M=0,I=0):n.sign(T)===n.sign(E)?(M=T+E,I=_/M):(I=T-E,M=_/I);var w,x;0===R&&0===m?(w=0,x=0):n.sign(R)===n.sign(m)?(w=R+m,x=o/w):(x=R-m,w=o/x);var C=r.computeRealRoots(1,M,w),P=r.computeRealRoots(1,I,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),_=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,p=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===p){if(l=s.computeRealRoots(E,m,_),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-v)),T.push(new e(a,i*S,i*v))}return T}var N=y*y,O=p*p,g=E*E,M=y*p,I=g+O,w=2*(m*E+M),x=2*_*E+m*m-O+N,C=2*(_*m-M),P=_*_-N;if(0===I&&0===w&&0===x&&0===C)return T;l=c.computeRealRoots(I,w,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(_)?d(E*B+_,m*F,o.EPSILON12):o.sign(_)===o.sign(m*F)?d(E*B,m*F+_,o.EPSILON12):d(E*B+m*F,_,o.EPSILON12);var q=d(p*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,p=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,_),A=e.subtract(i,r,p),S=e.cross(E,A,y),v=e.dot(m,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var N=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*N)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*N)<0||l+f>1)return;h=e.dot(A,c)*N}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;m.lineSegmentSphere=function(t,n,a,i){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,O=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),f=e.multiplyComponents(c,t.direction,O),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,_=r/s;return m<_?new i(m,_):{start:_,stop:m}}var p=Math.sqrt(r/a);return new i(p,p)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var g=new e,M=new e,I=new e,w=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,g);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,g),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,M),M),m=e.normalize(e.cross(f,d,I),I),_=C;_[0]=f.x,_[1]=f.y,_[2]=f.z,_[3]=d.x,_[4]=d.y,_[5]=d.z,_[6]=m.x,_[7]=m.y,_[8]=m.z;var p=u.transpose(_,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,v=u.multiply(u.multiply(p,T,F),R,F),N=u.multiply(u.multiply(v,y,B),_,B),O=u.multiplyByVector(v,a,x),G=E(N,e.negate(O,g),0,0,1),W=G.length;if(W>0){for(var X=e.clone(e.ZERO,z),V=Number.NEGATIVE_INFINITY,H=0;H<W;++H){A=u.multiplyByVector(y,u.multiplyByVector(_,G[H],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>V&&(V=k,X=e.clone(A,X))}var Z=n.cartesianToCartographic(X,q);return V=o.clamp(V,0,1),S=e.magnitude(e.subtract(X,a,w))*Math.sqrt(1-V*V),S=c?-S:S,Z.height=S,n.cartographicToCartesian(Z,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=p,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return _(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,_,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(_=d.progress,m=function(e){h.push(e),--l||(E=m=p,d.reject(h))},E=function(e){f.push(e),--c||(E=m=p,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,_);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return _(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function _(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function p(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,_,p;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,N=0;s&&N<v;N++)switch(s.charAt(N)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(N+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,p=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(p),y,c,f,R,S);case"c":return u(String.fromCharCode(+p),y,c,f,R);case"b":return o(p,2,A,y,c,f,R);case"o":return o(p,8,A,y,c,f,R);case"x":return o(p,16,A,y,c,f,R);case"X":return o(p,16,A,y,c,f,R).toUpperCase();case"u":return o(p,10,A,y,c,f,R);case"i":case"d":return d=+p||0,d=Math.round(d-d%1),E=d<0?"-":T,p=E+a(String(Math.abs(d)),f,"0",!1),i(p,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+p,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],_=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],p=E+Math.abs(d)[m](f),i(p,E,y,c,R)[_]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var _=new i,p=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,N=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+N.source,g=/^(\d{2}):?(\d{2})(\.\d+)?/.source+N.source,M=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+N.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,_=0,y=0,N=0,I=u[0],w=u[1];if(null!==(u=I.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(R)))n=+u[1],s=+u[2];else if(null!==(u=I.match(T)))n=+u[1];else{var x;if(null!==(u=I.match(A)))n=+u[1],x=+u[2],i=o(n);else if(null!==(u=I.match(S))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(M),null!==u?(h=+u[1],_=+u[2],y=+u[3],N=1e3*+(u[4]||0),D=5):(u=w.match(g),null!==u?(h=+u[1],_=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(O))&&(h=+u[1],_=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,_-=B;break;case"-":h+=F,_+=B;break;case"Z":break;default:_+=new Date(Date.UTC(n,s-1,l,h,_)).getTimezoneOffset()}}var b=60===y;for(b&&y--;_>=60;)_-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:p[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:p[s-1];for(;_<0;)_+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:p[s-1],l+=a;var z=E(n,s,l,h,_,y,N);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var I=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,I);r(a)||(m.addSeconds(e,-1,I),a=h(I,I),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var _=d+2-12*c|0,p=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=p,t.month=_,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(p,_,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,_),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,_);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}} -function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return N[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function _(e){var t=d(e);return e.state=s.ACTIVE,v.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function p(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A);var v=[],N={},O="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();p(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=v.length;for(e=0;e<r;++e)t=v[e],t.cancelled&&p(t),t.state===s.ACTIVE?n>0&&(v[e-n]=t):++n;v.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-v.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?p(t):!t.throttleByServer||h(t.serverKey)?(_(t),++u):p(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=N[a];return r(i)||(N[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return _(e);if(!(v.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;p(t)}return d(e)}},l.clearForSpecs=function(){for(;S.length>0;){p(S.pop())}for(var e=v.length,t=0;t<e;++t)p(v[t]);v.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return N[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;a=n(a,t.url);var d=r(t.request)?t.request:new i;return d.url=a,d.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function d(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return h(a,i);case"blob":var o=h(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&h.setRequestHeader(m,i[m]);r(t)&&(h.responseType=t);var _=!1;return"string"==typeof e&&(_=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!_||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(a),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var _=e._samples=n.samples,p=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=_.length;R<A;R+=e._columnCount){var S=_[R+a],v=_[R+m],N=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(N,v,f.TAI);if(p.push(O),T){if(v!==y&&r(y)){var g=o.leapSeconds,M=t(g,O,d);if(M<0){var I=new u(O,v);g.splice(~M,0,I)}}y=v}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function _(e,t,n){return t+e*(n-t)}function p(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],p=n[d+e._ut1MinusUtcSecondsColumn],y=p-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=p:p-=R-T)}return u.xPoleWander=_(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=_(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=_(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=_(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=_(f,E,p),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,p(this,i,this._samples,e,s,l,n),n}var _=t(i,e,o.compare,this._dateColumn);return _>=0?(_<i.length-1&&i[_+1].equals(e)&&++_,s=_,l=_):(l=~_,(s=l-1)<0&&(s=0)),this._lastIndex=s,p(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,_=i-s*this._stepSizeDays,p=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)p[E]=_-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=p[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var _=l,p=0;d>h&&(p=1),E>h&&E>d&&(p=2);var y=_[p],T=_[y];n=Math.sqrt(e[u.getElementIndex(p,p)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[p]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,p)]+e[u.getElementIndex(p,y)])*n,R[T]=(e[u.getElementIndex(T,p)]+e[u.getElementIndex(p,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var _=new e,p=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,_);var u=s.computeAngle(y);r[o]=_.x*u,r[o+1]=_.y*u,r[o+2]=_.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,p);var u=e.magnitude(p);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(p,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,N=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),N=s.multiplyByScalar(i,Math.sin(n*u),N),r=s.add(v,N,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var O=new e,g=new e,M=new s,I=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,M);s.multiply(i,r,I);var o=s.log(I,O);s.multiply(i,t,I);var u=s.log(I,g);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,M),u=s.slerp(n,r,a,I);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;C[L]=1/(F*B),P[L]=F/B}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,M),u=s.fastSlerp(n,r,a,I);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,_,p,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},N={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,g=new n,M=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(v[i])?r=v[i]:(r=function(r,i,s){if(u(s)||(s=new p),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(S[t],0,g),"east"!==t&&"west"!==t&&n.multiplyByScalar(g,c,g),n.unpack(S[a],0,M),"east"!==a&&"west"!==a&&n.multiplyByScalar(M,c,M)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,N.up);var l=N.up,h=N.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,N.east),n.cross(l,h,N.north),n.multiplyByScalar(N.up,-1,N.down),n.multiplyByScalar(N.east,-1,N.west),n.multiplyByScalar(N.north,-1,N.south),O=N[e],g=N[t],M=N[a]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=g.x,s[5]=g.y,s[6]=g.z,s[7]=0,s[8]=M.x,s[9]=M.y,s[10]=M.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var I=new y,w=new n(1,1,1),x=new p;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,I),s=p.fromTranslationQuaternionRotationScale(n.ZERO,u,w,x);return i=a(e,r,i),p.multiply(i,s,i)};var C=new p,P=new _;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=p.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new _(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new _);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return _.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new _,b=new _;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new _);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=_.fromRotationZ(-i.s,b),h=_.multiply(l,f,B),d=e.dayNumber,p=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=p/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var v=_.fromRotationZ(S,b),N=_.multiply(h,v,B),O=Math.cos(n.xPoleWander),g=Math.cos(n.yPoleWander),M=Math.sin(n.xPoleWander),I=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var x=-47e-6*w*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=b;return U[0]=O*C,U[1]=O*P,U[2]=M,U[3]=-g*P+I*M*C,U[4]=g*C+I*M*P,U[5]=-I*O,U[6]=-I*P-g*M*C,U[7]=I*C-g*M*P,U[8]=g*O,_.multiply(N,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return p.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),p.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W) -;return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new _),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var X=new p(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),V=new a,H=new n,Y=new n,k=new _,Z=new p,j=new p;return R.basisTo2D=function(e,t,r){var a=p.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,V),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,Z),c=p.inverseTransformation(s,j),l=p.getRotation(t,k),f=p.multiplyByMatrix3(c,l,r);return p.multiply(X,f,r),p.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,Z),o=p.inverseTransformation(i,j),u=a.cartesianToCartographic(t,V),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=p.fromTranslation(s,Z);return p.multiply(X,o,r),p.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var _=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,_).center,n)};var p=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=p;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=p;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,a=(n-r)/n,i=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,i),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,_=m*m,p=_*m,y=_*_,T=1+m-3*_/4+5*p/4-175*y/64,R=1-m+15*_/8-35*p/8,A=1-3*m+35*_/4,S=1-5*m,v=T*l-R*Math.sin(2*l)*m/2-A*Math.sin(4*l)*_/16-S*Math.sin(6*l)*p/48-5*Math.sin(8*l)*y/512,N=e._constants;N.a=n,N.b=r,N.f=a,N.cosineHeading=i,N.sineHeading=o,N.tanU=u,N.cosineU=s,N.sineU=c,N.sigma=l,N.sineAlpha=f,N.sineSquaredAlpha=h,N.cosineSquaredAlpha=d,N.cosineAlpha=E,N.u2Over4=m,N.u4Over16=_,N.u6Over64=p,N.u8Over256=y,N.a0=T,N.a1=R,N.a2=A,N.a3=S,N.distanceRatio=v}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,a,i,o){var u=c(e,n);return(1-u)*e*t*(r+u*a*(o+u*i*(2*o*o-1)))}function f(e,t,n,r,a,i,o){var s,c,f,h,d,E=(t-n)/t,m=i-r,_=Math.atan((1-E)*Math.tan(a)),p=Math.atan((1-E)*Math.tan(o)),y=Math.cos(_),T=Math.sin(_),R=Math.cos(p),A=Math.sin(p),S=y*R,v=y*A,N=T*A,O=T*R,g=m,M=u.TWO_PI,I=Math.cos(g),w=Math.sin(g);do{I=Math.cos(g),w=Math.sin(g);var x=v-O*I;f=Math.sqrt(R*R*w*w+x*x),c=N+S*I,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=S*w/f,h=1-C*C),M=g,d=c-2*N/h,isNaN(d)&&(d=0),g=m+l(E,C,h,s,f,c,d)}while(Math.abs(g-M)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),B=n*U*(s-F),b=Math.atan2(R*w,v-O*I),z=Math.atan2(y*w,v*I-O);e._distance=B,e._startHeading=b,e._endHeading=z,e._uSquared=P}function h(n,r,a,i){e.normalize(i.cartographicToCartesian(r,m),E),e.normalize(i.cartographicToCartesian(a,m),m);f(n,i.maximumRadius,i.minimumRadius,r.longitude,r.latitude,a.longitude,a.latitude),n._start=t.clone(r,n._start),n._end=t.clone(a,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,i){var u=r(i,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(n)&&h(this,e,n,u)}var E=new e,m=new e;return i(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,i=r.distanceRatio+e/r.b,o=Math.cos(2*i),u=Math.cos(4*i),s=Math.cos(6*i),c=Math.sin(2*i),f=Math.sin(4*i),h=Math.sin(6*i),d=Math.sin(8*i),E=i*i,m=i*E,_=r.u8Over256,p=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*_*o/3+i*(1-p+7*T/4-15*y/4+579*_/64-(T-15*y/4+187*_/16)*o-(5*y/4-115*_/16)*u-29*_*s/16)+(p/2-T+71*y/32-85*_/16)*c+(5*T/16-5*y/4+383*_/96)*f-E*((y-11*_/2)*c+5*_*f/2)+(29*y/96-29*_/16)*h+539*_*d/1536,A=Math.asin(Math.sin(R)*r.cosineAlpha),S=Math.atan(r.a/r.b*Math.tan(A));R-=r.sigma;var v=Math.cos(2*r.sigma+R),N=Math.sin(R),O=Math.cos(R),g=r.cosineU*O,M=r.sineU*N,I=Math.atan2(N*r.sineHeading,g-M*r.cosineHeading),w=I-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,N,O,v);return a(n)?(n.longitude=this._start.longitude+w,n.latitude=S,n.height=0,n):new t(this._start.longitude+w,S,0)},d}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=N;r.length=e;var a;if(t===n){for(a=0;a<e;a++)r[a]=t;return r}var i=n-t,o=i/e;for(a=0;a<e;a++){var u=t+a*o;r[a]=u}return r}function d(t,n,r,a,i,o,u,s){var c=a.scaleToGeodeticSurface(t,I),l=a.scaleToGeodeticSurface(n,w),f=E.numberOfPoints(t,n,r),d=a.cartesianToCartographic(c,O),m=a.cartesianToCartographic(l,g),_=h(f,i,o);x.setEndPoints(d,m);var p=x.surfaceDistance/f,y=s;d.height=i;var T=a.cartographicToCartesian(d,M);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var A=x.interpolateUsingSurfaceDistance(R*p,g);A.height=_[R],T=a.cartographicToCartesian(A,M),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var a=e.distance(t,n);return Math.ceil(a/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),a=0;a<n;a++){var i=e[a];r[a]=t.cartesianToCartographic(i,m).height}return r};var _=new l,p=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,A=new f(e.UNIT_X,0),S=new e,v=new e,N=[],O=new t,g=new t,M=new e,I=new e,w=new e,x=new o;return E.wrapLongitude=function(t,a){var i=[],o=[];if(r(t)&&t.length>0){a=n(a,l.IDENTITY);var s=l.inverseTransformation(a,_),c=l.multiplyByPoint(s,e.ZERO,p),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,A),N=1;i.push(e.clone(t[0]));for(var O=i[0],g=t.length,M=1;M<g;++M){var I=t[M];if(f.getPointDistance(m,O)<0||f.getPointDistance(m,I)<0){var w=u.lineSegmentPlane(O,I,d,S);if(r(w)){var x=e.multiplyByScalar(h,5e-9,v);f.getPointDistance(d,O)<0&&e.negate(x,x),i.push(e.add(w,x,new e)),o.push(N+1),e.negate(x,x),i.push(e.add(w,x,new e)),N=1}}i.push(e.clone(t[M])),N++,O=I}o.push(N)}return{positions:i,lengths:o}},E.generateArc=function(t){r(t)||(t={});var a=t.positions,o=a.length,u=n(t.ellipsoid,i.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(a[0],I);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,M);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var _=t.minDistance;if(!r(_)){var p=n(t.granularity,c.RADIANS_PER_DEGREE);_=c.chordLength(p,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(a[y],a[y+1],_);var R=3*(T+1),A=new Array(R),S=0;for(y=0;y<o-1;y++){S=d(a[y],a[y+1],_,u,f?l[y]:l,f?l[y+1]:l,A,S)}N.length=0;var v=a[o-1],g=u.cartesianToCartographic(v,O);g.height=f?l[o-1]:l;var w=u.cartographicToCartesian(g,M);return e.pack(w,A,R-3),A},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,a=new Array(r),i=0;i<r;i++)a[i]=e.unpack(n,3*i);return a},E}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var a=e[r];U=t.cartesianToCartographic(a,U),n[r]=U.height,e[r]=t.scaleToGeodeticSurface(a,a)}return n}function d(e,n,r,a){var i,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/a),l=new Array(c);if(n===r){for(i=0;i<c;i++)l[i]=n;return l.push(r),l}var f=r-n,h=f/c;for(i=1;i<c;i++){var d=n+i*h;l[i]=d}return l[0]=n,l.push(r),l}function E(n,r,a,o){var u=new i(a,o),s=u.projectPointOntoPlane(t.add(a,n,D),D),c=u.projectPointOntoPlane(t.add(a,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function m(e,n,r,a,i,o,c,l){var h=G,d=W;B=f.eastNorthUpToFixedFrame(e,i,B),h=s.multiplyByPointAsVector(B,F,h),h=t.normalize(h,h);var m=E(h,n,e,i);z=u.fromRotationZ(m,z),X.z=o,B=s.multiplyTransformation(B,s.fromRotationTranslation(z,X,b),B);var _=q;_[0]=c;for(var p=0;p<l;p++)for(var y=0;y<r.length;y+=3)d=t.fromArray(r,y,d),d=u.multiplyByVector(_,d,d),d=s.multiplyByPoint(B,d,d),a.push(d.x,d.y,d.z);return a}function _(e,n,r,a,i,o,u){for(var s=0;s<e.length;s+=3){a=m(t.fromArray(e,s,V),n,r,a,i,o[s/3],u,1)}return a}function p(e,t){var n=e.length,r=new Array(6*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-i,l=u.y-o;r[a++]=c,r[a++]=0,r[a++]=l,r[a++]=c,r[a++]=0,r[a++]=l}return u=e[0],r[a++]=u.x-i,r[a++]=0,r[a++]=u.y-o,r}function y(e,t){for(var n=e.length,r=new Array(3*n),a=0,i=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[a++]=e[u].x-i,r[a++]=0,r[a++]=e[u].y-o;return r}function T(e,n,r,i,s,c,f,h,d,E){var _,p=t.angleBetween(t.subtract(n,e,x),t.subtract(r,e,C)),y=i===a.BEVELED?0:Math.ceil(p/o.toRadians(5));_=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,x),p/(y+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,p/(y+1),H),k);var T,R;if(n=t.clone(n,Y),y>0)for(var A=E?2:1,S=0;S<y;S++)n=u.multiplyByVector(_,n,n),T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,h,f,c,d,1,A);else T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=m(R,T,h,f,c,d,1,1),r=t.clone(r,Y),T=t.subtract(r,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(r,C),f=m(R,T,h,f,c,d,1,1);return f}var R=[new t,new t],A=new t,S=new t,v=new t,N=new t,O=new t,g=new t,M=new t,I=new t,w=new t,x=new t,C=new t,P={},U=new r,D=new t,L=new t,F=new t(-1,0,0),B=new s,b=new s,z=new u,q=u.IDENTITY.clone(),G=new t,W=new n,X=new t,V=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],a=n-1,i=0;i<n;a=i++){var o=t[a],u=t[i];e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,a){var o=new i(r,a),u=o.projectPointOntoPlane(t.add(r,e,D),D),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var Z=new t,j=new t;return P.computePositions=function(e,n,r,i,u){var s=i._ellipsoid,l=h(e,s),f=i._granularity,E=i._cornerType,C=u?p(n,r):y(n,r),U=u?y(n,r):void 0,D=r.height/2,L=r.width/2,F=e.length,B=[],b=u?[]:void 0,z=A,q=S,G=v,W=N,X=O,V=g,H=M,Y=I,k=w,K=e[0],J=e[1];W=s.geodeticSurfaceNormal(K,W),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(W,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(b=m(K,Y,U,b,s,Q+D,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<F-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),W=s.geodeticSurfaceNormal(K,W);var ae=t.multiplyByScalar(W,t.dot(z,W),Z);t.subtract(z,ae,ae),t.normalize(ae,ae);var ie=t.multiplyByScalar(W,t.dot(q,W),j);t.subtract(q,ie,ie),t.normalize(ie,ie);if(!o.equalsEpsilon(Math.abs(t.dot(ae,ie)),1,o.EPSILON7)){G=t.cross(G,W,G),G=t.cross(W,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,x))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(X=t.add(K,t.multiplyByScalar(G,oe*L,G),X),V=t.add(X,t.multiplyByScalar(Y,L,V),V),R[0]=t.clone(k,R[0]),R[1]=t.clone(V,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=_(te,Y,C,B,s,ee,1),Y=t.cross(W,z,Y),Y=t.normalize(Y,Y),H=t.add(X,t.multiplyByScalar(Y,L,H),H),E===a.ROUNDED||E===a.BEVELED?T(X,V,H,E,ue,s,B,C,$+D,u):(G=t.negate(G,G),B=m(K,G,C,B,s,$+D,oe,re)),k=t.clone(H,k)):(X=t.add(K,t.multiplyByScalar(G,oe*L,G),X),V=t.add(X,t.multiplyByScalar(Y,-L,V),V),R[0]=t.clone(k,R[0]),R[1]=t.clone(V,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=_(te,Y,C,B,s,ee,1),Y=t.cross(W,z,Y),Y=t.normalize(Y,Y),H=t.add(X,t.multiplyByScalar(Y,-L,H),H),E===a.ROUNDED||E===a.BEVELED?T(X,V,H,E,ue,s,B,C,$+D,u):B=m(K,G,C,B,s,$+D,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else B=m(k,Y,C,B,s,Q+D,1,1),k=K;Q=$,$=l[ne+1],K=J}R[0]=t.clone(k,R[0]),R[1]=t.clone(K,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=_(te,Y,C,B,s,ee,1),u&&(b=m(K,Y,U,b,s,$+D,1,1)),F=B.length;var se=u?F+b.length:F,ce=new Float64Array(se);return ce.set(B),u&&ce.set(b,F),ce},P}),define("Core/PolylineVolumeOutlineGeometry",["./arrayRemoveDuplicates","./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CornerType","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PolylineVolumeGeometryLibrary","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,_,p,y,T){"use strict";function R(e,t){var r=new d;r.position=new h({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:e});var a,o,u=t.length,s=r.position.values.length/3,c=e.length/3,l=c/u,m=E.createTypedArray(s,2*u*(l+1)),_=0;a=0;var p=a*u;for(o=0;o<u-1;o++)m[_++]=o+p,m[_++]=o+p+1;for(m[_++]=u-1+p,m[_++]=p,a=l-1,p=a*u,o=0;o<u-1;o++)m[_++]=o+p,m[_++]=o+p+1;for(m[_++]=u-1+p,m[_++]=p,a=0;a<l-1;a++){var T=u*a,R=T+u;for(o=0;o<u;o++)m[_++]=o+T,m[_++]=o+R}return new f({attributes:r,indices:E.createTypedArray(s,m),boundingSphere:n.fromVertices(e),primitiveType:y.LINES})}function A(e){e=u(e,u.EMPTY_OBJECT);var t=e.polylinePositions,n=e.shapePositions;this._positions=t,this._shape=n,this._ellipsoid=l.clone(u(e.ellipsoid,l.WGS84)),this._cornerType=u(e.cornerType,o.ROUNDED),this._granularity=u(e.granularity,m.RADIANS_PER_DEGREE),this._workerName="createPolylineVolumeOutlineGeometry";var i=1+t.length*a.packedLength;i+=1+n.length*r.packedLength,this.packedLength=i+l.packedLength+2}A.pack=function(e,t,n){n=u(n,0);var i,o=e._positions,s=o.length;for(t[n++]=s,i=0;i<s;++i,n+=a.packedLength)a.pack(o[i],t,n);var c=e._shape;for(s=c.length,t[n++]=s,i=0;i<s;++i,n+=r.packedLength)r.pack(c[i],t,n);return l.pack(e._ellipsoid,t,n),n+=l.packedLength,t[n++]=e._cornerType,t[n]=e._granularity,t};var S=l.clone(l.UNIT_SPHERE),v={polylinePositions:void 0,shapePositions:void 0,ellipsoid:S,height:void 0,cornerType:void 0,granularity:void 0};A.unpack=function(e,t,n){t=u(t,0);var i,o=e[t++],c=new Array(o);for(i=0;i<o;++i,t+=a.packedLength)c[i]=a.unpack(e,t);o=e[t++];var f=new Array(o);for(i=0;i<o;++i,t+=r.packedLength)f[i]=r.unpack(e,t);var h=l.unpack(e,t,S);t+=l.packedLength;var d=e[t++],E=e[t];return s(n)?(n._positions=c,n._shape=f,n._ellipsoid=l.clone(h,n._ellipsoid),n._cornerType=d,n._granularity=E,n):(v.polylinePositions=c,v.shapePositions=f,v.cornerType=d,v.granularity=E,new A(v))};var N=new t;return A.createGeometry=function(n){var r=n._positions,i=e(r,a.equalsEpsilon),o=n._shape;if(o=p.removeDuplicatesFromShape(o),!(i.length<2||o.length<3)){_.computeWindingOrder2D(o)===T.CLOCKWISE&&o.reverse();var u=t.fromPoints(o,N);return R(p.computePositions(i,o,u,n,!1),o)}},A}),define("Workers/createPolylineVolumeOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolylineVolumeOutlineGeometry"],function(e,t,n){"use strict";function r(r,a){return e(a)&&(r=n.unpack(r,a)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,E=i.y,p=i.z,m=l*l*d*d,y=f*f*E*E,_=h*h*p*p,T=m+y+_,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,g=u.z,O=o;O.x=v.x*A*2,O.y=v.y*S*2,O.z=v.z*g*2;var N,I,w,M,x,C,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),b=0;do{B-=b,w=1/(1+B*A),M=1/(1+B*S),x=1/(1+B*g),C=w*w,P=M*M,U=x*x,D=C*w,L=P*M,F=U*x,N=m*C+y*P+_*U-1,I=m*D*A+y*L*S+_*F*g;b=N/(-2*I)}while(Math.abs(N)>r.EPSILON12);return t(c)?(c.x=l*w,c.y=f*M,c.z=h*x,c):new e(l*w,f*M,h*x)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var E=r(n)?n.oneOverRadii:f,p=r(n)?n.oneOverRadiiSquared:h,m=r(n)?n._centerToleranceSquared:d,y=o(t,E,p,m,c);if(r(y)){var _=e.multiplyComponents(y,p,s);_=e.normalize(_,_);var T=e.subtract(t,y,l),R=Math.atan2(_.y,_.x),v=Math.asin(_.z),A=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=v,i.height=A,i):new u(R,v,A)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,p=new e,m=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,p);if(i(a)){var o=this.geodeticSurfaceNormal(a,E),u=e.subtract(n,a,m),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/arrayRemoveDuplicates",["./Check","./defaultValue","./defined","./Math"],function(e,t,n,r){"use strict";function i(e,r,i){if(n(e)){i=t(i,!1);var o=e.length;if(o<2)return e;var u,s,c;for(u=1;u<o&&(s=e[u-1],c=e[u],!r(s,c,a));++u);if(u===o)return i&&r(e[0],e[e.length-1],a)?e.slice(1):e;for(var l=e.slice(0,u);u<o;++u)c=e[u],r(s,c,a)||(l.push(c),s=c);return i&&l.length>1&&r(l[0],l[l.length-1],a)&&l.shift(),l}}var a=r.EPSILON10;return i}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,E),o=Math.max(o,E)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,p=e.length;E<p;E++){var m=t.cartesianToCartographic(e[E]);o=Math.min(o,m.longitude),c=Math.max(c,m.longitude),h=Math.min(h,m.latitude),d=Math.max(d,m.latitude);var y=m.longitude>=0?m.longitude:m.longitude+u.TWO_PI;l=Math.min(l,y),f=Math.max(f,y)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,p=c;p.height=i,p.longitude=E,p.latitude=f,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=f<0?f:h>0?h:0;for(var m=1;m<8;++m)p.longitude=-Math.PI+m*u.PI_OVER_TWO,s.contains(e,p)&&(o[l]=t.cartographicToCartesian(p,o[l]),l++);return 0===p.latitude&&(p.longitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingRectangle",["./Cartesian2","./Cartographic","./Check","./defaultValue","./defined","./GeographicProjection","./Intersect","./Rectangle"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,n,i){this.x=r(e,0),this.y=r(t,0),this.width=r(n,0),this.height=r(i,0)}s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.x,t[n++]=e.y,t[n++]=e.width,t[n]=e.height,t},s.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new s),n.x=e[t++],n.y=e[t++],n.width=e[t++],n.height=e[t],n},s.fromPoints=function(e,t){if(i(t)||(t=new s),!i(e)||0===e.length)return t.x=0,t.y=0,t.width=0,t.height=0,t;for(var n=e.length,r=e[0].x,a=e[0].y,o=e[0].x,u=e[0].y,c=1;c<n;c++){var l=e[c],f=l.x,h=l.y;r=Math.min(f,r),o=Math.max(f,o),a=Math.min(h,a),u=Math.max(h,u)}return t.x=r,t.y=a,t.width=o-r,t.height=u-a,t};var c=new a,l=new t,f=new t;return s.fromRectangle=function(t,n,a){if(i(a)||(a=new s),!i(t))return a.x=0,a.y=0,a.width=0,a.height=0,a;n=r(n,c);var o=n.project(u.southwest(t,l)),h=n.project(u.northeast(t,f));return e.subtract(h,o,h),a.x=o.x,a.y=o.y,a.width=h.x,a.height=h.y,a},s.clone=function(e,t){if(i(e))return i(t)?(t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t):new s(e.x,e.y,e.width,e.height)},s.union=function(e,t,n){i(n)||(n=new s);var r=Math.min(e.x,t.x),a=Math.min(e.y,t.y),o=Math.max(e.x+e.width,t.x+t.width),u=Math.max(e.y+e.height,t.y+t.height);return n.x=r,n.y=a,n.width=o-r,n.height=u-a,n},s.expand=function(e,t,n){n=s.clone(e,n);var r=t.x-n.x,i=t.y-n.y;return r>n.width?n.width=r:r<0&&(n.width-=r,n.x=t.x),i>n.height?n.height=i:i<0&&(n.height-=i,n.y=t.y),n},s.intersect=function(e,t){var n=e.x,r=e.y,i=t.x,a=t.y;return n>i+t.width||n+e.width<i||r+e.height<a||r>a+t.height?o.OUTSIDE:o.INTERSECTING},s.equals=function(e,t){return e===t||i(e)&&i(t)&&e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.intersect=function(e){return s.intersect(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(p[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(p[a],E[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=E[i],h=p[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,m=e[s.getElementIndex(h,h)],y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(h,f)],T=(m-y)/2/_;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0), +t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,p=2*(i-h),m=2*(a+l),y=2*(i+h),_=-n+u-f+d,T=2*(c-o),R=2*(a-l),v=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=E,t[1]=y,t[2]=R,t[3]=p,t[4]=_,t[5]=v,t[6]=m,t[7]=T,t[8]=A,t):new s(E,p,m,y,_,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,E=a*i+c*o*u,p=-c*i+a*o*u,m=-o,y=c*n,_=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=m,t[3]=f,t[4]=E,t[5]=y,t[6]=h,t[7]=p,t[8]=_,t):new s(l,f,h,d,E,p,m,y,_)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],p=[2,2,1],m=new s,y=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,m),s.transpose(m,y),s.multiply(h,m,h),s.multiply(y,h,h),s.multiply(o,m,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,E,p,m){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(p,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(m,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,p=t.y*t.w,m=t.z*t.z,y=t.z*t.w,_=t.w*t.w,T=s-d-m+_,R=2*(c-y),v=2*(f+p),A=2*(c+y),S=-s+d-m+_,g=2*(E-h),O=2*(f-p),N=2*(E+h),I=-s-d+m+_;return r[0]=T*a,r[1]=A*a,r[2]=O*a,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=N*o,r[7]=0,r[8]=v*u,r[9]=g*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,p=f.y,m=f.z,y=d.x,_=d.y,T=d.z,R=r.x,v=r.y,A=r.z,S=u*-R+s*-v+c*-A,g=y*-R+_*-v+T*-A,O=E*R+p*v+m*A;return i(n)?(n[0]=u,n[1]=y,n[2]=-E,n[3]=0,n[4]=s,n[5]=_,n[6]=-p,n[7]=0,n[8]=c,n[9]=T,n[10]=-m,n[11]=0,n[12]=S,n[13]=g,n[14]=O,n[15]=1,n):new l(u,s,c,S,y,_,T,g,-E,-p,-m,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,p=a+c,m=o+l,y=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=p,i[13]=m,i[14]=y,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],p=e[12],m=e[13],y=e[14],_=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],g=t[5],O=t[6],N=t[7],I=t[8],w=t[9],M=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*v+p*A,F=i*T+s*R+h*v+m*A,B=a*T+c*R+d*v+y*A,b=o*T+l*R+E*v+_*A,z=r*S+u*g+f*O+p*N,q=i*S+s*g+h*O+m*N,G=a*S+c*g+d*O+y*N,V=o*S+l*g+E*O+_*N,W=r*I+u*w+f*M+p*x,X=i*I+s*w+h*M+m*x,H=a*I+c*w+d*M+y*x,Y=o*I+l*w+E*M+_*x,k=r*C+u*P+f*U+p*D,j=i*C+s*P+h*U+m*D,Z=a*C+c*P+d*U+y*D,K=o*C+l*P+E*U+_*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],p=t[0],m=t[1],y=t[2],_=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],g=t[12],O=t[13],N=t[14],I=r*p+o*m+c*y,w=i*p+u*m+l*y,M=a*p+s*m+f*y,x=r*_+o*T+c*R,C=i*_+u*T+l*R,P=a*_+s*T+f*R,U=r*v+o*A+c*S,D=i*v+u*A+l*S,L=a*v+s*A+f*S,F=r*g+o*O+c*N+h,B=i*g+u*O+l*N+d,b=a*g+s*O+f*N+E;return n[0]=I,n[1]=w,n[2]=M,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],p=t[3],m=t[4],y=t[5],_=t[6],T=t[7],R=t[8],v=r*h+o*d+c*E,A=i*h+u*d+l*E,S=a*h+s*d+f*E,g=r*p+o*m+c*y,O=i*p+u*m+l*y,N=a*p+s*m+f*y,I=r*_+o*T+c*R,w=i*_+u*T+l*R,M=a*_+s*T+f*R;return n[0]=v,n[1]=A,n[2]=S,n[3]=0,n[4]=g,n[5]=O,n[6]=N,n[7]=0,n[8]=I,n[9]=w,n[10]=M,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var m=new e;l.multiplyByUniformScale=function(e,t,n){return m.x=t,m.y=t,m.z=t,l.multiplyByScale(e,m,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var y=new s,_=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,y),_,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],p=e[2],m=e[6],v=e[10],A=e[14],S=e[3],g=e[7],O=e[11],N=e[15],I=v*N,w=A*O,M=m*N,x=A*g,C=m*O,P=v*g,U=p*N,D=A*S,L=p*O,F=v*S,B=p*g,b=m*S,z=I*h+x*d+C*E-(w*h+M*d+P*E),q=w*f+U*d+F*E-(I*f+D*d+L*E),G=M*f+D*h+B*E-(x*f+U*h+b*E),V=P*f+L*h+b*d-(C*f+F*h+B*d),W=w*i+M*a+P*o-(I*i+x*a+C*o),X=I*r+D*a+L*o-(w*r+U*a+F*o),H=x*r+U*i+b*o-(M*r+D*i+B*o),Y=C*r+F*i+B*a-(P*r+L*i+b*a);I=a*E,w=o*d,M=i*E,x=o*h,C=i*d,P=a*h,U=r*E,D=o*f,L=r*d,F=a*f,B=r*h,b=i*f;var k=I*g+x*O+C*N-(w*g+M*O+P*N),j=w*S+U*O+F*N-(I*S+D*O+L*N),Z=M*S+D*g+B*N-(x*S+U*g+b*N),K=P*S+L*g+b*O-(C*S+F*g+B*O),J=M*v+P*A+w*m-(C*A+I*m+x*v),Q=L*A+I*p+D*v-(U*v+F*A+w*p),$=U*m+b*A+x*p-(B*A+M*p+D*m),ee=B*v+C*p+F*m-(L*m+b*v+P*p),te=r*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-i*d,p=-a*f-o*h-u*d,m=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=p,t[14]=m,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var E=new e,p=new e,m=new e,y=new e,_=new e,T=new e,R=new e,v=new e,A=new e,S=new e,g=new e,O=new e,N=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,E),u=e.clone(i,p),s=e.clone(i,m),c=e.clone(i,y),l=e.clone(i,_),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var N=i.x,I=i.y,w=i.z;N<o.x&&e.clone(i,o),N>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),w<s.z&&e.clone(i,s),w>f.z&&e.clone(i,f)}var M=e.magnitudeSquared(e.subtract(c,o,v)),x=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(f,s,v)),P=o,U=c,D=M;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,v)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,v),.5,O),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,v));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,L,v));if(W>F){var X=Math.sqrt(W);B=.5*(B+X),F=B*B;var H=X-B;L.x=(B*L.x+H*i.x)/X,L.y=(B*L.y+H*i.y)/X,L.z=(B*L.z+H*i.z)/X}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var I=new u,w=new e,M=new e,x=new t,C=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,I),h.southwest(t,x),x.height=r,h.northeast(t,C),C.height=o;var s=n.project(x,w),c=n.project(C,M),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var p=u.center;return p.x=s.x+.5*l,p.y=s.y+.5*f,p.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,p),f=e.clone(u,m),h=e.clone(u,y),N=e.clone(u,_),I=e.clone(u,T),w=t.length;for(s=0;s<w;s+=r){var M=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=M,u.y=x,u.z=C,M<c.x&&e.clone(u,c),M>h.x&&e.clone(u,h),x<l.y&&e.clone(u,l),x>N.y&&e.clone(u,N),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(h,c,v)),U=e.magnitudeSquared(e.subtract(N,l,v)),D=e.magnitudeSquared(e.subtract(I,f,v)),L=c,F=h,B=P;U>B&&(B=U,L=l,F=N),D>B&&(B=D,L=f,F=I);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,v)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=N.y,V.z=I.z;var W=e.multiplyByScalar(e.add(G,V,v),.5,O),X=0;for(s=0;s<w;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,v));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,b,v));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;b.x=(q*b.x+j*u.x)/k,b.y=(q*b.y+j*u.y)/k,b.z=(q*b.z+j*u.z)/k}}return q<X?(e.clone(b,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,E),s=e.clone(i,p),c=e.clone(i,m),l=e.clone(i,y),f=e.clone(i,_),h=e.clone(i,T),N=t.length;for(o=0;o<N;o+=3){var I=t[o]+n[o],w=t[o+1]+n[o+1],M=t[o+2]+n[o+2];i.x=I,i.y=w,i.z=M,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),w<s.y&&e.clone(i,s),w>f.y&&e.clone(i,f),M<c.z&&e.clone(i,c),M>h.z&&e.clone(i,h)}var x=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(f,s,v)),P=e.magnitudeSquared(e.subtract(h,c,v)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,v)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,v),.5,O),V=0;for(o=0;o<N;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,v));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,F,v));if(X>B){var H=Math.sqrt(X);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<V?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++], +r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var B=new e,b=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,B),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,W=new e,X=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,p=E[0];e.add(s,l,p),e.add(p,c,p),p=E[1],e.add(s,l,p),e.add(p,h,p),p=E[2],e.add(s,f,p),e.add(p,h,p),p=E[3],e.add(s,f,p),e.add(p,c,p),e.negate(s,s),p=E[4],e.add(s,l,p),e.add(p,c,p),p=E[5],e.add(s,l,p),e.add(p,h,p),p=E[6],e.add(s,f,p),e.add(p,h,p),p=E[7],e.add(s,f,p),e.add(p,c,p);for(var m=E.length,y=0;y<m;++y){var _=E[y];e.add(o,_,_);var T=a.cartesianToCartographic(_,k);n.project(T,_)}r=d.fromPoints(E,r),o=r.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return N*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(v)&&(v=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,g=r(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0,N=r(e[1]),N.isNightly=!!e[2])}return O}function c(){return s()&&N}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,w=r(e[1]))}return I}function f(){return l()&&w}function h(){if(!t(M)){M=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(M=!0,x=r(e[1]))}return M}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function p(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function m(){return E()&&P}function y(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function _(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return _()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,g,O,N,I,w,M,x,C,P,U,D,L,F,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:m,isWindows:p,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:y,supportsImageRenderingPixelated:_,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/CornerType",["./freezeObject"],function(e){"use strict";return e({ROUNDED:0,MITERED:1,BEVELED:2})}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,E,p,m;if(a&&(u=s(e,n,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var y=i;y<o;y+=i)E=e[y],p=e[y+1],E<l&&(l=E),p<f&&(f=p),E>h&&(h=E),p>d&&(d=p);m=Math.max(h-l,d-f)}return r(u,c,i,l,f,m),c}function t(e,t,n,r,i){var a,o;if(i===w(e,t,n,r)>0)for(a=t;a<n;a+=r)o=O(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=O(a,e[a],e[a+1],o);return o&&T(o,o.next)&&(N(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==_(r.prev,r,r.next))r=r.next;else{if(N(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,p,m=e;e.prev!==e.next;)if(E=e.prev,p=e.next,f?a(e,c,l,f):i(e))t.push(E.i/s),t.push(e.i/s),t.push(p.i/s),N(e),e=p.next,m=p.next;else if((e=p)===m){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(_(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(m(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&_(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(_(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&m(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&_(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!T(i,a)&&R(i,r,r.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),N(r),N(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&y(s,c)){var l=g(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,i,a,o,u),void r(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,f=o<u-1?r[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(p(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=g(t,e);n(r,r.next)}}function f(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=l&&m(a<f?i:o,a,l,f,a<f?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var i=e;do{null===i.z&&(i.z=E(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function p(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function m(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function y(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function _(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||_(e,t,n)>0!=_(e,t,r)>0&&_(n,r,e)>0!=_(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return _(e.prev,e,e.next)<0?_(e,t,e.next)>=0&&_(e,e.prev,t)>=0:_(e,t,e.prev)<0||_(e,e.next,t)<0}function S(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function g(e,t){var n=new I(e.i,e.x,e.y),r=new I(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function O(e,t,n,r){var i=new I(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function N(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function w(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(w(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(w(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,p={} +;p.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},p.computeWindingOrder2D=function(e){return p.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},p.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var m=new n,y=new n,_=new n,T=new n,R=new n,v=new n,A=new n;return p.computeSubdivision=function(e,t,r,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,p=new Array(3*E),S=0;for(h=0;h<E;h++){var g=t[h];p[S++]=g.x,p[S++]=g.y,p[S++]=g.z}for(var O=[],N={},I=e.maximumRadius,w=l.chordLength(u,I),M=w*w;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(p,3*D,m),F=n.fromArray(p,3*U,y),B=n.fromArray(p,3*P,_),b=n.multiplyByScalar(n.normalize(L,T),I,T),z=n.multiplyByScalar(n.normalize(F,R),I,R),q=n.multiplyByScalar(n.normalize(B,v),I,v),G=n.magnitudeSquared(n.subtract(b,z,A)),V=n.magnitudeSquared(n.subtract(z,q,A)),W=n.magnitudeSquared(n.subtract(q,b,A)),X=Math.max(G,V,W);X>M?G===X?(x=Math.min(D,U)+" "+Math.max(D,U),h=N[x],o(h)||(C=n.add(L,F,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),h=p.length/3-1,N[x]=h),d.push(D,h,P),d.push(h,U,P)):V===X?(x=Math.min(U,P)+" "+Math.max(U,P),h=N[x],o(h)||(C=n.add(F,B,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),h=p.length/3-1,N[x]=h),d.push(U,h,D),d.push(h,P,D)):W===X&&(x=Math.min(P,D)+" "+Math.max(P,D),h=N[x],o(h)||(C=n.add(B,L,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),h=p.length/3-1,N[x]=h),d.push(P,h,U),d.push(h,D,U)):(O.push(D),O.push(U),O.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:p})},indices:O,primitiveType:f.TRIANGLES})},p.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=d,c=E;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},p}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,p=d.y,m=d.z;i=Math.min(E,i),s=Math.max(E,s),o=Math.min(p,o),c=Math.max(p,c),u=Math.min(m,u),l=Math.max(m,l)}var y=n.minimum;y.x=i,y.y=o,y.z=u;var _=n.maximum;_.x=s,_.y=c,_.z=l;var T=e.add(y,_,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,p=o*c-u*s,m=u*c-d,y=4*E*m-p*p;if(y<0){var _,T,R;h*f>=l*d?(_=o,T=E,R=-2*u*E+o*p):(_=c,T=m,R=-c*p+2*s*m);var v=R<0?-1:1,A=-v*Math.abs(_)*Math.sqrt(-y);a=-R+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),O=a===A?-g:-T/g;return i=T<=0?g+O:-R/(g*g+O*O+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var N=E,I=-2*u*E+o*p,w=m,M=-c*p+2*s*m,x=Math.sqrt(y),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-I)/3);i=2*Math.sqrt(-N);var U=Math.cos(P);a=i*U;var D=i*(-U/2-C*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*x,-M)/3),i=2*Math.sqrt(-w),U=Math.cos(P),a=i*U,D=i*(-U/2-C*Math.sin(P));var b=-c,z=a+D<2*s?a+s:D+s,q=b/z,G=F*z,V=-L*z-F*b,W=L*b,X=(s*V-u*W)/(-u*V+s*G);return B<=X?B<=q?X<=q?[B,X,q]:[B,q,X]:[q,B,X]:B<=q?[X,B,q]:X<=q?[X,q,B]:[q,X,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var p,m=E[0],y=E[1];if(m>=0&&y>=0){var _=Math.sqrt(m),T=Math.sqrt(y);return[h-T,h-_,h+_,h+T]}if(m>=0&&y<0)return p=Math.sqrt(m),[h-p,h+p];if(m<0&&y>=0)return p=Math.sqrt(y),[h-p,h+p]}return[]}if(d>0){var R=Math.sqrt(d),v=(s+d-c/R)/2,A=(s+d+c/R)/2,S=r.computeRealRoots(1,R,v),g=r.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,p,m=d[0],y=i-m,_=y*y,T=t/2,R=y/2,v=_-4*o,A=_+4*Math.abs(o),S=c-4*m,g=c+4*Math.abs(m);if(m<0||v*g<S*A){var O=Math.sqrt(S);E=O/2,p=0===O?0:(t*R-a)/O}else{var N=Math.sqrt(v);E=0===N?0:(t*R-a)/N,p=N/2}var I,w;0===T&&0===E?(I=0,w=0):n.sign(T)===n.sign(E)?(I=T+E,w=m/I):(w=T-E,I=m/w);var M,x;0===R&&0===p?(M=0,x=0):n.sign(R)===n.sign(p)?(M=R+p,x=o/M):(x=R-p,M=o/x);var C=r.computeRealRoots(1,I,M),P=r.computeRealRoots(1,w,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,_),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,p=f(h,d,E,A);if(r(p))return i.start=p.root0,i.stop=p.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,i,a){var l,f=i*i,h=a*a,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,p=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),m=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,y=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),_=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===_&&0===y){if(l=s.computeRealRoots(E,p,m),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-v)),T.push(new e(i,a*R,a*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(i,a*A,a*-S)),T.push(new e(i,a*A,a*S))}return T}var g=_*_,O=y*y,N=E*E,I=_*y,w=N+O,M=2*(p*E+I),x=2*m*E+p*p-O+g,C=2*(m*p-I),P=m*m-g;if(0===w&&0===M&&0===x&&0===C)return T;l=c.computeRealRoots(w,M,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(m)?d(E*B+m,p*F,o.EPSILON12):o.sign(m)===o.sign(p*F)?d(E*B,p*F+m,o.EPSILON12):d(E*B+p*F,m,o.EPSILON12);var q=d(y*F,_,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var p={};p.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var m=new e,y=new e,_=new e,T=new e,R=new e;p.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,p=e.subtract(i,r,m),v=e.subtract(a,r,y),A=e.cross(E,v,_),S=e.dot(p,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,p,R),(f=e.dot(E,c))<0||l+f>S)return;h=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,r,T),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,p,R),(f=e.dot(E,c)*g)<0||l+f>1)return;h=e.dot(v,c)*g}return h},p.rayTriangle=function(t,n,i,a,o,u){var s=p.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;p.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=p.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};p.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;p.lineSegmentSphere=function(t,n,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,O=new e;p.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,O),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var p=s/i,m=r/s;return p<m?new a(p,m):{start:m,stop:p}}var y=Math.sqrt(r/i);return new a(y,y)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var N=new e,I=new e,w=new e,M=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;p.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,N);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,N),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,M),d=e.normalize(e.cross(h,f,I),I),p=e.normalize(e.cross(f,d,w),w),m=C;m[0]=f.x,m[1]=f.y,m[2]=f.z,m[3]=d.x,m[4]=d.y,m[5]=d.z,m[6]=p.x,m[7]=p.y,m[8]=p.z;var y=u.transpose(m,P),_=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var v,A,S=u.multiply(u.multiply(y,T,F),R,F),g=u.multiply(u.multiply(S,_,B),m,B),O=u.multiplyByVector(S,i,x),G=E(g,e.negate(O,N),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(_,u.multiplyByVector(m,G[H],b),b);var Y=e.normalize(e.subtract(v,i,M),M),k=e.dot(Y,a);k>X&&(X=k,W=e.clone(v,W))}var j=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),A=e.magnitude(e.subtract(W,i,M))*Math.sqrt(1-X*X),A=c?-A:A,j.height=A,n.cartographicToCartesian(j,new e)}};var G=new e;return p.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},p.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return p.lineSegmentPlane(t,n,i,f),p.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return p.lineSegmentPlane(n,r,i,f),p.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return p.lineSegmentPlane(r,t,i,f),p.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return p.lineSegmentPlane(n,t,i,f),p.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return p.lineSegmentPlane(r,n,i,f),p.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return p.lineSegmentPlane(t,r,i,f),p.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},p}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function i(e){return E(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return p(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=y,p(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return m(2,arguments),e(t,function(t){function u(e){p(e)}function s(e){E(e)}var c,l,f,h,d,E,p,m,_,T;if(_=t.length>>>0,c=Math.max(0,Math.min(n,_)),f=[],l=_-c+1,h=[],d=o(),c)for(m=d.progress,p=function(e){h.push(e),--l||(E=p=y,d.reject(h))},E=function(e){f.push(e),--c||(E=p=y,d.resolve(f))},T=0;T<_;++T)T in t&&e(t[T],s,u,m);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return m(1,arguments),h(e,_).then(t,n,r)}function f(){return h(arguments,_)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function E(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function p(e,t){for(var n,r=0;n=e[r++];)n(t)}function m(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function y(){}function _(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,E,p,m,y;if("%%"==e)return"%";for(var _=!1,T="",R=!1,v=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":_=!0;break;case"'":A=s.charAt(g+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,_=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,y=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(y),_,c,f,R,A);case"c":return u(String.fromCharCode(+y),_,c,f,R);case"b":return o(y,2,v,_,c,f,R);case"o":return o(y,8,v,_,c,f,R);case"x":return o(y,16,v,_,c,f,R);case"X":return o(y,16,v,_,c,f,R).toUpperCase();case"u":return o(y,10,v,_,c,f,R);case"i":case"d":return d=+y||0,d=Math.round(d-d%1),E=d<0?"-":T,y=E+i(String(Math.abs(d)),f,"0",!1),a(y,E,_,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+y,E=d<0?"-":T,p=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],m=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],y=E+Math.abs(d)[p](f),a(y,E,_,c,R)[m]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return p.compare(e.julianDate,t.julianDate)}function f(e){_.julianDate=e;var n=p.leapSeconds,r=t(n,_,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){p.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}p.addSeconds(e,i,e)}function h(e,n){_.julianDate=e;var r=p.leapSeconds,i=t(r,_,l);if(i<0&&(i=~i),0===i)return p.addSeconds(e,-r[0].offset,n);if(i>=r.length)return p.addSeconds(e,-r[i-1].offset,n);var a=p.secondsDifference(r[i].julianDate,e);return 0===a?p.addSeconds(e,-r[i].offset,n):a<=1?void 0:p.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function p(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var m=new a,y=[31,28,31,30,31,30,31,31,30,31,30,31],_=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+g.source,N=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;p.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new p(n[0],n[1],c.UTC)},p.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new p(n[0],n[1],c.UTC)},p.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,m=0,_=0,g=0,w=u[0],M=u[1];if(null!==(u=w.match(S)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=w.match(R)))n=+u[1],s=+u[2];else if(null!==(u=w.match(T)))n=+u[1];else{var x;if(null!==(u=w.match(v)))n=+u[1],x=+u[2],a=o(n);else if(null!==(u=w.match(A))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(x),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(M)){u=M.match(I),null!==u?(h=+u[1],m=+u[2],_=+u[3],g=1e3*+(u[4]||0),D=5):(u=M.match(N),null!==u?(h=+u[1],m=+u[2],_=60*+(u[3]||0),D=4):null!==(u=M.match(O))&&(h=+u[1],m=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,m-=B;break;case"-":h+=F,m+=B;break;case"Z":break;default:m+=new Date(Date.UTC(n,s-1,l,h,m)).getTimezoneOffset()}}var b=60===_;for(b&&_--;m>=60;)m-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:y[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:y[s-1];for(;m<0;)m+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:y[s-1],l+=i;var z=E(n,s,l,h,m,_,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new p(z[0],z[1],c.UTC),b&&p.addSeconds(t,1,t),t},p.now=function(e){return p.fromDate(new Date,e)};var w=new p(0,0,c.TAI);return p.toGregorianDate=function(e,t){var n=!1,i=h(e,w);r(i)||(p.addSeconds(e,-1,w),i=h(w,w),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var m=d+2-12*c|0,y=100*(l-49)+f+c|0,_=u/s.SECONDS_PER_HOUR|0,T=u-_*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return _+=12,_>23&&(_-=24),n&&(v+=1),r(t)?(t.year=y,t.month=m,t.day=E,t.hour=_,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=n,t):new a(y,m,E,_,R,v,A,n)},p.toDate=function(e){var t=p.toGregorianDate(e,m),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},p.toIso8601=function(t,n){var i,a=p.toGregorianDate(t,m);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},p.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new p(e.dayNumber,e.secondsOfDay,c.TAI)},p.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},p.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},p.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(p.secondsDifference(e,t))<=n},p.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},p.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},p.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},p.computeTaiMinusUtc=function(e){_.julianDate=e;var n=p.leapSeconds,r=t(n,_,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},p.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},p.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},p.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},p.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},p.lessThan=function(e,t){return p.compare(e,t)<0},p.lessThanOrEquals=function(e,t){return p.compare(e,t)<=0},p.greaterThan=function(e,t){return p.compare(e,t)>0},p.greaterThanOrEquals=function(e,t){return p.compare(e,t)>=0},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p.prototype.equalsEpsilon=function(e,t){return p.equalsEpsilon(this,e,t)},p.prototype.toString=function(){return p.toIso8601(this)},p.leapSeconds=[new u(new p(2441317,43210,c.TAI),10),new u(new p(2441499,43211,c.TAI),11),new u(new p(2441683,43212,c.TAI),12),new u(new p(2442048,43213,c.TAI),13),new u(new p(2442413,43214,c.TAI),14),new u(new p(2442778,43215,c.TAI),15),new u(new p(2443144,43216,c.TAI),16),new u(new p(2443509,43217,c.TAI),17),new u(new p(2443874,43218,c.TAI),18),new u(new p(2444239,43219,c.TAI),19),new u(new p(2444786,43220,c.TAI),20),new u(new p(2445151,43221,c.TAI),21),new u(new p(2445516,43222,c.TAI),22),new u(new p(2446247,43223,c.TAI),23),new u(new p(2447161,43224,c.TAI),24),new u(new p(2447892,43225,c.TAI),25),new u(new p(2448257,43226,c.TAI),26),new u(new p(2448804,43227,c.TAI),27),new u(new p(2449169,43228,c.TAI),28),new u(new p(2449534,43229,c.TAI),29),new u(new p(2450083,43230,c.TAI),30),new u(new p(2450630,43231,c.TAI),31),new u(new p(2451179,43232,c.TAI),32),new u(new p(2453736,43233,c.TAI),33),new u(new p(2454832,43234,c.TAI),34),new u(new p(2456109,43235,c.TAI),35),new u(new p(2457204,43236,c.TAI),36),new u(new p(2457754,43237,c.TAI),37)],p}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){ +var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return O[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function p(e){return function(t){e.state!==c.CANCELLED&&(--v.numberOfActiveRequests,--O[e.serverKey],I.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==c.CANCELLED&&(++v.numberOfFailedRequests,--v.numberOfActiveRequests,--O[e.serverKey],I.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function y(e){var t=E(e);return e.state=c.ACTIVE,g.push(e),++v.numberOfActiveRequests,++v.numberOfActiveRequestsEver,++O[e.serverKey],e.requestFunction().then(p(e)).otherwise(m(e)),t}function _(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++v.numberOfCancelledRequests,e.deferred.reject(),t&&(--v.numberOfActiveRequests,--O[e.serverKey],++v.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){v.numberOfAttemptedRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(v.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+v.numberOfAttemptedRequests),v.numberOfActiveRequests>0&&console.log("Number of active requests: "+v.numberOfActiveRequests),v.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+v.numberOfCancelledRequests),v.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+v.numberOfCancelledActiveRequests),v.numberOfFailedRequests>0&&console.log("Number of failed requests: "+v.numberOfFailedRequests),T())}var v={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var g=[],O={},N="undefined"!=typeof document?new e(document.location.href):new e,I=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=I,i(f,{statistics:{get:function(){return v}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&_(t),t.state===c.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||d(t.serverKey)?(y(t),++u):_(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(N);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=O[i];return r(a)||(O[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return I.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++v.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return y(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(r(t)){if(t===e)return;_(t)}return E(e)}},f.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=g.length,t=0;t<e;++t)_(g[t]);g.length=0,O={},v.numberOfAttemptedRequests=0,v.numberOfActiveRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0,v.numberOfFailedRequests=0,v.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return O[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,p,m,y,_,T,R,v,A,S,g,O){"use strict";function N(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=y(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function I(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=m(n):e.query=r[0]}function w(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function M(e){if(e.state===v.ISSUED||e.state===v.ACTIVE)throw new A("The Resource is already being fetched.");e.state=v.UNISSUED,e.deferred=void 0}function x(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=w(e.templateValues,{}),this._queryParameters=w(e.queryParameters,{}),this.headers=w(e.headers,{}),this.request=i(e.request,new _),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function C(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=O.defer();return x._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==v.FAILED?O.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,C(e,t)):O.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=O.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},x._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==v.FAILED?O.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=v.UNISSUED,i.deferred=void 0,P(e,t,n)):O.reject(r)})})}function U(e,t){M(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=O.defer(),f=x._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==v.FAILED?O.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,e.fetch(t)):O.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var B=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();x.createIfNeeded=function(e,t){if(e instanceof x)return e.clone();if("string"!=typeof e)return e;var n=w(t,{});return n.url=e,new x(n)},o(x,{isBlobSupported:{get:function(){return B}}}),o(x.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);N(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return p(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),x.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new g(this._url);e&&I(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},x.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},x.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},x.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new g(e.url);N(n,t),n.fragment=void 0,t._url=n.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},x.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return O(!1);var n=this;return O(t(this,e)).then(function(e){return++n._retryCount,e})},x.prototype.clone=function(e){return a(e)||(e=new x({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},x.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},x.prototype.appendForwardSlash=function(){this._url=e(this._url)},x.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},x.fetchArrayBuffer=function(e){return new x(e).fetchArrayBuffer()},x.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},x.fetchBlob=function(e){return new x(e).fetchBlob()},x.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),M(this.request),!B||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return C(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new x({url:t}),C(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),O.reject(e)})}},x.fetchImage=function(e){return new x(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},x.prototype.fetchText=function(){return this.fetch({responseType:"text"})},x.fetchText=function(e){return new x(e).fetchText()},x.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},x.fetchJson=function(e){return new x(e).fetchJson()},x.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},x.fetchXML=function(e){return new x(e).fetchXML()},x.prototype.fetchJsonp=function(e){e=i(e,"callback"),M(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},x.fetchJsonp=function(e){return new x(e).fetchJsonp(e.callbackParameterName)},x.prototype.fetch=function(e){return e=w(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var b=/^data:(.*?)(;base64)?,(.*)$/;return x.fetch=function(e){return new x(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x.prototype.post=function(e,n){return t.defined("data",e),n=w(n,{}),n.method="POST",n.data=e,U(this,n)},x.post=function(e){return new x(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},x._Implementations={},x._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(S.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},x._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=b.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},x._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},x._DefaultImplementations={},x._DefaultImplementations.createImage=x._Implementations.createImage,x._DefaultImplementations.loadWithXhr=x._Implementations.loadWithXhr,x._DefaultImplementations.loadAndExecuteScript=x._Implementations.loadAndExecuteScript,x.DEFAULT=c(new x({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),x}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),p=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||E<0||p<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var m=e._samples=n.samples,y=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=p,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var _,T=e._addNewLeapSeconds,R=0,v=m.length;R<v;R+=e._columnCount){var A=m[R+i],S=m[R+p],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(g,S,f.TAI);if(y.push(O),T){if(S!==_&&r(_)){var N=o.leapSeconds,I=t(N,O,d);if(I<0){var w=new u(O,S);N.splice(~I,0,w)}}_=S}}}function p(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function m(e,t,n){return t+e*(n-t)}function y(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return p(e,n,i,s,u),u;if(r.equals(l))return p(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,E=n[h+e._ut1MinusUtcSecondsColumn],y=n[d+e._ut1MinusUtcSecondsColumn],_=y-E;if(_>.5||_<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=y:y-=R-T)}return u.xPoleWander=m(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=m(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=m(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=m(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=m(f,E,y),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),p=E||o.greaterThanOrEquals(h,e);if(d&&p)return s=u,!E&&h.equals(e)&&++s,l=s+1,y(this,a,this._samples,e,s,l,n),n}var m=t(a,e,o.compare,this._dateColumn);return m>=0?(m<a.length-1&&a[m+1].equals(e)&&++m,s=m,l=m):(l=~m,(s=l-1)<0&&(s=0)),this._lastIndex=s,y(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0), +r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var E,p,m=a-s*this._stepSizeDays,y=this._work,_=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)y[E]=m-R[E];for(E=0;E<=u;++E){for(T[E]=1,p=0;p<=u;++p)p!==E&&(T[E]*=y[p]);T[E]*=_[E];var v=3*(s+E);n.x+=T[E]*d[v++],n.y+=T[E]*d[v++],n.s+=T[E]*d[v]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],p=h+d+E;if(p>0)n=Math.sqrt(p+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var m=l,y=0;d>h&&(y=1),E>h&&E>d&&(y=2);var _=m[y],T=m[_];n=Math.sqrt(e[u.getElementIndex(y,y)]-e[u.getElementIndex(_,_)]-e[u.getElementIndex(T,T)]+1);var R=f;R[y]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,_)]-e[u.getElementIndex(_,T)])*n,R[_]=(e[u.getElementIndex(_,y)]+e[u.getElementIndex(y,_)])*n,R[T]=(e[u.getElementIndex(T,y)]+e[u.getElementIndex(y,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,E=new s,p=new s;s.fromHeadingPitchRoll=function(t,n){return p=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,p,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var m=new e,y=new e,_=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),_),s.multiply(_,R,_),_.w<0&&s.negate(_,_),s.computeAxis(_,m);var u=s.computeAngle(_);r[o]=m.x*u,r[o+1]=m.y*u,r[o+2]=m.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,y);var u=e.magnitude(y);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,_):s.fromAxisAngle(y,u,_),s.multiply(_,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,E=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),g=s.multiplyByScalar(a,Math.sin(n*u),g),r=s.add(S,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,N=new e,I=new s,w=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,I);s.multiply(a,r,w);var o=s.log(w,O);s.multiply(a,t,w);var u=s.log(w,N);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,I),u=s.slerp(n,r,i,w);return s.slerp(o,u,2*i*(1-i),a)};for(var M=new s,x=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;C[L]=1/(F*B),P[L]=F/B}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,M);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,I),u=s.fastSlerp(n,r,i,w);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,p,m,y,_,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,N=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=v[e][t],a=e+t;return u(S[a])?r=S[a]:(r=function(r,a,s){if(u(s)||(s=new y),p.equalsEpsilon(r.x,0,p.EPSILON14)&&p.equalsEpsilon(r.y,0,p.EPSILON14)){var c=p.sign(r.z);n.unpack(A[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(A[t],0,N),"east"!==t&&"west"!==t&&n.multiplyByScalar(N,c,N),n.unpack(A[i],0,I),"east"!==i&&"west"!==i&&n.multiplyByScalar(I,c,I)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),O=g[e],N=g[t],I=g[i]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=N.x,s[5]=N.y,s[6]=N.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},S[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var w=new _,M=new n(1,1,1),x=new y;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=_.fromHeadingPitchRoll(t,w),s=y.fromTranslationQuaternionRotationScale(n.ZERO,u,M,x);return a=i(e,r,a),y.multiply(a,s,a)};var C=new y,P=new m;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=y.getRotation(a,P);return _.fromRotationMatrix(o,i)};var U=p.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%p.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new m(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new m);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return m.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new m,b=new m;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new m);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=m.fromRotationZ(-a.s,b),h=m.multiply(l,f,B),d=e.dayNumber,y=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,_=d-2451545,v=y/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(_+v);A=A%1*p.TWO_PI;var S=m.fromRotationZ(A,b),g=m.multiply(h,S,B),O=Math.cos(n.xPoleWander),N=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),w=Math.sin(n.yPoleWander),M=r-2451545+i/T.SECONDS_PER_DAY;M/=36525;var x=-47e-6*M*p.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=b;return U[0]=O*C,U[1]=O*P,U[2]=I,U[3]=-N*P+w*I*C,U[4]=N*C+w*I*P,U[5]=-w*O,U[6]=-w*P-N*I*C,U[7]=w*C-N*I*P,U[8]=N*O,m.multiply(g,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return y.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),y.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,p.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new m),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new y(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new n,Y=new n,k=new m,j=new y,Z=new y;return R.basisTo2D=function(e,t,r){var i=y.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=y.inverseTransformation(s,Z),l=y.getRotation(t,k),f=y.multiplyByMatrix3(c,l,r);return y.multiply(W,f,r),y.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=y.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=y.fromTranslation(s,j);return y.multiply(W,o,r),y.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,p)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,p));var a=n.fromCartesian4(l.getColumn(r,2,p));this._plane=f.fromPointNormal(e,a)}var p=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var m=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,m).center,n)};var y=new h,_=new n;E.prototype.projectPointOntoPlane=function(e,r){var i=y;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,_);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=y;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,_);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,_));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,i=(n-r)/n,a=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-i)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,a),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),p=t/4,m=p*p,y=m*p,_=m*m,T=1+p-3*m/4+5*y/4-175*_/64,R=1-p+15*m/8-35*y/8,v=1-3*p+35*m/4,A=1-5*p,S=T*l-R*Math.sin(2*l)*p/2-v*Math.sin(4*l)*m/16-A*Math.sin(6*l)*y/48-5*Math.sin(8*l)*_/512,g=e._constants;g.a=n,g.b=r,g.f=i,g.cosineHeading=a,g.sineHeading=o,g.tanU=u,g.cosineU=s,g.sineU=c,g.sigma=l,g.sineAlpha=f,g.sineSquaredAlpha=h,g.cosineSquaredAlpha=d,g.cosineAlpha=E,g.u2Over4=p,g.u4Over16=m,g.u6Over64=y,g.u8Over256=_,g.a0=T,g.a1=R,g.a2=v,g.a3=A,g.distanceRatio=S}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,i,a,o){var u=c(e,n);return(1-u)*e*t*(r+u*i*(o+u*a*(2*o*o-1)))}function f(e,t,n,r,i,a,o){var s,c,f,h,d,E=(t-n)/t,p=a-r,m=Math.atan((1-E)*Math.tan(i)),y=Math.atan((1-E)*Math.tan(o)),_=Math.cos(m),T=Math.sin(m),R=Math.cos(y),v=Math.sin(y),A=_*R,S=_*v,g=T*v,O=T*R,N=p,I=u.TWO_PI,w=Math.cos(N),M=Math.sin(N);do{w=Math.cos(N),M=Math.sin(N);var x=S-O*w;f=Math.sqrt(R*R*M*M+x*x),c=g+A*w,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=A*M/f,h=1-C*C),I=N,d=c-2*g/h,isNaN(d)&&(d=0),N=p+l(E,C,h,s,f,c,d)}while(Math.abs(N-I)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),B=n*U*(s-F),b=Math.atan2(R*M,S-O*w),z=Math.atan2(_*M,S*w-O);e._distance=B,e._startHeading=b,e._endHeading=z,e._uSquared=P}function h(n,r,i,a){e.normalize(a.cartographicToCartesian(r,p),E),e.normalize(a.cartographicToCartesian(i,p),p);f(n,a.maximumRadius,a.minimumRadius,r.longitude,r.latitude,i.longitude,i.latitude),n._start=t.clone(r,n._start),n._end=t.clone(i,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,a){var u=r(a,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,i(e)&&i(n)&&h(this,e,n,u)}var E=new e,p=new e;return a(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,a=r.distanceRatio+e/r.b,o=Math.cos(2*a),u=Math.cos(4*a),s=Math.cos(6*a),c=Math.sin(2*a),f=Math.sin(4*a),h=Math.sin(6*a),d=Math.sin(8*a),E=a*a,p=a*E,m=r.u8Over256,y=r.u2Over4,_=r.u6Over64,T=r.u4Over16,R=2*p*m*o/3+a*(1-y+7*T/4-15*_/4+579*m/64-(T-15*_/4+187*m/16)*o-(5*_/4-115*m/16)*u-29*m*s/16)+(y/2-T+71*_/32-85*m/16)*c+(5*T/16-5*_/4+383*m/96)*f-E*((_-11*m/2)*c+5*m*f/2)+(29*_/96-29*m/16)*h+539*m*d/1536,v=Math.asin(Math.sin(R)*r.cosineAlpha),A=Math.atan(r.a/r.b*Math.tan(v));R-=r.sigma;var S=Math.cos(2*r.sigma+R),g=Math.sin(R),O=Math.cos(R),N=r.cosineU*O,I=r.sineU*g,w=Math.atan2(g*r.sineHeading,N-I*r.cosineHeading),M=w-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,g,O,S);return i(n)?(n.longitude=this._start.longitude+M,n.latitude=A,n.height=0,n):new t(this._start.longitude+M,A,0)},d}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=g;r.length=e;var i;if(t===n){for(i=0;i<e;i++)r[i]=t;return r}var a=n-t,o=a/e;for(i=0;i<e;i++){var u=t+i*o;r[i]=u}return r}function d(t,n,r,i,a,o,u,s){var c=i.scaleToGeodeticSurface(t,w),l=i.scaleToGeodeticSurface(n,M),f=E.numberOfPoints(t,n,r),d=i.cartesianToCartographic(c,O),p=i.cartesianToCartographic(l,N),m=h(f,a,o);x.setEndPoints(d,p);var y=x.surfaceDistance/f,_=s;d.height=a;var T=i.cartographicToCartesian(d,I);e.pack(T,u,_),_+=3;for(var R=1;R<f;R++){var v=x.interpolateUsingSurfaceDistance(R*y,N);v.height=m[R],T=i.cartographicToCartesian(v,I),e.pack(T,u,_),_+=3}return _}var E={};E.numberOfPoints=function(t,n,r){var i=e.distance(t,n);return Math.ceil(i/r)};var p=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),i=0;i<n;i++){var a=e[i];r[i]=t.cartesianToCartographic(a,p).height}return r};var m=new l,y=new e,_=new e,T=new f(e.UNIT_X,0),R=new e,v=new f(e.UNIT_X,0),A=new e,S=new e,g=[],O=new t,N=new t,I=new e,w=new e,M=new e,x=new o;return E.wrapLongitude=function(t,i){var a=[],o=[];if(r(t)&&t.length>0){i=n(i,l.IDENTITY);var s=l.inverseTransformation(i,m),c=l.multiplyByPoint(s,e.ZERO,y),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,_),_),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),p=f.fromPointNormal(c,E,v),g=1;a.push(e.clone(t[0]));for(var O=a[0],N=t.length,I=1;I<N;++I){var w=t[I];if(f.getPointDistance(p,O)<0||f.getPointDistance(p,w)<0){var M=u.lineSegmentPlane(O,w,d,A);if(r(M)){var x=e.multiplyByScalar(h,5e-9,S);f.getPointDistance(d,O)<0&&e.negate(x,x),a.push(e.add(M,x,new e)),o.push(g+1),e.negate(x,x),a.push(e.add(M,x,new e)),g=1}}a.push(e.clone(t[I])),g++,O=w}o.push(g)}return{positions:a,lengths:o}},E.generateArc=function(t){r(t)||(t={});var i=t.positions,o=i.length,u=n(t.ellipsoid,a.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(i[0],w);if(0!==(l=f?l[0]:l)){var p=u.geodeticSurfaceNormal(h,I);e.multiplyByScalar(p,l,p),e.add(h,p,h)}return[h.x,h.y,h.z]}var m=t.minDistance;if(!r(m)){var y=n(t.granularity,c.RADIANS_PER_DEGREE);m=c.chordLength(y,u.maximumRadius)}var _,T=0;for(_=0;_<o-1;_++)T+=E.numberOfPoints(i[_],i[_+1],m);var R=3*(T+1),v=new Array(R),A=0;for(_=0;_<o-1;_++){A=d(i[_],i[_+1],m,u,f?l[_]:l,f?l[_+1]:l,v,A)}g.length=0;var S=i[o-1],N=u.cartesianToCartographic(S,O);N.height=f?l[o-1]:l;var M=u.cartographicToCartesian(N,I);return e.pack(M,v,R-3),v},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,i=new Array(r),a=0;a<r;a++)i[a]=e.unpack(n,3*a);return i},E}),define("Core/PolylineVolumeGeometryLibrary",["./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./CornerType","./EllipsoidTangentPlane","./Math","./Matrix3","./Matrix4","./PolylinePipeline","./Quaternion","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++){var i=e[r];U=t.cartesianToCartographic(i,U),n[r]=U.height,e[r]=t.scaleToGeodeticSurface(i,i)}return n}function d(e,n,r,i){var a,o=e[0],u=e[1],s=t.angleBetween(o,u),c=Math.ceil(s/i),l=new Array(c);if(n===r){for(a=0;a<c;a++)l[a]=n;return l.push(r),l}var f=r-n,h=f/c;for(a=1;a<c;a++){var d=n+a*h;l[a]=d}return l[0]=n,l.push(r),l}function E(n,r,i,o){var u=new a(i,o),s=u.projectPointOntoPlane(t.add(i,n,D),D),c=u.projectPointOntoPlane(t.add(i,r,L),L),l=e.angleBetween(s,c);return c.x*s.y-c.y*s.x>=0?-l:l}function p(e,n,r,i,a,o,c,l){var h=G,d=V;B=f.eastNorthUpToFixedFrame(e,a,B),h=s.multiplyByPointAsVector(B,F,h),h=t.normalize(h,h);var p=E(h,n,e,a);z=u.fromRotationZ(p,z),W.z=o,B=s.multiplyTransformation(B,s.fromRotationTranslation(z,W,b),B);var m=q;m[0]=c;for(var y=0;y<l;y++)for(var _=0;_<r.length;_+=3)d=t.fromArray(r,_,d),d=u.multiplyByVector(m,d,d),d=s.multiplyByPoint(B,d,d),i.push(d.x,d.y,d.z);return i}function m(e,n,r,i,a,o,u){for(var s=0;s<e.length;s+=3){i=p(t.fromArray(e,s,X),n,r,i,a,o[s/3],u,1)}return i}function y(e,t){var n=e.length,r=new Array(6*n),i=0,a=t.x+t.width/2,o=t.y+t.height/2,u=e[0];r[i++]=u.x-a,r[i++]=0,r[i++]=u.y-o;for(var s=1;s<n;s++){u=e[s];var c=u.x-a,l=u.y-o;r[i++]=c,r[i++]=0,r[i++]=l,r[i++]=c,r[i++]=0,r[i++]=l}return u=e[0],r[i++]=u.x-a,r[i++]=0,r[i++]=u.y-o,r}function _(e,t){for(var n=e.length,r=new Array(3*n),i=0,a=t.x+t.width/2,o=t.y+t.height/2,u=0;u<n;u++)r[i++]=e[u].x-a,r[i++]=0,r[i++]=e[u].y-o;return r}function T(e,n,r,a,s,c,f,h,d,E){var m,y=t.angleBetween(t.subtract(n,e,x),t.subtract(r,e,C)),_=a===i.BEVELED?0:Math.ceil(y/o.toRadians(5));m=s?u.fromQuaternion(l.fromAxisAngle(t.negate(e,x),y/(_+1),H),k):u.fromQuaternion(l.fromAxisAngle(e,y/(_+1),H),k);var T,R;if(n=t.clone(n,Y),_>0)for(var v=E?2:1,A=0;A<_;A++)n=u.multiplyByVector(m,n,n),T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=p(R,T,h,f,c,d,1,v);else T=t.subtract(n,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(n,C),f=p(R,T,h,f,c,d,1,1),r=t.clone(r,Y),T=t.subtract(r,e,x),T=t.normalize(T,T),s||(T=t.negate(T,T)),R=c.scaleToGeodeticSurface(r,C),f=p(R,T,h,f,c,d,1,1);return f}var R=[new t,new t],v=new t,A=new t,S=new t,g=new t,O=new t,N=new t,I=new t,w=new t,M=new t,x=new t,C=new t,P={},U=new r,D=new t,L=new t,F=new t(-1,0,0),B=new s,b=new s,z=new u,q=u.IDENTITY.clone(),G=new t,V=new n,W=new t,X=new t,H=new l,Y=new t,k=new u;P.removeDuplicatesFromShape=function(t){for(var n=t.length,r=[],i=n-1,a=0;a<n;i=a++){var o=t[i],u=t[a];e.equals(o,u)||r.push(u)}return r},P.angleIsGreaterThanPi=function(e,n,r,i){var o=new a(r,i),u=o.projectPointOntoPlane(t.add(r,e,D),D),s=o.projectPointOntoPlane(t.add(r,n,L),L);return s.x*u.y-s.y*u.x>=0};var j=new t,Z=new t;return P.computePositions=function(e,n,r,a,u){var s=a._ellipsoid,l=h(e,s),f=a._granularity,E=a._cornerType,C=u?y(n,r):_(n,r),U=u?_(n,r):void 0,D=r.height/2,L=r.width/2,F=e.length,B=[],b=u?[]:void 0,z=v,q=A,G=S,V=g,W=O,X=N,H=I,Y=w,k=M,K=e[0],J=e[1];V=s.geodeticSurfaceNormal(K,V),z=t.subtract(J,K,z),z=t.normalize(z,z),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y);var Q=l[0],$=l[1];u&&(b=p(K,Y,U,b,s,Q+D,1,1)),k=t.clone(K,k),K=J,q=t.negate(z,q);for(var ee,te,ne=1;ne<F-1;ne++){var re=u?2:1;J=e[ne+1],z=t.subtract(J,K,z),z=t.normalize(z,z),G=t.add(z,q,G),G=t.normalize(G,G),V=s.geodeticSurfaceNormal(K,V);var ie=t.multiplyByScalar(V,t.dot(z,V),j);t.subtract(z,ie,ie),t.normalize(ie,ie);var ae=t.multiplyByScalar(V,t.dot(q,V),Z);t.subtract(q,ae,ae),t.normalize(ae,ae);if(!o.equalsEpsilon(Math.abs(t.dot(ie,ae)),1,o.EPSILON7)){G=t.cross(G,V,G),G=t.cross(V,G,G),G=t.normalize(G,G);var oe=1/Math.max(.25,t.magnitude(t.cross(G,q,x))),ue=P.angleIsGreaterThanPi(z,q,K,s);ue?(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=m(te,Y,C,B,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,L,H),H),E===i.ROUNDED||E===i.BEVELED?T(W,X,H,E,ue,s,B,C,$+D,u):(G=t.negate(G,G),B=p(K,G,C,B,s,$+D,oe,re)),k=t.clone(H,k)):(W=t.add(K,t.multiplyByScalar(G,oe*L,G),W),X=t.add(W,t.multiplyByScalar(Y,-L,X),X),R[0]=t.clone(k,R[0]),R[1]=t.clone(X,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=m(te,Y,C,B,s,ee,1),Y=t.cross(V,z,Y),Y=t.normalize(Y,Y),H=t.add(W,t.multiplyByScalar(Y,-L,H),H),E===i.ROUNDED||E===i.BEVELED?T(W,X,H,E,ue,s,B,C,$+D,u):B=p(K,G,C,B,s,$+D,oe,re),k=t.clone(H,k)),q=t.negate(z,q)}else B=p(k,Y,C,B,s,Q+D,1,1),k=K;Q=$,$=l[ne+1],K=J}R[0]=t.clone(k,R[0]),R[1]=t.clone(K,R[1]),ee=d(R,Q+D,$+D,f),te=c.generateArc({positions:R,granularity:f,ellipsoid:s}),B=m(te,Y,C,B,s,ee,1),u&&(b=p(K,Y,U,b,s,$+D,1,1)),F=B.length;var se=u?F+b.length:F,ce=new Float64Array(se);return ce.set(B),u&&ce.set(b,F),ce},P}),define("Core/PolylineVolumeOutlineGeometry",["./arrayRemoveDuplicates","./BoundingRectangle","./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./CornerType","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PolylineVolumeGeometryLibrary","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,p,m,y,_,T){"use strict";function R(e,t){var r=new d;r.position=new h({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:e});var i,o,u=t.length,s=r.position.values.length/3,c=e.length/3,l=c/u,p=E.createTypedArray(s,2*u*(l+1)),m=0;i=0;var y=i*u;for(o=0;o<u-1;o++)p[m++]=o+y,p[m++]=o+y+1;for(p[m++]=u-1+y,p[m++]=y,i=l-1,y=i*u,o=0;o<u-1;o++)p[m++]=o+y,p[m++]=o+y+1;for(p[m++]=u-1+y,p[m++]=y,i=0;i<l-1;i++){var T=u*i,R=T+u;for(o=0;o<u;o++)p[m++]=o+T,p[m++]=o+R}return new f({attributes:r,indices:E.createTypedArray(s,p),boundingSphere:n.fromVertices(e),primitiveType:_.LINES})}function v(e){e=u(e,u.EMPTY_OBJECT);var t=e.polylinePositions,n=e.shapePositions;this._positions=t,this._shape=n,this._ellipsoid=l.clone(u(e.ellipsoid,l.WGS84)),this._cornerType=u(e.cornerType,o.ROUNDED),this._granularity=u(e.granularity,p.RADIANS_PER_DEGREE),this._workerName="createPolylineVolumeOutlineGeometry";var a=1+t.length*i.packedLength;a+=1+n.length*r.packedLength,this.packedLength=a+l.packedLength+2}v.pack=function(e,t,n){n=u(n,0);var a,o=e._positions,s=o.length;for(t[n++]=s,a=0;a<s;++a,n+=i.packedLength)i.pack(o[a],t,n);var c=e._shape;for(s=c.length,t[n++]=s,a=0;a<s;++a,n+=r.packedLength)r.pack(c[a],t,n);return l.pack(e._ellipsoid,t,n),n+=l.packedLength,t[n++]=e._cornerType,t[n]=e._granularity,t};var A=l.clone(l.UNIT_SPHERE),S={polylinePositions:void 0,shapePositions:void 0,ellipsoid:A,height:void 0,cornerType:void 0,granularity:void 0};v.unpack=function(e,t,n){t=u(t,0);var a,o=e[t++],c=new Array(o);for(a=0;a<o;++a,t+=i.packedLength)c[a]=i.unpack(e,t);o=e[t++];var f=new Array(o);for(a=0;a<o;++a,t+=r.packedLength)f[a]=r.unpack(e,t);var h=l.unpack(e,t,A);t+=l.packedLength;var d=e[t++],E=e[t];return s(n)?(n._positions=c,n._shape=f,n._ellipsoid=l.clone(h,n._ellipsoid),n._cornerType=d,n._granularity=E,n):(S.polylinePositions=c,S.shapePositions=f,S.cornerType=d,S.granularity=E,new v(S))};var g=new t;return v.createGeometry=function(n){var r=n._positions,a=e(r,i.equalsEpsilon),o=n._shape;if(o=y.removeDuplicatesFromShape(o),!(a.length<2||o.length<3)){m.computeWindingOrder2D(o)===T.CLOCKWISE&&o.reverse();var u=t.fromPoints(o,g);return R(y.computePositions(a,o,u,n,!1),o)}},v}),define("Workers/createPolylineVolumeOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/PolylineVolumeOutlineGeometry"],function(e,t,n){"use strict";function r(r,i){return e(i)&&(r=n.unpack(r,i)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleGeometry.js index 74ea3a57..afea7eb0 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleGeometry.js @@ -55,8 +55,9 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var E=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,E=r*u-a*o;return n.x=c,n.y=l,n.z=E,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var f=new o,h=new o,d=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:d,c=Math.cos(r);f.x=c*Math.cos(e),f.y=c*Math.sin(e),f.z=Math.sin(r),f=o.normalize(f,f),o.multiplyComponents(s,f,h);var l=Math.sqrt(o.dot(f,h));return h=o.divideByScalar(h,l,h),f=o.multiplyByScalar(f,a,f),n(u)||(u=new o),o.add(h,f,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,E=n.y,f=n.z,h=a.x,d=a.y,p=a.z,y=l*l*h*h,_=E*E*d*d,m=f*f*p*p,T=y+_+m,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,N=u.z,g=o;g.x=v.x*A*2,g.y=v.y*S*2,g.z=v.z*N*2;var I,M,O,x,w,C,P,L,b,U,F,D=(1-R)*e.magnitude(n)/(.5*e.magnitude(g)),B=0;do{D-=B,O=1/(1+D*A),x=1/(1+D*S),w=1/(1+D*N),C=O*O,P=x*x,L=w*w,b=C*O,U=P*x,F=L*w,I=y*C+_*P+m*L-1,M=y*b*A+_*U*S+m*F*N;B=I/(-2*M)}while(Math.abs(I)>r.EPSILON12);return t(c)?(c.x=l*O,c.y=E*x,c.z=f*w,c):new e(l*O,E*x,f*w)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,E=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,n,a){var d=r(n)?n.oneOverRadii:E,p=r(n)?n.oneOverRadiiSquared:f,y=r(n)?n._centerToleranceSquared:h,_=o(t,d,p,y,c);if(r(_)){var m=e.multiplyComponents(_,p,s);m=e.normalize(m,m);var T=e.subtract(t,_,l),R=Math.atan2(m.y,m.x),v=Math.asin(m.z),A=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=v,a.height=A,a):new u(R,v,A)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function E(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(E.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),E.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new E(r.x,r.y,r.z)}},E.fromCartesian3=function(e,t){return a(t)||(t=new E),a(e)?(l(t,e.x,e.y,e.z),t):t},E.WGS84=u(new E(6378137,6378137,6356752.314245179)),E.UNIT_SPHERE=u(new E(1,1,1)),E.MOON=u(new E(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),E.prototype.clone=function(e){return E.clone(this,e)},E.packedLength=e.packedLength,E.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},E.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return E.fromCartesian3(i,a)},E.prototype.geocentricSurfaceNormal=e.normalize,E.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},E.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var f=new e,h=new e;E.prototype.cartographicToCartesian=function(t,n){var r=f,i=h;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},E.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var d=new e,p=new e,y=new e;return E.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,p);if(a(i)){var o=this.geodeticSurfaceNormal(i,d),u=e.subtract(n,i,y),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),E=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=E,r):new t(c,l,E)}},E.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},E.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},E.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},E.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},E.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},E.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},E.prototype.toString=function(){return this._radii.toString()},E.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},E}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,E=0,f=e.length;E<f;E++){var h=e[E];n=Math.min(n,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,d),o=Math.max(o,d)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,E=-Number.MAX_VALUE,f=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0,p=e.length;d<p;d++){var y=t.cartesianToCartographic(e[d]);o=Math.min(o,y.longitude),c=Math.max(c,y.longitude),f=Math.min(f,y.latitude),h=Math.max(h,y.latitude);var _=y.longitude>=0?y.longitude:y.longitude+u.TWO_PI;l=Math.min(l,_),E=Math.max(E,_)}return c-o>E-l&&(o=l,c=E,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=f,a.east=c,a.north=h,a):new s(o,f,c,h)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),E=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&E<=l)){var f=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(f>=h))return r(n)?(n.west=l,n.south=f,n.east=E,n.north=h,n):new s(l,f,E,h)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),E=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=E,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,E=e.north,f=e.south,h=e.east,d=e.west,p=c;p.height=a,p.longitude=d,p.latitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=f,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=E<0?E:f>0?f:0;for(var y=1;y<8;++y)p.longitude=-Math.PI+y*u.PI_OVER_TWO,s.contains(e,p)&&(o[l]=t.cartographicToCartesian(p,o[l]),l++);return 0===p.latitude&&(p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(p[n],d[n])];t+=2*r*r}return Math.sqrt(t)}function E(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(p[i],d[i])]);o>r&&(a=i,r=o)}var c=1,l=0,E=d[a],f=p[a];if(Math.abs(e[s.getElementIndex(f,E)])>n){var h,y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(E,E)],m=e[s.getElementIndex(f,E)],T=(y-_)/2/m;h=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(E,E)]=t[s.getElementIndex(f,f)]=c,t[s.getElementIndex(f,E)]=l,t[s.getElementIndex(E,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,E=e.z*e.z,f=e.z*e.w,h=e.w*e.w,d=n-u-E+h,p=2*(a-f),y=2*(i+l),_=2*(a+f),m=-n+u-E+h,T=2*(c-o),R=2*(i-l),v=2*(c+o),A=-n-u+E+h;return r(t)?(t[0]=d,t[1]=_,t[2]=R,t[3]=p,t[4]=m,t[5]=v,t[6]=y,t[7]=T,t[8]=A,t):new s(d,p,y,_,m,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,E=-i*u+c*o*a,f=c*u+i*o*a,h=n*u,d=i*a+c*o*u,p=-c*a+i*o*u,y=-o,_=c*n,m=i*n;return r(t)?(t[0]=l,t[1]=h,t[2]=y,t[3]=E,t[4]=d,t[5]=_,t[6]=f,t[7]=p,t[8]=m,t):new s(l,E,f,h,d,p,y,_,m)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var f=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),n};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],E=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=E,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var d=[1,0,0],p=[2,2,1],y=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),h=n*c(f);i<10&&l(f)>h;)E(f,y),s.transpose(y,_),s.multiply(f,y,f),s.multiply(_,f,f),s.multiply(o,y,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){ -var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],E=e[8],f=s.determinant(e);t[0]=o*E-l*u,t[1]=l*a-r*E,t[2]=r*u-o*a,t[3]=c*u-i*E,t[4]=n*E-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var h=1/f;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,E,f,h,d,p,y){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(h,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(d,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(E,0),this[11]=r(p,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(f,0),this[15]=r(y,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,E=t.x*t.z,f=t.x*t.w,h=t.y*t.y,d=t.y*t.z,p=t.y*t.w,y=t.z*t.z,_=t.z*t.w,m=t.w*t.w,T=s-h-y+m,R=2*(c-_),v=2*(E+p),A=2*(c+_),S=-s+h-y+m,N=2*(d-f),g=2*(E-p),I=2*(d+f),M=-s-h+y+m;return r[0]=T*i,r[1]=A*i,r[2]=g*i,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=I*o,r[7]=0,r[8]=v*u,r[9]=N*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var E=new e,f=new e,h=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,E),e.normalize(e.cross(E,o,f),f),e.normalize(e.cross(f,E,h),h);var u=f.x,s=f.y,c=f.z,d=E.x,p=E.y,y=E.z,_=h.x,m=h.y,T=h.z,R=r.x,v=r.y,A=r.z,S=u*-R+s*-v+c*-A,N=_*-R+m*-v+T*-A,g=d*R+p*v+y*A;return a(n)?(n[0]=u,n[1]=_,n[2]=-d,n[3]=0,n[4]=s,n[5]=m,n[6]=-p,n[7]=0,n[8]=c,n[9]=T,n[10]=-y,n[11]=0,n[12]=S,n[13]=N,n[14]=g,n[15]=1,n):new l(u,s,c,S,_,m,T,N,-d,-p,-y,g,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,E=-(r+n)*s,f=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=E,o[14]=f,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),E=-(i+a)/(i-a),f=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=E,o[11]=-1,o[12]=0,o[13]=0,o[14]=f,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,E=.5*(n-t),f=c,h=l,d=E,p=i+c,y=o+l,_=t+E;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=d,a[11]=0,a[12]=p,a[13]=y,a[14]=_,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var d=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],d)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],d)),n};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],E=e[8],f=e[9],h=e[10],d=e[11],p=e[12],y=e[13],_=e[14],m=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],N=t[5],g=t[6],I=t[7],M=t[8],O=t[9],x=t[10],w=t[11],C=t[12],P=t[13],L=t[14],b=t[15],U=r*T+u*R+E*v+p*A,F=a*T+s*R+f*v+y*A,D=i*T+c*R+h*v+_*A,B=o*T+l*R+d*v+m*A,z=r*S+u*N+E*g+p*I,G=a*S+s*N+f*g+y*I,q=i*S+c*N+h*g+_*I,V=o*S+l*N+d*g+m*I,X=r*M+u*O+E*x+p*w,W=a*M+s*O+f*x+y*w,H=i*M+c*O+h*x+_*w,Y=o*M+l*O+d*x+m*w,k=r*C+u*P+E*L+p*b,Z=a*C+s*P+f*L+y*b,K=i*C+c*P+h*L+_*b,j=o*C+l*P+d*L+m*b;return n[0]=U,n[1]=F,n[2]=D,n[3]=B,n[4]=z,n[5]=G,n[6]=q,n[7]=V,n[8]=X,n[9]=W,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=K,n[15]=j,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=e[12],h=e[13],d=e[14],p=t[0],y=t[1],_=t[2],m=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],N=t[12],g=t[13],I=t[14],M=r*p+o*y+c*_,O=a*p+u*y+l*_,x=i*p+s*y+E*_,w=r*m+o*T+c*R,C=a*m+u*T+l*R,P=i*m+s*T+E*R,L=r*v+o*A+c*S,b=a*v+u*A+l*S,U=i*v+s*A+E*S,F=r*N+o*g+c*I+f,D=a*N+u*g+l*I+h,B=i*N+s*g+E*I+d;return n[0]=M,n[1]=O,n[2]=x,n[3]=0,n[4]=w,n[5]=C,n[6]=P,n[7]=0,n[8]=L,n[9]=b,n[10]=U,n[11]=0,n[12]=F,n[13]=D,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=t[0],h=t[1],d=t[2],p=t[3],y=t[4],_=t[5],m=t[6],T=t[7],R=t[8],v=r*f+o*h+c*d,A=a*f+u*h+l*d,S=i*f+s*h+E*d,N=r*p+o*y+c*_,g=a*p+u*y+l*_,I=i*p+s*y+E*_,M=r*m+o*T+c*R,O=a*m+u*T+l*R,x=i*m+s*T+E*R;return n[0]=v,n[1]=A,n[2]=S,n[3]=0,n[4]=N,n[5]=g,n[6]=I,n[7]=0,n[8]=M,n[9]=O,n[10]=x,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var y=new e;l.multiplyByUniformScale=function(e,t,n){return y.x=t,y.y=t,y.z=t,l.multiplyByScale(e,y,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,m=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),m,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],E=e[1],f=e[5],h=e[9],d=e[13],p=e[2],y=e[6],v=e[10],A=e[14],S=e[3],N=e[7],g=e[11],I=e[15],M=v*I,O=A*g,x=y*I,w=A*N,C=y*g,P=v*N,L=p*I,b=A*S,U=p*g,F=v*S,D=p*N,B=y*S,z=M*f+w*h+C*d-(O*f+x*h+P*d),G=O*E+L*h+F*d-(M*E+b*h+U*d),q=x*E+b*f+D*d-(w*E+L*f+B*d),V=P*E+U*f+B*h-(C*E+F*f+D*h),X=O*a+x*i+P*o-(M*a+w*i+C*o),W=M*r+b*i+U*o-(O*r+L*i+F*o),H=w*r+L*a+B*o-(x*r+b*a+D*o),Y=C*r+F*a+D*i-(P*r+U*a+B*i);M=i*d,O=o*h,x=a*d,w=o*f,C=a*h,P=i*f,L=r*d,b=o*E,U=r*h,F=i*E,D=r*f,B=a*E;var k=M*N+w*g+C*I-(O*N+x*g+P*I),Z=O*S+L*g+F*I-(M*S+b*g+U*I),K=x*S+b*N+D*I-(w*S+L*N+B*I),j=P*S+U*N+B*g-(C*S+F*N+D*g),Q=x*v+P*A+O*y-(C*A+M*y+w*v),J=U*A+M*p+b*v-(L*v+F*A+O*p),$=L*y+B*A+w*p-(D*A+x*p+b*y),ee=D*v+C*p+F*y-(U*y+B*v+P*p),te=r*z+a*G+i*q+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=G*te,n[2]=q*te,n[3]=V*te,n[4]=X*te,n[5]=W*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=K*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],E=e[12],f=e[13],h=e[14],d=-n*E-r*f-a*h,p=-i*E-o*f-u*h,y=-s*E-c*f-l*h;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=d,t[13]=p,t[14]=y,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,E){"use strict";function f(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var h=new e,d=new e,p=new e,y=new e,_=new e,m=new e,T=new e,R=new e,v=new e,A=new e,S=new e,N=new e;f.fromPoints=function(t,n){if(a(n)||(n=new f),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,h),u=e.clone(i,d),s=e.clone(i,p),c=e.clone(i,y),l=e.clone(i,_),E=e.clone(i,m),g=t.length;for(r=1;r<g;r++){e.clone(t[r],i);var I=i.x,M=i.y,O=i.z;I<o.x&&e.clone(i,o),I>c.x&&e.clone(i,c),M<u.y&&e.clone(i,u),M>l.y&&e.clone(i,l),O<s.z&&e.clone(i,s),O>E.z&&e.clone(i,E)}var x=e.magnitudeSquared(e.subtract(c,o,R)),w=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(E,s,R)),P=o,L=c,b=x;w>b&&(b=w,P=u,L=l),C>b&&(b=C,P=s,L=E);var U=v;U.x=.5*(P.x+L.x),U.y=.5*(P.y+L.y),U.z=.5*(P.z+L.z);var F=e.magnitudeSquared(e.subtract(L,U,R)),D=Math.sqrt(F),B=A;B.x=o.x,B.y=u.y,B.z=s.z;var z=S;z.x=c.x,z.y=l.y,z.z=E.z;var G=e.multiplyByScalar(e.add(B,z,R),.5,N),q=0;for(r=0;r<g;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,G,R));V>q&&(q=V);var X=e.magnitudeSquared(e.subtract(i,U,R));if(X>F){var W=Math.sqrt(X);D=.5*(D+W),F=D*D;var H=W-D;U.x=(D*U.x+H*i.x)/W,U.y=(D*U.y+H*i.y)/W,U.z=(D*U.z+H*i.z)/W}}return D<q?(e.clone(U,n.center),n.radius=D):(e.clone(G,n.center),n.radius=q),n};var g=new o,I=new e,M=new e,O=new t,x=new t;f.fromRectangle2D=function(e,t,n){return f.fromRectangleWithHeights2D(e,t,0,0,n)},f.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,g),E.southwest(t,O),O.height=i,E.northeast(t,x),x.height=o;var s=n.project(O,I),c=n.project(x,M),l=c.x-s.x,h=c.y-s.y,d=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+d*d);var p=u.center;return p.x=s.x+.5*l,p.y=s.y+.5*h,p.z=s.z+.5*d,u};var w=[];f.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=E.subsample(t,n,o,w);return f.fromPoints(s,u)},f.fromVertices=function(t,n,i,o){if(a(o)||(o=new f),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,h),l=e.clone(u,d),E=e.clone(u,p),g=e.clone(u,y),I=e.clone(u,_),M=e.clone(u,m),O=t.length;for(s=0;s<O;s+=i){var x=t[s]+n.x,w=t[s+1]+n.y,C=t[s+2]+n.z;u.x=x,u.y=w,u.z=C,x<c.x&&e.clone(u,c),x>g.x&&e.clone(u,g),w<l.y&&e.clone(u,l),w>I.y&&e.clone(u,I),C<E.z&&e.clone(u,E),C>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(g,c,R)),L=e.magnitudeSquared(e.subtract(I,l,R)),b=e.magnitudeSquared(e.subtract(M,E,R)),U=c,F=g,D=P;L>D&&(D=L,U=l,F=I),b>D&&(D=b,U=E,F=M);var B=v;B.x=.5*(U.x+F.x),B.y=.5*(U.y+F.y),B.z=.5*(U.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,R)),G=Math.sqrt(z),q=A;q.x=c.x,q.y=l.y,q.z=E.z;var V=S;V.x=g.x,V.y=I.y,V.z=M.z;var X=e.multiplyByScalar(e.add(q,V,R),.5,N),W=0;for(s=0;s<O;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,R));H>W&&(W=H);var Y=e.magnitudeSquared(e.subtract(u,B,R));if(Y>z){var k=Math.sqrt(Y);G=.5*(G+k),z=G*G;var Z=k-G;B.x=(G*B.x+Z*u.x)/k,B.y=(G*B.y+Z*u.y)/k,B.z=(G*B.z+Z*u.z)/k}}return G<W?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=W),o},f.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new f),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,h),s=e.clone(i,d),c=e.clone(i,p),l=e.clone(i,y),E=e.clone(i,_),g=e.clone(i,m),I=t.length;for(o=0;o<I;o+=3){var M=t[o]+n[o],O=t[o+1]+n[o+1],x=t[o+2]+n[o+2];i.x=M,i.y=O,i.z=x,M<u.x&&e.clone(i,u),M>l.x&&e.clone(i,l),O<s.y&&e.clone(i,s),O>E.y&&e.clone(i,E),x<c.z&&e.clone(i,c),x>g.z&&e.clone(i,g)}var w=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(E,s,R)),P=e.magnitudeSquared(e.subtract(g,c,R)),L=u,b=l,U=w;C>U&&(U=C,L=s,b=E),P>U&&(U=P,L=c,b=g);var F=v;F.x=.5*(L.x+b.x),F.y=.5*(L.y+b.y),F.z=.5*(L.z+b.z);var D=e.magnitudeSquared(e.subtract(b,F,R)),B=Math.sqrt(D),z=A;z.x=u.x,z.y=s.y,z.z=c.z;var G=S;G.x=l.x,G.y=E.y,G.z=g.z;var q=e.multiplyByScalar(e.add(z,G,R),.5,N),V=0;for(o=0;o<I;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,q,R));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(i,F,R));if(W>D){var H=Math.sqrt(W);B=.5*(B+H),D=B*B;var Y=H-B;F.x=(B*F.x+Y*i.x)/H,F.y=(B*F.y+Y*i.y)/H,F.z=(B*F.z+Y*i.z)/H}}return B<V?(e.clone(F,r.center),r.radius=B):(e.clone(q,r.center),r.radius=V),r},f.fromCornerPoints=function(t,n,r){a(r)||(r=new f);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},f.fromEllipsoid=function(t,n){return a(n)||(n=new f),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;f.fromBoundingSpheres=function(t,n){if(a(n)||(n=new f),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return f.clone(t[0],n);if(2===r)return f.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=f.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,L=new e,b=new e;f.fromOrientedBoundingBox=function(t,n){a(n)||(n=new f);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,L),u=c.getColumn(r,2,b);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},f.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new f(t.center,t.radius)},f.packedLength=4,f.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},f.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new f);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var U=new e,F=new e;f.union=function(t,n,r){a(r)||(r=new f);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,U),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var E=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+E)/l,F);return e.add(h,i,h),e.clone(h,r.center),r.radius=E,r};var D=new e;f.expand=function(t,n,r){r=f.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,D));return a>r.radius&&(r.radius=a),r},f.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},f.transform=function(e,t,n){return a(n)||(n=new f),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var B=new e;f.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,B);return e.magnitudeSquared(r)-t.radius*t.radius},f.transformWithoutScale=function(e,t,n){return a(n)||(n=new f),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;f.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var G=new e,q=new e,V=new e,X=new e,W=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return f.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,G),c=e.cross(e.UNIT_Z,s,q);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var E=e.negate(l,W),h=e.negate(c,X),d=Y,p=d[0];e.add(s,l,p),e.add(p,c,p),p=d[1],e.add(s,l,p),e.add(p,h,p),p=d[2],e.add(s,E,p),e.add(p,h,p),p=d[3],e.add(s,E,p),e.add(p,c,p),e.negate(s,s),p=d[4],e.add(s,l,p),e.add(p,c,p),p=d[5],e.add(s,l,p),e.add(p,h,p),p=d[6],e.add(s,E,p),e.add(p,h,p),p=d[7],e.add(s,E,p),e.add(p,c,p);for(var y=d.length,_=0;_<y;++_){var m=d[_];e.add(o,m,m);var T=i.cartesianToCartographic(m,H);n.project(T,m)}a=f.fromPoints(d,a),o=a.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,a},f.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},f.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},f.prototype.intersectPlane=function(e){return f.intersectPlane(this,e)},f.prototype.distanceSquaredTo=function(e){return f.distanceSquaredTo(this,e)},f.prototype.computePlaneDistances=function(e,t,n){return f.computePlaneDistances(this,e,t,n)},f.prototype.isOccluded=function(e){return f.isOccluded(this,e)},f.prototype.equals=function(e){return f.equals(this,e)},f.prototype.clone=function(e){return f.clone(this,e)},f}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var E=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){ -return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(v)&&(v=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function i(){return a()&&A}function o(){if(!t(S)&&(S=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=r(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(g)){g=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(g=!0,I=r(e[1]),I.isNightly=!!e[2])}return g}function c(){return s()&&I}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,O=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,O=r(e[1]))}return M}function E(){return l()&&O}function f(){if(!t(x)){x=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,w=r(e[1]))}return x}function h(){return f()&&w}function d(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function p(){return t(L)||(L=/Windows/i.test(R.appVersion)),L}function y(){return d()&&P}function _(){return t(b)||(b="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),b}function m(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(U=n)}return F}function T(){return m()?U:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,N,g,I,M,O,x,w,C,P,L,b,U,F,D={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:E,isEdge:f,edgeVersion:h,isFirefox:d,firefoxVersion:y,isWindows:p,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:m,imageRenderingValue:T};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=r.clone(e(t.modelMatrix,r.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return a}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,a){"use strict";var i={};i.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,n){return i.octDecodeInRange(e,t,255,n)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return i.octDecode(r,a,t)},i.octPack=function(e,t,n,r){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(n,o);return r.x=65536*s.x+a,r.y=65536*s.y+u,r},i.octUnpack=function(e,t,n,r){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,n),i.octDecode(o,s,r)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},i}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,n,r){"use strict";function a(n,a,s,c,l){r(l)||(l=new t);var E,f,h,d,p,y,_,m;r(a.z)?(E=t.subtract(s,a,i),f=t.subtract(c,a,o),h=t.subtract(n,a,u),d=t.dot(E,E),p=t.dot(E,f),y=t.dot(E,h),_=t.dot(f,f),m=t.dot(f,h)):(E=e.subtract(s,a,i),f=e.subtract(c,a,o),h=e.subtract(n,a,u),d=e.dot(E,E),p=e.dot(E,f),y=e.dot(E,h),_=e.dot(f,f),m=e.dot(f,h));var T=1/(d*_-p*p);return l.y=(_*y-p*m)*T,l.z=(d*m-p*y)*T,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,n){"use strict";function r(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}r.encode=function(e,t){n(t)||(t={high:0,low:0});var r;return e>=0?(r=65536*Math.floor(e/65536),t.high=r,t.low=e-r):(r=65536*Math.floor(-e/65536),t.high=-r,t.low=e+r),t};var a={high:0,low:0};r.fromCartesian=function(e,t){n(t)||(t=new r);var i=t.high,o=t.low;return r.encode(e.x,a),i.x=a.high,o.x=a.low,r.encode(e.y,a),i.y=a.high,o.y=a.low,r.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new r;return r.writeElements=function(e,t,n){r.fromCartesian(e,i);var a=i.high,o=i.low;t[n]=a.x,t[n+1]=a.y,t[n+2]=a.z,t[n+3]=o.x,t[n+4]=o.y,t[n+5]=o.z},r}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,E=n(c,-l,t.EPSILON14);if(E<0)return[];var f=-.5*n(r,t.sign(r)*Math.sqrt(E),t.EPSILON14);return r>0?[f/e,a/f]:[a/f,f/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,E=u*c,f=u*u,h=s*s,d=o*s-f,p=o*c-u*s,y=u*c-h,_=4*d*y-p*p;if(_<0){var m,T,R;f*E>=l*h?(m=o,T=d,R=-2*u*d+o*p):(m=c,T=y,R=-c*p+2*s*y);var v=R<0?-1:1,A=-v*Math.abs(m)*Math.sqrt(-_);i=-R+A;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),g=i===A?-N:-T/N;return a=T<=0?N+g:-R/(N*N+g*g+T),f*E>=l*h?[(a-u)/o]:[-c/(a+s)]}var I=d,M=-2*u*d+o*p,O=y,x=-c*p+2*s*y,w=Math.sqrt(_),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*w,-M)/3);a=2*Math.sqrt(-I);var L=Math.cos(P);i=a*L;var b=a*(-L/2-C*Math.sin(P)),U=i+b>2*u?i-u:b-u,F=o,D=U/F;P=Math.abs(Math.atan2(c*w,-x)/3),a=2*Math.sqrt(-O),L=Math.cos(P),i=a*L,b=a*(-L/2-C*Math.sin(P));var B=-c,z=i+b<2*s?i+s:b+s,G=B/z,q=F*z,V=-U*z-F*B,X=U*B,W=(s*V-u*X)/(-u*V+s*q);return D<=W?D<=G?W<=G?[D,W,G]:[D,G,W]:[G,D,W]:D<=G?[W,D,G]:W<=G?[W,G,D]:[G,W,D]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,E=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(E.length>0){var f=-t/4,h=E[E.length-1];if(Math.abs(h)<n.EPSILON14){var d=r.computeRealRoots(1,s,l);if(2===d.length){var p,y=d[0],_=d[1];if(y>=0&&_>=0){var m=Math.sqrt(y),T=Math.sqrt(_);return[f-T,f-m,f+m,f+T]}if(y>=0&&_<0)return p=Math.sqrt(y),[f-p,f+p];if(y<0&&_>=0)return p=Math.sqrt(_),[f-p,f+p]}return[]}if(h>0){var R=Math.sqrt(h),v=(s+h-c/R)/2,A=(s+h+c/R)/2,S=r.computeRealRoots(1,R,v),N=r.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=f,S[1]+=f,0!==N.length?(N[0]+=f,N[1]+=f,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=f,N[1]+=f,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,E=i*t+s-4*o,f=c*o-i*a*t+u,h=e.computeRealRoots(1,l,E,f);if(h.length>0){var d,p,y=h[0],_=a-y,m=_*_,T=t/2,R=_/2,v=m-4*o,A=m+4*Math.abs(o),S=c-4*y,N=c+4*Math.abs(y);if(y<0||v*N<S*A){var g=Math.sqrt(S);d=g/2,p=0===g?0:(t*R-i)/g}else{var I=Math.sqrt(v);d=0===I?0:(t*R-i)/I,p=I/2}var M,O;0===T&&0===d?(M=0,O=0):n.sign(T)===n.sign(d)?(M=T+d,O=y/M):(O=T-d,M=y/O);var x,w;0===R&&0===p?(x=0,w=0):n.sign(R)===n.sign(p)?(x=R+p,w=o/x):(w=R-p,x=o/w);var C=r.computeRealRoots(1,M,x),P=r.computeRealRoots(1,O,w);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,E=r*r,f=E*r,h=a*a;return u*c*E-4*s*f-4*e*l*E+18*e*t*n*f-27*i*E*E+256*o*(h*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*E+144*i*n*E)+h*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,E=u/t,f=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=E<0?h+1:h,h+=f<0?h+1:h){case 0:return a(c,l,E,f);case 1:case 2:return i(c,l,E,f);case 3:case 4:return a(c,l,E,f);case 5:return i(c,l,E,f);case 6:case 7:return a(c,l,E,f);case 8:return i(c,l,E,f);case 9:case 10:return a(c,l,E,f);case 11:return i(c,l,E,f);case 12:case 13:case 14:case 15:return a(c,l,E,f);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function E(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function f(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,m),f=e.dot(u,u),h=2*e.dot(u,l),d=e.magnitudeSquared(l)-c,p=E(f,h,d,A) -;if(r(p))return a.start=p.root0,a.stop=p.root1,a}function h(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function d(t,n,r,a,i){var l,E=a*a,f=i*i,d=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,p=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),y=t[u.COLUMN0ROW0]*E+t[u.COLUMN2ROW2]*f+a*n.x+r,_=f*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),m=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===m&&0===_){if(l=s.computeRealRoots(d,p,y),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-v)),T.push(new e(a,i*R,i*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(a,i*A,i*-S)),T.push(new e(a,i*A,i*S))}return T}var N=m*m,g=_*_,I=d*d,M=m*_,O=I+g,x=2*(p*d+M),w=2*y*d+p*p-g+N,C=2*(y*p-M),P=y*y-N;if(0===O&&0===x&&0===w&&0===C)return T;l=c.computeRealRoots(O,x,w,C,P);var L=l.length;if(0===L)return T;for(var b=0;b<L;++b){var U,F=l[b],D=F*F,B=Math.max(1-D,0),z=Math.sqrt(B);U=o.sign(d)===o.sign(y)?h(d*D+y,p*F,o.EPSILON12):o.sign(y)===o.sign(p*F)?h(d*D,p*F+y,o.EPSILON12):h(d*D+p*F,y,o.EPSILON12);var G=h(_*F,m,o.EPSILON15),q=U*G;q<0?T.push(new e(a,i*F,i*z)):q>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++b):T.push(new e(a,i*F,i*z))}return T}var p={};p.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var y=new e,_=new e,m=new e,T=new e,R=new e;p.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,E,f,h=t.origin,d=t.direction,p=e.subtract(a,r,y),v=e.subtract(i,r,_),A=e.cross(d,v,m),S=e.dot(p,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,r,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,p,R),(E=e.dot(d,c))<0||l+E>S)return;f=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,r,T),(l=e.dot(s,A)*N)<0||l>1)return;if(c=e.cross(s,p,R),(E=e.dot(d,c)*N)<0||l+E>1)return;f=e.dot(v,c)*N}return f},p.rayTriangle=function(t,n,a,i,o,u){var s=p.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;p.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=p.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};p.raySphere=function(e,t,n){if(n=f(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;p.lineSegmentSphere=function(t,n,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=f(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,g=new e;p.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),E=e.multiplyComponents(c,t.direction,g),f=e.magnitudeSquared(l),h=e.dot(l,E);if(f>1){if(h>=0)return;var d=h*h;if(r=f-1,a=e.magnitudeSquared(E),o=a*r,d<o)return;if(d>o){u=h*h-o,s=-h+Math.sqrt(u);var p=s/a,y=r/s;return p<y?new i(p,y):{start:y,stop:p}}var _=Math.sqrt(r/a);return new i(_,_)}return f<1?(r=f-1,a=e.magnitudeSquared(E),o=a*r,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(E),new i(0,-h/a)):void 0};var I=new e,M=new e,O=new e,x=new e,w=new e,C=new u,P=new u,L=new u,b=new u,U=new u,F=new u,D=new u,B=new e,z=new e,G=new t;p.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,I);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,I),E=e.normalize(l,l),f=e.mostOrthogonalAxis(l,x),h=e.normalize(e.cross(f,E,M),M),p=e.normalize(e.cross(E,h,O),O),y=C;y[0]=E.x,y[1]=E.y,y[2]=E.z,y[3]=h.x,y[4]=h.y,y[5]=h.z,y[6]=p.x,y[7]=p.y,y[8]=p.z;var _=u.transpose(y,P),m=u.fromScale(n.radii,L),T=u.fromScale(n.oneOverRadii,b),R=U;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var v,A,S=u.multiply(u.multiply(_,T,F),R,F),N=u.multiply(u.multiply(S,m,D),y,D),g=u.multiplyByVector(S,a,w),q=d(N,e.negate(g,I),0,0,1),V=q.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(m,u.multiplyByVector(y,q[H],B),B);var Y=e.normalize(e.subtract(v,a,x),x),k=e.dot(Y,i);k>W&&(W=k,X=e.clone(v,X))}var Z=n.cartesianToCartographic(X,G);return W=o.clamp(W,0,1),A=e.magnitude(e.subtract(X,a,x))*Math.sqrt(1-W*W),A=c?-A:A,Z.height=A,n.cartographicToCartesian(Z,new e)}};var q=new e;return p.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,q),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),E=-(a.distance+l)/c;if(!(E<0||E>1))return e.multiplyByScalar(u,E,i),e.add(t,i,i),i}},p.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var E,f;if(1!==l&&2!==l||(E=new e,f=new e),1===l){if(u)return p.lineSegmentPlane(t,n,a,E),p.lineSegmentPlane(t,r,a,f),{positions:[t,n,r,E,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return p.lineSegmentPlane(n,r,a,E),p.lineSegmentPlane(n,t,a,f),{positions:[t,n,r,E,f],indices:[1,3,4,2,0,4,2,4,3]};if(c)return p.lineSegmentPlane(r,t,a,E),p.lineSegmentPlane(r,n,a,f),{positions:[t,n,r,E,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return p.lineSegmentPlane(n,t,a,E),p.lineSegmentPlane(r,t,a,f),{positions:[t,n,r,E,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return p.lineSegmentPlane(r,n,a,E),p.lineSegmentPlane(t,n,a,f),{positions:[t,n,r,E,f],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return p.lineSegmentPlane(t,r,a,E),p.lineSegmentPlane(n,r,a,f),{positions:[t,n,r,E,f],indices:[0,1,4,0,4,3,2,3,4]}}},p}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";var r={};return r.calculateACMR=function(n){n=e(n,e.EMPTY_OBJECT);var r=n.indices,a=n.maximumIndex,i=e(n.cacheSize,24),o=r.length;if(!t(a)){a=0;for(var u=0,s=r[u];u<o;)s>a&&(a=s),++u,s=r[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var E=i+1,f=0;f<o;++f)E-c[r[f]]>i&&(c[r[f]]=E,++E);return(E-i+1)/(o/3)},r.tipsify=function(n){function r(e,t,n,r){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<r;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}n=e(n,e.EMPTY_OBJECT);var a,i=n.indices,o=n.maximumIndex,u=e(n.cacheSize,24),s=i.length,c=0,l=0,E=i[l],f=s;if(t(o))c=o+1;else{for(;l<f;)E>c&&(c=E),++l,E=i[l];if(-1===c)return 0;++c}var h,d=[];for(h=0;h<c;h++)d[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var p=0;l<f;)d[i[l]].vertexTriangles.push(p),++d[i[l]].numLiveTriangles,d[i[l+1]].vertexTriangles.push(p),++d[i[l+1]].numLiveTriangles,d[i[l+2]].vertexTriangles.push(p),++d[i[l+2]].numLiveTriangles,++p,l+=3;var y=0,_=u+1;a=1;var m,T,R=[],v=[],A=0,S=[],N=s/3,g=[];for(h=0;h<N;h++)g[h]=!1;for(var I,M;-1!==y;){R=[],T=d[y],M=T.vertexTriangles.length;for(var O=0;O<M;++O)if(p=T.vertexTriangles[O],!g[p]){g[p]=!0,l=p+p+p;for(var x=0;x<3;++x)I=i[l],R.push(I),v.push(I),S[A]=I,++A,m=d[I],--m.numLiveTriangles,_-m.timeStamp>u&&(m.timeStamp=_,++_),++l}y=function(e,t,n,a,i,o,u){for(var s,c=-1,l=-1,E=0;E<n.length;){var f=n[E];a[f].numLiveTriangles&&(s=0,i-a[f].timeStamp+2*a[f].numLiveTriangles<=t&&(s=i-a[f].timeStamp),(s>l||-1===l)&&(l=s,c=f)),++E}return-1===c?r(a,o,e,u):c}(i,u,R,d,_,v,c)}return S},r}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,n,r,a,i,o,u,s,c,l,E,f,h,d,p,y,_,m,T,R,v,A,S,N){"use strict";function g(e,t,n,r,a){e[t++]=n,e[t++]=r,e[t++]=r,e[t++]=a,e[t++]=a,e[t]=n}function I(e){for(var t=e.length,n=t/3*6,r=y.createTypedArray(t,n),a=0,i=0;i<t;i+=3,a+=6)g(r,a,e[i],e[i+1],e[i+2]);return r}function M(e){var t=e.length;if(t>=3){var n=6*(t-2),r=y.createTypedArray(t,n);g(r,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)g(r,a,e[i-1],e[i],e[i-2]);return r}return new Uint16Array}function O(e){if(e.length>0){for(var t=e.length-1,n=6*(t-1),r=y.createTypedArray(t,n),a=e[0],i=0,o=1;o<t;++o,i+=6)g(r,i,a,e[o],e[o+1]);return r}return new Uint16Array}function x(e){var t={};for(var n in e)if(e.hasOwnProperty(n)&&c(e[n])&&c(e[n].values)){var r=e[n];t[n]=new d({componentDatatype:r.componentDatatype,componentsPerAttribute:r.componentsPerAttribute,normalize:r.normalize,values:[]})}return t}function w(e,t,n){for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values))for(var a=t[r],i=0;i<a.componentsPerAttribute;++i)e[r].values.push(a.values[n*a.componentsPerAttribute+i])}function C(e,t){if(c(t))for(var n=t.values,r=n.length,i=0;i<r;i+=3)a.unpack(n,i,ie),v.multiplyByPoint(e,ie,ie),a.pack(ie,n,i)}function P(e,t){if(c(t))for(var n=t.values,r=n.length,i=0;i<r;i+=3)a.unpack(n,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,n,i)}function L(e,t){var n,r=e.length,a={},i=e[0][t].attributes;for(n in i)if(i.hasOwnProperty(n)&&c(i[n])&&c(i[n].values)){for(var o=i[n],s=o.values.length,l=!0,E=1;E<r;++E){var f=e[E][t].attributes[n];if(!c(f)||o.componentDatatype!==f.componentDatatype||o.componentsPerAttribute!==f.componentsPerAttribute||o.normalize!==f.normalize){l=!1;break}s+=f.values.length}l&&(a[n]=new d({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function b(e,t){var r,i,o,u,s,l,E,f=e.length,d=(e[0].modelMatrix,c(e[0][t].indices)),p=e[0][t].primitiveType,_=L(e,t);for(r in _)if(_.hasOwnProperty(r))for(s=_[r].values,u=0,i=0;i<f;++i)for(l=e[i][t].attributes[r].values,E=l.length,o=0;o<E;++o)s[u++]=l[o];var m;if(d){var T=0;for(i=0;i<f;++i)T+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:_,primitiveType:S.POINTS})),v=y.createTypedArray(R,T),A=0,N=0;for(i=0;i<f;++i){var g=e[i][t].indices,I=g.length;for(u=0;u<I;++u)v[A++]=N+g[u];N+=h.computeNumberOfVertices(e[i][t])}m=v}var M,O=new a,x=0;for(i=0;i<f;++i){if(M=e[i][t].boundingSphere,!c(M)){O=void 0;break}a.add(M.center,O,O)}if(c(O))for(a.divideByScalar(O,f,O),i=0;i<f;++i){M=e[i][t].boundingSphere;var w=a.magnitude(a.subtract(M.center,O,se))+M.radius;w>x&&(x=w)}return new h({attributes:_,indices:m,primitiveType:p,boundingSphere:c(O)?new n(O,x):void 0})}function U(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function F(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,3*(t-2));n[0]=1,n[1]=0,n[2]=2;for(var r=3,a=3;a<t;++a)n[r++]=a-1,n[r++]=0,n[r++]=a;return e.indices=n,e.primitiveType=S.TRIANGLES,e}function D(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,3*(t-2));n[0]=0,n[1]=1,n[2]=2,t>3&&(n[3]=0,n[4]=2,n[5]=3);for(var r=6,a=3;a<t-1;a+=2)n[r++]=a,n[r++]=a-1,n[r++]=a+1,a+2<t&&(n[r++]=a,n[r++]=a+1,n[r++]=a+2);return e.indices=n,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function z(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,2*(t-1));n[0]=0,n[1]=1;for(var r=2,a=2;a<t;++a)n[r++]=a-1,n[r++]=a;return e.indices=n,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,2*t);n[0]=0,n[1]=1;for(var r=2,a=2;a<t;++a)n[r++]=a-1,n[r++]=a;return n[r++]=t-1,n[r]=0,e.indices=n,e.primitiveType=S.LINES,e}function q(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return F(e);case S.TRIANGLE_STRIP:return D(e);case S.TRIANGLES:return U(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<T.EPSILON6&&(e.y=t?-T.EPSILON6:T.EPSILON6)}function X(e,t,n){if(0!==e.y&&0!==t.y&&0!==n.y)return V(e,e.y<0),V(t,t.y<0),void V(n,n.y<0);var r,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(n.y);r=a>i?a>o?T.sign(e.y):T.sign(n.y):i>o?T.sign(t.y):T.sign(n.y);var u=r<0;V(e,u),V(t,u),V(n,u)}function W(e,t,n,r){a.add(e,a.multiplyByScalar(a.subtract(t,e,ve),e.y/(e.y-t.y),ve),n),a.clone(n,r),V(n,!0),V(r,!1)}function H(e,t,n){if(!(e.x>=0||t.x>=0||n.x>=0)){X(e,t,n);var r=e.y<0,a=t.y<0,i=n.y<0,o=0;o+=r?1:0,o+=a?1:0,o+=i?1:0;var u=Ie.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,r?(W(e,t,Ae,Ne),W(e,n,Se,ge),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(W(t,n,Ae,Ne),W(t,e,Se,ge),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(W(n,e,Ae,Ne),W(n,t,Se,ge),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,r?a?i||(W(n,e,Ae,Ne),W(n,t,Se,ge),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(W(t,n,Ae,Ne),W(t,e,Se,ge),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(W(e,t,Ae,Ne),W(e,n,Se,ge),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Ie.positions;return s[0]=e,s[1]=t,s[2]=n,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=Ne,s[6]=ge,s.length=7),Ie}}function Y(e,t){var r=e.attributes;if(0!==r.position.values.length){for(var a in r)if(r.hasOwnProperty(a)&&c(r[a])&&c(r[a].values)){var i=r[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=y.createTypedArray(o,e.indices),t&&(e.boundingSphere=n.fromVertices(r.position.values)),e}}function k(e){var t=e.attributes,n={};for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values)){var a=t[r];n[r]=new d({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:n,indices:[],primitiveType:e.primitiveType})}function Z(e,t,n){var r=c(e.geometry.boundingSphere);t=Y(t,r),n=Y(n,r),c(n)&&!c(t)?e.geometry=n:!c(n)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=n,e.geometry=void 0)}function K(e,n,i,o,u,s,l,E,f,h,d,p){if(c(s)||c(l)||c(E)||c(f)||c(h)){var y=a.fromArray(u,3*e,Me),_=a.fromArray(u,3*n,Oe),m=a.fromArray(u,3*i,xe),T=t(o,y,_,m,we);if(c(s)){var R=a.fromArray(s,3*e,Me),v=a.fromArray(s,3*n,Oe),A=a.fromArray(s,3*i,xe);a.multiplyByScalar(R,T.x,R),a.multiplyByScalar(v,T.y,v),a.multiplyByScalar(A,T.z,A);var S=a.add(R,v,R);a.add(S,A,S),a.normalize(S,S),a.pack(S,d.normal.values,3*p)}if(c(h)){var N=a.fromArray(h,3*e,Me),g=a.fromArray(h,3*n,Oe),I=a.fromArray(h,3*i,xe);a.multiplyByScalar(N,T.x,N),a.multiplyByScalar(g,T.y,g),a.multiplyByScalar(I,T.z,I);var M;a.equals(N,a.ZERO)&&a.equals(g,a.ZERO)&&a.equals(I,a.ZERO)?(M=Me,M.x=0,M.y=0,M.z=0):(M=a.add(N,g,N),a.add(M,I,M),a.normalize(M,M)),a.pack(M,d.extrudeDirection.values,3*p)}if(c(l)){var O=a.fromArray(l,3*e,Me),x=a.fromArray(l,3*n,Oe),w=a.fromArray(l,3*i,xe);a.multiplyByScalar(O,T.x,O),a.multiplyByScalar(x,T.y,x),a.multiplyByScalar(w,T.z,w);var C=a.add(O,x,O);a.add(C,w,C),a.normalize(C,C),a.pack(C,d.tangent.values,3*p)}if(c(E)){var P=a.fromArray(E,3*e,Me),L=a.fromArray(E,3*n,Oe),b=a.fromArray(E,3*i,xe);a.multiplyByScalar(P,T.x,P),a.multiplyByScalar(L,T.y,L),a.multiplyByScalar(b,T.z,b);var U=a.add(P,L,P);a.add(U,b,U),a.normalize(U,U),a.pack(U,d.bitangent.values,3*p)}if(c(f)){var F=r.fromArray(f,2*e,Ce),D=r.fromArray(f,2*n,Pe),B=r.fromArray(f,2*i,Le);r.multiplyByScalar(F,T.x,F),r.multiplyByScalar(D,T.y,D),r.multiplyByScalar(B,T.z,B);var z=r.add(F,D,F);r.add(z,B,z),r.pack(z,d.st.values,2*p)}}}function j(e,t,n,r,a,i){var o=e.position.values.length/3;if(-1!==a){var u=r[a],s=n[u];return-1===s?(n[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function Q(e){var t,n,r,i,o,u=e.geometry,s=u.attributes,l=s.position.values,E=c(s.normal)?s.normal.values:void 0,f=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,d=c(s.st)?s.st.values:void 0,p=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,y=u.indices,_=k(u),m=k(u),T=[];T.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<T.length;++o)T[o]=-1,R[o]=-1;var v=y.length;for(o=0;o<v;o+=3){var A=y[o],S=y[o+1],N=y[o+2],g=a.fromArray(l,3*A),I=a.fromArray(l,3*S),M=a.fromArray(l,3*N),O=H(g,I,M);if(c(O)&&O.positions.length>3)for(var x=O.positions,w=O.indices,C=w.length,P=0;P<C;++P){var L=w[P],b=x[L];b.y<0?(t=m.attributes,n=m.indices,r=T):(t=_.attributes,n=_.indices,r=R),i=j(t,n,r,y,L<3?o+L:-1,b),K(A,S,N,b,l,E,h,f,d,p,t,i)}else c(O)&&(g=O.positions[0],I=O.positions[1],M=O.positions[2]),g.y<0?(t=m.attributes,n=m.indices,r=T):(t=_.attributes,n=_.indices,r=R),i=j(t,n,r,y,o,g),K(A,S,N,g,l,E,h,f,d,p,t,i),i=j(t,n,r,y,o+1,I),K(A,S,N,I,l,E,h,f,d,p,t,i),i=j(t,n,r,y,o+2,M),K(A,S,N,M,l,E,h,f,d,p,t,i)}Z(e,m,_)}function J(e){var t,n=e.geometry,r=n.attributes,i=r.position.values,o=n.indices,u=k(n),s=k(n),l=o.length,E=[];E.length=i.length/3;var f=[];for(f.length=i.length/3,t=0;t<E.length;++t)E[t]=-1,f[t]=-1;for(t=0;t<l;t+=2){var h=o[t],d=o[t+1],p=a.fromArray(i,3*h,Me),y=a.fromArray(i,3*d,Oe);Math.abs(p.y)<T.EPSILON6&&(p.y<0?p.y=-T.EPSILON6:p.y=T.EPSILON6),Math.abs(y.y)<T.EPSILON6&&(y.y<0?y.y=-T.EPSILON6:y.y=T.EPSILON6);var _=u.attributes,R=u.indices,v=f,A=s.attributes,S=s.indices,N=E,g=m.lineSegmentPlane(p,y,be,xe);if(c(g)){var I=a.multiplyByScalar(a.UNIT_Y,5*T.EPSILON9,Ue);p.y<0&&(a.negate(I,I),_=s.attributes,R=s.indices,v=E,A=u.attributes,S=u.indices,N=f);var M=a.add(g,I,Fe);j(_,R,v,o,t,p),j(_,R,v,o,-1,M),a.negate(I,I),a.add(g,I,M),j(A,S,N,o,-1,M),j(A,S,N,o,t+1,y)}else{var O,x,w;p.y<0?(O=s.attributes,x=s.indices,w=E):(O=u.attributes,x=u.indices,w=f),j(O,x,w,o,t,p),j(O,x,w,o,t+1,y)}}Z(e,s,u)}function $(e){for(var t=e.attributes,n=t.position.values,r=t.prevPosition.values,i=t.nextPosition.values,o=n.length,u=0;u<o;u+=3){var s=a.unpack(n,u,ze);if(!(s.x>0)){var c=a.unpack(r,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(r[u]=n[u-3],r[u+1]=n[u-2],r[u+2]=n[u-1]):a.pack(s,r,u));var l=a.unpack(i,u,qe);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=n[u+3],i[u+1]=n[u+4],i[u+2]=n[u+5]):a.pack(s,i,u))}}}function ee(e){var t,n,o,u=e.geometry,s=u.attributes,l=s.position.values,E=s.prevPosition.values,f=s.nextPosition.values,h=s.expandAndWidth.values,d=c(s.st)?s.st.values:void 0,p=c(s.color)?s.color.values:void 0,y=k(u),_=k(u),R=!1,v=l.length/3;for(t=0;t<v;t+=4){var A=t,S=t+2,N=a.fromArray(l,3*A,ze),g=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<ke)for(N.y=ke*(g.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,n=3*A;n<3*A+12;n+=3)E[n]=l[3*t],E[n+1]=l[3*t+1],E[n+2]=l[3*t+2];if(Math.abs(g.y)<ke)for(g.y=ke*(N.y<0?-1:1),l[3*(t+2)+1]=g.y,l[3*(t+3)+1]=g.y,n=3*A;n<3*A+12;n+=3)f[n]=l[3*(t+2)],f[n+1]=l[3*(t+2)+1],f[n+2]=l[3*(t+2)+2];var I=y.attributes,M=y.indices,O=_.attributes,x=_.indices,w=m.lineSegmentPlane(N,g,be,Ve);if(c(w)){R=!0;var C=a.multiplyByScalar(a.UNIT_Y,Ye,Xe);N.y<0&&(a.negate(C,C),I=_.attributes,M=_.indices,O=y.attributes,x=y.indices);var P=a.add(w,C,We);I.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.prevPosition.values.push(E[3*A],E[3*A+1],E[3*A+2]),I.prevPosition.values.push(E[3*A+3],E[3*A+4],E[3*A+5]),I.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),a.negate(C,C),a.add(w,C,P),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.prevPosition.values.push(P.x,P.y,P.z),O.prevPosition.values.push(P.x,P.y,P.z),O.prevPosition.values.push(P.x,P.y,P.z),O.prevPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.nextPosition.values.push(f[3*S],f[3*S+1],f[3*S+2]),O.nextPosition.values.push(f[3*S+3],f[3*S+4],f[3*S+5]);var L=r.fromArray(h,2*A,De),b=Math.abs(L.y);I.expandAndWidth.values.push(-1,b,1,b),I.expandAndWidth.values.push(-1,-b,1,-b),O.expandAndWidth.values.push(-1,b,1,b),O.expandAndWidth.values.push(-1,-b,1,-b);var U=a.magnitudeSquared(a.subtract(w,N,qe));if(U/=a.magnitudeSquared(a.subtract(g,N,qe)),c(p)){var F=i.fromArray(p,4*A,He),D=i.fromArray(p,4*S,He),B=T.lerp(F.x,D.x,U),z=T.lerp(F.y,D.y,U),G=T.lerp(F.z,D.z,U),q=T.lerp(F.w,D.w,U);for(n=4*A;n<4*A+8;++n)I.color.values.push(p[n]);for(I.color.values.push(B,z,G,q),I.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),n=4*S;n<4*S+8;++n)O.color.values.push(p[n])}if(c(d)){var V=r.fromArray(d,2*A,De),X=r.fromArray(d,2*(t+3),Be),W=T.lerp(V.x,X.x,U);for(n=2*A;n<2*A+4;++n)I.st.values.push(d[n]);for(I.st.values.push(W,V.y),I.st.values.push(W,X.y),O.st.values.push(W,V.y),O.st.values.push(W,X.y),n=2*S;n<2*S+4;++n)O.st.values.push(d[n])}o=I.position.values.length/3-4,M.push(o,o+2,o+1),M.push(o+1,o+2,o+3),o=O.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3)}else{var H,Y;for(N.y<0?(H=_.attributes,Y=_.indices):(H=y.attributes,Y=y.indices),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),n=3*t;n<3*t+12;++n)H.prevPosition.values.push(E[n]),H.nextPosition.values.push(f[n]);for(n=2*t;n<2*t+8;++n)H.expandAndWidth.values.push(h[n]),c(d)&&H.st.values.push(d[n]);if(c(p))for(n=4*t;n<4*t+16;++n)H.color.values.push(p[n]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}R&&($(_),$(y)),Z(e,_,y)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=I(t);break;case S.TRIANGLE_STRIP:e.indices=M(t);break;case S.TRIANGLE_FAN:e.indices=O(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,r){t=s(t,"normal"),r=s(r,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),E=0,f=0;f<o;f+=3)l[E++]=a[f],l[E++]=a[f+1],l[E++]=a[f+2],l[E++]=a[f]+i[f]*r,l[E++]=a[f+1]+i[f+1]*r,l[E++]=a[f+2]+i[f+2]*r;var p,y=e.boundingSphere;return c(y)&&(p=new n(y.center,y.radius+r)),new h({attributes:{position:new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:p})},te.createAttributeLocations=function(e){var t,n=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],r=e.attributes,a={},i=0,o=n.length;for(t=0;t<o;++t){var u=n[t];c(r[u])&&(a[u]=i++)}for(var s in r)r.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),n=e.indices;if(c(n)){for(var r=new Int32Array(t),a=0;a<t;a++)r[a]=-1;for(var i,o=n,s=o.length,l=y.createTypedArray(t,s),E=0,f=0,d=0;E<s;)i=r[o[E]],-1!==i?l[f]=i:(i=o[E],r[i]=d,l[f]=d,++d),++E,++f;e.indices=l;var p=e.attributes;for(var _ in p)if(p.hasOwnProperty(_)&&c(p[_])&&c(p[_].values)){for(var m=p[_],T=m.values,R=0,v=m.componentsPerAttribute,A=u.createTypedArray(m.componentDatatype,d*v);R<t;){var S=r[R];if(-1!==S)for(var N=0;N<v;N++)A[v*S+N]=T[v*R+N];++R}m.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var n=e.indices;if(e.primitiveType===S.TRIANGLES&&c(n)){for(var r=n.length,a=0,i=0;i<r;i++)n[i]>a&&(a=n[i]);e.indices=N.tipsify({indices:n,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],n=h.computeNumberOfVertices(e);if(c(e.indices)&&n>=T.SIXTY_FOUR_KILOBYTES){var r,a=[],i=[],o=0,u=x(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?r=3:e.primitiveType===S.LINES?r=2:e.primitiveType===S.POINTS&&(r=1);for(var E=0;E<l;E+=r){for(var f=0;f<r;++f){var d=s[E+f],p=a[d];c(p)||(p=o++,a[d]=p,w(u,e.attributes,d)),i.push(p)}o+r>=T.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=x(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var ne=new a,re=new o;te.projectTo2D=function(e,t,n,r,i){var o=e.attributes[t];i=c(i)?i:new f;for(var s=i.ellipsoid,l=o.values,E=new Float64Array(l.length),h=0,p=0;p<l.length;p+=3){var y=a.fromArray(l,p,ne),_=s.cartesianToCartographic(y,re),m=i.project(_,ne);E[h++]=m.x,E[h++]=m.y,E[h++]=m.z}return e.attributes[n]=o,e.attributes[r]=new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:E}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,n,r){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)E.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var f=a.componentsPerAttribute;return e.attributes[n]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:s}),e.attributes[r]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:c}),delete e.attributes[t],e};var ie=new a,oe=new v,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(v.equals(t,v.IDENTITY))return e;var r=e.geometry.attributes;C(t,r.position),C(t,r.prevPosition),C(t,r.nextPosition),(c(r.normal)||c(r.tangent)||c(r.bitangent))&&(v.inverse(t,oe),v.transpose(oe,oe),v.getRotation(oe,ue),P(ue,r.normal),P(ue,r.tangent),P(ue,r.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=n.transform(a,t,a)),e.modelMatrix=v.clone(v.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],n=[],r=e.length,a=0;a<r;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&n.push(i)}var o=[];return t.length>0&&o.push(b(t,"geometry")),n.length>0&&(o.push(b(n,"westHemisphereGeometry")),o.push(b(n,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,Ee=new a,fe=new a;te.computeNormal=function(e){var t,n=e.indices,r=e.attributes,i=r.position.values,o=r.position.values.length/3,s=n.length,c=new Array(o),l=new Array(s/3),E=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var f=0;for(t=0;t<s;t+=3){var h=n[t],p=n[t+1],y=n[t+2],_=3*h,m=3*p,R=3*y;le.x=i[_],le.y=i[_+1],le.z=i[_+2],Ee.x=i[m],Ee.y=i[m+1],Ee.z=i[m+2],fe.x=i[R],fe.y=i[R+1],fe.z=i[R+2],c[h].count++,c[p].count++,c[y].count++,a.subtract(Ee,le,Ee),a.subtract(fe,le,fe),l[f]=a.cross(Ee,fe,new a),f++}var v=0;for(t=0;t<o;t++)c[t].indexOffset+=v,v+=c[t].count;f=0;var A;for(t=0;t<s;t+=3){A=c[n[t]];var S=A.indexOffset+A.currentCount;E[S]=f,A.currentCount++,A=c[n[t+1]],S=A.indexOffset+A.currentCount,E[S]=f,A.currentCount++,A=c[n[t+2]],S=A.indexOffset+A.currentCount,E[S]=f,A.currentCount++,f++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var g=3*t;if(A=c[t],a.clone(a.ZERO,ce),A.count>0){for(f=0;f<A.count;f++)a.add(ce,l[E[A.indexOffset+f]],ce);a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&a.clone(l[E[A.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[g]=ce.x,N[g+1]=ce.y,N[g+2]=ce.z}return e.attributes.normal=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,de=new a,pe=new a;te.computeTangentAndBitangent=function(e){var t,n=(e.attributes,e.indices),r=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=n.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var E,f,h;for(t=0;t<c;t+=3){var p=n[t],y=n[t+1],_=n[t+2];E=3*p,f=3*y,h=3*_;var m=2*p,T=2*y,R=2*_,v=r[E],A=r[E+1],S=r[E+2],N=o[m],g=o[m+1],I=o[T+1]-g,M=o[R+1]-g,O=1/((o[T]-N)*M-(o[R]-N)*I),x=(M*(r[f]-v)-I*(r[h]-v))*O,w=(M*(r[f+1]-A)-I*(r[h+1]-A))*O,C=(M*(r[f+2]-S)-I*(r[h+2]-S))*O;l[E]+=x,l[E+1]+=w,l[E+2]+=C,l[f]+=x,l[f+1]+=w,l[f+2]+=C,l[h]+=x,l[h+1]+=w,l[h+2]+=C}var P=new Float32Array(3*s),L=new Float32Array(3*s);for(t=0;t<s;t++){E=3*t,f=E+1,h=E+2;var b=a.fromArray(i,E,he),U=a.fromArray(l,E,pe),F=a.dot(b,U);a.multiplyByScalar(b,F,de),a.normalize(a.subtract(U,de,U),U),P[E]=U.x,P[f]=U.y,P[h]=U.z,a.normalize(a.cross(b,U,U),U),L[E]=U.x,L[f]=U.y,L[h]=U.z}return e.attributes.tangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:L}),e};var ye=new r,_e=new a,me=new a,Te=new a,Re=new r;te.compressVertices=function(t){var n,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),E=0;for(n=0;n<i;++n)a.fromArray(s,3*n,_e),a.equals(_e,a.ZERO)?E+=2:(Re=e.octEncodeInRange(_e,65535,Re),l[E++]=Re.x,l[E++]=Re.y);return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var f=t.attributes.normal,h=t.attributes.st,p=c(f),y=c(h);if(!p&&!y)return t;var _,m,T,R,v=t.attributes.tangent,A=t.attributes.bitangent,S=c(v),N=c(A);p&&(_=f.values),y&&(m=h.values),S&&(T=v.values),N&&(R=A.values),i=(p?_.length:m.length)/(p?3:2);var g=i,I=y&&p?2:1;I+=S||N?1:0,g*=I;var M=new Float32Array(g),O=0;for(n=0;n<i;++n){y&&(r.fromArray(m,2*n,ye),M[O++]=e.compressTextureCoordinates(ye));var x=3*n;p&&c(T)&&c(R)?(a.fromArray(_,x,_e),a.fromArray(T,x,me),a.fromArray(R,x,Te),e.octPack(_e,me,Te,ye),M[O++]=ye.x,M[O++]=ye.y):(p&&(a.fromArray(_,x,_e),M[O++]=e.octEncodeFloat(_e)),S&&(a.fromArray(T,x,_e),M[O++]=e.octEncodeFloat(_e)),N&&(a.fromArray(R,x,_e),M[O++]=e.octEncodeFloat(_e)))}return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:I,values:M}),p&&delete t.attributes.normal,y&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var ve=new a,Ae=new a,Se=new a,Ne=new a,ge=new a,Ie={positions:new Array(7),indices:new Array(9)},Me=new a,Oe=new a,xe=new a,we=new a,Ce=new r,Pe=new r,Le=new r,be=A.fromPointNormal(a.ZERO,a.UNIT_Y),Ue=new a,Fe=new a,De=new r,Be=new r,ze=new a,Ge=new a,qe=new a,Ve=new a,Xe=new a,We=new a,He=new i,Ye=5*T.EPSILON9,ke=T.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,r=t.boundingSphere;if(c(r)){if(r.center.x-r.radius>0||n.intersectPlane(r,A.ORIGIN_ZX_PLANE)!==_.INTERSECTING)return e}if(t.geometryType!==p.NONE)switch(t.geometryType){case p.POLYLINES:ee(e);break;case p.TRIANGLES:Q(e);break;case p.LINES:J(e)}else q(t),t.primitiveType===S.TRIANGLES?Q(e):t.primitiveType===S.LINES&&J(e);return e},te}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,E,f,h,d,p,y;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=f=e[0],E=h=e[1];for(var _=a;_<o;_+=a)d=e[_],p=e[_+1],d<l&&(l=d),p<E&&(E=p),d>f&&(f=d),p>h&&(h=p);y=Math.max(f-l,h-E)}return r(u,c,a,l,E,y),c}function t(e,t,n,r,a){var i,o -;if(a===O(e,t,n,r)>0)for(i=t;i<n;i+=r)o=g(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=g(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(I(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==m(r.prev,r,r.next))r=r.next;else{if(I(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,E,h){if(e){!h&&E&&f(e,c,l,E);for(var d,p,y=e;e.prev!==e.next;)if(d=e.prev,p=e.next,E?i(e,c,l,E):a(e))t.push(d.i/s),t.push(e.i/s),t.push(p.i/s),I(e),e=p.next,y=p.next;else if((e=p)===y){h?1===h?(e=o(e,t,s),r(e,t,s,c,l,E,2)):2===h&&u(e,t,s,c,l,E):r(n(e),t,s,c,l,E,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(m(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(y(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&m(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(m(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,E=d(u,s,t,n,r),f=d(c,l,t,n,r),h=e.nextZ;h&&h.z<=f;){if(h!==e.prev&&h!==e.next&&y(a.x,a.y,i.x,i.y,o.x,o.y,h.x,h.y)&&m(h.prev,h,h.next)>=0)return!1;h=h.nextZ}for(h=e.prevZ;h&&h.z>=E;){if(h!==e.prev&&h!==e.next&&y(a.x,a.y,i.x,i.y,o.x,o.y,h.x,h.y)&&m(h.prev,h,h.next)>=0)return!1;h=h.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&A(a,i)&&A(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),I(r),I(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&_(s,c)){var l=N(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,E,f,h=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,E=o<u-1?r[o+1]*i:e.length,f=t(e,s,E,i,!1),f===f.next&&(f.steiner=!0),h.push(p(f));for(h.sort(c),o=0;o<h.length;o++)l(h[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=E(e,t)){var r=N(t,e);n(r,r.next)}}function E(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,E=n.y,f=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&y(i<E?a:o,i,l,E,i<E?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<f||s===f&&r.x>n.x)&&A(r,e)&&(n=r,f=s),r=r.next;return n}function f(e,t,n,r){var a=e;do{null===a.z&&(a.z=d(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,h(a)}function h(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function d(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function p(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function y(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function m(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||m(e,t,n)>0!=m(e,t,r)>0&&m(n,r,e)>0!=m(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return m(e.prev,e,e.next)<0?m(e,t,e.next)>=0&&m(e,e.prev,t)>=0:m(e,t,e.prev)<0||m(e,e.next,t)<0}function S(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function N(e,t){var n=new M(e.i,e.x,e.y),r=new M(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function g(e,t,n,r){var a=new M(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function I(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function M(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function O(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(O(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(O(e,c,l,n))}var E=0;for(u=0;u<r.length;u+=3){var f=r[u]*n,h=r[u+1]*n,d=r[u+2]*n;E+=Math.abs((e[f]-e[d])*(e[h+1]-e[f+1])-(e[f]-e[h])*(e[d+1]-e[f+1]))}return 0===o&&0===E?0:Math.abs((E-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,E,f){"use strict";var h=new n,d=new n,p={};p.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},p.computeWindingOrder2D=function(e){return p.computeArea2D(e)>0?f.COUNTER_CLOCKWISE:f.CLOCKWISE},p.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var y=new n,_=new n,m=new n,T=new n,R=new n,v=new n,A=new n;return p.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var f,h=r.slice(0),d=t.length,p=new Array(3*d),S=0;for(f=0;f<d;f++){var N=t[f];p[S++]=N.x,p[S++]=N.y,p[S++]=N.z}for(var g=[],I={},M=e.maximumRadius,O=l.chordLength(u,M),x=O*O;h.length>0;){var w,C,P=h.pop(),L=h.pop(),b=h.pop(),U=n.fromArray(p,3*b,y),F=n.fromArray(p,3*L,_),D=n.fromArray(p,3*P,m),B=n.multiplyByScalar(n.normalize(U,T),M,T),z=n.multiplyByScalar(n.normalize(F,R),M,R),G=n.multiplyByScalar(n.normalize(D,v),M,v),q=n.magnitudeSquared(n.subtract(B,z,A)),V=n.magnitudeSquared(n.subtract(z,G,A)),X=n.magnitudeSquared(n.subtract(G,B,A)),W=Math.max(q,V,X);W>x?q===W?(w=Math.min(b,L)+" "+Math.max(b,L),f=I[w],o(f)||(C=n.add(U,F,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),f=p.length/3-1,I[w]=f),h.push(b,f,P),h.push(f,L,P)):V===W?(w=Math.min(L,P)+" "+Math.max(L,P),f=I[w],o(f)||(C=n.add(F,D,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),f=p.length/3-1,I[w]=f),h.push(L,f,b),h.push(f,P,b)):X===W&&(w=Math.min(P,b)+" "+Math.max(P,b),f=I[w],o(f)||(C=n.add(D,U,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),f=p.length/3-1,I[w]=f),h.push(P,f,L),h.push(f,b,L)):(g.push(b),g.push(L),g.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:p})},indices:g,primitiveType:E.TRIANGLES})},p.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=h,c=d;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,E=0;E<l;E+=3)n.fromArray(e,E,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[E]=c.x,e[E+1]=c.y,e[E+2]=c.z;return e},p}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,E=c.z*o,f=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=E,a.w=f,a):new s(u,l,E,f)};var l=[1,2,0],E=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,f=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],d=e[u.COLUMN2ROW2],p=f+h+d;if(p>0)n=Math.sqrt(p+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var y=l,_=0;h>f&&(_=1),d>f&&d>h&&(_=2);var m=y[_],T=y[m];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(m,m)]-e[u.getElementIndex(T,T)]+1);var R=E;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,m)]-e[u.getElementIndex(m,T)])*n,R[m]=(e[u.getElementIndex(m,_)]+e[u.getElementIndex(_,m)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var f=new s,h=new s,d=new s,p=new s;s.fromHeadingPitchRoll=function(t,n){return p=s.fromAxisAngle(e.UNIT_X,t.roll,f),d=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(d,p,d),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,f),s.multiply(h,n,n)};var y=new e,_=new e,m=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),m),s.multiply(m,R,m),m.w<0&&s.negate(m,m),s.computeAxis(m,y);var u=s.computeAngle(m);r[o]=y.x*u,r[o+1]=y.y*u,r[o+2]=y.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,m):s.fromAxisAngle(_,u,m),s.multiply(m,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,E=o*u+r*l+a*c-i*s,f=o*s-r*c+a*l+i*u,h=o*c+r*s-a*u+i*l,d=o*l-r*u-a*s-i*c;return n.x=E,n.y=f,n.z=h,n.w=d,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,S=new s,N=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=A=s.negate(t,A)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),N=s.multiplyByScalar(i,Math.sin(n*u),N),r=s.add(S,N,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var g=new e,I=new e,M=new s,O=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,M);s.multiply(i,r,O);var o=s.log(O,g);s.multiply(i,t,O);var u=s.log(O,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,M),u=s.slerp(n,r,a,O);return s.slerp(o,u,2*a*(1-a),i)};for(var x=new s,w=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],L=a.supportsTypedArrays()?new Float32Array(8):[],b=a.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var F=U+1,D=2*F+1;C[U]=1/(F*D),P[U]=F/D}return C[7]=w/136,P[7]=8*w/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,E=7;E>=0;--E)L[E]=(C[E]*c-P[E])*o,b[E]=(C[E]*l-P[E])*o;var f=a*n*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),h=u*(1+b[0]*(1+b[1]*(1+b[2]*(1+b[3]*(1+b[4]*(1+b[5]*(1+b[6]*(1+b[7])))))))),d=s.multiplyByScalar(e,h,x);return s.multiplyByScalar(t,f,r),s.add(d,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,M),u=s.fastSlerp(n,r,a,O);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Matrix2",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./freezeObject"],function(e,t,n,r,a,i){"use strict";function o(e,t,r,a){this[0]=n(e,0),this[1]=n(r,0),this[2]=n(t,0),this[3]=n(a,0)}o.packedLength=4,o.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t},o.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new o),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a},o.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):new o(e[0],e[2],e[1],e[3])},o.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new o),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a},o.fromColumnMajorArray=function(e,t){return o.clone(e,t)},o.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[2],t[2]=e[1],t[3]=e[3],t):new o(e[0],e[1],e[2],e[3])},o.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=e.y,t):new o(e.x,0,0,e.y)},o.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=e,t):new o(e,0,0,e)},o.fromRotation=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=-a,t[3]=n,t):new o(n,-a,a,n)},o.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):[e[0],e[1],e[2],e[3]]},o.getElementIndex=function(e,t){return 2*e+t},o.getColumn=function(e,t,n){var r=2*t,a=e[r],i=e[r+1];return n.x=a,n.y=i,n},o.setColumn=function(e,t,n,r){r=o.clone(e,r);var a=2*t;return r[a]=n.x,r[a+1]=n.y,r},o.getRow=function(e,t,n){var r=e[t],a=e[t+2];return n.x=r,n.y=a,n},o.setRow=function(e,t,n,r){return r=o.clone(e,r),r[t]=n.x,r[t+2]=n.y,r};var u=new e;o.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],u)),n.y=e.magnitude(e.fromElements(t[2],t[3],u)),n};var s=new e;return o.getMaximumScale=function(t){return o.getScale(t,s),e.maximumComponent(s)},o.multiply=function(e,t,n){var r=e[0]*t[0]+e[2]*t[1],a=e[0]*t[2]+e[2]*t[3],i=e[1]*t[0]+e[3]*t[1],o=e[1]*t[2]+e[3]*t[3];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n},o.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n},o.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n},o.multiplyByVector=function(e,t,n){var r=e[0]*t.x+e[2]*t.y,a=e[1]*t.x+e[3]*t.y;return n.x=r,n.y=a,n},o.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n},o.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.y,n[3]=e[3]*t.y,n},o.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},o.transpose=function(e,t){var n=e[0],r=e[2],a=e[1],i=e[3];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t},o.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},o.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]},o.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n},o.IDENTITY=i(new o(1,0,0,1)),o.ZERO=i(new o(0,0,0,0)),o.COLUMN0ROW0=0,o.COLUMN0ROW1=1,o.COLUMN1ROW0=2,o.COLUMN1ROW1=3,a(o.prototype,{length:{get:function(){return o.packedLength}}}),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t){return o.equalsEpsilon(this,e,t)},o.prototype.toString=function(){return"("+this[0]+", "+this[2]+")\n("+this[1]+", "+this[3]+")"},o}),define("Core/RectangleGeometryLibrary",["./Cartesian3","./Cartographic","./defined","./DeveloperError","./GeographicProjection","./Math","./Matrix2","./Rectangle"],function(e,t,n,r,a,i,o,u){"use strict";function s(t,n,r,a,i,u,s){var c=Math.cos(n),l=a*c,E=r*c,f=Math.sin(n),p=a*f,m=r*f;d=_.project(t,d),d=e.subtract(d,y,d);var T=o.fromRotation(n,h);d=o.multiplyByVector(T,d,d),d=e.add(d,y,d),t=_.unproject(d,t),u-=1,s-=1;var R=t.latitude,v=R+u*m,A=R-l*s,S=R-l*s+u*m,N=Math.max(R,v,A,S),g=Math.min(R,v,A,S),I=t.longitude,M=I+u*E,O=I+s*p,x=I+s*p+u*E;return{north:N,south:g,east:Math.max(I,M,O,x),west:Math.min(I,M,O,x),granYCos:l,granYSin:p,granXCos:E,granXSin:m,nwCorner:t}}var c=Math.cos,l=Math.sin,E=Math.sqrt,f={};f.computePosition=function(e,t,r,a,i){var o=e.ellipsoid.radiiSquared,u=e.nwCorner,s=e.rectangle,f=u.latitude-e.granYCos*t+r*e.granXSin,h=c(f),d=l(f),p=o.z*d,y=u.longitude+t*e.granYSin+r*e.granXCos,_=h*c(y),m=h*l(y),T=o.x*_,R=o.y*m,v=E(T*_+R*m+p*d);if(a.x=T/v,a.y=R/v,a.z=p/v,n(e.vertexFormat)&&e.vertexFormat.st){var A=e.stNwCorner;n(A)?(f=A.latitude-e.stGranYCos*t+r*e.stGranXSin,y=A.longitude+t*e.stGranYSin+r*e.stGranXCos,i.x=(y-e.stWest)*e.lonScalar,i.y=(f-e.stSouth)*e.latScalar):(i.x=(y-s.west)*e.lonScalar,i.y=(f-s.south)*e.latScalar)}};var h=new o,d=new e,p=new t,y=new e,_=new a;return f.computeOptions=function(e,t,n,r){var a,o,c,l,E,f=e._granularity,h=e._ellipsoid,d=e._surfaceHeight,m=e._rotation,T=e._stRotation,R=e._extrudedHeight,v=t.east,A=t.west,S=t.north,N=t.south,g=S-N;A>v?(E=i.TWO_PI-A+v,a=Math.ceil(E/f)+1,o=Math.ceil(g/f)+1,c=E/(a-1),l=g/(o-1)):(E=v-A,a=Math.ceil(E/f)+1,o=Math.ceil(g/f)+1,c=E/(a-1),l=g/(o-1)),n=u.northwest(t,n);var I=u.center(t,p);0===m&&0===T||(I.longitude<n.longitude&&(I.longitude+=i.TWO_PI),y=_.project(I,y));var M=l,O=c,x={granYCos:M,granYSin:0,granXCos:O,granXSin:0,ellipsoid:h,surfaceHeight:d,extrudedHeight:R,nwCorner:n,rectangle:t,width:a,height:o};if(0!==m){var w=s(n,m,c,l,I,a,o);S=w.north,N=w.south,v=w.east,A=w.west,x.granYCos=w.granYCos,x.granYSin=w.granYSin,x.granXCos=w.granXCos,x.granXSin=w.granXSin,t.north=S,t.south=N,t.east=v,t.west=A}if(0!==T){m-=T,r=u.northwest(t,r);var C=s(r,m,c,l,I,a,o);x.stGranYCos=C.granYCos,x.stGranXCos=C.granXCos,x.stGranYSin=C.granYSin,x.stGranXSin=C.granXSin,x.stNwCorner=r,x.stWest=C.west,x.stSouth=C.south}return x},f}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},a.unpack=function(n,r,i){return r=e(r,0),t(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(e,n){if(t(e))return t(n)||(n=new a),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},a}),define("Core/RectangleGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./PolygonPipeline","./PrimitiveType","./Quaternion","./Rectangle","./RectangleGeometryLibrary","./VertexFormat"],function(e,t,n,r,a,i,o,u,s,c,l,E,f,h,d,p,y,_,m,T,R,v,A,S,N){"use strict";function g(e,t){var n=new E({attributes:new h,primitiveType:R.TRIANGLES});return n.attributes.position=new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:t.positions}),e.normal&&(n.attributes.normal=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:t.normals})),e.tangent&&(n.attributes.tangent=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:t.tangents})),e.bitangent&&(n.attributes.bitangent=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:t.bitangents})),n}function I(e,t,r,a){var i=e.length,o=t.normal?new Float32Array(i):void 0,u=t.tangent?new Float32Array(i):void 0,s=t.bitangent?new Float32Array(i):void 0,c=0,l=D,E=F,f=U;if(t.normal||t.tangent||t.bitangent)for(var h=0;h<i;h+=3){var d=n.fromArray(e,h,b),p=c+1,y=c+2;f=r.geodeticSurfaceNormal(d,f),(t.tangent||t.bitangent)&&(n.cross(n.UNIT_Z,f,E),m.multiplyByVector(a,E,E),n.normalize(E,E),t.bitangent&&n.normalize(n.cross(f,E,l),l)),t.normal&&(o[c]=f.x,o[p]=f.y,o[y]=f.z),t.tangent&&(u[c]=E.x,u[p]=E.y,u[y]=E.z),t.bitangent&&(s[c]=l.x,s[p]=l.y,s[y]=l.z),c+=3}return g(t,{positions:e,normals:o,tangents:u,bitangents:s})}function M(e,t,r){var a=e.length,i=t.normal?new Float32Array(a):void 0,o=t.tangent?new Float32Array(a):void 0,u=t.bitangent?new Float32Array(a):void 0,s=0,c=0,l=0,E=!0,f=D,h=F,d=U;if(t.normal||t.tangent||t.bitangent)for(var p=0;p<a;p+=6){var y=n.fromArray(e,p,b),m=n.fromArray(e,(p+6)%a,V);if(E){var T=n.fromArray(e,(p+3)%a,X);n.subtract(m,y,m),n.subtract(T,y,T),d=n.normalize(n.cross(T,m,d),d),E=!1}n.equalsEpsilon(m,y,_.EPSILON10)&&(E=!0),(t.tangent||t.bitangent)&&(f=r.geodeticSurfaceNormal(y,f),t.tangent&&(h=n.normalize(n.cross(f,d,h),h))),t.normal&&(i[s++]=d.x,i[s++]=d.y,i[s++]=d.z,i[s++]=d.x,i[s++]=d.y,i[s++]=d.z),t.tangent&&(o[c++]=h.x,o[c++]=h.y,o[c++]=h.z,o[c++]=h.x,o[c++]=h.y,o[c++]=h.z),t.bitangent&&(u[l++]=f.x,u[l++]=f.y,u[l++]=f.z,u[l++]=f.x,u[l++]=f.y,u[l++]=f.z)}return g(t,{positions:e,normals:i,tangents:o,bitangents:u})}function O(e){for(var t=e.vertexFormat,n=e.ellipsoid,r=e.size,a=e.height,o=e.width,u=t.position?new Float64Array(3*r):void 0,s=t.st?new Float32Array(2*r):void 0,c=0,l=0,E=b,h=z,d=Number.MAX_VALUE,p=Number.MAX_VALUE,_=-Number.MAX_VALUE,m=-Number.MAX_VALUE,T=0;T<a;++T)for(var R=0;R<o;++R)S.computePosition(e,T,R,E,h),u[c++]=E.x,u[c++]=E.y,u[c++]=E.z,t.st&&(s[l++]=h.x,s[l++]=h.y,d=Math.min(d,h.x),p=Math.min(p,h.y),_=Math.max(_,h.x),m=Math.max(m,h.y));if(t.st&&(d<0||p<0||_>1||m>1))for(var v=0;v<s.length;v+=2)s[v]=(s[v]-d)/(_-d),s[v+1]=(s[v+1]-p)/(m-p);for(var A=I(u,t,n,e.tangentRotationMatrix),N=6*(o-1)*(a-1),g=y.createTypedArray(r,N),M=0,O=0,x=0;x<a-1;++x){for(var w=0;w<o-1;++w){var C=M,P=C+o,L=P+1,U=C+1;g[O++]=C,g[O++]=P,g[O++]=U,g[O++]=U,g[O++]=P,g[O++]=L,++M}++M}return A.indices=g,t.st&&(A.attributes.st=new f({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:s})),A}function x(e,t,n,r,a){return e[t++]=r[n],e[t++]=r[n+1],e[t++]=r[n+2],e[t++]=a[n],e[t++]=a[n+1],e[t++]=a[n+2],e}function w(e,t,n,r){return e[t++]=r[n],e[t++]=r[n+1],e[t++]=r[n],e[t++]=r[n+1],e}function C(e){var t,r=e.shadowVolume,a=e.vertexFormat,o=e.surfaceHeight,u=e.extrudedHeight,s=Math.min(u,o),c=Math.max(u,o),l=e.height,E=e.width,h=e.ellipsoid;r&&(e.vertexFormat=N.clone(a,W),e.vertexFormat.normal=!0);var m=O(e);if(_.equalsEpsilon(s,c,_.EPSILON10))return m;var R=T.scaleToGeodeticHeight(m.attributes.position.values,c,h,!1);R=new Float64Array(R);var v=R.length,A=2*v,S=new Float64Array(A);S.set(R);var g=T.scaleToGeodeticHeight(m.attributes.position.values,s,h);S.set(g,v),m.attributes.position.values=S;var I,C,P=a.normal?new Float32Array(A):void 0,L=a.tangent?new Float32Array(A):void 0,b=a.bitangent?new Float32Array(A):void 0,U=a.st?new Float32Array(A/3*2):void 0;if(a.normal){for(C=m.attributes.normal.values,P.set(C),t=0;t<v;t++)C[t]=-C[t];P.set(C,v),m.attributes.normal.values=P}if(r){C=m.attributes.normal.values,a.normal||(m.attributes.normal=void 0);var F=new Float32Array(A);for(t=0;t<v;t++)C[t]=-C[t];F.set(C,v),m.attributes.extrudeDirection=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:F})}if(a.tangent){var D=m.attributes.tangent.values;for(L.set(D),t=0;t<v;t++)D[t]=-D[t];L.set(D,v),m.attributes.tangent.values=L}if(a.bitangent){var B=m.attributes.bitangent.values;b.set(B),b.set(B,v),m.attributes.bitangent.values=b}a.st&&(I=m.attributes.st.values,U.set(I),U.set(I,v/3*2),m.attributes.st.values=U);var z=m.indices,G=z.length,q=v/3,H=y.createTypedArray(A/3,2*G);for(H.set(z),t=0;t<G;t+=3)H[t+G]=z[t+2]+q,H[t+1+G]=z[t+1]+q,H[t+2+G]=z[t]+q;m.indices=H;var Y,k=2*E+2*l-4,Z=2*(k+4),K=new Float64Array(3*Z),j=r?new Float32Array(3*Z):void 0,Q=a.st?new Float32Array(2*Z):void 0,J=0,$=0,ee=0,te=E*l;for(t=0;t<te;t+=E)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);for(t=te-E;t<te;t++)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);for(t=te-1;t>0;t-=E)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);for(t=E-1;t>=0;t--)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);var ne=M(K,a,h);a.st&&(ne.attributes.st=new f({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:Q})),r&&(ne.attributes.extrudeDirection=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:j}));var re,ae,ie,oe,ue=y.createTypedArray(Z,6*k);v=K.length/3;var se=0;for(t=0;t<v-1;t+=2){re=t,oe=(re+2)%v;var ce=n.fromArray(K,3*re,V),le=n.fromArray(K,3*oe,X);n.equalsEpsilon(ce,le,_.EPSILON10)||(ae=(re+1)%v,ie=(ae+2)%v,ue[se++]=re,ue[se++]=ae,ue[se++]=oe,ue[se++]=oe,ue[se++]=ae,ue[se++]=ie)}return ne.indices=ue,ne=p.combineInstances([new d({geometry:m}),new d({geometry:ne})]),ne[0]}function P(e,t,n){if(0===n)return A.clone(e);A.northeast(e,K[0]),A.northwest(e,K[1]),A.southeast(e,K[2]),A.southwest(e,K[3]),t.cartographicArrayToCartesianArray(K,Z);var r=t.geodeticSurfaceNormalCartographic(A.center(e,Y));v.fromAxisAngle(r,n,k),m.fromQuaternion(k,H);for(var a=0;a<4;++a)m.multiplyByVector(H,Z[a],Z[a]);return t.cartesianArrayToCartographicArray(Z,K),A.fromCartographicArray(K)}function L(e){e=o(e,o.EMPTY_OBJECT);var t=e.rectangle,n=o(e.rotation,0);this._rectangle=t,this._granularity=o(e.granularity,_.RADIANS_PER_DEGREE),this._ellipsoid=l.clone(o(e.ellipsoid,l.WGS84)),this._surfaceHeight=o(e.height,0),this._rotation=n,this._stRotation=o(e.stRotation,0),this._vertexFormat=N.clone(o(e.vertexFormat,N.DEFAULT)),this._extrudedHeight=o(e.extrudedHeight,0),this._extrude=u(e.extrudedHeight),this._closeTop=o(e.closeTop,!0),this._closeBottom=o(e.closeBottom,!0),this._shadowVolume=o(e.shadowVolume,!1),this._workerName="createRectangleGeometry",this._rotatedRectangle=P(this._rectangle,this._ellipsoid,n)}var b=new n,U=new n,F=new n,D=new n,B=new A,z=new t,G=new e,q=new e,V=new n,X=new n,W=new N,H=new m,Y=new n,k=new v,Z=[new n,new n,new n,new n],K=[new r,new r,new r,new r];L.packedLength=A.packedLength+l.packedLength+N.packedLength+A.packedLength+9,L.pack=function(e,t,n){return n=o(n,0),A.pack(e._rectangle,t,n),n+=A.packedLength,l.pack(e._ellipsoid,t,n),n+=l.packedLength,N.pack(e._vertexFormat,t,n),n+=N.packedLength,A.pack(e._rotatedRectangle,t,n),n+=A.packedLength,t[n++]=e._granularity,t[n++]=e._surfaceHeight,t[n++]=e._rotation,t[n++]=e._stRotation,t[n++]=e._extrudedHeight,t[n++]=e._extrude?1:0,t[n++]=e._closeTop?1:0,t[n++]=e._closeBottom?1:0,t[n]=e._shadowVolume?1:0,t};var j=new A,Q=new A,J=l.clone(l.UNIT_SPHERE),$={rectangle:j,ellipsoid:J,vertexFormat:W,granularity:void 0,height:void 0,rotation:void 0,stRotation:void 0,extrudedHeight:void 0,closeTop:void 0,closeBottom:void 0,shadowVolume:void 0};L.unpack=function(e,t,n){t=o(t,0);var r=A.unpack(e,t,j);t+=A.packedLength;var a=l.unpack(e,t,J);t+=l.packedLength;var i=N.unpack(e,t,W);t+=N.packedLength;var s=A.unpack(e,t,Q);t+=A.packedLength;var c=e[t++],E=e[t++],f=e[t++],h=e[t++],d=e[t++],p=1===e[t++],y=1===e[t++],_=1===e[t++],m=1===e[t];return u(n)?(n._rectangle=A.clone(r,n._rectangle),n._ellipsoid=l.clone(a,n._ellipsoid),n._vertexFormat=N.clone(i,n._vertexFormat),n._granularity=c,n._surfaceHeight=E,n._rotation=f,n._stRotation=h,n._extrudedHeight=p?d:void 0,n._extrude=p,n._closeTop=y,n._closeBottom=_,n._rotatedRectangle=s,n._shadowVolume=m,n):($.granularity=c,$.height=E,$.rotation=f,$.stRotation=h,$.extrudedHeight=p?d:void 0,$.closeTop=y,$.closeBottom=_,$.shadowVolume=m,new L($))};var ee=new m,te=new r,ne=new r,re=new v,ae=new r;return L.createGeometry=function(t){if(!_.equalsEpsilon(t._rectangle.north,t._rectangle.south,_.EPSILON10)&&!_.equalsEpsilon(t._rectangle.east,t._rectangle.west,_.EPSILON10)){var n=A.clone(t._rectangle,B),r=t._ellipsoid,a=t._surfaceHeight,i=t._extrude,o=t._extrudedHeight,u=t._rotation,s=t._stRotation,c=t._vertexFormat,l=S.computeOptions(t,n,te,ne),f=ee;if(0!==s||0!==u){var h=A.center(n,ae),d=r.geodeticSurfaceNormalCartographic(h,V);v.fromAxisAngle(d,-s,re),m.fromQuaternion(re,f)}else m.clone(m.IDENTITY,f);l.lonScalar=1/t._rectangle.width,l.latScalar=1/t._rectangle.height,l.vertexFormat=c,l.rotation=u,l.stRotation=s,l.tangentRotationMatrix=f,l.size=l.width*l.height;var p,y;if(n=t._rectangle,i){l.shadowVolume=t._shadowVolume,p=C(l);var R=e.fromRectangle3D(n,r,a,q),N=e.fromRectangle3D(n,r,o,G);y=e.union(R,N)}else p=O(l),p.attributes.position.values=T.scaleToGeodeticHeight(p.attributes.position.values,a,r,!1),y=e.fromRectangle3D(n,r,a);return c.position||delete p.attributes.position,new E({attributes:p.attributes,indices:p.indices,primitiveType:p.primitiveType,boundingSphere:y})}},L.createShadowVolume=function(e,t,n){var r=e._granularity,a=e._ellipsoid,i=t(r,a),o=n(r,a);return new L({rectangle:e._rectangle,rotation:e._rotation,ellipsoid:a,stRotation:e._stRotation,granularity:r,extrudedHeight:o,height:i,closeTop:!0,closeBottom:!0,vertexFormat:N.POSITION_ONLY,shadowVolume:!0})},s(L.prototype,{rectangle:{get:function(){return this._rotatedRectangle}}}),L}),define("Workers/createRectangleGeometry",["../Core/defined","../Core/Ellipsoid","../Core/Rectangle","../Core/RectangleGeometry"],function(e,t,n,r){"use strict";function a(a,i){return e(i)&&(a=r.unpack(a,i)),a._ellipsoid=t.clone(a._ellipsoid),a._rectangle=n.clone(a._rectangle),r.createGeometry(a)}return a})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var E=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,E=r*u-a*o;return n.x=c,n.y=l,n.z=E,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var f=new o,h=new o,d=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:d,c=Math.cos(r);f.x=c*Math.cos(e),f.y=c*Math.sin(e),f.z=Math.sin(r),f=o.normalize(f,f),o.multiplyComponents(s,f,h);var l=Math.sqrt(o.dot(f,h));return h=o.divideByScalar(h,l,h),f=o.multiplyByScalar(f,a,f),n(u)||(u=new o),o.add(h,f,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,E=n.y,f=n.z,h=a.x,d=a.y,p=a.z,y=l*l*h*h,_=E*E*d*d,m=f*f*p*p,T=y+_+m,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,N=u.z,g=o;g.x=v.x*A*2,g.y=v.y*S*2,g.z=v.z*N*2;var I,M,O,x,w,C,P,L,b,U,F,D=(1-R)*e.magnitude(n)/(.5*e.magnitude(g)),B=0;do{D-=B,O=1/(1+D*A),x=1/(1+D*S),w=1/(1+D*N),C=O*O,P=x*x,L=w*w,b=C*O,U=P*x,F=L*w,I=y*C+_*P+m*L-1,M=y*b*A+_*U*S+m*F*N;B=I/(-2*M)}while(Math.abs(I)>r.EPSILON12);return t(c)?(c.x=l*O,c.y=E*x,c.z=f*w,c):new e(l*O,E*x,f*w)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,E=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,n,a){var d=r(n)?n.oneOverRadii:E,p=r(n)?n.oneOverRadiiSquared:f,y=r(n)?n._centerToleranceSquared:h,_=o(t,d,p,y,c);if(r(_)){var m=e.multiplyComponents(_,p,s);m=e.normalize(m,m);var T=e.subtract(t,_,l),R=Math.atan2(m.y,m.x),v=Math.asin(m.z),A=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=v,a.height=A,a):new u(R,v,A)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function E(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(E.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),E.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new E(r.x,r.y,r.z)}},E.fromCartesian3=function(e,t){return a(t)||(t=new E),a(e)?(l(t,e.x,e.y,e.z),t):t},E.WGS84=u(new E(6378137,6378137,6356752.314245179)),E.UNIT_SPHERE=u(new E(1,1,1)),E.MOON=u(new E(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),E.prototype.clone=function(e){return E.clone(this,e)},E.packedLength=e.packedLength,E.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},E.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return E.fromCartesian3(i,a)},E.prototype.geocentricSurfaceNormal=e.normalize,E.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},E.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var f=new e,h=new e;E.prototype.cartographicToCartesian=function(t,n){var r=f,i=h;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},E.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var d=new e,p=new e,y=new e;return E.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,p);if(a(i)){var o=this.geodeticSurfaceNormal(i,d),u=e.subtract(n,i,y),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),E=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=E,r):new t(c,l,E)}},E.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},E.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},E.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},E.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},E.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},E.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},E.prototype.toString=function(){return this._radii.toString()},E.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},E}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,E=0,f=e.length;E<f;E++){var h=e[E];n=Math.min(n,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,d),o=Math.max(o,d)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,E=-Number.MAX_VALUE,f=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0,p=e.length;d<p;d++){var y=t.cartesianToCartographic(e[d]);o=Math.min(o,y.longitude),c=Math.max(c,y.longitude),f=Math.min(f,y.latitude),h=Math.max(h,y.latitude);var _=y.longitude>=0?y.longitude:y.longitude+u.TWO_PI;l=Math.min(l,_),E=Math.max(E,_)}return c-o>E-l&&(o=l,c=E,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=f,a.east=c,a.north=h,a):new s(o,f,c,h)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),E=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&E<=l)){var f=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(f>=h))return r(n)?(n.west=l,n.south=f,n.east=E,n.north=h,n):new s(l,f,E,h)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),E=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=E,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,E=e.north,f=e.south,h=e.east,d=e.west,p=c;p.height=a,p.longitude=d,p.latitude=E,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=f,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.latitude=E<0?E:f>0?f:0;for(var y=1;y<8;++y)p.longitude=-Math.PI+y*u.PI_OVER_TWO,s.contains(e,p)&&(o[l]=t.cartographicToCartesian(p,o[l]),l++);return 0===p.latitude&&(p.longitude=d,o[l]=t.cartographicToCartesian(p,o[l]),l++,p.longitude=h,o[l]=t.cartographicToCartesian(p,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(p[n],d[n])];t+=2*r*r}return Math.sqrt(t)}function E(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(p[i],d[i])]);o>r&&(a=i,r=o)}var c=1,l=0,E=d[a],f=p[a];if(Math.abs(e[s.getElementIndex(f,E)])>n){var h,y=e[s.getElementIndex(f,f)],_=e[s.getElementIndex(E,E)],m=e[s.getElementIndex(f,E)],T=(y-_)/2/m;h=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(E,E)]=t[s.getElementIndex(f,f)]=c,t[s.getElementIndex(f,E)]=l,t[s.getElementIndex(E,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,E=e.z*e.z,f=e.z*e.w,h=e.w*e.w,d=n-u-E+h,p=2*(a-f),y=2*(i+l),_=2*(a+f),m=-n+u-E+h,T=2*(c-o),R=2*(i-l),v=2*(c+o),A=-n-u+E+h;return r(t)?(t[0]=d,t[1]=_,t[2]=R,t[3]=p,t[4]=m,t[5]=v,t[6]=y,t[7]=T,t[8]=A,t):new s(d,p,y,_,m,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,E=-i*u+c*o*a,f=c*u+i*o*a,h=n*u,d=i*a+c*o*u,p=-c*a+i*o*u,y=-o,_=c*n,m=i*n;return r(t)?(t[0]=l,t[1]=h,t[2]=y,t[3]=E,t[4]=d,t[5]=_,t[6]=f,t[7]=p,t[8]=m,t):new s(l,E,f,h,d,p,y,_,m)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var f=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),n};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],E=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=E,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var d=[1,0,0],p=[2,2,1],y=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),h=n*c(f);i<10&&l(f)>h;)E(f,y),s.transpose(y,_),s.multiply(f,y,f),s.multiply(_,f,f),s.multiply(o,y,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t}, +s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],E=e[8],f=s.determinant(e);t[0]=o*E-l*u,t[1]=l*a-r*E,t[2]=r*u-o*a,t[3]=c*u-i*E,t[4]=n*E-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var h=1/f;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,E,f,h,d,p,y){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(h,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(d,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(E,0),this[11]=r(p,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(f,0),this[15]=r(y,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,E=t.x*t.z,f=t.x*t.w,h=t.y*t.y,d=t.y*t.z,p=t.y*t.w,y=t.z*t.z,_=t.z*t.w,m=t.w*t.w,T=s-h-y+m,R=2*(c-_),v=2*(E+p),A=2*(c+_),S=-s+h-y+m,N=2*(d-f),g=2*(E-p),I=2*(d+f),M=-s-h+y+m;return r[0]=T*i,r[1]=A*i,r[2]=g*i,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=I*o,r[7]=0,r[8]=v*u,r[9]=N*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var E=new e,f=new e,h=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,E),e.normalize(e.cross(E,o,f),f),e.normalize(e.cross(f,E,h),h);var u=f.x,s=f.y,c=f.z,d=E.x,p=E.y,y=E.z,_=h.x,m=h.y,T=h.z,R=r.x,v=r.y,A=r.z,S=u*-R+s*-v+c*-A,N=_*-R+m*-v+T*-A,g=d*R+p*v+y*A;return a(n)?(n[0]=u,n[1]=_,n[2]=-d,n[3]=0,n[4]=s,n[5]=m,n[6]=-p,n[7]=0,n[8]=c,n[9]=T,n[10]=-y,n[11]=0,n[12]=S,n[13]=N,n[14]=g,n[15]=1,n):new l(u,s,c,S,_,m,T,N,-d,-p,-y,g,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,E=-(r+n)*s,f=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=E,o[14]=f,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),E=-(i+a)/(i-a),f=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=E,o[11]=-1,o[12]=0,o[13]=0,o[14]=f,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,E=.5*(n-t),f=c,h=l,d=E,p=i+c,y=o+l,_=t+E;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=d,a[11]=0,a[12]=p,a[13]=y,a[14]=_,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var d=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],d)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],d)),n};var p=new e;l.getMaximumScale=function(t){return l.getScale(t,p),e.maximumComponent(p)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],E=e[8],f=e[9],h=e[10],d=e[11],p=e[12],y=e[13],_=e[14],m=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],N=t[5],g=t[6],I=t[7],M=t[8],O=t[9],x=t[10],w=t[11],C=t[12],P=t[13],L=t[14],b=t[15],U=r*T+u*R+E*v+p*A,F=a*T+s*R+f*v+y*A,D=i*T+c*R+h*v+_*A,B=o*T+l*R+d*v+m*A,z=r*S+u*N+E*g+p*I,G=a*S+s*N+f*g+y*I,q=i*S+c*N+h*g+_*I,V=o*S+l*N+d*g+m*I,X=r*M+u*O+E*x+p*w,W=a*M+s*O+f*x+y*w,H=i*M+c*O+h*x+_*w,Y=o*M+l*O+d*x+m*w,k=r*C+u*P+E*L+p*b,Z=a*C+s*P+f*L+y*b,K=i*C+c*P+h*L+_*b,j=o*C+l*P+d*L+m*b;return n[0]=U,n[1]=F,n[2]=D,n[3]=B,n[4]=z,n[5]=G,n[6]=q,n[7]=V,n[8]=X,n[9]=W,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=K,n[15]=j,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=e[12],h=e[13],d=e[14],p=t[0],y=t[1],_=t[2],m=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],N=t[12],g=t[13],I=t[14],M=r*p+o*y+c*_,O=a*p+u*y+l*_,x=i*p+s*y+E*_,w=r*m+o*T+c*R,C=a*m+u*T+l*R,P=i*m+s*T+E*R,L=r*v+o*A+c*S,b=a*v+u*A+l*S,U=i*v+s*A+E*S,F=r*N+o*g+c*I+f,D=a*N+u*g+l*I+h,B=i*N+s*g+E*I+d;return n[0]=M,n[1]=O,n[2]=x,n[3]=0,n[4]=w,n[5]=C,n[6]=P,n[7]=0,n[8]=L,n[9]=b,n[10]=U,n[11]=0,n[12]=F,n[13]=D,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],E=e[10],f=t[0],h=t[1],d=t[2],p=t[3],y=t[4],_=t[5],m=t[6],T=t[7],R=t[8],v=r*f+o*h+c*d,A=a*f+u*h+l*d,S=i*f+s*h+E*d,N=r*p+o*y+c*_,g=a*p+u*y+l*_,I=i*p+s*y+E*_,M=r*m+o*T+c*R,O=a*m+u*T+l*R,x=i*m+s*T+E*R;return n[0]=v,n[1]=A,n[2]=S,n[3]=0,n[4]=N,n[5]=g,n[6]=I,n[7]=0,n[8]=M,n[9]=O,n[10]=x,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var y=new e;l.multiplyByUniformScale=function(e,t,n){return y.x=t,y.y=t,y.z=t,l.multiplyByScale(e,y,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,m=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),m,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],E=e[1],f=e[5],h=e[9],d=e[13],p=e[2],y=e[6],v=e[10],A=e[14],S=e[3],N=e[7],g=e[11],I=e[15],M=v*I,O=A*g,x=y*I,w=A*N,C=y*g,P=v*N,L=p*I,b=A*S,U=p*g,F=v*S,D=p*N,B=y*S,z=M*f+w*h+C*d-(O*f+x*h+P*d),G=O*E+L*h+F*d-(M*E+b*h+U*d),q=x*E+b*f+D*d-(w*E+L*f+B*d),V=P*E+U*f+B*h-(C*E+F*f+D*h),X=O*a+x*i+P*o-(M*a+w*i+C*o),W=M*r+b*i+U*o-(O*r+L*i+F*o),H=w*r+L*a+B*o-(x*r+b*a+D*o),Y=C*r+F*a+D*i-(P*r+U*a+B*i);M=i*d,O=o*h,x=a*d,w=o*f,C=a*h,P=i*f,L=r*d,b=o*E,U=r*h,F=i*E,D=r*f,B=a*E;var k=M*N+w*g+C*I-(O*N+x*g+P*I),Z=O*S+L*g+F*I-(M*S+b*g+U*I),K=x*S+b*N+D*I-(w*S+L*N+B*I),j=P*S+U*N+B*g-(C*S+F*N+D*g),Q=x*v+P*A+O*y-(C*A+M*y+w*v),J=U*A+M*p+b*v-(L*v+F*A+O*p),$=L*y+B*A+w*p-(D*A+x*p+b*y),ee=D*v+C*p+F*y-(U*y+B*v+P*p),te=r*z+a*G+i*q+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=G*te,n[2]=q*te,n[3]=V*te,n[4]=X*te,n[5]=W*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=K*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],E=e[12],f=e[13],h=e[14],d=-n*E-r*f-a*h,p=-i*E-o*f-u*h,y=-s*E-c*f-l*h;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=d,t[13]=p,t[14]=y,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,E,f){"use strict";function h(t,n){this.center=e.clone(a(t,e.ZERO)),this.radius=a(n,0)}var d=new e,p=new e,y=new e,_=new e,m=new e,T=new e,R=new e,v=new e,A=new e,S=new e,N=new e,g=new e,I=4/3*n.PI;h.fromPoints=function(t,n){if(i(n)||(n=new h),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],R),o=e.clone(a,d),u=e.clone(a,p),s=e.clone(a,y),c=e.clone(a,_),l=e.clone(a,m),E=e.clone(a,T),f=t.length;for(r=1;r<f;r++){e.clone(t[r],a);var I=a.x,M=a.y,O=a.z;I<o.x&&e.clone(a,o),I>c.x&&e.clone(a,c),M<u.y&&e.clone(a,u),M>l.y&&e.clone(a,l),O<s.z&&e.clone(a,s),O>E.z&&e.clone(a,E)}var x=e.magnitudeSquared(e.subtract(c,o,v)),w=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(E,s,v)),P=o,L=c,b=x;w>b&&(b=w,P=u,L=l),C>b&&(b=C,P=s,L=E);var U=A;U.x=.5*(P.x+L.x),U.y=.5*(P.y+L.y),U.z=.5*(P.z+L.z);var F=e.magnitudeSquared(e.subtract(L,U,v)),D=Math.sqrt(F),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=E.z;var G=e.multiplyByScalar(e.add(B,z,v),.5,g),q=0;for(r=0;r<f;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,G,v));V>q&&(q=V);var X=e.magnitudeSquared(e.subtract(a,U,v));if(X>F){var W=Math.sqrt(X);D=.5*(D+W),F=D*D;var H=W-D;U.x=(D*U.x+H*a.x)/W,U.y=(D*U.y+H*a.y)/W,U.z=(D*U.z+H*a.z)/W}}return D<q?(e.clone(U,n.center),n.radius=D):(e.clone(G,n.center),n.radius=q),n};var M=new u,O=new e,x=new e,w=new t,C=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,r,o,u){if(i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=a(n,M),f.southwest(t,w),w.height=r,f.northeast(t,C),C.height=o;var s=n.project(w,O),c=n.project(C,x),l=c.x-s.x,E=c.y-s.y,d=c.z-s.z;u.radius=.5*Math.sqrt(l*l+E*E+d*d);var p=u.center;return p.x=s.x+.5*l,p.y=s.y+.5*E,p.z=s.z+.5*d,u};var P=[];h.fromRectangle3D=function(t,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,r,P);return h.fromPoints(s,u)},h.fromVertices=function(t,n,r,o){if(i(o)||(o=new h),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=a(n,e.ZERO),r=a(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,p),E=e.clone(u,y),f=e.clone(u,_),I=e.clone(u,m),M=e.clone(u,T),O=t.length;for(s=0;s<O;s+=r){var x=t[s]+n.x,w=t[s+1]+n.y,C=t[s+2]+n.z;u.x=x,u.y=w,u.z=C,x<c.x&&e.clone(u,c),x>f.x&&e.clone(u,f),w<l.y&&e.clone(u,l),w>I.y&&e.clone(u,I),C<E.z&&e.clone(u,E),C>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(f,c,v)),L=e.magnitudeSquared(e.subtract(I,l,v)),b=e.magnitudeSquared(e.subtract(M,E,v)),U=c,F=f,D=P;L>D&&(D=L,U=l,F=I),b>D&&(D=b,U=E,F=M);var B=A;B.x=.5*(U.x+F.x),B.y=.5*(U.y+F.y),B.z=.5*(U.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,v)),G=Math.sqrt(z),q=S;q.x=c.x,q.y=l.y,q.z=E.z;var V=N;V.x=f.x,V.y=I.y,V.z=M.z;var X=e.multiplyByScalar(e.add(q,V,v),.5,g),W=0;for(s=0;s<O;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,v));H>W&&(W=H);var Y=e.magnitudeSquared(e.subtract(u,B,v));if(Y>z){var k=Math.sqrt(Y);G=.5*(G+k),z=G*G;var Z=k-G;B.x=(G*B.x+Z*u.x)/k,B.y=(G*B.y+Z*u.y)/k,B.z=(G*B.z+Z*u.z)/k}}return G<W?(e.clone(B,o.center),o.radius=G):(e.clone(X,o.center),o.radius=W),o},h.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new h),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=R;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,d),s=e.clone(a,p),c=e.clone(a,y),l=e.clone(a,_),E=e.clone(a,m),f=e.clone(a,T),I=t.length;for(o=0;o<I;o+=3){var M=t[o]+n[o],O=t[o+1]+n[o+1],x=t[o+2]+n[o+2];a.x=M,a.y=O,a.z=x,M<u.x&&e.clone(a,u),M>l.x&&e.clone(a,l),O<s.y&&e.clone(a,s),O>E.y&&e.clone(a,E),x<c.z&&e.clone(a,c),x>f.z&&e.clone(a,f)}var w=e.magnitudeSquared(e.subtract(l,u,v)),C=e.magnitudeSquared(e.subtract(E,s,v)),P=e.magnitudeSquared(e.subtract(f,c,v)),L=u,b=l,U=w;C>U&&(U=C,L=s,b=E),P>U&&(U=P,L=c,b=f);var F=A;F.x=.5*(L.x+b.x),F.y=.5*(L.y+b.y),F.z=.5*(L.z+b.z);var D=e.magnitudeSquared(e.subtract(b,F,v)),B=Math.sqrt(D),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var G=N;G.x=l.x,G.y=E.y,G.z=f.z;var q=e.multiplyByScalar(e.add(z,G,v),.5,g),V=0;for(o=0;o<I;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(a,q,v));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(a,F,v));if(W>D){var H=Math.sqrt(W);B=.5*(B+H),D=B*B;var Y=H-B;F.x=(B*F.x+Y*a.x)/H,F.y=(B*F.y+Y*a.y)/H,F.z=(B*F.z+Y*a.z)/H}}return B<V?(e.clone(F,r.center),r.radius=B):(e.clone(q,r.center),r.radius=V),r},h.fromCornerPoints=function(t,n,r){i(r)||(r=new h);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},h.fromEllipsoid=function(t,n){return i(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var L=new e;h.fromBoundingSpheres=function(t,n){if(i(n)||(n=new h),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,L)+c.radius)}return n.radius=s,n};var b=new e,U=new e,F=new e;h.fromOrientedBoundingBox=function(t,n){i(n)||(n=new h);var r=t.halfAxes,a=l.getColumn(r,0,b),o=l.getColumn(r,1,U),u=l.getColumn(r,2,F);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},h.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=a(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=a(t,0),i(n)||(n=new h);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var D=new e,B=new e;h.union=function(t,n,r){i(r)||(r=new h);var a=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,a,D),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var E=.5*(o+l+s),f=e.multiplyByScalar(c,(-o+E)/l,B);return e.add(f,a,f),e.clone(f,r.center),r.radius=E,r};var z=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,z));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?s.OUTSIDE:o<a?s.INTERSECTING:s.INSIDE},h.transform=function(e,t,n){return i(n)||(n=new h),n.center=E.multiplyByPoint(t,e.center,n.center),n.radius=E.getMaximumScale(t)*e.radius,n};var G=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,G);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return i(n)||(n=new h),n.center=E.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var q=new e;h.computePlaneDistances=function(t,n,r,a){i(a)||(a=new c);var o=e.subtract(t.center,n,q),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var V=new e,X=new e,W=new e,H=new e,Y=new e,k=new t,Z=new Array(8),K=0;K<8;++K)Z[K]=new e;var j=new u;return h.projectTo2D=function(t,n,r){n=a(n,j);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var E=e.negate(l,Y),f=e.negate(c,H),d=Z,p=d[0];e.add(s,l,p),e.add(p,c,p),p=d[1],e.add(s,l,p),e.add(p,f,p),p=d[2],e.add(s,E,p),e.add(p,f,p),p=d[3],e.add(s,E,p),e.add(p,c,p),e.negate(s,s),p=d[4],e.add(s,l,p),e.add(p,c,p),p=d[5],e.add(s,l,p),e.add(p,f,p),p=d[6],e.add(s,E,p),e.add(p,f,p),p=d[7],e.add(s,E,p),e.add(p,c,p);for(var y=d.length,_=0;_<y;++_){var m=d[_];e.add(o,m,m);var T=i.cartesianToCartographic(m,k);n.project(T,m)}r=h.fromPoints(d,r),o=r.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,r},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h.prototype.volume=function(){var e=this.radius;return I*e*e*e},h}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var E=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)), +o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(v)&&(v=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function i(){return a()&&A}function o(){if(!t(S)&&(S=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,N=r(e[1]))}return S}function u(){return o()&&N}function s(){if(!t(g)){g=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(g=!0,I=r(e[1]),I.isNightly=!!e[2])}return g}function c(){return s()&&I}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,O=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,O=r(e[1]))}return M}function E(){return l()&&O}function f(){if(!t(x)){x=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,w=r(e[1]))}return x}function h(){return f()&&w}function d(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function p(){return t(L)||(L=/Windows/i.test(R.appVersion)),L}function y(){return d()&&P}function _(){return t(b)||(b="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),b}function m(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(U=n)}return F}function T(){return m()?U:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,N,g,I,M,O,x,w,C,P,L,b,U,F,D={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:E,isEdge:f,edgeVersion:h,isFirefox:d,firefoxVersion:y,isWindows:p,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:m,imageRenderingValue:T};return D.supportsFullscreen=function(){return n.supportsFullscreen()},D.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},D.supportsWebWorkers=function(){return"undefined"!=typeof Worker},D}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/GeometryInstance",["./defaultValue","./defined","./DeveloperError","./Matrix4"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.geometry=t.geometry,this.modelMatrix=r.clone(e(t.modelMatrix,r.IDENTITY)),this.id=t.id,this.pickPrimitive=t.pickPrimitive,this.attributes=e(t.attributes,{}),this.westHemisphereGeometry=void 0,this.eastHemisphereGeometry=void 0}return a}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,n,r,a,i){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,a=n.y;n.x=(1-Math.abs(a))*i.signNotZero(r),n.y=(1-Math.abs(r))*i.signNotZero(a)}return n.x=i.toSNorm(n.x,t),n.y=i.toSNorm(n.y,t),n},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,n,r,a){if(a.x=i.fromSNorm(e,r),a.y=i.fromSNorm(n,r),a.z=1-(Math.abs(a.x)+Math.abs(a.y)),a.z<0){var o=a.x;a.x=(1-Math.abs(a.y))*i.signNotZero(o),a.y=(1-Math.abs(o))*i.signNotZero(a.y)}return t.normalize(a,a)},u.octDecode=function(e,t,n){return u.octDecodeInRange(e,t,255,n)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return u.octDecode(r,a,t)},u.octPack=function(e,t,n,r){var a=u.octEncodeFloat(e),i=u.octEncodeFloat(t),o=u.octEncode(n,s);return r.x=65536*o.x+a,r.y=65536*o.y+i,r},u.octUnpack=function(e,t,n,r){var a=e.x/65536,i=Math.floor(a),o=65536*(a-i);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,n),u.octDecode(i,s,r)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},u.zigZagDeltaDecode=function(e,t,n){for(var a=e.length,i=0,u=0,s=0,c=0;c<a;++c)i+=o(e[c]),u+=o(t[c]),e[c]=i,t[c]=u,r(n)&&(s+=o(n[c]),n[c]=s)},u}),define("Core/barycentricCoordinates",["./Cartesian2","./Cartesian3","./Check","./defined"],function(e,t,n,r){"use strict";function a(n,a,s,c,l){r(l)||(l=new t);var E,f,h,d,p,y,_,m;r(a.z)?(E=t.subtract(s,a,i),f=t.subtract(c,a,o),h=t.subtract(n,a,u),d=t.dot(E,E),p=t.dot(E,f),y=t.dot(E,h),_=t.dot(f,f),m=t.dot(f,h)):(E=e.subtract(s,a,i),f=e.subtract(c,a,o),h=e.subtract(n,a,u),d=e.dot(E,E),p=e.dot(E,f),y=e.dot(E,h),_=e.dot(f,f),m=e.dot(f,h));var T=1/(d*_-p*p);return l.y=(_*y-p*m)*T,l.z=(d*m-p*y)*T,l.x=1-l.y-l.z,l}var i=new t,o=new t,u=new t;return a}),define("Core/EncodedCartesian3",["./Cartesian3","./Check","./defined"],function(e,t,n){"use strict";function r(){this.high=e.clone(e.ZERO),this.low=e.clone(e.ZERO)}r.encode=function(e,t){n(t)||(t={high:0,low:0});var r;return e>=0?(r=65536*Math.floor(e/65536),t.high=r,t.low=e-r):(r=65536*Math.floor(-e/65536),t.high=-r,t.low=e+r),t};var a={high:0,low:0};r.fromCartesian=function(e,t){n(t)||(t=new r);var i=t.high,o=t.low;return r.encode(e.x,a),i.x=a.high,o.x=a.low,r.encode(e.y,a),i.y=a.high,o.y=a.low,r.encode(e.z,a),i.z=a.high,o.z=a.low,t};var i=new r;return r.writeElements=function(e,t,n){r.fromCartesian(e,i);var a=i.high,o=i.low;t[n]=a.x,t[n+1]=a.y,t[n+2]=a.z,t[n+3]=o.x,t[n+4]=o.y,t[n+5]=o.z},r}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,E=n(c,-l,t.EPSILON14);if(E<0)return[];var f=-.5*n(r,t.sign(r)*Math.sqrt(E),t.EPSILON14);return r>0?[f/e,a/f]:[a/f,f/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,E=u*c,f=u*u,h=s*s,d=o*s-f,p=o*c-u*s,y=u*c-h,_=4*d*y-p*p;if(_<0){var m,T,R;f*E>=l*h?(m=o,T=d,R=-2*u*d+o*p):(m=c,T=y,R=-c*p+2*s*y);var v=R<0?-1:1,A=-v*Math.abs(m)*Math.sqrt(-_);i=-R+A;var S=i/2,N=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),g=i===A?-N:-T/N;return a=T<=0?N+g:-R/(N*N+g*g+T),f*E>=l*h?[(a-u)/o]:[-c/(a+s)]}var I=d,M=-2*u*d+o*p,O=y,x=-c*p+2*s*y,w=Math.sqrt(_),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*w,-M)/3);a=2*Math.sqrt(-I);var L=Math.cos(P);i=a*L;var b=a*(-L/2-C*Math.sin(P)),U=i+b>2*u?i-u:b-u,F=o,D=U/F;P=Math.abs(Math.atan2(c*w,-x)/3),a=2*Math.sqrt(-O),L=Math.cos(P),i=a*L,b=a*(-L/2-C*Math.sin(P));var B=-c,z=i+b<2*s?i+s:b+s,G=B/z,q=F*z,V=-U*z-F*B,X=U*B,W=(s*V-u*X)/(-u*V+s*q);return D<=W?D<=G?W<=G?[D,W,G]:[D,G,W]:[G,D,W]:D<=G?[W,D,G]:W<=G?[W,G,D]:[G,W,D]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,E=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(E.length>0){var f=-t/4,h=E[E.length-1];if(Math.abs(h)<n.EPSILON14){var d=r.computeRealRoots(1,s,l);if(2===d.length){var p,y=d[0],_=d[1];if(y>=0&&_>=0){var m=Math.sqrt(y),T=Math.sqrt(_);return[f-T,f-m,f+m,f+T]}if(y>=0&&_<0)return p=Math.sqrt(y),[f-p,f+p];if(y<0&&_>=0)return p=Math.sqrt(_),[f-p,f+p]}return[]}if(h>0){var R=Math.sqrt(h),v=(s+h-c/R)/2,A=(s+h+c/R)/2,S=r.computeRealRoots(1,R,v),N=r.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=f,S[1]+=f,0!==N.length?(N[0]+=f,N[1]+=f,S[1]<=N[0]?[S[0],S[1],N[0],N[1]]:N[1]<=S[0]?[N[0],N[1],S[0],S[1]]:S[0]>=N[0]&&S[1]<=N[1]?[N[0],S[0],S[1],N[1]]:N[0]>=S[0]&&N[1]<=S[1]?[S[0],N[0],N[1],S[1]]:S[0]>N[0]&&S[0]<N[1]?[N[0],S[0],N[1],S[1]]:[S[0],N[0],S[1],N[1]]):S):0!==N.length?(N[0]+=f,N[1]+=f,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,E=i*t+s-4*o,f=c*o-i*a*t+u,h=e.computeRealRoots(1,l,E,f);if(h.length>0){var d,p,y=h[0],_=a-y,m=_*_,T=t/2,R=_/2,v=m-4*o,A=m+4*Math.abs(o),S=c-4*y,N=c+4*Math.abs(y);if(y<0||v*N<S*A){var g=Math.sqrt(S);d=g/2,p=0===g?0:(t*R-i)/g}else{var I=Math.sqrt(v);d=0===I?0:(t*R-i)/I,p=I/2}var M,O;0===T&&0===d?(M=0,O=0):n.sign(T)===n.sign(d)?(M=T+d,O=y/M):(O=T-d,M=y/O);var x,w;0===R&&0===p?(x=0,w=0):n.sign(R)===n.sign(p)?(x=R+p,w=o/x):(w=R-p,x=o/w);var C=r.computeRealRoots(1,M,x),P=r.computeRealRoots(1,O,w);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,E=r*r,f=E*r,h=a*a;return u*c*E-4*s*f-4*e*l*E+18*e*t*n*f-27*i*E*E+256*o*(h*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*E+144*i*n*E)+h*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,E=u/t,f=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=E<0?h+1:h,h+=f<0?h+1:h){case 0:return a(c,l,E,f);case 1:case 2:return i(c,l,E,f);case 3:case 4:return a(c,l,E,f);case 5:return i(c,l,E,f);case 6:case 7:return a(c,l,E,f);case 8:return i(c,l,E,f);case 9:case 10:return a(c,l,E,f);case 11:return i(c,l,E,f);case 12:case 13:case 14:case 15:return a(c,l,E,f);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){ +"use strict";function E(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function f(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,m),f=e.dot(u,u),h=2*e.dot(u,l),d=e.magnitudeSquared(l)-c,p=E(f,h,d,A);if(r(p))return a.start=p.root0,a.stop=p.root1,a}function h(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function d(t,n,r,a,i){var l,E=a*a,f=i*i,d=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,p=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),y=t[u.COLUMN0ROW0]*E+t[u.COLUMN2ROW2]*f+a*n.x+r,_=f*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),m=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===m&&0===_){if(l=s.computeRealRoots(d,p,y),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-v)),T.push(new e(a,i*R,i*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(a,i*A,i*-S)),T.push(new e(a,i*A,i*S))}return T}var N=m*m,g=_*_,I=d*d,M=m*_,O=I+g,x=2*(p*d+M),w=2*y*d+p*p-g+N,C=2*(y*p-M),P=y*y-N;if(0===O&&0===x&&0===w&&0===C)return T;l=c.computeRealRoots(O,x,w,C,P);var L=l.length;if(0===L)return T;for(var b=0;b<L;++b){var U,F=l[b],D=F*F,B=Math.max(1-D,0),z=Math.sqrt(B);U=o.sign(d)===o.sign(y)?h(d*D+y,p*F,o.EPSILON12):o.sign(y)===o.sign(p*F)?h(d*D,p*F+y,o.EPSILON12):h(d*D+p*F,y,o.EPSILON12);var G=h(_*F,m,o.EPSILON15),q=U*G;q<0?T.push(new e(a,i*F,i*z)):q>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++b):T.push(new e(a,i*F,i*z))}return T}var p={};p.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var y=new e,_=new e,m=new e,T=new e,R=new e;p.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,E,f,h=t.origin,d=t.direction,p=e.subtract(a,r,y),v=e.subtract(i,r,_),A=e.cross(d,v,m),S=e.dot(p,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(h,r,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,p,R),(E=e.dot(d,c))<0||l+E>S)return;f=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var N=1/S;if(s=e.subtract(h,r,T),(l=e.dot(s,A)*N)<0||l>1)return;if(c=e.cross(s,p,R),(E=e.dot(d,c)*N)<0||l+E>1)return;f=e.dot(v,c)*N}return f},p.rayTriangle=function(t,n,a,i,o,u){var s=p.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;p.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=p.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};p.raySphere=function(e,t,n){if(n=f(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;p.lineSegmentSphere=function(t,n,a,i){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=f(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,g=new e;p.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),E=e.multiplyComponents(c,t.direction,g),f=e.magnitudeSquared(l),h=e.dot(l,E);if(f>1){if(h>=0)return;var d=h*h;if(r=f-1,a=e.magnitudeSquared(E),o=a*r,d<o)return;if(d>o){u=h*h-o,s=-h+Math.sqrt(u);var p=s/a,y=r/s;return p<y?new i(p,y):{start:y,stop:p}}var _=Math.sqrt(r/a);return new i(_,_)}return f<1?(r=f-1,a=e.magnitudeSquared(E),o=a*r,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(E),new i(0,-h/a)):void 0};var I=new e,M=new e,O=new e,x=new e,w=new e,C=new u,P=new u,L=new u,b=new u,U=new u,F=new u,D=new u,B=new e,z=new e,G=new t;p.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,I);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,I),E=e.normalize(l,l),f=e.mostOrthogonalAxis(l,x),h=e.normalize(e.cross(f,E,M),M),p=e.normalize(e.cross(E,h,O),O),y=C;y[0]=E.x,y[1]=E.y,y[2]=E.z,y[3]=h.x,y[4]=h.y,y[5]=h.z,y[6]=p.x,y[7]=p.y,y[8]=p.z;var _=u.transpose(y,P),m=u.fromScale(n.radii,L),T=u.fromScale(n.oneOverRadii,b),R=U;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var v,A,S=u.multiply(u.multiply(_,T,F),R,F),N=u.multiply(u.multiply(S,m,D),y,D),g=u.multiplyByVector(S,a,w),q=d(N,e.negate(g,I),0,0,1),V=q.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){v=u.multiplyByVector(m,u.multiplyByVector(y,q[H],B),B);var Y=e.normalize(e.subtract(v,a,x),x),k=e.dot(Y,i);k>W&&(W=k,X=e.clone(v,X))}var Z=n.cartesianToCartographic(X,G);return W=o.clamp(W,0,1),A=e.magnitude(e.subtract(X,a,x))*Math.sqrt(1-W*W),A=c?-A:A,Z.height=A,n.cartographicToCartesian(Z,new e)}};var q=new e;return p.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,q),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),E=-(a.distance+l)/c;if(!(E<0||E>1))return e.multiplyByScalar(u,E,i),e.add(t,i,i),i}},p.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var E,f;if(1!==l&&2!==l||(E=new e,f=new e),1===l){if(u)return p.lineSegmentPlane(t,n,a,E),p.lineSegmentPlane(t,r,a,f),{positions:[t,n,r,E,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return p.lineSegmentPlane(n,r,a,E),p.lineSegmentPlane(n,t,a,f),{positions:[t,n,r,E,f],indices:[1,3,4,2,0,4,2,4,3]};if(c)return p.lineSegmentPlane(r,t,a,E),p.lineSegmentPlane(r,n,a,f),{positions:[t,n,r,E,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return p.lineSegmentPlane(n,t,a,E),p.lineSegmentPlane(r,t,a,f),{positions:[t,n,r,E,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return p.lineSegmentPlane(r,n,a,E),p.lineSegmentPlane(t,n,a,f),{positions:[t,n,r,E,f],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return p.lineSegmentPlane(t,r,a,E),p.lineSegmentPlane(n,r,a,f),{positions:[t,n,r,E,f],indices:[0,1,4,0,4,3,2,3,4]}}},p}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,a){n(a)||(a=new e);var i=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,i,c);return e.subtract(r,o,a)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/Tipsify",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";var r={};return r.calculateACMR=function(n){n=e(n,e.EMPTY_OBJECT);var r=n.indices,a=n.maximumIndex,i=e(n.cacheSize,24),o=r.length;if(!t(a)){a=0;for(var u=0,s=r[u];u<o;)s>a&&(a=s),++u,s=r[u]}for(var c=[],l=0;l<a+1;l++)c[l]=0;for(var E=i+1,f=0;f<o;++f)E-c[r[f]]>i&&(c[r[f]]=E,++E);return(E-i+1)/(o/3)},r.tipsify=function(n){function r(e,t,n,r){for(;t.length>=1;){var i=t[t.length-1];if(t.splice(t.length-1,1),e[i].numLiveTriangles>0)return i}for(;a<r;){if(e[a].numLiveTriangles>0)return++a-1;++a}return-1}n=e(n,e.EMPTY_OBJECT);var a,i=n.indices,o=n.maximumIndex,u=e(n.cacheSize,24),s=i.length,c=0,l=0,E=i[l],f=s;if(t(o))c=o+1;else{for(;l<f;)E>c&&(c=E),++l,E=i[l];if(-1===c)return 0;++c}var h,d=[];for(h=0;h<c;h++)d[h]={numLiveTriangles:0,timeStamp:0,vertexTriangles:[]};l=0;for(var p=0;l<f;)d[i[l]].vertexTriangles.push(p),++d[i[l]].numLiveTriangles,d[i[l+1]].vertexTriangles.push(p),++d[i[l+1]].numLiveTriangles,d[i[l+2]].vertexTriangles.push(p),++d[i[l+2]].numLiveTriangles,++p,l+=3;var y=0,_=u+1;a=1;var m,T,R=[],v=[],A=0,S=[],N=s/3,g=[];for(h=0;h<N;h++)g[h]=!1;for(var I,M;-1!==y;){R=[],T=d[y],M=T.vertexTriangles.length;for(var O=0;O<M;++O)if(p=T.vertexTriangles[O],!g[p]){g[p]=!0,l=p+p+p;for(var x=0;x<3;++x)I=i[l],R.push(I),v.push(I),S[A]=I,++A,m=d[I],--m.numLiveTriangles,_-m.timeStamp>u&&(m.timeStamp=_,++_),++l}y=function(e,t,n,a,i,o,u){for(var s,c=-1,l=-1,E=0;E<n.length;){var f=n[E];a[f].numLiveTriangles&&(s=0,i-a[f].timeStamp+2*a[f].numLiveTriangles<=t&&(s=i-a[f].timeStamp),(s>l||-1===l)&&(l=s,c=f)),++E}return-1===c?r(a,o,e,u):c}(i,u,R,d,_,v,c)}return S},r}),define("Core/GeometryPipeline",["./AttributeCompression","./barycentricCoordinates","./BoundingSphere","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./EncodedCartesian3","./GeographicProjection","./Geometry","./GeometryAttribute","./GeometryType","./IndexDatatype","./Intersect","./IntersectionTests","./Math","./Matrix3","./Matrix4","./Plane","./PrimitiveType","./Tipsify"],function(e,t,n,r,a,i,o,u,s,c,l,E,f,h,d,p,y,_,m,T,R,v,A,S,N){"use strict";function g(e,t,n,r,a){e[t++]=n,e[t++]=r,e[t++]=r,e[t++]=a,e[t++]=a,e[t]=n}function I(e){for(var t=e.length,n=t/3*6,r=y.createTypedArray(t,n),a=0,i=0;i<t;i+=3,a+=6)g(r,a,e[i],e[i+1],e[i+2]);return r}function M(e){var t=e.length;if(t>=3){var n=6*(t-2),r=y.createTypedArray(t,n);g(r,0,e[0],e[1],e[2]);for(var a=6,i=3;i<t;++i,a+=6)g(r,a,e[i-1],e[i],e[i-2]);return r}return new Uint16Array}function O(e){if(e.length>0){for(var t=e.length-1,n=6*(t-1),r=y.createTypedArray(t,n),a=e[0],i=0,o=1;o<t;++o,i+=6)g(r,i,a,e[o],e[o+1]);return r}return new Uint16Array}function x(e){var t={};for(var n in e)if(e.hasOwnProperty(n)&&c(e[n])&&c(e[n].values)){var r=e[n];t[n]=new d({componentDatatype:r.componentDatatype,componentsPerAttribute:r.componentsPerAttribute,normalize:r.normalize,values:[]})}return t}function w(e,t,n){for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values))for(var a=t[r],i=0;i<a.componentsPerAttribute;++i)e[r].values.push(a.values[n*a.componentsPerAttribute+i])}function C(e,t){if(c(t))for(var n=t.values,r=n.length,i=0;i<r;i+=3)a.unpack(n,i,ie),v.multiplyByPoint(e,ie,ie),a.pack(ie,n,i)}function P(e,t){if(c(t))for(var n=t.values,r=n.length,i=0;i<r;i+=3)a.unpack(n,i,ie),R.multiplyByVector(e,ie,ie),ie=a.normalize(ie,ie),a.pack(ie,n,i)}function L(e,t){var n,r=e.length,a={},i=e[0][t].attributes;for(n in i)if(i.hasOwnProperty(n)&&c(i[n])&&c(i[n].values)){for(var o=i[n],s=o.values.length,l=!0,E=1;E<r;++E){var f=e[E][t].attributes[n];if(!c(f)||o.componentDatatype!==f.componentDatatype||o.componentsPerAttribute!==f.componentsPerAttribute||o.normalize!==f.normalize){l=!1;break}s+=f.values.length}l&&(a[n]=new d({componentDatatype:o.componentDatatype,componentsPerAttribute:o.componentsPerAttribute,normalize:o.normalize,values:u.createTypedArray(o.componentDatatype,s)}))}return a}function b(e,t){var r,i,o,u,s,l,E,f=e.length,d=(e[0].modelMatrix,c(e[0][t].indices)),p=e[0][t].primitiveType,_=L(e,t);for(r in _)if(_.hasOwnProperty(r))for(s=_[r].values,u=0,i=0;i<f;++i)for(l=e[i][t].attributes[r].values,E=l.length,o=0;o<E;++o)s[u++]=l[o];var m;if(d){var T=0;for(i=0;i<f;++i)T+=e[i][t].indices.length;var R=h.computeNumberOfVertices(new h({attributes:_,primitiveType:S.POINTS})),v=y.createTypedArray(R,T),A=0,N=0;for(i=0;i<f;++i){var g=e[i][t].indices,I=g.length;for(u=0;u<I;++u)v[A++]=N+g[u];N+=h.computeNumberOfVertices(e[i][t])}m=v}var M,O=new a,x=0;for(i=0;i<f;++i){if(M=e[i][t].boundingSphere,!c(M)){O=void 0;break}a.add(M.center,O,O)}if(c(O))for(a.divideByScalar(O,f,O),i=0;i<f;++i){M=e[i][t].boundingSphere;var w=a.magnitude(a.subtract(M.center,O,se))+M.radius;w>x&&(x=w)}return new h({attributes:_,indices:m,primitiveType:p,boundingSphere:c(O)?new n(O,x):void 0})}function U(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function F(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,3*(t-2));n[0]=1,n[1]=0,n[2]=2;for(var r=3,a=3;a<t;++a)n[r++]=a-1,n[r++]=0,n[r++]=a;return e.indices=n,e.primitiveType=S.TRIANGLES,e}function D(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,3*(t-2));n[0]=0,n[1]=1,n[2]=2,t>3&&(n[3]=0,n[4]=2,n[5]=3);for(var r=6,a=3;a<t-1;a+=2)n[r++]=a,n[r++]=a-1,n[r++]=a+1,a+2<t&&(n[r++]=a,n[r++]=a+1,n[r++]=a+2);return e.indices=n,e.primitiveType=S.TRIANGLES,e}function B(e){if(c(e.indices))return e;for(var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,t),r=0;r<t;++r)n[r]=r;return e.indices=n,e}function z(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,2*(t-1));n[0]=0,n[1]=1;for(var r=2,a=2;a<t;++a)n[r++]=a-1,n[r++]=a;return e.indices=n,e.primitiveType=S.LINES,e}function G(e){var t=h.computeNumberOfVertices(e),n=y.createTypedArray(t,2*t);n[0]=0,n[1]=1;for(var r=2,a=2;a<t;++a)n[r++]=a-1,n[r++]=a;return n[r++]=t-1,n[r]=0,e.indices=n,e.primitiveType=S.LINES,e}function q(e){switch(e.primitiveType){case S.TRIANGLE_FAN:return F(e);case S.TRIANGLE_STRIP:return D(e);case S.TRIANGLES:return U(e);case S.LINE_STRIP:return z(e);case S.LINE_LOOP:return G(e);case S.LINES:return B(e)}return e}function V(e,t){Math.abs(e.y)<T.EPSILON6&&(e.y=t?-T.EPSILON6:T.EPSILON6)}function X(e,t,n){if(0!==e.y&&0!==t.y&&0!==n.y)return V(e,e.y<0),V(t,t.y<0),void V(n,n.y<0);var r,a=Math.abs(e.y),i=Math.abs(t.y),o=Math.abs(n.y);r=a>i?a>o?T.sign(e.y):T.sign(n.y):i>o?T.sign(t.y):T.sign(n.y);var u=r<0;V(e,u),V(t,u),V(n,u)}function W(e,t,n,r){a.add(e,a.multiplyByScalar(a.subtract(t,e,ve),e.y/(e.y-t.y),ve),n),a.clone(n,r),V(n,!0),V(r,!1)}function H(e,t,n){if(!(e.x>=0||t.x>=0||n.x>=0)){X(e,t,n);var r=e.y<0,a=t.y<0,i=n.y<0,o=0;o+=r?1:0,o+=a?1:0,o+=i?1:0;var u=Ie.indices;1===o?(u[1]=3,u[2]=4,u[5]=6,u[7]=6,u[8]=5,r?(W(e,t,Ae,Ne),W(e,n,Se,ge),u[0]=0,u[3]=1,u[4]=2,u[6]=1):a?(W(t,n,Ae,Ne),W(t,e,Se,ge),u[0]=1,u[3]=2,u[4]=0,u[6]=2):i&&(W(n,e,Ae,Ne),W(n,t,Se,ge),u[0]=2,u[3]=0,u[4]=1,u[6]=0)):2===o&&(u[2]=4,u[4]=4,u[5]=3,u[7]=5,u[8]=6,r?a?i||(W(n,e,Ae,Ne),W(n,t,Se,ge),u[0]=0,u[1]=1,u[3]=0,u[6]=2):(W(t,n,Ae,Ne),W(t,e,Se,ge),u[0]=2,u[1]=0,u[3]=2,u[6]=1):(W(e,t,Ae,Ne),W(e,n,Se,ge),u[0]=1,u[1]=2,u[3]=1,u[6]=0));var s=Ie.positions;return s[0]=e,s[1]=t,s[2]=n,s.length=3,1!==o&&2!==o||(s[3]=Ae,s[4]=Se,s[5]=Ne,s[6]=ge,s.length=7),Ie}}function Y(e,t){var r=e.attributes;if(0!==r.position.values.length){for(var a in r)if(r.hasOwnProperty(a)&&c(r[a])&&c(r[a].values)){var i=r[a];i.values=u.createTypedArray(i.componentDatatype,i.values)}var o=h.computeNumberOfVertices(e);return e.indices=y.createTypedArray(o,e.indices),t&&(e.boundingSphere=n.fromVertices(r.position.values)),e}}function k(e){var t=e.attributes,n={};for(var r in t)if(t.hasOwnProperty(r)&&c(t[r])&&c(t[r].values)){var a=t[r];n[r]=new d({componentDatatype:a.componentDatatype,componentsPerAttribute:a.componentsPerAttribute,normalize:a.normalize,values:[]})}return new h({attributes:n,indices:[],primitiveType:e.primitiveType})}function Z(e,t,n){var r=c(e.geometry.boundingSphere);t=Y(t,r),n=Y(n,r),c(n)&&!c(t)?e.geometry=n:!c(n)&&c(t)?e.geometry=t:(e.westHemisphereGeometry=t,e.eastHemisphereGeometry=n,e.geometry=void 0)}function K(e,n,i,o,u,s,l,E,f,h,d,p){if(c(s)||c(l)||c(E)||c(f)||c(h)){var y=a.fromArray(u,3*e,Me),_=a.fromArray(u,3*n,Oe),m=a.fromArray(u,3*i,xe),T=t(o,y,_,m,we);if(c(s)){var R=a.fromArray(s,3*e,Me),v=a.fromArray(s,3*n,Oe),A=a.fromArray(s,3*i,xe);a.multiplyByScalar(R,T.x,R),a.multiplyByScalar(v,T.y,v),a.multiplyByScalar(A,T.z,A);var S=a.add(R,v,R);a.add(S,A,S),a.normalize(S,S),a.pack(S,d.normal.values,3*p)}if(c(h)){var N=a.fromArray(h,3*e,Me),g=a.fromArray(h,3*n,Oe),I=a.fromArray(h,3*i,xe);a.multiplyByScalar(N,T.x,N),a.multiplyByScalar(g,T.y,g),a.multiplyByScalar(I,T.z,I);var M;a.equals(N,a.ZERO)&&a.equals(g,a.ZERO)&&a.equals(I,a.ZERO)?(M=Me,M.x=0,M.y=0,M.z=0):(M=a.add(N,g,N),a.add(M,I,M),a.normalize(M,M)),a.pack(M,d.extrudeDirection.values,3*p)}if(c(l)){var O=a.fromArray(l,3*e,Me),x=a.fromArray(l,3*n,Oe),w=a.fromArray(l,3*i,xe);a.multiplyByScalar(O,T.x,O),a.multiplyByScalar(x,T.y,x),a.multiplyByScalar(w,T.z,w);var C=a.add(O,x,O);a.add(C,w,C),a.normalize(C,C),a.pack(C,d.tangent.values,3*p)}if(c(E)){var P=a.fromArray(E,3*e,Me),L=a.fromArray(E,3*n,Oe),b=a.fromArray(E,3*i,xe);a.multiplyByScalar(P,T.x,P),a.multiplyByScalar(L,T.y,L),a.multiplyByScalar(b,T.z,b);var U=a.add(P,L,P);a.add(U,b,U),a.normalize(U,U),a.pack(U,d.bitangent.values,3*p)}if(c(f)){var F=r.fromArray(f,2*e,Ce),D=r.fromArray(f,2*n,Pe),B=r.fromArray(f,2*i,Le);r.multiplyByScalar(F,T.x,F),r.multiplyByScalar(D,T.y,D),r.multiplyByScalar(B,T.z,B);var z=r.add(F,D,F);r.add(z,B,z),r.pack(z,d.st.values,2*p)}}}function j(e,t,n,r,a,i){var o=e.position.values.length/3;if(-1!==a){var u=r[a],s=n[u];return-1===s?(n[u]=o,e.position.values.push(i.x,i.y,i.z),t.push(o),o):(t.push(s),s)}return e.position.values.push(i.x,i.y,i.z),t.push(o),o}function Q(e){var t,n,r,i,o,u=e.geometry,s=u.attributes,l=s.position.values,E=c(s.normal)?s.normal.values:void 0,f=c(s.bitangent)?s.bitangent.values:void 0,h=c(s.tangent)?s.tangent.values:void 0,d=c(s.st)?s.st.values:void 0,p=c(s.extrudeDirection)?s.extrudeDirection.values:void 0,y=u.indices,_=k(u),m=k(u),T=[];T.length=l.length/3;var R=[];for(R.length=l.length/3,o=0;o<T.length;++o)T[o]=-1,R[o]=-1;var v=y.length;for(o=0;o<v;o+=3){var A=y[o],S=y[o+1],N=y[o+2],g=a.fromArray(l,3*A),I=a.fromArray(l,3*S),M=a.fromArray(l,3*N),O=H(g,I,M);if(c(O)&&O.positions.length>3)for(var x=O.positions,w=O.indices,C=w.length,P=0;P<C;++P){var L=w[P],b=x[L];b.y<0?(t=m.attributes,n=m.indices,r=T):(t=_.attributes,n=_.indices,r=R),i=j(t,n,r,y,L<3?o+L:-1,b),K(A,S,N,b,l,E,h,f,d,p,t,i)}else c(O)&&(g=O.positions[0],I=O.positions[1],M=O.positions[2]),g.y<0?(t=m.attributes,n=m.indices,r=T):(t=_.attributes,n=_.indices,r=R),i=j(t,n,r,y,o,g),K(A,S,N,g,l,E,h,f,d,p,t,i),i=j(t,n,r,y,o+1,I),K(A,S,N,I,l,E,h,f,d,p,t,i),i=j(t,n,r,y,o+2,M),K(A,S,N,M,l,E,h,f,d,p,t,i)}Z(e,m,_)}function J(e){var t,n=e.geometry,r=n.attributes,i=r.position.values,o=n.indices,u=k(n),s=k(n),l=o.length,E=[];E.length=i.length/3;var f=[];for(f.length=i.length/3,t=0;t<E.length;++t)E[t]=-1,f[t]=-1;for(t=0;t<l;t+=2){var h=o[t],d=o[t+1],p=a.fromArray(i,3*h,Me),y=a.fromArray(i,3*d,Oe);Math.abs(p.y)<T.EPSILON6&&(p.y<0?p.y=-T.EPSILON6:p.y=T.EPSILON6),Math.abs(y.y)<T.EPSILON6&&(y.y<0?y.y=-T.EPSILON6:y.y=T.EPSILON6);var _=u.attributes,R=u.indices,v=f,A=s.attributes,S=s.indices,N=E,g=m.lineSegmentPlane(p,y,be,xe);if(c(g)){var I=a.multiplyByScalar(a.UNIT_Y,5*T.EPSILON9,Ue);p.y<0&&(a.negate(I,I),_=s.attributes,R=s.indices,v=E,A=u.attributes,S=u.indices,N=f);var M=a.add(g,I,Fe);j(_,R,v,o,t,p),j(_,R,v,o,-1,M),a.negate(I,I),a.add(g,I,M),j(A,S,N,o,-1,M),j(A,S,N,o,t+1,y)}else{var O,x,w;p.y<0?(O=s.attributes,x=s.indices,w=E):(O=u.attributes,x=u.indices,w=f),j(O,x,w,o,t,p),j(O,x,w,o,t+1,y)}}Z(e,s,u)}function $(e){for(var t=e.attributes,n=t.position.values,r=t.prevPosition.values,i=t.nextPosition.values,o=n.length,u=0;u<o;u+=3){var s=a.unpack(n,u,ze);if(!(s.x>0)){var c=a.unpack(r,u,Ge);(s.y<0&&c.y>0||s.y>0&&c.y<0)&&(u-3>0?(r[u]=n[u-3],r[u+1]=n[u-2],r[u+2]=n[u-1]):a.pack(s,r,u));var l=a.unpack(i,u,qe);(s.y<0&&l.y>0||s.y>0&&l.y<0)&&(u+3<o?(i[u]=n[u+3],i[u+1]=n[u+4],i[u+2]=n[u+5]):a.pack(s,i,u))}}}function ee(e){var t,n,o,u=e.geometry,s=u.attributes,l=s.position.values,E=s.prevPosition.values,f=s.nextPosition.values,h=s.expandAndWidth.values,d=c(s.st)?s.st.values:void 0,p=c(s.color)?s.color.values:void 0,y=k(u),_=k(u),R=!1,v=l.length/3;for(t=0;t<v;t+=4){var A=t,S=t+2,N=a.fromArray(l,3*A,ze),g=a.fromArray(l,3*S,Ge);if(Math.abs(N.y)<ke)for(N.y=ke*(g.y<0?-1:1),l[3*t+1]=N.y,l[3*(t+1)+1]=N.y,n=3*A;n<3*A+12;n+=3)E[n]=l[3*t],E[n+1]=l[3*t+1],E[n+2]=l[3*t+2];if(Math.abs(g.y)<ke)for(g.y=ke*(N.y<0?-1:1),l[3*(t+2)+1]=g.y,l[3*(t+3)+1]=g.y,n=3*A;n<3*A+12;n+=3)f[n]=l[3*(t+2)],f[n+1]=l[3*(t+2)+1],f[n+2]=l[3*(t+2)+2];var I=y.attributes,M=y.indices,O=_.attributes,x=_.indices,w=m.lineSegmentPlane(N,g,be,Ve);if(c(w)){R=!0;var C=a.multiplyByScalar(a.UNIT_Y,Ye,Xe);N.y<0&&(a.negate(C,C),I=_.attributes,M=_.indices,O=y.attributes,x=y.indices);var P=a.add(w,C,We);I.position.values.push(N.x,N.y,N.z,N.x,N.y,N.z),I.position.values.push(P.x,P.y,P.z),I.position.values.push(P.x,P.y,P.z),I.prevPosition.values.push(E[3*A],E[3*A+1],E[3*A+2]),I.prevPosition.values.push(E[3*A+3],E[3*A+4],E[3*A+5]),I.prevPosition.values.push(N.x,N.y,N.z,N.x,N.y,N.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),I.nextPosition.values.push(P.x,P.y,P.z),a.negate(C,C),a.add(w,C,P),O.position.values.push(P.x,P.y,P.z),O.position.values.push(P.x,P.y,P.z),O.position.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.prevPosition.values.push(P.x,P.y,P.z),O.prevPosition.values.push(P.x,P.y,P.z),O.prevPosition.values.push(P.x,P.y,P.z),O.prevPosition.values.push(P.x,P.y,P.z),O.nextPosition.values.push(g.x,g.y,g.z,g.x,g.y,g.z),O.nextPosition.values.push(f[3*S],f[3*S+1],f[3*S+2]),O.nextPosition.values.push(f[3*S+3],f[3*S+4],f[3*S+5]);var L=r.fromArray(h,2*A,De),b=Math.abs(L.y);I.expandAndWidth.values.push(-1,b,1,b),I.expandAndWidth.values.push(-1,-b,1,-b),O.expandAndWidth.values.push(-1,b,1,b),O.expandAndWidth.values.push(-1,-b,1,-b);var U=a.magnitudeSquared(a.subtract(w,N,qe));if(U/=a.magnitudeSquared(a.subtract(g,N,qe)),c(p)){var F=i.fromArray(p,4*A,He),D=i.fromArray(p,4*S,He),B=T.lerp(F.x,D.x,U),z=T.lerp(F.y,D.y,U),G=T.lerp(F.z,D.z,U),q=T.lerp(F.w,D.w,U);for(n=4*A;n<4*A+8;++n)I.color.values.push(p[n]);for(I.color.values.push(B,z,G,q),I.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),O.color.values.push(B,z,G,q),n=4*S;n<4*S+8;++n)O.color.values.push(p[n])}if(c(d)){var V=r.fromArray(d,2*A,De),X=r.fromArray(d,2*(t+3),Be),W=T.lerp(V.x,X.x,U);for(n=2*A;n<2*A+4;++n)I.st.values.push(d[n]);for(I.st.values.push(W,V.y),I.st.values.push(W,X.y),O.st.values.push(W,V.y),O.st.values.push(W,X.y),n=2*S;n<2*S+4;++n)O.st.values.push(d[n])}o=I.position.values.length/3-4,M.push(o,o+2,o+1),M.push(o+1,o+2,o+3),o=O.position.values.length/3-4,x.push(o,o+2,o+1),x.push(o+1,o+2,o+3)}else{var H,Y;for(N.y<0?(H=_.attributes,Y=_.indices):(H=y.attributes,Y=y.indices),H.position.values.push(N.x,N.y,N.z),H.position.values.push(N.x,N.y,N.z),H.position.values.push(g.x,g.y,g.z),H.position.values.push(g.x,g.y,g.z),n=3*t;n<3*t+12;++n)H.prevPosition.values.push(E[n]),H.nextPosition.values.push(f[n]);for(n=2*t;n<2*t+8;++n)H.expandAndWidth.values.push(h[n]),c(d)&&H.st.values.push(d[n]);if(c(p))for(n=4*t;n<4*t+16;++n)H.color.values.push(p[n]);o=H.position.values.length/3-4,Y.push(o,o+2,o+1),Y.push(o+1,o+2,o+3)}}R&&($(_),$(y)),Z(e,_,y)}var te={};te.toWireframe=function(e){var t=e.indices;if(c(t)){switch(e.primitiveType){case S.TRIANGLES:e.indices=I(t);break;case S.TRIANGLE_STRIP:e.indices=M(t);break;case S.TRIANGLE_FAN:e.indices=O(t)}e.primitiveType=S.LINES}return e},te.createLineSegmentsForVectors=function(e,t,r){t=s(t,"normal"),r=s(r,1e4);for(var a=e.attributes.position.values,i=e.attributes[t].values,o=a.length,l=new Float64Array(2*o),E=0,f=0;f<o;f+=3)l[E++]=a[f],l[E++]=a[f+1],l[E++]=a[f+2],l[E++]=a[f]+i[f]*r,l[E++]=a[f+1]+i[f+1]*r,l[E++]=a[f+2]+i[f+2]*r;var p,y=e.boundingSphere;return c(y)&&(p=new n(y.center,y.radius+r)),new h({attributes:{position:new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:l})},primitiveType:S.LINES,boundingSphere:p})},te.createAttributeLocations=function(e){var t,n=["position","positionHigh","positionLow","position3DHigh","position3DLow","position2DHigh","position2DLow","pickColor","normal","st","tangent","bitangent","extrudeDirection","compressedAttributes"],r=e.attributes,a={},i=0,o=n.length;for(t=0;t<o;++t){var u=n[t];c(r[u])&&(a[u]=i++)}for(var s in r)r.hasOwnProperty(s)&&!c(a[s])&&(a[s]=i++);return a},te.reorderForPreVertexCache=function(e){var t=h.computeNumberOfVertices(e),n=e.indices;if(c(n)){for(var r=new Int32Array(t),a=0;a<t;a++)r[a]=-1;for(var i,o=n,s=o.length,l=y.createTypedArray(t,s),E=0,f=0,d=0;E<s;)i=r[o[E]],-1!==i?l[f]=i:(i=o[E],r[i]=d,l[f]=d,++d),++E,++f;e.indices=l;var p=e.attributes;for(var _ in p)if(p.hasOwnProperty(_)&&c(p[_])&&c(p[_].values)){for(var m=p[_],T=m.values,R=0,v=m.componentsPerAttribute,A=u.createTypedArray(m.componentDatatype,d*v);R<t;){var S=r[R];if(-1!==S)for(var N=0;N<v;N++)A[v*S+N]=T[v*R+N];++R}m.values=A}}return e},te.reorderForPostVertexCache=function(e,t){var n=e.indices;if(e.primitiveType===S.TRIANGLES&&c(n)){for(var r=n.length,a=0,i=0;i<r;i++)n[i]>a&&(a=n[i]);e.indices=N.tipsify({indices:n,maximumIndex:a,cacheSize:t})}return e},te.fitToUnsignedShortIndices=function(e){var t=[],n=h.computeNumberOfVertices(e);if(c(e.indices)&&n>=T.SIXTY_FOUR_KILOBYTES){var r,a=[],i=[],o=0,u=x(e.attributes),s=e.indices,l=s.length;e.primitiveType===S.TRIANGLES?r=3:e.primitiveType===S.LINES?r=2:e.primitiveType===S.POINTS&&(r=1);for(var E=0;E<l;E+=r){for(var f=0;f<r;++f){var d=s[E+f],p=a[d];c(p)||(p=o++,a[d]=p,w(u,e.attributes,d)),i.push(p)}o+r>=T.SIXTY_FOUR_KILOBYTES&&(t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV})),a=[],i=[],o=0,u=x(e.attributes))}0!==i.length&&t.push(new h({attributes:u,indices:i,primitiveType:e.primitiveType,boundingSphere:e.boundingSphere,boundingSphereCV:e.boundingSphereCV}))}else t.push(e);return t};var ne=new a,re=new o;te.projectTo2D=function(e,t,n,r,i){var o=e.attributes[t];i=c(i)?i:new f;for(var s=i.ellipsoid,l=o.values,E=new Float64Array(l.length),h=0,p=0;p<l.length;p+=3){var y=a.fromArray(l,p,ne),_=s.cartesianToCartographic(y,re),m=i.project(_,ne);E[h++]=m.x,E[h++]=m.y,E[h++]=m.z}return e.attributes[n]=o,e.attributes[r]=new d({componentDatatype:u.DOUBLE,componentsPerAttribute:3,values:E}),delete e.attributes[t],e};var ae={high:0,low:0};te.encodeAttribute=function(e,t,n,r){for(var a=e.attributes[t],i=a.values,o=i.length,s=new Float32Array(o),c=new Float32Array(o),l=0;l<o;++l)E.encode(i[l],ae),s[l]=ae.high,c[l]=ae.low;var f=a.componentsPerAttribute;return e.attributes[n]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:s}),e.attributes[r]=new d({componentDatatype:u.FLOAT,componentsPerAttribute:f,values:c}),delete e.attributes[t],e};var ie=new a,oe=new v,ue=new R;te.transformToWorldCoordinates=function(e){var t=e.modelMatrix;if(v.equals(t,v.IDENTITY))return e;var r=e.geometry.attributes;C(t,r.position),C(t,r.prevPosition),C(t,r.nextPosition),(c(r.normal)||c(r.tangent)||c(r.bitangent))&&(v.inverse(t,oe),v.transpose(oe,oe),v.getRotation(oe,ue),P(ue,r.normal),P(ue,r.tangent),P(ue,r.bitangent));var a=e.geometry.boundingSphere;return c(a)&&(e.geometry.boundingSphere=n.transform(a,t,a)),e.modelMatrix=v.clone(v.IDENTITY),e};var se=new a;te.combineInstances=function(e){for(var t=[],n=[],r=e.length,a=0;a<r;++a){var i=e[a];c(i.geometry)?t.push(i):c(i.westHemisphereGeometry)&&c(i.eastHemisphereGeometry)&&n.push(i)}var o=[];return t.length>0&&o.push(b(t,"geometry")),n.length>0&&(o.push(b(n,"westHemisphereGeometry")),o.push(b(n,"eastHemisphereGeometry"))),o};var ce=new a,le=new a,Ee=new a,fe=new a;te.computeNormal=function(e){var t,n=e.indices,r=e.attributes,i=r.position.values,o=r.position.values.length/3,s=n.length,c=new Array(o),l=new Array(s/3),E=new Array(s);for(t=0;t<o;t++)c[t]={indexOffset:0,count:0,currentCount:0};var f=0;for(t=0;t<s;t+=3){var h=n[t],p=n[t+1],y=n[t+2],_=3*h,m=3*p,R=3*y;le.x=i[_],le.y=i[_+1],le.z=i[_+2],Ee.x=i[m],Ee.y=i[m+1],Ee.z=i[m+2],fe.x=i[R],fe.y=i[R+1],fe.z=i[R+2],c[h].count++,c[p].count++,c[y].count++,a.subtract(Ee,le,Ee),a.subtract(fe,le,fe),l[f]=a.cross(Ee,fe,new a),f++}var v=0;for(t=0;t<o;t++)c[t].indexOffset+=v,v+=c[t].count;f=0;var A;for(t=0;t<s;t+=3){A=c[n[t]];var S=A.indexOffset+A.currentCount;E[S]=f,A.currentCount++,A=c[n[t+1]],S=A.indexOffset+A.currentCount,E[S]=f,A.currentCount++,A=c[n[t+2]],S=A.indexOffset+A.currentCount,E[S]=f,A.currentCount++,f++}var N=new Float32Array(3*o);for(t=0;t<o;t++){var g=3*t;if(A=c[t],a.clone(a.ZERO,ce),A.count>0){for(f=0;f<A.count;f++)a.add(ce,l[E[A.indexOffset+f]],ce);a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&a.clone(l[E[A.indexOffset]],ce)}a.equalsEpsilon(a.ZERO,ce,T.EPSILON10)&&(ce.z=1),a.normalize(ce,ce),N[g]=ce.x,N[g+1]=ce.y,N[g+2]=ce.z}return e.attributes.normal=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:N}),e};var he=new a,de=new a,pe=new a;te.computeTangentAndBitangent=function(e){var t,n=(e.attributes,e.indices),r=e.attributes.position.values,i=e.attributes.normal.values,o=e.attributes.st.values,s=e.attributes.position.values.length/3,c=n.length,l=new Array(3*s);for(t=0;t<l.length;t++)l[t]=0;var E,f,h;for(t=0;t<c;t+=3){var p=n[t],y=n[t+1],_=n[t+2];E=3*p,f=3*y,h=3*_;var m=2*p,T=2*y,R=2*_,v=r[E],A=r[E+1],S=r[E+2],N=o[m],g=o[m+1],I=o[T+1]-g,M=o[R+1]-g,O=1/((o[T]-N)*M-(o[R]-N)*I),x=(M*(r[f]-v)-I*(r[h]-v))*O,w=(M*(r[f+1]-A)-I*(r[h+1]-A))*O,C=(M*(r[f+2]-S)-I*(r[h+2]-S))*O;l[E]+=x,l[E+1]+=w,l[E+2]+=C,l[f]+=x,l[f+1]+=w,l[f+2]+=C,l[h]+=x,l[h+1]+=w,l[h+2]+=C}var P=new Float32Array(3*s),L=new Float32Array(3*s);for(t=0;t<s;t++){E=3*t,f=E+1,h=E+2;var b=a.fromArray(i,E,he),U=a.fromArray(l,E,pe),F=a.dot(b,U);a.multiplyByScalar(b,F,de),a.normalize(a.subtract(U,de,U),U),P[E]=U.x,P[f]=U.y,P[h]=U.z,a.normalize(a.cross(b,U,U),U),L[E]=U.x,L[f]=U.y,L[h]=U.z}return e.attributes.tangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:P}),e.attributes.bitangent=new d({componentDatatype:u.FLOAT,componentsPerAttribute:3,values:L}),e};var ye=new r,_e=new a,me=new a,Te=new a,Re=new r;te.compressVertices=function(t){var n,i,o=t.attributes.extrudeDirection;if(c(o)){var s=o.values;i=s.length/3;var l=new Float32Array(2*i),E=0;for(n=0;n<i;++n)a.fromArray(s,3*n,_e),a.equals(_e,a.ZERO)?E+=2:(Re=e.octEncodeInRange(_e,65535,Re),l[E++]=Re.x,l[E++]=Re.y);return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:2,values:l}),delete t.attributes.extrudeDirection,t}var f=t.attributes.normal,h=t.attributes.st,p=c(f),y=c(h);if(!p&&!y)return t;var _,m,T,R,v=t.attributes.tangent,A=t.attributes.bitangent,S=c(v),N=c(A);p&&(_=f.values),y&&(m=h.values),S&&(T=v.values),N&&(R=A.values),i=(p?_.length:m.length)/(p?3:2);var g=i,I=y&&p?2:1;I+=S||N?1:0,g*=I;var M=new Float32Array(g),O=0;for(n=0;n<i;++n){y&&(r.fromArray(m,2*n,ye),M[O++]=e.compressTextureCoordinates(ye));var x=3*n;p&&c(T)&&c(R)?(a.fromArray(_,x,_e),a.fromArray(T,x,me),a.fromArray(R,x,Te),e.octPack(_e,me,Te,ye),M[O++]=ye.x,M[O++]=ye.y):(p&&(a.fromArray(_,x,_e),M[O++]=e.octEncodeFloat(_e)),S&&(a.fromArray(T,x,_e),M[O++]=e.octEncodeFloat(_e)),N&&(a.fromArray(R,x,_e),M[O++]=e.octEncodeFloat(_e)))}return t.attributes.compressedAttributes=new d({componentDatatype:u.FLOAT,componentsPerAttribute:I,values:M}),p&&delete t.attributes.normal,y&&delete t.attributes.st,N&&delete t.attributes.bitangent,S&&delete t.attributes.tangent,t};var ve=new a,Ae=new a,Se=new a,Ne=new a,ge=new a,Ie={positions:new Array(7),indices:new Array(9)},Me=new a,Oe=new a,xe=new a,we=new a,Ce=new r,Pe=new r,Le=new r,be=A.fromPointNormal(a.ZERO,a.UNIT_Y),Ue=new a,Fe=new a,De=new r,Be=new r,ze=new a,Ge=new a,qe=new a,Ve=new a,Xe=new a,We=new a,He=new i,Ye=5*T.EPSILON9,ke=T.EPSILON6;return te.splitLongitude=function(e){var t=e.geometry,r=t.boundingSphere;if(c(r)){if(r.center.x-r.radius>0||n.intersectPlane(r,A.ORIGIN_ZX_PLANE)!==_.INTERSECTING)return e}if(t.geometryType!==p.NONE)switch(t.geometryType){case p.POLYLINES:ee(e);break;case p.TRIANGLES:Q(e);break +;case p.LINES:J(e)}else q(t),t.primitiveType===S.TRIANGLES?Q(e):t.primitiveType===S.LINES&&J(e);return e},te}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,E,f,h,d,p,y;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=f=e[0],E=h=e[1];for(var _=a;_<o;_+=a)d=e[_],p=e[_+1],d<l&&(l=d),p<E&&(E=p),d>f&&(f=d),p>h&&(h=p);y=Math.max(f-l,h-E)}return r(u,c,a,l,E,y),c}function t(e,t,n,r,a){var i,o;if(a===O(e,t,n,r)>0)for(i=t;i<n;i+=r)o=g(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=g(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(I(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==m(r.prev,r,r.next))r=r.next;else{if(I(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,E,h){if(e){!h&&E&&f(e,c,l,E);for(var d,p,y=e;e.prev!==e.next;)if(d=e.prev,p=e.next,E?i(e,c,l,E):a(e))t.push(d.i/s),t.push(e.i/s),t.push(p.i/s),I(e),e=p.next,y=p.next;else if((e=p)===y){h?1===h?(e=o(e,t,s),r(e,t,s,c,l,E,2)):2===h&&u(e,t,s,c,l,E):r(n(e),t,s,c,l,E,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(m(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(y(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&m(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(m(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,E=d(u,s,t,n,r),f=d(c,l,t,n,r),h=e.nextZ;h&&h.z<=f;){if(h!==e.prev&&h!==e.next&&y(a.x,a.y,i.x,i.y,o.x,o.y,h.x,h.y)&&m(h.prev,h,h.next)>=0)return!1;h=h.nextZ}for(h=e.prevZ;h&&h.z>=E;){if(h!==e.prev&&h!==e.next&&y(a.x,a.y,i.x,i.y,o.x,o.y,h.x,h.y)&&m(h.prev,h,h.next)>=0)return!1;h=h.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&A(a,i)&&A(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),I(r),I(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&_(s,c)){var l=N(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,E,f,h=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,E=o<u-1?r[o+1]*i:e.length,f=t(e,s,E,i,!1),f===f.next&&(f.steiner=!0),h.push(p(f));for(h.sort(c),o=0;o<h.length;o++)l(h[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=E(e,t)){var r=N(t,e);n(r,r.next)}}function E(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,E=n.y,f=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&y(i<E?a:o,i,l,E,i<E?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<f||s===f&&r.x>n.x)&&A(r,e)&&(n=r,f=s),r=r.next;return n}function f(e,t,n,r){var a=e;do{null===a.z&&(a.z=d(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,h(a)}function h(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function d(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function p(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function y(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function m(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||m(e,t,n)>0!=m(e,t,r)>0&&m(n,r,e)>0!=m(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return m(e.prev,e,e.next)<0?m(e,t,e.next)>=0&&m(e,e.prev,t)>=0:m(e,t,e.prev)<0||m(e,e.next,t)<0}function S(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function N(e,t){var n=new M(e.i,e.x,e.y),r=new M(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function g(e,t,n,r){var a=new M(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function I(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function M(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function O(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(O(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(O(e,c,l,n))}var E=0;for(u=0;u<r.length;u+=3){var f=r[u]*n,h=r[u+1]*n,d=r[u+2]*n;E+=Math.abs((e[f]-e[d])*(e[h+1]-e[f+1])-(e[f]-e[h])*(e[d+1]-e[f+1]))}return 0===o&&0===E?0:Math.abs((E-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,E,f){"use strict";var h=new n,d=new n,p={};p.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},p.computeWindingOrder2D=function(e){return p.computeArea2D(e)>0?f.COUNTER_CLOCKWISE:f.CLOCKWISE},p.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var y=new n,_=new n,m=new n,T=new n,R=new n,v=new n,A=new n;return p.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var f,h=r.slice(0),d=t.length,p=new Array(3*d),S=0;for(f=0;f<d;f++){var N=t[f];p[S++]=N.x,p[S++]=N.y,p[S++]=N.z}for(var g=[],I={},M=e.maximumRadius,O=l.chordLength(u,M),x=O*O;h.length>0;){var w,C,P=h.pop(),L=h.pop(),b=h.pop(),U=n.fromArray(p,3*b,y),F=n.fromArray(p,3*L,_),D=n.fromArray(p,3*P,m),B=n.multiplyByScalar(n.normalize(U,T),M,T),z=n.multiplyByScalar(n.normalize(F,R),M,R),G=n.multiplyByScalar(n.normalize(D,v),M,v),q=n.magnitudeSquared(n.subtract(B,z,A)),V=n.magnitudeSquared(n.subtract(z,G,A)),X=n.magnitudeSquared(n.subtract(G,B,A)),W=Math.max(q,V,X);W>x?q===W?(w=Math.min(b,L)+" "+Math.max(b,L),f=I[w],o(f)||(C=n.add(U,F,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),f=p.length/3-1,I[w]=f),h.push(b,f,P),h.push(f,L,P)):V===W?(w=Math.min(L,P)+" "+Math.max(L,P),f=I[w],o(f)||(C=n.add(F,D,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),f=p.length/3-1,I[w]=f),h.push(L,f,b),h.push(f,P,b)):X===W&&(w=Math.min(P,b)+" "+Math.max(P,b),f=I[w],o(f)||(C=n.add(D,U,A),n.multiplyByScalar(C,.5,C),p.push(C.x,C.y,C.z),f=p.length/3-1,I[w]=f),h.push(P,f,L),h.push(f,b,L)):(g.push(b),g.push(L),g.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:p})},indices:g,primitiveType:E.TRIANGLES})},p.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=h,c=d;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,E=0;E<l;E+=3)n.fromArray(e,E,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[E]=c.x,e[E+1]=c.y,e[E+2]=c.z;return e},p}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,E=c.z*o,f=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=E,a.w=f,a):new s(u,l,E,f)};var l=[1,2,0],E=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,f=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],d=e[u.COLUMN2ROW2],p=f+h+d;if(p>0)n=Math.sqrt(p+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var y=l,_=0;h>f&&(_=1),d>f&&d>h&&(_=2);var m=y[_],T=y[m];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(m,m)]-e[u.getElementIndex(T,T)]+1);var R=E;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,m)]-e[u.getElementIndex(m,T)])*n,R[m]=(e[u.getElementIndex(m,_)]+e[u.getElementIndex(_,m)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var f=new s,h=new s,d=new s,p=new s;s.fromHeadingPitchRoll=function(t,n){return p=s.fromAxisAngle(e.UNIT_X,t.roll,f),d=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(d,p,d),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,f),s.multiply(h,n,n)};var y=new e,_=new e,m=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),m),s.multiply(m,R,m),m.w<0&&s.negate(m,m),s.computeAxis(m,y);var u=s.computeAngle(m);r[o]=y.x*u,r[o+1]=y.y*u,r[o+2]=y.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,m):s.fromAxisAngle(_,u,m),s.multiply(m,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,E=o*u+r*l+a*c-i*s,f=o*s-r*c+a*l+i*u,h=o*c+r*s-a*u+i*l,d=o*l-r*u-a*s-i*c;return n.x=E,n.y=f,n.z=h,n.w=d,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,S=new s,N=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=A=s.negate(t,A)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),N=s.multiplyByScalar(i,Math.sin(n*u),N),r=s.add(S,N,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var g=new e,I=new e,M=new s,O=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,M);s.multiply(i,r,O);var o=s.log(O,g);s.multiply(i,t,O);var u=s.log(O,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,M),u=s.slerp(n,r,a,O);return s.slerp(o,u,2*a*(1-a),i)};for(var x=new s,w=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],L=a.supportsTypedArrays()?new Float32Array(8):[],b=a.supportsTypedArrays()?new Float32Array(8):[],U=0;U<7;++U){var F=U+1,D=2*F+1;C[U]=1/(F*D),P[U]=F/D}return C[7]=w/136,P[7]=8*w/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,E=7;E>=0;--E)L[E]=(C[E]*c-P[E])*o,b[E]=(C[E]*l-P[E])*o;var f=a*n*(1+L[0]*(1+L[1]*(1+L[2]*(1+L[3]*(1+L[4]*(1+L[5]*(1+L[6]*(1+L[7])))))))),h=u*(1+b[0]*(1+b[1]*(1+b[2]*(1+b[3]*(1+b[4]*(1+b[5]*(1+b[6]*(1+b[7])))))))),d=s.multiplyByScalar(e,h,x);return s.multiplyByScalar(t,f,r),s.add(d,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,M),u=s.fastSlerp(n,r,a,O);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Matrix2",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./freezeObject"],function(e,t,n,r,a,i){"use strict";function o(e,t,r,a){this[0]=n(e,0),this[1]=n(r,0),this[2]=n(t,0),this[3]=n(a,0)}o.packedLength=4,o.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t},o.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new o),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a},o.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):new o(e[0],e[2],e[1],e[3])},o.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new o),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a},o.fromColumnMajorArray=function(e,t){return o.clone(e,t)},o.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[2],t[2]=e[1],t[3]=e[3],t):new o(e[0],e[1],e[2],e[3])},o.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=e.y,t):new o(e.x,0,0,e.y)},o.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=e,t):new o(e,0,0,e)},o.fromRotation=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=-a,t[3]=n,t):new o(n,-a,a,n)},o.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):[e[0],e[1],e[2],e[3]]},o.getElementIndex=function(e,t){return 2*e+t},o.getColumn=function(e,t,n){var r=2*t,a=e[r],i=e[r+1];return n.x=a,n.y=i,n},o.setColumn=function(e,t,n,r){r=o.clone(e,r);var a=2*t;return r[a]=n.x,r[a+1]=n.y,r},o.getRow=function(e,t,n){var r=e[t],a=e[t+2];return n.x=r,n.y=a,n},o.setRow=function(e,t,n,r){return r=o.clone(e,r),r[t]=n.x,r[t+2]=n.y,r};var u=new e;o.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],u)),n.y=e.magnitude(e.fromElements(t[2],t[3],u)),n};var s=new e;return o.getMaximumScale=function(t){return o.getScale(t,s),e.maximumComponent(s)},o.multiply=function(e,t,n){var r=e[0]*t[0]+e[2]*t[1],a=e[0]*t[2]+e[2]*t[3],i=e[1]*t[0]+e[3]*t[1],o=e[1]*t[2]+e[3]*t[3];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n},o.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n},o.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n},o.multiplyByVector=function(e,t,n){var r=e[0]*t.x+e[2]*t.y,a=e[1]*t.x+e[3]*t.y;return n.x=r,n.y=a,n},o.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n},o.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.y,n[3]=e[3]*t.y,n},o.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},o.transpose=function(e,t){var n=e[0],r=e[2],a=e[1],i=e[3];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t},o.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},o.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]},o.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n},o.IDENTITY=i(new o(1,0,0,1)),o.ZERO=i(new o(0,0,0,0)),o.COLUMN0ROW0=0,o.COLUMN0ROW1=1,o.COLUMN1ROW0=2,o.COLUMN1ROW1=3,a(o.prototype,{length:{get:function(){return o.packedLength}}}),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t){return o.equalsEpsilon(this,e,t)},o.prototype.toString=function(){return"("+this[0]+", "+this[2]+")\n("+this[1]+", "+this[3]+")"},o}),define("Core/RectangleGeometryLibrary",["./Cartesian3","./Cartographic","./defined","./DeveloperError","./GeographicProjection","./Math","./Matrix2","./Rectangle"],function(e,t,n,r,a,i,o,u){"use strict";function s(t,n,r,a,i,u,s){var c=Math.cos(n),l=a*c,E=r*c,f=Math.sin(n),p=a*f,m=r*f;d=_.project(t,d),d=e.subtract(d,y,d);var T=o.fromRotation(n,h);d=o.multiplyByVector(T,d,d),d=e.add(d,y,d),t=_.unproject(d,t),u-=1,s-=1;var R=t.latitude,v=R+u*m,A=R-l*s,S=R-l*s+u*m,N=Math.max(R,v,A,S),g=Math.min(R,v,A,S),I=t.longitude,M=I+u*E,O=I+s*p,x=I+s*p+u*E;return{north:N,south:g,east:Math.max(I,M,O,x),west:Math.min(I,M,O,x),granYCos:l,granYSin:p,granXCos:E,granXSin:m,nwCorner:t}}var c=Math.cos,l=Math.sin,E=Math.sqrt,f={};f.computePosition=function(e,t,r,a,i){var o=e.ellipsoid.radiiSquared,u=e.nwCorner,s=e.rectangle,f=u.latitude-e.granYCos*t+r*e.granXSin,h=c(f),d=l(f),p=o.z*d,y=u.longitude+t*e.granYSin+r*e.granXCos,_=h*c(y),m=h*l(y),T=o.x*_,R=o.y*m,v=E(T*_+R*m+p*d);if(a.x=T/v,a.y=R/v,a.z=p/v,n(e.vertexFormat)&&e.vertexFormat.st){var A=e.stNwCorner;n(A)?(f=A.latitude-e.stGranYCos*t+r*e.stGranXSin,y=A.longitude+t*e.stGranYSin+r*e.stGranXCos,i.x=(y-e.stWest)*e.lonScalar,i.y=(f-e.stSouth)*e.latScalar):(i.x=(y-s.west)*e.lonScalar,i.y=(f-s.south)*e.latScalar)}};var h=new o,d=new e,p=new t,y=new e,_=new a;return f.computeOptions=function(e,t,n,r){var a,o,c,l,E,f=e._granularity,h=e._ellipsoid,d=e._surfaceHeight,m=e._rotation,T=e._stRotation,R=e._extrudedHeight,v=t.east,A=t.west,S=t.north,N=t.south,g=S-N;A>v?(E=i.TWO_PI-A+v,a=Math.ceil(E/f)+1,o=Math.ceil(g/f)+1,c=E/(a-1),l=g/(o-1)):(E=v-A,a=Math.ceil(E/f)+1,o=Math.ceil(g/f)+1,c=E/(a-1),l=g/(o-1)),n=u.northwest(t,n);var I=u.center(t,p);0===m&&0===T||(I.longitude<n.longitude&&(I.longitude+=i.TWO_PI),y=_.project(I,y));var M=l,O=c,x={granYCos:M,granYSin:0,granXCos:O,granXSin:0,ellipsoid:h,surfaceHeight:d,extrudedHeight:R,nwCorner:n,rectangle:t,width:a,height:o};if(0!==m){var w=s(n,m,c,l,I,a,o);S=w.north,N=w.south,v=w.east,A=w.west,x.granYCos=w.granYCos,x.granYSin=w.granYSin,x.granXCos=w.granXCos,x.granXSin=w.granXSin,t.north=S,t.south=N,t.east=v,t.west=A}if(0!==T){m-=T,r=u.northwest(t,r);var C=s(r,m,c,l,I,a,o);x.stGranYCos=C.granYCos,x.stGranXCos=C.granXCos,x.stGranYSin=C.granYSin,x.stGranXSin=C.granXSin,x.stNwCorner=r,x.stWest=C.west,x.stSouth=C.south}return x},f}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},a.unpack=function(n,r,i){return r=e(r,0),t(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(e,n){if(t(e))return t(n)||(n=new a),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},a}),define("Core/RectangleGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./ComponentDatatype","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./GeometryInstance","./GeometryPipeline","./IndexDatatype","./Math","./Matrix3","./PolygonPipeline","./PrimitiveType","./Quaternion","./Rectangle","./RectangleGeometryLibrary","./VertexFormat"],function(e,t,n,r,a,i,o,u,s,c,l,E,f,h,d,p,y,_,m,T,R,v,A,S,N){"use strict";function g(e,t){var n=new E({attributes:new h,primitiveType:R.TRIANGLES});return n.attributes.position=new f({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:t.positions}),e.normal&&(n.attributes.normal=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:t.normals})),e.tangent&&(n.attributes.tangent=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:t.tangents})),e.bitangent&&(n.attributes.bitangent=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:t.bitangents})),n}function I(e,t,r,a){var i=e.length,o=t.normal?new Float32Array(i):void 0,u=t.tangent?new Float32Array(i):void 0,s=t.bitangent?new Float32Array(i):void 0,c=0,l=D,E=F,f=U;if(t.normal||t.tangent||t.bitangent)for(var h=0;h<i;h+=3){var d=n.fromArray(e,h,b),p=c+1,y=c+2;f=r.geodeticSurfaceNormal(d,f),(t.tangent||t.bitangent)&&(n.cross(n.UNIT_Z,f,E),m.multiplyByVector(a,E,E),n.normalize(E,E),t.bitangent&&n.normalize(n.cross(f,E,l),l)),t.normal&&(o[c]=f.x,o[p]=f.y,o[y]=f.z),t.tangent&&(u[c]=E.x,u[p]=E.y,u[y]=E.z),t.bitangent&&(s[c]=l.x,s[p]=l.y,s[y]=l.z),c+=3}return g(t,{positions:e,normals:o,tangents:u,bitangents:s})}function M(e,t,r){var a=e.length,i=t.normal?new Float32Array(a):void 0,o=t.tangent?new Float32Array(a):void 0,u=t.bitangent?new Float32Array(a):void 0,s=0,c=0,l=0,E=!0,f=D,h=F,d=U;if(t.normal||t.tangent||t.bitangent)for(var p=0;p<a;p+=6){var y=n.fromArray(e,p,b),m=n.fromArray(e,(p+6)%a,V);if(E){var T=n.fromArray(e,(p+3)%a,X);n.subtract(m,y,m),n.subtract(T,y,T),d=n.normalize(n.cross(T,m,d),d),E=!1}n.equalsEpsilon(m,y,_.EPSILON10)&&(E=!0),(t.tangent||t.bitangent)&&(f=r.geodeticSurfaceNormal(y,f),t.tangent&&(h=n.normalize(n.cross(f,d,h),h))),t.normal&&(i[s++]=d.x,i[s++]=d.y,i[s++]=d.z,i[s++]=d.x,i[s++]=d.y,i[s++]=d.z),t.tangent&&(o[c++]=h.x,o[c++]=h.y,o[c++]=h.z,o[c++]=h.x,o[c++]=h.y,o[c++]=h.z),t.bitangent&&(u[l++]=f.x,u[l++]=f.y,u[l++]=f.z,u[l++]=f.x,u[l++]=f.y,u[l++]=f.z)}return g(t,{positions:e,normals:i,tangents:o,bitangents:u})}function O(e){for(var t=e.vertexFormat,n=e.ellipsoid,r=e.size,a=e.height,o=e.width,u=t.position?new Float64Array(3*r):void 0,s=t.st?new Float32Array(2*r):void 0,c=0,l=0,E=b,h=z,d=Number.MAX_VALUE,p=Number.MAX_VALUE,_=-Number.MAX_VALUE,m=-Number.MAX_VALUE,T=0;T<a;++T)for(var R=0;R<o;++R)S.computePosition(e,T,R,E,h),u[c++]=E.x,u[c++]=E.y,u[c++]=E.z,t.st&&(s[l++]=h.x,s[l++]=h.y,d=Math.min(d,h.x),p=Math.min(p,h.y),_=Math.max(_,h.x),m=Math.max(m,h.y));if(t.st&&(d<0||p<0||_>1||m>1))for(var v=0;v<s.length;v+=2)s[v]=(s[v]-d)/(_-d),s[v+1]=(s[v+1]-p)/(m-p);for(var A=I(u,t,n,e.tangentRotationMatrix),N=6*(o-1)*(a-1),g=y.createTypedArray(r,N),M=0,O=0,x=0;x<a-1;++x){for(var w=0;w<o-1;++w){var C=M,P=C+o,L=P+1,U=C+1;g[O++]=C,g[O++]=P,g[O++]=U,g[O++]=U,g[O++]=P,g[O++]=L,++M}++M}return A.indices=g,t.st&&(A.attributes.st=new f({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:s})),A}function x(e,t,n,r,a){return e[t++]=r[n],e[t++]=r[n+1],e[t++]=r[n+2],e[t++]=a[n],e[t++]=a[n+1],e[t++]=a[n+2],e}function w(e,t,n,r){return e[t++]=r[n],e[t++]=r[n+1],e[t++]=r[n],e[t++]=r[n+1],e}function C(e){var t,r=e.shadowVolume,a=e.vertexFormat,o=e.surfaceHeight,u=e.extrudedHeight,s=Math.min(u,o),c=Math.max(u,o),l=e.height,E=e.width,h=e.ellipsoid;r&&(e.vertexFormat=N.clone(a,W),e.vertexFormat.normal=!0);var m=O(e);if(_.equalsEpsilon(s,c,_.EPSILON10))return m;var R=T.scaleToGeodeticHeight(m.attributes.position.values,c,h,!1);R=new Float64Array(R);var v=R.length,A=2*v,S=new Float64Array(A);S.set(R);var g=T.scaleToGeodeticHeight(m.attributes.position.values,s,h);S.set(g,v),m.attributes.position.values=S;var I,C,P=a.normal?new Float32Array(A):void 0,L=a.tangent?new Float32Array(A):void 0,b=a.bitangent?new Float32Array(A):void 0,U=a.st?new Float32Array(A/3*2):void 0;if(a.normal){for(C=m.attributes.normal.values,P.set(C),t=0;t<v;t++)C[t]=-C[t];P.set(C,v),m.attributes.normal.values=P}if(r){C=m.attributes.normal.values,a.normal||(m.attributes.normal=void 0);var F=new Float32Array(A);for(t=0;t<v;t++)C[t]=-C[t];F.set(C,v),m.attributes.extrudeDirection=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:F})}if(a.tangent){var D=m.attributes.tangent.values;for(L.set(D),t=0;t<v;t++)D[t]=-D[t];L.set(D,v),m.attributes.tangent.values=L}if(a.bitangent){var B=m.attributes.bitangent.values;b.set(B),b.set(B,v),m.attributes.bitangent.values=b}a.st&&(I=m.attributes.st.values,U.set(I),U.set(I,v/3*2),m.attributes.st.values=U);var z=m.indices,G=z.length,q=v/3,H=y.createTypedArray(A/3,2*G);for(H.set(z),t=0;t<G;t+=3)H[t+G]=z[t+2]+q,H[t+1+G]=z[t+1]+q,H[t+2+G]=z[t]+q;m.indices=H;var Y,k=2*E+2*l-4,Z=2*(k+4),K=new Float64Array(3*Z),j=r?new Float32Array(3*Z):void 0,Q=a.st?new Float32Array(2*Z):void 0,J=0,$=0,ee=0,te=E*l;for(t=0;t<te;t+=E)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);for(t=te-E;t<te;t++)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);for(t=te-1;t>0;t-=E)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);for(t=E-1;t>=0;t--)Y=3*t,K=x(K,J,Y,R,g),J+=6,a.st&&(Q=w(Q,$,2*t,I),$+=4),r&&(ee+=3,j[ee++]=C[Y],j[ee++]=C[Y+1],j[ee++]=C[Y+2]);var ne=M(K,a,h);a.st&&(ne.attributes.st=new f({componentDatatype:i.FLOAT,componentsPerAttribute:2,values:Q})),r&&(ne.attributes.extrudeDirection=new f({componentDatatype:i.FLOAT,componentsPerAttribute:3,values:j}));var re,ae,ie,oe,ue=y.createTypedArray(Z,6*k);v=K.length/3;var se=0;for(t=0;t<v-1;t+=2){re=t,oe=(re+2)%v;var ce=n.fromArray(K,3*re,V),le=n.fromArray(K,3*oe,X);n.equalsEpsilon(ce,le,_.EPSILON10)||(ae=(re+1)%v,ie=(ae+2)%v,ue[se++]=re,ue[se++]=ae,ue[se++]=oe,ue[se++]=oe,ue[se++]=ae,ue[se++]=ie)}return ne.indices=ue,ne=p.combineInstances([new d({geometry:m}),new d({geometry:ne})]),ne[0]}function P(e,t,n){if(0===n)return A.clone(e);A.northeast(e,K[0]),A.northwest(e,K[1]),A.southeast(e,K[2]),A.southwest(e,K[3]),t.cartographicArrayToCartesianArray(K,Z);var r=t.geodeticSurfaceNormalCartographic(A.center(e,Y));v.fromAxisAngle(r,n,k),m.fromQuaternion(k,H);for(var a=0;a<4;++a)m.multiplyByVector(H,Z[a],Z[a]);return t.cartesianArrayToCartographicArray(Z,K),A.fromCartographicArray(K)}function L(e){e=o(e,o.EMPTY_OBJECT);var t=e.rectangle,n=o(e.rotation,0);this._rectangle=t,this._granularity=o(e.granularity,_.RADIANS_PER_DEGREE),this._ellipsoid=l.clone(o(e.ellipsoid,l.WGS84)),this._surfaceHeight=o(e.height,0),this._rotation=n,this._stRotation=o(e.stRotation,0),this._vertexFormat=N.clone(o(e.vertexFormat,N.DEFAULT)),this._extrudedHeight=o(e.extrudedHeight,0),this._extrude=u(e.extrudedHeight),this._closeTop=o(e.closeTop,!0),this._closeBottom=o(e.closeBottom,!0),this._shadowVolume=o(e.shadowVolume,!1),this._workerName="createRectangleGeometry",this._rotatedRectangle=P(this._rectangle,this._ellipsoid,n)}var b=new n,U=new n,F=new n,D=new n,B=new A,z=new t,G=new e,q=new e,V=new n,X=new n,W=new N,H=new m,Y=new n,k=new v,Z=[new n,new n,new n,new n],K=[new r,new r,new r,new r];L.packedLength=A.packedLength+l.packedLength+N.packedLength+A.packedLength+9,L.pack=function(e,t,n){return n=o(n,0),A.pack(e._rectangle,t,n),n+=A.packedLength,l.pack(e._ellipsoid,t,n),n+=l.packedLength,N.pack(e._vertexFormat,t,n),n+=N.packedLength,A.pack(e._rotatedRectangle,t,n),n+=A.packedLength,t[n++]=e._granularity,t[n++]=e._surfaceHeight,t[n++]=e._rotation,t[n++]=e._stRotation,t[n++]=e._extrudedHeight,t[n++]=e._extrude?1:0,t[n++]=e._closeTop?1:0,t[n++]=e._closeBottom?1:0,t[n]=e._shadowVolume?1:0,t};var j=new A,Q=new A,J=l.clone(l.UNIT_SPHERE),$={rectangle:j,ellipsoid:J,vertexFormat:W,granularity:void 0,height:void 0,rotation:void 0,stRotation:void 0,extrudedHeight:void 0,closeTop:void 0,closeBottom:void 0,shadowVolume:void 0};L.unpack=function(e,t,n){t=o(t,0);var r=A.unpack(e,t,j);t+=A.packedLength;var a=l.unpack(e,t,J);t+=l.packedLength;var i=N.unpack(e,t,W);t+=N.packedLength;var s=A.unpack(e,t,Q);t+=A.packedLength;var c=e[t++],E=e[t++],f=e[t++],h=e[t++],d=e[t++],p=1===e[t++],y=1===e[t++],_=1===e[t++],m=1===e[t];return u(n)?(n._rectangle=A.clone(r,n._rectangle),n._ellipsoid=l.clone(a,n._ellipsoid),n._vertexFormat=N.clone(i,n._vertexFormat),n._granularity=c,n._surfaceHeight=E,n._rotation=f,n._stRotation=h,n._extrudedHeight=p?d:void 0,n._extrude=p,n._closeTop=y,n._closeBottom=_,n._rotatedRectangle=s,n._shadowVolume=m,n):($.granularity=c,$.height=E,$.rotation=f,$.stRotation=h,$.extrudedHeight=p?d:void 0,$.closeTop=y,$.closeBottom=_,$.shadowVolume=m,new L($))};var ee=new m,te=new r,ne=new r,re=new v,ae=new r;return L.createGeometry=function(t){if(!_.equalsEpsilon(t._rectangle.north,t._rectangle.south,_.EPSILON10)&&!_.equalsEpsilon(t._rectangle.east,t._rectangle.west,_.EPSILON10)){var n=A.clone(t._rectangle,B),r=t._ellipsoid,a=t._surfaceHeight,i=t._extrude,o=t._extrudedHeight,u=t._rotation,s=t._stRotation,c=t._vertexFormat,l=S.computeOptions(t,n,te,ne),f=ee;if(0!==s||0!==u){var h=A.center(n,ae),d=r.geodeticSurfaceNormalCartographic(h,V);v.fromAxisAngle(d,-s,re),m.fromQuaternion(re,f)}else m.clone(m.IDENTITY,f);l.lonScalar=1/t._rectangle.width,l.latScalar=1/t._rectangle.height,l.vertexFormat=c,l.rotation=u,l.stRotation=s,l.tangentRotationMatrix=f,l.size=l.width*l.height;var p,y;if(n=t._rectangle,i){l.shadowVolume=t._shadowVolume,p=C(l);var R=e.fromRectangle3D(n,r,a,q),N=e.fromRectangle3D(n,r,o,G);y=e.union(R,N)}else p=O(l),p.attributes.position.values=T.scaleToGeodeticHeight(p.attributes.position.values,a,r,!1),y=e.fromRectangle3D(n,r,a);return c.position||delete p.attributes.position,new E({attributes:p.attributes,indices:p.indices,primitiveType:p.primitiveType,boundingSphere:y})}},L.createShadowVolume=function(e,t,n){var r=e._granularity,a=e._ellipsoid,i=t(r,a),o=n(r,a);return new L({rectangle:e._rectangle,rotation:e._rotation,ellipsoid:a,stRotation:e._stRotation,granularity:r,extrudedHeight:o,height:i,closeTop:!0,closeBottom:!0, +vertexFormat:N.POSITION_ONLY,shadowVolume:!0})},s(L.prototype,{rectangle:{get:function(){return this._rotatedRectangle}}}),L}),define("Workers/createRectangleGeometry",["../Core/defined","../Core/Ellipsoid","../Core/Rectangle","../Core/RectangleGeometry"],function(e,t,n,r){"use strict";function a(a,i){return e(i)&&(a=r.unpack(a,i)),a._ellipsoid=t.clone(a._ellipsoid),a._rectangle=n.clone(a._rectangle),r.createGeometry(a)}return a})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleOutlineGeometry.js index 82eeb638..bb76f8ba 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createRectangleOutlineGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,E),o.normalize(t,c);var n=o.dot(E,c),r=o.magnitude(o.cross(E,c,E));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,E=i*s-a*u,c=a*o-r*s,_=r*u-i*o;return n.x=E,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var l=new o,f=new o,T=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:T,E=Math.cos(r);l.x=E*Math.cos(e),l.y=E*Math.sin(e),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,f);var c=Math.sqrt(o.dot(l,f));return f=o.divideByScalar(f,c,f),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(f,l,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],E=a/2;r[E]=o.fromDegrees(u,s,0,t,r[E])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],E=a/2;r[E]=o.fromRadians(u,s,0,t,r[E])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],E=e[a+2],c=a/3;r[c]=o.fromDegrees(u,s,E,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],E=e[a+2],c=a/3;r[c]=o.fromRadians(u,s,E,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,E){var c=n.x,_=n.y,l=n.z,f=i.x,T=i.y,R=i.z,h=c*c*f*f,d=_*_*T*T,A=l*l*R*R,N=h+d+A,y=Math.sqrt(1/N),S=e.multiplyByScalar(n,y,a);if(N<s)return isFinite(y)?e.clone(S,E):void 0;var I=u.x,p=u.y,m=u.z,M=o;M.x=S.x*I*2,M.y=S.y*p*2,M.z=S.z*m*2;var O,x,C,g,v,U,L,w,P,F,D,B=(1-y)*e.magnitude(n)/(.5*e.magnitude(M)),z=0;do{B-=z,C=1/(1+B*I),g=1/(1+B*p),v=1/(1+B*m),U=C*C,L=g*g,w=v*v,P=U*C,F=L*g,D=w*v,O=h*U+d*L+A*w-1,x=h*P*I+d*F*p+A*D*m;z=O/(-2*x)}while(Math.abs(O)>r.EPSILON12);return t(E)?(E.x=c*C,E.y=_*g,E.z=l*v,E):new e(c*C,_*g,l*v)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,E=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),l=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),f=a.EPSILON1;return u.fromCartesian=function(t,n,i){var T=r(n)?n.oneOverRadii:_,R=r(n)?n.oneOverRadiiSquared:l,h=r(n)?n._centerToleranceSquared:f,d=o(t,T,R,h,E);if(r(d)){var A=e.multiplyComponents(d,R,s);A=e.normalize(A,A);var N=e.subtract(t,d,c),y=Math.atan2(A.y,A.x),S=Math.asin(A.z),I=a.sign(e.dot(N,t))*e.magnitude(N);return r(i)?(i.longitude=y,i.latitude=S,i.height=I,i):new u(y,S,I)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,E){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),E=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=E,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var l=new e,f=new e;_.prototype.cartographicToCartesian=function(t,n){var r=l,a=f;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var T=new e,R=new e,h=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,R);if(i(a)){var o=this.geodeticSurfaceNormal(a,T),u=e.subtract(n,a,h),E=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=E,r.latitude=c,r.height=_,r):new t(E,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return E(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,E=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,l=e.length;_<l;_++){var f=e[_];n=Math.min(n,f.longitude),i=Math.max(i,f.longitude),E=Math.min(E,f.latitude),c=Math.max(c,f.latitude);var T=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;a=Math.min(a,T),o=Math.max(o,T)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=E,t.east=i,t.north=c,t):new s(n,E,i,c)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,E=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,T=0,R=e.length;T<R;T++){var h=t.cartesianToCartographic(e[T]);o=Math.min(o,h.longitude),E=Math.max(E,h.longitude),l=Math.min(l,h.latitude),f=Math.max(f,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;c=Math.min(c,d),_=Math.max(_,d)}return E-o>_-c&&(o=c,E=_,E>u.PI&&(E-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=E,i.north=f,i):new s(o,l,E,f)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,E=t.west;i<a&&o>0?i+=u.TWO_PI:o<E&&i>0&&(o+=u.TWO_PI),i<a&&E<0?E+=u.TWO_PI:o<E&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,E)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var l=Math.max(e.south,t.south),f=Math.min(e.north,t.north);if(!(l>=f))return r(n)?(n.west=c,n.south=l,n.east=_,n.north=f,n):new s(c,l,_,f)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,E=t.west;i<a&&o>0?i+=u.TWO_PI:o<E&&i>0&&(o+=u.TWO_PI),i<a&&E<0?E+=u.TWO_PI:o<E&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,E)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var E=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,l=e.south,f=e.east,T=e.west,R=E;R.height=i,R.longitude=T,R.latitude=_,o[c]=t.cartographicToCartesian(R,o[c]),c++,R.longitude=f,o[c]=t.cartographicToCartesian(R,o[c]),c++,R.latitude=l,o[c]=t.cartographicToCartesian(R,o[c]),c++,R.longitude=T,o[c]=t.cartographicToCartesian(R,o[c]),c++,R.latitude=_<0?_:l>0?l:0;for(var h=1;h<8;++h)R.longitude=-Math.PI+h*u.PI_OVER_TWO,s.contains(e,R)&&(o[c]=t.cartographicToCartesian(R,o[c]),c++);return 0===R.latitude&&(R.longitude=T,o[c]=t.cartographicToCartesian(R,o[c]),c++,R.longitude=f,o[c]=t.cartographicToCartesian(R,o[c]),c++),o.length=c,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,E){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(E,0)}function E(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(R[n],T[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(R[a],T[a])]);o>r&&(i=a,r=o)}var E=1,c=0,_=T[i],l=R[i];if(Math.abs(e[s.getElementIndex(l,_)])>n){var f,h=e[s.getElementIndex(l,l)],d=e[s.getElementIndex(_,_)],A=e[s.getElementIndex(l,_)],N=(h-d)/2/A;f=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),E=1/Math.sqrt(1+f*f),c=f*E}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(_,_)]=t[s.getElementIndex(l,l)]=E,t[s.getElementIndex(l,_)]=c,t[s.getElementIndex(_,l)]=-c,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,E=e.y*e.z,c=e.y*e.w,_=e.z*e.z,l=e.z*e.w,f=e.w*e.w,T=n-u-_+f,R=2*(i-l),h=2*(a+c),d=2*(i+l),A=-n+u-_+f,N=2*(E-o),y=2*(a-c),S=2*(E+o),I=-n-u+_+f;return r(t)?(t[0]=T,t[1]=d,t[2]=y,t[3]=R,t[4]=A,t[5]=S,t[6]=h,t[7]=N,t[8]=I,t):new s(T,R,h,d,A,N,y,S,I)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),E=Math.sin(e.roll),c=n*i,_=-a*u+E*o*i,l=E*u+a*o*i,f=n*u,T=a*i+E*o*u,R=-E*i+a*o*u,h=-o,d=E*n,A=a*n;return r(t)?(t[0]=c,t[1]=f,t[2]=h,t[3]=_,t[4]=T,t[5]=d,t[6]=l,t[7]=R,t[8]=A,t):new s(c,_,l,f,T,R,h,d,A)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var l=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],l)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],l)),n};var f=new e;s.getMaximumScale=function(t){return s.getScale(t,f),e.maximumComponent(f)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],E=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=E,n[7]=c,n[8]=_,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],E=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=E,t[8]=c,t};var T=[1,0,0],R=[2,2,1],h=new s,d=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),l=t.diagonal=s.clone(e,t.diagonal),f=n*E(l);a<10&&c(l)>f;)_(l,h),s.transpose(h,d),s.multiply(l,h,l),s.multiply(d,l,l),s.multiply(o,h,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],E=e[8];return t*(a*E-s*o)+i*(s*r-n*E)+u*(n*o-a*r)},s.inverse=function(e,t){ -var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],E=e[6],c=e[7],_=e[8],l=s.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=E*u-a*_,t[4]=n*_-E*i,t[5]=a*i-n*u,t[6]=a*c-E*o,t[7]=E*r-n*c,t[8]=n*o-a*r;var f=1/l;return s.multiplyByScalar(t,f,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,E);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,E){"use strict";function c(e,t,n,i,a,o,u,s,E,c,_,l,f,T,R,h){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(E,0),this[3]=r(f,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(T,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(R,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(h,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,E=t.x*t.y,_=t.x*t.z,l=t.x*t.w,f=t.y*t.y,T=t.y*t.z,R=t.y*t.w,h=t.z*t.z,d=t.z*t.w,A=t.w*t.w,N=s-f-h+A,y=2*(E-d),S=2*(_+R),I=2*(E+d),p=-s+f-h+A,m=2*(T-l),M=2*(_-R),O=2*(T+l),x=-s-f+h+A;return r[0]=N*a,r[1]=I*a,r[2]=M*a,r[3]=0,r[4]=y*o,r[5]=p*o,r[6]=O*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=x*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(s.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,l=new e,f=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,l),l),e.normalize(e.cross(l,_,f),f);var u=l.x,s=l.y,E=l.z,T=_.x,R=_.y,h=_.z,d=f.x,A=f.y,N=f.z,y=r.x,S=r.y,I=r.z,p=u*-y+s*-S+E*-I,m=d*-y+A*-S+N*-I,M=T*y+R*S+h*I;return i(n)?(n[0]=u,n[1]=d,n[2]=-T,n[3]=0,n[4]=s,n[5]=A,n[6]=-R,n[7]=0,n[8]=E,n[9]=N,n[10]=-h,n[11]=0,n[12]=p,n[13]=m,n[14]=M,n[15]=1,n):new c(u,s,E,p,d,A,N,m,-T,-R,-h,M,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),E=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=E,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),E=1/(a-i),c=-(t+e)*u,_=-(r+n)*s,l=-(a+i)*E;return u*=2,s*=2,E*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=E,o[11]=0,o[12]=c,o[13]=_,o[14]=l,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),E=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=E,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),E=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=E,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var E=.5*u,c=.5*s,_=.5*(n-t),l=E,f=c,T=_,R=a+E,h=o+c,d=t+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=f,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=T,i[11]=0,i[12]=R,i[13]=h,i[14]=d,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var T=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],T)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],T)),n};var R=new e;c.getMaximumScale=function(t){return c.getScale(t,R),e.maximumComponent(R)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],E=e[6],c=e[7],_=e[8],l=e[9],f=e[10],T=e[11],R=e[12],h=e[13],d=e[14],A=e[15],N=t[0],y=t[1],S=t[2],I=t[3],p=t[4],m=t[5],M=t[6],O=t[7],x=t[8],C=t[9],g=t[10],v=t[11],U=t[12],L=t[13],w=t[14],P=t[15],F=r*N+u*y+_*S+R*I,D=i*N+s*y+l*S+h*I,B=a*N+E*y+f*S+d*I,z=o*N+c*y+T*S+A*I,G=r*p+u*m+_*M+R*O,b=i*p+s*m+l*M+h*O,X=a*p+E*m+f*M+d*O,q=o*p+c*m+T*M+A*O,V=r*x+u*C+_*g+R*v,H=i*x+s*C+l*g+h*v,W=a*x+E*C+f*g+d*v,Y=o*x+c*C+T*g+A*v,k=r*U+u*L+_*w+R*P,Z=i*U+s*L+l*w+h*P,K=a*U+E*L+f*w+d*P,j=o*U+c*L+T*w+A*P;return n[0]=F,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=q,n[8]=V,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=Z,n[14]=K,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],E=e[8],c=e[9],_=e[10],l=e[12],f=e[13],T=e[14],R=t[0],h=t[1],d=t[2],A=t[4],N=t[5],y=t[6],S=t[8],I=t[9],p=t[10],m=t[12],M=t[13],O=t[14],x=r*R+o*h+E*d,C=i*R+u*h+c*d,g=a*R+s*h+_*d,v=r*A+o*N+E*y,U=i*A+u*N+c*y,L=a*A+s*N+_*y,w=r*S+o*I+E*p,P=i*S+u*I+c*p,F=a*S+s*I+_*p,D=r*m+o*M+E*O+l,B=i*m+u*M+c*O+f,z=a*m+s*M+_*O+T;return n[0]=x,n[1]=C,n[2]=g,n[3]=0,n[4]=v,n[5]=U,n[6]=L,n[7]=0,n[8]=w,n[9]=P,n[10]=F,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],E=e[8],c=e[9],_=e[10],l=t[0],f=t[1],T=t[2],R=t[3],h=t[4],d=t[5],A=t[6],N=t[7],y=t[8],S=r*l+o*f+E*T,I=i*l+u*f+c*T,p=a*l+s*f+_*T,m=r*R+o*h+E*d,M=i*R+u*h+c*d,O=a*R+s*h+_*d,x=r*A+o*N+E*y,C=i*A+u*N+c*y,g=a*A+s*N+_*y;return n[0]=S,n[1]=I,n[2]=p,n[3]=0,n[4]=m,n[5]=M,n[6]=O,n[7]=0,n[8]=x,n[9]=C,n[10]=g,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var h=new e;c.multiplyByUniformScale=function(e,t,n){return h.x=t,h.y=t,h.z=t,c.multiplyByScale(e,h,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,E=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=E,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var d=new s,A=new s,N=new t,y=new t(0,0,0,1);return c.inverse=function(e,n){if(s.equalsEpsilon(c.getRotation(e,d),A,u.EPSILON7)&&t.equals(c.getRow(e,3,N),y))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],l=e[5],f=e[9],T=e[13],R=e[2],h=e[6],S=e[10],I=e[14],p=e[3],m=e[7],M=e[11],O=e[15],x=S*O,C=I*M,g=h*O,v=I*m,U=h*M,L=S*m,w=R*O,P=I*p,F=R*M,D=S*p,B=R*m,z=h*p,G=x*l+v*f+U*T-(C*l+g*f+L*T),b=C*_+w*f+D*T-(x*_+P*f+F*T),X=g*_+P*l+B*T-(v*_+w*l+z*T),q=L*_+F*l+z*f-(U*_+D*l+B*f),V=C*i+g*a+L*o-(x*i+v*a+U*o),H=x*r+P*a+F*o-(C*r+w*a+D*o),W=v*r+w*i+z*o-(g*r+P*i+B*o),Y=U*r+D*i+B*a-(L*r+F*i+z*a);x=a*T,C=o*f,g=i*T,v=o*l,U=i*f,L=a*l,w=r*T,P=o*_,F=r*f,D=a*_,B=r*l,z=i*_;var k=x*m+v*M+U*O-(C*m+g*M+L*O),Z=C*p+w*M+D*O-(x*p+P*M+F*O),K=g*p+P*m+B*O-(v*p+w*m+z*O),j=L*p+F*m+z*M-(U*p+D*m+B*M),Q=g*S+L*I+C*h-(U*I+x*h+v*S),J=F*I+x*R+P*S-(w*S+D*I+C*R),$=w*h+z*I+v*R-(B*I+g*R+P*h),ee=B*S+U*R+D*h-(F*h+z*S+L*R),te=r*G+i*b+a*X+o*q;if(Math.abs(te)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=q*te,n[4]=V*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=K*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],E=e[9],c=e[10],_=e[12],l=e[13],f=e[14],T=-n*_-r*l-i*f,R=-a*_-o*l-u*f,h=-s*_-E*l-c*f;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=E,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=T,t[13]=R,t[14]=h,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,E,c,_){"use strict";function l(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var f=new e,T=new e,R=new e,h=new e,d=new e,A=new e,N=new e,y=new e,S=new e,I=new e,p=new e,m=new e;l.fromPoints=function(t,n){if(i(n)||(n=new l),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],N),o=e.clone(a,f),u=e.clone(a,T),s=e.clone(a,R),E=e.clone(a,h),c=e.clone(a,d),_=e.clone(a,A),M=t.length;for(r=1;r<M;r++){e.clone(t[r],a);var O=a.x,x=a.y,C=a.z;O<o.x&&e.clone(a,o),O>E.x&&e.clone(a,E),x<u.y&&e.clone(a,u),x>c.y&&e.clone(a,c),C<s.z&&e.clone(a,s),C>_.z&&e.clone(a,_)}var g=e.magnitudeSquared(e.subtract(E,o,y)),v=e.magnitudeSquared(e.subtract(c,u,y)),U=e.magnitudeSquared(e.subtract(_,s,y)),L=o,w=E,P=g;v>P&&(P=v,L=u,w=c),U>P&&(P=U,L=s,w=_);var F=S;F.x=.5*(L.x+w.x),F.y=.5*(L.y+w.y),F.z=.5*(L.z+w.z);var D=e.magnitudeSquared(e.subtract(w,F,y)),B=Math.sqrt(D),z=I;z.x=o.x,z.y=u.y,z.z=s.z;var G=p;G.x=E.x,G.y=c.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,y),.5,m),X=0;for(r=0;r<M;r++){e.clone(t[r],a);var q=e.magnitude(e.subtract(a,b,y));q>X&&(X=q);var V=e.magnitudeSquared(e.subtract(a,F,y));if(V>D){var H=Math.sqrt(V);B=.5*(B+H),D=B*B;var W=H-B;F.x=(B*F.x+W*a.x)/H,F.y=(B*F.y+W*a.y)/H,F.z=(B*F.z+W*a.z)/H}}return B<X?(e.clone(F,n.center),n.radius=B):(e.clone(b,n.center),n.radius=X),n};var M=new o,O=new e,x=new e,C=new t,g=new t;l.fromRectangle2D=function(e,t,n){return l.fromRectangleWithHeights2D(e,t,0,0,n)},l.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new l),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,M),_.southwest(t,C),C.height=a,_.northeast(t,g),g.height=o;var s=n.project(C,O),E=n.project(g,x),c=E.x-s.x,f=E.y-s.y,T=E.z-s.z;u.radius=.5*Math.sqrt(c*c+f*f+T*T);var R=u.center;return R.x=s.x+.5*c,R.y=s.y+.5*f,R.z=s.z+.5*T,u};var v=[];l.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new l),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=_.subsample(t,n,o,v);return l.fromPoints(s,u)},l.fromVertices=function(t,n,a,o){if(i(o)||(o=new l),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=N;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,E=e.clone(u,f),c=e.clone(u,T),_=e.clone(u,R),M=e.clone(u,h),O=e.clone(u,d),x=e.clone(u,A),C=t.length;for(s=0;s<C;s+=a){var g=t[s]+n.x,v=t[s+1]+n.y,U=t[s+2]+n.z;u.x=g,u.y=v,u.z=U,g<E.x&&e.clone(u,E),g>M.x&&e.clone(u,M),v<c.y&&e.clone(u,c),v>O.y&&e.clone(u,O),U<_.z&&e.clone(u,_),U>x.z&&e.clone(u,x)}var L=e.magnitudeSquared(e.subtract(M,E,y)),w=e.magnitudeSquared(e.subtract(O,c,y)),P=e.magnitudeSquared(e.subtract(x,_,y)),F=E,D=M,B=L;w>B&&(B=w,F=c,D=O),P>B&&(B=P,F=_,D=x);var z=S;z.x=.5*(F.x+D.x),z.y=.5*(F.y+D.y),z.z=.5*(F.z+D.z);var G=e.magnitudeSquared(e.subtract(D,z,y)),b=Math.sqrt(G),X=I;X.x=E.x,X.y=c.y,X.z=_.z;var q=p;q.x=M.x,q.y=O.y,q.z=x.z;var V=e.multiplyByScalar(e.add(X,q,y),.5,m),H=0;for(s=0;s<C;s+=a){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var W=e.magnitude(e.subtract(u,V,y));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,y));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var Z=k-b;z.x=(b*z.x+Z*u.x)/k,z.y=(b*z.y+Z*u.y)/k,z.z=(b*z.z+Z*u.z)/k}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(V,o.center),o.radius=H),o},l.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new l),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=N;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,f),s=e.clone(a,T),E=e.clone(a,R),c=e.clone(a,h),_=e.clone(a,d),M=e.clone(a,A),O=t.length;for(o=0;o<O;o+=3){var x=t[o]+n[o],C=t[o+1]+n[o+1],g=t[o+2]+n[o+2];a.x=x,a.y=C,a.z=g,x<u.x&&e.clone(a,u),x>c.x&&e.clone(a,c),C<s.y&&e.clone(a,s),C>_.y&&e.clone(a,_),g<E.z&&e.clone(a,E),g>M.z&&e.clone(a,M)}var v=e.magnitudeSquared(e.subtract(c,u,y)),U=e.magnitudeSquared(e.subtract(_,s,y)),L=e.magnitudeSquared(e.subtract(M,E,y)),w=u,P=c,F=v;U>F&&(F=U,w=s,P=_),L>F&&(F=L,w=E,P=M);var D=S;D.x=.5*(w.x+P.x),D.y=.5*(w.y+P.y),D.z=.5*(w.z+P.z);var B=e.magnitudeSquared(e.subtract(P,D,y)),z=Math.sqrt(B),G=I;G.x=u.x,G.y=s.y,G.z=E.z;var b=p;b.x=c.x,b.y=_.y,b.z=M.z;var X=e.multiplyByScalar(e.add(G,b,y),.5,m),q=0;for(o=0;o<O;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var V=e.magnitude(e.subtract(a,X,y));V>q&&(q=V);var H=e.magnitudeSquared(e.subtract(a,D,y));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*a.x)/W,D.y=(z*D.y+Y*a.y)/W,D.z=(z*D.z+Y*a.z)/W}}return z<q?(e.clone(D,r.center),r.radius=z):(e.clone(X,r.center),r.radius=q),r},l.fromCornerPoints=function(t,n,r){i(r)||(r=new l);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},l.fromEllipsoid=function(t,n){return i(n)||(n=new l),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;l.fromBoundingSpheres=function(t,n){if(i(n)||(n=new l),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return l.clone(t[0],n);if(2===r)return l.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=l.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var E=t[a];s=Math.max(s,e.distance(u,E.center,U)+E.radius)}return n.radius=s,n};var L=new e,w=new e,P=new e;l.fromOrientedBoundingBox=function(t,n){i(n)||(n=new l);var r=t.halfAxes,a=E.getColumn(r,0,L),o=E.getColumn(r,1,w),u=E.getColumn(r,2,P);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},l.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new l(t.center,t.radius)},l.packedLength=4,l.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},l.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new l);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var F=new e,D=new e;l.union=function(t,n,r){i(r)||(r=new l);var a=t.center,o=t.radius,u=n.center,s=n.radius,E=e.subtract(u,a,F),c=e.magnitude(E);if(o>=c+s)return t.clone(r),r;if(s>=c+o)return n.clone(r),r;var _=.5*(o+c+s),f=e.multiplyByScalar(E,(-o+_)/c,D);return e.add(f,a,f),e.clone(f,r.center),r.radius=_,r};var B=new e;l.expand=function(t,n,r){r=l.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,B));return i>r.radius&&(r.radius=i),r},l.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},l.transform=function(e,t,n){return i(n)||(n=new l),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var z=new e;l.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,z);return e.magnitudeSquared(r)-t.radius*t.radius},l.transformWithoutScale=function(e,t,n){return i(n)||(n=new l),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;l.computePlaneDistances=function(t,n,r,a){i(a)||(a=new s);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,q=new e,V=new e,H=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return l.projectTo2D=function(t,n,i){n=r(n,Z);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,b),E=e.cross(e.UNIT_Z,s,X);e.normalize(E,E);var c=e.cross(s,E,q);e.normalize(c,c),e.multiplyByScalar(s,u,s),e.multiplyByScalar(c,u,c),e.multiplyByScalar(E,u,E);var _=e.negate(c,H),f=e.negate(E,V),T=Y,R=T[0];e.add(s,c,R),e.add(R,E,R),R=T[1],e.add(s,c,R),e.add(R,f,R),R=T[2],e.add(s,_,R),e.add(R,f,R),R=T[3],e.add(s,_,R),e.add(R,E,R),e.negate(s,s),R=T[4],e.add(s,c,R),e.add(R,E,R),R=T[5],e.add(s,c,R),e.add(R,f,R),R=T[6],e.add(s,_,R),e.add(R,f,R),R=T[7],e.add(s,_,R),e.add(R,E,R);for(var h=T.length,d=0;d<h;++d){var A=T[d];e.add(o,A,A);var N=a.cartesianToCartographic(A,W);n.project(N,A)}i=l.fromPoints(T,i),o=i.center;var y=o.x,S=o.y,I=o.z;return o.x=I,o.y=y,o.z=S,i},l.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},l.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},l.prototype.intersectPlane=function(e){return l.intersectPlane(this,e)},l.prototype.distanceSquaredTo=function(e){return l.distanceSquaredTo(this,e)},l.prototype.computePlaneDistances=function(e,t,n){return l.computePlaneDistances(this,e,t,n)},l.prototype.isOccluded=function(e){return l.isOccluded(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.prototype.clone=function(e){return l.clone(this,e)},l}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!l())){var e=/ Chrome\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(S=!0,I=r(e[1]))}return S}function a(){return i()&&I}function o(){if(!t(p)&&(p=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(y.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(p=!0,m=r(e[1]))}return p}function u(){return o()&&m}function s(){if(!t(M)){M=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(y.userAgent);null!==e&&(M=!0,O=r(e[1]),O.isNightly=!!e[2])}return M}function E(){return s()&&O}function c(){if(!t(x)){x=!1;var e;"Microsoft Internet Explorer"===y.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(y.userAgent))&&(x=!0, -C=r(e[1])):"Netscape"===y.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(y.userAgent))&&(x=!0,C=r(e[1]))}return x}function _(){return c()&&C}function l(){if(!t(g)){g=!1;var e=/ Edge\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(g=!0,v=r(e[1]))}return g}function f(){return l()&&v}function T(){if(!t(U)){U=!1;var e=/Firefox\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(U=!0,L=r(e[1]))}return U}function R(){return t(w)||(w=/Windows/i.test(y.appVersion)),w}function h(){return T()&&L}function d(){return t(P)||(P="undefined"!=typeof PointerEvent&&(!t(y.pointerEnabled)||y.pointerEnabled)),P}function A(){if(!t(D)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;D=t(n)&&""!==n,D&&(F=n)}return D}function N(){return A()?F:void 0}var y;y="undefined"!=typeof navigator?navigator:{};var S,I,p,m,M,O,x,C,g,v,U,L,w,P,F,D,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:c,internetExplorerVersion:_,isEdge:l,edgeVersion:f,isFirefox:T,firefoxVersion:h,isWindows:R,hardwareConcurrency:e(y.hardwareConcurrency,3),supportsPointerEvents:d,supportsImageRenderingPixelated:A,imageRenderingValue:N};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),E=[];if(!u)return E;var c,_,l,f,T,R,h;if(a&&(u=s(e,n,u,i)),e.length>80*i){c=l=e[0],_=f=e[1];for(var d=i;d<o;d+=i)T=e[d],R=e[d+1],T<c&&(c=T),R<_&&(_=R),T>l&&(l=T),R>f&&(f=R);h=Math.max(l-c,f-_)}return r(u,E,i,c,_,h),E}function t(e,t,n,r,i){var a,o;if(i===C(e,t,n,r)>0)for(a=t;a<n;a+=r)o=M(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=M(a,e[a],e[a+1],o);return o&&N(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!N(r,r.next)&&0!==A(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,E,c,_,f){if(e){!f&&_&&l(e,E,c,_);for(var T,R,h=e;e.prev!==e.next;)if(T=e.prev,R=e.next,_?a(e,E,c,_):i(e))t.push(T.i/s),t.push(e.i/s),t.push(R.i/s),O(e),e=R.next,h=R.next;else if((e=R)===h){f?1===f?(e=o(e,t,s),r(e,t,s,E,c,_,2)):2===f&&u(e,t,s,E,c,_):r(n(e),t,s,E,c,_,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(A(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(h(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&A(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(A(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,E=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,c=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,_=T(u,s,t,n,r),l=T(E,c,t,n,r),f=e.nextZ;f&&f.z<=l;){if(f!==e.prev&&f!==e.next&&h(i.x,i.y,a.x,a.y,o.x,o.y,f.x,f.y)&&A(f.prev,f,f.next)>=0)return!1;f=f.nextZ}for(f=e.prevZ;f&&f.z>=_;){if(f!==e.prev&&f!==e.next&&h(i.x,i.y,a.x,a.y,o.x,o.y,f.x,f.y)&&A(f.prev,f,f.next)>=0)return!1;f=f.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!N(i,a)&&y(i,r,r.next,a)&&I(i,a)&&I(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),O(r),O(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var E=s.next.next;E!==s.prev;){if(s.i!==E.i&&d(s,E)){var c=m(s,E);return s=n(s,s.next),c=n(c,c.next),r(s,t,i,a,o,u),void r(c,t,i,a,o,u)}E=E.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,_,l,f=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,_=o<u-1?r[o+1]*a:e.length,l=t(e,s,_,a,!1),l===l.next&&(l.steiner=!0),f.push(R(l));for(f.sort(E),o=0;o<f.length;o++)c(f[o],i),i=n(i,i.next);return i}function E(e,t){return e.x-t.x}function c(e,t){if(t=_(e,t)){var r=m(t,e);n(r,r.next)}}function _(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,E=n,c=n.x,_=n.y,l=1/0;for(r=n.next;r!==E;)i>=r.x&&r.x>=c&&h(a<_?i:o,a,c,_,a<_?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<l||s===l&&r.x>n.x)&&I(r,e)&&(n=r,l=s),r=r.next;return n}function l(e,t,n,r){var i=e;do{null===i.z&&(i.z=T(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,f(i)}function f(e){var t,n,r,i,a,o,u,s,E=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<E&&(u++,r=r.nextZ);t++);for(s=E;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,E*=2}while(o>1);return e}function T(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function R(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function h(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function d(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!S(e,t)&&I(e,t)&&I(t,e)&&p(e,t)}function A(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function N(e,t){return e.x===t.x&&e.y===t.y}function y(e,t,n,r){return!!(N(e,t)&&N(n,r)||N(e,r)&&N(n,t))||A(e,t,n)>0!=A(e,t,r)>0&&A(n,r,e)>0!=A(n,r,t)>0}function S(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&y(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function I(e,t){return A(e.prev,e,e.next)<0?A(e,t,e.next)>=0&&A(e,e.prev,t)>=0:A(e,t,e.prev)<0||A(e,e.next,t)<0}function p(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function m(e,t){var n=new x(e.i,e.x,e.y),r=new x(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function M(e,t,n,r){var i=new x(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function x(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function C(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(C(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var E=t[u]*n,c=u<s-1?t[u+1]*n:e.length;o-=Math.abs(C(e,E,c,n))}var _=0;for(u=0;u<r.length;u+=3){var l=r[u]*n,f=r[u+1]*n,T=r[u+2]*n;_+=Math.abs((e[l]-e[T])*(e[f+1]-e[l+1])-(e[l]-e[f])*(e[T+1]-e[l+1]))}return 0===o&&0===_?0:Math.abs((_-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var E=new o,c=new o;o.angleBetween=function(e,t){return o.normalize(e,E),o.normalize(t,c),a.acosClamped(o.dot(E,c))};var _=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,E,c,_,l){"use strict";var f=new n,T=new n,R={};R.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},R.computeWindingOrder2D=function(e){return R.computeArea2D(e)>0?l.COUNTER_CLOCKWISE:l.CLOCKWISE},R.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var h=new n,d=new n,A=new n,N=new n,y=new n,S=new n,I=new n;return R.computeSubdivision=function(e,t,r,u){u=a(u,c.RADIANS_PER_DEGREE);var l,f=r.slice(0),T=t.length,R=new Array(3*T),p=0;for(l=0;l<T;l++){var m=t[l];R[p++]=m.x,R[p++]=m.y,R[p++]=m.z}for(var M=[],O={},x=e.maximumRadius,C=c.chordLength(u,x),g=C*C;f.length>0;){var v,U,L=f.pop(),w=f.pop(),P=f.pop(),F=n.fromArray(R,3*P,h),D=n.fromArray(R,3*w,d),B=n.fromArray(R,3*L,A),z=n.multiplyByScalar(n.normalize(F,N),x,N),G=n.multiplyByScalar(n.normalize(D,y),x,y),b=n.multiplyByScalar(n.normalize(B,S),x,S),X=n.magnitudeSquared(n.subtract(z,G,I)),q=n.magnitudeSquared(n.subtract(G,b,I)),V=n.magnitudeSquared(n.subtract(b,z,I)),H=Math.max(X,q,V);H>g?X===H?(v=Math.min(P,w)+" "+Math.max(P,w),l=O[v],o(l)||(U=n.add(F,D,I),n.multiplyByScalar(U,.5,U),R.push(U.x,U.y,U.z),l=R.length/3-1,O[v]=l),f.push(P,l,L),f.push(l,w,L)):q===H?(v=Math.min(w,L)+" "+Math.max(w,L),l=O[v],o(l)||(U=n.add(D,B,I),n.multiplyByScalar(U,.5,U),R.push(U.x,U.y,U.z),l=R.length/3-1,O[v]=l),f.push(w,l,P),f.push(l,L,P)):V===H&&(v=Math.min(L,P)+" "+Math.max(L,P),l=O[v],o(l)||(U=n.add(B,F,I),n.multiplyByScalar(U,.5,U),R.push(U.x,U.y,U.z),l=R.length/3-1,O[v]=l),f.push(L,l,w),f.push(l,P,w)):(M.push(P),M.push(w),M.push(L))}return new s({attributes:{position:new E({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:R})},indices:M,primitiveType:_.TRIANGLES})},R.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=f,E=T;if(t=a(t,0),i=a(i,!0),o(e))for(var c=e.length,_=0;_<c;_+=3)n.fromArray(e,_,E),i&&(E=r.scaleToGeodeticSurface(E,E)),0!==t&&(s=r.geodeticSurfaceNormal(E,s),n.multiplyByScalar(s,t,s),n.add(E,s,E)),e[_]=E.x,e[_+1]=E.y,e[_+2]=E.z;return e},R}),define("Core/Matrix2",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./freezeObject"],function(e,t,n,r,i,a){"use strict";function o(e,t,r,i){this[0]=n(e,0),this[1]=n(r,0),this[2]=n(t,0),this[3]=n(i,0)}o.packedLength=4,o.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t},o.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new o),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i},o.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):new o(e[0],e[2],e[1],e[3])},o.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new o),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i},o.fromColumnMajorArray=function(e,t){return o.clone(e,t)},o.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[2],t[2]=e[1],t[3]=e[3], -t):new o(e[0],e[1],e[2],e[3])},o.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=e.y,t):new o(e.x,0,0,e.y)},o.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=e,t):new o(e,0,0,e)},o.fromRotation=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=-i,t[3]=n,t):new o(n,-i,i,n)},o.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):[e[0],e[1],e[2],e[3]]},o.getElementIndex=function(e,t){return 2*e+t},o.getColumn=function(e,t,n){var r=2*t,i=e[r],a=e[r+1];return n.x=i,n.y=a,n},o.setColumn=function(e,t,n,r){r=o.clone(e,r);var i=2*t;return r[i]=n.x,r[i+1]=n.y,r},o.getRow=function(e,t,n){var r=e[t],i=e[t+2];return n.x=r,n.y=i,n},o.setRow=function(e,t,n,r){return r=o.clone(e,r),r[t]=n.x,r[t+2]=n.y,r};var u=new e;o.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],u)),n.y=e.magnitude(e.fromElements(t[2],t[3],u)),n};var s=new e;return o.getMaximumScale=function(t){return o.getScale(t,s),e.maximumComponent(s)},o.multiply=function(e,t,n){var r=e[0]*t[0]+e[2]*t[1],i=e[0]*t[2]+e[2]*t[3],a=e[1]*t[0]+e[3]*t[1],o=e[1]*t[2]+e[3]*t[3];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n},o.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n},o.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n},o.multiplyByVector=function(e,t,n){var r=e[0]*t.x+e[2]*t.y,i=e[1]*t.x+e[3]*t.y;return n.x=r,n.y=i,n},o.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n},o.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.y,n[3]=e[3]*t.y,n},o.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},o.transpose=function(e,t){var n=e[0],r=e[2],i=e[1],a=e[3];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t},o.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},o.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]},o.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n},o.IDENTITY=a(new o(1,0,0,1)),o.ZERO=a(new o(0,0,0,0)),o.COLUMN0ROW0=0,o.COLUMN0ROW1=1,o.COLUMN1ROW0=2,o.COLUMN1ROW1=3,i(o.prototype,{length:{get:function(){return o.packedLength}}}),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t){return o.equalsEpsilon(this,e,t)},o.prototype.toString=function(){return"("+this[0]+", "+this[2]+")\n("+this[1]+", "+this[3]+")"},o}),define("Core/RectangleGeometryLibrary",["./Cartesian3","./Cartographic","./defined","./DeveloperError","./GeographicProjection","./Math","./Matrix2","./Rectangle"],function(e,t,n,r,i,a,o,u){"use strict";function s(t,n,r,i,a,u,s){var E=Math.cos(n),c=i*E,_=r*E,l=Math.sin(n),R=i*l,A=r*l;T=d.project(t,T),T=e.subtract(T,h,T);var N=o.fromRotation(n,f);T=o.multiplyByVector(N,T,T),T=e.add(T,h,T),t=d.unproject(T,t),u-=1,s-=1;var y=t.latitude,S=y+u*A,I=y-c*s,p=y-c*s+u*A,m=Math.max(y,S,I,p),M=Math.min(y,S,I,p),O=t.longitude,x=O+u*_,C=O+s*R,g=O+s*R+u*_;return{north:m,south:M,east:Math.max(O,x,C,g),west:Math.min(O,x,C,g),granYCos:c,granYSin:R,granXCos:_,granXSin:A,nwCorner:t}}var E=Math.cos,c=Math.sin,_=Math.sqrt,l={};l.computePosition=function(e,t,r,i,a){var o=e.ellipsoid.radiiSquared,u=e.nwCorner,s=e.rectangle,l=u.latitude-e.granYCos*t+r*e.granXSin,f=E(l),T=c(l),R=o.z*T,h=u.longitude+t*e.granYSin+r*e.granXCos,d=f*E(h),A=f*c(h),N=o.x*d,y=o.y*A,S=_(N*d+y*A+R*T);if(i.x=N/S,i.y=y/S,i.z=R/S,n(e.vertexFormat)&&e.vertexFormat.st){var I=e.stNwCorner;n(I)?(l=I.latitude-e.stGranYCos*t+r*e.stGranXSin,h=I.longitude+t*e.stGranYSin+r*e.stGranXCos,a.x=(h-e.stWest)*e.lonScalar,a.y=(l-e.stSouth)*e.latScalar):(a.x=(h-s.west)*e.lonScalar,a.y=(l-s.south)*e.latScalar)}};var f=new o,T=new e,R=new t,h=new e,d=new i;return l.computeOptions=function(e,t,n,r){var i,o,E,c,_,l=e._granularity,f=e._ellipsoid,T=e._surfaceHeight,A=e._rotation,N=e._stRotation,y=e._extrudedHeight,S=t.east,I=t.west,p=t.north,m=t.south,M=p-m;I>S?(_=a.TWO_PI-I+S,i=Math.ceil(_/l)+1,o=Math.ceil(M/l)+1,E=_/(i-1),c=M/(o-1)):(_=S-I,i=Math.ceil(_/l)+1,o=Math.ceil(M/l)+1,E=_/(i-1),c=M/(o-1)),n=u.northwest(t,n);var O=u.center(t,R);0===A&&0===N||(O.longitude<n.longitude&&(O.longitude+=a.TWO_PI),h=d.project(O,h));var x=c,C=E,g={granYCos:x,granYSin:0,granXCos:C,granXSin:0,ellipsoid:f,surfaceHeight:T,extrudedHeight:y,nwCorner:n,rectangle:t,width:i,height:o};if(0!==A){var v=s(n,A,E,c,O,i,o);p=v.north,m=v.south,S=v.east,I=v.west,g.granYCos=v.granYCos,g.granYSin=v.granYSin,g.granXCos=v.granXCos,g.granXSin=v.granXSin,t.north=p,t.south=m,t.east=S,t.west=I}if(0!==N){A-=N,r=u.northwest(t,r);var U=s(r,A,E,c,O,i,o);g.stGranYCos=U.granYCos,g.stGranXCos=U.granXCos,g.stGranYSin=U.granYSin,g.stGranXSin=U.granXSin,g.stNwCorner=r,g.stWest=U.west,g.stSouth=U.south}return g},l}),define("Core/RectangleOutlineGeometry",["./BoundingSphere","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Rectangle","./RectangleGeometryLibrary"],function(e,t,n,r,i,a,o,u,s,E,c,_,l,f,T,R,h){"use strict";function d(e){var t,n=e.size,i=e.height,a=e.width,o=new Float64Array(3*n),u=0,l=0,f=I;for(t=0;t<a;t++)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(t=a-1,l=1;l<i;l++)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(l=i-1,t=a-2;t>=0;t--)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(t=0,l=i-2;l>0;l--)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(var R=o.length/3*2,d=_.createTypedArray(o.length/3,R),A=0,N=0;N<o.length/3-1;N++)d[A++]=N,d[A++]=N+1;d[A++]=o.length/3-1,d[A++]=0;var y=new s({attributes:new c,primitiveType:T.LINES});return y.attributes.position=new E({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:o}),y.indices=d,y}function A(e){var t=e.surfaceHeight,n=e.extrudedHeight,r=e.ellipsoid,i=Math.min(n,t),a=Math.max(n,t),o=d(e);if(l.equalsEpsilon(i,a,l.EPSILON10))return o;var u=e.height,s=e.width,E=f.scaleToGeodeticHeight(o.attributes.position.values,a,r,!1),c=E.length,T=new Float64Array(2*c);T.set(E);var R=f.scaleToGeodeticHeight(o.attributes.position.values,i,r);T.set(R,c),o.attributes.position.values=T;var h=T.length/3*2+8,A=_.createTypedArray(T.length/3,h);c=T.length/6;for(var N=0,y=0;y<c-1;y++)A[N++]=y,A[N++]=y+1,A[N++]=y+c,A[N++]=y+c+1;return A[N++]=c-1,A[N++]=0,A[N++]=c+c-1,A[N++]=c,A[N++]=0,A[N++]=c,A[N++]=s-1,A[N++]=c+s-1,A[N++]=s+u-2,A[N++]=s+u-2+c,A[N++]=2*s+u-3,A[N++]=2*s+u-3+c,o.indices=A,o}function N(e){e=i(e,i.EMPTY_OBJECT);var t=e.rectangle,n=i(e.granularity,l.RADIANS_PER_DEGREE),r=i(e.ellipsoid,u.WGS84),a=i(e.height,0),o=i(e.rotation,0),s=e.extrudedHeight;this._rectangle=t,this._granularity=n,this._ellipsoid=r,this._surfaceHeight=a,this._rotation=o,this._extrudedHeight=s,this._workerName="createRectangleOutlineGeometry"}var y=new e,S=new e,I=new t,p=new R;N.packedLength=R.packedLength+u.packedLength+5,N.pack=function(e,t,n){return n=i(n,0),R.pack(e._rectangle,t,n),n+=R.packedLength,u.pack(e._ellipsoid,t,n),n+=u.packedLength,t[n++]=e._granularity,t[n++]=e._surfaceHeight,t[n++]=e._rotation,t[n++]=a(e._extrudedHeight)?1:0,t[n]=i(e._extrudedHeight,0),t};var m=new R,M=u.clone(u.UNIT_SPHERE),O={rectangle:m,ellipsoid:M,granularity:void 0,height:void 0,rotation:void 0,extrudedHeight:void 0};N.unpack=function(e,t,n){t=i(t,0);var r=R.unpack(e,t,m);t+=R.packedLength;var o=u.unpack(e,t,M);t+=u.packedLength;var s=e[t++],E=e[t++],c=e[t++],_=e[t++],l=e[t];return a(n)?(n._rectangle=R.clone(r,n._rectangle),n._ellipsoid=u.clone(o,n._ellipsoid),n._surfaceHeight=E,n._rotation=c,n._extrudedHeight=_?l:void 0,n):(O.granularity=s,O.height=E,O.rotation=c,O.extrudedHeight=_?l:void 0,new N(O))};var x=new n;return N.createGeometry=function(t){var n=R.clone(t._rectangle,p),r=t._ellipsoid,i=t._surfaceHeight,o=t._extrudedHeight,u=h.computeOptions(t,n,x);u.size=2*u.width+2*u.height-4;var E,c;if(n=t._rectangle,!l.equalsEpsilon(n.north,n.south,l.EPSILON10)&&!l.equalsEpsilon(n.east,n.west,l.EPSILON10)){if(a(o)){E=A(u);var _=e.fromRectangle3D(n,r,i,S),N=e.fromRectangle3D(n,r,o,y);c=e.union(_,N)}else E=d(u),E.attributes.position.values=f.scaleToGeodeticHeight(E.attributes.position.values,i,r,!1),c=e.fromRectangle3D(n,r,i);return new s({attributes:E.attributes,indices:E.indices,primitiveType:T.LINES,boundingSphere:c})}},N}),define("Workers/createRectangleOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/Rectangle","../Core/RectangleOutlineGeometry"],function(e,t,n,r){"use strict";function i(i,a){return e(a)&&(i=r.unpack(i,a)),i._ellipsoid=t.clone(i._ellipsoid),i._rectangle=n.clone(i._rectangle),r.createGeometry(i)}return i})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,E=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,E);var n=o.dot(c,E),r=o.magnitude(o.cross(c,E,c));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,E=a*o-r*s,_=r*u-i*o;return n.x=c,n.y=E,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var l=new o,f=new o,T=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:T,c=Math.cos(r);l.x=c*Math.cos(e),l.y=c*Math.sin(e),l.z=Math.sin(r),l=o.normalize(l,l),o.multiplyComponents(s,l,f);var E=Math.sqrt(o.dot(l,f));return f=o.divideByScalar(f,E,f),l=o.multiplyByScalar(l,i,l),n(u)||(u=new o),o.add(f,l,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],E=a/3;r[E]=o.fromDegrees(u,s,c,t,r[E])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],E=a/3;r[E]=o.fromRadians(u,s,c,t,r[E])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var E=n.x,_=n.y,l=n.z,f=i.x,T=i.y,R=i.z,h=E*E*f*f,d=_*_*T*T,A=l*l*R*R,N=h+d+A,y=Math.sqrt(1/N),S=e.multiplyByScalar(n,y,a);if(N<s)return isFinite(y)?e.clone(S,c):void 0;var I=u.x,p=u.y,m=u.z,M=o;M.x=S.x*I*2,M.y=S.y*p*2,M.z=S.z*m*2;var O,x,C,g,v,U,L,w,P,F,D,B=(1-y)*e.magnitude(n)/(.5*e.magnitude(M)),z=0;do{B-=z,C=1/(1+B*I),g=1/(1+B*p),v=1/(1+B*m),U=C*C,L=g*g,w=v*v,P=U*C,F=L*g,D=w*v,O=h*U+d*L+A*w-1,x=h*P*I+d*F*p+A*D*m;z=O/(-2*x)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=E*C,c.y=_*g,c.z=l*v,c):new e(E*C,_*g,l*v)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,E=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),l=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),f=a.EPSILON1;return u.fromCartesian=function(t,n,i){var T=r(n)?n.oneOverRadii:_,R=r(n)?n.oneOverRadiiSquared:l,h=r(n)?n._centerToleranceSquared:f,d=o(t,T,R,h,c);if(r(d)){var A=e.multiplyComponents(d,R,s);A=e.normalize(A,A);var N=e.subtract(t,d,E),y=Math.atan2(A.y,A.x),S=Math.asin(A.z),I=a.sign(e.dot(N,t))*e.magnitude(N);return r(i)?(i.longitude=y,i.latitude=S,i.height=I,i):new u(y,S,I)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function E(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,E(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(E(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var l=new e,f=new e;_.prototype.cartographicToCartesian=function(t,n){var r=l,a=f;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var T=new e,R=new e,h=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,R);if(i(a)){var o=this.geodeticSurfaceNormal(a,T),u=e.subtract(n,a,h),c=Math.atan2(o.y,o.x),E=Math.asin(o.z),_=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=E,r.height=_,r):new t(c,E,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,E=-Number.MAX_VALUE,_=0,l=e.length;_<l;_++){var f=e[_];n=Math.min(n,f.longitude),i=Math.max(i,f.longitude),c=Math.min(c,f.latitude),E=Math.max(E,f.latitude);var T=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;a=Math.min(a,T),o=Math.max(o,T)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=E,t):new s(n,c,i,E)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,E=Number.MAX_VALUE,_=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,T=0,R=e.length;T<R;T++){var h=t.cartesianToCartographic(e[T]);o=Math.min(o,h.longitude),c=Math.max(c,h.longitude),l=Math.min(l,h.latitude),f=Math.max(f,h.latitude);var d=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;E=Math.min(E,d),_=Math.max(_,d)}return c-o>_-E&&(o=E,c=_,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=l,i.east=c,i.north=f,i):new s(o,l,c,f)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.negativePiToPi(Math.max(a,c)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=E)){var l=Math.max(e.south,t.south),f=Math.min(e.north,t.north);if(!(l>=f))return r(n)?(n.west=E,n.south=l,n.east=_,n.north=f,n):new s(E,l,_,f)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var E=u.convertLongitudeRange(Math.min(a,c)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=E,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var E=0,_=e.north,l=e.south,f=e.east,T=e.west,R=c;R.height=i,R.longitude=T,R.latitude=_,o[E]=t.cartographicToCartesian(R,o[E]),E++,R.longitude=f,o[E]=t.cartographicToCartesian(R,o[E]),E++,R.latitude=l,o[E]=t.cartographicToCartesian(R,o[E]),E++,R.longitude=T,o[E]=t.cartographicToCartesian(R,o[E]),E++,R.latitude=_<0?_:l>0?l:0;for(var h=1;h<8;++h)R.longitude=-Math.PI+h*u.PI_OVER_TWO,s.contains(e,R)&&(o[E]=t.cartographicToCartesian(R,o[E]),E++);return 0===R.latitude&&(R.longitude=T,o[E]=t.cartographicToCartesian(R,o[E]),E++,R.longitude=f,o[E]=t.cartographicToCartesian(R,o[E]),E++),o.length=E,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function E(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(R[n],T[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(R[a],T[a])]);o>r&&(i=a,r=o)}var c=1,E=0,_=T[i],l=R[i];if(Math.abs(e[s.getElementIndex(l,_)])>n){var f,h=e[s.getElementIndex(l,l)],d=e[s.getElementIndex(_,_)],A=e[s.getElementIndex(l,_)],N=(h-d)/2/A;f=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),c=1/Math.sqrt(1+f*f),E=f*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(_,_)]=t[s.getElementIndex(l,l)]=c,t[s.getElementIndex(l,_)]=E,t[s.getElementIndex(_,l)]=-E,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,E=e.y*e.w,_=e.z*e.z,l=e.z*e.w,f=e.w*e.w,T=n-u-_+f,R=2*(i-l),h=2*(a+E),d=2*(i+l),A=-n+u-_+f,N=2*(c-o),y=2*(a-E),S=2*(c+o),I=-n-u+_+f;return r(t)?(t[0]=T,t[1]=d,t[2]=y,t[3]=R,t[4]=A,t[5]=S,t[6]=h,t[7]=N,t[8]=I,t):new s(T,R,h,d,A,N,y,S,I)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),E=n*i,_=-a*u+c*o*i,l=c*u+a*o*i,f=n*u,T=a*i+c*o*u,R=-c*i+a*o*u,h=-o,d=c*n,A=a*n;return r(t)?(t[0]=E,t[1]=f,t[2]=h,t[3]=_,t[4]=T,t[5]=d,t[6]=l,t[7]=R,t[8]=A,t):new s(E,_,l,f,T,R,h,d,A)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var l=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],l)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],l)),n};var f=new e;s.getMaximumScale=function(t){return s.getScale(t,f),e.maximumComponent(f)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],E=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=E,n[8]=_,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],E=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=E,t};var T=[1,0,0],R=[2,2,1],h=new s,d=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),l=t.diagonal=s.clone(e,t.diagonal),f=n*c(l);a<10&&E(l)>f;)_(l,h),s.transpose(h,d),s.multiply(l,h,l),s.multiply(d,l,l),s.multiply(o,h,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t}, +s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],E=e[7],_=e[8],l=s.determinant(e);t[0]=o*_-E*u,t[1]=E*i-r*_,t[2]=r*u-o*i,t[3]=c*u-a*_,t[4]=n*_-c*i,t[5]=a*i-n*u,t[6]=a*E-c*o,t[7]=c*r-n*E,t[8]=n*o-a*r;var f=1/l;return s.multiplyByScalar(t,f,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function E(e,t,n,i,a,o,u,s,c,E,_,l,f,T,R,h){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(f,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(E,0),this[7]=r(T,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(R,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(l,0),this[15]=r(h,0)}E.packedLength=16,E.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},E.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new E),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},E.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new E(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},E.fromArray=E.unpack,E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},E.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new E(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},E.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new E);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,_=t.x*t.z,l=t.x*t.w,f=t.y*t.y,T=t.y*t.z,R=t.y*t.w,h=t.z*t.z,d=t.z*t.w,A=t.w*t.w,N=s-f-h+A,y=2*(c-d),S=2*(_+R),I=2*(c+d),p=-s+f-h+A,m=2*(T-l),M=2*(_-R),O=2*(T+l),x=-s-f+h+A;return r[0]=N*a,r[1]=I*a,r[2]=M*a,r[3]=0,r[4]=y*o,r[5]=p*o,r[6]=O*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=x*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},E.fromTranslationRotationScale=function(e,t){return E.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},E.fromTranslation=function(e,t){return E.fromRotationTranslation(s.IDENTITY,e,t)},E.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new E(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},E.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new E(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,l=new e,f=new e;E.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,l),l),e.normalize(e.cross(l,_,f),f);var u=l.x,s=l.y,c=l.z,T=_.x,R=_.y,h=_.z,d=f.x,A=f.y,N=f.z,y=r.x,S=r.y,I=r.z,p=u*-y+s*-S+c*-I,m=d*-y+A*-S+N*-I,M=T*y+R*S+h*I;return i(n)?(n[0]=u,n[1]=d,n[2]=-T,n[3]=0,n[4]=s,n[5]=A,n[6]=-R,n[7]=0,n[8]=c,n[9]=N,n[10]=-h,n[11]=0,n[12]=p,n[13]=m,n[14]=M,n[15]=1,n):new E(u,s,c,p,d,A,N,m,-T,-R,-h,M,0,0,0,1)},E.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},E.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),E=-(t+e)*u,_=-(r+n)*s,l=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=E,o[13]=_,o[14]=l,o[15]=1,o},E.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),E=(r+n)/(r-n),_=-(a+i)/(a-i),l=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=E,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},E.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),E=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},E.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,E=.5*s,_=.5*(n-t),l=c,f=E,T=_,R=a+c,h=o+E,d=t+_;return i[0]=l,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=f,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=T,i[11]=0,i[12]=R,i[13]=h,i[14]=d,i[15]=1,i},E.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},E.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},E.getElementIndex=function(e,t){return 4*e+t},E.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},E.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},E.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],T)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],E=e[7],_=e[8],l=e[9],f=e[10],T=e[11],R=e[12],h=e[13],d=e[14],A=e[15],N=t[0],y=t[1],S=t[2],I=t[3],p=t[4],m=t[5],M=t[6],O=t[7],x=t[8],C=t[9],g=t[10],v=t[11],U=t[12],L=t[13],w=t[14],P=t[15],F=r*N+u*y+_*S+R*I,D=i*N+s*y+l*S+h*I,B=a*N+c*y+f*S+d*I,z=o*N+E*y+T*S+A*I,G=r*p+u*m+_*M+R*O,b=i*p+s*m+l*M+h*O,X=a*p+c*m+f*M+d*O,q=o*p+E*m+T*M+A*O,V=r*x+u*C+_*g+R*v,H=i*x+s*C+l*g+h*v,W=a*x+c*C+f*g+d*v,Y=o*x+E*C+T*g+A*v,k=r*U+u*L+_*w+R*P,Z=i*U+s*L+l*w+h*P,K=a*U+c*L+f*w+d*P,j=o*U+E*L+T*w+A*P;return n[0]=F,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=q,n[8]=V,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=Z,n[14]=K,n[15]=j,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},E.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],E=e[9],_=e[10],l=e[12],f=e[13],T=e[14],R=t[0],h=t[1],d=t[2],A=t[4],N=t[5],y=t[6],S=t[8],I=t[9],p=t[10],m=t[12],M=t[13],O=t[14],x=r*R+o*h+c*d,C=i*R+u*h+E*d,g=a*R+s*h+_*d,v=r*A+o*N+c*y,U=i*A+u*N+E*y,L=a*A+s*N+_*y,w=r*S+o*I+c*p,P=i*S+u*I+E*p,F=a*S+s*I+_*p,D=r*m+o*M+c*O+l,B=i*m+u*M+E*O+f,z=a*m+s*M+_*O+T;return n[0]=x,n[1]=C,n[2]=g,n[3]=0,n[4]=v,n[5]=U,n[6]=L,n[7]=0,n[8]=w,n[9]=P,n[10]=F,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},E.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],E=e[9],_=e[10],l=t[0],f=t[1],T=t[2],R=t[3],h=t[4],d=t[5],A=t[6],N=t[7],y=t[8],S=r*l+o*f+c*T,I=i*l+u*f+E*T,p=a*l+s*f+_*T,m=r*R+o*h+c*d,M=i*R+u*h+E*d,O=a*R+s*h+_*d,x=r*A+o*N+c*y,C=i*A+u*N+E*y,g=a*A+s*N+_*y;return n[0]=S,n[1]=I,n[2]=p,n[3]=0,n[4]=m,n[5]=M,n[6]=O,n[7]=0,n[8]=x,n[9]=C,n[10]=g,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},E.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var h=new e;E.multiplyByUniformScale=function(e,t,n){return h.x=t,h.y=t,h.z=t,E.multiplyByScale(e,h,n)},E.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?E.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,E=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=E,n},E.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},E.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},E.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},E.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},E.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},E.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},E.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var d=new s,A=new s,N=new t,y=new t(0,0,0,1);return E.inverse=function(e,n){if(s.equalsEpsilon(E.getRotation(e,d),A,u.EPSILON7)&&t.equals(E.getRow(e,3,N),y))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],l=e[5],f=e[9],T=e[13],R=e[2],h=e[6],S=e[10],I=e[14],p=e[3],m=e[7],M=e[11],O=e[15],x=S*O,C=I*M,g=h*O,v=I*m,U=h*M,L=S*m,w=R*O,P=I*p,F=R*M,D=S*p,B=R*m,z=h*p,G=x*l+v*f+U*T-(C*l+g*f+L*T),b=C*_+w*f+D*T-(x*_+P*f+F*T),X=g*_+P*l+B*T-(v*_+w*l+z*T),q=L*_+F*l+z*f-(U*_+D*l+B*f),V=C*i+g*a+L*o-(x*i+v*a+U*o),H=x*r+P*a+F*o-(C*r+w*a+D*o),W=v*r+w*i+z*o-(g*r+P*i+B*o),Y=U*r+D*i+B*a-(L*r+F*i+z*a);x=a*T,C=o*f,g=i*T,v=o*l,U=i*f,L=a*l,w=r*T,P=o*_,F=r*f,D=a*_,B=r*l,z=i*_;var k=x*m+v*M+U*O-(C*m+g*M+L*O),Z=C*p+w*M+D*O-(x*p+P*M+F*O),K=g*p+P*m+B*O-(v*p+w*m+z*O),j=L*p+F*m+z*M-(U*p+D*m+B*M),Q=g*S+L*I+C*h-(U*I+x*h+v*S),J=F*I+x*R+P*S-(w*S+D*I+C*R),$=w*h+z*I+v*R-(B*I+g*R+P*h),ee=B*S+U*R+D*h-(F*h+z*S+L*R),te=r*G+i*b+a*X+o*q;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=G*te,n[1]=b*te,n[2]=X*te,n[3]=q*te,n[4]=V*te,n[5]=H*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=K*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},E.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],E=e[10],_=e[12],l=e[13],f=e[14],T=-n*_-r*l-i*f,R=-a*_-o*l-u*f,h=-s*_-c*l-E*f;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=E,t[11]=0,t[12]=T,t[13]=R,t[14]=h,t[15]=1,t},E.IDENTITY=o(new E(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN0ROW3=3,E.COLUMN1ROW0=4,E.COLUMN1ROW1=5,E.COLUMN1ROW2=6,E.COLUMN1ROW3=7,E.COLUMN2ROW0=8,E.COLUMN2ROW1=9,E.COLUMN2ROW2=10,E.COLUMN2ROW3=11,E.COLUMN3ROW0=12,E.COLUMN3ROW1=13,E.COLUMN3ROW2=14,E.COLUMN3ROW3=15,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,E,_,l){"use strict";function f(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var T=new e,R=new e,h=new e,d=new e,A=new e,N=new e,y=new e,S=new e,I=new e,p=new e,m=new e,M=new e,O=4/3*n.PI;f.fromPoints=function(t,n){if(a(n)||(n=new f),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],y),o=e.clone(i,T),u=e.clone(i,R),s=e.clone(i,h),c=e.clone(i,d),E=e.clone(i,A),_=e.clone(i,N),l=t.length;for(r=1;r<l;r++){e.clone(t[r],i);var O=i.x,x=i.y,C=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),x<u.y&&e.clone(i,u),x>E.y&&e.clone(i,E),C<s.z&&e.clone(i,s),C>_.z&&e.clone(i,_)}var g=e.magnitudeSquared(e.subtract(c,o,S)),v=e.magnitudeSquared(e.subtract(E,u,S)),U=e.magnitudeSquared(e.subtract(_,s,S)),L=o,w=c,P=g;v>P&&(P=v,L=u,w=E),U>P&&(P=U,L=s,w=_);var F=I;F.x=.5*(L.x+w.x),F.y=.5*(L.y+w.y),F.z=.5*(L.z+w.z);var D=e.magnitudeSquared(e.subtract(w,F,S)),B=Math.sqrt(D),z=p;z.x=o.x,z.y=u.y,z.z=s.z;var G=m;G.x=c.x,G.y=E.y,G.z=_.z;var b=e.multiplyByScalar(e.add(z,G,S),.5,M),X=0;for(r=0;r<l;r++){e.clone(t[r],i);var q=e.magnitude(e.subtract(i,b,S));q>X&&(X=q);var V=e.magnitudeSquared(e.subtract(i,F,S));if(V>D){var H=Math.sqrt(V);B=.5*(B+H),D=B*B;var W=H-B;F.x=(B*F.x+W*i.x)/H,F.y=(B*F.y+W*i.y)/H,F.z=(B*F.z+W*i.z)/H}}return B<X?(e.clone(F,n.center),n.radius=B):(e.clone(b,n.center),n.radius=X),n};var x=new u,C=new e,g=new e,v=new t,U=new t;f.fromRectangle2D=function(e,t,n){return f.fromRectangleWithHeights2D(e,t,0,0,n)},f.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,x),l.southwest(t,v),v.height=r,l.northeast(t,U),U.height=o;var s=n.project(v,C),c=n.project(U,g),E=c.x-s.x,_=c.y-s.y,T=c.z-s.z;u.radius=.5*Math.sqrt(E*E+_*_+T*T);var R=u.center;return R.x=s.x+.5*E,R.y=s.y+.5*_,R.z=s.z+.5*T,u};var L=[];f.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=l.subsample(t,n,r,L);return f.fromPoints(s,u)},f.fromVertices=function(t,n,r,o){if(a(o)||(o=new f),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=y;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,T),E=e.clone(u,R),_=e.clone(u,h),l=e.clone(u,d),O=e.clone(u,A),x=e.clone(u,N),C=t.length;for(s=0;s<C;s+=r){var g=t[s]+n.x,v=t[s+1]+n.y,U=t[s+2]+n.z;u.x=g,u.y=v,u.z=U,g<c.x&&e.clone(u,c),g>l.x&&e.clone(u,l),v<E.y&&e.clone(u,E),v>O.y&&e.clone(u,O),U<_.z&&e.clone(u,_),U>x.z&&e.clone(u,x)}var L=e.magnitudeSquared(e.subtract(l,c,S)),w=e.magnitudeSquared(e.subtract(O,E,S)),P=e.magnitudeSquared(e.subtract(x,_,S)),F=c,D=l,B=L;w>B&&(B=w,F=E,D=O),P>B&&(B=P,F=_,D=x);var z=I;z.x=.5*(F.x+D.x),z.y=.5*(F.y+D.y),z.z=.5*(F.z+D.z);var G=e.magnitudeSquared(e.subtract(D,z,S)),b=Math.sqrt(G),X=p;X.x=c.x,X.y=E.y,X.z=_.z;var q=m;q.x=l.x,q.y=O.y,q.z=x.z;var V=e.multiplyByScalar(e.add(X,q,S),.5,M),H=0;for(s=0;s<C;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var W=e.magnitude(e.subtract(u,V,S));W>H&&(H=W);var Y=e.magnitudeSquared(e.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var Z=k-b;z.x=(b*z.x+Z*u.x)/k,z.y=(b*z.y+Z*u.y)/k,z.z=(b*z.z+Z*u.z)/k}}return b<H?(e.clone(z,o.center),o.radius=b):(e.clone(V,o.center),o.radius=H),o},f.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new f),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=y;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,T),s=e.clone(i,R),c=e.clone(i,h),E=e.clone(i,d),_=e.clone(i,A),l=e.clone(i,N),O=t.length;for(o=0;o<O;o+=3){var x=t[o]+n[o],C=t[o+1]+n[o+1],g=t[o+2]+n[o+2];i.x=x,i.y=C,i.z=g,x<u.x&&e.clone(i,u),x>E.x&&e.clone(i,E),C<s.y&&e.clone(i,s),C>_.y&&e.clone(i,_),g<c.z&&e.clone(i,c),g>l.z&&e.clone(i,l)}var v=e.magnitudeSquared(e.subtract(E,u,S)),U=e.magnitudeSquared(e.subtract(_,s,S)),L=e.magnitudeSquared(e.subtract(l,c,S)),w=u,P=E,F=v;U>F&&(F=U,w=s,P=_),L>F&&(F=L,w=c,P=l);var D=I;D.x=.5*(w.x+P.x),D.y=.5*(w.y+P.y),D.z=.5*(w.z+P.z);var B=e.magnitudeSquared(e.subtract(P,D,S)),z=Math.sqrt(B),G=p;G.x=u.x,G.y=s.y,G.z=c.z;var b=m;b.x=E.x,b.y=_.y,b.z=l.z;var X=e.multiplyByScalar(e.add(G,b,S),.5,M),q=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var V=e.magnitude(e.subtract(i,X,S));V>q&&(q=V);var H=e.magnitudeSquared(e.subtract(i,D,S));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*i.x)/W,D.y=(z*D.y+Y*i.y)/W,D.z=(z*D.z+Y*i.z)/W}}return z<q?(e.clone(D,r.center),r.radius=z):(e.clone(X,r.center),r.radius=q),r},f.fromCornerPoints=function(t,n,r){a(r)||(r=new f);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},f.fromEllipsoid=function(t,n){return a(n)||(n=new f),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var w=new e;f.fromBoundingSpheres=function(t,n){if(a(n)||(n=new f),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return f.clone(t[0],n);if(2===r)return f.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=f.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,w)+c.radius)}return n.radius=s,n};var P=new e,F=new e,D=new e;f.fromOrientedBoundingBox=function(t,n){a(n)||(n=new f);var r=t.halfAxes,i=E.getColumn(r,0,P),o=E.getColumn(r,1,F),u=E.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},f.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new f(t.center,t.radius)},f.packedLength=4,f.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},f.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new f);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var B=new e,z=new e;f.union=function(t,n,r){a(r)||(r=new f);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,B),E=e.magnitude(c);if(o>=E+s)return t.clone(r),r;if(s>=E+o)return n.clone(r),r;var _=.5*(o+E+s),l=e.multiplyByScalar(c,(-o+_)/E,z);return e.add(l,i,l),e.clone(l,r.center),r.radius=_,r};var G=new e;f.expand=function(t,n,r){r=f.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,G));return i>r.radius&&(r.radius=i),r},f.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},f.transform=function(e,t,n){return a(n)||(n=new f),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=_.getMaximumScale(t)*e.radius,n};var b=new e;f.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},f.transformWithoutScale=function(e,t,n){return a(n)||(n=new f),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var X=new e;f.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,X),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,V=new e,H=new e,W=new e,Y=new e,k=new t,Z=new Array(8),K=0;K<8;++K)Z[K]=new e;var j=new u;return f.projectTo2D=function(t,n,r){n=i(n,j);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,V);e.normalize(c,c);var E=e.cross(s,c,H);e.normalize(E,E),e.multiplyByScalar(s,u,s),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c);var _=e.negate(E,Y),l=e.negate(c,W),T=Z,R=T[0];e.add(s,E,R),e.add(R,c,R),R=T[1],e.add(s,E,R),e.add(R,l,R),R=T[2],e.add(s,_,R),e.add(R,l,R),R=T[3],e.add(s,_,R),e.add(R,c,R),e.negate(s,s),R=T[4],e.add(s,E,R),e.add(R,c,R),R=T[5],e.add(s,E,R),e.add(R,l,R),R=T[6],e.add(s,_,R),e.add(R,l,R),R=T[7],e.add(s,_,R),e.add(R,c,R);for(var h=T.length,d=0;d<h;++d){var A=T[d];e.add(o,A,A);var N=a.cartesianToCartographic(A,k);n.project(N,A)}r=f.fromPoints(T,r),o=r.center;var y=o.x,S=o.y,I=o.z;return o.x=I,o.y=y,o.z=S,r},f.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},f.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},f.prototype.intersectPlane=function(e){return f.intersectPlane(this,e)},f.prototype.distanceSquaredTo=function(e){return f.distanceSquaredTo(this,e)},f.prototype.computePlaneDistances=function(e,t,n){return f.computePlaneDistances(this,e,t,n)},f.prototype.isOccluded=function(e){return f.isOccluded(this,e)},f.prototype.equals=function(e){return f.equals(this,e)},f.prototype.clone=function(e){return f.clone(this,e)},f.prototype.volume=function(){var e=this.radius;return O*e*e*e},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!l())){var e=/ Chrome\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(S=!0,I=r(e[1]))}return S}function a(){return i()&&I}function o(){if(!t(p)&&(p=!1,!i()&&!l()&&/ Safari\/[\.0-9]+/.test(y.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(p=!0,m=r(e[1]))}return p}function u(){return o()&&m}function s(){if(!t(M)){M=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(y.userAgent) +;null!==e&&(M=!0,O=r(e[1]),O.isNightly=!!e[2])}return M}function c(){return s()&&O}function E(){if(!t(x)){x=!1;var e;"Microsoft Internet Explorer"===y.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(y.userAgent))&&(x=!0,C=r(e[1])):"Netscape"===y.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(y.userAgent))&&(x=!0,C=r(e[1]))}return x}function _(){return E()&&C}function l(){if(!t(g)){g=!1;var e=/ Edge\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(g=!0,v=r(e[1]))}return g}function f(){return l()&&v}function T(){if(!t(U)){U=!1;var e=/Firefox\/([\.0-9]+)/.exec(y.userAgent);null!==e&&(U=!0,L=r(e[1]))}return U}function R(){return t(w)||(w=/Windows/i.test(y.appVersion)),w}function h(){return T()&&L}function d(){return t(P)||(P="undefined"!=typeof PointerEvent&&(!t(y.pointerEnabled)||y.pointerEnabled)),P}function A(){if(!t(D)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;D=t(n)&&""!==n,D&&(F=n)}return D}function N(){return A()?F:void 0}var y;y="undefined"!=typeof navigator?navigator:{};var S,I,p,m,M,O,x,C,g,v,U,L,w,P,F,D,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:E,internetExplorerVersion:_,isEdge:l,edgeVersion:f,isFirefox:T,firefoxVersion:h,isWindows:R,hardwareConcurrency:e(y.hardwareConcurrency,3),supportsPointerEvents:d,supportsImageRenderingPixelated:A,imageRenderingValue:N};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var E,_,l,f,T,R,h;if(a&&(u=s(e,n,u,i)),e.length>80*i){E=l=e[0],_=f=e[1];for(var d=i;d<o;d+=i)T=e[d],R=e[d+1],T<E&&(E=T),R<_&&(_=R),T>l&&(l=T),R>f&&(f=R);h=Math.max(l-E,f-_)}return r(u,c,i,E,_,h),c}function t(e,t,n,r,i){var a,o;if(i===C(e,t,n,r)>0)for(a=t;a<n;a+=r)o=M(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=M(a,e[a],e[a+1],o);return o&&N(o,o.next)&&(O(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!N(r,r.next)&&0!==A(r.prev,r,r.next))r=r.next;else{if(O(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,E,_,f){if(e){!f&&_&&l(e,c,E,_);for(var T,R,h=e;e.prev!==e.next;)if(T=e.prev,R=e.next,_?a(e,c,E,_):i(e))t.push(T.i/s),t.push(e.i/s),t.push(R.i/s),O(e),e=R.next,h=R.next;else if((e=R)===h){f?1===f?(e=o(e,t,s),r(e,t,s,c,E,_,2)):2===f&&u(e,t,s,c,E,_):r(n(e),t,s,c,E,_,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(A(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(h(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&A(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(A(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,E=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,_=T(u,s,t,n,r),l=T(c,E,t,n,r),f=e.nextZ;f&&f.z<=l;){if(f!==e.prev&&f!==e.next&&h(i.x,i.y,a.x,a.y,o.x,o.y,f.x,f.y)&&A(f.prev,f,f.next)>=0)return!1;f=f.nextZ}for(f=e.prevZ;f&&f.z>=_;){if(f!==e.prev&&f!==e.next&&h(i.x,i.y,a.x,a.y,o.x,o.y,f.x,f.y)&&A(f.prev,f,f.next)>=0)return!1;f=f.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!N(i,a)&&y(i,r,r.next,a)&&I(i,a)&&I(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),O(r),O(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&d(s,c)){var E=m(s,c);return s=n(s,s.next),E=n(E,E.next),r(s,t,i,a,o,u),void r(E,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,_,l,f=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,_=o<u-1?r[o+1]*a:e.length,l=t(e,s,_,a,!1),l===l.next&&(l.steiner=!0),f.push(R(l));for(f.sort(c),o=0;o<f.length;o++)E(f[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function E(e,t){if(t=_(e,t)){var r=m(t,e);n(r,r.next)}}function _(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,E=n.x,_=n.y,l=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=E&&h(a<_?i:o,a,E,_,a<_?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<l||s===l&&r.x>n.x)&&I(r,e)&&(n=r,l=s),r=r.next;return n}function l(e,t,n,r){var i=e;do{null===i.z&&(i.z=T(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,f(i)}function f(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function T(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function R(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function h(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function d(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!S(e,t)&&I(e,t)&&I(t,e)&&p(e,t)}function A(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function N(e,t){return e.x===t.x&&e.y===t.y}function y(e,t,n,r){return!!(N(e,t)&&N(n,r)||N(e,r)&&N(n,t))||A(e,t,n)>0!=A(e,t,r)>0&&A(n,r,e)>0!=A(n,r,t)>0}function S(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&y(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function I(e,t){return A(e.prev,e,e.next)<0?A(e,t,e.next)>=0&&A(e,e.prev,t)>=0:A(e,t,e.prev)<0||A(e,e.next,t)<0}function p(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function m(e,t){var n=new x(e.i,e.x,e.y),r=new x(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function M(e,t,n,r){var i=new x(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function x(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function C(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(C(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,E=u<s-1?t[u+1]*n:e.length;o-=Math.abs(C(e,c,E,n))}var _=0;for(u=0;u<r.length;u+=3){var l=r[u]*n,f=r[u+1]*n,T=r[u+2]*n;_+=Math.abs((e[l]-e[T])*(e[f+1]-e[l+1])-(e[l]-e[f])*(e[T+1]-e[l+1]))}return 0===o&&0===_?0:Math.abs((_-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,E=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,E),a.acosClamped(o.dot(c,E))};var _=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,E,_,l){"use strict";var f=new n,T=new n,R={};R.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},R.computeWindingOrder2D=function(e){return R.computeArea2D(e)>0?l.COUNTER_CLOCKWISE:l.CLOCKWISE},R.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var h=new n,d=new n,A=new n,N=new n,y=new n,S=new n,I=new n;return R.computeSubdivision=function(e,t,r,u){u=a(u,E.RADIANS_PER_DEGREE);var l,f=r.slice(0),T=t.length,R=new Array(3*T),p=0;for(l=0;l<T;l++){var m=t[l];R[p++]=m.x,R[p++]=m.y,R[p++]=m.z}for(var M=[],O={},x=e.maximumRadius,C=E.chordLength(u,x),g=C*C;f.length>0;){var v,U,L=f.pop(),w=f.pop(),P=f.pop(),F=n.fromArray(R,3*P,h),D=n.fromArray(R,3*w,d),B=n.fromArray(R,3*L,A),z=n.multiplyByScalar(n.normalize(F,N),x,N),G=n.multiplyByScalar(n.normalize(D,y),x,y),b=n.multiplyByScalar(n.normalize(B,S),x,S),X=n.magnitudeSquared(n.subtract(z,G,I)),q=n.magnitudeSquared(n.subtract(G,b,I)),V=n.magnitudeSquared(n.subtract(b,z,I)),H=Math.max(X,q,V);H>g?X===H?(v=Math.min(P,w)+" "+Math.max(P,w),l=O[v],o(l)||(U=n.add(F,D,I),n.multiplyByScalar(U,.5,U),R.push(U.x,U.y,U.z),l=R.length/3-1,O[v]=l),f.push(P,l,L),f.push(l,w,L)):q===H?(v=Math.min(w,L)+" "+Math.max(w,L),l=O[v],o(l)||(U=n.add(D,B,I),n.multiplyByScalar(U,.5,U),R.push(U.x,U.y,U.z),l=R.length/3-1,O[v]=l),f.push(w,l,P),f.push(l,L,P)):V===H&&(v=Math.min(L,P)+" "+Math.max(L,P),l=O[v],o(l)||(U=n.add(B,F,I),n.multiplyByScalar(U,.5,U),R.push(U.x,U.y,U.z),l=R.length/3-1,O[v]=l),f.push(L,l,w),f.push(l,P,w)):(M.push(P),M.push(w),M.push(L))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:R})},indices:M,primitiveType:_.TRIANGLES})},R.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=f,c=T;if(t=a(t,0),i=a(i,!0),o(e))for(var E=e.length,_=0;_<E;_+=3)n.fromArray(e,_,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[_]=c.x,e[_+1]=c.y,e[_+2]=c.z;return e},R}),define("Core/Matrix2",["./Cartesian2","./Check","./defaultValue","./defined","./defineProperties","./freezeObject"],function(e,t,n,r,i,a){"use strict";function o(e,t,r,i){this[0]=n(e,0),this[1]=n(r,0),this[2]=n(t,0),this[3]=n(i,0)}o.packedLength=4,o.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t},o.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new o),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i},o.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):new o(e[0],e[2],e[1],e[3])},o.fromArray=function(e,t,i){return t=n(t,0), +r(i)||(i=new o),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i},o.fromColumnMajorArray=function(e,t){return o.clone(e,t)},o.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[2],t[2]=e[1],t[3]=e[3],t):new o(e[0],e[1],e[2],e[3])},o.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=e.y,t):new o(e.x,0,0,e.y)},o.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=e,t):new o(e,0,0,e)},o.fromRotation=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=-i,t[3]=n,t):new o(n,-i,i,n)},o.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t):[e[0],e[1],e[2],e[3]]},o.getElementIndex=function(e,t){return 2*e+t},o.getColumn=function(e,t,n){var r=2*t,i=e[r],a=e[r+1];return n.x=i,n.y=a,n},o.setColumn=function(e,t,n,r){r=o.clone(e,r);var i=2*t;return r[i]=n.x,r[i+1]=n.y,r},o.getRow=function(e,t,n){var r=e[t],i=e[t+2];return n.x=r,n.y=i,n},o.setRow=function(e,t,n,r){return r=o.clone(e,r),r[t]=n.x,r[t+2]=n.y,r};var u=new e;o.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],u)),n.y=e.magnitude(e.fromElements(t[2],t[3],u)),n};var s=new e;return o.getMaximumScale=function(t){return o.getScale(t,s),e.maximumComponent(s)},o.multiply=function(e,t,n){var r=e[0]*t[0]+e[2]*t[1],i=e[0]*t[2]+e[2]*t[3],a=e[1]*t[0]+e[3]*t[1],o=e[1]*t[2]+e[3]*t[3];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n},o.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n},o.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n},o.multiplyByVector=function(e,t,n){var r=e[0]*t.x+e[2]*t.y,i=e[1]*t.x+e[3]*t.y;return n.x=r,n.y=i,n},o.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n},o.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.y,n[3]=e[3]*t.y,n},o.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},o.transpose=function(e,t){var n=e[0],r=e[2],i=e[1],a=e[3];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t},o.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t},o.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},o.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]},o.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n},o.IDENTITY=a(new o(1,0,0,1)),o.ZERO=a(new o(0,0,0,0)),o.COLUMN0ROW0=0,o.COLUMN0ROW1=1,o.COLUMN1ROW0=2,o.COLUMN1ROW1=3,i(o.prototype,{length:{get:function(){return o.packedLength}}}),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t){return o.equalsEpsilon(this,e,t)},o.prototype.toString=function(){return"("+this[0]+", "+this[2]+")\n("+this[1]+", "+this[3]+")"},o}),define("Core/RectangleGeometryLibrary",["./Cartesian3","./Cartographic","./defined","./DeveloperError","./GeographicProjection","./Math","./Matrix2","./Rectangle"],function(e,t,n,r,i,a,o,u){"use strict";function s(t,n,r,i,a,u,s){var c=Math.cos(n),E=i*c,_=r*c,l=Math.sin(n),R=i*l,A=r*l;T=d.project(t,T),T=e.subtract(T,h,T);var N=o.fromRotation(n,f);T=o.multiplyByVector(N,T,T),T=e.add(T,h,T),t=d.unproject(T,t),u-=1,s-=1;var y=t.latitude,S=y+u*A,I=y-E*s,p=y-E*s+u*A,m=Math.max(y,S,I,p),M=Math.min(y,S,I,p),O=t.longitude,x=O+u*_,C=O+s*R,g=O+s*R+u*_;return{north:m,south:M,east:Math.max(O,x,C,g),west:Math.min(O,x,C,g),granYCos:E,granYSin:R,granXCos:_,granXSin:A,nwCorner:t}}var c=Math.cos,E=Math.sin,_=Math.sqrt,l={};l.computePosition=function(e,t,r,i,a){var o=e.ellipsoid.radiiSquared,u=e.nwCorner,s=e.rectangle,l=u.latitude-e.granYCos*t+r*e.granXSin,f=c(l),T=E(l),R=o.z*T,h=u.longitude+t*e.granYSin+r*e.granXCos,d=f*c(h),A=f*E(h),N=o.x*d,y=o.y*A,S=_(N*d+y*A+R*T);if(i.x=N/S,i.y=y/S,i.z=R/S,n(e.vertexFormat)&&e.vertexFormat.st){var I=e.stNwCorner;n(I)?(l=I.latitude-e.stGranYCos*t+r*e.stGranXSin,h=I.longitude+t*e.stGranYSin+r*e.stGranXCos,a.x=(h-e.stWest)*e.lonScalar,a.y=(l-e.stSouth)*e.latScalar):(a.x=(h-s.west)*e.lonScalar,a.y=(l-s.south)*e.latScalar)}};var f=new o,T=new e,R=new t,h=new e,d=new i;return l.computeOptions=function(e,t,n,r){var i,o,c,E,_,l=e._granularity,f=e._ellipsoid,T=e._surfaceHeight,A=e._rotation,N=e._stRotation,y=e._extrudedHeight,S=t.east,I=t.west,p=t.north,m=t.south,M=p-m;I>S?(_=a.TWO_PI-I+S,i=Math.ceil(_/l)+1,o=Math.ceil(M/l)+1,c=_/(i-1),E=M/(o-1)):(_=S-I,i=Math.ceil(_/l)+1,o=Math.ceil(M/l)+1,c=_/(i-1),E=M/(o-1)),n=u.northwest(t,n);var O=u.center(t,R);0===A&&0===N||(O.longitude<n.longitude&&(O.longitude+=a.TWO_PI),h=d.project(O,h));var x=E,C=c,g={granYCos:x,granYSin:0,granXCos:C,granXSin:0,ellipsoid:f,surfaceHeight:T,extrudedHeight:y,nwCorner:n,rectangle:t,width:i,height:o};if(0!==A){var v=s(n,A,c,E,O,i,o);p=v.north,m=v.south,S=v.east,I=v.west,g.granYCos=v.granYCos,g.granYSin=v.granYSin,g.granXCos=v.granXCos,g.granXSin=v.granXSin,t.north=p,t.south=m,t.east=S,t.west=I}if(0!==N){A-=N,r=u.northwest(t,r);var U=s(r,A,c,E,O,i,o);g.stGranYCos=U.granYCos,g.stGranXCos=U.granXCos,g.stGranYSin=U.granYSin,g.stGranXSin=U.granXSin,g.stNwCorner=r,g.stWest=U.west,g.stSouth=U.south}return g},l}),define("Core/RectangleOutlineGeometry",["./BoundingSphere","./Cartesian3","./Cartographic","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolygonPipeline","./PrimitiveType","./Rectangle","./RectangleGeometryLibrary"],function(e,t,n,r,i,a,o,u,s,c,E,_,l,f,T,R,h){"use strict";function d(e){var t,n=e.size,i=e.height,a=e.width,o=new Float64Array(3*n),u=0,l=0,f=I;for(t=0;t<a;t++)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(t=a-1,l=1;l<i;l++)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(l=i-1,t=a-2;t>=0;t--)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(t=0,l=i-2;l>0;l--)h.computePosition(e,l,t,f),o[u++]=f.x,o[u++]=f.y,o[u++]=f.z;for(var R=o.length/3*2,d=_.createTypedArray(o.length/3,R),A=0,N=0;N<o.length/3-1;N++)d[A++]=N,d[A++]=N+1;d[A++]=o.length/3-1,d[A++]=0;var y=new s({attributes:new E,primitiveType:T.LINES});return y.attributes.position=new c({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:o}),y.indices=d,y}function A(e){var t=e.surfaceHeight,n=e.extrudedHeight,r=e.ellipsoid,i=Math.min(n,t),a=Math.max(n,t),o=d(e);if(l.equalsEpsilon(i,a,l.EPSILON10))return o;var u=e.height,s=e.width,c=f.scaleToGeodeticHeight(o.attributes.position.values,a,r,!1),E=c.length,T=new Float64Array(2*E);T.set(c);var R=f.scaleToGeodeticHeight(o.attributes.position.values,i,r);T.set(R,E),o.attributes.position.values=T;var h=T.length/3*2+8,A=_.createTypedArray(T.length/3,h);E=T.length/6;for(var N=0,y=0;y<E-1;y++)A[N++]=y,A[N++]=y+1,A[N++]=y+E,A[N++]=y+E+1;return A[N++]=E-1,A[N++]=0,A[N++]=E+E-1,A[N++]=E,A[N++]=0,A[N++]=E,A[N++]=s-1,A[N++]=E+s-1,A[N++]=s+u-2,A[N++]=s+u-2+E,A[N++]=2*s+u-3,A[N++]=2*s+u-3+E,o.indices=A,o}function N(e){e=i(e,i.EMPTY_OBJECT);var t=e.rectangle,n=i(e.granularity,l.RADIANS_PER_DEGREE),r=i(e.ellipsoid,u.WGS84),a=i(e.height,0),o=i(e.rotation,0),s=e.extrudedHeight;this._rectangle=t,this._granularity=n,this._ellipsoid=r,this._surfaceHeight=a,this._rotation=o,this._extrudedHeight=s,this._workerName="createRectangleOutlineGeometry"}var y=new e,S=new e,I=new t,p=new R;N.packedLength=R.packedLength+u.packedLength+5,N.pack=function(e,t,n){return n=i(n,0),R.pack(e._rectangle,t,n),n+=R.packedLength,u.pack(e._ellipsoid,t,n),n+=u.packedLength,t[n++]=e._granularity,t[n++]=e._surfaceHeight,t[n++]=e._rotation,t[n++]=a(e._extrudedHeight)?1:0,t[n]=i(e._extrudedHeight,0),t};var m=new R,M=u.clone(u.UNIT_SPHERE),O={rectangle:m,ellipsoid:M,granularity:void 0,height:void 0,rotation:void 0,extrudedHeight:void 0};N.unpack=function(e,t,n){t=i(t,0);var r=R.unpack(e,t,m);t+=R.packedLength;var o=u.unpack(e,t,M);t+=u.packedLength;var s=e[t++],c=e[t++],E=e[t++],_=e[t++],l=e[t];return a(n)?(n._rectangle=R.clone(r,n._rectangle),n._ellipsoid=u.clone(o,n._ellipsoid),n._surfaceHeight=c,n._rotation=E,n._extrudedHeight=_?l:void 0,n):(O.granularity=s,O.height=c,O.rotation=E,O.extrudedHeight=_?l:void 0,new N(O))};var x=new n;return N.createGeometry=function(t){var n=R.clone(t._rectangle,p),r=t._ellipsoid,i=t._surfaceHeight,o=t._extrudedHeight,u=h.computeOptions(t,n,x);u.size=2*u.width+2*u.height-4;var c,E;if(n=t._rectangle,!l.equalsEpsilon(n.north,n.south,l.EPSILON10)&&!l.equalsEpsilon(n.east,n.west,l.EPSILON10)){if(a(o)){c=A(u);var _=e.fromRectangle3D(n,r,i,S),N=e.fromRectangle3D(n,r,o,y);E=e.union(_,N)}else c=d(u),c.attributes.position.values=f.scaleToGeodeticHeight(c.attributes.position.values,i,r,!1),E=e.fromRectangle3D(n,r,i);return new s({attributes:c.attributes,indices:c.indices,primitiveType:T.LINES,boundingSphere:E})}},N}),define("Workers/createRectangleOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/Rectangle","../Core/RectangleOutlineGeometry"],function(e,t,n,r){"use strict";function i(i,a){return e(a)&&(i=r.unpack(i,a)),i._ellipsoid=t.clone(i._ellipsoid),i._rectangle=n.clone(i._rectangle),r.createGeometry(i)}return i})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSimplePolylineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSimplePolylineGeometry.js index 49194c44..efb2d564 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSimplePolylineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSimplePolylineGeometry.js @@ -55,7 +55,7 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function r(e){return e+" is required, actual value was undefined"}function n(e,t,r){return"Expected "+r+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(n,a){if(!e(a))throw new t(r(n))},a.typeOf.func=function(e,r){if("function"!=typeof r)throw new t(n(typeof r,"function",e))},a.typeOf.string=function(e,r){if("string"!=typeof r)throw new t(n(typeof r,"string",e))},a.typeOf.number=function(e,r){if("number"!=typeof r)throw new t(n(typeof r,"number",e))},a.typeOf.number.lessThan=function(e,r,n){if(a.typeOf.number(e,r),r>=n)throw new t("Expected "+e+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r>n)throw new t("Expected "+e+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(e,r,n){if(a.typeOf.number(e,r),r<=n)throw new t("Expected "+e+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(e,r,n){if(a.typeOf.number(e,r),r<n)throw new t("Expected "+e+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(e,r){if("object"!=typeof r)throw new t(n(typeof r,"object",e))},a.typeOf.bool=function(e,r){if("boolean"!=typeof r)throw new t(n(typeof r,"boolean",e))},a.typeOf.number.equals=function(e,r,n,o){if(a.typeOf.number(e,n),a.typeOf.number(r,o),n!==o)throw new t(e+" must be equal to "+r+", the actual values are "+n+" and "+o)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^e>>>1^t[1&e];for(;r<this.N-1;r++)e=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,r){return r=t(r,255),Math.round((.5*a.clamp(e,-1,1)+.5)*r)},a.fromSNorm=function(e,r){return r=t(r,255),a.clamp(e,0,r)/r*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,r){return(1-r)*e+r*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,r=e-Math.floor(e/t)*t;return r<-Math.PI?r+t:r>=Math.PI?r-t:r},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,r,n,a){a=t(a,n);var o=Math.abs(e-r);return o<=a||o<=n*Math.max(Math.abs(e),Math.abs(r))};var o=[1];a.factorial=function(e){var t=o.length;if(e>=t)for(var r=o[t-1],n=t;n<=e;n++)o.push(r*n);return o[e]},a.incrementWrap=function(e,r,n){return n=t(n,0),++e,e>r&&(e=n),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,r){return e<t?t:e>r?r:e};var i=new e;return a.setRandomNumberSeed=function(t){i=new e(t)},a.nextRandomNumber=function(){return i.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var r=e*t;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,o){"use strict";function i(e,r,n){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0)}i.fromSpherical=function(e,n){r(n)||(n=new i);var a=e.clock,o=e.cone,u=t(e.magnitude,1),s=u*Math.sin(o);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(o),n},i.fromElements=function(e,t,n,a){return r(a)?(a.x=e,a.y=t,a.z=n,a):new i(e,t,n)},i.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new i(e.x,e.y,e.z)},i.fromCartesian4=i.clone,i.packedLength=3,i.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n]=e.z,r},i.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new i),a.x=e[n++],a.y=e[n++],a.z=e[n],a},i.packArray=function(e,t){var n=e.length;r(t)?t.length=3*n:t=new Array(3*n);for(var a=0;a<n;++a)i.pack(e[a],t,3*a);return t},i.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/3:t=new Array(n/3);for(var a=0;a<n;a+=3){var o=a/3;t[o]=i.unpack(e,a,t[o])}return t},i.fromArray=i.unpack,i.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},i.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},i.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r},i.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r},i.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},i.magnitude=function(e){return Math.sqrt(i.magnitudeSquared(e))};var u=new i;i.distance=function(e,t){return i.subtract(e,t,u),i.magnitude(u)},i.distanceSquared=function(e,t){return i.subtract(e,t,u),i.magnitudeSquared(u)},i.normalize=function(e,t){var r=i.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t},i.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},i.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r},i.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r},i.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r},i.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r},i.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r},i.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r},i.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},i.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new i;i.lerp=function(e,t,r,n){return i.multiplyByScalar(t,r,s),n=i.multiplyByScalar(e,1-r,n),i.add(s,n,n)};var E=new i,l=new i;i.angleBetween=function(e,t){i.normalize(e,E),i.normalize(t,l);var r=i.dot(E,l),n=i.magnitude(i.cross(E,l,E));return Math.atan2(n,r)};var c=new i;i.mostOrthogonalAxis=function(e,t){var r=i.normalize(e,c);return i.abs(r,r),t=r.x<=r.y?r.x<=r.z?i.clone(i.UNIT_X,t):i.clone(i.UNIT_Z,t):r.y<=r.z?i.clone(i.UNIT_Y,t):i.clone(i.UNIT_Z,t)},i.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},i.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]},i.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&o.equalsEpsilon(e.x,t.x,n,a)&&o.equalsEpsilon(e.y,t.y,n,a)&&o.equalsEpsilon(e.z,t.z,n,a)},i.cross=function(e,t,r){var n=e.x,a=e.y,o=e.z,i=t.x,u=t.y,s=t.z,E=a*s-o*u,l=o*i-n*s,c=n*u-a*i;return r.x=E,r.y=l,r.z=c,r},i.fromDegrees=function(e,t,r,n,a){return e=o.toRadians(e),t=o.toRadians(t),i.fromRadians(e,t,r,n,a)};var f=new i,_=new i,R=new i(40680631590769,40680631590769,40408299984661.445);return i.fromRadians=function(e,n,a,o,u){a=t(a,0);var s=r(o)?o.radiiSquared:R,E=Math.cos(n);f.x=E*Math.cos(e),f.y=E*Math.sin(e),f.z=Math.sin(n),f=i.normalize(f,f),i.multiplyComponents(s,f,_);var l=Math.sqrt(i.dot(f,_));return _=i.divideByScalar(_,l,_),f=i.multiplyByScalar(f,a,f),r(u)||(u=new i),i.add(_,f,u)},i.fromDegreesArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=e[o],s=e[o+1],E=o/2;n[E]=i.fromDegrees(u,s,0,t,n[E])}return n},i.fromRadiansArray=function(e,t,n){var a=e.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=e[o],s=e[o+1],E=o/2;n[E]=i.fromRadians(u,s,0,t,n[E])}return n},i.fromDegreesArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=e[o],s=e[o+1],E=e[o+2],l=o/3;n[l]=i.fromDegrees(u,s,E,t,n[l])}return n},i.fromRadiansArrayHeights=function(e,t,n){var a=e.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=e[o],s=e[o+1],E=e[o+2],l=o/3;n[l]=i.fromRadians(u,s,E,t,n[l])}return n},i.ZERO=a(new i(0,0,0)),i.UNIT_X=a(new i(1,0,0)),i.UNIT_Y=a(new i(0,1,0)),i.UNIT_Z=a(new i(0,0,1)),i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i.prototype.equalsEpsilon=function(e,t,r){return i.equalsEpsilon(this,e,t,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,r,n){"use strict";function a(r,a,u,s,E){var l=r.x,c=r.y,f=r.z,_=a.x,R=a.y,T=a.z,h=l*l*_*_,A=c*c*R*R,d=f*f*T*T,S=h+A+d,m=Math.sqrt(1/S),C=e.multiplyByScalar(r,m,o);if(S<s)return isFinite(m)?e.clone(C,E):void 0;var N=u.x,I=u.y,M=u.z,p=i;p.x=C.x*N*2,p.y=C.y*I*2,p.z=C.z*M*2;var O,g,y,F,L,U,v,D,P,B,w,x=(1-m)*e.magnitude(r)/(.5*e.magnitude(p)),G=0;do{x-=G,y=1/(1+x*N),F=1/(1+x*I),L=1/(1+x*M),U=y*y,v=F*F,D=L*L,P=U*y,B=v*F,w=D*L,O=h*U+A*v+d*D-1,g=h*P*N+A*B*I+d*w*M;G=O/(-2*g)}while(Math.abs(O)>n.EPSILON12);return t(E)?(E.x=l*y,E.y=c*F,E.z=f*L,E):new e(l*y,c*F,f*L)}var o=new e,i=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,o,i){"use strict";function u(e,t,n){this.longitude=r(e,0),this.latitude=r(t,0),this.height=r(n,0)}u.fromRadians=function(e,t,a,o){return a=r(a,0),n(o)?(o.longitude=e,o.latitude=t,o.height=a,o):new u(e,t,a)},u.fromDegrees=function(e,t,r,n){return e=o.toRadians(e),t=o.toRadians(t),u.fromRadians(e,t,r,n)};var s=new e,E=new e,l=new e,c=new e(1/6378137,1/6378137,1/6356752.314245179),f=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),_=o.EPSILON1;return u.fromCartesian=function(t,r,a){var R=n(r)?r.oneOverRadii:c,T=n(r)?r.oneOverRadiiSquared:f,h=n(r)?r._centerToleranceSquared:_,A=i(t,R,T,h,E);if(n(A)){var d=e.multiplyComponents(A,T,s);d=e.normalize(d,d);var S=e.subtract(t,A,l),m=Math.atan2(d.y,d.x),C=Math.asin(d.z),N=o.sign(e.dot(S,t))*e.magnitude(S);return n(a)?(a.longitude=m,a.latitude=C,a.height=N,a):new u(m,C,N)}},u.clone=function(e,t){if(n(e))return n(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||n(e)&&n(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e.longitude-t.longitude)<=r&&Math.abs(e.latitude-t.latitude)<=r&&Math.abs(e.height-t.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),r=Object.defineProperties;return t&&e(r)||(r=function(e){return e}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,r,n,a,o,i,u,s,E){"use strict";function l(t,r,a,o){r=n(r,0),a=n(a,0),o=n(o,0),t._radii=new e(r,a,o),t._radiiSquared=new e(r*r,a*a,o*o),t._radiiToTheFourth=new e(r*r*r*r,a*a*a*a,o*o*o*o),t._oneOverRadii=new e(0===r?0:1/r,0===a?0:1/a,0===o?0:1/o),t._oneOverRadiiSquared=new e(0===r?0:1/(r*r),0===a?0:1/(a*a),0===o?0:1/(o*o)),t._minimumRadius=Math.min(r,a,o),t._maximumRadius=Math.max(r,a,o),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function c(e,t,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,r)}o(c.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),c.clone=function(t,r){if(a(t)){var n=t._radii;return a(r)?(e.clone(n,r._radii),e.clone(t._radiiSquared,r._radiiSquared),e.clone(t._radiiToTheFourth,r._radiiToTheFourth),e.clone(t._oneOverRadii,r._oneOverRadii),e.clone(t._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=t._minimumRadius,r._maximumRadius=t._maximumRadius,r._centerToleranceSquared=t._centerToleranceSquared,r):new c(n.x,n.y,n.z)}},c.fromCartesian3=function(e,t){return a(t)||(t=new c),a(e)?(l(t,e.x,e.y,e.z),t):t},c.WGS84=u(new c(6378137,6378137,6356752.314245179)),c.UNIT_SPHERE=u(new c(1,1,1)),c.MOON=u(new c(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),c.prototype.clone=function(e){return c.clone(this,e)},c.packedLength=e.packedLength,c.pack=function(t,r,a){return a=n(a,0),e.pack(t._radii,r,a),r},c.unpack=function(t,r,a){r=n(r,0);var o=e.unpack(t,r);return c.fromCartesian3(o,a)},c.prototype.geocentricSurfaceNormal=e.normalize,c.prototype.geodeticSurfaceNormalCartographic=function(t,r){var n=t.longitude,o=t.latitude,i=Math.cos(o),u=i*Math.cos(n),s=i*Math.sin(n),E=Math.sin(o);return a(r)||(r=new e),r.x=u,r.y=s,r.z=E,e.normalize(r,r)},c.prototype.geodeticSurfaceNormal=function(t,r){return a(r)||(r=new e),r=e.multiplyComponents(t,this._oneOverRadiiSquared,r),e.normalize(r,r)};var f=new e,_=new e;c.prototype.cartographicToCartesian=function(t,r){var n=f,o=_;this.geodeticSurfaceNormalCartographic(t,n),e.multiplyComponents(this._radiiSquared,n,o);var i=Math.sqrt(e.dot(n,o));return e.divideByScalar(o,i,o),e.multiplyByScalar(n,t.height,n),a(r)||(r=new e),e.add(o,n,r)},c.prototype.cartographicArrayToCartesianArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;n++)t[n]=this.cartographicToCartesian(e[n],t[n]);return t};var R=new e,T=new e,h=new e;return c.prototype.cartesianToCartographic=function(r,n){var o=this.scaleToGeodeticSurface(r,T);if(a(o)){var i=this.geodeticSurfaceNormal(o,R),u=e.subtract(r,o,h),E=Math.atan2(i.y,i.x),l=Math.asin(i.z),c=s.sign(e.dot(u,r))*e.magnitude(u);return a(n)?(n.longitude=E,n.latitude=l,n.height=c,n):new t(E,l,c)}},c.prototype.cartesianArrayToCartographicArray=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var n=0;n<r;++n)t[n]=this.cartesianToCartographic(e[n],t[n]);return t},c.prototype.scaleToGeodeticSurface=function(e,t){return E(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},c.prototype.scaleToGeocentricSurface=function(t,r){a(r)||(r=new e);var n=t.x,o=t.y,i=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+o*o*u.y+i*i*u.z);return e.multiplyByScalar(t,s,r)},c.prototype.transformPositionToScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._oneOverRadii,r)},c.prototype.transformPositionFromScaledSpace=function(t,r){return a(r)||(r=new e),e.multiplyComponents(t,this._radii,r)},c.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},c.prototype.toString=function(){return this._radii.toString()},c.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,r,o){r=n(r,0);var i=this._squaredXOverSquaredZ;if(a(o)||(o=new e),o.x=0,o.y=0,o.z=t.z*(1-i),!(Math.abs(o.z)>=this._radii.z-r))return o},c}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,r,n,a,o,i){"use strict";function u(e){this._ellipsoid=r(e,i.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,r){var a=this._semimajorAxis,o=t.longitude*a,i=t.latitude*a,u=t.height;return n(r)?(r.x=o,r.y=i,r.z=u,r):new e(o,i,u)},u.prototype.unproject=function(e,r){var a=this._oneOverSemimajorAxis,o=e.x*a,i=e.y*a,u=e.z;return n(r)?(r.longitude=o,r.latitude=i,r.height=u,r):new t(o,i,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,r){this.start=e(t,0),this.stop=e(r,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,o,i,u){"use strict";function s(e,t,n,a,o,i,u,s,E){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(t,0),this[4]=r(o,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(i,0),this[8]=r(E,0)}function E(e){for(var t=0,r=0;r<9;++r){var n=e[r];t+=n*n}return Math.sqrt(t)}function l(e){for(var t=0,r=0;r<3;++r){var n=e[s.getElementIndex(T[r],R[r])];t+=2*n*n}return Math.sqrt(t)}function c(e,t){for(var r=u.EPSILON15,n=0,a=1,o=0;o<3;++o){var i=Math.abs(e[s.getElementIndex(T[o],R[o])]);i>n&&(a=o,n=i)}var E=1,l=0,c=R[a],f=T[a];if(Math.abs(e[s.getElementIndex(f,c)])>r){var _,h=e[s.getElementIndex(f,f)],A=e[s.getElementIndex(c,c)],d=e[s.getElementIndex(f,c)],S=(h-A)/2/d;_=S<0?-1/(-S+Math.sqrt(1+S*S)):1/(S+Math.sqrt(1+S*S)),E=1/Math.sqrt(1+_*_),l=_*E}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(c,c)]=t[s.getElementIndex(f,f)]=E,t[s.getElementIndex(f,c)]=l,t[s.getElementIndex(c,f)]=-l,t}s.packedLength=9,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(n(e))return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var r=e.x*e.x,a=e.x*e.y,o=e.x*e.z,i=e.x*e.w,u=e.y*e.y,E=e.y*e.z,l=e.y*e.w,c=e.z*e.z,f=e.z*e.w,_=e.w*e.w,R=r-u-c+_,T=2*(a-f),h=2*(o+l),A=2*(a+f),d=-r+u-c+_,S=2*(E-i),m=2*(o-l),C=2*(E+i),N=-r-u+c+_;return n(t)?(t[0]=R,t[1]=A,t[2]=m,t[3]=T,t[4]=d,t[5]=C,t[6]=h,t[7]=S,t[8]=N,t):new s(R,T,h,A,d,S,m,C,N)},s.fromHeadingPitchRoll=function(e,t){var r=Math.cos(-e.pitch),a=Math.cos(-e.heading),o=Math.cos(e.roll),i=Math.sin(-e.pitch),u=Math.sin(-e.heading),E=Math.sin(e.roll),l=r*a,c=-o*u+E*i*a,f=E*u+o*i*a,_=r*u,R=o*a+E*i*u,T=-E*a+o*i*u,h=-i,A=E*r,d=o*r;return n(t)?(t[0]=l,t[1]=_,t[2]=h,t[3]=c,t[4]=R,t[5]=A,t[6]=f,t[7]=T,t[8]=d,t):new s(l,c,f,_,R,T,h,A,d)},s.fromScale=function(e,t){return n(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return n(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return n(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=r,t[5]=a,t[6]=0,t[7]=-a,t[8]=r,t):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=r,t):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(e,t){var r=Math.cos(e),a=Math.sin(e);return n(t)?(t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(e,t){return n(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,r){var n=3*t,a=e[n],o=e[n+1],i=e[n+2];return r.x=a,r.y=o,r.z=i,r},s.setColumn=function(e,t,r,n){n=s.clone(e,n);var a=3*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(e,t,r){var n=e[t],a=e[t+3],o=e[t+6];return r.x=n,r.y=a,r.z=o,r},s.setRow=function(e,t,r,n){return n=s.clone(e,n),n[t]=r.x,n[t+3]=r.y,n[t+6]=r.z,n};var f=new e;s.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],f)),r.y=e.magnitude(e.fromElements(t[3],t[4],t[5],f)),r.z=e.magnitude(e.fromElements(t[6],t[7],t[8],f)),r};var _=new e;s.getMaximumScale=function(t){return s.getScale(t,_),e.maximumComponent(_)},s.multiply=function(e,t,r){var n=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],o=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],i=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],E=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],c=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return r[0]=n,r[1]=a,r[2]=o,r[3]=i,r[4]=u,r[5]=s,r[6]=E,r[7]=l,r[8]=c,r},s.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r},s.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r},s.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,o=t.z,i=e[0]*n+e[3]*a+e[6]*o,u=e[1]*n+e[4]*a+e[7]*o,s=e[2]*n+e[5]*a+e[8]*o;return r.x=i,r.y=u,r.z=s,r},s.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r},s.multiplyByScale=function(e,t,r){return r[0]=e[0]*t.x,r[1]=e[1]*t.x,r[2]=e[2]*t.x,r[3]=e[3]*t.y,r[4]=e[4]*t.y,r[5]=e[5]*t.y,r[6]=e[6]*t.z,r[7]=e[7]*t.z,r[8]=e[8]*t.z,r},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var r=e[0],n=e[3],a=e[6],o=e[1],i=e[4],u=e[7],s=e[2],E=e[5],l=e[8];return t[0]=r,t[1]=n,t[2]=a,t[3]=o,t[4]=i,t[5]=u,t[6]=s,t[7]=E,t[8]=l,t};var R=[1,0,0],T=[2,2,1],h=new s,A=new s;return s.computeEigenDecomposition=function(e,t){var r=u.EPSILON20,a=0,o=0;n(t)||(t={});for(var i=t.unitary=s.clone(s.IDENTITY,t.unitary),f=t.diagonal=s.clone(e,t.diagonal),_=r*E(f);o<10&&l(f)>_;)c(f,h),s.transpose(h,A),s.multiply(f,h,f),s.multiply(A,f,f),s.multiply(i,h,i),++a>2&&(++o,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],r=e[3],n=e[6],a=e[1],o=e[4],i=e[7],u=e[2],s=e[5],E=e[8];return t*(o*E-s*i)+a*(s*n-r*E)+u*(r*i-o*n)},s.inverse=function(e,t){var r=e[0],n=e[1],a=e[2],o=e[3],i=e[4],u=e[5],E=e[6],l=e[7],c=e[8],f=s.determinant(e);t[0]=i*c-l*u,t[1]=l*a-n*c,t[2]=n*u-i*a,t[3]=E*u-o*c,t[4]=r*c-E*a,t[5]=o*a-r*u,t[6]=o*l-E*i,t[7]=E*n-r*l,t[8]=r*i-o*n;var _=1/f;return s.multiplyByScalar(t,_,t)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,r){return e===t||n(e)&&n(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r},s.IDENTITY=i(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=i(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,r,n,a,o){"use strict";function i(e,r,n,a){this.x=t(e,0),this.y=t(r,0),this.z=t(n,0),this.w=t(a,0)}i.fromElements=function(e,t,n,a,o){return r(o)?(o.x=e,o.y=t,o.z=n,o.w=a,o):new i(e,t,n,a)},i.fromColor=function(e,t){return r(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new i(e.red,e.green,e.blue,e.alpha)},i.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new i(e.x,e.y,e.z,e.w)},i.packedLength=4,i.pack=function(e,r,n){return n=t(n,0),r[n++]=e.x,r[n++]=e.y,r[n++]=e.z,r[n]=e.w,r},i.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new i),a.x=e[n++],a.y=e[n++],a.z=e[n++],a.w=e[n],a},i.packArray=function(e,t){var n=e.length;r(t)?t.length=4*n:t=new Array(4*n);for(var a=0;a<n;++a)i.pack(e[a],t,4*a);return t},i.unpackArray=function(e,t){var n=e.length;r(t)?t.length=n/4:t=new Array(n/4);for(var a=0;a<n;a+=4){var o=a/4;t[o]=i.unpack(e,a,t[o])}return t},i.fromArray=i.unpack,i.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},i.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},i.minimumByComponent=function(e,t,r){return r.x=Math.min(e.x,t.x),r.y=Math.min(e.y,t.y),r.z=Math.min(e.z,t.z),r.w=Math.min(e.w,t.w),r},i.maximumByComponent=function(e,t,r){return r.x=Math.max(e.x,t.x),r.y=Math.max(e.y,t.y),r.z=Math.max(e.z,t.z),r.w=Math.max(e.w,t.w),r},i.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},i.magnitude=function(e){return Math.sqrt(i.magnitudeSquared(e))};var u=new i;i.distance=function(e,t){return i.subtract(e,t,u),i.magnitude(u)},i.distanceSquared=function(e,t){return i.subtract(e,t,u),i.magnitudeSquared(u)},i.normalize=function(e,t){var r=i.magnitude(e);return t.x=e.x/r,t.y=e.y/r,t.z=e.z/r,t.w=e.w/r,t},i.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},i.multiplyComponents=function(e,t,r){return r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w,r},i.divideComponents=function(e,t,r){return r.x=e.x/t.x,r.y=e.y/t.y,r.z=e.z/t.z,r.w=e.w/t.w,r},i.add=function(e,t,r){return r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w,r},i.subtract=function(e,t,r){return r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w,r},i.multiplyByScalar=function(e,t,r){return r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t,r},i.divideByScalar=function(e,t,r){return r.x=e.x/t,r.y=e.y/t,r.z=e.z/t,r.w=e.w/t,r},i.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},i.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new i;i.lerp=function(e,t,r,n){return i.multiplyByScalar(t,r,s),n=i.multiplyByScalar(e,1-r,n),i.add(s,n,n)};var E=new i;return i.mostOrthogonalAxis=function(e,t){var r=i.normalize(e,E);return i.abs(r,r),t=r.x<=r.y?r.x<=r.z?r.x<=r.w?i.clone(i.UNIT_X,t):i.clone(i.UNIT_W,t):r.z<=r.w?i.clone(i.UNIT_Z,t):i.clone(i.UNIT_W,t):r.y<=r.z?r.y<=r.w?i.clone(i.UNIT_Y,t):i.clone(i.UNIT_W,t):r.z<=r.w?i.clone(i.UNIT_Z,t):i.clone(i.UNIT_W,t)},i.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},i.equalsArray=function(e,t,r){return e.x===t[r]&&e.y===t[r+1]&&e.z===t[r+2]&&e.w===t[r+3]},i.equalsEpsilon=function(e,t,n,a){return e===t||r(e)&&r(t)&&o.equalsEpsilon(e.x,t.x,n,a)&&o.equalsEpsilon(e.y,t.y,n,a)&&o.equalsEpsilon(e.z,t.z,n,a)&&o.equalsEpsilon(e.w,t.w,n,a)},i.ZERO=a(new i(0,0,0,0)),i.UNIT_X=a(new i(1,0,0,0)),i.UNIT_Y=a(new i(0,1,0,0)),i.UNIT_Z=a(new i(0,0,1,0)),i.UNIT_W=a(new i(0,0,0,1)),i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i.prototype.equalsEpsilon=function(e,t,r){return i.equalsEpsilon(this,e,t,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},i}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,r,n,a,o,i,u,s,E){"use strict";function l(e,t,r,a,o,i,u,s,E,l,c,f,_,R,T,h){this[0]=n(e,0),this[1]=n(o,0),this[2]=n(E,0),this[3]=n(_,0),this[4]=n(t,0),this[5]=n(i,0),this[6]=n(l,0),this[7]=n(R,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(c,0),this[11]=n(T,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(h,0)}l.packedLength=16,l.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t[r++]=e[9],t[r++]=e[10],t[r++]=e[11],t[r++]=e[12],t[r++]=e[13],t[r++]=e[14],t[r]=e[15],t},l.unpack=function(e,t,r){return t=n(t,0),a(r)||(r=new l),r[0]=e[t++],r[1]=e[t++],r[2]=e[t++],r[3]=e[t++],r[4]=e[t++],r[5]=e[t++],r[6]=e[t++],r[7]=e[t++],r[8]=e[t++],r[9]=e[t++],r[10]=e[t++],r[11]=e[t++],r[12]=e[t++],r[13]=e[t++],r[14]=e[t++],r[15]=e[t],r},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,r,o){return r=n(r,e.ZERO),a(o)?(o[0]=t[0],o[1]=t[1],o[2]=t[2],o[3]=0,o[4]=t[3],o[5]=t[4],o[6]=t[5],o[7]=0,o[8]=t[6],o[9]=t[7],o[10]=t[8],o[11]=0,o[12]=r.x,o[13]=r.y,o[14]=r.z,o[15]=1,o):new l(t[0],t[3],t[6],r.x,t[1],t[4],t[7],r.y,t[2],t[5],t[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,r,n){a(n)||(n=new l);var o=r.x,i=r.y,u=r.z,s=t.x*t.x,E=t.x*t.y,c=t.x*t.z,f=t.x*t.w,_=t.y*t.y,R=t.y*t.z,T=t.y*t.w,h=t.z*t.z,A=t.z*t.w,d=t.w*t.w,S=s-_-h+d,m=2*(E-A),C=2*(c+T),N=2*(E+A),I=-s+_-h+d,M=2*(R-f),p=2*(c-T),O=2*(R+f),g=-s-_+h+d;return n[0]=S*o,n[1]=N*o,n[2]=p*o,n[3]=0,n[4]=m*i,n[5]=I*i,n[6]=O*i,n[7]=0,n[8]=C*u,n[9]=M*u,n[10]=g*u,n[11]=0,n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=1,n},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var c=new e,f=new e,_=new e;l.fromCamera=function(t,r){var n=t.position,o=t.direction,i=t.up;e.normalize(o,c),e.normalize(e.cross(c,i,f),f),e.normalize(e.cross(f,c,_),_);var u=f.x,s=f.y,E=f.z,R=c.x,T=c.y,h=c.z,A=_.x,d=_.y,S=_.z,m=n.x,C=n.y,N=n.z,I=u*-m+s*-C+E*-N,M=A*-m+d*-C+S*-N,p=R*m+T*C+h*N;return a(r)?(r[0]=u,r[1]=A,r[2]=-R,r[3]=0,r[4]=s,r[5]=d,r[6]=-T,r[7]=0,r[8]=E,r[9]=S,r[10]=-h,r[11]=0,r[12]=I,r[13]=M,r[14]=p,r[15]=1,r):new l(u,s,E,I,A,d,S,M,-R,-T,-h,p,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,r,n,a){var o=Math.tan(.5*e),i=1/o,u=i/t,s=(n+r)/(r-n),E=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=i,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,r,n,a,o,i){var u=1/(t-e),s=1/(n-r),E=1/(o-a),l=-(t+e)*u,c=-(n+r)*s,f=-(o+a)*E;return u*=2,s*=2,E*=-2,i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=l,i[13]=c,i[14]=f,i[15]=1,i},l.computePerspectiveOffCenter=function(e,t,r,n,a,o,i){var u=2*a/(t-e),s=2*a/(n-r),E=(t+e)/(t-e),l=(n+r)/(n-r),c=-(o+a)/(o-a),f=-2*o*a/(o-a);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=E,i[9]=l,i[10]=c,i[11]=-1,i[12]=0,i[13]=0,i[14]=f,i[15]=0,i},l.computeInfinitePerspectiveOffCenter=function(e,t,r,n,a,o){var i=2*a/(t-e),u=2*a/(n-r),s=(t+e)/(t-e),E=(n+r)/(n-r),l=-2*a;return o[0]=i,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=u,o[6]=0,o[7]=0,o[8]=s,o[9]=E,o[10]=-1,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},l.computeViewportTransformation=function(e,t,r,a){e=n(e,n.EMPTY_OBJECT);var o=n(e.x,0),i=n(e.y,0),u=n(e.width,0),s=n(e.height,0);t=n(t,0),r=n(r,1);var E=.5*u,l=.5*s,c=.5*(r-t),f=E,_=l,R=c,T=o+E,h=i+l,A=t+c;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=_,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=T,a[13]=h,a[14]=A,a[15]=1,a},l.computeView=function(t,r,n,a,o){return o[0]=a.x,o[1]=n.x,o[2]=-r.x,o[3]=0,o[4]=a.y,o[5]=n.y,o[6]=-r.y,o[7]=0,o[8]=a.z,o[9]=n.z,o[10]=-r.z,o[11]=0,o[12]=-e.dot(a,t),o[13]=-e.dot(n,t),o[14]=e.dot(r,t),o[15]=1,o},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,r){var n=4*t,a=e[n],o=e[n+1],i=e[n+2],u=e[n+3];return r.x=a,r.y=o,r.z=i,r.w=u,r},l.setColumn=function(e,t,r,n){n=l.clone(e,n);var a=4*t;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(e,t,r){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=e[15],r},l.getRow=function(e,t,r){var n=e[t],a=e[t+4],o=e[t+8],i=e[t+12];return r.x=n,r.y=a,r.z=o,r.w=i,r},l.setRow=function(e,t,r,n){return n=l.clone(e,n),n[t]=r.x,n[t+4]=r.y,n[t+8]=r.z,n[t+12]=r.w,n};var R=new e;l.getScale=function(t,r){return r.x=e.magnitude(e.fromElements(t[0],t[1],t[2],R)),r.y=e.magnitude(e.fromElements(t[4],t[5],t[6],R)),r.z=e.magnitude(e.fromElements(t[8],t[9],t[10],R)),r};var T=new e;l.getMaximumScale=function(t){return l.getScale(t,T),e.maximumComponent(T)},l.multiply=function(e,t,r){var n=e[0],a=e[1],o=e[2],i=e[3],u=e[4],s=e[5],E=e[6],l=e[7],c=e[8],f=e[9],_=e[10],R=e[11],T=e[12],h=e[13],A=e[14],d=e[15],S=t[0],m=t[1],C=t[2],N=t[3],I=t[4],M=t[5],p=t[6],O=t[7],g=t[8],y=t[9],F=t[10],L=t[11],U=t[12],v=t[13],D=t[14],P=t[15],B=n*S+u*m+c*C+T*N,w=a*S+s*m+f*C+h*N,x=o*S+E*m+_*C+A*N,G=i*S+l*m+R*C+d*N,b=n*I+u*M+c*p+T*O,z=a*I+s*M+f*p+h*O,H=o*I+E*M+_*p+A*O,V=i*I+l*M+R*p+d*O,X=n*g+u*y+c*F+T*L,q=a*g+s*y+f*F+h*L,W=o*g+E*y+_*F+A*L,Y=i*g+l*y+R*F+d*L,K=n*U+u*v+c*D+T*P,k=a*U+s*v+f*D+h*P,Z=o*U+E*v+_*D+A*P,j=i*U+l*v+R*D+d*P;return r[0]=B,r[1]=w,r[2]=x,r[3]=G,r[4]=b,r[5]=z,r[6]=H,r[7]=V,r[8]=X,r[9]=q,r[10]=W,r[11]=Y,r[12]=K,r[13]=k,r[14]=Z,r[15]=j,r},l.add=function(e,t,r){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},l.subtract=function(e,t,r){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},l.multiplyTransformation=function(e,t,r){var n=e[0],a=e[1],o=e[2],i=e[4],u=e[5],s=e[6],E=e[8],l=e[9],c=e[10],f=e[12],_=e[13],R=e[14],T=t[0],h=t[1],A=t[2],d=t[4],S=t[5],m=t[6],C=t[8],N=t[9],I=t[10],M=t[12],p=t[13],O=t[14],g=n*T+i*h+E*A,y=a*T+u*h+l*A,F=o*T+s*h+c*A,L=n*d+i*S+E*m,U=a*d+u*S+l*m,v=o*d+s*S+c*m,D=n*C+i*N+E*I,P=a*C+u*N+l*I,B=o*C+s*N+c*I,w=n*M+i*p+E*O+f,x=a*M+u*p+l*O+_,G=o*M+s*p+c*O+R;return r[0]=g,r[1]=y,r[2]=F,r[3]=0,r[4]=L,r[5]=U,r[6]=v,r[7]=0,r[8]=D,r[9]=P,r[10]=B,r[11]=0,r[12]=w,r[13]=x,r[14]=G,r[15]=1,r},l.multiplyByMatrix3=function(e,t,r){var n=e[0],a=e[1],o=e[2],i=e[4],u=e[5],s=e[6],E=e[8],l=e[9],c=e[10],f=t[0],_=t[1],R=t[2],T=t[3],h=t[4],A=t[5],d=t[6],S=t[7],m=t[8],C=n*f+i*_+E*R,N=a*f+u*_+l*R,I=o*f+s*_+c*R,M=n*T+i*h+E*A,p=a*T+u*h+l*A,O=o*T+s*h+c*A,g=n*d+i*S+E*m,y=a*d+u*S+l*m,F=o*d+s*S+c*m;return r[0]=C,r[1]=N,r[2]=I,r[3]=0,r[4]=M,r[5]=p,r[6]=O,r[7]=0,r[8]=g,r[9]=y,r[10]=F,r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=e[15],r},l.multiplyByTranslation=function(e,t,r){var n=t.x,a=t.y,o=t.z,i=n*e[0]+a*e[4]+o*e[8]+e[12],u=n*e[1]+a*e[5]+o*e[9]+e[13],s=n*e[2]+a*e[6]+o*e[10]+e[14];return r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=e[3],r[4]=e[4],r[5]=e[5],r[6]=e[6],r[7]=e[7],r[8]=e[8],r[9]=e[9],r[10]=e[10],r[11]=e[11],r[12]=i,r[13]=u,r[14]=s,r[15]=e[15],r};var h=new e;l.multiplyByUniformScale=function(e,t,r){return h.x=t,h.y=t,h.z=t,l.multiplyByScale(e,h,r)},l.multiplyByScale=function(e,t,r){var n=t.x,a=t.y,o=t.z;return 1===n&&1===a&&1===o?l.clone(e,r):(r[0]=n*e[0],r[1]=n*e[1],r[2]=n*e[2],r[3]=0,r[4]=a*e[4],r[5]=a*e[5],r[6]=a*e[6],r[7]=0,r[8]=o*e[8],r[9]=o*e[9],r[10]=o*e[10],r[11]=0,r[12]=e[12],r[13]=e[13],r[14]=e[14],r[15]=1,r)},l.multiplyByVector=function(e,t,r){var n=t.x,a=t.y,o=t.z,i=t.w,u=e[0]*n+e[4]*a+e[8]*o+e[12]*i,s=e[1]*n+e[5]*a+e[9]*o+e[13]*i,E=e[2]*n+e[6]*a+e[10]*o+e[14]*i,l=e[3]*n+e[7]*a+e[11]*o+e[15]*i;return r.x=u,r.y=s,r.z=E,r.w=l,r},l.multiplyByPointAsVector=function(e,t,r){var n=t.x,a=t.y,o=t.z,i=e[0]*n+e[4]*a+e[8]*o,u=e[1]*n+e[5]*a+e[9]*o,s=e[2]*n+e[6]*a+e[10]*o;return r.x=i,r.y=u,r.z=s,r},l.multiplyByPoint=function(e,t,r){var n=t.x,a=t.y,o=t.z,i=e[0]*n+e[4]*a+e[8]*o+e[12],u=e[1]*n+e[5]*a+e[9]*o+e[13],s=e[2]*n+e[6]*a+e[10]*o+e[14];return r.x=i,r.y=u,r.z=s,r},l.multiplyByScalar=function(e,t,r){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var r=e[1],n=e[2],a=e[3],o=e[6],i=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=r,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=n,t[9]=o,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=i,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,r){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=r&&Math.abs(e[1]-t[1])<=r&&Math.abs(e[2]-t[2])<=r&&Math.abs(e[3]-t[3])<=r&&Math.abs(e[4]-t[4])<=r&&Math.abs(e[5]-t[5])<=r&&Math.abs(e[6]-t[6])<=r&&Math.abs(e[7]-t[7])<=r&&Math.abs(e[8]-t[8])<=r&&Math.abs(e[9]-t[9])<=r&&Math.abs(e[10]-t[10])<=r&&Math.abs(e[11]-t[11])<=r&&Math.abs(e[12]-t[12])<=r&&Math.abs(e[13]-t[13])<=r&&Math.abs(e[14]-t[14])<=r&&Math.abs(e[15]-t[15])<=r},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var A=new s,d=new s,S=new t,m=new t(0,0,0,1);return l.inverse=function(e,r){if(s.equalsEpsilon(l.getRotation(e,A),d,u.EPSILON7)&&t.equals(l.getRow(e,3,S),m))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-e[12],r[13]=-e[13],r[14]=-e[14],r[15]=1,r;var n=e[0],a=e[4],o=e[8],i=e[12],c=e[1],f=e[5],_=e[9],R=e[13],T=e[2],h=e[6],C=e[10],N=e[14],I=e[3],M=e[7],p=e[11],O=e[15],g=C*O,y=N*p,F=h*O,L=N*M,U=h*p,v=C*M,D=T*O,P=N*I,B=T*p,w=C*I,x=T*M,G=h*I,b=g*f+L*_+U*R-(y*f+F*_+v*R),z=y*c+D*_+w*R-(g*c+P*_+B*R),H=F*c+P*f+x*R-(L*c+D*f+G*R),V=v*c+B*f+G*_-(U*c+w*f+x*_),X=y*a+F*o+v*i-(g*a+L*o+U*i),q=g*n+P*o+B*i-(y*n+D*o+w*i),W=L*n+D*a+G*i-(F*n+P*a+x*i),Y=U*n+w*a+x*o-(v*n+B*a+G*o);g=o*R,y=i*_,F=a*R,L=i*f,U=a*_,v=o*f,D=n*R,P=i*c,B=n*_,w=o*c,x=n*f,G=a*c;var K=g*M+L*p+U*O-(y*M+F*p+v*O),k=y*I+D*p+w*O-(g*I+P*p+B*O),Z=F*I+P*M+x*O-(L*I+D*M+G*O),j=v*I+B*M+G*p-(U*I+w*M+x*p),Q=F*C+v*N+y*h-(U*N+g*h+L*C),J=B*N+g*T+P*C-(D*C+w*N+y*T),$=D*h+G*N+L*T-(x*N+F*T+P*h),ee=x*C+U*T+w*h-(B*h+G*C+v*T),te=n*b+a*z+o*H+i*V;if(Math.abs(te)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return te=1/te,r[0]=b*te,r[1]=z*te,r[2]=H*te,r[3]=V*te,r[4]=X*te,r[5]=q*te,r[6]=W*te,r[7]=Y*te,r[8]=K*te,r[9]=k*te,r[10]=Z*te,r[11]=j*te,r[12]=Q*te,r[13]=J*te,r[14]=$*te,r[15]=ee*te,r},l.inverseTransformation=function(e,t){var r=e[0],n=e[1],a=e[2],o=e[4],i=e[5],u=e[6],s=e[8],E=e[9],l=e[10],c=e[12],f=e[13],_=e[14],R=-r*c-n*f-a*_,T=-o*c-i*f-u*_,h=-s*c-E*f-l*_;return t[0]=r,t[1]=o,t[2]=s,t[3]=0,t[4]=n,t[5]=i,t[6]=E,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=R,t[13]=T,t[14]=h,t[15]=1,t},l.IDENTITY=i(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=i(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,o(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,r){return e[0]===t[r]&&e[1]===t[r+1]&&e[2]===t[r+2]&&e[3]===t[r+3]&&e[4]===t[r+4]&&e[5]===t[r+5]&&e[6]===t[r+6]&&e[7]===t[r+7]&&e[8]===t[r+8]&&e[9]===t[r+9]&&e[10]===t[r+10]&&e[11]===t[r+11]&&e[12]===t[r+12]&&e[13]===t[r+13]&&e[14]===t[r+14]&&e[15]===t[r+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,r,n,a,o,i,u){"use strict";function s(e,t,n,a){this.west=r(e,0),this.south=r(t,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,n){return n=r(n,0),t[n++]=e.west,t[n++]=e.south,t[n++]=e.east,t[n]=e.north,t},s.unpack=function(e,t,a){return t=r(t,0),n(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,r=e.west;return t<r&&(t+=u.TWO_PI),t-r},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,o,i){return e=u.toRadians(r(e,0)),t=u.toRadians(r(t,0)),a=u.toRadians(r(a,0)),o=u.toRadians(r(o,0)),n(i)?(i.west=e,i.south=t,i.east=a,i.north=o,i):new s(e,t,a,o)},s.fromRadians=function(e,t,a,o,i){return n(i)?(i.west=r(e,0),i.south=r(t,0),i.east=r(a,0),i.north=r(o,0),i):new s(e,t,a,o)},s.fromCartographicArray=function(e,t){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,o=Number.MAX_VALUE,i=-Number.MAX_VALUE,E=Number.MAX_VALUE,l=-Number.MAX_VALUE,c=0,f=e.length;c<f;c++){var _=e[c];r=Math.min(r,_.longitude),a=Math.max(a,_.longitude),E=Math.min(E,_.latitude),l=Math.max(l,_.latitude);var R=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;o=Math.min(o,R),i=Math.max(i,R)}return a-r>i-o&&(r=o,a=i,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(t)?(t.west=r,t.south=E,t.east=a,t.north=l,t):new s(r,E,a,l)},s.fromCartesianArray=function(e,t,a){t=r(t,o.WGS84);for(var i=Number.MAX_VALUE,E=-Number.MAX_VALUE,l=Number.MAX_VALUE,c=-Number.MAX_VALUE,f=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=0,T=e.length;R<T;R++){var h=t.cartesianToCartographic(e[R]);i=Math.min(i,h.longitude),E=Math.max(E,h.longitude),f=Math.min(f,h.latitude),_=Math.max(_,h.latitude);var A=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;l=Math.min(l,A),c=Math.max(c,A)}return E-i>c-l&&(i=l,E=c,E>u.PI&&(E-=u.TWO_PI),i>u.PI&&(i-=u.TWO_PI)),n(a)?(a.west=i,a.south=f,a.east=E,a.north=_,a):new s(i,f,E,_)},s.clone=function(e,t){if(n(e))return n(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||n(e)&&n(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return n(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.south,r.height=0,r):new e(t.west,t.south)},s.northwest=function(t,r){return n(r)?(r.longitude=t.west,r.latitude=t.north,r.height=0,r):new e(t.west,t.north)},s.northeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.north,r.height=0,r):new e(t.east,t.north)},s.southeast=function(t,r){return n(r)?(r.longitude=t.east,r.latitude=t.south,r.height=0,r):new e(t.east,t.south)},s.center=function(t,r){var a=t.east,o=t.west;a<o&&(a+=u.TWO_PI);var i=u.negativePiToPi(.5*(o+a)),s=.5*(t.south+t.north);return n(r)?(r.longitude=i,r.latitude=s,r.height=0,r):new e(i,s)},s.intersection=function(e,t,r){var a=e.east,o=e.west,i=t.east,E=t.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var l=u.negativePiToPi(Math.max(o,E)),c=u.negativePiToPi(Math.min(a,i));if(!((e.west<e.east||t.west<t.east)&&c<=l)){var f=Math.max(e.south,t.south),_=Math.min(e.north,t.north);if(!(f>=_))return n(r)?(r.west=l,r.south=f,r.east=c,r.north=_,r):new s(l,f,c,_)}},s.simpleIntersection=function(e,t,r){var a=Math.max(e.west,t.west),o=Math.max(e.south,t.south),i=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(o>=u||a>=i))return n(r)?(r.west=a,r.south=o,r.east=i,r.north=u,r):new s(a,o,i,u)},s.union=function(e,t,r){n(r)||(r=new s);var a=e.east,o=e.west,i=t.east,E=t.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(o,E)),c=u.convertLongitudeRange(Math.max(a,i));return r.west=l,r.south=Math.min(e.south,t.south),r.east=c,r.north=Math.max(e.north,t.north),r},s.expand=function(e,t,r){return n(r)||(r=new s),r.west=Math.min(e.west,t.longitude),r.south=Math.min(e.south,t.latitude),r.east=Math.max(e.east,t.longitude),r.north=Math.max(e.north,t.latitude),r},s.contains=function(e,t){var r=t.longitude,n=t.latitude,a=e.west,o=e.east;return o<a&&(o+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<o||u.equalsEpsilon(r,o,u.EPSILON14))&&n>=e.south&&n<=e.north};var E=new e;return s.subsample=function(e,t,a,i){t=r(t,o.WGS84),a=r(a,0),n(i)||(i=[]);var l=0,c=e.north,f=e.south,_=e.east,R=e.west,T=E;T.height=a,T.longitude=R,T.latitude=c,i[l]=t.cartographicToCartesian(T,i[l]),l++,T.longitude=_,i[l]=t.cartographicToCartesian(T,i[l]),l++,T.latitude=f,i[l]=t.cartographicToCartesian(T,i[l]),l++,T.longitude=R,i[l]=t.cartographicToCartesian(T,i[l]),l++,T.latitude=c<0?c:f>0?f:0;for(var h=1;h<8;++h)T.longitude=-Math.PI+h*u.PI_OVER_TWO,s.contains(e,T)&&(i[l]=t.cartographicToCartesian(T,i[l]),l++);return 0===T.latitude&&(T.longitude=R,i[l]=t.cartographicToCartesian(T,i[l]),l++,T.longitude=_,i[l]=t.cartographicToCartesian(T,i[l]),l++),i.length=l,i},s.MAX_VALUE=i(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,r,n,a,o,i,u,s,E,l,c){"use strict";function f(t,r){this.center=e.clone(n(t,e.ZERO)),this.radius=n(r,0)}var _=new e,R=new e,T=new e,h=new e,A=new e,d=new e,S=new e,m=new e,C=new e,N=new e,I=new e,M=new e;f.fromPoints=function(t,r){if(a(r)||(r=new f),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n,o=e.clone(t[0],S),i=e.clone(o,_),u=e.clone(o,R),s=e.clone(o,T),E=e.clone(o,h),l=e.clone(o,A),c=e.clone(o,d),p=t.length;for(n=1;n<p;n++){e.clone(t[n],o);var O=o.x,g=o.y,y=o.z;O<i.x&&e.clone(o,i),O>E.x&&e.clone(o,E),g<u.y&&e.clone(o,u),g>l.y&&e.clone(o,l),y<s.z&&e.clone(o,s),y>c.z&&e.clone(o,c)}var F=e.magnitudeSquared(e.subtract(E,i,m)),L=e.magnitudeSquared(e.subtract(l,u,m)),U=e.magnitudeSquared(e.subtract(c,s,m)),v=i,D=E,P=F;L>P&&(P=L,v=u,D=l),U>P&&(P=U,v=s,D=c);var B=C;B.x=.5*(v.x+D.x),B.y=.5*(v.y+D.y),B.z=.5*(v.z+D.z);var w=e.magnitudeSquared(e.subtract(D,B,m)),x=Math.sqrt(w),G=N;G.x=i.x,G.y=u.y,G.z=s.z;var b=I;b.x=E.x,b.y=l.y,b.z=c.z;var z=e.multiplyByScalar(e.add(G,b,m),.5,M),H=0;for(n=0;n<p;n++){e.clone(t[n],o);var V=e.magnitude(e.subtract(o,z,m));V>H&&(H=V);var X=e.magnitudeSquared(e.subtract(o,B,m));if(X>w){var q=Math.sqrt(X);x=.5*(x+q),w=x*x;var W=q-x;B.x=(x*B.x+W*o.x)/q,B.y=(x*B.y+W*o.y)/q,B.z=(x*B.z+W*o.z)/q}}return x<H?(e.clone(B,r.center),r.radius=x):(e.clone(z,r.center),r.radius=H),r};var p=new i,O=new e,g=new e,y=new t,F=new t;f.fromRectangle2D=function(e,t,r){return f.fromRectangleWithHeights2D(e,t,0,0,r)},f.fromRectangleWithHeights2D=function(t,r,o,i,u){if(a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;r=n(r,p),c.southwest(t,y),y.height=o,c.northeast(t,F),F.height=i;var s=r.project(y,O),E=r.project(F,g),l=E.x-s.x,_=E.y-s.y,R=E.z-s.z;u.radius=.5*Math.sqrt(l*l+_*_+R*R);var T=u.center;return T.x=s.x+.5*l,T.y=s.y+.5*_,T.z=s.z+.5*R,u};var L=[];f.fromRectangle3D=function(t,r,i,u){if(r=n(r,o.WGS84),i=n(i,0),a(u)||(u=new f),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=c.subsample(t,r,i,L);return f.fromPoints(s,u)},f.fromVertices=function(t,r,o,i){if(a(i)||(i=new f),!a(t)||0===t.length)return i.center=e.clone(e.ZERO,i.center),i.radius=0,i;r=n(r,e.ZERO),o=n(o,3);var u=S;u.x=t[0]+r.x,u.y=t[1]+r.y,u.z=t[2]+r.z;var s,E=e.clone(u,_),l=e.clone(u,R),c=e.clone(u,T),p=e.clone(u,h),O=e.clone(u,A),g=e.clone(u,d),y=t.length;for(s=0;s<y;s+=o){var F=t[s]+r.x,L=t[s+1]+r.y,U=t[s+2]+r.z;u.x=F,u.y=L,u.z=U,F<E.x&&e.clone(u,E),F>p.x&&e.clone(u,p),L<l.y&&e.clone(u,l),L>O.y&&e.clone(u,O),U<c.z&&e.clone(u,c),U>g.z&&e.clone(u,g)}var v=e.magnitudeSquared(e.subtract(p,E,m)),D=e.magnitudeSquared(e.subtract(O,l,m)),P=e.magnitudeSquared(e.subtract(g,c,m)),B=E,w=p,x=v;D>x&&(x=D,B=l,w=O),P>x&&(x=P,B=c,w=g);var G=C;G.x=.5*(B.x+w.x),G.y=.5*(B.y+w.y),G.z=.5*(B.z+w.z);var b=e.magnitudeSquared(e.subtract(w,G,m)),z=Math.sqrt(b),H=N;H.x=E.x,H.y=l.y,H.z=c.z;var V=I;V.x=p.x,V.y=O.y,V.z=g.z;var X=e.multiplyByScalar(e.add(H,V,m),.5,M),q=0;for(s=0;s<y;s+=o){u.x=t[s]+r.x,u.y=t[s+1]+r.y,u.z=t[s+2]+r.z;var W=e.magnitude(e.subtract(u,X,m));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,G,m));if(Y>b){var K=Math.sqrt(Y);z=.5*(z+K),b=z*z;var k=K-z;G.x=(z*G.x+k*u.x)/K,G.y=(z*G.y+k*u.y)/K,G.z=(z*G.z+k*u.z)/K}}return z<q?(e.clone(G,i.center),i.radius=z):(e.clone(X,i.center),i.radius=q),i},f.fromEncodedCartesianVertices=function(t,r,n){if(a(n)||(n=new f),!a(t)||!a(r)||t.length!==r.length||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var o=S;o.x=t[0]+r[0],o.y=t[1]+r[1],o.z=t[2]+r[2];var i,u=e.clone(o,_),s=e.clone(o,R),E=e.clone(o,T),l=e.clone(o,h),c=e.clone(o,A),p=e.clone(o,d),O=t.length;for(i=0;i<O;i+=3){var g=t[i]+r[i],y=t[i+1]+r[i+1],F=t[i+2]+r[i+2];o.x=g,o.y=y,o.z=F,g<u.x&&e.clone(o,u),g>l.x&&e.clone(o,l),y<s.y&&e.clone(o,s),y>c.y&&e.clone(o,c),F<E.z&&e.clone(o,E),F>p.z&&e.clone(o,p)}var L=e.magnitudeSquared(e.subtract(l,u,m)),U=e.magnitudeSquared(e.subtract(c,s,m)),v=e.magnitudeSquared(e.subtract(p,E,m)),D=u,P=l,B=L;U>B&&(B=U,D=s,P=c),v>B&&(B=v,D=E,P=p);var w=C;w.x=.5*(D.x+P.x),w.y=.5*(D.y+P.y),w.z=.5*(D.z+P.z);var x=e.magnitudeSquared(e.subtract(P,w,m)),G=Math.sqrt(x),b=N;b.x=u.x,b.y=s.y,b.z=E.z;var z=I;z.x=l.x,z.y=c.y,z.z=p.z;var H=e.multiplyByScalar(e.add(b,z,m),.5,M),V=0;for(i=0;i<O;i+=3){o.x=t[i]+r[i],o.y=t[i+1]+r[i+1],o.z=t[i+2]+r[i+2];var X=e.magnitude(e.subtract(o,H,m));X>V&&(V=X);var q=e.magnitudeSquared(e.subtract(o,w,m));if(q>x){var W=Math.sqrt(q);G=.5*(G+W),x=G*G;var Y=W-G;w.x=(G*w.x+Y*o.x)/W,w.y=(G*w.y+Y*o.y)/W,w.z=(G*w.z+Y*o.z)/W}}return G<V?(e.clone(w,n.center),n.radius=G):(e.clone(H,n.center),n.radius=V),n},f.fromCornerPoints=function(t,r,n){a(n)||(n=new f);var o=n.center;return e.add(t,r,o),e.multiplyByScalar(o,.5,o),n.radius=e.distance(o,r),n},f.fromEllipsoid=function(t,r){return a(r)||(r=new f),e.clone(e.ZERO,r.center),r.radius=t.maximumRadius,r};var U=new e;f.fromBoundingSpheres=function(t,r){if(a(r)||(r=new f),!a(t)||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var n=t.length;if(1===n)return f.clone(t[0],r);if(2===n)return f.union(t[0],t[1],r);var o,i=[];for(o=0;o<n;o++)i.push(t[o].center);r=f.fromPoints(i,r);var u=r.center,s=r.radius;for(o=0;o<n;o++){var E=t[o];s=Math.max(s,e.distance(u,E.center,U)+E.radius)}return r.radius=s,r};var v=new e,D=new e,P=new e;f.fromOrientedBoundingBox=function(t,r){a(r)||(r=new f);var n=t.halfAxes,o=E.getColumn(n,0,v),i=E.getColumn(n,1,D),u=E.getColumn(n,2,P);return e.add(o,i,o),e.add(o,u,o),r.center=e.clone(t.center,r.center),r.radius=e.magnitude(o),r},f.clone=function(t,r){if(a(t))return a(r)?(r.center=e.clone(t.center,r.center),r.radius=t.radius,r):new f(t.center,t.radius)},f.packedLength=4,f.pack=function(e,t,r){r=n(r,0);var a=e.center;return t[r++]=a.x,t[r++]=a.y,t[r++]=a.z,t[r]=e.radius,t},f.unpack=function(e,t,r){t=n(t,0),a(r)||(r=new f);var o=r.center;return o.x=e[t++],o.y=e[t++],o.z=e[t++],r.radius=e[t],r};var B=new e,w=new e;f.union=function(t,r,n){a(n)||(n=new f);var o=t.center,i=t.radius,u=r.center,s=r.radius,E=e.subtract(u,o,B),l=e.magnitude(E);if(i>=l+s)return t.clone(n),n;if(s>=l+i)return r.clone(n),n;var c=.5*(i+l+s),_=e.multiplyByScalar(E,(-i+c)/l,w);return e.add(_,o,_),e.clone(_,n.center),n.radius=c,n};var x=new e;f.expand=function(t,r,n){n=f.clone(t,n);var a=e.magnitude(e.subtract(r,n.center,x));return a>n.radius&&(n.radius=a),n},f.intersectPlane=function(t,r){var n=t.center,a=t.radius,o=r.normal,i=e.dot(o,n)+r.distance;return i<-a?u.OUTSIDE:i<a?u.INTERSECTING:u.INSIDE},f.transform=function(e,t,r){return a(r)||(r=new f),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=l.getMaximumScale(t)*e.radius,r};var G=new e;f.distanceSquaredTo=function(t,r){var n=e.subtract(t.center,r,G);return e.magnitudeSquared(n)-t.radius*t.radius},f.transformWithoutScale=function(e,t,r){return a(r)||(r=new f),r.center=l.multiplyByPoint(t,e.center,r.center),r.radius=e.radius,r};var b=new e;f.computePlaneDistances=function(t,r,n,o){a(o)||(o=new s);var i=e.subtract(t.center,r,b),u=e.dot(n,i);return o.start=u-t.radius,o.stop=u+t.radius,o};for(var z=new e,H=new e,V=new e,X=new e,q=new e,W=new t,Y=new Array(8),K=0;K<8;++K)Y[K]=new e;var k=new i;return f.projectTo2D=function(t,r,a){r=n(r,k);var o=r.ellipsoid,i=t.center,u=t.radius,s=o.geodeticSurfaceNormal(i,z),E=e.cross(e.UNIT_Z,s,H);e.normalize(E,E);var l=e.cross(s,E,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(E,u,E);var c=e.negate(l,q),_=e.negate(E,X),R=Y,T=R[0];e.add(s,l,T),e.add(T,E,T),T=R[1],e.add(s,l,T),e.add(T,_,T),T=R[2],e.add(s,c,T),e.add(T,_,T),T=R[3],e.add(s,c,T),e.add(T,E,T),e.negate(s,s),T=R[4],e.add(s,l,T),e.add(T,E,T),T=R[5],e.add(s,l,T),e.add(T,_,T),T=R[6],e.add(s,c,T),e.add(T,_,T),T=R[7],e.add(s,c,T),e.add(T,E,T);for(var h=R.length,A=0;A<h;++A){var d=R[A];e.add(i,d,d);var S=o.cartesianToCartographic(d,W);r.project(S,d)}a=f.fromPoints(R,a),i=a.center;var m=i.x,C=i.y,N=i.z;return i.x=N,i.y=m,i.z=C,a},f.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},f.equals=function(t,r){return t===r||a(t)&&a(r)&&e.equals(t.center,r.center)&&t.radius===r.radius},f.prototype.intersectPlane=function(e){return f.intersectPlane(this,e)},f.prototype.distanceSquaredTo=function(e){return f.distanceSquaredTo(this,e)},f.prototype.computePlaneDistances=function(e,t,r){return f.computePlaneDistances(this,e,t,r)},f.prototype.isOccluded=function(e){return f.isOccluded(this,e)},f.prototype.equals=function(e){return f.equals(this,e)},f.prototype.clone=function(e){return f.clone(this,e)},f}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(r))return r;r=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,o=["webkit","moz","o","ms","khtml"],i=0,u=o.length;i<u;++i){var s=o[i];a=s+"RequestFullscreen","function"==typeof t[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[n.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,r){"use strict";function n(e){for(var t=e.split("."),r=0,n=t.length;r<n;++r)t[r]=parseInt(t[r],10);return t}function a(){if(!t(C)&&(C=!1,!f())){var e=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==e&&(C=!0,N=n(e[1]))}return C}function o(){return a()&&N}function i(){if(!t(I)&&(I=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==e&&(I=!0,M=n(e[1]))}return I}function u(){return i()&&M}function s(){if(!t(p)){p=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==e&&(p=!0,O=n(e[1]),O.isNightly=!!e[2])}return p}function E(){return s()&&O}function l(){if(!t(g)){g=!1;var e;"Microsoft Internet Explorer"===m.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0, -y=n(e[1])):"Netscape"===m.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(e[1]))}return g}function c(){return l()&&y}function f(){if(!t(F)){F=!1;var e=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==e&&(F=!0,L=n(e[1]))}return F}function _(){return f()&&L}function R(){if(!t(U)){U=!1;var e=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==e&&(U=!0,v=n(e[1]))}return U}function T(){return t(D)||(D=/Windows/i.test(m.appVersion)),D}function h(){return R()&&v}function A(){return t(P)||(P="undefined"!=typeof PointerEvent&&(!t(m.pointerEnabled)||m.pointerEnabled)),P}function d(){if(!t(w)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=e.style.imageRendering;w=t(r)&&""!==r,w&&(B=r)}return w}function S(){return d()?B:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var C,N,I,M,p,O,g,y,F,L,U,v,D,P,B,w,x={isChrome:a,chromeVersion:o,isSafari:i,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:l,internetExplorerVersion:c,isEdge:f,edgeVersion:_,isFirefox:R,firefoxVersion:h,isWindows:T,hardwareConcurrency:e(m.hardwareConcurrency,3),supportsPointerEvents:A,supportsImageRenderingPixelated:d,imageRenderingValue:S};return x.supportsFullscreen=function(){return r.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/Color",["./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math"],function(e,t,r,n,a,o){"use strict";function i(e,t,r){return r<0&&(r+=1),r>1&&(r-=1),6*r<1?e+6*(t-e)*r:2*r<1?t:3*r<2?e+(t-e)*(2/3-r)*6:e}function u(e,r,n,a){this.red=t(e,1),this.green=t(r,1),this.blue=t(n,1),this.alpha=t(a,1)}u.fromCartesian4=function(e,t){return r(t)?(t.red=e.x,t.green=e.y,t.blue=e.z,t.alpha=e.w,t):new u(e.x,e.y,e.z,e.w)},u.fromBytes=function(e,n,a,o,i){return e=u.byteToFloat(t(e,255)),n=u.byteToFloat(t(n,255)),a=u.byteToFloat(t(a,255)),o=u.byteToFloat(t(o,255)),r(i)?(i.red=e,i.green=n,i.blue=a,i.alpha=o,i):new u(e,n,a,o)},u.fromAlpha=function(e,t,n){return r(n)?(n.red=e.red,n.green=e.green,n.blue=e.blue,n.alpha=t,n):new u(e.red,e.green,e.blue,t)};var s,E,l;n.supportsTypedArrays()&&(s=new ArrayBuffer(4),E=new Uint32Array(s),l=new Uint8Array(s)),u.fromRgba=function(e,t){return E[0]=e,u.fromBytes(l[0],l[1],l[2],l[3],t)},u.fromHsl=function(e,n,a,o,s){e=t(e,0)%1,n=t(n,0),a=t(a,0),o=t(o,1);var E=a,l=a,c=a;if(0!==n){var f;f=a<.5?a*(1+n):a+n-a*n;var _=2*a-f;E=i(_,f,e+1/3),l=i(_,f,e),c=i(_,f,e-1/3)}return r(s)?(s.red=E,s.green=l,s.blue=c,s.alpha=o,s):new u(E,l,c,o)},u.fromRandom=function(e,n){e=t(e,t.EMPTY_OBJECT);var a=e.red;if(!r(a)){var i=t(e.minimumRed,0),s=t(e.maximumRed,1);a=i+o.nextRandomNumber()*(s-i)}var E=e.green;if(!r(E)){var l=t(e.minimumGreen,0),c=t(e.maximumGreen,1);E=l+o.nextRandomNumber()*(c-l)}var f=e.blue;if(!r(f)){var _=t(e.minimumBlue,0),R=t(e.maximumBlue,1);f=_+o.nextRandomNumber()*(R-_)}var T=e.alpha;if(!r(T)){var h=t(e.minimumAlpha,0),A=t(e.maximumAlpha,1);T=h+o.nextRandomNumber()*(A-h)}return r(n)?(n.red=a,n.green=E,n.blue=f,n.alpha=T,n):new u(a,E,f,T)};var c=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,f=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,_=/^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i,R=/^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i;return u.fromCssColorString=function(e,n){r(n)||(n=new u);var a=u[e.toUpperCase()];if(r(a))return u.clone(a,n),n;var o=c.exec(e);return null!==o?(n.red=parseInt(o[1],16)/15,n.green=parseInt(o[2],16)/15,n.blue=parseInt(o[3],16)/15,n.alpha=1,n):null!==(o=f.exec(e))?(n.red=parseInt(o[1],16)/255,n.green=parseInt(o[2],16)/255,n.blue=parseInt(o[3],16)/255,n.alpha=1,n):null!==(o=_.exec(e))?(n.red=parseFloat(o[1])/("%"===o[1].substr(-1)?100:255),n.green=parseFloat(o[2])/("%"===o[2].substr(-1)?100:255),n.blue=parseFloat(o[3])/("%"===o[3].substr(-1)?100:255),n.alpha=parseFloat(t(o[4],"1.0")),n):null!==(o=R.exec(e))?u.fromHsl(parseFloat(o[1])/360,parseFloat(o[2])/100,parseFloat(o[3])/100,parseFloat(t(o[4],"1.0")),n):n=void 0},u.packedLength=4,u.pack=function(e,r,n){return n=t(n,0),r[n++]=e.red,r[n++]=e.green,r[n++]=e.blue,r[n]=e.alpha,r},u.unpack=function(e,n,a){return n=t(n,0),r(a)||(a=new u),a.red=e[n++],a.green=e[n++],a.blue=e[n++],a.alpha=e[n],a},u.byteToFloat=function(e){return e/255},u.floatToByte=function(e){return 1===e?255:256*e|0},u.clone=function(e,t){if(r(e))return r(t)?(t.red=e.red,t.green=e.green,t.blue=e.blue,t.alpha=e.alpha,t):new u(e.red,e.green,e.blue,e.alpha)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.red===t.red&&e.green===t.green&&e.blue===t.blue&&e.alpha===t.alpha},u.equalsArray=function(e,t,r){return e.red===t[r]&&e.green===t[r+1]&&e.blue===t[r+2]&&e.alpha===t[r+3]},u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return this===e||r(e)&&Math.abs(this.red-e.red)<=t&&Math.abs(this.green-e.green)<=t&&Math.abs(this.blue-e.blue)<=t&&Math.abs(this.alpha-e.alpha)<=t},u.prototype.toString=function(){return"("+this.red+", "+this.green+", "+this.blue+", "+this.alpha+")"},u.prototype.toCssColorString=function(){var e=u.floatToByte(this.red),t=u.floatToByte(this.green),r=u.floatToByte(this.blue);return 1===this.alpha?"rgb("+e+","+t+","+r+")":"rgba("+e+","+t+","+r+","+this.alpha+")"},u.prototype.toBytes=function(e){var t=u.floatToByte(this.red),n=u.floatToByte(this.green),a=u.floatToByte(this.blue),o=u.floatToByte(this.alpha);return r(e)?(e[0]=t,e[1]=n,e[2]=a,e[3]=o,e):[t,n,a,o]},u.prototype.toRgba=function(){return l[0]=u.floatToByte(this.red),l[1]=u.floatToByte(this.green),l[2]=u.floatToByte(this.blue),l[3]=u.floatToByte(this.alpha),E[0]},u.prototype.brighten=function(e,t){return e=1-e,t.red=1-(1-this.red)*e,t.green=1-(1-this.green)*e,t.blue=1-(1-this.blue)*e,t.alpha=this.alpha,t},u.prototype.darken=function(e,t){return e=1-e,t.red=this.red*e,t.green=this.green*e,t.blue=this.blue*e,t.alpha=this.alpha,t},u.prototype.withAlpha=function(e,t){return u.fromAlpha(this,e,t)},u.add=function(e,t,r){return r.red=e.red+t.red,r.green=e.green+t.green,r.blue=e.blue+t.blue,r.alpha=e.alpha+t.alpha,r},u.subtract=function(e,t,r){return r.red=e.red-t.red,r.green=e.green-t.green,r.blue=e.blue-t.blue,r.alpha=e.alpha-t.alpha,r},u.multiply=function(e,t,r){return r.red=e.red*t.red,r.green=e.green*t.green,r.blue=e.blue*t.blue,r.alpha=e.alpha*t.alpha,r},u.divide=function(e,t,r){return r.red=e.red/t.red,r.green=e.green/t.green,r.blue=e.blue/t.blue,r.alpha=e.alpha/t.alpha,r},u.mod=function(e,t,r){return r.red=e.red%t.red,r.green=e.green%t.green,r.blue=e.blue%t.blue,r.alpha=e.alpha%t.alpha,r},u.multiplyByScalar=function(e,t,r){return r.red=e.red*t,r.green=e.green*t,r.blue=e.blue*t,r.alpha=e.alpha*t,r},u.divideByScalar=function(e,t,r){return r.red=e.red/t,r.green=e.green/t,r.blue=e.blue/t,r.alpha=e.alpha/t,r},u.ALICEBLUE=a(u.fromCssColorString("#F0F8FF")),u.ANTIQUEWHITE=a(u.fromCssColorString("#FAEBD7")),u.AQUA=a(u.fromCssColorString("#00FFFF")),u.AQUAMARINE=a(u.fromCssColorString("#7FFFD4")),u.AZURE=a(u.fromCssColorString("#F0FFFF")),u.BEIGE=a(u.fromCssColorString("#F5F5DC")),u.BISQUE=a(u.fromCssColorString("#FFE4C4")),u.BLACK=a(u.fromCssColorString("#000000")),u.BLANCHEDALMOND=a(u.fromCssColorString("#FFEBCD")),u.BLUE=a(u.fromCssColorString("#0000FF")),u.BLUEVIOLET=a(u.fromCssColorString("#8A2BE2")),u.BROWN=a(u.fromCssColorString("#A52A2A")),u.BURLYWOOD=a(u.fromCssColorString("#DEB887")),u.CADETBLUE=a(u.fromCssColorString("#5F9EA0")),u.CHARTREUSE=a(u.fromCssColorString("#7FFF00")),u.CHOCOLATE=a(u.fromCssColorString("#D2691E")),u.CORAL=a(u.fromCssColorString("#FF7F50")),u.CORNFLOWERBLUE=a(u.fromCssColorString("#6495ED")),u.CORNSILK=a(u.fromCssColorString("#FFF8DC")),u.CRIMSON=a(u.fromCssColorString("#DC143C")),u.CYAN=a(u.fromCssColorString("#00FFFF")),u.DARKBLUE=a(u.fromCssColorString("#00008B")),u.DARKCYAN=a(u.fromCssColorString("#008B8B")),u.DARKGOLDENROD=a(u.fromCssColorString("#B8860B")),u.DARKGRAY=a(u.fromCssColorString("#A9A9A9")),u.DARKGREEN=a(u.fromCssColorString("#006400")),u.DARKGREY=u.DARKGRAY,u.DARKKHAKI=a(u.fromCssColorString("#BDB76B")),u.DARKMAGENTA=a(u.fromCssColorString("#8B008B")),u.DARKOLIVEGREEN=a(u.fromCssColorString("#556B2F")),u.DARKORANGE=a(u.fromCssColorString("#FF8C00")),u.DARKORCHID=a(u.fromCssColorString("#9932CC")),u.DARKRED=a(u.fromCssColorString("#8B0000")),u.DARKSALMON=a(u.fromCssColorString("#E9967A")),u.DARKSEAGREEN=a(u.fromCssColorString("#8FBC8F")),u.DARKSLATEBLUE=a(u.fromCssColorString("#483D8B")),u.DARKSLATEGRAY=a(u.fromCssColorString("#2F4F4F")),u.DARKSLATEGREY=u.DARKSLATEGRAY,u.DARKTURQUOISE=a(u.fromCssColorString("#00CED1")),u.DARKVIOLET=a(u.fromCssColorString("#9400D3")),u.DEEPPINK=a(u.fromCssColorString("#FF1493")),u.DEEPSKYBLUE=a(u.fromCssColorString("#00BFFF")),u.DIMGRAY=a(u.fromCssColorString("#696969")),u.DIMGREY=u.DIMGRAY,u.DODGERBLUE=a(u.fromCssColorString("#1E90FF")),u.FIREBRICK=a(u.fromCssColorString("#B22222")),u.FLORALWHITE=a(u.fromCssColorString("#FFFAF0")),u.FORESTGREEN=a(u.fromCssColorString("#228B22")),u.FUCHSIA=a(u.fromCssColorString("#FF00FF")),u.GAINSBORO=a(u.fromCssColorString("#DCDCDC")),u.GHOSTWHITE=a(u.fromCssColorString("#F8F8FF")),u.GOLD=a(u.fromCssColorString("#FFD700")),u.GOLDENROD=a(u.fromCssColorString("#DAA520")),u.GRAY=a(u.fromCssColorString("#808080")),u.GREEN=a(u.fromCssColorString("#008000")),u.GREENYELLOW=a(u.fromCssColorString("#ADFF2F")),u.GREY=u.GRAY,u.HONEYDEW=a(u.fromCssColorString("#F0FFF0")),u.HOTPINK=a(u.fromCssColorString("#FF69B4")),u.INDIANRED=a(u.fromCssColorString("#CD5C5C")),u.INDIGO=a(u.fromCssColorString("#4B0082")),u.IVORY=a(u.fromCssColorString("#FFFFF0")),u.KHAKI=a(u.fromCssColorString("#F0E68C")),u.LAVENDER=a(u.fromCssColorString("#E6E6FA")),u.LAVENDAR_BLUSH=a(u.fromCssColorString("#FFF0F5")),u.LAWNGREEN=a(u.fromCssColorString("#7CFC00")),u.LEMONCHIFFON=a(u.fromCssColorString("#FFFACD")),u.LIGHTBLUE=a(u.fromCssColorString("#ADD8E6")),u.LIGHTCORAL=a(u.fromCssColorString("#F08080")),u.LIGHTCYAN=a(u.fromCssColorString("#E0FFFF")),u.LIGHTGOLDENRODYELLOW=a(u.fromCssColorString("#FAFAD2")),u.LIGHTGRAY=a(u.fromCssColorString("#D3D3D3")),u.LIGHTGREEN=a(u.fromCssColorString("#90EE90")),u.LIGHTGREY=u.LIGHTGRAY,u.LIGHTPINK=a(u.fromCssColorString("#FFB6C1")),u.LIGHTSEAGREEN=a(u.fromCssColorString("#20B2AA")),u.LIGHTSKYBLUE=a(u.fromCssColorString("#87CEFA")),u.LIGHTSLATEGRAY=a(u.fromCssColorString("#778899")),u.LIGHTSLATEGREY=u.LIGHTSLATEGRAY,u.LIGHTSTEELBLUE=a(u.fromCssColorString("#B0C4DE")),u.LIGHTYELLOW=a(u.fromCssColorString("#FFFFE0")),u.LIME=a(u.fromCssColorString("#00FF00")),u.LIMEGREEN=a(u.fromCssColorString("#32CD32")),u.LINEN=a(u.fromCssColorString("#FAF0E6")),u.MAGENTA=a(u.fromCssColorString("#FF00FF")),u.MAROON=a(u.fromCssColorString("#800000")),u.MEDIUMAQUAMARINE=a(u.fromCssColorString("#66CDAA")),u.MEDIUMBLUE=a(u.fromCssColorString("#0000CD")),u.MEDIUMORCHID=a(u.fromCssColorString("#BA55D3")),u.MEDIUMPURPLE=a(u.fromCssColorString("#9370DB")),u.MEDIUMSEAGREEN=a(u.fromCssColorString("#3CB371")),u.MEDIUMSLATEBLUE=a(u.fromCssColorString("#7B68EE")),u.MEDIUMSPRINGGREEN=a(u.fromCssColorString("#00FA9A")),u.MEDIUMTURQUOISE=a(u.fromCssColorString("#48D1CC")),u.MEDIUMVIOLETRED=a(u.fromCssColorString("#C71585")),u.MIDNIGHTBLUE=a(u.fromCssColorString("#191970")),u.MINTCREAM=a(u.fromCssColorString("#F5FFFA")),u.MISTYROSE=a(u.fromCssColorString("#FFE4E1")),u.MOCCASIN=a(u.fromCssColorString("#FFE4B5")),u.NAVAJOWHITE=a(u.fromCssColorString("#FFDEAD")),u.NAVY=a(u.fromCssColorString("#000080")),u.OLDLACE=a(u.fromCssColorString("#FDF5E6")),u.OLIVE=a(u.fromCssColorString("#808000")),u.OLIVEDRAB=a(u.fromCssColorString("#6B8E23")),u.ORANGE=a(u.fromCssColorString("#FFA500")),u.ORANGERED=a(u.fromCssColorString("#FF4500")),u.ORCHID=a(u.fromCssColorString("#DA70D6")),u.PALEGOLDENROD=a(u.fromCssColorString("#EEE8AA")),u.PALEGREEN=a(u.fromCssColorString("#98FB98")),u.PALETURQUOISE=a(u.fromCssColorString("#AFEEEE")),u.PALEVIOLETRED=a(u.fromCssColorString("#DB7093")),u.PAPAYAWHIP=a(u.fromCssColorString("#FFEFD5")),u.PEACHPUFF=a(u.fromCssColorString("#FFDAB9")),u.PERU=a(u.fromCssColorString("#CD853F")),u.PINK=a(u.fromCssColorString("#FFC0CB")),u.PLUM=a(u.fromCssColorString("#DDA0DD")),u.POWDERBLUE=a(u.fromCssColorString("#B0E0E6")),u.PURPLE=a(u.fromCssColorString("#800080")),u.RED=a(u.fromCssColorString("#FF0000")),u.ROSYBROWN=a(u.fromCssColorString("#BC8F8F")),u.ROYALBLUE=a(u.fromCssColorString("#4169E1")),u.SADDLEBROWN=a(u.fromCssColorString("#8B4513")),u.SALMON=a(u.fromCssColorString("#FA8072")),u.SANDYBROWN=a(u.fromCssColorString("#F4A460")),u.SEAGREEN=a(u.fromCssColorString("#2E8B57")),u.SEASHELL=a(u.fromCssColorString("#FFF5EE")),u.SIENNA=a(u.fromCssColorString("#A0522D")),u.SILVER=a(u.fromCssColorString("#C0C0C0")),u.SKYBLUE=a(u.fromCssColorString("#87CEEB")),u.SLATEBLUE=a(u.fromCssColorString("#6A5ACD")),u.SLATEGRAY=a(u.fromCssColorString("#708090")),u.SLATEGREY=u.SLATEGRAY,u.SNOW=a(u.fromCssColorString("#FFFAFA")),u.SPRINGGREEN=a(u.fromCssColorString("#00FF7F")),u.STEELBLUE=a(u.fromCssColorString("#4682B4")),u.TAN=a(u.fromCssColorString("#D2B48C")),u.TEAL=a(u.fromCssColorString("#008080")),u.THISTLE=a(u.fromCssColorString("#D8BFD8")),u.TOMATO=a(u.fromCssColorString("#FF6347")),u.TURQUOISE=a(u.fromCssColorString("#40E0D0")),u.VIOLET=a(u.fromCssColorString("#EE82EE")),u.WHEAT=a(u.fromCssColorString("#F5DEB3")),u.WHITE=a(u.fromCssColorString("#FFFFFF")),u.WHITESMOKE=a(u.fromCssColorString("#F5F5F5")),u.YELLOW=a(u.fromCssColorString("#FFFF00")),u.YELLOWGREEN=a(u.fromCssColorString("#9ACD32")),u.TRANSPARENT=a(new u(0,0,0,0)),u}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,r,n,a,o){"use strict";if(!n.supportsTypedArrays())return{};var i={BYTE:o.BYTE,UNSIGNED_BYTE:o.UNSIGNED_BYTE,SHORT:o.SHORT,UNSIGNED_SHORT:o.UNSIGNED_SHORT,INT:o.INT,UNSIGNED_INT:o.UNSIGNED_INT,FLOAT:o.FLOAT,DOUBLE:o.DOUBLE};return i.getSizeInBytes=function(e){switch(e){case i.BYTE:return Int8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.SHORT:return Int16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.INT:return Int32Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case i.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case i.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},i.fromTypedArray=function(e){return e instanceof Int8Array?i.BYTE:e instanceof Uint8Array?i.UNSIGNED_BYTE:e instanceof Int16Array?i.SHORT:e instanceof Uint16Array?i.UNSIGNED_SHORT:e instanceof Int32Array?i.INT:e instanceof Uint32Array?i.UNSIGNED_INT:e instanceof Float32Array?i.FLOAT:e instanceof Float64Array?i.DOUBLE:void 0},i.validate=function(e){return t(e)&&(e===i.BYTE||e===i.UNSIGNED_BYTE||e===i.SHORT||e===i.UNSIGNED_SHORT||e===i.INT||e===i.UNSIGNED_INT||e===i.FLOAT||e===i.DOUBLE)},i.createTypedArray=function(e,t){switch(e){case i.BYTE:return new Int8Array(t);case i.UNSIGNED_BYTE:return new Uint8Array(t);case i.SHORT:return new Int16Array(t);case i.UNSIGNED_SHORT:return new Uint16Array(t);case i.INT:return new Int32Array(t);case i.UNSIGNED_INT:return new Uint32Array(t);case i.FLOAT:return new Float32Array(t);case i.DOUBLE:return new Float64Array(t)}},i.createArrayBufferView=function(t,r,n,a){switch(n=e(n,0),a=e(a,(r.byteLength-n)/i.getSizeInBytes(t)),t){case i.BYTE:return new Int8Array(r,n,a);case i.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case i.SHORT:return new Int16Array(r,n,a);case i.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case i.INT:return new Int32Array(r,n,a);case i.UNSIGNED_INT:return new Uint32Array(r,n,a);case i.FLOAT:return new Float32Array(r,n,a);case i.DOUBLE:return new Float64Array(r,n,a)}},i.fromName=function(e){switch(e){case"BYTE":return i.BYTE;case"UNSIGNED_BYTE":return i.UNSIGNED_BYTE;case"SHORT":return i.SHORT;case"UNSIGNED_SHORT":return i.UNSIGNED_SHORT;case"INT":return i.INT;case"UNSIGNED_INT":return i.UNSIGNED_INT;case"FLOAT":return i.FLOAT;case"DOUBLE":return i.DOUBLE}},a(i)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var r={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===r.POINTS||e===r.LINES||e===r.LINE_LOOP||e===r.LINE_STRIP||e===r.TRIANGLES||e===r.TRIANGLE_STRIP||e===r.TRIANGLE_FAN}};return e(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,r,n,a,o){"use strict";function i(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,o.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return i.computeNumberOfVertices=function(e){var t=-1;for(var n in e.attributes)if(e.attributes.hasOwnProperty(n)&&r(e.attributes[n])&&r(e.attributes[n].values)){var a=e.attributes[n],o=a.values.length/a.componentsPerAttribute;t=o}return t},i}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,r){"use strict";function n(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,r,n,a){"use strict";var o={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return o.getSizeInBytes=function(e){switch(e){case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},o.validate=function(t){return e(t)&&(t===o.UNSIGNED_BYTE||t===o.UNSIGNED_SHORT||t===o.UNSIGNED_INT)},o.createTypedArray=function(e,t){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)}, -o.createTypedArrayFromArrayBuffer=function(e,t,r,a){return e>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,r,a):new Uint16Array(t,r,a)},r(o)}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,r,n,a,o,i,u){"use strict";function s(e){var t=e._uSquared,r=e._ellipsoid.maximumRadius,n=e._ellipsoid.minimumRadius,a=(r-n)/r,o=Math.cos(e._startHeading),i=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),E=s*u,l=Math.atan2(u,o),c=s*i,f=c*c,_=1-f,R=Math.sqrt(_),T=t/4,h=T*T,A=h*T,d=h*h,S=1+T-3*h/4+5*A/4-175*d/64,m=1-T+15*h/8-35*A/8,C=1-3*T+35*h/4,N=1-5*T,I=S*l-m*Math.sin(2*l)*T/2-C*Math.sin(4*l)*h/16-N*Math.sin(6*l)*A/48-5*Math.sin(8*l)*d/512,M=e._constants;M.a=r,M.b=n,M.f=a,M.cosineHeading=o,M.sineHeading=i,M.tanU=u,M.cosineU=s,M.sineU=E,M.sigma=l,M.sineAlpha=c,M.sineSquaredAlpha=f,M.cosineSquaredAlpha=_,M.cosineAlpha=R,M.u2Over4=T,M.u4Over16=h,M.u6Over64=A,M.u8Over256=d,M.a0=S,M.a1=m,M.a2=C,M.a3=N,M.distanceRatio=I}function E(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,r,n,a,o,i){var u=E(e,r);return(1-u)*e*t*(n+u*a*(i+u*o*(2*i*i-1)))}function c(e,t,r,n,a,o,i){var s,E,c,f,_,R=(t-r)/t,T=o-n,h=Math.atan((1-R)*Math.tan(a)),A=Math.atan((1-R)*Math.tan(i)),d=Math.cos(h),S=Math.sin(h),m=Math.cos(A),C=Math.sin(A),N=d*m,I=d*C,M=S*C,p=S*m,O=T,g=u.TWO_PI,y=Math.cos(O),F=Math.sin(O);do{y=Math.cos(O),F=Math.sin(O);var L=I-p*y;c=Math.sqrt(m*m*F*F+L*L),E=M+N*y,s=Math.atan2(c,E);var U;0===c?(U=0,f=1):(U=N*F/c,f=1-U*U),g=O,_=E-2*M/f,isNaN(_)&&(_=0),O=T+l(R,U,f,s,c,E,_)}while(Math.abs(O-g)>u.EPSILON12);var v=f*(t*t-r*r)/(r*r),D=1+v*(4096+v*(v*(320-175*v)-768))/16384,P=v*(256+v*(v*(74-47*v)-128))/1024,B=_*_,w=P*c*(_+P*(E*(2*B-1)-P*_*(4*c*c-3)*(4*B-3)/6)/4),x=r*D*(s-w),G=Math.atan2(m*F,I-p*y),b=Math.atan2(d*F,I*y-p);e._distance=x,e._startHeading=G,e._endHeading=b,e._uSquared=v}function f(r,n,a,o){e.normalize(o.cartographicToCartesian(n,T),R),e.normalize(o.cartographicToCartesian(a,T),T);c(r,o.maximumRadius,o.minimumRadius,n.longitude,n.latitude,a.longitude,a.latitude),r._start=t.clone(n,r._start),r._end=t.clone(a,r._end),r._start.height=0,r._end.height=0,s(r)}function _(e,r,o){var u=n(o,i.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(r)&&f(this,e,r,u)}var R=new e,T=new e;return o(_.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),_.prototype.setEndPoints=function(e,t){f(this,e,t,this._ellipsoid)},_.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},_.prototype.interpolateUsingSurfaceDistance=function(e,r){var n=this._constants,o=n.distanceRatio+e/n.b,i=Math.cos(2*o),u=Math.cos(4*o),s=Math.cos(6*o),E=Math.sin(2*o),c=Math.sin(4*o),f=Math.sin(6*o),_=Math.sin(8*o),R=o*o,T=o*R,h=n.u8Over256,A=n.u2Over4,d=n.u6Over64,S=n.u4Over16,m=2*T*h*i/3+o*(1-A+7*S/4-15*d/4+579*h/64-(S-15*d/4+187*h/16)*i-(5*d/4-115*h/16)*u-29*h*s/16)+(A/2-S+71*d/32-85*h/16)*E+(5*S/16-5*d/4+383*h/96)*c-R*((d-11*h/2)*E+5*h*c/2)+(29*d/96-29*h/16)*f+539*h*_/1536,C=Math.asin(Math.sin(m)*n.cosineAlpha),N=Math.atan(n.a/n.b*Math.tan(C));m-=n.sigma;var I=Math.cos(2*n.sigma+m),M=Math.sin(m),p=Math.cos(m),O=n.cosineU*p,g=n.sineU*M,y=Math.atan2(M*n.sineHeading,O-g*n.cosineHeading),F=y-l(n.f,n.sineAlpha,n.cosineSquaredAlpha,m,M,p,I);return a(r)?(r.longitude=this._start.longitude+F,r.latitude=N,r.height=0,r):new t(this._start.longitude+F,N,0)},_}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function r(e,r,n){var a=e+r;return t.sign(e)!==t.sign(r)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(e,t,r){return t*t-4*e*r},n.computeRealRoots=function(e,n,a){var o;if(0===e)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var i=Math.abs(a),u=Math.abs(e);if(i<u&&i/u<t.EPSILON14)return[0,0];if(i>u&&u/i<t.EPSILON14)return[];if((o=-a/e)<0)return[];var s=Math.sqrt(o);return[-s,s]}if(0===a)return o=-n/e,o<0?[o,0]:[0,o];var E=n*n,l=4*e*a,c=r(E,-l,t.EPSILON14);if(c<0)return[];var f=-.5*r(n,t.sign(n)*Math.sqrt(c),t.EPSILON14);return n>0?[f/e,a/f]:[a/f,f/e]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function r(e,t,r,n){var a,o,i=e,u=t/3,s=r/3,E=n,l=i*s,c=u*E,f=u*u,_=s*s,R=i*s-f,T=i*E-u*s,h=u*E-_,A=4*R*h-T*T;if(A<0){var d,S,m;f*c>=l*_?(d=i,S=R,m=-2*u*R+i*T):(d=E,S=h,m=-E*T+2*s*h);var C=m<0?-1:1,N=-C*Math.abs(d)*Math.sqrt(-A);o=-m+N;var I=o/2,M=I<0?-Math.pow(-I,1/3):Math.pow(I,1/3),p=o===N?-M:-S/M;return a=S<=0?M+p:-m/(M*M+p*p+S),f*c>=l*_?[(a-u)/i]:[-E/(a+s)]}var O=R,g=-2*u*R+i*T,y=h,F=-E*T+2*s*h,L=Math.sqrt(A),U=Math.sqrt(3)/2,v=Math.abs(Math.atan2(i*L,-g)/3);a=2*Math.sqrt(-O);var D=Math.cos(v);o=a*D;var P=a*(-D/2-U*Math.sin(v)),B=o+P>2*u?o-u:P-u,w=i,x=B/w;v=Math.abs(Math.atan2(E*L,-F)/3),a=2*Math.sqrt(-y),D=Math.cos(v),o=a*D,P=a*(-D/2-U*Math.sin(v));var G=-E,b=o+P<2*s?o+s:P+s,z=G/b,H=w*b,V=-B*b-w*G,X=B*G,q=(s*V-u*X)/(-u*V+s*H);return x<=q?x<=z?q<=z?[x,q,z]:[x,z,q]:[z,x,q]:x<=z?[q,x,z]:q<=z?[q,z,x]:[z,q,x]}var n={};return n.computeDiscriminant=function(e,t,r,n){var a=e*e,o=t*t,i=r*r;return 18*e*t*r*n+o*i-27*a*(n*n)-4*(e*i*r+o*t*n)},n.computeRealRoots=function(e,n,a,o){var i,u;if(0===e)return t.computeRealRoots(n,a,o);if(0===n){if(0===a){if(0===o)return[0,0,0];u=-o/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===o?(i=t.computeRealRoots(e,0,a),0===i.Length?[0]:[i[0],0,i[1]]):r(e,0,a,o)}return 0===a?0===o?(u=-n/e,u<0?[u,0,0]:[0,0,u]):r(e,n,0,o):0===o?(i=t.computeRealRoots(e,n,a),0===i.length?[0]:i[1]<=0?[i[0],i[1],0]:i[0]>=0?[0,i[0],i[1]]:[i[0],0,i[1]]):r(e,n,a,o)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,r,n){"use strict";function a(t,a,o,i){var u=t*t,s=a-3*u/8,E=o-a*t/2+u*t/8,l=i-o*t/4+a*u/16-3*u*u/256,c=e.computeRealRoots(1,2*s,s*s-4*l,-E*E);if(c.length>0){var f=-t/4,_=c[c.length-1];if(Math.abs(_)<r.EPSILON14){var R=n.computeRealRoots(1,s,l);if(2===R.length){var T,h=R[0],A=R[1];if(h>=0&&A>=0){var d=Math.sqrt(h),S=Math.sqrt(A);return[f-S,f-d,f+d,f+S]}if(h>=0&&A<0)return T=Math.sqrt(h),[f-T,f+T];if(h<0&&A>=0)return T=Math.sqrt(A),[f-T,f+T]}return[]}if(_>0){var m=Math.sqrt(_),C=(s+_-E/m)/2,N=(s+_+E/m)/2,I=n.computeRealRoots(1,m,C),M=n.computeRealRoots(1,-m,N);return 0!==I.length?(I[0]+=f,I[1]+=f,0!==M.length?(M[0]+=f,M[1]+=f,I[1]<=M[0]?[I[0],I[1],M[0],M[1]]:M[1]<=I[0]?[M[0],M[1],I[0],I[1]]:I[0]>=M[0]&&I[1]<=M[1]?[M[0],I[0],I[1],M[1]]:M[0]>=I[0]&&M[1]<=I[1]?[I[0],M[0],M[1],I[1]]:I[0]>M[0]&&I[0]<M[1]?[M[0],I[0],M[1],I[1]]:[I[0],M[0],I[1],M[1]]):I):0!==M.length?(M[0]+=f,M[1]+=f,M):[]}}return[]}function o(t,a,o,i){var u=o*o,s=a*a,E=t*t,l=-2*a,c=o*t+s-4*i,f=E*i-o*a*t+u,_=e.computeRealRoots(1,l,c,f);if(_.length>0){var R,T,h=_[0],A=a-h,d=A*A,S=t/2,m=A/2,C=d-4*i,N=d+4*Math.abs(i),I=E-4*h,M=E+4*Math.abs(h);if(h<0||C*M<I*N){var p=Math.sqrt(I);R=p/2,T=0===p?0:(t*m-o)/p}else{var O=Math.sqrt(C);R=0===O?0:(t*m-o)/O,T=O/2}var g,y;0===S&&0===R?(g=0,y=0):r.sign(S)===r.sign(R)?(g=S+R,y=h/g):(y=S-R,g=h/y);var F,L;0===m&&0===T?(F=0,L=0):r.sign(m)===r.sign(T)?(F=m+T,L=i/F):(L=m-T,F=i/L);var U=n.computeRealRoots(1,g,F),v=n.computeRealRoots(1,y,L);if(0!==U.length)return 0!==v.length?U[1]<=v[0]?[U[0],U[1],v[0],v[1]]:v[1]<=U[0]?[v[0],v[1],U[0],U[1]]:U[0]>=v[0]&&U[1]<=v[1]?[v[0],U[0],U[1],v[1]]:v[0]>=U[0]&&v[1]<=U[1]?[U[0],v[0],v[1],U[1]]:U[0]>v[0]&&U[0]<v[1]?[v[0],U[0],v[1],U[1]]:[U[0],v[0],U[1],v[1]]:U;if(0!==v.length)return v}return[]}var i={};return i.computeDiscriminant=function(e,t,r,n,a){var o=e*e,i=o*e,u=t*t,s=u*t,E=r*r,l=E*r,c=n*n,f=c*n,_=a*a;return u*E*c-4*s*f-4*e*l*c+18*e*t*r*f-27*o*c*c+256*i*(_*a)+a*(18*s*r*n-4*u*l+16*e*E*E-80*e*t*E*n-6*e*u*c+144*o*r*c)+_*(144*e*u*r-27*u*u-128*o*E-192*o*t*n)},i.computeRealRoots=function(t,n,i,u,s){if(Math.abs(t)<r.EPSILON15)return e.computeRealRoots(n,i,u,s);var E=n/t,l=i/t,c=u/t,f=s/t,_=E<0?1:0;switch(_+=l<0?_+1:_,_+=c<0?_+1:_,_+=f<0?_+1:_){case 0:return a(E,l,c,f);case 1:case 2:return o(E,l,c,f);case 3:case 4:return a(E,l,c,f);case 5:return o(E,l,c,f);case 6:case 7:return a(E,l,c,f);case 8:return o(E,l,c,f);case 9:case 10:return a(E,l,c,f);case 11:return o(E,l,c,f);case 12:case 13:case 14:case 15:return a(E,l,c,f);default:return}},i}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,r,n){"use strict";function a(r,n){n=e.clone(t(n,e.ZERO)),e.equals(n,e.ZERO)||e.normalize(n,n),this.origin=e.clone(t(r,e.ZERO)),this.direction=n}return a.getPoint=function(t,n,a){return r(a)||(a=new e),a=e.multiplyByScalar(t.direction,n,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,r,n,a,o,i,u,s,E,l){"use strict";function c(e,t,r,n){var a=t*t-4*e*r;if(!(a<0)){if(a>0){var o=1/(2*e),i=Math.sqrt(a),u=(-t+i)*o,s=(-t-i)*o;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var E=-t/(2*e);if(0!==E)return n.root0=n.root1=E,n}}function f(t,r,a){n(a)||(a=new o);var i=t.origin,u=t.direction,s=r.center,E=r.radius*r.radius,l=e.subtract(i,s,d),f=e.dot(u,u),_=2*e.dot(u,l),R=e.magnitudeSquared(l)-E,T=c(f,_,R,N);if(n(T))return a.start=T.root0,a.stop=T.root1,a}function _(e,t,r){var n=e+t;return i.sign(e)!==i.sign(t)&&Math.abs(n/Math.max(Math.abs(e),Math.abs(t)))<r?0:n}function R(t,r,n,a,o){var l,c=a*a,f=o*o,R=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*f,T=o*(a*_(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],i.EPSILON15)+r.y),h=t[u.COLUMN0ROW0]*c+t[u.COLUMN2ROW2]*f+a*r.x+n,A=f*_(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],i.EPSILON15),d=o*(a*_(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+r.z),S=[];if(0===d&&0===A){if(l=s.computeRealRoots(R,T,h),0===l.length)return S;var m=l[0],C=Math.sqrt(Math.max(1-m*m,0));if(S.push(new e(a,o*m,o*-C)),S.push(new e(a,o*m,o*C)),2===l.length){var N=l[1],I=Math.sqrt(Math.max(1-N*N,0));S.push(new e(a,o*N,o*-I)),S.push(new e(a,o*N,o*I))}return S}var M=d*d,p=A*A,O=R*R,g=d*A,y=O+p,F=2*(T*R+g),L=2*h*R+T*T-p+M,U=2*(h*T-g),v=h*h-M;if(0===y&&0===F&&0===L&&0===U)return S;l=E.computeRealRoots(y,F,L,U,v);var D=l.length;if(0===D)return S;for(var P=0;P<D;++P){var B,w=l[P],x=w*w,G=Math.max(1-x,0),b=Math.sqrt(G);B=i.sign(R)===i.sign(h)?_(R*x+h,T*w,i.EPSILON12):i.sign(h)===i.sign(T*w)?_(R*x,T*w+h,i.EPSILON12):_(R*x+T*w,h,i.EPSILON12);var z=_(A*w,d,i.EPSILON15),H=B*z;H<0?S.push(new e(a,o*w,o*b)):H>0?S.push(new e(a,o*w,o*-b)):0!==b?(S.push(new e(a,o*w,o*-b)),S.push(new e(a,o*w,o*b)),++P):S.push(new e(a,o*w,o*b))}return S}var T={};T.rayPlane=function(t,r,a){n(a)||(a=new e);var o=t.origin,u=t.direction,s=r.normal,E=e.dot(s,u);if(!(Math.abs(E)<i.EPSILON15)){var l=(-r.distance-e.dot(s,o))/E;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(o,a,a)}};var h=new e,A=new e,d=new e,S=new e,m=new e;T.rayTriangleParametric=function(t,n,a,o,u){u=r(u,!1);var s,E,l,c,f,_=t.origin,R=t.direction,T=e.subtract(a,n,h),C=e.subtract(o,n,A),N=e.cross(R,C,d),I=e.dot(T,N);if(u){if(I<i.EPSILON6)return;if(s=e.subtract(_,n,S),(l=e.dot(s,N))<0||l>I)return;if(E=e.cross(s,T,m),(c=e.dot(R,E))<0||l+c>I)return;f=e.dot(C,E)/I}else{if(Math.abs(I)<i.EPSILON6)return;var M=1/I;if(s=e.subtract(_,n,S),(l=e.dot(s,N)*M)<0||l>1)return;if(E=e.cross(s,T,m),(c=e.dot(R,E)*M)<0||l+c>1)return;f=e.dot(C,E)*M}return f},T.rayTriangle=function(t,r,a,o,i,u){var s=T.rayTriangleParametric(t,r,a,o,i);if(n(s)&&!(s<0))return n(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var C=new l;T.lineSegmentTriangle=function(t,r,a,o,i,u,s){var E=C;e.clone(t,E.origin),e.subtract(r,t,E.direction),e.normalize(E.direction,E.direction);var l=T.rayTriangleParametric(E,a,o,i,u);if(!(!n(l)||l<0||l>e.distance(t,r)))return n(s)||(s=new e),e.multiplyByScalar(E.direction,l,s),e.add(E.origin,s,s)};var N={root0:0,root1:0};T.raySphere=function(e,t,r){if(r=f(e,t,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var I=new l;T.lineSegmentSphere=function(t,r,a,o){var i=I;e.clone(t,i.origin);var u=e.subtract(r,t,i.direction),s=e.magnitude(u);if(e.normalize(u,u),o=f(i,a,o),!(!n(o)||o.stop<0||o.start>s))return o.start=Math.max(o.start,0),o.stop=Math.min(o.stop,s),o};var M=new e,p=new e;T.rayEllipsoid=function(t,r){var n,a,i,u,s,E=r.oneOverRadii,l=e.multiplyComponents(E,t.origin,M),c=e.multiplyComponents(E,t.direction,p),f=e.magnitudeSquared(l),_=e.dot(l,c);if(f>1){if(_>=0)return;var R=_*_;if(n=f-1,a=e.magnitudeSquared(c),i=a*n,R<i)return;if(R>i){u=_*_-i,s=-_+Math.sqrt(u);var T=s/a,h=n/s;return T<h?new o(T,h):{start:h,stop:T}}var A=Math.sqrt(n/a);return new o(A,A)}return f<1?(n=f-1,a=e.magnitudeSquared(c),i=a*n,u=_*_-i,s=-_+Math.sqrt(u),new o(0,s/a)):_<0?(a=e.magnitudeSquared(c),new o(0,-_/a)):void 0};var O=new e,g=new e,y=new e,F=new e,L=new e,U=new u,v=new u,D=new u,P=new u,B=new u,w=new u,x=new u,G=new e,b=new e,z=new t;T.grazingAltitudeLocation=function(t,r){var a=t.origin,o=t.direction;if(!e.equals(a,e.ZERO)){var s=r.geodeticSurfaceNormal(a,O);if(e.dot(o,s)>=0)return a}var E=n(this.rayEllipsoid(t,r)),l=r.transformPositionToScaledSpace(o,O),c=e.normalize(l,l),f=e.mostOrthogonalAxis(l,F),_=e.normalize(e.cross(f,c,g),g),T=e.normalize(e.cross(c,_,y),y),h=U;h[0]=c.x,h[1]=c.y,h[2]=c.z,h[3]=_.x,h[4]=_.y,h[5]=_.z,h[6]=T.x,h[7]=T.y,h[8]=T.z;var A=u.transpose(h,v),d=u.fromScale(r.radii,D),S=u.fromScale(r.oneOverRadii,P),m=B;m[0]=0,m[1]=-o.z,m[2]=o.y,m[3]=o.z,m[4]=0,m[5]=-o.x,m[6]=-o.y,m[7]=o.x,m[8]=0;var C,N,I=u.multiply(u.multiply(A,S,w),m,w),M=u.multiply(u.multiply(I,d,x),h,x),p=u.multiplyByVector(I,a,L),H=R(M,e.negate(p,O),0,0,1),V=H.length;if(V>0){for(var X=e.clone(e.ZERO,b),q=Number.NEGATIVE_INFINITY,W=0;W<V;++W){C=u.multiplyByVector(d,u.multiplyByVector(h,H[W],G),G);var Y=e.normalize(e.subtract(C,a,F),F),K=e.dot(Y,o);K>q&&(q=K,X=e.clone(C,X))}var k=r.cartesianToCartographic(X,z);return q=i.clamp(q,0,1),N=e.magnitude(e.subtract(X,a,F))*Math.sqrt(1-q*q),N=E?-N:N,k.height=N,r.cartographicToCartesian(k,new e)}};var H=new e;return T.lineSegmentPlane=function(t,r,a,o){n(o)||(o=new e);var u=e.subtract(r,t,H),s=a.normal,E=e.dot(s,u);if(!(Math.abs(E)<i.EPSILON6)){var l=e.dot(s,t),c=-(a.distance+l)/E;if(!(c<0||c>1))return e.multiplyByScalar(u,c,o),e.add(t,o,o),o}},T.trianglePlaneIntersection=function(t,r,n,a){var o=a.normal,i=a.distance,u=e.dot(o,t)+i<0,s=e.dot(o,r)+i<0,E=e.dot(o,n)+i<0,l=0;l+=u?1:0,l+=s?1:0,l+=E?1:0;var c,f;if(1!==l&&2!==l||(c=new e,f=new e),1===l){if(u)return T.lineSegmentPlane(t,r,a,c),T.lineSegmentPlane(t,n,a,f),{positions:[t,r,n,c,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return T.lineSegmentPlane(r,n,a,c),T.lineSegmentPlane(r,t,a,f),{positions:[t,r,n,c,f],indices:[1,3,4,2,0,4,2,4,3]};if(E)return T.lineSegmentPlane(n,t,a,c),T.lineSegmentPlane(n,r,a,f),{positions:[t,r,n,c,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return T.lineSegmentPlane(r,t,a,c),T.lineSegmentPlane(n,t,a,f),{positions:[t,r,n,c,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return T.lineSegmentPlane(n,r,a,c),T.lineSegmentPlane(t,r,a,f),{positions:[t,r,n,c,f],indices:[2,0,4,2,4,3,1,3,4]};if(!E)return T.lineSegmentPlane(t,n,a,c),T.lineSegmentPlane(r,n,a,f),{positions:[t,r,n,c,f],indices:[0,1,4,0,4,3,2,3,4]}}},T}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,r,n,a,o,i){"use strict";function u(t,r){this.normal=e.clone(t),this.distance=r}u.fromPointNormal=function(t,n,a){var o=-e.dot(n,t);return r(a)?(e.clone(n,a.normal),a.distance=o,a):new u(n,o)};var s=new e;u.fromCartesian4=function(t,n){var a=e.fromCartesian4(t,s),o=t.w;return r(n)?(e.clone(a,n.normal),n.distance=o,n):new u(a,o)},u.getPointDistance=function(t,r){return e.dot(t.normal,r)+t.distance};var E=new e;return u.transform=function(t,r,n){return i.multiplyByPointAsVector(r,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,E),i.multiplyByPoint(r,E,E),u.fromPointNormal(E,s,n)},u.clone=function(t,n){return r(n)?(e.clone(t.normal,n.normal),n.distance=t.distance,n):new u(t.normal,t.distance)},u.equals=function(t,r){return t.distance===r.distance&&e.equals(t.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,r,n,a,o,i,u,s,E,l,c){"use strict";function f(e,t,r){var n=M;n.length=e;var a;if(t===r){for(a=0;a<e;a++)n[a]=t;return n}var o=r-t,i=o/e;for(a=0;a<e;a++){var u=t+a*i;n[a]=u}return n}function _(t,r,n,a,o,i,u,s){var E=a.scaleToGeodeticSurface(t,y),l=a.scaleToGeodeticSurface(r,F),c=R.numberOfPoints(t,r,n),_=a.cartesianToCartographic(E,p),T=a.cartesianToCartographic(l,O),h=f(c,o,i);L.setEndPoints(_,T);var A=L.surfaceDistance/c,d=s;_.height=o;var S=a.cartographicToCartesian(_,g);e.pack(S,u,d),d+=3;for(var m=1;m<c;m++){var C=L.interpolateUsingSurfaceDistance(m*A,O);C.height=h[m],S=a.cartographicToCartesian(C,g),e.pack(S,u,d),d+=3}return d}var R={};R.numberOfPoints=function(t,r,n){var a=e.distance(t,r);return Math.ceil(a/n)};var T=new t;R.extractHeights=function(e,t){for(var r=e.length,n=new Array(r),a=0;a<r;a++){var o=e[a];n[a]=t.cartesianToCartographic(o,T).height}return n};var h=new l,A=new e,d=new e,S=new c(e.UNIT_X,0),m=new e,C=new c(e.UNIT_X,0),N=new e,I=new e,M=[],p=new t,O=new t,g=new e,y=new e,F=new e,L=new i;return R.wrapLongitude=function(t,a){var o=[],i=[];if(n(t)&&t.length>0){a=r(a,l.IDENTITY);var s=l.inverseTransformation(a,h),E=l.multiplyByPoint(s,e.ZERO,A),f=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,d),d),_=c.fromPointNormal(E,f,S),R=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,m),m),T=c.fromPointNormal(E,R,C),M=1;o.push(e.clone(t[0]));for(var p=o[0],O=t.length,g=1;g<O;++g){var y=t[g];if(c.getPointDistance(T,p)<0||c.getPointDistance(T,y)<0){var F=u.lineSegmentPlane(p,y,_,N);if(n(F)){var L=e.multiplyByScalar(f,5e-9,I);c.getPointDistance(_,p)<0&&e.negate(L,L),o.push(e.add(F,L,new e)),i.push(M+1),e.negate(L,L),o.push(e.add(F,L,new e)),M=1}}o.push(e.clone(t[g])),M++,p=y}i.push(M)}return{positions:o,lengths:i}},R.generateArc=function(t){n(t)||(t={});var a=t.positions,i=a.length,u=r(t.ellipsoid,o.WGS84),l=r(t.height,0),c=s(l);if(i<1)return[];if(1===i){var f=u.scaleToGeodeticSurface(a[0],y);if(0!==(l=c?l[0]:l)){var T=u.geodeticSurfaceNormal(f,g);e.multiplyByScalar(T,l,T),e.add(f,T,f)}return[f.x,f.y,f.z]}var h=t.minDistance;if(!n(h)){var A=r(t.granularity,E.RADIANS_PER_DEGREE);h=E.chordLength(A,u.maximumRadius)}var d,S=0;for(d=0;d<i-1;d++)S+=R.numberOfPoints(a[d],a[d+1],h);var m=3*(S+1),C=new Array(m),N=0;for(d=0;d<i-1;d++){N=_(a[d],a[d+1],h,u,c?l[d]:l,c?l[d+1]:l,C,N)}M.length=0;var I=a[i-1],O=u.cartesianToCartographic(I,p);O.height=c?l[i-1]:l;var F=u.cartographicToCartesian(O,g);return e.pack(F,C,m-3),C},R.generateCartesianArc=function(t){for(var r=R.generateArc(t),n=r.length/3,a=new Array(n),o=0;o<n;o++)a[o]=e.unpack(r,3*o);return a},R}),define("Core/SimplePolylineGeometry",["./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType"],function(e,t,r,n,a,o,i,u,s,E,l,c,f,_,R){"use strict";function T(e,t,n,a,o,i,u){var s,E=_.numberOfPoints(e,t,o),l=n.red,c=n.green,f=n.blue,R=n.alpha,T=a.red,h=a.green,A=a.blue,d=a.alpha;if(r.equals(n,a)){for(s=0;s<E;s++)i[u++]=r.floatToByte(l),i[u++]=r.floatToByte(c),i[u++]=r.floatToByte(f),i[u++]=r.floatToByte(R);return u}var S=(T-l)/E,m=(h-c)/E,C=(A-f)/E,N=(d-R)/E,I=u;for(s=0;s<E;s++)i[I++]=r.floatToByte(l+s*S),i[I++]=r.floatToByte(c+s*m),i[I++]=r.floatToByte(f+s*C),i[I++]=r.floatToByte(R+s*N);return I}function h(e){e=a(e,a.EMPTY_OBJECT);var n=e.positions,i=e.colors,s=a(e.colorsPerVertex,!1);this._positions=n,this._colors=i,this._colorsPerVertex=s,this._followSurface=a(e.followSurface,!0),this._granularity=a(e.granularity,f.RADIANS_PER_DEGREE),this._ellipsoid=a(e.ellipsoid,u.WGS84),this._workerName="createSimplePolylineGeometry";var E=1+n.length*t.packedLength;E+=o(i)?1+i.length*r.packedLength:1,this.packedLength=E+u.packedLength+3}h.pack=function(e,n,i){i=a(i,0);var s,E=e._positions,l=E.length;for(n[i++]=l,s=0;s<l;++s,i+=t.packedLength)t.pack(E[s],n,i);var c=e._colors;for(l=o(c)?c.length:0,n[i++]=l,s=0;s<l;++s,i+=r.packedLength)r.pack(c[s],n,i);return u.pack(e._ellipsoid,n,i),i+=u.packedLength,n[i++]=e._colorsPerVertex?1:0,n[i++]=e._followSurface?1:0,n[i]=e._granularity,n},h.unpack=function(e,n,i){n=a(n,0);var s,E=e[n++],l=new Array(E);for(s=0;s<E;++s,n+=t.packedLength)l[s]=t.unpack(e,n);E=e[n++];var c=E>0?new Array(E):void 0;for(s=0;s<E;++s,n+=r.packedLength)c[s]=r.unpack(e,n);var f=u.unpack(e,n);n+=u.packedLength;var _=1===e[n++],R=1===e[n++],T=e[n];return o(i)?(i._positions=l,i._colors=c,i._ellipsoid=f,i._colorsPerVertex=_,i._followSurface=R,i._granularity=T,i):new h({positions:l,colors:c,ellipsoid:f,colorsPerVertex:_,followSurface:R,granularity:T})};var A=new Array(2),d=new Array(2),S={positions:A,height:d,ellipsoid:void 0,minDistance:void 0};return h.createGeometry=function(a){var i,u,h,m,C,N=a._positions,I=a._colors,M=a._colorsPerVertex,p=a._followSurface,O=a._granularity,g=a._ellipsoid,y=f.chordLength(O,g.maximumRadius),F=o(I)&&!M,L=N.length,U=0;if(p){var v=_.extractHeights(N,g),D=S;if(D.minDistance=y,D.ellipsoid=g,F){var P=0;for(i=0;i<L-1;i++)P+=_.numberOfPoints(N[i],N[i+1],y)+1;u=new Float64Array(3*P),m=new Uint8Array(4*P),D.positions=A,D.height=d;var B=0;for(i=0;i<L-1;++i){A[0]=N[i],A[1]=N[i+1],d[0]=v[i],d[1]=v[i+1];var w=_.generateArc(D);if(o(I)){var x=w.length/3;C=I[i];for(var G=0;G<x;++G)m[B++]=r.floatToByte(C.red),m[B++]=r.floatToByte(C.green),m[B++]=r.floatToByte(C.blue),m[B++]=r.floatToByte(C.alpha)}u.set(w,U),U+=w.length}}else if(D.positions=N,D.height=v,u=new Float64Array(_.generateArc(D)),o(I)){for(m=new Uint8Array(u.length/3*4),i=0;i<L-1;++i){var b=N[i],z=N[i+1],H=I[i],V=I[i+1];U=T(b,z,H,V,y,m,U)}var X=I[L-1];m[U++]=r.floatToByte(X.red),m[U++]=r.floatToByte(X.green),m[U++]=r.floatToByte(X.blue),m[U++]=r.floatToByte(X.alpha)}}else{h=F?2*L-2:L,u=new Float64Array(3*h),m=o(I)?new Uint8Array(4*h):void 0;var q=0,W=0;for(i=0;i<L;++i){var Y=N[i];if(F&&i>0&&(t.pack(Y,u,q),q+=3,C=I[i-1],m[W++]=r.floatToByte(C.red),m[W++]=r.floatToByte(C.green),m[W++]=r.floatToByte(C.blue),m[W++]=r.floatToByte(C.alpha)),F&&i===L-1)break;t.pack(Y,u,q),q+=3,o(I)&&(C=I[i],m[W++]=r.floatToByte(C.red),m[W++]=r.floatToByte(C.green),m[W++]=r.floatToByte(C.blue),m[W++]=r.floatToByte(C.alpha))}}var K=new l;K.position=new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:u}),o(I)&&(K.color=new E({componentDatatype:n.UNSIGNED_BYTE,componentsPerAttribute:4,values:m,normalize:!0})),h=u.length/3;var k=2*(h-1),Z=c.createTypedArray(h,k),j=0;for(i=0;i<h-1;++i)Z[j++]=i,Z[j++]=i+1;return new s({attributes:K,indices:Z,primitiveType:R.LINES,boundingSphere:e.fromPoints(N)})},h}),define("Workers/createSimplePolylineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/SimplePolylineGeometry"],function(e,t,r){"use strict";function n(n,a){return e(a)&&(n=r.unpack(n,a)),n._ellipsoid=t.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function r(t){return t+" is required, actual value was undefined"}function n(t,e,r){return"Expected "+r+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(n,a){if(!t(a))throw new e(r(n))},a.typeOf.func=function(t,r){if("function"!=typeof r)throw new e(n(typeof r,"function",t))},a.typeOf.string=function(t,r){if("string"!=typeof r)throw new e(n(typeof r,"string",t))},a.typeOf.number=function(t,r){if("number"!=typeof r)throw new e(n(typeof r,"number",t))},a.typeOf.number.lessThan=function(t,r,n){if(a.typeOf.number(t,r),r>=n)throw new e("Expected "+t+" to be less than "+n+", actual value was "+r)},a.typeOf.number.lessThanOrEquals=function(t,r,n){if(a.typeOf.number(t,r),r>n)throw new e("Expected "+t+" to be less than or equal to "+n+", actual value was "+r)},a.typeOf.number.greaterThan=function(t,r,n){if(a.typeOf.number(t,r),r<=n)throw new e("Expected "+t+" to be greater than "+n+", actual value was "+r)},a.typeOf.number.greaterThanOrEquals=function(t,r,n){if(a.typeOf.number(t,r),r<n)throw new e("Expected "+t+" to be greater than or equal to"+n+", actual value was "+r)},a.typeOf.object=function(t,r){if("object"!=typeof r)throw new e(n(typeof r,"object",t))},a.typeOf.bool=function(t,r){if("boolean"!=typeof r)throw new e(n(typeof r,"boolean",t))},a.typeOf.number.equals=function(t,r,n,o){if(a.typeOf.number(t,n),a.typeOf.number(r,o),n!==o)throw new e(t+" must be equal to "+r+", the actual values are "+n+" and "+o)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var r;for(this.mti==this.N+1&&this.init_genrand(5489),r=0;r<this.N-this.M;r++)t=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+this.M]^t>>>1^e[1&t];for(;r<this.N-1;r++)t=this.mt[r]&this.UPPER_MASK|this.mt[r+1]&this.LOWER_MASK,this.mt[r]=this.mt[r+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,r,n){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,r){return r=e(r,255),Math.round((.5*a.clamp(t,-1,1)+.5)*r)},a.fromSNorm=function(t,r){return r=e(r,255),a.clamp(t,0,r)/r*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,r){return(1-r)*t+r*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,r=t-Math.floor(t/e)*e;return r<-Math.PI?r+e:r>=Math.PI?r-e:r},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,r,n,a){a=e(a,n);var o=Math.abs(t-r);return o<=a||o<=n*Math.max(Math.abs(t),Math.abs(r))};var o=[1];a.factorial=function(t){var e=o.length;if(t>=e)for(var r=o[e-1],n=e;n<=t;n++)o.push(r*n);return o[t]},a.incrementWrap=function(t,r,n){return n=e(n,0),++t,t>r&&(t=n),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,r){return t<e?e:t>r?r:t};var i=new t;return a.setRandomNumberSeed=function(e){i=new t(e)},a.nextRandomNumber=function(){return i.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var r=t*e;return 1-Math.exp(-r*r)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,r,n){this.x=e(t,0),this.y=e(r,0),this.z=e(n,0)}i.fromSpherical=function(t,n){r(n)||(n=new i);var a=t.clock,o=t.cone,u=e(t.magnitude,1),s=u*Math.sin(o);return n.x=s*Math.cos(a),n.y=s*Math.sin(a),n.z=u*Math.cos(o),n},i.fromElements=function(t,e,n,a){return r(a)?(a.x=t,a.y=e,a.z=n,a):new i(t,e,n)},i.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new i(t.x,t.y,t.z)},i.fromCartesian4=i.clone,i.packedLength=3,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.x,r[n++]=t.y,r[n]=t.z,r},i.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new i),a.x=t[n++],a.y=t[n++],a.z=t[n],a},i.packArray=function(t,e){var n=t.length;r(e)?e.length=3*n:e=new Array(3*n);for(var a=0;a<n;++a)i.pack(t[a],e,3*a);return e},i.unpackArray=function(t,e){var n=t.length;r(e)?e.length=n/3:e=new Array(n/3);for(var a=0;a<n;a+=3){var o=a/3;e[o]=i.unpack(t,a,e[o])}return e},i.fromArray=i.unpack,i.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},i.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},i.minimumByComponent=function(t,e,r){return r.x=Math.min(t.x,e.x),r.y=Math.min(t.y,e.y),r.z=Math.min(t.z,e.z),r},i.maximumByComponent=function(t,e,r){return r.x=Math.max(t.x,e.x),r.y=Math.max(t.y,e.y),r.z=Math.max(t.z,e.z),r},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},i.magnitude=function(t){return Math.sqrt(i.magnitudeSquared(t))};var u=new i;i.distance=function(t,e){return i.subtract(t,e,u),i.magnitude(u)},i.distanceSquared=function(t,e){return i.subtract(t,e,u),i.magnitudeSquared(u)},i.normalize=function(t,e){var r=i.magnitude(t);return e.x=t.x/r,e.y=t.y/r,e.z=t.z/r,e},i.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},i.multiplyComponents=function(t,e,r){return r.x=t.x*e.x,r.y=t.y*e.y,r.z=t.z*e.z,r},i.divideComponents=function(t,e,r){return r.x=t.x/e.x,r.y=t.y/e.y,r.z=t.z/e.z,r},i.add=function(t,e,r){return r.x=t.x+e.x,r.y=t.y+e.y,r.z=t.z+e.z,r},i.subtract=function(t,e,r){return r.x=t.x-e.x,r.y=t.y-e.y,r.z=t.z-e.z,r},i.multiplyByScalar=function(t,e,r){return r.x=t.x*e,r.y=t.y*e,r.z=t.z*e,r},i.divideByScalar=function(t,e,r){return r.x=t.x/e,r.y=t.y/e,r.z=t.z/e,r},i.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},i.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var s=new i;i.lerp=function(t,e,r,n){return i.multiplyByScalar(e,r,s),n=i.multiplyByScalar(t,1-r,n),i.add(s,n,n)};var E=new i,l=new i;i.angleBetween=function(t,e){i.normalize(t,E),i.normalize(e,l);var r=i.dot(E,l),n=i.magnitude(i.cross(E,l,E));return Math.atan2(n,r)};var c=new i;i.mostOrthogonalAxis=function(t,e){var r=i.normalize(t,c);return i.abs(r,r),e=r.x<=r.y?r.x<=r.z?i.clone(i.UNIT_X,e):i.clone(i.UNIT_Z,e):r.y<=r.z?i.clone(i.UNIT_Y,e):i.clone(i.UNIT_Z,e)},i.projectVector=function(t,e,r){var n=i.dot(t,e)/i.dot(e,e);return i.multiplyByScalar(e,n,r)},i.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},i.equalsArray=function(t,e,r){return t.x===e[r]&&t.y===e[r+1]&&t.z===e[r+2]},i.equalsEpsilon=function(t,e,n,a){return t===e||r(t)&&r(e)&&o.equalsEpsilon(t.x,e.x,n,a)&&o.equalsEpsilon(t.y,e.y,n,a)&&o.equalsEpsilon(t.z,e.z,n,a)},i.cross=function(t,e,r){var n=t.x,a=t.y,o=t.z,i=e.x,u=e.y,s=e.z,E=a*s-o*u,l=o*i-n*s,c=n*u-a*i;return r.x=E,r.y=l,r.z=c,r},i.fromDegrees=function(t,e,r,n,a){return t=o.toRadians(t),e=o.toRadians(e),i.fromRadians(t,e,r,n,a)};var f=new i,_=new i,R=new i(40680631590769,40680631590769,40408299984661.445);return i.fromRadians=function(t,n,a,o,u){a=e(a,0);var s=r(o)?o.radiiSquared:R,E=Math.cos(n);f.x=E*Math.cos(t),f.y=E*Math.sin(t),f.z=Math.sin(n),f=i.normalize(f,f),i.multiplyComponents(s,f,_);var l=Math.sqrt(i.dot(f,_));return _=i.divideByScalar(_,l,_),f=i.multiplyByScalar(f,a,f),r(u)||(u=new i),i.add(_,f,u)},i.fromDegreesArray=function(t,e,n){var a=t.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=t[o],s=t[o+1],E=o/2;n[E]=i.fromDegrees(u,s,0,e,n[E])}return n},i.fromRadiansArray=function(t,e,n){var a=t.length;r(n)?n.length=a/2:n=new Array(a/2);for(var o=0;o<a;o+=2){var u=t[o],s=t[o+1],E=o/2;n[E]=i.fromRadians(u,s,0,e,n[E])}return n},i.fromDegreesArrayHeights=function(t,e,n){var a=t.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=t[o],s=t[o+1],E=t[o+2],l=o/3;n[l]=i.fromDegrees(u,s,E,e,n[l])}return n},i.fromRadiansArrayHeights=function(t,e,n){var a=t.length;r(n)?n.length=a/3:n=new Array(a/3);for(var o=0;o<a;o+=3){var u=t[o],s=t[o+1],E=t[o+2],l=o/3;n[l]=i.fromRadians(u,s,E,e,n[l])}return n},i.ZERO=a(new i(0,0,0)),i.UNIT_X=a(new i(1,0,0)),i.UNIT_Y=a(new i(0,1,0)),i.UNIT_Z=a(new i(0,0,1)),i.prototype.clone=function(t){return i.clone(this,t)},i.prototype.equals=function(t){return i.equals(this,t)},i.prototype.equalsEpsilon=function(t,e,r){return i.equalsEpsilon(this,t,e,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,r,n){"use strict";function a(r,a,u,s,E){var l=r.x,c=r.y,f=r.z,_=a.x,R=a.y,T=a.z,h=l*l*_*_,A=c*c*R*R,d=f*f*T*T,S=h+A+d,m=Math.sqrt(1/S),C=t.multiplyByScalar(r,m,o);if(S<s)return isFinite(m)?t.clone(C,E):void 0;var N=u.x,I=u.y,M=u.z,p=i;p.x=C.x*N*2,p.y=C.y*I*2,p.z=C.z*M*2;var O,g,y,F,L,v,U,P,D,B,w,x=(1-m)*t.magnitude(r)/(.5*t.magnitude(p)),G=0;do{x-=G,y=1/(1+x*N),F=1/(1+x*I),L=1/(1+x*M),v=y*y,U=F*F,P=L*L,D=v*y,B=U*F,w=P*L,O=h*v+A*U+d*P-1,g=h*D*N+A*B*I+d*w*M;G=O/(-2*g)}while(Math.abs(O)>n.EPSILON12);return e(E)?(E.x=l*y,E.y=c*F,E.z=f*L,E):new t(l*y,c*F,f*L)}var o=new t,i=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,r,n,a,o,i){"use strict";function u(t,e,n){this.longitude=r(t,0),this.latitude=r(e,0),this.height=r(n,0)}u.fromRadians=function(t,e,a,o){return a=r(a,0),n(o)?(o.longitude=t,o.latitude=e,o.height=a,o):new u(t,e,a)},u.fromDegrees=function(t,e,r,n){return t=o.toRadians(t),e=o.toRadians(e),u.fromRadians(t,e,r,n)};var s=new t,E=new t,l=new t,c=new t(1/6378137,1/6378137,1/6356752.314245179),f=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),_=o.EPSILON1;return u.fromCartesian=function(e,r,a){var R=n(r)?r.oneOverRadii:c,T=n(r)?r.oneOverRadiiSquared:f,h=n(r)?r._centerToleranceSquared:_,A=i(e,R,T,h,E);if(n(A)){var d=t.multiplyComponents(A,T,s);d=t.normalize(d,d);var S=t.subtract(e,A,l),m=Math.atan2(d.y,d.x),C=Math.asin(d.z),N=o.sign(t.dot(S,e))*t.magnitude(S);return n(a)?(a.longitude=m,a.latitude=C,a.height=N,a):new u(m,C,N)}},u.toCartesian=function(e,r,n){return t.fromRadians(e.longitude,e.latitude,e.height,r,n)},u.clone=function(t,e){if(n(t))return n(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||n(t)&&n(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,r){return t===e||n(t)&&n(e)&&Math.abs(t.longitude-e.longitude)<=r&&Math.abs(t.latitude-e.latitude)<=r&&Math.abs(t.height-e.height)<=r},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),r=Object.defineProperties;return e&&t(r)||(r=function(t){return t}),r}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,r,n,a,o,i,u,s,E){"use strict";function l(e,r,a,o){r=n(r,0),a=n(a,0),o=n(o,0),e._radii=new t(r,a,o),e._radiiSquared=new t(r*r,a*a,o*o),e._radiiToTheFourth=new t(r*r*r*r,a*a*a*a,o*o*o*o),e._oneOverRadii=new t(0===r?0:1/r,0===a?0:1/a,0===o?0:1/o),e._oneOverRadiiSquared=new t(0===r?0:1/(r*r),0===a?0:1/(a*a),0===o?0:1/(o*o)),e._minimumRadius=Math.min(r,a,o),e._maximumRadius=Math.max(r,a,o),e._centerToleranceSquared=s.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function c(t,e,r){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,t,e,r)}o(c.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),c.clone=function(e,r){if(a(e)){var n=e._radii;return a(r)?(t.clone(n,r._radii),t.clone(e._radiiSquared,r._radiiSquared),t.clone(e._radiiToTheFourth,r._radiiToTheFourth),t.clone(e._oneOverRadii,r._oneOverRadii),t.clone(e._oneOverRadiiSquared,r._oneOverRadiiSquared),r._minimumRadius=e._minimumRadius,r._maximumRadius=e._maximumRadius,r._centerToleranceSquared=e._centerToleranceSquared,r):new c(n.x,n.y,n.z)}},c.fromCartesian3=function(t,e){return a(e)||(e=new c),a(t)?(l(e,t.x,t.y,t.z),e):e},c.WGS84=u(new c(6378137,6378137,6356752.314245179)),c.UNIT_SPHERE=u(new c(1,1,1)),c.MOON=u(new c(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),c.prototype.clone=function(t){return c.clone(this,t)},c.packedLength=t.packedLength,c.pack=function(e,r,a){return a=n(a,0),t.pack(e._radii,r,a),r},c.unpack=function(e,r,a){r=n(r,0);var o=t.unpack(e,r);return c.fromCartesian3(o,a)},c.prototype.geocentricSurfaceNormal=t.normalize,c.prototype.geodeticSurfaceNormalCartographic=function(e,r){var n=e.longitude,o=e.latitude,i=Math.cos(o),u=i*Math.cos(n),s=i*Math.sin(n),E=Math.sin(o);return a(r)||(r=new t),r.x=u,r.y=s,r.z=E,t.normalize(r,r)},c.prototype.geodeticSurfaceNormal=function(e,r){return a(r)||(r=new t),r=t.multiplyComponents(e,this._oneOverRadiiSquared,r),t.normalize(r,r)};var f=new t,_=new t;c.prototype.cartographicToCartesian=function(e,r){var n=f,o=_;this.geodeticSurfaceNormalCartographic(e,n),t.multiplyComponents(this._radiiSquared,n,o);var i=Math.sqrt(t.dot(n,o));return t.divideByScalar(o,i,o),t.multiplyByScalar(n,e.height,n),a(r)||(r=new t),t.add(o,n,r)},c.prototype.cartographicArrayToCartesianArray=function(t,e){var r=t.length;a(e)?e.length=r:e=new Array(r);for(var n=0;n<r;n++)e[n]=this.cartographicToCartesian(t[n],e[n]);return e};var R=new t,T=new t,h=new t;return c.prototype.cartesianToCartographic=function(r,n){var o=this.scaleToGeodeticSurface(r,T);if(a(o)){var i=this.geodeticSurfaceNormal(o,R),u=t.subtract(r,o,h),E=Math.atan2(i.y,i.x),l=Math.asin(i.z),c=s.sign(t.dot(u,r))*t.magnitude(u);return a(n)?(n.longitude=E,n.latitude=l,n.height=c,n):new e(E,l,c)}},c.prototype.cartesianArrayToCartographicArray=function(t,e){var r=t.length;a(e)?e.length=r:e=new Array(r);for(var n=0;n<r;++n)e[n]=this.cartesianToCartographic(t[n],e[n]);return e},c.prototype.scaleToGeodeticSurface=function(t,e){return E(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},c.prototype.scaleToGeocentricSurface=function(e,r){a(r)||(r=new t);var n=e.x,o=e.y,i=e.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(n*n*u.x+o*o*u.y+i*i*u.z);return t.multiplyByScalar(e,s,r)},c.prototype.transformPositionToScaledSpace=function(e,r){return a(r)||(r=new t),t.multiplyComponents(e,this._oneOverRadii,r)},c.prototype.transformPositionFromScaledSpace=function(e,r){return a(r)||(r=new t),t.multiplyComponents(e,this._radii,r)},c.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},c.prototype.toString=function(){return this._radii.toString()},c.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,r,o){r=n(r,0);var i=this._squaredXOverSquaredZ;if(a(o)||(o=new t),o.x=0,o.y=0,o.z=e.z*(1-i),!(Math.abs(o.z)>=this._radii.z-r))return o},c}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,r,n,a,o,i){"use strict";function u(t){this._ellipsoid=r(t,i.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,r){var a=this._semimajorAxis,o=e.longitude*a,i=e.latitude*a,u=e.height;return n(r)?(r.x=o,r.y=i,r.z=u,r):new t(o,i,u)},u.prototype.unproject=function(t,r){var a=this._oneOverSemimajorAxis,o=t.x*a,i=t.y*a,u=t.z;return n(r)?(r.longitude=o,r.latitude=i,r.height=u,r):new e(o,i,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,r){this.start=t(e,0),this.stop=t(r,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t,e,n,a,o,i,u,s,E){this[0]=r(t,0),this[1]=r(a,0),this[2]=r(u,0),this[3]=r(e,0),this[4]=r(o,0),this[5]=r(s,0),this[6]=r(n,0),this[7]=r(i,0),this[8]=r(E,0)}function E(t){for(var e=0,r=0;r<9;++r){var n=t[r];e+=n*n}return Math.sqrt(e)}function l(t){for(var e=0,r=0;r<3;++r){var n=t[s.getElementIndex(T[r],R[r])];e+=2*n*n}return Math.sqrt(e)}function c(t,e){for(var r=u.EPSILON15,n=0,a=1,o=0;o<3;++o){var i=Math.abs(t[s.getElementIndex(T[o],R[o])]);i>n&&(a=o,n=i)}var E=1,l=0,c=R[a],f=T[a];if(Math.abs(t[s.getElementIndex(f,c)])>r){var _,h=t[s.getElementIndex(f,f)],A=t[s.getElementIndex(c,c)],d=t[s.getElementIndex(f,c)],S=(h-A)/2/d;_=S<0?-1/(-S+Math.sqrt(1+S*S)):1/(S+Math.sqrt(1+S*S)),E=1/Math.sqrt(1+_*_),l=_*E}return e=s.clone(s.IDENTITY,e),e[s.getElementIndex(c,c)]=e[s.getElementIndex(f,f)]=E,e[s.getElementIndex(f,c)]=l,e[s.getElementIndex(c,f)]=-l,e}s.packedLength=9,s.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e},s.unpack=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},s.clone=function(t,e){if(n(t))return n(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new s(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},s.fromArray=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},s.fromColumnMajorArray=function(t,e){return s.clone(t,e)},s.fromRowMajorArray=function(t,e){return n(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new s(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},s.fromQuaternion=function(t,e){var r=t.x*t.x,a=t.x*t.y,o=t.x*t.z,i=t.x*t.w,u=t.y*t.y,E=t.y*t.z,l=t.y*t.w,c=t.z*t.z,f=t.z*t.w,_=t.w*t.w,R=r-u-c+_,T=2*(a-f),h=2*(o+l),A=2*(a+f),d=-r+u-c+_,S=2*(E-i),m=2*(o-l),C=2*(E+i),N=-r-u+c+_;return n(e)?(e[0]=R,e[1]=A,e[2]=m,e[3]=T,e[4]=d,e[5]=C,e[6]=h,e[7]=S,e[8]=N,e):new s(R,T,h,A,d,S,m,C,N)},s.fromHeadingPitchRoll=function(t,e){var r=Math.cos(-t.pitch),a=Math.cos(-t.heading),o=Math.cos(t.roll),i=Math.sin(-t.pitch),u=Math.sin(-t.heading),E=Math.sin(t.roll),l=r*a,c=-o*u+E*i*a,f=E*u+o*i*a,_=r*u,R=o*a+E*i*u,T=-E*a+o*i*u,h=-i,A=E*r,d=o*r;return n(e)?(e[0]=l,e[1]=_,e[2]=h,e[3]=c,e[4]=R,e[5]=A,e[6]=f,e[7]=T,e[8]=d,e):new s(l,c,f,_,R,T,h,A,d)},s.fromScale=function(t,e){return n(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new s(t.x,0,0,0,t.y,0,0,0,t.z)},s.fromUniformScale=function(t,e){return n(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new s(t,0,0,0,t,0,0,0,t)},s.fromCrossProduct=function(t,e){return n(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new s(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},s.fromRotationX=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=r,e[5]=a,e[6]=0,e[7]=-a,e[8]=r,e):new s(1,0,0,0,r,-a,0,a,r)},s.fromRotationY=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=r,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=r,e):new s(r,0,a,0,1,0,-a,0,r)},s.fromRotationZ=function(t,e){var r=Math.cos(t),a=Math.sin(t);return n(e)?(e[0]=r,e[1]=a,e[2]=0,e[3]=-a,e[4]=r,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new s(r,-a,0,a,r,0,0,0,1)},s.toArray=function(t,e){return n(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},s.getElementIndex=function(t,e){return 3*t+e},s.getColumn=function(t,e,r){var n=3*e,a=t[n],o=t[n+1],i=t[n+2];return r.x=a,r.y=o,r.z=i,r},s.setColumn=function(t,e,r,n){n=s.clone(t,n);var a=3*e;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n},s.getRow=function(t,e,r){var n=t[e],a=t[e+3],o=t[e+6];return r.x=n,r.y=a,r.z=o,r},s.setRow=function(t,e,r,n){return n=s.clone(t,n),n[e]=r.x,n[e+3]=r.y,n[e+6]=r.z,n};var f=new t;s.getScale=function(e,r){return r.x=t.magnitude(t.fromElements(e[0],e[1],e[2],f)),r.y=t.magnitude(t.fromElements(e[3],e[4],e[5],f)),r.z=t.magnitude(t.fromElements(e[6],e[7],e[8],f)),r};var _=new t;s.getMaximumScale=function(e){return s.getScale(e,_),t.maximumComponent(_)},s.multiply=function(t,e,r){var n=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],o=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],i=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],s=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],E=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],l=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],c=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return r[0]=n,r[1]=a,r[2]=o,r[3]=i,r[4]=u,r[5]=s,r[6]=E,r[7]=l,r[8]=c,r},s.add=function(t,e,r){return r[0]=t[0]+e[0],r[1]=t[1]+e[1],r[2]=t[2]+e[2],r[3]=t[3]+e[3],r[4]=t[4]+e[4],r[5]=t[5]+e[5],r[6]=t[6]+e[6],r[7]=t[7]+e[7],r[8]=t[8]+e[8],r},s.subtract=function(t,e,r){return r[0]=t[0]-e[0],r[1]=t[1]-e[1],r[2]=t[2]-e[2],r[3]=t[3]-e[3],r[4]=t[4]-e[4],r[5]=t[5]-e[5],r[6]=t[6]-e[6],r[7]=t[7]-e[7],r[8]=t[8]-e[8],r},s.multiplyByVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[3]*a+t[6]*o,u=t[1]*n+t[4]*a+t[7]*o,s=t[2]*n+t[5]*a+t[8]*o;return r.x=i,r.y=u,r.z=s,r},s.multiplyByScalar=function(t,e,r){return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*e,r[5]=t[5]*e,r[6]=t[6]*e,r[7]=t[7]*e,r[8]=t[8]*e,r},s.multiplyByScale=function(t,e,r){return r[0]=t[0]*e.x,r[1]=t[1]*e.x,r[2]=t[2]*e.x,r[3]=t[3]*e.y,r[4]=t[4]*e.y,r[5]=t[5]*e.y,r[6]=t[6]*e.z,r[7]=t[7]*e.z,r[8]=t[8]*e.z,r},s.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},s.transpose=function(t,e){var r=t[0],n=t[3],a=t[6],o=t[1],i=t[4],u=t[7],s=t[2],E=t[5],l=t[8];return e[0]=r,e[1]=n,e[2]=a,e[3]=o,e[4]=i,e[5]=u,e[6]=s,e[7]=E,e[8]=l,e};var R=[1,0,0],T=[2,2,1],h=new s,A=new s;return s.computeEigenDecomposition=function(t,e){var r=u.EPSILON20,a=0,o=0;n(e)||(e={});for(var i=e.unitary=s.clone(s.IDENTITY,e.unitary),f=e.diagonal=s.clone(t,e.diagonal),_=r*E(f);o<10&&l(f)>_;)c(f,h),s.transpose(h,A),s.multiply(f,h,f),s.multiply(A,f,f),s.multiply(i,h,i),++a>2&&(++o,a=0);return e},s.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},s.determinant=function(t){var e=t[0],r=t[3],n=t[6],a=t[1],o=t[4],i=t[7],u=t[2],s=t[5],E=t[8];return e*(o*E-s*i)+a*(s*n-r*E)+u*(r*i-o*n)},s.inverse=function(t,e){var r=t[0],n=t[1],a=t[2],o=t[3],i=t[4],u=t[5],E=t[6],l=t[7],c=t[8],f=s.determinant(t);e[0]=i*c-l*u,e[1]=l*a-n*c,e[2]=n*u-i*a,e[3]=E*u-o*c,e[4]=r*c-E*a,e[5]=o*a-r*u,e[6]=o*l-E*i,e[7]=E*n-r*l,e[8]=r*i-o*n;var _=1/f;return s.multiplyByScalar(e,_,e)},s.equals=function(t,e){return t===e||n(t)&&n(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},s.equalsEpsilon=function(t,e,r){return t===e||n(t)&&n(e)&&Math.abs(t[0]-e[0])<=r&&Math.abs(t[1]-e[1])<=r&&Math.abs(t[2]-e[2])<=r&&Math.abs(t[3]-e[3])<=r&&Math.abs(t[4]-e[4])<=r&&Math.abs(t[5]-e[5])<=r&&Math.abs(t[6]-e[6])<=r&&Math.abs(t[7]-e[7])<=r&&Math.abs(t[8]-e[8])<=r},s.IDENTITY=i(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=i(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equalsArray=function(t,e,r){return t[0]===e[r]&&t[1]===e[r+1]&&t[2]===e[r+2]&&t[3]===e[r+3]&&t[4]===e[r+4]&&t[5]===e[r+5]&&t[6]===e[r+6]&&t[7]===e[r+7]&&t[8]===e[r+8]},s.prototype.equalsEpsilon=function(t,e){return s.equalsEpsilon(this,t,e)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,r,n,a){this.x=e(t,0),this.y=e(r,0),this.z=e(n,0),this.w=e(a,0)}i.fromElements=function(t,e,n,a,o){return r(o)?(o.x=t,o.y=e,o.z=n,o.w=a,o):new i(t,e,n,a)},i.fromColor=function(t,e){return r(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new i(t.red,t.green,t.blue,t.alpha)},i.clone=function(t,e){if(r(t))return r(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new i(t.x,t.y,t.z,t.w)},i.packedLength=4,i.pack=function(t,r,n){return n=e(n,0),r[n++]=t.x,r[n++]=t.y,r[n++]=t.z,r[n]=t.w,r},i.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new i),a.x=t[n++],a.y=t[n++],a.z=t[n++],a.w=t[n],a},i.packArray=function(t,e){var n=t.length;r(e)?e.length=4*n:e=new Array(4*n);for(var a=0;a<n;++a)i.pack(t[a],e,4*a);return e},i.unpackArray=function(t,e){var n=t.length;r(e)?e.length=n/4:e=new Array(n/4);for(var a=0;a<n;a+=4){var o=a/4;e[o]=i.unpack(t,a,e[o])}return e},i.fromArray=i.unpack,i.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},i.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},i.minimumByComponent=function(t,e,r){return r.x=Math.min(t.x,e.x),r.y=Math.min(t.y,e.y),r.z=Math.min(t.z,e.z),r.w=Math.min(t.w,e.w),r},i.maximumByComponent=function(t,e,r){return r.x=Math.max(t.x,e.x),r.y=Math.max(t.y,e.y),r.z=Math.max(t.z,e.z),r.w=Math.max(t.w,e.w),r},i.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},i.magnitude=function(t){return Math.sqrt(i.magnitudeSquared(t))};var u=new i;i.distance=function(t,e){return i.subtract(t,e,u),i.magnitude(u)},i.distanceSquared=function(t,e){return i.subtract(t,e,u),i.magnitudeSquared(u)},i.normalize=function(t,e){var r=i.magnitude(t);return e.x=t.x/r,e.y=t.y/r,e.z=t.z/r,e.w=t.w/r,e},i.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},i.multiplyComponents=function(t,e,r){return r.x=t.x*e.x,r.y=t.y*e.y,r.z=t.z*e.z,r.w=t.w*e.w,r},i.divideComponents=function(t,e,r){return r.x=t.x/e.x,r.y=t.y/e.y,r.z=t.z/e.z,r.w=t.w/e.w,r},i.add=function(t,e,r){return r.x=t.x+e.x,r.y=t.y+e.y,r.z=t.z+e.z,r.w=t.w+e.w,r},i.subtract=function(t,e,r){return r.x=t.x-e.x,r.y=t.y-e.y,r.z=t.z-e.z,r.w=t.w-e.w,r},i.multiplyByScalar=function(t,e,r){return r.x=t.x*e,r.y=t.y*e,r.z=t.z*e,r.w=t.w*e,r},i.divideByScalar=function(t,e,r){return r.x=t.x/e,r.y=t.y/e,r.z=t.z/e,r.w=t.w/e,r},i.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},i.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var s=new i;i.lerp=function(t,e,r,n){return i.multiplyByScalar(e,r,s),n=i.multiplyByScalar(t,1-r,n),i.add(s,n,n)};var E=new i;return i.mostOrthogonalAxis=function(t,e){var r=i.normalize(t,E);return i.abs(r,r),e=r.x<=r.y?r.x<=r.z?r.x<=r.w?i.clone(i.UNIT_X,e):i.clone(i.UNIT_W,e):r.z<=r.w?i.clone(i.UNIT_Z,e):i.clone(i.UNIT_W,e):r.y<=r.z?r.y<=r.w?i.clone(i.UNIT_Y,e):i.clone(i.UNIT_W,e):r.z<=r.w?i.clone(i.UNIT_Z,e):i.clone(i.UNIT_W,e)},i.equals=function(t,e){return t===e||r(t)&&r(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},i.equalsArray=function(t,e,r){return t.x===e[r]&&t.y===e[r+1]&&t.z===e[r+2]&&t.w===e[r+3]},i.equalsEpsilon=function(t,e,n,a){return t===e||r(t)&&r(e)&&o.equalsEpsilon(t.x,e.x,n,a)&&o.equalsEpsilon(t.y,e.y,n,a)&&o.equalsEpsilon(t.z,e.z,n,a)&&o.equalsEpsilon(t.w,e.w,n,a)},i.ZERO=a(new i(0,0,0,0)),i.UNIT_X=a(new i(1,0,0,0)),i.UNIT_Y=a(new i(0,1,0,0)),i.UNIT_Z=a(new i(0,0,1,0)),i.UNIT_W=a(new i(0,0,0,1)),i.prototype.clone=function(t){return i.clone(this,t)},i.prototype.equals=function(t){return i.equals(this,t)},i.prototype.equalsEpsilon=function(t,e,r){return i.equalsEpsilon(this,t,e,r)},i.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},i}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,r,n,a,o,i,u,s,E){"use strict";function l(t,e,r,a,o,i,u,s,E,l,c,f,_,R,T,h){this[0]=n(t,0),this[1]=n(o,0),this[2]=n(E,0),this[3]=n(_,0),this[4]=n(e,0),this[5]=n(i,0),this[6]=n(l,0),this[7]=n(R,0),this[8]=n(r,0),this[9]=n(u,0),this[10]=n(c,0),this[11]=n(T,0),this[12]=n(a,0),this[13]=n(s,0),this[14]=n(f,0),this[15]=n(h,0)}l.packedLength=16,l.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e[r++]=t[9],e[r++]=t[10],e[r++]=t[11],e[r++]=t[12],e[r++]=t[13],e[r++]=t[14],e[r]=t[15],e},l.unpack=function(t,e,r){return e=n(e,0),a(r)||(r=new l),r[0]=t[e++],r[1]=t[e++],r[2]=t[e++],r[3]=t[e++],r[4]=t[e++],r[5]=t[e++],r[6]=t[e++],r[7]=t[e++],r[8]=t[e++],r[9]=t[e++],r[10]=t[e++],r[11]=t[e++],r[12]=t[e++],r[13]=t[e++],r[14]=t[e++],r[15]=t[e],r},l.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new l(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(t,e){return l.clone(t,e)},l.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new l(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},l.fromRotationTranslation=function(e,r,o){return r=n(r,t.ZERO),a(o)?(o[0]=e[0],o[1]=e[1],o[2]=e[2],o[3]=0,o[4]=e[3],o[5]=e[4],o[6]=e[5],o[7]=0,o[8]=e[6],o[9]=e[7],o[10]=e[8],o[11]=0,o[12]=r.x,o[13]=r.y,o[14]=r.z,o[15]=1,o):new l(e[0],e[3],e[6],r.x,e[1],e[4],e[7],r.y,e[2],e[5],e[8],r.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(t,e,r,n){a(n)||(n=new l);var o=r.x,i=r.y,u=r.z,s=e.x*e.x,E=e.x*e.y,c=e.x*e.z,f=e.x*e.w,_=e.y*e.y,R=e.y*e.z,T=e.y*e.w,h=e.z*e.z,A=e.z*e.w,d=e.w*e.w,S=s-_-h+d,m=2*(E-A),C=2*(c+T),N=2*(E+A),I=-s+_-h+d,M=2*(R-f),p=2*(c-T),O=2*(R+f),g=-s-_+h+d;return n[0]=S*o,n[1]=N*o,n[2]=p*o,n[3]=0,n[4]=m*i,n[5]=I*i,n[6]=O*i,n[7]=0,n[8]=C*u,n[9]=M*u,n[10]=g*u,n[11]=0,n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=1,n},l.fromTranslationRotationScale=function(t,e){return l.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},l.fromTranslation=function(t,e){return l.fromRotationTranslation(s.IDENTITY,t,e)},l.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new l(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},l.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new l(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var c=new t,f=new t,_=new t;l.fromCamera=function(e,r){var n=e.position,o=e.direction,i=e.up;t.normalize(o,c),t.normalize(t.cross(c,i,f),f),t.normalize(t.cross(f,c,_),_);var u=f.x,s=f.y,E=f.z,R=c.x,T=c.y,h=c.z,A=_.x,d=_.y,S=_.z,m=n.x,C=n.y,N=n.z,I=u*-m+s*-C+E*-N,M=A*-m+d*-C+S*-N,p=R*m+T*C+h*N;return a(r)?(r[0]=u,r[1]=A,r[2]=-R,r[3]=0,r[4]=s,r[5]=d,r[6]=-T,r[7]=0,r[8]=E,r[9]=S,r[10]=-h,r[11]=0,r[12]=I,r[13]=M,r[14]=p,r[15]=1,r):new l(u,s,E,I,A,d,S,M,-R,-T,-h,p,0,0,0,1)},l.computePerspectiveFieldOfView=function(t,e,r,n,a){var o=Math.tan(.5*t),i=1/o,u=i/e,s=(n+r)/(r-n),E=2*n*r/(r-n);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=i,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=E,a[15]=0,a},l.computeOrthographicOffCenter=function(t,e,r,n,a,o,i){var u=1/(e-t),s=1/(n-r),E=1/(o-a),l=-(e+t)*u,c=-(n+r)*s,f=-(o+a)*E;return u*=2,s*=2,E*=-2,i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=l,i[13]=c,i[14]=f,i[15]=1,i},l.computePerspectiveOffCenter=function(t,e,r,n,a,o,i){var u=2*a/(e-t),s=2*a/(n-r),E=(e+t)/(e-t),l=(n+r)/(n-r),c=-(o+a)/(o-a),f=-2*o*a/(o-a);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=s,i[6]=0,i[7]=0,i[8]=E,i[9]=l,i[10]=c,i[11]=-1,i[12]=0,i[13]=0,i[14]=f,i[15]=0,i},l.computeInfinitePerspectiveOffCenter=function(t,e,r,n,a,o){var i=2*a/(e-t),u=2*a/(n-r),s=(e+t)/(e-t),E=(n+r)/(n-r),l=-2*a;return o[0]=i,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=u,o[6]=0,o[7]=0,o[8]=s,o[9]=E,o[10]=-1,o[11]=-1,o[12]=0,o[13]=0,o[14]=l,o[15]=0,o},l.computeViewportTransformation=function(t,e,r,a){t=n(t,n.EMPTY_OBJECT);var o=n(t.x,0),i=n(t.y,0),u=n(t.width,0),s=n(t.height,0);e=n(e,0),r=n(r,1);var E=.5*u,l=.5*s,c=.5*(r-e),f=E,_=l,R=c,T=o+E,h=i+l,A=e+c;return a[0]=f,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=_,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=T,a[13]=h,a[14]=A,a[15]=1,a},l.computeView=function(e,r,n,a,o){return o[0]=a.x,o[1]=n.x,o[2]=-r.x,o[3]=0,o[4]=a.y,o[5]=n.y,o[6]=-r.y,o[7]=0,o[8]=a.z,o[9]=n.z,o[10]=-r.z,o[11]=0,o[12]=-t.dot(a,e),o[13]=-t.dot(n,e),o[14]=t.dot(r,e),o[15]=1,o},l.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},l.getElementIndex=function(t,e){return 4*t+e},l.getColumn=function(t,e,r){var n=4*e,a=t[n],o=t[n+1],i=t[n+2],u=t[n+3];return r.x=a,r.y=o,r.z=i,r.w=u,r},l.setColumn=function(t,e,r,n){n=l.clone(t,n);var a=4*e;return n[a]=r.x,n[a+1]=r.y,n[a+2]=r.z,n[a+3]=r.w,n},l.setTranslation=function(t,e,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=t[15],r},l.getRow=function(t,e,r){var n=t[e],a=t[e+4],o=t[e+8],i=t[e+12];return r.x=n,r.y=a,r.z=o,r.w=i,r},l.setRow=function(t,e,r,n){return n=l.clone(t,n),n[e]=r.x,n[e+4]=r.y,n[e+8]=r.z,n[e+12]=r.w,n};var R=new t;l.getScale=function(e,r){return r.x=t.magnitude(t.fromElements(e[0],e[1],e[2],R)),r.y=t.magnitude(t.fromElements(e[4],e[5],e[6],R)),r.z=t.magnitude(t.fromElements(e[8],e[9],e[10],R)),r};var T=new t;l.getMaximumScale=function(e){return l.getScale(e,T),t.maximumComponent(T)},l.multiply=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[3],u=t[4],s=t[5],E=t[6],l=t[7],c=t[8],f=t[9],_=t[10],R=t[11],T=t[12],h=t[13],A=t[14],d=t[15],S=e[0],m=e[1],C=e[2],N=e[3],I=e[4],M=e[5],p=e[6],O=e[7],g=e[8],y=e[9],F=e[10],L=e[11],v=e[12],U=e[13],P=e[14],D=e[15],B=n*S+u*m+c*C+T*N,w=a*S+s*m+f*C+h*N,x=o*S+E*m+_*C+A*N,G=i*S+l*m+R*C+d*N,b=n*I+u*M+c*p+T*O,z=a*I+s*M+f*p+h*O,H=o*I+E*M+_*p+A*O,V=i*I+l*M+R*p+d*O,X=n*g+u*y+c*F+T*L,q=a*g+s*y+f*F+h*L,W=o*g+E*y+_*F+A*L,Y=i*g+l*y+R*F+d*L,K=n*v+u*U+c*P+T*D,k=a*v+s*U+f*P+h*D,Z=o*v+E*U+_*P+A*D,j=i*v+l*U+R*P+d*D;return r[0]=B,r[1]=w,r[2]=x,r[3]=G,r[4]=b,r[5]=z,r[6]=H,r[7]=V,r[8]=X,r[9]=q,r[10]=W,r[11]=Y,r[12]=K,r[13]=k,r[14]=Z,r[15]=j,r},l.add=function(t,e,r){return r[0]=t[0]+e[0],r[1]=t[1]+e[1],r[2]=t[2]+e[2],r[3]=t[3]+e[3],r[4]=t[4]+e[4],r[5]=t[5]+e[5],r[6]=t[6]+e[6],r[7]=t[7]+e[7],r[8]=t[8]+e[8],r[9]=t[9]+e[9],r[10]=t[10]+e[10],r[11]=t[11]+e[11],r[12]=t[12]+e[12],r[13]=t[13]+e[13],r[14]=t[14]+e[14],r[15]=t[15]+e[15],r},l.subtract=function(t,e,r){return r[0]=t[0]-e[0],r[1]=t[1]-e[1],r[2]=t[2]-e[2],r[3]=t[3]-e[3],r[4]=t[4]-e[4],r[5]=t[5]-e[5],r[6]=t[6]-e[6],r[7]=t[7]-e[7],r[8]=t[8]-e[8],r[9]=t[9]-e[9],r[10]=t[10]-e[10],r[11]=t[11]-e[11],r[12]=t[12]-e[12],r[13]=t[13]-e[13],r[14]=t[14]-e[14],r[15]=t[15]-e[15],r},l.multiplyTransformation=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[4],u=t[5],s=t[6],E=t[8],l=t[9],c=t[10],f=t[12],_=t[13],R=t[14],T=e[0],h=e[1],A=e[2],d=e[4],S=e[5],m=e[6],C=e[8],N=e[9],I=e[10],M=e[12],p=e[13],O=e[14],g=n*T+i*h+E*A,y=a*T+u*h+l*A,F=o*T+s*h+c*A,L=n*d+i*S+E*m,v=a*d+u*S+l*m,U=o*d+s*S+c*m,P=n*C+i*N+E*I,D=a*C+u*N+l*I,B=o*C+s*N+c*I,w=n*M+i*p+E*O+f,x=a*M+u*p+l*O+_,G=o*M+s*p+c*O+R;return r[0]=g,r[1]=y,r[2]=F,r[3]=0,r[4]=L,r[5]=v,r[6]=U,r[7]=0,r[8]=P,r[9]=D,r[10]=B,r[11]=0,r[12]=w,r[13]=x,r[14]=G,r[15]=1,r},l.multiplyByMatrix3=function(t,e,r){var n=t[0],a=t[1],o=t[2],i=t[4],u=t[5],s=t[6],E=t[8],l=t[9],c=t[10],f=e[0],_=e[1],R=e[2],T=e[3],h=e[4],A=e[5],d=e[6],S=e[7],m=e[8],C=n*f+i*_+E*R,N=a*f+u*_+l*R,I=o*f+s*_+c*R,M=n*T+i*h+E*A,p=a*T+u*h+l*A,O=o*T+s*h+c*A,g=n*d+i*S+E*m,y=a*d+u*S+l*m,F=o*d+s*S+c*m;return r[0]=C,r[1]=N,r[2]=I,r[3]=0,r[4]=M,r[5]=p,r[6]=O,r[7]=0,r[8]=g,r[9]=y,r[10]=F,r[11]=0,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15],r},l.multiplyByTranslation=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=n*t[0]+a*t[4]+o*t[8]+t[12],u=n*t[1]+a*t[5]+o*t[9]+t[13],s=n*t[2]+a*t[6]+o*t[10]+t[14];return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=i,r[13]=u,r[14]=s,r[15]=t[15],r};var h=new t;l.multiplyByUniformScale=function(t,e,r){return h.x=e,h.y=e,h.z=e,l.multiplyByScale(t,h,r)},l.multiplyByScale=function(t,e,r){var n=e.x,a=e.y,o=e.z;return 1===n&&1===a&&1===o?l.clone(t,r):(r[0]=n*t[0],r[1]=n*t[1],r[2]=n*t[2],r[3]=0,r[4]=a*t[4],r[5]=a*t[5],r[6]=a*t[6],r[7]=0,r[8]=o*t[8],r[9]=o*t[9],r[10]=o*t[10],r[11]=0,r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=1,r)},l.multiplyByVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=e.w,u=t[0]*n+t[4]*a+t[8]*o+t[12]*i,s=t[1]*n+t[5]*a+t[9]*o+t[13]*i,E=t[2]*n+t[6]*a+t[10]*o+t[14]*i,l=t[3]*n+t[7]*a+t[11]*o+t[15]*i;return r.x=u,r.y=s,r.z=E,r.w=l,r},l.multiplyByPointAsVector=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[4]*a+t[8]*o,u=t[1]*n+t[5]*a+t[9]*o,s=t[2]*n+t[6]*a+t[10]*o;return r.x=i,r.y=u,r.z=s,r},l.multiplyByPoint=function(t,e,r){var n=e.x,a=e.y,o=e.z,i=t[0]*n+t[4]*a+t[8]*o+t[12],u=t[1]*n+t[5]*a+t[9]*o+t[13],s=t[2]*n+t[6]*a+t[10]*o+t[14];return r.x=i,r.y=u,r.z=s,r},l.multiplyByScalar=function(t,e,r){return r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e,r[3]=t[3]*e,r[4]=t[4]*e,r[5]=t[5]*e,r[6]=t[6]*e,r[7]=t[7]*e,r[8]=t[8]*e,r[9]=t[9]*e,r[10]=t[10]*e,r[11]=t[11]*e,r[12]=t[12]*e,r[13]=t[13]*e,r[14]=t[14]*e,r[15]=t[15]*e,r},l.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},l.transpose=function(t,e){var r=t[1],n=t[2],a=t[3],o=t[6],i=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=r,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=n,e[9]=o,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=i,e[14]=u,e[15]=t[15],e},l.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},l.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},l.equalsEpsilon=function(t,e,r){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=r&&Math.abs(t[1]-e[1])<=r&&Math.abs(t[2]-e[2])<=r&&Math.abs(t[3]-e[3])<=r&&Math.abs(t[4]-e[4])<=r&&Math.abs(t[5]-e[5])<=r&&Math.abs(t[6]-e[6])<=r&&Math.abs(t[7]-e[7])<=r&&Math.abs(t[8]-e[8])<=r&&Math.abs(t[9]-e[9])<=r&&Math.abs(t[10]-e[10])<=r&&Math.abs(t[11]-e[11])<=r&&Math.abs(t[12]-e[12])<=r&&Math.abs(t[13]-e[13])<=r&&Math.abs(t[14]-e[14])<=r&&Math.abs(t[15]-e[15])<=r},l.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},l.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var A=new s,d=new s,S=new e,m=new e(0,0,0,1);return l.inverse=function(t,r){if(s.equalsEpsilon(l.getRotation(t,A),d,u.EPSILON7)&&e.equals(l.getRow(t,3,S),m))return r[0]=0,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=0,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=0,r[11]=0,r[12]=-t[12],r[13]=-t[13],r[14]=-t[14],r[15]=1,r;var n=t[0],a=t[4],o=t[8],i=t[12],c=t[1],f=t[5],_=t[9],R=t[13],T=t[2],h=t[6],C=t[10],N=t[14],I=t[3],M=t[7],p=t[11],O=t[15],g=C*O,y=N*p,F=h*O,L=N*M,v=h*p,U=C*M,P=T*O,D=N*I,B=T*p,w=C*I,x=T*M,G=h*I,b=g*f+L*_+v*R-(y*f+F*_+U*R),z=y*c+P*_+w*R-(g*c+D*_+B*R),H=F*c+D*f+x*R-(L*c+P*f+G*R),V=U*c+B*f+G*_-(v*c+w*f+x*_),X=y*a+F*o+U*i-(g*a+L*o+v*i),q=g*n+D*o+B*i-(y*n+P*o+w*i),W=L*n+P*a+G*i-(F*n+D*a+x*i),Y=v*n+w*a+x*o-(U*n+B*a+G*o);g=o*R,y=i*_,F=a*R,L=i*f,v=a*_,U=o*f,P=n*R,D=i*c,B=n*_,w=o*c,x=n*f,G=a*c;var K=g*M+L*p+v*O-(y*M+F*p+U*O),k=y*I+P*p+w*O-(g*I+D*p+B*O),Z=F*I+D*M+x*O-(L*I+P*M+G*O),j=U*I+B*M+G*p-(v*I+w*M+x*p),Q=F*C+U*N+y*h-(v*N+g*h+L*C),J=B*N+g*T+D*C-(P*C+w*N+y*T),$=P*h+G*N+L*T-(x*N+F*T+D*h),tt=x*C+v*T+w*h-(B*h+G*C+U*T),et=n*b+a*z+o*H+i*V;if(Math.abs(et)<u.EPSILON20)throw new E("matrix is not invertible because its determinate is zero.");return et=1/et,r[0]=b*et,r[1]=z*et,r[2]=H*et,r[3]=V*et,r[4]=X*et,r[5]=q*et,r[6]=W*et,r[7]=Y*et,r[8]=K*et,r[9]=k*et,r[10]=Z*et,r[11]=j*et,r[12]=Q*et,r[13]=J*et,r[14]=$*et,r[15]=tt*et,r},l.inverseTransformation=function(t,e){var r=t[0],n=t[1],a=t[2],o=t[4],i=t[5],u=t[6],s=t[8],E=t[9],l=t[10],c=t[12],f=t[13],_=t[14],R=-r*c-n*f-a*_,T=-o*c-i*f-u*_,h=-s*c-E*f-l*_;return e[0]=r,e[1]=o,e[2]=s,e[3]=0,e[4]=n,e[5]=i,e[6]=E,e[7]=0,e[8]=a,e[9]=u,e[10]=l,e[11]=0,e[12]=R,e[13]=T,e[14]=h,e[15]=1,e},l.IDENTITY=i(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=i(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,o(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(t){return l.clone(this,t)},l.prototype.equals=function(t){return l.equals(this,t)},l.equalsArray=function(t,e,r){return t[0]===e[r]&&t[1]===e[r+1]&&t[2]===e[r+2]&&t[3]===e[r+3]&&t[4]===e[r+4]&&t[5]===e[r+5]&&t[6]===e[r+6]&&t[7]===e[r+7]&&t[8]===e[r+8]&&t[9]===e[r+9]&&t[10]===e[r+10]&&t[11]===e[r+11]&&t[12]===e[r+12]&&t[13]===e[r+13]&&t[14]===e[r+14]&&t[15]===e[r+15]},l.prototype.equalsEpsilon=function(t,e){return l.equalsEpsilon(this,t,e)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t,e,n,a){this.west=r(t,0),this.south=r(e,0),this.east=r(n,0),this.north=r(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(t,e,n){return n=r(n,0),e[n++]=t.west,e[n++]=t.south,e[n++]=t.east,e[n]=t.north,e},s.unpack=function(t,e,a){return e=r(e,0),n(a)||(a=new s),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},s.computeWidth=function(t){var e=t.east,r=t.west;return e<r&&(e+=u.TWO_PI),e-r},s.computeHeight=function(t){return t.north-t.south},s.fromDegrees=function(t,e,a,o,i){return t=u.toRadians(r(t,0)),e=u.toRadians(r(e,0)),a=u.toRadians(r(a,0)),o=u.toRadians(r(o,0)),n(i)?(i.west=t,i.south=e,i.east=a,i.north=o,i):new s(t,e,a,o)},s.fromRadians=function(t,e,a,o,i){return n(i)?(i.west=r(t,0),i.south=r(e,0),i.east=r(a,0),i.north=r(o,0),i):new s(t,e,a,o)},s.fromCartographicArray=function(t,e){for(var r=Number.MAX_VALUE,a=-Number.MAX_VALUE,o=Number.MAX_VALUE,i=-Number.MAX_VALUE,E=Number.MAX_VALUE,l=-Number.MAX_VALUE,c=0,f=t.length;c<f;c++){var _=t[c];r=Math.min(r,_.longitude),a=Math.max(a,_.longitude),E=Math.min(E,_.latitude),l=Math.max(l,_.latitude);var R=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;o=Math.min(o,R),i=Math.max(i,R)}return a-r>i-o&&(r=o,a=i,a>u.PI&&(a-=u.TWO_PI),r>u.PI&&(r-=u.TWO_PI)),n(e)?(e.west=r,e.south=E,e.east=a,e.north=l,e):new s(r,E,a,l)},s.fromCartesianArray=function(t,e,a){e=r(e,o.WGS84);for(var i=Number.MAX_VALUE,E=-Number.MAX_VALUE,l=Number.MAX_VALUE,c=-Number.MAX_VALUE,f=Number.MAX_VALUE,_=-Number.MAX_VALUE,R=0,T=t.length;R<T;R++){var h=e.cartesianToCartographic(t[R]);i=Math.min(i,h.longitude),E=Math.max(E,h.longitude),f=Math.min(f,h.latitude),_=Math.max(_,h.latitude);var A=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;l=Math.min(l,A),c=Math.max(c,A)}return E-i>c-l&&(i=l,E=c,E>u.PI&&(E-=u.TWO_PI),i>u.PI&&(i-=u.TWO_PI)),n(a)?(a.west=i,a.south=f,a.east=E,a.north=_,a):new s(i,f,E,_)},s.clone=function(t,e){if(n(t))return n(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new s(t.west,t.south,t.east,t.north)},s.prototype.clone=function(t){return s.clone(this,t)},s.prototype.equals=function(t){return s.equals(this,t)},s.equals=function(t,e){return t===e||n(t)&&n(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},s.prototype.equalsEpsilon=function(t,e){return n(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},s.validate=function(t){},s.southwest=function(e,r){return n(r)?(r.longitude=e.west,r.latitude=e.south,r.height=0,r):new t(e.west,e.south)},s.northwest=function(e,r){return n(r)?(r.longitude=e.west,r.latitude=e.north,r.height=0,r):new t(e.west,e.north)},s.northeast=function(e,r){return n(r)?(r.longitude=e.east,r.latitude=e.north,r.height=0,r):new t(e.east,e.north)},s.southeast=function(e,r){return n(r)?(r.longitude=e.east,r.latitude=e.south,r.height=0,r):new t(e.east,e.south)},s.center=function(e,r){var a=e.east,o=e.west;a<o&&(a+=u.TWO_PI);var i=u.negativePiToPi(.5*(o+a)),s=.5*(e.south+e.north);return n(r)?(r.longitude=i,r.latitude=s,r.height=0,r):new t(i,s)},s.intersection=function(t,e,r){var a=t.east,o=t.west,i=e.east,E=e.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var l=u.negativePiToPi(Math.max(o,E)),c=u.negativePiToPi(Math.min(a,i));if(!((t.west<t.east||e.west<e.east)&&c<=l)){var f=Math.max(t.south,e.south),_=Math.min(t.north,e.north);if(!(f>=_))return n(r)?(r.west=l,r.south=f,r.east=c,r.north=_,r):new s(l,f,c,_)}},s.simpleIntersection=function(t,e,r){var a=Math.max(t.west,e.west),o=Math.max(t.south,e.south),i=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(o>=u||a>=i))return n(r)?(r.west=a,r.south=o,r.east=i,r.north=u,r):new s(a,o,i,u)},s.union=function(t,e,r){n(r)||(r=new s);var a=t.east,o=t.west,i=e.east,E=e.west;a<o&&i>0?a+=u.TWO_PI:i<E&&a>0&&(i+=u.TWO_PI),a<o&&E<0?E+=u.TWO_PI:i<E&&o<0&&(o+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(o,E)),c=u.convertLongitudeRange(Math.max(a,i));return r.west=l,r.south=Math.min(t.south,e.south),r.east=c,r.north=Math.max(t.north,e.north),r},s.expand=function(t,e,r){return n(r)||(r=new s),r.west=Math.min(t.west,e.longitude),r.south=Math.min(t.south,e.latitude),r.east=Math.max(t.east,e.longitude),r.north=Math.max(t.north,e.latitude),r},s.contains=function(t,e){var r=e.longitude,n=e.latitude,a=t.west,o=t.east;return o<a&&(o+=u.TWO_PI,r<0&&(r+=u.TWO_PI)),(r>a||u.equalsEpsilon(r,a,u.EPSILON14))&&(r<o||u.equalsEpsilon(r,o,u.EPSILON14))&&n>=t.south&&n<=t.north};var E=new t;return s.subsample=function(t,e,a,i){e=r(e,o.WGS84),a=r(a,0),n(i)||(i=[]);var l=0,c=t.north,f=t.south,_=t.east,R=t.west,T=E;T.height=a,T.longitude=R,T.latitude=c,i[l]=e.cartographicToCartesian(T,i[l]),l++,T.longitude=_,i[l]=e.cartographicToCartesian(T,i[l]),l++,T.latitude=f,i[l]=e.cartographicToCartesian(T,i[l]),l++,T.longitude=R,i[l]=e.cartographicToCartesian(T,i[l]),l++,T.latitude=c<0?c:f>0?f:0;for(var h=1;h<8;++h)T.longitude=-Math.PI+h*u.PI_OVER_TWO,s.contains(t,T)&&(i[l]=e.cartographicToCartesian(T,i[l]),l++);return 0===T.latitude&&(T.longitude=R,i[l]=e.cartographicToCartesian(T,i[l]),l++,T.longitude=_,i[l]=e.cartographicToCartesian(T,i[l]),l++),i.length=l,i},s.MAX_VALUE=i(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,r,n,a,o,i,u,s,E,l,c,f){"use strict";function _(e,r){this.center=t.clone(a(e,t.ZERO)),this.radius=a(r,0)}var R=new t,T=new t,h=new t,A=new t,d=new t,S=new t,m=new t,C=new t,N=new t,I=new t,M=new t,p=new t,O=4/3*r.PI;_.fromPoints=function(e,r){if(o(r)||(r=new _),!o(e)||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var n,a=t.clone(e[0],m),i=t.clone(a,R),u=t.clone(a,T),s=t.clone(a,h),E=t.clone(a,A),l=t.clone(a,d),c=t.clone(a,S),f=e.length;for(n=1;n<f;n++){t.clone(e[n],a);var O=a.x,g=a.y,y=a.z;O<i.x&&t.clone(a,i),O>E.x&&t.clone(a,E),g<u.y&&t.clone(a,u),g>l.y&&t.clone(a,l),y<s.z&&t.clone(a,s),y>c.z&&t.clone(a,c)}var F=t.magnitudeSquared(t.subtract(E,i,C)),L=t.magnitudeSquared(t.subtract(l,u,C)),v=t.magnitudeSquared(t.subtract(c,s,C)),U=i,P=E,D=F;L>D&&(D=L,U=u,P=l),v>D&&(D=v,U=s,P=c);var B=N;B.x=.5*(U.x+P.x),B.y=.5*(U.y+P.y),B.z=.5*(U.z+P.z);var w=t.magnitudeSquared(t.subtract(P,B,C)),x=Math.sqrt(w),G=I;G.x=i.x,G.y=u.y,G.z=s.z;var b=M;b.x=E.x,b.y=l.y,b.z=c.z;var z=t.multiplyByScalar(t.add(G,b,C),.5,p),H=0;for(n=0;n<f;n++){t.clone(e[n],a);var V=t.magnitude(t.subtract(a,z,C));V>H&&(H=V);var X=t.magnitudeSquared(t.subtract(a,B,C));if(X>w){var q=Math.sqrt(X);x=.5*(x+q),w=x*x;var W=q-x;B.x=(x*B.x+W*a.x)/q,B.y=(x*B.y+W*a.y)/q,B.z=(x*B.z+W*a.z)/q}}return x<H?(t.clone(B,r.center),r.radius=x):(t.clone(z,r.center),r.radius=H),r};var g=new u,y=new t,F=new t,L=new e,v=new e;_.fromRectangle2D=function(t,e,r){return _.fromRectangleWithHeights2D(t,e,0,0,r)},_.fromRectangleWithHeights2D=function(e,r,n,i,u){if(o(u)||(u=new _),!o(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;r=a(r,g),f.southwest(e,L),L.height=n,f.northeast(e,v),v.height=i;var s=r.project(L,y),E=r.project(v,F),l=E.x-s.x,c=E.y-s.y,R=E.z-s.z;u.radius=.5*Math.sqrt(l*l+c*c+R*R);var T=u.center;return T.x=s.x+.5*l,T.y=s.y+.5*c,T.z=s.z+.5*R,u};var U=[];_.fromRectangle3D=function(e,r,n,u){if(r=a(r,i.WGS84),n=a(n,0),o(u)||(u=new _),!o(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var s=f.subsample(e,r,n,U);return _.fromPoints(s,u)},_.fromVertices=function(e,r,n,i){if(o(i)||(i=new _),!o(e)||0===e.length)return i.center=t.clone(t.ZERO,i.center),i.radius=0,i;r=a(r,t.ZERO),n=a(n,3);var u=m;u.x=e[0]+r.x,u.y=e[1]+r.y,u.z=e[2]+r.z;var s,E=t.clone(u,R),l=t.clone(u,T),c=t.clone(u,h),f=t.clone(u,A),O=t.clone(u,d),g=t.clone(u,S),y=e.length;for(s=0;s<y;s+=n){var F=e[s]+r.x,L=e[s+1]+r.y,v=e[s+2]+r.z;u.x=F,u.y=L,u.z=v,F<E.x&&t.clone(u,E),F>f.x&&t.clone(u,f),L<l.y&&t.clone(u,l),L>O.y&&t.clone(u,O),v<c.z&&t.clone(u,c),v>g.z&&t.clone(u,g)}var U=t.magnitudeSquared(t.subtract(f,E,C)),P=t.magnitudeSquared(t.subtract(O,l,C)),D=t.magnitudeSquared(t.subtract(g,c,C)),B=E,w=f,x=U;P>x&&(x=P,B=l,w=O),D>x&&(x=D,B=c,w=g);var G=N;G.x=.5*(B.x+w.x),G.y=.5*(B.y+w.y),G.z=.5*(B.z+w.z);var b=t.magnitudeSquared(t.subtract(w,G,C)),z=Math.sqrt(b),H=I;H.x=E.x,H.y=l.y,H.z=c.z;var V=M;V.x=f.x,V.y=O.y,V.z=g.z;var X=t.multiplyByScalar(t.add(H,V,C),.5,p),q=0;for(s=0;s<y;s+=n){u.x=e[s]+r.x,u.y=e[s+1]+r.y,u.z=e[s+2]+r.z;var W=t.magnitude(t.subtract(u,X,C));W>q&&(q=W);var Y=t.magnitudeSquared(t.subtract(u,G,C));if(Y>b){var K=Math.sqrt(Y);z=.5*(z+K),b=z*z;var k=K-z;G.x=(z*G.x+k*u.x)/K,G.y=(z*G.y+k*u.y)/K,G.z=(z*G.z+k*u.z)/K}}return z<q?(t.clone(G,i.center),i.radius=z):(t.clone(X,i.center),i.radius=q),i},_.fromEncodedCartesianVertices=function(e,r,n){if(o(n)||(n=new _),!o(e)||!o(r)||e.length!==r.length||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var a=m;a.x=e[0]+r[0],a.y=e[1]+r[1],a.z=e[2]+r[2];var i,u=t.clone(a,R),s=t.clone(a,T),E=t.clone(a,h),l=t.clone(a,A),c=t.clone(a,d),f=t.clone(a,S),O=e.length;for(i=0;i<O;i+=3){var g=e[i]+r[i],y=e[i+1]+r[i+1],F=e[i+2]+r[i+2];a.x=g,a.y=y,a.z=F,g<u.x&&t.clone(a,u),g>l.x&&t.clone(a,l),y<s.y&&t.clone(a,s),y>c.y&&t.clone(a,c),F<E.z&&t.clone(a,E),F>f.z&&t.clone(a,f)}var L=t.magnitudeSquared(t.subtract(l,u,C)),v=t.magnitudeSquared(t.subtract(c,s,C)),U=t.magnitudeSquared(t.subtract(f,E,C)),P=u,D=l,B=L;v>B&&(B=v,P=s,D=c),U>B&&(B=U,P=E,D=f);var w=N;w.x=.5*(P.x+D.x),w.y=.5*(P.y+D.y),w.z=.5*(P.z+D.z);var x=t.magnitudeSquared(t.subtract(D,w,C)),G=Math.sqrt(x),b=I;b.x=u.x,b.y=s.y,b.z=E.z;var z=M;z.x=l.x,z.y=c.y,z.z=f.z;var H=t.multiplyByScalar(t.add(b,z,C),.5,p),V=0;for(i=0;i<O;i+=3){a.x=e[i]+r[i],a.y=e[i+1]+r[i+1],a.z=e[i+2]+r[i+2];var X=t.magnitude(t.subtract(a,H,C));X>V&&(V=X);var q=t.magnitudeSquared(t.subtract(a,w,C));if(q>x){var W=Math.sqrt(q);G=.5*(G+W),x=G*G;var Y=W-G;w.x=(G*w.x+Y*a.x)/W,w.y=(G*w.y+Y*a.y)/W,w.z=(G*w.z+Y*a.z)/W}}return G<V?(t.clone(w,n.center),n.radius=G):(t.clone(H,n.center),n.radius=V),n},_.fromCornerPoints=function(e,r,n){o(n)||(n=new _);var a=n.center;return t.add(e,r,a),t.multiplyByScalar(a,.5,a),n.radius=t.distance(a,r),n},_.fromEllipsoid=function(e,r){return o(r)||(r=new _),t.clone(t.ZERO,r.center),r.radius=e.maximumRadius,r};var P=new t;_.fromBoundingSpheres=function(e,r){if(o(r)||(r=new _),!o(e)||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var n=e.length;if(1===n)return _.clone(e[0],r);if(2===n)return _.union(e[0],e[1],r);var a,i=[];for(a=0;a<n;a++)i.push(e[a].center);r=_.fromPoints(i,r);var u=r.center,s=r.radius;for(a=0;a<n;a++){var E=e[a];s=Math.max(s,t.distance(u,E.center,P)+E.radius)}return r.radius=s,r};var D=new t,B=new t,w=new t;_.fromOrientedBoundingBox=function(e,r){o(r)||(r=new _);var n=e.halfAxes,a=l.getColumn(n,0,D),i=l.getColumn(n,1,B),u=l.getColumn(n,2,w);return t.add(a,i,a),t.add(a,u,a),r.center=t.clone(e.center,r.center),r.radius=t.magnitude(a),r},_.clone=function(e,r){if(o(e))return o(r)?(r.center=t.clone(e.center,r.center),r.radius=e.radius,r):new _(e.center,e.radius)},_.packedLength=4,_.pack=function(t,e,r){r=a(r,0);var n=t.center;return e[r++]=n.x,e[r++]=n.y,e[r++]=n.z,e[r]=t.radius,e},_.unpack=function(t,e,r){e=a(e,0),o(r)||(r=new _);var n=r.center;return n.x=t[e++],n.y=t[e++],n.z=t[e++],r.radius=t[e],r};var x=new t,G=new t;_.union=function(e,r,n){o(n)||(n=new _);var a=e.center,i=e.radius,u=r.center,s=r.radius,E=t.subtract(u,a,x),l=t.magnitude(E);if(i>=l+s)return e.clone(n),n;if(s>=l+i)return r.clone(n),n;var c=.5*(i+l+s),f=t.multiplyByScalar(E,(-i+c)/l,G);return t.add(f,a,f),t.clone(f,n.center),n.radius=c,n};var b=new t;_.expand=function(e,r,n){n=_.clone(e,n);var a=t.magnitude(t.subtract(r,n.center,b));return a>n.radius&&(n.radius=a),n},_.intersectPlane=function(e,r){var n=e.center,a=e.radius,o=r.normal,i=t.dot(o,n)+r.distance;return i<-a?s.OUTSIDE:i<a?s.INTERSECTING:s.INSIDE},_.transform=function(t,e,r){return o(r)||(r=new _),r.center=c.multiplyByPoint(e,t.center,r.center),r.radius=c.getMaximumScale(e)*t.radius,r};var z=new t;_.distanceSquaredTo=function(e,r){var n=t.subtract(e.center,r,z);return t.magnitudeSquared(n)-e.radius*e.radius},_.transformWithoutScale=function(t,e,r){return o(r)||(r=new _),r.center=c.multiplyByPoint(e,t.center,r.center),r.radius=t.radius,r};var H=new t;_.computePlaneDistances=function(e,r,n,a){o(a)||(a=new E);var i=t.subtract(e.center,r,H),u=t.dot(n,i);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var V=new t,X=new t,q=new t,W=new t,Y=new t,K=new e,k=new Array(8),Z=0;Z<8;++Z)k[Z]=new t;var j=new u;return _.projectTo2D=function(e,r,n){r=a(r,j);var o=r.ellipsoid,i=e.center,u=e.radius,s=o.geodeticSurfaceNormal(i,V),E=t.cross(t.UNIT_Z,s,X);t.normalize(E,E);var l=t.cross(s,E,q);t.normalize(l,l),t.multiplyByScalar(s,u,s),t.multiplyByScalar(l,u,l),t.multiplyByScalar(E,u,E);var c=t.negate(l,Y),f=t.negate(E,W),R=k,T=R[0];t.add(s,l,T),t.add(T,E,T),T=R[1],t.add(s,l,T),t.add(T,f,T),T=R[2],t.add(s,c,T),t.add(T,f,T),T=R[3],t.add(s,c,T),t.add(T,E,T),t.negate(s,s),T=R[4],t.add(s,l,T),t.add(T,E,T),T=R[5],t.add(s,l,T),t.add(T,f,T),T=R[6],t.add(s,c,T),t.add(T,f,T),T=R[7],t.add(s,c,T),t.add(T,E,T);for(var h=R.length,A=0;A<h;++A){var d=R[A];t.add(i,d,d);var S=o.cartesianToCartographic(d,K);r.project(S,d)}n=_.fromPoints(R,n),i=n.center;var m=i.x,C=i.y,N=i.z;return i.x=N,i.y=m,i.z=C,n},_.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},_.equals=function(e,r){return e===r||o(e)&&o(r)&&t.equals(e.center,r.center)&&e.radius===r.radius},_.prototype.intersectPlane=function(t){return _.intersectPlane(this,t)},_.prototype.distanceSquaredTo=function(t){return _.distanceSquaredTo(this,t)},_.prototype.computePlaneDistances=function(t,e,r){return _.computePlaneDistances(this,t,e,r)},_.prototype.isOccluded=function(t){return _.isOccluded(this,t)},_.prototype.equals=function(t){return _.equals(this,t)},_.prototype.clone=function(t){return _.clone(this,t)},_.prototype.volume=function(){var t=this.radius;return O*t*t*t},_}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var r,n={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return n.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[n.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(r))return r;r=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return n.requestFullscreen="requestFullscreen",n.exitFullscreen="exitFullscreen",n.fullscreenEnabled="fullscreenEnabled",n.fullscreenElement="fullscreenElement",n.fullscreenchange="fullscreenchange",n.fullscreenerror="fullscreenerror",r=!0;for(var a,o=["webkit","moz","o","ms","khtml"],i=0,u=o.length;i<u;++i){var s=o[i];a=s+"RequestFullscreen","function"==typeof e[a]?(n.requestFullscreen=a,r=!0):(a=s+"RequestFullScreen","function"==typeof e[a]&&(n.requestFullscreen=a,r=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?n.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(n.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?n.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(n.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?n.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(n.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),n.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),n.fullscreenerror=a)}return r},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[n.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[n.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,r){"use strict";function n(t){for(var e=t.split("."),r=0,n=e.length;r<n;++r)e[r]=parseInt(e[r],10);return e}function a(){if(!e(C)&&(C=!1,!f())){var t=/ Chrome\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(C=!0,N=n(t[1]))}return C}function o(){return a()&&N}function i(){if(!e(I)&&(I=!1,!a()&&!f()&&/ Safari\/[\.0-9]+/.test(m.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(I=!0,M=n(t[1]))}return I}function u(){return i()&&M}function s(){if(!e(p)){p=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(m.userAgent);null!==t&&(p=!0, +O=n(t[1]),O.isNightly=!!t[2])}return p}function E(){return s()&&O}function l(){if(!e(g)){g=!1;var t;"Microsoft Internet Explorer"===m.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(t[1])):"Netscape"===m.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(m.userAgent))&&(g=!0,y=n(t[1]))}return g}function c(){return l()&&y}function f(){if(!e(F)){F=!1;var t=/ Edge\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(F=!0,L=n(t[1]))}return F}function _(){return f()&&L}function R(){if(!e(v)){v=!1;var t=/Firefox\/([\.0-9]+)/.exec(m.userAgent);null!==t&&(v=!0,U=n(t[1]))}return v}function T(){return e(P)||(P=/Windows/i.test(m.appVersion)),P}function h(){return R()&&U}function A(){return e(D)||(D="undefined"!=typeof PointerEvent&&(!e(m.pointerEnabled)||m.pointerEnabled)),D}function d(){if(!e(w)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var r=t.style.imageRendering;w=e(r)&&""!==r,w&&(B=r)}return w}function S(){return d()?B:void 0}var m;m="undefined"!=typeof navigator?navigator:{};var C,N,I,M,p,O,g,y,F,L,v,U,P,D,B,w,x={isChrome:a,chromeVersion:o,isSafari:i,safariVersion:u,isWebkit:s,webkitVersion:E,isInternetExplorer:l,internetExplorerVersion:c,isEdge:f,edgeVersion:_,isFirefox:R,firefoxVersion:h,isWindows:T,hardwareConcurrency:t(m.hardwareConcurrency,3),supportsPointerEvents:A,supportsImageRenderingPixelated:d,imageRenderingValue:S};return x.supportsFullscreen=function(){return r.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/Color",["./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math"],function(t,e,r,n,a,o){"use strict";function i(t,e,r){return r<0&&(r+=1),r>1&&(r-=1),6*r<1?t+6*(e-t)*r:2*r<1?e:3*r<2?t+(e-t)*(2/3-r)*6:t}function u(t,r,n,a){this.red=e(t,1),this.green=e(r,1),this.blue=e(n,1),this.alpha=e(a,1)}u.fromCartesian4=function(t,e){return r(e)?(e.red=t.x,e.green=t.y,e.blue=t.z,e.alpha=t.w,e):new u(t.x,t.y,t.z,t.w)},u.fromBytes=function(t,n,a,o,i){return t=u.byteToFloat(e(t,255)),n=u.byteToFloat(e(n,255)),a=u.byteToFloat(e(a,255)),o=u.byteToFloat(e(o,255)),r(i)?(i.red=t,i.green=n,i.blue=a,i.alpha=o,i):new u(t,n,a,o)},u.fromAlpha=function(t,e,n){return r(n)?(n.red=t.red,n.green=t.green,n.blue=t.blue,n.alpha=e,n):new u(t.red,t.green,t.blue,e)};var s,E,l;n.supportsTypedArrays()&&(s=new ArrayBuffer(4),E=new Uint32Array(s),l=new Uint8Array(s)),u.fromRgba=function(t,e){return E[0]=t,u.fromBytes(l[0],l[1],l[2],l[3],e)},u.fromHsl=function(t,n,a,o,s){t=e(t,0)%1,n=e(n,0),a=e(a,0),o=e(o,1);var E=a,l=a,c=a;if(0!==n){var f;f=a<.5?a*(1+n):a+n-a*n;var _=2*a-f;E=i(_,f,t+1/3),l=i(_,f,t),c=i(_,f,t-1/3)}return r(s)?(s.red=E,s.green=l,s.blue=c,s.alpha=o,s):new u(E,l,c,o)},u.fromRandom=function(t,n){t=e(t,e.EMPTY_OBJECT);var a=t.red;if(!r(a)){var i=e(t.minimumRed,0),s=e(t.maximumRed,1);a=i+o.nextRandomNumber()*(s-i)}var E=t.green;if(!r(E)){var l=e(t.minimumGreen,0),c=e(t.maximumGreen,1);E=l+o.nextRandomNumber()*(c-l)}var f=t.blue;if(!r(f)){var _=e(t.minimumBlue,0),R=e(t.maximumBlue,1);f=_+o.nextRandomNumber()*(R-_)}var T=t.alpha;if(!r(T)){var h=e(t.minimumAlpha,0),A=e(t.maximumAlpha,1);T=h+o.nextRandomNumber()*(A-h)}return r(n)?(n.red=a,n.green=E,n.blue=f,n.alpha=T,n):new u(a,E,f,T)};var c=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,f=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,_=/^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i,R=/^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i;return u.fromCssColorString=function(t,n){r(n)||(n=new u);var a=u[t.toUpperCase()];if(r(a))return u.clone(a,n),n;var o=c.exec(t);return null!==o?(n.red=parseInt(o[1],16)/15,n.green=parseInt(o[2],16)/15,n.blue=parseInt(o[3],16)/15,n.alpha=1,n):null!==(o=f.exec(t))?(n.red=parseInt(o[1],16)/255,n.green=parseInt(o[2],16)/255,n.blue=parseInt(o[3],16)/255,n.alpha=1,n):null!==(o=_.exec(t))?(n.red=parseFloat(o[1])/("%"===o[1].substr(-1)?100:255),n.green=parseFloat(o[2])/("%"===o[2].substr(-1)?100:255),n.blue=parseFloat(o[3])/("%"===o[3].substr(-1)?100:255),n.alpha=parseFloat(e(o[4],"1.0")),n):null!==(o=R.exec(t))?u.fromHsl(parseFloat(o[1])/360,parseFloat(o[2])/100,parseFloat(o[3])/100,parseFloat(e(o[4],"1.0")),n):n=void 0},u.packedLength=4,u.pack=function(t,r,n){return n=e(n,0),r[n++]=t.red,r[n++]=t.green,r[n++]=t.blue,r[n]=t.alpha,r},u.unpack=function(t,n,a){return n=e(n,0),r(a)||(a=new u),a.red=t[n++],a.green=t[n++],a.blue=t[n++],a.alpha=t[n],a},u.byteToFloat=function(t){return t/255},u.floatToByte=function(t){return 1===t?255:256*t|0},u.clone=function(t,e){if(r(t))return r(e)?(e.red=t.red,e.green=t.green,e.blue=t.blue,e.alpha=t.alpha,e):new u(t.red,t.green,t.blue,t.alpha)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.red===e.red&&t.green===e.green&&t.blue===e.blue&&t.alpha===e.alpha},u.equalsArray=function(t,e,r){return t.red===e[r]&&t.green===e[r+1]&&t.blue===e[r+2]&&t.alpha===e[r+3]},u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return this===t||r(t)&&Math.abs(this.red-t.red)<=e&&Math.abs(this.green-t.green)<=e&&Math.abs(this.blue-t.blue)<=e&&Math.abs(this.alpha-t.alpha)<=e},u.prototype.toString=function(){return"("+this.red+", "+this.green+", "+this.blue+", "+this.alpha+")"},u.prototype.toCssColorString=function(){var t=u.floatToByte(this.red),e=u.floatToByte(this.green),r=u.floatToByte(this.blue);return 1===this.alpha?"rgb("+t+","+e+","+r+")":"rgba("+t+","+e+","+r+","+this.alpha+")"},u.prototype.toBytes=function(t){var e=u.floatToByte(this.red),n=u.floatToByte(this.green),a=u.floatToByte(this.blue),o=u.floatToByte(this.alpha);return r(t)?(t[0]=e,t[1]=n,t[2]=a,t[3]=o,t):[e,n,a,o]},u.prototype.toRgba=function(){return l[0]=u.floatToByte(this.red),l[1]=u.floatToByte(this.green),l[2]=u.floatToByte(this.blue),l[3]=u.floatToByte(this.alpha),E[0]},u.prototype.brighten=function(t,e){return t=1-t,e.red=1-(1-this.red)*t,e.green=1-(1-this.green)*t,e.blue=1-(1-this.blue)*t,e.alpha=this.alpha,e},u.prototype.darken=function(t,e){return t=1-t,e.red=this.red*t,e.green=this.green*t,e.blue=this.blue*t,e.alpha=this.alpha,e},u.prototype.withAlpha=function(t,e){return u.fromAlpha(this,t,e)},u.add=function(t,e,r){return r.red=t.red+e.red,r.green=t.green+e.green,r.blue=t.blue+e.blue,r.alpha=t.alpha+e.alpha,r},u.subtract=function(t,e,r){return r.red=t.red-e.red,r.green=t.green-e.green,r.blue=t.blue-e.blue,r.alpha=t.alpha-e.alpha,r},u.multiply=function(t,e,r){return r.red=t.red*e.red,r.green=t.green*e.green,r.blue=t.blue*e.blue,r.alpha=t.alpha*e.alpha,r},u.divide=function(t,e,r){return r.red=t.red/e.red,r.green=t.green/e.green,r.blue=t.blue/e.blue,r.alpha=t.alpha/e.alpha,r},u.mod=function(t,e,r){return r.red=t.red%e.red,r.green=t.green%e.green,r.blue=t.blue%e.blue,r.alpha=t.alpha%e.alpha,r},u.multiplyByScalar=function(t,e,r){return r.red=t.red*e,r.green=t.green*e,r.blue=t.blue*e,r.alpha=t.alpha*e,r},u.divideByScalar=function(t,e,r){return r.red=t.red/e,r.green=t.green/e,r.blue=t.blue/e,r.alpha=t.alpha/e,r},u.ALICEBLUE=a(u.fromCssColorString("#F0F8FF")),u.ANTIQUEWHITE=a(u.fromCssColorString("#FAEBD7")),u.AQUA=a(u.fromCssColorString("#00FFFF")),u.AQUAMARINE=a(u.fromCssColorString("#7FFFD4")),u.AZURE=a(u.fromCssColorString("#F0FFFF")),u.BEIGE=a(u.fromCssColorString("#F5F5DC")),u.BISQUE=a(u.fromCssColorString("#FFE4C4")),u.BLACK=a(u.fromCssColorString("#000000")),u.BLANCHEDALMOND=a(u.fromCssColorString("#FFEBCD")),u.BLUE=a(u.fromCssColorString("#0000FF")),u.BLUEVIOLET=a(u.fromCssColorString("#8A2BE2")),u.BROWN=a(u.fromCssColorString("#A52A2A")),u.BURLYWOOD=a(u.fromCssColorString("#DEB887")),u.CADETBLUE=a(u.fromCssColorString("#5F9EA0")),u.CHARTREUSE=a(u.fromCssColorString("#7FFF00")),u.CHOCOLATE=a(u.fromCssColorString("#D2691E")),u.CORAL=a(u.fromCssColorString("#FF7F50")),u.CORNFLOWERBLUE=a(u.fromCssColorString("#6495ED")),u.CORNSILK=a(u.fromCssColorString("#FFF8DC")),u.CRIMSON=a(u.fromCssColorString("#DC143C")),u.CYAN=a(u.fromCssColorString("#00FFFF")),u.DARKBLUE=a(u.fromCssColorString("#00008B")),u.DARKCYAN=a(u.fromCssColorString("#008B8B")),u.DARKGOLDENROD=a(u.fromCssColorString("#B8860B")),u.DARKGRAY=a(u.fromCssColorString("#A9A9A9")),u.DARKGREEN=a(u.fromCssColorString("#006400")),u.DARKGREY=u.DARKGRAY,u.DARKKHAKI=a(u.fromCssColorString("#BDB76B")),u.DARKMAGENTA=a(u.fromCssColorString("#8B008B")),u.DARKOLIVEGREEN=a(u.fromCssColorString("#556B2F")),u.DARKORANGE=a(u.fromCssColorString("#FF8C00")),u.DARKORCHID=a(u.fromCssColorString("#9932CC")),u.DARKRED=a(u.fromCssColorString("#8B0000")),u.DARKSALMON=a(u.fromCssColorString("#E9967A")),u.DARKSEAGREEN=a(u.fromCssColorString("#8FBC8F")),u.DARKSLATEBLUE=a(u.fromCssColorString("#483D8B")),u.DARKSLATEGRAY=a(u.fromCssColorString("#2F4F4F")),u.DARKSLATEGREY=u.DARKSLATEGRAY,u.DARKTURQUOISE=a(u.fromCssColorString("#00CED1")),u.DARKVIOLET=a(u.fromCssColorString("#9400D3")),u.DEEPPINK=a(u.fromCssColorString("#FF1493")),u.DEEPSKYBLUE=a(u.fromCssColorString("#00BFFF")),u.DIMGRAY=a(u.fromCssColorString("#696969")),u.DIMGREY=u.DIMGRAY,u.DODGERBLUE=a(u.fromCssColorString("#1E90FF")),u.FIREBRICK=a(u.fromCssColorString("#B22222")),u.FLORALWHITE=a(u.fromCssColorString("#FFFAF0")),u.FORESTGREEN=a(u.fromCssColorString("#228B22")),u.FUCHSIA=a(u.fromCssColorString("#FF00FF")),u.GAINSBORO=a(u.fromCssColorString("#DCDCDC")),u.GHOSTWHITE=a(u.fromCssColorString("#F8F8FF")),u.GOLD=a(u.fromCssColorString("#FFD700")),u.GOLDENROD=a(u.fromCssColorString("#DAA520")),u.GRAY=a(u.fromCssColorString("#808080")),u.GREEN=a(u.fromCssColorString("#008000")),u.GREENYELLOW=a(u.fromCssColorString("#ADFF2F")),u.GREY=u.GRAY,u.HONEYDEW=a(u.fromCssColorString("#F0FFF0")),u.HOTPINK=a(u.fromCssColorString("#FF69B4")),u.INDIANRED=a(u.fromCssColorString("#CD5C5C")),u.INDIGO=a(u.fromCssColorString("#4B0082")),u.IVORY=a(u.fromCssColorString("#FFFFF0")),u.KHAKI=a(u.fromCssColorString("#F0E68C")),u.LAVENDER=a(u.fromCssColorString("#E6E6FA")),u.LAVENDAR_BLUSH=a(u.fromCssColorString("#FFF0F5")),u.LAWNGREEN=a(u.fromCssColorString("#7CFC00")),u.LEMONCHIFFON=a(u.fromCssColorString("#FFFACD")),u.LIGHTBLUE=a(u.fromCssColorString("#ADD8E6")),u.LIGHTCORAL=a(u.fromCssColorString("#F08080")),u.LIGHTCYAN=a(u.fromCssColorString("#E0FFFF")),u.LIGHTGOLDENRODYELLOW=a(u.fromCssColorString("#FAFAD2")),u.LIGHTGRAY=a(u.fromCssColorString("#D3D3D3")),u.LIGHTGREEN=a(u.fromCssColorString("#90EE90")),u.LIGHTGREY=u.LIGHTGRAY,u.LIGHTPINK=a(u.fromCssColorString("#FFB6C1")),u.LIGHTSEAGREEN=a(u.fromCssColorString("#20B2AA")),u.LIGHTSKYBLUE=a(u.fromCssColorString("#87CEFA")),u.LIGHTSLATEGRAY=a(u.fromCssColorString("#778899")),u.LIGHTSLATEGREY=u.LIGHTSLATEGRAY,u.LIGHTSTEELBLUE=a(u.fromCssColorString("#B0C4DE")),u.LIGHTYELLOW=a(u.fromCssColorString("#FFFFE0")),u.LIME=a(u.fromCssColorString("#00FF00")),u.LIMEGREEN=a(u.fromCssColorString("#32CD32")),u.LINEN=a(u.fromCssColorString("#FAF0E6")),u.MAGENTA=a(u.fromCssColorString("#FF00FF")),u.MAROON=a(u.fromCssColorString("#800000")),u.MEDIUMAQUAMARINE=a(u.fromCssColorString("#66CDAA")),u.MEDIUMBLUE=a(u.fromCssColorString("#0000CD")),u.MEDIUMORCHID=a(u.fromCssColorString("#BA55D3")),u.MEDIUMPURPLE=a(u.fromCssColorString("#9370DB")),u.MEDIUMSEAGREEN=a(u.fromCssColorString("#3CB371")),u.MEDIUMSLATEBLUE=a(u.fromCssColorString("#7B68EE")),u.MEDIUMSPRINGGREEN=a(u.fromCssColorString("#00FA9A")),u.MEDIUMTURQUOISE=a(u.fromCssColorString("#48D1CC")),u.MEDIUMVIOLETRED=a(u.fromCssColorString("#C71585")),u.MIDNIGHTBLUE=a(u.fromCssColorString("#191970")),u.MINTCREAM=a(u.fromCssColorString("#F5FFFA")),u.MISTYROSE=a(u.fromCssColorString("#FFE4E1")),u.MOCCASIN=a(u.fromCssColorString("#FFE4B5")),u.NAVAJOWHITE=a(u.fromCssColorString("#FFDEAD")),u.NAVY=a(u.fromCssColorString("#000080")),u.OLDLACE=a(u.fromCssColorString("#FDF5E6")),u.OLIVE=a(u.fromCssColorString("#808000")),u.OLIVEDRAB=a(u.fromCssColorString("#6B8E23")),u.ORANGE=a(u.fromCssColorString("#FFA500")),u.ORANGERED=a(u.fromCssColorString("#FF4500")),u.ORCHID=a(u.fromCssColorString("#DA70D6")),u.PALEGOLDENROD=a(u.fromCssColorString("#EEE8AA")),u.PALEGREEN=a(u.fromCssColorString("#98FB98")),u.PALETURQUOISE=a(u.fromCssColorString("#AFEEEE")),u.PALEVIOLETRED=a(u.fromCssColorString("#DB7093")),u.PAPAYAWHIP=a(u.fromCssColorString("#FFEFD5")),u.PEACHPUFF=a(u.fromCssColorString("#FFDAB9")),u.PERU=a(u.fromCssColorString("#CD853F")),u.PINK=a(u.fromCssColorString("#FFC0CB")),u.PLUM=a(u.fromCssColorString("#DDA0DD")),u.POWDERBLUE=a(u.fromCssColorString("#B0E0E6")),u.PURPLE=a(u.fromCssColorString("#800080")),u.RED=a(u.fromCssColorString("#FF0000")),u.ROSYBROWN=a(u.fromCssColorString("#BC8F8F")),u.ROYALBLUE=a(u.fromCssColorString("#4169E1")),u.SADDLEBROWN=a(u.fromCssColorString("#8B4513")),u.SALMON=a(u.fromCssColorString("#FA8072")),u.SANDYBROWN=a(u.fromCssColorString("#F4A460")),u.SEAGREEN=a(u.fromCssColorString("#2E8B57")),u.SEASHELL=a(u.fromCssColorString("#FFF5EE")),u.SIENNA=a(u.fromCssColorString("#A0522D")),u.SILVER=a(u.fromCssColorString("#C0C0C0")),u.SKYBLUE=a(u.fromCssColorString("#87CEEB")),u.SLATEBLUE=a(u.fromCssColorString("#6A5ACD")),u.SLATEGRAY=a(u.fromCssColorString("#708090")),u.SLATEGREY=u.SLATEGRAY,u.SNOW=a(u.fromCssColorString("#FFFAFA")),u.SPRINGGREEN=a(u.fromCssColorString("#00FF7F")),u.STEELBLUE=a(u.fromCssColorString("#4682B4")),u.TAN=a(u.fromCssColorString("#D2B48C")),u.TEAL=a(u.fromCssColorString("#008080")),u.THISTLE=a(u.fromCssColorString("#D8BFD8")),u.TOMATO=a(u.fromCssColorString("#FF6347")),u.TURQUOISE=a(u.fromCssColorString("#40E0D0")),u.VIOLET=a(u.fromCssColorString("#EE82EE")),u.WHEAT=a(u.fromCssColorString("#F5DEB3")),u.WHITE=a(u.fromCssColorString("#FFFFFF")),u.WHITESMOKE=a(u.fromCssColorString("#F5F5F5")),u.YELLOW=a(u.fromCssColorString("#FFFF00")),u.YELLOWGREEN=a(u.fromCssColorString("#9ACD32")),u.TRANSPARENT=a(new u(0,0,0,0)),u}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,r,n,a,o){"use strict";if(!n.supportsTypedArrays())return{};var i={BYTE:o.BYTE,UNSIGNED_BYTE:o.UNSIGNED_BYTE,SHORT:o.SHORT,UNSIGNED_SHORT:o.UNSIGNED_SHORT,INT:o.INT,UNSIGNED_INT:o.UNSIGNED_INT,FLOAT:o.FLOAT,DOUBLE:o.DOUBLE};return i.getSizeInBytes=function(t){switch(t){case i.BYTE:return Int8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.SHORT:return Int16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.INT:return Int32Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case i.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case i.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},i.fromTypedArray=function(t){return t instanceof Int8Array?i.BYTE:t instanceof Uint8Array?i.UNSIGNED_BYTE:t instanceof Int16Array?i.SHORT:t instanceof Uint16Array?i.UNSIGNED_SHORT:t instanceof Int32Array?i.INT:t instanceof Uint32Array?i.UNSIGNED_INT:t instanceof Float32Array?i.FLOAT:t instanceof Float64Array?i.DOUBLE:void 0},i.validate=function(t){return e(t)&&(t===i.BYTE||t===i.UNSIGNED_BYTE||t===i.SHORT||t===i.UNSIGNED_SHORT||t===i.INT||t===i.UNSIGNED_INT||t===i.FLOAT||t===i.DOUBLE)},i.createTypedArray=function(t,e){switch(t){case i.BYTE:return new Int8Array(e);case i.UNSIGNED_BYTE:return new Uint8Array(e);case i.SHORT:return new Int16Array(e);case i.UNSIGNED_SHORT:return new Uint16Array(e);case i.INT:return new Int32Array(e);case i.UNSIGNED_INT:return new Uint32Array(e);case i.FLOAT:return new Float32Array(e);case i.DOUBLE:return new Float64Array(e)}},i.createArrayBufferView=function(e,r,n,a){switch(n=t(n,0),a=t(a,(r.byteLength-n)/i.getSizeInBytes(e)),e){case i.BYTE:return new Int8Array(r,n,a);case i.UNSIGNED_BYTE:return new Uint8Array(r,n,a);case i.SHORT:return new Int16Array(r,n,a);case i.UNSIGNED_SHORT:return new Uint16Array(r,n,a);case i.INT:return new Int32Array(r,n,a);case i.UNSIGNED_INT:return new Uint32Array(r,n,a);case i.FLOAT:return new Float32Array(r,n,a);case i.DOUBLE:return new Float64Array(r,n,a)}},i.fromName=function(t){switch(t){case"BYTE":return i.BYTE;case"UNSIGNED_BYTE":return i.UNSIGNED_BYTE;case"SHORT":return i.SHORT;case"UNSIGNED_SHORT":return i.UNSIGNED_SHORT;case"INT":return i.INT;case"UNSIGNED_INT":return i.UNSIGNED_INT;case"FLOAT":return i.FLOAT;case"DOUBLE":return i.DOUBLE}},a(i)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var r={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===r.POINTS||t===r.LINES||t===r.LINE_LOOP||t===r.LINE_STRIP||t===r.TRIANGLES||t===r.TRIANGLE_STRIP||t===r.TRIANGLE_FAN}};return t(r)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,r,n,a,o){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,o.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return i.computeNumberOfVertices=function(t){var e=-1;for(var n in t.attributes)if(t.attributes.hasOwnProperty(n)&&r(t.attributes[n])&&r(t.attributes[n].values)){var a=t.attributes[n],o=a.values.length/a.componentsPerAttribute;e=o}return e},i}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,r){"use strict";function n(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return n}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,r,n,a){"use strict";var o={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return o.getSizeInBytes=function(t){switch(t){case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT} +},o.validate=function(e){return t(e)&&(e===o.UNSIGNED_BYTE||e===o.UNSIGNED_SHORT||e===o.UNSIGNED_INT)},o.createTypedArray=function(t,e){return t>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},o.createTypedArrayFromArrayBuffer=function(t,e,r,a){return t>=n.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,r,a):new Uint16Array(e,r,a)},r(o)}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(t,e,r,n,a,o,i,u){"use strict";function s(t){var e=t._uSquared,r=t._ellipsoid.maximumRadius,n=t._ellipsoid.minimumRadius,a=(r-n)/r,o=Math.cos(t._startHeading),i=Math.sin(t._startHeading),u=(1-a)*Math.tan(t._start.latitude),s=1/Math.sqrt(1+u*u),E=s*u,l=Math.atan2(u,o),c=s*i,f=c*c,_=1-f,R=Math.sqrt(_),T=e/4,h=T*T,A=h*T,d=h*h,S=1+T-3*h/4+5*A/4-175*d/64,m=1-T+15*h/8-35*A/8,C=1-3*T+35*h/4,N=1-5*T,I=S*l-m*Math.sin(2*l)*T/2-C*Math.sin(4*l)*h/16-N*Math.sin(6*l)*A/48-5*Math.sin(8*l)*d/512,M=t._constants;M.a=r,M.b=n,M.f=a,M.cosineHeading=o,M.sineHeading=i,M.tanU=u,M.cosineU=s,M.sineU=E,M.sigma=l,M.sineAlpha=c,M.sineSquaredAlpha=f,M.cosineSquaredAlpha=_,M.cosineAlpha=R,M.u2Over4=T,M.u4Over16=h,M.u6Over64=A,M.u8Over256=d,M.a0=S,M.a1=m,M.a2=C,M.a3=N,M.distanceRatio=I}function E(t,e){return t*e*(4+t*(4-3*e))/16}function l(t,e,r,n,a,o,i){var u=E(t,r);return(1-u)*t*e*(n+u*a*(i+u*o*(2*i*i-1)))}function c(t,e,r,n,a,o,i){var s,E,c,f,_,R=(e-r)/e,T=o-n,h=Math.atan((1-R)*Math.tan(a)),A=Math.atan((1-R)*Math.tan(i)),d=Math.cos(h),S=Math.sin(h),m=Math.cos(A),C=Math.sin(A),N=d*m,I=d*C,M=S*C,p=S*m,O=T,g=u.TWO_PI,y=Math.cos(O),F=Math.sin(O);do{y=Math.cos(O),F=Math.sin(O);var L=I-p*y;c=Math.sqrt(m*m*F*F+L*L),E=M+N*y,s=Math.atan2(c,E);var v;0===c?(v=0,f=1):(v=N*F/c,f=1-v*v),g=O,_=E-2*M/f,isNaN(_)&&(_=0),O=T+l(R,v,f,s,c,E,_)}while(Math.abs(O-g)>u.EPSILON12);var U=f*(e*e-r*r)/(r*r),P=1+U*(4096+U*(U*(320-175*U)-768))/16384,D=U*(256+U*(U*(74-47*U)-128))/1024,B=_*_,w=D*c*(_+D*(E*(2*B-1)-D*_*(4*c*c-3)*(4*B-3)/6)/4),x=r*P*(s-w),G=Math.atan2(m*F,I-p*y),b=Math.atan2(d*F,I*y-p);t._distance=x,t._startHeading=G,t._endHeading=b,t._uSquared=U}function f(r,n,a,o){t.normalize(o.cartographicToCartesian(n,T),R),t.normalize(o.cartographicToCartesian(a,T),T);c(r,o.maximumRadius,o.minimumRadius,n.longitude,n.latitude,a.longitude,a.latitude),r._start=e.clone(n,r._start),r._end=e.clone(a,r._end),r._start.height=0,r._end.height=0,s(r)}function _(t,r,o){var u=n(o,i.WGS84);this._ellipsoid=u,this._start=new e,this._end=new e,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(t)&&a(r)&&f(this,t,r,u)}var R=new t,T=new t;return o(_.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),_.prototype.setEndPoints=function(t,e){f(this,t,e,this._ellipsoid)},_.prototype.interpolateUsingFraction=function(t,e){return this.interpolateUsingSurfaceDistance(this._distance*t,e)},_.prototype.interpolateUsingSurfaceDistance=function(t,r){var n=this._constants,o=n.distanceRatio+t/n.b,i=Math.cos(2*o),u=Math.cos(4*o),s=Math.cos(6*o),E=Math.sin(2*o),c=Math.sin(4*o),f=Math.sin(6*o),_=Math.sin(8*o),R=o*o,T=o*R,h=n.u8Over256,A=n.u2Over4,d=n.u6Over64,S=n.u4Over16,m=2*T*h*i/3+o*(1-A+7*S/4-15*d/4+579*h/64-(S-15*d/4+187*h/16)*i-(5*d/4-115*h/16)*u-29*h*s/16)+(A/2-S+71*d/32-85*h/16)*E+(5*S/16-5*d/4+383*h/96)*c-R*((d-11*h/2)*E+5*h*c/2)+(29*d/96-29*h/16)*f+539*h*_/1536,C=Math.asin(Math.sin(m)*n.cosineAlpha),N=Math.atan(n.a/n.b*Math.tan(C));m-=n.sigma;var I=Math.cos(2*n.sigma+m),M=Math.sin(m),p=Math.cos(m),O=n.cosineU*p,g=n.sineU*M,y=Math.atan2(M*n.sineHeading,O-g*n.cosineHeading),F=y-l(n.f,n.sineAlpha,n.cosineSquaredAlpha,m,M,p,I);return a(r)?(r.longitude=this._start.longitude+F,r.latitude=N,r.height=0,r):new e(this._start.longitude+F,N,0)},_}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(t,e){"use strict";function r(t,r,n){var a=t+r;return e.sign(t)!==e.sign(r)&&Math.abs(a/Math.max(Math.abs(t),Math.abs(r)))<n?0:a}var n={};return n.computeDiscriminant=function(t,e,r){return e*e-4*t*r},n.computeRealRoots=function(t,n,a){var o;if(0===t)return 0===n?[]:[-a/n];if(0===n){if(0===a)return[0,0];var i=Math.abs(a),u=Math.abs(t);if(i<u&&i/u<e.EPSILON14)return[0,0];if(i>u&&u/i<e.EPSILON14)return[];if((o=-a/t)<0)return[];var s=Math.sqrt(o);return[-s,s]}if(0===a)return o=-n/t,o<0?[o,0]:[0,o];var E=n*n,l=4*t*a,c=r(E,-l,e.EPSILON14);if(c<0)return[];var f=-.5*r(n,e.sign(n)*Math.sqrt(c),e.EPSILON14);return n>0?[f/t,a/f]:[a/f,f/t]},n}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(t,e){"use strict";function r(t,e,r,n){var a,o,i=t,u=e/3,s=r/3,E=n,l=i*s,c=u*E,f=u*u,_=s*s,R=i*s-f,T=i*E-u*s,h=u*E-_,A=4*R*h-T*T;if(A<0){var d,S,m;f*c>=l*_?(d=i,S=R,m=-2*u*R+i*T):(d=E,S=h,m=-E*T+2*s*h);var C=m<0?-1:1,N=-C*Math.abs(d)*Math.sqrt(-A);o=-m+N;var I=o/2,M=I<0?-Math.pow(-I,1/3):Math.pow(I,1/3),p=o===N?-M:-S/M;return a=S<=0?M+p:-m/(M*M+p*p+S),f*c>=l*_?[(a-u)/i]:[-E/(a+s)]}var O=R,g=-2*u*R+i*T,y=h,F=-E*T+2*s*h,L=Math.sqrt(A),v=Math.sqrt(3)/2,U=Math.abs(Math.atan2(i*L,-g)/3);a=2*Math.sqrt(-O);var P=Math.cos(U);o=a*P;var D=a*(-P/2-v*Math.sin(U)),B=o+D>2*u?o-u:D-u,w=i,x=B/w;U=Math.abs(Math.atan2(E*L,-F)/3),a=2*Math.sqrt(-y),P=Math.cos(U),o=a*P,D=a*(-P/2-v*Math.sin(U));var G=-E,b=o+D<2*s?o+s:D+s,z=G/b,H=w*b,V=-B*b-w*G,X=B*G,q=(s*V-u*X)/(-u*V+s*H);return x<=q?x<=z?q<=z?[x,q,z]:[x,z,q]:[z,x,q]:x<=z?[q,x,z]:q<=z?[q,z,x]:[z,q,x]}var n={};return n.computeDiscriminant=function(t,e,r,n){var a=t*t,o=e*e,i=r*r;return 18*t*e*r*n+o*i-27*a*(n*n)-4*(t*i*r+o*e*n)},n.computeRealRoots=function(t,n,a,o){var i,u;if(0===t)return e.computeRealRoots(n,a,o);if(0===n){if(0===a){if(0===o)return[0,0,0];u=-o/t;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===o?(i=e.computeRealRoots(t,0,a),0===i.Length?[0]:[i[0],0,i[1]]):r(t,0,a,o)}return 0===a?0===o?(u=-n/t,u<0?[u,0,0]:[0,0,u]):r(t,n,0,o):0===o?(i=e.computeRealRoots(t,n,a),0===i.length?[0]:i[1]<=0?[i[0],i[1],0]:i[0]>=0?[0,i[0],i[1]]:[i[0],0,i[1]]):r(t,n,a,o)},n}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(t,e,r,n){"use strict";function a(e,a,o,i){var u=e*e,s=a-3*u/8,E=o-a*e/2+u*e/8,l=i-o*e/4+a*u/16-3*u*u/256,c=t.computeRealRoots(1,2*s,s*s-4*l,-E*E);if(c.length>0){var f=-e/4,_=c[c.length-1];if(Math.abs(_)<r.EPSILON14){var R=n.computeRealRoots(1,s,l);if(2===R.length){var T,h=R[0],A=R[1];if(h>=0&&A>=0){var d=Math.sqrt(h),S=Math.sqrt(A);return[f-S,f-d,f+d,f+S]}if(h>=0&&A<0)return T=Math.sqrt(h),[f-T,f+T];if(h<0&&A>=0)return T=Math.sqrt(A),[f-T,f+T]}return[]}if(_>0){var m=Math.sqrt(_),C=(s+_-E/m)/2,N=(s+_+E/m)/2,I=n.computeRealRoots(1,m,C),M=n.computeRealRoots(1,-m,N);return 0!==I.length?(I[0]+=f,I[1]+=f,0!==M.length?(M[0]+=f,M[1]+=f,I[1]<=M[0]?[I[0],I[1],M[0],M[1]]:M[1]<=I[0]?[M[0],M[1],I[0],I[1]]:I[0]>=M[0]&&I[1]<=M[1]?[M[0],I[0],I[1],M[1]]:M[0]>=I[0]&&M[1]<=I[1]?[I[0],M[0],M[1],I[1]]:I[0]>M[0]&&I[0]<M[1]?[M[0],I[0],M[1],I[1]]:[I[0],M[0],I[1],M[1]]):I):0!==M.length?(M[0]+=f,M[1]+=f,M):[]}}return[]}function o(e,a,o,i){var u=o*o,s=a*a,E=e*e,l=-2*a,c=o*e+s-4*i,f=E*i-o*a*e+u,_=t.computeRealRoots(1,l,c,f);if(_.length>0){var R,T,h=_[0],A=a-h,d=A*A,S=e/2,m=A/2,C=d-4*i,N=d+4*Math.abs(i),I=E-4*h,M=E+4*Math.abs(h);if(h<0||C*M<I*N){var p=Math.sqrt(I);R=p/2,T=0===p?0:(e*m-o)/p}else{var O=Math.sqrt(C);R=0===O?0:(e*m-o)/O,T=O/2}var g,y;0===S&&0===R?(g=0,y=0):r.sign(S)===r.sign(R)?(g=S+R,y=h/g):(y=S-R,g=h/y);var F,L;0===m&&0===T?(F=0,L=0):r.sign(m)===r.sign(T)?(F=m+T,L=i/F):(L=m-T,F=i/L);var v=n.computeRealRoots(1,g,F),U=n.computeRealRoots(1,y,L);if(0!==v.length)return 0!==U.length?v[1]<=U[0]?[v[0],v[1],U[0],U[1]]:U[1]<=v[0]?[U[0],U[1],v[0],v[1]]:v[0]>=U[0]&&v[1]<=U[1]?[U[0],v[0],v[1],U[1]]:U[0]>=v[0]&&U[1]<=v[1]?[v[0],U[0],U[1],v[1]]:v[0]>U[0]&&v[0]<U[1]?[U[0],v[0],U[1],v[1]]:[v[0],U[0],v[1],U[1]]:v;if(0!==U.length)return U}return[]}var i={};return i.computeDiscriminant=function(t,e,r,n,a){var o=t*t,i=o*t,u=e*e,s=u*e,E=r*r,l=E*r,c=n*n,f=c*n,_=a*a;return u*E*c-4*s*f-4*t*l*c+18*t*e*r*f-27*o*c*c+256*i*(_*a)+a*(18*s*r*n-4*u*l+16*t*E*E-80*t*e*E*n-6*t*u*c+144*o*r*c)+_*(144*t*u*r-27*u*u-128*o*E-192*o*e*n)},i.computeRealRoots=function(e,n,i,u,s){if(Math.abs(e)<r.EPSILON15)return t.computeRealRoots(n,i,u,s);var E=n/e,l=i/e,c=u/e,f=s/e,_=E<0?1:0;switch(_+=l<0?_+1:_,_+=c<0?_+1:_,_+=f<0?_+1:_){case 0:return a(E,l,c,f);case 1:case 2:return o(E,l,c,f);case 3:case 4:return a(E,l,c,f);case 5:return o(E,l,c,f);case 6:case 7:return a(E,l,c,f);case 8:return o(E,l,c,f);case 9:case 10:return a(E,l,c,f);case 11:return o(E,l,c,f);case 12:case 13:case 14:case 15:return a(E,l,c,f);default:return}},i}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(t,e,r,n){"use strict";function a(r,n){n=t.clone(e(n,t.ZERO)),t.equals(n,t.ZERO)||t.normalize(n,n),this.origin=t.clone(e(r,t.ZERO)),this.direction=n}return a.getPoint=function(e,n,a){return r(a)||(a=new t),a=t.multiplyByScalar(e.direction,n,a),t.add(e.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(t,e,r,n,a,o,i,u,s,E,l){"use strict";function c(t,e,r,n){var a=e*e-4*t*r;if(!(a<0)){if(a>0){var o=1/(2*t),i=Math.sqrt(a),u=(-e+i)*o,s=(-e-i)*o;return u<s?(n.root0=u,n.root1=s):(n.root0=s,n.root1=u),n}var E=-e/(2*t);if(0!==E)return n.root0=n.root1=E,n}}function f(e,r,a){n(a)||(a=new o);var i=e.origin,u=e.direction,s=r.center,E=r.radius*r.radius,l=t.subtract(i,s,d),f=t.dot(u,u),_=2*t.dot(u,l),R=t.magnitudeSquared(l)-E,T=c(f,_,R,N);if(n(T))return a.start=T.root0,a.stop=T.root1,a}function _(t,e,r){var n=t+e;return i.sign(t)!==i.sign(e)&&Math.abs(n/Math.max(Math.abs(t),Math.abs(e)))<r?0:n}function R(e,r,n,a,o){var l,c=a*a,f=o*o,R=(e[u.COLUMN1ROW1]-e[u.COLUMN2ROW2])*f,T=o*(a*_(e[u.COLUMN1ROW0],e[u.COLUMN0ROW1],i.EPSILON15)+r.y),h=e[u.COLUMN0ROW0]*c+e[u.COLUMN2ROW2]*f+a*r.x+n,A=f*_(e[u.COLUMN2ROW1],e[u.COLUMN1ROW2],i.EPSILON15),d=o*(a*_(e[u.COLUMN2ROW0],e[u.COLUMN0ROW2])+r.z),S=[];if(0===d&&0===A){if(l=s.computeRealRoots(R,T,h),0===l.length)return S;var m=l[0],C=Math.sqrt(Math.max(1-m*m,0));if(S.push(new t(a,o*m,o*-C)),S.push(new t(a,o*m,o*C)),2===l.length){var N=l[1],I=Math.sqrt(Math.max(1-N*N,0));S.push(new t(a,o*N,o*-I)),S.push(new t(a,o*N,o*I))}return S}var M=d*d,p=A*A,O=R*R,g=d*A,y=O+p,F=2*(T*R+g),L=2*h*R+T*T-p+M,v=2*(h*T-g),U=h*h-M;if(0===y&&0===F&&0===L&&0===v)return S;l=E.computeRealRoots(y,F,L,v,U);var P=l.length;if(0===P)return S;for(var D=0;D<P;++D){var B,w=l[D],x=w*w,G=Math.max(1-x,0),b=Math.sqrt(G);B=i.sign(R)===i.sign(h)?_(R*x+h,T*w,i.EPSILON12):i.sign(h)===i.sign(T*w)?_(R*x,T*w+h,i.EPSILON12):_(R*x+T*w,h,i.EPSILON12);var z=_(A*w,d,i.EPSILON15),H=B*z;H<0?S.push(new t(a,o*w,o*b)):H>0?S.push(new t(a,o*w,o*-b)):0!==b?(S.push(new t(a,o*w,o*-b)),S.push(new t(a,o*w,o*b)),++D):S.push(new t(a,o*w,o*b))}return S}var T={};T.rayPlane=function(e,r,a){n(a)||(a=new t);var o=e.origin,u=e.direction,s=r.normal,E=t.dot(s,u);if(!(Math.abs(E)<i.EPSILON15)){var l=(-r.distance-t.dot(s,o))/E;if(!(l<0))return a=t.multiplyByScalar(u,l,a),t.add(o,a,a)}};var h=new t,A=new t,d=new t,S=new t,m=new t;T.rayTriangleParametric=function(e,n,a,o,u){u=r(u,!1);var s,E,l,c,f,_=e.origin,R=e.direction,T=t.subtract(a,n,h),C=t.subtract(o,n,A),N=t.cross(R,C,d),I=t.dot(T,N);if(u){if(I<i.EPSILON6)return;if(s=t.subtract(_,n,S),(l=t.dot(s,N))<0||l>I)return;if(E=t.cross(s,T,m),(c=t.dot(R,E))<0||l+c>I)return;f=t.dot(C,E)/I}else{if(Math.abs(I)<i.EPSILON6)return;var M=1/I;if(s=t.subtract(_,n,S),(l=t.dot(s,N)*M)<0||l>1)return;if(E=t.cross(s,T,m),(c=t.dot(R,E)*M)<0||l+c>1)return;f=t.dot(C,E)*M}return f},T.rayTriangle=function(e,r,a,o,i,u){var s=T.rayTriangleParametric(e,r,a,o,i);if(n(s)&&!(s<0))return n(u)||(u=new t),t.multiplyByScalar(e.direction,s,u),t.add(e.origin,u,u)};var C=new l;T.lineSegmentTriangle=function(e,r,a,o,i,u,s){var E=C;t.clone(e,E.origin),t.subtract(r,e,E.direction),t.normalize(E.direction,E.direction);var l=T.rayTriangleParametric(E,a,o,i,u);if(!(!n(l)||l<0||l>t.distance(e,r)))return n(s)||(s=new t),t.multiplyByScalar(E.direction,l,s),t.add(E.origin,s,s)};var N={root0:0,root1:0};T.raySphere=function(t,e,r){if(r=f(t,e,r),n(r)&&!(r.stop<0))return r.start=Math.max(r.start,0),r};var I=new l;T.lineSegmentSphere=function(e,r,a,o){var i=I;t.clone(e,i.origin);var u=t.subtract(r,e,i.direction),s=t.magnitude(u);if(t.normalize(u,u),o=f(i,a,o),!(!n(o)||o.stop<0||o.start>s))return o.start=Math.max(o.start,0),o.stop=Math.min(o.stop,s),o};var M=new t,p=new t;T.rayEllipsoid=function(e,r){var n,a,i,u,s,E=r.oneOverRadii,l=t.multiplyComponents(E,e.origin,M),c=t.multiplyComponents(E,e.direction,p),f=t.magnitudeSquared(l),_=t.dot(l,c);if(f>1){if(_>=0)return;var R=_*_;if(n=f-1,a=t.magnitudeSquared(c),i=a*n,R<i)return;if(R>i){u=_*_-i,s=-_+Math.sqrt(u);var T=s/a,h=n/s;return T<h?new o(T,h):{start:h,stop:T}}var A=Math.sqrt(n/a);return new o(A,A)}return f<1?(n=f-1,a=t.magnitudeSquared(c),i=a*n,u=_*_-i,s=-_+Math.sqrt(u),new o(0,s/a)):_<0?(a=t.magnitudeSquared(c),new o(0,-_/a)):void 0};var O=new t,g=new t,y=new t,F=new t,L=new t,v=new u,U=new u,P=new u,D=new u,B=new u,w=new u,x=new u,G=new t,b=new t,z=new e;T.grazingAltitudeLocation=function(e,r){var a=e.origin,o=e.direction;if(!t.equals(a,t.ZERO)){var s=r.geodeticSurfaceNormal(a,O);if(t.dot(o,s)>=0)return a}var E=n(this.rayEllipsoid(e,r)),l=r.transformPositionToScaledSpace(o,O),c=t.normalize(l,l),f=t.mostOrthogonalAxis(l,F),_=t.normalize(t.cross(f,c,g),g),T=t.normalize(t.cross(c,_,y),y),h=v;h[0]=c.x,h[1]=c.y,h[2]=c.z,h[3]=_.x,h[4]=_.y,h[5]=_.z,h[6]=T.x,h[7]=T.y,h[8]=T.z;var A=u.transpose(h,U),d=u.fromScale(r.radii,P),S=u.fromScale(r.oneOverRadii,D),m=B;m[0]=0,m[1]=-o.z,m[2]=o.y,m[3]=o.z,m[4]=0,m[5]=-o.x,m[6]=-o.y,m[7]=o.x,m[8]=0;var C,N,I=u.multiply(u.multiply(A,S,w),m,w),M=u.multiply(u.multiply(I,d,x),h,x),p=u.multiplyByVector(I,a,L),H=R(M,t.negate(p,O),0,0,1),V=H.length;if(V>0){for(var X=t.clone(t.ZERO,b),q=Number.NEGATIVE_INFINITY,W=0;W<V;++W){C=u.multiplyByVector(d,u.multiplyByVector(h,H[W],G),G);var Y=t.normalize(t.subtract(C,a,F),F),K=t.dot(Y,o);K>q&&(q=K,X=t.clone(C,X))}var k=r.cartesianToCartographic(X,z);return q=i.clamp(q,0,1),N=t.magnitude(t.subtract(X,a,F))*Math.sqrt(1-q*q),N=E?-N:N,k.height=N,r.cartographicToCartesian(k,new t)}};var H=new t;return T.lineSegmentPlane=function(e,r,a,o){n(o)||(o=new t);var u=t.subtract(r,e,H),s=a.normal,E=t.dot(s,u);if(!(Math.abs(E)<i.EPSILON6)){var l=t.dot(s,e),c=-(a.distance+l)/E;if(!(c<0||c>1))return t.multiplyByScalar(u,c,o),t.add(e,o,o),o}},T.trianglePlaneIntersection=function(e,r,n,a){var o=a.normal,i=a.distance,u=t.dot(o,e)+i<0,s=t.dot(o,r)+i<0,E=t.dot(o,n)+i<0,l=0;l+=u?1:0,l+=s?1:0,l+=E?1:0;var c,f;if(1!==l&&2!==l||(c=new t,f=new t),1===l){if(u)return T.lineSegmentPlane(e,r,a,c),T.lineSegmentPlane(e,n,a,f),{positions:[e,r,n,c,f],indices:[0,3,4,1,2,4,1,4,3]};if(s)return T.lineSegmentPlane(r,n,a,c),T.lineSegmentPlane(r,e,a,f),{positions:[e,r,n,c,f],indices:[1,3,4,2,0,4,2,4,3]};if(E)return T.lineSegmentPlane(n,e,a,c),T.lineSegmentPlane(n,r,a,f),{positions:[e,r,n,c,f],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return T.lineSegmentPlane(r,e,a,c),T.lineSegmentPlane(n,e,a,f),{positions:[e,r,n,c,f],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return T.lineSegmentPlane(n,r,a,c),T.lineSegmentPlane(e,r,a,f),{positions:[e,r,n,c,f],indices:[2,0,4,2,4,3,1,3,4]};if(!E)return T.lineSegmentPlane(e,n,a,c),T.lineSegmentPlane(r,n,a,f),{positions:[e,r,n,c,f],indices:[0,1,4,0,4,3,2,3,4]}}},T}),define("Core/isArray",["./defined"],function(t){"use strict";var e=Array.isArray;return t(e)||(e=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),e}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(t,e,r,n,a,o,i){"use strict";function u(e,r){this.normal=t.clone(e),this.distance=r}u.fromPointNormal=function(e,n,a){var o=-t.dot(n,e);return r(a)?(t.clone(n,a.normal),a.distance=o,a):new u(n,o)};var s=new t;u.fromCartesian4=function(e,n){var a=t.fromCartesian4(e,s),o=e.w;return r(n)?(t.clone(a,n.normal),n.distance=o,n):new u(a,o)},u.getPointDistance=function(e,r){return t.dot(e.normal,r)+e.distance};var E=new t;u.projectPointOntoPlane=function(e,n,a){r(a)||(a=new t);var o=u.getPointDistance(e,n),i=t.multiplyByScalar(e.normal,o,E);return t.subtract(n,i,a)};var l=new t;return u.transform=function(e,r,n){return i.multiplyByPointAsVector(r,e.normal,s),t.normalize(s,s),t.multiplyByScalar(e.normal,-e.distance,l),i.multiplyByPoint(r,l,l),u.fromPointNormal(l,s,n)},u.clone=function(e,n){return r(n)?(t.clone(e.normal,n.normal),n.distance=e.distance,n):new u(e.normal,e.distance)},u.equals=function(e,r){return e.distance===r.distance&&t.equals(e.normal,r.normal)},u.ORIGIN_XY_PLANE=a(new u(t.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(t.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(t.UNIT_Y,0)),u}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(t,e,r,n,a,o,i,u,s,E,l,c){"use strict";function f(t,e,r){var n=M;n.length=t;var a;if(e===r){for(a=0;a<t;a++)n[a]=e;return n}var o=r-e,i=o/t;for(a=0;a<t;a++){var u=e+a*i;n[a]=u}return n}function _(e,r,n,a,o,i,u,s){var E=a.scaleToGeodeticSurface(e,y),l=a.scaleToGeodeticSurface(r,F),c=R.numberOfPoints(e,r,n),_=a.cartesianToCartographic(E,p),T=a.cartesianToCartographic(l,O),h=f(c,o,i);L.setEndPoints(_,T);var A=L.surfaceDistance/c,d=s;_.height=o;var S=a.cartographicToCartesian(_,g);t.pack(S,u,d),d+=3;for(var m=1;m<c;m++){var C=L.interpolateUsingSurfaceDistance(m*A,O);C.height=h[m],S=a.cartographicToCartesian(C,g),t.pack(S,u,d),d+=3}return d}var R={};R.numberOfPoints=function(e,r,n){var a=t.distance(e,r);return Math.ceil(a/n)};var T=new e;R.extractHeights=function(t,e){for(var r=t.length,n=new Array(r),a=0;a<r;a++){var o=t[a];n[a]=e.cartesianToCartographic(o,T).height}return n};var h=new l,A=new t,d=new t,S=new c(t.UNIT_X,0),m=new t,C=new c(t.UNIT_X,0),N=new t,I=new t,M=[],p=new e,O=new e,g=new t,y=new t,F=new t,L=new i;return R.wrapLongitude=function(e,a){var o=[],i=[];if(n(e)&&e.length>0){a=r(a,l.IDENTITY);var s=l.inverseTransformation(a,h),E=l.multiplyByPoint(s,t.ZERO,A),f=t.normalize(l.multiplyByPointAsVector(s,t.UNIT_Y,d),d),_=c.fromPointNormal(E,f,S),R=t.normalize(l.multiplyByPointAsVector(s,t.UNIT_X,m),m),T=c.fromPointNormal(E,R,C),M=1;o.push(t.clone(e[0]));for(var p=o[0],O=e.length,g=1;g<O;++g){var y=e[g];if(c.getPointDistance(T,p)<0||c.getPointDistance(T,y)<0){var F=u.lineSegmentPlane(p,y,_,N);if(n(F)){var L=t.multiplyByScalar(f,5e-9,I);c.getPointDistance(_,p)<0&&t.negate(L,L),o.push(t.add(F,L,new t)),i.push(M+1),t.negate(L,L),o.push(t.add(F,L,new t)),M=1}}o.push(t.clone(e[g])),M++,p=y}i.push(M)}return{positions:o,lengths:i}},R.generateArc=function(e){n(e)||(e={});var a=e.positions,i=a.length,u=r(e.ellipsoid,o.WGS84),l=r(e.height,0),c=s(l);if(i<1)return[];if(1===i){var f=u.scaleToGeodeticSurface(a[0],y);if(0!==(l=c?l[0]:l)){var T=u.geodeticSurfaceNormal(f,g);t.multiplyByScalar(T,l,T),t.add(f,T,f)}return[f.x,f.y,f.z]}var h=e.minDistance;if(!n(h)){var A=r(e.granularity,E.RADIANS_PER_DEGREE);h=E.chordLength(A,u.maximumRadius)}var d,S=0;for(d=0;d<i-1;d++)S+=R.numberOfPoints(a[d],a[d+1],h);var m=3*(S+1),C=new Array(m),N=0;for(d=0;d<i-1;d++){N=_(a[d],a[d+1],h,u,c?l[d]:l,c?l[d+1]:l,C,N)}M.length=0;var I=a[i-1],O=u.cartesianToCartographic(I,p);O.height=c?l[i-1]:l;var F=u.cartographicToCartesian(O,g);return t.pack(F,C,m-3),C},R.generateCartesianArc=function(e){for(var r=R.generateArc(e),n=r.length/3,a=new Array(n),o=0;o<n;o++)a[o]=t.unpack(r,3*o);return a},R}),define("Core/SimplePolylineGeometry",["./BoundingSphere","./Cartesian3","./Color","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PolylinePipeline","./PrimitiveType"],function(t,e,r,n,a,o,i,u,s,E,l,c,f,_,R){"use strict";function T(t,e,n,a,o,i,u){var s,E=_.numberOfPoints(t,e,o),l=n.red,c=n.green,f=n.blue,R=n.alpha,T=a.red,h=a.green,A=a.blue,d=a.alpha;if(r.equals(n,a)){for(s=0;s<E;s++)i[u++]=r.floatToByte(l),i[u++]=r.floatToByte(c),i[u++]=r.floatToByte(f),i[u++]=r.floatToByte(R);return u}var S=(T-l)/E,m=(h-c)/E,C=(A-f)/E,N=(d-R)/E,I=u;for(s=0;s<E;s++)i[I++]=r.floatToByte(l+s*S),i[I++]=r.floatToByte(c+s*m),i[I++]=r.floatToByte(f+s*C),i[I++]=r.floatToByte(R+s*N);return I}function h(t){t=a(t,a.EMPTY_OBJECT);var n=t.positions,i=t.colors,s=a(t.colorsPerVertex,!1);this._positions=n,this._colors=i,this._colorsPerVertex=s,this._followSurface=a(t.followSurface,!0),this._granularity=a(t.granularity,f.RADIANS_PER_DEGREE),this._ellipsoid=a(t.ellipsoid,u.WGS84),this._workerName="createSimplePolylineGeometry";var E=1+n.length*e.packedLength;E+=o(i)?1+i.length*r.packedLength:1,this.packedLength=E+u.packedLength+3}h.pack=function(t,n,i){i=a(i,0);var s,E=t._positions,l=E.length;for(n[i++]=l,s=0;s<l;++s,i+=e.packedLength)e.pack(E[s],n,i);var c=t._colors;for(l=o(c)?c.length:0,n[i++]=l,s=0;s<l;++s,i+=r.packedLength)r.pack(c[s],n,i);return u.pack(t._ellipsoid,n,i),i+=u.packedLength,n[i++]=t._colorsPerVertex?1:0,n[i++]=t._followSurface?1:0,n[i]=t._granularity,n},h.unpack=function(t,n,i){n=a(n,0);var s,E=t[n++],l=new Array(E);for(s=0;s<E;++s,n+=e.packedLength)l[s]=e.unpack(t,n);E=t[n++];var c=E>0?new Array(E):void 0;for(s=0;s<E;++s,n+=r.packedLength)c[s]=r.unpack(t,n);var f=u.unpack(t,n);n+=u.packedLength;var _=1===t[n++],R=1===t[n++],T=t[n];return o(i)?(i._positions=l,i._colors=c,i._ellipsoid=f,i._colorsPerVertex=_,i._followSurface=R,i._granularity=T,i):new h({positions:l,colors:c,ellipsoid:f,colorsPerVertex:_,followSurface:R,granularity:T})};var A=new Array(2),d=new Array(2),S={positions:A,height:d,ellipsoid:void 0,minDistance:void 0};return h.createGeometry=function(a){var i,u,h,m,C,N=a._positions,I=a._colors,M=a._colorsPerVertex,p=a._followSurface,O=a._granularity,g=a._ellipsoid,y=f.chordLength(O,g.maximumRadius),F=o(I)&&!M,L=N.length,v=0;if(p){var U=_.extractHeights(N,g),P=S;if(P.minDistance=y,P.ellipsoid=g,F){var D=0;for(i=0;i<L-1;i++)D+=_.numberOfPoints(N[i],N[i+1],y)+1;u=new Float64Array(3*D),m=new Uint8Array(4*D),P.positions=A,P.height=d;var B=0;for(i=0;i<L-1;++i){A[0]=N[i],A[1]=N[i+1],d[0]=U[i],d[1]=U[i+1];var w=_.generateArc(P);if(o(I)){var x=w.length/3;C=I[i];for(var G=0;G<x;++G)m[B++]=r.floatToByte(C.red),m[B++]=r.floatToByte(C.green),m[B++]=r.floatToByte(C.blue),m[B++]=r.floatToByte(C.alpha)}u.set(w,v),v+=w.length}}else if(P.positions=N,P.height=U,u=new Float64Array(_.generateArc(P)),o(I)){for(m=new Uint8Array(u.length/3*4),i=0;i<L-1;++i){var b=N[i],z=N[i+1],H=I[i],V=I[i+1];v=T(b,z,H,V,y,m,v)}var X=I[L-1];m[v++]=r.floatToByte(X.red),m[v++]=r.floatToByte(X.green),m[v++]=r.floatToByte(X.blue),m[v++]=r.floatToByte(X.alpha)}}else{h=F?2*L-2:L,u=new Float64Array(3*h),m=o(I)?new Uint8Array(4*h):void 0;var q=0,W=0;for(i=0;i<L;++i){var Y=N[i];if(F&&i>0&&(e.pack(Y,u,q),q+=3,C=I[i-1],m[W++]=r.floatToByte(C.red),m[W++]=r.floatToByte(C.green),m[W++]=r.floatToByte(C.blue),m[W++]=r.floatToByte(C.alpha)),F&&i===L-1)break;e.pack(Y,u,q),q+=3,o(I)&&(C=I[i],m[W++]=r.floatToByte(C.red),m[W++]=r.floatToByte(C.green),m[W++]=r.floatToByte(C.blue),m[W++]=r.floatToByte(C.alpha))}}var K=new l;K.position=new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:u}),o(I)&&(K.color=new E({componentDatatype:n.UNSIGNED_BYTE,componentsPerAttribute:4,values:m,normalize:!0})),h=u.length/3;var k=2*(h-1),Z=c.createTypedArray(h,k),j=0;for(i=0;i<h-1;++i)Z[j++]=i,Z[j++]=i+1;return new s({attributes:K,indices:Z,primitiveType:R.LINES,boundingSphere:t.fromPoints(N)})},h}),define("Workers/createSimplePolylineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/SimplePolylineGeometry"],function(t,e,r){"use strict";function n(n,a){return t(a)&&(n=r.unpack(n,a)),n._ellipsoid=e.clone(n._ellipsoid),r.createGeometry(n)}return n})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereGeometry.js index 163e5f4f..0ba695dd 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,l=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:R,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,l);var c=Math.sqrt(o.dot(T,l));return l=o.divideByScalar(l,c,l),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(l,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,l=a.x,R=a.y,f=a.z,A=c*c*l*l,h=_*_*R*R,N=T*T*f*f,d=A+h+N,I=Math.sqrt(1/d),S=t.multiplyByScalar(n,I,i);if(d<E)return isFinite(I)?t.clone(S,s):void 0;var m=u.x,M=u.y,O=u.z,y=o;y.x=S.x*m*2,y.y=S.y*M*2,y.z=S.z*O*2;var p,C,U,P,L,F,w,g,v,x,D,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*m),P=1/(1+B*M),L=1/(1+B*O),F=U*U,w=P*P,g=L*L,v=F*U,x=w*P,D=g*L,p=A*F+h*w+N*g-1,C=A*v*m+h*x*M+N*D*O;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*P,s.z=T*L,s):new t(c*U,_*P,T*L)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),l=i.EPSILON1;return u.fromCartesian=function(e,n,a){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:l,h=o(e,R,f,A,s);if(r(h)){var N=t.multiplyComponents(h,f,E);N=t.normalize(N,N);var d=t.subtract(e,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),m=i.sign(t.dot(d,e))*t.magnitude(d);return r(a)?(a.longitude=I,a.latitude=S,a.height=m,a):new u(I,S,m)}},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,l=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=l;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var R=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,f);if(a(i)){var o=this.geodeticSurfaceNormal(i,R),u=t.subtract(n,i,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],R[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(f[i],R[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=R[a],T=f[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var l,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],N=t[E.getElementIndex(T,_)],d=(A-h)/2/N;l=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+l*l),c=l*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,l=t.w*t.w,R=n-u-_+l,f=2*(a-T),A=2*(i+c),h=2*(a+T),N=-n+u-_+l,d=2*(s-o),I=2*(i-c),S=2*(s+o),m=-n-u+_+l;return r(e)?(e[0]=R,e[1]=h,e[2]=I,e[3]=f,e[4]=N,e[5]=S,e[6]=A,e[7]=d,e[8]=m,e):new E(R,f,A,h,N,d,I,S,m)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,l=n*u,R=i*a+s*o*u,f=-s*a+i*o*u,A=-o,h=s*n,N=i*n;return r(e)?(e[0]=c,e[1]=l,e[2]=A,e[3]=_,e[4]=R,e[5]=h,e[6]=T,e[7]=f,e[8]=N,e):new E(c,_,T,l,R,f,A,h,N)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var l=new t;E.getMaximumScale=function(e){return E.getScale(e,l),t.maximumComponent(l)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var R=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),l=n*s(T);i<10&&c(T)>l;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var l=1/T;return E.multiplyByScalar(e,l,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){ -var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,l,R,f,A){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(l,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,l=e.y*e.y,R=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,N=e.w*e.w,d=E-l-A+N,I=2*(s-h),S=2*(_+f),m=2*(s+h),M=-E+l-A+N,O=2*(R-T),y=2*(_-f),p=2*(R+T),C=-E-l+A+N;return r[0]=d*i,r[1]=m*i,r[2]=y*i,r[3]=0,r[4]=I*o,r[5]=M*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=O*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,l=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,l),l);var u=T.x,E=T.y,s=T.z,R=_.x,f=_.y,A=_.z,h=l.x,N=l.y,d=l.z,I=r.x,S=r.y,m=r.z,M=u*-I+E*-S+s*-m,O=h*-I+N*-S+d*-m,y=R*I+f*S+A*m;return a(n)?(n[0]=u,n[1]=h,n[2]=-R,n[3]=0,n[4]=E,n[5]=N,n[6]=-f,n[7]=0,n[8]=s,n[9]=d,n[10]=-A,n[11]=0,n[12]=M,n[13]=O,n[14]=y,n[15]=1,n):new c(u,E,s,M,h,N,d,O,-R,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,l=c,R=_,f=i+s,A=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=l,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=f,a[13]=A,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var R=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],R)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],R)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],R)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],l=t[10],R=t[11],f=t[12],A=t[13],h=t[14],N=t[15],d=e[0],I=e[1],S=e[2],m=e[3],M=e[4],O=e[5],y=e[6],p=e[7],C=e[8],U=e[9],P=e[10],L=e[11],F=e[12],w=e[13],g=e[14],v=e[15],x=r*d+u*I+_*S+f*m,D=a*d+E*I+T*S+A*m,B=i*d+s*I+l*S+h*m,z=o*d+c*I+R*S+N*m,G=r*M+u*O+_*y+f*p,b=a*M+E*O+T*y+A*p,X=i*M+s*O+l*y+h*p,V=o*M+c*O+R*y+N*p,q=r*C+u*U+_*P+f*L,H=a*C+E*U+T*P+A*L,W=i*C+s*U+l*P+h*L,Y=o*C+c*U+R*P+N*L,k=r*F+u*w+_*g+f*v,K=a*F+E*w+T*g+A*v,Z=i*F+s*w+l*g+h*v,j=o*F+c*w+R*g+N*v;return n[0]=x,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],l=t[13],R=t[14],f=e[0],A=e[1],h=e[2],N=e[4],d=e[5],I=e[6],S=e[8],m=e[9],M=e[10],O=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=a*f+u*A+c*h,P=i*f+E*A+_*h,L=r*N+o*d+s*I,F=a*N+u*d+c*I,w=i*N+E*d+_*I,g=r*S+o*m+s*M,v=a*S+u*m+c*M,x=i*S+E*m+_*M,D=r*O+o*y+s*p+T,B=a*O+u*y+c*p+l,z=i*O+E*y+_*p+R;return n[0]=C,n[1]=U,n[2]=P,n[3]=0,n[4]=L,n[5]=F,n[6]=w,n[7]=0,n[8]=g,n[9]=v,n[10]=x,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],l=e[1],R=e[2],f=e[3],A=e[4],h=e[5],N=e[6],d=e[7],I=e[8],S=r*T+o*l+s*R,m=a*T+u*l+c*R,M=i*T+E*l+_*R,O=r*f+o*A+s*h,y=a*f+u*A+c*h,p=i*f+E*A+_*h,C=r*N+o*d+s*I,U=a*N+u*d+c*I,P=i*N+E*d+_*I;return n[0]=S,n[1]=m,n[2]=M,n[3]=0,n[4]=O,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=P,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,N=new E,d=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),N,u.EPSILON7)&&e.equals(c.getRow(t,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],l=t[9],R=t[13],f=t[2],A=t[6],S=t[10],m=t[14],M=t[3],O=t[7],y=t[11],p=t[15],C=S*p,U=m*y,P=A*p,L=m*O,F=A*y,w=S*O,g=f*p,v=m*M,x=f*y,D=S*M,B=f*O,z=A*M,G=C*T+L*l+F*R-(U*T+P*l+w*R),b=U*_+g*l+D*R-(C*_+v*l+x*R),X=P*_+v*T+B*R-(L*_+g*T+z*R),V=w*_+x*T+z*l-(F*_+D*T+B*l),q=U*a+P*i+w*o-(C*a+L*i+F*o),H=C*r+v*i+x*o-(U*r+g*i+D*o),W=L*r+g*a+z*o-(P*r+v*a+B*o),Y=F*r+D*a+B*i-(w*r+x*a+z*i);C=i*R,U=o*l,P=a*R,L=o*T,F=a*l,w=i*T,g=r*R,v=o*_,x=r*l,D=i*_,B=r*T,z=a*_;var k=C*O+L*y+F*p-(U*O+P*y+w*p),K=U*M+g*y+D*p-(C*M+v*y+x*p),Z=P*M+v*O+B*p-(L*M+g*O+z*p),j=w*M+x*O+z*y-(F*M+D*O+B*y),Q=P*S+w*m+U*A-(F*m+C*A+L*S),J=x*m+C*f+v*S-(g*S+D*m+U*f),$=g*A+z*m+L*f-(B*m+P*f+v*A),tt=B*S+F*f+D*A-(x*A+z*S+w*f),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],l=t[14],R=-n*_-r*T-a*l,f=-i*_-o*T-u*l,A=-E*_-s*T-c*l;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=R,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var l=t[_];n=Math.min(n,l.longitude),a=Math.max(a,l.longitude),s=Math.min(s,l.latitude),c=Math.max(c,l.latitude);var R=l.longitude>=0?l.longitude:l.longitude+u.TWO_PI;i=Math.min(i,R),o=Math.max(o,R)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,l=-Number.MAX_VALUE,R=0,f=t.length;R<f;R++){var A=e.cartesianToCartographic(t[R]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),l=Math.max(l,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=l,a):new E(o,T,s,l)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),l=Math.min(t.north,e.north);if(!(T>=l))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=l,n):new E(c,T,_,l)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,l=t.east,R=t.west,f=s;f.height=a,f.longitude=R,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_){"use strict";function T(e,n){this.center=t.clone(r(e,t.ZERO)),this.radius=r(n,0)}var l=new t,R=new t,f=new t,A=new t,h=new t,N=new t,d=new t,I=new t,S=new t,m=new t,M=new t,O=new t;T.fromPoints=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,i=t.clone(e[0],d),o=t.clone(i,l),u=t.clone(i,R),E=t.clone(i,f),s=t.clone(i,A),c=t.clone(i,h),_=t.clone(i,N),y=e.length;for(r=1;r<y;r++){t.clone(e[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&t.clone(i,o),p>s.x&&t.clone(i,s),C<u.y&&t.clone(i,u),C>c.y&&t.clone(i,c),U<E.z&&t.clone(i,E),U>_.z&&t.clone(i,_)}var P=t.magnitudeSquared(t.subtract(s,o,I)),L=t.magnitudeSquared(t.subtract(c,u,I)),F=t.magnitudeSquared(t.subtract(_,E,I)),w=o,g=s,v=P;L>v&&(v=L,w=u,g=c),F>v&&(v=F,w=E,g=_);var x=S;x.x=.5*(w.x+g.x),x.y=.5*(w.y+g.y),x.z=.5*(w.z+g.z);var D=t.magnitudeSquared(t.subtract(g,x,I)),B=Math.sqrt(D),z=m;z.x=o.x,z.y=u.y,z.z=E.z;var G=M;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,I),.5,O),X=0;for(r=0;r<y;r++){t.clone(e[r],i);var V=t.magnitude(t.subtract(i,b,I));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(i,x,I));if(q>D){var H=Math.sqrt(q);B=.5*(B+H),D=B*B;var W=H-B;x.x=(B*x.x+W*i.x)/H,x.y=(B*x.y+W*i.y)/H,x.z=(B*x.z+W*i.z)/H}}return B<X?(t.clone(x,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var y=new o,p=new t,C=new t,U=new e,P=new e;T.fromRectangle2D=function(t,e,n){return T.fromRectangleWithHeights2D(t,e,0,0,n)},T.fromRectangleWithHeights2D=function(e,n,i,o,u){if(a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(e,U),U.height=i,_.northeast(e,P),P.height=o;var E=n.project(U,p),s=n.project(P,C),c=s.x-E.x,l=s.y-E.y,R=s.z-E.z;u.radius=.5*Math.sqrt(c*c+l*l+R*R);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*l,f.z=E.z+.5*R,u};var L=[];T.fromRectangle3D=function(e,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new T),!a(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=_.subsample(e,n,o,L);return T.fromPoints(E,u)},T.fromVertices=function(e,n,i,o){if(a(o)||(o=new T),!a(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=r(n,t.ZERO),i=r(i,3);var u=d;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,l),c=t.clone(u,R),_=t.clone(u,f),y=t.clone(u,A),p=t.clone(u,h),C=t.clone(u,N),U=e.length;for(E=0;E<U;E+=i){var P=e[E]+n.x,L=e[E+1]+n.y,F=e[E+2]+n.z;u.x=P,u.y=L,u.z=F,P<s.x&&t.clone(u,s),P>y.x&&t.clone(u,y),L<c.y&&t.clone(u,c),L>p.y&&t.clone(u,p),F<_.z&&t.clone(u,_),F>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(y,s,I)),g=t.magnitudeSquared(t.subtract(p,c,I)),v=t.magnitudeSquared(t.subtract(C,_,I)),x=s,D=y,B=w;g>B&&(B=g,x=c,D=p),v>B&&(B=v,x=_,D=C);var z=S;z.x=.5*(x.x+D.x),z.y=.5*(x.y+D.y),z.z=.5*(x.z+D.z);var G=t.magnitudeSquared(t.subtract(D,z,I)),b=Math.sqrt(G),X=m;X.x=s.x,X.y=c.y,X.z=_.z;var V=M;V.x=y.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,I),.5,O),H=0;for(E=0;E<U;E+=i){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,I));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,I));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},T.fromEncodedCartesianVertices=function(e,n,r){if(a(r)||(r=new T),!a(e)||!a(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var i=d;i.x=e[0]+n[0],i.y=e[1]+n[1],i.z=e[2]+n[2];var o,u=t.clone(i,l),E=t.clone(i,R),s=t.clone(i,f),c=t.clone(i,A),_=t.clone(i,h),y=t.clone(i,N),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],P=e[o+2]+n[o+2];i.x=C,i.y=U,i.z=P,C<u.x&&t.clone(i,u),C>c.x&&t.clone(i,c),U<E.y&&t.clone(i,E),U>_.y&&t.clone(i,_),P<s.z&&t.clone(i,s),P>y.z&&t.clone(i,y)}var L=t.magnitudeSquared(t.subtract(c,u,I)),F=t.magnitudeSquared(t.subtract(_,E,I)),w=t.magnitudeSquared(t.subtract(y,s,I)),g=u,v=c,x=L;F>x&&(x=F,g=E,v=_),w>x&&(x=w,g=s,v=y);var D=S;D.x=.5*(g.x+v.x),D.y=.5*(g.y+v.y),D.z=.5*(g.z+v.z);var B=t.magnitudeSquared(t.subtract(v,D,I)),z=Math.sqrt(B),G=m;G.x=u.x,G.y=E.y,G.z=s.z;var b=M;b.x=c.x,b.y=_.y,b.z=y.z;var X=t.multiplyByScalar(t.add(G,b,I),.5,O),V=0;for(o=0;o<p;o+=3){i.x=e[o]+n[o],i.y=e[o+1]+n[o+1],i.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(i,X,I));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(i,D,I));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*i.x)/W,D.y=(z*D.y+Y*i.y)/W,D.z=(z*D.z+Y*i.z)/W}}return z<V?(t.clone(D,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(e,n,r){a(r)||(r=new T);var i=r.center;return t.add(e,n,i),t.multiplyByScalar(i,.5,i),r.radius=t.distance(i,n),r},T.fromEllipsoid=function(e,n){return a(n)||(n=new T),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var F=new t;T.fromBoundingSpheres=function(e,n){if(a(n)||(n=new T),!a(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return T.clone(e[0],n);if(2===r)return T.union(e[0],e[1],n);var i,o=[];for(i=0;i<r;i++)o.push(e[i].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=e[i];E=Math.max(E,t.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var w=new t,g=new t,v=new t;T.fromOrientedBoundingBox=function(e,n){a(n)||(n=new T);var r=e.halfAxes,i=s.getColumn(r,0,w),o=s.getColumn(r,1,g),u=s.getColumn(r,2,v);return t.add(i,o,i),t.add(i,u,i),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(i),n},T.clone=function(e,n){if(a(e))return a(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new T(e.center,e.radius)},T.packedLength=4,T.pack=function(t,e,n){n=r(n,0);var a=t.center;return e[n++]=a.x,e[n++]=a.y,e[n++]=a.z,e[n]=t.radius,e},T.unpack=function(t,e,n){e=r(e,0),a(n)||(n=new T);var i=n.center;return i.x=t[e++],i.y=t[e++],i.z=t[e++],n.radius=t[e],n};var x=new t,D=new t;T.union=function(e,n,r){a(r)||(r=new T);var i=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,i,x),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),l=t.multiplyByScalar(s,(-o+_)/c,D);return t.add(l,i,l),t.clone(l,r.center),r.radius=_,r};var B=new t;T.expand=function(e,n,r){r=T.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},T.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},T.transform=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=c.getMaximumScale(e)*t.radius,n};var z=new t;T.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,z);return t.magnitudeSquared(r)-e.radius*e.radius},T.transformWithoutScale=function(t,e,n){return a(n)||(n=new T),n.center=c.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var G=new t;T.computePlaneDistances=function(e,n,r,i){a(i)||(i=new E);var o=t.subtract(e.center,n,G),u=t.dot(r,o);return i.start=u-e.radius,i.stop=u+e.radius,i};for(var b=new t,X=new t,V=new t,q=new t,H=new t,W=new e,Y=new Array(8),k=0;k<8;++k)Y[k]=new t;var K=new o;return T.projectTo2D=function(e,n,a){n=r(n,K);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,b),s=t.cross(t.UNIT_Z,E,X);t.normalize(s,s);var c=t.cross(E,s,V);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,H),l=t.negate(s,q),R=Y,f=R[0];t.add(E,c,f),t.add(f,s,f),f=R[1],t.add(E,c,f),t.add(f,l,f),f=R[2],t.add(E,_,f),t.add(f,l,f),f=R[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=R[4],t.add(E,c,f),t.add(f,s,f),f=R[5],t.add(E,c,f),t.add(f,l,f),f=R[6],t.add(E,_,f),t.add(f,l,f),f=R[7],t.add(E,_,f),t.add(f,s,f);for(var A=R.length,h=0;h<A;++h){var N=R[h];t.add(o,N,N);var d=i.cartesianToCartographic(N,W);n.project(d,N)}a=T.fromPoints(R,a),o=a.center;var I=o.x,S=o.y,m=o.z;return o.x=m,o.y=I,o.z=S,a},T.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},T.equals=function(e,n){return e===n||a(e)&&a(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},T.prototype.intersectPlane=function(t){return T.intersectPlane(this,t)},T.prototype.distanceSquaredTo=function(t){return T.distanceSquaredTo(this,t)},T.prototype.computePlaneDistances=function(t,e,n){return T.computePlaneDistances(this,t,e,n)},T.prototype.isOccluded=function(t){return T.isOccluded(this,t)},T.prototype.equals=function(t){return T.equals(this,t)},T.prototype.clone=function(t){return T.clone(this,t)},T}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var a=0;a<r;++a)o.pack(t[a],e,2*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),i.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}), -define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,m=r(t[1]))}return S}function i(){return a()&&m}function o(){if(!e(M)&&(M=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(M=!0,O=r(t[1]))}return M}function u(){return o()&&O}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(P)){P=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(P=!0,L=r(t[1]))}return P}function l(){return T()&&L}function R(){if(!e(F)){F=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(F=!0,w=r(t[1]))}return F}function f(){return e(g)||(g=/Windows/i.test(I.appVersion)),g}function A(){return R()&&w}function h(){return e(v)||(v="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),v}function N(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(x=n)}return D}function d(){return N()?x:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,m,M,O,y,p,C,U,P,L,F,w,g,v,x,D,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:l,isFirefox:R,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(t){switch(t){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(e){return t(e)&&(e===i.UNSIGNED_BYTE||e===i.UNSIGNED_SHORT||e===i.UNSIGNED_INT)},i.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},i.createTypedArrayFromArrayBuffer=function(t,e,n,a){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,a):new Uint16Array(e,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/EllipsoidGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c,_,T,l,R){"use strict";function f(t){t=a(t,a.EMPTY_OBJECT);var e=a(t.radii,S),r=Math.round(a(t.stackPartitions,64)),i=Math.round(a(t.slicePartitions,64)),o=a(t.vertexFormat,R.DEFAULT);this._radii=n.clone(e),this._stackPartitions=r,this._slicePartitions=i,this._vertexFormat=R.clone(o),this._workerName="createEllipsoidGeometry"}var A=new n,h=new n,N=new n,d=new n,I=new n,S=new n(1,1,1),m=Math.cos,M=Math.sin;f.packedLength=n.packedLength+R.packedLength+2,f.pack=function(t,e,r){return r=a(r,0),n.pack(t._radii,e,r),r+=n.packedLength,R.pack(t._vertexFormat,e,r),r+=R.packedLength,e[r++]=t._stackPartitions,e[r]=t._slicePartitions,e};var O=new n,y=new R,p={radii:O,vertexFormat:y,stackPartitions:void 0,slicePartitions:void 0};return f.unpack=function(t,e,r){e=a(e,0);var o=n.unpack(t,e,O);e+=n.packedLength;var u=R.unpack(t,e,y);e+=R.packedLength;var E=t[e++],s=t[e];return i(r)?(r._radii=n.clone(o,r._radii),r._vertexFormat=R.clone(u,r._vertexFormat),r._stackPartitions=E,r._slicePartitions=s,r):(p.stackPartitions=E,p.slicePartitions=s,new f(p))},f.createGeometry=function(a){var i=a._radii;if(!(i.x<=0||i.y<=0||i.z<=0)){var o,R,f=u.fromCartesian3(i),S=a._vertexFormat,O=a._slicePartitions+1,y=a._stackPartitions+1,p=y*O,C=new Float64Array(3*p),U=6*(O-1)*(y-2),P=_.createTypedArray(p,U),L=S.normal?new Float32Array(3*p):void 0,F=S.tangent?new Float32Array(3*p):void 0,w=S.bitangent?new Float32Array(3*p):void 0,g=S.st?new Float32Array(2*p):void 0,v=new Array(O),x=new Array(O),D=0;for(o=0;o<O;o++){var B=T.TWO_PI*o/(O-1);v[o]=m(B),x[o]=M(B),C[D++]=0,C[D++]=0,C[D++]=i.z}for(o=1;o<y-1;o++){var z=Math.PI*o/(y-1),G=M(z),b=i.x*G,X=i.y*G,V=i.z*m(z);for(R=0;R<O;R++)C[D++]=v[R]*b,C[D++]=x[R]*X,C[D++]=V}for(o=0;o<O;o++)C[D++]=0,C[D++]=0,C[D++]=-i.z;var q=new c;S.position&&(q.position=new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:C}));var H=0,W=0,Y=0,k=0;if(S.st||S.normal||S.tangent||S.bitangent){for(o=0;o<p;o++){var K=n.fromArray(C,3*o,A),Z=f.geodeticSurfaceNormal(K,h);if(S.st){var j=e.negate(Z,I);e.magnitude(j)<T.EPSILON6&&(D=3*(o+O*Math.floor(.5*y)),D>C.length&&(D=3*(o-O*Math.floor(.5*y))),n.fromArray(C,D,j),f.geodeticSurfaceNormal(j,j),e.negate(j,j)),g[H++]=Math.atan2(j.y,j.x)/T.TWO_PI+.5,g[H++]=Math.asin(Z.z)/Math.PI+.5}if(S.normal&&(L[W++]=Z.x,L[W++]=Z.y,L[W++]=Z.z),S.tangent||S.bitangent){var Q=N;if(o<O||o>p-O-1?(n.cross(n.UNIT_X,Z,Q),n.normalize(Q,Q)):(n.cross(n.UNIT_Z,Z,Q),n.normalize(Q,Q)),S.tangent&&(F[Y++]=Q.x,F[Y++]=Q.y,F[Y++]=Q.z),S.bitangent){var J=n.cross(Z,Q,d);n.normalize(J,J),w[k++]=J.x,w[k++]=J.y,w[k++]=J.z}}}S.st&&(q.st=new s({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:g})),S.normal&&(q.normal=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:L})),S.tangent&&(q.tangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:F})),S.bitangent&&(q.bitangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:w}))}for(D=0,R=0;R<O-1;R++)P[D++]=O+R,P[D++]=O+R+1,P[D++]=R+1;var $,tt;for(o=1;o<y-2;o++)for($=o*O,tt=(o+1)*O,R=0;R<O-1;R++)P[D++]=tt+R,P[D++]=tt+R+1,P[D++]=$+R+1,P[D++]=tt+R,P[D++]=$+R+1,P[D++]=$+R;for(o=y-2,$=o*O,tt=(o+1)*O,R=0;R<O-1;R++)P[D++]=tt+R,P[D++]=$+R+1,P[D++]=$+R;return new E({attributes:q,indices:P,primitiveType:l.TRIANGLES,boundingSphere:t.fromEllipsoid(f)})}},f}),define("Core/SphereGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipsoidGeometry","./VertexFormat"],function(t,e,n,r,a,i){"use strict";function o(e){var r=n(e.radius,1),i=new t(r,r,r),o={radii:i,stackPartitions:e.stackPartitions,slicePartitions:e.slicePartitions,vertexFormat:e.vertexFormat};this._ellipsoidGeometry=new a(o),this._workerName="createSphereGeometry"}o.packedLength=a.packedLength,o.pack=function(t,e,n){return a.pack(t._ellipsoidGeometry,e,n)};var u=new a,E={radius:void 0,radii:new t,vertexFormat:new i,stackPartitions:void 0,slicePartitions:void 0};return o.unpack=function(e,n,s){var c=a.unpack(e,n,u);return E.vertexFormat=i.clone(c._vertexFormat,E.vertexFormat),E.stackPartitions=c._stackPartitions,E.slicePartitions=c._slicePartitions,r(s)?(t.clone(c._radii,E.radii),s._ellipsoidGeometry=new a(E),s):(E.radius=c._radii.x,new o(E))},o.createGeometry=function(t){return a.createGeometry(t._ellipsoidGeometry)},o}),define("Workers/createSphereGeometry",["../Core/defined","../Core/SphereGeometry"],function(t,e){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function t(t){return void 0!==t&&null!==t}return t}),define("Core/DeveloperError",["./defined"],function(t){"use strict";function e(t){this.name="DeveloperError",this.message=t;var e;try{throw new Error}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e.throwInstantiationError=function(){throw new e("This function defines an interface and should not be called directly.")},e}),define("Core/Check",["./defined","./DeveloperError"],function(t,e){"use strict";function n(t){return t+" is required, actual value was undefined"}function r(t,e,n){return"Expected "+n+" to be typeof "+e+", actual typeof was "+t}var a={};return a.typeOf={},a.defined=function(r,a){if(!t(a))throw new e(n(r))},a.typeOf.func=function(t,n){if("function"!=typeof n)throw new e(r(typeof n,"function",t))},a.typeOf.string=function(t,n){if("string"!=typeof n)throw new e(r(typeof n,"string",t))},a.typeOf.number=function(t,n){if("number"!=typeof n)throw new e(r(typeof n,"number",t))},a.typeOf.number.lessThan=function(t,n,r){if(a.typeOf.number(t,n),n>=r)throw new e("Expected "+t+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n>r)throw new e("Expected "+t+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(t,n,r){if(a.typeOf.number(t,n),n<=r)throw new e("Expected "+t+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(t,n,r){if(a.typeOf.number(t,n),n<r)throw new e("Expected "+t+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(t,n){if("object"!=typeof n)throw new e(r(typeof n,"object",t))},a.typeOf.bool=function(t,n){if("boolean"!=typeof n)throw new e(r(typeof n,"boolean",t))},a.typeOf.number.equals=function(t,n,r,i){if(a.typeOf.number(t,r),a.typeOf.number(n,i),r!==i)throw new e(t+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(t){"use strict";var e=Object.freeze;return t(e)||(e=function(t){return t}),e}),define("Core/defaultValue",["./freezeObject"],function(t){"use strict";function e(t,e){return void 0!==t&&null!==t?t:e}return e.EMPTY_OBJECT=t({}),e}),define("ThirdParty/mersenne-twister",[],function(){var t=function(t){void 0==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(t)};return t.prototype.init_genrand=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti<this.N;this.mti++){var t=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.genrand_int32=function(){var t,e=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^t>>>1^e[1&t];for(;n<this.N-1;n++)t=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^t>>>1^e[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^e[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},t.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},t}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(t,e,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(t){return t>0?1:t<0?-1:0},a.signNotZero=function(t){return t<0?-1:1},a.toSNorm=function(t,n){return n=e(n,255),Math.round((.5*a.clamp(t,-1,1)+.5)*n)},a.fromSNorm=function(t,n){return n=e(n,255),a.clamp(t,0,n)/n*2-1},a.sinh=function(t){return.5*(Math.pow(Math.E,t)-Math.pow(Math.E,-1*t))},a.cosh=function(t){return.5*(Math.pow(Math.E,t)+Math.pow(Math.E,-1*t))},a.lerp=function(t,e,n){return(1-n)*t+n*e},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(t){return t*a.RADIANS_PER_DEGREE},a.toDegrees=function(t){return t*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(t){var e=a.TWO_PI,n=t-Math.floor(t/e)*e;return n<-Math.PI?n+e:n>=Math.PI?n-e:n},a.clampToLatitudeRange=function(t){return a.clamp(t,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(t){return a.zeroToTwoPi(t+a.PI)-a.PI},a.zeroToTwoPi=function(t){var e=a.mod(t,a.TWO_PI);return Math.abs(e)<a.EPSILON14&&Math.abs(t)>a.EPSILON14?a.TWO_PI:e},a.mod=function(t,e){return(t%e+e)%e},a.equalsEpsilon=function(t,n,r,a){a=e(a,r);var i=Math.abs(t-n);return i<=a||i<=r*Math.max(Math.abs(t),Math.abs(n))};var i=[1];a.factorial=function(t){var e=i.length;if(t>=e)for(var n=i[e-1],r=e;r<=t;r++)i.push(n*r);return i[t]},a.incrementWrap=function(t,n,r){return r=e(r,0),++t,t>n&&(t=r),t},a.isPowerOfTwo=function(t){return 0!==t&&0==(t&t-1)},a.nextPowerOfTwo=function(t){return--t,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},a.clamp=function(t,e,n){return t<e?e:t>n?n:t};var o=new t;return a.setRandomNumberSeed=function(e){o=new t(e)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(t,e){return a.nextRandomNumber()*(e-t)+t},a.acosClamped=function(t){return Math.acos(a.clamp(t,-1,1))},a.asinClamped=function(t){return Math.asin(a.clamp(t,-1,1))},a.chordLength=function(t,e){return 2*e*Math.sin(.5*t)},a.logBase=function(t,e){return Math.log(t)/Math.log(e)},a.fog=function(t,e){var n=t*e;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0)}o.fromSpherical=function(t,r){n(r)||(r=new o);var a=t.clock,i=t.cone,u=e(t.magnitude,1),E=u*Math.sin(i);return r.x=E*Math.cos(a),r.y=E*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(t,e,r,a){return n(a)?(a.x=t,a.y=e,a.z=r,a):new o(t,e,r)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e):new o(t.x,t.y,t.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r]=t.z,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=3*r:e=new Array(3*r);for(var a=0;a<r;++a)o.pack(t[a],e,3*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/3:e=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){o.normalize(t,s),o.normalize(e,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Z,e):n.y<=n.z?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_Z,e)},o.projectVector=function(t,e,n){var r=o.dot(t,e)/o.dot(e,e);return o.multiplyByScalar(e,r,n)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)},o.cross=function(t,e,n){var r=t.x,a=t.y,i=t.z,o=e.x,u=e.y,E=e.z,s=a*E-i*u,c=i*o-r*E,_=r*u-a*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(t,e,n,r,a){return t=i.toRadians(t),e=i.toRadians(e),o.fromRadians(t,e,n,r,a)};var T=new o,l=new o,R=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(t,r,a,i,u){a=e(a,0);var E=n(i)?i.radiiSquared:R,s=Math.cos(r);T.x=s*Math.cos(t),T.y=s*Math.sin(t),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,l);var c=Math.sqrt(o.dot(T,l));return l=o.divideByScalar(l,c,l),T=o.multiplyByScalar(T,a,T),n(u)||(u=new o),o.add(l,T,u)},o.fromDegreesArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromDegrees(u,E,0,e,r[s])}return r},o.fromRadiansArray=function(t,e,r){var a=t.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=t[i],E=t[i+1],s=i/2;r[s]=o.fromRadians(u,E,0,e,r[s])}return r},o.fromDegreesArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromDegrees(u,E,s,e,r[c])}return r},o.fromRadiansArrayHeights=function(t,e,r){var a=t.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=t[i],E=t[i+1],s=t[i+2],c=i/3;r[c]=o.fromRadians(u,E,s,e,r[c])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(t,e,n,r){"use strict";function a(n,a,u,E,s){var c=n.x,_=n.y,T=n.z,l=a.x,R=a.y,f=a.z,A=c*c*l*l,h=_*_*R*R,d=T*T*f*f,N=A+h+d,I=Math.sqrt(1/N),S=t.multiplyByScalar(n,I,i);if(N<E)return isFinite(I)?t.clone(S,s):void 0;var m=u.x,O=u.y,M=u.z,y=o;y.x=S.x*m*2,y.y=S.y*O*2,y.z=S.z*M*2;var p,C,U,P,L,F,w,g,v,x,D,B=(1-I)*t.magnitude(n)/(.5*t.magnitude(y)),z=0;do{B-=z,U=1/(1+B*m),P=1/(1+B*O),L=1/(1+B*M),F=U*U,w=P*P,g=L*L,v=F*U,x=w*P,D=g*L,p=A*F+h*w+d*g-1,C=A*v*m+h*x*O+d*D*M;z=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return e(s)?(s.x=c*U,s.y=_*P,s.z=T*L,s):new t(c*U,_*P,T*L)}var i=new t,o=new t;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o){"use strict";function u(t,e,r){this.longitude=n(t,0),this.latitude=n(e,0),this.height=n(r,0)}u.fromRadians=function(t,e,a,i){return a=n(a,0),r(i)?(i.longitude=t,i.latitude=e,i.height=a,i):new u(t,e,a)},u.fromDegrees=function(t,e,n,r){return t=i.toRadians(t),e=i.toRadians(e),u.fromRadians(t,e,n,r)};var E=new t,s=new t,c=new t,_=new t(1/6378137,1/6378137,1/6356752.314245179),T=new t(1/40680631590769,1/40680631590769,1/40408299984661.445),l=i.EPSILON1;return u.fromCartesian=function(e,n,a){var R=r(n)?n.oneOverRadii:_,f=r(n)?n.oneOverRadiiSquared:T,A=r(n)?n._centerToleranceSquared:l,h=o(e,R,f,A,s);if(r(h)){var d=t.multiplyComponents(h,f,E);d=t.normalize(d,d);var N=t.subtract(e,h,c),I=Math.atan2(d.y,d.x),S=Math.asin(d.z),m=i.sign(t.dot(N,e))*t.magnitude(N);return r(a)?(a.longitude=I,a.latitude=S,a.height=m,a):new u(I,S,m)}},u.toCartesian=function(e,n,r){return t.fromRadians(e.longitude,e.latitude,e.height,n,r)},u.clone=function(t,e){if(r(t))return r(e)?(e.longitude=t.longitude,e.latitude=t.latitude,e.height=t.height,e):new u(t.longitude,t.latitude,t.height)},u.equals=function(t,e){return t===e||r(t)&&r(e)&&t.longitude===e.longitude&&t.latitude===e.latitude&&t.height===e.height},u.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t.longitude-e.longitude)<=n&&Math.abs(t.latitude-e.latitude)<=n&&Math.abs(t.height-e.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(t){return u.clone(this,t)},u.prototype.equals=function(t){return u.equals(this,t)},u.prototype.equalsEpsilon=function(t,e){return u.equalsEpsilon(this,t,e)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(t){"use strict";var e=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(t){return!1}}(),n=Object.defineProperties;return e&&t(n)||(n=function(t){return t}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(e,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),e._radii=new t(n,a,i),e._radiiSquared=new t(n*n,a*a,i*i),e._radiiToTheFourth=new t(n*n*n*n,a*a*a*a,i*i*i*i),e._oneOverRadii=new t(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),e._oneOverRadiiSquared=new t(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),e._minimumRadius=Math.min(n,a,i),e._maximumRadius=Math.max(n,a,i),e._centerToleranceSquared=E.EPSILON1,0!==e._radiiSquared.z&&(e._squaredXOverSquaredZ=e._radiiSquared.x/e._radiiSquared.z)}function _(t,e,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,t,e,n)}i(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(e,n){if(a(e)){var r=e._radii;return a(n)?(t.clone(r,n._radii),t.clone(e._radiiSquared,n._radiiSquared),t.clone(e._radiiToTheFourth,n._radiiToTheFourth),t.clone(e._oneOverRadii,n._oneOverRadii),t.clone(e._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=e._minimumRadius,n._maximumRadius=e._maximumRadius,n._centerToleranceSquared=e._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(t,e){return a(e)||(e=new _),a(t)?(c(e,t.x,t.y,t.z),e):e},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(t){return _.clone(this,t)},_.packedLength=t.packedLength,_.pack=function(e,n,a){return a=r(a,0),t.pack(e._radii,n,a),n},_.unpack=function(e,n,a){n=r(n,0);var i=t.unpack(e,n);return _.fromCartesian3(i,a)},_.prototype.geocentricSurfaceNormal=t.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(e,n){var r=e.longitude,i=e.latitude,o=Math.cos(i),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(i);return a(n)||(n=new t),n.x=u,n.y=E,n.z=s,t.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(e,n){return a(n)||(n=new t),n=t.multiplyComponents(e,this._oneOverRadiiSquared,n),t.normalize(n,n)};var T=new t,l=new t;_.prototype.cartographicToCartesian=function(e,n){var r=T,i=l;this.geodeticSurfaceNormalCartographic(e,r),t.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(t.dot(r,i));return t.divideByScalar(i,o,i),t.multiplyByScalar(r,e.height,r),a(n)||(n=new t),t.add(i,r,n)},_.prototype.cartographicArrayToCartesianArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;r++)e[r]=this.cartographicToCartesian(t[r],e[r]);return e};var R=new t,f=new t,A=new t;return _.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,f);if(a(i)){var o=this.geodeticSurfaceNormal(i,R),u=t.subtract(n,i,A),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(t.dot(u,n))*t.magnitude(u);return a(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new e(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(t,e){var n=t.length;a(e)?e.length=n:e=new Array(n);for(var r=0;r<n;++r)e[r]=this.cartesianToCartographic(t[r],e[r]);return e},_.prototype.scaleToGeodeticSurface=function(t,e){return s(t,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,e)},_.prototype.scaleToGeocentricSurface=function(e,n){a(n)||(n=new t);var r=e.x,i=e.y,o=e.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return t.multiplyByScalar(e,E,n)},_.prototype.transformPositionToScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(e,n){return a(n)||(n=new t),t.multiplyComponents(e,this._radii,n)},_.prototype.equals=function(e){return this===e||a(e)&&t.equals(this._radii,e._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(e,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new t),i.x=0,i.y=0,i.z=e.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(t,e,n,r,a,i,o){"use strict";function u(t){this._ellipsoid=n(t,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(e,n){var a=this._semimajorAxis,i=e.longitude*a,o=e.latitude*a,u=e.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new t(i,o,u)},u.prototype.unproject=function(t,n){var a=this._oneOverSemimajorAxis,i=t.x*a,o=t.y*a,u=t.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new e(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(t){"use strict";return t({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(t){"use strict";function e(e,n){this.start=t(e,0),this.stop=t(n,0)}return e}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a,i,o,u,E,s){this[0]=n(t,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(e,0),this[4]=n(i,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(t){for(var e=0,n=0;n<9;++n){var r=t[n];e+=r*r}return Math.sqrt(e)}function c(t){for(var e=0,n=0;n<3;++n){var r=t[E.getElementIndex(f[n],R[n])];e+=2*r*r}return Math.sqrt(e)}function _(t,e){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(t[E.getElementIndex(f[i],R[i])]);o>r&&(a=i,r=o)}var s=1,c=0,_=R[a],T=f[a];if(Math.abs(t[E.getElementIndex(T,_)])>n){var l,A=t[E.getElementIndex(T,T)],h=t[E.getElementIndex(_,_)],d=t[E.getElementIndex(T,_)],N=(A-h)/2/d;l=N<0?-1/(-N+Math.sqrt(1+N*N)):1/(N+Math.sqrt(1+N*N)),s=1/Math.sqrt(1+l*l),c=l*s}return e=E.clone(E.IDENTITY,e),e[E.getElementIndex(_,_)]=e[E.getElementIndex(T,T)]=s,e[E.getElementIndex(T,_)]=c,e[E.getElementIndex(_,T)]=-c,e}E.packedLength=9,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t[0],e[r++]=t[1],e[r++]=t[2],e[r++]=t[3],e[r++]=t[4],e[r++]=t[5],e[r++]=t[6],e[r++]=t[7],e[r++]=t[8],e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e++],a[1]=t[e++],a[2]=t[e++],a[3]=t[e++],a[4]=t[e++],a[5]=t[e++],a[6]=t[e++],a[7]=t[e++],a[8]=t[e++],a},E.clone=function(t,e){if(r(t))return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):new E(t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8])},E.fromArray=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a[0]=t[e],a[1]=t[e+1],a[2]=t[e+2],a[3]=t[e+3],a[4]=t[e+4],a[5]=t[e+5],a[6]=t[e+6],a[7]=t[e+7],a[8]=t[e+8],a},E.fromColumnMajorArray=function(t,e){return E.clone(t,e)},E.fromRowMajorArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],e):new E(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},E.fromQuaternion=function(t,e){var n=t.x*t.x,a=t.x*t.y,i=t.x*t.z,o=t.x*t.w,u=t.y*t.y,s=t.y*t.z,c=t.y*t.w,_=t.z*t.z,T=t.z*t.w,l=t.w*t.w,R=n-u-_+l,f=2*(a-T),A=2*(i+c),h=2*(a+T),d=-n+u-_+l,N=2*(s-o),I=2*(i-c),S=2*(s+o),m=-n-u+_+l;return r(e)?(e[0]=R,e[1]=h,e[2]=I,e[3]=f,e[4]=d,e[5]=S,e[6]=A,e[7]=N,e[8]=m,e):new E(R,f,A,h,d,N,I,S,m)},E.fromHeadingPitchRoll=function(t,e){var n=Math.cos(-t.pitch),a=Math.cos(-t.heading),i=Math.cos(t.roll),o=Math.sin(-t.pitch),u=Math.sin(-t.heading),s=Math.sin(t.roll),c=n*a,_=-i*u+s*o*a,T=s*u+i*o*a,l=n*u,R=i*a+s*o*u,f=-s*a+i*o*u,A=-o,h=s*n,d=i*n;return r(e)?(e[0]=c,e[1]=l,e[2]=A,e[3]=_,e[4]=R,e[5]=h,e[6]=T,e[7]=f,e[8]=d,e):new E(c,_,T,l,R,f,A,h,d)},E.fromScale=function(t,e){return r(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=t.y,e[5]=0,e[6]=0,e[7]=0,e[8]=t.z,e):new E(t.x,0,0,0,t.y,0,0,0,t.z)},E.fromUniformScale=function(t,e){return r(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=t,e[5]=0,e[6]=0,e[7]=0,e[8]=t,e):new E(t,0,0,0,t,0,0,0,t)},E.fromCrossProduct=function(t,e){return r(e)?(e[0]=0,e[1]=t.z,e[2]=-t.y,e[3]=-t.z,e[4]=0,e[5]=t.x,e[6]=t.y,e[7]=-t.x,e[8]=0,e):new E(0,-t.z,t.y,t.z,0,-t.x,-t.y,t.x,0)},E.fromRotationX=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=n,e[5]=a,e[6]=0,e[7]=-a,e[8]=n,e):new E(1,0,0,0,n,-a,0,a,n)},E.fromRotationY=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=0,e[2]=-a,e[3]=0,e[4]=1,e[5]=0,e[6]=a,e[7]=0,e[8]=n,e):new E(n,0,a,0,1,0,-a,0,n)},E.fromRotationZ=function(t,e){var n=Math.cos(t),a=Math.sin(t);return r(e)?(e[0]=n,e[1]=a,e[2]=0,e[3]=-a,e[4]=n,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e):new E(n,-a,0,a,n,0,0,0,1)},E.toArray=function(t,e){return r(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]]},E.getElementIndex=function(t,e){return 3*t+e},E.getColumn=function(t,e,n){var r=3*e,a=t[r],i=t[r+1],o=t[r+2];return n.x=a,n.y=i,n.z=o,n},E.setColumn=function(t,e,n,r){r=E.clone(t,r);var a=3*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},E.getRow=function(t,e,n){var r=t[e],a=t[e+3],i=t[e+6];return n.x=r,n.y=a,n.z=i,n},E.setRow=function(t,e,n,r){return r=E.clone(t,r),r[e]=n.x,r[e+3]=n.y,r[e+6]=n.z,r};var T=new t;E.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],T)),n.y=t.magnitude(t.fromElements(e[3],e[4],e[5],T)),n.z=t.magnitude(t.fromElements(e[6],e[7],e[8],T)),n};var l=new t;E.getMaximumScale=function(e){return E.getScale(e,l),t.maximumComponent(l)},E.multiply=function(t,e,n){var r=t[0]*e[0]+t[3]*e[1]+t[6]*e[2],a=t[1]*e[0]+t[4]*e[1]+t[7]*e[2],i=t[2]*e[0]+t[5]*e[1]+t[8]*e[2],o=t[0]*e[3]+t[3]*e[4]+t[6]*e[5],u=t[1]*e[3]+t[4]*e[4]+t[7]*e[5],E=t[2]*e[3]+t[5]*e[4]+t[8]*e[5],s=t[0]*e[6]+t[3]*e[7]+t[6]*e[8],c=t[1]*e[6]+t[4]*e[7]+t[7]*e[8],_=t[2]*e[6]+t[5]*e[7]+t[8]*e[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n},E.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n},E.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[3]*a+t[6]*i,u=t[1]*r+t[4]*a+t[7]*i,E=t[2]*r+t[5]*a+t[8]*i;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n},E.multiplyByScale=function(t,e,n){return n[0]=t[0]*e.x,n[1]=t[1]*e.x,n[2]=t[2]*e.x,n[3]=t[3]*e.y,n[4]=t[4]*e.y,n[5]=t[5]*e.y,n[6]=t[6]*e.z,n[7]=t[7]*e.z,n[8]=t[8]*e.z,n},E.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e},E.transpose=function(t,e){var n=t[0],r=t[3],a=t[6],i=t[1],o=t[4],u=t[7],E=t[2],s=t[5],c=t[8];return e[0]=n,e[1]=r,e[2]=a,e[3]=i,e[4]=o,e[5]=u,e[6]=E,e[7]=s,e[8]=c,e};var R=[1,0,0],f=[2,2,1],A=new E,h=new E;return E.computeEigenDecomposition=function(t,e){var n=u.EPSILON20,a=0,i=0;r(e)||(e={});for(var o=e.unitary=E.clone(E.IDENTITY,e.unitary),T=e.diagonal=E.clone(t,e.diagonal),l=n*s(T);i<10&&c(T)>l;)_(T,A),E.transpose(A,h),E.multiply(T,A,T),E.multiply(h,T,T),E.multiply(o,A,o),++a>2&&(++i,a=0);return e},E.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e},E.determinant=function(t){var e=t[0],n=t[3],r=t[6],a=t[1],i=t[4],o=t[7],u=t[2],E=t[5],s=t[8];return e*(i*s-E*o)+a*(E*r-n*s)+u*(n*o-i*r)},E.inverse=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[3],o=t[4],u=t[5],s=t[6],c=t[7],_=t[8],T=E.determinant(t);e[0]=o*_-c*u,e[1]=c*a-r*_,e[2]=r*u-o*a,e[3]=s*u-i*_,e[4]=n*_-s*a,e[5]=i*a-n*u,e[6]=i*c-s*o,e[7]=s*r-n*c,e[8]=n*o-i*r;var l=1/T;return E.multiplyByScalar(e,l,e)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]},E.equalsEpsilon=function(t,e,n){return t===e||r(t)&&r(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,a(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]},E.prototype.equalsEpsilon=function(t,e){return E.equalsEpsilon(this,t,e)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n,r,a){this.x=e(t,0),this.y=e(n,0),this.z=e(r,0),this.w=e(a,0)}o.fromElements=function(t,e,r,a,i){return n(i)?(i.x=t,i.y=e,i.z=r,i.w=a,i):new o(t,e,r,a)},o.fromColor=function(t,e){return n(e)?(e.x=t.red,e.y=t.green,e.z=t.blue,e.w=t.alpha,e):new o(t.red,t.green,t.blue,t.alpha)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e):new o(t.x,t.y,t.z,t.w)},o.packedLength=4,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r++]=t.y,n[r++]=t.z,n[r]=t.w,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r++],a.z=t[r++],a.w=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=4*r:e=new Array(4*r);for(var a=0;a<r;++a)o.pack(t[a],e,4*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/4:e=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y,t.z,t.w)},o.minimumComponent=function(t){return Math.min(t.x,t.y,t.z,t.w)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.z=Math.min(t.z,e.z),n.w=Math.min(t.w,e.w),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n.z=Math.max(t.z,e.z),n.w=Math.max(t.w,e.w),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y+t.z*t.z+t.w*t.w},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e.z=t.z/n,e.w=t.w/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y+t.z*e.z+t.w*e.w},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n.z=t.z*e.z,n.w=t.w*e.w,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n.z=t.z/e.z,n.w=t.w/e.w,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n.z=t.z+e.z,n.w=t.w+e.w,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n.z=t.z-e.z,n.w=t.w-e.w,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n.z=t.z*e,n.w=t.w*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n.z=t.z/e,n.w=t.w/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e.z=-t.z,e.w=-t.w,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e.z=Math.abs(t.z),e.w=Math.abs(t.w),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,s);return o.abs(n,n),e=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,e):o.clone(o.UNIT_W,e):n.z<=n.w?o.clone(o.UNIT_Z,e):o.clone(o.UNIT_W,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y&&t.z===e.z&&t.w===e.w},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]&&t.z===e[n+2]&&t.w===e[n+3]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)&&i.equalsEpsilon(t.z,e.z,r,a)&&i.equalsEpsilon(t.w,e.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(t){"use strict";function e(t){this.name="RuntimeError",this.message=t;var e;try{throw new Error +}catch(t){e=t.stack}this.stack=e}return t(Object.create)&&(e.prototype=Object.create(Error.prototype),e.prototype.constructor=e),e.prototype.toString=function(){var e=this.name+": "+this.message;return t(this.stack)&&(e+="\n"+this.stack.toString()),e},e}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(t,e,n,r,a,i,o,u,E,s){"use strict";function c(t,e,n,a,i,o,u,E,s,c,_,T,l,R,f,A){this[0]=r(t,0),this[1]=r(i,0),this[2]=r(s,0),this[3]=r(l,0),this[4]=r(e,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(R,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(f,0),this[12]=r(a,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(A,0)}c.packedLength=16,c.pack=function(t,e,n){return n=r(n,0),e[n++]=t[0],e[n++]=t[1],e[n++]=t[2],e[n++]=t[3],e[n++]=t[4],e[n++]=t[5],e[n++]=t[6],e[n++]=t[7],e[n++]=t[8],e[n++]=t[9],e[n++]=t[10],e[n++]=t[11],e[n++]=t[12],e[n++]=t[13],e[n++]=t[14],e[n]=t[15],e},c.unpack=function(t,e,n){return e=r(e,0),a(n)||(n=new c),n[0]=t[e++],n[1]=t[e++],n[2]=t[e++],n[3]=t[e++],n[4]=t[e++],n[5]=t[e++],n[6]=t[e++],n[7]=t[e++],n[8]=t[e++],n[9]=t[e++],n[10]=t[e++],n[11]=t[e++],n[12]=t[e++],n[13]=t[e++],n[14]=t[e++],n[15]=t[e],n},c.clone=function(t,e){if(a(t))return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):new c(t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(t,e){return c.clone(t,e)},c.fromRowMajorArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15],e):new c(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},c.fromRotationTranslation=function(e,n,i){return n=r(n,t.ZERO),a(i)?(i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=0,i[4]=e[3],i[5]=e[4],i[6]=e[5],i[7]=0,i[8]=e[6],i[9]=e[7],i[10]=e[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new c(e[0],e[3],e[6],n.x,e[1],e[4],e[7],n.y,e[2],e[5],e[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(t,e,n,r){a(r)||(r=new c);var i=n.x,o=n.y,u=n.z,E=e.x*e.x,s=e.x*e.y,_=e.x*e.z,T=e.x*e.w,l=e.y*e.y,R=e.y*e.z,f=e.y*e.w,A=e.z*e.z,h=e.z*e.w,d=e.w*e.w,N=E-l-A+d,I=2*(s-h),S=2*(_+f),m=2*(s+h),O=-E+l-A+d,M=2*(R-T),y=2*(_-f),p=2*(R+T),C=-E-l+A+d;return r[0]=N*i,r[1]=m*i,r[2]=y*i,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=M*u,r[10]=C*u,r[11]=0,r[12]=t.x,r[13]=t.y,r[14]=t.z,r[15]=1,r},c.fromTranslationRotationScale=function(t,e){return c.fromTranslationQuaternionRotationScale(t.translation,t.rotation,t.scale,e)},c.fromTranslation=function(t,e){return c.fromRotationTranslation(E.IDENTITY,t,e)},c.fromScale=function(t,e){return a(e)?(e[0]=t.x,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t.y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t.z,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t.x,0,0,0,0,t.y,0,0,0,0,t.z,0,0,0,0,1)},c.fromUniformScale=function(t,e){return a(e)?(e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):new c(t,0,0,0,0,t,0,0,0,0,t,0,0,0,0,1)};var _=new t,T=new t,l=new t;c.fromCamera=function(e,n){var r=e.position,i=e.direction,o=e.up;t.normalize(i,_),t.normalize(t.cross(_,o,T),T),t.normalize(t.cross(T,_,l),l);var u=T.x,E=T.y,s=T.z,R=_.x,f=_.y,A=_.z,h=l.x,d=l.y,N=l.z,I=r.x,S=r.y,m=r.z,O=u*-I+E*-S+s*-m,M=h*-I+d*-S+N*-m,y=R*I+f*S+A*m;return a(n)?(n[0]=u,n[1]=h,n[2]=-R,n[3]=0,n[4]=E,n[5]=d,n[6]=-f,n[7]=0,n[8]=s,n[9]=N,n[10]=-A,n[11]=0,n[12]=O,n[13]=M,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,d,N,M,-R,-f,-A,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(t,e,n,r,a){var i=Math.tan(.5*t),o=1/i,u=o/e,E=(r+n)/(n-r),s=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=-1,a[12]=0,a[13]=0,a[14]=s,a[15]=0,a},c.computeOrthographicOffCenter=function(t,e,n,r,a,i,o){var u=1/(e-t),E=1/(r-n),s=1/(i-a),c=-(e+t)*u,_=-(r+n)*E,T=-(i+a)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(t,e,n,r,a,i,o){var u=2*a/(e-t),E=2*a/(r-n),s=(e+t)/(e-t),c=(r+n)/(r-n),_=-(i+a)/(i-a),T=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(t,e,n,r,a,i){var o=2*a/(e-t),u=2*a/(r-n),E=(e+t)/(e-t),s=(r+n)/(r-n),c=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=E,i[9]=s,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},c.computeViewportTransformation=function(t,e,n,a){t=r(t,r.EMPTY_OBJECT);var i=r(t.x,0),o=r(t.y,0),u=r(t.width,0),E=r(t.height,0);e=r(e,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-e),T=s,l=c,R=_,f=i+s,A=o+c,h=e+_;return a[0]=T,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=l,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=R,a[11]=0,a[12]=f,a[13]=A,a[14]=h,a[15]=1,a},c.computeView=function(e,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-t.dot(a,e),i[13]=-t.dot(r,e),i[14]=t.dot(n,e),i[15]=1,i},c.toArray=function(t,e){return a(e)?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e):[t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15]]},c.getElementIndex=function(t,e){return 4*t+e},c.getColumn=function(t,e,n){var r=4*e,a=t[r],i=t[r+1],o=t[r+2],u=t[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},c.setColumn=function(t,e,n,r){r=c.clone(t,r);var a=4*e;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},c.setTranslation=function(t,e,n){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=e.x,n[13]=e.y,n[14]=e.z,n[15]=t[15],n},c.getRow=function(t,e,n){var r=t[e],a=t[e+4],i=t[e+8],o=t[e+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},c.setRow=function(t,e,n,r){return r=c.clone(t,r),r[e]=n.x,r[e+4]=n.y,r[e+8]=n.z,r[e+12]=n.w,r};var R=new t;c.getScale=function(e,n){return n.x=t.magnitude(t.fromElements(e[0],e[1],e[2],R)),n.y=t.magnitude(t.fromElements(e[4],e[5],e[6],R)),n.z=t.magnitude(t.fromElements(e[8],e[9],e[10],R)),n};var f=new t;c.getMaximumScale=function(e){return c.getScale(e,f),t.maximumComponent(f)},c.multiply=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[3],u=t[4],E=t[5],s=t[6],c=t[7],_=t[8],T=t[9],l=t[10],R=t[11],f=t[12],A=t[13],h=t[14],d=t[15],N=e[0],I=e[1],S=e[2],m=e[3],O=e[4],M=e[5],y=e[6],p=e[7],C=e[8],U=e[9],P=e[10],L=e[11],F=e[12],w=e[13],g=e[14],v=e[15],x=r*N+u*I+_*S+f*m,D=a*N+E*I+T*S+A*m,B=i*N+s*I+l*S+h*m,z=o*N+c*I+R*S+d*m,G=r*O+u*M+_*y+f*p,b=a*O+E*M+T*y+A*p,X=i*O+s*M+l*y+h*p,V=o*O+c*M+R*y+d*p,q=r*C+u*U+_*P+f*L,H=a*C+E*U+T*P+A*L,W=i*C+s*U+l*P+h*L,Y=o*C+c*U+R*P+d*L,k=r*F+u*w+_*g+f*v,K=a*F+E*w+T*g+A*v,Z=i*F+s*w+l*g+h*v,j=o*F+c*w+R*g+d*v;return n[0]=x,n[1]=D,n[2]=B,n[3]=z,n[4]=G,n[5]=b,n[6]=X,n[7]=V,n[8]=q,n[9]=H,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(t,e,n){return n[0]=t[0]+e[0],n[1]=t[1]+e[1],n[2]=t[2]+e[2],n[3]=t[3]+e[3],n[4]=t[4]+e[4],n[5]=t[5]+e[5],n[6]=t[6]+e[6],n[7]=t[7]+e[7],n[8]=t[8]+e[8],n[9]=t[9]+e[9],n[10]=t[10]+e[10],n[11]=t[11]+e[11],n[12]=t[12]+e[12],n[13]=t[13]+e[13],n[14]=t[14]+e[14],n[15]=t[15]+e[15],n},c.subtract=function(t,e,n){return n[0]=t[0]-e[0],n[1]=t[1]-e[1],n[2]=t[2]-e[2],n[3]=t[3]-e[3],n[4]=t[4]-e[4],n[5]=t[5]-e[5],n[6]=t[6]-e[6],n[7]=t[7]-e[7],n[8]=t[8]-e[8],n[9]=t[9]-e[9],n[10]=t[10]-e[10],n[11]=t[11]-e[11],n[12]=t[12]-e[12],n[13]=t[13]-e[13],n[14]=t[14]-e[14],n[15]=t[15]-e[15],n},c.multiplyTransformation=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=t[12],l=t[13],R=t[14],f=e[0],A=e[1],h=e[2],d=e[4],N=e[5],I=e[6],S=e[8],m=e[9],O=e[10],M=e[12],y=e[13],p=e[14],C=r*f+o*A+s*h,U=a*f+u*A+c*h,P=i*f+E*A+_*h,L=r*d+o*N+s*I,F=a*d+u*N+c*I,w=i*d+E*N+_*I,g=r*S+o*m+s*O,v=a*S+u*m+c*O,x=i*S+E*m+_*O,D=r*M+o*y+s*p+T,B=a*M+u*y+c*p+l,z=i*M+E*y+_*p+R;return n[0]=C,n[1]=U,n[2]=P,n[3]=0,n[4]=L,n[5]=F,n[6]=w,n[7]=0,n[8]=g,n[9]=v,n[10]=x,n[11]=0,n[12]=D,n[13]=B,n[14]=z,n[15]=1,n},c.multiplyByMatrix3=function(t,e,n){var r=t[0],a=t[1],i=t[2],o=t[4],u=t[5],E=t[6],s=t[8],c=t[9],_=t[10],T=e[0],l=e[1],R=e[2],f=e[3],A=e[4],h=e[5],d=e[6],N=e[7],I=e[8],S=r*T+o*l+s*R,m=a*T+u*l+c*R,O=i*T+E*l+_*R,M=r*f+o*A+s*h,y=a*f+u*A+c*h,p=i*f+E*A+_*h,C=r*d+o*N+s*I,U=a*d+u*N+c*I,P=i*d+E*N+_*I;return n[0]=S,n[1]=m,n[2]=O,n[3]=0,n[4]=M,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=P,n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},c.multiplyByTranslation=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=r*t[0]+a*t[4]+i*t[8]+t[12],u=r*t[1]+a*t[5]+i*t[9]+t[13],E=r*t[2]+a*t[6]+i*t[10]+t[14];return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=o,n[13]=u,n[14]=E,n[15]=t[15],n};var A=new t;c.multiplyByUniformScale=function(t,e,n){return A.x=e,A.y=e,A.z=e,c.multiplyByScale(t,A,n)},c.multiplyByScale=function(t,e,n){var r=e.x,a=e.y,i=e.z;return 1===r&&1===a&&1===i?c.clone(t,n):(n[0]=r*t[0],n[1]=r*t[1],n[2]=r*t[2],n[3]=0,n[4]=a*t[4],n[5]=a*t[5],n[6]=a*t[6],n[7]=0,n[8]=i*t[8],n[9]=i*t[9],n[10]=i*t[10],n[11]=0,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=1,n)},c.multiplyByVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t[0]*r+t[4]*a+t[8]*i+t[12]*o,E=t[1]*r+t[5]*a+t[9]*i+t[13]*o,s=t[2]*r+t[6]*a+t[10]*i+t[14]*o,c=t[3]*r+t[7]*a+t[11]*i+t[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i,u=t[1]*r+t[5]*a+t[9]*i,E=t[2]*r+t[6]*a+t[10]*i;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(t,e,n){var r=e.x,a=e.y,i=e.z,o=t[0]*r+t[4]*a+t[8]*i+t[12],u=t[1]*r+t[5]*a+t[9]*i+t[13],E=t[2]*r+t[6]*a+t[10]*i+t[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(t,e,n){return n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*e,n[9]=t[9]*e,n[10]=t[10]*e,n[11]=t[11]*e,n[12]=t[12]*e,n[13]=t[13]*e,n[14]=t[14]*e,n[15]=t[15]*e,n},c.negate=function(t,e){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=-t[7],e[8]=-t[8],e[9]=-t[9],e[10]=-t[10],e[11]=-t[11],e[12]=-t[12],e[13]=-t[13],e[14]=-t[14],e[15]=-t[15],e},c.transpose=function(t,e){var n=t[1],r=t[2],a=t[3],i=t[6],o=t[7],u=t[11];return e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[10]=t[10],e[11]=t[14],e[12]=a,e[13]=o,e[14]=u,e[15]=t[15],e},c.abs=function(t,e){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e[4]=Math.abs(t[4]),e[5]=Math.abs(t[5]),e[6]=Math.abs(t[6]),e[7]=Math.abs(t[7]),e[8]=Math.abs(t[8]),e[9]=Math.abs(t[9]),e[10]=Math.abs(t[10]),e[11]=Math.abs(t[11]),e[12]=Math.abs(t[12]),e[13]=Math.abs(t[13]),e[14]=Math.abs(t[14]),e[15]=Math.abs(t[15]),e},c.equals=function(t,e){return t===e||a(t)&&a(e)&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[3]===e[3]&&t[7]===e[7]&&t[11]===e[11]&&t[15]===e[15]},c.equalsEpsilon=function(t,e,n){return t===e||a(t)&&a(e)&&Math.abs(t[0]-e[0])<=n&&Math.abs(t[1]-e[1])<=n&&Math.abs(t[2]-e[2])<=n&&Math.abs(t[3]-e[3])<=n&&Math.abs(t[4]-e[4])<=n&&Math.abs(t[5]-e[5])<=n&&Math.abs(t[6]-e[6])<=n&&Math.abs(t[7]-e[7])<=n&&Math.abs(t[8]-e[8])<=n&&Math.abs(t[9]-e[9])<=n&&Math.abs(t[10]-e[10])<=n&&Math.abs(t[11]-e[11])<=n&&Math.abs(t[12]-e[12])<=n&&Math.abs(t[13]-e[13])<=n&&Math.abs(t[14]-e[14])<=n&&Math.abs(t[15]-e[15])<=n},c.getTranslation=function(t,e){return e.x=t[12],e.y=t[13],e.z=t[14],e},c.getRotation=function(t,e){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e};var h=new E,d=new E,N=new e,I=new e(0,0,0,1);return c.inverse=function(t,n){if(E.equalsEpsilon(c.getRotation(t,h),d,u.EPSILON7)&&e.equals(c.getRow(t,3,N),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=1,n;var r=t[0],a=t[4],i=t[8],o=t[12],_=t[1],T=t[5],l=t[9],R=t[13],f=t[2],A=t[6],S=t[10],m=t[14],O=t[3],M=t[7],y=t[11],p=t[15],C=S*p,U=m*y,P=A*p,L=m*M,F=A*y,w=S*M,g=f*p,v=m*O,x=f*y,D=S*O,B=f*M,z=A*O,G=C*T+L*l+F*R-(U*T+P*l+w*R),b=U*_+g*l+D*R-(C*_+v*l+x*R),X=P*_+v*T+B*R-(L*_+g*T+z*R),V=w*_+x*T+z*l-(F*_+D*T+B*l),q=U*a+P*i+w*o-(C*a+L*i+F*o),H=C*r+v*i+x*o-(U*r+g*i+D*o),W=L*r+g*a+z*o-(P*r+v*a+B*o),Y=F*r+D*a+B*i-(w*r+x*a+z*i);C=i*R,U=o*l,P=a*R,L=o*T,F=a*l,w=i*T,g=r*R,v=o*_,x=r*l,D=i*_,B=r*T,z=a*_;var k=C*M+L*y+F*p-(U*M+P*y+w*p),K=U*O+g*y+D*p-(C*O+v*y+x*p),Z=P*O+v*M+B*p-(L*O+g*M+z*p),j=w*O+x*M+z*y-(F*O+D*M+B*y),Q=P*S+w*m+U*A-(F*m+C*A+L*S),J=x*m+C*f+v*S-(g*S+D*m+U*f),$=g*A+z*m+L*f-(B*m+P*f+v*A),tt=B*S+F*f+D*A-(x*A+z*S+w*f),et=r*G+a*b+i*X+o*V;if(Math.abs(et)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return et=1/et,n[0]=G*et,n[1]=b*et,n[2]=X*et,n[3]=V*et,n[4]=q*et,n[5]=H*et,n[6]=W*et,n[7]=Y*et,n[8]=k*et,n[9]=K*et,n[10]=Z*et,n[11]=j*et,n[12]=Q*et,n[13]=J*et,n[14]=$*et,n[15]=tt*et,n},c.inverseTransformation=function(t,e){var n=t[0],r=t[1],a=t[2],i=t[4],o=t[5],u=t[6],E=t[8],s=t[9],c=t[10],_=t[12],T=t[13],l=t[14],R=-n*_-r*T-a*l,f=-i*_-o*T-u*l,A=-E*_-s*T-c*l;return e[0]=n,e[1]=i,e[2]=E,e[3]=0,e[4]=r,e[5]=o,e[6]=s,e[7]=0,e[8]=a,e[9]=u,e[10]=c,e[11]=0,e[12]=R,e[13]=f,e[14]=A,e[15]=1,e},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,i(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(t){return c.clone(this,t)},c.prototype.equals=function(t){return c.equals(this,t)},c.equalsArray=function(t,e,n){return t[0]===e[n]&&t[1]===e[n+1]&&t[2]===e[n+2]&&t[3]===e[n+3]&&t[4]===e[n+4]&&t[5]===e[n+5]&&t[6]===e[n+6]&&t[7]===e[n+7]&&t[8]===e[n+8]&&t[9]===e[n+9]&&t[10]===e[n+10]&&t[11]===e[n+11]&&t[12]===e[n+12]&&t[13]===e[n+13]&&t[14]===e[n+14]&&t[15]===e[n+15]},c.prototype.equalsEpsilon=function(t,e){return c.equalsEpsilon(this,t,e)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(t,e,n,r,a,i,o,u){"use strict";function E(t,e,r,a){this.west=n(t,0),this.south=n(e,0),this.east=n(r,0),this.north=n(a,0)}a(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(t,e,r){return r=n(r,0),e[r++]=t.west,e[r++]=t.south,e[r++]=t.east,e[r]=t.north,e},E.unpack=function(t,e,a){return e=n(e,0),r(a)||(a=new E),a.west=t[e++],a.south=t[e++],a.east=t[e++],a.north=t[e],a},E.computeWidth=function(t){var e=t.east,n=t.west;return e<n&&(e+=u.TWO_PI),e-n},E.computeHeight=function(t){return t.north-t.south},E.fromDegrees=function(t,e,a,i,o){return t=u.toRadians(n(t,0)),e=u.toRadians(n(e,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=t,o.south=e,o.east=a,o.north=i,o):new E(t,e,a,i)},E.fromRadians=function(t,e,a,i,o){return r(o)?(o.west=n(t,0),o.south=n(e,0),o.east=n(a,0),o.north=n(i,0),o):new E(t,e,a,i)},E.fromCartographicArray=function(t,e){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=t.length;_<T;_++){var l=t[_];n=Math.min(n,l.longitude),a=Math.max(a,l.longitude),s=Math.min(s,l.latitude),c=Math.max(c,l.latitude);var R=l.longitude>=0?l.longitude:l.longitude+u.TWO_PI;i=Math.min(i,R),o=Math.max(o,R)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(e)?(e.west=n,e.south=s,e.east=a,e.north=c,e):new E(n,s,a,c)},E.fromCartesianArray=function(t,e,a){e=n(e,i.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,l=-Number.MAX_VALUE,R=0,f=t.length;R<f;R++){var A=e.cartesianToCartographic(t[R]);o=Math.min(o,A.longitude),s=Math.max(s,A.longitude),T=Math.min(T,A.latitude),l=Math.max(l,A.latitude);var h=A.longitude>=0?A.longitude:A.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=T,a.east=s,a.north=l,a):new E(o,T,s,l)},E.clone=function(t,e){if(r(t))return r(e)?(e.west=t.west,e.south=t.south,e.east=t.east,e.north=t.north,e):new E(t.west,t.south,t.east,t.north)},E.prototype.clone=function(t){return E.clone(this,t)},E.prototype.equals=function(t){return E.equals(this,t)},E.equals=function(t,e){return t===e||r(t)&&r(e)&&t.west===e.west&&t.south===e.south&&t.east===e.east&&t.north===e.north},E.prototype.equalsEpsilon=function(t,e){return r(t)&&Math.abs(this.west-t.west)<=e&&Math.abs(this.south-t.south)<=e&&Math.abs(this.east-t.east)<=e&&Math.abs(this.north-t.north)<=e},E.validate=function(t){},E.southwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.south,n.height=0,n):new t(e.west,e.south)},E.northwest=function(e,n){return r(n)?(n.longitude=e.west,n.latitude=e.north,n.height=0,n):new t(e.west,e.north)},E.northeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.north,n.height=0,n):new t(e.east,e.north)},E.southeast=function(e,n){return r(n)?(n.longitude=e.east,n.latitude=e.south,n.height=0,n):new t(e.east,e.south)},E.center=function(e,n){var a=e.east,i=e.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),E=.5*(e.south+e.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new t(o,E)},E.intersection=function(t,e,n){var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.negativePiToPi(Math.max(i,s)),_=u.negativePiToPi(Math.min(a,o));if(!((t.west<t.east||e.west<e.east)&&_<=c)){var T=Math.max(t.south,e.south),l=Math.min(t.north,e.north);if(!(T>=l))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=l,n):new E(c,T,_,l)}},E.simpleIntersection=function(t,e,n){var a=Math.max(t.west,e.west),i=Math.max(t.south,e.south),o=Math.min(t.east,e.east),u=Math.min(t.north,e.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new E(a,i,o,u)},E.union=function(t,e,n){r(n)||(n=new E);var a=t.east,i=t.west,o=e.east,s=e.west;a<i&&o>0?a+=u.TWO_PI:o<s&&a>0&&(o+=u.TWO_PI),a<i&&s<0?s+=u.TWO_PI:o<s&&i<0&&(i+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(i,s)),_=u.convertLongitudeRange(Math.max(a,o));return n.west=c,n.south=Math.min(t.south,e.south),n.east=_,n.north=Math.max(t.north,e.north),n},E.expand=function(t,e,n){return r(n)||(n=new E),n.west=Math.min(t.west,e.longitude),n.south=Math.min(t.south,e.latitude),n.east=Math.max(t.east,e.longitude),n.north=Math.max(t.north,e.latitude),n},E.contains=function(t,e){var n=e.longitude,r=e.latitude,a=t.west,i=t.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=t.south&&r<=t.north};var s=new t;return E.subsample=function(t,e,a,o){e=n(e,i.WGS84),a=n(a,0),r(o)||(o=[]);var c=0,_=t.north,T=t.south,l=t.east,R=t.west,f=s;f.height=a,f.longitude=R,f.latitude=_,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=T,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.latitude=_<0?_:T>0?T:0;for(var A=1;A<8;++A)f.longitude=-Math.PI+A*u.PI_OVER_TWO,E.contains(t,f)&&(o[c]=e.cartographicToCartesian(f,o[c]),c++);return 0===f.latitude&&(f.longitude=R,o[c]=e.cartographicToCartesian(f,o[c]),c++,f.longitude=l,o[c]=e.cartographicToCartesian(f,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(t,e,n,r,a,i,o,u,E,s,c,_,T){"use strict";function l(e,n){this.center=t.clone(a(e,t.ZERO)),this.radius=a(n,0)}var R=new t,f=new t,A=new t,h=new t,d=new t,N=new t,I=new t,S=new t,m=new t,O=new t,M=new t,y=new t,p=4/3*n.PI;l.fromPoints=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r,a=t.clone(e[0],I),o=t.clone(a,R),u=t.clone(a,f),E=t.clone(a,A),s=t.clone(a,h),c=t.clone(a,d),_=t.clone(a,N),T=e.length;for(r=1;r<T;r++){t.clone(e[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&t.clone(a,o),p>s.x&&t.clone(a,s),C<u.y&&t.clone(a,u),C>c.y&&t.clone(a,c),U<E.z&&t.clone(a,E),U>_.z&&t.clone(a,_)}var P=t.magnitudeSquared(t.subtract(s,o,S)),L=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),w=o,g=s,v=P;L>v&&(v=L,w=u,g=c),F>v&&(v=F,w=E,g=_);var x=m;x.x=.5*(w.x+g.x),x.y=.5*(w.y+g.y),x.z=.5*(w.z+g.z);var D=t.magnitudeSquared(t.subtract(g,x,S)),B=Math.sqrt(D),z=O;z.x=o.x,z.y=u.y,z.z=E.z;var G=M;G.x=s.x,G.y=c.y,G.z=_.z;var b=t.multiplyByScalar(t.add(z,G,S),.5,y),X=0;for(r=0;r<T;r++){t.clone(e[r],a);var V=t.magnitude(t.subtract(a,b,S));V>X&&(X=V);var q=t.magnitudeSquared(t.subtract(a,x,S));if(q>D){var H=Math.sqrt(q);B=.5*(B+H),D=B*B;var W=H-B;x.x=(B*x.x+W*a.x)/H,x.y=(B*x.y+W*a.y)/H,x.z=(B*x.z+W*a.z)/H}}return B<X?(t.clone(x,n.center),n.radius=B):(t.clone(b,n.center),n.radius=X),n};var C=new u,U=new t,P=new t,L=new e,F=new e;l.fromRectangle2D=function(t,e,n){return l.fromRectangleWithHeights2D(t,e,0,0,n)},l.fromRectangleWithHeights2D=function(e,n,r,o,u){if(i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;n=a(n,C),T.southwest(e,L),L.height=r,T.northeast(e,F),F.height=o;var E=n.project(L,U),s=n.project(F,P),c=s.x-E.x,_=s.y-E.y,R=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+R*R);var f=u.center;return f.x=E.x+.5*c,f.y=E.y+.5*_,f.z=E.z+.5*R,u};var w=[];l.fromRectangle3D=function(e,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new l),!i(e))return u.center=t.clone(t.ZERO,u.center),u.radius=0,u;var E=T.subsample(e,n,r,w);return l.fromPoints(E,u)},l.fromVertices=function(e,n,r,o){if(i(o)||(o=new l),!i(e)||0===e.length)return o.center=t.clone(t.ZERO,o.center),o.radius=0,o;n=a(n,t.ZERO),r=a(r,3);var u=I;u.x=e[0]+n.x,u.y=e[1]+n.y,u.z=e[2]+n.z;var E,s=t.clone(u,R),c=t.clone(u,f),_=t.clone(u,A),T=t.clone(u,h),p=t.clone(u,d),C=t.clone(u,N),U=e.length;for(E=0;E<U;E+=r){var P=e[E]+n.x,L=e[E+1]+n.y,F=e[E+2]+n.z;u.x=P,u.y=L,u.z=F,P<s.x&&t.clone(u,s),P>T.x&&t.clone(u,T),L<c.y&&t.clone(u,c),L>p.y&&t.clone(u,p),F<_.z&&t.clone(u,_),F>C.z&&t.clone(u,C)}var w=t.magnitudeSquared(t.subtract(T,s,S)),g=t.magnitudeSquared(t.subtract(p,c,S)),v=t.magnitudeSquared(t.subtract(C,_,S)),x=s,D=T,B=w;g>B&&(B=g,x=c,D=p),v>B&&(B=v,x=_,D=C);var z=m;z.x=.5*(x.x+D.x),z.y=.5*(x.y+D.y),z.z=.5*(x.z+D.z);var G=t.magnitudeSquared(t.subtract(D,z,S)),b=Math.sqrt(G),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=M;V.x=T.x,V.y=p.y,V.z=C.z;var q=t.multiplyByScalar(t.add(X,V,S),.5,y),H=0;for(E=0;E<U;E+=r){u.x=e[E]+n.x,u.y=e[E+1]+n.y,u.z=e[E+2]+n.z;var W=t.magnitude(t.subtract(u,q,S));W>H&&(H=W);var Y=t.magnitudeSquared(t.subtract(u,z,S));if(Y>G){var k=Math.sqrt(Y);b=.5*(b+k),G=b*b;var K=k-b;z.x=(b*z.x+K*u.x)/k,z.y=(b*z.y+K*u.y)/k,z.z=(b*z.z+K*u.z)/k}}return b<H?(t.clone(z,o.center),o.radius=b):(t.clone(q,o.center),o.radius=H),o},l.fromEncodedCartesianVertices=function(e,n,r){if(i(r)||(r=new l),!i(e)||!i(n)||e.length!==n.length||0===e.length)return r.center=t.clone(t.ZERO,r.center),r.radius=0,r;var a=I;a.x=e[0]+n[0],a.y=e[1]+n[1],a.z=e[2]+n[2];var o,u=t.clone(a,R),E=t.clone(a,f),s=t.clone(a,A),c=t.clone(a,h),_=t.clone(a,d),T=t.clone(a,N),p=e.length;for(o=0;o<p;o+=3){var C=e[o]+n[o],U=e[o+1]+n[o+1],P=e[o+2]+n[o+2];a.x=C,a.y=U,a.z=P,C<u.x&&t.clone(a,u),C>c.x&&t.clone(a,c),U<E.y&&t.clone(a,E),U>_.y&&t.clone(a,_),P<s.z&&t.clone(a,s),P>T.z&&t.clone(a,T)}var L=t.magnitudeSquared(t.subtract(c,u,S)),F=t.magnitudeSquared(t.subtract(_,E,S)),w=t.magnitudeSquared(t.subtract(T,s,S)),g=u,v=c,x=L;F>x&&(x=F,g=E,v=_),w>x&&(x=w,g=s,v=T);var D=m;D.x=.5*(g.x+v.x),D.y=.5*(g.y+v.y),D.z=.5*(g.z+v.z);var B=t.magnitudeSquared(t.subtract(v,D,S)),z=Math.sqrt(B),G=O;G.x=u.x,G.y=E.y,G.z=s.z;var b=M;b.x=c.x,b.y=_.y,b.z=T.z;var X=t.multiplyByScalar(t.add(G,b,S),.5,y),V=0;for(o=0;o<p;o+=3){a.x=e[o]+n[o],a.y=e[o+1]+n[o+1],a.z=e[o+2]+n[o+2];var q=t.magnitude(t.subtract(a,X,S));q>V&&(V=q);var H=t.magnitudeSquared(t.subtract(a,D,S));if(H>B){var W=Math.sqrt(H);z=.5*(z+W),B=z*z;var Y=W-z;D.x=(z*D.x+Y*a.x)/W,D.y=(z*D.y+Y*a.y)/W,D.z=(z*D.z+Y*a.z)/W}}return z<V?(t.clone(D,r.center),r.radius=z):(t.clone(X,r.center),r.radius=V),r},l.fromCornerPoints=function(e,n,r){i(r)||(r=new l);var a=r.center;return t.add(e,n,a),t.multiplyByScalar(a,.5,a),r.radius=t.distance(a,n),r},l.fromEllipsoid=function(e,n){return i(n)||(n=new l),t.clone(t.ZERO,n.center),n.radius=e.maximumRadius,n};var g=new t;l.fromBoundingSpheres=function(e,n){if(i(n)||(n=new l),!i(e)||0===e.length)return n.center=t.clone(t.ZERO,n.center),n.radius=0,n;var r=e.length;if(1===r)return l.clone(e[0],n);if(2===r)return l.union(e[0],e[1],n);var a,o=[];for(a=0;a<r;a++)o.push(e[a].center);n=l.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=e[a];E=Math.max(E,t.distance(u,s.center,g)+s.radius)}return n.radius=E,n};var v=new t,x=new t,D=new t;l.fromOrientedBoundingBox=function(e,n){i(n)||(n=new l);var r=e.halfAxes,a=c.getColumn(r,0,v),o=c.getColumn(r,1,x),u=c.getColumn(r,2,D);return t.add(a,o,a),t.add(a,u,a),n.center=t.clone(e.center,n.center),n.radius=t.magnitude(a),n},l.clone=function(e,n){if(i(e))return i(n)?(n.center=t.clone(e.center,n.center),n.radius=e.radius,n):new l(e.center,e.radius)},l.packedLength=4,l.pack=function(t,e,n){n=a(n,0);var r=t.center;return e[n++]=r.x,e[n++]=r.y,e[n++]=r.z,e[n]=t.radius,e},l.unpack=function(t,e,n){e=a(e,0),i(n)||(n=new l);var r=n.center;return r.x=t[e++],r.y=t[e++],r.z=t[e++],n.radius=t[e],n};var B=new t,z=new t;l.union=function(e,n,r){i(r)||(r=new l);var a=e.center,o=e.radius,u=n.center,E=n.radius,s=t.subtract(u,a,B),c=t.magnitude(s);if(o>=c+E)return e.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=t.multiplyByScalar(s,(-o+_)/c,z);return t.add(T,a,T),t.clone(T,r.center),r.radius=_,r};var G=new t;l.expand=function(e,n,r){r=l.clone(e,r);var a=t.magnitude(t.subtract(n,r.center,G));return a>r.radius&&(r.radius=a),r},l.intersectPlane=function(e,n){var r=e.center,a=e.radius,i=n.normal,o=t.dot(i,r)+n.distance;return o<-a?E.OUTSIDE:o<a?E.INTERSECTING:E.INSIDE},l.transform=function(t,e,n){return i(n)||(n=new l),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=_.getMaximumScale(e)*t.radius,n};var b=new t;l.distanceSquaredTo=function(e,n){var r=t.subtract(e.center,n,b);return t.magnitudeSquared(r)-e.radius*e.radius},l.transformWithoutScale=function(t,e,n){return i(n)||(n=new l),n.center=_.multiplyByPoint(e,t.center,n.center),n.radius=t.radius,n};var X=new t;l.computePlaneDistances=function(e,n,r,a){i(a)||(a=new s);var o=t.subtract(e.center,n,X),u=t.dot(r,o);return a.start=u-e.radius,a.stop=u+e.radius,a};for(var V=new t,q=new t,H=new t,W=new t,Y=new t,k=new e,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new t;var j=new u;return l.projectTo2D=function(e,n,r){n=a(n,j);var i=n.ellipsoid,o=e.center,u=e.radius,E=i.geodeticSurfaceNormal(o,V),s=t.cross(t.UNIT_Z,E,q);t.normalize(s,s);var c=t.cross(E,s,H);t.normalize(c,c),t.multiplyByScalar(E,u,E),t.multiplyByScalar(c,u,c),t.multiplyByScalar(s,u,s);var _=t.negate(c,Y),T=t.negate(s,W),R=K,f=R[0];t.add(E,c,f),t.add(f,s,f),f=R[1],t.add(E,c,f),t.add(f,T,f),f=R[2],t.add(E,_,f),t.add(f,T,f),f=R[3],t.add(E,_,f),t.add(f,s,f),t.negate(E,E),f=R[4],t.add(E,c,f),t.add(f,s,f),f=R[5],t.add(E,c,f),t.add(f,T,f),f=R[6],t.add(E,_,f),t.add(f,T,f),f=R[7],t.add(E,_,f),t.add(f,s,f);for(var A=R.length,h=0;h<A;++h){var d=R[h];t.add(o,d,d);var N=i.cartesianToCartographic(d,k);n.project(N,d)}r=l.fromPoints(R,r),o=r.center;var I=o.x,S=o.y,m=o.z;return o.x=m,o.y=I,o.z=S,r},l.isOccluded=function(t,e){return!e.isBoundingSphereVisible(t)},l.equals=function(e,n){return e===n||i(e)&&i(n)&&t.equals(e.center,n.center)&&e.radius===n.radius},l.prototype.intersectPlane=function(t){return l.intersectPlane(this,t)},l.prototype.distanceSquaredTo=function(t){return l.distanceSquaredTo(this,t)},l.prototype.computePlaneDistances=function(t,e,n){return l.computePlaneDistances(this,t,e,n)},l.prototype.isOccluded=function(t){return l.isOccluded(this,t)},l.prototype.equals=function(t){return l.equals(this,t)},l.prototype.clone=function(t){return l.clone(this,t)},l.prototype.volume=function(){var t=this.radius;return p*t*t*t},l}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(t,e,n,r,a,i){"use strict";function o(t,n){this.x=e(t,0),this.y=e(n,0)}o.fromElements=function(t,e,r){return n(r)?(r.x=t,r.y=e,r):new o(t,e)},o.clone=function(t,e){if(n(t))return n(e)?(e.x=t.x,e.y=t.y,e):new o(t.x,t.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(t,n,r){return r=e(r,0),n[r++]=t.x,n[r]=t.y,n},o.unpack=function(t,r,a){return r=e(r,0),n(a)||(a=new o),a.x=t[r++],a.y=t[r],a},o.packArray=function(t,e){var r=t.length;n(e)?e.length=2*r:e=new Array(2*r);for(var a=0;a<r;++a)o.pack(t[a],e,2*a);return e},o.unpackArray=function(t,e){var r=t.length;n(e)?e.length=r/2:e=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;e[i]=o.unpack(t,a,e[i])}return e},o.fromArray=o.unpack,o.maximumComponent=function(t){return Math.max(t.x,t.y)},o.minimumComponent=function(t){return Math.min(t.x,t.y)},o.minimumByComponent=function(t,e,n){return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n},o.maximumByComponent=function(t,e,n){return n.x=Math.max(t.x,e.x),n.y=Math.max(t.y,e.y),n},o.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},o.magnitude=function(t){return Math.sqrt(o.magnitudeSquared(t))};var u=new o;o.distance=function(t,e){return o.subtract(t,e,u),o.magnitude(u)},o.distanceSquared=function(t,e){return o.subtract(t,e,u),o.magnitudeSquared(u)},o.normalize=function(t,e){var n=o.magnitude(t);return e.x=t.x/n,e.y=t.y/n,e},o.dot=function(t,e){return t.x*e.x+t.y*e.y},o.multiplyComponents=function(t,e,n){return n.x=t.x*e.x,n.y=t.y*e.y,n},o.divideComponents=function(t,e,n){return n.x=t.x/e.x,n.y=t.y/e.y,n},o.add=function(t,e,n){return n.x=t.x+e.x,n.y=t.y+e.y,n},o.subtract=function(t,e,n){return n.x=t.x-e.x,n.y=t.y-e.y,n},o.multiplyByScalar=function(t,e,n){return n.x=t.x*e,n.y=t.y*e,n},o.divideByScalar=function(t,e,n){return n.x=t.x/e,n.y=t.y/e,n},o.negate=function(t,e){return e.x=-t.x,e.y=-t.y,e},o.abs=function(t,e){return e.x=Math.abs(t.x),e.y=Math.abs(t.y),e};var E=new o;o.lerp=function(t,e,n,r){return o.multiplyByScalar(e,n,E),r=o.multiplyByScalar(t,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(t,e){return o.normalize(t,s),o.normalize(e,c),i.acosClamped(o.dot(s,c))};var _=new o;return o.mostOrthogonalAxis=function(t,e){var n=o.normalize(t,_);return o.abs(n,n),e=n.x<=n.y?o.clone(o.UNIT_X,e):o.clone(o.UNIT_Y,e)},o.equals=function(t,e){return t===e||n(t)&&n(e)&&t.x===e.x&&t.y===e.y},o.equalsArray=function(t,e,n){return t.x===e[n]&&t.y===e[n+1]},o.equalsEpsilon=function(t,e,r,a){return t===e||n(t)&&n(e)&&i.equalsEpsilon(t.x,e.x,r,a)&&i.equalsEpsilon(t.y,e.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)), +o.prototype.clone=function(t){return o.clone(this,t)},o.prototype.equals=function(t){return o.equals(this,t)},o.prototype.equalsEpsilon=function(t,e,n){return o.equalsEpsilon(this,t,e,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Fullscreen",["./defined","./defineProperties"],function(t,e){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return e(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(t(n))return n;n=!1;var e=document.body;if("function"==typeof e.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var E=i[o];a=E+"RequestFullscreen","function"==typeof e[a]?(r.requestFullscreen=a,n=!0):(a=E+"RequestFullScreen","function"==typeof e[a]&&(r.requestFullscreen=a,n=!0)),a=E+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=E+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=E+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=E+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=E+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=E+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=E+"fullscreenchange",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=E+"fullscreenerror",void 0!==document["on"+a]&&("ms"===E&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(t,e){a.supportsFullscreen()&&t[r.requestFullscreen]({vrDisplay:e})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(t,e,n){"use strict";function r(t){for(var e=t.split("."),n=0,r=e.length;n<r;++n)e[n]=parseInt(e[n],10);return e}function a(){if(!e(S)&&(S=!1,!T())){var t=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(S=!0,m=r(t[1]))}return S}function i(){return a()&&m}function o(){if(!e(O)&&(O=!1,!a()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var t=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(O=!0,M=r(t[1]))}return O}function u(){return o()&&M}function E(){if(!e(y)){y=!1;var t=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==t&&(y=!0,p=r(t[1]),p.isNightly=!!t[2])}return y}function s(){return E()&&p}function c(){if(!e(C)){C=!1;var t;"Microsoft Internet Explorer"===I.appName?null!==(t=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1])):"Netscape"===I.appName&&null!==(t=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(t[1]))}return C}function _(){return c()&&U}function T(){if(!e(P)){P=!1;var t=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(P=!0,L=r(t[1]))}return P}function l(){return T()&&L}function R(){if(!e(F)){F=!1;var t=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==t&&(F=!0,w=r(t[1]))}return F}function f(){return e(g)||(g=/Windows/i.test(I.appVersion)),g}function A(){return R()&&w}function h(){return e(v)||(v="undefined"!=typeof PointerEvent&&(!e(I.pointerEnabled)||I.pointerEnabled)),v}function d(){if(!e(D)){var t=document.createElement("canvas");t.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=t.style.imageRendering;D=e(n)&&""!==n,D&&(x=n)}return D}function N(){return d()?x:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,m,O,M,y,p,C,U,P,L,F,w,g,v,x,D,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:l,isFirefox:R,firefoxVersion:A,isWindows:f,hardwareConcurrency:t(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:d,imageRenderingValue:N};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(t){"use strict";return t({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(t,e,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(t){switch(t){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(t){return t instanceof Int8Array?o.BYTE:t instanceof Uint8Array?o.UNSIGNED_BYTE:t instanceof Int16Array?o.SHORT:t instanceof Uint16Array?o.UNSIGNED_SHORT:t instanceof Int32Array?o.INT:t instanceof Uint32Array?o.UNSIGNED_INT:t instanceof Float32Array?o.FLOAT:t instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(t){return e(t)&&(t===o.BYTE||t===o.UNSIGNED_BYTE||t===o.SHORT||t===o.UNSIGNED_SHORT||t===o.INT||t===o.UNSIGNED_INT||t===o.FLOAT||t===o.DOUBLE)},o.createTypedArray=function(t,e){switch(t){case o.BYTE:return new Int8Array(e);case o.UNSIGNED_BYTE:return new Uint8Array(e);case o.SHORT:return new Int16Array(e);case o.UNSIGNED_SHORT:return new Uint16Array(e);case o.INT:return new Int32Array(e);case o.UNSIGNED_INT:return new Uint32Array(e);case o.FLOAT:return new Float32Array(e);case o.DOUBLE:return new Float64Array(e)}},o.createArrayBufferView=function(e,n,r,a){switch(r=t(r,0),a=t(a,(n.byteLength-r)/o.getSizeInBytes(e)),e){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(t){switch(t){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(t){"use strict";return t({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(t,e){"use strict";var n={POINTS:e.POINTS,LINES:e.LINES,LINE_LOOP:e.LINE_LOOP,LINE_STRIP:e.LINE_STRIP,TRIANGLES:e.TRIANGLES,TRIANGLE_STRIP:e.TRIANGLE_STRIP,TRIANGLE_FAN:e.TRIANGLE_FAN,validate:function(t){return t===n.POINTS||t===n.LINES||t===n.LINE_LOOP||t===n.LINE_STRIP||t===n.TRIANGLES||t===n.TRIANGLE_STRIP||t===n.TRIANGLE_FAN}};return t(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(t,e,n,r,a,i){"use strict";function o(t){t=e(t,e.EMPTY_OBJECT),this.attributes=t.attributes,this.indices=t.indices,this.primitiveType=e(t.primitiveType,i.TRIANGLES),this.boundingSphere=t.boundingSphere,this.geometryType=e(t.geometryType,a.NONE),this.boundingSphereCV=t.boundingSphereCV}return o.computeNumberOfVertices=function(t){var e=-1;for(var r in t.attributes)if(t.attributes.hasOwnProperty(r)&&n(t.attributes[r])&&n(t.attributes[r].values)){var a=t.attributes[r],i=a.values.length/a.componentsPerAttribute;e=i}return e},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(t,e,n){"use strict";function r(e){e=t(e,t.EMPTY_OBJECT),this.componentDatatype=e.componentDatatype,this.componentsPerAttribute=e.componentsPerAttribute,this.normalize=t(e.normalize,!1),this.values=e.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(t){"use strict";function e(e){e=t(e,t.EMPTY_OBJECT),this.position=e.position,this.normal=e.normal,this.st=e.st,this.bitangent=e.bitangent,this.tangent=e.tangent,this.color=e.color}return e}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(t,e,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(t){switch(t){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(e){return t(e)&&(e===i.UNSIGNED_BYTE||e===i.UNSIGNED_SHORT||e===i.UNSIGNED_INT)},i.createTypedArray=function(t,e){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e):new Uint16Array(e)},i.createTypedArrayFromArrayBuffer=function(t,e,n,a){return t>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(e,n,a):new Uint16Array(e,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(t,e,n,r){"use strict";function a(e){e=t(e,t.EMPTY_OBJECT),this.position=t(e.position,!1),this.normal=t(e.normal,!1),this.st=t(e.st,!1),this.bitangent=t(e.bitangent,!1),this.tangent=t(e.tangent,!1),this.color=t(e.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(e,n,r){return r=t(r,0),n[r++]=e.position?1:0,n[r++]=e.normal?1:0,n[r++]=e.st?1:0,n[r++]=e.tangent?1:0,n[r++]=e.bitangent?1:0,n[r]=e.color?1:0,n},a.unpack=function(n,r,i){return r=t(r,0),e(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(t,n){if(e(t))return e(n)||(n=new a),n.position=t.position,n.normal=t.normal,n.st=t.st,n.tangent=t.tangent,n.bitangent=t.bitangent,n.color=t.color,n},a}),define("Core/EllipsoidGeometry",["./BoundingSphere","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat"],function(t,e,n,r,a,i,o,u,E,s,c,_,T,l,R){"use strict";function f(t){t=a(t,a.EMPTY_OBJECT);var e=a(t.radii,S),r=Math.round(a(t.stackPartitions,64)),i=Math.round(a(t.slicePartitions,64)),o=a(t.vertexFormat,R.DEFAULT);this._radii=n.clone(e),this._stackPartitions=r,this._slicePartitions=i,this._vertexFormat=R.clone(o),this._workerName="createEllipsoidGeometry"}var A=new n,h=new n,d=new n,N=new n,I=new n,S=new n(1,1,1),m=Math.cos,O=Math.sin;f.packedLength=n.packedLength+R.packedLength+2,f.pack=function(t,e,r){return r=a(r,0),n.pack(t._radii,e,r),r+=n.packedLength,R.pack(t._vertexFormat,e,r),r+=R.packedLength,e[r++]=t._stackPartitions,e[r]=t._slicePartitions,e};var M=new n,y=new R,p={radii:M,vertexFormat:y,stackPartitions:void 0,slicePartitions:void 0};f.unpack=function(t,e,r){e=a(e,0);var o=n.unpack(t,e,M);e+=n.packedLength;var u=R.unpack(t,e,y);e+=R.packedLength;var E=t[e++],s=t[e];return i(r)?(r._radii=n.clone(o,r._radii),r._vertexFormat=R.clone(u,r._vertexFormat),r._stackPartitions=E,r._slicePartitions=s,r):(p.stackPartitions=E,p.slicePartitions=s,new f(p))},f.createGeometry=function(a){var i=a._radii;if(!(i.x<=0||i.y<=0||i.z<=0)){var o,R,f=u.fromCartesian3(i),S=a._vertexFormat,M=a._slicePartitions+1,y=a._stackPartitions+1,p=y*M,C=new Float64Array(3*p),U=6*(M-1)*(y-2),P=_.createTypedArray(p,U),L=S.normal?new Float32Array(3*p):void 0,F=S.tangent?new Float32Array(3*p):void 0,w=S.bitangent?new Float32Array(3*p):void 0,g=S.st?new Float32Array(2*p):void 0,v=new Array(M),x=new Array(M),D=0;for(o=0;o<M;o++){var B=T.TWO_PI*o/(M-1);v[o]=m(B),x[o]=O(B),C[D++]=0,C[D++]=0,C[D++]=i.z}for(o=1;o<y-1;o++){var z=Math.PI*o/(y-1),G=O(z),b=i.x*G,X=i.y*G,V=i.z*m(z);for(R=0;R<M;R++)C[D++]=v[R]*b,C[D++]=x[R]*X,C[D++]=V}for(o=0;o<M;o++)C[D++]=0,C[D++]=0,C[D++]=-i.z;var q=new c;S.position&&(q.position=new s({componentDatatype:r.DOUBLE,componentsPerAttribute:3,values:C}));var H=0,W=0,Y=0,k=0;if(S.st||S.normal||S.tangent||S.bitangent){for(o=0;o<p;o++){var K=n.fromArray(C,3*o,A),Z=f.geodeticSurfaceNormal(K,h);if(S.st){var j=e.negate(Z,I);e.magnitude(j)<T.EPSILON6&&(D=3*(o+M*Math.floor(.5*y)),D>C.length&&(D=3*(o-M*Math.floor(.5*y))),n.fromArray(C,D,j),f.geodeticSurfaceNormal(j,j),e.negate(j,j)),g[H++]=Math.atan2(j.y,j.x)/T.TWO_PI+.5,g[H++]=Math.asin(Z.z)/Math.PI+.5}if(S.normal&&(L[W++]=Z.x,L[W++]=Z.y,L[W++]=Z.z),S.tangent||S.bitangent){var Q=d;if(o<M||o>p-M-1?(n.cross(n.UNIT_X,Z,Q),n.normalize(Q,Q)):(n.cross(n.UNIT_Z,Z,Q),n.normalize(Q,Q)),S.tangent&&(F[Y++]=Q.x,F[Y++]=Q.y,F[Y++]=Q.z),S.bitangent){var J=n.cross(Z,Q,N);n.normalize(J,J),w[k++]=J.x,w[k++]=J.y,w[k++]=J.z}}}S.st&&(q.st=new s({componentDatatype:r.FLOAT,componentsPerAttribute:2,values:g})),S.normal&&(q.normal=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:L})),S.tangent&&(q.tangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:F})),S.bitangent&&(q.bitangent=new s({componentDatatype:r.FLOAT,componentsPerAttribute:3,values:w}))}for(D=0,R=0;R<M-1;R++)P[D++]=M+R,P[D++]=M+R+1,P[D++]=R+1;var $,tt;for(o=1;o<y-2;o++)for($=o*M,tt=(o+1)*M,R=0;R<M-1;R++)P[D++]=tt+R,P[D++]=tt+R+1,P[D++]=$+R+1,P[D++]=tt+R,P[D++]=$+R+1,P[D++]=$+R;for(o=y-2,$=o*M,tt=(o+1)*M,R=0;R<M-1;R++)P[D++]=tt+R,P[D++]=$+R+1,P[D++]=$+R;return new E({attributes:q,indices:P,primitiveType:l.TRIANGLES,boundingSphere:t.fromEllipsoid(f)})}};var C;return f.getUnitEllipsoid=function(){return i(C)||(C=f.createGeometry(new f({radii:new n(1,1,1),vertexFormat:R.POSITION_ONLY}))),C},f}),define("Core/SphereGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipsoidGeometry","./VertexFormat"],function(t,e,n,r,a,i){"use strict";function o(e){var r=n(e.radius,1),i=new t(r,r,r),o={radii:i,stackPartitions:e.stackPartitions,slicePartitions:e.slicePartitions,vertexFormat:e.vertexFormat};this._ellipsoidGeometry=new a(o),this._workerName="createSphereGeometry"}o.packedLength=a.packedLength,o.pack=function(t,e,n){return a.pack(t._ellipsoidGeometry,e,n)};var u=new a,E={radius:void 0,radii:new t,vertexFormat:new i,stackPartitions:void 0,slicePartitions:void 0};return o.unpack=function(e,n,s){var c=a.unpack(e,n,u);return E.vertexFormat=i.clone(c._vertexFormat,E.vertexFormat),E.stackPartitions=c._stackPartitions,E.slicePartitions=c._slicePartitions,r(s)?(t.clone(c._radii,E.radii),s._ellipsoidGeometry=new a(E),s):(E.radius=c._radii.x,new o(E))},o.createGeometry=function(t){return a.createGeometry(t._ellipsoidGeometry)},o}),define("Workers/createSphereGeometry",["../Core/defined","../Core/SphereGeometry"],function(t,e){"use strict";return function(n,r){return t(r)&&(n=e.unpack(n,r)),e.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereOutlineGeometry.js index e8345fc5..7c6d5ba0 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createSphereOutlineGeometry.js @@ -55,6 +55,6 @@ mersenne-twister.js - https://gist.github.com/banksean/300494 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(e),T.y=s*Math.sin(e),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,P,L,F,w,v,D,B,g,x=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),G=0;do{x-=G,U=1/(1+x*M),P=1/(1+x*O),L=1/(1+x*m),F=U*U,w=P*P,v=L*L,D=F*U,B=w*P,g=v*L,p=f*F+h*w+N*v-1,C=f*D*M+h*B*O+N*g*m;G=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*P,s.z=T*L,s):new e(c*U,_*P,T*L)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),T=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var T=new e,R=new e;_.prototype.cartographicToCartesian=function(t,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(e[E.getElementIndex(T,_)])>n){var R,f=e[E.getElementIndex(T,T)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(T,T)]=s,t[E.getElementIndex(T,_)]=c,t[E.getElementIndex(_,T)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,T=e.z*e.w,R=e.w*e.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=M,t):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=R,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=T,t[7]=A,t[8]=N,t):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],T)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),T=t.diagonal=E.clone(e,t.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],T=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(t,R,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,T=t.x*t.w,R=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,T=new e,R=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,T),T),e.normalize(e.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),T=s,R=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],T=e[9],R=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],P=t[10],L=t[11],F=t[12],w=t[13],v=t[14],D=t[15],B=r*d+u*I+_*S+A*M,g=i*d+E*I+T*S+f*M,x=a*d+s*I+R*S+h*M,G=o*d+c*I+l*S+N*M,z=r*O+u*m+_*y+A*p,b=i*O+E*m+T*y+f*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,H=r*C+u*U+_*P+A*L,q=i*C+E*U+T*P+f*L,W=a*C+s*U+R*P+h*L,Y=o*C+c*U+l*P+N*L,k=r*F+u*w+_*v+A*D,K=i*F+E*w+T*v+f*D,Z=a*F+s*w+R*v+h*D,j=o*F+c*w+l*v+N*D;return n[0]=B,n[1]=g,n[2]=x,n[3]=G,n[4]=z,n[5]=b,n[6]=X,n[7]=V,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=e[12],R=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,P=a*A+E*f+_*h,L=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,v=r*S+o*M+s*O,D=i*S+u*M+c*O,B=a*S+E*M+_*O,g=r*m+o*y+s*p+T,x=i*m+u*y+c*p+R,G=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=P,n[3]=0,n[4]=L,n[5]=F,n[6]=w,n[7]=0,n[8]=v,n[9]=D,n[10]=B,n[11]=0,n[12]=g,n[13]=x,n[14]=G,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=t[0],R=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,P=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=P,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],T=e[5],R=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,P=f*p,L=M*m,F=f*y,w=S*m,v=A*p,D=M*O,B=A*y,g=S*O,x=A*m,G=f*O,z=C*T+L*R+F*l-(U*T+P*R+w*l),b=U*_+v*R+g*l-(C*_+D*R+B*l),X=P*_+D*T+x*l-(L*_+v*T+G*l),V=w*_+B*T+G*R-(F*_+g*T+x*R),H=U*i+P*a+w*o-(C*i+L*a+F*o),q=C*r+D*a+B*o-(U*r+v*a+g*o),W=L*r+v*i+G*o-(P*r+D*i+x*o),Y=F*r+g*i+x*a-(w*r+B*i+G*a);C=a*l,U=o*R,P=i*l,L=o*T,F=i*R,w=a*T,v=r*l,D=o*_,B=r*R,g=a*_,x=r*T,G=i*_;var k=C*m+L*y+F*p-(U*m+P*y+w*p),K=U*O+v*y+g*p-(C*O+D*y+B*p),Z=P*O+D*m+x*p-(L*O+v*m+G*p),j=w*O+B*m+G*y-(F*O+g*m+x*y),Q=P*S+w*M+U*f-(F*M+C*f+L*S),J=B*M+C*A+D*S-(v*S+g*M+U*A),$=v*f+G*M+L*A-(x*M+P*A+D*f),ee=x*S+F*A+g*f-(B*f+G*S+w*A),te=r*z+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],T=e[13],R=e[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=e.length;_<T;_++){var R=e[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var T=Math.max(e.south,t.south),R=Math.min(e.north,t.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,T=e.south,R=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_){"use strict";function T(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var R=new e,l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e;T.fromPoints=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],d),o=e.clone(a,R),u=e.clone(a,l),E=e.clone(a,A),s=e.clone(a,f),c=e.clone(a,h),_=e.clone(a,N),y=t.length;for(r=1;r<y;r++){e.clone(t[r],a);var p=a.x,C=a.y,U=a.z;p<o.x&&e.clone(a,o),p>s.x&&e.clone(a,s),C<u.y&&e.clone(a,u),C>c.y&&e.clone(a,c),U<E.z&&e.clone(a,E),U>_.z&&e.clone(a,_)}var P=e.magnitudeSquared(e.subtract(s,o,I)),L=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),w=o,v=s,D=P;L>D&&(D=L,w=u,v=c),F>D&&(D=F,w=E,v=_);var B=S;B.x=.5*(w.x+v.x),B.y=.5*(w.y+v.y),B.z=.5*(w.z+v.z);var g=e.magnitudeSquared(e.subtract(v,B,I)),x=Math.sqrt(g),G=M;G.x=o.x,G.y=u.y,G.z=E.z;var z=O;z.x=s.x,z.y=c.y,z.z=_.z;var b=e.multiplyByScalar(e.add(G,z,I),.5,m),X=0;for(r=0;r<y;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,b,I));V>X&&(X=V);var H=e.magnitudeSquared(e.subtract(a,B,I));if(H>g){var q=Math.sqrt(H);x=.5*(x+q),g=x*x;var W=q-x;B.x=(x*B.x+W*a.x)/q,B.y=(x*B.y+W*a.y)/q,B.z=(x*B.z+W*a.z)/q}}return x<X?(e.clone(B,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var y=new o,p=new e,C=new e,U=new t,P=new t;T.fromRectangle2D=function(e,t,n){return T.fromRectangleWithHeights2D(e,t,0,0,n)},T.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,y),_.southwest(t,U),U.height=a,_.northeast(t,P),P.height=o;var E=n.project(U,p),s=n.project(P,C),c=s.x-E.x,R=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+R*R+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*R,A.z=E.z+.5*l,u};var L=[];T.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new T),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=_.subsample(t,n,o,L);return T.fromPoints(E,u)},T.fromVertices=function(t,n,a,o){if(i(o)||(o=new T),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=d;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,R),c=e.clone(u,l),_=e.clone(u,A),y=e.clone(u,f),p=e.clone(u,h),C=e.clone(u,N),U=t.length;for(E=0;E<U;E+=a){var P=t[E]+n.x,L=t[E+1]+n.y,F=t[E+2]+n.z;u.x=P,u.y=L,u.z=F,P<s.x&&e.clone(u,s),P>y.x&&e.clone(u,y),L<c.y&&e.clone(u,c),L>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(y,s,I)),v=e.magnitudeSquared(e.subtract(p,c,I)),D=e.magnitudeSquared(e.subtract(C,_,I)),B=s,g=y,x=w;v>x&&(x=v,B=c,g=p),D>x&&(x=D,B=_,g=C);var G=S;G.x=.5*(B.x+g.x),G.y=.5*(B.y+g.y),G.z=.5*(B.z+g.z);var z=e.magnitudeSquared(e.subtract(g,G,I)),b=Math.sqrt(z),X=M;X.x=s.x,X.y=c.y,X.z=_.z;var V=O;V.x=y.x,V.y=p.y,V.z=C.z;var H=e.multiplyByScalar(e.add(X,V,I),.5,m),q=0;for(E=0;E<U;E+=a){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,H,I));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,G,I));if(Y>z){var k=Math.sqrt(Y);b=.5*(b+k),z=b*b;var K=k-b;G.x=(b*G.x+K*u.x)/k,G.y=(b*G.y+K*u.y)/k,G.z=(b*G.z+K*u.z)/k}}return b<q?(e.clone(G,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},T.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new T),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=d;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,R),E=e.clone(a,l),s=e.clone(a,A),c=e.clone(a,f),_=e.clone(a,h),y=e.clone(a,N),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],P=t[o+2]+n[o+2];a.x=C,a.y=U,a.z=P,C<u.x&&e.clone(a,u),C>c.x&&e.clone(a,c),U<E.y&&e.clone(a,E),U>_.y&&e.clone(a,_),P<s.z&&e.clone(a,s),P>y.z&&e.clone(a,y)}var L=e.magnitudeSquared(e.subtract(c,u,I)),F=e.magnitudeSquared(e.subtract(_,E,I)),w=e.magnitudeSquared(e.subtract(y,s,I)),v=u,D=c,B=L;F>B&&(B=F,v=E,D=_),w>B&&(B=w,v=s,D=y);var g=S;g.x=.5*(v.x+D.x),g.y=.5*(v.y+D.y),g.z=.5*(v.z+D.z);var x=e.magnitudeSquared(e.subtract(D,g,I)),G=Math.sqrt(x),z=M;z.x=u.x,z.y=E.y,z.z=s.z;var b=O;b.x=c.x,b.y=_.y,b.z=y.z;var X=e.multiplyByScalar(e.add(z,b,I),.5,m),V=0;for(o=0;o<p;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(a,X,I));H>V&&(V=H);var q=e.magnitudeSquared(e.subtract(a,g,I));if(q>x){var W=Math.sqrt(q);G=.5*(G+W),x=G*G;var Y=W-G;g.x=(G*g.x+Y*a.x)/W,g.y=(G*g.y+Y*a.y)/W,g.z=(G*g.z+Y*a.z)/W}}return G<V?(e.clone(g,r.center),r.radius=G):(e.clone(X,r.center),r.radius=V),r},T.fromCornerPoints=function(t,n,r){i(r)||(r=new T);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},T.fromEllipsoid=function(t,n){return i(n)||(n=new T),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var F=new e;T.fromBoundingSpheres=function(t,n){if(i(n)||(n=new T),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return T.clone(t[0],n);if(2===r)return T.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=T.fromPoints(o,n);var u=n.center,E=n.radius;for(a=0;a<r;a++){var s=t[a];E=Math.max(E,e.distance(u,s.center,F)+s.radius)}return n.radius=E,n};var w=new e,v=new e,D=new e;T.fromOrientedBoundingBox=function(t,n){i(n)||(n=new T);var r=t.halfAxes,a=s.getColumn(r,0,w),o=s.getColumn(r,1,v),u=s.getColumn(r,2,D);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},T.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new T(t.center,t.radius)},T.packedLength=4,T.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},T.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new T);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var B=new e,g=new e;T.union=function(t,n,r){i(r)||(r=new T);var a=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,a,B),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),R=e.multiplyByScalar(s,(-o+_)/c,g);return e.add(R,a,R),e.clone(R,r.center),r.radius=_,r};var x=new e;T.expand=function(t,n,r){r=T.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,x));return i>r.radius&&(r.radius=i),r},T.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},T.transform=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=c.getMaximumScale(t)*e.radius,n};var G=new e;T.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,G);return e.magnitudeSquared(r)-t.radius*t.radius},T.transformWithoutScale=function(e,t,n){return i(n)||(n=new T),n.center=c.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;T.computePlaneDistances=function(t,n,r,a){i(a)||(a=new E);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var b=new e,X=new e,V=new e,H=new e,q=new e,W=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var K=new o;return T.projectTo2D=function(t,n,i){n=r(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,b),s=e.cross(e.UNIT_Z,E,X);e.normalize(s,s);var c=e.cross(E,s,V);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,q),R=e.negate(s,H),l=Y,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,R,A),A=l[2],e.add(E,_,A),e.add(A,R,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,R,A),A=l[6],e.add(E,_,A),e.add(A,R,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,W);n.project(d,N)}i=T.fromPoints(l,i),o=i.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,i},T.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},T.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},T.prototype.intersectPlane=function(e){return T.intersectPlane(this,e)},T.prototype.distanceSquaredTo=function(e){return T.distanceSquaredTo(this,e)},T.prototype.computePlaneDistances=function(e,t,n){return T.computePlaneDistances(this,e,t,n)},T.prototype.isOccluded=function(e){return T.isOccluded(this,e)},T.prototype.equals=function(e){return T.equals(this,e)},T.prototype.clone=function(e){return T.clone(this,e)},T}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!T())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0,p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0, -U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function T(){if(!t(P)){P=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(P=!0,L=r(e[1]))}return P}function R(){return T()&&L}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function A(){return t(v)||(v=/Windows/i.test(I.appVersion)),v}function f(){return l()&&w}function h(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),D}function N(){if(!t(g)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;g=t(n)&&""!==n,g&&(B=n)}return g}function d(){return N()?B:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,P,L,F,w,v,D,B,g,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipsoidOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e){e=r(e,r.EMPTY_OBJECT);var n=r(e.radii,l),i=Math.round(r(e.stackPartitions,10)),a=Math.round(r(e.slicePartitions,8)),o=Math.round(r(e.subdivisions,128));this._radii=t.clone(n),this._stackPartitions=i,this._slicePartitions=a,this._subdivisions=o,this._workerName="createEllipsoidOutlineGeometry"}var l=new t(1,1,1),A=Math.cos,f=Math.sin;R.packedLength=t.packedLength+3,R.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),i+=t.packedLength,n[i++]=e._stackPartitions,n[i++]=e._slicePartitions,n[i]=e._subdivisions,n};var h=new t,N={radii:h,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return R.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,h);n+=t.packedLength;var u=e[n++],E=e[n++],s=e[n++];return i(a)?(a._radii=t.clone(o,a._radii),a._stackPartitions=u,a._slicePartitions=E,a._subdivisions=s,a):(N.stackPartitions=u,N.slicePartitions=E,N.subdivisions=s,new R(N))},R.createGeometry=function(t){var r=t._radii;if(!(r.x<=0||r.y<=0||r.z<=0)){var i,a,R,l,h,N,d=o.fromCartesian3(r),I=t._stackPartitions,S=t._slicePartitions,M=t._subdivisions,O=M*(I+S-1),m=O-S+2,y=new Float64Array(3*m),p=c.createTypedArray(m,2*O),C=0,U=new Array(M),P=new Array(M);for(i=0;i<M;i++)R=_.TWO_PI*i/M,U[i]=A(R),P[i]=f(R);for(i=1;i<I;i++)for(l=Math.PI*i/I,h=A(l),N=f(l),a=0;a<M;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(U.length=S,P.length=S,i=0;i<S;i++)R=_.TWO_PI*i/S,U[i]=A(R),P[i]=f(R);for(y[C++]=0,y[C++]=0,y[C++]=r.z,i=1;i<M;i++)for(l=Math.PI*i/M,h=A(l),N=f(l),a=0;a<S;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(y[C++]=0,y[C++]=0,y[C++]=-r.z,C=0,i=0;i<I-1;++i){var L=i*M;for(a=0;a<M-1;++a)p[C++]=L+a,p[C++]=L+a+1;p[C++]=L+M-1,p[C++]=L}var F=M*(I-1);for(a=1;a<S+1;++a)p[C++]=F,p[C++]=F+a;for(i=0;i<M-2;++i){var w=i*S+1+F,v=(i+1)*S+1+F;for(a=0;a<S-1;++a)p[C++]=v+a,p[C++]=w+a;p[C++]=v+S-1,p[C++]=w+S-1}var D=y.length/3-1;for(a=D-1;a>D-S-1;--a)p[C++]=D,p[C++]=a;var B=new s({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:y})});return new u({attributes:B,indices:p,primitiveType:T.LINES,boundingSphere:e.fromEllipsoid(d)})}},R}),define("Core/SphereOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipsoidOutlineGeometry"],function(e,t,n,r,i){"use strict";function a(t){var r=n(t.radius,1),a=new e(r,r,r),o={radii:a,stackPartitions:t.stackPartitions,slicePartitions:t.slicePartitions,subdivisions:t.subdivisions};this._ellipsoidGeometry=new i(o),this._workerName="createSphereOutlineGeometry"}a.packedLength=i.packedLength,a.pack=function(e,t,n){return i.pack(e._ellipsoidGeometry,t,n)};var o=new i,u={radius:void 0,radii:new e,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return a.unpack=function(t,n,E){var s=i.unpack(t,n,o);return u.stackPartitions=s._stackPartitions,u.slicePartitions=s._slicePartitions,u.subdivisions=s._subdivisions,r(E)?(e.clone(s._radii,u.radii),E._ellipsoidGeometry=new i(u),E):(u.radius=s._radii.x,new a(u))},a.createGeometry=function(e){return i.createGeometry(e._ellipsoidGeometry)},a}),define("Workers/createSphereOutlineGeometry",["../Core/defined","../Core/SphereOutlineGeometry"],function(e,t){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),E=u*Math.sin(a);return r.x=E*Math.cos(i),r.y=E*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o,c=new o;o.angleBetween=function(e,t){o.normalize(e,s),o.normalize(t,c);var n=o.dot(s,c),r=o.magnitude(o.cross(s,c,s));return Math.atan2(r,n)};var _=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,_);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,E=t.z,s=i*E-a*u,c=a*o-r*E,_=r*u-i*o;return n.x=s,n.y=c,n.z=_,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var T=new o,R=new o,l=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var E=n(a)?a.radiiSquared:l,s=Math.cos(r);T.x=s*Math.cos(e),T.y=s*Math.sin(e),T.z=Math.sin(r),T=o.normalize(T,T),o.multiplyComponents(E,T,R);var c=Math.sqrt(o.dot(T,R));return R=o.divideByScalar(R,c,R),T=o.multiplyByScalar(T,i,T),n(u)||(u=new o),o.add(R,T,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromDegrees(u,E,0,t,r[s])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],E=e[a+1],s=a/2;r[s]=o.fromRadians(u,E,0,t,r[s])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromDegrees(u,E,s,t,r[c])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],E=e[a+1],s=e[a+2],c=a/3;r[c]=o.fromRadians(u,E,s,t,r[c])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,E,s){var c=n.x,_=n.y,T=n.z,R=i.x,l=i.y,A=i.z,f=c*c*R*R,h=_*_*l*l,N=T*T*A*A,d=f+h+N,I=Math.sqrt(1/d),S=e.multiplyByScalar(n,I,a);if(d<E)return isFinite(I)?e.clone(S,s):void 0;var M=u.x,O=u.y,m=u.z,y=o;y.x=S.x*M*2,y.y=S.y*O*2,y.z=S.z*m*2;var p,C,U,P,L,F,w,v,D,B,g,x=(1-I)*e.magnitude(n)/(.5*e.magnitude(y)),G=0;do{x-=G,U=1/(1+x*M),P=1/(1+x*O),L=1/(1+x*m),F=U*U,w=P*P,v=L*L,D=F*U,B=w*P,g=v*L,p=f*F+h*w+N*v-1,C=f*D*M+h*B*O+N*g*m;G=p/(-2*C)}while(Math.abs(p)>r.EPSILON12);return t(s)?(s.x=c*U,s.y=_*P,s.z=T*L,s):new e(c*U,_*P,T*L)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var E=new e,s=new e,c=new e,_=new e(1/6378137,1/6378137,1/6356752.314245179),T=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),R=a.EPSILON1;return u.fromCartesian=function(t,n,i){var l=r(n)?n.oneOverRadii:_,A=r(n)?n.oneOverRadiiSquared:T,f=r(n)?n._centerToleranceSquared:R,h=o(t,l,A,f,s);if(r(h)){var N=e.multiplyComponents(h,A,E);N=e.normalize(N,N);var d=e.subtract(t,h,c),I=Math.atan2(N.y,N.x),S=Math.asin(N.z),M=a.sign(e.dot(d,t))*e.magnitude(d);return r(i)?(i.longitude=I,i.latitude=S,i.height=M,i):new u(I,S,M)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=E.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function _(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,c(this,e,t,n)}a(_.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),_.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new _(r.x,r.y,r.z)}},_.fromCartesian3=function(e,t){return i(t)||(t=new _),i(e)?(c(t,e.x,e.y,e.z),t):t},_.WGS84=u(new _(6378137,6378137,6356752.314245179)),_.UNIT_SPHERE=u(new _(1,1,1)),_.MOON=u(new _(E.LUNAR_RADIUS,E.LUNAR_RADIUS,E.LUNAR_RADIUS)),_.prototype.clone=function(e){return _.clone(this,e)},_.packedLength=e.packedLength,_.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},_.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return _.fromCartesian3(a,i)},_.prototype.geocentricSurfaceNormal=e.normalize,_.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),E=o*Math.sin(r),s=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=E,n.z=s,e.normalize(n,n)},_.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var T=new e,R=new e;_.prototype.cartographicToCartesian=function(t,n){var r=T,a=R;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},_.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var l=new e,A=new e,f=new e;return _.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,A);if(i(a)){var o=this.geodeticSurfaceNormal(a,l),u=e.subtract(n,a,f),s=Math.atan2(o.y,o.x),c=Math.asin(o.z),_=E.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=s,r.latitude=c,r.height=_,r):new t(s,c,_)}},_.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},_.prototype.scaleToGeodeticSurface=function(e,t){return s(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},_.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,E=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,E,n)},_.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},_.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},_.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},_.prototype.toString=function(){return this._radii.toString()},_.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},_}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i,a,o,u,E,s){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(E,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(s,0)}function s(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function c(e){for(var t=0,n=0;n<3;++n){var r=e[E.getElementIndex(A[n],l[n])];t+=2*r*r}return Math.sqrt(t)}function _(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[E.getElementIndex(A[a],l[a])]);o>r&&(i=a,r=o)}var s=1,c=0,_=l[i],T=A[i];if(Math.abs(e[E.getElementIndex(T,_)])>n){var R,f=e[E.getElementIndex(T,T)],h=e[E.getElementIndex(_,_)],N=e[E.getElementIndex(T,_)],d=(f-h)/2/N;R=d<0?-1/(-d+Math.sqrt(1+d*d)):1/(d+Math.sqrt(1+d*d)),s=1/Math.sqrt(1+R*R),c=R*s}return t=E.clone(E.IDENTITY,t),t[E.getElementIndex(_,_)]=t[E.getElementIndex(T,T)]=s,t[E.getElementIndex(T,_)]=c,t[E.getElementIndex(_,T)]=-c,t}E.packedLength=9,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},E.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new E(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},E.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},E.fromColumnMajorArray=function(e,t){return E.clone(e,t)},E.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new E(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},E.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,s=e.y*e.z,c=e.y*e.w,_=e.z*e.z,T=e.z*e.w,R=e.w*e.w,l=n-u-_+R,A=2*(i-T),f=2*(a+c),h=2*(i+T),N=-n+u-_+R,d=2*(s-o),I=2*(a-c),S=2*(s+o),M=-n-u+_+R;return r(t)?(t[0]=l,t[1]=h,t[2]=I,t[3]=A,t[4]=N,t[5]=S,t[6]=f,t[7]=d,t[8]=M,t):new E(l,A,f,h,N,d,I,S,M)},E.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),s=Math.sin(e.roll),c=n*i,_=-a*u+s*o*i,T=s*u+a*o*i,R=n*u,l=a*i+s*o*u,A=-s*i+a*o*u,f=-o,h=s*n,N=a*n;return r(t)?(t[0]=c,t[1]=R,t[2]=f,t[3]=_,t[4]=l,t[5]=h,t[6]=T,t[7]=A,t[8]=N,t):new E(c,_,T,R,l,A,f,h,N)},E.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new E(e.x,0,0,0,e.y,0,0,0,e.z)},E.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new E(e,0,0,0,e,0,0,0,e)},E.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new E(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},E.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new E(1,0,0,0,n,-i,0,i,n)},E.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new E(n,0,i,0,1,0,-i,0,n)},E.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new E(n,-i,0,i,n,0,0,0,1)},E.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},E.getElementIndex=function(e,t){return 3*e+t},E.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},E.setColumn=function(e,t,n,r){r=E.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},E.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},E.setRow=function(e,t,n,r){return r=E.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var T=new e;E.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],T)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],T)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],T)),n};var R=new e;E.getMaximumScale=function(t){return E.getScale(t,R),e.maximumComponent(R)},E.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],E=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],s=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],c=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],_=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=E,n[6]=s,n[7]=c,n[8]=_,n},E.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},E.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},E.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,E=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=E,n},E.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},E.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},E.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},E.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],E=e[2],s=e[5],c=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=E,t[7]=s,t[8]=c,t};var l=[1,0,0],A=[2,2,1],f=new E,h=new E;return E.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=E.clone(E.IDENTITY,t.unitary),T=t.diagonal=E.clone(e,t.diagonal),R=n*s(T);a<10&&c(T)>R;)_(T,f),E.transpose(f,h),E.multiply(T,f,T),E.multiply(h,T,T),E.multiply(o,f,o),++i>2&&(++a,i=0);return t},E.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},E.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],E=e[5],s=e[8];return t*(a*s-E*o)+i*(E*r-n*s)+u*(n*o-a*r)},E.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],s=e[6],c=e[7],_=e[8],T=E.determinant(e);t[0]=o*_-c*u,t[1]=c*i-r*_,t[2]=r*u-o*i,t[3]=s*u-a*_,t[4]=n*_-s*i,t[5]=a*i-n*u,t[6]=a*c-s*o,t[7]=s*r-n*c,t[8]=n*o-a*r;var R=1/T;return E.multiplyByScalar(t,R,t)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},E.IDENTITY=o(new E(1,0,0,0,1,0,0,0,1)),E.ZERO=o(new E(0,0,0,0,0,0,0,0,0)),E.COLUMN0ROW0=0,E.COLUMN0ROW1=1,E.COLUMN0ROW2=2,E.COLUMN1ROW0=3,E.COLUMN1ROW1=4,E.COLUMN1ROW2=5,E.COLUMN2ROW0=6,E.COLUMN2ROW1=7,E.COLUMN2ROW2=8,i(E.prototype,{length:{get:function(){return E.packedLength}}}),E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},E}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var E=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,E),r=o.multiplyByScalar(e,1-n,r),o.add(E,r,r)};var s=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,s);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,E,s){"use strict";function c(e,t,n,i,a,o,u,E,s,c,_,T,R,l,A,f){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(s,0),this[3]=r(R,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(c,0),this[7]=r(l,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(_,0),this[11]=r(A,0),this[12]=r(i,0),this[13]=r(E,0),this[14]=r(T,0),this[15]=r(f,0)}c.packedLength=16,c.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},c.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new c),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},c.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new c(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},c.fromArray=c.unpack,c.fromColumnMajorArray=function(e,t){return c.clone(e,t)},c.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new c(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},c.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new c(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},c.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new c);var a=n.x,o=n.y,u=n.z,E=t.x*t.x,s=t.x*t.y,_=t.x*t.z,T=t.x*t.w,R=t.y*t.y,l=t.y*t.z,A=t.y*t.w,f=t.z*t.z,h=t.z*t.w,N=t.w*t.w,d=E-R-f+N,I=2*(s-h),S=2*(_+A),M=2*(s+h),O=-E+R-f+N,m=2*(l-T),y=2*(_-A),p=2*(l+T),C=-E-R+f+N;return r[0]=d*a,r[1]=M*a,r[2]=y*a,r[3]=0,r[4]=I*o,r[5]=O*o,r[6]=p*o,r[7]=0,r[8]=S*u,r[9]=m*u,r[10]=C*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},c.fromTranslationRotationScale=function(e,t){return c.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},c.fromTranslation=function(e,t){return c.fromRotationTranslation(E.IDENTITY,e,t)},c.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},c.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new c(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var _=new e,T=new e,R=new e;c.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,_),e.normalize(e.cross(_,o,T),T),e.normalize(e.cross(T,_,R),R);var u=T.x,E=T.y,s=T.z,l=_.x,A=_.y,f=_.z,h=R.x,N=R.y,d=R.z,I=r.x,S=r.y,M=r.z,O=u*-I+E*-S+s*-M,m=h*-I+N*-S+d*-M,y=l*I+A*S+f*M;return i(n)?(n[0]=u,n[1]=h,n[2]=-l,n[3]=0,n[4]=E,n[5]=N,n[6]=-A,n[7]=0,n[8]=s,n[9]=d,n[10]=-f,n[11]=0,n[12]=O,n[13]=m,n[14]=y,n[15]=1,n):new c(u,E,s,O,h,N,d,m,-l,-A,-f,y,0,0,0,1)},c.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,E=(r+n)/(n-r),s=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=-1,i[12]=0,i[13]=0,i[14]=s,i[15]=0,i},c.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),E=1/(r-n),s=1/(a-i),c=-(t+e)*u,_=-(r+n)*E,T=-(a+i)*s;return u*=2,E*=2,s*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=s,o[11]=0,o[12]=c,o[13]=_,o[14]=T,o[15]=1,o},c.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),E=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),_=-(a+i)/(a-i),T=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=E,o[6]=0,o[7]=0,o[8]=s,o[9]=c,o[10]=_,o[11]=-1,o[12]=0,o[13]=0,o[14]=T,o[15]=0,o},c.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),E=(t+e)/(t-e),s=(r+n)/(r-n),c=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=E,a[9]=s,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},c.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),E=r(e.height,0);t=r(t,0),n=r(n,1);var s=.5*u,c=.5*E,_=.5*(n-t),T=s,R=c,l=_,A=a+s,f=o+c,h=t+_;return i[0]=T,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=R,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=l,i[11]=0,i[12]=A,i[13]=f,i[14]=h,i[15]=1,i},c.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},c.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},c.getElementIndex=function(e,t){return 4*e+t},c.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},c.setColumn=function(e,t,n,r){r=c.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},c.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},c.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},c.setRow=function(e,t,n,r){return r=c.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var l=new e;c.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],l)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],l)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],l)),n};var A=new e;c.getMaximumScale=function(t){return c.getScale(t,A),e.maximumComponent(A)},c.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],E=e[5],s=e[6],c=e[7],_=e[8],T=e[9],R=e[10],l=e[11],A=e[12],f=e[13],h=e[14],N=e[15],d=t[0],I=t[1],S=t[2],M=t[3],O=t[4],m=t[5],y=t[6],p=t[7],C=t[8],U=t[9],P=t[10],L=t[11],F=t[12],w=t[13],v=t[14],D=t[15],B=r*d+u*I+_*S+A*M,g=i*d+E*I+T*S+f*M,x=a*d+s*I+R*S+h*M,G=o*d+c*I+l*S+N*M,z=r*O+u*m+_*y+A*p,b=i*O+E*m+T*y+f*p,X=a*O+s*m+R*y+h*p,V=o*O+c*m+l*y+N*p,H=r*C+u*U+_*P+A*L,q=i*C+E*U+T*P+f*L,W=a*C+s*U+R*P+h*L,Y=o*C+c*U+l*P+N*L,k=r*F+u*w+_*v+A*D,K=i*F+E*w+T*v+f*D,Z=a*F+s*w+R*v+h*D,j=o*F+c*w+l*v+N*D;return n[0]=B,n[1]=g,n[2]=x,n[3]=G,n[4]=z,n[5]=b,n[6]=X,n[7]=V,n[8]=H,n[9]=q,n[10]=W,n[11]=Y,n[12]=k,n[13]=K,n[14]=Z,n[15]=j,n},c.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},c.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},c.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=e[12],R=e[13],l=e[14],A=t[0],f=t[1],h=t[2],N=t[4],d=t[5],I=t[6],S=t[8],M=t[9],O=t[10],m=t[12],y=t[13],p=t[14],C=r*A+o*f+s*h,U=i*A+u*f+c*h,P=a*A+E*f+_*h,L=r*N+o*d+s*I,F=i*N+u*d+c*I,w=a*N+E*d+_*I,v=r*S+o*M+s*O,D=i*S+u*M+c*O,B=a*S+E*M+_*O,g=r*m+o*y+s*p+T,x=i*m+u*y+c*p+R,G=a*m+E*y+_*p+l;return n[0]=C,n[1]=U,n[2]=P,n[3]=0,n[4]=L,n[5]=F,n[6]=w,n[7]=0,n[8]=v,n[9]=D,n[10]=B,n[11]=0,n[12]=g,n[13]=x,n[14]=G,n[15]=1,n},c.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],E=e[6],s=e[8],c=e[9],_=e[10],T=t[0],R=t[1],l=t[2],A=t[3],f=t[4],h=t[5],N=t[6],d=t[7],I=t[8],S=r*T+o*R+s*l,M=i*T+u*R+c*l,O=a*T+E*R+_*l,m=r*A+o*f+s*h,y=i*A+u*f+c*h,p=a*A+E*f+_*h,C=r*N+o*d+s*I,U=i*N+u*d+c*I,P=a*N+E*d+_*I;return n[0]=S,n[1]=M,n[2]=O,n[3]=0,n[4]=m,n[5]=y,n[6]=p,n[7]=0,n[8]=C,n[9]=U,n[10]=P,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},c.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],E=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=E,n[15]=e[15],n};var f=new e;c.multiplyByUniformScale=function(e,t,n){return f.x=t,f.y=t,f.z=t,c.multiplyByScale(e,f,n)},c.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?c.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},c.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,E=e[1]*r+e[5]*i+e[9]*a+e[13]*o,s=e[2]*r+e[6]*i+e[10]*a+e[14]*o,c=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=E,n.z=s,n.w=c,n},c.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,E=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=E,n},c.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],E=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=E,n},c.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},c.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},c.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},c.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},c.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},c.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},c.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},c.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var h=new E,N=new E,d=new t,I=new t(0,0,0,1);return c.inverse=function(e,n){if(E.equalsEpsilon(c.getRotation(e,h),N,u.EPSILON7)&&t.equals(c.getRow(e,3,d),I))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],_=e[1],T=e[5],R=e[9],l=e[13],A=e[2],f=e[6],S=e[10],M=e[14],O=e[3],m=e[7],y=e[11],p=e[15],C=S*p,U=M*y,P=f*p,L=M*m,F=f*y,w=S*m,v=A*p,D=M*O,B=A*y,g=S*O,x=A*m,G=f*O,z=C*T+L*R+F*l-(U*T+P*R+w*l),b=U*_+v*R+g*l-(C*_+D*R+B*l),X=P*_+D*T+x*l-(L*_+v*T+G*l),V=w*_+B*T+G*R-(F*_+g*T+x*R),H=U*i+P*a+w*o-(C*i+L*a+F*o),q=C*r+D*a+B*o-(U*r+v*a+g*o),W=L*r+v*i+G*o-(P*r+D*i+x*o),Y=F*r+g*i+x*a-(w*r+B*i+G*a);C=a*l,U=o*R,P=i*l,L=o*T,F=i*R,w=a*T,v=r*l,D=o*_,B=r*R,g=a*_,x=r*T,G=i*_;var k=C*m+L*y+F*p-(U*m+P*y+w*p),K=U*O+v*y+g*p-(C*O+D*y+B*p),Z=P*O+D*m+x*p-(L*O+v*m+G*p),j=w*O+B*m+G*y-(F*O+g*m+x*y),Q=P*S+w*M+U*f-(F*M+C*f+L*S),J=B*M+C*A+D*S-(v*S+g*M+U*A),$=v*f+G*M+L*A-(x*M+P*A+D*f),ee=x*S+F*A+g*f-(B*f+G*S+w*A),te=r*z+i*b+a*X+o*V;if(Math.abs(te)<u.EPSILON20)throw new s("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=b*te,n[2]=X*te,n[3]=V*te,n[4]=H*te,n[5]=q*te,n[6]=W*te,n[7]=Y*te,n[8]=k*te,n[9]=K*te,n[10]=Z*te,n[11]=j*te,n[12]=Q*te,n[13]=J*te,n[14]=$*te,n[15]=ee*te,n},c.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],E=e[8],s=e[9],c=e[10],_=e[12],T=e[13],R=e[14],l=-n*_-r*T-i*R,A=-a*_-o*T-u*R,f=-E*_-s*T-c*R;return t[0]=n,t[1]=a,t[2]=E,t[3]=0,t[4]=r,t[5]=o,t[6]=s,t[7]=0,t[8]=i,t[9]=u,t[10]=c,t[11]=0,t[12]=l,t[13]=A,t[14]=f,t[15]=1,t},c.IDENTITY=o(new c(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),c.ZERO=o(new c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),c.COLUMN0ROW0=0,c.COLUMN0ROW1=1,c.COLUMN0ROW2=2,c.COLUMN0ROW3=3,c.COLUMN1ROW0=4,c.COLUMN1ROW1=5,c.COLUMN1ROW2=6,c.COLUMN1ROW3=7,c.COLUMN2ROW0=8,c.COLUMN2ROW1=9,c.COLUMN2ROW2=10,c.COLUMN2ROW3=11,c.COLUMN3ROW0=12,c.COLUMN3ROW1=13,c.COLUMN3ROW2=14,c.COLUMN3ROW3=15,a(c.prototype,{length:{get:function(){return c.packedLength}}}),c.prototype.clone=function(e){return c.clone(this,e)},c.prototype.equals=function(e){return c.equals(this,e)},c.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},c.prototype.equalsEpsilon=function(e,t){return c.equalsEpsilon(this,e,t)},c.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},c}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function E(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(E.prototype,{width:{get:function(){return E.computeWidth(this)}},height:{get:function(){return E.computeHeight(this)}}}),E.packedLength=4,E.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},E.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new E),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},E.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},E.computeHeight=function(e){return e.north-e.south},E.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new E(e,t,i,a)},E.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new E(e,t,i,a)},E.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,s=Number.MAX_VALUE,c=-Number.MAX_VALUE,_=0,T=e.length;_<T;_++){var R=e[_];n=Math.min(n,R.longitude),i=Math.max(i,R.longitude),s=Math.min(s,R.latitude),c=Math.max(c,R.latitude);var l=R.longitude>=0?R.longitude:R.longitude+u.TWO_PI;a=Math.min(a,l),o=Math.max(o,l)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=s,t.east=i,t.north=c,t):new E(n,s,i,c)},E.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,s=-Number.MAX_VALUE,c=Number.MAX_VALUE,_=-Number.MAX_VALUE,T=Number.MAX_VALUE,R=-Number.MAX_VALUE,l=0,A=e.length;l<A;l++){var f=t.cartesianToCartographic(e[l]);o=Math.min(o,f.longitude),s=Math.max(s,f.longitude),T=Math.min(T,f.latitude),R=Math.max(R,f.latitude);var h=f.longitude>=0?f.longitude:f.longitude+u.TWO_PI;c=Math.min(c,h),_=Math.max(_,h)}return s-o>_-c&&(o=c,s=_,s>u.PI&&(s-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=T,i.east=s,i.north=R,i):new E(o,T,s,R)},E.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new E(e.west,e.south,e.east,e.north)},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},E.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},E.validate=function(e){},E.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},E.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},E.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},E.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},E.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),E=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=E,n.height=0,n):new e(o,E)},E.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.negativePiToPi(Math.max(a,s)),_=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&_<=c)){var T=Math.max(e.south,t.south),R=Math.min(e.north,t.north);if(!(T>=R))return r(n)?(n.west=c,n.south=T,n.east=_,n.north=R,n):new E(c,T,_,R)}},E.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new E(i,a,o,u)},E.union=function(e,t,n){r(n)||(n=new E);var i=e.east,a=e.west,o=t.east,s=t.west;i<a&&o>0?i+=u.TWO_PI:o<s&&i>0&&(o+=u.TWO_PI),i<a&&s<0?s+=u.TWO_PI:o<s&&a<0&&(a+=u.TWO_PI);var c=u.convertLongitudeRange(Math.min(a,s)),_=u.convertLongitudeRange(Math.max(i,o));return n.west=c,n.south=Math.min(e.south,t.south),n.east=_,n.north=Math.max(e.north,t.north),n},E.expand=function(e,t,n){return r(n)||(n=new E),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},E.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var s=new e;return E.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var c=0,_=e.north,T=e.south,R=e.east,l=e.west,A=s;A.height=i,A.longitude=l,A.latitude=_,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=T,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.latitude=_<0?_:T>0?T:0;for(var f=1;f<8;++f)A.longitude=-Math.PI+f*u.PI_OVER_TWO,E.contains(e,A)&&(o[c]=t.cartographicToCartesian(A,o[c]),c++);return 0===A.latitude&&(A.longitude=l,o[c]=t.cartographicToCartesian(A,o[c]),c++,A.longitude=R,o[c]=t.cartographicToCartesian(A,o[c]),c++),o.length=c,o},E.MAX_VALUE=o(new E(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),E}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var l=new e,A=new e,f=new e,h=new e,N=new e,d=new e,I=new e,S=new e,M=new e,O=new e,m=new e,y=new e,p=4/3*n.PI;R.fromPoints=function(t,n){if(a(n)||(n=new R),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],I),o=e.clone(i,l),u=e.clone(i,A),E=e.clone(i,f),s=e.clone(i,h),c=e.clone(i,N),_=e.clone(i,d),T=t.length;for(r=1;r<T;r++){e.clone(t[r],i);var p=i.x,C=i.y,U=i.z;p<o.x&&e.clone(i,o),p>s.x&&e.clone(i,s),C<u.y&&e.clone(i,u),C>c.y&&e.clone(i,c),U<E.z&&e.clone(i,E),U>_.z&&e.clone(i,_)}var P=e.magnitudeSquared(e.subtract(s,o,S)),L=e.magnitudeSquared(e.subtract(c,u,S)),F=e.magnitudeSquared(e.subtract(_,E,S)),w=o,v=s,D=P;L>D&&(D=L,w=u,v=c),F>D&&(D=F,w=E,v=_);var B=M;B.x=.5*(w.x+v.x),B.y=.5*(w.y+v.y),B.z=.5*(w.z+v.z);var g=e.magnitudeSquared(e.subtract(v,B,S)),x=Math.sqrt(g),G=O;G.x=o.x,G.y=u.y,G.z=E.z;var z=m;z.x=s.x,z.y=c.y,z.z=_.z;var b=e.multiplyByScalar(e.add(G,z,S),.5,y),X=0;for(r=0;r<T;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,b,S));V>X&&(X=V);var H=e.magnitudeSquared(e.subtract(i,B,S));if(H>g){var q=Math.sqrt(H);x=.5*(x+q),g=x*x;var W=q-x;B.x=(x*B.x+W*i.x)/q,B.y=(x*B.y+W*i.y)/q,B.z=(x*B.z+W*i.z)/q}}return x<X?(e.clone(B,n.center),n.radius=x):(e.clone(b,n.center),n.radius=X),n};var C=new u,U=new e,P=new e,L=new t,F=new t;R.fromRectangle2D=function(e,t,n){return R.fromRectangleWithHeights2D(e,t,0,0,n)},R.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new R),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,C),T.southwest(t,L),L.height=r,T.northeast(t,F),F.height=o;var E=n.project(L,U),s=n.project(F,P),c=s.x-E.x,_=s.y-E.y,l=s.z-E.z;u.radius=.5*Math.sqrt(c*c+_*_+l*l);var A=u.center;return A.x=E.x+.5*c,A.y=E.y+.5*_,A.z=E.z+.5*l,u};var w=[];R.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new R),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var E=T.subsample(t,n,r,w);return R.fromPoints(E,u)},R.fromVertices=function(t,n,r,o){if(a(o)||(o=new R),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=I;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var E,s=e.clone(u,l),c=e.clone(u,A),_=e.clone(u,f),T=e.clone(u,h),p=e.clone(u,N),C=e.clone(u,d),U=t.length;for(E=0;E<U;E+=r){var P=t[E]+n.x,L=t[E+1]+n.y,F=t[E+2]+n.z;u.x=P,u.y=L,u.z=F,P<s.x&&e.clone(u,s),P>T.x&&e.clone(u,T),L<c.y&&e.clone(u,c),L>p.y&&e.clone(u,p),F<_.z&&e.clone(u,_),F>C.z&&e.clone(u,C)}var w=e.magnitudeSquared(e.subtract(T,s,S)),v=e.magnitudeSquared(e.subtract(p,c,S)),D=e.magnitudeSquared(e.subtract(C,_,S)),B=s,g=T,x=w;v>x&&(x=v,B=c,g=p),D>x&&(x=D,B=_,g=C);var G=M;G.x=.5*(B.x+g.x),G.y=.5*(B.y+g.y),G.z=.5*(B.z+g.z);var z=e.magnitudeSquared(e.subtract(g,G,S)),b=Math.sqrt(z),X=O;X.x=s.x,X.y=c.y,X.z=_.z;var V=m;V.x=T.x,V.y=p.y,V.z=C.z;var H=e.multiplyByScalar(e.add(X,V,S),.5,y),q=0;for(E=0;E<U;E+=r){u.x=t[E]+n.x,u.y=t[E+1]+n.y,u.z=t[E+2]+n.z;var W=e.magnitude(e.subtract(u,H,S));W>q&&(q=W);var Y=e.magnitudeSquared(e.subtract(u,G,S));if(Y>z){var k=Math.sqrt(Y);b=.5*(b+k),z=b*b;var K=k-b;G.x=(b*G.x+K*u.x)/k,G.y=(b*G.y+K*u.y)/k,G.z=(b*G.z+K*u.z)/k}}return b<q?(e.clone(G,o.center),o.radius=b):(e.clone(H,o.center),o.radius=q),o},R.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new R),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=I;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,l),E=e.clone(i,A),s=e.clone(i,f),c=e.clone(i,h),_=e.clone(i,N),T=e.clone(i,d),p=t.length;for(o=0;o<p;o+=3){var C=t[o]+n[o],U=t[o+1]+n[o+1],P=t[o+2]+n[o+2];i.x=C,i.y=U,i.z=P,C<u.x&&e.clone(i,u),C>c.x&&e.clone(i,c),U<E.y&&e.clone(i,E),U>_.y&&e.clone(i,_),P<s.z&&e.clone(i,s),P>T.z&&e.clone(i,T)}var L=e.magnitudeSquared(e.subtract(c,u,S)),F=e.magnitudeSquared(e.subtract(_,E,S)),w=e.magnitudeSquared(e.subtract(T,s,S)),v=u,D=c,B=L;F>B&&(B=F,v=E,D=_),w>B&&(B=w,v=s,D=T);var g=M;g.x=.5*(v.x+D.x),g.y=.5*(v.y+D.y),g.z=.5*(v.z+D.z);var x=e.magnitudeSquared(e.subtract(D,g,S)),G=Math.sqrt(x),z=O;z.x=u.x,z.y=E.y,z.z=s.z;var b=m;b.x=c.x,b.y=_.y,b.z=T.z;var X=e.multiplyByScalar(e.add(z,b,S),.5,y),V=0;for(o=0;o<p;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var H=e.magnitude(e.subtract(i,X,S));H>V&&(V=H);var q=e.magnitudeSquared(e.subtract(i,g,S));if(q>x){var W=Math.sqrt(q);G=.5*(G+W),x=G*G;var Y=W-G;g.x=(G*g.x+Y*i.x)/W,g.y=(G*g.y+Y*i.y)/W,g.z=(G*g.z+Y*i.z)/W}}return G<V?(e.clone(g,r.center),r.radius=G):(e.clone(X,r.center),r.radius=V),r},R.fromCornerPoints=function(t,n,r){a(r)||(r=new R);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},R.fromEllipsoid=function(t,n){return a(n)||(n=new R),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var v=new e;R.fromBoundingSpheres=function(t,n){if(a(n)||(n=new R),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return R.clone(t[0],n);if(2===r)return R.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=R.fromPoints(o,n);var u=n.center,E=n.radius;for(i=0;i<r;i++){var s=t[i];E=Math.max(E,e.distance(u,s.center,v)+s.radius)}return n.radius=E,n};var D=new e,B=new e,g=new e;R.fromOrientedBoundingBox=function(t,n){a(n)||(n=new R);var r=t.halfAxes,i=c.getColumn(r,0,D),o=c.getColumn(r,1,B),u=c.getColumn(r,2,g);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},R.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new R(t.center,t.radius)},R.packedLength=4,R.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},R.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new R);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var x=new e,G=new e;R.union=function(t,n,r){a(r)||(r=new R);var i=t.center,o=t.radius,u=n.center,E=n.radius,s=e.subtract(u,i,x),c=e.magnitude(s);if(o>=c+E)return t.clone(r),r;if(E>=c+o)return n.clone(r),r;var _=.5*(o+c+E),T=e.multiplyByScalar(s,(-o+_)/c,G);return e.add(T,i,T),e.clone(T,r.center),r.radius=_,r};var z=new e;R.expand=function(t,n,r){r=R.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},R.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?E.OUTSIDE:o<i?E.INTERSECTING:E.INSIDE},R.transform=function(e,t,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=_.getMaximumScale(t)*e.radius,n};var b=new e;R.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},R.transformWithoutScale=function(e,t,n){return a(n)||(n=new R),n.center=_.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var X=new e;R.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,X),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,H=new e,q=new e,W=new e,Y=new e,k=new t,K=new Array(8),Z=0;Z<8;++Z)K[Z]=new e;var j=new u;return R.projectTo2D=function(t,n,r){n=i(n,j);var a=n.ellipsoid,o=t.center,u=t.radius,E=a.geodeticSurfaceNormal(o,V),s=e.cross(e.UNIT_Z,E,H);e.normalize(s,s);var c=e.cross(E,s,q);e.normalize(c,c),e.multiplyByScalar(E,u,E),e.multiplyByScalar(c,u,c),e.multiplyByScalar(s,u,s);var _=e.negate(c,Y),T=e.negate(s,W),l=K,A=l[0];e.add(E,c,A),e.add(A,s,A),A=l[1],e.add(E,c,A),e.add(A,T,A),A=l[2],e.add(E,_,A),e.add(A,T,A),A=l[3],e.add(E,_,A),e.add(A,s,A),e.negate(E,E),A=l[4],e.add(E,c,A),e.add(A,s,A),A=l[5],e.add(E,c,A),e.add(A,T,A),A=l[6],e.add(E,_,A),e.add(A,T,A),A=l[7],e.add(E,_,A),e.add(A,s,A);for(var f=l.length,h=0;h<f;++h){var N=l[h];e.add(o,N,N);var d=a.cartesianToCartographic(N,k);n.project(d,N)}r=R.fromPoints(l,r),o=r.center;var I=o.x,S=o.y,M=o.z;return o.x=M,o.y=I,o.z=S,r},R.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},R.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},R.prototype.intersectPlane=function(e){return R.intersectPlane(this,e)},R.prototype.distanceSquaredTo=function(e){return R.distanceSquaredTo(this,e)},R.prototype.computePlaneDistances=function(e,t,n){return R.computePlaneDistances(this,e,t,n)},R.prototype.isOccluded=function(e){return R.isOccluded(this,e)},R.prototype.equals=function(e){return R.equals(this,e)},R.prototype.clone=function(e){return R.clone(this,e)},R.prototype.volume=function(){var e=this.radius;return p*e*e*e},R}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var E=a[o];i=E+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=E+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=E+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=E+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=E+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=E+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=E+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=E+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=E+"fullscreenchange",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=E+"fullscreenerror",void 0!==document["on"+i]&&("ms"===E&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(S)&&(S=!1,!T())){var e=/ Chrome\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(S=!0,M=r(e[1]))}return S}function a(){return i()&&M}function o(){if(!t(O)&&(O=!1,!i()&&!T()&&/ Safari\/[\.0-9]+/.test(I.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(O=!0,m=r(e[1]))}return O}function u(){return o()&&m}function E(){if(!t(y)){y=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(I.userAgent);null!==e&&(y=!0, +p=r(e[1]),p.isNightly=!!e[2])}return y}function s(){return E()&&p}function c(){if(!t(C)){C=!1;var e;"Microsoft Internet Explorer"===I.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1])):"Netscape"===I.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(I.userAgent))&&(C=!0,U=r(e[1]))}return C}function _(){return c()&&U}function T(){if(!t(P)){P=!1;var e=/ Edge\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(P=!0,L=r(e[1]))}return P}function R(){return T()&&L}function l(){if(!t(F)){F=!1;var e=/Firefox\/([\.0-9]+)/.exec(I.userAgent);null!==e&&(F=!0,w=r(e[1]))}return F}function A(){return t(v)||(v=/Windows/i.test(I.appVersion)),v}function f(){return l()&&w}function h(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(I.pointerEnabled)||I.pointerEnabled)),D}function N(){if(!t(g)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;g=t(n)&&""!==n,g&&(B=n)}return g}function d(){return N()?B:void 0}var I;I="undefined"!=typeof navigator?navigator:{};var S,M,O,m,y,p,C,U,P,L,F,w,v,D,B,g,x={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:E,webkitVersion:s,isInternetExplorer:c,internetExplorerVersion:_,isEdge:T,edgeVersion:R,isFirefox:l,firefoxVersion:f,isWindows:A,hardwareConcurrency:e(I.hardwareConcurrency,3),supportsPointerEvents:h,supportsImageRenderingPixelated:N,imageRenderingValue:d};return x.supportsFullscreen=function(){return n.supportsFullscreen()},x.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},x.supportsWebWorkers=function(){return"undefined"!=typeof Worker},x}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/EllipsoidOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType"],function(e,t,n,r,i,a,o,u,E,s,c,_,T){"use strict";function R(e){e=r(e,r.EMPTY_OBJECT);var n=r(e.radii,l),i=Math.round(r(e.stackPartitions,10)),a=Math.round(r(e.slicePartitions,8)),o=Math.round(r(e.subdivisions,128));this._radii=t.clone(n),this._stackPartitions=i,this._slicePartitions=a,this._subdivisions=o,this._workerName="createEllipsoidOutlineGeometry"}var l=new t(1,1,1),A=Math.cos,f=Math.sin;R.packedLength=t.packedLength+3,R.pack=function(e,n,i){return i=r(i,0),t.pack(e._radii,n,i),i+=t.packedLength,n[i++]=e._stackPartitions,n[i++]=e._slicePartitions,n[i]=e._subdivisions,n};var h=new t,N={radii:h,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return R.unpack=function(e,n,a){n=r(n,0);var o=t.unpack(e,n,h);n+=t.packedLength;var u=e[n++],E=e[n++],s=e[n++];return i(a)?(a._radii=t.clone(o,a._radii),a._stackPartitions=u,a._slicePartitions=E,a._subdivisions=s,a):(N.stackPartitions=u,N.slicePartitions=E,N.subdivisions=s,new R(N))},R.createGeometry=function(t){var r=t._radii;if(!(r.x<=0||r.y<=0||r.z<=0)){var i,a,R,l,h,N,d=o.fromCartesian3(r),I=t._stackPartitions,S=t._slicePartitions,M=t._subdivisions,O=M*(I+S-1),m=O-S+2,y=new Float64Array(3*m),p=c.createTypedArray(m,2*O),C=0,U=new Array(M),P=new Array(M);for(i=0;i<M;i++)R=_.TWO_PI*i/M,U[i]=A(R),P[i]=f(R);for(i=1;i<I;i++)for(l=Math.PI*i/I,h=A(l),N=f(l),a=0;a<M;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(U.length=S,P.length=S,i=0;i<S;i++)R=_.TWO_PI*i/S,U[i]=A(R),P[i]=f(R);for(y[C++]=0,y[C++]=0,y[C++]=r.z,i=1;i<M;i++)for(l=Math.PI*i/M,h=A(l),N=f(l),a=0;a<S;a++)y[C++]=r.x*U[a]*N,y[C++]=r.y*P[a]*N,y[C++]=r.z*h;for(y[C++]=0,y[C++]=0,y[C++]=-r.z,C=0,i=0;i<I-1;++i){var L=i*M;for(a=0;a<M-1;++a)p[C++]=L+a,p[C++]=L+a+1;p[C++]=L+M-1,p[C++]=L}var F=M*(I-1);for(a=1;a<S+1;++a)p[C++]=F,p[C++]=F+a;for(i=0;i<M-2;++i){var w=i*S+1+F,v=(i+1)*S+1+F;for(a=0;a<S-1;++a)p[C++]=v+a,p[C++]=w+a;p[C++]=v+S-1,p[C++]=w+S-1}var D=y.length/3-1;for(a=D-1;a>D-S-1;--a)p[C++]=D,p[C++]=a;var B=new s({position:new E({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:y})});return new u({attributes:B,indices:p,primitiveType:T.LINES,boundingSphere:e.fromEllipsoid(d)})}},R}),define("Core/SphereOutlineGeometry",["./Cartesian3","./Check","./defaultValue","./defined","./EllipsoidOutlineGeometry"],function(e,t,n,r,i){"use strict";function a(t){var r=n(t.radius,1),a=new e(r,r,r),o={radii:a,stackPartitions:t.stackPartitions,slicePartitions:t.slicePartitions,subdivisions:t.subdivisions};this._ellipsoidGeometry=new i(o),this._workerName="createSphereOutlineGeometry"}a.packedLength=i.packedLength,a.pack=function(e,t,n){return i.pack(e._ellipsoidGeometry,t,n)};var o=new i,u={radius:void 0,radii:new e,stackPartitions:void 0,slicePartitions:void 0,subdivisions:void 0};return a.unpack=function(t,n,E){var s=i.unpack(t,n,o);return u.stackPartitions=s._stackPartitions,u.slicePartitions=s._slicePartitions,u.subdivisions=s._subdivisions,r(E)?(e.clone(s._radii,u.radii),E._ellipsoidGeometry=new i(u),E):(u.radius=s._radii.x,new a(u))},a.createGeometry=function(e){return i.createGeometry(e._ellipsoidGeometry)},a}),define("Workers/createSphereOutlineGeometry",["../Core/defined","../Core/SphereOutlineGeometry"],function(e,t){"use strict";return function(n,r){return e(r)&&(n=t.unpack(n,r)),t.createGeometry(n)}})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js index 2ab603e4..44f1bf66 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var d=new o,h=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);d.x=c*Math.cos(e),d.y=c*Math.sin(e),d.z=Math.sin(r),d=o.normalize(d,d),o.multiplyComponents(s,d,h);var l=Math.sqrt(o.dot(d,h));return h=o.divideByScalar(h,l,h),d=o.multiplyByScalar(d,a,d),n(u)||(u=new o),o.add(h,d,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,d=1;d<f;d++){var h=t[d],E=h.x,m=h.y,_=h.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(_,u),l=Math.max(_,l)}var p=n.minimum;p.x=a,p.y=o,p.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(p,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,d=n.z,h=a.x,E=a.y,m=a.z,_=l*l*h*h,p=f*f*E*E,y=d*d*m*m,T=_+p+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,N=u.y,M=u.z,O=o;O.x=A.x*S*2,O.y=A.y*N*2,O.z=A.z*M*2;var v,I,g,w,C,x,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),b=0;do{B-=b,g=1/(1+B*S),w=1/(1+B*N),C=1/(1+B*M),x=g*g,P=w*w,U=C*C,D=x*g,L=P*w,F=U*C,v=_*x+p*P+y*U-1,I=_*D*S+p*L*N+y*F*M;b=v/(-2*I)}while(Math.abs(v)>r.EPSILON12);return t(c)?(c.x=l*g,c.y=f*w,c.z=d*C,c):new e(l*g,f*w,d*C)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),d=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:d,_=r(n)?n._centerToleranceSquared:h,p=o(t,E,m,_,c);if(r(p)){var y=e.multiplyComponents(p,m,s);y=e.normalize(y,y);var T=e.subtract(t,p,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var d=new e,h=new e;f.prototype.cartographicToCartesian=function(t,n){var r=d,i=h;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,_=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],d=m[a];if(Math.abs(e[s.getElementIndex(d,f)])>n){var h,_=e[s.getElementIndex(d,d)],p=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(d,f)],T=(_-p)/2/y;h=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(d,d)]=c,t[s.getElementIndex(d,f)]=l,t[s.getElementIndex(f,d)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,d=e.z*e.w,h=e.w*e.w,E=n-u-f+h,m=2*(a-d),_=2*(i+l),p=2*(a+d),y=-n+u-f+h,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+h;return r(t)?(t[0]=E,t[1]=p,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=_,t[7]=T,t[8]=S,t):new s(E,m,_,p,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,d=c*u+i*o*a,h=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,_=-o,p=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=h,t[2]=_,t[3]=f,t[4]=E,t[5]=p,t[6]=d,t[7]=m,t[8]=y,t):new s(l,f,d,h,E,m,_,p,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var d=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],d)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],d)),n};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],_=new s,p=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),d=t.diagonal=s.clone(e,t.diagonal),h=n*c(d);i<10&&l(d)>h;)f(d,_),s.transpose(_,p),s.multiply(d,_,d),s.multiply(p,d,d),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],d=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var h=1/d;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t}, -o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,d,h,E,m,_){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(h,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(d,0),this[15]=r(_,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,d=t.x*t.w,h=t.y*t.y,E=t.y*t.z,m=t.y*t.w,_=t.z*t.z,p=t.z*t.w,y=t.w*t.w,T=s-h-_+y,R=2*(c-p),A=2*(f+m),S=2*(c+p),N=-s+h-_+y,M=2*(E-d),O=2*(f-m),v=2*(E+d),I=-s-h+_+y;return r[0]=T*i,r[1]=S*i,r[2]=O*i,r[3]=0,r[4]=R*o,r[5]=N*o,r[6]=v*o,r[7]=0,r[8]=A*u,r[9]=M*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,d=new e,h=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,d),d),e.normalize(e.cross(d,f,h),h);var u=d.x,s=d.y,c=d.z,E=f.x,m=f.y,_=f.z,p=h.x,y=h.y,T=h.z,R=r.x,A=r.y,S=r.z,N=u*-R+s*-A+c*-S,M=p*-R+y*-A+T*-S,O=E*R+m*A+_*S;return a(n)?(n[0]=u,n[1]=p,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-_,n[11]=0,n[12]=N,n[13]=M,n[14]=O,n[15]=1,n):new l(u,s,c,N,p,y,T,M,-E,-m,-_,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,d=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=d,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),d=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=d,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),d=c,h=l,E=f,m=i+c,_=o+l,p=t+f;return a[0]=d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=_,a[14]=p,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],d=e[9],h=e[10],E=e[11],m=e[12],_=e[13],p=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],N=t[4],M=t[5],O=t[6],v=t[7],I=t[8],g=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+d*A+_*S,B=i*T+c*R+h*A+p*S,b=o*T+l*R+E*A+y*S,z=r*N+u*M+f*O+m*v,q=a*N+s*M+d*O+_*v,G=i*N+c*M+h*O+p*v,W=o*N+l*M+E*O+y*v,V=r*I+u*g+f*w+m*C,X=a*I+s*g+d*w+_*C,H=i*I+c*g+h*w+p*C,Y=o*I+l*g+E*w+y*C,k=r*x+u*P+f*U+m*D,j=a*x+s*P+d*U+_*D,Z=i*x+c*P+h*U+p*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=V,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=e[12],h=e[13],E=e[14],m=t[0],_=t[1],p=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],N=t[10],M=t[12],O=t[13],v=t[14],I=r*m+o*_+c*p,g=a*m+u*_+l*p,w=i*m+s*_+f*p,C=r*y+o*T+c*R,x=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*N,D=a*A+u*S+l*N,L=i*A+s*S+f*N,F=r*M+o*O+c*v+d,B=a*M+u*O+l*v+h,b=i*M+s*O+f*v+E;return n[0]=I,n[1]=g,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=t[0],h=t[1],E=t[2],m=t[3],_=t[4],p=t[5],y=t[6],T=t[7],R=t[8],A=r*d+o*h+c*E,S=a*d+u*h+l*E,N=i*d+s*h+f*E,M=r*m+o*_+c*p,O=a*m+u*_+l*p,v=i*m+s*_+f*p,I=r*y+o*T+c*R,g=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=N,n[3]=0,n[4]=M,n[5]=O,n[6]=v,n[7]=0,n[8]=I,n[9]=g,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var _=new e;l.multiplyByUniformScale=function(e,t,n){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var p=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,p),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],d=e[5],h=e[9],E=e[13],m=e[2],_=e[6],A=e[10],S=e[14],N=e[3],M=e[7],O=e[11],v=e[15],I=A*v,g=S*O,w=_*v,C=S*M,x=_*O,P=A*M,U=m*v,D=S*N,L=m*O,F=A*N,B=m*M,b=_*N,z=I*d+C*h+x*E-(g*d+w*h+P*E),q=g*f+U*h+F*E-(I*f+D*h+L*E),G=w*f+D*d+B*E-(C*f+U*d+b*E),W=P*f+L*d+b*h-(x*f+F*d+B*h),V=g*a+w*i+P*o-(I*a+C*i+x*o),X=I*r+D*i+L*o-(g*r+U*i+F*o),H=C*r+U*a+b*o-(w*r+D*a+B*o),Y=x*r+F*a+B*i-(P*r+L*a+b*i);I=i*E,g=o*h,w=a*E,C=o*d,x=a*h,P=i*d,U=r*E,D=o*f,L=r*h,F=i*f,B=r*d,b=a*f;var k=I*M+C*O+x*v-(g*M+w*O+P*v),j=g*N+U*O+F*v-(I*N+D*O+L*v),Z=w*N+D*M+B*v-(C*N+U*M+b*v),K=P*N+L*M+b*O-(x*N+F*M+B*O),J=w*A+P*S+g*_-(x*S+I*_+C*A),Q=L*S+I*m+D*A-(U*A+F*S+g*m),$=U*_+b*S+C*m-(B*S+w*m+D*_),ee=B*A+x*m+F*_-(L*_+b*A+P*m),te=r*z+a*q+i*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=V*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],d=e[13],h=e[14],E=-n*f-r*d-a*h,m=-i*f-o*d-u*h,_=-s*f-c*d-l*h;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,d=e.length;f<d;f++){var h=e[f];n=Math.min(n,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var E=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,d=Number.MAX_VALUE,h=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var _=t.cartesianToCartographic(e[E]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),d=Math.min(d,_.latitude),h=Math.max(h,_.latitude);var p=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,p),f=Math.max(f,p)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=d,a.east=c,a.north=h,a):new s(o,d,c,h)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var d=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(d>=h))return r(n)?(n.west=l,n.south=d,n.east=f,n.north=h,n):new s(l,d,f,h)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,d=e.south,h=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:d>0?d:0;for(var _=1;_<8;++_)m.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var h=new e,E=new e,m=new e,_=new e,p=new e,y=new e,T=new e,R=new e,A=new e,S=new e,N=new e,M=new e;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,h),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,_),l=e.clone(i,p),f=e.clone(i,y),O=t.length;for(r=1;r<O;r++){e.clone(t[r],i);var v=i.x,I=i.y,g=i.z;v<o.x&&e.clone(i,o),v>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),g<s.z&&e.clone(i,s),g>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,M),G=0;for(r=0;r<O;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var V=e.magnitudeSquared(e.subtract(i,L,R));if(V>F){var X=Math.sqrt(V);B=.5*(B+X),F=B*B;var H=X-B;L.x=(B*L.x+H*i.x)/X,L.y=(B*L.y+H*i.y)/X,L.z=(B*L.z+H*i.z)/X}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var O=new o,v=new e,I=new e,g=new t,w=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),f.southwest(t,g),g.height=i,f.northeast(t,w),w.height=o;var s=n.project(g,v),c=n.project(w,I),l=c.x-s.x,h=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*h,m.z=s.z+.5*E,u};var C=[];d.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,C);return d.fromPoints(s,u)},d.fromVertices=function(t,n,i,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,h),l=e.clone(u,E),f=e.clone(u,m),O=e.clone(u,_),v=e.clone(u,p),I=e.clone(u,y),g=t.length;for(s=0;s<g;s+=i){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>O.x&&e.clone(u,O),C<l.y&&e.clone(u,l),C>v.y&&e.clone(u,v),x<f.z&&e.clone(u,f),x>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(O,c,R)),U=e.magnitudeSquared(e.subtract(v,l,R)),D=e.magnitudeSquared(e.subtract(I,f,R)),L=c,F=O,B=P;U>B&&(B=U,L=l,F=v),D>B&&(B=D,L=f,F=I);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=N;W.x=O.x,W.y=v.y,W.z=I.z;var V=e.multiplyByScalar(e.add(G,W,R),.5,M),X=0;for(s=0;s<g;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,V,R));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;b.x=(q*b.x+j*u.x)/k,b.y=(q*b.y+j*u.y)/k,b.z=(q*b.z+j*u.z)/k}}return q<X?(e.clone(b,o.center),o.radius=q):(e.clone(V,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,h),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,_),f=e.clone(i,p),O=e.clone(i,y),v=t.length;for(o=0;o<v;o+=3){var I=t[o]+n[o],g=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=I,i.y=g,i.z=w,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),g<s.y&&e.clone(i,s),g>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>O.z&&e.clone(i,O)}var C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(O,c,R)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=O);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=N;q.x=l.x,q.y=f.y,q.z=O.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,M),W=0;for(o=0;o<v;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var V=e.magnitude(e.subtract(i,G,R));V>W&&(W=V);var X=e.magnitudeSquared(e.subtract(i,F,R));if(X>B){var H=Math.sqrt(X);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var x=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,x)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new d);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var B=new e;d.expand=function(t,n,r){r=d.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},d.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,W=new e,V=new e,X=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var j=new o;return d.projectTo2D=function(t,n,a){n=r(n,j);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,X),h=e.negate(c,V),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var _=E.length,p=0;p<_;++p){var y=E[p];e.add(o,y,y);var T=i.cartesianToCartographic(y,H);n.project(T,y)}a=d.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){ -return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,n,r,a,i,o){"use strict";function u(e,n){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,a(n)&&(this.cameraPosition=n)}function s(e,n,r){var a=e.transformPositionToScaledSpace(n,E),i=t.magnitudeSquared(a),o=Math.sqrt(i),u=t.divideByScalar(a,o,m);i=Math.max(1,i),o=Math.max(1,o);var s=t.dot(u,r),c=t.magnitude(t.cross(u,r,u)),l=1/o;return 1/(s*l-c*(Math.sqrt(i-1)*l))}function c(e,n,r){if(!(n<=0||n===1/0||n!==n))return t.multiplyByScalar(e,n,r)}function l(e,n){return t.equals(n,t.ZERO)?n:(e.transformPositionToScaledSpace(n,_),t.normalize(_,_))}i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var n=this._ellipsoid,r=n.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),a=t.magnitudeSquared(r)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=r,this._distanceToLimbInScaledSpaceSquared=a}}});var f=new t;u.prototype.isPointVisible=function(e){var t=this._ellipsoid,n=t.transformPositionToScaledSpace(e,f);return this.isScaledSpacePointVisible(n)},u.prototype.isScaledSpacePointVisible=function(e){var n=this._cameraPositionInScaledSpace,r=this._distanceToLimbInScaledSpaceSquared,a=t.subtract(e,n,f),i=-t.dot(a,n);return!(r<0?i>0:i>r&&i*i/t.magnitudeSquared(a)>r)},u.prototype.computeHorizonCullingPoint=function(e,n,r){a(r)||(r=new t);for(var i=this._ellipsoid,o=l(i,e),u=0,f=0,d=n.length;f<d;++f){var h=n[f],E=s(i,h,o);u=Math.max(u,E)}return c(o,u,r)};var d=new t;u.prototype.computeHorizonCullingPointFromVertices=function(e,n,i,o,u){a(u)||(u=new t),o=r(o,t.ZERO);for(var f=this._ellipsoid,h=l(f,e),E=0,m=0,_=n.length;m<_;m+=i){d.x=n[m]+o.x,d.y=n[m+1]+o.y,d.z=n[m+2]+o.z;var p=s(f,d,h);E=Math.max(E,p)}return c(h,E,u)};var h=[];u.prototype.computeHorizonCullingPointFromRectangle=function(n,r,a){var i=o.subsample(n,r,0,h),u=e.fromPoints(i);if(!(t.magnitude(u.center)<.1*r.minimumRadius))return this.computeHorizonCullingPoint(u.center,i,a)};var E=new t,m=new t,_=new t;return u}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var d=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[d/e,a/d]:[a/d,d/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,d=u*u,h=s*s,E=o*s-d,m=o*c-u*s,_=u*c-h,p=4*E*_-m*m;if(p<0){var y,T,R;d*f>=l*h?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=_,R=-c*m+2*s*_);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-p);i=-R+S;var N=i/2,M=N<0?-Math.pow(-N,1/3):Math.pow(N,1/3),O=i===S?-M:-T/M;return a=T<=0?M+O:-R/(M*M+O*O+T),d*f>=l*h?[(a-u)/o]:[-c/(a+s)]}var v=E,I=-2*u*E+o*m,g=_,w=-c*m+2*s*_,C=Math.sqrt(p),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-I)/3);a=2*Math.sqrt(-v);var U=Math.cos(P);i=a*U;var D=a*(-U/2-x*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),a=2*Math.sqrt(-g),U=Math.cos(P),i=a*U,D=a*(-U/2-x*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,V=L*b,X=(s*W-u*V)/(-u*W+s*G);return B<=X?B<=q?X<=q?[B,X,q]:[B,q,X]:[q,B,X]:B<=q?[X,B,q]:X<=q?[X,q,B]:[q,X,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var d=-t/4,h=f[f.length-1];if(Math.abs(h)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,_=E[0],p=E[1];if(_>=0&&p>=0){var y=Math.sqrt(_),T=Math.sqrt(p);return[d-T,d-y,d+y,d+T]}if(_>=0&&p<0)return m=Math.sqrt(_),[d-m,d+m];if(_<0&&p>=0)return m=Math.sqrt(p),[d-m,d+m]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,S=(s+h+c/R)/2,N=r.computeRealRoots(1,R,A),M=r.computeRealRoots(1,-R,S);return 0!==N.length?(N[0]+=d,N[1]+=d,0!==M.length?(M[0]+=d,M[1]+=d,N[1]<=M[0]?[N[0],N[1],M[0],M[1]]:M[1]<=N[0]?[M[0],M[1],N[0],N[1]]:N[0]>=M[0]&&N[1]<=M[1]?[M[0],N[0],N[1],M[1]]:M[0]>=N[0]&&M[1]<=N[1]?[N[0],M[0],M[1],N[1]]:N[0]>M[0]&&N[0]<M[1]?[M[0],N[0],M[1],N[1]]:[N[0],M[0],N[1],M[1]]):N):0!==M.length?(M[0]+=d,M[1]+=d,M):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,d=c*o-i*a*t+u,h=e.computeRealRoots(1,l,f,d);if(h.length>0){var E,m,_=h[0],p=a-_,y=p*p,T=t/2,R=p/2,A=y-4*o,S=y+4*Math.abs(o),N=c-4*_,M=c+4*Math.abs(_);if(_<0||A*M<N*S){var O=Math.sqrt(N);E=O/2,m=0===O?0:(t*R-i)/O}else{var v=Math.sqrt(A);E=0===v?0:(t*R-i)/v,m=v/2}var I,g;0===T&&0===E?(I=0,g=0):n.sign(T)===n.sign(E)?(I=T+E,g=_/I):(g=T-E,I=_/g);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,I,w),P=r.computeRealRoots(1,g,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,d=f*r,h=a*a;return u*c*f-4*s*d-4*e*l*f+18*e*t*n*d-27*i*f*f+256*o*(h*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+h*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,d=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=f<0?h+1:h,h+=d<0?h+1:h){case 0:return a(c,l,f,d);case 1:case 2:return i(c,l,f,d);case 3:case 4:return a(c,l,f,d);case 5:return i(c,l,f,d);case 6:case 7:return a(c,l,f,d);case 8:return i(c,l,f,d);case 9:case 10:return a(c,l,f,d);case 11:return i(c,l,f,d);case 12:case 13:case 14:case 15:return a(c,l,f,d);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function d(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),d=e.dot(u,u),h=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(d,h,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function h(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,d=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*d,m=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),_=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*d+a*n.x+r,p=d*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===p){if(l=s.computeRealRoots(E,m,_),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],N=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-N)),T.push(new e(a,i*S,i*N))}return T}var M=y*y,O=p*p,v=E*E,I=y*p,g=v+O,w=2*(m*E+I),C=2*_*E+m*m-O+M,x=2*(_*m-I),P=_*_-M;if(0===g&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(g,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(_)?h(E*B+_,m*F,o.EPSILON12):o.sign(_)===o.sign(m*F)?h(E*B,m*F+_,o.EPSILON12):h(E*B+m*F,_,o.EPSILON12);var q=h(p*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,p=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,d,h=t.origin,E=t.direction,m=e.subtract(a,r,_),A=e.subtract(i,r,p),S=e.cross(E,A,y),N=e.dot(m,S);if(u){if(N<o.EPSILON6)return;if(s=e.subtract(h,r,T),(l=e.dot(s,S))<0||l>N)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>N)return;d=e.dot(A,c)/N}else{if(Math.abs(N)<o.EPSILON6)return;var M=1/N;if(s=e.subtract(h,r,T),(l=e.dot(s,S)*M)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*M)<0||l+f>1)return;d=e.dot(A,c)*M}return d},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=d(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var N=new l;m.lineSegmentSphere=function(t,n,a,i){var o=N;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=d(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var M=new e,O=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,M),f=e.multiplyComponents(c,t.direction,O),d=e.magnitudeSquared(l),h=e.dot(l,f);if(d>1){if(h>=0)return;var E=h*h;if(r=d-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=h*h-o,s=-h+Math.sqrt(u);var m=s/a,_=r/s;return m<_?new i(m,_):{start:_,stop:m}}var p=Math.sqrt(r/a);return new i(p,p)}return d<1?(r=d-1,a=e.magnitudeSquared(f),o=a*r,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(f),new i(0,-h/a)):void 0};var v=new e,I=new e,g=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,v);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,v),f=e.normalize(l,l),d=e.mostOrthogonalAxis(l,w),h=e.normalize(e.cross(d,f,I),I),m=e.normalize(e.cross(f,h,g),g),_=x;_[0]=f.x,_[1]=f.y,_[2]=f.z,_[3]=h.x,_[4]=h.y,_[5]=h.z,_[6]=m.x,_[7]=m.y,_[8]=m.z;var p=u.transpose(_,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,N=u.multiply(u.multiply(p,T,F),R,F),M=u.multiply(u.multiply(N,y,B),_,B),O=u.multiplyByVector(N,a,C),G=E(M,e.negate(O,v),0,0,1),W=G.length;if(W>0){for(var V=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<W;++H){A=u.multiplyByVector(y,u.multiplyByVector(_,G[H],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>X&&(X=k,V=e.clone(A,V))}var j=n.cartesianToCartographic(V,q);return X=o.clamp(X,0,1),S=e.magnitude(e.subtract(V,a,w))*Math.sqrt(1-X*X),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,d;if(1!==l&&2!==l||(f=new e,d=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,d),{positions:[t,n,r,f,d],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,d),{positions:[t,n,r,f,d],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,d),{positions:[t,n,r,f,d],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,d),{positions:[t,n,r,f,d],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,d),{positions:[t,n,r,f,d],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,d),{positions:[t,n,r,f,d],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return d(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return h(e)}var s,c,l,f,d,h,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],d=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},h=function(e){return m(f,e),e},E=function(e){return e=t(e),d=e.then,E=t,h=p,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return _(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,d,h,E,m,_,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,d=[],h=o(),c)for(_=h.progress,m=function(e){d.push(e),--l||(E=m=p,h.reject(d))},E=function(e){f.push(e),--c||(E=m=p,h.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,_);else h.resolve(f);return h.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return _(1,arguments),d(e,y).then(t,n,r)}function f(){return d(arguments,y)}function d(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function h(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function _(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function p(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=d,e.reduce=h,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,d){var h,E,m,_,p;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",N=s.length,M=0;s&&M<N;M++)switch(s.charAt(M)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(M+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(d)>-1?6:"d"==d?0:void 0,p=r?t[r.slice(0,-1)]:t[n++],d){case"s":return u(String(p),y,c,f,R,S);case"c":return u(String.fromCharCode(+p),y,c,f,R);case"b":return o(p,2,A,y,c,f,R);case"o":return o(p,8,A,y,c,f,R);case"x":return o(p,16,A,y,c,f,R);case"X":return o(p,16,A,y,c,f,R).toUpperCase();case"u":return o(p,10,A,y,c,f,R);case"i":case"d":return h=+p||0,h=Math.round(h-h%1),E=h<0?"-":T,p=E+a(String(Math.abs(h)),f,"0",!1),i(p,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return h=+p,E=h<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(d.toLowerCase())],_=["toString","toUpperCase"]["eEfFgG".indexOf(d)%2],p=E+Math.abs(h)[m](f),i(p,E,y,c,R)[_]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function d(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function h(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,h(a,t,this),r===c.UTC&&f(this)}var _=new i,p=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,N=/^(\d{4})-?(\d{2})-?(\d{2})$/,M=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+M.source,v=/^(\d{2}):?(\d{2})(\.\d+)?/.source+M.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+M.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(h(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(h(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,d=0,_=0,y=0,M=0,g=u[0],w=u[1];if(null!==(u=g.match(N)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=g.match(R)))n=+u[1],s=+u[2];else if(null!==(u=g.match(T)))n=+u[1];else{var C;if(null!==(u=g.match(A)))n=+u[1],C=+u[2],i=o(n);else if(null!==(u=g.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(C),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(I),null!==u?(d=+u[1],_=+u[2],y=+u[3],M=1e3*+(u[4]||0),D=5):(u=w.match(v),null!==u?(d=+u[1],_=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(O))&&(d=+u[1],_=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":d-=F,_-=B;break;case"-":d+=F,_+=B;break;case"Z":break;default:_+=new Date(Date.UTC(n,s-1,l,d,_)).getTimezoneOffset()}}var b=60===y;for(b&&y--;_>=60;)_-=60,d++;for(;d>=24;)d-=24,l++;for(a=i&&2===s?29:p[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:p[s-1];for(;_<0;)_+=60,d--;for(;d<0;)d+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:p[s-1],l+=a;var z=E(n,s,l,d,_,y,M);return r(t)?(h(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var g=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=d(e,g);r(a)||(m.addSeconds(e,-1,g),a=d(g,g),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var h=80*c/2447|0,E=c-(2447*h/80|0)|0;c=h/11|0;var _=h+2-12*c|0,p=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=p,t.month=_,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(p,_,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,_),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,_);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return h(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return h(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return h(e.dayNumber,r,n)},m.addDays=function(e,t,n){return h(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e, -this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return M[e]<l.maximumRequestsPerServer}function h(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--M[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--M[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function _(e){var t=h(e);return e.state=s.ACTIVE,N.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++M[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function p(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--M[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A);var N=[],M={},O="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();p(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=N.length;for(e=0;e<r;++e)t=N[e],t.cancelled&&p(t),t.state===s.ACTIVE?n>0&&(N[e-n]=t):++n;N.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-N.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?p(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):p(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=M[a];return r(i)||(M[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return _(e);if(!(N.length>=l.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;p(t)}return h(e)}},l.clearForSpecs=function(){for(;S.length>0;){p(S.pop())}for(var e=N.length,t=0;t<e;++t)p(N[t]);N.length=0,M={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return M[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,d=t.overrideMimeType;a=n(a,t.url);var h=r(t.request)?t.request:new i;return h.url=a,h.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,d);return r(n)&&r(n.abort)&&(h.cancelFunction=function(){n.abort()}),t.promise},u.request(h)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function d(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function h(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return d(a,i);case"blob":var o=d(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(h(f,t));var d=new XMLHttpRequest;if(c.contains(e)&&(d.withCredentials=!0),r(l)&&r(d.overrideMimeType)&&d.overrideMimeType(l),d.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&d.setRequestHeader(m,i[m]);r(t)&&(d.responseType=t);var _=!1;return"string"==typeof e&&(_=0===e.indexOf("file://")),d.onload=function(){if((d.status<200||d.status>=300)&&(!_||0!==d.status))return void u.reject(new o(d.status,d.response,d.getAllResponseHeaders()));var e=d.response,n=d.responseType;if(204===d.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(d.responseXML)&&d.responseXML.hasChildNodes()?u.resolve(d.responseXML):""!==n&&"text"!==n||!r(d.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(d.responseText);else u.resolve(e)},d.onerror=function(e){u.reject(new o)},d.send(a),d},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function h(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),d=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||d<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var _=e._samples=n.samples,p=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=d,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=_.length;R<A;R+=e._columnCount){var S=_[R+a],N=_[R+m],M=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(M,N,f.TAI);if(p.push(O),T){if(N!==y&&r(y)){var v=o.leapSeconds,I=t(v,O,h);if(I<0){var g=new u(O,N);v.splice(~I,0,g)}}y=N}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function _(e,t,n){return t+e*(n-t)}function p(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),d=a*s,h=i*s,E=n[d+e._ut1MinusUtcSecondsColumn],p=n[h+e._ut1MinusUtcSecondsColumn],y=p-E;if(y>.5||y<-.5){var T=n[d+e._taiMinusUtcSecondsColumn],R=n[h+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=p:p-=R-T)}return u.xPoleWander=_(f,n[d+e._xPoleWanderRadiansColumn],n[h+e._xPoleWanderRadiansColumn]),u.yPoleWander=_(f,n[d+e._yPoleWanderRadiansColumn],n[h+e._yPoleWanderRadiansColumn]),u.xPoleOffset=_(f,n[d+e._xCelestialPoleOffsetRadiansColumn],n[h+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=_(f,n[d+e._yCelestialPoleOffsetRadiansColumn],n[h+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=_(f,E,p),u}return d.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),d.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},d.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],d=i[u+1],h=o.lessThanOrEquals(f,e),E=!r(d),m=E||o.greaterThanOrEquals(d,e);if(h&&m)return s=u,!E&&d.equals(e)&&++s,l=s+1,p(this,i,this._samples,e,s,l,n),n}var _=t(i,e,o.compare,this._dateColumn);return _>=0?(_<i.length-1&&i[_+1].equals(e)&&++_,s=_,l=_):(l=~_,(s=l-1)<0&&(s=0)),this._lastIndex=s,p(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},d}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(d)||(d=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(h)||(h=document.createElement("a"));var n=d(e);return h.href=n,h.href=h.href,h.href}var f,d,h,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,d=s/this._samplesPerXysFile|0,h=[],E=f;E<=d;++E)h.push(l(this,E));return e.all(h)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var d=!1,h=this._samples;if(r(h[3*s])||(l(this,s/this._samplesPerXysFile|0),d=!0),r(h[3*f])||(l(this,f/this._samplesPerXysFile|0),d=!0),!d){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,_=i-s*this._stepSizeDays,p=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)p[E]=_-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=p[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*h[A++],n.y+=T[E]*h[A++],n.s+=T[E]*h[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!d())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(N)&&(N=!1,!a()&&!d()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(N=!0,M=r(e[1]))}return N}function u(){return o()&&M}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0,v=r(e[1]),v.isNightly=!!e[2])}return O}function c(){return s()&&v}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,g=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,g=r(e[1]))}return I}function f(){return l()&&g}function d(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function h(){return d()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function _(){return E()&&P}function p(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,N,M,O,v,I,g,w,C,x,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:d,edgeVersion:h,isFirefox:E,firefoxVersion:_,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:p,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,d=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=d,a):new s(u,l,f,d)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,d=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=d+h+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var _=l,p=0;h>d&&(p=1),E>d&&E>h&&(p=2);var y=_[p],T=_[y];n=Math.sqrt(e[u.getElementIndex(p,p)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[p]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,p)]+e[u.getElementIndex(p,y)])*n,R[T]=(e[u.getElementIndex(T,p)]+e[u.getElementIndex(p,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var d=new s,h=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,d),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,d),s.multiply(h,n,n)};var _=new e,p=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,_);var u=s.computeAngle(y);r[o]=_.x*u,r[o+1]=_.y*u,r[o+2]=_.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,p);var u=e.magnitude(p);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(p,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,d=o*s-r*c+a*l+i*u,h=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=d,n.z=h,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,N=new s,M=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return N=s.multiplyByScalar(e,Math.sin((1-n)*u),N),M=s.multiplyByScalar(i,Math.sin(n*u),M),r=s.add(N,M,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var O=new e,v=new e,I=new s,g=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,I);s.multiply(i,r,g);var o=s.log(g,O);s.multiply(i,t,g);var u=s.log(g,v);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,I),u=s.slerp(n,r,a,g);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,C=1.9011074535173003,x=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;x[L]=1/(F*B),P[L]=F/B}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var d=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),h=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,h,w);return s.multiplyByScalar(t,d,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,I),u=s.fastSlerp(n,r,a,g);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}), -define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E,m,_,p,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},N={},M={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,v=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(N[i])?r=N[i]:(r=function(r,i,s){if(u(s)||(s=new p),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(S[t],0,v),"east"!==t&&"west"!==t&&n.multiplyByScalar(v,c,v),n.unpack(S[a],0,I),"east"!==a&&"west"!==a&&n.multiplyByScalar(I,c,I)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,M.up);var l=M.up,d=M.east;d.x=-r.y,d.y=r.x,d.z=0,n.normalize(d,M.east),n.cross(l,d,M.north),n.multiplyByScalar(M.up,-1,M.down),n.multiplyByScalar(M.east,-1,M.west),n.multiplyByScalar(M.north,-1,M.south),O=M[e],v=M[t],I=M[a]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=v.x,s[5]=v.y,s[6]=v.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},N[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var g=new y,w=new n(1,1,1),C=new p;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,g),s=p.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return i=a(e,r,i),p.multiply(i,s,i)};var x=new p,P=new _;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=p.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,d=Math.cos(f),h=Math.sin(f);return u(t)?(t[0]=d,t[1]=-h,t[2]=0,t[3]=h,t[4]=d,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new _(d,h,0,-h,d,0,0,0,1)},R.iau2006XysData=new d,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new _);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return _.transpose(n,t)};var L=new h(0,0,0),F=new l(0,0,0,0,0,0),B=new _,b=new _;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new _);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=_.fromRotationZ(-i.s,b),d=_.multiply(l,f,B),h=e.dayNumber,p=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=h-2451545,A=p/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var N=_.fromRotationZ(S,b),M=_.multiply(d,N,B),O=Math.cos(n.xPoleWander),v=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),g=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=b;return U[0]=O*x,U[1]=O*P,U[2]=I,U[3]=-v*P+g*I*x,U[4]=v*x+g*I*P,U[5]=-g*O,U[6]=-g*P-v*I*x,U[7]=g*x-v*I*P,U[8]=v*O,_.multiply(M,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return p.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),p.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new _),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var V=new p(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new _,j=new p,Z=new p;return R.basisTo2D=function(e,t,r){var a=p.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=p.inverseTransformation(s,Z),l=p.getRotation(t,k),f=p.multiplyByMatrix3(c,l,r);return p.multiply(V,f,r),p.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=p.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=p.fromTranslation(s,j);return p.multiply(V,o,r),p.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=h.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var _=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,_).center,n)};var p=new d,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=p;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=p;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var d=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(d,c,d),a.scaleToGeocentricSurface(d,d)}return t},E}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E){"use strict";function m(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=d.clone(a(t,d.ZERO))}function _(e,t,r,a,o,u,s,c){i(c)||(c=new m);var l=c.halfAxes;d.setColumn(l,0,e.xAxis,l),d.setColumn(l,1,e.yAxis,l),d.setColumn(l,2,e.zAxis,l);var f=O;f.x=(t+r)/2,f.y=(a+o)/2,f.z=(u+s)/2;var h=v;h.x=(r-t)/2,h.y=(o-a)/2,h.z=(s-u)/2;var E=c.center;return f=d.multiplyByVector(l,f,f),n.add(e.origin,f,E),d.multiplyByScale(l,h,l),c}var p=new n,y=new n,T=new n,R=new n,A=new n,S=new n,N=new d,M={unitary:new d,diagonal:new d};m.fromPoints=function(e,t){if(i(t)||(t=new m),!i(e)||0===e.length)return t.halfAxes=d.ZERO,t.center=n.ZERO,t;var r,a=e.length,o=n.clone(e[0],p);for(r=1;r<a;r++)n.add(o,e[r],o);var u=1/a;n.multiplyByScalar(o,u,o);var s,c=0,l=0,f=0,h=0,E=0,_=0;for(r=0;r<a;r++)s=n.subtract(e[r],o,y),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,h+=s.y*s.y,E+=s.y*s.z,_+=s.z*s.z;c*=u,l*=u,f*=u,h*=u,E*=u,_*=u;var O=N;O[0]=c,O[1]=l,O[2]=f,O[3]=l,O[4]=h,O[5]=E,O[6]=f,O[7]=E,O[8]=_;var v=d.computeEigenDecomposition(O,M),I=d.clone(v.unitary,t.halfAxes),g=d.getColumn(I,0,R),w=d.getColumn(I,1,A),C=d.getColumn(I,2,S),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<a;r++)s=e[r],x=Math.max(n.dot(g,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(g,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);g=n.multiplyByScalar(g,.5*(D+x),g),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var B=n.add(g,w,t.center);n.add(B,C,B);var b=T;return b.x=x-D,b.y=P-L,b.z=U-F,n.multiplyByScalar(b,.5,b),d.multiplyByScale(t.halfAxes,b,t.halfAxes),t};var O=new n,v=new n,I=new r,g=new n,w=[new r,new r,new r,new r,new r,new r,new r,new r],C=[new n,new n,new n,new n,new n,new n,new n,new n],x=[new t,new t,new t,new t,new t,new t,new t,new t];m.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,u.WGS84);var o=E.center(e,I),c=r.cartographicToCartesian(o,g),l=new s(c,r),f=l.plane,d=w[0],m=w[1],p=w[2],y=w[3],T=w[4],R=w[5],A=w[6],S=w[7],N=o.longitude,M=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=M,d.latitude=m.latitude=p.latitude=e.north,A.longitude=S.longitude=d.longitude=e.west,R.longitude=m.longitude=N,T.longitude=y.longitude=p.longitude=e.east,p.height=m.height=d.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(w,C),l.projectPointsToNearestOnPlane(C,x);var O=Math.min(x[6].x,x[7].x,x[0].x),v=Math.max(x[2].x,x[3].x,x[4].x),P=Math.min(x[4].y,x[5].y,x[6].y),U=Math.max(x[0].y,x[1].y,x[2].y);return p.height=d.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(w,C),_(l,O,v,P,U,Math.min(h.getPointDistance(f,C[0]),h.getPointDistance(f,C[2]),h.getPointDistance(f,C[4]),h.getPointDistance(f,C[6])),n,i)},m.clone=function(e,t){if(i(e))return i(t)?(n.clone(e.center,t.center),d.clone(e.halfAxes,t.halfAxes),t):new m(e.center,e.halfAxes)},m.intersectPlane=function(e,t){var r=e.center,a=t.normal,i=e.halfAxes,o=a.x,u=a.y,s=a.z,l=Math.abs(o*i[d.COLUMN0ROW0]+u*i[d.COLUMN0ROW1]+s*i[d.COLUMN0ROW2])+Math.abs(o*i[d.COLUMN1ROW0]+u*i[d.COLUMN1ROW1]+s*i[d.COLUMN1ROW2])+Math.abs(o*i[d.COLUMN2ROW0]+u*i[d.COLUMN2ROW1]+s*i[d.COLUMN2ROW2]),f=n.dot(a,r)+t.distance;return f<=-l?c.OUTSIDE:f>=l?c.INSIDE:c.INTERSECTING};var P=new n,U=new n,D=new n,L=new n;m.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,O),a=e.halfAxes,i=d.getColumn(a,0,P),o=d.getColumn(a,1,U),u=d.getColumn(a,2,D),s=n.magnitude(i),c=n.magnitude(o),l=n.magnitude(u);n.normalize(i,i),n.normalize(o,o),n.normalize(u,u);var f=L;f.x=n.dot(r,i),f.y=n.dot(r,o),f.z=n.dot(r,u);var h,E=0;return f.x<-s?(h=f.x+s,E+=h*h):f.x>s&&(h=f.x-s,E+=h*h),f.y<-c?(h=f.y+c,E+=h*h):f.y>c&&(h=f.y-c,E+=h*h),f.z<-l?(h=f.z+l,E+=h*h):f.z>l&&(h=f.z-l,E+=h*h),E};var F=new n,B=new n;m.computePlaneDistances=function(e,t,r,a){i(a)||(a=new l);var o=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,f=d.getColumn(c,0,P),h=d.getColumn(c,1,U),E=d.getColumn(c,2,D),m=n.add(f,h,F);n.add(m,E,m),n.add(m,s,m);var _=n.subtract(m,t,B),p=n.dot(r,_);return o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.add(m,h,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),a.start=o,a.stop=u,a};var b=new e;return m.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,b);return!n.isBoundingSphereVisible(r)},m.prototype.intersectPlane=function(e){return m.intersectPlane(this,e)},m.prototype.distanceSquaredTo=function(e){return m.distanceSquaredTo(this,e)},m.prototype.computePlaneDistances=function(e,t,n){return m.computePlaneDistances(this,e,t,n)},m.prototype.isOccluded=function(e){return m.isOccluded(this,e)},m.equals=function(e,t){return e===t||i(e)&&i(t)&&n.equals(e.center,t.center)&&d.equals(e.halfAxes,t.halfAxes)},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,a){"use strict";var i={};i.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,n){return i.octDecodeInRange(e,t,255,n)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return i.octDecode(r,a,t)},i.octPack=function(e,t,n,r){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(n,o);return r.x=65536*s.x+a,r.y=65536*s.y+u,r},i.octUnpack=function(e,t,n,r){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,n),i.octDecode(o,s,r)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},i}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}), -define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t,r,o,c,d){var _,p,y,T;if(i(e)&&i(t)&&i(r)&&i(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),N=r-t;_=Math.max(n.maximumComponent(S),N)<m-1?s.BITS12:s.NONE,p=e.center,y=u.inverseTransformation(o,new u);var M=n.negate(R,l);u.multiply(u.fromTranslation(M,h),y,y);var O=l;O.x=1/S.x,O.y=1/S.y,O.z=1/S.z,u.multiply(u.fromScale(O,h),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var v=u.fromTranslation(R,h),I=u.fromScale(S,E),g=u.multiply(v,I,h);u.multiply(o,g,o),u.multiply(T,g,T)}this.quantization=_,this.minimumHeight=t,this.maximumHeight=r,this.center=p,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=a(d,!1)}var l=new n,f=new n,d=new t,h=new u,E=new u,m=Math.pow(2,12);c.prototype.encode=function(r,a,i,c,f,h,E){var m=c.x,_=c.y;if(this.quantization===s.BITS12){i=u.multiplyByPoint(this.toScaledENU,i,l),i.x=o.clamp(i.x,0,1),i.y=o.clamp(i.y,0,1),i.z=o.clamp(i.z,0,1);var p=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/p,0,1);t.fromElements(i.x,i.y,d);var T=e.compressTextureCoordinates(d);t.fromElements(i.z,y,d);var R=e.compressTextureCoordinates(d);t.fromElements(m,_,d);var A=e.compressTextureCoordinates(d);if(r[a++]=T,r[a++]=R,r[a++]=A,this.hasWebMercatorT){t.fromElements(E,0,d);var S=e.compressTextureCoordinates(d);r[a++]=S}}else n.subtract(i,this.center,l),r[a++]=l.x,r[a++]=l.y,r[a++]=l.z,r[a++]=f,r[a++]=m,r[a++]=_,this.hasWebMercatorT&&(r[a++]=E);return this.hasVertexNormals&&(r[a++]=e.octPackFloat(h)),a},c.prototype.decodePosition=function(t,r,a){if(i(a)||(a=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],d);a.x=o.x,a.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],d);return a.z=c.x,u.multiplyByPoint(this.fromScaledENU,a,a)}return a.x=t[r],a.y=t[r+1],a.z=t[r+2],n.add(a,this.center,a)},c.prototype.decodeTextureCoordinates=function(n,r,a){return i(a)||(a=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],a):t.fromElements(n[r+4],n[r+5],a)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],d).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var a=e[n]/256,i=Math.floor(a),o=256*(a-i);return t.fromElements(i,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var _={position3DAndHeight:0,textureCoordAndEncodedNormals:1},p={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,a=r.getSizeInBytes(n);if(this.quantization===s.NONE){var i=2;return this.hasWebMercatorT&&++i,this.hasVertexNormals&&++i,t=(4+i)*a,[{index:_.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:_.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:i,offsetInBytes:4*a,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*a,[{index:p.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:p.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*a,strideInBytes:t}]):[{index:p.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?_:p},c.clone=function(e,t){return i(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},s.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},s}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,a=t.message;n=e(r)&&e(a)?r+": "+a:t.toString();var i=t.stack;return e(i)&&(n+="\n"+i),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return r}),define("Workers/createVerticesFromGoogleEarthEnterpriseBuffer",["../Core/AxisAlignedBoundingBox","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/Ellipsoid","../Core/EllipsoidalOccluder","../Core/Math","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/Rectangle","../Core/RuntimeError","../Core/TerrainEncoding","../Core/Transforms","../Core/WebMercatorProjection","./createTaskProcessorWorker"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E,m,_,p){"use strict";function y(e,t,n){n=i(n,c);for(var r=e.length,a=0;a<r;++a)if(n.equalsEpsilon(e[a],t,c.EPSILON12))return a;return-1}function T(e,t){e.ellipsoid=u.clone(e.ellipsoid),e.rectangle=d.clone(e.rectangle);var n=R(e.buffer,e.relativeToCenter,e.ellipsoid,e.rectangle,e.nativeRectangle,e.exaggeration,e.skirtHeight,e.includeWebMercatorT,e.negativeAltitudeExponentBias,e.negativeElevationThreshold),r=n.vertices;t.push(r.buffer);var a=n.indices;return t.push(a.buffer),{vertices:r.buffer,indices:a.buffer,numberOfAttributes:n.encoding.getStride(),minimumHeight:n.minimumHeight,maximumHeight:n.maximumHeight,boundingSphere3D:n.boundingSphere3D,orientedBoundingBox:n.orientedBoundingBox,occludeePointInScaledSpace:n.occludeePointInScaledSpace,encoding:n.encoding,vertexCountWithoutSkirts:n.vertexCountWithoutSkirts,skirtIndex:n.skirtIndex}}function R(i,u,d,p,T,R,P,U,D,L){var F,B,b,z,q,G;o(p)?(F=p.west,B=p.south,b=p.east,z=p.north,q=p.width,G=p.height):(F=c.toRadians(T.west),B=c.toRadians(T.south),b=c.toRadians(T.east),z=c.toRadians(T.north),q=c.toRadians(p.width),G=c.toRadians(p.height));var W,V,X=[B,z],H=[F,b],Y=m.eastNorthUpToFixedFrame(u,d),k=l.inverseTransformation(Y,x);U&&(W=_.geodeticLatitudeToMercatorAngle(B),V=1/(_.geodeticLatitudeToMercatorAngle(z)-W));var j=new DataView(i),Z=Number.POSITIVE_INFINITY,K=Number.NEGATIVE_INFINITY,J=w;J.x=Number.POSITIVE_INFINITY,J.y=Number.POSITIVE_INFINITY,J.z=Number.POSITIVE_INFINITY;var Q=C;Q.x=Number.NEGATIVE_INFINITY,Q.y=Number.NEGATIVE_INFINITY,Q.z=Number.NEGATIVE_INFINITY;var $,ee,te=0,ne=0,re=0;for(ee=0;ee<4;++ee){var ae=te;$=j.getUint32(ae,!0),ae+=M;var ie=c.toRadians(180*j.getFloat64(ae,!0));ae+=v,-1===y(H,ie)&&H.push(ie);var oe=c.toRadians(180*j.getFloat64(ae,!0));ae+=v,-1===y(X,oe)&&X.push(oe),ae+=2*v;var ue=j.getInt32(ae,!0);ae+=N,ne+=ue,ue=j.getInt32(ae,!0),re+=3*ue,te+=$+M}var se=[],ce=[],le=new Array(ne),fe=new Array(ne),de=new Array(ne),he=U?new Array(ne):[],Ee=new Array(re),me=[],_e=[],pe=[],ye=[],Te=0,Re=0;for(te=0,ee=0;ee<4;++ee){$=j.getUint32(te,!0),te+=M;var Ae=te,Se=c.toRadians(180*j.getFloat64(te,!0));te+=v;var Ne=c.toRadians(180*j.getFloat64(te,!0));te+=v;var Me=c.toRadians(180*j.getFloat64(te,!0)),Oe=.5*Me;te+=v;var ve=c.toRadians(180*j.getFloat64(te,!0)),Ie=.5*ve;te+=v;var ge=j.getInt32(te,!0);te+=N;var we=j.getInt32(te,!0);te+=N,te+=N;for(var Ce=new Array(ge),xe=0;xe<ge;++xe){var Pe=Se+j.getUint8(te++)*Me;I.longitude=Pe;var Ue=Ne+j.getUint8(te++)*ve;I.latitude=Ue;var De=6371010*j.getFloat32(te,!0);if(te+=O,De<L&&(De*=D),De*=R,I.height=De,-1!==y(H,Pe)||-1!==y(X,Ue)){var Le=y(se,I,a);if(-1!==Le){Ce[xe]=ce[Le];continue}se.push(a.clone(I)),ce.push(Te)}Ce[xe]=Te,Math.abs(Pe-F)<Oe?me.push({index:Te,cartographic:a.clone(I)}):Math.abs(Pe-b)<Oe?pe.push({index:Te,cartographic:a.clone(I)}):Math.abs(Ue-B)<Ie?_e.push({index:Te,cartographic:a.clone(I)}):Math.abs(Ue-z)<Ie&&ye.push({index:Te,cartographic:a.clone(I)}),Z=Math.min(De,Z),K=Math.max(De,K),de[Te]=De;var Fe=d.cartographicToCartesian(I);le[Te]=Fe,U&&(he[Te]=(_.geodeticLatitudeToMercatorAngle(Ue)-W)*V),l.multiplyByPoint(k,Fe,g),r.minimumByComponent(g,J,J),r.maximumByComponent(g,Q,Q);var Be=(Pe-F)/(b-F);Be=c.clamp(Be,0,1);var be=(Ue-B)/(z-B);be=c.clamp(be,0,1),fe[Te]=new n(Be,be),++Te}for(var ze=3*we,qe=0;qe<ze;++qe,++Re)Ee[Re]=Ce[j.getUint16(te,!0)],te+=S;if($!==te-Ae)throw new h("Invalid terrain tile.")}le.length=Te,fe.length=Te,de.length=Te,U&&(he.length=Te);var Ge=Te,We=Re,Ve={hMin:Z,lastBorderPoint:void 0,skirtHeight:P,toENU:k,ellipsoid:d,minimum:J,maximum:Q};me.sort(function(e,t){return t.cartographic.latitude-e.cartographic.latitude}),_e.sort(function(e,t){return e.cartographic.longitude-t.cartographic.longitude}),pe.sort(function(e,t){return e.cartographic.latitude-t.cartographic.latitude}),ye.sort(function(e,t){return t.cartographic.longitude-e.cartographic.longitude});if(A(le,de,fe,he,Ee,Ve,me,-1e-5*q,!0,-1e-5*G),A(le,de,fe,he,Ee,Ve,_e,-1e-5*G,!1),A(le,de,fe,he,Ee,Ve,pe,1e-5*q,!0,1e-5*G),A(le,de,fe,he,Ee,Ve,ye,1e-5*G,!1),me.length>0&&ye.length>0){var Xe=me[0].index,He=Ge,Ye=ye[ye.length-1].index,ke=le.length-1;Ee.push(Ye,ke,He,He,Xe,Ye)}ne=le.length;var je,Ze=t.fromPoints(le);o(p)&&p.width<c.PI_OVER_TWO+c.EPSILON5&&(je=f.fromRectangle(p,Z,K,d));for(var Ke=new s(d),Je=Ke.computeHorizonCullingPoint(u,le),Qe=new e(J,Q,u),$e=new E(Qe,Ve.hMin,K,Y,!1,U),et=new Float32Array(ne*$e.getStride()),tt=0,nt=0;nt<ne;++nt)tt=$e.encode(et,tt,le[nt],fe[nt],de[nt],void 0,he[nt]);return{vertices:et,indices:new Uint16Array(Ee),maximumHeight:K,minimumHeight:Z,encoding:$e,boundingSphere3D:Ze,orientedBoundingBox:je,occludeePointInScaledSpace:Je,vertexCountWithoutSkirts:Ge,skirtIndex:We}}function A(e,t,i,u,s,f,d,h,E,m){for(var _=d.length,p=0;p<_;++p){var y=d[p],T=y.cartographic,R=y.index,A=e.length,S=T.longitude,N=T.latitude;N=c.clamp(N,-c.PI_OVER_TWO,c.PI_OVER_TWO);var M=T.height-f.skirtHeight;f.hMin=Math.min(f.hMin,M),a.fromRadians(S,N,M,I),E&&(I.longitude+=h),E?p===_-1?I.latitude+=m:0===p&&(I.latitude-=m):I.latitude+=h;var O=f.ellipsoid.cartographicToCartesian(I);e.push(O),t.push(M),i.push(n.clone(i[R])),u.length>0&&u.push(u[R]),l.multiplyByPoint(f.toENU,O,g);var v=f.minimum,w=f.maximum;r.minimumByComponent(g,v,v),r.maximumByComponent(g,w,w);var C=f.lastBorderPoint;if(o(C)){var x=C.index;s.push(x,A-1,A,A,R,x)}f.lastBorderPoint=y}}var S=Uint16Array.BYTES_PER_ELEMENT,N=Int32Array.BYTES_PER_ELEMENT,M=Uint32Array.BYTES_PER_ELEMENT,O=Float32Array.BYTES_PER_ELEMENT,v=Float64Array.BYTES_PER_ELEMENT,I=new a,g=new r,w=new r,C=new r,x=new l;return p(T)})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,m=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:m,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],m=d.x,E=d.y,p=d.z;i=Math.min(m,i),s=Math.max(m,s),o=Math.min(E,o),c=Math.max(E,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=i,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,m=i.y,E=i.z,p=l*l*d*d,_=f*f*m*m,y=h*h*E*E,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,g=u.z,N=o;N.x=A.x*S*2,N.y=A.y*v*2,N.z=A.z*g*2;var I,O,M,w,C,x,P,U,D,L,F,b=(1-R)*e.magnitude(n)/(.5*e.magnitude(N)),B=0;do{b-=B,M=1/(1+b*S),w=1/(1+b*v),C=1/(1+b*g),x=M*M,P=w*w,U=C*C,D=x*M,L=P*w,F=U*C,I=p*x+_*P+y*U-1,O=p*D*S+_*L*v+y*F*g;B=I/(-2*O)}while(Math.abs(I)>r.EPSILON12);return t(c)?(c.x=l*M,c.y=f*w,c.z=h*C,c):new e(l*M,f*w,h*C)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var m=r(n)?n.oneOverRadii:f,E=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,m,E,p,c);if(r(_)){var y=e.multiplyComponents(_,E,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=A,i.height=S,i):new u(R,A,S)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var m=new e,E=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,E);if(i(a)){var o=this.geodeticSurfaceNormal(a,m),u=e.subtract(n,a,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(E[n],m[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(E[a],m[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=m[i],h=E[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,m=n-u-f+d,E=2*(i-h),p=2*(a+l),_=2*(i+h),y=-n+u-f+d,T=2*(c-o),R=2*(a-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=m,t[1]=_,t[2]=R,t[3]=E,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=S,t):new s(m,E,p,_,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,m=a*i+c*o*u,E=-c*i+a*o*u,p=-o,_=c*n,y=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=m,t[5]=_,t[6]=h,t[7]=E,t[8]=y,t):new s(l,f,h,d,m,E,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var m=[1,0,0],E=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t, +n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,m,E,p){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(m,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(E,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,m=t.y*t.z,E=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),A=2*(f+E),S=2*(c+_),v=-s+d-p+y,g=2*(m-h),N=2*(f-E),I=2*(m+h),O=-s-d+p+y;return r[0]=T*a,r[1]=S*a,r[2]=N*a,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=I*o,r[7]=0,r[8]=A*u,r[9]=g*u,r[10]=O*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,m=f.x,E=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,g=_*-R+y*-A+T*-S,N=m*R+E*A+p*S;return i(n)?(n[0]=u,n[1]=_,n[2]=-m,n[3]=0,n[4]=s,n[5]=y,n[6]=-E,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=v,n[13]=g,n[14]=N,n[15]=1,n):new l(u,s,c,v,_,y,T,g,-m,-E,-p,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,m=f,E=a+c,p=o+l,_=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=m,i[11]=0,i[12]=E,i[13]=p,i[14]=_,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var m=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],m)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],m)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],m)),n};var E=new e;l.getMaximumScale=function(t){return l.getScale(t,E),e.maximumComponent(E)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],m=e[11],E=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],g=t[5],N=t[6],I=t[7],O=t[8],M=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+E*S,F=i*T+s*R+h*A+p*S,b=a*T+c*R+d*A+_*S,B=o*T+l*R+m*A+y*S,z=r*v+u*g+f*N+E*I,q=i*v+s*g+h*N+p*I,G=a*v+c*g+d*N+_*I,V=o*v+l*g+m*N+y*I,W=r*O+u*M+f*w+E*C,X=i*O+s*M+h*w+p*C,H=a*O+c*M+d*w+_*C,k=o*O+l*M+m*w+y*C,Y=r*x+u*P+f*U+E*D,j=i*x+s*P+h*U+p*D,Z=a*x+c*P+d*U+_*D,K=o*x+l*P+m*U+y*D;return n[0]=L,n[1]=F,n[2]=b,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=k,n[12]=Y,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],m=e[14],E=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],g=t[12],N=t[13],I=t[14],O=r*E+o*p+c*_,M=i*E+u*p+l*_,w=a*E+s*p+f*_,C=r*y+o*T+c*R,x=i*y+u*T+l*R,P=a*y+s*T+f*R,U=r*A+o*S+c*v,D=i*A+u*S+l*v,L=a*A+s*S+f*v,F=r*g+o*N+c*I+h,b=i*g+u*N+l*I+d,B=a*g+s*N+f*I+m;return n[0]=O,n[1]=M,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=b,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],m=t[2],E=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*m,S=i*h+u*d+l*m,v=a*h+s*d+f*m,g=r*E+o*p+c*_,N=i*E+u*p+l*_,I=a*E+s*p+f*_,O=r*y+o*T+c*R,M=i*y+u*T+l*R,w=a*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=g,n[5]=N,n[6]=I,n[7]=0,n[8]=O,n[9]=M,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],m=e[13],E=e[2],p=e[6],A=e[10],S=e[14],v=e[3],g=e[7],N=e[11],I=e[15],O=A*I,M=S*N,w=p*I,C=S*g,x=p*N,P=A*g,U=E*I,D=S*v,L=E*N,F=A*v,b=E*g,B=p*v,z=O*h+C*d+x*m-(M*h+w*d+P*m),q=M*f+U*d+F*m-(O*f+D*d+L*m),G=w*f+D*h+b*m-(C*f+U*h+B*m),V=P*f+L*h+B*d-(x*f+F*h+b*d),W=M*i+w*a+P*o-(O*i+C*a+x*o),X=O*r+D*a+L*o-(M*r+U*a+F*o),H=C*r+U*i+B*o-(w*r+D*i+b*o),k=x*r+F*i+b*a-(P*r+L*i+B*a);O=a*m,M=o*d,w=i*m,C=o*h,x=i*d,P=a*h,U=r*m,D=o*f,L=r*d,F=a*f,b=r*h,B=i*f;var Y=O*g+C*N+x*I-(M*g+w*N+P*I),j=M*v+U*N+F*I-(O*v+D*N+L*I),Z=w*v+D*g+b*I-(C*v+U*g+B*I),K=P*v+L*g+B*N-(x*v+F*g+b*N),J=w*A+P*S+M*p-(x*S+O*p+C*A),Q=L*S+O*E+D*A-(U*A+F*S+M*E),$=U*p+B*S+C*E-(b*S+w*E+D*p),ee=b*A+x*E+F*p-(L*p+B*A+P*E),te=r*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=k*te,n[8]=Y*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],m=-n*f-r*h-i*d,E=-a*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=m,t[13]=E,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var m=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,m),o=Math.max(o,m)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,m=0,E=e.length;m<E;m++){var p=t.cartesianToCartographic(e[m]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,m=e.west,E=c;E.height=i,E.longitude=m,E.latitude=f,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=h,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=m,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)E.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,E)&&(o[l]=t.cartographicToCartesian(E,o[l]),l++);return 0===E.latitude&&(E.longitude=m,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var m=new e,E=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,g=new e,N=new e,I=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,m),u=e.clone(i,E),s=e.clone(i,p),c=e.clone(i,_),l=e.clone(i,y),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var I=i.x,O=i.y,M=i.z;I<o.x&&e.clone(i,o),I>c.x&&e.clone(i,c),O<u.y&&e.clone(i,u),O>l.y&&e.clone(i,l),M<s.z&&e.clone(i,s),M>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,A)),C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=S;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,A)),b=Math.sqrt(F),B=v;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,A),.5,N),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,A));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,L,A));if(W>F){var X=Math.sqrt(W);b=.5*(b+X),F=b*b;var H=X-b;L.x=(b*L.x+H*i.x)/X,L.y=(b*L.y+H*i.y)/X,L.z=(b*L.z+H*i.z)/X}}return b<G?(e.clone(L,n.center),n.radius=b):(e.clone(q,n.center),n.radius=G),n};var O=new u,M=new e,w=new e,C=new t,x=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,O),h.southwest(t,C),C.height=r,h.northeast(t,x),x.height=o;var s=n.project(C,M),c=n.project(x,w),l=c.x-s.x,f=c.y-s.y,m=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+m*m);var E=u.center;return E.x=s.x+.5*l,E.y=s.y+.5*f,E.z=s.z+.5*m,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,m),l=e.clone(u,E),f=e.clone(u,p),h=e.clone(u,_),I=e.clone(u,y),O=e.clone(u,T),M=t.length;for(s=0;s<M;s+=r){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>h.x&&e.clone(u,h),C<l.y&&e.clone(u,l),C>I.y&&e.clone(u,I),x<f.z&&e.clone(u,f),x>O.z&&e.clone(u,O)}var P=e.magnitudeSquared(e.subtract(h,c,A)),U=e.magnitudeSquared(e.subtract(I,l,A)),D=e.magnitudeSquared(e.subtract(O,f,A)),L=c,F=h,b=P;U>b&&(b=U,L=l,F=I),D>b&&(b=D,L=f,F=O);var B=S;B.x=.5*(L.x+F.x),B.y=.5*(L.y+F.y),B.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,A)),q=Math.sqrt(z),G=v;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=I.y,V.z=O.z;var W=e.multiplyByScalar(e.add(G,V,A),.5,N),X=0;for(s=0;s<M;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,A));H>X&&(X=H);var k=e.magnitudeSquared(e.subtract(u,B,A));if(k>z){var Y=Math.sqrt(k);q=.5*(q+Y),z=q*q;var j=Y-q;B.x=(q*B.x+j*u.x)/Y,B.y=(q*B.y+j*u.y)/Y,B.z=(q*B.z+j*u.z)/Y}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,m),s=e.clone(i,E),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),h=e.clone(i,T),I=t.length;for(o=0;o<I;o+=3){var O=t[o]+n[o],M=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=O,i.y=M,i.z=w,O<u.x&&e.clone(i,u),O>l.x&&e.clone(i,l),M<s.y&&e.clone(i,s),M>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>h.z&&e.clone(i,h)}var C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=e.magnitudeSquared(e.subtract(h,c,A)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=S;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var b=e.magnitudeSquared(e.subtract(D,F,A)),B=Math.sqrt(b),z=v;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,A),.5,N),V=0;for(o=0;o<I;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,A));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,F,A));if(X>b){var H=Math.sqrt(X);B=.5*(B+H),b=B*B;var k=H-B;F.x=(B*F.x+k*i.x)/H,F.y=(B*F.y+k*i.y)/H,F.z=(B*F.z+k*i.z)/H}}return B<V?(e.clone(F,r.center),r.radius=B):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var b=new e,B=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,b),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,W=new e,X=new e,H=new e,k=new e,Y=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,k),h=e.negate(c,H),m=j,E=m[0];e.add(s,l,E),e.add(E,c,E),E=m[1],e.add(s,l,E),e.add(E,h,E),E=m[2],e.add(s,f,E),e.add(E,h,E),E=m[3],e.add(s,f,E),e.add(E,c,E),e.negate(s,s),E=m[4],e.add(s,l,E),e.add(E,c,E),E=m[5],e.add(s,l,E),e.add(E,h,E),E=m[6],e.add(s,f,E),e.add(E,h,E),E=m[7],e.add(s,f,E),e.add(E,c,E);for(var p=m.length,_=0;_<p;++_){var y=m[_];e.add(o,y,y);var T=a.cartesianToCartographic(y,Y);n.project(T,y)}r=d.fromPoints(m,r),o=r.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return I*e*e*e},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x), +n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,n,r,i,a,o){"use strict";function u(e,n){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,i(n)&&(this.cameraPosition=n)}function s(e,n,r){var i=e.transformPositionToScaledSpace(n,m),a=t.magnitudeSquared(i),o=Math.sqrt(a),u=t.divideByScalar(i,o,E);a=Math.max(1,a),o=Math.max(1,o);var s=t.dot(u,r),c=t.magnitude(t.cross(u,r,u)),l=1/o;return 1/(s*l-c*(Math.sqrt(a-1)*l))}function c(e,n,r){if(!(n<=0||n===1/0||n!==n))return t.multiplyByScalar(e,n,r)}function l(e,n){return t.equals(n,t.ZERO)?n:(e.transformPositionToScaledSpace(n,p),t.normalize(p,p))}a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var n=this._ellipsoid,r=n.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),i=t.magnitudeSquared(r)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=r,this._distanceToLimbInScaledSpaceSquared=i}}});var f=new t;u.prototype.isPointVisible=function(e){var t=this._ellipsoid,n=t.transformPositionToScaledSpace(e,f);return this.isScaledSpacePointVisible(n)},u.prototype.isScaledSpacePointVisible=function(e){var n=this._cameraPositionInScaledSpace,r=this._distanceToLimbInScaledSpaceSquared,i=t.subtract(e,n,f),a=-t.dot(i,n);return!(r<0?a>0:a>r&&a*a/t.magnitudeSquared(i)>r)},u.prototype.computeHorizonCullingPoint=function(e,n,r){i(r)||(r=new t);for(var a=this._ellipsoid,o=l(a,e),u=0,f=0,h=n.length;f<h;++f){var d=n[f],m=s(a,d,o);u=Math.max(u,m)}return c(o,u,r)};var h=new t;u.prototype.computeHorizonCullingPointFromVertices=function(e,n,a,o,u){i(u)||(u=new t),o=r(o,t.ZERO);for(var f=this._ellipsoid,d=l(f,e),m=0,E=0,p=n.length;E<p;E+=a){h.x=n[E]+o.x,h.y=n[E+1]+o.y,h.z=n[E+2]+o.z;var _=s(f,h,d);m=Math.max(m,_)}return c(d,m,u)};var d=[];u.prototype.computeHorizonCullingPointFromRectangle=function(n,r,i){var a=o.subsample(n,r,0,d),u=e.fromPoints(a);if(!(t.magnitude(u.center)<.1*r.minimumRadius))return this.computeHorizonCullingPoint(u.center,a,i)};var m=new t,E=new t,p=new t;return u}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,m=o*s-h,E=o*c-u*s,p=u*c-d,_=4*m*p-E*E;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=m,R=-2*u*m+o*E):(y=c,T=p,R=-c*E+2*s*p);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-_);a=-R+S;var v=a/2,g=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),N=a===S?-g:-T/g;return i=T<=0?g+N:-R/(g*g+N*N+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var I=m,O=-2*u*m+o*E,M=p,w=-c*E+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-O)/3);i=2*Math.sqrt(-I);var U=Math.cos(P);a=i*U;var D=i*(-U/2-x*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,b=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),i=2*Math.sqrt(-M),U=Math.cos(P),a=i*U,D=i*(-U/2-x*Math.sin(P));var B=-c,z=a+D<2*s?a+s:D+s,q=B/z,G=F*z,V=-L*z-F*B,W=L*B,X=(s*V-u*W)/(-u*V+s*G);return b<=X?b<=q?X<=q?[b,X,q]:[b,q,X]:[q,b,X]:b<=q?[X,b,q]:X<=q?[X,q,b]:[q,X,b]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var m=r.computeRealRoots(1,s,l);if(2===m.length){var E,p=m[0],_=m[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return E=Math.sqrt(p),[h-E,h+E];if(p<0&&_>=0)return E=Math.sqrt(_),[h-E,h+E]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),g=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,v[1]<=g[0]?[v[0],v[1],g[0],g[1]]:g[1]<=v[0]?[g[0],g[1],v[0],v[1]]:v[0]>=g[0]&&v[1]<=g[1]?[g[0],v[0],v[1],g[1]]:g[0]>=v[0]&&g[1]<=v[1]?[v[0],g[0],g[1],v[1]]:v[0]>g[0]&&v[0]<g[1]?[g[0],v[0],g[1],v[1]]:[v[0],g[0],v[1],g[1]]):v):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var m,E,p=d[0],_=i-p,y=_*_,T=t/2,R=_/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*p,g=c+4*Math.abs(p);if(p<0||A*g<v*S){var N=Math.sqrt(v);m=N/2,E=0===N?0:(t*R-a)/N}else{var I=Math.sqrt(A);m=0===I?0:(t*R-a)/I,E=I/2}var O,M;0===T&&0===m?(O=0,M=0):n.sign(T)===n.sign(m)?(O=T+m,M=p/O):(M=T-m,O=p/M);var w,C;0===R&&0===E?(w=0,C=0):n.sign(R)===n.sign(E)?(w=R+E,C=o/w):(C=R-E,w=o/C);var x=r.computeRealRoots(1,O,w),P=r.computeRealRoots(1,M,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),m=e.magnitudeSquared(l)-c,E=f(h,d,m,S);if(r(E))return i.start=E.root0,i.stop=E.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function m(t,n,r,i,a){var l,f=i*i,h=a*a,m=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,E=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(m,E,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-A)),T.push(new e(i,a*R,a*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(i,a*S,a*-v)),T.push(new e(i,a*S,a*v))}return T}var g=y*y,N=_*_,I=m*m,O=y*_,M=I+N,w=2*(E*m+O),C=2*p*m+E*E-N+g,x=2*(p*E-O),P=p*p-g;if(0===M&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(M,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],b=F*F,B=Math.max(1-b,0),z=Math.sqrt(B);L=o.sign(m)===o.sign(p)?d(m*b+p,E*F,o.EPSILON12):o.sign(p)===o.sign(E*F)?d(m*b,E*F+p,o.EPSILON12):d(m*b+E*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var E={};E.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var p=new e,_=new e,y=new e,T=new e,R=new e;E.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,m=t.direction,E=e.subtract(i,r,p),A=e.subtract(a,r,_),S=e.cross(m,A,y),v=e.dot(E,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,E,R),(f=e.dot(m,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var g=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*g)<0||l>1)return;if(c=e.cross(s,E,R),(f=e.dot(m,c)*g)<0||l+f>1)return;h=e.dot(A,c)*g}return h},E.rayTriangle=function(t,n,i,a,o,u){var s=E.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;E.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=E.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};E.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;E.lineSegmentSphere=function(t,n,i,a){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;E.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var m=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,m<o)return;if(m>o){u=d*d-o,s=-d+Math.sqrt(u);var E=s/i,p=r/s;return E<p?new a(E,p):{start:p,stop:E}}var _=Math.sqrt(r/i);return new a(_,_)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var I=new e,O=new e,M=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,b=new u,B=new e,z=new e,q=new t;E.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,I);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,I),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,O),O),E=e.normalize(e.cross(f,d,M),M),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=E.x,p[7]=E.y,p[8]=E.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var A,S,v=u.multiply(u.multiply(_,T,F),R,F),g=u.multiply(u.multiply(v,y,b),p,b),N=u.multiplyByVector(v,i,C),G=m(g,e.negate(N,I),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],B),B);var k=e.normalize(e.subtract(A,i,w),w),Y=e.dot(k,a);Y>X&&(X=Y,W=e.clone(A,W))}var j=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),S=e.magnitude(e.subtract(W,i,w))*Math.sqrt(1-X*X),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return E.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},E.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return E.lineSegmentPlane(t,n,i,f),E.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return E.lineSegmentPlane(n,r,i,f),E.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return E.lineSegmentPlane(r,t,i,f),E.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return E.lineSegmentPlane(n,t,i,f),E.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return E.lineSegmentPlane(r,n,i,f),E.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return E.lineSegmentPlane(t,r,i,f),E.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},E}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return m(e)}function i(e){return m(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,m;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return E(f,e),e},m=function(e){return e=t(e),h=e.then,m=t,d=_,E(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return p(2,arguments),e(t,function(t){function u(e){E(e)}function s(e){m(e)}var c,l,f,h,d,m,E,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,E=function(e){h.push(e),--l||(m=E=_,d.reject(h))},m=function(e){f.push(e),--c||(m=E=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function m(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function E(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=m,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,m,E,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,g=0;s&&g<v;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(g+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,S);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),m=d<0?"-":T,_=m+i(String(Math.abs(d)),f,"0",!1),a(_,m,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,m=d<0?"-":T,E=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=m+Math.abs(d)[E](f),a(_,m,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return E.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=E.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){E.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}E.addSeconds(e,i,e)}function h(e,n){y.julianDate=e;var r=E.leapSeconds,i=t(r,y,l);if(i<0&&(i=~i),0===i)return E.addSeconds(e,-r[0].offset,n);if(i>=r.length)return E.addSeconds(e,-r[i-1].offset,n);var a=E.secondsDifference(r[i].julianDate,e);return 0===a?E.addSeconds(e,-r[i].offset,n):a<=1?void 0:E.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function m(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function E(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var p=new a,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;E.fromGregorianDate=function(e,t){var n=m(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new E(n[0],n[1],c.UTC)},E.fromDate=function(e,t){var n=m(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new E(n[0],n[1],c.UTC)},E.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,g=0,M=u[0],w=u[1];if(null!==(u=M.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=M.match(R)))n=+u[1],s=+u[2];else if(null!==(u=M.match(T)))n=+u[1];else{var C;if(null!==(u=M.match(A)))n=+u[1],C=+u[2],a=o(n);else if(null!==(u=M.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(C),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(w)){u=w.match(O),null!==u?(h=+u[1],p=+u[2],y=+u[3],g=1e3*+(u[4]||0),D=5):(u=w.match(I),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(N))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],b=+(u[D+2]||0);switch(L){case"+":h-=F,p-=b;break;case"-":h+=F,p+=b;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var B=60===y;for(B&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:_[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:_[s-1],l+=i;var z=m(n,s,l,h,p,y,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new E(z[0],z[1],c.UTC),B&&E.addSeconds(t,1,t),t},E.now=function(e){return E.fromDate(new Date,e)};var M=new E(0,0,c.TAI);return E.toGregorianDate=function(e,t){var n=!1,i=h(e,M);r(i)||(E.addSeconds(e,-1,M),i=h(M,M),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,m=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=m,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new a(_,p,m,y,R,A,S,n)},E.toDate=function(e){var t=E.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},E.toIso8601=function(t,n){var i,a=E.toGregorianDate(t,p);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},E.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new E(e.dayNumber,e.secondsOfDay,c.TAI)},E.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(E.secondsDifference(e,t))<=n},E.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},E.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},E.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},E.computeTaiMinusUtc=function(e){y.julianDate=e;var n=E.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},E.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},E.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},E.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},E.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},E.lessThan=function(e,t){return E.compare(e,t)<0},E.lessThanOrEquals=function(e,t){return E.compare(e,t)<=0},E.greaterThan=function(e,t){return E.compare(e,t)>0},E.greaterThanOrEquals=function(e,t){return E.compare(e,t)>=0},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return E.toIso8601(this)},E.leapSeconds=[new u(new E(2441317,43210,c.TAI),10),new u(new E(2441499,43211,c.TAI),11),new u(new E(2441683,43212,c.TAI),12),new u(new E(2442048,43213,c.TAI),13),new u(new E(2442413,43214,c.TAI),14),new u(new E(2442778,43215,c.TAI),15),new u(new E(2443144,43216,c.TAI),16),new u(new E(2443509,43217,c.TAI),17),new u(new E(2443874,43218,c.TAI),18),new u(new E(2444239,43219,c.TAI),19),new u(new E(2444786,43220,c.TAI),20),new u(new E(2445151,43221,c.TAI),21),new u(new E(2445516,43222,c.TAI),22),new u(new E(2446247,43223,c.TAI),23),new u(new E(2447161,43224,c.TAI),24),new u(new E(2447892,43225,c.TAI),25),new u(new E(2448257,43226,c.TAI),26),new u(new E(2448804,43227,c.TAI),27),new u(new E(2449169,43228,c.TAI),28),new u(new E(2449534,43229,c.TAI),29),new u(new E(2450083,43230,c.TAI),30),new u(new E(2450630,43231,c.TAI),31),new u(new E(2451179,43232,c.TAI),32),new u(new E(2453736,43233,c.TAI),33),new u(new E(2454832,43234,c.TAI),34),new u(new E(2456109,43235,c.TAI),35),new u(new E(2457204,43236,c.TAI),36),new u(new E(2457754,43237,c.TAI),37)],E}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={} +;return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function m(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==c.CANCELLED&&(--A.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){return function(t){e.state!==c.CANCELLED&&(++A.numberOfFailedRequests,--A.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function _(e){var t=m(e);return e.state=c.ACTIVE,g.push(e),++A.numberOfActiveRequests,++A.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(p(e)),t}function y(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++A.numberOfCancelledRequests,e.deferred.reject(),t&&(--A.numberOfActiveRequests,--N[e.serverKey],++A.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){A.numberOfAttemptedRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(A.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+A.numberOfAttemptedRequests),A.numberOfActiveRequests>0&&console.log("Number of active requests: "+A.numberOfActiveRequests),A.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+A.numberOfCancelledRequests),A.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+A.numberOfCancelledActiveRequests),A.numberOfFailedRequests>0&&console.log("Number of failed requests: "+A.numberOfFailedRequests),T())}var A={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},S=20,v=new o({comparator:l});v.maximumLength=S,v.reserve(S);var g=[],N={},I="undefined"!=typeof document?new e(document.location.href):new e,O=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=O,i(f,{statistics:{get:function(){return A}},priorityHeapLength:{get:function(){return S},set:function(e){if(e<S)for(;v.length>e;){var t=v.pop();y(t)}S=e,v.maximumLength=e,v.reserve(e)}}}),f.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&y(t),t.state===c.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=v.internalArray,a=v.length;for(e=0;e<a;++e)h(i[e]);v.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&v.length>0;)t=v.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):y(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(I);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=N[i];return r(a)||(N[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return O.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++A.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return _(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=v.insert(e);if(r(t)){if(t===e)return;y(t)}return m(e)}},f.clearForSpecs=function(){for(;v.length>0;){y(v.pop())}for(var e=g.length,t=0;t<e;++t)y(g[t]);g.length=0,N={},A.numberOfAttemptedRequests=0,A.numberOfActiveRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0,A.numberOfFailedRequests=0,A.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=v,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E,p,_,y,T,R,A,S,v,g,N){"use strict";function I(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=_(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function O(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=p(n):e.query=r[0]}function M(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function w(e){if(e.state===A.ISSUED||e.state===A.ACTIVE)throw new S("The Resource is already being fetched.");e.state=A.UNISSUED,e.deferred=void 0}function C(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=M(e.templateValues,{}),this._queryParameters=M(e.queryParameters,{}),this.headers=M(e.headers,{}),this.request=i(e.request,new y),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function x(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=N.defer();return C._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=A.UNISSUED,n.deferred=void 0,x(e,t)):N.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=N.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},C._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=A.UNISSUED,i.deferred=void 0,P(e,t,n)):N.reject(r)})})}function U(e,t){w(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=C._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=A.UNISSUED,n.deferred=void 0,e.fetch(t)):N.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var b=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();C.createIfNeeded=function(e,t){if(e instanceof C)return e.clone();if("string"!=typeof e)return e;var n=M(t,{});return n.url=e,new C(n)},o(C,{isBlobSupported:{get:function(){return b}}}),o(C.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);I(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return E(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return m(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),C.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new g(this._url);e&&O(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},C.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},C.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},C.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new g(e.url);I(n,t),n.fragment=void 0,t._url=n.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},C.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var n=this;return N(t(this,e)).then(function(e){return++n._retryCount,e})},C.prototype.clone=function(e){return a(e)||(e=new C({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},C.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},C.prototype.appendForwardSlash=function(){this._url=e(this._url)},C.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},C.fetchArrayBuffer=function(e){return new C(e).fetchArrayBuffer()},C.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},C.fetchBlob=function(e){return new C(e).fetchBlob()},C.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),w(this.request),!b||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return x(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new C({url:t}),x(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),N.reject(e)})}},C.fetchImage=function(e){return new C(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},C.prototype.fetchText=function(){return this.fetch({responseType:"text"})},C.fetchText=function(e){return new C(e).fetchText()},C.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},C.fetchJson=function(e){return new C(e).fetchJson()},C.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},C.fetchXML=function(e){return new C(e).fetchXML()},C.prototype.fetchJsonp=function(e){e=i(e,"callback"),w(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},C.fetchJsonp=function(e){return new C(e).fetchJsonp(e.callbackParameterName)},C.prototype.fetch=function(e){return e=M(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return C.fetch=function(e){return new C(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C.prototype.post=function(e,n){return t.defined("data",e),n=M(n,{}),n.method="POST",n.data=e,U(this,n)},C.post=function(e){return new C(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C._Implementations={},C._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(v.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},C._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(v.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new S("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},C._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},C._DefaultImplementations={},C._DefaultImplementations.createImage=C._Implementations.createImage,C._DefaultImplementations.loadWithXhr=C._Implementations.loadWithXhr,C._DefaultImplementations.loadAndExecuteScript=C._Implementations.loadAndExecuteScript,C.DEFAULT=c(new C({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),C}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))m(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){m(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else m(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function m(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||m<0||E<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=m,e._taiMinusUtcSecondsColumn=E,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var S=p[R+i],v=p[R+E],g=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,v,f.TAI);if(_.push(N),T){if(v!==y&&r(y)){var I=o.leapSeconds,O=t(I,N,d);if(O<0){var M=new u(N,v);I.splice(~O,0,M)}}y=v}}}function E(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return E(e,n,i,s,u),u;if(r.equals(l))return E(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,m=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-m;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?m=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,m,_),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),m=!r(h),E=m||o.greaterThanOrEquals(h,e);if(d&&E)return s=u,!m&&h.equals(e)&&++s,l=s+1,_(this,a,this._samples,e,s,l,n),n}var p=t(a,e,o.compare,this._dateColumn);return p>=0?(p<a.length-1&&a[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){ +var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],m=f;m<=h;++m)d.push(l(this,m));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var m,E,p=a-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(m=0;m<=u;++m)_[m]=p-R[m];for(m=0;m<=u;++m){for(T[m]=1,E=0;E<=u;++E)E!==m&&(T[m]*=_[E]);T[m]*=y[m];var A=3*(s+m);n.x+=T[m]*d[A++],n.y+=T[m]*d[A++],n.s+=T[m]*d[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function a(){return i()&&S}function o(){if(!t(v)&&(v=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,g=r(e[1]))}return v}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(N=!0,I=r(e[1]),I.isNightly=!!e[2])}return N}function c(){return s()&&I}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,M=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,M=r(e[1]))}return O}function f(){return l()&&M}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function m(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function E(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return m()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,g,N,I,O,M,w,C,x,P,U,D,L,F,b={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:m,firefoxVersion:p,isWindows:E,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return b.supportsFullscreen=function(){return n.supportsFullscreen()},b.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},b.supportsWebWorkers=function(){return"undefined"!=typeof Worker},b}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],m=e[u.COLUMN2ROW2],E=h+d+m;if(E>0)n=Math.sqrt(E+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),m>h&&m>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,m=new s,E=new s;s.fromHeadingPitchRoll=function(t,n){return E=s.fromAxisAngle(e.UNIT_X,t.roll,h),m=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(m,E,m),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,m=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=m,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,g=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=S=s.negate(t,S)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),g=s.multiplyByScalar(a,Math.sin(n*u),g),r=s.add(v,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var N=new e,I=new e,O=new s,M=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,O);s.multiply(a,r,M);var o=s.log(M,N);s.multiply(a,t,M);var u=s.log(M,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,O),s.multiply(n,O,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,O),u=s.slerp(n,r,i,M);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,C=1.9011074535173003,x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,b=2*F+1;x[L]=1/(F*b),P[L]=F/b}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),m=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(m,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,O),u=s.fastSlerp(n,r,i,M);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,I=new n,O=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=A[e][t],a=e+t;return u(v[a])?r=v[a]:(r=function(r,a,s){if(u(s)||(s=new _),E.equalsEpsilon(r.x,0,E.EPSILON14)&&E.equalsEpsilon(r.y,0,E.EPSILON14)){var c=E.sign(r.z);n.unpack(S[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(S[t],0,I),"east"!==t&&"west"!==t&&n.multiplyByScalar(I,c,I),n.unpack(S[i],0,O),"east"!==i&&"west"!==i&&n.multiplyByScalar(O,c,O)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),N=g[e],I=g[t],O=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=I.x,s[5]=I.y,s[6]=I.z,s[7]=0,s[8]=O.x,s[9]=O.y,s[10]=O.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var M=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,M),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return a=i(e,r,a),_.multiply(a,s,a)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(a,P);return y.fromRotationMatrix(o,i)};var U=E.TWO_PI/86400,D=new m;R.computeTemeToPseudoFixedMatrix=function(e,t){D=m.addSeconds(e,-m.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%E.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),b=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=b;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-a.s,B),h=p.multiply(l,f,b),d=e.dayNumber,_=e.secondsOfDay-m.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=_/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*E.TWO_PI;var v=p.fromRotationZ(S,B),g=p.multiply(h,v,b),N=Math.cos(n.xPoleWander),I=Math.cos(n.yPoleWander),O=Math.sin(n.xPoleWander),M=Math.sin(n.yPoleWander),w=r-2451545+i/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*E.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=B;return U[0]=N*x,U[1]=N*P,U[2]=O,U[3]=-I*P+M*O*x,U[4]=I*x+M*O*P,U[5]=-M*N,U[6]=-M*P-I*O*x,U[7]=M*x-I*O*P,U[8]=I*N,p.multiply(g,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return _.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,E.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new p),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new n,k=new n,Y=new p,j=new _,Z=new _;return R.basisTo2D=function(e,t,r){var i=_.getTranslation(t,k),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=_.inverseTransformation(s,Z),l=_.getRotation(t,Y),f=_.multiplyByMatrix3(c,l,r);return _.multiply(W,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=_.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,j);return _.multiply(W,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function m(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,E)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,E));var a=n.fromCartesian4(l.getColumn(r,2,E));this._plane=f.fromPointNormal(e,a)}var E=new r;o(m.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;m.fromPoints=function(t,n){return new m(e.fromPoints(t,p).center,n)};var _=new h,y=new n;m.prototype.projectPointOntoPlane=function(e,r){var i=_;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,y);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},m.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},m.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=_;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,y);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},m.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return m.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},m}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E){"use strict";function p(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=d.clone(a(t,d.ZERO))}function _(e,t,r,i,a,u,s,c){o(c)||(c=new p);var l=c.halfAxes;d.setColumn(l,0,e.xAxis,l),d.setColumn(l,1,e.yAxis,l),d.setColumn(l,2,e.zAxis,l);var f=I;f.x=(t+r)/2,f.y=(i+a)/2,f.z=(u+s)/2;var h=O;h.x=(r-t)/2,h.y=(a-i)/2,h.z=(s-u)/2;var m=c.center;return f=d.multiplyByVector(l,f,f),n.add(e.origin,f,m),d.multiplyByScale(l,h,l),c}p.packedLength=n.packedLength+d.packedLength,p.pack=function(e,t,r){return r=a(r,0),n.pack(e.center,t,r),d.pack(e.halfAxes,t,r+n.packedLength),t},p.unpack=function(e,t,r){return t=a(t,0),o(r)||(r=new p),n.unpack(e,t,r.center),d.unpack(e,t+n.packedLength,r.halfAxes),r};var y=new n,T=new n,R=new n,A=new n,S=new n,v=new n,g=new d,N={unitary:new d,diagonal:new d};p.fromPoints=function(e,t){if(o(t)||(t=new p),!o(e)||0===e.length)return t.halfAxes=d.ZERO,t.center=n.ZERO,t;var r,i=e.length,a=n.clone(e[0],y);for(r=1;r<i;r++)n.add(a,e[r],a);var u=1/i;n.multiplyByScalar(a,u,a);var s,c=0,l=0,f=0,h=0,m=0,E=0;for(r=0;r<i;r++)s=n.subtract(e[r],a,T),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,h+=s.y*s.y,m+=s.y*s.z,E+=s.z*s.z;c*=u,l*=u,f*=u,h*=u,m*=u,E*=u;var _=g;_[0]=c,_[1]=l,_[2]=f,_[3]=l,_[4]=h,_[5]=m,_[6]=f,_[7]=m,_[8]=E;var I=d.computeEigenDecomposition(_,N),O=d.clone(I.unitary,t.halfAxes),M=d.getColumn(O,0,A),w=d.getColumn(O,1,S),C=d.getColumn(O,2,v),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<i;r++)s=e[r],x=Math.max(n.dot(M,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(M,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);M=n.multiplyByScalar(M,.5*(D+x),M),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var b=n.add(M,w,t.center);n.add(b,C,b);var B=R;return B.x=x-D,B.y=P-L,B.z=U-F,n.multiplyByScalar(B,.5,B),d.multiplyByScale(t.halfAxes,B,t.halfAxes),t};var I=new n,O=new n,M=new r,w=new n,C=[new r,new r,new r,new r,new r,new r,new r,new r],x=[new n,new n,new n,new n,new n,new n,new n,new n],P=[new t,new t,new t,new t,new t,new t,new t,new t];p.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,s.WGS84);var o=E.center(e,M),u=r.cartographicToCartesian(o,w),l=new c(u,r),f=l.plane,h=C[0],d=C[1],p=C[2],y=C[3],T=C[4],R=C[5],A=C[6],S=C[7],v=o.longitude,g=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=g,h.latitude=d.latitude=p.latitude=e.north,A.longitude=S.longitude=h.longitude=e.west,R.longitude=d.longitude=v,T.longitude=y.longitude=p.longitude=e.east,p.height=d.height=h.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(C,x),l.projectPointsToNearestOnPlane(x,P);var N=Math.min(P[6].x,P[7].x,P[0].x),I=Math.max(P[2].x,P[3].x,P[4].x),O=Math.min(P[4].y,P[5].y,P[6].y),U=Math.max(P[0].y,P[1].y,P[2].y);return p.height=h.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(C,x),_(l,N,I,O,U,Math.min(m.getPointDistance(f,x[0]),m.getPointDistance(f,x[2]),m.getPointDistance(f,x[4]),m.getPointDistance(f,x[6])),n,i)},p.clone=function(e,t){if(o(e))return o(t)?(n.clone(e.center,t.center),d.clone(e.halfAxes,t.halfAxes),t):new p(e.center,e.halfAxes)},p.intersectPlane=function(e,t){var r=e.center,i=t.normal,a=e.halfAxes,o=i.x,u=i.y,s=i.z,c=Math.abs(o*a[d.COLUMN0ROW0]+u*a[d.COLUMN0ROW1]+s*a[d.COLUMN0ROW2])+Math.abs(o*a[d.COLUMN1ROW0]+u*a[d.COLUMN1ROW1]+s*a[d.COLUMN1ROW2])+Math.abs(o*a[d.COLUMN2ROW0]+u*a[d.COLUMN2ROW1]+s*a[d.COLUMN2ROW2]),f=n.dot(i,r)+t.distance;return f<=-c?l.OUTSIDE:f>=c?l.INSIDE:l.INTERSECTING};var U=new n,D=new n,L=new n,F=new n;p.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,I),i=e.halfAxes,a=d.getColumn(i,0,U),o=d.getColumn(i,1,D),u=d.getColumn(i,2,L),s=n.magnitude(a),c=n.magnitude(o),l=n.magnitude(u);n.normalize(a,a),n.normalize(o,o),n.normalize(u,u);var f=F;f.x=n.dot(r,a),f.y=n.dot(r,o),f.z=n.dot(r,u);var h,m=0;return f.x<-s?(h=f.x+s,m+=h*h):f.x>s&&(h=f.x-s,m+=h*h),f.y<-c?(h=f.y+c,m+=h*h):f.y>c&&(h=f.y-c,m+=h*h),f.z<-l?(h=f.z+l,m+=h*h):f.z>l&&(h=f.z-l,m+=h*h),m};var b=new n,B=new n;p.computePlaneDistances=function(e,t,r,i){o(i)||(i=new f);var a=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,l=d.getColumn(c,0,U),h=d.getColumn(c,1,D),m=d.getColumn(c,2,L),E=n.add(l,h,b);n.add(E,m,E),n.add(E,s,E);var p=n.subtract(E,t,B),_=n.dot(r,p);return a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,E),n.add(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,E),n.subtract(E,h,E),n.add(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,E),n.subtract(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.add(E,h,E),n.add(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.add(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.subtract(E,h,E),n.add(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.subtract(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),i.start=a,i.stop=u,i};var z=new e;return p.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,z);return!n.isBoundingSphereVisible(r)},p.prototype.intersectPlane=function(e){return p.intersectPlane(this,e)},p.prototype.distanceSquaredTo=function(e){return p.distanceSquaredTo(this,e)},p.prototype.computePlaneDistances=function(e,t,n){return p.computePlaneDistances(this,e,t,n)},p.prototype.isOccluded=function(e){return p.isOccluded(this,e)},p.equals=function(e,t){return e===t||o(e)&&o(t)&&n.equals(e.center,t.center)&&d.equals(e.halfAxes,t.halfAxes)},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,n,r,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,n){return u.octDecodeInRange(e,t,255,n)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),i=256*(n-r);return u.octDecode(r,i,t)},u.octPack=function(e,t,n,r){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(n,s);return r.x=65536*o.x+i,r.y=65536*o.y+a,r},u.octUnpack=function(e,t,n,r){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,n),u.octDecode(a,s,r)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},u.zigZagDeltaDecode=function(e,t,n){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,r(n)&&(s+=o(n[c]),n[c]=s)},u}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989, +TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,i,a,o,u,s){"use strict";function c(e,t,r,o,c,h){var p,_,y,T;if(a(e)&&a(t)&&a(r)&&a(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),v=r-t;p=Math.max(n.maximumComponent(S),v)<E-1?s.BITS12:s.NONE,_=e.center,y=u.inverseTransformation(o,new u);var g=n.negate(R,l);u.multiply(u.fromTranslation(g,d),y,y);var N=l;N.x=1/S.x,N.y=1/S.y,N.z=1/S.z,u.multiply(u.fromScale(N,d),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var I=u.fromTranslation(R,d),O=u.fromScale(S,m),M=u.multiply(I,O,d);u.multiply(o,M,o),u.multiply(T,M,T)}this.quantization=p,this.minimumHeight=t,this.maximumHeight=r,this.center=_,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=i(h,!1)}var l=new n,f=new n,h=new t,d=new u,m=new u,E=Math.pow(2,12);c.prototype.encode=function(r,i,a,c,f,d,m){var E=c.x,p=c.y;if(this.quantization===s.BITS12){a=u.multiplyByPoint(this.toScaledENU,a,l),a.x=o.clamp(a.x,0,1),a.y=o.clamp(a.y,0,1),a.z=o.clamp(a.z,0,1);var _=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/_,0,1);t.fromElements(a.x,a.y,h);var T=e.compressTextureCoordinates(h);t.fromElements(a.z,y,h);var R=e.compressTextureCoordinates(h);t.fromElements(E,p,h);var A=e.compressTextureCoordinates(h);if(r[i++]=T,r[i++]=R,r[i++]=A,this.hasWebMercatorT){t.fromElements(m,0,h);var S=e.compressTextureCoordinates(h);r[i++]=S}}else n.subtract(a,this.center,l),r[i++]=l.x,r[i++]=l.y,r[i++]=l.z,r[i++]=f,r[i++]=E,r[i++]=p,this.hasWebMercatorT&&(r[i++]=m);return this.hasVertexNormals&&(r[i++]=e.octPackFloat(d)),i},c.prototype.decodePosition=function(t,r,i){if(a(i)||(i=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],h);i.x=o.x,i.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],h);return i.z=c.x,u.multiplyByPoint(this.fromScaledENU,i,i)}return i.x=t[r],i.y=t[r+1],i.z=t[r+2],n.add(i,this.center,i)},c.prototype.decodeTextureCoordinates=function(n,r,i){return a(i)||(i=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],i):t.fromElements(n[r+4],n[r+5],i)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var i=e[n]/256,a=Math.floor(i),o=256*(i-a);return t.fromElements(a,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var p={position3DAndHeight:0,textureCoordAndEncodedNormals:1},_={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,i=r.getSizeInBytes(n);if(this.quantization===s.NONE){var a=2;return this.hasWebMercatorT&&++a,this.hasVertexNormals&&++a,t=(4+a)*i,[{index:p.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:p.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:a,offsetInBytes:4*i,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*i,[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:_.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*i,strideInBytes:t}]):[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?p:_},c.clone=function(e,t){return a(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},s.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=s.mercatorAngleToGeodeticLatitude(e.y*i),u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},s}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,i=t.message;n=e(r)&&e(i)?r+": "+i:t.toString();var a=t.stack;return e(a)&&(n+="\n"+a),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var i,a=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;a.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,a)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(i)||(i=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(a.length=0);try{i(o,a)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),i(o)}}}return r}),define("Workers/createVerticesFromGoogleEarthEnterpriseBuffer",["../Core/AxisAlignedBoundingBox","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defaultValue","../Core/defined","../Core/Ellipsoid","../Core/EllipsoidalOccluder","../Core/Math","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/Rectangle","../Core/RuntimeError","../Core/TerrainEncoding","../Core/Transforms","../Core/WebMercatorProjection","./createTaskProcessorWorker"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E,p,_){"use strict";function y(e,t,n){n=a(n,c);for(var r=e.length,i=0;i<r;++i)if(n.equalsEpsilon(e[i],t,c.EPSILON12))return i;return-1}function T(e,t){e.ellipsoid=u.clone(e.ellipsoid),e.rectangle=h.clone(e.rectangle);var n=R(e.buffer,e.relativeToCenter,e.ellipsoid,e.rectangle,e.nativeRectangle,e.exaggeration,e.skirtHeight,e.includeWebMercatorT,e.negativeAltitudeExponentBias,e.negativeElevationThreshold),r=n.vertices;t.push(r.buffer);var i=n.indices;return t.push(i.buffer),{vertices:r.buffer,indices:i.buffer,numberOfAttributes:n.encoding.getStride(),minimumHeight:n.minimumHeight,maximumHeight:n.maximumHeight,boundingSphere3D:n.boundingSphere3D,orientedBoundingBox:n.orientedBoundingBox,occludeePointInScaledSpace:n.occludeePointInScaledSpace,encoding:n.encoding,vertexCountWithoutSkirts:n.vertexCountWithoutSkirts,skirtIndex:n.skirtIndex}}function R(a,u,h,_,T,R,P,U,D,L){var F,b,B,z,q,G;o(_)?(F=_.west,b=_.south,B=_.east,z=_.north,q=_.width,G=_.height):(F=c.toRadians(T.west),b=c.toRadians(T.south),B=c.toRadians(T.east),z=c.toRadians(T.north),q=c.toRadians(_.width),G=c.toRadians(_.height));var V,W,X=[b,z],H=[F,B],k=E.eastNorthUpToFixedFrame(u,h),Y=l.inverseTransformation(k,x);U&&(V=p.geodeticLatitudeToMercatorAngle(b),W=1/(p.geodeticLatitudeToMercatorAngle(z)-V));var j=new DataView(a),Z=Number.POSITIVE_INFINITY,K=Number.NEGATIVE_INFINITY,J=w;J.x=Number.POSITIVE_INFINITY,J.y=Number.POSITIVE_INFINITY,J.z=Number.POSITIVE_INFINITY;var Q=C;Q.x=Number.NEGATIVE_INFINITY,Q.y=Number.NEGATIVE_INFINITY,Q.z=Number.NEGATIVE_INFINITY;var $,ee,te=0,ne=0,re=0;for(ee=0;ee<4;++ee){var ie=te;$=j.getUint32(ie,!0),ie+=g;var ae=c.toRadians(180*j.getFloat64(ie,!0));ie+=I,-1===y(H,ae)&&H.push(ae);var oe=c.toRadians(180*j.getFloat64(ie,!0));ie+=I,-1===y(X,oe)&&X.push(oe),ie+=2*I;var ue=j.getInt32(ie,!0);ie+=v,ne+=ue,ue=j.getInt32(ie,!0),re+=3*ue,te+=$+g}var se=[],ce=[],le=new Array(ne),fe=new Array(ne),he=new Array(ne),de=U?new Array(ne):[],me=new Array(re),Ee=[],pe=[],_e=[],ye=[],Te=0,Re=0;for(te=0,ee=0;ee<4;++ee){$=j.getUint32(te,!0),te+=g;var Ae=te,Se=c.toRadians(180*j.getFloat64(te,!0));te+=I;var ve=c.toRadians(180*j.getFloat64(te,!0));te+=I;var ge=c.toRadians(180*j.getFloat64(te,!0)),Ne=.5*ge;te+=I;var Ie=c.toRadians(180*j.getFloat64(te,!0)),Oe=.5*Ie;te+=I;var Me=j.getInt32(te,!0);te+=v;var we=j.getInt32(te,!0);te+=v,te+=v;for(var Ce=new Array(Me),xe=0;xe<Me;++xe){var Pe=Se+j.getUint8(te++)*ge;O.longitude=Pe;var Ue=ve+j.getUint8(te++)*Ie;O.latitude=Ue;var De=6371010*j.getFloat32(te,!0);if(te+=N,De<L&&(De*=D),De*=R,O.height=De,-1!==y(H,Pe)||-1!==y(X,Ue)){var Le=y(se,O,i);if(-1!==Le){Ce[xe]=ce[Le];continue}se.push(i.clone(O)),ce.push(Te)}Ce[xe]=Te,Math.abs(Pe-F)<Ne?Ee.push({index:Te,cartographic:i.clone(O)}):Math.abs(Pe-B)<Ne?_e.push({index:Te,cartographic:i.clone(O)}):Math.abs(Ue-b)<Oe?pe.push({index:Te,cartographic:i.clone(O)}):Math.abs(Ue-z)<Oe&&ye.push({index:Te,cartographic:i.clone(O)}),Z=Math.min(De,Z),K=Math.max(De,K),he[Te]=De;var Fe=h.cartographicToCartesian(O);le[Te]=Fe,U&&(de[Te]=(p.geodeticLatitudeToMercatorAngle(Ue)-V)*W),l.multiplyByPoint(Y,Fe,M),r.minimumByComponent(M,J,J),r.maximumByComponent(M,Q,Q);var be=(Pe-F)/(B-F);be=c.clamp(be,0,1);var Be=(Ue-b)/(z-b);Be=c.clamp(Be,0,1),fe[Te]=new n(be,Be),++Te}for(var ze=3*we,qe=0;qe<ze;++qe,++Re)me[Re]=Ce[j.getUint16(te,!0)],te+=S;if($!==te-Ae)throw new d("Invalid terrain tile.")}le.length=Te,fe.length=Te,he.length=Te,U&&(de.length=Te);var Ge=Te,Ve=Re,We={hMin:Z,lastBorderPoint:void 0,skirtHeight:P,toENU:Y,ellipsoid:h,minimum:J,maximum:Q};Ee.sort(function(e,t){return t.cartographic.latitude-e.cartographic.latitude}),pe.sort(function(e,t){return e.cartographic.longitude-t.cartographic.longitude}),_e.sort(function(e,t){return e.cartographic.latitude-t.cartographic.latitude}),ye.sort(function(e,t){return t.cartographic.longitude-e.cartographic.longitude});if(A(le,he,fe,de,me,We,Ee,-1e-5*q,!0,-1e-5*G),A(le,he,fe,de,me,We,pe,-1e-5*G,!1),A(le,he,fe,de,me,We,_e,1e-5*q,!0,1e-5*G),A(le,he,fe,de,me,We,ye,1e-5*G,!1),Ee.length>0&&ye.length>0){var Xe=Ee[0].index,He=Ge,ke=ye[ye.length-1].index,Ye=le.length-1;me.push(ke,Ye,He,He,Xe,ke)}ne=le.length;var je,Ze=t.fromPoints(le);o(_)&&_.width<c.PI_OVER_TWO+c.EPSILON5&&(je=f.fromRectangle(_,Z,K,h));for(var Ke=new s(h),Je=Ke.computeHorizonCullingPoint(u,le),Qe=new e(J,Q,u),$e=new m(Qe,We.hMin,K,k,!1,U),et=new Float32Array(ne*$e.getStride()),tt=0,nt=0;nt<ne;++nt)tt=$e.encode(et,tt,le[nt],fe[nt],he[nt],void 0,de[nt]);return{vertices:et,indices:new Uint16Array(me),maximumHeight:K,minimumHeight:Z,encoding:$e,boundingSphere3D:Ze,orientedBoundingBox:je,occludeePointInScaledSpace:Je,vertexCountWithoutSkirts:Ge,skirtIndex:Ve}}function A(e,t,a,u,s,f,h,d,m,E){for(var p=h.length,_=0;_<p;++_){var y=h[_],T=y.cartographic,R=y.index,A=e.length,S=T.longitude,v=T.latitude;v=c.clamp(v,-c.PI_OVER_TWO,c.PI_OVER_TWO);var g=T.height-f.skirtHeight;f.hMin=Math.min(f.hMin,g),i.fromRadians(S,v,g,O),m&&(O.longitude+=d),m?_===p-1?O.latitude+=E:0===_&&(O.latitude-=E):O.latitude+=d;var N=f.ellipsoid.cartographicToCartesian(O);e.push(N),t.push(g),a.push(n.clone(a[R])),u.length>0&&u.push(u[R]),l.multiplyByPoint(f.toENU,N,M);var I=f.minimum,w=f.maximum;r.minimumByComponent(M,I,I),r.maximumByComponent(M,w,w);var C=f.lastBorderPoint;if(o(C)){var x=C.index;s.push(x,A-1,A,A,R,x)}f.lastBorderPoint=y}}var S=Uint16Array.BYTES_PER_ELEMENT,v=Int32Array.BYTES_PER_ELEMENT,g=Uint32Array.BYTES_PER_ELEMENT,N=Float32Array.BYTES_PER_ELEMENT,I=Float64Array.BYTES_PER_ELEMENT,O=new i,M=new r,w=new r,C=new r,x=new l;return _(T)})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromHeightmap.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromHeightmap.js index 372db0a4..89e72c9a 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromHeightmap.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromHeightmap.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var d=new o,h=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);d.x=c*Math.cos(e),d.y=c*Math.sin(e),d.z=Math.sin(r),d=o.normalize(d,d),o.multiplyComponents(s,d,h);var l=Math.sqrt(o.dot(d,h));return h=o.divideByScalar(h,l,h),d=o.multiplyByScalar(d,a,d),n(u)||(u=new o),o.add(h,d,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,d=n.z,h=a.x,E=a.y,m=a.z,_=l*l*h*h,p=f*f*E*E,T=d*d*m*m,y=_+p+T,R=Math.sqrt(1/y),A=e.multiplyByScalar(n,R,i);if(y<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,N=u.y,M=u.z,O=o;O.x=A.x*S*2,O.y=A.y*N*2,O.z=A.z*M*2;var I,v,g,w,C,x,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),b=0;do{B-=b,g=1/(1+B*S),w=1/(1+B*N),C=1/(1+B*M),x=g*g,P=w*w,U=C*C,D=x*g,L=P*w,F=U*C,I=_*x+p*P+T*U-1,v=_*D*S+p*L*N+T*F*M;b=I/(-2*v)}while(Math.abs(I)>r.EPSILON12);return t(c)?(c.x=l*g,c.y=f*w,c.z=d*C,c):new e(l*g,f*w,d*C)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),d=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),h=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:d,_=r(n)?n._centerToleranceSquared:h,p=o(t,E,m,_,c);if(r(p)){var T=e.multiplyComponents(p,m,s);T=e.normalize(T,T);var y=e.subtract(t,p,l),R=Math.atan2(T.y,T.x),A=Math.asin(T.z),S=i.sign(e.dot(y,t))*e.magnitude(y);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var d=new e,h=new e;f.prototype.cartographicToCartesian=function(t,n){var r=d,i=h;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,_=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,d=1;d<f;d++){var h=t[d],E=h.x,m=h.y,_=h.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(_,u),l=Math.max(_,l)}var p=n.minimum;p.x=a,p.y=o,p.z=u;var T=n.maximum;T.x=s,T.y=c,T.z=l;var y=e.add(p,T,n.center);return e.multiplyByScalar(y,.5,y),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],d=m[a];if(Math.abs(e[s.getElementIndex(d,f)])>n){var h,_=e[s.getElementIndex(d,d)],p=e[s.getElementIndex(f,f)],T=e[s.getElementIndex(d,f)],y=(_-p)/2/T;h=y<0?-1/(-y+Math.sqrt(1+y*y)):1/(y+Math.sqrt(1+y*y)),c=1/Math.sqrt(1+h*h),l=h*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(d,d)]=c,t[s.getElementIndex(d,f)]=l,t[s.getElementIndex(f,d)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,d=e.z*e.w,h=e.w*e.w,E=n-u-f+h,m=2*(a-d),_=2*(i+l),p=2*(a+d),T=-n+u-f+h,y=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+h;return r(t)?(t[0]=E,t[1]=p,t[2]=R,t[3]=m,t[4]=T,t[5]=A,t[6]=_,t[7]=y,t[8]=S,t):new s(E,m,_,p,T,y,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,d=c*u+i*o*a,h=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,_=-o,p=c*n,T=i*n;return r(t)?(t[0]=l,t[1]=h,t[2]=_,t[3]=f,t[4]=E,t[5]=p,t[6]=d,t[7]=m,t[8]=T,t):new s(l,f,d,h,E,m,_,p,T)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var d=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],d)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],d)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],d)),n};var h=new e;s.getMaximumScale=function(t){return s.getScale(t,h),e.maximumComponent(h)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],_=new s,p=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),d=t.diagonal=s.clone(e,t.diagonal),h=n*c(d);i<10&&l(d)>h;)f(d,_),s.transpose(_,p),s.multiply(d,_,d),s.multiply(p,d,d),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],d=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var h=1/d;return s.multiplyByScalar(t,h,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t}, -o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,d,h,E,m,_){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(h,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(d,0),this[15]=r(_,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,d=t.x*t.w,h=t.y*t.y,E=t.y*t.z,m=t.y*t.w,_=t.z*t.z,p=t.z*t.w,T=t.w*t.w,y=s-h-_+T,R=2*(c-p),A=2*(f+m),S=2*(c+p),N=-s+h-_+T,M=2*(E-d),O=2*(f-m),I=2*(E+d),v=-s-h+_+T;return r[0]=y*i,r[1]=S*i,r[2]=O*i,r[3]=0,r[4]=R*o,r[5]=N*o,r[6]=I*o,r[7]=0,r[8]=A*u,r[9]=M*u,r[10]=v*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,d=new e,h=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,d),d),e.normalize(e.cross(d,f,h),h);var u=d.x,s=d.y,c=d.z,E=f.x,m=f.y,_=f.z,p=h.x,T=h.y,y=h.z,R=r.x,A=r.y,S=r.z,N=u*-R+s*-A+c*-S,M=p*-R+T*-A+y*-S,O=E*R+m*A+_*S;return a(n)?(n[0]=u,n[1]=p,n[2]=-E,n[3]=0,n[4]=s,n[5]=T,n[6]=-m,n[7]=0,n[8]=c,n[9]=y,n[10]=-_,n[11]=0,n[12]=N,n[13]=M,n[14]=O,n[15]=1,n):new l(u,s,c,N,p,T,y,M,-E,-m,-_,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,d=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=d,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),d=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=d,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),d=c,h=l,E=f,m=i+c,_=o+l,p=t+f;return a[0]=d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=h,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=_,a[14]=p,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],d=e[9],h=e[10],E=e[11],m=e[12],_=e[13],p=e[14],T=e[15],y=t[0],R=t[1],A=t[2],S=t[3],N=t[4],M=t[5],O=t[6],I=t[7],v=t[8],g=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*y+u*R+f*A+m*S,F=a*y+s*R+d*A+_*S,B=i*y+c*R+h*A+p*S,b=o*y+l*R+E*A+T*S,z=r*N+u*M+f*O+m*I,q=a*N+s*M+d*O+_*I,G=i*N+c*M+h*O+p*I,W=o*N+l*M+E*O+T*I,V=r*v+u*g+f*w+m*C,X=a*v+s*g+d*w+_*C,H=i*v+c*g+h*w+p*C,Y=o*v+l*g+E*w+T*C,k=r*x+u*P+f*U+m*D,j=a*x+s*P+d*U+_*D,Z=i*x+c*P+h*U+p*D,K=o*x+l*P+E*U+T*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=V,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=e[12],h=e[13],E=e[14],m=t[0],_=t[1],p=t[2],T=t[4],y=t[5],R=t[6],A=t[8],S=t[9],N=t[10],M=t[12],O=t[13],I=t[14],v=r*m+o*_+c*p,g=a*m+u*_+l*p,w=i*m+s*_+f*p,C=r*T+o*y+c*R,x=a*T+u*y+l*R,P=i*T+s*y+f*R,U=r*A+o*S+c*N,D=a*A+u*S+l*N,L=i*A+s*S+f*N,F=r*M+o*O+c*I+d,B=a*M+u*O+l*I+h,b=i*M+s*O+f*I+E;return n[0]=v,n[1]=g,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],d=t[0],h=t[1],E=t[2],m=t[3],_=t[4],p=t[5],T=t[6],y=t[7],R=t[8],A=r*d+o*h+c*E,S=a*d+u*h+l*E,N=i*d+s*h+f*E,M=r*m+o*_+c*p,O=a*m+u*_+l*p,I=i*m+s*_+f*p,v=r*T+o*y+c*R,g=a*T+u*y+l*R,w=i*T+s*y+f*R;return n[0]=A,n[1]=S,n[2]=N,n[3]=0,n[4]=M,n[5]=O,n[6]=I,n[7]=0,n[8]=v,n[9]=g,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var _=new e;l.multiplyByUniformScale=function(e,t,n){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var p=new s,T=new s,y=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,p),T,u.EPSILON7)&&t.equals(l.getRow(e,3,y),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],d=e[5],h=e[9],E=e[13],m=e[2],_=e[6],A=e[10],S=e[14],N=e[3],M=e[7],O=e[11],I=e[15],v=A*I,g=S*O,w=_*I,C=S*M,x=_*O,P=A*M,U=m*I,D=S*N,L=m*O,F=A*N,B=m*M,b=_*N,z=v*d+C*h+x*E-(g*d+w*h+P*E),q=g*f+U*h+F*E-(v*f+D*h+L*E),G=w*f+D*d+B*E-(C*f+U*d+b*E),W=P*f+L*d+b*h-(x*f+F*d+B*h),V=g*a+w*i+P*o-(v*a+C*i+x*o),X=v*r+D*i+L*o-(g*r+U*i+F*o),H=C*r+U*a+b*o-(w*r+D*a+B*o),Y=x*r+F*a+B*i-(P*r+L*a+b*i);v=i*E,g=o*h,w=a*E,C=o*d,x=a*h,P=i*d,U=r*E,D=o*f,L=r*h,F=i*f,B=r*d,b=a*f;var k=v*M+C*O+x*I-(g*M+w*O+P*I),j=g*N+U*O+F*I-(v*N+D*O+L*I),Z=w*N+D*M+B*I-(C*N+U*M+b*I),K=P*N+L*M+b*O-(x*N+F*M+B*O),J=w*A+P*S+g*_-(x*S+v*_+C*A),Q=L*S+v*m+D*A-(U*A+F*S+g*m),$=U*_+b*S+C*m-(B*S+w*m+D*_),ee=B*A+x*m+F*_-(L*_+b*A+P*m),te=r*z+a*q+i*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=V*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],d=e[13],h=e[14],E=-n*f-r*d-a*h,m=-i*f-o*d-u*h,_=-s*f-c*d-l*h;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,d=e.length;f<d;f++){var h=e[f];n=Math.min(n,h.longitude),a=Math.max(a,h.longitude),c=Math.min(c,h.latitude),l=Math.max(l,h.latitude);var E=h.longitude>=0?h.longitude:h.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,d=Number.MAX_VALUE,h=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var _=t.cartesianToCartographic(e[E]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),d=Math.min(d,_.latitude),h=Math.max(h,_.latitude);var p=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,p),f=Math.max(f,p)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=d,a.east=c,a.north=h,a):new s(o,d,c,h)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var d=Math.max(e.south,t.south),h=Math.min(e.north,t.north);if(!(d>=h))return r(n)?(n.west=l,n.south=d,n.east=f,n.north=h,n):new s(l,d,f,h)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,d=e.south,h=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:d>0?d:0;for(var _=1;_<8;++_)m.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var h=new e,E=new e,m=new e,_=new e,p=new e,T=new e,y=new e,R=new e,A=new e,S=new e,N=new e,M=new e;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],y),o=e.clone(i,h),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,_),l=e.clone(i,p),f=e.clone(i,T),O=t.length;for(r=1;r<O;r++){e.clone(t[r],i);var I=i.x,v=i.y,g=i.z;I<o.x&&e.clone(i,o),I>c.x&&e.clone(i,c),v<u.y&&e.clone(i,u),v>l.y&&e.clone(i,l),g<s.z&&e.clone(i,s),g>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,M),G=0;for(r=0;r<O;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var V=e.magnitudeSquared(e.subtract(i,L,R));if(V>F){var X=Math.sqrt(V);B=.5*(B+X),F=B*B;var H=X-B;L.x=(B*L.x+H*i.x)/X,L.y=(B*L.y+H*i.y)/X,L.z=(B*L.z+H*i.z)/X}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var O=new o,I=new e,v=new e,g=new t,w=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),f.southwest(t,g),g.height=i,f.northeast(t,w),w.height=o;var s=n.project(g,I),c=n.project(w,v),l=c.x-s.x,h=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+h*h+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*h,m.z=s.z+.5*E,u};var C=[];d.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,C);return d.fromPoints(s,u)},d.fromVertices=function(t,n,i,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=y;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,h),l=e.clone(u,E),f=e.clone(u,m),O=e.clone(u,_),I=e.clone(u,p),v=e.clone(u,T),g=t.length;for(s=0;s<g;s+=i){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>O.x&&e.clone(u,O),C<l.y&&e.clone(u,l),C>I.y&&e.clone(u,I),x<f.z&&e.clone(u,f),x>v.z&&e.clone(u,v)}var P=e.magnitudeSquared(e.subtract(O,c,R)),U=e.magnitudeSquared(e.subtract(I,l,R)),D=e.magnitudeSquared(e.subtract(v,f,R)),L=c,F=O,B=P;U>B&&(B=U,L=l,F=I),D>B&&(B=D,L=f,F=v);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=N;W.x=O.x,W.y=I.y,W.z=v.z;var V=e.multiplyByScalar(e.add(G,W,R),.5,M),X=0;for(s=0;s<g;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,V,R));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;b.x=(q*b.x+j*u.x)/k,b.y=(q*b.y+j*u.y)/k,b.z=(q*b.z+j*u.z)/k}}return q<X?(e.clone(b,o.center),o.radius=q):(e.clone(V,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=y;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,h),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,_),f=e.clone(i,p),O=e.clone(i,T),I=t.length;for(o=0;o<I;o+=3){var v=t[o]+n[o],g=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=v,i.y=g,i.z=w,v<u.x&&e.clone(i,u),v>l.x&&e.clone(i,l),g<s.y&&e.clone(i,s),g>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>O.z&&e.clone(i,O)}var C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(O,c,R)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=O);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=N;q.x=l.x,q.y=f.y,q.z=O.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,M),W=0;for(o=0;o<I;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var V=e.magnitude(e.subtract(i,G,R));V>W&&(W=V);var X=e.magnitudeSquared(e.subtract(i,F,R));if(X>B){var H=Math.sqrt(X);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var x=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,x)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new d);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var B=new e;d.expand=function(t,n,r){r=d.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},d.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,W=new e,V=new e,X=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var j=new o;return d.projectTo2D=function(t,n,a){n=r(n,j);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,X),h=e.negate(c,V),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var _=E.length,p=0;p<_;++p){var T=E[p];e.add(o,T,T);var y=i.cartesianToCartographic(T,H);n.project(y,T)}a=d.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){ -return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,n,r,a,i,o){"use strict";function u(e,n){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,a(n)&&(this.cameraPosition=n)}function s(e,n,r){var a=e.transformPositionToScaledSpace(n,E),i=t.magnitudeSquared(a),o=Math.sqrt(i),u=t.divideByScalar(a,o,m);i=Math.max(1,i),o=Math.max(1,o);var s=t.dot(u,r),c=t.magnitude(t.cross(u,r,u)),l=1/o;return 1/(s*l-c*(Math.sqrt(i-1)*l))}function c(e,n,r){if(!(n<=0||n===1/0||n!==n))return t.multiplyByScalar(e,n,r)}function l(e,n){return t.equals(n,t.ZERO)?n:(e.transformPositionToScaledSpace(n,_),t.normalize(_,_))}i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var n=this._ellipsoid,r=n.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),a=t.magnitudeSquared(r)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=r,this._distanceToLimbInScaledSpaceSquared=a}}});var f=new t;u.prototype.isPointVisible=function(e){var t=this._ellipsoid,n=t.transformPositionToScaledSpace(e,f);return this.isScaledSpacePointVisible(n)},u.prototype.isScaledSpacePointVisible=function(e){var n=this._cameraPositionInScaledSpace,r=this._distanceToLimbInScaledSpaceSquared,a=t.subtract(e,n,f),i=-t.dot(a,n);return!(r<0?i>0:i>r&&i*i/t.magnitudeSquared(a)>r)},u.prototype.computeHorizonCullingPoint=function(e,n,r){a(r)||(r=new t);for(var i=this._ellipsoid,o=l(i,e),u=0,f=0,d=n.length;f<d;++f){var h=n[f],E=s(i,h,o);u=Math.max(u,E)}return c(o,u,r)};var d=new t;u.prototype.computeHorizonCullingPointFromVertices=function(e,n,i,o,u){a(u)||(u=new t),o=r(o,t.ZERO);for(var f=this._ellipsoid,h=l(f,e),E=0,m=0,_=n.length;m<_;m+=i){d.x=n[m]+o.x,d.y=n[m+1]+o.y,d.z=n[m+2]+o.z;var p=s(f,d,h);E=Math.max(E,p)}return c(h,E,u)};var h=[];u.prototype.computeHorizonCullingPointFromRectangle=function(n,r,a){var i=o.subsample(n,r,0,h),u=e.fromPoints(i);if(!(t.magnitude(u.center)<.1*r.minimumRadius))return this.computeHorizonCullingPoint(u.center,i,a)};var E=new t,m=new t,_=new t;return u}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var d=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[d/e,a/d]:[a/d,d/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,d=u*u,h=s*s,E=o*s-d,m=o*c-u*s,_=u*c-h,p=4*E*_-m*m;if(p<0){var T,y,R;d*f>=l*h?(T=o,y=E,R=-2*u*E+o*m):(T=c,y=_,R=-c*m+2*s*_);var A=R<0?-1:1,S=-A*Math.abs(T)*Math.sqrt(-p);i=-R+S;var N=i/2,M=N<0?-Math.pow(-N,1/3):Math.pow(N,1/3),O=i===S?-M:-y/M;return a=y<=0?M+O:-R/(M*M+O*O+y),d*f>=l*h?[(a-u)/o]:[-c/(a+s)]}var I=E,v=-2*u*E+o*m,g=_,w=-c*m+2*s*_,C=Math.sqrt(p),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-v)/3);a=2*Math.sqrt(-I);var U=Math.cos(P);i=a*U;var D=a*(-U/2-x*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),a=2*Math.sqrt(-g),U=Math.cos(P),i=a*U,D=a*(-U/2-x*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,V=L*b,X=(s*W-u*V)/(-u*W+s*G);return B<=X?B<=q?X<=q?[B,X,q]:[B,q,X]:[q,B,X]:B<=q?[X,B,q]:X<=q?[X,q,B]:[q,X,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var d=-t/4,h=f[f.length-1];if(Math.abs(h)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,_=E[0],p=E[1];if(_>=0&&p>=0){var T=Math.sqrt(_),y=Math.sqrt(p);return[d-y,d-T,d+T,d+y]}if(_>=0&&p<0)return m=Math.sqrt(_),[d-m,d+m];if(_<0&&p>=0)return m=Math.sqrt(p),[d-m,d+m]}return[]}if(h>0){var R=Math.sqrt(h),A=(s+h-c/R)/2,S=(s+h+c/R)/2,N=r.computeRealRoots(1,R,A),M=r.computeRealRoots(1,-R,S);return 0!==N.length?(N[0]+=d,N[1]+=d,0!==M.length?(M[0]+=d,M[1]+=d,N[1]<=M[0]?[N[0],N[1],M[0],M[1]]:M[1]<=N[0]?[M[0],M[1],N[0],N[1]]:N[0]>=M[0]&&N[1]<=M[1]?[M[0],N[0],N[1],M[1]]:M[0]>=N[0]&&M[1]<=N[1]?[N[0],M[0],M[1],N[1]]:N[0]>M[0]&&N[0]<M[1]?[M[0],N[0],M[1],N[1]]:[N[0],M[0],N[1],M[1]]):N):0!==M.length?(M[0]+=d,M[1]+=d,M):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,d=c*o-i*a*t+u,h=e.computeRealRoots(1,l,f,d);if(h.length>0){var E,m,_=h[0],p=a-_,T=p*p,y=t/2,R=p/2,A=T-4*o,S=T+4*Math.abs(o),N=c-4*_,M=c+4*Math.abs(_);if(_<0||A*M<N*S){var O=Math.sqrt(N);E=O/2,m=0===O?0:(t*R-i)/O}else{var I=Math.sqrt(A);E=0===I?0:(t*R-i)/I,m=I/2}var v,g;0===y&&0===E?(v=0,g=0):n.sign(y)===n.sign(E)?(v=y+E,g=_/v):(g=y-E,v=_/g);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,v,w),P=r.computeRealRoots(1,g,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,d=f*r,h=a*a;return u*c*f-4*s*d-4*e*l*f+18*e*t*n*d-27*i*f*f+256*o*(h*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+h*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,d=s/t,h=c<0?1:0;switch(h+=l<0?h+1:h,h+=f<0?h+1:h,h+=d<0?h+1:h){case 0:return a(c,l,f,d);case 1:case 2:return i(c,l,f,d);case 3:case 4:return a(c,l,f,d);case 5:return i(c,l,f,d);case 6:case 7:return a(c,l,f,d);case 8:return i(c,l,f,d);case 9:case 10:return a(c,l,f,d);case 11:return i(c,l,f,d);case 12:case 13:case 14:case 15:return a(c,l,f,d);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function d(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,T),d=e.dot(u,u),h=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(d,h,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function h(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,d=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*d,m=i*(a*h(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),_=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*d+a*n.x+r,p=d*h(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),T=i*(a*h(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),y=[];if(0===T&&0===p){if(l=s.computeRealRoots(E,m,_),0===l.length)return y;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(y.push(new e(a,i*R,i*-A)),y.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],N=Math.sqrt(Math.max(1-S*S,0));y.push(new e(a,i*S,i*-N)),y.push(new e(a,i*S,i*N))}return y}var M=T*T,O=p*p,I=E*E,v=T*p,g=I+O,w=2*(m*E+v),C=2*_*E+m*m-O+M,x=2*(_*m-v),P=_*_-M;if(0===g&&0===w&&0===C&&0===x)return y;l=c.computeRealRoots(g,w,C,x,P);var U=l.length;if(0===U)return y;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(_)?h(E*B+_,m*F,o.EPSILON12):o.sign(_)===o.sign(m*F)?h(E*B,m*F+_,o.EPSILON12):h(E*B+m*F,_,o.EPSILON12);var q=h(p*F,T,o.EPSILON15),G=L*q;G<0?y.push(new e(a,i*F,i*z)):G>0?y.push(new e(a,i*F,i*-z)):0!==z?(y.push(new e(a,i*F,i*-z)),y.push(new e(a,i*F,i*z)),++D):y.push(new e(a,i*F,i*z))}return y}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,p=new e,T=new e,y=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,d,h=t.origin,E=t.direction,m=e.subtract(a,r,_),A=e.subtract(i,r,p),S=e.cross(E,A,T),N=e.dot(m,S);if(u){if(N<o.EPSILON6)return;if(s=e.subtract(h,r,y),(l=e.dot(s,S))<0||l>N)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>N)return;d=e.dot(A,c)/N}else{if(Math.abs(N)<o.EPSILON6)return;var M=1/N;if(s=e.subtract(h,r,y),(l=e.dot(s,S)*M)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*M)<0||l+f>1)return;d=e.dot(A,c)*M}return d},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=d(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var N=new l;m.lineSegmentSphere=function(t,n,a,i){var o=N;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=d(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var M=new e,O=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,M),f=e.multiplyComponents(c,t.direction,O),d=e.magnitudeSquared(l),h=e.dot(l,f);if(d>1){if(h>=0)return;var E=h*h;if(r=d-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=h*h-o,s=-h+Math.sqrt(u);var m=s/a,_=r/s;return m<_?new i(m,_):{start:_,stop:m}}var p=Math.sqrt(r/a);return new i(p,p)}return d<1?(r=d-1,a=e.magnitudeSquared(f),o=a*r,u=h*h-o,s=-h+Math.sqrt(u),new i(0,s/a)):h<0?(a=e.magnitudeSquared(f),new i(0,-h/a)):void 0};var I=new e,v=new e,g=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,I);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,I),f=e.normalize(l,l),d=e.mostOrthogonalAxis(l,w),h=e.normalize(e.cross(d,f,v),v),m=e.normalize(e.cross(f,h,g),g),_=x;_[0]=f.x,_[1]=f.y,_[2]=f.z,_[3]=h.x,_[4]=h.y,_[5]=h.z,_[6]=m.x,_[7]=m.y,_[8]=m.z;var p=u.transpose(_,P),T=u.fromScale(n.radii,U),y=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,N=u.multiply(u.multiply(p,y,F),R,F),M=u.multiply(u.multiply(N,T,B),_,B),O=u.multiplyByVector(N,a,C),G=E(M,e.negate(O,I),0,0,1),W=G.length;if(W>0){for(var V=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<W;++H){A=u.multiplyByVector(T,u.multiplyByVector(_,G[H],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>X&&(X=k,V=e.clone(A,V))}var j=n.cartesianToCartographic(V,q);return X=o.clamp(X,0,1),S=e.magnitude(e.subtract(V,a,w))*Math.sqrt(1-X*X),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,d;if(1!==l&&2!==l||(f=new e,d=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,d),{positions:[t,n,r,f,d],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,d),{positions:[t,n,r,f,d],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,d),{positions:[t,n,r,f,d],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,d),{positions:[t,n,r,f,d],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,d),{positions:[t,n,r,f,d],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,d),{positions:[t,n,r,f,d],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return d(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return h(e)}var s,c,l,f,d,h,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],d=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},h=function(e){return m(f,e),e},E=function(e){return e=t(e),d=e.then,E=t,h=p,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return _(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,d,h,E,m,_,T,y;if(T=t.length>>>0,c=Math.max(0,Math.min(n,T)),f=[],l=T-c+1,d=[],h=o(),c)for(_=h.progress,m=function(e){d.push(e),--l||(E=m=p,h.reject(d))},E=function(e){f.push(e),--c||(E=m=p,h.resolve(f))},y=0;y<T;++y)y in t&&e(t[y],s,u,_);else h.resolve(f);return h.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return _(1,arguments),d(e,T).then(t,n,r)}function f(){return d(arguments,T)}function d(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function h(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},y.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function _(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function p(){}function T(e){return e}var y,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=d,e.reduce=h,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,y=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,d){var h,E,m,_,p;if("%%"==e)return"%";for(var T=!1,y="",R=!1,A=!1,S=" ",N=s.length,M=0;s&&M<N;M++)switch(s.charAt(M)){case" ":y=" ";break;case"+":y="+";break;case"-":T=!0;break;case"'":S=s.charAt(M+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,T=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(d)>-1?6:"d"==d?0:void 0,p=r?t[r.slice(0,-1)]:t[n++],d){case"s":return u(String(p),T,c,f,R,S);case"c":return u(String.fromCharCode(+p),T,c,f,R);case"b":return o(p,2,A,T,c,f,R);case"o":return o(p,8,A,T,c,f,R);case"x":return o(p,16,A,T,c,f,R);case"X":return o(p,16,A,T,c,f,R).toUpperCase();case"u":return o(p,10,A,T,c,f,R);case"i":case"d":return h=+p||0,h=Math.round(h-h%1),E=h<0?"-":y,p=E+a(String(Math.abs(h)),f,"0",!1),i(p,E,T,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return h=+p,E=h<0?"-":y,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(d.toLowerCase())],_=["toString","toUpperCase"]["eEfFgG".indexOf(d)%2],p=E+Math.abs(h)[m](f),i(p,E,T,c,R)[_]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){T.julianDate=e;var n=m.leapSeconds,r=t(n,T,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function d(e,n){T.julianDate=e;var r=m.leapSeconds,a=t(r,T,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function h(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,h(a,t,this),r===c.UTC&&f(this)}var _=new i,p=[31,28,31,30,31,30,31,31,30,31,30,31],T=new u,y=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,N=/^(\d{4})-?(\d{2})-?(\d{2})$/,M=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+M.source,I=/^(\d{2}):?(\d{2})(\.\d+)?/.source+M.source,v=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+M.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(h(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(h(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,d=0,_=0,T=0,M=0,g=u[0],w=u[1];if(null!==(u=g.match(N)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=g.match(R)))n=+u[1],s=+u[2];else if(null!==(u=g.match(y)))n=+u[1];else{var C;if(null!==(u=g.match(A)))n=+u[1],C=+u[2],i=o(n);else if(null!==(u=g.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(C),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(v),null!==u?(d=+u[1],_=+u[2],T=+u[3],M=1e3*+(u[4]||0),D=5):(u=w.match(I),null!==u?(d=+u[1],_=+u[2],T=60*+(u[3]||0),D=4):null!==(u=w.match(O))&&(d=+u[1],_=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":d-=F,_-=B;break;case"-":d+=F,_+=B;break;case"Z":break;default:_+=new Date(Date.UTC(n,s-1,l,d,_)).getTimezoneOffset()}}var b=60===T;for(b&&T--;_>=60;)_-=60,d++;for(;d>=24;)d-=24,l++;for(a=i&&2===s?29:p[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:p[s-1];for(;_<0;)_+=60,d--;for(;d<0;)d+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:p[s-1],l+=a;var z=E(n,s,l,d,_,T,M);return r(t)?(h(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var g=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=d(e,g);r(a)||(m.addSeconds(e,-1,g),a=d(g,g),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var h=80*c/2447|0,E=c-(2447*h/80|0)|0;c=h/11|0;var _=h+2-12*c|0,p=100*(l-49)+f+c|0,T=u/s.SECONDS_PER_HOUR|0,y=u-T*s.SECONDS_PER_HOUR,R=y/s.SECONDS_PER_MINUTE|0;y-=R*s.SECONDS_PER_MINUTE;var A=0|y,S=(y-A)/s.SECONDS_PER_MILLISECOND;return T+=12,T>23&&(T-=24),n&&(A+=1),r(t)?(t.year=p,t.month=_,t.day=E,t.hour=T,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(p,_,E,T,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,_),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,_);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){T.julianDate=e;var n=m.leapSeconds,r=t(n,T,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return h(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return h(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return h(e.dayNumber,r,n)},m.addDays=function(e,t,n){return h(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e, -this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return M[e]<l.maximumRequestsPerServer}function h(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--M[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--M[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function _(e){var t=h(e);return e.state=s.ACTIVE,N.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++M[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function p(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--M[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function y(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),T())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A);var N=[],M={},O="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();p(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=N.length;for(e=0;e<r;++e)t=N[e],t.cancelled&&p(t),t.state===s.ACTIVE?n>0&&(N[e-n]=t):++n;N.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-N.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?p(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):p(t);y()},l.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=M[a];return r(i)||(M[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return _(e);if(!(N.length>=l.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;p(t)}return h(e)}},l.clearForSpecs=function(){for(;S.length>0;){p(S.pop())}for(var e=N.length,t=0;t<e;++t)p(N[t]);N.length=0,M={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return M[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,d=t.overrideMimeType;a=n(a,t.url);var h=r(t.request)?t.request:new i;return h.url=a,h.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,d);return r(n)&&r(n.abort)&&(h.cancelFunction=function(){n.abort()}),t.promise},u.request(h)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function d(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function h(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return d(a,i);case"blob":var o=d(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(h(f,t));var d=new XMLHttpRequest;if(c.contains(e)&&(d.withCredentials=!0),r(l)&&r(d.overrideMimeType)&&d.overrideMimeType(l),d.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&d.setRequestHeader(m,i[m]);r(t)&&(d.responseType=t);var _=!1;return"string"==typeof e&&(_=0===e.indexOf("file://")),d.onload=function(){if((d.status<200||d.status>=300)&&(!_||0!==d.status))return void u.reject(new o(d.status,d.response,d.getAllResponseHeaders()));var e=d.response,n=d.responseType;if(204===d.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(d.responseXML)&&d.responseXML.hasChildNodes()?u.resolve(d.responseXML):""!==n&&"text"!==n||!r(d.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(d.responseText);else u.resolve(e)},d.onerror=function(e){u.reject(new o)},d.send(a),d},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function d(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function h(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),d=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||d<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var _=e._samples=n.samples,p=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=d,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var T,y=e._addNewLeapSeconds,R=0,A=_.length;R<A;R+=e._columnCount){var S=_[R+a],N=_[R+m],M=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(M,N,f.TAI);if(p.push(O),y){if(N!==T&&r(T)){var I=o.leapSeconds,v=t(I,O,h);if(v<0){var g=new u(O,N);I.splice(~v,0,g)}}T=N}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function _(e,t,n){return t+e*(n-t)}function p(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),d=a*s,h=i*s,E=n[d+e._ut1MinusUtcSecondsColumn],p=n[h+e._ut1MinusUtcSecondsColumn],T=p-E;if(T>.5||T<-.5){var y=n[d+e._taiMinusUtcSecondsColumn],R=n[h+e._taiMinusUtcSecondsColumn];y!==R&&(l.equals(r)?E=p:p-=R-y)}return u.xPoleWander=_(f,n[d+e._xPoleWanderRadiansColumn],n[h+e._xPoleWanderRadiansColumn]),u.yPoleWander=_(f,n[d+e._yPoleWanderRadiansColumn],n[h+e._yPoleWanderRadiansColumn]),u.xPoleOffset=_(f,n[d+e._xCelestialPoleOffsetRadiansColumn],n[h+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=_(f,n[d+e._yCelestialPoleOffsetRadiansColumn],n[h+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=_(f,E,p),u}return d.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),d.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},d.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],d=i[u+1],h=o.lessThanOrEquals(f,e),E=!r(d),m=E||o.greaterThanOrEquals(d,e);if(h&&m)return s=u,!E&&d.equals(e)&&++s,l=s+1,p(this,i,this._samples,e,s,l,n),n}var _=t(i,e,o.compare,this._dateColumn);return _>=0?(_<i.length-1&&i[_+1].equals(e)&&++_,s=_,l=_):(l=~_,(s=l-1)<0&&(s=0)),this._lastIndex=s,p(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},d}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(d)||(d=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(h)||(h=document.createElement("a"));var n=d(e);return h.href=n,h.href=h.href,h.href}var f,d,h,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,d=s/this._samplesPerXysFile|0,h=[],E=f;E<=d;++E)h.push(l(this,E));return e.all(h)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var d=!1,h=this._samples;if(r(h[3*s])||(l(this,s/this._samplesPerXysFile|0),d=!0),r(h[3*f])||(l(this,f/this._samplesPerXysFile|0),d=!0),!d){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,_=i-s*this._stepSizeDays,p=this._work,T=this._denominators,y=this._coef,R=this._xTable;for(E=0;E<=u;++E)p[E]=_-R[E];for(E=0;E<=u;++E){for(y[E]=1,m=0;m<=u;++m)m!==E&&(y[E]*=p[m]);y[E]*=T[E];var A=3*(s+E);n.x+=y[E]*h[A++],n.y+=y[E]*h[A++],n.s+=y[E]*h[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!d())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(N)&&(N=!1,!a()&&!d()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(N=!0,M=r(e[1]))}return N}function u(){return o()&&M}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0,I=r(e[1]),I.isNightly=!!e[2])}return O}function c(){return s()&&I}function l(){if(!t(v)){v=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(v=!0,g=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(v=!0,g=r(e[1]))}return v}function f(){return l()&&g}function d(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function h(){return d()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function _(){return E()&&P}function p(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function T(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function y(){return T()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,N,M,O,I,v,g,w,C,x,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:d,edgeVersion:h,isFirefox:E,firefoxVersion:_,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:p,supportsImageRenderingPixelated:T,imageRenderingValue:y};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,d=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=d,a):new s(u,l,f,d)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,d=e[u.COLUMN0ROW0],h=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=d+h+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var _=l,p=0;h>d&&(p=1),E>d&&E>h&&(p=2);var T=_[p],y=_[T];n=Math.sqrt(e[u.getElementIndex(p,p)]-e[u.getElementIndex(T,T)]-e[u.getElementIndex(y,y)]+1);var R=f;R[p]=.5*n,n=.5/n,c=(e[u.getElementIndex(y,T)]-e[u.getElementIndex(T,y)])*n,R[T]=(e[u.getElementIndex(T,p)]+e[u.getElementIndex(p,T)])*n,R[y]=(e[u.getElementIndex(y,p)]+e[u.getElementIndex(p,y)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var d=new s,h=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,d),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),h=s.fromAxisAngle(e.UNIT_Z,-t.heading,d),s.multiply(h,n,n)};var _=new e,p=new e,T=new s,y=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),T),s.multiply(T,R,T),T.w<0&&s.negate(T,T),s.computeAxis(T,_);var u=s.computeAngle(T);r[o]=_.x*u,r[o+1]=_.y*u,r[o+2]=_.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,p);var u=e.magnitude(p);return s.unpack(n,4*i,y),0===u?s.clone(s.IDENTITY,T):s.fromAxisAngle(p,u,T),s.multiply(T,y,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,d=o*s-r*c+a*l+i*u,h=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=d,n.z=h,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,N=new s,M=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return N=s.multiplyByScalar(e,Math.sin((1-n)*u),N),M=s.multiplyByScalar(i,Math.sin(n*u),M),r=s.add(N,M,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var O=new e,I=new e,v=new s,g=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,v);s.multiply(i,r,g);var o=s.log(g,O);s.multiply(i,t,g);var u=s.log(g,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,v),s.multiply(n,v,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,v),u=s.slerp(n,r,a,g);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,C=1.9011074535173003,x=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;x[L]=1/(F*B),P[L]=F/B}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var d=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),h=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,h,w);return s.multiplyByScalar(t,d,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,v),u=s.fastSlerp(n,r,a,g);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}), -define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E,m,_,p,T,y){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},N={},M={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,I=new n,v=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(N[i])?r=N[i]:(r=function(r,i,s){if(u(s)||(s=new p),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(S[t],0,I),"east"!==t&&"west"!==t&&n.multiplyByScalar(I,c,I),n.unpack(S[a],0,v),"east"!==a&&"west"!==a&&n.multiplyByScalar(v,c,v)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,M.up);var l=M.up,d=M.east;d.x=-r.y,d.y=r.x,d.z=0,n.normalize(d,M.east),n.cross(l,d,M.north),n.multiplyByScalar(M.up,-1,M.down),n.multiplyByScalar(M.east,-1,M.west),n.multiplyByScalar(M.north,-1,M.south),O=M[e],I=M[t],v=M[a]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=I.x,s[5]=I.y,s[6]=I.z,s[7]=0,s[8]=v.x,s[9]=v.y,s[10]=v.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},N[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var g=new T,w=new n(1,1,1),C=new p;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=T.fromHeadingPitchRoll(t,g),s=p.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return i=a(e,r,i),p.multiply(i,s,i)};var x=new p,P=new _;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=p.getRotation(i,P);return T.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/y.DAYS_PER_JULIAN_CENTURY:(i-.5)/y.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*y.SECONDS_PER_DAY)%y.SECONDS_PER_DAY,f=s+c*l,d=Math.cos(f),h=Math.sin(f);return u(t)?(t[0]=d,t[1]=-h,t[2]=0,t[3]=h,t[4]=d,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new _(d,h,0,-h,d,0,0,0,1)},R.iau2006XysData=new d,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new _);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return _.transpose(n,t)};var L=new h(0,0,0),F=new l(0,0,0,0,0,0),B=new _,b=new _;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new _);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=_.fromRotationZ(-i.s,b),d=_.multiply(l,f,B),h=e.dayNumber,p=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,T=h-2451545,A=p/y.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(T+A);S=S%1*m.TWO_PI;var N=_.fromRotationZ(S,b),M=_.multiply(d,N,B),O=Math.cos(n.xPoleWander),I=Math.cos(n.yPoleWander),v=Math.sin(n.xPoleWander),g=Math.sin(n.yPoleWander),w=r-2451545+a/y.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=b;return U[0]=O*x,U[1]=O*P,U[2]=v,U[3]=-I*P+g*v*x,U[4]=I*x+g*v*P,U[5]=-g*O,U[6]=-g*P-I*v*x,U[7]=g*x-I*v*P,U[8]=I*O,_.multiply(M,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return p.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),p.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new _),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var V=new p(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new _,j=new p,Z=new p;return R.basisTo2D=function(e,t,r){var a=p.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=p.inverseTransformation(s,Z),l=p.getRotation(t,k),f=p.multiplyByMatrix3(c,l,r);return p.multiply(V,f,r),p.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=p.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=p.fromTranslation(s,j);return p.multiply(V,o,r),p.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=h.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var _=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,_).center,n)};var p=new d,T=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=p;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,T);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,T)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=p;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,T);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,T));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var y=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=y,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var d=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(d,c,d),a.scaleToGeocentricSurface(d,d)}return t},E}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E){"use strict";function m(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=d.clone(a(t,d.ZERO))}function _(e,t,r,a,o,u,s,c){i(c)||(c=new m);var l=c.halfAxes;d.setColumn(l,0,e.xAxis,l),d.setColumn(l,1,e.yAxis,l),d.setColumn(l,2,e.zAxis,l);var f=O;f.x=(t+r)/2,f.y=(a+o)/2,f.z=(u+s)/2;var h=I;h.x=(r-t)/2,h.y=(o-a)/2,h.z=(s-u)/2;var E=c.center;return f=d.multiplyByVector(l,f,f),n.add(e.origin,f,E),d.multiplyByScale(l,h,l),c}var p=new n,T=new n,y=new n,R=new n,A=new n,S=new n,N=new d,M={unitary:new d,diagonal:new d};m.fromPoints=function(e,t){if(i(t)||(t=new m),!i(e)||0===e.length)return t.halfAxes=d.ZERO,t.center=n.ZERO,t;var r,a=e.length,o=n.clone(e[0],p);for(r=1;r<a;r++)n.add(o,e[r],o);var u=1/a;n.multiplyByScalar(o,u,o);var s,c=0,l=0,f=0,h=0,E=0,_=0;for(r=0;r<a;r++)s=n.subtract(e[r],o,T),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,h+=s.y*s.y,E+=s.y*s.z,_+=s.z*s.z;c*=u,l*=u,f*=u,h*=u,E*=u,_*=u;var O=N;O[0]=c,O[1]=l,O[2]=f,O[3]=l,O[4]=h,O[5]=E,O[6]=f,O[7]=E,O[8]=_;var I=d.computeEigenDecomposition(O,M),v=d.clone(I.unitary,t.halfAxes),g=d.getColumn(v,0,R),w=d.getColumn(v,1,A),C=d.getColumn(v,2,S),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<a;r++)s=e[r],x=Math.max(n.dot(g,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(g,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);g=n.multiplyByScalar(g,.5*(D+x),g),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var B=n.add(g,w,t.center);n.add(B,C,B);var b=y;return b.x=x-D,b.y=P-L,b.z=U-F,n.multiplyByScalar(b,.5,b),d.multiplyByScale(t.halfAxes,b,t.halfAxes),t};var O=new n,I=new n,v=new r,g=new n,w=[new r,new r,new r,new r,new r,new r,new r,new r],C=[new n,new n,new n,new n,new n,new n,new n,new n],x=[new t,new t,new t,new t,new t,new t,new t,new t];m.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,u.WGS84);var o=E.center(e,v),c=r.cartographicToCartesian(o,g),l=new s(c,r),f=l.plane,d=w[0],m=w[1],p=w[2],T=w[3],y=w[4],R=w[5],A=w[6],S=w[7],N=o.longitude,M=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=y.latitude=e.south,S.latitude=T.latitude=M,d.latitude=m.latitude=p.latitude=e.north,A.longitude=S.longitude=d.longitude=e.west,R.longitude=m.longitude=N,y.longitude=T.longitude=p.longitude=e.east,p.height=m.height=d.height=S.height=A.height=R.height=y.height=T.height=n,r.cartographicArrayToCartesianArray(w,C),l.projectPointsToNearestOnPlane(C,x);var O=Math.min(x[6].x,x[7].x,x[0].x),I=Math.max(x[2].x,x[3].x,x[4].x),P=Math.min(x[4].y,x[5].y,x[6].y),U=Math.max(x[0].y,x[1].y,x[2].y);return p.height=d.height=y.height=A.height=t,r.cartographicArrayToCartesianArray(w,C),_(l,O,I,P,U,Math.min(h.getPointDistance(f,C[0]),h.getPointDistance(f,C[2]),h.getPointDistance(f,C[4]),h.getPointDistance(f,C[6])),n,i)},m.clone=function(e,t){if(i(e))return i(t)?(n.clone(e.center,t.center),d.clone(e.halfAxes,t.halfAxes),t):new m(e.center,e.halfAxes)},m.intersectPlane=function(e,t){var r=e.center,a=t.normal,i=e.halfAxes,o=a.x,u=a.y,s=a.z,l=Math.abs(o*i[d.COLUMN0ROW0]+u*i[d.COLUMN0ROW1]+s*i[d.COLUMN0ROW2])+Math.abs(o*i[d.COLUMN1ROW0]+u*i[d.COLUMN1ROW1]+s*i[d.COLUMN1ROW2])+Math.abs(o*i[d.COLUMN2ROW0]+u*i[d.COLUMN2ROW1]+s*i[d.COLUMN2ROW2]),f=n.dot(a,r)+t.distance;return f<=-l?c.OUTSIDE:f>=l?c.INSIDE:c.INTERSECTING};var P=new n,U=new n,D=new n,L=new n;m.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,O),a=e.halfAxes,i=d.getColumn(a,0,P),o=d.getColumn(a,1,U),u=d.getColumn(a,2,D),s=n.magnitude(i),c=n.magnitude(o),l=n.magnitude(u);n.normalize(i,i),n.normalize(o,o),n.normalize(u,u);var f=L;f.x=n.dot(r,i),f.y=n.dot(r,o),f.z=n.dot(r,u);var h,E=0;return f.x<-s?(h=f.x+s,E+=h*h):f.x>s&&(h=f.x-s,E+=h*h),f.y<-c?(h=f.y+c,E+=h*h):f.y>c&&(h=f.y-c,E+=h*h),f.z<-l?(h=f.z+l,E+=h*h):f.z>l&&(h=f.z-l,E+=h*h),E};var F=new n,B=new n;m.computePlaneDistances=function(e,t,r,a){i(a)||(a=new l);var o=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,f=d.getColumn(c,0,P),h=d.getColumn(c,1,U),E=d.getColumn(c,2,D),m=n.add(f,h,F);n.add(m,E,m),n.add(m,s,m);var _=n.subtract(m,t,B),p=n.dot(r,_);return o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.add(m,h,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),a.start=o,a.stop=u,a};var b=new e;return m.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,b);return!n.isBoundingSphereVisible(r)},m.prototype.intersectPlane=function(e){return m.intersectPlane(this,e)},m.prototype.distanceSquaredTo=function(e){return m.distanceSquaredTo(this,e)},m.prototype.computePlaneDistances=function(e,t,n){return m.computePlaneDistances(this,e,t,n)},m.prototype.isOccluded=function(e){return m.isOccluded(this,e)},m.equals=function(e,t){return e===t||i(e)&&i(t)&&n.equals(e.center,t.center)&&d.equals(e.halfAxes,t.halfAxes)},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,a){"use strict";var i={};i.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,n){return i.octDecodeInRange(e,t,255,n)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return i.octDecode(r,a,t)},i.octPack=function(e,t,n,r){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(n,o);return r.x=65536*s.x+a,r.y=65536*s.y+u,r},i.octUnpack=function(e,t,n,r){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,n),i.octDecode(o,s,r)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},i}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}), -define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t,r,o,c,d){var _,p,T,y;if(i(e)&&i(t)&&i(r)&&i(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),N=r-t;_=Math.max(n.maximumComponent(S),N)<m-1?s.BITS12:s.NONE,p=e.center,T=u.inverseTransformation(o,new u);var M=n.negate(R,l);u.multiply(u.fromTranslation(M,h),T,T);var O=l;O.x=1/S.x,O.y=1/S.y,O.z=1/S.z,u.multiply(u.fromScale(O,h),T,T),y=u.clone(o),u.setTranslation(y,n.ZERO,y),o=u.clone(o,new u);var I=u.fromTranslation(R,h),v=u.fromScale(S,E),g=u.multiply(I,v,h);u.multiply(o,g,o),u.multiply(y,g,y)}this.quantization=_,this.minimumHeight=t,this.maximumHeight=r,this.center=p,this.toScaledENU=T,this.fromScaledENU=o,this.matrix=y,this.hasVertexNormals=c,this.hasWebMercatorT=a(d,!1)}var l=new n,f=new n,d=new t,h=new u,E=new u,m=Math.pow(2,12);c.prototype.encode=function(r,a,i,c,f,h,E){var m=c.x,_=c.y;if(this.quantization===s.BITS12){i=u.multiplyByPoint(this.toScaledENU,i,l),i.x=o.clamp(i.x,0,1),i.y=o.clamp(i.y,0,1),i.z=o.clamp(i.z,0,1);var p=this.maximumHeight-this.minimumHeight,T=o.clamp((f-this.minimumHeight)/p,0,1);t.fromElements(i.x,i.y,d);var y=e.compressTextureCoordinates(d);t.fromElements(i.z,T,d);var R=e.compressTextureCoordinates(d);t.fromElements(m,_,d);var A=e.compressTextureCoordinates(d);if(r[a++]=y,r[a++]=R,r[a++]=A,this.hasWebMercatorT){t.fromElements(E,0,d);var S=e.compressTextureCoordinates(d);r[a++]=S}}else n.subtract(i,this.center,l),r[a++]=l.x,r[a++]=l.y,r[a++]=l.z,r[a++]=f,r[a++]=m,r[a++]=_,this.hasWebMercatorT&&(r[a++]=E);return this.hasVertexNormals&&(r[a++]=e.octPackFloat(h)),a},c.prototype.decodePosition=function(t,r,a){if(i(a)||(a=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],d);a.x=o.x,a.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],d);return a.z=c.x,u.multiplyByPoint(this.fromScaledENU,a,a)}return a.x=t[r],a.y=t[r+1],a.z=t[r+2],n.add(a,this.center,a)},c.prototype.decodeTextureCoordinates=function(n,r,a){return i(a)||(a=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],a):t.fromElements(n[r+4],n[r+5],a)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],d).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var a=e[n]/256,i=Math.floor(a),o=256*(a-i);return t.fromElements(i,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var _={position3DAndHeight:0,textureCoordAndEncodedNormals:1},p={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,a=r.getSizeInBytes(n);if(this.quantization===s.NONE){var i=2;return this.hasWebMercatorT&&++i,this.hasVertexNormals&&++i,t=(4+i)*a,[{index:_.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:_.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:i,offsetInBytes:4*a,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*a,[{index:p.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:p.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*a,strideInBytes:t}]):[{index:p.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?_:p},c.clone=function(e,t){return i(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},s.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},s}),define("Core/HeightmapTessellator",["./AxisAlignedBoundingBox","./BoundingSphere","./Cartesian2","./Cartesian3","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidalOccluder","./freezeObject","./Math","./Matrix4","./OrientedBoundingBox","./Rectangle","./TerrainEncoding","./Transforms","./WebMercatorProjection"],function(e,t,n,r,a,i,o,u,s,c,l,f,d,h,E,m,_){"use strict";var p={};p.DEFAULT_STRUCTURE=c({heightScale:1,heightOffset:0,elementsPerHeight:1,stride:1,elementMultiplier:256,isBigEndian:!1});var T=new r,y=new f,R=new r,A=new r;return p.computeVertices=function(o){var c,S,N,M,O=Math.cos,I=Math.sin,v=Math.sqrt,g=Math.atan,w=Math.exp,C=l.PI_OVER_TWO,x=l.toRadians,P=o.heightmap,U=o.width,D=o.height,L=o.skirtHeight,F=a(o.isGeographic,!0),B=a(o.ellipsoid,u.WGS84),b=1/B.maximumRadius,z=o.nativeRectangle,q=o.rectangle;i(q)?(c=q.west,S=q.south,N=q.east,M=q.north):F?(c=x(z.west),S=x(z.south),N=x(z.east),M=x(z.north)):(c=z.west*b,S=C-2*g(w(-z.south*b)),N=z.east*b,M=C-2*g(w(-z.north*b)));var G=o.relativeToCenter,W=i(G);G=W?G:r.ZERO;var V=a(o.exaggeration,1),X=a(o.includeWebMercatorT,!1),H=a(o.structure,p.DEFAULT_STRUCTURE),Y=a(H.heightScale,p.DEFAULT_STRUCTURE.heightScale),k=a(H.heightOffset,p.DEFAULT_STRUCTURE.heightOffset),j=a(H.elementsPerHeight,p.DEFAULT_STRUCTURE.elementsPerHeight),Z=a(H.stride,p.DEFAULT_STRUCTURE.stride),K=a(H.elementMultiplier,p.DEFAULT_STRUCTURE.elementMultiplier),J=a(H.isBigEndian,p.DEFAULT_STRUCTURE.isBigEndian),Q=h.computeWidth(z),$=h.computeHeight(z),ee=Q/(U-1),te=$/(D-1);F||(Q*=b,$*=b);var ne,re,ae=B.radiiSquared,ie=ae.x,oe=ae.y,ue=ae.z,se=65536,ce=-65536,le=m.eastNorthUpToFixedFrame(G,B),fe=f.inverseTransformation(le,y);X&&(ne=_.geodeticLatitudeToMercatorAngle(S),re=1/(_.geodeticLatitudeToMercatorAngle(M)-ne));var de=R;de.x=Number.POSITIVE_INFINITY,de.y=Number.POSITIVE_INFINITY,de.z=Number.POSITIVE_INFINITY;var he=A;he.x=Number.NEGATIVE_INFINITY,he.y=Number.NEGATIVE_INFINITY,he.z=Number.NEGATIVE_INFINITY;var Ee=Number.POSITIVE_INFINITY,me=U+(L>0?2:0),_e=D+(L>0?2:0),pe=me*_e,Te=new Array(pe),ye=new Array(pe),Re=new Array(pe),Ae=X?new Array(pe):[],Se=0,Ne=D,Me=0,Oe=U;L>0&&(--Se,++Ne,--Me,++Oe);for(var Ie=0,ve=Se;ve<Ne;++ve){var ge=ve;ge<0&&(ge=0),ge>=D&&(ge=D-1);var we=z.north-te*ge;we=F?x(we):C-2*g(w(-we*b));var Ce=O(we),xe=I(we),Pe=ue*xe,Ue=(we-S)/(M-S);Ue=l.clamp(Ue,0,1);var De;X&&(De=(_.geodeticLatitudeToMercatorAngle(we)-ne)*re);for(var Le=Me;Le<Oe;++Le){var Fe=Le;Fe<0&&(Fe=0),Fe>=U&&(Fe=U-1);var Be=z.west+ee*Fe;F?Be=x(Be):Be*=b;var be,ze=ge*(U*Z)+Fe*Z;if(1===j)be=P[ze];else{be=0;var qe;if(J)for(qe=0;qe<j;++qe)be=be*K+P[ze+qe];else for(qe=j-1;qe>=0;--qe)be=be*K+P[ze+qe]}be=(be*Y+k)*V;var Ge=(Be-c)/(N-c);if(Ge=l.clamp(Ge,0,1),Re[Ie]=new n(Ge,Ue),ce=Math.max(ce,be),se=Math.min(se,be),Le!==Fe||ve!==ge){Le<0?Be-=1e-5*Q:Be+=1e-5*Q,ve<0?we+=1e-5*$:we-=1e-5*$,Ce=O(we),xe=I(we),Pe=ue*xe,be-=L}var We=Ce*O(Be),Ve=Ce*I(Be),Xe=ie*We,He=oe*Ve,Ye=v(Xe*We+He*Ve+Pe*xe),ke=1/Ye,je=Xe*ke,Ze=He*ke,Ke=Pe*ke,Je=new r;Je.x=je+We*be,Je.y=Ze+Ve*be,Je.z=Ke+xe*be,Te[Ie]=Je,ye[Ie]=be,X&&(Ae[Ie]=De),Ie++,f.multiplyByPoint(fe,Je,T),r.minimumByComponent(T,de,de),r.maximumByComponent(T,he,he),Ee=Math.min(Ee,be)}}var Qe,$e=t.fromPoints(Te);i(q)&&q.width<l.PI_OVER_TWO+l.EPSILON5&&(Qe=d.fromRectangle(q,se,ce,B));var et;if(W){et=new s(B).computeHorizonCullingPoint(G,Te)}for(var tt=new e(de,he,G),nt=new E(tt,Ee,ce,le,!1,X),rt=new Float32Array(pe*nt.getStride()),at=0,it=0;it<pe;++it)at=nt.encode(rt,at,Te[it],Re[it],ye[it],void 0,Ae[it]);return{vertices:rt,maximumHeight:ce,minimumHeight:se,encoding:nt,boundingSphere3D:$e,orientedBoundingBox:Qe,occludeePointInScaledSpace:et}},p}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,a=t.message;n=e(r)&&e(a)?r+": "+a:t.toString();var i=t.stack;return e(i)&&(n+="\n"+i),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return r}),define("Workers/createVerticesFromHeightmap",["../Core/Ellipsoid","../Core/HeightmapTessellator","../Core/Rectangle","./createTaskProcessorWorker"],function(e,t,n,r){"use strict";function a(r,a){var i=r.width,o=r.height;r.skirtHeight>0&&(i+=2,o+=2),r.ellipsoid=e.clone(r.ellipsoid),r.rectangle=n.clone(r.rectangle);var u=t.computeVertices(r),s=u.vertices;return a.push(s.buffer),{vertices:s.buffer,numberOfAttributes:u.encoding.getStride(),minimumHeight:u.minimumHeight,maximumHeight:u.maximumHeight,gridWidth:i,gridHeight:o,boundingSphere3D:u.boundingSphere3D,orientedBoundingBox:u.orientedBoundingBox,occludeePointInScaledSpace:u.occludeePointInScaledSpace,encoding:u.encoding}}return r(a)})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,m=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:m,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,m=i.y,E=i.z,p=l*l*d*d,_=f*f*m*m,y=h*h*E*E,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,g=u.z,N=o;N.x=A.x*S*2,N.y=A.y*v*2,N.z=A.z*g*2;var O,M,I,w,C,x,P,U,D,L,F,b=(1-R)*e.magnitude(n)/(.5*e.magnitude(N)),B=0;do{b-=B,I=1/(1+b*S),w=1/(1+b*v),C=1/(1+b*g),x=I*I,P=w*w,U=C*C,D=x*I,L=P*w,F=U*C,O=p*x+_*P+y*U-1,M=p*D*S+_*L*v+y*F*g;B=O/(-2*M)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*I,c.y=f*w,c.z=h*C,c):new e(l*I,f*w,h*C)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var m=r(n)?n.oneOverRadii:f,E=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,m,E,p,c);if(r(_)){var y=e.multiplyComponents(_,E,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=A,i.height=S,i):new u(R,A,S)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var m=new e,E=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,E);if(i(a)){var o=this.geodeticSurfaceNormal(a,m),u=e.subtract(n,a,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],m=d.x,E=d.y,p=d.z;i=Math.min(m,i),s=Math.max(m,s),o=Math.min(E,o),c=Math.max(E,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=i,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(E[n],m[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(E[a],m[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=m[i],h=E[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,m=n-u-f+d,E=2*(i-h),p=2*(a+l),_=2*(i+h),y=-n+u-f+d,T=2*(c-o),R=2*(a-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=m,t[1]=_,t[2]=R,t[3]=E,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=S,t):new s(m,E,p,_,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,m=a*i+c*o*u,E=-c*i+a*o*u,p=-o,_=c*n,y=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=m,t[5]=_,t[6]=h,t[7]=E,t[8]=y,t):new s(l,f,h,d,m,E,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var m=[1,0,0],E=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t, +n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,m,E,p){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(m,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(E,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,m=t.y*t.z,E=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),A=2*(f+E),S=2*(c+_),v=-s+d-p+y,g=2*(m-h),N=2*(f-E),O=2*(m+h),M=-s-d+p+y;return r[0]=T*a,r[1]=S*a,r[2]=N*a,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=O*o,r[7]=0,r[8]=A*u,r[9]=g*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,m=f.x,E=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,g=_*-R+y*-A+T*-S,N=m*R+E*A+p*S;return i(n)?(n[0]=u,n[1]=_,n[2]=-m,n[3]=0,n[4]=s,n[5]=y,n[6]=-E,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=v,n[13]=g,n[14]=N,n[15]=1,n):new l(u,s,c,v,_,y,T,g,-m,-E,-p,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,m=f,E=a+c,p=o+l,_=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=m,i[11]=0,i[12]=E,i[13]=p,i[14]=_,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var m=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],m)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],m)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],m)),n};var E=new e;l.getMaximumScale=function(t){return l.getScale(t,E),e.maximumComponent(E)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],m=e[11],E=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],g=t[5],N=t[6],O=t[7],M=t[8],I=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+E*S,F=i*T+s*R+h*A+p*S,b=a*T+c*R+d*A+_*S,B=o*T+l*R+m*A+y*S,z=r*v+u*g+f*N+E*O,q=i*v+s*g+h*N+p*O,G=a*v+c*g+d*N+_*O,V=o*v+l*g+m*N+y*O,W=r*M+u*I+f*w+E*C,X=i*M+s*I+h*w+p*C,H=a*M+c*I+d*w+_*C,Y=o*M+l*I+m*w+y*C,k=r*x+u*P+f*U+E*D,j=i*x+s*P+h*U+p*D,Z=a*x+c*P+d*U+_*D,K=o*x+l*P+m*U+y*D;return n[0]=L,n[1]=F,n[2]=b,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],m=e[14],E=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],g=t[12],N=t[13],O=t[14],M=r*E+o*p+c*_,I=i*E+u*p+l*_,w=a*E+s*p+f*_,C=r*y+o*T+c*R,x=i*y+u*T+l*R,P=a*y+s*T+f*R,U=r*A+o*S+c*v,D=i*A+u*S+l*v,L=a*A+s*S+f*v,F=r*g+o*N+c*O+h,b=i*g+u*N+l*O+d,B=a*g+s*N+f*O+m;return n[0]=M,n[1]=I,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=b,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],m=t[2],E=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*m,S=i*h+u*d+l*m,v=a*h+s*d+f*m,g=r*E+o*p+c*_,N=i*E+u*p+l*_,O=a*E+s*p+f*_,M=r*y+o*T+c*R,I=i*y+u*T+l*R,w=a*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=g,n[5]=N,n[6]=O,n[7]=0,n[8]=M,n[9]=I,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],m=e[13],E=e[2],p=e[6],A=e[10],S=e[14],v=e[3],g=e[7],N=e[11],O=e[15],M=A*O,I=S*N,w=p*O,C=S*g,x=p*N,P=A*g,U=E*O,D=S*v,L=E*N,F=A*v,b=E*g,B=p*v,z=M*h+C*d+x*m-(I*h+w*d+P*m),q=I*f+U*d+F*m-(M*f+D*d+L*m),G=w*f+D*h+b*m-(C*f+U*h+B*m),V=P*f+L*h+B*d-(x*f+F*h+b*d),W=I*i+w*a+P*o-(M*i+C*a+x*o),X=M*r+D*a+L*o-(I*r+U*a+F*o),H=C*r+U*i+B*o-(w*r+D*i+b*o),Y=x*r+F*i+b*a-(P*r+L*i+B*a);M=a*m,I=o*d,w=i*m,C=o*h,x=i*d,P=a*h,U=r*m,D=o*f,L=r*d,F=a*f,b=r*h,B=i*f;var k=M*g+C*N+x*O-(I*g+w*N+P*O),j=I*v+U*N+F*O-(M*v+D*N+L*O),Z=w*v+D*g+b*O-(C*v+U*g+B*O),K=P*v+L*g+B*N-(x*v+F*g+b*N),J=w*A+P*S+I*p-(x*S+M*p+C*A),Q=L*S+M*E+D*A-(U*A+F*S+I*E),$=U*p+B*S+C*E-(b*S+w*E+D*p),ee=b*A+x*E+F*p-(L*p+B*A+P*E),te=r*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],m=-n*f-r*h-i*d,E=-a*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=m,t[13]=E,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var m=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,m),o=Math.max(o,m)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,m=0,E=e.length;m<E;m++){var p=t.cartesianToCartographic(e[m]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,m=e.west,E=c;E.height=i,E.longitude=m,E.latitude=f,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=h,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=m,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)E.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,E)&&(o[l]=t.cartographicToCartesian(E,o[l]),l++);return 0===E.latitude&&(E.longitude=m,o[l]=t.cartographicToCartesian(E,o[l]),l++,E.longitude=d,o[l]=t.cartographicToCartesian(E,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var m=new e,E=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,g=new e,N=new e,O=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,m),u=e.clone(i,E),s=e.clone(i,p),c=e.clone(i,_),l=e.clone(i,y),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var O=i.x,M=i.y,I=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),M<u.y&&e.clone(i,u),M>l.y&&e.clone(i,l),I<s.z&&e.clone(i,s),I>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,A)),C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=S;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,A)),b=Math.sqrt(F),B=v;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,A),.5,N),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,A));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(i,L,A));if(W>F){var X=Math.sqrt(W);b=.5*(b+X),F=b*b;var H=X-b;L.x=(b*L.x+H*i.x)/X,L.y=(b*L.y+H*i.y)/X,L.z=(b*L.z+H*i.z)/X}}return b<G?(e.clone(L,n.center),n.radius=b):(e.clone(q,n.center),n.radius=G),n};var M=new u,I=new e,w=new e,C=new t,x=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,M),h.southwest(t,C),C.height=r,h.northeast(t,x),x.height=o;var s=n.project(C,I),c=n.project(x,w),l=c.x-s.x,f=c.y-s.y,m=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+m*m);var E=u.center;return E.x=s.x+.5*l,E.y=s.y+.5*f,E.z=s.z+.5*m,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,m),l=e.clone(u,E),f=e.clone(u,p),h=e.clone(u,_),O=e.clone(u,y),M=e.clone(u,T),I=t.length;for(s=0;s<I;s+=r){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>h.x&&e.clone(u,h),C<l.y&&e.clone(u,l),C>O.y&&e.clone(u,O),x<f.z&&e.clone(u,f),x>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(h,c,A)),U=e.magnitudeSquared(e.subtract(O,l,A)),D=e.magnitudeSquared(e.subtract(M,f,A)),L=c,F=h,b=P;U>b&&(b=U,L=l,F=O),D>b&&(b=D,L=f,F=M);var B=S;B.x=.5*(L.x+F.x),B.y=.5*(L.y+F.y),B.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,A)),q=Math.sqrt(z),G=v;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=O.y,V.z=M.z;var W=e.multiplyByScalar(e.add(G,V,A),.5,N),X=0;for(s=0;s<I;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,A));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,B,A));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;B.x=(q*B.x+j*u.x)/k,B.y=(q*B.y+j*u.y)/k,B.z=(q*B.z+j*u.z)/k}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,m),s=e.clone(i,E),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),h=e.clone(i,T),O=t.length;for(o=0;o<O;o+=3){var M=t[o]+n[o],I=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=M,i.y=I,i.z=w,M<u.x&&e.clone(i,u),M>l.x&&e.clone(i,l),I<s.y&&e.clone(i,s),I>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>h.z&&e.clone(i,h)}var C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=e.magnitudeSquared(e.subtract(h,c,A)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=S;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var b=e.magnitudeSquared(e.subtract(D,F,A)),B=Math.sqrt(b),z=v;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,A),.5,N),V=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,A));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(i,F,A));if(X>b){var H=Math.sqrt(X);B=.5*(B+H),b=B*B;var Y=H-B;F.x=(B*F.x+Y*i.x)/H,F.y=(B*F.y+Y*i.y)/H,F.z=(B*F.z+Y*i.z)/H}}return B<V?(e.clone(F,r.center),r.radius=B):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var b=new e,B=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,b),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,W=new e,X=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),m=j,E=m[0];e.add(s,l,E),e.add(E,c,E),E=m[1],e.add(s,l,E),e.add(E,h,E),E=m[2],e.add(s,f,E),e.add(E,h,E),E=m[3],e.add(s,f,E),e.add(E,c,E),e.negate(s,s),E=m[4],e.add(s,l,E),e.add(E,c,E),E=m[5],e.add(s,l,E),e.add(E,h,E),E=m[6],e.add(s,f,E),e.add(E,h,E),E=m[7],e.add(s,f,E),e.add(E,c,E);for(var p=m.length,_=0;_<p;++_){var y=m[_];e.add(o,y,y);var T=a.cartesianToCartographic(y,k);n.project(T,y)}r=d.fromPoints(m,r),o=r.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return O*e*e*e},d}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x), +n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,n,r,i,a,o){"use strict";function u(e,n){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,i(n)&&(this.cameraPosition=n)}function s(e,n,r){var i=e.transformPositionToScaledSpace(n,m),a=t.magnitudeSquared(i),o=Math.sqrt(a),u=t.divideByScalar(i,o,E);a=Math.max(1,a),o=Math.max(1,o);var s=t.dot(u,r),c=t.magnitude(t.cross(u,r,u)),l=1/o;return 1/(s*l-c*(Math.sqrt(a-1)*l))}function c(e,n,r){if(!(n<=0||n===1/0||n!==n))return t.multiplyByScalar(e,n,r)}function l(e,n){return t.equals(n,t.ZERO)?n:(e.transformPositionToScaledSpace(n,p),t.normalize(p,p))}a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var n=this._ellipsoid,r=n.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),i=t.magnitudeSquared(r)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=r,this._distanceToLimbInScaledSpaceSquared=i}}});var f=new t;u.prototype.isPointVisible=function(e){var t=this._ellipsoid,n=t.transformPositionToScaledSpace(e,f);return this.isScaledSpacePointVisible(n)},u.prototype.isScaledSpacePointVisible=function(e){var n=this._cameraPositionInScaledSpace,r=this._distanceToLimbInScaledSpaceSquared,i=t.subtract(e,n,f),a=-t.dot(i,n);return!(r<0?a>0:a>r&&a*a/t.magnitudeSquared(i)>r)},u.prototype.computeHorizonCullingPoint=function(e,n,r){i(r)||(r=new t);for(var a=this._ellipsoid,o=l(a,e),u=0,f=0,h=n.length;f<h;++f){var d=n[f],m=s(a,d,o);u=Math.max(u,m)}return c(o,u,r)};var h=new t;u.prototype.computeHorizonCullingPointFromVertices=function(e,n,a,o,u){i(u)||(u=new t),o=r(o,t.ZERO);for(var f=this._ellipsoid,d=l(f,e),m=0,E=0,p=n.length;E<p;E+=a){h.x=n[E]+o.x,h.y=n[E+1]+o.y,h.z=n[E+2]+o.z;var _=s(f,h,d);m=Math.max(m,_)}return c(d,m,u)};var d=[];u.prototype.computeHorizonCullingPointFromRectangle=function(n,r,i){var a=o.subsample(n,r,0,d),u=e.fromPoints(a);if(!(t.magnitude(u.center)<.1*r.minimumRadius))return this.computeHorizonCullingPoint(u.center,a,i)};var m=new t,E=new t,p=new t;return u}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,m=o*s-h,E=o*c-u*s,p=u*c-d,_=4*m*p-E*E;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=m,R=-2*u*m+o*E):(y=c,T=p,R=-c*E+2*s*p);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-_);a=-R+S;var v=a/2,g=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),N=a===S?-g:-T/g;return i=T<=0?g+N:-R/(g*g+N*N+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var O=m,M=-2*u*m+o*E,I=p,w=-c*E+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-M)/3);i=2*Math.sqrt(-O);var U=Math.cos(P);a=i*U;var D=i*(-U/2-x*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,b=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),i=2*Math.sqrt(-I),U=Math.cos(P),a=i*U,D=i*(-U/2-x*Math.sin(P));var B=-c,z=a+D<2*s?a+s:D+s,q=B/z,G=F*z,V=-L*z-F*B,W=L*B,X=(s*V-u*W)/(-u*V+s*G);return b<=X?b<=q?X<=q?[b,X,q]:[b,q,X]:[q,b,X]:b<=q?[X,b,q]:X<=q?[X,q,b]:[q,X,b]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var m=r.computeRealRoots(1,s,l);if(2===m.length){var E,p=m[0],_=m[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return E=Math.sqrt(p),[h-E,h+E];if(p<0&&_>=0)return E=Math.sqrt(_),[h-E,h+E]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),g=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,v[1]<=g[0]?[v[0],v[1],g[0],g[1]]:g[1]<=v[0]?[g[0],g[1],v[0],v[1]]:v[0]>=g[0]&&v[1]<=g[1]?[g[0],v[0],v[1],g[1]]:g[0]>=v[0]&&g[1]<=v[1]?[v[0],g[0],g[1],v[1]]:v[0]>g[0]&&v[0]<g[1]?[g[0],v[0],g[1],v[1]]:[v[0],g[0],v[1],g[1]]):v):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var m,E,p=d[0],_=i-p,y=_*_,T=t/2,R=_/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*p,g=c+4*Math.abs(p);if(p<0||A*g<v*S){var N=Math.sqrt(v);m=N/2,E=0===N?0:(t*R-a)/N}else{var O=Math.sqrt(A);m=0===O?0:(t*R-a)/O,E=O/2}var M,I;0===T&&0===m?(M=0,I=0):n.sign(T)===n.sign(m)?(M=T+m,I=p/M):(I=T-m,M=p/I);var w,C;0===R&&0===E?(w=0,C=0):n.sign(R)===n.sign(E)?(w=R+E,C=o/w):(C=R-E,w=o/C);var x=r.computeRealRoots(1,M,w),P=r.computeRealRoots(1,I,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),m=e.magnitudeSquared(l)-c,E=f(h,d,m,S);if(r(E))return i.start=E.root0,i.stop=E.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function m(t,n,r,i,a){var l,f=i*i,h=a*a,m=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,E=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(m,E,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-A)),T.push(new e(i,a*R,a*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(i,a*S,a*-v)),T.push(new e(i,a*S,a*v))}return T}var g=y*y,N=_*_,O=m*m,M=y*_,I=O+N,w=2*(E*m+M),C=2*p*m+E*E-N+g,x=2*(p*E-M),P=p*p-g;if(0===I&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(I,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],b=F*F,B=Math.max(1-b,0),z=Math.sqrt(B);L=o.sign(m)===o.sign(p)?d(m*b+p,E*F,o.EPSILON12):o.sign(p)===o.sign(E*F)?d(m*b,E*F+p,o.EPSILON12):d(m*b+E*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var E={};E.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var p=new e,_=new e,y=new e,T=new e,R=new e;E.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,m=t.direction,E=e.subtract(i,r,p),A=e.subtract(a,r,_),S=e.cross(m,A,y),v=e.dot(E,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,E,R),(f=e.dot(m,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var g=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*g)<0||l>1)return;if(c=e.cross(s,E,R),(f=e.dot(m,c)*g)<0||l+f>1)return;h=e.dot(A,c)*g}return h},E.rayTriangle=function(t,n,i,a,o,u){var s=E.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;E.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=E.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};E.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;E.lineSegmentSphere=function(t,n,i,a){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;E.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var m=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,m<o)return;if(m>o){u=d*d-o,s=-d+Math.sqrt(u);var E=s/i,p=r/s;return E<p?new a(E,p):{start:p,stop:E}}var _=Math.sqrt(r/i);return new a(_,_)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var O=new e,M=new e,I=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,b=new u,B=new e,z=new e,q=new t;E.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,O);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,M),M),E=e.normalize(e.cross(f,d,I),I),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=E.x,p[7]=E.y,p[8]=E.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var A,S,v=u.multiply(u.multiply(_,T,F),R,F),g=u.multiply(u.multiply(v,y,b),p,b),N=u.multiplyByVector(v,i,C),G=m(g,e.negate(N,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],B),B);var Y=e.normalize(e.subtract(A,i,w),w),k=e.dot(Y,a);k>X&&(X=k,W=e.clone(A,W))}var j=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),S=e.magnitude(e.subtract(W,i,w))*Math.sqrt(1-X*X),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return E.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},E.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return E.lineSegmentPlane(t,n,i,f),E.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return E.lineSegmentPlane(n,r,i,f),E.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return E.lineSegmentPlane(r,t,i,f),E.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return E.lineSegmentPlane(n,t,i,f),E.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return E.lineSegmentPlane(r,n,i,f),E.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return E.lineSegmentPlane(t,r,i,f),E.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},E}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return m(e)}function i(e){return m(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,m;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return E(f,e),e},m=function(e){return e=t(e),h=e.then,m=t,d=_,E(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return p(2,arguments),e(t,function(t){function u(e){E(e)}function s(e){m(e)}var c,l,f,h,d,m,E,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,E=function(e){h.push(e),--l||(m=E=_,d.reject(h))},m=function(e){f.push(e),--c||(m=E=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function m(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function E(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=m,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,m,E,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,g=0;s&&g<v;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(g+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,S);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),m=d<0?"-":T,_=m+i(String(Math.abs(d)),f,"0",!1),a(_,m,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,m=d<0?"-":T,E=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=m+Math.abs(d)[E](f),a(_,m,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return E.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=E.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){E.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}E.addSeconds(e,i,e)}function h(e,n){y.julianDate=e;var r=E.leapSeconds,i=t(r,y,l);if(i<0&&(i=~i),0===i)return E.addSeconds(e,-r[0].offset,n);if(i>=r.length)return E.addSeconds(e,-r[i-1].offset,n);var a=E.secondsDifference(r[i].julianDate,e);return 0===a?E.addSeconds(e,-r[i].offset,n):a<=1?void 0:E.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function m(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function E(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var p=new a,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,M=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;E.fromGregorianDate=function(e,t){var n=m(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new E(n[0],n[1],c.UTC)},E.fromDate=function(e,t){var n=m(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new E(n[0],n[1],c.UTC)},E.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,g=0,I=u[0],w=u[1];if(null!==(u=I.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=I.match(R)))n=+u[1],s=+u[2];else if(null!==(u=I.match(T)))n=+u[1];else{var C;if(null!==(u=I.match(A)))n=+u[1],C=+u[2],a=o(n);else if(null!==(u=I.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(C),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(w)){u=w.match(M),null!==u?(h=+u[1],p=+u[2],y=+u[3],g=1e3*+(u[4]||0),D=5):(u=w.match(O),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(N))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],b=+(u[D+2]||0);switch(L){case"+":h-=F,p-=b;break;case"-":h+=F,p+=b;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var B=60===y;for(B&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:_[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:_[s-1],l+=i;var z=m(n,s,l,h,p,y,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new E(z[0],z[1],c.UTC),B&&E.addSeconds(t,1,t),t},E.now=function(e){return E.fromDate(new Date,e)};var I=new E(0,0,c.TAI);return E.toGregorianDate=function(e,t){var n=!1,i=h(e,I);r(i)||(E.addSeconds(e,-1,I),i=h(I,I),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,m=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=m,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new a(_,p,m,y,R,A,S,n)},E.toDate=function(e){var t=E.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},E.toIso8601=function(t,n){var i,a=E.toGregorianDate(t,p);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},E.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new E(e.dayNumber,e.secondsOfDay,c.TAI)},E.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},E.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},E.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(E.secondsDifference(e,t))<=n},E.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},E.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},E.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},E.computeTaiMinusUtc=function(e){y.julianDate=e;var n=E.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},E.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},E.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},E.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},E.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},E.lessThan=function(e,t){return E.compare(e,t)<0},E.lessThanOrEquals=function(e,t){return E.compare(e,t)<=0},E.greaterThan=function(e,t){return E.compare(e,t)>0},E.greaterThanOrEquals=function(e,t){return E.compare(e,t)>=0},E.prototype.clone=function(e){return E.clone(this,e)},E.prototype.equals=function(e){return E.equals(this,e)},E.prototype.equalsEpsilon=function(e,t){return E.equalsEpsilon(this,e,t)},E.prototype.toString=function(){return E.toIso8601(this)},E.leapSeconds=[new u(new E(2441317,43210,c.TAI),10),new u(new E(2441499,43211,c.TAI),11),new u(new E(2441683,43212,c.TAI),12),new u(new E(2442048,43213,c.TAI),13),new u(new E(2442413,43214,c.TAI),14),new u(new E(2442778,43215,c.TAI),15),new u(new E(2443144,43216,c.TAI),16),new u(new E(2443509,43217,c.TAI),17),new u(new E(2443874,43218,c.TAI),18),new u(new E(2444239,43219,c.TAI),19),new u(new E(2444786,43220,c.TAI),20),new u(new E(2445151,43221,c.TAI),21),new u(new E(2445516,43222,c.TAI),22),new u(new E(2446247,43223,c.TAI),23),new u(new E(2447161,43224,c.TAI),24),new u(new E(2447892,43225,c.TAI),25),new u(new E(2448257,43226,c.TAI),26),new u(new E(2448804,43227,c.TAI),27),new u(new E(2449169,43228,c.TAI),28),new u(new E(2449534,43229,c.TAI),29),new u(new E(2450083,43230,c.TAI),30),new u(new E(2450630,43231,c.TAI),31),new u(new E(2451179,43232,c.TAI),32),new u(new E(2453736,43233,c.TAI),33),new u(new E(2454832,43234,c.TAI),34),new u(new E(2456109,43235,c.TAI),35),new u(new E(2457204,43236,c.TAI),36),new u(new E(2457754,43237,c.TAI),37)],E}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={} +;return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function m(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==c.CANCELLED&&(--A.numberOfActiveRequests,--N[e.serverKey],M.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){return function(t){e.state!==c.CANCELLED&&(++A.numberOfFailedRequests,--A.numberOfActiveRequests,--N[e.serverKey],M.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function _(e){var t=m(e);return e.state=c.ACTIVE,g.push(e),++A.numberOfActiveRequests,++A.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(p(e)),t}function y(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++A.numberOfCancelledRequests,e.deferred.reject(),t&&(--A.numberOfActiveRequests,--N[e.serverKey],++A.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){A.numberOfAttemptedRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(A.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+A.numberOfAttemptedRequests),A.numberOfActiveRequests>0&&console.log("Number of active requests: "+A.numberOfActiveRequests),A.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+A.numberOfCancelledRequests),A.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+A.numberOfCancelledActiveRequests),A.numberOfFailedRequests>0&&console.log("Number of failed requests: "+A.numberOfFailedRequests),T())}var A={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},S=20,v=new o({comparator:l});v.maximumLength=S,v.reserve(S);var g=[],N={},O="undefined"!=typeof document?new e(document.location.href):new e,M=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=M,i(f,{statistics:{get:function(){return A}},priorityHeapLength:{get:function(){return S},set:function(e){if(e<S)for(;v.length>e;){var t=v.pop();y(t)}S=e,v.maximumLength=e,v.reserve(e)}}}),f.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&y(t),t.state===c.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=v.internalArray,a=v.length;for(e=0;e<a;++e)h(i[e]);v.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&v.length>0;)t=v.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):y(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=N[i];return r(a)||(N[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return M.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++A.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return _(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=v.insert(e);if(r(t)){if(t===e)return;y(t)}return m(e)}},f.clearForSpecs=function(){for(;v.length>0;){y(v.pop())}for(var e=g.length,t=0;t<e;++t)y(g[t]);g.length=0,N={},A.numberOfAttemptedRequests=0,A.numberOfActiveRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0,A.numberOfFailedRequests=0,A.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=v,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E,p,_,y,T,R,A,S,v,g,N){"use strict";function O(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=_(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function M(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=p(n):e.query=r[0]}function I(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function w(e){if(e.state===A.ISSUED||e.state===A.ACTIVE)throw new S("The Resource is already being fetched.");e.state=A.UNISSUED,e.deferred=void 0}function C(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=I(e.templateValues,{}),this._queryParameters=I(e.queryParameters,{}),this.headers=I(e.headers,{}),this.request=i(e.request,new y),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function x(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=N.defer();return C._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=A.UNISSUED,n.deferred=void 0,x(e,t)):N.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=N.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},C._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=A.UNISSUED,i.deferred=void 0,P(e,t,n)):N.reject(r)})})}function U(e,t){w(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=C._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=A.UNISSUED,n.deferred=void 0,e.fetch(t)):N.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var b=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();C.createIfNeeded=function(e,t){if(e instanceof C)return e.clone();if("string"!=typeof e)return e;var n=I(t,{});return n.url=e,new C(n)},o(C,{isBlobSupported:{get:function(){return b}}}),o(C.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);O(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return E(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return m(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),C.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new g(this._url);e&&M(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},C.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},C.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},C.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new g(e.url);O(n,t),n.fragment=void 0,t._url=n.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},C.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var n=this;return N(t(this,e)).then(function(e){return++n._retryCount,e})},C.prototype.clone=function(e){return a(e)||(e=new C({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},C.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},C.prototype.appendForwardSlash=function(){this._url=e(this._url)},C.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},C.fetchArrayBuffer=function(e){return new C(e).fetchArrayBuffer()},C.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},C.fetchBlob=function(e){return new C(e).fetchBlob()},C.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),w(this.request),!b||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return x(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new C({url:t}),x(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),N.reject(e)})}},C.fetchImage=function(e){return new C(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},C.prototype.fetchText=function(){return this.fetch({responseType:"text"})},C.fetchText=function(e){return new C(e).fetchText()},C.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},C.fetchJson=function(e){return new C(e).fetchJson()},C.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},C.fetchXML=function(e){return new C(e).fetchXML()},C.prototype.fetchJsonp=function(e){e=i(e,"callback"),w(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},C.fetchJsonp=function(e){return new C(e).fetchJsonp(e.callbackParameterName)},C.prototype.fetch=function(e){return e=I(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return C.fetch=function(e){return new C(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C.prototype.post=function(e,n){return t.defined("data",e),n=I(n,{}),n.method="POST",n.data=e,U(this,n)},C.post=function(e){return new C(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C._Implementations={},C._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(v.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},C._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(v.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new S("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},C._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},C._DefaultImplementations={},C._DefaultImplementations.createImage=C._Implementations.createImage,C._DefaultImplementations.loadWithXhr=C._Implementations.loadWithXhr,C._DefaultImplementations.loadAndExecuteScript=C._Implementations.loadAndExecuteScript,C.DEFAULT=c(new C({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),C}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))m(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){m(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else m(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function m(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||m<0||E<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=m,e._taiMinusUtcSecondsColumn=E,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var S=p[R+i],v=p[R+E],g=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,v,f.TAI);if(_.push(N),T){if(v!==y&&r(y)){var O=o.leapSeconds,M=t(O,N,d);if(M<0){var I=new u(N,v);O.splice(~M,0,I)}}y=v}}}function E(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return E(e,n,i,s,u),u;if(r.equals(l))return E(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,m=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-m;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?m=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,m,_),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),m=!r(h),E=m||o.greaterThanOrEquals(h,e);if(d&&E)return s=u,!m&&h.equals(e)&&++s,l=s+1,_(this,a,this._samples,e,s,l,n),n}var p=t(a,e,o.compare,this._dateColumn);return p>=0?(p<a.length-1&&a[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){ +var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],m=f;m<=h;++m)d.push(l(this,m));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var m,E,p=a-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(m=0;m<=u;++m)_[m]=p-R[m];for(m=0;m<=u;++m){for(T[m]=1,E=0;E<=u;++E)E!==m&&(T[m]*=_[E]);T[m]*=y[m];var A=3*(s+m);n.x+=T[m]*d[A++],n.y+=T[m]*d[A++],n.s+=T[m]*d[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function a(){return i()&&S}function o(){if(!t(v)&&(v=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,g=r(e[1]))}return v}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(N=!0,O=r(e[1]),O.isNightly=!!e[2])}return N}function c(){return s()&&O}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,I=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,I=r(e[1]))}return M}function f(){return l()&&I}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function m(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function E(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return m()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,g,N,O,M,I,w,C,x,P,U,D,L,F,b={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:m,firefoxVersion:p,isWindows:E,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return b.supportsFullscreen=function(){return n.supportsFullscreen()},b.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},b.supportsWebWorkers=function(){return"undefined"!=typeof Worker},b}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],m=e[u.COLUMN2ROW2],E=h+d+m;if(E>0)n=Math.sqrt(E+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),m>h&&m>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,m=new s,E=new s;s.fromHeadingPitchRoll=function(t,n){return E=s.fromAxisAngle(e.UNIT_X,t.roll,h),m=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(m,E,m),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,m=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=m,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,g=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=S=s.negate(t,S)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),g=s.multiplyByScalar(a,Math.sin(n*u),g),r=s.add(v,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var N=new e,O=new e,M=new s,I=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,M);s.multiply(a,r,I);var o=s.log(I,N);s.multiply(a,t,I);var u=s.log(I,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,M),u=s.slerp(n,r,i,I);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,C=1.9011074535173003,x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,b=2*F+1;x[L]=1/(F*b),P[L]=F/b}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),m=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(m,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,M),u=s.fastSlerp(n,r,i,I);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,O=new n,M=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=A[e][t],a=e+t;return u(v[a])?r=v[a]:(r=function(r,a,s){if(u(s)||(s=new _),E.equalsEpsilon(r.x,0,E.EPSILON14)&&E.equalsEpsilon(r.y,0,E.EPSILON14)){var c=E.sign(r.z);n.unpack(S[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(S[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(S[i],0,M),"east"!==i&&"west"!==i&&n.multiplyByScalar(M,c,M)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),N=g[e],O=g[t],M=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=M.x,s[9]=M.y,s[10]=M.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var I=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,I),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return a=i(e,r,a),_.multiply(a,s,a)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(a,P);return y.fromRotationMatrix(o,i)};var U=E.TWO_PI/86400,D=new m;R.computeTemeToPseudoFixedMatrix=function(e,t){D=m.addSeconds(e,-m.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%E.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),b=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=b;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-a.s,B),h=p.multiply(l,f,b),d=e.dayNumber,_=e.secondsOfDay-m.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=_/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*E.TWO_PI;var v=p.fromRotationZ(S,B),g=p.multiply(h,v,b),N=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),M=Math.sin(n.xPoleWander),I=Math.sin(n.yPoleWander),w=r-2451545+i/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*E.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=B;return U[0]=N*x,U[1]=N*P,U[2]=M,U[3]=-O*P+I*M*x,U[4]=O*x+I*M*P,U[5]=-I*N,U[6]=-I*P-O*M*x,U[7]=I*x-O*M*P,U[8]=O*N,p.multiply(g,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return _.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,E.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new p),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var W=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new i,H=new n,Y=new n,k=new p,j=new _,Z=new _;return R.basisTo2D=function(e,t,r){var i=_.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=_.inverseTransformation(s,Z),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(W,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=_.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,j);return _.multiply(W,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function m(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,E)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,E));var a=n.fromCartesian4(l.getColumn(r,2,E));this._plane=f.fromPointNormal(e,a)}var E=new r;o(m.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;m.fromPoints=function(t,n){return new m(e.fromPoints(t,p).center,n)};var _=new h,y=new n;m.prototype.projectPointOntoPlane=function(e,r){var i=_;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,y);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},m.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},m.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=_;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,y);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},m.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return m.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},m}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E){"use strict";function p(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=d.clone(a(t,d.ZERO))}function _(e,t,r,i,a,u,s,c){o(c)||(c=new p);var l=c.halfAxes;d.setColumn(l,0,e.xAxis,l),d.setColumn(l,1,e.yAxis,l),d.setColumn(l,2,e.zAxis,l);var f=O;f.x=(t+r)/2,f.y=(i+a)/2,f.z=(u+s)/2;var h=M;h.x=(r-t)/2,h.y=(a-i)/2,h.z=(s-u)/2;var m=c.center;return f=d.multiplyByVector(l,f,f),n.add(e.origin,f,m),d.multiplyByScale(l,h,l),c}p.packedLength=n.packedLength+d.packedLength,p.pack=function(e,t,r){return r=a(r,0),n.pack(e.center,t,r),d.pack(e.halfAxes,t,r+n.packedLength),t},p.unpack=function(e,t,r){return t=a(t,0),o(r)||(r=new p),n.unpack(e,t,r.center),d.unpack(e,t+n.packedLength,r.halfAxes),r};var y=new n,T=new n,R=new n,A=new n,S=new n,v=new n,g=new d,N={unitary:new d,diagonal:new d};p.fromPoints=function(e,t){if(o(t)||(t=new p),!o(e)||0===e.length)return t.halfAxes=d.ZERO,t.center=n.ZERO,t;var r,i=e.length,a=n.clone(e[0],y);for(r=1;r<i;r++)n.add(a,e[r],a);var u=1/i;n.multiplyByScalar(a,u,a);var s,c=0,l=0,f=0,h=0,m=0,E=0;for(r=0;r<i;r++)s=n.subtract(e[r],a,T),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,h+=s.y*s.y,m+=s.y*s.z,E+=s.z*s.z;c*=u,l*=u,f*=u,h*=u,m*=u,E*=u;var _=g;_[0]=c,_[1]=l,_[2]=f,_[3]=l,_[4]=h,_[5]=m,_[6]=f,_[7]=m,_[8]=E;var O=d.computeEigenDecomposition(_,N),M=d.clone(O.unitary,t.halfAxes),I=d.getColumn(M,0,A),w=d.getColumn(M,1,S),C=d.getColumn(M,2,v),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<i;r++)s=e[r],x=Math.max(n.dot(I,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(I,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);I=n.multiplyByScalar(I,.5*(D+x),I),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var b=n.add(I,w,t.center);n.add(b,C,b);var B=R;return B.x=x-D,B.y=P-L,B.z=U-F,n.multiplyByScalar(B,.5,B),d.multiplyByScale(t.halfAxes,B,t.halfAxes),t};var O=new n,M=new n,I=new r,w=new n,C=[new r,new r,new r,new r,new r,new r,new r,new r],x=[new n,new n,new n,new n,new n,new n,new n,new n],P=[new t,new t,new t,new t,new t,new t,new t,new t];p.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,s.WGS84);var o=E.center(e,I),u=r.cartographicToCartesian(o,w),l=new c(u,r),f=l.plane,h=C[0],d=C[1],p=C[2],y=C[3],T=C[4],R=C[5],A=C[6],S=C[7],v=o.longitude,g=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=g,h.latitude=d.latitude=p.latitude=e.north,A.longitude=S.longitude=h.longitude=e.west,R.longitude=d.longitude=v,T.longitude=y.longitude=p.longitude=e.east,p.height=d.height=h.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(C,x),l.projectPointsToNearestOnPlane(x,P);var N=Math.min(P[6].x,P[7].x,P[0].x),O=Math.max(P[2].x,P[3].x,P[4].x),M=Math.min(P[4].y,P[5].y,P[6].y),U=Math.max(P[0].y,P[1].y,P[2].y);return p.height=h.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(C,x),_(l,N,O,M,U,Math.min(m.getPointDistance(f,x[0]),m.getPointDistance(f,x[2]),m.getPointDistance(f,x[4]),m.getPointDistance(f,x[6])),n,i)},p.clone=function(e,t){if(o(e))return o(t)?(n.clone(e.center,t.center),d.clone(e.halfAxes,t.halfAxes),t):new p(e.center,e.halfAxes)},p.intersectPlane=function(e,t){var r=e.center,i=t.normal,a=e.halfAxes,o=i.x,u=i.y,s=i.z,c=Math.abs(o*a[d.COLUMN0ROW0]+u*a[d.COLUMN0ROW1]+s*a[d.COLUMN0ROW2])+Math.abs(o*a[d.COLUMN1ROW0]+u*a[d.COLUMN1ROW1]+s*a[d.COLUMN1ROW2])+Math.abs(o*a[d.COLUMN2ROW0]+u*a[d.COLUMN2ROW1]+s*a[d.COLUMN2ROW2]),f=n.dot(i,r)+t.distance;return f<=-c?l.OUTSIDE:f>=c?l.INSIDE:l.INTERSECTING};var U=new n,D=new n,L=new n,F=new n;p.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,O),i=e.halfAxes,a=d.getColumn(i,0,U),o=d.getColumn(i,1,D),u=d.getColumn(i,2,L),s=n.magnitude(a),c=n.magnitude(o),l=n.magnitude(u);n.normalize(a,a),n.normalize(o,o),n.normalize(u,u);var f=F;f.x=n.dot(r,a),f.y=n.dot(r,o),f.z=n.dot(r,u);var h,m=0;return f.x<-s?(h=f.x+s,m+=h*h):f.x>s&&(h=f.x-s,m+=h*h),f.y<-c?(h=f.y+c,m+=h*h):f.y>c&&(h=f.y-c,m+=h*h),f.z<-l?(h=f.z+l,m+=h*h):f.z>l&&(h=f.z-l,m+=h*h),m};var b=new n,B=new n;p.computePlaneDistances=function(e,t,r,i){o(i)||(i=new f);var a=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,l=d.getColumn(c,0,U),h=d.getColumn(c,1,D),m=d.getColumn(c,2,L),E=n.add(l,h,b);n.add(E,m,E),n.add(E,s,E);var p=n.subtract(E,t,B),_=n.dot(r,p);return a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,E),n.add(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,E),n.subtract(E,h,E),n.add(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,E),n.subtract(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.add(E,h,E),n.add(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.add(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.subtract(E,h,E),n.add(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,E),n.subtract(E,h,E),n.subtract(E,m,E),n.subtract(E,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),i.start=a,i.stop=u,i};var z=new e;return p.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,z);return!n.isBoundingSphereVisible(r)},p.prototype.intersectPlane=function(e){return p.intersectPlane(this,e)},p.prototype.distanceSquaredTo=function(e){return p.distanceSquaredTo(this,e)},p.prototype.computePlaneDistances=function(e,t,n){return p.computePlaneDistances(this,e,t,n)},p.prototype.isOccluded=function(e){return p.isOccluded(this,e)},p.equals=function(e,t){return e===t||o(e)&&o(t)&&n.equals(e.center,t.center)&&d.equals(e.halfAxes,t.halfAxes)},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,n,r,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,n){return u.octDecodeInRange(e,t,255,n)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),i=256*(n-r);return u.octDecode(r,i,t)},u.octPack=function(e,t,n,r){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(n,s);return r.x=65536*o.x+i,r.y=65536*o.y+a,r},u.octUnpack=function(e,t,n,r){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,n),u.octDecode(a,s,r)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},u.zigZagDeltaDecode=function(e,t,n){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,r(n)&&(s+=o(n[c]),n[c]=s)},u}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989, +TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,i,a,o,u,s){"use strict";function c(e,t,r,o,c,h){var p,_,y,T;if(a(e)&&a(t)&&a(r)&&a(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),v=r-t;p=Math.max(n.maximumComponent(S),v)<E-1?s.BITS12:s.NONE,_=e.center,y=u.inverseTransformation(o,new u);var g=n.negate(R,l);u.multiply(u.fromTranslation(g,d),y,y);var N=l;N.x=1/S.x,N.y=1/S.y,N.z=1/S.z,u.multiply(u.fromScale(N,d),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var O=u.fromTranslation(R,d),M=u.fromScale(S,m),I=u.multiply(O,M,d);u.multiply(o,I,o),u.multiply(T,I,T)}this.quantization=p,this.minimumHeight=t,this.maximumHeight=r,this.center=_,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=i(h,!1)}var l=new n,f=new n,h=new t,d=new u,m=new u,E=Math.pow(2,12);c.prototype.encode=function(r,i,a,c,f,d,m){var E=c.x,p=c.y;if(this.quantization===s.BITS12){a=u.multiplyByPoint(this.toScaledENU,a,l),a.x=o.clamp(a.x,0,1),a.y=o.clamp(a.y,0,1),a.z=o.clamp(a.z,0,1);var _=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/_,0,1);t.fromElements(a.x,a.y,h);var T=e.compressTextureCoordinates(h);t.fromElements(a.z,y,h);var R=e.compressTextureCoordinates(h);t.fromElements(E,p,h);var A=e.compressTextureCoordinates(h);if(r[i++]=T,r[i++]=R,r[i++]=A,this.hasWebMercatorT){t.fromElements(m,0,h);var S=e.compressTextureCoordinates(h);r[i++]=S}}else n.subtract(a,this.center,l),r[i++]=l.x,r[i++]=l.y,r[i++]=l.z,r[i++]=f,r[i++]=E,r[i++]=p,this.hasWebMercatorT&&(r[i++]=m);return this.hasVertexNormals&&(r[i++]=e.octPackFloat(d)),i},c.prototype.decodePosition=function(t,r,i){if(a(i)||(i=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],h);i.x=o.x,i.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],h);return i.z=c.x,u.multiplyByPoint(this.fromScaledENU,i,i)}return i.x=t[r],i.y=t[r+1],i.z=t[r+2],n.add(i,this.center,i)},c.prototype.decodeTextureCoordinates=function(n,r,i){return a(i)||(i=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],i):t.fromElements(n[r+4],n[r+5],i)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var i=e[n]/256,a=Math.floor(i),o=256*(i-a);return t.fromElements(a,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var p={position3DAndHeight:0,textureCoordAndEncodedNormals:1},_={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,i=r.getSizeInBytes(n);if(this.quantization===s.NONE){var a=2;return this.hasWebMercatorT&&++a,this.hasVertexNormals&&++a,t=(4+a)*i,[{index:p.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:p.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:a,offsetInBytes:4*i,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*i,[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:_.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*i,strideInBytes:t}]):[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?p:_},c.clone=function(e,t){return a(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},s.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=s.mercatorAngleToGeodeticLatitude(e.y*i),u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},s}),define("Core/HeightmapTessellator",["./AxisAlignedBoundingBox","./BoundingSphere","./Cartesian2","./Cartesian3","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidalOccluder","./freezeObject","./Math","./Matrix4","./OrientedBoundingBox","./Rectangle","./TerrainEncoding","./Transforms","./WebMercatorProjection"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,m,E,p){"use strict";var _={};_.DEFAULT_STRUCTURE=c({heightScale:1,heightOffset:0,elementsPerHeight:1,stride:1,elementMultiplier:256,isBigEndian:!1});var y=new r,T=new f,R=new r,A=new r;return _.computeVertices=function(o){var c,S,v,g,N=Math.cos,O=Math.sin,M=Math.sqrt,I=Math.atan,w=Math.exp,C=l.PI_OVER_TWO,x=l.toRadians,P=o.heightmap,U=o.width,D=o.height,L=o.skirtHeight,F=i(o.isGeographic,!0),b=i(o.ellipsoid,u.WGS84),B=1/b.maximumRadius,z=o.nativeRectangle,q=o.rectangle;a(q)?(c=q.west,S=q.south,v=q.east,g=q.north):F?(c=x(z.west),S=x(z.south),v=x(z.east),g=x(z.north)):(c=z.west*B,S=C-2*I(w(-z.south*B)),v=z.east*B,g=C-2*I(w(-z.north*B)));var G=o.relativeToCenter,V=a(G);G=V?G:r.ZERO;var W=i(o.exaggeration,1),X=i(o.includeWebMercatorT,!1),H=i(o.structure,_.DEFAULT_STRUCTURE),Y=i(H.heightScale,_.DEFAULT_STRUCTURE.heightScale),k=i(H.heightOffset,_.DEFAULT_STRUCTURE.heightOffset),j=i(H.elementsPerHeight,_.DEFAULT_STRUCTURE.elementsPerHeight),Z=i(H.stride,_.DEFAULT_STRUCTURE.stride),K=i(H.elementMultiplier,_.DEFAULT_STRUCTURE.elementMultiplier),J=i(H.isBigEndian,_.DEFAULT_STRUCTURE.isBigEndian),Q=d.computeWidth(z),$=d.computeHeight(z),ee=Q/(U-1),te=$/(D-1);F||(Q*=B,$*=B);var ne,re,ie=b.radiiSquared,ae=ie.x,oe=ie.y,ue=ie.z,se=65536,ce=-65536,le=E.eastNorthUpToFixedFrame(G,b),fe=f.inverseTransformation(le,T);X&&(ne=p.geodeticLatitudeToMercatorAngle(S),re=1/(p.geodeticLatitudeToMercatorAngle(g)-ne));var he=R;he.x=Number.POSITIVE_INFINITY,he.y=Number.POSITIVE_INFINITY,he.z=Number.POSITIVE_INFINITY;var de=A;de.x=Number.NEGATIVE_INFINITY,de.y=Number.NEGATIVE_INFINITY,de.z=Number.NEGATIVE_INFINITY;var me=Number.POSITIVE_INFINITY,Ee=U+(L>0?2:0),pe=D+(L>0?2:0),_e=Ee*pe,ye=new Array(_e),Te=new Array(_e),Re=new Array(_e),Ae=X?new Array(_e):[],Se=0,ve=D,ge=0,Ne=U;L>0&&(--Se,++ve,--ge,++Ne);for(var Oe=0,Me=Se;Me<ve;++Me){var Ie=Me;Ie<0&&(Ie=0),Ie>=D&&(Ie=D-1);var we=z.north-te*Ie;we=F?x(we):C-2*I(w(-we*B));var Ce=N(we),xe=O(we),Pe=ue*xe,Ue=(we-S)/(g-S);Ue=l.clamp(Ue,0,1);var De;X&&(De=(p.geodeticLatitudeToMercatorAngle(we)-ne)*re);for(var Le=ge;Le<Ne;++Le){var Fe=Le;Fe<0&&(Fe=0),Fe>=U&&(Fe=U-1);var be=z.west+ee*Fe;F?be=x(be):be*=B;var Be,ze=Ie*(U*Z)+Fe*Z;if(1===j)Be=P[ze];else{Be=0;var qe;if(J)for(qe=0;qe<j;++qe)Be=Be*K+P[ze+qe];else for(qe=j-1;qe>=0;--qe)Be=Be*K+P[ze+qe]}Be=(Be*Y+k)*W;var Ge=(be-c)/(v-c);if(Ge=l.clamp(Ge,0,1),Re[Oe]=new n(Ge,Ue),ce=Math.max(ce,Be),se=Math.min(se,Be),Le!==Fe||Me!==Ie){Le<0?be-=1e-5*Q:be+=1e-5*Q,Me<0?we+=1e-5*$:we-=1e-5*$,Ce=N(we),xe=O(we),Pe=ue*xe,Be-=L}var Ve=Ce*N(be),We=Ce*O(be),Xe=ae*Ve,He=oe*We,Ye=M(Xe*Ve+He*We+Pe*xe),ke=1/Ye,je=Xe*ke,Ze=He*ke,Ke=Pe*ke,Je=new r;Je.x=je+Ve*Be,Je.y=Ze+We*Be,Je.z=Ke+xe*Be,ye[Oe]=Je,Te[Oe]=Be,X&&(Ae[Oe]=De),Oe++,f.multiplyByPoint(fe,Je,y),r.minimumByComponent(y,he,he),r.maximumByComponent(y,de,de),me=Math.min(me,Be)}}var Qe,$e=t.fromPoints(ye);a(q)&&q.width<l.PI_OVER_TWO+l.EPSILON5&&(Qe=h.fromRectangle(q,se,ce,b));var et;if(V){et=new s(b).computeHorizonCullingPoint(G,ye)}for(var tt=new e(he,de,G),nt=new m(tt,me,ce,le,!1,X),rt=new Float32Array(_e*nt.getStride()),it=0,at=0;at<_e;++at)it=nt.encode(rt,it,ye[at],Re[at],Te[at],void 0,Ae[at]);return{vertices:rt,maximumHeight:ce,minimumHeight:se,encoding:nt,boundingSphere3D:$e,orientedBoundingBox:Qe,occludeePointInScaledSpace:et}},_}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,i=t.message;n=e(r)&&e(i)?r+": "+i:t.toString();var a=t.stack;return e(a)&&(n+="\n"+a),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var i,a=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;a.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,a)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(i)||(i=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(a.length=0);try{i(o,a)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),i(o)}}}return r}),define("Workers/createVerticesFromHeightmap",["../Core/Ellipsoid","../Core/HeightmapTessellator","../Core/Rectangle","./createTaskProcessorWorker"],function(e,t,n,r){"use strict";function i(r,i){var a=r.width,o=r.height;r.skirtHeight>0&&(a+=2,o+=2),r.ellipsoid=e.clone(r.ellipsoid),r.rectangle=n.clone(r.rectangle);var u=t.computeVertices(r),s=u.vertices;return i.push(s.buffer),{vertices:s.buffer,numberOfAttributes:u.encoding.getStride(),minimumHeight:u.minimumHeight,maximumHeight:u.maximumHeight,gridWidth:a,gridHeight:o,boundingSphere3D:u.boundingSphere3D,orientedBoundingBox:u.orientedBoundingBox,occludeePointInScaledSpace:u.occludeePointInScaledSpace,encoding:u.encoding}}return r(i)})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromQuantizedTerrainMesh.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromQuantizedTerrainMesh.js index 35ff9cb9..c1a51de3 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromQuantizedTerrainMesh.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createVerticesFromQuantizedTerrainMesh.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,a){"use strict";var i={};i.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,n){return i.octDecodeInRange(e,t,255,n)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return i.octDecode(r,a,t)},i.octPack=function(e,t,n,r){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(n,o);return r.x=65536*s.x+a,r.y=65536*s.y+u,r},i.octUnpack=function(e,t,n,r){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,n),i.octDecode(o,s,r)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},i}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,_=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(_,u),l=Math.max(_,l)}var p=n.minimum;p.x=a,p.y=o,p.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(p,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,_=l*l*d*d,p=f*f*E*E,y=h*h*m*m,T=_+p+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,N=u.y,I=u.z,M=o;M.x=A.x*S*2,M.y=A.y*N*2,M.z=A.z*I*2;var O,v,g,w,C,x,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(M)),b=0;do{B-=b,g=1/(1+B*S),w=1/(1+B*N),C=1/(1+B*I),x=g*g,P=w*w,U=C*C,D=x*g,L=P*w,F=U*C,O=_*x+p*P+y*U-1,v=_*D*S+p*L*N+y*F*I;b=O/(-2*v)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*g,c.y=f*w,c.z=h*C,c):new e(l*g,f*w,h*C)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,_=r(n)?n._centerToleranceSquared:d,p=o(t,E,m,_,c);if(r(p)){var y=e.multiplyComponents(p,m,s);y=e.normalize(y,y);var T=e.subtract(t,p,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,_=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,_=e[s.getElementIndex(h,h)],p=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(_-p)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),_=2*(i+l),p=2*(a+h),y=-n+u-f+d,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=p,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=_,t[7]=T,t[8]=S,t):new s(E,m,_,p,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,_=-o,p=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=_,t[3]=f,t[4]=E,t[5]=p,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,_,p,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],_=new s,p=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={}) -;for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,_),s.transpose(_,p),s.multiply(h,_,h),s.multiply(p,h,h),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,_){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(_,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,_=t.z*t.z,p=t.z*t.w,y=t.w*t.w,T=s-d-_+y,R=2*(c-p),A=2*(f+m),S=2*(c+p),N=-s+d-_+y,I=2*(E-h),M=2*(f-m),O=2*(E+h),v=-s-d+_+y;return r[0]=T*i,r[1]=S*i,r[2]=M*i,r[3]=0,r[4]=R*o,r[5]=N*o,r[6]=O*o,r[7]=0,r[8]=A*u,r[9]=I*u,r[10]=v*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,_=f.z,p=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,N=u*-R+s*-A+c*-S,I=p*-R+y*-A+T*-S,M=E*R+m*A+_*S;return a(n)?(n[0]=u,n[1]=p,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-_,n[11]=0,n[12]=N,n[13]=I,n[14]=M,n[15]=1,n):new l(u,s,c,N,p,y,T,I,-E,-m,-_,M,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,_=o+l,p=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=_,a[14]=p,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],_=e[13],p=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],N=t[4],I=t[5],M=t[6],O=t[7],v=t[8],g=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+h*A+_*S,B=i*T+c*R+d*A+p*S,b=o*T+l*R+E*A+y*S,z=r*N+u*I+f*M+m*O,q=a*N+s*I+h*M+_*O,G=i*N+c*I+d*M+p*O,W=o*N+l*I+E*M+y*O,V=r*v+u*g+f*w+m*C,X=a*v+s*g+h*w+_*C,H=i*v+c*g+d*w+p*C,Y=o*v+l*g+E*w+y*C,k=r*x+u*P+f*U+m*D,j=a*x+s*P+h*U+_*D,Z=i*x+c*P+d*U+p*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=V,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],_=t[1],p=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],N=t[10],I=t[12],M=t[13],O=t[14],v=r*m+o*_+c*p,g=a*m+u*_+l*p,w=i*m+s*_+f*p,C=r*y+o*T+c*R,x=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*N,D=a*A+u*S+l*N,L=i*A+s*S+f*N,F=r*I+o*M+c*O+h,B=a*I+u*M+l*O+d,b=i*I+s*M+f*O+E;return n[0]=v,n[1]=g,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],_=t[4],p=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=a*h+u*d+l*E,N=i*h+s*d+f*E,I=r*m+o*_+c*p,M=a*m+u*_+l*p,O=i*m+s*_+f*p,v=r*y+o*T+c*R,g=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=N,n[3]=0,n[4]=I,n[5]=M,n[6]=O,n[7]=0,n[8]=v,n[9]=g,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var _=new e;l.multiplyByUniformScale=function(e,t,n){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var p=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,p),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],_=e[6],A=e[10],S=e[14],N=e[3],I=e[7],M=e[11],O=e[15],v=A*O,g=S*M,w=_*O,C=S*I,x=_*M,P=A*I,U=m*O,D=S*N,L=m*M,F=A*N,B=m*I,b=_*N,z=v*h+C*d+x*E-(g*h+w*d+P*E),q=g*f+U*d+F*E-(v*f+D*d+L*E),G=w*f+D*h+B*E-(C*f+U*h+b*E),W=P*f+L*h+b*d-(x*f+F*h+B*d),V=g*a+w*i+P*o-(v*a+C*i+x*o),X=v*r+D*i+L*o-(g*r+U*i+F*o),H=C*r+U*a+b*o-(w*r+D*a+B*o),Y=x*r+F*a+B*i-(P*r+L*a+b*i);v=i*E,g=o*d,w=a*E,C=o*h,x=a*d,P=i*h,U=r*E,D=o*f,L=r*d,F=i*f,B=r*h,b=a*f;var k=v*I+C*M+x*O-(g*I+w*M+P*O),j=g*N+U*M+F*O-(v*N+D*M+L*O),Z=w*N+D*I+B*O-(C*N+U*I+b*O),K=P*N+L*I+b*M-(x*N+F*I+B*M),J=w*A+P*S+g*_-(x*S+v*_+C*A),Q=L*S+v*m+D*A-(U*A+F*S+g*m),$=U*_+b*S+C*m-(B*S+w*m+D*_),ee=B*A+x*m+F*_-(L*_+b*A+P*m),te=r*z+a*q+i*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=V*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,_=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var _=t.cartesianToCartographic(e[E]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),h=Math.min(h,_.latitude),d=Math.max(d,_.latitude);var p=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,p),f=Math.max(f,p)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var _=1;_<8;++_)m.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,E=new e,m=new e,_=new e,p=new e,y=new e,T=new e,R=new e,A=new e,S=new e,N=new e,I=new e;h.fromPoints=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,d),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,_),l=e.clone(i,p),f=e.clone(i,y),M=t.length;for(r=1;r<M;r++){e.clone(t[r],i);var O=i.x,v=i.y,g=i.z;O<o.x&&e.clone(i,o),O>c.x&&e.clone(i,c),v<u.y&&e.clone(i,u),v>l.y&&e.clone(i,l),g<s.z&&e.clone(i,s),g>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,I),G=0;for(r=0;r<M;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var V=e.magnitudeSquared(e.subtract(i,L,R));if(V>F){var X=Math.sqrt(V);B=.5*(B+X),F=B*B;var H=X-B;L.x=(B*L.x+H*i.x)/X,L.y=(B*L.y+H*i.y)/X,L.z=(B*L.z+H*i.z)/X}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var M=new o,O=new e,v=new e,g=new t,w=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,M),f.southwest(t,g),g.height=i,f.northeast(t,w),w.height=o;var s=n.project(g,O),c=n.project(w,v),l=c.x-s.x,d=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*E,u};var C=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,C);return h.fromPoints(s,u)},h.fromVertices=function(t,n,i,o){if(a(o)||(o=new h),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,E),f=e.clone(u,m),M=e.clone(u,_),O=e.clone(u,p),v=e.clone(u,y),g=t.length;for(s=0;s<g;s+=i){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>M.x&&e.clone(u,M),C<l.y&&e.clone(u,l),C>O.y&&e.clone(u,O),x<f.z&&e.clone(u,f),x>v.z&&e.clone(u,v)}var P=e.magnitudeSquared(e.subtract(M,c,R)),U=e.magnitudeSquared(e.subtract(O,l,R)),D=e.magnitudeSquared(e.subtract(v,f,R)),L=c,F=M,B=P;U>B&&(B=U,L=l,F=O),D>B&&(B=D,L=f,F=v);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=N;W.x=M.x,W.y=O.y,W.z=v.z;var V=e.multiplyByScalar(e.add(G,W,R),.5,I),X=0;for(s=0;s<g;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,V,R));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;b.x=(q*b.x+j*u.x)/k,b.y=(q*b.y+j*u.y)/k,b.z=(q*b.z+j*u.z)/k}}return q<X?(e.clone(b,o.center),o.radius=q):(e.clone(V,o.center),o.radius=X),o},h.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new h),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,d),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,_),f=e.clone(i,p),M=e.clone(i,y),O=t.length;for(o=0;o<O;o+=3){var v=t[o]+n[o],g=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=v,i.y=g,i.z=w,v<u.x&&e.clone(i,u),v>l.x&&e.clone(i,l),g<s.y&&e.clone(i,s),g>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>M.z&&e.clone(i,M)}var C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(M,c,R)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=M);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=N;q.x=l.x,q.y=f.y,q.z=M.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,I),W=0;for(o=0;o<O;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var V=e.magnitude(e.subtract(i,G,R));V>W&&(W=V);var X=e.magnitudeSquared(e.subtract(i,F,R));if(X>B){var H=Math.sqrt(X);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},h.fromCornerPoints=function(t,n,r){a(r)||(r=new h);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},h.fromEllipsoid=function(t,n){return a(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var x=new e;h.fromBoundingSpheres=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,x)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;h.fromOrientedBoundingBox=function(t,n){ -a(n)||(n=new h);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},h.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new h);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;h.union=function(t,n,r){a(r)||(r=new h);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(d,i,d),e.clone(d,r.center),r.radius=f,r};var B=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,W=new e,V=new e,X=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var j=new o;return h.projectTo2D=function(t,n,a){n=r(n,j);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,X),d=e.negate(c,V),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,d,m),m=E[2],e.add(s,f,m),e.add(m,d,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,d,m),m=E[6],e.add(s,f,m),e.add(m,d,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var _=E.length,p=0;p<_;++p){var y=E[p];e.add(o,y,y);var T=i.cartesianToCartographic(y,H);n.project(T,y)}a=h.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,_=u*c-d,p=4*E*_-m*m;if(p<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=_,R=-c*m+2*s*_);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-p);i=-R+S;var N=i/2,I=N<0?-Math.pow(-N,1/3):Math.pow(N,1/3),M=i===S?-I:-T/I;return a=T<=0?I+M:-R/(I*I+M*M+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var O=E,v=-2*u*E+o*m,g=_,w=-c*m+2*s*_,C=Math.sqrt(p),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-v)/3);a=2*Math.sqrt(-O);var U=Math.cos(P);i=a*U;var D=a*(-U/2-x*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),a=2*Math.sqrt(-g),U=Math.cos(P),i=a*U,D=a*(-U/2-x*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,V=L*b,X=(s*W-u*V)/(-u*W+s*G);return B<=X?B<=q?X<=q?[B,X,q]:[B,q,X]:[q,B,X]:B<=q?[X,B,q]:X<=q?[X,q,B]:[q,X,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,_=E[0],p=E[1];if(_>=0&&p>=0){var y=Math.sqrt(_),T=Math.sqrt(p);return[h-T,h-y,h+y,h+T]}if(_>=0&&p<0)return m=Math.sqrt(_),[h-m,h+m];if(_<0&&p>=0)return m=Math.sqrt(p),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,N=r.computeRealRoots(1,R,A),I=r.computeRealRoots(1,-R,S);return 0!==N.length?(N[0]+=h,N[1]+=h,0!==I.length?(I[0]+=h,I[1]+=h,N[1]<=I[0]?[N[0],N[1],I[0],I[1]]:I[1]<=N[0]?[I[0],I[1],N[0],N[1]]:N[0]>=I[0]&&N[1]<=I[1]?[I[0],N[0],N[1],I[1]]:I[0]>=N[0]&&I[1]<=N[1]?[N[0],I[0],I[1],N[1]]:N[0]>I[0]&&N[0]<I[1]?[I[0],N[0],I[1],N[1]]:[N[0],I[0],N[1],I[1]]):N):0!==I.length?(I[0]+=h,I[1]+=h,I):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,_=d[0],p=a-_,y=p*p,T=t/2,R=p/2,A=y-4*o,S=y+4*Math.abs(o),N=c-4*_,I=c+4*Math.abs(_);if(_<0||A*I<N*S){var M=Math.sqrt(N);E=M/2,m=0===M?0:(t*R-i)/M}else{var O=Math.sqrt(A);E=0===O?0:(t*R-i)/O,m=O/2}var v,g;0===T&&0===E?(v=0,g=0):n.sign(T)===n.sign(E)?(v=T+E,g=_/v):(g=T-E,v=_/g);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,v,w),P=r.computeRealRoots(1,g,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),_=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,p=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===p){if(l=s.computeRealRoots(E,m,_),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],N=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-N)),T.push(new e(a,i*S,i*N))}return T}var I=y*y,M=p*p,O=E*E,v=y*p,g=O+M,w=2*(m*E+v),C=2*_*E+m*m-M+I,x=2*(_*m-v),P=_*_-I;if(0===g&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(g,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(_)?d(E*B+_,m*F,o.EPSILON12):o.sign(_)===o.sign(m*F)?d(E*B,m*F+_,o.EPSILON12):d(E*B+m*F,_,o.EPSILON12);var q=d(p*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,p=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,_),A=e.subtract(i,r,p),S=e.cross(E,A,y),N=e.dot(m,S);if(u){if(N<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>N)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>N)return;h=e.dot(A,c)/N}else{if(Math.abs(N)<o.EPSILON6)return;var I=1/N;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*I)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*I)<0||l+f>1)return;h=e.dot(A,c)*I}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var N=new l;m.lineSegmentSphere=function(t,n,a,i){var o=N;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var I=new e,M=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,I),f=e.multiplyComponents(c,t.direction,M),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,_=r/s;return m<_?new i(m,_):{start:_,stop:m}}var p=Math.sqrt(r/a);return new i(p,p)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var O=new e,v=new e,g=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,v),v),m=e.normalize(e.cross(f,d,g),g),_=x;_[0]=f.x,_[1]=f.y,_[2]=f.z,_[3]=d.x,_[4]=d.y,_[5]=d.z,_[6]=m.x,_[7]=m.y,_[8]=m.z;var p=u.transpose(_,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,N=u.multiply(u.multiply(p,T,F),R,F),I=u.multiply(u.multiply(N,y,B),_,B),M=u.multiplyByVector(N,a,C),G=E(I,e.negate(M,O),0,0,1),W=G.length;if(W>0){for(var V=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<W;++H){A=u.multiplyByVector(y,u.multiplyByVector(_,G[H],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>X&&(X=k,V=e.clone(A,V))}var j=n.cartesianToCartographic(V,q);return X=o.clamp(X,0,1),S=e.magnitude(e.subtract(V,a,w))*Math.sqrt(1-X*X),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=p,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return _(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,_,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(_=d.progress,m=function(e){h.push(e),--l||(E=m=p,d.reject(h))},E=function(e){f.push(e),--c||(E=m=p,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,_);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return _(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){ -e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function _(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function p(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,_,p;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",N=s.length,I=0;s&&I<N;I++)switch(s.charAt(I)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(I+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,p=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(p),y,c,f,R,S);case"c":return u(String.fromCharCode(+p),y,c,f,R);case"b":return o(p,2,A,y,c,f,R);case"o":return o(p,8,A,y,c,f,R);case"x":return o(p,16,A,y,c,f,R);case"X":return o(p,16,A,y,c,f,R).toUpperCase();case"u":return o(p,10,A,y,c,f,R);case"i":case"d":return d=+p||0,d=Math.round(d-d%1),E=d<0?"-":T,p=E+a(String(Math.abs(d)),f,"0",!1),i(p,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+p,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],_=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],p=E+Math.abs(d)[m](f),i(p,E,y,c,R)[_]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var _=new i,p=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,N=/^(\d{4})-?(\d{2})-?(\d{2})$/,I=/([Z+\-])?(\d{2})?:?(\d{2})?$/,M=/^(\d{2})(\.\d+)?/.source+I.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+I.source,v=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+I.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,_=0,y=0,I=0,g=u[0],w=u[1];if(null!==(u=g.match(N)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=g.match(R)))n=+u[1],s=+u[2];else if(null!==(u=g.match(T)))n=+u[1];else{var C;if(null!==(u=g.match(A)))n=+u[1],C=+u[2],i=o(n);else if(null!==(u=g.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(C),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(v),null!==u?(h=+u[1],_=+u[2],y=+u[3],I=1e3*+(u[4]||0),D=5):(u=w.match(O),null!==u?(h=+u[1],_=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(M))&&(h=+u[1],_=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,_-=B;break;case"-":h+=F,_+=B;break;case"Z":break;default:_+=new Date(Date.UTC(n,s-1,l,h,_)).getTimezoneOffset()}}var b=60===y;for(b&&y--;_>=60;)_-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:p[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:p[s-1];for(;_<0;)_+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:p[s-1],l+=a;var z=E(n,s,l,h,_,y,I);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var g=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,g);r(a)||(m.addSeconds(e,-1,g),a=h(g,g),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var _=d+2-12*c|0,p=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=p,t.month=_,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(p,_,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,_),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,_);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return I[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--I[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--I[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function _(e){var t=d(e);return e.state=s.ACTIVE,N.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++I[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function p(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--I[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A);var N=[],I={},M="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();p(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=N.length;for(e=0;e<r;++e)t=N[e],t.cancelled&&p(t),t.state===s.ACTIVE?n>0&&(N[e-n]=t):++n;N.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-N.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?p(t):!t.throttleByServer||h(t.serverKey)?(_(t),++u):p(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(M);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=I[a];return r(i)||(I[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return _(e);if(!(N.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;p(t)}return d(e)}},l.clearForSpecs=function(){for(;S.length>0;){p(S.pop())}for(var e=N.length,t=0;t<e;++t)p(N[t]);N.length=0,I={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return I[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;a=n(a,t.url);var d=r(t.request)?t.request:new i;return d.url=a,d.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function d(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return h(a,i);case"blob":var o=h(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&h.setRequestHeader(m,i[m]);r(t)&&(h.responseType=t);var _=!1;return"string"==typeof e&&(_=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!_||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(a),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var _=e._samples=n.samples,p=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=_.length;R<A;R+=e._columnCount){var S=_[R+a],N=_[R+m],I=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,M=new o(I,N,f.TAI);if(p.push(M),T){if(N!==y&&r(y)){var O=o.leapSeconds,v=t(O,M,d);if(v<0){var g=new u(M,N);O.splice(~v,0,g)}}y=N}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function _(e,t,n){return t+e*(n-t)}function p(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],p=n[d+e._ut1MinusUtcSecondsColumn],y=p-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=p:p-=R-T)}return u.xPoleWander=_(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=_(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=_(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=_(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=_(f,E,p),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,p(this,i,this._samples,e,s,l,n),n}var _=t(i,e,o.compare,this._dateColumn);return _>=0?(_<i.length-1&&i[_+1].equals(e)&&++_,s=_,l=_):(l=~_,(s=l-1)<0&&(s=0)),this._lastIndex=s,p(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){ -"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,_=i-s*this._stepSizeDays,p=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)p[E]=_-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=p[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(N)&&(N=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(N=!0,I=r(e[1]))}return N}function u(){return o()&&I}function s(){if(!t(M)){M=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(M=!0,O=r(e[1]),O.isNightly=!!e[2])}return M}function c(){return s()&&O}function l(){if(!t(v)){v=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(v=!0,g=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(v=!0,g=r(e[1]))}return v}function f(){return l()&&g}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function _(){return E()&&P}function p(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,N,I,M,O,v,g,w,C,x,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:_,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:p,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var _=l,p=0;d>h&&(p=1),E>h&&E>d&&(p=2);var y=_[p],T=_[y];n=Math.sqrt(e[u.getElementIndex(p,p)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[p]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,p)]+e[u.getElementIndex(p,y)])*n,R[T]=(e[u.getElementIndex(T,p)]+e[u.getElementIndex(p,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var _=new e,p=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,_);var u=s.computeAngle(y);r[o]=_.x*u,r[o+1]=_.y*u,r[o+2]=_.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,p);var u=e.magnitude(p);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(p,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,N=new s,I=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return N=s.multiplyByScalar(e,Math.sin((1-n)*u),N),I=s.multiplyByScalar(i,Math.sin(n*u),I),r=s.add(N,I,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var M=new e,O=new e,v=new s,g=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,v);s.multiply(i,r,g);var o=s.log(g,M);s.multiply(i,t,g);var u=s.log(g,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,v),s.multiply(n,v,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,v),u=s.slerp(n,r,a,g);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,C=1.9011074535173003,x=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;x[L]=1/(F*B),P[L]=F/B}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,v),u=s.fastSlerp(n,r,a,g);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,_,p,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},N={},I={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},M=new n,O=new n,v=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(N[i])?r=N[i]:(r=function(r,i,s){if(u(s)||(s=new p),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,M),"east"!==e&&"west"!==e&&n.multiplyByScalar(M,c,M),n.unpack(S[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(S[a],0,v),"east"!==a&&"west"!==a&&n.multiplyByScalar(v,c,v)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,I.up);var l=I.up,h=I.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,I.east),n.cross(l,h,I.north),n.multiplyByScalar(I.up,-1,I.down),n.multiplyByScalar(I.east,-1,I.west),n.multiplyByScalar(I.north,-1,I.south),M=I[e],O=I[t],v=I[a]}return s[0]=M.x,s[1]=M.y,s[2]=M.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=v.x,s[9]=v.y,s[10]=v.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},N[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var g=new y,w=new n(1,1,1),C=new p;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,g),s=p.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return i=a(e,r,i),p.multiply(i,s,i)};var x=new p,P=new _;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=p.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new _(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new _);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return _.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new _,b=new _;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new _);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=_.fromRotationZ(-i.s,b),h=_.multiply(l,f,B),d=e.dayNumber,p=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=p/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var N=_.fromRotationZ(S,b),I=_.multiply(h,N,B),M=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),v=Math.sin(n.xPoleWander),g=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=b;return U[0]=M*x,U[1]=M*P,U[2]=v,U[3]=-O*P+g*v*x,U[4]=O*x+g*v*P,U[5]=-g*M,U[6]=-g*P-O*v*x,U[7]=g*x-O*v*P,U[8]=O*M,_.multiply(I,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return p.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),p.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new _),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var V=new p(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new _,j=new p,Z=new p;return R.basisTo2D=function(e,t,r){var a=p.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=p.inverseTransformation(s,Z),l=p.getRotation(t,k),f=p.multiplyByMatrix3(c,l,r);return p.multiply(V,f,r),p.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=p.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=p.fromTranslation(s,j);return p.multiply(V,o,r),p.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var _=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,_).center,n)};var p=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=p;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=p;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E){"use strict";function m(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=h.clone(a(t,h.ZERO))}function _(e,t,r,a,o,u,s,c){i(c)||(c=new m);var l=c.halfAxes;h.setColumn(l,0,e.xAxis,l),h.setColumn(l,1,e.yAxis,l),h.setColumn(l,2,e.zAxis,l);var f=M;f.x=(t+r)/2,f.y=(a+o)/2,f.z=(u+s)/2;var d=O;d.x=(r-t)/2,d.y=(o-a)/2,d.z=(s-u)/2;var E=c.center;return f=h.multiplyByVector(l,f,f),n.add(e.origin,f,E),h.multiplyByScale(l,d,l),c}var p=new n,y=new n,T=new n,R=new n,A=new n,S=new n,N=new h,I={unitary:new h,diagonal:new h};m.fromPoints=function(e,t){if(i(t)||(t=new m),!i(e)||0===e.length)return t.halfAxes=h.ZERO,t.center=n.ZERO,t;var r,a=e.length,o=n.clone(e[0],p);for(r=1;r<a;r++)n.add(o,e[r],o);var u=1/a;n.multiplyByScalar(o,u,o);var s,c=0,l=0,f=0,d=0,E=0,_=0;for(r=0;r<a;r++)s=n.subtract(e[r],o,y),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,d+=s.y*s.y,E+=s.y*s.z,_+=s.z*s.z;c*=u,l*=u,f*=u,d*=u,E*=u,_*=u;var M=N;M[0]=c,M[1]=l,M[2]=f,M[3]=l,M[4]=d,M[5]=E,M[6]=f,M[7]=E,M[8]=_;var O=h.computeEigenDecomposition(M,I),v=h.clone(O.unitary,t.halfAxes),g=h.getColumn(v,0,R),w=h.getColumn(v,1,A),C=h.getColumn(v,2,S),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<a;r++)s=e[r],x=Math.max(n.dot(g,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(g,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);g=n.multiplyByScalar(g,.5*(D+x),g),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var B=n.add(g,w,t.center);n.add(B,C,B);var b=T;return b.x=x-D,b.y=P-L,b.z=U-F,n.multiplyByScalar(b,.5,b),h.multiplyByScale(t.halfAxes,b,t.halfAxes),t};var M=new n,O=new n,v=new r,g=new n,w=[new r,new r,new r,new r,new r,new r,new r,new r],C=[new n,new n,new n,new n,new n,new n,new n,new n],x=[new t,new t,new t,new t,new t,new t,new t,new t];m.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,u.WGS84);var o=E.center(e,v),c=r.cartographicToCartesian(o,g),l=new s(c,r),f=l.plane,h=w[0],m=w[1],p=w[2],y=w[3],T=w[4],R=w[5],A=w[6],S=w[7],N=o.longitude,I=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=I,h.latitude=m.latitude=p.latitude=e.north,A.longitude=S.longitude=h.longitude=e.west,R.longitude=m.longitude=N,T.longitude=y.longitude=p.longitude=e.east,p.height=m.height=h.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(w,C),l.projectPointsToNearestOnPlane(C,x);var M=Math.min(x[6].x,x[7].x,x[0].x),O=Math.max(x[2].x,x[3].x,x[4].x),P=Math.min(x[4].y,x[5].y,x[6].y),U=Math.max(x[0].y,x[1].y,x[2].y);return p.height=h.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(w,C),_(l,M,O,P,U,Math.min(d.getPointDistance(f,C[0]),d.getPointDistance(f,C[2]),d.getPointDistance(f,C[4]),d.getPointDistance(f,C[6])),n,i)},m.clone=function(e,t){if(i(e))return i(t)?(n.clone(e.center,t.center),h.clone(e.halfAxes,t.halfAxes),t):new m(e.center,e.halfAxes)},m.intersectPlane=function(e,t){var r=e.center,a=t.normal,i=e.halfAxes,o=a.x,u=a.y,s=a.z,l=Math.abs(o*i[h.COLUMN0ROW0]+u*i[h.COLUMN0ROW1]+s*i[h.COLUMN0ROW2])+Math.abs(o*i[h.COLUMN1ROW0]+u*i[h.COLUMN1ROW1]+s*i[h.COLUMN1ROW2])+Math.abs(o*i[h.COLUMN2ROW0]+u*i[h.COLUMN2ROW1]+s*i[h.COLUMN2ROW2]),f=n.dot(a,r)+t.distance;return f<=-l?c.OUTSIDE:f>=l?c.INSIDE:c.INTERSECTING};var P=new n,U=new n,D=new n,L=new n;m.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,M),a=e.halfAxes,i=h.getColumn(a,0,P),o=h.getColumn(a,1,U),u=h.getColumn(a,2,D),s=n.magnitude(i),c=n.magnitude(o),l=n.magnitude(u);n.normalize(i,i),n.normalize(o,o),n.normalize(u,u);var f=L;f.x=n.dot(r,i),f.y=n.dot(r,o),f.z=n.dot(r,u);var d,E=0;return f.x<-s?(d=f.x+s,E+=d*d):f.x>s&&(d=f.x-s,E+=d*d),f.y<-c?(d=f.y+c,E+=d*d):f.y>c&&(d=f.y-c,E+=d*d),f.z<-l?(d=f.z+l,E+=d*d):f.z>l&&(d=f.z-l,E+=d*d),E};var F=new n,B=new n;m.computePlaneDistances=function(e,t,r,a){i(a)||(a=new l);var o=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,f=h.getColumn(c,0,P),d=h.getColumn(c,1,U),E=h.getColumn(c,2,D),m=n.add(f,d,F);n.add(m,E,m),n.add(m,s,m);var _=n.subtract(m,t,B),p=n.dot(r,_);return o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.add(m,d,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.subtract(m,d,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.add(s,f,m),n.subtract(m,d,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.add(m,d,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.add(m,d,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.subtract(m,d,m),n.add(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),n.subtract(s,f,m),n.subtract(m,d,m),n.subtract(m,E,m),n.subtract(m,t,_),p=n.dot(r,_),o=Math.min(p,o),u=Math.max(p,u),a.start=o,a.stop=u,a};var b=new e;return m.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,b);return!n.isBoundingSphereVisible(r)},m.prototype.intersectPlane=function(e){return m.intersectPlane(this,e)},m.prototype.distanceSquaredTo=function(e){return m.distanceSquaredTo(this,e)},m.prototype.computePlaneDistances=function(e,t,n){return m.computePlaneDistances(this,e,t,n)},m.prototype.isOccluded=function(e){return m.isOccluded(this,e)},m.equals=function(e,t){return e===t||i(e)&&i(t)&&n.equals(e.center,t.center)&&h.equals(e.halfAxes,t.halfAxes)},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t,r,o,c,h){var _,p,y,T;if(i(e)&&i(t)&&i(r)&&i(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),N=r-t;_=Math.max(n.maximumComponent(S),N)<m-1?s.BITS12:s.NONE,p=e.center,y=u.inverseTransformation(o,new u);var I=n.negate(R,l);u.multiply(u.fromTranslation(I,d),y,y);var M=l;M.x=1/S.x,M.y=1/S.y,M.z=1/S.z,u.multiply(u.fromScale(M,d),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var O=u.fromTranslation(R,d),v=u.fromScale(S,E),g=u.multiply(O,v,d);u.multiply(o,g,o),u.multiply(T,g,T)}this.quantization=_,this.minimumHeight=t,this.maximumHeight=r,this.center=p,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=a(h,!1)}var l=new n,f=new n,h=new t,d=new u,E=new u,m=Math.pow(2,12);c.prototype.encode=function(r,a,i,c,f,d,E){var m=c.x,_=c.y;if(this.quantization===s.BITS12){i=u.multiplyByPoint(this.toScaledENU,i,l),i.x=o.clamp(i.x,0,1),i.y=o.clamp(i.y,0,1),i.z=o.clamp(i.z,0,1);var p=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/p,0,1);t.fromElements(i.x,i.y,h);var T=e.compressTextureCoordinates(h);t.fromElements(i.z,y,h);var R=e.compressTextureCoordinates(h);t.fromElements(m,_,h);var A=e.compressTextureCoordinates(h);if(r[a++]=T,r[a++]=R,r[a++]=A,this.hasWebMercatorT){t.fromElements(E,0,h);var S=e.compressTextureCoordinates(h);r[a++]=S}}else n.subtract(i,this.center,l),r[a++]=l.x,r[a++]=l.y,r[a++]=l.z,r[a++]=f,r[a++]=m,r[a++]=_,this.hasWebMercatorT&&(r[a++]=E);return this.hasVertexNormals&&(r[a++]=e.octPackFloat(d)),a},c.prototype.decodePosition=function(t,r,a){if(i(a)||(a=new n), -r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],h);a.x=o.x,a.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],h);return a.z=c.x,u.multiplyByPoint(this.fromScaledENU,a,a)}return a.x=t[r],a.y=t[r+1],a.z=t[r+2],n.add(a,this.center,a)},c.prototype.decodeTextureCoordinates=function(n,r,a){return i(a)||(a=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],a):t.fromElements(n[r+4],n[r+5],a)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var a=e[n]/256,i=Math.floor(a),o=256*(a-i);return t.fromElements(i,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var _={position3DAndHeight:0,textureCoordAndEncodedNormals:1},p={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,a=r.getSizeInBytes(n);if(this.quantization===s.NONE){var i=2;return this.hasWebMercatorT&&++i,this.hasVertexNormals&&++i,t=(4+i)*a,[{index:_.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:_.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:i,offsetInBytes:4*a,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*a,[{index:p.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:p.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*a,strideInBytes:t}]):[{index:p.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?_:p},c.clone=function(e,t){return i(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},s.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},s}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,a=t.message;n=e(r)&&e(a)?r+": "+a:t.toString();var i=t.stack;return e(i)&&(n+="\n"+i),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return r}),define("Workers/createVerticesFromQuantizedTerrainMesh",["../Core/AttributeCompression","../Core/AxisAlignedBoundingBox","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defined","../Core/Ellipsoid","../Core/IndexDatatype","../Core/Math","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/TerrainEncoding","../Core/Transforms","../Core/WebMercatorProjection","./createTaskProcessorWorker"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m){"use strict";function _(i,m){var _,g,w=i.quantizedVertices,C=w.length/3,x=i.octEncodedNormals,P=i.westIndices.length+i.eastIndices.length+i.southIndices.length+i.northIndices.length,U=i.includeWebMercatorT,D=i.rectangle,L=D.west,F=D.south,B=D.east,b=D.north,z=u.clone(i.ellipsoid),q=i.exaggeration,G=i.minimumHeight*q,W=i.maximumHeight*q,V=i.relativeToCenter,X=d.eastNorthUpToFixedFrame(V,z),H=l.inverseTransformation(X,new l);U&&(_=E.geodeticLatitudeToMercatorAngle(F),g=1/(E.geodeticLatitudeToMercatorAngle(b)-_));var Y=w.subarray(0,C),k=w.subarray(C,2*C),j=w.subarray(2*C,3*C),Z=o(x),K=new Array(C),J=new Array(C),Q=new Array(C),$=U?new Array(C):[],ee=A;ee.x=Number.POSITIVE_INFINITY,ee.y=Number.POSITIVE_INFINITY,ee.z=Number.POSITIVE_INFINITY;var te=S;te.x=Number.NEGATIVE_INFINITY,te.y=Number.NEGATIVE_INFINITY,te.z=Number.NEGATIVE_INFINITY;for(var ne=Number.POSITIVE_INFINITY,re=Number.NEGATIVE_INFINITY,ae=Number.POSITIVE_INFINITY,ie=Number.NEGATIVE_INFINITY,oe=0;oe<C;++oe){var ue=Y[oe]/T,se=k[oe]/T,ce=c.lerp(G,W,j[oe]/T);N.longitude=c.lerp(L,B,ue),N.latitude=c.lerp(F,b,se),N.height=ce,ne=Math.min(N.longitude,ne),re=Math.max(N.longitude,re),ae=Math.min(N.latitude,ae),ie=Math.max(N.latitude,ie);var le=z.cartographicToCartesian(N);K[oe]=new r(ue,se),J[oe]=ce,Q[oe]=le,U&&($[oe]=(E.geodeticLatitudeToMercatorAngle(N.latitude)-_)*g),l.multiplyByPoint(H,le,R),a.minimumByComponent(R,ee,ee),a.maximumByComponent(R,te,te)}var fe,he;1!==q&&(he=n.fromPoints(Q),fe=f.fromRectangle(D,G,W,z));var de=G;de=Math.min(de,p(i.westIndices,i.westSkirtHeight,J,K,D,z,H,ee,te)),de=Math.min(de,p(i.southIndices,i.southSkirtHeight,J,K,D,z,H,ee,te)),de=Math.min(de,p(i.eastIndices,i.eastSkirtHeight,J,K,D,z,H,ee,te)),de=Math.min(de,p(i.northIndices,i.northSkirtHeight,J,K,D,z,H,ee,te));for(var Ee=new t(ee,te,V),me=new h(Ee,de,W,X,Z,U),_e=me.getStride(),pe=C*_e+P*_e,ye=new Float32Array(pe),Te=0,Re=0;Re<C;++Re){if(Z){var Ae=2*Re;if(I.x=x[Ae],I.y=x[Ae+1],1!==q){var Se=e.octDecode(I.x,I.y,M),Ne=d.eastNorthUpToFixedFrame(Q[Re],z,v),Ie=l.inverseTransformation(Ne,O);l.multiplyByPointAsVector(Ie,Se,Se),Se.z*=q,a.normalize(Se,Se),l.multiplyByPointAsVector(Ne,Se,Se),a.normalize(Se,Se),e.octEncode(Se,I)}}Te=me.encode(ye,Te,Q[Re],K[Re],J[Re],I,$[Re])}var Me=Math.max(0,2*(P-4)),Oe=i.indices.length+3*Me,ve=s.createTypedArray(C+P,Oe);ve.set(i.indices,0);var ge=1e-4*(re-ne),we=1e-4*(ie-ae),Ce=-ge,xe=ge,Pe=we,Ue=-we,De=C*_e,Le=i.indices.length;return Le=y(ye,De,ve,Le,i.westIndices,me,J,K,x,z,D,i.westSkirtHeight,!0,q,_,g,Ce,0),De+=i.westIndices.length*_e,Le=y(ye,De,ve,Le,i.southIndices,me,J,K,x,z,D,i.southSkirtHeight,!1,q,_,g,0,Ue),De+=i.southIndices.length*_e,Le=y(ye,De,ve,Le,i.eastIndices,me,J,K,x,z,D,i.eastSkirtHeight,!1,q,_,g,xe,0),De+=i.eastIndices.length*_e,y(ye,De,ve,Le,i.northIndices,me,J,K,x,z,D,i.northSkirtHeight,!0,q,_,g,0,Pe),m.push(ye.buffer,ve.buffer),{vertices:ye.buffer,indices:ve.buffer,vertexStride:_e,center:V,minimumHeight:G,maximumHeight:W,boundingSphere:he,orientedBoundingBox:fe,encoding:me,skirtIndex:i.indices.length}}function p(e,t,n,r,i,o,u,s,f){var h=Number.POSITIVE_INFINITY,d=i.north,E=i.south,m=i.east,_=i.west;m<_&&(m+=c.TWO_PI);for(var p=e.length,y=0;y<p;++y){var T=e[y],A=n[T],S=r[T];N.longitude=c.lerp(_,m,S.x),N.latitude=c.lerp(E,d,S.y),N.height=A-t;var I=o.cartographicToCartesian(N,R);l.multiplyByPoint(u,I,I),a.minimumByComponent(I,s,s),a.maximumByComponent(I,f,f),h=Math.min(h,N.height)}return h}function y(t,n,r,i,u,s,f,h,m,_,p,y,T,A,S,g,w,C){var x,P,U;T?(x=u.length-1,P=-1,U=-1):(x=0,P=u.length,U=1);var D=-1,L=o(m),F=s.getStride(),B=n/F,b=p.north,z=p.south,q=p.east,G=p.west;q<G&&(q+=c.TWO_PI);for(var W=x;W!==P;W+=U){var V=u[W],X=f[V],H=h[V];N.longitude=c.lerp(G,q,H.x)+w,N.latitude=c.lerp(z,b,H.y)+C,N.height=X-y;var Y=_.cartographicToCartesian(N,R);if(L){var k=2*V;if(I.x=m[k],I.y=m[k+1],1!==A){var j=e.octDecode(I.x,I.y,M),Z=d.eastNorthUpToFixedFrame(R,_,v),K=l.inverseTransformation(Z,O);l.multiplyByPointAsVector(K,j,j),j.z*=A,a.normalize(j,j),l.multiplyByPointAsVector(Z,j,j),a.normalize(j,j),e.octEncode(j,I)}}var J;s.hasWebMercatorT&&(J=(E.geodeticLatitudeToMercatorAngle(N.latitude)-S)*g),n=s.encode(t,n,Y,H,N.height,I,J),-1!==D&&(r[i++]=D,r[i++]=B-1,r[i++]=V,r[i++]=B-1,r[i++]=B,r[i++]=V),D=V,++B}return i}var T=32767,R=new a,A=new a,S=new a,N=new i,I=new r,M=new a,O=new l,v=new l;return m(_)})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,n,r,a,i){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,a=n.y;n.x=(1-Math.abs(a))*i.signNotZero(r),n.y=(1-Math.abs(r))*i.signNotZero(a)}return n.x=i.toSNorm(n.x,t),n.y=i.toSNorm(n.y,t),n},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,n,r,a){if(a.x=i.fromSNorm(e,r),a.y=i.fromSNorm(n,r),a.z=1-(Math.abs(a.x)+Math.abs(a.y)),a.z<0){var o=a.x;a.x=(1-Math.abs(a.y))*i.signNotZero(o),a.y=(1-Math.abs(o))*i.signNotZero(a.y)}return t.normalize(a,a)},u.octDecode=function(e,t,n){return u.octDecodeInRange(e,t,255,n)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return u.octDecode(r,a,t)},u.octPack=function(e,t,n,r){var a=u.octEncodeFloat(e),i=u.octEncodeFloat(t),o=u.octEncode(n,s);return r.x=65536*o.x+a,r.y=65536*o.y+i,r},u.octUnpack=function(e,t,n,r){var a=e.x/65536,i=Math.floor(a),o=65536*(a-i);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,n),u.octDecode(i,s,r)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},u.zigZagDeltaDecode=function(e,t,n){for(var a=e.length,i=0,u=0,s=0,c=0;c<a;++c)i+=o(e[c]),u+=o(t[c]),e[c]=i,t[c]=u,r(n)&&(s+=o(n[c]),n[c]=s)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=a,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,p=l*l*d*d,_=f*f*E*E,y=h*h*m*m,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,N=u.y,v=u.z,I=o;I.x=A.x*S*2,I.y=A.y*N*2,I.z=A.z*v*2;var O,M,g,w,C,x,P,U,D,L,F,b=(1-R)*e.magnitude(n)/(.5*e.magnitude(I)),B=0;do{b-=B,g=1/(1+b*S),w=1/(1+b*N),C=1/(1+b*v),x=g*g,P=w*w,U=C*C,D=x*g,L=P*w,F=U*C,O=p*x+_*P+y*U-1,M=p*D*S+_*L*N+y*F*v;B=O/(-2*M)}while(Math.abs(O)>r.EPSILON12);return t(c)?(c.x=l*g,c.y=f*w,c.z=h*C,c):new e(l*g,f*w,h*C)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),p=2*(i+l),_=2*(a+h),y=-n+u-f+d,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=S,t):new s(E,m,p,_,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,_=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1], +t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),A=2*(f+m),S=2*(c+_),N=-s+d-p+y,v=2*(E-h),I=2*(f-m),O=2*(E+h),M=-s-d+p+y;return r[0]=T*i,r[1]=S*i,r[2]=I*i,r[3]=0,r[4]=R*o,r[5]=N*o,r[6]=O*o,r[7]=0,r[8]=A*u,r[9]=v*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,N=u*-R+s*-A+c*-S,v=_*-R+y*-A+T*-S,I=E*R+m*A+p*S;return a(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=N,n[13]=v,n[14]=I,n[15]=1,n):new l(u,s,c,N,_,y,T,v,-E,-m,-p,I,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,p=o+l,_=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=_,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],N=t[4],v=t[5],I=t[6],O=t[7],M=t[8],g=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+h*A+p*S,b=i*T+c*R+d*A+_*S,B=o*T+l*R+E*A+y*S,z=r*N+u*v+f*I+m*O,q=a*N+s*v+h*I+p*O,G=i*N+c*v+d*I+_*O,V=o*N+l*v+E*I+y*O,W=r*M+u*g+f*w+m*C,X=a*M+s*g+h*w+p*C,H=i*M+c*g+d*w+_*C,Y=o*M+l*g+E*w+y*C,k=r*x+u*P+f*U+m*D,j=a*x+s*P+h*U+p*D,Z=i*x+c*P+d*U+_*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=b,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=W,n[9]=X,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],N=t[10],v=t[12],I=t[13],O=t[14],M=r*m+o*p+c*_,g=a*m+u*p+l*_,w=i*m+s*p+f*_,C=r*y+o*T+c*R,x=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*N,D=a*A+u*S+l*N,L=i*A+s*S+f*N,F=r*v+o*I+c*O+h,b=a*v+u*I+l*O+d,B=i*v+s*I+f*O+E;return n[0]=M,n[1]=g,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=b,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=a*h+u*d+l*E,N=i*h+s*d+f*E,v=r*m+o*p+c*_,I=a*m+u*p+l*_,O=i*m+s*p+f*_,M=r*y+o*T+c*R,g=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=N,n[3]=0,n[4]=v,n[5]=I,n[6]=O,n[7]=0,n[8]=M,n[9]=g,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],A=e[10],S=e[14],N=e[3],v=e[7],I=e[11],O=e[15],M=A*O,g=S*I,w=p*O,C=S*v,x=p*I,P=A*v,U=m*O,D=S*N,L=m*I,F=A*N,b=m*v,B=p*N,z=M*h+C*d+x*E-(g*h+w*d+P*E),q=g*f+U*d+F*E-(M*f+D*d+L*E),G=w*f+D*h+b*E-(C*f+U*h+B*E),V=P*f+L*h+B*d-(x*f+F*h+b*d),W=g*a+w*i+P*o-(M*a+C*i+x*o),X=M*r+D*i+L*o-(g*r+U*i+F*o),H=C*r+U*a+B*o-(w*r+D*a+b*o),Y=x*r+F*a+b*i-(P*r+L*a+B*i);M=i*E,g=o*d,w=a*E,C=o*h,x=a*d,P=i*h,U=r*E,D=o*f,L=r*d,F=i*f,b=r*h,B=a*f;var k=M*v+C*I+x*O-(g*v+w*I+P*O),j=g*N+U*I+F*O-(M*N+D*I+L*O),Z=w*N+D*v+b*O-(C*N+U*v+B*O),K=P*N+L*v+B*I-(x*N+F*v+b*I),J=w*A+P*S+g*p-(x*S+M*p+C*A),Q=L*S+M*m+D*A-(U*A+F*S+g*m),$=U*p+B*S+C*m-(b*S+w*m+D*p),ee=b*A+x*m+F*p-(L*p+B*A+P*m),te=r*z+a*q+i*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=W*te,n[5]=X*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(a(t,e.ZERO)),this.radius=a(n,0)}var E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,S=new e,N=new e,v=new e,I=new e,O=4/3*n.PI;d.fromPoints=function(t,n){if(i(n)||(n=new d),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],R),o=e.clone(a,E),u=e.clone(a,m),s=e.clone(a,p),c=e.clone(a,_),l=e.clone(a,y),f=e.clone(a,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],a);var O=a.x,M=a.y,g=a.z;O<o.x&&e.clone(a,o),O>c.x&&e.clone(a,c),M<u.y&&e.clone(a,u),M>l.y&&e.clone(a,l),g<s.z&&e.clone(a,s),g>f.z&&e.clone(a,f)}var w=e.magnitudeSquared(e.subtract(c,o,A)),C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=S;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,A)),b=Math.sqrt(F),B=N;B.x=o.x,B.y=u.y,B.z=s.z;var z=v;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,A),.5,I),G=0;for(r=0;r<h;r++){e.clone(t[r],a);var V=e.magnitude(e.subtract(a,q,A));V>G&&(G=V);var W=e.magnitudeSquared(e.subtract(a,L,A));if(W>F){var X=Math.sqrt(W);b=.5*(b+X),F=b*b;var H=X-b;L.x=(b*L.x+H*a.x)/X,L.y=(b*L.y+H*a.y)/X,L.z=(b*L.z+H*a.z)/X}}return b<G?(e.clone(L,n.center),n.radius=b):(e.clone(q,n.center),n.radius=G),n};var M=new u,g=new e,w=new e,C=new t,x=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(i(u)||(u=new d),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=a(n,M),h.southwest(t,C),C.height=r,h.northeast(t,x),x.height=o;var s=n.project(C,g),c=n.project(x,w),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=a(n,o.WGS84),r=a(r,0),i(u)||(u=new d),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(i(o)||(o=new d),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=a(n,e.ZERO),r=a(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,m),f=e.clone(u,p),h=e.clone(u,_),O=e.clone(u,y),M=e.clone(u,T),g=t.length;for(s=0;s<g;s+=r){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>h.x&&e.clone(u,h),C<l.y&&e.clone(u,l),C>O.y&&e.clone(u,O),x<f.z&&e.clone(u,f),x>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(h,c,A)),U=e.magnitudeSquared(e.subtract(O,l,A)),D=e.magnitudeSquared(e.subtract(M,f,A)),L=c,F=h,b=P;U>b&&(b=U,L=l,F=O),D>b&&(b=D,L=f,F=M);var B=S;B.x=.5*(L.x+F.x),B.y=.5*(L.y+F.y),B.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,A)),q=Math.sqrt(z),G=N;G.x=c.x,G.y=l.y,G.z=f.z;var V=v;V.x=h.x,V.y=O.y,V.z=M.z;var W=e.multiplyByScalar(e.add(G,V,A),.5,I),X=0;for(s=0;s<g;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,A));H>X&&(X=H);var Y=e.magnitudeSquared(e.subtract(u,B,A));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;B.x=(q*B.x+j*u.x)/k,B.y=(q*B.y+j*u.y)/k,B.z=(q*B.z+j*u.z)/k}}return q<X?(e.clone(B,o.center),o.radius=q):(e.clone(W,o.center),o.radius=X),o},d.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new d),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=R;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,E),s=e.clone(a,m),c=e.clone(a,p),l=e.clone(a,_),f=e.clone(a,y),h=e.clone(a,T),O=t.length;for(o=0;o<O;o+=3){var M=t[o]+n[o],g=t[o+1]+n[o+1],w=t[o+2]+n[o+2];a.x=M,a.y=g,a.z=w,M<u.x&&e.clone(a,u),M>l.x&&e.clone(a,l),g<s.y&&e.clone(a,s),g>f.y&&e.clone(a,f),w<c.z&&e.clone(a,c),w>h.z&&e.clone(a,h)}var C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=e.magnitudeSquared(e.subtract(h,c,A)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=S;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var b=e.magnitudeSquared(e.subtract(D,F,A)),B=Math.sqrt(b),z=N;z.x=u.x,z.y=s.y,z.z=c.z;var q=v;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,A),.5,I),V=0;for(o=0;o<O;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(a,G,A));W>V&&(V=W);var X=e.magnitudeSquared(e.subtract(a,F,A));if(X>b){var H=Math.sqrt(X);B=.5*(B+H),b=B*B;var Y=H-B;F.x=(B*F.x+Y*a.x)/H,F.y=(B*F.y+Y*a.y)/H,F.z=(B*F.z+Y*a.z)/H}}return B<V?(e.clone(F,r.center),r.radius=B):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){i(r)||(r=new d);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},d.fromEllipsoid=function(t,n){return i(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(i(n)||(n=new d), +!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){i(n)||(n=new d);var r=t.halfAxes,a=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},d.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=a(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=a(t,0),i(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var b=new e,B=new e;d.union=function(t,n,r){i(r)||(r=new d);var a=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,a,b),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,a,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,z));return a>r.radius&&(r.radius=a),r},d.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?s.OUTSIDE:o<a?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return i(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return i(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,a){i(a)||(a=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var V=new e,W=new e,X=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=a(n,K);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,W);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=i.cartesianToCartographic(y,k);n.project(T,y)}r=d.fromPoints(E,r),o=r.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return O*e*e*e},d}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,_=4*E*p-m*m;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-_);i=-R+S;var N=i/2,v=N<0?-Math.pow(-N,1/3):Math.pow(N,1/3),I=i===S?-v:-T/v;return a=T<=0?v+I:-R/(v*v+I*I+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var O=E,M=-2*u*E+o*m,g=p,w=-c*m+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-M)/3);a=2*Math.sqrt(-O);var U=Math.cos(P);i=a*U;var D=a*(-U/2-x*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,b=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),a=2*Math.sqrt(-g),U=Math.cos(P),i=a*U,D=a*(-U/2-x*Math.sin(P));var B=-c,z=i+D<2*s?i+s:D+s,q=B/z,G=F*z,V=-L*z-F*B,W=L*B,X=(s*V-u*W)/(-u*V+s*G);return b<=X?b<=q?X<=q?[b,X,q]:[b,q,X]:[q,b,X]:b<=q?[X,b,q]:X<=q?[X,q,b]:[q,X,b]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,N=r.computeRealRoots(1,R,A),v=r.computeRealRoots(1,-R,S);return 0!==N.length?(N[0]+=h,N[1]+=h,0!==v.length?(v[0]+=h,v[1]+=h,N[1]<=v[0]?[N[0],N[1],v[0],v[1]]:v[1]<=N[0]?[v[0],v[1],N[0],N[1]]:N[0]>=v[0]&&N[1]<=v[1]?[v[0],N[0],N[1],v[1]]:v[0]>=N[0]&&v[1]<=N[1]?[N[0],v[0],v[1],N[1]]:N[0]>v[0]&&N[0]<v[1]?[v[0],N[0],v[1],N[1]]:[N[0],v[0],N[1],v[1]]):N):0!==v.length?(v[0]+=h,v[1]+=h,v):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],_=a-p,y=_*_,T=t/2,R=_/2,A=y-4*o,S=y+4*Math.abs(o),N=c-4*p,v=c+4*Math.abs(p);if(p<0||A*v<N*S){var I=Math.sqrt(N);E=I/2,m=0===I?0:(t*R-i)/I}else{var O=Math.sqrt(A);E=0===O?0:(t*R-i)/O,m=O/2}var M,g;0===T&&0===E?(M=0,g=0):n.sign(T)===n.sign(E)?(M=T+E,g=p/M):(g=T-E,M=p/g);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,M,w),P=r.computeRealRoots(1,g,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],N=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-N)),T.push(new e(a,i*S,i*N))}return T}var v=y*y,I=_*_,O=E*E,M=y*_,g=O+I,w=2*(m*E+M),C=2*p*E+m*m-I+v,x=2*(p*m-M),P=p*p-v;if(0===g&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(g,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],b=F*F,B=Math.max(1-b,0),z=Math.sqrt(B);L=o.sign(E)===o.sign(p)?d(E*b+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?d(E*b,m*F+p,o.EPSILON12):d(E*b+m*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,p),A=e.subtract(i,r,_),S=e.cross(E,A,y),N=e.dot(m,S);if(u){if(N<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>N)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>N)return;h=e.dot(A,c)/N}else{if(Math.abs(N)<o.EPSILON6)return;var v=1/N;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*v)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*v)<0||l+f>1)return;h=e.dot(A,c)*v}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var N=new l;m.lineSegmentSphere=function(t,n,a,i){var o=N;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var v=new e,I=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,v),f=e.multiplyComponents(c,t.direction,I),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,p=r/s;return m<p?new i(m,p):{start:p,stop:m}}var _=Math.sqrt(r/a);return new i(_,_)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var O=new e,M=new e,g=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,b=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,O);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,O),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,M),M),m=e.normalize(e.cross(f,d,g),g),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,N=u.multiply(u.multiply(_,T,F),R,F),v=u.multiply(u.multiply(N,y,b),p,b),I=u.multiplyByVector(N,a,C),G=E(v,e.negate(I,O),0,0,1),V=G.length;if(V>0){for(var W=e.clone(e.ZERO,z),X=Number.NEGATIVE_INFINITY,H=0;H<V;++H){A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],B),B);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>X&&(X=k,W=e.clone(A,W))}var j=n.cartesianToCartographic(W,q);return X=o.clamp(X,0,1),S=e.magnitude(e.subtract(W,a,w))*Math.sqrt(1-X*X),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,a){n(a)||(a=new e);var i=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,i,c);return e.subtract(r,o,a)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=_,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){ +return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=_,d.reject(h))},E=function(e){f.push(e),--c||(E=m=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",N=s.length,v=0;s&&v<N;v++)switch(s.charAt(v)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(v+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,S);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),E=d<0?"-":T,_=E+a(String(Math.abs(d)),f,"0",!1),i(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=E+Math.abs(d)[m](f),i(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var p=new i,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,N=/^(\d{4})-?(\d{2})-?(\d{2})$/,v=/([Z+\-])?(\d{2})?:?(\d{2})?$/,I=/^(\d{2})(\.\d+)?/.source+v.source,O=/^(\d{2}):?(\d{2})(\.\d+)?/.source+v.source,M=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+v.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,v=0,g=u[0],w=u[1];if(null!==(u=g.match(N)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=g.match(R)))n=+u[1],s=+u[2];else if(null!==(u=g.match(T)))n=+u[1];else{var C;if(null!==(u=g.match(A)))n=+u[1],C=+u[2],i=o(n);else if(null!==(u=g.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(C),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(M),null!==u?(h=+u[1],p=+u[2],y=+u[3],v=1e3*+(u[4]||0),D=5):(u=w.match(O),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(I))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],b=+(u[D+2]||0);switch(L){case"+":h-=F,p-=b;break;case"-":h+=F,p+=b;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var B=60===y;for(B&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:_[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:_[s-1],l+=a;var z=E(n,s,l,h,p,y,v);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var g=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,g);r(a)||(m.addSeconds(e,-1,g),a=h(g,g),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(_,p,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,p);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,a,i){i=e(i,!1);var o,u,s,c={},l=t(r),f=t(a);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&i&&"object"==typeof u&&a.hasOwnProperty(o)?(s=a[o],c[o]="object"==typeof s?n(u,s,i):u):c[o]=u);if(f)for(o in a)a.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=a[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(a[n])||(a[n]=!0,console.warn(e(r,n)))}var a={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(e,t){return a._implementation(e,t,document)}return a._implementation=function(n,r,a){r=t(r,t(a.baseURI,a.location.href));var i=new e(r);return new e(n).resolve(i).toString()},a}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var a="",i=n.lastIndexOf("/");return-1!==i&&(a=n.substring(0,i+1)),r?(n=new e(n),t(n.query)&&(a+="?"+n.query),t(n.fragment)&&(a+="#"+n.fragment),a):a}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,a=r.lastIndexOf("/");return-1!==a&&(r=r.substr(a+1)),a=r.lastIndexOf("."),r=-1===a?"":r.substr(a+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,a=n.protocol;return n.href=t,n.href=n.href,a!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var a=e[r],i=encodeURIComponent(r)+"=";if(n(a))for(var o=0,u=a.length;o<u;++o)t+=i+encodeURIComponent(a[o])+"&";else t+=i+encodeURIComponent(a)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var a=t.replace(/\+/g,"%20").split(/[&;]/),i=0,o=a.length;i<o;++i){var u=a[i].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT);var a=e(t.throttleByServer,!1),i=a||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return a.prototype.cancel=function(){this.cancelled=!0},a.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new a(this)},a}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function a(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,a=-1,i=0;i<n.length;i++)if(n[i]===e&&r[i]===t){a=i;break}return-1!==a&&(this._insideRaiseEvent?(this._toRemove.push(a),n[a]=void 0,r[a]=void 0):(n.splice(a,1),r.splice(a,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,i=n.length;for(e=0;e<i;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((i=u.length)>0){for(u.sort(a),e=0;e<i;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return I[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--A.numberOfActiveRequests,--I[e.serverKey],M.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){return function(t){e.state!==c.CANCELLED&&(++A.numberOfFailedRequests,--A.numberOfActiveRequests,--I[e.serverKey],M.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function _(e){var t=E(e);return e.state=c.ACTIVE,v.push(e),++A.numberOfActiveRequests,++A.numberOfActiveRequestsEver,++I[e.serverKey],e.requestFunction().then(m(e)).otherwise(p(e)),t}function y(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++A.numberOfCancelledRequests,e.deferred.reject(),t&&(--A.numberOfActiveRequests,--I[e.serverKey],++A.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){A.numberOfAttemptedRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(A.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+A.numberOfAttemptedRequests),A.numberOfActiveRequests>0&&console.log("Number of active requests: "+A.numberOfActiveRequests),A.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+A.numberOfCancelledRequests),A.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+A.numberOfCancelledActiveRequests),A.numberOfFailedRequests>0&&console.log("Number of failed requests: "+A.numberOfFailedRequests),T())}var A={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},S=20,N=new o({comparator:l});N.maximumLength=S,N.reserve(S);var v=[],I={},O="undefined"!=typeof document?new e(document.location.href):new e,M=new i;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=M,a(f,{statistics:{get:function(){return A}},priorityHeapLength:{get:function(){return S},set:function(e){if(e<S)for(;N.length>e;){var t=N.pop();y(t)}S=e,N.maximumLength=e,N.reserve(e)}}}),f.update=function(){var e,t,n=0,r=v.length;for(e=0;e<r;++e)t=v[e],t.cancelled&&y(t),t.state===c.ACTIVE?n>0&&(v[e-n]=t):++n;v.length-=n;var a=N.internalArray,i=N.length;for(e=0;e<i;++e)h(a[e]);N.resort();for(var o=Math.max(f.maximumRequests-v.length,0),u=0;u<o&&N.length>0;)t=N.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):y(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=I[a];return r(i)||(I[a]=0),a},f.request=function(e){if(s(e.url)||u(e.url))return M.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++A.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return _(e);if(!(v.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=N.insert(e);if(r(t)){if(t===e)return;y(t)}return E(e)}},f.clearForSpecs=function(){for(;N.length>0;){y(N.pop())}for(var e=v.length,t=0;t<e;++t)y(v[t]);v.length=0,I={},A.numberOfAttemptedRequests=0,A.numberOfActiveRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0,A.numberOfFailedRequests=0,A.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return I[e]},f.requestHeap=N,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,_,y,T,R,A,S,N,v,I){"use strict";function O(e,t){var n=e.query;if(!i(n)||0===n.length)return{};var a;if(-1===n.indexOf("=")){var o={};o[n]=void 0,a=o}else a=_(n);t._queryParameters=r(t._queryParameters,a),e.query=void 0}function M(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||i(n[r[0]])?e.query=p(n):e.query=r[0]}function g(e,t){return i(e)?i(e.clone)?e.clone():n(e):t}function w(e){if(e.state===A.ISSUED||e.state===A.ACTIVE)throw new S("The Resource is already being fetched.");e.state=A.UNISSUED,e.deferred=void 0}function C(e){e=a(e,a.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=g(e.templateValues,{}),this._queryParameters=g(e.queryParameters,{}),this.headers=g(e.headers,{}),this.request=a(e.request,new y),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=a(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function x(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var a=I.defer();return C._Implementations.createImage(n,r&&t,a),a.promise};var r=R.request(n);if(i(r))return r.otherwise(function(r){return n.state!==A.FAILED?I.reject(r):e.retryOnError(r).then(function(a){return a?(n.state=A.UNISSUED,n.deferred=void 0,x(e,t)):I.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var a=e.request;a.url=e.url,a.requestFunction=function(){var t=I.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},C._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(a);if(i(o))return o.otherwise(function(r){return a.state!==A.FAILED?I.reject(r):e.retryOnError(r).then(function(i){return i?(a.state=A.UNISSUED,a.deferred=void 0,P(e,t,n)):I.reject(r)})})}function U(e,t){w(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var a=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=I.defer(),f=C._Implementations.loadWithXhr(e.url,a,s,c,o,l,u);return i(f)&&i(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var a=R.request(n);if(i(a))return a.then(function(e){return e}).otherwise(function(r){return n.state!==A.FAILED?I.reject(r):e.retryOnError(r).then(function(a){return a?(n.state=A.UNISSUED,n.deferred=void 0,e.fetch(t)):I.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function F(e,t){t=a(t,"");var n=e[1],r=!!e[2],i=e[3];switch(t){case"":case"text":return D(r,i);case"arraybuffer":return L(r,i);case"blob":var o=L(r,i);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,i),n);case"json":return JSON.parse(D(r,i))}}var b=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();C.createIfNeeded=function(e,t){if(e instanceof C)return e.clone();if("string"!=typeof e)return e;var n=g(t,{});return n.url=e,new C(n)},o(C,{isBlobSupported:{get:function(){return b}}}),o(C.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new v(e);O(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),C.prototype.getUrlComponent=function(e,t){ +if(this.isDataUri)return this._url;var n=new v(this._url);e&&M(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),a=this._templateValues,o=Object.keys(a);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=a[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&i(this.proxy)&&(r=this.proxy.getURL(r)),r},C.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},C.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},C.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,i(e.url)){var n=new v(e.url);O(n,t),n.fragment=void 0,t._url=n.resolve(new v(l(this._url))).toString()}return i(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),i(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),i(e.headers)&&(t.headers=r(e.headers,t.headers)),i(e.proxy)&&(t.proxy=e.proxy),i(e.request)?t.request=e.request:t.request=this.request.clone(),i(e.retryCallback)&&(t.retryCallback=e.retryCallback),i(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},C.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return I(!1);var n=this;return I(t(this,e)).then(function(e){return++n._retryCount,e})},C.prototype.clone=function(e){return i(e)||(e=new C({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},C.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},C.prototype.appendForwardSlash=function(){this._url=e(this._url)},C.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},C.fetchArrayBuffer=function(e){return new C(e).fetchArrayBuffer()},C.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},C.fetchBlob=function(e){return new C(e).fetchBlob()},C.prototype.fetchImage=function(e,t){if(i(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=a(e,!1),t=a(t,!0),w(this.request),!b||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return x(this,t);var n=this.fetchBlob();if(i(n)){var r,o;return n.then(function(e){if(i(e)){o=e;var t=window.URL.createObjectURL(e);return r=new C({url:t}),x(r)}}).then(function(e){if(i(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return i(r)&&window.URL.revokeObjectURL(r.url),I.reject(e)})}},C.fetchImage=function(e){return new C(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},C.prototype.fetchText=function(){return this.fetch({responseType:"text"})},C.fetchText=function(e){return new C(e).fetchText()},C.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(i(e))return e.then(function(e){if(i(e))return JSON.parse(e)})},C.fetchJson=function(e){return new C(e).fetchJson()},C.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},C.fetchXML=function(e){return new C(e).fetchXML()},C.prototype.fetchJsonp=function(e){e=a(e,"callback"),w(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(i(window[t]));return P(this,e,t)},C.fetchJsonp=function(e){return new C(e).fetchJsonp(e.callbackParameterName)},C.prototype.fetch=function(e){return e=g(e,a.EMPTY_OBJECT),e.method="GET",U(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return C.fetch=function(e){return new C(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C.prototype.post=function(e,n){return t.defined("data",e),n=g(n,{}),n.method="POST",n.data=e,U(this,n)},C.post=function(e){return new C(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C._Implementations={},C._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(N.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},C._Implementations.loadWithXhr=function(e,t,n,r,a,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(N.contains(e)&&(c.withCredentials=!0),i(u)&&i(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),i(a))for(var l in a)a.hasOwnProperty(l)&&c.setRequestHeader(l,a[l]);i(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!i(e)||i(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&i(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!i(c.responseText)?o.reject(new S("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},C._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var a=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,a.removeChild(r)},r.onerror=function(e){n.reject(e)},a.appendChild(r)},C._DefaultImplementations={},C._DefaultImplementations.createImage=C._Implementations.createImage,C._DefaultImplementations.loadWithXhr=C._Implementations.loadWithXhr,C._DefaultImplementations.loadAndExecuteScript=C._Implementations.loadAndExecuteScript,C.DEFAULT=c(new C({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),C}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=s.createIfNeeded(t.url),i=this;this._downloadPromise=e(a.fetchJson(),function(e){E(i,e)},function(){i._dataError="An error occurred while retrieving the EOP data from the URL "+a.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var S=p[R+a],N=p[R+m],v=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,I=new o(v,N,f.TAI);if(_.push(I),T){if(N!==y&&r(y)){var O=o.leapSeconds,M=t(O,I,d);if(M<0){var g=new u(I,N);O.splice(~M,0,g)}}y=N}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,_(this,i,this._samples,e,s,l,n),n}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,a){"use strict";function i(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=d.exec(r);if(null!==a)return a[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:i(),l=new r({url:e})}function u(e){return a.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(a.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,a[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:a}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(N)&&(N=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(N=!0,v=r(e[1]))}return N}function u(){return o()&&v}function s(){if(!t(I)){I=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(I=!0,O=r(e[1]),O.isNightly=!!e[2])}return I}function c(){return s()&&O}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,g=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,g=r(e[1]))}return M}function f(){return l()&&g}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,N,v,I,O,M,g,w,C,x,P,U,D,L,F,b={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return b.supportsFullscreen=function(){return n.supportsFullscreen()},b.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},b.supportsWebWorkers=function(){return"undefined"!=typeof Worker},b}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),E>h&&E>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,N=new s,v=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return N=s.multiplyByScalar(e,Math.sin((1-n)*u),N),v=s.multiplyByScalar(i,Math.sin(n*u),v),r=s.add(N,v,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var I=new e,O=new e,M=new s,g=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,M);s.multiply(i,r,g);var o=s.log(g,I);s.multiply(i,t,g);var u=s.log(g,O);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,M),u=s.slerp(n,r,a,g);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,C=1.9011074535173003,x=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,b=2*F+1;x[L]=1/(F*b),P[L]=F/b}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,M),u=s.fastSlerp(n,r,a,g);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},N={},v={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},I=new n,O=new n,M=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(N[i])?r=N[i]:(r=function(r,i,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,I),"east"!==e&&"west"!==e&&n.multiplyByScalar(I,c,I),n.unpack(S[t],0,O),"east"!==t&&"west"!==t&&n.multiplyByScalar(O,c,O),n.unpack(S[a],0,M),"east"!==a&&"west"!==a&&n.multiplyByScalar(M,c,M)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,v.up);var l=v.up,h=v.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,v.east),n.cross(l,h,v.north),n.multiplyByScalar(v.up,-1,v.down),n.multiplyByScalar(v.east,-1,v.west),n.multiplyByScalar(v.north,-1,v.south),I=v[e],O=v[t],M=v[a]}return s[0]=I.x,s[1]=I.y,s[2]=I.z,s[3]=0,s[4]=O.x,s[5]=O.y,s[6]=O.z,s[7]=0,s[8]=M.x,s[9]=M.y,s[10]=M.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},N[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var g=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,g),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return i=a(e,r,i),_.multiply(i,s,i)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),b=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=b;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,B),h=p.multiply(l,f,b),d=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=_/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var N=p.fromRotationZ(S,B),v=p.multiply(h,N,b),I=Math.cos(n.xPoleWander),O=Math.cos(n.yPoleWander),M=Math.sin(n.xPoleWander),g=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=B;return U[0]=I*x,U[1]=I*P,U[2]=M,U[3]=-O*P+g*M*x,U[4]=O*x+g*M*P,U[5]=-g*I,U[6]=-g*P-O*M*x,U[7]=g*x-O*M*P,U[8]=O*I,p.multiply(v,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return _.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var W=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),X=new a,H=new n,Y=new n,k=new p,j=new _,Z=new _;return R.basisTo2D=function(e,t,r){var a=_.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,X),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,j),c=_.inverseTransformation(s,Z),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(W,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,j),o=_.inverseTransformation(i,Z),u=a.cartesianToCartographic(t,X),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,j);return _.multiply(W,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{ +get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=_;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=_;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m){"use strict";function p(e,t){this.center=n.clone(i(e,n.ZERO)),this.halfAxes=d.clone(i(t,d.ZERO))}function _(e,t,r,a,i,u,s,c){o(c)||(c=new p);var l=c.halfAxes;d.setColumn(l,0,e.xAxis,l),d.setColumn(l,1,e.yAxis,l),d.setColumn(l,2,e.zAxis,l);var f=O;f.x=(t+r)/2,f.y=(a+i)/2,f.z=(u+s)/2;var h=M;h.x=(r-t)/2,h.y=(i-a)/2,h.z=(s-u)/2;var E=c.center;return f=d.multiplyByVector(l,f,f),n.add(e.origin,f,E),d.multiplyByScale(l,h,l),c}p.packedLength=n.packedLength+d.packedLength,p.pack=function(e,t,r){return r=i(r,0),n.pack(e.center,t,r),d.pack(e.halfAxes,t,r+n.packedLength),t},p.unpack=function(e,t,r){return t=i(t,0),o(r)||(r=new p),n.unpack(e,t,r.center),d.unpack(e,t+n.packedLength,r.halfAxes),r};var y=new n,T=new n,R=new n,A=new n,S=new n,N=new n,v=new d,I={unitary:new d,diagonal:new d};p.fromPoints=function(e,t){if(o(t)||(t=new p),!o(e)||0===e.length)return t.halfAxes=d.ZERO,t.center=n.ZERO,t;var r,a=e.length,i=n.clone(e[0],y);for(r=1;r<a;r++)n.add(i,e[r],i);var u=1/a;n.multiplyByScalar(i,u,i);var s,c=0,l=0,f=0,h=0,E=0,m=0;for(r=0;r<a;r++)s=n.subtract(e[r],i,T),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,h+=s.y*s.y,E+=s.y*s.z,m+=s.z*s.z;c*=u,l*=u,f*=u,h*=u,E*=u,m*=u;var _=v;_[0]=c,_[1]=l,_[2]=f,_[3]=l,_[4]=h,_[5]=E,_[6]=f,_[7]=E,_[8]=m;var O=d.computeEigenDecomposition(_,I),M=d.clone(O.unitary,t.halfAxes),g=d.getColumn(M,0,A),w=d.getColumn(M,1,S),C=d.getColumn(M,2,N),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<a;r++)s=e[r],x=Math.max(n.dot(g,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(g,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);g=n.multiplyByScalar(g,.5*(D+x),g),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var b=n.add(g,w,t.center);n.add(b,C,b);var B=R;return B.x=x-D,B.y=P-L,B.z=U-F,n.multiplyByScalar(B,.5,B),d.multiplyByScale(t.halfAxes,B,t.halfAxes),t};var O=new n,M=new n,g=new r,w=new n,C=[new r,new r,new r,new r,new r,new r,new r,new r],x=[new n,new n,new n,new n,new n,new n,new n,new n],P=[new t,new t,new t,new t,new t,new t,new t,new t];p.fromRectangle=function(e,t,n,r,a){t=i(t,0),n=i(n,0),r=i(r,s.WGS84);var o=m.center(e,g),u=r.cartographicToCartesian(o,w),l=new c(u,r),f=l.plane,h=C[0],d=C[1],p=C[2],y=C[3],T=C[4],R=C[5],A=C[6],S=C[7],N=o.longitude,v=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=v,h.latitude=d.latitude=p.latitude=e.north,A.longitude=S.longitude=h.longitude=e.west,R.longitude=d.longitude=N,T.longitude=y.longitude=p.longitude=e.east,p.height=d.height=h.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(C,x),l.projectPointsToNearestOnPlane(x,P);var I=Math.min(P[6].x,P[7].x,P[0].x),O=Math.max(P[2].x,P[3].x,P[4].x),M=Math.min(P[4].y,P[5].y,P[6].y),U=Math.max(P[0].y,P[1].y,P[2].y);return p.height=h.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(C,x),_(l,I,O,M,U,Math.min(E.getPointDistance(f,x[0]),E.getPointDistance(f,x[2]),E.getPointDistance(f,x[4]),E.getPointDistance(f,x[6])),n,a)},p.clone=function(e,t){if(o(e))return o(t)?(n.clone(e.center,t.center),d.clone(e.halfAxes,t.halfAxes),t):new p(e.center,e.halfAxes)},p.intersectPlane=function(e,t){var r=e.center,a=t.normal,i=e.halfAxes,o=a.x,u=a.y,s=a.z,c=Math.abs(o*i[d.COLUMN0ROW0]+u*i[d.COLUMN0ROW1]+s*i[d.COLUMN0ROW2])+Math.abs(o*i[d.COLUMN1ROW0]+u*i[d.COLUMN1ROW1]+s*i[d.COLUMN1ROW2])+Math.abs(o*i[d.COLUMN2ROW0]+u*i[d.COLUMN2ROW1]+s*i[d.COLUMN2ROW2]),f=n.dot(a,r)+t.distance;return f<=-c?l.OUTSIDE:f>=c?l.INSIDE:l.INTERSECTING};var U=new n,D=new n,L=new n,F=new n;p.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,O),a=e.halfAxes,i=d.getColumn(a,0,U),o=d.getColumn(a,1,D),u=d.getColumn(a,2,L),s=n.magnitude(i),c=n.magnitude(o),l=n.magnitude(u);n.normalize(i,i),n.normalize(o,o),n.normalize(u,u);var f=F;f.x=n.dot(r,i),f.y=n.dot(r,o),f.z=n.dot(r,u);var h,E=0;return f.x<-s?(h=f.x+s,E+=h*h):f.x>s&&(h=f.x-s,E+=h*h),f.y<-c?(h=f.y+c,E+=h*h):f.y>c&&(h=f.y-c,E+=h*h),f.z<-l?(h=f.z+l,E+=h*h):f.z>l&&(h=f.z-l,E+=h*h),E};var b=new n,B=new n;p.computePlaneDistances=function(e,t,r,a){o(a)||(a=new f);var i=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,l=d.getColumn(c,0,U),h=d.getColumn(c,1,D),E=d.getColumn(c,2,L),m=n.add(l,h,b);n.add(m,E,m),n.add(m,s,m);var p=n.subtract(m,t,B),_=n.dot(r,p);return i=Math.min(_,i),u=Math.max(_,u),n.add(s,l,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),n.add(s,l,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),n.add(s,l,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),n.subtract(s,l,m),n.add(m,h,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),n.subtract(s,l,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),n.subtract(s,l,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),n.subtract(s,l,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),i=Math.min(_,i),u=Math.max(_,u),a.start=i,a.stop=u,a};var z=new e;return p.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,z);return!n.isBoundingSphereVisible(r)},p.prototype.intersectPlane=function(e){return p.intersectPlane(this,e)},p.prototype.distanceSquaredTo=function(e){return p.distanceSquaredTo(this,e)},p.prototype.computePlaneDistances=function(e,t,n){return p.computePlaneDistances(this,e,t,n)},p.prototype.isOccluded=function(e){return p.isOccluded(this,e)},p.equals=function(e,t){return e===t||o(e)&&o(t)&&n.equals(e.center,t.center)&&d.equals(e.halfAxes,t.halfAxes)},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t,r,o,c,h){var p,_,y,T;if(i(e)&&i(t)&&i(r)&&i(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),N=r-t;p=Math.max(n.maximumComponent(S),N)<m-1?s.BITS12:s.NONE,_=e.center,y=u.inverseTransformation(o,new u);var v=n.negate(R,l);u.multiply(u.fromTranslation(v,d),y,y);var I=l;I.x=1/S.x,I.y=1/S.y,I.z=1/S.z,u.multiply(u.fromScale(I,d),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var O=u.fromTranslation(R,d),M=u.fromScale(S,E),g=u.multiply(O,M,d);u.multiply(o,g,o),u.multiply(T,g,T)}this.quantization=p,this.minimumHeight=t,this.maximumHeight=r,this.center=_,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=a(h,!1)}var l=new n,f=new n,h=new t,d=new u,E=new u,m=Math.pow(2,12);c.prototype.encode=function(r,a,i,c,f,d,E){var m=c.x,p=c.y;if(this.quantization===s.BITS12){i=u.multiplyByPoint(this.toScaledENU,i,l),i.x=o.clamp(i.x,0,1),i.y=o.clamp(i.y,0,1),i.z=o.clamp(i.z,0,1);var _=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/_,0,1);t.fromElements(i.x,i.y,h);var T=e.compressTextureCoordinates(h);t.fromElements(i.z,y,h);var R=e.compressTextureCoordinates(h);t.fromElements(m,p,h);var A=e.compressTextureCoordinates(h);if(r[a++]=T,r[a++]=R,r[a++]=A,this.hasWebMercatorT){t.fromElements(E,0,h);var S=e.compressTextureCoordinates(h);r[a++]=S}}else n.subtract(i,this.center,l),r[a++]=l.x,r[a++]=l.y,r[a++]=l.z,r[a++]=f,r[a++]=m,r[a++]=p,this.hasWebMercatorT&&(r[a++]=E);return this.hasVertexNormals&&(r[a++]=e.octPackFloat(d)),a},c.prototype.decodePosition=function(t,r,a){if(i(a)||(a=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],h);a.x=o.x,a.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],h);return a.z=c.x,u.multiplyByPoint(this.fromScaledENU,a,a)}return a.x=t[r],a.y=t[r+1],a.z=t[r+2],n.add(a,this.center,a)},c.prototype.decodeTextureCoordinates=function(n,r,a){return i(a)||(a=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],a):t.fromElements(n[r+4],n[r+5],a)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var a=e[n]/256,i=Math.floor(a),o=256*(a-i);return t.fromElements(i,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var p={position3DAndHeight:0,textureCoordAndEncodedNormals:1},_={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,a=r.getSizeInBytes(n);if(this.quantization===s.NONE){var i=2;return this.hasWebMercatorT&&++i,this.hasVertexNormals&&++i,t=(4+i)*a,[{index:p.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:p.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:i,offsetInBytes:4*a,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*a,[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:_.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*a,strideInBytes:t}]):[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?p:_},c.clone=function(e,t){return i(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/WebMercatorProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(s.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),s.mercatorAngleToGeodeticLatitude=function(e){return u.PI_OVER_TWO-2*Math.atan(Math.exp(-e))},s.geodeticLatitudeToMercatorAngle=function(e){e>s.MaximumLatitude?e=s.MaximumLatitude:e<-s.MaximumLatitude&&(e=-s.MaximumLatitude);var t=Math.sin(e);return.5*Math.log((1+t)/(1-t))},s.MaximumLatitude=s.mercatorAngleToGeodeticLatitude(Math.PI),s.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=s.geodeticLatitudeToMercatorAngle(t.latitude)*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},s.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=s.mercatorAngleToGeodeticLatitude(e.y*a),u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},s}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,a=t.message;n=e(r)&&e(a)?r+": "+a:t.toString();var i=t.stack;return e(i)&&(n+="\n"+i),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return r}),define("Workers/createVerticesFromQuantizedTerrainMesh",["../Core/AttributeCompression","../Core/AxisAlignedBoundingBox","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defined","../Core/Ellipsoid","../Core/IndexDatatype","../Core/Math","../Core/Matrix4","../Core/OrientedBoundingBox","../Core/TerrainEncoding","../Core/Transforms","../Core/WebMercatorProjection","./createTaskProcessorWorker"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m){"use strict";function p(i,m){var p,g,w=i.quantizedVertices,C=w.length/3,x=i.octEncodedNormals,P=i.westIndices.length+i.eastIndices.length+i.southIndices.length+i.northIndices.length,U=i.includeWebMercatorT,D=i.rectangle,L=D.west,F=D.south,b=D.east,B=D.north,z=u.clone(i.ellipsoid),q=i.exaggeration,G=i.minimumHeight*q,V=i.maximumHeight*q,W=i.relativeToCenter,X=d.eastNorthUpToFixedFrame(W,z),H=l.inverseTransformation(X,new l);U&&(p=E.geodeticLatitudeToMercatorAngle(F),g=1/(E.geodeticLatitudeToMercatorAngle(B)-p));var Y=w.subarray(0,C),k=w.subarray(C,2*C),j=w.subarray(2*C,3*C),Z=o(x),K=new Array(C),J=new Array(C),Q=new Array(C),$=U?new Array(C):[],ee=A;ee.x=Number.POSITIVE_INFINITY,ee.y=Number.POSITIVE_INFINITY,ee.z=Number.POSITIVE_INFINITY;var te=S;te.x=Number.NEGATIVE_INFINITY,te.y=Number.NEGATIVE_INFINITY,te.z=Number.NEGATIVE_INFINITY;for(var ne=Number.POSITIVE_INFINITY,re=Number.NEGATIVE_INFINITY,ae=Number.POSITIVE_INFINITY,ie=Number.NEGATIVE_INFINITY,oe=0;oe<C;++oe){var ue=Y[oe]/T,se=k[oe]/T,ce=c.lerp(G,V,j[oe]/T);N.longitude=c.lerp(L,b,ue),N.latitude=c.lerp(F,B,se),N.height=ce,ne=Math.min(N.longitude,ne),re=Math.max(N.longitude,re),ae=Math.min(N.latitude,ae),ie=Math.max(N.latitude,ie);var le=z.cartographicToCartesian(N);K[oe]=new r(ue,se),J[oe]=ce,Q[oe]=le,U&&($[oe]=(E.geodeticLatitudeToMercatorAngle(N.latitude)-p)*g),l.multiplyByPoint(H,le,R),a.minimumByComponent(R,ee,ee),a.maximumByComponent(R,te,te)}var fe,he;1!==q&&(he=n.fromPoints(Q),fe=f.fromRectangle(D,G,V,z));var de=G;de=Math.min(de,_(i.westIndices,i.westSkirtHeight,J,K,D,z,H,ee,te)),de=Math.min(de,_(i.southIndices,i.southSkirtHeight,J,K,D,z,H,ee,te)),de=Math.min(de,_(i.eastIndices,i.eastSkirtHeight,J,K,D,z,H,ee,te)),de=Math.min(de,_(i.northIndices,i.northSkirtHeight,J,K,D,z,H,ee,te));for(var Ee=new t(ee,te,W),me=new h(Ee,de,V,X,Z,U),pe=me.getStride(),_e=C*pe+P*pe,ye=new Float32Array(_e),Te=0,Re=0;Re<C;++Re){if(Z){var Ae=2*Re;if(v.x=x[Ae],v.y=x[Ae+1],1!==q){var Se=e.octDecode(v.x,v.y,I),Ne=d.eastNorthUpToFixedFrame(Q[Re],z,M),ve=l.inverseTransformation(Ne,O);l.multiplyByPointAsVector(ve,Se,Se),Se.z*=q,a.normalize(Se,Se),l.multiplyByPointAsVector(Ne,Se,Se),a.normalize(Se,Se),e.octEncode(Se,v)}}Te=me.encode(ye,Te,Q[Re],K[Re],J[Re],v,$[Re])}var Ie=Math.max(0,2*(P-4)),Oe=i.indices.length+3*Ie,Me=s.createTypedArray(C+P,Oe);Me.set(i.indices,0);var ge=1e-4*(re-ne),we=1e-4*(ie-ae),Ce=-ge,xe=ge,Pe=we,Ue=-we,De=C*pe,Le=i.indices.length;return Le=y(ye,De,Me,Le,i.westIndices,me,J,K,x,z,D,i.westSkirtHeight,!0,q,p,g,Ce,0),De+=i.westIndices.length*pe,Le=y(ye,De,Me,Le,i.southIndices,me,J,K,x,z,D,i.southSkirtHeight,!1,q,p,g,0,Ue),De+=i.southIndices.length*pe,Le=y(ye,De,Me,Le,i.eastIndices,me,J,K,x,z,D,i.eastSkirtHeight,!1,q,p,g,xe,0),De+=i.eastIndices.length*pe,y(ye,De,Me,Le,i.northIndices,me,J,K,x,z,D,i.northSkirtHeight,!0,q,p,g,0,Pe),m.push(ye.buffer,Me.buffer),{vertices:ye.buffer,indices:Me.buffer,vertexStride:pe,center:W,minimumHeight:G,maximumHeight:V,boundingSphere:he,orientedBoundingBox:fe,encoding:me,skirtIndex:i.indices.length}}function _(e,t,n,r,i,o,u,s,f){var h=Number.POSITIVE_INFINITY,d=i.north,E=i.south,m=i.east,p=i.west;m<p&&(m+=c.TWO_PI);for(var _=e.length,y=0;y<_;++y){var T=e[y],A=n[T],S=r[T];N.longitude=c.lerp(p,m,S.x),N.latitude=c.lerp(E,d,S.y),N.height=A-t;var v=o.cartographicToCartesian(N,R);l.multiplyByPoint(u,v,v),a.minimumByComponent(v,s,s),a.maximumByComponent(v,f,f),h=Math.min(h,N.height)}return h}function y(t,n,r,i,u,s,f,h,m,p,_,y,T,A,S,g,w,C){var x,P,U;T?(x=u.length-1,P=-1,U=-1):(x=0,P=u.length,U=1);var D=-1,L=o(m),F=s.getStride(),b=n/F,B=_.north,z=_.south,q=_.east,G=_.west;q<G&&(q+=c.TWO_PI);for(var V=x;V!==P;V+=U){var W=u[V],X=f[W],H=h[W];N.longitude=c.lerp(G,q,H.x)+w,N.latitude=c.lerp(z,B,H.y)+C,N.height=X-y;var Y=p.cartographicToCartesian(N,R);if(L){var k=2*W;if(v.x=m[k],v.y=m[k+1],1!==A){var j=e.octDecode(v.x,v.y,I),Z=d.eastNorthUpToFixedFrame(R,p,M),K=l.inverseTransformation(Z,O);l.multiplyByPointAsVector(K,j,j),j.z*=A,a.normalize(j,j),l.multiplyByPointAsVector(Z,j,j),a.normalize(j,j),e.octEncode(j,v)}}var J;s.hasWebMercatorT&&(J=(E.geodeticLatitudeToMercatorAngle(N.latitude)-S)*g),n=s.encode(t,n,Y,H,N.height,v,J),-1!==D&&(r[i++]=D,r[i++]=b-1,r[i++]=W,r[i++]=b-1,r[i++]=b,r[i++]=W),D=W,++b}return i}var T=32767,R=new a,A=new a,S=new a,N=new i,v=new r,I=new a,O=new l,M=new l;return m(p)})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallGeometry.js index d3db7a04..8db166a0 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallGeometry.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,_=l*l*d*d,p=f*f*E*E,y=h*h*m*m,T=_+p+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,N=u.z,O=o;O.x=A.x*S*2,O.y=A.y*v*2,O.z=A.z*N*2;var g,I,M,w,x,C,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),b=0;do{B-=b,M=1/(1+B*S),w=1/(1+B*v),x=1/(1+B*N),C=M*M,P=w*w,U=x*x,D=C*M,L=P*w,F=U*x,g=_*C+p*P+y*U-1,I=_*D*S+p*L*v+y*F*N;b=g/(-2*I)}while(Math.abs(g)>r.EPSILON12);return t(c)?(c.x=l*M,c.y=f*w,c.z=h*x,c):new e(l*M,f*w,h*x)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,_=r(n)?n._centerToleranceSquared:d,p=o(t,E,m,_,c);if(r(p)){var y=e.multiplyComponents(p,m,s);y=e.normalize(y,y);var T=e.subtract(t,p,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,_=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,_=e[s.getElementIndex(h,h)],p=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(_-p)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),_=2*(i+l),p=2*(a+h),y=-n+u-f+d,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=p,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=_,t[7]=T,t[8]=S,t):new s(E,m,_,p,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,_=-o,p=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=_,t[3]=f,t[4]=E,t[5]=p,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,_,p,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],_=new s,p=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,_),s.transpose(_,p),s.multiply(h,_,h),s.multiply(p,h,h),s.multiply(o,_,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,_){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(_,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,_=t.z*t.z,p=t.z*t.w,y=t.w*t.w,T=s-d-_+y,R=2*(c-p),A=2*(f+m),S=2*(c+p),v=-s+d-_+y,N=2*(E-h),O=2*(f-m),g=2*(E+h),I=-s-d+_+y;return r[0]=T*i,r[1]=S*i,r[2]=O*i,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=g*o,r[7]=0,r[8]=A*u,r[9]=N*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,_=f.z,p=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,N=p*-R+y*-A+T*-S,O=E*R+m*A+_*S;return a(n)?(n[0]=u,n[1]=p,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-_,n[11]=0,n[12]=v,n[13]=N,n[14]=O,n[15]=1,n):new l(u,s,c,v,p,y,T,N,-E,-m,-_,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,_=o+l,p=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=_,a[14]=p,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],_=e[13],p=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],N=t[5],O=t[6],g=t[7],I=t[8],M=t[9],w=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+h*A+_*S,B=i*T+c*R+d*A+p*S,b=o*T+l*R+E*A+y*S,z=r*v+u*N+f*O+m*g,q=a*v+s*N+h*O+_*g,G=i*v+c*N+d*O+p*g,W=o*v+l*N+E*O+y*g,X=r*I+u*M+f*w+m*x,H=a*I+s*M+h*w+_*x,V=i*I+c*M+d*w+p*x,Y=o*I+l*M+E*w+y*x,k=r*C+u*P+f*U+m*D,Z=a*C+s*P+h*U+_*D,j=i*C+c*P+d*U+p*D,K=o*C+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=X,n[9]=H,n[10]=V,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],_=t[1],p=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],N=t[12],O=t[13],g=t[14],I=r*m+o*_+c*p,M=a*m+u*_+l*p,w=i*m+s*_+f*p,x=r*y+o*T+c*R,C=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*v,D=a*A+u*S+l*v,L=i*A+s*S+f*v,F=r*N+o*O+c*g+h,B=a*N+u*O+l*g+d,b=i*N+s*O+f*g+E;return n[0]=I,n[1]=M,n[2]=w,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],_=t[4],p=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=a*h+u*d+l*E,v=i*h+s*d+f*E,N=r*m+o*_+c*p,O=a*m+u*_+l*p,g=i*m+s*_+f*p,I=r*y+o*T+c*R,M=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=N,n[5]=O,n[6]=g,n[7]=0,n[8]=I,n[9]=M,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var _=new e;l.multiplyByUniformScale=function(e,t,n){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var p=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,p),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],_=e[6],A=e[10],S=e[14],v=e[3],N=e[7],O=e[11],g=e[15],I=A*g,M=S*O,w=_*g,x=S*N,C=_*O,P=A*N,U=m*g,D=S*v,L=m*O,F=A*v,B=m*N,b=_*v,z=I*h+x*d+C*E-(M*h+w*d+P*E),q=M*f+U*d+F*E-(I*f+D*d+L*E),G=w*f+D*h+B*E-(x*f+U*h+b*E),W=P*f+L*h+b*d-(C*f+F*h+B*d),X=M*a+w*i+P*o-(I*a+x*i+C*o),H=I*r+D*i+L*o-(M*r+U*i+F*o),V=x*r+U*a+b*o-(w*r+D*a+B*o),Y=C*r+F*a+B*i-(P*r+L*a+b*i);I=i*E,M=o*d,w=a*E,x=o*h,C=a*d,P=i*h,U=r*E,D=o*f,L=r*d,F=i*f,B=r*h,b=a*f;var k=I*N+x*O+C*g-(M*N+w*O+P*g),Z=M*v+U*O+F*g-(I*v+D*O+L*g),j=w*v+D*N+B*g-(x*v+U*N+b*g),K=P*v+L*N+b*O-(C*v+F*N+B*O),J=w*A+P*S+M*_-(C*S+I*_+x*A),Q=L*S+I*m+D*A-(U*A+F*S+M*m),$=U*_+b*S+x*m-(B*S+w*m+D*_),ee=B*A+C*m+F*_-(L*_+b*A+P*m),te=r*z+a*q+i*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=X*te,n[5]=H*te,n[6]=V*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,_=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var _=t.cartesianToCartographic(e[E]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),h=Math.min(h,_.latitude),d=Math.max(d,_.latitude);var p=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,p),f=Math.max(f,p)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var _=1;_<8;++_)m.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,E=new e,m=new e,_=new e,p=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,N=new e;h.fromPoints=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,d),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,_),l=e.clone(i,p),f=e.clone(i,y),O=t.length;for(r=1;r<O;r++){e.clone(t[r],i);var g=i.x,I=i.y,M=i.z;g<o.x&&e.clone(i,o),g>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),M<s.z&&e.clone(i,s),M>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=v;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,N),G=0;for(r=0;r<O;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,R));W>G&&(G=W);var X=e.magnitudeSquared(e.subtract(i,L,R));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var V=H-B;L.x=(B*L.x+V*i.x)/H,L.y=(B*L.y+V*i.y)/H,L.z=(B*L.z+V*i.z)/H}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var O=new o,g=new e,I=new e,M=new t,w=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),f.southwest(t,M),M.height=i,f.northeast(t,w),w.height=o;var s=n.project(M,g),c=n.project(w,I),l=c.x-s.x,d=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*E,u};var x=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,x);return h.fromPoints(s,u)},h.fromVertices=function(t,n,i,o){if(a(o)||(o=new h),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,E),f=e.clone(u,m),O=e.clone(u,_),g=e.clone(u,p),I=e.clone(u,y),M=t.length;for(s=0;s<M;s+=i){var w=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=w,u.y=x,u.z=C,w<c.x&&e.clone(u,c),w>O.x&&e.clone(u,O),x<l.y&&e.clone(u,l),x>g.y&&e.clone(u,g),C<f.z&&e.clone(u,f),C>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(O,c,R)),U=e.magnitudeSquared(e.subtract(g,l,R)),D=e.magnitudeSquared(e.subtract(I,f,R)),L=c,F=O,B=P;U>B&&(B=U,L=l,F=g),D>B&&(B=D,L=f,F=I);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=v;W.x=O.x,W.y=g.y,W.z=I.z;var X=e.multiplyByScalar(e.add(G,W,R),.5,N),H=0;for(s=0;s<M;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var V=e.magnitude(e.subtract(u,X,R));V>H&&(H=V);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;b.x=(q*b.x+Z*u.x)/k,b.y=(q*b.y+Z*u.y)/k,b.z=(q*b.z+Z*u.z)/k}}return q<H?(e.clone(b,o.center),o.radius=q):(e.clone(X,o.center),o.radius=H),o},h.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new h),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,d),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,_),f=e.clone(i,p),O=e.clone(i,y),g=t.length;for(o=0;o<g;o+=3){var I=t[o]+n[o],M=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=I,i.y=M,i.z=w,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),M<s.y&&e.clone(i,s),M>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>O.z&&e.clone(i,O)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(O,c,R)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=O);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=v;q.x=l.x,q.y=f.y,q.z=O.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,N),W=0;for(o=0;o<g;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,G,R));X>W&&(W=X);var H=e.magnitudeSquared(e.subtract(i,F,R));if(H>B){var V=Math.sqrt(H);b=.5*(b+V),B=b*b;var Y=V-b;F.x=(b*F.x+Y*i.x)/V,F.y=(b*F.y+Y*i.y)/V,F.z=(b*F.z+Y*i.z)/V}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},h.fromCornerPoints=function(t,n,r){a(r)||(r=new h);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},h.fromEllipsoid=function(t,n){return a(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;h.fromBoundingSpheres=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;h.fromOrientedBoundingBox=function(t,n){a(n)||(n=new h);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},h.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new h);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;h.union=function(t,n,r){a(r)||(r=new h);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(d,i,d),e.clone(d,r.center),r.radius=f,r};var B=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,W=new e,X=new e,H=new e,V=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,H),d=e.negate(c,X),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,d,m),m=E[2],e.add(s,f,m),e.add(m,d,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,d,m),m=E[6],e.add(s,f,m),e.add(m,d,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var _=E.length,p=0;p<_;++p){var y=E[p];e.add(o,y,y);var T=i.cartesianToCartographic(y,V);n.project(T,y)}a=h.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(v)&&(v=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,N=r(e[1]))}return v}function u(){return o()&&N}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0,g=r(e[1]),g.isNightly=!!e[2])}return O}function c(){return s()&&g}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0, -M=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,M=r(e[1]))}return I}function f(){return l()&&M}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,x=r(e[1]))}return w}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function _(){return E()&&P}function p(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,N,O,g,I,M,w,x,C,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:_,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:p,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,a,i){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,i.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,a.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var a=e.attributes[r],i=a.values.length/a.componentsPerAttribute;t=i}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function a(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return a.POSITION_ONLY=r(new a({position:!0})),a.POSITION_AND_NORMAL=r(new a({position:!0,normal:!0})),a.POSITION_NORMAL_AND_ST=r(new a({position:!0,normal:!0,st:!0})),a.POSITION_AND_ST=r(new a({position:!0,st:!0})),a.POSITION_AND_COLOR=r(new a({position:!0,color:!0})),a.ALL=r(new a({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),a.DEFAULT=a.POSITION_NORMAL_AND_ST,a.packedLength=6,a.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},a.unpack=function(n,r,i){return r=e(r,0),t(i)||(i=new a),i.position=1===n[r++],i.normal=1===n[r++],i.st=1===n[r++],i.tangent=1===n[r++],i.bitangent=1===n[r++],i.color=1===n[r],i},a.clone=function(e,n){if(t(e))return t(n)||(n=new a),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},a}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,_=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(_,u),l=Math.max(_,l)}var p=n.minimum;p.x=a,p.y=o,p.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(p,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,_=u*c-d,p=4*E*_-m*m;if(p<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=_,R=-c*m+2*s*_);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-p);i=-R+S;var v=i/2,N=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),O=i===S?-N:-T/N;return a=T<=0?N+O:-R/(N*N+O*O+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var g=E,I=-2*u*E+o*m,M=_,w=-c*m+2*s*_,x=Math.sqrt(p),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-I)/3);a=2*Math.sqrt(-g);var U=Math.cos(P);i=a*U;var D=a*(-U/2-C*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*x,-w)/3),a=2*Math.sqrt(-M),U=Math.cos(P),i=a*U,D=a*(-U/2-C*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,X=L*b,H=(s*W-u*X)/(-u*W+s*G);return B<=H?B<=q?H<=q?[B,H,q]:[B,q,H]:[q,B,H]:B<=q?[H,B,q]:H<=q?[H,q,B]:[q,H,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,_=E[0],p=E[1];if(_>=0&&p>=0){var y=Math.sqrt(_),T=Math.sqrt(p);return[h-T,h-y,h+y,h+T]}if(_>=0&&p<0)return m=Math.sqrt(_),[h-m,h+m];if(_<0&&p>=0)return m=Math.sqrt(p),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),N=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==N.length?(N[0]+=h,N[1]+=h,v[1]<=N[0]?[v[0],v[1],N[0],N[1]]:N[1]<=v[0]?[N[0],N[1],v[0],v[1]]:v[0]>=N[0]&&v[1]<=N[1]?[N[0],v[0],v[1],N[1]]:N[0]>=v[0]&&N[1]<=v[1]?[v[0],N[0],N[1],v[1]]:v[0]>N[0]&&v[0]<N[1]?[N[0],v[0],N[1],v[1]]:[v[0],N[0],v[1],N[1]]):v):0!==N.length?(N[0]+=h,N[1]+=h,N):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,_=d[0],p=a-_,y=p*p,T=t/2,R=p/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*_,N=c+4*Math.abs(_);if(_<0||A*N<v*S){var O=Math.sqrt(v);E=O/2,m=0===O?0:(t*R-i)/O}else{var g=Math.sqrt(A);E=0===g?0:(t*R-i)/g,m=g/2}var I,M;0===T&&0===E?(I=0,M=0):n.sign(T)===n.sign(E)?(I=T+E,M=_/I):(M=T-E,I=_/M);var w,x;0===R&&0===m?(w=0,x=0):n.sign(R)===n.sign(m)?(w=R+m,x=o/w):(x=R-m,w=o/x);var C=r.computeRealRoots(1,I,w),P=r.computeRealRoots(1,M,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){ -var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),_=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,p=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===p){if(l=s.computeRealRoots(E,m,_),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-v)),T.push(new e(a,i*S,i*v))}return T}var N=y*y,O=p*p,g=E*E,I=y*p,M=g+O,w=2*(m*E+I),x=2*_*E+m*m-O+N,C=2*(_*m-I),P=_*_-N;if(0===M&&0===w&&0===x&&0===C)return T;l=c.computeRealRoots(M,w,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(_)?d(E*B+_,m*F,o.EPSILON12):o.sign(_)===o.sign(m*F)?d(E*B,m*F+_,o.EPSILON12):d(E*B+m*F,_,o.EPSILON12);var q=d(p*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var _=new e,p=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,_),A=e.subtract(i,r,p),S=e.cross(E,A,y),v=e.dot(m,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var N=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*N)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*N)<0||l+f>1)return;h=e.dot(A,c)*N}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;m.lineSegmentSphere=function(t,n,a,i){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var N=new e,O=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),f=e.multiplyComponents(c,t.direction,O),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,_=r/s;return m<_?new i(m,_):{start:_,stop:m}}var p=Math.sqrt(r/a);return new i(p,p)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var g=new e,I=new e,M=new e,w=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,g);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,g),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,I),I),m=e.normalize(e.cross(f,d,M),M),_=C;_[0]=f.x,_[1]=f.y,_[2]=f.z,_[3]=d.x,_[4]=d.y,_[5]=d.z,_[6]=m.x,_[7]=m.y,_[8]=m.z;var p=u.transpose(_,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,v=u.multiply(u.multiply(p,T,F),R,F),N=u.multiply(u.multiply(v,y,B),_,B),O=u.multiplyByVector(v,a,x),G=E(N,e.negate(O,g),0,0,1),W=G.length;if(W>0){for(var X=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,V=0;V<W;++V){A=u.multiplyByVector(y,u.multiplyByVector(_,G[V],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>H&&(H=k,X=e.clone(A,X))}var Z=n.cartesianToCartographic(X,q);return H=o.clamp(H,0,1),S=e.magnitude(e.subtract(X,a,w))*Math.sqrt(1-H*H),S=c?-S:S,Z.height=S,n.cartographicToCartesian(Z,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=p,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return _(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,_,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(_=d.progress,m=function(e){h.push(e),--l||(E=m=p,d.reject(h))},E=function(e){f.push(e),--c||(E=m=p,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,_);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return _(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function _(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function p(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,_,p;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,N=0;s&&N<v;N++)switch(s.charAt(N)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(N+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,p=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(p),y,c,f,R,S);case"c":return u(String.fromCharCode(+p),y,c,f,R);case"b":return o(p,2,A,y,c,f,R);case"o":return o(p,8,A,y,c,f,R);case"x":return o(p,16,A,y,c,f,R);case"X":return o(p,16,A,y,c,f,R).toUpperCase();case"u":return o(p,10,A,y,c,f,R);case"i":case"d":return d=+p||0,d=Math.round(d-d%1),E=d<0?"-":T,p=E+a(String(Math.abs(d)),f,"0",!1),i(p,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+p,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],_=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],p=E+Math.abs(d)[m](f),i(p,E,y,c,R)[_]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var _=new i,p=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,N=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+N.source,g=/^(\d{2}):?(\d{2})(\.\d+)?/.source+N.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+N.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,_=0,y=0,N=0,M=u[0],w=u[1];if(null!==(u=M.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=M.match(R)))n=+u[1],s=+u[2];else if(null!==(u=M.match(T)))n=+u[1];else{var x;if(null!==(u=M.match(A)))n=+u[1],x=+u[2],i=o(n);else if(null!==(u=M.match(S))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(x),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(I),null!==u?(h=+u[1],_=+u[2],y=+u[3],N=1e3*+(u[4]||0),D=5):(u=w.match(g),null!==u?(h=+u[1],_=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(O))&&(h=+u[1],_=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,_-=B;break;case"-":h+=F,_+=B;break;case"Z":break;default:_+=new Date(Date.UTC(n,s-1,l,h,_)).getTimezoneOffset()}}var b=60===y;for(b&&y--;_>=60;)_-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:p[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:p[s-1];for(;_<0;)_+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:p[s-1],l+=a;var z=E(n,s,l,h,_,y,N);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var M=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,M);r(a)||(m.addSeconds(e,-1,M),a=h(M,M),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var _=d+2-12*c|0,p=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=p,t.month=_,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(p,_,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,_),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,_);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return N[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function _(e){var t=d(e);return e.state=s.ACTIVE,v.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function p(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A);var v=[],N={},O="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();p(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=v.length;for(e=0;e<r;++e)t=v[e],t.cancelled&&p(t),t.state===s.ACTIVE?n>0&&(v[e-n]=t):++n;v.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-v.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?p(t):!t.throttleByServer||h(t.serverKey)?(_(t),++u):p(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=N[a];return r(i)||(N[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return _(e);if(!(v.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;p(t)}return d(e)}},l.clearForSpecs=function(){for(;S.length>0;){p(S.pop())}for(var e=v.length,t=0;t<e;++t)p(v[t]);v.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return N[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;a=n(a,t.url);var d=r(t.request)?t.request:new i;return d.url=a,d.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function d(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return h(a,i);case"blob":var o=h(a,i);return new Blob([o],{type:r});case"document": -return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&h.setRequestHeader(m,i[m]);r(t)&&(h.responseType=t);var _=!1;return"string"==typeof e&&(_=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!_||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(a),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var _=e._samples=n.samples,p=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=_.length;R<A;R+=e._columnCount){var S=_[R+a],v=_[R+m],N=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(N,v,f.TAI);if(p.push(O),T){if(v!==y&&r(y)){var g=o.leapSeconds,I=t(g,O,d);if(I<0){var M=new u(O,v);g.splice(~I,0,M)}}y=v}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function _(e,t,n){return t+e*(n-t)}function p(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],p=n[d+e._ut1MinusUtcSecondsColumn],y=p-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=p:p-=R-T)}return u.xPoleWander=_(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=_(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=_(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=_(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=_(f,E,p),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,p(this,i,this._samples,e,s,l,n),n}var _=t(i,e,o.compare,this._dateColumn);return _>=0?(_<i.length-1&&i[_+1].equals(e)&&++_,s=_,l=_):(l=~_,(s=l-1)<0&&(s=0)),this._lastIndex=s,p(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,_=i-s*this._stepSizeDays,p=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)p[E]=_-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=p[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var _=l,p=0;d>h&&(p=1),E>h&&E>d&&(p=2);var y=_[p],T=_[y];n=Math.sqrt(e[u.getElementIndex(p,p)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[p]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,p)]+e[u.getElementIndex(p,y)])*n,R[T]=(e[u.getElementIndex(T,p)]+e[u.getElementIndex(p,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var _=new e,p=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,_);var u=s.computeAngle(y);r[o]=_.x*u,r[o+1]=_.y*u,r[o+2]=_.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,p);var u=e.magnitude(p);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(p,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,N=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),N=s.multiplyByScalar(i,Math.sin(n*u),N),r=s.add(v,N,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var O=new e,g=new e,I=new s,M=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,I);s.multiply(i,r,M);var o=s.log(M,O);s.multiply(i,t,M);var u=s.log(M,g);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,I),u=s.slerp(n,r,a,M);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,x=1.9011074535173003,C=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;C[L]=1/(F*B),P[L]=F/B}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,I),u=s.fastSlerp(n,r,a,M);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,_,p,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},N={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,g=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(v[i])?r=v[i]:(r=function(r,i,s){if(u(s)||(s=new p),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(S[t],0,g),"east"!==t&&"west"!==t&&n.multiplyByScalar(g,c,g),n.unpack(S[a],0,I),"east"!==a&&"west"!==a&&n.multiplyByScalar(I,c,I)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,N.up);var l=N.up,h=N.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,N.east),n.cross(l,h,N.north),n.multiplyByScalar(N.up,-1,N.down),n.multiplyByScalar(N.east,-1,N.west),n.multiplyByScalar(N.north,-1,N.south),O=N[e],g=N[t],I=N[a]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=g.x,s[5]=g.y,s[6]=g.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var M=new y,w=new n(1,1,1),x=new p;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,M),s=p.fromTranslationQuaternionRotationScale(n.ZERO,u,w,x);return i=a(e,r,i),p.multiply(i,s,i)};var C=new p,P=new _;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=p.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new _(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new _);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return _.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new _,b=new _;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new _);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=_.fromRotationZ(-i.s,b),h=_.multiply(l,f,B),d=e.dayNumber,p=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=p/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var v=_.fromRotationZ(S,b),N=_.multiply(h,v,B),O=Math.cos(n.xPoleWander),g=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),M=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var x=-47e-6*w*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=b;return U[0]=O*C,U[1]=O*P,U[2]=I,U[3]=-g*P+M*I*C,U[4]=g*C+M*I*P,U[5]=-M*O,U[6]=-M*P-g*I*C,U[7]=M*C-g*I*P,U[8]=g*O,_.multiply(N,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return p.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),p.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new _),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var X=new p(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),H=new a,V=new n,Y=new n,k=new _,Z=new p,j=new p;return R.basisTo2D=function(e,t,r){var a=p.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,H),u=e.project(o,V);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,Z),c=p.inverseTransformation(s,j),l=p.getRotation(t,k),f=p.multiplyByMatrix3(c,l,r);return p.multiply(X,f,r),p.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,Z),o=p.inverseTransformation(i,j),u=a.cartesianToCartographic(t,H),s=e.project(u,V);n.fromElements(s.z,s.x,s.y,s);var c=p.fromTranslation(s,Z);return p.multiply(X,o,r),p.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var _=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,_).center,n)};var p=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=p;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=p;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,a){a=a||2;var i=n&&n.length,o=i?n[0]*a:e.length,u=t(e,0,o,a,!0),c=[];if(!u)return c;var l,f,h,d,E,m,_;if(i&&(u=s(e,n,u,a)),e.length>80*a){l=h=e[0],f=d=e[1];for(var p=a;p<o;p+=a)E=e[p],m=e[p+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);_=Math.max(h-l,d-f)}return r(u,c,a,l,f,_),c}function t(e,t,n,r,a){var i,o;if(a===M(e,t,n,r)>0)for(i=t;i<n;i+=r)o=O(i,e[i],e[i+1],o);else for(i=n-r;i>=t;i-=r)o=O(i,e[i],e[i+1],o);return o&&T(o,o.next)&&(g(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(g(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,_=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?i(e,c,l,f):a(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),g(e),e=m.next,_=m.next;else if((e=m)===_){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var a=e.next.next;a!==e.prev;){if(_(t.x,t.y,n.x,n.y,r.x,r.y,a.x,a.y)&&y(a.prev,a,a.next)>=0)return!1;a=a.next}return!0}function i(e,t,n,r){var a=e.prev,i=e,o=e.next;if(y(a,i,o)>=0)return!1;for(var u=a.x<i.x?a.x<o.x?a.x:o.x:i.x<o.x?i.x:o.x,s=a.y<i.y?a.y<o.y?a.y:o.y:i.y<o.y?i.y:o.y,c=a.x>i.x?a.x>o.x?a.x:o.x:i.x>o.x?i.x:o.x,l=a.y>i.y?a.y>o.y?a.y:o.y:i.y>o.y?i.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&_(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&_(a.x,a.y,i.x,i.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var a=r.prev,i=r.next.next;!T(a,i)&&R(a,r,r.next,i)&&S(a,i)&&S(i,a)&&(t.push(a.i/n),t.push(r.i/n),t.push(i.i/n),g(r),g(r.next),r=e=i),r=r.next}while(r!==e);return r}function u(e,t,a,i,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&p(s,c)){var l=N(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,a,i,o,u),void r(l,t,a,i,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,a,i){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*i,f=o<u-1?r[o+1]*i:e.length,h=t(e,s,f,i,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],a),a=n(a,a.next);return a}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=N(t,e);n(r,r.next)}}function f(e,t){var n,r=t,a=e.x,i=e.y,o=-1/0;do{if(i<=r.y&&i>=r.next.y){var u=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=a&&u>o){if(o=u,u===a){if(i===r.y)return r;if(i===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(a===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)a>=r.x&&r.x>=l&&_(i<f?a:o,i,l,f,i<f?o:a,i,r.x,r.y)&&((s=Math.abs(i-r.y)/(a-r.x))<h||s===h&&r.x>n.x)&&S(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var a=e;do{null===a.z&&(a.z=E(a.x,a.y,t,n,r)),a.prevZ=a.prev,a.nextZ=a.next,a=a.next}while(a!==e);a.prevZ.nextZ=null,a.prevZ=null,d(a)}function d(e){var t,n,r,a,i,o,u,s,c=1;do{for(n=e,e=null,i=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(a=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(a=n,n=n.nextZ,u--):(a=r,r=r.nextZ,s--):(a=n,n=n.nextZ,u--),i?i.nextZ=a:e=a,a.prevZ=i,i=a;n=r}i.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,a){return e=32767*(e-n)/a,t=32767*(t-r)/a,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function _(e,t,n,r,a,i,o,u){return(a-o)*(t-u)-(e-o)*(i-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(i-u)-(a-o)*(r-u)>=0}function p(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!A(e,t)&&S(e,t)&&S(t,e)&&v(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function A(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function S(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function v(e,t){var n=e,r=!1,a=(e.x+t.x)/2,i=(e.y+t.y)/2;do{n.y>i!=n.next.y>i&&a<(n.next.x-n.x)*(i-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function N(e,t){var n=new I(e.i,e.x,e.y),r=new I(t.i,t.x,t.y),a=e.next,i=t.prev;return e.next=t,t.prev=e,n.next=a,a.prev=n,r.next=n,n.prev=r,i.next=r,r.prev=i,r}function O(e,t,n,r){var a=new I(e,t,n);return r?(a.next=r.next,a.prev=r,r.next.prev=a,r.next=a):(a.prev=a,a.next=a),a}function g(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function M(e,t,n,r){for(var a=0,i=t,o=n-r;i<n;i+=r)a+=(e[o]-e[i])*(e[i+1]+e[o+1]),o=i;return a}return e.deviation=function(e,t,n,r){var a=t&&t.length,i=a?t[0]*n:e.length,o=Math.abs(M(e,0,i,n));if(a)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(M(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,a=0;a<e.length;a++){for(var i=0;i<e[a].length;i++)for(var o=0;o<t;o++)n.vertices.push(e[a][i][o]);a>0&&(r+=e[a-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}), -define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,a,i,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,a=0;a<t;r=a++){var i=e[r],o=e[a];n+=i.x*o.y-o.x*i.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var a=t.packArray(n);return e(a,r,2)};var _=new n,p=new n,y=new n,T=new n,R=new n,A=new n,S=new n;return m.computeSubdivision=function(e,t,r,u){u=i(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),v=0;for(h=0;h<E;h++){var N=t[h];m[v++]=N.x,m[v++]=N.y,m[v++]=N.z}for(var O=[],g={},I=e.maximumRadius,M=l.chordLength(u,I),w=M*M;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,_),F=n.fromArray(m,3*U,p),B=n.fromArray(m,3*P,y),b=n.multiplyByScalar(n.normalize(L,T),I,T),z=n.multiplyByScalar(n.normalize(F,R),I,R),q=n.multiplyByScalar(n.normalize(B,A),I,A),G=n.magnitudeSquared(n.subtract(b,z,S)),W=n.magnitudeSquared(n.subtract(z,q,S)),X=n.magnitudeSquared(n.subtract(q,b,S)),H=Math.max(G,W,X);H>w?G===H?(x=Math.min(D,U)+" "+Math.max(D,U),h=g[x],o(h)||(C=n.add(L,F,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,g[x]=h),d.push(D,h,P),d.push(h,U,P)):W===H?(x=Math.min(U,P)+" "+Math.max(U,P),h=g[x],o(h)||(C=n.add(F,B,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,g[x]=h),d.push(U,h,D),d.push(h,P,D)):X===H&&(x=Math.min(P,D)+" "+Math.max(P,D),h=g[x],o(h)||(C=n.add(B,L,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,g[x]=h),d.push(P,h,U),d.push(h,D,U)):(O.push(D),O.push(U),O.push(P))}return new s({attributes:{position:new c({componentDatatype:a.DOUBLE,componentsPerAttribute:3,values:m})},indices:O,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,a){r=i(r,u.WGS84);var s=d,c=E;if(t=i(t,0),a=i(a,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),a&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,a=(n-r)/n,i=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-a)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,i),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,_=m*m,p=_*m,y=_*_,T=1+m-3*_/4+5*p/4-175*y/64,R=1-m+15*_/8-35*p/8,A=1-3*m+35*_/4,S=1-5*m,v=T*l-R*Math.sin(2*l)*m/2-A*Math.sin(4*l)*_/16-S*Math.sin(6*l)*p/48-5*Math.sin(8*l)*y/512,N=e._constants;N.a=n,N.b=r,N.f=a,N.cosineHeading=i,N.sineHeading=o,N.tanU=u,N.cosineU=s,N.sineU=c,N.sigma=l,N.sineAlpha=f,N.sineSquaredAlpha=h,N.cosineSquaredAlpha=d,N.cosineAlpha=E,N.u2Over4=m,N.u4Over16=_,N.u6Over64=p,N.u8Over256=y,N.a0=T,N.a1=R,N.a2=A,N.a3=S,N.distanceRatio=v}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,a,i,o){var u=c(e,n);return(1-u)*e*t*(r+u*a*(o+u*i*(2*o*o-1)))}function f(e,t,n,r,a,i,o){var s,c,f,h,d,E=(t-n)/t,m=i-r,_=Math.atan((1-E)*Math.tan(a)),p=Math.atan((1-E)*Math.tan(o)),y=Math.cos(_),T=Math.sin(_),R=Math.cos(p),A=Math.sin(p),S=y*R,v=y*A,N=T*A,O=T*R,g=m,I=u.TWO_PI,M=Math.cos(g),w=Math.sin(g);do{M=Math.cos(g),w=Math.sin(g);var x=v-O*M;f=Math.sqrt(R*R*w*w+x*x),c=N+S*M,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=S*w/f,h=1-C*C),I=g,d=c-2*N/h,isNaN(d)&&(d=0),g=m+l(E,C,h,s,f,c,d)}while(Math.abs(g-I)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),B=n*U*(s-F),b=Math.atan2(R*w,v-O*M),z=Math.atan2(y*w,v*M-O);e._distance=B,e._startHeading=b,e._endHeading=z,e._uSquared=P}function h(n,r,a,i){e.normalize(i.cartographicToCartesian(r,m),E),e.normalize(i.cartographicToCartesian(a,m),m);f(n,i.maximumRadius,i.minimumRadius,r.longitude,r.latitude,a.longitude,a.latitude),n._start=t.clone(r,n._start),n._end=t.clone(a,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,i){var u=r(i,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,a(e)&&a(n)&&h(this,e,n,u)}var E=new e,m=new e;return i(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,i=r.distanceRatio+e/r.b,o=Math.cos(2*i),u=Math.cos(4*i),s=Math.cos(6*i),c=Math.sin(2*i),f=Math.sin(4*i),h=Math.sin(6*i),d=Math.sin(8*i),E=i*i,m=i*E,_=r.u8Over256,p=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*_*o/3+i*(1-p+7*T/4-15*y/4+579*_/64-(T-15*y/4+187*_/16)*o-(5*y/4-115*_/16)*u-29*_*s/16)+(p/2-T+71*y/32-85*_/16)*c+(5*T/16-5*y/4+383*_/96)*f-E*((y-11*_/2)*c+5*_*f/2)+(29*y/96-29*_/16)*h+539*_*d/1536,A=Math.asin(Math.sin(R)*r.cosineAlpha),S=Math.atan(r.a/r.b*Math.tan(A));R-=r.sigma;var v=Math.cos(2*r.sigma+R),N=Math.sin(R),O=Math.cos(R),g=r.cosineU*O,I=r.sineU*N,M=Math.atan2(N*r.sineHeading,g-I*r.cosineHeading),w=M-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,N,O,v);return a(n)?(n.longitude=this._start.longitude+w,n.latitude=S,n.height=0,n):new t(this._start.longitude+w,S,0)},d}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=N;r.length=e;var a;if(t===n){for(a=0;a<e;a++)r[a]=t;return r}var i=n-t,o=i/e;for(a=0;a<e;a++){var u=t+a*o;r[a]=u}return r}function d(t,n,r,a,i,o,u,s){var c=a.scaleToGeodeticSurface(t,M),l=a.scaleToGeodeticSurface(n,w),f=E.numberOfPoints(t,n,r),d=a.cartesianToCartographic(c,O),m=a.cartesianToCartographic(l,g),_=h(f,i,o);x.setEndPoints(d,m);var p=x.surfaceDistance/f,y=s;d.height=i;var T=a.cartographicToCartesian(d,I);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var A=x.interpolateUsingSurfaceDistance(R*p,g);A.height=_[R],T=a.cartographicToCartesian(A,I),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var a=e.distance(t,n);return Math.ceil(a/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),a=0;a<n;a++){var i=e[a];r[a]=t.cartesianToCartographic(i,m).height}return r};var _=new l,p=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,A=new f(e.UNIT_X,0),S=new e,v=new e,N=[],O=new t,g=new t,I=new e,M=new e,w=new e,x=new o;return E.wrapLongitude=function(t,a){var i=[],o=[];if(r(t)&&t.length>0){a=n(a,l.IDENTITY);var s=l.inverseTransformation(a,_),c=l.multiplyByPoint(s,e.ZERO,p),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,A),N=1;i.push(e.clone(t[0]));for(var O=i[0],g=t.length,I=1;I<g;++I){var M=t[I];if(f.getPointDistance(m,O)<0||f.getPointDistance(m,M)<0){var w=u.lineSegmentPlane(O,M,d,S);if(r(w)){var x=e.multiplyByScalar(h,5e-9,v);f.getPointDistance(d,O)<0&&e.negate(x,x),i.push(e.add(w,x,new e)),o.push(N+1),e.negate(x,x),i.push(e.add(w,x,new e)),N=1}}i.push(e.clone(t[I])),N++,O=M}o.push(N)}return{positions:i,lengths:o}},E.generateArc=function(t){r(t)||(t={});var a=t.positions,o=a.length,u=n(t.ellipsoid,i.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(a[0],M);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,I);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var _=t.minDistance;if(!r(_)){var p=n(t.granularity,c.RADIANS_PER_DEGREE);_=c.chordLength(p,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(a[y],a[y+1],_);var R=3*(T+1),A=new Array(R),S=0;for(y=0;y<o-1;y++){S=d(a[y],a[y+1],_,u,f?l[y]:l,f?l[y+1]:l,A,S)}N.length=0;var v=a[o-1],g=u.cartesianToCartographic(v,O);g.height=f?l[o-1]:l;var w=u.cartographicToCartesian(g,I);return e.pack(w,A,R-3),A},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,a=new Array(r),i=0;i<r;i++)a[i]=e.unpack(n,3*i);return a},E}),define("Core/WallGeometryLibrary",["./Cartographic","./defined","./EllipsoidTangentPlane","./Math","./PolygonPipeline","./PolylinePipeline","./WindingOrder"],function(e,t,n,r,a,i,o){"use strict";function u(e,t){return r.equalsEpsilon(e.latitude,t.latitude,r.EPSILON14)&&r.equalsEpsilon(e.longitude,t.longitude,r.EPSILON14)}function s(n,r,a,i){var o=r.length;if(!(o<2)){var s=t(i),c=t(a),h=!0,d=new Array(o),E=new Array(o),m=new Array(o),_=r[0];d[0]=_;var p=n.cartesianToCartographic(_,l);c&&(p.height=a[0]),h=h&&p.height<=0,E[0]=p.height,m[0]=s?i[0]:0;for(var y=1,T=1;T<o;++T){var R=r[T],A=n.cartesianToCartographic(R,f);c&&(A.height=a[T]),h=h&&A.height<=0,u(p,A)?p.height<A.height&&(E[y-1]=A.height):(d[y]=R,E[y]=A.height,m[y]=s?i[T]:0,e.clone(A,p),++y)}if(!(h||y<2))return d.length=y,E.length=y,m.length=y,{positions:d,topHeights:E,bottomHeights:m}}}var c={},l=new e,f=new e,h=new Array(2),d=new Array(2),E={positions:void 0,height:void 0,granularity:void 0,ellipsoid:void 0};return c.computePositions=function(e,u,c,l,f,m){var _=s(e,u,c,l);if(t(_)){if(u=_.positions,c=_.topHeights,l=_.bottomHeights,u.length>=3){var p=n.fromPoints(u,e),y=p.projectPointsOntoPlane(u);a.computeWindingOrder2D(y)===o.CLOCKWISE&&(u.reverse(),c.reverse(),l.reverse())}var T,R,A=u.length,S=A-2,v=r.chordLength(f,e.maximumRadius),N=E;if(N.minDistance=v,N.ellipsoid=e,m){var O,g=0;for(O=0;O<A-1;O++)g+=i.numberOfPoints(u[O],u[O+1],v)+1;T=new Float64Array(3*g),R=new Float64Array(3*g);var I=h,M=d;N.positions=I,N.height=M;var w=0;for(O=0;O<A-1;O++){I[0]=u[O],I[1]=u[O+1],M[0]=c[O],M[1]=c[O+1];var x=i.generateArc(N);T.set(x,w),M[0]=l[O],M[1]=l[O+1],R.set(i.generateArc(N),w),w+=x.length}}else N.positions=u,N.height=c,T=new Float64Array(i.generateArc(N)),N.height=l,R=new Float64Array(i.generateArc(N));return{bottomPositions:R,topPositions:T,numCorners:S}}},c}),define("Core/WallGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat","./WallGeometryLibrary"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E){"use strict";function m(e){e=r(e,r.EMPTY_OBJECT);var n=e.positions,i=e.maximumHeights,u=e.minimumHeights,s=r(e.vertexFormat,d.DEFAULT),c=r(e.granularity,f.RADIANS_PER_DEGREE),l=r(e.ellipsoid,o.WGS84);this._positions=n,this._minimumHeights=u,this._maximumHeights=i,this._vertexFormat=d.clone(s),this._granularity=c,this._ellipsoid=o.clone(l),this._workerName="createWallGeometry";var h=1+n.length*t.packedLength+2;a(u)&&(h+=u.length),a(i)&&(h+=i.length),this.packedLength=h+o.packedLength+d.packedLength+1}var _=new t,p=new t,y=new t,T=new t,R=new t,A=new t,S=new t,v=new t;m.pack=function(e,n,i){i=r(i,0);var u,s=e._positions,c=s.length;for(n[i++]=c,u=0;u<c;++u,i+=t.packedLength)t.pack(s[u],n,i);var l=e._minimumHeights;if(c=a(l)?l.length:0,n[i++]=c,a(l))for(u=0;u<c;++u)n[i++]=l[u];var f=e._maximumHeights;if(c=a(f)?f.length:0,n[i++]=c,a(f))for(u=0;u<c;++u)n[i++]=f[u];return o.pack(e._ellipsoid,n,i),i+=o.packedLength,d.pack(e._vertexFormat,n,i),i+=d.packedLength,n[i]=e._granularity,n};var N=o.clone(o.UNIT_SPHERE),O=new d,g={positions:void 0,minimumHeights:void 0,maximumHeights:void 0,ellipsoid:N,vertexFormat:O,granularity:void 0};return m.unpack=function(e,n,i){n=r(n,0);var u,s=e[n++],c=new Array(s);for(u=0;u<s;++u,n+=t.packedLength)c[u]=t.unpack(e,n);s=e[n++];var l;if(s>0)for(l=new Array(s),u=0;u<s;++u)l[u]=e[n++];s=e[n++];var f;if(s>0)for(f=new Array(s),u=0;u<s;++u)f[u]=e[n++];var h=o.unpack(e,n,N);n+=o.packedLength;var E=d.unpack(e,n,O);n+=d.packedLength;var _=e[n];return a(i)?(i._positions=c,i._minimumHeights=l,i._maximumHeights=f,i._ellipsoid=o.clone(h,i._ellipsoid),i._vertexFormat=d.clone(E,i._vertexFormat),i._granularity=_,i):(g.positions=c,g.minimumHeights=l,g.maximumHeights=f,g.granularity=_,new m(g))},m.fromConstantHeights=function(e){e=r(e,r.EMPTY_OBJECT);var t,n,i=e.positions,o=e.minimumHeight,u=e.maximumHeight,s=a(o),c=a(u);if(s||c){var l=i.length;t=s?new Array(l):void 0,n=c?new Array(l):void 0;for(var f=0;f<l;++f)s&&(t[f]=o),c&&(n[f]=u)}return new m({positions:i,maximumHeights:n,minimumHeights:t,ellipsoid:e.ellipsoid,vertexFormat:e.vertexFormat})},m.createGeometry=function(r){var i=r._positions,o=r._minimumHeights,d=r._maximumHeights,m=r._vertexFormat,N=r._granularity,O=r._ellipsoid,g=E.computePositions(O,i,d,o,N,!0);if(a(g)){var I=g.bottomPositions,M=g.topPositions,w=g.numCorners,x=M.length,C=2*x,P=m.position?new Float64Array(C):void 0,U=m.normal?new Float32Array(C):void 0,D=m.tangent?new Float32Array(C):void 0,L=m.bitangent?new Float32Array(C):void 0,F=m.st?new Float32Array(C/3*2):void 0,B=0,b=0,z=0,q=0,G=0,W=v,X=S,H=A,V=!0;x/=3;var Y,k=0,Z=1/(x-i.length+1);for(Y=0;Y<x;++Y){var j=3*Y,K=t.fromArray(M,j,_),J=t.fromArray(I,j,p);if(m.position&&(P[B++]=J.x,P[B++]=J.y,P[B++]=J.z,P[B++]=K.x,P[B++]=K.y,P[B++]=K.z),m.st&&(F[G++]=k,F[G++]=0,F[G++]=k,F[G++]=1),m.normal||m.tangent||m.bitangent){var Q,$=t.clone(t.ZERO,R),ee=O.scaleToGeodeticSurface(t.fromArray(M,j,p),p);if(Y+1<x&&(Q=O.scaleToGeodeticSurface(t.fromArray(M,j+3,y),y),$=t.fromArray(M,j+3,R)),V){var te=t.subtract($,K,T),ne=t.subtract(ee,K,_);W=t.normalize(t.cross(ne,te,W),W),V=!1}t.equalsEpsilon(Q,ee,f.EPSILON10)?V=!0:(k+=Z,m.tangent&&(X=t.normalize(t.subtract(Q,ee,X),X)),m.bitangent&&(H=t.normalize(t.cross(W,X,H),H))),m.normal&&(U[b++]=W.x,U[b++]=W.y,U[b++]=W.z,U[b++]=W.x,U[b++]=W.y,U[b++]=W.z),m.tangent&&(D[q++]=X.x,D[q++]=X.y,D[q++]=X.z,D[q++]=X.x,D[q++]=X.y,D[q++]=X.z),m.bitangent&&(L[z++]=H.x,L[z++]=H.y,L[z++]=H.z,L[z++]=H.x,L[z++]=H.y,L[z++]=H.z)}}var re=new c;m.position&&(re.position=new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:P})),m.normal&&(re.normal=new s({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:U})),m.tangent&&(re.tangent=new s({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:D})),m.bitangent&&(re.bitangent=new s({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:L})),m.st&&(re.st=new s({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:F}));var ae=C/3;C-=6*(w+1);var ie=l.createTypedArray(ae,C),oe=0;for(Y=0;Y<ae-2;Y+=2){var ue=Y,se=Y+2,ce=t.fromArray(P,3*ue,_),le=t.fromArray(P,3*se,p);if(!t.equalsEpsilon(ce,le,f.EPSILON10)){var fe=Y+1,he=Y+3;ie[oe++]=fe,ie[oe++]=ue,ie[oe++]=he,ie[oe++]=he,ie[oe++]=ue,ie[oe++]=se}}return new u({attributes:re,indices:ie,primitiveType:h.TRIANGLES,boundingSphere:new e.fromVertices(P)})}},m}),define("Workers/createWallGeometry",["../Core/defined","../Core/Ellipsoid","../Core/WallGeometry"],function(e,t,n){"use strict";function r(r,a){return e(a)&&(r=n.unpack(r,a)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,E=i.y,m=i.z,p=l*l*d*d,_=f*f*E*E,y=h*h*m*m,T=p+_+y,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,g=u.z,O=o;O.x=v.x*A*2,O.y=v.y*S*2,O.z=v.z*g*2;var N,I,M,w,C,x,P,U,D,L,F,b=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),B=0;do{b-=B,M=1/(1+b*A),w=1/(1+b*S),C=1/(1+b*g),x=M*M,P=w*w,U=C*C,D=x*M,L=P*w,F=U*C,N=p*x+_*P+y*U-1,I=p*D*A+_*L*S+y*F*g;B=N/(-2*I)}while(Math.abs(N)>r.EPSILON12);return t(c)?(c.x=l*M,c.y=f*w,c.z=h*C,c):new e(l*M,f*w,h*C)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),v=Math.asin(y.z),A=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=v,i.height=A,i):new u(R,v,A)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,E),u=e.subtract(n,a,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],E[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=E[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(i-h),p=2*(a+l),_=2*(i+h),y=-n+u-f+d,T=2*(c-o),R=2*(a-l),v=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=v,t[6]=p,t[7]=T,t[8]=A,t):new s(E,m,p,_,y,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,E=a*i+c*o*u,m=-c*i+a*o*u,p=-o,_=c*n,y=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),v=2*(f+m),A=2*(c+_),S=-s+d-p+y,g=2*(E-h),O=2*(f-m),N=2*(E+h),I=-s-d+p+y;return r[0]=T*a,r[1]=A*a,r[2]=O*a,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=N*o,r[7]=0,r[8]=v*u,r[9]=g*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,v=r.y,A=r.z,S=u*-R+s*-v+c*-A,g=_*-R+y*-v+T*-A,O=E*R+m*v+p*A;return i(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=S,n[13]=g,n[14]=O,n[15]=1,n):new l(u,s,c,S,_,y,T,g,-E,-m,-p,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=a+c,p=o+l,_=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=m,i[13]=p,i[14]=_,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],g=t[5],O=t[6],N=t[7],I=t[8],M=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*v+m*A,F=i*T+s*R+h*v+p*A,b=a*T+c*R+d*v+_*A,B=o*T+l*R+E*v+y*A,z=r*S+u*g+f*O+m*N,q=i*S+s*g+h*O+p*N,G=a*S+c*g+d*O+_*N,W=o*S+l*g+E*O+y*N,X=r*I+u*M+f*w+m*C,V=i*I+s*M+h*w+p*C,H=a*I+c*M+d*w+_*C,Y=o*I+l*M+E*w+y*C,k=r*x+u*P+f*U+m*D,j=i*x+s*P+h*U+p*D,Z=a*x+c*P+d*U+_*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=b,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=X,n[9]=V,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],g=t[12],O=t[13],N=t[14],I=r*m+o*p+c*_,M=i*m+u*p+l*_,w=a*m+s*p+f*_,C=r*y+o*T+c*R,x=i*y+u*T+l*R,P=a*y+s*T+f*R,U=r*v+o*A+c*S,D=i*v+u*A+l*S,L=a*v+s*A+f*S,F=r*g+o*O+c*N+h,b=i*g+u*O+l*N+d,B=a*g+s*O+f*N+E;return n[0]=I,n[1]=M,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=b,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],v=r*h+o*d+c*E,A=i*h+u*d+l*E,S=a*h+s*d+f*E,g=r*m+o*p+c*_,O=i*m+u*p+l*_,N=a*m+s*p+f*_,I=r*y+o*T+c*R,M=i*y+u*T+l*R,w=a*y+s*T+f*R;return n[0]=v,n[1]=A,n[2]=S,n[3]=0,n[4]=g,n[5]=O,n[6]=N,n[7]=0,n[8]=I,n[9]=M,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],v=e[10],A=e[14],S=e[3],g=e[7],O=e[11],N=e[15],I=v*N,M=A*O,w=p*N,C=A*g,x=p*O,P=v*g,U=m*N,D=A*S,L=m*O,F=v*S,b=m*g,B=p*S,z=I*h+C*d+x*E-(M*h+w*d+P*E),q=M*f+U*d+F*E-(I*f+D*d+L*E),G=w*f+D*h+b*E-(C*f+U*h+B*E),W=P*f+L*h+B*d-(x*f+F*h+b*d),X=M*i+w*a+P*o-(I*i+C*a+x*o),V=I*r+D*a+L*o-(M*r+U*a+F*o),H=C*r+U*i+B*o-(w*r+D*i+b*o),Y=x*r+F*i+b*a-(P*r+L*i+B*a);I=a*E,M=o*d,w=i*E,C=o*h,x=i*d,P=a*h,U=r*E,D=o*f,L=r*d,F=a*f,b=r*h,B=i*f;var k=I*g+C*O+x*N-(M*g+w*O+P*N),j=M*S+U*O+F*N-(I*S+D*O+L*N),Z=w*S+D*g+b*N-(C*S+U*g+B*N),K=P*S+L*g+B*O-(x*S+F*g+b*O),J=w*v+P*A+M*p-(x*A+I*p+C*v),Q=L*A+I*m+D*v-(U*v+F*A+M*m),$=U*p+B*A+C*m-(b*A+w*m+D*p),ee=b*v+x*m+F*p-(L*p+B*v+P*m),te=r*z+i*q+a*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=X*te,n[5]=V*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-i*d,m=-a*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,E),o=Math.max(o,E)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=i,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,v=new e,A=new e,S=new e,g=new e,O=new e,N=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,E),u=e.clone(i,m),s=e.clone(i,p),c=e.clone(i,_),l=e.clone(i,y),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var N=i.x,I=i.y,M=i.z;N<o.x&&e.clone(i,o),N>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),M<s.z&&e.clone(i,s),M>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,v)),C=e.magnitudeSquared(e.subtract(l,u,v)),x=e.magnitudeSquared(e.subtract(f,s,v)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,v)),b=Math.sqrt(F),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,v),.5,O),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,v));W>G&&(G=W);var X=e.magnitudeSquared(e.subtract(i,L,v));if(X>F){var V=Math.sqrt(X);b=.5*(b+V),F=b*b;var H=V-b;L.x=(b*L.x+H*i.x)/V,L.y=(b*L.y+H*i.y)/V,L.z=(b*L.z+H*i.z)/V}}return b<G?(e.clone(L,n.center),n.radius=b):(e.clone(q,n.center),n.radius=G),n};var I=new u,M=new e,w=new e,C=new t,x=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,I),h.southwest(t,C),C.height=r,h.northeast(t,x),x.height=o;var s=n.project(C,M),c=n.project(x,w),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,m),f=e.clone(u,p),h=e.clone(u,_),N=e.clone(u,y),I=e.clone(u,T),M=t.length;for(s=0;s<M;s+=r){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>h.x&&e.clone(u,h),C<l.y&&e.clone(u,l),C>N.y&&e.clone(u,N),x<f.z&&e.clone(u,f),x>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(h,c,v)),U=e.magnitudeSquared(e.subtract(N,l,v)),D=e.magnitudeSquared(e.subtract(I,f,v)),L=c,F=h,b=P;U>b&&(b=U,L=l,F=N),D>b&&(b=D,L=f,F=I);var B=A;B.x=.5*(L.x+F.x),B.y=.5*(L.y+F.y),B.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,v)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=g;W.x=h.x,W.y=N.y,W.z=I.z;var X=e.multiplyByScalar(e.add(G,W,v),.5,O),V=0;for(s=0;s<M;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,v));H>V&&(V=H);var Y=e.magnitudeSquared(e.subtract(u,B,v));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;B.x=(q*B.x+j*u.x)/k,B.y=(q*B.y+j*u.y)/k,B.z=(q*B.z+j*u.z)/k}}return q<V?(e.clone(B,o.center),o.radius=q):(e.clone(X,o.center),o.radius=V),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),h=e.clone(i,T),N=t.length;for(o=0;o<N;o+=3){var I=t[o]+n[o],M=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=I,i.y=M,i.z=w,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),M<s.y&&e.clone(i,s),M>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>h.z&&e.clone(i,h)}var C=e.magnitudeSquared(e.subtract(l,u,v)),x=e.magnitudeSquared(e.subtract(f,s,v)),P=e.magnitudeSquared(e.subtract(h,c,v)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var b=e.magnitudeSquared(e.subtract(D,F,v)),B=Math.sqrt(b),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,v),.5,O),W=0;for(o=0;o<N;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,G,v));X>W&&(W=X);var V=e.magnitudeSquared(e.subtract(i,F,v));if(V>b){var H=Math.sqrt(V);B=.5*(B+H),b=B*B;var Y=H-B;F.x=(B*F.x+Y*i.x)/H,F.y=(B*F.y+Y*i.y)/H,F.z=(B*F.z+Y*i.z)/H}}return B<W?(e.clone(F,r.center),r.radius=B):(e.clone(G,r.center),r.radius=W),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var b=new e,B=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,b),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var W=new e,X=new e,V=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,W),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=a.cartesianToCartographic(y,k);n.project(T,y)}r=d.fromPoints(E,r),o=r.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return N*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(v)&&(v=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,g=r(e[1]))}return S}function u(){return o()&&g}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0, +N=r(e[1]),N.isNightly=!!e[2])}return O}function c(){return s()&&N}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,M=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,M=r(e[1]))}return I}function f(){return l()&&M}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,g,O,N,I,M,w,C,x,P,U,D,L,F,b={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return b.supportsFullscreen=function(){return n.supportsFullscreen()},b.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},b.supportsWebWorkers=function(){return"undefined"!=typeof Worker},b}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/VertexFormat",["./defaultValue","./defined","./DeveloperError","./freezeObject"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT),this.position=e(t.position,!1),this.normal=e(t.normal,!1),this.st=e(t.st,!1),this.bitangent=e(t.bitangent,!1),this.tangent=e(t.tangent,!1),this.color=e(t.color,!1)}return i.POSITION_ONLY=r(new i({position:!0})),i.POSITION_AND_NORMAL=r(new i({position:!0,normal:!0})),i.POSITION_NORMAL_AND_ST=r(new i({position:!0,normal:!0,st:!0})),i.POSITION_AND_ST=r(new i({position:!0,st:!0})),i.POSITION_AND_COLOR=r(new i({position:!0,color:!0})),i.ALL=r(new i({position:!0,normal:!0,st:!0,tangent:!0,bitangent:!0})),i.DEFAULT=i.POSITION_NORMAL_AND_ST,i.packedLength=6,i.pack=function(t,n,r){return r=e(r,0),n[r++]=t.position?1:0,n[r++]=t.normal?1:0,n[r++]=t.st?1:0,n[r++]=t.tangent?1:0,n[r++]=t.bitangent?1:0,n[r]=t.color?1:0,n},i.unpack=function(n,r,a){return r=e(r,0),t(a)||(a=new i),a.position=1===n[r++],a.normal=1===n[r++],a.st=1===n[r++],a.tangent=1===n[r++],a.bitangent=1===n[r++],a.color=1===n[r],a},i.clone=function(e,n){if(t(e))return t(n)||(n=new i),n.position=e.position,n.normal=e.normal,n.st=e.st,n.tangent=e.tangent,n.bitangent=e.bitangent,n.color=e.color,n},i}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;i=Math.min(E,i),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=i,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,_=4*E*p-m*m;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var v=R<0?-1:1,A=-v*Math.abs(y)*Math.sqrt(-_);a=-R+A;var S=a/2,g=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),O=a===A?-g:-T/g;return i=T<=0?g+O:-R/(g*g+O*O+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var N=E,I=-2*u*E+o*m,M=p,w=-c*m+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-I)/3);i=2*Math.sqrt(-N);var U=Math.cos(P);a=i*U;var D=i*(-U/2-x*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,b=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),i=2*Math.sqrt(-M),U=Math.cos(P),a=i*U,D=i*(-U/2-x*Math.sin(P));var B=-c,z=a+D<2*s?a+s:D+s,q=B/z,G=F*z,W=-L*z-F*B,X=L*B,V=(s*W-u*X)/(-u*W+s*G);return b<=V?b<=q?V<=q?[b,V,q]:[b,q,V]:[q,b,V]:b<=q?[V,b,q]:V<=q?[V,q,b]:[q,V,b]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),v=(s+d-c/R)/2,A=(s+d+c/R)/2,S=r.computeRealRoots(1,R,v),g=r.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,S[1]<=g[0]?[S[0],S[1],g[0],g[1]]:g[1]<=S[0]?[g[0],g[1],S[0],S[1]]:S[0]>=g[0]&&S[1]<=g[1]?[g[0],S[0],S[1],g[1]]:g[0]>=S[0]&&g[1]<=S[1]?[S[0],g[0],g[1],S[1]]:S[0]>g[0]&&S[0]<g[1]?[g[0],S[0],g[1],S[1]]:[S[0],g[0],S[1],g[1]]):S):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],_=i-p,y=_*_,T=t/2,R=_/2,v=y-4*o,A=y+4*Math.abs(o),S=c-4*p,g=c+4*Math.abs(p);if(p<0||v*g<S*A){var O=Math.sqrt(S);E=O/2,m=0===O?0:(t*R-a)/O}else{var N=Math.sqrt(v);E=0===N?0:(t*R-a)/N,m=N/2}var I,M;0===T&&0===E?(I=0,M=0):n.sign(T)===n.sign(E)?(I=T+E,M=p/I):(M=T-E,I=p/M);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,I,w),P=r.computeRealRoots(1,M,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,A);if(r(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r} +function E(t,n,r,i,a){var l,f=i*i,h=a*a,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-v)),T.push(new e(i,a*R,a*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(i,a*A,a*-S)),T.push(new e(i,a*A,a*S))}return T}var g=y*y,O=_*_,N=E*E,I=y*_,M=N+O,w=2*(m*E+I),C=2*p*E+m*m-O+g,x=2*(p*m-I),P=p*p-g;if(0===M&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(M,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],b=F*F,B=Math.max(1-b,0),z=Math.sqrt(B);L=o.sign(E)===o.sign(p)?d(E*b+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?d(E*b,m*F+p,o.EPSILON12):d(E*b+m*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var m={};m.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(i,r,p),v=e.subtract(a,r,_),A=e.cross(E,v,y),S=e.dot(m,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>S)return;h=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var g=1/S;if(s=e.subtract(d,r,T),(l=e.dot(s,A)*g)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*g)<0||l+f>1)return;h=e.dot(v,c)*g}return h},m.rayTriangle=function(t,n,i,a,o,u){var s=m.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;m.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;m.lineSegmentSphere=function(t,n,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,O=new e;m.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,O),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,p=r/s;return m<p?new a(m,p):{start:p,stop:m}}var _=Math.sqrt(r/i);return new a(_,_)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var N=new e,I=new e,M=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,b=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,N);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,N),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,I),I),m=e.normalize(e.cross(f,d,M),M),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var v,A,S=u.multiply(u.multiply(_,T,F),R,F),g=u.multiply(u.multiply(S,y,b),p,b),O=u.multiplyByVector(S,i,C),G=E(g,e.negate(O,N),0,0,1),W=G.length;if(W>0){for(var X=e.clone(e.ZERO,z),V=Number.NEGATIVE_INFINITY,H=0;H<W;++H){v=u.multiplyByVector(y,u.multiplyByVector(p,G[H],B),B);var Y=e.normalize(e.subtract(v,i,w),w),k=e.dot(Y,a);k>V&&(V=k,X=e.clone(v,X))}var j=n.cartesianToCartographic(X,q);return V=o.clamp(V,0,1),A=e.magnitude(e.subtract(X,i,w))*Math.sqrt(1-V*V),A=c?-A:A,j.height=A,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function i(e){return E(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=_,m(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=_,d.reject(h))},E=function(e){f.push(e),--c||(E=m=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function E(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,v=!1,A=" ",S=s.length,g=0;s&&g<S;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":A=s.charAt(g+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,A);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,v,y,c,f,R);case"o":return o(_,8,v,y,c,f,R);case"x":return o(_,16,v,y,c,f,R);case"X":return o(_,16,v,y,c,f,R).toUpperCase();case"u":return o(_,10,v,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),E=d<0?"-":T,_=E+i(String(Math.abs(d)),f,"0",!1),a(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=E+Math.abs(d)[m](f),a(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}m.addSeconds(e,i,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,i=t(r,y,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-r[0].offset,n);if(i>=r.length)return m.addSeconds(e,-r[i-1].offset,n);var a=m.secondsDifference(r[i].julianDate,e);return 0===a?m.addSeconds(e,-r[i].offset,n):a<=1?void 0:m.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var p=new a,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+g.source,N=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,g=0,M=u[0],w=u[1];if(null!==(u=M.match(S)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=M.match(R)))n=+u[1],s=+u[2];else if(null!==(u=M.match(T)))n=+u[1];else{var C;if(null!==(u=M.match(v)))n=+u[1],C=+u[2],a=o(n);else if(null!==(u=M.match(A))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(C),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(w)){u=w.match(I),null!==u?(h=+u[1],p=+u[2],y=+u[3],g=1e3*+(u[4]||0),D=5):(u=w.match(N),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(O))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],b=+(u[D+2]||0);switch(L){case"+":h-=F,p-=b;break;case"-":h+=F,p+=b;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var B=60===y;for(B&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:_[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:_[s-1],l+=i;var z=E(n,s,l,h,p,y,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var M=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,i=h(e,M);r(i)||(m.addSeconds(e,-1,M),i=h(M,M),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(v+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=n,t):new a(_,p,E,y,R,v,A,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var i,a=m.toGregorianDate(t,p);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return O[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--v.numberOfActiveRequests,--O[e.serverKey],I.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){ +return function(t){e.state!==c.CANCELLED&&(++v.numberOfFailedRequests,--v.numberOfActiveRequests,--O[e.serverKey],I.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function _(e){var t=E(e);return e.state=c.ACTIVE,g.push(e),++v.numberOfActiveRequests,++v.numberOfActiveRequestsEver,++O[e.serverKey],e.requestFunction().then(m(e)).otherwise(p(e)),t}function y(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++v.numberOfCancelledRequests,e.deferred.reject(),t&&(--v.numberOfActiveRequests,--O[e.serverKey],++v.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){v.numberOfAttemptedRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(v.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+v.numberOfAttemptedRequests),v.numberOfActiveRequests>0&&console.log("Number of active requests: "+v.numberOfActiveRequests),v.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+v.numberOfCancelledRequests),v.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+v.numberOfCancelledActiveRequests),v.numberOfFailedRequests>0&&console.log("Number of failed requests: "+v.numberOfFailedRequests),T())}var v={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var g=[],O={},N="undefined"!=typeof document?new e(document.location.href):new e,I=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=I,i(f,{statistics:{get:function(){return v}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();y(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&y(t),t.state===c.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):y(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(N);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=O[i];return r(a)||(O[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return I.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++v.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return _(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(r(t)){if(t===e)return;y(t)}return E(e)}},f.clearForSpecs=function(){for(;S.length>0;){y(S.pop())}for(var e=g.length,t=0;t<e;++t)y(g[t]);g.length=0,O={},v.numberOfAttemptedRequests=0,v.numberOfActiveRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0,v.numberOfFailedRequests=0,v.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return O[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,p,_,y,T,R,v,A,S,g,O){"use strict";function N(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=_(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function I(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=p(n):e.query=r[0]}function M(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function w(e){if(e.state===v.ISSUED||e.state===v.ACTIVE)throw new A("The Resource is already being fetched.");e.state=v.UNISSUED,e.deferred=void 0}function C(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=M(e.templateValues,{}),this._queryParameters=M(e.queryParameters,{}),this.headers=M(e.headers,{}),this.request=i(e.request,new y),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function x(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=O.defer();return C._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==v.FAILED?O.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,x(e,t)):O.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=O.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},C._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==v.FAILED?O.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=v.UNISSUED,i.deferred=void 0,P(e,t,n)):O.reject(r)})})}function U(e,t){w(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=O.defer(),f=C._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==v.FAILED?O.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,e.fetch(t)):O.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var b=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();C.createIfNeeded=function(e,t){if(e instanceof C)return e.clone();if("string"!=typeof e)return e;var n=M(t,{});return n.url=e,new C(n)},o(C,{isBlobSupported:{get:function(){return b}}}),o(C.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);N(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),C.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new g(this._url);e&&I(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},C.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},C.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},C.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new g(e.url);N(n,t),n.fragment=void 0,t._url=n.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},C.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return O(!1);var n=this;return O(t(this,e)).then(function(e){return++n._retryCount,e})},C.prototype.clone=function(e){return a(e)||(e=new C({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},C.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},C.prototype.appendForwardSlash=function(){this._url=e(this._url)},C.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},C.fetchArrayBuffer=function(e){return new C(e).fetchArrayBuffer()},C.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},C.fetchBlob=function(e){return new C(e).fetchBlob()},C.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),w(this.request),!b||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return x(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new C({url:t}),x(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),O.reject(e)})}},C.fetchImage=function(e){return new C(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},C.prototype.fetchText=function(){return this.fetch({responseType:"text"})},C.fetchText=function(e){return new C(e).fetchText()},C.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},C.fetchJson=function(e){return new C(e).fetchJson()},C.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},C.fetchXML=function(e){return new C(e).fetchXML()},C.prototype.fetchJsonp=function(e){e=i(e,"callback"),w(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},C.fetchJsonp=function(e){return new C(e).fetchJsonp(e.callbackParameterName)},C.prototype.fetch=function(e){return e=M(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return C.fetch=function(e){return new C(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C.prototype.post=function(e,n){return t.defined("data",e),n=M(n,{}),n.method="POST",n.data=e,U(this,n)},C.post=function(e){return new C(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C._Implementations={},C._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(S.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},C._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},C._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},C._DefaultImplementations={},C._DefaultImplementations.createImage=C._Implementations.createImage,C._DefaultImplementations.loadWithXhr=C._Implementations.loadWithXhr,C._DefaultImplementations.loadAndExecuteScript=C._Implementations.loadAndExecuteScript,C.DEFAULT=c(new C({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),C}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,v=p.length;R<v;R+=e._columnCount){var A=p[R+i],S=p[R+m],g=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(g,S,f.TAI);if(_.push(O),T){if(S!==y&&r(y)){var N=o.leapSeconds,I=t(N,O,d);if(I<0){var M=new u(O,S);N.splice(~I,0,M)}}y=S}}}function m(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return m(e,n,i,s,u),u;if(r.equals(l))return m(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,E=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,_(this,a,this._samples,e,s,l,n),n}var p=t(a,e,o.compare,this._dateColumn);return p>=0?(p<a.length-1&&a[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var E,m,p=a-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var v=3*(s+E);n.x+=T[E]*d[v++],n.y+=T[E]*d[v++],n.s+=T[E]*d[v]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),E>h&&E>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,E=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,S=new s,g=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),g=s.multiplyByScalar(a,Math.sin(n*u),g),r=s.add(S,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,N=new e,I=new s,M=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,I);s.multiply(a,r,M);var o=s.log(M,O);s.multiply(a,t,M);var u=s.log(M,N);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,I),u=s.slerp(n,r,i,M);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,C=1.9011074535173003,x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,b=2*F+1;x[L]=1/(F*b),P[L]=F/b}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,I),u=s.fastSlerp(n,r,i,M);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,p,_,y,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,N=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=v[e][t],a=e+t;return u(S[a])?r=S[a]:(r=function(r,a,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(A[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(A[t],0,N),"east"!==t&&"west"!==t&&n.multiplyByScalar(N,c,N),n.unpack(A[i],0,I),"east"!==i&&"west"!==i&&n.multiplyByScalar(I,c,I)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),O=g[e],N=g[t],I=g[i]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=N.x,s[5]=N.y,s[6]=N.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},S[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var M=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,M),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return a=i(e,r,a),_.multiply(a,s,a)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(a,P);return y.fromRotationMatrix(o,i)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE +;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),b=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=b;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-a.s,B),h=p.multiply(l,f,b),d=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,v=_/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(y+v);A=A%1*m.TWO_PI;var S=p.fromRotationZ(A,B),g=p.multiply(h,S,b),O=Math.cos(n.xPoleWander),N=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),M=Math.sin(n.yPoleWander),w=r-2451545+i/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=B;return U[0]=O*x,U[1]=O*P,U[2]=I,U[3]=-N*P+M*I*x,U[4]=N*x+M*I*P,U[5]=-M*O,U[6]=-M*P-N*I*x,U[7]=M*x-N*I*P,U[8]=N*O,p.multiply(g,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return _.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new p),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var X=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),V=new i,H=new n,Y=new n,k=new p,j=new _,Z=new _;return R.basisTo2D=function(e,t,r){var i=_.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,V),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=_.inverseTransformation(s,Z),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(X,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=_.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,V),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,j);return _.multiply(X,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var a=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,a)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var i=_;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,y);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=_;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,y);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},E}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,E,m,p;if(a&&(u=s(e,n,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var _=i;_<o;_+=i)E=e[_],m=e[_+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);p=Math.max(h-l,d-f)}return r(u,c,i,l,f,p),c}function t(e,t,n,r,i){var a,o;if(i===M(e,t,n,r)>0)for(a=t;a<n;a+=r)o=O(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=O(a,e[a],e[a+1],o);return o&&T(o,o.next)&&(N(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(N(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,p=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?a(e,c,l,f):i(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),N(e),e=m.next,p=m.next;else if((e=m)===p){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(p(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&y(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(y(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&p(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&p(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!T(i,a)&&R(i,r,r.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),N(r),N(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&_(s,c)){var l=g(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,i,a,o,u),void r(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,f=o<u-1?r[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=g(t,e);n(r,r.next)}}function f(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=l&&p(a<f?i:o,a,l,f,a<f?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var i=e;do{null===i.z&&(i.z=E(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function p(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function S(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function g(e,t){var n=new I(e.i,e.x,e.y),r=new I(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function O(e,t,n,r){var i=new I(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function N(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function M(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(M(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(M(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var p=new n,_=new n,y=new n,T=new n,R=new n,v=new n,A=new n;return m.computeSubdivision=function(e,t,r,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),S=0;for(h=0;h<E;h++){var g=t[h];m[S++]=g.x,m[S++]=g.y,m[S++]=g.z}for(var O=[],N={},I=e.maximumRadius,M=l.chordLength(u,I),w=M*M;d.length>0;){var C,x,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,p),F=n.fromArray(m,3*U,_),b=n.fromArray(m,3*P,y),B=n.multiplyByScalar(n.normalize(L,T),I,T),z=n.multiplyByScalar(n.normalize(F,R),I,R),q=n.multiplyByScalar(n.normalize(b,v),I,v),G=n.magnitudeSquared(n.subtract(B,z,A)),W=n.magnitudeSquared(n.subtract(z,q,A)),X=n.magnitudeSquared(n.subtract(q,B,A)),V=Math.max(G,W,X);V>w?G===V?(C=Math.min(D,U)+" "+Math.max(D,U),h=N[C],o(h)||(x=n.add(L,F,A),n.multiplyByScalar(x,.5,x),m.push(x.x,x.y,x.z),h=m.length/3-1,N[C]=h),d.push(D,h,P),d.push(h,U,P)):W===V?(C=Math.min(U,P)+" "+Math.max(U,P),h=N[C],o(h)||(x=n.add(F,b,A),n.multiplyByScalar(x,.5,x),m.push(x.x,x.y,x.z),h=m.length/3-1,N[C]=h),d.push(U,h,D),d.push(h,P,D)):X===V&&(C=Math.min(P,D)+" "+Math.max(P,D),h=N[C],o(h)||(x=n.add(b,L,A),n.multiplyByScalar(x,.5,x),m.push(x.x,x.y,x.z),h=m.length/3-1,N[C]=h),d.push(P,h,U),d.push(h,D,U)):(O.push(D),O.push(U),O.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:m})},indices:O,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=d,c=E;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,i=(n-r)/n,a=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-i)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,a),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,p=m*m,_=p*m,y=p*p,T=1+m-3*p/4+5*_/4-175*y/64,R=1-m+15*p/8-35*_/8,v=1-3*m+35*p/4,A=1-5*m,S=T*l-R*Math.sin(2*l)*m/2-v*Math.sin(4*l)*p/16-A*Math.sin(6*l)*_/48-5*Math.sin(8*l)*y/512,g=e._constants;g.a=n,g.b=r,g.f=i,g.cosineHeading=a,g.sineHeading=o,g.tanU=u,g.cosineU=s,g.sineU=c,g.sigma=l,g.sineAlpha=f,g.sineSquaredAlpha=h,g.cosineSquaredAlpha=d,g.cosineAlpha=E,g.u2Over4=m,g.u4Over16=p,g.u6Over64=_,g.u8Over256=y,g.a0=T,g.a1=R,g.a2=v,g.a3=A,g.distanceRatio=S}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,i,a,o){var u=c(e,n);return(1-u)*e*t*(r+u*i*(o+u*a*(2*o*o-1)))}function f(e,t,n,r,i,a,o){var s,c,f,h,d,E=(t-n)/t,m=a-r,p=Math.atan((1-E)*Math.tan(i)),_=Math.atan((1-E)*Math.tan(o)),y=Math.cos(p),T=Math.sin(p),R=Math.cos(_),v=Math.sin(_),A=y*R,S=y*v,g=T*v,O=T*R,N=m,I=u.TWO_PI,M=Math.cos(N),w=Math.sin(N);do{M=Math.cos(N),w=Math.sin(N);var C=S-O*M;f=Math.sqrt(R*R*w*w+C*C),c=g+A*M,s=Math.atan2(f,c);var x;0===f?(x=0,h=1):(x=A*w/f,h=1-x*x),I=N,d=c-2*g/h,isNaN(d)&&(d=0),N=m+l(E,x,h,s,f,c,d)}while(Math.abs(N-I)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),b=n*U*(s-F),B=Math.atan2(R*w,S-O*M),z=Math.atan2(y*w,S*M-O);e._distance=b,e._startHeading=B,e._endHeading=z,e._uSquared=P}function h(n,r,i,a){e.normalize(a.cartographicToCartesian(r,m),E),e.normalize(a.cartographicToCartesian(i,m),m);f(n,a.maximumRadius,a.minimumRadius,r.longitude,r.latitude,i.longitude,i.latitude),n._start=t.clone(r,n._start),n._end=t.clone(i,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,a){var u=r(a,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,i(e)&&i(n)&&h(this,e,n,u)}var E=new e,m=new e;return a(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,a=r.distanceRatio+e/r.b,o=Math.cos(2*a),u=Math.cos(4*a),s=Math.cos(6*a),c=Math.sin(2*a),f=Math.sin(4*a),h=Math.sin(6*a),d=Math.sin(8*a),E=a*a,m=a*E,p=r.u8Over256,_=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*p*o/3+a*(1-_+7*T/4-15*y/4+579*p/64-(T-15*y/4+187*p/16)*o-(5*y/4-115*p/16)*u-29*p*s/16)+(_/2-T+71*y/32-85*p/16)*c+(5*T/16-5*y/4+383*p/96)*f-E*((y-11*p/2)*c+5*p*f/2)+(29*y/96-29*p/16)*h+539*p*d/1536,v=Math.asin(Math.sin(R)*r.cosineAlpha),A=Math.atan(r.a/r.b*Math.tan(v));R-=r.sigma;var S=Math.cos(2*r.sigma+R),g=Math.sin(R),O=Math.cos(R),N=r.cosineU*O,I=r.sineU*g,M=Math.atan2(g*r.sineHeading,N-I*r.cosineHeading),w=M-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,g,O,S);return i(n)?(n.longitude=this._start.longitude+w,n.latitude=A,n.height=0,n):new t(this._start.longitude+w,A,0)},d}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=g;r.length=e;var i;if(t===n){for(i=0;i<e;i++)r[i]=t;return r}var a=n-t,o=a/e;for(i=0;i<e;i++){var u=t+i*o;r[i]=u}return r}function d(t,n,r,i,a,o,u,s){var c=i.scaleToGeodeticSurface(t,M),l=i.scaleToGeodeticSurface(n,w),f=E.numberOfPoints(t,n,r),d=i.cartesianToCartographic(c,O),m=i.cartesianToCartographic(l,N),p=h(f,a,o);C.setEndPoints(d,m);var _=C.surfaceDistance/f,y=s;d.height=a;var T=i.cartographicToCartesian(d,I);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var v=C.interpolateUsingSurfaceDistance(R*_,N);v.height=p[R],T=i.cartographicToCartesian(v,I),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var i=e.distance(t,n);return Math.ceil(i/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),i=0;i<n;i++){var a=e[i];r[i]=t.cartesianToCartographic(a,m).height}return r};var p=new l,_=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,v=new f(e.UNIT_X,0),A=new e,S=new e,g=[],O=new t,N=new t,I=new e,M=new e,w=new e,C=new o;return E.wrapLongitude=function(t,i){var a=[],o=[];if(r(t)&&t.length>0){i=n(i,l.IDENTITY);var s=l.inverseTransformation(i,p),c=l.multiplyByPoint(s,e.ZERO,_),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,v),g=1;a.push(e.clone(t[0]));for(var O=a[0],N=t.length,I=1;I<N;++I){var M=t[I];if(f.getPointDistance(m,O)<0||f.getPointDistance(m,M)<0){var w=u.lineSegmentPlane(O,M,d,A);if(r(w)){var C=e.multiplyByScalar(h,5e-9,S);f.getPointDistance(d,O)<0&&e.negate(C,C),a.push(e.add(w,C,new e)),o.push(g+1),e.negate(C,C),a.push(e.add(w,C,new e)),g=1}}a.push(e.clone(t[I])),g++,O=M}o.push(g)}return{positions:a,lengths:o}},E.generateArc=function(t){r(t)||(t={});var i=t.positions,o=i.length,u=n(t.ellipsoid,a.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(i[0],M);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,I);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var p=t.minDistance;if(!r(p)){var _=n(t.granularity,c.RADIANS_PER_DEGREE);p=c.chordLength(_,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(i[y],i[y+1],p);var R=3*(T+1),v=new Array(R),A=0;for(y=0;y<o-1;y++){A=d(i[y],i[y+1],p,u,f?l[y]:l,f?l[y+1]:l,v,A)}g.length=0;var S=i[o-1],N=u.cartesianToCartographic(S,O);N.height=f?l[o-1]:l;var w=u.cartographicToCartesian(N,I);return e.pack(w,v,R-3),v},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,i=new Array(r),a=0;a<r;a++)i[a]=e.unpack(n,3*a);return i},E}),define("Core/WallGeometryLibrary",["./Cartographic","./defined","./EllipsoidTangentPlane","./Math","./PolygonPipeline","./PolylinePipeline","./WindingOrder"],function(e,t,n,r,i,a,o){"use strict";function u(e,t){return r.equalsEpsilon(e.latitude,t.latitude,r.EPSILON14)&&r.equalsEpsilon(e.longitude,t.longitude,r.EPSILON14)}function s(n,r,i,a){var o=r.length;if(!(o<2)){var s=t(a),c=t(i),h=!0,d=new Array(o),E=new Array(o),m=new Array(o),p=r[0];d[0]=p;var _=n.cartesianToCartographic(p,l);c&&(_.height=i[0]),h=h&&_.height<=0,E[0]=_.height,m[0]=s?a[0]:0;for(var y=1,T=1;T<o;++T){var R=r[T],v=n.cartesianToCartographic(R,f);c&&(v.height=i[T]),h=h&&v.height<=0,u(_,v)?_.height<v.height&&(E[y-1]=v.height):(d[y]=R,E[y]=v.height,m[y]=s?a[T]:0,e.clone(v,_),++y)}if(!(h||y<2))return d.length=y,E.length=y,m.length=y,{positions:d,topHeights:E,bottomHeights:m}}}var c={},l=new e,f=new e,h=new Array(2),d=new Array(2),E={positions:void 0,height:void 0,granularity:void 0,ellipsoid:void 0};return c.computePositions=function(e,u,c,l,f,m){var p=s(e,u,c,l);if(t(p)){if(u=p.positions,c=p.topHeights,l=p.bottomHeights,u.length>=3){var _=n.fromPoints(u,e),y=_.projectPointsOntoPlane(u);i.computeWindingOrder2D(y)===o.CLOCKWISE&&(u.reverse(),c.reverse(),l.reverse())}var T,R,v=u.length,A=v-2,S=r.chordLength(f,e.maximumRadius),g=E;if(g.minDistance=S,g.ellipsoid=e,m){var O,N=0;for(O=0;O<v-1;O++)N+=a.numberOfPoints(u[O],u[O+1],S)+1;T=new Float64Array(3*N),R=new Float64Array(3*N);var I=h,M=d;g.positions=I,g.height=M;var w=0;for(O=0;O<v-1;O++){I[0]=u[O],I[1]=u[O+1],M[0]=c[O],M[1]=c[O+1];var C=a.generateArc(g);T.set(C,w),M[0]=l[O],M[1]=l[O+1],R.set(a.generateArc(g),w),w+=C.length}}else g.positions=u,g.height=c,T=new Float64Array(a.generateArc(g)),g.height=l,R=new Float64Array(a.generateArc(g));return{bottomPositions:R,topPositions:T,numCorners:A}}},c}),define("Core/WallGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./VertexFormat","./WallGeometryLibrary"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E){"use strict";function m(e){e=r(e,r.EMPTY_OBJECT);var n=e.positions,a=e.maximumHeights,u=e.minimumHeights,s=r(e.vertexFormat,d.DEFAULT),c=r(e.granularity,f.RADIANS_PER_DEGREE),l=r(e.ellipsoid,o.WGS84);this._positions=n,this._minimumHeights=u,this._maximumHeights=a,this._vertexFormat=d.clone(s),this._granularity=c,this._ellipsoid=o.clone(l),this._workerName="createWallGeometry";var h=1+n.length*t.packedLength+2;i(u)&&(h+=u.length),i(a)&&(h+=a.length),this.packedLength=h+o.packedLength+d.packedLength+1}var p=new t,_=new t,y=new t,T=new t,R=new t,v=new t,A=new t,S=new t;m.pack=function(e,n,a){a=r(a,0);var u,s=e._positions,c=s.length;for(n[a++]=c,u=0;u<c;++u,a+=t.packedLength)t.pack(s[u],n,a);var l=e._minimumHeights;if(c=i(l)?l.length:0,n[a++]=c,i(l))for(u=0;u<c;++u)n[a++]=l[u];var f=e._maximumHeights;if(c=i(f)?f.length:0,n[a++]=c,i(f))for(u=0;u<c;++u)n[a++]=f[u];return o.pack(e._ellipsoid,n,a),a+=o.packedLength,d.pack(e._vertexFormat,n,a),a+=d.packedLength,n[a]=e._granularity,n};var g=o.clone(o.UNIT_SPHERE),O=new d,N={positions:void 0,minimumHeights:void 0,maximumHeights:void 0,ellipsoid:g,vertexFormat:O,granularity:void 0};return m.unpack=function(e,n,a){n=r(n,0);var u,s=e[n++],c=new Array(s);for(u=0;u<s;++u,n+=t.packedLength)c[u]=t.unpack(e,n);s=e[n++];var l;if(s>0)for(l=new Array(s),u=0;u<s;++u)l[u]=e[n++];s=e[n++];var f;if(s>0)for(f=new Array(s),u=0;u<s;++u)f[u]=e[n++];var h=o.unpack(e,n,g);n+=o.packedLength;var E=d.unpack(e,n,O);n+=d.packedLength;var p=e[n];return i(a)?(a._positions=c,a._minimumHeights=l,a._maximumHeights=f,a._ellipsoid=o.clone(h,a._ellipsoid),a._vertexFormat=d.clone(E,a._vertexFormat),a._granularity=p,a):(N.positions=c,N.minimumHeights=l,N.maximumHeights=f,N.granularity=p,new m(N))},m.fromConstantHeights=function(e){e=r(e,r.EMPTY_OBJECT);var t,n,a=e.positions,o=e.minimumHeight,u=e.maximumHeight,s=i(o),c=i(u);if(s||c){var l=a.length;t=s?new Array(l):void 0,n=c?new Array(l):void 0;for(var f=0;f<l;++f)s&&(t[f]=o),c&&(n[f]=u)}return new m({positions:a,maximumHeights:n,minimumHeights:t,ellipsoid:e.ellipsoid,vertexFormat:e.vertexFormat})},m.createGeometry=function(r){var a=r._positions,o=r._minimumHeights,d=r._maximumHeights,m=r._vertexFormat,g=r._granularity,O=r._ellipsoid,N=E.computePositions(O,a,d,o,g,!0);if(i(N)){var I=N.bottomPositions,M=N.topPositions,w=N.numCorners,C=M.length,x=2*C,P=m.position?new Float64Array(x):void 0,U=m.normal?new Float32Array(x):void 0,D=m.tangent?new Float32Array(x):void 0,L=m.bitangent?new Float32Array(x):void 0,F=m.st?new Float32Array(x/3*2):void 0,b=0,B=0,z=0,q=0,G=0,W=S,X=A,V=v,H=!0;C/=3;var Y,k=0,j=1/(C-a.length+1);for(Y=0;Y<C;++Y){var Z=3*Y,K=t.fromArray(M,Z,p),J=t.fromArray(I,Z,_);if(m.position&&(P[b++]=J.x,P[b++]=J.y,P[b++]=J.z,P[b++]=K.x,P[b++]=K.y,P[b++]=K.z),m.st&&(F[G++]=k,F[G++]=0,F[G++]=k,F[G++]=1),m.normal||m.tangent||m.bitangent){var Q,$=t.clone(t.ZERO,R),ee=O.scaleToGeodeticSurface(t.fromArray(M,Z,_),_);if(Y+1<C&&(Q=O.scaleToGeodeticSurface(t.fromArray(M,Z+3,y),y),$=t.fromArray(M,Z+3,R)),H){var te=t.subtract($,K,T),ne=t.subtract(ee,K,p);W=t.normalize(t.cross(ne,te,W),W),H=!1}t.equalsEpsilon(Q,ee,f.EPSILON10)?H=!0:(k+=j,m.tangent&&(X=t.normalize(t.subtract(Q,ee,X),X)),m.bitangent&&(V=t.normalize(t.cross(W,X,V),V))),m.normal&&(U[B++]=W.x,U[B++]=W.y,U[B++]=W.z,U[B++]=W.x,U[B++]=W.y,U[B++]=W.z),m.tangent&&(D[q++]=X.x,D[q++]=X.y,D[q++]=X.z,D[q++]=X.x,D[q++]=X.y,D[q++]=X.z),m.bitangent&&(L[z++]=V.x,L[z++]=V.y,L[z++]=V.z,L[z++]=V.x,L[z++]=V.y,L[z++]=V.z)}}var re=new c;m.position&&(re.position=new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:P})),m.normal&&(re.normal=new s({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:U})),m.tangent&&(re.tangent=new s({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:D})),m.bitangent&&(re.bitangent=new s({componentDatatype:n.FLOAT,componentsPerAttribute:3,values:L})),m.st&&(re.st=new s({componentDatatype:n.FLOAT,componentsPerAttribute:2,values:F}));var ie=x/3;x-=6*(w+1);var ae=l.createTypedArray(ie,x),oe=0;for(Y=0;Y<ie-2;Y+=2){var ue=Y,se=Y+2,ce=t.fromArray(P,3*ue,p),le=t.fromArray(P,3*se,_);if(!t.equalsEpsilon(ce,le,f.EPSILON10)){var fe=Y+1,he=Y+3;ae[oe++]=fe,ae[oe++]=ue,ae[oe++]=he,ae[oe++]=he,ae[oe++]=ue,ae[oe++]=se}}return new u({attributes:re,indices:ae,primitiveType:h.TRIANGLES,boundingSphere:new e.fromVertices(P)})}},m}),define("Workers/createWallGeometry",["../Core/defined","../Core/Ellipsoid","../Core/WallGeometry"],function(e,t,n){"use strict";function r(r,i){return e(i)&&(r=n.unpack(r,i)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallOutlineGeometry.js index 2cbb384a..30715ead 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/createWallOutlineGeometry.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,E=i.y,m=i.z,_=l*l*d*d,p=f*f*E*E,y=h*h*m*m,T=_+p+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,N=u.z,O=o;O.x=A.x*S*2,O.y=A.y*v*2,O.z=A.z*N*2;var I,M,g,w,x,C,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(O)),b=0;do{B-=b,g=1/(1+B*S),w=1/(1+B*v),x=1/(1+B*N),C=g*g,P=w*w,U=x*x,D=C*g,L=P*w,F=U*x,I=_*C+p*P+y*U-1,M=_*D*S+p*L*v+y*F*N;b=I/(-2*M)}while(Math.abs(I)>r.EPSILON12);return t(c)?(c.x=l*g,c.y=f*w,c.z=h*x,c):new e(l*g,f*w,h*x)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,_=r(n)?n._centerToleranceSquared:d,p=o(t,E,m,_,c);if(r(p)){var y=e.multiplyComponents(p,m,s);y=e.normalize(y,y);var T=e.subtract(t,p,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=A,i.height=S,i):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,_=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,E),u=e.subtract(n,a,_),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],E[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=E[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,_=e[s.getElementIndex(h,h)],p=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(_-p)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(i-h),_=2*(a+l),p=2*(i+h),y=-n+u-f+d,T=2*(c-o),R=2*(a-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=p,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=_,t[7]=T,t[8]=S,t):new s(E,m,_,p,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,E=a*i+c*o*u,m=-c*i+a*o*u,_=-o,p=c*n,y=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=_,t[3]=f,t[4]=E,t[5]=p,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,_,p,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],_=new s,p=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,_),s.transpose(_,p),s.multiply(h,_,h),s.multiply(p,h,h),s.multiply(o,_,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){ -var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,E,m,_){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(_,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,_=t.z*t.z,p=t.z*t.w,y=t.w*t.w,T=s-d-_+y,R=2*(c-p),A=2*(f+m),S=2*(c+p),v=-s+d-_+y,N=2*(E-h),O=2*(f-m),I=2*(E+h),M=-s-d+_+y;return r[0]=T*a,r[1]=S*a,r[2]=O*a,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=I*o,r[7]=0,r[8]=A*u,r[9]=N*u,r[10]=M*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,_=f.z,p=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,N=p*-R+y*-A+T*-S,O=E*R+m*A+_*S;return i(n)?(n[0]=u,n[1]=p,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-_,n[11]=0,n[12]=v,n[13]=N,n[14]=O,n[15]=1,n):new l(u,s,c,v,p,y,T,N,-E,-m,-_,O,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=a+c,_=o+l,p=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=m,i[13]=_,i[14]=p,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],_=e[13],p=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],N=t[5],O=t[6],I=t[7],M=t[8],g=t[9],w=t[10],x=t[11],C=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=i*T+s*R+h*A+_*S,B=a*T+c*R+d*A+p*S,b=o*T+l*R+E*A+y*S,z=r*v+u*N+f*O+m*I,q=i*v+s*N+h*O+_*I,G=a*v+c*N+d*O+p*I,W=o*v+l*N+E*O+y*I,X=r*M+u*g+f*w+m*x,H=i*M+s*g+h*w+_*x,V=a*M+c*g+d*w+p*x,Y=o*M+l*g+E*w+y*x,k=r*C+u*P+f*U+m*D,Z=i*C+s*P+h*U+_*D,j=a*C+c*P+d*U+p*D,K=o*C+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=X,n[9]=H,n[10]=V,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],_=t[1],p=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],N=t[12],O=t[13],I=t[14],M=r*m+o*_+c*p,g=i*m+u*_+l*p,w=a*m+s*_+f*p,x=r*y+o*T+c*R,C=i*y+u*T+l*R,P=a*y+s*T+f*R,U=r*A+o*S+c*v,D=i*A+u*S+l*v,L=a*A+s*S+f*v,F=r*N+o*O+c*I+h,B=i*N+u*O+l*I+d,b=a*N+s*O+f*I+E;return n[0]=M,n[1]=g,n[2]=w,n[3]=0,n[4]=x,n[5]=C,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],_=t[4],p=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=i*h+u*d+l*E,v=a*h+s*d+f*E,N=r*m+o*_+c*p,O=i*m+u*_+l*p,I=a*m+s*_+f*p,M=r*y+o*T+c*R,g=i*y+u*T+l*R,w=a*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=N,n[5]=O,n[6]=I,n[7]=0,n[8]=M,n[9]=g,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var _=new e;l.multiplyByUniformScale=function(e,t,n){return _.x=t,_.y=t,_.z=t,l.multiplyByScale(e,_,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var p=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,p),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],_=e[6],A=e[10],S=e[14],v=e[3],N=e[7],O=e[11],I=e[15],M=A*I,g=S*O,w=_*I,x=S*N,C=_*O,P=A*N,U=m*I,D=S*v,L=m*O,F=A*v,B=m*N,b=_*v,z=M*h+x*d+C*E-(g*h+w*d+P*E),q=g*f+U*d+F*E-(M*f+D*d+L*E),G=w*f+D*h+B*E-(x*f+U*h+b*E),W=P*f+L*h+b*d-(C*f+F*h+B*d),X=g*i+w*a+P*o-(M*i+x*a+C*o),H=M*r+D*a+L*o-(g*r+U*a+F*o),V=x*r+U*i+b*o-(w*r+D*i+B*o),Y=C*r+F*i+B*a-(P*r+L*i+b*a);M=a*E,g=o*d,w=i*E,x=o*h,C=i*d,P=a*h,U=r*E,D=o*f,L=r*d,F=a*f,B=r*h,b=i*f;var k=M*N+x*O+C*I-(g*N+w*O+P*I),Z=g*v+U*O+F*I-(M*v+D*O+L*I),j=w*v+D*N+B*I-(x*v+U*N+b*I),K=P*v+L*N+b*O-(C*v+F*N+B*O),J=w*A+P*S+g*_-(C*S+M*_+x*A),Q=L*S+M*m+D*A-(U*A+F*S+g*m),$=U*_+b*S+x*m-(B*S+w*m+D*_),ee=B*A+C*m+F*_-(L*_+b*A+P*m),te=r*z+i*q+a*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=X*te,n[5]=H*te,n[6]=V*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-i*d,m=-a*f-o*h-u*d,_=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=_,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,E),o=Math.max(o,E)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var _=t.cartesianToCartographic(e[E]);o=Math.min(o,_.longitude),c=Math.max(c,_.longitude),h=Math.min(h,_.latitude),d=Math.max(d,_.latitude);var p=_.longitude>=0?_.longitude:_.longitude+u.TWO_PI;l=Math.min(l,p),f=Math.max(f,p)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=i,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var _=1;_<8;++_)m.longitude=-Math.PI+_*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,E=new e,m=new e,_=new e,p=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,N=new e;h.fromPoints=function(t,n){if(i(n)||(n=new h),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,a=e.clone(t[0],T),o=e.clone(a,d),u=e.clone(a,E),s=e.clone(a,m),c=e.clone(a,_),l=e.clone(a,p),f=e.clone(a,y),O=t.length;for(r=1;r<O;r++){e.clone(t[r],a);var I=a.x,M=a.y,g=a.z;I<o.x&&e.clone(a,o),I>c.x&&e.clone(a,c),M<u.y&&e.clone(a,u),M>l.y&&e.clone(a,l),g<s.z&&e.clone(a,s),g>f.z&&e.clone(a,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;x>D&&(D=x,P=u,U=l),C>D&&(D=C,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=v;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,N),G=0;for(r=0;r<O;r++){e.clone(t[r],a);var W=e.magnitude(e.subtract(a,q,R));W>G&&(G=W);var X=e.magnitudeSquared(e.subtract(a,L,R));if(X>F){var H=Math.sqrt(X);B=.5*(B+H),F=B*B;var V=H-B;L.x=(B*L.x+V*a.x)/H,L.y=(B*L.y+V*a.y)/H,L.z=(B*L.z+V*a.z)/H}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var O=new o,I=new e,M=new e,g=new t,w=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,a,o,u){if(i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,O),f.southwest(t,g),g.height=a,f.northeast(t,w),w.height=o;var s=n.project(g,I),c=n.project(w,M),l=c.x-s.x,d=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*E,u};var x=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,a.WGS84),o=r(o,0),i(u)||(u=new h),!i(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,x);return h.fromPoints(s,u)},h.fromVertices=function(t,n,a,o){if(i(o)||(o=new h),!i(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),a=r(a,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,E),f=e.clone(u,m),O=e.clone(u,_),I=e.clone(u,p),M=e.clone(u,y),g=t.length;for(s=0;s<g;s+=a){var w=t[s]+n.x,x=t[s+1]+n.y,C=t[s+2]+n.z;u.x=w,u.y=x,u.z=C,w<c.x&&e.clone(u,c),w>O.x&&e.clone(u,O),x<l.y&&e.clone(u,l),x>I.y&&e.clone(u,I),C<f.z&&e.clone(u,f),C>M.z&&e.clone(u,M)}var P=e.magnitudeSquared(e.subtract(O,c,R)),U=e.magnitudeSquared(e.subtract(I,l,R)),D=e.magnitudeSquared(e.subtract(M,f,R)),L=c,F=O,B=P;U>B&&(B=U,L=l,F=I),D>B&&(B=D,L=f,F=M);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=v;W.x=O.x,W.y=I.y,W.z=M.z;var X=e.multiplyByScalar(e.add(G,W,R),.5,N),H=0;for(s=0;s<g;s+=a){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var V=e.magnitude(e.subtract(u,X,R));V>H&&(H=V);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;b.x=(q*b.x+Z*u.x)/k,b.y=(q*b.y+Z*u.y)/k,b.z=(q*b.z+Z*u.z)/k}}return q<H?(e.clone(b,o.center),o.radius=q):(e.clone(X,o.center),o.radius=H),o},h.fromEncodedCartesianVertices=function(t,n,r){if(i(r)||(r=new h),!i(t)||!i(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var a=T;a.x=t[0]+n[0],a.y=t[1]+n[1],a.z=t[2]+n[2];var o,u=e.clone(a,d),s=e.clone(a,E),c=e.clone(a,m),l=e.clone(a,_),f=e.clone(a,p),O=e.clone(a,y),I=t.length;for(o=0;o<I;o+=3){var M=t[o]+n[o],g=t[o+1]+n[o+1],w=t[o+2]+n[o+2];a.x=M,a.y=g,a.z=w,M<u.x&&e.clone(a,u),M>l.x&&e.clone(a,l),g<s.y&&e.clone(a,s),g>f.y&&e.clone(a,f),w<c.z&&e.clone(a,c),w>O.z&&e.clone(a,O)}var x=e.magnitudeSquared(e.subtract(l,u,R)),C=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(O,c,R)),U=u,D=l,L=x;C>L&&(L=C,U=s,D=f),P>L&&(L=P,U=c,D=O);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=v;q.x=l.x,q.y=f.y,q.z=O.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,N),W=0;for(o=0;o<I;o+=3){a.x=t[o]+n[o],a.y=t[o+1]+n[o+1],a.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(a,G,R));X>W&&(W=X);var H=e.magnitudeSquared(e.subtract(a,F,R));if(H>B){var V=Math.sqrt(H);b=.5*(b+V),B=b*b;var Y=V-b;F.x=(b*F.x+Y*a.x)/V,F.y=(b*F.y+Y*a.y)/V,F.z=(b*F.z+Y*a.z)/V}}return b<W?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=W),r},h.fromCornerPoints=function(t,n,r){i(r)||(r=new h);var a=r.center;return e.add(t,n,a),e.multiplyByScalar(a,.5,a),r.radius=e.distance(a,n),r},h.fromEllipsoid=function(t,n){return i(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var C=new e;h.fromBoundingSpheres=function(t,n){if(i(n)||(n=new h),!i(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var a,o=[];for(a=0;a<r;a++)o.push(t[a].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(a=0;a<r;a++){var c=t[a];s=Math.max(s,e.distance(u,c.center,C)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;h.fromOrientedBoundingBox=function(t,n){i(n)||(n=new h);var r=t.halfAxes,a=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(a,o,a),e.add(a,u,a),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(a),n},h.clone=function(t,n){if(i(t))return i(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var i=e.center;return t[n++]=i.x,t[n++]=i.y,t[n++]=i.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),i(n)||(n=new h);var a=n.center;return a.x=e[t++],a.y=e[t++],a.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;h.union=function(t,n,r){i(r)||(r=new h);var a=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,a,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(d,a,d),e.clone(d,r.center),r.radius=f,r};var B=new e;h.expand=function(t,n,r){r=h.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,B));return i>r.radius&&(r.radius=i),r},h.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?u.OUTSIDE:o<i?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return i(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return i(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,a){i(a)||(a=new s);var o=e.subtract(t.center,n,z),u=e.dot(r,o);return a.start=u-t.radius,a.stop=u+t.radius,a};for(var q=new e,G=new e,W=new e,X=new e,H=new e,V=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,n,i){n=r(n,Z);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,H),d=e.negate(c,X),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,d,m),m=E[2],e.add(s,f,m),e.add(m,d,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,d,m),m=E[6],e.add(s,f,m),e.add(m,d,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var _=E.length,p=0;p<_;++p){var y=E[p];e.add(o,y,y);var T=a.cartesianToCartographic(y,V);n.project(T,y)}i=h.fromPoints(E,i),o=i.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,i},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||i(t)&&i(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function a(){return i()&&S}function o(){if(!t(v)&&(v=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,N=r(e[1]))}return v}function u(){return o()&&N}function s(){if(!t(O)){O=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(O=!0,I=r(e[1]),I.isNightly=!!e[2])}return O}function c(){return s()&&I}function l(){if(!t(M)){M=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0, -g=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(M=!0,g=r(e[1]))}return M}function f(){return l()&&g}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,x=r(e[1]))}return w}function d(){return h()&&x}function E(){if(!t(C)){C=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(C=!0,P=r(e[1]))}return C}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function _(){return E()&&P}function p(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,N,O,I,M,g,w,x,C,P,U,D,L,F,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:_,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:p,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,_=d.z;i=Math.min(E,i),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(_,u),l=Math.max(_,l)}var p=n.minimum;p.x=i,p.y=o,p.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(p,y,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,_=u*c-d,p=4*E*_-m*m;if(p<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=_,R=-c*m+2*s*_);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-p);a=-R+S;var v=a/2,N=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),O=a===S?-N:-T/N;return i=T<=0?N+O:-R/(N*N+O*O+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var I=E,M=-2*u*E+o*m,g=_,w=-c*m+2*s*_,x=Math.sqrt(p),C=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*x,-M)/3);i=2*Math.sqrt(-I);var U=Math.cos(P);a=i*U;var D=i*(-U/2-C*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*x,-w)/3),i=2*Math.sqrt(-g),U=Math.cos(P),a=i*U,D=i*(-U/2-C*Math.sin(P));var b=-c,z=a+D<2*s?a+s:D+s,q=b/z,G=F*z,W=-L*z-F*b,X=L*b,H=(s*W-u*X)/(-u*W+s*G);return B<=H?B<=q?H<=q?[B,H,q]:[B,q,H]:[q,B,H]:B<=q?[H,B,q]:H<=q?[H,q,B]:[q,H,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,_=E[0],p=E[1];if(_>=0&&p>=0){var y=Math.sqrt(_),T=Math.sqrt(p);return[h-T,h-y,h+y,h+T]}if(_>=0&&p<0)return m=Math.sqrt(_),[h-m,h+m];if(_<0&&p>=0)return m=Math.sqrt(p),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),N=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==N.length?(N[0]+=h,N[1]+=h,v[1]<=N[0]?[v[0],v[1],N[0],N[1]]:N[1]<=v[0]?[N[0],N[1],v[0],v[1]]:v[0]>=N[0]&&v[1]<=N[1]?[N[0],v[0],v[1],N[1]]:N[0]>=v[0]&&N[1]<=v[1]?[v[0],N[0],N[1],v[1]]:v[0]>N[0]&&v[0]<N[1]?[N[0],v[0],N[1],v[1]]:[v[0],N[0],v[1],N[1]]):v):0!==N.length?(N[0]+=h,N[1]+=h,N):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,_=d[0],p=i-_,y=p*p,T=t/2,R=p/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*_,N=c+4*Math.abs(_);if(_<0||A*N<v*S){var O=Math.sqrt(v);E=O/2,m=0===O?0:(t*R-a)/O}else{var I=Math.sqrt(A);E=0===I?0:(t*R-a)/I,m=I/2}var M,g;0===T&&0===E?(M=0,g=0):n.sign(T)===n.sign(E)?(M=T+E,g=_/M):(g=T-E,M=_/g);var w,x;0===R&&0===m?(w=0,x=0):n.sign(R)===n.sign(m)?(w=R+m,x=o/w):(x=R-m,w=o/x);var C=r.computeRealRoots(1,M,w),P=r.computeRealRoots(1,g,x);if(0!==C.length)return 0!==P.length?C[1]<=P[0]?[C[0],C[1],P[0],P[1]]:P[1]<=C[0]?[P[0],P[1],C[0],C[1]]:C[0]>=P[0]&&C[1]<=P[1]?[P[0],C[0],C[1],P[1]]:P[0]>=C[0]&&P[1]<=C[1]?[C[0],P[0],P[1],C[1]]:C[0]>P[0]&&C[0]<P[1]?[P[0],C[0],P[1],C[1]]:[C[0],P[0],C[1],P[1]]:C;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,i,a){var l,f=i*i,h=a*a,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),_=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,p=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===p){if(l=s.computeRealRoots(E,m,_),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-A)),T.push(new e(i,a*R,a*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(i,a*S,a*-v)),T.push(new e(i,a*S,a*v))}return T}var N=y*y,O=p*p,I=E*E,M=y*p,g=I+O,w=2*(m*E+M),x=2*_*E+m*m-O+N,C=2*(_*m-M),P=_*_-N;if(0===g&&0===w&&0===x&&0===C)return T;l=c.computeRealRoots(g,w,x,C,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(_)?d(E*B+_,m*F,o.EPSILON12):o.sign(_)===o.sign(m*F)?d(E*B,m*F+_,o.EPSILON12):d(E*B+m*F,_,o.EPSILON12);var q=d(p*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var m={};m.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var _=new e,p=new e,y=new e,T=new e,R=new e -;m.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(i,r,_),A=e.subtract(a,r,p),S=e.cross(E,A,y),v=e.dot(m,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var N=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*N)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*N)<0||l+f>1)return;h=e.dot(A,c)*N}return h},m.rayTriangle=function(t,n,i,a,o,u){var s=m.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;m.lineSegmentSphere=function(t,n,i,a){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var N=new e,O=new e;m.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,N),f=e.multiplyComponents(c,t.direction,O),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,_=r/s;return m<_?new a(m,_):{start:_,stop:m}}var p=Math.sqrt(r/i);return new a(p,p)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var I=new e,M=new e,g=new e,w=new e,x=new e,C=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,I);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,I),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,M),M),m=e.normalize(e.cross(f,d,g),g),_=C;_[0]=f.x,_[1]=f.y,_[2]=f.z,_[3]=d.x,_[4]=d.y,_[5]=d.z,_[6]=m.x,_[7]=m.y,_[8]=m.z;var p=u.transpose(_,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var A,S,v=u.multiply(u.multiply(p,T,F),R,F),N=u.multiply(u.multiply(v,y,B),_,B),O=u.multiplyByVector(v,i,x),G=E(N,e.negate(O,I),0,0,1),W=G.length;if(W>0){for(var X=e.clone(e.ZERO,z),H=Number.NEGATIVE_INFINITY,V=0;V<W;++V){A=u.multiplyByVector(y,u.multiplyByVector(_,G[V],b),b);var Y=e.normalize(e.subtract(A,i,w),w),k=e.dot(Y,a);k>H&&(H=k,X=e.clone(A,X))}var Z=n.cartesianToCartographic(X,q);return H=o.clamp(H,0,1),S=e.magnitude(e.subtract(X,i,w))*Math.sqrt(1-H*H),S=c?-S:S,Z.height=S,n.cartographicToCartesian(Z,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function i(e){return E(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=p,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return _(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,_,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(_=d.progress,m=function(e){h.push(e),--l||(E=m=p,d.reject(h))},E=function(e){f.push(e),--c||(E=m=p,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,_);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return _(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function E(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function _(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function p(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,E,m,_,p;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,N=0;s&&N<v;N++)switch(s.charAt(N)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(N+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,p=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(p),y,c,f,R,S);case"c":return u(String.fromCharCode(+p),y,c,f,R);case"b":return o(p,2,A,y,c,f,R);case"o":return o(p,8,A,y,c,f,R);case"x":return o(p,16,A,y,c,f,R);case"X":return o(p,16,A,y,c,f,R).toUpperCase();case"u":return o(p,10,A,y,c,f,R);case"i":case"d":return d=+p||0,d=Math.round(d-d%1),E=d<0?"-":T,p=E+i(String(Math.abs(d)),f,"0",!1),a(p,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+p,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],_=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],p=E+Math.abs(d)[m](f),a(p,E,y,c,R)[_]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}m.addSeconds(e,i,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,i=t(r,y,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-r[0].offset,n);if(i>=r.length)return m.addSeconds(e,-r[i-1].offset,n);var a=m.secondsDifference(r[i].julianDate,e);return 0===a?m.addSeconds(e,-r[i].offset,n):a<=1?void 0:m.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var _=new a,p=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,N=/([Z+\-])?(\d{2})?:?(\d{2})?$/,O=/^(\d{2})(\.\d+)?/.source+N.source,I=/^(\d{2}):?(\d{2})(\.\d+)?/.source+N.source,M=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+N.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,_=0,y=0,N=0,g=u[0],w=u[1];if(null!==(u=g.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=g.match(R)))n=+u[1],s=+u[2];else if(null!==(u=g.match(T)))n=+u[1];else{var x;if(null!==(u=g.match(A)))n=+u[1],x=+u[2],a=o(n);else if(null!==(u=g.match(S))){n=+u[1];var C=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));x=7*C+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(x),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(w)){u=w.match(M),null!==u?(h=+u[1],_=+u[2],y=+u[3],N=1e3*+(u[4]||0),D=5):(u=w.match(I),null!==u?(h=+u[1],_=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(O))&&(h=+u[1],_=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,_-=B;break;case"-":h+=F,_+=B;break;case"Z":break;default:_+=new Date(Date.UTC(n,s-1,l,h,_)).getTimezoneOffset()}}var b=60===y;for(b&&y--;_>=60;)_-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:p[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:p[s-1];for(;_<0;)_+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:p[s-1],l+=i;var z=E(n,s,l,h,_,y,N);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var g=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,i=h(e,g);r(i)||(m.addSeconds(e,-1,g),i=h(g,g),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var _=d+2-12*c|0,p=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=p,t.month=_,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new a(p,_,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,_),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var i,a=m.toGregorianDate(t,_);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var i=e(r.throttleByServer,!1),a=i||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return N[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--N[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function _(e){var t=d(e);return e.state=s.ACTIVE,v.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function p(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--N[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new a({comparator:c});S.maximumLength=A,S.reserve(A);var v=[],N={},O="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,i(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();p(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=v.length;for(e=0;e<r;++e)t=v[e],t.cancelled&&p(t),t.state===s.ACTIVE?n>0&&(v[e-n]=t):++n;v.length-=n;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)f(i[e]);S.resort();for(var o=Math.max(l.maximumRequests-v.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?p(t):!t.throttleByServer||h(t.serverKey)?(_(t),++u):p(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(O);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=N[i];return r(a)||(N[i]=0),i},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return _(e);if(!(v.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;p(t)}return d(e)}},l.clearForSpecs=function(){for(;S.length>0;){p(S.pop())}for(var e=v.length,t=0;t<e;++t)p(v[t]);v.length=0,N={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return N[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var i=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;i=n(i,t.url);var d=r(t.request)?t.request:new a;return d.url=i,d.requestFunction=function(){var t=e.defer(),n=l.load(i,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function d(e,t){t=n(t,"");var r=e[1],i=!!e[2],a=e[3];switch(t){case"":case"text":return f(i,a);case"arraybuffer":return h(i,a);case"blob":var o=h(i,a);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(i,a),r);case"json":return JSON.parse(f(i,a))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,i,a,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(a))for(var m in a)a.hasOwnProperty(m)&&h.setRequestHeader(m,a[m]);r(t)&&(h.responseType=t);var _=!1;return"string"==typeof e&&(_=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!_||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(i),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict" -;function i(n,i,o){t(i)?t(i.Accept)||(i=e(i),i.Accept=a.Accept):i=a;var u=r(n,i,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var a={Accept:"application/json,*/*;q=0.01"};return i}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var i=this;this._downloadPromise=e(s(t.url),function(e){E(i,e)},function(){i._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var _=e._samples=n.samples,p=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=_.length;R<A;R+=e._columnCount){var S=_[R+i],v=_[R+m],N=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,O=new o(N,v,f.TAI);if(p.push(O),T){if(v!==y&&r(y)){var I=o.leapSeconds,M=t(I,O,d);if(M<0){var g=new u(O,v);I.splice(~M,0,g)}}y=v}}}function m(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function _(e,t,n){return t+e*(n-t)}function p(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return m(e,n,i,s,u),u;if(r.equals(l))return m(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,E=n[h+e._ut1MinusUtcSecondsColumn],p=n[d+e._ut1MinusUtcSecondsColumn],y=p-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=p:p-=R-T)}return u.xPoleWander=_(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=_(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=_(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=_(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=_(f,E,p),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,p(this,a,this._samples,e,s,l,n),n}var _=t(a,e,o.compare,this._dateColumn);return _>=0?(_<a.length-1&&a[_+1].equals(e)&&++_,s=_,l=_):(l=~_,(s=l-1)<0&&(s=0)),this._lastIndex=s,p(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=t(r,document.location.href);var i=new e(r);return new e(n).resolve(i).toString()}return i}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(r,i,a){if(a=t(a,!0),r instanceof e||(r=new e(r)),i instanceof e||(i=new e(i)),"data"===r.scheme)return r.toString();if("data"===i.scheme)return i.toString();n(i.authority)&&!n(i.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?i.scheme=new e(document.location.href).scheme:i.scheme=r.scheme);var o=r;i.isAbsolute()&&(o=i);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?a?r.path.replace(/\/?$/,"/")+i.path.replace(/^\/?/g,""):r.path+i.path:i.path;var s=n(r.query),c=n(i.query);s&&c?u+="?"+r.query+"&"+i.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+i.query);var l=n(i.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+i.fragment),u}return i}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,i,a){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=E.exec(r);if(null!==i)return i[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return a.toUrl("../"+e)}function c(e){return i(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(a.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,i[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",i):t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var E,m,_=a-s*this._stepSizeDays,p=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)p[E]=_-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=p[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var _=l,p=0;d>h&&(p=1),E>h&&E>d&&(p=2);var y=_[p],T=_[y];n=Math.sqrt(e[u.getElementIndex(p,p)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[p]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,p)]+e[u.getElementIndex(p,y)])*n,R[T]=(e[u.getElementIndex(T,p)]+e[u.getElementIndex(p,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var _=new e,p=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,_);var u=s.computeAngle(y);r[o]=_.x*u,r[o+1]=_.y*u,r[o+2]=_.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,p);var u=e.magnitude(p);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(p,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,E=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,N=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=S=s.negate(t,S)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),N=s.multiplyByScalar(a,Math.sin(n*u),N),r=s.add(v,N,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var O=new e,I=new e,M=new s,g=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,M);s.multiply(a,r,g);var o=s.log(g,O);s.multiply(a,t,g);var u=s.log(g,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,M),s.multiply(n,M,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,M),u=s.slerp(n,r,i,g);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,x=1.9011074535173003,C=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;C[L]=1/(F*B),P[L]=F/B}return C[7]=x/136,P[7]=8*x/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(C[f]*c-P[f])*o,D[f]=(C[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,M),u=s.fastSlerp(n,r,i,g);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,_,p,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},N={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},O=new n,I=new n,M=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=A[e][t],a=e+t;return u(v[a])?r=v[a]:(r=function(r,a,s){if(u(s)||(s=new p),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,O),"east"!==e&&"west"!==e&&n.multiplyByScalar(O,c,O),n.unpack(S[t],0,I),"east"!==t&&"west"!==t&&n.multiplyByScalar(I,c,I),n.unpack(S[i],0,M),"east"!==i&&"west"!==i&&n.multiplyByScalar(M,c,M)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,N.up);var l=N.up,h=N.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,N.east),n.cross(l,h,N.north),n.multiplyByScalar(N.up,-1,N.down),n.multiplyByScalar(N.east,-1,N.west),n.multiplyByScalar(N.north,-1,N.south),O=N[e],I=N[t],M=N[i]}return s[0]=O.x,s[1]=O.y,s[2]=O.z,s[3]=0,s[4]=I.x,s[5]=I.y,s[6]=I.z,s[7]=0,s[8]=M.x,s[9]=M.y,s[10]=M.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var g=new y,w=new n(1,1,1),x=new p;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,g),s=p.fromTranslationQuaternionRotationScale(n.ZERO,u,w,x);return a=i(e,r,a),p.multiply(a,s,a)};var C=new p,P=new _;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,C),o=p.getRotation(a,P);return y.fromRotationMatrix(o,i)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new _(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new _);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return _.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new _,b=new _;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new _);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=_.fromRotationZ(-a.s,b),h=_.multiply(l,f,B),d=e.dayNumber,p=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=p/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var v=_.fromRotationZ(S,b),N=_.multiply(h,v,B),O=Math.cos(n.xPoleWander),I=Math.cos(n.yPoleWander),M=Math.sin(n.xPoleWander),g=Math.sin(n.yPoleWander),w=r-2451545+i/T.SECONDS_PER_DAY;w/=36525;var x=-47e-6*w*m.RADIANS_PER_DEGREE/3600,C=Math.cos(x),P=Math.sin(x),U=b;return U[0]=O*C,U[1]=O*P,U[2]=M,U[3]=-I*P+g*M*C,U[4]=I*C+g*M*P,U[5]=-g*O,U[6]=-g*P-I*M*C,U[7]=g*C-I*M*P,U[8]=I*O,_.multiply(N,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return p.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),p.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new _),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var X=new p(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),H=new i,V=new n,Y=new n,k=new _,Z=new p,j=new p;return R.basisTo2D=function(e,t,r){var i=p.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,H),u=e.project(o,V);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,Z),c=p.inverseTransformation(s,j),l=p.getRotation(t,k),f=p.multiplyByMatrix3(c,l,r);return p.multiply(X,f,r),p.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,Z),o=p.inverseTransformation(a,j),u=i.cartesianToCartographic(t,H),s=e.project(u,V);n.fromElements(s.z,s.x,s.y,s);var c=p.fromTranslation(s,Z);return p.multiply(X,o,r),p.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var a=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,a)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var _=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,_).center,n)};var p=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var i=p;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,y);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=p;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,y);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},E}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,E,m,_;if(a&&(u=s(e,n,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var p=i;p<o;p+=i)E=e[p],m=e[p+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);_=Math.max(h-l,d-f)}return r(u,c,i,l,f,_),c}function t(e,t,n,r,i){var a,o;if(i===g(e,t,n,r)>0)for(a=t;a<n;a+=r)o=O(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=O(a,e[a],e[a+1],o);return o&&T(o,o.next)&&(I(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(I(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,_=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?a(e,c,l,f):i(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),I(e),e=m.next,_=m.next;else if((e=m)===_){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(_(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&y(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(y(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&_(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&_(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!T(i,a)&&R(i,r,r.next,a)&&S(i,a)&&S(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),I(r),I(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&p(s,c)){var l=N(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,i,a,o,u),void r(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,f=o<u-1?r[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=N(t,e);n(r,r.next)}}function f(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=l&&_(a<f?i:o,a,l,f,a<f?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<h||s===h&&r.x>n.x)&&S(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var i=e;do{null===i.z&&(i.z=E(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function _(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function p(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!A(e,t)&&S(e,t)&&S(t,e)&&v(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function A(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function S(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function v(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function N(e,t){var n=new M(e.i,e.x,e.y),r=new M(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function O(e,t,n,r){var i=new M(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function I(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function M(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function g(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(g(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(g(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var _=new n,p=new n,y=new n,T=new n,R=new n,A=new n,S=new n;return m.computeSubdivision=function(e,t,r,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),v=0;for(h=0;h<E;h++){var N=t[h];m[v++]=N.x,m[v++]=N.y,m[v++]=N.z}for(var O=[],I={},M=e.maximumRadius,g=l.chordLength(u,M),w=g*g;d.length>0;){var x,C,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,_),F=n.fromArray(m,3*U,p),B=n.fromArray(m,3*P,y),b=n.multiplyByScalar(n.normalize(L,T),M,T),z=n.multiplyByScalar(n.normalize(F,R),M,R),q=n.multiplyByScalar(n.normalize(B,A),M,A),G=n.magnitudeSquared(n.subtract(b,z,S)),W=n.magnitudeSquared(n.subtract(z,q,S)),X=n.magnitudeSquared(n.subtract(q,b,S)),H=Math.max(G,W,X);H>w?G===H?(x=Math.min(D,U)+" "+Math.max(D,U),h=I[x],o(h)||(C=n.add(L,F,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,I[x]=h),d.push(D,h,P),d.push(h,U,P)):W===H?(x=Math.min(U,P)+" "+Math.max(U,P),h=I[x], -o(h)||(C=n.add(F,B,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,I[x]=h),d.push(U,h,D),d.push(h,P,D)):X===H&&(x=Math.min(P,D)+" "+Math.max(P,D),h=I[x],o(h)||(C=n.add(B,L,S),n.multiplyByScalar(C,.5,C),m.push(C.x,C.y,C.z),h=m.length/3-1,I[x]=h),d.push(P,h,U),d.push(h,D,U)):(O.push(D),O.push(U),O.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:m})},indices:O,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=d,c=E;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,i=(n-r)/n,a=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-i)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,a),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,_=m*m,p=_*m,y=_*_,T=1+m-3*_/4+5*p/4-175*y/64,R=1-m+15*_/8-35*p/8,A=1-3*m+35*_/4,S=1-5*m,v=T*l-R*Math.sin(2*l)*m/2-A*Math.sin(4*l)*_/16-S*Math.sin(6*l)*p/48-5*Math.sin(8*l)*y/512,N=e._constants;N.a=n,N.b=r,N.f=i,N.cosineHeading=a,N.sineHeading=o,N.tanU=u,N.cosineU=s,N.sineU=c,N.sigma=l,N.sineAlpha=f,N.sineSquaredAlpha=h,N.cosineSquaredAlpha=d,N.cosineAlpha=E,N.u2Over4=m,N.u4Over16=_,N.u6Over64=p,N.u8Over256=y,N.a0=T,N.a1=R,N.a2=A,N.a3=S,N.distanceRatio=v}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,i,a,o){var u=c(e,n);return(1-u)*e*t*(r+u*i*(o+u*a*(2*o*o-1)))}function f(e,t,n,r,i,a,o){var s,c,f,h,d,E=(t-n)/t,m=a-r,_=Math.atan((1-E)*Math.tan(i)),p=Math.atan((1-E)*Math.tan(o)),y=Math.cos(_),T=Math.sin(_),R=Math.cos(p),A=Math.sin(p),S=y*R,v=y*A,N=T*A,O=T*R,I=m,M=u.TWO_PI,g=Math.cos(I),w=Math.sin(I);do{g=Math.cos(I),w=Math.sin(I);var x=v-O*g;f=Math.sqrt(R*R*w*w+x*x),c=N+S*g,s=Math.atan2(f,c);var C;0===f?(C=0,h=1):(C=S*w/f,h=1-C*C),M=I,d=c-2*N/h,isNaN(d)&&(d=0),I=m+l(E,C,h,s,f,c,d)}while(Math.abs(I-M)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),B=n*U*(s-F),b=Math.atan2(R*w,v-O*g),z=Math.atan2(y*w,v*g-O);e._distance=B,e._startHeading=b,e._endHeading=z,e._uSquared=P}function h(n,r,i,a){e.normalize(a.cartographicToCartesian(r,m),E),e.normalize(a.cartographicToCartesian(i,m),m);f(n,a.maximumRadius,a.minimumRadius,r.longitude,r.latitude,i.longitude,i.latitude),n._start=t.clone(r,n._start),n._end=t.clone(i,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,a){var u=r(a,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,i(e)&&i(n)&&h(this,e,n,u)}var E=new e,m=new e;return a(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,a=r.distanceRatio+e/r.b,o=Math.cos(2*a),u=Math.cos(4*a),s=Math.cos(6*a),c=Math.sin(2*a),f=Math.sin(4*a),h=Math.sin(6*a),d=Math.sin(8*a),E=a*a,m=a*E,_=r.u8Over256,p=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*_*o/3+a*(1-p+7*T/4-15*y/4+579*_/64-(T-15*y/4+187*_/16)*o-(5*y/4-115*_/16)*u-29*_*s/16)+(p/2-T+71*y/32-85*_/16)*c+(5*T/16-5*y/4+383*_/96)*f-E*((y-11*_/2)*c+5*_*f/2)+(29*y/96-29*_/16)*h+539*_*d/1536,A=Math.asin(Math.sin(R)*r.cosineAlpha),S=Math.atan(r.a/r.b*Math.tan(A));R-=r.sigma;var v=Math.cos(2*r.sigma+R),N=Math.sin(R),O=Math.cos(R),I=r.cosineU*O,M=r.sineU*N,g=Math.atan2(N*r.sineHeading,I-M*r.cosineHeading),w=g-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,N,O,v);return i(n)?(n.longitude=this._start.longitude+w,n.latitude=S,n.height=0,n):new t(this._start.longitude+w,S,0)},d}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=N;r.length=e;var i;if(t===n){for(i=0;i<e;i++)r[i]=t;return r}var a=n-t,o=a/e;for(i=0;i<e;i++){var u=t+i*o;r[i]=u}return r}function d(t,n,r,i,a,o,u,s){var c=i.scaleToGeodeticSurface(t,g),l=i.scaleToGeodeticSurface(n,w),f=E.numberOfPoints(t,n,r),d=i.cartesianToCartographic(c,O),m=i.cartesianToCartographic(l,I),_=h(f,a,o);x.setEndPoints(d,m);var p=x.surfaceDistance/f,y=s;d.height=a;var T=i.cartographicToCartesian(d,M);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var A=x.interpolateUsingSurfaceDistance(R*p,I);A.height=_[R],T=i.cartographicToCartesian(A,M),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var i=e.distance(t,n);return Math.ceil(i/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),i=0;i<n;i++){var a=e[i];r[i]=t.cartesianToCartographic(a,m).height}return r};var _=new l,p=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,A=new f(e.UNIT_X,0),S=new e,v=new e,N=[],O=new t,I=new t,M=new e,g=new e,w=new e,x=new o;return E.wrapLongitude=function(t,i){var a=[],o=[];if(r(t)&&t.length>0){i=n(i,l.IDENTITY);var s=l.inverseTransformation(i,_),c=l.multiplyByPoint(s,e.ZERO,p),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,A),N=1;a.push(e.clone(t[0]));for(var O=a[0],I=t.length,M=1;M<I;++M){var g=t[M];if(f.getPointDistance(m,O)<0||f.getPointDistance(m,g)<0){var w=u.lineSegmentPlane(O,g,d,S);if(r(w)){var x=e.multiplyByScalar(h,5e-9,v);f.getPointDistance(d,O)<0&&e.negate(x,x),a.push(e.add(w,x,new e)),o.push(N+1),e.negate(x,x),a.push(e.add(w,x,new e)),N=1}}a.push(e.clone(t[M])),N++,O=g}o.push(N)}return{positions:a,lengths:o}},E.generateArc=function(t){r(t)||(t={});var i=t.positions,o=i.length,u=n(t.ellipsoid,a.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(i[0],g);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,M);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var _=t.minDistance;if(!r(_)){var p=n(t.granularity,c.RADIANS_PER_DEGREE);_=c.chordLength(p,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(i[y],i[y+1],_);var R=3*(T+1),A=new Array(R),S=0;for(y=0;y<o-1;y++){S=d(i[y],i[y+1],_,u,f?l[y]:l,f?l[y+1]:l,A,S)}N.length=0;var v=i[o-1],I=u.cartesianToCartographic(v,O);I.height=f?l[o-1]:l;var w=u.cartographicToCartesian(I,M);return e.pack(w,A,R-3),A},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,i=new Array(r),a=0;a<r;a++)i[a]=e.unpack(n,3*a);return i},E}),define("Core/WallGeometryLibrary",["./Cartographic","./defined","./EllipsoidTangentPlane","./Math","./PolygonPipeline","./PolylinePipeline","./WindingOrder"],function(e,t,n,r,i,a,o){"use strict";function u(e,t){return r.equalsEpsilon(e.latitude,t.latitude,r.EPSILON14)&&r.equalsEpsilon(e.longitude,t.longitude,r.EPSILON14)}function s(n,r,i,a){var o=r.length;if(!(o<2)){var s=t(a),c=t(i),h=!0,d=new Array(o),E=new Array(o),m=new Array(o),_=r[0];d[0]=_;var p=n.cartesianToCartographic(_,l);c&&(p.height=i[0]),h=h&&p.height<=0,E[0]=p.height,m[0]=s?a[0]:0;for(var y=1,T=1;T<o;++T){var R=r[T],A=n.cartesianToCartographic(R,f);c&&(A.height=i[T]),h=h&&A.height<=0,u(p,A)?p.height<A.height&&(E[y-1]=A.height):(d[y]=R,E[y]=A.height,m[y]=s?a[T]:0,e.clone(A,p),++y)}if(!(h||y<2))return d.length=y,E.length=y,m.length=y,{positions:d,topHeights:E,bottomHeights:m}}}var c={},l=new e,f=new e,h=new Array(2),d=new Array(2),E={positions:void 0,height:void 0,granularity:void 0,ellipsoid:void 0};return c.computePositions=function(e,u,c,l,f,m){var _=s(e,u,c,l);if(t(_)){if(u=_.positions,c=_.topHeights,l=_.bottomHeights,u.length>=3){var p=n.fromPoints(u,e),y=p.projectPointsOntoPlane(u);i.computeWindingOrder2D(y)===o.CLOCKWISE&&(u.reverse(),c.reverse(),l.reverse())}var T,R,A=u.length,S=A-2,v=r.chordLength(f,e.maximumRadius),N=E;if(N.minDistance=v,N.ellipsoid=e,m){var O,I=0;for(O=0;O<A-1;O++)I+=a.numberOfPoints(u[O],u[O+1],v)+1;T=new Float64Array(3*I),R=new Float64Array(3*I);var M=h,g=d;N.positions=M,N.height=g;var w=0;for(O=0;O<A-1;O++){M[0]=u[O],M[1]=u[O+1],g[0]=c[O],g[1]=c[O+1];var x=a.generateArc(N);T.set(x,w),g[0]=l[O],g[1]=l[O+1],R.set(a.generateArc(N),w),w+=x.length}}else N.positions=u,N.height=c,T=new Float64Array(a.generateArc(N)),N.height=l,R=new Float64Array(a.generateArc(N));return{bottomPositions:R,topPositions:T,numCorners:S}}},c}),define("Core/WallOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./WallGeometryLibrary"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e){e=r(e,r.EMPTY_OBJECT);var n=e.positions,a=e.maximumHeights,u=e.minimumHeights,s=r(e.granularity,f.RADIANS_PER_DEGREE),c=r(e.ellipsoid,o.WGS84);this._positions=n,this._minimumHeights=u,this._maximumHeights=a,this._granularity=s,this._ellipsoid=o.clone(c),this._workerName="createWallOutlineGeometry";var l=1+n.length*t.packedLength+2;i(u)&&(l+=u.length),i(a)&&(l+=a.length),this.packedLength=l+o.packedLength+1}var m=new t,_=new t;E.pack=function(e,n,a){a=r(a,0);var u,s=e._positions,c=s.length;for(n[a++]=c,u=0;u<c;++u,a+=t.packedLength)t.pack(s[u],n,a);var l=e._minimumHeights;if(c=i(l)?l.length:0,n[a++]=c,i(l))for(u=0;u<c;++u)n[a++]=l[u];var f=e._maximumHeights;if(c=i(f)?f.length:0,n[a++]=c,i(f))for(u=0;u<c;++u)n[a++]=f[u];return o.pack(e._ellipsoid,n,a),a+=o.packedLength,n[a]=e._granularity,n};var p=o.clone(o.UNIT_SPHERE),y={positions:void 0,minimumHeights:void 0,maximumHeights:void 0,ellipsoid:p,granularity:void 0};return E.unpack=function(e,n,a){n=r(n,0);var u,s=e[n++],c=new Array(s);for(u=0;u<s;++u,n+=t.packedLength)c[u]=t.unpack(e,n);s=e[n++];var l;if(s>0)for(l=new Array(s),u=0;u<s;++u)l[u]=e[n++];s=e[n++];var f;if(s>0)for(f=new Array(s),u=0;u<s;++u)f[u]=e[n++];var h=o.unpack(e,n,p);n+=o.packedLength;var d=e[n];return i(a)?(a._positions=c,a._minimumHeights=l,a._maximumHeights=f,a._ellipsoid=o.clone(h,a._ellipsoid),a._granularity=d,a):(y.positions=c,y.minimumHeights=l,y.maximumHeights=f,y.granularity=d,new E(y))},E.fromConstantHeights=function(e){e=r(e,r.EMPTY_OBJECT);var t,n,a=e.positions,o=e.minimumHeight,u=e.maximumHeight,s=i(o),c=i(u);if(s||c){var l=a.length;t=s?new Array(l):void 0,n=c?new Array(l):void 0;for(var f=0;f<l;++f)s&&(t[f]=o),c&&(n[f]=u)}return new E({positions:a,maximumHeights:n,minimumHeights:t,ellipsoid:e.ellipsoid})},E.createGeometry=function(r){var a=r._positions,o=r._minimumHeights,E=r._maximumHeights,p=r._granularity,y=r._ellipsoid,T=d.computePositions(y,a,E,o,p,!1);if(i(T)){var R=T.bottomPositions,A=T.topPositions,S=A.length,v=2*S,N=new Float64Array(v),O=0;S/=3;var I;for(I=0;I<S;++I){var M=3*I,g=t.fromArray(A,M,m),w=t.fromArray(R,M,_);N[O++]=w.x,N[O++]=w.y,N[O++]=w.z,N[O++]=g.x,N[O++]=g.y,N[O++]=g.z}var x=new c({position:new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:N})}),C=v/3;v=2*C-4+C;var P=l.createTypedArray(C,v),U=0;for(I=0;I<C-2;I+=2){var D=I,L=I+2,F=t.fromArray(N,3*D,m),B=t.fromArray(N,3*L,_);if(!t.equalsEpsilon(F,B,f.EPSILON10)){var b=I+1,z=I+3;P[U++]=b,P[U++]=D,P[U++]=b,P[U++]=z,P[U++]=D,P[U++]=L}}return P[U++]=C-2,P[U++]=C-1,new u({attributes:x,indices:P,primitiveType:h.LINES,boundingSphere:new e.fromVertices(N)})}},E}),define("Workers/createWallOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/WallOutlineGeometry"],function(e,t,n){"use strict";function r(r,i){return e(i)&&(r=n.unpack(r,i)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,E=i.y,m=i.z,p=l*l*d*d,_=f*f*E*E,y=h*h*m*m,T=p+_+y,R=Math.sqrt(1/T),v=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(v,c):void 0;var A=u.x,S=u.y,O=u.z,g=o;g.x=v.x*A*2,g.y=v.y*S*2,g.z=v.z*O*2;var N,I,M,w,C,x,P,U,D,L,F,b=(1-R)*e.magnitude(n)/(.5*e.magnitude(g)),B=0;do{b-=B,M=1/(1+b*A),w=1/(1+b*S),C=1/(1+b*O),x=M*M,P=w*w,U=C*C,D=x*M,L=P*w,F=U*C,N=p*x+_*P+y*U-1,I=p*D*A+_*L*S+y*F*O;B=N/(-2*I)}while(Math.abs(N)>r.EPSILON12);return t(c)?(c.x=l*M,c.y=f*w,c.z=h*C,c):new e(l*M,f*w,h*C)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),v=Math.asin(y.z),A=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=v,i.height=A,i):new u(R,v,A)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,E),u=e.subtract(n,a,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],E[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=E[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(i-h),p=2*(a+l),_=2*(i+h),y=-n+u-f+d,T=2*(c-o),R=2*(a-l),v=2*(c+o),A=-n-u+f+d;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=v,t[6]=p,t[7]=T,t[8]=A,t):new s(E,m,p,_,y,T,R,v,A)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,E=a*i+c*o*u,m=-c*i+a*o*u,p=-o,_=c*n,y=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error +}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),v=2*(f+m),A=2*(c+_),S=-s+d-p+y,O=2*(E-h),g=2*(f-m),N=2*(E+h),I=-s-d+p+y;return r[0]=T*a,r[1]=A*a,r[2]=g*a,r[3]=0,r[4]=R*o,r[5]=S*o,r[6]=N*o,r[7]=0,r[8]=v*u,r[9]=O*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,v=r.y,A=r.z,S=u*-R+s*-v+c*-A,O=_*-R+y*-v+T*-A,g=E*R+m*v+p*A;return i(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=S,n[13]=O,n[14]=g,n[15]=1,n):new l(u,s,c,S,_,y,T,O,-E,-m,-p,g,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=a+c,p=o+l,_=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=m,i[13]=p,i[14]=_,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],v=t[2],A=t[3],S=t[4],O=t[5],g=t[6],N=t[7],I=t[8],M=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*v+m*A,F=i*T+s*R+h*v+p*A,b=a*T+c*R+d*v+_*A,B=o*T+l*R+E*v+y*A,z=r*S+u*O+f*g+m*N,q=i*S+s*O+h*g+p*N,G=a*S+c*O+d*g+_*N,W=o*S+l*O+E*g+y*N,X=r*I+u*M+f*w+m*C,V=i*I+s*M+h*w+p*C,H=a*I+c*M+d*w+_*C,Y=o*I+l*M+E*w+y*C,k=r*x+u*P+f*U+m*D,j=i*x+s*P+h*U+p*D,Z=a*x+c*P+d*U+_*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=b,n[3]=B,n[4]=z,n[5]=q,n[6]=G,n[7]=W,n[8]=X,n[9]=V,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],v=t[8],A=t[9],S=t[10],O=t[12],g=t[13],N=t[14],I=r*m+o*p+c*_,M=i*m+u*p+l*_,w=a*m+s*p+f*_,C=r*y+o*T+c*R,x=i*y+u*T+l*R,P=a*y+s*T+f*R,U=r*v+o*A+c*S,D=i*v+u*A+l*S,L=a*v+s*A+f*S,F=r*O+o*g+c*N+h,b=i*O+u*g+l*N+d,B=a*O+s*g+f*N+E;return n[0]=I,n[1]=M,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=b,n[14]=B,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],v=r*h+o*d+c*E,A=i*h+u*d+l*E,S=a*h+s*d+f*E,O=r*m+o*p+c*_,g=i*m+u*p+l*_,N=a*m+s*p+f*_,I=r*y+o*T+c*R,M=i*y+u*T+l*R,w=a*y+s*T+f*R;return n[0]=v,n[1]=A,n[2]=S,n[3]=0,n[4]=O,n[5]=g,n[6]=N,n[7]=0,n[8]=I,n[9]=M,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],v=e[10],A=e[14],S=e[3],O=e[7],g=e[11],N=e[15],I=v*N,M=A*g,w=p*N,C=A*O,x=p*g,P=v*O,U=m*N,D=A*S,L=m*g,F=v*S,b=m*O,B=p*S,z=I*h+C*d+x*E-(M*h+w*d+P*E),q=M*f+U*d+F*E-(I*f+D*d+L*E),G=w*f+D*h+b*E-(C*f+U*h+B*E),W=P*f+L*h+B*d-(x*f+F*h+b*d),X=M*i+w*a+P*o-(I*i+C*a+x*o),V=I*r+D*a+L*o-(M*r+U*a+F*o),H=C*r+U*i+B*o-(w*r+D*i+b*o),Y=x*r+F*i+b*a-(P*r+L*i+B*a);I=a*E,M=o*d,w=i*E,C=o*h,x=i*d,P=a*h,U=r*E,D=o*f,L=r*d,F=a*f,b=r*h,B=i*f;var k=I*O+C*g+x*N-(M*O+w*g+P*N),j=M*S+U*g+F*N-(I*S+D*g+L*N),Z=w*S+D*O+b*N-(C*S+U*O+B*N),K=P*S+L*O+B*g-(x*S+F*O+b*g),J=w*v+P*A+M*p-(x*A+I*p+C*v),Q=L*A+I*m+D*v-(U*v+F*A+M*m),$=U*p+B*A+C*m-(b*A+w*m+D*p),ee=b*v+x*m+F*p-(L*p+B*v+P*m),te=r*z+i*q+a*G+o*W;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=W*te,n[4]=X*te,n[5]=V*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-i*d,m=-a*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,E),o=Math.max(o,E)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=i,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,v=new e,A=new e,S=new e,O=new e,g=new e,N=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,E),u=e.clone(i,m),s=e.clone(i,p),c=e.clone(i,_),l=e.clone(i,y),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var N=i.x,I=i.y,M=i.z;N<o.x&&e.clone(i,o),N>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),M<s.z&&e.clone(i,s),M>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,v)),C=e.magnitudeSquared(e.subtract(l,u,v)),x=e.magnitudeSquared(e.subtract(f,s,v)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,v)),b=Math.sqrt(F),B=S;B.x=o.x,B.y=u.y,B.z=s.z;var z=O;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(B,z,v),.5,g),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var W=e.magnitude(e.subtract(i,q,v));W>G&&(G=W);var X=e.magnitudeSquared(e.subtract(i,L,v));if(X>F){var V=Math.sqrt(X);b=.5*(b+V),F=b*b;var H=V-b;L.x=(b*L.x+H*i.x)/V,L.y=(b*L.y+H*i.y)/V,L.z=(b*L.z+H*i.z)/V}}return b<G?(e.clone(L,n.center),n.radius=b):(e.clone(q,n.center),n.radius=G),n};var I=new u,M=new e,w=new e,C=new t,x=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,I),h.southwest(t,C),C.height=r,h.northeast(t,x),x.height=o;var s=n.project(C,M),c=n.project(x,w),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,m),f=e.clone(u,p),h=e.clone(u,_),N=e.clone(u,y),I=e.clone(u,T),M=t.length;for(s=0;s<M;s+=r){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>h.x&&e.clone(u,h),C<l.y&&e.clone(u,l),C>N.y&&e.clone(u,N),x<f.z&&e.clone(u,f),x>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(h,c,v)),U=e.magnitudeSquared(e.subtract(N,l,v)),D=e.magnitudeSquared(e.subtract(I,f,v)),L=c,F=h,b=P;U>b&&(b=U,L=l,F=N),D>b&&(b=D,L=f,F=I);var B=A;B.x=.5*(L.x+F.x),B.y=.5*(L.y+F.y),B.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,B,v)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var W=O;W.x=h.x,W.y=N.y,W.z=I.z;var X=e.multiplyByScalar(e.add(G,W,v),.5,g),V=0;for(s=0;s<M;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,v));H>V&&(V=H);var Y=e.magnitudeSquared(e.subtract(u,B,v));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;B.x=(q*B.x+j*u.x)/k,B.y=(q*B.y+j*u.y)/k,B.z=(q*B.z+j*u.z)/k}}return q<V?(e.clone(B,o.center),o.radius=q):(e.clone(X,o.center),o.radius=V),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),h=e.clone(i,T),N=t.length;for(o=0;o<N;o+=3){var I=t[o]+n[o],M=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=I,i.y=M,i.z=w,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),M<s.y&&e.clone(i,s),M>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>h.z&&e.clone(i,h)}var C=e.magnitudeSquared(e.subtract(l,u,v)),x=e.magnitudeSquared(e.subtract(f,s,v)),P=e.magnitudeSquared(e.subtract(h,c,v)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var b=e.magnitudeSquared(e.subtract(D,F,v)),B=Math.sqrt(b),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=O;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,v),.5,g),W=0;for(o=0;o<N;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,G,v));X>W&&(W=X);var V=e.magnitudeSquared(e.subtract(i,F,v));if(V>b){var H=Math.sqrt(V);B=.5*(B+H),b=B*B;var Y=H-B;F.x=(B*F.x+Y*i.x)/H,F.y=(B*F.y+Y*i.y)/H,F.z=(B*F.z+Y*i.z)/H}}return B<W?(e.clone(F,r.center),r.radius=B):(e.clone(G,r.center),r.radius=W),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var b=new e,B=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,b),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,B);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r},d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var W=new e,X=new e,V=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,W),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,V);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=a.cartesianToCartographic(y,k);n.project(T,y)}r=d.fromPoints(E,r),o=r.center;var R=o.x,v=o.y,A=o.z;return o.x=A,o.y=R,o.z=v,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return N*e*e*e},d}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(v)&&(v=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,A=r(e[1]))}return v}function a(){return i()&&A}function o(){if(!t(S)&&(S=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(S=!0,O=r(e[1]))}return S}function u(){return o()&&O}function s(){if(!t(g)){g=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(g=!0, +N=r(e[1]),N.isNightly=!!e[2])}return g}function c(){return s()&&N}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,M=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,M=r(e[1]))}return I}function f(){return l()&&M}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var v,A,S,O,g,N,I,M,w,C,x,P,U,D,L,F,b={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return b.supportsFullscreen=function(){return n.supportsFullscreen()},b.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},b.supportsWebWorkers=function(){return"undefined"!=typeof Worker},b}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/GeometryType",["./freezeObject"],function(e){"use strict";return e({NONE:0,TRIANGLES:1,LINES:2,POLYLINES:3})}),define("Core/PrimitiveType",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={POINTS:t.POINTS,LINES:t.LINES,LINE_LOOP:t.LINE_LOOP,LINE_STRIP:t.LINE_STRIP,TRIANGLES:t.TRIANGLES,TRIANGLE_STRIP:t.TRIANGLE_STRIP,TRIANGLE_FAN:t.TRIANGLE_FAN,validate:function(e){return e===n.POINTS||e===n.LINES||e===n.LINE_LOOP||e===n.LINE_STRIP||e===n.TRIANGLES||e===n.TRIANGLE_STRIP||e===n.TRIANGLE_FAN}};return e(n)}),define("Core/Geometry",["./Check","./defaultValue","./defined","./DeveloperError","./GeometryType","./PrimitiveType"],function(e,t,n,r,i,a){"use strict";function o(e){e=t(e,t.EMPTY_OBJECT),this.attributes=e.attributes,this.indices=e.indices,this.primitiveType=t(e.primitiveType,a.TRIANGLES),this.boundingSphere=e.boundingSphere,this.geometryType=t(e.geometryType,i.NONE),this.boundingSphereCV=e.boundingSphereCV}return o.computeNumberOfVertices=function(e){var t=-1;for(var r in e.attributes)if(e.attributes.hasOwnProperty(r)&&n(e.attributes[r])&&n(e.attributes[r].values)){var i=e.attributes[r],a=i.values.length/i.componentsPerAttribute;t=a}return t},o}),define("Core/GeometryAttribute",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){t=e(t,e.EMPTY_OBJECT),this.componentDatatype=t.componentDatatype,this.componentsPerAttribute=t.componentsPerAttribute,this.normalize=e(t.normalize,!1),this.values=t.values}return r}),define("Core/GeometryAttributes",["./defaultValue"],function(e){"use strict";function t(t){t=e(t,e.EMPTY_OBJECT),this.position=t.position,this.normal=t.normal,this.st=t.st,this.bitangent=t.bitangent,this.tangent=t.tangent,this.color=t.color}return t}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;i=Math.min(E,i),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=i,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,_=4*E*p-m*m;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var v=R<0?-1:1,A=-v*Math.abs(y)*Math.sqrt(-_);a=-R+A;var S=a/2,O=S<0?-Math.pow(-S,1/3):Math.pow(S,1/3),g=a===A?-O:-T/O;return i=T<=0?O+g:-R/(O*O+g*g+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var N=E,I=-2*u*E+o*m,M=p,w=-c*m+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-I)/3);i=2*Math.sqrt(-N);var U=Math.cos(P);a=i*U;var D=i*(-U/2-x*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,b=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),i=2*Math.sqrt(-M),U=Math.cos(P),a=i*U,D=i*(-U/2-x*Math.sin(P));var B=-c,z=a+D<2*s?a+s:D+s,q=B/z,G=F*z,W=-L*z-F*B,X=L*B,V=(s*W-u*X)/(-u*W+s*G);return b<=V?b<=q?V<=q?[b,V,q]:[b,q,V]:[q,b,V]:b<=q?[V,b,q]:V<=q?[V,q,b]:[q,V,b]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),v=(s+d-c/R)/2,A=(s+d+c/R)/2,S=r.computeRealRoots(1,R,v),O=r.computeRealRoots(1,-R,A);return 0!==S.length?(S[0]+=h,S[1]+=h,0!==O.length?(O[0]+=h,O[1]+=h,S[1]<=O[0]?[S[0],S[1],O[0],O[1]]:O[1]<=S[0]?[O[0],O[1],S[0],S[1]]:S[0]>=O[0]&&S[1]<=O[1]?[O[0],S[0],S[1],O[1]]:O[0]>=S[0]&&O[1]<=S[1]?[S[0],O[0],O[1],S[1]]:S[0]>O[0]&&S[0]<O[1]?[O[0],S[0],O[1],S[1]]:[S[0],O[0],S[1],O[1]]):S):0!==O.length?(O[0]+=h,O[1]+=h,O):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],_=i-p,y=_*_,T=t/2,R=_/2,v=y-4*o,A=y+4*Math.abs(o),S=c-4*p,O=c+4*Math.abs(p);if(p<0||v*O<S*A){var g=Math.sqrt(S);E=g/2,m=0===g?0:(t*R-a)/g}else{var N=Math.sqrt(v);E=0===N?0:(t*R-a)/N,m=N/2}var I,M;0===T&&0===E?(I=0,M=0):n.sign(T)===n.sign(E)?(I=T+E,M=p/I):(M=T-E,I=p/M);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,I,w),P=r.computeRealRoots(1,M,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,A);if(r(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,i,a){var l,f=i*i,h=a*a,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],v=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-v)),T.push(new e(i,a*R,a*v)),2===l.length){var A=l[1],S=Math.sqrt(Math.max(1-A*A,0));T.push(new e(i,a*A,a*-S)),T.push(new e(i,a*A,a*S))}return T}var O=y*y,g=_*_,N=E*E,I=y*_,M=N+g,w=2*(m*E+I),C=2*p*E+m*m-g+O,x=2*(p*m-I),P=p*p-O;if(0===M&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(M,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],b=F*F,B=Math.max(1-b,0),z=Math.sqrt(B);L=o.sign(E)===o.sign(p)?d(E*b+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?d(E*b,m*F+p,o.EPSILON12):d(E*b+m*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var m={};m.rayPlane=function(t,n,i){r(i)||(i=new e) +;var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(i,r,p),v=e.subtract(a,r,_),A=e.cross(E,v,y),S=e.dot(m,A);if(u){if(S<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,A))<0||l>S)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>S)return;h=e.dot(v,c)/S}else{if(Math.abs(S)<o.EPSILON6)return;var O=1/S;if(s=e.subtract(d,r,T),(l=e.dot(s,A)*O)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*O)<0||l+f>1)return;h=e.dot(v,c)*O}return h},m.rayTriangle=function(t,n,i,a,o,u){var s=m.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var v=new l;m.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=v;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var A={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var S=new l;m.lineSegmentSphere=function(t,n,i,a){var o=S;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var O=new e,g=new e;m.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,O),f=e.multiplyComponents(c,t.direction,g),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,p=r/s;return m<p?new a(m,p):{start:p,stop:m}}var _=Math.sqrt(r/i);return new a(_,_)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var N=new e,I=new e,M=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,b=new u,B=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,N);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,N),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,I),I),m=e.normalize(e.cross(f,d,M),M),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var v,A,S=u.multiply(u.multiply(_,T,F),R,F),O=u.multiply(u.multiply(S,y,b),p,b),g=u.multiplyByVector(S,i,C),G=E(O,e.negate(g,N),0,0,1),W=G.length;if(W>0){for(var X=e.clone(e.ZERO,z),V=Number.NEGATIVE_INFINITY,H=0;H<W;++H){v=u.multiplyByVector(y,u.multiplyByVector(p,G[H],B),B);var Y=e.normalize(e.subtract(v,i,w),w),k=e.dot(Y,a);k>V&&(V=k,X=e.clone(v,X))}var j=n.cartesianToCartographic(X,q);return V=o.clamp(V,0,1),A=e.magnitude(e.subtract(X,i,w))*Math.sqrt(1-V*V),A=c?-A:A,j.height=A,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function i(e){return E(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=_,m(l,e),f=l=v,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=_,d.reject(h))},E=function(e){f.push(e),--c||(E=m=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function E(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,v;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(v,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(v,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,v=!1,A=" ",S=s.length,O=0;s&&O<S;O++)switch(s.charAt(O)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":A=s.charAt(O+1);break;case"0":R=!0;break;case"#":v=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,A);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,v,y,c,f,R);case"o":return o(_,8,v,y,c,f,R);case"x":return o(_,16,v,y,c,f,R);case"X":return o(_,16,v,y,c,f,R).toUpperCase();case"u":return o(_,10,v,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),E=d<0?"-":T,_=E+i(String(Math.abs(d)),f,"0",!1),a(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=E+Math.abs(d)[m](f),a(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}m.addSeconds(e,i,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,i=t(r,y,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-r[0].offset,n);if(i>=r.length)return m.addSeconds(e,-r[i-1].offset,n);var a=m.secondsDifference(r[i].julianDate,e);return 0===a?m.addSeconds(e,-r[i].offset,n):a<=1?void 0:m.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var p=new a,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,v=/^(\d{4})-?(\d{3})$/,A=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,S=/^(\d{4})-?(\d{2})-?(\d{2})$/,O=/([Z+\-])?(\d{2})?:?(\d{2})?$/,g=/^(\d{2})(\.\d+)?/.source+O.source,N=/^(\d{2}):?(\d{2})(\.\d+)?/.source+O.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+O.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,O=0,M=u[0],w=u[1];if(null!==(u=M.match(S)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=M.match(R)))n=+u[1],s=+u[2];else if(null!==(u=M.match(T)))n=+u[1];else{var C;if(null!==(u=M.match(v)))n=+u[1],C=+u[2],a=o(n);else if(null!==(u=M.match(A))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(C),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(w)){u=w.match(I),null!==u?(h=+u[1],p=+u[2],y=+u[3],O=1e3*+(u[4]||0),D=5):(u=w.match(N),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(g))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],b=+(u[D+2]||0);switch(L){case"+":h-=F,p-=b;break;case"-":h+=F,p+=b;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var B=60===y;for(B&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:_[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:_[s-1],l+=i;var z=E(n,s,l,h,p,y,O);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),B&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var M=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,i=h(e,M);r(i)||(m.addSeconds(e,-1,M),i=h(M,M),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var v=0|T,A=(T-v)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(v+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=v,t.millisecond=A,t.isLeapSecond=n,t):new a(_,p,E,y,R,v,A,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var i,a=m.toGregorianDate(t,p);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return g[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--v.numberOfActiveRequests,--g[e.serverKey],I.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){return function(t){e.state!==c.CANCELLED&&(++v.numberOfFailedRequests,--v.numberOfActiveRequests,--g[e.serverKey],I.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function _(e){var t=E(e);return e.state=c.ACTIVE,O.push(e),++v.numberOfActiveRequests,++v.numberOfActiveRequestsEver,++g[e.serverKey],e.requestFunction().then(m(e)).otherwise(p(e)),t}function y(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++v.numberOfCancelledRequests,e.deferred.reject(),t&&(--v.numberOfActiveRequests,--g[e.serverKey],++v.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){v.numberOfAttemptedRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(v.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+v.numberOfAttemptedRequests),v.numberOfActiveRequests>0&&console.log("Number of active requests: "+v.numberOfActiveRequests),v.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+v.numberOfCancelledRequests),v.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+v.numberOfCancelledActiveRequests), +v.numberOfFailedRequests>0&&console.log("Number of failed requests: "+v.numberOfFailedRequests),T())}var v={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new o({comparator:l});S.maximumLength=A,S.reserve(A);var O=[],g={},N="undefined"!=typeof document?new e(document.location.href):new e,I=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=I,i(f,{statistics:{get:function(){return v}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();y(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),f.update=function(){var e,t,n=0,r=O.length;for(e=0;e<r;++e)t=O[e],t.cancelled&&y(t),t.state===c.ACTIVE?n>0&&(O[e-n]=t):++n;O.length-=n;var i=S.internalArray,a=S.length;for(e=0;e<a;++e)h(i[e]);S.resort();for(var o=Math.max(f.maximumRequests-O.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):y(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(N);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=g[i];return r(a)||(g[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return I.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++v.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return _(e);if(!(O.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=S.insert(e);if(r(t)){if(t===e)return;y(t)}return E(e)}},f.clearForSpecs=function(){for(;S.length>0;){y(S.pop())}for(var e=O.length,t=0;t<e;++t)y(O[t]);O.length=0,g={},v.numberOfAttemptedRequests=0,v.numberOfActiveRequests=0,v.numberOfCancelledRequests=0,v.numberOfCancelledActiveRequests=0,v.numberOfFailedRequests=0,v.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return g[e]},f.requestHeap=S,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}),define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,p,_,y,T,R,v,A,S,O,g){"use strict";function N(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=_(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function I(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=p(n):e.query=r[0]}function M(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function w(e){if(e.state===v.ISSUED||e.state===v.ACTIVE)throw new A("The Resource is already being fetched.");e.state=v.UNISSUED,e.deferred=void 0}function C(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=M(e.templateValues,{}),this._queryParameters=M(e.queryParameters,{}),this.headers=M(e.headers,{}),this.request=i(e.request,new y),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function x(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=g.defer();return C._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==v.FAILED?g.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,x(e,t)):g.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=g.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},C._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==v.FAILED?g.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=v.UNISSUED,i.deferred=void 0,P(e,t,n)):g.reject(r)})})}function U(e,t){w(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=g.defer(),f=C._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==v.FAILED?g.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=v.UNISSUED,n.deferred=void 0,e.fetch(t)):g.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var b=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();C.createIfNeeded=function(e,t){if(e instanceof C)return e.clone();if("string"!=typeof e)return e;var n=M(t,{});return n.url=e,new C(n)},o(C,{isBlobSupported:{get:function(){return b}}}),o(C.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new O(e);N(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),C.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new O(this._url);e&&I(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},C.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},C.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},C.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new O(e.url);N(n,t),n.fragment=void 0,t._url=n.resolve(new O(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},C.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return g(!1);var n=this;return g(t(this,e)).then(function(e){return++n._retryCount,e})},C.prototype.clone=function(e){return a(e)||(e=new C({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},C.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},C.prototype.appendForwardSlash=function(){this._url=e(this._url)},C.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},C.fetchArrayBuffer=function(e){return new C(e).fetchArrayBuffer()},C.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},C.fetchBlob=function(e){return new C(e).fetchBlob()},C.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),w(this.request),!b||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return x(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new C({url:t}),x(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),g.reject(e)})}},C.fetchImage=function(e){return new C(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},C.prototype.fetchText=function(){return this.fetch({responseType:"text"})},C.fetchText=function(e){return new C(e).fetchText()},C.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},C.fetchJson=function(e){return new C(e).fetchJson()},C.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},C.fetchXML=function(e){return new C(e).fetchXML()},C.prototype.fetchJsonp=function(e){e=i(e,"callback"),w(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},C.fetchJsonp=function(e){return new C(e).fetchJsonp(e.callbackParameterName)},C.prototype.fetch=function(e){return e=M(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var B=/^data:(.*?)(;base64)?,(.*)$/;return C.fetch=function(e){return new C(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C.prototype.post=function(e,n){return t.defined("data",e),n=M(n,{}),n.method="POST",n.data=e,U(this,n)},C.post=function(e){return new C(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C._Implementations={},C._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(S.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},C._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=B.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(S.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new A("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},C._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},C._DefaultImplementations={},C._DefaultImplementations.createImage=C._Implementations.createImage,C._DefaultImplementations.loadWithXhr=C._Implementations.loadWithXhr,C._DefaultImplementations.loadAndExecuteScript=C._Implementations.loadAndExecuteScript,C.DEFAULT=c(new C({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),C}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,v=p.length;R<v;R+=e._columnCount){var A=p[R+i],S=p[R+m],O=A+l.MODIFIED_JULIAN_DATE_DIFFERENCE,g=new o(O,S,f.TAI);if(_.push(g),T){if(S!==y&&r(y)){var N=o.leapSeconds,I=t(N,g,d);if(I<0){var M=new u(g,S);N.splice(~I,0,M)}}y=S}}}function m(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return m(e,n,i,s,u),u;if(r.equals(l))return m(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,E=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,_(this,a,this._samples,e,s,l,n),n}var p=t(a,e,o.compare,this._dateColumn);return p>=0?(p<a.length-1&&a[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var E,m,p=a-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var v=3*(s+E);n.x+=T[E]*d[v++],n.y+=T[E]*d[v++],n.s+=T[E]*d[v]}return n}}}},s}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),E>h&&E>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,E=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var v=new s;s.lerp=function(e,t,n,r){return v=s.multiplyByScalar(t,n,v),r=s.multiplyByScalar(e,1-n,r),s.add(v,r,r)};var A=new s,S=new s,O=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=A=s.negate(t,A)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return S=s.multiplyByScalar(e,Math.sin((1-n)*u),S),O=s.multiplyByScalar(a,Math.sin(n*u),O),r=s.add(S,O,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var g=new e,N=new e,I=new s,M=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,I);s.multiply(a,r,M);var o=s.log(M,g);s.multiply(a,t,M);var u=s.log(M,N);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,I),u=s.slerp(n,r,i,M);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,C=1.9011074535173003,x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,b=2*F+1;x[L]=1/(F*b),P[L]=F/b}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,I),u=s.fastSlerp(n,r,i,M);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,p,_,y,T){"use strict";var R={},v={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},A={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},S={},O={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},g=new n,N=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!v.hasOwnProperty(e)||!v[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=v[e][t],a=e+t;return u(S[a])?r=S[a]:(r=function(r,a,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(A[e],0,g),"east"!==e&&"west"!==e&&n.multiplyByScalar(g,c,g),n.unpack(A[t],0,N),"east"!==t&&"west"!==t&&n.multiplyByScalar(N,c,N),n.unpack(A[i],0,I),"east"!==i&&"west"!==i&&n.multiplyByScalar(I,c,I)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,O.up);var l=O.up,h=O.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,O.east),n.cross(l,h,O.north),n.multiplyByScalar(O.up,-1,O.down),n.multiplyByScalar(O.east,-1,O.west),n.multiplyByScalar(O.north,-1,O.south),g=O[e],N=O[t],I=O[i]}return s[0]=g.x,s[1]=g.y,s[2]=g.z,s[3]=0,s[4]=N.x,s[5]=N.y,s[6]=N.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},S[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var M=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,M),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return a=i(e,r,a),_.multiply(a,s,a)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(a,P);return y.fromRotationMatrix(o,i)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),b=new p,B=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=b;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-a.s,B),h=p.multiply(l,f,b),d=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,v=_/T.SECONDS_PER_DAY,A=.779057273264+v+.00273781191135448*(y+v);A=A%1*m.TWO_PI +;var S=p.fromRotationZ(A,B),O=p.multiply(h,S,b),g=Math.cos(n.xPoleWander),N=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),M=Math.sin(n.yPoleWander),w=r-2451545+i/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=B;return U[0]=g*x,U[1]=g*P,U[2]=I,U[3]=-N*P+M*I*x,U[4]=N*x+M*I*P,U[5]=-M*g,U[6]=-M*P-N*I*x,U[7]=M*x-N*I*P,U[8]=N*g,p.multiply(O,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return _.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,W=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,W);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new p),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var X=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),V=new i,H=new n,Y=new n,k=new p,j=new _,Z=new _;return R.basisTo2D=function(e,t,r){var i=_.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,V),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=_.inverseTransformation(s,Z),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(X,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=_.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,V),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,j);return _.multiply(X,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var a=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,a)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var i=_;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,y);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=_;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,y);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},E}),define("ThirdParty/earcut-2.1.1",[],function(){"use strict";function e(e,n,i){i=i||2;var a=n&&n.length,o=a?n[0]*i:e.length,u=t(e,0,o,i,!0),c=[];if(!u)return c;var l,f,h,d,E,m,p;if(a&&(u=s(e,n,u,i)),e.length>80*i){l=h=e[0],f=d=e[1];for(var _=i;_<o;_+=i)E=e[_],m=e[_+1],E<l&&(l=E),m<f&&(f=m),E>h&&(h=E),m>d&&(d=m);p=Math.max(h-l,d-f)}return r(u,c,i,l,f,p),c}function t(e,t,n,r,i){var a,o;if(i===M(e,t,n,r)>0)for(a=t;a<n;a+=r)o=g(a,e[a],e[a+1],o);else for(a=n-r;a>=t;a-=r)o=g(a,e[a],e[a+1],o);return o&&T(o,o.next)&&(N(o),o=o.next),o}function n(e,t){if(!e)return e;t||(t=e);var n,r=e;do{if(n=!1,r.steiner||!T(r,r.next)&&0!==y(r.prev,r,r.next))r=r.next;else{if(N(r),(r=t=r.prev)===r.next)return null;n=!0}}while(n||r!==t);return t}function r(e,t,s,c,l,f,d){if(e){!d&&f&&h(e,c,l,f);for(var E,m,p=e;e.prev!==e.next;)if(E=e.prev,m=e.next,f?a(e,c,l,f):i(e))t.push(E.i/s),t.push(e.i/s),t.push(m.i/s),N(e),e=m.next,p=m.next;else if((e=m)===p){d?1===d?(e=o(e,t,s),r(e,t,s,c,l,f,2)):2===d&&u(e,t,s,c,l,f):r(n(e),t,s,c,l,f,1);break}}}function i(e){var t=e.prev,n=e,r=e.next;if(y(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(p(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&y(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function a(e,t,n,r){var i=e.prev,a=e,o=e.next;if(y(i,a,o)>=0)return!1;for(var u=i.x<a.x?i.x<o.x?i.x:o.x:a.x<o.x?a.x:o.x,s=i.y<a.y?i.y<o.y?i.y:o.y:a.y<o.y?a.y:o.y,c=i.x>a.x?i.x>o.x?i.x:o.x:a.x>o.x?a.x:o.x,l=i.y>a.y?i.y>o.y?i.y:o.y:a.y>o.y?a.y:o.y,f=E(u,s,t,n,r),h=E(c,l,t,n,r),d=e.nextZ;d&&d.z<=h;){if(d!==e.prev&&d!==e.next&&p(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&p(i.x,i.y,a.x,a.y,o.x,o.y,d.x,d.y)&&y(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function o(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;!T(i,a)&&R(i,r,r.next,a)&&A(i,a)&&A(a,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(a.i/n),N(r),N(r.next),r=e=a),r=r.next}while(r!==e);return r}function u(e,t,i,a,o,u){var s=e;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&_(s,c)){var l=O(s,c);return s=n(s,s.next),l=n(l,l.next),r(s,t,i,a,o,u),void r(l,t,i,a,o,u)}c=c.next}s=s.next}while(s!==e)}function s(e,r,i,a){var o,u,s,f,h,d=[];for(o=0,u=r.length;o<u;o++)s=r[o]*a,f=o<u-1?r[o+1]*a:e.length,h=t(e,s,f,a,!1),h===h.next&&(h.steiner=!0),d.push(m(h));for(d.sort(c),o=0;o<d.length;o++)l(d[o],i),i=n(i,i.next);return i}function c(e,t){return e.x-t.x}function l(e,t){if(t=f(e,t)){var r=O(t,e);n(r,r.next)}}function f(e,t){var n,r=t,i=e.x,a=e.y,o=-1/0;do{if(a<=r.y&&a>=r.next.y){var u=r.x+(a-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(u<=i&&u>o){if(o=u,u===i){if(a===r.y)return r;if(a===r.next.y)return r.next}n=r.x<r.next.x?r:r.next}}r=r.next}while(r!==t);if(!n)return null;if(i===o)return n.prev;var s,c=n,l=n.x,f=n.y,h=1/0;for(r=n.next;r!==c;)i>=r.x&&r.x>=l&&p(a<f?i:o,a,l,f,a<f?o:i,a,r.x,r.y)&&((s=Math.abs(a-r.y)/(i-r.x))<h||s===h&&r.x>n.x)&&A(r,e)&&(n=r,h=s),r=r.next;return n}function h(e,t,n,r){var i=e;do{null===i.z&&(i.z=E(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,d(i)}function d(e){var t,n,r,i,a,o,u,s,c=1;do{for(n=e,e=null,a=null,o=0;n;){for(o++,r=n,u=0,t=0;t<c&&(u++,r=r.nextZ);t++);for(s=c;u>0||s>0&&r;)0===u?(i=r,r=r.nextZ,s--):0!==s&&r?n.z<=r.z?(i=n,n=n.nextZ,u--):(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;n=r}a.nextZ=null,c*=2}while(o>1);return e}function E(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do{t.x<n.x&&(n=t),t=t.next}while(t!==e);return n}function p(e,t,n,r,i,a,o,u){return(i-o)*(t-u)-(e-o)*(a-u)>=0&&(e-o)*(r-u)-(n-o)*(t-u)>=0&&(n-o)*(a-u)-(i-o)*(r-u)>=0}function _(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!v(e,t)&&A(e,t)&&A(t,e)&&S(e,t)}function y(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function T(e,t){return e.x===t.x&&e.y===t.y}function R(e,t,n,r){return!!(T(e,t)&&T(n,r)||T(e,r)&&T(n,t))||y(e,t,n)>0!=y(e,t,r)>0&&y(n,r,e)>0!=y(n,r,t)>0}function v(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&R(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function A(e,t){return y(e.prev,e,e.next)<0?y(e,t,e.next)>=0&&y(e,e.prev,t)>=0:y(e,t,e.prev)<0||y(e,e.next,t)<0}function S(e,t){var n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{n.y>a!=n.next.y>a&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next}while(n!==e);return r}function O(e,t){var n=new I(e.i,e.x,e.y),r=new I(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function g(e,t,n,r){var i=new I(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function N(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function I(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function M(e,t,n,r){for(var i=0,a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}return e.deviation=function(e,t,n,r){var i=t&&t.length,a=i?t[0]*n:e.length,o=Math.abs(M(e,0,a,n));if(i)for(var u=0,s=t.length;u<s;u++){var c=t[u]*n,l=u<s-1?t[u+1]*n:e.length;o-=Math.abs(M(e,c,l,n))}var f=0;for(u=0;u<r.length;u+=3){var h=r[u]*n,d=r[u+1]*n,E=r[u+2]*n;f+=Math.abs((e[h]-e[E])*(e[d+1]-e[h+1])-(e[h]-e[d])*(e[E+1]-e[h+1]))}return 0===o&&0===f?0:Math.abs((f-o)/o)},e.flatten=function(e){for(var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0,i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++)for(var o=0;o<t;o++)n.vertices.push(e[i][a][o]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},e}),define("Core/WindingOrder",["./freezeObject","./WebGLConstants"],function(e,t){"use strict";var n={CLOCKWISE:t.CW,COUNTER_CLOCKWISE:t.CCW,validate:function(e){return e===n.CLOCKWISE||e===n.COUNTER_CLOCKWISE}};return e(n)}),define("Core/PolygonPipeline",["../ThirdParty/earcut-2.1.1","./Cartesian2","./Cartesian3","./Check","./ComponentDatatype","./defaultValue","./defined","./Ellipsoid","./Geometry","./GeometryAttribute","./Math","./PrimitiveType","./WindingOrder"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";var d=new n,E=new n,m={};m.computeArea2D=function(e){for(var t=e.length,n=0,r=t-1,i=0;i<t;r=i++){var a=e[r],o=e[i];n+=a.x*o.y-o.x*a.y}return.5*n},m.computeWindingOrder2D=function(e){return m.computeArea2D(e)>0?h.COUNTER_CLOCKWISE:h.CLOCKWISE},m.triangulate=function(n,r){var i=t.packArray(n);return e(i,r,2)};var p=new n,_=new n,y=new n,T=new n,R=new n,v=new n,A=new n;return m.computeSubdivision=function(e,t,r,u){u=a(u,l.RADIANS_PER_DEGREE);var h,d=r.slice(0),E=t.length,m=new Array(3*E),S=0;for(h=0;h<E;h++){var O=t[h];m[S++]=O.x,m[S++]=O.y,m[S++]=O.z}for(var g=[],N={},I=e.maximumRadius,M=l.chordLength(u,I),w=M*M;d.length>0;){var C,x,P=d.pop(),U=d.pop(),D=d.pop(),L=n.fromArray(m,3*D,p),F=n.fromArray(m,3*U,_),b=n.fromArray(m,3*P,y),B=n.multiplyByScalar(n.normalize(L,T),I,T),z=n.multiplyByScalar(n.normalize(F,R),I,R),q=n.multiplyByScalar(n.normalize(b,v),I,v),G=n.magnitudeSquared(n.subtract(B,z,A)),W=n.magnitudeSquared(n.subtract(z,q,A)),X=n.magnitudeSquared(n.subtract(q,B,A)),V=Math.max(G,W,X);V>w?G===V?(C=Math.min(D,U)+" "+Math.max(D,U),h=N[C],o(h)||(x=n.add(L,F,A),n.multiplyByScalar(x,.5,x),m.push(x.x,x.y,x.z),h=m.length/3-1,N[C]=h),d.push(D,h,P),d.push(h,U,P)):W===V?(C=Math.min(U,P)+" "+Math.max(U,P),h=N[C],o(h)||(x=n.add(F,b,A),n.multiplyByScalar(x,.5,x),m.push(x.x,x.y,x.z),h=m.length/3-1,N[C]=h),d.push(U,h,D),d.push(h,P,D)):X===V&&(C=Math.min(P,D)+" "+Math.max(P,D),h=N[C],o(h)||(x=n.add(b,L,A),n.multiplyByScalar(x,.5,x),m.push(x.x,x.y,x.z),h=m.length/3-1,N[C]=h),d.push(P,h,U),d.push(h,D,U)):(g.push(D),g.push(U),g.push(P))}return new s({attributes:{position:new c({componentDatatype:i.DOUBLE,componentsPerAttribute:3,values:m})},indices:g,primitiveType:f.TRIANGLES})},m.scaleToGeodeticHeight=function(e,t,r,i){r=a(r,u.WGS84);var s=d,c=E;if(t=a(t,0),i=a(i,!0),o(e))for(var l=e.length,f=0;f<l;f+=3)n.fromArray(e,f,c),i&&(c=r.scaleToGeodeticSurface(c,c)),0!==t&&(s=r.geodeticSurfaceNormal(c,s),n.multiplyByScalar(s,t,s),n.add(c,s,c)),e[f]=c.x,e[f+1]=c.y,e[f+2]=c.z;return e},m}),define("Core/EllipsoidGeodesic",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){var t=e._uSquared,n=e._ellipsoid.maximumRadius,r=e._ellipsoid.minimumRadius,i=(n-r)/n,a=Math.cos(e._startHeading),o=Math.sin(e._startHeading),u=(1-i)*Math.tan(e._start.latitude),s=1/Math.sqrt(1+u*u),c=s*u,l=Math.atan2(u,a),f=s*o,h=f*f,d=1-h,E=Math.sqrt(d),m=t/4,p=m*m,_=p*m,y=p*p,T=1+m-3*p/4+5*_/4-175*y/64,R=1-m+15*p/8-35*_/8,v=1-3*m+35*p/4,A=1-5*m,S=T*l-R*Math.sin(2*l)*m/2-v*Math.sin(4*l)*p/16-A*Math.sin(6*l)*_/48-5*Math.sin(8*l)*y/512,O=e._constants;O.a=n,O.b=r,O.f=i,O.cosineHeading=a,O.sineHeading=o,O.tanU=u,O.cosineU=s,O.sineU=c,O.sigma=l,O.sineAlpha=f,O.sineSquaredAlpha=h,O.cosineSquaredAlpha=d,O.cosineAlpha=E,O.u2Over4=m,O.u4Over16=p,O.u6Over64=_,O.u8Over256=y,O.a0=T,O.a1=R,O.a2=v,O.a3=A,O.distanceRatio=S}function c(e,t){return e*t*(4+e*(4-3*t))/16}function l(e,t,n,r,i,a,o){var u=c(e,n);return(1-u)*e*t*(r+u*i*(o+u*a*(2*o*o-1)))}function f(e,t,n,r,i,a,o){var s,c,f,h,d,E=(t-n)/t,m=a-r,p=Math.atan((1-E)*Math.tan(i)),_=Math.atan((1-E)*Math.tan(o)),y=Math.cos(p),T=Math.sin(p),R=Math.cos(_),v=Math.sin(_),A=y*R,S=y*v,O=T*v,g=T*R,N=m,I=u.TWO_PI,M=Math.cos(N),w=Math.sin(N);do{M=Math.cos(N),w=Math.sin(N);var C=S-g*M;f=Math.sqrt(R*R*w*w+C*C),c=O+A*M,s=Math.atan2(f,c);var x;0===f?(x=0,h=1):(x=A*w/f,h=1-x*x),I=N,d=c-2*O/h,isNaN(d)&&(d=0),N=m+l(E,x,h,s,f,c,d)}while(Math.abs(N-I)>u.EPSILON12);var P=h*(t*t-n*n)/(n*n),U=1+P*(4096+P*(P*(320-175*P)-768))/16384,D=P*(256+P*(P*(74-47*P)-128))/1024,L=d*d,F=D*f*(d+D*(c*(2*L-1)-D*d*(4*f*f-3)*(4*L-3)/6)/4),b=n*U*(s-F),B=Math.atan2(R*w,S-g*M),z=Math.atan2(y*w,S*M-g);e._distance=b,e._startHeading=B,e._endHeading=z,e._uSquared=P}function h(n,r,i,a){e.normalize(a.cartographicToCartesian(r,m),E),e.normalize(a.cartographicToCartesian(i,m),m);f(n,a.maximumRadius,a.minimumRadius,r.longitude,r.latitude,i.longitude,i.latitude),n._start=t.clone(r,n._start),n._end=t.clone(i,n._end),n._start.height=0,n._end.height=0,s(n)}function d(e,n,a){var u=r(a,o.WGS84);this._ellipsoid=u,this._start=new t,this._end=new t,this._constants={},this._startHeading=void 0,this._endHeading=void 0,this._distance=void 0,this._uSquared=void 0,i(e)&&i(n)&&h(this,e,n,u)}var E=new e,m=new e;return a(d.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},surfaceDistance:{get:function(){return this._distance}},start:{get:function(){return this._start}},end:{get:function(){return this._end}},startHeading:{get:function(){return this._startHeading}},endHeading:{get:function(){return this._endHeading}}}),d.prototype.setEndPoints=function(e,t){h(this,e,t,this._ellipsoid)},d.prototype.interpolateUsingFraction=function(e,t){return this.interpolateUsingSurfaceDistance(this._distance*e,t)},d.prototype.interpolateUsingSurfaceDistance=function(e,n){var r=this._constants,a=r.distanceRatio+e/r.b,o=Math.cos(2*a),u=Math.cos(4*a),s=Math.cos(6*a),c=Math.sin(2*a),f=Math.sin(4*a),h=Math.sin(6*a),d=Math.sin(8*a),E=a*a,m=a*E,p=r.u8Over256,_=r.u2Over4,y=r.u6Over64,T=r.u4Over16,R=2*m*p*o/3+a*(1-_+7*T/4-15*y/4+579*p/64-(T-15*y/4+187*p/16)*o-(5*y/4-115*p/16)*u-29*p*s/16)+(_/2-T+71*y/32-85*p/16)*c+(5*T/16-5*y/4+383*p/96)*f-E*((y-11*p/2)*c+5*p*f/2)+(29*y/96-29*p/16)*h+539*p*d/1536,v=Math.asin(Math.sin(R)*r.cosineAlpha),A=Math.atan(r.a/r.b*Math.tan(v));R-=r.sigma;var S=Math.cos(2*r.sigma+R),O=Math.sin(R),g=Math.cos(R),N=r.cosineU*g,I=r.sineU*O,M=Math.atan2(O*r.sineHeading,N-I*r.cosineHeading),w=M-l(r.f,r.sineAlpha,r.cosineSquaredAlpha,R,O,g,S);return i(n)?(n.longitude=this._start.longitude+w,n.latitude=A,n.height=0,n):new t(this._start.longitude+w,A,0)},d}),define("Core/PolylinePipeline",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidGeodesic","./IntersectionTests","./isArray","./Math","./Matrix4","./Plane"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(e,t,n){var r=O;r.length=e;var i;if(t===n){for(i=0;i<e;i++)r[i]=t;return r}var a=n-t,o=a/e;for(i=0;i<e;i++){var u=t+i*o;r[i]=u}return r}function d(t,n,r,i,a,o,u,s){var c=i.scaleToGeodeticSurface(t,M),l=i.scaleToGeodeticSurface(n,w),f=E.numberOfPoints(t,n,r),d=i.cartesianToCartographic(c,g),m=i.cartesianToCartographic(l,N),p=h(f,a,o);C.setEndPoints(d,m);var _=C.surfaceDistance/f,y=s;d.height=a;var T=i.cartographicToCartesian(d,I);e.pack(T,u,y),y+=3;for(var R=1;R<f;R++){var v=C.interpolateUsingSurfaceDistance(R*_,N);v.height=p[R],T=i.cartographicToCartesian(v,I),e.pack(T,u,y),y+=3}return y}var E={};E.numberOfPoints=function(t,n,r){var i=e.distance(t,n);return Math.ceil(i/r)};var m=new t;E.extractHeights=function(e,t){for(var n=e.length,r=new Array(n),i=0;i<n;i++){var a=e[i];r[i]=t.cartesianToCartographic(a,m).height}return r};var p=new l,_=new e,y=new e,T=new f(e.UNIT_X,0),R=new e,v=new f(e.UNIT_X,0),A=new e,S=new e,O=[],g=new t,N=new t,I=new e,M=new e,w=new e,C=new o;return E.wrapLongitude=function(t,i){var a=[],o=[];if(r(t)&&t.length>0){i=n(i,l.IDENTITY);var s=l.inverseTransformation(i,p),c=l.multiplyByPoint(s,e.ZERO,_),h=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_Y,y),y),d=f.fromPointNormal(c,h,T),E=e.normalize(l.multiplyByPointAsVector(s,e.UNIT_X,R),R),m=f.fromPointNormal(c,E,v),O=1;a.push(e.clone(t[0]));for(var g=a[0],N=t.length,I=1;I<N;++I){var M=t[I];if(f.getPointDistance(m,g)<0||f.getPointDistance(m,M)<0){var w=u.lineSegmentPlane(g,M,d,A);if(r(w)){var C=e.multiplyByScalar(h,5e-9,S);f.getPointDistance(d,g)<0&&e.negate(C,C),a.push(e.add(w,C,new e)),o.push(O+1),e.negate(C,C),a.push(e.add(w,C,new e)),O=1}}a.push(e.clone(t[I])),O++,g=M}o.push(O)}return{positions:a,lengths:o}},E.generateArc=function(t){r(t)||(t={});var i=t.positions,o=i.length,u=n(t.ellipsoid,a.WGS84),l=n(t.height,0),f=s(l);if(o<1)return[];if(1===o){var h=u.scaleToGeodeticSurface(i[0],M);if(0!==(l=f?l[0]:l)){var m=u.geodeticSurfaceNormal(h,I);e.multiplyByScalar(m,l,m),e.add(h,m,h)}return[h.x,h.y,h.z]}var p=t.minDistance;if(!r(p)){var _=n(t.granularity,c.RADIANS_PER_DEGREE);p=c.chordLength(_,u.maximumRadius)}var y,T=0;for(y=0;y<o-1;y++)T+=E.numberOfPoints(i[y],i[y+1],p);var R=3*(T+1),v=new Array(R),A=0;for(y=0;y<o-1;y++){A=d(i[y],i[y+1],p,u,f?l[y]:l,f?l[y+1]:l,v,A)}O.length=0;var S=i[o-1],N=u.cartesianToCartographic(S,g);N.height=f?l[o-1]:l;var w=u.cartographicToCartesian(N,I);return e.pack(w,v,R-3),v},E.generateCartesianArc=function(t){for(var n=E.generateArc(t),r=n.length/3,i=new Array(r),a=0;a<r;a++)i[a]=e.unpack(n,3*a);return i},E}),define("Core/WallGeometryLibrary",["./Cartographic","./defined","./EllipsoidTangentPlane","./Math","./PolygonPipeline","./PolylinePipeline","./WindingOrder"],function(e,t,n,r,i,a,o){"use strict";function u(e,t){return r.equalsEpsilon(e.latitude,t.latitude,r.EPSILON14)&&r.equalsEpsilon(e.longitude,t.longitude,r.EPSILON14)}function s(n,r,i,a){var o=r.length;if(!(o<2)){var s=t(a),c=t(i),h=!0,d=new Array(o),E=new Array(o),m=new Array(o),p=r[0];d[0]=p;var _=n.cartesianToCartographic(p,l);c&&(_.height=i[0]),h=h&&_.height<=0,E[0]=_.height,m[0]=s?a[0]:0;for(var y=1,T=1;T<o;++T){var R=r[T],v=n.cartesianToCartographic(R,f);c&&(v.height=i[T]),h=h&&v.height<=0,u(_,v)?_.height<v.height&&(E[y-1]=v.height):(d[y]=R,E[y]=v.height,m[y]=s?a[T]:0,e.clone(v,_),++y)}if(!(h||y<2))return d.length=y,E.length=y,m.length=y,{positions:d,topHeights:E,bottomHeights:m}}}var c={},l=new e,f=new e,h=new Array(2),d=new Array(2),E={positions:void 0,height:void 0,granularity:void 0,ellipsoid:void 0};return c.computePositions=function(e,u,c,l,f,m){var p=s(e,u,c,l);if(t(p)){if(u=p.positions,c=p.topHeights,l=p.bottomHeights,u.length>=3){var _=n.fromPoints(u,e),y=_.projectPointsOntoPlane(u);i.computeWindingOrder2D(y)===o.CLOCKWISE&&(u.reverse(),c.reverse(),l.reverse())}var T,R,v=u.length,A=v-2,S=r.chordLength(f,e.maximumRadius),O=E;if(O.minDistance=S,O.ellipsoid=e,m){var g,N=0;for(g=0;g<v-1;g++)N+=a.numberOfPoints(u[g],u[g+1],S)+1;T=new Float64Array(3*N),R=new Float64Array(3*N);var I=h,M=d;O.positions=I,O.height=M;var w=0;for(g=0;g<v-1;g++){I[0]=u[g],I[1]=u[g+1],M[0]=c[g],M[1]=c[g+1];var C=a.generateArc(O);T.set(C,w),M[0]=l[g],M[1]=l[g+1],R.set(a.generateArc(O),w),w+=C.length}}else O.positions=u,O.height=c,T=new Float64Array(a.generateArc(O)),O.height=l,R=new Float64Array(a.generateArc(O));return{bottomPositions:R,topPositions:T,numCorners:A}}},c}),define("Core/WallOutlineGeometry",["./BoundingSphere","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./Geometry","./GeometryAttribute","./GeometryAttributes","./IndexDatatype","./Math","./PrimitiveType","./WallGeometryLibrary"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e){e=r(e,r.EMPTY_OBJECT);var n=e.positions,a=e.maximumHeights,u=e.minimumHeights,s=r(e.granularity,f.RADIANS_PER_DEGREE),c=r(e.ellipsoid,o.WGS84);this._positions=n,this._minimumHeights=u,this._maximumHeights=a,this._granularity=s,this._ellipsoid=o.clone(c),this._workerName="createWallOutlineGeometry";var l=1+n.length*t.packedLength+2;i(u)&&(l+=u.length),i(a)&&(l+=a.length),this.packedLength=l+o.packedLength+1}var m=new t,p=new t;E.pack=function(e,n,a){a=r(a,0);var u,s=e._positions,c=s.length;for(n[a++]=c,u=0;u<c;++u,a+=t.packedLength)t.pack(s[u],n,a);var l=e._minimumHeights;if(c=i(l)?l.length:0,n[a++]=c,i(l))for(u=0;u<c;++u)n[a++]=l[u];var f=e._maximumHeights;if(c=i(f)?f.length:0,n[a++]=c,i(f))for(u=0;u<c;++u)n[a++]=f[u];return o.pack(e._ellipsoid,n,a),a+=o.packedLength,n[a]=e._granularity,n};var _=o.clone(o.UNIT_SPHERE),y={positions:void 0,minimumHeights:void 0,maximumHeights:void 0,ellipsoid:_,granularity:void 0};return E.unpack=function(e,n,a){n=r(n,0);var u,s=e[n++],c=new Array(s);for(u=0;u<s;++u,n+=t.packedLength)c[u]=t.unpack(e,n);s=e[n++];var l;if(s>0)for(l=new Array(s),u=0;u<s;++u)l[u]=e[n++];s=e[n++];var f;if(s>0)for(f=new Array(s),u=0;u<s;++u)f[u]=e[n++];var h=o.unpack(e,n,_);n+=o.packedLength;var d=e[n];return i(a)?(a._positions=c,a._minimumHeights=l,a._maximumHeights=f,a._ellipsoid=o.clone(h,a._ellipsoid),a._granularity=d,a):(y.positions=c,y.minimumHeights=l,y.maximumHeights=f,y.granularity=d,new E(y))},E.fromConstantHeights=function(e){e=r(e,r.EMPTY_OBJECT);var t,n,a=e.positions,o=e.minimumHeight,u=e.maximumHeight,s=i(o),c=i(u);if(s||c){var l=a.length;t=s?new Array(l):void 0,n=c?new Array(l):void 0;for(var f=0;f<l;++f)s&&(t[f]=o),c&&(n[f]=u)}return new E({positions:a,maximumHeights:n,minimumHeights:t,ellipsoid:e.ellipsoid})},E.createGeometry=function(r){var a=r._positions,o=r._minimumHeights,E=r._maximumHeights,_=r._granularity,y=r._ellipsoid,T=d.computePositions(y,a,E,o,_,!1);if(i(T)){var R=T.bottomPositions,v=T.topPositions,A=v.length,S=2*A,O=new Float64Array(S),g=0;A/=3;var N;for(N=0;N<A;++N){var I=3*N,M=t.fromArray(v,I,m),w=t.fromArray(R,I,p);O[g++]=w.x,O[g++]=w.y,O[g++]=w.z,O[g++]=M.x,O[g++]=M.y,O[g++]=M.z}var C=new c({position:new s({componentDatatype:n.DOUBLE,componentsPerAttribute:3,values:O})}),x=S/3;S=2*x-4+x;var P=l.createTypedArray(x,S),U=0;for(N=0;N<x-2;N+=2){var D=N,L=N+2,F=t.fromArray(O,3*D,m),b=t.fromArray(O,3*L,p);if(!t.equalsEpsilon(F,b,f.EPSILON10)){var B=N+1,z=N+3;P[U++]=B,P[U++]=D,P[U++]=B,P[U++]=z,P[U++]=D,P[U++]=L}}return P[U++]=x-2,P[U++]=x-1,new u({attributes:C,indices:P,primitiveType:h.LINES,boundingSphere:new e.fromVertices(O)})}},E}),define("Workers/createWallOutlineGeometry",["../Core/defined","../Core/Ellipsoid","../Core/WallOutlineGeometry"],function(e,t,n){"use strict";function r(r,i){return e(i)&&(r=n.unpack(r,i)),r._ellipsoid=t.clone(r._ellipsoid),n.createGeometry(r)}return r})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/upsampleQuantizedTerrainMesh.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/upsampleQuantizedTerrainMesh.js index 1af10b36..cd3fa0b6 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/upsampleQuantizedTerrainMesh.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/Cesium/Workers/upsampleQuantizedTerrainMesh.js @@ -222,9 +222,9 @@ OTHER DEALINGS IN THE SOFTWARE. * */ -!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var a={};return a.typeOf={},a.defined=function(r,a){if(!e(a))throw new t(n(r))},a.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},a.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},a.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},a.typeOf.number.lessThan=function(e,n,r){if(a.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},a.typeOf.number.lessThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},a.typeOf.number.greaterThan=function(e,n,r){if(a.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},a.typeOf.number.greaterThanOrEquals=function(e,n,r){if(a.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},a.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},a.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},a.typeOf.number.equals=function(e,n,r,i){if(a.typeOf.number(e,r),a.typeOf.number(n,i),r!==i)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+i)},a}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var a={};a.EPSILON1=.1,a.EPSILON2=.01,a.EPSILON3=.001,a.EPSILON4=1e-4,a.EPSILON5=1e-5,a.EPSILON6=1e-6,a.EPSILON7=1e-7,a.EPSILON8=1e-8,a.EPSILON9=1e-9,a.EPSILON10=1e-10,a.EPSILON11=1e-11,a.EPSILON12=1e-12,a.EPSILON13=1e-13,a.EPSILON14=1e-14,a.EPSILON15=1e-15,a.EPSILON16=1e-16,a.EPSILON17=1e-17,a.EPSILON18=1e-18,a.EPSILON19=1e-19,a.EPSILON20=1e-20,a.GRAVITATIONALPARAMETER=3986004418e5,a.SOLAR_RADIUS=6955e5,a.LUNAR_RADIUS=1737400,a.SIXTY_FOUR_KILOBYTES=65536,a.sign=function(e){return e>0?1:e<0?-1:0},a.signNotZero=function(e){return e<0?-1:1},a.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*a.clamp(e,-1,1)+.5)*n)},a.fromSNorm=function(e,n){return n=t(n,255),a.clamp(e,0,n)/n*2-1},a.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},a.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},a.lerp=function(e,t,n){return(1-n)*e+n*t},a.PI=Math.PI,a.ONE_OVER_PI=1/Math.PI,a.PI_OVER_TWO=.5*Math.PI,a.PI_OVER_THREE=Math.PI/3,a.PI_OVER_FOUR=Math.PI/4,a.PI_OVER_SIX=Math.PI/6,a.THREE_PI_OVER_TWO=3*Math.PI*.5,a.TWO_PI=2*Math.PI,a.ONE_OVER_TWO_PI=1/(2*Math.PI),a.RADIANS_PER_DEGREE=Math.PI/180,a.DEGREES_PER_RADIAN=180/Math.PI,a.RADIANS_PER_ARCSECOND=a.RADIANS_PER_DEGREE/3600,a.toRadians=function(e){return e*a.RADIANS_PER_DEGREE},a.toDegrees=function(e){return e*a.DEGREES_PER_RADIAN},a.convertLongitudeRange=function(e){var t=a.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},a.clampToLatitudeRange=function(e){return a.clamp(e,-1*a.PI_OVER_TWO,a.PI_OVER_TWO)},a.negativePiToPi=function(e){return a.zeroToTwoPi(e+a.PI)-a.PI},a.zeroToTwoPi=function(e){var t=a.mod(e,a.TWO_PI);return Math.abs(t)<a.EPSILON14&&Math.abs(e)>a.EPSILON14?a.TWO_PI:t},a.mod=function(e,t){return(e%t+t)%t},a.equalsEpsilon=function(e,n,r,a){a=t(a,r);var i=Math.abs(e-n);return i<=a||i<=r*Math.max(Math.abs(e),Math.abs(n))};var i=[1];a.factorial=function(e){var t=i.length;if(e>=t)for(var n=i[t-1],r=t;r<=e;r++)i.push(n*r);return i[e]},a.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},a.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},a.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},a.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return a.setRandomNumberSeed=function(t){o=new e(t)},a.nextRandomNumber=function(){return o.random()},a.randomBetween=function(e,t){return a.nextRandomNumber()*(t-e)+e},a.acosClamped=function(e){return Math.acos(a.clamp(e,-1,1))},a.asinClamped=function(e){return Math.asin(a.clamp(e,-1,1))},a.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},a.logBase=function(e,t){return Math.log(e)/Math.log(t)},a.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},a}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var a=0;a<r;++a)o.pack(e[a],t,2*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var a=0;a<r;a+=2){var i=a/2;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),i.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)},o.ZERO=a(new o(0,0)),o.UNIT_X=a(new o(1,0)),o.UNIT_Y=a(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var a=e.clock,i=e.cone,u=t(e.magnitude,1),s=u*Math.sin(i);return r.x=s*Math.cos(a),r.y=s*Math.sin(a),r.z=u*Math.cos(i),r},o.fromElements=function(e,t,r,a){return n(a)?(a.x=e,a.y=t,a.z=r,a):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var a=0;a<r;++a)o.pack(e[a],t,3*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var a=0;a<r;a+=3){var i=a/3;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)},o.cross=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=t.x,u=t.y,s=t.z,c=a*s-i*u,l=i*o-r*s,f=r*u-a*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,a){return e=i.toRadians(e),t=i.toRadians(t),o.fromRadians(e,t,n,r,a)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,a,i,u){a=t(a,0);var s=n(i)?i.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,a,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var a=e.length;n(r)?r.length=a/2:r=new Array(a/2);for(var i=0;i<a;i+=2){var u=e[i],s=e[i+1],c=i/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var a=e.length;n(r)?r.length=a/3:r=new Array(a/3);for(var i=0;i<a;i+=3){var u=e[i],s=e[i+1],c=e[i+2],l=i/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=a(new o(0,0,0)),o.UNIT_X=a(new o(1,0,0)),o.UNIT_Y=a(new o(0,1,0)),o.UNIT_Z=a(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./DeveloperError","./Math"],function(e,t,n,r,a){"use strict";var i={};i.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},i.octEncode=function(e,t){return i.octEncodeInRange(e,255,t)},i.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},i.octDecode=function(e,t,n){return i.octDecodeInRange(e,t,255,n)},i.octPackFloat=function(e){return 256*e.x+e.y};var o=new e;return i.octEncodeFloat=function(e){return i.octEncode(e,o),i.octPackFloat(o)},i.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),a=256*(n-r);return i.octDecode(r,a,t)},i.octPack=function(e,t,n,r){var a=i.octEncodeFloat(e),u=i.octEncodeFloat(t),s=i.octEncode(n,o);return r.x=65536*s.x+a,r.y=65536*s.y+u,r},i.octUnpack=function(e,t,n,r){var a=e.x/65536,o=Math.floor(a),u=65536*(a-o);a=e.y/65536;var s=Math.floor(a),c=65536*(a-s);i.octDecodeFloat(u,t),i.octDecodeFloat(c,n),i.octDecode(o,s,r)},i.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},i.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},i}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function a(n,a,u,s,c){var l=n.x,f=n.y,h=n.z,d=a.x,E=a.y,m=a.z,p=l*l*d*d,_=f*f*E*E,y=h*h*m*m,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,i);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,N=u.y,O=u.z,M=o;M.x=A.x*S*2,M.y=A.y*N*2,M.z=A.z*O*2;var v,I,g,w,C,x,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(M)),b=0;do{B-=b,g=1/(1+B*S),w=1/(1+B*N),C=1/(1+B*O),x=g*g,P=w*w,U=C*C,D=x*g,L=P*w,F=U*C,v=p*x+_*P+y*U-1,I=p*D*S+_*L*N+y*F*O;b=v/(-2*I)}while(Math.abs(v)>r.EPSILON12);return t(c)?(c.x=l*g,c.y=f*w,c.z=h*C,c):new e(l*g,f*w,h*C)}var i=new e,o=new e;return a}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,a,i){return a=n(a,0),r(i)?(i.longitude=e,i.latitude=t,i.height=a,i):new u(e,t,a)},u.fromDegrees=function(e,t,n,r){return e=i.toRadians(e),t=i.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=i.EPSILON1;return u.fromCartesian=function(t,n,a){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=i.sign(e.dot(T,t))*e.magnitude(T);return r(a)?(a.longitude=R,a.latitude=A,a.height=S,a):new u(R,A,S)}},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=a(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t,n,a,i){n=r(n,0),a=r(a,0),i=r(i,0),t._radii=new e(n,a,i),t._radiiSquared=new e(n*n,a*a,i*i),t._radiiToTheFourth=new e(n*n*n*n,a*a*a*a,i*i*i*i),t._oneOverRadii=new e(0===n?0:1/n,0===a?0:1/a,0===i?0:1/i),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===a?0:1/(a*a),0===i?0:1/(i*i)),t._minimumRadius=Math.min(n,a,i),t._maximumRadius=Math.max(n,a,i),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}i(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(a(t)){var r=t._radii;return a(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return a(t)||(t=new f),a(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,a){return a=r(a,0),e.pack(t._radii,n,a),n},f.unpack=function(t,n,a){n=r(n,0);var i=e.unpack(t,n);return f.fromCartesian3(i,a)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,i=t.latitude,o=Math.cos(i),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(i);return a(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return a(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,i=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,i);var o=Math.sqrt(e.dot(r,i));return e.divideByScalar(i,o,i),e.multiplyByScalar(r,t.height,r),a(n)||(n=new e),e.add(i,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var i=this.scaleToGeodeticSurface(n,m);if(a(i)){var o=this.geodeticSurfaceNormal(i,E),u=e.subtract(n,i,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return a(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;a(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){a(n)||(n=new e);var r=t.x,i=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+i*i*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return a(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||a(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,i){n=r(n,0);var o=this._squaredXOverSquaredZ;if(a(i)||(i=new e),i.x=0,i.y=0,i.z=t.z*(1-o),!(Math.abs(i.z)>=this._radii.z-n))return i},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,a,i,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var a=this._semimajorAxis,i=t.longitude*a,o=t.latitude*a,u=t.height;return r(n)?(n.x=i,n.y=o,n.z=u,n):new e(i,o,u)},u.prototype.unproject=function(e,n){var a=this._oneOverSemimajorAxis,i=e.x*a,o=e.y*a,u=e.z;return r(n)?(n.longitude=i,n.latitude=o,n.height=u,n):new t(i,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a,i,o,u,s,c){this[0]=n(e,0),this[1]=n(a,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(i,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,a=1,i=0;i<3;++i){var o=Math.abs(e[s.getElementIndex(m[i],E[i])]);o>r&&(a=i,r=o)}var c=1,l=0,f=E[a],h=m[a];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t++],a[1]=e[t++],a[2]=e[t++],a[3]=e[t++],a[4]=e[t++],a[5]=e[t++],a[6]=e[t++],a[7]=e[t++],a[8]=e[t++],a},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a[0]=e[t],a[1]=e[t+1],a[2]=e[t+2],a[3]=e[t+3],a[4]=e[t+4],a[5]=e[t+5],a[6]=e[t+6],a[7]=e[t+7],a[8]=e[t+8],a},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,a=e.x*e.y,i=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(a-h),p=2*(i+l),_=2*(a+h),y=-n+u-f+d,T=2*(c-o),R=2*(i-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=S,t):new s(E,m,p,_,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),a=Math.cos(-e.heading),i=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*a,f=-i*u+c*o*a,h=c*u+i*o*a,d=n*u,E=i*a+c*o*u,m=-c*a+i*o*u,p=-o,_=c*n,y=i*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=a,t[6]=0,t[7]=-a,t[8]=n,t):new s(1,0,0,0,n,-a,0,a,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-a,t[3]=0,t[4]=1,t[5]=0,t[6]=a,t[7]=0,t[8]=n,t):new s(n,0,a,0,1,0,-a,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),a=Math.sin(e);return r(t)?(t[0]=n,t[1]=a,t[2]=0,t[3]=-a,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-a,0,a,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,a=e[r],i=e[r+1],o=e[r+2];return n.x=a,n.y=i,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var a=3*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],a=e[t+3],i=e[t+6];return n.x=r,n.y=a,n.z=i,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],a=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],i=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=a,n[2]=i,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[3]*a+e[6]*i,u=e[1]*r+e[4]*a+e[7]*i,s=e[2]*r+e[5]*a+e[8]*i;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],a=e[6],i=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=a,t[3]=i,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,a=0,i=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);i<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++a>2&&(++i,a=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],a=e[1],i=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(i*c-s*o)+a*(s*r-n*c)+u*(n*o-i*r)},s.inverse=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*a-r*f,t[2]=r*u-o*a,t[3]=c*u-i*f,t[4]=n*f-c*a,t[5]=i*a-n*u,t[6]=i*l-c*o,t[7]=c*r-n*l,t[8]=n*o-i*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,a(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){ -return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,a,i){"use strict";function o(e,n,r,a){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(a,0)}o.fromElements=function(e,t,r,a,i){return n(i)?(i.x=e,i.y=t,i.z=r,i.w=a,i):new o(e,t,r,a)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,a){return r=t(r,0),n(a)||(a=new o),a.x=e[r++],a.y=e[r++],a.z=e[r++],a.w=e[r],a},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var a=0;a<r;++a)o.pack(e[a],t,4*a);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var a=0;a<r;a+=4){var i=a/4;t[i]=o.unpack(e,a,t[i])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,a){return e===t||n(e)&&n(t)&&i.equalsEpsilon(e.x,t.x,r,a)&&i.equalsEpsilon(e.y,t.y,r,a)&&i.equalsEpsilon(e.z,t.z,r,a)&&i.equalsEpsilon(e.w,t.w,r,a)},o.ZERO=a(new o(0,0,0,0)),o.UNIT_X=a(new o(1,0,0,0)),o.UNIT_Y=a(new o(0,1,0,0)),o.UNIT_Z=a(new o(0,0,1,0)),o.UNIT_W=a(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t,n,a,i,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(i,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(a,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),a(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(a(e))return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,i){return n=r(n,e.ZERO),a(i)?(i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=0,i[4]=t[3],i[5]=t[4],i[6]=t[5],i[7]=0,i[8]=t[6],i[9]=t[7],i[10]=t[8],i[11]=0,i[12]=n.x,i[13]=n.y,i[14]=n.z,i[15]=1,i):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){a(r)||(r=new l);var i=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),A=2*(f+m),S=2*(c+_),N=-s+d-p+y,O=2*(E-h),M=2*(f-m),v=2*(E+h),I=-s-d+p+y;return r[0]=T*i,r[1]=S*i,r[2]=M*i,r[3]=0,r[4]=R*o,r[5]=N*o,r[6]=v*o,r[7]=0,r[8]=A*u,r[9]=O*u,r[10]=I*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return a(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return a(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,i=t.direction,o=t.up;e.normalize(i,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,N=u*-R+s*-A+c*-S,O=_*-R+y*-A+T*-S,M=E*R+m*A+p*S;return a(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=N,n[13]=O,n[14]=M,n[15]=1,n):new l(u,s,c,N,_,y,T,O,-E,-m,-p,M,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,a){var i=Math.tan(.5*e),o=1/i,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return a[0]=u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=o,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=s,a[11]=-1,a[12]=0,a[13]=0,a[14]=c,a[15]=0,a},l.computeOrthographicOffCenter=function(e,t,n,r,a,i,o){var u=1/(t-e),s=1/(r-n),c=1/(i-a),l=-(t+e)*u,f=-(r+n)*s,h=-(i+a)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,a,i,o){var u=2*a/(t-e),s=2*a/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(i+a)/(i-a),h=-2*i*a/(i-a);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,a,i){var o=2*a/(t-e),u=2*a/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*a;return i[0]=o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=u,i[6]=0,i[7]=0,i[8]=s,i[9]=c,i[10]=-1,i[11]=-1,i[12]=0,i[13]=0,i[14]=l,i[15]=0,i},l.computeViewportTransformation=function(e,t,n,a){e=r(e,r.EMPTY_OBJECT);var i=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=i+c,p=o+l,_=t+f;return a[0]=h,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=d,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=E,a[11]=0,a[12]=m,a[13]=p,a[14]=_,a[15]=1,a},l.computeView=function(t,n,r,a,i){return i[0]=a.x,i[1]=r.x,i[2]=-n.x,i[3]=0,i[4]=a.y,i[5]=r.y,i[6]=-n.y,i[7]=0,i[8]=a.z,i[9]=r.z,i[10]=-n.z,i[11]=0,i[12]=-e.dot(a,t),i[13]=-e.dot(r,t),i[14]=e.dot(n,t),i[15]=1,i},l.toArray=function(e,t){return a(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,a=e[r],i=e[r+1],o=e[r+2],u=e[r+3];return n.x=a,n.y=i,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var a=4*t;return r[a]=n.x,r[a+1]=n.y,r[a+2]=n.z,r[a+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],a=e[t+4],i=e[t+8],o=e[t+12];return n.x=r,n.y=a,n.z=i,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],N=t[4],O=t[5],M=t[6],v=t[7],I=t[8],g=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=a*T+s*R+h*A+p*S,B=i*T+c*R+d*A+_*S,b=o*T+l*R+E*A+y*S,z=r*N+u*O+f*M+m*v,q=a*N+s*O+h*M+p*v,G=i*N+c*O+d*M+_*v,X=o*N+l*O+E*M+y*v,W=r*I+u*g+f*w+m*C,V=a*I+s*g+h*w+p*C,H=i*I+c*g+d*w+_*C,Y=o*I+l*g+E*w+y*C,k=r*x+u*P+f*U+m*D,Z=a*x+s*P+h*U+p*D,j=i*x+c*P+d*U+_*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=X,n[8]=W,n[9]=V,n[10]=H,n[11]=Y,n[12]=k,n[13]=Z,n[14]=j,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],N=t[10],O=t[12],M=t[13],v=t[14],I=r*m+o*p+c*_,g=a*m+u*p+l*_,w=i*m+s*p+f*_,C=r*y+o*T+c*R,x=a*y+u*T+l*R,P=i*y+s*T+f*R,U=r*A+o*S+c*N,D=a*A+u*S+l*N,L=i*A+s*S+f*N,F=r*O+o*M+c*v+h,B=a*O+u*M+l*v+d,b=i*O+s*M+f*v+E;return n[0]=I,n[1]=g,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],a=e[1],i=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=a*h+u*d+l*E,N=i*h+s*d+f*E,O=r*m+o*p+c*_,M=a*m+u*p+l*_,v=i*m+s*p+f*_,I=r*y+o*T+c*R,g=a*y+u*T+l*R,w=i*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=N,n[3]=0,n[4]=O,n[5]=M,n[6]=v,n[7]=0,n[8]=I,n[9]=g,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=r*e[0]+a*e[4]+i*e[8]+e[12],u=r*e[1]+a*e[5]+i*e[9]+e[13],s=r*e[2]+a*e[6]+i*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,a=t.y,i=t.z;return 1===r&&1===a&&1===i?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=a*e[4],n[5]=a*e[5],n[6]=a*e[6],n[7]=0,n[8]=i*e[8],n[9]=i*e[9],n[10]=i*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=t.w,u=e[0]*r+e[4]*a+e[8]*i+e[12]*o,s=e[1]*r+e[5]*a+e[9]*i+e[13]*o,c=e[2]*r+e[6]*a+e[10]*i+e[14]*o,l=e[3]*r+e[7]*a+e[11]*i+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i,u=e[1]*r+e[5]*a+e[9]*i,s=e[2]*r+e[6]*a+e[10]*i;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,a=t.y,i=t.z,o=e[0]*r+e[4]*a+e[8]*i+e[12],u=e[1]*r+e[5]*a+e[9]*i+e[13],s=e[2]*r+e[6]*a+e[10]*i+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],a=e[3],i=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=i,t[10]=e[10],t[11]=e[14],t[12]=a,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||a(e)&&a(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||a(e)&&a(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],a=e[4],i=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],A=e[10],S=e[14],N=e[3],O=e[7],M=e[11],v=e[15],I=A*v,g=S*M,w=p*v,C=S*O,x=p*M,P=A*O,U=m*v,D=S*N,L=m*M,F=A*N,B=m*O,b=p*N,z=I*h+C*d+x*E-(g*h+w*d+P*E),q=g*f+U*d+F*E-(I*f+D*d+L*E),G=w*f+D*h+B*E-(C*f+U*h+b*E),X=P*f+L*h+b*d-(x*f+F*h+B*d),W=g*a+w*i+P*o-(I*a+C*i+x*o),V=I*r+D*i+L*o-(g*r+U*i+F*o),H=C*r+U*a+b*o-(w*r+D*a+B*o),Y=x*r+F*a+B*i-(P*r+L*a+b*i);I=i*E,g=o*d,w=a*E,C=o*h,x=a*d,P=i*h,U=r*E,D=o*f,L=r*d,F=i*f,B=r*h,b=a*f;var k=I*O+C*M+x*v-(g*O+w*M+P*v),Z=g*N+U*M+F*v-(I*N+D*M+L*v),j=w*N+D*O+B*v-(C*N+U*O+b*v),K=P*N+L*O+b*M-(x*N+F*O+B*M),J=w*A+P*S+g*p-(x*S+I*p+C*A),Q=L*S+I*m+D*A-(U*A+F*S+g*m),$=U*p+b*S+C*m-(B*S+w*m+D*p),ee=B*A+x*m+F*p-(L*p+b*A+P*m),te=r*z+a*q+i*G+o*X;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=X*te,n[4]=W*te,n[5]=V*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=Z*te,n[10]=j*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],a=e[2],i=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-a*d,m=-i*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=i,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=a,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,i(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(a,0)}a(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.west=e[t++],a.south=e[t++],a.east=e[t++],a.north=e[t],a},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,a,i,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),a=u.toRadians(n(a,0)),i=u.toRadians(n(i,0)),r(o)?(o.west=e,o.south=t,o.east=a,o.north=i,o):new s(e,t,a,i)},s.fromRadians=function(e,t,a,i,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(a,0),o.north=n(i,0),o):new s(e,t,a,i)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,a=-Number.MAX_VALUE,i=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),a=Math.max(a,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;i=Math.min(i,E),o=Math.max(o,E)}return a-n>o-i&&(n=i,a=o,a>u.PI&&(a-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=a,t.north=l,t):new s(n,c,a,l)},s.fromCartesianArray=function(e,t,a){t=n(t,i.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(a)?(a.west=o,a.south=h,a.east=c,a.north=d,a):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var a=t.east,i=t.west;a<i&&(a+=u.TWO_PI);var o=u.negativePiToPi(.5*(i+a)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.negativePiToPi(Math.max(i,c)),f=u.negativePiToPi(Math.min(a,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var a=Math.max(e.west,t.west),i=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(i>=u||a>=o))return r(n)?(n.west=a,n.south=i,n.east=o,n.north=u,n):new s(a,i,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var a=e.east,i=e.west,o=t.east,c=t.west;a<i&&o>0?a+=u.TWO_PI:o<c&&a>0&&(o+=u.TWO_PI),a<i&&c<0?c+=u.TWO_PI:o<c&&i<0&&(i+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(i,c)),f=u.convertLongitudeRange(Math.max(a,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,a=e.west,i=e.east;return i<a&&(i+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>a||u.equalsEpsilon(n,a,u.EPSILON14))&&(n<i||u.equalsEpsilon(n,i,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,a,o){t=n(t,i.WGS84),a=n(a,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=a,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t,n){this.center=e.clone(r(t,e.ZERO)),this.radius=r(n,0)}var d=new e,E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,S=new e,N=new e,O=new e;h.fromPoints=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],T),o=e.clone(i,d),u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),M=t.length;for(r=1;r<M;r++){e.clone(t[r],i);var v=i.x,I=i.y,g=i.z;v<o.x&&e.clone(i,o),v>c.x&&e.clone(i,c),I<u.y&&e.clone(i,u),I>l.y&&e.clone(i,l),g<s.z&&e.clone(i,s),g>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,R)),C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=A;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,R)),B=Math.sqrt(F),b=S;b.x=o.x,b.y=u.y,b.z=s.z;var z=N;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,R),.5,O),G=0;for(r=0;r<M;r++){e.clone(t[r],i);var X=e.magnitude(e.subtract(i,q,R));X>G&&(G=X);var W=e.magnitudeSquared(e.subtract(i,L,R));if(W>F){var V=Math.sqrt(W);B=.5*(B+V),F=B*B;var H=V-B;L.x=(B*L.x+H*i.x)/V,L.y=(B*L.y+H*i.y)/V,L.z=(B*L.z+H*i.z)/V}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var M=new o,v=new e,I=new e,g=new t,w=new t;h.fromRectangle2D=function(e,t,n){return h.fromRectangleWithHeights2D(e,t,0,0,n)},h.fromRectangleWithHeights2D=function(t,n,i,o,u){if(a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=r(n,M),f.southwest(t,g),g.height=i,f.northeast(t,w),w.height=o;var s=n.project(g,v),c=n.project(w,I),l=c.x-s.x,d=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+d*d+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*d,m.z=s.z+.5*E,u};var C=[];h.fromRectangle3D=function(t,n,o,u){if(n=r(n,i.WGS84),o=r(o,0),a(u)||(u=new h),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=f.subsample(t,n,o,C);return h.fromPoints(s,u)},h.fromVertices=function(t,n,i,o){if(a(o)||(o=new h),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=r(n,e.ZERO),i=r(i,3);var u=T;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,d),l=e.clone(u,E),f=e.clone(u,m),M=e.clone(u,p),v=e.clone(u,_),I=e.clone(u,y),g=t.length;for(s=0;s<g;s+=i){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>M.x&&e.clone(u,M),C<l.y&&e.clone(u,l),C>v.y&&e.clone(u,v),x<f.z&&e.clone(u,f),x>I.z&&e.clone(u,I)}var P=e.magnitudeSquared(e.subtract(M,c,R)),U=e.magnitudeSquared(e.subtract(v,l,R)),D=e.magnitudeSquared(e.subtract(I,f,R)),L=c,F=M,B=P;U>B&&(B=U,L=l,F=v),D>B&&(B=D,L=f,F=I);var b=A;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,R)),q=Math.sqrt(z),G=S;G.x=c.x,G.y=l.y,G.z=f.z;var X=N;X.x=M.x,X.y=v.y,X.z=I.z;var W=e.multiplyByScalar(e.add(G,X,R),.5,O),V=0;for(s=0;s<g;s+=i){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,W,R));H>V&&(V=H);var Y=e.magnitudeSquared(e.subtract(u,b,R));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var Z=k-q;b.x=(q*b.x+Z*u.x)/k,b.y=(q*b.y+Z*u.y)/k,b.z=(q*b.z+Z*u.z)/k}}return q<V?(e.clone(b,o.center),o.radius=q):(e.clone(W,o.center),o.radius=V),o},h.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new h),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=T;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,d),s=e.clone(i,E),c=e.clone(i,m),l=e.clone(i,p),f=e.clone(i,_),M=e.clone(i,y),v=t.length;for(o=0;o<v;o+=3){var I=t[o]+n[o],g=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=I,i.y=g,i.z=w,I<u.x&&e.clone(i,u),I>l.x&&e.clone(i,l),g<s.y&&e.clone(i,s),g>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>M.z&&e.clone(i,M)}var C=e.magnitudeSquared(e.subtract(l,u,R)),x=e.magnitudeSquared(e.subtract(f,s,R)),P=e.magnitudeSquared(e.subtract(M,c,R)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=M);var F=A;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,R)),b=Math.sqrt(B),z=S;z.x=u.x,z.y=s.y,z.z=c.z;var q=N;q.x=l.x,q.y=f.y,q.z=M.z;var G=e.multiplyByScalar(e.add(z,q,R),.5,O),X=0;for(o=0;o<v;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var W=e.magnitude(e.subtract(i,G,R));W>X&&(X=W);var V=e.magnitudeSquared(e.subtract(i,F,R));if(V>B){var H=Math.sqrt(V);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<X?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=X),r},h.fromCornerPoints=function(t,n,r){a(r)||(r=new h);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},h.fromEllipsoid=function(t,n){return a(n)||(n=new h),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var x=new e;h.fromBoundingSpheres=function(t,n){if(a(n)||(n=new h),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return h.clone(t[0],n);if(2===r)return h.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=h.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,x)+c.radius)}return n.radius=s,n};var P=new e,U=new e,D=new e;h.fromOrientedBoundingBox=function(t,n){a(n)||(n=new h);var r=t.halfAxes,i=c.getColumn(r,0,P),o=c.getColumn(r,1,U),u=c.getColumn(r,2,D);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},h.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new h(t.center,t.radius)},h.packedLength=4,h.pack=function(e,t,n){n=r(n,0);var a=e.center;return t[n++]=a.x,t[n++]=a.y,t[n++]=a.z,t[n]=e.radius,t},h.unpack=function(e,t,n){t=r(t,0),a(n)||(n=new h);var i=n.center;return i.x=e[t++],i.y=e[t++],i.z=e[t++],n.radius=e[t],n};var L=new e,F=new e;h.union=function(t,n,r){a(r)||(r=new h);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,L),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),d=e.multiplyByScalar(c,(-o+f)/l,F);return e.add(d,i,d),e.clone(d,r.center),r.radius=f,r};var B=new e;h.expand=function(t,n,r){r=h.clone(t,r);var a=e.magnitude(e.subtract(n,r.center,B));return a>r.radius&&(r.radius=a),r},h.intersectPlane=function(t,n){var r=t.center,a=t.radius,i=n.normal,o=e.dot(i,r)+n.distance;return o<-a?u.OUTSIDE:o<a?u.INTERSECTING:u.INSIDE},h.transform=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=l.getMaximumScale(t)*e.radius,n};var b=new e;h.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,b);return e.magnitudeSquared(r)-t.radius*t.radius},h.transformWithoutScale=function(e,t,n){return a(n)||(n=new h),n.center=l.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var z=new e;h.computePlaneDistances=function(t,n,r,i){a(i)||(i=new s) -;var o=e.subtract(t.center,n,z),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var q=new e,G=new e,X=new e,W=new e,V=new e,H=new t,Y=new Array(8),k=0;k<8;++k)Y[k]=new e;var Z=new o;return h.projectTo2D=function(t,n,a){n=r(n,Z);var i=n.ellipsoid,o=t.center,u=t.radius,s=i.geodeticSurfaceNormal(o,q),c=e.cross(e.UNIT_Z,s,G);e.normalize(c,c);var l=e.cross(s,c,X);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,V),d=e.negate(c,W),E=Y,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,d,m),m=E[2],e.add(s,f,m),e.add(m,d,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,d,m),m=E[6],e.add(s,f,m),e.add(m,d,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=i.cartesianToCartographic(y,H);n.project(T,y)}a=h.fromPoints(E,a),o=a.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,a},h.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},h.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},h.prototype.intersectPlane=function(e){return h.intersectPlane(this,e)},h.prototype.distanceSquaredTo=function(e){return h.distanceSquaredTo(this,e)},h.prototype.computePlaneDistances=function(e,t,n){return h.computePlaneDistances(this,e,t,n)},h.prototype.isOccluded=function(e){return h.isOccluded(this,e)},h.prototype.equals=function(e){return h.equals(this,e)},h.prototype.clone=function(e){return h.clone(this,e)},h}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,n,r,a,i,o){"use strict";function u(e,n){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,a(n)&&(this.cameraPosition=n)}function s(e,n,r){var a=e.transformPositionToScaledSpace(n,E),i=t.magnitudeSquared(a),o=Math.sqrt(i),u=t.divideByScalar(a,o,m);i=Math.max(1,i),o=Math.max(1,o);var s=t.dot(u,r),c=t.magnitude(t.cross(u,r,u)),l=1/o;return 1/(s*l-c*(Math.sqrt(i-1)*l))}function c(e,n,r){if(!(n<=0||n===1/0||n!==n))return t.multiplyByScalar(e,n,r)}function l(e,n){return t.equals(n,t.ZERO)?n:(e.transformPositionToScaledSpace(n,p),t.normalize(p,p))}i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var n=this._ellipsoid,r=n.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),a=t.magnitudeSquared(r)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=r,this._distanceToLimbInScaledSpaceSquared=a}}});var f=new t;u.prototype.isPointVisible=function(e){var t=this._ellipsoid,n=t.transformPositionToScaledSpace(e,f);return this.isScaledSpacePointVisible(n)},u.prototype.isScaledSpacePointVisible=function(e){var n=this._cameraPositionInScaledSpace,r=this._distanceToLimbInScaledSpaceSquared,a=t.subtract(e,n,f),i=-t.dot(a,n);return!(r<0?i>0:i>r&&i*i/t.magnitudeSquared(a)>r)},u.prototype.computeHorizonCullingPoint=function(e,n,r){a(r)||(r=new t);for(var i=this._ellipsoid,o=l(i,e),u=0,f=0,h=n.length;f<h;++f){var d=n[f],E=s(i,d,o);u=Math.max(u,E)}return c(o,u,r)};var h=new t;u.prototype.computeHorizonCullingPointFromVertices=function(e,n,i,o,u){a(u)||(u=new t),o=r(o,t.ZERO);for(var f=this._ellipsoid,d=l(f,e),E=0,m=0,p=n.length;m<p;m+=i){h.x=n[m]+o.x,h.y=n[m+1]+o.y,h.z=n[m+2]+o.z;var _=s(f,h,d);E=Math.max(E,_)}return c(d,E,u)};var d=[];u.prototype.computeHorizonCullingPointFromRectangle=function(n,r,a){var i=o.subsample(n,r,0,d),u=e.fromPoints(i);if(!(t.magnitude(u.center)<.1*r.minimumRadius))return this.computeHorizonCullingPoint(u.center,i,a)};var E=new t,m=new t,p=new t;return u}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,a){"use strict";var i={UNSIGNED_BYTE:a.UNSIGNED_BYTE,UNSIGNED_SHORT:a.UNSIGNED_SHORT,UNSIGNED_INT:a.UNSIGNED_INT};return i.getSizeInBytes=function(e){switch(e){case i.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case i.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case i.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},i.validate=function(t){return e(t)&&(t===i.UNSIGNED_BYTE||t===i.UNSIGNED_SHORT||t===i.UNSIGNED_INT)},i.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},i.createTypedArrayFromArrayBuffer=function(e,t,n,a){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,a):new Uint16Array(t,n,a)},n(i)}),define("Core/Intersections2D",["./Cartesian3","./defined","./DeveloperError"],function(e,t,n){"use strict";var r={};return r.clipTriangleAtAxisAlignedThreshold=function(e,n,r,a,i,o){t(o)?o.length=0:o=[];var u,s,c;n?(u=r<e,s=a<e,c=i<e):(u=r>e,s=a>e,c=i>e);var l,f,h,d,E,m,p=u+s+c;return 1===p?u?(l=(e-r)/(a-r),f=(e-r)/(i-r),o.push(1),o.push(2),1!==f&&(o.push(-1),o.push(0),o.push(2),o.push(f)),1!==l&&(o.push(-1),o.push(0),o.push(1),o.push(l))):s?(h=(e-a)/(i-a),d=(e-a)/(r-a),o.push(2),o.push(0),1!==d&&(o.push(-1),o.push(1),o.push(0),o.push(d)),1!==h&&(o.push(-1),o.push(1),o.push(2),o.push(h))):c&&(E=(e-i)/(r-i),m=(e-i)/(a-i),o.push(0),o.push(1),1!==m&&(o.push(-1),o.push(2),o.push(1),o.push(m)),1!==E&&(o.push(-1),o.push(2),o.push(0),o.push(E))):2===p?u||r===e?s||a===e?c||i===e||(f=(e-r)/(i-r),h=(e-a)/(i-a),o.push(2),o.push(-1),o.push(0),o.push(2),o.push(f),o.push(-1),o.push(1),o.push(2),o.push(h)):(m=(e-i)/(a-i),l=(e-r)/(a-r),o.push(1),o.push(-1),o.push(2),o.push(1),o.push(m),o.push(-1),o.push(0),o.push(1),o.push(l)):(d=(e-a)/(r-a),E=(e-i)/(r-i),o.push(0),o.push(-1),o.push(1),o.push(0),o.push(d),o.push(-1),o.push(2),o.push(0),o.push(E)):3!==p&&(o.push(0),o.push(1),o.push(2)),o},r.computeBarycentricCoordinates=function(n,r,a,i,o,u,s,c,l){var f=a-s,h=s-o,d=u-c,E=i-c,m=1/(d*f+h*E),p=r-c,_=n-s,y=(d*_+h*p)*m,T=(-E*_+f*p)*m,R=1-y-T;return t(l)?(l.x=y,l.y=T,l.z=R,l):new e(y,T,R)},r}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,a){"use strict";function i(t,a,i){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(a,e.ZERO)),r(i)?i=e.clone(i):(i=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(i,.5,i)),this.center=i}i.fromPoints=function(t,n){if(r(n)||(n=new i),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var a=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;a=Math.min(E,a),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=a,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},i.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new i(t.minimum,t.maximum)},i.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return i.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),i=n.normal,u=r.x*Math.abs(i.x)+r.y*Math.abs(i.y)+r.z*Math.abs(i.z),s=e.dot(t.center,i)+n.distance;return s-u>0?a.INSIDE:s+u<0?a.OUTSIDE:a.INTERSECTING},i.prototype.clone=function(e){return i.clone(this,e)},i.prototype.intersectPlane=function(e){return i.intersectPlane(this,e)},i.prototype.equals=function(e){return i.equals(this,e)},i}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var a=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(a/Math.max(Math.abs(e),Math.abs(n)))<r?0:a}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,a){var i;if(0===e)return 0===r?[]:[-a/r];if(0===r){if(0===a)return[0,0];var o=Math.abs(a),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((i=-a/e)<0)return[];var s=Math.sqrt(i);return[-s,s]}if(0===a)return i=-r/e,i<0?[i,0]:[0,i];var c=r*r,l=4*e*a,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,a/h]:[a/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var a,i,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,_=4*E*p-m*m;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-_);i=-R+S;var N=i/2,O=N<0?-Math.pow(-N,1/3):Math.pow(N,1/3),M=i===S?-O:-T/O;return a=T<=0?O+M:-R/(O*O+M*M+T),h*f>=l*d?[(a-u)/o]:[-c/(a+s)]}var v=E,I=-2*u*E+o*m,g=p,w=-c*m+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-I)/3);a=2*Math.sqrt(-v);var U=Math.cos(P);i=a*U;var D=a*(-U/2-x*Math.sin(P)),L=i+D>2*u?i-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),a=2*Math.sqrt(-g),U=Math.cos(P),i=a*U,D=a*(-U/2-x*Math.sin(P));var b=-c,z=i+D<2*s?i+s:D+s,q=b/z,G=F*z,X=-L*z-F*b,W=L*b,V=(s*X-u*W)/(-u*X+s*G);return B<=V?B<=q?V<=q?[B,V,q]:[B,q,V]:[q,B,V]:B<=q?[V,B,q]:V<=q?[V,q,B]:[q,V,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var a=e*e,i=t*t,o=n*n;return 18*e*t*n*r+i*o-27*a*(r*r)-4*(e*o*n+i*t*r)},r.computeRealRoots=function(e,r,a,i){var o,u;if(0===e)return t.computeRealRoots(r,a,i);if(0===r){if(0===a){if(0===i)return[0,0,0];u=-i/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===i?(o=t.computeRealRoots(e,0,a),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,a,i)}return 0===a?0===i?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,i):0===i?(o=t.computeRealRoots(e,r,a),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,a,i)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function a(t,a,i,o){var u=t*t,s=a-3*u/8,c=i-a*t/2+u*t/8,l=o-i*t/4+a*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,N=r.computeRealRoots(1,R,A),O=r.computeRealRoots(1,-R,S);return 0!==N.length?(N[0]+=h,N[1]+=h,0!==O.length?(O[0]+=h,O[1]+=h,N[1]<=O[0]?[N[0],N[1],O[0],O[1]]:O[1]<=N[0]?[O[0],O[1],N[0],N[1]]:N[0]>=O[0]&&N[1]<=O[1]?[O[0],N[0],N[1],O[1]]:O[0]>=N[0]&&O[1]<=N[1]?[N[0],O[0],O[1],N[1]]:N[0]>O[0]&&N[0]<O[1]?[O[0],N[0],O[1],N[1]]:[N[0],O[0],N[1],O[1]]):N):0!==O.length?(O[0]+=h,O[1]+=h,O):[]}}return[]}function i(t,a,i,o){var u=i*i,s=a*a,c=t*t,l=-2*a,f=i*t+s-4*o,h=c*o-i*a*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],_=a-p,y=_*_,T=t/2,R=_/2,A=y-4*o,S=y+4*Math.abs(o),N=c-4*p,O=c+4*Math.abs(p);if(p<0||A*O<N*S){var M=Math.sqrt(N);E=M/2,m=0===M?0:(t*R-i)/M}else{var v=Math.sqrt(A);E=0===v?0:(t*R-i)/v,m=v/2}var I,g;0===T&&0===E?(I=0,g=0):n.sign(T)===n.sign(E)?(I=T+E,g=p/I):(g=T-E,I=p/g);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,I,w),P=r.computeRealRoots(1,g,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,a){var i=e*e,o=i*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=a*a;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*i*f*f+256*o*(d*a)+a*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*i*n*f)+d*(144*e*u*n-27*u*u-128*i*c-192*i*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return a(c,l,f,h);case 1:case 2:return i(c,l,f,h);case 3:case 4:return a(c,l,f,h);case 5:return i(c,l,f,h);case 6:case 7:return a(c,l,f,h);case 8:return i(c,l,f,h);case 9:case 10:return a(c,l,f,h);case 11:return i(c,l,f,h);case 12:case 13:case 14:case 15:return a(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return a.getPoint=function(t,r,a){return n(a)||(a=new e),a=e.multiplyByScalar(t.direction,r,a),e.add(t.origin,a,a)},a}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,a,i,o,u,s,c,l){"use strict";function f(e,t,n,r){var a=t*t-4*e*n;if(!(a<0)){if(a>0){var i=1/(2*e),o=Math.sqrt(a),u=(-t+o)*i,s=(-t-o)*i;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,a){r(a)||(a=new i);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return a.start=m.root0,a.stop=m.root1,a}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,a,i){var l,f=a*a,h=i*i,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=i*(a*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+a*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=i*(a*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(a,i*R,i*-A)),T.push(new e(a,i*R,i*A)),2===l.length){var S=l[1],N=Math.sqrt(Math.max(1-S*S,0));T.push(new e(a,i*S,i*-N)),T.push(new e(a,i*S,i*N))}return T}var O=y*y,M=_*_,v=E*E,I=y*_,g=v+M,w=2*(m*E+I),C=2*p*E+m*m-M+O,x=2*(p*m-I),P=p*p-O;if(0===g&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(g,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(p)?d(E*B+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?d(E*B,m*F+p,o.EPSILON12):d(E*B+m*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(a,i*F,i*z)):G>0?T.push(new e(a,i*F,i*-z)):0!==z?(T.push(new e(a,i*F,i*-z)),T.push(new e(a,i*F,i*z)),++D):T.push(new e(a,i*F,i*z))}return T}var m={};m.rayPlane=function(t,n,a){r(a)||(a=new e);var i=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,i))/c;if(!(l<0))return a=e.multiplyByScalar(u,l,a),e.add(i,a,a)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,a,i,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(a,r,p),A=e.subtract(i,r,_),S=e.cross(E,A,y),N=e.dot(m,S);if(u){if(N<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>N)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>N)return;h=e.dot(A,c)/N}else{if(Math.abs(N)<o.EPSILON6)return;var O=1/N;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*O)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*O)<0||l+f>1)return;h=e.dot(A,c)*O}return h},m.rayTriangle=function(t,n,a,i,o,u){var s=m.rayTriangleParametric(t,n,a,i,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,a,i,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,a,i,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var N=new l;m.lineSegmentSphere=function(t,n,a,i){var o=N;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),i=h(o,a,i),!(!r(i)||i.stop<0||i.start>s))return i.start=Math.max(i.start,0),i.stop=Math.min(i.stop,s),i};var O=new e,M=new e;m.rayEllipsoid=function(t,n){var r,a,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,O),f=e.multiplyComponents(c,t.direction,M),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,a=e.magnitudeSquared(f),o=a*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/a,p=r/s;return m<p?new i(m,p):{start:p,stop:m}}var _=Math.sqrt(r/a);return new i(_,_)}return h<1?(r=h-1,a=e.magnitudeSquared(f),o=a*r,u=d*d-o,s=-d+Math.sqrt(u),new i(0,s/a)):d<0?(a=e.magnitudeSquared(f),new i(0,-d/a)):void 0};var v=new e,I=new e,g=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var a=t.origin,i=t.direction;if(!e.equals(a,e.ZERO)){var s=n.geodeticSurfaceNormal(a,v);if(e.dot(i,s)>=0)return a}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(i,v),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,I),I),m=e.normalize(e.cross(f,d,g),g),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-i.z,R[2]=i.y,R[3]=i.z,R[4]=0,R[5]=-i.x,R[6]=-i.y,R[7]=i.x,R[8]=0;var A,S,N=u.multiply(u.multiply(_,T,F),R,F),O=u.multiply(u.multiply(N,y,B),p,B),M=u.multiplyByVector(N,a,C),G=E(O,e.negate(M,v),0,0,1),X=G.length;if(X>0){for(var W=e.clone(e.ZERO,z),V=Number.NEGATIVE_INFINITY,H=0;H<X;++H){A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],b),b);var Y=e.normalize(e.subtract(A,a,w),w),k=e.dot(Y,i);k>V&&(V=k,W=e.clone(A,W))}var Z=n.cartesianToCartographic(W,q);return V=o.clamp(V,0,1),S=e.magnitude(e.subtract(W,a,w))*Math.sqrt(1-V*V),S=c?-S:S,Z.height=S,n.cartographicToCartesian(Z,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,a,i){r(i)||(i=new e);var u=e.subtract(n,t,G),s=a.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(a.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,i),e.add(t,i,i),i}},m.trianglePlaneIntersection=function(t,n,r,a){var i=a.normal,o=a.distance,u=e.dot(i,t)+o<0,s=e.dot(i,n)+o<0,c=e.dot(i,r)+o<0,l=0;l+=u?1:0,l+=s?1:0, -l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,a,f),m.lineSegmentPlane(t,r,a,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,a,f),m.lineSegmentPlane(n,t,a,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,a,f),m.lineSegmentPlane(r,n,a,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,a,f),m.lineSegmentPlane(r,t,a,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,a,f),m.lineSegmentPlane(t,n,a,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,a,f),m.lineSegmentPlane(n,r,a,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,a,i,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,a){var i=-e.dot(r,t);return n(a)?(e.clone(r,a.normal),a.distance=i,a):new u(r,i)};var s=new e;u.fromCartesian4=function(t,r){var a=e.fromCartesian4(t,s),i=t.w;return n(r)?(e.clone(a,r.normal),r.distance=i,r):new u(a,i)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,c),o.multiplyByPoint(n,c,c),u.fromPointNormal(c,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=a(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=a(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=a(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,a){return t(e).then(n,r,a)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=a(e),t}function n(t){return e(t,i)}function r(e){this.then=e}function a(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return i(e)}})}function i(e){return new r(function(n,r){try{return r?t(r(e)):i(e)}catch(e){return i(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function a(e){return E(i(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:a,progress:u,promise:c,resolver:{resolve:n,reject:a,progress:u}},l=[],f=[],h=function(e,t,n){var r,a;return r=o(),a="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,a)}),f.push(a),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=_,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,a,i){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=_,d.reject(h))},E=function(e){f.push(e),--c||(E=m=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,a,i)})}function c(e,t,n,r){function a(e){return t?t(e[0]):e[0]}return s(e,1,a,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,a,i,u,s,c;if(i=a=t.length>>>0,r=[],c=o(),i)for(u=function(t,a){e(t,n).then(function(e){r[a]=e,--i||c.resolve(r)},c.reject)},s=0;s<a;s++)s in t?u(t[s],s):--i;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var a;return a=t.length,r[0]=function(t,r,i){return e(t,function(t){return e(r,function(e){return n(t,e,i,a)})})},T.apply(t,r)})}function E(t,n,r){var a=arguments.length>2;return e(t,function(e){return e=a?r:e,n.resolve(e),e},function(e){return n.reject(e),i(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,a,i;if(i=0,t=Object(this),a=t.length>>>0,n=arguments,n.length<=1)for(;;){if(i in t){r=t[i++];break}if(++i>=a)throw new TypeError}else r=n[1];for(;i<a;++i)i in t&&(r=e(r,t[i],i,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,a,i=0,o=e.length-1;i<=o;)if(r=~~((i+o)/2),(a=n(e[r],t))<0)i=r+1;else{if(!(a>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,a){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=a}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],a=function(e,t,n,r){n||(n=" ");var a=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+a:a+e},i=function(e,t,n,r,i,o){var u=r-e.length;return u>0&&(e=n||!i?a(e,r,o,n):e.slice(0,t.length)+a("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+a(c.toString(t),u||0,"0",!1),i(e,n,r,o,s)},u=function(e,t,n,r,a,o){return null!=r&&(e=e.slice(0,r)),i(e,"",t,n,a,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",N=s.length,O=0;s&&O<N;O++)switch(s.charAt(O)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(O+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,S);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),E=d<0?"-":T,_=E+a(String(Math.abs(d)),f,"0",!1),i(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=E+Math.abs(d)[m](f),i(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,a,i,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=a,this.second=i,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var a=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>a&&(r--,a=n[r].offset)}m.addSeconds(e,a,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,a=t(r,y,l);if(a<0&&(a=~a),0===a)return m.addSeconds(e,-r[0].offset,n);if(a>=r.length)return m.addSeconds(e,-r[a-1].offset,n);var i=m.secondsDifference(r[a].julianDate,e);return 0===i?m.addSeconds(e,-r[a].offset,n):i<=1?void 0:m.addSeconds(e,-r[--a].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,a,i,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=i+(r*s.SECONDS_PER_HOUR+a*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var a=0|e;t+=(e-a)*s.SECONDS_PER_DAY,d(a,t,this),r===c.UTC&&f(this)}var p=new i,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,N=/^(\d{4})-?(\d{2})-?(\d{2})$/,O=/([Z+\-])?(\d{2})?:?(\d{2})?$/,M=/^(\d{2})(\.\d+)?/.source+O.source,v=/^(\d{2}):?(\d{2})(\.\d+)?/.source+O.source,I=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+O.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,a,i,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,O=0,g=u[0],w=u[1];if(null!==(u=g.match(N)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=g.match(R)))n=+u[1],s=+u[2];else if(null!==(u=g.match(T)))n=+u[1];else{var C;if(null!==(u=g.match(A)))n=+u[1],C=+u[2],i=o(n);else if(null!==(u=g.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}a=new Date(Date.UTC(n,0,1)),a.setUTCDate(C),s=a.getUTCMonth()+1,l=a.getUTCDate()}i=o(n);var D;if(r(w)){u=w.match(I),null!==u?(h=+u[1],p=+u[2],y=+u[3],O=1e3*+(u[4]||0),D=5):(u=w.match(v),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(M))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,p-=B;break;case"-":h+=F,p+=B;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var b=60===y;for(b&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(a=i&&2===s?29:_[s-1];l>a;)l-=a,s++,s>12&&(s-=12,n++),a=i&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),a=i&&2===s?29:_[s-1],l+=a;var z=E(n,s,l,h,p,y,O);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var g=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,a=h(e,g);r(a)||(m.addSeconds(e,-1,g),a=h(g,g),n=!0);var o=a.dayNumber,u=a.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new i(_,p,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var a,i=m.toGregorianDate(t,p);return r(n)||0===i.millisecond?r(n)&&0!==n?(a=(.01*i.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",i.year,i.month,i.day,i.hour,i.minute,i.second):(a=(.01*i.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",i.year,i.month,i.day,i.hour,i.minute,i.second,a))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var a=new n.constructor;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];r&&(o=t(o,r)),a[i]=o}return a}return t}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./RequestState","./RequestType"],function(e,t,n){"use strict";function r(r){r=e(r,e.EMPTY_OBJECT);var a=e(r.throttleByServer,!1),i=a||e(r.throttle,!1);this.url=r.url,this.requestFunction=r.requestFunction,this.cancelFunction=r.cancelFunction,this.priorityFunction=r.priorityFunction,this.priority=e(r.priority,0),this.throttle=i,this.throttleByServer=a,this.type=e(r.type,n.OTHER),this.serverKey=void 0,this.state=t.UNISSUED,this.deferred=void 0,this.cancelled=!1}return r.prototype.cancel=function(){this.cancelled=!0},r}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var a=n[r],i=a.indexOf(": ");if(i>0){var o=a.substring(0,i),u=a.substring(i+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return i.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(a,t)),this.path&&(this.path=this.path.replace(a,t)),this.query&&(this.query=this.query.replace(a,t)),this.fragment&&(this.fragment=this.fragment.replace(a,t))};var a=/%[0-9a-z]{2}/gi,i=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function a(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function i(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(a.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),a.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},a.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,a=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(a[c],a[e])<0?c:e,s<n&&r(a[s],a[o])<0&&(o=s),o!==e?(i(a,o,e),e=o):u=!1}},a.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},a.prototype.insert=function(e){var t=this._array,r=this._comparator,a=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;i(t,o,u),o=u}var s;return n(a)&&this._length>a&&(s=t[a],this._length=a),s},a.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return i(n,e,--this._length),this.heapify(e),r}},a}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t){return e.priority-t.priority}function l(){}function f(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function h(e){return O[e]<l.maximumRequestsPerServer}function d(e){return e.state===s.UNISSUED&&(e.state=s.ISSUED,e.deferred=t.defer()),e.deferred.promise}function E(e){return function(t){e.state!==s.CANCELLED&&(--R.numberOfActiveRequests,--O[e.serverKey],e.state=s.RECEIVED,e.deferred.resolve(t))}}function m(e){return function(t){e.state!==s.CANCELLED&&(++R.numberOfFailedRequests,--R.numberOfActiveRequests,--O[e.serverKey],e.state=s.FAILED,e.deferred.reject(t))}}function p(e){var t=d(e);return e.state=s.ACTIVE,N.push(e),++R.numberOfActiveRequests,++R.numberOfActiveRequestsEver,++O[e.serverKey],e.requestFunction().then(E(e)).otherwise(m(e)),t}function _(e){var t=e.state===s.ACTIVE;e.state=s.CANCELLED,++R.numberOfCancelledRequests,e.deferred.reject(),t&&(--R.numberOfActiveRequests,--O[e.serverKey],++R.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function y(){R.numberOfAttemptedRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0}function T(){l.debugShowStatistics&&(R.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+R.numberOfAttemptedRequests),R.numberOfActiveRequests>0&&console.log("Number of active requests: "+R.numberOfActiveRequests),R.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+R.numberOfCancelledRequests),R.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+R.numberOfCancelledActiveRequests),R.numberOfFailedRequests>0&&console.log("Number of failed requests: "+R.numberOfFailedRequests),y())}var R={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},A=20,S=new i({comparator:c});S.maximumLength=A,S.reserve(A);var N=[],O={},M="undefined"!=typeof document?new e(document.location.href):new e;return l.maximumRequests=50,l.maximumRequestsPerServer=6,l.throttleRequests=!0,l.debugShowStatistics=!1,a(l,{statistics:{get:function(){return R}},priorityHeapLength:{get:function(){return A},set:function(e){if(e<A)for(;S.length>e;){var t=S.pop();_(t)}A=e,S.maximumLength=e,S.reserve(e)}}}),l.update=function(){var e,t,n=0,r=N.length;for(e=0;e<r;++e)t=N[e],t.cancelled&&_(t),t.state===s.ACTIVE?n>0&&(N[e-n]=t):++n;N.length-=n;var a=S.internalArray,i=S.length;for(e=0;e<i;++e)f(a[e]);S.resort();for(var o=Math.max(l.maximumRequests-N.length,0),u=0;u<o&&S.length>0;)t=S.pop(),t.cancelled?_(t):!t.throttleByServer||h(t.serverKey)?(p(t),++u):_(t);T()},l.getServerKey=function(t){var n=new e(t).resolve(M);n.normalize();var a=n.authority;/:/.test(a)||(a=a+":"+("https"===n.scheme?"443":"80"));var i=O[a];return r(i)||(O[a]=0),a},l.request=function(e){if(u(e.url)||o(e.url))return e.state=s.RECEIVED,e.requestFunction();if(++R.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=l.getServerKey(e.url)),!l.throttleRequests||!e.throttle)return p(e);if(!(N.length>=l.maximumRequests)&&(!e.throttleByServer||h(e.serverKey))){f(e);var t=S.insert(e);if(r(t)){if(t===e)return;_(t)}return d(e)}},l.clearForSpecs=function(){for(;S.length>0;){_(S.pop())}for(var e=N.length,t=0;t<e;++t)_(N[t]);N.length=0,O={},R.numberOfAttemptedRequests=0,R.numberOfActiveRequests=0,R.numberOfCancelledRequests=0,R.numberOfCancelledActiveRequests=0,R.numberOfFailedRequests=0,R.numberOfActiveRequestsEver=0},l.numberOfActiveRequestsByServer=function(e){return O[e]},l.requestHeap=S,l}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var a=r.getAuthority();if(t(a)){if(-1!==a.indexOf("@")){a=a.split("@")[1]}if(-1===a.indexOf(":")){var i=r.getScheme();if(t(i)||(i=window.location.protocol,i=i.substring(0,i.length-1)),"http"===i)a+=":80";else{if("https"!==i)return;a+=":443"}}return a}}var a={},i={};return a.add=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])||(i[r]=!0)},a.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(i[r])&&delete i[r]},a.contains=function(e){var n=r(e);return!(!t(n)||!t(i[n]))},a.clear=function(){i={}},a}),define("Core/loadWithXhr",["../ThirdParty/when","./Check","./defaultValue","./defined","./DeveloperError","./Request","./RequestErrorEvent","./RequestScheduler","./RuntimeError","./TrustedServers"],function(e,t,n,r,a,i,o,u,s,c){"use strict";function l(t){t=n(t,n.EMPTY_OBJECT);var a=t.url,o=t.responseType,s=n(t.method,"GET"),c=t.data,f=t.headers,h=t.overrideMimeType;a=n(a,t.url);var d=r(t.request)?t.request:new i;return d.url=a,d.requestFunction=function(){var t=e.defer(),n=l.load(a,o,s,c,f,t,h);return r(n)&&r(n.abort)&&(d.cancelFunction=function(){n.abort()}),t.promise},u.request(d)}function f(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function h(e,t){for(var n=f(e,t),r=new ArrayBuffer(n.length),a=new Uint8Array(r),i=0;i<n.length;i++)a[i]=n.charCodeAt(i);return r}function d(e,t){t=n(t,"");var r=e[1],a=!!e[2],i=e[3];switch(t){case"":case"text":return f(a,i);case"arraybuffer":return h(a,i);case"blob":var o=h(a,i);return new Blob([o],{type:r});case"document":return(new DOMParser).parseFromString(f(a,i),r);case"json":return JSON.parse(f(a,i))}}var E=/^data:(.*?)(;base64)?,(.*)$/;return l.load=function(e,t,n,a,i,u,l){var f=E.exec(e);if(null!==f)return void u.resolve(d(f,t));var h=new XMLHttpRequest;if(c.contains(e)&&(h.withCredentials=!0),r(l)&&r(h.overrideMimeType)&&h.overrideMimeType(l),h.open(n,e,!0),r(i))for(var m in i)i.hasOwnProperty(m)&&h.setRequestHeader(m,i[m]);r(t)&&(h.responseType=t);var p=!1;return"string"==typeof e&&(p=0===e.indexOf("file://")),h.onload=function(){if((h.status<200||h.status>=300)&&(!p||0!==h.status))return void u.reject(new o(h.status,h.response,h.getAllResponseHeaders()));var e=h.response,n=h.responseType;if(204===h.status)u.resolve();else if(!r(e)||r(t)&&n!==t)if("json"===t&&"string"==typeof e)try{u.resolve(JSON.parse(e))}catch(e){u.reject(e)}else(""===n||"document"===n)&&r(h.responseXML)&&h.responseXML.hasChildNodes()?u.resolve(h.responseXML):""!==n&&"text"!==n||!r(h.responseText)?u.reject(new s("Invalid XMLHttpRequest response type.")):u.resolve(h.responseText);else u.resolve(e)},h.onerror=function(e){u.reject(new o)},h.send(a),h},l.defaultLoad=l.load,l}),define("Core/loadText",["./loadWithXhr"],function(e){"use strict";function t(t,n,r){return e({url:t,headers:n,request:r})}return t}),define("Core/loadJson",["./clone","./defined","./DeveloperError","./loadText"],function(e,t,n,r){"use strict";function a(n,a,o){t(a)?t(a.Accept)||(a=e(a),a.Accept=i.Accept):a=i;var u=r(n,a,o);if(t(u))return u.then(function(e){if(t(e))return JSON.parse(e)})}var i={Accept:"application/json,*/*;q=0.01"};return a}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./loadJson","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,a,i,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var a=this;this._downloadPromise=e(s(t.url),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+t.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var a=n.columnNames.indexOf("modifiedJulianDateUtc"),i=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(a<0||i<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=a,e._xPoleWanderRadiansColumn=i,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var S=p[R+a],N=p[R+m],O=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,M=new o(O,N,f.TAI);if(_.push(M),T){if(N!==y&&r(y)){var v=o.leapSeconds,I=t(v,M,d);if(I<0){var g=new u(M,N);v.splice(~I,0,g)}}y=N}}}function m(e,t,n,r,a){var i=n*r;a.xPoleWander=t[i+e._xPoleWanderRadiansColumn],a.yPoleWander=t[i+e._yPoleWanderRadiansColumn],a.xPoleOffset=t[i+e._xCelestialPoleOffsetRadiansColumn],a.yPoleOffset=t[i+e._yCelestialPoleOffsetRadiansColumn],a.ut1MinusUtc=t[i+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,a,i,u){var s=e._columnCount;if(i>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[a],l=t[i];if(c.equals(l)||r.equals(c))return m(e,n,a,s,u),u;if(r.equals(l))return m(e,n,i,s,u),u -;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=a*s,d=i*s,E=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return h.NONE=i({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new a(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new a(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var i=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=i[u],h=i[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,_(this,i,this._samples,e,s,l,n),n}var p=t(i,e,o.compare,this._dateColumn);return p>=0?(p<i.length-1&&i[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,i,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(n,r){r=t(r,document.location.href);var a=new e(r);return new e(n).resolve(a).toString()}return a}),define("Core/joinUrls",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function a(r,a,i){if(i=t(i,!0),r instanceof e||(r=new e(r)),a instanceof e||(a=new e(a)),"data"===r.scheme)return r.toString();if("data"===a.scheme)return a.toString();n(a.authority)&&!n(a.scheme)&&("undefined"!=typeof document&&n(document.location)&&n(document.location.href)?a.scheme=new e(document.location.href).scheme:a.scheme=r.scheme);var o=r;a.isAbsolute()&&(o=a);var u="";n(o.scheme)&&(u+=o.scheme+":"),n(o.authority)&&(u+="//"+o.authority,""!==o.path&&"/"!==o.path&&(u=u.replace(/\/?$/,"/"),o.path=o.path.replace(/^\/?/g,""),""===o.authority&&(u+="/"))),u+=o===r?i?r.path.replace(/\/?$/,"/")+a.path.replace(/^\/?/g,""):r.path+a.path:a.path;var s=n(r.query),c=n(a.query);s&&c?u+="?"+r.query+"&"+a.query:s&&!c?u+="?"+r.query:!s&&c&&(u+="?"+a.query);var l=n(a.fragment);return n(r.fragment)&&!l?u+="#"+r.fragment:l&&(u+="#"+a.fragment),u}return a}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./getAbsoluteUri","./joinUrls","require"],function(e,t,n,r,a,i){"use strict";function o(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),a=E.exec(r);if(null!==a)return a[1]}}function u(){if(t(f))return f;var n;return n="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:o(),f=new e(r(n))}function s(e){return i.toUrl("../"+e)}function c(e){return a(u(),e)}function l(e){t(h)||(h=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?s:c),t(d)||(d=document.createElement("a"));var n=h(e);return d.href=n,d.href=d.href,d.href}var f,h,d,E=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return l._cesiumScriptRegex=E,l.setBaseUrl=function(t){f=new e(t).resolve(new e(document.location.href))},l}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./loadJson","./TimeStandard"],function(e,t,n,r,a,i,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=e.xysFileUrlTemplate,this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new i(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),a=this._xTable=new Array(t+1),o=Math.pow(this._stepSizeDays,t),s=0;s<=t;++s){r[s]=o,a[s]=s*this._stepSizeDays;for(var c=0;c<=t;++c)c!==s&&(r[s]*=s-c);r[s]=1/r[s]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,i.daysDifference(r,e._sampleZeroDateTT)}function l(n,a){if(n._chunkDownloadsInProgress[a])return n._chunkDownloadsInProgress[a];var i=e.defer();n._chunkDownloadsInProgress[a]=i;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.replace("{0}",a):t("Assets/IAU2006_XYS/IAU2006_XYS_"+a+".json"),e(o(u),function(e){n._chunkDownloadsInProgress[a]=!1;for(var t=n._samples,r=e.samples,o=a*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];i.resolve()}),i.promise}var f=new i(0,0,u.TAI);return s.prototype.preload=function(t,n,r,a){var i=c(this,t,n),o=c(this,r,a),u=i/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var i=c(this,e,t);if(!(i<0)){var o=i/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new a(0,0,0);var E,m,p=i-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},a={};return t(a,{element:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(a.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(a.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(a.supportsFullscreen())return null!==a.element}}}),a.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var a,i=["webkit","moz","o","ms","khtml"],o=0,u=i.length;o<u;++o){var s=i[o];a=s+"RequestFullscreen","function"==typeof t[a]?(r.requestFullscreen=a,n=!0):(a=s+"RequestFullScreen","function"==typeof t[a]&&(r.requestFullscreen=a,n=!0)),a=s+"ExitFullscreen","function"==typeof document[a]?r.exitFullscreen=a:(a=s+"CancelFullScreen","function"==typeof document[a]&&(r.exitFullscreen=a)),a=s+"FullscreenEnabled",void 0!==document[a]?r.fullscreenEnabled=a:(a=s+"FullScreenEnabled",void 0!==document[a]&&(r.fullscreenEnabled=a)),a=s+"FullscreenElement",void 0!==document[a]?r.fullscreenElement=a:(a=s+"FullScreenElement",void 0!==document[a]&&(r.fullscreenElement=a)),a=s+"fullscreenchange",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenChange"),r.fullscreenchange=a),a=s+"fullscreenerror",void 0!==document["on"+a]&&("ms"===s&&(a="MSFullscreenError"),r.fullscreenerror=a)}return n},a.requestFullscreen=function(e,t){a.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},a.exitFullscreen=function(){a.supportsFullscreen()&&document[r.exitFullscreen]()},a}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function a(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function i(){return a()&&S}function o(){if(!t(N)&&(N=!1,!a()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(N=!0,O=r(e[1]))}return N}function u(){return o()&&O}function s(){if(!t(M)){M=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(M=!0,v=r(e[1]),v.isNightly=!!e[2])}return M}function c(){return s()&&v}function l(){if(!t(I)){I=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,g=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(I=!0,g=r(e[1]))}return I}function f(){return l()&&g}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,N,O,M,v,I,g,w,C,x,P,U,D,L,F,B={isChrome:a,chromeVersion:i,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,a,i,o,u){"use strict";function s(e,t,r,a){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(a,0)}var c=new e;s.fromAxisAngle=function(t,n,a){var i=n/2,o=Math.sin(i);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(i);return r(a)?(a.x=u,a.y=l,a.z=f,a.w=h,a):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,a,i,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,a=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,i=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),E>h&&E>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,a=-R[0],i=-R[1],o=-R[2]}return r(t)?(t.x=a,t.y=i,t.z=o,t.w=c,t):new s(a,i,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,a){return t=n(t,0),r(a)||(a=new s),a.x=e[t],a.y=e[t+1],a.z=e[t+2],a.w=e[t+3],a},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var a=0,i=n-t+1;a<i;a++){var o=3*a;s.unpack(e,4*(t+a),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,a,i,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*i,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,a=e.y*n,i=e.z*n,o=e.w*n;return t.x=r,t.y=a,t.z=i,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,a=e.y,i=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+a*c-i*s,h=o*s-r*c+a*l+i*u,d=o*c+r*s-a*u+i*l,E=o*l-r*u-a*s-i*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,N=new s,O=new s;s.slerp=function(e,t,n,r){var a=s.dot(e,t),i=t;if(a<0&&(a=-a,i=S=s.negate(t,S)),1-a<o.EPSILON6)return s.lerp(e,i,n,r);var u=Math.acos(a);return N=s.multiplyByScalar(e,Math.sin((1-n)*u),N),O=s.multiplyByScalar(i,Math.sin(n*u),O),r=s.add(N,O,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),a=0;return 0!==r&&(a=r/Math.sin(r)),e.multiplyByScalar(t,a,n)},s.exp=function(t,n){var r=e.magnitude(t),a=0;return 0!==r&&(a=Math.sin(r)/r),n.x=t.x*a,n.y=t.y*a,n.z=t.z*a,n.w=Math.cos(r),n};var M=new e,v=new e,I=new s,g=new s;s.computeInnerQuadrangle=function(t,n,r,a){var i=s.conjugate(n,I);s.multiply(i,r,g);var o=s.log(g,M);s.multiply(i,t,g);var u=s.log(g,v);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,I),s.multiply(n,I,a)},s.squad=function(e,t,n,r,a,i){var o=s.slerp(e,t,a,I),u=s.slerp(n,r,a,g);return s.slerp(o,u,2*a*(1-a),i)};for(var w=new s,C=1.9011074535173003,x=a.supportsTypedArrays()?new Float32Array(8):[],P=a.supportsTypedArrays()?new Float32Array(8):[],U=a.supportsTypedArrays()?new Float32Array(8):[],D=a.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;x[L]=1/(F*B),P[L]=F/B}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var a,i=s.dot(e,t);i>=0?a=1:(a=-1,i=-i);for(var o=i-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=a*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,a,i){var o=s.fastSlerp(e,t,a,I),u=s.fastSlerp(n,r,a,g);return s.fastSlerp(o,u,2*a*(1-a),i)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=i(new s(0,0,0,0)),s.IDENTITY=i(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E,m,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},N={},O={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},M=new n,v=new n,I=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,a=A[e][t],i=e+t;return u(N[i])?r=N[i]:(r=function(r,i,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,M),"east"!==e&&"west"!==e&&n.multiplyByScalar(M,c,M),n.unpack(S[t],0,v),"east"!==t&&"west"!==t&&n.multiplyByScalar(v,c,v),n.unpack(S[a],0,I),"east"!==a&&"west"!==a&&n.multiplyByScalar(I,c,I)}else{i=o(i,f.WGS84),i.geodeticSurfaceNormal(r,O.up);var l=O.up,h=O.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,O.east),n.cross(l,h,O.north),n.multiplyByScalar(O.up,-1,O.down),n.multiplyByScalar(O.east,-1,O.west),n.multiplyByScalar(O.north,-1,O.south),M=O[e],v=O[t],I=O[a]}return s[0]=M.x,s[1]=M.y,s[2]=M.z,s[3]=0,s[4]=v.x,s[5]=v.y,s[6]=v.z,s[7]=0,s[8]=I.x,s[9]=I.y,s[10]=I.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},N[i]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var g=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,a,i){a=o(a,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,g),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return i=a(e,r,i),_.multiply(i,s,i)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,a){var i=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(i,P);return y.fromRotationMatrix(o,a)};var U=m.TWO_PI/86400,D=new E;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,a=D.secondsOfDay,i=r-2451545;n=a>=43200?(i+.5)/T.DAYS_PER_JULIAN_CENTURY:(i-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(a+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,a=t.stop.dayNumber,i=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,a,i),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new p,b=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,a=e.secondsOfDay+32.184,i=R.iau2006XysData.computeXysRadians(r,a,L);if(u(i)){var o=i.x+n.xPoleOffset,s=i.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-i.s,b),h=p.multiply(l,f,B),d=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=_/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var N=p.fromRotationZ(S,b),O=p.multiply(h,N,B),M=Math.cos(n.xPoleWander),v=Math.cos(n.yPoleWander),I=Math.sin(n.xPoleWander),g=Math.sin(n.yPoleWander),w=r-2451545+a/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=b;return U[0]=M*x,U[1]=M*P,U[2]=I,U[3]=-v*P+g*I*x,U[4]=v*x+g*I*P,U[5]=-g*M,U[6]=-g*P-v*I*x,U[7]=g*x-v*I*P,U[8]=v*M,p.multiply(O,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,a,i){u(i)||(i=new t);var o=z;return _.multiplyByVector(e,r.fromElements(a.x,a.y,a.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,i)};var q=new n,G=new n,X=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,a){var i=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,i,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,X);return n.cross(t,c,s),n.negate(s,s),u(a)||(a=new p),a[0]=t.x,a[1]=t.y,a[2]=t.z,a[3]=s.x,a[4]=s.y,a[5]=s.z,a[6]=c.x,a[7]=c.y,a[8]=c.z,a};var W=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),V=new a,H=new n,Y=new n,k=new p,Z=new _,j=new _;return R.basisTo2D=function(e,t,r){var a=_.getTranslation(t,Y),i=e.ellipsoid,o=i.cartesianToCartographic(a,V),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(a,i,Z),c=_.inverseTransformation(s,j),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(W,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var a=e.ellipsoid,i=R.eastNorthUpToFixedFrame(t,a,Z),o=_.inverseTransformation(i,j),u=a.cartesianToCartographic(t,V),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,Z);return _.multiply(W,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=a(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var i=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,i)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var a=_;a.origin=e,n.normalize(e,a.direction);var o=c.rayPlane(a,this._plane,y);if(i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y)),i(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return i(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){i(t)||(t=[]);for(var n=0,r=e.length,a=0;a<r;a++){var o=this.projectPointOntoPlane(e[a],t[n]);i(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){i(r)||(r=new t);var a=_;a.origin=e,n.clone(this._plane.normal,a.direction);var o=c.rayPlane(a,this._plane,y);i(o)||(n.negate(a.direction,a.direction),o=c.rayPlane(a,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){i(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;i(t)?t.length=r:t=new Array(r);for(var a=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),i(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),a.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d,E){"use strict";function m(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=h.clone(a(t,h.ZERO))}function p(e,t,r,a,o,u,s,c){i(c)||(c=new m);var l=c.halfAxes;h.setColumn(l,0,e.xAxis,l),h.setColumn(l,1,e.yAxis,l),h.setColumn(l,2,e.zAxis,l);var f=M;f.x=(t+r)/2,f.y=(a+o)/2,f.z=(u+s)/2;var d=v;d.x=(r-t)/2,d.y=(o-a)/2,d.z=(s-u)/2;var E=c.center;return f=h.multiplyByVector(l,f,f),n.add(e.origin,f,E),h.multiplyByScale(l,d,l),c}var _=new n,y=new n,T=new n,R=new n,A=new n,S=new n,N=new h,O={unitary:new h,diagonal:new h};m.fromPoints=function(e,t){if(i(t)||(t=new m),!i(e)||0===e.length)return t.halfAxes=h.ZERO,t.center=n.ZERO,t;var r,a=e.length,o=n.clone(e[0],_);for(r=1;r<a;r++)n.add(o,e[r],o);var u=1/a;n.multiplyByScalar(o,u,o);var s,c=0,l=0,f=0,d=0,E=0,p=0;for(r=0;r<a;r++)s=n.subtract(e[r],o,y),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,d+=s.y*s.y,E+=s.y*s.z,p+=s.z*s.z;c*=u,l*=u,f*=u,d*=u,E*=u,p*=u;var M=N;M[0]=c,M[1]=l,M[2]=f,M[3]=l,M[4]=d,M[5]=E,M[6]=f,M[7]=E,M[8]=p;var v=h.computeEigenDecomposition(M,O),I=h.clone(v.unitary,t.halfAxes),g=h.getColumn(I,0,R),w=h.getColumn(I,1,A),C=h.getColumn(I,2,S),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<a;r++)s=e[r],x=Math.max(n.dot(g,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(g,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);g=n.multiplyByScalar(g,.5*(D+x),g),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var B=n.add(g,w,t.center);n.add(B,C,B);var b=T;return b.x=x-D,b.y=P-L,b.z=U-F,n.multiplyByScalar(b,.5,b),h.multiplyByScale(t.halfAxes,b,t.halfAxes),t};var M=new n,v=new n,I=new r,g=new n,w=[new r,new r,new r,new r,new r,new r,new r,new r],C=[new n,new n,new n,new n,new n,new n,new n,new n],x=[new t,new t,new t,new t,new t,new t,new t,new t];m.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,u.WGS84);var o=E.center(e,I),c=r.cartographicToCartesian(o,g),l=new s(c,r),f=l.plane,h=w[0],m=w[1],_=w[2],y=w[3],T=w[4],R=w[5],A=w[6],S=w[7],N=o.longitude,O=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=O,h.latitude=m.latitude=_.latitude=e.north,A.longitude=S.longitude=h.longitude=e.west,R.longitude=m.longitude=N,T.longitude=y.longitude=_.longitude=e.east,_.height=m.height=h.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(w,C),l.projectPointsToNearestOnPlane(C,x);var M=Math.min(x[6].x,x[7].x,x[0].x),v=Math.max(x[2].x,x[3].x,x[4].x),P=Math.min(x[4].y,x[5].y,x[6].y),U=Math.max(x[0].y,x[1].y,x[2].y);return _.height=h.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(w,C),p(l,M,v,P,U,Math.min(d.getPointDistance(f,C[0]),d.getPointDistance(f,C[2]),d.getPointDistance(f,C[4]),d.getPointDistance(f,C[6])),n,i)},m.clone=function(e,t){if(i(e))return i(t)?(n.clone(e.center,t.center),h.clone(e.halfAxes,t.halfAxes),t):new m(e.center,e.halfAxes)},m.intersectPlane=function(e,t){var r=e.center,a=t.normal,i=e.halfAxes,o=a.x,u=a.y,s=a.z,l=Math.abs(o*i[h.COLUMN0ROW0]+u*i[h.COLUMN0ROW1]+s*i[h.COLUMN0ROW2])+Math.abs(o*i[h.COLUMN1ROW0]+u*i[h.COLUMN1ROW1]+s*i[h.COLUMN1ROW2])+Math.abs(o*i[h.COLUMN2ROW0]+u*i[h.COLUMN2ROW1]+s*i[h.COLUMN2ROW2]),f=n.dot(a,r)+t.distance;return f<=-l?c.OUTSIDE:f>=l?c.INSIDE:c.INTERSECTING};var P=new n,U=new n,D=new n,L=new n;m.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,M),a=e.halfAxes,i=h.getColumn(a,0,P),o=h.getColumn(a,1,U),u=h.getColumn(a,2,D),s=n.magnitude(i),c=n.magnitude(o),l=n.magnitude(u);n.normalize(i,i),n.normalize(o,o),n.normalize(u,u);var f=L;f.x=n.dot(r,i),f.y=n.dot(r,o),f.z=n.dot(r,u);var d,E=0;return f.x<-s?(d=f.x+s,E+=d*d):f.x>s&&(d=f.x-s,E+=d*d),f.y<-c?(d=f.y+c,E+=d*d):f.y>c&&(d=f.y-c,E+=d*d),f.z<-l?(d=f.z+l,E+=d*d):f.z>l&&(d=f.z-l,E+=d*d),E};var F=new n,B=new n;m.computePlaneDistances=function(e,t,r,a){i(a)||(a=new l);var o=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,f=h.getColumn(c,0,P),d=h.getColumn(c,1,U),E=h.getColumn(c,2,D),m=n.add(f,d,F);n.add(m,E,m),n.add(m,s,m);var p=n.subtract(m,t,B),_=n.dot(r,p);return o=Math.min(_,o),u=Math.max(_,u),n.add(s,f,m),n.add(m,d,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),n.add(s,f,m),n.subtract(m,d,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),n.add(s,f,m),n.subtract(m,d,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),n.subtract(s,f,m),n.add(m,d,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),n.subtract(s,f,m),n.add(m,d,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),n.subtract(s,f,m),n.subtract(m,d,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),n.subtract(s,f,m),n.subtract(m,d,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),o=Math.min(_,o),u=Math.max(_,u),a.start=o,a.stop=u,a};var b=new e;return m.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,b);return!n.isBoundingSphereVisible(r)},m.prototype.intersectPlane=function(e){return m.intersectPlane(this,e)},m.prototype.distanceSquaredTo=function(e){return m.distanceSquaredTo(this,e)},m.prototype.computePlaneDistances=function(e,t,n){return m.computePlaneDistances(this,e,t,n)},m.prototype.isOccluded=function(e){return m.isOccluded(this,e)},m.equals=function(e,t){return e===t||i(e)&&i(t)&&n.equals(e.center,t.center)&&h.equals(e.halfAxes,t.halfAxes)},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,a,i){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:i.BYTE,UNSIGNED_BYTE:i.UNSIGNED_BYTE,SHORT:i.SHORT,UNSIGNED_SHORT:i.UNSIGNED_SHORT,INT:i.INT,UNSIGNED_INT:i.UNSIGNED_INT,FLOAT:i.FLOAT,DOUBLE:i.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT: -return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,a){switch(r=e(r,0),a=e(a,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,a);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,a);case o.SHORT:return new Int16Array(n,r,a);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,a);case o.INT:return new Int32Array(n,r,a);case o.UNSIGNED_INT:return new Uint32Array(n,r,a);case o.FLOAT:return new Float32Array(n,r,a);case o.DOUBLE:return new Float64Array(n,r,a)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},a(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,a,i,o,u,s){"use strict";function c(e,t,r,o,c,h){var p,_,y,T;if(i(e)&&i(t)&&i(r)&&i(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),N=r-t;p=Math.max(n.maximumComponent(S),N)<m-1?s.BITS12:s.NONE,_=e.center,y=u.inverseTransformation(o,new u);var O=n.negate(R,l);u.multiply(u.fromTranslation(O,d),y,y);var M=l;M.x=1/S.x,M.y=1/S.y,M.z=1/S.z,u.multiply(u.fromScale(M,d),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var v=u.fromTranslation(R,d),I=u.fromScale(S,E),g=u.multiply(v,I,d);u.multiply(o,g,o),u.multiply(T,g,T)}this.quantization=p,this.minimumHeight=t,this.maximumHeight=r,this.center=_,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=a(h,!1)}var l=new n,f=new n,h=new t,d=new u,E=new u,m=Math.pow(2,12);c.prototype.encode=function(r,a,i,c,f,d,E){var m=c.x,p=c.y;if(this.quantization===s.BITS12){i=u.multiplyByPoint(this.toScaledENU,i,l),i.x=o.clamp(i.x,0,1),i.y=o.clamp(i.y,0,1),i.z=o.clamp(i.z,0,1);var _=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/_,0,1);t.fromElements(i.x,i.y,h);var T=e.compressTextureCoordinates(h);t.fromElements(i.z,y,h);var R=e.compressTextureCoordinates(h);t.fromElements(m,p,h);var A=e.compressTextureCoordinates(h);if(r[a++]=T,r[a++]=R,r[a++]=A,this.hasWebMercatorT){t.fromElements(E,0,h);var S=e.compressTextureCoordinates(h);r[a++]=S}}else n.subtract(i,this.center,l),r[a++]=l.x,r[a++]=l.y,r[a++]=l.z,r[a++]=f,r[a++]=m,r[a++]=p,this.hasWebMercatorT&&(r[a++]=E);return this.hasVertexNormals&&(r[a++]=e.octPackFloat(d)),a},c.prototype.decodePosition=function(t,r,a){if(i(a)||(a=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],h);a.x=o.x,a.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],h);return a.z=c.x,u.multiplyByPoint(this.fromScaledENU,a,a)}return a.x=t[r],a.y=t[r+1],a.z=t[r+2],n.add(a,this.center,a)},c.prototype.decodeTextureCoordinates=function(n,r,a){return i(a)||(a=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],a):t.fromElements(n[r+4],n[r+5],a)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var a=e[n]/256,i=Math.floor(a),o=256*(a-i);return t.fromElements(i,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var p={position3DAndHeight:0,textureCoordAndEncodedNormals:1},_={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,a=r.getSizeInBytes(n);if(this.quantization===s.NONE){var i=2;return this.hasWebMercatorT&&++i,this.hasVertexNormals&&++i,t=(4+i)*a,[{index:p.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:p.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:i,offsetInBytes:4*a,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*a,[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:_.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*a,strideInBytes:t}]):[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?p:_},c.clone=function(e,t){return i(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,a=t.message;n=e(r)&&e(a)?r+": "+a:t.toString();var i=t.stack;return e(i)&&(n+="\n"+i),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var a,i=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;i.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,i)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(a)||(a=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(i.length=0);try{a(o,i)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),a(o)}}}return r}),define("Workers/upsampleQuantizedTerrainMesh",["../Core/AttributeCompression","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defined","../Core/Ellipsoid","../Core/EllipsoidalOccluder","../Core/IndexDatatype","../Core/Intersections2D","../Core/Math","../Core/OrientedBoundingBox","../Core/TerrainEncoding","./createTaskProcessorWorker"],function(e,t,n,r,a,i,o,u,s,c,l,f,h,d){"use strict";function E(e,n){var a=e.isEastChild,i=e.isNorthChild,d=a?T:0,E=a?y:T,p=i?T:0,L=i?y:T,F=M,B=v,b=I,z=w;F.length=0,B.length=0,b.length=0,z.length=0;var q=g;q.length=0;var G={},X=e.vertices,W=e.indices;W=W.subarray(0,e.skirtIndex);var V,H,Y,k=h.clone(e.encoding),Z=k.hasVertexNormals,j=e.exaggeration,K=0,J=e.vertexCountWithoutSkirts,Q=e.minimumHeight,$=e.maximumHeight,ee=new Array(J),te=new Array(J),ne=new Array(J),re=Z?new Array(2*J):void 0;for(H=0,Y=0;H<J;++H,Y+=2){var ae=k.decodeTextureCoordinates(X,H,U);if(V=k.decodeHeight(X,H)/j,ee[H]=l.clamp(ae.x*y|0,0,y),te[H]=l.clamp(ae.y*y|0,0,y),ne[H]=l.clamp((V-Q)/($-Q)*y|0,0,y),ee[H]<20&&(ee[H]=0),te[H]<20&&(te[H]=0),y-ee[H]<20&&(ee[H]=y),y-te[H]<20&&(te[H]=y),Z){var ie=k.getOctEncodedNormal(X,H,D);re[Y]=ie.x,re[Y+1]=ie.y}}var oe,ue;for(H=0,Y=0;H<J;++H,Y+=2)oe=ee[H],ue=te[H],(a&&oe>=T||!a&&oe<=T)&&(i&&ue>=T||!i&&ue<=T)&&(G[H]=K,F.push(oe),B.push(ue),b.push(ne[H]),Z&&(z.push(re[Y]),z.push(re[Y+1])),++K);var se=[];se.push(new m),se.push(new m),se.push(new m);var ce=[];ce.push(new m),ce.push(new m),ce.push(new m);var le,fe;for(H=0;H<W.length;H+=3){var he=W[H],de=W[H+1],Ee=W[H+2],me=ee[he],pe=ee[de],_e=ee[Ee];se[0].initializeIndexed(ee,te,ne,re,he),se[1].initializeIndexed(ee,te,ne,re,de),se[2].initializeIndexed(ee,te,ne,re,Ee);var ye=c.clipTriangleAtAxisAlignedThreshold(T,a,me,pe,_e,R);le=0,le>=ye.length||((le=ce[0].initializeFromClipResult(ye,le,se))>=ye.length||(le=ce[1].initializeFromClipResult(ye,le,se))>=ye.length||(le=ce[2].initializeFromClipResult(ye,le,se),fe=c.clipTriangleAtAxisAlignedThreshold(T,i,ce[0].getV(),ce[1].getV(),ce[2].getV(),A),_(F,B,b,z,q,G,fe,ce,Z),le<ye.length&&(ce[2].clone(ce[1]),ce[2].initializeFromClipResult(ye,le,se),fe=c.clipTriangleAtAxisAlignedThreshold(T,i,ce[0].getV(),ce[1].getV(),ce[2].getV(),A),_(F,B,b,z,q,G,fe,ce,Z))))}var Te=a?-y:0,Re=i?-y:0,Ae=[],Se=[],Ne=[],Oe=[],Me=Number.MAX_VALUE,ve=-Me,Ie=S;Ie.length=0;var ge=o.clone(e.ellipsoid),we=e.childRectangle,Ce=we.north,xe=we.south,Pe=we.east,Ue=we.west;for(Pe<Ue&&(Pe+=l.TWO_PI),H=0;H<F.length;++H)oe=Math.round(F[H]),oe<=d?(Ae.push(H),oe=0):oe>=E?(Ne.push(H),oe=y):oe=2*oe+Te,F[H]=oe,ue=Math.round(B[H]),ue<=p?(Se.push(H),ue=0):ue>=L?(Oe.push(H),ue=y):ue=2*ue+Re,B[H]=ue,V=l.lerp(Q,$,b[H]/y),V<Me&&(Me=V),V>ve&&(ve=V),b[H]=V,N.longitude=l.lerp(Ue,Pe,oe/y),N.latitude=l.lerp(xe,Ce,ue/y),N.height=V,ge.cartographicToCartesian(N,O),Ie.push(O.x),Ie.push(O.y),Ie.push(O.z);var De=t.fromVertices(Ie,r.ZERO,3,x),Le=f.fromRectangle(we,Me,ve,ge,P),Fe=new u(ge),Be=Fe.computeHorizonCullingPointFromVertices(De.center,Ie,3,De.center,C),be=ve-Me,ze=new Uint16Array(F.length+B.length+b.length);for(H=0;H<F.length;++H)ze[H]=F[H];var qe=F.length;for(H=0;H<B.length;++H)ze[qe+H]=B[H];for(qe+=B.length,H=0;H<b.length;++H)ze[qe+H]=y*(b[H]-Me)/be;var Ge,Xe=s.createTypedArray(F.length,q);if(Z){var We=new Uint8Array(z);n.push(ze.buffer,Xe.buffer,We.buffer),Ge=We.buffer}else n.push(ze.buffer,Xe.buffer);return{vertices:ze.buffer,encodedNormals:Ge,indices:Xe.buffer,minimumHeight:Me,maximumHeight:ve,westIndices:Ae,southIndices:Se,eastIndices:Ne,northIndices:Oe,boundingSphere:De,orientedBoundingBox:Le,horizonOcclusionPoint:Be}}function m(){this.vertexBuffer=void 0,this.index=void 0,this.first=void 0,this.second=void 0,this.ratio=void 0}function p(t,n){++F;var a=B[F],i=b[F];return a=e.octDecode(t.first.getNormalX(),t.first.getNormalY(),a),i=e.octDecode(t.second.getNormalX(),t.second.getNormalY(),i),O=r.lerp(a,i,t.ratio,O),r.normalize(O,O),e.octEncode(O,n),--F,n}function _(e,t,n,r,a,o,u,s,c){if(0!==u.length){for(var l=0,f=0;f<u.length;)f=z[l++].initializeFromClipResult(u,f,s);for(var h=0;h<l;++h){var d=z[h];if(d.isIndexed())d.newIndex=o[d.index],d.uBuffer=e,d.vBuffer=t,d.heightBuffer=n,c&&(d.normalBuffer=r);else{var E=d.getKey();if(i(o[E]))d.newIndex=o[E];else{var m=e.length;e.push(d.getU()),t.push(d.getV()),n.push(d.getH()),c&&(r.push(d.getNormalX()),r.push(d.getNormalY())),d.newIndex=m,o[E]=m}}}3===l?(a.push(z[0].newIndex),a.push(z[1].newIndex),a.push(z[2].newIndex)):4===l&&(a.push(z[0].newIndex),a.push(z[1].newIndex),a.push(z[2].newIndex),a.push(z[0].newIndex),a.push(z[2].newIndex),a.push(z[3].newIndex))}}var y=32767,T=y/2|0,R=[],A=[],S=[],N=new a,O=new r,M=[],v=[],I=[],g=[],w=[],C=new r,x=new t,P=new f,U=new n,D=new r;m.prototype.clone=function(e){return i(e)||(e=new m),e.uBuffer=this.uBuffer,e.vBuffer=this.vBuffer,e.heightBuffer=this.heightBuffer,e.normalBuffer=this.normalBuffer,e.index=this.index,e.first=this.first,e.second=this.second,e.ratio=this.ratio,e},m.prototype.initializeIndexed=function(e,t,n,r,a){this.uBuffer=e,this.vBuffer=t,this.heightBuffer=n,this.normalBuffer=r,this.index=a,this.first=void 0,this.second=void 0,this.ratio=void 0},m.prototype.initializeFromClipResult=function(e,t,n){var r=t+1;return-1!==e[t]?n[e[t]].clone(this):(this.vertexBuffer=void 0,this.index=void 0,this.first=n[e[r]],++r,this.second=n[e[r]],++r,this.ratio=e[r],++r),r},m.prototype.getKey=function(){return this.isIndexed()?this.index:JSON.stringify({first:this.first.getKey(),second:this.second.getKey(),ratio:this.ratio})},m.prototype.isIndexed=function(){return i(this.index)},m.prototype.getH=function(){return i(this.index)?this.heightBuffer[this.index]:l.lerp(this.first.getH(),this.second.getH(),this.ratio)},m.prototype.getU=function(){return i(this.index)?this.uBuffer[this.index]:l.lerp(this.first.getU(),this.second.getU(),this.ratio)},m.prototype.getV=function(){return i(this.index)?this.vBuffer[this.index]:l.lerp(this.first.getV(),this.second.getV(),this.ratio)};var L=new n,F=-1,B=[new r,new r],b=[new r,new r];m.prototype.getNormalX=function(){return i(this.index)?this.normalBuffer[2*this.index]:(L=p(this,L),L.x)},m.prototype.getNormalY=function(){return i(this.index)?this.normalBuffer[2*this.index+1]:(L=p(this,L),L.y)};var z=[];return z.push(new m),z.push(new m),z.push(new m),z.push(new m),d(E)})}(); \ No newline at end of file +!function(){define("Core/defined",[],function(){"use strict";function e(e){return void 0!==e&&null!==e}return e}),define("Core/DeveloperError",["./defined"],function(e){"use strict";function t(e){this.name="DeveloperError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t.throwInstantiationError=function(){throw new t("This function defines an interface and should not be called directly.")},t}),define("Core/Check",["./defined","./DeveloperError"],function(e,t){"use strict";function n(e){return e+" is required, actual value was undefined"}function r(e,t,n){return"Expected "+n+" to be typeof "+t+", actual typeof was "+e}var i={};return i.typeOf={},i.defined=function(r,i){if(!e(i))throw new t(n(r))},i.typeOf.func=function(e,n){if("function"!=typeof n)throw new t(r(typeof n,"function",e))},i.typeOf.string=function(e,n){if("string"!=typeof n)throw new t(r(typeof n,"string",e))},i.typeOf.number=function(e,n){if("number"!=typeof n)throw new t(r(typeof n,"number",e))},i.typeOf.number.lessThan=function(e,n,r){if(i.typeOf.number(e,n),n>=r)throw new t("Expected "+e+" to be less than "+r+", actual value was "+n)},i.typeOf.number.lessThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n>r)throw new t("Expected "+e+" to be less than or equal to "+r+", actual value was "+n)},i.typeOf.number.greaterThan=function(e,n,r){if(i.typeOf.number(e,n),n<=r)throw new t("Expected "+e+" to be greater than "+r+", actual value was "+n)},i.typeOf.number.greaterThanOrEquals=function(e,n,r){if(i.typeOf.number(e,n),n<r)throw new t("Expected "+e+" to be greater than or equal to"+r+", actual value was "+n)},i.typeOf.object=function(e,n){if("object"!=typeof n)throw new t(r(typeof n,"object",e))},i.typeOf.bool=function(e,n){if("boolean"!=typeof n)throw new t(r(typeof n,"boolean",e))},i.typeOf.number.equals=function(e,n,r,a){if(i.typeOf.number(e,r),i.typeOf.number(n,a),r!==a)throw new t(e+" must be equal to "+n+", the actual values are "+r+" and "+a)},i}),define("Core/freezeObject",["./defined"],function(e){"use strict";var t=Object.freeze;return e(t)||(t=function(e){return e}),t}),define("Core/defaultValue",["./freezeObject"],function(e){"use strict";function t(e,t){return void 0!==e&&null!==e?e:t}return t.EMPTY_OBJECT=e({}),t}),define("ThirdParty/mersenne-twister",[],function(){var e=function(e){void 0==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,this.init_genrand(e)};return e.prototype.init_genrand=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){var e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},e.prototype.genrand_int32=function(){var e,t=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var n;for(this.mti==this.N+1&&this.init_genrand(5489),n=0;n<this.N-this.M;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+this.M]^e>>>1^t[1&e];for(;n<this.N-1;n++)e=this.mt[n]&this.UPPER_MASK|this.mt[n+1]&this.LOWER_MASK,this.mt[n]=this.mt[n+(this.M-this.N)]^e>>>1^t[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^t[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},e.prototype.random=function(){return this.genrand_int32()*(1/4294967296)},e}),define("Core/Math",["../ThirdParty/mersenne-twister","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";var i={};i.EPSILON1=.1,i.EPSILON2=.01,i.EPSILON3=.001,i.EPSILON4=1e-4,i.EPSILON5=1e-5,i.EPSILON6=1e-6,i.EPSILON7=1e-7,i.EPSILON8=1e-8,i.EPSILON9=1e-9,i.EPSILON10=1e-10,i.EPSILON11=1e-11,i.EPSILON12=1e-12,i.EPSILON13=1e-13,i.EPSILON14=1e-14,i.EPSILON15=1e-15,i.EPSILON16=1e-16,i.EPSILON17=1e-17,i.EPSILON18=1e-18,i.EPSILON19=1e-19,i.EPSILON20=1e-20,i.GRAVITATIONALPARAMETER=3986004418e5,i.SOLAR_RADIUS=6955e5,i.LUNAR_RADIUS=1737400,i.SIXTY_FOUR_KILOBYTES=65536,i.sign=function(e){return e>0?1:e<0?-1:0},i.signNotZero=function(e){return e<0?-1:1},i.toSNorm=function(e,n){return n=t(n,255),Math.round((.5*i.clamp(e,-1,1)+.5)*n)},i.fromSNorm=function(e,n){return n=t(n,255),i.clamp(e,0,n)/n*2-1},i.sinh=function(e){return.5*(Math.pow(Math.E,e)-Math.pow(Math.E,-1*e))},i.cosh=function(e){return.5*(Math.pow(Math.E,e)+Math.pow(Math.E,-1*e))},i.lerp=function(e,t,n){return(1-n)*e+n*t},i.PI=Math.PI,i.ONE_OVER_PI=1/Math.PI,i.PI_OVER_TWO=.5*Math.PI,i.PI_OVER_THREE=Math.PI/3,i.PI_OVER_FOUR=Math.PI/4,i.PI_OVER_SIX=Math.PI/6,i.THREE_PI_OVER_TWO=3*Math.PI*.5,i.TWO_PI=2*Math.PI,i.ONE_OVER_TWO_PI=1/(2*Math.PI),i.RADIANS_PER_DEGREE=Math.PI/180,i.DEGREES_PER_RADIAN=180/Math.PI,i.RADIANS_PER_ARCSECOND=i.RADIANS_PER_DEGREE/3600,i.toRadians=function(e){return e*i.RADIANS_PER_DEGREE},i.toDegrees=function(e){return e*i.DEGREES_PER_RADIAN},i.convertLongitudeRange=function(e){var t=i.TWO_PI,n=e-Math.floor(e/t)*t;return n<-Math.PI?n+t:n>=Math.PI?n-t:n},i.clampToLatitudeRange=function(e){return i.clamp(e,-1*i.PI_OVER_TWO,i.PI_OVER_TWO)},i.negativePiToPi=function(e){return i.zeroToTwoPi(e+i.PI)-i.PI},i.zeroToTwoPi=function(e){var t=i.mod(e,i.TWO_PI);return Math.abs(t)<i.EPSILON14&&Math.abs(e)>i.EPSILON14?i.TWO_PI:t},i.mod=function(e,t){return(e%t+t)%t},i.equalsEpsilon=function(e,n,r,i){i=t(i,r);var a=Math.abs(e-n);return a<=i||a<=r*Math.max(Math.abs(e),Math.abs(n))};var a=[1];i.factorial=function(e){var t=a.length;if(e>=t)for(var n=a[t-1],r=t;r<=e;r++)a.push(n*r);return a[e]},i.incrementWrap=function(e,n,r){return r=t(r,0),++e,e>n&&(e=r),e},i.isPowerOfTwo=function(e){return 0!==e&&0==(e&e-1)},i.nextPowerOfTwo=function(e){return--e,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},i.clamp=function(e,t,n){return e<t?t:e>n?n:e};var o=new e;return i.setRandomNumberSeed=function(t){o=new e(t)},i.nextRandomNumber=function(){return o.random()},i.randomBetween=function(e,t){return i.nextRandomNumber()*(t-e)+e},i.acosClamped=function(e){return Math.acos(i.clamp(e,-1,1))},i.asinClamped=function(e){return Math.asin(i.clamp(e,-1,1))},i.chordLength=function(e,t){return 2*t*Math.sin(.5*e)},i.logBase=function(e,t){return Math.log(e)/Math.log(t)},i.fog=function(e,t){var n=e*t;return 1-Math.exp(-n*n)},i}),define("Core/Cartesian2",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n){this.x=t(e,0),this.y=t(n,0)}o.fromElements=function(e,t,r){return n(r)?(r.x=e,r.y=t,r):new o(e,t)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t):new o(e.x,e.y)},o.fromCartesian3=o.clone,o.fromCartesian4=o.clone,o.packedLength=2,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r]=e.y,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=2*r:t=new Array(2*r);for(var i=0;i<r;++i)o.pack(e[i],t,2*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/2:t=new Array(r/2);for(var i=0;i<r;i+=2){var a=i/2;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y)},o.minimumComponent=function(e){return Math.min(e.x,e.y)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){return o.normalize(e,c),o.normalize(t,l),a.acosClamped(o.dot(c,l))};var f=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Y,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)},o.ZERO=i(new o(0,0)),o.UNIT_X=i(new o(1,0)),o.UNIT_Y=i(new o(0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+")"},o}),define("Core/Cartesian3",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0)}o.fromSpherical=function(e,r){n(r)||(r=new o);var i=e.clock,a=e.cone,u=t(e.magnitude,1),s=u*Math.sin(a);return r.x=s*Math.cos(i),r.y=s*Math.sin(i),r.z=u*Math.cos(a),r},o.fromElements=function(e,t,r,i){return n(i)?(i.x=e,i.y=t,i.z=r,i):new o(e,t,r)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t):new o(e.x,e.y,e.z)},o.fromCartesian4=o.clone,o.packedLength=3,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r]=e.z,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=3*r:t=new Array(3*r);for(var i=0;i<r;++i)o.pack(e[i],t,3*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/3:t=new Array(r/3);for(var i=0;i<r;i+=3){var a=i/3;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o,l=new o;o.angleBetween=function(e,t){o.normalize(e,c),o.normalize(t,l);var n=o.dot(c,l),r=o.magnitude(o.cross(c,l,c));return Math.atan2(r,n)};var f=new o;o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,f);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?o.clone(o.UNIT_X,t):o.clone(o.UNIT_Z,t):n.y<=n.z?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_Z,t)},o.projectVector=function(e,t,n){var r=o.dot(e,t)/o.dot(t,t);return o.multiplyByScalar(t,r,n)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)},o.cross=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=t.x,u=t.y,s=t.z,c=i*s-a*u,l=a*o-r*s,f=r*u-i*o;return n.x=c,n.y=l,n.z=f,n},o.fromDegrees=function(e,t,n,r,i){return e=a.toRadians(e),t=a.toRadians(t),o.fromRadians(e,t,n,r,i)};var h=new o,d=new o,E=new o(40680631590769,40680631590769,40408299984661.445);return o.fromRadians=function(e,r,i,a,u){i=t(i,0);var s=n(a)?a.radiiSquared:E,c=Math.cos(r);h.x=c*Math.cos(e),h.y=c*Math.sin(e),h.z=Math.sin(r),h=o.normalize(h,h),o.multiplyComponents(s,h,d);var l=Math.sqrt(o.dot(h,d));return d=o.divideByScalar(d,l,d),h=o.multiplyByScalar(h,i,h),n(u)||(u=new o),o.add(d,h,u)},o.fromDegreesArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromDegrees(u,s,0,t,r[c])}return r},o.fromRadiansArray=function(e,t,r){var i=e.length;n(r)?r.length=i/2:r=new Array(i/2);for(var a=0;a<i;a+=2){var u=e[a],s=e[a+1],c=a/2;r[c]=o.fromRadians(u,s,0,t,r[c])}return r},o.fromDegreesArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromDegrees(u,s,c,t,r[l])}return r},o.fromRadiansArrayHeights=function(e,t,r){var i=e.length;n(r)?r.length=i/3:r=new Array(i/3);for(var a=0;a<i;a+=3){var u=e[a],s=e[a+1],c=e[a+2],l=a/3;r[l]=o.fromRadians(u,s,c,t,r[l])}return r},o.ZERO=i(new o(0,0,0)),o.UNIT_X=i(new o(1,0,0)),o.UNIT_Y=i(new o(0,1,0)),o.UNIT_Z=i(new o(0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},o}),define("Core/AttributeCompression",["./Cartesian2","./Cartesian3","./Check","./defined","./DeveloperError","./Math"],function(e,t,n,r,i,a){"use strict";function o(e){return e>>1^-(1&e)}var u={};u.octEncodeInRange=function(e,t,n){if(n.x=e.x/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),n.y=e.y/(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z)),e.z<0){var r=n.x,i=n.y;n.x=(1-Math.abs(i))*a.signNotZero(r),n.y=(1-Math.abs(r))*a.signNotZero(i)}return n.x=a.toSNorm(n.x,t),n.y=a.toSNorm(n.y,t),n},u.octEncode=function(e,t){return u.octEncodeInRange(e,255,t)},u.octDecodeInRange=function(e,n,r,i){if(i.x=a.fromSNorm(e,r),i.y=a.fromSNorm(n,r),i.z=1-(Math.abs(i.x)+Math.abs(i.y)),i.z<0){var o=i.x;i.x=(1-Math.abs(i.y))*a.signNotZero(o),i.y=(1-Math.abs(o))*a.signNotZero(i.y)}return t.normalize(i,i)},u.octDecode=function(e,t,n){return u.octDecodeInRange(e,t,255,n)},u.octPackFloat=function(e){return 256*e.x+e.y};var s=new e;return u.octEncodeFloat=function(e){return u.octEncode(e,s),u.octPackFloat(s)},u.octDecodeFloat=function(e,t){var n=e/256,r=Math.floor(n),i=256*(n-r);return u.octDecode(r,i,t)},u.octPack=function(e,t,n,r){var i=u.octEncodeFloat(e),a=u.octEncodeFloat(t),o=u.octEncode(n,s);return r.x=65536*o.x+i,r.y=65536*o.y+a,r},u.octUnpack=function(e,t,n,r){var i=e.x/65536,a=Math.floor(i),o=65536*(i-a);i=e.y/65536;var s=Math.floor(i),c=65536*(i-s);u.octDecodeFloat(o,t),u.octDecodeFloat(c,n),u.octDecode(a,s,r)},u.compressTextureCoordinates=function(e){return 4096*(4095*e.x|0)+(4095*e.y|0)},u.decompressTextureCoordinates=function(e,t){var n=e/4096,r=Math.floor(n);return t.x=r/4095,t.y=(e-4096*r)/4095,t},u.zigZagDeltaDecode=function(e,t,n){for(var i=e.length,a=0,u=0,s=0,c=0;c<i;++c)a+=o(e[c]),u+=o(t[c]),e[c]=a,t[c]=u,r(n)&&(s+=o(n[c]),n[c]=s)},u}),define("Core/scaleToGeodeticSurface",["./Cartesian3","./defined","./DeveloperError","./Math"],function(e,t,n,r){"use strict";function i(n,i,u,s,c){var l=n.x,f=n.y,h=n.z,d=i.x,E=i.y,m=i.z,p=l*l*d*d,_=f*f*E*E,y=h*h*m*m,T=p+_+y,R=Math.sqrt(1/T),A=e.multiplyByScalar(n,R,a);if(T<s)return isFinite(R)?e.clone(A,c):void 0;var S=u.x,v=u.y,g=u.z,N=o;N.x=A.x*S*2,N.y=A.y*v*2,N.z=A.z*g*2;var I,O,M,w,C,x,P,U,D,L,F,B=(1-R)*e.magnitude(n)/(.5*e.magnitude(N)),b=0;do{B-=b,M=1/(1+B*S),w=1/(1+B*v),C=1/(1+B*g),x=M*M,P=w*w,U=C*C,D=x*M,L=P*w,F=U*C,I=p*x+_*P+y*U-1,O=p*D*S+_*L*v+y*F*g;b=I/(-2*O)}while(Math.abs(I)>r.EPSILON12);return t(c)?(c.x=l*M,c.y=f*w,c.z=h*C,c):new e(l*M,f*w,h*C)}var a=new e,o=new e;return i}),define("Core/Cartographic",["./Cartesian3","./Check","./defaultValue","./defined","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o){"use strict";function u(e,t,r){this.longitude=n(e,0),this.latitude=n(t,0),this.height=n(r,0)}u.fromRadians=function(e,t,i,a){return i=n(i,0),r(a)?(a.longitude=e,a.latitude=t,a.height=i,a):new u(e,t,i)},u.fromDegrees=function(e,t,n,r){return e=a.toRadians(e),t=a.toRadians(t),u.fromRadians(e,t,n,r)};var s=new e,c=new e,l=new e,f=new e(1/6378137,1/6378137,1/6356752.314245179),h=new e(1/40680631590769,1/40680631590769,1/40408299984661.445),d=a.EPSILON1;return u.fromCartesian=function(t,n,i){var E=r(n)?n.oneOverRadii:f,m=r(n)?n.oneOverRadiiSquared:h,p=r(n)?n._centerToleranceSquared:d,_=o(t,E,m,p,c);if(r(_)){var y=e.multiplyComponents(_,m,s);y=e.normalize(y,y);var T=e.subtract(t,_,l),R=Math.atan2(y.y,y.x),A=Math.asin(y.z),S=a.sign(e.dot(T,t))*e.magnitude(T);return r(i)?(i.longitude=R,i.latitude=A,i.height=S,i):new u(R,A,S)}},u.toCartesian=function(t,n,r){return e.fromRadians(t.longitude,t.latitude,t.height,n,r)},u.clone=function(e,t){if(r(e))return r(t)?(t.longitude=e.longitude,t.latitude=e.latitude,t.height=e.height,t):new u(e.longitude,e.latitude,e.height)},u.equals=function(e,t){return e===t||r(e)&&r(t)&&e.longitude===t.longitude&&e.latitude===t.latitude&&e.height===t.height},u.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.longitude-t.longitude)<=n&&Math.abs(e.latitude-t.latitude)<=n&&Math.abs(e.height-t.height)<=n},u.ZERO=i(new u(0,0,0)),u.prototype.clone=function(e){return u.clone(this,e)},u.prototype.equals=function(e){return u.equals(this,e)},u.prototype.equalsEpsilon=function(e,t){return u.equalsEpsilon(this,e,t)},u.prototype.toString=function(){return"("+this.longitude+", "+this.latitude+", "+this.height+")"},u}),define("Core/defineProperties",["./defined"],function(e){"use strict";var t=function(){try{return"x"in Object.defineProperty({},"x",{})}catch(e){return!1}}(),n=Object.defineProperties;return t&&e(n)||(n=function(e){return e}),n}),define("Core/Ellipsoid",["./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math","./scaleToGeodeticSurface"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(t,n,i,a){n=r(n,0),i=r(i,0),a=r(a,0),t._radii=new e(n,i,a),t._radiiSquared=new e(n*n,i*i,a*a),t._radiiToTheFourth=new e(n*n*n*n,i*i*i*i,a*a*a*a),t._oneOverRadii=new e(0===n?0:1/n,0===i?0:1/i,0===a?0:1/a),t._oneOverRadiiSquared=new e(0===n?0:1/(n*n),0===i?0:1/(i*i),0===a?0:1/(a*a)),t._minimumRadius=Math.min(n,i,a),t._maximumRadius=Math.max(n,i,a),t._centerToleranceSquared=s.EPSILON1,0!==t._radiiSquared.z&&(t._squaredXOverSquaredZ=t._radiiSquared.x/t._radiiSquared.z)}function f(e,t,n){this._radii=void 0,this._radiiSquared=void 0,this._radiiToTheFourth=void 0,this._oneOverRadii=void 0,this._oneOverRadiiSquared=void 0,this._minimumRadius=void 0,this._maximumRadius=void 0,this._centerToleranceSquared=void 0,this._squaredXOverSquaredZ=void 0,l(this,e,t,n)}a(f.prototype,{radii:{get:function(){return this._radii}},radiiSquared:{get:function(){return this._radiiSquared}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth}},oneOverRadii:{get:function(){return this._oneOverRadii}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared}},minimumRadius:{get:function(){return this._minimumRadius}},maximumRadius:{get:function(){return this._maximumRadius}}}),f.clone=function(t,n){if(i(t)){var r=t._radii;return i(n)?(e.clone(r,n._radii),e.clone(t._radiiSquared,n._radiiSquared),e.clone(t._radiiToTheFourth,n._radiiToTheFourth),e.clone(t._oneOverRadii,n._oneOverRadii),e.clone(t._oneOverRadiiSquared,n._oneOverRadiiSquared),n._minimumRadius=t._minimumRadius,n._maximumRadius=t._maximumRadius,n._centerToleranceSquared=t._centerToleranceSquared,n):new f(r.x,r.y,r.z)}},f.fromCartesian3=function(e,t){return i(t)||(t=new f),i(e)?(l(t,e.x,e.y,e.z),t):t},f.WGS84=u(new f(6378137,6378137,6356752.314245179)),f.UNIT_SPHERE=u(new f(1,1,1)),f.MOON=u(new f(s.LUNAR_RADIUS,s.LUNAR_RADIUS,s.LUNAR_RADIUS)),f.prototype.clone=function(e){return f.clone(this,e)},f.packedLength=e.packedLength,f.pack=function(t,n,i){return i=r(i,0),e.pack(t._radii,n,i),n},f.unpack=function(t,n,i){n=r(n,0);var a=e.unpack(t,n);return f.fromCartesian3(a,i)},f.prototype.geocentricSurfaceNormal=e.normalize,f.prototype.geodeticSurfaceNormalCartographic=function(t,n){var r=t.longitude,a=t.latitude,o=Math.cos(a),u=o*Math.cos(r),s=o*Math.sin(r),c=Math.sin(a);return i(n)||(n=new e),n.x=u,n.y=s,n.z=c,e.normalize(n,n)},f.prototype.geodeticSurfaceNormal=function(t,n){return i(n)||(n=new e),n=e.multiplyComponents(t,this._oneOverRadiiSquared,n),e.normalize(n,n)};var h=new e,d=new e;f.prototype.cartographicToCartesian=function(t,n){var r=h,a=d;this.geodeticSurfaceNormalCartographic(t,r),e.multiplyComponents(this._radiiSquared,r,a);var o=Math.sqrt(e.dot(r,a));return e.divideByScalar(a,o,a),e.multiplyByScalar(r,t.height,r),i(n)||(n=new e),e.add(a,r,n)},f.prototype.cartographicArrayToCartesianArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;r++)t[r]=this.cartographicToCartesian(e[r],t[r]);return t};var E=new e,m=new e,p=new e;return f.prototype.cartesianToCartographic=function(n,r){var a=this.scaleToGeodeticSurface(n,m);if(i(a)){var o=this.geodeticSurfaceNormal(a,E),u=e.subtract(n,a,p),c=Math.atan2(o.y,o.x),l=Math.asin(o.z),f=s.sign(e.dot(u,n))*e.magnitude(u);return i(r)?(r.longitude=c,r.latitude=l,r.height=f,r):new t(c,l,f)}},f.prototype.cartesianArrayToCartographicArray=function(e,t){var n=e.length;i(t)?t.length=n:t=new Array(n);for(var r=0;r<n;++r)t[r]=this.cartesianToCartographic(e[r],t[r]);return t},f.prototype.scaleToGeodeticSurface=function(e,t){return c(e,this._oneOverRadii,this._oneOverRadiiSquared,this._centerToleranceSquared,t)},f.prototype.scaleToGeocentricSurface=function(t,n){i(n)||(n=new e);var r=t.x,a=t.y,o=t.z,u=this._oneOverRadiiSquared,s=1/Math.sqrt(r*r*u.x+a*a*u.y+o*o*u.z);return e.multiplyByScalar(t,s,n)},f.prototype.transformPositionToScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._oneOverRadii,n)},f.prototype.transformPositionFromScaledSpace=function(t,n){return i(n)||(n=new e),e.multiplyComponents(t,this._radii,n)},f.prototype.equals=function(t){return this===t||i(t)&&e.equals(this._radii,t._radii)},f.prototype.toString=function(){return this._radii.toString()},f.prototype.getSurfaceNormalIntersectionWithZAxis=function(t,n,a){n=r(n,0);var o=this._squaredXOverSquaredZ;if(i(a)||(a=new e),a.x=0,a.y=0,a.z=t.z*(1-o),!(Math.abs(a.z)>=this._radii.z-n))return a},f}),define("Core/GeographicProjection",["./Cartesian3","./Cartographic","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid"],function(e,t,n,r,i,a,o){"use strict";function u(e){this._ellipsoid=n(e,o.WGS84),this._semimajorAxis=this._ellipsoid.maximumRadius,this._oneOverSemimajorAxis=1/this._semimajorAxis}return i(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}}}),u.prototype.project=function(t,n){var i=this._semimajorAxis,a=t.longitude*i,o=t.latitude*i,u=t.height;return r(n)?(n.x=a,n.y=o,n.z=u,n):new e(a,o,u)},u.prototype.unproject=function(e,n){var i=this._oneOverSemimajorAxis,a=e.x*i,o=e.y*i,u=e.z;return r(n)?(n.longitude=a,n.latitude=o,n.height=u,n):new t(a,o,u)},u}),define("Core/Intersect",["./freezeObject"],function(e){"use strict";return e({OUTSIDE:-1,INTERSECTING:0,INSIDE:1})}),define("Core/Interval",["./defaultValue"],function(e){"use strict";function t(t,n){this.start=e(t,0),this.stop=e(n,0)}return t}),define("Core/Matrix3",["./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i,a,o,u,s,c){this[0]=n(e,0),this[1]=n(i,0),this[2]=n(u,0),this[3]=n(t,0),this[4]=n(a,0),this[5]=n(s,0),this[6]=n(r,0),this[7]=n(o,0),this[8]=n(c,0)}function c(e){for(var t=0,n=0;n<9;++n){var r=e[n];t+=r*r}return Math.sqrt(t)}function l(e){for(var t=0,n=0;n<3;++n){var r=e[s.getElementIndex(m[n],E[n])];t+=2*r*r}return Math.sqrt(t)}function f(e,t){for(var n=u.EPSILON15,r=0,i=1,a=0;a<3;++a){var o=Math.abs(e[s.getElementIndex(m[a],E[a])]);o>r&&(i=a,r=o)}var c=1,l=0,f=E[i],h=m[i];if(Math.abs(e[s.getElementIndex(h,f)])>n){var d,p=e[s.getElementIndex(h,h)],_=e[s.getElementIndex(f,f)],y=e[s.getElementIndex(h,f)],T=(p-_)/2/y;d=T<0?-1/(-T+Math.sqrt(1+T*T)):1/(T+Math.sqrt(1+T*T)),c=1/Math.sqrt(1+d*d),l=d*c}return t=s.clone(s.IDENTITY,t),t[s.getElementIndex(f,f)]=t[s.getElementIndex(h,h)]=c,t[s.getElementIndex(h,f)]=l,t[s.getElementIndex(f,h)]=-l,t}s.packedLength=9,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e[0],t[r++]=e[1],t[r++]=e[2],t[r++]=e[3],t[r++]=e[4],t[r++]=e[5],t[r++]=e[6],t[r++]=e[7],t[r++]=e[8],t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t++],i[1]=e[t++],i[2]=e[t++],i[3]=e[t++],i[4]=e[t++],i[5]=e[t++],i[6]=e[t++],i[7]=e[t++],i[8]=e[t++],i},s.clone=function(e,t){if(r(e))return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):new s(e[0],e[3],e[6],e[1],e[4],e[7],e[2],e[5],e[8])},s.fromArray=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i[0]=e[t],i[1]=e[t+1],i[2]=e[t+2],i[3]=e[t+3],i[4]=e[t+4],i[5]=e[t+5],i[6]=e[t+6],i[7]=e[t+7],i[8]=e[t+8],i},s.fromColumnMajorArray=function(e,t){return s.clone(e,t)},s.fromRowMajorArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],t):new s(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8])},s.fromQuaternion=function(e,t){var n=e.x*e.x,i=e.x*e.y,a=e.x*e.z,o=e.x*e.w,u=e.y*e.y,c=e.y*e.z,l=e.y*e.w,f=e.z*e.z,h=e.z*e.w,d=e.w*e.w,E=n-u-f+d,m=2*(i-h),p=2*(a+l),_=2*(i+h),y=-n+u-f+d,T=2*(c-o),R=2*(a-l),A=2*(c+o),S=-n-u+f+d;return r(t)?(t[0]=E,t[1]=_,t[2]=R,t[3]=m,t[4]=y,t[5]=A,t[6]=p,t[7]=T,t[8]=S,t):new s(E,m,p,_,y,T,R,A,S)},s.fromHeadingPitchRoll=function(e,t){var n=Math.cos(-e.pitch),i=Math.cos(-e.heading),a=Math.cos(e.roll),o=Math.sin(-e.pitch),u=Math.sin(-e.heading),c=Math.sin(e.roll),l=n*i,f=-a*u+c*o*i,h=c*u+a*o*i,d=n*u,E=a*i+c*o*u,m=-c*i+a*o*u,p=-o,_=c*n,y=a*n;return r(t)?(t[0]=l,t[1]=d,t[2]=p,t[3]=f,t[4]=E,t[5]=_,t[6]=h,t[7]=m,t[8]=y,t):new s(l,f,h,d,E,m,p,_,y)},s.fromScale=function(e,t){return r(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=e.y,t[5]=0,t[6]=0,t[7]=0,t[8]=e.z,t):new s(e.x,0,0,0,e.y,0,0,0,e.z)},s.fromUniformScale=function(e,t){return r(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=e,t[5]=0,t[6]=0,t[7]=0,t[8]=e,t):new s(e,0,0,0,e,0,0,0,e)},s.fromCrossProduct=function(e,t){return r(t)?(t[0]=0,t[1]=e.z,t[2]=-e.y,t[3]=-e.z,t[4]=0,t[5]=e.x,t[6]=e.y,t[7]=-e.x,t[8]=0,t):new s(0,-e.z,e.y,e.z,0,-e.x,-e.y,e.x,0)},s.fromRotationX=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=n,t[5]=i,t[6]=0,t[7]=-i,t[8]=n,t):new s(1,0,0,0,n,-i,0,i,n)},s.fromRotationY=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=0,t[2]=-i,t[3]=0,t[4]=1,t[5]=0,t[6]=i,t[7]=0,t[8]=n,t):new s(n,0,i,0,1,0,-i,0,n)},s.fromRotationZ=function(e,t){var n=Math.cos(e),i=Math.sin(e);return r(t)?(t[0]=n,t[1]=i,t[2]=0,t[3]=-i,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new s(n,-i,0,i,n,0,0,0,1)},s.toArray=function(e,t){return r(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8]]},s.getElementIndex=function(e,t){return 3*e+t},s.getColumn=function(e,t,n){var r=3*t,i=e[r],a=e[r+1],o=e[r+2];return n.x=i,n.y=a,n.z=o,n},s.setColumn=function(e,t,n,r){r=s.clone(e,r);var i=3*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r},s.getRow=function(e,t,n){var r=e[t],i=e[t+3],a=e[t+6];return n.x=r,n.y=i,n.z=a,n},s.setRow=function(e,t,n,r){return r=s.clone(e,r),r[t]=n.x,r[t+3]=n.y,r[t+6]=n.z,r};var h=new e;s.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],h)),n.y=e.magnitude(e.fromElements(t[3],t[4],t[5],h)),n.z=e.magnitude(e.fromElements(t[6],t[7],t[8],h)),n};var d=new e;s.getMaximumScale=function(t){return s.getScale(t,d),e.maximumComponent(d)},s.multiply=function(e,t,n){var r=e[0]*t[0]+e[3]*t[1]+e[6]*t[2],i=e[1]*t[0]+e[4]*t[1]+e[7]*t[2],a=e[2]*t[0]+e[5]*t[1]+e[8]*t[2],o=e[0]*t[3]+e[3]*t[4]+e[6]*t[5],u=e[1]*t[3]+e[4]*t[4]+e[7]*t[5],s=e[2]*t[3]+e[5]*t[4]+e[8]*t[5],c=e[0]*t[6]+e[3]*t[7]+e[6]*t[8],l=e[1]*t[6]+e[4]*t[7]+e[7]*t[8],f=e[2]*t[6]+e[5]*t[7]+e[8]*t[8];return n[0]=r,n[1]=i,n[2]=a,n[3]=o,n[4]=u,n[5]=s,n[6]=c,n[7]=l,n[8]=f,n},s.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n},s.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n},s.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[3]*i+e[6]*a,u=e[1]*r+e[4]*i+e[7]*a,s=e[2]*r+e[5]*i+e[8]*a;return n.x=o,n.y=u,n.z=s,n},s.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n},s.multiplyByScale=function(e,t,n){return n[0]=e[0]*t.x,n[1]=e[1]*t.x,n[2]=e[2]*t.x,n[3]=e[3]*t.y,n[4]=e[4]*t.y,n[5]=e[5]*t.y,n[6]=e[6]*t.z,n[7]=e[7]*t.z,n[8]=e[8]*t.z,n},s.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t},s.transpose=function(e,t){var n=e[0],r=e[3],i=e[6],a=e[1],o=e[4],u=e[7],s=e[2],c=e[5],l=e[8];return t[0]=n,t[1]=r,t[2]=i,t[3]=a,t[4]=o,t[5]=u,t[6]=s,t[7]=c,t[8]=l,t};var E=[1,0,0],m=[2,2,1],p=new s,_=new s;return s.computeEigenDecomposition=function(e,t){var n=u.EPSILON20,i=0,a=0;r(t)||(t={});for(var o=t.unitary=s.clone(s.IDENTITY,t.unitary),h=t.diagonal=s.clone(e,t.diagonal),d=n*c(h);a<10&&l(h)>d;)f(h,p),s.transpose(p,_),s.multiply(h,p,h),s.multiply(_,h,h),s.multiply(o,p,o),++i>2&&(++a,i=0);return t},s.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t},s.determinant=function(e){var t=e[0],n=e[3],r=e[6],i=e[1],a=e[4],o=e[7],u=e[2],s=e[5],c=e[8];return t*(a*c-s*o)+i*(s*r-n*c)+u*(n*o-a*r)},s.inverse=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],u=e[5],c=e[6],l=e[7],f=e[8],h=s.determinant(e);t[0]=o*f-l*u,t[1]=l*i-r*f,t[2]=r*u-o*i,t[3]=c*u-a*f,t[4]=n*f-c*i,t[5]=a*i-n*u,t[6]=a*l-c*o,t[7]=c*r-n*l,t[8]=n*o-a*r;var d=1/h;return s.multiplyByScalar(t,d,t)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},s.equalsEpsilon=function(e,t,n){ +return e===t||r(e)&&r(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n},s.IDENTITY=o(new s(1,0,0,0,1,0,0,0,1)),s.ZERO=o(new s(0,0,0,0,0,0,0,0,0)),s.COLUMN0ROW0=0,s.COLUMN0ROW1=1,s.COLUMN0ROW2=2,s.COLUMN1ROW0=3,s.COLUMN1ROW1=4,s.COLUMN1ROW2=5,s.COLUMN2ROW0=6,s.COLUMN2ROW1=7,s.COLUMN2ROW2=8,i(s.prototype,{length:{get:function(){return s.packedLength}}}),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this[0]+", "+this[3]+", "+this[6]+")\n("+this[1]+", "+this[4]+", "+this[7]+")\n("+this[2]+", "+this[5]+", "+this[8]+")"},s}),define("Core/Cartesian4",["./Check","./defaultValue","./defined","./DeveloperError","./freezeObject","./Math"],function(e,t,n,r,i,a){"use strict";function o(e,n,r,i){this.x=t(e,0),this.y=t(n,0),this.z=t(r,0),this.w=t(i,0)}o.fromElements=function(e,t,r,i,a){return n(a)?(a.x=e,a.y=t,a.z=r,a.w=i,a):new o(e,t,r,i)},o.fromColor=function(e,t){return n(t)?(t.x=e.red,t.y=e.green,t.z=e.blue,t.w=e.alpha,t):new o(e.red,e.green,e.blue,e.alpha)},o.clone=function(e,t){if(n(e))return n(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new o(e.x,e.y,e.z,e.w)},o.packedLength=4,o.pack=function(e,n,r){return r=t(r,0),n[r++]=e.x,n[r++]=e.y,n[r++]=e.z,n[r]=e.w,n},o.unpack=function(e,r,i){return r=t(r,0),n(i)||(i=new o),i.x=e[r++],i.y=e[r++],i.z=e[r++],i.w=e[r],i},o.packArray=function(e,t){var r=e.length;n(t)?t.length=4*r:t=new Array(4*r);for(var i=0;i<r;++i)o.pack(e[i],t,4*i);return t},o.unpackArray=function(e,t){var r=e.length;n(t)?t.length=r/4:t=new Array(r/4);for(var i=0;i<r;i+=4){var a=i/4;t[a]=o.unpack(e,i,t[a])}return t},o.fromArray=o.unpack,o.maximumComponent=function(e){return Math.max(e.x,e.y,e.z,e.w)},o.minimumComponent=function(e){return Math.min(e.x,e.y,e.z,e.w)},o.minimumByComponent=function(e,t,n){return n.x=Math.min(e.x,t.x),n.y=Math.min(e.y,t.y),n.z=Math.min(e.z,t.z),n.w=Math.min(e.w,t.w),n},o.maximumByComponent=function(e,t,n){return n.x=Math.max(e.x,t.x),n.y=Math.max(e.y,t.y),n.z=Math.max(e.z,t.z),n.w=Math.max(e.w,t.w),n},o.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},o.magnitude=function(e){return Math.sqrt(o.magnitudeSquared(e))};var u=new o;o.distance=function(e,t){return o.subtract(e,t,u),o.magnitude(u)},o.distanceSquared=function(e,t){return o.subtract(e,t,u),o.magnitudeSquared(u)},o.normalize=function(e,t){var n=o.magnitude(e);return t.x=e.x/n,t.y=e.y/n,t.z=e.z/n,t.w=e.w/n,t},o.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},o.multiplyComponents=function(e,t,n){return n.x=e.x*t.x,n.y=e.y*t.y,n.z=e.z*t.z,n.w=e.w*t.w,n},o.divideComponents=function(e,t,n){return n.x=e.x/t.x,n.y=e.y/t.y,n.z=e.z/t.z,n.w=e.w/t.w,n},o.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},o.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},o.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},o.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},o.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},o.abs=function(e,t){return t.x=Math.abs(e.x),t.y=Math.abs(e.y),t.z=Math.abs(e.z),t.w=Math.abs(e.w),t};var s=new o;o.lerp=function(e,t,n,r){return o.multiplyByScalar(t,n,s),r=o.multiplyByScalar(e,1-n,r),o.add(s,r,r)};var c=new o;return o.mostOrthogonalAxis=function(e,t){var n=o.normalize(e,c);return o.abs(n,n),t=n.x<=n.y?n.x<=n.z?n.x<=n.w?o.clone(o.UNIT_X,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t):n.y<=n.z?n.y<=n.w?o.clone(o.UNIT_Y,t):o.clone(o.UNIT_W,t):n.z<=n.w?o.clone(o.UNIT_Z,t):o.clone(o.UNIT_W,t)},o.equals=function(e,t){return e===t||n(e)&&n(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},o.equalsArray=function(e,t,n){return e.x===t[n]&&e.y===t[n+1]&&e.z===t[n+2]&&e.w===t[n+3]},o.equalsEpsilon=function(e,t,r,i){return e===t||n(e)&&n(t)&&a.equalsEpsilon(e.x,t.x,r,i)&&a.equalsEpsilon(e.y,t.y,r,i)&&a.equalsEpsilon(e.z,t.z,r,i)&&a.equalsEpsilon(e.w,t.w,r,i)},o.ZERO=i(new o(0,0,0,0)),o.UNIT_X=i(new o(1,0,0,0)),o.UNIT_Y=i(new o(0,1,0,0)),o.UNIT_Z=i(new o(0,0,1,0)),o.UNIT_W=i(new o(0,0,0,1)),o.prototype.clone=function(e){return o.clone(this,e)},o.prototype.equals=function(e){return o.equals(this,e)},o.prototype.equalsEpsilon=function(e,t,n){return o.equalsEpsilon(this,e,t,n)},o.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},o}),define("Core/RuntimeError",["./defined"],function(e){"use strict";function t(e){this.name="RuntimeError",this.message=e;var t;try{throw new Error}catch(e){t=e.stack}this.stack=t}return e(Object.create)&&(t.prototype=Object.create(Error.prototype),t.prototype.constructor=t),t.prototype.toString=function(){var t=this.name+": "+this.message;return e(this.stack)&&(t+="\n"+this.stack.toString()),t},t}),define("Core/Matrix4",["./Cartesian3","./Cartesian4","./Check","./defaultValue","./defined","./defineProperties","./freezeObject","./Math","./Matrix3","./RuntimeError"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t,n,i,a,o,u,s,c,l,f,h,d,E,m,p){this[0]=r(e,0),this[1]=r(a,0),this[2]=r(c,0),this[3]=r(d,0),this[4]=r(t,0),this[5]=r(o,0),this[6]=r(l,0),this[7]=r(E,0),this[8]=r(n,0),this[9]=r(u,0),this[10]=r(f,0),this[11]=r(m,0),this[12]=r(i,0),this[13]=r(s,0),this[14]=r(h,0),this[15]=r(p,0)}l.packedLength=16,l.pack=function(e,t,n){return n=r(n,0),t[n++]=e[0],t[n++]=e[1],t[n++]=e[2],t[n++]=e[3],t[n++]=e[4],t[n++]=e[5],t[n++]=e[6],t[n++]=e[7],t[n++]=e[8],t[n++]=e[9],t[n++]=e[10],t[n++]=e[11],t[n++]=e[12],t[n++]=e[13],t[n++]=e[14],t[n]=e[15],t},l.unpack=function(e,t,n){return t=r(t,0),i(n)||(n=new l),n[0]=e[t++],n[1]=e[t++],n[2]=e[t++],n[3]=e[t++],n[4]=e[t++],n[5]=e[t++],n[6]=e[t++],n[7]=e[t++],n[8]=e[t++],n[9]=e[t++],n[10]=e[t++],n[11]=e[t++],n[12]=e[t++],n[13]=e[t++],n[14]=e[t++],n[15]=e[t],n},l.clone=function(e,t){if(i(e))return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):new l(e[0],e[4],e[8],e[12],e[1],e[5],e[9],e[13],e[2],e[6],e[10],e[14],e[3],e[7],e[11],e[15])},l.fromArray=l.unpack,l.fromColumnMajorArray=function(e,t){return l.clone(e,t)},l.fromRowMajorArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t):new l(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])},l.fromRotationTranslation=function(t,n,a){return n=r(n,e.ZERO),i(a)?(a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=0,a[4]=t[3],a[5]=t[4],a[6]=t[5],a[7]=0,a[8]=t[6],a[9]=t[7],a[10]=t[8],a[11]=0,a[12]=n.x,a[13]=n.y,a[14]=n.z,a[15]=1,a):new l(t[0],t[3],t[6],n.x,t[1],t[4],t[7],n.y,t[2],t[5],t[8],n.z,0,0,0,1)},l.fromTranslationQuaternionRotationScale=function(e,t,n,r){i(r)||(r=new l);var a=n.x,o=n.y,u=n.z,s=t.x*t.x,c=t.x*t.y,f=t.x*t.z,h=t.x*t.w,d=t.y*t.y,E=t.y*t.z,m=t.y*t.w,p=t.z*t.z,_=t.z*t.w,y=t.w*t.w,T=s-d-p+y,R=2*(c-_),A=2*(f+m),S=2*(c+_),v=-s+d-p+y,g=2*(E-h),N=2*(f-m),I=2*(E+h),O=-s-d+p+y;return r[0]=T*a,r[1]=S*a,r[2]=N*a,r[3]=0,r[4]=R*o,r[5]=v*o,r[6]=I*o,r[7]=0,r[8]=A*u,r[9]=g*u,r[10]=O*u,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,r},l.fromTranslationRotationScale=function(e,t){return l.fromTranslationQuaternionRotationScale(e.translation,e.rotation,e.scale,t)},l.fromTranslation=function(e,t){return l.fromRotationTranslation(s.IDENTITY,e,t)},l.fromScale=function(e,t){return i(t)?(t[0]=e.x,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e.y,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e.z,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1)},l.fromUniformScale=function(e,t){return i(t)?(t[0]=e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t):new l(e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1)};var f=new e,h=new e,d=new e;l.fromCamera=function(t,n){var r=t.position,a=t.direction,o=t.up;e.normalize(a,f),e.normalize(e.cross(f,o,h),h),e.normalize(e.cross(h,f,d),d);var u=h.x,s=h.y,c=h.z,E=f.x,m=f.y,p=f.z,_=d.x,y=d.y,T=d.z,R=r.x,A=r.y,S=r.z,v=u*-R+s*-A+c*-S,g=_*-R+y*-A+T*-S,N=E*R+m*A+p*S;return i(n)?(n[0]=u,n[1]=_,n[2]=-E,n[3]=0,n[4]=s,n[5]=y,n[6]=-m,n[7]=0,n[8]=c,n[9]=T,n[10]=-p,n[11]=0,n[12]=v,n[13]=g,n[14]=N,n[15]=1,n):new l(u,s,c,v,_,y,T,g,-E,-m,-p,N,0,0,0,1)},l.computePerspectiveFieldOfView=function(e,t,n,r,i){var a=Math.tan(.5*e),o=1/a,u=o/t,s=(r+n)/(n-r),c=2*r*n/(n-r);return i[0]=u,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=s,i[11]=-1,i[12]=0,i[13]=0,i[14]=c,i[15]=0,i},l.computeOrthographicOffCenter=function(e,t,n,r,i,a,o){var u=1/(t-e),s=1/(r-n),c=1/(a-i),l=-(t+e)*u,f=-(r+n)*s,h=-(a+i)*c;return u*=2,s*=2,c*=-2,o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=c,o[11]=0,o[12]=l,o[13]=f,o[14]=h,o[15]=1,o},l.computePerspectiveOffCenter=function(e,t,n,r,i,a,o){var u=2*i/(t-e),s=2*i/(r-n),c=(t+e)/(t-e),l=(r+n)/(r-n),f=-(a+i)/(a-i),h=-2*a*i/(a-i);return o[0]=u,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=s,o[6]=0,o[7]=0,o[8]=c,o[9]=l,o[10]=f,o[11]=-1,o[12]=0,o[13]=0,o[14]=h,o[15]=0,o},l.computeInfinitePerspectiveOffCenter=function(e,t,n,r,i,a){var o=2*i/(t-e),u=2*i/(r-n),s=(t+e)/(t-e),c=(r+n)/(r-n),l=-2*i;return a[0]=o,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=u,a[6]=0,a[7]=0,a[8]=s,a[9]=c,a[10]=-1,a[11]=-1,a[12]=0,a[13]=0,a[14]=l,a[15]=0,a},l.computeViewportTransformation=function(e,t,n,i){e=r(e,r.EMPTY_OBJECT);var a=r(e.x,0),o=r(e.y,0),u=r(e.width,0),s=r(e.height,0);t=r(t,0),n=r(n,1);var c=.5*u,l=.5*s,f=.5*(n-t),h=c,d=l,E=f,m=a+c,p=o+l,_=t+f;return i[0]=h,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=d,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=E,i[11]=0,i[12]=m,i[13]=p,i[14]=_,i[15]=1,i},l.computeView=function(t,n,r,i,a){return a[0]=i.x,a[1]=r.x,a[2]=-n.x,a[3]=0,a[4]=i.y,a[5]=r.y,a[6]=-n.y,a[7]=0,a[8]=i.z,a[9]=r.z,a[10]=-n.z,a[11]=0,a[12]=-e.dot(i,t),a[13]=-e.dot(r,t),a[14]=e.dot(n,t),a[15]=1,a},l.toArray=function(e,t){return i(t)?(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t):[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]]},l.getElementIndex=function(e,t){return 4*e+t},l.getColumn=function(e,t,n){var r=4*t,i=e[r],a=e[r+1],o=e[r+2],u=e[r+3];return n.x=i,n.y=a,n.z=o,n.w=u,n},l.setColumn=function(e,t,n,r){r=l.clone(e,r);var i=4*t;return r[i]=n.x,r[i+1]=n.y,r[i+2]=n.z,r[i+3]=n.w,r},l.setTranslation=function(e,t,n){return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=t.x,n[13]=t.y,n[14]=t.z,n[15]=e[15],n},l.getRow=function(e,t,n){var r=e[t],i=e[t+4],a=e[t+8],o=e[t+12];return n.x=r,n.y=i,n.z=a,n.w=o,n},l.setRow=function(e,t,n,r){return r=l.clone(e,r),r[t]=n.x,r[t+4]=n.y,r[t+8]=n.z,r[t+12]=n.w,r};var E=new e;l.getScale=function(t,n){return n.x=e.magnitude(e.fromElements(t[0],t[1],t[2],E)),n.y=e.magnitude(e.fromElements(t[4],t[5],t[6],E)),n.z=e.magnitude(e.fromElements(t[8],t[9],t[10],E)),n};var m=new e;l.getMaximumScale=function(t){return l.getScale(t,m),e.maximumComponent(m)},l.multiply=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[3],u=e[4],s=e[5],c=e[6],l=e[7],f=e[8],h=e[9],d=e[10],E=e[11],m=e[12],p=e[13],_=e[14],y=e[15],T=t[0],R=t[1],A=t[2],S=t[3],v=t[4],g=t[5],N=t[6],I=t[7],O=t[8],M=t[9],w=t[10],C=t[11],x=t[12],P=t[13],U=t[14],D=t[15],L=r*T+u*R+f*A+m*S,F=i*T+s*R+h*A+p*S,B=a*T+c*R+d*A+_*S,b=o*T+l*R+E*A+y*S,z=r*v+u*g+f*N+m*I,q=i*v+s*g+h*N+p*I,G=a*v+c*g+d*N+_*I,V=o*v+l*g+E*N+y*I,X=r*O+u*M+f*w+m*C,W=i*O+s*M+h*w+p*C,H=a*O+c*M+d*w+_*C,Y=o*O+l*M+E*w+y*C,k=r*x+u*P+f*U+m*D,j=i*x+s*P+h*U+p*D,Z=a*x+c*P+d*U+_*D,K=o*x+l*P+E*U+y*D;return n[0]=L,n[1]=F,n[2]=B,n[3]=b,n[4]=z,n[5]=q,n[6]=G,n[7]=V,n[8]=X,n[9]=W,n[10]=H,n[11]=Y,n[12]=k,n[13]=j,n[14]=Z,n[15]=K,n},l.add=function(e,t,n){return n[0]=e[0]+t[0],n[1]=e[1]+t[1],n[2]=e[2]+t[2],n[3]=e[3]+t[3],n[4]=e[4]+t[4],n[5]=e[5]+t[5],n[6]=e[6]+t[6],n[7]=e[7]+t[7],n[8]=e[8]+t[8],n[9]=e[9]+t[9],n[10]=e[10]+t[10],n[11]=e[11]+t[11],n[12]=e[12]+t[12],n[13]=e[13]+t[13],n[14]=e[14]+t[14],n[15]=e[15]+t[15],n},l.subtract=function(e,t,n){return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],n[3]=e[3]-t[3],n[4]=e[4]-t[4],n[5]=e[5]-t[5],n[6]=e[6]-t[6],n[7]=e[7]-t[7],n[8]=e[8]-t[8],n[9]=e[9]-t[9],n[10]=e[10]-t[10],n[11]=e[11]-t[11],n[12]=e[12]-t[12],n[13]=e[13]-t[13],n[14]=e[14]-t[14],n[15]=e[15]-t[15],n},l.multiplyTransformation=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=e[12],d=e[13],E=e[14],m=t[0],p=t[1],_=t[2],y=t[4],T=t[5],R=t[6],A=t[8],S=t[9],v=t[10],g=t[12],N=t[13],I=t[14],O=r*m+o*p+c*_,M=i*m+u*p+l*_,w=a*m+s*p+f*_,C=r*y+o*T+c*R,x=i*y+u*T+l*R,P=a*y+s*T+f*R,U=r*A+o*S+c*v,D=i*A+u*S+l*v,L=a*A+s*S+f*v,F=r*g+o*N+c*I+h,B=i*g+u*N+l*I+d,b=a*g+s*N+f*I+E;return n[0]=O,n[1]=M,n[2]=w,n[3]=0,n[4]=C,n[5]=x,n[6]=P,n[7]=0,n[8]=U,n[9]=D,n[10]=L,n[11]=0,n[12]=F,n[13]=B,n[14]=b,n[15]=1,n},l.multiplyByMatrix3=function(e,t,n){var r=e[0],i=e[1],a=e[2],o=e[4],u=e[5],s=e[6],c=e[8],l=e[9],f=e[10],h=t[0],d=t[1],E=t[2],m=t[3],p=t[4],_=t[5],y=t[6],T=t[7],R=t[8],A=r*h+o*d+c*E,S=i*h+u*d+l*E,v=a*h+s*d+f*E,g=r*m+o*p+c*_,N=i*m+u*p+l*_,I=a*m+s*p+f*_,O=r*y+o*T+c*R,M=i*y+u*T+l*R,w=a*y+s*T+f*R;return n[0]=A,n[1]=S,n[2]=v,n[3]=0,n[4]=g,n[5]=N,n[6]=I,n[7]=0,n[8]=O,n[9]=M,n[10]=w,n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=e[15],n},l.multiplyByTranslation=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=r*e[0]+i*e[4]+a*e[8]+e[12],u=r*e[1]+i*e[5]+a*e[9]+e[13],s=r*e[2]+i*e[6]+a*e[10]+e[14];return n[0]=e[0],n[1]=e[1],n[2]=e[2],n[3]=e[3],n[4]=e[4],n[5]=e[5],n[6]=e[6],n[7]=e[7],n[8]=e[8],n[9]=e[9],n[10]=e[10],n[11]=e[11],n[12]=o,n[13]=u,n[14]=s,n[15]=e[15],n};var p=new e;l.multiplyByUniformScale=function(e,t,n){return p.x=t,p.y=t,p.z=t,l.multiplyByScale(e,p,n)},l.multiplyByScale=function(e,t,n){var r=t.x,i=t.y,a=t.z;return 1===r&&1===i&&1===a?l.clone(e,n):(n[0]=r*e[0],n[1]=r*e[1],n[2]=r*e[2],n[3]=0,n[4]=i*e[4],n[5]=i*e[5],n[6]=i*e[6],n[7]=0,n[8]=a*e[8],n[9]=a*e[9],n[10]=a*e[10],n[11]=0,n[12]=e[12],n[13]=e[13],n[14]=e[14],n[15]=1,n)},l.multiplyByVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=t.w,u=e[0]*r+e[4]*i+e[8]*a+e[12]*o,s=e[1]*r+e[5]*i+e[9]*a+e[13]*o,c=e[2]*r+e[6]*i+e[10]*a+e[14]*o,l=e[3]*r+e[7]*i+e[11]*a+e[15]*o;return n.x=u,n.y=s,n.z=c,n.w=l,n},l.multiplyByPointAsVector=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a,u=e[1]*r+e[5]*i+e[9]*a,s=e[2]*r+e[6]*i+e[10]*a;return n.x=o,n.y=u,n.z=s,n},l.multiplyByPoint=function(e,t,n){var r=t.x,i=t.y,a=t.z,o=e[0]*r+e[4]*i+e[8]*a+e[12],u=e[1]*r+e[5]*i+e[9]*a+e[13],s=e[2]*r+e[6]*i+e[10]*a+e[14];return n.x=o,n.y=u,n.z=s,n},l.multiplyByScalar=function(e,t,n){return n[0]=e[0]*t,n[1]=e[1]*t,n[2]=e[2]*t,n[3]=e[3]*t,n[4]=e[4]*t,n[5]=e[5]*t,n[6]=e[6]*t,n[7]=e[7]*t,n[8]=e[8]*t,n[9]=e[9]*t,n[10]=e[10]*t,n[11]=e[11]*t,n[12]=e[12]*t,n[13]=e[13]*t,n[14]=e[14]*t,n[15]=e[15]*t,n},l.negate=function(e,t){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},l.transpose=function(e,t){var n=e[1],r=e[2],i=e[3],a=e[6],o=e[7],u=e[11];return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=n,t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=a,t[10]=e[10],t[11]=e[14],t[12]=i,t[13]=o,t[14]=u,t[15]=e[15],t},l.abs=function(e,t){return t[0]=Math.abs(e[0]),t[1]=Math.abs(e[1]),t[2]=Math.abs(e[2]),t[3]=Math.abs(e[3]),t[4]=Math.abs(e[4]),t[5]=Math.abs(e[5]),t[6]=Math.abs(e[6]),t[7]=Math.abs(e[7]),t[8]=Math.abs(e[8]),t[9]=Math.abs(e[9]),t[10]=Math.abs(e[10]),t[11]=Math.abs(e[11]),t[12]=Math.abs(e[12]),t[13]=Math.abs(e[13]),t[14]=Math.abs(e[14]),t[15]=Math.abs(e[15]),t},l.equals=function(e,t){return e===t||i(e)&&i(t)&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[3]===t[3]&&e[7]===t[7]&&e[11]===t[11]&&e[15]===t[15]},l.equalsEpsilon=function(e,t,n){return e===t||i(e)&&i(t)&&Math.abs(e[0]-t[0])<=n&&Math.abs(e[1]-t[1])<=n&&Math.abs(e[2]-t[2])<=n&&Math.abs(e[3]-t[3])<=n&&Math.abs(e[4]-t[4])<=n&&Math.abs(e[5]-t[5])<=n&&Math.abs(e[6]-t[6])<=n&&Math.abs(e[7]-t[7])<=n&&Math.abs(e[8]-t[8])<=n&&Math.abs(e[9]-t[9])<=n&&Math.abs(e[10]-t[10])<=n&&Math.abs(e[11]-t[11])<=n&&Math.abs(e[12]-t[12])<=n&&Math.abs(e[13]-t[13])<=n&&Math.abs(e[14]-t[14])<=n&&Math.abs(e[15]-t[15])<=n},l.getTranslation=function(e,t){return t.x=e[12],t.y=e[13],t.z=e[14],t},l.getRotation=function(e,t){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t};var _=new s,y=new s,T=new t,R=new t(0,0,0,1);return l.inverse=function(e,n){if(s.equalsEpsilon(l.getRotation(e,_),y,u.EPSILON7)&&t.equals(l.getRow(e,3,T),R))return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=0,n[11]=0,n[12]=-e[12],n[13]=-e[13],n[14]=-e[14],n[15]=1,n;var r=e[0],i=e[4],a=e[8],o=e[12],f=e[1],h=e[5],d=e[9],E=e[13],m=e[2],p=e[6],A=e[10],S=e[14],v=e[3],g=e[7],N=e[11],I=e[15],O=A*I,M=S*N,w=p*I,C=S*g,x=p*N,P=A*g,U=m*I,D=S*v,L=m*N,F=A*v,B=m*g,b=p*v,z=O*h+C*d+x*E-(M*h+w*d+P*E),q=M*f+U*d+F*E-(O*f+D*d+L*E),G=w*f+D*h+B*E-(C*f+U*h+b*E),V=P*f+L*h+b*d-(x*f+F*h+B*d),X=M*i+w*a+P*o-(O*i+C*a+x*o),W=O*r+D*a+L*o-(M*r+U*a+F*o),H=C*r+U*i+b*o-(w*r+D*i+B*o),Y=x*r+F*i+B*a-(P*r+L*i+b*a);O=a*E,M=o*d,w=i*E,C=o*h,x=i*d,P=a*h,U=r*E,D=o*f,L=r*d,F=a*f,B=r*h,b=i*f;var k=O*g+C*N+x*I-(M*g+w*N+P*I),j=M*v+U*N+F*I-(O*v+D*N+L*I),Z=w*v+D*g+B*I-(C*v+U*g+b*I),K=P*v+L*g+b*N-(x*v+F*g+B*N),J=w*A+P*S+M*p-(x*S+O*p+C*A),Q=L*S+O*m+D*A-(U*A+F*S+M*m),$=U*p+b*S+C*m-(B*S+w*m+D*p),ee=B*A+x*m+F*p-(L*p+b*A+P*m),te=r*z+i*q+a*G+o*V;if(Math.abs(te)<u.EPSILON20)throw new c("matrix is not invertible because its determinate is zero.");return te=1/te,n[0]=z*te,n[1]=q*te,n[2]=G*te,n[3]=V*te,n[4]=X*te,n[5]=W*te,n[6]=H*te,n[7]=Y*te,n[8]=k*te,n[9]=j*te,n[10]=Z*te,n[11]=K*te,n[12]=J*te,n[13]=Q*te,n[14]=$*te,n[15]=ee*te,n},l.inverseTransformation=function(e,t){var n=e[0],r=e[1],i=e[2],a=e[4],o=e[5],u=e[6],s=e[8],c=e[9],l=e[10],f=e[12],h=e[13],d=e[14],E=-n*f-r*h-i*d,m=-a*f-o*h-u*d,p=-s*f-c*h-l*d;return t[0]=n,t[1]=a,t[2]=s,t[3]=0,t[4]=r,t[5]=o,t[6]=c,t[7]=0,t[8]=i,t[9]=u,t[10]=l,t[11]=0,t[12]=E,t[13]=m,t[14]=p,t[15]=1,t},l.IDENTITY=o(new l(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)),l.ZERO=o(new l(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)),l.COLUMN0ROW0=0,l.COLUMN0ROW1=1,l.COLUMN0ROW2=2,l.COLUMN0ROW3=3,l.COLUMN1ROW0=4,l.COLUMN1ROW1=5,l.COLUMN1ROW2=6,l.COLUMN1ROW3=7,l.COLUMN2ROW0=8,l.COLUMN2ROW1=9,l.COLUMN2ROW2=10,l.COLUMN2ROW3=11,l.COLUMN3ROW0=12,l.COLUMN3ROW1=13,l.COLUMN3ROW2=14,l.COLUMN3ROW3=15,a(l.prototype,{length:{get:function(){return l.packedLength}}}),l.prototype.clone=function(e){return l.clone(this,e)},l.prototype.equals=function(e){return l.equals(this,e)},l.equalsArray=function(e,t,n){return e[0]===t[n]&&e[1]===t[n+1]&&e[2]===t[n+2]&&e[3]===t[n+3]&&e[4]===t[n+4]&&e[5]===t[n+5]&&e[6]===t[n+6]&&e[7]===t[n+7]&&e[8]===t[n+8]&&e[9]===t[n+9]&&e[10]===t[n+10]&&e[11]===t[n+11]&&e[12]===t[n+12]&&e[13]===t[n+13]&&e[14]===t[n+14]&&e[15]===t[n+15]},l.prototype.equalsEpsilon=function(e,t){return l.equalsEpsilon(this,e,t)},l.prototype.toString=function(){return"("+this[0]+", "+this[4]+", "+this[8]+", "+this[12]+")\n("+this[1]+", "+this[5]+", "+this[9]+", "+this[13]+")\n("+this[2]+", "+this[6]+", "+this[10]+", "+this[14]+")\n("+this[3]+", "+this[7]+", "+this[11]+", "+this[15]+")"},l}),define("Core/Rectangle",["./Cartographic","./Check","./defaultValue","./defined","./defineProperties","./Ellipsoid","./freezeObject","./Math"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.west=n(e,0),this.south=n(t,0),this.east=n(r,0),this.north=n(i,0)}i(s.prototype,{width:{get:function(){return s.computeWidth(this)}},height:{get:function(){return s.computeHeight(this)}}}),s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.west,t[r++]=e.south,t[r++]=e.east,t[r]=e.north,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.west=e[t++],i.south=e[t++],i.east=e[t++],i.north=e[t],i},s.computeWidth=function(e){var t=e.east,n=e.west;return t<n&&(t+=u.TWO_PI),t-n},s.computeHeight=function(e){return e.north-e.south},s.fromDegrees=function(e,t,i,a,o){return e=u.toRadians(n(e,0)),t=u.toRadians(n(t,0)),i=u.toRadians(n(i,0)),a=u.toRadians(n(a,0)),r(o)?(o.west=e,o.south=t,o.east=i,o.north=a,o):new s(e,t,i,a)},s.fromRadians=function(e,t,i,a,o){return r(o)?(o.west=n(e,0),o.south=n(t,0),o.east=n(i,0),o.north=n(a,0),o):new s(e,t,i,a)},s.fromCartographicArray=function(e,t){for(var n=Number.MAX_VALUE,i=-Number.MAX_VALUE,a=Number.MAX_VALUE,o=-Number.MAX_VALUE,c=Number.MAX_VALUE,l=-Number.MAX_VALUE,f=0,h=e.length;f<h;f++){var d=e[f];n=Math.min(n,d.longitude),i=Math.max(i,d.longitude),c=Math.min(c,d.latitude),l=Math.max(l,d.latitude);var E=d.longitude>=0?d.longitude:d.longitude+u.TWO_PI;a=Math.min(a,E),o=Math.max(o,E)}return i-n>o-a&&(n=a,i=o,i>u.PI&&(i-=u.TWO_PI),n>u.PI&&(n-=u.TWO_PI)),r(t)?(t.west=n,t.south=c,t.east=i,t.north=l,t):new s(n,c,i,l)},s.fromCartesianArray=function(e,t,i){t=n(t,a.WGS84);for(var o=Number.MAX_VALUE,c=-Number.MAX_VALUE,l=Number.MAX_VALUE,f=-Number.MAX_VALUE,h=Number.MAX_VALUE,d=-Number.MAX_VALUE,E=0,m=e.length;E<m;E++){var p=t.cartesianToCartographic(e[E]);o=Math.min(o,p.longitude),c=Math.max(c,p.longitude),h=Math.min(h,p.latitude),d=Math.max(d,p.latitude);var _=p.longitude>=0?p.longitude:p.longitude+u.TWO_PI;l=Math.min(l,_),f=Math.max(f,_)}return c-o>f-l&&(o=l,c=f,c>u.PI&&(c-=u.TWO_PI),o>u.PI&&(o-=u.TWO_PI)),r(i)?(i.west=o,i.south=h,i.east=c,i.north=d,i):new s(o,h,c,d)},s.clone=function(e,t){if(r(e))return r(t)?(t.west=e.west,t.south=e.south,t.east=e.east,t.north=e.north,t):new s(e.west,e.south,e.east,e.north)},s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.west===t.west&&e.south===t.south&&e.east===t.east&&e.north===t.north},s.prototype.equalsEpsilon=function(e,t){return r(e)&&Math.abs(this.west-e.west)<=t&&Math.abs(this.south-e.south)<=t&&Math.abs(this.east-e.east)<=t&&Math.abs(this.north-e.north)<=t},s.validate=function(e){},s.southwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.south,n.height=0,n):new e(t.west,t.south)},s.northwest=function(t,n){return r(n)?(n.longitude=t.west,n.latitude=t.north,n.height=0,n):new e(t.west,t.north)},s.northeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.north,n.height=0,n):new e(t.east,t.north)},s.southeast=function(t,n){return r(n)?(n.longitude=t.east,n.latitude=t.south,n.height=0,n):new e(t.east,t.south)},s.center=function(t,n){var i=t.east,a=t.west;i<a&&(i+=u.TWO_PI);var o=u.negativePiToPi(.5*(a+i)),s=.5*(t.south+t.north);return r(n)?(n.longitude=o,n.latitude=s,n.height=0,n):new e(o,s)},s.intersection=function(e,t,n){var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.negativePiToPi(Math.max(a,c)),f=u.negativePiToPi(Math.min(i,o));if(!((e.west<e.east||t.west<t.east)&&f<=l)){var h=Math.max(e.south,t.south),d=Math.min(e.north,t.north);if(!(h>=d))return r(n)?(n.west=l,n.south=h,n.east=f,n.north=d,n):new s(l,h,f,d)}},s.simpleIntersection=function(e,t,n){var i=Math.max(e.west,t.west),a=Math.max(e.south,t.south),o=Math.min(e.east,t.east),u=Math.min(e.north,t.north);if(!(a>=u||i>=o))return r(n)?(n.west=i,n.south=a,n.east=o,n.north=u,n):new s(i,a,o,u)},s.union=function(e,t,n){r(n)||(n=new s);var i=e.east,a=e.west,o=t.east,c=t.west;i<a&&o>0?i+=u.TWO_PI:o<c&&i>0&&(o+=u.TWO_PI),i<a&&c<0?c+=u.TWO_PI:o<c&&a<0&&(a+=u.TWO_PI);var l=u.convertLongitudeRange(Math.min(a,c)),f=u.convertLongitudeRange(Math.max(i,o));return n.west=l,n.south=Math.min(e.south,t.south),n.east=f,n.north=Math.max(e.north,t.north),n},s.expand=function(e,t,n){return r(n)||(n=new s),n.west=Math.min(e.west,t.longitude),n.south=Math.min(e.south,t.latitude),n.east=Math.max(e.east,t.longitude),n.north=Math.max(e.north,t.latitude),n},s.contains=function(e,t){var n=t.longitude,r=t.latitude,i=e.west,a=e.east;return a<i&&(a+=u.TWO_PI,n<0&&(n+=u.TWO_PI)),(n>i||u.equalsEpsilon(n,i,u.EPSILON14))&&(n<a||u.equalsEpsilon(n,a,u.EPSILON14))&&r>=e.south&&r<=e.north};var c=new e;return s.subsample=function(e,t,i,o){t=n(t,a.WGS84),i=n(i,0),r(o)||(o=[]);var l=0,f=e.north,h=e.south,d=e.east,E=e.west,m=c;m.height=i,m.longitude=E,m.latitude=f,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=h,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.latitude=f<0?f:h>0?h:0;for(var p=1;p<8;++p)m.longitude=-Math.PI+p*u.PI_OVER_TWO,s.contains(e,m)&&(o[l]=t.cartographicToCartesian(m,o[l]),l++);return 0===m.latitude&&(m.longitude=E,o[l]=t.cartographicToCartesian(m,o[l]),l++,m.longitude=d,o[l]=t.cartographicToCartesian(m,o[l]),l++),o.length=l,o},s.MAX_VALUE=o(new s(-Math.PI,-u.PI_OVER_TWO,Math.PI,u.PI_OVER_TWO)),s}),define("Core/BoundingSphere",["./Cartesian3","./Cartographic","./Math","./Check","./defaultValue","./defined","./Ellipsoid","./GeographicProjection","./Intersect","./Interval","./Matrix3","./Matrix4","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h){"use strict";function d(t,n){this.center=e.clone(i(t,e.ZERO)),this.radius=i(n,0)}var E=new e,m=new e,p=new e,_=new e,y=new e,T=new e,R=new e,A=new e,S=new e,v=new e,g=new e,N=new e,I=4/3*n.PI;d.fromPoints=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r,i=e.clone(t[0],R),o=e.clone(i,E),u=e.clone(i,m),s=e.clone(i,p),c=e.clone(i,_),l=e.clone(i,y),f=e.clone(i,T),h=t.length;for(r=1;r<h;r++){e.clone(t[r],i);var I=i.x,O=i.y,M=i.z;I<o.x&&e.clone(i,o),I>c.x&&e.clone(i,c),O<u.y&&e.clone(i,u),O>l.y&&e.clone(i,l),M<s.z&&e.clone(i,s),M>f.z&&e.clone(i,f)}var w=e.magnitudeSquared(e.subtract(c,o,A)),C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=o,U=c,D=w;C>D&&(D=C,P=u,U=l),x>D&&(D=x,P=s,U=f);var L=S;L.x=.5*(P.x+U.x),L.y=.5*(P.y+U.y),L.z=.5*(P.z+U.z);var F=e.magnitudeSquared(e.subtract(U,L,A)),B=Math.sqrt(F),b=v;b.x=o.x,b.y=u.y,b.z=s.z;var z=g;z.x=c.x,z.y=l.y,z.z=f.z;var q=e.multiplyByScalar(e.add(b,z,A),.5,N),G=0;for(r=0;r<h;r++){e.clone(t[r],i);var V=e.magnitude(e.subtract(i,q,A));V>G&&(G=V);var X=e.magnitudeSquared(e.subtract(i,L,A));if(X>F){var W=Math.sqrt(X);B=.5*(B+W),F=B*B;var H=W-B;L.x=(B*L.x+H*i.x)/W,L.y=(B*L.y+H*i.y)/W,L.z=(B*L.z+H*i.z)/W}}return B<G?(e.clone(L,n.center),n.radius=B):(e.clone(q,n.center),n.radius=G),n};var O=new u,M=new e,w=new e,C=new t,x=new t;d.fromRectangle2D=function(e,t,n){return d.fromRectangleWithHeights2D(e,t,0,0,n)},d.fromRectangleWithHeights2D=function(t,n,r,o,u){if(a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;n=i(n,O),h.southwest(t,C),C.height=r,h.northeast(t,x),x.height=o;var s=n.project(C,M),c=n.project(x,w),l=c.x-s.x,f=c.y-s.y,E=c.z-s.z;u.radius=.5*Math.sqrt(l*l+f*f+E*E);var m=u.center;return m.x=s.x+.5*l,m.y=s.y+.5*f,m.z=s.z+.5*E,u};var P=[];d.fromRectangle3D=function(t,n,r,u){if(n=i(n,o.WGS84),r=i(r,0),a(u)||(u=new d),!a(t))return u.center=e.clone(e.ZERO,u.center),u.radius=0,u;var s=h.subsample(t,n,r,P);return d.fromPoints(s,u)},d.fromVertices=function(t,n,r,o){if(a(o)||(o=new d),!a(t)||0===t.length)return o.center=e.clone(e.ZERO,o.center),o.radius=0,o;n=i(n,e.ZERO),r=i(r,3);var u=R;u.x=t[0]+n.x,u.y=t[1]+n.y,u.z=t[2]+n.z;var s,c=e.clone(u,E),l=e.clone(u,m),f=e.clone(u,p),h=e.clone(u,_),I=e.clone(u,y),O=e.clone(u,T),M=t.length;for(s=0;s<M;s+=r){var w=t[s]+n.x,C=t[s+1]+n.y,x=t[s+2]+n.z;u.x=w,u.y=C,u.z=x,w<c.x&&e.clone(u,c),w>h.x&&e.clone(u,h),C<l.y&&e.clone(u,l),C>I.y&&e.clone(u,I),x<f.z&&e.clone(u,f),x>O.z&&e.clone(u,O)}var P=e.magnitudeSquared(e.subtract(h,c,A)),U=e.magnitudeSquared(e.subtract(I,l,A)),D=e.magnitudeSquared(e.subtract(O,f,A)),L=c,F=h,B=P;U>B&&(B=U,L=l,F=I),D>B&&(B=D,L=f,F=O);var b=S;b.x=.5*(L.x+F.x),b.y=.5*(L.y+F.y),b.z=.5*(L.z+F.z);var z=e.magnitudeSquared(e.subtract(F,b,A)),q=Math.sqrt(z),G=v;G.x=c.x,G.y=l.y,G.z=f.z;var V=g;V.x=h.x,V.y=I.y,V.z=O.z;var X=e.multiplyByScalar(e.add(G,V,A),.5,N),W=0;for(s=0;s<M;s+=r){u.x=t[s]+n.x,u.y=t[s+1]+n.y,u.z=t[s+2]+n.z;var H=e.magnitude(e.subtract(u,X,A));H>W&&(W=H);var Y=e.magnitudeSquared(e.subtract(u,b,A));if(Y>z){var k=Math.sqrt(Y);q=.5*(q+k),z=q*q;var j=k-q;b.x=(q*b.x+j*u.x)/k,b.y=(q*b.y+j*u.y)/k,b.z=(q*b.z+j*u.z)/k}}return q<W?(e.clone(b,o.center),o.radius=q):(e.clone(X,o.center),o.radius=W),o},d.fromEncodedCartesianVertices=function(t,n,r){if(a(r)||(r=new d),!a(t)||!a(n)||t.length!==n.length||0===t.length)return r.center=e.clone(e.ZERO,r.center),r.radius=0,r;var i=R;i.x=t[0]+n[0],i.y=t[1]+n[1],i.z=t[2]+n[2];var o,u=e.clone(i,E),s=e.clone(i,m),c=e.clone(i,p),l=e.clone(i,_),f=e.clone(i,y),h=e.clone(i,T),I=t.length;for(o=0;o<I;o+=3){var O=t[o]+n[o],M=t[o+1]+n[o+1],w=t[o+2]+n[o+2];i.x=O,i.y=M,i.z=w,O<u.x&&e.clone(i,u),O>l.x&&e.clone(i,l),M<s.y&&e.clone(i,s),M>f.y&&e.clone(i,f),w<c.z&&e.clone(i,c),w>h.z&&e.clone(i,h)}var C=e.magnitudeSquared(e.subtract(l,u,A)),x=e.magnitudeSquared(e.subtract(f,s,A)),P=e.magnitudeSquared(e.subtract(h,c,A)),U=u,D=l,L=C;x>L&&(L=x,U=s,D=f),P>L&&(L=P,U=c,D=h);var F=S;F.x=.5*(U.x+D.x),F.y=.5*(U.y+D.y),F.z=.5*(U.z+D.z);var B=e.magnitudeSquared(e.subtract(D,F,A)),b=Math.sqrt(B),z=v;z.x=u.x,z.y=s.y,z.z=c.z;var q=g;q.x=l.x,q.y=f.y,q.z=h.z;var G=e.multiplyByScalar(e.add(z,q,A),.5,N),V=0;for(o=0;o<I;o+=3){i.x=t[o]+n[o],i.y=t[o+1]+n[o+1],i.z=t[o+2]+n[o+2];var X=e.magnitude(e.subtract(i,G,A));X>V&&(V=X);var W=e.magnitudeSquared(e.subtract(i,F,A));if(W>B){var H=Math.sqrt(W);b=.5*(b+H),B=b*b;var Y=H-b;F.x=(b*F.x+Y*i.x)/H,F.y=(b*F.y+Y*i.y)/H,F.z=(b*F.z+Y*i.z)/H}}return b<V?(e.clone(F,r.center),r.radius=b):(e.clone(G,r.center),r.radius=V),r},d.fromCornerPoints=function(t,n,r){a(r)||(r=new d);var i=r.center;return e.add(t,n,i),e.multiplyByScalar(i,.5,i),r.radius=e.distance(i,n),r},d.fromEllipsoid=function(t,n){return a(n)||(n=new d),e.clone(e.ZERO,n.center),n.radius=t.maximumRadius,n};var U=new e;d.fromBoundingSpheres=function(t,n){if(a(n)||(n=new d),!a(t)||0===t.length)return n.center=e.clone(e.ZERO,n.center),n.radius=0,n;var r=t.length;if(1===r)return d.clone(t[0],n);if(2===r)return d.union(t[0],t[1],n);var i,o=[];for(i=0;i<r;i++)o.push(t[i].center);n=d.fromPoints(o,n);var u=n.center,s=n.radius;for(i=0;i<r;i++){var c=t[i];s=Math.max(s,e.distance(u,c.center,U)+c.radius)}return n.radius=s,n};var D=new e,L=new e,F=new e;d.fromOrientedBoundingBox=function(t,n){a(n)||(n=new d);var r=t.halfAxes,i=l.getColumn(r,0,D),o=l.getColumn(r,1,L),u=l.getColumn(r,2,F);return e.add(i,o,i),e.add(i,u,i),n.center=e.clone(t.center,n.center),n.radius=e.magnitude(i),n},d.clone=function(t,n){if(a(t))return a(n)?(n.center=e.clone(t.center,n.center),n.radius=t.radius,n):new d(t.center,t.radius)},d.packedLength=4,d.pack=function(e,t,n){n=i(n,0);var r=e.center;return t[n++]=r.x,t[n++]=r.y,t[n++]=r.z,t[n]=e.radius,t},d.unpack=function(e,t,n){t=i(t,0),a(n)||(n=new d);var r=n.center;return r.x=e[t++],r.y=e[t++],r.z=e[t++],n.radius=e[t],n};var B=new e,b=new e;d.union=function(t,n,r){a(r)||(r=new d);var i=t.center,o=t.radius,u=n.center,s=n.radius,c=e.subtract(u,i,B),l=e.magnitude(c);if(o>=l+s)return t.clone(r),r;if(s>=l+o)return n.clone(r),r;var f=.5*(o+l+s),h=e.multiplyByScalar(c,(-o+f)/l,b);return e.add(h,i,h),e.clone(h,r.center),r.radius=f,r};var z=new e;d.expand=function(t,n,r){r=d.clone(t,r);var i=e.magnitude(e.subtract(n,r.center,z));return i>r.radius&&(r.radius=i),r}, +d.intersectPlane=function(t,n){var r=t.center,i=t.radius,a=n.normal,o=e.dot(a,r)+n.distance;return o<-i?s.OUTSIDE:o<i?s.INTERSECTING:s.INSIDE},d.transform=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=f.getMaximumScale(t)*e.radius,n};var q=new e;d.distanceSquaredTo=function(t,n){var r=e.subtract(t.center,n,q);return e.magnitudeSquared(r)-t.radius*t.radius},d.transformWithoutScale=function(e,t,n){return a(n)||(n=new d),n.center=f.multiplyByPoint(t,e.center,n.center),n.radius=e.radius,n};var G=new e;d.computePlaneDistances=function(t,n,r,i){a(i)||(i=new c);var o=e.subtract(t.center,n,G),u=e.dot(r,o);return i.start=u-t.radius,i.stop=u+t.radius,i};for(var V=new e,X=new e,W=new e,H=new e,Y=new e,k=new t,j=new Array(8),Z=0;Z<8;++Z)j[Z]=new e;var K=new u;return d.projectTo2D=function(t,n,r){n=i(n,K);var a=n.ellipsoid,o=t.center,u=t.radius,s=a.geodeticSurfaceNormal(o,V),c=e.cross(e.UNIT_Z,s,X);e.normalize(c,c);var l=e.cross(s,c,W);e.normalize(l,l),e.multiplyByScalar(s,u,s),e.multiplyByScalar(l,u,l),e.multiplyByScalar(c,u,c);var f=e.negate(l,Y),h=e.negate(c,H),E=j,m=E[0];e.add(s,l,m),e.add(m,c,m),m=E[1],e.add(s,l,m),e.add(m,h,m),m=E[2],e.add(s,f,m),e.add(m,h,m),m=E[3],e.add(s,f,m),e.add(m,c,m),e.negate(s,s),m=E[4],e.add(s,l,m),e.add(m,c,m),m=E[5],e.add(s,l,m),e.add(m,h,m),m=E[6],e.add(s,f,m),e.add(m,h,m),m=E[7],e.add(s,f,m),e.add(m,c,m);for(var p=E.length,_=0;_<p;++_){var y=E[_];e.add(o,y,y);var T=a.cartesianToCartographic(y,k);n.project(T,y)}r=d.fromPoints(E,r),o=r.center;var R=o.x,A=o.y,S=o.z;return o.x=S,o.y=R,o.z=A,r},d.isOccluded=function(e,t){return!t.isBoundingSphereVisible(e)},d.equals=function(t,n){return t===n||a(t)&&a(n)&&e.equals(t.center,n.center)&&t.radius===n.radius},d.prototype.intersectPlane=function(e){return d.intersectPlane(this,e)},d.prototype.distanceSquaredTo=function(e){return d.distanceSquaredTo(this,e)},d.prototype.computePlaneDistances=function(e,t,n){return d.computePlaneDistances(this,e,t,n)},d.prototype.isOccluded=function(e){return d.isOccluded(this,e)},d.prototype.equals=function(e){return d.equals(this,e)},d.prototype.clone=function(e){return d.clone(this,e)},d.prototype.volume=function(){var e=this.radius;return I*e*e*e},d}),define("Core/EllipsoidalOccluder",["./BoundingSphere","./Cartesian3","./Check","./defaultValue","./defined","./defineProperties","./Rectangle"],function(e,t,n,r,i,a,o){"use strict";function u(e,n){this._ellipsoid=e,this._cameraPosition=new t,this._cameraPositionInScaledSpace=new t,this._distanceToLimbInScaledSpaceSquared=0,i(n)&&(this.cameraPosition=n)}function s(e,n,r){var i=e.transformPositionToScaledSpace(n,E),a=t.magnitudeSquared(i),o=Math.sqrt(a),u=t.divideByScalar(i,o,m);a=Math.max(1,a),o=Math.max(1,o);var s=t.dot(u,r),c=t.magnitude(t.cross(u,r,u)),l=1/o;return 1/(s*l-c*(Math.sqrt(a-1)*l))}function c(e,n,r){if(!(n<=0||n===1/0||n!==n))return t.multiplyByScalar(e,n,r)}function l(e,n){return t.equals(n,t.ZERO)?n:(e.transformPositionToScaledSpace(n,p),t.normalize(p,p))}a(u.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},cameraPosition:{get:function(){return this._cameraPosition},set:function(e){var n=this._ellipsoid,r=n.transformPositionToScaledSpace(e,this._cameraPositionInScaledSpace),i=t.magnitudeSquared(r)-1;t.clone(e,this._cameraPosition),this._cameraPositionInScaledSpace=r,this._distanceToLimbInScaledSpaceSquared=i}}});var f=new t;u.prototype.isPointVisible=function(e){var t=this._ellipsoid,n=t.transformPositionToScaledSpace(e,f);return this.isScaledSpacePointVisible(n)},u.prototype.isScaledSpacePointVisible=function(e){var n=this._cameraPositionInScaledSpace,r=this._distanceToLimbInScaledSpaceSquared,i=t.subtract(e,n,f),a=-t.dot(i,n);return!(r<0?a>0:a>r&&a*a/t.magnitudeSquared(i)>r)},u.prototype.computeHorizonCullingPoint=function(e,n,r){i(r)||(r=new t);for(var a=this._ellipsoid,o=l(a,e),u=0,f=0,h=n.length;f<h;++f){var d=n[f],E=s(a,d,o);u=Math.max(u,E)}return c(o,u,r)};var h=new t;u.prototype.computeHorizonCullingPointFromVertices=function(e,n,a,o,u){i(u)||(u=new t),o=r(o,t.ZERO);for(var f=this._ellipsoid,d=l(f,e),E=0,m=0,p=n.length;m<p;m+=a){h.x=n[m]+o.x,h.y=n[m+1]+o.y,h.z=n[m+2]+o.z;var _=s(f,h,d);E=Math.max(E,_)}return c(d,E,u)};var d=[];u.prototype.computeHorizonCullingPointFromRectangle=function(n,r,i){var a=o.subsample(n,r,0,d),u=e.fromPoints(a);if(!(t.magnitude(u.center)<.1*r.minimumRadius))return this.computeHorizonCullingPoint(u.center,a,i)};var E=new t,m=new t,p=new t;return u}),define("Core/WebGLConstants",["./freezeObject"],function(e){"use strict";return e({DEPTH_BUFFER_BIT:256,STENCIL_BUFFER_BIT:1024,COLOR_BUFFER_BIT:16384,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,ZERO:0,ONE:1,SRC_COLOR:768,ONE_MINUS_SRC_COLOR:769,SRC_ALPHA:770,ONE_MINUS_SRC_ALPHA:771,DST_ALPHA:772,ONE_MINUS_DST_ALPHA:773,DST_COLOR:774,ONE_MINUS_DST_COLOR:775,SRC_ALPHA_SATURATE:776,FUNC_ADD:32774,BLEND_EQUATION:32777,BLEND_EQUATION_RGB:32777,BLEND_EQUATION_ALPHA:34877,FUNC_SUBTRACT:32778,FUNC_REVERSE_SUBTRACT:32779,BLEND_DST_RGB:32968,BLEND_SRC_RGB:32969,BLEND_DST_ALPHA:32970,BLEND_SRC_ALPHA:32971,CONSTANT_COLOR:32769,ONE_MINUS_CONSTANT_COLOR:32770,CONSTANT_ALPHA:32771,ONE_MINUS_CONSTANT_ALPHA:32772,BLEND_COLOR:32773,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,ARRAY_BUFFER_BINDING:34964,ELEMENT_ARRAY_BUFFER_BINDING:34965,STREAM_DRAW:35040,STATIC_DRAW:35044,DYNAMIC_DRAW:35048,BUFFER_SIZE:34660,BUFFER_USAGE:34661,CURRENT_VERTEX_ATTRIB:34342,FRONT:1028,BACK:1029,FRONT_AND_BACK:1032,CULL_FACE:2884,BLEND:3042,DITHER:3024,STENCIL_TEST:2960,DEPTH_TEST:2929,SCISSOR_TEST:3089,POLYGON_OFFSET_FILL:32823,SAMPLE_ALPHA_TO_COVERAGE:32926,SAMPLE_COVERAGE:32928,NO_ERROR:0,INVALID_ENUM:1280,INVALID_VALUE:1281,INVALID_OPERATION:1282,OUT_OF_MEMORY:1285,CW:2304,CCW:2305,LINE_WIDTH:2849,ALIASED_POINT_SIZE_RANGE:33901,ALIASED_LINE_WIDTH_RANGE:33902,CULL_FACE_MODE:2885,FRONT_FACE:2886,DEPTH_RANGE:2928,DEPTH_WRITEMASK:2930,DEPTH_CLEAR_VALUE:2931,DEPTH_FUNC:2932,STENCIL_CLEAR_VALUE:2961,STENCIL_FUNC:2962,STENCIL_FAIL:2964,STENCIL_PASS_DEPTH_FAIL:2965,STENCIL_PASS_DEPTH_PASS:2966,STENCIL_REF:2967,STENCIL_VALUE_MASK:2963,STENCIL_WRITEMASK:2968,STENCIL_BACK_FUNC:34816,STENCIL_BACK_FAIL:34817,STENCIL_BACK_PASS_DEPTH_FAIL:34818,STENCIL_BACK_PASS_DEPTH_PASS:34819,STENCIL_BACK_REF:36003,STENCIL_BACK_VALUE_MASK:36004,STENCIL_BACK_WRITEMASK:36005,VIEWPORT:2978,SCISSOR_BOX:3088,COLOR_CLEAR_VALUE:3106,COLOR_WRITEMASK:3107,UNPACK_ALIGNMENT:3317,PACK_ALIGNMENT:3333,MAX_TEXTURE_SIZE:3379,MAX_VIEWPORT_DIMS:3386,SUBPIXEL_BITS:3408,RED_BITS:3410,GREEN_BITS:3411,BLUE_BITS:3412,ALPHA_BITS:3413,DEPTH_BITS:3414,STENCIL_BITS:3415,POLYGON_OFFSET_UNITS:10752,POLYGON_OFFSET_FACTOR:32824,TEXTURE_BINDING_2D:32873,SAMPLE_BUFFERS:32936,SAMPLES:32937,SAMPLE_COVERAGE_VALUE:32938,SAMPLE_COVERAGE_INVERT:32939,COMPRESSED_TEXTURE_FORMATS:34467,DONT_CARE:4352,FASTEST:4353,NICEST:4354,GENERATE_MIPMAP_HINT:33170,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,DEPTH_COMPONENT:6402,ALPHA:6406,RGB:6407,RGBA:6408,LUMINANCE:6409,LUMINANCE_ALPHA:6410,UNSIGNED_SHORT_4_4_4_4:32819,UNSIGNED_SHORT_5_5_5_1:32820,UNSIGNED_SHORT_5_6_5:33635,FRAGMENT_SHADER:35632,VERTEX_SHADER:35633,MAX_VERTEX_ATTRIBS:34921,MAX_VERTEX_UNIFORM_VECTORS:36347,MAX_VARYING_VECTORS:36348,MAX_COMBINED_TEXTURE_IMAGE_UNITS:35661,MAX_VERTEX_TEXTURE_IMAGE_UNITS:35660,MAX_TEXTURE_IMAGE_UNITS:34930,MAX_FRAGMENT_UNIFORM_VECTORS:36349,SHADER_TYPE:35663,DELETE_STATUS:35712,LINK_STATUS:35714,VALIDATE_STATUS:35715,ATTACHED_SHADERS:35717,ACTIVE_UNIFORMS:35718,ACTIVE_ATTRIBUTES:35721,SHADING_LANGUAGE_VERSION:35724,CURRENT_PROGRAM:35725,NEVER:512,LESS:513,EQUAL:514,LEQUAL:515,GREATER:516,NOTEQUAL:517,GEQUAL:518,ALWAYS:519,KEEP:7680,REPLACE:7681,INCR:7682,DECR:7683,INVERT:5386,INCR_WRAP:34055,DECR_WRAP:34056,VENDOR:7936,RENDERER:7937,VERSION:7938,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,TEXTURE_MAG_FILTER:10240,TEXTURE_MIN_FILTER:10241,TEXTURE_WRAP_S:10242,TEXTURE_WRAP_T:10243,TEXTURE_2D:3553,TEXTURE:5890,TEXTURE_CUBE_MAP:34067,TEXTURE_BINDING_CUBE_MAP:34068,TEXTURE_CUBE_MAP_POSITIVE_X:34069,TEXTURE_CUBE_MAP_NEGATIVE_X:34070,TEXTURE_CUBE_MAP_POSITIVE_Y:34071,TEXTURE_CUBE_MAP_NEGATIVE_Y:34072,TEXTURE_CUBE_MAP_POSITIVE_Z:34073,TEXTURE_CUBE_MAP_NEGATIVE_Z:34074,MAX_CUBE_MAP_TEXTURE_SIZE:34076,TEXTURE0:33984,TEXTURE1:33985,TEXTURE2:33986,TEXTURE3:33987,TEXTURE4:33988,TEXTURE5:33989,TEXTURE6:33990,TEXTURE7:33991,TEXTURE8:33992,TEXTURE9:33993,TEXTURE10:33994,TEXTURE11:33995,TEXTURE12:33996,TEXTURE13:33997,TEXTURE14:33998,TEXTURE15:33999,TEXTURE16:34e3,TEXTURE17:34001,TEXTURE18:34002,TEXTURE19:34003,TEXTURE20:34004,TEXTURE21:34005,TEXTURE22:34006,TEXTURE23:34007,TEXTURE24:34008,TEXTURE25:34009,TEXTURE26:34010,TEXTURE27:34011,TEXTURE28:34012,TEXTURE29:34013,TEXTURE30:34014,TEXTURE31:34015,ACTIVE_TEXTURE:34016,REPEAT:10497,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,INT_VEC2:35667,INT_VEC3:35668,INT_VEC4:35669,BOOL:35670,BOOL_VEC2:35671,BOOL_VEC3:35672,BOOL_VEC4:35673,FLOAT_MAT2:35674,FLOAT_MAT3:35675,FLOAT_MAT4:35676,SAMPLER_2D:35678,SAMPLER_CUBE:35680,VERTEX_ATTRIB_ARRAY_ENABLED:34338,VERTEX_ATTRIB_ARRAY_SIZE:34339,VERTEX_ATTRIB_ARRAY_STRIDE:34340,VERTEX_ATTRIB_ARRAY_TYPE:34341,VERTEX_ATTRIB_ARRAY_NORMALIZED:34922,VERTEX_ATTRIB_ARRAY_POINTER:34373,VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:34975,IMPLEMENTATION_COLOR_READ_TYPE:35738,IMPLEMENTATION_COLOR_READ_FORMAT:35739,COMPILE_STATUS:35713,LOW_FLOAT:36336,MEDIUM_FLOAT:36337,HIGH_FLOAT:36338,LOW_INT:36339,MEDIUM_INT:36340,HIGH_INT:36341,FRAMEBUFFER:36160,RENDERBUFFER:36161,RGBA4:32854,RGB5_A1:32855,RGB565:36194,DEPTH_COMPONENT16:33189,STENCIL_INDEX:6401,STENCIL_INDEX8:36168,DEPTH_STENCIL:34041,RENDERBUFFER_WIDTH:36162,RENDERBUFFER_HEIGHT:36163,RENDERBUFFER_INTERNAL_FORMAT:36164,RENDERBUFFER_RED_SIZE:36176,RENDERBUFFER_GREEN_SIZE:36177,RENDERBUFFER_BLUE_SIZE:36178,RENDERBUFFER_ALPHA_SIZE:36179,RENDERBUFFER_DEPTH_SIZE:36180,RENDERBUFFER_STENCIL_SIZE:36181,FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:36048,FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:36049,FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:36050,FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:36051,COLOR_ATTACHMENT0:36064,DEPTH_ATTACHMENT:36096,STENCIL_ATTACHMENT:36128,DEPTH_STENCIL_ATTACHMENT:33306,NONE:0,FRAMEBUFFER_COMPLETE:36053,FRAMEBUFFER_INCOMPLETE_ATTACHMENT:36054,FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:36055,FRAMEBUFFER_INCOMPLETE_DIMENSIONS:36057,FRAMEBUFFER_UNSUPPORTED:36061,FRAMEBUFFER_BINDING:36006,RENDERBUFFER_BINDING:36007,MAX_RENDERBUFFER_SIZE:34024,INVALID_FRAMEBUFFER_OPERATION:1286,UNPACK_FLIP_Y_WEBGL:37440,UNPACK_PREMULTIPLY_ALPHA_WEBGL:37441,CONTEXT_LOST_WEBGL:37442,UNPACK_COLORSPACE_CONVERSION_WEBGL:37443,BROWSER_DEFAULT_WEBGL:37444,COMPRESSED_RGB_S3TC_DXT1_EXT:33776,COMPRESSED_RGBA_S3TC_DXT1_EXT:33777,COMPRESSED_RGBA_S3TC_DXT3_EXT:33778,COMPRESSED_RGBA_S3TC_DXT5_EXT:33779,COMPRESSED_RGB_PVRTC_4BPPV1_IMG:35840,COMPRESSED_RGB_PVRTC_2BPPV1_IMG:35841,COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:35842,COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:35843,COMPRESSED_RGB_ETC1_WEBGL:36196,DOUBLE:5130,READ_BUFFER:3074,UNPACK_ROW_LENGTH:3314,UNPACK_SKIP_ROWS:3315,UNPACK_SKIP_PIXELS:3316,PACK_ROW_LENGTH:3330,PACK_SKIP_ROWS:3331,PACK_SKIP_PIXELS:3332,COLOR:6144,DEPTH:6145,STENCIL:6146,RED:6403,RGB8:32849,RGBA8:32856,RGB10_A2:32857,TEXTURE_BINDING_3D:32874,UNPACK_SKIP_IMAGES:32877,UNPACK_IMAGE_HEIGHT:32878,TEXTURE_3D:32879,TEXTURE_WRAP_R:32882,MAX_3D_TEXTURE_SIZE:32883,UNSIGNED_INT_2_10_10_10_REV:33640,MAX_ELEMENTS_VERTICES:33e3,MAX_ELEMENTS_INDICES:33001,TEXTURE_MIN_LOD:33082,TEXTURE_MAX_LOD:33083,TEXTURE_BASE_LEVEL:33084,TEXTURE_MAX_LEVEL:33085,MIN:32775,MAX:32776,DEPTH_COMPONENT24:33190,MAX_TEXTURE_LOD_BIAS:34045,TEXTURE_COMPARE_MODE:34892,TEXTURE_COMPARE_FUNC:34893,CURRENT_QUERY:34917,QUERY_RESULT:34918,QUERY_RESULT_AVAILABLE:34919,STREAM_READ:35041,STREAM_COPY:35042,STATIC_READ:35045,STATIC_COPY:35046,DYNAMIC_READ:35049,DYNAMIC_COPY:35050,MAX_DRAW_BUFFERS:34852,DRAW_BUFFER0:34853,DRAW_BUFFER1:34854,DRAW_BUFFER2:34855,DRAW_BUFFER3:34856,DRAW_BUFFER4:34857,DRAW_BUFFER5:34858,DRAW_BUFFER6:34859,DRAW_BUFFER7:34860,DRAW_BUFFER8:34861,DRAW_BUFFER9:34862,DRAW_BUFFER10:34863,DRAW_BUFFER11:34864,DRAW_BUFFER12:34865,DRAW_BUFFER13:34866,DRAW_BUFFER14:34867,DRAW_BUFFER15:34868,MAX_FRAGMENT_UNIFORM_COMPONENTS:35657,MAX_VERTEX_UNIFORM_COMPONENTS:35658,SAMPLER_3D:35679,SAMPLER_2D_SHADOW:35682,FRAGMENT_SHADER_DERIVATIVE_HINT:35723,PIXEL_PACK_BUFFER:35051,PIXEL_UNPACK_BUFFER:35052,PIXEL_PACK_BUFFER_BINDING:35053,PIXEL_UNPACK_BUFFER_BINDING:35055,FLOAT_MAT2x3:35685,FLOAT_MAT2x4:35686,FLOAT_MAT3x2:35687,FLOAT_MAT3x4:35688,FLOAT_MAT4x2:35689,FLOAT_MAT4x3:35690,SRGB:35904,SRGB8:35905,SRGB8_ALPHA8:35907,COMPARE_REF_TO_TEXTURE:34894,RGBA32F:34836,RGB32F:34837,RGBA16F:34842,RGB16F:34843,VERTEX_ATTRIB_ARRAY_INTEGER:35069,MAX_ARRAY_TEXTURE_LAYERS:35071,MIN_PROGRAM_TEXEL_OFFSET:35076,MAX_PROGRAM_TEXEL_OFFSET:35077,MAX_VARYING_COMPONENTS:35659,TEXTURE_2D_ARRAY:35866,TEXTURE_BINDING_2D_ARRAY:35869,R11F_G11F_B10F:35898,UNSIGNED_INT_10F_11F_11F_REV:35899,RGB9_E5:35901,UNSIGNED_INT_5_9_9_9_REV:35902,TRANSFORM_FEEDBACK_BUFFER_MODE:35967,MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:35968,TRANSFORM_FEEDBACK_VARYINGS:35971,TRANSFORM_FEEDBACK_BUFFER_START:35972,TRANSFORM_FEEDBACK_BUFFER_SIZE:35973,TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:35976,RASTERIZER_DISCARD:35977,MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:35978,MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:35979,INTERLEAVED_ATTRIBS:35980,SEPARATE_ATTRIBS:35981,TRANSFORM_FEEDBACK_BUFFER:35982,TRANSFORM_FEEDBACK_BUFFER_BINDING:35983,RGBA32UI:36208,RGB32UI:36209,RGBA16UI:36214,RGB16UI:36215,RGBA8UI:36220,RGB8UI:36221,RGBA32I:36226,RGB32I:36227,RGBA16I:36232,RGB16I:36233,RGBA8I:36238,RGB8I:36239,RED_INTEGER:36244,RGB_INTEGER:36248,RGBA_INTEGER:36249,SAMPLER_2D_ARRAY:36289,SAMPLER_2D_ARRAY_SHADOW:36292,SAMPLER_CUBE_SHADOW:36293,UNSIGNED_INT_VEC2:36294,UNSIGNED_INT_VEC3:36295,UNSIGNED_INT_VEC4:36296,INT_SAMPLER_2D:36298,INT_SAMPLER_3D:36299,INT_SAMPLER_CUBE:36300,INT_SAMPLER_2D_ARRAY:36303,UNSIGNED_INT_SAMPLER_2D:36306,UNSIGNED_INT_SAMPLER_3D:36307,UNSIGNED_INT_SAMPLER_CUBE:36308,UNSIGNED_INT_SAMPLER_2D_ARRAY:36311,DEPTH_COMPONENT32F:36012,DEPTH32F_STENCIL8:36013,FLOAT_32_UNSIGNED_INT_24_8_REV:36269,FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:33296,FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:33297,FRAMEBUFFER_ATTACHMENT_RED_SIZE:33298,FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:33299,FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:33300,FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:33301,FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:33302,FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:33303,FRAMEBUFFER_DEFAULT:33304,UNSIGNED_INT_24_8:34042,DEPTH24_STENCIL8:35056,UNSIGNED_NORMALIZED:35863,DRAW_FRAMEBUFFER_BINDING:36006,READ_FRAMEBUFFER:36008,DRAW_FRAMEBUFFER:36009,READ_FRAMEBUFFER_BINDING:36010,RENDERBUFFER_SAMPLES:36011,FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:36052,MAX_COLOR_ATTACHMENTS:36063,COLOR_ATTACHMENT1:36065,COLOR_ATTACHMENT2:36066,COLOR_ATTACHMENT3:36067,COLOR_ATTACHMENT4:36068,COLOR_ATTACHMENT5:36069,COLOR_ATTACHMENT6:36070,COLOR_ATTACHMENT7:36071,COLOR_ATTACHMENT8:36072,COLOR_ATTACHMENT9:36073,COLOR_ATTACHMENT10:36074,COLOR_ATTACHMENT11:36075,COLOR_ATTACHMENT12:36076,COLOR_ATTACHMENT13:36077,COLOR_ATTACHMENT14:36078,COLOR_ATTACHMENT15:36079,FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:36182,MAX_SAMPLES:36183,HALF_FLOAT:5131,RG:33319,RG_INTEGER:33320,R8:33321,RG8:33323,R16F:33325,R32F:33326,RG16F:33327,RG32F:33328,R8I:33329,R8UI:33330,R16I:33331,R16UI:33332,R32I:33333,R32UI:33334,RG8I:33335,RG8UI:33336,RG16I:33337,RG16UI:33338,RG32I:33339,RG32UI:33340,VERTEX_ARRAY_BINDING:34229,R8_SNORM:36756,RG8_SNORM:36757,RGB8_SNORM:36758,RGBA8_SNORM:36759,SIGNED_NORMALIZED:36764,COPY_READ_BUFFER:36662,COPY_WRITE_BUFFER:36663,COPY_READ_BUFFER_BINDING:36662,COPY_WRITE_BUFFER_BINDING:36663,UNIFORM_BUFFER:35345,UNIFORM_BUFFER_BINDING:35368,UNIFORM_BUFFER_START:35369,UNIFORM_BUFFER_SIZE:35370,MAX_VERTEX_UNIFORM_BLOCKS:35371,MAX_FRAGMENT_UNIFORM_BLOCKS:35373,MAX_COMBINED_UNIFORM_BLOCKS:35374,MAX_UNIFORM_BUFFER_BINDINGS:35375,MAX_UNIFORM_BLOCK_SIZE:35376,MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:35377,MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:35379,UNIFORM_BUFFER_OFFSET_ALIGNMENT:35380,ACTIVE_UNIFORM_BLOCKS:35382,UNIFORM_TYPE:35383,UNIFORM_SIZE:35384,UNIFORM_BLOCK_INDEX:35386,UNIFORM_OFFSET:35387,UNIFORM_ARRAY_STRIDE:35388,UNIFORM_MATRIX_STRIDE:35389,UNIFORM_IS_ROW_MAJOR:35390,UNIFORM_BLOCK_BINDING:35391,UNIFORM_BLOCK_DATA_SIZE:35392,UNIFORM_BLOCK_ACTIVE_UNIFORMS:35394,UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:35395,UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:35396,UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:35398,INVALID_INDEX:4294967295,MAX_VERTEX_OUTPUT_COMPONENTS:37154,MAX_FRAGMENT_INPUT_COMPONENTS:37157,MAX_SERVER_WAIT_TIMEOUT:37137,OBJECT_TYPE:37138,SYNC_CONDITION:37139,SYNC_STATUS:37140,SYNC_FLAGS:37141,SYNC_FENCE:37142,SYNC_GPU_COMMANDS_COMPLETE:37143,UNSIGNALED:37144,SIGNALED:37145,ALREADY_SIGNALED:37146,TIMEOUT_EXPIRED:37147,CONDITION_SATISFIED:37148,WAIT_FAILED:37149,SYNC_FLUSH_COMMANDS_BIT:1,VERTEX_ATTRIB_ARRAY_DIVISOR:35070,ANY_SAMPLES_PASSED:35887,ANY_SAMPLES_PASSED_CONSERVATIVE:36202,SAMPLER_BINDING:35097,RGB10_A2UI:36975,INT_2_10_10_10_REV:36255,TRANSFORM_FEEDBACK:36386,TRANSFORM_FEEDBACK_PAUSED:36387,TRANSFORM_FEEDBACK_ACTIVE:36388,TRANSFORM_FEEDBACK_BINDING:36389,COMPRESSED_R11_EAC:37488,COMPRESSED_SIGNED_R11_EAC:37489,COMPRESSED_RG11_EAC:37490,COMPRESSED_SIGNED_RG11_EAC:37491,COMPRESSED_RGB8_ETC2:37492,COMPRESSED_SRGB8_ETC2:37493,COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:37494,COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:37495,COMPRESSED_RGBA8_ETC2_EAC:37496,COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:37497,TEXTURE_IMMUTABLE_FORMAT:37167,MAX_ELEMENT_INDEX:36203,TEXTURE_IMMUTABLE_LEVELS:33503,MAX_TEXTURE_MAX_ANISOTROPY_EXT:34047})}),define("Core/IndexDatatype",["./defined","./DeveloperError","./freezeObject","./Math","./WebGLConstants"],function(e,t,n,r,i){"use strict";var a={UNSIGNED_BYTE:i.UNSIGNED_BYTE,UNSIGNED_SHORT:i.UNSIGNED_SHORT,UNSIGNED_INT:i.UNSIGNED_INT};return a.getSizeInBytes=function(e){switch(e){case a.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case a.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case a.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT}},a.validate=function(t){return e(t)&&(t===a.UNSIGNED_BYTE||t===a.UNSIGNED_SHORT||t===a.UNSIGNED_INT)},a.createTypedArray=function(e,t){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t):new Uint16Array(t)},a.createTypedArrayFromArrayBuffer=function(e,t,n,i){return e>=r.SIXTY_FOUR_KILOBYTES?new Uint32Array(t,n,i):new Uint16Array(t,n,i)},n(a)}),define("Core/Intersections2D",["./Cartesian3","./defined","./DeveloperError"],function(e,t,n){"use strict";var r={};return r.clipTriangleAtAxisAlignedThreshold=function(e,n,r,i,a,o){t(o)?o.length=0:o=[];var u,s,c;n?(u=r<e,s=i<e,c=a<e):(u=r>e,s=i>e,c=a>e);var l,f,h,d,E,m,p=u+s+c;return 1===p?u?(l=(e-r)/(i-r),f=(e-r)/(a-r),o.push(1),o.push(2),1!==f&&(o.push(-1),o.push(0),o.push(2),o.push(f)),1!==l&&(o.push(-1),o.push(0),o.push(1),o.push(l))):s?(h=(e-i)/(a-i),d=(e-i)/(r-i),o.push(2),o.push(0),1!==d&&(o.push(-1),o.push(1),o.push(0),o.push(d)),1!==h&&(o.push(-1),o.push(1),o.push(2),o.push(h))):c&&(E=(e-a)/(r-a),m=(e-a)/(i-a),o.push(0),o.push(1),1!==m&&(o.push(-1),o.push(2),o.push(1),o.push(m)),1!==E&&(o.push(-1),o.push(2),o.push(0),o.push(E))):2===p?u||r===e?s||i===e?c||a===e||(f=(e-r)/(a-r),h=(e-i)/(a-i),o.push(2),o.push(-1),o.push(0),o.push(2),o.push(f),o.push(-1),o.push(1),o.push(2),o.push(h)):(m=(e-a)/(i-a),l=(e-r)/(i-r),o.push(1),o.push(-1),o.push(2),o.push(1),o.push(m),o.push(-1),o.push(0),o.push(1),o.push(l)):(d=(e-i)/(r-i),E=(e-a)/(r-a),o.push(0),o.push(-1),o.push(1),o.push(0),o.push(d),o.push(-1),o.push(2),o.push(0),o.push(E)):3!==p&&(o.push(0),o.push(1),o.push(2)),o},r.computeBarycentricCoordinates=function(n,r,i,a,o,u,s,c,l){var f=i-s,h=s-o,d=u-c,E=a-c,m=1/(d*f+h*E),p=r-c,_=n-s,y=(d*_+h*p)*m,T=(-E*_+f*p)*m,R=1-y-T;return t(l)?(l.x=y,l.y=T,l.z=R,l):new e(y,T,R)},r}),define("Core/AxisAlignedBoundingBox",["./Cartesian3","./Check","./defaultValue","./defined","./Intersect"],function(e,t,n,r,i){"use strict";function a(t,i,a){this.minimum=e.clone(n(t,e.ZERO)),this.maximum=e.clone(n(i,e.ZERO)),r(a)?a=e.clone(a):(a=e.add(this.minimum,this.maximum,new e),e.multiplyByScalar(a,.5,a)),this.center=a}a.fromPoints=function(t,n){if(r(n)||(n=new a),!r(t)||0===t.length)return n.minimum=e.clone(e.ZERO,n.minimum),n.maximum=e.clone(e.ZERO,n.maximum),n.center=e.clone(e.ZERO,n.center),n;for(var i=t[0].x,o=t[0].y,u=t[0].z,s=t[0].x,c=t[0].y,l=t[0].z,f=t.length,h=1;h<f;h++){var d=t[h],E=d.x,m=d.y,p=d.z;i=Math.min(E,i),s=Math.max(E,s),o=Math.min(m,o),c=Math.max(m,c),u=Math.min(p,u),l=Math.max(p,l)}var _=n.minimum;_.x=i,_.y=o,_.z=u;var y=n.maximum;y.x=s,y.y=c,y.z=l;var T=e.add(_,y,n.center);return e.multiplyByScalar(T,.5,T),n},a.clone=function(t,n){if(r(t))return r(n)?(n.minimum=e.clone(t.minimum,n.minimum),n.maximum=e.clone(t.maximum,n.maximum),n.center=e.clone(t.center,n.center),n):new a(t.minimum,t.maximum)},a.equals=function(t,n){return t===n||r(t)&&r(n)&&e.equals(t.center,n.center)&&e.equals(t.minimum,n.minimum)&&e.equals(t.maximum,n.maximum)};var o=new e;return a.intersectPlane=function(t,n){o=e.subtract(t.maximum,t.minimum,o);var r=e.multiplyByScalar(o,.5,o),a=n.normal,u=r.x*Math.abs(a.x)+r.y*Math.abs(a.y)+r.z*Math.abs(a.z),s=e.dot(t.center,a)+n.distance;return s-u>0?i.INSIDE:s+u<0?i.OUTSIDE:i.INTERSECTING},a.prototype.clone=function(e){return a.clone(this,e)},a.prototype.intersectPlane=function(e){return a.intersectPlane(this,e)},a.prototype.equals=function(e){return a.equals(this,e)},a}),define("Core/QuadraticRealPolynomial",["./DeveloperError","./Math"],function(e,t){"use strict";function n(e,n,r){var i=e+n;return t.sign(e)!==t.sign(n)&&Math.abs(i/Math.max(Math.abs(e),Math.abs(n)))<r?0:i}var r={};return r.computeDiscriminant=function(e,t,n){return t*t-4*e*n},r.computeRealRoots=function(e,r,i){var a;if(0===e)return 0===r?[]:[-i/r];if(0===r){if(0===i)return[0,0];var o=Math.abs(i),u=Math.abs(e);if(o<u&&o/u<t.EPSILON14)return[0,0];if(o>u&&u/o<t.EPSILON14)return[];if((a=-i/e)<0)return[];var s=Math.sqrt(a);return[-s,s]}if(0===i)return a=-r/e,a<0?[a,0]:[0,a];var c=r*r,l=4*e*i,f=n(c,-l,t.EPSILON14);if(f<0)return[];var h=-.5*n(r,t.sign(r)*Math.sqrt(f),t.EPSILON14);return r>0?[h/e,i/h]:[i/h,h/e]},r}),define("Core/CubicRealPolynomial",["./DeveloperError","./QuadraticRealPolynomial"],function(e,t){"use strict";function n(e,t,n,r){var i,a,o=e,u=t/3,s=n/3,c=r,l=o*s,f=u*c,h=u*u,d=s*s,E=o*s-h,m=o*c-u*s,p=u*c-d,_=4*E*p-m*m;if(_<0){var y,T,R;h*f>=l*d?(y=o,T=E,R=-2*u*E+o*m):(y=c,T=p,R=-c*m+2*s*p);var A=R<0?-1:1,S=-A*Math.abs(y)*Math.sqrt(-_);a=-R+S;var v=a/2,g=v<0?-Math.pow(-v,1/3):Math.pow(v,1/3),N=a===S?-g:-T/g;return i=T<=0?g+N:-R/(g*g+N*N+T),h*f>=l*d?[(i-u)/o]:[-c/(i+s)]}var I=E,O=-2*u*E+o*m,M=p,w=-c*m+2*s*p,C=Math.sqrt(_),x=Math.sqrt(3)/2,P=Math.abs(Math.atan2(o*C,-O)/3);i=2*Math.sqrt(-I);var U=Math.cos(P);a=i*U;var D=i*(-U/2-x*Math.sin(P)),L=a+D>2*u?a-u:D-u,F=o,B=L/F;P=Math.abs(Math.atan2(c*C,-w)/3),i=2*Math.sqrt(-M),U=Math.cos(P),a=i*U,D=i*(-U/2-x*Math.sin(P));var b=-c,z=a+D<2*s?a+s:D+s,q=b/z,G=F*z,V=-L*z-F*b,X=L*b,W=(s*V-u*X)/(-u*V+s*G);return B<=W?B<=q?W<=q?[B,W,q]:[B,q,W]:[q,B,W]:B<=q?[W,B,q]:W<=q?[W,q,B]:[q,W,B]}var r={};return r.computeDiscriminant=function(e,t,n,r){var i=e*e,a=t*t,o=n*n;return 18*e*t*n*r+a*o-27*i*(r*r)-4*(e*o*n+a*t*r)},r.computeRealRoots=function(e,r,i,a){var o,u;if(0===e)return t.computeRealRoots(r,i,a);if(0===r){if(0===i){if(0===a)return[0,0,0];u=-a/e;var s=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3);return[s,s,s]}return 0===a?(o=t.computeRealRoots(e,0,i),0===o.Length?[0]:[o[0],0,o[1]]):n(e,0,i,a)}return 0===i?0===a?(u=-r/e,u<0?[u,0,0]:[0,0,u]):n(e,r,0,a):0===a?(o=t.computeRealRoots(e,r,i),0===o.length?[0]:o[1]<=0?[o[0],o[1],0]:o[0]>=0?[0,o[0],o[1]]:[o[0],0,o[1]]):n(e,r,i,a)},r}),define("Core/QuarticRealPolynomial",["./CubicRealPolynomial","./DeveloperError","./Math","./QuadraticRealPolynomial"],function(e,t,n,r){"use strict";function i(t,i,a,o){var u=t*t,s=i-3*u/8,c=a-i*t/2+u*t/8,l=o-a*t/4+i*u/16-3*u*u/256,f=e.computeRealRoots(1,2*s,s*s-4*l,-c*c);if(f.length>0){var h=-t/4,d=f[f.length-1];if(Math.abs(d)<n.EPSILON14){var E=r.computeRealRoots(1,s,l);if(2===E.length){var m,p=E[0],_=E[1];if(p>=0&&_>=0){var y=Math.sqrt(p),T=Math.sqrt(_);return[h-T,h-y,h+y,h+T]}if(p>=0&&_<0)return m=Math.sqrt(p),[h-m,h+m];if(p<0&&_>=0)return m=Math.sqrt(_),[h-m,h+m]}return[]}if(d>0){var R=Math.sqrt(d),A=(s+d-c/R)/2,S=(s+d+c/R)/2,v=r.computeRealRoots(1,R,A),g=r.computeRealRoots(1,-R,S);return 0!==v.length?(v[0]+=h,v[1]+=h,0!==g.length?(g[0]+=h,g[1]+=h,v[1]<=g[0]?[v[0],v[1],g[0],g[1]]:g[1]<=v[0]?[g[0],g[1],v[0],v[1]]:v[0]>=g[0]&&v[1]<=g[1]?[g[0],v[0],v[1],g[1]]:g[0]>=v[0]&&g[1]<=v[1]?[v[0],g[0],g[1],v[1]]:v[0]>g[0]&&v[0]<g[1]?[g[0],v[0],g[1],v[1]]:[v[0],g[0],v[1],g[1]]):v):0!==g.length?(g[0]+=h,g[1]+=h,g):[]}}return[]}function a(t,i,a,o){var u=a*a,s=i*i,c=t*t,l=-2*i,f=a*t+s-4*o,h=c*o-a*i*t+u,d=e.computeRealRoots(1,l,f,h);if(d.length>0){var E,m,p=d[0],_=i-p,y=_*_,T=t/2,R=_/2,A=y-4*o,S=y+4*Math.abs(o),v=c-4*p,g=c+4*Math.abs(p);if(p<0||A*g<v*S){var N=Math.sqrt(v);E=N/2,m=0===N?0:(t*R-a)/N}else{var I=Math.sqrt(A);E=0===I?0:(t*R-a)/I,m=I/2}var O,M;0===T&&0===E?(O=0,M=0):n.sign(T)===n.sign(E)?(O=T+E,M=p/O):(M=T-E,O=p/M);var w,C;0===R&&0===m?(w=0,C=0):n.sign(R)===n.sign(m)?(w=R+m,C=o/w):(C=R-m,w=o/C);var x=r.computeRealRoots(1,O,w),P=r.computeRealRoots(1,M,C);if(0!==x.length)return 0!==P.length?x[1]<=P[0]?[x[0],x[1],P[0],P[1]]:P[1]<=x[0]?[P[0],P[1],x[0],x[1]]:x[0]>=P[0]&&x[1]<=P[1]?[P[0],x[0],x[1],P[1]]:P[0]>=x[0]&&P[1]<=x[1]?[x[0],P[0],P[1],x[1]]:x[0]>P[0]&&x[0]<P[1]?[P[0],x[0],P[1],x[1]]:[x[0],P[0],x[1],P[1]]:x;if(0!==P.length)return P}return[]}var o={};return o.computeDiscriminant=function(e,t,n,r,i){var a=e*e,o=a*e,u=t*t,s=u*t,c=n*n,l=c*n,f=r*r,h=f*r,d=i*i;return u*c*f-4*s*h-4*e*l*f+18*e*t*n*h-27*a*f*f+256*o*(d*i)+i*(18*s*n*r-4*u*l+16*e*c*c-80*e*t*c*r-6*e*u*f+144*a*n*f)+d*(144*e*u*n-27*u*u-128*a*c-192*a*t*r)},o.computeRealRoots=function(t,r,o,u,s){if(Math.abs(t)<n.EPSILON15)return e.computeRealRoots(r,o,u,s);var c=r/t,l=o/t,f=u/t,h=s/t,d=c<0?1:0;switch(d+=l<0?d+1:d,d+=f<0?d+1:d,d+=h<0?d+1:d){case 0:return i(c,l,f,h);case 1:case 2:return a(c,l,f,h);case 3:case 4:return i(c,l,f,h);case 5:return a(c,l,f,h);case 6:case 7:return i(c,l,f,h);case 8:return a(c,l,f,h);case 9:case 10:return i(c,l,f,h);case 11:return a(c,l,f,h);case 12:case 13:case 14:case 15:return i(c,l,f,h);default:return}},o}),define("Core/Ray",["./Cartesian3","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(n,r){r=e.clone(t(r,e.ZERO)),e.equals(r,e.ZERO)||e.normalize(r,r),this.origin=e.clone(t(n,e.ZERO)),this.direction=r}return i.getPoint=function(t,r,i){return n(i)||(i=new e),i=e.multiplyByScalar(t.direction,r,i),e.add(t.origin,i,i)},i}),define("Core/IntersectionTests",["./Cartesian3","./Cartographic","./defaultValue","./defined","./DeveloperError","./Interval","./Math","./Matrix3","./QuadraticRealPolynomial","./QuarticRealPolynomial","./Ray"],function(e,t,n,r,i,a,o,u,s,c,l){"use strict";function f(e,t,n,r){var i=t*t-4*e*n;if(!(i<0)){if(i>0){var a=1/(2*e),o=Math.sqrt(i),u=(-t+o)*a,s=(-t-o)*a;return u<s?(r.root0=u,r.root1=s):(r.root0=s,r.root1=u),r}var c=-t/(2*e);if(0!==c)return r.root0=r.root1=c,r}}function h(t,n,i){r(i)||(i=new a);var o=t.origin,u=t.direction,s=n.center,c=n.radius*n.radius,l=e.subtract(o,s,y),h=e.dot(u,u),d=2*e.dot(u,l),E=e.magnitudeSquared(l)-c,m=f(h,d,E,S);if(r(m))return i.start=m.root0,i.stop=m.root1,i}function d(e,t,n){var r=e+t;return o.sign(e)!==o.sign(t)&&Math.abs(r/Math.max(Math.abs(e),Math.abs(t)))<n?0:r}function E(t,n,r,i,a){var l,f=i*i,h=a*a,E=(t[u.COLUMN1ROW1]-t[u.COLUMN2ROW2])*h,m=a*(i*d(t[u.COLUMN1ROW0],t[u.COLUMN0ROW1],o.EPSILON15)+n.y),p=t[u.COLUMN0ROW0]*f+t[u.COLUMN2ROW2]*h+i*n.x+r,_=h*d(t[u.COLUMN2ROW1],t[u.COLUMN1ROW2],o.EPSILON15),y=a*(i*d(t[u.COLUMN2ROW0],t[u.COLUMN0ROW2])+n.z),T=[];if(0===y&&0===_){if(l=s.computeRealRoots(E,m,p),0===l.length)return T;var R=l[0],A=Math.sqrt(Math.max(1-R*R,0));if(T.push(new e(i,a*R,a*-A)),T.push(new e(i,a*R,a*A)),2===l.length){var S=l[1],v=Math.sqrt(Math.max(1-S*S,0));T.push(new e(i,a*S,a*-v)),T.push(new e(i,a*S,a*v))}return T}var g=y*y,N=_*_,I=E*E,O=y*_,M=I+N,w=2*(m*E+O),C=2*p*E+m*m-N+g,x=2*(p*m-O),P=p*p-g;if(0===M&&0===w&&0===C&&0===x)return T;l=c.computeRealRoots(M,w,C,x,P);var U=l.length;if(0===U)return T;for(var D=0;D<U;++D){var L,F=l[D],B=F*F,b=Math.max(1-B,0),z=Math.sqrt(b);L=o.sign(E)===o.sign(p)?d(E*B+p,m*F,o.EPSILON12):o.sign(p)===o.sign(m*F)?d(E*B,m*F+p,o.EPSILON12):d(E*B+m*F,p,o.EPSILON12);var q=d(_*F,y,o.EPSILON15),G=L*q;G<0?T.push(new e(i,a*F,a*z)):G>0?T.push(new e(i,a*F,a*-z)):0!==z?(T.push(new e(i,a*F,a*-z)),T.push(new e(i,a*F,a*z)),++D):T.push(new e(i,a*F,a*z))}return T}var m={};m.rayPlane=function(t,n,i){r(i)||(i=new e);var a=t.origin,u=t.direction,s=n.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON15)){var l=(-n.distance-e.dot(s,a))/c;if(!(l<0))return i=e.multiplyByScalar(u,l,i),e.add(a,i,i)}};var p=new e,_=new e,y=new e,T=new e,R=new e;m.rayTriangleParametric=function(t,r,i,a,u){u=n(u,!1);var s,c,l,f,h,d=t.origin,E=t.direction,m=e.subtract(i,r,p),A=e.subtract(a,r,_),S=e.cross(E,A,y),v=e.dot(m,S);if(u){if(v<o.EPSILON6)return;if(s=e.subtract(d,r,T),(l=e.dot(s,S))<0||l>v)return;if(c=e.cross(s,m,R),(f=e.dot(E,c))<0||l+f>v)return;h=e.dot(A,c)/v}else{if(Math.abs(v)<o.EPSILON6)return;var g=1/v;if(s=e.subtract(d,r,T),(l=e.dot(s,S)*g)<0||l>1)return;if(c=e.cross(s,m,R),(f=e.dot(E,c)*g)<0||l+f>1)return;h=e.dot(A,c)*g}return h},m.rayTriangle=function(t,n,i,a,o,u){var s=m.rayTriangleParametric(t,n,i,a,o);if(r(s)&&!(s<0))return r(u)||(u=new e),e.multiplyByScalar(t.direction,s,u),e.add(t.origin,u,u)};var A=new l;m.lineSegmentTriangle=function(t,n,i,a,o,u,s){var c=A;e.clone(t,c.origin),e.subtract(n,t,c.direction),e.normalize(c.direction,c.direction);var l=m.rayTriangleParametric(c,i,a,o,u);if(!(!r(l)||l<0||l>e.distance(t,n)))return r(s)||(s=new e),e.multiplyByScalar(c.direction,l,s),e.add(c.origin,s,s)};var S={root0:0,root1:0};m.raySphere=function(e,t,n){if(n=h(e,t,n),r(n)&&!(n.stop<0))return n.start=Math.max(n.start,0),n};var v=new l;m.lineSegmentSphere=function(t,n,i,a){var o=v;e.clone(t,o.origin);var u=e.subtract(n,t,o.direction),s=e.magnitude(u);if(e.normalize(u,u),a=h(o,i,a),!(!r(a)||a.stop<0||a.start>s))return a.start=Math.max(a.start,0),a.stop=Math.min(a.stop,s),a};var g=new e,N=new e;m.rayEllipsoid=function(t,n){var r,i,o,u,s,c=n.oneOverRadii,l=e.multiplyComponents(c,t.origin,g),f=e.multiplyComponents(c,t.direction,N),h=e.magnitudeSquared(l),d=e.dot(l,f);if(h>1){if(d>=0)return;var E=d*d;if(r=h-1,i=e.magnitudeSquared(f),o=i*r,E<o)return;if(E>o){u=d*d-o,s=-d+Math.sqrt(u);var m=s/i,p=r/s;return m<p?new a(m,p):{start:p,stop:m}}var _=Math.sqrt(r/i);return new a(_,_)}return h<1?(r=h-1,i=e.magnitudeSquared(f),o=i*r,u=d*d-o,s=-d+Math.sqrt(u),new a(0,s/i)):d<0?(i=e.magnitudeSquared(f),new a(0,-d/i)):void 0};var I=new e,O=new e,M=new e,w=new e,C=new e,x=new u,P=new u,U=new u,D=new u,L=new u,F=new u,B=new u,b=new e,z=new e,q=new t;m.grazingAltitudeLocation=function(t,n){var i=t.origin,a=t.direction;if(!e.equals(i,e.ZERO)){var s=n.geodeticSurfaceNormal(i,I);if(e.dot(a,s)>=0)return i}var c=r(this.rayEllipsoid(t,n)),l=n.transformPositionToScaledSpace(a,I),f=e.normalize(l,l),h=e.mostOrthogonalAxis(l,w),d=e.normalize(e.cross(h,f,O),O),m=e.normalize(e.cross(f,d,M),M),p=x;p[0]=f.x,p[1]=f.y,p[2]=f.z,p[3]=d.x,p[4]=d.y,p[5]=d.z,p[6]=m.x,p[7]=m.y,p[8]=m.z;var _=u.transpose(p,P),y=u.fromScale(n.radii,U),T=u.fromScale(n.oneOverRadii,D),R=L;R[0]=0,R[1]=-a.z,R[2]=a.y,R[3]=a.z,R[4]=0,R[5]=-a.x,R[6]=-a.y,R[7]=a.x,R[8]=0;var A,S,v=u.multiply(u.multiply(_,T,F),R,F),g=u.multiply(u.multiply(v,y,B),p,B),N=u.multiplyByVector(v,i,C),G=E(g,e.negate(N,I),0,0,1),V=G.length;if(V>0){for(var X=e.clone(e.ZERO,z),W=Number.NEGATIVE_INFINITY,H=0;H<V;++H){ +A=u.multiplyByVector(y,u.multiplyByVector(p,G[H],b),b);var Y=e.normalize(e.subtract(A,i,w),w),k=e.dot(Y,a);k>W&&(W=k,X=e.clone(A,X))}var j=n.cartesianToCartographic(X,q);return W=o.clamp(W,0,1),S=e.magnitude(e.subtract(X,i,w))*Math.sqrt(1-W*W),S=c?-S:S,j.height=S,n.cartographicToCartesian(j,new e)}};var G=new e;return m.lineSegmentPlane=function(t,n,i,a){r(a)||(a=new e);var u=e.subtract(n,t,G),s=i.normal,c=e.dot(s,u);if(!(Math.abs(c)<o.EPSILON6)){var l=e.dot(s,t),f=-(i.distance+l)/c;if(!(f<0||f>1))return e.multiplyByScalar(u,f,a),e.add(t,a,a),a}},m.trianglePlaneIntersection=function(t,n,r,i){var a=i.normal,o=i.distance,u=e.dot(a,t)+o<0,s=e.dot(a,n)+o<0,c=e.dot(a,r)+o<0,l=0;l+=u?1:0,l+=s?1:0,l+=c?1:0;var f,h;if(1!==l&&2!==l||(f=new e,h=new e),1===l){if(u)return m.lineSegmentPlane(t,n,i,f),m.lineSegmentPlane(t,r,i,h),{positions:[t,n,r,f,h],indices:[0,3,4,1,2,4,1,4,3]};if(s)return m.lineSegmentPlane(n,r,i,f),m.lineSegmentPlane(n,t,i,h),{positions:[t,n,r,f,h],indices:[1,3,4,2,0,4,2,4,3]};if(c)return m.lineSegmentPlane(r,t,i,f),m.lineSegmentPlane(r,n,i,h),{positions:[t,n,r,f,h],indices:[2,3,4,0,1,4,0,4,3]}}else if(2===l){if(!u)return m.lineSegmentPlane(n,t,i,f),m.lineSegmentPlane(r,t,i,h),{positions:[t,n,r,f,h],indices:[1,2,4,1,4,3,0,3,4]};if(!s)return m.lineSegmentPlane(r,n,i,f),m.lineSegmentPlane(t,n,i,h),{positions:[t,n,r,f,h],indices:[2,0,4,2,4,3,1,3,4]};if(!c)return m.lineSegmentPlane(t,r,i,f),m.lineSegmentPlane(n,r,i,h),{positions:[t,n,r,f,h],indices:[0,1,4,0,4,3,2,3,4]}}},m}),define("Core/Plane",["./Cartesian3","./Check","./defined","./DeveloperError","./freezeObject","./Math","./Matrix4"],function(e,t,n,r,i,a,o){"use strict";function u(t,n){this.normal=e.clone(t),this.distance=n}u.fromPointNormal=function(t,r,i){var a=-e.dot(r,t);return n(i)?(e.clone(r,i.normal),i.distance=a,i):new u(r,a)};var s=new e;u.fromCartesian4=function(t,r){var i=e.fromCartesian4(t,s),a=t.w;return n(r)?(e.clone(i,r.normal),r.distance=a,r):new u(i,a)},u.getPointDistance=function(t,n){return e.dot(t.normal,n)+t.distance};var c=new e;u.projectPointOntoPlane=function(t,r,i){n(i)||(i=new e);var a=u.getPointDistance(t,r),o=e.multiplyByScalar(t.normal,a,c);return e.subtract(r,o,i)};var l=new e;return u.transform=function(t,n,r){return o.multiplyByPointAsVector(n,t.normal,s),e.normalize(s,s),e.multiplyByScalar(t.normal,-t.distance,l),o.multiplyByPoint(n,l,l),u.fromPointNormal(l,s,r)},u.clone=function(t,r){return n(r)?(e.clone(t.normal,r.normal),r.distance=t.distance,r):new u(t.normal,t.distance)},u.equals=function(t,n){return t.distance===n.distance&&e.equals(t.normal,n.normal)},u.ORIGIN_XY_PLANE=i(new u(e.UNIT_Z,0)),u.ORIGIN_YZ_PLANE=i(new u(e.UNIT_X,0)),u.ORIGIN_ZX_PLANE=i(new u(e.UNIT_Y,0)),u}),function(e){"use strict";e("ThirdParty/when",[],function(){function e(e,n,r,i){return t(e).then(n,r,i)}function t(e){var t,n;return e instanceof r?t=e:u(e)?(n=o(),e.then(function(e){n.resolve(e)},function(e){n.reject(e)},function(e){n.progress(e)}),t=n.promise):t=i(e),t}function n(t){return e(t,a)}function r(e){this.then=e}function i(e){return new r(function(n){try{return t(n?n(e):e)}catch(e){return a(e)}})}function a(e){return new r(function(n,r){try{return r?t(r(e)):a(e)}catch(e){return a(e)}})}function o(){function e(e,t,n){return h(e,t,n)}function n(e){return E(e)}function i(e){return E(a(e))}function u(e){return d(e)}var s,c,l,f,h,d,E;return c=new r(e),s={then:e,resolve:n,reject:i,progress:u,promise:c,resolver:{resolve:n,reject:i,progress:u}},l=[],f=[],h=function(e,t,n){var r,i;return r=o(),i="function"==typeof n?function(e){try{r.progress(n(e))}catch(e){r.progress(e)}}:function(e){r.progress(e)},l.push(function(n){n.then(e,t).then(r.resolve,r.reject,i)}),f.push(i),r.promise},d=function(e){return m(f,e),e},E=function(e){return e=t(e),h=e.then,E=t,d=_,m(l,e),f=l=A,e},s}function u(e){return e&&"function"==typeof e.then}function s(t,n,r,i,a){return p(2,arguments),e(t,function(t){function u(e){m(e)}function s(e){E(e)}var c,l,f,h,d,E,m,p,y,T;if(y=t.length>>>0,c=Math.max(0,Math.min(n,y)),f=[],l=y-c+1,h=[],d=o(),c)for(p=d.progress,m=function(e){h.push(e),--l||(E=m=_,d.reject(h))},E=function(e){f.push(e),--c||(E=m=_,d.resolve(f))},T=0;T<y;++T)T in t&&e(t[T],s,u,p);else d.resolve(f);return d.then(r,i,a)})}function c(e,t,n,r){function i(e){return t?t(e[0]):e[0]}return s(e,1,i,n,r)}function l(e,t,n,r){return p(1,arguments),h(e,y).then(t,n,r)}function f(){return h(arguments,y)}function h(t,n){return e(t,function(t){var r,i,a,u,s,c;if(a=i=t.length>>>0,r=[],c=o(),a)for(u=function(t,i){e(t,n).then(function(e){r[i]=e,--a||c.resolve(r)},c.reject)},s=0;s<i;s++)s in t?u(t[s],s):--a;else c.resolve(r);return c.promise})}function d(t,n){var r=R.call(arguments,1);return e(t,function(t){var i;return i=t.length,r[0]=function(t,r,a){return e(t,function(t){return e(r,function(e){return n(t,e,a,i)})})},T.apply(t,r)})}function E(t,n,r){var i=arguments.length>2;return e(t,function(e){return e=i?r:e,n.resolve(e),e},function(e){return n.reject(e),a(e)},n.progress)}function m(e,t){for(var n,r=0;n=e[r++];)n(t)}function p(e,t){for(var n,r=t.length;r>e;)if(null!=(n=t[--r])&&"function"!=typeof n)throw new Error("arg "+r+" must be a function")}function _(){}function y(e){return e}var T,R,A;return e.defer=o,e.resolve=t,e.reject=n,e.join=f,e.all=l,e.map=h,e.reduce=d,e.any=c,e.some=s,e.chain=E,e.isPromise=u,r.prototype={always:function(e,t){return this.then(e,e,t)},otherwise:function(e){return this.then(A,e)},yield:function(e){return this.then(function(){return e})},spread:function(e){return this.then(function(t){return l(t,function(t){return e.apply(A,t)})})}},R=[].slice,T=[].reduce||function(e){var t,n,r,i,a;if(a=0,t=Object(this),i=t.length>>>0,n=arguments,n.length<=1)for(;;){if(a in t){r=t[a++];break}if(++a>=i)throw new TypeError}else r=n[1];for(;a<i;++a)a in t&&(r=e(r,t[a],a,t));return r},e})}("function"==typeof define&&define.amd?define:function(e){"object"==typeof exports?module.exports=e():this.when=e()}),define("Core/binarySearch",["./Check"],function(e){"use strict";function t(e,t,n){for(var r,i,a=0,o=e.length-1;a<=o;)if(r=~~((a+o)/2),(i=n(e[r],t))<0)a=r+1;else{if(!(i>0))return r;o=r-1}return~(o+1)}return t}),define("Core/EarthOrientationParametersSample",[],function(){"use strict";function e(e,t,n,r,i){this.xPoleWander=e,this.yPoleWander=t,this.xPoleOffset=n,this.yPoleOffset=r,this.ut1MinusUtc=i}return e}),define("ThirdParty/sprintf",[],function(){function e(){var e=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g,t=arguments,n=0,r=t[n++],i=function(e,t,n,r){n||(n=" ");var i=e.length>=t?"":Array(1+t-e.length>>>0).join(n);return r?e+i:i+e},a=function(e,t,n,r,a,o){var u=r-e.length;return u>0&&(e=n||!a?i(e,r,o,n):e.slice(0,t.length)+i("",u,"0",!0)+e.slice(t.length)),e},o=function(e,t,n,r,o,u,s){var c=e>>>0;return n=n&&c&&{2:"0b",8:"0",16:"0x"}[t]||"",e=n+i(c.toString(t),u||0,"0",!1),a(e,n,r,o,s)},u=function(e,t,n,r,i,o){return null!=r&&(e=e.slice(0,r)),a(e,"",t,n,i,o)},s=function(e,r,s,c,l,f,h){var d,E,m,p,_;if("%%"==e)return"%";for(var y=!1,T="",R=!1,A=!1,S=" ",v=s.length,g=0;s&&g<v;g++)switch(s.charAt(g)){case" ":T=" ";break;case"+":T="+";break;case"-":y=!0;break;case"'":S=s.charAt(g+1);break;case"0":R=!0;break;case"#":A=!0}if(c=c?"*"==c?+t[n++]:"*"==c.charAt(0)?+t[c.slice(1,-1)]:+c:0,c<0&&(c=-c,y=!0),!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");switch(f=f?"*"==f?+t[n++]:"*"==f.charAt(0)?+t[f.slice(1,-1)]:+f:"fFeE".indexOf(h)>-1?6:"d"==h?0:void 0,_=r?t[r.slice(0,-1)]:t[n++],h){case"s":return u(String(_),y,c,f,R,S);case"c":return u(String.fromCharCode(+_),y,c,f,R);case"b":return o(_,2,A,y,c,f,R);case"o":return o(_,8,A,y,c,f,R);case"x":return o(_,16,A,y,c,f,R);case"X":return o(_,16,A,y,c,f,R).toUpperCase();case"u":return o(_,10,A,y,c,f,R);case"i":case"d":return d=+_||0,d=Math.round(d-d%1),E=d<0?"-":T,_=E+i(String(Math.abs(d)),f,"0",!1),a(_,E,y,c,R);case"e":case"E":case"f":case"F":case"g":case"G":return d=+_,E=d<0?"-":T,m=["toExponential","toFixed","toPrecision"]["efg".indexOf(h.toLowerCase())],p=["toString","toUpperCase"]["eEfFgG".indexOf(h)%2],_=E+Math.abs(d)[m](f),a(_,E,y,c,R)[p]();default:return e}};return r.replace(e,s)}return e}),define("Core/GregorianDate",[],function(){"use strict";function e(e,t,n,r,i,a,o,u){this.year=e,this.month=t,this.day=n,this.hour=r,this.minute=i,this.second=a,this.millisecond=o,this.isLeapSecond=u}return e}),define("Core/isLeapYear",["./DeveloperError"],function(e){"use strict";function t(e){return e%4==0&&e%100!=0||e%400==0}return t}),define("Core/LeapSecond",[],function(){"use strict";function e(e,t){this.julianDate=e,this.offset=t}return e}),define("Core/TimeConstants",["./freezeObject"],function(e){"use strict";return e({SECONDS_PER_MILLISECOND:.001,SECONDS_PER_MINUTE:60,MINUTES_PER_HOUR:60,HOURS_PER_DAY:24,SECONDS_PER_HOUR:3600,MINUTES_PER_DAY:1440,SECONDS_PER_DAY:86400,DAYS_PER_JULIAN_CENTURY:36525,PICOSECOND:1e-9,MODIFIED_JULIAN_DATE_DIFFERENCE:2400000.5})}),define("Core/TimeStandard",["./freezeObject"],function(e){"use strict";return e({UTC:0,TAI:1})}),define("Core/JulianDate",["../ThirdParty/sprintf","./binarySearch","./defaultValue","./defined","./DeveloperError","./GregorianDate","./isLeapYear","./LeapSecond","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return m.compare(e.julianDate,t.julianDate)}function f(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);r<0&&(r=~r),r>=n.length&&(r=n.length-1);var i=n[r].offset;if(r>0){m.secondsDifference(n[r].julianDate,e)>i&&(r--,i=n[r].offset)}m.addSeconds(e,i,e)}function h(e,n){y.julianDate=e;var r=m.leapSeconds,i=t(r,y,l);if(i<0&&(i=~i),0===i)return m.addSeconds(e,-r[0].offset,n);if(i>=r.length)return m.addSeconds(e,-r[i-1].offset,n);var a=m.secondsDifference(r[i].julianDate,e);return 0===a?m.addSeconds(e,-r[i].offset,n):a<=1?void 0:m.addSeconds(e,-r[--i].offset,n)}function d(e,t,n){var r=t/s.SECONDS_PER_DAY|0;return e+=r,t-=s.SECONDS_PER_DAY*r,t<0&&(e--,t+=s.SECONDS_PER_DAY),n.dayNumber=e,n.secondsOfDay=t,n}function E(e,t,n,r,i,a,o){var u=(t-14)/12|0,c=e+4800+u,l=(1461*c/4|0)+(367*(t-2-12*u)/12|0)-(3*((c+100)/100|0)/4|0)+n-32075;(r-=12)<0&&(r+=24);var f=a+(r*s.SECONDS_PER_HOUR+i*s.SECONDS_PER_MINUTE+o*s.SECONDS_PER_MILLISECOND);return f>=43200&&(l-=1),[l,f]}function m(e,t,r){this.dayNumber=void 0,this.secondsOfDay=void 0,e=n(e,0),t=n(t,0),r=n(r,c.UTC);var i=0|e;t+=(e-i)*s.SECONDS_PER_DAY,d(i,t,this),r===c.UTC&&f(this)}var p=new a,_=[31,28,31,30,31,30,31,31,30,31,30,31],y=new u,T=/^(\d{4})$/,R=/^(\d{4})-(\d{2})$/,A=/^(\d{4})-?(\d{3})$/,S=/^(\d{4})-?W(\d{2})-?(\d{1})?$/,v=/^(\d{4})-?(\d{2})-?(\d{2})$/,g=/([Z+\-])?(\d{2})?:?(\d{2})?$/,N=/^(\d{2})(\.\d+)?/.source+g.source,I=/^(\d{2}):?(\d{2})(\.\d+)?/.source+g.source,O=/^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source+g.source;m.fromGregorianDate=function(e,t){var n=E(e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond);return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromDate=function(e,t){var n=E(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds());return r(t)?(d(n[0],n[1],t),f(t),t):new m(n[0],n[1],c.UTC)},m.fromIso8601=function(e,t){e=e.replace(",",".");var n,i,a,u=e.split("T"),s=1,l=1,h=0,p=0,y=0,g=0,M=u[0],w=u[1];if(null!==(u=M.match(v)))n=+u[1],s=+u[2],l=+u[3];else if(null!==(u=M.match(R)))n=+u[1],s=+u[2];else if(null!==(u=M.match(T)))n=+u[1];else{var C;if(null!==(u=M.match(A)))n=+u[1],C=+u[2],a=o(n);else if(null!==(u=M.match(S))){n=+u[1];var x=+u[2],P=+u[3]||0,U=new Date(Date.UTC(n,0,4));C=7*x+P-U.getUTCDay()-3}i=new Date(Date.UTC(n,0,1)),i.setUTCDate(C),s=i.getUTCMonth()+1,l=i.getUTCDate()}a=o(n);var D;if(r(w)){u=w.match(O),null!==u?(h=+u[1],p=+u[2],y=+u[3],g=1e3*+(u[4]||0),D=5):(u=w.match(I),null!==u?(h=+u[1],p=+u[2],y=60*+(u[3]||0),D=4):null!==(u=w.match(N))&&(h=+u[1],p=60*+(u[2]||0),D=3));var L=u[D],F=+u[D+1],B=+(u[D+2]||0);switch(L){case"+":h-=F,p-=B;break;case"-":h+=F,p+=B;break;case"Z":break;default:p+=new Date(Date.UTC(n,s-1,l,h,p)).getTimezoneOffset()}}var b=60===y;for(b&&y--;p>=60;)p-=60,h++;for(;h>=24;)h-=24,l++;for(i=a&&2===s?29:_[s-1];l>i;)l-=i,s++,s>12&&(s-=12,n++),i=a&&2===s?29:_[s-1];for(;p<0;)p+=60,h--;for(;h<0;)h+=24,l--;for(;l<1;)s--,s<1&&(s+=12,n--),i=a&&2===s?29:_[s-1],l+=i;var z=E(n,s,l,h,p,y,g);return r(t)?(d(z[0],z[1],t),f(t)):t=new m(z[0],z[1],c.UTC),b&&m.addSeconds(t,1,t),t},m.now=function(e){return m.fromDate(new Date,e)};var M=new m(0,0,c.TAI);return m.toGregorianDate=function(e,t){var n=!1,i=h(e,M);r(i)||(m.addSeconds(e,-1,M),i=h(M,M),n=!0);var o=i.dayNumber,u=i.secondsOfDay;u>=43200&&(o+=1);var c=o+68569|0,l=4*c/146097|0;c=c-((146097*l+3)/4|0)|0;var f=4e3*(c+1)/1461001|0;c=c-(1461*f/4|0)+31|0;var d=80*c/2447|0,E=c-(2447*d/80|0)|0;c=d/11|0;var p=d+2-12*c|0,_=100*(l-49)+f+c|0,y=u/s.SECONDS_PER_HOUR|0,T=u-y*s.SECONDS_PER_HOUR,R=T/s.SECONDS_PER_MINUTE|0;T-=R*s.SECONDS_PER_MINUTE;var A=0|T,S=(T-A)/s.SECONDS_PER_MILLISECOND;return y+=12,y>23&&(y-=24),n&&(A+=1),r(t)?(t.year=_,t.month=p,t.day=E,t.hour=y,t.minute=R,t.second=A,t.millisecond=S,t.isLeapSecond=n,t):new a(_,p,E,y,R,A,S,n)},m.toDate=function(e){var t=m.toGregorianDate(e,p),n=t.second;return t.isLeapSecond&&(n-=1),new Date(Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,n,t.millisecond))},m.toIso8601=function(t,n){var i,a=m.toGregorianDate(t,p);return r(n)||0===a.millisecond?r(n)&&0!==n?(i=(.01*a.millisecond).toFixed(n).replace(".","").slice(0,n),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i)):e("%04d-%02d-%02dT%02d:%02d:%02dZ",a.year,a.month,a.day,a.hour,a.minute,a.second):(i=(.01*a.millisecond).toString().replace(".",""),e("%04d-%02d-%02dT%02d:%02d:%02d.%sZ",a.year,a.month,a.day,a.hour,a.minute,a.second,i))},m.clone=function(e,t){if(r(e))return r(t)?(t.dayNumber=e.dayNumber,t.secondsOfDay=e.secondsOfDay,t):new m(e.dayNumber,e.secondsOfDay,c.TAI)},m.compare=function(e,t){var n=e.dayNumber-t.dayNumber;return 0!==n?n:e.secondsOfDay-t.secondsOfDay},m.equals=function(e,t){return e===t||r(e)&&r(t)&&e.dayNumber===t.dayNumber&&e.secondsOfDay===t.secondsOfDay},m.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(m.secondsDifference(e,t))<=n},m.totalDays=function(e){return e.dayNumber+e.secondsOfDay/s.SECONDS_PER_DAY},m.secondsDifference=function(e,t){return(e.dayNumber-t.dayNumber)*s.SECONDS_PER_DAY+(e.secondsOfDay-t.secondsOfDay)},m.daysDifference=function(e,t){return e.dayNumber-t.dayNumber+(e.secondsOfDay-t.secondsOfDay)/s.SECONDS_PER_DAY},m.computeTaiMinusUtc=function(e){y.julianDate=e;var n=m.leapSeconds,r=t(n,y,l);return r<0&&(r=~r,--r<0&&(r=0)),n[r].offset},m.addSeconds=function(e,t,n){return d(e.dayNumber,e.secondsOfDay+t,n)},m.addMinutes=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_MINUTE;return d(e.dayNumber,r,n)},m.addHours=function(e,t,n){var r=e.secondsOfDay+t*s.SECONDS_PER_HOUR;return d(e.dayNumber,r,n)},m.addDays=function(e,t,n){return d(e.dayNumber+t,e.secondsOfDay,n)},m.lessThan=function(e,t){return m.compare(e,t)<0},m.lessThanOrEquals=function(e,t){return m.compare(e,t)<=0},m.greaterThan=function(e,t){return m.compare(e,t)>0},m.greaterThanOrEquals=function(e,t){return m.compare(e,t)>=0},m.prototype.clone=function(e){return m.clone(this,e)},m.prototype.equals=function(e){return m.equals(this,e)},m.prototype.equalsEpsilon=function(e,t){return m.equalsEpsilon(this,e,t)},m.prototype.toString=function(){return m.toIso8601(this)},m.leapSeconds=[new u(new m(2441317,43210,c.TAI),10),new u(new m(2441499,43211,c.TAI),11),new u(new m(2441683,43212,c.TAI),12),new u(new m(2442048,43213,c.TAI),13),new u(new m(2442413,43214,c.TAI),14),new u(new m(2442778,43215,c.TAI),15),new u(new m(2443144,43216,c.TAI),16),new u(new m(2443509,43217,c.TAI),17),new u(new m(2443874,43218,c.TAI),18),new u(new m(2444239,43219,c.TAI),19),new u(new m(2444786,43220,c.TAI),20),new u(new m(2445151,43221,c.TAI),21),new u(new m(2445516,43222,c.TAI),22),new u(new m(2446247,43223,c.TAI),23),new u(new m(2447161,43224,c.TAI),24),new u(new m(2447892,43225,c.TAI),25),new u(new m(2448257,43226,c.TAI),26),new u(new m(2448804,43227,c.TAI),27),new u(new m(2449169,43228,c.TAI),28),new u(new m(2449534,43229,c.TAI),29),new u(new m(2450083,43230,c.TAI),30),new u(new m(2450630,43231,c.TAI),31),new u(new m(2451179,43232,c.TAI),32),new u(new m(2453736,43233,c.TAI),33),new u(new m(2454832,43234,c.TAI),34),new u(new m(2456109,43235,c.TAI),35),new u(new m(2457204,43236,c.TAI),36),new u(new m(2457754,43237,c.TAI),37)],m}),define("Core/appendForwardSlash",[],function(){"use strict";function e(e){return 0!==e.length&&"/"===e[e.length-1]||(e+="/"),e}return e}),define("Core/clone",["./defaultValue"],function(e){"use strict";function t(n,r){if(null===n||"object"!=typeof n)return n;r=e(r,!1);var i=new n.constructor;for(var a in n)if(n.hasOwnProperty(a)){var o=n[a];r&&(o=t(o,r)),i[a]=o}return i}return t}),define("Core/combine",["./defaultValue","./defined"],function(e,t){"use strict";function n(r,i,a){a=e(a,!1);var o,u,s,c={},l=t(r),f=t(i);if(l)for(o in r)r.hasOwnProperty(o)&&(u=r[o],f&&a&&"object"==typeof u&&i.hasOwnProperty(o)?(s=i[o],c[o]="object"==typeof s?n(u,s,a):u):c[o]=u);if(f)for(o in i)i.hasOwnProperty(o)&&!c.hasOwnProperty(o)&&(s=i[o],c[o]=s);return c}return n}),define("Core/oneTimeWarning",["./defaultValue","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){t(i[n])||(i[n]=!0,console.warn(e(r,n)))}var i={};return r.geometryOutlines="Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.",r}),define("Core/deprecationWarning",["./defined","./DeveloperError","./oneTimeWarning"],function(e,t,n){"use strict";function r(e,t){n(e,t)}return r}),define("ThirdParty/Uri",[],function(){function e(t){if(t instanceof e)this.scheme=t.scheme,this.authority=t.authority,this.path=t.path,this.query=t.query,this.fragment=t.fragment;else if(t){var n=r.exec(t);this.scheme=n[1],this.authority=n[2],this.path=n[3],this.query=n[4],this.fragment=n[5]}}function t(e){var t=unescape(e);return a.test(t)?t:e.toUpperCase()}function n(e,t,n,r){return(t||"")+n.toLowerCase()+(r||"")}e.prototype.scheme=null,e.prototype.authority=null,e.prototype.path="",e.prototype.query=null,e.prototype.fragment=null;var r=new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$");e.prototype.getScheme=function(){return this.scheme},e.prototype.getAuthority=function(){return this.authority},e.prototype.getPath=function(){return this.path},e.prototype.getQuery=function(){return this.query},e.prototype.getFragment=function(){return this.fragment},e.prototype.isAbsolute=function(){return!!this.scheme&&!this.fragment},e.prototype.isSameDocumentAs=function(e){return e.scheme==this.scheme&&e.authority==this.authority&&e.path==this.path&&e.query==this.query},e.prototype.equals=function(e){return this.isSameDocumentAs(e)&&e.fragment==this.fragment},e.prototype.normalize=function(){this.removeDotSegments(),this.scheme&&(this.scheme=this.scheme.toLowerCase()),this.authority&&(this.authority=this.authority.replace(o,n).replace(i,t)),this.path&&(this.path=this.path.replace(i,t)),this.query&&(this.query=this.query.replace(i,t)),this.fragment&&(this.fragment=this.fragment.replace(i,t))};var i=/%[0-9a-z]{2}/gi,a=/[a-zA-Z0-9\-\._~]/,o=/(.*@)?([^@:]*)(:.*)?/;return e.prototype.resolve=function(t){var n=new e;return this.scheme?(n.scheme=this.scheme,n.authority=this.authority,n.path=this.path,n.query=this.query):(n.scheme=t.scheme,this.authority?(n.authority=this.authority,n.path=this.path,n.query=this.query):(n.authority=t.authority,""==this.path?(n.path=t.path,n.query=this.query||t.query):("/"==this.path.charAt(0)?(n.path=this.path,n.removeDotSegments()):(t.authority&&""==t.path?n.path="/"+this.path:n.path=t.path.substring(0,t.path.lastIndexOf("/")+1)+this.path,n.removeDotSegments()),n.query=this.query))),n.fragment=this.fragment,n},e.prototype.removeDotSegments=function(){var e,t=this.path.split("/"),n=[],r=""==t[0];r&&t.shift();for(""==t[0]&&t.shift();t.length;)e=t.shift(),".."==e?n.pop():"."!=e&&n.push(e);"."!=e&&".."!=e||n.push(""),r&&n.unshift(""),this.path=n.join("/")},e.prototype.toString=function(){var e="";return this.scheme&&(e+=this.scheme+":"),this.authority&&(e+="//"+this.authority),e+=this.path,this.query&&(e+="?"+this.query),this.fragment&&(e+="#"+this.fragment),e},e}),define("Core/getAbsoluteUri",["../ThirdParty/Uri","./defaultValue","./defined","./DeveloperError"],function(e,t,n,r){"use strict";function i(e,t){return i._implementation(e,t,document)}return i._implementation=function(n,r,i){r=t(r,t(i.baseURI,i.location.href));var a=new e(r);return new e(n).resolve(a).toString()},i}),define("Core/getBaseUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n,r){var i="",a=n.lastIndexOf("/");return-1!==a&&(i=n.substring(0,a+1)),r?(n=new e(n),t(n.query)&&(i+="?"+n.query),t(n.fragment)&&(i+="#"+n.fragment),i):i}return r}),define("Core/getExtensionFromUri",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(t){var n=new e(t);n.normalize();var r=n.path,i=r.lastIndexOf("/");return-1!==i&&(r=r.substr(i+1)),i=r.lastIndexOf("."),r=-1===i?"":r.substr(i+1)}return r}),define("Core/isBlobUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^blob:/i;return t}),define("Core/isCrossOriginUrl",["./defined"],function(e){"use strict";function t(t){e(n)||(n=document.createElement("a")),n.href=window.location.href;var r=n.host,i=n.protocol;return n.href=t,n.href=n.href,i!==n.protocol||r!==n.host}var n;return t}),define("Core/isDataUri",["./Check"],function(e){"use strict";function t(e){return n.test(e)}var n=/^data:/i;return t}),define("Core/isArray",["./defined"],function(e){"use strict";var t=Array.isArray;return e(t)||(t=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),t}),define("Core/objectToQuery",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(e){var t="";for(var r in e)if(e.hasOwnProperty(r)){var i=e[r],a=encodeURIComponent(r)+"=";if(n(i))for(var o=0,u=i.length;o<u;++o)t+=a+encodeURIComponent(i[o])+"&";else t+=a+encodeURIComponent(i)+"&"}return t=t.slice(0,-1)}return r}),define("Core/queryToObject",["./defined","./DeveloperError","./isArray"],function(e,t,n){"use strict";function r(t){var r={};if(""===t)return r;for(var i=t.replace(/\+/g,"%20").split(/[&;]/),a=0,o=i.length;a<o;++a){var u=i[a].split("="),s=decodeURIComponent(u[0]),c=u[1];c=e(c)?decodeURIComponent(c):"";var l=r[s];"string"==typeof l?r[s]=[l,c]:n(l)?l.push(c):r[s]=c}return r}return r}),define("Core/RequestState",["../Core/freezeObject"],function(e){"use strict";return e({UNISSUED:0,ISSUED:1,ACTIVE:2,RECEIVED:3,CANCELLED:4,FAILED:5})}),define("Core/RequestType",["../Core/freezeObject"],function(e){"use strict";return e({TERRAIN:0,IMAGERY:1,TILES3D:2,OTHER:3})}),define("Core/Request",["./defaultValue","./defined","./RequestState","./RequestType"],function(e,t,n,r){"use strict";function i(t){t=e(t,e.EMPTY_OBJECT);var i=e(t.throttleByServer,!1),a=i||e(t.throttle,!1);this.url=t.url,this.requestFunction=t.requestFunction,this.cancelFunction=t.cancelFunction,this.priorityFunction=t.priorityFunction,this.priority=e(t.priority,0),this.throttle=a,this.throttleByServer=i,this.type=e(t.type,r.OTHER),this.serverKey=void 0,this.state=n.UNISSUED,this.deferred=void 0,this.cancelled=!1}return i.prototype.cancel=function(){this.cancelled=!0},i.prototype.clone=function(e){return t(e)?(e.url=this.url,e.requestFunction=this.requestFunction,e.cancelFunction=this.cancelFunction,e.priorityFunction=this.priorityFunction,e.priority=this.priority,e.throttle=this.throttle,e.throttleByServer=this.throttleByServer,e.type=this.type,e.serverKey=this.serverKey,e.state=this.RequestState.UNISSUED,e.deferred=void 0,e.cancelled=!1,e):new i(this)},i}),define("Core/parseResponseHeaders",[],function(){"use strict";function e(e){var t={};if(!e)return t;for(var n=e.split("\r\n"),r=0;r<n.length;++r){var i=n[r],a=i.indexOf(": ");if(a>0){var o=i.substring(0,a),u=i.substring(a+2);t[o]=u}}return t}return e}),define("Core/RequestErrorEvent",["./defined","./parseResponseHeaders"],function(e,t){"use strict";function n(e,n,r){this.statusCode=e,this.response=n,this.responseHeaders=r,"string"==typeof this.responseHeaders&&(this.responseHeaders=t(this.responseHeaders))}return n.prototype.toString=function(){var t="Request has failed.";return e(this.statusCode)&&(t+=" Status Code: "+this.statusCode),t},n}),define("Core/Event",["./Check","./defined","./defineProperties"],function(e,t,n){"use strict";function r(){this._listeners=[],this._scopes=[],this._toRemove=[],this._insideRaiseEvent=!1}function i(e,t){return t-e}return n(r.prototype,{numberOfListeners:{get:function(){return this._listeners.length-this._toRemove.length}}}),r.prototype.addEventListener=function(e,t){this._listeners.push(e),this._scopes.push(t);var n=this;return function(){n.removeEventListener(e,t)}},r.prototype.removeEventListener=function(e,t){for(var n=this._listeners,r=this._scopes,i=-1,a=0;a<n.length;a++)if(n[a]===e&&r[a]===t){i=a;break}return-1!==i&&(this._insideRaiseEvent?(this._toRemove.push(i),n[i]=void 0,r[i]=void 0):(n.splice(i,1),r.splice(i,1)),!0)},r.prototype.raiseEvent=function(){this._insideRaiseEvent=!0;var e,n=this._listeners,r=this._scopes,a=n.length;for(e=0;e<a;e++){var o=n[e];t(o)&&n[e].apply(r[e],arguments)}var u=this._toRemove;if((a=u.length)>0){for(u.sort(i),e=0;e<a;e++){var s=u[e];n.splice(s,1),r.splice(s,1)}u.length=0}this._insideRaiseEvent=!1},r}),define("Core/Heap",["./Check","./defaultValue","./defined","./defineProperties"],function(e,t,n,r){"use strict";function i(e){this._comparator=e.comparator,this._array=[],this._length=0,this._maximumLength=void 0}function a(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}return r(i.prototype,{length:{get:function(){return this._length}},internalArray:{get:function(){return this._array}},maximumLength:{get:function(){return this._maximumLength},set:function(e){this._maximumLength=e,this._length>e&&e>0&&(this._length=e,this._array.length=e)}},comparator:{get:function(){return this._comparator}}}),i.prototype.reserve=function(e){e=t(e,this._length),this._array.length=e},i.prototype.heapify=function(e){e=t(e,0);for(var n=this._length,r=this._comparator,i=this._array,o=-1,u=!0;u;){var s=2*(e+1),c=s-1;o=c<n&&r(i[c],i[e])<0?c:e,s<n&&r(i[s],i[o])<0&&(o=s),o!==e?(a(i,o,e),e=o):u=!1}},i.prototype.resort=function(){for(var e=this._length,t=Math.ceil(e/2);t>=0;--t)this.heapify(t)},i.prototype.insert=function(e){var t=this._array,r=this._comparator,i=this._maximumLength,o=this._length++;for(o<t.length?t[o]=e:t.push(e);0!==o;){var u=Math.floor((o-1)/2);if(!(r(t[o],t[u])<0))break;a(t,o,u),o=u}var s;return n(i)&&this._length>i&&(s=t[i],this._length=i),s},i.prototype.pop=function(e){if(e=t(e,0),0!==this._length){var n=this._array,r=n[e];return a(n,e,--this._length),this.heapify(e),r}},i}),define("Core/RequestScheduler",["../ThirdParty/Uri","../ThirdParty/when","./Check","./defined","./defineProperties","./Event","./Heap","./isBlobUri","./isDataUri","./RequestState"],function(e,t,n,r,i,a,o,u,s,c){"use strict";function l(e,t){return e.priority-t.priority}function f(){}function h(e){r(e.priorityFunction)&&(e.priority=e.priorityFunction())}function d(e){return N[e]<f.maximumRequestsPerServer}function E(e){return e.state===c.UNISSUED&&(e.state=c.ISSUED,e.deferred=t.defer()),e.deferred.promise}function m(e){return function(t){e.state!==c.CANCELLED&&(--A.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(),e.state=c.RECEIVED,e.deferred.resolve(t))}}function p(e){return function(t){e.state!==c.CANCELLED&&(++A.numberOfFailedRequests,--A.numberOfActiveRequests,--N[e.serverKey],O.raiseEvent(t),e.state=c.FAILED,e.deferred.reject(t))}}function _(e){var t=E(e);return e.state=c.ACTIVE,g.push(e),++A.numberOfActiveRequests,++A.numberOfActiveRequestsEver,++N[e.serverKey],e.requestFunction().then(m(e)).otherwise(p(e)),t}function y(e){var t=e.state===c.ACTIVE;e.state=c.CANCELLED,++A.numberOfCancelledRequests,e.deferred.reject(),t&&(--A.numberOfActiveRequests,--N[e.serverKey],++A.numberOfCancelledActiveRequests),r(e.cancelFunction)&&e.cancelFunction()}function T(){A.numberOfAttemptedRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0}function R(){f.debugShowStatistics&&(A.numberOfAttemptedRequests>0&&console.log("Number of attempted requests: "+A.numberOfAttemptedRequests),A.numberOfActiveRequests>0&&console.log("Number of active requests: "+A.numberOfActiveRequests),A.numberOfCancelledRequests>0&&console.log("Number of cancelled requests: "+A.numberOfCancelledRequests),A.numberOfCancelledActiveRequests>0&&console.log("Number of cancelled active requests: "+A.numberOfCancelledActiveRequests),A.numberOfFailedRequests>0&&console.log("Number of failed requests: "+A.numberOfFailedRequests),T())}var A={numberOfAttemptedRequests:0,numberOfActiveRequests:0,numberOfCancelledRequests:0,numberOfCancelledActiveRequests:0,numberOfFailedRequests:0,numberOfActiveRequestsEver:0},S=20,v=new o({comparator:l});v.maximumLength=S,v.reserve(S);var g=[],N={},I="undefined"!=typeof document?new e(document.location.href):new e,O=new a;return f.maximumRequests=50,f.maximumRequestsPerServer=6,f.throttleRequests=!0,f.debugShowStatistics=!1,f.requestCompletedEvent=O,i(f,{statistics:{get:function(){return A}},priorityHeapLength:{get:function(){return S},set:function(e){if(e<S)for(;v.length>e;){var t=v.pop();y(t)}S=e,v.maximumLength=e,v.reserve(e)}}}),f.update=function(){var e,t,n=0,r=g.length;for(e=0;e<r;++e)t=g[e],t.cancelled&&y(t),t.state===c.ACTIVE?n>0&&(g[e-n]=t):++n;g.length-=n;var i=v.internalArray,a=v.length;for(e=0;e<a;++e)h(i[e]);v.resort();for(var o=Math.max(f.maximumRequests-g.length,0),u=0;u<o&&v.length>0;)t=v.pop(),t.cancelled?y(t):!t.throttleByServer||d(t.serverKey)?(_(t),++u):y(t);R()},f.getServerKey=function(t){var n=new e(t).resolve(I);n.normalize();var i=n.authority;/:/.test(i)||(i=i+":"+("https"===n.scheme?"443":"80"));var a=N[i];return r(a)||(N[i]=0),i},f.request=function(e){if(s(e.url)||u(e.url))return O.raiseEvent(),e.state=c.RECEIVED,e.requestFunction();if(++A.numberOfAttemptedRequests,r(e.serverKey)||(e.serverKey=f.getServerKey(e.url)),!f.throttleRequests||!e.throttle)return _(e);if(!(g.length>=f.maximumRequests)&&(!e.throttleByServer||d(e.serverKey))){h(e);var t=v.insert(e);if(r(t)){if(t===e)return;y(t)}return E(e)}},f.clearForSpecs=function(){for(;v.length>0;){y(v.pop())}for(var e=g.length,t=0;t<e;++t)y(g[t]);g.length=0,N={},A.numberOfAttemptedRequests=0,A.numberOfActiveRequests=0,A.numberOfCancelledRequests=0,A.numberOfCancelledActiveRequests=0,A.numberOfFailedRequests=0,A.numberOfActiveRequestsEver=0},f.numberOfActiveRequestsByServer=function(e){return N[e]},f.requestHeap=v,f}),define("Core/TrustedServers",["../ThirdParty/Uri","./defined","./DeveloperError"],function(e,t,n){"use strict";function r(n){var r=new e(n);r.normalize();var i=r.getAuthority();if(t(i)){if(-1!==i.indexOf("@")){i=i.split("@")[1]}if(-1===i.indexOf(":")){var a=r.getScheme();if(t(a)||(a=window.location.protocol,a=a.substring(0,a.length-1)),"http"===a)i+=":80";else{if("https"!==a)return;i+=":443"}}return i}}var i={},a={};return i.add=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])||(a[r]=!0)},i.remove=function(e,n){var r=e.toLowerCase()+":"+n;t(a[r])&&delete a[r]},i.contains=function(e){var n=r(e);return!(!t(n)||!t(a[n]))},i.clear=function(){a={}},i}), +define("Core/Resource",["./appendForwardSlash","./Check","./clone","./combine","./defaultValue","./defined","./defineProperties","./deprecationWarning","./DeveloperError","./freezeObject","./getAbsoluteUri","./getBaseUri","./getExtensionFromUri","./isBlobUri","./isCrossOriginUrl","./isDataUri","./objectToQuery","./queryToObject","./Request","./RequestErrorEvent","./RequestScheduler","./RequestState","./RuntimeError","./TrustedServers","../ThirdParty/Uri","../ThirdParty/when"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,p,_,y,T,R,A,S,v,g,N){"use strict";function I(e,t){var n=e.query;if(!a(n)||0===n.length)return{};var i;if(-1===n.indexOf("=")){var o={};o[n]=void 0,i=o}else i=_(n);t._queryParameters=r(t._queryParameters,i),e.query=void 0}function O(e,t){var n=t._queryParameters,r=Object.keys(n);1!==r.length||a(n[r[0]])?e.query=p(n):e.query=r[0]}function M(e,t){return a(e)?a(e.clone)?e.clone():n(e):t}function w(e){if(e.state===A.ISSUED||e.state===A.ACTIVE)throw new S("The Resource is already being fetched.");e.state=A.UNISSUED,e.deferred=void 0}function C(e){e=i(e,i.EMPTY_OBJECT),"string"==typeof e&&(e={url:e}),this._url=void 0,this._templateValues=M(e.templateValues,{}),this._queryParameters=M(e.queryParameters,{}),this.headers=M(e.headers,{}),this.request=i(e.request,new y),this.proxy=e.proxy,this.retryCallback=e.retryCallback,this.retryAttempts=i(e.retryAttempts,0),this._retryCount=0,this.url=e.url}function x(e,t){var n=e.request;n.url=e.url,n.requestFunction=function(){var n=e.url,r=!1;e.isDataUri||e.isBlobUri||(r=e.isCrossOriginUrl);var i=N.defer();return C._Implementations.createImage(n,r&&t,i),i.promise};var r=R.request(n);if(a(r))return r.otherwise(function(r){return n.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=A.UNISSUED,n.deferred=void 0,x(e,t)):N.reject(r)})})}function P(e,t,n){var r={};r[t]=n,e.addQueryParameters(r);var i=e.request;i.url=e.url,i.requestFunction=function(){var t=N.defer();return window[n]=function(e){t.resolve(e);try{delete window[n]}catch(e){window[n]=void 0}},C._Implementations.loadAndExecuteScript(e.url,n,t),t.promise};var o=R.request(i);if(a(o))return o.otherwise(function(r){return i.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(a){return a?(i.state=A.UNISSUED,i.deferred=void 0,P(e,t,n)):N.reject(r)})})}function U(e,t){w(e.request);var n=e.request;n.url=e.url,n.requestFunction=function(){var i=t.responseType,o=r(e.headers,t.headers),u=t.overrideMimeType,s=t.method,c=t.data,l=N.defer(),f=C._Implementations.loadWithXhr(e.url,i,s,c,o,l,u);return a(f)&&a(f.abort)&&(n.cancelFunction=function(){f.abort()}),l.promise};var i=R.request(n);if(a(i))return i.then(function(e){return e}).otherwise(function(r){return n.state!==A.FAILED?N.reject(r):e.retryOnError(r).then(function(i){return i?(n.state=A.UNISSUED,n.deferred=void 0,e.fetch(t)):N.reject(r)})})}function D(e,t){var n=decodeURIComponent(t);return e?atob(n):n}function L(e,t){for(var n=D(e,t),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return r}function F(e,t){t=i(t,"");var n=e[1],r=!!e[2],a=e[3];switch(t){case"":case"text":return D(r,a);case"arraybuffer":return L(r,a);case"blob":var o=L(r,a);return new Blob([o],{type:n});case"document":return(new DOMParser).parseFromString(D(r,a),n);case"json":return JSON.parse(D(r,a))}}var B=function(){try{var e=new XMLHttpRequest;return e.open("GET","#",!0),e.responseType="blob","blob"===e.responseType}catch(e){return!1}}();C.createIfNeeded=function(e,t){if(e instanceof C)return e.clone();if("string"!=typeof e)return e;var n=M(t,{});return n.url=e,new C(n)},o(C,{isBlobSupported:{get:function(){return B}}}),o(C.prototype,{queryParameters:{get:function(){return this._queryParameters}},templateValues:{get:function(){return this._templateValues}},url:{get:function(){return this.getUrlComponent(!0,!0)},set:function(e){var t=new g(e);I(t,this),t.fragment=void 0,this._url=t.toString()}},extension:{get:function(){return h(this._url)}},isDataUri:{get:function(){return m(this._url)}},isBlobUri:{get:function(){return d(this._url)}},isCrossOriginUrl:{get:function(){return E(this._url)}},hasHeaders:{get:function(){return Object.keys(this.headers).length>0}}}),C.prototype.getUrlComponent=function(e,t){if(this.isDataUri)return this._url;var n=new g(this._url);e&&O(n,this);var r=n.toString().replace(/%7B/g,"{").replace(/%7D/g,"}"),i=this._templateValues,o=Object.keys(i);if(o.length>0)for(var u=0;u<o.length;u++){var s=o[u],c=i[s];r=r.replace(new RegExp("{"+s+"}","g"),encodeURIComponent(c))}return t&&a(this.proxy)&&(r=this.proxy.getURL(r)),r},C.prototype.addQueryParameters=function(e,t){this._queryParameters=t?r(this._queryParameters,e):r(e,this._queryParameters)},C.prototype.addTemplateValues=function(e,t){this._templateValues=t?r(this._templateValues,e):r(e,this._templateValues)},C.prototype.getDerivedResource=function(e){var t=this.clone();if(t._retryCount=0,a(e.url)){var n=new g(e.url);I(n,t),n.fragment=void 0,t._url=n.resolve(new g(l(this._url))).toString()}return a(e.queryParameters)&&(t._queryParameters=r(e.queryParameters,t._queryParameters)),a(e.templateValues)&&(t._templateValues=r(e.templateValues,t.templateValues)),a(e.headers)&&(t.headers=r(e.headers,t.headers)),a(e.proxy)&&(t.proxy=e.proxy),a(e.request)?t.request=e.request:t.request=this.request.clone(),a(e.retryCallback)&&(t.retryCallback=e.retryCallback),a(e.retryAttempts)&&(t.retryAttempts=e.retryAttempts),t},C.prototype.retryOnError=function(e){var t=this.retryCallback;if("function"!=typeof t||this._retryCount>=this.retryAttempts)return N(!1);var n=this;return N(t(this,e)).then(function(e){return++n._retryCount,e})},C.prototype.clone=function(e){return a(e)||(e=new C({url:this._url})),e._url=this._url,e._queryParameters=n(this._queryParameters),e._templateValues=n(this._templateValues),e.headers=n(this.headers),e.proxy=this.proxy,e.retryCallback=this.retryCallback,e.retryAttempts=this.retryAttempts,e._retryCount=0,e.request=this.request,e},C.prototype.getBaseUri=function(e){return f(this.getUrlComponent(e),e)},C.prototype.appendForwardSlash=function(){this._url=e(this._url)},C.prototype.fetchArrayBuffer=function(){return this.fetch({responseType:"arraybuffer"})},C.fetchArrayBuffer=function(e){return new C(e).fetchArrayBuffer()},C.prototype.fetchBlob=function(){return this.fetch({responseType:"blob"})},C.fetchBlob=function(e){return new C(e).fetchBlob()},C.prototype.fetchImage=function(e,t){if(a(t)&&u("Resource.fetchImage.allowCrossOrigin","The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified."),e=i(e,!1),t=i(t,!0),w(this.request),!B||this.isDataUri||this.isBlobUri||!this.hasHeaders&&!e)return x(this,t);var n=this.fetchBlob();if(a(n)){var r,o;return n.then(function(e){if(a(e)){o=e;var t=window.URL.createObjectURL(e);return r=new C({url:t}),x(r)}}).then(function(e){if(a(e))return window.URL.revokeObjectURL(r.url),e.blob=o,e}).otherwise(function(e){return a(r)&&window.URL.revokeObjectURL(r.url),N.reject(e)})}},C.fetchImage=function(e){return new C(e).fetchImage(e.preferBlob,e.allowCrossOrigin)},C.prototype.fetchText=function(){return this.fetch({responseType:"text"})},C.fetchText=function(e){return new C(e).fetchText()},C.prototype.fetchJson=function(){var e=this.fetch({responseType:"text",headers:{Accept:"application/json,*/*;q=0.01"}});if(a(e))return e.then(function(e){if(a(e))return JSON.parse(e)})},C.fetchJson=function(e){return new C(e).fetchJson()},C.prototype.fetchXML=function(){return this.fetch({responseType:"document",overrideMimeType:"text/xml"})},C.fetchXML=function(e){return new C(e).fetchXML()},C.prototype.fetchJsonp=function(e){e=i(e,"callback"),w(this.request);var t;do{t="loadJsonp"+Math.random().toString().substring(2,8)}while(a(window[t]));return P(this,e,t)},C.fetchJsonp=function(e){return new C(e).fetchJsonp(e.callbackParameterName)},C.prototype.fetch=function(e){return e=M(e,i.EMPTY_OBJECT),e.method="GET",U(this,e)};var b=/^data:(.*?)(;base64)?,(.*)$/;return C.fetch=function(e){return new C(e).fetch({responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C.prototype.post=function(e,n){return t.defined("data",e),n=M(n,{}),n.method="POST",n.data=e,U(this,n)},C.post=function(e){return new C(e).post(e.data,{responseType:e.responseType,overrideMimeType:e.overrideMimeType})},C._Implementations={},C._Implementations.createImage=function(e,t,n){var r=new Image;r.onload=function(){n.resolve(r)},r.onerror=function(e){n.reject(e)},t&&(v.contains(e)?r.crossOrigin="use-credentials":r.crossOrigin=""),r.src=e},C._Implementations.loadWithXhr=function(e,t,n,r,i,o,u){var s=b.exec(e);if(null!==s)return void o.resolve(F(s,t));var c=new XMLHttpRequest;if(v.contains(e)&&(c.withCredentials=!0),a(u)&&a(c.overrideMimeType)&&c.overrideMimeType(u),c.open(n,e,!0),a(i))for(var l in i)i.hasOwnProperty(l)&&c.setRequestHeader(l,i[l]);a(t)&&(c.responseType=t);var f=!1;return"string"==typeof e&&(f=0===e.indexOf("file://")),c.onload=function(){if((c.status<200||c.status>=300)&&(!f||0!==c.status))return void o.reject(new T(c.status,c.response,c.getAllResponseHeaders()));var e=c.response,n=c.responseType;if(204===c.status)o.resolve();else if(!a(e)||a(t)&&n!==t)if("json"===t&&"string"==typeof e)try{o.resolve(JSON.parse(e))}catch(e){o.reject(e)}else(""===n||"document"===n)&&a(c.responseXML)&&c.responseXML.hasChildNodes()?o.resolve(c.responseXML):""!==n&&"text"!==n||!a(c.responseText)?o.reject(new S("Invalid XMLHttpRequest response type.")):o.resolve(c.responseText);else o.resolve(e)},c.onerror=function(e){o.reject(new T)},c.send(r),c},C._Implementations.loadAndExecuteScript=function(e,t,n){var r=document.createElement("script");r.async=!0,r.src=e;var i=document.getElementsByTagName("head")[0];r.onload=function(){r.onload=void 0,i.removeChild(r)},r.onerror=function(e){n.reject(e)},i.appendChild(r)},C._DefaultImplementations={},C._DefaultImplementations.createImage=C._Implementations.createImage,C._DefaultImplementations.loadWithXhr=C._Implementations.loadWithXhr,C._DefaultImplementations.loadAndExecuteScript=C._Implementations.loadAndExecuteScript,C.DEFAULT=c(new C({url:"undefined"==typeof document?"":document.location.href.split("?")[0]})),C}),define("Core/EarthOrientationParameters",["../ThirdParty/when","./binarySearch","./defaultValue","./defined","./EarthOrientationParametersSample","./freezeObject","./JulianDate","./LeapSecond","./Resource","./RuntimeError","./TimeConstants","./TimeStandard"],function(e,t,n,r,i,a,o,u,s,c,l,f){"use strict";function h(t){if(t=n(t,n.EMPTY_OBJECT),this._dates=void 0,this._samples=void 0,this._dateColumn=-1,this._xPoleWanderRadiansColumn=-1,this._yPoleWanderRadiansColumn=-1,this._ut1MinusUtcSecondsColumn=-1,this._xCelestialPoleOffsetRadiansColumn=-1,this._yCelestialPoleOffsetRadiansColumn=-1,this._taiMinusUtcSecondsColumn=-1,this._columnCount=0,this._lastIndex=-1,this._downloadPromise=void 0,this._dataError=void 0,this._addNewLeapSeconds=n(t.addNewLeapSeconds,!0),r(t.data))E(this,t.data);else if(r(t.url)){var i=s.createIfNeeded(t.url),a=this;this._downloadPromise=e(i.fetchJson(),function(e){E(a,e)},function(){a._dataError="An error occurred while retrieving the EOP data from the URL "+i.url+"."})}else E(this,{columnNames:["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"],samples:[]})}function d(e,t){return o.compare(e.julianDate,t)}function E(e,n){if(!r(n.columnNames))return void(e._dataError="Error in loaded EOP data: The columnNames property is required.");if(!r(n.samples))return void(e._dataError="Error in loaded EOP data: The samples property is required.");var i=n.columnNames.indexOf("modifiedJulianDateUtc"),a=n.columnNames.indexOf("xPoleWanderRadians"),s=n.columnNames.indexOf("yPoleWanderRadians"),c=n.columnNames.indexOf("ut1MinusUtcSeconds"),h=n.columnNames.indexOf("xCelestialPoleOffsetRadians"),E=n.columnNames.indexOf("yCelestialPoleOffsetRadians"),m=n.columnNames.indexOf("taiMinusUtcSeconds");if(i<0||a<0||s<0||c<0||h<0||E<0||m<0)return void(e._dataError="Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns");var p=e._samples=n.samples,_=e._dates=[];e._dateColumn=i,e._xPoleWanderRadiansColumn=a,e._yPoleWanderRadiansColumn=s,e._ut1MinusUtcSecondsColumn=c,e._xCelestialPoleOffsetRadiansColumn=h,e._yCelestialPoleOffsetRadiansColumn=E,e._taiMinusUtcSecondsColumn=m,e._columnCount=n.columnNames.length,e._lastIndex=void 0;for(var y,T=e._addNewLeapSeconds,R=0,A=p.length;R<A;R+=e._columnCount){var S=p[R+i],v=p[R+m],g=S+l.MODIFIED_JULIAN_DATE_DIFFERENCE,N=new o(g,v,f.TAI);if(_.push(N),T){if(v!==y&&r(y)){var I=o.leapSeconds,O=t(I,N,d);if(O<0){var M=new u(N,v);I.splice(~O,0,M)}}y=v}}}function m(e,t,n,r,i){var a=n*r;i.xPoleWander=t[a+e._xPoleWanderRadiansColumn],i.yPoleWander=t[a+e._yPoleWanderRadiansColumn],i.xPoleOffset=t[a+e._xCelestialPoleOffsetRadiansColumn],i.yPoleOffset=t[a+e._yCelestialPoleOffsetRadiansColumn],i.ut1MinusUtc=t[a+e._ut1MinusUtcSecondsColumn]}function p(e,t,n){return t+e*(n-t)}function _(e,t,n,r,i,a,u){var s=e._columnCount;if(a>t.length-1)return u.xPoleWander=0,u.yPoleWander=0,u.xPoleOffset=0,u.yPoleOffset=0,u.ut1MinusUtc=0,u;var c=t[i],l=t[a];if(c.equals(l)||r.equals(c))return m(e,n,i,s,u),u;if(r.equals(l))return m(e,n,a,s,u),u;var f=o.secondsDifference(r,c)/o.secondsDifference(l,c),h=i*s,d=a*s,E=n[h+e._ut1MinusUtcSecondsColumn],_=n[d+e._ut1MinusUtcSecondsColumn],y=_-E;if(y>.5||y<-.5){var T=n[h+e._taiMinusUtcSecondsColumn],R=n[d+e._taiMinusUtcSecondsColumn];T!==R&&(l.equals(r)?E=_:_-=R-T)}return u.xPoleWander=p(f,n[h+e._xPoleWanderRadiansColumn],n[d+e._xPoleWanderRadiansColumn]),u.yPoleWander=p(f,n[h+e._yPoleWanderRadiansColumn],n[d+e._yPoleWanderRadiansColumn]),u.xPoleOffset=p(f,n[h+e._xCelestialPoleOffsetRadiansColumn],n[d+e._xCelestialPoleOffsetRadiansColumn]),u.yPoleOffset=p(f,n[h+e._yCelestialPoleOffsetRadiansColumn],n[d+e._yCelestialPoleOffsetRadiansColumn]),u.ut1MinusUtc=p(f,E,_),u}return h.NONE=a({getPromiseToLoad:function(){return e()},compute:function(e,t){return r(t)?(t.xPoleWander=0,t.yPoleWander=0,t.xPoleOffset=0,t.yPoleOffset=0,t.ut1MinusUtc=0):t=new i(0,0,0,0,0),t}}),h.prototype.getPromiseToLoad=function(){return e(this._downloadPromise)},h.prototype.compute=function(e,n){if(r(this._samples)){if(r(n)||(n=new i(0,0,0,0,0)),0===this._samples.length)return n.xPoleWander=0,n.yPoleWander=0,n.xPoleOffset=0,n.yPoleOffset=0,n.ut1MinusUtc=0,n;var a=this._dates,u=this._lastIndex,s=0,l=0;if(r(u)){var f=a[u],h=a[u+1],d=o.lessThanOrEquals(f,e),E=!r(h),m=E||o.greaterThanOrEquals(h,e);if(d&&m)return s=u,!E&&h.equals(e)&&++s,l=s+1,_(this,a,this._samples,e,s,l,n),n}var p=t(a,e,o.compare,this._dateColumn);return p>=0?(p<a.length-1&&a[p+1].equals(e)&&++p,s=p,l=p):(l=~p,(s=l-1)<0&&(s=0)),this._lastIndex=s,_(this,a,this._samples,e,s,l,n),n}if(r(this._dataError))throw new c(this._dataError)},h}),define("Core/buildModuleUrl",["../ThirdParty/Uri","./defined","./DeveloperError","./Resource","require"],function(e,t,n,r,i){"use strict";function a(){for(var e=document.getElementsByTagName("script"),t=0,n=e.length;t<n;++t){var r=e[t].getAttribute("src"),i=d.exec(r);if(null!==i)return i[1]}}function o(){if(t(l))return l;var e;return e="undefined"!=typeof CESIUM_BASE_URL?CESIUM_BASE_URL:a(),l=new r({url:e})}function u(e){return i.toUrl("../"+e)}function s(e){return o().getDerivedResource({url:e}).url}function c(e){t(f)||(f=t(define.amd)&&!define.amd.toUrlUndefined&&t(i.toUrl)?u:s),t(h)||(h=document.createElement("a"));var n=f(e);return h.href=n,h.href=h.href,h.href}var l,f,h,d=/((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i;return c._cesiumScriptRegex=d,c.setBaseUrl=function(e){l=r.DEFAULT.getDerivedResource({url:e})},c}),define("Core/Iau2006XysSample",[],function(){"use strict";function e(e,t,n){this.x=e,this.y=t,this.s=n}return e}),define("Core/Iau2006XysData",["../ThirdParty/when","./buildModuleUrl","./defaultValue","./defined","./Iau2006XysSample","./JulianDate","./Resource","./TimeStandard"],function(e,t,n,r,i,a,o,u){"use strict";function s(e){e=n(e,n.EMPTY_OBJECT),this._xysFileUrlTemplate=o.createIfNeeded(e.xysFileUrlTemplate),this._interpolationOrder=n(e.interpolationOrder,9),this._sampleZeroJulianEphemerisDate=n(e.sampleZeroJulianEphemerisDate,2442396.5),this._sampleZeroDateTT=new a(this._sampleZeroJulianEphemerisDate,0,u.TAI),this._stepSizeDays=n(e.stepSizeDays,1),this._samplesPerXysFile=n(e.samplesPerXysFile,1e3),this._totalSamples=n(e.totalSamples,27426),this._samples=new Array(3*this._totalSamples),this._chunkDownloadsInProgress=[];for(var t=this._interpolationOrder,r=this._denominators=new Array(t+1),i=this._xTable=new Array(t+1),s=Math.pow(this._stepSizeDays,t),c=0;c<=t;++c){r[c]=s,i[c]=c*this._stepSizeDays;for(var l=0;l<=t;++l)l!==c&&(r[c]*=c-l);r[c]=1/r[c]}this._work=new Array(t+1),this._coef=new Array(t+1)}function c(e,t,n){var r=f;return r.dayNumber=t,r.secondsOfDay=n,a.daysDifference(r,e._sampleZeroDateTT)}function l(n,i){if(n._chunkDownloadsInProgress[i])return n._chunkDownloadsInProgress[i];var a=e.defer();n._chunkDownloadsInProgress[i]=a;var u,s=n._xysFileUrlTemplate;return u=r(s)?s.getDerivedResource({templateValues:{0:i}}):new o({url:t("Assets/IAU2006_XYS/IAU2006_XYS_"+i+".json")}),e(u.fetchJson(),function(e){n._chunkDownloadsInProgress[i]=!1;for(var t=n._samples,r=e.samples,o=i*n._samplesPerXysFile*3,u=0,s=r.length;u<s;++u)t[o+u]=r[u];a.resolve()}),a.promise}var f=new a(0,0,u.TAI);return s.prototype.preload=function(t,n,r,i){var a=c(this,t,n),o=c(this,r,i),u=a/this._stepSizeDays-this._interpolationOrder/2|0;u<0&&(u=0);var s=o/this._stepSizeDays-this._interpolationOrder/2|0+this._interpolationOrder;s>=this._totalSamples&&(s=this._totalSamples-1);for(var f=u/this._samplesPerXysFile|0,h=s/this._samplesPerXysFile|0,d=[],E=f;E<=h;++E)d.push(l(this,E));return e.all(d)},s.prototype.computeXysRadians=function(e,t,n){var a=c(this,e,t);if(!(a<0)){var o=a/this._stepSizeDays|0;if(!(o>=this._totalSamples)){var u=this._interpolationOrder,s=o-(u/2|0);s<0&&(s=0);var f=s+u;f>=this._totalSamples&&(f=this._totalSamples-1,(s=f-u)<0&&(s=0));var h=!1,d=this._samples;if(r(d[3*s])||(l(this,s/this._samplesPerXysFile|0),h=!0),r(d[3*f])||(l(this,f/this._samplesPerXysFile|0),h=!0),!h){r(n)?(n.x=0,n.y=0,n.s=0):n=new i(0,0,0);var E,m,p=a-s*this._stepSizeDays,_=this._work,y=this._denominators,T=this._coef,R=this._xTable;for(E=0;E<=u;++E)_[E]=p-R[E];for(E=0;E<=u;++E){for(T[E]=1,m=0;m<=u;++m)m!==E&&(T[E]*=_[m]);T[E]*=y[E];var A=3*(s+E);n.x+=T[E]*d[A++],n.y+=T[E]*d[A++],n.s+=T[E]*d[A]}return n}}}},s}),define("Core/Fullscreen",["./defined","./defineProperties"],function(e,t){"use strict";var n,r={requestFullscreen:void 0,exitFullscreen:void 0,fullscreenEnabled:void 0,fullscreenElement:void 0,fullscreenchange:void 0,fullscreenerror:void 0},i={};return t(i,{element:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenElement]}},changeEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenchange}},errorEventName:{get:function(){if(i.supportsFullscreen())return r.fullscreenerror}},enabled:{get:function(){if(i.supportsFullscreen())return document[r.fullscreenEnabled]}},fullscreen:{get:function(){if(i.supportsFullscreen())return null!==i.element}}}),i.supportsFullscreen=function(){if(e(n))return n;n=!1;var t=document.body;if("function"==typeof t.requestFullscreen)return r.requestFullscreen="requestFullscreen",r.exitFullscreen="exitFullscreen",r.fullscreenEnabled="fullscreenEnabled",r.fullscreenElement="fullscreenElement",r.fullscreenchange="fullscreenchange",r.fullscreenerror="fullscreenerror",n=!0;for(var i,a=["webkit","moz","o","ms","khtml"],o=0,u=a.length;o<u;++o){var s=a[o];i=s+"RequestFullscreen","function"==typeof t[i]?(r.requestFullscreen=i,n=!0):(i=s+"RequestFullScreen","function"==typeof t[i]&&(r.requestFullscreen=i,n=!0)),i=s+"ExitFullscreen","function"==typeof document[i]?r.exitFullscreen=i:(i=s+"CancelFullScreen","function"==typeof document[i]&&(r.exitFullscreen=i)),i=s+"FullscreenEnabled",void 0!==document[i]?r.fullscreenEnabled=i:(i=s+"FullScreenEnabled",void 0!==document[i]&&(r.fullscreenEnabled=i)),i=s+"FullscreenElement",void 0!==document[i]?r.fullscreenElement=i:(i=s+"FullScreenElement",void 0!==document[i]&&(r.fullscreenElement=i)),i=s+"fullscreenchange",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenChange"),r.fullscreenchange=i),i=s+"fullscreenerror",void 0!==document["on"+i]&&("ms"===s&&(i="MSFullscreenError"),r.fullscreenerror=i)}return n},i.requestFullscreen=function(e,t){i.supportsFullscreen()&&e[r.requestFullscreen]({vrDisplay:t})},i.exitFullscreen=function(){i.supportsFullscreen()&&document[r.exitFullscreen]()},i}),define("Core/FeatureDetection",["./defaultValue","./defined","./Fullscreen"],function(e,t,n){"use strict";function r(e){for(var t=e.split("."),n=0,r=t.length;n<r;++n)t[n]=parseInt(t[n],10);return t}function i(){if(!t(A)&&(A=!1,!h())){var e=/ Chrome\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(A=!0,S=r(e[1]))}return A}function a(){return i()&&S}function o(){if(!t(v)&&(v=!1,!i()&&!h()&&/ Safari\/[\.0-9]+/.test(R.userAgent))){var e=/ Version\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(v=!0,g=r(e[1]))}return v}function u(){return o()&&g}function s(){if(!t(N)){N=!1;var e=/ AppleWebKit\/([\.0-9]+)(\+?)/.exec(R.userAgent);null!==e&&(N=!0,I=r(e[1]),I.isNightly=!!e[2])}return N}function c(){return s()&&I}function l(){if(!t(O)){O=!1;var e;"Microsoft Internet Explorer"===R.appName?null!==(e=/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,M=r(e[1])):"Netscape"===R.appName&&null!==(e=/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(R.userAgent))&&(O=!0,M=r(e[1]))}return O}function f(){return l()&&M}function h(){if(!t(w)){w=!1;var e=/ Edge\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(w=!0,C=r(e[1]))}return w}function d(){return h()&&C}function E(){if(!t(x)){x=!1;var e=/Firefox\/([\.0-9]+)/.exec(R.userAgent);null!==e&&(x=!0,P=r(e[1]))}return x}function m(){return t(U)||(U=/Windows/i.test(R.appVersion)),U}function p(){return E()&&P}function _(){return t(D)||(D="undefined"!=typeof PointerEvent&&(!t(R.pointerEnabled)||R.pointerEnabled)),D}function y(){if(!t(F)){var e=document.createElement("canvas");e.setAttribute("style","image-rendering: -moz-crisp-edges;image-rendering: pixelated;");var n=e.style.imageRendering;F=t(n)&&""!==n,F&&(L=n)}return F}function T(){return y()?L:void 0}var R;R="undefined"!=typeof navigator?navigator:{};var A,S,v,g,N,I,O,M,w,C,x,P,U,D,L,F,B={isChrome:i,chromeVersion:a,isSafari:o,safariVersion:u,isWebkit:s,webkitVersion:c,isInternetExplorer:l,internetExplorerVersion:f,isEdge:h,edgeVersion:d,isFirefox:E,firefoxVersion:p,isWindows:m,hardwareConcurrency:e(R.hardwareConcurrency,3),supportsPointerEvents:_,supportsImageRenderingPixelated:y,imageRenderingValue:T};return B.supportsFullscreen=function(){return n.supportsFullscreen()},B.supportsTypedArrays=function(){return"undefined"!=typeof ArrayBuffer},B.supportsWebWorkers=function(){return"undefined"!=typeof Worker},B}),define("Core/Quaternion",["./Cartesian3","./Check","./defaultValue","./defined","./FeatureDetection","./freezeObject","./Math","./Matrix3"],function(e,t,n,r,i,a,o,u){"use strict";function s(e,t,r,i){this.x=n(e,0),this.y=n(t,0),this.z=n(r,0),this.w=n(i,0)}var c=new e;s.fromAxisAngle=function(t,n,i){var a=n/2,o=Math.sin(a);c=e.normalize(t,c);var u=c.x*o,l=c.y*o,f=c.z*o,h=Math.cos(a);return r(i)?(i.x=u,i.y=l,i.z=f,i.w=h,i):new s(u,l,f,h)};var l=[1,2,0],f=new Array(3);s.fromRotationMatrix=function(e,t){var n,i,a,o,c,h=e[u.COLUMN0ROW0],d=e[u.COLUMN1ROW1],E=e[u.COLUMN2ROW2],m=h+d+E;if(m>0)n=Math.sqrt(m+1),c=.5*n,n=.5/n,i=(e[u.COLUMN1ROW2]-e[u.COLUMN2ROW1])*n,a=(e[u.COLUMN2ROW0]-e[u.COLUMN0ROW2])*n,o=(e[u.COLUMN0ROW1]-e[u.COLUMN1ROW0])*n;else{var p=l,_=0;d>h&&(_=1),E>h&&E>d&&(_=2);var y=p[_],T=p[y];n=Math.sqrt(e[u.getElementIndex(_,_)]-e[u.getElementIndex(y,y)]-e[u.getElementIndex(T,T)]+1);var R=f;R[_]=.5*n,n=.5/n,c=(e[u.getElementIndex(T,y)]-e[u.getElementIndex(y,T)])*n,R[y]=(e[u.getElementIndex(y,_)]+e[u.getElementIndex(_,y)])*n,R[T]=(e[u.getElementIndex(T,_)]+e[u.getElementIndex(_,T)])*n,i=-R[0],a=-R[1],o=-R[2]}return r(t)?(t.x=i,t.y=a,t.z=o,t.w=c,t):new s(i,a,o,c)};var h=new s,d=new s,E=new s,m=new s;s.fromHeadingPitchRoll=function(t,n){return m=s.fromAxisAngle(e.UNIT_X,t.roll,h),E=s.fromAxisAngle(e.UNIT_Y,-t.pitch,n),n=s.multiply(E,m,E),d=s.fromAxisAngle(e.UNIT_Z,-t.heading,h),s.multiply(d,n,n)};var p=new e,_=new e,y=new s,T=new s,R=new s;s.packedLength=4,s.pack=function(e,t,r){return r=n(r,0),t[r++]=e.x,t[r++]=e.y,t[r++]=e.z,t[r]=e.w,t},s.unpack=function(e,t,i){return t=n(t,0),r(i)||(i=new s),i.x=e[t],i.y=e[t+1],i.z=e[t+2],i.w=e[t+3],i},s.packedInterpolationLength=3,s.convertPackedArrayForInterpolation=function(e,t,n,r){s.unpack(e,4*n,R),s.conjugate(R,R);for(var i=0,a=n-t+1;i<a;i++){var o=3*i;s.unpack(e,4*(t+i),y),s.multiply(y,R,y),y.w<0&&s.negate(y,y),s.computeAxis(y,p);var u=s.computeAngle(y);r[o]=p.x*u,r[o+1]=p.y*u,r[o+2]=p.z*u}},s.unpackInterpolationResult=function(t,n,i,a,o){r(o)||(o=new s),e.fromArray(t,0,_);var u=e.magnitude(_);return s.unpack(n,4*a,T),0===u?s.clone(s.IDENTITY,y):s.fromAxisAngle(_,u,y),s.multiply(y,T,o)},s.clone=function(e,t){if(r(e))return r(t)?(t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w,t):new s(e.x,e.y,e.z,e.w)},s.conjugate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w,t},s.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y+e.z*e.z+e.w*e.w},s.magnitude=function(e){return Math.sqrt(s.magnitudeSquared(e))},s.normalize=function(e,t){var n=1/s.magnitude(e),r=e.x*n,i=e.y*n,a=e.z*n,o=e.w*n;return t.x=r,t.y=i,t.z=a,t.w=o,t},s.inverse=function(e,t){var n=s.magnitudeSquared(e);return t=s.conjugate(e,t),s.multiplyByScalar(t,1/n,t)},s.add=function(e,t,n){return n.x=e.x+t.x,n.y=e.y+t.y,n.z=e.z+t.z,n.w=e.w+t.w,n},s.subtract=function(e,t,n){return n.x=e.x-t.x,n.y=e.y-t.y,n.z=e.z-t.z,n.w=e.w-t.w,n},s.negate=function(e,t){return t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=-e.w,t},s.dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w},s.multiply=function(e,t,n){var r=e.x,i=e.y,a=e.z,o=e.w,u=t.x,s=t.y,c=t.z,l=t.w,f=o*u+r*l+i*c-a*s,h=o*s-r*c+i*l+a*u,d=o*c+r*s-i*u+a*l,E=o*l-r*u-i*s-a*c;return n.x=f,n.y=h,n.z=d,n.w=E,n},s.multiplyByScalar=function(e,t,n){return n.x=e.x*t,n.y=e.y*t,n.z=e.z*t,n.w=e.w*t,n},s.divideByScalar=function(e,t,n){return n.x=e.x/t,n.y=e.y/t,n.z=e.z/t,n.w=e.w/t,n},s.computeAxis=function(e,t){var n=e.w;if(Math.abs(n-1)<o.EPSILON6)return t.x=t.y=t.z=0,t;var r=1/Math.sqrt(1-n*n);return t.x=e.x*r,t.y=e.y*r,t.z=e.z*r,t},s.computeAngle=function(e){return Math.abs(e.w-1)<o.EPSILON6?0:2*Math.acos(e.w)};var A=new s;s.lerp=function(e,t,n,r){return A=s.multiplyByScalar(t,n,A),r=s.multiplyByScalar(e,1-n,r),s.add(A,r,r)};var S=new s,v=new s,g=new s;s.slerp=function(e,t,n,r){var i=s.dot(e,t),a=t;if(i<0&&(i=-i,a=S=s.negate(t,S)),1-i<o.EPSILON6)return s.lerp(e,a,n,r);var u=Math.acos(i);return v=s.multiplyByScalar(e,Math.sin((1-n)*u),v),g=s.multiplyByScalar(a,Math.sin(n*u),g),r=s.add(v,g,r),s.multiplyByScalar(r,1/Math.sin(u),r)},s.log=function(t,n){var r=o.acosClamped(t.w),i=0;return 0!==r&&(i=r/Math.sin(r)),e.multiplyByScalar(t,i,n)},s.exp=function(t,n){var r=e.magnitude(t),i=0;return 0!==r&&(i=Math.sin(r)/r),n.x=t.x*i,n.y=t.y*i,n.z=t.z*i,n.w=Math.cos(r),n};var N=new e,I=new e,O=new s,M=new s;s.computeInnerQuadrangle=function(t,n,r,i){var a=s.conjugate(n,O);s.multiply(a,r,M);var o=s.log(M,N);s.multiply(a,t,M);var u=s.log(M,I);return e.add(o,u,o),e.multiplyByScalar(o,.25,o),e.negate(o,o),s.exp(o,O),s.multiply(n,O,i)},s.squad=function(e,t,n,r,i,a){var o=s.slerp(e,t,i,O),u=s.slerp(n,r,i,M);return s.slerp(o,u,2*i*(1-i),a)};for(var w=new s,C=1.9011074535173003,x=i.supportsTypedArrays()?new Float32Array(8):[],P=i.supportsTypedArrays()?new Float32Array(8):[],U=i.supportsTypedArrays()?new Float32Array(8):[],D=i.supportsTypedArrays()?new Float32Array(8):[],L=0;L<7;++L){var F=L+1,B=2*F+1;x[L]=1/(F*B),P[L]=F/B}return x[7]=C/136,P[7]=8*C/17,s.fastSlerp=function(e,t,n,r){var i,a=s.dot(e,t);a>=0?i=1:(i=-1,a=-a);for(var o=a-1,u=1-n,c=n*n,l=u*u,f=7;f>=0;--f)U[f]=(x[f]*c-P[f])*o,D[f]=(x[f]*l-P[f])*o;var h=i*n*(1+U[0]*(1+U[1]*(1+U[2]*(1+U[3]*(1+U[4]*(1+U[5]*(1+U[6]*(1+U[7])))))))),d=u*(1+D[0]*(1+D[1]*(1+D[2]*(1+D[3]*(1+D[4]*(1+D[5]*(1+D[6]*(1+D[7])))))))),E=s.multiplyByScalar(e,d,w);return s.multiplyByScalar(t,h,r),s.add(E,r,r)},s.fastSquad=function(e,t,n,r,i,a){var o=s.fastSlerp(e,t,i,O),u=s.fastSlerp(n,r,i,M);return s.fastSlerp(o,u,2*i*(1-i),a)},s.equals=function(e,t){return e===t||r(e)&&r(t)&&e.x===t.x&&e.y===t.y&&e.z===t.z&&e.w===t.w},s.equalsEpsilon=function(e,t,n){return e===t||r(e)&&r(t)&&Math.abs(e.x-t.x)<=n&&Math.abs(e.y-t.y)<=n&&Math.abs(e.z-t.z)<=n&&Math.abs(e.w-t.w)<=n},s.ZERO=a(new s(0,0,0,0)),s.IDENTITY=a(new s(0,0,0,1)),s.prototype.clone=function(e){return s.clone(this,e)},s.prototype.equals=function(e){return s.equals(this,e)},s.prototype.equalsEpsilon=function(e,t){return s.equalsEpsilon(this,e,t)},s.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+", "+this.w+")"},s}),define("Core/Transforms",["../ThirdParty/when","./Cartesian2","./Cartesian3","./Cartesian4","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./EarthOrientationParameters","./EarthOrientationParametersSample","./Ellipsoid","./Iau2006XysData","./Iau2006XysSample","./JulianDate","./Math","./Matrix3","./Matrix4","./Quaternion","./TimeConstants"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m,p,_,y,T){"use strict";var R={},A={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},S={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},v={},g={east:new n,north:new n,up:new n,west:new n,south:new n,down:new n},N=new n,I=new n,O=new n;R.localFrameToFixedFrameGenerator=function(e,t){if(!A.hasOwnProperty(e)||!A[e].hasOwnProperty(t))throw new s("firstAxis and secondAxis must be east, north, up, west, south or down.");var r,i=A[e][t],a=e+t;return u(v[a])?r=v[a]:(r=function(r,a,s){if(u(s)||(s=new _),m.equalsEpsilon(r.x,0,m.EPSILON14)&&m.equalsEpsilon(r.y,0,m.EPSILON14)){var c=m.sign(r.z);n.unpack(S[e],0,N),"east"!==e&&"west"!==e&&n.multiplyByScalar(N,c,N),n.unpack(S[t],0,I),"east"!==t&&"west"!==t&&n.multiplyByScalar(I,c,I),n.unpack(S[i],0,O),"east"!==i&&"west"!==i&&n.multiplyByScalar(O,c,O)}else{a=o(a,f.WGS84),a.geodeticSurfaceNormal(r,g.up);var l=g.up,h=g.east;h.x=-r.y,h.y=r.x,h.z=0,n.normalize(h,g.east),n.cross(l,h,g.north),n.multiplyByScalar(g.up,-1,g.down),n.multiplyByScalar(g.east,-1,g.west),n.multiplyByScalar(g.north,-1,g.south),N=g[e],I=g[t],O=g[i]}return s[0]=N.x,s[1]=N.y,s[2]=N.z,s[3]=0,s[4]=I.x,s[5]=I.y,s[6]=I.z,s[7]=0,s[8]=O.x,s[9]=O.y,s[10]=O.z,s[11]=0,s[12]=r.x,s[13]=r.y,s[14]=r.z,s[15]=1,s},v[a]=r),r},R.eastNorthUpToFixedFrame=R.localFrameToFixedFrameGenerator("east","north"),R.northEastDownToFixedFrame=R.localFrameToFixedFrameGenerator("north","east"),R.northUpEastToFixedFrame=R.localFrameToFixedFrameGenerator("north","up"),R.northWestUpToFixedFrame=R.localFrameToFixedFrameGenerator("north","west");var M=new y,w=new n(1,1,1),C=new _;R.headingPitchRollToFixedFrame=function(e,t,r,i,a){i=o(i,R.eastNorthUpToFixedFrame);var u=y.fromHeadingPitchRoll(t,M),s=_.fromTranslationQuaternionRotationScale(n.ZERO,u,w,C);return a=i(e,r,a),_.multiply(a,s,a)};var x=new _,P=new p;R.headingPitchRollQuaternion=function(e,t,n,r,i){var a=R.headingPitchRollToFixedFrame(e,t,n,r,x),o=_.getRotation(a,P);return y.fromRotationMatrix(o,i)};var U=m.TWO_PI/86400,D=new E +;R.computeTemeToPseudoFixedMatrix=function(e,t){D=E.addSeconds(e,-E.computeTaiMinusUtc(e),D);var n,r=D.dayNumber,i=D.secondsOfDay,a=r-2451545;n=i>=43200?(a+.5)/T.DAYS_PER_JULIAN_CENTURY:(a-.5)/T.DAYS_PER_JULIAN_CENTURY;var o=24110.54841+n*(8640184.812866+n*(.093104+-62e-7*n)),s=o*U%m.TWO_PI,c=72921158553e-15+1.1772758384668e-19*(r-2451545.5),l=(i+.5*T.SECONDS_PER_DAY)%T.SECONDS_PER_DAY,f=s+c*l,h=Math.cos(f),d=Math.sin(f);return u(t)?(t[0]=h,t[1]=-d,t[2]=0,t[3]=d,t[4]=h,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t):new p(h,d,0,-d,h,0,0,0,1)},R.iau2006XysData=new h,R.earthOrientationParameters=c.NONE;R.preloadIcrfFixed=function(t){var n=t.start.dayNumber,r=t.start.secondsOfDay+32.184,i=t.stop.dayNumber,a=t.stop.secondsOfDay+32.184,o=R.iau2006XysData.preload(n,r,i,a),u=R.earthOrientationParameters.getPromiseToLoad();return e.all([o,u])},R.computeIcrfToFixedMatrix=function(e,t){u(t)||(t=new p);var n=R.computeFixedToIcrfMatrix(e,t);if(u(n))return p.transpose(n,t)};var L=new d(0,0,0),F=new l(0,0,0,0,0,0),B=new p,b=new p;R.computeFixedToIcrfMatrix=function(e,t){u(t)||(t=new p);var n=R.earthOrientationParameters.compute(e,F);if(u(n)){var r=e.dayNumber,i=e.secondsOfDay+32.184,a=R.iau2006XysData.computeXysRadians(r,i,L);if(u(a)){var o=a.x+n.xPoleOffset,s=a.y+n.yPoleOffset,c=1/(1+Math.sqrt(1-o*o-s*s)),l=B;l[0]=1-c*o*o,l[3]=-c*o*s,l[6]=o,l[1]=-c*o*s,l[4]=1-c*s*s,l[7]=s,l[2]=-o,l[5]=-s,l[8]=1-c*(o*o+s*s);var f=p.fromRotationZ(-a.s,b),h=p.multiply(l,f,B),d=e.dayNumber,_=e.secondsOfDay-E.computeTaiMinusUtc(e)+n.ut1MinusUtc,y=d-2451545,A=_/T.SECONDS_PER_DAY,S=.779057273264+A+.00273781191135448*(y+A);S=S%1*m.TWO_PI;var v=p.fromRotationZ(S,b),g=p.multiply(h,v,B),N=Math.cos(n.xPoleWander),I=Math.cos(n.yPoleWander),O=Math.sin(n.xPoleWander),M=Math.sin(n.yPoleWander),w=r-2451545+i/T.SECONDS_PER_DAY;w/=36525;var C=-47e-6*w*m.RADIANS_PER_DEGREE/3600,x=Math.cos(C),P=Math.sin(C),U=b;return U[0]=N*x,U[1]=N*P,U[2]=O,U[3]=-I*P+M*O*x,U[4]=I*x+M*O*P,U[5]=-M*N,U[6]=-M*P-I*O*x,U[7]=M*x-I*O*P,U[8]=I*N,p.multiply(g,U,t)}}};var z=new r;R.pointToWindowCoordinates=function(e,t,n,r){return r=R.pointToGLWindowCoordinates(e,t,n,r),r.y=2*t[5]-r.y,r},R.pointToGLWindowCoordinates=function(e,n,i,a){u(a)||(a=new t);var o=z;return _.multiplyByVector(e,r.fromElements(i.x,i.y,i.z,1,o),o),r.multiplyByScalar(o,1/o.w,o),_.multiplyByVector(n,o,o),t.fromCartesian4(o,a)};var q=new n,G=new n,V=new n;R.rotationMatrixFromPositionVelocity=function(e,t,r,i){var a=o(r,f.WGS84).geodeticSurfaceNormal(e,q),s=n.cross(t,a,G);n.equalsEpsilon(s,n.ZERO,m.EPSILON6)&&(s=n.clone(n.UNIT_X,s));var c=n.cross(s,t,V);return n.cross(t,c,s),n.negate(s,s),u(i)||(i=new p),i[0]=t.x,i[1]=t.y,i[2]=t.z,i[3]=s.x,i[4]=s.y,i[5]=s.z,i[6]=c.x,i[7]=c.y,i[8]=c.z,i};var X=new _(0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1),W=new i,H=new n,Y=new n,k=new p,j=new _,Z=new _;return R.basisTo2D=function(e,t,r){var i=_.getTranslation(t,Y),a=e.ellipsoid,o=a.cartesianToCartographic(i,W),u=e.project(o,H);n.fromElements(u.z,u.x,u.y,u);var s=R.eastNorthUpToFixedFrame(i,a,j),c=_.inverseTransformation(s,Z),l=_.getRotation(t,k),f=_.multiplyByMatrix3(c,l,r);return _.multiply(X,f,r),_.setTranslation(r,u,r),r},R.wgs84To2DModelMatrix=function(e,t,r){var i=e.ellipsoid,a=R.eastNorthUpToFixedFrame(t,i,j),o=_.inverseTransformation(a,Z),u=i.cartesianToCartographic(t,W),s=e.project(u,H);n.fromElements(s.z,s.x,s.y,s);var c=_.fromTranslation(s,j);return _.multiply(X,o,r),_.multiply(c,r,r),r},R}),define("Core/EllipsoidTangentPlane",["./AxisAlignedBoundingBox","./Cartesian2","./Cartesian3","./Cartesian4","./defaultValue","./defined","./defineProperties","./DeveloperError","./Ellipsoid","./IntersectionTests","./Matrix4","./Plane","./Ray","./Transforms"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,t){t=i(t,s.WGS84),e=t.scaleToGeodeticSurface(e);var r=d.eastNorthUpToFixedFrame(e,t);this._ellipsoid=t,this._origin=e,this._xAxis=n.fromCartesian4(l.getColumn(r,0,m)),this._yAxis=n.fromCartesian4(l.getColumn(r,1,m));var a=n.fromCartesian4(l.getColumn(r,2,m));this._plane=f.fromPointNormal(e,a)}var m=new r;o(E.prototype,{ellipsoid:{get:function(){return this._ellipsoid}},origin:{get:function(){return this._origin}},plane:{get:function(){return this._plane}},xAxis:{get:function(){return this._xAxis}},yAxis:{get:function(){return this._yAxis}},zAxis:{get:function(){return this._plane.normal}}});var p=new e;E.fromPoints=function(t,n){return new E(e.fromPoints(t,p).center,n)};var _=new h,y=new n;E.prototype.projectPointOntoPlane=function(e,r){var i=_;i.origin=e,n.normalize(e,i.direction);var o=c.rayPlane(i,this._plane,y);if(a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y)),a(o)){var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return a(r)?(r.x=s,r.y=l,r):new t(s,l)}},E.prototype.projectPointsOntoPlane=function(e,t){a(t)||(t=[]);for(var n=0,r=e.length,i=0;i<r;i++){var o=this.projectPointOntoPlane(e[i],t[n]);a(o)&&(t[n]=o,n++)}return t.length=n,t},E.prototype.projectPointToNearestOnPlane=function(e,r){a(r)||(r=new t);var i=_;i.origin=e,n.clone(this._plane.normal,i.direction);var o=c.rayPlane(i,this._plane,y);a(o)||(n.negate(i.direction,i.direction),o=c.rayPlane(i,this._plane,y));var u=n.subtract(o,this._origin,o),s=n.dot(this._xAxis,u),l=n.dot(this._yAxis,u);return r.x=s,r.y=l,r},E.prototype.projectPointsToNearestOnPlane=function(e,t){a(t)||(t=[]);var n=e.length;t.length=n;for(var r=0;r<n;r++)t[r]=this.projectPointToNearestOnPlane(e[r],t[r]);return t};var T=new n;return E.prototype.projectPointsOntoEllipsoid=function(e,t){var r=e.length;a(t)?t.length=r:t=new Array(r);for(var i=this._ellipsoid,o=this._origin,u=this._xAxis,s=this._yAxis,c=T,l=0;l<r;++l){var f=e[l];n.multiplyByScalar(u,f.x,c),a(t[l])||(t[l]=new n);var h=n.add(o,c,t[l]);n.multiplyByScalar(s,f.y,c),n.add(h,c,h),i.scaleToGeocentricSurface(h,h)}return t},E}),define("Core/OrientedBoundingBox",["./BoundingSphere","./Cartesian2","./Cartesian3","./Cartographic","./Check","./defaultValue","./defined","./DeveloperError","./Ellipsoid","./EllipsoidTangentPlane","./Intersect","./Interval","./Math","./Matrix3","./Plane","./Rectangle"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d,E,m){"use strict";function p(e,t){this.center=n.clone(a(e,n.ZERO)),this.halfAxes=d.clone(a(t,d.ZERO))}function _(e,t,r,i,a,u,s,c){o(c)||(c=new p);var l=c.halfAxes;d.setColumn(l,0,e.xAxis,l),d.setColumn(l,1,e.yAxis,l),d.setColumn(l,2,e.zAxis,l);var f=I;f.x=(t+r)/2,f.y=(i+a)/2,f.z=(u+s)/2;var h=O;h.x=(r-t)/2,h.y=(a-i)/2,h.z=(s-u)/2;var E=c.center;return f=d.multiplyByVector(l,f,f),n.add(e.origin,f,E),d.multiplyByScale(l,h,l),c}p.packedLength=n.packedLength+d.packedLength,p.pack=function(e,t,r){return r=a(r,0),n.pack(e.center,t,r),d.pack(e.halfAxes,t,r+n.packedLength),t},p.unpack=function(e,t,r){return t=a(t,0),o(r)||(r=new p),n.unpack(e,t,r.center),d.unpack(e,t+n.packedLength,r.halfAxes),r};var y=new n,T=new n,R=new n,A=new n,S=new n,v=new n,g=new d,N={unitary:new d,diagonal:new d};p.fromPoints=function(e,t){if(o(t)||(t=new p),!o(e)||0===e.length)return t.halfAxes=d.ZERO,t.center=n.ZERO,t;var r,i=e.length,a=n.clone(e[0],y);for(r=1;r<i;r++)n.add(a,e[r],a);var u=1/i;n.multiplyByScalar(a,u,a);var s,c=0,l=0,f=0,h=0,E=0,m=0;for(r=0;r<i;r++)s=n.subtract(e[r],a,T),c+=s.x*s.x,l+=s.x*s.y,f+=s.x*s.z,h+=s.y*s.y,E+=s.y*s.z,m+=s.z*s.z;c*=u,l*=u,f*=u,h*=u,E*=u,m*=u;var _=g;_[0]=c,_[1]=l,_[2]=f,_[3]=l,_[4]=h,_[5]=E,_[6]=f,_[7]=E,_[8]=m;var I=d.computeEigenDecomposition(_,N),O=d.clone(I.unitary,t.halfAxes),M=d.getColumn(O,0,A),w=d.getColumn(O,1,S),C=d.getColumn(O,2,v),x=-Number.MAX_VALUE,P=-Number.MAX_VALUE,U=-Number.MAX_VALUE,D=Number.MAX_VALUE,L=Number.MAX_VALUE,F=Number.MAX_VALUE;for(r=0;r<i;r++)s=e[r],x=Math.max(n.dot(M,s),x),P=Math.max(n.dot(w,s),P),U=Math.max(n.dot(C,s),U),D=Math.min(n.dot(M,s),D),L=Math.min(n.dot(w,s),L),F=Math.min(n.dot(C,s),F);M=n.multiplyByScalar(M,.5*(D+x),M),w=n.multiplyByScalar(w,.5*(L+P),w),C=n.multiplyByScalar(C,.5*(F+U),C);var B=n.add(M,w,t.center);n.add(B,C,B);var b=R;return b.x=x-D,b.y=P-L,b.z=U-F,n.multiplyByScalar(b,.5,b),d.multiplyByScale(t.halfAxes,b,t.halfAxes),t};var I=new n,O=new n,M=new r,w=new n,C=[new r,new r,new r,new r,new r,new r,new r,new r],x=[new n,new n,new n,new n,new n,new n,new n,new n],P=[new t,new t,new t,new t,new t,new t,new t,new t];p.fromRectangle=function(e,t,n,r,i){t=a(t,0),n=a(n,0),r=a(r,s.WGS84);var o=m.center(e,M),u=r.cartographicToCartesian(o,w),l=new c(u,r),f=l.plane,h=C[0],d=C[1],p=C[2],y=C[3],T=C[4],R=C[5],A=C[6],S=C[7],v=o.longitude,g=e.south<0&&e.north>0?0:o.latitude;A.latitude=R.latitude=T.latitude=e.south,S.latitude=y.latitude=g,h.latitude=d.latitude=p.latitude=e.north,A.longitude=S.longitude=h.longitude=e.west,R.longitude=d.longitude=v,T.longitude=y.longitude=p.longitude=e.east,p.height=d.height=h.height=S.height=A.height=R.height=T.height=y.height=n,r.cartographicArrayToCartesianArray(C,x),l.projectPointsToNearestOnPlane(x,P);var N=Math.min(P[6].x,P[7].x,P[0].x),I=Math.max(P[2].x,P[3].x,P[4].x),O=Math.min(P[4].y,P[5].y,P[6].y),U=Math.max(P[0].y,P[1].y,P[2].y);return p.height=h.height=T.height=A.height=t,r.cartographicArrayToCartesianArray(C,x),_(l,N,I,O,U,Math.min(E.getPointDistance(f,x[0]),E.getPointDistance(f,x[2]),E.getPointDistance(f,x[4]),E.getPointDistance(f,x[6])),n,i)},p.clone=function(e,t){if(o(e))return o(t)?(n.clone(e.center,t.center),d.clone(e.halfAxes,t.halfAxes),t):new p(e.center,e.halfAxes)},p.intersectPlane=function(e,t){var r=e.center,i=t.normal,a=e.halfAxes,o=i.x,u=i.y,s=i.z,c=Math.abs(o*a[d.COLUMN0ROW0]+u*a[d.COLUMN0ROW1]+s*a[d.COLUMN0ROW2])+Math.abs(o*a[d.COLUMN1ROW0]+u*a[d.COLUMN1ROW1]+s*a[d.COLUMN1ROW2])+Math.abs(o*a[d.COLUMN2ROW0]+u*a[d.COLUMN2ROW1]+s*a[d.COLUMN2ROW2]),f=n.dot(i,r)+t.distance;return f<=-c?l.OUTSIDE:f>=c?l.INSIDE:l.INTERSECTING};var U=new n,D=new n,L=new n,F=new n;p.distanceSquaredTo=function(e,t){var r=n.subtract(t,e.center,I),i=e.halfAxes,a=d.getColumn(i,0,U),o=d.getColumn(i,1,D),u=d.getColumn(i,2,L),s=n.magnitude(a),c=n.magnitude(o),l=n.magnitude(u);n.normalize(a,a),n.normalize(o,o),n.normalize(u,u);var f=F;f.x=n.dot(r,a),f.y=n.dot(r,o),f.z=n.dot(r,u);var h,E=0;return f.x<-s?(h=f.x+s,E+=h*h):f.x>s&&(h=f.x-s,E+=h*h),f.y<-c?(h=f.y+c,E+=h*h):f.y>c&&(h=f.y-c,E+=h*h),f.z<-l?(h=f.z+l,E+=h*h):f.z>l&&(h=f.z-l,E+=h*h),E};var B=new n,b=new n;p.computePlaneDistances=function(e,t,r,i){o(i)||(i=new f);var a=Number.POSITIVE_INFINITY,u=Number.NEGATIVE_INFINITY,s=e.center,c=e.halfAxes,l=d.getColumn(c,0,U),h=d.getColumn(c,1,D),E=d.getColumn(c,2,L),m=n.add(l,h,B);n.add(m,E,m),n.add(m,s,m);var p=n.subtract(m,t,b),_=n.dot(r,p);return a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.add(s,l,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,m),n.add(m,h,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,m),n.add(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,m),n.subtract(m,h,m),n.add(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),n.subtract(s,l,m),n.subtract(m,h,m),n.subtract(m,E,m),n.subtract(m,t,p),_=n.dot(r,p),a=Math.min(_,a),u=Math.max(_,u),i.start=a,i.stop=u,i};var z=new e;return p.isOccluded=function(t,n){var r=e.fromOrientedBoundingBox(t,z);return!n.isBoundingSphereVisible(r)},p.prototype.intersectPlane=function(e){return p.intersectPlane(this,e)},p.prototype.distanceSquaredTo=function(e){return p.distanceSquaredTo(this,e)},p.prototype.computePlaneDistances=function(e,t,n){return p.computePlaneDistances(this,e,t,n)},p.prototype.isOccluded=function(e){return p.isOccluded(this,e)},p.equals=function(e,t){return e===t||o(e)&&o(t)&&n.equals(e.center,t.center)&&d.equals(e.halfAxes,t.halfAxes)},p.prototype.clone=function(e){return p.clone(this,e)},p.prototype.equals=function(e){return p.equals(this,e)},p}),define("Core/ComponentDatatype",["./defaultValue","./defined","./DeveloperError","./FeatureDetection","./freezeObject","./WebGLConstants"],function(e,t,n,r,i,a){"use strict";if(!r.supportsTypedArrays())return{};var o={BYTE:a.BYTE,UNSIGNED_BYTE:a.UNSIGNED_BYTE,SHORT:a.SHORT,UNSIGNED_SHORT:a.UNSIGNED_SHORT,INT:a.INT,UNSIGNED_INT:a.UNSIGNED_INT,FLOAT:a.FLOAT,DOUBLE:a.DOUBLE};return o.getSizeInBytes=function(e){switch(e){case o.BYTE:return Int8Array.BYTES_PER_ELEMENT;case o.UNSIGNED_BYTE:return Uint8Array.BYTES_PER_ELEMENT;case o.SHORT:return Int16Array.BYTES_PER_ELEMENT;case o.UNSIGNED_SHORT:return Uint16Array.BYTES_PER_ELEMENT;case o.INT:return Int32Array.BYTES_PER_ELEMENT;case o.UNSIGNED_INT:return Uint32Array.BYTES_PER_ELEMENT;case o.FLOAT:return Float32Array.BYTES_PER_ELEMENT;case o.DOUBLE:return Float64Array.BYTES_PER_ELEMENT}},o.fromTypedArray=function(e){return e instanceof Int8Array?o.BYTE:e instanceof Uint8Array?o.UNSIGNED_BYTE:e instanceof Int16Array?o.SHORT:e instanceof Uint16Array?o.UNSIGNED_SHORT:e instanceof Int32Array?o.INT:e instanceof Uint32Array?o.UNSIGNED_INT:e instanceof Float32Array?o.FLOAT:e instanceof Float64Array?o.DOUBLE:void 0},o.validate=function(e){return t(e)&&(e===o.BYTE||e===o.UNSIGNED_BYTE||e===o.SHORT||e===o.UNSIGNED_SHORT||e===o.INT||e===o.UNSIGNED_INT||e===o.FLOAT||e===o.DOUBLE)},o.createTypedArray=function(e,t){switch(e){case o.BYTE:return new Int8Array(t);case o.UNSIGNED_BYTE:return new Uint8Array(t);case o.SHORT:return new Int16Array(t);case o.UNSIGNED_SHORT:return new Uint16Array(t);case o.INT:return new Int32Array(t);case o.UNSIGNED_INT:return new Uint32Array(t);case o.FLOAT:return new Float32Array(t);case o.DOUBLE:return new Float64Array(t)}},o.createArrayBufferView=function(t,n,r,i){switch(r=e(r,0),i=e(i,(n.byteLength-r)/o.getSizeInBytes(t)),t){case o.BYTE:return new Int8Array(n,r,i);case o.UNSIGNED_BYTE:return new Uint8Array(n,r,i);case o.SHORT:return new Int16Array(n,r,i);case o.UNSIGNED_SHORT:return new Uint16Array(n,r,i);case o.INT:return new Int32Array(n,r,i);case o.UNSIGNED_INT:return new Uint32Array(n,r,i);case o.FLOAT:return new Float32Array(n,r,i);case o.DOUBLE:return new Float64Array(n,r,i)}},o.fromName=function(e){switch(e){case"BYTE":return o.BYTE;case"UNSIGNED_BYTE":return o.UNSIGNED_BYTE;case"SHORT":return o.SHORT;case"UNSIGNED_SHORT":return o.UNSIGNED_SHORT;case"INT":return o.INT;case"UNSIGNED_INT":return o.UNSIGNED_INT;case"FLOAT":return o.FLOAT;case"DOUBLE":return o.DOUBLE}},i(o)}),define("Core/TerrainQuantization",["./freezeObject"],function(e){"use strict";return e({NONE:0,BITS12:1})}),define("Core/TerrainEncoding",["./AttributeCompression","./Cartesian2","./Cartesian3","./ComponentDatatype","./defaultValue","./defined","./Math","./Matrix4","./TerrainQuantization"],function(e,t,n,r,i,a,o,u,s){"use strict";function c(e,t,r,o,c,h){var p,_,y,T;if(a(e)&&a(t)&&a(r)&&a(o)){var R=e.minimum,A=e.maximum,S=n.subtract(A,R,f),v=r-t;p=Math.max(n.maximumComponent(S),v)<m-1?s.BITS12:s.NONE,_=e.center,y=u.inverseTransformation(o,new u);var g=n.negate(R,l);u.multiply(u.fromTranslation(g,d),y,y);var N=l;N.x=1/S.x,N.y=1/S.y,N.z=1/S.z,u.multiply(u.fromScale(N,d),y,y),T=u.clone(o),u.setTranslation(T,n.ZERO,T),o=u.clone(o,new u);var I=u.fromTranslation(R,d),O=u.fromScale(S,E),M=u.multiply(I,O,d);u.multiply(o,M,o),u.multiply(T,M,T)}this.quantization=p,this.minimumHeight=t,this.maximumHeight=r,this.center=_,this.toScaledENU=y,this.fromScaledENU=o,this.matrix=T,this.hasVertexNormals=c,this.hasWebMercatorT=i(h,!1)}var l=new n,f=new n,h=new t,d=new u,E=new u,m=Math.pow(2,12);c.prototype.encode=function(r,i,a,c,f,d,E){var m=c.x,p=c.y;if(this.quantization===s.BITS12){a=u.multiplyByPoint(this.toScaledENU,a,l),a.x=o.clamp(a.x,0,1),a.y=o.clamp(a.y,0,1),a.z=o.clamp(a.z,0,1);var _=this.maximumHeight-this.minimumHeight,y=o.clamp((f-this.minimumHeight)/_,0,1);t.fromElements(a.x,a.y,h);var T=e.compressTextureCoordinates(h);t.fromElements(a.z,y,h);var R=e.compressTextureCoordinates(h);t.fromElements(m,p,h);var A=e.compressTextureCoordinates(h);if(r[i++]=T,r[i++]=R,r[i++]=A,this.hasWebMercatorT){t.fromElements(E,0,h);var S=e.compressTextureCoordinates(h);r[i++]=S}}else n.subtract(a,this.center,l),r[i++]=l.x,r[i++]=l.y,r[i++]=l.z,r[i++]=f,r[i++]=m,r[i++]=p,this.hasWebMercatorT&&(r[i++]=E);return this.hasVertexNormals&&(r[i++]=e.octPackFloat(d)),i},c.prototype.decodePosition=function(t,r,i){if(a(i)||(i=new n),r*=this.getStride(),this.quantization===s.BITS12){var o=e.decompressTextureCoordinates(t[r],h);i.x=o.x,i.y=o.y;var c=e.decompressTextureCoordinates(t[r+1],h);return i.z=c.x,u.multiplyByPoint(this.fromScaledENU,i,i)}return i.x=t[r],i.y=t[r+1],i.z=t[r+2],n.add(i,this.center,i)},c.prototype.decodeTextureCoordinates=function(n,r,i){return a(i)||(i=new t),r*=this.getStride(),this.quantization===s.BITS12?e.decompressTextureCoordinates(n[r+2],i):t.fromElements(n[r+4],n[r+5],i)},c.prototype.decodeHeight=function(t,n){if(n*=this.getStride(),this.quantization===s.BITS12){return e.decompressTextureCoordinates(t[n+1],h).y*(this.maximumHeight-this.minimumHeight)+this.minimumHeight}return t[n+3]},c.prototype.getOctEncodedNormal=function(e,n,r){n=(n+1)*this.getStride()-1;var i=e[n]/256,a=Math.floor(i),o=256*(i-a);return t.fromElements(a,o,r)},c.prototype.getStride=function(){var e;switch(this.quantization){case s.BITS12:e=3;break;default:e=6}return this.hasWebMercatorT&&++e,this.hasVertexNormals&&++e,e};var p={position3DAndHeight:0,textureCoordAndEncodedNormals:1},_={compressed0:0,compressed1:1};return c.prototype.getAttributes=function(e){var t,n=r.FLOAT,i=r.getSizeInBytes(n);if(this.quantization===s.NONE){var a=2;return this.hasWebMercatorT&&++a,this.hasVertexNormals&&++a,t=(4+a)*i,[{index:p.position3DAndHeight,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:4,offsetInBytes:0,strideInBytes:t},{index:p.textureCoordAndEncodedNormals,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:a,offsetInBytes:4*i,strideInBytes:t}]}var o=3,u=0;return(this.hasWebMercatorT||this.hasVertexNormals)&&++o,this.hasWebMercatorT&&this.hasVertexNormals?(++u,t=(o+u)*i,[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o,offsetInBytes:0,strideInBytes:t},{index:_.compressed1,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:u,offsetInBytes:o*i,strideInBytes:t}]):[{index:_.compressed0,vertexBuffer:e,componentDatatype:n,componentsPerAttribute:o}]},c.prototype.getAttributeLocations=function(){return this.quantization===s.NONE?p:_},c.clone=function(e,t){return a(t)||(t=new c),t.quantization=e.quantization,t.minimumHeight=e.minimumHeight,t.maximumHeight=e.maximumHeight,t.center=n.clone(e.center),t.toScaledENU=u.clone(e.toScaledENU),t.fromScaledENU=u.clone(e.fromScaledENU),t.matrix=u.clone(e.matrix),t.hasVertexNormals=e.hasVertexNormals,t.hasWebMercatorT=e.hasWebMercatorT,t},c}),define("Core/formatError",["./defined"],function(e){"use strict";function t(t){var n,r=t.name,i=t.message;n=e(r)&&e(i)?r+": "+i:t.toString();var a=t.stack;return e(a)&&(n+="\n"+a),n}return t}),define("Workers/createTaskProcessorWorker",["../Core/defaultValue","../Core/defined","../Core/formatError"],function(e,t,n){"use strict";function r(r){var i,a=[],o={id:void 0,result:void 0,error:void 0};return function(u){var s=u.data;a.length=0,o.id=s.id,o.error=void 0,o.result=void 0;try{o.result=r(s.parameters,a)}catch(e){e instanceof Error?o.error={name:e.name,message:e.message,stack:e.stack}:o.error=e}t(i)||(i=e(self.webkitPostMessage,self.postMessage)),s.canTransferArrayBuffer||(a.length=0);try{i(o,a)}catch(e){o.result=void 0,o.error="postMessage failed with error: "+n(e)+"\n with responseMessage: "+JSON.stringify(o),i(o)}}}return r}),define("Workers/upsampleQuantizedTerrainMesh",["../Core/AttributeCompression","../Core/BoundingSphere","../Core/Cartesian2","../Core/Cartesian3","../Core/Cartographic","../Core/defined","../Core/Ellipsoid","../Core/EllipsoidalOccluder","../Core/IndexDatatype","../Core/Intersections2D","../Core/Math","../Core/OrientedBoundingBox","../Core/TerrainEncoding","./createTaskProcessorWorker"],function(e,t,n,r,i,a,o,u,s,c,l,f,h,d){"use strict";function E(e,n){var i=e.isEastChild,a=e.isNorthChild,d=i?T:0,E=i?y:T,p=a?T:0,L=a?y:T,F=N,B=I,b=O,z=w;F.length=0,B.length=0,b.length=0,z.length=0;var q=M;q.length=0;var G={},V=e.vertices,X=e.indices;X=X.subarray(0,e.skirtIndex);var W,H,Y,k=h.clone(e.encoding),j=k.hasVertexNormals,Z=e.exaggeration,K=0,J=e.vertexCountWithoutSkirts,Q=e.minimumHeight,$=e.maximumHeight,ee=new Array(J),te=new Array(J),ne=new Array(J),re=j?new Array(2*J):void 0;for(H=0,Y=0;H<J;++H,Y+=2){var ie=k.decodeTextureCoordinates(V,H,U);if(W=k.decodeHeight(V,H)/Z,ee[H]=l.clamp(ie.x*y|0,0,y),te[H]=l.clamp(ie.y*y|0,0,y),ne[H]=l.clamp((W-Q)/($-Q)*y|0,0,y),ee[H]<20&&(ee[H]=0),te[H]<20&&(te[H]=0),y-ee[H]<20&&(ee[H]=y),y-te[H]<20&&(te[H]=y),j){var ae=k.getOctEncodedNormal(V,H,D);re[Y]=ae.x,re[Y+1]=ae.y}}var oe,ue;for(H=0,Y=0;H<J;++H,Y+=2)oe=ee[H],ue=te[H],(i&&oe>=T||!i&&oe<=T)&&(a&&ue>=T||!a&&ue<=T)&&(G[H]=K,F.push(oe),B.push(ue),b.push(ne[H]),j&&(z.push(re[Y]),z.push(re[Y+1])),++K);var se=[];se.push(new m),se.push(new m),se.push(new m);var ce=[];ce.push(new m),ce.push(new m),ce.push(new m);var le,fe;for(H=0;H<X.length;H+=3){var he=X[H],de=X[H+1],Ee=X[H+2],me=ee[he],pe=ee[de],_e=ee[Ee];se[0].initializeIndexed(ee,te,ne,re,he),se[1].initializeIndexed(ee,te,ne,re,de),se[2].initializeIndexed(ee,te,ne,re,Ee);var ye=c.clipTriangleAtAxisAlignedThreshold(T,i,me,pe,_e,R);le=0,le>=ye.length||((le=ce[0].initializeFromClipResult(ye,le,se))>=ye.length||(le=ce[1].initializeFromClipResult(ye,le,se))>=ye.length||(le=ce[2].initializeFromClipResult(ye,le,se),fe=c.clipTriangleAtAxisAlignedThreshold(T,a,ce[0].getV(),ce[1].getV(),ce[2].getV(),A),_(F,B,b,z,q,G,fe,ce,j),le<ye.length&&(ce[2].clone(ce[1]),ce[2].initializeFromClipResult(ye,le,se),fe=c.clipTriangleAtAxisAlignedThreshold(T,a,ce[0].getV(),ce[1].getV(),ce[2].getV(),A),_(F,B,b,z,q,G,fe,ce,j))))}var Te=i?-y:0,Re=a?-y:0,Ae=[],Se=[],ve=[],ge=[],Ne=Number.MAX_VALUE,Ie=-Ne,Oe=S;Oe.length=0;var Me=o.clone(e.ellipsoid),we=e.childRectangle,Ce=we.north,xe=we.south,Pe=we.east,Ue=we.west;for(Pe<Ue&&(Pe+=l.TWO_PI),H=0;H<F.length;++H)oe=Math.round(F[H]),oe<=d?(Ae.push(H),oe=0):oe>=E?(ve.push(H),oe=y):oe=2*oe+Te,F[H]=oe,ue=Math.round(B[H]),ue<=p?(Se.push(H),ue=0):ue>=L?(ge.push(H),ue=y):ue=2*ue+Re,B[H]=ue,W=l.lerp(Q,$,b[H]/y),W<Ne&&(Ne=W),W>Ie&&(Ie=W),b[H]=W,v.longitude=l.lerp(Ue,Pe,oe/y),v.latitude=l.lerp(xe,Ce,ue/y),v.height=W,Me.cartographicToCartesian(v,g),Oe.push(g.x),Oe.push(g.y),Oe.push(g.z);var De=t.fromVertices(Oe,r.ZERO,3,x),Le=f.fromRectangle(we,Ne,Ie,Me,P),Fe=new u(Me),Be=Fe.computeHorizonCullingPointFromVertices(De.center,Oe,3,De.center,C),be=Ie-Ne,ze=new Uint16Array(F.length+B.length+b.length);for(H=0;H<F.length;++H)ze[H]=F[H];var qe=F.length;for(H=0;H<B.length;++H)ze[qe+H]=B[H];for(qe+=B.length,H=0;H<b.length;++H)ze[qe+H]=y*(b[H]-Ne)/be;var Ge,Ve=s.createTypedArray(F.length,q);if(j){var Xe=new Uint8Array(z);n.push(ze.buffer,Ve.buffer,Xe.buffer),Ge=Xe.buffer}else n.push(ze.buffer,Ve.buffer);return{vertices:ze.buffer,encodedNormals:Ge,indices:Ve.buffer,minimumHeight:Ne,maximumHeight:Ie,westIndices:Ae,southIndices:Se,eastIndices:ve,northIndices:ge,boundingSphere:De,orientedBoundingBox:Le,horizonOcclusionPoint:Be}}function m(){this.vertexBuffer=void 0,this.index=void 0,this.first=void 0,this.second=void 0,this.ratio=void 0}function p(t,n){++F;var i=B[F],a=b[F];return i=e.octDecode(t.first.getNormalX(),t.first.getNormalY(),i),a=e.octDecode(t.second.getNormalX(),t.second.getNormalY(),a),g=r.lerp(i,a,t.ratio,g),r.normalize(g,g),e.octEncode(g,n),--F,n}function _(e,t,n,r,i,o,u,s,c){if(0!==u.length){for(var l=0,f=0;f<u.length;)f=z[l++].initializeFromClipResult(u,f,s);for(var h=0;h<l;++h){var d=z[h];if(d.isIndexed())d.newIndex=o[d.index],d.uBuffer=e,d.vBuffer=t,d.heightBuffer=n,c&&(d.normalBuffer=r);else{var E=d.getKey();if(a(o[E]))d.newIndex=o[E];else{var m=e.length;e.push(d.getU()),t.push(d.getV()),n.push(d.getH()),c&&(r.push(d.getNormalX()),r.push(d.getNormalY())),d.newIndex=m,o[E]=m}}}3===l?(i.push(z[0].newIndex),i.push(z[1].newIndex),i.push(z[2].newIndex)):4===l&&(i.push(z[0].newIndex),i.push(z[1].newIndex),i.push(z[2].newIndex),i.push(z[0].newIndex),i.push(z[2].newIndex),i.push(z[3].newIndex))}}var y=32767,T=y/2|0,R=[],A=[],S=[],v=new i,g=new r,N=[],I=[],O=[],M=[],w=[],C=new r,x=new t,P=new f,U=new n,D=new r;m.prototype.clone=function(e){return a(e)||(e=new m),e.uBuffer=this.uBuffer,e.vBuffer=this.vBuffer,e.heightBuffer=this.heightBuffer,e.normalBuffer=this.normalBuffer,e.index=this.index,e.first=this.first,e.second=this.second,e.ratio=this.ratio,e},m.prototype.initializeIndexed=function(e,t,n,r,i){this.uBuffer=e,this.vBuffer=t,this.heightBuffer=n,this.normalBuffer=r,this.index=i,this.first=void 0,this.second=void 0,this.ratio=void 0},m.prototype.initializeFromClipResult=function(e,t,n){var r=t+1;return-1!==e[t]?n[e[t]].clone(this):(this.vertexBuffer=void 0,this.index=void 0,this.first=n[e[r]],++r,this.second=n[e[r]],++r,this.ratio=e[r],++r),r},m.prototype.getKey=function(){return this.isIndexed()?this.index:JSON.stringify({first:this.first.getKey(),second:this.second.getKey(),ratio:this.ratio})},m.prototype.isIndexed=function(){return a(this.index)},m.prototype.getH=function(){return a(this.index)?this.heightBuffer[this.index]:l.lerp(this.first.getH(),this.second.getH(),this.ratio)},m.prototype.getU=function(){return a(this.index)?this.uBuffer[this.index]:l.lerp(this.first.getU(),this.second.getU(),this.ratio)},m.prototype.getV=function(){return a(this.index)?this.vBuffer[this.index]:l.lerp(this.first.getV(),this.second.getV(),this.ratio)};var L=new n,F=-1,B=[new r,new r],b=[new r,new r];m.prototype.getNormalX=function(){return a(this.index)?this.normalBuffer[2*this.index]:(L=p(this,L),L.x)},m.prototype.getNormalY=function(){return a(this.index)?this.normalBuffer[2*this.index+1]:(L=p(this,L),L.y)};var z=[];return z.push(new m),z.push(new m),z.push(new m),z.push(new m),d(E)})}(); \ No newline at end of file diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Cesium.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Cesium.js index 63b11ced..9166ec54 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Cesium.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Cesium.js @@ -2022,6 +2022,594 @@ define('Core/defineProperties',[ return defineProperties; }); +define('Core/Fullscreen',[ + './defined', + './defineProperties' + ], function( + defined, + defineProperties) { + 'use strict'; + + var _supportsFullscreen; + var _names = { + requestFullscreen : undefined, + exitFullscreen : undefined, + fullscreenEnabled : undefined, + fullscreenElement : undefined, + fullscreenchange : undefined, + fullscreenerror : undefined + }; + + /** + * Browser-independent functions for working with the standard fullscreen API. + * + * @exports Fullscreen + * + * @see {@link http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html|W3C Fullscreen Living Specification} + */ + var Fullscreen = {}; + + defineProperties(Fullscreen, { + /** + * The element that is currently fullscreen, if any. To simply check if the + * browser is in fullscreen mode or not, use {@link Fullscreen#fullscreen}. + * @memberof Fullscreen + * @type {Object} + * @readonly + */ + element : { + get : function() { + if (!Fullscreen.supportsFullscreen()) { + return undefined; + } + + return document[_names.fullscreenElement]; + } + }, + + /** + * The name of the event on the document that is fired when fullscreen is + * entered or exited. This event name is intended for use with addEventListener. + * In your event handler, to determine if the browser is in fullscreen mode or not, + * use {@link Fullscreen#fullscreen}. + * @memberof Fullscreen + * @type {String} + * @readonly + */ + changeEventName : { + get : function() { + if (!Fullscreen.supportsFullscreen()) { + return undefined; + } + + return _names.fullscreenchange; + } + }, + + /** + * The name of the event that is fired when a fullscreen error + * occurs. This event name is intended for use with addEventListener. + * @memberof Fullscreen + * @type {String} + * @readonly + */ + errorEventName : { + get : function() { + if (!Fullscreen.supportsFullscreen()) { + return undefined; + } + + return _names.fullscreenerror; + } + }, + + /** + * Determine whether the browser will allow an element to be made fullscreen, or not. + * For example, by default, iframes cannot go fullscreen unless the containing page + * adds an "allowfullscreen" attribute (or prefixed equivalent). + * @memberof Fullscreen + * @type {Boolean} + * @readonly + */ + enabled : { + get : function() { + if (!Fullscreen.supportsFullscreen()) { + return undefined; + } + + return document[_names.fullscreenEnabled]; + } + }, + + /** + * Determines if the browser is currently in fullscreen mode. + * @memberof Fullscreen + * @type {Boolean} + * @readonly + */ + fullscreen : { + get : function() { + if (!Fullscreen.supportsFullscreen()) { + return undefined; + } + + return Fullscreen.element !== null; + } + } + }); + + /** + * Detects whether the browser supports the standard fullscreen API. + * + * @returns {Boolean} <code>true</code> if the browser supports the standard fullscreen API, + * <code>false</code> otherwise. + */ + Fullscreen.supportsFullscreen = function() { + if (defined(_supportsFullscreen)) { + return _supportsFullscreen; + } + + _supportsFullscreen = false; + + var body = document.body; + if (typeof body.requestFullscreen === 'function') { + // go with the unprefixed, standard set of names + _names.requestFullscreen = 'requestFullscreen'; + _names.exitFullscreen = 'exitFullscreen'; + _names.fullscreenEnabled = 'fullscreenEnabled'; + _names.fullscreenElement = 'fullscreenElement'; + _names.fullscreenchange = 'fullscreenchange'; + _names.fullscreenerror = 'fullscreenerror'; + _supportsFullscreen = true; + return _supportsFullscreen; + } + + //check for the correct combination of prefix plus the various names that browsers use + var prefixes = ['webkit', 'moz', 'o', 'ms', 'khtml']; + var name; + for (var i = 0, len = prefixes.length; i < len; ++i) { + var prefix = prefixes[i]; + + // casing of Fullscreen differs across browsers + name = prefix + 'RequestFullscreen'; + if (typeof body[name] === 'function') { + _names.requestFullscreen = name; + _supportsFullscreen = true; + } else { + name = prefix + 'RequestFullScreen'; + if (typeof body[name] === 'function') { + _names.requestFullscreen = name; + _supportsFullscreen = true; + } + } + + // disagreement about whether it's "exit" as per spec, or "cancel" + name = prefix + 'ExitFullscreen'; + if (typeof document[name] === 'function') { + _names.exitFullscreen = name; + } else { + name = prefix + 'CancelFullScreen'; + if (typeof document[name] === 'function') { + _names.exitFullscreen = name; + } + } + + // casing of Fullscreen differs across browsers + name = prefix + 'FullscreenEnabled'; + if (document[name] !== undefined) { + _names.fullscreenEnabled = name; + } else { + name = prefix + 'FullScreenEnabled'; + if (document[name] !== undefined) { + _names.fullscreenEnabled = name; + } + } + + // casing of Fullscreen differs across browsers + name = prefix + 'FullscreenElement'; + if (document[name] !== undefined) { + _names.fullscreenElement = name; + } else { + name = prefix + 'FullScreenElement'; + if (document[name] !== undefined) { + _names.fullscreenElement = name; + } + } + + // thankfully, event names are all lowercase per spec + name = prefix + 'fullscreenchange'; + // event names do not have 'on' in the front, but the property on the document does + if (document['on' + name] !== undefined) { + //except on IE + if (prefix === 'ms') { + name = 'MSFullscreenChange'; + } + _names.fullscreenchange = name; + } + + name = prefix + 'fullscreenerror'; + if (document['on' + name] !== undefined) { + //except on IE + if (prefix === 'ms') { + name = 'MSFullscreenError'; + } + _names.fullscreenerror = name; + } + } + + return _supportsFullscreen; + }; + + /** + * Asynchronously requests the browser to enter fullscreen mode on the given element. + * If fullscreen mode is not supported by the browser, does nothing. + * + * @param {Object} element The HTML element which will be placed into fullscreen mode. + * @param {HMDVRDevice} [vrDevice] The VR device. + * + * @example + * // Put the entire page into fullscreen. + * Cesium.Fullscreen.requestFullscreen(document.body) + * + * // Place only the Cesium canvas into fullscreen. + * Cesium.Fullscreen.requestFullscreen(scene.canvas) + */ + Fullscreen.requestFullscreen = function(element, vrDevice) { + if (!Fullscreen.supportsFullscreen()) { + return; + } + + element[_names.requestFullscreen]({ vrDisplay: vrDevice }); + }; + + /** + * Asynchronously exits fullscreen mode. If the browser is not currently + * in fullscreen, or if fullscreen mode is not supported by the browser, does nothing. + */ + Fullscreen.exitFullscreen = function() { + if (!Fullscreen.supportsFullscreen()) { + return; + } + + document[_names.exitFullscreen](); + }; + + return Fullscreen; +}); + +define('Core/FeatureDetection',[ + './defaultValue', + './defined', + './Fullscreen' + ], function( + defaultValue, + defined, + Fullscreen) { + 'use strict'; + + var theNavigator; + if (typeof navigator !== 'undefined') { + theNavigator = navigator; + } else { + theNavigator = {}; + } + + function extractVersion(versionString) { + var parts = versionString.split('.'); + for (var i = 0, len = parts.length; i < len; ++i) { + parts[i] = parseInt(parts[i], 10); + } + return parts; + } + + var isChromeResult; + var chromeVersionResult; + function isChrome() { + if (!defined(isChromeResult)) { + isChromeResult = false; + // Edge contains Chrome in the user agent too + if (!isEdge()) { + var fields = (/ Chrome\/([\.0-9]+)/).exec(theNavigator.userAgent); + if (fields !== null) { + isChromeResult = true; + chromeVersionResult = extractVersion(fields[1]); + } + } + } + + return isChromeResult; + } + + function chromeVersion() { + return isChrome() && chromeVersionResult; + } + + var isSafariResult; + var safariVersionResult; + function isSafari() { + if (!defined(isSafariResult)) { + isSafariResult = false; + + // Chrome and Edge contain Safari in the user agent too + if (!isChrome() && !isEdge() && (/ Safari\/[\.0-9]+/).test(theNavigator.userAgent)) { + var fields = (/ Version\/([\.0-9]+)/).exec(theNavigator.userAgent); + if (fields !== null) { + isSafariResult = true; + safariVersionResult = extractVersion(fields[1]); + } + } + } + + return isSafariResult; + } + + function safariVersion() { + return isSafari() && safariVersionResult; + } + + var isWebkitResult; + var webkitVersionResult; + function isWebkit() { + if (!defined(isWebkitResult)) { + isWebkitResult = false; + + var fields = (/ AppleWebKit\/([\.0-9]+)(\+?)/).exec(theNavigator.userAgent); + if (fields !== null) { + isWebkitResult = true; + webkitVersionResult = extractVersion(fields[1]); + webkitVersionResult.isNightly = !!fields[2]; + } + } + + return isWebkitResult; + } + + function webkitVersion() { + return isWebkit() && webkitVersionResult; + } + + var isInternetExplorerResult; + var internetExplorerVersionResult; + function isInternetExplorer() { + if (!defined(isInternetExplorerResult)) { + isInternetExplorerResult = false; + + var fields; + if (theNavigator.appName === 'Microsoft Internet Explorer') { + fields = /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(theNavigator.userAgent); + if (fields !== null) { + isInternetExplorerResult = true; + internetExplorerVersionResult = extractVersion(fields[1]); + } + } else if (theNavigator.appName === 'Netscape') { + fields = /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(theNavigator.userAgent); + if (fields !== null) { + isInternetExplorerResult = true; + internetExplorerVersionResult = extractVersion(fields[1]); + } + } + } + return isInternetExplorerResult; + } + + function internetExplorerVersion() { + return isInternetExplorer() && internetExplorerVersionResult; + } + + var isEdgeResult; + var edgeVersionResult; + function isEdge() { + if (!defined(isEdgeResult)) { + isEdgeResult = false; + var fields = (/ Edge\/([\.0-9]+)/).exec(theNavigator.userAgent); + if (fields !== null) { + isEdgeResult = true; + edgeVersionResult = extractVersion(fields[1]); + } + } + return isEdgeResult; + } + + function edgeVersion() { + return isEdge() && edgeVersionResult; + } + + var isFirefoxResult; + var firefoxVersionResult; + function isFirefox() { + if (!defined(isFirefoxResult)) { + isFirefoxResult = false; + + var fields = /Firefox\/([\.0-9]+)/.exec(theNavigator.userAgent); + if (fields !== null) { + isFirefoxResult = true; + firefoxVersionResult = extractVersion(fields[1]); + } + } + return isFirefoxResult; + } + + var isWindowsResult; + function isWindows() { + if (!defined(isWindowsResult)) { + isWindowsResult = /Windows/i.test(theNavigator.appVersion); + } + return isWindowsResult; + } + + + function firefoxVersion() { + return isFirefox() && firefoxVersionResult; + } + + var hasPointerEvents; + function supportsPointerEvents() { + if (!defined(hasPointerEvents)) { + //While navigator.pointerEnabled is deprecated in the W3C specification + //we still need to use it if it exists in order to support browsers + //that rely on it, such as the Windows WebBrowser control which defines + //PointerEvent but sets navigator.pointerEnabled to false. + hasPointerEvents = typeof PointerEvent !== 'undefined' && (!defined(theNavigator.pointerEnabled) || theNavigator.pointerEnabled); + } + return hasPointerEvents; + } + + var imageRenderingValueResult; + var supportsImageRenderingPixelatedResult; + function supportsImageRenderingPixelated() { + if (!defined(supportsImageRenderingPixelatedResult)) { + var canvas = document.createElement('canvas'); + canvas.setAttribute('style', + 'image-rendering: -moz-crisp-edges;' + + 'image-rendering: pixelated;'); + //canvas.style.imageRendering will be undefined, null or an empty string on unsupported browsers. + var tmp = canvas.style.imageRendering; + supportsImageRenderingPixelatedResult = defined(tmp) && tmp !== ''; + if (supportsImageRenderingPixelatedResult) { + imageRenderingValueResult = tmp; + } + } + return supportsImageRenderingPixelatedResult; + } + + function imageRenderingValue() { + return supportsImageRenderingPixelated() ? imageRenderingValueResult : undefined; + } + + /** + * A set of functions to detect whether the current browser supports + * various features. + * + * @exports FeatureDetection + */ + var FeatureDetection = { + isChrome : isChrome, + chromeVersion : chromeVersion, + isSafari : isSafari, + safariVersion : safariVersion, + isWebkit : isWebkit, + webkitVersion : webkitVersion, + isInternetExplorer : isInternetExplorer, + internetExplorerVersion : internetExplorerVersion, + isEdge : isEdge, + edgeVersion : edgeVersion, + isFirefox : isFirefox, + firefoxVersion : firefoxVersion, + isWindows : isWindows, + hardwareConcurrency : defaultValue(theNavigator.hardwareConcurrency, 3), + supportsPointerEvents : supportsPointerEvents, + supportsImageRenderingPixelated: supportsImageRenderingPixelated, + imageRenderingValue: imageRenderingValue + }; + + /** + * Detects whether the current browser supports the full screen standard. + * + * @returns {Boolean} true if the browser supports the full screen standard, false if not. + * + * @see Fullscreen + * @see {@link http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html|W3C Fullscreen Living Specification} + */ + FeatureDetection.supportsFullscreen = function() { + return Fullscreen.supportsFullscreen(); + }; + + /** + * Detects whether the current browser supports typed arrays. + * + * @returns {Boolean} true if the browser supports typed arrays, false if not. + * + * @see {@link http://www.khronos.org/registry/typedarray/specs/latest/|Typed Array Specification} + */ + FeatureDetection.supportsTypedArrays = function() { + return typeof ArrayBuffer !== 'undefined'; + }; + + /** + * Detects whether the current browser supports Web Workers. + * + * @returns {Boolean} true if the browsers supports Web Workers, false if not. + * + * @see {@link http://www.w3.org/TR/workers/} + */ + FeatureDetection.supportsWebWorkers = function() { + return typeof Worker !== 'undefined'; + }; + + return FeatureDetection; +}); + +define('Core/arraySlice',[ + './Check', + './defaultValue', + './defined', + './FeatureDetection' + ], function( + Check, + defaultValue, + defined, + FeatureDetection) { + 'use strict'; + + var slice = function(array, begin, end) { + Check.defined('array', array); + if (defined(begin)) { + Check.typeOf.number('begin', begin); + } + if (defined(end)) { + Check.typeOf.number('end', end); + } + return array.slice(begin, end); + }; + + if (FeatureDetection.supportsTypedArrays()) { + var tempArray = new Uint8Array(1); + if (typeof tempArray.slice !== 'function') { + var typedArrayTypes = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + slice = function(array, begin, end) { + Check.defined('array', array); + if (defined(begin)) { + Check.typeOf.number('begin', begin); + } + if (defined(end)) { + Check.typeOf.number('end', end); + } + + if (typeof array.slice === 'function') { + return array.slice(begin, end); + } + + var copy = Array.prototype.slice.call(array, begin, end); + var length = typedArrayTypes.length; + for (var i = 0; i < length; ++i) { + if (array instanceof typedArrayTypes[i]) { + copy = new typedArrayTypes[i](copy); + break; + } + } + + return copy; + }; + } + } + + /** + * Create a shallow copy of an array from begin to end. + * + * @param {Array} array The array to fill. + * @param {Number} [begin=0] The index to start at. + * @param {Number} [end=array.length] The index to end at which is not included. + * + * @returns {Array} The resulting array. + * @private + */ + function arraySlice(array, begin, end) { + return slice(array, begin, end); + } + + return arraySlice; +}); + define('Core/AssociativeArray',[ './defined', './defineProperties', @@ -3481,6 +4069,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -3841,12 +4445,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -4098,6 +4704,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -4560,7 +5207,7 @@ define('Core/Credit',[ * var credit = new Cesium.Credit({ * text : 'Cesium', * imageUrl : '/images/cesium_logo.png', - * link : 'http://cesiumjs.org/' + * link : 'https://cesiumjs.org/' * }); */ function Credit(options) { @@ -4754,7 +5401,7 @@ define('Core/BingMapsApi',[ console.log(errorString); printedBingWarning = true; } - return 'Aig5SkZ4pNMN8b4rX-RUH2c_95mK-wjb4WL9k50K51faErEGnNsxgpWHXiqS3Rhe'; + return 'Ar9n20kTp-N8tEg3Dpx-Pgocmx3W0-GUnD_Bgt3h8g6pSeDL8yxByTVGHyMyjI2p'; } return BingMapsApi.defaultKey; @@ -4778,6427 +5425,6752 @@ define('Core/BingMapsApi',[ return BingMapsApi; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { +define('Core/scaleToGeodeticSurface',[ + './Cartesian3', + './defined', + './DeveloperError', + './Math' + ], function( + Cartesian3, + defined, + DeveloperError, + CesiumMath) { + 'use strict'; - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; + var scaleToGeodeticSurfaceIntersection = new Cartesian3(); + var scaleToGeodeticSurfaceGradient = new Cartesian3(); - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + /** + * Scales the provided Cartesian position along the geodetic surface normal + * so that it is on the surface of this ellipsoid. If the position is + * at the center of the ellipsoid, this function returns undefined. + * + * @param {Cartesian3} cartesian The Cartesian position to scale. + * @param {Cartesian3} oneOverRadii One over radii of the ellipsoid. + * @param {Cartesian3} oneOverRadiiSquared One over radii squared of the ellipsoid. + * @param {Number} centerToleranceSquared Tolerance for closeness to the center. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center. + * + * @exports scaleToGeodeticSurface + * + * @private + */ + function scaleToGeodeticSurface(cartesian, oneOverRadii, oneOverRadiiSquared, centerToleranceSquared, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + if (!defined(oneOverRadii)) { + throw new DeveloperError('oneOverRadii is required.'); + } + if (!defined(oneOverRadiiSquared)) { + throw new DeveloperError('oneOverRadiiSquared is required.'); + } + if (!defined(centerToleranceSquared)) { + throw new DeveloperError('centerToleranceSquared is required.'); + } + + var positionX = cartesian.x; + var positionY = cartesian.y; + var positionZ = cartesian.z; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + var oneOverRadiiX = oneOverRadii.x; + var oneOverRadiiY = oneOverRadii.y; + var oneOverRadiiZ = oneOverRadii.z; - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + var x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX; + var y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY; + var z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ; - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; + // Compute the squared ellipsoid norm. + var squaredNorm = x2 + y2 + z2; + var ratio = Math.sqrt(1.0 / squaredNorm); - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + // As an initial approximation, assume that the radial intersection is the projection point. + var intersection = Cartesian3.multiplyByScalar(cartesian, ratio, scaleToGeodeticSurfaceIntersection); - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + // If the position is near the center, the iteration will not converge. + if (squaredNorm < centerToleranceSquared) { + return !isFinite(ratio) ? undefined : Cartesian3.clone(intersection, result); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + var oneOverRadiiSquaredX = oneOverRadiiSquared.x; + var oneOverRadiiSquaredY = oneOverRadiiSquared.y; + var oneOverRadiiSquaredZ = oneOverRadiiSquared.z; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // Use the gradient at the intersection point in place of the true unit normal. + // The difference in magnitude will be absorbed in the multiplier. + var gradient = scaleToGeodeticSurfaceGradient; + gradient.x = intersection.x * oneOverRadiiSquaredX * 2.0; + gradient.y = intersection.y * oneOverRadiiSquaredY * 2.0; + gradient.z = intersection.z * oneOverRadiiSquaredZ * 2.0; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + // Compute the initial guess at the normal vector multiplier, lambda. + var lambda = (1.0 - ratio) * Cartesian3.magnitude(cartesian) / (0.5 * Cartesian3.magnitude(gradient)); + var correction = 0.0; - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + var func; + var denominator; + var xMultiplier; + var yMultiplier; + var zMultiplier; + var xMultiplier2; + var yMultiplier2; + var zMultiplier2; + var xMultiplier3; + var yMultiplier3; + var zMultiplier3; - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + do { + lambda -= correction; - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX); + yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY); + zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ); - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + xMultiplier2 = xMultiplier * xMultiplier; + yMultiplier2 = yMultiplier * yMultiplier; + zMultiplier2 = zMultiplier * zMultiplier; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + xMultiplier3 = xMultiplier2 * xMultiplier; + yMultiplier3 = yMultiplier2 * yMultiplier; + zMultiplier3 = zMultiplier2 * zMultiplier; - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0; - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; + // "denominator" here refers to the use of this expression in the velocity and acceleration + // computations in the sections to follow. + denominator = x2 * xMultiplier3 * oneOverRadiiSquaredX + y2 * yMultiplier3 * oneOverRadiiSquaredY + z2 * zMultiplier3 * oneOverRadiiSquaredZ; - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var derivative = -2.0 * denominator; -// var cache = {}; + correction = func / derivative; + } while (Math.abs(func) > CesiumMath.EPSILON12); - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + if (!defined(result)) { + return new Cartesian3(positionX * xMultiplier, positionY * yMultiplier, positionZ * zMultiplier); + } + result.x = positionX * xMultiplier; + result.y = positionY * yMultiplier; + result.z = positionZ * zMultiplier; + return result; + } -return URI; + return scaleToGeodeticSurface; }); -/** - @license - when.js - https://github.com/cujojs/when - - MIT License (c) copyright B Cavalier & J Hann - - * A lightweight CommonJS Promises/A and when() implementation - * when is part of the cujo.js family of libraries (http://cujojs.com/) - * - * Licensed under the MIT License at: - * http://www.opensource.org/licenses/mit-license.php - * - * @version 1.7.1 - */ - -(function(define) { 'use strict'; -define('ThirdParty/when',[],function () { - var reduceArray, slice, undef; - - // - // Public API - // - - when.defer = defer; // Create a deferred - when.resolve = resolve; // Create a resolved promise - when.reject = reject; // Create a rejected promise - - when.join = join; // Join 2 or more promises - - when.all = all; // Resolve a list of promises - when.map = map; // Array.map() for promises - when.reduce = reduce; // Array.reduce() for promises - - when.any = any; // One-winner race - when.some = some; // Multi-winner race +define('Core/Cartographic',[ + './Cartesian3', + './Check', + './defaultValue', + './defined', + './freezeObject', + './Math', + './scaleToGeodeticSurface' + ], function( + Cartesian3, + Check, + defaultValue, + defined, + freezeObject, + CesiumMath, + scaleToGeodeticSurface) { + 'use strict'; - when.chain = chain; // Make a promise trigger another resolver + /** + * A position defined by longitude, latitude, and height. + * @alias Cartographic + * @constructor + * + * @param {Number} [longitude=0.0] The longitude, in radians. + * @param {Number} [latitude=0.0] The latitude, in radians. + * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * + * @see Ellipsoid + */ + function Cartographic(longitude, latitude, height) { + /** + * The longitude, in radians. + * @type {Number} + * @default 0.0 + */ + this.longitude = defaultValue(longitude, 0.0); - when.isPromise = isPromise; // Determine if a thing is a promise + /** + * The latitude, in radians. + * @type {Number} + * @default 0.0 + */ + this.latitude = defaultValue(latitude, 0.0); - /** - * Register an observer for a promise or immediate value. - * - * @param {*} promiseOrValue - * @param {function?} [onFulfilled] callback to be called when promiseOrValue is - * successfully fulfilled. If promiseOrValue is an immediate value, callback - * will be invoked immediately. - * @param {function?} [onRejected] callback to be called when promiseOrValue is - * rejected. - * @param {function?} [onProgress] callback to be called when progress updates - * are issued for promiseOrValue. - * @returns {Promise} a new {@link Promise} that will complete with the return - * value of callback or errback or the completion value of promiseOrValue if - * callback and/or errback is not supplied. - */ - function when(promiseOrValue, onFulfilled, onRejected, onProgress) { - // Get a trusted promise for the input promiseOrValue, and then - // register promise handlers - return resolve(promiseOrValue).then(onFulfilled, onRejected, onProgress); - } + /** + * The height, in meters, above the ellipsoid. + * @type {Number} + * @default 0.0 + */ + this.height = defaultValue(height, 0.0); + } - /** - * Returns promiseOrValue if promiseOrValue is a {@link Promise}, a new Promise if - * promiseOrValue is a foreign promise, or a new, already-fulfilled {@link Promise} - * whose value is promiseOrValue if promiseOrValue is an immediate value. - * - * @param {*} promiseOrValue - * @returns Guaranteed to return a trusted Promise. If promiseOrValue is a when.js {@link Promise} - * returns promiseOrValue, otherwise, returns a new, already-resolved, when.js {@link Promise} - * whose resolution value is: - * * the resolution value of promiseOrValue if it's a foreign promise, or - * * promiseOrValue if it's a value - */ - function resolve(promiseOrValue) { - var promise, deferred; + /** + * Creates a new Cartographic instance from longitude and latitude + * specified in radians. + * + * @param {Number} longitude The longitude, in radians. + * @param {Number} latitude The latitude, in radians. + * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. + */ + Cartographic.fromRadians = function(longitude, latitude, height, result) { + Check.typeOf.number('longitude', longitude); + Check.typeOf.number('latitude', latitude); + + height = defaultValue(height, 0.0); - if(promiseOrValue instanceof Promise) { - // It's a when.js promise, so we trust it - promise = promiseOrValue; + if (!defined(result)) { + return new Cartographic(longitude, latitude, height); + } - } else { - // It's not a when.js promise. See if it's a foreign promise or a value. - if(isPromise(promiseOrValue)) { - // It's a thenable, but we don't know where it came from, so don't trust - // its implementation entirely. Introduce a trusted middleman when.js promise - deferred = defer(); + result.longitude = longitude; + result.latitude = latitude; + result.height = height; + return result; + }; - // IMPORTANT: This is the only place when.js should ever call .then() on an - // untrusted promise. Don't expose the return value to the untrusted promise - promiseOrValue.then( - function(value) { deferred.resolve(value); }, - function(reason) { deferred.reject(reason); }, - function(update) { deferred.progress(update); } - ); + /** + * Creates a new Cartographic instance from longitude and latitude + * specified in degrees. The values in the resulting object will + * be in radians. + * + * @param {Number} longitude The longitude, in degrees. + * @param {Number} latitude The latitude, in degrees. + * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. + */ + Cartographic.fromDegrees = function(longitude, latitude, height, result) { + Check.typeOf.number('longitude', longitude); + Check.typeOf.number('latitude', latitude); + longitude = CesiumMath.toRadians(longitude); + latitude = CesiumMath.toRadians(latitude); - promise = deferred.promise; + return Cartographic.fromRadians(longitude, latitude, height, result); + }; - } else { - // It's a value, not a promise. Create a resolved promise for it. - promise = fulfilled(promiseOrValue); - } - } + var cartesianToCartographicN = new Cartesian3(); + var cartesianToCartographicP = new Cartesian3(); + var cartesianToCartographicH = new Cartesian3(); + var wgs84OneOverRadii = new Cartesian3(1.0 / 6378137.0, 1.0 / 6378137.0, 1.0 / 6356752.3142451793); + var wgs84OneOverRadiiSquared = new Cartesian3(1.0 / (6378137.0 * 6378137.0), 1.0 / (6378137.0 * 6378137.0), 1.0 / (6356752.3142451793 * 6356752.3142451793)); + var wgs84CenterToleranceSquared = CesiumMath.EPSILON1; - return promise; - } + /** + * Creates a new Cartographic instance from a Cartesian position. The values in the + * resulting object will be in radians. + * + * @param {Cartesian3} cartesian The Cartesian position to convert to cartographic representation. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter, new Cartographic instance if none was provided, or undefined if the cartesian is at the center of the ellipsoid. + */ + Cartographic.fromCartesian = function(cartesian, ellipsoid, result) { + var oneOverRadii = defined(ellipsoid) ? ellipsoid.oneOverRadii : wgs84OneOverRadii; + var oneOverRadiiSquared = defined(ellipsoid) ? ellipsoid.oneOverRadiiSquared : wgs84OneOverRadiiSquared; + var centerToleranceSquared = defined(ellipsoid) ? ellipsoid._centerToleranceSquared : wgs84CenterToleranceSquared; - /** - * Returns a rejected promise for the supplied promiseOrValue. The returned - * promise will be rejected with: - * - promiseOrValue, if it is a value, or - * - if promiseOrValue is a promise - * - promiseOrValue's value after it is fulfilled - * - promiseOrValue's reason after it is rejected - * @param {*} promiseOrValue the rejected value of the returned {@link Promise} - * @returns {Promise} rejected {@link Promise} - */ - function reject(promiseOrValue) { - return when(promiseOrValue, rejected); - } + //`cartesian is required.` is thrown from scaleToGeodeticSurface + var p = scaleToGeodeticSurface(cartesian, oneOverRadii, oneOverRadiiSquared, centerToleranceSquared, cartesianToCartographicP); - /** - * Trusted Promise constructor. A Promise created from this constructor is - * a trusted when.js promise. Any other duck-typed promise is considered - * untrusted. - * @constructor - * @name Promise - */ - function Promise(then) { - this.then = then; - } + if (!defined(p)) { + return undefined; + } - Promise.prototype = { - /** - * Register a callback that will be called when a promise is - * fulfilled or rejected. Optionally also register a progress handler. - * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress) - * @param {function?} [onFulfilledOrRejected] - * @param {function?} [onProgress] - * @returns {Promise} - */ - always: function(onFulfilledOrRejected, onProgress) { - return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress); - }, + var n = Cartesian3.multiplyComponents(p, oneOverRadiiSquared, cartesianToCartographicN); + n = Cartesian3.normalize(n, n); - /** - * Register a rejection handler. Shortcut for .then(undefined, onRejected) - * @param {function?} onRejected - * @returns {Promise} - */ - otherwise: function(onRejected) { - return this.then(undef, onRejected); - }, + var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH); - /** - * Shortcut for .then(function() { return value; }) - * @param {*} value - * @returns {Promise} a promise that: - * - is fulfilled if value is not a promise, or - * - if value is a promise, will fulfill with its value, or reject - * with its reason. - */ - yield: function(value) { - return this.then(function() { - return value; - }); - }, + var longitude = Math.atan2(n.y, n.x); + var latitude = Math.asin(n.z); + var height = CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h); - /** - * Assumes that this promise will fulfill with an array, and arranges - * for the onFulfilled to be called with the array as its argument list - * i.e. onFulfilled.spread(undefined, array). - * @param {function} onFulfilled function to receive spread arguments - * @returns {Promise} - */ - spread: function(onFulfilled) { - return this.then(function(array) { - // array may contain promises, so resolve its contents. - return all(array, function(array) { - return onFulfilled.apply(undef, array); - }); - }); - } - }; + if (!defined(result)) { + return new Cartographic(longitude, latitude, height); + } + result.longitude = longitude; + result.latitude = latitude; + result.height = height; + return result; + }; - /** - * Create an already-resolved promise for the supplied value - * @private - * - * @param {*} value - * @returns {Promise} fulfilled promise - */ - function fulfilled(value) { - var p = new Promise(function(onFulfilled) { - // TODO: Promises/A+ check typeof onFulfilled - try { - return resolve(onFulfilled ? onFulfilled(value) : value); - } catch(e) { - return rejected(e); - } - }); + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; - return p; - } + /** + * Duplicates a Cartographic instance. + * + * @param {Cartographic} cartographic The cartographic to duplicate. + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. (Returns undefined if cartographic is undefined) + */ + Cartographic.clone = function(cartographic, result) { + if (!defined(cartographic)) { + return undefined; + } + if (!defined(result)) { + return new Cartographic(cartographic.longitude, cartographic.latitude, cartographic.height); + } + result.longitude = cartographic.longitude; + result.latitude = cartographic.latitude; + result.height = cartographic.height; + return result; + }; - /** - * Create an already-rejected {@link Promise} with the supplied - * rejection reason. - * @private - * - * @param {*} reason - * @returns {Promise} rejected promise - */ - function rejected(reason) { - var p = new Promise(function(_, onRejected) { - // TODO: Promises/A+ check typeof onRejected - try { - return onRejected ? resolve(onRejected(reason)) : rejected(reason); - } catch(e) { - return rejected(e); - } - }); + /** + * Compares the provided cartographics componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Cartographic} [left] The first cartographic. + * @param {Cartographic} [right] The second cartographic. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + Cartographic.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + (left.longitude === right.longitude) && + (left.latitude === right.latitude) && + (left.height === right.height)); + }; - return p; - } + /** + * Compares the provided cartographics componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Cartographic} [left] The first cartographic. + * @param {Cartographic} [right] The second cartographic. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + */ + Cartographic.equalsEpsilon = function(left, right, epsilon) { + Check.typeOf.number('epsilon', epsilon); + + return (left === right) || + ((defined(left)) && + (defined(right)) && + (Math.abs(left.longitude - right.longitude) <= epsilon) && + (Math.abs(left.latitude - right.latitude) <= epsilon) && + (Math.abs(left.height - right.height) <= epsilon)); + }; - /** - * Creates a new, Deferred with fully isolated resolver and promise parts, - * either or both of which may be given out safely to consumers. - * The Deferred itself has the full API: resolve, reject, progress, and - * then. The resolver has resolve, reject, and progress. The promise - * only has then. - * - * @returns {Deferred} - */ - function defer() { - var deferred, promise, handlers, progressHandlers, - _then, _progress, _resolve; + /** + * An immutable Cartographic instance initialized to (0.0, 0.0, 0.0). + * + * @type {Cartographic} + * @constant + */ + Cartographic.ZERO = freezeObject(new Cartographic(0.0, 0.0, 0.0)); - /** - * The promise for the new deferred - * @type {Promise} - */ - promise = new Promise(then); + /** + * Duplicates this instance. + * + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. + */ + Cartographic.prototype.clone = function(result) { + return Cartographic.clone(this, result); + }; - /** - * The full Deferred object, with {@link Promise} and {@link Resolver} parts - * @class Deferred - * @name Deferred - */ - deferred = { - then: then, // DEPRECATED: use deferred.promise.then - resolve: promiseResolve, - reject: promiseReject, - // TODO: Consider renaming progress() to notify() - progress: promiseProgress, + /** + * Compares the provided against this cartographic componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Cartographic} [right] The second cartographic. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + Cartographic.prototype.equals = function(right) { + return Cartographic.equals(this, right); + }; - promise: promise, + /** + * Compares the provided against this cartographic componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Cartographic} [right] The second cartographic. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + */ + Cartographic.prototype.equalsEpsilon = function(right, epsilon) { + return Cartographic.equalsEpsilon(this, right, epsilon); + }; - resolver: { - resolve: promiseResolve, - reject: promiseReject, - progress: promiseProgress - } - }; + /** + * Creates a string representing this cartographic in the format '(longitude, latitude, height)'. + * + * @returns {String} A string representing the provided cartographic in the format '(longitude, latitude, height)'. + */ + Cartographic.prototype.toString = function() { + return '(' + this.longitude + ', ' + this.latitude + ', ' + this.height + ')'; + }; - handlers = []; - progressHandlers = []; + return Cartographic; +}); - /** - * Pre-resolution then() that adds the supplied callback, errback, and progback - * functions to the registered listeners - * @private - * - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - */ - _then = function(onFulfilled, onRejected, onProgress) { - // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress - var deferred, progressHandler; +define('Core/Ellipsoid',[ + './Cartesian3', + './Cartographic', + './Check', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './freezeObject', + './Math', + './scaleToGeodeticSurface' + ], function( + Cartesian3, + Cartographic, + Check, + defaultValue, + defined, + defineProperties, + DeveloperError, + freezeObject, + CesiumMath, + scaleToGeodeticSurface) { + 'use strict'; - deferred = defer(); + function initialize(ellipsoid, x, y, z) { + x = defaultValue(x, 0.0); + y = defaultValue(y, 0.0); + z = defaultValue(z, 0.0); - progressHandler = typeof onProgress === 'function' - ? function(update) { - try { - // Allow progress handler to transform progress event - deferred.progress(onProgress(update)); - } catch(e) { - // Use caught value as progress - deferred.progress(e); - } - } - : function(update) { deferred.progress(update); }; + Check.typeOf.number.greaterThanOrEquals('x', x, 0.0); + Check.typeOf.number.greaterThanOrEquals('y', y, 0.0); + Check.typeOf.number.greaterThanOrEquals('z', z, 0.0); + + ellipsoid._radii = new Cartesian3(x, y, z); - handlers.push(function(promise) { - promise.then(onFulfilled, onRejected) - .then(deferred.resolve, deferred.reject, progressHandler); - }); + ellipsoid._radiiSquared = new Cartesian3(x * x, + y * y, + z * z); - progressHandlers.push(progressHandler); + ellipsoid._radiiToTheFourth = new Cartesian3(x * x * x * x, + y * y * y * y, + z * z * z * z); - return deferred.promise; - }; + ellipsoid._oneOverRadii = new Cartesian3(x === 0.0 ? 0.0 : 1.0 / x, + y === 0.0 ? 0.0 : 1.0 / y, + z === 0.0 ? 0.0 : 1.0 / z); - /** - * Issue a progress event, notifying all progress listeners - * @private - * @param {*} update progress event payload to pass to all listeners - */ - _progress = function(update) { - processQueue(progressHandlers, update); - return update; - }; + ellipsoid._oneOverRadiiSquared = new Cartesian3(x === 0.0 ? 0.0 : 1.0 / (x * x), + y === 0.0 ? 0.0 : 1.0 / (y * y), + z === 0.0 ? 0.0 : 1.0 / (z * z)); - /** - * Transition from pre-resolution state to post-resolution state, notifying - * all listeners of the resolution or rejection - * @private - * @param {*} value the value of this deferred - */ - _resolve = function(value) { - value = resolve(value); + ellipsoid._minimumRadius = Math.min(x, y, z); - // Replace _then with one that directly notifies with the result. - _then = value.then; - // Replace _resolve so that this Deferred can only be resolved once - _resolve = resolve; - // Make _progress a noop, to disallow progress for the resolved promise. - _progress = noop; + ellipsoid._maximumRadius = Math.max(x, y, z); - // Notify handlers - processQueue(handlers, value); + ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1; - // Free progressHandlers array since we'll never issue progress events - progressHandlers = handlers = undef; + if (ellipsoid._radiiSquared.z !== 0) { + ellipsoid._squaredXOverSquaredZ = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z; + } + } - return value; - }; + /** + * A quadratic surface defined in Cartesian coordinates by the equation + * <code>(x / a)^2 + (y / b)^2 + (z / c)^2 = 1</code>. Primarily used + * by Cesium to represent the shape of planetary bodies. + * + * Rather than constructing this object directly, one of the provided + * constants is normally used. + * @alias Ellipsoid + * @constructor + * + * @param {Number} [x=0] The radius in the x direction. + * @param {Number} [y=0] The radius in the y direction. + * @param {Number} [z=0] The radius in the z direction. + * + * @exception {DeveloperError} All radii components must be greater than or equal to zero. + * + * @see Ellipsoid.fromCartesian3 + * @see Ellipsoid.WGS84 + * @see Ellipsoid.UNIT_SPHERE + */ + function Ellipsoid(x, y, z) { + this._radii = undefined; + this._radiiSquared = undefined; + this._radiiToTheFourth = undefined; + this._oneOverRadii = undefined; + this._oneOverRadiiSquared = undefined; + this._minimumRadius = undefined; + this._maximumRadius = undefined; + this._centerToleranceSquared = undefined; + this._squaredXOverSquaredZ = undefined; - return deferred; + initialize(this, x, y, z); + } - /** - * Wrapper to allow _then to be replaced safely - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} new promise - */ - function then(onFulfilled, onRejected, onProgress) { - // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress - return _then(onFulfilled, onRejected, onProgress); - } - - /** - * Wrapper to allow _resolve to be replaced - */ - function promiseResolve(val) { - return _resolve(val); - } - - /** - * Wrapper to allow _reject to be replaced - */ - function promiseReject(err) { - return _resolve(rejected(err)); - } - - /** - * Wrapper to allow _progress to be replaced - */ - function promiseProgress(update) { - return _progress(update); - } - } - - /** - * Determines if promiseOrValue is a promise or not. Uses the feature - * test from http://wiki.commonjs.org/wiki/Promises/A to determine if - * promiseOrValue is a promise. - * - * @param {*} promiseOrValue anything - * @returns {boolean} true if promiseOrValue is a {@link Promise} - */ - function isPromise(promiseOrValue) { - return promiseOrValue && typeof promiseOrValue.then === 'function'; - } - - /** - * Initiates a competitive race, returning a promise that will resolve when - * howMany of the supplied promisesOrValues have resolved, or will reject when - * it becomes impossible for howMany to resolve, for example, when - * (promisesOrValues.length - howMany) + 1 input promises reject. - * - * @param {Array} promisesOrValues array of anything, may contain a mix - * of promises and values - * @param howMany {number} number of promisesOrValues to resolve - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} promise that will resolve to an array of howMany values that - * resolved first, or will reject with an array of (promisesOrValues.length - howMany) + 1 - * rejection reasons. - */ - function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) { - - checkCallbacks(2, arguments); - - return when(promisesOrValues, function(promisesOrValues) { - - var toResolve, toReject, values, reasons, deferred, fulfillOne, rejectOne, progress, len, i; - - len = promisesOrValues.length >>> 0; + defineProperties(Ellipsoid.prototype, { + /** + * Gets the radii of the ellipsoid. + * @memberof Ellipsoid.prototype + * @type {Cartesian3} + * @readonly + */ + radii : { + get: function() { + return this._radii; + } + }, + /** + * Gets the squared radii of the ellipsoid. + * @memberof Ellipsoid.prototype + * @type {Cartesian3} + * @readonly + */ + radiiSquared : { + get : function() { + return this._radiiSquared; + } + }, + /** + * Gets the radii of the ellipsoid raise to the fourth power. + * @memberof Ellipsoid.prototype + * @type {Cartesian3} + * @readonly + */ + radiiToTheFourth : { + get : function() { + return this._radiiToTheFourth; + } + }, + /** + * Gets one over the radii of the ellipsoid. + * @memberof Ellipsoid.prototype + * @type {Cartesian3} + * @readonly + */ + oneOverRadii : { + get : function() { + return this._oneOverRadii; + } + }, + /** + * Gets one over the squared radii of the ellipsoid. + * @memberof Ellipsoid.prototype + * @type {Cartesian3} + * @readonly + */ + oneOverRadiiSquared : { + get : function() { + return this._oneOverRadiiSquared; + } + }, + /** + * Gets the minimum radius of the ellipsoid. + * @memberof Ellipsoid.prototype + * @type {Number} + * @readonly + */ + minimumRadius : { + get : function() { + return this._minimumRadius; + } + }, + /** + * Gets the maximum radius of the ellipsoid. + * @memberof Ellipsoid.prototype + * @type {Number} + * @readonly + */ + maximumRadius : { + get : function() { + return this._maximumRadius; + } + } + }); - toResolve = Math.max(0, Math.min(howMany, len)); - values = []; + /** + * Duplicates an Ellipsoid instance. + * + * @param {Ellipsoid} ellipsoid The ellipsoid to duplicate. + * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new + * instance should be created. + * @returns {Ellipsoid} The cloned Ellipsoid. (Returns undefined if ellipsoid is undefined) + */ + Ellipsoid.clone = function(ellipsoid, result) { + if (!defined(ellipsoid)) { + return undefined; + } + var radii = ellipsoid._radii; - toReject = (len - toResolve) + 1; - reasons = []; + if (!defined(result)) { + return new Ellipsoid(radii.x, radii.y, radii.z); + } - deferred = defer(); + Cartesian3.clone(radii, result._radii); + Cartesian3.clone(ellipsoid._radiiSquared, result._radiiSquared); + Cartesian3.clone(ellipsoid._radiiToTheFourth, result._radiiToTheFourth); + Cartesian3.clone(ellipsoid._oneOverRadii, result._oneOverRadii); + Cartesian3.clone(ellipsoid._oneOverRadiiSquared, result._oneOverRadiiSquared); + result._minimumRadius = ellipsoid._minimumRadius; + result._maximumRadius = ellipsoid._maximumRadius; + result._centerToleranceSquared = ellipsoid._centerToleranceSquared; - // No items in the input, resolve immediately - if (!toResolve) { - deferred.resolve(values); + return result; + }; - } else { - progress = deferred.progress; + /** + * Computes an Ellipsoid from a Cartesian specifying the radii in x, y, and z directions. + * + * @param {Cartesian3} [cartesian=Cartesian3.ZERO] The ellipsoid's radius in the x, y, and z directions. + * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new + * instance should be created. + * @returns {Ellipsoid} A new Ellipsoid instance. + * + * @exception {DeveloperError} All radii components must be greater than or equal to zero. + * + * @see Ellipsoid.WGS84 + * @see Ellipsoid.UNIT_SPHERE + */ + Ellipsoid.fromCartesian3 = function(cartesian, result) { + if (!defined(result)) { + result = new Ellipsoid(); + } - rejectOne = function(reason) { - reasons.push(reason); - if(!--toReject) { - fulfillOne = rejectOne = noop; - deferred.reject(reasons); - } - }; + if (!defined(cartesian)) { + return result; + } - fulfillOne = function(val) { - // This orders the values based on promise resolution order - // Another strategy would be to use the original position of - // the corresponding promise. - values.push(val); + initialize(result, cartesian.x, cartesian.y, cartesian.z); + return result; + }; - if (!--toResolve) { - fulfillOne = rejectOne = noop; - deferred.resolve(values); - } - }; + /** + * An Ellipsoid instance initialized to the WGS84 standard. + * + * @type {Ellipsoid} + * @constant + */ + Ellipsoid.WGS84 = freezeObject(new Ellipsoid(6378137.0, 6378137.0, 6356752.3142451793)); - for(i = 0; i < len; ++i) { - if(i in promisesOrValues) { - when(promisesOrValues[i], fulfiller, rejecter, progress); - } - } - } + /** + * An Ellipsoid instance initialized to radii of (1.0, 1.0, 1.0). + * + * @type {Ellipsoid} + * @constant + */ + Ellipsoid.UNIT_SPHERE = freezeObject(new Ellipsoid(1.0, 1.0, 1.0)); - return deferred.then(onFulfilled, onRejected, onProgress); + /** + * An Ellipsoid instance initialized to a sphere with the lunar radius. + * + * @type {Ellipsoid} + * @constant + */ + Ellipsoid.MOON = freezeObject(new Ellipsoid(CesiumMath.LUNAR_RADIUS, CesiumMath.LUNAR_RADIUS, CesiumMath.LUNAR_RADIUS)); - function rejecter(reason) { - rejectOne(reason); - } + /** + * Duplicates an Ellipsoid instance. + * + * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new + * instance should be created. + * @returns {Ellipsoid} The cloned Ellipsoid. + */ + Ellipsoid.prototype.clone = function(result) { + return Ellipsoid.clone(this, result); + }; - function fulfiller(val) { - fulfillOne(val); - } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + Ellipsoid.packedLength = Cartesian3.packedLength; - }); - } + /** + * Stores the provided instance into the provided array. + * + * @param {Ellipsoid} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + Ellipsoid.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - /** - * Initiates a competitive race, returning a promise that will resolve when - * any one of the supplied promisesOrValues has resolved or will reject when - * *all* promisesOrValues have rejected. - * - * @param {Array|Promise} promisesOrValues array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} promise that will resolve to the value that resolved first, or - * will reject with an array of all rejected inputs. - */ - function any(promisesOrValues, onFulfilled, onRejected, onProgress) { + Cartesian3.pack(value._radii, array, startingIndex); - function unwrapSingleResult(val) { - return onFulfilled ? onFulfilled(val[0]) : val[0]; - } + return array; + }; - return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress); - } + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Ellipsoid} [result] The object into which to store the result. + * @returns {Ellipsoid} The modified result parameter or a new Ellipsoid instance if one was not provided. + */ + Ellipsoid.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - /** - * Return a promise that will resolve only once all the supplied promisesOrValues - * have resolved. The resolution value of the returned promise will be an array - * containing the resolution values of each of the promisesOrValues. - * @memberOf when - * - * @param {Array|Promise} promisesOrValues array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} - */ - function all(promisesOrValues, onFulfilled, onRejected, onProgress) { - checkCallbacks(1, arguments); - return map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); - } + var radii = Cartesian3.unpack(array, startingIndex); + return Ellipsoid.fromCartesian3(radii, result); + }; - /** - * Joins multiple promises into a single returned promise. - * @returns {Promise} a promise that will fulfill when *all* the input promises - * have fulfilled, or will reject when *any one* of the input promises rejects. - */ - function join(/* ...promises */) { - return map(arguments, identity); - } + /** + * Computes the unit vector directed from the center of this ellipsoid toward the provided Cartesian position. + * @function + * + * @param {Cartesian3} cartesian The Cartesian for which to to determine the geocentric normal. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. + */ + Ellipsoid.prototype.geocentricSurfaceNormal = Cartesian3.normalize; - /** - * Traditional map function, similar to `Array.prototype.map()`, but allows - * input to contain {@link Promise}s and/or values, and mapFunc may return - * either a value or a {@link Promise} - * - * @param {Array|Promise} promise array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function} mapFunc mapping function mapFunc(value) which may return - * either a {@link Promise} or value - * @returns {Promise} a {@link Promise} that will resolve to an array containing - * the mapped output values. - */ - function map(promise, mapFunc) { - return when(promise, function(array) { - var results, len, toResolve, resolve, i, d; + /** + * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position. + * + * @param {Cartographic} cartographic The cartographic position for which to to determine the geodetic normal. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. + */ + Ellipsoid.prototype.geodeticSurfaceNormalCartographic = function(cartographic, result) { + Check.typeOf.object('cartographic', cartographic); + + var longitude = cartographic.longitude; + var latitude = cartographic.latitude; + var cosLatitude = Math.cos(latitude); - // Since we know the resulting length, we can preallocate the results - // array to avoid array expansions. - toResolve = len = array.length >>> 0; - results = []; - d = defer(); + var x = cosLatitude * Math.cos(longitude); + var y = cosLatitude * Math.sin(longitude); + var z = Math.sin(latitude); - if(!toResolve) { - d.resolve(results); - } else { + if (!defined(result)) { + result = new Cartesian3(); + } + result.x = x; + result.y = y; + result.z = z; + return Cartesian3.normalize(result, result); + }; - resolve = function resolveOne(item, i) { - when(item, mapFunc).then(function(mapped) { - results[i] = mapped; + /** + * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position. + * + * @param {Cartesian3} cartesian The Cartesian position for which to to determine the surface normal. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. + */ + Ellipsoid.prototype.geodeticSurfaceNormal = function(cartesian, result) { + if (!defined(result)) { + result = new Cartesian3(); + } + result = Cartesian3.multiplyComponents(cartesian, this._oneOverRadiiSquared, result); + return Cartesian3.normalize(result, result); + }; - if(!--toResolve) { - d.resolve(results); - } - }, d.reject); - }; + var cartographicToCartesianNormal = new Cartesian3(); + var cartographicToCartesianK = new Cartesian3(); - // Since mapFunc may be async, get all invocations of it into flight - for(i = 0; i < len; i++) { - if(i in array) { - resolve(array[i], i); - } else { - --toResolve; - } - } + /** + * Converts the provided cartographic to Cartesian representation. + * + * @param {Cartographic} cartographic The cartographic position. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. + * + * @example + * //Create a Cartographic and determine it's Cartesian representation on a WGS84 ellipsoid. + * var position = new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 5000); + * var cartesianPosition = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position); + */ + Ellipsoid.prototype.cartographicToCartesian = function(cartographic, result) { + //`cartographic is required` is thrown from geodeticSurfaceNormalCartographic. + var n = cartographicToCartesianNormal; + var k = cartographicToCartesianK; + this.geodeticSurfaceNormalCartographic(cartographic, n); + Cartesian3.multiplyComponents(this._radiiSquared, n, k); + var gamma = Math.sqrt(Cartesian3.dot(n, k)); + Cartesian3.divideByScalar(k, gamma, k); + Cartesian3.multiplyByScalar(n, cartographic.height, n); - } + if (!defined(result)) { + result = new Cartesian3(); + } + return Cartesian3.add(k, n, result); + }; - return d.promise; + /** + * Converts the provided array of cartographics to an array of Cartesians. + * + * @param {Cartographic[]} cartographics An array of cartographic positions. + * @param {Cartesian3[]} [result] The object onto which to store the result. + * @returns {Cartesian3[]} The modified result parameter or a new Array instance if none was provided. + * + * @example + * //Convert an array of Cartographics and determine their Cartesian representation on a WGS84 ellipsoid. + * var positions = [new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 0), + * new Cesium.Cartographic(Cesium.Math.toRadians(21.321), Cesium.Math.toRadians(78.123), 100), + * new Cesium.Cartographic(Cesium.Math.toRadians(21.645), Cesium.Math.toRadians(78.456), 250)]; + * var cartesianPositions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(positions); + */ + Ellipsoid.prototype.cartographicArrayToCartesianArray = function(cartographics, result) { + Check.defined('cartographics', cartographics); + + var length = cartographics.length; + if (!defined(result)) { + result = new Array(length); + } else { + result.length = length; + } + for ( var i = 0; i < length; i++) { + result[i] = this.cartographicToCartesian(cartographics[i], result[i]); + } + return result; + }; - }); - } + var cartesianToCartographicN = new Cartesian3(); + var cartesianToCartographicP = new Cartesian3(); + var cartesianToCartographicH = new Cartesian3(); - /** - * Traditional reduce function, similar to `Array.prototype.reduce()`, but - * input may contain promises and/or values, and reduceFunc - * may return either a value or a promise, *and* initialValue may - * be a promise for the starting value. - * - * @param {Array|Promise} promise array or promise for an array of anything, - * may contain a mix of promises and values. - * @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total), - * where total is the total number of items being reduced, and will be the same - * in each call to reduceFunc. - * @returns {Promise} that will resolve to the final reduced value - */ - function reduce(promise, reduceFunc /*, initialValue */) { - var args = slice.call(arguments, 1); + /** + * Converts the provided cartesian to cartographic representation. + * The cartesian is undefined at the center of the ellipsoid. + * + * @param {Cartesian3} cartesian The Cartesian position to convert to cartographic representation. + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter, new Cartographic instance if none was provided, or undefined if the cartesian is at the center of the ellipsoid. + * + * @example + * //Create a Cartesian and determine it's Cartographic representation on a WGS84 ellipsoid. + * var position = new Cesium.Cartesian3(17832.12, 83234.52, 952313.73); + * var cartographicPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); + */ + Ellipsoid.prototype.cartesianToCartographic = function(cartesian, result) { + //`cartesian is required.` is thrown from scaleToGeodeticSurface + var p = this.scaleToGeodeticSurface(cartesian, cartesianToCartographicP); - return when(promise, function(array) { - var total; + if (!defined(p)) { + return undefined; + } - total = array.length; + var n = this.geodeticSurfaceNormal(p, cartesianToCartographicN); + var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH); - // Wrap the supplied reduceFunc with one that handles promises and then - // delegates to the supplied. - args[0] = function (current, val, i) { - return when(current, function (c) { - return when(val, function (value) { - return reduceFunc(c, value, i, total); - }); - }); - }; + var longitude = Math.atan2(n.y, n.x); + var latitude = Math.asin(n.z); + var height = CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h); - return reduceArray.apply(array, args); - }); - } + if (!defined(result)) { + return new Cartographic(longitude, latitude, height); + } + result.longitude = longitude; + result.latitude = latitude; + result.height = height; + return result; + }; - /** - * Ensure that resolution of promiseOrValue will trigger resolver with the - * value or reason of promiseOrValue, or instead with resolveValue if it is provided. - * - * @param promiseOrValue - * @param {Object} resolver - * @param {function} resolver.resolve - * @param {function} resolver.reject - * @param {*} [resolveValue] - * @returns {Promise} - */ - function chain(promiseOrValue, resolver, resolveValue) { - var useResolveValue = arguments.length > 2; + /** + * Converts the provided array of cartesians to an array of cartographics. + * + * @param {Cartesian3[]} cartesians An array of Cartesian positions. + * @param {Cartographic[]} [result] The object onto which to store the result. + * @returns {Cartographic[]} The modified result parameter or a new Array instance if none was provided. + * + * @example + * //Create an array of Cartesians and determine their Cartographic representation on a WGS84 ellipsoid. + * var positions = [new Cesium.Cartesian3(17832.12, 83234.52, 952313.73), + * new Cesium.Cartesian3(17832.13, 83234.53, 952313.73), + * new Cesium.Cartesian3(17832.14, 83234.54, 952313.73)] + * var cartographicPositions = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray(positions); + */ + Ellipsoid.prototype.cartesianArrayToCartographicArray = function(cartesians, result) { + Check.defined('cartesians', cartesians); + + var length = cartesians.length; + if (!defined(result)) { + result = new Array(length); + } else { + result.length = length; + } + for ( var i = 0; i < length; ++i) { + result[i] = this.cartesianToCartographic(cartesians[i], result[i]); + } + return result; + }; - return when(promiseOrValue, - function(val) { - val = useResolveValue ? resolveValue : val; - resolver.resolve(val); - return val; - }, - function(reason) { - resolver.reject(reason); - return rejected(reason); - }, - resolver.progress - ); - } + /** + * Scales the provided Cartesian position along the geodetic surface normal + * so that it is on the surface of this ellipsoid. If the position is + * at the center of the ellipsoid, this function returns undefined. + * + * @param {Cartesian3} cartesian The Cartesian position to scale. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center. + */ + Ellipsoid.prototype.scaleToGeodeticSurface = function(cartesian, result) { + return scaleToGeodeticSurface(cartesian, this._oneOverRadii, this._oneOverRadiiSquared, this._centerToleranceSquared, result); + }; - // - // Utility functions - // + /** + * Scales the provided Cartesian position along the geocentric surface normal + * so that it is on the surface of this ellipsoid. + * + * @param {Cartesian3} cartesian The Cartesian position to scale. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. + */ + Ellipsoid.prototype.scaleToGeocentricSurface = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + + if (!defined(result)) { + result = new Cartesian3(); + } - /** - * Apply all functions in queue to value - * @param {Array} queue array of functions to execute - * @param {*} value argument passed to each function - */ - function processQueue(queue, value) { - var handler, i = 0; + var positionX = cartesian.x; + var positionY = cartesian.y; + var positionZ = cartesian.z; + var oneOverRadiiSquared = this._oneOverRadiiSquared; - while (handler = queue[i++]) { - handler(value); - } - } + var beta = 1.0 / Math.sqrt((positionX * positionX) * oneOverRadiiSquared.x + + (positionY * positionY) * oneOverRadiiSquared.y + + (positionZ * positionZ) * oneOverRadiiSquared.z); - /** - * Helper that checks arrayOfCallbacks to ensure that each element is either - * a function, or null or undefined. - * @private - * @param {number} start index at which to start checking items in arrayOfCallbacks - * @param {Array} arrayOfCallbacks array to check - * @throws {Error} if any element of arrayOfCallbacks is something other than - * a functions, null, or undefined. - */ - function checkCallbacks(start, arrayOfCallbacks) { - // TODO: Promises/A+ update type checking and docs - var arg, i = arrayOfCallbacks.length; + return Cartesian3.multiplyByScalar(cartesian, beta, result); + }; - while(i > start) { - arg = arrayOfCallbacks[--i]; + /** + * Transforms a Cartesian X, Y, Z position to the ellipsoid-scaled space by multiplying + * its components by the result of {@link Ellipsoid#oneOverRadii}. + * + * @param {Cartesian3} position The position to transform. + * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and + * return a new instance. + * @returns {Cartesian3} The position expressed in the scaled space. The returned instance is the + * one passed as the result parameter if it is not undefined, or a new instance of it is. + */ + Ellipsoid.prototype.transformPositionToScaledSpace = function(position, result) { + if (!defined(result)) { + result = new Cartesian3(); + } - if (arg != null && typeof arg != 'function') { - throw new Error('arg '+i+' must be a function'); - } - } - } + return Cartesian3.multiplyComponents(position, this._oneOverRadii, result); + }; - /** - * No-Op function used in method replacement - * @private - */ - function noop() {} + /** + * Transforms a Cartesian X, Y, Z position from the ellipsoid-scaled space by multiplying + * its components by the result of {@link Ellipsoid#radii}. + * + * @param {Cartesian3} position The position to transform. + * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and + * return a new instance. + * @returns {Cartesian3} The position expressed in the unscaled space. The returned instance is the + * one passed as the result parameter if it is not undefined, or a new instance of it is. + */ + Ellipsoid.prototype.transformPositionFromScaledSpace = function(position, result) { + if (!defined(result)) { + result = new Cartesian3(); + } - slice = [].slice; + return Cartesian3.multiplyComponents(position, this._radii, result); + }; - // ES5 reduce implementation if native not available - // See: http://es5.github.com/#x15.4.4.21 as there are many - // specifics and edge cases. - reduceArray = [].reduce || - function(reduceFunc /*, initialValue */) { - /*jshint maxcomplexity: 7*/ + /** + * Compares this Ellipsoid against the provided Ellipsoid componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Ellipsoid} [right] The other Ellipsoid. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + Ellipsoid.prototype.equals = function(right) { + return (this === right) || + (defined(right) && + Cartesian3.equals(this._radii, right._radii)); + }; - // ES5 dictates that reduce.length === 1 + /** + * Creates a string representing this Ellipsoid in the format '(radii.x, radii.y, radii.z)'. + * + * @returns {String} A string representing this ellipsoid in the format '(radii.x, radii.y, radii.z)'. + */ + Ellipsoid.prototype.toString = function() { + return this._radii.toString(); + }; - // This implementation deviates from ES5 spec in the following ways: - // 1. It does not check if reduceFunc is a Callable + /** + * Computes a point which is the intersection of the surface normal with the z-axis. + * + * @param {Cartesian3} position the position. must be on the surface of the ellipsoid. + * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. + * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center. + * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis). + * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / AxisOfRotation is bigger than the square root of 2 + * @param {Cartesian3} [result] The cartesian to which to copy the result, or undefined to create and + * return a new instance. + * @returns {Cartesian3 | undefined} the intersection point if it's inside the ellipsoid, undefined otherwise + * + * @exception {DeveloperError} position is required. + * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). + * @exception {DeveloperError} Ellipsoid.radii.z must be greater than 0. + */ + Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) { + Check.typeOf.object('position', position); - var arr, args, reduced, len, i; + if (!CesiumMath.equalsEpsilon(this._radii.x, this._radii.y, CesiumMath.EPSILON15)) { + throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); + } - i = 0; - // This generates a jshint warning, despite being valid - // "Missing 'new' prefix when invoking a constructor." - // See https://github.com/jshint/jshint/issues/392 - arr = Object(this); - len = arr.length >>> 0; - args = arguments; + Check.typeOf.number.greaterThan('Ellipsoid.radii.z', this._radii.z, 0); + + buffer = defaultValue(buffer, 0.0); - // If no initialValue, use first item of array (we know length !== 0 here) - // and adjust i to start at second item - if(args.length <= 1) { - // Skip to the first real element in the array - for(;;) { - if(i in arr) { - reduced = arr[i++]; - break; - } + var squaredXOverSquaredZ = this._squaredXOverSquaredZ; - // If we reached the end of the array without finding any real - // elements, it's a TypeError - if(++i >= len) { - throw new TypeError(); - } - } - } else { - // If initialValue provided, use it - reduced = args[1]; - } + if (!defined(result)) { + result = new Cartesian3(); + } - // Do the actual reduce - for(;i < len; ++i) { - // Skip holes - if(i in arr) { - reduced = reduceFunc(reduced, arr[i], i, arr); - } - } + result.x = 0.0; + result.y = 0.0; + result.z = position.z * (1 - squaredXOverSquaredZ); - return reduced; - }; + if (Math.abs(result.z) >= this._radii.z - buffer) { + return undefined; + } - function identity(x) { - return x; - } + return result; + }; - return when; + return Ellipsoid; }); -})(typeof define == 'function' && define.amd - ? define - : function (factory) { typeof exports === 'object' - ? (module.exports = factory()) - : (this.when = factory()); - } - // Boilerplate for AMD, Node, and browser global -); -define('Core/combine',[ +define('Core/Rectangle',[ + './Cartographic', + './Check', './defaultValue', - './defined' + './defined', + './defineProperties', + './Ellipsoid', + './freezeObject', + './Math' ], function( + Cartographic, + Check, defaultValue, - defined) { + defined, + defineProperties, + Ellipsoid, + freezeObject, + CesiumMath) { 'use strict'; /** - * Merges two objects, copying their properties onto a new combined object. When two objects have the same - * property, the value of the property on the first object is used. If either object is undefined, - * it will be treated as an empty object. - * - * @example - * var object1 = { - * propOne : 1, - * propTwo : { - * value1 : 10 - * } - * } - * var object2 = { - * propTwo : 2 - * } - * var final = Cesium.combine(object1, object2); + * A two dimensional region specified as longitude and latitude coordinates. * - * // final === { - * // propOne : 1, - * // propTwo : { - * // value1 : 10 - * // } - * // } + * @alias Rectangle + * @constructor * - * @param {Object} [object1] The first object to merge. - * @param {Object} [object2] The second object to merge. - * @param {Boolean} [deep=false] Perform a recursive merge. - * @returns {Object} The combined object containing all properties from both objects. + * @param {Number} [west=0.0] The westernmost longitude, in radians, in the range [-Pi, Pi]. + * @param {Number} [south=0.0] The southernmost latitude, in radians, in the range [-Pi/2, Pi/2]. + * @param {Number} [east=0.0] The easternmost longitude, in radians, in the range [-Pi, Pi]. + * @param {Number} [north=0.0] The northernmost latitude, in radians, in the range [-Pi/2, Pi/2]. * - * @exports combine + * @see Packable */ - function combine(object1, object2, deep) { - deep = defaultValue(deep, false); + function Rectangle(west, south, east, north) { + /** + * The westernmost longitude in radians in the range [-Pi, Pi]. + * + * @type {Number} + * @default 0.0 + */ + this.west = defaultValue(west, 0.0); - var result = {}; + /** + * The southernmost latitude in radians in the range [-Pi/2, Pi/2]. + * + * @type {Number} + * @default 0.0 + */ + this.south = defaultValue(south, 0.0); - var object1Defined = defined(object1); - var object2Defined = defined(object2); - var property; - var object1Value; - var object2Value; - if (object1Defined) { - for (property in object1) { - if (object1.hasOwnProperty(property)) { - object1Value = object1[property]; - if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { - object2Value = object2[property]; - if (typeof object2Value === 'object') { - result[property] = combine(object1Value, object2Value, deep); - } else { - result[property] = object1Value; - } - } else { - result[property] = object1Value; - } - } + /** + * The easternmost longitude in radians in the range [-Pi, Pi]. + * + * @type {Number} + * @default 0.0 + */ + this.east = defaultValue(east, 0.0); + + /** + * The northernmost latitude in radians in the range [-Pi/2, Pi/2]. + * + * @type {Number} + * @default 0.0 + */ + this.north = defaultValue(north, 0.0); + } + + defineProperties(Rectangle.prototype, { + /** + * Gets the width of the rectangle in radians. + * @memberof Rectangle.prototype + * @type {Number} + */ + width : { + get : function() { + return Rectangle.computeWidth(this); } - } - if (object2Defined) { - for (property in object2) { - if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { - object2Value = object2[property]; - result[property] = object2Value; - } + }, + + /** + * Gets the height of the rectangle in radians. + * @memberof Rectangle.prototype + * @type {Number} + */ + height : { + get : function() { + return Rectangle.computeHeight(this); } } - return result; - } - - return combine; -}); + }); -define('Core/isArray',[ - './defined' - ], function( - defined) { - 'use strict'; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + Rectangle.packedLength = 4; /** - * Tests an object to see if it is an array. - * @exports isArray + * Stores the provided instance into the provided array. * - * @param {Object} value The value to test. - * @returns {Boolean} true if the value is an array, false otherwise. + * @param {Rectangle} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - var isArray = Array.isArray; - if (!defined(isArray)) { - isArray = function(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }; - } + Rectangle.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - return isArray; -}); + array[startingIndex++] = value.west; + array[startingIndex++] = value.south; + array[startingIndex++] = value.east; + array[startingIndex] = value.north; -define('Core/objectToQuery',[ - './defined', - './DeveloperError', - './isArray' - ], function( - defined, - DeveloperError, - isArray) { - 'use strict'; + return array; + }; /** - * Converts an object representing a set of name/value pairs into a query string, - * with names and values encoded properly for use in a URL. Values that are arrays - * will produce multiple values with the same name. - * @exports objectToQuery - * - * @param {Object} obj The object containing data to encode. - * @returns {String} An encoded query string. - * - * - * @example - * var str = Cesium.objectToQuery({ - * key1 : 'some value', - * key2 : 'a/b', - * key3 : ['x', 'y'] - * }); + * Retrieves an instance from a packed array. * - * @see queryToObject - * // str will be: - * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Rectangle} [result] The object into which to store the result. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if one was not provided. */ - function objectToQuery(obj) { - if (!defined(obj)) { - throw new DeveloperError('obj is required.'); - } + Rectangle.unpack = function(array, startingIndex, result) { + Check.defined('array', array); - var result = ''; - for ( var propName in obj) { - if (obj.hasOwnProperty(propName)) { - var value = obj[propName]; + startingIndex = defaultValue(startingIndex, 0); - var part = encodeURIComponent(propName) + '='; - if (isArray(value)) { - for (var i = 0, len = value.length; i < len; ++i) { - result += part + encodeURIComponent(value[i]) + '&'; - } - } else { - result += part + encodeURIComponent(value) + '&'; - } - } + if (!defined(result)) { + result = new Rectangle(); } - // trim last & - result = result.slice(0, -1); - - // This function used to replace %20 with + which is more compact and readable. - // However, some servers didn't properly handle + as a space. - // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 - + result.west = array[startingIndex++]; + result.south = array[startingIndex++]; + result.east = array[startingIndex++]; + result.north = array[startingIndex]; return result; - } + }; - return objectToQuery; -}); + /** + * Computes the width of a rectangle in radians. + * @param {Rectangle} rectangle The rectangle to compute the width of. + * @returns {Number} The width. + */ + Rectangle.computeWidth = function(rectangle) { + Check.typeOf.object('rectangle', rectangle); + var east = rectangle.east; + var west = rectangle.west; + if (east < west) { + east += CesiumMath.TWO_PI; + } + return east - west; + }; -define('Core/queryToObject',[ - './defined', - './DeveloperError', - './isArray' - ], function( - defined, - DeveloperError, - isArray) { - 'use strict'; + /** + * Computes the height of a rectangle in radians. + * @param {Rectangle} rectangle The rectangle to compute the height of. + * @returns {Number} The height. + */ + Rectangle.computeHeight = function(rectangle) { + Check.typeOf.object('rectangle', rectangle); + return rectangle.north - rectangle.south; + }; /** - * Parses a query string into an object, where the keys and values of the object are the - * name/value pairs from the query string, decoded. If a name appears multiple times, - * the value in the object will be an array of values. - * @exports queryToObject - * - * @param {String} queryString The query string. - * @returns {Object} An object containing the parameters parsed from the query string. + * Creates a rectangle given the boundary longitude and latitude in degrees. * + * @param {Number} [west=0.0] The westernmost longitude in degrees in the range [-180.0, 180.0]. + * @param {Number} [south=0.0] The southernmost latitude in degrees in the range [-90.0, 90.0]. + * @param {Number} [east=0.0] The easternmost longitude in degrees in the range [-180.0, 180.0]. + * @param {Number} [north=0.0] The northernmost latitude in degrees in the range [-90.0, 90.0]. + * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. * * @example - * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); - * // obj will be: - * // { - * // key1 : 'some value', - * // key2 : 'a/b', - * // key3 : ['x', 'y'] - * // } - * - * @see objectToQuery + * var rectangle = Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0); */ - function queryToObject(queryString) { - if (!defined(queryString)) { - throw new DeveloperError('queryString is required.'); - } - - var result = {}; - if (queryString === '') { - return result; - } - var parts = queryString.replace(/\+/g, '%20').split('&'); - for (var i = 0, len = parts.length; i < len; ++i) { - var subparts = parts[i].split('='); - - var name = decodeURIComponent(subparts[0]); - var value = subparts[1]; - if (defined(value)) { - value = decodeURIComponent(value); - } else { - value = ''; - } + Rectangle.fromDegrees = function(west, south, east, north, result) { + west = CesiumMath.toRadians(defaultValue(west, 0.0)); + south = CesiumMath.toRadians(defaultValue(south, 0.0)); + east = CesiumMath.toRadians(defaultValue(east, 0.0)); + north = CesiumMath.toRadians(defaultValue(north, 0.0)); - var resultValue = result[name]; - if (typeof resultValue === 'string') { - // expand the single value to an array - result[name] = [resultValue, value]; - } else if (isArray(resultValue)) { - resultValue.push(value); - } else { - result[name] = value; - } + if (!defined(result)) { + return new Rectangle(west, south, east, north); } - return result; - } - return queryToObject; -}); + result.west = west; + result.south = south; + result.east = east; + result.north = north; -define('Core/RequestState',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + return result; + }; /** - * State of the request. + * Creates a rectangle given the boundary longitude and latitude in radians. * - * @exports RequestState + * @param {Number} [west=0.0] The westernmost longitude in radians in the range [-Math.PI, Math.PI]. + * @param {Number} [south=0.0] The southernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. + * @param {Number} [east=0.0] The easternmost longitude in radians in the range [-Math.PI, Math.PI]. + * @param {Number} [north=0.0] The northernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. + * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. + * + * @example + * var rectangle = Cesium.Rectangle.fromRadians(0.0, Math.PI/4, Math.PI/8, 3*Math.PI/4); */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, + Rectangle.fromRadians = function(west, south, east, north, result) { + if (!defined(result)) { + return new Rectangle(west, south, east, north); + } - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + result.west = defaultValue(west, 0.0); + result.south = defaultValue(south, 0.0); + result.east = defaultValue(east, 0.0); + result.north = defaultValue(north, 0.0); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 + return result; }; - return freezeObject(RequestState); -}); - -define('Core/RequestType',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; - /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Creates the smallest possible Rectangle that encloses all positions in the provided array. * - * @exports RequestType + * @param {Cartographic[]} cartographics The list of Cartographic instances. + * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, + Rectangle.fromCartographicArray = function(cartographics, result) { + Check.defined('cartographics', cartographics); + + var west = Number.MAX_VALUE; + var east = -Number.MAX_VALUE; + var westOverIDL = Number.MAX_VALUE; + var eastOverIDL = -Number.MAX_VALUE; + var south = Number.MAX_VALUE; + var north = -Number.MAX_VALUE; - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, + for ( var i = 0, len = cartographics.length; i < len; i++) { + var position = cartographics[i]; + west = Math.min(west, position.longitude); + east = Math.max(east, position.longitude); + south = Math.min(south, position.latitude); + north = Math.max(north, position.latitude); - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + var lonAdjusted = position.longitude >= 0 ? position.longitude : position.longitude + CesiumMath.TWO_PI; + westOverIDL = Math.min(westOverIDL, lonAdjusted); + eastOverIDL = Math.max(eastOverIDL, lonAdjusted); + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + if(east - west > eastOverIDL - westOverIDL) { + west = westOverIDL; + east = eastOverIDL; - return freezeObject(RequestType); -}); + if (east > CesiumMath.PI) { + east = east - CesiumMath.TWO_PI; + } + if (west > CesiumMath.PI) { + west = west - CesiumMath.TWO_PI; + } + } -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' - ], function( - defaultValue, - RequestState, - RequestType) { - 'use strict'; + if (!defined(result)) { + return new Rectangle(west, south, east, north); + } + + result.west = west; + result.south = south; + result.east = east; + result.north = north; + return result; + }; /** - * Stores information for making a request. In general this does not need to be constructed directly. - * - * @alias Request - * @constructor + * Creates the smallest possible Rectangle that encloses all positions in the provided array. * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {Cartesian3[]} cartesians The list of Cartesian instances. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid the cartesians are on. + * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); - - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; - - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; + Rectangle.fromCartesianArray = function(cartesians, ellipsoid, result) { + Check.defined('cartesians', cartesians); + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; + var west = Number.MAX_VALUE; + var east = -Number.MAX_VALUE; + var westOverIDL = Number.MAX_VALUE; + var eastOverIDL = -Number.MAX_VALUE; + var south = Number.MAX_VALUE; + var north = -Number.MAX_VALUE; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; + for ( var i = 0, len = cartesians.length; i < len; i++) { + var position = ellipsoid.cartesianToCartographic(cartesians[i]); + west = Math.min(west, position.longitude); + east = Math.max(east, position.longitude); + south = Math.min(south, position.latitude); + north = Math.max(north, position.latitude); - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + var lonAdjusted = position.longitude >= 0 ? position.longitude : position.longitude + CesiumMath.TWO_PI; + westOverIDL = Math.min(westOverIDL, lonAdjusted); + eastOverIDL = Math.max(eastOverIDL, lonAdjusted); + } - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + if(east - west > eastOverIDL - westOverIDL) { + west = westOverIDL; + east = eastOverIDL; - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + if (east > CesiumMath.PI) { + east = east - CesiumMath.TWO_PI; + } + if (west > CesiumMath.PI) { + west = west - CesiumMath.TWO_PI; + } + } - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + if (!defined(result)) { + return new Rectangle(west, south, east, north); + } - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + result.west = west; + result.south = south; + result.east = east; + result.north = north; + return result; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Duplicates a Rectangle. + * + * @param {Rectangle} rectangle The rectangle to clone. + * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. (Returns undefined if rectangle is undefined) + */ + Rectangle.clone = function(rectangle, result) { + if (!defined(rectangle)) { + return undefined; + } - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + if (!defined(result)) { + return new Rectangle(rectangle.west, rectangle.south, rectangle.east, rectangle.north); + } - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + result.west = rectangle.west; + result.south = rectangle.south; + result.east = rectangle.east; + result.north = rectangle.north; + return result; + }; /** - * Mark the request as cancelled. + * Duplicates this Rectangle. * - * @private + * @param {Rectangle} [result] The object onto which to store the result. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. */ - Request.prototype.cancel = function() { - this.cancelled = true; + Rectangle.prototype.clone = function(result) { + return Rectangle.clone(this, result); }; /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. + * Compares the provided Rectangle with this Rectangle componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Rectangle} [other] The Rectangle to compare. + * @returns {Boolean} <code>true</code> if the Rectangles are equal, <code>false</code> otherwise. */ + Rectangle.prototype.equals = function(other) { + return Rectangle.equals(this, other); + }; /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback + * Compares the provided rectangles and returns <code>true</code> if they are equal, + * <code>false</code> otherwise. + * + * @param {Rectangle} [left] The first Rectangle. + * @param {Rectangle} [right] The second Rectangle. + * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. */ + Rectangle.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + (left.west === right.west) && + (left.south === right.south) && + (left.east === right.east) && + (left.north === right.north)); + }; /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. + * Compares the provided Rectangle with this Rectangle componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Rectangle} [other] The Rectangle to compare. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if the Rectangles are within the provided epsilon, <code>false</code> otherwise. */ - - return Request; -}); - -define('Core/Heap',[ - './Check', - './defaultValue', - './defined', - './defineProperties' - ], function( - Check, - defaultValue, - defined, - defineProperties) { - 'use strict'; + Rectangle.prototype.equalsEpsilon = function(other, epsilon) { + Check.typeOf.number('epsilon', epsilon); + + return defined(other) && + (Math.abs(this.west - other.west) <= epsilon) && + (Math.abs(this.south - other.south) <= epsilon) && + (Math.abs(this.east - other.east) <= epsilon) && + (Math.abs(this.north - other.north) <= epsilon); + }; /** - * Array implementation of a heap. + * Checks a Rectangle's properties and throws if they are not in valid ranges. * - * @alias Heap - * @constructor - * @private + * @param {Rectangle} rectangle The rectangle to validate * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @exception {DeveloperError} <code>north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. + * @exception {DeveloperError} <code>south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. + * @exception {DeveloperError} <code>east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. + * @exception {DeveloperError} <code>west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; - } - - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + Rectangle.validate = function(rectangle) { + Check.typeOf.object('rectangle', rectangle); - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, + var north = rectangle.north; + Check.typeOf.number.greaterThanOrEquals('north', north, -CesiumMath.PI_OVER_TWO); + Check.typeOf.number.lessThanOrEquals('north', north, CesiumMath.PI_OVER_TWO); - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, + var south = rectangle.south; + Check.typeOf.number.greaterThanOrEquals('south', south, -CesiumMath.PI_OVER_TWO); + Check.typeOf.number.lessThanOrEquals('south', south, CesiumMath.PI_OVER_TWO); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } - } - }); + var west = rectangle.west; + Check.typeOf.number.greaterThanOrEquals('west', west, -Math.PI); + Check.typeOf.number.lessThanOrEquals('west', west, Math.PI); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } + var east = rectangle.east; + Check.typeOf.number.greaterThanOrEquals('east', east, -Math.PI); + Check.typeOf.number.lessThanOrEquals('east', east, Math.PI); + }; /** - * Resizes the internal array of the heap. + * Computes the southwest corner of a rectangle. * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * @param {Rectangle} rectangle The rectangle for which to find the corner + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + Rectangle.southwest = function(rectangle, result) { + Check.typeOf.object('rectangle', rectangle); + + if (!defined(result)) { + return new Cartographic(rectangle.west, rectangle.south); + } + result.longitude = rectangle.west; + result.latitude = rectangle.south; + result.height = 0.0; + return result; }; /** - * Update the heap so that index and all descendants satisfy the heap property. + * Computes the northwest corner of a rectangle. * - * @param {Number} [index=0] The starting index to heapify from. + * @param {Rectangle} rectangle The rectangle for which to find the corner + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; - - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; - - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } + Rectangle.northwest = function(rectangle, result) { + Check.typeOf.object('rectangle', rectangle); + + if (!defined(result)) { + return new Cartographic(rectangle.west, rectangle.north); + } + result.longitude = rectangle.west; + result.latitude = rectangle.north; + result.height = 0.0; + return result; + }; - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; - } + /** + * Computes the northeast corner of a rectangle. + * + * @param {Rectangle} rectangle The rectangle for which to find the corner + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. + */ + Rectangle.northeast = function(rectangle, result) { + Check.typeOf.object('rectangle', rectangle); + + if (!defined(result)) { + return new Cartographic(rectangle.east, rectangle.north); } + result.longitude = rectangle.east; + result.latitude = rectangle.north; + result.height = 0.0; + return result; }; /** - * Resort the heap. + * Computes the southeast corner of a rectangle. + * + * @param {Rectangle} rectangle The rectangle for which to find the corner + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + Rectangle.southeast = function(rectangle, result) { + Check.typeOf.object('rectangle', rectangle); + + if (!defined(result)) { + return new Cartographic(rectangle.east, rectangle.south); } + result.longitude = rectangle.east; + result.latitude = rectangle.south; + result.height = 0.0; + return result; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Computes the center of a rectangle. * - * @param {*} element The element to insert + * @param {Rectangle} rectangle The rectangle for which to find the center + * @param {Cartographic} [result] The object onto which to store the result. + * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. + */ + Rectangle.center = function(rectangle, result) { + Check.typeOf.object('rectangle', rectangle); + + var east = rectangle.east; + var west = rectangle.west; + + if (east < west) { + east += CesiumMath.TWO_PI; + } + + var longitude = CesiumMath.negativePiToPi((west + east) * 0.5); + var latitude = (rectangle.south + rectangle.north) * 0.5; + + if (!defined(result)) { + return new Cartographic(longitude, latitude); + } + + result.longitude = longitude; + result.latitude = latitude; + result.height = 0.0; + return result; + }; + + /** + * Computes the intersection of two rectangles. This function assumes that the rectangle's coordinates are + * latitude and longitude in radians and produces a correct intersection, taking into account the fact that + * the same angle can be represented with multiple values as well as the wrapping of longitude at the + * anti-meridian. For a simple intersection that ignores these factors and can be used with projected + * coordinates, see {@link Rectangle.simpleIntersection}. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @param {Rectangle} rectangle On rectangle to find an intersection + * @param {Rectangle} otherRectangle Another rectangle to find an intersection + * @param {Rectangle} [result] The object onto which to store the result. + * @returns {Rectangle|undefined} The modified result parameter, a new Rectangle instance if none was provided or undefined if there is no intersection. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + Rectangle.intersection = function(rectangle, otherRectangle, result) { + Check.typeOf.object('rectangle', rectangle); + Check.typeOf.object('otherRectangle', otherRectangle); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + var rectangleEast = rectangle.east; + var rectangleWest = rectangle.west; - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + var otherRectangleEast = otherRectangle.east; + var otherRectangleWest = otherRectangle.west; + + if (rectangleEast < rectangleWest && otherRectangleEast > 0.0) { + rectangleEast += CesiumMath.TWO_PI; + } else if (otherRectangleEast < otherRectangleWest && rectangleEast > 0.0) { + otherRectangleEast += CesiumMath.TWO_PI; } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + if (rectangleEast < rectangleWest && otherRectangleWest < 0.0) { + otherRectangleWest += CesiumMath.TWO_PI; + } else if (otherRectangleEast < otherRectangleWest && rectangleWest < 0.0) { + rectangleWest += CesiumMath.TWO_PI; } - var removedElement; + var west = CesiumMath.negativePiToPi(Math.max(rectangleWest, otherRectangleWest)); + var east = CesiumMath.negativePiToPi(Math.min(rectangleEast, otherRectangleEast)); - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + if ((rectangle.west < rectangle.east || otherRectangle.west < otherRectangle.east) && east <= west) { + return undefined; } - return removedElement; + var south = Math.max(rectangle.south, otherRectangle.south); + var north = Math.min(rectangle.north, otherRectangle.north); + + if (south >= north) { + return undefined; + } + + if (!defined(result)) { + return new Rectangle(west, south, east, north); + } + result.west = west; + result.south = south; + result.east = east; + result.north = north; + return result; }; /** - * Remove the element specified by index from the heap and return it. + * Computes a simple intersection of two rectangles. Unlike {@link Rectangle.intersection}, this function + * does not attempt to put the angular coordinates into a consistent range or to account for crossing the + * anti-meridian. As such, it can be used for rectangles where the coordinates are not simply latitude + * and longitude (i.e. projected coordinates). * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @param {Rectangle} rectangle On rectangle to find an intersection + * @param {Rectangle} otherRectangle Another rectangle to find an intersection + * @param {Rectangle} [result] The object onto which to store the result. + * @returns {Rectangle|undefined} The modified result parameter, a new Rectangle instance if none was provided or undefined if there is no intersection. */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { + Rectangle.simpleIntersection = function(rectangle, otherRectangle, result) { + Check.typeOf.object('rectangle', rectangle); + Check.typeOf.object('otherRectangle', otherRectangle); + + var west = Math.max(rectangle.west, otherRectangle.west); + var south = Math.max(rectangle.south, otherRectangle.south); + var east = Math.min(rectangle.east, otherRectangle.east); + var north = Math.min(rectangle.north, otherRectangle.north); + + if (south >= north || west >= east) { return undefined; } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + + if (!defined(result)) { + return new Rectangle(west, south, east, north); + } + + result.west = west; + result.south = south; + result.east = east; + result.north = north; + return result; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * Computes a rectangle that is the union of two rectangles. + * + * @param {Rectangle} rectangle A rectangle to enclose in rectangle. + * @param {Rectangle} otherRectangle A rectangle to enclose in a rectangle. + * @param {Rectangle} [result] The object onto which to store the result. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. */ + Rectangle.union = function(rectangle, otherRectangle, result) { + Check.typeOf.object('rectangle', rectangle); + Check.typeOf.object('otherRectangle', otherRectangle); + + if (!defined(result)) { + result = new Rectangle(); + } - return Heap; -}); + var rectangleEast = rectangle.east; + var rectangleWest = rectangle.west; -define('Core/isBlobUri',[ - './Check' - ], function( - Check) { - 'use strict'; + var otherRectangleEast = otherRectangle.east; + var otherRectangleWest = otherRectangle.west; - var blobUriRegex = /^blob:/i; + if (rectangleEast < rectangleWest && otherRectangleEast > 0.0) { + rectangleEast += CesiumMath.TWO_PI; + } else if (otherRectangleEast < otherRectangleWest && rectangleEast > 0.0) { + otherRectangleEast += CesiumMath.TWO_PI; + } + + if (rectangleEast < rectangleWest && otherRectangleWest < 0.0) { + otherRectangleWest += CesiumMath.TWO_PI; + } else if (otherRectangleEast < otherRectangleWest && rectangleWest < 0.0) { + rectangleWest += CesiumMath.TWO_PI; + } + + var west = CesiumMath.convertLongitudeRange(Math.min(rectangleWest, otherRectangleWest)); + var east = CesiumMath.convertLongitudeRange(Math.max(rectangleEast, otherRectangleEast)); + + result.west = west; + result.south = Math.min(rectangle.south, otherRectangle.south); + result.east = east; + result.north = Math.max(rectangle.north, otherRectangle.north); + + return result; + }; /** - * Determines if the specified uri is a blob uri. - * - * @exports isBlobUri - * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * Computes a rectangle by enlarging the provided rectangle until it contains the provided cartographic. * - * @private + * @param {Rectangle} rectangle A rectangle to expand. + * @param {Cartographic} cartographic A cartographic to enclose in a rectangle. + * @param {Rectangle} [result] The object onto which to store the result. + * @returns {Rectangle} The modified result parameter or a new Rectangle instance if one was not provided. */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + Rectangle.expand = function(rectangle, cartographic, result) { + Check.typeOf.object('rectangle', rectangle); + Check.typeOf.object('cartographic', cartographic); - return blobUriRegex.test(uri); - } - - return isBlobUri; -}); + if (!defined(result)) { + result = new Rectangle(); + } -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + result.west = Math.min(rectangle.west, cartographic.longitude); + result.south = Math.min(rectangle.south, cartographic.latitude); + result.east = Math.max(rectangle.east, cartographic.longitude); + result.north = Math.max(rectangle.north, cartographic.latitude); - var dataUriRegex = /^data:/i; + return result; + }; /** - * Determines if the specified uri is a data uri. - * - * @exports isDataUri - * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * Returns true if the cartographic is on or inside the rectangle, false otherwise. * - * @private + * @param {Rectangle} rectangle The rectangle + * @param {Cartographic} cartographic The cartographic to test. + * @returns {Boolean} true if the provided cartographic is inside the rectangle, false otherwise. */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); + Rectangle.contains = function(rectangle, cartographic) { + Check.typeOf.object('rectangle', rectangle); + Check.typeOf.object('cartographic', cartographic); - return dataUriRegex.test(uri); - } + var longitude = cartographic.longitude; + var latitude = cartographic.latitude; - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; - - function sortRequests(a, b) { - return a.priority - b.priority; - } + var west = rectangle.west; + var east = rectangle.east; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + if (east < west) { + east += CesiumMath.TWO_PI; + if (longitude < 0.0) { + longitude += CesiumMath.TWO_PI; + } + } + return (longitude > west || CesiumMath.equalsEpsilon(longitude, west, CesiumMath.EPSILON14)) && + (longitude < east || CesiumMath.equalsEpsilon(longitude, east, CesiumMath.EPSILON14)) && + latitude >= rectangle.south && + latitude <= rectangle.north; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); - - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; - - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); - + var subsampleLlaScratch = new Cartographic(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler + * Samples a rectangle so that it includes a list of Cartesian points suitable for passing to + * {@link BoundingSphere#fromPoints}. Sampling is necessary to account + * for rectangles that cover the poles or cross the equator. * - * @private - */ - function RequestScheduler() { - } - - /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 - */ - RequestScheduler.maximumRequests = 50; - - /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 - */ - RequestScheduler.maximumRequestsPerServer = 6; - - /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true - */ - RequestScheduler.throttleRequests = true; - - /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * @param {Rectangle} rectangle The rectangle to subsample. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use. + * @param {Number} [surfaceHeight=0.0] The height of the rectangle above the ellipsoid. + * @param {Cartesian3[]} [result] The array of Cartesians onto which to store the result. + * @returns {Cartesian3[]} The modified result parameter or a new Array of Cartesians instances if none was provided. */ - RequestScheduler.debugShowStatistics = false; - - defineProperties(RequestScheduler, { - /** - * Returns the statistics used by the request scheduler. - * - * @memberof RequestScheduler - * - * @type Object - * @readonly - */ - statistics : { - get : function() { - return statistics; - } - }, - - /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. - * - * @memberof RequestScheduler - * - * @type {Number} - * @default 20 - */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); - } - } - }); + Rectangle.subsample = function(rectangle, ellipsoid, surfaceHeight, result) { + Check.typeOf.object('rectangle', rectangle); + + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + surfaceHeight = defaultValue(surfaceHeight, 0.0); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + if (!defined(result)) { + result = []; } - } - - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var length = 0; - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); - } - return request.deferred.promise; - } + var north = rectangle.north; + var south = rectangle.south; + var east = rectangle.east; + var west = rectangle.west; - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + var lla = subsampleLlaScratch; + lla.height = surfaceHeight; - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + lla.longitude = west; + lla.latitude = north; + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + lla.longitude = east; + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + lla.latitude = south; + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + lla.longitude = west; + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; - if (defined(request.cancelFunction)) { - request.cancelFunction(); + if (north < 0.0) { + lla.latitude = north; + } else if (south > 0.0) { + lla.latitude = south; + } else { + lla.latitude = 0.0; } - } - - /** - * Sort requests by priority and start requests. - */ - RequestScheduler.update = function() { - var i; - var request; - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; + for ( var i = 1; i < 8; ++i) { + lla.longitude = -Math.PI + i * CesiumMath.PI_OVER_TWO; + if (Rectangle.contains(rectangle, lla)) { + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; } } - activeRequests.length -= removeCount; - - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); - } - requestHeap.resort(); - - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } - - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } - startRequest(request); - ++filledSlots; + if (lla.latitude === 0.0) { + lla.longitude = west; + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; + lla.longitude = east; + result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); + length++; } - - updateStatistics(); + result.length = length; + return result; }; /** - * Get the server key from a given url. + * The largest possible rectangle. * - * @param {String} url The url. - * @returns {String} The server key. - */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); - } + * @type {Rectangle} + * @constant + */ + Rectangle.MAX_VALUE = freezeObject(new Rectangle(-Math.PI, -CesiumMath.PI_OVER_TWO, Math.PI, CesiumMath.PI_OVER_TWO)); - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + return Rectangle; +}); - return serverKey; - }; +define('Core/clone',[ + './defaultValue' + ], function( + defaultValue) { + 'use strict'; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Clones an object, returning a new object containing the same properties. * - * @param {Request} request The request object. + * @exports clone * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @param {Object} object The object to clone. + * @param {Boolean} [deep=false] If true, all properties will be deep cloned recursively. + * @returns {Object} The cloned object. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + function clone(object, deep) { + if (object === null || typeof object !== 'object') { + return object; } - ++statistics.numberOfAttemptedRequests; + deep = defaultValue(deep, false); - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); + var result = new object.constructor(); + for ( var propertyName in object) { + if (object.hasOwnProperty(propertyName)) { + var value = object[propertyName]; + if (deep) { + value = clone(value, deep); + } + result[propertyName] = value; + } } - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); - } + return result; + } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + return clone; +}); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } +define('Core/combine',[ + './defaultValue', + './defined' + ], function( + defaultValue, + defined) { + 'use strict'; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + /** + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. + * + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine + */ + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); } - - return issueRequest(request); - }; - - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; } - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + return combine; +}); - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' + ], function( + defaultValue, + defined, + DeveloperError) { + 'use strict'; - clearStatistics(); - } + var warnings = {}; /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. + * + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } * * @private */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; - - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; - - /** - * For testing only. - * - * @private - */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; - }; + } - /** - * For testing only. - * - * @private - */ - RequestScheduler.requestHeap = requestHeap; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return RequestScheduler; + return oneTimeWarning; }); -define('Core/loadJsonp',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './combine', - './defaultValue', +define('Core/deprecationWarning',[ './defined', './DeveloperError', - './objectToQuery', - './queryToObject', - './Request', - './RequestScheduler' + './oneTimeWarning' ], function( - Uri, - when, - combine, - defaultValue, defined, DeveloperError, - objectToQuery, - queryToObject, - Request, - RequestScheduler) { + oneTimeWarning) { 'use strict'; /** - * Requests a resource using JSONP. - * - * @exports loadJsonp + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @param {String} url The URL to request. - * @param {Object} [options] Object with the following properties: - * @param {Object} [options.parameters] Any extra query parameters to append to the URL. - * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. - * @param {Proxy} [options.proxy] A proxy to use for the request. This object is expected to have a getURL function which returns the proxied URL, if needed. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @exports deprecationWarning * + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. * * @example - * // load a data asynchronously - * Cesium.loadJsonp('some/webservice').then(function(data) { - * // use the loaded data - * }).otherwise(function(error) { - * // an error occurred + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } * }); * - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadJsonp(url, options, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); } - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + oneTimeWarning(identifier, message); + } - //generate a unique function name - var functionName; - do { - functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); - } while (defined(window[functionName])); + return deprecationWarning; +}); - var uri = new Uri(url); +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - var queryOptions = queryToObject(defaultValue(uri.query, '')); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - if (defined(options.parameters)) { - queryOptions = combine(options.parameters, queryOptions); - } + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - var callbackParameterName = defaultValue(options.callbackParameterName, 'callback'); - queryOptions[callbackParameterName] = functionName; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - uri.query = objectToQuery(queryOptions); + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - url = uri.toString(); + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - var proxy = options.proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - request = defined(request) ? request : new Request(); - request.url = url; - request.requestFunction = function() { - var deferred = when.defer(); + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - //assign a function with that name in the global scope - window[functionName] = function(data) { - deferred.resolve(data); + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - try { - delete window[functionName]; - } catch (e) { - window[functionName] = undefined; - } - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - loadJsonp.loadAndExecuteScript(url, functionName, deferred); - return deferred.promise; - }; + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - return RequestScheduler.request(request); - } + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadJsonp.loadAndExecuteScript = function(url, functionName, deferred) { - var script = document.createElement('script'); - script.async = true; - script.src = url; + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - var head = document.getElementsByTagName('head')[0]; - script.onload = function() { - script.onload = undefined; - head.removeChild(script); - }; - script.onerror = function(e) { - deferred.reject(e); - }; + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; - head.appendChild(script); - }; + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - loadJsonp.defaultLoadAndExecuteScript = loadJsonp.loadAndExecuteScript; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - return loadJsonp; + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; + + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; + + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; + +// var cache = {}; + + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); -define('Core/scaleToGeodeticSurface',[ - './Cartesian3', +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './DeveloperError', - './Math' + './DeveloperError' ], function( - Cartesian3, + Uri, + defaultValue, defined, - DeveloperError, - CesiumMath) { + DeveloperError) { 'use strict'; - var scaleToGeodeticSurfaceIntersection = new Cartesian3(); - var scaleToGeodeticSurfaceGradient = new Cartesian3(); - /** - * Scales the provided Cartesian position along the geodetic surface normal - * so that it is on the surface of this ellipsoid. If the position is - * at the center of the ellipsoid, this function returns undefined. - * - * @param {Cartesian3} cartesian The Cartesian position to scale. - * @param {Cartesian3} oneOverRadii One over radii of the ellipsoid. - * @param {Cartesian3} oneOverRadiiSquared One over radii squared of the ellipsoid. - * @param {Number} centerToleranceSquared Tolerance for closeness to the center. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @exports scaleToGeodeticSurface + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @private + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function scaleToGeodeticSurface(cartesian, oneOverRadii, oneOverRadiiSquared, centerToleranceSquared, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); - } - if (!defined(oneOverRadii)) { - throw new DeveloperError('oneOverRadii is required.'); - } - if (!defined(oneOverRadiiSquared)) { - throw new DeveloperError('oneOverRadiiSquared is required.'); - } - if (!defined(centerToleranceSquared)) { - throw new DeveloperError('centerToleranceSquared is required.'); - } - - var positionX = cartesian.x; - var positionY = cartesian.y; - var positionZ = cartesian.z; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - var oneOverRadiiX = oneOverRadii.x; - var oneOverRadiiY = oneOverRadii.y; - var oneOverRadiiZ = oneOverRadii.z; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - var x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX; - var y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY; - var z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ; + return getAbsoluteUri; +}); - // Compute the squared ellipsoid norm. - var squaredNorm = x2 + y2 + z2; - var ratio = Math.sqrt(1.0 / squaredNorm); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; - // As an initial approximation, assume that the radial intersection is the projection point. - var intersection = Cartesian3.multiplyByScalar(cartesian, ratio, scaleToGeodeticSurfaceIntersection); - - // If the position is near the center, the iteration will not converge. - if (squaredNorm < centerToleranceSquared) { - return !isFinite(ratio) ? undefined : Cartesian3.clone(intersection, result); + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); } - var oneOverRadiiSquaredX = oneOverRadiiSquared.x; - var oneOverRadiiSquaredY = oneOverRadiiSquared.y; - var oneOverRadiiSquaredZ = oneOverRadiiSquared.z; - - // Use the gradient at the intersection point in place of the true unit normal. - // The difference in magnitude will be absorbed in the multiplier. - var gradient = scaleToGeodeticSurfaceGradient; - gradient.x = intersection.x * oneOverRadiiSquaredX * 2.0; - gradient.y = intersection.y * oneOverRadiiSquaredY * 2.0; - gradient.z = intersection.z * oneOverRadiiSquaredZ * 2.0; - - // Compute the initial guess at the normal vector multiplier, lambda. - var lambda = (1.0 - ratio) * Cartesian3.magnitude(cartesian) / (0.5 * Cartesian3.magnitude(gradient)); - var correction = 0.0; - - var func; - var denominator; - var xMultiplier; - var yMultiplier; - var zMultiplier; - var xMultiplier2; - var yMultiplier2; - var zMultiplier2; - var xMultiplier3; - var yMultiplier3; - var zMultiplier3; + if (!includeQuery) { + return basePath; + } - do { - lambda -= correction; + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } - xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX); - yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY); - zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ); + return basePath; + } - xMultiplier2 = xMultiplier * xMultiplier; - yMultiplier2 = yMultiplier * yMultiplier; - zMultiplier2 = zMultiplier * zMultiplier; + return getBaseUri; +}); - xMultiplier3 = xMultiplier2 * xMultiplier; - yMultiplier3 = yMultiplier2 * yMultiplier; - zMultiplier3 = zMultiplier2 * zMultiplier; +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; - func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0; + /** + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri + * + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); + */ + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - // "denominator" here refers to the use of this expression in the velocity and acceleration - // computations in the sections to follow. - denominator = x2 * xMultiplier3 * oneOverRadiiSquaredX + y2 * yMultiplier3 * oneOverRadiiSquaredY + z2 * zMultiplier3 * oneOverRadiiSquaredZ; + return getExtensionFromUri; +}); - var derivative = -2.0 * denominator; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - correction = func / derivative; - } while (Math.abs(func) > CesiumMath.EPSILON12); + var blobUriRegex = /^blob:/i; - if (!defined(result)) { - return new Cartesian3(positionX * xMultiplier, positionY * yMultiplier, positionZ * zMultiplier); - } - result.x = positionX * xMultiplier; - result.y = positionY * yMultiplier; - result.z = positionZ * zMultiplier; - return result; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); } - return scaleToGeodeticSurface; + return isBlobUri; }); -define('Core/Cartographic',[ - './Cartesian3', - './Check', - './defaultValue', - './defined', - './freezeObject', - './Math', - './scaleToGeodeticSurface' +define('Core/isCrossOriginUrl',[ + './defined' ], function( - Cartesian3, - Check, - defaultValue, - defined, - freezeObject, - CesiumMath, - scaleToGeodeticSurface) { + defined) { 'use strict'; + var a; + /** - * A position defined by longitude, latitude, and height. - * @alias Cartographic - * @constructor - * - * @param {Number} [longitude=0.0] The longitude, in radians. - * @param {Number} [latitude=0.0] The latitude, in radians. - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * Given a URL, determine whether that URL is considered cross-origin to the current page. * - * @see Ellipsoid + * @private */ - function Cartographic(longitude, latitude, height) { - /** - * The longitude, in radians. - * @type {Number} - * @default 0.0 - */ - this.longitude = defaultValue(longitude, 0.0); + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * The latitude, in radians. - * @type {Number} - * @default 0.0 - */ - this.latitude = defaultValue(latitude, 0.0); + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - /** - * The height, in meters, above the ellipsoid. - * @type {Number} - * @default 0.0 - */ - this.height = defaultValue(height, 0.0); + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; } + return isCrossOriginUrl; +}); + +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; + + var dataUriRegex = /^data:/i; + /** - * Creates a new Cartographic instance from longitude and latitude - * specified in radians. + * Determines if the specified uri is a data uri. * - * @param {Number} longitude The longitude, in radians. - * @param {Number} latitude The latitude, in radians. - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private */ - Cartographic.fromRadians = function(longitude, latitude, height, result) { - Check.typeOf.number('longitude', longitude); - Check.typeOf.number('latitude', latitude); + function isDataUri(uri) { + Check.typeOf.string('uri', uri); - height = defaultValue(height, 0.0); + return dataUriRegex.test(uri); + } - if (!defined(result)) { - return new Cartographic(longitude, latitude, height); - } + return isDataUri; +}); - result.longitude = longitude; - result.latitude = latitude; - result.height = height; - return result; - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; /** - * Creates a new Cartographic instance from longitude and latitude - * specified in degrees. The values in the resulting object will - * be in radians. + * Tests an object to see if it is an array. + * @exports isArray * - * @param {Number} longitude The longitude, in degrees. - * @param {Number} latitude The latitude, in degrees. - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. */ - Cartographic.fromDegrees = function(longitude, latitude, height, result) { - Check.typeOf.number('longitude', longitude); - Check.typeOf.number('latitude', latitude); - longitude = CesiumMath.toRadians(longitude); - latitude = CesiumMath.toRadians(latitude); + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } - return Cartographic.fromRadians(longitude, latitude, height, result); - }; + return isArray; +}); - var cartesianToCartographicN = new Cartesian3(); - var cartesianToCartographicP = new Cartesian3(); - var cartesianToCartographicH = new Cartesian3(); - var wgs84OneOverRadii = new Cartesian3(1.0 / 6378137.0, 1.0 / 6378137.0, 1.0 / 6356752.3142451793); - var wgs84OneOverRadiiSquared = new Cartesian3(1.0 / (6378137.0 * 6378137.0), 1.0 / (6378137.0 * 6378137.0), 1.0 / (6356752.3142451793 * 6356752.3142451793)); - var wgs84CenterToleranceSquared = CesiumMath.EPSILON1; +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; /** - * Creates a new Cartographic instance from a Cartesian position. The values in the - * resulting object will be in radians. + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery * - * @param {Cartesian3} cartesian The Cartesian position to convert to cartographic representation. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter, new Cartographic instance if none was provided, or undefined if the cartesian is at the center of the ellipsoid. + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' */ - Cartographic.fromCartesian = function(cartesian, ellipsoid, result) { - var oneOverRadii = defined(ellipsoid) ? ellipsoid.oneOverRadii : wgs84OneOverRadii; - var oneOverRadiiSquared = defined(ellipsoid) ? ellipsoid.oneOverRadiiSquared : wgs84OneOverRadiiSquared; - var centerToleranceSquared = defined(ellipsoid) ? ellipsoid._centerToleranceSquared : wgs84CenterToleranceSquared; - - //`cartesian is required.` is thrown from scaleToGeodeticSurface - var p = scaleToGeodeticSurface(cartesian, oneOverRadii, oneOverRadiiSquared, centerToleranceSquared, cartesianToCartographicP); - - if (!defined(p)) { - return undefined; + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; - var n = Cartesian3.multiplyComponents(p, oneOverRadiiSquared, cartesianToCartographicN); - n = Cartesian3.normalize(n, n); + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } - var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH); + // trim last & + result = result.slice(0, -1); - var longitude = Math.atan2(n.y, n.x); - var latitude = Math.asin(n.z); - var height = CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h); + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 - if (!defined(result)) { - return new Cartographic(longitude, latitude, height); - } - result.longitude = longitude; - result.latitude = latitude; - result.height = height; return result; - }; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; /** - * Duplicates a Cartographic instance. + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject * - * @param {Cartographic} cartographic The cartographic to duplicate. - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. (Returns undefined if cartographic is undefined) + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery */ - Cartographic.clone = function(cartographic, result) { - if (!defined(cartographic)) { - return undefined; + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); } - if (!defined(result)) { - return new Cartographic(cartographic.longitude, cartographic.latitude, cartographic.height); + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } } - result.longitude = cartographic.longitude; - result.latitude = cartographic.latitude; - result.height = cartographic.height; return result; - }; + } - /** - * Compares the provided cartographics componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Cartographic} [left] The first cartographic. - * @param {Cartographic} [right] The second cartographic. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Cartographic.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.longitude === right.longitude) && - (left.latitude === right.latitude) && - (left.height === right.height)); - }; + return queryToObject; +}); - /** - * Compares the provided cartographics componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {Cartographic} [left] The first cartographic. - * @param {Cartographic} [right] The second cartographic. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. - */ - Cartographic.equalsEpsilon = function(left, right, epsilon) { - Check.typeOf.number('epsilon', epsilon); - - return (left === right) || - ((defined(left)) && - (defined(right)) && - (Math.abs(left.longitude - right.longitude) <= epsilon) && - (Math.abs(left.latitude - right.latitude) <= epsilon) && - (Math.abs(left.height - right.height) <= epsilon)); - }; +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; /** - * An immutable Cartographic instance initialized to (0.0, 0.0, 0.0). + * State of the request. * - * @type {Cartographic} - * @constant + * @exports RequestState */ - Cartographic.ZERO = freezeObject(new Cartographic(0.0, 0.0, 0.0)); + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, - /** - * Duplicates this instance. - * - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. - */ - Cartographic.prototype.clone = function(result) { - return Cartographic.clone(this, result); - }; + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, - /** - * Compares the provided against this cartographic componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Cartographic} [right] The second cartographic. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Cartographic.prototype.equals = function(right) { - return Cartographic.equals(this, right); - }; + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, - /** - * Compares the provided against this cartographic componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {Cartographic} [right] The second cartographic. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. - */ - Cartographic.prototype.equalsEpsilon = function(right, epsilon) { - return Cartographic.equalsEpsilon(this, right, epsilon); + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 }; + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** - * Creates a string representing this cartographic in the format '(longitude, latitude, height)'. + * An enum identifying the type of request. Used for finer grained logging and priority sorting. * - * @returns {String} A string representing the provided cartographic in the format '(longitude, latitude, height)'. + * @exports RequestType */ - Cartographic.prototype.toString = function() { - return '(' + this.longitude + ', ' + this.latitude + ', ' + this.height + ')'; + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 }; - return Cartographic; + return freezeObject(RequestType); }); -define('Core/Ellipsoid',[ - './Cartesian3', - './Cartographic', - './Check', +define('Core/Request',[ './defaultValue', './defined', - './defineProperties', - './DeveloperError', - './freezeObject', - './Math', - './scaleToGeodeticSurface' + './RequestState', + './RequestType' ], function( - Cartesian3, - Cartographic, - Check, defaultValue, defined, - defineProperties, - DeveloperError, - freezeObject, - CesiumMath, - scaleToGeodeticSurface) { + RequestState, + RequestType) { 'use strict'; - function initialize(ellipsoid, x, y, z) { - x = defaultValue(x, 0.0); - y = defaultValue(y, 0.0); - z = defaultValue(z, 0.0); - - Check.typeOf.number.greaterThanOrEquals('x', x, 0.0); - Check.typeOf.number.greaterThanOrEquals('y', y, 0.0); - Check.typeOf.number.greaterThanOrEquals('z', z, 0.0); - - ellipsoid._radii = new Cartesian3(x, y, z); - - ellipsoid._radiiSquared = new Cartesian3(x * x, - y * y, - z * z); - - ellipsoid._radiiToTheFourth = new Cartesian3(x * x * x * x, - y * y * y * y, - z * z * z * z); - - ellipsoid._oneOverRadii = new Cartesian3(x === 0.0 ? 0.0 : 1.0 / x, - y === 0.0 ? 0.0 : 1.0 / y, - z === 0.0 ? 0.0 : 1.0 / z); - - ellipsoid._oneOverRadiiSquared = new Cartesian3(x === 0.0 ? 0.0 : 1.0 / (x * x), - y === 0.0 ? 0.0 : 1.0 / (y * y), - z === 0.0 ? 0.0 : 1.0 / (z * z)); - - ellipsoid._minimumRadius = Math.min(x, y, z); - - ellipsoid._maximumRadius = Math.max(x, y, z); - - ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1; - - if (ellipsoid._radiiSquared.z !== 0) { - ellipsoid._squaredXOverSquaredZ = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z; - } - } - /** - * A quadratic surface defined in Cartesian coordinates by the equation - * <code>(x / a)^2 + (y / b)^2 + (z / c)^2 = 1</code>. Primarily used - * by Cesium to represent the shape of planetary bodies. + * Stores information for making a request. In general this does not need to be constructed directly. * - * Rather than constructing this object directly, one of the provided - * constants is normally used. - * @alias Ellipsoid + * @alias Request * @constructor * - * @param {Number} [x=0] The radius in the x direction. - * @param {Number} [y=0] The radius in the y direction. - * @param {Number} [z=0] The radius in the z direction. - * - * @exception {DeveloperError} All radii components must be greater than or equal to zero. - * - * @see Ellipsoid.fromCartesian3 - * @see Ellipsoid.WGS84 - * @see Ellipsoid.UNIT_SPHERE + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. */ - function Ellipsoid(x, y, z) { - this._radii = undefined; - this._radiiSquared = undefined; - this._radiiToTheFourth = undefined; - this._oneOverRadii = undefined; - this._oneOverRadiiSquared = undefined; - this._minimumRadius = undefined; - this._maximumRadius = undefined; - this._centerToleranceSquared = undefined; - this._squaredXOverSquaredZ = undefined; + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - initialize(this, x, y, z); - } + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); - defineProperties(Ellipsoid.prototype, { /** - * Gets the radii of the ellipsoid. - * @memberof Ellipsoid.prototype - * @type {Cartesian3} - * @readonly + * The URL to request. + * + * @type {String} */ - radii : { - get: function() { - return this._radii; - } - }, + this.url = options.url; + /** - * Gets the squared radii of the ellipsoid. - * @memberof Ellipsoid.prototype - * @type {Cartesian3} - * @readonly + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} */ - radiiSquared : { - get : function() { - return this._radiiSquared; - } - }, + this.requestFunction = options.requestFunction; + /** - * Gets the radii of the ellipsoid raise to the fourth power. - * @memberof Ellipsoid.prototype - * @type {Cartesian3} - * @readonly + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} */ - radiiToTheFourth : { - get : function() { - return this._radiiToTheFourth; - } - }, + this.cancelFunction = options.cancelFunction; + /** - * Gets one over the radii of the ellipsoid. - * @memberof Ellipsoid.prototype - * @type {Cartesian3} + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} * @readonly + * + * @default false */ - oneOverRadii : { - get : function() { - return this._oneOverRadii; - } - }, + this.throttle = throttle; + /** - * Gets one over the squared radii of the ellipsoid. - * @memberof Ellipsoid.prototype - * @type {Cartesian3} + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} * @readonly + * + * @default false */ - oneOverRadiiSquared : { - get : function() { - return this._oneOverRadiiSquared; - } - }, + this.throttleByServer = throttleByServer; + /** - * Gets the minimum radius of the ellipsoid. - * @memberof Ellipsoid.prototype - * @type {Number} + * Type of request. + * + * @type {RequestType} * @readonly + * + * @default RequestType.OTHER */ - minimumRadius : { - get : function() { - return this._minimumRadius; - } - }, + this.type = defaultValue(options.type, RequestType.OTHER); + /** - * Gets the maximum radius of the ellipsoid. - * @memberof Ellipsoid.prototype - * @type {Number} + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} * @readonly */ - maximumRadius : { - get : function() { - return this._maximumRadius; - } - } - }); + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } /** - * Duplicates an Ellipsoid instance. + * Mark the request as cancelled. * - * @param {Ellipsoid} ellipsoid The ellipsoid to duplicate. - * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new - * instance should be created. - * @returns {Ellipsoid} The cloned Ellipsoid. (Returns undefined if ellipsoid is undefined) + * @private */ - Ellipsoid.clone = function(ellipsoid, result) { - if (!defined(ellipsoid)) { - return undefined; - } - var radii = ellipsoid._radii; - - if (!defined(result)) { - return new Ellipsoid(radii.x, radii.y, radii.z); - } - - Cartesian3.clone(radii, result._radii); - Cartesian3.clone(ellipsoid._radiiSquared, result._radiiSquared); - Cartesian3.clone(ellipsoid._radiiToTheFourth, result._radiiToTheFourth); - Cartesian3.clone(ellipsoid._oneOverRadii, result._oneOverRadii); - Cartesian3.clone(ellipsoid._oneOverRadiiSquared, result._oneOverRadiiSquared); - result._minimumRadius = ellipsoid._minimumRadius; - result._maximumRadius = ellipsoid._maximumRadius; - result._centerToleranceSquared = ellipsoid._centerToleranceSquared; - - return result; + Request.prototype.cancel = function() { + this.cancelled = true; }; + /** - * Computes an Ellipsoid from a Cartesian specifying the radii in x, y, and z directions. - * - * @param {Cartesian3} [cartesian=Cartesian3.ZERO] The ellipsoid's radius in the x, y, and z directions. - * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new - * instance should be created. - * @returns {Ellipsoid} A new Ellipsoid instance. + * Duplicates a Request instance. * - * @exception {DeveloperError} All radii components must be greater than or equal to zero. + * @param {Request} [result] The object onto which to store the result. * - * @see Ellipsoid.WGS84 - * @see Ellipsoid.UNIT_SPHERE + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. */ - Ellipsoid.fromCartesian3 = function(cartesian, result) { + Request.prototype.clone = function(result) { if (!defined(result)) { - result = new Ellipsoid(); + return new Request(this); } - if (!defined(cartesian)) { - return result; - } + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; - initialize(result, cartesian.x, cartesian.y, cartesian.z); return result; }; /** - * An Ellipsoid instance initialized to the WGS84 standard. - * - * @type {Ellipsoid} - * @constant + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. */ - Ellipsoid.WGS84 = freezeObject(new Ellipsoid(6378137.0, 6378137.0, 6356752.3142451793)); /** - * An Ellipsoid instance initialized to radii of (1.0, 1.0, 1.0). - * - * @type {Ellipsoid} - * @constant + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback */ - Ellipsoid.UNIT_SPHERE = freezeObject(new Ellipsoid(1.0, 1.0, 1.0)); /** - * An Ellipsoid instance initialized to a sphere with the lunar radius. - * - * @type {Ellipsoid} - * @constant + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. */ - Ellipsoid.MOON = freezeObject(new Ellipsoid(CesiumMath.LUNAR_RADIUS, CesiumMath.LUNAR_RADIUS, CesiumMath.LUNAR_RADIUS)); - /** - * Duplicates an Ellipsoid instance. - * - * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new - * instance should be created. - * @returns {Ellipsoid} The cloned Ellipsoid. - */ - Ellipsoid.prototype.clone = function(result) { - return Ellipsoid.clone(this, result); - }; + return Request; +}); - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - Ellipsoid.packedLength = Cartesian3.packedLength; +define('Core/parseResponseHeaders',[], function() { + 'use strict'; /** - * Stores the provided instance into the provided array. + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. * - * @param {Ellipsoid} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @exports parseResponseHeaders * - * @returns {Number[]} The array that was packed into - */ - Ellipsoid.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); - - Cartesian3.pack(value._radii, array, startingIndex); - - return array; - }; - - /** - * Retrieves an instance from a packed array. + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Ellipsoid} [result] The object into which to store the result. - * @returns {Ellipsoid} The modified result parameter or a new Ellipsoid instance if one was not provided. + * @private */ - Ellipsoid.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + function parseResponseHeaders(headerString) { + var headers = {}; - var radii = Cartesian3.unpack(array, startingIndex); - return Ellipsoid.fromCartesian3(radii, result); - }; + if (!headerString) { + return headers; + } - /** - * Computes the unit vector directed from the center of this ellipsoid toward the provided Cartesian position. - * @function - * - * @param {Cartesian3} cartesian The Cartesian for which to to determine the geocentric normal. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. - */ - Ellipsoid.prototype.geocentricSurfaceNormal = Cartesian3.normalize; + var headerPairs = headerString.split('\u000d\u000a'); - /** - * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position. - * - * @param {Cartographic} cartographic The cartographic position for which to to determine the geodetic normal. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. - */ - Ellipsoid.prototype.geodeticSurfaceNormalCartographic = function(cartographic, result) { - Check.typeOf.object('cartographic', cartographic); - - var longitude = cartographic.longitude; - var latitude = cartographic.latitude; - var cosLatitude = Math.cos(latitude); - - var x = cosLatitude * Math.cos(longitude); - var y = cosLatitude * Math.sin(longitude); - var z = Math.sin(latitude); - - if (!defined(result)) { - result = new Cartesian3(); + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } } - result.x = x; - result.y = y; - result.z = z; - return Cartesian3.normalize(result, result); - }; - /** - * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position. - * - * @param {Cartesian3} cartesian The Cartesian position for which to to determine the surface normal. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. - */ - Ellipsoid.prototype.geodeticSurfaceNormal = function(cartesian, result) { - if (!defined(result)) { - result = new Cartesian3(); - } - result = Cartesian3.multiplyComponents(cartesian, this._oneOverRadiiSquared, result); - return Cartesian3.normalize(result, result); - }; + return headers; + } - var cartographicToCartesianNormal = new Cartesian3(); - var cartographicToCartesianK = new Cartesian3(); + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; /** - * Converts the provided cartographic to Cartesian representation. + * An event that is raised when a request encounters an error. * - * @param {Cartographic} cartographic The cartographic position. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. + * @constructor + * @alias RequestErrorEvent * - * @example - * //Create a Cartographic and determine it's Cartesian representation on a WGS84 ellipsoid. - * var position = new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 5000); - * var cartesianPosition = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position); + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. */ - Ellipsoid.prototype.cartographicToCartesian = function(cartographic, result) { - //`cartographic is required` is thrown from geodeticSurfaceNormalCartographic. - var n = cartographicToCartesianNormal; - var k = cartographicToCartesianK; - this.geodeticSurfaceNormalCartographic(cartographic, n); - Cartesian3.multiplyComponents(this._radiiSquared, n, k); - var gamma = Math.sqrt(Cartesian3.dot(n, k)); - Cartesian3.divideByScalar(k, gamma, k); - Cartesian3.multiplyByScalar(n, cartographic.height, n); + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; - if (!defined(result)) { - result = new Cartesian3(); + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); } - return Cartesian3.add(k, n, result); - }; + } /** - * Converts the provided array of cartographics to an array of Cartesians. - * - * @param {Cartographic[]} cartographics An array of cartographic positions. - * @param {Cartesian3[]} [result] The object onto which to store the result. - * @returns {Cartesian3[]} The modified result parameter or a new Array instance if none was provided. + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent * - * @example - * //Convert an array of Cartographics and determine their Cartesian representation on a WGS84 ellipsoid. - * var positions = [new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 0), - * new Cesium.Cartographic(Cesium.Math.toRadians(21.321), Cesium.Math.toRadians(78.123), 100), - * new Cesium.Cartographic(Cesium.Math.toRadians(21.645), Cesium.Math.toRadians(78.456), 250)]; - * var cartesianPositions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(positions); + * @returns {String} A string representing the provided RequestErrorEvent. */ - Ellipsoid.prototype.cartographicArrayToCartesianArray = function(cartographics, result) { - Check.defined('cartographics', cartographics); - - var length = cartographics.length; - if (!defined(result)) { - result = new Array(length); - } else { - result.length = length; - } - for ( var i = 0; i < length; i++) { - result[i] = this.cartographicToCartesian(cartographics[i], result[i]); + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; } - return result; + return str; }; - var cartesianToCartographicN = new Cartesian3(); - var cartesianToCartographicP = new Cartesian3(); - var cartesianToCartographicH = new Cartesian3(); + return RequestErrorEvent; +}); - /** - * Converts the provided cartesian to cartographic representation. - * The cartesian is undefined at the center of the ellipsoid. - * - * @param {Cartesian3} cartesian The Cartesian position to convert to cartographic representation. - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter, new Cartographic instance if none was provided, or undefined if the cartesian is at the center of the ellipsoid. - * - * @example - * //Create a Cartesian and determine it's Cartographic representation on a WGS84 ellipsoid. - * var position = new Cesium.Cartesian3(17832.12, 83234.52, 952313.73); - * var cartographicPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); - */ - Ellipsoid.prototype.cartesianToCartographic = function(cartesian, result) { - //`cartesian is required.` is thrown from scaleToGeodeticSurface - var p = this.scaleToGeodeticSurface(cartesian, cartesianToCartographicP); +/** + @license + when.js - https://github.com/cujojs/when - if (!defined(p)) { - return undefined; - } + MIT License (c) copyright B Cavalier & J Hann - var n = this.geodeticSurfaceNormal(p, cartesianToCartographicN); - var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH); + * A lightweight CommonJS Promises/A and when() implementation + * when is part of the cujo.js family of libraries (http://cujojs.com/) + * + * Licensed under the MIT License at: + * http://www.opensource.org/licenses/mit-license.php + * + * @version 1.7.1 + */ - var longitude = Math.atan2(n.y, n.x); - var latitude = Math.asin(n.z); - var height = CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h); +(function(define) { 'use strict'; +define('ThirdParty/when',[],function () { + var reduceArray, slice, undef; - if (!defined(result)) { - return new Cartographic(longitude, latitude, height); - } - result.longitude = longitude; - result.latitude = latitude; - result.height = height; - return result; - }; + // + // Public API + // - /** - * Converts the provided array of cartesians to an array of cartographics. - * - * @param {Cartesian3[]} cartesians An array of Cartesian positions. - * @param {Cartographic[]} [result] The object onto which to store the result. - * @returns {Cartographic[]} The modified result parameter or a new Array instance if none was provided. - * - * @example - * //Create an array of Cartesians and determine their Cartographic representation on a WGS84 ellipsoid. - * var positions = [new Cesium.Cartesian3(17832.12, 83234.52, 952313.73), - * new Cesium.Cartesian3(17832.13, 83234.53, 952313.73), - * new Cesium.Cartesian3(17832.14, 83234.54, 952313.73)] - * var cartographicPositions = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray(positions); - */ - Ellipsoid.prototype.cartesianArrayToCartographicArray = function(cartesians, result) { - Check.defined('cartesians', cartesians); - - var length = cartesians.length; - if (!defined(result)) { - result = new Array(length); - } else { - result.length = length; - } - for ( var i = 0; i < length; ++i) { - result[i] = this.cartesianToCartographic(cartesians[i], result[i]); - } - return result; - }; + when.defer = defer; // Create a deferred + when.resolve = resolve; // Create a resolved promise + when.reject = reject; // Create a rejected promise - /** - * Scales the provided Cartesian position along the geodetic surface normal - * so that it is on the surface of this ellipsoid. If the position is - * at the center of the ellipsoid, this function returns undefined. - * - * @param {Cartesian3} cartesian The Cartesian position to scale. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center. - */ - Ellipsoid.prototype.scaleToGeodeticSurface = function(cartesian, result) { - return scaleToGeodeticSurface(cartesian, this._oneOverRadii, this._oneOverRadiiSquared, this._centerToleranceSquared, result); - }; + when.join = join; // Join 2 or more promises - /** - * Scales the provided Cartesian position along the geocentric surface normal - * so that it is on the surface of this ellipsoid. - * - * @param {Cartesian3} cartesian The Cartesian position to scale. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided. - */ - Ellipsoid.prototype.scaleToGeocentricSurface = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - - if (!defined(result)) { - result = new Cartesian3(); - } + when.all = all; // Resolve a list of promises + when.map = map; // Array.map() for promises + when.reduce = reduce; // Array.reduce() for promises - var positionX = cartesian.x; - var positionY = cartesian.y; - var positionZ = cartesian.z; - var oneOverRadiiSquared = this._oneOverRadiiSquared; + when.any = any; // One-winner race + when.some = some; // Multi-winner race - var beta = 1.0 / Math.sqrt((positionX * positionX) * oneOverRadiiSquared.x + - (positionY * positionY) * oneOverRadiiSquared.y + - (positionZ * positionZ) * oneOverRadiiSquared.z); + when.chain = chain; // Make a promise trigger another resolver - return Cartesian3.multiplyByScalar(cartesian, beta, result); - }; + when.isPromise = isPromise; // Determine if a thing is a promise - /** - * Transforms a Cartesian X, Y, Z position to the ellipsoid-scaled space by multiplying - * its components by the result of {@link Ellipsoid#oneOverRadii}. - * - * @param {Cartesian3} position The position to transform. - * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and - * return a new instance. - * @returns {Cartesian3} The position expressed in the scaled space. The returned instance is the - * one passed as the result parameter if it is not undefined, or a new instance of it is. - */ - Ellipsoid.prototype.transformPositionToScaledSpace = function(position, result) { - if (!defined(result)) { - result = new Cartesian3(); - } + /** + * Register an observer for a promise or immediate value. + * + * @param {*} promiseOrValue + * @param {function?} [onFulfilled] callback to be called when promiseOrValue is + * successfully fulfilled. If promiseOrValue is an immediate value, callback + * will be invoked immediately. + * @param {function?} [onRejected] callback to be called when promiseOrValue is + * rejected. + * @param {function?} [onProgress] callback to be called when progress updates + * are issued for promiseOrValue. + * @returns {Promise} a new {@link Promise} that will complete with the return + * value of callback or errback or the completion value of promiseOrValue if + * callback and/or errback is not supplied. + */ + function when(promiseOrValue, onFulfilled, onRejected, onProgress) { + // Get a trusted promise for the input promiseOrValue, and then + // register promise handlers + return resolve(promiseOrValue).then(onFulfilled, onRejected, onProgress); + } - return Cartesian3.multiplyComponents(position, this._oneOverRadii, result); - }; + /** + * Returns promiseOrValue if promiseOrValue is a {@link Promise}, a new Promise if + * promiseOrValue is a foreign promise, or a new, already-fulfilled {@link Promise} + * whose value is promiseOrValue if promiseOrValue is an immediate value. + * + * @param {*} promiseOrValue + * @returns Guaranteed to return a trusted Promise. If promiseOrValue is a when.js {@link Promise} + * returns promiseOrValue, otherwise, returns a new, already-resolved, when.js {@link Promise} + * whose resolution value is: + * * the resolution value of promiseOrValue if it's a foreign promise, or + * * promiseOrValue if it's a value + */ + function resolve(promiseOrValue) { + var promise, deferred; - /** - * Transforms a Cartesian X, Y, Z position from the ellipsoid-scaled space by multiplying - * its components by the result of {@link Ellipsoid#radii}. - * - * @param {Cartesian3} position The position to transform. - * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and - * return a new instance. - * @returns {Cartesian3} The position expressed in the unscaled space. The returned instance is the - * one passed as the result parameter if it is not undefined, or a new instance of it is. - */ - Ellipsoid.prototype.transformPositionFromScaledSpace = function(position, result) { - if (!defined(result)) { - result = new Cartesian3(); - } + if(promiseOrValue instanceof Promise) { + // It's a when.js promise, so we trust it + promise = promiseOrValue; - return Cartesian3.multiplyComponents(position, this._radii, result); - }; + } else { + // It's not a when.js promise. See if it's a foreign promise or a value. + if(isPromise(promiseOrValue)) { + // It's a thenable, but we don't know where it came from, so don't trust + // its implementation entirely. Introduce a trusted middleman when.js promise + deferred = defer(); - /** - * Compares this Ellipsoid against the provided Ellipsoid componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Ellipsoid} [right] The other Ellipsoid. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - Ellipsoid.prototype.equals = function(right) { - return (this === right) || - (defined(right) && - Cartesian3.equals(this._radii, right._radii)); - }; + // IMPORTANT: This is the only place when.js should ever call .then() on an + // untrusted promise. Don't expose the return value to the untrusted promise + promiseOrValue.then( + function(value) { deferred.resolve(value); }, + function(reason) { deferred.reject(reason); }, + function(update) { deferred.progress(update); } + ); - /** - * Creates a string representing this Ellipsoid in the format '(radii.x, radii.y, radii.z)'. - * - * @returns {String} A string representing this ellipsoid in the format '(radii.x, radii.y, radii.z)'. - */ - Ellipsoid.prototype.toString = function() { - return this._radii.toString(); - }; + promise = deferred.promise; - /** - * Computes a point which is the intersection of the surface normal with the z-axis. - * - * @param {Cartesian3} position the position. must be on the surface of the ellipsoid. - * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. - * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center. - * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis). - * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / AxisOfRotation is bigger than the square root of 2 - * @param {Cartesian3} [result] The cartesian to which to copy the result, or undefined to create and - * return a new instance. - * @returns {Cartesian3 | undefined} the intersection point if it's inside the ellipsoid, undefined otherwise - * - * @exception {DeveloperError} position is required. - * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y). - * @exception {DeveloperError} Ellipsoid.radii.z must be greater than 0. - */ - Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) { - Check.typeOf.object('position', position); + } else { + // It's a value, not a promise. Create a resolved promise for it. + promise = fulfilled(promiseOrValue); + } + } - if (!CesiumMath.equalsEpsilon(this._radii.x, this._radii.y, CesiumMath.EPSILON15)) { - throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); - } + return promise; + } - Check.typeOf.number.greaterThan('Ellipsoid.radii.z', this._radii.z, 0); - - buffer = defaultValue(buffer, 0.0); + /** + * Returns a rejected promise for the supplied promiseOrValue. The returned + * promise will be rejected with: + * - promiseOrValue, if it is a value, or + * - if promiseOrValue is a promise + * - promiseOrValue's value after it is fulfilled + * - promiseOrValue's reason after it is rejected + * @param {*} promiseOrValue the rejected value of the returned {@link Promise} + * @returns {Promise} rejected {@link Promise} + */ + function reject(promiseOrValue) { + return when(promiseOrValue, rejected); + } - var squaredXOverSquaredZ = this._squaredXOverSquaredZ; + /** + * Trusted Promise constructor. A Promise created from this constructor is + * a trusted when.js promise. Any other duck-typed promise is considered + * untrusted. + * @constructor + * @name Promise + */ + function Promise(then) { + this.then = then; + } - if (!defined(result)) { - result = new Cartesian3(); - } + Promise.prototype = { + /** + * Register a callback that will be called when a promise is + * fulfilled or rejected. Optionally also register a progress handler. + * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress) + * @param {function?} [onFulfilledOrRejected] + * @param {function?} [onProgress] + * @returns {Promise} + */ + always: function(onFulfilledOrRejected, onProgress) { + return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress); + }, - result.x = 0.0; - result.y = 0.0; - result.z = position.z * (1 - squaredXOverSquaredZ); + /** + * Register a rejection handler. Shortcut for .then(undefined, onRejected) + * @param {function?} onRejected + * @returns {Promise} + */ + otherwise: function(onRejected) { + return this.then(undef, onRejected); + }, - if (Math.abs(result.z) >= this._radii.z - buffer) { - return undefined; - } + /** + * Shortcut for .then(function() { return value; }) + * @param {*} value + * @returns {Promise} a promise that: + * - is fulfilled if value is not a promise, or + * - if value is a promise, will fulfill with its value, or reject + * with its reason. + */ + yield: function(value) { + return this.then(function() { + return value; + }); + }, - return result; - }; + /** + * Assumes that this promise will fulfill with an array, and arranges + * for the onFulfilled to be called with the array as its argument list + * i.e. onFulfilled.spread(undefined, array). + * @param {function} onFulfilled function to receive spread arguments + * @returns {Promise} + */ + spread: function(onFulfilled) { + return this.then(function(array) { + // array may contain promises, so resolve its contents. + return all(array, function(array) { + return onFulfilled.apply(undef, array); + }); + }); + } + }; - return Ellipsoid; -}); + /** + * Create an already-resolved promise for the supplied value + * @private + * + * @param {*} value + * @returns {Promise} fulfilled promise + */ + function fulfilled(value) { + var p = new Promise(function(onFulfilled) { + // TODO: Promises/A+ check typeof onFulfilled + try { + return resolve(onFulfilled ? onFulfilled(value) : value); + } catch(e) { + return rejected(e); + } + }); -define('Core/Rectangle',[ - './Cartographic', - './Check', - './defaultValue', - './defined', - './defineProperties', - './Ellipsoid', - './freezeObject', - './Math' - ], function( - Cartographic, - Check, - defaultValue, - defined, - defineProperties, - Ellipsoid, - freezeObject, - CesiumMath) { - 'use strict'; + return p; + } - /** - * A two dimensional region specified as longitude and latitude coordinates. - * - * @alias Rectangle - * @constructor - * - * @param {Number} [west=0.0] The westernmost longitude, in radians, in the range [-Pi, Pi]. - * @param {Number} [south=0.0] The southernmost latitude, in radians, in the range [-Pi/2, Pi/2]. - * @param {Number} [east=0.0] The easternmost longitude, in radians, in the range [-Pi, Pi]. - * @param {Number} [north=0.0] The northernmost latitude, in radians, in the range [-Pi/2, Pi/2]. - * - * @see Packable - */ - function Rectangle(west, south, east, north) { - /** - * The westernmost longitude in radians in the range [-Pi, Pi]. - * - * @type {Number} - * @default 0.0 - */ - this.west = defaultValue(west, 0.0); + /** + * Create an already-rejected {@link Promise} with the supplied + * rejection reason. + * @private + * + * @param {*} reason + * @returns {Promise} rejected promise + */ + function rejected(reason) { + var p = new Promise(function(_, onRejected) { + // TODO: Promises/A+ check typeof onRejected + try { + return onRejected ? resolve(onRejected(reason)) : rejected(reason); + } catch(e) { + return rejected(e); + } + }); - /** - * The southernmost latitude in radians in the range [-Pi/2, Pi/2]. - * - * @type {Number} - * @default 0.0 - */ - this.south = defaultValue(south, 0.0); + return p; + } - /** - * The easternmost longitude in radians in the range [-Pi, Pi]. - * - * @type {Number} - * @default 0.0 - */ - this.east = defaultValue(east, 0.0); + /** + * Creates a new, Deferred with fully isolated resolver and promise parts, + * either or both of which may be given out safely to consumers. + * The Deferred itself has the full API: resolve, reject, progress, and + * then. The resolver has resolve, reject, and progress. The promise + * only has then. + * + * @returns {Deferred} + */ + function defer() { + var deferred, promise, handlers, progressHandlers, + _then, _progress, _resolve; - /** - * The northernmost latitude in radians in the range [-Pi/2, Pi/2]. - * - * @type {Number} - * @default 0.0 - */ - this.north = defaultValue(north, 0.0); - } + /** + * The promise for the new deferred + * @type {Promise} + */ + promise = new Promise(then); - defineProperties(Rectangle.prototype, { - /** - * Gets the width of the rectangle in radians. - * @memberof Rectangle.prototype - * @type {Number} - */ - width : { - get : function() { - return Rectangle.computeWidth(this); - } - }, + /** + * The full Deferred object, with {@link Promise} and {@link Resolver} parts + * @class Deferred + * @name Deferred + */ + deferred = { + then: then, // DEPRECATED: use deferred.promise.then + resolve: promiseResolve, + reject: promiseReject, + // TODO: Consider renaming progress() to notify() + progress: promiseProgress, - /** - * Gets the height of the rectangle in radians. - * @memberof Rectangle.prototype - * @type {Number} - */ - height : { - get : function() { - return Rectangle.computeHeight(this); - } - } - }); + promise: promise, - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - Rectangle.packedLength = 4; + resolver: { + resolve: promiseResolve, + reject: promiseReject, + progress: promiseProgress + } + }; - /** - * Stores the provided instance into the provided array. - * - * @param {Rectangle} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - Rectangle.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + handlers = []; + progressHandlers = []; - array[startingIndex++] = value.west; - array[startingIndex++] = value.south; - array[startingIndex++] = value.east; - array[startingIndex] = value.north; + /** + * Pre-resolution then() that adds the supplied callback, errback, and progback + * functions to the registered listeners + * @private + * + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + */ + _then = function(onFulfilled, onRejected, onProgress) { + // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress + var deferred, progressHandler; - return array; - }; + deferred = defer(); - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Rectangle} [result] The object into which to store the result. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if one was not provided. - */ - Rectangle.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + progressHandler = typeof onProgress === 'function' + ? function(update) { + try { + // Allow progress handler to transform progress event + deferred.progress(onProgress(update)); + } catch(e) { + // Use caught value as progress + deferred.progress(e); + } + } + : function(update) { deferred.progress(update); }; - if (!defined(result)) { - result = new Rectangle(); - } + handlers.push(function(promise) { + promise.then(onFulfilled, onRejected) + .then(deferred.resolve, deferred.reject, progressHandler); + }); - result.west = array[startingIndex++]; - result.south = array[startingIndex++]; - result.east = array[startingIndex++]; - result.north = array[startingIndex]; - return result; - }; + progressHandlers.push(progressHandler); - /** - * Computes the width of a rectangle in radians. - * @param {Rectangle} rectangle The rectangle to compute the width of. - * @returns {Number} The width. - */ - Rectangle.computeWidth = function(rectangle) { - Check.typeOf.object('rectangle', rectangle); - var east = rectangle.east; - var west = rectangle.west; - if (east < west) { - east += CesiumMath.TWO_PI; - } - return east - west; - }; + return deferred.promise; + }; - /** - * Computes the height of a rectangle in radians. - * @param {Rectangle} rectangle The rectangle to compute the height of. - * @returns {Number} The height. - */ - Rectangle.computeHeight = function(rectangle) { - Check.typeOf.object('rectangle', rectangle); - return rectangle.north - rectangle.south; - }; + /** + * Issue a progress event, notifying all progress listeners + * @private + * @param {*} update progress event payload to pass to all listeners + */ + _progress = function(update) { + processQueue(progressHandlers, update); + return update; + }; - /** - * Creates a rectangle given the boundary longitude and latitude in degrees. - * - * @param {Number} [west=0.0] The westernmost longitude in degrees in the range [-180.0, 180.0]. - * @param {Number} [south=0.0] The southernmost latitude in degrees in the range [-90.0, 90.0]. - * @param {Number} [east=0.0] The easternmost longitude in degrees in the range [-180.0, 180.0]. - * @param {Number} [north=0.0] The northernmost latitude in degrees in the range [-90.0, 90.0]. - * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. - * - * @example - * var rectangle = Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0); - */ - Rectangle.fromDegrees = function(west, south, east, north, result) { - west = CesiumMath.toRadians(defaultValue(west, 0.0)); - south = CesiumMath.toRadians(defaultValue(south, 0.0)); - east = CesiumMath.toRadians(defaultValue(east, 0.0)); - north = CesiumMath.toRadians(defaultValue(north, 0.0)); + /** + * Transition from pre-resolution state to post-resolution state, notifying + * all listeners of the resolution or rejection + * @private + * @param {*} value the value of this deferred + */ + _resolve = function(value) { + value = resolve(value); - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } + // Replace _then with one that directly notifies with the result. + _then = value.then; + // Replace _resolve so that this Deferred can only be resolved once + _resolve = resolve; + // Make _progress a noop, to disallow progress for the resolved promise. + _progress = noop; - result.west = west; - result.south = south; - result.east = east; - result.north = north; + // Notify handlers + processQueue(handlers, value); - return result; - }; + // Free progressHandlers array since we'll never issue progress events + progressHandlers = handlers = undef; - /** - * Creates a rectangle given the boundary longitude and latitude in radians. - * - * @param {Number} [west=0.0] The westernmost longitude in radians in the range [-Math.PI, Math.PI]. - * @param {Number} [south=0.0] The southernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. - * @param {Number} [east=0.0] The easternmost longitude in radians in the range [-Math.PI, Math.PI]. - * @param {Number} [north=0.0] The northernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. - * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. - * - * @example - * var rectangle = Cesium.Rectangle.fromRadians(0.0, Math.PI/4, Math.PI/8, 3*Math.PI/4); - */ - Rectangle.fromRadians = function(west, south, east, north, result) { - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } + return value; + }; - result.west = defaultValue(west, 0.0); - result.south = defaultValue(south, 0.0); - result.east = defaultValue(east, 0.0); - result.north = defaultValue(north, 0.0); + return deferred; - return result; - }; + /** + * Wrapper to allow _then to be replaced safely + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} new promise + */ + function then(onFulfilled, onRejected, onProgress) { + // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress + return _then(onFulfilled, onRejected, onProgress); + } - /** - * Creates the smallest possible Rectangle that encloses all positions in the provided array. - * - * @param {Cartographic[]} cartographics The list of Cartographic instances. - * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. - */ - Rectangle.fromCartographicArray = function(cartographics, result) { - Check.defined('cartographics', cartographics); - - var west = Number.MAX_VALUE; - var east = -Number.MAX_VALUE; - var westOverIDL = Number.MAX_VALUE; - var eastOverIDL = -Number.MAX_VALUE; - var south = Number.MAX_VALUE; - var north = -Number.MAX_VALUE; + /** + * Wrapper to allow _resolve to be replaced + */ + function promiseResolve(val) { + return _resolve(val); + } - for ( var i = 0, len = cartographics.length; i < len; i++) { - var position = cartographics[i]; - west = Math.min(west, position.longitude); - east = Math.max(east, position.longitude); - south = Math.min(south, position.latitude); - north = Math.max(north, position.latitude); + /** + * Wrapper to allow _reject to be replaced + */ + function promiseReject(err) { + return _resolve(rejected(err)); + } - var lonAdjusted = position.longitude >= 0 ? position.longitude : position.longitude + CesiumMath.TWO_PI; - westOverIDL = Math.min(westOverIDL, lonAdjusted); - eastOverIDL = Math.max(eastOverIDL, lonAdjusted); - } + /** + * Wrapper to allow _progress to be replaced + */ + function promiseProgress(update) { + return _progress(update); + } + } - if(east - west > eastOverIDL - westOverIDL) { - west = westOverIDL; - east = eastOverIDL; + /** + * Determines if promiseOrValue is a promise or not. Uses the feature + * test from http://wiki.commonjs.org/wiki/Promises/A to determine if + * promiseOrValue is a promise. + * + * @param {*} promiseOrValue anything + * @returns {boolean} true if promiseOrValue is a {@link Promise} + */ + function isPromise(promiseOrValue) { + return promiseOrValue && typeof promiseOrValue.then === 'function'; + } - if (east > CesiumMath.PI) { - east = east - CesiumMath.TWO_PI; - } - if (west > CesiumMath.PI) { - west = west - CesiumMath.TWO_PI; - } - } + /** + * Initiates a competitive race, returning a promise that will resolve when + * howMany of the supplied promisesOrValues have resolved, or will reject when + * it becomes impossible for howMany to resolve, for example, when + * (promisesOrValues.length - howMany) + 1 input promises reject. + * + * @param {Array} promisesOrValues array of anything, may contain a mix + * of promises and values + * @param howMany {number} number of promisesOrValues to resolve + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} promise that will resolve to an array of howMany values that + * resolved first, or will reject with an array of (promisesOrValues.length - howMany) + 1 + * rejection reasons. + */ + function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) { - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } + checkCallbacks(2, arguments); - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; - }; + return when(promisesOrValues, function(promisesOrValues) { - /** - * Creates the smallest possible Rectangle that encloses all positions in the provided array. - * - * @param {Cartesian3[]} cartesians The list of Cartesian instances. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid the cartesians are on. - * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. - */ - Rectangle.fromCartesianArray = function(cartesians, ellipsoid, result) { - Check.defined('cartesians', cartesians); - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + var toResolve, toReject, values, reasons, deferred, fulfillOne, rejectOne, progress, len, i; - var west = Number.MAX_VALUE; - var east = -Number.MAX_VALUE; - var westOverIDL = Number.MAX_VALUE; - var eastOverIDL = -Number.MAX_VALUE; - var south = Number.MAX_VALUE; - var north = -Number.MAX_VALUE; + len = promisesOrValues.length >>> 0; - for ( var i = 0, len = cartesians.length; i < len; i++) { - var position = ellipsoid.cartesianToCartographic(cartesians[i]); - west = Math.min(west, position.longitude); - east = Math.max(east, position.longitude); - south = Math.min(south, position.latitude); - north = Math.max(north, position.latitude); + toResolve = Math.max(0, Math.min(howMany, len)); + values = []; - var lonAdjusted = position.longitude >= 0 ? position.longitude : position.longitude + CesiumMath.TWO_PI; - westOverIDL = Math.min(westOverIDL, lonAdjusted); - eastOverIDL = Math.max(eastOverIDL, lonAdjusted); - } + toReject = (len - toResolve) + 1; + reasons = []; - if(east - west > eastOverIDL - westOverIDL) { - west = westOverIDL; - east = eastOverIDL; + deferred = defer(); - if (east > CesiumMath.PI) { - east = east - CesiumMath.TWO_PI; - } - if (west > CesiumMath.PI) { - west = west - CesiumMath.TWO_PI; - } - } + // No items in the input, resolve immediately + if (!toResolve) { + deferred.resolve(values); - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } + } else { + progress = deferred.progress; - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; - }; + rejectOne = function(reason) { + reasons.push(reason); + if(!--toReject) { + fulfillOne = rejectOne = noop; + deferred.reject(reasons); + } + }; - /** - * Duplicates a Rectangle. - * - * @param {Rectangle} rectangle The rectangle to clone. - * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. (Returns undefined if rectangle is undefined) - */ - Rectangle.clone = function(rectangle, result) { - if (!defined(rectangle)) { - return undefined; - } + fulfillOne = function(val) { + // This orders the values based on promise resolution order + // Another strategy would be to use the original position of + // the corresponding promise. + values.push(val); - if (!defined(result)) { - return new Rectangle(rectangle.west, rectangle.south, rectangle.east, rectangle.north); - } + if (!--toResolve) { + fulfillOne = rejectOne = noop; + deferred.resolve(values); + } + }; - result.west = rectangle.west; - result.south = rectangle.south; - result.east = rectangle.east; - result.north = rectangle.north; - return result; - }; + for(i = 0; i < len; ++i) { + if(i in promisesOrValues) { + when(promisesOrValues[i], fulfiller, rejecter, progress); + } + } + } - /** - * Duplicates this Rectangle. - * - * @param {Rectangle} [result] The object onto which to store the result. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. - */ - Rectangle.prototype.clone = function(result) { - return Rectangle.clone(this, result); - }; + return deferred.then(onFulfilled, onRejected, onProgress); - /** - * Compares the provided Rectangle with this Rectangle componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Rectangle} [other] The Rectangle to compare. - * @returns {Boolean} <code>true</code> if the Rectangles are equal, <code>false</code> otherwise. - */ - Rectangle.prototype.equals = function(other) { - return Rectangle.equals(this, other); - }; + function rejecter(reason) { + rejectOne(reason); + } - /** - * Compares the provided rectangles and returns <code>true</code> if they are equal, - * <code>false</code> otherwise. - * - * @param {Rectangle} [left] The first Rectangle. - * @param {Rectangle} [right] The second Rectangle. - * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. - */ - Rectangle.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.west === right.west) && - (left.south === right.south) && - (left.east === right.east) && - (left.north === right.north)); - }; + function fulfiller(val) { + fulfillOne(val); + } - /** - * Compares the provided Rectangle with this Rectangle componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {Rectangle} [other] The Rectangle to compare. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if the Rectangles are within the provided epsilon, <code>false</code> otherwise. - */ - Rectangle.prototype.equalsEpsilon = function(other, epsilon) { - Check.typeOf.number('epsilon', epsilon); - - return defined(other) && - (Math.abs(this.west - other.west) <= epsilon) && - (Math.abs(this.south - other.south) <= epsilon) && - (Math.abs(this.east - other.east) <= epsilon) && - (Math.abs(this.north - other.north) <= epsilon); - }; + }); + } - /** - * Checks a Rectangle's properties and throws if they are not in valid ranges. - * - * @param {Rectangle} rectangle The rectangle to validate - * - * @exception {DeveloperError} <code>north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. - * @exception {DeveloperError} <code>south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. - * @exception {DeveloperError} <code>east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. - * @exception {DeveloperError} <code>west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. - */ - Rectangle.validate = function(rectangle) { - Check.typeOf.object('rectangle', rectangle); + /** + * Initiates a competitive race, returning a promise that will resolve when + * any one of the supplied promisesOrValues has resolved or will reject when + * *all* promisesOrValues have rejected. + * + * @param {Array|Promise} promisesOrValues array of anything, may contain a mix + * of {@link Promise}s and values + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} promise that will resolve to the value that resolved first, or + * will reject with an array of all rejected inputs. + */ + function any(promisesOrValues, onFulfilled, onRejected, onProgress) { - var north = rectangle.north; - Check.typeOf.number.greaterThanOrEquals('north', north, -CesiumMath.PI_OVER_TWO); - Check.typeOf.number.lessThanOrEquals('north', north, CesiumMath.PI_OVER_TWO); + function unwrapSingleResult(val) { + return onFulfilled ? onFulfilled(val[0]) : val[0]; + } - var south = rectangle.south; - Check.typeOf.number.greaterThanOrEquals('south', south, -CesiumMath.PI_OVER_TWO); - Check.typeOf.number.lessThanOrEquals('south', south, CesiumMath.PI_OVER_TWO); + return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress); + } - var west = rectangle.west; - Check.typeOf.number.greaterThanOrEquals('west', west, -Math.PI); - Check.typeOf.number.lessThanOrEquals('west', west, Math.PI); + /** + * Return a promise that will resolve only once all the supplied promisesOrValues + * have resolved. The resolution value of the returned promise will be an array + * containing the resolution values of each of the promisesOrValues. + * @memberOf when + * + * @param {Array|Promise} promisesOrValues array of anything, may contain a mix + * of {@link Promise}s and values + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} + */ + function all(promisesOrValues, onFulfilled, onRejected, onProgress) { + checkCallbacks(1, arguments); + return map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); + } - var east = rectangle.east; - Check.typeOf.number.greaterThanOrEquals('east', east, -Math.PI); - Check.typeOf.number.lessThanOrEquals('east', east, Math.PI); - }; + /** + * Joins multiple promises into a single returned promise. + * @returns {Promise} a promise that will fulfill when *all* the input promises + * have fulfilled, or will reject when *any one* of the input promises rejects. + */ + function join(/* ...promises */) { + return map(arguments, identity); + } - /** - * Computes the southwest corner of a rectangle. - * - * @param {Rectangle} rectangle The rectangle for which to find the corner - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. - */ - Rectangle.southwest = function(rectangle, result) { - Check.typeOf.object('rectangle', rectangle); - - if (!defined(result)) { - return new Cartographic(rectangle.west, rectangle.south); - } - result.longitude = rectangle.west; - result.latitude = rectangle.south; - result.height = 0.0; - return result; - }; + /** + * Traditional map function, similar to `Array.prototype.map()`, but allows + * input to contain {@link Promise}s and/or values, and mapFunc may return + * either a value or a {@link Promise} + * + * @param {Array|Promise} promise array of anything, may contain a mix + * of {@link Promise}s and values + * @param {function} mapFunc mapping function mapFunc(value) which may return + * either a {@link Promise} or value + * @returns {Promise} a {@link Promise} that will resolve to an array containing + * the mapped output values. + */ + function map(promise, mapFunc) { + return when(promise, function(array) { + var results, len, toResolve, resolve, i, d; - /** - * Computes the northwest corner of a rectangle. - * - * @param {Rectangle} rectangle The rectangle for which to find the corner - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. - */ - Rectangle.northwest = function(rectangle, result) { - Check.typeOf.object('rectangle', rectangle); - - if (!defined(result)) { - return new Cartographic(rectangle.west, rectangle.north); - } - result.longitude = rectangle.west; - result.latitude = rectangle.north; - result.height = 0.0; - return result; - }; + // Since we know the resulting length, we can preallocate the results + // array to avoid array expansions. + toResolve = len = array.length >>> 0; + results = []; + d = defer(); - /** - * Computes the northeast corner of a rectangle. - * - * @param {Rectangle} rectangle The rectangle for which to find the corner - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. - */ - Rectangle.northeast = function(rectangle, result) { - Check.typeOf.object('rectangle', rectangle); - - if (!defined(result)) { - return new Cartographic(rectangle.east, rectangle.north); - } - result.longitude = rectangle.east; - result.latitude = rectangle.north; - result.height = 0.0; - return result; - }; + if(!toResolve) { + d.resolve(results); + } else { - /** - * Computes the southeast corner of a rectangle. - * - * @param {Rectangle} rectangle The rectangle for which to find the corner - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. - */ - Rectangle.southeast = function(rectangle, result) { - Check.typeOf.object('rectangle', rectangle); - - if (!defined(result)) { - return new Cartographic(rectangle.east, rectangle.south); - } - result.longitude = rectangle.east; - result.latitude = rectangle.south; - result.height = 0.0; - return result; - }; + resolve = function resolveOne(item, i) { + when(item, mapFunc).then(function(mapped) { + results[i] = mapped; - /** - * Computes the center of a rectangle. - * - * @param {Rectangle} rectangle The rectangle for which to find the center - * @param {Cartographic} [result] The object onto which to store the result. - * @returns {Cartographic} The modified result parameter or a new Cartographic instance if none was provided. - */ - Rectangle.center = function(rectangle, result) { - Check.typeOf.object('rectangle', rectangle); - - var east = rectangle.east; - var west = rectangle.west; + if(!--toResolve) { + d.resolve(results); + } + }, d.reject); + }; - if (east < west) { - east += CesiumMath.TWO_PI; - } + // Since mapFunc may be async, get all invocations of it into flight + for(i = 0; i < len; i++) { + if(i in array) { + resolve(array[i], i); + } else { + --toResolve; + } + } - var longitude = CesiumMath.negativePiToPi((west + east) * 0.5); - var latitude = (rectangle.south + rectangle.north) * 0.5; + } - if (!defined(result)) { - return new Cartographic(longitude, latitude); - } + return d.promise; - result.longitude = longitude; - result.latitude = latitude; - result.height = 0.0; - return result; - }; + }); + } - /** - * Computes the intersection of two rectangles. This function assumes that the rectangle's coordinates are - * latitude and longitude in radians and produces a correct intersection, taking into account the fact that - * the same angle can be represented with multiple values as well as the wrapping of longitude at the - * anti-meridian. For a simple intersection that ignores these factors and can be used with projected - * coordinates, see {@link Rectangle.simpleIntersection}. - * - * @param {Rectangle} rectangle On rectangle to find an intersection - * @param {Rectangle} otherRectangle Another rectangle to find an intersection - * @param {Rectangle} [result] The object onto which to store the result. - * @returns {Rectangle|undefined} The modified result parameter, a new Rectangle instance if none was provided or undefined if there is no intersection. - */ - Rectangle.intersection = function(rectangle, otherRectangle, result) { - Check.typeOf.object('rectangle', rectangle); - Check.typeOf.object('otherRectangle', otherRectangle); - - var rectangleEast = rectangle.east; - var rectangleWest = rectangle.west; + /** + * Traditional reduce function, similar to `Array.prototype.reduce()`, but + * input may contain promises and/or values, and reduceFunc + * may return either a value or a promise, *and* initialValue may + * be a promise for the starting value. + * + * @param {Array|Promise} promise array or promise for an array of anything, + * may contain a mix of promises and values. + * @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total), + * where total is the total number of items being reduced, and will be the same + * in each call to reduceFunc. + * @returns {Promise} that will resolve to the final reduced value + */ + function reduce(promise, reduceFunc /*, initialValue */) { + var args = slice.call(arguments, 1); - var otherRectangleEast = otherRectangle.east; - var otherRectangleWest = otherRectangle.west; + return when(promise, function(array) { + var total; - if (rectangleEast < rectangleWest && otherRectangleEast > 0.0) { - rectangleEast += CesiumMath.TWO_PI; - } else if (otherRectangleEast < otherRectangleWest && rectangleEast > 0.0) { - otherRectangleEast += CesiumMath.TWO_PI; - } + total = array.length; - if (rectangleEast < rectangleWest && otherRectangleWest < 0.0) { - otherRectangleWest += CesiumMath.TWO_PI; - } else if (otherRectangleEast < otherRectangleWest && rectangleWest < 0.0) { - rectangleWest += CesiumMath.TWO_PI; - } + // Wrap the supplied reduceFunc with one that handles promises and then + // delegates to the supplied. + args[0] = function (current, val, i) { + return when(current, function (c) { + return when(val, function (value) { + return reduceFunc(c, value, i, total); + }); + }); + }; - var west = CesiumMath.negativePiToPi(Math.max(rectangleWest, otherRectangleWest)); - var east = CesiumMath.negativePiToPi(Math.min(rectangleEast, otherRectangleEast)); + return reduceArray.apply(array, args); + }); + } - if ((rectangle.west < rectangle.east || otherRectangle.west < otherRectangle.east) && east <= west) { - return undefined; - } + /** + * Ensure that resolution of promiseOrValue will trigger resolver with the + * value or reason of promiseOrValue, or instead with resolveValue if it is provided. + * + * @param promiseOrValue + * @param {Object} resolver + * @param {function} resolver.resolve + * @param {function} resolver.reject + * @param {*} [resolveValue] + * @returns {Promise} + */ + function chain(promiseOrValue, resolver, resolveValue) { + var useResolveValue = arguments.length > 2; - var south = Math.max(rectangle.south, otherRectangle.south); - var north = Math.min(rectangle.north, otherRectangle.north); + return when(promiseOrValue, + function(val) { + val = useResolveValue ? resolveValue : val; + resolver.resolve(val); + return val; + }, + function(reason) { + resolver.reject(reason); + return rejected(reason); + }, + resolver.progress + ); + } - if (south >= north) { - return undefined; - } + // + // Utility functions + // - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; - }; + /** + * Apply all functions in queue to value + * @param {Array} queue array of functions to execute + * @param {*} value argument passed to each function + */ + function processQueue(queue, value) { + var handler, i = 0; - /** - * Computes a simple intersection of two rectangles. Unlike {@link Rectangle.intersection}, this function - * does not attempt to put the angular coordinates into a consistent range or to account for crossing the - * anti-meridian. As such, it can be used for rectangles where the coordinates are not simply latitude - * and longitude (i.e. projected coordinates). - * - * @param {Rectangle} rectangle On rectangle to find an intersection - * @param {Rectangle} otherRectangle Another rectangle to find an intersection - * @param {Rectangle} [result] The object onto which to store the result. - * @returns {Rectangle|undefined} The modified result parameter, a new Rectangle instance if none was provided or undefined if there is no intersection. - */ - Rectangle.simpleIntersection = function(rectangle, otherRectangle, result) { - Check.typeOf.object('rectangle', rectangle); - Check.typeOf.object('otherRectangle', otherRectangle); - - var west = Math.max(rectangle.west, otherRectangle.west); - var south = Math.max(rectangle.south, otherRectangle.south); - var east = Math.min(rectangle.east, otherRectangle.east); - var north = Math.min(rectangle.north, otherRectangle.north); + while (handler = queue[i++]) { + handler(value); + } + } - if (south >= north || west >= east) { - return undefined; - } + /** + * Helper that checks arrayOfCallbacks to ensure that each element is either + * a function, or null or undefined. + * @private + * @param {number} start index at which to start checking items in arrayOfCallbacks + * @param {Array} arrayOfCallbacks array to check + * @throws {Error} if any element of arrayOfCallbacks is something other than + * a functions, null, or undefined. + */ + function checkCallbacks(start, arrayOfCallbacks) { + // TODO: Promises/A+ update type checking and docs + var arg, i = arrayOfCallbacks.length; - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } + while(i > start) { + arg = arrayOfCallbacks[--i]; - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; - }; + if (arg != null && typeof arg != 'function') { + throw new Error('arg '+i+' must be a function'); + } + } + } - /** - * Computes a rectangle that is the union of two rectangles. - * - * @param {Rectangle} rectangle A rectangle to enclose in rectangle. - * @param {Rectangle} otherRectangle A rectangle to enclose in a rectangle. - * @param {Rectangle} [result] The object onto which to store the result. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. - */ - Rectangle.union = function(rectangle, otherRectangle, result) { - Check.typeOf.object('rectangle', rectangle); - Check.typeOf.object('otherRectangle', otherRectangle); - - if (!defined(result)) { - result = new Rectangle(); - } + /** + * No-Op function used in method replacement + * @private + */ + function noop() {} - var rectangleEast = rectangle.east; - var rectangleWest = rectangle.west; + slice = [].slice; - var otherRectangleEast = otherRectangle.east; - var otherRectangleWest = otherRectangle.west; + // ES5 reduce implementation if native not available + // See: http://es5.github.com/#x15.4.4.21 as there are many + // specifics and edge cases. + reduceArray = [].reduce || + function(reduceFunc /*, initialValue */) { + /*jshint maxcomplexity: 7*/ - if (rectangleEast < rectangleWest && otherRectangleEast > 0.0) { - rectangleEast += CesiumMath.TWO_PI; - } else if (otherRectangleEast < otherRectangleWest && rectangleEast > 0.0) { - otherRectangleEast += CesiumMath.TWO_PI; - } + // ES5 dictates that reduce.length === 1 - if (rectangleEast < rectangleWest && otherRectangleWest < 0.0) { - otherRectangleWest += CesiumMath.TWO_PI; - } else if (otherRectangleEast < otherRectangleWest && rectangleWest < 0.0) { - rectangleWest += CesiumMath.TWO_PI; - } + // This implementation deviates from ES5 spec in the following ways: + // 1. It does not check if reduceFunc is a Callable - var west = CesiumMath.convertLongitudeRange(Math.min(rectangleWest, otherRectangleWest)); - var east = CesiumMath.convertLongitudeRange(Math.max(rectangleEast, otherRectangleEast)); + var arr, args, reduced, len, i; - result.west = west; - result.south = Math.min(rectangle.south, otherRectangle.south); - result.east = east; - result.north = Math.max(rectangle.north, otherRectangle.north); + i = 0; + // This generates a jshint warning, despite being valid + // "Missing 'new' prefix when invoking a constructor." + // See https://github.com/jshint/jshint/issues/392 + arr = Object(this); + len = arr.length >>> 0; + args = arguments; - return result; - }; + // If no initialValue, use first item of array (we know length !== 0 here) + // and adjust i to start at second item + if(args.length <= 1) { + // Skip to the first real element in the array + for(;;) { + if(i in arr) { + reduced = arr[i++]; + break; + } + + // If we reached the end of the array without finding any real + // elements, it's a TypeError + if(++i >= len) { + throw new TypeError(); + } + } + } else { + // If initialValue provided, use it + reduced = args[1]; + } + + // Do the actual reduce + for(;i < len; ++i) { + // Skip holes + if(i in arr) { + reduced = reduceFunc(reduced, arr[i], i, arr); + } + } + + return reduced; + }; + + function identity(x) { + return x; + } + + return when; +}); +})(typeof define == 'function' && define.amd + ? define + : function (factory) { typeof exports === 'object' + ? (module.exports = factory()) + : (this.when = factory()); + } + // Boilerplate for AMD, Node, and browser global +); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; /** - * Computes a rectangle by enlarging the provided rectangle until it contains the provided cartographic. + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. * - * @param {Rectangle} rectangle A rectangle to expand. - * @param {Cartographic} cartographic A cartographic to enclose in a rectangle. - * @param {Rectangle} [result] The object onto which to store the result. - * @returns {Rectangle} The modified result parameter or a new Rectangle instance if one was not provided. + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); */ - Rectangle.expand = function(rectangle, cartographic, result) { - Check.typeOf.object('rectangle', rectangle); - Check.typeOf.object('cartographic', cartographic); - - if (!defined(result)) { - result = new Rectangle(); - } - - result.west = Math.min(rectangle.west, cartographic.longitude); - result.south = Math.min(rectangle.south, cartographic.latitude); - result.east = Math.max(rectangle.east, cartographic.longitude); - result.north = Math.max(rectangle.north, cartographic.latitude); + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } - return result; - }; + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); /** - * Returns true if the cartographic is on or inside the rectangle, false otherwise. + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. * - * @param {Rectangle} rectangle The rectangle - * @param {Cartographic} cartographic The cartographic to test. - * @returns {Boolean} true if the provided cartographic is inside the rectangle, false otherwise. + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener */ - Rectangle.contains = function(rectangle, cartographic) { - Check.typeOf.object('rectangle', rectangle); - Check.typeOf.object('cartographic', cartographic); + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); - var longitude = cartographic.longitude; - var latitude = cartographic.latitude; - - var west = rectangle.west; - var east = rectangle.east; + this._listeners.push(listener); + this._scopes.push(scope); - if (east < west) { - east += CesiumMath.TWO_PI; - if (longitude < 0.0) { - longitude += CesiumMath.TWO_PI; - } - } - return (longitude > west || CesiumMath.equalsEpsilon(longitude, west, CesiumMath.EPSILON14)) && - (longitude < east || CesiumMath.equalsEpsilon(longitude, east, CesiumMath.EPSILON14)) && - latitude >= rectangle.south && - latitude <= rectangle.north; + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; }; - var subsampleLlaScratch = new Cartographic(); /** - * Samples a rectangle so that it includes a list of Cartesian points suitable for passing to - * {@link BoundingSphere#fromPoints}. Sampling is necessary to account - * for rectangles that cover the poles or cross the equator. + * Unregisters a previously registered callback. * - * @param {Rectangle} rectangle The rectangle to subsample. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use. - * @param {Number} [surfaceHeight=0.0] The height of the rectangle above the ellipsoid. - * @param {Cartesian3[]} [result] The array of Cartesians onto which to store the result. - * @returns {Cartesian3[]} The modified result parameter or a new Array of Cartesians instances if none was provided. + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent */ - Rectangle.subsample = function(rectangle, ellipsoid, surfaceHeight, result) { - Check.typeOf.object('rectangle', rectangle); + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - surfaceHeight = defaultValue(surfaceHeight, 0.0); + var listeners = this._listeners; + var scopes = this._scopes; - if (!defined(result)) { - result = []; + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } } - var length = 0; - - var north = rectangle.north; - var south = rectangle.south; - var east = rectangle.east; - var west = rectangle.west; - var lla = subsampleLlaScratch; - lla.height = surfaceHeight; + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } - lla.longitude = west; - lla.latitude = north; - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; + return false; + }; - lla.longitude = east; - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; + function compareNumber(a,b) { + return b - a; + } - lla.latitude = south; - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; - lla.longitude = west; - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; - if (north < 0.0) { - lla.latitude = north; - } else if (south > 0.0) { - lla.latitude = south; - } else { - lla.latitude = 0.0; + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } } - for ( var i = 1; i < 8; ++i) { - lla.longitude = -Math.PI + i * CesiumMath.PI_OVER_TWO; - if (Rectangle.contains(rectangle, lla)) { - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); } + toRemove.length = 0; } - if (lla.latitude === 0.0) { - lla.longitude = west; - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; - lla.longitude = east; - result[length] = ellipsoid.cartographicToCartesian(lla, result[length]); - length++; - } - result.length = length; - return result; + this._insideRaiseEvent = false; }; /** - * The largest possible rectangle. - * - * @type {Rectangle} - * @constant - */ - Rectangle.MAX_VALUE = freezeObject(new Rectangle(-Math.PI, -CesiumMath.PI_OVER_TWO, Math.PI, CesiumMath.PI_OVER_TWO)); + * A function that removes a listener. + * @callback Event~RemoveCallback + */ - return Rectangle; + return Event; }); -define('Core/BingMapsGeocoderService',[ - './BingMapsApi', +define('Core/Heap',[ './Check', './defaultValue', './defined', - './defineProperties', - './loadJsonp', - './Rectangle' + './defineProperties' ], function( - BingMapsApi, Check, defaultValue, defined, - defineProperties, - loadJsonp, - Rectangle) { + defineProperties) { 'use strict'; - var url = 'https://dev.virtualearth.net/REST/v1/Locations'; - /** - * Provides geocoding through Bing Maps. - * @alias BingMapsGeocoderService + * Array implementation of a heap. + * + * @alias Heap * @constructor + * @private * * @param {Object} options Object with the following properties: - * @param {Scene} options.scene The scene - * @param {String} [options.key] A key to use with the Bing Maps geocoding service + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. */ - function BingMapsGeocoderService(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - Check.typeOf.object('options.scene', options.scene); + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); - var key = options.key; - this._key = BingMapsApi.getKey(key); - - if (defined(key)) { - var errorCredit = BingMapsApi.getErrorCredit(key); - if (defined(errorCredit)) { - options.scene._frameState.creditDisplay.addDefaultCredit(errorCredit); - } - } + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; } - defineProperties(BingMapsGeocoderService.prototype, { + defineProperties(Heap.prototype, { /** - * The URL endpoint for the Bing geocoder service - * @type {String} - * @memberof {BingMapsGeocoderService.prototype} + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} * @readonly */ - url : { - get : function () { - return url; + length : { + get : function() { + return this._length; } }, /** - * The key for the Bing geocoder service - * @type {String} - * @memberof {BingMapsGeocoderService.prototype} + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} * @readonly */ - key : { - get : function () { - return this._key; + internalArray : { + get : function() { + return this._array; } - } - }); + }, - /** - * @function - * - * @param {String} query The query to be sent to the geocoder service - * @returns {Promise<GeocoderResult[]>} - */ - BingMapsGeocoderService.prototype.geocode = function(query) { - Check.typeOf.string('query', query); - - var key = this.key; - var promise = loadJsonp(url, { - parameters : { - query : query, - key : key + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; }, - callbackParameterName : 'jsonp' - }); - - return promise.then(function(result) { - if (result.resourceSets.length === 0) { - return []; + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } } + }, - var results = result.resourceSets[0].resources; - - return results.map(function (resource) { - var bbox = resource.bbox; - var south = bbox[0]; - var west = bbox[1]; - var north = bbox[2]; - var east = bbox[3]; - return { - displayName: resource.name, - destination: Rectangle.fromDegrees(west, south, east, north) - }; - }); - }); - }; - - return BingMapsGeocoderService; -}); - -define('Core/GeographicProjection',[ - './Cartesian3', - './Cartographic', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid' - ], function( - Cartesian3, - Cartographic, - defaultValue, - defined, - defineProperties, - DeveloperError, - Ellipsoid) { - 'use strict'; - - /** - * A simple map projection where longitude and latitude are linearly mapped to X and Y by multiplying - * them by the {@link Ellipsoid#maximumRadius}. This projection - * is commonly known as geographic, equirectangular, equidistant cylindrical, or plate carrée. It - * is also known as EPSG:4326. - * - * @alias GeographicProjection - * @constructor - * - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid. - * - * @see WebMercatorProjection - */ - function GeographicProjection(ellipsoid) { - this._ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - this._semimajorAxis = this._ellipsoid.maximumRadius; - this._oneOverSemimajorAxis = 1.0 / this._semimajorAxis; - } - - defineProperties(GeographicProjection.prototype, { /** - * Gets the {@link Ellipsoid}. + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. * - * @memberof GeographicProjection.prototype + * @memberof Heap.prototype * - * @type {Ellipsoid} - * @readonly + * @type {Heap~ComparatorCallback} */ - ellipsoid : { + comparator : { get : function() { - return this._ellipsoid; + return this._comparator; } } }); + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + /** - * Projects a set of {@link Cartographic} coordinates, in radians, to map coordinates, in meters. - * X and Y are the longitude and latitude, respectively, multiplied by the maximum radius of the - * ellipsoid. Z is the unmodified height. + * Resizes the internal array of the heap. * - * @param {Cartographic} cartographic The coordinates to project. - * @param {Cartesian3} [result] An instance into which to copy the result. If this parameter is - * undefined, a new instance is created and returned. - * @returns {Cartesian3} The projected coordinates. If the result parameter is not undefined, the - * coordinates are copied there and that instance is returned. Otherwise, a new instance is - * created and returned. + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. */ - GeographicProjection.prototype.project = function(cartographic, result) { - // Actually this is the special case of equidistant cylindrical called the plate carree - var semimajorAxis = this._semimajorAxis; - var x = cartographic.longitude * semimajorAxis; - var y = cartographic.latitude * semimajorAxis; - var z = cartographic.height; - - if (!defined(result)) { - return new Cartesian3(x, y, z); - } - - result.x = x; - result.y = y; - result.z = z; - return result; + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; }; /** - * Unprojects a set of projected {@link Cartesian3} coordinates, in meters, to {@link Cartographic} - * coordinates, in radians. Longitude and Latitude are the X and Y coordinates, respectively, - * divided by the maximum radius of the ellipsoid. Height is the unmodified Z coordinate. + * Update the heap so that index and all descendants satisfy the heap property. * - * @param {Cartesian3} cartesian The Cartesian position to unproject with height (z) in meters. - * @param {Cartographic} [result] An instance into which to copy the result. If this parameter is - * undefined, a new instance is created and returned. - * @returns {Cartographic} The unprojected coordinates. If the result parameter is not undefined, the - * coordinates are copied there and that instance is returned. Otherwise, a new instance is - * created and returned. + * @param {Number} [index=0] The starting index to heapify from. */ - GeographicProjection.prototype.unproject = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required'); + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); - var oneOverEarthSemimajorAxis = this._oneOverSemimajorAxis; - var longitude = cartesian.x * oneOverEarthSemimajorAxis; - var latitude = cartesian.y * oneOverEarthSemimajorAxis; - var height = cartesian.z; + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; - if (!defined(result)) { - return new Cartographic(longitude, latitude, height); + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); } - result.longitude = longitude; - result.latitude = latitude; - result.height = height; - return result; + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; + + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } + + return removedElement; }; - return GeographicProjection; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/BoundingRectangle',[ - './Cartesian2', - './Cartographic', +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './GeographicProjection', - './Intersect', - './Rectangle' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( - Cartesian2, - Cartographic, + Uri, + when, Check, - defaultValue, defined, - GeographicProjection, - Intersect, - Rectangle) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * A bounding rectangle given by a corner, width and height. - * @alias BoundingRectangle - * @constructor + * Tracks the number of active requests and prioritizes incoming requests. * - * @param {Number} [x=0.0] The x coordinate of the rectangle. - * @param {Number} [y=0.0] The y coordinate of the rectangle. - * @param {Number} [width=0.0] The width of the rectangle. - * @param {Number} [height=0.0] The height of the rectangle. + * @exports RequestScheduler * - * @see BoundingSphere - * @see Packable + * @private */ - function BoundingRectangle(x, y, width, height) { - /** - * The x coordinate of the rectangle. - * @type {Number} - * @default 0.0 - */ - this.x = defaultValue(x, 0.0); - - /** - * The y coordinate of the rectangle. - * @type {Number} - * @default 0.0 - */ - this.y = defaultValue(y, 0.0); - - /** - * The width of the rectangle. - * @type {Number} - * @default 0.0 - */ - this.width = defaultValue(width, 0.0); - - /** - * The height of the rectangle. - * @type {Number} - * @default 0.0 - */ - this.height = defaultValue(height, 0.0); + function RequestScheduler() { } /** - * The number of elements used to pack the object into an array. + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. * @type {Number} + * @default 50 */ - BoundingRectangle.packedLength = 4; + RequestScheduler.maximumRequests = 50; /** - * Stores the provided instance into the provided array. - * - * @param {BoundingRectangle} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 */ - BoundingRectangle.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + RequestScheduler.maximumRequestsPerServer = 6; - array[startingIndex++] = value.x; - array[startingIndex++] = value.y; - array[startingIndex++] = value.width; - array[startingIndex] = value.height; + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; - return array; - }; + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; /** - * Retrieves an instance from a packed array. + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {BoundingRectangle} [result] The object into which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. + * @type {Event} + * @default Event() */ - BoundingRectangle.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + RequestScheduler.requestCompletedEvent = requestCompletedEvent; - if (!defined(result)) { - result = new BoundingRectangle(); + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } } - result.x = array[startingIndex++]; - result.y = array[startingIndex++]; - result.width = array[startingIndex++]; - result.height = array[startingIndex]; - return result; - }; + }); - /** - * Computes a bounding rectangle enclosing the list of 2D points. - * The rectangle is oriented with the corner at the bottom left. - * - * @param {Cartesian2[]} positions List of points that the bounding rectangle will enclose. Each point must have <code>x</code> and <code>y</code> properties. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. - */ - BoundingRectangle.fromPoints = function(positions, result) { - if (!defined(result)) { - result = new BoundingRectangle(); + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); } + } - if (!defined(positions) || positions.length === 0) { - result.x = 0; - result.y = 0; - result.width = 0; - result.height = 0; - return result; + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); } + return request.deferred.promise; + } - var length = positions.length; + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } - var minimumX = positions[0].x; - var minimumY = positions[0].y; + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } - var maximumX = positions[0].x; - var maximumY = positions[0].y; + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } - for ( var i = 1; i < length; i++) { - var p = positions[i]; - var x = p.x; - var y = p.y; + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); - minimumX = Math.min(x, minimumX); - maximumX = Math.max(x, maximumX); - minimumY = Math.min(y, minimumY); - maximumY = Math.max(y, maximumY); + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - result.x = minimumX; - result.y = minimumY; - result.width = maximumX - minimumX; - result.height = maximumY - minimumY; - return result; - }; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } + } - var defaultProjection = new GeographicProjection(); - var fromRectangleLowerLeft = new Cartographic(); - var fromRectangleUpperRight = new Cartographic(); /** - * Computes a bounding rectangle from a rectangle. - * - * @param {Rectangle} rectangle The valid rectangle used to create a bounding rectangle. - * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. + * Sort requests by priority and start requests. */ - BoundingRectangle.fromRectangle = function(rectangle, projection, result) { - if (!defined(result)) { - result = new BoundingRectangle(); + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } } + activeRequests.length -= removeCount; - if (!defined(rectangle)) { - result.x = 0; - result.y = 0; - result.width = 0; - result.height = 0; - return result; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); } + requestHeap.resort(); - projection = defaultValue(projection, defaultProjection); + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } - var lowerLeft = projection.project(Rectangle.southwest(rectangle, fromRectangleLowerLeft)); - var upperRight = projection.project(Rectangle.northeast(rectangle, fromRectangleUpperRight)); + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } - Cartesian2.subtract(upperRight, lowerLeft, upperRight); + startRequest(request); + ++filledSlots; + } - result.x = lowerLeft.x; - result.y = lowerLeft.y; - result.width = upperRight.x; - result.height = upperRight.y; - return result; + updateStatistics(); }; /** - * Duplicates a BoundingRectangle instance. + * Get the server key from a given url. * - * @param {BoundingRectangle} rectangle The bounding rectangle to duplicate. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. (Returns undefined if rectangle is undefined) + * @param {String} url The url. + * @returns {String} The server key. */ - BoundingRectangle.clone = function(rectangle, result) { - if (!defined(rectangle)) { - return undefined; + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); } - if (!defined(result)) { - return new BoundingRectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height); + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } - result.x = rectangle.x; - result.y = rectangle.y; - result.width = rectangle.width; - result.height = rectangle.height; - return result; + return serverKey; }; /** - * Computes a bounding rectangle that is the union of the left and right bounding rectangles. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {BoundingRectangle} left A rectangle to enclose in bounding rectangle. - * @param {BoundingRectangle} right A rectangle to enclose in a bounding rectangle. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - BoundingRectangle.union = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - if (!defined(result)) { - result = new BoundingRectangle(); + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); } - var lowerLeftX = Math.min(left.x, right.x); - var lowerLeftY = Math.min(left.y, right.y); - var upperRightX = Math.max(left.x + left.width, right.x + right.width); - var upperRightY = Math.max(left.y + left.height, right.y + right.height); + ++statistics.numberOfAttemptedRequests; - result.x = lowerLeftX; - result.y = lowerLeftY; - result.width = upperRightX - lowerLeftX; - result.height = upperRightY - lowerLeftY; - return result; - }; + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } - /** - * Computes a bounding rectangle by enlarging the provided rectangle until it contains the provided point. - * - * @param {BoundingRectangle} rectangle A rectangle to expand. - * @param {Cartesian2} point A point to enclose in a bounding rectangle. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. - */ - BoundingRectangle.expand = function(rectangle, point, result) { - Check.typeOf.object('rectangle', rectangle); - Check.typeOf.object('point', point); - - result = BoundingRectangle.clone(rectangle, result); + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } - var width = point.x - result.x; - var height = point.y - result.y; + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } - if (width > result.width) { - result.width = width; - } else if (width < 0) { - result.width -= width; - result.x = point.x; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; } - if (height > result.height) { - result.height = height; - } else if (height < 0) { - result.height -= height; - result.y = point.y; + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); } - return result; + return issueRequest(request); }; - /** - * Determines if two rectangles intersect. - * - * @param {BoundingRectangle} left A rectangle to check for intersection. - * @param {BoundingRectangle} right The other rectangle to check for intersection. - * @returns {Intersect} <code>Intersect.INTESECTING</code> if the rectangles intersect, <code>Intersect.OUTSIDE</code> otherwise. - */ - BoundingRectangle.intersect = function(left, right) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - - var leftX = left.x; - var leftY = left.y; - var rightX = right.x; - var rightY = right.y; - if (!(leftX > rightX + right.width || - leftX + left.width < rightX || - leftY + left.height < rightY || - leftY > rightY + right.height)) { - return Intersect.INTERSECTING; + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; } - return Intersect.OUTSIDE; - }; + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } - /** - * Compares the provided BoundingRectangles componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {BoundingRectangle} [left] The first BoundingRectangle. - * @param {BoundingRectangle} [right] The second BoundingRectangle. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - BoundingRectangle.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.x === right.x) && - (left.y === right.y) && - (left.width === right.width) && - (left.height === right.height)); - }; + clearStatistics(); + } /** - * Duplicates this BoundingRectangle instance. + * For testing only. Clears any requests that may not have completed from previous tests. * - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. + * @private */ - BoundingRectangle.prototype.clone = function(result) { - return BoundingRectangle.clone(this, result); + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; + + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Determines if this rectangle intersects with another. + * For testing only. * - * @param {BoundingRectangle} right A rectangle to check for intersection. - * @returns {Intersect} <code>Intersect.INTESECTING</code> if the rectangles intersect, <code>Intersect.OUTSIDE</code> otherwise. + * @private */ - BoundingRectangle.prototype.intersect = function(right) { - return BoundingRectangle.intersect(this, right); + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * Compares this BoundingRectangle against the provided BoundingRectangle componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * For testing only. * - * @param {BoundingRectangle} [right] The right hand side BoundingRectangle. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @private */ - BoundingRectangle.prototype.equals = function(right) { - return BoundingRectangle.equals(this, right); - }; + RequestScheduler.requestHeap = requestHeap; - return BoundingRectangle; + return RequestScheduler; }); -define('Core/Interval',[ - './defaultValue' +define('Core/RuntimeError',[ + './defined' ], function( - defaultValue) { + defined) { 'use strict'; /** - * Represents the closed interval [start, stop]. - * @alias Interval + * Constructs an exception object that is thrown due to an error that can occur at runtime, e.g., + * out of memory, could not compile shader, etc. If a function may throw this + * exception, the calling code should be prepared to catch it. + * <br /><br /> + * On the other hand, a {@link DeveloperError} indicates an exception due + * to a developer error, e.g., invalid argument, that usually indicates a bug in the + * calling code. + * + * @alias RuntimeError * @constructor + * @extends Error * - * @param {Number} [start=0.0] The beginning of the interval. - * @param {Number} [stop=0.0] The end of the interval. + * @param {String} [message] The error message for this exception. + * + * @see DeveloperError */ - function Interval(start, stop) { + function RuntimeError(message) { /** - * The beginning of the interval. - * @type {Number} - * @default 0.0 + * 'RuntimeError' indicating that this exception was thrown due to a runtime error. + * @type {String} + * @readonly */ - this.start = defaultValue(start, 0.0); + this.name = 'RuntimeError'; + /** - * The end of the interval. - * @type {Number} - * @default 0.0 + * The explanation for why this exception was thrown. + * @type {String} + * @readonly */ - this.stop = defaultValue(stop, 0.0); + this.message = message; + + //Browsers such as IE don't have a stack property until you actually throw the error. + var stack; + try { + throw new Error(); + } catch (e) { + stack = e.stack; + } + + /** + * The stack trace of this exception, if available. + * @type {String} + * @readonly + */ + this.stack = stack; } - return Interval; + if (defined(Object.create)) { + RuntimeError.prototype = Object.create(Error.prototype); + RuntimeError.prototype.constructor = RuntimeError; + } + + RuntimeError.prototype.toString = function() { + var str = this.name + ': ' + this.message; + + if (defined(this.stack)) { + str += '\n' + this.stack.toString(); + } + + return str; + }; + + return RuntimeError; }); -define('Core/Matrix3',[ - './Cartesian3', - './Check', - './defaultValue', +define('Core/TrustedServers',[ + '../ThirdParty/Uri', './defined', - './defineProperties', - './DeveloperError', - './freezeObject', - './Math' + './DeveloperError' ], function( - Cartesian3, - Check, - defaultValue, + Uri, defined, - defineProperties, - DeveloperError, - freezeObject, - CesiumMath) { + DeveloperError) { 'use strict'; /** - * A 3x3 matrix, indexable as a column-major order array. - * Constructor parameters are in row-major order for code readability. - * @alias Matrix3 - * @constructor + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. * - * @param {Number} [column0Row0=0.0] The value for column 0, row 0. - * @param {Number} [column1Row0=0.0] The value for column 1, row 0. - * @param {Number} [column2Row0=0.0] The value for column 2, row 0. - * @param {Number} [column0Row1=0.0] The value for column 0, row 1. - * @param {Number} [column1Row1=0.0] The value for column 1, row 1. - * @param {Number} [column2Row1=0.0] The value for column 2, row 1. - * @param {Number} [column0Row2=0.0] The value for column 0, row 2. - * @param {Number} [column1Row2=0.0] The value for column 1, row 2. - * @param {Number} [column2Row2=0.0] The value for column 2, row 2. + * @exports TrustedServers * - * @see Matrix3.fromColumnMajorArray - * @see Matrix3.fromRowMajorArray - * @see Matrix3.fromQuaternion - * @see Matrix3.fromScale - * @see Matrix3.fromUniformScale - * @see Matrix2 - * @see Matrix4 - */ - function Matrix3(column0Row0, column1Row0, column2Row0, - column0Row1, column1Row1, column2Row1, - column0Row2, column1Row2, column2Row2) { - this[0] = defaultValue(column0Row0, 0.0); - this[1] = defaultValue(column0Row1, 0.0); - this[2] = defaultValue(column0Row2, 0.0); - this[3] = defaultValue(column1Row0, 0.0); - this[4] = defaultValue(column1Row1, 0.0); - this[5] = defaultValue(column1Row2, 0.0); - this[6] = defaultValue(column2Row0, 0.0); - this[7] = defaultValue(column2Row1, 0.0); - this[8] = defaultValue(column2Row2, 0.0); - } - - /** - * The number of elements used to pack the object into an array. - * @type {Number} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ - Matrix3.packedLength = 9; + var TrustedServers = {}; + var _servers = {}; /** - * Stores the provided instance into the provided array. + * Adds a trusted server to the registry * - * @param {Matrix3} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @returns {Number[]} The array that was packed into + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); */ - Matrix3.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - startingIndex = defaultValue(startingIndex, 0); - - array[startingIndex++] = value[0]; - array[startingIndex++] = value[1]; - array[startingIndex++] = value[2]; - array[startingIndex++] = value[3]; - array[startingIndex++] = value[4]; - array[startingIndex++] = value[5]; - array[startingIndex++] = value[6]; - array[startingIndex++] = value[7]; - array[startingIndex++] = value[8]; - - return array; + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } }; /** - * Retrieves an instance from a packed array. + * Removes a trusted server from the registry * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Matrix3} [result] The object into which to store the result. - * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - Matrix3.unpack = function(array, startingIndex, result) { - Check.defined('array', array); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - startingIndex = defaultValue(startingIndex, 0); + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - if (!defined(result)) { - result = new Matrix3(); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); + + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL } - result[0] = array[startingIndex++]; - result[1] = array[startingIndex++]; - result[2] = array[startingIndex++]; - result[3] = array[startingIndex++]; - result[4] = array[startingIndex++]; - result[5] = array[startingIndex++]; - result[6] = array[startingIndex++]; - result[7] = array[startingIndex++]; - result[8] = array[startingIndex++]; - return result; - }; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Duplicates a Matrix3 instance. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @param {Matrix3} matrix The matrix to duplicate. - * @param {Matrix3} [result] The object onto which to store the result. - * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. (Returns undefined if matrix is undefined) + * @param {String} url The url to be tested against the trusted list + * + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - Matrix3.clone = function(matrix, result) { - if (!defined(matrix)) { - return undefined; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); } - if (!defined(result)) { - return new Matrix3(matrix[0], matrix[3], matrix[6], - matrix[1], matrix[4], matrix[7], - matrix[2], matrix[5], matrix[8]); + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; } - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[3]; - result[4] = matrix[4]; - result[5] = matrix[5]; - result[6] = matrix[6]; - result[7] = matrix[7]; - result[8] = matrix[8]; - return result; + + return false; }; /** - * Creates a Matrix3 from 9 consecutive elements in an array. - * - * @param {Number[]} array The array whose 9 consecutive elements correspond to the positions of the matrix. Assumes column-major order. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. - * @param {Matrix3} [result] The object onto which to store the result. - * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. + * Clears the registry * * @example - * // Create the Matrix3: - * // [1.0, 2.0, 3.0] - * // [1.0, 2.0, 3.0] - * // [1.0, 2.0, 3.0] - * - * var v = [1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0]; - * var m = Cesium.Matrix3.fromArray(v); - * - * // Create same Matrix3 with using an offset into an array - * var v2 = [0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0]; - * var m2 = Cesium.Matrix3.fromArray(v2, 2); - */ - Matrix3.fromArray = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; + }; - if (!defined(result)) { - result = new Matrix3(); - } + return TrustedServers; +}); - result[0] = array[startingIndex]; - result[1] = array[startingIndex + 1]; - result[2] = array[startingIndex + 2]; - result[3] = array[startingIndex + 3]; - result[4] = array[startingIndex + 4]; - result[5] = array[startingIndex + 5]; - result[6] = array[startingIndex + 6]; - result[7] = array[startingIndex + 7]; - result[8] = array[startingIndex + 8]; - return result; - }; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - /** - * Creates a Matrix3 instance from a column-major order array. - * - * @param {Number[]} values The column-major order array. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. - */ - Matrix3.fromColumnMajorArray = function(values, result) { - Check.defined('values', values); - - return Matrix3.clone(values, result); - }; + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Creates a Matrix3 instance from a row-major order array. - * The resulting matrix will be in column-major order. - * - * @param {Number[]} values The row-major order array. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * @private */ - Matrix3.fromRowMajorArray = function(values, result) { - Check.defined('values', values); - - if (!defined(result)) { - return new Matrix3(values[0], values[1], values[2], - values[3], values[4], values[5], - values[6], values[7], values[8]); + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); } - result[0] = values[0]; - result[1] = values[3]; - result[2] = values[6]; - result[3] = values[1]; - result[4] = values[4]; - result[5] = values[7]; - result[6] = values[2]; - result[7] = values[5]; - result[8] = values[8]; - return result; - }; + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } /** - * Computes a 3x3 rotation matrix from the provided quaternion. - * - * @param {Quaternion} quaternion the quaternion to use. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The 3x3 rotation matrix from this quaternion. + * @private */ - Matrix3.fromQuaternion = function(quaternion, result) { - Check.typeOf.object('quaternion', quaternion); - - var x2 = quaternion.x * quaternion.x; - var xy = quaternion.x * quaternion.y; - var xz = quaternion.x * quaternion.z; - var xw = quaternion.x * quaternion.w; - var y2 = quaternion.y * quaternion.y; - var yz = quaternion.y * quaternion.z; - var yw = quaternion.y * quaternion.w; - var z2 = quaternion.z * quaternion.z; - var zw = quaternion.z * quaternion.w; - var w2 = quaternion.w * quaternion.w; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; - var m00 = x2 - y2 - z2 + w2; - var m01 = 2.0 * (xy - zw); - var m02 = 2.0 * (xz + yw); + var keys = Object.keys(queryObject); - var m10 = 2.0 * (xy + zw); - var m11 = -x2 + y2 - z2 + w2; - var m12 = 2.0 * (yz - xw); + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } - var m20 = 2.0 * (xz - yw); - var m21 = 2.0 * (yz + xw); - var m22 = -x2 - y2 + z2 + w2; + /** + * @private + */ + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } - if (!defined(result)) { - return new Matrix3(m00, m01, m02, - m10, m11, m12, - m20, m21, m22); + return defined(obj.clone) ? obj.clone() : clone(obj); + } + + /** + * @private + */ + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); } - result[0] = m00; - result[1] = m10; - result[2] = m20; - result[3] = m01; - result[4] = m11; - result[5] = m21; - result[6] = m02; - result[7] = m12; - result[8] = m22; - return result; - }; + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * Computes a 3x3 rotation matrix from the provided headingPitchRoll. (see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles ) + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. * - * @param {HeadingPitchRoll} headingPitchRoll the headingPitchRoll to use. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The 3x3 rotation matrix from this headingPitchRoll. + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - Matrix3.fromHeadingPitchRoll = function(headingPitchRoll, result) { - Check.typeOf.object('headingPitchRoll', headingPitchRoll); + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); - var cosTheta = Math.cos(-headingPitchRoll.pitch); - var cosPsi = Math.cos(-headingPitchRoll.heading); - var cosPhi = Math.cos(headingPitchRoll.roll); - var sinTheta = Math.sin(-headingPitchRoll.pitch); - var sinPsi = Math.sin(-headingPitchRoll.heading); - var sinPhi = Math.sin(headingPitchRoll.roll); + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - var m00 = cosTheta * cosPsi; - var m01 = -cosPhi * sinPsi + sinPhi * sinTheta * cosPsi; - var m02 = sinPhi * sinPsi + cosPhi * sinTheta * cosPsi; + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); - var m10 = cosTheta * sinPsi; - var m11 = cosPhi * cosPsi + sinPhi * sinTheta * sinPsi; - var m12 = -sinPhi * cosPsi + cosPhi * sinTheta * sinPsi; + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); - var m20 = -sinTheta; - var m21 = sinPhi * cosTheta; - var m22 = cosPhi * cosTheta; + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; - if (!defined(result)) { - return new Matrix3(m00, m01, m02, - m10, m11, m12, - m20, m21, m22); - } - result[0] = m00; - result[1] = m10; - result[2] = m20; - result[3] = m01; - result[4] = m11; - result[5] = m21; - result[6] = m02; - result[7] = m12; - result[8] = m22; - return result; - }; + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } /** - * Computes a Matrix3 instance representing a non-uniform scale. + * A helper function to create a resource depending on whether we have a String or a Resource * - * @param {Cartesian3} scale The x, y, and z scale factors. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. * - * @example - * // Creates - * // [7.0, 0.0, 0.0] - * // [0.0, 8.0, 0.0] - * // [0.0, 0.0, 9.0] - * var m = Cesium.Matrix3.fromScale(new Cesium.Cartesian3(7.0, 8.0, 9.0)); + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private */ - Matrix3.fromScale = function(scale, result) { - Check.typeOf.object('scale', scale); - - if (!defined(result)) { - return new Matrix3( - scale.x, 0.0, 0.0, - 0.0, scale.y, 0.0, - 0.0, 0.0, scale.z); + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); } - result[0] = scale.x; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = scale.y; - result[5] = 0.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = scale.z; - return result; + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); }; + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } + } + }); + + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, + + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, + + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); + + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); + } + }, + + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, + + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); + } + } + }); + /** - * Computes a Matrix3 instance representing a uniform scale. + * Returns the url, optional with the query string and processed by a proxy. * - * @param {Number} scale The uniform scale factor. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. * - * @example - * // Creates - * // [2.0, 0.0, 0.0] - * // [0.0, 2.0, 0.0] - * // [0.0, 0.0, 2.0] - * var m = Cesium.Matrix3.fromUniformScale(2.0); + * @returns {String} The url with all the requested components. */ - Matrix3.fromUniformScale = function(scale, result) { - Check.typeOf.number('scale', scale); - - if (!defined(result)) { - return new Matrix3( - scale, 0.0, 0.0, - 0.0, scale, 0.0, - 0.0, 0.0, scale); + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - result[0] = scale; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = scale; - result[5] = 0.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = scale; - return result; + var uri = new Uri(this._url); + + if (query) { + stringifyQuery(uri, this); + } + + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); + } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; }; /** - * Computes a Matrix3 instance representing the cross product equivalent matrix of a Cartesian3 vector. - * - * @param {Cartesian3} vector the vector on the left hand side of the cross product operation. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. * - * @example - * // Creates - * // [0.0, -9.0, 8.0] - * // [9.0, 0.0, -7.0] - * // [-8.0, 7.0, 0.0] - * var m = Cesium.Matrix3.fromCrossProduct(new Cesium.Cartesian3(7.0, 8.0, 9.0)); + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. */ - Matrix3.fromCrossProduct = function(vector, result) { - Check.typeOf.object('vector', vector); - - if (!defined(result)) { - return new Matrix3( - 0.0, -vector.z, vector.y, - vector.z, 0.0, -vector.x, - -vector.y, vector.x, 0.0); + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } - - result[0] = 0.0; - result[1] = vector.z; - result[2] = -vector.y; - result[3] = -vector.z; - result[4] = 0.0; - result[5] = vector.x; - result[6] = vector.y; - result[7] = -vector.x; - result[8] = 0.0; - return result; }; /** - * Creates a rotation matrix around the x-axis. - * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. * - * @example - * // Rotate a point 45 degrees counterclockwise around the x-axis. - * var p = new Cesium.Cartesian3(5, 6, 7); - * var m = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(45.0)); - * var rotated = Cesium.Matrix3.multiplyByVector(m, p, new Cesium.Cartesian3()); + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. */ - Matrix3.fromRotationX = function(angle, result) { - Check.typeOf.number('angle', angle); - - var cosAngle = Math.cos(angle); - var sinAngle = Math.sin(angle); - - if (!defined(result)) { - return new Matrix3( - 1.0, 0.0, 0.0, - 0.0, cosAngle, -sinAngle, - 0.0, sinAngle, cosAngle); + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); } - - result[0] = 1.0; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = cosAngle; - result[5] = sinAngle; - result[6] = 0.0; - result[7] = -sinAngle; - result[8] = cosAngle; - - return result; }; /** - * Creates a rotation matrix around the y-axis. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. * - * @example - * // Rotate a point 45 degrees counterclockwise around the y-axis. - * var p = new Cesium.Cartesian3(5, 6, 7); - * var m = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(45.0)); - * var rotated = Cesium.Matrix3.multiplyByVector(m, p, new Cesium.Cartesian3()); + * @returns {Resource} The resource derived from the current one. */ - Matrix3.fromRotationY = function(angle, result) { - Check.typeOf.number('angle', angle); - - var cosAngle = Math.cos(angle); - var sinAngle = Math.sin(angle); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; - if (!defined(result)) { - return new Matrix3( - cosAngle, 0.0, sinAngle, - 0.0, 1.0, 0.0, - -sinAngle, 0.0, cosAngle); + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - result[0] = cosAngle; - result[1] = 0.0; - result[2] = -sinAngle; - result[3] = 0.0; - result[4] = 1.0; - result[5] = 0.0; - result[6] = sinAngle; - result[7] = 0.0; - result[8] = cosAngle; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; + } - return result; + return resource; }; /** - * Creates a rotation matrix around the z-axis. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. - * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * @param {Error} [error] The error that was encountered. * - * @example - * // Rotate a point 45 degrees counterclockwise around the z-axis. - * var p = new Cesium.Cartesian3(5, 6, 7); - * var m = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(45.0)); - * var rotated = Cesium.Matrix3.multiplyByVector(m, p, new Cesium.Cartesian3()); + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - Matrix3.fromRotationZ = function(angle, result) { - Check.typeOf.number('angle', angle); - - var cosAngle = Math.cos(angle); - var sinAngle = Math.sin(angle); - - if (!defined(result)) { - return new Matrix3( - cosAngle, -sinAngle, 0.0, - sinAngle, cosAngle, 0.0, - 0.0, 0.0, 1.0); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - result[0] = cosAngle; - result[1] = sinAngle; - result[2] = 0.0; - result[3] = -sinAngle; - result[4] = cosAngle; - result[5] = 0.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 1.0; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - return result; + return result; + }); }; /** - * Creates an Array from the provided Matrix3 instance. - * The array will be in column-major order. + * Duplicates a Resource instance. * - * @param {Matrix3} matrix The matrix to use.. - * @param {Number[]} [result] The Array onto which to store the result. - * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. */ - Matrix3.toArray = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - + Resource.prototype.clone = function(result) { if (!defined(result)) { - return [matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7], matrix[8]]; + result = new Resource({ + url : this._url + }); } - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[3]; - result[4] = matrix[4]; - result[5] = matrix[5]; - result[6] = matrix[6]; - result[7] = matrix[7]; - result[8] = matrix[8]; + + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; + + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; + return result; }; /** - * Computes the array index of the element at the provided row and column. - * - * @param {Number} row The zero-based index of the row. - * @param {Number} column The zero-based index of the column. - * @returns {Number} The index of the element at the provided row and column. + * Returns the base path of the Resource. * - * @exception {DeveloperError} row must be 0, 1, or 2. - * @exception {DeveloperError} column must be 0, 1, or 2. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri * - * @example - * var myMatrix = new Cesium.Matrix3(); - * var column1Row0Index = Cesium.Matrix3.getElementIndex(1, 0); - * var column1Row0 = myMatrix[column1Row0Index] - * myMatrix[column1Row0Index] = 10.0; + * @returns {String} The base URI of the resource */ - Matrix3.getElementIndex = function(column, row) { - Check.typeOf.number.greaterThanOrEquals('row', row, 0); - Check.typeOf.number.lessThanOrEquals('row', row, 2); - Check.typeOf.number.greaterThanOrEquals('column', column, 0); - Check.typeOf.number.lessThanOrEquals('column', column, 2); - - return column * 3 + row; + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); }; /** - * Retrieves a copy of the matrix column at the provided index as a Cartesian3 instance. - * - * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to retrieve. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. - * - * @exception {DeveloperError} index must be 0, 1, or 2. + * Appends a forward slash to the URL. */ - Matrix3.getColumn = function(matrix, index, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 2); - Check.typeOf.object('result', result); - - var startIndex = index * 3; - var x = matrix[startIndex]; - var y = matrix[startIndex + 1]; - var z = matrix[startIndex + 2]; - - result.x = x; - result.y = y; - result.z = z; - return result; + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; /** - * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian3 instance. + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to set. - * @param {Cartesian3} cartesian The Cartesian whose values will be assigned to the specified column. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exception {DeveloperError} index must be 0, 1, or 2. + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.setColumn = function(matrix, index, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 2); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - result = Matrix3.clone(matrix, result); - var startIndex = index * 3; - result[startIndex] = cartesian.x; - result[startIndex + 1] = cartesian.y; - result[startIndex + 2] = cartesian.z; - return result; + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); }; /** - * Retrieves a copy of the matrix row at the provided index as a Cartesian3 instance. - * - * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to retrieve. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. + * Creates a Resource and calls fetchArrayBuffer() on it. * - * @exception {DeveloperError} index must be 0, 1, or 2. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - Matrix3.getRow = function(matrix, index, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 2); - Check.typeOf.object('result', result); - - var x = matrix[index]; - var y = matrix[index + 3]; - var z = matrix[index + 6]; - - result.x = x; - result.y = y; - result.z = z; - return result; + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); }; /** - * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian3 instance. + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to set. - * @param {Cartesian3} cartesian The Cartesian whose values will be assigned to the specified row. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exception {DeveloperError} index must be 0, 1, or 2. + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.setRow = function(matrix, index, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 2); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - result = Matrix3.clone(matrix, result); - result[index] = cartesian.x; - result[index + 3] = cartesian.y; - result[index + 6] = cartesian.z; - return result; + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); }; - var scratchColumn = new Cartesian3(); - /** - * Extracts the non-uniform scale assuming the matrix is an affine transformation. + * Creates a Resource and calls fetchBlob() on it. * - * @param {Matrix3} matrix The matrix. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - Matrix3.getScale = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result.x = Cartesian3.magnitude(Cartesian3.fromElements(matrix[0], matrix[1], matrix[2], scratchColumn)); - result.y = Cartesian3.magnitude(Cartesian3.fromElements(matrix[3], matrix[4], matrix[5], scratchColumn)); - result.z = Cartesian3.magnitude(Cartesian3.fromElements(matrix[6], matrix[7], matrix[8], scratchColumn)); - return result; + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); }; - var scratchScale = new Cartesian3(); - /** - * Computes the maximum scale assuming the matrix is an affine transformation. - * The maximum scale is the maximum length of the column vectors. + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @param {Matrix3} matrix The matrix. - * @returns {Number} The maximum scale. + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.getMaximumScale = function(matrix) { - Matrix3.getScale(matrix, scratchScale); - return Cartesian3.maximumComponent(scratchScale); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); + } + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); + } + + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; + } + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); }; - /** - * Computes the product of two matrices. - * - * @param {Matrix3} left The first matrix. - * @param {Matrix3} right The second matrix. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. - */ - Matrix3.multiply = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - var column0Row0 = left[0] * right[0] + left[3] * right[1] + left[6] * right[2]; - var column0Row1 = left[1] * right[0] + left[4] * right[1] + left[7] * right[2]; - var column0Row2 = left[2] * right[0] + left[5] * right[1] + left[8] * right[2]; + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; - var column1Row0 = left[0] * right[3] + left[3] * right[4] + left[6] * right[5]; - var column1Row1 = left[1] * right[3] + left[4] * right[4] + left[7] * right[5]; - var column1Row2 = left[2] * right[3] + left[5] * right[4] + left[8] * right[5]; + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } - var column2Row0 = left[0] * right[6] + left[3] * right[7] + left[6] * right[8]; - var column2Row1 = left[1] * right[6] + left[4] * right[7] + left[7] * right[8]; - var column2Row2 = left[2] * right[6] + left[5] * right[7] + left[8] * right[8]; + var deferred = when.defer(); - result[0] = column0Row0; - result[1] = column0Row1; - result[2] = column0Row2; - result[3] = column1Row0; - result[4] = column1Row1; - result[5] = column1Row2; - result[6] = column2Row0; - result[7] = column2Row1; - result[8] = column2Row2; - return result; + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource and calls fetchImage() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * Computes the sum of two matrices. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Matrix3} left The first matrix. - * @param {Matrix3} right The second matrix. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.add = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result[0] = left[0] + right[0]; - result[1] = left[1] + right[1]; - result[2] = left[2] + right[2]; - result[3] = left[3] + right[3]; - result[4] = left[4] + right[4]; - result[5] = left[5] + right[5]; - result[6] = left[6] + right[6]; - result[7] = left[7] + right[7]; - result[8] = left[8] + right[8]; - return result; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); }; /** - * Computes the difference of two matrices. + * Creates a Resource and calls fetchText() on it. * - * @param {Matrix3} left The first matrix. - * @param {Matrix3} right The second matrix. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - Matrix3.subtract = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result[0] = left[0] - right[0]; - result[1] = left[1] - right[1]; - result[2] = left[2] - right[2]; - result[3] = left[3] - right[3]; - result[4] = left[4] - right[4]; - result[5] = left[5] - right[5]; - result[6] = left[6] - right[6]; - result[7] = left[7] - right[7]; - result[8] = left[8] - right[8]; - return result; + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Computes the product of a matrix and a column vector. + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. * - * @param {Matrix3} matrix The matrix. - * @param {Cartesian3} cartesian The column. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.multiplyByVector = function(matrix, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var vX = cartesian.x; - var vY = cartesian.y; - var vZ = cartesian.z; + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - var x = matrix[0] * vX + matrix[3] * vY + matrix[6] * vZ; - var y = matrix[1] * vX + matrix[4] * vY + matrix[7] * vZ; - var z = matrix[2] * vX + matrix[5] * vY + matrix[8] * vZ; + if (!defined(promise)) { + return undefined; + } - result.x = x; - result.y = y; - result.z = z; - return result; + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); }; /** - * Computes the product of a matrix and a scalar. + * Creates a Resource and calls fetchJson() on it. * - * @param {Matrix3} matrix The matrix. - * @param {Number} scalar The number to multiply by. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - Matrix3.multiplyByScalar = function(matrix, scalar, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result[0] = matrix[0] * scalar; - result[1] = matrix[1] * scalar; - result[2] = matrix[2] * scalar; - result[3] = matrix[3] * scalar; - result[4] = matrix[4] * scalar; - result[5] = matrix[5] * scalar; - result[6] = matrix[6] * scalar; - result[7] = matrix[7] * scalar; - result[8] = matrix[8] * scalar; - return result; + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); }; /** - * Computes the product of a matrix times a (non-uniform) scale, as if the scale were a scale matrix. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Matrix3} matrix The matrix on the left-hand side. - * @param {Cartesian3} scale The non-uniform scale on the right-hand side. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Instead of Cesium.Matrix3.multiply(m, Cesium.Matrix3.fromScale(scale), m); - * Cesium.Matrix3.multiplyByScale(m, scale, m); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see Matrix3.fromScale - * @see Matrix3.multiplyByUniformScale + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.multiplyByScale = function(matrix, scale, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('scale', scale); - Check.typeOf.object('result', result); - - result[0] = matrix[0] * scale.x; - result[1] = matrix[1] * scale.x; - result[2] = matrix[2] * scale.x; - result[3] = matrix[3] * scale.y; - result[4] = matrix[4] * scale.y; - result[5] = matrix[5] * scale.y; - result[6] = matrix[6] * scale.z; - result[7] = matrix[7] * scale.z; - result[8] = matrix[8] * scale.z; - return result; + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); }; /** - * Creates a negated copy of the provided matrix. + * Creates a Resource and calls fetchXML() on it. * - * @param {Matrix3} matrix The matrix to negate. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - Matrix3.negate = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result[0] = -matrix[0]; - result[1] = -matrix[1]; - result[2] = -matrix[2]; - result[3] = -matrix[3]; - result[4] = -matrix[4]; - result[5] = -matrix[5]; - result[6] = -matrix[6]; - result[7] = -matrix[7]; - result[8] = -matrix[8]; - return result; + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Computes the transpose of the provided matrix. + * Requests a resource using JSONP. * - * @param {Matrix3} matrix The matrix to transpose. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.transpose = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - var column0Row0 = matrix[0]; - var column0Row1 = matrix[3]; - var column0Row2 = matrix[6]; - var column1Row0 = matrix[1]; - var column1Row1 = matrix[4]; - var column1Row2 = matrix[7]; - var column2Row0 = matrix[2]; - var column2Row1 = matrix[5]; - var column2Row2 = matrix[8]; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); - result[0] = column0Row0; - result[1] = column0Row1; - result[2] = column0Row2; - result[3] = column1Row0; - result[4] = column1Row1; - result[5] = column1Row2; - result[6] = column2Row0; - result[7] = column2Row1; - result[8] = column2Row2; - return result; + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - function computeFrobeniusNorm(matrix) { - var norm = 0.0; - for (var i = 0; i < 9; ++i) { - var temp = matrix[i]; - norm += temp * temp; - } + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); - return Math.sqrt(norm); - } + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); - var rowVal = [1, 0, 0]; - var colVal = [2, 2, 1]; + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); - function offDiagonalFrobeniusNorm(matrix) { - // Computes the "off-diagonal" Frobenius norm. - // Assumes matrix is symmetric. + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; - var norm = 0.0; - for (var i = 0; i < 3; ++i) { - var temp = matrix[Matrix3.getElementIndex(colVal[i], rowVal[i])]; - norm += 2.0 * temp * temp; + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - return Math.sqrt(norm); + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); } - function shurDecomposition(matrix, result) { - // This routine was created based upon Matrix Computations, 3rd ed., by Golub and Van Loan, - // section 8.4.2 The 2by2 Symmetric Schur Decomposition. - // - // The routine takes a matrix, which is assumed to be symmetric, and - // finds the largest off-diagonal term, and then creates - // a matrix (result) which can be used to help reduce it + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; - var tolerance = CesiumMath.EPSILON15; + /** + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - var maxDiagonal = 0.0; - var rotAxis = 1; + return makeRequest(this, options); + }; - // find pivot (rotAxis) based on max diagonal of matrix - for (var i = 0; i < 3; ++i) { - var temp = Math.abs(matrix[Matrix3.getElementIndex(colVal[i], rowVal[i])]); - if (temp > maxDiagonal) { - rotAxis = i; - maxDiagonal = temp; + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; + + request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; + var deferred = when.defer(); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); + if (defined(xhr) && defined(xhr.abort)) { + request.cancelFunction = function() { + xhr.abort(); + }; } + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - var c = 1.0; - var s = 0.0; + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - var p = rowVal[rotAxis]; - var q = colVal[rotAxis]; + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - if (Math.abs(matrix[Matrix3.getElementIndex(q, p)]) > tolerance) { - var qq = matrix[Matrix3.getElementIndex(q, q)]; - var pp = matrix[Matrix3.getElementIndex(p, p)]; - var qp = matrix[Matrix3.getElementIndex(q, p)]; + return resource.fetch(options); + } - var tau = (qq - pp) / 2.0 / qp; - var t; + return when.reject(e); + }); + }); + } - if (tau < 0.0) { - t = -1.0 / (-tau + Math.sqrt(1.0 + tau * tau)); - } else { - t = 1.0 / (tau + Math.sqrt(1.0 + tau * tau)); - } + var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; - c = 1.0 / Math.sqrt(1.0 + t * t); - s = t * c; + function decodeDataUriText(isBase64, data) { + var result = decodeURIComponent(data); + if (isBase64) { + return atob(result); } + return result; + } - result = Matrix3.clone(Matrix3.IDENTITY, result); + function decodeDataUriArrayBuffer(isBase64, data) { + var byteString = decodeDataUriText(isBase64, data); + var buffer = new ArrayBuffer(byteString.length); + var view = new Uint8Array(buffer); + for (var i = 0; i < byteString.length; i++) { + view[i] = byteString.charCodeAt(i); + } + return buffer; + } - result[Matrix3.getElementIndex(p, p)] = result[Matrix3.getElementIndex(q, q)] = c; - result[Matrix3.getElementIndex(q, p)] = s; - result[Matrix3.getElementIndex(p, q)] = -s; + function decodeDataUri(dataUriRegexResult, responseType) { + responseType = defaultValue(responseType, ''); + var mimeType = dataUriRegexResult[1]; + var isBase64 = !!dataUriRegexResult[2]; + var data = dataUriRegexResult[3]; - return result; + switch (responseType) { + case '': + case 'text': + return decodeDataUriText(isBase64, data); + case 'arraybuffer': + return decodeDataUriArrayBuffer(isBase64, data); + case 'blob': + var buffer = decodeDataUriArrayBuffer(isBase64, data); + return new Blob([buffer], { + type : mimeType + }); + case 'document': + var parser = new DOMParser(); + return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); + case 'json': + return JSON.parse(decodeDataUriText(isBase64, data)); + default: + throw new DeveloperError('Unhandled responseType: ' + responseType); + } } - var jMatrix = new Matrix3(); - var jMatrixTranspose = new Matrix3(); + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; /** - * Computes the eigenvectors and eigenvalues of a symmetric matrix. - * <p> - * Returns a diagonal matrix and unitary matrix such that: - * <code>matrix = unitary matrix * diagonal matrix * transpose(unitary matrix)</code> - * </p> - * <p> - * The values along the diagonal of the diagonal matrix are the eigenvalues. The columns - * of the unitary matrix are the corresponding eigenvectors. - * </p> + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Matrix3} matrix The matrix to decompose into diagonal and unitary matrix. Expected to be symmetric. - * @param {Object} [result] An object with unitary and diagonal properties which are matrices onto which to store the result. - * @returns {Object} An object with unitary and diagonal properties which are the unitary and diagonal matrices, respectively. + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @example - * var a = //... symetric matrix - * var result = { - * unitary : new Cesium.Matrix3(), - * diagonal : new Cesium.Matrix3() - * }; - * Cesium.Matrix3.computeEigenDecomposition(a, result); * - * var unitaryTranspose = Cesium.Matrix3.transpose(result.unitary, new Cesium.Matrix3()); - * var b = Cesium.Matrix3.multiply(result.unitary, result.diagonal, new Cesium.Matrix3()); - * Cesium.Matrix3.multiply(b, unitaryTranspose, b); // b is now equal to a + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); * - * var lambda = Cesium.Matrix3.getColumn(result.diagonal, 0, new Cesium.Cartesian3()).x; // first eigenvalue - * var v = Cesium.Matrix3.getColumn(result.unitary, 0, new Cesium.Cartesian3()); // first eigenvector - * var c = Cesium.Cartesian3.multiplyByScalar(v, lambda, new Cesium.Cartesian3()); // equal to Cesium.Matrix3.multiplyByVector(a, v) + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - Matrix3.computeEigenDecomposition = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - - // This routine was created based upon Matrix Computations, 3rd ed., by Golub and Van Loan, - // section 8.4.3 The Classical Jacobi Algorithm + Resource.prototype.post = function(data, options) { + Check.defined('data', data); - var tolerance = CesiumMath.EPSILON20; - var maxSweeps = 10; + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; - var count = 0; - var sweep = 0; + return makeRequest(this, options); + }; - if (!defined(result)) { - result = {}; - } + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; - var unitaryMatrix = result.unitary = Matrix3.clone(Matrix3.IDENTITY, result.unitary); - var diagMatrix = result.diagonal = Matrix3.clone(matrix, result.diagonal); + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; - var epsilon = tolerance * computeFrobeniusNorm(diagMatrix); + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); - while (sweep < maxSweeps && offDiagonalFrobeniusNorm(diagMatrix) > epsilon) { - shurDecomposition(diagMatrix, jMatrix); - Matrix3.transpose(jMatrix, jMatrixTranspose); - Matrix3.multiply(diagMatrix, jMatrix, diagMatrix); - Matrix3.multiply(jMatrixTranspose, diagMatrix, diagMatrix); - Matrix3.multiply(unitaryMatrix, jMatrix, unitaryMatrix); + image.onload = function() { + deferred.resolve(image); + }; - if (++count > 2) { - ++sweep; - count = 0; + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; } } - return result; + image.src = url; }; - /** - * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements. - * - * @param {Matrix3} matrix The matrix with signed elements. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. - */ - Matrix3.abs = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result[0] = Math.abs(matrix[0]); - result[1] = Math.abs(matrix[1]); - result[2] = Math.abs(matrix[2]); - result[3] = Math.abs(matrix[3]); - result[4] = Math.abs(matrix[4]); - result[5] = Math.abs(matrix[5]); - result[6] = Math.abs(matrix[6]); - result[7] = Math.abs(matrix[7]); - result[8] = Math.abs(matrix[8]); + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + var dataUriRegexResult = dataUriRegex.exec(url); + if (dataUriRegexResult !== null) { + deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); + return; + } - return result; - }; + var xhr = new XMLHttpRequest(); - /** - * Computes the determinant of the provided matrix. - * - * @param {Matrix3} matrix The matrix to use. - * @returns {Number} The value of the determinant of the matrix. - */ - Matrix3.determinant = function(matrix) { - Check.typeOf.object('matrix', matrix); - - var m11 = matrix[0]; - var m21 = matrix[3]; - var m31 = matrix[6]; - var m12 = matrix[1]; - var m22 = matrix[4]; - var m32 = matrix[7]; - var m13 = matrix[2]; - var m23 = matrix[5]; - var m33 = matrix[8]; + if (TrustedServers.contains(url)) { + xhr.withCredentials = true; + } - return m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13 * (m21 * m32 - m22 * m31); - }; + if (defined(overrideMimeType) && defined(xhr.overrideMimeType)) { + xhr.overrideMimeType(overrideMimeType); + } - /** - * Computes the inverse of the provided matrix. - * - * @param {Matrix3} matrix The matrix to invert. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. - * - * @exception {DeveloperError} matrix is not invertible. - */ - Matrix3.inverse = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - var m11 = matrix[0]; - var m21 = matrix[1]; - var m31 = matrix[2]; - var m12 = matrix[3]; - var m22 = matrix[4]; - var m32 = matrix[5]; - var m13 = matrix[6]; - var m23 = matrix[7]; - var m33 = matrix[8]; + xhr.open(method, url, true); - var determinant = Matrix3.determinant(matrix); + if (defined(headers)) { + for (var key in headers) { + if (headers.hasOwnProperty(key)) { + xhr.setRequestHeader(key, headers[key]); + } + } + } - if (Math.abs(determinant) <= CesiumMath.EPSILON15) { - throw new DeveloperError('matrix is not invertible'); + if (defined(responseType)) { + xhr.responseType = responseType; } - - result[0] = m22 * m33 - m23 * m32; - result[1] = m23 * m31 - m21 * m33; - result[2] = m21 * m32 - m22 * m31; - result[3] = m13 * m32 - m12 * m33; - result[4] = m11 * m33 - m13 * m31; - result[5] = m12 * m31 - m11 * m32; - result[6] = m12 * m23 - m13 * m22; - result[7] = m13 * m21 - m11 * m23; - result[8] = m11 * m22 - m12 * m21; - var scale = 1.0 / determinant; - return Matrix3.multiplyByScalar(result, scale, result); - }; + // While non-standard, file protocol always returns a status of 0 on success + var localFile = false; + if (typeof url === 'string') { + localFile = url.indexOf('file://') === 0; + } - /** - * Compares the provided matrices componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Matrix3} [left] The first matrix. - * @param {Matrix3} [right] The second matrix. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Matrix3.equals = function(left, right) { - return (left === right) || - (defined(left) && - defined(right) && - left[0] === right[0] && - left[1] === right[1] && - left[2] === right[2] && - left[3] === right[3] && - left[4] === right[4] && - left[5] === right[5] && - left[6] === right[6] && - left[7] === right[7] && - left[8] === right[8]); + xhr.onload = function() { + if ((xhr.status < 200 || xhr.status >= 300) && !(localFile && xhr.status === 0)) { + deferred.reject(new RequestErrorEvent(xhr.status, xhr.response, xhr.getAllResponseHeaders())); + return; + } + + var response = xhr.response; + var browserResponseType = xhr.responseType; + + //All modern browsers will go into either the first or second if block or last else block. + //Other code paths support older browsers that either do not support the supplied responseType + //or do not support the xhr.response property. + if (xhr.status === 204) { + // accept no content + deferred.resolve(); + } else if (defined(response) && (!defined(responseType) || (browserResponseType === responseType))) { + deferred.resolve(response); + } else if ((responseType === 'json') && typeof response === 'string') { + try { + deferred.resolve(JSON.parse(response)); + } catch (e) { + deferred.reject(e); + } + } else if ((browserResponseType === '' || browserResponseType === 'document') && defined(xhr.responseXML) && xhr.responseXML.hasChildNodes()) { + deferred.resolve(xhr.responseXML); + } else if ((browserResponseType === '' || browserResponseType === 'text') && defined(xhr.responseText)) { + deferred.resolve(xhr.responseText); + } else { + deferred.reject(new RuntimeError('Invalid XMLHttpRequest response type.')); + } + }; + + xhr.onerror = function(e) { + deferred.reject(new RequestErrorEvent()); + }; + + xhr.send(data); + + return xhr; }; - /** - * Compares the provided matrices componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {Matrix3} [left] The first matrix. - * @param {Matrix3} [right] The second matrix. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. - */ - Matrix3.equalsEpsilon = function(left, right, epsilon) { - Check.typeOf.number('epsilon', epsilon); - - return (left === right) || - (defined(left) && - defined(right) && - Math.abs(left[0] - right[0]) <= epsilon && - Math.abs(left[1] - right[1]) <= epsilon && - Math.abs(left[2] - right[2]) <= epsilon && - Math.abs(left[3] - right[3]) <= epsilon && - Math.abs(left[4] - right[4]) <= epsilon && - Math.abs(left[5] - right[5]) <= epsilon && - Math.abs(left[6] - right[6]) <= epsilon && - Math.abs(left[7] - right[7]) <= epsilon && - Math.abs(left[8] - right[8]) <= epsilon); + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; + + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; + + head.appendChild(script); }; /** - * An immutable Matrix3 instance initialized to the identity matrix. + * The default implementations * - * @type {Matrix3} - * @constant + * @private */ - Matrix3.IDENTITY = freezeObject(new Matrix3(1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0)); + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; /** - * An immutable Matrix3 instance initialized to the zero matrix. + * A resource instance initialized to the current browser location * - * @type {Matrix3} + * @type {Resource} * @constant */ - Matrix3.ZERO = freezeObject(new Matrix3(0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0)); + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); /** - * The index into Matrix3 for column 0, row 0. + * A function that returns the value of the property. + * @callback Resource~RetryCallback * - * @type {Number} - * @constant + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. */ - Matrix3.COLUMN0ROW0 = 0; - /** - * The index into Matrix3 for column 0, row 1. - * - * @type {Number} - * @constant - */ - Matrix3.COLUMN0ROW1 = 1; + return Resource; +}); - /** - * The index into Matrix3 for column 0, row 2. - * - * @type {Number} - * @constant - */ - Matrix3.COLUMN0ROW2 = 2; +define('Core/BingMapsGeocoderService',[ + './BingMapsApi', + './Check', + './defaultValue', + './defined', + './defineProperties', + './Rectangle', + './Resource' + ], function( + BingMapsApi, + Check, + defaultValue, + defined, + defineProperties, + Rectangle, + Resource) { + 'use strict'; - /** - * The index into Matrix3 for column 1, row 0. - * - * @type {Number} - * @constant - */ - Matrix3.COLUMN1ROW0 = 3; + var url = 'https://dev.virtualearth.net/REST/v1/Locations'; /** - * The index into Matrix3 for column 1, row 1. + * Provides geocoding through Bing Maps. + * @alias BingMapsGeocoderService + * @constructor * - * @type {Number} - * @constant + * @param {Object} options Object with the following properties: + * @param {Scene} options.scene The scene + * @param {String} [options.key] A key to use with the Bing Maps geocoding service */ - Matrix3.COLUMN1ROW1 = 4; + function BingMapsGeocoderService(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Check.typeOf.object('options.scene', options.scene); + + var key = options.key; + this._key = BingMapsApi.getKey(key); - /** - * The index into Matrix3 for column 1, row 2. - * - * @type {Number} - * @constant - */ - Matrix3.COLUMN1ROW2 = 5; + if (defined(key)) { + var errorCredit = BingMapsApi.getErrorCredit(key); + if (defined(errorCredit)) { + options.scene._frameState.creditDisplay.addDefaultCredit(errorCredit); + } + } - /** - * The index into Matrix3 for column 2, row 0. - * - * @type {Number} - * @constant - */ - Matrix3.COLUMN2ROW0 = 6; + this._resource = new Resource({ + url: url, + queryParameters: { + key: this._key + } + }); + } + + defineProperties(BingMapsGeocoderService.prototype, { + /** + * The URL endpoint for the Bing geocoder service + * @type {String} + * @memberof {BingMapsGeocoderService.prototype} + * @readonly + */ + url : { + get : function () { + return url; + } + }, + + /** + * The key for the Bing geocoder service + * @type {String} + * @memberof {BingMapsGeocoderService.prototype} + * @readonly + */ + key : { + get : function () { + return this._key; + } + } + }); /** - * The index into Matrix3 for column 2, row 1. + * @function * - * @type {Number} - * @constant + * @param {String} query The query to be sent to the geocoder service + * @returns {Promise<GeocoderResult[]>} */ - Matrix3.COLUMN2ROW1 = 7; + BingMapsGeocoderService.prototype.geocode = function(query) { + Check.typeOf.string('query', query); + + var resource = this._resource.getDerivedResource({ + queryParameters: { + query: query + } + }); + + return resource.fetchJsonp('jsonp').then(function(result) { + if (result.resourceSets.length === 0) { + return []; + } + + var results = result.resourceSets[0].resources; + + return results.map(function (resource) { + var bbox = resource.bbox; + var south = bbox[0]; + var west = bbox[1]; + var north = bbox[2]; + var east = bbox[3]; + return { + displayName: resource.name, + destination: Rectangle.fromDegrees(west, south, east, north) + }; + }); + }); + }; + + return BingMapsGeocoderService; +}); + +define('Core/GeographicProjection',[ + './Cartesian3', + './Cartographic', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Ellipsoid' + ], function( + Cartesian3, + Cartographic, + defaultValue, + defined, + defineProperties, + DeveloperError, + Ellipsoid) { + 'use strict'; /** - * The index into Matrix3 for column 2, row 2. + * A simple map projection where longitude and latitude are linearly mapped to X and Y by multiplying + * them by the {@link Ellipsoid#maximumRadius}. This projection + * is commonly known as geographic, equirectangular, equidistant cylindrical, or plate carrée. It + * is also known as EPSG:4326. * - * @type {Number} - * @constant + * @alias GeographicProjection + * @constructor + * + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid. + * + * @see WebMercatorProjection */ - Matrix3.COLUMN2ROW2 = 8; + function GeographicProjection(ellipsoid) { + this._ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + this._semimajorAxis = this._ellipsoid.maximumRadius; + this._oneOverSemimajorAxis = 1.0 / this._semimajorAxis; + } - defineProperties(Matrix3.prototype, { + defineProperties(GeographicProjection.prototype, { /** - * Gets the number of items in the collection. - * @memberof Matrix3.prototype + * Gets the {@link Ellipsoid}. * - * @type {Number} + * @memberof GeographicProjection.prototype + * + * @type {Ellipsoid} + * @readonly */ - length : { + ellipsoid : { get : function() { - return Matrix3.packedLength; + return this._ellipsoid; } } }); /** - * Duplicates the provided Matrix3 instance. + * Projects a set of {@link Cartographic} coordinates, in radians, to map coordinates, in meters. + * X and Y are the longitude and latitude, respectively, multiplied by the maximum radius of the + * ellipsoid. Z is the unmodified height. * - * @param {Matrix3} [result] The object onto which to store the result. - * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. + * @param {Cartographic} cartographic The coordinates to project. + * @param {Cartesian3} [result] An instance into which to copy the result. If this parameter is + * undefined, a new instance is created and returned. + * @returns {Cartesian3} The projected coordinates. If the result parameter is not undefined, the + * coordinates are copied there and that instance is returned. Otherwise, a new instance is + * created and returned. */ - Matrix3.prototype.clone = function(result) { - return Matrix3.clone(this, result); - }; + GeographicProjection.prototype.project = function(cartographic, result) { + // Actually this is the special case of equidistant cylindrical called the plate carree + var semimajorAxis = this._semimajorAxis; + var x = cartographic.longitude * semimajorAxis; + var y = cartographic.latitude * semimajorAxis; + var z = cartographic.height; - /** - * Compares this matrix to the provided matrix componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Matrix3} [right] The right hand side matrix. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - Matrix3.prototype.equals = function(right) { - return Matrix3.equals(this, right); - }; + if (!defined(result)) { + return new Cartesian3(x, y, z); + } - /** - * @private - */ - Matrix3.equalsArray = function(matrix, array, offset) { - return matrix[0] === array[offset] && - matrix[1] === array[offset + 1] && - matrix[2] === array[offset + 2] && - matrix[3] === array[offset + 3] && - matrix[4] === array[offset + 4] && - matrix[5] === array[offset + 5] && - matrix[6] === array[offset + 6] && - matrix[7] === array[offset + 7] && - matrix[8] === array[offset + 8]; + result.x = x; + result.y = y; + result.z = z; + return result; }; /** - * Compares this matrix to the provided matrix componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. + * Unprojects a set of projected {@link Cartesian3} coordinates, in meters, to {@link Cartographic} + * coordinates, in radians. Longitude and Latitude are the X and Y coordinates, respectively, + * divided by the maximum radius of the ellipsoid. Height is the unmodified Z coordinate. * - * @param {Matrix3} [right] The right hand side matrix. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {Cartesian3} cartesian The Cartesian position to unproject with height (z) in meters. + * @param {Cartographic} [result] An instance into which to copy the result. If this parameter is + * undefined, a new instance is created and returned. + * @returns {Cartographic} The unprojected coordinates. If the result parameter is not undefined, the + * coordinates are copied there and that instance is returned. Otherwise, a new instance is + * created and returned. */ - Matrix3.prototype.equalsEpsilon = function(right, epsilon) { - return Matrix3.equalsEpsilon(this, right, epsilon); - }; + GeographicProjection.prototype.unproject = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required'); + } + + var oneOverEarthSemimajorAxis = this._oneOverSemimajorAxis; + var longitude = cartesian.x * oneOverEarthSemimajorAxis; + var latitude = cartesian.y * oneOverEarthSemimajorAxis; + var height = cartesian.z; - /** - * Creates a string representing this Matrix with each row being - * on a separate line and in the format '(column0, column1, column2)'. - * - * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2)'. - */ - Matrix3.prototype.toString = function() { - return '(' + this[0] + ', ' + this[3] + ', ' + this[6] + ')\n' + - '(' + this[1] + ', ' + this[4] + ', ' + this[7] + ')\n' + - '(' + this[2] + ', ' + this[5] + ', ' + this[8] + ')'; + if (!defined(result)) { + return new Cartographic(longitude, latitude, height); + } + + result.longitude = longitude; + result.latitude = latitude; + result.height = height; + return result; }; - return Matrix3; + return GeographicProjection; }); -define('Core/Cartesian4',[ +define('Core/BoundingRectangle',[ + './Cartesian2', + './Cartographic', './Check', './defaultValue', './defined', - './DeveloperError', - './freezeObject', - './Math' + './GeographicProjection', + './Intersect', + './Rectangle' ], function( + Cartesian2, + Cartographic, Check, defaultValue, defined, - DeveloperError, - freezeObject, - CesiumMath) { + GeographicProjection, + Intersect, + Rectangle) { 'use strict'; /** - * A 4D Cartesian point. - * @alias Cartesian4 + * A bounding rectangle given by a corner, width and height. + * @alias BoundingRectangle * @constructor * - * @param {Number} [x=0.0] The X component. - * @param {Number} [y=0.0] The Y component. - * @param {Number} [z=0.0] The Z component. - * @param {Number} [w=0.0] The W component. + * @param {Number} [x=0.0] The x coordinate of the rectangle. + * @param {Number} [y=0.0] The y coordinate of the rectangle. + * @param {Number} [width=0.0] The width of the rectangle. + * @param {Number} [height=0.0] The height of the rectangle. * - * @see Cartesian2 - * @see Cartesian3 + * @see BoundingSphere * @see Packable */ - function Cartesian4(x, y, z, w) { + function BoundingRectangle(x, y, width, height) { /** - * The X component. + * The x coordinate of the rectangle. * @type {Number} * @default 0.0 */ this.x = defaultValue(x, 0.0); /** - * The Y component. + * The y coordinate of the rectangle. * @type {Number} * @default 0.0 */ this.y = defaultValue(y, 0.0); /** - * The Z component. + * The width of the rectangle. * @type {Number} * @default 0.0 */ - this.z = defaultValue(z, 0.0); + this.width = defaultValue(width, 0.0); /** - * The W component. + * The height of the rectangle. * @type {Number} * @default 0.0 */ - this.w = defaultValue(w, 0.0); + this.height = defaultValue(height, 0.0); } - /** - * Creates a Cartesian4 instance from x, y, z and w coordinates. - * - * @param {Number} x The x coordinate. - * @param {Number} y The y coordinate. - * @param {Number} z The z coordinate. - * @param {Number} w The w coordinate. - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. - */ - Cartesian4.fromElements = function(x, y, z, w, result) { - if (!defined(result)) { - return new Cartesian4(x, y, z, w); - } - - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; - }; - - /** - * Creates a Cartesian4 instance from a {@link Color}. <code>red</code>, <code>green</code>, <code>blue</code>, - * and <code>alpha</code> map to <code>x</code>, <code>y</code>, <code>z</code>, and <code>w</code>, respectively. - * - * @param {Color} color The source color. - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. - */ - Cartesian4.fromColor = function(color, result) { - Check.typeOf.object('color', color); - if (!defined(result)) { - return new Cartesian4(color.red, color.green, color.blue, color.alpha); - } - - result.x = color.red; - result.y = color.green; - result.z = color.blue; - result.w = color.alpha; - return result; - }; - - /** - * Duplicates a Cartesian4 instance. - * - * @param {Cartesian4} cartesian The Cartesian to duplicate. - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. (Returns undefined if cartesian is undefined) - */ - Cartesian4.clone = function(cartesian, result) { - if (!defined(cartesian)) { - return undefined; - } - - if (!defined(result)) { - return new Cartesian4(cartesian.x, cartesian.y, cartesian.z, cartesian.w); - } - - result.x = cartesian.x; - result.y = cartesian.y; - result.z = cartesian.z; - result.w = cartesian.w; - return result; - }; - - /** * The number of elements used to pack the object into an array. * @type {Number} */ - Cartesian4.packedLength = 4; + BoundingRectangle.packedLength = 4; /** * Stores the provided instance into the provided array. * - * @param {Cartesian4} value The value to pack. + * @param {BoundingRectangle} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - Cartesian4.pack = function(value, array, startingIndex) { + BoundingRectangle.pack = function(value, array, startingIndex) { Check.typeOf.object('value', value); Check.defined('array', array); @@ -11206,8 +12178,8 @@ define('Core/Cartesian4',[ array[startingIndex++] = value.x; array[startingIndex++] = value.y; - array[startingIndex++] = value.z; - array[startingIndex] = value.w; + array[startingIndex++] = value.width; + array[startingIndex] = value.height; return array; }; @@ -11217,794 +12189,377 @@ define('Core/Cartesian4',[ * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Cartesian4} [result] The object into which to store the result. - * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. + * @param {BoundingRectangle} [result] The object into which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ - Cartesian4.unpack = function(array, startingIndex, result) { + BoundingRectangle.unpack = function(array, startingIndex, result) { Check.defined('array', array); startingIndex = defaultValue(startingIndex, 0); if (!defined(result)) { - result = new Cartesian4(); + result = new BoundingRectangle(); } result.x = array[startingIndex++]; result.y = array[startingIndex++]; - result.z = array[startingIndex++]; - result.w = array[startingIndex]; + result.width = array[startingIndex++]; + result.height = array[startingIndex]; return result; }; /** - * Flattens an array of Cartesian4s into and array of components. + * Computes a bounding rectangle enclosing the list of 2D points. + * The rectangle is oriented with the corner at the bottom left. * - * @param {Cartesian4[]} array The array of cartesians to pack. - * @param {Number[]} result The array onto which to store the result. - * @returns {Number[]} The packed array. + * @param {Cartesian2[]} positions List of points that the bounding rectangle will enclose. Each point must have <code>x</code> and <code>y</code> properties. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ - Cartesian4.packArray = function(array, result) { - Check.defined('array', array); - - var length = array.length; + BoundingRectangle.fromPoints = function(positions, result) { if (!defined(result)) { - result = new Array(length * 4); - } else { - result.length = length * 4; + result = new BoundingRectangle(); } - for (var i = 0; i < length; ++i) { - Cartesian4.pack(array[i], result, i * 4); + if (!defined(positions) || positions.length === 0) { + result.x = 0; + result.y = 0; + result.width = 0; + result.height = 0; + return result; + } + + var length = positions.length; + + var minimumX = positions[0].x; + var minimumY = positions[0].y; + + var maximumX = positions[0].x; + var maximumY = positions[0].y; + + for ( var i = 1; i < length; i++) { + var p = positions[i]; + var x = p.x; + var y = p.y; + + minimumX = Math.min(x, minimumX); + maximumX = Math.max(x, maximumX); + minimumY = Math.min(y, minimumY); + maximumY = Math.max(y, maximumY); } + + result.x = minimumX; + result.y = minimumY; + result.width = maximumX - minimumX; + result.height = maximumY - minimumY; return result; }; + var defaultProjection = new GeographicProjection(); + var fromRectangleLowerLeft = new Cartographic(); + var fromRectangleUpperRight = new Cartographic(); /** - * Unpacks an array of cartesian components into and array of Cartesian4s. + * Computes a bounding rectangle from a rectangle. * - * @param {Number[]} array The array of components to unpack. - * @param {Cartesian4[]} result The array onto which to store the result. - * @returns {Cartesian4[]} The unpacked array. + * @param {Rectangle} rectangle The valid rectangle used to create a bounding rectangle. + * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ - Cartesian4.unpackArray = function(array, result) { - Check.defined('array', array); - - var length = array.length; + BoundingRectangle.fromRectangle = function(rectangle, projection, result) { if (!defined(result)) { - result = new Array(length / 4); - } else { - result.length = length / 4; + result = new BoundingRectangle(); } - for (var i = 0; i < length; i += 4) { - var index = i / 4; - result[index] = Cartesian4.unpack(array, i, result[index]); + if (!defined(rectangle)) { + result.x = 0; + result.y = 0; + result.width = 0; + result.height = 0; + return result; } + + projection = defaultValue(projection, defaultProjection); + + var lowerLeft = projection.project(Rectangle.southwest(rectangle, fromRectangleLowerLeft)); + var upperRight = projection.project(Rectangle.northeast(rectangle, fromRectangleUpperRight)); + + Cartesian2.subtract(upperRight, lowerLeft, upperRight); + + result.x = lowerLeft.x; + result.y = lowerLeft.y; + result.width = upperRight.x; + result.height = upperRight.y; return result; }; /** - * Creates a Cartesian4 from four consecutive elements in an array. - * @function - * - * @param {Number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. - * - * @example - * // Create a Cartesian4 with (1.0, 2.0, 3.0, 4.0) - * var v = [1.0, 2.0, 3.0, 4.0]; - * var p = Cesium.Cartesian4.fromArray(v); + * Duplicates a BoundingRectangle instance. * - * // Create a Cartesian4 with (1.0, 2.0, 3.0, 4.0) using an offset into an array - * var v2 = [0.0, 0.0, 1.0, 2.0, 3.0, 4.0]; - * var p2 = Cesium.Cartesian4.fromArray(v2, 2); + * @param {BoundingRectangle} rectangle The bounding rectangle to duplicate. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. (Returns undefined if rectangle is undefined) */ - Cartesian4.fromArray = Cartesian4.unpack; + BoundingRectangle.clone = function(rectangle, result) { + if (!defined(rectangle)) { + return undefined; + } - /** - * Computes the value of the maximum component for the supplied Cartesian. - * - * @param {Cartesian4} cartesian The cartesian to use. - * @returns {Number} The value of the maximum component. - */ - Cartesian4.maximumComponent = function(cartesian) { - Check.typeOf.object('cartesian', cartesian); - - return Math.max(cartesian.x, cartesian.y, cartesian.z, cartesian.w); - }; - - /** - * Computes the value of the minimum component for the supplied Cartesian. - * - * @param {Cartesian4} cartesian The cartesian to use. - * @returns {Number} The value of the minimum component. - */ - Cartesian4.minimumComponent = function(cartesian) { - Check.typeOf.object('cartesian', cartesian); - - return Math.min(cartesian.x, cartesian.y, cartesian.z, cartesian.w); - }; - - /** - * Compares two Cartesians and computes a Cartesian which contains the minimum components of the supplied Cartesians. - * - * @param {Cartesian4} first A cartesian to compare. - * @param {Cartesian4} second A cartesian to compare. - * @param {Cartesian4} result The object into which to store the result. - * @returns {Cartesian4} A cartesian with the minimum components. - */ - Cartesian4.minimumByComponent = function(first, second, result) { - Check.typeOf.object('first', first); - Check.typeOf.object('second', second); - Check.typeOf.object('result', result); - - result.x = Math.min(first.x, second.x); - result.y = Math.min(first.y, second.y); - result.z = Math.min(first.z, second.z); - result.w = Math.min(first.w, second.w); - - return result; - }; - - /** - * Compares two Cartesians and computes a Cartesian which contains the maximum components of the supplied Cartesians. - * - * @param {Cartesian4} first A cartesian to compare. - * @param {Cartesian4} second A cartesian to compare. - * @param {Cartesian4} result The object into which to store the result. - * @returns {Cartesian4} A cartesian with the maximum components. - */ - Cartesian4.maximumByComponent = function(first, second, result) { - Check.typeOf.object('first', first); - Check.typeOf.object('second', second); - Check.typeOf.object('result', result); - - result.x = Math.max(first.x, second.x); - result.y = Math.max(first.y, second.y); - result.z = Math.max(first.z, second.z); - result.w = Math.max(first.w, second.w); + if (!defined(result)) { + return new BoundingRectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height); + } + result.x = rectangle.x; + result.y = rectangle.y; + result.width = rectangle.width; + result.height = rectangle.height; return result; }; /** - * Computes the provided Cartesian's squared magnitude. - * - * @param {Cartesian4} cartesian The Cartesian instance whose squared magnitude is to be computed. - * @returns {Number} The squared magnitude. - */ - Cartesian4.magnitudeSquared = function(cartesian) { - Check.typeOf.object('cartesian', cartesian); - - return cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z + cartesian.w * cartesian.w; - }; - - /** - * Computes the Cartesian's magnitude (length). - * - * @param {Cartesian4} cartesian The Cartesian instance whose magnitude is to be computed. - * @returns {Number} The magnitude. - */ - Cartesian4.magnitude = function(cartesian) { - return Math.sqrt(Cartesian4.magnitudeSquared(cartesian)); - }; - - var distanceScratch = new Cartesian4(); - - /** - * Computes the 4-space distance between two points. - * - * @param {Cartesian4} left The first point to compute the distance from. - * @param {Cartesian4} right The second point to compute the distance to. - * @returns {Number} The distance between two points. - * - * @example - * // Returns 1.0 - * var d = Cesium.Cartesian4.distance( - * new Cesium.Cartesian4(1.0, 0.0, 0.0, 0.0), - * new Cesium.Cartesian4(2.0, 0.0, 0.0, 0.0)); - */ - Cartesian4.distance = function(left, right) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - - Cartesian4.subtract(left, right, distanceScratch); - return Cartesian4.magnitude(distanceScratch); - }; - - /** - * Computes the squared distance between two points. Comparing squared distances - * using this function is more efficient than comparing distances using {@link Cartesian4#distance}. - * - * @param {Cartesian4} left The first point to compute the distance from. - * @param {Cartesian4} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * Computes a bounding rectangle that is the union of the left and right bounding rectangles. * - * @example - * // Returns 4.0, not 2.0 - * var d = Cesium.Cartesian4.distance( - * new Cesium.Cartesian4(1.0, 0.0, 0.0, 0.0), - * new Cesium.Cartesian4(3.0, 0.0, 0.0, 0.0)); + * @param {BoundingRectangle} left A rectangle to enclose in bounding rectangle. + * @param {BoundingRectangle} right A rectangle to enclose in a bounding rectangle. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ - Cartesian4.distanceSquared = function(left, right) { + BoundingRectangle.union = function(left, right, result) { Check.typeOf.object('left', left); Check.typeOf.object('right', right); - Cartesian4.subtract(left, right, distanceScratch); - return Cartesian4.magnitudeSquared(distanceScratch); - }; - - /** - * Computes the normalized form of the supplied Cartesian. - * - * @param {Cartesian4} cartesian The Cartesian to be normalized. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.normalize = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var magnitude = Cartesian4.magnitude(cartesian); - - result.x = cartesian.x / magnitude; - result.y = cartesian.y / magnitude; - result.z = cartesian.z / magnitude; - result.w = cartesian.w / magnitude; - - if (isNaN(result.x) || isNaN(result.y) || isNaN(result.z) || isNaN(result.w)) { - throw new DeveloperError('normalized result is not a number'); + if (!defined(result)) { + result = new BoundingRectangle(); } - - return result; - }; - - /** - * Computes the dot (scalar) product of two Cartesians. - * - * @param {Cartesian4} left The first Cartesian. - * @param {Cartesian4} right The second Cartesian. - * @returns {Number} The dot product. - */ - Cartesian4.dot = function(left, right) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - - return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; - }; - - /** - * Computes the componentwise product of two Cartesians. - * - * @param {Cartesian4} left The first Cartesian. - * @param {Cartesian4} right The second Cartesian. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.multiplyComponents = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.x = left.x * right.x; - result.y = left.y * right.y; - result.z = left.z * right.z; - result.w = left.w * right.w; - return result; - }; - /** - * Computes the componentwise quotient of two Cartesians. - * - * @param {Cartesian4} left The first Cartesian. - * @param {Cartesian4} right The second Cartesian. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.divideComponents = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.x = left.x / right.x; - result.y = left.y / right.y; - result.z = left.z / right.z; - result.w = left.w / right.w; - return result; - }; + var lowerLeftX = Math.min(left.x, right.x); + var lowerLeftY = Math.min(left.y, right.y); + var upperRightX = Math.max(left.x + left.width, right.x + right.width); + var upperRightY = Math.max(left.y + left.height, right.y + right.height); - /** - * Computes the componentwise sum of two Cartesians. - * - * @param {Cartesian4} left The first Cartesian. - * @param {Cartesian4} right The second Cartesian. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.add = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.x = left.x + right.x; - result.y = left.y + right.y; - result.z = left.z + right.z; - result.w = left.w + right.w; + result.x = lowerLeftX; + result.y = lowerLeftY; + result.width = upperRightX - lowerLeftX; + result.height = upperRightY - lowerLeftY; return result; }; /** - * Computes the componentwise difference of two Cartesians. + * Computes a bounding rectangle by enlarging the provided rectangle until it contains the provided point. * - * @param {Cartesian4} left The first Cartesian. - * @param {Cartesian4} right The second Cartesian. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. + * @param {BoundingRectangle} rectangle A rectangle to expand. + * @param {Cartesian2} point A point to enclose in a bounding rectangle. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ - Cartesian4.subtract = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); + BoundingRectangle.expand = function(rectangle, point, result) { + Check.typeOf.object('rectangle', rectangle); + Check.typeOf.object('point', point); - result.x = left.x - right.x; - result.y = left.y - right.y; - result.z = left.z - right.z; - result.w = left.w - right.w; - return result; - }; + result = BoundingRectangle.clone(rectangle, result); - /** - * Multiplies the provided Cartesian componentwise by the provided scalar. - * - * @param {Cartesian4} cartesian The Cartesian to be scaled. - * @param {Number} scalar The scalar to multiply with. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.multiplyByScalar = function(cartesian, scalar, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result.x = cartesian.x * scalar; - result.y = cartesian.y * scalar; - result.z = cartesian.z * scalar; - result.w = cartesian.w * scalar; - return result; - }; + var width = point.x - result.x; + var height = point.y - result.y; - /** - * Divides the provided Cartesian componentwise by the provided scalar. - * - * @param {Cartesian4} cartesian The Cartesian to be divided. - * @param {Number} scalar The scalar to divide by. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.divideByScalar = function(cartesian, scalar, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result.x = cartesian.x / scalar; - result.y = cartesian.y / scalar; - result.z = cartesian.z / scalar; - result.w = cartesian.w / scalar; - return result; - }; + if (width > result.width) { + result.width = width; + } else if (width < 0) { + result.width -= width; + result.x = point.x; + } - /** - * Negates the provided Cartesian. - * - * @param {Cartesian4} cartesian The Cartesian to be negated. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.negate = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - result.x = -cartesian.x; - result.y = -cartesian.y; - result.z = -cartesian.z; - result.w = -cartesian.w; - return result; - }; + if (height > result.height) { + result.height = height; + } else if (height < 0) { + result.height -= height; + result.y = point.y; + } - /** - * Computes the absolute value of the provided Cartesian. - * - * @param {Cartesian4} cartesian The Cartesian whose absolute value is to be computed. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.abs = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - result.x = Math.abs(cartesian.x); - result.y = Math.abs(cartesian.y); - result.z = Math.abs(cartesian.z); - result.w = Math.abs(cartesian.w); return result; }; - var lerpScratch = new Cartesian4(); - /** - * Computes the linear interpolation or extrapolation at t using the provided cartesians. - * - * @param {Cartesian4} start The value corresponding to t at 0.0. - * @param {Cartesian4}end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Cartesian4.lerp = function(start, end, t, result) { - Check.typeOf.object('start', start); - Check.typeOf.object('end', end); - Check.typeOf.number('t', t); - Check.typeOf.object('result', result); - - Cartesian4.multiplyByScalar(end, t, lerpScratch); - result = Cartesian4.multiplyByScalar(start, 1.0 - t, result); - return Cartesian4.add(lerpScratch, result, result); - }; - - var mostOrthogonalAxisScratch = new Cartesian4(); /** - * Returns the axis that is most orthogonal to the provided Cartesian. + * Determines if two rectangles intersect. * - * @param {Cartesian4} cartesian The Cartesian on which to find the most orthogonal axis. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The most orthogonal axis. + * @param {BoundingRectangle} left A rectangle to check for intersection. + * @param {BoundingRectangle} right The other rectangle to check for intersection. + * @returns {Intersect} <code>Intersect.INTESECTING</code> if the rectangles intersect, <code>Intersect.OUTSIDE</code> otherwise. */ - Cartesian4.mostOrthogonalAxis = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); + BoundingRectangle.intersect = function(left, right) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); - var f = Cartesian4.normalize(cartesian, mostOrthogonalAxisScratch); - Cartesian4.abs(f, f); - - if (f.x <= f.y) { - if (f.x <= f.z) { - if (f.x <= f.w) { - result = Cartesian4.clone(Cartesian4.UNIT_X, result); - } else { - result = Cartesian4.clone(Cartesian4.UNIT_W, result); - } - } else if (f.z <= f.w) { - result = Cartesian4.clone(Cartesian4.UNIT_Z, result); - } else { - result = Cartesian4.clone(Cartesian4.UNIT_W, result); - } - } else if (f.y <= f.z) { - if (f.y <= f.w) { - result = Cartesian4.clone(Cartesian4.UNIT_Y, result); - } else { - result = Cartesian4.clone(Cartesian4.UNIT_W, result); - } - } else if (f.z <= f.w) { - result = Cartesian4.clone(Cartesian4.UNIT_Z, result); - } else { - result = Cartesian4.clone(Cartesian4.UNIT_W, result); + var leftX = left.x; + var leftY = left.y; + var rightX = right.x; + var rightY = right.y; + if (!(leftX > rightX + right.width || + leftX + left.width < rightX || + leftY + left.height < rightY || + leftY > rightY + right.height)) { + return Intersect.INTERSECTING; } - return result; + return Intersect.OUTSIDE; }; /** - * Compares the provided Cartesians componentwise and returns + * Compares the provided BoundingRectangles componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {Cartesian4} [left] The first Cartesian. - * @param {Cartesian4} [right] The second Cartesian. + * @param {BoundingRectangle} [left] The first BoundingRectangle. + * @param {BoundingRectangle} [right] The second BoundingRectangle. * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - Cartesian4.equals = function(left, right) { + BoundingRectangle.equals = function(left, right) { return (left === right) || ((defined(left)) && (defined(right)) && (left.x === right.x) && (left.y === right.y) && - (left.z === right.z) && - (left.w === right.w)); - }; - - /** - * @private - */ - Cartesian4.equalsArray = function(cartesian, array, offset) { - return cartesian.x === array[offset] && - cartesian.y === array[offset + 1] && - cartesian.z === array[offset + 2] && - cartesian.w === array[offset + 3]; + (left.width === right.width) && + (left.height === right.height)); }; /** - * Compares the provided Cartesians componentwise and returns - * <code>true</code> if they pass an absolute or relative tolerance test, - * <code>false</code> otherwise. + * Duplicates this BoundingRectangle instance. * - * @param {Cartesian4} [left] The first Cartesian. - * @param {Cartesian4} [right] The second Cartesian. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ - Cartesian4.equalsEpsilon = function(left, right, relativeEpsilon, absoluteEpsilon) { - return (left === right) || - (defined(left) && - defined(right) && - CesiumMath.equalsEpsilon(left.x, right.x, relativeEpsilon, absoluteEpsilon) && - CesiumMath.equalsEpsilon(left.y, right.y, relativeEpsilon, absoluteEpsilon) && - CesiumMath.equalsEpsilon(left.z, right.z, relativeEpsilon, absoluteEpsilon) && - CesiumMath.equalsEpsilon(left.w, right.w, relativeEpsilon, absoluteEpsilon)); + BoundingRectangle.prototype.clone = function(result) { + return BoundingRectangle.clone(this, result); }; /** - * An immutable Cartesian4 instance initialized to (0.0, 0.0, 0.0, 0.0). - * - * @type {Cartesian4} - * @constant - */ - Cartesian4.ZERO = freezeObject(new Cartesian4(0.0, 0.0, 0.0, 0.0)); - - /** - * An immutable Cartesian4 instance initialized to (1.0, 0.0, 0.0, 0.0). - * - * @type {Cartesian4} - * @constant - */ - Cartesian4.UNIT_X = freezeObject(new Cartesian4(1.0, 0.0, 0.0, 0.0)); - - /** - * An immutable Cartesian4 instance initialized to (0.0, 1.0, 0.0, 0.0). - * - * @type {Cartesian4} - * @constant - */ - Cartesian4.UNIT_Y = freezeObject(new Cartesian4(0.0, 1.0, 0.0, 0.0)); - - /** - * An immutable Cartesian4 instance initialized to (0.0, 0.0, 1.0, 0.0). - * - * @type {Cartesian4} - * @constant - */ - Cartesian4.UNIT_Z = freezeObject(new Cartesian4(0.0, 0.0, 1.0, 0.0)); - - /** - * An immutable Cartesian4 instance initialized to (0.0, 0.0, 0.0, 1.0). - * - * @type {Cartesian4} - * @constant - */ - Cartesian4.UNIT_W = freezeObject(new Cartesian4(0.0, 0.0, 0.0, 1.0)); - - /** - * Duplicates this Cartesian4 instance. + * Determines if this rectangle intersects with another. * - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. + * @param {BoundingRectangle} right A rectangle to check for intersection. + * @returns {Intersect} <code>Intersect.INTESECTING</code> if the rectangles intersect, <code>Intersect.OUTSIDE</code> otherwise. */ - Cartesian4.prototype.clone = function(result) { - return Cartesian4.clone(this, result); + BoundingRectangle.prototype.intersect = function(right) { + return BoundingRectangle.intersect(this, right); }; /** - * Compares this Cartesian against the provided Cartesian componentwise and returns + * Compares this BoundingRectangle against the provided BoundingRectangle componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {Cartesian4} [right] The right hand side Cartesian. + * @param {BoundingRectangle} [right] The right hand side BoundingRectangle. * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ - Cartesian4.prototype.equals = function(right) { - return Cartesian4.equals(this, right); - }; - - /** - * Compares this Cartesian against the provided Cartesian componentwise and returns - * <code>true</code> if they pass an absolute or relative tolerance test, - * <code>false</code> otherwise. - * - * @param {Cartesian4} [right] The right hand side Cartesian. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. - */ - Cartesian4.prototype.equalsEpsilon = function(right, relativeEpsilon, absoluteEpsilon) { - return Cartesian4.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); - }; - - /** - * Creates a string representing this Cartesian in the format '(x, y)'. - * - * @returns {String} A string representing the provided Cartesian in the format '(x, y)'. - */ - Cartesian4.prototype.toString = function() { - return '(' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ')'; + BoundingRectangle.prototype.equals = function(right) { + return BoundingRectangle.equals(this, right); }; - return Cartesian4; + return BoundingRectangle; }); -define('Core/RuntimeError',[ - './defined' +define('Core/Interval',[ + './defaultValue' ], function( - defined) { + defaultValue) { 'use strict'; /** - * Constructs an exception object that is thrown due to an error that can occur at runtime, e.g., - * out of memory, could not compile shader, etc. If a function may throw this - * exception, the calling code should be prepared to catch it. - * <br /><br /> - * On the other hand, a {@link DeveloperError} indicates an exception due - * to a developer error, e.g., invalid argument, that usually indicates a bug in the - * calling code. - * - * @alias RuntimeError + * Represents the closed interval [start, stop]. + * @alias Interval * @constructor - * @extends Error * - * @param {String} [message] The error message for this exception. - * - * @see DeveloperError + * @param {Number} [start=0.0] The beginning of the interval. + * @param {Number} [stop=0.0] The end of the interval. */ - function RuntimeError(message) { - /** - * 'RuntimeError' indicating that this exception was thrown due to a runtime error. - * @type {String} - * @readonly - */ - this.name = 'RuntimeError'; - + function Interval(start, stop) { /** - * The explanation for why this exception was thrown. - * @type {String} - * @readonly + * The beginning of the interval. + * @type {Number} + * @default 0.0 */ - this.message = message; - - //Browsers such as IE don't have a stack property until you actually throw the error. - var stack; - try { - throw new Error(); - } catch (e) { - stack = e.stack; - } - + this.start = defaultValue(start, 0.0); /** - * The stack trace of this exception, if available. - * @type {String} - * @readonly + * The end of the interval. + * @type {Number} + * @default 0.0 */ - this.stack = stack; - } - - if (defined(Object.create)) { - RuntimeError.prototype = Object.create(Error.prototype); - RuntimeError.prototype.constructor = RuntimeError; + this.stop = defaultValue(stop, 0.0); } - RuntimeError.prototype.toString = function() { - var str = this.name + ': ' + this.message; - - if (defined(this.stack)) { - str += '\n' + this.stack.toString(); - } - - return str; - }; - - return RuntimeError; + return Interval; }); -define('Core/Matrix4',[ +define('Core/Matrix3',[ './Cartesian3', - './Cartesian4', './Check', './defaultValue', './defined', './defineProperties', + './DeveloperError', './freezeObject', - './Math', - './Matrix3', - './RuntimeError' + './Math' ], function( Cartesian3, - Cartesian4, Check, defaultValue, defined, defineProperties, + DeveloperError, freezeObject, - CesiumMath, - Matrix3, - RuntimeError) { + CesiumMath) { 'use strict'; /** - * A 4x4 matrix, indexable as a column-major order array. + * A 3x3 matrix, indexable as a column-major order array. * Constructor parameters are in row-major order for code readability. - * @alias Matrix4 + * @alias Matrix3 * @constructor * * @param {Number} [column0Row0=0.0] The value for column 0, row 0. * @param {Number} [column1Row0=0.0] The value for column 1, row 0. * @param {Number} [column2Row0=0.0] The value for column 2, row 0. - * @param {Number} [column3Row0=0.0] The value for column 3, row 0. * @param {Number} [column0Row1=0.0] The value for column 0, row 1. * @param {Number} [column1Row1=0.0] The value for column 1, row 1. * @param {Number} [column2Row1=0.0] The value for column 2, row 1. - * @param {Number} [column3Row1=0.0] The value for column 3, row 1. * @param {Number} [column0Row2=0.0] The value for column 0, row 2. * @param {Number} [column1Row2=0.0] The value for column 1, row 2. * @param {Number} [column2Row2=0.0] The value for column 2, row 2. - * @param {Number} [column3Row2=0.0] The value for column 3, row 2. - * @param {Number} [column0Row3=0.0] The value for column 0, row 3. - * @param {Number} [column1Row3=0.0] The value for column 1, row 3. - * @param {Number} [column2Row3=0.0] The value for column 2, row 3. - * @param {Number} [column3Row3=0.0] The value for column 3, row 3. * - * @see Matrix4.fromColumnMajorArray - * @see Matrix4.fromRowMajorArray - * @see Matrix4.fromRotationTranslation - * @see Matrix4.fromTranslationRotationScale - * @see Matrix4.fromTranslationQuaternionRotationScale - * @see Matrix4.fromTranslation - * @see Matrix4.fromScale - * @see Matrix4.fromUniformScale - * @see Matrix4.fromCamera - * @see Matrix4.computePerspectiveFieldOfView - * @see Matrix4.computeOrthographicOffCenter - * @see Matrix4.computePerspectiveOffCenter - * @see Matrix4.computeInfinitePerspectiveOffCenter - * @see Matrix4.computeViewportTransformation - * @see Matrix4.computeView + * @see Matrix3.fromColumnMajorArray + * @see Matrix3.fromRowMajorArray + * @see Matrix3.fromQuaternion + * @see Matrix3.fromScale + * @see Matrix3.fromUniformScale * @see Matrix2 - * @see Matrix3 - * @see Packable + * @see Matrix4 */ - function Matrix4(column0Row0, column1Row0, column2Row0, column3Row0, - column0Row1, column1Row1, column2Row1, column3Row1, - column0Row2, column1Row2, column2Row2, column3Row2, - column0Row3, column1Row3, column2Row3, column3Row3) { + function Matrix3(column0Row0, column1Row0, column2Row0, + column0Row1, column1Row1, column2Row1, + column0Row2, column1Row2, column2Row2) { this[0] = defaultValue(column0Row0, 0.0); this[1] = defaultValue(column0Row1, 0.0); this[2] = defaultValue(column0Row2, 0.0); - this[3] = defaultValue(column0Row3, 0.0); - this[4] = defaultValue(column1Row0, 0.0); - this[5] = defaultValue(column1Row1, 0.0); - this[6] = defaultValue(column1Row2, 0.0); - this[7] = defaultValue(column1Row3, 0.0); - this[8] = defaultValue(column2Row0, 0.0); - this[9] = defaultValue(column2Row1, 0.0); - this[10] = defaultValue(column2Row2, 0.0); - this[11] = defaultValue(column2Row3, 0.0); - this[12] = defaultValue(column3Row0, 0.0); - this[13] = defaultValue(column3Row1, 0.0); - this[14] = defaultValue(column3Row2, 0.0); - this[15] = defaultValue(column3Row3, 0.0); + this[3] = defaultValue(column1Row0, 0.0); + this[4] = defaultValue(column1Row1, 0.0); + this[5] = defaultValue(column1Row2, 0.0); + this[6] = defaultValue(column2Row0, 0.0); + this[7] = defaultValue(column2Row1, 0.0); + this[8] = defaultValue(column2Row2, 0.0); } /** * The number of elements used to pack the object into an array. * @type {Number} */ - Matrix4.packedLength = 16; + Matrix3.packedLength = 9; /** * Stores the provided instance into the provided array. * - * @param {Matrix4} value The value to pack. + * @param {Matrix3} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - Matrix4.pack = function(value, array, startingIndex) { + Matrix3.pack = function(value, array, startingIndex) { Check.typeOf.object('value', value); Check.defined('array', array); @@ -12019,13 +12574,6 @@ define('Core/Matrix4',[ array[startingIndex++] = value[6]; array[startingIndex++] = value[7]; array[startingIndex++] = value[8]; - array[startingIndex++] = value[9]; - array[startingIndex++] = value[10]; - array[startingIndex++] = value[11]; - array[startingIndex++] = value[12]; - array[startingIndex++] = value[13]; - array[startingIndex++] = value[14]; - array[startingIndex] = value[15]; return array; }; @@ -12035,16 +12583,16 @@ define('Core/Matrix4',[ * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Matrix4} [result] The object into which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object into which to store the result. + * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. */ - Matrix4.unpack = function(array, startingIndex, result) { + Matrix3.unpack = function(array, startingIndex, result) { Check.defined('array', array); startingIndex = defaultValue(startingIndex, 0); if (!defined(result)) { - result = new Matrix4(); + result = new Matrix3(); } result[0] = array[startingIndex++]; @@ -12056,32 +12604,24 @@ define('Core/Matrix4',[ result[6] = array[startingIndex++]; result[7] = array[startingIndex++]; result[8] = array[startingIndex++]; - result[9] = array[startingIndex++]; - result[10] = array[startingIndex++]; - result[11] = array[startingIndex++]; - result[12] = array[startingIndex++]; - result[13] = array[startingIndex++]; - result[14] = array[startingIndex++]; - result[15] = array[startingIndex]; return result; }; /** - * Duplicates a Matrix4 instance. + * Duplicates a Matrix3 instance. * - * @param {Matrix4} matrix The matrix to duplicate. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. (Returns undefined if matrix is undefined) + * @param {Matrix3} matrix The matrix to duplicate. + * @param {Matrix3} [result] The object onto which to store the result. + * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. (Returns undefined if matrix is undefined) */ - Matrix4.clone = function(matrix, result) { + Matrix3.clone = function(matrix, result) { if (!defined(matrix)) { return undefined; } if (!defined(result)) { - return new Matrix4(matrix[0], matrix[4], matrix[8], matrix[12], - matrix[1], matrix[5], matrix[9], matrix[13], - matrix[2], matrix[6], matrix[10], matrix[14], - matrix[3], matrix[7], matrix[11], matrix[15]); + return new Matrix3(matrix[0], matrix[3], matrix[6], + matrix[1], matrix[4], matrix[7], + matrix[2], matrix[5], matrix[8]); } result[0] = matrix[0]; result[1] = matrix[1]; @@ -12092,170 +12632,112 @@ define('Core/Matrix4',[ result[6] = matrix[6]; result[7] = matrix[7]; result[8] = matrix[8]; - result[9] = matrix[9]; - result[10] = matrix[10]; - result[11] = matrix[11]; - result[12] = matrix[12]; - result[13] = matrix[13]; - result[14] = matrix[14]; - result[15] = matrix[15]; return result; }; /** - * Creates a Matrix4 from 16 consecutive elements in an array. - * @function + * Creates a Matrix3 from 9 consecutive elements in an array. * - * @param {Number[]} array The array whose 16 consecutive elements correspond to the positions of the matrix. Assumes column-major order. + * @param {Number[]} array The array whose 9 consecutive elements correspond to the positions of the matrix. Assumes column-major order. * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object onto which to store the result. + * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. * * @example - * // Create the Matrix4: - * // [1.0, 2.0, 3.0, 4.0] - * // [1.0, 2.0, 3.0, 4.0] - * // [1.0, 2.0, 3.0, 4.0] - * // [1.0, 2.0, 3.0, 4.0] + * // Create the Matrix3: + * // [1.0, 2.0, 3.0] + * // [1.0, 2.0, 3.0] + * // [1.0, 2.0, 3.0] * - * var v = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0]; - * var m = Cesium.Matrix4.fromArray(v); + * var v = [1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0]; + * var m = Cesium.Matrix3.fromArray(v); * - * // Create same Matrix4 with using an offset into an array - * var v2 = [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0]; - * var m2 = Cesium.Matrix4.fromArray(v2, 2); + * // Create same Matrix3 with using an offset into an array + * var v2 = [0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0]; + * var m2 = Cesium.Matrix3.fromArray(v2, 2); */ - Matrix4.fromArray = Matrix4.unpack; + Matrix3.fromArray = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new Matrix3(); + } + + result[0] = array[startingIndex]; + result[1] = array[startingIndex + 1]; + result[2] = array[startingIndex + 2]; + result[3] = array[startingIndex + 3]; + result[4] = array[startingIndex + 4]; + result[5] = array[startingIndex + 5]; + result[6] = array[startingIndex + 6]; + result[7] = array[startingIndex + 7]; + result[8] = array[startingIndex + 8]; + return result; + }; /** - * Computes a Matrix4 instance from a column-major order array. + * Creates a Matrix3 instance from a column-major order array. * * @param {Number[]} values The column-major order array. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. */ - Matrix4.fromColumnMajorArray = function(values, result) { + Matrix3.fromColumnMajorArray = function(values, result) { Check.defined('values', values); - return Matrix4.clone(values, result); + return Matrix3.clone(values, result); }; /** - * Computes a Matrix4 instance from a row-major order array. + * Creates a Matrix3 instance from a row-major order array. * The resulting matrix will be in column-major order. * * @param {Number[]} values The row-major order array. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. */ - Matrix4.fromRowMajorArray = function(values, result) { + Matrix3.fromRowMajorArray = function(values, result) { Check.defined('values', values); if (!defined(result)) { - return new Matrix4(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], - values[8], values[9], values[10], values[11], - values[12], values[13], values[14], values[15]); + return new Matrix3(values[0], values[1], values[2], + values[3], values[4], values[5], + values[6], values[7], values[8]); } result[0] = values[0]; - result[1] = values[4]; - result[2] = values[8]; - result[3] = values[12]; - result[4] = values[1]; - result[5] = values[5]; - result[6] = values[9]; - result[7] = values[13]; - result[8] = values[2]; - result[9] = values[6]; - result[10] = values[10]; - result[11] = values[14]; - result[12] = values[3]; - result[13] = values[7]; - result[14] = values[11]; - result[15] = values[15]; - return result; - }; - - /** - * Computes a Matrix4 instance from a Matrix3 representing the rotation - * and a Cartesian3 representing the translation. - * - * @param {Matrix3} rotation The upper left portion of the matrix representing the rotation. - * @param {Cartesian3} [translation=Cartesian3.ZERO] The upper right portion of the matrix representing the translation. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. - */ - Matrix4.fromRotationTranslation = function(rotation, translation, result) { - Check.typeOf.object('rotation', rotation); - - translation = defaultValue(translation, Cartesian3.ZERO); - - if (!defined(result)) { - return new Matrix4(rotation[0], rotation[3], rotation[6], translation.x, - rotation[1], rotation[4], rotation[7], translation.y, - rotation[2], rotation[5], rotation[8], translation.z, - 0.0, 0.0, 0.0, 1.0); - } - - result[0] = rotation[0]; - result[1] = rotation[1]; - result[2] = rotation[2]; - result[3] = 0.0; - result[4] = rotation[3]; - result[5] = rotation[4]; - result[6] = rotation[5]; - result[7] = 0.0; - result[8] = rotation[6]; - result[9] = rotation[7]; - result[10] = rotation[8]; - result[11] = 0.0; - result[12] = translation.x; - result[13] = translation.y; - result[14] = translation.z; - result[15] = 1.0; + result[1] = values[3]; + result[2] = values[6]; + result[3] = values[1]; + result[4] = values[4]; + result[5] = values[7]; + result[6] = values[2]; + result[7] = values[5]; + result[8] = values[8]; return result; }; /** - * Computes a Matrix4 instance from a translation, rotation, and scale (TRS) - * representation with the rotation represented as a quaternion. - * - * @param {Cartesian3} translation The translation transformation. - * @param {Quaternion} rotation The rotation transformation. - * @param {Cartesian3} scale The non-uniform scale transformation. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * Computes a 3x3 rotation matrix from the provided quaternion. * - * @example - * var result = Cesium.Matrix4.fromTranslationQuaternionRotationScale( - * new Cesium.Cartesian3(1.0, 2.0, 3.0), // translation - * Cesium.Quaternion.IDENTITY, // rotation - * new Cesium.Cartesian3(7.0, 8.0, 9.0), // scale - * result); + * @param {Quaternion} quaternion the quaternion to use. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The 3x3 rotation matrix from this quaternion. */ - Matrix4.fromTranslationQuaternionRotationScale = function(translation, rotation, scale, result) { - Check.typeOf.object('translation', translation); - Check.typeOf.object('rotation', rotation); - Check.typeOf.object('scale', scale); + Matrix3.fromQuaternion = function(quaternion, result) { + Check.typeOf.object('quaternion', quaternion); - if (!defined(result)) { - result = new Matrix4(); - } - - var scaleX = scale.x; - var scaleY = scale.y; - var scaleZ = scale.z; - - var x2 = rotation.x * rotation.x; - var xy = rotation.x * rotation.y; - var xz = rotation.x * rotation.z; - var xw = rotation.x * rotation.w; - var y2 = rotation.y * rotation.y; - var yz = rotation.y * rotation.z; - var yw = rotation.y * rotation.w; - var z2 = rotation.z * rotation.z; - var zw = rotation.z * rotation.w; - var w2 = rotation.w * rotation.w; + var x2 = quaternion.x * quaternion.x; + var xy = quaternion.x * quaternion.y; + var xz = quaternion.x * quaternion.z; + var xw = quaternion.x * quaternion.w; + var y2 = quaternion.y * quaternion.y; + var yz = quaternion.y * quaternion.z; + var yw = quaternion.y * quaternion.w; + var z2 = quaternion.z * quaternion.z; + var zw = quaternion.z * quaternion.w; + var w2 = quaternion.w * quaternion.w; var m00 = x2 - y2 - z2 + w2; var m01 = 2.0 * (xy - zw); @@ -12269,542 +12751,307 @@ define('Core/Matrix4',[ var m21 = 2.0 * (yz + xw); var m22 = -x2 - y2 + z2 + w2; - result[0] = m00 * scaleX; - result[1] = m10 * scaleX; - result[2] = m20 * scaleX; - result[3] = 0.0; - result[4] = m01 * scaleY; - result[5] = m11 * scaleY; - result[6] = m21 * scaleY; - result[7] = 0.0; - result[8] = m02 * scaleZ; - result[9] = m12 * scaleZ; - result[10] = m22 * scaleZ; - result[11] = 0.0; - result[12] = translation.x; - result[13] = translation.y; - result[14] = translation.z; - result[15] = 1.0; - + if (!defined(result)) { + return new Matrix3(m00, m01, m02, + m10, m11, m12, + m20, m21, m22); + } + result[0] = m00; + result[1] = m10; + result[2] = m20; + result[3] = m01; + result[4] = m11; + result[5] = m21; + result[6] = m02; + result[7] = m12; + result[8] = m22; return result; }; /** - * Creates a Matrix4 instance from a {@link TranslationRotationScale} instance. + * Computes a 3x3 rotation matrix from the provided headingPitchRoll. (see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles ) * - * @param {TranslationRotationScale} translationRotationScale The instance. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * @param {HeadingPitchRoll} headingPitchRoll the headingPitchRoll to use. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The 3x3 rotation matrix from this headingPitchRoll. */ - Matrix4.fromTranslationRotationScale = function(translationRotationScale, result) { - Check.typeOf.object('translationRotationScale', translationRotationScale); + Matrix3.fromHeadingPitchRoll = function(headingPitchRoll, result) { + Check.typeOf.object('headingPitchRoll', headingPitchRoll); - return Matrix4.fromTranslationQuaternionRotationScale(translationRotationScale.translation, translationRotationScale.rotation, translationRotationScale.scale, result); - }; + var cosTheta = Math.cos(-headingPitchRoll.pitch); + var cosPsi = Math.cos(-headingPitchRoll.heading); + var cosPhi = Math.cos(headingPitchRoll.roll); + var sinTheta = Math.sin(-headingPitchRoll.pitch); + var sinPsi = Math.sin(-headingPitchRoll.heading); + var sinPhi = Math.sin(headingPitchRoll.roll); - /** - * Creates a Matrix4 instance from a Cartesian3 representing the translation. - * - * @param {Cartesian3} translation The upper right portion of the matrix representing the translation. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. - * - * @see Matrix4.multiplyByTranslation - */ - Matrix4.fromTranslation = function(translation, result) { - Check.typeOf.object('translation', translation); - - return Matrix4.fromRotationTranslation(Matrix3.IDENTITY, translation, result); + var m00 = cosTheta * cosPsi; + var m01 = -cosPhi * sinPsi + sinPhi * sinTheta * cosPsi; + var m02 = sinPhi * sinPsi + cosPhi * sinTheta * cosPsi; + + var m10 = cosTheta * sinPsi; + var m11 = cosPhi * cosPsi + sinPhi * sinTheta * sinPsi; + var m12 = -sinPhi * cosPsi + cosPhi * sinTheta * sinPsi; + + var m20 = -sinTheta; + var m21 = sinPhi * cosTheta; + var m22 = cosPhi * cosTheta; + + if (!defined(result)) { + return new Matrix3(m00, m01, m02, + m10, m11, m12, + m20, m21, m22); + } + result[0] = m00; + result[1] = m10; + result[2] = m20; + result[3] = m01; + result[4] = m11; + result[5] = m21; + result[6] = m02; + result[7] = m12; + result[8] = m22; + return result; }; /** - * Computes a Matrix4 instance representing a non-uniform scale. + * Computes a Matrix3 instance representing a non-uniform scale. * * @param {Cartesian3} scale The x, y, and z scale factors. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * * @example * // Creates - * // [7.0, 0.0, 0.0, 0.0] - * // [0.0, 8.0, 0.0, 0.0] - * // [0.0, 0.0, 9.0, 0.0] - * // [0.0, 0.0, 0.0, 1.0] - * var m = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(7.0, 8.0, 9.0)); + * // [7.0, 0.0, 0.0] + * // [0.0, 8.0, 0.0] + * // [0.0, 0.0, 9.0] + * var m = Cesium.Matrix3.fromScale(new Cesium.Cartesian3(7.0, 8.0, 9.0)); */ - Matrix4.fromScale = function(scale, result) { + Matrix3.fromScale = function(scale, result) { Check.typeOf.object('scale', scale); if (!defined(result)) { - return new Matrix4( - scale.x, 0.0, 0.0, 0.0, - 0.0, scale.y, 0.0, 0.0, - 0.0, 0.0, scale.z, 0.0, - 0.0, 0.0, 0.0, 1.0); + return new Matrix3( + scale.x, 0.0, 0.0, + 0.0, scale.y, 0.0, + 0.0, 0.0, scale.z); } result[0] = scale.x; result[1] = 0.0; result[2] = 0.0; result[3] = 0.0; - result[4] = 0.0; - result[5] = scale.y; + result[4] = scale.y; + result[5] = 0.0; result[6] = 0.0; result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = scale.z; - result[11] = 0.0; - result[12] = 0.0; - result[13] = 0.0; - result[14] = 0.0; - result[15] = 1.0; + result[8] = scale.z; return result; }; /** - * Computes a Matrix4 instance representing a uniform scale. + * Computes a Matrix3 instance representing a uniform scale. * * @param {Number} scale The uniform scale factor. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * * @example * // Creates - * // [2.0, 0.0, 0.0, 0.0] - * // [0.0, 2.0, 0.0, 0.0] - * // [0.0, 0.0, 2.0, 0.0] - * // [0.0, 0.0, 0.0, 1.0] - * var m = Cesium.Matrix4.fromUniformScale(2.0); + * // [2.0, 0.0, 0.0] + * // [0.0, 2.0, 0.0] + * // [0.0, 0.0, 2.0] + * var m = Cesium.Matrix3.fromUniformScale(2.0); */ - Matrix4.fromUniformScale = function(scale, result) { + Matrix3.fromUniformScale = function(scale, result) { Check.typeOf.number('scale', scale); if (!defined(result)) { - return new Matrix4(scale, 0.0, 0.0, 0.0, - 0.0, scale, 0.0, 0.0, - 0.0, 0.0, scale, 0.0, - 0.0, 0.0, 0.0, 1.0); + return new Matrix3( + scale, 0.0, 0.0, + 0.0, scale, 0.0, + 0.0, 0.0, scale); } result[0] = scale; result[1] = 0.0; result[2] = 0.0; result[3] = 0.0; - result[4] = 0.0; - result[5] = scale; + result[4] = scale; + result[5] = 0.0; result[6] = 0.0; result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = scale; - result[11] = 0.0; - result[12] = 0.0; - result[13] = 0.0; - result[14] = 0.0; - result[15] = 1.0; + result[8] = scale; return result; }; - var fromCameraF = new Cartesian3(); - var fromCameraR = new Cartesian3(); - var fromCameraU = new Cartesian3(); - /** - * Computes a Matrix4 instance from a Camera. + * Computes a Matrix3 instance representing the cross product equivalent matrix of a Cartesian3 vector. * - * @param {Camera} camera The camera to use. - * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * @param {Cartesian3} vector the vector on the left hand side of the cross product operation. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * + * @example + * // Creates + * // [0.0, -9.0, 8.0] + * // [9.0, 0.0, -7.0] + * // [-8.0, 7.0, 0.0] + * var m = Cesium.Matrix3.fromCrossProduct(new Cesium.Cartesian3(7.0, 8.0, 9.0)); */ - Matrix4.fromCamera = function(camera, result) { - Check.typeOf.object('camera', camera); - - var position = camera.position; - var direction = camera.direction; - var up = camera.up; - - Check.typeOf.object('camera.position', position); - Check.typeOf.object('camera.direction', direction); - Check.typeOf.object('camera.up', up); + Matrix3.fromCrossProduct = function(vector, result) { + Check.typeOf.object('vector', vector); - Cartesian3.normalize(direction, fromCameraF); - Cartesian3.normalize(Cartesian3.cross(fromCameraF, up, fromCameraR), fromCameraR); - Cartesian3.normalize(Cartesian3.cross(fromCameraR, fromCameraF, fromCameraU), fromCameraU); - - var sX = fromCameraR.x; - var sY = fromCameraR.y; - var sZ = fromCameraR.z; - var fX = fromCameraF.x; - var fY = fromCameraF.y; - var fZ = fromCameraF.z; - var uX = fromCameraU.x; - var uY = fromCameraU.y; - var uZ = fromCameraU.z; - var positionX = position.x; - var positionY = position.y; - var positionZ = position.z; - var t0 = sX * -positionX + sY * -positionY+ sZ * -positionZ; - var t1 = uX * -positionX + uY * -positionY+ uZ * -positionZ; - var t2 = fX * positionX + fY * positionY + fZ * positionZ; - - // The code below this comment is an optimized - // version of the commented lines. - // Rather that create two matrices and then multiply, - // we just bake in the multiplcation as part of creation. - // var rotation = new Matrix4( - // sX, sY, sZ, 0.0, - // uX, uY, uZ, 0.0, - // -fX, -fY, -fZ, 0.0, - // 0.0, 0.0, 0.0, 1.0); - // var translation = new Matrix4( - // 1.0, 0.0, 0.0, -position.x, - // 0.0, 1.0, 0.0, -position.y, - // 0.0, 0.0, 1.0, -position.z, - // 0.0, 0.0, 0.0, 1.0); - // return rotation.multiply(translation); if (!defined(result)) { - return new Matrix4( - sX, sY, sZ, t0, - uX, uY, uZ, t1, - -fX, -fY, -fZ, t2, - 0.0, 0.0, 0.0, 1.0); + return new Matrix3( + 0.0, -vector.z, vector.y, + vector.z, 0.0, -vector.x, + -vector.y, vector.x, 0.0); } - result[0] = sX; - result[1] = uX; - result[2] = -fX; - result[3] = 0.0; - result[4] = sY; - result[5] = uY; - result[6] = -fY; - result[7] = 0.0; - result[8] = sZ; - result[9] = uZ; - result[10] = -fZ; - result[11] = 0.0; - result[12] = t0; - result[13] = t1; - result[14] = t2; - result[15] = 1.0; - return result; - }; - - /** - * Computes a Matrix4 instance representing a perspective transformation matrix. - * - * @param {Number} fovY The field of view along the Y axis in radians. - * @param {Number} aspectRatio The aspect ratio. - * @param {Number} near The distance to the near plane in meters. - * @param {Number} far The distance to the far plane in meters. - * @param {Matrix4} result The object in which the result will be stored. - * @returns {Matrix4} The modified result parameter. - * - * @exception {DeveloperError} fovY must be in (0, PI]. - * @exception {DeveloperError} aspectRatio must be greater than zero. - * @exception {DeveloperError} near must be greater than zero. - * @exception {DeveloperError} far must be greater than zero. - */ - Matrix4.computePerspectiveFieldOfView = function(fovY, aspectRatio, near, far, result) { - Check.typeOf.number.greaterThan('fovY', fovY, 0.0); - Check.typeOf.number.lessThan('fovY', fovY, Math.PI); - Check.typeOf.number.greaterThan('near', near, 0.0); - Check.typeOf.number.greaterThan('far', far, 0.0); - Check.typeOf.object('result', result); - - var bottom = Math.tan(fovY * 0.5); - var column1Row1 = 1.0 / bottom; - var column0Row0 = column1Row1 / aspectRatio; - var column2Row2 = (far + near) / (near - far); - var column3Row2 = (2.0 * far * near) / (near - far); - - result[0] = column0Row0; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = 0.0; - result[5] = column1Row1; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = column2Row2; - result[11] = -1.0; - result[12] = 0.0; - result[13] = 0.0; - result[14] = column3Row2; - result[15] = 0.0; - return result; - }; - - /** - * Computes a Matrix4 instance representing an orthographic transformation matrix. - * - * @param {Number} left The number of meters to the left of the camera that will be in view. - * @param {Number} right The number of meters to the right of the camera that will be in view. - * @param {Number} bottom The number of meters below of the camera that will be in view. - * @param {Number} top The number of meters above of the camera that will be in view. - * @param {Number} near The distance to the near plane in meters. - * @param {Number} far The distance to the far plane in meters. - * @param {Matrix4} result The object in which the result will be stored. - * @returns {Matrix4} The modified result parameter. - */ - Matrix4.computeOrthographicOffCenter = function(left, right, bottom, top, near, far, result) { - Check.typeOf.number('left', left); - Check.typeOf.number('right', right); - Check.typeOf.number('bottom', bottom); - Check.typeOf.number('top', top); - Check.typeOf.number('near', near); - Check.typeOf.number('far', far); - Check.typeOf.object('result', result); - - var a = 1.0 / (right - left); - var b = 1.0 / (top - bottom); - var c = 1.0 / (far - near); - - var tx = -(right + left) * a; - var ty = -(top + bottom) * b; - var tz = -(far + near) * c; - a *= 2.0; - b *= 2.0; - c *= -2.0; - - result[0] = a; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; + result[0] = 0.0; + result[1] = vector.z; + result[2] = -vector.y; + result[3] = -vector.z; result[4] = 0.0; - result[5] = b; - result[6] = 0.0; - result[7] = 0.0; + result[5] = vector.x; + result[6] = vector.y; + result[7] = -vector.x; result[8] = 0.0; - result[9] = 0.0; - result[10] = c; - result[11] = 0.0; - result[12] = tx; - result[13] = ty; - result[14] = tz; - result[15] = 1.0; return result; }; /** - * Computes a Matrix4 instance representing an off center perspective transformation. + * Creates a rotation matrix around the x-axis. * - * @param {Number} left The number of meters to the left of the camera that will be in view. - * @param {Number} right The number of meters to the right of the camera that will be in view. - * @param {Number} bottom The number of meters below of the camera that will be in view. - * @param {Number} top The number of meters above of the camera that will be in view. - * @param {Number} near The distance to the near plane in meters. - * @param {Number} far The distance to the far plane in meters. - * @param {Matrix4} result The object in which the result will be stored. - * @returns {Matrix4} The modified result parameter. + * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * + * @example + * // Rotate a point 45 degrees counterclockwise around the x-axis. + * var p = new Cesium.Cartesian3(5, 6, 7); + * var m = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(45.0)); + * var rotated = Cesium.Matrix3.multiplyByVector(m, p, new Cesium.Cartesian3()); */ - Matrix4.computePerspectiveOffCenter = function(left, right, bottom, top, near, far, result) { - Check.typeOf.number('left', left); - Check.typeOf.number('right', right); - Check.typeOf.number('bottom', bottom); - Check.typeOf.number('top', top); - Check.typeOf.number('near', near); - Check.typeOf.number('far', far); - Check.typeOf.object('result', result); + Matrix3.fromRotationX = function(angle, result) { + Check.typeOf.number('angle', angle); - var column0Row0 = 2.0 * near / (right - left); - var column1Row1 = 2.0 * near / (top - bottom); - var column2Row0 = (right + left) / (right - left); - var column2Row1 = (top + bottom) / (top - bottom); - var column2Row2 = -(far + near) / (far - near); - var column2Row3 = -1.0; - var column3Row2 = -2.0 * far * near / (far - near); + var cosAngle = Math.cos(angle); + var sinAngle = Math.sin(angle); - result[0] = column0Row0; + if (!defined(result)) { + return new Matrix3( + 1.0, 0.0, 0.0, + 0.0, cosAngle, -sinAngle, + 0.0, sinAngle, cosAngle); + } + + result[0] = 1.0; result[1] = 0.0; result[2] = 0.0; result[3] = 0.0; - result[4] = 0.0; - result[5] = column1Row1; + result[4] = cosAngle; + result[5] = sinAngle; result[6] = 0.0; - result[7] = 0.0; - result[8] = column2Row0; - result[9] = column2Row1; - result[10] = column2Row2; - result[11] = column2Row3; - result[12] = 0.0; - result[13] = 0.0; - result[14] = column3Row2; - result[15] = 0.0; + result[7] = -sinAngle; + result[8] = cosAngle; + return result; }; /** - * Computes a Matrix4 instance representing an infinite off center perspective transformation. + * Creates a rotation matrix around the y-axis. * - * @param {Number} left The number of meters to the left of the camera that will be in view. - * @param {Number} right The number of meters to the right of the camera that will be in view. - * @param {Number} bottom The number of meters below of the camera that will be in view. - * @param {Number} top The number of meters above of the camera that will be in view. - * @param {Number} near The distance to the near plane in meters. - * @param {Matrix4} result The object in which the result will be stored. - * @returns {Matrix4} The modified result parameter. + * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. + * + * @example + * // Rotate a point 45 degrees counterclockwise around the y-axis. + * var p = new Cesium.Cartesian3(5, 6, 7); + * var m = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(45.0)); + * var rotated = Cesium.Matrix3.multiplyByVector(m, p, new Cesium.Cartesian3()); */ - Matrix4.computeInfinitePerspectiveOffCenter = function(left, right, bottom, top, near, result) { - Check.typeOf.number('left', left); - Check.typeOf.number('right', right); - Check.typeOf.number('bottom', bottom); - Check.typeOf.number('top', top); - Check.typeOf.number('near', near); - Check.typeOf.object('result', result); + Matrix3.fromRotationY = function(angle, result) { + Check.typeOf.number('angle', angle); - var column0Row0 = 2.0 * near / (right - left); - var column1Row1 = 2.0 * near / (top - bottom); - var column2Row0 = (right + left) / (right - left); - var column2Row1 = (top + bottom) / (top - bottom); - var column2Row2 = -1.0; - var column2Row3 = -1.0; - var column3Row2 = -2.0 * near; + var cosAngle = Math.cos(angle); + var sinAngle = Math.sin(angle); - result[0] = column0Row0; + if (!defined(result)) { + return new Matrix3( + cosAngle, 0.0, sinAngle, + 0.0, 1.0, 0.0, + -sinAngle, 0.0, cosAngle); + } + + result[0] = cosAngle; result[1] = 0.0; - result[2] = 0.0; + result[2] = -sinAngle; result[3] = 0.0; - result[4] = 0.0; - result[5] = column1Row1; - result[6] = 0.0; + result[4] = 1.0; + result[5] = 0.0; + result[6] = sinAngle; result[7] = 0.0; - result[8] = column2Row0; - result[9] = column2Row1; - result[10] = column2Row2; - result[11] = column2Row3; - result[12] = 0.0; - result[13] = 0.0; - result[14] = column3Row2; - result[15] = 0.0; + result[8] = cosAngle; + return result; }; /** - * Computes a Matrix4 instance that transforms from normalized device coordinates to window coordinates. + * Creates a rotation matrix around the z-axis. * - * @param {Object}[viewport = { x : 0.0, y : 0.0, width : 0.0, height : 0.0 }] The viewport's corners as shown in Example 1. - * @param {Number}[nearDepthRange=0.0] The near plane distance in window coordinates. - * @param {Number}[farDepthRange=1.0] The far plane distance in window coordinates. - * @param {Matrix4} result The object in which the result will be stored. - * @returns {Matrix4} The modified result parameter. + * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * * @example - * // Create viewport transformation using an explicit viewport and depth range. - * var m = Cesium.Matrix4.computeViewportTransformation({ - * x : 0.0, - * y : 0.0, - * width : 1024.0, - * height : 768.0 - * }, 0.0, 1.0, new Cesium.Matrix4()); + * // Rotate a point 45 degrees counterclockwise around the z-axis. + * var p = new Cesium.Cartesian3(5, 6, 7); + * var m = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(45.0)); + * var rotated = Cesium.Matrix3.multiplyByVector(m, p, new Cesium.Cartesian3()); */ - Matrix4.computeViewportTransformation = function(viewport, nearDepthRange, farDepthRange, result) { - Check.typeOf.object('result', result); + Matrix3.fromRotationZ = function(angle, result) { + Check.typeOf.number('angle', angle); - viewport = defaultValue(viewport, defaultValue.EMPTY_OBJECT); - var x = defaultValue(viewport.x, 0.0); - var y = defaultValue(viewport.y, 0.0); - var width = defaultValue(viewport.width, 0.0); - var height = defaultValue(viewport.height, 0.0); - nearDepthRange = defaultValue(nearDepthRange, 0.0); - farDepthRange = defaultValue(farDepthRange, 1.0); - - var halfWidth = width * 0.5; - var halfHeight = height * 0.5; - var halfDepth = (farDepthRange - nearDepthRange) * 0.5; + var cosAngle = Math.cos(angle); + var sinAngle = Math.sin(angle); - var column0Row0 = halfWidth; - var column1Row1 = halfHeight; - var column2Row2 = halfDepth; - var column3Row0 = x + halfWidth; - var column3Row1 = y + halfHeight; - var column3Row2 = nearDepthRange + halfDepth; - var column3Row3 = 1.0; + if (!defined(result)) { + return new Matrix3( + cosAngle, -sinAngle, 0.0, + sinAngle, cosAngle, 0.0, + 0.0, 0.0, 1.0); + } - result[0] = column0Row0; - result[1] = 0.0; + result[0] = cosAngle; + result[1] = sinAngle; result[2] = 0.0; - result[3] = 0.0; - result[4] = 0.0; - result[5] = column1Row1; + result[3] = -sinAngle; + result[4] = cosAngle; + result[5] = 0.0; result[6] = 0.0; result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = column2Row2; - result[11] = 0.0; - result[12] = column3Row0; - result[13] = column3Row1; - result[14] = column3Row2; - result[15] = column3Row3; - return result; - }; + result[8] = 1.0; - /** - * Computes a Matrix4 instance that transforms from world space to view space. - * - * @param {Cartesian3} position The position of the camera. - * @param {Cartesian3} direction The forward direction. - * @param {Cartesian3} up The up direction. - * @param {Cartesian3} right The right direction. - * @param {Matrix4} result The object in which the result will be stored. - * @returns {Matrix4} The modified result parameter. - */ - Matrix4.computeView = function(position, direction, up, right, result) { - Check.typeOf.object('position', position); - Check.typeOf.object('direction', direction); - Check.typeOf.object('up', up); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result[0] = right.x; - result[1] = up.x; - result[2] = -direction.x; - result[3] = 0.0; - result[4] = right.y; - result[5] = up.y; - result[6] = -direction.y; - result[7] = 0.0; - result[8] = right.z; - result[9] = up.z; - result[10] = -direction.z; - result[11] = 0.0; - result[12] = -Cartesian3.dot(right, position); - result[13] = -Cartesian3.dot(up, position); - result[14] = Cartesian3.dot(direction, position); - result[15] = 1.0; return result; }; /** - * Computes an Array from the provided Matrix4 instance. + * Creates an Array from the provided Matrix3 instance. * The array will be in column-major order. * - * @param {Matrix4} matrix The matrix to use.. + * @param {Matrix3} matrix The matrix to use.. * @param {Number[]} [result] The Array onto which to store the result. * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. - * - * @example - * //create an array from an instance of Matrix4 - * // m = [10.0, 14.0, 18.0, 22.0] - * // [11.0, 15.0, 19.0, 23.0] - * // [12.0, 16.0, 20.0, 24.0] - * // [13.0, 17.0, 21.0, 25.0] - * var a = Cesium.Matrix4.toArray(m); - * - * // m remains the same - * //creates a = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0] */ - Matrix4.toArray = function(matrix, result) { + Matrix3.toArray = function(matrix, result) { Check.typeOf.object('matrix', matrix); if (!defined(result)) { - return [matrix[0], matrix[1], matrix[2], matrix[3], - matrix[4], matrix[5], matrix[6], matrix[7], - matrix[8], matrix[9], matrix[10], matrix[11], - matrix[12], matrix[13], matrix[14], matrix[15]]; + return [matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7], matrix[8]]; } result[0] = matrix[0]; result[1] = matrix[1]; @@ -12815,13 +13062,6 @@ define('Core/Matrix4',[ result[6] = matrix[6]; result[7] = matrix[7]; result[8] = matrix[8]; - result[9] = matrix[9]; - result[10] = matrix[10]; - result[11] = matrix[11]; - result[12] = matrix[12]; - result[13] = matrix[13]; - result[14] = matrix[14]; - result[15] = matrix[15]; return result; }; @@ -12832,241 +13072,125 @@ define('Core/Matrix4',[ * @param {Number} column The zero-based index of the column. * @returns {Number} The index of the element at the provided row and column. * - * @exception {DeveloperError} row must be 0, 1, 2, or 3. - * @exception {DeveloperError} column must be 0, 1, 2, or 3. + * @exception {DeveloperError} row must be 0, 1, or 2. + * @exception {DeveloperError} column must be 0, 1, or 2. * * @example - * var myMatrix = new Cesium.Matrix4(); - * var column1Row0Index = Cesium.Matrix4.getElementIndex(1, 0); - * var column1Row0 = myMatrix[column1Row0Index]; + * var myMatrix = new Cesium.Matrix3(); + * var column1Row0Index = Cesium.Matrix3.getElementIndex(1, 0); + * var column1Row0 = myMatrix[column1Row0Index] * myMatrix[column1Row0Index] = 10.0; */ - Matrix4.getElementIndex = function(column, row) { + Matrix3.getElementIndex = function(column, row) { Check.typeOf.number.greaterThanOrEquals('row', row, 0); - Check.typeOf.number.lessThanOrEquals('row', row, 3); - + Check.typeOf.number.lessThanOrEquals('row', row, 2); Check.typeOf.number.greaterThanOrEquals('column', column, 0); - Check.typeOf.number.lessThanOrEquals('column', column, 3); + Check.typeOf.number.lessThanOrEquals('column', column, 2); - return column * 4 + row; + return column * 3 + row; }; /** - * Retrieves a copy of the matrix column at the provided index as a Cartesian4 instance. + * Retrieves a copy of the matrix column at the provided index as a Cartesian3 instance. * - * @param {Matrix4} matrix The matrix to use. + * @param {Matrix3} matrix The matrix to use. * @param {Number} index The zero-based index of the column to retrieve. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - * - * @exception {DeveloperError} index must be 0, 1, 2, or 3. - * - * @example - * //returns a Cartesian4 instance with values from the specified column - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] - * - * //Example 1: Creates an instance of Cartesian - * var a = Cesium.Matrix4.getColumn(m, 2, new Cesium.Cartesian4()); - * - * @example - * //Example 2: Sets values for Cartesian instance - * var a = new Cesium.Cartesian4(); - * Cesium.Matrix4.getColumn(m, 2, a); + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. * - * // a.x = 12.0; a.y = 16.0; a.z = 20.0; a.w = 24.0; + * @exception {DeveloperError} index must be 0, 1, or 2. */ - Matrix4.getColumn = function(matrix, index, result) { + Matrix3.getColumn = function(matrix, index, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 3); - + Check.typeOf.number.lessThanOrEquals('index', index, 2); Check.typeOf.object('result', result); - var startIndex = index * 4; + var startIndex = index * 3; var x = matrix[startIndex]; var y = matrix[startIndex + 1]; var z = matrix[startIndex + 2]; - var w = matrix[startIndex + 3]; result.x = x; result.y = y; result.z = z; - result.w = w; return result; }; /** - * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian4 instance. + * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian3 instance. * - * @param {Matrix4} matrix The matrix to use. + * @param {Matrix3} matrix The matrix to use. * @param {Number} index The zero-based index of the column to set. - * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified column. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * @exception {DeveloperError} index must be 0, 1, 2, or 3. - * - * @example - * //creates a new Matrix4 instance with new column values from the Cartesian4 instance - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] - * - * var a = Cesium.Matrix4.setColumn(m, 2, new Cesium.Cartesian4(99.0, 98.0, 97.0, 96.0), new Cesium.Matrix4()); + * @param {Cartesian3} cartesian The Cartesian whose values will be assigned to the specified column. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. * - * // m remains the same - * // a = [10.0, 11.0, 99.0, 13.0] - * // [14.0, 15.0, 98.0, 17.0] - * // [18.0, 19.0, 97.0, 21.0] - * // [22.0, 23.0, 96.0, 25.0] + * @exception {DeveloperError} index must be 0, 1, or 2. */ - Matrix4.setColumn = function(matrix, index, cartesian, result) { + Matrix3.setColumn = function(matrix, index, cartesian, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 3); - + Check.typeOf.number.lessThanOrEquals('index', index, 2); Check.typeOf.object('cartesian', cartesian); Check.typeOf.object('result', result); - result = Matrix4.clone(matrix, result); - var startIndex = index * 4; + result = Matrix3.clone(matrix, result); + var startIndex = index * 3; result[startIndex] = cartesian.x; result[startIndex + 1] = cartesian.y; result[startIndex + 2] = cartesian.z; - result[startIndex + 3] = cartesian.w; - return result; - }; - - /** - * Computes a new matrix that replaces the translation in the rightmost column of the provided - * matrix with the provided translation. This assumes the matrix is an affine transformation - * - * @param {Matrix4} matrix The matrix to use. - * @param {Cartesian3} translation The translation that replaces the translation of the provided matrix. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - */ - Matrix4.setTranslation = function(matrix, translation, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('translation', translation); - Check.typeOf.object('result', result); - - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[3]; - - result[4] = matrix[4]; - result[5] = matrix[5]; - result[6] = matrix[6]; - result[7] = matrix[7]; - - result[8] = matrix[8]; - result[9] = matrix[9]; - result[10] = matrix[10]; - result[11] = matrix[11]; - - result[12] = translation.x; - result[13] = translation.y; - result[14] = translation.z; - result[15] = matrix[15]; - return result; }; /** - * Retrieves a copy of the matrix row at the provided index as a Cartesian4 instance. + * Retrieves a copy of the matrix row at the provided index as a Cartesian3 instance. * - * @param {Matrix4} matrix The matrix to use. + * @param {Matrix3} matrix The matrix to use. * @param {Number} index The zero-based index of the row to retrieve. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - * - * @exception {DeveloperError} index must be 0, 1, 2, or 3. - * - * @example - * //returns a Cartesian4 instance with values from the specified column - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] - * - * //Example 1: Returns an instance of Cartesian - * var a = Cesium.Matrix4.getRow(m, 2, new Cesium.Cartesian4()); - * - * @example - * //Example 2: Sets values for a Cartesian instance - * var a = new Cesium.Cartesian4(); - * Cesium.Matrix4.getRow(m, 2, a); + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. * - * // a.x = 18.0; a.y = 19.0; a.z = 20.0; a.w = 21.0; + * @exception {DeveloperError} index must be 0, 1, or 2. */ - Matrix4.getRow = function(matrix, index, result) { + Matrix3.getRow = function(matrix, index, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 3); - + Check.typeOf.number.lessThanOrEquals('index', index, 2); Check.typeOf.object('result', result); var x = matrix[index]; - var y = matrix[index + 4]; - var z = matrix[index + 8]; - var w = matrix[index + 12]; + var y = matrix[index + 3]; + var z = matrix[index + 6]; result.x = x; result.y = y; result.z = z; - result.w = w; return result; }; /** - * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian4 instance. + * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian3 instance. * - * @param {Matrix4} matrix The matrix to use. + * @param {Matrix3} matrix The matrix to use. * @param {Number} index The zero-based index of the row to set. - * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified row. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * @exception {DeveloperError} index must be 0, 1, 2, or 3. - * - * @example - * //create a new Matrix4 instance with new row values from the Cartesian4 instance - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] - * - * var a = Cesium.Matrix4.setRow(m, 2, new Cesium.Cartesian4(99.0, 98.0, 97.0, 96.0), new Cesium.Matrix4()); + * @param {Cartesian3} cartesian The Cartesian whose values will be assigned to the specified row. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. * - * // m remains the same - * // a = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [99.0, 98.0, 97.0, 96.0] - * // [22.0, 23.0, 24.0, 25.0] + * @exception {DeveloperError} index must be 0, 1, or 2. */ - Matrix4.setRow = function(matrix, index, cartesian, result) { + Matrix3.setRow = function(matrix, index, cartesian, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 3); - + Check.typeOf.number.lessThanOrEquals('index', index, 2); Check.typeOf.object('cartesian', cartesian); Check.typeOf.object('result', result); - result = Matrix4.clone(matrix, result); + result = Matrix3.clone(matrix, result); result[index] = cartesian.x; - result[index + 4] = cartesian.y; - result[index + 8] = cartesian.z; - result[index + 12] = cartesian.w; + result[index + 3] = cartesian.y; + result[index + 6] = cartesian.z; return result; }; @@ -13075,17 +13199,17 @@ define('Core/Matrix4',[ /** * Extracts the non-uniform scale assuming the matrix is an affine transformation. * - * @param {Matrix4} matrix The matrix. + * @param {Matrix3} matrix The matrix. * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter + * @returns {Cartesian3} The modified result parameter. */ - Matrix4.getScale = function(matrix, result) { + Matrix3.getScale = function(matrix, result) { Check.typeOf.object('matrix', matrix); Check.typeOf.object('result', result); result.x = Cartesian3.magnitude(Cartesian3.fromElements(matrix[0], matrix[1], matrix[2], scratchColumn)); - result.y = Cartesian3.magnitude(Cartesian3.fromElements(matrix[4], matrix[5], matrix[6], scratchColumn)); - result.z = Cartesian3.magnitude(Cartesian3.fromElements(matrix[8], matrix[9], matrix[10], scratchColumn)); + result.y = Cartesian3.magnitude(Cartesian3.fromElements(matrix[3], matrix[4], matrix[5], scratchColumn)); + result.z = Cartesian3.magnitude(Cartesian3.fromElements(matrix[6], matrix[7], matrix[8], scratchColumn)); return result; }; @@ -13093,112 +13217,62 @@ define('Core/Matrix4',[ /** * Computes the maximum scale assuming the matrix is an affine transformation. - * The maximum scale is the maximum length of the column vectors in the upper-left - * 3x3 matrix. + * The maximum scale is the maximum length of the column vectors. * - * @param {Matrix4} matrix The matrix. + * @param {Matrix3} matrix The matrix. * @returns {Number} The maximum scale. */ - Matrix4.getMaximumScale = function(matrix) { - Matrix4.getScale(matrix, scratchScale); + Matrix3.getMaximumScale = function(matrix) { + Matrix3.getScale(matrix, scratchScale); return Cartesian3.maximumComponent(scratchScale); }; /** * Computes the product of two matrices. * - * @param {Matrix4} left The first matrix. - * @param {Matrix4} right The second matrix. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * @param {Matrix3} left The first matrix. + * @param {Matrix3} right The second matrix. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. */ - Matrix4.multiply = function(left, right, result) { + Matrix3.multiply = function(left, right, result) { Check.typeOf.object('left', left); Check.typeOf.object('right', right); Check.typeOf.object('result', result); - var left0 = left[0]; - var left1 = left[1]; - var left2 = left[2]; - var left3 = left[3]; - var left4 = left[4]; - var left5 = left[5]; - var left6 = left[6]; - var left7 = left[7]; - var left8 = left[8]; - var left9 = left[9]; - var left10 = left[10]; - var left11 = left[11]; - var left12 = left[12]; - var left13 = left[13]; - var left14 = left[14]; - var left15 = left[15]; - - var right0 = right[0]; - var right1 = right[1]; - var right2 = right[2]; - var right3 = right[3]; - var right4 = right[4]; - var right5 = right[5]; - var right6 = right[6]; - var right7 = right[7]; - var right8 = right[8]; - var right9 = right[9]; - var right10 = right[10]; - var right11 = right[11]; - var right12 = right[12]; - var right13 = right[13]; - var right14 = right[14]; - var right15 = right[15]; - - var column0Row0 = left0 * right0 + left4 * right1 + left8 * right2 + left12 * right3; - var column0Row1 = left1 * right0 + left5 * right1 + left9 * right2 + left13 * right3; - var column0Row2 = left2 * right0 + left6 * right1 + left10 * right2 + left14 * right3; - var column0Row3 = left3 * right0 + left7 * right1 + left11 * right2 + left15 * right3; - - var column1Row0 = left0 * right4 + left4 * right5 + left8 * right6 + left12 * right7; - var column1Row1 = left1 * right4 + left5 * right5 + left9 * right6 + left13 * right7; - var column1Row2 = left2 * right4 + left6 * right5 + left10 * right6 + left14 * right7; - var column1Row3 = left3 * right4 + left7 * right5 + left11 * right6 + left15 * right7; + var column0Row0 = left[0] * right[0] + left[3] * right[1] + left[6] * right[2]; + var column0Row1 = left[1] * right[0] + left[4] * right[1] + left[7] * right[2]; + var column0Row2 = left[2] * right[0] + left[5] * right[1] + left[8] * right[2]; - var column2Row0 = left0 * right8 + left4 * right9 + left8 * right10 + left12 * right11; - var column2Row1 = left1 * right8 + left5 * right9 + left9 * right10 + left13 * right11; - var column2Row2 = left2 * right8 + left6 * right9 + left10 * right10 + left14 * right11; - var column2Row3 = left3 * right8 + left7 * right9 + left11 * right10 + left15 * right11; + var column1Row0 = left[0] * right[3] + left[3] * right[4] + left[6] * right[5]; + var column1Row1 = left[1] * right[3] + left[4] * right[4] + left[7] * right[5]; + var column1Row2 = left[2] * right[3] + left[5] * right[4] + left[8] * right[5]; - var column3Row0 = left0 * right12 + left4 * right13 + left8 * right14 + left12 * right15; - var column3Row1 = left1 * right12 + left5 * right13 + left9 * right14 + left13 * right15; - var column3Row2 = left2 * right12 + left6 * right13 + left10 * right14 + left14 * right15; - var column3Row3 = left3 * right12 + left7 * right13 + left11 * right14 + left15 * right15; + var column2Row0 = left[0] * right[6] + left[3] * right[7] + left[6] * right[8]; + var column2Row1 = left[1] * right[6] + left[4] * right[7] + left[7] * right[8]; + var column2Row2 = left[2] * right[6] + left[5] * right[7] + left[8] * right[8]; result[0] = column0Row0; result[1] = column0Row1; result[2] = column0Row2; - result[3] = column0Row3; - result[4] = column1Row0; - result[5] = column1Row1; - result[6] = column1Row2; - result[7] = column1Row3; - result[8] = column2Row0; - result[9] = column2Row1; - result[10] = column2Row2; - result[11] = column2Row3; - result[12] = column3Row0; - result[13] = column3Row1; - result[14] = column3Row2; - result[15] = column3Row3; + result[3] = column1Row0; + result[4] = column1Row1; + result[5] = column1Row2; + result[6] = column2Row0; + result[7] = column2Row1; + result[8] = column2Row2; return result; }; /** * Computes the sum of two matrices. * - * @param {Matrix4} left The first matrix. - * @param {Matrix4} right The second matrix. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * @param {Matrix3} left The first matrix. + * @param {Matrix3} right The second matrix. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. */ - Matrix4.add = function(left, right, result) { + Matrix3.add = function(left, right, result) { Check.typeOf.object('left', left); Check.typeOf.object('right', right); Check.typeOf.object('result', result); @@ -13212,25 +13286,18 @@ define('Core/Matrix4',[ result[6] = left[6] + right[6]; result[7] = left[7] + right[7]; result[8] = left[8] + right[8]; - result[9] = left[9] + right[9]; - result[10] = left[10] + right[10]; - result[11] = left[11] + right[11]; - result[12] = left[12] + right[12]; - result[13] = left[13] + right[13]; - result[14] = left[14] + right[14]; - result[15] = left[15] + right[15]; return result; }; /** * Computes the difference of two matrices. * - * @param {Matrix4} left The first matrix. - * @param {Matrix4} right The second matrix. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * @param {Matrix3} left The first matrix. + * @param {Matrix3} right The second matrix. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. */ - Matrix4.subtract = function(left, right, result) { + Matrix3.subtract = function(left, right, result) { Check.typeOf.object('left', left); Check.typeOf.object('right', right); Check.typeOf.object('result', result); @@ -13244,633 +13311,412 @@ define('Core/Matrix4',[ result[6] = left[6] - right[6]; result[7] = left[7] - right[7]; result[8] = left[8] - right[8]; - result[9] = left[9] - right[9]; - result[10] = left[10] - right[10]; - result[11] = left[11] - right[11]; - result[12] = left[12] - right[12]; - result[13] = left[13] - right[13]; - result[14] = left[14] - right[14]; - result[15] = left[15] - right[15]; return result; }; /** - * Computes the product of two matrices assuming the matrices are - * affine transformation matrices, where the upper left 3x3 elements - * are a rotation matrix, and the upper three elements in the fourth - * column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. - * The matrix is not verified to be in the proper form. - * This method is faster than computing the product for general 4x4 - * matrices using {@link Matrix4.multiply}. - * - * @param {Matrix4} left The first matrix. - * @param {Matrix4} right The second matrix. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * Computes the product of a matrix and a column vector. * - * @example - * var m1 = new Cesium.Matrix4(1.0, 6.0, 7.0, 0.0, 2.0, 5.0, 8.0, 0.0, 3.0, 4.0, 9.0, 0.0, 0.0, 0.0, 0.0, 1.0); - * var m2 = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(1.0, 1.0, 1.0)); - * var m3 = Cesium.Matrix4.multiplyTransformation(m1, m2, new Cesium.Matrix4()); + * @param {Matrix3} matrix The matrix. + * @param {Cartesian3} cartesian The column. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. */ - Matrix4.multiplyTransformation = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); + Matrix3.multiplyByVector = function(matrix, cartesian, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('cartesian', cartesian); Check.typeOf.object('result', result); - var left0 = left[0]; - var left1 = left[1]; - var left2 = left[2]; - var left4 = left[4]; - var left5 = left[5]; - var left6 = left[6]; - var left8 = left[8]; - var left9 = left[9]; - var left10 = left[10]; - var left12 = left[12]; - var left13 = left[13]; - var left14 = left[14]; - - var right0 = right[0]; - var right1 = right[1]; - var right2 = right[2]; - var right4 = right[4]; - var right5 = right[5]; - var right6 = right[6]; - var right8 = right[8]; - var right9 = right[9]; - var right10 = right[10]; - var right12 = right[12]; - var right13 = right[13]; - var right14 = right[14]; - - var column0Row0 = left0 * right0 + left4 * right1 + left8 * right2; - var column0Row1 = left1 * right0 + left5 * right1 + left9 * right2; - var column0Row2 = left2 * right0 + left6 * right1 + left10 * right2; - - var column1Row0 = left0 * right4 + left4 * right5 + left8 * right6; - var column1Row1 = left1 * right4 + left5 * right5 + left9 * right6; - var column1Row2 = left2 * right4 + left6 * right5 + left10 * right6; + var vX = cartesian.x; + var vY = cartesian.y; + var vZ = cartesian.z; - var column2Row0 = left0 * right8 + left4 * right9 + left8 * right10; - var column2Row1 = left1 * right8 + left5 * right9 + left9 * right10; - var column2Row2 = left2 * right8 + left6 * right9 + left10 * right10; + var x = matrix[0] * vX + matrix[3] * vY + matrix[6] * vZ; + var y = matrix[1] * vX + matrix[4] * vY + matrix[7] * vZ; + var z = matrix[2] * vX + matrix[5] * vY + matrix[8] * vZ; - var column3Row0 = left0 * right12 + left4 * right13 + left8 * right14 + left12; - var column3Row1 = left1 * right12 + left5 * right13 + left9 * right14 + left13; - var column3Row2 = left2 * right12 + left6 * right13 + left10 * right14 + left14; + result.x = x; + result.y = y; + result.z = z; + return result; + }; - result[0] = column0Row0; - result[1] = column0Row1; - result[2] = column0Row2; - result[3] = 0.0; - result[4] = column1Row0; - result[5] = column1Row1; - result[6] = column1Row2; - result[7] = 0.0; - result[8] = column2Row0; - result[9] = column2Row1; - result[10] = column2Row2; - result[11] = 0.0; - result[12] = column3Row0; - result[13] = column3Row1; - result[14] = column3Row2; - result[15] = 1.0; + /** + * Computes the product of a matrix and a scalar. + * + * @param {Matrix3} matrix The matrix. + * @param {Number} scalar The number to multiply by. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. + */ + Matrix3.multiplyByScalar = function(matrix, scalar, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result[0] = matrix[0] * scalar; + result[1] = matrix[1] * scalar; + result[2] = matrix[2] * scalar; + result[3] = matrix[3] * scalar; + result[4] = matrix[4] * scalar; + result[5] = matrix[5] * scalar; + result[6] = matrix[6] * scalar; + result[7] = matrix[7] * scalar; + result[8] = matrix[8] * scalar; return result; }; /** - * Multiplies a transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) - * by a 3x3 rotation matrix. This is an optimization - * for <code>Matrix4.multiply(m, Matrix4.fromRotationTranslation(rotation), m);</code> with less allocations and arithmetic operations. + * Computes the product of a matrix times a (non-uniform) scale, as if the scale were a scale matrix. + * + * @param {Matrix3} matrix The matrix on the left-hand side. + * @param {Cartesian3} scale The non-uniform scale on the right-hand side. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. * - * @param {Matrix4} matrix The matrix on the left-hand side. - * @param {Matrix3} rotation The 3x3 rotation matrix on the right-hand side. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. * * @example - * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromRotationTranslation(rotation), m); - * Cesium.Matrix4.multiplyByMatrix3(m, rotation, m); + * // Instead of Cesium.Matrix3.multiply(m, Cesium.Matrix3.fromScale(scale), m); + * Cesium.Matrix3.multiplyByScale(m, scale, m); + * + * @see Matrix3.fromScale + * @see Matrix3.multiplyByUniformScale */ - Matrix4.multiplyByMatrix3 = function(matrix, rotation, result) { + Matrix3.multiplyByScale = function(matrix, scale, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.object('rotation', rotation); + Check.typeOf.object('scale', scale); Check.typeOf.object('result', result); - var left0 = matrix[0]; - var left1 = matrix[1]; - var left2 = matrix[2]; - var left4 = matrix[4]; - var left5 = matrix[5]; - var left6 = matrix[6]; - var left8 = matrix[8]; - var left9 = matrix[9]; - var left10 = matrix[10]; - - var right0 = rotation[0]; - var right1 = rotation[1]; - var right2 = rotation[2]; - var right4 = rotation[3]; - var right5 = rotation[4]; - var right6 = rotation[5]; - var right8 = rotation[6]; - var right9 = rotation[7]; - var right10 = rotation[8]; - - var column0Row0 = left0 * right0 + left4 * right1 + left8 * right2; - var column0Row1 = left1 * right0 + left5 * right1 + left9 * right2; - var column0Row2 = left2 * right0 + left6 * right1 + left10 * right2; - - var column1Row0 = left0 * right4 + left4 * right5 + left8 * right6; - var column1Row1 = left1 * right4 + left5 * right5 + left9 * right6; - var column1Row2 = left2 * right4 + left6 * right5 + left10 * right6; - - var column2Row0 = left0 * right8 + left4 * right9 + left8 * right10; - var column2Row1 = left1 * right8 + left5 * right9 + left9 * right10; - var column2Row2 = left2 * right8 + left6 * right9 + left10 * right10; - - result[0] = column0Row0; - result[1] = column0Row1; - result[2] = column0Row2; - result[3] = 0.0; - result[4] = column1Row0; - result[5] = column1Row1; - result[6] = column1Row2; - result[7] = 0.0; - result[8] = column2Row0; - result[9] = column2Row1; - result[10] = column2Row2; - result[11] = 0.0; - result[12] = matrix[12]; - result[13] = matrix[13]; - result[14] = matrix[14]; - result[15] = matrix[15]; + result[0] = matrix[0] * scale.x; + result[1] = matrix[1] * scale.x; + result[2] = matrix[2] * scale.x; + result[3] = matrix[3] * scale.y; + result[4] = matrix[4] * scale.y; + result[5] = matrix[5] * scale.y; + result[6] = matrix[6] * scale.z; + result[7] = matrix[7] * scale.z; + result[8] = matrix[8] * scale.z; return result; }; /** - * Multiplies a transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) - * by an implicit translation matrix defined by a {@link Cartesian3}. This is an optimization - * for <code>Matrix4.multiply(m, Matrix4.fromTranslation(position), m);</code> with less allocations and arithmetic operations. - * - * @param {Matrix4} matrix The matrix on the left-hand side. - * @param {Cartesian3} translation The translation on the right-hand side. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * Creates a negated copy of the provided matrix. * - * @example - * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromTranslation(position), m); - * Cesium.Matrix4.multiplyByTranslation(m, position, m); + * @param {Matrix3} matrix The matrix to negate. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. */ - Matrix4.multiplyByTranslation = function(matrix, translation, result) { + Matrix3.negate = function(matrix, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.object('translation', translation); Check.typeOf.object('result', result); - var x = translation.x; - var y = translation.y; - var z = translation.z; - - var tx = (x * matrix[0]) + (y * matrix[4]) + (z * matrix[8]) + matrix[12]; - var ty = (x * matrix[1]) + (y * matrix[5]) + (z * matrix[9]) + matrix[13]; - var tz = (x * matrix[2]) + (y * matrix[6]) + (z * matrix[10]) + matrix[14]; - - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[3]; - result[4] = matrix[4]; - result[5] = matrix[5]; - result[6] = matrix[6]; - result[7] = matrix[7]; - result[8] = matrix[8]; - result[9] = matrix[9]; - result[10] = matrix[10]; - result[11] = matrix[11]; - result[12] = tx; - result[13] = ty; - result[14] = tz; - result[15] = matrix[15]; + result[0] = -matrix[0]; + result[1] = -matrix[1]; + result[2] = -matrix[2]; + result[3] = -matrix[3]; + result[4] = -matrix[4]; + result[5] = -matrix[5]; + result[6] = -matrix[6]; + result[7] = -matrix[7]; + result[8] = -matrix[8]; return result; }; - var uniformScaleScratch = new Cartesian3(); - /** - * Multiplies an affine transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) - * by an implicit uniform scale matrix. This is an optimization - * for <code>Matrix4.multiply(m, Matrix4.fromUniformScale(scale), m);</code>, where - * <code>m</code> must be an affine matrix. - * This function performs fewer allocations and arithmetic operations. - * - * @param {Matrix4} matrix The affine matrix on the left-hand side. - * @param {Number} scale The uniform scale on the right-hand side. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * - * @example - * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromUniformScale(scale), m); - * Cesium.Matrix4.multiplyByUniformScale(m, scale, m); + * Computes the transpose of the provided matrix. * - * @see Matrix4.fromUniformScale - * @see Matrix4.multiplyByScale + * @param {Matrix3} matrix The matrix to transpose. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. */ - Matrix4.multiplyByUniformScale = function(matrix, scale, result) { + Matrix3.transpose = function(matrix, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.number('scale', scale); Check.typeOf.object('result', result); - uniformScaleScratch.x = scale; - uniformScaleScratch.y = scale; - uniformScaleScratch.z = scale; - return Matrix4.multiplyByScale(matrix, uniformScaleScratch, result); + var column0Row0 = matrix[0]; + var column0Row1 = matrix[3]; + var column0Row2 = matrix[6]; + var column1Row0 = matrix[1]; + var column1Row1 = matrix[4]; + var column1Row2 = matrix[7]; + var column2Row0 = matrix[2]; + var column2Row1 = matrix[5]; + var column2Row2 = matrix[8]; + + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = column1Row0; + result[4] = column1Row1; + result[5] = column1Row2; + result[6] = column2Row0; + result[7] = column2Row1; + result[8] = column2Row2; + return result; }; - /** - * Multiplies an affine transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) - * by an implicit non-uniform scale matrix. This is an optimization - * for <code>Matrix4.multiply(m, Matrix4.fromUniformScale(scale), m);</code>, where - * <code>m</code> must be an affine matrix. - * This function performs fewer allocations and arithmetic operations. - * - * @param {Matrix4} matrix The affine matrix on the left-hand side. - * @param {Cartesian3} scale The non-uniform scale on the right-hand side. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * - * @example - * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromScale(scale), m); - * Cesium.Matrix4.multiplyByScale(m, scale, m); - * - * @see Matrix4.fromScale - * @see Matrix4.multiplyByUniformScale - */ - Matrix4.multiplyByScale = function(matrix, scale, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('scale', scale); - Check.typeOf.object('result', result); - - var scaleX = scale.x; - var scaleY = scale.y; - var scaleZ = scale.z; + function computeFrobeniusNorm(matrix) { + var norm = 0.0; + for (var i = 0; i < 9; ++i) { + var temp = matrix[i]; + norm += temp * temp; + } - // Faster than Cartesian3.equals - if ((scaleX === 1.0) && (scaleY === 1.0) && (scaleZ === 1.0)) { - return Matrix4.clone(matrix, result); + return Math.sqrt(norm); + } + + var rowVal = [1, 0, 0]; + var colVal = [2, 2, 1]; + + function offDiagonalFrobeniusNorm(matrix) { + // Computes the "off-diagonal" Frobenius norm. + // Assumes matrix is symmetric. + + var norm = 0.0; + for (var i = 0; i < 3; ++i) { + var temp = matrix[Matrix3.getElementIndex(colVal[i], rowVal[i])]; + norm += 2.0 * temp * temp; } - result[0] = scaleX * matrix[0]; - result[1] = scaleX * matrix[1]; - result[2] = scaleX * matrix[2]; - result[3] = 0.0; - result[4] = scaleY * matrix[4]; - result[5] = scaleY * matrix[5]; - result[6] = scaleY * matrix[6]; - result[7] = 0.0; - result[8] = scaleZ * matrix[8]; - result[9] = scaleZ * matrix[9]; - result[10] = scaleZ * matrix[10]; - result[11] = 0.0; - result[12] = matrix[12]; - result[13] = matrix[13]; - result[14] = matrix[14]; - result[15] = 1.0; - return result; - }; + return Math.sqrt(norm); + } - /** - * Computes the product of a matrix and a column vector. - * - * @param {Matrix4} matrix The matrix. - * @param {Cartesian4} cartesian The vector. - * @param {Cartesian4} result The object onto which to store the result. - * @returns {Cartesian4} The modified result parameter. - */ - Matrix4.multiplyByVector = function(matrix, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var vX = cartesian.x; - var vY = cartesian.y; - var vZ = cartesian.z; - var vW = cartesian.w; + function shurDecomposition(matrix, result) { + // This routine was created based upon Matrix Computations, 3rd ed., by Golub and Van Loan, + // section 8.4.2 The 2by2 Symmetric Schur Decomposition. + // + // The routine takes a matrix, which is assumed to be symmetric, and + // finds the largest off-diagonal term, and then creates + // a matrix (result) which can be used to help reduce it - var x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12] * vW; - var y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13] * vW; - var z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14] * vW; - var w = matrix[3] * vX + matrix[7] * vY + matrix[11] * vZ + matrix[15] * vW; + var tolerance = CesiumMath.EPSILON15; - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; - }; + var maxDiagonal = 0.0; + var rotAxis = 1; - /** - * Computes the product of a matrix and a {@link Cartesian3}. This is equivalent to calling {@link Matrix4.multiplyByVector} - * with a {@link Cartesian4} with a <code>w</code> component of zero. - * - * @param {Matrix4} matrix The matrix. - * @param {Cartesian3} cartesian The point. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. - * - * @example - * var p = new Cesium.Cartesian3(1.0, 2.0, 3.0); - * var result = Cesium.Matrix4.multiplyByPointAsVector(matrix, p, new Cesium.Cartesian3()); - * // A shortcut for - * // Cartesian3 p = ... - * // Cesium.Matrix4.multiplyByVector(matrix, new Cesium.Cartesian4(p.x, p.y, p.z, 0.0), result); - */ - Matrix4.multiplyByPointAsVector = function(matrix, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var vX = cartesian.x; - var vY = cartesian.y; - var vZ = cartesian.z; + // find pivot (rotAxis) based on max diagonal of matrix + for (var i = 0; i < 3; ++i) { + var temp = Math.abs(matrix[Matrix3.getElementIndex(colVal[i], rowVal[i])]); + if (temp > maxDiagonal) { + rotAxis = i; + maxDiagonal = temp; + } + } - var x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ; - var y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ; - var z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ; + var c = 1.0; + var s = 0.0; - result.x = x; - result.y = y; - result.z = z; - return result; - }; + var p = rowVal[rotAxis]; + var q = colVal[rotAxis]; - /** - * Computes the product of a matrix and a {@link Cartesian3}. This is equivalent to calling {@link Matrix4.multiplyByVector} - * with a {@link Cartesian4} with a <code>w</code> component of 1, but returns a {@link Cartesian3} instead of a {@link Cartesian4}. - * - * @param {Matrix4} matrix The matrix. - * @param {Cartesian3} cartesian The point. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. - * - * @example - * var p = new Cesium.Cartesian3(1.0, 2.0, 3.0); - * var result = Cesium.Matrix4.multiplyByPoint(matrix, p, new Cesium.Cartesian3()); - */ - Matrix4.multiplyByPoint = function(matrix, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var vX = cartesian.x; - var vY = cartesian.y; - var vZ = cartesian.z; + if (Math.abs(matrix[Matrix3.getElementIndex(q, p)]) > tolerance) { + var qq = matrix[Matrix3.getElementIndex(q, q)]; + var pp = matrix[Matrix3.getElementIndex(p, p)]; + var qp = matrix[Matrix3.getElementIndex(q, p)]; - var x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12]; - var y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13]; - var z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14]; + var tau = (qq - pp) / 2.0 / qp; + var t; + + if (tau < 0.0) { + t = -1.0 / (-tau + Math.sqrt(1.0 + tau * tau)); + } else { + t = 1.0 / (tau + Math.sqrt(1.0 + tau * tau)); + } + + c = 1.0 / Math.sqrt(1.0 + t * t); + s = t * c; + } + + result = Matrix3.clone(Matrix3.IDENTITY, result); + + result[Matrix3.getElementIndex(p, p)] = result[Matrix3.getElementIndex(q, q)] = c; + result[Matrix3.getElementIndex(q, p)] = s; + result[Matrix3.getElementIndex(p, q)] = -s; - result.x = x; - result.y = y; - result.z = z; return result; - }; + } + + var jMatrix = new Matrix3(); + var jMatrixTranspose = new Matrix3(); /** - * Computes the product of a matrix and a scalar. + * Computes the eigenvectors and eigenvalues of a symmetric matrix. + * <p> + * Returns a diagonal matrix and unitary matrix such that: + * <code>matrix = unitary matrix * diagonal matrix * transpose(unitary matrix)</code> + * </p> + * <p> + * The values along the diagonal of the diagonal matrix are the eigenvalues. The columns + * of the unitary matrix are the corresponding eigenvectors. + * </p> * - * @param {Matrix4} matrix The matrix. - * @param {Number} scalar The number to multiply by. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * @param {Matrix3} matrix The matrix to decompose into diagonal and unitary matrix. Expected to be symmetric. + * @param {Object} [result] An object with unitary and diagonal properties which are matrices onto which to store the result. + * @returns {Object} An object with unitary and diagonal properties which are the unitary and diagonal matrices, respectively. * * @example - * //create a Matrix4 instance which is a scaled version of the supplied Matrix4 - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] + * var a = //... symetric matrix + * var result = { + * unitary : new Cesium.Matrix3(), + * diagonal : new Cesium.Matrix3() + * }; + * Cesium.Matrix3.computeEigenDecomposition(a, result); * - * var a = Cesium.Matrix4.multiplyByScalar(m, -2, new Cesium.Matrix4()); + * var unitaryTranspose = Cesium.Matrix3.transpose(result.unitary, new Cesium.Matrix3()); + * var b = Cesium.Matrix3.multiply(result.unitary, result.diagonal, new Cesium.Matrix3()); + * Cesium.Matrix3.multiply(b, unitaryTranspose, b); // b is now equal to a * - * // m remains the same - * // a = [-20.0, -22.0, -24.0, -26.0] - * // [-28.0, -30.0, -32.0, -34.0] - * // [-36.0, -38.0, -40.0, -42.0] - * // [-44.0, -46.0, -48.0, -50.0] + * var lambda = Cesium.Matrix3.getColumn(result.diagonal, 0, new Cesium.Cartesian3()).x; // first eigenvalue + * var v = Cesium.Matrix3.getColumn(result.unitary, 0, new Cesium.Cartesian3()); // first eigenvector + * var c = Cesium.Cartesian3.multiplyByScalar(v, lambda, new Cesium.Cartesian3()); // equal to Cesium.Matrix3.multiplyByVector(a, v) */ - Matrix4.multiplyByScalar = function(matrix, scalar, result) { + Matrix3.computeEigenDecomposition = function(matrix, result) { Check.typeOf.object('matrix', matrix); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - result[0] = matrix[0] * scalar; - result[1] = matrix[1] * scalar; - result[2] = matrix[2] * scalar; - result[3] = matrix[3] * scalar; - result[4] = matrix[4] * scalar; - result[5] = matrix[5] * scalar; - result[6] = matrix[6] * scalar; - result[7] = matrix[7] * scalar; - result[8] = matrix[8] * scalar; - result[9] = matrix[9] * scalar; - result[10] = matrix[10] * scalar; - result[11] = matrix[11] * scalar; - result[12] = matrix[12] * scalar; - result[13] = matrix[13] * scalar; - result[14] = matrix[14] * scalar; - result[15] = matrix[15] * scalar; + // This routine was created based upon Matrix Computations, 3rd ed., by Golub and Van Loan, + // section 8.4.3 The Classical Jacobi Algorithm + + var tolerance = CesiumMath.EPSILON20; + var maxSweeps = 10; + + var count = 0; + var sweep = 0; + + if (!defined(result)) { + result = {}; + } + + var unitaryMatrix = result.unitary = Matrix3.clone(Matrix3.IDENTITY, result.unitary); + var diagMatrix = result.diagonal = Matrix3.clone(matrix, result.diagonal); + + var epsilon = tolerance * computeFrobeniusNorm(diagMatrix); + + while (sweep < maxSweeps && offDiagonalFrobeniusNorm(diagMatrix) > epsilon) { + shurDecomposition(diagMatrix, jMatrix); + Matrix3.transpose(jMatrix, jMatrixTranspose); + Matrix3.multiply(diagMatrix, jMatrix, diagMatrix); + Matrix3.multiply(jMatrixTranspose, diagMatrix, diagMatrix); + Matrix3.multiply(unitaryMatrix, jMatrix, unitaryMatrix); + + if (++count > 2) { + ++sweep; + count = 0; + } + } + return result; }; /** - * Computes a negated copy of the provided matrix. - * - * @param {Matrix4} matrix The matrix to negate. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * @example - * //create a new Matrix4 instance which is a negation of a Matrix4 - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] - * - * var a = Cesium.Matrix4.negate(m, new Cesium.Matrix4()); + * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements. * - * // m remains the same - * // a = [-10.0, -11.0, -12.0, -13.0] - * // [-14.0, -15.0, -16.0, -17.0] - * // [-18.0, -19.0, -20.0, -21.0] - * // [-22.0, -23.0, -24.0, -25.0] + * @param {Matrix3} matrix The matrix with signed elements. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. */ - Matrix4.negate = function(matrix, result) { + Matrix3.abs = function(matrix, result) { Check.typeOf.object('matrix', matrix); Check.typeOf.object('result', result); - result[0] = -matrix[0]; - result[1] = -matrix[1]; - result[2] = -matrix[2]; - result[3] = -matrix[3]; - result[4] = -matrix[4]; - result[5] = -matrix[5]; - result[6] = -matrix[6]; - result[7] = -matrix[7]; - result[8] = -matrix[8]; - result[9] = -matrix[9]; - result[10] = -matrix[10]; - result[11] = -matrix[11]; - result[12] = -matrix[12]; - result[13] = -matrix[13]; - result[14] = -matrix[14]; - result[15] = -matrix[15]; + result[0] = Math.abs(matrix[0]); + result[1] = Math.abs(matrix[1]); + result[2] = Math.abs(matrix[2]); + result[3] = Math.abs(matrix[3]); + result[4] = Math.abs(matrix[4]); + result[5] = Math.abs(matrix[5]); + result[6] = Math.abs(matrix[6]); + result[7] = Math.abs(matrix[7]); + result[8] = Math.abs(matrix[8]); + return result; }; /** - * Computes the transpose of the provided matrix. - * - * @param {Matrix4} matrix The matrix to transpose. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * @example - * //returns transpose of a Matrix4 - * // m = [10.0, 11.0, 12.0, 13.0] - * // [14.0, 15.0, 16.0, 17.0] - * // [18.0, 19.0, 20.0, 21.0] - * // [22.0, 23.0, 24.0, 25.0] - * - * var a = Cesium.Matrix4.transpose(m, new Cesium.Matrix4()); + * Computes the determinant of the provided matrix. * - * // m remains the same - * // a = [10.0, 14.0, 18.0, 22.0] - * // [11.0, 15.0, 19.0, 23.0] - * // [12.0, 16.0, 20.0, 24.0] - * // [13.0, 17.0, 21.0, 25.0] + * @param {Matrix3} matrix The matrix to use. + * @returns {Number} The value of the determinant of the matrix. */ - Matrix4.transpose = function(matrix, result) { + Matrix3.determinant = function(matrix) { Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - var matrix1 = matrix[1]; - var matrix2 = matrix[2]; - var matrix3 = matrix[3]; - var matrix6 = matrix[6]; - var matrix7 = matrix[7]; - var matrix11 = matrix[11]; + var m11 = matrix[0]; + var m21 = matrix[3]; + var m31 = matrix[6]; + var m12 = matrix[1]; + var m22 = matrix[4]; + var m32 = matrix[7]; + var m13 = matrix[2]; + var m23 = matrix[5]; + var m33 = matrix[8]; - result[0] = matrix[0]; - result[1] = matrix[4]; - result[2] = matrix[8]; - result[3] = matrix[12]; - result[4] = matrix1; - result[5] = matrix[5]; - result[6] = matrix[9]; - result[7] = matrix[13]; - result[8] = matrix2; - result[9] = matrix6; - result[10] = matrix[10]; - result[11] = matrix[14]; - result[12] = matrix3; - result[13] = matrix7; - result[14] = matrix11; - result[15] = matrix[15]; - return result; + return m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13 * (m21 * m32 - m22 * m31); }; /** - * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements. + * Computes the inverse of the provided matrix. * - * @param {Matrix4} matrix The matrix with signed elements. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. + * @param {Matrix3} matrix The matrix to invert. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. + * + * @exception {DeveloperError} matrix is not invertible. */ - Matrix4.abs = function(matrix, result) { + Matrix3.inverse = function(matrix, result) { Check.typeOf.object('matrix', matrix); Check.typeOf.object('result', result); - result[0] = Math.abs(matrix[0]); - result[1] = Math.abs(matrix[1]); - result[2] = Math.abs(matrix[2]); - result[3] = Math.abs(matrix[3]); - result[4] = Math.abs(matrix[4]); - result[5] = Math.abs(matrix[5]); - result[6] = Math.abs(matrix[6]); - result[7] = Math.abs(matrix[7]); - result[8] = Math.abs(matrix[8]); - result[9] = Math.abs(matrix[9]); - result[10] = Math.abs(matrix[10]); - result[11] = Math.abs(matrix[11]); - result[12] = Math.abs(matrix[12]); - result[13] = Math.abs(matrix[13]); - result[14] = Math.abs(matrix[14]); - result[15] = Math.abs(matrix[15]); + var m11 = matrix[0]; + var m21 = matrix[1]; + var m31 = matrix[2]; + var m12 = matrix[3]; + var m22 = matrix[4]; + var m32 = matrix[5]; + var m13 = matrix[6]; + var m23 = matrix[7]; + var m33 = matrix[8]; - return result; + var determinant = Matrix3.determinant(matrix); + + if (Math.abs(determinant) <= CesiumMath.EPSILON15) { + throw new DeveloperError('matrix is not invertible'); + } + + result[0] = m22 * m33 - m23 * m32; + result[1] = m23 * m31 - m21 * m33; + result[2] = m21 * m32 - m22 * m31; + result[3] = m13 * m32 - m12 * m33; + result[4] = m11 * m33 - m13 * m31; + result[5] = m12 * m31 - m11 * m32; + result[6] = m12 * m23 - m13 * m22; + result[7] = m13 * m21 - m11 * m23; + result[8] = m11 * m22 - m12 * m21; + + var scale = 1.0 / determinant; + return Matrix3.multiplyByScalar(result, scale, result); }; /** * Compares the provided matrices componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {Matrix4} [left] The first matrix. - * @param {Matrix4} [right] The second matrix. + * @param {Matrix3} [left] The first matrix. + * @param {Matrix3} [right] The second matrix. * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - * - * @example - * //compares two Matrix4 instances - * - * // a = [10.0, 14.0, 18.0, 22.0] - * // [11.0, 15.0, 19.0, 23.0] - * // [12.0, 16.0, 20.0, 24.0] - * // [13.0, 17.0, 21.0, 25.0] - * - * // b = [10.0, 14.0, 18.0, 22.0] - * // [11.0, 15.0, 19.0, 23.0] - * // [12.0, 16.0, 20.0, 24.0] - * // [13.0, 17.0, 21.0, 25.0] - * - * if(Cesium.Matrix4.equals(a,b)) { - * console.log("Both matrices are equal"); - * } else { - * console.log("They are not equal"); - * } - * - * //Prints "Both matrices are equal" on the console */ - Matrix4.equals = function(left, right) { - // Given that most matrices will be transformation matrices, the elements - // are tested in order such that the test is likely to fail as early - // as possible. I _think_ this is just as friendly to the L1 cache - // as testing in index order. It is certainty faster in practice. + Matrix3.equals = function(left, right) { return (left === right) || (defined(left) && defined(right) && - // Translation - left[12] === right[12] && - left[13] === right[13] && - left[14] === right[14] && - - // Rotation/scale left[0] === right[0] && left[1] === right[1] && left[2] === right[2] && + left[3] === right[3] && left[4] === right[4] && left[5] === right[5] && left[6] === right[6] && - left[8] === right[8] && - left[9] === right[9] && - left[10] === right[10] && - - // Bottom row - left[3] === right[3] && left[7] === right[7] && - left[11] === right[11] && - left[15] === right[15]); + left[8] === right[8]); }; /** @@ -13878,33 +13724,12 @@ define('Core/Matrix4',[ * <code>true</code> if they are within the provided epsilon, * <code>false</code> otherwise. * - * @param {Matrix4} [left] The first matrix. - * @param {Matrix4} [right] The second matrix. + * @param {Matrix3} [left] The first matrix. + * @param {Matrix3} [right] The second matrix. * @param {Number} epsilon The epsilon to use for equality testing. * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. - * - * @example - * //compares two Matrix4 instances - * - * // a = [10.5, 14.5, 18.5, 22.5] - * // [11.5, 15.5, 19.5, 23.5] - * // [12.5, 16.5, 20.5, 24.5] - * // [13.5, 17.5, 21.5, 25.5] - * - * // b = [10.0, 14.0, 18.0, 22.0] - * // [11.0, 15.0, 19.0, 23.0] - * // [12.0, 16.0, 20.0, 24.0] - * // [13.0, 17.0, 21.0, 25.0] - * - * if(Cesium.Matrix4.equalsEpsilon(a,b,0.1)){ - * console.log("Difference between both the matrices is less than 0.1"); - * } else { - * console.log("Difference between both the matrices is not less than 0.1"); - * } - * - * //Prints "Difference between both the matrices is not less than 0.1" on the console */ - Matrix4.equalsEpsilon = function(left, right, epsilon) { + Matrix3.equalsEpsilon = function(left, right, epsilon) { Check.typeOf.number('epsilon', epsilon); return (left === right) || @@ -13918,463 +13743,140 @@ define('Core/Matrix4',[ Math.abs(left[5] - right[5]) <= epsilon && Math.abs(left[6] - right[6]) <= epsilon && Math.abs(left[7] - right[7]) <= epsilon && - Math.abs(left[8] - right[8]) <= epsilon && - Math.abs(left[9] - right[9]) <= epsilon && - Math.abs(left[10] - right[10]) <= epsilon && - Math.abs(left[11] - right[11]) <= epsilon && - Math.abs(left[12] - right[12]) <= epsilon && - Math.abs(left[13] - right[13]) <= epsilon && - Math.abs(left[14] - right[14]) <= epsilon && - Math.abs(left[15] - right[15]) <= epsilon); - }; - - /** - * Gets the translation portion of the provided matrix, assuming the matrix is a affine transformation matrix. - * - * @param {Matrix4} matrix The matrix to use. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. - */ - Matrix4.getTranslation = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result.x = matrix[12]; - result.y = matrix[13]; - result.z = matrix[14]; - return result; - }; - - /** - * Gets the upper left 3x3 rotation matrix of the provided matrix, assuming the matrix is a affine transformation matrix. - * - * @param {Matrix4} matrix The matrix to use. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix3} The modified result parameter. - * - * @example - * // returns a Matrix3 instance from a Matrix4 instance - * - * // m = [10.0, 14.0, 18.0, 22.0] - * // [11.0, 15.0, 19.0, 23.0] - * // [12.0, 16.0, 20.0, 24.0] - * // [13.0, 17.0, 21.0, 25.0] - * - * var b = new Cesium.Matrix3(); - * Cesium.Matrix4.getRotation(m,b); - * - * // b = [10.0, 14.0, 18.0] - * // [11.0, 15.0, 19.0] - * // [12.0, 16.0, 20.0] - */ - Matrix4.getRotation = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[4]; - result[4] = matrix[5]; - result[5] = matrix[6]; - result[6] = matrix[8]; - result[7] = matrix[9]; - result[8] = matrix[10]; - return result; - }; - - var scratchInverseRotation = new Matrix3(); - var scratchMatrix3Zero = new Matrix3(); - var scratchBottomRow = new Cartesian4(); - var scratchExpectedBottomRow = new Cartesian4(0.0, 0.0, 0.0, 1.0); - - /** - * Computes the inverse of the provided matrix using Cramers Rule. - * If the determinant is zero, the matrix can not be inverted, and an exception is thrown. - * If the matrix is an affine transformation matrix, it is more efficient - * to invert it with {@link Matrix4.inverseTransformation}. - * - * @param {Matrix4} matrix The matrix to invert. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - * - * @exception {RuntimeError} matrix is not invertible because its determinate is zero. - */ - Matrix4.inverse = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - // Special case for a zero scale matrix that can occur, for example, - // when a model's node has a [0, 0, 0] scale. - if (Matrix3.equalsEpsilon(Matrix4.getRotation(matrix, scratchInverseRotation), scratchMatrix3Zero, CesiumMath.EPSILON7) && - Cartesian4.equals(Matrix4.getRow(matrix, 3, scratchBottomRow), scratchExpectedBottomRow)) { - - result[0] = 0.0; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = 0.0; - result[5] = 0.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = 0.0; - result[11] = 0.0; - result[12] = -matrix[12]; - result[13] = -matrix[13]; - result[14] = -matrix[14]; - result[15] = 1.0; - return result; - } - - // - // Ported from: - // ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf - // - var src0 = matrix[0]; - var src1 = matrix[4]; - var src2 = matrix[8]; - var src3 = matrix[12]; - var src4 = matrix[1]; - var src5 = matrix[5]; - var src6 = matrix[9]; - var src7 = matrix[13]; - var src8 = matrix[2]; - var src9 = matrix[6]; - var src10 = matrix[10]; - var src11 = matrix[14]; - var src12 = matrix[3]; - var src13 = matrix[7]; - var src14 = matrix[11]; - var src15 = matrix[15]; - - // calculate pairs for first 8 elements (cofactors) - var tmp0 = src10 * src15; - var tmp1 = src11 * src14; - var tmp2 = src9 * src15; - var tmp3 = src11 * src13; - var tmp4 = src9 * src14; - var tmp5 = src10 * src13; - var tmp6 = src8 * src15; - var tmp7 = src11 * src12; - var tmp8 = src8 * src14; - var tmp9 = src10 * src12; - var tmp10 = src8 * src13; - var tmp11 = src9 * src12; - - // calculate first 8 elements (cofactors) - var dst0 = (tmp0 * src5 + tmp3 * src6 + tmp4 * src7) - (tmp1 * src5 + tmp2 * src6 + tmp5 * src7); - var dst1 = (tmp1 * src4 + tmp6 * src6 + tmp9 * src7) - (tmp0 * src4 + tmp7 * src6 + tmp8 * src7); - var dst2 = (tmp2 * src4 + tmp7 * src5 + tmp10 * src7) - (tmp3 * src4 + tmp6 * src5 + tmp11 * src7); - var dst3 = (tmp5 * src4 + tmp8 * src5 + tmp11 * src6) - (tmp4 * src4 + tmp9 * src5 + tmp10 * src6); - var dst4 = (tmp1 * src1 + tmp2 * src2 + tmp5 * src3) - (tmp0 * src1 + tmp3 * src2 + tmp4 * src3); - var dst5 = (tmp0 * src0 + tmp7 * src2 + tmp8 * src3) - (tmp1 * src0 + tmp6 * src2 + tmp9 * src3); - var dst6 = (tmp3 * src0 + tmp6 * src1 + tmp11 * src3) - (tmp2 * src0 + tmp7 * src1 + tmp10 * src3); - var dst7 = (tmp4 * src0 + tmp9 * src1 + tmp10 * src2) - (tmp5 * src0 + tmp8 * src1 + tmp11 * src2); - - // calculate pairs for second 8 elements (cofactors) - tmp0 = src2 * src7; - tmp1 = src3 * src6; - tmp2 = src1 * src7; - tmp3 = src3 * src5; - tmp4 = src1 * src6; - tmp5 = src2 * src5; - tmp6 = src0 * src7; - tmp7 = src3 * src4; - tmp8 = src0 * src6; - tmp9 = src2 * src4; - tmp10 = src0 * src5; - tmp11 = src1 * src4; - - // calculate second 8 elements (cofactors) - var dst8 = (tmp0 * src13 + tmp3 * src14 + tmp4 * src15) - (tmp1 * src13 + tmp2 * src14 + tmp5 * src15); - var dst9 = (tmp1 * src12 + tmp6 * src14 + tmp9 * src15) - (tmp0 * src12 + tmp7 * src14 + tmp8 * src15); - var dst10 = (tmp2 * src12 + tmp7 * src13 + tmp10 * src15) - (tmp3 * src12 + tmp6 * src13 + tmp11 * src15); - var dst11 = (tmp5 * src12 + tmp8 * src13 + tmp11 * src14) - (tmp4 * src12 + tmp9 * src13 + tmp10 * src14); - var dst12 = (tmp2 * src10 + tmp5 * src11 + tmp1 * src9) - (tmp4 * src11 + tmp0 * src9 + tmp3 * src10); - var dst13 = (tmp8 * src11 + tmp0 * src8 + tmp7 * src10) - (tmp6 * src10 + tmp9 * src11 + tmp1 * src8); - var dst14 = (tmp6 * src9 + tmp11 * src11 + tmp3 * src8) - (tmp10 * src11 + tmp2 * src8 + tmp7 * src9); - var dst15 = (tmp10 * src10 + tmp4 * src8 + tmp9 * src9) - (tmp8 * src9 + tmp11 * src10 + tmp5 * src8); - - // calculate determinant - var det = src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3; - - if (Math.abs(det) < CesiumMath.EPSILON20) { - throw new RuntimeError('matrix is not invertible because its determinate is zero.'); - } - - // calculate matrix inverse - det = 1.0 / det; - - result[0] = dst0 * det; - result[1] = dst1 * det; - result[2] = dst2 * det; - result[3] = dst3 * det; - result[4] = dst4 * det; - result[5] = dst5 * det; - result[6] = dst6 * det; - result[7] = dst7 * det; - result[8] = dst8 * det; - result[9] = dst9 * det; - result[10] = dst10 * det; - result[11] = dst11 * det; - result[12] = dst12 * det; - result[13] = dst13 * det; - result[14] = dst14 * det; - result[15] = dst15 * det; - return result; - }; - - /** - * Computes the inverse of the provided matrix assuming it is - * an affine transformation matrix, where the upper left 3x3 elements - * are a rotation matrix, and the upper three elements in the fourth - * column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. - * The matrix is not verified to be in the proper form. - * This method is faster than computing the inverse for a general 4x4 - * matrix using {@link Matrix4.inverse}. - * - * @param {Matrix4} matrix The matrix to invert. - * @param {Matrix4} result The object onto which to store the result. - * @returns {Matrix4} The modified result parameter. - */ - Matrix4.inverseTransformation = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - //This function is an optimized version of the below 4 lines. - //var rT = Matrix3.transpose(Matrix4.getRotation(matrix)); - //var rTN = Matrix3.negate(rT); - //var rTT = Matrix3.multiplyByVector(rTN, Matrix4.getTranslation(matrix)); - //return Matrix4.fromRotationTranslation(rT, rTT, result); - - var matrix0 = matrix[0]; - var matrix1 = matrix[1]; - var matrix2 = matrix[2]; - var matrix4 = matrix[4]; - var matrix5 = matrix[5]; - var matrix6 = matrix[6]; - var matrix8 = matrix[8]; - var matrix9 = matrix[9]; - var matrix10 = matrix[10]; - - var vX = matrix[12]; - var vY = matrix[13]; - var vZ = matrix[14]; - - var x = -matrix0 * vX - matrix1 * vY - matrix2 * vZ; - var y = -matrix4 * vX - matrix5 * vY - matrix6 * vZ; - var z = -matrix8 * vX - matrix9 * vY - matrix10 * vZ; - - result[0] = matrix0; - result[1] = matrix4; - result[2] = matrix8; - result[3] = 0.0; - result[4] = matrix1; - result[5] = matrix5; - result[6] = matrix9; - result[7] = 0.0; - result[8] = matrix2; - result[9] = matrix6; - result[10] = matrix10; - result[11] = 0.0; - result[12] = x; - result[13] = y; - result[14] = z; - result[15] = 1.0; - return result; + Math.abs(left[8] - right[8]) <= epsilon); }; /** - * An immutable Matrix4 instance initialized to the identity matrix. - * - * @type {Matrix4} - * @constant - */ - Matrix4.IDENTITY = freezeObject(new Matrix4(1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0)); - - /** - * An immutable Matrix4 instance initialized to the zero matrix. + * An immutable Matrix3 instance initialized to the identity matrix. * - * @type {Matrix4} + * @type {Matrix3} * @constant */ - Matrix4.ZERO = freezeObject(new Matrix4(0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0)); + Matrix3.IDENTITY = freezeObject(new Matrix3(1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0)); /** - * The index into Matrix4 for column 0, row 0. + * An immutable Matrix3 instance initialized to the zero matrix. * - * @type {Number} + * @type {Matrix3} * @constant */ - Matrix4.COLUMN0ROW0 = 0; + Matrix3.ZERO = freezeObject(new Matrix3(0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0)); /** - * The index into Matrix4 for column 0, row 1. + * The index into Matrix3 for column 0, row 0. * * @type {Number} * @constant */ - Matrix4.COLUMN0ROW1 = 1; + Matrix3.COLUMN0ROW0 = 0; /** - * The index into Matrix4 for column 0, row 2. + * The index into Matrix3 for column 0, row 1. * * @type {Number} * @constant */ - Matrix4.COLUMN0ROW2 = 2; + Matrix3.COLUMN0ROW1 = 1; /** - * The index into Matrix4 for column 0, row 3. + * The index into Matrix3 for column 0, row 2. * * @type {Number} * @constant */ - Matrix4.COLUMN0ROW3 = 3; + Matrix3.COLUMN0ROW2 = 2; /** - * The index into Matrix4 for column 1, row 0. + * The index into Matrix3 for column 1, row 0. * * @type {Number} * @constant */ - Matrix4.COLUMN1ROW0 = 4; + Matrix3.COLUMN1ROW0 = 3; /** - * The index into Matrix4 for column 1, row 1. + * The index into Matrix3 for column 1, row 1. * * @type {Number} * @constant */ - Matrix4.COLUMN1ROW1 = 5; + Matrix3.COLUMN1ROW1 = 4; /** - * The index into Matrix4 for column 1, row 2. + * The index into Matrix3 for column 1, row 2. * * @type {Number} * @constant */ - Matrix4.COLUMN1ROW2 = 6; + Matrix3.COLUMN1ROW2 = 5; /** - * The index into Matrix4 for column 1, row 3. + * The index into Matrix3 for column 2, row 0. * * @type {Number} * @constant */ - Matrix4.COLUMN1ROW3 = 7; + Matrix3.COLUMN2ROW0 = 6; /** - * The index into Matrix4 for column 2, row 0. + * The index into Matrix3 for column 2, row 1. * * @type {Number} * @constant */ - Matrix4.COLUMN2ROW0 = 8; + Matrix3.COLUMN2ROW1 = 7; /** - * The index into Matrix4 for column 2, row 1. + * The index into Matrix3 for column 2, row 2. * * @type {Number} * @constant */ - Matrix4.COLUMN2ROW1 = 9; + Matrix3.COLUMN2ROW2 = 8; - /** - * The index into Matrix4 for column 2, row 2. - * - * @type {Number} - * @constant - */ - Matrix4.COLUMN2ROW2 = 10; - - /** - * The index into Matrix4 for column 2, row 3. - * - * @type {Number} - * @constant - */ - Matrix4.COLUMN2ROW3 = 11; - - /** - * The index into Matrix4 for column 3, row 0. - * - * @type {Number} - * @constant - */ - Matrix4.COLUMN3ROW0 = 12; - - /** - * The index into Matrix4 for column 3, row 1. - * - * @type {Number} - * @constant - */ - Matrix4.COLUMN3ROW1 = 13; - - /** - * The index into Matrix4 for column 3, row 2. - * - * @type {Number} - * @constant - */ - Matrix4.COLUMN3ROW2 = 14; - - /** - * The index into Matrix4 for column 3, row 3. - * - * @type {Number} - * @constant - */ - Matrix4.COLUMN3ROW3 = 15; - - defineProperties(Matrix4.prototype, { + defineProperties(Matrix3.prototype, { /** * Gets the number of items in the collection. - * @memberof Matrix4.prototype + * @memberof Matrix3.prototype * * @type {Number} */ length : { get : function() { - return Matrix4.packedLength; + return Matrix3.packedLength; } } }); /** - * Duplicates the provided Matrix4 instance. + * Duplicates the provided Matrix3 instance. * - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. + * @param {Matrix3} [result] The object onto which to store the result. + * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. */ - Matrix4.prototype.clone = function(result) { - return Matrix4.clone(this, result); + Matrix3.prototype.clone = function(result) { + return Matrix3.clone(this, result); }; /** * Compares this matrix to the provided matrix componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {Matrix4} [right] The right hand side matrix. + * @param {Matrix3} [right] The right hand side matrix. * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ - Matrix4.prototype.equals = function(right) { - return Matrix4.equals(this, right); + Matrix3.prototype.equals = function(right) { + return Matrix3.equals(this, right); }; /** * @private */ - Matrix4.equalsArray = function(matrix, array, offset) { + Matrix3.equalsArray = function(matrix, array, offset) { return matrix[0] === array[offset] && matrix[1] === array[offset + 1] && matrix[2] === array[offset + 2] && @@ -14383,14 +13885,7 @@ define('Core/Matrix4',[ matrix[5] === array[offset + 5] && matrix[6] === array[offset + 6] && matrix[7] === array[offset + 7] && - matrix[8] === array[offset + 8] && - matrix[9] === array[offset + 9] && - matrix[10] === array[offset + 10] && - matrix[11] === array[offset + 11] && - matrix[12] === array[offset + 12] && - matrix[13] === array[offset + 13] && - matrix[14] === array[offset + 14] && - matrix[15] === array[offset + 15]; + matrix[8] === array[offset + 8]; }; /** @@ -14398,34618 +13893,34103 @@ define('Core/Matrix4',[ * <code>true</code> if they are within the provided epsilon, * <code>false</code> otherwise. * - * @param {Matrix4} [right] The right hand side matrix. + * @param {Matrix3} [right] The right hand side matrix. * @param {Number} epsilon The epsilon to use for equality testing. * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ - Matrix4.prototype.equalsEpsilon = function(right, epsilon) { - return Matrix4.equalsEpsilon(this, right, epsilon); + Matrix3.prototype.equalsEpsilon = function(right, epsilon) { + return Matrix3.equalsEpsilon(this, right, epsilon); }; /** - * Computes a string representing this Matrix with each row being - * on a separate line and in the format '(column0, column1, column2, column3)'. + * Creates a string representing this Matrix with each row being + * on a separate line and in the format '(column0, column1, column2)'. * - * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2, column3)'. + * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2)'. */ - Matrix4.prototype.toString = function() { - return '(' + this[0] + ', ' + this[4] + ', ' + this[8] + ', ' + this[12] +')\n' + - '(' + this[1] + ', ' + this[5] + ', ' + this[9] + ', ' + this[13] +')\n' + - '(' + this[2] + ', ' + this[6] + ', ' + this[10] + ', ' + this[14] +')\n' + - '(' + this[3] + ', ' + this[7] + ', ' + this[11] + ', ' + this[15] +')'; + Matrix3.prototype.toString = function() { + return '(' + this[0] + ', ' + this[3] + ', ' + this[6] + ')\n' + + '(' + this[1] + ', ' + this[4] + ', ' + this[7] + ')\n' + + '(' + this[2] + ', ' + this[5] + ', ' + this[8] + ')'; }; - return Matrix4; + return Matrix3; }); -define('Core/BoundingSphere',[ - './Cartesian3', - './Cartographic', +define('Core/Cartesian4',[ './Check', './defaultValue', './defined', - './Ellipsoid', - './GeographicProjection', - './Intersect', - './Interval', - './Matrix3', - './Matrix4', - './Rectangle' + './DeveloperError', + './freezeObject', + './Math' ], function( - Cartesian3, - Cartographic, Check, defaultValue, defined, - Ellipsoid, - GeographicProjection, - Intersect, - Interval, - Matrix3, - Matrix4, - Rectangle) { + DeveloperError, + freezeObject, + CesiumMath) { 'use strict'; /** - * A bounding sphere with a center and a radius. - * @alias BoundingSphere + * A 4D Cartesian point. + * @alias Cartesian4 * @constructor * - * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere. - * @param {Number} [radius=0.0] The radius of the bounding sphere. + * @param {Number} [x=0.0] The X component. + * @param {Number} [y=0.0] The Y component. + * @param {Number} [z=0.0] The Z component. + * @param {Number} [w=0.0] The W component. * - * @see AxisAlignedBoundingBox - * @see BoundingRectangle + * @see Cartesian2 + * @see Cartesian3 * @see Packable */ - function BoundingSphere(center, radius) { + function Cartesian4(x, y, z, w) { /** - * The center point of the sphere. - * @type {Cartesian3} - * @default {@link Cartesian3.ZERO} + * The X component. + * @type {Number} + * @default 0.0 */ - this.center = Cartesian3.clone(defaultValue(center, Cartesian3.ZERO)); + this.x = defaultValue(x, 0.0); /** - * The radius of the sphere. + * The Y component. * @type {Number} * @default 0.0 */ - this.radius = defaultValue(radius, 0.0); - } + this.y = defaultValue(y, 0.0); - var fromPointsXMin = new Cartesian3(); - var fromPointsYMin = new Cartesian3(); - var fromPointsZMin = new Cartesian3(); - var fromPointsXMax = new Cartesian3(); - var fromPointsYMax = new Cartesian3(); - var fromPointsZMax = new Cartesian3(); - var fromPointsCurrentPos = new Cartesian3(); - var fromPointsScratch = new Cartesian3(); - var fromPointsRitterCenter = new Cartesian3(); - var fromPointsMinBoxPt = new Cartesian3(); - var fromPointsMaxBoxPt = new Cartesian3(); - var fromPointsNaiveCenterScratch = new Cartesian3(); + /** + * The Z component. + * @type {Number} + * @default 0.0 + */ + this.z = defaultValue(z, 0.0); + + /** + * The W component. + * @type {Number} + * @default 0.0 + */ + this.w = defaultValue(w, 0.0); + } /** - * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. - * The bounding sphere is computed by running two algorithms, a naive algorithm and - * Ritter's algorithm. The smaller of the two spheres is used to ensure a tight fit. - * - * @param {Cartesian3[]} [positions] An array of points that the bounding sphere will enclose. Each point must have <code>x</code>, <code>y</code>, and <code>z</code> properties. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + * Creates a Cartesian4 instance from x, y, z and w coordinates. * - * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article} + * @param {Number} x The x coordinate. + * @param {Number} y The y coordinate. + * @param {Number} z The z coordinate. + * @param {Number} w The w coordinate. + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. */ - BoundingSphere.fromPoints = function(positions, result) { + Cartesian4.fromElements = function(x, y, z, w, result) { if (!defined(result)) { - result = new BoundingSphere(); - } - - if (!defined(positions) || positions.length === 0) { - result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = 0.0; - return result; - } - - var currentPos = Cartesian3.clone(positions[0], fromPointsCurrentPos); - - var xMin = Cartesian3.clone(currentPos, fromPointsXMin); - var yMin = Cartesian3.clone(currentPos, fromPointsYMin); - var zMin = Cartesian3.clone(currentPos, fromPointsZMin); - - var xMax = Cartesian3.clone(currentPos, fromPointsXMax); - var yMax = Cartesian3.clone(currentPos, fromPointsYMax); - var zMax = Cartesian3.clone(currentPos, fromPointsZMax); - - var numPositions = positions.length; - var i; - for (i = 1; i < numPositions; i++) { - Cartesian3.clone(positions[i], currentPos); - - var x = currentPos.x; - var y = currentPos.y; - var z = currentPos.z; - - // Store points containing the the smallest and largest components - if (x < xMin.x) { - Cartesian3.clone(currentPos, xMin); - } - - if (x > xMax.x) { - Cartesian3.clone(currentPos, xMax); - } - - if (y < yMin.y) { - Cartesian3.clone(currentPos, yMin); - } - - if (y > yMax.y) { - Cartesian3.clone(currentPos, yMax); - } - - if (z < zMin.z) { - Cartesian3.clone(currentPos, zMin); - } - - if (z > zMax.z) { - Cartesian3.clone(currentPos, zMax); - } - } - - // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). - var xSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(xMax, xMin, fromPointsScratch)); - var ySpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(yMax, yMin, fromPointsScratch)); - var zSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(zMax, zMin, fromPointsScratch)); - - // Set the diameter endpoints to the largest span. - var diameter1 = xMin; - var diameter2 = xMax; - var maxSpan = xSpan; - if (ySpan > maxSpan) { - maxSpan = ySpan; - diameter1 = yMin; - diameter2 = yMax; - } - if (zSpan > maxSpan) { - maxSpan = zSpan; - diameter1 = zMin; - diameter2 = zMax; - } - - // Calculate the center of the initial sphere found by Ritter's algorithm - var ritterCenter = fromPointsRitterCenter; - ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; - ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; - ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; - - // Calculate the radius of the initial sphere found by Ritter's algorithm - var radiusSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)); - var ritterRadius = Math.sqrt(radiusSquared); - - // Find the center of the sphere found using the Naive method. - var minBoxPt = fromPointsMinBoxPt; - minBoxPt.x = xMin.x; - minBoxPt.y = yMin.y; - minBoxPt.z = zMin.z; - - var maxBoxPt = fromPointsMaxBoxPt; - maxBoxPt.x = xMax.x; - maxBoxPt.y = yMax.y; - maxBoxPt.z = zMax.z; - - var naiveCenter = Cartesian3.multiplyByScalar(Cartesian3.add(minBoxPt, maxBoxPt, fromPointsScratch), 0.5, fromPointsNaiveCenterScratch); - - // Begin 2nd pass to find naive radius and modify the ritter sphere. - var naiveRadius = 0; - for (i = 0; i < numPositions; i++) { - Cartesian3.clone(positions[i], currentPos); - - // Find the furthest point from the naive center to calculate the naive radius. - var r = Cartesian3.magnitude(Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)); - if (r > naiveRadius) { - naiveRadius = r; - } - - // Make adjustments to the Ritter Sphere to include all points. - var oldCenterToPointSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)); - if (oldCenterToPointSquared > radiusSquared) { - var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); - // Calculate new radius to include the point that lies outside - ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; - radiusSquared = ritterRadius * ritterRadius; - // Calculate center of new Ritter sphere - var oldToNew = oldCenterToPoint - ritterRadius; - ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; - ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; - ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; - } - } - - if (ritterRadius < naiveRadius) { - Cartesian3.clone(ritterCenter, result.center); - result.radius = ritterRadius; - } else { - Cartesian3.clone(naiveCenter, result.center); - result.radius = naiveRadius; + return new Cartesian4(x, y, z, w); } + result.x = x; + result.y = y; + result.z = z; + result.w = w; return result; }; - var defaultProjection = new GeographicProjection(); - var fromRectangle2DLowerLeft = new Cartesian3(); - var fromRectangle2DUpperRight = new Cartesian3(); - var fromRectangle2DSouthwest = new Cartographic(); - var fromRectangle2DNortheast = new Cartographic(); - /** - * Computes a bounding sphere from a rectangle projected in 2D. + * Creates a Cartesian4 instance from a {@link Color}. <code>red</code>, <code>green</code>, <code>blue</code>, + * and <code>alpha</code> map to <code>x</code>, <code>y</code>, <code>z</code>, and <code>w</code>, respectively. * - * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere. - * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Color} color The source color. + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. */ - BoundingSphere.fromRectangle2D = function(rectangle, projection, result) { - return BoundingSphere.fromRectangleWithHeights2D(rectangle, projection, 0.0, 0.0, result); + Cartesian4.fromColor = function(color, result) { + Check.typeOf.object('color', color); + if (!defined(result)) { + return new Cartesian4(color.red, color.green, color.blue, color.alpha); + } + + result.x = color.red; + result.y = color.green; + result.z = color.blue; + result.w = color.alpha; + return result; }; /** - * Computes a bounding sphere from a rectangle projected in 2D. The bounding sphere accounts for the - * object's minimum and maximum heights over the rectangle. + * Duplicates a Cartesian4 instance. * - * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere. - * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. - * @param {Number} [minimumHeight=0.0] The minimum height over the rectangle. - * @param {Number} [maximumHeight=0.0] The maximum height over the rectangle. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} cartesian The Cartesian to duplicate. + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. (Returns undefined if cartesian is undefined) */ - BoundingSphere.fromRectangleWithHeights2D = function(rectangle, projection, minimumHeight, maximumHeight, result) { - if (!defined(result)) { - result = new BoundingSphere(); + Cartesian4.clone = function(cartesian, result) { + if (!defined(cartesian)) { + return undefined; } - if (!defined(rectangle)) { - result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = 0.0; - return result; + if (!defined(result)) { + return new Cartesian4(cartesian.x, cartesian.y, cartesian.z, cartesian.w); } - projection = defaultValue(projection, defaultProjection); - - Rectangle.southwest(rectangle, fromRectangle2DSouthwest); - fromRectangle2DSouthwest.height = minimumHeight; - Rectangle.northeast(rectangle, fromRectangle2DNortheast); - fromRectangle2DNortheast.height = maximumHeight; - - var lowerLeft = projection.project(fromRectangle2DSouthwest, fromRectangle2DLowerLeft); - var upperRight = projection.project(fromRectangle2DNortheast, fromRectangle2DUpperRight); - - var width = upperRight.x - lowerLeft.x; - var height = upperRight.y - lowerLeft.y; - var elevation = upperRight.z - lowerLeft.z; - - result.radius = Math.sqrt(width * width + height * height + elevation * elevation) * 0.5; - var center = result.center; - center.x = lowerLeft.x + width * 0.5; - center.y = lowerLeft.y + height * 0.5; - center.z = lowerLeft.z + elevation * 0.5; + result.x = cartesian.x; + result.y = cartesian.y; + result.z = cartesian.z; + result.w = cartesian.w; return result; }; - var fromRectangle3DScratch = []; /** - * Computes a bounding sphere from a rectangle in 3D. The bounding sphere is created using a subsample of points - * on the ellipsoid and contained in the rectangle. It may not be accurate for all rectangles on all types of ellipsoids. - * - * @param {Rectangle} [rectangle] The valid rectangle used to create a bounding sphere. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle. - * @param {Number} [surfaceHeight=0.0] The height above the surface of the ellipsoid. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * The number of elements used to pack the object into an array. + * @type {Number} */ - BoundingSphere.fromRectangle3D = function(rectangle, ellipsoid, surfaceHeight, result) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - surfaceHeight = defaultValue(surfaceHeight, 0.0); - - if (!defined(result)) { - result = new BoundingSphere(); - } - - if (!defined(rectangle)) { - result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = 0.0; - return result; - } - - var positions = Rectangle.subsample(rectangle, ellipsoid, surfaceHeight, fromRectangle3DScratch); - return BoundingSphere.fromPoints(positions, result); - }; + Cartesian4.packedLength = 4; /** - * Computes a tight-fitting bounding sphere enclosing a list of 3D points, where the points are - * stored in a flat array in X, Y, Z, order. The bounding sphere is computed by running two - * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to - * ensure a tight fit. - * - * @param {Number[]} [positions] An array of points that the bounding sphere will enclose. Each point - * is formed from three elements in the array in the order X, Y, Z. - * @param {Cartesian3} [center=Cartesian3.ZERO] The position to which the positions are relative, which need not be the - * origin of the coordinate system. This is useful when the positions are to be used for - * relative-to-center (RTC) rendering. - * @param {Number} [stride=3] The number of array elements per vertex. It must be at least 3, but it may - * be higher. Regardless of the value of this parameter, the X coordinate of the first position - * is at array index 0, the Y coordinate is at array index 1, and the Z coordinate is at array index - * 2. When stride is 3, the X coordinate of the next position then begins at array index 3. If - * the stride is 5, however, two array elements are skipped and the next position begins at array - * index 5. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + * Stores the provided instance into the provided array. * - * @example - * // Compute the bounding sphere from 3 positions, each specified relative to a center. - * // In addition to the X, Y, and Z coordinates, the points array contains two additional - * // elements per point which are ignored for the purpose of computing the bounding sphere. - * var center = new Cesium.Cartesian3(1.0, 2.0, 3.0); - * var points = [1.0, 2.0, 3.0, 0.1, 0.2, - * 4.0, 5.0, 6.0, 0.1, 0.2, - * 7.0, 8.0, 9.0, 0.1, 0.2]; - * var sphere = Cesium.BoundingSphere.fromVertices(points, center, 5); + * @param {Cartesian4} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article} + * @returns {Number[]} The array that was packed into */ - BoundingSphere.fromVertices = function(positions, center, stride, result) { - if (!defined(result)) { - result = new BoundingSphere(); - } - - if (!defined(positions) || positions.length === 0) { - result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = 0.0; - return result; - } - - center = defaultValue(center, Cartesian3.ZERO); - - stride = defaultValue(stride, 3); - - Check.typeOf.number.greaterThanOrEquals('stride', stride, 3); + Cartesian4.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); - var currentPos = fromPointsCurrentPos; - currentPos.x = positions[0] + center.x; - currentPos.y = positions[1] + center.y; - currentPos.z = positions[2] + center.z; - - var xMin = Cartesian3.clone(currentPos, fromPointsXMin); - var yMin = Cartesian3.clone(currentPos, fromPointsYMin); - var zMin = Cartesian3.clone(currentPos, fromPointsZMin); - - var xMax = Cartesian3.clone(currentPos, fromPointsXMax); - var yMax = Cartesian3.clone(currentPos, fromPointsYMax); - var zMax = Cartesian3.clone(currentPos, fromPointsZMax); - - var numElements = positions.length; - var i; - for (i = 0; i < numElements; i += stride) { - var x = positions[i] + center.x; - var y = positions[i + 1] + center.y; - var z = positions[i + 2] + center.z; - - currentPos.x = x; - currentPos.y = y; - currentPos.z = z; - - // Store points containing the the smallest and largest components - if (x < xMin.x) { - Cartesian3.clone(currentPos, xMin); - } - - if (x > xMax.x) { - Cartesian3.clone(currentPos, xMax); - } - - if (y < yMin.y) { - Cartesian3.clone(currentPos, yMin); - } - - if (y > yMax.y) { - Cartesian3.clone(currentPos, yMax); - } - - if (z < zMin.z) { - Cartesian3.clone(currentPos, zMin); - } - - if (z > zMax.z) { - Cartesian3.clone(currentPos, zMax); - } - } - - // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). - var xSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(xMax, xMin, fromPointsScratch)); - var ySpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(yMax, yMin, fromPointsScratch)); - var zSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(zMax, zMin, fromPointsScratch)); - - // Set the diameter endpoints to the largest span. - var diameter1 = xMin; - var diameter2 = xMax; - var maxSpan = xSpan; - if (ySpan > maxSpan) { - maxSpan = ySpan; - diameter1 = yMin; - diameter2 = yMax; - } - if (zSpan > maxSpan) { - maxSpan = zSpan; - diameter1 = zMin; - diameter2 = zMax; - } - - // Calculate the center of the initial sphere found by Ritter's algorithm - var ritterCenter = fromPointsRitterCenter; - ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; - ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; - ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; - - // Calculate the radius of the initial sphere found by Ritter's algorithm - var radiusSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)); - var ritterRadius = Math.sqrt(radiusSquared); - - // Find the center of the sphere found using the Naive method. - var minBoxPt = fromPointsMinBoxPt; - minBoxPt.x = xMin.x; - minBoxPt.y = yMin.y; - minBoxPt.z = zMin.z; - - var maxBoxPt = fromPointsMaxBoxPt; - maxBoxPt.x = xMax.x; - maxBoxPt.y = yMax.y; - maxBoxPt.z = zMax.z; - - var naiveCenter = Cartesian3.multiplyByScalar(Cartesian3.add(minBoxPt, maxBoxPt, fromPointsScratch), 0.5, fromPointsNaiveCenterScratch); + startingIndex = defaultValue(startingIndex, 0); - // Begin 2nd pass to find naive radius and modify the ritter sphere. - var naiveRadius = 0; - for (i = 0; i < numElements; i += stride) { - currentPos.x = positions[i] + center.x; - currentPos.y = positions[i + 1] + center.y; - currentPos.z = positions[i + 2] + center.z; + array[startingIndex++] = value.x; + array[startingIndex++] = value.y; + array[startingIndex++] = value.z; + array[startingIndex] = value.w; - // Find the furthest point from the naive center to calculate the naive radius. - var r = Cartesian3.magnitude(Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)); - if (r > naiveRadius) { - naiveRadius = r; - } + return array; + }; - // Make adjustments to the Ritter Sphere to include all points. - var oldCenterToPointSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)); - if (oldCenterToPointSquared > radiusSquared) { - var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); - // Calculate new radius to include the point that lies outside - ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; - radiusSquared = ritterRadius * ritterRadius; - // Calculate center of new Ritter sphere - var oldToNew = oldCenterToPoint - ritterRadius; - ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; - ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; - ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; - } - } + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Cartesian4} [result] The object into which to store the result. + * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. + */ + Cartesian4.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - if (ritterRadius < naiveRadius) { - Cartesian3.clone(ritterCenter, result.center); - result.radius = ritterRadius; - } else { - Cartesian3.clone(naiveCenter, result.center); - result.radius = naiveRadius; + if (!defined(result)) { + result = new Cartesian4(); } - + result.x = array[startingIndex++]; + result.y = array[startingIndex++]; + result.z = array[startingIndex++]; + result.w = array[startingIndex]; return result; }; /** - * Computes a tight-fitting bounding sphere enclosing a list of {@link EncodedCartesian3}s, where the points are - * stored in parallel flat arrays in X, Y, Z, order. The bounding sphere is computed by running two - * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to - * ensure a tight fit. - * - * @param {Number[]} [positionsHigh] An array of high bits of the encoded cartesians that the bounding sphere will enclose. Each point - * is formed from three elements in the array in the order X, Y, Z. - * @param {Number[]} [positionsLow] An array of low bits of the encoded cartesians that the bounding sphere will enclose. Each point - * is formed from three elements in the array in the order X, Y, Z. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + * Flattens an array of Cartesian4s into and array of components. * - * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article} + * @param {Cartesian4[]} array The array of cartesians to pack. + * @param {Number[]} result The array onto which to store the result. + * @returns {Number[]} The packed array. */ - BoundingSphere.fromEncodedCartesianVertices = function(positionsHigh, positionsLow, result) { + Cartesian4.packArray = function(array, result) { + Check.defined('array', array); + + var length = array.length; if (!defined(result)) { - result = new BoundingSphere(); - } - - if (!defined(positionsHigh) || !defined(positionsLow) || positionsHigh.length !== positionsLow.length || positionsHigh.length === 0) { - result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = 0.0; - return result; - } - - var currentPos = fromPointsCurrentPos; - currentPos.x = positionsHigh[0] + positionsLow[0]; - currentPos.y = positionsHigh[1] + positionsLow[1]; - currentPos.z = positionsHigh[2] + positionsLow[2]; - - var xMin = Cartesian3.clone(currentPos, fromPointsXMin); - var yMin = Cartesian3.clone(currentPos, fromPointsYMin); - var zMin = Cartesian3.clone(currentPos, fromPointsZMin); - - var xMax = Cartesian3.clone(currentPos, fromPointsXMax); - var yMax = Cartesian3.clone(currentPos, fromPointsYMax); - var zMax = Cartesian3.clone(currentPos, fromPointsZMax); - - var numElements = positionsHigh.length; - var i; - for (i = 0; i < numElements; i += 3) { - var x = positionsHigh[i] + positionsLow[i]; - var y = positionsHigh[i + 1] + positionsLow[i + 1]; - var z = positionsHigh[i + 2] + positionsLow[i + 2]; - - currentPos.x = x; - currentPos.y = y; - currentPos.z = z; - - // Store points containing the the smallest and largest components - if (x < xMin.x) { - Cartesian3.clone(currentPos, xMin); - } - - if (x > xMax.x) { - Cartesian3.clone(currentPos, xMax); - } - - if (y < yMin.y) { - Cartesian3.clone(currentPos, yMin); - } - - if (y > yMax.y) { - Cartesian3.clone(currentPos, yMax); - } - - if (z < zMin.z) { - Cartesian3.clone(currentPos, zMin); - } - - if (z > zMax.z) { - Cartesian3.clone(currentPos, zMax); - } - } - - // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). - var xSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(xMax, xMin, fromPointsScratch)); - var ySpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(yMax, yMin, fromPointsScratch)); - var zSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(zMax, zMin, fromPointsScratch)); - - // Set the diameter endpoints to the largest span. - var diameter1 = xMin; - var diameter2 = xMax; - var maxSpan = xSpan; - if (ySpan > maxSpan) { - maxSpan = ySpan; - diameter1 = yMin; - diameter2 = yMax; - } - if (zSpan > maxSpan) { - maxSpan = zSpan; - diameter1 = zMin; - diameter2 = zMax; - } - - // Calculate the center of the initial sphere found by Ritter's algorithm - var ritterCenter = fromPointsRitterCenter; - ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; - ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; - ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; - - // Calculate the radius of the initial sphere found by Ritter's algorithm - var radiusSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)); - var ritterRadius = Math.sqrt(radiusSquared); - - // Find the center of the sphere found using the Naive method. - var minBoxPt = fromPointsMinBoxPt; - minBoxPt.x = xMin.x; - minBoxPt.y = yMin.y; - minBoxPt.z = zMin.z; - - var maxBoxPt = fromPointsMaxBoxPt; - maxBoxPt.x = xMax.x; - maxBoxPt.y = yMax.y; - maxBoxPt.z = zMax.z; - - var naiveCenter = Cartesian3.multiplyByScalar(Cartesian3.add(minBoxPt, maxBoxPt, fromPointsScratch), 0.5, fromPointsNaiveCenterScratch); - - // Begin 2nd pass to find naive radius and modify the ritter sphere. - var naiveRadius = 0; - for (i = 0; i < numElements; i += 3) { - currentPos.x = positionsHigh[i] + positionsLow[i]; - currentPos.y = positionsHigh[i + 1] + positionsLow[i + 1]; - currentPos.z = positionsHigh[i + 2] + positionsLow[i + 2]; - - // Find the furthest point from the naive center to calculate the naive radius. - var r = Cartesian3.magnitude(Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)); - if (r > naiveRadius) { - naiveRadius = r; - } - - // Make adjustments to the Ritter Sphere to include all points. - var oldCenterToPointSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)); - if (oldCenterToPointSquared > radiusSquared) { - var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); - // Calculate new radius to include the point that lies outside - ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; - radiusSquared = ritterRadius * ritterRadius; - // Calculate center of new Ritter sphere - var oldToNew = oldCenterToPoint - ritterRadius; - ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; - ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; - ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; - } - } - - if (ritterRadius < naiveRadius) { - Cartesian3.clone(ritterCenter, result.center); - result.radius = ritterRadius; + result = new Array(length * 4); } else { - Cartesian3.clone(naiveCenter, result.center); - result.radius = naiveRadius; + result.length = length * 4; } + for (var i = 0; i < length; ++i) { + Cartesian4.pack(array[i], result, i * 4); + } return result; }; /** - * Computes a bounding sphere from the corner points of an axis-aligned bounding box. The sphere - * tighly and fully encompases the box. - * - * @param {Cartesian3} [corner] The minimum height over the rectangle. - * @param {Cartesian3} [oppositeCorner] The maximum height over the rectangle. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * Unpacks an array of cartesian components into and array of Cartesian4s. * - * @example - * // Create a bounding sphere around the unit cube - * var sphere = Cesium.BoundingSphere.fromCornerPoints(new Cesium.Cartesian3(-0.5, -0.5, -0.5), new Cesium.Cartesian3(0.5, 0.5, 0.5)); + * @param {Number[]} array The array of components to unpack. + * @param {Cartesian4[]} result The array onto which to store the result. + * @returns {Cartesian4[]} The unpacked array. */ - BoundingSphere.fromCornerPoints = function(corner, oppositeCorner, result) { - Check.typeOf.object('corner', corner); - Check.typeOf.object('oppositeCorner', oppositeCorner); + Cartesian4.unpackArray = function(array, result) { + Check.defined('array', array); + var length = array.length; if (!defined(result)) { - result = new BoundingSphere(); + result = new Array(length / 4); + } else { + result.length = length / 4; } - var center = result.center; - Cartesian3.add(corner, oppositeCorner, center); - Cartesian3.multiplyByScalar(center, 0.5, center); - result.radius = Cartesian3.distance(center, oppositeCorner); + for (var i = 0; i < length; i += 4) { + var index = i / 4; + result[index] = Cartesian4.unpack(array, i, result[index]); + } return result; }; /** - * Creates a bounding sphere encompassing an ellipsoid. + * Creates a Cartesian4 from four consecutive elements in an array. + * @function * - * @param {Ellipsoid} ellipsoid The ellipsoid around which to create a bounding sphere. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively. + * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. * * @example - * var boundingSphere = Cesium.BoundingSphere.fromEllipsoid(ellipsoid); + * // Create a Cartesian4 with (1.0, 2.0, 3.0, 4.0) + * var v = [1.0, 2.0, 3.0, 4.0]; + * var p = Cesium.Cartesian4.fromArray(v); + * + * // Create a Cartesian4 with (1.0, 2.0, 3.0, 4.0) using an offset into an array + * var v2 = [0.0, 0.0, 1.0, 2.0, 3.0, 4.0]; + * var p2 = Cesium.Cartesian4.fromArray(v2, 2); */ - BoundingSphere.fromEllipsoid = function(ellipsoid, result) { - Check.typeOf.object('ellipsoid', ellipsoid); - - if (!defined(result)) { - result = new BoundingSphere(); - } + Cartesian4.fromArray = Cartesian4.unpack; - Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = ellipsoid.maximumRadius; - return result; + /** + * Computes the value of the maximum component for the supplied Cartesian. + * + * @param {Cartesian4} cartesian The cartesian to use. + * @returns {Number} The value of the maximum component. + */ + Cartesian4.maximumComponent = function(cartesian) { + Check.typeOf.object('cartesian', cartesian); + + return Math.max(cartesian.x, cartesian.y, cartesian.z, cartesian.w); }; - var fromBoundingSpheresScratch = new Cartesian3(); - /** - * Computes a tight-fitting bounding sphere enclosing the provided array of bounding spheres. + * Computes the value of the minimum component for the supplied Cartesian. * - * @param {BoundingSphere[]} [boundingSpheres] The array of bounding spheres. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} cartesian The cartesian to use. + * @returns {Number} The value of the minimum component. */ - BoundingSphere.fromBoundingSpheres = function(boundingSpheres, result) { - if (!defined(result)) { - result = new BoundingSphere(); - } - - if (!defined(boundingSpheres) || boundingSpheres.length === 0) { - result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); - result.radius = 0.0; - return result; - } - - var length = boundingSpheres.length; - if (length === 1) { - return BoundingSphere.clone(boundingSpheres[0], result); - } - - if (length === 2) { - return BoundingSphere.union(boundingSpheres[0], boundingSpheres[1], result); - } - - var positions = []; - var i; - for (i = 0; i < length; i++) { - positions.push(boundingSpheres[i].center); - } - - result = BoundingSphere.fromPoints(positions, result); - - var center = result.center; - var radius = result.radius; - for (i = 0; i < length; i++) { - var tmp = boundingSpheres[i]; - radius = Math.max(radius, Cartesian3.distance(center, tmp.center, fromBoundingSpheresScratch) + tmp.radius); - } - result.radius = radius; - - return result; + Cartesian4.minimumComponent = function(cartesian) { + Check.typeOf.object('cartesian', cartesian); + + return Math.min(cartesian.x, cartesian.y, cartesian.z, cartesian.w); }; - var fromOrientedBoundingBoxScratchU = new Cartesian3(); - var fromOrientedBoundingBoxScratchV = new Cartesian3(); - var fromOrientedBoundingBoxScratchW = new Cartesian3(); - /** - * Computes a tight-fitting bounding sphere enclosing the provided oriented bounding box. + * Compares two Cartesians and computes a Cartesian which contains the minimum components of the supplied Cartesians. * - * @param {OrientedBoundingBox} orientedBoundingBox The oriented bounding box. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} first A cartesian to compare. + * @param {Cartesian4} second A cartesian to compare. + * @param {Cartesian4} result The object into which to store the result. + * @returns {Cartesian4} A cartesian with the minimum components. */ - BoundingSphere.fromOrientedBoundingBox = function(orientedBoundingBox, result) { - Check.defined('orientedBoundingBox', orientedBoundingBox); + Cartesian4.minimumByComponent = function(first, second, result) { + Check.typeOf.object('first', first); + Check.typeOf.object('second', second); + Check.typeOf.object('result', result); - if (!defined(result)) { - result = new BoundingSphere(); - } - - var halfAxes = orientedBoundingBox.halfAxes; - var u = Matrix3.getColumn(halfAxes, 0, fromOrientedBoundingBoxScratchU); - var v = Matrix3.getColumn(halfAxes, 1, fromOrientedBoundingBoxScratchV); - var w = Matrix3.getColumn(halfAxes, 2, fromOrientedBoundingBoxScratchW); - - Cartesian3.add(u, v, u); - Cartesian3.add(u, w, u); - - result.center = Cartesian3.clone(orientedBoundingBox.center, result.center); - result.radius = Cartesian3.magnitude(u); + result.x = Math.min(first.x, second.x); + result.y = Math.min(first.y, second.y); + result.z = Math.min(first.z, second.z); + result.w = Math.min(first.w, second.w); return result; }; /** - * Duplicates a BoundingSphere instance. + * Compares two Cartesians and computes a Cartesian which contains the maximum components of the supplied Cartesians. * - * @param {BoundingSphere} sphere The bounding sphere to duplicate. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. (Returns undefined if sphere is undefined) + * @param {Cartesian4} first A cartesian to compare. + * @param {Cartesian4} second A cartesian to compare. + * @param {Cartesian4} result The object into which to store the result. + * @returns {Cartesian4} A cartesian with the maximum components. */ - BoundingSphere.clone = function(sphere, result) { - if (!defined(sphere)) { - return undefined; - } - - if (!defined(result)) { - return new BoundingSphere(sphere.center, sphere.radius); - } + Cartesian4.maximumByComponent = function(first, second, result) { + Check.typeOf.object('first', first); + Check.typeOf.object('second', second); + Check.typeOf.object('result', result); + + result.x = Math.max(first.x, second.x); + result.y = Math.max(first.y, second.y); + result.z = Math.max(first.z, second.z); + result.w = Math.max(first.w, second.w); - result.center = Cartesian3.clone(sphere.center, result.center); - result.radius = sphere.radius; return result; }; /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - BoundingSphere.packedLength = 4; - - /** - * Stores the provided instance into the provided array. - * - * @param {BoundingSphere} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * Computes the provided Cartesian's squared magnitude. * - * @returns {Number[]} The array that was packed into + * @param {Cartesian4} cartesian The Cartesian instance whose squared magnitude is to be computed. + * @returns {Number} The squared magnitude. */ - BoundingSphere.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + Cartesian4.magnitudeSquared = function(cartesian) { + Check.typeOf.object('cartesian', cartesian); - startingIndex = defaultValue(startingIndex, 0); - - var center = value.center; - array[startingIndex++] = center.x; - array[startingIndex++] = center.y; - array[startingIndex++] = center.z; - array[startingIndex] = value.radius; - - return array; + return cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z + cartesian.w * cartesian.w; }; /** - * Retrieves an instance from a packed array. + * Computes the Cartesian's magnitude (length). * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {BoundingSphere} [result] The object into which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. - */ - BoundingSphere.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + * @param {Cartesian4} cartesian The Cartesian instance whose magnitude is to be computed. + * @returns {Number} The magnitude. + */ + Cartesian4.magnitude = function(cartesian) { + return Math.sqrt(Cartesian4.magnitudeSquared(cartesian)); + }; - if (!defined(result)) { - result = new BoundingSphere(); - } + var distanceScratch = new Cartesian4(); - var center = result.center; - center.x = array[startingIndex++]; - center.y = array[startingIndex++]; - center.z = array[startingIndex++]; - result.radius = array[startingIndex]; - return result; + /** + * Computes the 4-space distance between two points. + * + * @param {Cartesian4} left The first point to compute the distance from. + * @param {Cartesian4} right The second point to compute the distance to. + * @returns {Number} The distance between two points. + * + * @example + * // Returns 1.0 + * var d = Cesium.Cartesian4.distance( + * new Cesium.Cartesian4(1.0, 0.0, 0.0, 0.0), + * new Cesium.Cartesian4(2.0, 0.0, 0.0, 0.0)); + */ + Cartesian4.distance = function(left, right) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + + Cartesian4.subtract(left, right, distanceScratch); + return Cartesian4.magnitude(distanceScratch); }; - var unionScratch = new Cartesian3(); - var unionScratchCenter = new Cartesian3(); /** - * Computes a bounding sphere that contains both the left and right bounding spheres. + * Computes the squared distance between two points. Comparing squared distances + * using this function is more efficient than comparing distances using {@link Cartesian4#distance}. * - * @param {BoundingSphere} left A sphere to enclose in a bounding sphere. - * @param {BoundingSphere} right A sphere to enclose in a bounding sphere. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} left The first point to compute the distance from. + * @param {Cartesian4} right The second point to compute the distance to. + * @returns {Number} The distance between two points. + * + * @example + * // Returns 4.0, not 2.0 + * var d = Cesium.Cartesian4.distance( + * new Cesium.Cartesian4(1.0, 0.0, 0.0, 0.0), + * new Cesium.Cartesian4(3.0, 0.0, 0.0, 0.0)); */ - BoundingSphere.union = function(left, right, result) { + Cartesian4.distanceSquared = function(left, right) { Check.typeOf.object('left', left); Check.typeOf.object('right', right); - if (!defined(result)) { - result = new BoundingSphere(); - } - - var leftCenter = left.center; - var leftRadius = left.radius; - var rightCenter = right.center; - var rightRadius = right.radius; + Cartesian4.subtract(left, right, distanceScratch); + return Cartesian4.magnitudeSquared(distanceScratch); + }; - var toRightCenter = Cartesian3.subtract(rightCenter, leftCenter, unionScratch); - var centerSeparation = Cartesian3.magnitude(toRightCenter); + /** + * Computes the normalized form of the supplied Cartesian. + * + * @param {Cartesian4} cartesian The Cartesian to be normalized. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. + */ + Cartesian4.normalize = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var magnitude = Cartesian4.magnitude(cartesian); - if (leftRadius >= (centerSeparation + rightRadius)) { - // Left sphere wins. - left.clone(result); - return result; - } + result.x = cartesian.x / magnitude; + result.y = cartesian.y / magnitude; + result.z = cartesian.z / magnitude; + result.w = cartesian.w / magnitude; - if (rightRadius >= (centerSeparation + leftRadius)) { - // Right sphere wins. - right.clone(result); - return result; + if (isNaN(result.x) || isNaN(result.y) || isNaN(result.z) || isNaN(result.w)) { + throw new DeveloperError('normalized result is not a number'); } - - // There are two tangent points, one on far side of each sphere. - var halfDistanceBetweenTangentPoints = (leftRadius + centerSeparation + rightRadius) * 0.5; - - // Compute the center point halfway between the two tangent points. - var center = Cartesian3.multiplyByScalar(toRightCenter, - (-leftRadius + halfDistanceBetweenTangentPoints) / centerSeparation, unionScratchCenter); - Cartesian3.add(center, leftCenter, center); - Cartesian3.clone(center, result.center); - result.radius = halfDistanceBetweenTangentPoints; - + return result; }; - var expandScratch = new Cartesian3(); /** - * Computes a bounding sphere by enlarging the provided sphere to contain the provided point. + * Computes the dot (scalar) product of two Cartesians. * - * @param {BoundingSphere} sphere A sphere to expand. - * @param {Cartesian3} point A point to enclose in a bounding sphere. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} left The first Cartesian. + * @param {Cartesian4} right The second Cartesian. + * @returns {Number} The dot product. */ - BoundingSphere.expand = function(sphere, point, result) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('point', point); + Cartesian4.dot = function(left, right) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); - result = BoundingSphere.clone(sphere, result); - - var radius = Cartesian3.magnitude(Cartesian3.subtract(point, result.center, expandScratch)); - if (radius > result.radius) { - result.radius = radius; - } + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + }; + /** + * Computes the componentwise product of two Cartesians. + * + * @param {Cartesian4} left The first Cartesian. + * @param {Cartesian4} right The second Cartesian. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. + */ + Cartesian4.multiplyComponents = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.x = left.x * right.x; + result.y = left.y * right.y; + result.z = left.z * right.z; + result.w = left.w * right.w; return result; }; /** - * Determines which side of a plane a sphere is located. + * Computes the componentwise quotient of two Cartesians. * - * @param {BoundingSphere} sphere The bounding sphere to test. - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is - * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere - * intersects the plane. + * @param {Cartesian4} left The first Cartesian. + * @param {Cartesian4} right The second Cartesian. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.intersectPlane = function(sphere, plane) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('plane', plane); + Cartesian4.divideComponents = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); - var center = sphere.center; - var radius = sphere.radius; - var normal = plane.normal; - var distanceToPlane = Cartesian3.dot(normal, center) + plane.distance; - - if (distanceToPlane < -radius) { - // The center point is negative side of the plane normal - return Intersect.OUTSIDE; - } else if (distanceToPlane < radius) { - // The center point is positive side of the plane, but radius extends beyond it; partial overlap - return Intersect.INTERSECTING; - } - return Intersect.INSIDE; + result.x = left.x / right.x; + result.y = left.y / right.y; + result.z = left.z / right.z; + result.w = left.w / right.w; + return result; }; /** - * Applies a 4x4 affine transformation matrix to a bounding sphere. + * Computes the componentwise sum of two Cartesians. * - * @param {BoundingSphere} sphere The bounding sphere to apply the transformation to. - * @param {Matrix4} transform The transformation matrix to apply to the bounding sphere. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} left The first Cartesian. + * @param {Cartesian4} right The second Cartesian. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.transform = function(sphere, transform, result) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('transform', transform); + Cartesian4.add = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); - if (!defined(result)) { - result = new BoundingSphere(); - } - - result.center = Matrix4.multiplyByPoint(transform, sphere.center, result.center); - result.radius = Matrix4.getMaximumScale(transform) * sphere.radius; - + result.x = left.x + right.x; + result.y = left.y + right.y; + result.z = left.z + right.z; + result.w = left.w + right.w; return result; }; - var distanceSquaredToScratch = new Cartesian3(); - /** - * Computes the estimated distance squared from the closest point on a bounding sphere to a point. - * - * @param {BoundingSphere} sphere The sphere. - * @param {Cartesian3} cartesian The point - * @returns {Number} The estimated distance squared from the bounding sphere to the point. + * Computes the componentwise difference of two Cartesians. * - * @example - * // Sort bounding spheres from back to front - * spheres.sort(function(a, b) { - * return Cesium.BoundingSphere.distanceSquaredTo(b, camera.positionWC) - Cesium.BoundingSphere.distanceSquaredTo(a, camera.positionWC); - * }); + * @param {Cartesian4} left The first Cartesian. + * @param {Cartesian4} right The second Cartesian. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.distanceSquaredTo = function(sphere, cartesian) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('cartesian', cartesian); + Cartesian4.subtract = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); - var diff = Cartesian3.subtract(sphere.center, cartesian, distanceSquaredToScratch); - return Cartesian3.magnitudeSquared(diff) - sphere.radius * sphere.radius; + result.x = left.x - right.x; + result.y = left.y - right.y; + result.z = left.z - right.z; + result.w = left.w - right.w; + return result; }; /** - * Applies a 4x4 affine transformation matrix to a bounding sphere where there is no scale - * The transformation matrix is not verified to have a uniform scale of 1. - * This method is faster than computing the general bounding sphere transform using {@link BoundingSphere.transform}. - * - * @param {BoundingSphere} sphere The bounding sphere to apply the transformation to. - * @param {Matrix4} transform The transformation matrix to apply to the bounding sphere. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * Multiplies the provided Cartesian componentwise by the provided scalar. * - * @example - * var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid); - * var boundingSphere = new Cesium.BoundingSphere(); - * var newBoundingSphere = Cesium.BoundingSphere.transformWithoutScale(boundingSphere, modelMatrix); + * @param {Cartesian4} cartesian The Cartesian to be scaled. + * @param {Number} scalar The scalar to multiply with. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.transformWithoutScale = function(sphere, transform, result) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('transform', transform); + Cartesian4.multiplyByScalar = function(cartesian, scalar, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); - if (!defined(result)) { - result = new BoundingSphere(); - } - - result.center = Matrix4.multiplyByPoint(transform, sphere.center, result.center); - result.radius = sphere.radius; - + result.x = cartesian.x * scalar; + result.y = cartesian.y * scalar; + result.z = cartesian.z * scalar; + result.w = cartesian.w * scalar; return result; }; - var scratchCartesian3 = new Cartesian3(); /** - * The distances calculated by the vector from the center of the bounding sphere to position projected onto direction - * plus/minus the radius of the bounding sphere. - * <br> - * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the - * closest and farthest planes from position that intersect the bounding sphere. + * Divides the provided Cartesian componentwise by the provided scalar. * - * @param {BoundingSphere} sphere The bounding sphere to calculate the distance to. - * @param {Cartesian3} position The position to calculate the distance from. - * @param {Cartesian3} direction The direction from position. - * @param {Interval} [result] A Interval to store the nearest and farthest distances. - * @returns {Interval} The nearest and farthest distances on the bounding sphere from position in direction. + * @param {Cartesian4} cartesian The Cartesian to be divided. + * @param {Number} scalar The scalar to divide by. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.computePlaneDistances = function(sphere, position, direction, result) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('position', position); - Check.typeOf.object('direction', direction); + Cartesian4.divideByScalar = function(cartesian, scalar, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); - if (!defined(result)) { - result = new Interval(); - } - - var toCenter = Cartesian3.subtract(sphere.center, position, scratchCartesian3); - var mag = Cartesian3.dot(direction, toCenter); - - result.start = mag - sphere.radius; - result.stop = mag + sphere.radius; + result.x = cartesian.x / scalar; + result.y = cartesian.y / scalar; + result.z = cartesian.z / scalar; + result.w = cartesian.w / scalar; return result; }; - var projectTo2DNormalScratch = new Cartesian3(); - var projectTo2DEastScratch = new Cartesian3(); - var projectTo2DNorthScratch = new Cartesian3(); - var projectTo2DWestScratch = new Cartesian3(); - var projectTo2DSouthScratch = new Cartesian3(); - var projectTo2DCartographicScratch = new Cartographic(); - var projectTo2DPositionsScratch = new Array(8); - for (var n = 0; n < 8; ++n) { - projectTo2DPositionsScratch[n] = new Cartesian3(); - } - - var projectTo2DProjection = new GeographicProjection(); /** - * Creates a bounding sphere in 2D from a bounding sphere in 3D world coordinates. + * Negates the provided Cartesian. * - * @param {BoundingSphere} sphere The bounding sphere to transform to 2D. - * @param {Object} [projection=GeographicProjection] The projection to 2D. - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} cartesian The Cartesian to be negated. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.projectTo2D = function(sphere, projection, result) { - Check.typeOf.object('sphere', sphere); + Cartesian4.negate = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); - projection = defaultValue(projection, projectTo2DProjection); - - var ellipsoid = projection.ellipsoid; - var center = sphere.center; - var radius = sphere.radius; - - var normal = ellipsoid.geodeticSurfaceNormal(center, projectTo2DNormalScratch); - var east = Cartesian3.cross(Cartesian3.UNIT_Z, normal, projectTo2DEastScratch); - Cartesian3.normalize(east, east); - var north = Cartesian3.cross(normal, east, projectTo2DNorthScratch); - Cartesian3.normalize(north, north); - - Cartesian3.multiplyByScalar(normal, radius, normal); - Cartesian3.multiplyByScalar(north, radius, north); - Cartesian3.multiplyByScalar(east, radius, east); - - var south = Cartesian3.negate(north, projectTo2DSouthScratch); - var west = Cartesian3.negate(east, projectTo2DWestScratch); - - var positions = projectTo2DPositionsScratch; - - // top NE corner - var corner = positions[0]; - Cartesian3.add(normal, north, corner); - Cartesian3.add(corner, east, corner); - - // top NW corner - corner = positions[1]; - Cartesian3.add(normal, north, corner); - Cartesian3.add(corner, west, corner); - - // top SW corner - corner = positions[2]; - Cartesian3.add(normal, south, corner); - Cartesian3.add(corner, west, corner); - - // top SE corner - corner = positions[3]; - Cartesian3.add(normal, south, corner); - Cartesian3.add(corner, east, corner); - - Cartesian3.negate(normal, normal); - - // bottom NE corner - corner = positions[4]; - Cartesian3.add(normal, north, corner); - Cartesian3.add(corner, east, corner); - - // bottom NW corner - corner = positions[5]; - Cartesian3.add(normal, north, corner); - Cartesian3.add(corner, west, corner); - - // bottom SW corner - corner = positions[6]; - Cartesian3.add(normal, south, corner); - Cartesian3.add(corner, west, corner); - - // bottom SE corner - corner = positions[7]; - Cartesian3.add(normal, south, corner); - Cartesian3.add(corner, east, corner); - - var length = positions.length; - for (var i = 0; i < length; ++i) { - var position = positions[i]; - Cartesian3.add(center, position, position); - var cartographic = ellipsoid.cartesianToCartographic(position, projectTo2DCartographicScratch); - projection.project(cartographic, position); - } - - result = BoundingSphere.fromPoints(positions, result); - - // swizzle center components - center = result.center; - var x = center.x; - var y = center.y; - var z = center.z; - center.x = z; - center.y = x; - center.z = y; + result.x = -cartesian.x; + result.y = -cartesian.y; + result.z = -cartesian.z; + result.w = -cartesian.w; + return result; + }; + /** + * Computes the absolute value of the provided Cartesian. + * + * @param {Cartesian4} cartesian The Cartesian whose absolute value is to be computed. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. + */ + Cartesian4.abs = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + result.x = Math.abs(cartesian.x); + result.y = Math.abs(cartesian.y); + result.z = Math.abs(cartesian.z); + result.w = Math.abs(cartesian.w); return result; }; + var lerpScratch = new Cartesian4(); /** - * Determines whether or not a sphere is hidden from view by the occluder. + * Computes the linear interpolation or extrapolation at t using the provided cartesians. * - * @param {BoundingSphere} sphere The bounding sphere surrounding the occludee object. - * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. + * @param {Cartesian4} start The value corresponding to t at 0.0. + * @param {Cartesian4}end The value corresponding to t at 1.0. + * @param {Number} t The point along t at which to interpolate. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. */ - BoundingSphere.isOccluded = function(sphere, occluder) { - Check.typeOf.object('sphere', sphere); - Check.typeOf.object('occluder', occluder); - return !occluder.isBoundingSphereVisible(sphere); + Cartesian4.lerp = function(start, end, t, result) { + Check.typeOf.object('start', start); + Check.typeOf.object('end', end); + Check.typeOf.number('t', t); + Check.typeOf.object('result', result); + + Cartesian4.multiplyByScalar(end, t, lerpScratch); + result = Cartesian4.multiplyByScalar(start, 1.0 - t, result); + return Cartesian4.add(lerpScratch, result, result); }; + var mostOrthogonalAxisScratch = new Cartesian4(); /** - * Compares the provided BoundingSphere componentwise and returns + * Returns the axis that is most orthogonal to the provided Cartesian. + * + * @param {Cartesian4} cartesian The Cartesian on which to find the most orthogonal axis. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The most orthogonal axis. + */ + Cartesian4.mostOrthogonalAxis = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var f = Cartesian4.normalize(cartesian, mostOrthogonalAxisScratch); + Cartesian4.abs(f, f); + + if (f.x <= f.y) { + if (f.x <= f.z) { + if (f.x <= f.w) { + result = Cartesian4.clone(Cartesian4.UNIT_X, result); + } else { + result = Cartesian4.clone(Cartesian4.UNIT_W, result); + } + } else if (f.z <= f.w) { + result = Cartesian4.clone(Cartesian4.UNIT_Z, result); + } else { + result = Cartesian4.clone(Cartesian4.UNIT_W, result); + } + } else if (f.y <= f.z) { + if (f.y <= f.w) { + result = Cartesian4.clone(Cartesian4.UNIT_Y, result); + } else { + result = Cartesian4.clone(Cartesian4.UNIT_W, result); + } + } else if (f.z <= f.w) { + result = Cartesian4.clone(Cartesian4.UNIT_Z, result); + } else { + result = Cartesian4.clone(Cartesian4.UNIT_W, result); + } + + return result; + }; + + /** + * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {BoundingSphere} [left] The first BoundingSphere. - * @param {BoundingSphere} [right] The second BoundingSphere. + * @param {Cartesian4} [left] The first Cartesian. + * @param {Cartesian4} [right] The second Cartesian. * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - BoundingSphere.equals = function(left, right) { + Cartesian4.equals = function(left, right) { return (left === right) || ((defined(left)) && (defined(right)) && - Cartesian3.equals(left.center, right.center) && - left.radius === right.radius); + (left.x === right.x) && + (left.y === right.y) && + (left.z === right.z) && + (left.w === right.w)); }; /** - * Determines which side of a plane the sphere is located. + * @private + */ + Cartesian4.equalsArray = function(cartesian, array, offset) { + return cartesian.x === array[offset] && + cartesian.y === array[offset + 1] && + cartesian.z === array[offset + 2] && + cartesian.w === array[offset + 3]; + }; + + /** + * Compares the provided Cartesians componentwise and returns + * <code>true</code> if they pass an absolute or relative tolerance test, + * <code>false</code> otherwise. * - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is - * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere - * intersects the plane. + * @param {Cartesian4} [left] The first Cartesian. + * @param {Cartesian4} [right] The second Cartesian. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ - BoundingSphere.prototype.intersectPlane = function(plane) { - return BoundingSphere.intersectPlane(this, plane); + Cartesian4.equalsEpsilon = function(left, right, relativeEpsilon, absoluteEpsilon) { + return (left === right) || + (defined(left) && + defined(right) && + CesiumMath.equalsEpsilon(left.x, right.x, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(left.y, right.y, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(left.z, right.z, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(left.w, right.w, relativeEpsilon, absoluteEpsilon)); }; /** - * Computes the estimated distance squared from the closest point on a bounding sphere to a point. + * An immutable Cartesian4 instance initialized to (0.0, 0.0, 0.0, 0.0). * - * @param {Cartesian3} cartesian The point - * @returns {Number} The estimated distance squared from the bounding sphere to the point. + * @type {Cartesian4} + * @constant + */ + Cartesian4.ZERO = freezeObject(new Cartesian4(0.0, 0.0, 0.0, 0.0)); + + /** + * An immutable Cartesian4 instance initialized to (1.0, 0.0, 0.0, 0.0). * - * @example - * // Sort bounding spheres from back to front - * spheres.sort(function(a, b) { - * return b.distanceSquaredTo(camera.positionWC) - a.distanceSquaredTo(camera.positionWC); - * }); + * @type {Cartesian4} + * @constant */ - BoundingSphere.prototype.distanceSquaredTo = function(cartesian) { - return BoundingSphere.distanceSquaredTo(this, cartesian); - }; + Cartesian4.UNIT_X = freezeObject(new Cartesian4(1.0, 0.0, 0.0, 0.0)); /** - * The distances calculated by the vector from the center of the bounding sphere to position projected onto direction - * plus/minus the radius of the bounding sphere. - * <br> - * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the - * closest and farthest planes from position that intersect the bounding sphere. + * An immutable Cartesian4 instance initialized to (0.0, 1.0, 0.0, 0.0). * - * @param {Cartesian3} position The position to calculate the distance from. - * @param {Cartesian3} direction The direction from position. - * @param {Interval} [result] A Interval to store the nearest and farthest distances. - * @returns {Interval} The nearest and farthest distances on the bounding sphere from position in direction. + * @type {Cartesian4} + * @constant */ - BoundingSphere.prototype.computePlaneDistances = function(position, direction, result) { - return BoundingSphere.computePlaneDistances(this, position, direction, result); - }; + Cartesian4.UNIT_Y = freezeObject(new Cartesian4(0.0, 1.0, 0.0, 0.0)); /** - * Determines whether or not a sphere is hidden from view by the occluder. + * An immutable Cartesian4 instance initialized to (0.0, 0.0, 1.0, 0.0). * - * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. + * @type {Cartesian4} + * @constant */ - BoundingSphere.prototype.isOccluded = function(occluder) { - return BoundingSphere.isOccluded(this, occluder); + Cartesian4.UNIT_Z = freezeObject(new Cartesian4(0.0, 0.0, 1.0, 0.0)); + + /** + * An immutable Cartesian4 instance initialized to (0.0, 0.0, 0.0, 1.0). + * + * @type {Cartesian4} + * @constant + */ + Cartesian4.UNIT_W = freezeObject(new Cartesian4(0.0, 0.0, 0.0, 1.0)); + + /** + * Duplicates this Cartesian4 instance. + * + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. + */ + Cartesian4.prototype.clone = function(result) { + return Cartesian4.clone(this, result); }; /** - * Compares this BoundingSphere against the provided BoundingSphere componentwise and returns + * Compares this Cartesian against the provided Cartesian componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {BoundingSphere} [right] The right hand side BoundingSphere. + * @param {Cartesian4} [right] The right hand side Cartesian. * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ - BoundingSphere.prototype.equals = function(right) { - return BoundingSphere.equals(this, right); + Cartesian4.prototype.equals = function(right) { + return Cartesian4.equals(this, right); }; /** - * Duplicates this BoundingSphere instance. + * Compares this Cartesian against the provided Cartesian componentwise and returns + * <code>true</code> if they pass an absolute or relative tolerance test, + * <code>false</code> otherwise. * - * @param {BoundingSphere} [result] The object onto which to store the result. - * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * @param {Cartesian4} [right] The right hand side Cartesian. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ - BoundingSphere.prototype.clone = function(result) { - return BoundingSphere.clone(this, result); + Cartesian4.prototype.equalsEpsilon = function(right, relativeEpsilon, absoluteEpsilon) { + return Cartesian4.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); }; - return BoundingSphere; + /** + * Creates a string representing this Cartesian in the format '(x, y)'. + * + * @returns {String} A string representing the provided Cartesian in the format '(x, y)'. + */ + Cartesian4.prototype.toString = function() { + return '(' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ')'; + }; + + return Cartesian4; }); -define('Core/Fullscreen',[ +define('Core/Matrix4',[ + './Cartesian3', + './Cartesian4', + './Check', + './defaultValue', './defined', - './defineProperties' + './defineProperties', + './freezeObject', + './Math', + './Matrix3', + './RuntimeError' ], function( + Cartesian3, + Cartesian4, + Check, + defaultValue, defined, - defineProperties) { + defineProperties, + freezeObject, + CesiumMath, + Matrix3, + RuntimeError) { 'use strict'; - var _supportsFullscreen; - var _names = { - requestFullscreen : undefined, - exitFullscreen : undefined, - fullscreenEnabled : undefined, - fullscreenElement : undefined, - fullscreenchange : undefined, - fullscreenerror : undefined - }; - /** - * Browser-independent functions for working with the standard fullscreen API. + * A 4x4 matrix, indexable as a column-major order array. + * Constructor parameters are in row-major order for code readability. + * @alias Matrix4 + * @constructor * - * @exports Fullscreen + * @param {Number} [column0Row0=0.0] The value for column 0, row 0. + * @param {Number} [column1Row0=0.0] The value for column 1, row 0. + * @param {Number} [column2Row0=0.0] The value for column 2, row 0. + * @param {Number} [column3Row0=0.0] The value for column 3, row 0. + * @param {Number} [column0Row1=0.0] The value for column 0, row 1. + * @param {Number} [column1Row1=0.0] The value for column 1, row 1. + * @param {Number} [column2Row1=0.0] The value for column 2, row 1. + * @param {Number} [column3Row1=0.0] The value for column 3, row 1. + * @param {Number} [column0Row2=0.0] The value for column 0, row 2. + * @param {Number} [column1Row2=0.0] The value for column 1, row 2. + * @param {Number} [column2Row2=0.0] The value for column 2, row 2. + * @param {Number} [column3Row2=0.0] The value for column 3, row 2. + * @param {Number} [column0Row3=0.0] The value for column 0, row 3. + * @param {Number} [column1Row3=0.0] The value for column 1, row 3. + * @param {Number} [column2Row3=0.0] The value for column 2, row 3. + * @param {Number} [column3Row3=0.0] The value for column 3, row 3. * - * @see {@link http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html|W3C Fullscreen Living Specification} + * @see Matrix4.fromColumnMajorArray + * @see Matrix4.fromRowMajorArray + * @see Matrix4.fromRotationTranslation + * @see Matrix4.fromTranslationRotationScale + * @see Matrix4.fromTranslationQuaternionRotationScale + * @see Matrix4.fromTranslation + * @see Matrix4.fromScale + * @see Matrix4.fromUniformScale + * @see Matrix4.fromCamera + * @see Matrix4.computePerspectiveFieldOfView + * @see Matrix4.computeOrthographicOffCenter + * @see Matrix4.computePerspectiveOffCenter + * @see Matrix4.computeInfinitePerspectiveOffCenter + * @see Matrix4.computeViewportTransformation + * @see Matrix4.computeView + * @see Matrix2 + * @see Matrix3 + * @see Packable */ - var Fullscreen = {}; - - defineProperties(Fullscreen, { - /** - * The element that is currently fullscreen, if any. To simply check if the - * browser is in fullscreen mode or not, use {@link Fullscreen#fullscreen}. - * @memberof Fullscreen - * @type {Object} - * @readonly - */ - element : { - get : function() { - if (!Fullscreen.supportsFullscreen()) { - return undefined; - } - - return document[_names.fullscreenElement]; - } - }, - - /** - * The name of the event on the document that is fired when fullscreen is - * entered or exited. This event name is intended for use with addEventListener. - * In your event handler, to determine if the browser is in fullscreen mode or not, - * use {@link Fullscreen#fullscreen}. - * @memberof Fullscreen - * @type {String} - * @readonly - */ - changeEventName : { - get : function() { - if (!Fullscreen.supportsFullscreen()) { - return undefined; - } - - return _names.fullscreenchange; - } - }, - - /** - * The name of the event that is fired when a fullscreen error - * occurs. This event name is intended for use with addEventListener. - * @memberof Fullscreen - * @type {String} - * @readonly - */ - errorEventName : { - get : function() { - if (!Fullscreen.supportsFullscreen()) { - return undefined; - } - - return _names.fullscreenerror; - } - }, - - /** - * Determine whether the browser will allow an element to be made fullscreen, or not. - * For example, by default, iframes cannot go fullscreen unless the containing page - * adds an "allowfullscreen" attribute (or prefixed equivalent). - * @memberof Fullscreen - * @type {Boolean} - * @readonly - */ - enabled : { - get : function() { - if (!Fullscreen.supportsFullscreen()) { - return undefined; - } - - return document[_names.fullscreenEnabled]; - } - }, - - /** - * Determines if the browser is currently in fullscreen mode. - * @memberof Fullscreen - * @type {Boolean} - * @readonly - */ - fullscreen : { - get : function() { - if (!Fullscreen.supportsFullscreen()) { - return undefined; - } + function Matrix4(column0Row0, column1Row0, column2Row0, column3Row0, + column0Row1, column1Row1, column2Row1, column3Row1, + column0Row2, column1Row2, column2Row2, column3Row2, + column0Row3, column1Row3, column2Row3, column3Row3) { + this[0] = defaultValue(column0Row0, 0.0); + this[1] = defaultValue(column0Row1, 0.0); + this[2] = defaultValue(column0Row2, 0.0); + this[3] = defaultValue(column0Row3, 0.0); + this[4] = defaultValue(column1Row0, 0.0); + this[5] = defaultValue(column1Row1, 0.0); + this[6] = defaultValue(column1Row2, 0.0); + this[7] = defaultValue(column1Row3, 0.0); + this[8] = defaultValue(column2Row0, 0.0); + this[9] = defaultValue(column2Row1, 0.0); + this[10] = defaultValue(column2Row2, 0.0); + this[11] = defaultValue(column2Row3, 0.0); + this[12] = defaultValue(column3Row0, 0.0); + this[13] = defaultValue(column3Row1, 0.0); + this[14] = defaultValue(column3Row2, 0.0); + this[15] = defaultValue(column3Row3, 0.0); + } - return Fullscreen.element !== null; - } - } - }); + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + Matrix4.packedLength = 16; /** - * Detects whether the browser supports the standard fullscreen API. + * Stores the provided instance into the provided array. * - * @returns {Boolean} <code>true</code> if the browser supports the standard fullscreen API, - * <code>false</code> otherwise. + * @param {Matrix4} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - Fullscreen.supportsFullscreen = function() { - if (defined(_supportsFullscreen)) { - return _supportsFullscreen; - } - - _supportsFullscreen = false; - - var body = document.body; - if (typeof body.requestFullscreen === 'function') { - // go with the unprefixed, standard set of names - _names.requestFullscreen = 'requestFullscreen'; - _names.exitFullscreen = 'exitFullscreen'; - _names.fullscreenEnabled = 'fullscreenEnabled'; - _names.fullscreenElement = 'fullscreenElement'; - _names.fullscreenchange = 'fullscreenchange'; - _names.fullscreenerror = 'fullscreenerror'; - _supportsFullscreen = true; - return _supportsFullscreen; - } - - //check for the correct combination of prefix plus the various names that browsers use - var prefixes = ['webkit', 'moz', 'o', 'ms', 'khtml']; - var name; - for (var i = 0, len = prefixes.length; i < len; ++i) { - var prefix = prefixes[i]; - - // casing of Fullscreen differs across browsers - name = prefix + 'RequestFullscreen'; - if (typeof body[name] === 'function') { - _names.requestFullscreen = name; - _supportsFullscreen = true; - } else { - name = prefix + 'RequestFullScreen'; - if (typeof body[name] === 'function') { - _names.requestFullscreen = name; - _supportsFullscreen = true; - } - } - - // disagreement about whether it's "exit" as per spec, or "cancel" - name = prefix + 'ExitFullscreen'; - if (typeof document[name] === 'function') { - _names.exitFullscreen = name; - } else { - name = prefix + 'CancelFullScreen'; - if (typeof document[name] === 'function') { - _names.exitFullscreen = name; - } - } - - // casing of Fullscreen differs across browsers - name = prefix + 'FullscreenEnabled'; - if (document[name] !== undefined) { - _names.fullscreenEnabled = name; - } else { - name = prefix + 'FullScreenEnabled'; - if (document[name] !== undefined) { - _names.fullscreenEnabled = name; - } - } - - // casing of Fullscreen differs across browsers - name = prefix + 'FullscreenElement'; - if (document[name] !== undefined) { - _names.fullscreenElement = name; - } else { - name = prefix + 'FullScreenElement'; - if (document[name] !== undefined) { - _names.fullscreenElement = name; - } - } - - // thankfully, event names are all lowercase per spec - name = prefix + 'fullscreenchange'; - // event names do not have 'on' in the front, but the property on the document does - if (document['on' + name] !== undefined) { - //except on IE - if (prefix === 'ms') { - name = 'MSFullscreenChange'; - } - _names.fullscreenchange = name; - } + Matrix4.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - name = prefix + 'fullscreenerror'; - if (document['on' + name] !== undefined) { - //except on IE - if (prefix === 'ms') { - name = 'MSFullscreenError'; - } - _names.fullscreenerror = name; - } - } + array[startingIndex++] = value[0]; + array[startingIndex++] = value[1]; + array[startingIndex++] = value[2]; + array[startingIndex++] = value[3]; + array[startingIndex++] = value[4]; + array[startingIndex++] = value[5]; + array[startingIndex++] = value[6]; + array[startingIndex++] = value[7]; + array[startingIndex++] = value[8]; + array[startingIndex++] = value[9]; + array[startingIndex++] = value[10]; + array[startingIndex++] = value[11]; + array[startingIndex++] = value[12]; + array[startingIndex++] = value[13]; + array[startingIndex++] = value[14]; + array[startingIndex] = value[15]; - return _supportsFullscreen; + return array; }; /** - * Asynchronously requests the browser to enter fullscreen mode on the given element. - * If fullscreen mode is not supported by the browser, does nothing. - * - * @param {Object} element The HTML element which will be placed into fullscreen mode. - * @param {HMDVRDevice} [vrDevice] The VR device. - * - * @example - * // Put the entire page into fullscreen. - * Cesium.Fullscreen.requestFullscreen(document.body) + * Retrieves an instance from a packed array. * - * // Place only the Cesium canvas into fullscreen. - * Cesium.Fullscreen.requestFullscreen(scene.canvas) + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Matrix4} [result] The object into which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. */ - Fullscreen.requestFullscreen = function(element, vrDevice) { - if (!Fullscreen.supportsFullscreen()) { - return; + Matrix4.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new Matrix4(); } - element[_names.requestFullscreen]({ vrDisplay: vrDevice }); + result[0] = array[startingIndex++]; + result[1] = array[startingIndex++]; + result[2] = array[startingIndex++]; + result[3] = array[startingIndex++]; + result[4] = array[startingIndex++]; + result[5] = array[startingIndex++]; + result[6] = array[startingIndex++]; + result[7] = array[startingIndex++]; + result[8] = array[startingIndex++]; + result[9] = array[startingIndex++]; + result[10] = array[startingIndex++]; + result[11] = array[startingIndex++]; + result[12] = array[startingIndex++]; + result[13] = array[startingIndex++]; + result[14] = array[startingIndex++]; + result[15] = array[startingIndex]; + return result; }; /** - * Asynchronously exits fullscreen mode. If the browser is not currently - * in fullscreen, or if fullscreen mode is not supported by the browser, does nothing. + * Duplicates a Matrix4 instance. + * + * @param {Matrix4} matrix The matrix to duplicate. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. (Returns undefined if matrix is undefined) */ - Fullscreen.exitFullscreen = function() { - if (!Fullscreen.supportsFullscreen()) { - return; + Matrix4.clone = function(matrix, result) { + if (!defined(matrix)) { + return undefined; } - - document[_names.exitFullscreen](); + if (!defined(result)) { + return new Matrix4(matrix[0], matrix[4], matrix[8], matrix[12], + matrix[1], matrix[5], matrix[9], matrix[13], + matrix[2], matrix[6], matrix[10], matrix[14], + matrix[3], matrix[7], matrix[11], matrix[15]); + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; }; - return Fullscreen; -}); - -define('Core/FeatureDetection',[ - './defaultValue', - './defined', - './Fullscreen' - ], function( - defaultValue, - defined, - Fullscreen) { - 'use strict'; + /** + * Creates a Matrix4 from 16 consecutive elements in an array. + * @function + * + * @param {Number[]} array The array whose 16 consecutive elements correspond to the positions of the matrix. Assumes column-major order. + * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. + * + * @example + * // Create the Matrix4: + * // [1.0, 2.0, 3.0, 4.0] + * // [1.0, 2.0, 3.0, 4.0] + * // [1.0, 2.0, 3.0, 4.0] + * // [1.0, 2.0, 3.0, 4.0] + * + * var v = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0]; + * var m = Cesium.Matrix4.fromArray(v); + * + * // Create same Matrix4 with using an offset into an array + * var v2 = [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0]; + * var m2 = Cesium.Matrix4.fromArray(v2, 2); + */ + Matrix4.fromArray = Matrix4.unpack; - var theNavigator; - if (typeof navigator !== 'undefined') { - theNavigator = navigator; - } else { - theNavigator = {}; - } + /** + * Computes a Matrix4 instance from a column-major order array. + * + * @param {Number[]} values The column-major order array. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + */ + Matrix4.fromColumnMajorArray = function(values, result) { + Check.defined('values', values); + + return Matrix4.clone(values, result); + }; - function extractVersion(versionString) { - var parts = versionString.split('.'); - for (var i = 0, len = parts.length; i < len; ++i) { - parts[i] = parseInt(parts[i], 10); + /** + * Computes a Matrix4 instance from a row-major order array. + * The resulting matrix will be in column-major order. + * + * @param {Number[]} values The row-major order array. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + */ + Matrix4.fromRowMajorArray = function(values, result) { + Check.defined('values', values); + + if (!defined(result)) { + return new Matrix4(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15]); } - return parts; - } + result[0] = values[0]; + result[1] = values[4]; + result[2] = values[8]; + result[3] = values[12]; + result[4] = values[1]; + result[5] = values[5]; + result[6] = values[9]; + result[7] = values[13]; + result[8] = values[2]; + result[9] = values[6]; + result[10] = values[10]; + result[11] = values[14]; + result[12] = values[3]; + result[13] = values[7]; + result[14] = values[11]; + result[15] = values[15]; + return result; + }; - var isChromeResult; - var chromeVersionResult; - function isChrome() { - if (!defined(isChromeResult)) { - isChromeResult = false; - // Edge contains Chrome in the user agent too - if (!isEdge()) { - var fields = (/ Chrome\/([\.0-9]+)/).exec(theNavigator.userAgent); - if (fields !== null) { - isChromeResult = true; - chromeVersionResult = extractVersion(fields[1]); - } - } + /** + * Computes a Matrix4 instance from a Matrix3 representing the rotation + * and a Cartesian3 representing the translation. + * + * @param {Matrix3} rotation The upper left portion of the matrix representing the rotation. + * @param {Cartesian3} [translation=Cartesian3.ZERO] The upper right portion of the matrix representing the translation. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + */ + Matrix4.fromRotationTranslation = function(rotation, translation, result) { + Check.typeOf.object('rotation', rotation); + + translation = defaultValue(translation, Cartesian3.ZERO); + + if (!defined(result)) { + return new Matrix4(rotation[0], rotation[3], rotation[6], translation.x, + rotation[1], rotation[4], rotation[7], translation.y, + rotation[2], rotation[5], rotation[8], translation.z, + 0.0, 0.0, 0.0, 1.0); } - return isChromeResult; - } + result[0] = rotation[0]; + result[1] = rotation[1]; + result[2] = rotation[2]; + result[3] = 0.0; + result[4] = rotation[3]; + result[5] = rotation[4]; + result[6] = rotation[5]; + result[7] = 0.0; + result[8] = rotation[6]; + result[9] = rotation[7]; + result[10] = rotation[8]; + result[11] = 0.0; + result[12] = translation.x; + result[13] = translation.y; + result[14] = translation.z; + result[15] = 1.0; + return result; + }; - function chromeVersion() { - return isChrome() && chromeVersionResult; - } + /** + * Computes a Matrix4 instance from a translation, rotation, and scale (TRS) + * representation with the rotation represented as a quaternion. + * + * @param {Cartesian3} translation The translation transformation. + * @param {Quaternion} rotation The rotation transformation. + * @param {Cartesian3} scale The non-uniform scale transformation. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * + * @example + * var result = Cesium.Matrix4.fromTranslationQuaternionRotationScale( + * new Cesium.Cartesian3(1.0, 2.0, 3.0), // translation + * Cesium.Quaternion.IDENTITY, // rotation + * new Cesium.Cartesian3(7.0, 8.0, 9.0), // scale + * result); + */ + Matrix4.fromTranslationQuaternionRotationScale = function(translation, rotation, scale, result) { + Check.typeOf.object('translation', translation); + Check.typeOf.object('rotation', rotation); + Check.typeOf.object('scale', scale); + + if (!defined(result)) { + result = new Matrix4(); + } - var isSafariResult; - var safariVersionResult; - function isSafari() { - if (!defined(isSafariResult)) { - isSafariResult = false; + var scaleX = scale.x; + var scaleY = scale.y; + var scaleZ = scale.z; - // Chrome and Edge contain Safari in the user agent too - if (!isChrome() && !isEdge() && (/ Safari\/[\.0-9]+/).test(theNavigator.userAgent)) { - var fields = (/ Version\/([\.0-9]+)/).exec(theNavigator.userAgent); - if (fields !== null) { - isSafariResult = true; - safariVersionResult = extractVersion(fields[1]); - } - } - } + var x2 = rotation.x * rotation.x; + var xy = rotation.x * rotation.y; + var xz = rotation.x * rotation.z; + var xw = rotation.x * rotation.w; + var y2 = rotation.y * rotation.y; + var yz = rotation.y * rotation.z; + var yw = rotation.y * rotation.w; + var z2 = rotation.z * rotation.z; + var zw = rotation.z * rotation.w; + var w2 = rotation.w * rotation.w; - return isSafariResult; - } + var m00 = x2 - y2 - z2 + w2; + var m01 = 2.0 * (xy - zw); + var m02 = 2.0 * (xz + yw); - function safariVersion() { - return isSafari() && safariVersionResult; - } + var m10 = 2.0 * (xy + zw); + var m11 = -x2 + y2 - z2 + w2; + var m12 = 2.0 * (yz - xw); - var isWebkitResult; - var webkitVersionResult; - function isWebkit() { - if (!defined(isWebkitResult)) { - isWebkitResult = false; + var m20 = 2.0 * (xz - yw); + var m21 = 2.0 * (yz + xw); + var m22 = -x2 - y2 + z2 + w2; - var fields = (/ AppleWebKit\/([\.0-9]+)(\+?)/).exec(theNavigator.userAgent); - if (fields !== null) { - isWebkitResult = true; - webkitVersionResult = extractVersion(fields[1]); - webkitVersionResult.isNightly = !!fields[2]; - } - } + result[0] = m00 * scaleX; + result[1] = m10 * scaleX; + result[2] = m20 * scaleX; + result[3] = 0.0; + result[4] = m01 * scaleY; + result[5] = m11 * scaleY; + result[6] = m21 * scaleY; + result[7] = 0.0; + result[8] = m02 * scaleZ; + result[9] = m12 * scaleZ; + result[10] = m22 * scaleZ; + result[11] = 0.0; + result[12] = translation.x; + result[13] = translation.y; + result[14] = translation.z; + result[15] = 1.0; - return isWebkitResult; - } + return result; + }; - function webkitVersion() { - return isWebkit() && webkitVersionResult; - } + /** + * Creates a Matrix4 instance from a {@link TranslationRotationScale} instance. + * + * @param {TranslationRotationScale} translationRotationScale The instance. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + */ + Matrix4.fromTranslationRotationScale = function(translationRotationScale, result) { + Check.typeOf.object('translationRotationScale', translationRotationScale); + + return Matrix4.fromTranslationQuaternionRotationScale(translationRotationScale.translation, translationRotationScale.rotation, translationRotationScale.scale, result); + }; - var isInternetExplorerResult; - var internetExplorerVersionResult; - function isInternetExplorer() { - if (!defined(isInternetExplorerResult)) { - isInternetExplorerResult = false; + /** + * Creates a Matrix4 instance from a Cartesian3 representing the translation. + * + * @param {Cartesian3} translation The upper right portion of the matrix representing the translation. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * + * @see Matrix4.multiplyByTranslation + */ + Matrix4.fromTranslation = function(translation, result) { + Check.typeOf.object('translation', translation); + + return Matrix4.fromRotationTranslation(Matrix3.IDENTITY, translation, result); + }; - var fields; - if (theNavigator.appName === 'Microsoft Internet Explorer') { - fields = /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(theNavigator.userAgent); - if (fields !== null) { - isInternetExplorerResult = true; - internetExplorerVersionResult = extractVersion(fields[1]); - } - } else if (theNavigator.appName === 'Netscape') { - fields = /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(theNavigator.userAgent); - if (fields !== null) { - isInternetExplorerResult = true; - internetExplorerVersionResult = extractVersion(fields[1]); - } - } + /** + * Computes a Matrix4 instance representing a non-uniform scale. + * + * @param {Cartesian3} scale The x, y, and z scale factors. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * + * @example + * // Creates + * // [7.0, 0.0, 0.0, 0.0] + * // [0.0, 8.0, 0.0, 0.0] + * // [0.0, 0.0, 9.0, 0.0] + * // [0.0, 0.0, 0.0, 1.0] + * var m = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(7.0, 8.0, 9.0)); + */ + Matrix4.fromScale = function(scale, result) { + Check.typeOf.object('scale', scale); + + if (!defined(result)) { + return new Matrix4( + scale.x, 0.0, 0.0, 0.0, + 0.0, scale.y, 0.0, 0.0, + 0.0, 0.0, scale.z, 0.0, + 0.0, 0.0, 0.0, 1.0); } - return isInternetExplorerResult; - } - function internetExplorerVersion() { - return isInternetExplorer() && internetExplorerVersionResult; - } + result[0] = scale.x; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = scale.y; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = scale.z; + result[11] = 0.0; + result[12] = 0.0; + result[13] = 0.0; + result[14] = 0.0; + result[15] = 1.0; + return result; + }; - var isEdgeResult; - var edgeVersionResult; - function isEdge() { - if (!defined(isEdgeResult)) { - isEdgeResult = false; - var fields = (/ Edge\/([\.0-9]+)/).exec(theNavigator.userAgent); - if (fields !== null) { - isEdgeResult = true; - edgeVersionResult = extractVersion(fields[1]); - } + /** + * Computes a Matrix4 instance representing a uniform scale. + * + * @param {Number} scale The uniform scale factor. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + * + * @example + * // Creates + * // [2.0, 0.0, 0.0, 0.0] + * // [0.0, 2.0, 0.0, 0.0] + * // [0.0, 0.0, 2.0, 0.0] + * // [0.0, 0.0, 0.0, 1.0] + * var m = Cesium.Matrix4.fromUniformScale(2.0); + */ + Matrix4.fromUniformScale = function(scale, result) { + Check.typeOf.number('scale', scale); + + if (!defined(result)) { + return new Matrix4(scale, 0.0, 0.0, 0.0, + 0.0, scale, 0.0, 0.0, + 0.0, 0.0, scale, 0.0, + 0.0, 0.0, 0.0, 1.0); } - return isEdgeResult; - } - function edgeVersion() { - return isEdge() && edgeVersionResult; - } + result[0] = scale; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = scale; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = scale; + result[11] = 0.0; + result[12] = 0.0; + result[13] = 0.0; + result[14] = 0.0; + result[15] = 1.0; + return result; + }; - var isFirefoxResult; - var firefoxVersionResult; - function isFirefox() { - if (!defined(isFirefoxResult)) { - isFirefoxResult = false; + var fromCameraF = new Cartesian3(); + var fromCameraR = new Cartesian3(); + var fromCameraU = new Cartesian3(); - var fields = /Firefox\/([\.0-9]+)/.exec(theNavigator.userAgent); - if (fields !== null) { - isFirefoxResult = true; - firefoxVersionResult = extractVersion(fields[1]); - } - } - return isFirefoxResult; - } + /** + * Computes a Matrix4 instance from a Camera. + * + * @param {Camera} camera The camera to use. + * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. + */ + Matrix4.fromCamera = function(camera, result) { + Check.typeOf.object('camera', camera); + + var position = camera.position; + var direction = camera.direction; + var up = camera.up; - var isWindowsResult; - function isWindows() { - if (!defined(isWindowsResult)) { - isWindowsResult = /Windows/i.test(theNavigator.appVersion); + Check.typeOf.object('camera.position', position); + Check.typeOf.object('camera.direction', direction); + Check.typeOf.object('camera.up', up); + + Cartesian3.normalize(direction, fromCameraF); + Cartesian3.normalize(Cartesian3.cross(fromCameraF, up, fromCameraR), fromCameraR); + Cartesian3.normalize(Cartesian3.cross(fromCameraR, fromCameraF, fromCameraU), fromCameraU); + + var sX = fromCameraR.x; + var sY = fromCameraR.y; + var sZ = fromCameraR.z; + var fX = fromCameraF.x; + var fY = fromCameraF.y; + var fZ = fromCameraF.z; + var uX = fromCameraU.x; + var uY = fromCameraU.y; + var uZ = fromCameraU.z; + var positionX = position.x; + var positionY = position.y; + var positionZ = position.z; + var t0 = sX * -positionX + sY * -positionY+ sZ * -positionZ; + var t1 = uX * -positionX + uY * -positionY+ uZ * -positionZ; + var t2 = fX * positionX + fY * positionY + fZ * positionZ; + + // The code below this comment is an optimized + // version of the commented lines. + // Rather that create two matrices and then multiply, + // we just bake in the multiplcation as part of creation. + // var rotation = new Matrix4( + // sX, sY, sZ, 0.0, + // uX, uY, uZ, 0.0, + // -fX, -fY, -fZ, 0.0, + // 0.0, 0.0, 0.0, 1.0); + // var translation = new Matrix4( + // 1.0, 0.0, 0.0, -position.x, + // 0.0, 1.0, 0.0, -position.y, + // 0.0, 0.0, 1.0, -position.z, + // 0.0, 0.0, 0.0, 1.0); + // return rotation.multiply(translation); + if (!defined(result)) { + return new Matrix4( + sX, sY, sZ, t0, + uX, uY, uZ, t1, + -fX, -fY, -fZ, t2, + 0.0, 0.0, 0.0, 1.0); } - return isWindowsResult; - } + result[0] = sX; + result[1] = uX; + result[2] = -fX; + result[3] = 0.0; + result[4] = sY; + result[5] = uY; + result[6] = -fY; + result[7] = 0.0; + result[8] = sZ; + result[9] = uZ; + result[10] = -fZ; + result[11] = 0.0; + result[12] = t0; + result[13] = t1; + result[14] = t2; + result[15] = 1.0; + return result; + }; + /** + * Computes a Matrix4 instance representing a perspective transformation matrix. + * + * @param {Number} fovY The field of view along the Y axis in radians. + * @param {Number} aspectRatio The aspect ratio. + * @param {Number} near The distance to the near plane in meters. + * @param {Number} far The distance to the far plane in meters. + * @param {Matrix4} result The object in which the result will be stored. + * @returns {Matrix4} The modified result parameter. + * + * @exception {DeveloperError} fovY must be in (0, PI]. + * @exception {DeveloperError} aspectRatio must be greater than zero. + * @exception {DeveloperError} near must be greater than zero. + * @exception {DeveloperError} far must be greater than zero. + */ + Matrix4.computePerspectiveFieldOfView = function(fovY, aspectRatio, near, far, result) { + Check.typeOf.number.greaterThan('fovY', fovY, 0.0); + Check.typeOf.number.lessThan('fovY', fovY, Math.PI); + Check.typeOf.number.greaterThan('near', near, 0.0); + Check.typeOf.number.greaterThan('far', far, 0.0); + Check.typeOf.object('result', result); + + var bottom = Math.tan(fovY * 0.5); - function firefoxVersion() { - return isFirefox() && firefoxVersionResult; - } + var column1Row1 = 1.0 / bottom; + var column0Row0 = column1Row1 / aspectRatio; + var column2Row2 = (far + near) / (near - far); + var column3Row2 = (2.0 * far * near) / (near - far); - var hasPointerEvents; - function supportsPointerEvents() { - if (!defined(hasPointerEvents)) { - //While navigator.pointerEnabled is deprecated in the W3C specification - //we still need to use it if it exists in order to support browsers - //that rely on it, such as the Windows WebBrowser control which defines - //PointerEvent but sets navigator.pointerEnabled to false. - hasPointerEvents = typeof PointerEvent !== 'undefined' && (!defined(theNavigator.pointerEnabled) || theNavigator.pointerEnabled); - } - return hasPointerEvents; - } + result[0] = column0Row0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = column1Row1; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = column2Row2; + result[11] = -1.0; + result[12] = 0.0; + result[13] = 0.0; + result[14] = column3Row2; + result[15] = 0.0; + return result; + }; - var imageRenderingValueResult; - var supportsImageRenderingPixelatedResult; - function supportsImageRenderingPixelated() { - if (!defined(supportsImageRenderingPixelatedResult)) { - var canvas = document.createElement('canvas'); - canvas.setAttribute('style', - 'image-rendering: -moz-crisp-edges;' + - 'image-rendering: pixelated;'); - //canvas.style.imageRendering will be undefined, null or an empty string on unsupported browsers. - var tmp = canvas.style.imageRendering; - supportsImageRenderingPixelatedResult = defined(tmp) && tmp !== ''; - if (supportsImageRenderingPixelatedResult) { - imageRenderingValueResult = tmp; - } - } - return supportsImageRenderingPixelatedResult; - } + /** + * Computes a Matrix4 instance representing an orthographic transformation matrix. + * + * @param {Number} left The number of meters to the left of the camera that will be in view. + * @param {Number} right The number of meters to the right of the camera that will be in view. + * @param {Number} bottom The number of meters below of the camera that will be in view. + * @param {Number} top The number of meters above of the camera that will be in view. + * @param {Number} near The distance to the near plane in meters. + * @param {Number} far The distance to the far plane in meters. + * @param {Matrix4} result The object in which the result will be stored. + * @returns {Matrix4} The modified result parameter. + */ + Matrix4.computeOrthographicOffCenter = function(left, right, bottom, top, near, far, result) { + Check.typeOf.number('left', left); + Check.typeOf.number('right', right); + Check.typeOf.number('bottom', bottom); + Check.typeOf.number('top', top); + Check.typeOf.number('near', near); + Check.typeOf.number('far', far); + Check.typeOf.object('result', result); + + var a = 1.0 / (right - left); + var b = 1.0 / (top - bottom); + var c = 1.0 / (far - near); - function imageRenderingValue() { - return supportsImageRenderingPixelated() ? imageRenderingValueResult : undefined; - } + var tx = -(right + left) * a; + var ty = -(top + bottom) * b; + var tz = -(far + near) * c; + a *= 2.0; + b *= 2.0; + c *= -2.0; + + result[0] = a; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = b; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = c; + result[11] = 0.0; + result[12] = tx; + result[13] = ty; + result[14] = tz; + result[15] = 1.0; + return result; + }; /** - * A set of functions to detect whether the current browser supports - * various features. + * Computes a Matrix4 instance representing an off center perspective transformation. * - * @exports FeatureDetection + * @param {Number} left The number of meters to the left of the camera that will be in view. + * @param {Number} right The number of meters to the right of the camera that will be in view. + * @param {Number} bottom The number of meters below of the camera that will be in view. + * @param {Number} top The number of meters above of the camera that will be in view. + * @param {Number} near The distance to the near plane in meters. + * @param {Number} far The distance to the far plane in meters. + * @param {Matrix4} result The object in which the result will be stored. + * @returns {Matrix4} The modified result parameter. */ - var FeatureDetection = { - isChrome : isChrome, - chromeVersion : chromeVersion, - isSafari : isSafari, - safariVersion : safariVersion, - isWebkit : isWebkit, - webkitVersion : webkitVersion, - isInternetExplorer : isInternetExplorer, - internetExplorerVersion : internetExplorerVersion, - isEdge : isEdge, - edgeVersion : edgeVersion, - isFirefox : isFirefox, - firefoxVersion : firefoxVersion, - isWindows : isWindows, - hardwareConcurrency : defaultValue(theNavigator.hardwareConcurrency, 3), - supportsPointerEvents : supportsPointerEvents, - supportsImageRenderingPixelated: supportsImageRenderingPixelated, - imageRenderingValue: imageRenderingValue + Matrix4.computePerspectiveOffCenter = function(left, right, bottom, top, near, far, result) { + Check.typeOf.number('left', left); + Check.typeOf.number('right', right); + Check.typeOf.number('bottom', bottom); + Check.typeOf.number('top', top); + Check.typeOf.number('near', near); + Check.typeOf.number('far', far); + Check.typeOf.object('result', result); + + var column0Row0 = 2.0 * near / (right - left); + var column1Row1 = 2.0 * near / (top - bottom); + var column2Row0 = (right + left) / (right - left); + var column2Row1 = (top + bottom) / (top - bottom); + var column2Row2 = -(far + near) / (far - near); + var column2Row3 = -1.0; + var column3Row2 = -2.0 * far * near / (far - near); + + result[0] = column0Row0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = column1Row1; + result[6] = 0.0; + result[7] = 0.0; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = column2Row3; + result[12] = 0.0; + result[13] = 0.0; + result[14] = column3Row2; + result[15] = 0.0; + return result; }; /** - * Detects whether the current browser supports the full screen standard. + * Computes a Matrix4 instance representing an infinite off center perspective transformation. * - * @returns {Boolean} true if the browser supports the full screen standard, false if not. + * @param {Number} left The number of meters to the left of the camera that will be in view. + * @param {Number} right The number of meters to the right of the camera that will be in view. + * @param {Number} bottom The number of meters below of the camera that will be in view. + * @param {Number} top The number of meters above of the camera that will be in view. + * @param {Number} near The distance to the near plane in meters. + * @param {Matrix4} result The object in which the result will be stored. + * @returns {Matrix4} The modified result parameter. + */ + Matrix4.computeInfinitePerspectiveOffCenter = function(left, right, bottom, top, near, result) { + Check.typeOf.number('left', left); + Check.typeOf.number('right', right); + Check.typeOf.number('bottom', bottom); + Check.typeOf.number('top', top); + Check.typeOf.number('near', near); + Check.typeOf.object('result', result); + + var column0Row0 = 2.0 * near / (right - left); + var column1Row1 = 2.0 * near / (top - bottom); + var column2Row0 = (right + left) / (right - left); + var column2Row1 = (top + bottom) / (top - bottom); + var column2Row2 = -1.0; + var column2Row3 = -1.0; + var column3Row2 = -2.0 * near; + + result[0] = column0Row0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = column1Row1; + result[6] = 0.0; + result[7] = 0.0; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = column2Row3; + result[12] = 0.0; + result[13] = 0.0; + result[14] = column3Row2; + result[15] = 0.0; + return result; + }; + + /** + * Computes a Matrix4 instance that transforms from normalized device coordinates to window coordinates. * - * @see Fullscreen - * @see {@link http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html|W3C Fullscreen Living Specification} + * @param {Object}[viewport = { x : 0.0, y : 0.0, width : 0.0, height : 0.0 }] The viewport's corners as shown in Example 1. + * @param {Number}[nearDepthRange=0.0] The near plane distance in window coordinates. + * @param {Number}[farDepthRange=1.0] The far plane distance in window coordinates. + * @param {Matrix4} result The object in which the result will be stored. + * @returns {Matrix4} The modified result parameter. + * + * @example + * // Create viewport transformation using an explicit viewport and depth range. + * var m = Cesium.Matrix4.computeViewportTransformation({ + * x : 0.0, + * y : 0.0, + * width : 1024.0, + * height : 768.0 + * }, 0.0, 1.0, new Cesium.Matrix4()); */ - FeatureDetection.supportsFullscreen = function() { - return Fullscreen.supportsFullscreen(); + Matrix4.computeViewportTransformation = function(viewport, nearDepthRange, farDepthRange, result) { + Check.typeOf.object('result', result); + + viewport = defaultValue(viewport, defaultValue.EMPTY_OBJECT); + var x = defaultValue(viewport.x, 0.0); + var y = defaultValue(viewport.y, 0.0); + var width = defaultValue(viewport.width, 0.0); + var height = defaultValue(viewport.height, 0.0); + nearDepthRange = defaultValue(nearDepthRange, 0.0); + farDepthRange = defaultValue(farDepthRange, 1.0); + + var halfWidth = width * 0.5; + var halfHeight = height * 0.5; + var halfDepth = (farDepthRange - nearDepthRange) * 0.5; + + var column0Row0 = halfWidth; + var column1Row1 = halfHeight; + var column2Row2 = halfDepth; + var column3Row0 = x + halfWidth; + var column3Row1 = y + halfHeight; + var column3Row2 = nearDepthRange + halfDepth; + var column3Row3 = 1.0; + + result[0] = column0Row0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = column1Row1; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = column2Row2; + result[11] = 0.0; + result[12] = column3Row0; + result[13] = column3Row1; + result[14] = column3Row2; + result[15] = column3Row3; + return result; }; /** - * Detects whether the current browser supports typed arrays. + * Computes a Matrix4 instance that transforms from world space to view space. * - * @returns {Boolean} true if the browser supports typed arrays, false if not. + * @param {Cartesian3} position The position of the camera. + * @param {Cartesian3} direction The forward direction. + * @param {Cartesian3} up The up direction. + * @param {Cartesian3} right The right direction. + * @param {Matrix4} result The object in which the result will be stored. + * @returns {Matrix4} The modified result parameter. + */ + Matrix4.computeView = function(position, direction, up, right, result) { + Check.typeOf.object('position', position); + Check.typeOf.object('direction', direction); + Check.typeOf.object('up', up); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result[0] = right.x; + result[1] = up.x; + result[2] = -direction.x; + result[3] = 0.0; + result[4] = right.y; + result[5] = up.y; + result[6] = -direction.y; + result[7] = 0.0; + result[8] = right.z; + result[9] = up.z; + result[10] = -direction.z; + result[11] = 0.0; + result[12] = -Cartesian3.dot(right, position); + result[13] = -Cartesian3.dot(up, position); + result[14] = Cartesian3.dot(direction, position); + result[15] = 1.0; + return result; + }; + + /** + * Computes an Array from the provided Matrix4 instance. + * The array will be in column-major order. * - * @see {@link http://www.khronos.org/registry/typedarray/specs/latest/|Typed Array Specification} + * @param {Matrix4} matrix The matrix to use.. + * @param {Number[]} [result] The Array onto which to store the result. + * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. + * + * @example + * //create an array from an instance of Matrix4 + * // m = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] + * var a = Cesium.Matrix4.toArray(m); + * + * // m remains the same + * //creates a = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0] */ - FeatureDetection.supportsTypedArrays = function() { - return typeof ArrayBuffer !== 'undefined'; + Matrix4.toArray = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + + if (!defined(result)) { + return [matrix[0], matrix[1], matrix[2], matrix[3], + matrix[4], matrix[5], matrix[6], matrix[7], + matrix[8], matrix[9], matrix[10], matrix[11], + matrix[12], matrix[13], matrix[14], matrix[15]]; + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; }; /** - * Detects whether the current browser supports Web Workers. + * Computes the array index of the element at the provided row and column. * - * @returns {Boolean} true if the browsers supports Web Workers, false if not. + * @param {Number} row The zero-based index of the row. + * @param {Number} column The zero-based index of the column. + * @returns {Number} The index of the element at the provided row and column. * - * @see {@link http://www.w3.org/TR/workers/} + * @exception {DeveloperError} row must be 0, 1, 2, or 3. + * @exception {DeveloperError} column must be 0, 1, 2, or 3. + * + * @example + * var myMatrix = new Cesium.Matrix4(); + * var column1Row0Index = Cesium.Matrix4.getElementIndex(1, 0); + * var column1Row0 = myMatrix[column1Row0Index]; + * myMatrix[column1Row0Index] = 10.0; */ - FeatureDetection.supportsWebWorkers = function() { - return typeof Worker !== 'undefined'; + Matrix4.getElementIndex = function(column, row) { + Check.typeOf.number.greaterThanOrEquals('row', row, 0); + Check.typeOf.number.lessThanOrEquals('row', row, 3); + + Check.typeOf.number.greaterThanOrEquals('column', column, 0); + Check.typeOf.number.lessThanOrEquals('column', column, 3); + + return column * 4 + row; }; - return FeatureDetection; -}); + /** + * Retrieves a copy of the matrix column at the provided index as a Cartesian4 instance. + * + * @param {Matrix4} matrix The matrix to use. + * @param {Number} index The zero-based index of the column to retrieve. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. + * + * @exception {DeveloperError} index must be 0, 1, 2, or 3. + * + * @example + * //returns a Cartesian4 instance with values from the specified column + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] + * + * //Example 1: Creates an instance of Cartesian + * var a = Cesium.Matrix4.getColumn(m, 2, new Cesium.Cartesian4()); + * + * @example + * //Example 2: Sets values for Cartesian instance + * var a = new Cesium.Cartesian4(); + * Cesium.Matrix4.getColumn(m, 2, a); + * + * // a.x = 12.0; a.y = 16.0; a.z = 20.0; a.w = 24.0; + */ + Matrix4.getColumn = function(matrix, index, result) { + Check.typeOf.object('matrix', matrix); -define('Core/WebGLConstants',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 3); + + Check.typeOf.object('result', result); + + var startIndex = index * 4; + var x = matrix[startIndex]; + var y = matrix[startIndex + 1]; + var z = matrix[startIndex + 2]; + var w = matrix[startIndex + 3]; + + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + }; /** - * Enum containing WebGL Constant values by name. - * for use without an active WebGL context, or in cases where certain constants are unavailable using the WebGL context - * (For example, in [Safari 9]{@link https://github.com/AnalyticalGraphicsInc/cesium/issues/2989}). + * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian4 instance. * - * These match the constants from the [WebGL 1.0]{@link https://www.khronos.org/registry/webgl/specs/latest/1.0/} - * and [WebGL 2.0]{@link https://www.khronos.org/registry/webgl/specs/latest/2.0/} - * specifications. + * @param {Matrix4} matrix The matrix to use. + * @param {Number} index The zero-based index of the column to set. + * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified column. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * - * @exports WebGLConstants + * @exception {DeveloperError} index must be 0, 1, 2, or 3. + * + * @example + * //creates a new Matrix4 instance with new column values from the Cartesian4 instance + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] + * + * var a = Cesium.Matrix4.setColumn(m, 2, new Cesium.Cartesian4(99.0, 98.0, 97.0, 96.0), new Cesium.Matrix4()); + * + * // m remains the same + * // a = [10.0, 11.0, 99.0, 13.0] + * // [14.0, 15.0, 98.0, 17.0] + * // [18.0, 19.0, 97.0, 21.0] + * // [22.0, 23.0, 96.0, 25.0] */ - var WebGLConstants = { - DEPTH_BUFFER_BIT : 0x00000100, - STENCIL_BUFFER_BIT : 0x00000400, - COLOR_BUFFER_BIT : 0x00004000, - POINTS : 0x0000, - LINES : 0x0001, - LINE_LOOP : 0x0002, - LINE_STRIP : 0x0003, - TRIANGLES : 0x0004, - TRIANGLE_STRIP : 0x0005, - TRIANGLE_FAN : 0x0006, - ZERO : 0, - ONE : 1, - SRC_COLOR : 0x0300, - ONE_MINUS_SRC_COLOR : 0x0301, - SRC_ALPHA : 0x0302, - ONE_MINUS_SRC_ALPHA : 0x0303, - DST_ALPHA : 0x0304, - ONE_MINUS_DST_ALPHA : 0x0305, - DST_COLOR : 0x0306, - ONE_MINUS_DST_COLOR : 0x0307, - SRC_ALPHA_SATURATE : 0x0308, - FUNC_ADD : 0x8006, - BLEND_EQUATION : 0x8009, - BLEND_EQUATION_RGB : 0x8009, // same as BLEND_EQUATION - BLEND_EQUATION_ALPHA : 0x883D, - FUNC_SUBTRACT : 0x800A, - FUNC_REVERSE_SUBTRACT : 0x800B, - BLEND_DST_RGB : 0x80C8, - BLEND_SRC_RGB : 0x80C9, - BLEND_DST_ALPHA : 0x80CA, - BLEND_SRC_ALPHA : 0x80CB, - CONSTANT_COLOR : 0x8001, - ONE_MINUS_CONSTANT_COLOR : 0x8002, - CONSTANT_ALPHA : 0x8003, - ONE_MINUS_CONSTANT_ALPHA : 0x8004, - BLEND_COLOR : 0x8005, - ARRAY_BUFFER : 0x8892, - ELEMENT_ARRAY_BUFFER : 0x8893, - ARRAY_BUFFER_BINDING : 0x8894, - ELEMENT_ARRAY_BUFFER_BINDING : 0x8895, - STREAM_DRAW : 0x88E0, - STATIC_DRAW : 0x88E4, - DYNAMIC_DRAW : 0x88E8, - BUFFER_SIZE : 0x8764, - BUFFER_USAGE : 0x8765, - CURRENT_VERTEX_ATTRIB : 0x8626, - FRONT : 0x0404, - BACK : 0x0405, - FRONT_AND_BACK : 0x0408, - CULL_FACE : 0x0B44, - BLEND : 0x0BE2, - DITHER : 0x0BD0, - STENCIL_TEST : 0x0B90, - DEPTH_TEST : 0x0B71, - SCISSOR_TEST : 0x0C11, - POLYGON_OFFSET_FILL : 0x8037, - SAMPLE_ALPHA_TO_COVERAGE : 0x809E, - SAMPLE_COVERAGE : 0x80A0, - NO_ERROR : 0, - INVALID_ENUM : 0x0500, - INVALID_VALUE : 0x0501, - INVALID_OPERATION : 0x0502, - OUT_OF_MEMORY : 0x0505, - CW : 0x0900, - CCW : 0x0901, - LINE_WIDTH : 0x0B21, - ALIASED_POINT_SIZE_RANGE : 0x846D, - ALIASED_LINE_WIDTH_RANGE : 0x846E, - CULL_FACE_MODE : 0x0B45, - FRONT_FACE : 0x0B46, - DEPTH_RANGE : 0x0B70, - DEPTH_WRITEMASK : 0x0B72, - DEPTH_CLEAR_VALUE : 0x0B73, - DEPTH_FUNC : 0x0B74, - STENCIL_CLEAR_VALUE : 0x0B91, - STENCIL_FUNC : 0x0B92, - STENCIL_FAIL : 0x0B94, - STENCIL_PASS_DEPTH_FAIL : 0x0B95, - STENCIL_PASS_DEPTH_PASS : 0x0B96, - STENCIL_REF : 0x0B97, - STENCIL_VALUE_MASK : 0x0B93, - STENCIL_WRITEMASK : 0x0B98, - STENCIL_BACK_FUNC : 0x8800, - STENCIL_BACK_FAIL : 0x8801, - STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802, - STENCIL_BACK_PASS_DEPTH_PASS : 0x8803, - STENCIL_BACK_REF : 0x8CA3, - STENCIL_BACK_VALUE_MASK : 0x8CA4, - STENCIL_BACK_WRITEMASK : 0x8CA5, - VIEWPORT : 0x0BA2, - SCISSOR_BOX : 0x0C10, - COLOR_CLEAR_VALUE : 0x0C22, - COLOR_WRITEMASK : 0x0C23, - UNPACK_ALIGNMENT : 0x0CF5, - PACK_ALIGNMENT : 0x0D05, - MAX_TEXTURE_SIZE : 0x0D33, - MAX_VIEWPORT_DIMS : 0x0D3A, - SUBPIXEL_BITS : 0x0D50, - RED_BITS : 0x0D52, - GREEN_BITS : 0x0D53, - BLUE_BITS : 0x0D54, - ALPHA_BITS : 0x0D55, - DEPTH_BITS : 0x0D56, - STENCIL_BITS : 0x0D57, - POLYGON_OFFSET_UNITS : 0x2A00, - POLYGON_OFFSET_FACTOR : 0x8038, - TEXTURE_BINDING_2D : 0x8069, - SAMPLE_BUFFERS : 0x80A8, - SAMPLES : 0x80A9, - SAMPLE_COVERAGE_VALUE : 0x80AA, - SAMPLE_COVERAGE_INVERT : 0x80AB, - COMPRESSED_TEXTURE_FORMATS : 0x86A3, - DONT_CARE : 0x1100, - FASTEST : 0x1101, - NICEST : 0x1102, - GENERATE_MIPMAP_HINT : 0x8192, - BYTE : 0x1400, - UNSIGNED_BYTE : 0x1401, - SHORT : 0x1402, - UNSIGNED_SHORT : 0x1403, - INT : 0x1404, - UNSIGNED_INT : 0x1405, - FLOAT : 0x1406, - DEPTH_COMPONENT : 0x1902, - ALPHA : 0x1906, - RGB : 0x1907, - RGBA : 0x1908, - LUMINANCE : 0x1909, - LUMINANCE_ALPHA : 0x190A, - UNSIGNED_SHORT_4_4_4_4 : 0x8033, - UNSIGNED_SHORT_5_5_5_1 : 0x8034, - UNSIGNED_SHORT_5_6_5 : 0x8363, - FRAGMENT_SHADER : 0x8B30, - VERTEX_SHADER : 0x8B31, - MAX_VERTEX_ATTRIBS : 0x8869, - MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB, - MAX_VARYING_VECTORS : 0x8DFC, - MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D, - MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C, - MAX_TEXTURE_IMAGE_UNITS : 0x8872, - MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD, - SHADER_TYPE : 0x8B4F, - DELETE_STATUS : 0x8B80, - LINK_STATUS : 0x8B82, - VALIDATE_STATUS : 0x8B83, - ATTACHED_SHADERS : 0x8B85, - ACTIVE_UNIFORMS : 0x8B86, - ACTIVE_ATTRIBUTES : 0x8B89, - SHADING_LANGUAGE_VERSION : 0x8B8C, - CURRENT_PROGRAM : 0x8B8D, - NEVER : 0x0200, - LESS : 0x0201, - EQUAL : 0x0202, - LEQUAL : 0x0203, - GREATER : 0x0204, - NOTEQUAL : 0x0205, - GEQUAL : 0x0206, - ALWAYS : 0x0207, - KEEP : 0x1E00, - REPLACE : 0x1E01, - INCR : 0x1E02, - DECR : 0x1E03, - INVERT : 0x150A, - INCR_WRAP : 0x8507, - DECR_WRAP : 0x8508, - VENDOR : 0x1F00, - RENDERER : 0x1F01, - VERSION : 0x1F02, - NEAREST : 0x2600, - LINEAR : 0x2601, - NEAREST_MIPMAP_NEAREST : 0x2700, - LINEAR_MIPMAP_NEAREST : 0x2701, - NEAREST_MIPMAP_LINEAR : 0x2702, - LINEAR_MIPMAP_LINEAR : 0x2703, - TEXTURE_MAG_FILTER : 0x2800, - TEXTURE_MIN_FILTER : 0x2801, - TEXTURE_WRAP_S : 0x2802, - TEXTURE_WRAP_T : 0x2803, - TEXTURE_2D : 0x0DE1, - TEXTURE : 0x1702, - TEXTURE_CUBE_MAP : 0x8513, - TEXTURE_BINDING_CUBE_MAP : 0x8514, - TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515, - TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516, - TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517, - TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518, - TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519, - TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A, - MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C, - TEXTURE0 : 0x84C0, - TEXTURE1 : 0x84C1, - TEXTURE2 : 0x84C2, - TEXTURE3 : 0x84C3, - TEXTURE4 : 0x84C4, - TEXTURE5 : 0x84C5, - TEXTURE6 : 0x84C6, - TEXTURE7 : 0x84C7, - TEXTURE8 : 0x84C8, - TEXTURE9 : 0x84C9, - TEXTURE10 : 0x84CA, - TEXTURE11 : 0x84CB, - TEXTURE12 : 0x84CC, - TEXTURE13 : 0x84CD, - TEXTURE14 : 0x84CE, - TEXTURE15 : 0x84CF, - TEXTURE16 : 0x84D0, - TEXTURE17 : 0x84D1, - TEXTURE18 : 0x84D2, - TEXTURE19 : 0x84D3, - TEXTURE20 : 0x84D4, - TEXTURE21 : 0x84D5, - TEXTURE22 : 0x84D6, - TEXTURE23 : 0x84D7, - TEXTURE24 : 0x84D8, - TEXTURE25 : 0x84D9, - TEXTURE26 : 0x84DA, - TEXTURE27 : 0x84DB, - TEXTURE28 : 0x84DC, - TEXTURE29 : 0x84DD, - TEXTURE30 : 0x84DE, - TEXTURE31 : 0x84DF, - ACTIVE_TEXTURE : 0x84E0, - REPEAT : 0x2901, - CLAMP_TO_EDGE : 0x812F, - MIRRORED_REPEAT : 0x8370, - FLOAT_VEC2 : 0x8B50, - FLOAT_VEC3 : 0x8B51, - FLOAT_VEC4 : 0x8B52, - INT_VEC2 : 0x8B53, - INT_VEC3 : 0x8B54, - INT_VEC4 : 0x8B55, - BOOL : 0x8B56, - BOOL_VEC2 : 0x8B57, - BOOL_VEC3 : 0x8B58, - BOOL_VEC4 : 0x8B59, - FLOAT_MAT2 : 0x8B5A, - FLOAT_MAT3 : 0x8B5B, - FLOAT_MAT4 : 0x8B5C, - SAMPLER_2D : 0x8B5E, - SAMPLER_CUBE : 0x8B60, - VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622, - VERTEX_ATTRIB_ARRAY_SIZE : 0x8623, - VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624, - VERTEX_ATTRIB_ARRAY_TYPE : 0x8625, - VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A, - VERTEX_ATTRIB_ARRAY_POINTER : 0x8645, - VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F, - IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A, - IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B, - COMPILE_STATUS : 0x8B81, - LOW_FLOAT : 0x8DF0, - MEDIUM_FLOAT : 0x8DF1, - HIGH_FLOAT : 0x8DF2, - LOW_INT : 0x8DF3, - MEDIUM_INT : 0x8DF4, - HIGH_INT : 0x8DF5, - FRAMEBUFFER : 0x8D40, - RENDERBUFFER : 0x8D41, - RGBA4 : 0x8056, - RGB5_A1 : 0x8057, - RGB565 : 0x8D62, - DEPTH_COMPONENT16 : 0x81A5, - STENCIL_INDEX : 0x1901, - STENCIL_INDEX8 : 0x8D48, - DEPTH_STENCIL : 0x84F9, - RENDERBUFFER_WIDTH : 0x8D42, - RENDERBUFFER_HEIGHT : 0x8D43, - RENDERBUFFER_INTERNAL_FORMAT : 0x8D44, - RENDERBUFFER_RED_SIZE : 0x8D50, - RENDERBUFFER_GREEN_SIZE : 0x8D51, - RENDERBUFFER_BLUE_SIZE : 0x8D52, - RENDERBUFFER_ALPHA_SIZE : 0x8D53, - RENDERBUFFER_DEPTH_SIZE : 0x8D54, - RENDERBUFFER_STENCIL_SIZE : 0x8D55, - FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0, - FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1, - FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2, - FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3, - COLOR_ATTACHMENT0 : 0x8CE0, - DEPTH_ATTACHMENT : 0x8D00, - STENCIL_ATTACHMENT : 0x8D20, - DEPTH_STENCIL_ATTACHMENT : 0x821A, - NONE : 0, - FRAMEBUFFER_COMPLETE : 0x8CD5, - FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6, - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7, - FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9, - FRAMEBUFFER_UNSUPPORTED : 0x8CDD, - FRAMEBUFFER_BINDING : 0x8CA6, - RENDERBUFFER_BINDING : 0x8CA7, - MAX_RENDERBUFFER_SIZE : 0x84E8, - INVALID_FRAMEBUFFER_OPERATION : 0x0506, - UNPACK_FLIP_Y_WEBGL : 0x9240, - UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241, - CONTEXT_LOST_WEBGL : 0x9242, - UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243, - BROWSER_DEFAULT_WEBGL : 0x9244, - - // WEBGL_compressed_texture_s3tc - COMPRESSED_RGB_S3TC_DXT1_EXT : 0x83F0, - COMPRESSED_RGBA_S3TC_DXT1_EXT : 0x83F1, - COMPRESSED_RGBA_S3TC_DXT3_EXT : 0x83F2, - COMPRESSED_RGBA_S3TC_DXT5_EXT : 0x83F3, - - // WEBGL_compressed_texture_pvrtc - COMPRESSED_RGB_PVRTC_4BPPV1_IMG : 0x8C00, - COMPRESSED_RGB_PVRTC_2BPPV1_IMG : 0x8C01, - COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : 0x8C02, - COMPRESSED_RGBA_PVRTC_2BPPV1_IMG : 0x8C03, - - // WEBGL_compressed_texture_etc1 - COMPRESSED_RGB_ETC1_WEBGL : 0x8D64, - - // Desktop OpenGL - DOUBLE : 0x140A, + Matrix4.setColumn = function(matrix, index, cartesian, result) { + Check.typeOf.object('matrix', matrix); - // WebGL 2 - READ_BUFFER : 0x0C02, - UNPACK_ROW_LENGTH : 0x0CF2, - UNPACK_SKIP_ROWS : 0x0CF3, - UNPACK_SKIP_PIXELS : 0x0CF4, - PACK_ROW_LENGTH : 0x0D02, - PACK_SKIP_ROWS : 0x0D03, - PACK_SKIP_PIXELS : 0x0D04, - COLOR : 0x1800, - DEPTH : 0x1801, - STENCIL : 0x1802, - RED : 0x1903, - RGB8 : 0x8051, - RGBA8 : 0x8058, - RGB10_A2 : 0x8059, - TEXTURE_BINDING_3D : 0x806A, - UNPACK_SKIP_IMAGES : 0x806D, - UNPACK_IMAGE_HEIGHT : 0x806E, - TEXTURE_3D : 0x806F, - TEXTURE_WRAP_R : 0x8072, - MAX_3D_TEXTURE_SIZE : 0x8073, - UNSIGNED_INT_2_10_10_10_REV : 0x8368, - MAX_ELEMENTS_VERTICES : 0x80E8, - MAX_ELEMENTS_INDICES : 0x80E9, - TEXTURE_MIN_LOD : 0x813A, - TEXTURE_MAX_LOD : 0x813B, - TEXTURE_BASE_LEVEL : 0x813C, - TEXTURE_MAX_LEVEL : 0x813D, - MIN : 0x8007, - MAX : 0x8008, - DEPTH_COMPONENT24 : 0x81A6, - MAX_TEXTURE_LOD_BIAS : 0x84FD, - TEXTURE_COMPARE_MODE : 0x884C, - TEXTURE_COMPARE_FUNC : 0x884D, - CURRENT_QUERY : 0x8865, - QUERY_RESULT : 0x8866, - QUERY_RESULT_AVAILABLE : 0x8867, - STREAM_READ : 0x88E1, - STREAM_COPY : 0x88E2, - STATIC_READ : 0x88E5, - STATIC_COPY : 0x88E6, - DYNAMIC_READ : 0x88E9, - DYNAMIC_COPY : 0x88EA, - MAX_DRAW_BUFFERS : 0x8824, - DRAW_BUFFER0 : 0x8825, - DRAW_BUFFER1 : 0x8826, - DRAW_BUFFER2 : 0x8827, - DRAW_BUFFER3 : 0x8828, - DRAW_BUFFER4 : 0x8829, - DRAW_BUFFER5 : 0x882A, - DRAW_BUFFER6 : 0x882B, - DRAW_BUFFER7 : 0x882C, - DRAW_BUFFER8 : 0x882D, - DRAW_BUFFER9 : 0x882E, - DRAW_BUFFER10 : 0x882F, - DRAW_BUFFER11 : 0x8830, - DRAW_BUFFER12 : 0x8831, - DRAW_BUFFER13 : 0x8832, - DRAW_BUFFER14 : 0x8833, - DRAW_BUFFER15 : 0x8834, - MAX_FRAGMENT_UNIFORM_COMPONENTS : 0x8B49, - MAX_VERTEX_UNIFORM_COMPONENTS : 0x8B4A, - SAMPLER_3D : 0x8B5F, - SAMPLER_2D_SHADOW : 0x8B62, - FRAGMENT_SHADER_DERIVATIVE_HINT : 0x8B8B, - PIXEL_PACK_BUFFER : 0x88EB, - PIXEL_UNPACK_BUFFER : 0x88EC, - PIXEL_PACK_BUFFER_BINDING : 0x88ED, - PIXEL_UNPACK_BUFFER_BINDING : 0x88EF, - FLOAT_MAT2x3 : 0x8B65, - FLOAT_MAT2x4 : 0x8B66, - FLOAT_MAT3x2 : 0x8B67, - FLOAT_MAT3x4 : 0x8B68, - FLOAT_MAT4x2 : 0x8B69, - FLOAT_MAT4x3 : 0x8B6A, - SRGB : 0x8C40, - SRGB8 : 0x8C41, - SRGB8_ALPHA8 : 0x8C43, - COMPARE_REF_TO_TEXTURE : 0x884E, - RGBA32F : 0x8814, - RGB32F : 0x8815, - RGBA16F : 0x881A, - RGB16F : 0x881B, - VERTEX_ATTRIB_ARRAY_INTEGER : 0x88FD, - MAX_ARRAY_TEXTURE_LAYERS : 0x88FF, - MIN_PROGRAM_TEXEL_OFFSET : 0x8904, - MAX_PROGRAM_TEXEL_OFFSET : 0x8905, - MAX_VARYING_COMPONENTS : 0x8B4B, - TEXTURE_2D_ARRAY : 0x8C1A, - TEXTURE_BINDING_2D_ARRAY : 0x8C1D, - R11F_G11F_B10F : 0x8C3A, - UNSIGNED_INT_10F_11F_11F_REV : 0x8C3B, - RGB9_E5 : 0x8C3D, - UNSIGNED_INT_5_9_9_9_REV : 0x8C3E, - TRANSFORM_FEEDBACK_BUFFER_MODE : 0x8C7F, - MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS : 0x8C80, - TRANSFORM_FEEDBACK_VARYINGS : 0x8C83, - TRANSFORM_FEEDBACK_BUFFER_START : 0x8C84, - TRANSFORM_FEEDBACK_BUFFER_SIZE : 0x8C85, - TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN : 0x8C88, - RASTERIZER_DISCARD : 0x8C89, - MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS : 0x8C8A, - MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS : 0x8C8B, - INTERLEAVED_ATTRIBS : 0x8C8C, - SEPARATE_ATTRIBS : 0x8C8D, - TRANSFORM_FEEDBACK_BUFFER : 0x8C8E, - TRANSFORM_FEEDBACK_BUFFER_BINDING : 0x8C8F, - RGBA32UI : 0x8D70, - RGB32UI : 0x8D71, - RGBA16UI : 0x8D76, - RGB16UI : 0x8D77, - RGBA8UI : 0x8D7C, - RGB8UI : 0x8D7D, - RGBA32I : 0x8D82, - RGB32I : 0x8D83, - RGBA16I : 0x8D88, - RGB16I : 0x8D89, - RGBA8I : 0x8D8E, - RGB8I : 0x8D8F, - RED_INTEGER : 0x8D94, - RGB_INTEGER : 0x8D98, - RGBA_INTEGER : 0x8D99, - SAMPLER_2D_ARRAY : 0x8DC1, - SAMPLER_2D_ARRAY_SHADOW : 0x8DC4, - SAMPLER_CUBE_SHADOW : 0x8DC5, - UNSIGNED_INT_VEC2 : 0x8DC6, - UNSIGNED_INT_VEC3 : 0x8DC7, - UNSIGNED_INT_VEC4 : 0x8DC8, - INT_SAMPLER_2D : 0x8DCA, - INT_SAMPLER_3D : 0x8DCB, - INT_SAMPLER_CUBE : 0x8DCC, - INT_SAMPLER_2D_ARRAY : 0x8DCF, - UNSIGNED_INT_SAMPLER_2D : 0x8DD2, - UNSIGNED_INT_SAMPLER_3D : 0x8DD3, - UNSIGNED_INT_SAMPLER_CUBE : 0x8DD4, - UNSIGNED_INT_SAMPLER_2D_ARRAY : 0x8DD7, - DEPTH_COMPONENT32F : 0x8CAC, - DEPTH32F_STENCIL8 : 0x8CAD, - FLOAT_32_UNSIGNED_INT_24_8_REV : 0x8DAD, - FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : 0x8210, - FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE : 0x8211, - FRAMEBUFFER_ATTACHMENT_RED_SIZE : 0x8212, - FRAMEBUFFER_ATTACHMENT_GREEN_SIZE : 0x8213, - FRAMEBUFFER_ATTACHMENT_BLUE_SIZE : 0x8214, - FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE : 0x8215, - FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE : 0x8216, - FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE : 0x8217, - FRAMEBUFFER_DEFAULT : 0x8218, - UNSIGNED_INT_24_8 : 0x84FA, - DEPTH24_STENCIL8 : 0x88F0, - UNSIGNED_NORMALIZED : 0x8C17, - DRAW_FRAMEBUFFER_BINDING : 0x8CA6, // Same as FRAMEBUFFER_BINDING - READ_FRAMEBUFFER : 0x8CA8, - DRAW_FRAMEBUFFER : 0x8CA9, - READ_FRAMEBUFFER_BINDING : 0x8CAA, - RENDERBUFFER_SAMPLES : 0x8CAB, - FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER : 0x8CD4, - MAX_COLOR_ATTACHMENTS : 0x8CDF, - COLOR_ATTACHMENT1 : 0x8CE1, - COLOR_ATTACHMENT2 : 0x8CE2, - COLOR_ATTACHMENT3 : 0x8CE3, - COLOR_ATTACHMENT4 : 0x8CE4, - COLOR_ATTACHMENT5 : 0x8CE5, - COLOR_ATTACHMENT6 : 0x8CE6, - COLOR_ATTACHMENT7 : 0x8CE7, - COLOR_ATTACHMENT8 : 0x8CE8, - COLOR_ATTACHMENT9 : 0x8CE9, - COLOR_ATTACHMENT10 : 0x8CEA, - COLOR_ATTACHMENT11 : 0x8CEB, - COLOR_ATTACHMENT12 : 0x8CEC, - COLOR_ATTACHMENT13 : 0x8CED, - COLOR_ATTACHMENT14 : 0x8CEE, - COLOR_ATTACHMENT15 : 0x8CEF, - FRAMEBUFFER_INCOMPLETE_MULTISAMPLE : 0x8D56, - MAX_SAMPLES : 0x8D57, - HALF_FLOAT : 0x140B, - RG : 0x8227, - RG_INTEGER : 0x8228, - R8 : 0x8229, - RG8 : 0x822B, - R16F : 0x822D, - R32F : 0x822E, - RG16F : 0x822F, - RG32F : 0x8230, - R8I : 0x8231, - R8UI : 0x8232, - R16I : 0x8233, - R16UI : 0x8234, - R32I : 0x8235, - R32UI : 0x8236, - RG8I : 0x8237, - RG8UI : 0x8238, - RG16I : 0x8239, - RG16UI : 0x823A, - RG32I : 0x823B, - RG32UI : 0x823C, - VERTEX_ARRAY_BINDING : 0x85B5, - R8_SNORM : 0x8F94, - RG8_SNORM : 0x8F95, - RGB8_SNORM : 0x8F96, - RGBA8_SNORM : 0x8F97, - SIGNED_NORMALIZED : 0x8F9C, - COPY_READ_BUFFER : 0x8F36, - COPY_WRITE_BUFFER : 0x8F37, - COPY_READ_BUFFER_BINDING : 0x8F36, // Same as COPY_READ_BUFFER - COPY_WRITE_BUFFER_BINDING : 0x8F37, // Same as COPY_WRITE_BUFFER - UNIFORM_BUFFER : 0x8A11, - UNIFORM_BUFFER_BINDING : 0x8A28, - UNIFORM_BUFFER_START : 0x8A29, - UNIFORM_BUFFER_SIZE : 0x8A2A, - MAX_VERTEX_UNIFORM_BLOCKS : 0x8A2B, - MAX_FRAGMENT_UNIFORM_BLOCKS : 0x8A2D, - MAX_COMBINED_UNIFORM_BLOCKS : 0x8A2E, - MAX_UNIFORM_BUFFER_BINDINGS : 0x8A2F, - MAX_UNIFORM_BLOCK_SIZE : 0x8A30, - MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS : 0x8A31, - MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS : 0x8A33, - UNIFORM_BUFFER_OFFSET_ALIGNMENT : 0x8A34, - ACTIVE_UNIFORM_BLOCKS : 0x8A36, - UNIFORM_TYPE : 0x8A37, - UNIFORM_SIZE : 0x8A38, - UNIFORM_BLOCK_INDEX : 0x8A3A, - UNIFORM_OFFSET : 0x8A3B, - UNIFORM_ARRAY_STRIDE : 0x8A3C, - UNIFORM_MATRIX_STRIDE : 0x8A3D, - UNIFORM_IS_ROW_MAJOR : 0x8A3E, - UNIFORM_BLOCK_BINDING : 0x8A3F, - UNIFORM_BLOCK_DATA_SIZE : 0x8A40, - UNIFORM_BLOCK_ACTIVE_UNIFORMS : 0x8A42, - UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES : 0x8A43, - UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER : 0x8A44, - UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER : 0x8A46, - INVALID_INDEX : 0xFFFFFFFF, - MAX_VERTEX_OUTPUT_COMPONENTS : 0x9122, - MAX_FRAGMENT_INPUT_COMPONENTS : 0x9125, - MAX_SERVER_WAIT_TIMEOUT : 0x9111, - OBJECT_TYPE : 0x9112, - SYNC_CONDITION : 0x9113, - SYNC_STATUS : 0x9114, - SYNC_FLAGS : 0x9115, - SYNC_FENCE : 0x9116, - SYNC_GPU_COMMANDS_COMPLETE : 0x9117, - UNSIGNALED : 0x9118, - SIGNALED : 0x9119, - ALREADY_SIGNALED : 0x911A, - TIMEOUT_EXPIRED : 0x911B, - CONDITION_SATISFIED : 0x911C, - WAIT_FAILED : 0x911D, - SYNC_FLUSH_COMMANDS_BIT : 0x00000001, - VERTEX_ATTRIB_ARRAY_DIVISOR : 0x88FE, - ANY_SAMPLES_PASSED : 0x8C2F, - ANY_SAMPLES_PASSED_CONSERVATIVE : 0x8D6A, - SAMPLER_BINDING : 0x8919, - RGB10_A2UI : 0x906F, - INT_2_10_10_10_REV : 0x8D9F, - TRANSFORM_FEEDBACK : 0x8E22, - TRANSFORM_FEEDBACK_PAUSED : 0x8E23, - TRANSFORM_FEEDBACK_ACTIVE : 0x8E24, - TRANSFORM_FEEDBACK_BINDING : 0x8E25, - COMPRESSED_R11_EAC : 0x9270, - COMPRESSED_SIGNED_R11_EAC : 0x9271, - COMPRESSED_RG11_EAC : 0x9272, - COMPRESSED_SIGNED_RG11_EAC : 0x9273, - COMPRESSED_RGB8_ETC2 : 0x9274, - COMPRESSED_SRGB8_ETC2 : 0x9275, - COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276, - COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277, - COMPRESSED_RGBA8_ETC2_EAC : 0x9278, - COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279, - TEXTURE_IMMUTABLE_FORMAT : 0x912F, - MAX_ELEMENT_INDEX : 0x8D6B, - TEXTURE_IMMUTABLE_LEVELS : 0x82DF, + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 3); - // Extensions - MAX_TEXTURE_MAX_ANISOTROPY_EXT : 0x84FF + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + result = Matrix4.clone(matrix, result); + var startIndex = index * 4; + result[startIndex] = cartesian.x; + result[startIndex + 1] = cartesian.y; + result[startIndex + 2] = cartesian.z; + result[startIndex + 3] = cartesian.w; + return result; }; - return freezeObject(WebGLConstants); -}); - -define('Core/ComponentDatatype',[ - './defaultValue', - './defined', - './DeveloperError', - './FeatureDetection', - './freezeObject', - './WebGLConstants' - ], function( - defaultValue, - defined, - DeveloperError, - FeatureDetection, - freezeObject, - WebGLConstants) { - 'use strict'; - - // Bail out if the browser doesn't support typed arrays, to prevent the setup function - // from failing, since we won't be able to create a WebGL context anyway. - if (!FeatureDetection.supportsTypedArrays()) { - return {}; - } - /** - * WebGL component datatypes. Components are intrinsics, - * which form attributes, which form vertices. + * Computes a new matrix that replaces the translation in the rightmost column of the provided + * matrix with the provided translation. This assumes the matrix is an affine transformation * - * @exports ComponentDatatype + * @param {Matrix4} matrix The matrix to use. + * @param {Cartesian3} translation The translation that replaces the translation of the provided matrix. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. */ - var ComponentDatatype = { - /** - * 8-bit signed byte corresponding to <code>gl.BYTE</code> and the type - * of an element in <code>Int8Array</code>. - * - * @type {Number} - * @constant - */ - BYTE : WebGLConstants.BYTE, - - /** - * 8-bit unsigned byte corresponding to <code>UNSIGNED_BYTE</code> and the type - * of an element in <code>Uint8Array</code>. - * - * @type {Number} - * @constant - */ - UNSIGNED_BYTE : WebGLConstants.UNSIGNED_BYTE, - - /** - * 16-bit signed short corresponding to <code>SHORT</code> and the type - * of an element in <code>Int16Array</code>. - * - * @type {Number} - * @constant - */ - SHORT : WebGLConstants.SHORT, - - /** - * 16-bit unsigned short corresponding to <code>UNSIGNED_SHORT</code> and the type - * of an element in <code>Uint16Array</code>. - * - * @type {Number} - * @constant - */ - UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT, + Matrix4.setTranslation = function(matrix, translation, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('translation', translation); + Check.typeOf.object('result', result); + + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; - /** - * 32-bit signed int corresponding to <code>INT</code> and the type - * of an element in <code>Int32Array</code>. - * - * @memberOf ComponentDatatype - * - * @type {Number} - * @constant - */ - INT : WebGLConstants.INT, + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; - /** - * 32-bit unsigned int corresponding to <code>UNSIGNED_INT</code> and the type - * of an element in <code>Uint32Array</code>. - * - * @memberOf ComponentDatatype - * - * @type {Number} - * @constant - */ - UNSIGNED_INT : WebGLConstants.UNSIGNED_INT, + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; - /** - * 32-bit floating-point corresponding to <code>FLOAT</code> and the type - * of an element in <code>Float32Array</code>. - * - * @type {Number} - * @constant - */ - FLOAT : WebGLConstants.FLOAT, + result[12] = translation.x; + result[13] = translation.y; + result[14] = translation.z; + result[15] = matrix[15]; - /** - * 64-bit floating-point corresponding to <code>gl.DOUBLE</code> (in Desktop OpenGL; - * this is not supported in WebGL, and is emulated in Cesium via {@link GeometryPipeline.encodeAttribute}) - * and the type of an element in <code>Float64Array</code>. - * - * @memberOf ComponentDatatype - * - * @type {Number} - * @constant - * @default 0x140A - */ - DOUBLE : WebGLConstants.DOUBLE + return result; }; /** - * Returns the size, in bytes, of the corresponding datatype. + * Retrieves a copy of the matrix row at the provided index as a Cartesian4 instance. * - * @param {ComponentDatatype} componentDatatype The component datatype to get the size of. - * @returns {Number} The size in bytes. + * @param {Matrix4} matrix The matrix to use. + * @param {Number} index The zero-based index of the row to retrieve. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. * - * @exception {DeveloperError} componentDatatype is not a valid value. + * @exception {DeveloperError} index must be 0, 1, 2, or 3. * * @example - * // Returns Int8Array.BYTES_PER_ELEMENT - * var size = Cesium.ComponentDatatype.getSizeInBytes(Cesium.ComponentDatatype.BYTE); - */ - ComponentDatatype.getSizeInBytes = function(componentDatatype){ - if (!defined(componentDatatype)) { - throw new DeveloperError('value is required.'); - } - - switch (componentDatatype) { - case ComponentDatatype.BYTE: - return Int8Array.BYTES_PER_ELEMENT; - case ComponentDatatype.UNSIGNED_BYTE: - return Uint8Array.BYTES_PER_ELEMENT; - case ComponentDatatype.SHORT: - return Int16Array.BYTES_PER_ELEMENT; - case ComponentDatatype.UNSIGNED_SHORT: - return Uint16Array.BYTES_PER_ELEMENT; - case ComponentDatatype.INT: - return Int32Array.BYTES_PER_ELEMENT; - case ComponentDatatype.UNSIGNED_INT: - return Uint32Array.BYTES_PER_ELEMENT; - case ComponentDatatype.FLOAT: - return Float32Array.BYTES_PER_ELEMENT; - case ComponentDatatype.DOUBLE: - return Float64Array.BYTES_PER_ELEMENT; - default: - throw new DeveloperError('componentDatatype is not a valid value.'); - } - }; - - /** - * Gets the {@link ComponentDatatype} for the provided TypedArray instance. - * - * @param {TypedArray} array The typed array. - * @returns {ComponentDatatype} The ComponentDatatype for the provided array, or undefined if the array is not a TypedArray. - */ - ComponentDatatype.fromTypedArray = function(array) { - if (array instanceof Int8Array) { - return ComponentDatatype.BYTE; - } - if (array instanceof Uint8Array) { - return ComponentDatatype.UNSIGNED_BYTE; - } - if (array instanceof Int16Array) { - return ComponentDatatype.SHORT; - } - if (array instanceof Uint16Array) { - return ComponentDatatype.UNSIGNED_SHORT; - } - if (array instanceof Int32Array) { - return ComponentDatatype.INT; - } - if (array instanceof Uint32Array) { - return ComponentDatatype.UNSIGNED_INT; - } - if (array instanceof Float32Array) { - return ComponentDatatype.FLOAT; - } - if (array instanceof Float64Array) { - return ComponentDatatype.DOUBLE; - } - }; - - /** - * Validates that the provided component datatype is a valid {@link ComponentDatatype} + * //returns a Cartesian4 instance with values from the specified column + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] * - * @param {ComponentDatatype} componentDatatype The component datatype to validate. - * @returns {Boolean} <code>true</code> if the provided component datatype is a valid value; otherwise, <code>false</code>. + * //Example 1: Returns an instance of Cartesian + * var a = Cesium.Matrix4.getRow(m, 2, new Cesium.Cartesian4()); * * @example - * if (!Cesium.ComponentDatatype.validate(componentDatatype)) { - * throw new Cesium.DeveloperError('componentDatatype must be a valid value.'); - * } + * //Example 2: Sets values for a Cartesian instance + * var a = new Cesium.Cartesian4(); + * Cesium.Matrix4.getRow(m, 2, a); + * + * // a.x = 18.0; a.y = 19.0; a.z = 20.0; a.w = 21.0; */ - ComponentDatatype.validate = function(componentDatatype) { - return defined(componentDatatype) && - (componentDatatype === ComponentDatatype.BYTE || - componentDatatype === ComponentDatatype.UNSIGNED_BYTE || - componentDatatype === ComponentDatatype.SHORT || - componentDatatype === ComponentDatatype.UNSIGNED_SHORT || - componentDatatype === ComponentDatatype.INT || - componentDatatype === ComponentDatatype.UNSIGNED_INT || - componentDatatype === ComponentDatatype.FLOAT || - componentDatatype === ComponentDatatype.DOUBLE); + Matrix4.getRow = function(matrix, index, result) { + Check.typeOf.object('matrix', matrix); + + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 3); + + Check.typeOf.object('result', result); + + var x = matrix[index]; + var y = matrix[index + 4]; + var z = matrix[index + 8]; + var w = matrix[index + 12]; + + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; }; /** - * Creates a typed array corresponding to component data type. + * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian4 instance. * - * @param {ComponentDatatype} componentDatatype The component data type. - * @param {Number|Array} valuesOrLength The length of the array to create or an array. - * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array. + * @param {Matrix4} matrix The matrix to use. + * @param {Number} index The zero-based index of the row to set. + * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified row. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * - * @exception {DeveloperError} componentDatatype is not a valid value. + * @exception {DeveloperError} index must be 0, 1, 2, or 3. * * @example - * // creates a Float32Array with length of 100 - * var typedArray = Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, 100); + * //create a new Matrix4 instance with new row values from the Cartesian4 instance + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] + * + * var a = Cesium.Matrix4.setRow(m, 2, new Cesium.Cartesian4(99.0, 98.0, 97.0, 96.0), new Cesium.Matrix4()); + * + * // m remains the same + * // a = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [99.0, 98.0, 97.0, 96.0] + * // [22.0, 23.0, 24.0, 25.0] */ - ComponentDatatype.createTypedArray = function(componentDatatype, valuesOrLength) { - if (!defined(componentDatatype)) { - throw new DeveloperError('componentDatatype is required.'); - } - if (!defined(valuesOrLength)) { - throw new DeveloperError('valuesOrLength is required.'); - } + Matrix4.setRow = function(matrix, index, cartesian, result) { + Check.typeOf.object('matrix', matrix); + + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 3); + + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); - switch (componentDatatype) { - case ComponentDatatype.BYTE: - return new Int8Array(valuesOrLength); - case ComponentDatatype.UNSIGNED_BYTE: - return new Uint8Array(valuesOrLength); - case ComponentDatatype.SHORT: - return new Int16Array(valuesOrLength); - case ComponentDatatype.UNSIGNED_SHORT: - return new Uint16Array(valuesOrLength); - case ComponentDatatype.INT: - return new Int32Array(valuesOrLength); - case ComponentDatatype.UNSIGNED_INT: - return new Uint32Array(valuesOrLength); - case ComponentDatatype.FLOAT: - return new Float32Array(valuesOrLength); - case ComponentDatatype.DOUBLE: - return new Float64Array(valuesOrLength); - default: - throw new DeveloperError('componentDatatype is not a valid value.'); - } + result = Matrix4.clone(matrix, result); + result[index] = cartesian.x; + result[index + 4] = cartesian.y; + result[index + 8] = cartesian.z; + result[index + 12] = cartesian.w; + return result; }; + var scratchColumn = new Cartesian3(); + /** - * Creates a typed view of an array of bytes. - * - * @param {ComponentDatatype} componentDatatype The type of the view to create. - * @param {ArrayBuffer} buffer The buffer storage to use for the view. - * @param {Number} [byteOffset] The offset, in bytes, to the first element in the view. - * @param {Number} [length] The number of elements in the view. - * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array view of the buffer. + * Extracts the non-uniform scale assuming the matrix is an affine transformation. * - * @exception {DeveloperError} componentDatatype is not a valid value. + * @param {Matrix4} matrix The matrix. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter */ - ComponentDatatype.createArrayBufferView = function(componentDatatype, buffer, byteOffset, length) { - if (!defined(componentDatatype)) { - throw new DeveloperError('componentDatatype is required.'); - } - if (!defined(buffer)) { - throw new DeveloperError('buffer is required.'); - } + Matrix4.getScale = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - byteOffset = defaultValue(byteOffset, 0); - length = defaultValue(length, (buffer.byteLength - byteOffset) / ComponentDatatype.getSizeInBytes(componentDatatype)); - - switch (componentDatatype) { - case ComponentDatatype.BYTE: - return new Int8Array(buffer, byteOffset, length); - case ComponentDatatype.UNSIGNED_BYTE: - return new Uint8Array(buffer, byteOffset, length); - case ComponentDatatype.SHORT: - return new Int16Array(buffer, byteOffset, length); - case ComponentDatatype.UNSIGNED_SHORT: - return new Uint16Array(buffer, byteOffset, length); - case ComponentDatatype.INT: - return new Int32Array(buffer, byteOffset, length); - case ComponentDatatype.UNSIGNED_INT: - return new Uint32Array(buffer, byteOffset, length); - case ComponentDatatype.FLOAT: - return new Float32Array(buffer, byteOffset, length); - case ComponentDatatype.DOUBLE: - return new Float64Array(buffer, byteOffset, length); - default: - throw new DeveloperError('componentDatatype is not a valid value.'); - } + result.x = Cartesian3.magnitude(Cartesian3.fromElements(matrix[0], matrix[1], matrix[2], scratchColumn)); + result.y = Cartesian3.magnitude(Cartesian3.fromElements(matrix[4], matrix[5], matrix[6], scratchColumn)); + result.z = Cartesian3.magnitude(Cartesian3.fromElements(matrix[8], matrix[9], matrix[10], scratchColumn)); + return result; }; + var scratchScale = new Cartesian3(); + /** - * Get the ComponentDatatype from its name. - * - * @param {String} name The name of the ComponentDatatype. - * @returns {ComponentDatatype} The ComponentDatatype. + * Computes the maximum scale assuming the matrix is an affine transformation. + * The maximum scale is the maximum length of the column vectors in the upper-left + * 3x3 matrix. * - * @exception {DeveloperError} name is not a valid value. + * @param {Matrix4} matrix The matrix. + * @returns {Number} The maximum scale. */ - ComponentDatatype.fromName = function(name) { - switch (name) { - case 'BYTE': - return ComponentDatatype.BYTE; - case 'UNSIGNED_BYTE': - return ComponentDatatype.UNSIGNED_BYTE; - case 'SHORT': - return ComponentDatatype.SHORT; - case 'UNSIGNED_SHORT': - return ComponentDatatype.UNSIGNED_SHORT; - case 'INT': - return ComponentDatatype.INT; - case 'UNSIGNED_INT': - return ComponentDatatype.UNSIGNED_INT; - case 'FLOAT': - return ComponentDatatype.FLOAT; - case 'DOUBLE': - return ComponentDatatype.DOUBLE; - default: - throw new DeveloperError('name is not a valid value.'); - } + Matrix4.getMaximumScale = function(matrix) { + Matrix4.getScale(matrix, scratchScale); + return Cartesian3.maximumComponent(scratchScale); }; - return freezeObject(ComponentDatatype); -}); - -define('Core/GeometryType',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; - /** - * @private + * Computes the product of two matrices. + * + * @param {Matrix4} left The first matrix. + * @param {Matrix4} right The second matrix. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. */ - var GeometryType = { - NONE : 0, - TRIANGLES : 1, - LINES : 2, - POLYLINES : 3 - }; - - return freezeObject(GeometryType); -}); - -define('Core/PrimitiveType',[ - './freezeObject', - './WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; - - /** - * The type of a geometric primitive, i.e., points, lines, and triangles. - * - * @exports PrimitiveType - */ - var PrimitiveType = { - /** - * Points primitive where each vertex (or index) is a separate point. - * - * @type {Number} - * @constant - */ - POINTS : WebGLConstants.POINTS, - - /** - * Lines primitive where each two vertices (or indices) is a line segment. Line segments are not necessarily connected. - * - * @type {Number} - * @constant - */ - LINES : WebGLConstants.LINES, + Matrix4.multiply = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + var left0 = left[0]; + var left1 = left[1]; + var left2 = left[2]; + var left3 = left[3]; + var left4 = left[4]; + var left5 = left[5]; + var left6 = left[6]; + var left7 = left[7]; + var left8 = left[8]; + var left9 = left[9]; + var left10 = left[10]; + var left11 = left[11]; + var left12 = left[12]; + var left13 = left[13]; + var left14 = left[14]; + var left15 = left[15]; - /** - * Line loop primitive where each vertex (or index) after the first connects a line to - * the previous vertex, and the last vertex implicitly connects to the first. - * - * @type {Number} - * @constant - */ - LINE_LOOP : WebGLConstants.LINE_LOOP, + var right0 = right[0]; + var right1 = right[1]; + var right2 = right[2]; + var right3 = right[3]; + var right4 = right[4]; + var right5 = right[5]; + var right6 = right[6]; + var right7 = right[7]; + var right8 = right[8]; + var right9 = right[9]; + var right10 = right[10]; + var right11 = right[11]; + var right12 = right[12]; + var right13 = right[13]; + var right14 = right[14]; + var right15 = right[15]; - /** - * Line strip primitive where each vertex (or index) after the first connects a line to the previous vertex. - * - * @type {Number} - * @constant - */ - LINE_STRIP : WebGLConstants.LINE_STRIP, + var column0Row0 = left0 * right0 + left4 * right1 + left8 * right2 + left12 * right3; + var column0Row1 = left1 * right0 + left5 * right1 + left9 * right2 + left13 * right3; + var column0Row2 = left2 * right0 + left6 * right1 + left10 * right2 + left14 * right3; + var column0Row3 = left3 * right0 + left7 * right1 + left11 * right2 + left15 * right3; - /** - * Triangles primitive where each three vertices (or indices) is a triangle. Triangles do not necessarily share edges. - * - * @type {Number} - * @constant - */ - TRIANGLES : WebGLConstants.TRIANGLES, + var column1Row0 = left0 * right4 + left4 * right5 + left8 * right6 + left12 * right7; + var column1Row1 = left1 * right4 + left5 * right5 + left9 * right6 + left13 * right7; + var column1Row2 = left2 * right4 + left6 * right5 + left10 * right6 + left14 * right7; + var column1Row3 = left3 * right4 + left7 * right5 + left11 * right6 + left15 * right7; - /** - * Triangle strip primitive where each vertex (or index) after the first two connect to - * the previous two vertices forming a triangle. For example, this can be used to model a wall. - * - * @type {Number} - * @constant - */ - TRIANGLE_STRIP : WebGLConstants.TRIANGLE_STRIP, + var column2Row0 = left0 * right8 + left4 * right9 + left8 * right10 + left12 * right11; + var column2Row1 = left1 * right8 + left5 * right9 + left9 * right10 + left13 * right11; + var column2Row2 = left2 * right8 + left6 * right9 + left10 * right10 + left14 * right11; + var column2Row3 = left3 * right8 + left7 * right9 + left11 * right10 + left15 * right11; - /** - * Triangle fan primitive where each vertex (or index) after the first two connect to - * the previous vertex and the first vertex forming a triangle. For example, this can be used - * to model a cone or circle. - * - * @type {Number} - * @constant - */ - TRIANGLE_FAN : WebGLConstants.TRIANGLE_FAN, + var column3Row0 = left0 * right12 + left4 * right13 + left8 * right14 + left12 * right15; + var column3Row1 = left1 * right12 + left5 * right13 + left9 * right14 + left13 * right15; + var column3Row2 = left2 * right12 + left6 * right13 + left10 * right14 + left14 * right15; + var column3Row3 = left3 * right12 + left7 * right13 + left11 * right14 + left15 * right15; - /** - * @private - */ - validate : function(primitiveType) { - return primitiveType === PrimitiveType.POINTS || - primitiveType === PrimitiveType.LINES || - primitiveType === PrimitiveType.LINE_LOOP || - primitiveType === PrimitiveType.LINE_STRIP || - primitiveType === PrimitiveType.TRIANGLES || - primitiveType === PrimitiveType.TRIANGLE_STRIP || - primitiveType === PrimitiveType.TRIANGLE_FAN; - } + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = column0Row3; + result[4] = column1Row0; + result[5] = column1Row1; + result[6] = column1Row2; + result[7] = column1Row3; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = column2Row3; + result[12] = column3Row0; + result[13] = column3Row1; + result[14] = column3Row2; + result[15] = column3Row3; + return result; }; - return freezeObject(PrimitiveType); -}); - -define('Core/Geometry',[ - './Check', - './defaultValue', - './defined', - './DeveloperError', - './GeometryType', - './PrimitiveType' - ], function( - Check, - defaultValue, - defined, - DeveloperError, - GeometryType, - PrimitiveType) { - 'use strict'; - /** - * A geometry representation with attributes forming vertices and optional index data - * defining primitives. Geometries and an {@link Appearance}, which describes the shading, - * can be assigned to a {@link Primitive} for visualization. A <code>Primitive</code> can - * be created from many heterogeneous - in many cases - geometries for performance. - * <p> - * Geometries can be transformed and optimized using functions in {@link GeometryPipeline}. - * </p> - * - * @alias Geometry - * @constructor + * Computes the sum of two matrices. * - * @param {Object} options Object with the following properties: - * @param {GeometryAttributes} options.attributes Attributes, which make up the geometry's vertices. - * @param {PrimitiveType} [options.primitiveType=PrimitiveType.TRIANGLES] The type of primitives in the geometry. - * @param {Uint16Array|Uint32Array} [options.indices] Optional index data that determines the primitives in the geometry. - * @param {BoundingSphere} [options.boundingSphere] An optional bounding sphere that fully enclosed the geometry. + * @param {Matrix4} left The first matrix. + * @param {Matrix4} right The second matrix. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. + */ + Matrix4.add = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result[0] = left[0] + right[0]; + result[1] = left[1] + right[1]; + result[2] = left[2] + right[2]; + result[3] = left[3] + right[3]; + result[4] = left[4] + right[4]; + result[5] = left[5] + right[5]; + result[6] = left[6] + right[6]; + result[7] = left[7] + right[7]; + result[8] = left[8] + right[8]; + result[9] = left[9] + right[9]; + result[10] = left[10] + right[10]; + result[11] = left[11] + right[11]; + result[12] = left[12] + right[12]; + result[13] = left[13] + right[13]; + result[14] = left[14] + right[14]; + result[15] = left[15] + right[15]; + return result; + }; + + /** + * Computes the difference of two matrices. * - * @see PolygonGeometry - * @see RectangleGeometry - * @see EllipseGeometry - * @see CircleGeometry - * @see WallGeometry - * @see SimplePolylineGeometry - * @see BoxGeometry - * @see EllipsoidGeometry + * @param {Matrix4} left The first matrix. + * @param {Matrix4} right The second matrix. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. + */ + Matrix4.subtract = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result[0] = left[0] - right[0]; + result[1] = left[1] - right[1]; + result[2] = left[2] - right[2]; + result[3] = left[3] - right[3]; + result[4] = left[4] - right[4]; + result[5] = left[5] - right[5]; + result[6] = left[6] - right[6]; + result[7] = left[7] - right[7]; + result[8] = left[8] - right[8]; + result[9] = left[9] - right[9]; + result[10] = left[10] - right[10]; + result[11] = left[11] - right[11]; + result[12] = left[12] - right[12]; + result[13] = left[13] - right[13]; + result[14] = left[14] - right[14]; + result[15] = left[15] - right[15]; + return result; + }; + + /** + * Computes the product of two matrices assuming the matrices are + * affine transformation matrices, where the upper left 3x3 elements + * are a rotation matrix, and the upper three elements in the fourth + * column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. + * The matrix is not verified to be in the proper form. + * This method is faster than computing the product for general 4x4 + * matrices using {@link Matrix4.multiply}. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @param {Matrix4} left The first matrix. + * @param {Matrix4} right The second matrix. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * * @example - * // Create geometry with a position attribute and indexed lines. - * var positions = new Float64Array([ - * 0.0, 0.0, 0.0, - * 7500000.0, 0.0, 0.0, - * 0.0, 7500000.0, 0.0 - * ]); - * - * var geometry = new Cesium.Geometry({ - * attributes : { - * position : new Cesium.GeometryAttribute({ - * componentDatatype : Cesium.ComponentDatatype.DOUBLE, - * componentsPerAttribute : 3, - * values : positions - * }) - * }, - * indices : new Uint16Array([0, 1, 1, 2, 2, 0]), - * primitiveType : Cesium.PrimitiveType.LINES, - * boundingSphere : Cesium.BoundingSphere.fromVertices(positions) - * }); + * var m1 = new Cesium.Matrix4(1.0, 6.0, 7.0, 0.0, 2.0, 5.0, 8.0, 0.0, 3.0, 4.0, 9.0, 0.0, 0.0, 0.0, 0.0, 1.0); + * var m2 = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(1.0, 1.0, 1.0)); + * var m3 = Cesium.Matrix4.multiplyTransformation(m1, m2, new Cesium.Matrix4()); */ - function Geometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - Check.typeOf.object('options.attributes', options.attributes); + Matrix4.multiplyTransformation = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); - /** - * Attributes, which make up the geometry's vertices. Each property in this object corresponds to a - * {@link GeometryAttribute} containing the attribute's data. - * <p> - * Attributes are always stored non-interleaved in a Geometry. - * </p> - * <p> - * There are reserved attribute names with well-known semantics. The following attributes - * are created by a Geometry (depending on the provided {@link VertexFormat}. - * <ul> - * <li><code>position</code> - 3D vertex position. 64-bit floating-point (for precision). 3 components per attribute. See {@link VertexFormat#position}.</li> - * <li><code>normal</code> - Normal (normalized), commonly used for lighting. 32-bit floating-point. 3 components per attribute. See {@link VertexFormat#normal}.</li> - * <li><code>st</code> - 2D texture coordinate. 32-bit floating-point. 2 components per attribute. See {@link VertexFormat#st}.</li> - * <li><code>bitangent</code> - Bitangent (normalized), used for tangent-space effects like bump mapping. 32-bit floating-point. 3 components per attribute. See {@link VertexFormat#bitangent}.</li> - * <li><code>tangent</code> - Tangent (normalized), used for tangent-space effects like bump mapping. 32-bit floating-point. 3 components per attribute. See {@link VertexFormat#tangent}.</li> - * </ul> - * </p> - * <p> - * The following attribute names are generally not created by a Geometry, but are added - * to a Geometry by a {@link Primitive} or {@link GeometryPipeline} functions to prepare - * the geometry for rendering. - * <ul> - * <li><code>position3DHigh</code> - High 32 bits for encoded 64-bit position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> - * <li><code>position3DLow</code> - Low 32 bits for encoded 64-bit position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> - * <li><code>position3DHigh</code> - High 32 bits for encoded 64-bit 2D (Columbus view) position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> - * <li><code>position2DLow</code> - Low 32 bits for encoded 64-bit 2D (Columbus view) position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> - * <li><code>color</code> - RGBA color (normalized) usually from {@link GeometryInstance#color}. 32-bit floating-point. 4 components per attribute.</li> - * <li><code>pickColor</code> - RGBA color used for picking. 32-bit floating-point. 4 components per attribute.</li> - * </ul> - * </p> - * - * @type GeometryAttributes - * - * @default undefined - * - * - * @example - * geometry.attributes.position = new Cesium.GeometryAttribute({ - * componentDatatype : Cesium.ComponentDatatype.FLOAT, - * componentsPerAttribute : 3, - * values : new Float32Array(0) - * }); - * - * @see GeometryAttribute - * @see VertexFormat - */ - this.attributes = options.attributes; + var left0 = left[0]; + var left1 = left[1]; + var left2 = left[2]; + var left4 = left[4]; + var left5 = left[5]; + var left6 = left[6]; + var left8 = left[8]; + var left9 = left[9]; + var left10 = left[10]; + var left12 = left[12]; + var left13 = left[13]; + var left14 = left[14]; - /** - * Optional index data that - along with {@link Geometry#primitiveType} - - * determines the primitives in the geometry. - * - * @type Array - * - * @default undefined - */ - this.indices = options.indices; + var right0 = right[0]; + var right1 = right[1]; + var right2 = right[2]; + var right4 = right[4]; + var right5 = right[5]; + var right6 = right[6]; + var right8 = right[8]; + var right9 = right[9]; + var right10 = right[10]; + var right12 = right[12]; + var right13 = right[13]; + var right14 = right[14]; - /** - * The type of primitives in the geometry. This is most often {@link PrimitiveType.TRIANGLES}, - * but can varying based on the specific geometry. - * - * @type PrimitiveType - * - * @default undefined - */ - this.primitiveType = defaultValue(options.primitiveType, PrimitiveType.TRIANGLES); + var column0Row0 = left0 * right0 + left4 * right1 + left8 * right2; + var column0Row1 = left1 * right0 + left5 * right1 + left9 * right2; + var column0Row2 = left2 * right0 + left6 * right1 + left10 * right2; - /** - * An optional bounding sphere that fully encloses the geometry. This is - * commonly used for culling. - * - * @type BoundingSphere - * - * @default undefined - */ - this.boundingSphere = options.boundingSphere; + var column1Row0 = left0 * right4 + left4 * right5 + left8 * right6; + var column1Row1 = left1 * right4 + left5 * right5 + left9 * right6; + var column1Row2 = left2 * right4 + left6 * right5 + left10 * right6; - /** - * @private - */ - this.geometryType = defaultValue(options.geometryType, GeometryType.NONE); + var column2Row0 = left0 * right8 + left4 * right9 + left8 * right10; + var column2Row1 = left1 * right8 + left5 * right9 + left9 * right10; + var column2Row2 = left2 * right8 + left6 * right9 + left10 * right10; - /** - * @private - */ - this.boundingSphereCV = options.boundingSphereCV; - } + var column3Row0 = left0 * right12 + left4 * right13 + left8 * right14 + left12; + var column3Row1 = left1 * right12 + left5 * right13 + left9 * right14 + left13; + var column3Row2 = left2 * right12 + left6 * right13 + left10 * right14 + left14; + + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = 0.0; + result[4] = column1Row0; + result[5] = column1Row1; + result[6] = column1Row2; + result[7] = 0.0; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = 0.0; + result[12] = column3Row0; + result[13] = column3Row1; + result[14] = column3Row2; + result[15] = 1.0; + return result; + }; /** - * Computes the number of vertices in a geometry. The runtime is linear with - * respect to the number of attributes in a vertex, not the number of vertices. + * Multiplies a transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) + * by a 3x3 rotation matrix. This is an optimization + * for <code>Matrix4.multiply(m, Matrix4.fromRotationTranslation(rotation), m);</code> with less allocations and arithmetic operations. * - * @param {Geometry} geometry The geometry. - * @returns {Number} The number of vertices in the geometry. + * @param {Matrix4} matrix The matrix on the left-hand side. + * @param {Matrix3} rotation The 3x3 rotation matrix on the right-hand side. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * * @example - * var numVertices = Cesium.Geometry.computeNumberOfVertices(geometry); + * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromRotationTranslation(rotation), m); + * Cesium.Matrix4.multiplyByMatrix3(m, rotation, m); */ - Geometry.computeNumberOfVertices = function(geometry) { - Check.typeOf.object('geometry', geometry); + Matrix4.multiplyByMatrix3 = function(matrix, rotation, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('rotation', rotation); + Check.typeOf.object('result', result); - var numberOfVertices = -1; - for ( var property in geometry.attributes) { - if (geometry.attributes.hasOwnProperty(property) && - defined(geometry.attributes[property]) && - defined(geometry.attributes[property].values)) { + var left0 = matrix[0]; + var left1 = matrix[1]; + var left2 = matrix[2]; + var left4 = matrix[4]; + var left5 = matrix[5]; + var left6 = matrix[6]; + var left8 = matrix[8]; + var left9 = matrix[9]; + var left10 = matrix[10]; - var attribute = geometry.attributes[property]; - var num = attribute.values.length / attribute.componentsPerAttribute; - if ((numberOfVertices !== num) && (numberOfVertices !== -1)) { - throw new DeveloperError('All attribute lists must have the same number of attributes.'); - } - numberOfVertices = num; - } - } + var right0 = rotation[0]; + var right1 = rotation[1]; + var right2 = rotation[2]; + var right4 = rotation[3]; + var right5 = rotation[4]; + var right6 = rotation[5]; + var right8 = rotation[6]; + var right9 = rotation[7]; + var right10 = rotation[8]; - return numberOfVertices; - }; + var column0Row0 = left0 * right0 + left4 * right1 + left8 * right2; + var column0Row1 = left1 * right0 + left5 * right1 + left9 * right2; + var column0Row2 = left2 * right0 + left6 * right1 + left10 * right2; - return Geometry; -}); + var column1Row0 = left0 * right4 + left4 * right5 + left8 * right6; + var column1Row1 = left1 * right4 + left5 * right5 + left9 * right6; + var column1Row2 = left2 * right4 + left6 * right5 + left10 * right6; -define('Core/GeometryAttribute',[ - './defaultValue', - './defined', - './DeveloperError' - ], function( - defaultValue, - defined, - DeveloperError) { - 'use strict'; + var column2Row0 = left0 * right8 + left4 * right9 + left8 * right10; + var column2Row1 = left1 * right8 + left5 * right9 + left9 * right10; + var column2Row2 = left2 * right8 + left6 * right9 + left10 * right10; + + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = 0.0; + result[4] = column1Row0; + result[5] = column1Row1; + result[6] = column1Row2; + result[7] = 0.0; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = 0.0; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + }; /** - * Values and type information for geometry attributes. A {@link Geometry} - * generally contains one or more attributes. All attributes together form - * the geometry's vertices. - * - * @alias GeometryAttribute - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {ComponentDatatype} [options.componentDatatype] The datatype of each component in the attribute, e.g., individual elements in values. - * @param {Number} [options.componentsPerAttribute] A number between 1 and 4 that defines the number of components in an attributes. - * @param {Boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * @param {TypedArray} [options.values] The values for the attributes stored in a typed array. - * - * @exception {DeveloperError} options.componentsPerAttribute must be between 1 and 4. + * Multiplies a transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) + * by an implicit translation matrix defined by a {@link Cartesian3}. This is an optimization + * for <code>Matrix4.multiply(m, Matrix4.fromTranslation(position), m);</code> with less allocations and arithmetic operations. * + * @param {Matrix4} matrix The matrix on the left-hand side. + * @param {Cartesian3} translation The translation on the right-hand side. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * * @example - * var geometry = new Cesium.Geometry({ - * attributes : { - * position : new Cesium.GeometryAttribute({ - * componentDatatype : Cesium.ComponentDatatype.FLOAT, - * componentsPerAttribute : 3, - * values : new Float32Array([ - * 0.0, 0.0, 0.0, - * 7500000.0, 0.0, 0.0, - * 0.0, 7500000.0, 0.0 - * ]) - * }) - * }, - * primitiveType : Cesium.PrimitiveType.LINE_LOOP - * }); - * - * @see Geometry + * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromTranslation(position), m); + * Cesium.Matrix4.multiplyByTranslation(m, position, m); */ - function GeometryAttribute(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (!defined(options.componentDatatype)) { - throw new DeveloperError('options.componentDatatype is required.'); - } - if (!defined(options.componentsPerAttribute)) { - throw new DeveloperError('options.componentsPerAttribute is required.'); - } - if (options.componentsPerAttribute < 1 || options.componentsPerAttribute > 4) { - throw new DeveloperError('options.componentsPerAttribute must be between 1 and 4.'); - } - if (!defined(options.values)) { - throw new DeveloperError('options.values is required.'); - } + Matrix4.multiplyByTranslation = function(matrix, translation, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('translation', translation); + Check.typeOf.object('result', result); - /** - * The datatype of each component in the attribute, e.g., individual elements in - * {@link GeometryAttribute#values}. - * - * @type ComponentDatatype - * - * @default undefined - */ - this.componentDatatype = options.componentDatatype; - - /** - * A number between 1 and 4 that defines the number of components in an attributes. - * For example, a position attribute with x, y, and z components would have 3 as - * shown in the code example. - * - * @type Number - * - * @default undefined - * - * @example - * attribute.componentDatatype = Cesium.ComponentDatatype.FLOAT; - * attribute.componentsPerAttribute = 3; - * attribute.values = new Float32Array([ - * 0.0, 0.0, 0.0, - * 7500000.0, 0.0, 0.0, - * 0.0, 7500000.0, 0.0 - * ]); - */ - this.componentsPerAttribute = options.componentsPerAttribute; - - /** - * When <code>true</code> and <code>componentDatatype</code> is an integer format, - * indicate that the components should be mapped to the range [0, 1] (unsigned) - * or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * <p> - * This is commonly used when storing colors using {@link ComponentDatatype.UNSIGNED_BYTE}. - * </p> - * - * @type Boolean - * - * @default false - * - * @example - * attribute.componentDatatype = Cesium.ComponentDatatype.UNSIGNED_BYTE; - * attribute.componentsPerAttribute = 4; - * attribute.normalize = true; - * attribute.values = new Uint8Array([ - * Cesium.Color.floatToByte(color.red), - * Cesium.Color.floatToByte(color.green), - * Cesium.Color.floatToByte(color.blue), - * Cesium.Color.floatToByte(color.alpha) - * ]); - */ - this.normalize = defaultValue(options.normalize, false); + var x = translation.x; + var y = translation.y; + var z = translation.z; - /** - * The values for the attributes stored in a typed array. In the code example, - * every three elements in <code>values</code> defines one attributes since - * <code>componentsPerAttribute</code> is 3. - * - * @type TypedArray - * - * @default undefined - * - * @example - * attribute.componentDatatype = Cesium.ComponentDatatype.FLOAT; - * attribute.componentsPerAttribute = 3; - * attribute.values = new Float32Array([ - * 0.0, 0.0, 0.0, - * 7500000.0, 0.0, 0.0, - * 0.0, 7500000.0, 0.0 - * ]); - */ - this.values = options.values; - } + var tx = (x * matrix[0]) + (y * matrix[4]) + (z * matrix[8]) + matrix[12]; + var ty = (x * matrix[1]) + (y * matrix[5]) + (z * matrix[9]) + matrix[13]; + var tz = (x * matrix[2]) + (y * matrix[6]) + (z * matrix[10]) + matrix[14]; - return GeometryAttribute; -}); + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = tx; + result[13] = ty; + result[14] = tz; + result[15] = matrix[15]; + return result; + }; -define('Core/GeometryAttributes',[ - './defaultValue' - ], function( - defaultValue) { - 'use strict'; + var uniformScaleScratch = new Cartesian3(); /** - * Attributes, which make up a geometry's vertices. Each property in this object corresponds to a - * {@link GeometryAttribute} containing the attribute's data. - * <p> - * Attributes are always stored non-interleaved in a Geometry. - * </p> + * Multiplies an affine transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) + * by an implicit uniform scale matrix. This is an optimization + * for <code>Matrix4.multiply(m, Matrix4.fromUniformScale(scale), m);</code>, where + * <code>m</code> must be an affine matrix. + * This function performs fewer allocations and arithmetic operations. * - * @alias GeometryAttributes - * @constructor + * @param {Matrix4} matrix The affine matrix on the left-hand side. + * @param {Number} scale The uniform scale on the right-hand side. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. + * + * + * @example + * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromUniformScale(scale), m); + * Cesium.Matrix4.multiplyByUniformScale(m, scale, m); + * + * @see Matrix4.fromUniformScale + * @see Matrix4.multiplyByScale */ - function GeometryAttributes(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * The 3D position attribute. - * <p> - * 64-bit floating-point (for precision). 3 components per attribute. - * </p> - * - * @type GeometryAttribute - * - * @default undefined - */ - this.position = options.position; - - /** - * The normal attribute (normalized), which is commonly used for lighting. - * <p> - * 32-bit floating-point. 3 components per attribute. - * </p> - * - * @type GeometryAttribute - * - * @default undefined - */ - this.normal = options.normal; - - /** - * The 2D texture coordinate attribute. - * <p> - * 32-bit floating-point. 2 components per attribute - * </p> - * - * @type GeometryAttribute - * - * @default undefined - */ - this.st = options.st; - - /** - * The bitangent attribute (normalized), which is used for tangent-space effects like bump mapping. - * <p> - * 32-bit floating-point. 3 components per attribute. - * </p> - * - * @type GeometryAttribute - * - * @default undefined - */ - this.bitangent = options.bitangent; - - /** - * The tangent attribute (normalized), which is used for tangent-space effects like bump mapping. - * <p> - * 32-bit floating-point. 3 components per attribute. - * </p> - * - * @type GeometryAttribute - * - * @default undefined - */ - this.tangent = options.tangent; - - /** - * The color attribute. - * <p> - * 8-bit unsigned integer. 4 components per attribute. - * </p> - * - * @type GeometryAttribute - * - * @default undefined - */ - this.color = options.color; - } - - return GeometryAttributes; -}); - -define('Core/VertexFormat',[ - './defaultValue', - './defined', - './DeveloperError', - './freezeObject' - ], function( - defaultValue, - defined, - DeveloperError, - freezeObject) { - 'use strict'; + Matrix4.multiplyByUniformScale = function(matrix, scale, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.number('scale', scale); + Check.typeOf.object('result', result); + + uniformScaleScratch.x = scale; + uniformScaleScratch.y = scale; + uniformScaleScratch.z = scale; + return Matrix4.multiplyByScale(matrix, uniformScaleScratch, result); + }; /** - * A vertex format defines what attributes make up a vertex. A VertexFormat can be provided - * to a {@link Geometry} to request that certain properties be computed, e.g., just position, - * position and normal, etc. + * Multiplies an affine transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>) + * by an implicit non-uniform scale matrix. This is an optimization + * for <code>Matrix4.multiply(m, Matrix4.fromUniformScale(scale), m);</code>, where + * <code>m</code> must be an affine matrix. + * This function performs fewer allocations and arithmetic operations. * - * @param {Object} [options] An object with boolean properties corresponding to VertexFormat properties as shown in the code example. + * @param {Matrix4} matrix The affine matrix on the left-hand side. + * @param {Cartesian3} scale The non-uniform scale on the right-hand side. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * - * @alias VertexFormat - * @constructor * * @example - * // Create a vertex format with position and 2D texture coordinate attributes. - * var format = new Cesium.VertexFormat({ - * position : true, - * st : true - * }); + * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromScale(scale), m); + * Cesium.Matrix4.multiplyByScale(m, scale, m); * - * @see Geometry#attributes - * @see Packable + * @see Matrix4.fromScale + * @see Matrix4.multiplyByUniformScale */ - function VertexFormat(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * When <code>true</code>, the vertex has a 3D position attribute. - * <p> - * 64-bit floating-point (for precision). 3 components per attribute. - * </p> - * - * @type Boolean - * - * @default false - */ - this.position = defaultValue(options.position, false); + Matrix4.multiplyByScale = function(matrix, scale, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('scale', scale); + Check.typeOf.object('result', result); + + var scaleX = scale.x; + var scaleY = scale.y; + var scaleZ = scale.z; - /** - * When <code>true</code>, the vertex has a normal attribute (normalized), which is commonly used for lighting. - * <p> - * 32-bit floating-point. 3 components per attribute. - * </p> - * - * @type Boolean - * - * @default false - */ - this.normal = defaultValue(options.normal, false); + // Faster than Cartesian3.equals + if ((scaleX === 1.0) && (scaleY === 1.0) && (scaleZ === 1.0)) { + return Matrix4.clone(matrix, result); + } - /** - * When <code>true</code>, the vertex has a 2D texture coordinate attribute. - * <p> - * 32-bit floating-point. 2 components per attribute - * </p> - * - * @type Boolean - * - * @default false - */ - this.st = defaultValue(options.st, false); + result[0] = scaleX * matrix[0]; + result[1] = scaleX * matrix[1]; + result[2] = scaleX * matrix[2]; + result[3] = 0.0; + result[4] = scaleY * matrix[4]; + result[5] = scaleY * matrix[5]; + result[6] = scaleY * matrix[6]; + result[7] = 0.0; + result[8] = scaleZ * matrix[8]; + result[9] = scaleZ * matrix[9]; + result[10] = scaleZ * matrix[10]; + result[11] = 0.0; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = 1.0; + return result; + }; - /** - * When <code>true</code>, the vertex has a bitangent attribute (normalized), which is used for tangent-space effects like bump mapping. - * <p> - * 32-bit floating-point. 3 components per attribute. - * </p> - * - * @type Boolean - * - * @default false - */ - this.bitangent = defaultValue(options.bitangent, false); + /** + * Computes the product of a matrix and a column vector. + * + * @param {Matrix4} matrix The matrix. + * @param {Cartesian4} cartesian The vector. + * @param {Cartesian4} result The object onto which to store the result. + * @returns {Cartesian4} The modified result parameter. + */ + Matrix4.multiplyByVector = function(matrix, cartesian, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var vX = cartesian.x; + var vY = cartesian.y; + var vZ = cartesian.z; + var vW = cartesian.w; - /** - * When <code>true</code>, the vertex has a tangent attribute (normalized), which is used for tangent-space effects like bump mapping. - * <p> - * 32-bit floating-point. 3 components per attribute. - * </p> - * - * @type Boolean - * - * @default false - */ - this.tangent = defaultValue(options.tangent, false); + var x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12] * vW; + var y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13] * vW; + var z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14] * vW; + var w = matrix[3] * vX + matrix[7] * vY + matrix[11] * vZ + matrix[15] * vW; - /** - * When <code>true</code>, the vertex has an RGB color attribute. - * <p> - * 8-bit unsigned byte. 3 components per attribute. - * </p> - * - * @type Boolean - * - * @default false - */ - this.color = defaultValue(options.color, false); - } + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + }; /** - * An immutable vertex format with only a position attribute. + * Computes the product of a matrix and a {@link Cartesian3}. This is equivalent to calling {@link Matrix4.multiplyByVector} + * with a {@link Cartesian4} with a <code>w</code> component of zero. * - * @type {VertexFormat} - * @constant + * @param {Matrix4} matrix The matrix. + * @param {Cartesian3} cartesian The point. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. * - * @see VertexFormat#position + * @example + * var p = new Cesium.Cartesian3(1.0, 2.0, 3.0); + * var result = Cesium.Matrix4.multiplyByPointAsVector(matrix, p, new Cesium.Cartesian3()); + * // A shortcut for + * // Cartesian3 p = ... + * // Cesium.Matrix4.multiplyByVector(matrix, new Cesium.Cartesian4(p.x, p.y, p.z, 0.0), result); */ - VertexFormat.POSITION_ONLY = freezeObject(new VertexFormat({ - position : true - })); + Matrix4.multiplyByPointAsVector = function(matrix, cartesian, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var vX = cartesian.x; + var vY = cartesian.y; + var vZ = cartesian.z; + + var x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ; + var y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ; + var z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ; + + result.x = x; + result.y = y; + result.z = z; + return result; + }; /** - * An immutable vertex format with position and normal attributes. - * This is compatible with per-instance color appearances like {@link PerInstanceColorAppearance}. + * Computes the product of a matrix and a {@link Cartesian3}. This is equivalent to calling {@link Matrix4.multiplyByVector} + * with a {@link Cartesian4} with a <code>w</code> component of 1, but returns a {@link Cartesian3} instead of a {@link Cartesian4}. * - * @type {VertexFormat} - * @constant + * @param {Matrix4} matrix The matrix. + * @param {Cartesian3} cartesian The point. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. * - * @see VertexFormat#position - * @see VertexFormat#normal + * @example + * var p = new Cesium.Cartesian3(1.0, 2.0, 3.0); + * var result = Cesium.Matrix4.multiplyByPoint(matrix, p, new Cesium.Cartesian3()); */ - VertexFormat.POSITION_AND_NORMAL = freezeObject(new VertexFormat({ - position : true, - normal : true - })); - - /** - * An immutable vertex format with position, normal, and st attributes. - * This is compatible with {@link MaterialAppearance} when {@link MaterialAppearance#materialSupport} - * is <code>TEXTURED/code>. - * - * @type {VertexFormat} - * @constant - * - * @see VertexFormat#position - * @see VertexFormat#normal - * @see VertexFormat#st - */ - VertexFormat.POSITION_NORMAL_AND_ST = freezeObject(new VertexFormat({ - position : true, - normal : true, - st : true - })); + Matrix4.multiplyByPoint = function(matrix, cartesian, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var vX = cartesian.x; + var vY = cartesian.y; + var vZ = cartesian.z; - /** - * An immutable vertex format with position and st attributes. - * This is compatible with {@link EllipsoidSurfaceAppearance}. - * - * @type {VertexFormat} - * @constant - * - * @see VertexFormat#position - * @see VertexFormat#st - */ - VertexFormat.POSITION_AND_ST = freezeObject(new VertexFormat({ - position : true, - st : true - })); + var x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12]; + var y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13]; + var z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14]; + + result.x = x; + result.y = y; + result.z = z; + return result; + }; /** - * An immutable vertex format with position and color attributes. + * Computes the product of a matrix and a scalar. * - * @type {VertexFormat} - * @constant + * @param {Matrix4} matrix The matrix. + * @param {Number} scalar The number to multiply by. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * - * @see VertexFormat#position - * @see VertexFormat#color - */ - VertexFormat.POSITION_AND_COLOR = freezeObject(new VertexFormat({ - position : true, - color : true - })); - - /** - * An immutable vertex format with well-known attributes: position, normal, st, tangent, and bitangent. + * @example + * //create a Matrix4 instance which is a scaled version of the supplied Matrix4 + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] * - * @type {VertexFormat} - * @constant + * var a = Cesium.Matrix4.multiplyByScalar(m, -2, new Cesium.Matrix4()); * - * @see VertexFormat#position - * @see VertexFormat#normal - * @see VertexFormat#st - * @see VertexFormat#tangent - * @see VertexFormat#bitangent + * // m remains the same + * // a = [-20.0, -22.0, -24.0, -26.0] + * // [-28.0, -30.0, -32.0, -34.0] + * // [-36.0, -38.0, -40.0, -42.0] + * // [-44.0, -46.0, -48.0, -50.0] */ - VertexFormat.ALL = freezeObject(new VertexFormat({ - position : true, - normal : true, - st : true, - tangent : true, - bitangent : true - })); + Matrix4.multiplyByScalar = function(matrix, scalar, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result[0] = matrix[0] * scalar; + result[1] = matrix[1] * scalar; + result[2] = matrix[2] * scalar; + result[3] = matrix[3] * scalar; + result[4] = matrix[4] * scalar; + result[5] = matrix[5] * scalar; + result[6] = matrix[6] * scalar; + result[7] = matrix[7] * scalar; + result[8] = matrix[8] * scalar; + result[9] = matrix[9] * scalar; + result[10] = matrix[10] * scalar; + result[11] = matrix[11] * scalar; + result[12] = matrix[12] * scalar; + result[13] = matrix[13] * scalar; + result[14] = matrix[14] * scalar; + result[15] = matrix[15] * scalar; + return result; + }; /** - * An immutable vertex format with position, normal, and st attributes. - * This is compatible with most appearances and materials; however - * normal and st attributes are not always required. When this is - * known in advance, another <code>VertexFormat</code> should be used. + * Computes a negated copy of the provided matrix. * - * @type {VertexFormat} - * @constant + * @param {Matrix4} matrix The matrix to negate. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. * - * @see VertexFormat#position - * @see VertexFormat#normal - */ - VertexFormat.DEFAULT = VertexFormat.POSITION_NORMAL_AND_ST; - - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - VertexFormat.packedLength = 6; - - /** - * Stores the provided instance into the provided array. + * @example + * //create a new Matrix4 instance which is a negation of a Matrix4 + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] * - * @param {VertexFormat} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * var a = Cesium.Matrix4.negate(m, new Cesium.Matrix4()); * - * @returns {Number[]} The array that was packed into + * // m remains the same + * // a = [-10.0, -11.0, -12.0, -13.0] + * // [-14.0, -15.0, -16.0, -17.0] + * // [-18.0, -19.0, -20.0, -21.0] + * // [-22.0, -23.0, -24.0, -25.0] */ - VertexFormat.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); - } + Matrix4.negate = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - startingIndex = defaultValue(startingIndex, 0); - - array[startingIndex++] = value.position ? 1.0 : 0.0; - array[startingIndex++] = value.normal ? 1.0 : 0.0; - array[startingIndex++] = value.st ? 1.0 : 0.0; - array[startingIndex++] = value.tangent ? 1.0 : 0.0; - array[startingIndex++] = value.bitangent ? 1.0 : 0.0; - array[startingIndex] = value.color ? 1.0 : 0.0; - - return array; + result[0] = -matrix[0]; + result[1] = -matrix[1]; + result[2] = -matrix[2]; + result[3] = -matrix[3]; + result[4] = -matrix[4]; + result[5] = -matrix[5]; + result[6] = -matrix[6]; + result[7] = -matrix[7]; + result[8] = -matrix[8]; + result[9] = -matrix[9]; + result[10] = -matrix[10]; + result[11] = -matrix[11]; + result[12] = -matrix[12]; + result[13] = -matrix[13]; + result[14] = -matrix[14]; + result[15] = -matrix[15]; + return result; }; /** - * Retrieves an instance from a packed array. + * Computes the transpose of the provided matrix. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {VertexFormat} [result] The object into which to store the result. - * @returns {VertexFormat} The modified result parameter or a new VertexFormat instance if one was not provided. + * @param {Matrix4} matrix The matrix to transpose. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. + * + * @example + * //returns transpose of a Matrix4 + * // m = [10.0, 11.0, 12.0, 13.0] + * // [14.0, 15.0, 16.0, 17.0] + * // [18.0, 19.0, 20.0, 21.0] + * // [22.0, 23.0, 24.0, 25.0] + * + * var a = Cesium.Matrix4.transpose(m, new Cesium.Matrix4()); + * + * // m remains the same + * // a = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] */ - VertexFormat.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); - } + Matrix4.transpose = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - startingIndex = defaultValue(startingIndex, 0); - - if (!defined(result)) { - result = new VertexFormat(); - } + var matrix1 = matrix[1]; + var matrix2 = matrix[2]; + var matrix3 = matrix[3]; + var matrix6 = matrix[6]; + var matrix7 = matrix[7]; + var matrix11 = matrix[11]; - result.position = array[startingIndex++] === 1.0; - result.normal = array[startingIndex++] === 1.0; - result.st = array[startingIndex++] === 1.0; - result.tangent = array[startingIndex++] === 1.0; - result.bitangent = array[startingIndex++] === 1.0; - result.color = array[startingIndex] === 1.0; + result[0] = matrix[0]; + result[1] = matrix[4]; + result[2] = matrix[8]; + result[3] = matrix[12]; + result[4] = matrix1; + result[5] = matrix[5]; + result[6] = matrix[9]; + result[7] = matrix[13]; + result[8] = matrix2; + result[9] = matrix6; + result[10] = matrix[10]; + result[11] = matrix[14]; + result[12] = matrix3; + result[13] = matrix7; + result[14] = matrix11; + result[15] = matrix[15]; return result; }; /** - * Duplicates a VertexFormat instance. + * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements. * - * @param {VertexFormat} vertexFormat The vertex format to duplicate. - * @param {VertexFormat} [result] The object onto which to store the result. - * @returns {VertexFormat} The modified result parameter or a new VertexFormat instance if one was not provided. (Returns undefined if vertexFormat is undefined) + * @param {Matrix4} matrix The matrix with signed elements. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. */ - VertexFormat.clone = function(vertexFormat, result) { - if (!defined(vertexFormat)) { - return undefined; - } - if (!defined(result)) { - result = new VertexFormat(); - } + Matrix4.abs = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); + + result[0] = Math.abs(matrix[0]); + result[1] = Math.abs(matrix[1]); + result[2] = Math.abs(matrix[2]); + result[3] = Math.abs(matrix[3]); + result[4] = Math.abs(matrix[4]); + result[5] = Math.abs(matrix[5]); + result[6] = Math.abs(matrix[6]); + result[7] = Math.abs(matrix[7]); + result[8] = Math.abs(matrix[8]); + result[9] = Math.abs(matrix[9]); + result[10] = Math.abs(matrix[10]); + result[11] = Math.abs(matrix[11]); + result[12] = Math.abs(matrix[12]); + result[13] = Math.abs(matrix[13]); + result[14] = Math.abs(matrix[14]); + result[15] = Math.abs(matrix[15]); - result.position = vertexFormat.position; - result.normal = vertexFormat.normal; - result.st = vertexFormat.st; - result.tangent = vertexFormat.tangent; - result.bitangent = vertexFormat.bitangent; - result.color = vertexFormat.color; return result; }; - return VertexFormat; -}); - -define('Core/BoxGeometry',[ - './BoundingSphere', - './Cartesian3', - './Check', - './ComponentDatatype', - './defaultValue', - './defined', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './PrimitiveType', - './VertexFormat' - ], function( - BoundingSphere, - Cartesian3, - Check, - ComponentDatatype, - defaultValue, - defined, - Geometry, - GeometryAttribute, - GeometryAttributes, - PrimitiveType, - VertexFormat) { - 'use strict'; - - var diffScratch = new Cartesian3(); - /** - * Describes a cube centered at the origin. + * Compares the provided matrices componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @alias BoxGeometry - * @constructor + * @param {Matrix4} [left] The first matrix. + * @param {Matrix4} [right] The second matrix. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.minimum The minimum x, y, and z coordinates of the box. - * @param {Cartesian3} options.maximum The maximum x, y, and z coordinates of the box. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @example + * //compares two Matrix4 instances * - * @see BoxGeometry.fromDimensions - * @see BoxGeometry.createGeometry - * @see Packable + * // a = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo} + * // b = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] * - * @example - * var box = new Cesium.BoxGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, - * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0), - * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0) - * }); - * var geometry = Cesium.BoxGeometry.createGeometry(box); + * if(Cesium.Matrix4.equals(a,b)) { + * console.log("Both matrices are equal"); + * } else { + * console.log("They are not equal"); + * } + * + * //Prints "Both matrices are equal" on the console */ - function BoxGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var min = options.minimum; - var max = options.maximum; + Matrix4.equals = function(left, right) { + // Given that most matrices will be transformation matrices, the elements + // are tested in order such that the test is likely to fail as early + // as possible. I _think_ this is just as friendly to the L1 cache + // as testing in index order. It is certainty faster in practice. + return (left === right) || + (defined(left) && + defined(right) && + // Translation + left[12] === right[12] && + left[13] === right[13] && + left[14] === right[14] && - Check.typeOf.object('min', min); - Check.typeOf.object('max', max); - - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + // Rotation/scale + left[0] === right[0] && + left[1] === right[1] && + left[2] === right[2] && + left[4] === right[4] && + left[5] === right[5] && + left[6] === right[6] && + left[8] === right[8] && + left[9] === right[9] && + left[10] === right[10] && - this._minimum = Cartesian3.clone(min); - this._maximum = Cartesian3.clone(max); - this._vertexFormat = vertexFormat; - this._workerName = 'createBoxGeometry'; - } + // Bottom row + left[3] === right[3] && + left[7] === right[7] && + left[11] === right[11] && + left[15] === right[15]); + }; /** - * Creates a cube centered at the origin given its dimensions. + * Compares the provided matrices componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.dimensions The width, depth, and height of the box stored in the x, y, and z coordinates of the <code>Cartesian3</code>, respectively. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @returns {BoxGeometry} + * @param {Matrix4} [left] The first matrix. + * @param {Matrix4} [right] The second matrix. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. * - * @exception {DeveloperError} All dimensions components must be greater than or equal to zero. + * @example + * //compares two Matrix4 instances * + * // a = [10.5, 14.5, 18.5, 22.5] + * // [11.5, 15.5, 19.5, 23.5] + * // [12.5, 16.5, 20.5, 24.5] + * // [13.5, 17.5, 21.5, 25.5] * - * @example - * var box = Cesium.BoxGeometry.fromDimensions({ - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, - * dimensions : new Cesium.Cartesian3(500000.0, 500000.0, 500000.0) - * }); - * var geometry = Cesium.BoxGeometry.createGeometry(box); + * // b = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] * - * @see BoxGeometry.createGeometry + * if(Cesium.Matrix4.equalsEpsilon(a,b,0.1)){ + * console.log("Difference between both the matrices is less than 0.1"); + * } else { + * console.log("Difference between both the matrices is not less than 0.1"); + * } + * + * //Prints "Difference between both the matrices is not less than 0.1" on the console */ - BoxGeometry.fromDimensions = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var dimensions = options.dimensions; - - Check.typeOf.object('dimensions', dimensions); - Check.typeOf.number.greaterThanOrEquals('dimensions.x', dimensions.x, 0); - Check.typeOf.number.greaterThanOrEquals('dimensions.y', dimensions.y, 0); - Check.typeOf.number.greaterThanOrEquals('dimensions.z', dimensions.z, 0); + Matrix4.equalsEpsilon = function(left, right, epsilon) { + Check.typeOf.number('epsilon', epsilon); - var corner = Cartesian3.multiplyByScalar(dimensions, 0.5, new Cartesian3()); + return (left === right) || + (defined(left) && + defined(right) && + Math.abs(left[0] - right[0]) <= epsilon && + Math.abs(left[1] - right[1]) <= epsilon && + Math.abs(left[2] - right[2]) <= epsilon && + Math.abs(left[3] - right[3]) <= epsilon && + Math.abs(left[4] - right[4]) <= epsilon && + Math.abs(left[5] - right[5]) <= epsilon && + Math.abs(left[6] - right[6]) <= epsilon && + Math.abs(left[7] - right[7]) <= epsilon && + Math.abs(left[8] - right[8]) <= epsilon && + Math.abs(left[9] - right[9]) <= epsilon && + Math.abs(left[10] - right[10]) <= epsilon && + Math.abs(left[11] - right[11]) <= epsilon && + Math.abs(left[12] - right[12]) <= epsilon && + Math.abs(left[13] - right[13]) <= epsilon && + Math.abs(left[14] - right[14]) <= epsilon && + Math.abs(left[15] - right[15]) <= epsilon); + }; - return new BoxGeometry({ - minimum : Cartesian3.negate(corner, new Cartesian3()), - maximum : corner, - vertexFormat : options.vertexFormat - }); + /** + * Gets the translation portion of the provided matrix, assuming the matrix is a affine transformation matrix. + * + * @param {Matrix4} matrix The matrix to use. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. + */ + Matrix4.getTranslation = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); + + result.x = matrix[12]; + result.y = matrix[13]; + result.z = matrix[14]; + return result; }; /** - * Creates a cube from the dimensions of an AxisAlignedBoundingBox. + * Gets the upper left 3x3 rotation matrix of the provided matrix, assuming the matrix is a affine transformation matrix. * - * @param {AxisAlignedBoundingBox} boundingBox A description of the AxisAlignedBoundingBox. - * @returns {BoxGeometry} + * @param {Matrix4} matrix The matrix to use. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix3} The modified result parameter. * + * @example + * // returns a Matrix3 instance from a Matrix4 instance * + * // m = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] * - * @example - * var aabb = Cesium.AxisAlignedBoundingBox.fromPoints(Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ])); - * var box = Cesium.BoxGeometry.fromAxisAlignedBoundingBox(aabb); + * var b = new Cesium.Matrix3(); + * Cesium.Matrix4.getRotation(m,b); * - * @see BoxGeometry.createGeometry + * // b = [10.0, 14.0, 18.0] + * // [11.0, 15.0, 19.0] + * // [12.0, 16.0, 20.0] */ - BoxGeometry.fromAxisAlignedBoundingBox = function (boundingBox) { - Check.typeOf.object('boundingBox', boundingBox); + Matrix4.getRotation = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - return new BoxGeometry({ - minimum : boundingBox.minimum, - maximum : boundingBox.maximum - }); + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[4]; + result[4] = matrix[5]; + result[5] = matrix[6]; + result[6] = matrix[8]; + result[7] = matrix[9]; + result[8] = matrix[10]; + return result; }; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - BoxGeometry.packedLength = 2 * Cartesian3.packedLength + VertexFormat.packedLength; + var scratchInverseRotation = new Matrix3(); + var scratchMatrix3Zero = new Matrix3(); + var scratchBottomRow = new Cartesian4(); + var scratchExpectedBottomRow = new Cartesian4(0.0, 0.0, 0.0, 1.0); - /** - * Stores the provided instance into the provided array. - * - * @param {BoxGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - BoxGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + /** + * Computes the inverse of the provided matrix using Cramers Rule. + * If the determinant is zero, the matrix can not be inverted, and an exception is thrown. + * If the matrix is an affine transformation matrix, it is more efficient + * to invert it with {@link Matrix4.inverseTransformation}. + * + * @param {Matrix4} matrix The matrix to invert. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. + * + * @exception {RuntimeError} matrix is not invertible because its determinate is zero. + */ + Matrix4.inverse = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - startingIndex = defaultValue(startingIndex, 0); + // Special case for a zero scale matrix that can occur, for example, + // when a model's node has a [0, 0, 0] scale. + if (Matrix3.equalsEpsilon(Matrix4.getRotation(matrix, scratchInverseRotation), scratchMatrix3Zero, CesiumMath.EPSILON7) && + Cartesian4.equals(Matrix4.getRow(matrix, 3, scratchBottomRow), scratchExpectedBottomRow)) { - Cartesian3.pack(value._minimum, array, startingIndex); - Cartesian3.pack(value._maximum, array, startingIndex + Cartesian3.packedLength); - VertexFormat.pack(value._vertexFormat, array, startingIndex + 2 * Cartesian3.packedLength); + result[0] = 0.0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = 0.0; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = 0.0; + result[11] = 0.0; + result[12] = -matrix[12]; + result[13] = -matrix[13]; + result[14] = -matrix[14]; + result[15] = 1.0; + return result; + } - return array; - }; + // + // Ported from: + // ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf + // + var src0 = matrix[0]; + var src1 = matrix[4]; + var src2 = matrix[8]; + var src3 = matrix[12]; + var src4 = matrix[1]; + var src5 = matrix[5]; + var src6 = matrix[9]; + var src7 = matrix[13]; + var src8 = matrix[2]; + var src9 = matrix[6]; + var src10 = matrix[10]; + var src11 = matrix[14]; + var src12 = matrix[3]; + var src13 = matrix[7]; + var src14 = matrix[11]; + var src15 = matrix[15]; - var scratchMin = new Cartesian3(); - var scratchMax = new Cartesian3(); - var scratchVertexFormat = new VertexFormat(); - var scratchOptions = { - minimum: scratchMin, - maximum: scratchMax, - vertexFormat: scratchVertexFormat + // calculate pairs for first 8 elements (cofactors) + var tmp0 = src10 * src15; + var tmp1 = src11 * src14; + var tmp2 = src9 * src15; + var tmp3 = src11 * src13; + var tmp4 = src9 * src14; + var tmp5 = src10 * src13; + var tmp6 = src8 * src15; + var tmp7 = src11 * src12; + var tmp8 = src8 * src14; + var tmp9 = src10 * src12; + var tmp10 = src8 * src13; + var tmp11 = src9 * src12; + + // calculate first 8 elements (cofactors) + var dst0 = (tmp0 * src5 + tmp3 * src6 + tmp4 * src7) - (tmp1 * src5 + tmp2 * src6 + tmp5 * src7); + var dst1 = (tmp1 * src4 + tmp6 * src6 + tmp9 * src7) - (tmp0 * src4 + tmp7 * src6 + tmp8 * src7); + var dst2 = (tmp2 * src4 + tmp7 * src5 + tmp10 * src7) - (tmp3 * src4 + tmp6 * src5 + tmp11 * src7); + var dst3 = (tmp5 * src4 + tmp8 * src5 + tmp11 * src6) - (tmp4 * src4 + tmp9 * src5 + tmp10 * src6); + var dst4 = (tmp1 * src1 + tmp2 * src2 + tmp5 * src3) - (tmp0 * src1 + tmp3 * src2 + tmp4 * src3); + var dst5 = (tmp0 * src0 + tmp7 * src2 + tmp8 * src3) - (tmp1 * src0 + tmp6 * src2 + tmp9 * src3); + var dst6 = (tmp3 * src0 + tmp6 * src1 + tmp11 * src3) - (tmp2 * src0 + tmp7 * src1 + tmp10 * src3); + var dst7 = (tmp4 * src0 + tmp9 * src1 + tmp10 * src2) - (tmp5 * src0 + tmp8 * src1 + tmp11 * src2); + + // calculate pairs for second 8 elements (cofactors) + tmp0 = src2 * src7; + tmp1 = src3 * src6; + tmp2 = src1 * src7; + tmp3 = src3 * src5; + tmp4 = src1 * src6; + tmp5 = src2 * src5; + tmp6 = src0 * src7; + tmp7 = src3 * src4; + tmp8 = src0 * src6; + tmp9 = src2 * src4; + tmp10 = src0 * src5; + tmp11 = src1 * src4; + + // calculate second 8 elements (cofactors) + var dst8 = (tmp0 * src13 + tmp3 * src14 + tmp4 * src15) - (tmp1 * src13 + tmp2 * src14 + tmp5 * src15); + var dst9 = (tmp1 * src12 + tmp6 * src14 + tmp9 * src15) - (tmp0 * src12 + tmp7 * src14 + tmp8 * src15); + var dst10 = (tmp2 * src12 + tmp7 * src13 + tmp10 * src15) - (tmp3 * src12 + tmp6 * src13 + tmp11 * src15); + var dst11 = (tmp5 * src12 + tmp8 * src13 + tmp11 * src14) - (tmp4 * src12 + tmp9 * src13 + tmp10 * src14); + var dst12 = (tmp2 * src10 + tmp5 * src11 + tmp1 * src9) - (tmp4 * src11 + tmp0 * src9 + tmp3 * src10); + var dst13 = (tmp8 * src11 + tmp0 * src8 + tmp7 * src10) - (tmp6 * src10 + tmp9 * src11 + tmp1 * src8); + var dst14 = (tmp6 * src9 + tmp11 * src11 + tmp3 * src8) - (tmp10 * src11 + tmp2 * src8 + tmp7 * src9); + var dst15 = (tmp10 * src10 + tmp4 * src8 + tmp9 * src9) - (tmp8 * src9 + tmp11 * src10 + tmp5 * src8); + + // calculate determinant + var det = src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3; + + if (Math.abs(det) < CesiumMath.EPSILON20) { + throw new RuntimeError('matrix is not invertible because its determinate is zero.'); + } + + // calculate matrix inverse + det = 1.0 / det; + + result[0] = dst0 * det; + result[1] = dst1 * det; + result[2] = dst2 * det; + result[3] = dst3 * det; + result[4] = dst4 * det; + result[5] = dst5 * det; + result[6] = dst6 * det; + result[7] = dst7 * det; + result[8] = dst8 * det; + result[9] = dst9 * det; + result[10] = dst10 * det; + result[11] = dst11 * det; + result[12] = dst12 * det; + result[13] = dst13 * det; + result[14] = dst14 * det; + result[15] = dst15 * det; + return result; }; /** - * Retrieves an instance from a packed array. + * Computes the inverse of the provided matrix assuming it is + * an affine transformation matrix, where the upper left 3x3 elements + * are a rotation matrix, and the upper three elements in the fourth + * column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. + * The matrix is not verified to be in the proper form. + * This method is faster than computing the inverse for a general 4x4 + * matrix using {@link Matrix4.inverse}. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {BoxGeometry} [result] The object into which to store the result. - * @returns {BoxGeometry} The modified result parameter or a new BoxGeometry instance if one was not provided. + * @param {Matrix4} matrix The matrix to invert. + * @param {Matrix4} result The object onto which to store the result. + * @returns {Matrix4} The modified result parameter. */ - BoxGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); + Matrix4.inverseTransformation = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - startingIndex = defaultValue(startingIndex, 0); + //This function is an optimized version of the below 4 lines. + //var rT = Matrix3.transpose(Matrix4.getRotation(matrix)); + //var rTN = Matrix3.negate(rT); + //var rTT = Matrix3.multiplyByVector(rTN, Matrix4.getTranslation(matrix)); + //return Matrix4.fromRotationTranslation(rT, rTT, result); - var min = Cartesian3.unpack(array, startingIndex, scratchMin); - var max = Cartesian3.unpack(array, startingIndex + Cartesian3.packedLength, scratchMax); - var vertexFormat = VertexFormat.unpack(array, startingIndex + 2 * Cartesian3.packedLength, scratchVertexFormat); + var matrix0 = matrix[0]; + var matrix1 = matrix[1]; + var matrix2 = matrix[2]; + var matrix4 = matrix[4]; + var matrix5 = matrix[5]; + var matrix6 = matrix[6]; + var matrix8 = matrix[8]; + var matrix9 = matrix[9]; + var matrix10 = matrix[10]; - if (!defined(result)) { - return new BoxGeometry(scratchOptions); - } + var vX = matrix[12]; + var vY = matrix[13]; + var vZ = matrix[14]; - result._minimum = Cartesian3.clone(min, result._minimum); - result._maximum = Cartesian3.clone(max, result._maximum); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + var x = -matrix0 * vX - matrix1 * vY - matrix2 * vZ; + var y = -matrix4 * vX - matrix5 * vY - matrix6 * vZ; + var z = -matrix8 * vX - matrix9 * vY - matrix10 * vZ; + result[0] = matrix0; + result[1] = matrix4; + result[2] = matrix8; + result[3] = 0.0; + result[4] = matrix1; + result[5] = matrix5; + result[6] = matrix9; + result[7] = 0.0; + result[8] = matrix2; + result[9] = matrix6; + result[10] = matrix10; + result[11] = 0.0; + result[12] = x; + result[13] = y; + result[14] = z; + result[15] = 1.0; return result; }; /** - * Computes the geometric representation of a box, including its vertices, indices, and a bounding sphere. + * An immutable Matrix4 instance initialized to the identity matrix. * - * @param {BoxGeometry} boxGeometry A description of the box. - * @returns {Geometry|undefined} The computed vertices and indices. + * @type {Matrix4} + * @constant */ - BoxGeometry.createGeometry = function(boxGeometry) { - var min = boxGeometry._minimum; - var max = boxGeometry._maximum; - var vertexFormat = boxGeometry._vertexFormat; - - if (Cartesian3.equals(min, max)) { - return; - } + Matrix4.IDENTITY = freezeObject(new Matrix4(1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0)); - var attributes = new GeometryAttributes(); - var indices; - var positions; + /** + * An immutable Matrix4 instance initialized to the zero matrix. + * + * @type {Matrix4} + * @constant + */ + Matrix4.ZERO = freezeObject(new Matrix4(0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0)); - if (vertexFormat.position && - (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent)) { - if (vertexFormat.position) { - // 8 corner points. Duplicated 3 times each for each incident edge/face. - positions = new Float64Array(6 * 4 * 3); + /** + * The index into Matrix4 for column 0, row 0. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN0ROW0 = 0; - // +z face - positions[0] = min.x; - positions[1] = min.y; - positions[2] = max.z; - positions[3] = max.x; - positions[4] = min.y; - positions[5] = max.z; - positions[6] = max.x; - positions[7] = max.y; - positions[8] = max.z; - positions[9] = min.x; - positions[10] = max.y; - positions[11] = max.z; + /** + * The index into Matrix4 for column 0, row 1. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN0ROW1 = 1; - // -z face - positions[12] = min.x; - positions[13] = min.y; - positions[14] = min.z; - positions[15] = max.x; - positions[16] = min.y; - positions[17] = min.z; - positions[18] = max.x; - positions[19] = max.y; - positions[20] = min.z; - positions[21] = min.x; - positions[22] = max.y; - positions[23] = min.z; + /** + * The index into Matrix4 for column 0, row 2. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN0ROW2 = 2; - // +x face - positions[24] = max.x; - positions[25] = min.y; - positions[26] = min.z; - positions[27] = max.x; - positions[28] = max.y; - positions[29] = min.z; - positions[30] = max.x; - positions[31] = max.y; - positions[32] = max.z; - positions[33] = max.x; - positions[34] = min.y; - positions[35] = max.z; + /** + * The index into Matrix4 for column 0, row 3. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN0ROW3 = 3; - // -x face - positions[36] = min.x; - positions[37] = min.y; - positions[38] = min.z; - positions[39] = min.x; - positions[40] = max.y; - positions[41] = min.z; - positions[42] = min.x; - positions[43] = max.y; - positions[44] = max.z; - positions[45] = min.x; - positions[46] = min.y; - positions[47] = max.z; + /** + * The index into Matrix4 for column 1, row 0. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN1ROW0 = 4; - // +y face - positions[48] = min.x; - positions[49] = max.y; - positions[50] = min.z; - positions[51] = max.x; - positions[52] = max.y; - positions[53] = min.z; - positions[54] = max.x; - positions[55] = max.y; - positions[56] = max.z; - positions[57] = min.x; - positions[58] = max.y; - positions[59] = max.z; + /** + * The index into Matrix4 for column 1, row 1. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN1ROW1 = 5; - // -y face - positions[60] = min.x; - positions[61] = min.y; - positions[62] = min.z; - positions[63] = max.x; - positions[64] = min.y; - positions[65] = min.z; - positions[66] = max.x; - positions[67] = min.y; - positions[68] = max.z; - positions[69] = min.x; - positions[70] = min.y; - positions[71] = max.z; + /** + * The index into Matrix4 for column 1, row 2. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN1ROW2 = 6; - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - } + /** + * The index into Matrix4 for column 1, row 3. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN1ROW3 = 7; - if (vertexFormat.normal) { - var normals = new Float32Array(6 * 4 * 3); + /** + * The index into Matrix4 for column 2, row 0. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN2ROW0 = 8; - // +z face - normals[0] = 0.0; - normals[1] = 0.0; - normals[2] = 1.0; - normals[3] = 0.0; - normals[4] = 0.0; - normals[5] = 1.0; - normals[6] = 0.0; - normals[7] = 0.0; - normals[8] = 1.0; - normals[9] = 0.0; - normals[10] = 0.0; - normals[11] = 1.0; + /** + * The index into Matrix4 for column 2, row 1. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN2ROW1 = 9; - // -z face - normals[12] = 0.0; - normals[13] = 0.0; - normals[14] = -1.0; - normals[15] = 0.0; - normals[16] = 0.0; - normals[17] = -1.0; - normals[18] = 0.0; - normals[19] = 0.0; - normals[20] = -1.0; - normals[21] = 0.0; - normals[22] = 0.0; - normals[23] = -1.0; + /** + * The index into Matrix4 for column 2, row 2. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN2ROW2 = 10; - // +x face - normals[24] = 1.0; - normals[25] = 0.0; - normals[26] = 0.0; - normals[27] = 1.0; - normals[28] = 0.0; - normals[29] = 0.0; - normals[30] = 1.0; - normals[31] = 0.0; - normals[32] = 0.0; - normals[33] = 1.0; - normals[34] = 0.0; - normals[35] = 0.0; - - // -x face - normals[36] = -1.0; - normals[37] = 0.0; - normals[38] = 0.0; - normals[39] = -1.0; - normals[40] = 0.0; - normals[41] = 0.0; - normals[42] = -1.0; - normals[43] = 0.0; - normals[44] = 0.0; - normals[45] = -1.0; - normals[46] = 0.0; - normals[47] = 0.0; - - // +y face - normals[48] = 0.0; - normals[49] = 1.0; - normals[50] = 0.0; - normals[51] = 0.0; - normals[52] = 1.0; - normals[53] = 0.0; - normals[54] = 0.0; - normals[55] = 1.0; - normals[56] = 0.0; - normals[57] = 0.0; - normals[58] = 1.0; - normals[59] = 0.0; - - // -y face - normals[60] = 0.0; - normals[61] = -1.0; - normals[62] = 0.0; - normals[63] = 0.0; - normals[64] = -1.0; - normals[65] = 0.0; - normals[66] = 0.0; - normals[67] = -1.0; - normals[68] = 0.0; - normals[69] = 0.0; - normals[70] = -1.0; - normals[71] = 0.0; - - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } - - if (vertexFormat.st) { - var texCoords = new Float32Array(6 * 4 * 2); - - // +z face - texCoords[0] = 0.0; - texCoords[1] = 0.0; - texCoords[2] = 1.0; - texCoords[3] = 0.0; - texCoords[4] = 1.0; - texCoords[5] = 1.0; - texCoords[6] = 0.0; - texCoords[7] = 1.0; - - // -z face - texCoords[8] = 1.0; - texCoords[9] = 0.0; - texCoords[10] = 0.0; - texCoords[11] = 0.0; - texCoords[12] = 0.0; - texCoords[13] = 1.0; - texCoords[14] = 1.0; - texCoords[15] = 1.0; - - //+x face - texCoords[16] = 0.0; - texCoords[17] = 0.0; - texCoords[18] = 1.0; - texCoords[19] = 0.0; - texCoords[20] = 1.0; - texCoords[21] = 1.0; - texCoords[22] = 0.0; - texCoords[23] = 1.0; - - // -x face - texCoords[24] = 1.0; - texCoords[25] = 0.0; - texCoords[26] = 0.0; - texCoords[27] = 0.0; - texCoords[28] = 0.0; - texCoords[29] = 1.0; - texCoords[30] = 1.0; - texCoords[31] = 1.0; - - // +y face - texCoords[32] = 1.0; - texCoords[33] = 0.0; - texCoords[34] = 0.0; - texCoords[35] = 0.0; - texCoords[36] = 0.0; - texCoords[37] = 1.0; - texCoords[38] = 1.0; - texCoords[39] = 1.0; - - // -y face - texCoords[40] = 0.0; - texCoords[41] = 0.0; - texCoords[42] = 1.0; - texCoords[43] = 0.0; - texCoords[44] = 1.0; - texCoords[45] = 1.0; - texCoords[46] = 0.0; - texCoords[47] = 1.0; - - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : texCoords - }); - } - - if (vertexFormat.tangent) { - var tangents = new Float32Array(6 * 4 * 3); - - // +z face - tangents[0] = 1.0; - tangents[1] = 0.0; - tangents[2] = 0.0; - tangents[3] = 1.0; - tangents[4] = 0.0; - tangents[5] = 0.0; - tangents[6] = 1.0; - tangents[7] = 0.0; - tangents[8] = 0.0; - tangents[9] = 1.0; - tangents[10] = 0.0; - tangents[11] = 0.0; - - // -z face - tangents[12] = -1.0; - tangents[13] = 0.0; - tangents[14] = 0.0; - tangents[15] = -1.0; - tangents[16] = 0.0; - tangents[17] = 0.0; - tangents[18] = -1.0; - tangents[19] = 0.0; - tangents[20] = 0.0; - tangents[21] = -1.0; - tangents[22] = 0.0; - tangents[23] = 0.0; - - // +x face - tangents[24] = 0.0; - tangents[25] = 1.0; - tangents[26] = 0.0; - tangents[27] = 0.0; - tangents[28] = 1.0; - tangents[29] = 0.0; - tangents[30] = 0.0; - tangents[31] = 1.0; - tangents[32] = 0.0; - tangents[33] = 0.0; - tangents[34] = 1.0; - tangents[35] = 0.0; - - // -x face - tangents[36] = 0.0; - tangents[37] = -1.0; - tangents[38] = 0.0; - tangents[39] = 0.0; - tangents[40] = -1.0; - tangents[41] = 0.0; - tangents[42] = 0.0; - tangents[43] = -1.0; - tangents[44] = 0.0; - tangents[45] = 0.0; - tangents[46] = -1.0; - tangents[47] = 0.0; - - // +y face - tangents[48] = -1.0; - tangents[49] = 0.0; - tangents[50] = 0.0; - tangents[51] = -1.0; - tangents[52] = 0.0; - tangents[53] = 0.0; - tangents[54] = -1.0; - tangents[55] = 0.0; - tangents[56] = 0.0; - tangents[57] = -1.0; - tangents[58] = 0.0; - tangents[59] = 0.0; - - // -y face - tangents[60] = 1.0; - tangents[61] = 0.0; - tangents[62] = 0.0; - tangents[63] = 1.0; - tangents[64] = 0.0; - tangents[65] = 0.0; - tangents[66] = 1.0; - tangents[67] = 0.0; - tangents[68] = 0.0; - tangents[69] = 1.0; - tangents[70] = 0.0; - tangents[71] = 0.0; - - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); - } - - if (vertexFormat.bitangent) { - var bitangents = new Float32Array(6 * 4 * 3); - - // +z face - bitangents[0] = 0.0; - bitangents[1] = 1.0; - bitangents[2] = 0.0; - bitangents[3] = 0.0; - bitangents[4] = 1.0; - bitangents[5] = 0.0; - bitangents[6] = 0.0; - bitangents[7] = 1.0; - bitangents[8] = 0.0; - bitangents[9] = 0.0; - bitangents[10] = 1.0; - bitangents[11] = 0.0; - - // -z face - bitangents[12] = 0.0; - bitangents[13] = 1.0; - bitangents[14] = 0.0; - bitangents[15] = 0.0; - bitangents[16] = 1.0; - bitangents[17] = 0.0; - bitangents[18] = 0.0; - bitangents[19] = 1.0; - bitangents[20] = 0.0; - bitangents[21] = 0.0; - bitangents[22] = 1.0; - bitangents[23] = 0.0; - - // +x face - bitangents[24] = 0.0; - bitangents[25] = 0.0; - bitangents[26] = 1.0; - bitangents[27] = 0.0; - bitangents[28] = 0.0; - bitangents[29] = 1.0; - bitangents[30] = 0.0; - bitangents[31] = 0.0; - bitangents[32] = 1.0; - bitangents[33] = 0.0; - bitangents[34] = 0.0; - bitangents[35] = 1.0; - - // -x face - bitangents[36] = 0.0; - bitangents[37] = 0.0; - bitangents[38] = 1.0; - bitangents[39] = 0.0; - bitangents[40] = 0.0; - bitangents[41] = 1.0; - bitangents[42] = 0.0; - bitangents[43] = 0.0; - bitangents[44] = 1.0; - bitangents[45] = 0.0; - bitangents[46] = 0.0; - bitangents[47] = 1.0; - - // +y face - bitangents[48] = 0.0; - bitangents[49] = 0.0; - bitangents[50] = 1.0; - bitangents[51] = 0.0; - bitangents[52] = 0.0; - bitangents[53] = 1.0; - bitangents[54] = 0.0; - bitangents[55] = 0.0; - bitangents[56] = 1.0; - bitangents[57] = 0.0; - bitangents[58] = 0.0; - bitangents[59] = 1.0; - - // -y face - bitangents[60] = 0.0; - bitangents[61] = 0.0; - bitangents[62] = 1.0; - bitangents[63] = 0.0; - bitangents[64] = 0.0; - bitangents[65] = 1.0; - bitangents[66] = 0.0; - bitangents[67] = 0.0; - bitangents[68] = 1.0; - bitangents[69] = 0.0; - bitangents[70] = 0.0; - bitangents[71] = 1.0; - - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } - - // 12 triangles: 6 faces, 2 triangles each. - indices = new Uint16Array(6 * 2 * 3); - - // +z face - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 0; - indices[4] = 2; - indices[5] = 3; - - // -z face - indices[6] = 4 + 2; - indices[7] = 4 + 1; - indices[8] = 4 + 0; - indices[9] = 4 + 3; - indices[10] = 4 + 2; - indices[11] = 4 + 0; - - // +x face - indices[12] = 8 + 0; - indices[13] = 8 + 1; - indices[14] = 8 + 2; - indices[15] = 8 + 0; - indices[16] = 8 + 2; - indices[17] = 8 + 3; - - // -x face - indices[18] = 12 + 2; - indices[19] = 12 + 1; - indices[20] = 12 + 0; - indices[21] = 12 + 3; - indices[22] = 12 + 2; - indices[23] = 12 + 0; - - // +y face - indices[24] = 16 + 2; - indices[25] = 16 + 1; - indices[26] = 16 + 0; - indices[27] = 16 + 3; - indices[28] = 16 + 2; - indices[29] = 16 + 0; - - // -y face - indices[30] = 20 + 0; - indices[31] = 20 + 1; - indices[32] = 20 + 2; - indices[33] = 20 + 0; - indices[34] = 20 + 2; - indices[35] = 20 + 3; - } else { - // Positions only - no need to duplicate corner points - positions = new Float64Array(8 * 3); - - positions[0] = min.x; - positions[1] = min.y; - positions[2] = min.z; - positions[3] = max.x; - positions[4] = min.y; - positions[5] = min.z; - positions[6] = max.x; - positions[7] = max.y; - positions[8] = min.z; - positions[9] = min.x; - positions[10] = max.y; - positions[11] = min.z; - positions[12] = min.x; - positions[13] = min.y; - positions[14] = max.z; - positions[15] = max.x; - positions[16] = min.y; - positions[17] = max.z; - positions[18] = max.x; - positions[19] = max.y; - positions[20] = max.z; - positions[21] = min.x; - positions[22] = max.y; - positions[23] = max.z; - - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - - // 12 triangles: 6 faces, 2 triangles each. - indices = new Uint16Array(6 * 2 * 3); - - // plane z = corner.Z - indices[0] = 4; - indices[1] = 5; - indices[2] = 6; - indices[3] = 4; - indices[4] = 6; - indices[5] = 7; - - // plane z = -corner.Z - indices[6] = 1; - indices[7] = 0; - indices[8] = 3; - indices[9] = 1; - indices[10] = 3; - indices[11] = 2; - - // plane x = corner.X - indices[12] = 1; - indices[13] = 6; - indices[14] = 5; - indices[15] = 1; - indices[16] = 2; - indices[17] = 6; - - // plane y = corner.Y - indices[18] = 2; - indices[19] = 3; - indices[20] = 7; - indices[21] = 2; - indices[22] = 7; - indices[23] = 6; - - // plane x = -corner.X - indices[24] = 3; - indices[25] = 0; - indices[26] = 4; - indices[27] = 3; - indices[28] = 4; - indices[29] = 7; - - // plane y = -corner.Y - indices[30] = 0; - indices[31] = 1; - indices[32] = 5; - indices[33] = 0; - indices[34] = 5; - indices[35] = 4; - } - - var diff = Cartesian3.subtract(max, min, diffScratch); - var radius = Cartesian3.magnitude(diff) * 0.5; - - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : new BoundingSphere(Cartesian3.ZERO, radius) - }); - }; - - return BoxGeometry; -}); - -define('Core/BoxOutlineGeometry',[ - './BoundingSphere', - './Cartesian3', - './Check', - './ComponentDatatype', - './defaultValue', - './defined', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './PrimitiveType' - ], function( - BoundingSphere, - Cartesian3, - Check, - ComponentDatatype, - defaultValue, - defined, - Geometry, - GeometryAttribute, - GeometryAttributes, - PrimitiveType) { - 'use strict'; - - var diffScratch = new Cartesian3(); + /** + * The index into Matrix4 for column 2, row 3. + * + * @type {Number} + * @constant + */ + Matrix4.COLUMN2ROW3 = 11; /** - * A description of the outline of a cube centered at the origin. - * - * @alias BoxOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.minimum The minimum x, y, and z coordinates of the box. - * @param {Cartesian3} options.maximum The maximum x, y, and z coordinates of the box. - * - * @see BoxOutlineGeometry.fromDimensions - * @see BoxOutlineGeometry.createGeometry - * @see Packable + * The index into Matrix4 for column 3, row 0. * - * @example - * var box = new Cesium.BoxOutlineGeometry({ - * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0), - * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0) - * }); - * var geometry = Cesium.BoxOutlineGeometry.createGeometry(box); + * @type {Number} + * @constant */ - function BoxOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var min = options.minimum; - var max = options.maximum; - - Check.typeOf.object('min', min); - Check.typeOf.object('max', max); - - this._min = Cartesian3.clone(min); - this._max = Cartesian3.clone(max); - this._workerName = 'createBoxOutlineGeometry'; - } + Matrix4.COLUMN3ROW0 = 12; /** - * Creates an outline of a cube centered at the origin given its dimensions. - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.dimensions The width, depth, and height of the box stored in the x, y, and z coordinates of the <code>Cartesian3</code>, respectively. - * @returns {BoxOutlineGeometry} - * - * @exception {DeveloperError} All dimensions components must be greater than or equal to zero. - * - * - * @example - * var box = Cesium.BoxOutlineGeometry.fromDimensions({ - * dimensions : new Cesium.Cartesian3(500000.0, 500000.0, 500000.0) - * }); - * var geometry = Cesium.BoxOutlineGeometry.createGeometry(box); + * The index into Matrix4 for column 3, row 1. * - * @see BoxOutlineGeometry.createGeometry + * @type {Number} + * @constant */ - BoxOutlineGeometry.fromDimensions = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var dimensions = options.dimensions; - - Check.typeOf.object('dimensions', dimensions); - Check.typeOf.number.greaterThanOrEquals('dimensions.x', dimensions.x, 0); - Check.typeOf.number.greaterThanOrEquals('dimensions.y', dimensions.y, 0); - Check.typeOf.number.greaterThanOrEquals('dimensions.z', dimensions.z, 0); - - var corner = Cartesian3.multiplyByScalar(dimensions, 0.5, new Cartesian3()); - - return new BoxOutlineGeometry({ - minimum : Cartesian3.negate(corner, new Cartesian3()), - maximum : corner - }); - }; + Matrix4.COLUMN3ROW1 = 13; /** - * Creates an outline of a cube from the dimensions of an AxisAlignedBoundingBox. - * - * @param {AxisAlignedBoundingBox} boundingBox A description of the AxisAlignedBoundingBox. - * @returns {BoxOutlineGeometry} - * - * - * - * @example - * var aabb = Cesium.AxisAlignedBoundingBox.fromPoints(Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ])); - * var box = Cesium.BoxOutlineGeometry.fromAxisAlignedBoundingBox(aabb); + * The index into Matrix4 for column 3, row 2. * - * @see BoxOutlineGeometry.createGeometry + * @type {Number} + * @constant */ - BoxOutlineGeometry.fromAxisAlignedBoundingBox = function(boundingBox) { - Check.typeOf.object('boundindBox', boundingBox); - - return new BoxOutlineGeometry({ - minimum : boundingBox.minimum, - maximum : boundingBox.maximum - }); - }; + Matrix4.COLUMN3ROW2 = 14; /** - * The number of elements used to pack the object into an array. + * The index into Matrix4 for column 3, row 3. + * * @type {Number} + * @constant */ - BoxOutlineGeometry.packedLength = 2 * Cartesian3.packedLength; + Matrix4.COLUMN3ROW3 = 15; + + defineProperties(Matrix4.prototype, { + /** + * Gets the number of items in the collection. + * @memberof Matrix4.prototype + * + * @type {Number} + */ + length : { + get : function() { + return Matrix4.packedLength; + } + } + }); /** - * Stores the provided instance into the provided array. - * - * @param {BoxOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * Duplicates the provided Matrix4 instance. * - * @returns {Number[]} The array that was packed into + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. */ - BoxOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + Matrix4.prototype.clone = function(result) { + return Matrix4.clone(this, result); + }; - Cartesian3.pack(value._min, array, startingIndex); - Cartesian3.pack(value._max, array, startingIndex + Cartesian3.packedLength); - return array; + /** + * Compares this matrix to the provided matrix componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Matrix4} [right] The right hand side matrix. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + Matrix4.prototype.equals = function(right) { + return Matrix4.equals(this, right); }; - var scratchMin = new Cartesian3(); - var scratchMax = new Cartesian3(); - var scratchOptions = { - minimum : scratchMin, - maximum : scratchMax + /** + * @private + */ + Matrix4.equalsArray = function(matrix, array, offset) { + return matrix[0] === array[offset] && + matrix[1] === array[offset + 1] && + matrix[2] === array[offset + 2] && + matrix[3] === array[offset + 3] && + matrix[4] === array[offset + 4] && + matrix[5] === array[offset + 5] && + matrix[6] === array[offset + 6] && + matrix[7] === array[offset + 7] && + matrix[8] === array[offset + 8] && + matrix[9] === array[offset + 9] && + matrix[10] === array[offset + 10] && + matrix[11] === array[offset + 11] && + matrix[12] === array[offset + 12] && + matrix[13] === array[offset + 13] && + matrix[14] === array[offset + 14] && + matrix[15] === array[offset + 15]; }; /** - * Retrieves an instance from a packed array. + * Compares this matrix to the provided matrix componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {BoxOutlineGeometry} [result] The object into which to store the result. - * @returns {BoxOutlineGeometry} The modified result parameter or a new BoxOutlineGeometry instance if one was not provided. + * @param {Matrix4} [right] The right hand side matrix. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ - BoxOutlineGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); - - var min = Cartesian3.unpack(array, startingIndex, scratchMin); - var max = Cartesian3.unpack(array, startingIndex + Cartesian3.packedLength, scratchMax); - - if (!defined(result)) { - return new BoxOutlineGeometry(scratchOptions); - } - - result._min = Cartesian3.clone(min, result._min); - result._max = Cartesian3.clone(max, result._max); - - return result; + Matrix4.prototype.equalsEpsilon = function(right, epsilon) { + return Matrix4.equalsEpsilon(this, right, epsilon); }; /** - * Computes the geometric representation of an outline of a box, including its vertices, indices, and a bounding sphere. + * Computes a string representing this Matrix with each row being + * on a separate line and in the format '(column0, column1, column2, column3)'. * - * @param {BoxOutlineGeometry} boxGeometry A description of the box outline. - * @returns {Geometry|undefined} The computed vertices and indices. + * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2, column3)'. */ - BoxOutlineGeometry.createGeometry = function(boxGeometry) { - var min = boxGeometry._min; - var max = boxGeometry._max; - - if (Cartesian3.equals(min, max)) { - return; - } - - var attributes = new GeometryAttributes(); - var indices = new Uint16Array(12 * 2); - var positions = new Float64Array(8 * 3); - - positions[0] = min.x; - positions[1] = min.y; - positions[2] = min.z; - positions[3] = max.x; - positions[4] = min.y; - positions[5] = min.z; - positions[6] = max.x; - positions[7] = max.y; - positions[8] = min.z; - positions[9] = min.x; - positions[10] = max.y; - positions[11] = min.z; - - positions[12] = min.x; - positions[13] = min.y; - positions[14] = max.z; - positions[15] = max.x; - positions[16] = min.y; - positions[17] = max.z; - positions[18] = max.x; - positions[19] = max.y; - positions[20] = max.z; - positions[21] = min.x; - positions[22] = max.y; - positions[23] = max.z; - - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - - // top - indices[0] = 4; - indices[1] = 5; - indices[2] = 5; - indices[3] = 6; - indices[4] = 6; - indices[5] = 7; - indices[6] = 7; - indices[7] = 4; - - // bottom - indices[8] = 0; - indices[9] = 1; - indices[10] = 1; - indices[11] = 2; - indices[12] = 2; - indices[13] = 3; - indices[14] = 3; - indices[15] = 0; - - // left - indices[16] = 0; - indices[17] = 4; - indices[18] = 1; - indices[19] = 5; - - //right - indices[20] = 2; - indices[21] = 6; - indices[22] = 3; - indices[23] = 7; - - var diff = Cartesian3.subtract(max, min, diffScratch); - var radius = Cartesian3.magnitude(diff) * 0.5; - - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : new BoundingSphere(Cartesian3.ZERO, radius) - }); + Matrix4.prototype.toString = function() { + return '(' + this[0] + ', ' + this[4] + ', ' + this[8] + ', ' + this[12] +')\n' + + '(' + this[1] + ', ' + this[5] + ', ' + this[9] + ', ' + this[13] +')\n' + + '(' + this[2] + ', ' + this[6] + ', ' + this[10] + ', ' + this[14] +')\n' + + '(' + this[3] + ', ' + this[7] + ', ' + this[11] + ', ' + this[15] +')'; }; - return BoxOutlineGeometry; + return Matrix4; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', +define('Core/BoundingSphere',[ + './Cartesian3', + './Cartographic', + './Math', + './Check', './defaultValue', './defined', - './DeveloperError' + './Ellipsoid', + './GeographicProjection', + './Intersect', + './Interval', + './Matrix3', + './Matrix4', + './Rectangle' ], function( - Uri, + Cartesian3, + Cartographic, + CesiumMath, + Check, defaultValue, defined, - DeveloperError) { + Ellipsoid, + GeographicProjection, + Intersect, + Interval, + Matrix3, + Matrix4, + Rectangle) { 'use strict'; /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri + * A bounding sphere with a center and a radius. + * @alias BoundingSphere + * @constructor * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. + * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere. + * @param {Number} [radius=0.0] The radius of the bounding sphere. * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); + * @see AxisAlignedBoundingBox + * @see BoundingRectangle + * @see Packable */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } + function BoundingSphere(center, radius) { + /** + * The center point of the sphere. + * @type {Cartesian3} + * @default {@link Cartesian3.ZERO} + */ + this.center = Cartesian3.clone(defaultValue(center, Cartesian3.ZERO)); - return getAbsoluteUri; -}); + /** + * The radius of the sphere. + * @type {Number} + * @default 0.0 + */ + this.radius = defaultValue(radius, 0.0); + } -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; + var fromPointsXMin = new Cartesian3(); + var fromPointsYMin = new Cartesian3(); + var fromPointsZMin = new Cartesian3(); + var fromPointsXMax = new Cartesian3(); + var fromPointsYMax = new Cartesian3(); + var fromPointsZMax = new Cartesian3(); + var fromPointsCurrentPos = new Cartesian3(); + var fromPointsScratch = new Cartesian3(); + var fromPointsRitterCenter = new Cartesian3(); + var fromPointsMinBoxPt = new Cartesian3(); + var fromPointsMaxBoxPt = new Cartesian3(); + var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. + * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. + * The bounding sphere is computed by running two algorithms, a naive algorithm and + * Ritter's algorithm. The smaller of the two spheres is used to ensure a tight fit. * - * @return {String} The combined url - * @private + * @param {Cartesian3[]} [positions] An array of points that the bounding sphere will enclose. Each point must have <code>x</code>, <code>y</code>, and <code>z</code> properties. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + * + * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article} */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); + BoundingSphere.fromPoints = function(positions, result) { + if (!defined(result)) { + result = new BoundingSphere(); } - - appendSlash = defaultValue(appendSlash, true); - if (!(first instanceof Uri)) { - first = new Uri(first); + if (!defined(positions) || positions.length === 0) { + result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = 0.0; + return result; } - if (!(second instanceof Uri)) { - second = new Uri(second); - } + var currentPos = Cartesian3.clone(positions[0], fromPointsCurrentPos); - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } + var xMin = Cartesian3.clone(currentPos, fromPointsXMin); + var yMin = Cartesian3.clone(currentPos, fromPointsYMin); + var zMin = Cartesian3.clone(currentPos, fromPointsZMin); - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } + var xMax = Cartesian3.clone(currentPos, fromPointsXMax); + var yMax = Cartesian3.clone(currentPos, fromPointsYMax); + var zMax = Cartesian3.clone(currentPos, fromPointsZMax); - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } + var numPositions = positions.length; + var i; + for (i = 1; i < numPositions; i++) { + Cartesian3.clone(positions[i], currentPos); - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } + var x = currentPos.x; + var y = currentPos.y; + var z = currentPos.z; - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; + // Store points containing the the smallest and largest components + if (x < xMin.x) { + Cartesian3.clone(currentPos, xMin); + } - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); + if (x > xMax.x) { + Cartesian3.clone(currentPos, xMax); + } - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } + if (y < yMin.y) { + Cartesian3.clone(currentPos, yMin); } - } - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; + if (y > yMax.y) { + Cartesian3.clone(currentPos, yMax); } - } else { - url += second.path; - } - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } + if (z < zMin.z) { + Cartesian3.clone(currentPos, zMin); + } - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; + if (z > zMax.z) { + Cartesian3.clone(currentPos, zMax); + } } - return url; - } - - return joinUrls; -}); - -define('Core/buildModuleUrl',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError', - './getAbsoluteUri', - './joinUrls', - 'require' - ], function( - Uri, - defined, - DeveloperError, - getAbsoluteUri, - joinUrls, - require) { - 'use strict'; - /*global CESIUM_BASE_URL*/ + // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). + var xSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(xMax, xMin, fromPointsScratch)); + var ySpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(yMax, yMin, fromPointsScratch)); + var zSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(zMax, zMin, fromPointsScratch)); - var cesiumScriptRegex = /((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i; - function getBaseUrlFromCesiumScript() { - var scripts = document.getElementsByTagName('script'); - for ( var i = 0, len = scripts.length; i < len; ++i) { - var src = scripts[i].getAttribute('src'); - var result = cesiumScriptRegex.exec(src); - if (result !== null) { - return result[1]; - } + // Set the diameter endpoints to the largest span. + var diameter1 = xMin; + var diameter2 = xMax; + var maxSpan = xSpan; + if (ySpan > maxSpan) { + maxSpan = ySpan; + diameter1 = yMin; + diameter2 = yMax; } - return undefined; - } - - var baseUrl; - function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (zSpan > maxSpan) { + maxSpan = zSpan; + diameter1 = zMin; + diameter2 = zMax; } - var baseUrlString; - if (typeof CESIUM_BASE_URL !== 'undefined') { - baseUrlString = CESIUM_BASE_URL; - } else { - baseUrlString = getBaseUrlFromCesiumScript(); - } + // Calculate the center of the initial sphere found by Ritter's algorithm + var ritterCenter = fromPointsRitterCenter; + ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; + ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; + ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; - if (!defined(baseUrlString)) { - throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); - } - - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + // Calculate the radius of the initial sphere found by Ritter's algorithm + var radiusSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)); + var ritterRadius = Math.sqrt(radiusSquared); - return baseUrl; - } + // Find the center of the sphere found using the Naive method. + var minBoxPt = fromPointsMinBoxPt; + minBoxPt.x = xMin.x; + minBoxPt.y = yMin.y; + minBoxPt.z = zMin.z; - function buildModuleUrlFromRequireToUrl(moduleID) { - //moduleID will be non-relative, so require it relative to this module, in Core. - return require.toUrl('../' + moduleID); - } + var maxBoxPt = fromPointsMaxBoxPt; + maxBoxPt.x = xMax.x; + maxBoxPt.y = yMax.y; + maxBoxPt.z = zMax.z; - function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); - } + var naiveCenter = Cartesian3.multiplyByScalar(Cartesian3.add(minBoxPt, maxBoxPt, fromPointsScratch), 0.5, fromPointsNaiveCenterScratch); - var implementation; - var a; + // Begin 2nd pass to find naive radius and modify the ritter sphere. + var naiveRadius = 0; + for (i = 0; i < numPositions; i++) { + Cartesian3.clone(positions[i], currentPos); - /** - * Given a non-relative moduleID, returns an absolute URL to the file represented by that module ID, - * using, in order of preference, require.toUrl, the value of a global CESIUM_BASE_URL, or - * the base URL of the Cesium.js script. - * - * @private - */ - function buildModuleUrl(moduleID) { - if (!defined(implementation)) { - //select implementation - if (defined(define.amd) && !define.amd.toUrlUndefined && defined(require.toUrl)) { - implementation = buildModuleUrlFromRequireToUrl; - } else { - implementation = buildModuleUrlFromBaseUrl; + // Find the furthest point from the naive center to calculate the naive radius. + var r = Cartesian3.magnitude(Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)); + if (r > naiveRadius) { + naiveRadius = r; } - } - if (!defined(a)) { - a = document.createElement('a'); + // Make adjustments to the Ritter Sphere to include all points. + var oldCenterToPointSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)); + if (oldCenterToPointSquared > radiusSquared) { + var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); + // Calculate new radius to include the point that lies outside + ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; + radiusSquared = ritterRadius * ritterRadius; + // Calculate center of new Ritter sphere + var oldToNew = oldCenterToPoint - ritterRadius; + ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; + ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; + ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; + } } - var url = implementation(moduleID); - - a.href = url; - a.href = a.href; // IE only absolutizes href on get, not set + if (ritterRadius < naiveRadius) { + Cartesian3.clone(ritterCenter, result.center); + result.radius = ritterRadius; + } else { + Cartesian3.clone(naiveCenter, result.center); + result.radius = naiveRadius; + } - return a.href; - } + return result; + }; - // exposed for testing - buildModuleUrl._cesiumScriptRegex = cesiumScriptRegex; + var defaultProjection = new GeographicProjection(); + var fromRectangle2DLowerLeft = new Cartesian3(); + var fromRectangle2DUpperRight = new Cartesian3(); + var fromRectangle2DSouthwest = new Cartographic(); + var fromRectangle2DNortheast = new Cartographic(); /** - * Sets the base URL for resolving modules. - * @param {String} value The new base URL. + * Computes a bounding sphere from a rectangle projected in 2D. + * + * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere. + * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ - buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + BoundingSphere.fromRectangle2D = function(rectangle, projection, result) { + return BoundingSphere.fromRectangleWithHeights2D(rectangle, projection, 0.0, 0.0, result); }; - return buildModuleUrl; -}); + /** + * Computes a bounding sphere from a rectangle projected in 2D. The bounding sphere accounts for the + * object's minimum and maximum heights over the rectangle. + * + * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere. + * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. + * @param {Number} [minimumHeight=0.0] The minimum height over the rectangle. + * @param {Number} [maximumHeight=0.0] The maximum height over the rectangle. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + */ + BoundingSphere.fromRectangleWithHeights2D = function(rectangle, projection, minimumHeight, maximumHeight, result) { + if (!defined(result)) { + result = new BoundingSphere(); + } -define('Core/cancelAnimationFrame',[ - './defined' - ], function( - defined) { - 'use strict'; + if (!defined(rectangle)) { + result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = 0.0; + return result; + } - if (typeof window === 'undefined') { - return; - } + projection = defaultValue(projection, defaultProjection); - var implementation = window.cancelAnimationFrame; - (function() { - // look for vendor prefixed function - if (!defined(implementation)) { - var vendors = ['webkit', 'moz', 'ms', 'o']; - var i = 0; - var len = vendors.length; - while (i < len && !defined(implementation)) { - implementation = window[vendors[i] + 'CancelAnimationFrame']; - if (!defined(implementation)) { - implementation = window[vendors[i] + 'CancelRequestAnimationFrame']; - } - ++i; - } + Rectangle.southwest(rectangle, fromRectangle2DSouthwest); + fromRectangle2DSouthwest.height = minimumHeight; + Rectangle.northeast(rectangle, fromRectangle2DNortheast); + fromRectangle2DNortheast.height = maximumHeight; + + var lowerLeft = projection.project(fromRectangle2DSouthwest, fromRectangle2DLowerLeft); + var upperRight = projection.project(fromRectangle2DNortheast, fromRectangle2DUpperRight); + + var width = upperRight.x - lowerLeft.x; + var height = upperRight.y - lowerLeft.y; + var elevation = upperRight.z - lowerLeft.z; + + result.radius = Math.sqrt(width * width + height * height + elevation * elevation) * 0.5; + var center = result.center; + center.x = lowerLeft.x + width * 0.5; + center.y = lowerLeft.y + height * 0.5; + center.z = lowerLeft.z + elevation * 0.5; + return result; + }; + + var fromRectangle3DScratch = []; + + /** + * Computes a bounding sphere from a rectangle in 3D. The bounding sphere is created using a subsample of points + * on the ellipsoid and contained in the rectangle. It may not be accurate for all rectangles on all types of ellipsoids. + * + * @param {Rectangle} [rectangle] The valid rectangle used to create a bounding sphere. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle. + * @param {Number} [surfaceHeight=0.0] The height above the surface of the ellipsoid. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + */ + BoundingSphere.fromRectangle3D = function(rectangle, ellipsoid, surfaceHeight, result) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + surfaceHeight = defaultValue(surfaceHeight, 0.0); + + if (!defined(result)) { + result = new BoundingSphere(); } - // otherwise, assume requestAnimationFrame is based on setTimeout, so use clearTimeout - if (!defined(implementation)) { - implementation = clearTimeout; + if (!defined(rectangle)) { + result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = 0.0; + return result; } - })(); + + var positions = Rectangle.subsample(rectangle, ellipsoid, surfaceHeight, fromRectangle3DScratch); + return BoundingSphere.fromPoints(positions, result); + }; /** - * A browser-independent function to cancel an animation frame requested using {@link requestAnimationFrame}. + * Computes a tight-fitting bounding sphere enclosing a list of 3D points, where the points are + * stored in a flat array in X, Y, Z, order. The bounding sphere is computed by running two + * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to + * ensure a tight fit. * - * @exports cancelAnimationFrame + * @param {Number[]} [positions] An array of points that the bounding sphere will enclose. Each point + * is formed from three elements in the array in the order X, Y, Z. + * @param {Cartesian3} [center=Cartesian3.ZERO] The position to which the positions are relative, which need not be the + * origin of the coordinate system. This is useful when the positions are to be used for + * relative-to-center (RTC) rendering. + * @param {Number} [stride=3] The number of array elements per vertex. It must be at least 3, but it may + * be higher. Regardless of the value of this parameter, the X coordinate of the first position + * is at array index 0, the Y coordinate is at array index 1, and the Z coordinate is at array index + * 2. When stride is 3, the X coordinate of the next position then begins at array index 3. If + * the stride is 5, however, two array elements are skipped and the next position begins at array + * index 5. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. * - * @param {Number} requestID The value returned by {@link requestAnimationFrame}. + * @example + * // Compute the bounding sphere from 3 positions, each specified relative to a center. + * // In addition to the X, Y, and Z coordinates, the points array contains two additional + * // elements per point which are ignored for the purpose of computing the bounding sphere. + * var center = new Cesium.Cartesian3(1.0, 2.0, 3.0); + * var points = [1.0, 2.0, 3.0, 0.1, 0.2, + * 4.0, 5.0, 6.0, 0.1, 0.2, + * 7.0, 8.0, 9.0, 0.1, 0.2]; + * var sphere = Cesium.BoundingSphere.fromVertices(points, center, 5); * - * @see {@link http://www.w3.org/TR/animation-timing/#the-WindowAnimationTiming-interface|The WindowAnimationTiming interface} + * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article} */ - function cancelAnimationFrame(requestID) { - // we need this extra wrapper function because the native cancelAnimationFrame - // functions must be invoked on the global scope (window), which is not the case - // if invoked as Cesium.cancelAnimationFrame(requestID) - implementation(requestID); - } + BoundingSphere.fromVertices = function(positions, center, stride, result) { + if (!defined(result)) { + result = new BoundingSphere(); + } - return cancelAnimationFrame; -}); + if (!defined(positions) || positions.length === 0) { + result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = 0.0; + return result; + } -define('Core/CartographicGeocoderService',[ - '../ThirdParty/when', - './Cartesian3', - './Check' - ], function( - when, - Cartesian3, - Check) { - 'use strict'; + center = defaultValue(center, Cartesian3.ZERO); - /** - * Geocodes queries containing longitude and latitude coordinates and an optional height. - * Query format: `longitude latitude (height)` with longitude/latitude in degrees and height in meters. - * - * @alias CartographicGeocoderService - * @constructor - */ - function CartographicGeocoderService() { - } + stride = defaultValue(stride, 3); - /** - * @function - * - * @param {String} query The query to be sent to the geocoder service - * @returns {Promise<GeocoderResult[]>} - */ - CartographicGeocoderService.prototype.geocode = function(query) { - Check.typeOf.string('query', query); + Check.typeOf.number.greaterThanOrEquals('stride', stride, 3); - var splitQuery = query.match(/[^\s,\n]+/g); - if ((splitQuery.length === 2) || (splitQuery.length === 3)) { - var longitude = +splitQuery[0]; - var latitude = +splitQuery[1]; - var height = (splitQuery.length === 3) ? +splitQuery[2] : 300.0; + var currentPos = fromPointsCurrentPos; + currentPos.x = positions[0] + center.x; + currentPos.y = positions[1] + center.y; + currentPos.z = positions[2] + center.z; - if (isNaN(longitude) && isNaN(latitude)) { - var coordTest = /^(\d+.?\d*)([nsew])/i; - for (var i = 0; i < splitQuery.length; ++i) { - var splitCoord = splitQuery[i].match(coordTest); - if (coordTest.test(splitQuery[i]) && splitCoord.length === 3) { - if (/^[ns]/i.test(splitCoord[2])) { - latitude = (/^[n]/i.test(splitCoord[2])) ? +splitCoord[1] : -splitCoord[1]; - } else if (/^[ew]/i.test(splitCoord[2])) { - longitude = (/^[e]/i.test(splitCoord[2])) ? +splitCoord[1] : -splitCoord[1]; - } - } - } + var xMin = Cartesian3.clone(currentPos, fromPointsXMin); + var yMin = Cartesian3.clone(currentPos, fromPointsYMin); + var zMin = Cartesian3.clone(currentPos, fromPointsZMin); + + var xMax = Cartesian3.clone(currentPos, fromPointsXMax); + var yMax = Cartesian3.clone(currentPos, fromPointsYMax); + var zMax = Cartesian3.clone(currentPos, fromPointsZMax); + + var numElements = positions.length; + var i; + for (i = 0; i < numElements; i += stride) { + var x = positions[i] + center.x; + var y = positions[i + 1] + center.y; + var z = positions[i + 2] + center.z; + + currentPos.x = x; + currentPos.y = y; + currentPos.z = z; + + // Store points containing the the smallest and largest components + if (x < xMin.x) { + Cartesian3.clone(currentPos, xMin); } - if (!isNaN(longitude) && !isNaN(latitude) && !isNaN(height)) { - var result = { - displayName: query, - destination: Cartesian3.fromDegrees(longitude, latitude, height) - }; - return when.resolve([result]); + if (x > xMax.x) { + Cartesian3.clone(currentPos, xMax); + } + + if (y < yMin.y) { + Cartesian3.clone(currentPos, yMin); + } + + if (y > yMax.y) { + Cartesian3.clone(currentPos, yMax); + } + + if (z < zMin.z) { + Cartesian3.clone(currentPos, zMin); + } + + if (z > zMax.z) { + Cartesian3.clone(currentPos, zMax); } } - return when.resolve([]); - }; - return CartographicGeocoderService; -}); + // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). + var xSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(xMax, xMin, fromPointsScratch)); + var ySpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(yMax, yMin, fromPointsScratch)); + var zSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(zMax, zMin, fromPointsScratch)); -define('Core/Spline',[ - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Math' -], function( - Check, - defaultValue, - defined, - DeveloperError, - CesiumMath) { - 'use strict'; + // Set the diameter endpoints to the largest span. + var diameter1 = xMin; + var diameter2 = xMax; + var maxSpan = xSpan; + if (ySpan > maxSpan) { + maxSpan = ySpan; + diameter1 = yMin; + diameter2 = yMax; + } + if (zSpan > maxSpan) { + maxSpan = zSpan; + diameter1 = zMin; + diameter2 = zMax; + } - /** - * Creates a curve parameterized and evaluated by time. This type describes an interface - * and is not intended to be instantiated directly. - * - * @alias Spline - * @constructor - * - * @see CatmullRomSpline - * @see HermiteSpline - * @see LinearSpline - * @see QuaternionSpline - */ - function Spline() { - /** - * An array of times for the control points. - * @type {Number[]} - * @default undefined - */ - this.times = undefined; + // Calculate the center of the initial sphere found by Ritter's algorithm + var ritterCenter = fromPointsRitterCenter; + ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; + ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; + ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; - /** - * An array of control points. - * @type {Cartesian3[]|Quaternion[]} - * @default undefined - */ - this.points = undefined; + // Calculate the radius of the initial sphere found by Ritter's algorithm + var radiusSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)); + var ritterRadius = Math.sqrt(radiusSquared); - DeveloperError.throwInstantiationError(); - } + // Find the center of the sphere found using the Naive method. + var minBoxPt = fromPointsMinBoxPt; + minBoxPt.x = xMin.x; + minBoxPt.y = yMin.y; + minBoxPt.z = zMin.z; - /** - * Evaluates the curve at a given time. - * @function - * - * @param {Number} time The time at which to evaluate the curve. - * @param {Cartesian3|Quaternion} [result] The object onto which to store the result. - * @returns {Cartesian3|Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. - * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. - */ - Spline.prototype.evaluate = DeveloperError.throwInstantiationError; + var maxBoxPt = fromPointsMaxBoxPt; + maxBoxPt.x = xMax.x; + maxBoxPt.y = yMax.y; + maxBoxPt.z = zMax.z; + + var naiveCenter = Cartesian3.multiplyByScalar(Cartesian3.add(minBoxPt, maxBoxPt, fromPointsScratch), 0.5, fromPointsNaiveCenterScratch); + + // Begin 2nd pass to find naive radius and modify the ritter sphere. + var naiveRadius = 0; + for (i = 0; i < numElements; i += stride) { + currentPos.x = positions[i] + center.x; + currentPos.y = positions[i + 1] + center.y; + currentPos.z = positions[i + 2] + center.z; + + // Find the furthest point from the naive center to calculate the naive radius. + var r = Cartesian3.magnitude(Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)); + if (r > naiveRadius) { + naiveRadius = r; + } + + // Make adjustments to the Ritter Sphere to include all points. + var oldCenterToPointSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)); + if (oldCenterToPointSquared > radiusSquared) { + var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); + // Calculate new radius to include the point that lies outside + ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; + radiusSquared = ritterRadius * ritterRadius; + // Calculate center of new Ritter sphere + var oldToNew = oldCenterToPoint - ritterRadius; + ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; + ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; + ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; + } + } + + if (ritterRadius < naiveRadius) { + Cartesian3.clone(ritterCenter, result.center); + result.radius = ritterRadius; + } else { + Cartesian3.clone(naiveCenter, result.center); + result.radius = naiveRadius; + } + + return result; + }; /** - * Finds an index <code>i</code> in <code>times</code> such that the parameter - * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. + * Computes a tight-fitting bounding sphere enclosing a list of {@link EncodedCartesian3}s, where the points are + * stored in parallel flat arrays in X, Y, Z, order. The bounding sphere is computed by running two + * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to + * ensure a tight fit. * - * @param {Number} time The time. - * @param {Number} startIndex The index from which to start the search. - * @returns {Number} The index for the element at the start of the interval. + * @param {Number[]} [positionsHigh] An array of high bits of the encoded cartesians that the bounding sphere will enclose. Each point + * is formed from three elements in the array in the order X, Y, Z. + * @param {Number[]} [positionsLow] An array of low bits of the encoded cartesians that the bounding sphere will enclose. Each point + * is formed from three elements in the array in the order X, Y, Z. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @see {@link http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding/|Bounding Sphere computation article} */ - Spline.prototype.findTimeInterval = function(time, startIndex) { - var times = this.times; - var length = times.length; - - if (!defined(time)) { - throw new DeveloperError('time is required.'); + BoundingSphere.fromEncodedCartesianVertices = function(positionsHigh, positionsLow, result) { + if (!defined(result)) { + result = new BoundingSphere(); } - if (time < times[0] || time > times[length - 1]) { - throw new DeveloperError('time is out of range.'); + + if (!defined(positionsHigh) || !defined(positionsLow) || positionsHigh.length !== positionsLow.length || positionsHigh.length === 0) { + result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = 0.0; + return result; } - - // Take advantage of temporal coherence by checking current, next and previous intervals - // for containment of time. - startIndex = defaultValue(startIndex, 0); - if (time >= times[startIndex]) { - if (startIndex + 1 < length && time < times[startIndex + 1]) { - return startIndex; - } else if (startIndex + 2 < length && time < times[startIndex + 2]) { - return startIndex + 1; + var currentPos = fromPointsCurrentPos; + currentPos.x = positionsHigh[0] + positionsLow[0]; + currentPos.y = positionsHigh[1] + positionsLow[1]; + currentPos.z = positionsHigh[2] + positionsLow[2]; + + var xMin = Cartesian3.clone(currentPos, fromPointsXMin); + var yMin = Cartesian3.clone(currentPos, fromPointsYMin); + var zMin = Cartesian3.clone(currentPos, fromPointsZMin); + + var xMax = Cartesian3.clone(currentPos, fromPointsXMax); + var yMax = Cartesian3.clone(currentPos, fromPointsYMax); + var zMax = Cartesian3.clone(currentPos, fromPointsZMax); + + var numElements = positionsHigh.length; + var i; + for (i = 0; i < numElements; i += 3) { + var x = positionsHigh[i] + positionsLow[i]; + var y = positionsHigh[i + 1] + positionsLow[i + 1]; + var z = positionsHigh[i + 2] + positionsLow[i + 2]; + + currentPos.x = x; + currentPos.y = y; + currentPos.z = z; + + // Store points containing the the smallest and largest components + if (x < xMin.x) { + Cartesian3.clone(currentPos, xMin); + } + + if (x > xMax.x) { + Cartesian3.clone(currentPos, xMax); + } + + if (y < yMin.y) { + Cartesian3.clone(currentPos, yMin); + } + + if (y > yMax.y) { + Cartesian3.clone(currentPos, yMax); + } + + if (z < zMin.z) { + Cartesian3.clone(currentPos, zMin); + } + + if (z > zMax.z) { + Cartesian3.clone(currentPos, zMax); } - } else if (startIndex - 1 >= 0 && time >= times[startIndex - 1]) { - return startIndex - 1; } - // The above failed so do a linear search. For the use cases so far, the - // length of the list is less than 10. In the future, if there is a bottle neck, - // it might be here. + // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). + var xSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(xMax, xMin, fromPointsScratch)); + var ySpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(yMax, yMin, fromPointsScratch)); + var zSpan = Cartesian3.magnitudeSquared(Cartesian3.subtract(zMax, zMin, fromPointsScratch)); - var i; - if (time > times[startIndex]) { - for (i = startIndex; i < length - 1; ++i) { - if (time >= times[i] && time < times[i + 1]) { - break; - } + // Set the diameter endpoints to the largest span. + var diameter1 = xMin; + var diameter2 = xMax; + var maxSpan = xSpan; + if (ySpan > maxSpan) { + maxSpan = ySpan; + diameter1 = yMin; + diameter2 = yMax; + } + if (zSpan > maxSpan) { + maxSpan = zSpan; + diameter1 = zMin; + diameter2 = zMax; + } + + // Calculate the center of the initial sphere found by Ritter's algorithm + var ritterCenter = fromPointsRitterCenter; + ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; + ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; + ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; + + // Calculate the radius of the initial sphere found by Ritter's algorithm + var radiusSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(diameter2, ritterCenter, fromPointsScratch)); + var ritterRadius = Math.sqrt(radiusSquared); + + // Find the center of the sphere found using the Naive method. + var minBoxPt = fromPointsMinBoxPt; + minBoxPt.x = xMin.x; + minBoxPt.y = yMin.y; + minBoxPt.z = zMin.z; + + var maxBoxPt = fromPointsMaxBoxPt; + maxBoxPt.x = xMax.x; + maxBoxPt.y = yMax.y; + maxBoxPt.z = zMax.z; + + var naiveCenter = Cartesian3.multiplyByScalar(Cartesian3.add(minBoxPt, maxBoxPt, fromPointsScratch), 0.5, fromPointsNaiveCenterScratch); + + // Begin 2nd pass to find naive radius and modify the ritter sphere. + var naiveRadius = 0; + for (i = 0; i < numElements; i += 3) { + currentPos.x = positionsHigh[i] + positionsLow[i]; + currentPos.y = positionsHigh[i + 1] + positionsLow[i + 1]; + currentPos.z = positionsHigh[i + 2] + positionsLow[i + 2]; + + // Find the furthest point from the naive center to calculate the naive radius. + var r = Cartesian3.magnitude(Cartesian3.subtract(currentPos, naiveCenter, fromPointsScratch)); + if (r > naiveRadius) { + naiveRadius = r; } - } else { - for (i = startIndex - 1; i >= 0; --i) { - if (time >= times[i] && time < times[i + 1]) { - break; - } + + // Make adjustments to the Ritter Sphere to include all points. + var oldCenterToPointSquared = Cartesian3.magnitudeSquared(Cartesian3.subtract(currentPos, ritterCenter, fromPointsScratch)); + if (oldCenterToPointSquared > radiusSquared) { + var oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); + // Calculate new radius to include the point that lies outside + ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; + radiusSquared = ritterRadius * ritterRadius; + // Calculate center of new Ritter sphere + var oldToNew = oldCenterToPoint - ritterRadius; + ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; + ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; + ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; } } - if (i === length - 1) { - i = length - 2; + if (ritterRadius < naiveRadius) { + Cartesian3.clone(ritterCenter, result.center); + result.radius = ritterRadius; + } else { + Cartesian3.clone(naiveCenter, result.center); + result.radius = naiveRadius; } - return i; + return result; }; /** - * Wraps the given time to the period covered by the spline. - * @function + * Computes a bounding sphere from the corner points of an axis-aligned bounding box. The sphere + * tighly and fully encompases the box. * - * @param {Number} time The time. - * @return {Number} The time, wrapped around the animation period. + * @param {Cartesian3} [corner] The minimum height over the rectangle. + * @param {Cartesian3} [oppositeCorner] The maximum height over the rectangle. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * + * @example + * // Create a bounding sphere around the unit cube + * var sphere = Cesium.BoundingSphere.fromCornerPoints(new Cesium.Cartesian3(-0.5, -0.5, -0.5), new Cesium.Cartesian3(0.5, 0.5, 0.5)); */ - Spline.prototype.wrapTime = function(time) { - Check.typeOf.number('time', time); + BoundingSphere.fromCornerPoints = function(corner, oppositeCorner, result) { + Check.typeOf.object('corner', corner); + Check.typeOf.object('oppositeCorner', oppositeCorner); - var times = this.times; - var timeEnd = times[times.length - 1]; - var timeStart = times[0]; - var timeStretch = timeEnd - timeStart; - var divs; - if (time < timeStart) { - divs = Math.floor((timeStart - time) / timeStretch) + 1; - time += divs * timeStretch; - } - if (time > timeEnd) { - divs = Math.floor((time - timeEnd) / timeStretch) + 1; - time -= divs * timeStretch; + if (!defined(result)) { + result = new BoundingSphere(); } - return time; + + var center = result.center; + Cartesian3.add(corner, oppositeCorner, center); + Cartesian3.multiplyByScalar(center, 0.5, center); + result.radius = Cartesian3.distance(center, oppositeCorner); + return result; }; /** - * Clamps the given time to the period covered by the spline. - * @function + * Creates a bounding sphere encompassing an ellipsoid. * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {Ellipsoid} ellipsoid The ellipsoid around which to create a bounding sphere. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + * + * @example + * var boundingSphere = Cesium.BoundingSphere.fromEllipsoid(ellipsoid); */ - Spline.prototype.clampTime = function(time) { - Check.typeOf.number('time', time); + BoundingSphere.fromEllipsoid = function(ellipsoid, result) { + Check.typeOf.object('ellipsoid', ellipsoid); - var times = this.times; - return CesiumMath.clamp(time, times[0], times[times.length - 1]); - }; + if (!defined(result)) { + result = new BoundingSphere(); + } - return Spline; -}); + Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = ellipsoid.maximumRadius; + return result; + }; -define('Core/LinearSpline',[ - './Cartesian3', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Spline' - ], function( - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Spline) { - 'use strict'; + var fromBoundingSpheresScratch = new Cartesian3(); /** - * A spline that uses piecewise linear interpolation to create a curve. - * - * @alias LinearSpline - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. - * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. - * - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be equal to points.length. - * - * - * @example - * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ]; - * var spline = new Cesium.LinearSpline({ - * times : times, - * points : [ - * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), - * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), - * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), - * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), - * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) - * ] - * }); - * - * var p0 = spline.evaluate(times[0]); + * Computes a tight-fitting bounding sphere enclosing the provided array of bounding spheres. * - * @see HermiteSpline - * @see CatmullRomSpline - * @see QuaternionSpline - * @see WeightSpline + * @param {BoundingSphere[]} [boundingSpheres] The array of bounding spheres. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ - function LinearSpline(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var points = options.points; - var times = options.times; + BoundingSphere.fromBoundingSpheres = function(boundingSpheres, result) { + if (!defined(result)) { + result = new BoundingSphere(); + } - if (!defined(points) || !defined(times)) { - throw new DeveloperError('points and times are required.'); + if (!defined(boundingSpheres) || boundingSpheres.length === 0) { + result.center = Cartesian3.clone(Cartesian3.ZERO, result.center); + result.radius = 0.0; + return result; } - if (points.length < 2) { - throw new DeveloperError('points.length must be greater than or equal to 2.'); + + var length = boundingSpheres.length; + if (length === 1) { + return BoundingSphere.clone(boundingSpheres[0], result); } - if (times.length !== points.length) { - throw new DeveloperError('times.length must be equal to points.length.'); + + if (length === 2) { + return BoundingSphere.union(boundingSpheres[0], boundingSpheres[1], result); } - - this._times = times; - this._points = points; - this._lastTimeIndex = 0; - } + var positions = []; + var i; + for (i = 0; i < length; i++) { + positions.push(boundingSpheres[i].center); + } - defineProperties(LinearSpline.prototype, { - /** - * An array of times for the control points. - * - * @memberof LinearSpline.prototype - * - * @type {Number[]} - * @readonly - */ - times : { - get : function() { - return this._times; - } - }, + result = BoundingSphere.fromPoints(positions, result); - /** - * An array of {@link Cartesian3} control points. - * - * @memberof LinearSpline.prototype - * - * @type {Cartesian3[]} - * @readonly - */ - points : { - get : function() { - return this._points; - } + var center = result.center; + var radius = result.radius; + for (i = 0; i < length; i++) { + var tmp = boundingSpheres[i]; + radius = Math.max(radius, Cartesian3.distance(center, tmp.center, fromBoundingSpheresScratch) + tmp.radius); } - }); + result.radius = radius; - /** - * Finds an index <code>i</code> in <code>times</code> such that the parameter - * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. - * @function - * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. - * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. - */ - LinearSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; + return result; + }; - /** - * Wraps the given time to the period covered by the spline. - * @function - * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. - */ - LinearSpline.prototype.wrapTime = Spline.prototype.wrapTime; + var fromOrientedBoundingBoxScratchU = new Cartesian3(); + var fromOrientedBoundingBoxScratchV = new Cartesian3(); + var fromOrientedBoundingBoxScratchW = new Cartesian3(); /** - * Clamps the given time to the period covered by the spline. - * @function + * Computes a tight-fitting bounding sphere enclosing the provided oriented bounding box. * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {OrientedBoundingBox} orientedBoundingBox The oriented bounding box. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ - LinearSpline.prototype.clampTime = Spline.prototype.clampTime; + BoundingSphere.fromOrientedBoundingBox = function(orientedBoundingBox, result) { + Check.defined('orientedBoundingBox', orientedBoundingBox); + + if (!defined(result)) { + result = new BoundingSphere(); + } + + var halfAxes = orientedBoundingBox.halfAxes; + var u = Matrix3.getColumn(halfAxes, 0, fromOrientedBoundingBoxScratchU); + var v = Matrix3.getColumn(halfAxes, 1, fromOrientedBoundingBoxScratchV); + var w = Matrix3.getColumn(halfAxes, 2, fromOrientedBoundingBoxScratchW); + + Cartesian3.add(u, v, u); + Cartesian3.add(u, w, u); + + result.center = Cartesian3.clone(orientedBoundingBox.center, result.center); + result.radius = Cartesian3.magnitude(u); + + return result; + }; /** - * Evaluates the curve at a given time. - * - * @param {Number} time The time at which to evaluate the curve. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. + * Duplicates a BoundingSphere instance. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @param {BoundingSphere} sphere The bounding sphere to duplicate. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. (Returns undefined if sphere is undefined) */ - LinearSpline.prototype.evaluate = function(time, result) { - var points = this.points; - var times = this.times; - - var i = this._lastTimeIndex = this.findTimeInterval(time, this._lastTimeIndex); - var u = (time - times[i]) / (times[i + 1] - times[i]); + BoundingSphere.clone = function(sphere, result) { + if (!defined(sphere)) { + return undefined; + } if (!defined(result)) { - result = new Cartesian3(); + return new BoundingSphere(sphere.center, sphere.radius); } - return Cartesian3.lerp(points[i], points[i + 1], u, result); + result.center = Cartesian3.clone(sphere.center, result.center); + result.radius = sphere.radius; + return result; }; - return LinearSpline; -}); - -define('Core/TridiagonalSystemSolver',[ - './Cartesian3', - './defined', - './DeveloperError' - ], function( - Cartesian3, - defined, - DeveloperError) { - 'use strict'; - /** - * Uses the Tridiagonal Matrix Algorithm, also known as the Thomas Algorithm, to solve - * a system of linear equations where the coefficient matrix is a tridiagonal matrix. - * - * @exports TridiagonalSystemSolver + * The number of elements used to pack the object into an array. + * @type {Number} */ - var TridiagonalSystemSolver = {}; + BoundingSphere.packedLength = 4; /** - * Solves a tridiagonal system of linear equations. - * - * @param {Number[]} diagonal An array with length <code>n</code> that contains the diagonal of the coefficient matrix. - * @param {Number[]} lower An array with length <code>n - 1</code> that contains the lower diagonal of the coefficient matrix. - * @param {Number[]} upper An array with length <code>n - 1</code> that contains the upper diagonal of the coefficient matrix. - * @param {Cartesian3[]} right An array of Cartesians with length <code>n</code> that is the right side of the system of equations. - * - * @exception {DeveloperError} diagonal and right must have the same lengths. - * @exception {DeveloperError} lower and upper must have the same lengths. - * @exception {DeveloperError} lower and upper must be one less than the length of diagonal. - * - * @performance Linear time. - * - * @example - * var lowerDiagonal = [1.0, 1.0, 1.0, 1.0]; - * var diagonal = [2.0, 4.0, 4.0, 4.0, 2.0]; - * var upperDiagonal = [1.0, 1.0, 1.0, 1.0]; - * var rightHandSide = [ - * new Cesium.Cartesian3(410757.0, -1595711.0, 1375302.0), - * new Cesium.Cartesian3(-5986705.0, -2190640.0, 1099600.0), - * new Cesium.Cartesian3(-12593180.0, 288588.0, -1755549.0), - * new Cesium.Cartesian3(-5349898.0, 2457005.0, -2685438.0), - * new Cesium.Cartesian3(845820.0, 1573488.0, -1205591.0) - * ]; + * Stores the provided instance into the provided array. * - * var solution = Cesium.TridiagonalSystemSolver.solve(lowerDiagonal, diagonal, upperDiagonal, rightHandSide); + * @param {BoundingSphere} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Cartesian3[]} An array of Cartesians with length <code>n</code> that is the solution to the tridiagonal system of equations. + * @returns {Number[]} The array that was packed into */ - TridiagonalSystemSolver.solve = function(lower, diagonal, upper, right) { - if (!defined(lower) || !(lower instanceof Array)) { - throw new DeveloperError('The array lower is required.'); - } - if (!defined(diagonal) || !(diagonal instanceof Array)) { - throw new DeveloperError('The array diagonal is required.'); - } - if (!defined(upper) || !(upper instanceof Array)) { - throw new DeveloperError('The array upper is required.'); - } - if (!defined(right) || !(right instanceof Array)) { - throw new DeveloperError('The array right is required.'); - } - if (diagonal.length !== right.length) { - throw new DeveloperError('diagonal and right must have the same lengths.'); - } - if (lower.length !== upper.length) { - throw new DeveloperError('lower and upper must have the same lengths.'); - } else if (lower.length !== diagonal.length - 1) { - throw new DeveloperError('lower and upper must be one less than the length of diagonal.'); - } + BoundingSphere.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); - var c = new Array(upper.length); - var d = new Array(right.length); - var x = new Array(right.length); - - var i; - for (i = 0; i < d.length; i++) { - d[i] = new Cartesian3(); - x[i] = new Cartesian3(); - } + startingIndex = defaultValue(startingIndex, 0); - c[0] = upper[0] / diagonal[0]; - d[0] = Cartesian3.multiplyByScalar(right[0], 1.0 / diagonal[0], d[0]); + var center = value.center; + array[startingIndex++] = center.x; + array[startingIndex++] = center.y; + array[startingIndex++] = center.z; + array[startingIndex] = value.radius; - var scalar; - for (i = 1; i < c.length; ++i) { - scalar = 1.0 / (diagonal[i] - c[i - 1] * lower[i - 1]); - c[i] = upper[i] * scalar; - d[i] = Cartesian3.subtract(right[i], Cartesian3.multiplyByScalar(d[i - 1], lower[i - 1], d[i]), d[i]); - d[i] = Cartesian3.multiplyByScalar(d[i], scalar, d[i]); - } + return array; + }; - scalar = 1.0 / (diagonal[i] - c[i - 1] * lower[i - 1]); - d[i] = Cartesian3.subtract(right[i], Cartesian3.multiplyByScalar(d[i - 1], lower[i - 1], d[i]), d[i]); - d[i] = Cartesian3.multiplyByScalar(d[i], scalar, d[i]); + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {BoundingSphere} [result] The object into which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + */ + BoundingSphere.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - x[x.length - 1] = d[d.length - 1]; - for (i = x.length - 2; i >= 0; --i) { - x[i] = Cartesian3.subtract(d[i], Cartesian3.multiplyByScalar(x[i + 1], c[i], x[i]), x[i]); + if (!defined(result)) { + result = new BoundingSphere(); } - return x; + var center = result.center; + center.x = array[startingIndex++]; + center.y = array[startingIndex++]; + center.z = array[startingIndex++]; + result.radius = array[startingIndex]; + return result; }; - return TridiagonalSystemSolver; -}); - -define('Core/HermiteSpline',[ - './Cartesian3', - './Cartesian4', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './LinearSpline', - './Matrix4', - './Spline', - './TridiagonalSystemSolver' - ], function( - Cartesian3, - Cartesian4, - defaultValue, - defined, - defineProperties, - DeveloperError, - LinearSpline, - Matrix4, - Spline, - TridiagonalSystemSolver) { - 'use strict'; - - var scratchLower = []; - var scratchDiagonal = []; - var scratchUpper = []; - var scratchRight = []; - - function generateClamped(points, firstTangent, lastTangent) { - var l = scratchLower; - var u = scratchUpper; - var d = scratchDiagonal; - var r = scratchRight; - - l.length = u.length = points.length - 1; - d.length = r.length = points.length; - - var i; - l[0] = d[0] = 1.0; - u[0] = 0.0; - - var right = r[0]; - if (!defined(right)) { - right = r[0] = new Cartesian3(); + var unionScratch = new Cartesian3(); + var unionScratchCenter = new Cartesian3(); + /** + * Computes a bounding sphere that contains both the left and right bounding spheres. + * + * @param {BoundingSphere} left A sphere to enclose in a bounding sphere. + * @param {BoundingSphere} right A sphere to enclose in a bounding sphere. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + */ + BoundingSphere.union = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + + if (!defined(result)) { + result = new BoundingSphere(); } - Cartesian3.clone(firstTangent, right); - - for (i = 1; i < l.length - 1; ++i) { - l[i] = u[i] = 1.0; - d[i] = 4.0; - right = r[i]; - if (!defined(right)) { - right = r[i] = new Cartesian3(); - } - Cartesian3.subtract(points[i + 1], points[i - 1], right); - Cartesian3.multiplyByScalar(right, 3.0, right); - } + var leftCenter = left.center; + var leftRadius = left.radius; + var rightCenter = right.center; + var rightRadius = right.radius; - l[i] = 0.0; - u[i] = 1.0; - d[i] = 4.0; + var toRightCenter = Cartesian3.subtract(rightCenter, leftCenter, unionScratch); + var centerSeparation = Cartesian3.magnitude(toRightCenter); - right = r[i]; - if (!defined(right)) { - right = r[i] = new Cartesian3(); + if (leftRadius >= (centerSeparation + rightRadius)) { + // Left sphere wins. + left.clone(result); + return result; } - Cartesian3.subtract(points[i + 1], points[i - 1], right); - Cartesian3.multiplyByScalar(right, 3.0, right); - d[i + 1] = 1.0; - right = r[i + 1]; - if (!defined(right)) { - right = r[i + 1] = new Cartesian3(); + if (rightRadius >= (centerSeparation + leftRadius)) { + // Right sphere wins. + right.clone(result); + return result; } - Cartesian3.clone(lastTangent, right); - return TridiagonalSystemSolver.solve(l, d, u, r); - } + // There are two tangent points, one on far side of each sphere. + var halfDistanceBetweenTangentPoints = (leftRadius + centerSeparation + rightRadius) * 0.5; - function generateNatural(points){ - var l = scratchLower; - var u = scratchUpper; - var d = scratchDiagonal; - var r = scratchRight; + // Compute the center point halfway between the two tangent points. + var center = Cartesian3.multiplyByScalar(toRightCenter, + (-leftRadius + halfDistanceBetweenTangentPoints) / centerSeparation, unionScratchCenter); + Cartesian3.add(center, leftCenter, center); + Cartesian3.clone(center, result.center); + result.radius = halfDistanceBetweenTangentPoints; - l.length = u.length = points.length - 1; - d.length = r.length = points.length; + return result; + }; - var i; - l[0] = u[0] = 1.0; - d[0] = 2.0; + var expandScratch = new Cartesian3(); + /** + * Computes a bounding sphere by enlarging the provided sphere to contain the provided point. + * + * @param {BoundingSphere} sphere A sphere to expand. + * @param {Cartesian3} point A point to enclose in a bounding sphere. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. + */ + BoundingSphere.expand = function(sphere, point, result) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('point', point); + + result = BoundingSphere.clone(sphere, result); - var right = r[0]; - if (!defined(right)) { - right = r[0] = new Cartesian3(); + var radius = Cartesian3.magnitude(Cartesian3.subtract(point, result.center, expandScratch)); + if (radius > result.radius) { + result.radius = radius; } - Cartesian3.subtract(points[1], points[0], right); - Cartesian3.multiplyByScalar(right, 3.0, right); - - for (i = 1; i < l.length; ++i) { - l[i] = u[i] = 1.0; - d[i] = 4.0; - right = r[i]; - if (!defined(right)) { - right = r[i] = new Cartesian3(); - } - Cartesian3.subtract(points[i + 1], points[i - 1], right); - Cartesian3.multiplyByScalar(right, 3.0, right); - } + return result; + }; - d[i] = 2.0; + /** + * Determines which side of a plane a sphere is located. + * + * @param {BoundingSphere} sphere The bounding sphere to test. + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is + * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere + * intersects the plane. + */ + BoundingSphere.intersectPlane = function(sphere, plane) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('plane', plane); + + var center = sphere.center; + var radius = sphere.radius; + var normal = plane.normal; + var distanceToPlane = Cartesian3.dot(normal, center) + plane.distance; - right = r[i]; - if (!defined(right)) { - right = r[i] = new Cartesian3(); + if (distanceToPlane < -radius) { + // The center point is negative side of the plane normal + return Intersect.OUTSIDE; + } else if (distanceToPlane < radius) { + // The center point is positive side of the plane, but radius extends beyond it; partial overlap + return Intersect.INTERSECTING; } - Cartesian3.subtract(points[i], points[i - 1], right); - Cartesian3.multiplyByScalar(right, 3.0, right); - - return TridiagonalSystemSolver.solve(l, d, u, r); - } + return Intersect.INSIDE; + }; /** - * A Hermite spline is a cubic interpolating spline. Points, incoming tangents, outgoing tangents, and times - * must be defined for each control point. The outgoing tangents are defined for points [0, n - 2] and the incoming - * tangents are defined for points [1, n - 1]. For example, when interpolating a segment of the curve between <code>points[i]</code> and - * <code>points[i + 1]</code>, the tangents at the points will be <code>outTangents[i]</code> and <code>inTangents[i]</code>, - * respectively. - * - * @alias HermiteSpline - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. - * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. - * @param {Cartesian3[]} options.inTangents The array of {@link Cartesian3} incoming tangents at each control point. - * @param {Cartesian3[]} options.outTangents The array of {@link Cartesian3} outgoing tangents at each control point. - * - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be equal to points.length. - * @exception {DeveloperError} inTangents and outTangents must have a length equal to points.length - 1. - * - * - * @example - * // Create a G<sup>1</sup> continuous Hermite spline - * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ]; - * var spline = new Cesium.HermiteSpline({ - * times : times, - * points : [ - * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), - * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), - * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), - * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), - * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) - * ], - * outTangents : [ - * new Cesium.Cartesian3(1125196, -161816, 270551), - * new Cesium.Cartesian3(-996690.5, -365906.5, 184028.5), - * new Cesium.Cartesian3(-2096917, 48379.5, -292683.5), - * new Cesium.Cartesian3(-890902.5, 408999.5, -447115) - * ], - * inTangents : [ - * new Cesium.Cartesian3(-1993381, -731813, 368057), - * new Cesium.Cartesian3(-4193834, 96759, -585367), - * new Cesium.Cartesian3(-1781805, 817999, -894230), - * new Cesium.Cartesian3(1165345, 112641, 47281) - * ] - * }); - * - * var p0 = spline.evaluate(times[0]); + * Applies a 4x4 affine transformation matrix to a bounding sphere. * - * @see CatmullRomSpline - * @see LinearSpline - * @see QuaternionSpline - * @see WeightSpline + * @param {BoundingSphere} sphere The bounding sphere to apply the transformation to. + * @param {Matrix4} transform The transformation matrix to apply to the bounding sphere. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ - function HermiteSpline(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var points = options.points; - var times = options.times; - var inTangents = options.inTangents; - var outTangents = options.outTangents; - - if (!defined(points) || !defined(times) || !defined(inTangents) || !defined(outTangents)) { - throw new DeveloperError('times, points, inTangents, and outTangents are required.'); - } - if (points.length < 2) { - throw new DeveloperError('points.length must be greater than or equal to 2.'); - } - if (times.length !== points.length) { - throw new DeveloperError('times.length must be equal to points.length.'); - } - if (inTangents.length !== outTangents.length || inTangents.length !== points.length - 1) { - throw new DeveloperError('inTangents and outTangents must have a length equal to points.length - 1.'); - } + BoundingSphere.transform = function(sphere, transform, result) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('transform', transform); - this._times = times; - this._points = points; - this._inTangents = inTangents; - this._outTangents = outTangents; - - this._lastTimeIndex = 0; - } - - defineProperties(HermiteSpline.prototype, { - /** - * An array of times for the control points. - * - * @memberof HermiteSpline.prototype - * - * @type {Number[]} - * @readonly - */ - times : { - get : function() { - return this._times; - } - }, + if (!defined(result)) { + result = new BoundingSphere(); + } - /** - * An array of {@link Cartesian3} control points. - * - * @memberof HermiteSpline.prototype - * - * @type {Cartesian3[]} - * @readonly - */ - points : { - get : function() { - return this._points; - } - }, + result.center = Matrix4.multiplyByPoint(transform, sphere.center, result.center); + result.radius = Matrix4.getMaximumScale(transform) * sphere.radius; - /** - * An array of {@link Cartesian3} incoming tangents at each control point. - * - * @memberof HermiteSpline.prototype - * - * @type {Cartesian3[]} - * @readonly - */ - inTangents : { - get : function() { - return this._inTangents; - } - }, + return result; + }; - /** - * An array of {@link Cartesian3} outgoing tangents at each control point. - * - * @memberof HermiteSpline.prototype - * - * @type {Cartesian3[]} - * @readonly - */ - outTangents : { - get : function() { - return this._outTangents; - } - } - }); + var distanceSquaredToScratch = new Cartesian3(); /** - * Creates a spline where the tangents at each control point are the same. - * The curves are guaranteed to be at least in the class C<sup>1</sup>. - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times The array of control point times. - * @param {Cartesian3[]} options.points The array of control points. - * @param {Cartesian3[]} options.tangents The array of tangents at the control points. - * @returns {HermiteSpline} A hermite spline. + * Computes the estimated distance squared from the closest point on a bounding sphere to a point. * - * @exception {DeveloperError} points, times and tangents are required. - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times, points and tangents must have the same length. + * @param {BoundingSphere} sphere The sphere. + * @param {Cartesian3} cartesian The point + * @returns {Number} The estimated distance squared from the bounding sphere to the point. * * @example - * var points = [ - * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), - * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), - * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), - * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), - * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) - * ]; - * - * // Add tangents - * var tangents = new Array(points.length); - * tangents[0] = new Cesium.Cartesian3(1125196, -161816, 270551); - * var temp = new Cesium.Cartesian3(); - * for (var i = 1; i < tangents.length - 1; ++i) { - * tangents[i] = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.subtract(points[i + 1], points[i - 1], temp), 0.5, new Cesium.Cartesian3()); - * } - * tangents[tangents.length - 1] = new Cesium.Cartesian3(1165345, 112641, 47281); - * - * var spline = Cesium.HermiteSpline.createC1({ - * times : times, - * points : points, - * tangents : tangents + * // Sort bounding spheres from back to front + * spheres.sort(function(a, b) { + * return Cesium.BoundingSphere.distanceSquaredTo(b, camera.positionWC) - Cesium.BoundingSphere.distanceSquaredTo(a, camera.positionWC); * }); */ - HermiteSpline.createC1 = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var times = options.times; - var points = options.points; - var tangents = options.tangents; - - if (!defined(points) || !defined(times) || !defined(tangents)) { - throw new DeveloperError('points, times and tangents are required.'); - } - if (points.length < 2) { - throw new DeveloperError('points.length must be greater than or equal to 2.'); - } - if (times.length !== points.length || times.length !== tangents.length) { - throw new DeveloperError('times, points and tangents must have the same length.'); - } + BoundingSphere.distanceSquaredTo = function(sphere, cartesian) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('cartesian', cartesian); - var outTangents = tangents.slice(0, tangents.length - 1); - var inTangents = tangents.slice(1, tangents.length); - - return new HermiteSpline({ - times : times, - points : points, - inTangents : inTangents, - outTangents : outTangents - }); + var diff = Cartesian3.subtract(sphere.center, cartesian, distanceSquaredToScratch); + return Cartesian3.magnitudeSquared(diff) - sphere.radius * sphere.radius; }; /** - * Creates a natural cubic spline. The tangents at the control points are generated - * to create a curve in the class C<sup>2</sup>. - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times The array of control point times. - * @param {Cartesian3[]} options.points The array of control points. - * @returns {HermiteSpline|LinearSpline} A hermite spline or a linear spline if less than 3 control points were given. + * Applies a 4x4 affine transformation matrix to a bounding sphere where there is no scale + * The transformation matrix is not verified to have a uniform scale of 1. + * This method is faster than computing the general bounding sphere transform using {@link BoundingSphere.transform}. * - * @exception {DeveloperError} points and times are required. - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be equal to points.length. + * @param {BoundingSphere} sphere The bounding sphere to apply the transformation to. + * @param {Matrix4} transform The transformation matrix to apply to the bounding sphere. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. * * @example - * // Create a natural cubic spline above the earth from Philadelphia to Los Angeles. - * var spline = Cesium.HermiteSpline.createNaturalCubic({ - * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ], - * points : [ - * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), - * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), - * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), - * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), - * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) - * ] - * }); + * var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid); + * var boundingSphere = new Cesium.BoundingSphere(); + * var newBoundingSphere = Cesium.BoundingSphere.transformWithoutScale(boundingSphere, modelMatrix); */ - HermiteSpline.createNaturalCubic = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var times = options.times; - var points = options.points; - - if (!defined(points) || !defined(times)) { - throw new DeveloperError('points and times are required.'); - } - if (points.length < 2) { - throw new DeveloperError('points.length must be greater than or equal to 2.'); - } - if (times.length !== points.length) { - throw new DeveloperError('times.length must be equal to points.length.'); - } + BoundingSphere.transformWithoutScale = function(sphere, transform, result) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('transform', transform); - if (points.length < 3) { - return new LinearSpline({ - points : points, - times : times - }); + if (!defined(result)) { + result = new BoundingSphere(); } - var tangents = generateNatural(points); - var outTangents = tangents.slice(0, tangents.length - 1); - var inTangents = tangents.slice(1, tangents.length); + result.center = Matrix4.multiplyByPoint(transform, sphere.center, result.center); + result.radius = sphere.radius; - return new HermiteSpline({ - times : times, - points : points, - inTangents : inTangents, - outTangents : outTangents - }); + return result; }; + var scratchCartesian3 = new Cartesian3(); /** - * Creates a clamped cubic spline. The tangents at the interior control points are generated - * to create a curve in the class C<sup>2</sup>. - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times The array of control point times. - * @param {Cartesian3[]} options.points The array of control points. - * @param {Cartesian3} options.firstTangent The outgoing tangent of the first control point. - * @param {Cartesian3} options.lastTangent The incoming tangent of the last control point. - * @returns {HermiteSpline|LinearSpline} A hermite spline or a linear spline if less than 3 control points were given. - * - * @exception {DeveloperError} points, times, firstTangent and lastTangent are required. - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be equal to points.length. + * The distances calculated by the vector from the center of the bounding sphere to position projected onto direction + * plus/minus the radius of the bounding sphere. + * <br> + * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the + * closest and farthest planes from position that intersect the bounding sphere. * - * @example - * // Create a clamped cubic spline above the earth from Philadelphia to Los Angeles. - * var spline = Cesium.HermiteSpline.createClampedCubic({ - * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ], - * points : [ - * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), - * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), - * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), - * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), - * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) - * ], - * firstTangent : new Cesium.Cartesian3(1125196, -161816, 270551), - * lastTangent : new Cesium.Cartesian3(1165345, 112641, 47281) - * }); + * @param {BoundingSphere} sphere The bounding sphere to calculate the distance to. + * @param {Cartesian3} position The position to calculate the distance from. + * @param {Cartesian3} direction The direction from position. + * @param {Interval} [result] A Interval to store the nearest and farthest distances. + * @returns {Interval} The nearest and farthest distances on the bounding sphere from position in direction. */ - HermiteSpline.createClampedCubic = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var times = options.times; - var points = options.points; - var firstTangent = options.firstTangent; - var lastTangent = options.lastTangent; - - if (!defined(points) || !defined(times) || !defined(firstTangent) || !defined(lastTangent)) { - throw new DeveloperError('points, times, firstTangent and lastTangent are required.'); - } - if (points.length < 2) { - throw new DeveloperError('points.length must be greater than or equal to 2.'); - } - if (times.length !== points.length) { - throw new DeveloperError('times.length must be equal to points.length.'); - } + BoundingSphere.computePlaneDistances = function(sphere, position, direction, result) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('position', position); + Check.typeOf.object('direction', direction); - if (points.length < 3) { - return new LinearSpline({ - points : points, - times : times - }); + if (!defined(result)) { + result = new Interval(); } - var tangents = generateClamped(points, firstTangent, lastTangent); - var outTangents = tangents.slice(0, tangents.length - 1); - var inTangents = tangents.slice(1, tangents.length); + var toCenter = Cartesian3.subtract(sphere.center, position, scratchCartesian3); + var mag = Cartesian3.dot(direction, toCenter); - return new HermiteSpline({ - times : times, - points : points, - inTangents : inTangents, - outTangents : outTangents - }); + result.start = mag - sphere.radius; + result.stop = mag + sphere.radius; + return result; }; - HermiteSpline.hermiteCoefficientMatrix = new Matrix4( - 2.0, -3.0, 0.0, 1.0, - -2.0, 3.0, 0.0, 0.0, - 1.0, -2.0, 1.0, 0.0, - 1.0, -1.0, 0.0, 0.0); + var projectTo2DNormalScratch = new Cartesian3(); + var projectTo2DEastScratch = new Cartesian3(); + var projectTo2DNorthScratch = new Cartesian3(); + var projectTo2DWestScratch = new Cartesian3(); + var projectTo2DSouthScratch = new Cartesian3(); + var projectTo2DCartographicScratch = new Cartographic(); + var projectTo2DPositionsScratch = new Array(8); + for (var n = 0; n < 8; ++n) { + projectTo2DPositionsScratch[n] = new Cartesian3(); + } + var projectTo2DProjection = new GeographicProjection(); /** - * Finds an index <code>i</code> in <code>times</code> such that the parameter - * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. - * @function - * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * Creates a bounding sphere in 2D from a bounding sphere in 3D world coordinates. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @param {BoundingSphere} sphere The bounding sphere to transform to 2D. + * @param {Object} [projection=GeographicProjection] The projection to 2D. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ - HermiteSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; + BoundingSphere.projectTo2D = function(sphere, projection, result) { + Check.typeOf.object('sphere', sphere); + + projection = defaultValue(projection, projectTo2DProjection); - var scratchTimeVec = new Cartesian4(); - var scratchTemp = new Cartesian3(); + var ellipsoid = projection.ellipsoid; + var center = sphere.center; + var radius = sphere.radius; - /** - * Wraps the given time to the period covered by the spline. - * @function - * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. - */ - HermiteSpline.prototype.wrapTime = Spline.prototype.wrapTime; + var normal = ellipsoid.geodeticSurfaceNormal(center, projectTo2DNormalScratch); + var east = Cartesian3.cross(Cartesian3.UNIT_Z, normal, projectTo2DEastScratch); + Cartesian3.normalize(east, east); + var north = Cartesian3.cross(normal, east, projectTo2DNorthScratch); + Cartesian3.normalize(north, north); - /** - * Clamps the given time to the period covered by the spline. - * @function - * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. - */ - HermiteSpline.prototype.clampTime = Spline.prototype.clampTime; + Cartesian3.multiplyByScalar(normal, radius, normal); + Cartesian3.multiplyByScalar(north, radius, north); + Cartesian3.multiplyByScalar(east, radius, east); - /** - * Evaluates the curve at a given time. - * - * @param {Number} time The time at which to evaluate the curve. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. - * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. - */ - HermiteSpline.prototype.evaluate = function(time, result) { - if (!defined(result)) { - result = new Cartesian3(); - } - var points = this.points; - var times = this.times; - var inTangents = this.inTangents; - var outTangents = this.outTangents; + var south = Cartesian3.negate(north, projectTo2DSouthScratch); + var west = Cartesian3.negate(east, projectTo2DWestScratch); - var i = this._lastTimeIndex = this.findTimeInterval(time, this._lastTimeIndex); - var u = (time - times[i]) / (times[i + 1] - times[i]); + var positions = projectTo2DPositionsScratch; - var timeVec = scratchTimeVec; - timeVec.z = u; - timeVec.y = u * u; - timeVec.x = timeVec.y * u; - timeVec.w = 1.0; + // top NE corner + var corner = positions[0]; + Cartesian3.add(normal, north, corner); + Cartesian3.add(corner, east, corner); - var coefs = Matrix4.multiplyByVector(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec); + // top NW corner + corner = positions[1]; + Cartesian3.add(normal, north, corner); + Cartesian3.add(corner, west, corner); - result = Cartesian3.multiplyByScalar(points[i], coefs.x, result); - Cartesian3.multiplyByScalar(points[i + 1], coefs.y, scratchTemp); - Cartesian3.add(result, scratchTemp, result); - Cartesian3.multiplyByScalar(outTangents[i], coefs.z, scratchTemp); - Cartesian3.add(result, scratchTemp, result); - Cartesian3.multiplyByScalar(inTangents[i], coefs.w, scratchTemp); - return Cartesian3.add(result, scratchTemp, result); - }; + // top SW corner + corner = positions[2]; + Cartesian3.add(normal, south, corner); + Cartesian3.add(corner, west, corner); - return HermiteSpline; -}); + // top SE corner + corner = positions[3]; + Cartesian3.add(normal, south, corner); + Cartesian3.add(corner, east, corner); -define('Core/CatmullRomSpline',[ - './Cartesian3', - './Cartesian4', - './Check', - './defaultValue', - './defined', - './defineProperties', - './HermiteSpline', - './Matrix4', - './Spline' - ], function( - Cartesian3, - Cartesian4, - Check, - defaultValue, - defined, - defineProperties, - HermiteSpline, - Matrix4, - Spline) { - 'use strict'; + Cartesian3.negate(normal, normal); - var scratchTimeVec = new Cartesian4(); - var scratchTemp0 = new Cartesian3(); - var scratchTemp1 = new Cartesian3(); + // bottom NE corner + corner = positions[4]; + Cartesian3.add(normal, north, corner); + Cartesian3.add(corner, east, corner); - function createEvaluateFunction(spline) { - var points = spline.points; - var times = spline.times; + // bottom NW corner + corner = positions[5]; + Cartesian3.add(normal, north, corner); + Cartesian3.add(corner, west, corner); - if (points.length < 3) { - var t0 = times[0]; - var invSpan = 1.0 / (times[1] - t0); + // bottom SW corner + corner = positions[6]; + Cartesian3.add(normal, south, corner); + Cartesian3.add(corner, west, corner); - var p0 = points[0]; - var p1 = points[1]; + // bottom SE corner + corner = positions[7]; + Cartesian3.add(normal, south, corner); + Cartesian3.add(corner, east, corner); - return function(time, result) { - if (!defined(result)){ - result = new Cartesian3(); - } - var u = (time - t0) * invSpan; - return Cartesian3.lerp(p0, p1, u, result); - }; + var length = positions.length; + for (var i = 0; i < length; ++i) { + var position = positions[i]; + Cartesian3.add(center, position, position); + var cartographic = ellipsoid.cartesianToCartographic(position, projectTo2DCartographicScratch); + projection.project(cartographic, position); } - return function(time, result) { - if (!defined(result)) { - result = new Cartesian3(); - } - var i = spline._lastTimeIndex = spline.findTimeInterval(time, spline._lastTimeIndex); - var u = (time - times[i]) / (times[i + 1] - times[i]); - - var timeVec = scratchTimeVec; - timeVec.z = u; - timeVec.y = u * u; - timeVec.x = timeVec.y * u; - timeVec.w = 1.0; - - var p0; - var p1; - var p2; - var p3; - var coefs; - - if (i === 0) { - p0 = points[0]; - p1 = points[1]; - p2 = spline.firstTangent; - - p3 = Cartesian3.subtract(points[2], p0, scratchTemp0); - Cartesian3.multiplyByScalar(p3, 0.5, p3); - - coefs = Matrix4.multiplyByVector(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec); - } else if (i === points.length - 2) { - p0 = points[i]; - p1 = points[i + 1]; - p3 = spline.lastTangent; - - p2 = Cartesian3.subtract(p1, points[i - 1], scratchTemp0); - Cartesian3.multiplyByScalar(p2, 0.5, p2); + result = BoundingSphere.fromPoints(positions, result); - coefs = Matrix4.multiplyByVector(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec); - } else { - p0 = points[i - 1]; - p1 = points[i]; - p2 = points[i + 1]; - p3 = points[i + 2]; - coefs = Matrix4.multiplyByVector(CatmullRomSpline.catmullRomCoefficientMatrix, timeVec, timeVec); - } - result = Cartesian3.multiplyByScalar(p0, coefs.x, result); - Cartesian3.multiplyByScalar(p1, coefs.y, scratchTemp1); - Cartesian3.add(result, scratchTemp1, result); - Cartesian3.multiplyByScalar(p2, coefs.z, scratchTemp1); - Cartesian3.add(result, scratchTemp1, result); - Cartesian3.multiplyByScalar(p3, coefs.w, scratchTemp1); - return Cartesian3.add(result, scratchTemp1, result); - }; - } + // swizzle center components + center = result.center; + var x = center.x; + var y = center.y; + var z = center.z; + center.x = z; + center.y = x; + center.z = y; - var firstTangentScratch = new Cartesian3(); - var lastTangentScratch = new Cartesian3(); + return result; + }; /** - * A Catmull-Rom spline is a cubic spline where the tangent at control points, - * except the first and last, are computed using the previous and next control points. - * Catmull-Rom splines are in the class C<sup>1</sup>. - * - * @alias CatmullRomSpline - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. - * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. - * @param {Cartesian3} [options.firstTangent] The tangent of the curve at the first control point. - * If the tangent is not given, it will be estimated. - * @param {Cartesian3} [options.lastTangent] The tangent of the curve at the last control point. - * If the tangent is not given, it will be estimated. - * - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be equal to points.length. - * - * - * @example - * // spline above the earth from Philadelphia to Los Angeles - * var spline = new Cesium.CatmullRomSpline({ - * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ], - * points : [ - * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), - * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), - * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), - * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), - * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) - * ] - * }); - * - * var p0 = spline.evaluate(times[i]); // equal to positions[i] - * var p1 = spline.evaluate(times[i] + delta); // interpolated value when delta < times[i + 1] - times[i] + * Determines whether or not a sphere is hidden from view by the occluder. * - * @see HermiteSpline - * @see LinearSpline - * @see QuaternionSpline - * @see WeightSpline + * @param {BoundingSphere} sphere The bounding sphere surrounding the occludee object. + * @param {Occluder} occluder The occluder. + * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. */ - function CatmullRomSpline(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var points = options.points; - var times = options.times; - var firstTangent = options.firstTangent; - var lastTangent = options.lastTangent; - - Check.defined('points', points); - Check.defined('times', times); - Check.typeOf.number.greaterThanOrEquals('points.length', points.length, 2); - Check.typeOf.number.equals('times.length', 'points.length', times.length, points.length); - - if (points.length > 2) { - if (!defined(firstTangent)) { - firstTangent = firstTangentScratch; - Cartesian3.multiplyByScalar(points[1], 2.0, firstTangent); - Cartesian3.subtract(firstTangent, points[2], firstTangent); - Cartesian3.subtract(firstTangent, points[0], firstTangent); - Cartesian3.multiplyByScalar(firstTangent, 0.5, firstTangent); - } - - if (!defined(lastTangent)) { - var n = points.length - 1; - lastTangent = lastTangentScratch; - Cartesian3.multiplyByScalar(points[n - 1], 2.0, lastTangent); - Cartesian3.subtract(points[n], lastTangent, lastTangent); - Cartesian3.add(lastTangent, points[n - 2], lastTangent); - Cartesian3.multiplyByScalar(lastTangent, 0.5, lastTangent); - } - } - - this._times = times; - this._points = points; - this._firstTangent = Cartesian3.clone(firstTangent); - this._lastTangent = Cartesian3.clone(lastTangent); - - this._evaluateFunction = createEvaluateFunction(this); - this._lastTimeIndex = 0; - } - - defineProperties(CatmullRomSpline.prototype, { - /** - * An array of times for the control points. - * - * @memberof CatmullRomSpline.prototype - * - * @type {Number[]} - * @readonly - */ - times : { - get : function() { - return this._times; - } - }, - - /** - * An array of {@link Cartesian3} control points. - * - * @memberof CatmullRomSpline.prototype - * - * @type {Cartesian3[]} - * @readonly - */ - points : { - get : function() { - return this._points; - } - }, - - /** - * The tangent at the first control point. - * - * @memberof CatmullRomSpline.prototype - * - * @type {Cartesian3} - * @readonly - */ - firstTangent : { - get : function() { - return this._firstTangent; - } - }, - - /** - * The tangent at the last control point. - * - * @memberof CatmullRomSpline.prototype - * - * @type {Cartesian3} - * @readonly - */ - lastTangent : { - get : function() { - return this._lastTangent; - } - } - }); + BoundingSphere.isOccluded = function(sphere, occluder) { + Check.typeOf.object('sphere', sphere); + Check.typeOf.object('occluder', occluder); + return !occluder.isBoundingSphereVisible(sphere); + }; /** - * @private + * Compares the provided BoundingSphere componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {BoundingSphere} [left] The first BoundingSphere. + * @param {BoundingSphere} [right] The second BoundingSphere. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - CatmullRomSpline.catmullRomCoefficientMatrix = new Matrix4( - -0.5, 1.0, -0.5, 0.0, - 1.5, -2.5, 0.0, 1.0, - -1.5, 2.0, 0.5, 0.0, - 0.5, -0.5, 0.0, 0.0); + BoundingSphere.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + Cartesian3.equals(left.center, right.center) && + left.radius === right.radius); + }; /** - * Finds an index <code>i</code> in <code>times</code> such that the parameter - * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. - * @function - * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * Determines which side of a plane the sphere is located. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is + * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere + * intersects the plane. */ - CatmullRomSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; + BoundingSphere.prototype.intersectPlane = function(plane) { + return BoundingSphere.intersectPlane(this, plane); + }; /** - * Wraps the given time to the period covered by the spline. - * @function + * Computes the estimated distance squared from the closest point on a bounding sphere to a point. * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {Cartesian3} cartesian The point + * @returns {Number} The estimated distance squared from the bounding sphere to the point. + * + * @example + * // Sort bounding spheres from back to front + * spheres.sort(function(a, b) { + * return b.distanceSquaredTo(camera.positionWC) - a.distanceSquaredTo(camera.positionWC); + * }); */ - CatmullRomSpline.prototype.wrapTime = Spline.prototype.wrapTime; + BoundingSphere.prototype.distanceSquaredTo = function(cartesian) { + return BoundingSphere.distanceSquaredTo(this, cartesian); + }; /** - * Clamps the given time to the period covered by the spline. - * @function + * The distances calculated by the vector from the center of the bounding sphere to position projected onto direction + * plus/minus the radius of the bounding sphere. + * <br> + * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the + * closest and farthest planes from position that intersect the bounding sphere. * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {Cartesian3} position The position to calculate the distance from. + * @param {Cartesian3} direction The direction from position. + * @param {Interval} [result] A Interval to store the nearest and farthest distances. + * @returns {Interval} The nearest and farthest distances on the bounding sphere from position in direction. */ - CatmullRomSpline.prototype.clampTime = Spline.prototype.clampTime; + BoundingSphere.prototype.computePlaneDistances = function(position, direction, result) { + return BoundingSphere.computePlaneDistances(this, position, direction, result); + }; /** - * Evaluates the curve at a given time. - * - * @param {Number} time The time at which to evaluate the curve. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. + * Determines whether or not a sphere is hidden from view by the occluder. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @param {Occluder} occluder The occluder. + * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. */ - CatmullRomSpline.prototype.evaluate = function(time, result) { - return this._evaluateFunction(time, result); + BoundingSphere.prototype.isOccluded = function(occluder) { + return BoundingSphere.isOccluded(this, occluder); }; - return CatmullRomSpline; -}); - -define('Core/Event',[ - './Check', - './defined', - './defineProperties' - ], function( - Check, - defined, - defineProperties) { - 'use strict'; - /** - * A generic utility class for managing subscribers for a particular event. - * This class is usually instantiated inside of a container class and - * exposed as a property for others to subscribe to. - * - * @alias Event - * @constructor - * - * @example - * MyObject.prototype.myListener = function(arg1, arg2) { - * this.myArg1Copy = arg1; - * this.myArg2Copy = arg2; - * } + * Compares this BoundingSphere against the provided BoundingSphere componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * var myObjectInstance = new MyObject(); - * var evt = new Cesium.Event(); - * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); - * evt.raiseEvent('1', '2'); - * evt.removeEventListener(MyObject.prototype.myListener); + * @param {BoundingSphere} [right] The right hand side BoundingSphere. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ - function Event() { - this._listeners = []; - this._scopes = []; - this._toRemove = []; - this._insideRaiseEvent = false; - } - - defineProperties(Event.prototype, { - /** - * The number of listeners currently subscribed to the event. - * @memberof Event.prototype - * @type {Number} - * @readonly - */ - numberOfListeners : { - get : function() { - return this._listeners.length - this._toRemove.length; - } - } - }); + BoundingSphere.prototype.equals = function(right) { + return BoundingSphere.equals(this, right); + }; /** - * Registers a callback function to be executed whenever the event is raised. - * An optional scope can be provided to serve as the <code>this</code> pointer - * in which the function will execute. - * - * @param {Function} listener The function to be executed when the event is raised. - * @param {Object} [scope] An optional object scope to serve as the <code>this</code> - * pointer in which the listener function will execute. - * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * Duplicates this BoundingSphere instance. * - * @see Event#raiseEvent - * @see Event#removeEventListener + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ - Event.prototype.addEventListener = function(listener, scope) { - Check.typeOf.func('listener', listener); - - this._listeners.push(listener); - this._scopes.push(scope); - - var event = this; - return function() { - event.removeEventListener(listener, scope); - }; + BoundingSphere.prototype.clone = function(result) { + return BoundingSphere.clone(this, result); }; /** - * Unregisters a previously registered callback. - * - * @param {Function} listener The function to be unregistered. - * @param {Object} [scope] The scope that was originally passed to addEventListener. - * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. - * - * @see Event#addEventListener - * @see Event#raiseEvent + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. */ - Event.prototype.removeEventListener = function(listener, scope) { - Check.typeOf.func('listener', listener); - - var listeners = this._listeners; - var scopes = this._scopes; - - var index = -1; - for (var i = 0; i < listeners.length; i++) { - if (listeners[i] === listener && scopes[i] === scope) { - index = i; - break; - } - } - - if (index !== -1) { - if (this._insideRaiseEvent) { - //In order to allow removing an event subscription from within - //a callback, we don't actually remove the items here. Instead - //remember the index they are at and undefined their value. - this._toRemove.push(index); - listeners[index] = undefined; - scopes[index] = undefined; - } else { - listeners.splice(index, 1); - scopes.splice(index, 1); - } - return true; - } - - return false; + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; }; - function compareNumber(a,b) { - return b - a; - } + return BoundingSphere; +}); + +define('Core/WebGLConstants',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; /** - * Raises the event by calling each registered listener with all supplied arguments. + * Enum containing WebGL Constant values by name. + * for use without an active WebGL context, or in cases where certain constants are unavailable using the WebGL context + * (For example, in [Safari 9]{@link https://github.com/AnalyticalGraphicsInc/cesium/issues/2989}). * - * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * These match the constants from the [WebGL 1.0]{@link https://www.khronos.org/registry/webgl/specs/latest/1.0/} + * and [WebGL 2.0]{@link https://www.khronos.org/registry/webgl/specs/latest/2.0/} + * specifications. * - * @see Event#addEventListener - * @see Event#removeEventListener + * @exports WebGLConstants */ - Event.prototype.raiseEvent = function() { - this._insideRaiseEvent = true; + var WebGLConstants = { + DEPTH_BUFFER_BIT : 0x00000100, + STENCIL_BUFFER_BIT : 0x00000400, + COLOR_BUFFER_BIT : 0x00004000, + POINTS : 0x0000, + LINES : 0x0001, + LINE_LOOP : 0x0002, + LINE_STRIP : 0x0003, + TRIANGLES : 0x0004, + TRIANGLE_STRIP : 0x0005, + TRIANGLE_FAN : 0x0006, + ZERO : 0, + ONE : 1, + SRC_COLOR : 0x0300, + ONE_MINUS_SRC_COLOR : 0x0301, + SRC_ALPHA : 0x0302, + ONE_MINUS_SRC_ALPHA : 0x0303, + DST_ALPHA : 0x0304, + ONE_MINUS_DST_ALPHA : 0x0305, + DST_COLOR : 0x0306, + ONE_MINUS_DST_COLOR : 0x0307, + SRC_ALPHA_SATURATE : 0x0308, + FUNC_ADD : 0x8006, + BLEND_EQUATION : 0x8009, + BLEND_EQUATION_RGB : 0x8009, // same as BLEND_EQUATION + BLEND_EQUATION_ALPHA : 0x883D, + FUNC_SUBTRACT : 0x800A, + FUNC_REVERSE_SUBTRACT : 0x800B, + BLEND_DST_RGB : 0x80C8, + BLEND_SRC_RGB : 0x80C9, + BLEND_DST_ALPHA : 0x80CA, + BLEND_SRC_ALPHA : 0x80CB, + CONSTANT_COLOR : 0x8001, + ONE_MINUS_CONSTANT_COLOR : 0x8002, + CONSTANT_ALPHA : 0x8003, + ONE_MINUS_CONSTANT_ALPHA : 0x8004, + BLEND_COLOR : 0x8005, + ARRAY_BUFFER : 0x8892, + ELEMENT_ARRAY_BUFFER : 0x8893, + ARRAY_BUFFER_BINDING : 0x8894, + ELEMENT_ARRAY_BUFFER_BINDING : 0x8895, + STREAM_DRAW : 0x88E0, + STATIC_DRAW : 0x88E4, + DYNAMIC_DRAW : 0x88E8, + BUFFER_SIZE : 0x8764, + BUFFER_USAGE : 0x8765, + CURRENT_VERTEX_ATTRIB : 0x8626, + FRONT : 0x0404, + BACK : 0x0405, + FRONT_AND_BACK : 0x0408, + CULL_FACE : 0x0B44, + BLEND : 0x0BE2, + DITHER : 0x0BD0, + STENCIL_TEST : 0x0B90, + DEPTH_TEST : 0x0B71, + SCISSOR_TEST : 0x0C11, + POLYGON_OFFSET_FILL : 0x8037, + SAMPLE_ALPHA_TO_COVERAGE : 0x809E, + SAMPLE_COVERAGE : 0x80A0, + NO_ERROR : 0, + INVALID_ENUM : 0x0500, + INVALID_VALUE : 0x0501, + INVALID_OPERATION : 0x0502, + OUT_OF_MEMORY : 0x0505, + CW : 0x0900, + CCW : 0x0901, + LINE_WIDTH : 0x0B21, + ALIASED_POINT_SIZE_RANGE : 0x846D, + ALIASED_LINE_WIDTH_RANGE : 0x846E, + CULL_FACE_MODE : 0x0B45, + FRONT_FACE : 0x0B46, + DEPTH_RANGE : 0x0B70, + DEPTH_WRITEMASK : 0x0B72, + DEPTH_CLEAR_VALUE : 0x0B73, + DEPTH_FUNC : 0x0B74, + STENCIL_CLEAR_VALUE : 0x0B91, + STENCIL_FUNC : 0x0B92, + STENCIL_FAIL : 0x0B94, + STENCIL_PASS_DEPTH_FAIL : 0x0B95, + STENCIL_PASS_DEPTH_PASS : 0x0B96, + STENCIL_REF : 0x0B97, + STENCIL_VALUE_MASK : 0x0B93, + STENCIL_WRITEMASK : 0x0B98, + STENCIL_BACK_FUNC : 0x8800, + STENCIL_BACK_FAIL : 0x8801, + STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802, + STENCIL_BACK_PASS_DEPTH_PASS : 0x8803, + STENCIL_BACK_REF : 0x8CA3, + STENCIL_BACK_VALUE_MASK : 0x8CA4, + STENCIL_BACK_WRITEMASK : 0x8CA5, + VIEWPORT : 0x0BA2, + SCISSOR_BOX : 0x0C10, + COLOR_CLEAR_VALUE : 0x0C22, + COLOR_WRITEMASK : 0x0C23, + UNPACK_ALIGNMENT : 0x0CF5, + PACK_ALIGNMENT : 0x0D05, + MAX_TEXTURE_SIZE : 0x0D33, + MAX_VIEWPORT_DIMS : 0x0D3A, + SUBPIXEL_BITS : 0x0D50, + RED_BITS : 0x0D52, + GREEN_BITS : 0x0D53, + BLUE_BITS : 0x0D54, + ALPHA_BITS : 0x0D55, + DEPTH_BITS : 0x0D56, + STENCIL_BITS : 0x0D57, + POLYGON_OFFSET_UNITS : 0x2A00, + POLYGON_OFFSET_FACTOR : 0x8038, + TEXTURE_BINDING_2D : 0x8069, + SAMPLE_BUFFERS : 0x80A8, + SAMPLES : 0x80A9, + SAMPLE_COVERAGE_VALUE : 0x80AA, + SAMPLE_COVERAGE_INVERT : 0x80AB, + COMPRESSED_TEXTURE_FORMATS : 0x86A3, + DONT_CARE : 0x1100, + FASTEST : 0x1101, + NICEST : 0x1102, + GENERATE_MIPMAP_HINT : 0x8192, + BYTE : 0x1400, + UNSIGNED_BYTE : 0x1401, + SHORT : 0x1402, + UNSIGNED_SHORT : 0x1403, + INT : 0x1404, + UNSIGNED_INT : 0x1405, + FLOAT : 0x1406, + DEPTH_COMPONENT : 0x1902, + ALPHA : 0x1906, + RGB : 0x1907, + RGBA : 0x1908, + LUMINANCE : 0x1909, + LUMINANCE_ALPHA : 0x190A, + UNSIGNED_SHORT_4_4_4_4 : 0x8033, + UNSIGNED_SHORT_5_5_5_1 : 0x8034, + UNSIGNED_SHORT_5_6_5 : 0x8363, + FRAGMENT_SHADER : 0x8B30, + VERTEX_SHADER : 0x8B31, + MAX_VERTEX_ATTRIBS : 0x8869, + MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB, + MAX_VARYING_VECTORS : 0x8DFC, + MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D, + MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C, + MAX_TEXTURE_IMAGE_UNITS : 0x8872, + MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD, + SHADER_TYPE : 0x8B4F, + DELETE_STATUS : 0x8B80, + LINK_STATUS : 0x8B82, + VALIDATE_STATUS : 0x8B83, + ATTACHED_SHADERS : 0x8B85, + ACTIVE_UNIFORMS : 0x8B86, + ACTIVE_ATTRIBUTES : 0x8B89, + SHADING_LANGUAGE_VERSION : 0x8B8C, + CURRENT_PROGRAM : 0x8B8D, + NEVER : 0x0200, + LESS : 0x0201, + EQUAL : 0x0202, + LEQUAL : 0x0203, + GREATER : 0x0204, + NOTEQUAL : 0x0205, + GEQUAL : 0x0206, + ALWAYS : 0x0207, + KEEP : 0x1E00, + REPLACE : 0x1E01, + INCR : 0x1E02, + DECR : 0x1E03, + INVERT : 0x150A, + INCR_WRAP : 0x8507, + DECR_WRAP : 0x8508, + VENDOR : 0x1F00, + RENDERER : 0x1F01, + VERSION : 0x1F02, + NEAREST : 0x2600, + LINEAR : 0x2601, + NEAREST_MIPMAP_NEAREST : 0x2700, + LINEAR_MIPMAP_NEAREST : 0x2701, + NEAREST_MIPMAP_LINEAR : 0x2702, + LINEAR_MIPMAP_LINEAR : 0x2703, + TEXTURE_MAG_FILTER : 0x2800, + TEXTURE_MIN_FILTER : 0x2801, + TEXTURE_WRAP_S : 0x2802, + TEXTURE_WRAP_T : 0x2803, + TEXTURE_2D : 0x0DE1, + TEXTURE : 0x1702, + TEXTURE_CUBE_MAP : 0x8513, + TEXTURE_BINDING_CUBE_MAP : 0x8514, + TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515, + TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516, + TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517, + TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518, + TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519, + TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A, + MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C, + TEXTURE0 : 0x84C0, + TEXTURE1 : 0x84C1, + TEXTURE2 : 0x84C2, + TEXTURE3 : 0x84C3, + TEXTURE4 : 0x84C4, + TEXTURE5 : 0x84C5, + TEXTURE6 : 0x84C6, + TEXTURE7 : 0x84C7, + TEXTURE8 : 0x84C8, + TEXTURE9 : 0x84C9, + TEXTURE10 : 0x84CA, + TEXTURE11 : 0x84CB, + TEXTURE12 : 0x84CC, + TEXTURE13 : 0x84CD, + TEXTURE14 : 0x84CE, + TEXTURE15 : 0x84CF, + TEXTURE16 : 0x84D0, + TEXTURE17 : 0x84D1, + TEXTURE18 : 0x84D2, + TEXTURE19 : 0x84D3, + TEXTURE20 : 0x84D4, + TEXTURE21 : 0x84D5, + TEXTURE22 : 0x84D6, + TEXTURE23 : 0x84D7, + TEXTURE24 : 0x84D8, + TEXTURE25 : 0x84D9, + TEXTURE26 : 0x84DA, + TEXTURE27 : 0x84DB, + TEXTURE28 : 0x84DC, + TEXTURE29 : 0x84DD, + TEXTURE30 : 0x84DE, + TEXTURE31 : 0x84DF, + ACTIVE_TEXTURE : 0x84E0, + REPEAT : 0x2901, + CLAMP_TO_EDGE : 0x812F, + MIRRORED_REPEAT : 0x8370, + FLOAT_VEC2 : 0x8B50, + FLOAT_VEC3 : 0x8B51, + FLOAT_VEC4 : 0x8B52, + INT_VEC2 : 0x8B53, + INT_VEC3 : 0x8B54, + INT_VEC4 : 0x8B55, + BOOL : 0x8B56, + BOOL_VEC2 : 0x8B57, + BOOL_VEC3 : 0x8B58, + BOOL_VEC4 : 0x8B59, + FLOAT_MAT2 : 0x8B5A, + FLOAT_MAT3 : 0x8B5B, + FLOAT_MAT4 : 0x8B5C, + SAMPLER_2D : 0x8B5E, + SAMPLER_CUBE : 0x8B60, + VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622, + VERTEX_ATTRIB_ARRAY_SIZE : 0x8623, + VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624, + VERTEX_ATTRIB_ARRAY_TYPE : 0x8625, + VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A, + VERTEX_ATTRIB_ARRAY_POINTER : 0x8645, + VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F, + IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A, + IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B, + COMPILE_STATUS : 0x8B81, + LOW_FLOAT : 0x8DF0, + MEDIUM_FLOAT : 0x8DF1, + HIGH_FLOAT : 0x8DF2, + LOW_INT : 0x8DF3, + MEDIUM_INT : 0x8DF4, + HIGH_INT : 0x8DF5, + FRAMEBUFFER : 0x8D40, + RENDERBUFFER : 0x8D41, + RGBA4 : 0x8056, + RGB5_A1 : 0x8057, + RGB565 : 0x8D62, + DEPTH_COMPONENT16 : 0x81A5, + STENCIL_INDEX : 0x1901, + STENCIL_INDEX8 : 0x8D48, + DEPTH_STENCIL : 0x84F9, + RENDERBUFFER_WIDTH : 0x8D42, + RENDERBUFFER_HEIGHT : 0x8D43, + RENDERBUFFER_INTERNAL_FORMAT : 0x8D44, + RENDERBUFFER_RED_SIZE : 0x8D50, + RENDERBUFFER_GREEN_SIZE : 0x8D51, + RENDERBUFFER_BLUE_SIZE : 0x8D52, + RENDERBUFFER_ALPHA_SIZE : 0x8D53, + RENDERBUFFER_DEPTH_SIZE : 0x8D54, + RENDERBUFFER_STENCIL_SIZE : 0x8D55, + FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0, + FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2, + FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3, + COLOR_ATTACHMENT0 : 0x8CE0, + DEPTH_ATTACHMENT : 0x8D00, + STENCIL_ATTACHMENT : 0x8D20, + DEPTH_STENCIL_ATTACHMENT : 0x821A, + NONE : 0, + FRAMEBUFFER_COMPLETE : 0x8CD5, + FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6, + FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7, + FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9, + FRAMEBUFFER_UNSUPPORTED : 0x8CDD, + FRAMEBUFFER_BINDING : 0x8CA6, + RENDERBUFFER_BINDING : 0x8CA7, + MAX_RENDERBUFFER_SIZE : 0x84E8, + INVALID_FRAMEBUFFER_OPERATION : 0x0506, + UNPACK_FLIP_Y_WEBGL : 0x9240, + UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241, + CONTEXT_LOST_WEBGL : 0x9242, + UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243, + BROWSER_DEFAULT_WEBGL : 0x9244, - var i; - var listeners = this._listeners; - var scopes = this._scopes; - var length = listeners.length; + // WEBGL_compressed_texture_s3tc + COMPRESSED_RGB_S3TC_DXT1_EXT : 0x83F0, + COMPRESSED_RGBA_S3TC_DXT1_EXT : 0x83F1, + COMPRESSED_RGBA_S3TC_DXT3_EXT : 0x83F2, + COMPRESSED_RGBA_S3TC_DXT5_EXT : 0x83F3, - for (i = 0; i < length; i++) { - var listener = listeners[i]; - if (defined(listener)) { - listeners[i].apply(scopes[i], arguments); - } - } + // WEBGL_compressed_texture_pvrtc + COMPRESSED_RGB_PVRTC_4BPPV1_IMG : 0x8C00, + COMPRESSED_RGB_PVRTC_2BPPV1_IMG : 0x8C01, + COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : 0x8C02, + COMPRESSED_RGBA_PVRTC_2BPPV1_IMG : 0x8C03, - //Actually remove items removed in removeEventListener. - var toRemove = this._toRemove; - length = toRemove.length; - if (length > 0) { - toRemove.sort(compareNumber); - for (i = 0; i < length; i++) { - var index = toRemove[i]; - listeners.splice(index, 1); - scopes.splice(index, 1); - } - toRemove.length = 0; - } + // WEBGL_compressed_texture_etc1 + COMPRESSED_RGB_ETC1_WEBGL : 0x8D64, - this._insideRaiseEvent = false; - }; + // Desktop OpenGL + DOUBLE : 0x140A, - /** - * A function that removes a listener. - * @callback Event~RemoveCallback - */ + // WebGL 2 + READ_BUFFER : 0x0C02, + UNPACK_ROW_LENGTH : 0x0CF2, + UNPACK_SKIP_ROWS : 0x0CF3, + UNPACK_SKIP_PIXELS : 0x0CF4, + PACK_ROW_LENGTH : 0x0D02, + PACK_SKIP_ROWS : 0x0D03, + PACK_SKIP_PIXELS : 0x0D04, + COLOR : 0x1800, + DEPTH : 0x1801, + STENCIL : 0x1802, + RED : 0x1903, + RGB8 : 0x8051, + RGBA8 : 0x8058, + RGB10_A2 : 0x8059, + TEXTURE_BINDING_3D : 0x806A, + UNPACK_SKIP_IMAGES : 0x806D, + UNPACK_IMAGE_HEIGHT : 0x806E, + TEXTURE_3D : 0x806F, + TEXTURE_WRAP_R : 0x8072, + MAX_3D_TEXTURE_SIZE : 0x8073, + UNSIGNED_INT_2_10_10_10_REV : 0x8368, + MAX_ELEMENTS_VERTICES : 0x80E8, + MAX_ELEMENTS_INDICES : 0x80E9, + TEXTURE_MIN_LOD : 0x813A, + TEXTURE_MAX_LOD : 0x813B, + TEXTURE_BASE_LEVEL : 0x813C, + TEXTURE_MAX_LEVEL : 0x813D, + MIN : 0x8007, + MAX : 0x8008, + DEPTH_COMPONENT24 : 0x81A6, + MAX_TEXTURE_LOD_BIAS : 0x84FD, + TEXTURE_COMPARE_MODE : 0x884C, + TEXTURE_COMPARE_FUNC : 0x884D, + CURRENT_QUERY : 0x8865, + QUERY_RESULT : 0x8866, + QUERY_RESULT_AVAILABLE : 0x8867, + STREAM_READ : 0x88E1, + STREAM_COPY : 0x88E2, + STATIC_READ : 0x88E5, + STATIC_COPY : 0x88E6, + DYNAMIC_READ : 0x88E9, + DYNAMIC_COPY : 0x88EA, + MAX_DRAW_BUFFERS : 0x8824, + DRAW_BUFFER0 : 0x8825, + DRAW_BUFFER1 : 0x8826, + DRAW_BUFFER2 : 0x8827, + DRAW_BUFFER3 : 0x8828, + DRAW_BUFFER4 : 0x8829, + DRAW_BUFFER5 : 0x882A, + DRAW_BUFFER6 : 0x882B, + DRAW_BUFFER7 : 0x882C, + DRAW_BUFFER8 : 0x882D, + DRAW_BUFFER9 : 0x882E, + DRAW_BUFFER10 : 0x882F, + DRAW_BUFFER11 : 0x8830, + DRAW_BUFFER12 : 0x8831, + DRAW_BUFFER13 : 0x8832, + DRAW_BUFFER14 : 0x8833, + DRAW_BUFFER15 : 0x8834, + MAX_FRAGMENT_UNIFORM_COMPONENTS : 0x8B49, + MAX_VERTEX_UNIFORM_COMPONENTS : 0x8B4A, + SAMPLER_3D : 0x8B5F, + SAMPLER_2D_SHADOW : 0x8B62, + FRAGMENT_SHADER_DERIVATIVE_HINT : 0x8B8B, + PIXEL_PACK_BUFFER : 0x88EB, + PIXEL_UNPACK_BUFFER : 0x88EC, + PIXEL_PACK_BUFFER_BINDING : 0x88ED, + PIXEL_UNPACK_BUFFER_BINDING : 0x88EF, + FLOAT_MAT2x3 : 0x8B65, + FLOAT_MAT2x4 : 0x8B66, + FLOAT_MAT3x2 : 0x8B67, + FLOAT_MAT3x4 : 0x8B68, + FLOAT_MAT4x2 : 0x8B69, + FLOAT_MAT4x3 : 0x8B6A, + SRGB : 0x8C40, + SRGB8 : 0x8C41, + SRGB8_ALPHA8 : 0x8C43, + COMPARE_REF_TO_TEXTURE : 0x884E, + RGBA32F : 0x8814, + RGB32F : 0x8815, + RGBA16F : 0x881A, + RGB16F : 0x881B, + VERTEX_ATTRIB_ARRAY_INTEGER : 0x88FD, + MAX_ARRAY_TEXTURE_LAYERS : 0x88FF, + MIN_PROGRAM_TEXEL_OFFSET : 0x8904, + MAX_PROGRAM_TEXEL_OFFSET : 0x8905, + MAX_VARYING_COMPONENTS : 0x8B4B, + TEXTURE_2D_ARRAY : 0x8C1A, + TEXTURE_BINDING_2D_ARRAY : 0x8C1D, + R11F_G11F_B10F : 0x8C3A, + UNSIGNED_INT_10F_11F_11F_REV : 0x8C3B, + RGB9_E5 : 0x8C3D, + UNSIGNED_INT_5_9_9_9_REV : 0x8C3E, + TRANSFORM_FEEDBACK_BUFFER_MODE : 0x8C7F, + MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS : 0x8C80, + TRANSFORM_FEEDBACK_VARYINGS : 0x8C83, + TRANSFORM_FEEDBACK_BUFFER_START : 0x8C84, + TRANSFORM_FEEDBACK_BUFFER_SIZE : 0x8C85, + TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN : 0x8C88, + RASTERIZER_DISCARD : 0x8C89, + MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS : 0x8C8A, + MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS : 0x8C8B, + INTERLEAVED_ATTRIBS : 0x8C8C, + SEPARATE_ATTRIBS : 0x8C8D, + TRANSFORM_FEEDBACK_BUFFER : 0x8C8E, + TRANSFORM_FEEDBACK_BUFFER_BINDING : 0x8C8F, + RGBA32UI : 0x8D70, + RGB32UI : 0x8D71, + RGBA16UI : 0x8D76, + RGB16UI : 0x8D77, + RGBA8UI : 0x8D7C, + RGB8UI : 0x8D7D, + RGBA32I : 0x8D82, + RGB32I : 0x8D83, + RGBA16I : 0x8D88, + RGB16I : 0x8D89, + RGBA8I : 0x8D8E, + RGB8I : 0x8D8F, + RED_INTEGER : 0x8D94, + RGB_INTEGER : 0x8D98, + RGBA_INTEGER : 0x8D99, + SAMPLER_2D_ARRAY : 0x8DC1, + SAMPLER_2D_ARRAY_SHADOW : 0x8DC4, + SAMPLER_CUBE_SHADOW : 0x8DC5, + UNSIGNED_INT_VEC2 : 0x8DC6, + UNSIGNED_INT_VEC3 : 0x8DC7, + UNSIGNED_INT_VEC4 : 0x8DC8, + INT_SAMPLER_2D : 0x8DCA, + INT_SAMPLER_3D : 0x8DCB, + INT_SAMPLER_CUBE : 0x8DCC, + INT_SAMPLER_2D_ARRAY : 0x8DCF, + UNSIGNED_INT_SAMPLER_2D : 0x8DD2, + UNSIGNED_INT_SAMPLER_3D : 0x8DD3, + UNSIGNED_INT_SAMPLER_CUBE : 0x8DD4, + UNSIGNED_INT_SAMPLER_2D_ARRAY : 0x8DD7, + DEPTH_COMPONENT32F : 0x8CAC, + DEPTH32F_STENCIL8 : 0x8CAD, + FLOAT_32_UNSIGNED_INT_24_8_REV : 0x8DAD, + FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : 0x8210, + FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE : 0x8211, + FRAMEBUFFER_ATTACHMENT_RED_SIZE : 0x8212, + FRAMEBUFFER_ATTACHMENT_GREEN_SIZE : 0x8213, + FRAMEBUFFER_ATTACHMENT_BLUE_SIZE : 0x8214, + FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE : 0x8215, + FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE : 0x8216, + FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE : 0x8217, + FRAMEBUFFER_DEFAULT : 0x8218, + UNSIGNED_INT_24_8 : 0x84FA, + DEPTH24_STENCIL8 : 0x88F0, + UNSIGNED_NORMALIZED : 0x8C17, + DRAW_FRAMEBUFFER_BINDING : 0x8CA6, // Same as FRAMEBUFFER_BINDING + READ_FRAMEBUFFER : 0x8CA8, + DRAW_FRAMEBUFFER : 0x8CA9, + READ_FRAMEBUFFER_BINDING : 0x8CAA, + RENDERBUFFER_SAMPLES : 0x8CAB, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER : 0x8CD4, + MAX_COLOR_ATTACHMENTS : 0x8CDF, + COLOR_ATTACHMENT1 : 0x8CE1, + COLOR_ATTACHMENT2 : 0x8CE2, + COLOR_ATTACHMENT3 : 0x8CE3, + COLOR_ATTACHMENT4 : 0x8CE4, + COLOR_ATTACHMENT5 : 0x8CE5, + COLOR_ATTACHMENT6 : 0x8CE6, + COLOR_ATTACHMENT7 : 0x8CE7, + COLOR_ATTACHMENT8 : 0x8CE8, + COLOR_ATTACHMENT9 : 0x8CE9, + COLOR_ATTACHMENT10 : 0x8CEA, + COLOR_ATTACHMENT11 : 0x8CEB, + COLOR_ATTACHMENT12 : 0x8CEC, + COLOR_ATTACHMENT13 : 0x8CED, + COLOR_ATTACHMENT14 : 0x8CEE, + COLOR_ATTACHMENT15 : 0x8CEF, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE : 0x8D56, + MAX_SAMPLES : 0x8D57, + HALF_FLOAT : 0x140B, + RG : 0x8227, + RG_INTEGER : 0x8228, + R8 : 0x8229, + RG8 : 0x822B, + R16F : 0x822D, + R32F : 0x822E, + RG16F : 0x822F, + RG32F : 0x8230, + R8I : 0x8231, + R8UI : 0x8232, + R16I : 0x8233, + R16UI : 0x8234, + R32I : 0x8235, + R32UI : 0x8236, + RG8I : 0x8237, + RG8UI : 0x8238, + RG16I : 0x8239, + RG16UI : 0x823A, + RG32I : 0x823B, + RG32UI : 0x823C, + VERTEX_ARRAY_BINDING : 0x85B5, + R8_SNORM : 0x8F94, + RG8_SNORM : 0x8F95, + RGB8_SNORM : 0x8F96, + RGBA8_SNORM : 0x8F97, + SIGNED_NORMALIZED : 0x8F9C, + COPY_READ_BUFFER : 0x8F36, + COPY_WRITE_BUFFER : 0x8F37, + COPY_READ_BUFFER_BINDING : 0x8F36, // Same as COPY_READ_BUFFER + COPY_WRITE_BUFFER_BINDING : 0x8F37, // Same as COPY_WRITE_BUFFER + UNIFORM_BUFFER : 0x8A11, + UNIFORM_BUFFER_BINDING : 0x8A28, + UNIFORM_BUFFER_START : 0x8A29, + UNIFORM_BUFFER_SIZE : 0x8A2A, + MAX_VERTEX_UNIFORM_BLOCKS : 0x8A2B, + MAX_FRAGMENT_UNIFORM_BLOCKS : 0x8A2D, + MAX_COMBINED_UNIFORM_BLOCKS : 0x8A2E, + MAX_UNIFORM_BUFFER_BINDINGS : 0x8A2F, + MAX_UNIFORM_BLOCK_SIZE : 0x8A30, + MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS : 0x8A31, + MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS : 0x8A33, + UNIFORM_BUFFER_OFFSET_ALIGNMENT : 0x8A34, + ACTIVE_UNIFORM_BLOCKS : 0x8A36, + UNIFORM_TYPE : 0x8A37, + UNIFORM_SIZE : 0x8A38, + UNIFORM_BLOCK_INDEX : 0x8A3A, + UNIFORM_OFFSET : 0x8A3B, + UNIFORM_ARRAY_STRIDE : 0x8A3C, + UNIFORM_MATRIX_STRIDE : 0x8A3D, + UNIFORM_IS_ROW_MAJOR : 0x8A3E, + UNIFORM_BLOCK_BINDING : 0x8A3F, + UNIFORM_BLOCK_DATA_SIZE : 0x8A40, + UNIFORM_BLOCK_ACTIVE_UNIFORMS : 0x8A42, + UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES : 0x8A43, + UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER : 0x8A44, + UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER : 0x8A46, + INVALID_INDEX : 0xFFFFFFFF, + MAX_VERTEX_OUTPUT_COMPONENTS : 0x9122, + MAX_FRAGMENT_INPUT_COMPONENTS : 0x9125, + MAX_SERVER_WAIT_TIMEOUT : 0x9111, + OBJECT_TYPE : 0x9112, + SYNC_CONDITION : 0x9113, + SYNC_STATUS : 0x9114, + SYNC_FLAGS : 0x9115, + SYNC_FENCE : 0x9116, + SYNC_GPU_COMMANDS_COMPLETE : 0x9117, + UNSIGNALED : 0x9118, + SIGNALED : 0x9119, + ALREADY_SIGNALED : 0x911A, + TIMEOUT_EXPIRED : 0x911B, + CONDITION_SATISFIED : 0x911C, + WAIT_FAILED : 0x911D, + SYNC_FLUSH_COMMANDS_BIT : 0x00000001, + VERTEX_ATTRIB_ARRAY_DIVISOR : 0x88FE, + ANY_SAMPLES_PASSED : 0x8C2F, + ANY_SAMPLES_PASSED_CONSERVATIVE : 0x8D6A, + SAMPLER_BINDING : 0x8919, + RGB10_A2UI : 0x906F, + INT_2_10_10_10_REV : 0x8D9F, + TRANSFORM_FEEDBACK : 0x8E22, + TRANSFORM_FEEDBACK_PAUSED : 0x8E23, + TRANSFORM_FEEDBACK_ACTIVE : 0x8E24, + TRANSFORM_FEEDBACK_BINDING : 0x8E25, + COMPRESSED_R11_EAC : 0x9270, + COMPRESSED_SIGNED_R11_EAC : 0x9271, + COMPRESSED_RG11_EAC : 0x9272, + COMPRESSED_SIGNED_RG11_EAC : 0x9273, + COMPRESSED_RGB8_ETC2 : 0x9274, + COMPRESSED_SRGB8_ETC2 : 0x9275, + COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276, + COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277, + COMPRESSED_RGBA8_ETC2_EAC : 0x9278, + COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279, + TEXTURE_IMMUTABLE_FORMAT : 0x912F, + MAX_ELEMENT_INDEX : 0x8D6B, + TEXTURE_IMMUTABLE_LEVELS : 0x82DF, - return Event; + // Extensions + MAX_TEXTURE_MAX_ANISOTROPY_EXT : 0x84FF + }; + + return freezeObject(WebGLConstants); }); -define('Core/GeographicTilingScheme',[ - './Cartesian2', - './Check', +define('Core/ComponentDatatype',[ './defaultValue', './defined', - './defineProperties', - './Ellipsoid', - './GeographicProjection', - './Math', - './Rectangle' + './DeveloperError', + './FeatureDetection', + './freezeObject', + './WebGLConstants' ], function( - Cartesian2, - Check, defaultValue, defined, - defineProperties, - Ellipsoid, - GeographicProjection, - CesiumMath, - Rectangle) { + DeveloperError, + FeatureDetection, + freezeObject, + WebGLConstants) { 'use strict'; + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; + } + /** - * A tiling scheme for geometry referenced to a simple {@link GeographicProjection} where - * longitude and latitude are directly mapped to X and Y. This projection is commonly - * known as geographic, equirectangular, equidistant cylindrical, or plate carrée. - * - * @alias GeographicTilingScheme - * @constructor + * WebGL component datatypes. Components are intrinsics, + * which form attributes, which form vertices. * - * @param {Object} [options] Object with the following properties: - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to - * the WGS84 ellipsoid. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the tiling scheme. - * @param {Number} [options.numberOfLevelZeroTilesX=2] The number of tiles in the X direction at level zero of - * the tile tree. - * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of - * the tile tree. + * @exports ComponentDatatype */ - function GeographicTilingScheme(options) { - options = defaultValue(options, {}); + var ComponentDatatype = { + /** + * 8-bit signed byte corresponding to <code>gl.BYTE</code> and the type + * of an element in <code>Int8Array</code>. + * + * @type {Number} + * @constant + */ + BYTE : WebGLConstants.BYTE, - this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - this._rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE); - this._projection = new GeographicProjection(this._ellipsoid); - this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 2); - this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1); - } + /** + * 8-bit unsigned byte corresponding to <code>UNSIGNED_BYTE</code> and the type + * of an element in <code>Uint8Array</code>. + * + * @type {Number} + * @constant + */ + UNSIGNED_BYTE : WebGLConstants.UNSIGNED_BYTE, - defineProperties(GeographicTilingScheme.prototype, { /** - * Gets the ellipsoid that is tiled by this tiling scheme. - * @memberof GeographicTilingScheme.prototype - * @type {Ellipsoid} + * 16-bit signed short corresponding to <code>SHORT</code> and the type + * of an element in <code>Int16Array</code>. + * + * @type {Number} + * @constant */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } - }, + SHORT : WebGLConstants.SHORT, /** - * Gets the rectangle, in radians, covered by this tiling scheme. - * @memberof GeographicTilingScheme.prototype - * @type {Rectangle} + * 16-bit unsigned short corresponding to <code>UNSIGNED_SHORT</code> and the type + * of an element in <code>Uint16Array</code>. + * + * @type {Number} + * @constant */ - rectangle : { - get : function() { - return this._rectangle; - } - }, + UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT, /** - * Gets the map projection used by this tiling scheme. - * @memberof GeographicTilingScheme.prototype - * @type {MapProjection} + * 32-bit signed int corresponding to <code>INT</code> and the type + * of an element in <code>Int32Array</code>. + * + * @memberOf ComponentDatatype + * + * @type {Number} + * @constant */ - projection : { - get : function() { - return this._projection; - } - } - }); + INT : WebGLConstants.INT, - /** - * Gets the total number of tiles in the X direction at a specified level-of-detail. - * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the X direction at the given level. - */ - GeographicTilingScheme.prototype.getNumberOfXTilesAtLevel = function(level) { - return this._numberOfLevelZeroTilesX << level; + /** + * 32-bit unsigned int corresponding to <code>UNSIGNED_INT</code> and the type + * of an element in <code>Uint32Array</code>. + * + * @memberOf ComponentDatatype + * + * @type {Number} + * @constant + */ + UNSIGNED_INT : WebGLConstants.UNSIGNED_INT, + + /** + * 32-bit floating-point corresponding to <code>FLOAT</code> and the type + * of an element in <code>Float32Array</code>. + * + * @type {Number} + * @constant + */ + FLOAT : WebGLConstants.FLOAT, + + /** + * 64-bit floating-point corresponding to <code>gl.DOUBLE</code> (in Desktop OpenGL; + * this is not supported in WebGL, and is emulated in Cesium via {@link GeometryPipeline.encodeAttribute}) + * and the type of an element in <code>Float64Array</code>. + * + * @memberOf ComponentDatatype + * + * @type {Number} + * @constant + * @default 0x140A + */ + DOUBLE : WebGLConstants.DOUBLE }; /** - * Gets the total number of tiles in the Y direction at a specified level-of-detail. + * Returns the size, in bytes, of the corresponding datatype. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the Y direction at the given level. + * @param {ComponentDatatype} componentDatatype The component datatype to get the size of. + * @returns {Number} The size in bytes. + * + * @exception {DeveloperError} componentDatatype is not a valid value. + * + * @example + * // Returns Int8Array.BYTES_PER_ELEMENT + * var size = Cesium.ComponentDatatype.getSizeInBytes(Cesium.ComponentDatatype.BYTE); */ - GeographicTilingScheme.prototype.getNumberOfYTilesAtLevel = function(level) { - return this._numberOfLevelZeroTilesY << level; + ComponentDatatype.getSizeInBytes = function(componentDatatype){ + if (!defined(componentDatatype)) { + throw new DeveloperError('value is required.'); + } + + switch (componentDatatype) { + case ComponentDatatype.BYTE: + return Int8Array.BYTES_PER_ELEMENT; + case ComponentDatatype.UNSIGNED_BYTE: + return Uint8Array.BYTES_PER_ELEMENT; + case ComponentDatatype.SHORT: + return Int16Array.BYTES_PER_ELEMENT; + case ComponentDatatype.UNSIGNED_SHORT: + return Uint16Array.BYTES_PER_ELEMENT; + case ComponentDatatype.INT: + return Int32Array.BYTES_PER_ELEMENT; + case ComponentDatatype.UNSIGNED_INT: + return Uint32Array.BYTES_PER_ELEMENT; + case ComponentDatatype.FLOAT: + return Float32Array.BYTES_PER_ELEMENT; + case ComponentDatatype.DOUBLE: + return Float64Array.BYTES_PER_ELEMENT; + default: + throw new DeveloperError('componentDatatype is not a valid value.'); + } }; /** - * Transforms a rectangle specified in geodetic radians to the native coordinate system - * of this tiling scheme. + * Gets the {@link ComponentDatatype} for the provided TypedArray instance. * - * @param {Rectangle} rectangle The rectangle to transform. - * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result' - * is undefined. + * @param {TypedArray} array The typed array. + * @returns {ComponentDatatype} The ComponentDatatype for the provided array, or undefined if the array is not a TypedArray. */ - GeographicTilingScheme.prototype.rectangleToNativeRectangle = function(rectangle, result) { - Check.defined('rectangle', rectangle); - - var west = CesiumMath.toDegrees(rectangle.west); - var south = CesiumMath.toDegrees(rectangle.south); - var east = CesiumMath.toDegrees(rectangle.east); - var north = CesiumMath.toDegrees(rectangle.north); - - if (!defined(result)) { - return new Rectangle(west, south, east, north); + ComponentDatatype.fromTypedArray = function(array) { + if (array instanceof Int8Array) { + return ComponentDatatype.BYTE; + } + if (array instanceof Uint8Array) { + return ComponentDatatype.UNSIGNED_BYTE; + } + if (array instanceof Int16Array) { + return ComponentDatatype.SHORT; + } + if (array instanceof Uint16Array) { + return ComponentDatatype.UNSIGNED_SHORT; + } + if (array instanceof Int32Array) { + return ComponentDatatype.INT; + } + if (array instanceof Uint32Array) { + return ComponentDatatype.UNSIGNED_INT; + } + if (array instanceof Float32Array) { + return ComponentDatatype.FLOAT; + } + if (array instanceof Float64Array) { + return ComponentDatatype.DOUBLE; } - - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; }; /** - * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates - * of the tiling scheme. + * Validates that the provided component datatype is a valid {@link ComponentDatatype} * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the rectangle - * if 'result' is undefined. + * @param {ComponentDatatype} componentDatatype The component datatype to validate. + * @returns {Boolean} <code>true</code> if the provided component datatype is a valid value; otherwise, <code>false</code>. + * + * @example + * if (!Cesium.ComponentDatatype.validate(componentDatatype)) { + * throw new Cesium.DeveloperError('componentDatatype must be a valid value.'); + * } */ - GeographicTilingScheme.prototype.tileXYToNativeRectangle = function(x, y, level, result) { - var rectangleRadians = this.tileXYToRectangle(x, y, level, result); - rectangleRadians.west = CesiumMath.toDegrees(rectangleRadians.west); - rectangleRadians.south = CesiumMath.toDegrees(rectangleRadians.south); - rectangleRadians.east = CesiumMath.toDegrees(rectangleRadians.east); - rectangleRadians.north = CesiumMath.toDegrees(rectangleRadians.north); - return rectangleRadians; + ComponentDatatype.validate = function(componentDatatype) { + return defined(componentDatatype) && + (componentDatatype === ComponentDatatype.BYTE || + componentDatatype === ComponentDatatype.UNSIGNED_BYTE || + componentDatatype === ComponentDatatype.SHORT || + componentDatatype === ComponentDatatype.UNSIGNED_SHORT || + componentDatatype === ComponentDatatype.INT || + componentDatatype === ComponentDatatype.UNSIGNED_INT || + componentDatatype === ComponentDatatype.FLOAT || + componentDatatype === ComponentDatatype.DOUBLE); }; /** - * Converts tile x, y coordinates and level to a cartographic rectangle in radians. + * Creates a typed array corresponding to component data type. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the rectangle - * if 'result' is undefined. + * @param {ComponentDatatype} componentDatatype The component data type. + * @param {Number|Array} valuesOrLength The length of the array to create or an array. + * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array. + * + * @exception {DeveloperError} componentDatatype is not a valid value. + * + * @example + * // creates a Float32Array with length of 100 + * var typedArray = Cesium.ComponentDatatype.createTypedArray(Cesium.ComponentDatatype.FLOAT, 100); */ - GeographicTilingScheme.prototype.tileXYToRectangle = function(x, y, level, result) { - var rectangle = this._rectangle; + ComponentDatatype.createTypedArray = function(componentDatatype, valuesOrLength) { + if (!defined(componentDatatype)) { + throw new DeveloperError('componentDatatype is required.'); + } + if (!defined(valuesOrLength)) { + throw new DeveloperError('valuesOrLength is required.'); + } + + switch (componentDatatype) { + case ComponentDatatype.BYTE: + return new Int8Array(valuesOrLength); + case ComponentDatatype.UNSIGNED_BYTE: + return new Uint8Array(valuesOrLength); + case ComponentDatatype.SHORT: + return new Int16Array(valuesOrLength); + case ComponentDatatype.UNSIGNED_SHORT: + return new Uint16Array(valuesOrLength); + case ComponentDatatype.INT: + return new Int32Array(valuesOrLength); + case ComponentDatatype.UNSIGNED_INT: + return new Uint32Array(valuesOrLength); + case ComponentDatatype.FLOAT: + return new Float32Array(valuesOrLength); + case ComponentDatatype.DOUBLE: + return new Float64Array(valuesOrLength); + default: + throw new DeveloperError('componentDatatype is not a valid value.'); + } + }; - var xTiles = this.getNumberOfXTilesAtLevel(level); - var yTiles = this.getNumberOfYTilesAtLevel(level); + /** + * Creates a typed view of an array of bytes. + * + * @param {ComponentDatatype} componentDatatype The type of the view to create. + * @param {ArrayBuffer} buffer The buffer storage to use for the view. + * @param {Number} [byteOffset] The offset, in bytes, to the first element in the view. + * @param {Number} [length] The number of elements in the view. + * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array view of the buffer. + * + * @exception {DeveloperError} componentDatatype is not a valid value. + */ + ComponentDatatype.createArrayBufferView = function(componentDatatype, buffer, byteOffset, length) { + if (!defined(componentDatatype)) { + throw new DeveloperError('componentDatatype is required.'); + } + if (!defined(buffer)) { + throw new DeveloperError('buffer is required.'); + } + + byteOffset = defaultValue(byteOffset, 0); + length = defaultValue(length, (buffer.byteLength - byteOffset) / ComponentDatatype.getSizeInBytes(componentDatatype)); - var xTileWidth = rectangle.width / xTiles; - var west = x * xTileWidth + rectangle.west; - var east = (x + 1) * xTileWidth + rectangle.west; + switch (componentDatatype) { + case ComponentDatatype.BYTE: + return new Int8Array(buffer, byteOffset, length); + case ComponentDatatype.UNSIGNED_BYTE: + return new Uint8Array(buffer, byteOffset, length); + case ComponentDatatype.SHORT: + return new Int16Array(buffer, byteOffset, length); + case ComponentDatatype.UNSIGNED_SHORT: + return new Uint16Array(buffer, byteOffset, length); + case ComponentDatatype.INT: + return new Int32Array(buffer, byteOffset, length); + case ComponentDatatype.UNSIGNED_INT: + return new Uint32Array(buffer, byteOffset, length); + case ComponentDatatype.FLOAT: + return new Float32Array(buffer, byteOffset, length); + case ComponentDatatype.DOUBLE: + return new Float64Array(buffer, byteOffset, length); + default: + throw new DeveloperError('componentDatatype is not a valid value.'); + } + }; - var yTileHeight = rectangle.height / yTiles; - var north = rectangle.north - y * yTileHeight; - var south = rectangle.north - (y + 1) * yTileHeight; + /** + * Get the ComponentDatatype from its name. + * + * @param {String} name The name of the ComponentDatatype. + * @returns {ComponentDatatype} The ComponentDatatype. + * + * @exception {DeveloperError} name is not a valid value. + */ + ComponentDatatype.fromName = function(name) { + switch (name) { + case 'BYTE': + return ComponentDatatype.BYTE; + case 'UNSIGNED_BYTE': + return ComponentDatatype.UNSIGNED_BYTE; + case 'SHORT': + return ComponentDatatype.SHORT; + case 'UNSIGNED_SHORT': + return ComponentDatatype.UNSIGNED_SHORT; + case 'INT': + return ComponentDatatype.INT; + case 'UNSIGNED_INT': + return ComponentDatatype.UNSIGNED_INT; + case 'FLOAT': + return ComponentDatatype.FLOAT; + case 'DOUBLE': + return ComponentDatatype.DOUBLE; + default: + throw new DeveloperError('name is not a valid value.'); + } + }; - if (!defined(result)) { - result = new Rectangle(west, south, east, north); - } + return freezeObject(ComponentDatatype); +}); - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; +define('Core/GeometryType',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * @private + */ + var GeometryType = { + NONE : 0, + TRIANGLES : 1, + LINES : 2, + POLYLINES : 3 }; + return freezeObject(GeometryType); +}); + +define('Core/PrimitiveType',[ + './freezeObject', + './WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + /** - * Calculates the tile x, y coordinates of the tile containing - * a given cartographic position. + * The type of a geometric primitive, i.e., points, lines, and triangles. * - * @param {Cartographic} position The position. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates - * if 'result' is undefined. + * @exports PrimitiveType */ - GeographicTilingScheme.prototype.positionToTileXY = function(position, level, result) { - var rectangle = this._rectangle; - if (!Rectangle.contains(rectangle, position)) { - // outside the bounds of the tiling scheme - return undefined; - } + var PrimitiveType = { + /** + * Points primitive where each vertex (or index) is a separate point. + * + * @type {Number} + * @constant + */ + POINTS : WebGLConstants.POINTS, - var xTiles = this.getNumberOfXTilesAtLevel(level); - var yTiles = this.getNumberOfYTilesAtLevel(level); + /** + * Lines primitive where each two vertices (or indices) is a line segment. Line segments are not necessarily connected. + * + * @type {Number} + * @constant + */ + LINES : WebGLConstants.LINES, - var xTileWidth = rectangle.width / xTiles; - var yTileHeight = rectangle.height / yTiles; + /** + * Line loop primitive where each vertex (or index) after the first connects a line to + * the previous vertex, and the last vertex implicitly connects to the first. + * + * @type {Number} + * @constant + */ + LINE_LOOP : WebGLConstants.LINE_LOOP, - var longitude = position.longitude; - if (rectangle.east < rectangle.west) { - longitude += CesiumMath.TWO_PI; - } + /** + * Line strip primitive where each vertex (or index) after the first connects a line to the previous vertex. + * + * @type {Number} + * @constant + */ + LINE_STRIP : WebGLConstants.LINE_STRIP, - var xTileCoordinate = (longitude - rectangle.west) / xTileWidth | 0; - if (xTileCoordinate >= xTiles) { - xTileCoordinate = xTiles - 1; - } + /** + * Triangles primitive where each three vertices (or indices) is a triangle. Triangles do not necessarily share edges. + * + * @type {Number} + * @constant + */ + TRIANGLES : WebGLConstants.TRIANGLES, - var yTileCoordinate = (rectangle.north - position.latitude) / yTileHeight | 0; - if (yTileCoordinate >= yTiles) { - yTileCoordinate = yTiles - 1; - } + /** + * Triangle strip primitive where each vertex (or index) after the first two connect to + * the previous two vertices forming a triangle. For example, this can be used to model a wall. + * + * @type {Number} + * @constant + */ + TRIANGLE_STRIP : WebGLConstants.TRIANGLE_STRIP, - if (!defined(result)) { - return new Cartesian2(xTileCoordinate, yTileCoordinate); - } + /** + * Triangle fan primitive where each vertex (or index) after the first two connect to + * the previous vertex and the first vertex forming a triangle. For example, this can be used + * to model a cone or circle. + * + * @type {Number} + * @constant + */ + TRIANGLE_FAN : WebGLConstants.TRIANGLE_FAN, - result.x = xTileCoordinate; - result.y = yTileCoordinate; - return result; + /** + * @private + */ + validate : function(primitiveType) { + return primitiveType === PrimitiveType.POINTS || + primitiveType === PrimitiveType.LINES || + primitiveType === PrimitiveType.LINE_LOOP || + primitiveType === PrimitiveType.LINE_STRIP || + primitiveType === PrimitiveType.TRIANGLES || + primitiveType === PrimitiveType.TRIANGLE_STRIP || + primitiveType === PrimitiveType.TRIANGLE_FAN; + } }; - return GeographicTilingScheme; + return freezeObject(PrimitiveType); }); -define('Core/EllipsoidalOccluder',[ - './BoundingSphere', - './Cartesian3', +define('Core/Geometry',[ './Check', './defaultValue', './defined', - './defineProperties', - './Rectangle' + './DeveloperError', + './GeometryType', + './PrimitiveType' ], function( - BoundingSphere, - Cartesian3, Check, defaultValue, defined, - defineProperties, - Rectangle) { + DeveloperError, + GeometryType, + PrimitiveType) { 'use strict'; /** - * Determine whether or not other objects are visible or hidden behind the visible horizon defined by - * an {@link Ellipsoid} and a camera position. The ellipsoid is assumed to be located at the - * origin of the coordinate system. This class uses the algorithm described in the - * {@link http://cesiumjs.org/2013/04/25/Horizon-culling/|Horizon Culling} blog post. + * A geometry representation with attributes forming vertices and optional index data + * defining primitives. Geometries and an {@link Appearance}, which describes the shading, + * can be assigned to a {@link Primitive} for visualization. A <code>Primitive</code> can + * be created from many heterogeneous - in many cases - geometries for performance. + * <p> + * Geometries can be transformed and optimized using functions in {@link GeometryPipeline}. + * </p> * - * @alias EllipsoidalOccluder + * @alias Geometry + * @constructor * - * @param {Ellipsoid} ellipsoid The ellipsoid to use as an occluder. - * @param {Cartesian3} [cameraPosition] The coordinate of the viewer/camera. If this parameter is not - * specified, {@link EllipsoidalOccluder#cameraPosition} must be called before - * testing visibility. + * @param {Object} options Object with the following properties: + * @param {GeometryAttributes} options.attributes Attributes, which make up the geometry's vertices. + * @param {PrimitiveType} [options.primitiveType=PrimitiveType.TRIANGLES] The type of primitives in the geometry. + * @param {Uint16Array|Uint32Array} [options.indices] Optional index data that determines the primitives in the geometry. + * @param {BoundingSphere} [options.boundingSphere] An optional bounding sphere that fully enclosed the geometry. * - * @constructor + * @see PolygonGeometry + * @see RectangleGeometry + * @see EllipseGeometry + * @see CircleGeometry + * @see WallGeometry + * @see SimplePolylineGeometry + * @see BoxGeometry + * @see EllipsoidGeometry + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example - * // Construct an ellipsoidal occluder with radii 1.0, 1.1, and 0.9. - * var cameraPosition = new Cesium.Cartesian3(5.0, 6.0, 7.0); - * var occluderEllipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9); - * var occluder = new Cesium.EllipsoidalOccluder(occluderEllipsoid, cameraPosition); + * // Create geometry with a position attribute and indexed lines. + * var positions = new Float64Array([ + * 0.0, 0.0, 0.0, + * 7500000.0, 0.0, 0.0, + * 0.0, 7500000.0, 0.0 + * ]); * - * @private + * var geometry = new Cesium.Geometry({ + * attributes : { + * position : new Cesium.GeometryAttribute({ + * componentDatatype : Cesium.ComponentDatatype.DOUBLE, + * componentsPerAttribute : 3, + * values : positions + * }) + * }, + * indices : new Uint16Array([0, 1, 1, 2, 2, 0]), + * primitiveType : Cesium.PrimitiveType.LINES, + * boundingSphere : Cesium.BoundingSphere.fromVertices(positions) + * }); */ - function EllipsoidalOccluder(ellipsoid, cameraPosition) { - Check.typeOf.object('ellipsoid', ellipsoid); - - this._ellipsoid = ellipsoid; - this._cameraPosition = new Cartesian3(); - this._cameraPositionInScaledSpace = new Cartesian3(); - this._distanceToLimbInScaledSpaceSquared = 0.0; + function Geometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - // cameraPosition fills in the above values - if (defined(cameraPosition)) { - this.cameraPosition = cameraPosition; - } - } + Check.typeOf.object('options.attributes', options.attributes); + + /** + * Attributes, which make up the geometry's vertices. Each property in this object corresponds to a + * {@link GeometryAttribute} containing the attribute's data. + * <p> + * Attributes are always stored non-interleaved in a Geometry. + * </p> + * <p> + * There are reserved attribute names with well-known semantics. The following attributes + * are created by a Geometry (depending on the provided {@link VertexFormat}. + * <ul> + * <li><code>position</code> - 3D vertex position. 64-bit floating-point (for precision). 3 components per attribute. See {@link VertexFormat#position}.</li> + * <li><code>normal</code> - Normal (normalized), commonly used for lighting. 32-bit floating-point. 3 components per attribute. See {@link VertexFormat#normal}.</li> + * <li><code>st</code> - 2D texture coordinate. 32-bit floating-point. 2 components per attribute. See {@link VertexFormat#st}.</li> + * <li><code>bitangent</code> - Bitangent (normalized), used for tangent-space effects like bump mapping. 32-bit floating-point. 3 components per attribute. See {@link VertexFormat#bitangent}.</li> + * <li><code>tangent</code> - Tangent (normalized), used for tangent-space effects like bump mapping. 32-bit floating-point. 3 components per attribute. See {@link VertexFormat#tangent}.</li> + * </ul> + * </p> + * <p> + * The following attribute names are generally not created by a Geometry, but are added + * to a Geometry by a {@link Primitive} or {@link GeometryPipeline} functions to prepare + * the geometry for rendering. + * <ul> + * <li><code>position3DHigh</code> - High 32 bits for encoded 64-bit position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> + * <li><code>position3DLow</code> - Low 32 bits for encoded 64-bit position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> + * <li><code>position3DHigh</code> - High 32 bits for encoded 64-bit 2D (Columbus view) position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> + * <li><code>position2DLow</code> - Low 32 bits for encoded 64-bit 2D (Columbus view) position computed with {@link GeometryPipeline.encodeAttribute}. 32-bit floating-point. 4 components per attribute.</li> + * <li><code>color</code> - RGBA color (normalized) usually from {@link GeometryInstance#color}. 32-bit floating-point. 4 components per attribute.</li> + * <li><code>pickColor</code> - RGBA color used for picking. 32-bit floating-point. 4 components per attribute.</li> + * </ul> + * </p> + * + * @type GeometryAttributes + * + * @default undefined + * + * + * @example + * geometry.attributes.position = new Cesium.GeometryAttribute({ + * componentDatatype : Cesium.ComponentDatatype.FLOAT, + * componentsPerAttribute : 3, + * values : new Float32Array(0) + * }); + * + * @see GeometryAttribute + * @see VertexFormat + */ + this.attributes = options.attributes; - defineProperties(EllipsoidalOccluder.prototype, { /** - * Gets the occluding ellipsoid. - * @memberof EllipsoidalOccluder.prototype - * @type {Ellipsoid} + * Optional index data that - along with {@link Geometry#primitiveType} - + * determines the primitives in the geometry. + * + * @type Array + * + * @default undefined */ - ellipsoid : { - get: function() { - return this._ellipsoid; - } - }, + this.indices = options.indices; + /** - * Gets or sets the position of the camera. - * @memberof EllipsoidalOccluder.prototype - * @type {Cartesian3} + * The type of primitives in the geometry. This is most often {@link PrimitiveType.TRIANGLES}, + * but can varying based on the specific geometry. + * + * @type PrimitiveType + * + * @default undefined */ - cameraPosition : { - get : function() { - return this._cameraPosition; - }, - set : function(cameraPosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ - var ellipsoid = this._ellipsoid; - var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace); - var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0; + this.primitiveType = defaultValue(options.primitiveType, PrimitiveType.TRIANGLES); - Cartesian3.clone(cameraPosition, this._cameraPosition); - this._cameraPositionInScaledSpace = cv; - this._distanceToLimbInScaledSpaceSquared = vhMagnitudeSquared; - } - } - }); + /** + * An optional bounding sphere that fully encloses the geometry. This is + * commonly used for culling. + * + * @type BoundingSphere + * + * @default undefined + */ + this.boundingSphere = options.boundingSphere; - var scratchCartesian = new Cartesian3(); + /** + * @private + */ + this.geometryType = defaultValue(options.geometryType, GeometryType.NONE); - /** - * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder. - * - * @param {Cartesian3} occludee The point to test for visibility. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. - * - * @example - * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5); - * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9); - * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition); - * var point = new Cesium.Cartesian3(0, -3, -3); - * occluder.isPointVisible(point); //returns true - */ - EllipsoidalOccluder.prototype.isPointVisible = function(occludee) { - var ellipsoid = this._ellipsoid; - var occludeeScaledSpacePosition = ellipsoid.transformPositionToScaledSpace(occludee, scratchCartesian); - return this.isScaledSpacePointVisible(occludeeScaledSpacePosition); - }; + /** + * @private + */ + this.boundingSphereCV = options.boundingSphereCV; + } /** - * Determines whether or not a point expressed in the ellipsoid scaled space, is hidden from view by the - * occluder. To transform a Cartesian X, Y, Z position in the coordinate system aligned with the ellipsoid - * into the scaled space, call {@link Ellipsoid#transformPositionToScaledSpace}. + * Computes the number of vertices in a geometry. The runtime is linear with + * respect to the number of attributes in a vertex, not the number of vertices. * - * @param {Cartesian3} occludeeScaledSpacePosition The point to test for visibility, represented in the scaled space. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * @param {Geometry} geometry The geometry. + * @returns {Number} The number of vertices in the geometry. * * @example - * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5); - * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9); - * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition); - * var point = new Cesium.Cartesian3(0, -3, -3); - * var scaledSpacePoint = ellipsoid.transformPositionToScaledSpace(point); - * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true - */ - EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ - var cv = this._cameraPositionInScaledSpace; - var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared; - var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian); - var vtDotVc = -Cartesian3.dot(vt, cv); - // If vhMagnitudeSquared < 0 then we are below the surface of the ellipsoid and - // in this case, set the culling plane to be on V. - var isOccluded = vhMagnitudeSquared < 0 ? vtDotVc > 0 : (vtDotVc > vhMagnitudeSquared && - vtDotVc * vtDotVc / Cartesian3.magnitudeSquared(vt) > vhMagnitudeSquared); - return !isOccluded; - }; - - /** - * Computes a point that can be used for horizon culling from a list of positions. If the point is below - * the horizon, all of the positions are guaranteed to be below the horizon as well. The returned point - * is expressed in the ellipsoid-scaled space and is suitable for use with - * {@link EllipsoidalOccluder#isScaledSpacePointVisible}. - * - * @param {Cartesian3} directionToPoint The direction that the computed point will lie along. - * A reasonable direction to use is the direction from the center of the ellipsoid to - * the center of the bounding sphere computed from the positions. The direction need not - * be normalized. - * @param {Cartesian3[]} positions The positions from which to compute the horizon culling point. The positions - * must be expressed in a reference frame centered at the ellipsoid and aligned with the - * ellipsoid's axes. - * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. - * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. + * var numVertices = Cesium.Geometry.computeNumberOfVertices(geometry); */ - EllipsoidalOccluder.prototype.computeHorizonCullingPoint = function(directionToPoint, positions, result) { - Check.typeOf.object('directionToPoint', directionToPoint); - Check.defined('positions', positions); + Geometry.computeNumberOfVertices = function(geometry) { + Check.typeOf.object('geometry', geometry); - if (!defined(result)) { - result = new Cartesian3(); - } - - var ellipsoid = this._ellipsoid; - var scaledSpaceDirectionToPoint = computeScaledSpaceDirectionToPoint(ellipsoid, directionToPoint); - var resultMagnitude = 0.0; + var numberOfVertices = -1; + for ( var property in geometry.attributes) { + if (geometry.attributes.hasOwnProperty(property) && + defined(geometry.attributes[property]) && + defined(geometry.attributes[property].values)) { - for (var i = 0, len = positions.length; i < len; ++i) { - var position = positions[i]; - var candidateMagnitude = computeMagnitude(ellipsoid, position, scaledSpaceDirectionToPoint); - resultMagnitude = Math.max(resultMagnitude, candidateMagnitude); + var attribute = geometry.attributes[property]; + var num = attribute.values.length / attribute.componentsPerAttribute; + if ((numberOfVertices !== num) && (numberOfVertices !== -1)) { + throw new DeveloperError('All attribute lists must have the same number of attributes.'); + } + numberOfVertices = num; + } } - return magnitudeToPoint(scaledSpaceDirectionToPoint, resultMagnitude, result); + return numberOfVertices; }; - var positionScratch = new Cartesian3(); + return Geometry; +}); + +define('Core/GeometryAttribute',[ + './defaultValue', + './defined', + './DeveloperError' + ], function( + defaultValue, + defined, + DeveloperError) { + 'use strict'; /** - * Computes a point that can be used for horizon culling from a list of positions. If the point is below - * the horizon, all of the positions are guaranteed to be below the horizon as well. The returned point - * is expressed in the ellipsoid-scaled space and is suitable for use with - * {@link EllipsoidalOccluder#isScaledSpacePointVisible}. + * Values and type information for geometry attributes. A {@link Geometry} + * generally contains one or more attributes. All attributes together form + * the geometry's vertices. * - * @param {Cartesian3} directionToPoint The direction that the computed point will lie along. - * A reasonable direction to use is the direction from the center of the ellipsoid to - * the center of the bounding sphere computed from the positions. The direction need not - * be normalized. - * @param {Number[]} vertices The vertices from which to compute the horizon culling point. The positions - * must be expressed in a reference frame centered at the ellipsoid and aligned with the - * ellipsoid's axes. - * @param {Number} [stride=3] - * @param {Cartesian3} [center=Cartesian3.ZERO] - * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. - * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. + * @alias GeometryAttribute + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {ComponentDatatype} [options.componentDatatype] The datatype of each component in the attribute, e.g., individual elements in values. + * @param {Number} [options.componentsPerAttribute] A number between 1 and 4 that defines the number of components in an attributes. + * @param {Boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * @param {TypedArray} [options.values] The values for the attributes stored in a typed array. + * + * @exception {DeveloperError} options.componentsPerAttribute must be between 1 and 4. + * + * + * @example + * var geometry = new Cesium.Geometry({ + * attributes : { + * position : new Cesium.GeometryAttribute({ + * componentDatatype : Cesium.ComponentDatatype.FLOAT, + * componentsPerAttribute : 3, + * values : new Float32Array([ + * 0.0, 0.0, 0.0, + * 7500000.0, 0.0, 0.0, + * 0.0, 7500000.0, 0.0 + * ]) + * }) + * }, + * primitiveType : Cesium.PrimitiveType.LINE_LOOP + * }); + * + * @see Geometry */ - EllipsoidalOccluder.prototype.computeHorizonCullingPointFromVertices = function(directionToPoint, vertices, stride, center, result) { - Check.typeOf.object('directionToPoint', directionToPoint); - Check.defined('vertices', vertices); - Check.typeOf.number('stride', stride); - - if (!defined(result)) { - result = new Cartesian3(); + function GeometryAttribute(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + if (!defined(options.componentDatatype)) { + throw new DeveloperError('options.componentDatatype is required.'); + } + if (!defined(options.componentsPerAttribute)) { + throw new DeveloperError('options.componentsPerAttribute is required.'); } + if (options.componentsPerAttribute < 1 || options.componentsPerAttribute > 4) { + throw new DeveloperError('options.componentsPerAttribute must be between 1 and 4.'); + } + if (!defined(options.values)) { + throw new DeveloperError('options.values is required.'); + } + + /** + * The datatype of each component in the attribute, e.g., individual elements in + * {@link GeometryAttribute#values}. + * + * @type ComponentDatatype + * + * @default undefined + */ + this.componentDatatype = options.componentDatatype; - center = defaultValue(center, Cartesian3.ZERO); - var ellipsoid = this._ellipsoid; - var scaledSpaceDirectionToPoint = computeScaledSpaceDirectionToPoint(ellipsoid, directionToPoint); - var resultMagnitude = 0.0; + /** + * A number between 1 and 4 that defines the number of components in an attributes. + * For example, a position attribute with x, y, and z components would have 3 as + * shown in the code example. + * + * @type Number + * + * @default undefined + * + * @example + * attribute.componentDatatype = Cesium.ComponentDatatype.FLOAT; + * attribute.componentsPerAttribute = 3; + * attribute.values = new Float32Array([ + * 0.0, 0.0, 0.0, + * 7500000.0, 0.0, 0.0, + * 0.0, 7500000.0, 0.0 + * ]); + */ + this.componentsPerAttribute = options.componentsPerAttribute; - for (var i = 0, len = vertices.length; i < len; i += stride) { - positionScratch.x = vertices[i] + center.x; - positionScratch.y = vertices[i + 1] + center.y; - positionScratch.z = vertices[i + 2] + center.z; + /** + * When <code>true</code> and <code>componentDatatype</code> is an integer format, + * indicate that the components should be mapped to the range [0, 1] (unsigned) + * or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * <p> + * This is commonly used when storing colors using {@link ComponentDatatype.UNSIGNED_BYTE}. + * </p> + * + * @type Boolean + * + * @default false + * + * @example + * attribute.componentDatatype = Cesium.ComponentDatatype.UNSIGNED_BYTE; + * attribute.componentsPerAttribute = 4; + * attribute.normalize = true; + * attribute.values = new Uint8Array([ + * Cesium.Color.floatToByte(color.red), + * Cesium.Color.floatToByte(color.green), + * Cesium.Color.floatToByte(color.blue), + * Cesium.Color.floatToByte(color.alpha) + * ]); + */ + this.normalize = defaultValue(options.normalize, false); - var candidateMagnitude = computeMagnitude(ellipsoid, positionScratch, scaledSpaceDirectionToPoint); - resultMagnitude = Math.max(resultMagnitude, candidateMagnitude); - } + /** + * The values for the attributes stored in a typed array. In the code example, + * every three elements in <code>values</code> defines one attributes since + * <code>componentsPerAttribute</code> is 3. + * + * @type TypedArray + * + * @default undefined + * + * @example + * attribute.componentDatatype = Cesium.ComponentDatatype.FLOAT; + * attribute.componentsPerAttribute = 3; + * attribute.values = new Float32Array([ + * 0.0, 0.0, 0.0, + * 7500000.0, 0.0, 0.0, + * 0.0, 7500000.0, 0.0 + * ]); + */ + this.values = options.values; + } - return magnitudeToPoint(scaledSpaceDirectionToPoint, resultMagnitude, result); - }; + return GeometryAttribute; +}); - var subsampleScratch = []; +define('Core/GeometryAttributes',[ + './defaultValue' + ], function( + defaultValue) { + 'use strict'; /** - * Computes a point that can be used for horizon culling of a rectangle. If the point is below - * the horizon, the ellipsoid-conforming rectangle is guaranteed to be below the horizon as well. - * The returned point is expressed in the ellipsoid-scaled space and is suitable for use with - * {@link EllipsoidalOccluder#isScaledSpacePointVisible}. + * Attributes, which make up a geometry's vertices. Each property in this object corresponds to a + * {@link GeometryAttribute} containing the attribute's data. + * <p> + * Attributes are always stored non-interleaved in a Geometry. + * </p> * - * @param {Rectangle} rectangle The rectangle for which to compute the horizon culling point. - * @param {Ellipsoid} ellipsoid The ellipsoid on which the rectangle is defined. This may be different from - * the ellipsoid used by this instance for occlusion testing. - * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. - * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. + * @alias GeometryAttributes + * @constructor */ - EllipsoidalOccluder.prototype.computeHorizonCullingPointFromRectangle = function(rectangle, ellipsoid, result) { - Check.typeOf.object('rectangle', rectangle); - - var positions = Rectangle.subsample(rectangle, ellipsoid, 0.0, subsampleScratch); - var bs = BoundingSphere.fromPoints(positions); - - // If the bounding sphere center is too close to the center of the occluder, it doesn't make - // sense to try to horizon cull it. - if (Cartesian3.magnitude(bs.center) < 0.1 * ellipsoid.minimumRadius) { - return undefined; - } - - return this.computeHorizonCullingPoint(bs.center, positions, result); - }; - - var scaledSpaceScratch = new Cartesian3(); - var directionScratch = new Cartesian3(); - - function computeMagnitude(ellipsoid, position, scaledSpaceDirectionToPoint) { - var scaledSpacePosition = ellipsoid.transformPositionToScaledSpace(position, scaledSpaceScratch); - var magnitudeSquared = Cartesian3.magnitudeSquared(scaledSpacePosition); - var magnitude = Math.sqrt(magnitudeSquared); - var direction = Cartesian3.divideByScalar(scaledSpacePosition, magnitude, directionScratch); - - // For the purpose of this computation, points below the ellipsoid are consider to be on it instead. - magnitudeSquared = Math.max(1.0, magnitudeSquared); - magnitude = Math.max(1.0, magnitude); - - var cosAlpha = Cartesian3.dot(direction, scaledSpaceDirectionToPoint); - var sinAlpha = Cartesian3.magnitude(Cartesian3.cross(direction, scaledSpaceDirectionToPoint, direction)); - var cosBeta = 1.0 / magnitude; - var sinBeta = Math.sqrt(magnitudeSquared - 1.0) * cosBeta; + function GeometryAttributes(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - return 1.0 / (cosAlpha * cosBeta - sinAlpha * sinBeta); - } + /** + * The 3D position attribute. + * <p> + * 64-bit floating-point (for precision). 3 components per attribute. + * </p> + * + * @type GeometryAttribute + * + * @default undefined + */ + this.position = options.position; - function magnitudeToPoint(scaledSpaceDirectionToPoint, resultMagnitude, result) { - // The horizon culling point is undefined if there were no positions from which to compute it, - // the directionToPoint is pointing opposite all of the positions, or if we computed NaN or infinity. - if (resultMagnitude <= 0.0 || resultMagnitude === 1.0 / 0.0 || resultMagnitude !== resultMagnitude) { - return undefined; - } + /** + * The normal attribute (normalized), which is commonly used for lighting. + * <p> + * 32-bit floating-point. 3 components per attribute. + * </p> + * + * @type GeometryAttribute + * + * @default undefined + */ + this.normal = options.normal; - return Cartesian3.multiplyByScalar(scaledSpaceDirectionToPoint, resultMagnitude, result); - } + /** + * The 2D texture coordinate attribute. + * <p> + * 32-bit floating-point. 2 components per attribute + * </p> + * + * @type GeometryAttribute + * + * @default undefined + */ + this.st = options.st; - var directionToPointScratch = new Cartesian3(); + /** + * The bitangent attribute (normalized), which is used for tangent-space effects like bump mapping. + * <p> + * 32-bit floating-point. 3 components per attribute. + * </p> + * + * @type GeometryAttribute + * + * @default undefined + */ + this.bitangent = options.bitangent; - function computeScaledSpaceDirectionToPoint(ellipsoid, directionToPoint) { - if (Cartesian3.equals(directionToPoint, Cartesian3.ZERO)) { - return directionToPoint; - } + /** + * The tangent attribute (normalized), which is used for tangent-space effects like bump mapping. + * <p> + * 32-bit floating-point. 3 components per attribute. + * </p> + * + * @type GeometryAttribute + * + * @default undefined + */ + this.tangent = options.tangent; - ellipsoid.transformPositionToScaledSpace(directionToPoint, directionToPointScratch); - return Cartesian3.normalize(directionToPointScratch, directionToPointScratch); + /** + * The color attribute. + * <p> + * 8-bit unsigned integer. 4 components per attribute. + * </p> + * + * @type GeometryAttribute + * + * @default undefined + */ + this.color = options.color; } - return EllipsoidalOccluder; + return GeometryAttributes; }); -define('Core/QuadraticRealPolynomial',[ +define('Core/VertexFormat',[ + './defaultValue', + './defined', './DeveloperError', - './Math' + './freezeObject' ], function( + defaultValue, + defined, DeveloperError, - CesiumMath) { + freezeObject) { 'use strict'; /** - * Defines functions for 2nd order polynomial functions of one variable with only real coefficients. + * A vertex format defines what attributes make up a vertex. A VertexFormat can be provided + * to a {@link Geometry} to request that certain properties be computed, e.g., just position, + * position and normal, etc. * - * @exports QuadraticRealPolynomial - */ - var QuadraticRealPolynomial = {}; - - /** - * Provides the discriminant of the quadratic equation from the supplied coefficients. + * @param {Object} [options] An object with boolean properties corresponding to VertexFormat properties as shown in the code example. * - * @param {Number} a The coefficient of the 2nd order monomial. - * @param {Number} b The coefficient of the 1st order monomial. - * @param {Number} c The coefficient of the 0th order monomial. - * @returns {Number} The value of the discriminant. - */ - QuadraticRealPolynomial.computeDiscriminant = function(a, b, c) { - if (typeof a !== 'number') { - throw new DeveloperError('a is a required number.'); - } - if (typeof b !== 'number') { - throw new DeveloperError('b is a required number.'); - } - if (typeof c !== 'number') { - throw new DeveloperError('c is a required number.'); - } - - var discriminant = b * b - 4.0 * a * c; - return discriminant; - }; - - function addWithCancellationCheck(left, right, tolerance) { - var difference = left + right; - if ((CesiumMath.sign(left) !== CesiumMath.sign(right)) && - Math.abs(difference / Math.max(Math.abs(left), Math.abs(right))) < tolerance) { - return 0.0; - } - - return difference; - } - - /** - * Provides the real valued roots of the quadratic polynomial with the provided coefficients. + * @alias VertexFormat + * @constructor * - * @param {Number} a The coefficient of the 2nd order monomial. - * @param {Number} b The coefficient of the 1st order monomial. - * @param {Number} c The coefficient of the 0th order monomial. - * @returns {Number[]} The real valued roots. + * @example + * // Create a vertex format with position and 2D texture coordinate attributes. + * var format = new Cesium.VertexFormat({ + * position : true, + * st : true + * }); + * + * @see Geometry#attributes + * @see Packable */ - QuadraticRealPolynomial.computeRealRoots = function(a, b, c) { - if (typeof a !== 'number') { - throw new DeveloperError('a is a required number.'); - } - if (typeof b !== 'number') { - throw new DeveloperError('b is a required number.'); - } - if (typeof c !== 'number') { - throw new DeveloperError('c is a required number.'); - } - - var ratio; - if (a === 0.0) { - if (b === 0.0) { - // Constant function: c = 0. - return []; - } + function VertexFormat(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - // Linear function: b * x + c = 0. - return [-c / b]; - } else if (b === 0.0) { - if (c === 0.0) { - // 2nd order monomial: a * x^2 = 0. - return [0.0, 0.0]; - } + /** + * When <code>true</code>, the vertex has a 3D position attribute. + * <p> + * 64-bit floating-point (for precision). 3 components per attribute. + * </p> + * + * @type Boolean + * + * @default false + */ + this.position = defaultValue(options.position, false); - var cMagnitude = Math.abs(c); - var aMagnitude = Math.abs(a); + /** + * When <code>true</code>, the vertex has a normal attribute (normalized), which is commonly used for lighting. + * <p> + * 32-bit floating-point. 3 components per attribute. + * </p> + * + * @type Boolean + * + * @default false + */ + this.normal = defaultValue(options.normal, false); - if ((cMagnitude < aMagnitude) && (cMagnitude / aMagnitude < CesiumMath.EPSILON14)) { // c ~= 0.0. - // 2nd order monomial: a * x^2 = 0. - return [0.0, 0.0]; - } else if ((cMagnitude > aMagnitude) && (aMagnitude / cMagnitude < CesiumMath.EPSILON14)) { // a ~= 0.0. - // Constant function: c = 0. - return []; - } - - // a * x^2 + c = 0 - ratio = -c / a; - - if (ratio < 0.0) { - // Both roots are complex. - return []; - } - - // Both roots are real. - var root = Math.sqrt(ratio); - return [-root, root]; - } else if (c === 0.0) { - // a * x^2 + b * x = 0 - ratio = -b / a; - if (ratio < 0.0) { - return [ratio, 0.0]; - } - - return [0.0, ratio]; - } - - // a * x^2 + b * x + c = 0 - var b2 = b * b; - var four_ac = 4.0 * a * c; - var radicand = addWithCancellationCheck(b2, -four_ac, CesiumMath.EPSILON14); - - if (radicand < 0.0) { - // Both roots are complex. - return []; - } - - var q = -0.5 * addWithCancellationCheck(b, CesiumMath.sign(b) * Math.sqrt(radicand), CesiumMath.EPSILON14); - if (b > 0.0) { - return [q / a, c / q]; - } + /** + * When <code>true</code>, the vertex has a 2D texture coordinate attribute. + * <p> + * 32-bit floating-point. 2 components per attribute + * </p> + * + * @type Boolean + * + * @default false + */ + this.st = defaultValue(options.st, false); - return [c / q, q / a]; - }; + /** + * When <code>true</code>, the vertex has a bitangent attribute (normalized), which is used for tangent-space effects like bump mapping. + * <p> + * 32-bit floating-point. 3 components per attribute. + * </p> + * + * @type Boolean + * + * @default false + */ + this.bitangent = defaultValue(options.bitangent, false); - return QuadraticRealPolynomial; -}); + /** + * When <code>true</code>, the vertex has a tangent attribute (normalized), which is used for tangent-space effects like bump mapping. + * <p> + * 32-bit floating-point. 3 components per attribute. + * </p> + * + * @type Boolean + * + * @default false + */ + this.tangent = defaultValue(options.tangent, false); -define('Core/CubicRealPolynomial',[ - './DeveloperError', - './QuadraticRealPolynomial' - ], function( - DeveloperError, - QuadraticRealPolynomial) { - 'use strict'; + /** + * When <code>true</code>, the vertex has an RGB color attribute. + * <p> + * 8-bit unsigned byte. 3 components per attribute. + * </p> + * + * @type Boolean + * + * @default false + */ + this.color = defaultValue(options.color, false); + } /** - * Defines functions for 3rd order polynomial functions of one variable with only real coefficients. + * An immutable vertex format with only a position attribute. * - * @exports CubicRealPolynomial + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position */ - var CubicRealPolynomial = {}; + VertexFormat.POSITION_ONLY = freezeObject(new VertexFormat({ + position : true + })); /** - * Provides the discriminant of the cubic equation from the supplied coefficients. + * An immutable vertex format with position and normal attributes. + * This is compatible with per-instance color appearances like {@link PerInstanceColorAppearance}. * - * @param {Number} a The coefficient of the 3rd order monomial. - * @param {Number} b The coefficient of the 2nd order monomial. - * @param {Number} c The coefficient of the 1st order monomial. - * @param {Number} d The coefficient of the 0th order monomial. - * @returns {Number} The value of the discriminant. + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position + * @see VertexFormat#normal */ - CubicRealPolynomial.computeDiscriminant = function(a, b, c, d) { - if (typeof a !== 'number') { - throw new DeveloperError('a is a required number.'); - } - if (typeof b !== 'number') { - throw new DeveloperError('b is a required number.'); - } - if (typeof c !== 'number') { - throw new DeveloperError('c is a required number.'); - } - if (typeof d !== 'number') { - throw new DeveloperError('d is a required number.'); - } - - var a2 = a * a; - var b2 = b * b; - var c2 = c * c; - var d2 = d * d; - - var discriminant = 18.0 * a * b * c * d + b2 * c2 - 27.0 * a2 * d2 - 4.0 * (a * c2 * c + b2 * b * d); - return discriminant; - }; - - function computeRealRoots(a, b, c, d) { - var A = a; - var B = b / 3.0; - var C = c / 3.0; - var D = d; - - var AC = A * C; - var BD = B * D; - var B2 = B * B; - var C2 = C * C; - var delta1 = A * C - B2; - var delta2 = A * D - B * C; - var delta3 = B * D - C2; - - var discriminant = 4.0 * delta1 * delta3 - delta2 * delta2; - var temp; - var temp1; - - if (discriminant < 0.0) { - var ABar; - var CBar; - var DBar; - - if (B2 * BD >= AC * C2) { - ABar = A; - CBar = delta1; - DBar = -2.0 * B * delta1 + A * delta2; - } else { - ABar = D; - CBar = delta3; - DBar = -D * delta2 + 2.0 * C * delta3; - } - - var s = (DBar < 0.0) ? -1.0 : 1.0; // This is not Math.Sign()! - var temp0 = -s * Math.abs(ABar) * Math.sqrt(-discriminant); - temp1 = -DBar + temp0; - - var x = temp1 / 2.0; - var p = x < 0.0 ? -Math.pow(-x, 1.0 / 3.0) : Math.pow(x, 1.0 / 3.0); - var q = (temp1 === temp0) ? -p : -CBar / p; - - temp = (CBar <= 0.0) ? p + q : -DBar / (p * p + q * q + CBar); - - if (B2 * BD >= AC * C2) { - return [(temp - B) / A]; - } - - return [-D / (temp + C)]; - } - - var CBarA = delta1; - var DBarA = -2.0 * B * delta1 + A * delta2; - - var CBarD = delta3; - var DBarD = -D * delta2 + 2.0 * C * delta3; - - var squareRootOfDiscriminant = Math.sqrt(discriminant); - var halfSquareRootOf3 = Math.sqrt(3.0) / 2.0; - - var theta = Math.abs(Math.atan2(A * squareRootOfDiscriminant, -DBarA) / 3.0); - temp = 2.0 * Math.sqrt(-CBarA); - var cosine = Math.cos(theta); - temp1 = temp * cosine; - var temp3 = temp * (-cosine / 2.0 - halfSquareRootOf3 * Math.sin(theta)); - - var numeratorLarge = (temp1 + temp3 > 2.0 * B) ? temp1 - B : temp3 - B; - var denominatorLarge = A; - - var root1 = numeratorLarge / denominatorLarge; + VertexFormat.POSITION_AND_NORMAL = freezeObject(new VertexFormat({ + position : true, + normal : true + })); - theta = Math.abs(Math.atan2(D * squareRootOfDiscriminant, -DBarD) / 3.0); - temp = 2.0 * Math.sqrt(-CBarD); - cosine = Math.cos(theta); - temp1 = temp * cosine; - temp3 = temp * (-cosine / 2.0 - halfSquareRootOf3 * Math.sin(theta)); + /** + * An immutable vertex format with position, normal, and st attributes. + * This is compatible with {@link MaterialAppearance} when {@link MaterialAppearance#materialSupport} + * is <code>TEXTURED/code>. + * + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position + * @see VertexFormat#normal + * @see VertexFormat#st + */ + VertexFormat.POSITION_NORMAL_AND_ST = freezeObject(new VertexFormat({ + position : true, + normal : true, + st : true + })); - var numeratorSmall = -D; - var denominatorSmall = (temp1 + temp3 < 2.0 * C) ? temp1 + C : temp3 + C; + /** + * An immutable vertex format with position and st attributes. + * This is compatible with {@link EllipsoidSurfaceAppearance}. + * + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position + * @see VertexFormat#st + */ + VertexFormat.POSITION_AND_ST = freezeObject(new VertexFormat({ + position : true, + st : true + })); - var root3 = numeratorSmall / denominatorSmall; + /** + * An immutable vertex format with position and color attributes. + * + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position + * @see VertexFormat#color + */ + VertexFormat.POSITION_AND_COLOR = freezeObject(new VertexFormat({ + position : true, + color : true + })); - var E = denominatorLarge * denominatorSmall; - var F = -numeratorLarge * denominatorSmall - denominatorLarge * numeratorSmall; - var G = numeratorLarge * numeratorSmall; + /** + * An immutable vertex format with well-known attributes: position, normal, st, tangent, and bitangent. + * + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position + * @see VertexFormat#normal + * @see VertexFormat#st + * @see VertexFormat#tangent + * @see VertexFormat#bitangent + */ + VertexFormat.ALL = freezeObject(new VertexFormat({ + position : true, + normal : true, + st : true, + tangent : true, + bitangent : true + })); - var root2 = (C * F - B * G) / (-B * F + C * E); + /** + * An immutable vertex format with position, normal, and st attributes. + * This is compatible with most appearances and materials; however + * normal and st attributes are not always required. When this is + * known in advance, another <code>VertexFormat</code> should be used. + * + * @type {VertexFormat} + * @constant + * + * @see VertexFormat#position + * @see VertexFormat#normal + */ + VertexFormat.DEFAULT = VertexFormat.POSITION_NORMAL_AND_ST; - if (root1 <= root2) { - if (root1 <= root3) { - if (root2 <= root3) { - return [root1, root2, root3]; - } - return [root1, root3, root2]; - } - return [root3, root1, root2]; - } - if (root1 <= root3) { - return [root2, root1, root3]; - } - if (root2 <= root3) { - return [root2, root3, root1]; - } - return [root3, root2, root1]; - } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + VertexFormat.packedLength = 6; /** - * Provides the real valued roots of the cubic polynomial with the provided coefficients. + * Stores the provided instance into the provided array. * - * @param {Number} a The coefficient of the 3rd order monomial. - * @param {Number} b The coefficient of the 2nd order monomial. - * @param {Number} c The coefficient of the 1st order monomial. - * @param {Number} d The coefficient of the 0th order monomial. - * @returns {Number[]} The real valued roots. + * @param {VertexFormat} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - CubicRealPolynomial.computeRealRoots = function(a, b, c, d) { - if (typeof a !== 'number') { - throw new DeveloperError('a is a required number.'); - } - if (typeof b !== 'number') { - throw new DeveloperError('b is a required number.'); - } - if (typeof c !== 'number') { - throw new DeveloperError('c is a required number.'); + VertexFormat.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); } - if (typeof d !== 'number') { - throw new DeveloperError('d is a required number.'); + if (!defined(array)) { + throw new DeveloperError('array is required'); } - var roots; - var ratio; - if (a === 0.0) { - // Quadratic function: b * x^2 + c * x + d = 0. - return QuadraticRealPolynomial.computeRealRoots(b, c, d); - } else if (b === 0.0) { - if (c === 0.0) { - if (d === 0.0) { - // 3rd order monomial: a * x^3 = 0. - return [0.0, 0.0, 0.0]; - } - - // a * x^3 + d = 0 - ratio = -d / a; - var root = (ratio < 0.0) ? -Math.pow(-ratio, 1.0 / 3.0) : Math.pow(ratio, 1.0 / 3.0); - return [root, root, root]; - } else if (d === 0.0) { - // x * (a * x^2 + c) = 0. - roots = QuadraticRealPolynomial.computeRealRoots(a, 0, c); - - // Return the roots in ascending order. - if (roots.Length === 0) { - return [0.0]; - } - return [roots[0], 0.0, roots[1]]; - } - - // Deflated cubic polynomial: a * x^3 + c * x + d= 0. - return computeRealRoots(a, 0, c, d); - } else if (c === 0.0) { - if (d === 0.0) { - // x^2 * (a * x + b) = 0. - ratio = -b / a; - if (ratio < 0.0) { - return [ratio, 0.0, 0.0]; - } - return [0.0, 0.0, ratio]; - } - // a * x^3 + b * x^2 + d = 0. - return computeRealRoots(a, b, 0, d); - } else if (d === 0.0) { - // x * (a * x^2 + b * x + c) = 0 - roots = QuadraticRealPolynomial.computeRealRoots(a, b, c); + startingIndex = defaultValue(startingIndex, 0); - // Return the roots in ascending order. - if (roots.length === 0) { - return [0.0]; - } else if (roots[1] <= 0.0) { - return [roots[0], roots[1], 0.0]; - } else if (roots[0] >= 0.0) { - return [0.0, roots[0], roots[1]]; - } - return [roots[0], 0.0, roots[1]]; - } + array[startingIndex++] = value.position ? 1.0 : 0.0; + array[startingIndex++] = value.normal ? 1.0 : 0.0; + array[startingIndex++] = value.st ? 1.0 : 0.0; + array[startingIndex++] = value.tangent ? 1.0 : 0.0; + array[startingIndex++] = value.bitangent ? 1.0 : 0.0; + array[startingIndex] = value.color ? 1.0 : 0.0; - return computeRealRoots(a, b, c, d); + return array; }; - return CubicRealPolynomial; -}); - -define('Core/QuarticRealPolynomial',[ - './CubicRealPolynomial', - './DeveloperError', - './Math', - './QuadraticRealPolynomial' - ], function( - CubicRealPolynomial, - DeveloperError, - CesiumMath, - QuadraticRealPolynomial) { - 'use strict'; - - /** - * Defines functions for 4th order polynomial functions of one variable with only real coefficients. - * - * @exports QuarticRealPolynomial - */ - var QuarticRealPolynomial = {}; - /** - * Provides the discriminant of the quartic equation from the supplied coefficients. + * Retrieves an instance from a packed array. * - * @param {Number} a The coefficient of the 4th order monomial. - * @param {Number} b The coefficient of the 3rd order monomial. - * @param {Number} c The coefficient of the 2nd order monomial. - * @param {Number} d The coefficient of the 1st order monomial. - * @param {Number} e The coefficient of the 0th order monomial. - * @returns {Number} The value of the discriminant. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {VertexFormat} [result] The object into which to store the result. + * @returns {VertexFormat} The modified result parameter or a new VertexFormat instance if one was not provided. */ - QuarticRealPolynomial.computeDiscriminant = function(a, b, c, d, e) { - if (typeof a !== 'number') { - throw new DeveloperError('a is a required number.'); - } - if (typeof b !== 'number') { - throw new DeveloperError('b is a required number.'); - } - if (typeof c !== 'number') { - throw new DeveloperError('c is a required number.'); - } - if (typeof d !== 'number') { - throw new DeveloperError('d is a required number.'); - } - if (typeof e !== 'number') { - throw new DeveloperError('e is a required number.'); + VertexFormat.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); } - var a2 = a * a; - var a3 = a2 * a; - var b2 = b * b; - var b3 = b2 * b; - var c2 = c * c; - var c3 = c2 * c; - var d2 = d * d; - var d3 = d2 * d; - var e2 = e * e; - var e3 = e2 * e; - - var discriminant = (b2 * c2 * d2 - 4.0 * b3 * d3 - 4.0 * a * c3 * d2 + 18 * a * b * c * d3 - 27.0 * a2 * d2 * d2 + 256.0 * a3 * e3) + - e * (18.0 * b3 * c * d - 4.0 * b2 * c3 + 16.0 * a * c2 * c2 - 80.0 * a * b * c2 * d - 6.0 * a * b2 * d2 + 144.0 * a2 * c * d2) + - e2 * (144.0 * a * b2 * c - 27.0 * b2 * b2 - 128.0 * a2 * c2 - 192.0 * a2 * b * d); - return discriminant; - }; - - function original(a3, a2, a1, a0) { - var a3Squared = a3 * a3; - - var p = a2 - 3.0 * a3Squared / 8.0; - var q = a1 - a2 * a3 / 2.0 + a3Squared * a3 / 8.0; - var r = a0 - a1 * a3 / 4.0 + a2 * a3Squared / 16.0 - 3.0 * a3Squared * a3Squared / 256.0; - - // Find the roots of the cubic equations: h^6 + 2 p h^4 + (p^2 - 4 r) h^2 - q^2 = 0. - var cubicRoots = CubicRealPolynomial.computeRealRoots(1.0, 2.0 * p, p * p - 4.0 * r, -q * q); - - if (cubicRoots.length > 0) { - var temp = -a3 / 4.0; - - // Use the largest positive root. - var hSquared = cubicRoots[cubicRoots.length - 1]; - - if (Math.abs(hSquared) < CesiumMath.EPSILON14) { - // y^4 + p y^2 + r = 0. - var roots = QuadraticRealPolynomial.computeRealRoots(1.0, p, r); - - if (roots.length === 2) { - var root0 = roots[0]; - var root1 = roots[1]; - - var y; - if (root0 >= 0.0 && root1 >= 0.0) { - var y0 = Math.sqrt(root0); - var y1 = Math.sqrt(root1); - - return [temp - y1, temp - y0, temp + y0, temp + y1]; - } else if (root0 >= 0.0 && root1 < 0.0) { - y = Math.sqrt(root0); - return [temp - y, temp + y]; - } else if (root0 < 0.0 && root1 >= 0.0) { - y = Math.sqrt(root1); - return [temp - y, temp + y]; - } - } - return []; - } else if (hSquared > 0.0) { - var h = Math.sqrt(hSquared); - - var m = (p + hSquared - q / h) / 2.0; - var n = (p + hSquared + q / h) / 2.0; - - // Now solve the two quadratic factors: (y^2 + h y + m)(y^2 - h y + n); - var roots1 = QuadraticRealPolynomial.computeRealRoots(1.0, h, m); - var roots2 = QuadraticRealPolynomial.computeRealRoots(1.0, -h, n); - - if (roots1.length !== 0) { - roots1[0] += temp; - roots1[1] += temp; - - if (roots2.length !== 0) { - roots2[0] += temp; - roots2[1] += temp; - - if (roots1[1] <= roots2[0]) { - return [roots1[0], roots1[1], roots2[0], roots2[1]]; - } else if (roots2[1] <= roots1[0]) { - return [roots2[0], roots2[1], roots1[0], roots1[1]]; - } else if (roots1[0] >= roots2[0] && roots1[1] <= roots2[1]) { - return [roots2[0], roots1[0], roots1[1], roots2[1]]; - } else if (roots2[0] >= roots1[0] && roots2[1] <= roots1[1]) { - return [roots1[0], roots2[0], roots2[1], roots1[1]]; - } else if (roots1[0] > roots2[0] && roots1[0] < roots2[1]) { - return [roots2[0], roots1[0], roots2[1], roots1[1]]; - } - return [roots1[0], roots2[0], roots1[1], roots2[1]]; - } - return roots1; - } - - if (roots2.length !== 0) { - roots2[0] += temp; - roots2[1] += temp; + startingIndex = defaultValue(startingIndex, 0); - return roots2; - } - return []; - } + if (!defined(result)) { + result = new VertexFormat(); } - return []; - } - - function neumark(a3, a2, a1, a0) { - var a1Squared = a1 * a1; - var a2Squared = a2 * a2; - var a3Squared = a3 * a3; - - var p = -2.0 * a2; - var q = a1 * a3 + a2Squared - 4.0 * a0; - var r = a3Squared * a0 - a1 * a2 * a3 + a1Squared; - - var cubicRoots = CubicRealPolynomial.computeRealRoots(1.0, p, q, r); - - if (cubicRoots.length > 0) { - // Use the most positive root - var y = cubicRoots[0]; - - var temp = (a2 - y); - var tempSquared = temp * temp; - - var g1 = a3 / 2.0; - var h1 = temp / 2.0; - - var m = tempSquared - 4.0 * a0; - var mError = tempSquared + 4.0 * Math.abs(a0); - - var n = a3Squared - 4.0 * y; - var nError = a3Squared + 4.0 * Math.abs(y); - - var g2; - var h2; - - if (y < 0.0 || (m * nError < n * mError)) { - var squareRootOfN = Math.sqrt(n); - g2 = squareRootOfN / 2.0; - h2 = squareRootOfN === 0.0 ? 0.0 : (a3 * h1 - a1) / squareRootOfN; - } else { - var squareRootOfM = Math.sqrt(m); - g2 = squareRootOfM === 0.0 ? 0.0 : (a3 * h1 - a1) / squareRootOfM; - h2 = squareRootOfM / 2.0; - } - - var G; - var g; - if (g1 === 0.0 && g2 === 0.0) { - G = 0.0; - g = 0.0; - } else if (CesiumMath.sign(g1) === CesiumMath.sign(g2)) { - G = g1 + g2; - g = y / G; - } else { - g = g1 - g2; - G = y / g; - } - - var H; - var h; - if (h1 === 0.0 && h2 === 0.0) { - H = 0.0; - h = 0.0; - } else if (CesiumMath.sign(h1) === CesiumMath.sign(h2)) { - H = h1 + h2; - h = a0 / H; - } else { - h = h1 - h2; - H = a0 / h; - } - // Now solve the two quadratic factors: (y^2 + G y + H)(y^2 + g y + h); - var roots1 = QuadraticRealPolynomial.computeRealRoots(1.0, G, H); - var roots2 = QuadraticRealPolynomial.computeRealRoots(1.0, g, h); - - if (roots1.length !== 0) { - if (roots2.length !== 0) { - if (roots1[1] <= roots2[0]) { - return [roots1[0], roots1[1], roots2[0], roots2[1]]; - } else if (roots2[1] <= roots1[0]) { - return [roots2[0], roots2[1], roots1[0], roots1[1]]; - } else if (roots1[0] >= roots2[0] && roots1[1] <= roots2[1]) { - return [roots2[0], roots1[0], roots1[1], roots2[1]]; - } else if (roots2[0] >= roots1[0] && roots2[1] <= roots1[1]) { - return [roots1[0], roots2[0], roots2[1], roots1[1]]; - } else if (roots1[0] > roots2[0] && roots1[0] < roots2[1]) { - return [roots2[0], roots1[0], roots2[1], roots1[1]]; - } - return [roots1[0], roots2[0], roots1[1], roots2[1]]; - } - return roots1; - } - if (roots2.length !== 0) { - return roots2; - } - } - return []; - } + result.position = array[startingIndex++] === 1.0; + result.normal = array[startingIndex++] === 1.0; + result.st = array[startingIndex++] === 1.0; + result.tangent = array[startingIndex++] === 1.0; + result.bitangent = array[startingIndex++] === 1.0; + result.color = array[startingIndex] === 1.0; + return result; + }; /** - * Provides the real valued roots of the quartic polynomial with the provided coefficients. + * Duplicates a VertexFormat instance. * - * @param {Number} a The coefficient of the 4th order monomial. - * @param {Number} b The coefficient of the 3rd order monomial. - * @param {Number} c The coefficient of the 2nd order monomial. - * @param {Number} d The coefficient of the 1st order monomial. - * @param {Number} e The coefficient of the 0th order monomial. - * @returns {Number[]} The real valued roots. + * @param {VertexFormat} vertexFormat The vertex format to duplicate. + * @param {VertexFormat} [result] The object onto which to store the result. + * @returns {VertexFormat} The modified result parameter or a new VertexFormat instance if one was not provided. (Returns undefined if vertexFormat is undefined) */ - QuarticRealPolynomial.computeRealRoots = function(a, b, c, d, e) { - if (typeof a !== 'number') { - throw new DeveloperError('a is a required number.'); - } - if (typeof b !== 'number') { - throw new DeveloperError('b is a required number.'); - } - if (typeof c !== 'number') { - throw new DeveloperError('c is a required number.'); - } - if (typeof d !== 'number') { - throw new DeveloperError('d is a required number.'); - } - if (typeof e !== 'number') { - throw new DeveloperError('e is a required number.'); + VertexFormat.clone = function(vertexFormat, result) { + if (!defined(vertexFormat)) { + return undefined; } - - if (Math.abs(a) < CesiumMath.EPSILON15) { - return CubicRealPolynomial.computeRealRoots(b, c, d, e); + if (!defined(result)) { + result = new VertexFormat(); } - var a3 = b / a; - var a2 = c / a; - var a1 = d / a; - var a0 = e / a; - - var k = (a3 < 0.0) ? 1 : 0; - k += (a2 < 0.0) ? k + 1 : k; - k += (a1 < 0.0) ? k + 1 : k; - k += (a0 < 0.0) ? k + 1 : k; - switch (k) { - case 0: - return original(a3, a2, a1, a0); - case 1: - return neumark(a3, a2, a1, a0); - case 2: - return neumark(a3, a2, a1, a0); - case 3: - return original(a3, a2, a1, a0); - case 4: - return original(a3, a2, a1, a0); - case 5: - return neumark(a3, a2, a1, a0); - case 6: - return original(a3, a2, a1, a0); - case 7: - return original(a3, a2, a1, a0); - case 8: - return neumark(a3, a2, a1, a0); - case 9: - return original(a3, a2, a1, a0); - case 10: - return original(a3, a2, a1, a0); - case 11: - return neumark(a3, a2, a1, a0); - case 12: - return original(a3, a2, a1, a0); - case 13: - return original(a3, a2, a1, a0); - case 14: - return original(a3, a2, a1, a0); - case 15: - return original(a3, a2, a1, a0); - default: - return undefined; - } + result.position = vertexFormat.position; + result.normal = vertexFormat.normal; + result.st = vertexFormat.st; + result.tangent = vertexFormat.tangent; + result.bitangent = vertexFormat.bitangent; + result.color = vertexFormat.color; + return result; }; - return QuarticRealPolynomial; + return VertexFormat; }); -define('Core/Ray',[ +define('Core/BoxGeometry',[ + './BoundingSphere', './Cartesian3', + './Check', + './ComponentDatatype', './defaultValue', './defined', - './DeveloperError' + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './PrimitiveType', + './VertexFormat' ], function( + BoundingSphere, Cartesian3, + Check, + ComponentDatatype, defaultValue, defined, - DeveloperError) { + Geometry, + GeometryAttribute, + GeometryAttributes, + PrimitiveType, + VertexFormat) { 'use strict'; + var diffScratch = new Cartesian3(); + /** - * Represents a ray that extends infinitely from the provided origin in the provided direction. - * @alias Ray + * Describes a cube centered at the origin. + * + * @alias BoxGeometry * @constructor * - * @param {Cartesian3} [origin=Cartesian3.ZERO] The origin of the ray. - * @param {Cartesian3} [direction=Cartesian3.ZERO] The direction of the ray. + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.minimum The minimum x, y, and z coordinates of the box. + * @param {Cartesian3} options.maximum The maximum x, y, and z coordinates of the box. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * + * @see BoxGeometry.fromDimensions + * @see BoxGeometry.createGeometry + * @see Packable + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo} + * + * @example + * var box = new Cesium.BoxGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, + * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0), + * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0) + * }); + * var geometry = Cesium.BoxGeometry.createGeometry(box); */ - function Ray(origin, direction) { - direction = Cartesian3.clone(defaultValue(direction, Cartesian3.ZERO)); - if (!Cartesian3.equals(direction, Cartesian3.ZERO)) { - Cartesian3.normalize(direction, direction); - } + function BoxGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The origin of the ray. - * @type {Cartesian3} - * @default {@link Cartesian3.ZERO} - */ - this.origin = Cartesian3.clone(defaultValue(origin, Cartesian3.ZERO)); + var min = options.minimum; + var max = options.maximum; - /** - * The direction of the ray. - * @type {Cartesian3} - */ - this.direction = direction; + Check.typeOf.object('min', min); + Check.typeOf.object('max', max); + + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + + this._minimum = Cartesian3.clone(min); + this._maximum = Cartesian3.clone(max); + this._vertexFormat = vertexFormat; + this._workerName = 'createBoxGeometry'; } /** - * Computes the point along the ray given by r(t) = o + t*d, - * where o is the origin of the ray and d is the direction. + * Creates a cube centered at the origin given its dimensions. + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.dimensions The width, depth, and height of the box stored in the x, y, and z coordinates of the <code>Cartesian3</code>, respectively. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @returns {BoxGeometry} + * + * @exception {DeveloperError} All dimensions components must be greater than or equal to zero. * - * @param {Ray} ray The ray. - * @param {Number} t A scalar value. - * @param {Cartesian3} [result] The object in which the result will be stored. - * @returns {Cartesian3} The modified result parameter, or a new instance if none was provided. * * @example - * //Get the first intersection point of a ray and an ellipsoid. - * var intersection = Cesium.IntersectionTests.rayEllipsoid(ray, ellipsoid); - * var point = Cesium.Ray.getPoint(ray, intersection.start); + * var box = Cesium.BoxGeometry.fromDimensions({ + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, + * dimensions : new Cesium.Cartesian3(500000.0, 500000.0, 500000.0) + * }); + * var geometry = Cesium.BoxGeometry.createGeometry(box); + * + * @see BoxGeometry.createGeometry */ - Ray.getPoint = function(ray, t, result) { - if (!defined(ray)){ - throw new DeveloperError('ray is requred'); - } - if (typeof t !== 'number') { - throw new DeveloperError('t is a required number'); - } + BoxGeometry.fromDimensions = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var dimensions = options.dimensions; + + Check.typeOf.object('dimensions', dimensions); + Check.typeOf.number.greaterThanOrEquals('dimensions.x', dimensions.x, 0); + Check.typeOf.number.greaterThanOrEquals('dimensions.y', dimensions.y, 0); + Check.typeOf.number.greaterThanOrEquals('dimensions.z', dimensions.z, 0); - if (!defined(result)) { - result = new Cartesian3(); - } + var corner = Cartesian3.multiplyByScalar(dimensions, 0.5, new Cartesian3()); - result = Cartesian3.multiplyByScalar(ray.direction, t, result); - return Cartesian3.add(ray.origin, result, result); + return new BoxGeometry({ + minimum : Cartesian3.negate(corner, new Cartesian3()), + maximum : corner, + vertexFormat : options.vertexFormat + }); }; - return Ray; -}); + /** + * Creates a cube from the dimensions of an AxisAlignedBoundingBox. + * + * @param {AxisAlignedBoundingBox} boundingBox A description of the AxisAlignedBoundingBox. + * @returns {BoxGeometry} + * + * + * + * @example + * var aabb = Cesium.AxisAlignedBoundingBox.fromPoints(Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ])); + * var box = Cesium.BoxGeometry.fromAxisAlignedBoundingBox(aabb); + * + * @see BoxGeometry.createGeometry + */ + BoxGeometry.fromAxisAlignedBoundingBox = function (boundingBox) { + Check.typeOf.object('boundingBox', boundingBox); + + return new BoxGeometry({ + minimum : boundingBox.minimum, + maximum : boundingBox.maximum + }); + }; -define('Core/IntersectionTests',[ - './Cartesian3', - './Cartographic', - './defaultValue', - './defined', - './DeveloperError', - './Interval', - './Math', - './Matrix3', - './QuadraticRealPolynomial', - './QuarticRealPolynomial', - './Ray' - ], function( - Cartesian3, - Cartographic, - defaultValue, - defined, - DeveloperError, - Interval, - CesiumMath, - Matrix3, - QuadraticRealPolynomial, - QuarticRealPolynomial, - Ray) { - 'use strict'; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + BoxGeometry.packedLength = 2 * Cartesian3.packedLength + VertexFormat.packedLength; /** - * Functions for computing the intersection between geometries such as rays, planes, triangles, and ellipsoids. + * Stores the provided instance into the provided array. * - * @exports IntersectionTests + * @param {BoxGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - var IntersectionTests = {}; + BoxGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + Cartesian3.pack(value._minimum, array, startingIndex); + Cartesian3.pack(value._maximum, array, startingIndex + Cartesian3.packedLength); + VertexFormat.pack(value._vertexFormat, array, startingIndex + 2 * Cartesian3.packedLength); + + return array; + }; + + var scratchMin = new Cartesian3(); + var scratchMax = new Cartesian3(); + var scratchVertexFormat = new VertexFormat(); + var scratchOptions = { + minimum: scratchMin, + maximum: scratchMax, + vertexFormat: scratchVertexFormat + }; /** - * Computes the intersection of a ray and a plane. + * Retrieves an instance from a packed array. * - * @param {Ray} ray The ray. - * @param {Plane} plane The plane. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The intersection point or undefined if there is no intersections. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {BoxGeometry} [result] The object into which to store the result. + * @returns {BoxGeometry} The modified result parameter or a new BoxGeometry instance if one was not provided. */ - IntersectionTests.rayPlane = function(ray, plane, result) { - if (!defined(ray)) { - throw new DeveloperError('ray is required.'); - } - if (!defined(plane)) { - throw new DeveloperError('plane is required.'); - } + BoxGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); - if (!defined(result)) { - result = new Cartesian3(); - } + startingIndex = defaultValue(startingIndex, 0); - var origin = ray.origin; - var direction = ray.direction; - var normal = plane.normal; - var denominator = Cartesian3.dot(normal, direction); + var min = Cartesian3.unpack(array, startingIndex, scratchMin); + var max = Cartesian3.unpack(array, startingIndex + Cartesian3.packedLength, scratchMax); + var vertexFormat = VertexFormat.unpack(array, startingIndex + 2 * Cartesian3.packedLength, scratchVertexFormat); - if (Math.abs(denominator) < CesiumMath.EPSILON15) { - // Ray is parallel to plane. The ray may be in the polygon's plane. - return undefined; + if (!defined(result)) { + return new BoxGeometry(scratchOptions); } - var t = (-plane.distance - Cartesian3.dot(normal, origin)) / denominator; - - if (t < 0) { - return undefined; - } + result._minimum = Cartesian3.clone(min, result._minimum); + result._maximum = Cartesian3.clone(max, result._maximum); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result = Cartesian3.multiplyByScalar(direction, t, result); - return Cartesian3.add(origin, result, result); + return result; }; - var scratchEdge0 = new Cartesian3(); - var scratchEdge1 = new Cartesian3(); - var scratchPVec = new Cartesian3(); - var scratchTVec = new Cartesian3(); - var scratchQVec = new Cartesian3(); - /** - * Computes the intersection of a ray and a triangle as a parametric distance along the input ray. + * Computes the geometric representation of a box, including its vertices, indices, and a bounding sphere. * - * Implements {@link https://cadxfem.org/inf/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf| - * Fast Minimum Storage Ray/Triangle Intersection} by Tomas Moller and Ben Trumbore. - * - * @memberof IntersectionTests - * - * @param {Ray} ray The ray. - * @param {Cartesian3} p0 The first vertex of the triangle. - * @param {Cartesian3} p1 The second vertex of the triangle. - * @param {Cartesian3} p2 The third vertex of the triangle. - * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle - * and return undefined for intersections with the back face. - * @returns {Number} The intersection as a parametric distance along the ray, or undefined if there is no intersection. + * @param {BoxGeometry} boxGeometry A description of the box. + * @returns {Geometry|undefined} The computed vertices and indices. */ - IntersectionTests.rayTriangleParametric = function(ray, p0, p1, p2, cullBackFaces) { - if (!defined(ray)) { - throw new DeveloperError('ray is required.'); - } - if (!defined(p0)) { - throw new DeveloperError('p0 is required.'); - } - if (!defined(p1)) { - throw new DeveloperError('p1 is required.'); - } - if (!defined(p2)) { - throw new DeveloperError('p2 is required.'); + BoxGeometry.createGeometry = function(boxGeometry) { + var min = boxGeometry._minimum; + var max = boxGeometry._maximum; + var vertexFormat = boxGeometry._vertexFormat; + + if (Cartesian3.equals(min, max)) { + return; } - - cullBackFaces = defaultValue(cullBackFaces, false); - var origin = ray.origin; - var direction = ray.direction; + var attributes = new GeometryAttributes(); + var indices; + var positions; - var edge0 = Cartesian3.subtract(p1, p0, scratchEdge0); - var edge1 = Cartesian3.subtract(p2, p0, scratchEdge1); + if (vertexFormat.position && + (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent)) { + if (vertexFormat.position) { + // 8 corner points. Duplicated 3 times each for each incident edge/face. + positions = new Float64Array(6 * 4 * 3); - var p = Cartesian3.cross(direction, edge1, scratchPVec); - var det = Cartesian3.dot(edge0, p); + // +z face + positions[0] = min.x; + positions[1] = min.y; + positions[2] = max.z; + positions[3] = max.x; + positions[4] = min.y; + positions[5] = max.z; + positions[6] = max.x; + positions[7] = max.y; + positions[8] = max.z; + positions[9] = min.x; + positions[10] = max.y; + positions[11] = max.z; - var tvec; - var q; + // -z face + positions[12] = min.x; + positions[13] = min.y; + positions[14] = min.z; + positions[15] = max.x; + positions[16] = min.y; + positions[17] = min.z; + positions[18] = max.x; + positions[19] = max.y; + positions[20] = min.z; + positions[21] = min.x; + positions[22] = max.y; + positions[23] = min.z; - var u; - var v; - var t; + // +x face + positions[24] = max.x; + positions[25] = min.y; + positions[26] = min.z; + positions[27] = max.x; + positions[28] = max.y; + positions[29] = min.z; + positions[30] = max.x; + positions[31] = max.y; + positions[32] = max.z; + positions[33] = max.x; + positions[34] = min.y; + positions[35] = max.z; - if (cullBackFaces) { - if (det < CesiumMath.EPSILON6) { - return undefined; - } + // -x face + positions[36] = min.x; + positions[37] = min.y; + positions[38] = min.z; + positions[39] = min.x; + positions[40] = max.y; + positions[41] = min.z; + positions[42] = min.x; + positions[43] = max.y; + positions[44] = max.z; + positions[45] = min.x; + positions[46] = min.y; + positions[47] = max.z; - tvec = Cartesian3.subtract(origin, p0, scratchTVec); - u = Cartesian3.dot(tvec, p); - if (u < 0.0 || u > det) { - return undefined; + // +y face + positions[48] = min.x; + positions[49] = max.y; + positions[50] = min.z; + positions[51] = max.x; + positions[52] = max.y; + positions[53] = min.z; + positions[54] = max.x; + positions[55] = max.y; + positions[56] = max.z; + positions[57] = min.x; + positions[58] = max.y; + positions[59] = max.z; + + // -y face + positions[60] = min.x; + positions[61] = min.y; + positions[62] = min.z; + positions[63] = max.x; + positions[64] = min.y; + positions[65] = min.z; + positions[66] = max.x; + positions[67] = min.y; + positions[68] = max.z; + positions[69] = min.x; + positions[70] = min.y; + positions[71] = max.z; + + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); } - q = Cartesian3.cross(tvec, edge0, scratchQVec); + if (vertexFormat.normal) { + var normals = new Float32Array(6 * 4 * 3); - v = Cartesian3.dot(direction, q); - if (v < 0.0 || u + v > det) { - return undefined; + // +z face + normals[0] = 0.0; + normals[1] = 0.0; + normals[2] = 1.0; + normals[3] = 0.0; + normals[4] = 0.0; + normals[5] = 1.0; + normals[6] = 0.0; + normals[7] = 0.0; + normals[8] = 1.0; + normals[9] = 0.0; + normals[10] = 0.0; + normals[11] = 1.0; + + // -z face + normals[12] = 0.0; + normals[13] = 0.0; + normals[14] = -1.0; + normals[15] = 0.0; + normals[16] = 0.0; + normals[17] = -1.0; + normals[18] = 0.0; + normals[19] = 0.0; + normals[20] = -1.0; + normals[21] = 0.0; + normals[22] = 0.0; + normals[23] = -1.0; + + // +x face + normals[24] = 1.0; + normals[25] = 0.0; + normals[26] = 0.0; + normals[27] = 1.0; + normals[28] = 0.0; + normals[29] = 0.0; + normals[30] = 1.0; + normals[31] = 0.0; + normals[32] = 0.0; + normals[33] = 1.0; + normals[34] = 0.0; + normals[35] = 0.0; + + // -x face + normals[36] = -1.0; + normals[37] = 0.0; + normals[38] = 0.0; + normals[39] = -1.0; + normals[40] = 0.0; + normals[41] = 0.0; + normals[42] = -1.0; + normals[43] = 0.0; + normals[44] = 0.0; + normals[45] = -1.0; + normals[46] = 0.0; + normals[47] = 0.0; + + // +y face + normals[48] = 0.0; + normals[49] = 1.0; + normals[50] = 0.0; + normals[51] = 0.0; + normals[52] = 1.0; + normals[53] = 0.0; + normals[54] = 0.0; + normals[55] = 1.0; + normals[56] = 0.0; + normals[57] = 0.0; + normals[58] = 1.0; + normals[59] = 0.0; + + // -y face + normals[60] = 0.0; + normals[61] = -1.0; + normals[62] = 0.0; + normals[63] = 0.0; + normals[64] = -1.0; + normals[65] = 0.0; + normals[66] = 0.0; + normals[67] = -1.0; + normals[68] = 0.0; + normals[69] = 0.0; + normals[70] = -1.0; + normals[71] = 0.0; + + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); } - t = Cartesian3.dot(edge1, q) / det; - } else { - if (Math.abs(det) < CesiumMath.EPSILON6) { - return undefined; + if (vertexFormat.st) { + var texCoords = new Float32Array(6 * 4 * 2); + + // +z face + texCoords[0] = 0.0; + texCoords[1] = 0.0; + texCoords[2] = 1.0; + texCoords[3] = 0.0; + texCoords[4] = 1.0; + texCoords[5] = 1.0; + texCoords[6] = 0.0; + texCoords[7] = 1.0; + + // -z face + texCoords[8] = 1.0; + texCoords[9] = 0.0; + texCoords[10] = 0.0; + texCoords[11] = 0.0; + texCoords[12] = 0.0; + texCoords[13] = 1.0; + texCoords[14] = 1.0; + texCoords[15] = 1.0; + + //+x face + texCoords[16] = 0.0; + texCoords[17] = 0.0; + texCoords[18] = 1.0; + texCoords[19] = 0.0; + texCoords[20] = 1.0; + texCoords[21] = 1.0; + texCoords[22] = 0.0; + texCoords[23] = 1.0; + + // -x face + texCoords[24] = 1.0; + texCoords[25] = 0.0; + texCoords[26] = 0.0; + texCoords[27] = 0.0; + texCoords[28] = 0.0; + texCoords[29] = 1.0; + texCoords[30] = 1.0; + texCoords[31] = 1.0; + + // +y face + texCoords[32] = 1.0; + texCoords[33] = 0.0; + texCoords[34] = 0.0; + texCoords[35] = 0.0; + texCoords[36] = 0.0; + texCoords[37] = 1.0; + texCoords[38] = 1.0; + texCoords[39] = 1.0; + + // -y face + texCoords[40] = 0.0; + texCoords[41] = 0.0; + texCoords[42] = 1.0; + texCoords[43] = 0.0; + texCoords[44] = 1.0; + texCoords[45] = 1.0; + texCoords[46] = 0.0; + texCoords[47] = 1.0; + + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : texCoords + }); } - var invDet = 1.0 / det; - tvec = Cartesian3.subtract(origin, p0, scratchTVec); - u = Cartesian3.dot(tvec, p) * invDet; - if (u < 0.0 || u > 1.0) { - return undefined; + if (vertexFormat.tangent) { + var tangents = new Float32Array(6 * 4 * 3); + + // +z face + tangents[0] = 1.0; + tangents[1] = 0.0; + tangents[2] = 0.0; + tangents[3] = 1.0; + tangents[4] = 0.0; + tangents[5] = 0.0; + tangents[6] = 1.0; + tangents[7] = 0.0; + tangents[8] = 0.0; + tangents[9] = 1.0; + tangents[10] = 0.0; + tangents[11] = 0.0; + + // -z face + tangents[12] = -1.0; + tangents[13] = 0.0; + tangents[14] = 0.0; + tangents[15] = -1.0; + tangents[16] = 0.0; + tangents[17] = 0.0; + tangents[18] = -1.0; + tangents[19] = 0.0; + tangents[20] = 0.0; + tangents[21] = -1.0; + tangents[22] = 0.0; + tangents[23] = 0.0; + + // +x face + tangents[24] = 0.0; + tangents[25] = 1.0; + tangents[26] = 0.0; + tangents[27] = 0.0; + tangents[28] = 1.0; + tangents[29] = 0.0; + tangents[30] = 0.0; + tangents[31] = 1.0; + tangents[32] = 0.0; + tangents[33] = 0.0; + tangents[34] = 1.0; + tangents[35] = 0.0; + + // -x face + tangents[36] = 0.0; + tangents[37] = -1.0; + tangents[38] = 0.0; + tangents[39] = 0.0; + tangents[40] = -1.0; + tangents[41] = 0.0; + tangents[42] = 0.0; + tangents[43] = -1.0; + tangents[44] = 0.0; + tangents[45] = 0.0; + tangents[46] = -1.0; + tangents[47] = 0.0; + + // +y face + tangents[48] = -1.0; + tangents[49] = 0.0; + tangents[50] = 0.0; + tangents[51] = -1.0; + tangents[52] = 0.0; + tangents[53] = 0.0; + tangents[54] = -1.0; + tangents[55] = 0.0; + tangents[56] = 0.0; + tangents[57] = -1.0; + tangents[58] = 0.0; + tangents[59] = 0.0; + + // -y face + tangents[60] = 1.0; + tangents[61] = 0.0; + tangents[62] = 0.0; + tangents[63] = 1.0; + tangents[64] = 0.0; + tangents[65] = 0.0; + tangents[66] = 1.0; + tangents[67] = 0.0; + tangents[68] = 0.0; + tangents[69] = 1.0; + tangents[70] = 0.0; + tangents[71] = 0.0; + + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); } - q = Cartesian3.cross(tvec, edge0, scratchQVec); + if (vertexFormat.bitangent) { + var bitangents = new Float32Array(6 * 4 * 3); - v = Cartesian3.dot(direction, q) * invDet; - if (v < 0.0 || u + v > 1.0) { - return undefined; + // +z face + bitangents[0] = 0.0; + bitangents[1] = 1.0; + bitangents[2] = 0.0; + bitangents[3] = 0.0; + bitangents[4] = 1.0; + bitangents[5] = 0.0; + bitangents[6] = 0.0; + bitangents[7] = 1.0; + bitangents[8] = 0.0; + bitangents[9] = 0.0; + bitangents[10] = 1.0; + bitangents[11] = 0.0; + + // -z face + bitangents[12] = 0.0; + bitangents[13] = 1.0; + bitangents[14] = 0.0; + bitangents[15] = 0.0; + bitangents[16] = 1.0; + bitangents[17] = 0.0; + bitangents[18] = 0.0; + bitangents[19] = 1.0; + bitangents[20] = 0.0; + bitangents[21] = 0.0; + bitangents[22] = 1.0; + bitangents[23] = 0.0; + + // +x face + bitangents[24] = 0.0; + bitangents[25] = 0.0; + bitangents[26] = 1.0; + bitangents[27] = 0.0; + bitangents[28] = 0.0; + bitangents[29] = 1.0; + bitangents[30] = 0.0; + bitangents[31] = 0.0; + bitangents[32] = 1.0; + bitangents[33] = 0.0; + bitangents[34] = 0.0; + bitangents[35] = 1.0; + + // -x face + bitangents[36] = 0.0; + bitangents[37] = 0.0; + bitangents[38] = 1.0; + bitangents[39] = 0.0; + bitangents[40] = 0.0; + bitangents[41] = 1.0; + bitangents[42] = 0.0; + bitangents[43] = 0.0; + bitangents[44] = 1.0; + bitangents[45] = 0.0; + bitangents[46] = 0.0; + bitangents[47] = 1.0; + + // +y face + bitangents[48] = 0.0; + bitangents[49] = 0.0; + bitangents[50] = 1.0; + bitangents[51] = 0.0; + bitangents[52] = 0.0; + bitangents[53] = 1.0; + bitangents[54] = 0.0; + bitangents[55] = 0.0; + bitangents[56] = 1.0; + bitangents[57] = 0.0; + bitangents[58] = 0.0; + bitangents[59] = 1.0; + + // -y face + bitangents[60] = 0.0; + bitangents[61] = 0.0; + bitangents[62] = 1.0; + bitangents[63] = 0.0; + bitangents[64] = 0.0; + bitangents[65] = 1.0; + bitangents[66] = 0.0; + bitangents[67] = 0.0; + bitangents[68] = 1.0; + bitangents[69] = 0.0; + bitangents[70] = 0.0; + bitangents[71] = 1.0; + + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); } - t = Cartesian3.dot(edge1, q) * invDet; - } + // 12 triangles: 6 faces, 2 triangles each. + indices = new Uint16Array(6 * 2 * 3); - return t; - }; + // +z face + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; - /** - * Computes the intersection of a ray and a triangle as a Cartesian3 coordinate. - * - * Implements {@link https://cadxfem.org/inf/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf| - * Fast Minimum Storage Ray/Triangle Intersection} by Tomas Moller and Ben Trumbore. - * - * @memberof IntersectionTests - * - * @param {Ray} ray The ray. - * @param {Cartesian3} p0 The first vertex of the triangle. - * @param {Cartesian3} p1 The second vertex of the triangle. - * @param {Cartesian3} p2 The third vertex of the triangle. - * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle - * and return undefined for intersections with the back face. - * @param {Cartesian3} [result] The <code>Cartesian3</code> onto which to store the result. - * @returns {Cartesian3} The intersection point or undefined if there is no intersections. - */ - IntersectionTests.rayTriangle = function(ray, p0, p1, p2, cullBackFaces, result) { - var t = IntersectionTests.rayTriangleParametric(ray, p0, p1, p2, cullBackFaces); - if (!defined(t) || t < 0.0) { - return undefined; - } + // -z face + indices[6] = 4 + 2; + indices[7] = 4 + 1; + indices[8] = 4 + 0; + indices[9] = 4 + 3; + indices[10] = 4 + 2; + indices[11] = 4 + 0; - if (!defined(result)) { - result = new Cartesian3(); - } + // +x face + indices[12] = 8 + 0; + indices[13] = 8 + 1; + indices[14] = 8 + 2; + indices[15] = 8 + 0; + indices[16] = 8 + 2; + indices[17] = 8 + 3; - Cartesian3.multiplyByScalar(ray.direction, t, result); - return Cartesian3.add(ray.origin, result, result); - }; + // -x face + indices[18] = 12 + 2; + indices[19] = 12 + 1; + indices[20] = 12 + 0; + indices[21] = 12 + 3; + indices[22] = 12 + 2; + indices[23] = 12 + 0; - var scratchLineSegmentTriangleRay = new Ray(); + // +y face + indices[24] = 16 + 2; + indices[25] = 16 + 1; + indices[26] = 16 + 0; + indices[27] = 16 + 3; + indices[28] = 16 + 2; + indices[29] = 16 + 0; - /** - * Computes the intersection of a line segment and a triangle. - * @memberof IntersectionTests - * - * @param {Cartesian3} v0 The an end point of the line segment. - * @param {Cartesian3} v1 The other end point of the line segment. - * @param {Cartesian3} p0 The first vertex of the triangle. - * @param {Cartesian3} p1 The second vertex of the triangle. - * @param {Cartesian3} p2 The third vertex of the triangle. - * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle - * and return undefined for intersections with the back face. - * @param {Cartesian3} [result] The <code>Cartesian3</code> onto which to store the result. - * @returns {Cartesian3} The intersection point or undefined if there is no intersections. - */ - IntersectionTests.lineSegmentTriangle = function(v0, v1, p0, p1, p2, cullBackFaces, result) { - if (!defined(v0)) { - throw new DeveloperError('v0 is required.'); - } - if (!defined(v1)) { - throw new DeveloperError('v1 is required.'); - } - if (!defined(p0)) { - throw new DeveloperError('p0 is required.'); - } - if (!defined(p1)) { - throw new DeveloperError('p1 is required.'); - } - if (!defined(p2)) { - throw new DeveloperError('p2 is required.'); - } - - var ray = scratchLineSegmentTriangleRay; - Cartesian3.clone(v0, ray.origin); - Cartesian3.subtract(v1, v0, ray.direction); - Cartesian3.normalize(ray.direction, ray.direction); + // -y face + indices[30] = 20 + 0; + indices[31] = 20 + 1; + indices[32] = 20 + 2; + indices[33] = 20 + 0; + indices[34] = 20 + 2; + indices[35] = 20 + 3; + } else { + // Positions only - no need to duplicate corner points + positions = new Float64Array(8 * 3); - var t = IntersectionTests.rayTriangleParametric(ray, p0, p1, p2, cullBackFaces); - if (!defined(t) || t < 0.0 || t > Cartesian3.distance(v0, v1)) { - return undefined; - } + positions[0] = min.x; + positions[1] = min.y; + positions[2] = min.z; + positions[3] = max.x; + positions[4] = min.y; + positions[5] = min.z; + positions[6] = max.x; + positions[7] = max.y; + positions[8] = min.z; + positions[9] = min.x; + positions[10] = max.y; + positions[11] = min.z; + positions[12] = min.x; + positions[13] = min.y; + positions[14] = max.z; + positions[15] = max.x; + positions[16] = min.y; + positions[17] = max.z; + positions[18] = max.x; + positions[19] = max.y; + positions[20] = max.z; + positions[21] = min.x; + positions[22] = max.y; + positions[23] = max.z; - if (!defined(result)) { - result = new Cartesian3(); - } + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); - Cartesian3.multiplyByScalar(ray.direction, t, result); - return Cartesian3.add(ray.origin, result, result); - }; + // 12 triangles: 6 faces, 2 triangles each. + indices = new Uint16Array(6 * 2 * 3); - function solveQuadratic(a, b, c, result) { - var det = b * b - 4.0 * a * c; - if (det < 0.0) { - return undefined; - } else if (det > 0.0) { - var denom = 1.0 / (2.0 * a); - var disc = Math.sqrt(det); - var root0 = (-b + disc) * denom; - var root1 = (-b - disc) * denom; + // plane z = corner.Z + indices[0] = 4; + indices[1] = 5; + indices[2] = 6; + indices[3] = 4; + indices[4] = 6; + indices[5] = 7; - if (root0 < root1) { - result.root0 = root0; - result.root1 = root1; - } else { - result.root0 = root1; - result.root1 = root0; - } + // plane z = -corner.Z + indices[6] = 1; + indices[7] = 0; + indices[8] = 3; + indices[9] = 1; + indices[10] = 3; + indices[11] = 2; - return result; - } + // plane x = corner.X + indices[12] = 1; + indices[13] = 6; + indices[14] = 5; + indices[15] = 1; + indices[16] = 2; + indices[17] = 6; - var root = -b / (2.0 * a); - if (root === 0.0) { - return undefined; + // plane y = corner.Y + indices[18] = 2; + indices[19] = 3; + indices[20] = 7; + indices[21] = 2; + indices[22] = 7; + indices[23] = 6; + + // plane x = -corner.X + indices[24] = 3; + indices[25] = 0; + indices[26] = 4; + indices[27] = 3; + indices[28] = 4; + indices[29] = 7; + + // plane y = -corner.Y + indices[30] = 0; + indices[31] = 1; + indices[32] = 5; + indices[33] = 0; + indices[34] = 5; + indices[35] = 4; } - result.root0 = result.root1 = root; - return result; - } + var diff = Cartesian3.subtract(max, min, diffScratch); + var radius = Cartesian3.magnitude(diff) * 0.5; - var raySphereRoots = { - root0 : 0.0, - root1 : 0.0 + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : new BoundingSphere(Cartesian3.ZERO, radius) + }); }; - function raySphere(ray, sphere, result) { - if (!defined(result)) { - result = new Interval(); + var unitBoxGeometry; + + /** + * Returns the geometric representation of a unit box, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private + */ + BoxGeometry.getUnitBox = function() { + if (!defined(unitBoxGeometry)) { + unitBoxGeometry = BoxGeometry.createGeometry(BoxGeometry.fromDimensions({ + dimensions : new Cartesian3(1.0, 1.0, 1.0), + vertexFormat : VertexFormat.POSITION_ONLY + })); } + return unitBoxGeometry; + }; - var origin = ray.origin; - var direction = ray.direction; + return BoxGeometry; +}); - var center = sphere.center; - var radiusSquared = sphere.radius * sphere.radius; +define('Core/BoxOutlineGeometry',[ + './BoundingSphere', + './Cartesian3', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './PrimitiveType' + ], function( + BoundingSphere, + Cartesian3, + Check, + ComponentDatatype, + defaultValue, + defined, + Geometry, + GeometryAttribute, + GeometryAttributes, + PrimitiveType) { + 'use strict'; - var diff = Cartesian3.subtract(origin, center, scratchPVec); + var diffScratch = new Cartesian3(); - var a = Cartesian3.dot(direction, direction); - var b = 2.0 * Cartesian3.dot(direction, diff); - var c = Cartesian3.magnitudeSquared(diff) - radiusSquared; + /** + * A description of the outline of a cube centered at the origin. + * + * @alias BoxOutlineGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.minimum The minimum x, y, and z coordinates of the box. + * @param {Cartesian3} options.maximum The maximum x, y, and z coordinates of the box. + * + * @see BoxOutlineGeometry.fromDimensions + * @see BoxOutlineGeometry.createGeometry + * @see Packable + * + * @example + * var box = new Cesium.BoxOutlineGeometry({ + * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0), + * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0) + * }); + * var geometry = Cesium.BoxOutlineGeometry.createGeometry(box); + */ + function BoxOutlineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var roots = solveQuadratic(a, b, c, raySphereRoots); - if (!defined(roots)) { - return undefined; - } + var min = options.minimum; + var max = options.maximum; - result.start = roots.root0; - result.stop = roots.root1; - return result; + Check.typeOf.object('min', min); + Check.typeOf.object('max', max); + + this._min = Cartesian3.clone(min); + this._max = Cartesian3.clone(max); + this._workerName = 'createBoxOutlineGeometry'; } /** - * Computes the intersection points of a ray with a sphere. - * @memberof IntersectionTests + * Creates an outline of a cube centered at the origin given its dimensions. * - * @param {Ray} ray The ray. - * @param {BoundingSphere} sphere The sphere. - * @param {Interval} [result] The result onto which to store the result. - * @returns {Interval} The interval containing scalar points along the ray or undefined if there are no intersections. + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.dimensions The width, depth, and height of the box stored in the x, y, and z coordinates of the <code>Cartesian3</code>, respectively. + * @returns {BoxOutlineGeometry} + * + * @exception {DeveloperError} All dimensions components must be greater than or equal to zero. + * + * + * @example + * var box = Cesium.BoxOutlineGeometry.fromDimensions({ + * dimensions : new Cesium.Cartesian3(500000.0, 500000.0, 500000.0) + * }); + * var geometry = Cesium.BoxOutlineGeometry.createGeometry(box); + * + * @see BoxOutlineGeometry.createGeometry */ - IntersectionTests.raySphere = function(ray, sphere, result) { - if (!defined(ray)) { - throw new DeveloperError('ray is required.'); - } - if (!defined(sphere)) { - throw new DeveloperError('sphere is required.'); - } + BoxOutlineGeometry.fromDimensions = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var dimensions = options.dimensions; + + Check.typeOf.object('dimensions', dimensions); + Check.typeOf.number.greaterThanOrEquals('dimensions.x', dimensions.x, 0); + Check.typeOf.number.greaterThanOrEquals('dimensions.y', dimensions.y, 0); + Check.typeOf.number.greaterThanOrEquals('dimensions.z', dimensions.z, 0); - result = raySphere(ray, sphere, result); - if (!defined(result) || result.stop < 0.0) { - return undefined; - } + var corner = Cartesian3.multiplyByScalar(dimensions, 0.5, new Cartesian3()); - result.start = Math.max(result.start, 0.0); - return result; + return new BoxOutlineGeometry({ + minimum : Cartesian3.negate(corner, new Cartesian3()), + maximum : corner + }); }; - var scratchLineSegmentRay = new Ray(); - /** - * Computes the intersection points of a line segment with a sphere. - * @memberof IntersectionTests + * Creates an outline of a cube from the dimensions of an AxisAlignedBoundingBox. * - * @param {Cartesian3} p0 An end point of the line segment. - * @param {Cartesian3} p1 The other end point of the line segment. - * @param {BoundingSphere} sphere The sphere. - * @param {Interval} [result] The result onto which to store the result. - * @returns {Interval} The interval containing scalar points along the ray or undefined if there are no intersections. + * @param {AxisAlignedBoundingBox} boundingBox A description of the AxisAlignedBoundingBox. + * @returns {BoxOutlineGeometry} + * + * + * + * @example + * var aabb = Cesium.AxisAlignedBoundingBox.fromPoints(Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ])); + * var box = Cesium.BoxOutlineGeometry.fromAxisAlignedBoundingBox(aabb); + * + * @see BoxOutlineGeometry.createGeometry */ - IntersectionTests.lineSegmentSphere = function(p0, p1, sphere, result) { - if (!defined(p0)) { - throw new DeveloperError('p0 is required.'); - } - if (!defined(p1)) { - throw new DeveloperError('p1 is required.'); - } - if (!defined(sphere)) { - throw new DeveloperError('sphere is required.'); - } + BoxOutlineGeometry.fromAxisAlignedBoundingBox = function(boundingBox) { + Check.typeOf.object('boundindBox', boundingBox); - var ray = scratchLineSegmentRay; - Cartesian3.clone(p0, ray.origin); - var direction = Cartesian3.subtract(p1, p0, ray.direction); + return new BoxOutlineGeometry({ + minimum : boundingBox.minimum, + maximum : boundingBox.maximum + }); + }; - var maxT = Cartesian3.magnitude(direction); - Cartesian3.normalize(direction, direction); + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + BoxOutlineGeometry.packedLength = 2 * Cartesian3.packedLength; - result = raySphere(ray, sphere, result); - if (!defined(result) || result.stop < 0.0 || result.start > maxT) { - return undefined; - } + /** + * Stores the provided instance into the provided array. + * + * @param {BoxOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + BoxOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - result.start = Math.max(result.start, 0.0); - result.stop = Math.min(result.stop, maxT); - return result; + Cartesian3.pack(value._min, array, startingIndex); + Cartesian3.pack(value._max, array, startingIndex + Cartesian3.packedLength); + return array; }; - var scratchQ = new Cartesian3(); - var scratchW = new Cartesian3(); + var scratchMin = new Cartesian3(); + var scratchMax = new Cartesian3(); + var scratchOptions = { + minimum : scratchMin, + maximum : scratchMax + }; /** - * Computes the intersection points of a ray with an ellipsoid. + * Retrieves an instance from a packed array. * - * @param {Ray} ray The ray. - * @param {Ellipsoid} ellipsoid The ellipsoid. - * @returns {Interval} The interval containing scalar points along the ray or undefined if there are no intersections. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {BoxOutlineGeometry} [result] The object into which to store the result. + * @returns {BoxOutlineGeometry} The modified result parameter or a new BoxOutlineGeometry instance if one was not provided. */ - IntersectionTests.rayEllipsoid = function(ray, ellipsoid) { - if (!defined(ray)) { - throw new DeveloperError('ray is required.'); - } - if (!defined(ellipsoid)) { - throw new DeveloperError('ellipsoid is required.'); - } + BoxOutlineGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); - var inverseRadii = ellipsoid.oneOverRadii; - var q = Cartesian3.multiplyComponents(inverseRadii, ray.origin, scratchQ); - var w = Cartesian3.multiplyComponents(inverseRadii, ray.direction, scratchW); + startingIndex = defaultValue(startingIndex, 0); - var q2 = Cartesian3.magnitudeSquared(q); - var qw = Cartesian3.dot(q, w); + var min = Cartesian3.unpack(array, startingIndex, scratchMin); + var max = Cartesian3.unpack(array, startingIndex + Cartesian3.packedLength, scratchMax); - var difference, w2, product, discriminant, temp; + if (!defined(result)) { + return new BoxOutlineGeometry(scratchOptions); + } - if (q2 > 1.0) { - // Outside ellipsoid. - if (qw >= 0.0) { - // Looking outward or tangent (0 intersections). - return undefined; - } + result._min = Cartesian3.clone(min, result._min); + result._max = Cartesian3.clone(max, result._max); - // qw < 0.0. - var qw2 = qw * qw; - difference = q2 - 1.0; // Positively valued. - w2 = Cartesian3.magnitudeSquared(w); - product = w2 * difference; + return result; + }; - if (qw2 < product) { - // Imaginary roots (0 intersections). - return undefined; - } else if (qw2 > product) { - // Distinct roots (2 intersections). - discriminant = qw * qw - product; - temp = -qw + Math.sqrt(discriminant); // Avoid cancellation. - var root0 = temp / w2; - var root1 = difference / temp; - if (root0 < root1) { - return new Interval(root0, root1); - } + /** + * Computes the geometric representation of an outline of a box, including its vertices, indices, and a bounding sphere. + * + * @param {BoxOutlineGeometry} boxGeometry A description of the box outline. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + BoxOutlineGeometry.createGeometry = function(boxGeometry) { + var min = boxGeometry._min; + var max = boxGeometry._max; - return { - start : root1, - stop : root0 - }; - } - // qw2 == product. Repeated roots (2 intersections). - var root = Math.sqrt(difference / w2); - return new Interval(root, root); - } else if (q2 < 1.0) { - // Inside ellipsoid (2 intersections). - difference = q2 - 1.0; // Negatively valued. - w2 = Cartesian3.magnitudeSquared(w); - product = w2 * difference; // Negatively valued. - - discriminant = qw * qw - product; - temp = -qw + Math.sqrt(discriminant); // Positively valued. - return new Interval(0.0, temp / w2); - } - // q2 == 1.0. On ellipsoid. - if (qw < 0.0) { - // Looking inward. - w2 = Cartesian3.magnitudeSquared(w); - return new Interval(0.0, -qw / w2); + if (Cartesian3.equals(min, max)) { + return; } - // qw >= 0.0. Looking outward or tangent. - return undefined; - }; + var attributes = new GeometryAttributes(); + var indices = new Uint16Array(12 * 2); + var positions = new Float64Array(8 * 3); - function addWithCancellationCheck(left, right, tolerance) { - var difference = left + right; - if ((CesiumMath.sign(left) !== CesiumMath.sign(right)) && - Math.abs(difference / Math.max(Math.abs(left), Math.abs(right))) < tolerance) { - return 0.0; - } + positions[0] = min.x; + positions[1] = min.y; + positions[2] = min.z; + positions[3] = max.x; + positions[4] = min.y; + positions[5] = min.z; + positions[6] = max.x; + positions[7] = max.y; + positions[8] = min.z; + positions[9] = min.x; + positions[10] = max.y; + positions[11] = min.z; - return difference; - } + positions[12] = min.x; + positions[13] = min.y; + positions[14] = max.z; + positions[15] = max.x; + positions[16] = min.y; + positions[17] = max.z; + positions[18] = max.x; + positions[19] = max.y; + positions[20] = max.z; + positions[21] = min.x; + positions[22] = max.y; + positions[23] = max.z; - function quadraticVectorExpression(A, b, c, x, w) { - var xSquared = x * x; - var wSquared = w * w; + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); - var l2 = (A[Matrix3.COLUMN1ROW1] - A[Matrix3.COLUMN2ROW2]) * wSquared; - var l1 = w * (x * addWithCancellationCheck(A[Matrix3.COLUMN1ROW0], A[Matrix3.COLUMN0ROW1], CesiumMath.EPSILON15) + b.y); - var l0 = (A[Matrix3.COLUMN0ROW0] * xSquared + A[Matrix3.COLUMN2ROW2] * wSquared) + x * b.x + c; + // top + indices[0] = 4; + indices[1] = 5; + indices[2] = 5; + indices[3] = 6; + indices[4] = 6; + indices[5] = 7; + indices[6] = 7; + indices[7] = 4; - var r1 = wSquared * addWithCancellationCheck(A[Matrix3.COLUMN2ROW1], A[Matrix3.COLUMN1ROW2], CesiumMath.EPSILON15); - var r0 = w * (x * addWithCancellationCheck(A[Matrix3.COLUMN2ROW0], A[Matrix3.COLUMN0ROW2]) + b.z); + // bottom + indices[8] = 0; + indices[9] = 1; + indices[10] = 1; + indices[11] = 2; + indices[12] = 2; + indices[13] = 3; + indices[14] = 3; + indices[15] = 0; - var cosines; - var solutions = []; - if (r0 === 0.0 && r1 === 0.0) { - cosines = QuadraticRealPolynomial.computeRealRoots(l2, l1, l0); - if (cosines.length === 0) { - return solutions; - } + // left + indices[16] = 0; + indices[17] = 4; + indices[18] = 1; + indices[19] = 5; - var cosine0 = cosines[0]; - var sine0 = Math.sqrt(Math.max(1.0 - cosine0 * cosine0, 0.0)); - solutions.push(new Cartesian3(x, w * cosine0, w * -sine0)); - solutions.push(new Cartesian3(x, w * cosine0, w * sine0)); + //right + indices[20] = 2; + indices[21] = 6; + indices[22] = 3; + indices[23] = 7; - if (cosines.length === 2) { - var cosine1 = cosines[1]; - var sine1 = Math.sqrt(Math.max(1.0 - cosine1 * cosine1, 0.0)); - solutions.push(new Cartesian3(x, w * cosine1, w * -sine1)); - solutions.push(new Cartesian3(x, w * cosine1, w * sine1)); - } + var diff = Cartesian3.subtract(max, min, diffScratch); + var radius = Cartesian3.magnitude(diff) * 0.5; - return solutions; - } + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : new BoundingSphere(Cartesian3.ZERO, radius) + }); + }; - var r0Squared = r0 * r0; - var r1Squared = r1 * r1; - var l2Squared = l2 * l2; - var r0r1 = r0 * r1; + return BoxOutlineGeometry; +}); - var c4 = l2Squared + r1Squared; - var c3 = 2.0 * (l1 * l2 + r0r1); - var c2 = 2.0 * l0 * l2 + l1 * l1 - r1Squared + r0Squared; - var c1 = 2.0 * (l0 * l1 - r0r1); - var c0 = l0 * l0 - r0Squared; +define('Core/buildModuleUrl',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError', + './Resource', + 'require' + ], function( + Uri, + defined, + DeveloperError, + Resource, + require) { + 'use strict'; + /*global CESIUM_BASE_URL*/ - if (c4 === 0.0 && c3 === 0.0 && c2 === 0.0 && c1 === 0.0) { - return solutions; + var cesiumScriptRegex = /((?:.*\/)|^)cesium[\w-]*\.js(?:\W|$)/i; + function getBaseUrlFromCesiumScript() { + var scripts = document.getElementsByTagName('script'); + for ( var i = 0, len = scripts.length; i < len; ++i) { + var src = scripts[i].getAttribute('src'); + var result = cesiumScriptRegex.exec(src); + if (result !== null) { + return result[1]; + } } + return undefined; + } - cosines = QuarticRealPolynomial.computeRealRoots(c4, c3, c2, c1, c0); - var length = cosines.length; - if (length === 0) { - return solutions; + var baseResource; + function getCesiumBaseUrl() { + if (defined(baseResource)) { + return baseResource; } - for ( var i = 0; i < length; ++i) { - var cosine = cosines[i]; - var cosineSquared = cosine * cosine; - var sineSquared = Math.max(1.0 - cosineSquared, 0.0); - var sine = Math.sqrt(sineSquared); + var baseUrlString; + if (typeof CESIUM_BASE_URL !== 'undefined') { + baseUrlString = CESIUM_BASE_URL; + } else { + baseUrlString = getBaseUrlFromCesiumScript(); + } - //var left = l2 * cosineSquared + l1 * cosine + l0; - var left; - if (CesiumMath.sign(l2) === CesiumMath.sign(l0)) { - left = addWithCancellationCheck(l2 * cosineSquared + l0, l1 * cosine, CesiumMath.EPSILON12); - } else if (CesiumMath.sign(l0) === CesiumMath.sign(l1 * cosine)) { - left = addWithCancellationCheck(l2 * cosineSquared, l1 * cosine + l0, CesiumMath.EPSILON12); - } else { - left = addWithCancellationCheck(l2 * cosineSquared + l1 * cosine, l0, CesiumMath.EPSILON12); - } + if (!defined(baseUrlString)) { + throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); + } + + baseResource = new Resource({ + url: baseUrlString + }); - var right = addWithCancellationCheck(r1 * cosine, r0, CesiumMath.EPSILON15); - var product = left * right; + return baseResource; + } - if (product < 0.0) { - solutions.push(new Cartesian3(x, w * cosine, w * sine)); - } else if (product > 0.0) { - solutions.push(new Cartesian3(x, w * cosine, w * -sine)); - } else if (sine !== 0.0) { - solutions.push(new Cartesian3(x, w * cosine, w * -sine)); - solutions.push(new Cartesian3(x, w * cosine, w * sine)); - ++i; - } else { - solutions.push(new Cartesian3(x, w * cosine, w * sine)); - } - } + function buildModuleUrlFromRequireToUrl(moduleID) { + //moduleID will be non-relative, so require it relative to this module, in Core. + return require.toUrl('../' + moduleID); + } - return solutions; + function buildModuleUrlFromBaseUrl(moduleID) { + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } - var firstAxisScratch = new Cartesian3(); - var secondAxisScratch = new Cartesian3(); - var thirdAxisScratch = new Cartesian3(); - var referenceScratch = new Cartesian3(); - var bCart = new Cartesian3(); - var bScratch = new Matrix3(); - var btScratch = new Matrix3(); - var diScratch = new Matrix3(); - var dScratch = new Matrix3(); - var cScratch = new Matrix3(); - var tempMatrix = new Matrix3(); - var aScratch = new Matrix3(); - var sScratch = new Cartesian3(); - var closestScratch = new Cartesian3(); - var surfPointScratch = new Cartographic(); + var implementation; + var a; /** - * Provides the point along the ray which is nearest to the ellipsoid. + * Given a non-relative moduleID, returns an absolute URL to the file represented by that module ID, + * using, in order of preference, require.toUrl, the value of a global CESIUM_BASE_URL, or + * the base URL of the Cesium.js script. * - * @param {Ray} ray The ray. - * @param {Ellipsoid} ellipsoid The ellipsoid. - * @returns {Cartesian3} The nearest planetodetic point on the ray. + * @private */ - IntersectionTests.grazingAltitudeLocation = function(ray, ellipsoid) { - if (!defined(ray)) { - throw new DeveloperError('ray is required.'); - } - if (!defined(ellipsoid)) { - throw new DeveloperError('ellipsoid is required.'); - } - - var position = ray.origin; - var direction = ray.direction; - - if (!Cartesian3.equals(position, Cartesian3.ZERO)) { - var normal = ellipsoid.geodeticSurfaceNormal(position, firstAxisScratch); - if (Cartesian3.dot(direction, normal) >= 0.0) { // The location provided is the closest point in altitude - return position; + function buildModuleUrl(moduleID) { + if (!defined(implementation)) { + //select implementation + if (defined(define.amd) && !define.amd.toUrlUndefined && defined(require.toUrl)) { + implementation = buildModuleUrlFromRequireToUrl; + } else { + implementation = buildModuleUrlFromBaseUrl; } } - var intersects = defined(this.rayEllipsoid(ray, ellipsoid)); - - // Compute the scaled direction vector. - var f = ellipsoid.transformPositionToScaledSpace(direction, firstAxisScratch); + if (!defined(a)) { + a = document.createElement('a'); + } - // Constructs a basis from the unit scaled direction vector. Construct its rotation and transpose. - var firstAxis = Cartesian3.normalize(f, f); - var reference = Cartesian3.mostOrthogonalAxis(f, referenceScratch); - var secondAxis = Cartesian3.normalize(Cartesian3.cross(reference, firstAxis, secondAxisScratch), secondAxisScratch); - var thirdAxis = Cartesian3.normalize(Cartesian3.cross(firstAxis, secondAxis, thirdAxisScratch), thirdAxisScratch); - var B = bScratch; - B[0] = firstAxis.x; - B[1] = firstAxis.y; - B[2] = firstAxis.z; - B[3] = secondAxis.x; - B[4] = secondAxis.y; - B[5] = secondAxis.z; - B[6] = thirdAxis.x; - B[7] = thirdAxis.y; - B[8] = thirdAxis.z; + var url = implementation(moduleID); - var B_T = Matrix3.transpose(B, btScratch); + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - // Get the scaling matrix and its inverse. - var D_I = Matrix3.fromScale(ellipsoid.radii, diScratch); - var D = Matrix3.fromScale(ellipsoid.oneOverRadii, dScratch); + return a.href; + } - var C = cScratch; - C[0] = 0.0; - C[1] = -direction.z; - C[2] = direction.y; - C[3] = direction.z; - C[4] = 0.0; - C[5] = -direction.x; - C[6] = -direction.y; - C[7] = direction.x; - C[8] = 0.0; + // exposed for testing + buildModuleUrl._cesiumScriptRegex = cesiumScriptRegex; - var temp = Matrix3.multiply(Matrix3.multiply(B_T, D, tempMatrix), C, tempMatrix); - var A = Matrix3.multiply(Matrix3.multiply(temp, D_I, aScratch), B, aScratch); - var b = Matrix3.multiplyByVector(temp, position, bCart); + /** + * Sets the base URL for resolving modules. + * @param {String} value The new base URL. + */ + buildModuleUrl.setBaseUrl = function(value) { + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); + }; - // Solve for the solutions to the expression in standard form: - var solutions = quadraticVectorExpression(A, Cartesian3.negate(b, firstAxisScratch), 0.0, 0.0, 1.0); + return buildModuleUrl; +}); - var s; - var altitude; - var length = solutions.length; - if (length > 0) { - var closest = Cartesian3.clone(Cartesian3.ZERO, closestScratch); - var maximumValue = Number.NEGATIVE_INFINITY; +define('Core/cancelAnimationFrame',[ + './defined' + ], function( + defined) { + 'use strict'; - for ( var i = 0; i < length; ++i) { - s = Matrix3.multiplyByVector(D_I, Matrix3.multiplyByVector(B, solutions[i], sScratch), sScratch); - var v = Cartesian3.normalize(Cartesian3.subtract(s, position, referenceScratch), referenceScratch); - var dotProduct = Cartesian3.dot(v, direction); + if (typeof window === 'undefined') { + return; + } - if (dotProduct > maximumValue) { - maximumValue = dotProduct; - closest = Cartesian3.clone(s, closest); + var implementation = window.cancelAnimationFrame; + (function() { + // look for vendor prefixed function + if (!defined(implementation)) { + var vendors = ['webkit', 'moz', 'ms', 'o']; + var i = 0; + var len = vendors.length; + while (i < len && !defined(implementation)) { + implementation = window[vendors[i] + 'CancelAnimationFrame']; + if (!defined(implementation)) { + implementation = window[vendors[i] + 'CancelRequestAnimationFrame']; } + ++i; } - - var surfacePoint = ellipsoid.cartesianToCartographic(closest, surfPointScratch); - maximumValue = CesiumMath.clamp(maximumValue, 0.0, 1.0); - altitude = Cartesian3.magnitude(Cartesian3.subtract(closest, position, referenceScratch)) * Math.sqrt(1.0 - maximumValue * maximumValue); - altitude = intersects ? -altitude : altitude; - surfacePoint.height = altitude; - return ellipsoid.cartographicToCartesian(surfacePoint, new Cartesian3()); } - return undefined; - }; - - var lineSegmentPlaneDifference = new Cartesian3(); + // otherwise, assume requestAnimationFrame is based on setTimeout, so use clearTimeout + if (!defined(implementation)) { + implementation = clearTimeout; + } + })(); /** - * Computes the intersection of a line segment and a plane. - * - * @param {Cartesian3} endPoint0 An end point of the line segment. - * @param {Cartesian3} endPoint1 The other end point of the line segment. - * @param {Plane} plane The plane. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The intersection point or undefined if there is no intersection. + * A browser-independent function to cancel an animation frame requested using {@link requestAnimationFrame}. * - * @example - * var origin = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); - * var normal = ellipsoid.geodeticSurfaceNormal(origin); - * var plane = Cesium.Plane.fromPointNormal(origin, normal); + * @exports cancelAnimationFrame * - * var p0 = new Cesium.Cartesian3(...); - * var p1 = new Cesium.Cartesian3(...); + * @param {Number} requestID The value returned by {@link requestAnimationFrame}. * - * // find the intersection of the line segment from p0 to p1 and the tangent plane at origin. - * var intersection = Cesium.IntersectionTests.lineSegmentPlane(p0, p1, plane); + * @see {@link http://www.w3.org/TR/animation-timing/#the-WindowAnimationTiming-interface|The WindowAnimationTiming interface} */ - IntersectionTests.lineSegmentPlane = function(endPoint0, endPoint1, plane, result) { - if (!defined(endPoint0)) { - throw new DeveloperError('endPoint0 is required.'); - } - if (!defined(endPoint1)) { - throw new DeveloperError('endPoint1 is required.'); - } - if (!defined(plane)) { - throw new DeveloperError('plane is required.'); - } - - if (!defined(result)) { - result = new Cartesian3(); - } - - var difference = Cartesian3.subtract(endPoint1, endPoint0, lineSegmentPlaneDifference); - var normal = plane.normal; - var nDotDiff = Cartesian3.dot(normal, difference); - - // check if the segment and plane are parallel - if (Math.abs(nDotDiff) < CesiumMath.EPSILON6) { - return undefined; - } - - var nDotP0 = Cartesian3.dot(normal, endPoint0); - var t = -(plane.distance + nDotP0) / nDotDiff; + function cancelAnimationFrame(requestID) { + // we need this extra wrapper function because the native cancelAnimationFrame + // functions must be invoked on the global scope (window), which is not the case + // if invoked as Cesium.cancelAnimationFrame(requestID) + implementation(requestID); + } - // intersection only if t is in [0, 1] - if (t < 0.0 || t > 1.0) { - return undefined; - } + return cancelAnimationFrame; +}); - // intersection is endPoint0 + t * (endPoint1 - endPoint0) - Cartesian3.multiplyByScalar(difference, t, result); - Cartesian3.add(endPoint0, result, result); - return result; - }; +define('Core/CartographicGeocoderService',[ + '../ThirdParty/when', + './Cartesian3', + './Check' + ], function( + when, + Cartesian3, + Check) { + 'use strict'; /** - * Computes the intersection of a triangle and a plane - * - * @param {Cartesian3} p0 First point of the triangle - * @param {Cartesian3} p1 Second point of the triangle - * @param {Cartesian3} p2 Third point of the triangle - * @param {Plane} plane Intersection plane - * @returns {Object} An object with properties <code>positions</code> and <code>indices</code>, which are arrays that represent three triangles that do not cross the plane. (Undefined if no intersection exists) - * - * @example - * var origin = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); - * var normal = ellipsoid.geodeticSurfaceNormal(origin); - * var plane = Cesium.Plane.fromPointNormal(origin, normal); + * Geocodes queries containing longitude and latitude coordinates and an optional height. + * Query format: `longitude latitude (height)` with longitude/latitude in degrees and height in meters. * - * var p0 = new Cesium.Cartesian3(...); - * var p1 = new Cesium.Cartesian3(...); - * var p2 = new Cesium.Cartesian3(...); + * @alias CartographicGeocoderService + * @constructor + */ + function CartographicGeocoderService() { + } + + /** + * @function * - * // convert the triangle composed of points (p0, p1, p2) to three triangles that don't cross the plane - * var triangles = Cesium.IntersectionTests.trianglePlaneIntersection(p0, p1, p2, plane); + * @param {String} query The query to be sent to the geocoder service + * @returns {Promise<GeocoderResult[]>} */ - IntersectionTests.trianglePlaneIntersection = function(p0, p1, p2, plane) { - if ((!defined(p0)) || - (!defined(p1)) || - (!defined(p2)) || - (!defined(plane))) { - throw new DeveloperError('p0, p1, p2, and plane are required.'); - } + CartographicGeocoderService.prototype.geocode = function(query) { + Check.typeOf.string('query', query); - var planeNormal = plane.normal; - var planeD = plane.distance; - var p0Behind = (Cartesian3.dot(planeNormal, p0) + planeD) < 0.0; - var p1Behind = (Cartesian3.dot(planeNormal, p1) + planeD) < 0.0; - var p2Behind = (Cartesian3.dot(planeNormal, p2) + planeD) < 0.0; - // Given these dots products, the calls to lineSegmentPlaneIntersection - // always have defined results. - - var numBehind = 0; - numBehind += p0Behind ? 1 : 0; - numBehind += p1Behind ? 1 : 0; - numBehind += p2Behind ? 1 : 0; - - var u1, u2; - if (numBehind === 1 || numBehind === 2) { - u1 = new Cartesian3(); - u2 = new Cartesian3(); - } - - if (numBehind === 1) { - if (p0Behind) { - IntersectionTests.lineSegmentPlane(p0, p1, plane, u1); - IntersectionTests.lineSegmentPlane(p0, p2, plane, u2); - - return { - positions : [p0, p1, p2, u1, u2 ], - indices : [ - // Behind - 0, 3, 4, - - // In front - 1, 2, 4, - 1, 4, 3 - ] - }; - } else if (p1Behind) { - IntersectionTests.lineSegmentPlane(p1, p2, plane, u1); - IntersectionTests.lineSegmentPlane(p1, p0, plane, u2); - - return { - positions : [p0, p1, p2, u1, u2 ], - indices : [ - // Behind - 1, 3, 4, - - // In front - 2, 0, 4, - 2, 4, 3 - ] - }; - } else if (p2Behind) { - IntersectionTests.lineSegmentPlane(p2, p0, plane, u1); - IntersectionTests.lineSegmentPlane(p2, p1, plane, u2); - - return { - positions : [p0, p1, p2, u1, u2 ], - indices : [ - // Behind - 2, 3, 4, + var splitQuery = query.match(/[^\s,\n]+/g); + if ((splitQuery.length === 2) || (splitQuery.length === 3)) { + var longitude = +splitQuery[0]; + var latitude = +splitQuery[1]; + var height = (splitQuery.length === 3) ? +splitQuery[2] : 300.0; - // In front - 0, 1, 4, - 0, 4, 3 - ] - }; + if (isNaN(longitude) && isNaN(latitude)) { + var coordTest = /^(\d+.?\d*)([nsew])/i; + for (var i = 0; i < splitQuery.length; ++i) { + var splitCoord = splitQuery[i].match(coordTest); + if (coordTest.test(splitQuery[i]) && splitCoord.length === 3) { + if (/^[ns]/i.test(splitCoord[2])) { + latitude = (/^[n]/i.test(splitCoord[2])) ? +splitCoord[1] : -splitCoord[1]; + } else if (/^[ew]/i.test(splitCoord[2])) { + longitude = (/^[e]/i.test(splitCoord[2])) ? +splitCoord[1] : -splitCoord[1]; + } + } + } } - } else if (numBehind === 2) { - if (!p0Behind) { - IntersectionTests.lineSegmentPlane(p1, p0, plane, u1); - IntersectionTests.lineSegmentPlane(p2, p0, plane, u2); - - return { - positions : [p0, p1, p2, u1, u2 ], - indices : [ - // Behind - 1, 2, 4, - 1, 4, 3, - - // In front - 0, 3, 4 - ] - }; - } else if (!p1Behind) { - IntersectionTests.lineSegmentPlane(p2, p1, plane, u1); - IntersectionTests.lineSegmentPlane(p0, p1, plane, u2); - - return { - positions : [p0, p1, p2, u1, u2 ], - indices : [ - // Behind - 2, 0, 4, - 2, 4, 3, - - // In front - 1, 3, 4 - ] - }; - } else if (!p2Behind) { - IntersectionTests.lineSegmentPlane(p0, p2, plane, u1); - IntersectionTests.lineSegmentPlane(p1, p2, plane, u2); - - return { - positions : [p0, p1, p2, u1, u2 ], - indices : [ - // Behind - 0, 1, 4, - 0, 4, 3, - // In front - 2, 3, 4 - ] + if (!isNaN(longitude) && !isNaN(latitude) && !isNaN(height)) { + var result = { + displayName: query, + destination: Cartesian3.fromDegrees(longitude, latitude, height) }; + return when.resolve([result]); } } - - // if numBehind is 3, the triangle is completely behind the plane; - // otherwise, it is completely in front (numBehind is 0). - return undefined; + return when.resolve([]); }; - return IntersectionTests; + return CartographicGeocoderService; }); -define('Core/Plane',[ - './Cartesian3', +define('Core/Spline',[ './Check', + './defaultValue', './defined', './DeveloperError', - './freezeObject', - './Math', - './Matrix4' - ], function( - Cartesian3, + './Math' +], function( Check, + defaultValue, defined, DeveloperError, - freezeObject, - CesiumMath, - Matrix4) { + CesiumMath) { 'use strict'; /** - * A plane in Hessian Normal Form defined by - * <pre> - * ax + by + cz + d = 0 - * </pre> - * where (a, b, c) is the plane's <code>normal</code>, d is the signed - * <code>distance</code> to the plane, and (x, y, z) is any point on - * the plane. + * Creates a curve parameterized and evaluated by time. This type describes an interface + * and is not intended to be instantiated directly. * - * @alias Plane + * @alias Spline * @constructor * - * @param {Cartesian3} normal The plane's normal (normalized). - * @param {Number} distance The shortest distance from the origin to the plane. The sign of - * <code>distance</code> determines which side of the plane the origin - * is on. If <code>distance</code> is positive, the origin is in the half-space - * in the direction of the normal; if negative, the origin is in the half-space - * opposite to the normal; if zero, the plane passes through the origin. - * - * @example - * // The plane x=0 - * var plane = new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0); - * - * @exception {DeveloperError} Normal must be normalized + * @see CatmullRomSpline + * @see HermiteSpline + * @see LinearSpline + * @see QuaternionSpline */ - function Plane(normal, distance) { - Check.typeOf.object('normal', normal); - if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { - throw new DeveloperError('normal must be normalized.'); - } - Check.typeOf.number('distance', distance); - + function Spline() { /** - * The plane's normal. - * - * @type {Cartesian3} + * An array of times for the control points. + * @type {Number[]} + * @default undefined */ - this.normal = Cartesian3.clone(normal); + this.times = undefined; /** - * The shortest distance from the origin to the plane. The sign of - * <code>distance</code> determines which side of the plane the origin - * is on. If <code>distance</code> is positive, the origin is in the half-space - * in the direction of the normal; if negative, the origin is in the half-space - * opposite to the normal; if zero, the plane passes through the origin. - * - * @type {Number} + * An array of control points. + * @type {Cartesian3[]|Quaternion[]} + * @default undefined */ - this.distance = distance; + this.points = undefined; + + DeveloperError.throwInstantiationError(); } /** - * Creates a plane from a normal and a point on the plane. - * - * @param {Cartesian3} point The point on the plane. - * @param {Cartesian3} normal The plane's normal (normalized). - * @param {Plane} [result] The object onto which to store the result. - * @returns {Plane} A new plane instance or the modified result parameter. + * Evaluates the curve at a given time. + * @function * - * @example - * var point = Cesium.Cartesian3.fromDegrees(-72.0, 40.0); - * var normal = ellipsoid.geodeticSurfaceNormal(point); - * var tangentPlane = Cesium.Plane.fromPointNormal(point, normal); + * @param {Number} time The time at which to evaluate the curve. + * @param {Cartesian3|Quaternion} [result] The object onto which to store the result. + * @returns {Cartesian3|Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. * - * @exception {DeveloperError} Normal must be normalized + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - Plane.fromPointNormal = function(point, normal, result) { - Check.typeOf.object('point', point); - Check.typeOf.object('normal', normal); - if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { - throw new DeveloperError('normal must be normalized.'); - } - - var distance = -Cartesian3.dot(normal, point); - - if (!defined(result)) { - return new Plane(normal, distance); - } - - Cartesian3.clone(normal, result.normal); - result.distance = distance; - return result; - }; + Spline.prototype.evaluate = DeveloperError.throwInstantiationError; - var scratchNormal = new Cartesian3(); /** - * Creates a plane from the general equation + * Finds an index <code>i</code> in <code>times</code> such that the parameter + * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * - * @param {Cartesian4} coefficients The plane's normal (normalized). - * @param {Plane} [result] The object onto which to store the result. - * @returns {Plane} A new plane instance or the modified result parameter. + * @param {Number} time The time. + * @param {Number} startIndex The index from which to start the search. + * @returns {Number} The index for the element at the start of the interval. * - * @exception {DeveloperError} Normal must be normalized + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - Plane.fromCartesian4 = function(coefficients, result) { - Check.typeOf.object('coefficients', coefficients); - - var normal = Cartesian3.fromCartesian4(coefficients, scratchNormal); - var distance = coefficients.w; + Spline.prototype.findTimeInterval = function(time, startIndex) { + var times = this.times; + var length = times.length; - if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { - throw new DeveloperError('normal must be normalized.'); + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (time < times[0] || time > times[length - 1]) { + throw new DeveloperError('time is out of range.'); } - if (!defined(result)) { - return new Plane(normal, distance); + // Take advantage of temporal coherence by checking current, next and previous intervals + // for containment of time. + startIndex = defaultValue(startIndex, 0); + + if (time >= times[startIndex]) { + if (startIndex + 1 < length && time < times[startIndex + 1]) { + return startIndex; + } else if (startIndex + 2 < length && time < times[startIndex + 2]) { + return startIndex + 1; + } + } else if (startIndex - 1 >= 0 && time >= times[startIndex - 1]) { + return startIndex - 1; } - Cartesian3.clone(normal, result.normal); - result.distance = distance; - return result; + + // The above failed so do a linear search. For the use cases so far, the + // length of the list is less than 10. In the future, if there is a bottle neck, + // it might be here. + + var i; + if (time > times[startIndex]) { + for (i = startIndex; i < length - 1; ++i) { + if (time >= times[i] && time < times[i + 1]) { + break; + } + } + } else { + for (i = startIndex - 1; i >= 0; --i) { + if (time >= times[i] && time < times[i + 1]) { + break; + } + } + } + + if (i === length - 1) { + i = length - 2; + } + + return i; }; /** - * Computes the signed shortest distance of a point to a plane. - * The sign of the distance determines which side of the plane the point - * is on. If the distance is positive, the point is in the half-space - * in the direction of the normal; if negative, the point is in the half-space - * opposite to the normal; if zero, the plane passes through the point. + * Wraps the given time to the period covered by the spline. + * @function * - * @param {Plane} plane The plane. - * @param {Cartesian3} point The point. - * @returns {Number} The signed shortest distance of the point to the plane. + * @param {Number} time The time. + * @return {Number} The time, wrapped around the animation period. */ - Plane.getPointDistance = function(plane, point) { - Check.typeOf.object('plane', plane); - Check.typeOf.object('point', point); + Spline.prototype.wrapTime = function(time) { + Check.typeOf.number('time', time); - return Cartesian3.dot(plane.normal, point) + plane.distance; + var times = this.times; + var timeEnd = times[times.length - 1]; + var timeStart = times[0]; + var timeStretch = timeEnd - timeStart; + var divs; + if (time < timeStart) { + divs = Math.floor((timeStart - time) / timeStretch) + 1; + time += divs * timeStretch; + } + if (time > timeEnd) { + divs = Math.floor((time - timeEnd) / timeStretch) + 1; + time -= divs * timeStretch; + } + return time; }; - var scratchPosition = new Cartesian3(); /** - * Transforms the plane by the given transformation matrix. + * Clamps the given time to the period covered by the spline. + * @function * - * @param {Plane} plane The plane. - * @param {Matrix4} transform The transformation matrix. - * @param {Plane} [result] The object into which to store the result. - * @returns {Plane} The plane transformed by the given transformation matrix. + * @param {Number} time The time. + * @return {Number} The time, clamped to the animation period. */ - Plane.transform = function(plane, transform, result) { - Check.typeOf.object('plane', plane); - Check.typeOf.object('transform', transform); + Spline.prototype.clampTime = function(time) { + Check.typeOf.number('time', time); - Matrix4.multiplyByPointAsVector(transform, plane.normal, scratchNormal); - Cartesian3.normalize(scratchNormal, scratchNormal); + var times = this.times; + return CesiumMath.clamp(time, times[0], times[times.length - 1]); + }; - Cartesian3.multiplyByScalar(plane.normal, -plane.distance, scratchPosition); - Matrix4.multiplyByPoint(transform, scratchPosition, scratchPosition); + return Spline; +}); - return Plane.fromPointNormal(scratchPosition, scratchNormal, result); - }; +define('Core/LinearSpline',[ + './Cartesian3', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Spline' + ], function( + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Spline) { + 'use strict'; /** - * Duplicates a Plane instance. + * A spline that uses piecewise linear interpolation to create a curve. * - * @param {Plane} plane The plane to duplicate. - * @param {Plane} [result] The object onto which to store the result. - * @returns {Plane} The modified result parameter or a new Plane instance if one was not provided. + * @alias LinearSpline + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * The values are in no way connected to the clock time. They are the parameterization for the curve. + * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. + * + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be equal to points.length. + * + * + * @example + * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ]; + * var spline = new Cesium.LinearSpline({ + * times : times, + * points : [ + * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), + * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), + * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), + * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), + * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) + * ] + * }); + * + * var p0 = spline.evaluate(times[0]); + * + * @see HermiteSpline + * @see CatmullRomSpline + * @see QuaternionSpline + * @see WeightSpline */ - Plane.clone = function(plane, result) { - Check.typeOf.object('plane', plane); - - if (!defined(result)) { - return new Plane(plane.normal, plane.distance); + function LinearSpline(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var points = options.points; + var times = options.times; + + if (!defined(points) || !defined(times)) { + throw new DeveloperError('points and times are required.'); + } + if (points.length < 2) { + throw new DeveloperError('points.length must be greater than or equal to 2.'); } + if (times.length !== points.length) { + throw new DeveloperError('times.length must be equal to points.length.'); + } + + this._times = times; + this._points = points; - Cartesian3.clone(plane.normal, result.normal); - result.distance = plane.distance; + this._lastTimeIndex = 0; + } - return result; - }; + defineProperties(LinearSpline.prototype, { + /** + * An array of times for the control points. + * + * @memberof LinearSpline.prototype + * + * @type {Number[]} + * @readonly + */ + times : { + get : function() { + return this._times; + } + }, + + /** + * An array of {@link Cartesian3} control points. + * + * @memberof LinearSpline.prototype + * + * @type {Cartesian3[]} + * @readonly + */ + points : { + get : function() { + return this._points; + } + } + }); /** - * Compares the provided Planes by normal and distance and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Finds an index <code>i</code> in <code>times</code> such that the parameter + * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. + * @function * - * @param {Plane} left The first plane. - * @param {Plane} right The second plane. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @param {Number} time The time. + * @returns {Number} The index for the element at the start of the interval. + * + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - Plane.equals = function(left, right) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - - return (left.distance === right.distance) && Cartesian3.equals(left.normal, right.normal); - }; + LinearSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; /** - * A constant initialized to the XY plane passing through the origin, with normal in positive Z. + * Wraps the given time to the period covered by the spline. + * @function * - * @type {Plane} - * @constant + * @param {Number} time The time. + * @return {Number} The time, wrapped around to the updated animation. */ - Plane.ORIGIN_XY_PLANE = freezeObject(new Plane(Cartesian3.UNIT_Z, 0.0)); + LinearSpline.prototype.wrapTime = Spline.prototype.wrapTime; /** - * A constant initialized to the YZ plane passing through the origin, with normal in positive X. + * Clamps the given time to the period covered by the spline. + * @function * - * @type {Plane} - * @constant + * @param {Number} time The time. + * @return {Number} The time, clamped to the animation period. */ - Plane.ORIGIN_YZ_PLANE = freezeObject(new Plane(Cartesian3.UNIT_X, 0.0)); + LinearSpline.prototype.clampTime = Spline.prototype.clampTime; /** - * A constant initialized to the ZX plane passing through the origin, with normal in positive Y. + * Evaluates the curve at a given time. * - * @type {Plane} - * @constant + * @param {Number} time The time at which to evaluate the curve. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. + * + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - Plane.ORIGIN_ZX_PLANE = freezeObject(new Plane(Cartesian3.UNIT_Y, 0.0)); + LinearSpline.prototype.evaluate = function(time, result) { + var points = this.points; + var times = this.times; - return Plane; -}); + var i = this._lastTimeIndex = this.findTimeInterval(time, this._lastTimeIndex); + var u = (time - times[i]) / (times[i + 1] - times[i]); -define('Core/EarthOrientationParametersSample',[],function() { + if (!defined(result)) { + result = new Cartesian3(); + } + + return Cartesian3.lerp(points[i], points[i + 1], u, result); + }; + + return LinearSpline; +}); + +define('Core/TridiagonalSystemSolver',[ + './Cartesian3', + './defined', + './DeveloperError' + ], function( + Cartesian3, + defined, + DeveloperError) { 'use strict'; /** - * A set of Earth Orientation Parameters (EOP) sampled at a time. + * Uses the Tridiagonal Matrix Algorithm, also known as the Thomas Algorithm, to solve + * a system of linear equations where the coefficient matrix is a tridiagonal matrix. * - * @alias EarthOrientationParametersSample - * @constructor + * @exports TridiagonalSystemSolver + */ + var TridiagonalSystemSolver = {}; + + /** + * Solves a tridiagonal system of linear equations. * - * @param {Number} xPoleWander The pole wander about the X axis, in radians. - * @param {Number} yPoleWander The pole wander about the Y axis, in radians. - * @param {Number} xPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. - * @param {Number} yPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. - * @param {Number} ut1MinusUtc The difference in time standards, UT1 - UTC, in seconds. + * @param {Number[]} diagonal An array with length <code>n</code> that contains the diagonal of the coefficient matrix. + * @param {Number[]} lower An array with length <code>n - 1</code> that contains the lower diagonal of the coefficient matrix. + * @param {Number[]} upper An array with length <code>n - 1</code> that contains the upper diagonal of the coefficient matrix. + * @param {Cartesian3[]} right An array of Cartesians with length <code>n</code> that is the right side of the system of equations. * - * @private + * @exception {DeveloperError} diagonal and right must have the same lengths. + * @exception {DeveloperError} lower and upper must have the same lengths. + * @exception {DeveloperError} lower and upper must be one less than the length of diagonal. + * + * @performance Linear time. + * + * @example + * var lowerDiagonal = [1.0, 1.0, 1.0, 1.0]; + * var diagonal = [2.0, 4.0, 4.0, 4.0, 2.0]; + * var upperDiagonal = [1.0, 1.0, 1.0, 1.0]; + * var rightHandSide = [ + * new Cesium.Cartesian3(410757.0, -1595711.0, 1375302.0), + * new Cesium.Cartesian3(-5986705.0, -2190640.0, 1099600.0), + * new Cesium.Cartesian3(-12593180.0, 288588.0, -1755549.0), + * new Cesium.Cartesian3(-5349898.0, 2457005.0, -2685438.0), + * new Cesium.Cartesian3(845820.0, 1573488.0, -1205591.0) + * ]; + * + * var solution = Cesium.TridiagonalSystemSolver.solve(lowerDiagonal, diagonal, upperDiagonal, rightHandSide); + * + * @returns {Cartesian3[]} An array of Cartesians with length <code>n</code> that is the solution to the tridiagonal system of equations. */ - function EarthOrientationParametersSample(xPoleWander, yPoleWander, xPoleOffset, yPoleOffset, ut1MinusUtc) { - /** - * The pole wander about the X axis, in radians. - * @type {Number} - */ - this.xPoleWander = xPoleWander; + TridiagonalSystemSolver.solve = function(lower, diagonal, upper, right) { + if (!defined(lower) || !(lower instanceof Array)) { + throw new DeveloperError('The array lower is required.'); + } + if (!defined(diagonal) || !(diagonal instanceof Array)) { + throw new DeveloperError('The array diagonal is required.'); + } + if (!defined(upper) || !(upper instanceof Array)) { + throw new DeveloperError('The array upper is required.'); + } + if (!defined(right) || !(right instanceof Array)) { + throw new DeveloperError('The array right is required.'); + } + if (diagonal.length !== right.length) { + throw new DeveloperError('diagonal and right must have the same lengths.'); + } + if (lower.length !== upper.length) { + throw new DeveloperError('lower and upper must have the same lengths.'); + } else if (lower.length !== diagonal.length - 1) { + throw new DeveloperError('lower and upper must be one less than the length of diagonal.'); + } + + var c = new Array(upper.length); + var d = new Array(right.length); + var x = new Array(right.length); - /** - * The pole wander about the Y axis, in radians. - * @type {Number} - */ - this.yPoleWander = yPoleWander; + var i; + for (i = 0; i < d.length; i++) { + d[i] = new Cartesian3(); + x[i] = new Cartesian3(); + } - /** - * The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. - * @type {Number} - */ - this.xPoleOffset = xPoleOffset; + c[0] = upper[0] / diagonal[0]; + d[0] = Cartesian3.multiplyByScalar(right[0], 1.0 / diagonal[0], d[0]); - /** - * The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. - * @type {Number} - */ - this.yPoleOffset = yPoleOffset; + var scalar; + for (i = 1; i < c.length; ++i) { + scalar = 1.0 / (diagonal[i] - c[i - 1] * lower[i - 1]); + c[i] = upper[i] * scalar; + d[i] = Cartesian3.subtract(right[i], Cartesian3.multiplyByScalar(d[i - 1], lower[i - 1], d[i]), d[i]); + d[i] = Cartesian3.multiplyByScalar(d[i], scalar, d[i]); + } - /** - * The difference in time standards, UT1 - UTC, in seconds. - * @type {Number} - */ - this.ut1MinusUtc = ut1MinusUtc; - } + scalar = 1.0 / (diagonal[i] - c[i - 1] * lower[i - 1]); + d[i] = Cartesian3.subtract(right[i], Cartesian3.multiplyByScalar(d[i - 1], lower[i - 1], d[i]), d[i]); + d[i] = Cartesian3.multiplyByScalar(d[i], scalar, d[i]); - return EarthOrientationParametersSample; -}); + x[x.length - 1] = d[d.length - 1]; + for (i = x.length - 2; i >= 0; --i) { + x[i] = Cartesian3.subtract(d[i], Cartesian3.multiplyByScalar(x[i + 1], c[i], x[i]), x[i]); + } -/** -@license -sprintf.js from the php.js project - https://github.com/kvz/phpjs -Directly from https://github.com/kvz/phpjs/blob/master/functions/strings/sprintf.js + return x; + }; -php.js is copyright 2012 Kevin van Zonneveld. + return TridiagonalSystemSolver; +}); -Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld -(http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White -(http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jack, Jonas -Raoni Soares Silva (http://www.jsfromhell.com), Philip Peterson, Legaev -Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous, Martijn Wieringa, -Rafa? Kukawski (http://blog.kukawski.pl), lmeyrick -(https://sourceforge.net/projects/bcmath-js/), Nate, Philippe Baumann, -Enrique Gonzalez, Webtoolkit.info (http://www.webtoolkit.info/), Carlos R. -L. Rodrigues (http://www.jsfromhell.com), Ash Searle -(http://hexmen.com/blog/), Jani Hartikainen, travc, Ole Vrijenhoek, -Erkekjetter, Michael Grier, Rafa? Kukawski (http://kukawski.pl), Johnny -Mast (http://www.phpvrouwen.nl), T.Wild, d3x, -http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript, -Rafa? Kukawski (http://blog.kukawski.pl/), stag019, pilus, WebDevHobo -(http://webdevhobo.blogspot.com/), marrtins, GeekFG -(http://geekfg.blogspot.com), Andrea Giammarchi -(http://webreflection.blogspot.com), Arpad Ray (mailto:arpad@php.net), -gorthaur, Paul Smith, Tim de Koning (http://www.kingsquare.nl), Joris, Oleg -Eremeev, Steve Hilder, majak, gettimeofday, KELAN, Josh Fraser -(http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/), -Marc Palau, Martin -(http://www.erlenwiese.de/), Breaking Par Consulting Inc -(http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7), -Chris, Mirek Slugen, saulius, Alfonso Jimenez -(http://www.alfonsojimenez.com), Diplom@t (http://difane.com/), felix, -Mailfaker (http://www.weedem.fr/), Tyler Akins (http://rumkin.com), Caio -Ariede (http://caioariede.com), Robin, Kankrelune -(http://www.webfaktory.info/), Karol Kowalski, Imgen Tata -(http://www.myipdf.com/), mdsjack (http://www.mdsjack.bo.it), Dreamer, -Felix Geisendoerfer (http://www.debuggable.com/felix), Lars Fischer, AJ, -David, Aman Gupta, Michael White, Public Domain -(http://www.json.org/json2.js), Steven Levithan -(http://blog.stevenlevithan.com), Sakimori, Pellentesque Malesuada, -Thunder.m, Dj (http://phpjs.org/functions/htmlentities:425#comment_134018), -Steve Clay, David James, Francois, class_exists, nobbler, T. Wild, Itsacon -(http://www.itsacon.net/), date, Ole Vrijenhoek (http://www.nervous.nl/), -Fox, Raphael (Ao RUDLER), Marco, noname, Mateusz "loonquawl" Zalega, Frank -Forte, Arno, ger, mktime, john (http://www.jd-tech.net), Nick Kolosov -(http://sammy.ru), marc andreu, Scott Cariss, Douglas Crockford -(http://javascript.crockford.com), madipta, Slawomir Kaniecki, -ReverseSyntax, Nathan, Alex Wilson, kenneth, Bayron Guevara, Adam Wallner -(http://web2.bitbaro.hu/), paulo kuong, jmweb, Lincoln Ramsay, djmix, -Pyerre, Jon Hohle, Thiago Mata (http://thiagomata.blog.com), lmeyrick -(https://sourceforge.net/projects/bcmath-js/this.), Linuxworld, duncan, -Gilbert, Sanjoy Roy, Shingo, sankai, Oskar Larsson H?gfeldt -(http://oskar-lh.name/), Denny Wardhana, 0m3r, Everlasto, Subhasis Deb, -josh, jd, Pier Paolo Ramon (http://www.mastersoup.com/), P, merabi, Soren -Hansen, Eugene Bulkin (http://doubleaw.com/), Der Simon -(http://innerdom.sourceforge.net/), echo is bad, Ozh, XoraX -(http://www.xorax.info), EdorFaus, JB, J A R, Marc Jansen, Francesco, LH, -Stoyan Kyosev (http://www.svest.org/), nord_ua, omid -(http://phpjs.org/functions/380:380#comment_137122), Brad Touesnard, MeEtc -(http://yass.meetcweb.com), Peter-Paul Koch -(http://www.quirksmode.org/js/beat.html), Olivier Louvignes -(http://mg-crea.com/), T0bsn, Tim Wiel, Bryan Elliott, Jalal Berrami, -Martin, JT, David Randall, Thomas Beaucourt (http://www.webapp.fr), taith, -vlado houba, Pierre-Luc Paour, Kristof Coomans (SCK-CEN Belgian Nucleair -Research Centre), Martin Pool, Kirk Strobeck, Rick Waldron, Brant Messenger -(http://www.brantmessenger.com/), Devan Penner-Woelk, Saulo Vallory, Wagner -B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong -(http://carrot.org/), Christoph, Daniel Esteban, strftime, Mick@el, rezna, -Simon Willison (http://simonwillison.net), Anton Ongson, Gabriel Paderni, -Marco van Oort, penutbutterjelly, Philipp Lenssen, Bjorn Roesbeke -(http://www.bjornroesbeke.be/), Bug?, Eric Nagel, Tomasz Wesolowski, -Evertjan Garretsen, Bobby Drake, Blues (http://tech.bluesmoon.info/), Luke -Godfrey, Pul, uestla, Alan C, Ulrich, Rafal Kukawski, Yves Sucaet, -sowberry, Norman "zEh" Fuchs, hitwork, Zahlii, johnrembo, Nick Callen, -Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Brian Tafoya -(http://www.premasolutions.com/), Philippe Jausions -(http://pear.php.net/user/jausions), Aidan Lister -(http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp, -strcmp, Taras Bogach, jpfle, Alexander Ermolaev -(http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando, -dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha -(http://www.pedrotainha.com), James, Arnout Kazemier -(http://www.3rd-Eden.com), Chris McMacken, gabriel paderni, Yannoo, -FGFEmperor, baris ozdil, Tod Gentille, Greg Frazier, jakes, 3D-GRAF, Allan -Jensen (http://www.winternet.no), Howard Yeend, Benjamin Lupton, davook, -daniel airton wermann (http://wermann.com.br), Atli T¨®r, Maximusya, Ryan -W Tenney (http://ryan.10e.us), Alexander M Beedie, fearphage -(http://http/my.opera.com/fearphage/), Nathan Sepulveda, Victor, Matteo, -Billy, stensi, Cord, Manish, T.J. Leahy, Riddler -(http://www.frontierwebdev.com/), Rafa? Kukawski, FremyCompany, Matt -Bradley, Tim de Koning, Luis Salazar (http://www.freaky-media.com/), Diogo -Resende, Rival, Andrej Pavlovic, Garagoth, Le Torbi -(http://www.letorbi.de/), Dino, Josep Sanz (http://www.ws3.es/), rem, -Russell Walker (http://www.nbill.co.uk/), Jamie Beck -(http://www.terabit.ca/), setcookie, Michael, YUI Library: -http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at -http://hacks.bluesmoon.info/strftime/strftime.js, Ben -(http://benblume.co.uk/), DtTvB -(http://dt.in.th/2008-09-16.string-length-in-bytes.html), Andreas, William, -meo, incidence, Cagri Ekin, Amirouche, Amir Habibi -(http://www.residence-mixte.com/), Luke Smith (http://lucassmith.name), -Kheang Hok Chin (http://www.distantia.ca/), Jay Klehr, Lorenzo Pisani, -Tony, Yen-Wei Liu, Greenseed, mk.keck, Leslie Hoare, dude, booeyOH, Ben -Bryan +define('Core/HermiteSpline',[ + './Cartesian3', + './Cartesian4', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './LinearSpline', + './Matrix4', + './Spline', + './TridiagonalSystemSolver' + ], function( + Cartesian3, + Cartesian4, + defaultValue, + defined, + defineProperties, + DeveloperError, + LinearSpline, + Matrix4, + Spline, + TridiagonalSystemSolver) { + 'use strict'; -Licensed under the MIT (MIT-LICENSE.txt) license. + var scratchLower = []; + var scratchDiagonal = []; + var scratchUpper = []; + var scratchRight = []; -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: + function generateClamped(points, firstTangent, lastTangent) { + var l = scratchLower; + var u = scratchUpper; + var d = scratchDiagonal; + var r = scratchRight; -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. + l.length = u.length = points.length - 1; + d.length = r.length = points.length; -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 KEVIN VAN ZONNEVELD 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. -*/ + var i; + l[0] = d[0] = 1.0; + u[0] = 0.0; -define('ThirdParty/sprintf',[],function() { + var right = r[0]; + if (!defined(right)) { + right = r[0] = new Cartesian3(); + } + Cartesian3.clone(firstTangent, right); -function sprintf () { - // http://kevin.vanzonneveld.net - // + original by: Ash Searle (http://hexmen.com/blog/) - // + namespaced by: Michael White (http://getsprink.com) - // + tweaked by: Jack - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Paulo Freitas - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Brett Zamir (http://brett-zamir.me) - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + improved by: Dj - // + improved by: Allidylls - // * example 1: sprintf("%01.2f", 123.1); - // * returns 1: 123.10 - // * example 2: sprintf("[%10s]", 'monkey'); - // * returns 2: '[ monkey]' - // * example 3: sprintf("[%'#10s]", 'monkey'); - // * returns 3: '[####monkey]' - // * example 4: sprintf("%d", 123456789012345); - // * returns 4: '123456789012345' - var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g; - var a = arguments, - i = 0, - format = a[i++]; + for (i = 1; i < l.length - 1; ++i) { + l[i] = u[i] = 1.0; + d[i] = 4.0; - // pad() - var pad = function (str, len, chr, leftJustify) { - if (!chr) { - chr = ' '; - } + right = r[i]; + if (!defined(right)) { + right = r[i] = new Cartesian3(); + } + Cartesian3.subtract(points[i + 1], points[i - 1], right); + Cartesian3.multiplyByScalar(right, 3.0, right); + } - var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); - return leftJustify ? str + padding : padding + str; - }; + l[i] = 0.0; + u[i] = 1.0; + d[i] = 4.0; - // justify() - var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) { - var diff = minWidth - value.length; - if (diff > 0) { - if (leftJustify || !zeroPad) { - value = pad(value, minWidth, customPadChar, leftJustify); - } else { - value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); - } - } - return value; - }; + right = r[i]; + if (!defined(right)) { + right = r[i] = new Cartesian3(); + } + Cartesian3.subtract(points[i + 1], points[i - 1], right); + Cartesian3.multiplyByScalar(right, 3.0, right); - // formatBaseX() - var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) { - // Note: casts negative numbers to positive ones - var number = value >>> 0; - prefix = prefix && number && { - '2': '0b', - '8': '0', - '16': '0x' - }[base] || ''; - value = prefix + pad(number.toString(base), precision || 0, '0', false); - return justify(value, prefix, leftJustify, minWidth, zeroPad); - }; + d[i + 1] = 1.0; + right = r[i + 1]; + if (!defined(right)) { + right = r[i + 1] = new Cartesian3(); + } + Cartesian3.clone(lastTangent, right); - // formatString() - var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) { - if (precision != null) { - value = value.slice(0, precision); + return TridiagonalSystemSolver.solve(l, d, u, r); } - return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar); - }; - // doFormat() - var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) { - var number; - var prefix; - var method; - var textTransform; - var value; + function generateNatural(points){ + var l = scratchLower; + var u = scratchUpper; + var d = scratchDiagonal; + var r = scratchRight; - if (substring == '%%') { - return '%'; - } + l.length = u.length = points.length - 1; + d.length = r.length = points.length; - // parse flags - var leftJustify = false, - positivePrefix = '', - zeroPad = false, - prefixBaseX = false, - customPadChar = ' '; - var flagsl = flags.length; - for (var j = 0; flags && j < flagsl; j++) { - switch (flags.charAt(j)) { - case ' ': - positivePrefix = ' '; - break; - case '+': - positivePrefix = '+'; - break; - case '-': - leftJustify = true; - break; - case "'": - customPadChar = flags.charAt(j + 1); - break; - case '0': - zeroPad = true; - break; - case '#': - prefixBaseX = true; - break; - } - } + var i; + l[0] = u[0] = 1.0; + d[0] = 2.0; - // parameters may be null, undefined, empty-string or real valued - // we want to ignore null, undefined and empty-string values - if (!minWidth) { - minWidth = 0; - } else if (minWidth == '*') { - minWidth = +a[i++]; - } else if (minWidth.charAt(0) == '*') { - minWidth = +a[minWidth.slice(1, -1)]; - } else { - minWidth = +minWidth; - } + var right = r[0]; + if (!defined(right)) { + right = r[0] = new Cartesian3(); + } + Cartesian3.subtract(points[1], points[0], right); + Cartesian3.multiplyByScalar(right, 3.0, right); - // Note: undocumented perl feature: - if (minWidth < 0) { - minWidth = -minWidth; - leftJustify = true; - } + for (i = 1; i < l.length; ++i) { + l[i] = u[i] = 1.0; + d[i] = 4.0; - if (!isFinite(minWidth)) { - throw new Error('sprintf: (minimum-)width must be finite'); - } + right = r[i]; + if (!defined(right)) { + right = r[i] = new Cartesian3(); + } + Cartesian3.subtract(points[i + 1], points[i - 1], right); + Cartesian3.multiplyByScalar(right, 3.0, right); + } - if (!precision) { - precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined; - } else if (precision == '*') { - precision = +a[i++]; - } else if (precision.charAt(0) == '*') { - precision = +a[precision.slice(1, -1)]; - } else { - precision = +precision; - } + d[i] = 2.0; - // grab value using valueIndex if required? - value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; + right = r[i]; + if (!defined(right)) { + right = r[i] = new Cartesian3(); + } + Cartesian3.subtract(points[i], points[i - 1], right); + Cartesian3.multiplyByScalar(right, 3.0, right); - switch (type) { - case 's': - return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar); - case 'c': - return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad); - case 'b': - return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'o': - return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'x': - return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'X': - return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase(); - case 'u': - return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'i': - case 'd': - number = +value || 0; - number = Math.round(number - number % 1); // Plain Math.round doesn't just truncate - prefix = number < 0 ? '-' : positivePrefix; - value = prefix + pad(String(Math.abs(number)), precision, '0', false); - return justify(value, prefix, leftJustify, minWidth, zeroPad); - case 'e': - case 'E': - case 'f': // Should handle locales (as per setlocale) - case 'F': - case 'g': - case 'G': - number = +value; - prefix = number < 0 ? '-' : positivePrefix; - method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; - textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; - value = prefix + Math.abs(number)[method](precision); - return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform](); - default: - return substring; + return TridiagonalSystemSolver.solve(l, d, u, r); } - }; - - return format.replace(regex, doFormat); -} - -return sprintf; -}); - -define('Core/GregorianDate',[],function() { - 'use strict'; /** - * Represents a Gregorian date in a more precise format than the JavaScript Date object. - * In addition to submillisecond precision, this object can also represent leap seconds. - * @alias GregorianDate + * A Hermite spline is a cubic interpolating spline. Points, incoming tangents, outgoing tangents, and times + * must be defined for each control point. The outgoing tangents are defined for points [0, n - 2] and the incoming + * tangents are defined for points [1, n - 1]. For example, when interpolating a segment of the curve between <code>points[i]</code> and + * <code>points[i + 1]</code>, the tangents at the points will be <code>outTangents[i]</code> and <code>inTangents[i]</code>, + * respectively. + * + * @alias HermiteSpline * @constructor * - * @see JulianDate#toGregorianDate + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * The values are in no way connected to the clock time. They are the parameterization for the curve. + * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. + * @param {Cartesian3[]} options.inTangents The array of {@link Cartesian3} incoming tangents at each control point. + * @param {Cartesian3[]} options.outTangents The array of {@link Cartesian3} outgoing tangents at each control point. + * + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be equal to points.length. + * @exception {DeveloperError} inTangents and outTangents must have a length equal to points.length - 1. + * + * + * @example + * // Create a G<sup>1</sup> continuous Hermite spline + * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ]; + * var spline = new Cesium.HermiteSpline({ + * times : times, + * points : [ + * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), + * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), + * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), + * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), + * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) + * ], + * outTangents : [ + * new Cesium.Cartesian3(1125196, -161816, 270551), + * new Cesium.Cartesian3(-996690.5, -365906.5, 184028.5), + * new Cesium.Cartesian3(-2096917, 48379.5, -292683.5), + * new Cesium.Cartesian3(-890902.5, 408999.5, -447115) + * ], + * inTangents : [ + * new Cesium.Cartesian3(-1993381, -731813, 368057), + * new Cesium.Cartesian3(-4193834, 96759, -585367), + * new Cesium.Cartesian3(-1781805, 817999, -894230), + * new Cesium.Cartesian3(1165345, 112641, 47281) + * ] + * }); + * + * var p0 = spline.evaluate(times[0]); + * + * @see CatmullRomSpline + * @see LinearSpline + * @see QuaternionSpline + * @see WeightSpline */ - function GregorianDate(year, month, day, hour, minute, second, millisecond, isLeapSecond) { - /** - * Gets or sets the year as a whole number. - * @type {Number} - */ - this.year = year; - /** - * Gets or sets the month as a whole number with range [1, 12]. - * @type {Number} - */ - this.month = month; - /** - * Gets or sets the day of the month as a whole number starting at 1. - * @type {Number} - */ - this.day = day; - /** - * Gets or sets the hour as a whole number with range [0, 23]. - * @type {Number} - */ - this.hour = hour; + function HermiteSpline(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var points = options.points; + var times = options.times; + var inTangents = options.inTangents; + var outTangents = options.outTangents; + + if (!defined(points) || !defined(times) || !defined(inTangents) || !defined(outTangents)) { + throw new DeveloperError('times, points, inTangents, and outTangents are required.'); + } + if (points.length < 2) { + throw new DeveloperError('points.length must be greater than or equal to 2.'); + } + if (times.length !== points.length) { + throw new DeveloperError('times.length must be equal to points.length.'); + } + if (inTangents.length !== outTangents.length || inTangents.length !== points.length - 1) { + throw new DeveloperError('inTangents and outTangents must have a length equal to points.length - 1.'); + } + + this._times = times; + this._points = points; + this._inTangents = inTangents; + this._outTangents = outTangents; + + this._lastTimeIndex = 0; + } + + defineProperties(HermiteSpline.prototype, { /** - * Gets or sets the minute of the hour as a whole number with range [0, 59]. - * @type {Number} + * An array of times for the control points. + * + * @memberof HermiteSpline.prototype + * + * @type {Number[]} + * @readonly */ - this.minute = minute; + times : { + get : function() { + return this._times; + } + }, + /** - * Gets or sets the second of the minute as a whole number with range [0, 60], with 60 representing a leap second. - * @type {Number} + * An array of {@link Cartesian3} control points. + * + * @memberof HermiteSpline.prototype + * + * @type {Cartesian3[]} + * @readonly */ - this.second = second; + points : { + get : function() { + return this._points; + } + }, + /** - * Gets or sets the millisecond of the second as a floating point number with range [0.0, 1000.0). - * @type {Number} + * An array of {@link Cartesian3} incoming tangents at each control point. + * + * @memberof HermiteSpline.prototype + * + * @type {Cartesian3[]} + * @readonly */ - this.millisecond = millisecond; + inTangents : { + get : function() { + return this._inTangents; + } + }, + /** - * Gets or sets whether this time is during a leap second. - * @type {Boolean} + * An array of {@link Cartesian3} outgoing tangents at each control point. + * + * @memberof HermiteSpline.prototype + * + * @type {Cartesian3[]} + * @readonly */ - this.isLeapSecond = isLeapSecond; - } - - return GregorianDate; -}); - -define('Core/isLeapYear',[ - './DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + outTangents : { + get : function() { + return this._outTangents; + } + } + }); /** - * Determines if a given date is a leap year. + * Creates a spline where the tangents at each control point are the same. + * The curves are guaranteed to be at least in the class C<sup>1</sup>. * - * @exports isLeapYear + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times The array of control point times. + * @param {Cartesian3[]} options.points The array of control points. + * @param {Cartesian3[]} options.tangents The array of tangents at the control points. + * @returns {HermiteSpline} A hermite spline. * - * @param {Number} year The year to be tested. - * @returns {Boolean} True if <code>year</code> is a leap year. + * @exception {DeveloperError} points, times and tangents are required. + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times, points and tangents must have the same length. * * @example - * var leapYear = Cesium.isLeapYear(2000); // true + * var points = [ + * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), + * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), + * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), + * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), + * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) + * ]; + * + * // Add tangents + * var tangents = new Array(points.length); + * tangents[0] = new Cesium.Cartesian3(1125196, -161816, 270551); + * var temp = new Cesium.Cartesian3(); + * for (var i = 1; i < tangents.length - 1; ++i) { + * tangents[i] = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.subtract(points[i + 1], points[i - 1], temp), 0.5, new Cesium.Cartesian3()); + * } + * tangents[tangents.length - 1] = new Cesium.Cartesian3(1165345, 112641, 47281); + * + * var spline = Cesium.HermiteSpline.createC1({ + * times : times, + * points : points, + * tangents : tangents + * }); */ - function isLeapYear(year) { - if (year === null || isNaN(year)) { - throw new DeveloperError('year is required and must be a number.'); + HermiteSpline.createC1 = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var times = options.times; + var points = options.points; + var tangents = options.tangents; + + if (!defined(points) || !defined(times) || !defined(tangents)) { + throw new DeveloperError('points, times and tangents are required.'); + } + if (points.length < 2) { + throw new DeveloperError('points.length must be greater than or equal to 2.'); + } + if (times.length !== points.length || times.length !== tangents.length) { + throw new DeveloperError('times, points and tangents must have the same length.'); } - return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); - } - - return isLeapYear; -}); + var outTangents = tangents.slice(0, tangents.length - 1); + var inTangents = tangents.slice(1, tangents.length); -define('Core/LeapSecond',[],function() { - 'use strict'; + return new HermiteSpline({ + times : times, + points : points, + inTangents : inTangents, + outTangents : outTangents + }); + }; /** - * Describes a single leap second, which is constructed from a {@link JulianDate} and a - * numerical offset representing the number of seconds TAI is ahead of the UTC time standard. - * @alias LeapSecond - * @constructor + * Creates a natural cubic spline. The tangents at the control points are generated + * to create a curve in the class C<sup>2</sup>. * - * @param {JulianDate} [date] A Julian date representing the time of the leap second. - * @param {Number} [offset] The cumulative number of seconds that TAI is ahead of UTC at the provided date. + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times The array of control point times. + * @param {Cartesian3[]} options.points The array of control points. + * @returns {HermiteSpline|LinearSpline} A hermite spline or a linear spline if less than 3 control points were given. + * + * @exception {DeveloperError} points and times are required. + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be equal to points.length. + * + * @example + * // Create a natural cubic spline above the earth from Philadelphia to Los Angeles. + * var spline = Cesium.HermiteSpline.createNaturalCubic({ + * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ], + * points : [ + * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), + * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), + * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), + * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), + * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) + * ] + * }); */ - function LeapSecond(date, offset) { - /** - * Gets or sets the date at which this leap second occurs. - * @type {JulianDate} - */ - this.julianDate = date; + HermiteSpline.createNaturalCubic = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * Gets or sets the cumulative number of seconds between the UTC and TAI time standards at the time - * of this leap second. - * @type {Number} - */ - this.offset = offset; - } + var times = options.times; + var points = options.points; - return LeapSecond; -}); + if (!defined(points) || !defined(times)) { + throw new DeveloperError('points and times are required.'); + } + if (points.length < 2) { + throw new DeveloperError('points.length must be greater than or equal to 2.'); + } + if (times.length !== points.length) { + throw new DeveloperError('times.length must be equal to points.length.'); + } + + if (points.length < 3) { + return new LinearSpline({ + points : points, + times : times + }); + } -define('Core/TimeConstants',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + var tangents = generateNatural(points); + var outTangents = tangents.slice(0, tangents.length - 1); + var inTangents = tangents.slice(1, tangents.length); + + return new HermiteSpline({ + times : times, + points : points, + inTangents : inTangents, + outTangents : outTangents + }); + }; /** - * Constants for time conversions like those done by {@link JulianDate}. + * Creates a clamped cubic spline. The tangents at the interior control points are generated + * to create a curve in the class C<sup>2</sup>. * - * @exports TimeConstants + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times The array of control point times. + * @param {Cartesian3[]} options.points The array of control points. + * @param {Cartesian3} options.firstTangent The outgoing tangent of the first control point. + * @param {Cartesian3} options.lastTangent The incoming tangent of the last control point. + * @returns {HermiteSpline|LinearSpline} A hermite spline or a linear spline if less than 3 control points were given. * - * @see JulianDate + * @exception {DeveloperError} points, times, firstTangent and lastTangent are required. + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be equal to points.length. * - * @private + * @example + * // Create a clamped cubic spline above the earth from Philadelphia to Los Angeles. + * var spline = Cesium.HermiteSpline.createClampedCubic({ + * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ], + * points : [ + * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), + * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), + * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), + * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), + * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) + * ], + * firstTangent : new Cesium.Cartesian3(1125196, -161816, 270551), + * lastTangent : new Cesium.Cartesian3(1165345, 112641, 47281) + * }); */ - var TimeConstants = { - /** - * The number of seconds in one millisecond: <code>0.001</code> - * @type {Number} - * @constant - */ - SECONDS_PER_MILLISECOND : 0.001, - - /** - * The number of seconds in one minute: <code>60</code>. - * @type {Number} - * @constant - */ - SECONDS_PER_MINUTE : 60.0, - - /** - * The number of minutes in one hour: <code>60</code>. - * @type {Number} - * @constant - */ - MINUTES_PER_HOUR : 60.0, - - /** - * The number of hours in one day: <code>24</code>. - * @type {Number} - * @constant - */ - HOURS_PER_DAY : 24.0, - - /** - * The number of seconds in one hour: <code>3600</code>. - * @type {Number} - * @constant - */ - SECONDS_PER_HOUR : 3600.0, - - /** - * The number of minutes in one day: <code>1440</code>. - * @type {Number} - * @constant - */ - MINUTES_PER_DAY : 1440.0, + HermiteSpline.createClampedCubic = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The number of seconds in one day, ignoring leap seconds: <code>86400</code>. - * @type {Number} - * @constant - */ - SECONDS_PER_DAY : 86400.0, + var times = options.times; + var points = options.points; + var firstTangent = options.firstTangent; + var lastTangent = options.lastTangent; - /** - * The number of days in one Julian century: <code>36525</code>. - * @type {Number} - * @constant - */ - DAYS_PER_JULIAN_CENTURY : 36525.0, + if (!defined(points) || !defined(times) || !defined(firstTangent) || !defined(lastTangent)) { + throw new DeveloperError('points, times, firstTangent and lastTangent are required.'); + } + if (points.length < 2) { + throw new DeveloperError('points.length must be greater than or equal to 2.'); + } + if (times.length !== points.length) { + throw new DeveloperError('times.length must be equal to points.length.'); + } + + if (points.length < 3) { + return new LinearSpline({ + points : points, + times : times + }); + } - /** - * One trillionth of a second. - * @type {Number} - * @constant - */ - PICOSECOND : 0.000000001, + var tangents = generateClamped(points, firstTangent, lastTangent); + var outTangents = tangents.slice(0, tangents.length - 1); + var inTangents = tangents.slice(1, tangents.length); - /** - * The number of days to subtract from a Julian date to determine the - * modified Julian date, which gives the number of days since midnight - * on November 17, 1858. - * @type {Number} - * @constant - */ - MODIFIED_JULIAN_DATE_DIFFERENCE : 2400000.5 + return new HermiteSpline({ + times : times, + points : points, + inTangents : inTangents, + outTangents : outTangents + }); }; - return freezeObject(TimeConstants); -}); - -define('Core/TimeStandard',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + HermiteSpline.hermiteCoefficientMatrix = new Matrix4( + 2.0, -3.0, 0.0, 1.0, + -2.0, 3.0, 0.0, 0.0, + 1.0, -2.0, 1.0, 0.0, + 1.0, -1.0, 0.0, 0.0); /** - * Provides the type of time standards which JulianDate can take as input. + * Finds an index <code>i</code> in <code>times</code> such that the parameter + * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. + * @function * - * @exports TimeStandard + * @param {Number} time The time. + * @returns {Number} The index for the element at the start of the interval. * - * @see JulianDate + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - var TimeStandard = { - /** - * Represents the coordinated Universal Time (UTC) time standard. - * - * UTC is related to TAI according to the relationship - * <code>UTC = TAI - deltaT</code> where <code>deltaT</code> is the number of leap - * seconds which have been introduced as of the time in TAI. - * - * @type {Number} - * @constant - */ - UTC : 0, + HermiteSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; - /** - * Represents the International Atomic Time (TAI) time standard. - * TAI is the principal time standard to which the other time standards are related. - * - * @type {Number} - * @constant - */ - TAI : 1 + var scratchTimeVec = new Cartesian4(); + var scratchTemp = new Cartesian3(); + + /** + * Wraps the given time to the period covered by the spline. + * @function + * + * @param {Number} time The time. + * @return {Number} The time, wrapped around to the updated animation. + */ + HermiteSpline.prototype.wrapTime = Spline.prototype.wrapTime; + + /** + * Clamps the given time to the period covered by the spline. + * @function + * + * @param {Number} time The time. + * @return {Number} The time, clamped to the animation period. + */ + HermiteSpline.prototype.clampTime = Spline.prototype.clampTime; + + /** + * Evaluates the curve at a given time. + * + * @param {Number} time The time at which to evaluate the curve. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. + * + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. + */ + HermiteSpline.prototype.evaluate = function(time, result) { + if (!defined(result)) { + result = new Cartesian3(); + } + var points = this.points; + var times = this.times; + var inTangents = this.inTangents; + var outTangents = this.outTangents; + + var i = this._lastTimeIndex = this.findTimeInterval(time, this._lastTimeIndex); + var u = (time - times[i]) / (times[i + 1] - times[i]); + + var timeVec = scratchTimeVec; + timeVec.z = u; + timeVec.y = u * u; + timeVec.x = timeVec.y * u; + timeVec.w = 1.0; + + var coefs = Matrix4.multiplyByVector(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec); + + result = Cartesian3.multiplyByScalar(points[i], coefs.x, result); + Cartesian3.multiplyByScalar(points[i + 1], coefs.y, scratchTemp); + Cartesian3.add(result, scratchTemp, result); + Cartesian3.multiplyByScalar(outTangents[i], coefs.z, scratchTemp); + Cartesian3.add(result, scratchTemp, result); + Cartesian3.multiplyByScalar(inTangents[i], coefs.w, scratchTemp); + return Cartesian3.add(result, scratchTemp, result); }; - return freezeObject(TimeStandard); + return HermiteSpline; }); -define('Core/JulianDate',[ - '../ThirdParty/sprintf', - './binarySearch', +define('Core/CatmullRomSpline',[ + './Cartesian3', + './Cartesian4', + './Check', './defaultValue', './defined', - './DeveloperError', - './GregorianDate', - './isLeapYear', - './LeapSecond', - './TimeConstants', - './TimeStandard' + './defineProperties', + './HermiteSpline', + './Matrix4', + './Spline' ], function( - sprintf, - binarySearch, + Cartesian3, + Cartesian4, + Check, defaultValue, defined, - DeveloperError, - GregorianDate, - isLeapYear, - LeapSecond, - TimeConstants, - TimeStandard) { + defineProperties, + HermiteSpline, + Matrix4, + Spline) { 'use strict'; - var gregorianDateScratch = new GregorianDate(); - var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - var daysInLeapFeburary = 29; - - function compareLeapSecondDates(leapSecond, dateToFind) { - return JulianDate.compare(leapSecond.julianDate, dateToFind.julianDate); - } + var scratchTimeVec = new Cartesian4(); + var scratchTemp0 = new Cartesian3(); + var scratchTemp1 = new Cartesian3(); - // we don't really need a leap second instance, anything with a julianDate property will do - var binarySearchScratchLeapSecond = new LeapSecond(); + function createEvaluateFunction(spline) { + var points = spline.points; + var times = spline.times; - function convertUtcToTai(julianDate) { - //Even though julianDate is in UTC, we'll treat it as TAI and - //search the leap second table for it. - binarySearchScratchLeapSecond.julianDate = julianDate; - var leapSeconds = JulianDate.leapSeconds; - var index = binarySearch(leapSeconds, binarySearchScratchLeapSecond, compareLeapSecondDates); + if (points.length < 3) { + var t0 = times[0]; + var invSpan = 1.0 / (times[1] - t0); - if (index < 0) { - index = ~index; - } + var p0 = points[0]; + var p1 = points[1]; - if (index >= leapSeconds.length) { - index = leapSeconds.length - 1; + return function(time, result) { + if (!defined(result)){ + result = new Cartesian3(); + } + var u = (time - t0) * invSpan; + return Cartesian3.lerp(p0, p1, u, result); + }; } - var offset = leapSeconds[index].offset; - if (index > 0) { - //Now we have the index of the closest leap second that comes on or after our UTC time. - //However, if the difference between the UTC date being converted and the TAI - //defined leap second is greater than the offset, we are off by one and need to use - //the previous leap second. - var difference = JulianDate.secondsDifference(leapSeconds[index].julianDate, julianDate); - if (difference > offset) { - index--; - offset = leapSeconds[index].offset; + return function(time, result) { + if (!defined(result)) { + result = new Cartesian3(); } - } - - JulianDate.addSeconds(julianDate, offset, julianDate); - } + var i = spline._lastTimeIndex = spline.findTimeInterval(time, spline._lastTimeIndex); + var u = (time - times[i]) / (times[i + 1] - times[i]); - function convertTaiToUtc(julianDate, result) { - binarySearchScratchLeapSecond.julianDate = julianDate; - var leapSeconds = JulianDate.leapSeconds; - var index = binarySearch(leapSeconds, binarySearchScratchLeapSecond, compareLeapSecondDates); - if (index < 0) { - index = ~index; - } + var timeVec = scratchTimeVec; + timeVec.z = u; + timeVec.y = u * u; + timeVec.x = timeVec.y * u; + timeVec.w = 1.0; - //All times before our first leap second get the first offset. - if (index === 0) { - return JulianDate.addSeconds(julianDate, -leapSeconds[0].offset, result); - } + var p0; + var p1; + var p2; + var p3; + var coefs; - //All times after our leap second get the last offset. - if (index >= leapSeconds.length) { - return JulianDate.addSeconds(julianDate, -leapSeconds[index - 1].offset, result); - } + if (i === 0) { + p0 = points[0]; + p1 = points[1]; + p2 = spline.firstTangent; - //Compute the difference between the found leap second and the time we are converting. - var difference = JulianDate.secondsDifference(leapSeconds[index].julianDate, julianDate); + p3 = Cartesian3.subtract(points[2], p0, scratchTemp0); + Cartesian3.multiplyByScalar(p3, 0.5, p3); - if (difference === 0) { - //The date is in our leap second table. - return JulianDate.addSeconds(julianDate, -leapSeconds[index].offset, result); - } + coefs = Matrix4.multiplyByVector(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec); + } else if (i === points.length - 2) { + p0 = points[i]; + p1 = points[i + 1]; + p3 = spline.lastTangent; - if (difference <= 1.0) { - //The requested date is during the moment of a leap second, then we cannot convert to UTC - return undefined; - } + p2 = Cartesian3.subtract(p1, points[i - 1], scratchTemp0); + Cartesian3.multiplyByScalar(p2, 0.5, p2); - //The time is in between two leap seconds, index is the leap second after the date - //we're converting, so we subtract one to get the correct LeapSecond instance. - return JulianDate.addSeconds(julianDate, -leapSeconds[--index].offset, result); + coefs = Matrix4.multiplyByVector(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec); + } else { + p0 = points[i - 1]; + p1 = points[i]; + p2 = points[i + 1]; + p3 = points[i + 2]; + coefs = Matrix4.multiplyByVector(CatmullRomSpline.catmullRomCoefficientMatrix, timeVec, timeVec); + } + result = Cartesian3.multiplyByScalar(p0, coefs.x, result); + Cartesian3.multiplyByScalar(p1, coefs.y, scratchTemp1); + Cartesian3.add(result, scratchTemp1, result); + Cartesian3.multiplyByScalar(p2, coefs.z, scratchTemp1); + Cartesian3.add(result, scratchTemp1, result); + Cartesian3.multiplyByScalar(p3, coefs.w, scratchTemp1); + return Cartesian3.add(result, scratchTemp1, result); + }; } - function setComponents(wholeDays, secondsOfDay, julianDate) { - var extraDays = (secondsOfDay / TimeConstants.SECONDS_PER_DAY) | 0; - wholeDays += extraDays; - secondsOfDay -= TimeConstants.SECONDS_PER_DAY * extraDays; - - if (secondsOfDay < 0) { - wholeDays--; - secondsOfDay += TimeConstants.SECONDS_PER_DAY; - } + var firstTangentScratch = new Cartesian3(); + var lastTangentScratch = new Cartesian3(); - julianDate.dayNumber = wholeDays; - julianDate.secondsOfDay = secondsOfDay; - return julianDate; - } + /** + * A Catmull-Rom spline is a cubic spline where the tangent at control points, + * except the first and last, are computed using the previous and next control points. + * Catmull-Rom splines are in the class C<sup>1</sup>. + * + * @alias CatmullRomSpline + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * The values are in no way connected to the clock time. They are the parameterization for the curve. + * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. + * @param {Cartesian3} [options.firstTangent] The tangent of the curve at the first control point. + * If the tangent is not given, it will be estimated. + * @param {Cartesian3} [options.lastTangent] The tangent of the curve at the last control point. + * If the tangent is not given, it will be estimated. + * + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be equal to points.length. + * + * + * @example + * // spline above the earth from Philadelphia to Los Angeles + * var spline = new Cesium.CatmullRomSpline({ + * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ], + * points : [ + * new Cesium.Cartesian3(1235398.0, -4810983.0, 4146266.0), + * new Cesium.Cartesian3(1372574.0, -5345182.0, 4606657.0), + * new Cesium.Cartesian3(-757983.0, -5542796.0, 4514323.0), + * new Cesium.Cartesian3(-2821260.0, -5248423.0, 4021290.0), + * new Cesium.Cartesian3(-2539788.0, -4724797.0, 3620093.0) + * ] + * }); + * + * var p0 = spline.evaluate(times[i]); // equal to positions[i] + * var p1 = spline.evaluate(times[i] + delta); // interpolated value when delta < times[i + 1] - times[i] + * + * @see HermiteSpline + * @see LinearSpline + * @see QuaternionSpline + * @see WeightSpline + */ + function CatmullRomSpline(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - function computeJulianDateComponents(year, month, day, hour, minute, second, millisecond) { - // Algorithm from page 604 of the Explanatory Supplement to the - // Astronomical Almanac (Seidelmann 1992). + var points = options.points; + var times = options.times; + var firstTangent = options.firstTangent; + var lastTangent = options.lastTangent; - var a = ((month - 14) / 12) | 0; - var b = year + 4800 + a; - var dayNumber = (((1461 * b) / 4) | 0) + (((367 * (month - 2 - 12 * a)) / 12) | 0) - (((3 * (((b + 100) / 100) | 0)) / 4) | 0) + day - 32075; + Check.defined('points', points); + Check.defined('times', times); + Check.typeOf.number.greaterThanOrEquals('points.length', points.length, 2); + Check.typeOf.number.equals('times.length', 'points.length', times.length, points.length); + + if (points.length > 2) { + if (!defined(firstTangent)) { + firstTangent = firstTangentScratch; + Cartesian3.multiplyByScalar(points[1], 2.0, firstTangent); + Cartesian3.subtract(firstTangent, points[2], firstTangent); + Cartesian3.subtract(firstTangent, points[0], firstTangent); + Cartesian3.multiplyByScalar(firstTangent, 0.5, firstTangent); + } - // JulianDates are noon-based - hour = hour - 12; - if (hour < 0) { - hour += 24; + if (!defined(lastTangent)) { + var n = points.length - 1; + lastTangent = lastTangentScratch; + Cartesian3.multiplyByScalar(points[n - 1], 2.0, lastTangent); + Cartesian3.subtract(points[n], lastTangent, lastTangent); + Cartesian3.add(lastTangent, points[n - 2], lastTangent); + Cartesian3.multiplyByScalar(lastTangent, 0.5, lastTangent); + } } - var secondsOfDay = second + ((hour * TimeConstants.SECONDS_PER_HOUR) + (minute * TimeConstants.SECONDS_PER_MINUTE) + (millisecond * TimeConstants.SECONDS_PER_MILLISECOND)); - - if (secondsOfDay >= 43200.0) { - dayNumber -= 1; - } + this._times = times; + this._points = points; + this._firstTangent = Cartesian3.clone(firstTangent); + this._lastTangent = Cartesian3.clone(lastTangent); - return [dayNumber, secondsOfDay]; + this._evaluateFunction = createEvaluateFunction(this); + this._lastTimeIndex = 0; } - //Regular expressions used for ISO8601 date parsing. - //YYYY - var matchCalendarYear = /^(\d{4})$/; - //YYYY-MM (YYYYMM is invalid) - var matchCalendarMonth = /^(\d{4})-(\d{2})$/; - //YYYY-DDD or YYYYDDD - var matchOrdinalDate = /^(\d{4})-?(\d{3})$/; - //YYYY-Www or YYYYWww or YYYY-Www-D or YYYYWwwD - var matchWeekDate = /^(\d{4})-?W(\d{2})-?(\d{1})?$/; - //YYYY-MM-DD or YYYYMMDD - var matchCalendarDate = /^(\d{4})-?(\d{2})-?(\d{2})$/; - // Match utc offset - var utcOffset = /([Z+\-])?(\d{2})?:?(\d{2})?$/; - // Match hours HH or HH.xxxxx - var matchHours = /^(\d{2})(\.\d+)?/.source + utcOffset.source; - // Match hours/minutes HH:MM HHMM.xxxxx - var matchHoursMinutes = /^(\d{2}):?(\d{2})(\.\d+)?/.source + utcOffset.source; - // Match hours/minutes HH:MM:SS HHMMSS.xxxxx - var matchHoursMinutesSeconds = /^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source + utcOffset.source; - - var iso8601ErrorMessage = 'Invalid ISO 8601 date.'; - - /** - * Represents an astronomical Julian date, which is the number of days since noon on January 1, -4712 (4713 BC). - * For increased precision, this class stores the whole number part of the date and the seconds - * part of the date in separate components. In order to be safe for arithmetic and represent - * leap seconds, the date is always stored in the International Atomic Time standard - * {@link TimeStandard.TAI}. - * @alias JulianDate - * @constructor - * - * @param {Number} [julianDayNumber=0.0] The Julian Day Number representing the number of whole days. Fractional days will also be handled correctly. - * @param {Number} [secondsOfDay=0.0] The number of seconds into the current Julian Day Number. Fractional seconds, negative seconds and seconds greater than a day will be handled correctly. - * @param {TimeStandard} [timeStandard=TimeStandard.UTC] The time standard in which the first two parameters are defined. - */ - function JulianDate(julianDayNumber, secondsOfDay, timeStandard) { + defineProperties(CatmullRomSpline.prototype, { /** - * Gets or sets the number of whole days. - * @type {Number} + * An array of times for the control points. + * + * @memberof CatmullRomSpline.prototype + * + * @type {Number[]} + * @readonly */ - this.dayNumber = undefined; + times : { + get : function() { + return this._times; + } + }, /** - * Gets or sets the number of seconds into the current day. - * @type {Number} + * An array of {@link Cartesian3} control points. + * + * @memberof CatmullRomSpline.prototype + * + * @type {Cartesian3[]} + * @readonly */ - this.secondsOfDay = undefined; - - julianDayNumber = defaultValue(julianDayNumber, 0.0); - secondsOfDay = defaultValue(secondsOfDay, 0.0); - timeStandard = defaultValue(timeStandard, TimeStandard.UTC); - - //If julianDayNumber is fractional, make it an integer and add the number of seconds the fraction represented. - var wholeDays = julianDayNumber | 0; - secondsOfDay = secondsOfDay + (julianDayNumber - wholeDays) * TimeConstants.SECONDS_PER_DAY; + points : { + get : function() { + return this._points; + } + }, - setComponents(wholeDays, secondsOfDay, this); + /** + * The tangent at the first control point. + * + * @memberof CatmullRomSpline.prototype + * + * @type {Cartesian3} + * @readonly + */ + firstTangent : { + get : function() { + return this._firstTangent; + } + }, - if (timeStandard === TimeStandard.UTC) { - convertUtcToTai(this); + /** + * The tangent at the last control point. + * + * @memberof CatmullRomSpline.prototype + * + * @type {Cartesian3} + * @readonly + */ + lastTangent : { + get : function() { + return this._lastTangent; + } } - } + }); /** - * Creates a new instance from a GregorianDate. + * @private + */ + CatmullRomSpline.catmullRomCoefficientMatrix = new Matrix4( + -0.5, 1.0, -0.5, 0.0, + 1.5, -2.5, 0.0, 1.0, + -1.5, 2.0, 0.5, 0.0, + 0.5, -0.5, 0.0, 0.0); + + /** + * Finds an index <code>i</code> in <code>times</code> such that the parameter + * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. + * @function * - * @param {GregorianDate} date A GregorianDate. - * @param {JulianDate} [result] An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter or a new instance if none was provided. + * @param {Number} time The time. + * @returns {Number} The index for the element at the start of the interval. * - * @exception {DeveloperError} date must be a valid GregorianDate. + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - JulianDate.fromGregorianDate = function(date, result) { - if (!(date instanceof GregorianDate)) { - throw new DeveloperError('date must be a valid GregorianDate.'); - } - - var components = computeJulianDateComponents(date.year, date.month, date.day, date.hour, date.minute, date.second, date.millisecond); - if (!defined(result)) { - return new JulianDate(components[0], components[1], TimeStandard.UTC); - } - setComponents(components[0], components[1], result); - convertUtcToTai(result); - return result; - }; + CatmullRomSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; /** - * Creates a new instance from a JavaScript Date. + * Wraps the given time to the period covered by the spline. + * @function * - * @param {Date} date A JavaScript Date. - * @param {JulianDate} [result] An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter or a new instance if none was provided. + * @param {Number} time The time. + * @return {Number} The time, wrapped around to the updated animation. + */ + CatmullRomSpline.prototype.wrapTime = Spline.prototype.wrapTime; + + /** + * Clamps the given time to the period covered by the spline. + * @function * - * @exception {DeveloperError} date must be a valid JavaScript Date. + * @param {Number} time The time. + * @return {Number} The time, clamped to the animation period. */ - JulianDate.fromDate = function(date, result) { - if (!(date instanceof Date) || isNaN(date.getTime())) { - throw new DeveloperError('date must be a valid JavaScript Date.'); - } - - var components = computeJulianDateComponents(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds()); - if (!defined(result)) { - return new JulianDate(components[0], components[1], TimeStandard.UTC); - } - setComponents(components[0], components[1], result); - convertUtcToTai(result); - return result; - }; + CatmullRomSpline.prototype.clampTime = Spline.prototype.clampTime; /** - * Creates a new instance from a from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} date. - * This method is superior to <code>Date.parse</code> because it will handle all valid formats defined by the ISO 8601 - * specification, including leap seconds and sub-millisecond times, which discarded by most JavaScript implementations. + * Evaluates the curve at a given time. * - * @param {String} iso8601String An ISO 8601 date. - * @param {JulianDate} [result] An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter or a new instance if none was provided. + * @param {Number} time The time at which to evaluate the curve. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. * - * @exception {DeveloperError} Invalid ISO 8601 date. + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - JulianDate.fromIso8601 = function(iso8601String, result) { - if (typeof iso8601String !== 'string') { - throw new DeveloperError(iso8601ErrorMessage); - } - - //Comma and decimal point both indicate a fractional number according to ISO 8601, - //start out by blanket replacing , with . which is the only valid such symbol in JS. - iso8601String = iso8601String.replace(',', '.'); - - //Split the string into its date and time components, denoted by a mandatory T - var tokens = iso8601String.split('T'); - var year; - var month = 1; - var day = 1; - var hour = 0; - var minute = 0; - var second = 0; - var millisecond = 0; + CatmullRomSpline.prototype.evaluate = function(time, result) { + return this._evaluateFunction(time, result); + }; - //Lacking a time is okay, but a missing date is illegal. - var date = tokens[0]; - var time = tokens[1]; - var tmp; - var inLeapYear; - if (!defined(date)) { - throw new DeveloperError(iso8601ErrorMessage); - } + return CatmullRomSpline; +}); - var dashCount; - - //First match the date against possible regular expressions. - tokens = date.match(matchCalendarDate); - if (tokens !== null) { - dashCount = date.split('-').length - 1; - if (dashCount > 0 && dashCount !== 2) { - throw new DeveloperError(iso8601ErrorMessage); - } - year = +tokens[1]; - month = +tokens[2]; - day = +tokens[3]; - } else { - tokens = date.match(matchCalendarMonth); - if (tokens !== null) { - year = +tokens[1]; - month = +tokens[2]; - } else { - tokens = date.match(matchCalendarYear); - if (tokens !== null) { - year = +tokens[1]; - } else { - //Not a year/month/day so it must be an ordinal date. - var dayOfYear; - tokens = date.match(matchOrdinalDate); - if (tokens !== null) { +define('Core/GeographicTilingScheme',[ + './Cartesian2', + './Check', + './defaultValue', + './defined', + './defineProperties', + './Ellipsoid', + './GeographicProjection', + './Math', + './Rectangle' + ], function( + Cartesian2, + Check, + defaultValue, + defined, + defineProperties, + Ellipsoid, + GeographicProjection, + CesiumMath, + Rectangle) { + 'use strict'; - year = +tokens[1]; - dayOfYear = +tokens[2]; - inLeapYear = isLeapYear(year); + /** + * A tiling scheme for geometry referenced to a simple {@link GeographicProjection} where + * longitude and latitude are directly mapped to X and Y. This projection is commonly + * known as geographic, equirectangular, equidistant cylindrical, or plate carrée. + * + * @alias GeographicTilingScheme + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to + * the WGS84 ellipsoid. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the tiling scheme. + * @param {Number} [options.numberOfLevelZeroTilesX=2] The number of tiles in the X direction at level zero of + * the tile tree. + * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of + * the tile tree. + */ + function GeographicTilingScheme(options) { + options = defaultValue(options, {}); - //This validation is only applicable for this format. - if (dayOfYear < 1 || (inLeapYear && dayOfYear > 366) || (!inLeapYear && dayOfYear > 365)) { - throw new DeveloperError(iso8601ErrorMessage); - } - } else { - tokens = date.match(matchWeekDate); - if (tokens !== null) { - //ISO week date to ordinal date from - //http://en.wikipedia.org/w/index.php?title=ISO_week_date&oldid=474176775 - year = +tokens[1]; - var weekNumber = +tokens[2]; - var dayOfWeek = +tokens[3] || 0; + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE); + this._projection = new GeographicProjection(this._ellipsoid); + this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 2); + this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1); + } - dashCount = date.split('-').length - 1; - if (dashCount > 0 && - ((!defined(tokens[3]) && dashCount !== 1) || - (defined(tokens[3]) && dashCount !== 2))) { - throw new DeveloperError(iso8601ErrorMessage); - } - - var january4 = new Date(Date.UTC(year, 0, 4)); - dayOfYear = (weekNumber * 7) + dayOfWeek - january4.getUTCDay() - 3; - } else { - //None of our regular expressions succeeded in parsing the date properly. - throw new DeveloperError(iso8601ErrorMessage); - } - } - //Split an ordinal date into month/day. - tmp = new Date(Date.UTC(year, 0, 1)); - tmp.setUTCDate(dayOfYear); - month = tmp.getUTCMonth() + 1; - day = tmp.getUTCDate(); - } + defineProperties(GeographicTilingScheme.prototype, { + /** + * Gets the ellipsoid that is tiled by this tiling scheme. + * @memberof GeographicTilingScheme.prototype + * @type {Ellipsoid} + */ + ellipsoid : { + get : function() { + return this._ellipsoid; } - } + }, - //Now that we have all of the date components, validate them to make sure nothing is out of range. - inLeapYear = isLeapYear(year); - if (month < 1 || month > 12 || day < 1 || ((month !== 2 || !inLeapYear) && day > daysInMonth[month - 1]) || (inLeapYear && month === 2 && day > daysInLeapFeburary)) { - throw new DeveloperError(iso8601ErrorMessage); - } - - //Now move onto the time string, which is much simpler. - //If no time is specified, it is considered the beginning of the day, UTC to match Javascript's implementation. - var offsetIndex; - if (defined(time)) { - tokens = time.match(matchHoursMinutesSeconds); - if (tokens !== null) { - dashCount = time.split(':').length - 1; - if (dashCount > 0 && dashCount !== 2 && dashCount !== 3) { - throw new DeveloperError(iso8601ErrorMessage); - } - - hour = +tokens[1]; - minute = +tokens[2]; - second = +tokens[3]; - millisecond = +(tokens[4] || 0) * 1000.0; - offsetIndex = 5; - } else { - tokens = time.match(matchHoursMinutes); - if (tokens !== null) { - dashCount = time.split(':').length - 1; - if (dashCount > 2) { - throw new DeveloperError(iso8601ErrorMessage); - } - - hour = +tokens[1]; - minute = +tokens[2]; - second = +(tokens[3] || 0) * 60.0; - offsetIndex = 4; - } else { - tokens = time.match(matchHours); - if (tokens !== null) { - hour = +tokens[1]; - minute = +(tokens[2] || 0) * 60.0; - offsetIndex = 3; - } else { - throw new DeveloperError(iso8601ErrorMessage); - } - } + /** + * Gets the rectangle, in radians, covered by this tiling scheme. + * @memberof GeographicTilingScheme.prototype + * @type {Rectangle} + */ + rectangle : { + get : function() { + return this._rectangle; } + }, - //Validate that all values are in proper range. Minutes and hours have special cases at 60 and 24. - if (minute >= 60 || second >= 61 || hour > 24 || (hour === 24 && (minute > 0 || second > 0 || millisecond > 0))) { - throw new DeveloperError(iso8601ErrorMessage); - } - - //Check the UTC offset value, if no value exists, use local time - //a Z indicates UTC, + or - are offsets. - var offset = tokens[offsetIndex]; - var offsetHours = +(tokens[offsetIndex + 1]); - var offsetMinutes = +(tokens[offsetIndex + 2] || 0); - switch (offset) { - case '+': - hour = hour - offsetHours; - minute = minute - offsetMinutes; - break; - case '-': - hour = hour + offsetHours; - minute = minute + offsetMinutes; - break; - case 'Z': - break; - default: - minute = minute + new Date(Date.UTC(year, month - 1, day, hour, minute)).getTimezoneOffset(); - break; + /** + * Gets the map projection used by this tiling scheme. + * @memberof GeographicTilingScheme.prototype + * @type {MapProjection} + */ + projection : { + get : function() { + return this._projection; } } + }); - //ISO8601 denotes a leap second by any time having a seconds component of 60 seconds. - //If that's the case, we need to temporarily subtract a second in order to build a UTC date. - //Then we add it back in after converting to TAI. - var isLeapSecond = second === 60; - if (isLeapSecond) { - second--; - } + /** + * Gets the total number of tiles in the X direction at a specified level-of-detail. + * + * @param {Number} level The level-of-detail. + * @returns {Number} The number of tiles in the X direction at the given level. + */ + GeographicTilingScheme.prototype.getNumberOfXTilesAtLevel = function(level) { + return this._numberOfLevelZeroTilesX << level; + }; - //Even if we successfully parsed the string into its components, after applying UTC offset or - //special cases like 24:00:00 denoting midnight, we need to normalize the data appropriately. + /** + * Gets the total number of tiles in the Y direction at a specified level-of-detail. + * + * @param {Number} level The level-of-detail. + * @returns {Number} The number of tiles in the Y direction at the given level. + */ + GeographicTilingScheme.prototype.getNumberOfYTilesAtLevel = function(level) { + return this._numberOfLevelZeroTilesY << level; + }; - //milliseconds can never be greater than 1000, and seconds can't be above 60, so we start with minutes - while (minute >= 60) { - minute -= 60; - hour++; - } + /** + * Transforms a rectangle specified in geodetic radians to the native coordinate system + * of this tiling scheme. + * + * @param {Rectangle} rectangle The rectangle to transform. + * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result' + * is undefined. + */ + GeographicTilingScheme.prototype.rectangleToNativeRectangle = function(rectangle, result) { + Check.defined('rectangle', rectangle); + + var west = CesiumMath.toDegrees(rectangle.west); + var south = CesiumMath.toDegrees(rectangle.south); + var east = CesiumMath.toDegrees(rectangle.east); + var north = CesiumMath.toDegrees(rectangle.north); - while (hour >= 24) { - hour -= 24; - day++; + if (!defined(result)) { + return new Rectangle(west, south, east, north); } - tmp = (inLeapYear && month === 2) ? daysInLeapFeburary : daysInMonth[month - 1]; - while (day > tmp) { - day -= tmp; - month++; - - if (month > 12) { - month -= 12; - year++; - } - - tmp = (inLeapYear && month === 2) ? daysInLeapFeburary : daysInMonth[month - 1]; - } + result.west = west; + result.south = south; + result.east = east; + result.north = north; + return result; + }; - //If UTC offset is at the beginning/end of the day, minutes can be negative. - while (minute < 0) { - minute += 60; - hour--; - } + /** + * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates + * of the tiling scheme. + * + * @param {Number} x The integer x coordinate of the tile. + * @param {Number} y The integer y coordinate of the tile. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the rectangle + * if 'result' is undefined. + */ + GeographicTilingScheme.prototype.tileXYToNativeRectangle = function(x, y, level, result) { + var rectangleRadians = this.tileXYToRectangle(x, y, level, result); + rectangleRadians.west = CesiumMath.toDegrees(rectangleRadians.west); + rectangleRadians.south = CesiumMath.toDegrees(rectangleRadians.south); + rectangleRadians.east = CesiumMath.toDegrees(rectangleRadians.east); + rectangleRadians.north = CesiumMath.toDegrees(rectangleRadians.north); + return rectangleRadians; + }; - while (hour < 0) { - hour += 24; - day--; - } + /** + * Converts tile x, y coordinates and level to a cartographic rectangle in radians. + * + * @param {Number} x The integer x coordinate of the tile. + * @param {Number} y The integer y coordinate of the tile. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the rectangle + * if 'result' is undefined. + */ + GeographicTilingScheme.prototype.tileXYToRectangle = function(x, y, level, result) { + var rectangle = this._rectangle; - while (day < 1) { - month--; - if (month < 1) { - month += 12; - year--; - } + var xTiles = this.getNumberOfXTilesAtLevel(level); + var yTiles = this.getNumberOfYTilesAtLevel(level); - tmp = (inLeapYear && month === 2) ? daysInLeapFeburary : daysInMonth[month - 1]; - day += tmp; - } + var xTileWidth = rectangle.width / xTiles; + var west = x * xTileWidth + rectangle.west; + var east = (x + 1) * xTileWidth + rectangle.west; - //Now create the JulianDate components from the Gregorian date and actually create our instance. - var components = computeJulianDateComponents(year, month, day, hour, minute, second, millisecond); + var yTileHeight = rectangle.height / yTiles; + var north = rectangle.north - y * yTileHeight; + var south = rectangle.north - (y + 1) * yTileHeight; if (!defined(result)) { - result = new JulianDate(components[0], components[1], TimeStandard.UTC); - } else { - setComponents(components[0], components[1], result); - convertUtcToTai(result); - } - - //If we were on a leap second, add it back. - if (isLeapSecond) { - JulianDate.addSeconds(result, 1, result); + result = new Rectangle(west, south, east, north); } + result.west = west; + result.south = south; + result.east = east; + result.north = north; return result; }; /** - * Creates a new instance that represents the current system time. - * This is equivalent to calling <code>JulianDate.fromDate(new Date());</code>. - * - * @param {JulianDate} [result] An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter or a new instance if none was provided. - */ - JulianDate.now = function(result) { - return JulianDate.fromDate(new Date(), result); - }; - - var toGregorianDateScratch = new JulianDate(0, 0, TimeStandard.TAI); - - /** - * Creates a {@link GregorianDate} from the provided instance. + * Calculates the tile x, y coordinates of the tile containing + * a given cartographic position. * - * @param {JulianDate} julianDate The date to be converted. - * @param {GregorianDate} [result] An existing instance to use for the result. - * @returns {GregorianDate} The modified result parameter or a new instance if none was provided. + * @param {Cartographic} position The position. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates + * if 'result' is undefined. */ - JulianDate.toGregorianDate = function(julianDate, result) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); - } - - var isLeapSecond = false; - var thisUtc = convertTaiToUtc(julianDate, toGregorianDateScratch); - if (!defined(thisUtc)) { - //Conversion to UTC will fail if we are during a leap second. - //If that's the case, subtract a second and convert again. - //JavaScript doesn't support leap seconds, so this results in second 59 being repeated twice. - JulianDate.addSeconds(julianDate, -1, toGregorianDateScratch); - thisUtc = convertTaiToUtc(toGregorianDateScratch, toGregorianDateScratch); - isLeapSecond = true; + GeographicTilingScheme.prototype.positionToTileXY = function(position, level, result) { + var rectangle = this._rectangle; + if (!Rectangle.contains(rectangle, position)) { + // outside the bounds of the tiling scheme + return undefined; } - var julianDayNumber = thisUtc.dayNumber; - var secondsOfDay = thisUtc.secondsOfDay; - - if (secondsOfDay >= 43200.0) { - julianDayNumber += 1; - } + var xTiles = this.getNumberOfXTilesAtLevel(level); + var yTiles = this.getNumberOfYTilesAtLevel(level); - // Algorithm from page 604 of the Explanatory Supplement to the - // Astronomical Almanac (Seidelmann 1992). - var L = (julianDayNumber + 68569) | 0; - var N = (4 * L / 146097) | 0; - L = (L - (((146097 * N + 3) / 4) | 0)) | 0; - var I = ((4000 * (L + 1)) / 1461001) | 0; - L = (L - (((1461 * I) / 4) | 0) + 31) | 0; - var J = ((80 * L) / 2447) | 0; - var day = (L - (((2447 * J) / 80) | 0)) | 0; - L = (J / 11) | 0; - var month = (J + 2 - 12 * L) | 0; - var year = (100 * (N - 49) + I + L) | 0; + var xTileWidth = rectangle.width / xTiles; + var yTileHeight = rectangle.height / yTiles; - var hour = (secondsOfDay / TimeConstants.SECONDS_PER_HOUR) | 0; - var remainingSeconds = secondsOfDay - (hour * TimeConstants.SECONDS_PER_HOUR); - var minute = (remainingSeconds / TimeConstants.SECONDS_PER_MINUTE) | 0; - remainingSeconds = remainingSeconds - (minute * TimeConstants.SECONDS_PER_MINUTE); - var second = remainingSeconds | 0; - var millisecond = ((remainingSeconds - second) / TimeConstants.SECONDS_PER_MILLISECOND); + var longitude = position.longitude; + if (rectangle.east < rectangle.west) { + longitude += CesiumMath.TWO_PI; + } - // JulianDates are noon-based - hour += 12; - if (hour > 23) { - hour -= 24; + var xTileCoordinate = (longitude - rectangle.west) / xTileWidth | 0; + if (xTileCoordinate >= xTiles) { + xTileCoordinate = xTiles - 1; } - //If we were on a leap second, add it back. - if (isLeapSecond) { - second += 1; + var yTileCoordinate = (rectangle.north - position.latitude) / yTileHeight | 0; + if (yTileCoordinate >= yTiles) { + yTileCoordinate = yTiles - 1; } if (!defined(result)) { - return new GregorianDate(year, month, day, hour, minute, second, millisecond, isLeapSecond); + return new Cartesian2(xTileCoordinate, yTileCoordinate); } - result.year = year; - result.month = month; - result.day = day; - result.hour = hour; - result.minute = minute; - result.second = second; - result.millisecond = millisecond; - result.isLeapSecond = isLeapSecond; + result.x = xTileCoordinate; + result.y = yTileCoordinate; return result; }; - /** - * Creates a JavaScript Date from the provided instance. - * Since JavaScript dates are only accurate to the nearest millisecond and - * cannot represent a leap second, consider using {@link JulianDate.toGregorianDate} instead. - * If the provided JulianDate is during a leap second, the previous second is used. - * - * @param {JulianDate} julianDate The date to be converted. - * @returns {Date} A new instance representing the provided date. - */ - JulianDate.toDate = function(julianDate) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); - } - - var gDate = JulianDate.toGregorianDate(julianDate, gregorianDateScratch); - var second = gDate.second; - if (gDate.isLeapSecond) { - second -= 1; - } - return new Date(Date.UTC(gDate.year, gDate.month - 1, gDate.day, gDate.hour, gDate.minute, second, gDate.millisecond)); - }; + return GeographicTilingScheme; +}); + +define('Core/EllipsoidalOccluder',[ + './BoundingSphere', + './Cartesian3', + './Check', + './defaultValue', + './defined', + './defineProperties', + './Rectangle' + ], function( + BoundingSphere, + Cartesian3, + Check, + defaultValue, + defined, + defineProperties, + Rectangle) { + 'use strict'; /** - * Creates an ISO8601 representation of the provided date. + * Determine whether or not other objects are visible or hidden behind the visible horizon defined by + * an {@link Ellipsoid} and a camera position. The ellipsoid is assumed to be located at the + * origin of the coordinate system. This class uses the algorithm described in the + * {@link https://cesium.com/blog/2013/04/25/Horizon-culling/|Horizon Culling} blog post. * - * @param {JulianDate} julianDate The date to be converted. - * @param {Number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. - * @returns {String} The ISO8601 representation of the provided date. + * @alias EllipsoidalOccluder + * + * @param {Ellipsoid} ellipsoid The ellipsoid to use as an occluder. + * @param {Cartesian3} [cameraPosition] The coordinate of the viewer/camera. If this parameter is not + * specified, {@link EllipsoidalOccluder#cameraPosition} must be called before + * testing visibility. + * + * @constructor + * + * @example + * // Construct an ellipsoidal occluder with radii 1.0, 1.1, and 0.9. + * var cameraPosition = new Cesium.Cartesian3(5.0, 6.0, 7.0); + * var occluderEllipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9); + * var occluder = new Cesium.EllipsoidalOccluder(occluderEllipsoid, cameraPosition); + * + * @private */ - JulianDate.toIso8601 = function(julianDate, precision) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); - } + function EllipsoidalOccluder(ellipsoid, cameraPosition) { + Check.typeOf.object('ellipsoid', ellipsoid); - var gDate = JulianDate.toGregorianDate(julianDate, gregorianDateScratch); - var millisecondStr; + this._ellipsoid = ellipsoid; + this._cameraPosition = new Cartesian3(); + this._cameraPositionInScaledSpace = new Cartesian3(); + this._distanceToLimbInScaledSpaceSquared = 0.0; - if (!defined(precision) && gDate.millisecond !== 0) { - //Forces milliseconds into a number with at least 3 digits to whatever the default toString() precision is. - millisecondStr = (gDate.millisecond * 0.01).toString().replace('.', ''); - return sprintf('%04d-%02d-%02dT%02d:%02d:%02d.%sZ', gDate.year, gDate.month, gDate.day, gDate.hour, gDate.minute, gDate.second, millisecondStr); + // cameraPosition fills in the above values + if (defined(cameraPosition)) { + this.cameraPosition = cameraPosition; } + } - //Precision is either 0 or milliseconds is 0 with undefined precision, in either case, leave off milliseconds entirely - if (!defined(precision) || precision === 0) { - return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ', gDate.year, gDate.month, gDate.day, gDate.hour, gDate.minute, gDate.second); + defineProperties(EllipsoidalOccluder.prototype, { + /** + * Gets the occluding ellipsoid. + * @memberof EllipsoidalOccluder.prototype + * @type {Ellipsoid} + */ + ellipsoid : { + get: function() { + return this._ellipsoid; + } + }, + /** + * Gets or sets the position of the camera. + * @memberof EllipsoidalOccluder.prototype + * @type {Cartesian3} + */ + cameraPosition : { + get : function() { + return this._cameraPosition; + }, + set : function(cameraPosition) { + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ + var ellipsoid = this._ellipsoid; + var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace); + var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0; + + Cartesian3.clone(cameraPosition, this._cameraPosition); + this._cameraPositionInScaledSpace = cv; + this._distanceToLimbInScaledSpaceSquared = vhMagnitudeSquared; + } } + }); - //Forces milliseconds into a number with at least 3 digits to whatever the specified precision is. - millisecondStr = (gDate.millisecond * 0.01).toFixed(precision).replace('.', '').slice(0, precision); - return sprintf('%04d-%02d-%02dT%02d:%02d:%02d.%sZ', gDate.year, gDate.month, gDate.day, gDate.hour, gDate.minute, gDate.second, millisecondStr); - }; + var scratchCartesian = new Cartesian3(); /** - * Duplicates a JulianDate instance. + * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder. * - * @param {JulianDate} julianDate The date to duplicate. - * @param {JulianDate} [result] An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter or a new instance if none was provided. Returns undefined if julianDate is undefined. - */ - JulianDate.clone = function(julianDate, result) { - if (!defined(julianDate)) { - return undefined; - } - if (!defined(result)) { - return new JulianDate(julianDate.dayNumber, julianDate.secondsOfDay, TimeStandard.TAI); - } - result.dayNumber = julianDate.dayNumber; - result.secondsOfDay = julianDate.secondsOfDay; - return result; - }; - - /** - * Compares two instances. + * @param {Cartesian3} occludee The point to test for visibility. + * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Number} A negative value if left is less than right, a positive value if left is greater than right, or zero if left and right are equal. + * @example + * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5); + * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9); + * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition); + * var point = new Cesium.Cartesian3(0, -3, -3); + * occluder.isPointVisible(point); //returns true */ - JulianDate.compare = function(left, right) { - if (!defined(left)) { - throw new DeveloperError('left is required.'); - } - if (!defined(right)) { - throw new DeveloperError('right is required.'); - } - - var julianDayNumberDifference = left.dayNumber - right.dayNumber; - if (julianDayNumberDifference !== 0) { - return julianDayNumberDifference; - } - return left.secondsOfDay - right.secondsOfDay; + EllipsoidalOccluder.prototype.isPointVisible = function(occludee) { + var ellipsoid = this._ellipsoid; + var occludeeScaledSpacePosition = ellipsoid.transformPositionToScaledSpace(occludee, scratchCartesian); + return this.isScaledSpacePointVisible(occludeeScaledSpacePosition); }; /** - * Compares two instances and returns <code>true</code> if they are equal, <code>false</code> otherwise. + * Determines whether or not a point expressed in the ellipsoid scaled space, is hidden from view by the + * occluder. To transform a Cartesian X, Y, Z position in the coordinate system aligned with the ellipsoid + * into the scaled space, call {@link Ellipsoid#transformPositionToScaledSpace}. * - * @param {JulianDate} [left] The first instance. - * @param {JulianDate} [right] The second instance. - * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. + * @param {Cartesian3} occludeeScaledSpacePosition The point to test for visibility, represented in the scaled space. + * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * + * @example + * var cameraPosition = new Cesium.Cartesian3(0, 0, 2.5); + * var ellipsoid = new Cesium.Ellipsoid(1.0, 1.1, 0.9); + * var occluder = new Cesium.EllipsoidalOccluder(ellipsoid, cameraPosition); + * var point = new Cesium.Cartesian3(0, -3, -3); + * var scaledSpacePoint = ellipsoid.transformPositionToScaledSpace(point); + * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true */ - JulianDate.equals = function(left, right) { - return (left === right) || - (defined(left) && - defined(right) && - left.dayNumber === right.dayNumber && - left.secondsOfDay === right.secondsOfDay); + EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) { + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ + var cv = this._cameraPositionInScaledSpace; + var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared; + var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian); + var vtDotVc = -Cartesian3.dot(vt, cv); + // If vhMagnitudeSquared < 0 then we are below the surface of the ellipsoid and + // in this case, set the culling plane to be on V. + var isOccluded = vhMagnitudeSquared < 0 ? vtDotVc > 0 : (vtDotVc > vhMagnitudeSquared && + vtDotVc * vtDotVc / Cartesian3.magnitudeSquared(vt) > vhMagnitudeSquared); + return !isOccluded; }; /** - * Compares two instances and returns <code>true</code> if they are within <code>epsilon</code> seconds of - * each other. That is, in order for the dates to be considered equal (and for - * this function to return <code>true</code>), the absolute value of the difference between them, in - * seconds, must be less than <code>epsilon</code>. + * Computes a point that can be used for horizon culling from a list of positions. If the point is below + * the horizon, all of the positions are guaranteed to be below the horizon as well. The returned point + * is expressed in the ellipsoid-scaled space and is suitable for use with + * {@link EllipsoidalOccluder#isScaledSpacePointVisible}. * - * @param {JulianDate} [left] The first instance. - * @param {JulianDate} [right] The second instance. - * @param {Number} epsilon The maximum number of seconds that should separate the two instances. - * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. + * @param {Cartesian3} directionToPoint The direction that the computed point will lie along. + * A reasonable direction to use is the direction from the center of the ellipsoid to + * the center of the bounding sphere computed from the positions. The direction need not + * be normalized. + * @param {Cartesian3[]} positions The positions from which to compute the horizon culling point. The positions + * must be expressed in a reference frame centered at the ellipsoid and aligned with the + * ellipsoid's axes. + * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. + * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. */ - JulianDate.equalsEpsilon = function(left, right, epsilon) { - if (!defined(epsilon)) { - throw new DeveloperError('epsilon is required.'); - } + EllipsoidalOccluder.prototype.computeHorizonCullingPoint = function(directionToPoint, positions, result) { + Check.typeOf.object('directionToPoint', directionToPoint); + Check.defined('positions', positions); - return (left === right) || - (defined(left) && - defined(right) && - Math.abs(JulianDate.secondsDifference(left, right)) <= epsilon); - }; + if (!defined(result)) { + result = new Cartesian3(); + } - /** - * Computes the total number of whole and fractional days represented by the provided instance. - * - * @param {JulianDate} julianDate The date. - * @returns {Number} The Julian date as single floating point number. - */ - JulianDate.totalDays = function(julianDate) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); + var ellipsoid = this._ellipsoid; + var scaledSpaceDirectionToPoint = computeScaledSpaceDirectionToPoint(ellipsoid, directionToPoint); + var resultMagnitude = 0.0; + + for (var i = 0, len = positions.length; i < len; ++i) { + var position = positions[i]; + var candidateMagnitude = computeMagnitude(ellipsoid, position, scaledSpaceDirectionToPoint); + resultMagnitude = Math.max(resultMagnitude, candidateMagnitude); } - return julianDate.dayNumber + (julianDate.secondsOfDay / TimeConstants.SECONDS_PER_DAY); + + return magnitudeToPoint(scaledSpaceDirectionToPoint, resultMagnitude, result); }; + var positionScratch = new Cartesian3(); + /** - * Computes the difference in seconds between the provided instance. + * Computes a point that can be used for horizon culling from a list of positions. If the point is below + * the horizon, all of the positions are guaranteed to be below the horizon as well. The returned point + * is expressed in the ellipsoid-scaled space and is suitable for use with + * {@link EllipsoidalOccluder#isScaledSpacePointVisible}. * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Number} The difference, in seconds, when subtracting <code>right</code> from <code>left</code>. + * @param {Cartesian3} directionToPoint The direction that the computed point will lie along. + * A reasonable direction to use is the direction from the center of the ellipsoid to + * the center of the bounding sphere computed from the positions. The direction need not + * be normalized. + * @param {Number[]} vertices The vertices from which to compute the horizon culling point. The positions + * must be expressed in a reference frame centered at the ellipsoid and aligned with the + * ellipsoid's axes. + * @param {Number} [stride=3] + * @param {Cartesian3} [center=Cartesian3.ZERO] + * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. + * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. */ - JulianDate.secondsDifference = function(left, right) { - if (!defined(left)) { - throw new DeveloperError('left is required.'); + EllipsoidalOccluder.prototype.computeHorizonCullingPointFromVertices = function(directionToPoint, vertices, stride, center, result) { + Check.typeOf.object('directionToPoint', directionToPoint); + Check.defined('vertices', vertices); + Check.typeOf.number('stride', stride); + + if (!defined(result)) { + result = new Cartesian3(); } - if (!defined(right)) { - throw new DeveloperError('right is required.'); + + center = defaultValue(center, Cartesian3.ZERO); + var ellipsoid = this._ellipsoid; + var scaledSpaceDirectionToPoint = computeScaledSpaceDirectionToPoint(ellipsoid, directionToPoint); + var resultMagnitude = 0.0; + + for (var i = 0, len = vertices.length; i < len; i += stride) { + positionScratch.x = vertices[i] + center.x; + positionScratch.y = vertices[i + 1] + center.y; + positionScratch.z = vertices[i + 2] + center.z; + + var candidateMagnitude = computeMagnitude(ellipsoid, positionScratch, scaledSpaceDirectionToPoint); + resultMagnitude = Math.max(resultMagnitude, candidateMagnitude); } - - var dayDifference = (left.dayNumber - right.dayNumber) * TimeConstants.SECONDS_PER_DAY; - return (dayDifference + (left.secondsOfDay - right.secondsOfDay)); + + return magnitudeToPoint(scaledSpaceDirectionToPoint, resultMagnitude, result); }; + var subsampleScratch = []; + /** - * Computes the difference in days between the provided instance. + * Computes a point that can be used for horizon culling of a rectangle. If the point is below + * the horizon, the ellipsoid-conforming rectangle is guaranteed to be below the horizon as well. + * The returned point is expressed in the ellipsoid-scaled space and is suitable for use with + * {@link EllipsoidalOccluder#isScaledSpacePointVisible}. * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Number} The difference, in days, when subtracting <code>right</code> from <code>left</code>. + * @param {Rectangle} rectangle The rectangle for which to compute the horizon culling point. + * @param {Ellipsoid} ellipsoid The ellipsoid on which the rectangle is defined. This may be different from + * the ellipsoid used by this instance for occlusion testing. + * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. + * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. */ - JulianDate.daysDifference = function(left, right) { - if (!defined(left)) { - throw new DeveloperError('left is required.'); - } - if (!defined(right)) { - throw new DeveloperError('right is required.'); - } + EllipsoidalOccluder.prototype.computeHorizonCullingPointFromRectangle = function(rectangle, ellipsoid, result) { + Check.typeOf.object('rectangle', rectangle); - var dayDifference = (left.dayNumber - right.dayNumber); - var secondDifference = (left.secondsOfDay - right.secondsOfDay) / TimeConstants.SECONDS_PER_DAY; - return dayDifference + secondDifference; - }; + var positions = Rectangle.subsample(rectangle, ellipsoid, 0.0, subsampleScratch); + var bs = BoundingSphere.fromPoints(positions); - /** - * Computes the number of seconds the provided instance is ahead of UTC. - * - * @param {JulianDate} julianDate The date. - * @returns {Number} The number of seconds the provided instance is ahead of UTC - */ - JulianDate.computeTaiMinusUtc = function(julianDate) { - binarySearchScratchLeapSecond.julianDate = julianDate; - var leapSeconds = JulianDate.leapSeconds; - var index = binarySearch(leapSeconds, binarySearchScratchLeapSecond, compareLeapSecondDates); - if (index < 0) { - index = ~index; - --index; - if (index < 0) { - index = 0; - } + // If the bounding sphere center is too close to the center of the occluder, it doesn't make + // sense to try to horizon cull it. + if (Cartesian3.magnitude(bs.center) < 0.1 * ellipsoid.minimumRadius) { + return undefined; } - return leapSeconds[index].offset; + + return this.computeHorizonCullingPoint(bs.center, positions, result); }; - /** - * Adds the provided number of seconds to the provided date instance. - * - * @param {JulianDate} julianDate The date. - * @param {Number} seconds The number of seconds to add or subtract. - * @param {JulianDate} result An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter. - */ - JulianDate.addSeconds = function(julianDate, seconds, result) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); - } - if (!defined(seconds)) { - throw new DeveloperError('seconds is required.'); + var scaledSpaceScratch = new Cartesian3(); + var directionScratch = new Cartesian3(); + + function computeMagnitude(ellipsoid, position, scaledSpaceDirectionToPoint) { + var scaledSpacePosition = ellipsoid.transformPositionToScaledSpace(position, scaledSpaceScratch); + var magnitudeSquared = Cartesian3.magnitudeSquared(scaledSpacePosition); + var magnitude = Math.sqrt(magnitudeSquared); + var direction = Cartesian3.divideByScalar(scaledSpacePosition, magnitude, directionScratch); + + // For the purpose of this computation, points below the ellipsoid are consider to be on it instead. + magnitudeSquared = Math.max(1.0, magnitudeSquared); + magnitude = Math.max(1.0, magnitude); + + var cosAlpha = Cartesian3.dot(direction, scaledSpaceDirectionToPoint); + var sinAlpha = Cartesian3.magnitude(Cartesian3.cross(direction, scaledSpaceDirectionToPoint, direction)); + var cosBeta = 1.0 / magnitude; + var sinBeta = Math.sqrt(magnitudeSquared - 1.0) * cosBeta; + + return 1.0 / (cosAlpha * cosBeta - sinAlpha * sinBeta); + } + + function magnitudeToPoint(scaledSpaceDirectionToPoint, resultMagnitude, result) { + // The horizon culling point is undefined if there were no positions from which to compute it, + // the directionToPoint is pointing opposite all of the positions, or if we computed NaN or infinity. + if (resultMagnitude <= 0.0 || resultMagnitude === 1.0 / 0.0 || resultMagnitude !== resultMagnitude) { + return undefined; } - if (!defined(result)) { - throw new DeveloperError('result is required.'); + + return Cartesian3.multiplyByScalar(scaledSpaceDirectionToPoint, resultMagnitude, result); + } + + var directionToPointScratch = new Cartesian3(); + + function computeScaledSpaceDirectionToPoint(ellipsoid, directionToPoint) { + if (Cartesian3.equals(directionToPoint, Cartesian3.ZERO)) { + return directionToPoint; } - - return setComponents(julianDate.dayNumber, julianDate.secondsOfDay + seconds, result); - }; + + ellipsoid.transformPositionToScaledSpace(directionToPoint, directionToPointScratch); + return Cartesian3.normalize(directionToPointScratch, directionToPointScratch); + } + + return EllipsoidalOccluder; +}); + +define('Core/QuadraticRealPolynomial',[ + './DeveloperError', + './Math' + ], function( + DeveloperError, + CesiumMath) { + 'use strict'; /** - * Adds the provided number of minutes to the provided date instance. + * Defines functions for 2nd order polynomial functions of one variable with only real coefficients. * - * @param {JulianDate} julianDate The date. - * @param {Number} minutes The number of minutes to add or subtract. - * @param {JulianDate} result An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter. + * @exports QuadraticRealPolynomial */ - JulianDate.addMinutes = function(julianDate, minutes, result) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); - } - if (!defined(minutes)) { - throw new DeveloperError('minutes is required.'); - } - if (!defined(result)) { - throw new DeveloperError('result is required.'); - } - - var newSecondsOfDay = julianDate.secondsOfDay + (minutes * TimeConstants.SECONDS_PER_MINUTE); - return setComponents(julianDate.dayNumber, newSecondsOfDay, result); - }; + var QuadraticRealPolynomial = {}; /** - * Adds the provided number of hours to the provided date instance. + * Provides the discriminant of the quadratic equation from the supplied coefficients. * - * @param {JulianDate} julianDate The date. - * @param {Number} hours The number of hours to add or subtract. - * @param {JulianDate} result An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter. + * @param {Number} a The coefficient of the 2nd order monomial. + * @param {Number} b The coefficient of the 1st order monomial. + * @param {Number} c The coefficient of the 0th order monomial. + * @returns {Number} The value of the discriminant. */ - JulianDate.addHours = function(julianDate, hours, result) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); + QuadraticRealPolynomial.computeDiscriminant = function(a, b, c) { + if (typeof a !== 'number') { + throw new DeveloperError('a is a required number.'); } - if (!defined(hours)) { - throw new DeveloperError('hours is required.'); + if (typeof b !== 'number') { + throw new DeveloperError('b is a required number.'); } - if (!defined(result)) { - throw new DeveloperError('result is required.'); + if (typeof c !== 'number') { + throw new DeveloperError('c is a required number.'); } - var newSecondsOfDay = julianDate.secondsOfDay + (hours * TimeConstants.SECONDS_PER_HOUR); - return setComponents(julianDate.dayNumber, newSecondsOfDay, result); + var discriminant = b * b - 4.0 * a * c; + return discriminant; }; + function addWithCancellationCheck(left, right, tolerance) { + var difference = left + right; + if ((CesiumMath.sign(left) !== CesiumMath.sign(right)) && + Math.abs(difference / Math.max(Math.abs(left), Math.abs(right))) < tolerance) { + return 0.0; + } + + return difference; + } + /** - * Adds the provided number of days to the provided date instance. + * Provides the real valued roots of the quadratic polynomial with the provided coefficients. * - * @param {JulianDate} julianDate The date. - * @param {Number} days The number of days to add or subtract. - * @param {JulianDate} result An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter. + * @param {Number} a The coefficient of the 2nd order monomial. + * @param {Number} b The coefficient of the 1st order monomial. + * @param {Number} c The coefficient of the 0th order monomial. + * @returns {Number[]} The real valued roots. */ - JulianDate.addDays = function(julianDate, days, result) { - if (!defined(julianDate)) { - throw new DeveloperError('julianDate is required.'); + QuadraticRealPolynomial.computeRealRoots = function(a, b, c) { + if (typeof a !== 'number') { + throw new DeveloperError('a is a required number.'); } - if (!defined(days)) { - throw new DeveloperError('days is required.'); + if (typeof b !== 'number') { + throw new DeveloperError('b is a required number.'); } - if (!defined(result)) { - throw new DeveloperError('result is required.'); + if (typeof c !== 'number') { + throw new DeveloperError('c is a required number.'); } - var newJulianDayNumber = julianDate.dayNumber + days; - return setComponents(newJulianDayNumber, julianDate.secondsOfDay, result); - }; + var ratio; + if (a === 0.0) { + if (b === 0.0) { + // Constant function: c = 0. + return []; + } - /** - * Compares the provided instances and returns <code>true</code> if <code>left</code> is earlier than <code>right</code>, <code>false</code> otherwise. - * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is earlier than <code>right</code>, <code>false</code> otherwise. - */ - JulianDate.lessThan = function(left, right) { - return JulianDate.compare(left, right) < 0; - }; + // Linear function: b * x + c = 0. + return [-c / b]; + } else if (b === 0.0) { + if (c === 0.0) { + // 2nd order monomial: a * x^2 = 0. + return [0.0, 0.0]; + } - /** - * Compares the provided instances and returns <code>true</code> if <code>left</code> is earlier than or equal to <code>right</code>, <code>false</code> otherwise. - * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is earlier than or equal to <code>right</code>, <code>false</code> otherwise. - */ - JulianDate.lessThanOrEquals = function(left, right) { - return JulianDate.compare(left, right) <= 0; - }; + var cMagnitude = Math.abs(c); + var aMagnitude = Math.abs(a); - /** - * Compares the provided instances and returns <code>true</code> if <code>left</code> is later than <code>right</code>, <code>false</code> otherwise. - * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is later than <code>right</code>, <code>false</code> otherwise. - */ - JulianDate.greaterThan = function(left, right) { - return JulianDate.compare(left, right) > 0; - }; + if ((cMagnitude < aMagnitude) && (cMagnitude / aMagnitude < CesiumMath.EPSILON14)) { // c ~= 0.0. + // 2nd order monomial: a * x^2 = 0. + return [0.0, 0.0]; + } else if ((cMagnitude > aMagnitude) && (aMagnitude / cMagnitude < CesiumMath.EPSILON14)) { // a ~= 0.0. + // Constant function: c = 0. + return []; + } - /** - * Compares the provided instances and returns <code>true</code> if <code>left</code> is later than or equal to <code>right</code>, <code>false</code> otherwise. - * - * @param {JulianDate} left The first instance. - * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is later than or equal to <code>right</code>, <code>false</code> otherwise. - */ - JulianDate.greaterThanOrEquals = function(left, right) { - return JulianDate.compare(left, right) >= 0; - }; + // a * x^2 + c = 0 + ratio = -c / a; - /** - * Duplicates this instance. - * - * @param {JulianDate} [result] An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter or a new instance if none was provided. - */ - JulianDate.prototype.clone = function(result) { - return JulianDate.clone(this, result); - }; + if (ratio < 0.0) { + // Both roots are complex. + return []; + } - /** - * Compares this and the provided instance and returns <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {JulianDate} [right] The second instance. - * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. - */ - JulianDate.prototype.equals = function(right) { - return JulianDate.equals(this, right); - }; + // Both roots are real. + var root = Math.sqrt(ratio); + return [-root, root]; + } else if (c === 0.0) { + // a * x^2 + b * x = 0 + ratio = -b / a; + if (ratio < 0.0) { + return [ratio, 0.0]; + } - /** - * Compares this and the provided instance and returns <code>true</code> if they are within <code>epsilon</code> seconds of - * each other. That is, in order for the dates to be considered equal (and for - * this function to return <code>true</code>), the absolute value of the difference between them, in - * seconds, must be less than <code>epsilon</code>. - * - * @param {JulianDate} [right] The second instance. - * @param {Number} epsilon The maximum number of seconds that should separate the two instances. - * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. - */ - JulianDate.prototype.equalsEpsilon = function(right, epsilon) { - return JulianDate.equalsEpsilon(this, right, epsilon); - }; + return [0.0, ratio]; + } - /** - * Creates a string representing this date in ISO8601 format. - * - * @returns {String} A string representing this date in ISO8601 format. - */ - JulianDate.prototype.toString = function() { - return JulianDate.toIso8601(this); - }; + // a * x^2 + b * x + c = 0 + var b2 = b * b; + var four_ac = 4.0 * a * c; + var radicand = addWithCancellationCheck(b2, -four_ac, CesiumMath.EPSILON14); - /** - * Gets or sets the list of leap seconds used throughout Cesium. - * @memberof JulianDate - * @type {LeapSecond[]} - */ - JulianDate.leapSeconds = [ - new LeapSecond(new JulianDate(2441317, 43210.0, TimeStandard.TAI), 10), // January 1, 1972 00:00:00 UTC - new LeapSecond(new JulianDate(2441499, 43211.0, TimeStandard.TAI), 11), // July 1, 1972 00:00:00 UTC - new LeapSecond(new JulianDate(2441683, 43212.0, TimeStandard.TAI), 12), // January 1, 1973 00:00:00 UTC - new LeapSecond(new JulianDate(2442048, 43213.0, TimeStandard.TAI), 13), // January 1, 1974 00:00:00 UTC - new LeapSecond(new JulianDate(2442413, 43214.0, TimeStandard.TAI), 14), // January 1, 1975 00:00:00 UTC - new LeapSecond(new JulianDate(2442778, 43215.0, TimeStandard.TAI), 15), // January 1, 1976 00:00:00 UTC - new LeapSecond(new JulianDate(2443144, 43216.0, TimeStandard.TAI), 16), // January 1, 1977 00:00:00 UTC - new LeapSecond(new JulianDate(2443509, 43217.0, TimeStandard.TAI), 17), // January 1, 1978 00:00:00 UTC - new LeapSecond(new JulianDate(2443874, 43218.0, TimeStandard.TAI), 18), // January 1, 1979 00:00:00 UTC - new LeapSecond(new JulianDate(2444239, 43219.0, TimeStandard.TAI), 19), // January 1, 1980 00:00:00 UTC - new LeapSecond(new JulianDate(2444786, 43220.0, TimeStandard.TAI), 20), // July 1, 1981 00:00:00 UTC - new LeapSecond(new JulianDate(2445151, 43221.0, TimeStandard.TAI), 21), // July 1, 1982 00:00:00 UTC - new LeapSecond(new JulianDate(2445516, 43222.0, TimeStandard.TAI), 22), // July 1, 1983 00:00:00 UTC - new LeapSecond(new JulianDate(2446247, 43223.0, TimeStandard.TAI), 23), // July 1, 1985 00:00:00 UTC - new LeapSecond(new JulianDate(2447161, 43224.0, TimeStandard.TAI), 24), // January 1, 1988 00:00:00 UTC - new LeapSecond(new JulianDate(2447892, 43225.0, TimeStandard.TAI), 25), // January 1, 1990 00:00:00 UTC - new LeapSecond(new JulianDate(2448257, 43226.0, TimeStandard.TAI), 26), // January 1, 1991 00:00:00 UTC - new LeapSecond(new JulianDate(2448804, 43227.0, TimeStandard.TAI), 27), // July 1, 1992 00:00:00 UTC - new LeapSecond(new JulianDate(2449169, 43228.0, TimeStandard.TAI), 28), // July 1, 1993 00:00:00 UTC - new LeapSecond(new JulianDate(2449534, 43229.0, TimeStandard.TAI), 29), // July 1, 1994 00:00:00 UTC - new LeapSecond(new JulianDate(2450083, 43230.0, TimeStandard.TAI), 30), // January 1, 1996 00:00:00 UTC - new LeapSecond(new JulianDate(2450630, 43231.0, TimeStandard.TAI), 31), // July 1, 1997 00:00:00 UTC - new LeapSecond(new JulianDate(2451179, 43232.0, TimeStandard.TAI), 32), // January 1, 1999 00:00:00 UTC - new LeapSecond(new JulianDate(2453736, 43233.0, TimeStandard.TAI), 33), // January 1, 2006 00:00:00 UTC - new LeapSecond(new JulianDate(2454832, 43234.0, TimeStandard.TAI), 34), // January 1, 2009 00:00:00 UTC - new LeapSecond(new JulianDate(2456109, 43235.0, TimeStandard.TAI), 35), // July 1, 2012 00:00:00 UTC - new LeapSecond(new JulianDate(2457204, 43236.0, TimeStandard.TAI), 36), // July 1, 2015 00:00:00 UTC - new LeapSecond(new JulianDate(2457754, 43237.0, TimeStandard.TAI), 37) // January 1, 2017 00:00:00 UTC - ]; + if (radicand < 0.0) { + // Both roots are complex. + return []; + } - return JulianDate; + var q = -0.5 * addWithCancellationCheck(b, CesiumMath.sign(b) * Math.sqrt(radicand), CesiumMath.EPSILON14); + if (b > 0.0) { + return [q / a, c / q]; + } + + return [c / q, q / a]; + }; + + return QuadraticRealPolynomial; }); -define('Core/clone',[ - './defaultValue' +define('Core/CubicRealPolynomial',[ + './DeveloperError', + './QuadraticRealPolynomial' ], function( - defaultValue) { + DeveloperError, + QuadraticRealPolynomial) { 'use strict'; /** - * Clones an object, returning a new object containing the same properties. + * Defines functions for 3rd order polynomial functions of one variable with only real coefficients. * - * @exports clone + * @exports CubicRealPolynomial + */ + var CubicRealPolynomial = {}; + + /** + * Provides the discriminant of the cubic equation from the supplied coefficients. * - * @param {Object} object The object to clone. - * @param {Boolean} [deep=false] If true, all properties will be deep cloned recursively. - * @returns {Object} The cloned object. + * @param {Number} a The coefficient of the 3rd order monomial. + * @param {Number} b The coefficient of the 2nd order monomial. + * @param {Number} c The coefficient of the 1st order monomial. + * @param {Number} d The coefficient of the 0th order monomial. + * @returns {Number} The value of the discriminant. */ - function clone(object, deep) { - if (object === null || typeof object !== 'object') { - return object; + CubicRealPolynomial.computeDiscriminant = function(a, b, c, d) { + if (typeof a !== 'number') { + throw new DeveloperError('a is a required number.'); + } + if (typeof b !== 'number') { + throw new DeveloperError('b is a required number.'); + } + if (typeof c !== 'number') { + throw new DeveloperError('c is a required number.'); } + if (typeof d !== 'number') { + throw new DeveloperError('d is a required number.'); + } + + var a2 = a * a; + var b2 = b * b; + var c2 = c * c; + var d2 = d * d; - deep = defaultValue(deep, false); + var discriminant = 18.0 * a * b * c * d + b2 * c2 - 27.0 * a2 * d2 - 4.0 * (a * c2 * c + b2 * b * d); + return discriminant; + }; - var result = new object.constructor(); - for ( var propertyName in object) { - if (object.hasOwnProperty(propertyName)) { - var value = object[propertyName]; - if (deep) { - value = clone(value, deep); - } - result[propertyName] = value; + function computeRealRoots(a, b, c, d) { + var A = a; + var B = b / 3.0; + var C = c / 3.0; + var D = d; + + var AC = A * C; + var BD = B * D; + var B2 = B * B; + var C2 = C * C; + var delta1 = A * C - B2; + var delta2 = A * D - B * C; + var delta3 = B * D - C2; + + var discriminant = 4.0 * delta1 * delta3 - delta2 * delta2; + var temp; + var temp1; + + if (discriminant < 0.0) { + var ABar; + var CBar; + var DBar; + + if (B2 * BD >= AC * C2) { + ABar = A; + CBar = delta1; + DBar = -2.0 * B * delta1 + A * delta2; + } else { + ABar = D; + CBar = delta3; + DBar = -D * delta2 + 2.0 * C * delta3; } - } - return result; - } + var s = (DBar < 0.0) ? -1.0 : 1.0; // This is not Math.Sign()! + var temp0 = -s * Math.abs(ABar) * Math.sqrt(-discriminant); + temp1 = -DBar + temp0; - return clone; -}); + var x = temp1 / 2.0; + var p = x < 0.0 ? -Math.pow(-x, 1.0 / 3.0) : Math.pow(x, 1.0 / 3.0); + var q = (temp1 === temp0) ? -p : -CBar / p; -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + temp = (CBar <= 0.0) ? p + q : -DBar / (p * p + q * q + CBar); - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + if (B2 * BD >= AC * C2) { + return [(temp - B) / A]; + } - if (!headerString) { - return headers; + return [-D / (temp + C)]; } - var headerPairs = headerString.split('\u000d\u000a'); + var CBarA = delta1; + var DBarA = -2.0 * B * delta1 + A * delta2; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } + var CBarD = delta3; + var DBarD = -D * delta2 + 2.0 * C * delta3; - return headers; - } + var squareRootOfDiscriminant = Math.sqrt(discriminant); + var halfSquareRootOf3 = Math.sqrt(3.0) / 2.0; - return parseResponseHeaders; -}); + var theta = Math.abs(Math.atan2(A * squareRootOfDiscriminant, -DBarA) / 3.0); + temp = 2.0 * Math.sqrt(-CBarA); + var cosine = Math.cos(theta); + temp1 = temp * cosine; + var temp3 = temp * (-cosine / 2.0 - halfSquareRootOf3 * Math.sin(theta)); -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; + var numeratorLarge = (temp1 + temp3 > 2.0 * B) ? temp1 - B : temp3 - B; + var denominatorLarge = A; - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + var root1 = numeratorLarge / denominatorLarge; - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + theta = Math.abs(Math.atan2(D * squareRootOfDiscriminant, -DBarD) / 3.0); + temp = 2.0 * Math.sqrt(-CBarD); + cosine = Math.cos(theta); + temp1 = temp * cosine; + temp3 = temp * (-cosine / 2.0 - halfSquareRootOf3 * Math.sin(theta)); - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + var numeratorSmall = -D; + var denominatorSmall = (temp1 + temp3 < 2.0 * C) ? temp1 + C : temp3 + C; - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); + var root3 = numeratorSmall / denominatorSmall; + + var E = denominatorLarge * denominatorSmall; + var F = -numeratorLarge * denominatorSmall - denominatorLarge * numeratorSmall; + var G = numeratorLarge * numeratorSmall; + + var root2 = (C * F - B * G) / (-B * F + C * E); + + if (root1 <= root2) { + if (root1 <= root3) { + if (root2 <= root3) { + return [root1, root2, root3]; + } + return [root1, root3, root2]; + } + return [root3, root1, root2]; + } + if (root1 <= root3) { + return [root2, root1, root3]; } + if (root2 <= root3) { + return [root2, root3, root1]; + } + return [root3, root2, root1]; } /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Provides the real valued roots of the cubic polynomial with the provided coefficients. * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {Number} a The coefficient of the 3rd order monomial. + * @param {Number} b The coefficient of the 2nd order monomial. + * @param {Number} c The coefficient of the 1st order monomial. + * @param {Number} d The coefficient of the 0th order monomial. + * @returns {Number[]} The real valued roots. */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + CubicRealPolynomial.computeRealRoots = function(a, b, c, d) { + if (typeof a !== 'number') { + throw new DeveloperError('a is a required number.'); } - return str; + if (typeof b !== 'number') { + throw new DeveloperError('b is a required number.'); + } + if (typeof c !== 'number') { + throw new DeveloperError('c is a required number.'); + } + if (typeof d !== 'number') { + throw new DeveloperError('d is a required number.'); + } + + var roots; + var ratio; + if (a === 0.0) { + // Quadratic function: b * x^2 + c * x + d = 0. + return QuadraticRealPolynomial.computeRealRoots(b, c, d); + } else if (b === 0.0) { + if (c === 0.0) { + if (d === 0.0) { + // 3rd order monomial: a * x^3 = 0. + return [0.0, 0.0, 0.0]; + } + + // a * x^3 + d = 0 + ratio = -d / a; + var root = (ratio < 0.0) ? -Math.pow(-ratio, 1.0 / 3.0) : Math.pow(ratio, 1.0 / 3.0); + return [root, root, root]; + } else if (d === 0.0) { + // x * (a * x^2 + c) = 0. + roots = QuadraticRealPolynomial.computeRealRoots(a, 0, c); + + // Return the roots in ascending order. + if (roots.Length === 0) { + return [0.0]; + } + return [roots[0], 0.0, roots[1]]; + } + + // Deflated cubic polynomial: a * x^3 + c * x + d= 0. + return computeRealRoots(a, 0, c, d); + } else if (c === 0.0) { + if (d === 0.0) { + // x^2 * (a * x + b) = 0. + ratio = -b / a; + if (ratio < 0.0) { + return [ratio, 0.0, 0.0]; + } + return [0.0, 0.0, ratio]; + } + // a * x^3 + b * x^2 + d = 0. + return computeRealRoots(a, b, 0, d); + } else if (d === 0.0) { + // x * (a * x^2 + b * x + c) = 0 + roots = QuadraticRealPolynomial.computeRealRoots(a, b, c); + + // Return the roots in ascending order. + if (roots.length === 0) { + return [0.0]; + } else if (roots[1] <= 0.0) { + return [roots[0], roots[1], 0.0]; + } else if (roots[0] >= 0.0) { + return [0.0, roots[0], roots[1]]; + } + return [roots[0], 0.0, roots[1]]; + } + + return computeRealRoots(a, b, c, d); }; - return RequestErrorEvent; + return CubicRealPolynomial; }); -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' +define('Core/QuarticRealPolynomial',[ + './CubicRealPolynomial', + './DeveloperError', + './Math', + './QuadraticRealPolynomial' ], function( - Uri, - defined, - DeveloperError) { + CubicRealPolynomial, + DeveloperError, + CesiumMath, + QuadraticRealPolynomial) { 'use strict'; /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. - * - * @exports TrustedServers + * Defines functions for 4th order polynomial functions of one variable with only real coefficients. * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @exports QuarticRealPolynomial */ - var TrustedServers = {}; - var _servers = {}; + var QuarticRealPolynomial = {}; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Provides the discriminant of the quartic equation from the supplied coefficients. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {Number} a The coefficient of the 4th order monomial. + * @param {Number} b The coefficient of the 3rd order monomial. + * @param {Number} c The coefficient of the 2nd order monomial. + * @param {Number} d The coefficient of the 1st order monomial. + * @param {Number} e The coefficient of the 0th order monomial. + * @returns {Number} The value of the discriminant. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); + QuarticRealPolynomial.computeDiscriminant = function(a, b, c, d, e) { + if (typeof a !== 'number') { + throw new DeveloperError('a is a required number.'); } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); + if (typeof b !== 'number') { + throw new DeveloperError('b is a required number.'); } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; + if (typeof c !== 'number') { + throw new DeveloperError('c is a required number.'); } - }; - - /** - * Removes a trusted server from the registry - * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. - * - * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); - */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); + if (typeof d !== 'number') { + throw new DeveloperError('d is a required number.'); } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); + if (typeof e !== 'number') { + throw new DeveloperError('e is a required number.'); } - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; + var a2 = a * a; + var a3 = a2 * a; + var b2 = b * b; + var b3 = b2 * b; + var c2 = c * c; + var c3 = c2 * c; + var d2 = d * d; + var d3 = d2 * d; + var e2 = e * e; + var e3 = e2 * e; - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); + var discriminant = (b2 * c2 * d2 - 4.0 * b3 * d3 - 4.0 * a * c3 * d2 + 18 * a * b * c * d3 - 27.0 * a2 * d2 * d2 + 256.0 * a3 * e3) + + e * (18.0 * b3 * c * d - 4.0 * b2 * c3 + 16.0 * a * c2 * c2 - 80.0 * a * b * c2 * d - 6.0 * a * b2 * d2 + 144.0 * a2 * c * d2) + + e2 * (144.0 * a * b2 * c - 27.0 * b2 * b2 - 128.0 * a2 * c2 - 192.0 * a2 * b * d); + return discriminant; + }; - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + function original(a3, a2, a1, a0) { + var a3Squared = a3 * a3; - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; - } + var p = a2 - 3.0 * a3Squared / 8.0; + var q = a1 - a2 * a3 / 2.0 + a3Squared * a3 / 8.0; + var r = a0 - a1 * a3 / 4.0 + a2 * a3Squared / 16.0 - 3.0 * a3Squared * a3Squared / 256.0; - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + // Find the roots of the cubic equations: h^6 + 2 p h^4 + (p^2 - 4 r) h^2 - q^2 = 0. + var cubicRoots = CubicRealPolynomial.computeRealRoots(1.0, 2.0 * p, p * p - 4.0 * r, -q * q); - return authority; - } + if (cubicRoots.length > 0) { + var temp = -a3 / 4.0; - /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. - * - * @param {String} url The url to be tested against the trusted list - * - * @returns {boolean} Returns true if url is trusted, false otherwise. - * - * @example - * // Add server - * TrustedServers.add('my.server.com', 81); - * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } - */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + // Use the largest positive root. + var hSquared = cubicRoots[cubicRoots.length - 1]; - return false; - }; + if (Math.abs(hSquared) < CesiumMath.EPSILON14) { + // y^4 + p y^2 + r = 0. + var roots = QuadraticRealPolynomial.computeRealRoots(1.0, p, r); - /** - * Clears the registry - * - * @example - * // Remove a trusted server - * TrustedServers.clear(); - */ - TrustedServers.clear = function() { - _servers = {}; - }; + if (roots.length === 2) { + var root0 = roots[0]; + var root1 = roots[1]; - return TrustedServers; -}); + var y; + if (root0 >= 0.0 && root1 >= 0.0) { + var y0 = Math.sqrt(root0); + var y1 = Math.sqrt(root1); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + return [temp - y1, temp - y0, temp + y0, temp + y1]; + } else if (root0 >= 0.0 && root1 < 0.0) { + y = Math.sqrt(root0); + return [temp - y, temp + y]; + } else if (root0 < 0.0 && root1 >= 0.0) { + y = Math.sqrt(root1); + return [temp - y, temp + y]; + } + } + return []; + } else if (hSquared > 0.0) { + var h = Math.sqrt(hSquared); - /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var m = (p + hSquared - q / h) / 2.0; + var n = (p + hSquared + q / h) / 2.0; - Check.defined('options.url', options.url); - - var url = options.url; + // Now solve the two quadratic factors: (y^2 + h y + m)(y^2 - h y + n); + var roots1 = QuadraticRealPolynomial.computeRealRoots(1.0, h, m); + var roots2 = QuadraticRealPolynomial.computeRealRoots(1.0, -h, n); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + if (roots1.length !== 0) { + roots1[0] += temp; + roots1[1] += temp; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; - request.requestFunction = function() { - var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); - if (defined(xhr) && defined(xhr.abort)) { - request.cancelFunction = function() { - xhr.abort(); - }; - } - return deferred.promise; - }; + if (roots2.length !== 0) { + roots2[0] += temp; + roots2[1] += temp; - return RequestScheduler.request(request); - } + if (roots1[1] <= roots2[0]) { + return [roots1[0], roots1[1], roots2[0], roots2[1]]; + } else if (roots2[1] <= roots1[0]) { + return [roots2[0], roots2[1], roots1[0], roots1[1]]; + } else if (roots1[0] >= roots2[0] && roots1[1] <= roots2[1]) { + return [roots2[0], roots1[0], roots1[1], roots2[1]]; + } else if (roots2[0] >= roots1[0] && roots2[1] <= roots1[1]) { + return [roots1[0], roots2[0], roots2[1], roots1[1]]; + } else if (roots1[0] > roots2[0] && roots1[0] < roots2[1]) { + return [roots2[0], roots1[0], roots2[1], roots1[1]]; + } + return [roots1[0], roots2[0], roots1[1], roots2[1]]; + } + return roots1; + } - var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + if (roots2.length !== 0) { + roots2[0] += temp; + roots2[1] += temp; - function decodeDataUriText(isBase64, data) { - var result = decodeURIComponent(data); - if (isBase64) { - return atob(result); + return roots2; + } + return []; + } } - return result; + return []; } - function decodeDataUriArrayBuffer(isBase64, data) { - var byteString = decodeDataUriText(isBase64, data); - var buffer = new ArrayBuffer(byteString.length); - var view = new Uint8Array(buffer); - for (var i = 0; i < byteString.length; i++) { - view[i] = byteString.charCodeAt(i); - } - return buffer; - } + function neumark(a3, a2, a1, a0) { + var a1Squared = a1 * a1; + var a2Squared = a2 * a2; + var a3Squared = a3 * a3; - function decodeDataUri(dataUriRegexResult, responseType) { - responseType = defaultValue(responseType, ''); - var mimeType = dataUriRegexResult[1]; - var isBase64 = !!dataUriRegexResult[2]; - var data = dataUriRegexResult[3]; + var p = -2.0 * a2; + var q = a1 * a3 + a2Squared - 4.0 * a0; + var r = a3Squared * a0 - a1 * a2 * a3 + a1Squared; - switch (responseType) { - case '': - case 'text': - return decodeDataUriText(isBase64, data); - case 'arraybuffer': - return decodeDataUriArrayBuffer(isBase64, data); - case 'blob': - var buffer = decodeDataUriArrayBuffer(isBase64, data); - return new Blob([buffer], { - type : mimeType - }); - case 'document': - var parser = new DOMParser(); - return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); - case 'json': - return JSON.parse(decodeDataUriText(isBase64, data)); - default: - throw new DeveloperError('Unhandled responseType: ' + responseType); - } - } + var cubicRoots = CubicRealPolynomial.computeRealRoots(1.0, p, q, r); - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { - var dataUriRegexResult = dataUriRegex.exec(url); - if (dataUriRegexResult !== null) { - deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); - return; - } + if (cubicRoots.length > 0) { + // Use the most positive root + var y = cubicRoots[0]; - var xhr = new XMLHttpRequest(); + var temp = (a2 - y); + var tempSquared = temp * temp; - if (TrustedServers.contains(url)) { - xhr.withCredentials = true; - } + var g1 = a3 / 2.0; + var h1 = temp / 2.0; - if (defined(overrideMimeType) && defined(xhr.overrideMimeType)) { - xhr.overrideMimeType(overrideMimeType); - } + var m = tempSquared - 4.0 * a0; + var mError = tempSquared + 4.0 * Math.abs(a0); - xhr.open(method, url, true); + var n = a3Squared - 4.0 * y; + var nError = a3Squared + 4.0 * Math.abs(y); - if (defined(headers)) { - for (var key in headers) { - if (headers.hasOwnProperty(key)) { - xhr.setRequestHeader(key, headers[key]); - } - } - } + var g2; + var h2; - if (defined(responseType)) { - xhr.responseType = responseType; - } + if (y < 0.0 || (m * nError < n * mError)) { + var squareRootOfN = Math.sqrt(n); + g2 = squareRootOfN / 2.0; + h2 = squareRootOfN === 0.0 ? 0.0 : (a3 * h1 - a1) / squareRootOfN; + } else { + var squareRootOfM = Math.sqrt(m); + g2 = squareRootOfM === 0.0 ? 0.0 : (a3 * h1 - a1) / squareRootOfM; + h2 = squareRootOfM / 2.0; + } - // While non-standard, file protocol always returns a status of 0 on success - var localFile = false; - if (typeof url === 'string') { - localFile = url.indexOf('file://') === 0; - } + var G; + var g; + if (g1 === 0.0 && g2 === 0.0) { + G = 0.0; + g = 0.0; + } else if (CesiumMath.sign(g1) === CesiumMath.sign(g2)) { + G = g1 + g2; + g = y / G; + } else { + g = g1 - g2; + G = y / g; + } - xhr.onload = function() { - if ((xhr.status < 200 || xhr.status >= 300) && !(localFile && xhr.status === 0)) { - deferred.reject(new RequestErrorEvent(xhr.status, xhr.response, xhr.getAllResponseHeaders())); - return; + var H; + var h; + if (h1 === 0.0 && h2 === 0.0) { + H = 0.0; + h = 0.0; + } else if (CesiumMath.sign(h1) === CesiumMath.sign(h2)) { + H = h1 + h2; + h = a0 / H; + } else { + h = h1 - h2; + H = a0 / h; } - var response = xhr.response; - var browserResponseType = xhr.responseType; + // Now solve the two quadratic factors: (y^2 + G y + H)(y^2 + g y + h); + var roots1 = QuadraticRealPolynomial.computeRealRoots(1.0, G, H); + var roots2 = QuadraticRealPolynomial.computeRealRoots(1.0, g, h); - //All modern browsers will go into either the first or second if block or last else block. - //Other code paths support older browsers that either do not support the supplied responseType - //or do not support the xhr.response property. - if (xhr.status === 204) { - // accept no content - deferred.resolve(); - } else if (defined(response) && (!defined(responseType) || (browserResponseType === responseType))) { - deferred.resolve(response); - } else if ((responseType === 'json') && typeof response === 'string') { - try { - deferred.resolve(JSON.parse(response)); - } catch (e) { - deferred.reject(e); + if (roots1.length !== 0) { + if (roots2.length !== 0) { + if (roots1[1] <= roots2[0]) { + return [roots1[0], roots1[1], roots2[0], roots2[1]]; + } else if (roots2[1] <= roots1[0]) { + return [roots2[0], roots2[1], roots1[0], roots1[1]]; + } else if (roots1[0] >= roots2[0] && roots1[1] <= roots2[1]) { + return [roots2[0], roots1[0], roots1[1], roots2[1]]; + } else if (roots2[0] >= roots1[0] && roots2[1] <= roots1[1]) { + return [roots1[0], roots2[0], roots2[1], roots1[1]]; + } else if (roots1[0] > roots2[0] && roots1[0] < roots2[1]) { + return [roots2[0], roots1[0], roots2[1], roots1[1]]; + } + return [roots1[0], roots2[0], roots1[1], roots2[1]]; } - } else if ((browserResponseType === '' || browserResponseType === 'document') && defined(xhr.responseXML) && xhr.responseXML.hasChildNodes()) { - deferred.resolve(xhr.responseXML); - } else if ((browserResponseType === '' || browserResponseType === 'text') && defined(xhr.responseText)) { - deferred.resolve(xhr.responseText); - } else { - deferred.reject(new RuntimeError('Invalid XMLHttpRequest response type.')); + return roots1; } - }; + if (roots2.length !== 0) { + return roots2; + } + } + return []; + } - xhr.onerror = function(e) { - deferred.reject(new RequestErrorEvent()); - }; + /** + * Provides the real valued roots of the quartic polynomial with the provided coefficients. + * + * @param {Number} a The coefficient of the 4th order monomial. + * @param {Number} b The coefficient of the 3rd order monomial. + * @param {Number} c The coefficient of the 2nd order monomial. + * @param {Number} d The coefficient of the 1st order monomial. + * @param {Number} e The coefficient of the 0th order monomial. + * @returns {Number[]} The real valued roots. + */ + QuarticRealPolynomial.computeRealRoots = function(a, b, c, d, e) { + if (typeof a !== 'number') { + throw new DeveloperError('a is a required number.'); + } + if (typeof b !== 'number') { + throw new DeveloperError('b is a required number.'); + } + if (typeof c !== 'number') { + throw new DeveloperError('c is a required number.'); + } + if (typeof d !== 'number') { + throw new DeveloperError('d is a required number.'); + } + if (typeof e !== 'number') { + throw new DeveloperError('e is a required number.'); + } + + if (Math.abs(a) < CesiumMath.EPSILON15) { + return CubicRealPolynomial.computeRealRoots(b, c, d, e); + } + var a3 = b / a; + var a2 = c / a; + var a1 = d / a; + var a0 = e / a; - xhr.send(data); + var k = (a3 < 0.0) ? 1 : 0; + k += (a2 < 0.0) ? k + 1 : k; + k += (a1 < 0.0) ? k + 1 : k; + k += (a0 < 0.0) ? k + 1 : k; - return xhr; + switch (k) { + case 0: + return original(a3, a2, a1, a0); + case 1: + return neumark(a3, a2, a1, a0); + case 2: + return neumark(a3, a2, a1, a0); + case 3: + return original(a3, a2, a1, a0); + case 4: + return original(a3, a2, a1, a0); + case 5: + return neumark(a3, a2, a1, a0); + case 6: + return original(a3, a2, a1, a0); + case 7: + return original(a3, a2, a1, a0); + case 8: + return neumark(a3, a2, a1, a0); + case 9: + return original(a3, a2, a1, a0); + case 10: + return original(a3, a2, a1, a0); + case 11: + return neumark(a3, a2, a1, a0); + case 12: + return original(a3, a2, a1, a0); + case 13: + return original(a3, a2, a1, a0); + case 14: + return original(a3, a2, a1, a0); + case 15: + return original(a3, a2, a1, a0); + default: + return undefined; + } }; - loadWithXhr.defaultLoad = loadWithXhr.load; - - return loadWithXhr; + return QuarticRealPolynomial; }); -define('Core/loadText',[ - './loadWithXhr' +define('Core/Ray',[ + './Cartesian3', + './defaultValue', + './defined', + './DeveloperError' ], function( - loadWithXhr) { + Cartesian3, + defaultValue, + defined, + DeveloperError) { 'use strict'; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * Represents a ray that extends infinitely from the provided origin in the provided direction. + * @alias Ray + * @constructor * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @param {Cartesian3} [origin=Cartesian3.ZERO] The origin of the ray. + * @param {Cartesian3} [direction=Cartesian3.ZERO] The direction of the ray. */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); + function Ray(origin, direction) { + direction = Cartesian3.clone(defaultValue(direction, Cartesian3.ZERO)); + if (!Cartesian3.equals(direction, Cartesian3.ZERO)) { + Cartesian3.normalize(direction, direction); + } -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; + /** + * The origin of the ray. + * @type {Cartesian3} + * @default {@link Cartesian3.ZERO} + */ + this.origin = Cartesian3.clone(defaultValue(origin, Cartesian3.ZERO)); - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + /** + * The direction of the ray. + * @type {Cartesian3} + */ + this.direction = direction; + } - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * Computes the point along the ray given by r(t) = o + t*d, + * where o is the origin of the ray and d is the direction. * + * @param {Ray} ray The ray. + * @param {Number} t A scalar value. + * @param {Cartesian3} [result] The object in which the result will be stored. + * @returns {Cartesian3} The modified result parameter, or a new instance if none was provided. * * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * //Get the first intersection point of a ray and an ellipsoid. + * var intersection = Cesium.IntersectionTests.rayEllipsoid(ray, ellipsoid); + * var point = Cesium.Ray.getPoint(ray, intersection.start); */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); + Ray.getPoint = function(ray, t, result) { + if (!defined(ray)){ + throw new DeveloperError('ray is requred'); } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; + if (typeof t !== 'number') { + throw new DeveloperError('t is a required number'); } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; + + if (!defined(result)) { + result = new Cartesian3(); } - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + result = Cartesian3.multiplyByScalar(ray.direction, t, result); + return Cartesian3.add(ray.origin, result, result); + }; - return loadJson; + return Ray; }); -define('Core/EarthOrientationParameters',[ - '../ThirdParty/when', - './binarySearch', +define('Core/IntersectionTests',[ + './Cartesian3', + './Cartographic', './defaultValue', './defined', - './EarthOrientationParametersSample', - './freezeObject', - './JulianDate', - './LeapSecond', - './loadJson', - './RuntimeError', - './TimeConstants', - './TimeStandard' + './DeveloperError', + './Interval', + './Math', + './Matrix3', + './QuadraticRealPolynomial', + './QuarticRealPolynomial', + './Ray' ], function( - when, - binarySearch, + Cartesian3, + Cartographic, defaultValue, defined, - EarthOrientationParametersSample, - freezeObject, - JulianDate, - LeapSecond, - loadJson, - RuntimeError, - TimeConstants, - TimeStandard) { + DeveloperError, + Interval, + CesiumMath, + Matrix3, + QuadraticRealPolynomial, + QuarticRealPolynomial, + Ray) { 'use strict'; /** - * Specifies Earth polar motion coordinates and the difference between UT1 and UTC. - * These Earth Orientation Parameters (EOP) are primarily used in the transformation from - * the International Celestial Reference Frame (ICRF) to the International Terrestrial - * Reference Frame (ITRF). - * - * @alias EarthOrientationParameters - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this - * parameter nor options.data is specified, all EOP values are assumed - * to be 0.0. If options.data is specified, this parameter is - * ignored. - * @param {Object} [options.data] The actual EOP data. If neither this - * parameter nor options.data is specified, all EOP values are assumed - * to be 0.0. - * @param {Boolean} [options.addNewLeapSeconds=true] True if leap seconds that - * are specified in the EOP data but not in {@link JulianDate.leapSeconds} - * should be added to {@link JulianDate.leapSeconds}. False if - * new leap seconds should be handled correctly in the context - * of the EOP data but otherwise ignored. - * - * @example - * // An example EOP data file, EOP.json: - * { - * "columnNames" : ["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"], - * "samples" : [ - * "2011-07-01T00:00:00Z",55743.0,2.117957047295119e-7,2.111518721609984e-6,-0.2908948,-2.956e-4,3.393695767766752e-11,3.3452143996557983e-10,34.0, - * "2011-07-02T00:00:00Z",55744.0,2.193297093339541e-7,2.115460256837405e-6,-0.29065,-1.824e-4,-8.241832578862112e-11,5.623838700870617e-10,34.0, - * "2011-07-03T00:00:00Z",55745.0,2.262286080161428e-7,2.1191157519929706e-6,-0.2905572,1.9e-6,-3.490658503988659e-10,6.981317007977318e-10,34.0 - * ] - * } - * - * @example - * // Loading the EOP data - * var eop = new Cesium.EarthOrientationParameters({ url : 'Data/EOP.json' }); - * Cesium.Transforms.earthOrientationParameters = eop; + * Functions for computing the intersection between geometries such as rays, planes, triangles, and ellipsoids. * - * @private + * @exports IntersectionTests */ - function EarthOrientationParameters(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._dates = undefined; - this._samples = undefined; + var IntersectionTests = {}; - this._dateColumn = -1; - this._xPoleWanderRadiansColumn = -1; - this._yPoleWanderRadiansColumn = -1; - this._ut1MinusUtcSecondsColumn = -1; - this._xCelestialPoleOffsetRadiansColumn = -1; - this._yCelestialPoleOffsetRadiansColumn = -1; - this._taiMinusUtcSecondsColumn = -1; + /** + * Computes the intersection of a ray and a plane. + * + * @param {Ray} ray The ray. + * @param {Plane} plane The plane. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The intersection point or undefined if there is no intersections. + */ + IntersectionTests.rayPlane = function(ray, plane, result) { + if (!defined(ray)) { + throw new DeveloperError('ray is required.'); + } + if (!defined(plane)) { + throw new DeveloperError('plane is required.'); + } + + if (!defined(result)) { + result = new Cartesian3(); + } - this._columnCount = 0; - this._lastIndex = -1; + var origin = ray.origin; + var direction = ray.direction; + var normal = plane.normal; + var denominator = Cartesian3.dot(normal, direction); - this._downloadPromise = undefined; - this._dataError = undefined; + if (Math.abs(denominator) < CesiumMath.EPSILON15) { + // Ray is parallel to plane. The ray may be in the polygon's plane. + return undefined; + } - this._addNewLeapSeconds = defaultValue(options.addNewLeapSeconds, true); + var t = (-plane.distance - Cartesian3.dot(normal, origin)) / denominator; - if (defined(options.data)) { - // Use supplied EOP data. - onDataReady(this, options.data); - } else if (defined(options.url)) { - // Download EOP data. - var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { - onDataReady(that, eopData); - }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; - }); - } else { - // Use all zeros for EOP data. - onDataReady(this, { - 'columnNames' : ['dateIso8601', 'modifiedJulianDateUtc', 'xPoleWanderRadians', 'yPoleWanderRadians', 'ut1MinusUtcSeconds', 'lengthOfDayCorrectionSeconds', 'xCelestialPoleOffsetRadians', 'yCelestialPoleOffsetRadians', 'taiMinusUtcSeconds'], - 'samples' : [] - }); + if (t < 0) { + return undefined; } - } - - /** - * A default {@link EarthOrientationParameters} instance that returns zero for all EOP values. - */ - EarthOrientationParameters.NONE = freezeObject({ - getPromiseToLoad : function() { - return when(); - }, - compute : function(date, result) { - if (!defined(result)) { - result = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0); - } else { - result.xPoleWander = 0.0; - result.yPoleWander = 0.0; - result.xPoleOffset = 0.0; - result.yPoleOffset = 0.0; - result.ut1MinusUtc = 0.0; - } - return result; - } - }); - /** - * Gets a promise that, when resolved, indicates that the EOP data has been loaded and is - * ready to use. - * - * @returns {Promise.<undefined>} The promise. - * - * @see when - */ - EarthOrientationParameters.prototype.getPromiseToLoad = function() { - return when(this._downloadPromise); + result = Cartesian3.multiplyByScalar(direction, t, result); + return Cartesian3.add(origin, result, result); }; + var scratchEdge0 = new Cartesian3(); + var scratchEdge1 = new Cartesian3(); + var scratchPVec = new Cartesian3(); + var scratchTVec = new Cartesian3(); + var scratchQVec = new Cartesian3(); + /** - * Computes the Earth Orientation Parameters (EOP) for a given date by interpolating. - * If the EOP data has not yet been download, this method returns undefined. + * Computes the intersection of a ray and a triangle as a parametric distance along the input ray. * - * @param {JulianDate} date The date for each to evaluate the EOP. - * @param {EarthOrientationParametersSample} [result] The instance to which to copy the result. - * If this parameter is undefined, a new instance is created and returned. - * @returns {EarthOrientationParametersSample} The EOP evaluated at the given date, or - * undefined if the data necessary to evaluate EOP at the date has not yet been - * downloaded. + * Implements {@link https://cadxfem.org/inf/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf| + * Fast Minimum Storage Ray/Triangle Intersection} by Tomas Moller and Ben Trumbore. * - * @exception {RuntimeError} The loaded EOP data has an error and cannot be used. + * @memberof IntersectionTests * - * @see EarthOrientationParameters#getPromiseToLoad + * @param {Ray} ray The ray. + * @param {Cartesian3} p0 The first vertex of the triangle. + * @param {Cartesian3} p1 The second vertex of the triangle. + * @param {Cartesian3} p2 The third vertex of the triangle. + * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle + * and return undefined for intersections with the back face. + * @returns {Number} The intersection as a parametric distance along the ray, or undefined if there is no intersection. */ - EarthOrientationParameters.prototype.compute = function(date, result) { - // We cannot compute until the samples are available. - if (!defined(this._samples)) { - if (defined(this._dataError)) { - throw new RuntimeError(this._dataError); - } - - return undefined; + IntersectionTests.rayTriangleParametric = function(ray, p0, p1, p2, cullBackFaces) { + if (!defined(ray)) { + throw new DeveloperError('ray is required.'); } - - if (!defined(result)) { - result = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0); + if (!defined(p0)) { + throw new DeveloperError('p0 is required.'); } - - if (this._samples.length === 0) { - result.xPoleWander = 0.0; - result.yPoleWander = 0.0; - result.xPoleOffset = 0.0; - result.yPoleOffset = 0.0; - result.ut1MinusUtc = 0.0; - return result; + if (!defined(p1)) { + throw new DeveloperError('p1 is required.'); + } + if (!defined(p2)) { + throw new DeveloperError('p2 is required.'); } + + cullBackFaces = defaultValue(cullBackFaces, false); - var dates = this._dates; - var lastIndex = this._lastIndex; + var origin = ray.origin; + var direction = ray.direction; - var before = 0; - var after = 0; - if (defined(lastIndex)) { - var previousIndexDate = dates[lastIndex]; - var nextIndexDate = dates[lastIndex + 1]; - var isAfterPrevious = JulianDate.lessThanOrEquals(previousIndexDate, date); - var isAfterLastSample = !defined(nextIndexDate); - var isBeforeNext = isAfterLastSample || JulianDate.greaterThanOrEquals(nextIndexDate, date); + var edge0 = Cartesian3.subtract(p1, p0, scratchEdge0); + var edge1 = Cartesian3.subtract(p2, p0, scratchEdge1); - if (isAfterPrevious && isBeforeNext) { - before = lastIndex; + var p = Cartesian3.cross(direction, edge1, scratchPVec); + var det = Cartesian3.dot(edge0, p); - if (!isAfterLastSample && nextIndexDate.equals(date)) { - ++before; - } - after = before + 1; + var tvec; + var q; - interpolate(this, dates, this._samples, date, before, after, result); - return result; - } - } + var u; + var v; + var t; - var index = binarySearch(dates, date, JulianDate.compare, this._dateColumn); - if (index >= 0) { - // If the next entry is the same date, use the later entry. This way, if two entries - // describe the same moment, one before a leap second and the other after, then we will use - // the post-leap second data. - if (index < dates.length - 1 && dates[index + 1].equals(date)) { - ++index; + if (cullBackFaces) { + if (det < CesiumMath.EPSILON6) { + return undefined; } - before = index; - after = index; - } else { - after = ~index; - before = after - 1; - // Use the first entry if the date requested is before the beginning of the data. - if (before < 0) { - before = 0; + tvec = Cartesian3.subtract(origin, p0, scratchTVec); + u = Cartesian3.dot(tvec, p); + if (u < 0.0 || u > det) { + return undefined; } - } - this._lastIndex = before; + q = Cartesian3.cross(tvec, edge0, scratchQVec); - interpolate(this, dates, this._samples, date, before, after, result); - return result; - }; + v = Cartesian3.dot(direction, q); + if (v < 0.0 || u + v > det) { + return undefined; + } - function compareLeapSecondDates(leapSecond, dateToFind) { - return JulianDate.compare(leapSecond.julianDate, dateToFind); - } + t = Cartesian3.dot(edge1, q) / det; + } else { + if (Math.abs(det) < CesiumMath.EPSILON6) { + return undefined; + } + var invDet = 1.0 / det; - function onDataReady(eop, eopData) { - if (!defined(eopData.columnNames)) { - eop._dataError = 'Error in loaded EOP data: The columnNames property is required.'; - return; - } + tvec = Cartesian3.subtract(origin, p0, scratchTVec); + u = Cartesian3.dot(tvec, p) * invDet; + if (u < 0.0 || u > 1.0) { + return undefined; + } - if (!defined(eopData.samples)) { - eop._dataError = 'Error in loaded EOP data: The samples property is required.'; - return; - } + q = Cartesian3.cross(tvec, edge0, scratchQVec); - var dateColumn = eopData.columnNames.indexOf('modifiedJulianDateUtc'); - var xPoleWanderRadiansColumn = eopData.columnNames.indexOf('xPoleWanderRadians'); - var yPoleWanderRadiansColumn = eopData.columnNames.indexOf('yPoleWanderRadians'); - var ut1MinusUtcSecondsColumn = eopData.columnNames.indexOf('ut1MinusUtcSeconds'); - var xCelestialPoleOffsetRadiansColumn = eopData.columnNames.indexOf('xCelestialPoleOffsetRadians'); - var yCelestialPoleOffsetRadiansColumn = eopData.columnNames.indexOf('yCelestialPoleOffsetRadians'); - var taiMinusUtcSecondsColumn = eopData.columnNames.indexOf('taiMinusUtcSeconds'); + v = Cartesian3.dot(direction, q) * invDet; + if (v < 0.0 || u + v > 1.0) { + return undefined; + } - if (dateColumn < 0 || xPoleWanderRadiansColumn < 0 || yPoleWanderRadiansColumn < 0 || ut1MinusUtcSecondsColumn < 0 || xCelestialPoleOffsetRadiansColumn < 0 || yCelestialPoleOffsetRadiansColumn < 0 || taiMinusUtcSecondsColumn < 0) { - eop._dataError = 'Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns'; - return; + t = Cartesian3.dot(edge1, q) * invDet; } - var samples = eop._samples = eopData.samples; - var dates = eop._dates = []; + return t; + }; - eop._dateColumn = dateColumn; - eop._xPoleWanderRadiansColumn = xPoleWanderRadiansColumn; - eop._yPoleWanderRadiansColumn = yPoleWanderRadiansColumn; - eop._ut1MinusUtcSecondsColumn = ut1MinusUtcSecondsColumn; - eop._xCelestialPoleOffsetRadiansColumn = xCelestialPoleOffsetRadiansColumn; - eop._yCelestialPoleOffsetRadiansColumn = yCelestialPoleOffsetRadiansColumn; - eop._taiMinusUtcSecondsColumn = taiMinusUtcSecondsColumn; + /** + * Computes the intersection of a ray and a triangle as a Cartesian3 coordinate. + * + * Implements {@link https://cadxfem.org/inf/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf| + * Fast Minimum Storage Ray/Triangle Intersection} by Tomas Moller and Ben Trumbore. + * + * @memberof IntersectionTests + * + * @param {Ray} ray The ray. + * @param {Cartesian3} p0 The first vertex of the triangle. + * @param {Cartesian3} p1 The second vertex of the triangle. + * @param {Cartesian3} p2 The third vertex of the triangle. + * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle + * and return undefined for intersections with the back face. + * @param {Cartesian3} [result] The <code>Cartesian3</code> onto which to store the result. + * @returns {Cartesian3} The intersection point or undefined if there is no intersections. + */ + IntersectionTests.rayTriangle = function(ray, p0, p1, p2, cullBackFaces, result) { + var t = IntersectionTests.rayTriangleParametric(ray, p0, p1, p2, cullBackFaces); + if (!defined(t) || t < 0.0) { + return undefined; + } - eop._columnCount = eopData.columnNames.length; - eop._lastIndex = undefined; + if (!defined(result)) { + result = new Cartesian3(); + } - var lastTaiMinusUtc; + Cartesian3.multiplyByScalar(ray.direction, t, result); + return Cartesian3.add(ray.origin, result, result); + }; - var addNewLeapSeconds = eop._addNewLeapSeconds; + var scratchLineSegmentTriangleRay = new Ray(); - // Convert the ISO8601 dates to JulianDates. - for (var i = 0, len = samples.length; i < len; i += eop._columnCount) { - var mjd = samples[i + dateColumn]; - var taiMinusUtc = samples[i + taiMinusUtcSecondsColumn]; - var day = mjd + TimeConstants.MODIFIED_JULIAN_DATE_DIFFERENCE; - var date = new JulianDate(day, taiMinusUtc, TimeStandard.TAI); - dates.push(date); + /** + * Computes the intersection of a line segment and a triangle. + * @memberof IntersectionTests + * + * @param {Cartesian3} v0 The an end point of the line segment. + * @param {Cartesian3} v1 The other end point of the line segment. + * @param {Cartesian3} p0 The first vertex of the triangle. + * @param {Cartesian3} p1 The second vertex of the triangle. + * @param {Cartesian3} p2 The third vertex of the triangle. + * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle + * and return undefined for intersections with the back face. + * @param {Cartesian3} [result] The <code>Cartesian3</code> onto which to store the result. + * @returns {Cartesian3} The intersection point or undefined if there is no intersections. + */ + IntersectionTests.lineSegmentTriangle = function(v0, v1, p0, p1, p2, cullBackFaces, result) { + if (!defined(v0)) { + throw new DeveloperError('v0 is required.'); + } + if (!defined(v1)) { + throw new DeveloperError('v1 is required.'); + } + if (!defined(p0)) { + throw new DeveloperError('p0 is required.'); + } + if (!defined(p1)) { + throw new DeveloperError('p1 is required.'); + } + if (!defined(p2)) { + throw new DeveloperError('p2 is required.'); + } + + var ray = scratchLineSegmentTriangleRay; + Cartesian3.clone(v0, ray.origin); + Cartesian3.subtract(v1, v0, ray.direction); + Cartesian3.normalize(ray.direction, ray.direction); - if (addNewLeapSeconds) { - if (taiMinusUtc !== lastTaiMinusUtc && defined(lastTaiMinusUtc)) { - // We crossed a leap second boundary, so add the leap second - // if it does not already exist. - var leapSeconds = JulianDate.leapSeconds; - var leapSecondIndex = binarySearch(leapSeconds, date, compareLeapSecondDates); - if (leapSecondIndex < 0) { - var leapSecond = new LeapSecond(date, taiMinusUtc); - leapSeconds.splice(~leapSecondIndex, 0, leapSecond); - } - } - lastTaiMinusUtc = taiMinusUtc; - } + var t = IntersectionTests.rayTriangleParametric(ray, p0, p1, p2, cullBackFaces); + if (!defined(t) || t < 0.0 || t > Cartesian3.distance(v0, v1)) { + return undefined; } - } - function fillResultFromIndex(eop, samples, index, columnCount, result) { - var start = index * columnCount; - result.xPoleWander = samples[start + eop._xPoleWanderRadiansColumn]; - result.yPoleWander = samples[start + eop._yPoleWanderRadiansColumn]; - result.xPoleOffset = samples[start + eop._xCelestialPoleOffsetRadiansColumn]; - result.yPoleOffset = samples[start + eop._yCelestialPoleOffsetRadiansColumn]; - result.ut1MinusUtc = samples[start + eop._ut1MinusUtcSecondsColumn]; - } + if (!defined(result)) { + result = new Cartesian3(); + } - function linearInterp(dx, y1, y2) { - return y1 + dx * (y2 - y1); - } + Cartesian3.multiplyByScalar(ray.direction, t, result); + return Cartesian3.add(ray.origin, result, result); + }; - function interpolate(eop, dates, samples, date, before, after, result) { - var columnCount = eop._columnCount; + function solveQuadratic(a, b, c, result) { + var det = b * b - 4.0 * a * c; + if (det < 0.0) { + return undefined; + } else if (det > 0.0) { + var denom = 1.0 / (2.0 * a); + var disc = Math.sqrt(det); + var root0 = (-b + disc) * denom; + var root1 = (-b - disc) * denom; + + if (root0 < root1) { + result.root0 = root0; + result.root1 = root1; + } else { + result.root0 = root1; + result.root1 = root0; + } - // First check the bounds on the EOP data - // If we are after the bounds of the data, return zeros. - // The 'before' index should never be less than zero. - if (after > dates.length - 1) { - result.xPoleWander = 0; - result.yPoleWander = 0; - result.xPoleOffset = 0; - result.yPoleOffset = 0; - result.ut1MinusUtc = 0; return result; } - var beforeDate = dates[before]; - var afterDate = dates[after]; - if (beforeDate.equals(afterDate) || date.equals(beforeDate)) { - fillResultFromIndex(eop, samples, before, columnCount, result); - return result; - } else if (date.equals(afterDate)) { - fillResultFromIndex(eop, samples, after, columnCount, result); - return result; + var root = -b / (2.0 * a); + if (root === 0.0) { + return undefined; } - var factor = JulianDate.secondsDifference(date, beforeDate) / JulianDate.secondsDifference(afterDate, beforeDate); + result.root0 = result.root1 = root; + return result; + } - var startBefore = before * columnCount; - var startAfter = after * columnCount; + var raySphereRoots = { + root0 : 0.0, + root1 : 0.0 + }; - // Handle UT1 leap second edge case - var beforeUt1MinusUtc = samples[startBefore + eop._ut1MinusUtcSecondsColumn]; - var afterUt1MinusUtc = samples[startAfter + eop._ut1MinusUtcSecondsColumn]; + function raySphere(ray, sphere, result) { + if (!defined(result)) { + result = new Interval(); + } - var offsetDifference = afterUt1MinusUtc - beforeUt1MinusUtc; - if (offsetDifference > 0.5 || offsetDifference < -0.5) { - // The absolute difference between the values is more than 0.5, so we may have - // crossed a leap second. Check if this is the case and, if so, adjust the - // afterValue to account for the leap second. This way, our interpolation will - // produce reasonable results. - var beforeTaiMinusUtc = samples[startBefore + eop._taiMinusUtcSecondsColumn]; - var afterTaiMinusUtc = samples[startAfter + eop._taiMinusUtcSecondsColumn]; - if (beforeTaiMinusUtc !== afterTaiMinusUtc) { - if (afterDate.equals(date)) { - // If we are at the end of the leap second interval, take the second value - // Otherwise, the interpolation below will yield the wrong side of the - // discontinuity - // At the end of the leap second, we need to start accounting for the jump - beforeUt1MinusUtc = afterUt1MinusUtc; - } else { - // Otherwise, remove the leap second so that the interpolation is correct - afterUt1MinusUtc -= afterTaiMinusUtc - beforeTaiMinusUtc; - } - } + var origin = ray.origin; + var direction = ray.direction; + + var center = sphere.center; + var radiusSquared = sphere.radius * sphere.radius; + + var diff = Cartesian3.subtract(origin, center, scratchPVec); + + var a = Cartesian3.dot(direction, direction); + var b = 2.0 * Cartesian3.dot(direction, diff); + var c = Cartesian3.magnitudeSquared(diff) - radiusSquared; + + var roots = solveQuadratic(a, b, c, raySphereRoots); + if (!defined(roots)) { + return undefined; } - result.xPoleWander = linearInterp(factor, samples[startBefore + eop._xPoleWanderRadiansColumn], samples[startAfter + eop._xPoleWanderRadiansColumn]); - result.yPoleWander = linearInterp(factor, samples[startBefore + eop._yPoleWanderRadiansColumn], samples[startAfter + eop._yPoleWanderRadiansColumn]); - result.xPoleOffset = linearInterp(factor, samples[startBefore + eop._xCelestialPoleOffsetRadiansColumn], samples[startAfter + eop._xCelestialPoleOffsetRadiansColumn]); - result.yPoleOffset = linearInterp(factor, samples[startBefore + eop._yCelestialPoleOffsetRadiansColumn], samples[startAfter + eop._yCelestialPoleOffsetRadiansColumn]); - result.ut1MinusUtc = linearInterp(factor, beforeUt1MinusUtc, afterUt1MinusUtc); + result.start = roots.root0; + result.stop = roots.root1; return result; } - return EarthOrientationParameters; -}); + /** + * Computes the intersection points of a ray with a sphere. + * @memberof IntersectionTests + * + * @param {Ray} ray The ray. + * @param {BoundingSphere} sphere The sphere. + * @param {Interval} [result] The result onto which to store the result. + * @returns {Interval} The interval containing scalar points along the ray or undefined if there are no intersections. + */ + IntersectionTests.raySphere = function(ray, sphere, result) { + if (!defined(ray)) { + throw new DeveloperError('ray is required.'); + } + if (!defined(sphere)) { + throw new DeveloperError('sphere is required.'); + } + + result = raySphere(ray, sphere, result); + if (!defined(result) || result.stop < 0.0) { + return undefined; + } -define('Core/Iau2006XysSample',[],function() { - 'use strict'; + result.start = Math.max(result.start, 0.0); + return result; + }; + + var scratchLineSegmentRay = new Ray(); /** - * An IAU 2006 XYS value sampled at a particular time. - * - * @alias Iau2006XysSample - * @constructor - * - * @param {Number} x The X value. - * @param {Number} y The Y value. - * @param {Number} s The S value. + * Computes the intersection points of a line segment with a sphere. + * @memberof IntersectionTests * - * @private + * @param {Cartesian3} p0 An end point of the line segment. + * @param {Cartesian3} p1 The other end point of the line segment. + * @param {BoundingSphere} sphere The sphere. + * @param {Interval} [result] The result onto which to store the result. + * @returns {Interval} The interval containing scalar points along the ray or undefined if there are no intersections. */ - function Iau2006XysSample(x, y, s) { - /** - * The X value. - * @type {Number} - */ - this.x = x; + IntersectionTests.lineSegmentSphere = function(p0, p1, sphere, result) { + if (!defined(p0)) { + throw new DeveloperError('p0 is required.'); + } + if (!defined(p1)) { + throw new DeveloperError('p1 is required.'); + } + if (!defined(sphere)) { + throw new DeveloperError('sphere is required.'); + } + + var ray = scratchLineSegmentRay; + Cartesian3.clone(p0, ray.origin); + var direction = Cartesian3.subtract(p1, p0, ray.direction); - /** - * The Y value. - * @type {Number} - */ - this.y = y; + var maxT = Cartesian3.magnitude(direction); + Cartesian3.normalize(direction, direction); - /** - * The S value. - * @type {Number} - */ - this.s = s; - } + result = raySphere(ray, sphere, result); + if (!defined(result) || result.stop < 0.0 || result.start > maxT) { + return undefined; + } - return Iau2006XysSample; -}); + result.start = Math.max(result.start, 0.0); + result.stop = Math.min(result.stop, maxT); + return result; + }; -define('Core/Iau2006XysData',[ - '../ThirdParty/when', - './buildModuleUrl', - './defaultValue', - './defined', - './Iau2006XysSample', - './JulianDate', - './loadJson', - './TimeStandard' - ], function( - when, - buildModuleUrl, - defaultValue, - defined, - Iau2006XysSample, - JulianDate, - loadJson, - TimeStandard) { - 'use strict'; + var scratchQ = new Cartesian3(); + var scratchW = new Cartesian3(); /** - * A set of IAU2006 XYS data that is used to evaluate the transformation between the International - * Celestial Reference Frame (ICRF) and the International Terrestrial Reference Frame (ITRF). - * - * @alias Iau2006XysData - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, - * `{0}` will be replaced with the file index. - * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. - * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the - * first XYS sample. - * @param {Number} [options.stepSizeDays=1.0] The step size, in days, between successive XYS samples. - * @param {Number} [options.samplesPerXysFile=1000] The number of samples in each XYS file. - * @param {Number} [options.totalSamples=27426] The total number of samples in all XYS files. + * Computes the intersection points of a ray with an ellipsoid. * - * @private + * @param {Ray} ray The ray. + * @param {Ellipsoid} ellipsoid The ellipsoid. + * @returns {Interval} The interval containing scalar points along the ray or undefined if there are no intersections. */ - function Iau2006XysData(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._xysFileUrlTemplate = options.xysFileUrlTemplate; - this._interpolationOrder = defaultValue(options.interpolationOrder, 9); - this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); - this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); - this._stepSizeDays = defaultValue(options.stepSizeDays, 1.0); - this._samplesPerXysFile = defaultValue(options.samplesPerXysFile, 1000); - this._totalSamples = defaultValue(options.totalSamples, 27426); - this._samples = new Array(this._totalSamples * 3); - this._chunkDownloadsInProgress = []; + IntersectionTests.rayEllipsoid = function(ray, ellipsoid) { + if (!defined(ray)) { + throw new DeveloperError('ray is required.'); + } + if (!defined(ellipsoid)) { + throw new DeveloperError('ellipsoid is required.'); + } + + var inverseRadii = ellipsoid.oneOverRadii; + var q = Cartesian3.multiplyComponents(inverseRadii, ray.origin, scratchQ); + var w = Cartesian3.multiplyComponents(inverseRadii, ray.direction, scratchW); - var order = this._interpolationOrder; + var q2 = Cartesian3.magnitudeSquared(q); + var qw = Cartesian3.dot(q, w); - // Compute denominators and X values for interpolation. - var denom = this._denominators = new Array(order + 1); - var xTable = this._xTable = new Array(order + 1); + var difference, w2, product, discriminant, temp; - var stepN = Math.pow(this._stepSizeDays, order); + if (q2 > 1.0) { + // Outside ellipsoid. + if (qw >= 0.0) { + // Looking outward or tangent (0 intersections). + return undefined; + } - for ( var i = 0; i <= order; ++i) { - denom[i] = stepN; - xTable[i] = i * this._stepSizeDays; + // qw < 0.0. + var qw2 = qw * qw; + difference = q2 - 1.0; // Positively valued. + w2 = Cartesian3.magnitudeSquared(w); + product = w2 * difference; - for ( var j = 0; j <= order; ++j) { - if (j !== i) { - denom[i] *= (i - j); + if (qw2 < product) { + // Imaginary roots (0 intersections). + return undefined; + } else if (qw2 > product) { + // Distinct roots (2 intersections). + discriminant = qw * qw - product; + temp = -qw + Math.sqrt(discriminant); // Avoid cancellation. + var root0 = temp / w2; + var root1 = difference / temp; + if (root0 < root1) { + return new Interval(root0, root1); } + + return { + start : root1, + stop : root0 + }; } + // qw2 == product. Repeated roots (2 intersections). + var root = Math.sqrt(difference / w2); + return new Interval(root, root); + } else if (q2 < 1.0) { + // Inside ellipsoid (2 intersections). + difference = q2 - 1.0; // Negatively valued. + w2 = Cartesian3.magnitudeSquared(w); + product = w2 * difference; // Negatively valued. - denom[i] = 1.0 / denom[i]; + discriminant = qw * qw - product; + temp = -qw + Math.sqrt(discriminant); // Positively valued. + return new Interval(0.0, temp / w2); + } + // q2 == 1.0. On ellipsoid. + if (qw < 0.0) { + // Looking inward. + w2 = Cartesian3.magnitudeSquared(w); + return new Interval(0.0, -qw / w2); } - // Allocate scratch arrays for interpolation. - this._work = new Array(order + 1); - this._coef = new Array(order + 1); + // qw >= 0.0. Looking outward or tangent. + return undefined; + }; + + function addWithCancellationCheck(left, right, tolerance) { + var difference = left + right; + if ((CesiumMath.sign(left) !== CesiumMath.sign(right)) && + Math.abs(difference / Math.max(Math.abs(left), Math.abs(right))) < tolerance) { + return 0.0; + } + + return difference; } - var julianDateScratch = new JulianDate(0, 0.0, TimeStandard.TAI); + function quadraticVectorExpression(A, b, c, x, w) { + var xSquared = x * x; + var wSquared = w * w; - function getDaysSinceEpoch(xys, dayTT, secondTT) { - var dateTT = julianDateScratch; - dateTT.dayNumber = dayTT; - dateTT.secondsOfDay = secondTT; - return JulianDate.daysDifference(dateTT, xys._sampleZeroDateTT); + var l2 = (A[Matrix3.COLUMN1ROW1] - A[Matrix3.COLUMN2ROW2]) * wSquared; + var l1 = w * (x * addWithCancellationCheck(A[Matrix3.COLUMN1ROW0], A[Matrix3.COLUMN0ROW1], CesiumMath.EPSILON15) + b.y); + var l0 = (A[Matrix3.COLUMN0ROW0] * xSquared + A[Matrix3.COLUMN2ROW2] * wSquared) + x * b.x + c; + + var r1 = wSquared * addWithCancellationCheck(A[Matrix3.COLUMN2ROW1], A[Matrix3.COLUMN1ROW2], CesiumMath.EPSILON15); + var r0 = w * (x * addWithCancellationCheck(A[Matrix3.COLUMN2ROW0], A[Matrix3.COLUMN0ROW2]) + b.z); + + var cosines; + var solutions = []; + if (r0 === 0.0 && r1 === 0.0) { + cosines = QuadraticRealPolynomial.computeRealRoots(l2, l1, l0); + if (cosines.length === 0) { + return solutions; + } + + var cosine0 = cosines[0]; + var sine0 = Math.sqrt(Math.max(1.0 - cosine0 * cosine0, 0.0)); + solutions.push(new Cartesian3(x, w * cosine0, w * -sine0)); + solutions.push(new Cartesian3(x, w * cosine0, w * sine0)); + + if (cosines.length === 2) { + var cosine1 = cosines[1]; + var sine1 = Math.sqrt(Math.max(1.0 - cosine1 * cosine1, 0.0)); + solutions.push(new Cartesian3(x, w * cosine1, w * -sine1)); + solutions.push(new Cartesian3(x, w * cosine1, w * sine1)); + } + + return solutions; + } + + var r0Squared = r0 * r0; + var r1Squared = r1 * r1; + var l2Squared = l2 * l2; + var r0r1 = r0 * r1; + + var c4 = l2Squared + r1Squared; + var c3 = 2.0 * (l1 * l2 + r0r1); + var c2 = 2.0 * l0 * l2 + l1 * l1 - r1Squared + r0Squared; + var c1 = 2.0 * (l0 * l1 - r0r1); + var c0 = l0 * l0 - r0Squared; + + if (c4 === 0.0 && c3 === 0.0 && c2 === 0.0 && c1 === 0.0) { + return solutions; + } + + cosines = QuarticRealPolynomial.computeRealRoots(c4, c3, c2, c1, c0); + var length = cosines.length; + if (length === 0) { + return solutions; + } + + for ( var i = 0; i < length; ++i) { + var cosine = cosines[i]; + var cosineSquared = cosine * cosine; + var sineSquared = Math.max(1.0 - cosineSquared, 0.0); + var sine = Math.sqrt(sineSquared); + + //var left = l2 * cosineSquared + l1 * cosine + l0; + var left; + if (CesiumMath.sign(l2) === CesiumMath.sign(l0)) { + left = addWithCancellationCheck(l2 * cosineSquared + l0, l1 * cosine, CesiumMath.EPSILON12); + } else if (CesiumMath.sign(l0) === CesiumMath.sign(l1 * cosine)) { + left = addWithCancellationCheck(l2 * cosineSquared, l1 * cosine + l0, CesiumMath.EPSILON12); + } else { + left = addWithCancellationCheck(l2 * cosineSquared + l1 * cosine, l0, CesiumMath.EPSILON12); + } + + var right = addWithCancellationCheck(r1 * cosine, r0, CesiumMath.EPSILON15); + var product = left * right; + + if (product < 0.0) { + solutions.push(new Cartesian3(x, w * cosine, w * sine)); + } else if (product > 0.0) { + solutions.push(new Cartesian3(x, w * cosine, w * -sine)); + } else if (sine !== 0.0) { + solutions.push(new Cartesian3(x, w * cosine, w * -sine)); + solutions.push(new Cartesian3(x, w * cosine, w * sine)); + ++i; + } else { + solutions.push(new Cartesian3(x, w * cosine, w * sine)); + } + } + + return solutions; } + var firstAxisScratch = new Cartesian3(); + var secondAxisScratch = new Cartesian3(); + var thirdAxisScratch = new Cartesian3(); + var referenceScratch = new Cartesian3(); + var bCart = new Cartesian3(); + var bScratch = new Matrix3(); + var btScratch = new Matrix3(); + var diScratch = new Matrix3(); + var dScratch = new Matrix3(); + var cScratch = new Matrix3(); + var tempMatrix = new Matrix3(); + var aScratch = new Matrix3(); + var sScratch = new Cartesian3(); + var closestScratch = new Cartesian3(); + var surfPointScratch = new Cartographic(); + /** - * Preloads XYS data for a specified date range. + * Provides the point along the ray which is nearest to the ellipsoid. * - * @param {Number} startDayTT The Julian day number of the beginning of the interval to preload, expressed in - * the Terrestrial Time (TT) time standard. - * @param {Number} startSecondTT The seconds past noon of the beginning of the interval to preload, expressed in - * the Terrestrial Time (TT) time standard. - * @param {Number} stopDayTT The Julian day number of the end of the interval to preload, expressed in - * the Terrestrial Time (TT) time standard. - * @param {Number} stopSecondTT The seconds past noon of the end of the interval to preload, expressed in - * the Terrestrial Time (TT) time standard. - * @returns {Promise.<undefined>} A promise that, when resolved, indicates that the requested interval has been - * preloaded. + * @param {Ray} ray The ray. + * @param {Ellipsoid} ellipsoid The ellipsoid. + * @returns {Cartesian3} The nearest planetodetic point on the ray. */ - Iau2006XysData.prototype.preload = function(startDayTT, startSecondTT, stopDayTT, stopSecondTT) { - var startDaysSinceEpoch = getDaysSinceEpoch(this, startDayTT, startSecondTT); - var stopDaysSinceEpoch = getDaysSinceEpoch(this, stopDayTT, stopSecondTT); - - var startIndex = (startDaysSinceEpoch / this._stepSizeDays - this._interpolationOrder / 2) | 0; - if (startIndex < 0) { - startIndex = 0; + IntersectionTests.grazingAltitudeLocation = function(ray, ellipsoid) { + if (!defined(ray)) { + throw new DeveloperError('ray is required.'); + } + if (!defined(ellipsoid)) { + throw new DeveloperError('ellipsoid is required.'); } + + var position = ray.origin; + var direction = ray.direction; - var stopIndex = (stopDaysSinceEpoch / this._stepSizeDays - this._interpolationOrder / 2) | 0 + this._interpolationOrder; - if (stopIndex >= this._totalSamples) { - stopIndex = this._totalSamples - 1; + if (!Cartesian3.equals(position, Cartesian3.ZERO)) { + var normal = ellipsoid.geodeticSurfaceNormal(position, firstAxisScratch); + if (Cartesian3.dot(direction, normal) >= 0.0) { // The location provided is the closest point in altitude + return position; + } } - var startChunk = (startIndex / this._samplesPerXysFile) | 0; - var stopChunk = (stopIndex / this._samplesPerXysFile) | 0; + var intersects = defined(this.rayEllipsoid(ray, ellipsoid)); - var promises = []; - for ( var i = startChunk; i <= stopChunk; ++i) { - promises.push(requestXysChunk(this, i)); + // Compute the scaled direction vector. + var f = ellipsoid.transformPositionToScaledSpace(direction, firstAxisScratch); + + // Constructs a basis from the unit scaled direction vector. Construct its rotation and transpose. + var firstAxis = Cartesian3.normalize(f, f); + var reference = Cartesian3.mostOrthogonalAxis(f, referenceScratch); + var secondAxis = Cartesian3.normalize(Cartesian3.cross(reference, firstAxis, secondAxisScratch), secondAxisScratch); + var thirdAxis = Cartesian3.normalize(Cartesian3.cross(firstAxis, secondAxis, thirdAxisScratch), thirdAxisScratch); + var B = bScratch; + B[0] = firstAxis.x; + B[1] = firstAxis.y; + B[2] = firstAxis.z; + B[3] = secondAxis.x; + B[4] = secondAxis.y; + B[5] = secondAxis.z; + B[6] = thirdAxis.x; + B[7] = thirdAxis.y; + B[8] = thirdAxis.z; + + var B_T = Matrix3.transpose(B, btScratch); + + // Get the scaling matrix and its inverse. + var D_I = Matrix3.fromScale(ellipsoid.radii, diScratch); + var D = Matrix3.fromScale(ellipsoid.oneOverRadii, dScratch); + + var C = cScratch; + C[0] = 0.0; + C[1] = -direction.z; + C[2] = direction.y; + C[3] = direction.z; + C[4] = 0.0; + C[5] = -direction.x; + C[6] = -direction.y; + C[7] = direction.x; + C[8] = 0.0; + + var temp = Matrix3.multiply(Matrix3.multiply(B_T, D, tempMatrix), C, tempMatrix); + var A = Matrix3.multiply(Matrix3.multiply(temp, D_I, aScratch), B, aScratch); + var b = Matrix3.multiplyByVector(temp, position, bCart); + + // Solve for the solutions to the expression in standard form: + var solutions = quadraticVectorExpression(A, Cartesian3.negate(b, firstAxisScratch), 0.0, 0.0, 1.0); + + var s; + var altitude; + var length = solutions.length; + if (length > 0) { + var closest = Cartesian3.clone(Cartesian3.ZERO, closestScratch); + var maximumValue = Number.NEGATIVE_INFINITY; + + for ( var i = 0; i < length; ++i) { + s = Matrix3.multiplyByVector(D_I, Matrix3.multiplyByVector(B, solutions[i], sScratch), sScratch); + var v = Cartesian3.normalize(Cartesian3.subtract(s, position, referenceScratch), referenceScratch); + var dotProduct = Cartesian3.dot(v, direction); + + if (dotProduct > maximumValue) { + maximumValue = dotProduct; + closest = Cartesian3.clone(s, closest); + } + } + + var surfacePoint = ellipsoid.cartesianToCartographic(closest, surfPointScratch); + maximumValue = CesiumMath.clamp(maximumValue, 0.0, 1.0); + altitude = Cartesian3.magnitude(Cartesian3.subtract(closest, position, referenceScratch)) * Math.sqrt(1.0 - maximumValue * maximumValue); + altitude = intersects ? -altitude : altitude; + surfacePoint.height = altitude; + return ellipsoid.cartographicToCartesian(surfacePoint, new Cartesian3()); } - return when.all(promises); + return undefined; }; + var lineSegmentPlaneDifference = new Cartesian3(); + /** - * Computes the XYS values for a given date by interpolating. If the required data is not yet downloaded, - * this method will return undefined. + * Computes the intersection of a line segment and a plane. * - * @param {Number} dayTT The Julian day number for which to compute the XYS value, expressed in - * the Terrestrial Time (TT) time standard. - * @param {Number} secondTT The seconds past noon of the date for which to compute the XYS value, expressed in - * the Terrestrial Time (TT) time standard. - * @param {Iau2006XysSample} [result] The instance to which to copy the interpolated result. If this parameter - * is undefined, a new instance is allocated and returned. - * @returns {Iau2006XysSample} The interpolated XYS values, or undefined if the required data for this - * computation has not yet been downloaded. + * @param {Cartesian3} endPoint0 An end point of the line segment. + * @param {Cartesian3} endPoint1 The other end point of the line segment. + * @param {Plane} plane The plane. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The intersection point or undefined if there is no intersection. * - * @see Iau2006XysData#preload + * @example + * var origin = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); + * var normal = ellipsoid.geodeticSurfaceNormal(origin); + * var plane = Cesium.Plane.fromPointNormal(origin, normal); + * + * var p0 = new Cesium.Cartesian3(...); + * var p1 = new Cesium.Cartesian3(...); + * + * // find the intersection of the line segment from p0 to p1 and the tangent plane at origin. + * var intersection = Cesium.IntersectionTests.lineSegmentPlane(p0, p1, plane); */ - Iau2006XysData.prototype.computeXysRadians = function(dayTT, secondTT, result) { - var daysSinceEpoch = getDaysSinceEpoch(this, dayTT, secondTT); - if (daysSinceEpoch < 0.0) { - // Can't evaluate prior to the epoch of the data. - return undefined; + IntersectionTests.lineSegmentPlane = function(endPoint0, endPoint1, plane, result) { + if (!defined(endPoint0)) { + throw new DeveloperError('endPoint0 is required.'); } - - var centerIndex = (daysSinceEpoch / this._stepSizeDays) | 0; - if (centerIndex >= this._totalSamples) { - // Can't evaluate after the last sample in the data. - return undefined; + if (!defined(endPoint1)) { + throw new DeveloperError('endPoint1 is required.'); } - - var degree = this._interpolationOrder; - - var firstIndex = centerIndex - ((degree / 2) | 0); - if (firstIndex < 0) { - firstIndex = 0; + if (!defined(plane)) { + throw new DeveloperError('plane is required.'); } - var lastIndex = firstIndex + degree; - if (lastIndex >= this._totalSamples) { - lastIndex = this._totalSamples - 1; - firstIndex = lastIndex - degree; - if (firstIndex < 0) { - firstIndex = 0; - } + + if (!defined(result)) { + result = new Cartesian3(); } - // Are all the samples we need present? - // We can assume so if the first and last are present - var isDataMissing = false; - var samples = this._samples; - if (!defined(samples[firstIndex * 3])) { - requestXysChunk(this, (firstIndex / this._samplesPerXysFile) | 0); - isDataMissing = true; - } + var difference = Cartesian3.subtract(endPoint1, endPoint0, lineSegmentPlaneDifference); + var normal = plane.normal; + var nDotDiff = Cartesian3.dot(normal, difference); - if (!defined(samples[lastIndex * 3])) { - requestXysChunk(this, (lastIndex / this._samplesPerXysFile) | 0); - isDataMissing = true; + // check if the segment and plane are parallel + if (Math.abs(nDotDiff) < CesiumMath.EPSILON6) { + return undefined; } - if (isDataMissing) { + var nDotP0 = Cartesian3.dot(normal, endPoint0); + var t = -(plane.distance + nDotP0) / nDotDiff; + + // intersection only if t is in [0, 1] + if (t < 0.0 || t > 1.0) { return undefined; } - if (!defined(result)) { - result = new Iau2006XysSample(0.0, 0.0, 0.0); - } else { - result.x = 0.0; - result.y = 0.0; - result.s = 0.0; - } + // intersection is endPoint0 + t * (endPoint1 - endPoint0) + Cartesian3.multiplyByScalar(difference, t, result); + Cartesian3.add(endPoint0, result, result); + return result; + }; - var x = daysSinceEpoch - firstIndex * this._stepSizeDays; + /** + * Computes the intersection of a triangle and a plane + * + * @param {Cartesian3} p0 First point of the triangle + * @param {Cartesian3} p1 Second point of the triangle + * @param {Cartesian3} p2 Third point of the triangle + * @param {Plane} plane Intersection plane + * @returns {Object} An object with properties <code>positions</code> and <code>indices</code>, which are arrays that represent three triangles that do not cross the plane. (Undefined if no intersection exists) + * + * @example + * var origin = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); + * var normal = ellipsoid.geodeticSurfaceNormal(origin); + * var plane = Cesium.Plane.fromPointNormal(origin, normal); + * + * var p0 = new Cesium.Cartesian3(...); + * var p1 = new Cesium.Cartesian3(...); + * var p2 = new Cesium.Cartesian3(...); + * + * // convert the triangle composed of points (p0, p1, p2) to three triangles that don't cross the plane + * var triangles = Cesium.IntersectionTests.trianglePlaneIntersection(p0, p1, p2, plane); + */ + IntersectionTests.trianglePlaneIntersection = function(p0, p1, p2, plane) { + if ((!defined(p0)) || + (!defined(p1)) || + (!defined(p2)) || + (!defined(plane))) { + throw new DeveloperError('p0, p1, p2, and plane are required.'); + } + + var planeNormal = plane.normal; + var planeD = plane.distance; + var p0Behind = (Cartesian3.dot(planeNormal, p0) + planeD) < 0.0; + var p1Behind = (Cartesian3.dot(planeNormal, p1) + planeD) < 0.0; + var p2Behind = (Cartesian3.dot(planeNormal, p2) + planeD) < 0.0; + // Given these dots products, the calls to lineSegmentPlaneIntersection + // always have defined results. - var work = this._work; - var denom = this._denominators; - var coef = this._coef; - var xTable = this._xTable; + var numBehind = 0; + numBehind += p0Behind ? 1 : 0; + numBehind += p1Behind ? 1 : 0; + numBehind += p2Behind ? 1 : 0; - var i, j; - for (i = 0; i <= degree; ++i) { - work[i] = x - xTable[i]; + var u1, u2; + if (numBehind === 1 || numBehind === 2) { + u1 = new Cartesian3(); + u2 = new Cartesian3(); } - for (i = 0; i <= degree; ++i) { - coef[i] = 1.0; + if (numBehind === 1) { + if (p0Behind) { + IntersectionTests.lineSegmentPlane(p0, p1, plane, u1); + IntersectionTests.lineSegmentPlane(p0, p2, plane, u2); - for (j = 0; j <= degree; ++j) { - if (j !== i) { - coef[i] *= work[j]; - } - } + return { + positions : [p0, p1, p2, u1, u2 ], + indices : [ + // Behind + 0, 3, 4, - coef[i] *= denom[i]; + // In front + 1, 2, 4, + 1, 4, 3 + ] + }; + } else if (p1Behind) { + IntersectionTests.lineSegmentPlane(p1, p2, plane, u1); + IntersectionTests.lineSegmentPlane(p1, p0, plane, u2); - var sampleIndex = (firstIndex + i) * 3; - result.x += coef[i] * samples[sampleIndex++]; - result.y += coef[i] * samples[sampleIndex++]; - result.s += coef[i] * samples[sampleIndex]; - } + return { + positions : [p0, p1, p2, u1, u2 ], + indices : [ + // Behind + 1, 3, 4, - return result; - }; + // In front + 2, 0, 4, + 2, 4, 3 + ] + }; + } else if (p2Behind) { + IntersectionTests.lineSegmentPlane(p2, p0, plane, u1); + IntersectionTests.lineSegmentPlane(p2, p1, plane, u2); - function requestXysChunk(xysData, chunkIndex) { - if (xysData._chunkDownloadsInProgress[chunkIndex]) { - // Chunk has already been requested. - return xysData._chunkDownloadsInProgress[chunkIndex]; - } + return { + positions : [p0, p1, p2, u1, u2 ], + indices : [ + // Behind + 2, 3, 4, - var deferred = when.defer(); + // In front + 0, 1, 4, + 0, 4, 3 + ] + }; + } + } else if (numBehind === 2) { + if (!p0Behind) { + IntersectionTests.lineSegmentPlane(p1, p0, plane, u1); + IntersectionTests.lineSegmentPlane(p2, p0, plane, u2); - xysData._chunkDownloadsInProgress[chunkIndex] = deferred; + return { + positions : [p0, p1, p2, u1, u2 ], + indices : [ + // Behind + 1, 2, 4, + 1, 4, 3, - var chunkUrl; - var xysFileUrlTemplate = xysData._xysFileUrlTemplate; - if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); - } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); - } + // In front + 0, 3, 4 + ] + }; + } else if (!p1Behind) { + IntersectionTests.lineSegmentPlane(p2, p1, plane, u1); + IntersectionTests.lineSegmentPlane(p0, p1, plane, u2); - when(loadJson(chunkUrl), function(chunk) { - xysData._chunkDownloadsInProgress[chunkIndex] = false; + return { + positions : [p0, p1, p2, u1, u2 ], + indices : [ + // Behind + 2, 0, 4, + 2, 4, 3, - var samples = xysData._samples; - var newSamples = chunk.samples; - var startIndex = chunkIndex * xysData._samplesPerXysFile * 3; + // In front + 1, 3, 4 + ] + }; + } else if (!p2Behind) { + IntersectionTests.lineSegmentPlane(p0, p2, plane, u1); + IntersectionTests.lineSegmentPlane(p1, p2, plane, u2); - for ( var i = 0, len = newSamples.length; i < len; ++i) { - samples[startIndex + i] = newSamples[i]; - } + return { + positions : [p0, p1, p2, u1, u2 ], + indices : [ + // Behind + 0, 1, 4, + 0, 4, 3, - deferred.resolve(); - }); + // In front + 2, 3, 4 + ] + }; + } + } - return deferred.promise; - } + // if numBehind is 3, the triangle is completely behind the plane; + // otherwise, it is completely in front (numBehind is 0). + return undefined; + }; - return Iau2006XysData; + return IntersectionTests; }); -define('Core/Quaternion',[ +define('Core/Plane',[ './Cartesian3', './Check', - './defaultValue', './defined', - './FeatureDetection', + './DeveloperError', './freezeObject', './Math', - './Matrix3' + './Matrix4' ], function( Cartesian3, Check, - defaultValue, defined, - FeatureDetection, + DeveloperError, freezeObject, CesiumMath, - Matrix3) { + Matrix4) { 'use strict'; /** - * A set of 4-dimensional coordinates used to represent rotation in 3-dimensional space. - * @alias Quaternion + * A plane in Hessian Normal Form defined by + * <pre> + * ax + by + cz + d = 0 + * </pre> + * where (a, b, c) is the plane's <code>normal</code>, d is the signed + * <code>distance</code> to the plane, and (x, y, z) is any point on + * the plane. + * + * @alias Plane * @constructor * - * @param {Number} [x=0.0] The X component. - * @param {Number} [y=0.0] The Y component. - * @param {Number} [z=0.0] The Z component. - * @param {Number} [w=0.0] The W component. + * @param {Cartesian3} normal The plane's normal (normalized). + * @param {Number} distance The shortest distance from the origin to the plane. The sign of + * <code>distance</code> determines which side of the plane the origin + * is on. If <code>distance</code> is positive, the origin is in the half-space + * in the direction of the normal; if negative, the origin is in the half-space + * opposite to the normal; if zero, the plane passes through the origin. * - * @see PackableForInterpolation + * @example + * // The plane x=0 + * var plane = new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0); + * + * @exception {DeveloperError} Normal must be normalized */ - function Quaternion(x, y, z, w) { - /** - * The X component. - * @type {Number} - * @default 0.0 - */ - this.x = defaultValue(x, 0.0); - - /** - * The Y component. - * @type {Number} - * @default 0.0 - */ - this.y = defaultValue(y, 0.0); - + function Plane(normal, distance) { + Check.typeOf.object('normal', normal); + if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { + throw new DeveloperError('normal must be normalized.'); + } + Check.typeOf.number('distance', distance); + /** - * The Z component. - * @type {Number} - * @default 0.0 + * The plane's normal. + * + * @type {Cartesian3} */ - this.z = defaultValue(z, 0.0); + this.normal = Cartesian3.clone(normal); /** - * The W component. + * The shortest distance from the origin to the plane. The sign of + * <code>distance</code> determines which side of the plane the origin + * is on. If <code>distance</code> is positive, the origin is in the half-space + * in the direction of the normal; if negative, the origin is in the half-space + * opposite to the normal; if zero, the plane passes through the origin. + * * @type {Number} - * @default 0.0 */ - this.w = defaultValue(w, 0.0); + this.distance = distance; } - var fromAxisAngleScratch = new Cartesian3(); - /** - * Computes a quaternion representing a rotation around an axis. + * Creates a plane from a normal and a point on the plane. * - * @param {Cartesian3} axis The axis of rotation. - * @param {Number} angle The angle in radians to rotate around the axis. - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + * @param {Cartesian3} point The point on the plane. + * @param {Cartesian3} normal The plane's normal (normalized). + * @param {Plane} [result] The object onto which to store the result. + * @returns {Plane} A new plane instance or the modified result parameter. + * + * @example + * var point = Cesium.Cartesian3.fromDegrees(-72.0, 40.0); + * var normal = ellipsoid.geodeticSurfaceNormal(point); + * var tangentPlane = Cesium.Plane.fromPointNormal(point, normal); + * + * @exception {DeveloperError} Normal must be normalized */ - Quaternion.fromAxisAngle = function(axis, angle, result) { - Check.typeOf.object('axis', axis); - Check.typeOf.number('angle', angle); + Plane.fromPointNormal = function(point, normal, result) { + Check.typeOf.object('point', point); + Check.typeOf.object('normal', normal); + if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { + throw new DeveloperError('normal must be normalized.'); + } - var halfAngle = angle / 2.0; - var s = Math.sin(halfAngle); - fromAxisAngleScratch = Cartesian3.normalize(axis, fromAxisAngleScratch); + var distance = -Cartesian3.dot(normal, point); - var x = fromAxisAngleScratch.x * s; - var y = fromAxisAngleScratch.y * s; - var z = fromAxisAngleScratch.z * s; - var w = Math.cos(halfAngle); if (!defined(result)) { - return new Quaternion(x, y, z, w); + return new Plane(normal, distance); } - result.x = x; - result.y = y; - result.z = z; - result.w = w; + + Cartesian3.clone(normal, result.normal); + result.distance = distance; return result; }; - var fromRotationMatrixNext = [1, 2, 0]; - var fromRotationMatrixQuat = new Array(3); + var scratchNormal = new Cartesian3(); /** - * Computes a Quaternion from the provided Matrix3 instance. - * - * @param {Matrix3} matrix The rotation matrix. - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + * Creates a plane from the general equation * - * @see Matrix3.fromQuaternion + * @param {Cartesian4} coefficients The plane's normal (normalized). + * @param {Plane} [result] The object onto which to store the result. + * @returns {Plane} A new plane instance or the modified result parameter. + * + * @exception {DeveloperError} Normal must be normalized */ - Quaternion.fromRotationMatrix = function(matrix, result) { - Check.typeOf.object('matrix', matrix); + Plane.fromCartesian4 = function(coefficients, result) { + Check.typeOf.object('coefficients', coefficients); - var root; - var x; - var y; - var z; - var w; - - var m00 = matrix[Matrix3.COLUMN0ROW0]; - var m11 = matrix[Matrix3.COLUMN1ROW1]; - var m22 = matrix[Matrix3.COLUMN2ROW2]; - var trace = m00 + m11 + m22; - - if (trace > 0.0) { - // |w| > 1/2, may as well choose w > 1/2 - root = Math.sqrt(trace + 1.0); // 2w - w = 0.5 * root; - root = 0.5 / root; // 1/(4w) - - x = (matrix[Matrix3.COLUMN1ROW2] - matrix[Matrix3.COLUMN2ROW1]) * root; - y = (matrix[Matrix3.COLUMN2ROW0] - matrix[Matrix3.COLUMN0ROW2]) * root; - z = (matrix[Matrix3.COLUMN0ROW1] - matrix[Matrix3.COLUMN1ROW0]) * root; - } else { - // |w| <= 1/2 - var next = fromRotationMatrixNext; - - var i = 0; - if (m11 > m00) { - i = 1; - } - if (m22 > m00 && m22 > m11) { - i = 2; - } - var j = next[i]; - var k = next[j]; - - root = Math.sqrt(matrix[Matrix3.getElementIndex(i, i)] - matrix[Matrix3.getElementIndex(j, j)] - matrix[Matrix3.getElementIndex(k, k)] + 1.0); - - var quat = fromRotationMatrixQuat; - quat[i] = 0.5 * root; - root = 0.5 / root; - w = (matrix[Matrix3.getElementIndex(k, j)] - matrix[Matrix3.getElementIndex(j, k)]) * root; - quat[j] = (matrix[Matrix3.getElementIndex(j, i)] + matrix[Matrix3.getElementIndex(i, j)]) * root; - quat[k] = (matrix[Matrix3.getElementIndex(k, i)] + matrix[Matrix3.getElementIndex(i, k)]) * root; + var normal = Cartesian3.fromCartesian4(coefficients, scratchNormal); + var distance = coefficients.w; - x = -quat[0]; - y = -quat[1]; - z = -quat[2]; + if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { + throw new DeveloperError('normal must be normalized.'); } - + if (!defined(result)) { - return new Quaternion(x, y, z, w); + return new Plane(normal, distance); } - result.x = x; - result.y = y; - result.z = z; - result.w = w; + Cartesian3.clone(normal, result.normal); + result.distance = distance; return result; }; - var scratchHPRQuaternion = new Quaternion(); - var scratchHeadingQuaternion = new Quaternion(); - var scratchPitchQuaternion = new Quaternion(); - var scratchRollQuaternion = new Quaternion(); - - /** - * Computes a rotation from the given heading, pitch and roll angles. Heading is the rotation about the - * negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about - * the positive x axis. - * - * @param {HeadingPitchRoll} headingPitchRoll The rotation expressed as a heading, pitch and roll. - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if none was provided. - */ - Quaternion.fromHeadingPitchRoll = function(headingPitchRoll, result) { - Check.typeOf.object('headingPitchRoll', headingPitchRoll); - - scratchRollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, headingPitchRoll.roll, scratchHPRQuaternion); - scratchPitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -headingPitchRoll.pitch, result); - result = Quaternion.multiply(scratchPitchQuaternion, scratchRollQuaternion, scratchPitchQuaternion); - scratchHeadingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -headingPitchRoll.heading, scratchHPRQuaternion); - return Quaternion.multiply(scratchHeadingQuaternion, result, result); - }; - - var sampledQuaternionAxis = new Cartesian3(); - var sampledQuaternionRotation = new Cartesian3(); - var sampledQuaternionTempQuaternion = new Quaternion(); - var sampledQuaternionQuaternion0 = new Quaternion(); - var sampledQuaternionQuaternion0Conjugate = new Quaternion(); - - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - Quaternion.packedLength = 4; - /** - * Stores the provided instance into the provided array. - * - * @param {Quaternion} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * Computes the signed shortest distance of a point to a plane. + * The sign of the distance determines which side of the plane the point + * is on. If the distance is positive, the point is in the half-space + * in the direction of the normal; if negative, the point is in the half-space + * opposite to the normal; if zero, the plane passes through the point. * - * @returns {Number[]} The array that was packed into + * @param {Plane} plane The plane. + * @param {Cartesian3} point The point. + * @returns {Number} The signed shortest distance of the point to the plane. */ - Quaternion.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + Plane.getPointDistance = function(plane, point) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); - startingIndex = defaultValue(startingIndex, 0); - - array[startingIndex++] = value.x; - array[startingIndex++] = value.y; - array[startingIndex++] = value.z; - array[startingIndex] = value.w; - - return array; + return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Quaternion} [result] The object into which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. */ - Quaternion.unpack = function(array, startingIndex, result) { - Check.defined('array', array); + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); - startingIndex = defaultValue(startingIndex, 0); - if (!defined(result)) { - result = new Quaternion(); + result = new Cartesian3(); } - result.x = array[startingIndex]; - result.y = array[startingIndex + 1]; - result.z = array[startingIndex + 2]; - result.w = array[startingIndex + 3]; - return result; - }; - - /** - * The number of elements used to store the object into an array in its interpolatable form. - * @type {Number} - */ - Quaternion.packedInterpolationLength = 3; - - /** - * Converts a packed array into a form suitable for interpolation. - * - * @param {Number[]} packedArray The packed array. - * @param {Number} [startingIndex=0] The index of the first element to be converted. - * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. - * @param {Number[]} result The object into which to store the result. - */ - Quaternion.convertPackedArrayForInterpolation = function(packedArray, startingIndex, lastIndex, result) { - Quaternion.unpack(packedArray, lastIndex * 4, sampledQuaternionQuaternion0Conjugate); - Quaternion.conjugate(sampledQuaternionQuaternion0Conjugate, sampledQuaternionQuaternion0Conjugate); - - for (var i = 0, len = lastIndex - startingIndex + 1; i < len; i++) { - var offset = i * 3; - Quaternion.unpack(packedArray, (startingIndex + i) * 4, sampledQuaternionTempQuaternion); - - Quaternion.multiply(sampledQuaternionTempQuaternion, sampledQuaternionQuaternion0Conjugate, sampledQuaternionTempQuaternion); - if (sampledQuaternionTempQuaternion.w < 0) { - Quaternion.negate(sampledQuaternionTempQuaternion, sampledQuaternionTempQuaternion); - } + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); - Quaternion.computeAxis(sampledQuaternionTempQuaternion, sampledQuaternionAxis); - var angle = Quaternion.computeAngle(sampledQuaternionTempQuaternion); - result[offset] = sampledQuaternionAxis.x * angle; - result[offset + 1] = sampledQuaternionAxis.y * angle; - result[offset + 2] = sampledQuaternionAxis.z * angle; - } + return Cartesian3.subtract(point, scaledNormal, result); }; + var scratchPosition = new Cartesian3(); /** - * Retrieves an instance from a packed array converted with {@link convertPackedArrayForInterpolation}. + * Transforms the plane by the given transformation matrix. * - * @param {Number[]} array The array previously packed for interpolation. - * @param {Number[]} sourceArray The original packed array. - * @param {Number} [firstIndex=0] The firstIndex used to convert the array. - * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. - * @param {Quaternion} [result] The object into which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + * @param {Plane} plane The plane. + * @param {Matrix4} transform The transformation matrix. + * @param {Plane} [result] The object into which to store the result. + * @returns {Plane} The plane transformed by the given transformation matrix. */ - Quaternion.unpackInterpolationResult = function(array, sourceArray, firstIndex, lastIndex, result) { - if (!defined(result)) { - result = new Quaternion(); - } - Cartesian3.fromArray(array, 0, sampledQuaternionRotation); - var magnitude = Cartesian3.magnitude(sampledQuaternionRotation); - - Quaternion.unpack(sourceArray, lastIndex * 4, sampledQuaternionQuaternion0); + Plane.transform = function(plane, transform, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('transform', transform); + + Matrix4.multiplyByPointAsVector(transform, plane.normal, scratchNormal); + Cartesian3.normalize(scratchNormal, scratchNormal); - if (magnitude === 0) { - Quaternion.clone(Quaternion.IDENTITY, sampledQuaternionTempQuaternion); - } else { - Quaternion.fromAxisAngle(sampledQuaternionRotation, magnitude, sampledQuaternionTempQuaternion); - } + Cartesian3.multiplyByScalar(plane.normal, -plane.distance, scratchPosition); + Matrix4.multiplyByPoint(transform, scratchPosition, scratchPosition); - return Quaternion.multiply(sampledQuaternionTempQuaternion, sampledQuaternionQuaternion0, result); + return Plane.fromPointNormal(scratchPosition, scratchNormal, result); }; /** - * Duplicates a Quaternion instance. + * Duplicates a Plane instance. * - * @param {Quaternion} quaternion The quaternion to duplicate. - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. (Returns undefined if quaternion is undefined) + * @param {Plane} plane The plane to duplicate. + * @param {Plane} [result] The object onto which to store the result. + * @returns {Plane} The modified result parameter or a new Plane instance if one was not provided. */ - Quaternion.clone = function(quaternion, result) { - if (!defined(quaternion)) { - return undefined; - } - + Plane.clone = function(plane, result) { + Check.typeOf.object('plane', plane); + if (!defined(result)) { - return new Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w); + return new Plane(plane.normal, plane.distance); } - result.x = quaternion.x; - result.y = quaternion.y; - result.z = quaternion.z; - result.w = quaternion.w; - return result; - }; + Cartesian3.clone(plane.normal, result.normal); + result.distance = plane.distance; - /** - * Computes the conjugate of the provided quaternion. - * - * @param {Quaternion} quaternion The quaternion to conjugate. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.conjugate = function(quaternion, result) { - Check.typeOf.object('quaternion', quaternion); - Check.typeOf.object('result', result); - - result.x = -quaternion.x; - result.y = -quaternion.y; - result.z = -quaternion.z; - result.w = quaternion.w; return result; }; /** - * Computes magnitude squared for the provided quaternion. + * Compares the provided Planes by normal and distance and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {Quaternion} quaternion The quaternion to conjugate. - * @returns {Number} The magnitude squared. + * @param {Plane} left The first plane. + * @param {Plane} right The second plane. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - Quaternion.magnitudeSquared = function(quaternion) { - Check.typeOf.object('quaternion', quaternion); + Plane.equals = function(left, right) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); - return quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z * quaternion.z + quaternion.w * quaternion.w; + return (left.distance === right.distance) && Cartesian3.equals(left.normal, right.normal); }; /** - * Computes magnitude for the provided quaternion. + * A constant initialized to the XY plane passing through the origin, with normal in positive Z. * - * @param {Quaternion} quaternion The quaternion to conjugate. - * @returns {Number} The magnitude. + * @type {Plane} + * @constant */ - Quaternion.magnitude = function(quaternion) { - return Math.sqrt(Quaternion.magnitudeSquared(quaternion)); - }; + Plane.ORIGIN_XY_PLANE = freezeObject(new Plane(Cartesian3.UNIT_Z, 0.0)); /** - * Computes the normalized form of the provided quaternion. + * A constant initialized to the YZ plane passing through the origin, with normal in positive X. * - * @param {Quaternion} quaternion The quaternion to normalize. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. + * @type {Plane} + * @constant */ - Quaternion.normalize = function(quaternion, result) { - Check.typeOf.object('result', result); - - var inverseMagnitude = 1.0 / Quaternion.magnitude(quaternion); - var x = quaternion.x * inverseMagnitude; - var y = quaternion.y * inverseMagnitude; - var z = quaternion.z * inverseMagnitude; - var w = quaternion.w * inverseMagnitude; - - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; - }; + Plane.ORIGIN_YZ_PLANE = freezeObject(new Plane(Cartesian3.UNIT_X, 0.0)); /** - * Computes the inverse of the provided quaternion. + * A constant initialized to the ZX plane passing through the origin, with normal in positive Y. * - * @param {Quaternion} quaternion The quaternion to normalize. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. + * @type {Plane} + * @constant */ - Quaternion.inverse = function(quaternion, result) { - Check.typeOf.object('result', result); - - var magnitudeSquared = Quaternion.magnitudeSquared(quaternion); - result = Quaternion.conjugate(quaternion, result); - return Quaternion.multiplyByScalar(result, 1.0 / magnitudeSquared, result); - }; + Plane.ORIGIN_ZX_PLANE = freezeObject(new Plane(Cartesian3.UNIT_Y, 0.0)); - /** - * Computes the componentwise sum of two quaternions. - * - * @param {Quaternion} left The first quaternion. - * @param {Quaternion} right The second quaternion. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.add = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.x = left.x + right.x; - result.y = left.y + right.y; - result.z = left.z + right.z; - result.w = left.w + right.w; - return result; - }; + return Plane; +}); - /** - * Computes the componentwise difference of two quaternions. - * - * @param {Quaternion} left The first quaternion. - * @param {Quaternion} right The second quaternion. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.subtract = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.x = left.x - right.x; - result.y = left.y - right.y; - result.z = left.z - right.z; - result.w = left.w - right.w; - return result; - }; +define('Core/EarthOrientationParametersSample',[],function() { + 'use strict'; /** - * Negates the provided quaternion. + * A set of Earth Orientation Parameters (EOP) sampled at a time. * - * @param {Quaternion} quaternion The quaternion to be negated. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.negate = function(quaternion, result) { - Check.typeOf.object('quaternion', quaternion); - Check.typeOf.object('result', result); - - result.x = -quaternion.x; - result.y = -quaternion.y; - result.z = -quaternion.z; - result.w = -quaternion.w; - return result; - }; - - /** - * Computes the dot (scalar) product of two quaternions. + * @alias EarthOrientationParametersSample + * @constructor * - * @param {Quaternion} left The first quaternion. - * @param {Quaternion} right The second quaternion. - * @returns {Number} The dot product. - */ - Quaternion.dot = function(left, right) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - - return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; - }; - - /** - * Computes the product of two quaternions. + * @param {Number} xPoleWander The pole wander about the X axis, in radians. + * @param {Number} yPoleWander The pole wander about the Y axis, in radians. + * @param {Number} xPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. + * @param {Number} yPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. + * @param {Number} ut1MinusUtc The difference in time standards, UT1 - UTC, in seconds. * - * @param {Quaternion} left The first quaternion. - * @param {Quaternion} right The second quaternion. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. + * @private */ - Quaternion.multiply = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - var leftX = left.x; - var leftY = left.y; - var leftZ = left.z; - var leftW = left.w; - - var rightX = right.x; - var rightY = right.y; - var rightZ = right.z; - var rightW = right.w; + function EarthOrientationParametersSample(xPoleWander, yPoleWander, xPoleOffset, yPoleOffset, ut1MinusUtc) { + /** + * The pole wander about the X axis, in radians. + * @type {Number} + */ + this.xPoleWander = xPoleWander; - var x = leftW * rightX + leftX * rightW + leftY * rightZ - leftZ * rightY; - var y = leftW * rightY - leftX * rightZ + leftY * rightW + leftZ * rightX; - var z = leftW * rightZ + leftX * rightY - leftY * rightX + leftZ * rightW; - var w = leftW * rightW - leftX * rightX - leftY * rightY - leftZ * rightZ; + /** + * The pole wander about the Y axis, in radians. + * @type {Number} + */ + this.yPoleWander = yPoleWander; - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; - }; + /** + * The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. + * @type {Number} + */ + this.xPoleOffset = xPoleOffset; - /** - * Multiplies the provided quaternion componentwise by the provided scalar. - * - * @param {Quaternion} quaternion The quaternion to be scaled. - * @param {Number} scalar The scalar to multiply with. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.multiplyByScalar = function(quaternion, scalar, result) { - Check.typeOf.object('quaternion', quaternion); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result.x = quaternion.x * scalar; - result.y = quaternion.y * scalar; - result.z = quaternion.z * scalar; - result.w = quaternion.w * scalar; - return result; - }; + /** + * The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. + * @type {Number} + */ + this.yPoleOffset = yPoleOffset; - /** - * Divides the provided quaternion componentwise by the provided scalar. - * - * @param {Quaternion} quaternion The quaternion to be divided. - * @param {Number} scalar The scalar to divide by. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.divideByScalar = function(quaternion, scalar, result) { - Check.typeOf.object('quaternion', quaternion); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result.x = quaternion.x / scalar; - result.y = quaternion.y / scalar; - result.z = quaternion.z / scalar; - result.w = quaternion.w / scalar; - return result; - }; + /** + * The difference in time standards, UT1 - UTC, in seconds. + * @type {Number} + */ + this.ut1MinusUtc = ut1MinusUtc; + } - /** - * Computes the axis of rotation of the provided quaternion. - * - * @param {Quaternion} quaternion The quaternion to use. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. - */ - Quaternion.computeAxis = function(quaternion, result) { - Check.typeOf.object('quaternion', quaternion); - Check.typeOf.object('result', result); - - var w = quaternion.w; - if (Math.abs(w - 1.0) < CesiumMath.EPSILON6) { - result.x = result.y = result.z = 0; - return result; - } + return EarthOrientationParametersSample; +}); - var scalar = 1.0 / Math.sqrt(1.0 - (w * w)); +/** +@license +sprintf.js from the php.js project - https://github.com/kvz/phpjs +Directly from https://github.com/kvz/phpjs/blob/master/functions/strings/sprintf.js - result.x = quaternion.x * scalar; - result.y = quaternion.y * scalar; - result.z = quaternion.z * scalar; - return result; - }; +php.js is copyright 2012 Kevin van Zonneveld. - /** - * Computes the angle of rotation of the provided quaternion. - * - * @param {Quaternion} quaternion The quaternion to use. - * @returns {Number} The angle of rotation. - */ - Quaternion.computeAngle = function(quaternion) { - Check.typeOf.object('quaternion', quaternion); - - if (Math.abs(quaternion.w - 1.0) < CesiumMath.EPSILON6) { - return 0.0; - } - return 2.0 * Math.acos(quaternion.w); - }; +Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld +(http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White +(http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jack, Jonas +Raoni Soares Silva (http://www.jsfromhell.com), Philip Peterson, Legaev +Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous, Martijn Wieringa, +Rafa? Kukawski (http://blog.kukawski.pl), lmeyrick +(https://sourceforge.net/projects/bcmath-js/), Nate, Philippe Baumann, +Enrique Gonzalez, Webtoolkit.info (http://www.webtoolkit.info/), Carlos R. +L. Rodrigues (http://www.jsfromhell.com), Ash Searle +(http://hexmen.com/blog/), Jani Hartikainen, travc, Ole Vrijenhoek, +Erkekjetter, Michael Grier, Rafa? Kukawski (http://kukawski.pl), Johnny +Mast (http://www.phpvrouwen.nl), T.Wild, d3x, +http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript, +Rafa? Kukawski (http://blog.kukawski.pl/), stag019, pilus, WebDevHobo +(http://webdevhobo.blogspot.com/), marrtins, GeekFG +(http://geekfg.blogspot.com), Andrea Giammarchi +(http://webreflection.blogspot.com), Arpad Ray (mailto:arpad@php.net), +gorthaur, Paul Smith, Tim de Koning (http://www.kingsquare.nl), Joris, Oleg +Eremeev, Steve Hilder, majak, gettimeofday, KELAN, Josh Fraser +(http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/), +Marc Palau, Martin +(http://www.erlenwiese.de/), Breaking Par Consulting Inc +(http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7), +Chris, Mirek Slugen, saulius, Alfonso Jimenez +(http://www.alfonsojimenez.com), Diplom@t (http://difane.com/), felix, +Mailfaker (http://www.weedem.fr/), Tyler Akins (http://rumkin.com), Caio +Ariede (http://caioariede.com), Robin, Kankrelune +(http://www.webfaktory.info/), Karol Kowalski, Imgen Tata +(http://www.myipdf.com/), mdsjack (http://www.mdsjack.bo.it), Dreamer, +Felix Geisendoerfer (http://www.debuggable.com/felix), Lars Fischer, AJ, +David, Aman Gupta, Michael White, Public Domain +(http://www.json.org/json2.js), Steven Levithan +(http://blog.stevenlevithan.com), Sakimori, Pellentesque Malesuada, +Thunder.m, Dj (http://phpjs.org/functions/htmlentities:425#comment_134018), +Steve Clay, David James, Francois, class_exists, nobbler, T. Wild, Itsacon +(http://www.itsacon.net/), date, Ole Vrijenhoek (http://www.nervous.nl/), +Fox, Raphael (Ao RUDLER), Marco, noname, Mateusz "loonquawl" Zalega, Frank +Forte, Arno, ger, mktime, john (http://www.jd-tech.net), Nick Kolosov +(http://sammy.ru), marc andreu, Scott Cariss, Douglas Crockford +(http://javascript.crockford.com), madipta, Slawomir Kaniecki, +ReverseSyntax, Nathan, Alex Wilson, kenneth, Bayron Guevara, Adam Wallner +(http://web2.bitbaro.hu/), paulo kuong, jmweb, Lincoln Ramsay, djmix, +Pyerre, Jon Hohle, Thiago Mata (http://thiagomata.blog.com), lmeyrick +(https://sourceforge.net/projects/bcmath-js/this.), Linuxworld, duncan, +Gilbert, Sanjoy Roy, Shingo, sankai, Oskar Larsson H?gfeldt +(http://oskar-lh.name/), Denny Wardhana, 0m3r, Everlasto, Subhasis Deb, +josh, jd, Pier Paolo Ramon (http://www.mastersoup.com/), P, merabi, Soren +Hansen, Eugene Bulkin (http://doubleaw.com/), Der Simon +(http://innerdom.sourceforge.net/), echo is bad, Ozh, XoraX +(http://www.xorax.info), EdorFaus, JB, J A R, Marc Jansen, Francesco, LH, +Stoyan Kyosev (http://www.svest.org/), nord_ua, omid +(http://phpjs.org/functions/380:380#comment_137122), Brad Touesnard, MeEtc +(http://yass.meetcweb.com), Peter-Paul Koch +(http://www.quirksmode.org/js/beat.html), Olivier Louvignes +(http://mg-crea.com/), T0bsn, Tim Wiel, Bryan Elliott, Jalal Berrami, +Martin, JT, David Randall, Thomas Beaucourt (http://www.webapp.fr), taith, +vlado houba, Pierre-Luc Paour, Kristof Coomans (SCK-CEN Belgian Nucleair +Research Centre), Martin Pool, Kirk Strobeck, Rick Waldron, Brant Messenger +(http://www.brantmessenger.com/), Devan Penner-Woelk, Saulo Vallory, Wagner +B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong +(http://carrot.org/), Christoph, Daniel Esteban, strftime, Mick@el, rezna, +Simon Willison (http://simonwillison.net), Anton Ongson, Gabriel Paderni, +Marco van Oort, penutbutterjelly, Philipp Lenssen, Bjorn Roesbeke +(http://www.bjornroesbeke.be/), Bug?, Eric Nagel, Tomasz Wesolowski, +Evertjan Garretsen, Bobby Drake, Blues (http://tech.bluesmoon.info/), Luke +Godfrey, Pul, uestla, Alan C, Ulrich, Rafal Kukawski, Yves Sucaet, +sowberry, Norman "zEh" Fuchs, hitwork, Zahlii, johnrembo, Nick Callen, +Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Brian Tafoya +(http://www.premasolutions.com/), Philippe Jausions +(http://pear.php.net/user/jausions), Aidan Lister +(http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp, +strcmp, Taras Bogach, jpfle, Alexander Ermolaev +(http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando, +dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha +(http://www.pedrotainha.com), James, Arnout Kazemier +(http://www.3rd-Eden.com), Chris McMacken, gabriel paderni, Yannoo, +FGFEmperor, baris ozdil, Tod Gentille, Greg Frazier, jakes, 3D-GRAF, Allan +Jensen (http://www.winternet.no), Howard Yeend, Benjamin Lupton, davook, +daniel airton wermann (http://wermann.com.br), Atli T¨®r, Maximusya, Ryan +W Tenney (http://ryan.10e.us), Alexander M Beedie, fearphage +(http://http/my.opera.com/fearphage/), Nathan Sepulveda, Victor, Matteo, +Billy, stensi, Cord, Manish, T.J. Leahy, Riddler +(http://www.frontierwebdev.com/), Rafa? Kukawski, FremyCompany, Matt +Bradley, Tim de Koning, Luis Salazar (http://www.freaky-media.com/), Diogo +Resende, Rival, Andrej Pavlovic, Garagoth, Le Torbi +(http://www.letorbi.de/), Dino, Josep Sanz (http://www.ws3.es/), rem, +Russell Walker (http://www.nbill.co.uk/), Jamie Beck +(http://www.terabit.ca/), setcookie, Michael, YUI Library: +http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at +http://hacks.bluesmoon.info/strftime/strftime.js, Ben +(http://benblume.co.uk/), DtTvB +(http://dt.in.th/2008-09-16.string-length-in-bytes.html), Andreas, William, +meo, incidence, Cagri Ekin, Amirouche, Amir Habibi +(http://www.residence-mixte.com/), Luke Smith (http://lucassmith.name), +Kheang Hok Chin (http://www.distantia.ca/), Jay Klehr, Lorenzo Pisani, +Tony, Yen-Wei Liu, Greenseed, mk.keck, Leslie Hoare, dude, booeyOH, Ben +Bryan - var lerpScratch = new Quaternion(); - /** - * Computes the linear interpolation or extrapolation at t using the provided quaternions. - * - * @param {Quaternion} start The value corresponding to t at 0.0. - * @param {Quaternion} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.lerp = function(start, end, t, result) { - Check.typeOf.object('start', start); - Check.typeOf.object('end', end); - Check.typeOf.number('t', t); - Check.typeOf.object('result', result); - - lerpScratch = Quaternion.multiplyByScalar(end, t, lerpScratch); - result = Quaternion.multiplyByScalar(start, 1.0 - t, result); - return Quaternion.add(lerpScratch, result, result); - }; +Licensed under the MIT (MIT-LICENSE.txt) license. - var slerpEndNegated = new Quaternion(); - var slerpScaledP = new Quaternion(); - var slerpScaledR = new Quaternion(); - /** - * Computes the spherical linear interpolation or extrapolation at t using the provided quaternions. - * - * @param {Quaternion} start The value corresponding to t at 0.0. - * @param {Quaternion} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - * - * @see Quaternion#fastSlerp - */ - Quaternion.slerp = function(start, end, t, result) { - Check.typeOf.object('start', start); - Check.typeOf.object('end', end); - Check.typeOf.number('t', t); - Check.typeOf.object('result', result); - - var dot = Quaternion.dot(start, end); +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 angle between start must be acute. Since q and -q represent - // the same rotation, negate q to get the acute angle. - var r = end; - if (dot < 0.0) { - dot = -dot; - r = slerpEndNegated = Quaternion.negate(end, slerpEndNegated); - } +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. - // dot > 0, as the dot product approaches 1, the angle between the - // quaternions vanishes. use linear interpolation. - if (1.0 - dot < CesiumMath.EPSILON6) { - return Quaternion.lerp(start, r, t, result); - } +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 KEVIN VAN ZONNEVELD 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. +*/ - var theta = Math.acos(dot); - slerpScaledP = Quaternion.multiplyByScalar(start, Math.sin((1 - t) * theta), slerpScaledP); - slerpScaledR = Quaternion.multiplyByScalar(r, Math.sin(t * theta), slerpScaledR); - result = Quaternion.add(slerpScaledP, slerpScaledR, result); - return Quaternion.multiplyByScalar(result, 1.0 / Math.sin(theta), result); - }; +define('ThirdParty/sprintf',[],function() { - /** - * The logarithmic quaternion function. - * - * @param {Quaternion} quaternion The unit quaternion. - * @param {Cartesian3} result The object onto which to store the result. - * @returns {Cartesian3} The modified result parameter. - */ - Quaternion.log = function(quaternion, result) { - Check.typeOf.object('quaternion', quaternion); - Check.typeOf.object('result', result); - - var theta = CesiumMath.acosClamped(quaternion.w); - var thetaOverSinTheta = 0.0; +function sprintf () { + // http://kevin.vanzonneveld.net + // + original by: Ash Searle (http://hexmen.com/blog/) + // + namespaced by: Michael White (http://getsprink.com) + // + tweaked by: Jack + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Paulo Freitas + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: Dj + // + improved by: Allidylls + // * example 1: sprintf("%01.2f", 123.1); + // * returns 1: 123.10 + // * example 2: sprintf("[%10s]", 'monkey'); + // * returns 2: '[ monkey]' + // * example 3: sprintf("[%'#10s]", 'monkey'); + // * returns 3: '[####monkey]' + // * example 4: sprintf("%d", 123456789012345); + // * returns 4: '123456789012345' + var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g; + var a = arguments, + i = 0, + format = a[i++]; - if (theta !== 0.0) { - thetaOverSinTheta = theta / Math.sin(theta); - } + // pad() + var pad = function (str, len, chr, leftJustify) { + if (!chr) { + chr = ' '; + } - return Cartesian3.multiplyByScalar(quaternion, thetaOverSinTheta, result); - }; + var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); + return leftJustify ? str + padding : padding + str; + }; - /** - * The exponential quaternion function. - * - * @param {Cartesian3} cartesian The cartesian. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - */ - Quaternion.exp = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var theta = Cartesian3.magnitude(cartesian); - var sinThetaOverTheta = 0.0; + // justify() + var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) { + var diff = minWidth - value.length; + if (diff > 0) { + if (leftJustify || !zeroPad) { + value = pad(value, minWidth, customPadChar, leftJustify); + } else { + value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); + } + } + return value; + }; - if (theta !== 0.0) { - sinThetaOverTheta = Math.sin(theta) / theta; - } + // formatBaseX() + var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) { + // Note: casts negative numbers to positive ones + var number = value >>> 0; + prefix = prefix && number && { + '2': '0b', + '8': '0', + '16': '0x' + }[base] || ''; + value = prefix + pad(number.toString(base), precision || 0, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad); + }; - result.x = cartesian.x * sinThetaOverTheta; - result.y = cartesian.y * sinThetaOverTheta; - result.z = cartesian.z * sinThetaOverTheta; - result.w = Math.cos(theta); + // formatString() + var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) { + if (precision != null) { + value = value.slice(0, precision); + } + return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar); + }; - return result; - }; + // doFormat() + var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) { + var number; + var prefix; + var method; + var textTransform; + var value; - var squadScratchCartesian0 = new Cartesian3(); - var squadScratchCartesian1 = new Cartesian3(); - var squadScratchQuaternion0 = new Quaternion(); - var squadScratchQuaternion1 = new Quaternion(); + if (substring == '%%') { + return '%'; + } - /** - * Computes an inner quadrangle point. - * <p>This will compute quaternions that ensure a squad curve is C<sup>1</sup>.</p> - * - * @param {Quaternion} q0 The first quaternion. - * @param {Quaternion} q1 The second quaternion. - * @param {Quaternion} q2 The third quaternion. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - * - * @see Quaternion#squad - */ - Quaternion.computeInnerQuadrangle = function(q0, q1, q2, result) { - Check.typeOf.object('q0', q0); - Check.typeOf.object('q1', q1); - Check.typeOf.object('q2', q2); - Check.typeOf.object('result', result); - - var qInv = Quaternion.conjugate(q1, squadScratchQuaternion0); - Quaternion.multiply(qInv, q2, squadScratchQuaternion1); - var cart0 = Quaternion.log(squadScratchQuaternion1, squadScratchCartesian0); + // parse flags + var leftJustify = false, + positivePrefix = '', + zeroPad = false, + prefixBaseX = false, + customPadChar = ' '; + var flagsl = flags.length; + for (var j = 0; flags && j < flagsl; j++) { + switch (flags.charAt(j)) { + case ' ': + positivePrefix = ' '; + break; + case '+': + positivePrefix = '+'; + break; + case '-': + leftJustify = true; + break; + case "'": + customPadChar = flags.charAt(j + 1); + break; + case '0': + zeroPad = true; + break; + case '#': + prefixBaseX = true; + break; + } + } - Quaternion.multiply(qInv, q0, squadScratchQuaternion1); - var cart1 = Quaternion.log(squadScratchQuaternion1, squadScratchCartesian1); + // parameters may be null, undefined, empty-string or real valued + // we want to ignore null, undefined and empty-string values + if (!minWidth) { + minWidth = 0; + } else if (minWidth == '*') { + minWidth = +a[i++]; + } else if (minWidth.charAt(0) == '*') { + minWidth = +a[minWidth.slice(1, -1)]; + } else { + minWidth = +minWidth; + } - Cartesian3.add(cart0, cart1, cart0); - Cartesian3.multiplyByScalar(cart0, 0.25, cart0); - Cartesian3.negate(cart0, cart0); - Quaternion.exp(cart0, squadScratchQuaternion0); + // Note: undocumented perl feature: + if (minWidth < 0) { + minWidth = -minWidth; + leftJustify = true; + } - return Quaternion.multiply(q1, squadScratchQuaternion0, result); - }; + if (!isFinite(minWidth)) { + throw new Error('sprintf: (minimum-)width must be finite'); + } - /** - * Computes the spherical quadrangle interpolation between quaternions. - * - * @param {Quaternion} q0 The first quaternion. - * @param {Quaternion} q1 The second quaternion. - * @param {Quaternion} s0 The first inner quadrangle. - * @param {Quaternion} s1 The second inner quadrangle. - * @param {Number} t The time in [0,1] used to interpolate. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. - * - * - * @example - * // 1. compute the squad interpolation between two quaternions on a curve - * var s0 = Cesium.Quaternion.computeInnerQuadrangle(quaternions[i - 1], quaternions[i], quaternions[i + 1], new Cesium.Quaternion()); - * var s1 = Cesium.Quaternion.computeInnerQuadrangle(quaternions[i], quaternions[i + 1], quaternions[i + 2], new Cesium.Quaternion()); - * var q = Cesium.Quaternion.squad(quaternions[i], quaternions[i + 1], s0, s1, t, new Cesium.Quaternion()); - * - * // 2. compute the squad interpolation as above but where the first quaternion is a end point. - * var s1 = Cesium.Quaternion.computeInnerQuadrangle(quaternions[0], quaternions[1], quaternions[2], new Cesium.Quaternion()); - * var q = Cesium.Quaternion.squad(quaternions[0], quaternions[1], quaternions[0], s1, t, new Cesium.Quaternion()); - * - * @see Quaternion#computeInnerQuadrangle - */ - Quaternion.squad = function(q0, q1, s0, s1, t, result) { - Check.typeOf.object('q0', q0); - Check.typeOf.object('q1', q1); - Check.typeOf.object('s0', s0); - Check.typeOf.object('s1', s1); - Check.typeOf.number('t', t); - Check.typeOf.object('result', result); - - var slerp0 = Quaternion.slerp(q0, q1, t, squadScratchQuaternion0); - var slerp1 = Quaternion.slerp(s0, s1, t, squadScratchQuaternion1); - return Quaternion.slerp(slerp0, slerp1, 2.0 * t * (1.0 - t), result); - }; + if (!precision) { + precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined; + } else if (precision == '*') { + precision = +a[i++]; + } else if (precision.charAt(0) == '*') { + precision = +a[precision.slice(1, -1)]; + } else { + precision = +precision; + } - var fastSlerpScratchQuaternion = new Quaternion(); - var opmu = 1.90110745351730037; - var u = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; - var v = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; - var bT = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; - var bD = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; + // grab value using valueIndex if required? + value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; - for (var i = 0; i < 7; ++i) { - var s = i + 1.0; - var t = 2.0 * s + 1.0; - u[i] = 1.0 / (s * t); - v[i] = s / t; + switch (type) { + case 's': + return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar); + case 'c': + return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad); + case 'b': + return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'o': + return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'x': + return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'X': + return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase(); + case 'u': + return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'i': + case 'd': + number = +value || 0; + number = Math.round(number - number % 1); // Plain Math.round doesn't just truncate + prefix = number < 0 ? '-' : positivePrefix; + value = prefix + pad(String(Math.abs(number)), precision, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad); + case 'e': + case 'E': + case 'f': // Should handle locales (as per setlocale) + case 'F': + case 'g': + case 'G': + number = +value; + prefix = number < 0 ? '-' : positivePrefix; + method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; + textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; + value = prefix + Math.abs(number)[method](precision); + return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform](); + default: + return substring; } + }; - u[7] = opmu / (8.0 * 17.0); - v[7] = opmu * 8.0 / 17.0; + return format.replace(regex, doFormat); +} + +return sprintf; +}); + +define('Core/GregorianDate',[],function() { + 'use strict'; /** - * Computes the spherical linear interpolation or extrapolation at t using the provided quaternions. - * This implementation is faster than {@link Quaternion#slerp}, but is only accurate up to 10<sup>-6</sup>. - * - * @param {Quaternion} start The value corresponding to t at 0.0. - * @param {Quaternion} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter. + * Represents a Gregorian date in a more precise format than the JavaScript Date object. + * In addition to submillisecond precision, this object can also represent leap seconds. + * @alias GregorianDate + * @constructor * - * @see Quaternion#slerp + * @see JulianDate#toGregorianDate */ - Quaternion.fastSlerp = function(start, end, t, result) { - Check.typeOf.object('start', start); - Check.typeOf.object('end', end); - Check.typeOf.number('t', t); - Check.typeOf.object('result', result); - - var x = Quaternion.dot(start, end); - - var sign; - if (x >= 0) { - sign = 1.0; - } else { - sign = -1.0; - x = -x; - } - - var xm1 = x - 1.0; - var d = 1.0 - t; - var sqrT = t * t; - var sqrD = d * d; - - for (var i = 7; i >= 0; --i) { - bT[i] = (u[i] * sqrT - v[i]) * xm1; - bD[i] = (u[i] * sqrD - v[i]) * xm1; - } + function GregorianDate(year, month, day, hour, minute, second, millisecond, isLeapSecond) { + /** + * Gets or sets the year as a whole number. + * @type {Number} + */ + this.year = year; + /** + * Gets or sets the month as a whole number with range [1, 12]. + * @type {Number} + */ + this.month = month; + /** + * Gets or sets the day of the month as a whole number starting at 1. + * @type {Number} + */ + this.day = day; + /** + * Gets or sets the hour as a whole number with range [0, 23]. + * @type {Number} + */ + this.hour = hour; + /** + * Gets or sets the minute of the hour as a whole number with range [0, 59]. + * @type {Number} + */ + this.minute = minute; + /** + * Gets or sets the second of the minute as a whole number with range [0, 60], with 60 representing a leap second. + * @type {Number} + */ + this.second = second; + /** + * Gets or sets the millisecond of the second as a floating point number with range [0.0, 1000.0). + * @type {Number} + */ + this.millisecond = millisecond; + /** + * Gets or sets whether this time is during a leap second. + * @type {Boolean} + */ + this.isLeapSecond = isLeapSecond; + } - var cT = sign * t * ( - 1.0 + bT[0] * (1.0 + bT[1] * (1.0 + bT[2] * (1.0 + bT[3] * ( - 1.0 + bT[4] * (1.0 + bT[5] * (1.0 + bT[6] * (1.0 + bT[7])))))))); - var cD = d * ( - 1.0 + bD[0] * (1.0 + bD[1] * (1.0 + bD[2] * (1.0 + bD[3] * ( - 1.0 + bD[4] * (1.0 + bD[5] * (1.0 + bD[6] * (1.0 + bD[7])))))))); + return GregorianDate; +}); - var temp = Quaternion.multiplyByScalar(start, cD, fastSlerpScratchQuaternion); - Quaternion.multiplyByScalar(end, cT, result); - return Quaternion.add(temp, result, result); - }; +define('Core/isLeapYear',[ + './DeveloperError' + ], function( + DeveloperError) { + 'use strict'; /** - * Computes the spherical quadrangle interpolation between quaternions. - * An implementation that is faster than {@link Quaternion#squad}, but less accurate. + * Determines if a given date is a leap year. * - * @param {Quaternion} q0 The first quaternion. - * @param {Quaternion} q1 The second quaternion. - * @param {Quaternion} s0 The first inner quadrangle. - * @param {Quaternion} s1 The second inner quadrangle. - * @param {Number} t The time in [0,1] used to interpolate. - * @param {Quaternion} result The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new instance if none was provided. + * @exports isLeapYear * - * @see Quaternion#squad + * @param {Number} year The year to be tested. + * @returns {Boolean} True if <code>year</code> is a leap year. + * + * @example + * var leapYear = Cesium.isLeapYear(2000); // true */ - Quaternion.fastSquad = function(q0, q1, s0, s1, t, result) { - Check.typeOf.object('q0', q0); - Check.typeOf.object('q1', q1); - Check.typeOf.object('s0', s0); - Check.typeOf.object('s1', s1); - Check.typeOf.number('t', t); - Check.typeOf.object('result', result); + function isLeapYear(year) { + if (year === null || isNaN(year)) { + throw new DeveloperError('year is required and must be a number.'); + } - var slerp0 = Quaternion.fastSlerp(q0, q1, t, squadScratchQuaternion0); - var slerp1 = Quaternion.fastSlerp(s0, s1, t, squadScratchQuaternion1); - return Quaternion.fastSlerp(slerp0, slerp1, 2.0 * t * (1.0 - t), result); - }; + return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); + } - /** - * Compares the provided quaternions componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Quaternion} [left] The first quaternion. - * @param {Quaternion} [right] The second quaternion. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Quaternion.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.x === right.x) && - (left.y === right.y) && - (left.z === right.z) && - (left.w === right.w)); - }; + return isLeapYear; +}); - /** - * Compares the provided quaternions componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {Quaternion} [left] The first quaternion. - * @param {Quaternion} [right] The second quaternion. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. - */ - Quaternion.equalsEpsilon = function(left, right, epsilon) { - Check.typeOf.number('epsilon', epsilon); - - return (left === right) || - ((defined(left)) && - (defined(right)) && - (Math.abs(left.x - right.x) <= epsilon) && - (Math.abs(left.y - right.y) <= epsilon) && - (Math.abs(left.z - right.z) <= epsilon) && - (Math.abs(left.w - right.w) <= epsilon)); - }; +define('Core/LeapSecond',[],function() { + 'use strict'; /** - * An immutable Quaternion instance initialized to (0.0, 0.0, 0.0, 0.0). + * Describes a single leap second, which is constructed from a {@link JulianDate} and a + * numerical offset representing the number of seconds TAI is ahead of the UTC time standard. + * @alias LeapSecond + * @constructor * - * @type {Quaternion} - * @constant + * @param {JulianDate} [date] A Julian date representing the time of the leap second. + * @param {Number} [offset] The cumulative number of seconds that TAI is ahead of UTC at the provided date. */ - Quaternion.ZERO = freezeObject(new Quaternion(0.0, 0.0, 0.0, 0.0)); + function LeapSecond(date, offset) { + /** + * Gets or sets the date at which this leap second occurs. + * @type {JulianDate} + */ + this.julianDate = date; - /** - * An immutable Quaternion instance initialized to (0.0, 0.0, 0.0, 1.0). - * - * @type {Quaternion} - * @constant - */ - Quaternion.IDENTITY = freezeObject(new Quaternion(0.0, 0.0, 0.0, 1.0)); + /** + * Gets or sets the cumulative number of seconds between the UTC and TAI time standards at the time + * of this leap second. + * @type {Number} + */ + this.offset = offset; + } - /** - * Duplicates this Quaternion instance. - * - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. - */ - Quaternion.prototype.clone = function(result) { - return Quaternion.clone(this, result); - }; + return LeapSecond; +}); - /** - * Compares this and the provided quaternion componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Quaternion} [right] The right hand side quaternion. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Quaternion.prototype.equals = function(right) { - return Quaternion.equals(this, right); - }; +define('Core/TimeConstants',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; /** - * Compares this and the provided quaternion componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. + * Constants for time conversions like those done by {@link JulianDate}. * - * @param {Quaternion} [right] The right hand side quaternion. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @exports TimeConstants + * + * @see JulianDate + * + * @private */ - Quaternion.prototype.equalsEpsilon = function(right, epsilon) { - return Quaternion.equalsEpsilon(this, right, epsilon); + var TimeConstants = { + /** + * The number of seconds in one millisecond: <code>0.001</code> + * @type {Number} + * @constant + */ + SECONDS_PER_MILLISECOND : 0.001, + + /** + * The number of seconds in one minute: <code>60</code>. + * @type {Number} + * @constant + */ + SECONDS_PER_MINUTE : 60.0, + + /** + * The number of minutes in one hour: <code>60</code>. + * @type {Number} + * @constant + */ + MINUTES_PER_HOUR : 60.0, + + /** + * The number of hours in one day: <code>24</code>. + * @type {Number} + * @constant + */ + HOURS_PER_DAY : 24.0, + + /** + * The number of seconds in one hour: <code>3600</code>. + * @type {Number} + * @constant + */ + SECONDS_PER_HOUR : 3600.0, + + /** + * The number of minutes in one day: <code>1440</code>. + * @type {Number} + * @constant + */ + MINUTES_PER_DAY : 1440.0, + + /** + * The number of seconds in one day, ignoring leap seconds: <code>86400</code>. + * @type {Number} + * @constant + */ + SECONDS_PER_DAY : 86400.0, + + /** + * The number of days in one Julian century: <code>36525</code>. + * @type {Number} + * @constant + */ + DAYS_PER_JULIAN_CENTURY : 36525.0, + + /** + * One trillionth of a second. + * @type {Number} + * @constant + */ + PICOSECOND : 0.000000001, + + /** + * The number of days to subtract from a Julian date to determine the + * modified Julian date, which gives the number of days since midnight + * on November 17, 1858. + * @type {Number} + * @constant + */ + MODIFIED_JULIAN_DATE_DIFFERENCE : 2400000.5 }; + return freezeObject(TimeConstants); +}); + +define('Core/TimeStandard',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** - * Returns a string representing this quaternion in the format (x, y, z, w). + * Provides the type of time standards which JulianDate can take as input. * - * @returns {String} A string representing this Quaternion. + * @exports TimeStandard + * + * @see JulianDate */ - Quaternion.prototype.toString = function() { - return '(' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ')'; + var TimeStandard = { + /** + * Represents the coordinated Universal Time (UTC) time standard. + * + * UTC is related to TAI according to the relationship + * <code>UTC = TAI - deltaT</code> where <code>deltaT</code> is the number of leap + * seconds which have been introduced as of the time in TAI. + * + * @type {Number} + * @constant + */ + UTC : 0, + + /** + * Represents the International Atomic Time (TAI) time standard. + * TAI is the principal time standard to which the other time standards are related. + * + * @type {Number} + * @constant + */ + TAI : 1 }; - return Quaternion; + return freezeObject(TimeStandard); }); -define('Core/Transforms',[ - '../ThirdParty/when', - './Cartesian2', - './Cartesian3', - './Cartesian4', - './Cartographic', - './Check', +define('Core/JulianDate',[ + '../ThirdParty/sprintf', + './binarySearch', './defaultValue', './defined', './DeveloperError', - './EarthOrientationParameters', - './EarthOrientationParametersSample', - './Ellipsoid', - './Iau2006XysData', - './Iau2006XysSample', - './JulianDate', - './Math', - './Matrix3', - './Matrix4', - './Quaternion', - './TimeConstants' + './GregorianDate', + './isLeapYear', + './LeapSecond', + './TimeConstants', + './TimeStandard' ], function( - when, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - Check, + sprintf, + binarySearch, defaultValue, defined, DeveloperError, - EarthOrientationParameters, - EarthOrientationParametersSample, - Ellipsoid, - Iau2006XysData, - Iau2006XysSample, - JulianDate, - CesiumMath, - Matrix3, - Matrix4, - Quaternion, - TimeConstants) { + GregorianDate, + isLeapYear, + LeapSecond, + TimeConstants, + TimeStandard) { 'use strict'; - /** - * Contains functions for transforming positions to various reference frames. - * - * @exports Transforms - */ - var Transforms = {}; + var gregorianDateScratch = new GregorianDate(); + var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + var daysInLeapFeburary = 29; - var vectorProductLocalFrame = { - up : { - south : 'east', - north : 'west', - west : 'south', - east : 'north' - }, - down : { - south : 'west', - north : 'east', - west : 'north', - east : 'south' - }, - south : { - up : 'west', - down : 'east', - west : 'down', - east : 'up' - }, - north : { - up : 'east', - down : 'west', - west : 'up', - east : 'down' - }, - west : { - up : 'north', - down : 'south', - north : 'down', - south : 'up' - }, - east : { - up : 'south', - down : 'north', - north : 'up', - south : 'down' + function compareLeapSecondDates(leapSecond, dateToFind) { + return JulianDate.compare(leapSecond.julianDate, dateToFind.julianDate); + } + + // we don't really need a leap second instance, anything with a julianDate property will do + var binarySearchScratchLeapSecond = new LeapSecond(); + + function convertUtcToTai(julianDate) { + //Even though julianDate is in UTC, we'll treat it as TAI and + //search the leap second table for it. + binarySearchScratchLeapSecond.julianDate = julianDate; + var leapSeconds = JulianDate.leapSeconds; + var index = binarySearch(leapSeconds, binarySearchScratchLeapSecond, compareLeapSecondDates); + + if (index < 0) { + index = ~index; } - }; - var degeneratePositionLocalFrame = { - north : [-1, 0, 0], - east : [0, 1, 0], - up : [0, 0, 1], - south : [1, 0, 0], - west : [0, -1, 0], - down : [0, 0, -1] - }; + if (index >= leapSeconds.length) { + index = leapSeconds.length - 1; + } - var localFrameToFixedFrameCache = {}; + var offset = leapSeconds[index].offset; + if (index > 0) { + //Now we have the index of the closest leap second that comes on or after our UTC time. + //However, if the difference between the UTC date being converted and the TAI + //defined leap second is greater than the offset, we are off by one and need to use + //the previous leap second. + var difference = JulianDate.secondsDifference(leapSeconds[index].julianDate, julianDate); + if (difference > offset) { + index--; + offset = leapSeconds[index].offset; + } + } - var scratchCalculateCartesian = { - east : new Cartesian3(), - north : new Cartesian3(), - up : new Cartesian3(), - west : new Cartesian3(), - south : new Cartesian3(), - down : new Cartesian3() - }; - var scratchFirstCartesian = new Cartesian3(); - var scratchSecondCartesian = new Cartesian3(); - var scratchThirdCartesian = new Cartesian3(); - /** - * Generates a function that computes a 4x4 transformation matrix from a reference frame - * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * @param {String} firstAxis name of the first axis of the local reference frame. Must be - * 'east', 'north', 'up', 'west', 'south' or 'down'. - * @param {String} secondAxis name of the second axis of the local reference frame. Must be - * 'east', 'north', 'up', 'west', 'south' or 'down'. - * @return {localFrameToFixedFrameGenerator~resultat} The function that will computes a - * 4x4 transformation matrix from a reference frame, with first axis and second axis compliant with the parameters, - */ - Transforms.localFrameToFixedFrameGenerator = function( firstAxis, secondAxis) { - if (!vectorProductLocalFrame.hasOwnProperty(firstAxis) || !vectorProductLocalFrame[firstAxis].hasOwnProperty(secondAxis)) { - throw new DeveloperError('firstAxis and secondAxis must be east, north, up, west, south or down.'); - } - var thirdAxis = vectorProductLocalFrame[firstAxis][secondAxis]; + JulianDate.addSeconds(julianDate, offset, julianDate); + } - /** - * Computes a 4x4 transformation matrix from a reference frame - * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * @callback Transforms~LocalFrameToFixedFrame - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. - */ - var resultat; - var hashAxis = firstAxis + secondAxis; - if (defined(localFrameToFixedFrameCache[hashAxis])) { - resultat = localFrameToFixedFrameCache[hashAxis]; - } else { - resultat = function(origin, ellipsoid, result) { - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); - } - if (!defined(result)) { - result = new Matrix4(); - } - // If x and y are zero, assume origin is at a pole, which is a special case. - if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - var sign = CesiumMath.sign(origin.z); + function convertTaiToUtc(julianDate, result) { + binarySearchScratchLeapSecond.julianDate = julianDate; + var leapSeconds = JulianDate.leapSeconds; + var index = binarySearch(leapSeconds, binarySearchScratchLeapSecond, compareLeapSecondDates); + if (index < 0) { + index = ~index; + } - Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian); - if (firstAxis !== 'east' && firstAxis !== 'west') { - Cartesian3.multiplyByScalar(scratchFirstCartesian, sign, scratchFirstCartesian); - } + //All times before our first leap second get the first offset. + if (index === 0) { + return JulianDate.addSeconds(julianDate, -leapSeconds[0].offset, result); + } - Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, scratchSecondCartesian); - if (secondAxis !== 'east' && secondAxis !== 'west') { - Cartesian3.multiplyByScalar(scratchSecondCartesian, sign, scratchSecondCartesian); - } + //All times after our leap second get the last offset. + if (index >= leapSeconds.length) { + return JulianDate.addSeconds(julianDate, -leapSeconds[index - 1].offset, result); + } - Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, scratchThirdCartesian); - if (thirdAxis !== 'east' && thirdAxis !== 'west') { - Cartesian3.multiplyByScalar(scratchThirdCartesian, sign, scratchThirdCartesian); - } - } else { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, scratchCalculateCartesian.up); + //Compute the difference between the found leap second and the time we are converting. + var difference = JulianDate.secondsDifference(leapSeconds[index].julianDate, julianDate); - var up = scratchCalculateCartesian.up; - var east = scratchCalculateCartesian.east; - east.x = -origin.y; - east.y = origin.x; - east.z = 0.0; - Cartesian3.normalize(east, scratchCalculateCartesian.east); - Cartesian3.cross(up, east, scratchCalculateCartesian.north); + if (difference === 0) { + //The date is in our leap second table. + return JulianDate.addSeconds(julianDate, -leapSeconds[index].offset, result); + } - Cartesian3.multiplyByScalar(scratchCalculateCartesian.up, -1, scratchCalculateCartesian.down); - Cartesian3.multiplyByScalar(scratchCalculateCartesian.east, -1, scratchCalculateCartesian.west); - Cartesian3.multiplyByScalar(scratchCalculateCartesian.north, -1, scratchCalculateCartesian.south); + if (difference <= 1.0) { + //The requested date is during the moment of a leap second, then we cannot convert to UTC + return undefined; + } - scratchFirstCartesian = scratchCalculateCartesian[firstAxis]; - scratchSecondCartesian = scratchCalculateCartesian[secondAxis]; - scratchThirdCartesian = scratchCalculateCartesian[thirdAxis]; - } - result[0] = scratchFirstCartesian.x; - result[1] = scratchFirstCartesian.y; - result[2] = scratchFirstCartesian.z; - result[3] = 0.0; - result[4] = scratchSecondCartesian.x; - result[5] = scratchSecondCartesian.y; - result[6] = scratchSecondCartesian.z; - result[7] = 0.0; - result[8] = scratchThirdCartesian.x; - result[9] = scratchThirdCartesian.y; - result[10] = scratchThirdCartesian.z; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - }; - localFrameToFixedFrameCache[hashAxis] = resultat; - } - return resultat; - }; + //The time is in between two leap seconds, index is the leap second after the date + //we're converting, so we subtract one to get the correct LeapSecond instance. + return JulianDate.addSeconds(julianDate, -leapSeconds[--index].offset, result); + } - /** - * Computes a 4x4 transformation matrix from a reference frame with an east-north-up axes - * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * The local axes are defined as: - * <ul> - * <li>The <code>x</code> axis points in the local east direction.</li> - * <li>The <code>y</code> axis points in the local north direction.</li> - * <li>The <code>z</code> axis points in the direction of the ellipsoid surface normal which passes through the position.</li> - * </ul> - * - * @function - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. - * - * @example - * // Get the transform from local east-north-up at cartographic (0.0, 0.0) to Earth's fixed frame. - * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); - */ - Transforms.eastNorthUpToFixedFrame = Transforms.localFrameToFixedFrameGenerator('east','north'); + function setComponents(wholeDays, secondsOfDay, julianDate) { + var extraDays = (secondsOfDay / TimeConstants.SECONDS_PER_DAY) | 0; + wholeDays += extraDays; + secondsOfDay -= TimeConstants.SECONDS_PER_DAY * extraDays; - /** - * Computes a 4x4 transformation matrix from a reference frame with an north-east-down axes - * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * The local axes are defined as: - * <ul> - * <li>The <code>x</code> axis points in the local north direction.</li> - * <li>The <code>y</code> axis points in the local east direction.</li> - * <li>The <code>z</code> axis points in the opposite direction of the ellipsoid surface normal which passes through the position.</li> - * </ul> - * - * @function - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. - * - * @example - * // Get the transform from local north-east-down at cartographic (0.0, 0.0) to Earth's fixed frame. - * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var transform = Cesium.Transforms.northEastDownToFixedFrame(center); - */ - Transforms.northEastDownToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','east'); + if (secondsOfDay < 0) { + wholeDays--; + secondsOfDay += TimeConstants.SECONDS_PER_DAY; + } - /** - * Computes a 4x4 transformation matrix from a reference frame with an north-up-east axes - * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * The local axes are defined as: - * <ul> - * <li>The <code>x</code> axis points in the local north direction.</li> - * <li>The <code>y</code> axis points in the direction of the ellipsoid surface normal which passes through the position.</li> - * <li>The <code>z</code> axis points in the local east direction.</li> - * </ul> - * - * @function - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. - * - * @example - * // Get the transform from local north-up-east at cartographic (0.0, 0.0) to Earth's fixed frame. - * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var transform = Cesium.Transforms.northUpEastToFixedFrame(center); - */ - Transforms.northUpEastToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','up'); + julianDate.dayNumber = wholeDays; + julianDate.secondsOfDay = secondsOfDay; + return julianDate; + } - /** - * Computes a 4x4 transformation matrix from a reference frame with an north-west-up axes - * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * The local axes are defined as: - * <ul> - * <li>The <code>x</code> axis points in the local north direction.</li> - * <li>The <code>y</code> axis points in the local west direction.</li> - * <li>The <code>z</code> axis points in the direction of the ellipsoid surface normal which passes through the position.</li> - * </ul> - * - * @function - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. - * - * @example - * // Get the transform from local north-West-Up at cartographic (0.0, 0.0) to Earth's fixed frame. - * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var transform = Cesium.Transforms.northWestUpToFixedFrame(center); - */ - Transforms.northWestUpToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','west'); + function computeJulianDateComponents(year, month, day, hour, minute, second, millisecond) { + // Algorithm from page 604 of the Explanatory Supplement to the + // Astronomical Almanac (Seidelmann 1992). - var scratchHPRQuaternion = new Quaternion(); - var scratchScale = new Cartesian3(1.0, 1.0, 1.0); - var scratchHPRMatrix4 = new Matrix4(); + var a = ((month - 14) / 12) | 0; + var b = year + 4800 + a; + var dayNumber = (((1461 * b) / 4) | 0) + (((367 * (month - 2 - 12 * a)) / 12) | 0) - (((3 * (((b + 100) / 100) | 0)) / 4) | 0) + day - 32075; + + // JulianDates are noon-based + hour = hour - 12; + if (hour < 0) { + hour += 24; + } + + var secondsOfDay = second + ((hour * TimeConstants.SECONDS_PER_HOUR) + (minute * TimeConstants.SECONDS_PER_MINUTE) + (millisecond * TimeConstants.SECONDS_PER_MILLISECOND)); + + if (secondsOfDay >= 43200.0) { + dayNumber -= 1; + } + + return [dayNumber, secondsOfDay]; + } + + //Regular expressions used for ISO8601 date parsing. + //YYYY + var matchCalendarYear = /^(\d{4})$/; + //YYYY-MM (YYYYMM is invalid) + var matchCalendarMonth = /^(\d{4})-(\d{2})$/; + //YYYY-DDD or YYYYDDD + var matchOrdinalDate = /^(\d{4})-?(\d{3})$/; + //YYYY-Www or YYYYWww or YYYY-Www-D or YYYYWwwD + var matchWeekDate = /^(\d{4})-?W(\d{2})-?(\d{1})?$/; + //YYYY-MM-DD or YYYYMMDD + var matchCalendarDate = /^(\d{4})-?(\d{2})-?(\d{2})$/; + // Match utc offset + var utcOffset = /([Z+\-])?(\d{2})?:?(\d{2})?$/; + // Match hours HH or HH.xxxxx + var matchHours = /^(\d{2})(\.\d+)?/.source + utcOffset.source; + // Match hours/minutes HH:MM HHMM.xxxxx + var matchHoursMinutes = /^(\d{2}):?(\d{2})(\.\d+)?/.source + utcOffset.source; + // Match hours/minutes HH:MM:SS HHMMSS.xxxxx + var matchHoursMinutesSeconds = /^(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?/.source + utcOffset.source; + + var iso8601ErrorMessage = 'Invalid ISO 8601 date.'; /** - * Computes a 4x4 transformation matrix from a reference frame with axes computed from the heading-pitch-roll angles - * centered at the provided origin to the provided ellipsoid's fixed reference frame. Heading is the rotation from the local north - * direction where a positive angle is increasing eastward. Pitch is the rotation from the local east-north plane. Positive pitch angles - * are above the plane. Negative pitch angles are below the plane. Roll is the first rotation applied about the local east axis. - * - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Transforms~LocalFrameToFixedFrame} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation - * matrix from a reference frame to the provided ellipsoid's fixed reference frame - * @param {Matrix4} [result] The object onto which to store the result. - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + * Represents an astronomical Julian date, which is the number of days since noon on January 1, -4712 (4713 BC). + * For increased precision, this class stores the whole number part of the date and the seconds + * part of the date in separate components. In order to be safe for arithmetic and represent + * leap seconds, the date is always stored in the International Atomic Time standard + * {@link TimeStandard.TAI}. + * @alias JulianDate + * @constructor * - * @example - * // Get the transform from local heading-pitch-roll at cartographic (0.0, 0.0) to Earth's fixed frame. - * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var heading = -Cesium.Math.PI_OVER_TWO; - * var pitch = Cesium.Math.PI_OVER_FOUR; - * var roll = 0.0; - * var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - * var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, hpr); + * @param {Number} [julianDayNumber=0.0] The Julian Day Number representing the number of whole days. Fractional days will also be handled correctly. + * @param {Number} [secondsOfDay=0.0] The number of seconds into the current Julian Day Number. Fractional seconds, negative seconds and seconds greater than a day will be handled correctly. + * @param {TimeStandard} [timeStandard=TimeStandard.UTC] The time standard in which the first two parameters are defined. */ - Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { - Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); - - fixedFrameTransform = defaultValue(fixedFrameTransform, Transforms.eastNorthUpToFixedFrame); - var hprQuaternion = Quaternion.fromHeadingPitchRoll(headingPitchRoll, scratchHPRQuaternion); - var hprMatrix = Matrix4.fromTranslationQuaternionRotationScale(Cartesian3.ZERO, hprQuaternion, scratchScale, scratchHPRMatrix4); - result = fixedFrameTransform(origin, ellipsoid, result); - return Matrix4.multiply(result, hprMatrix, result); - }; + function JulianDate(julianDayNumber, secondsOfDay, timeStandard) { + /** + * Gets or sets the number of whole days. + * @type {Number} + */ + this.dayNumber = undefined; - var scratchENUMatrix4 = new Matrix4(); - var scratchHPRMatrix3 = new Matrix3(); + /** + * Gets or sets the number of seconds into the current day. + * @type {Number} + */ + this.secondsOfDay = undefined; + + julianDayNumber = defaultValue(julianDayNumber, 0.0); + secondsOfDay = defaultValue(secondsOfDay, 0.0); + timeStandard = defaultValue(timeStandard, TimeStandard.UTC); + + //If julianDayNumber is fractional, make it an integer and add the number of seconds the fraction represented. + var wholeDays = julianDayNumber | 0; + secondsOfDay = secondsOfDay + (julianDayNumber - wholeDays) * TimeConstants.SECONDS_PER_DAY; + + setComponents(wholeDays, secondsOfDay, this); + + if (timeStandard === TimeStandard.UTC) { + convertUtcToTai(this); + } + } /** - * Computes a quaternion from a reference frame with axes computed from the heading-pitch-roll angles - * centered at the provided origin. Heading is the rotation from the local north - * direction where a positive angle is increasing eastward. Pitch is the rotation from the local east-north plane. Positive pitch angles - * are above the plane. Negative pitch angles are below the plane. Roll is the first rotation applied about the local east axis. + * Creates a new instance from a GregorianDate. * - * @param {Cartesian3} origin The center point of the local reference frame. - * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {Transforms~LocalFrameToFixedFrame} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation - * matrix from a reference frame to the provided ellipsoid's fixed reference frame - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new Quaternion instance if none was provided. + * @param {GregorianDate} date A GregorianDate. + * @param {JulianDate} [result] An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter or a new instance if none was provided. * - * @example - * // Get the quaternion from local heading-pitch-roll at cartographic (0.0, 0.0) to Earth's fixed frame. - * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var heading = -Cesium.Math.PI_OVER_TWO; - * var pitch = Cesium.Math.PI_OVER_FOUR; - * var roll = 0.0; - * var hpr = new HeadingPitchRoll(heading, pitch, roll); - * var quaternion = Cesium.Transforms.headingPitchRollQuaternion(center, hpr); + * @exception {DeveloperError} date must be a valid GregorianDate. */ - Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { - Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); + JulianDate.fromGregorianDate = function(date, result) { + if (!(date instanceof GregorianDate)) { + throw new DeveloperError('date must be a valid GregorianDate.'); + } - var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, scratchENUMatrix4); - var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3); - return Quaternion.fromRotationMatrix(rotation, result); + var components = computeJulianDateComponents(date.year, date.month, date.day, date.hour, date.minute, date.second, date.millisecond); + if (!defined(result)) { + return new JulianDate(components[0], components[1], TimeStandard.UTC); + } + setComponents(components[0], components[1], result); + convertUtcToTai(result); + return result; }; - var gmstConstant0 = 6 * 3600 + 41 * 60 + 50.54841; - var gmstConstant1 = 8640184.812866; - var gmstConstant2 = 0.093104; - var gmstConstant3 = -6.2E-6; - var rateCoef = 1.1772758384668e-19; - var wgs84WRPrecessing = 7.2921158553E-5; - var twoPiOverSecondsInDay = CesiumMath.TWO_PI / 86400.0; - var dateInUtc = new JulianDate(); - /** - * Computes a rotation matrix to transform a point or vector from True Equator Mean Equinox (TEME) axes to the - * pseudo-fixed axes at a given time. This method treats the UT1 time standard as equivalent to UTC. + * Creates a new instance from a JavaScript Date. * - * @param {JulianDate} date The time at which to compute the rotation matrix. - * @param {Matrix3} [result] The object onto which to store the result. - * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if none was provided. + * @param {Date} date A JavaScript Date. + * @param {JulianDate} [result] An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter or a new instance if none was provided. * - * @example - * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { - * var now = Cesium.JulianDate.now(); - * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); - * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); - * var inverseTransform = Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()); - * Cesium.Matrix4.multiplyByPoint(inverseTransform, offset, offset); - * camera.lookAtTransform(transform, offset); - * }); + * @exception {DeveloperError} date must be a valid JavaScript Date. */ - Transforms.computeTemeToPseudoFixedMatrix = function (date, result) { - if (!defined(date)) { - throw new DeveloperError('date is required.'); + JulianDate.fromDate = function(date, result) { + if (!(date instanceof Date) || isNaN(date.getTime())) { + throw new DeveloperError('date must be a valid JavaScript Date.'); } - // GMST is actually computed using UT1. We're using UTC as an approximation of UT1. - // We do not want to use the function like convertTaiToUtc in JulianDate because - // we explicitly do not want to fail when inside the leap second. - - dateInUtc = JulianDate.addSeconds(date, -JulianDate.computeTaiMinusUtc(date), dateInUtc); - var utcDayNumber = dateInUtc.dayNumber; - var utcSecondsIntoDay = dateInUtc.secondsOfDay; - - var t; - var diffDays = utcDayNumber - 2451545; - if (utcSecondsIntoDay >= 43200.0) { - t = (diffDays + 0.5) / TimeConstants.DAYS_PER_JULIAN_CENTURY; - } else { - t = (diffDays - 0.5) / TimeConstants.DAYS_PER_JULIAN_CENTURY; - } - - var gmst0 = gmstConstant0 + t * (gmstConstant1 + t * (gmstConstant2 + t * gmstConstant3)); - var angle = (gmst0 * twoPiOverSecondsInDay) % CesiumMath.TWO_PI; - var ratio = wgs84WRPrecessing + rateCoef * (utcDayNumber - 2451545.5); - var secondsSinceMidnight = (utcSecondsIntoDay + TimeConstants.SECONDS_PER_DAY * 0.5) % TimeConstants.SECONDS_PER_DAY; - var gha = angle + (ratio * secondsSinceMidnight); - var cosGha = Math.cos(gha); - var sinGha = Math.sin(gha); - + var components = computeJulianDateComponents(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds()); if (!defined(result)) { - return new Matrix3(cosGha, sinGha, 0.0, - -sinGha, cosGha, 0.0, - 0.0, 0.0, 1.0); + return new JulianDate(components[0], components[1], TimeStandard.UTC); } - result[0] = cosGha; - result[1] = -sinGha; - result[2] = 0.0; - result[3] = sinGha; - result[4] = cosGha; - result[5] = 0.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 1.0; + setComponents(components[0], components[1], result); + convertUtcToTai(result); return result; }; /** - * The source of IAU 2006 XYS data, used for computing the transformation between the - * Fixed and ICRF axes. - * @type {Iau2006XysData} + * Creates a new instance from a from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} date. + * This method is superior to <code>Date.parse</code> because it will handle all valid formats defined by the ISO 8601 + * specification, including leap seconds and sub-millisecond times, which discarded by most JavaScript implementations. * - * @see Transforms.computeIcrfToFixedMatrix - * @see Transforms.computeFixedToIcrfMatrix + * @param {String} iso8601String An ISO 8601 date. + * @param {JulianDate} [result] An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter or a new instance if none was provided. * - * @private + * @exception {DeveloperError} Invalid ISO 8601 date. */ - Transforms.iau2006XysData = new Iau2006XysData(); + JulianDate.fromIso8601 = function(iso8601String, result) { + if (typeof iso8601String !== 'string') { + throw new DeveloperError(iso8601ErrorMessage); + } + + //Comma and decimal point both indicate a fractional number according to ISO 8601, + //start out by blanket replacing , with . which is the only valid such symbol in JS. + iso8601String = iso8601String.replace(',', '.'); - /** - * The source of Earth Orientation Parameters (EOP) data, used for computing the transformation - * between the Fixed and ICRF axes. By default, zero values are used for all EOP values, - * yielding a reasonable but not completely accurate representation of the ICRF axes. - * @type {EarthOrientationParameters} - * - * @see Transforms.computeIcrfToFixedMatrix - * @see Transforms.computeFixedToIcrfMatrix - * - * @private - */ - Transforms.earthOrientationParameters = EarthOrientationParameters.NONE; + //Split the string into its date and time components, denoted by a mandatory T + var tokens = iso8601String.split('T'); + var year; + var month = 1; + var day = 1; + var hour = 0; + var minute = 0; + var second = 0; + var millisecond = 0; - var ttMinusTai = 32.184; - var j2000ttDays = 2451545.0; + //Lacking a time is okay, but a missing date is illegal. + var date = tokens[0]; + var time = tokens[1]; + var tmp; + var inLeapYear; + if (!defined(date)) { + throw new DeveloperError(iso8601ErrorMessage); + } - /** - * Preloads the data necessary to transform between the ICRF and Fixed axes, in either - * direction, over a given interval. This function returns a promise that, when resolved, - * indicates that the preload has completed. - * - * @param {TimeInterval} timeInterval The interval to preload. - * @returns {Promise.<undefined>} A promise that, when resolved, indicates that the preload has completed - * and evaluation of the transformation between the fixed and ICRF axes will - * no longer return undefined for a time inside the interval. - * - * - * @example - * var interval = new Cesium.TimeInterval(...); - * when(Cesium.Transforms.preloadIcrfFixed(interval), function() { - * // the data is now loaded - * }); - * - * @see Transforms.computeIcrfToFixedMatrix - * @see Transforms.computeFixedToIcrfMatrix - * @see when - */ - Transforms.preloadIcrfFixed = function(timeInterval) { - var startDayTT = timeInterval.start.dayNumber; - var startSecondTT = timeInterval.start.secondsOfDay + ttMinusTai; - var stopDayTT = timeInterval.stop.dayNumber; - var stopSecondTT = timeInterval.stop.secondsOfDay + ttMinusTai; - - var xysPromise = Transforms.iau2006XysData.preload(startDayTT, startSecondTT, stopDayTT, stopSecondTT); - var eopPromise = Transforms.earthOrientationParameters.getPromiseToLoad(); + var dashCount; + + //First match the date against possible regular expressions. + tokens = date.match(matchCalendarDate); + if (tokens !== null) { + dashCount = date.split('-').length - 1; + if (dashCount > 0 && dashCount !== 2) { + throw new DeveloperError(iso8601ErrorMessage); + } + year = +tokens[1]; + month = +tokens[2]; + day = +tokens[3]; + } else { + tokens = date.match(matchCalendarMonth); + if (tokens !== null) { + year = +tokens[1]; + month = +tokens[2]; + } else { + tokens = date.match(matchCalendarYear); + if (tokens !== null) { + year = +tokens[1]; + } else { + //Not a year/month/day so it must be an ordinal date. + var dayOfYear; + tokens = date.match(matchOrdinalDate); + if (tokens !== null) { - return when.all([xysPromise, eopPromise]); - }; + year = +tokens[1]; + dayOfYear = +tokens[2]; + inLeapYear = isLeapYear(year); - /** - * Computes a rotation matrix to transform a point or vector from the International Celestial - * Reference Frame (GCRF/ICRF) inertial frame axes to the Earth-Fixed frame axes (ITRF) - * at a given time. This function may return undefined if the data necessary to - * do the transformation is not yet loaded. - * - * @param {JulianDate} date The time at which to compute the rotation matrix. - * @param {Matrix3} [result] The object onto which to store the result. If this parameter is - * not specified, a new instance is created and returned. - * @returns {Matrix3} The rotation matrix, or undefined if the data necessary to do the - * transformation is not yet loaded. - * - * - * @example - * scene.preRender.addEventListener(function(scene, time) { - * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); - * if (Cesium.defined(icrfToFixed)) { - * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); - * var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed) - * var inverseTransform = Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()); - * Cesium.Matrix4.multiplyByPoint(inverseTransform, offset, offset); - * camera.lookAtTransform(transform, offset); - * } - * }); - * - * @see Transforms.preloadIcrfFixed - */ - Transforms.computeIcrfToFixedMatrix = function(date, result) { - if (!defined(date)) { - throw new DeveloperError('date is required.'); - } - if (!defined(result)) { - result = new Matrix3(); - } + //This validation is only applicable for this format. + if (dayOfYear < 1 || (inLeapYear && dayOfYear > 366) || (!inLeapYear && dayOfYear > 365)) { + throw new DeveloperError(iso8601ErrorMessage); + } + } else { + tokens = date.match(matchWeekDate); + if (tokens !== null) { + //ISO week date to ordinal date from + //http://en.wikipedia.org/w/index.php?title=ISO_week_date&oldid=474176775 + year = +tokens[1]; + var weekNumber = +tokens[2]; + var dayOfWeek = +tokens[3] || 0; - var fixedToIcrfMtx = Transforms.computeFixedToIcrfMatrix(date, result); - if (!defined(fixedToIcrfMtx)) { - return undefined; + dashCount = date.split('-').length - 1; + if (dashCount > 0 && + ((!defined(tokens[3]) && dashCount !== 1) || + (defined(tokens[3]) && dashCount !== 2))) { + throw new DeveloperError(iso8601ErrorMessage); + } + + var january4 = new Date(Date.UTC(year, 0, 4)); + dayOfYear = (weekNumber * 7) + dayOfWeek - january4.getUTCDay() - 3; + } else { + //None of our regular expressions succeeded in parsing the date properly. + throw new DeveloperError(iso8601ErrorMessage); + } + } + //Split an ordinal date into month/day. + tmp = new Date(Date.UTC(year, 0, 1)); + tmp.setUTCDate(dayOfYear); + month = tmp.getUTCMonth() + 1; + day = tmp.getUTCDate(); + } + } } - return Matrix3.transpose(fixedToIcrfMtx, result); - }; - - var xysScratch = new Iau2006XysSample(0.0, 0.0, 0.0); - var eopScratch = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - var rotation1Scratch = new Matrix3(); - var rotation2Scratch = new Matrix3(); - - /** - * Computes a rotation matrix to transform a point or vector from the Earth-Fixed frame axes (ITRF) - * to the International Celestial Reference Frame (GCRF/ICRF) inertial frame axes - * at a given time. This function may return undefined if the data necessary to - * do the transformation is not yet loaded. - * - * @param {JulianDate} date The time at which to compute the rotation matrix. - * @param {Matrix3} [result] The object onto which to store the result. If this parameter is - * not specified, a new instance is created and returned. - * @returns {Matrix3} The rotation matrix, or undefined if the data necessary to do the - * transformation is not yet loaded. - * - * - * @example - * // Transform a point from the ICRF axes to the Fixed axes. - * var now = Cesium.JulianDate.now(); - * var pointInFixed = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var fixedToIcrf = Cesium.Transforms.computeIcrfToFixedMatrix(now); - * var pointInInertial = new Cesium.Cartesian3(); - * if (Cesium.defined(fixedToIcrf)) { - * pointInInertial = Cesium.Matrix3.multiplyByVector(fixedToIcrf, pointInFixed, pointInInertial); - * } - * - * @see Transforms.preloadIcrfFixed - */ - Transforms.computeFixedToIcrfMatrix = function(date, result) { - if (!defined(date)) { - throw new DeveloperError('date is required.'); + //Now that we have all of the date components, validate them to make sure nothing is out of range. + inLeapYear = isLeapYear(year); + if (month < 1 || month > 12 || day < 1 || ((month !== 2 || !inLeapYear) && day > daysInMonth[month - 1]) || (inLeapYear && month === 2 && day > daysInLeapFeburary)) { + throw new DeveloperError(iso8601ErrorMessage); } - if (!defined(result)) { - result = new Matrix3(); + //Now move onto the time string, which is much simpler. + //If no time is specified, it is considered the beginning of the day, UTC to match Javascript's implementation. + var offsetIndex; + if (defined(time)) { + tokens = time.match(matchHoursMinutesSeconds); + if (tokens !== null) { + dashCount = time.split(':').length - 1; + if (dashCount > 0 && dashCount !== 2 && dashCount !== 3) { + throw new DeveloperError(iso8601ErrorMessage); + } + + hour = +tokens[1]; + minute = +tokens[2]; + second = +tokens[3]; + millisecond = +(tokens[4] || 0) * 1000.0; + offsetIndex = 5; + } else { + tokens = time.match(matchHoursMinutes); + if (tokens !== null) { + dashCount = time.split(':').length - 1; + if (dashCount > 2) { + throw new DeveloperError(iso8601ErrorMessage); + } + + hour = +tokens[1]; + minute = +tokens[2]; + second = +(tokens[3] || 0) * 60.0; + offsetIndex = 4; + } else { + tokens = time.match(matchHours); + if (tokens !== null) { + hour = +tokens[1]; + minute = +(tokens[2] || 0) * 60.0; + offsetIndex = 3; + } else { + throw new DeveloperError(iso8601ErrorMessage); + } + } + } + + //Validate that all values are in proper range. Minutes and hours have special cases at 60 and 24. + if (minute >= 60 || second >= 61 || hour > 24 || (hour === 24 && (minute > 0 || second > 0 || millisecond > 0))) { + throw new DeveloperError(iso8601ErrorMessage); + } + + //Check the UTC offset value, if no value exists, use local time + //a Z indicates UTC, + or - are offsets. + var offset = tokens[offsetIndex]; + var offsetHours = +(tokens[offsetIndex + 1]); + var offsetMinutes = +(tokens[offsetIndex + 2] || 0); + switch (offset) { + case '+': + hour = hour - offsetHours; + minute = minute - offsetMinutes; + break; + case '-': + hour = hour + offsetHours; + minute = minute + offsetMinutes; + break; + case 'Z': + break; + default: + minute = minute + new Date(Date.UTC(year, month - 1, day, hour, minute)).getTimezoneOffset(); + break; + } } - // Compute pole wander - var eop = Transforms.earthOrientationParameters.compute(date, eopScratch); - if (!defined(eop)) { - return undefined; + //ISO8601 denotes a leap second by any time having a seconds component of 60 seconds. + //If that's the case, we need to temporarily subtract a second in order to build a UTC date. + //Then we add it back in after converting to TAI. + var isLeapSecond = second === 60; + if (isLeapSecond) { + second--; } - // There is no external conversion to Terrestrial Time (TT). - // So use International Atomic Time (TAI) and convert using offsets. - // Here we are assuming that dayTT and secondTT are positive - var dayTT = date.dayNumber; - // It's possible here that secondTT could roll over 86400 - // This does not seem to affect the precision (unit tests check for this) - var secondTT = date.secondsOfDay + ttMinusTai; + //Even if we successfully parsed the string into its components, after applying UTC offset or + //special cases like 24:00:00 denoting midnight, we need to normalize the data appropriately. - var xys = Transforms.iau2006XysData.computeXysRadians(dayTT, secondTT, xysScratch); - if (!defined(xys)) { - return undefined; + //milliseconds can never be greater than 1000, and seconds can't be above 60, so we start with minutes + while (minute >= 60) { + minute -= 60; + hour++; } - var x = xys.x + eop.xPoleOffset; - var y = xys.y + eop.yPoleOffset; - - // Compute XYS rotation - var a = 1.0 / (1.0 + Math.sqrt(1.0 - x * x - y * y)); + while (hour >= 24) { + hour -= 24; + day++; + } - var rotation1 = rotation1Scratch; - rotation1[0] = 1.0 - a * x * x; - rotation1[3] = -a * x * y; - rotation1[6] = x; - rotation1[1] = -a * x * y; - rotation1[4] = 1 - a * y * y; - rotation1[7] = y; - rotation1[2] = -x; - rotation1[5] = -y; - rotation1[8] = 1 - a * (x * x + y * y); + tmp = (inLeapYear && month === 2) ? daysInLeapFeburary : daysInMonth[month - 1]; + while (day > tmp) { + day -= tmp; + month++; - var rotation2 = Matrix3.fromRotationZ(-xys.s, rotation2Scratch); - var matrixQ = Matrix3.multiply(rotation1, rotation2, rotation1Scratch); + if (month > 12) { + month -= 12; + year++; + } - // Similar to TT conversions above - // It's possible here that secondTT could roll over 86400 - // This does not seem to affect the precision (unit tests check for this) - var dateUt1day = date.dayNumber; - var dateUt1sec = date.secondsOfDay - JulianDate.computeTaiMinusUtc(date) + eop.ut1MinusUtc; + tmp = (inLeapYear && month === 2) ? daysInLeapFeburary : daysInMonth[month - 1]; + } - // Compute Earth rotation angle - // The IERS standard for era is - // era = 0.7790572732640 + 1.00273781191135448 * Tu - // where - // Tu = JulianDateInUt1 - 2451545.0 - // However, you get much more precision if you make the following simplification - // era = a + (1 + b) * (JulianDayNumber + FractionOfDay - 2451545) - // era = a + (JulianDayNumber - 2451545) + FractionOfDay + b (JulianDayNumber - 2451545 + FractionOfDay) - // era = a + FractionOfDay + b (JulianDayNumber - 2451545 + FractionOfDay) - // since (JulianDayNumber - 2451545) represents an integer number of revolutions which will be discarded anyway. - var daysSinceJ2000 = dateUt1day - 2451545; - var fractionOfDay = dateUt1sec / TimeConstants.SECONDS_PER_DAY; - var era = 0.7790572732640 + fractionOfDay + 0.00273781191135448 * (daysSinceJ2000 + fractionOfDay); - era = (era % 1.0) * CesiumMath.TWO_PI; + //If UTC offset is at the beginning/end of the day, minutes can be negative. + while (minute < 0) { + minute += 60; + hour--; + } - var earthRotation = Matrix3.fromRotationZ(era, rotation2Scratch); + while (hour < 0) { + hour += 24; + day--; + } - // pseudoFixed to ICRF - var pfToIcrf = Matrix3.multiply(matrixQ, earthRotation, rotation1Scratch); + while (day < 1) { + month--; + if (month < 1) { + month += 12; + year--; + } - // Compute pole wander matrix - var cosxp = Math.cos(eop.xPoleWander); - var cosyp = Math.cos(eop.yPoleWander); - var sinxp = Math.sin(eop.xPoleWander); - var sinyp = Math.sin(eop.yPoleWander); + tmp = (inLeapYear && month === 2) ? daysInLeapFeburary : daysInMonth[month - 1]; + day += tmp; + } - var ttt = (dayTT - j2000ttDays) + secondTT / TimeConstants.SECONDS_PER_DAY; - ttt /= 36525.0; + //Now create the JulianDate components from the Gregorian date and actually create our instance. + var components = computeJulianDateComponents(year, month, day, hour, minute, second, millisecond); - // approximate sp value in rad - var sp = -47.0e-6 * ttt * CesiumMath.RADIANS_PER_DEGREE / 3600.0; - var cossp = Math.cos(sp); - var sinsp = Math.sin(sp); + if (!defined(result)) { + result = new JulianDate(components[0], components[1], TimeStandard.UTC); + } else { + setComponents(components[0], components[1], result); + convertUtcToTai(result); + } - var fToPfMtx = rotation2Scratch; - fToPfMtx[0] = cosxp * cossp; - fToPfMtx[1] = cosxp * sinsp; - fToPfMtx[2] = sinxp; - fToPfMtx[3] = -cosyp * sinsp + sinyp * sinxp * cossp; - fToPfMtx[4] = cosyp * cossp + sinyp * sinxp * sinsp; - fToPfMtx[5] = -sinyp * cosxp; - fToPfMtx[6] = -sinyp * sinsp - cosyp * sinxp * cossp; - fToPfMtx[7] = sinyp * cossp - cosyp * sinxp * sinsp; - fToPfMtx[8] = cosyp * cosxp; + //If we were on a leap second, add it back. + if (isLeapSecond) { + JulianDate.addSeconds(result, 1, result); + } - return Matrix3.multiply(pfToIcrf, fToPfMtx, result); + return result; }; - var pointToWindowCoordinatesTemp = new Cartesian4(); - /** - * Transform a point from model coordinates to window coordinates. + * Creates a new instance that represents the current system time. + * This is equivalent to calling <code>JulianDate.fromDate(new Date());</code>. * - * @param {Matrix4} modelViewProjectionMatrix The 4x4 model-view-projection matrix. - * @param {Matrix4} viewportTransformation The 4x4 viewport transformation. - * @param {Cartesian3} point The point to transform. - * @param {Cartesian2} [result] The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. + * @param {JulianDate} [result] An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter or a new instance if none was provided. */ - Transforms.pointToWindowCoordinates = function (modelViewProjectionMatrix, viewportTransformation, point, result) { - result = Transforms.pointToGLWindowCoordinates(modelViewProjectionMatrix, viewportTransformation, point, result); - result.y = 2.0 * viewportTransformation[5] - result.y; - return result; + JulianDate.now = function(result) { + return JulianDate.fromDate(new Date(), result); }; + var toGregorianDateScratch = new JulianDate(0, 0, TimeStandard.TAI); + /** - * @private + * Creates a {@link GregorianDate} from the provided instance. + * + * @param {JulianDate} julianDate The date to be converted. + * @param {GregorianDate} [result] An existing instance to use for the result. + * @returns {GregorianDate} The modified result parameter or a new instance if none was provided. */ - Transforms.pointToGLWindowCoordinates = function(modelViewProjectionMatrix, viewportTransformation, point, result) { - if (!defined(modelViewProjectionMatrix)) { - throw new DeveloperError('modelViewProjectionMatrix is required.'); - } - - if (!defined(viewportTransformation)) { - throw new DeveloperError('viewportTransformation is required.'); - } - - if (!defined(point)) { - throw new DeveloperError('point is required.'); + JulianDate.toGregorianDate = function(julianDate, result) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } - if (!defined(result)) { - result = new Cartesian2(); + var isLeapSecond = false; + var thisUtc = convertTaiToUtc(julianDate, toGregorianDateScratch); + if (!defined(thisUtc)) { + //Conversion to UTC will fail if we are during a leap second. + //If that's the case, subtract a second and convert again. + //JavaScript doesn't support leap seconds, so this results in second 59 being repeated twice. + JulianDate.addSeconds(julianDate, -1, toGregorianDateScratch); + thisUtc = convertTaiToUtc(toGregorianDateScratch, toGregorianDateScratch); + isLeapSecond = true; } - var tmp = pointToWindowCoordinatesTemp; + var julianDayNumber = thisUtc.dayNumber; + var secondsOfDay = thisUtc.secondsOfDay; - Matrix4.multiplyByVector(modelViewProjectionMatrix, Cartesian4.fromElements(point.x, point.y, point.z, 1, tmp), tmp); - Cartesian4.multiplyByScalar(tmp, 1.0 / tmp.w, tmp); - Matrix4.multiplyByVector(viewportTransformation, tmp, tmp); - return Cartesian2.fromCartesian4(tmp, result); - }; + if (secondsOfDay >= 43200.0) { + julianDayNumber += 1; + } - var normalScratch = new Cartesian3(); - var rightScratch = new Cartesian3(); - var upScratch = new Cartesian3(); + // Algorithm from page 604 of the Explanatory Supplement to the + // Astronomical Almanac (Seidelmann 1992). + var L = (julianDayNumber + 68569) | 0; + var N = (4 * L / 146097) | 0; + L = (L - (((146097 * N + 3) / 4) | 0)) | 0; + var I = ((4000 * (L + 1)) / 1461001) | 0; + L = (L - (((1461 * I) / 4) | 0) + 31) | 0; + var J = ((80 * L) / 2447) | 0; + var day = (L - (((2447 * J) / 80) | 0)) | 0; + L = (J / 11) | 0; + var month = (J + 2 - 12 * L) | 0; + var year = (100 * (N - 49) + I + L) | 0; - /** - * @private - */ - Transforms.rotationMatrixFromPositionVelocity = function(position, velocity, ellipsoid, result) { - if (!defined(position)) { - throw new DeveloperError('position is required.'); - } + var hour = (secondsOfDay / TimeConstants.SECONDS_PER_HOUR) | 0; + var remainingSeconds = secondsOfDay - (hour * TimeConstants.SECONDS_PER_HOUR); + var minute = (remainingSeconds / TimeConstants.SECONDS_PER_MINUTE) | 0; + remainingSeconds = remainingSeconds - (minute * TimeConstants.SECONDS_PER_MINUTE); + var second = remainingSeconds | 0; + var millisecond = ((remainingSeconds - second) / TimeConstants.SECONDS_PER_MILLISECOND); - if (!defined(velocity)) { - throw new DeveloperError('velocity is required.'); - } - - var normal = defaultValue(ellipsoid, Ellipsoid.WGS84).geodeticSurfaceNormal(position, normalScratch); - var right = Cartesian3.cross(velocity, normal, rightScratch); - if (Cartesian3.equalsEpsilon(right, Cartesian3.ZERO, CesiumMath.EPSILON6)) { - right = Cartesian3.clone(Cartesian3.UNIT_X, right); + // JulianDates are noon-based + hour += 12; + if (hour > 23) { + hour -= 24; } - var up = Cartesian3.cross(right, velocity, upScratch); - Cartesian3.cross(velocity, up, right); - Cartesian3.negate(right, right); + //If we were on a leap second, add it back. + if (isLeapSecond) { + second += 1; + } if (!defined(result)) { - result = new Matrix3(); + return new GregorianDate(year, month, day, hour, minute, second, millisecond, isLeapSecond); } - result[0] = velocity.x; - result[1] = velocity.y; - result[2] = velocity.z; - result[3] = right.x; - result[4] = right.y; - result[5] = right.z; - result[6] = up.x; - result[7] = up.y; - result[8] = up.z; - + result.year = year; + result.month = month; + result.day = day; + result.hour = hour; + result.minute = minute; + result.second = second; + result.millisecond = millisecond; + result.isLeapSecond = isLeapSecond; return result; }; - var swizzleMatrix = new Matrix4( - 0.0, 0.0, 1.0, 0.0, - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ); - - var scratchCartographic = new Cartographic(); - var scratchCartesian3Projection = new Cartesian3(); - var scratchCenter = new Cartesian3(); - var scratchRotation = new Matrix3(); - var scratchFromENU = new Matrix4(); - var scratchToENU = new Matrix4(); - /** - * @private + * Creates a JavaScript Date from the provided instance. + * Since JavaScript dates are only accurate to the nearest millisecond and + * cannot represent a leap second, consider using {@link JulianDate.toGregorianDate} instead. + * If the provided JulianDate is during a leap second, the previous second is used. + * + * @param {JulianDate} julianDate The date to be converted. + * @returns {Date} A new instance representing the provided date. */ - Transforms.basisTo2D = function(projection, matrix, result) { - if (!defined(projection)) { - throw new DeveloperError('projection is required.'); + JulianDate.toDate = function(julianDate) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } - if (!defined(matrix)) { - throw new DeveloperError('matrix is required.'); + + var gDate = JulianDate.toGregorianDate(julianDate, gregorianDateScratch); + var second = gDate.second; + if (gDate.isLeapSecond) { + second -= 1; } - if (!defined(result)) { - throw new DeveloperError('result is required.'); + return new Date(Date.UTC(gDate.year, gDate.month - 1, gDate.day, gDate.hour, gDate.minute, second, gDate.millisecond)); + }; + + /** + * Creates an ISO8601 representation of the provided date. + * + * @param {JulianDate} julianDate The date to be converted. + * @param {Number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. + * @returns {String} The ISO8601 representation of the provided date. + */ + JulianDate.toIso8601 = function(julianDate, precision) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } - var rtcCenter = Matrix4.getTranslation(matrix, scratchCenter); - var ellipsoid = projection.ellipsoid; + var gDate = JulianDate.toGregorianDate(julianDate, gregorianDateScratch); + var millisecondStr; - // Get the 2D Center - var cartographic = ellipsoid.cartesianToCartographic(rtcCenter, scratchCartographic); - var projectedPosition = projection.project(cartographic, scratchCartesian3Projection); - Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, projectedPosition); + if (!defined(precision) && gDate.millisecond !== 0) { + //Forces milliseconds into a number with at least 3 digits to whatever the default toString() precision is. + millisecondStr = (gDate.millisecond * 0.01).toString().replace('.', ''); + return sprintf('%04d-%02d-%02dT%02d:%02d:%02d.%sZ', gDate.year, gDate.month, gDate.day, gDate.hour, gDate.minute, gDate.second, millisecondStr); + } - // Assuming the instance are positioned in WGS84, invert the WGS84 transform to get the local transform and then convert to 2D - var fromENU = Transforms.eastNorthUpToFixedFrame(rtcCenter, ellipsoid, scratchFromENU); - var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU); - var rotation = Matrix4.getRotation(matrix, scratchRotation); - var local = Matrix4.multiplyByMatrix3(toENU, rotation, result); - Matrix4.multiply(swizzleMatrix, local, result); // Swap x, y, z for 2D - Matrix4.setTranslation(result, projectedPosition, result); // Use the projected center + //Precision is either 0 or milliseconds is 0 with undefined precision, in either case, leave off milliseconds entirely + if (!defined(precision) || precision === 0) { + return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ', gDate.year, gDate.month, gDate.day, gDate.hour, gDate.minute, gDate.second); + } - return result; + //Forces milliseconds into a number with at least 3 digits to whatever the specified precision is. + millisecondStr = (gDate.millisecond * 0.01).toFixed(precision).replace('.', '').slice(0, precision); + return sprintf('%04d-%02d-%02dT%02d:%02d:%02d.%sZ', gDate.year, gDate.month, gDate.day, gDate.hour, gDate.minute, gDate.second, millisecondStr); }; /** - * @private + * Duplicates a JulianDate instance. + * + * @param {JulianDate} julianDate The date to duplicate. + * @param {JulianDate} [result] An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter or a new instance if none was provided. Returns undefined if julianDate is undefined. */ - Transforms.wgs84To2DModelMatrix = function(projection, center, result) { - if (!defined(projection)) { - throw new DeveloperError('projection is required.'); - } - if (!defined(center)) { - throw new DeveloperError('center is required.'); + JulianDate.clone = function(julianDate, result) { + if (!defined(julianDate)) { + return undefined; } if (!defined(result)) { - throw new DeveloperError('result is required.'); + return new JulianDate(julianDate.dayNumber, julianDate.secondsOfDay, TimeStandard.TAI); } - - var ellipsoid = projection.ellipsoid; - - var fromENU = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, scratchFromENU); - var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU); - - var cartographic = ellipsoid.cartesianToCartographic(center, scratchCartographic); - var projectedPosition = projection.project(cartographic, scratchCartesian3Projection); - Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, projectedPosition); - - var translation = Matrix4.fromTranslation(projectedPosition, scratchFromENU); - Matrix4.multiply(swizzleMatrix, toENU, result); - Matrix4.multiply(translation, result, result); - + result.dayNumber = julianDate.dayNumber; + result.secondsOfDay = julianDate.secondsOfDay; return result; }; - return Transforms; -}); - -define('Core/EllipsoidTangentPlane',[ - './AxisAlignedBoundingBox', - './Cartesian2', - './Cartesian3', - './Cartesian4', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid', - './IntersectionTests', - './Matrix4', - './Plane', - './Ray', - './Transforms' - ], function( - AxisAlignedBoundingBox, - Cartesian2, - Cartesian3, - Cartesian4, - defaultValue, - defined, - defineProperties, - DeveloperError, - Ellipsoid, - IntersectionTests, - Matrix4, - Plane, - Ray, - Transforms) { - 'use strict'; - - var scratchCart4 = new Cartesian4(); /** - * A plane tangent to the provided ellipsoid at the provided origin. - * If origin is not on the surface of the ellipsoid, it's surface projection will be used. - * If origin is at the center of the ellipsoid, an exception will be thrown. - * @alias EllipsoidTangentPlane - * @constructor - * - * @param {Cartesian3} origin The point on the surface of the ellipsoid where the tangent plane touches. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use. + * Compares two instances. * - * @exception {DeveloperError} origin must not be at the center of the ellipsoid. + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Number} A negative value if left is less than right, a positive value if left is greater than right, or zero if left and right are equal. */ - function EllipsoidTangentPlane(origin, ellipsoid) { - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); + JulianDate.compare = function(left, right) { + if (!defined(left)) { + throw new DeveloperError('left is required.'); } - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - origin = ellipsoid.scaleToGeodeticSurface(origin); - - if (!defined(origin)) { - throw new DeveloperError('origin must not be at the center of the ellipsoid.'); + if (!defined(right)) { + throw new DeveloperError('right is required.'); } - var eastNorthUp = Transforms.eastNorthUpToFixedFrame(origin, ellipsoid); - this._ellipsoid = ellipsoid; - this._origin = origin; - this._xAxis = Cartesian3.fromCartesian4(Matrix4.getColumn(eastNorthUp, 0, scratchCart4)); - this._yAxis = Cartesian3.fromCartesian4(Matrix4.getColumn(eastNorthUp, 1, scratchCart4)); - - var normal = Cartesian3.fromCartesian4(Matrix4.getColumn(eastNorthUp, 2, scratchCart4)); - this._plane = Plane.fromPointNormal(origin, normal); - } - - defineProperties(EllipsoidTangentPlane.prototype, { - /** - * Gets the ellipsoid. - * @memberof EllipsoidTangentPlane.prototype - * @type {Ellipsoid} - */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } - }, - - /** - * Gets the origin. - * @memberof EllipsoidTangentPlane.prototype - * @type {Cartesian3} - */ - origin : { - get : function() { - return this._origin; - } - }, - - /** - * Gets the plane which is tangent to the ellipsoid. - * @memberof EllipsoidTangentPlane.prototype - * @readonly - * @type {Plane} - */ - plane : { - get : function() { - return this._plane; - } - }, - - /** - * Gets the local X-axis (east) of the tangent plane. - * @memberof EllipsoidTangentPlane.prototype - * @readonly - * @type {Cartesian3} - */ - xAxis : { - get : function() { - return this._xAxis; - } - }, - - /** - * Gets the local Y-axis (north) of the tangent plane. - * @memberof EllipsoidTangentPlane.prototype - * @readonly - * @type {Cartesian3} - */ - yAxis : { - get : function() { - return this._yAxis; - } - }, - - /** - * Gets the local Z-axis (up) of the tangent plane. - * @member EllipsoidTangentPlane.prototype - * @readonly - * @type {Cartesian3} - */ - zAxis : { - get : function() { - return this._plane.normal; - } + var julianDayNumberDifference = left.dayNumber - right.dayNumber; + if (julianDayNumberDifference !== 0) { + return julianDayNumberDifference; } - }); + return left.secondsOfDay - right.secondsOfDay; + }; - var tmp = new AxisAlignedBoundingBox(); /** - * Creates a new instance from the provided ellipsoid and the center - * point of the provided Cartesians. + * Compares two instances and returns <code>true</code> if they are equal, <code>false</code> otherwise. * - * @param {Ellipsoid} ellipsoid The ellipsoid to use. - * @param {Cartesian3} cartesians The list of positions surrounding the center point. + * @param {JulianDate} [left] The first instance. + * @param {JulianDate} [right] The second instance. + * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. */ - EllipsoidTangentPlane.fromPoints = function(cartesians, ellipsoid) { - if (!defined(cartesians)) { - throw new DeveloperError('cartesians is required.'); - } - - var box = AxisAlignedBoundingBox.fromPoints(cartesians, tmp); - return new EllipsoidTangentPlane(box.center, ellipsoid); + JulianDate.equals = function(left, right) { + return (left === right) || + (defined(left) && + defined(right) && + left.dayNumber === right.dayNumber && + left.secondsOfDay === right.secondsOfDay); }; - var scratchProjectPointOntoPlaneRay = new Ray(); - var scratchProjectPointOntoPlaneCartesian3 = new Cartesian3(); - /** - * Computes the projection of the provided 3D position onto the 2D plane, radially outward from the {@link EllipsoidTangentPlane.ellipsoid} coordinate system origin. + * Compares two instances and returns <code>true</code> if they are within <code>epsilon</code> seconds of + * each other. That is, in order for the dates to be considered equal (and for + * this function to return <code>true</code>), the absolute value of the difference between them, in + * seconds, must be less than <code>epsilon</code>. * - * @param {Cartesian3} cartesian The point to project. - * @param {Cartesian2} [result] The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. Undefined if there is no intersection point + * @param {JulianDate} [left] The first instance. + * @param {JulianDate} [right] The second instance. + * @param {Number} epsilon The maximum number of seconds that should separate the two instances. + * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. */ - EllipsoidTangentPlane.prototype.projectPointOntoPlane = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); + JulianDate.equalsEpsilon = function(left, right, epsilon) { + if (!defined(epsilon)) { + throw new DeveloperError('epsilon is required.'); } - var ray = scratchProjectPointOntoPlaneRay; - ray.origin = cartesian; - Cartesian3.normalize(cartesian, ray.direction); + return (left === right) || + (defined(left) && + defined(right) && + Math.abs(JulianDate.secondsDifference(left, right)) <= epsilon); + }; - var intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); - if (!defined(intersectionPoint)) { - Cartesian3.negate(ray.direction, ray.direction); - intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); + /** + * Computes the total number of whole and fractional days represented by the provided instance. + * + * @param {JulianDate} julianDate The date. + * @returns {Number} The Julian date as single floating point number. + */ + JulianDate.totalDays = function(julianDate) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } + return julianDate.dayNumber + (julianDate.secondsOfDay / TimeConstants.SECONDS_PER_DAY); + }; - if (defined(intersectionPoint)) { - var v = Cartesian3.subtract(intersectionPoint, this._origin, intersectionPoint); - var x = Cartesian3.dot(this._xAxis, v); - var y = Cartesian3.dot(this._yAxis, v); - - if (!defined(result)) { - return new Cartesian2(x, y); - } - result.x = x; - result.y = y; - return result; + /** + * Computes the difference in seconds between the provided instance. + * + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Number} The difference, in seconds, when subtracting <code>right</code> from <code>left</code>. + */ + JulianDate.secondsDifference = function(left, right) { + if (!defined(left)) { + throw new DeveloperError('left is required.'); } - return undefined; + if (!defined(right)) { + throw new DeveloperError('right is required.'); + } + + var dayDifference = (left.dayNumber - right.dayNumber) * TimeConstants.SECONDS_PER_DAY; + return (dayDifference + (left.secondsOfDay - right.secondsOfDay)); }; /** - * Computes the projection of the provided 3D positions onto the 2D plane (where possible), radially outward from the global origin. - * The resulting array may be shorter than the input array - if a single projection is impossible it will not be included. - * - * @see EllipsoidTangentPlane.projectPointOntoPlane + * Computes the difference in days between the provided instance. * - * @param {Cartesian3[]} cartesians The array of points to project. - * @param {Cartesian2[]} [result] The array of Cartesian2 instances onto which to store results. - * @returns {Cartesian2[]} The modified result parameter or a new array of Cartesian2 instances if none was provided. + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Number} The difference, in days, when subtracting <code>right</code> from <code>left</code>. */ - EllipsoidTangentPlane.prototype.projectPointsOntoPlane = function(cartesians, result) { - if (!defined(cartesians)) { - throw new DeveloperError('cartesians is required.'); + JulianDate.daysDifference = function(left, right) { + if (!defined(left)) { + throw new DeveloperError('left is required.'); } - - if (!defined(result)) { - result = []; + if (!defined(right)) { + throw new DeveloperError('right is required.'); } + + var dayDifference = (left.dayNumber - right.dayNumber); + var secondDifference = (left.secondsOfDay - right.secondsOfDay) / TimeConstants.SECONDS_PER_DAY; + return dayDifference + secondDifference; + }; - var count = 0; - var length = cartesians.length; - for ( var i = 0; i < length; i++) { - var p = this.projectPointOntoPlane(cartesians[i], result[count]); - if (defined(p)) { - result[count] = p; - count++; + /** + * Computes the number of seconds the provided instance is ahead of UTC. + * + * @param {JulianDate} julianDate The date. + * @returns {Number} The number of seconds the provided instance is ahead of UTC + */ + JulianDate.computeTaiMinusUtc = function(julianDate) { + binarySearchScratchLeapSecond.julianDate = julianDate; + var leapSeconds = JulianDate.leapSeconds; + var index = binarySearch(leapSeconds, binarySearchScratchLeapSecond, compareLeapSecondDates); + if (index < 0) { + index = ~index; + --index; + if (index < 0) { + index = 0; } } - result.length = count; - return result; + return leapSeconds[index].offset; }; /** - * Computes the projection of the provided 3D position onto the 2D plane, along the plane normal. + * Adds the provided number of seconds to the provided date instance. * - * @param {Cartesian3} cartesian The point to project. - * @param {Cartesian2} [result] The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. + * @param {JulianDate} julianDate The date. + * @param {Number} seconds The number of seconds to add or subtract. + * @param {JulianDate} result An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter. */ - EllipsoidTangentPlane.prototype.projectPointToNearestOnPlane = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); + JulianDate.addSeconds = function(julianDate, seconds, result) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } - - if (!defined(result)) { - result = new Cartesian2(); + if (!defined(seconds)) { + throw new DeveloperError('seconds is required.'); } - - var ray = scratchProjectPointOntoPlaneRay; - ray.origin = cartesian; - Cartesian3.clone(this._plane.normal, ray.direction); - - var intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); - if (!defined(intersectionPoint)) { - Cartesian3.negate(ray.direction, ray.direction); - intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); + if (!defined(result)) { + throw new DeveloperError('result is required.'); } - - var v = Cartesian3.subtract(intersectionPoint, this._origin, intersectionPoint); - var x = Cartesian3.dot(this._xAxis, v); - var y = Cartesian3.dot(this._yAxis, v); - - result.x = x; - result.y = y; - return result; + + return setComponents(julianDate.dayNumber, julianDate.secondsOfDay + seconds, result); }; /** - * Computes the projection of the provided 3D positions onto the 2D plane, along the plane normal. - * - * @see EllipsoidTangentPlane.projectPointToNearestOnPlane + * Adds the provided number of minutes to the provided date instance. * - * @param {Cartesian3[]} cartesians The array of points to project. - * @param {Cartesian2[]} [result] The array of Cartesian2 instances onto which to store results. - * @returns {Cartesian2[]} The modified result parameter or a new array of Cartesian2 instances if none was provided. This will have the same length as <code>cartesians</code>. + * @param {JulianDate} julianDate The date. + * @param {Number} minutes The number of minutes to add or subtract. + * @param {JulianDate} result An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter. */ - EllipsoidTangentPlane.prototype.projectPointsToNearestOnPlane = function(cartesians, result) { - if (!defined(cartesians)) { - throw new DeveloperError('cartesians is required.'); + JulianDate.addMinutes = function(julianDate, minutes, result) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } - - if (!defined(result)) { - result = []; + if (!defined(minutes)) { + throw new DeveloperError('minutes is required.'); } - - var length = cartesians.length; - result.length = length; - for (var i = 0; i < length; i++) { - result[i] = this.projectPointToNearestOnPlane(cartesians[i], result[i]); + if (!defined(result)) { + throw new DeveloperError('result is required.'); } - return result; + + var newSecondsOfDay = julianDate.secondsOfDay + (minutes * TimeConstants.SECONDS_PER_MINUTE); + return setComponents(julianDate.dayNumber, newSecondsOfDay, result); }; - var projectPointsOntoEllipsoidScratch = new Cartesian3(); /** - * Computes the projection of the provided 2D positions onto the 3D ellipsoid. + * Adds the provided number of hours to the provided date instance. * - * @param {Cartesian2[]} cartesians The array of points to project. - * @param {Cartesian3[]} [result] The array of Cartesian3 instances onto which to store results. - * @returns {Cartesian3[]} The modified result parameter or a new array of Cartesian3 instances if none was provided. + * @param {JulianDate} julianDate The date. + * @param {Number} hours The number of hours to add or subtract. + * @param {JulianDate} result An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter. */ - EllipsoidTangentPlane.prototype.projectPointsOntoEllipsoid = function(cartesians, result) { - if (!defined(cartesians)) { - throw new DeveloperError('cartesians is required.'); + JulianDate.addHours = function(julianDate, hours, result) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); + } + if (!defined(hours)) { + throw new DeveloperError('hours is required.'); } - - var length = cartesians.length; if (!defined(result)) { - result = new Array(length); - } else { - result.length = length; + throw new DeveloperError('result is required.'); } + + var newSecondsOfDay = julianDate.secondsOfDay + (hours * TimeConstants.SECONDS_PER_HOUR); + return setComponents(julianDate.dayNumber, newSecondsOfDay, result); + }; - var ellipsoid = this._ellipsoid; - var origin = this._origin; - var xAxis = this._xAxis; - var yAxis = this._yAxis; - var tmp = projectPointsOntoEllipsoidScratch; - - for ( var i = 0; i < length; ++i) { - var position = cartesians[i]; - Cartesian3.multiplyByScalar(xAxis, position.x, tmp); - if (!defined(result[i])) { - result[i] = new Cartesian3(); - } - var point = Cartesian3.add(origin, tmp, result[i]); - Cartesian3.multiplyByScalar(yAxis, position.y, tmp); - Cartesian3.add(point, tmp, point); - ellipsoid.scaleToGeocentricSurface(point, point); + /** + * Adds the provided number of days to the provided date instance. + * + * @param {JulianDate} julianDate The date. + * @param {Number} days The number of days to add or subtract. + * @param {JulianDate} result An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter. + */ + JulianDate.addDays = function(julianDate, days, result) { + if (!defined(julianDate)) { + throw new DeveloperError('julianDate is required.'); } - - return result; + if (!defined(days)) { + throw new DeveloperError('days is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var newJulianDayNumber = julianDate.dayNumber + days; + return setComponents(newJulianDayNumber, julianDate.secondsOfDay, result); }; - return EllipsoidTangentPlane; -}); - -define('Core/OrientedBoundingBox',[ - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './Cartographic', + /** + * Compares the provided instances and returns <code>true</code> if <code>left</code> is earlier than <code>right</code>, <code>false</code> otherwise. + * + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Boolean} <code>true</code> if <code>left</code> is earlier than <code>right</code>, <code>false</code> otherwise. + */ + JulianDate.lessThan = function(left, right) { + return JulianDate.compare(left, right) < 0; + }; + + /** + * Compares the provided instances and returns <code>true</code> if <code>left</code> is earlier than or equal to <code>right</code>, <code>false</code> otherwise. + * + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Boolean} <code>true</code> if <code>left</code> is earlier than or equal to <code>right</code>, <code>false</code> otherwise. + */ + JulianDate.lessThanOrEquals = function(left, right) { + return JulianDate.compare(left, right) <= 0; + }; + + /** + * Compares the provided instances and returns <code>true</code> if <code>left</code> is later than <code>right</code>, <code>false</code> otherwise. + * + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Boolean} <code>true</code> if <code>left</code> is later than <code>right</code>, <code>false</code> otherwise. + */ + JulianDate.greaterThan = function(left, right) { + return JulianDate.compare(left, right) > 0; + }; + + /** + * Compares the provided instances and returns <code>true</code> if <code>left</code> is later than or equal to <code>right</code>, <code>false</code> otherwise. + * + * @param {JulianDate} left The first instance. + * @param {JulianDate} right The second instance. + * @returns {Boolean} <code>true</code> if <code>left</code> is later than or equal to <code>right</code>, <code>false</code> otherwise. + */ + JulianDate.greaterThanOrEquals = function(left, right) { + return JulianDate.compare(left, right) >= 0; + }; + + /** + * Duplicates this instance. + * + * @param {JulianDate} [result] An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter or a new instance if none was provided. + */ + JulianDate.prototype.clone = function(result) { + return JulianDate.clone(this, result); + }; + + /** + * Compares this and the provided instance and returns <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {JulianDate} [right] The second instance. + * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. + */ + JulianDate.prototype.equals = function(right) { + return JulianDate.equals(this, right); + }; + + /** + * Compares this and the provided instance and returns <code>true</code> if they are within <code>epsilon</code> seconds of + * each other. That is, in order for the dates to be considered equal (and for + * this function to return <code>true</code>), the absolute value of the difference between them, in + * seconds, must be less than <code>epsilon</code>. + * + * @param {JulianDate} [right] The second instance. + * @param {Number} epsilon The maximum number of seconds that should separate the two instances. + * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. + */ + JulianDate.prototype.equalsEpsilon = function(right, epsilon) { + return JulianDate.equalsEpsilon(this, right, epsilon); + }; + + /** + * Creates a string representing this date in ISO8601 format. + * + * @returns {String} A string representing this date in ISO8601 format. + */ + JulianDate.prototype.toString = function() { + return JulianDate.toIso8601(this); + }; + + /** + * Gets or sets the list of leap seconds used throughout Cesium. + * @memberof JulianDate + * @type {LeapSecond[]} + */ + JulianDate.leapSeconds = [ + new LeapSecond(new JulianDate(2441317, 43210.0, TimeStandard.TAI), 10), // January 1, 1972 00:00:00 UTC + new LeapSecond(new JulianDate(2441499, 43211.0, TimeStandard.TAI), 11), // July 1, 1972 00:00:00 UTC + new LeapSecond(new JulianDate(2441683, 43212.0, TimeStandard.TAI), 12), // January 1, 1973 00:00:00 UTC + new LeapSecond(new JulianDate(2442048, 43213.0, TimeStandard.TAI), 13), // January 1, 1974 00:00:00 UTC + new LeapSecond(new JulianDate(2442413, 43214.0, TimeStandard.TAI), 14), // January 1, 1975 00:00:00 UTC + new LeapSecond(new JulianDate(2442778, 43215.0, TimeStandard.TAI), 15), // January 1, 1976 00:00:00 UTC + new LeapSecond(new JulianDate(2443144, 43216.0, TimeStandard.TAI), 16), // January 1, 1977 00:00:00 UTC + new LeapSecond(new JulianDate(2443509, 43217.0, TimeStandard.TAI), 17), // January 1, 1978 00:00:00 UTC + new LeapSecond(new JulianDate(2443874, 43218.0, TimeStandard.TAI), 18), // January 1, 1979 00:00:00 UTC + new LeapSecond(new JulianDate(2444239, 43219.0, TimeStandard.TAI), 19), // January 1, 1980 00:00:00 UTC + new LeapSecond(new JulianDate(2444786, 43220.0, TimeStandard.TAI), 20), // July 1, 1981 00:00:00 UTC + new LeapSecond(new JulianDate(2445151, 43221.0, TimeStandard.TAI), 21), // July 1, 1982 00:00:00 UTC + new LeapSecond(new JulianDate(2445516, 43222.0, TimeStandard.TAI), 22), // July 1, 1983 00:00:00 UTC + new LeapSecond(new JulianDate(2446247, 43223.0, TimeStandard.TAI), 23), // July 1, 1985 00:00:00 UTC + new LeapSecond(new JulianDate(2447161, 43224.0, TimeStandard.TAI), 24), // January 1, 1988 00:00:00 UTC + new LeapSecond(new JulianDate(2447892, 43225.0, TimeStandard.TAI), 25), // January 1, 1990 00:00:00 UTC + new LeapSecond(new JulianDate(2448257, 43226.0, TimeStandard.TAI), 26), // January 1, 1991 00:00:00 UTC + new LeapSecond(new JulianDate(2448804, 43227.0, TimeStandard.TAI), 27), // July 1, 1992 00:00:00 UTC + new LeapSecond(new JulianDate(2449169, 43228.0, TimeStandard.TAI), 28), // July 1, 1993 00:00:00 UTC + new LeapSecond(new JulianDate(2449534, 43229.0, TimeStandard.TAI), 29), // July 1, 1994 00:00:00 UTC + new LeapSecond(new JulianDate(2450083, 43230.0, TimeStandard.TAI), 30), // January 1, 1996 00:00:00 UTC + new LeapSecond(new JulianDate(2450630, 43231.0, TimeStandard.TAI), 31), // July 1, 1997 00:00:00 UTC + new LeapSecond(new JulianDate(2451179, 43232.0, TimeStandard.TAI), 32), // January 1, 1999 00:00:00 UTC + new LeapSecond(new JulianDate(2453736, 43233.0, TimeStandard.TAI), 33), // January 1, 2006 00:00:00 UTC + new LeapSecond(new JulianDate(2454832, 43234.0, TimeStandard.TAI), 34), // January 1, 2009 00:00:00 UTC + new LeapSecond(new JulianDate(2456109, 43235.0, TimeStandard.TAI), 35), // July 1, 2012 00:00:00 UTC + new LeapSecond(new JulianDate(2457204, 43236.0, TimeStandard.TAI), 36), // July 1, 2015 00:00:00 UTC + new LeapSecond(new JulianDate(2457754, 43237.0, TimeStandard.TAI), 37) // January 1, 2017 00:00:00 UTC + ]; + + return JulianDate; +}); + +define('Core/EarthOrientationParameters',[ + '../ThirdParty/when', + './binarySearch', './defaultValue', './defined', - './DeveloperError', - './Ellipsoid', - './EllipsoidTangentPlane', - './Intersect', - './Interval', - './Math', - './Matrix3', - './Plane', - './Rectangle' + './EarthOrientationParametersSample', + './freezeObject', + './JulianDate', + './LeapSecond', + './Resource', + './RuntimeError', + './TimeConstants', + './TimeStandard' ], function( - BoundingSphere, - Cartesian2, - Cartesian3, - Cartographic, + when, + binarySearch, defaultValue, defined, - DeveloperError, - Ellipsoid, - EllipsoidTangentPlane, - Intersect, - Interval, - CesiumMath, - Matrix3, - Plane, - Rectangle) { + EarthOrientationParametersSample, + freezeObject, + JulianDate, + LeapSecond, + Resource, + RuntimeError, + TimeConstants, + TimeStandard) { 'use strict'; /** - * Creates an instance of an OrientedBoundingBox. - * An OrientedBoundingBox of some object is a closed and convex cuboid. It can provide a tighter bounding volume than {@link BoundingSphere} or {@link AxisAlignedBoundingBox} in many cases. - * @alias OrientedBoundingBox - * @constructor + * Specifies Earth polar motion coordinates and the difference between UT1 and UTC. + * These Earth Orientation Parameters (EOP) are primarily used in the transformation from + * the International Celestial Reference Frame (ICRF) to the International Terrestrial + * Reference Frame (ITRF). * - * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. - * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 - * cube centered at the origin. + * @alias EarthOrientationParameters + * @constructor * + * @param {Object} [options] Object with the following properties: + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this + * parameter nor options.data is specified, all EOP values are assumed + * to be 0.0. If options.data is specified, this parameter is + * ignored. + * @param {Object} [options.data] The actual EOP data. If neither this + * parameter nor options.data is specified, all EOP values are assumed + * to be 0.0. + * @param {Boolean} [options.addNewLeapSeconds=true] True if leap seconds that + * are specified in the EOP data but not in {@link JulianDate.leapSeconds} + * should be added to {@link JulianDate.leapSeconds}. False if + * new leap seconds should be handled correctly in the context + * of the EOP data but otherwise ignored. * * @example - * // Create an OrientedBoundingBox using a transformation matrix, a position where the box will be translated, and a scale. - * var center = new Cesium.Cartesian3(1.0, 0.0, 0.0); - * var halfAxes = Cesium.Matrix3.fromScale(new Cesium.Cartesian3(1.0, 3.0, 2.0), new Cesium.Matrix3()); + * // An example EOP data file, EOP.json: + * { + * "columnNames" : ["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"], + * "samples" : [ + * "2011-07-01T00:00:00Z",55743.0,2.117957047295119e-7,2.111518721609984e-6,-0.2908948,-2.956e-4,3.393695767766752e-11,3.3452143996557983e-10,34.0, + * "2011-07-02T00:00:00Z",55744.0,2.193297093339541e-7,2.115460256837405e-6,-0.29065,-1.824e-4,-8.241832578862112e-11,5.623838700870617e-10,34.0, + * "2011-07-03T00:00:00Z",55745.0,2.262286080161428e-7,2.1191157519929706e-6,-0.2905572,1.9e-6,-3.490658503988659e-10,6.981317007977318e-10,34.0 + * ] + * } * - * var obb = new Cesium.OrientedBoundingBox(center, halfAxes); + * @example + * // Loading the EOP data + * var eop = new Cesium.EarthOrientationParameters({ url : 'Data/EOP.json' }); + * Cesium.Transforms.earthOrientationParameters = eop; * - * @see BoundingSphere - * @see BoundingRectangle + * @private */ - function OrientedBoundingBox(center, halfAxes) { - /** - * The center of the box. - * @type {Cartesian3} - * @default {@link Cartesian3.ZERO} - */ - this.center = Cartesian3.clone(defaultValue(center, Cartesian3.ZERO)); - /** - * The transformation matrix, to rotate the box to the right position. - * @type {Matrix3} - * @default {@link Matrix3.IDENTITY} - */ - this.halfAxes = Matrix3.clone(defaultValue(halfAxes, Matrix3.ZERO)); + function EarthOrientationParameters(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._dates = undefined; + this._samples = undefined; + + this._dateColumn = -1; + this._xPoleWanderRadiansColumn = -1; + this._yPoleWanderRadiansColumn = -1; + this._ut1MinusUtcSecondsColumn = -1; + this._xCelestialPoleOffsetRadiansColumn = -1; + this._yCelestialPoleOffsetRadiansColumn = -1; + this._taiMinusUtcSecondsColumn = -1; + + this._columnCount = 0; + this._lastIndex = -1; + + this._downloadPromise = undefined; + this._dataError = undefined; + + this._addNewLeapSeconds = defaultValue(options.addNewLeapSeconds, true); + + if (defined(options.data)) { + // Use supplied EOP data. + onDataReady(this, options.data); + } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + + // Download EOP data. + var that = this; + this._downloadPromise = when(resource.fetchJson(), function(eopData) { + onDataReady(that, eopData); + }, function() { + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; + }); + } else { + // Use all zeros for EOP data. + onDataReady(this, { + 'columnNames' : ['dateIso8601', 'modifiedJulianDateUtc', 'xPoleWanderRadians', 'yPoleWanderRadians', 'ut1MinusUtcSeconds', 'lengthOfDayCorrectionSeconds', 'xCelestialPoleOffsetRadians', 'yCelestialPoleOffsetRadians', 'taiMinusUtcSeconds'], + 'samples' : [] + }); + } } - var scratchCartesian1 = new Cartesian3(); - var scratchCartesian2 = new Cartesian3(); - var scratchCartesian3 = new Cartesian3(); - var scratchCartesian4 = new Cartesian3(); - var scratchCartesian5 = new Cartesian3(); - var scratchCartesian6 = new Cartesian3(); - var scratchCovarianceResult = new Matrix3(); - var scratchEigenResult = { - unitary : new Matrix3(), - diagonal : new Matrix3() + /** + * A default {@link EarthOrientationParameters} instance that returns zero for all EOP values. + */ + EarthOrientationParameters.NONE = freezeObject({ + getPromiseToLoad : function() { + return when(); + }, + compute : function(date, result) { + if (!defined(result)) { + result = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0); + } else { + result.xPoleWander = 0.0; + result.yPoleWander = 0.0; + result.xPoleOffset = 0.0; + result.yPoleOffset = 0.0; + result.ut1MinusUtc = 0.0; + } + return result; + } + }); + + /** + * Gets a promise that, when resolved, indicates that the EOP data has been loaded and is + * ready to use. + * + * @returns {Promise.<undefined>} The promise. + * + * @see when + */ + EarthOrientationParameters.prototype.getPromiseToLoad = function() { + return when(this._downloadPromise); }; /** - * Computes an instance of an OrientedBoundingBox of the given positions. - * This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis). - * Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf + * Computes the Earth Orientation Parameters (EOP) for a given date by interpolating. + * If the EOP data has not yet been download, this method returns undefined. * - * @param {Cartesian3[]} positions List of {@link Cartesian3} points that the bounding box will enclose. - * @param {OrientedBoundingBox} [result] The object onto which to store the result. - * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + * @param {JulianDate} date The date for each to evaluate the EOP. + * @param {EarthOrientationParametersSample} [result] The instance to which to copy the result. + * If this parameter is undefined, a new instance is created and returned. + * @returns {EarthOrientationParametersSample} The EOP evaluated at the given date, or + * undefined if the data necessary to evaluate EOP at the date has not yet been + * downloaded. * - * @example - * // Compute an object oriented bounding box enclosing two points. - * var box = Cesium.OrientedBoundingBox.fromPoints([new Cesium.Cartesian3(2, 0, 0), new Cesium.Cartesian3(-2, 0, 0)]); + * @exception {RuntimeError} The loaded EOP data has an error and cannot be used. + * + * @see EarthOrientationParameters#getPromiseToLoad */ - OrientedBoundingBox.fromPoints = function(positions, result) { + EarthOrientationParameters.prototype.compute = function(date, result) { + // We cannot compute until the samples are available. + if (!defined(this._samples)) { + if (defined(this._dataError)) { + throw new RuntimeError(this._dataError); + } + + return undefined; + } + if (!defined(result)) { - result = new OrientedBoundingBox(); + result = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0); } - if (!defined(positions) || positions.length === 0) { - result.halfAxes = Matrix3.ZERO; - result.center = Cartesian3.ZERO; + if (this._samples.length === 0) { + result.xPoleWander = 0.0; + result.yPoleWander = 0.0; + result.xPoleOffset = 0.0; + result.yPoleOffset = 0.0; + result.ut1MinusUtc = 0.0; return result; } - var i; - var length = positions.length; + var dates = this._dates; + var lastIndex = this._lastIndex; - var meanPoint = Cartesian3.clone(positions[0], scratchCartesian1); - for (i = 1; i < length; i++) { - Cartesian3.add(meanPoint, positions[i], meanPoint); - } - var invLength = 1.0 / length; - Cartesian3.multiplyByScalar(meanPoint, invLength, meanPoint); + var before = 0; + var after = 0; + if (defined(lastIndex)) { + var previousIndexDate = dates[lastIndex]; + var nextIndexDate = dates[lastIndex + 1]; + var isAfterPrevious = JulianDate.lessThanOrEquals(previousIndexDate, date); + var isAfterLastSample = !defined(nextIndexDate); + var isBeforeNext = isAfterLastSample || JulianDate.greaterThanOrEquals(nextIndexDate, date); - var exx = 0.0; - var exy = 0.0; - var exz = 0.0; - var eyy = 0.0; - var eyz = 0.0; - var ezz = 0.0; - var p; + if (isAfterPrevious && isBeforeNext) { + before = lastIndex; - for (i = 0; i < length; i++) { - p = Cartesian3.subtract(positions[i], meanPoint, scratchCartesian2); - exx += p.x * p.x; - exy += p.x * p.y; - exz += p.x * p.z; - eyy += p.y * p.y; - eyz += p.y * p.z; - ezz += p.z * p.z; + if (!isAfterLastSample && nextIndexDate.equals(date)) { + ++before; + } + after = before + 1; + + interpolate(this, dates, this._samples, date, before, after, result); + return result; + } } - exx *= invLength; - exy *= invLength; - exz *= invLength; - eyy *= invLength; - eyz *= invLength; - ezz *= invLength; + var index = binarySearch(dates, date, JulianDate.compare, this._dateColumn); + if (index >= 0) { + // If the next entry is the same date, use the later entry. This way, if two entries + // describe the same moment, one before a leap second and the other after, then we will use + // the post-leap second data. + if (index < dates.length - 1 && dates[index + 1].equals(date)) { + ++index; + } + before = index; + after = index; + } else { + after = ~index; + before = after - 1; - var covarianceMatrix = scratchCovarianceResult; - covarianceMatrix[0] = exx; - covarianceMatrix[1] = exy; - covarianceMatrix[2] = exz; - covarianceMatrix[3] = exy; - covarianceMatrix[4] = eyy; - covarianceMatrix[5] = eyz; - covarianceMatrix[6] = exz; - covarianceMatrix[7] = eyz; - covarianceMatrix[8] = ezz; + // Use the first entry if the date requested is before the beginning of the data. + if (before < 0) { + before = 0; + } + } - var eigenDecomposition = Matrix3.computeEigenDecomposition(covarianceMatrix, scratchEigenResult); - var rotation = Matrix3.clone(eigenDecomposition.unitary, result.halfAxes); + this._lastIndex = before; - var v1 = Matrix3.getColumn(rotation, 0, scratchCartesian4); - var v2 = Matrix3.getColumn(rotation, 1, scratchCartesian5); - var v3 = Matrix3.getColumn(rotation, 2, scratchCartesian6); + interpolate(this, dates, this._samples, date, before, after, result); + return result; + }; - var u1 = -Number.MAX_VALUE; - var u2 = -Number.MAX_VALUE; - var u3 = -Number.MAX_VALUE; - var l1 = Number.MAX_VALUE; - var l2 = Number.MAX_VALUE; - var l3 = Number.MAX_VALUE; + function compareLeapSecondDates(leapSecond, dateToFind) { + return JulianDate.compare(leapSecond.julianDate, dateToFind); + } - for (i = 0; i < length; i++) { - p = positions[i]; - u1 = Math.max(Cartesian3.dot(v1, p), u1); - u2 = Math.max(Cartesian3.dot(v2, p), u2); - u3 = Math.max(Cartesian3.dot(v3, p), u3); + function onDataReady(eop, eopData) { + if (!defined(eopData.columnNames)) { + eop._dataError = 'Error in loaded EOP data: The columnNames property is required.'; + return; + } - l1 = Math.min(Cartesian3.dot(v1, p), l1); - l2 = Math.min(Cartesian3.dot(v2, p), l2); - l3 = Math.min(Cartesian3.dot(v3, p), l3); + if (!defined(eopData.samples)) { + eop._dataError = 'Error in loaded EOP data: The samples property is required.'; + return; } - v1 = Cartesian3.multiplyByScalar(v1, 0.5 * (l1 + u1), v1); - v2 = Cartesian3.multiplyByScalar(v2, 0.5 * (l2 + u2), v2); - v3 = Cartesian3.multiplyByScalar(v3, 0.5 * (l3 + u3), v3); + var dateColumn = eopData.columnNames.indexOf('modifiedJulianDateUtc'); + var xPoleWanderRadiansColumn = eopData.columnNames.indexOf('xPoleWanderRadians'); + var yPoleWanderRadiansColumn = eopData.columnNames.indexOf('yPoleWanderRadians'); + var ut1MinusUtcSecondsColumn = eopData.columnNames.indexOf('ut1MinusUtcSeconds'); + var xCelestialPoleOffsetRadiansColumn = eopData.columnNames.indexOf('xCelestialPoleOffsetRadians'); + var yCelestialPoleOffsetRadiansColumn = eopData.columnNames.indexOf('yCelestialPoleOffsetRadians'); + var taiMinusUtcSecondsColumn = eopData.columnNames.indexOf('taiMinusUtcSeconds'); - var center = Cartesian3.add(v1, v2, result.center); - Cartesian3.add(center, v3, center); + if (dateColumn < 0 || xPoleWanderRadiansColumn < 0 || yPoleWanderRadiansColumn < 0 || ut1MinusUtcSecondsColumn < 0 || xCelestialPoleOffsetRadiansColumn < 0 || yCelestialPoleOffsetRadiansColumn < 0 || taiMinusUtcSecondsColumn < 0) { + eop._dataError = 'Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns'; + return; + } - var scale = scratchCartesian3; - scale.x = u1 - l1; - scale.y = u2 - l2; - scale.z = u3 - l3; - Cartesian3.multiplyByScalar(scale, 0.5, scale); - Matrix3.multiplyByScale(result.halfAxes, scale, result.halfAxes); + var samples = eop._samples = eopData.samples; + var dates = eop._dates = []; - return result; - }; + eop._dateColumn = dateColumn; + eop._xPoleWanderRadiansColumn = xPoleWanderRadiansColumn; + eop._yPoleWanderRadiansColumn = yPoleWanderRadiansColumn; + eop._ut1MinusUtcSecondsColumn = ut1MinusUtcSecondsColumn; + eop._xCelestialPoleOffsetRadiansColumn = xCelestialPoleOffsetRadiansColumn; + eop._yCelestialPoleOffsetRadiansColumn = yCelestialPoleOffsetRadiansColumn; + eop._taiMinusUtcSecondsColumn = taiMinusUtcSecondsColumn; - var scratchOffset = new Cartesian3(); - var scratchScale = new Cartesian3(); - /** - * Computes an OrientedBoundingBox given extents in the east-north-up space of the tangent plane. - * - * @param {Plane} tangentPlane The tangent place corresponding to east-north-up. - * @param {Number} minimumX Minimum X extent in tangent plane space. - * @param {Number} maximumX Maximum X extent in tangent plane space. - * @param {Number} minimumY Minimum Y extent in tangent plane space. - * @param {Number} maximumY Maximum Y extent in tangent plane space. - * @param {Number} minimumZ Minimum Z extent in tangent plane space. - * @param {Number} maximumZ Maximum Z extent in tangent plane space. - * @param {OrientedBoundingBox} [result] The object onto which to store the result. - * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. - */ - function fromTangentPlaneExtents(tangentPlane, minimumX, maximumX, minimumY, maximumY, minimumZ, maximumZ, result) { - if (!defined(minimumX) || - !defined(maximumX) || - !defined(minimumY) || - !defined(maximumY) || - !defined(minimumZ) || - !defined(maximumZ)) { - throw new DeveloperError('all extents (minimum/maximum X/Y/Z) are required.'); - } - - if (!defined(result)) { - result = new OrientedBoundingBox(); - } + eop._columnCount = eopData.columnNames.length; + eop._lastIndex = undefined; - var halfAxes = result.halfAxes; - Matrix3.setColumn(halfAxes, 0, tangentPlane.xAxis, halfAxes); - Matrix3.setColumn(halfAxes, 1, tangentPlane.yAxis, halfAxes); - Matrix3.setColumn(halfAxes, 2, tangentPlane.zAxis, halfAxes); + var lastTaiMinusUtc; - var centerOffset = scratchOffset; - centerOffset.x = (minimumX + maximumX) / 2.0; - centerOffset.y = (minimumY + maximumY) / 2.0; - centerOffset.z = (minimumZ + maximumZ) / 2.0; + var addNewLeapSeconds = eop._addNewLeapSeconds; - var scale = scratchScale; - scale.x = (maximumX - minimumX) / 2.0; - scale.y = (maximumY - minimumY) / 2.0; - scale.z = (maximumZ - minimumZ) / 2.0; + // Convert the ISO8601 dates to JulianDates. + for (var i = 0, len = samples.length; i < len; i += eop._columnCount) { + var mjd = samples[i + dateColumn]; + var taiMinusUtc = samples[i + taiMinusUtcSecondsColumn]; + var day = mjd + TimeConstants.MODIFIED_JULIAN_DATE_DIFFERENCE; + var date = new JulianDate(day, taiMinusUtc, TimeStandard.TAI); + dates.push(date); - var center = result.center; - centerOffset = Matrix3.multiplyByVector(halfAxes, centerOffset, centerOffset); - Cartesian3.add(tangentPlane.origin, centerOffset, center); - Matrix3.multiplyByScale(halfAxes, scale, halfAxes); + if (addNewLeapSeconds) { + if (taiMinusUtc !== lastTaiMinusUtc && defined(lastTaiMinusUtc)) { + // We crossed a leap second boundary, so add the leap second + // if it does not already exist. + var leapSeconds = JulianDate.leapSeconds; + var leapSecondIndex = binarySearch(leapSeconds, date, compareLeapSecondDates); + if (leapSecondIndex < 0) { + var leapSecond = new LeapSecond(date, taiMinusUtc); + leapSeconds.splice(~leapSecondIndex, 0, leapSecond); + } + } + lastTaiMinusUtc = taiMinusUtc; + } + } + } - return result; + function fillResultFromIndex(eop, samples, index, columnCount, result) { + var start = index * columnCount; + result.xPoleWander = samples[start + eop._xPoleWanderRadiansColumn]; + result.yPoleWander = samples[start + eop._yPoleWanderRadiansColumn]; + result.xPoleOffset = samples[start + eop._xCelestialPoleOffsetRadiansColumn]; + result.yPoleOffset = samples[start + eop._yCelestialPoleOffsetRadiansColumn]; + result.ut1MinusUtc = samples[start + eop._ut1MinusUtcSecondsColumn]; } - var scratchRectangleCenterCartographic = new Cartographic(); - var scratchRectangleCenter = new Cartesian3(); - var perimeterCartographicScratch = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; - var perimeterCartesianScratch = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; - var perimeterProjectedScratch = [new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2()]; - /** - * Computes an OrientedBoundingBox that bounds a {@link Rectangle} on the surface of an {@link Ellipsoid}. - * There are no guarantees about the orientation of the bounding box. - * - * @param {Rectangle} rectangle The cartographic rectangle on the surface of the ellipsoid. - * @param {Number} [minimumHeight=0.0] The minimum height (elevation) within the tile. - * @param {Number} [maximumHeight=0.0] The maximum height (elevation) within the tile. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle is defined. - * @param {OrientedBoundingBox} [result] The object onto which to store the result. - * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. - * - * @exception {DeveloperError} rectangle.width must be between 0 and pi. - * @exception {DeveloperError} rectangle.height must be between 0 and pi. - * @exception {DeveloperError} ellipsoid must be an ellipsoid of revolution (<code>radii.x == radii.y</code>) - */ - OrientedBoundingBox.fromRectangle = function(rectangle, minimumHeight, maximumHeight, ellipsoid, result) { - if (!defined(rectangle)) { - throw new DeveloperError('rectangle is required'); - } - if (rectangle.width < 0.0 || rectangle.width > CesiumMath.TWO_PI) { - throw new DeveloperError('Rectangle width must be between 0 and 2*pi'); - } - if (rectangle.height < 0.0 || rectangle.height > CesiumMath.PI) { - throw new DeveloperError('Rectangle height must be between 0 and pi'); + function linearInterp(dx, y1, y2) { + return y1 + dx * (y2 - y1); + } + + function interpolate(eop, dates, samples, date, before, after, result) { + var columnCount = eop._columnCount; + + // First check the bounds on the EOP data + // If we are after the bounds of the data, return zeros. + // The 'before' index should never be less than zero. + if (after > dates.length - 1) { + result.xPoleWander = 0; + result.yPoleWander = 0; + result.xPoleOffset = 0; + result.yPoleOffset = 0; + result.ut1MinusUtc = 0; + return result; } - if (defined(ellipsoid) && !CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { - throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); + + var beforeDate = dates[before]; + var afterDate = dates[after]; + if (beforeDate.equals(afterDate) || date.equals(beforeDate)) { + fillResultFromIndex(eop, samples, before, columnCount, result); + return result; + } else if (date.equals(afterDate)) { + fillResultFromIndex(eop, samples, after, columnCount, result); + return result; } - - minimumHeight = defaultValue(minimumHeight, 0.0); - maximumHeight = defaultValue(maximumHeight, 0.0); - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - // The bounding box will be aligned with the tangent plane at the center of the rectangle. - var tangentPointCartographic = Rectangle.center(rectangle, scratchRectangleCenterCartographic); - var tangentPoint = ellipsoid.cartographicToCartesian(tangentPointCartographic, scratchRectangleCenter); - var tangentPlane = new EllipsoidTangentPlane(tangentPoint, ellipsoid); - var plane = tangentPlane.plane; + var factor = JulianDate.secondsDifference(date, beforeDate) / JulianDate.secondsDifference(afterDate, beforeDate); - // Corner arrangement: - // N/+y - // [0] [1] [2] - // W/-x [7] [3] E/+x - // [6] [5] [4] - // S/-y - // "C" refers to the central lat/long, which by default aligns with the tangent point (above). - // If the rectangle spans the equator, CW and CE are instead aligned with the equator. - var perimeterNW = perimeterCartographicScratch[0]; - var perimeterNC = perimeterCartographicScratch[1]; - var perimeterNE = perimeterCartographicScratch[2]; - var perimeterCE = perimeterCartographicScratch[3]; - var perimeterSE = perimeterCartographicScratch[4]; - var perimeterSC = perimeterCartographicScratch[5]; - var perimeterSW = perimeterCartographicScratch[6]; - var perimeterCW = perimeterCartographicScratch[7]; + var startBefore = before * columnCount; + var startAfter = after * columnCount; - var lonCenter = tangentPointCartographic.longitude; - var latCenter = (rectangle.south < 0.0 && rectangle.north > 0.0) ? 0.0 : tangentPointCartographic.latitude; - perimeterSW.latitude = perimeterSC.latitude = perimeterSE.latitude = rectangle.south; - perimeterCW.latitude = perimeterCE.latitude = latCenter; - perimeterNW.latitude = perimeterNC.latitude = perimeterNE.latitude = rectangle.north; - perimeterSW.longitude = perimeterCW.longitude = perimeterNW.longitude = rectangle.west; - perimeterSC.longitude = perimeterNC.longitude = lonCenter; - perimeterSE.longitude = perimeterCE.longitude = perimeterNE.longitude = rectangle.east; + // Handle UT1 leap second edge case + var beforeUt1MinusUtc = samples[startBefore + eop._ut1MinusUtcSecondsColumn]; + var afterUt1MinusUtc = samples[startAfter + eop._ut1MinusUtcSecondsColumn]; - // Compute XY extents using the rectangle at maximum height - perimeterNE.height = perimeterNC.height = perimeterNW.height = perimeterCW.height = perimeterSW.height = perimeterSC.height = perimeterSE.height = perimeterCE.height = maximumHeight; + var offsetDifference = afterUt1MinusUtc - beforeUt1MinusUtc; + if (offsetDifference > 0.5 || offsetDifference < -0.5) { + // The absolute difference between the values is more than 0.5, so we may have + // crossed a leap second. Check if this is the case and, if so, adjust the + // afterValue to account for the leap second. This way, our interpolation will + // produce reasonable results. + var beforeTaiMinusUtc = samples[startBefore + eop._taiMinusUtcSecondsColumn]; + var afterTaiMinusUtc = samples[startAfter + eop._taiMinusUtcSecondsColumn]; + if (beforeTaiMinusUtc !== afterTaiMinusUtc) { + if (afterDate.equals(date)) { + // If we are at the end of the leap second interval, take the second value + // Otherwise, the interpolation below will yield the wrong side of the + // discontinuity + // At the end of the leap second, we need to start accounting for the jump + beforeUt1MinusUtc = afterUt1MinusUtc; + } else { + // Otherwise, remove the leap second so that the interpolation is correct + afterUt1MinusUtc -= afterTaiMinusUtc - beforeTaiMinusUtc; + } + } + } - ellipsoid.cartographicArrayToCartesianArray(perimeterCartographicScratch, perimeterCartesianScratch); - tangentPlane.projectPointsToNearestOnPlane(perimeterCartesianScratch, perimeterProjectedScratch); - // See the `perimeterXX` definitions above for what these are - var minX = Math.min(perimeterProjectedScratch[6].x, perimeterProjectedScratch[7].x, perimeterProjectedScratch[0].x); - var maxX = Math.max(perimeterProjectedScratch[2].x, perimeterProjectedScratch[3].x, perimeterProjectedScratch[4].x); - var minY = Math.min(perimeterProjectedScratch[4].y, perimeterProjectedScratch[5].y, perimeterProjectedScratch[6].y); - var maxY = Math.max(perimeterProjectedScratch[0].y, perimeterProjectedScratch[1].y, perimeterProjectedScratch[2].y); + result.xPoleWander = linearInterp(factor, samples[startBefore + eop._xPoleWanderRadiansColumn], samples[startAfter + eop._xPoleWanderRadiansColumn]); + result.yPoleWander = linearInterp(factor, samples[startBefore + eop._yPoleWanderRadiansColumn], samples[startAfter + eop._yPoleWanderRadiansColumn]); + result.xPoleOffset = linearInterp(factor, samples[startBefore + eop._xCelestialPoleOffsetRadiansColumn], samples[startAfter + eop._xCelestialPoleOffsetRadiansColumn]); + result.yPoleOffset = linearInterp(factor, samples[startBefore + eop._yCelestialPoleOffsetRadiansColumn], samples[startAfter + eop._yCelestialPoleOffsetRadiansColumn]); + result.ut1MinusUtc = linearInterp(factor, beforeUt1MinusUtc, afterUt1MinusUtc); + return result; + } - // Compute minimum Z using the rectangle at minimum height - perimeterNE.height = perimeterNW.height = perimeterSE.height = perimeterSW.height = minimumHeight; - ellipsoid.cartographicArrayToCartesianArray(perimeterCartographicScratch, perimeterCartesianScratch); - var minZ = Math.min(Plane.getPointDistance(plane, perimeterCartesianScratch[0]), - Plane.getPointDistance(plane, perimeterCartesianScratch[2]), - Plane.getPointDistance(plane, perimeterCartesianScratch[4]), - Plane.getPointDistance(plane, perimeterCartesianScratch[6])); - var maxZ = maximumHeight; // Since the tangent plane touches the surface at height = 0, this is okay + return EarthOrientationParameters; +}); - return fromTangentPlaneExtents(tangentPlane, minX, maxX, minY, maxY, minZ, maxZ, result); - }; +define('Core/Iau2006XysSample',[],function() { + 'use strict'; /** - * Duplicates a OrientedBoundingBox instance. + * An IAU 2006 XYS value sampled at a particular time. * - * @param {OrientedBoundingBox} box The bounding box to duplicate. - * @param {OrientedBoundingBox} [result] The object onto which to store the result. - * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. (Returns undefined if box is undefined) + * @alias Iau2006XysSample + * @constructor + * + * @param {Number} x The X value. + * @param {Number} y The Y value. + * @param {Number} s The S value. + * + * @private */ - OrientedBoundingBox.clone = function(box, result) { - if (!defined(box)) { - return undefined; - } + function Iau2006XysSample(x, y, s) { + /** + * The X value. + * @type {Number} + */ + this.x = x; - if (!defined(result)) { - return new OrientedBoundingBox(box.center, box.halfAxes); - } + /** + * The Y value. + * @type {Number} + */ + this.y = y; - Cartesian3.clone(box.center, result.center); - Matrix3.clone(box.halfAxes, result.halfAxes); + /** + * The S value. + * @type {Number} + */ + this.s = s; + } - return result; - }; + return Iau2006XysSample; +}); + +define('Core/Iau2006XysData',[ + '../ThirdParty/when', + './buildModuleUrl', + './defaultValue', + './defined', + './Iau2006XysSample', + './JulianDate', + './Resource', + './TimeStandard' + ], function( + when, + buildModuleUrl, + defaultValue, + defined, + Iau2006XysSample, + JulianDate, + Resource, + TimeStandard) { + 'use strict'; /** - * Determines which side of a plane the oriented bounding box is located. + * A set of IAU2006 XYS data that is used to evaluate the transformation between the International + * Celestial Reference Frame (ICRF) and the International Terrestrial Reference Frame (ITRF). * - * @param {OrientedBoundingBox} box The oriented bounding box to test. - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is - * on the opposite side, and {@link Intersect.INTERSECTING} if the box - * intersects the plane. + * @alias Iau2006XysData + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * `{0}` will be replaced with the file index. + * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. + * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the + * first XYS sample. + * @param {Number} [options.stepSizeDays=1.0] The step size, in days, between successive XYS samples. + * @param {Number} [options.samplesPerXysFile=1000] The number of samples in each XYS file. + * @param {Number} [options.totalSamples=27426] The total number of samples in all XYS files. + * + * @private */ - OrientedBoundingBox.intersectPlane = function(box, plane) { - if (!defined(box)) { - throw new DeveloperError('box is required.'); - } + function Iau2006XysData(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (!defined(plane)) { - throw new DeveloperError('plane is required.'); - } - - var center = box.center; - var normal = plane.normal; - var halfAxes = box.halfAxes; - var normalX = normal.x, normalY = normal.y, normalZ = normal.z; - // plane is used as if it is its normal; the first three components are assumed to be normalized - var radEffective = Math.abs(normalX * halfAxes[Matrix3.COLUMN0ROW0] + normalY * halfAxes[Matrix3.COLUMN0ROW1] + normalZ * halfAxes[Matrix3.COLUMN0ROW2]) + - Math.abs(normalX * halfAxes[Matrix3.COLUMN1ROW0] + normalY * halfAxes[Matrix3.COLUMN1ROW1] + normalZ * halfAxes[Matrix3.COLUMN1ROW2]) + - Math.abs(normalX * halfAxes[Matrix3.COLUMN2ROW0] + normalY * halfAxes[Matrix3.COLUMN2ROW1] + normalZ * halfAxes[Matrix3.COLUMN2ROW2]); - var distanceToPlane = Cartesian3.dot(normal, center) + plane.distance; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); + this._interpolationOrder = defaultValue(options.interpolationOrder, 9); + this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); + this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); + this._stepSizeDays = defaultValue(options.stepSizeDays, 1.0); + this._samplesPerXysFile = defaultValue(options.samplesPerXysFile, 1000); + this._totalSamples = defaultValue(options.totalSamples, 27426); + this._samples = new Array(this._totalSamples * 3); + this._chunkDownloadsInProgress = []; - if (distanceToPlane <= -radEffective) { - // The entire box is on the negative side of the plane normal - return Intersect.OUTSIDE; - } else if (distanceToPlane >= radEffective) { - // The entire box is on the positive side of the plane normal - return Intersect.INSIDE; - } - return Intersect.INTERSECTING; - }; + var order = this._interpolationOrder; - var scratchCartesianU = new Cartesian3(); - var scratchCartesianV = new Cartesian3(); - var scratchCartesianW = new Cartesian3(); - var scratchPPrime = new Cartesian3(); + // Compute denominators and X values for interpolation. + var denom = this._denominators = new Array(order + 1); + var xTable = this._xTable = new Array(order + 1); - /** - * Computes the estimated distance squared from the closest point on a bounding box to a point. - * - * @param {OrientedBoundingBox} box The box. - * @param {Cartesian3} cartesian The point - * @returns {Number} The estimated distance squared from the bounding sphere to the point. - * - * @example - * // Sort bounding boxes from back to front - * boxes.sort(function(a, b) { - * return Cesium.OrientedBoundingBox.distanceSquaredTo(b, camera.positionWC) - Cesium.OrientedBoundingBox.distanceSquaredTo(a, camera.positionWC); - * }); - */ - OrientedBoundingBox.distanceSquaredTo = function(box, cartesian) { - // See Geometric Tools for Computer Graphics 10.4.2 + var stepN = Math.pow(this._stepSizeDays, order); - if (!defined(box)) { - throw new DeveloperError('box is required.'); - } - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); - } - - var offset = Cartesian3.subtract(cartesian, box.center, scratchOffset); + for ( var i = 0; i <= order; ++i) { + denom[i] = stepN; + xTable[i] = i * this._stepSizeDays; - var halfAxes = box.halfAxes; - var u = Matrix3.getColumn(halfAxes, 0, scratchCartesianU); - var v = Matrix3.getColumn(halfAxes, 1, scratchCartesianV); - var w = Matrix3.getColumn(halfAxes, 2, scratchCartesianW); + for ( var j = 0; j <= order; ++j) { + if (j !== i) { + denom[i] *= (i - j); + } + } - var uHalf = Cartesian3.magnitude(u); - var vHalf = Cartesian3.magnitude(v); - var wHalf = Cartesian3.magnitude(w); + denom[i] = 1.0 / denom[i]; + } - Cartesian3.normalize(u, u); - Cartesian3.normalize(v, v); - Cartesian3.normalize(w, w); + // Allocate scratch arrays for interpolation. + this._work = new Array(order + 1); + this._coef = new Array(order + 1); + } - var pPrime = scratchPPrime; - pPrime.x = Cartesian3.dot(offset, u); - pPrime.y = Cartesian3.dot(offset, v); - pPrime.z = Cartesian3.dot(offset, w); + var julianDateScratch = new JulianDate(0, 0.0, TimeStandard.TAI); - var distanceSquared = 0.0; - var d; + function getDaysSinceEpoch(xys, dayTT, secondTT) { + var dateTT = julianDateScratch; + dateTT.dayNumber = dayTT; + dateTT.secondsOfDay = secondTT; + return JulianDate.daysDifference(dateTT, xys._sampleZeroDateTT); + } - if (pPrime.x < -uHalf) { - d = pPrime.x + uHalf; - distanceSquared += d * d; - } else if (pPrime.x > uHalf) { - d = pPrime.x - uHalf; - distanceSquared += d * d; + /** + * Preloads XYS data for a specified date range. + * + * @param {Number} startDayTT The Julian day number of the beginning of the interval to preload, expressed in + * the Terrestrial Time (TT) time standard. + * @param {Number} startSecondTT The seconds past noon of the beginning of the interval to preload, expressed in + * the Terrestrial Time (TT) time standard. + * @param {Number} stopDayTT The Julian day number of the end of the interval to preload, expressed in + * the Terrestrial Time (TT) time standard. + * @param {Number} stopSecondTT The seconds past noon of the end of the interval to preload, expressed in + * the Terrestrial Time (TT) time standard. + * @returns {Promise.<undefined>} A promise that, when resolved, indicates that the requested interval has been + * preloaded. + */ + Iau2006XysData.prototype.preload = function(startDayTT, startSecondTT, stopDayTT, stopSecondTT) { + var startDaysSinceEpoch = getDaysSinceEpoch(this, startDayTT, startSecondTT); + var stopDaysSinceEpoch = getDaysSinceEpoch(this, stopDayTT, stopSecondTT); + + var startIndex = (startDaysSinceEpoch / this._stepSizeDays - this._interpolationOrder / 2) | 0; + if (startIndex < 0) { + startIndex = 0; } - if (pPrime.y < -vHalf) { - d = pPrime.y + vHalf; - distanceSquared += d * d; - } else if (pPrime.y > vHalf) { - d = pPrime.y - vHalf; - distanceSquared += d * d; + var stopIndex = (stopDaysSinceEpoch / this._stepSizeDays - this._interpolationOrder / 2) | 0 + this._interpolationOrder; + if (stopIndex >= this._totalSamples) { + stopIndex = this._totalSamples - 1; } - if (pPrime.z < -wHalf) { - d = pPrime.z + wHalf; - distanceSquared += d * d; - } else if (pPrime.z > wHalf) { - d = pPrime.z - wHalf; - distanceSquared += d * d; + var startChunk = (startIndex / this._samplesPerXysFile) | 0; + var stopChunk = (stopIndex / this._samplesPerXysFile) | 0; + + var promises = []; + for ( var i = startChunk; i <= stopChunk; ++i) { + promises.push(requestXysChunk(this, i)); } - return distanceSquared; + return when.all(promises); }; - var scratchCorner = new Cartesian3(); - var scratchToCenter = new Cartesian3(); - /** - * The distances calculated by the vector from the center of the bounding box to position projected onto direction. - * <br> - * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the - * closest and farthest planes from position that intersect the bounding box. + * Computes the XYS values for a given date by interpolating. If the required data is not yet downloaded, + * this method will return undefined. * - * @param {OrientedBoundingBox} box The bounding box to calculate the distance to. - * @param {Cartesian3} position The position to calculate the distance from. - * @param {Cartesian3} direction The direction from position. - * @param {Interval} [result] A Interval to store the nearest and farthest distances. - * @returns {Interval} The nearest and farthest distances on the bounding box from position in direction. + * @param {Number} dayTT The Julian day number for which to compute the XYS value, expressed in + * the Terrestrial Time (TT) time standard. + * @param {Number} secondTT The seconds past noon of the date for which to compute the XYS value, expressed in + * the Terrestrial Time (TT) time standard. + * @param {Iau2006XysSample} [result] The instance to which to copy the interpolated result. If this parameter + * is undefined, a new instance is allocated and returned. + * @returns {Iau2006XysSample} The interpolated XYS values, or undefined if the required data for this + * computation has not yet been downloaded. + * + * @see Iau2006XysData#preload */ - OrientedBoundingBox.computePlaneDistances = function(box, position, direction, result) { - if (!defined(box)) { - throw new DeveloperError('box is required.'); + Iau2006XysData.prototype.computeXysRadians = function(dayTT, secondTT, result) { + var daysSinceEpoch = getDaysSinceEpoch(this, dayTT, secondTT); + if (daysSinceEpoch < 0.0) { + // Can't evaluate prior to the epoch of the data. + return undefined; } - if (!defined(position)) { - throw new DeveloperError('position is required.'); + var centerIndex = (daysSinceEpoch / this._stepSizeDays) | 0; + if (centerIndex >= this._totalSamples) { + // Can't evaluate after the last sample in the data. + return undefined; } - if (!defined(direction)) { - throw new DeveloperError('direction is required.'); + var degree = this._interpolationOrder; + + var firstIndex = centerIndex - ((degree / 2) | 0); + if (firstIndex < 0) { + firstIndex = 0; } - - if (!defined(result)) { - result = new Interval(); + var lastIndex = firstIndex + degree; + if (lastIndex >= this._totalSamples) { + lastIndex = this._totalSamples - 1; + firstIndex = lastIndex - degree; + if (firstIndex < 0) { + firstIndex = 0; + } } - var minDist = Number.POSITIVE_INFINITY; - var maxDist = Number.NEGATIVE_INFINITY; - - var center = box.center; - var halfAxes = box.halfAxes; + // Are all the samples we need present? + // We can assume so if the first and last are present + var isDataMissing = false; + var samples = this._samples; + if (!defined(samples[firstIndex * 3])) { + requestXysChunk(this, (firstIndex / this._samplesPerXysFile) | 0); + isDataMissing = true; + } - var u = Matrix3.getColumn(halfAxes, 0, scratchCartesianU); - var v = Matrix3.getColumn(halfAxes, 1, scratchCartesianV); - var w = Matrix3.getColumn(halfAxes, 2, scratchCartesianW); - - // project first corner - var corner = Cartesian3.add(u, v, scratchCorner); - Cartesian3.add(corner, w, corner); - Cartesian3.add(corner, center, corner); - - var toCenter = Cartesian3.subtract(corner, position, scratchToCenter); - var mag = Cartesian3.dot(direction, toCenter); - - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); - - // project second corner - Cartesian3.add(center, u, corner); - Cartesian3.add(corner, v, corner); - Cartesian3.subtract(corner, w, corner); - - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); - - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); - - // project third corner - Cartesian3.add(center, u, corner); - Cartesian3.subtract(corner, v, corner); - Cartesian3.add(corner, w, corner); - - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); - - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); - - // project fourth corner - Cartesian3.add(center, u, corner); - Cartesian3.subtract(corner, v, corner); - Cartesian3.subtract(corner, w, corner); - - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); - - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); - - // project fifth corner - Cartesian3.subtract(center, u, corner); - Cartesian3.add(corner, v, corner); - Cartesian3.add(corner, w, corner); - - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); - - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); + if (!defined(samples[lastIndex * 3])) { + requestXysChunk(this, (lastIndex / this._samplesPerXysFile) | 0); + isDataMissing = true; + } - // project sixth corner - Cartesian3.subtract(center, u, corner); - Cartesian3.add(corner, v, corner); - Cartesian3.subtract(corner, w, corner); + if (isDataMissing) { + return undefined; + } - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); + if (!defined(result)) { + result = new Iau2006XysSample(0.0, 0.0, 0.0); + } else { + result.x = 0.0; + result.y = 0.0; + result.s = 0.0; + } - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); + var x = daysSinceEpoch - firstIndex * this._stepSizeDays; - // project seventh corner - Cartesian3.subtract(center, u, corner); - Cartesian3.subtract(corner, v, corner); - Cartesian3.add(corner, w, corner); + var work = this._work; + var denom = this._denominators; + var coef = this._coef; + var xTable = this._xTable; - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); + var i, j; + for (i = 0; i <= degree; ++i) { + work[i] = x - xTable[i]; + } - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); + for (i = 0; i <= degree; ++i) { + coef[i] = 1.0; - // project eighth corner - Cartesian3.subtract(center, u, corner); - Cartesian3.subtract(corner, v, corner); - Cartesian3.subtract(corner, w, corner); + for (j = 0; j <= degree; ++j) { + if (j !== i) { + coef[i] *= work[j]; + } + } - Cartesian3.subtract(corner, position, toCenter); - mag = Cartesian3.dot(direction, toCenter); + coef[i] *= denom[i]; - minDist = Math.min(mag, minDist); - maxDist = Math.max(mag, maxDist); + var sampleIndex = (firstIndex + i) * 3; + result.x += coef[i] * samples[sampleIndex++]; + result.y += coef[i] * samples[sampleIndex++]; + result.s += coef[i] * samples[sampleIndex]; + } - result.start = minDist; - result.stop = maxDist; return result; }; - var scratchBoundingSphere = new BoundingSphere(); - - /** - * Determines whether or not a bounding box is hidden from view by the occluder. - * - * @param {OrientedBoundingBox} box The bounding box surrounding the occludee object. - * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the box is not visible; otherwise <code>false</code>. - */ - OrientedBoundingBox.isOccluded = function(box, occluder) { - if (!defined(box)) { - throw new DeveloperError('box is required.'); - } - if (!defined(occluder)) { - throw new DeveloperError('occluder is required.'); + function requestXysChunk(xysData, chunkIndex) { + if (xysData._chunkDownloadsInProgress[chunkIndex]) { + // Chunk has already been requested. + return xysData._chunkDownloadsInProgress[chunkIndex]; } - - var sphere = BoundingSphere.fromOrientedBoundingBox(box, scratchBoundingSphere); - - return !occluder.isBoundingSphereVisible(sphere); - }; - - /** - * Determines which side of a plane the oriented bounding box is located. - * - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is - * on the opposite side, and {@link Intersect.INTERSECTING} if the box - * intersects the plane. - */ - OrientedBoundingBox.prototype.intersectPlane = function(plane) { - return OrientedBoundingBox.intersectPlane(this, plane); - }; - - /** - * Computes the estimated distance squared from the closest point on a bounding box to a point. - * - * @param {Cartesian3} cartesian The point - * @returns {Number} The estimated distance squared from the bounding sphere to the point. - * - * @example - * // Sort bounding boxes from back to front - * boxes.sort(function(a, b) { - * return b.distanceSquaredTo(camera.positionWC) - a.distanceSquaredTo(camera.positionWC); - * }); - */ - OrientedBoundingBox.prototype.distanceSquaredTo = function(cartesian) { - return OrientedBoundingBox.distanceSquaredTo(this, cartesian); - }; - - /** - * The distances calculated by the vector from the center of the bounding box to position projected onto direction. - * <br> - * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the - * closest and farthest planes from position that intersect the bounding box. - * - * @param {Cartesian3} position The position to calculate the distance from. - * @param {Cartesian3} direction The direction from position. - * @param {Interval} [result] A Interval to store the nearest and farthest distances. - * @returns {Interval} The nearest and farthest distances on the bounding box from position in direction. - */ - OrientedBoundingBox.prototype.computePlaneDistances = function(position, direction, result) { - return OrientedBoundingBox.computePlaneDistances(this, position, direction, result); - }; - /** - * Determines whether or not a bounding box is hidden from view by the occluder. - * - * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. - */ - OrientedBoundingBox.prototype.isOccluded = function(occluder) { - return OrientedBoundingBox.isOccluded(this, occluder); - }; + var deferred = when.defer(); - /** - * Compares the provided OrientedBoundingBox componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {OrientedBoundingBox} left The first OrientedBoundingBox. - * @param {OrientedBoundingBox} right The second OrientedBoundingBox. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - OrientedBoundingBox.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - Cartesian3.equals(left.center, right.center) && - Matrix3.equals(left.halfAxes, right.halfAxes)); - }; + xysData._chunkDownloadsInProgress[chunkIndex] = deferred; - /** - * Duplicates this OrientedBoundingBox instance. - * - * @param {OrientedBoundingBox} [result] The object onto which to store the result. - * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. - */ - OrientedBoundingBox.prototype.clone = function(result) { - return OrientedBoundingBox.clone(this, result); - }; + var chunkUrl; + var xysFileUrlTemplate = xysData._xysFileUrlTemplate; + if (defined(xysFileUrlTemplate)) { + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); + } else { + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); + } - /** - * Compares this OrientedBoundingBox against the provided OrientedBoundingBox componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {OrientedBoundingBox} [right] The right hand side OrientedBoundingBox. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - OrientedBoundingBox.prototype.equals = function(right) { - return OrientedBoundingBox.equals(this, right); - }; + when(chunkUrl.fetchJson(), function(chunk) { + xysData._chunkDownloadsInProgress[chunkIndex] = false; - return OrientedBoundingBox; -}); + var samples = xysData._samples; + var newSamples = chunk.samples; + var startIndex = chunkIndex * xysData._samplesPerXysFile * 3; -define('Core/TerrainQuantization',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + for ( var i = 0, len = newSamples.length; i < len; ++i) { + samples[startIndex + i] = newSamples[i]; + } - /** - * This enumerated type is used to determine how the vertices of the terrain mesh are compressed. - * - * @exports TerrainQuantization - * - * @private - */ - var TerrainQuantization = { - /** - * The vertices are not compressed. - * - * @type {Number} - * @constant - */ - NONE : 0, + deferred.resolve(); + }); - /** - * The vertices are compressed to 12 bits. - * - * @type {Number} - * @constant - */ - BITS12 : 1 - }; + return deferred.promise; + } - return freezeObject(TerrainQuantization); + return Iau2006XysData; }); -define('Core/TerrainEncoding',[ - './AttributeCompression', - './Cartesian2', +define('Core/Quaternion',[ './Cartesian3', - './ComponentDatatype', + './Check', './defaultValue', './defined', + './FeatureDetection', + './freezeObject', './Math', - './Matrix4', - './TerrainQuantization' + './Matrix3' ], function( - AttributeCompression, - Cartesian2, Cartesian3, - ComponentDatatype, + Check, defaultValue, defined, + FeatureDetection, + freezeObject, CesiumMath, - Matrix4, - TerrainQuantization) { + Matrix3) { 'use strict'; - var cartesian3Scratch = new Cartesian3(); - var cartesian3DimScratch = new Cartesian3(); - var cartesian2Scratch = new Cartesian2(); - var matrix4Scratch = new Matrix4(); - var matrix4Scratch2 = new Matrix4(); - - var SHIFT_LEFT_12 = Math.pow(2.0, 12.0); - /** - * Data used to quantize and pack the terrain mesh. The position can be unpacked for picking and all attributes - * are unpacked in the vertex shader. - * - * @alias TerrainEncoding + * A set of 4-dimensional coordinates used to represent rotation in 3-dimensional space. + * @alias Quaternion * @constructor * - * @param {AxisAlignedBoundingBox} axisAlignedBoundingBox The bounds of the tile in the east-north-up coordinates at the tiles center. - * @param {Number} minimumHeight The minimum height. - * @param {Number} maximumHeight The maximum height. - * @param {Matrix4} fromENU The east-north-up to fixed frame matrix at the center of the terrain mesh. - * @param {Boolean} hasVertexNormals If the mesh has vertex normals. - * @param {Boolean} [hasWebMercatorT=false] true if the terrain data includes a Web Mercator texture coordinate; otherwise, false. + * @param {Number} [x=0.0] The X component. + * @param {Number} [y=0.0] The Y component. + * @param {Number} [z=0.0] The Z component. + * @param {Number} [w=0.0] The W component. * - * @private + * @see PackableForInterpolation */ - function TerrainEncoding(axisAlignedBoundingBox, minimumHeight, maximumHeight, fromENU, hasVertexNormals, hasWebMercatorT) { - var quantization; - var center; - var toENU; - var matrix; - - if (defined(axisAlignedBoundingBox) && defined(minimumHeight) && defined(maximumHeight) && defined(fromENU)) { - var minimum = axisAlignedBoundingBox.minimum; - var maximum = axisAlignedBoundingBox.maximum; - - var dimensions = Cartesian3.subtract(maximum, minimum, cartesian3DimScratch); - var hDim = maximumHeight - minimumHeight; - var maxDim = Math.max(Cartesian3.maximumComponent(dimensions), hDim); - - if (maxDim < SHIFT_LEFT_12 - 1.0) { - quantization = TerrainQuantization.BITS12; - } else { - quantization = TerrainQuantization.NONE; - } - - center = axisAlignedBoundingBox.center; - toENU = Matrix4.inverseTransformation(fromENU, new Matrix4()); - - var translation = Cartesian3.negate(minimum, cartesian3Scratch); - Matrix4.multiply(Matrix4.fromTranslation(translation, matrix4Scratch), toENU, toENU); - - var scale = cartesian3Scratch; - scale.x = 1.0 / dimensions.x; - scale.y = 1.0 / dimensions.y; - scale.z = 1.0 / dimensions.z; - Matrix4.multiply(Matrix4.fromScale(scale, matrix4Scratch), toENU, toENU); - - matrix = Matrix4.clone(fromENU); - Matrix4.setTranslation(matrix, Cartesian3.ZERO, matrix); - - fromENU = Matrix4.clone(fromENU, new Matrix4()); - - var translationMatrix = Matrix4.fromTranslation(minimum, matrix4Scratch); - var scaleMatrix = Matrix4.fromScale(dimensions, matrix4Scratch2); - var st = Matrix4.multiply(translationMatrix, scaleMatrix,matrix4Scratch); - - Matrix4.multiply(fromENU, st, fromENU); - Matrix4.multiply(matrix, st, matrix); - } - - /** - * How the vertices of the mesh were compressed. - * @type {TerrainQuantization} - */ - this.quantization = quantization; - + function Quaternion(x, y, z, w) { /** - * The minimum height of the tile including the skirts. + * The X component. * @type {Number} + * @default 0.0 */ - this.minimumHeight = minimumHeight; + this.x = defaultValue(x, 0.0); /** - * The maximum height of the tile. + * The Y component. * @type {Number} + * @default 0.0 */ - this.maximumHeight = maximumHeight; - - /** - * The center of the tile. - * @type {Cartesian3} - */ - this.center = center; - - /** - * A matrix that takes a vertex from the tile, transforms it to east-north-up at the center and scales - * it so each component is in the [0, 1] range. - * @type {Matrix4} - */ - this.toScaledENU = toENU; - - /** - * A matrix that restores a vertex transformed with toScaledENU back to the earth fixed reference frame - * @type {Matrix4} - */ - this.fromScaledENU = fromENU; - - /** - * The matrix used to decompress the terrain vertices in the shader for RTE rendering. - * @type {Matrix4} - */ - this.matrix = matrix; + this.y = defaultValue(y, 0.0); /** - * The terrain mesh contains normals. - * @type {Boolean} + * The Z component. + * @type {Number} + * @default 0.0 */ - this.hasVertexNormals = hasVertexNormals; + this.z = defaultValue(z, 0.0); /** - * The terrain mesh contains a vertical texture coordinate following the Web Mercator projection. - * @type {Boolean} + * The W component. + * @type {Number} + * @default 0.0 */ - this.hasWebMercatorT = defaultValue(hasWebMercatorT, false); + this.w = defaultValue(w, 0.0); } - TerrainEncoding.prototype.encode = function(vertexBuffer, bufferIndex, position, uv, height, normalToPack, webMercatorT) { - var u = uv.x; - var v = uv.y; - - if (this.quantization === TerrainQuantization.BITS12) { - position = Matrix4.multiplyByPoint(this.toScaledENU, position, cartesian3Scratch); - - position.x = CesiumMath.clamp(position.x, 0.0, 1.0); - position.y = CesiumMath.clamp(position.y, 0.0, 1.0); - position.z = CesiumMath.clamp(position.z, 0.0, 1.0); + var fromAxisAngleScratch = new Cartesian3(); - var hDim = this.maximumHeight - this.minimumHeight; - var h = CesiumMath.clamp((height - this.minimumHeight) / hDim, 0.0, 1.0); + /** + * Computes a quaternion representing a rotation around an axis. + * + * @param {Cartesian3} axis The axis of rotation. + * @param {Number} angle The angle in radians to rotate around the axis. + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + */ + Quaternion.fromAxisAngle = function(axis, angle, result) { + Check.typeOf.object('axis', axis); + Check.typeOf.number('angle', angle); + + var halfAngle = angle / 2.0; + var s = Math.sin(halfAngle); + fromAxisAngleScratch = Cartesian3.normalize(axis, fromAxisAngleScratch); - Cartesian2.fromElements(position.x, position.y, cartesian2Scratch); - var compressed0 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); + var x = fromAxisAngleScratch.x * s; + var y = fromAxisAngleScratch.y * s; + var z = fromAxisAngleScratch.z * s; + var w = Math.cos(halfAngle); + if (!defined(result)) { + return new Quaternion(x, y, z, w); + } + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + }; - Cartesian2.fromElements(position.z, h, cartesian2Scratch); - var compressed1 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); + var fromRotationMatrixNext = [1, 2, 0]; + var fromRotationMatrixQuat = new Array(3); + /** + * Computes a Quaternion from the provided Matrix3 instance. + * + * @param {Matrix3} matrix The rotation matrix. + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + * + * @see Matrix3.fromQuaternion + */ + Quaternion.fromRotationMatrix = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + + var root; + var x; + var y; + var z; + var w; - Cartesian2.fromElements(u, v, cartesian2Scratch); - var compressed2 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); + var m00 = matrix[Matrix3.COLUMN0ROW0]; + var m11 = matrix[Matrix3.COLUMN1ROW1]; + var m22 = matrix[Matrix3.COLUMN2ROW2]; + var trace = m00 + m11 + m22; - vertexBuffer[bufferIndex++] = compressed0; - vertexBuffer[bufferIndex++] = compressed1; - vertexBuffer[bufferIndex++] = compressed2; + if (trace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + root = Math.sqrt(trace + 1.0); // 2w + w = 0.5 * root; + root = 0.5 / root; // 1/(4w) - if (this.hasWebMercatorT) { - Cartesian2.fromElements(webMercatorT, 0.0, cartesian2Scratch); - var compressed3 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); - vertexBuffer[bufferIndex++] = compressed3; - } + x = (matrix[Matrix3.COLUMN1ROW2] - matrix[Matrix3.COLUMN2ROW1]) * root; + y = (matrix[Matrix3.COLUMN2ROW0] - matrix[Matrix3.COLUMN0ROW2]) * root; + z = (matrix[Matrix3.COLUMN0ROW1] - matrix[Matrix3.COLUMN1ROW0]) * root; } else { - Cartesian3.subtract(position, this.center, cartesian3Scratch); - - vertexBuffer[bufferIndex++] = cartesian3Scratch.x; - vertexBuffer[bufferIndex++] = cartesian3Scratch.y; - vertexBuffer[bufferIndex++] = cartesian3Scratch.z; - vertexBuffer[bufferIndex++] = height; - vertexBuffer[bufferIndex++] = u; - vertexBuffer[bufferIndex++] = v; + // |w| <= 1/2 + var next = fromRotationMatrixNext; - if (this.hasWebMercatorT) { - vertexBuffer[bufferIndex++] = webMercatorT; + var i = 0; + if (m11 > m00) { + i = 1; } - } - - if (this.hasVertexNormals) { - vertexBuffer[bufferIndex++] = AttributeCompression.octPackFloat(normalToPack); - } - - return bufferIndex; - }; - - TerrainEncoding.prototype.decodePosition = function(buffer, index, result) { - if (!defined(result)) { - result = new Cartesian3(); - } - - index *= this.getStride(); + if (m22 > m00 && m22 > m11) { + i = 2; + } + var j = next[i]; + var k = next[j]; - if (this.quantization === TerrainQuantization.BITS12) { - var xy = AttributeCompression.decompressTextureCoordinates(buffer[index], cartesian2Scratch); - result.x = xy.x; - result.y = xy.y; + root = Math.sqrt(matrix[Matrix3.getElementIndex(i, i)] - matrix[Matrix3.getElementIndex(j, j)] - matrix[Matrix3.getElementIndex(k, k)] + 1.0); - var zh = AttributeCompression.decompressTextureCoordinates(buffer[index + 1], cartesian2Scratch); - result.z = zh.x; + var quat = fromRotationMatrixQuat; + quat[i] = 0.5 * root; + root = 0.5 / root; + w = (matrix[Matrix3.getElementIndex(k, j)] - matrix[Matrix3.getElementIndex(j, k)]) * root; + quat[j] = (matrix[Matrix3.getElementIndex(j, i)] + matrix[Matrix3.getElementIndex(i, j)]) * root; + quat[k] = (matrix[Matrix3.getElementIndex(k, i)] + matrix[Matrix3.getElementIndex(i, k)]) * root; - return Matrix4.multiplyByPoint(this.fromScaledENU, result, result); + x = -quat[0]; + y = -quat[1]; + z = -quat[2]; } - result.x = buffer[index]; - result.y = buffer[index + 1]; - result.z = buffer[index + 2]; - return Cartesian3.add(result, this.center, result); - }; - - TerrainEncoding.prototype.decodeTextureCoordinates = function(buffer, index, result) { if (!defined(result)) { - result = new Cartesian2(); - } - - index *= this.getStride(); - - if (this.quantization === TerrainQuantization.BITS12) { - return AttributeCompression.decompressTextureCoordinates(buffer[index + 2], result); + return new Quaternion(x, y, z, w); } - - return Cartesian2.fromElements(buffer[index + 4], buffer[index + 5], result); + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; }; - TerrainEncoding.prototype.decodeHeight = function(buffer, index) { - index *= this.getStride(); - - if (this.quantization === TerrainQuantization.BITS12) { - var zh = AttributeCompression.decompressTextureCoordinates(buffer[index + 1], cartesian2Scratch); - return zh.y * (this.maximumHeight - this.minimumHeight) + this.minimumHeight; - } + var scratchHPRQuaternion = new Quaternion(); + var scratchHeadingQuaternion = new Quaternion(); + var scratchPitchQuaternion = new Quaternion(); + var scratchRollQuaternion = new Quaternion(); - return buffer[index + 3]; + /** + * Computes a rotation from the given heading, pitch and roll angles. Heading is the rotation about the + * negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about + * the positive x axis. + * + * @param {HeadingPitchRoll} headingPitchRoll The rotation expressed as a heading, pitch and roll. + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if none was provided. + */ + Quaternion.fromHeadingPitchRoll = function(headingPitchRoll, result) { + Check.typeOf.object('headingPitchRoll', headingPitchRoll); + + scratchRollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, headingPitchRoll.roll, scratchHPRQuaternion); + scratchPitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -headingPitchRoll.pitch, result); + result = Quaternion.multiply(scratchPitchQuaternion, scratchRollQuaternion, scratchPitchQuaternion); + scratchHeadingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -headingPitchRoll.heading, scratchHPRQuaternion); + return Quaternion.multiply(scratchHeadingQuaternion, result, result); }; - TerrainEncoding.prototype.getOctEncodedNormal = function(buffer, index, result) { - var stride = this.getStride(); - index = (index + 1) * stride - 1; + var sampledQuaternionAxis = new Cartesian3(); + var sampledQuaternionRotation = new Cartesian3(); + var sampledQuaternionTempQuaternion = new Quaternion(); + var sampledQuaternionQuaternion0 = new Quaternion(); + var sampledQuaternionQuaternion0Conjugate = new Quaternion(); - var temp = buffer[index] / 256.0; - var x = Math.floor(temp); - var y = (temp - x) * 256.0; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + Quaternion.packedLength = 4; - return Cartesian2.fromElements(x, y, result); - }; + /** + * Stores the provided instance into the provided array. + * + * @param {Quaternion} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + Quaternion.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - TerrainEncoding.prototype.getStride = function() { - var vertexStride; + array[startingIndex++] = value.x; + array[startingIndex++] = value.y; + array[startingIndex++] = value.z; + array[startingIndex] = value.w; - switch (this.quantization) { - case TerrainQuantization.BITS12: - vertexStride = 3; - break; - default: - vertexStride = 6; - } + return array; + }; - if (this.hasWebMercatorT) { - ++vertexStride; - } + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Quaternion} [result] The object into which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + */ + Quaternion.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - if (this.hasVertexNormals) { - ++vertexStride; + if (!defined(result)) { + result = new Quaternion(); } - - return vertexStride; + result.x = array[startingIndex]; + result.y = array[startingIndex + 1]; + result.z = array[startingIndex + 2]; + result.w = array[startingIndex + 3]; + return result; }; - var attributesNone = { - position3DAndHeight : 0, - textureCoordAndEncodedNormals : 1 - }; - var attributes = { - compressed0 : 0, - compressed1 : 1 - }; + /** + * The number of elements used to store the object into an array in its interpolatable form. + * @type {Number} + */ + Quaternion.packedInterpolationLength = 3; - TerrainEncoding.prototype.getAttributes = function(buffer) { - var datatype = ComponentDatatype.FLOAT; - var sizeInBytes = ComponentDatatype.getSizeInBytes(datatype); - var stride; + /** + * Converts a packed array into a form suitable for interpolation. + * + * @param {Number[]} packedArray The packed array. + * @param {Number} [startingIndex=0] The index of the first element to be converted. + * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. + * @param {Number[]} result The object into which to store the result. + */ + Quaternion.convertPackedArrayForInterpolation = function(packedArray, startingIndex, lastIndex, result) { + Quaternion.unpack(packedArray, lastIndex * 4, sampledQuaternionQuaternion0Conjugate); + Quaternion.conjugate(sampledQuaternionQuaternion0Conjugate, sampledQuaternionQuaternion0Conjugate); - if (this.quantization === TerrainQuantization.NONE) { - var position3DAndHeightLength = 4; - var numTexCoordComponents = 2; + for (var i = 0, len = lastIndex - startingIndex + 1; i < len; i++) { + var offset = i * 3; + Quaternion.unpack(packedArray, (startingIndex + i) * 4, sampledQuaternionTempQuaternion); - if (this.hasWebMercatorT) { - ++numTexCoordComponents; - } + Quaternion.multiply(sampledQuaternionTempQuaternion, sampledQuaternionQuaternion0Conjugate, sampledQuaternionTempQuaternion); - if (this.hasVertexNormals) { - ++numTexCoordComponents; + if (sampledQuaternionTempQuaternion.w < 0) { + Quaternion.negate(sampledQuaternionTempQuaternion, sampledQuaternionTempQuaternion); } - stride = (position3DAndHeightLength + numTexCoordComponents) * sizeInBytes; - - return [{ - index : attributesNone.position3DAndHeight, - vertexBuffer : buffer, - componentDatatype : datatype, - componentsPerAttribute : position3DAndHeightLength, - offsetInBytes : 0, - strideInBytes : stride - }, { - index : attributesNone.textureCoordAndEncodedNormals, - vertexBuffer : buffer, - componentDatatype : datatype, - componentsPerAttribute : numTexCoordComponents, - offsetInBytes : position3DAndHeightLength * sizeInBytes, - strideInBytes : stride - }]; + Quaternion.computeAxis(sampledQuaternionTempQuaternion, sampledQuaternionAxis); + var angle = Quaternion.computeAngle(sampledQuaternionTempQuaternion); + result[offset] = sampledQuaternionAxis.x * angle; + result[offset + 1] = sampledQuaternionAxis.y * angle; + result[offset + 2] = sampledQuaternionAxis.z * angle; } + }; - var numCompressed0 = 3; - var numCompressed1 = 0; - - if (this.hasWebMercatorT || this.hasVertexNormals) { - ++numCompressed0; + /** + * Retrieves an instance from a packed array converted with {@link convertPackedArrayForInterpolation}. + * + * @param {Number[]} array The array previously packed for interpolation. + * @param {Number[]} sourceArray The original packed array. + * @param {Number} [firstIndex=0] The firstIndex used to convert the array. + * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. + * @param {Quaternion} [result] The object into which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + */ + Quaternion.unpackInterpolationResult = function(array, sourceArray, firstIndex, lastIndex, result) { + if (!defined(result)) { + result = new Quaternion(); } + Cartesian3.fromArray(array, 0, sampledQuaternionRotation); + var magnitude = Cartesian3.magnitude(sampledQuaternionRotation); - if (this.hasWebMercatorT && this.hasVertexNormals) { - ++numCompressed1; - - stride = (numCompressed0 + numCompressed1) * sizeInBytes; + Quaternion.unpack(sourceArray, lastIndex * 4, sampledQuaternionQuaternion0); - return [{ - index : attributes.compressed0, - vertexBuffer : buffer, - componentDatatype : datatype, - componentsPerAttribute : numCompressed0, - offsetInBytes : 0, - strideInBytes : stride - }, { - index : attributes.compressed1, - vertexBuffer : buffer, - componentDatatype : datatype, - componentsPerAttribute : numCompressed1, - offsetInBytes : numCompressed0 * sizeInBytes, - strideInBytes : stride - }]; + if (magnitude === 0) { + Quaternion.clone(Quaternion.IDENTITY, sampledQuaternionTempQuaternion); + } else { + Quaternion.fromAxisAngle(sampledQuaternionRotation, magnitude, sampledQuaternionTempQuaternion); } - return [{ - index : attributes.compressed0, - vertexBuffer : buffer, - componentDatatype : datatype, - componentsPerAttribute : numCompressed0 - }]; + + return Quaternion.multiply(sampledQuaternionTempQuaternion, sampledQuaternionQuaternion0, result); }; - TerrainEncoding.prototype.getAttributeLocations = function() { - if (this.quantization === TerrainQuantization.NONE) { - return attributesNone; + /** + * Duplicates a Quaternion instance. + * + * @param {Quaternion} quaternion The quaternion to duplicate. + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. (Returns undefined if quaternion is undefined) + */ + Quaternion.clone = function(quaternion, result) { + if (!defined(quaternion)) { + return undefined; } - return attributes; - }; - TerrainEncoding.clone = function(encoding, result) { if (!defined(result)) { - result = new TerrainEncoding(); + return new Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w); } - result.quantization = encoding.quantization; - result.minimumHeight = encoding.minimumHeight; - result.maximumHeight = encoding.maximumHeight; - result.center = Cartesian3.clone(encoding.center); - result.toScaledENU = Matrix4.clone(encoding.toScaledENU); - result.fromScaledENU = Matrix4.clone(encoding.fromScaledENU); - result.matrix = Matrix4.clone(encoding.matrix); - result.hasVertexNormals = encoding.hasVertexNormals; - result.hasWebMercatorT = encoding.hasWebMercatorT; + result.x = quaternion.x; + result.y = quaternion.y; + result.z = quaternion.z; + result.w = quaternion.w; return result; }; - return TerrainEncoding; -}); - -define('Core/WebMercatorProjection',[ - './Cartesian3', - './Cartographic', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid', - './Math' - ], function( - Cartesian3, - Cartographic, - defaultValue, - defined, - defineProperties, - DeveloperError, - Ellipsoid, - CesiumMath) { - 'use strict'; - - /** - * The map projection used by Google Maps, Bing Maps, and most of ArcGIS Online, EPSG:3857. This - * projection use longitude and latitude expressed with the WGS84 and transforms them to Mercator using - * the spherical (rather than ellipsoidal) equations. - * - * @alias WebMercatorProjection - * @constructor - * - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid. - * - * @see GeographicProjection - */ - function WebMercatorProjection(ellipsoid) { - this._ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - this._semimajorAxis = this._ellipsoid.maximumRadius; - this._oneOverSemimajorAxis = 1.0 / this._semimajorAxis; - } - - defineProperties(WebMercatorProjection.prototype, { - /** - * Gets the {@link Ellipsoid}. - * - * @memberof WebMercatorProjection.prototype - * - * @type {Ellipsoid} - * @readonly - */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } - } - }); - /** - * Converts a Mercator angle, in the range -PI to PI, to a geodetic latitude - * in the range -PI/2 to PI/2. + * Computes the conjugate of the provided quaternion. * - * @param {Number} mercatorAngle The angle to convert. - * @returns {Number} The geodetic latitude in radians. + * @param {Quaternion} quaternion The quaternion to conjugate. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. */ - WebMercatorProjection.mercatorAngleToGeodeticLatitude = function(mercatorAngle) { - return CesiumMath.PI_OVER_TWO - (2.0 * Math.atan(Math.exp(-mercatorAngle))); + Quaternion.conjugate = function(quaternion, result) { + Check.typeOf.object('quaternion', quaternion); + Check.typeOf.object('result', result); + + result.x = -quaternion.x; + result.y = -quaternion.y; + result.z = -quaternion.z; + result.w = quaternion.w; + return result; }; /** - * Converts a geodetic latitude in radians, in the range -PI/2 to PI/2, to a Mercator - * angle in the range -PI to PI. + * Computes magnitude squared for the provided quaternion. * - * @param {Number} latitude The geodetic latitude in radians. - * @returns {Number} The Mercator angle. + * @param {Quaternion} quaternion The quaternion to conjugate. + * @returns {Number} The magnitude squared. */ - WebMercatorProjection.geodeticLatitudeToMercatorAngle = function(latitude) { - // Clamp the latitude coordinate to the valid Mercator bounds. - if (latitude > WebMercatorProjection.MaximumLatitude) { - latitude = WebMercatorProjection.MaximumLatitude; - } else if (latitude < -WebMercatorProjection.MaximumLatitude) { - latitude = -WebMercatorProjection.MaximumLatitude; - } - var sinLatitude = Math.sin(latitude); - return 0.5 * Math.log((1.0 + sinLatitude) / (1.0 - sinLatitude)); + Quaternion.magnitudeSquared = function(quaternion) { + Check.typeOf.object('quaternion', quaternion); + + return quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z * quaternion.z + quaternion.w * quaternion.w; }; /** - * The maximum latitude (both North and South) supported by a Web Mercator - * (EPSG:3857) projection. Technically, the Mercator projection is defined - * for any latitude up to (but not including) 90 degrees, but it makes sense - * to cut it off sooner because it grows exponentially with increasing latitude. - * The logic behind this particular cutoff value, which is the one used by - * Google Maps, Bing Maps, and Esri, is that it makes the projection - * square. That is, the rectangle is equal in the X and Y directions. - * - * The constant value is computed by calling: - * WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI) + * Computes magnitude for the provided quaternion. * - * @type {Number} + * @param {Quaternion} quaternion The quaternion to conjugate. + * @returns {Number} The magnitude. */ - WebMercatorProjection.MaximumLatitude = WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI); + Quaternion.magnitude = function(quaternion) { + return Math.sqrt(Quaternion.magnitudeSquared(quaternion)); + }; /** - * Converts geodetic ellipsoid coordinates, in radians, to the equivalent Web Mercator - * X, Y, Z coordinates expressed in meters and returned in a {@link Cartesian3}. The height - * is copied unmodified to the Z coordinate. + * Computes the normalized form of the provided quaternion. * - * @param {Cartographic} cartographic The cartographic coordinates in radians. - * @param {Cartesian3} [result] The instance to which to copy the result, or undefined if a - * new instance should be created. - * @returns {Cartesian3} The equivalent web mercator X, Y, Z coordinates, in meters. + * @param {Quaternion} quaternion The quaternion to normalize. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. */ - WebMercatorProjection.prototype.project = function(cartographic, result) { - var semimajorAxis = this._semimajorAxis; - var x = cartographic.longitude * semimajorAxis; - var y = WebMercatorProjection.geodeticLatitudeToMercatorAngle(cartographic.latitude) * semimajorAxis; - var z = cartographic.height; - - if (!defined(result)) { - return new Cartesian3(x, y, z); - } + Quaternion.normalize = function(quaternion, result) { + Check.typeOf.object('result', result); + + var inverseMagnitude = 1.0 / Quaternion.magnitude(quaternion); + var x = quaternion.x * inverseMagnitude; + var y = quaternion.y * inverseMagnitude; + var z = quaternion.z * inverseMagnitude; + var w = quaternion.w * inverseMagnitude; result.x = x; result.y = y; result.z = z; + result.w = w; return result; }; /** - * Converts Web Mercator X, Y coordinates, expressed in meters, to a {@link Cartographic} - * containing geodetic ellipsoid coordinates. The Z coordinate is copied unmodified to the - * height. + * Computes the inverse of the provided quaternion. * - * @param {Cartesian3} cartesian The web mercator Cartesian position to unrproject with height (z) in meters. - * @param {Cartographic} [result] The instance to which to copy the result, or undefined if a - * new instance should be created. - * @returns {Cartographic} The equivalent cartographic coordinates. + * @param {Quaternion} quaternion The quaternion to normalize. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. */ - WebMercatorProjection.prototype.unproject = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required'); - } + Quaternion.inverse = function(quaternion, result) { + Check.typeOf.object('result', result); - var oneOverEarthSemimajorAxis = this._oneOverSemimajorAxis; - var longitude = cartesian.x * oneOverEarthSemimajorAxis; - var latitude = WebMercatorProjection.mercatorAngleToGeodeticLatitude(cartesian.y * oneOverEarthSemimajorAxis); - var height = cartesian.z; - - if (!defined(result)) { - return new Cartographic(longitude, latitude, height); - } - - result.longitude = longitude; - result.latitude = latitude; - result.height = height; - return result; + var magnitudeSquared = Quaternion.magnitudeSquared(quaternion); + result = Quaternion.conjugate(quaternion, result); + return Quaternion.multiplyByScalar(result, 1.0 / magnitudeSquared, result); }; - return WebMercatorProjection; -}); - -define('Core/HeightmapTessellator',[ - './AxisAlignedBoundingBox', - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './defaultValue', - './defined', - './DeveloperError', - './Ellipsoid', - './EllipsoidalOccluder', - './freezeObject', - './Math', - './Matrix4', - './OrientedBoundingBox', - './Rectangle', - './TerrainEncoding', - './Transforms', - './WebMercatorProjection' - ], function( - AxisAlignedBoundingBox, - BoundingSphere, - Cartesian2, - Cartesian3, - defaultValue, - defined, - DeveloperError, - Ellipsoid, - EllipsoidalOccluder, - freezeObject, - CesiumMath, - Matrix4, - OrientedBoundingBox, - Rectangle, - TerrainEncoding, - Transforms, - WebMercatorProjection) { - 'use strict'; - /** - * Contains functions to create a mesh from a heightmap image. - * - * @exports HeightmapTessellator + * Computes the componentwise sum of two quaternions. * - * @private + * @param {Quaternion} left The first quaternion. + * @param {Quaternion} right The second quaternion. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. */ - var HeightmapTessellator = {}; + Quaternion.add = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.x = left.x + right.x; + result.y = left.y + right.y; + result.z = left.z + right.z; + result.w = left.w + right.w; + return result; + }; /** - * The default structure of a heightmap, as given to {@link HeightmapTessellator.computeVertices}. + * Computes the componentwise difference of two quaternions. * - * @constant + * @param {Quaternion} left The first quaternion. + * @param {Quaternion} right The second quaternion. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. */ - HeightmapTessellator.DEFAULT_STRUCTURE = freezeObject({ - heightScale : 1.0, - heightOffset : 0.0, - elementsPerHeight : 1, - stride : 1, - elementMultiplier : 256.0, - isBigEndian : false - }); - - var cartesian3Scratch = new Cartesian3(); - var matrix4Scratch = new Matrix4(); - var minimumScratch = new Cartesian3(); - var maximumScratch = new Cartesian3(); + Quaternion.subtract = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.x = left.x - right.x; + result.y = left.y - right.y; + result.z = left.z - right.z; + result.w = left.w - right.w; + return result; + }; /** - * Fills an array of vertices from a heightmap image. - * - * @param {Object} options Object with the following properties: - * @param {TypedArray} options.heightmap The heightmap to tessellate. - * @param {Number} options.width The width of the heightmap, in height samples. - * @param {Number} options.height The height of the heightmap, in height samples. - * @param {Number} options.skirtHeight The height of skirts to drape at the edges of the heightmap. - * @param {Rectangle} options.nativeRectangle A rectangle in the native coordinates of the heightmap's projection. For - * a heightmap with a geographic projection, this is degrees. For the web mercator - * projection, this is meters. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Rectangle} [options.rectangle] The rectangle covered by the heightmap, in geodetic coordinates with north, south, east and - * west properties in radians. Either rectangle or nativeRectangle must be provided. If both - * are provided, they're assumed to be consistent. - * @param {Boolean} [options.isGeographic=true] True if the heightmap uses a {@link GeographicProjection}, or false if it uses - * a {@link WebMercatorProjection}. - * @param {Cartesian3} [options.relativeToCenter=Cartesian3.ZERO] The positions will be computed as <code>Cartesian3.subtract(worldPosition, relativeToCenter)</code>. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to which the heightmap applies. - * @param {Object} [options.structure] An object describing the structure of the height data. - * @param {Number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain - * the height above the heightOffset, in meters. The heightOffset is added to the resulting - * height after multiplying by the scale. - * @param {Number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final - * height in meters. The offset is added after the height sample is multiplied by the - * heightScale. - * @param {Number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height - * sample. This is usually 1, indicating that each element is a separate height sample. If - * it is greater than 1, that number of elements together form the height sample, which is - * computed according to the structure.elementMultiplier and structure.isBigEndian properties. - * @param {Number} [options.structure.stride=1] The number of elements to skip to get from the first element of - * one height to the first element of the next height. - * @param {Number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the - * stride property is greater than 1. For example, if the stride is 4 and the strideMultiplier - * is 256, the height is computed as follows: - * `height = buffer[index] + buffer[index + 1] * 256 + buffer[index + 2] * 256 * 256 + buffer[index + 3] * 256 * 256 * 256` - * This is assuming that the isBigEndian property is false. If it is true, the order of the - * elements is reversed. - * @param {Number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower - * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height - * buffer is a `Uint16Array`, this value should be 0 because a `Uint16Array` cannot store negative numbers. If this parameter is - * not specified, no minimum value is enforced. - * @param {Number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher - * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height - * buffer is a `Uint16Array`, this value should be `256 * 256 - 1` or 65535 because a `Uint16Array` cannot store numbers larger - * than 65535. If this parameter is not specified, no maximum value is enforced. - * @param {Boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the - * stride property is greater than 1. If this property is false, the first element is the - * low-order element. If it is true, the first element is the high-order element. + * Negates the provided quaternion. * - * @example - * var width = 5; - * var height = 5; - * var statistics = Cesium.HeightmapTessellator.computeVertices({ - * heightmap : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], - * width : width, - * height : height, - * skirtHeight : 0.0, - * nativeRectangle : { - * west : 10.0, - * east : 20.0, - * south : 30.0, - * north : 40.0 - * } - * }); + * @param {Quaternion} quaternion The quaternion to be negated. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + */ + Quaternion.negate = function(quaternion, result) { + Check.typeOf.object('quaternion', quaternion); + Check.typeOf.object('result', result); + + result.x = -quaternion.x; + result.y = -quaternion.y; + result.z = -quaternion.z; + result.w = -quaternion.w; + return result; + }; + + /** + * Computes the dot (scalar) product of two quaternions. * - * var encoding = statistics.encoding; - * var position = encoding.decodePosition(statistics.vertices, index * encoding.getStride()); + * @param {Quaternion} left The first quaternion. + * @param {Quaternion} right The second quaternion. + * @returns {Number} The dot product. */ - HeightmapTessellator.computeVertices = function(options) { - if (!defined(options) || !defined(options.heightmap)) { - throw new DeveloperError('options.heightmap is required.'); - } - if (!defined(options.width) || !defined(options.height)) { - throw new DeveloperError('options.width and options.height are required.'); - } - if (!defined(options.nativeRectangle)) { - throw new DeveloperError('options.nativeRectangle is required.'); - } - if (!defined(options.skirtHeight)) { - throw new DeveloperError('options.skirtHeight is required.'); - } + Quaternion.dot = function(left, right) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); - // This function tends to be a performance hotspot for terrain rendering, - // so it employs a lot of inlining and unrolling as an optimization. - // In particular, the functionality of Ellipsoid.cartographicToCartesian - // is inlined. + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + }; - var cos = Math.cos; - var sin = Math.sin; - var sqrt = Math.sqrt; - var atan = Math.atan; - var exp = Math.exp; - var piOverTwo = CesiumMath.PI_OVER_TWO; - var toRadians = CesiumMath.toRadians; + /** + * Computes the product of two quaternions. + * + * @param {Quaternion} left The first quaternion. + * @param {Quaternion} right The second quaternion. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + */ + Quaternion.multiply = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + var leftX = left.x; + var leftY = left.y; + var leftZ = left.z; + var leftW = left.w; - var heightmap = options.heightmap; - var width = options.width; - var height = options.height; - var skirtHeight = options.skirtHeight; + var rightX = right.x; + var rightY = right.y; + var rightZ = right.z; + var rightW = right.w; - var isGeographic = defaultValue(options.isGeographic, true); - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var x = leftW * rightX + leftX * rightW + leftY * rightZ - leftZ * rightY; + var y = leftW * rightY - leftX * rightZ + leftY * rightW + leftZ * rightX; + var z = leftW * rightZ + leftX * rightY - leftY * rightX + leftZ * rightW; + var w = leftW * rightW - leftX * rightX - leftY * rightY - leftZ * rightZ; - var oneOverGlobeSemimajorAxis = 1.0 / ellipsoid.maximumRadius; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + }; - var nativeRectangle = options.nativeRectangle; + /** + * Multiplies the provided quaternion componentwise by the provided scalar. + * + * @param {Quaternion} quaternion The quaternion to be scaled. + * @param {Number} scalar The scalar to multiply with. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + */ + Quaternion.multiplyByScalar = function(quaternion, scalar, result) { + Check.typeOf.object('quaternion', quaternion); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result.x = quaternion.x * scalar; + result.y = quaternion.y * scalar; + result.z = quaternion.z * scalar; + result.w = quaternion.w * scalar; + return result; + }; - var geographicWest; - var geographicSouth; - var geographicEast; - var geographicNorth; + /** + * Divides the provided quaternion componentwise by the provided scalar. + * + * @param {Quaternion} quaternion The quaternion to be divided. + * @param {Number} scalar The scalar to divide by. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + */ + Quaternion.divideByScalar = function(quaternion, scalar, result) { + Check.typeOf.object('quaternion', quaternion); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result.x = quaternion.x / scalar; + result.y = quaternion.y / scalar; + result.z = quaternion.z / scalar; + result.w = quaternion.w / scalar; + return result; + }; - var rectangle = options.rectangle; - if (!defined(rectangle)) { - if (isGeographic) { - geographicWest = toRadians(nativeRectangle.west); - geographicSouth = toRadians(nativeRectangle.south); - geographicEast = toRadians(nativeRectangle.east); - geographicNorth = toRadians(nativeRectangle.north); - } else { - geographicWest = nativeRectangle.west * oneOverGlobeSemimajorAxis; - geographicSouth = piOverTwo - (2.0 * atan(exp(-nativeRectangle.south * oneOverGlobeSemimajorAxis))); - geographicEast = nativeRectangle.east * oneOverGlobeSemimajorAxis; - geographicNorth = piOverTwo - (2.0 * atan(exp(-nativeRectangle.north * oneOverGlobeSemimajorAxis))); - } - } else { - geographicWest = rectangle.west; - geographicSouth = rectangle.south; - geographicEast = rectangle.east; - geographicNorth = rectangle.north; + /** + * Computes the axis of rotation of the provided quaternion. + * + * @param {Quaternion} quaternion The quaternion to use. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. + */ + Quaternion.computeAxis = function(quaternion, result) { + Check.typeOf.object('quaternion', quaternion); + Check.typeOf.object('result', result); + + var w = quaternion.w; + if (Math.abs(w - 1.0) < CesiumMath.EPSILON6) { + result.x = result.y = result.z = 0; + return result; } - var relativeToCenter = options.relativeToCenter; - var hasRelativeToCenter = defined(relativeToCenter); - relativeToCenter = hasRelativeToCenter ? relativeToCenter : Cartesian3.ZERO; - var exaggeration = defaultValue(options.exaggeration, 1.0); - var includeWebMercatorT = defaultValue(options.includeWebMercatorT, false); - - var structure = defaultValue(options.structure, HeightmapTessellator.DEFAULT_STRUCTURE); - var heightScale = defaultValue(structure.heightScale, HeightmapTessellator.DEFAULT_STRUCTURE.heightScale); - var heightOffset = defaultValue(structure.heightOffset, HeightmapTessellator.DEFAULT_STRUCTURE.heightOffset); - var elementsPerHeight = defaultValue(structure.elementsPerHeight, HeightmapTessellator.DEFAULT_STRUCTURE.elementsPerHeight); - var stride = defaultValue(structure.stride, HeightmapTessellator.DEFAULT_STRUCTURE.stride); - var elementMultiplier = defaultValue(structure.elementMultiplier, HeightmapTessellator.DEFAULT_STRUCTURE.elementMultiplier); - var isBigEndian = defaultValue(structure.isBigEndian, HeightmapTessellator.DEFAULT_STRUCTURE.isBigEndian); - - var rectangleWidth = Rectangle.computeWidth(nativeRectangle); - var rectangleHeight = Rectangle.computeHeight(nativeRectangle); + var scalar = 1.0 / Math.sqrt(1.0 - (w * w)); - var granularityX = rectangleWidth / (width - 1); - var granularityY = rectangleHeight / (height - 1); + result.x = quaternion.x * scalar; + result.y = quaternion.y * scalar; + result.z = quaternion.z * scalar; + return result; + }; - if (!isGeographic) { - rectangleWidth *= oneOverGlobeSemimajorAxis; - rectangleHeight *= oneOverGlobeSemimajorAxis; + /** + * Computes the angle of rotation of the provided quaternion. + * + * @param {Quaternion} quaternion The quaternion to use. + * @returns {Number} The angle of rotation. + */ + Quaternion.computeAngle = function(quaternion) { + Check.typeOf.object('quaternion', quaternion); + + if (Math.abs(quaternion.w - 1.0) < CesiumMath.EPSILON6) { + return 0.0; } + return 2.0 * Math.acos(quaternion.w); + }; - var radiiSquared = ellipsoid.radiiSquared; - var radiiSquaredX = radiiSquared.x; - var radiiSquaredY = radiiSquared.y; - var radiiSquaredZ = radiiSquared.z; - - var minimumHeight = 65536.0; - var maximumHeight = -65536.0; + var lerpScratch = new Quaternion(); + /** + * Computes the linear interpolation or extrapolation at t using the provided quaternions. + * + * @param {Quaternion} start The value corresponding to t at 0.0. + * @param {Quaternion} end The value corresponding to t at 1.0. + * @param {Number} t The point along t at which to interpolate. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + */ + Quaternion.lerp = function(start, end, t, result) { + Check.typeOf.object('start', start); + Check.typeOf.object('end', end); + Check.typeOf.number('t', t); + Check.typeOf.object('result', result); + + lerpScratch = Quaternion.multiplyByScalar(end, t, lerpScratch); + result = Quaternion.multiplyByScalar(start, 1.0 - t, result); + return Quaternion.add(lerpScratch, result, result); + }; - var fromENU = Transforms.eastNorthUpToFixedFrame(relativeToCenter, ellipsoid); - var toENU = Matrix4.inverseTransformation(fromENU, matrix4Scratch); + var slerpEndNegated = new Quaternion(); + var slerpScaledP = new Quaternion(); + var slerpScaledR = new Quaternion(); + /** + * Computes the spherical linear interpolation or extrapolation at t using the provided quaternions. + * + * @param {Quaternion} start The value corresponding to t at 0.0. + * @param {Quaternion} end The value corresponding to t at 1.0. + * @param {Number} t The point along t at which to interpolate. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + * + * @see Quaternion#fastSlerp + */ + Quaternion.slerp = function(start, end, t, result) { + Check.typeOf.object('start', start); + Check.typeOf.object('end', end); + Check.typeOf.number('t', t); + Check.typeOf.object('result', result); + + var dot = Quaternion.dot(start, end); - var southMercatorY; - var oneOverMercatorHeight; - if (includeWebMercatorT) { - southMercatorY = WebMercatorProjection.geodeticLatitudeToMercatorAngle(geographicSouth); - oneOverMercatorHeight = 1.0 / (WebMercatorProjection.geodeticLatitudeToMercatorAngle(geographicNorth) - southMercatorY); + // The angle between start must be acute. Since q and -q represent + // the same rotation, negate q to get the acute angle. + var r = end; + if (dot < 0.0) { + dot = -dot; + r = slerpEndNegated = Quaternion.negate(end, slerpEndNegated); } - var minimum = minimumScratch; - minimum.x = Number.POSITIVE_INFINITY; - minimum.y = Number.POSITIVE_INFINITY; - minimum.z = Number.POSITIVE_INFINITY; - - var maximum = maximumScratch; - maximum.x = Number.NEGATIVE_INFINITY; - maximum.y = Number.NEGATIVE_INFINITY; - maximum.z = Number.NEGATIVE_INFINITY; - - var hMin = Number.POSITIVE_INFINITY; - - var arrayWidth = width + (skirtHeight > 0.0 ? 2.0 : 0.0); - var arrayHeight = height + (skirtHeight > 0.0 ? 2.0 : 0.0); - var size = arrayWidth * arrayHeight; - var positions = new Array(size); - var heights = new Array(size); - var uvs = new Array(size); - var webMercatorTs = includeWebMercatorT ? new Array(size) : []; - - var startRow = 0; - var endRow = height; - var startCol = 0; - var endCol = width; - - if (skirtHeight > 0) { - --startRow; - ++endRow; - --startCol; - ++endCol; + // dot > 0, as the dot product approaches 1, the angle between the + // quaternions vanishes. use linear interpolation. + if (1.0 - dot < CesiumMath.EPSILON6) { + return Quaternion.lerp(start, r, t, result); } - var index = 0; - - for (var rowIndex = startRow; rowIndex < endRow; ++rowIndex) { - var row = rowIndex; - if (row < 0) { - row = 0; - } - if (row >= height) { - row = height - 1; - } - - var latitude = nativeRectangle.north - granularityY * row; - - if (!isGeographic) { - latitude = piOverTwo - (2.0 * atan(exp(-latitude * oneOverGlobeSemimajorAxis))); - } else { - latitude = toRadians(latitude); - } - - var cosLatitude = cos(latitude); - var nZ = sin(latitude); - var kZ = radiiSquaredZ * nZ; - - var v = (latitude - geographicSouth) / (geographicNorth - geographicSouth); - v = CesiumMath.clamp(v, 0.0, 1.0); - - var webMercatorT; - if (includeWebMercatorT) { - webMercatorT = (WebMercatorProjection.geodeticLatitudeToMercatorAngle(latitude) - southMercatorY) * oneOverMercatorHeight; - } - - for (var colIndex = startCol; colIndex < endCol; ++colIndex) { - var col = colIndex; - if (col < 0) { - col = 0; - } - if (col >= width) { - col = width - 1; - } - - var longitude = nativeRectangle.west + granularityX * col; - - if (!isGeographic) { - longitude = longitude * oneOverGlobeSemimajorAxis; - } else { - longitude = toRadians(longitude); - } + var theta = Math.acos(dot); + slerpScaledP = Quaternion.multiplyByScalar(start, Math.sin((1 - t) * theta), slerpScaledP); + slerpScaledR = Quaternion.multiplyByScalar(r, Math.sin(t * theta), slerpScaledR); + result = Quaternion.add(slerpScaledP, slerpScaledR, result); + return Quaternion.multiplyByScalar(result, 1.0 / Math.sin(theta), result); + }; - var terrainOffset = row * (width * stride) + col * stride; + /** + * The logarithmic quaternion function. + * + * @param {Quaternion} quaternion The unit quaternion. + * @param {Cartesian3} result The object onto which to store the result. + * @returns {Cartesian3} The modified result parameter. + */ + Quaternion.log = function(quaternion, result) { + Check.typeOf.object('quaternion', quaternion); + Check.typeOf.object('result', result); + + var theta = CesiumMath.acosClamped(quaternion.w); + var thetaOverSinTheta = 0.0; - var heightSample; - if (elementsPerHeight === 1) { - heightSample = heightmap[terrainOffset]; - } else { - heightSample = 0; + if (theta !== 0.0) { + thetaOverSinTheta = theta / Math.sin(theta); + } - var elementOffset; - if (isBigEndian) { - for (elementOffset = 0; elementOffset < elementsPerHeight; ++elementOffset) { - heightSample = (heightSample * elementMultiplier) + heightmap[terrainOffset + elementOffset]; - } - } else { - for (elementOffset = elementsPerHeight - 1; elementOffset >= 0; --elementOffset) { - heightSample = (heightSample * elementMultiplier) + heightmap[terrainOffset + elementOffset]; - } - } - } + return Cartesian3.multiplyByScalar(quaternion, thetaOverSinTheta, result); + }; - heightSample = (heightSample * heightScale + heightOffset) * exaggeration; + /** + * The exponential quaternion function. + * + * @param {Cartesian3} cartesian The cartesian. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + */ + Quaternion.exp = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var theta = Cartesian3.magnitude(cartesian); + var sinThetaOverTheta = 0.0; - var u = (longitude - geographicWest) / (geographicEast - geographicWest); - u = CesiumMath.clamp(u, 0.0, 1.0); - uvs[index] = new Cartesian2(u, v); + if (theta !== 0.0) { + sinThetaOverTheta = Math.sin(theta) / theta; + } - maximumHeight = Math.max(maximumHeight, heightSample); - minimumHeight = Math.min(minimumHeight, heightSample); + result.x = cartesian.x * sinThetaOverTheta; + result.y = cartesian.y * sinThetaOverTheta; + result.z = cartesian.z * sinThetaOverTheta; + result.w = Math.cos(theta); - if (colIndex !== col || rowIndex !== row) { - var percentage = 0.00001; - if (colIndex < 0) { - longitude -= percentage * rectangleWidth; - } else { - longitude += percentage * rectangleWidth; - } - if (rowIndex < 0) { - latitude += percentage * rectangleHeight; - } else { - latitude -= percentage * rectangleHeight; - } + return result; + }; - cosLatitude = cos(latitude); - nZ = sin(latitude); - kZ = radiiSquaredZ * nZ; - heightSample -= skirtHeight; - } + var squadScratchCartesian0 = new Cartesian3(); + var squadScratchCartesian1 = new Cartesian3(); + var squadScratchQuaternion0 = new Quaternion(); + var squadScratchQuaternion1 = new Quaternion(); - var nX = cosLatitude * cos(longitude); - var nY = cosLatitude * sin(longitude); + /** + * Computes an inner quadrangle point. + * <p>This will compute quaternions that ensure a squad curve is C<sup>1</sup>.</p> + * + * @param {Quaternion} q0 The first quaternion. + * @param {Quaternion} q1 The second quaternion. + * @param {Quaternion} q2 The third quaternion. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + * + * @see Quaternion#squad + */ + Quaternion.computeInnerQuadrangle = function(q0, q1, q2, result) { + Check.typeOf.object('q0', q0); + Check.typeOf.object('q1', q1); + Check.typeOf.object('q2', q2); + Check.typeOf.object('result', result); + + var qInv = Quaternion.conjugate(q1, squadScratchQuaternion0); + Quaternion.multiply(qInv, q2, squadScratchQuaternion1); + var cart0 = Quaternion.log(squadScratchQuaternion1, squadScratchCartesian0); - var kX = radiiSquaredX * nX; - var kY = radiiSquaredY * nY; + Quaternion.multiply(qInv, q0, squadScratchQuaternion1); + var cart1 = Quaternion.log(squadScratchQuaternion1, squadScratchCartesian1); - var gamma = sqrt((kX * nX) + (kY * nY) + (kZ * nZ)); - var oneOverGamma = 1.0 / gamma; + Cartesian3.add(cart0, cart1, cart0); + Cartesian3.multiplyByScalar(cart0, 0.25, cart0); + Cartesian3.negate(cart0, cart0); + Quaternion.exp(cart0, squadScratchQuaternion0); - var rSurfaceX = kX * oneOverGamma; - var rSurfaceY = kY * oneOverGamma; - var rSurfaceZ = kZ * oneOverGamma; + return Quaternion.multiply(q1, squadScratchQuaternion0, result); + }; - var position = new Cartesian3(); - position.x = rSurfaceX + nX * heightSample; - position.y = rSurfaceY + nY * heightSample; - position.z = rSurfaceZ + nZ * heightSample; + /** + * Computes the spherical quadrangle interpolation between quaternions. + * + * @param {Quaternion} q0 The first quaternion. + * @param {Quaternion} q1 The second quaternion. + * @param {Quaternion} s0 The first inner quadrangle. + * @param {Quaternion} s1 The second inner quadrangle. + * @param {Number} t The time in [0,1] used to interpolate. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + * + * + * @example + * // 1. compute the squad interpolation between two quaternions on a curve + * var s0 = Cesium.Quaternion.computeInnerQuadrangle(quaternions[i - 1], quaternions[i], quaternions[i + 1], new Cesium.Quaternion()); + * var s1 = Cesium.Quaternion.computeInnerQuadrangle(quaternions[i], quaternions[i + 1], quaternions[i + 2], new Cesium.Quaternion()); + * var q = Cesium.Quaternion.squad(quaternions[i], quaternions[i + 1], s0, s1, t, new Cesium.Quaternion()); + * + * // 2. compute the squad interpolation as above but where the first quaternion is a end point. + * var s1 = Cesium.Quaternion.computeInnerQuadrangle(quaternions[0], quaternions[1], quaternions[2], new Cesium.Quaternion()); + * var q = Cesium.Quaternion.squad(quaternions[0], quaternions[1], quaternions[0], s1, t, new Cesium.Quaternion()); + * + * @see Quaternion#computeInnerQuadrangle + */ + Quaternion.squad = function(q0, q1, s0, s1, t, result) { + Check.typeOf.object('q0', q0); + Check.typeOf.object('q1', q1); + Check.typeOf.object('s0', s0); + Check.typeOf.object('s1', s1); + Check.typeOf.number('t', t); + Check.typeOf.object('result', result); + + var slerp0 = Quaternion.slerp(q0, q1, t, squadScratchQuaternion0); + var slerp1 = Quaternion.slerp(s0, s1, t, squadScratchQuaternion1); + return Quaternion.slerp(slerp0, slerp1, 2.0 * t * (1.0 - t), result); + }; - positions[index] = position; - heights[index] = heightSample; + var fastSlerpScratchQuaternion = new Quaternion(); + var opmu = 1.90110745351730037; + var u = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; + var v = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; + var bT = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; + var bD = FeatureDetection.supportsTypedArrays() ? new Float32Array(8) : []; - if (includeWebMercatorT) { - webMercatorTs[index] = webMercatorT; - } + for (var i = 0; i < 7; ++i) { + var s = i + 1.0; + var t = 2.0 * s + 1.0; + u[i] = 1.0 / (s * t); + v[i] = s / t; + } - index++; + u[7] = opmu / (8.0 * 17.0); + v[7] = opmu * 8.0 / 17.0; - Matrix4.multiplyByPoint(toENU, position, cartesian3Scratch); + /** + * Computes the spherical linear interpolation or extrapolation at t using the provided quaternions. + * This implementation is faster than {@link Quaternion#slerp}, but is only accurate up to 10<sup>-6</sup>. + * + * @param {Quaternion} start The value corresponding to t at 0.0. + * @param {Quaternion} end The value corresponding to t at 1.0. + * @param {Number} t The point along t at which to interpolate. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter. + * + * @see Quaternion#slerp + */ + Quaternion.fastSlerp = function(start, end, t, result) { + Check.typeOf.object('start', start); + Check.typeOf.object('end', end); + Check.typeOf.number('t', t); + Check.typeOf.object('result', result); + + var x = Quaternion.dot(start, end); - Cartesian3.minimumByComponent(cartesian3Scratch, minimum, minimum); - Cartesian3.maximumByComponent(cartesian3Scratch, maximum, maximum); - hMin = Math.min(hMin, heightSample); - } + var sign; + if (x >= 0) { + sign = 1.0; + } else { + sign = -1.0; + x = -x; } - var boundingSphere3D = BoundingSphere.fromPoints(positions); - var orientedBoundingBox; - if (defined(rectangle) && rectangle.width < CesiumMath.PI_OVER_TWO + CesiumMath.EPSILON5) { - // Here, rectangle.width < pi/2, and rectangle.height < pi - // (though it would still work with rectangle.width up to pi) - orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, ellipsoid); - } + var xm1 = x - 1.0; + var d = 1.0 - t; + var sqrT = t * t; + var sqrD = d * d; - var occludeePointInScaledSpace; - if (hasRelativeToCenter) { - var occluder = new EllipsoidalOccluder(ellipsoid); - occludeePointInScaledSpace = occluder.computeHorizonCullingPoint(relativeToCenter, positions); + for (var i = 7; i >= 0; --i) { + bT[i] = (u[i] * sqrT - v[i]) * xm1; + bD[i] = (u[i] * sqrD - v[i]) * xm1; } - var aaBox = new AxisAlignedBoundingBox(minimum, maximum, relativeToCenter); - var encoding = new TerrainEncoding(aaBox, hMin, maximumHeight, fromENU, false, includeWebMercatorT); - var vertices = new Float32Array(size * encoding.getStride()); - - var bufferIndex = 0; - for (var j = 0; j < size; ++j) { - bufferIndex = encoding.encode(vertices, bufferIndex, positions[j], uvs[j], heights[j], undefined, webMercatorTs[j]); - } + var cT = sign * t * ( + 1.0 + bT[0] * (1.0 + bT[1] * (1.0 + bT[2] * (1.0 + bT[3] * ( + 1.0 + bT[4] * (1.0 + bT[5] * (1.0 + bT[6] * (1.0 + bT[7])))))))); + var cD = d * ( + 1.0 + bD[0] * (1.0 + bD[1] * (1.0 + bD[2] * (1.0 + bD[3] * ( + 1.0 + bD[4] * (1.0 + bD[5] * (1.0 + bD[6] * (1.0 + bD[7])))))))); - return { - vertices : vertices, - maximumHeight : maximumHeight, - minimumHeight : minimumHeight, - encoding : encoding, - boundingSphere3D : boundingSphere3D, - orientedBoundingBox : orientedBoundingBox, - occludeePointInScaledSpace : occludeePointInScaledSpace - }; + var temp = Quaternion.multiplyByScalar(start, cD, fastSlerpScratchQuaternion); + Quaternion.multiplyByScalar(end, cT, result); + return Quaternion.add(temp, result, result); }; - return HeightmapTessellator; -}); - -define('Core/destroyObject',[ - './defaultValue', - './DeveloperError' - ], function( - defaultValue, - DeveloperError) { - 'use strict'; - - function returnTrue() { - return true; - } - /** - * Destroys an object. Each of the object's functions, including functions in its prototype, - * is replaced with a function that throws a {@link DeveloperError}, except for the object's - * <code>isDestroyed</code> function, which is set to a function that returns <code>true</code>. - * The object's properties are removed with <code>delete</code>. - * <br /><br /> - * This function is used by objects that hold native resources, e.g., WebGL resources, which - * need to be explicitly released. Client code calls an object's <code>destroy</code> function, - * which then releases the native resource and calls <code>destroyObject</code> to put itself - * in a destroyed state. - * - * @exports destroyObject - * - * @param {Object} object The object to destroy. - * @param {String} [message] The message to include in the exception that is thrown if - * a destroyed object's function is called. - * + * Computes the spherical quadrangle interpolation between quaternions. + * An implementation that is faster than {@link Quaternion#squad}, but less accurate. * - * @example - * // How a texture would destroy itself. - * this.destroy = function () { - * _gl.deleteTexture(_texture); - * return Cesium.destroyObject(this); - * }; + * @param {Quaternion} q0 The first quaternion. + * @param {Quaternion} q1 The second quaternion. + * @param {Quaternion} s0 The first inner quadrangle. + * @param {Quaternion} s1 The second inner quadrangle. + * @param {Number} t The time in [0,1] used to interpolate. + * @param {Quaternion} result The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new instance if none was provided. * - * @see DeveloperError + * @see Quaternion#squad */ - function destroyObject(object, message) { - message = defaultValue(message, 'This object was destroyed, i.e., destroy() was called.'); - - function throwOnDestroyed() { - throw new DeveloperError(message); - } - - for ( var key in object) { - if (typeof object[key] === 'function') { - object[key] = throwOnDestroyed; - } - } - - object.isDestroyed = returnTrue; - - return undefined; - } + Quaternion.fastSquad = function(q0, q1, s0, s1, t, result) { + Check.typeOf.object('q0', q0); + Check.typeOf.object('q1', q1); + Check.typeOf.object('s0', s0); + Check.typeOf.object('s1', s1); + Check.typeOf.number('t', t); + Check.typeOf.object('result', result); + + var slerp0 = Quaternion.fastSlerp(q0, q1, t, squadScratchQuaternion0); + var slerp1 = Quaternion.fastSlerp(s0, s1, t, squadScratchQuaternion1); + return Quaternion.fastSlerp(slerp0, slerp1, 2.0 * t * (1.0 - t), result); + }; - return destroyObject; -}); + /** + * Compares the provided quaternions componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Quaternion} [left] The first quaternion. + * @param {Quaternion} [right] The second quaternion. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + Quaternion.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + (left.x === right.x) && + (left.y === right.y) && + (left.z === right.z) && + (left.w === right.w)); + }; -define('Core/isCrossOriginUrl',[ - './defined' - ], function( - defined) { - 'use strict'; + /** + * Compares the provided quaternions componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Quaternion} [left] The first quaternion. + * @param {Quaternion} [right] The second quaternion. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + */ + Quaternion.equalsEpsilon = function(left, right, epsilon) { + Check.typeOf.number('epsilon', epsilon); + + return (left === right) || + ((defined(left)) && + (defined(right)) && + (Math.abs(left.x - right.x) <= epsilon) && + (Math.abs(left.y - right.y) <= epsilon) && + (Math.abs(left.z - right.z) <= epsilon) && + (Math.abs(left.w - right.w) <= epsilon)); + }; - var a; + /** + * An immutable Quaternion instance initialized to (0.0, 0.0, 0.0, 0.0). + * + * @type {Quaternion} + * @constant + */ + Quaternion.ZERO = freezeObject(new Quaternion(0.0, 0.0, 0.0, 0.0)); /** - * Given a URL, determine whether that URL is considered cross-origin to the current page. + * An immutable Quaternion instance initialized to (0.0, 0.0, 0.0, 1.0). * - * @private + * @type {Quaternion} + * @constant */ - function isCrossOriginUrl(url) { - if (!defined(a)) { - a = document.createElement('a'); - } + Quaternion.IDENTITY = freezeObject(new Quaternion(0.0, 0.0, 0.0, 1.0)); - // copy window location into the anchor to get consistent results - // when the port is default for the protocol (e.g. 80 for HTTP) - a.href = window.location.href; + /** + * Duplicates this Quaternion instance. + * + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. + */ + Quaternion.prototype.clone = function(result) { + return Quaternion.clone(this, result); + }; - // host includes both hostname and port if the port is not standard - var host = a.host; - var protocol = a.protocol; + /** + * Compares this and the provided quaternion componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Quaternion} [right] The right hand side quaternion. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + Quaternion.prototype.equals = function(right) { + return Quaternion.equals(this, right); + }; - a.href = url; - a.href = a.href; // IE only absolutizes href on get, not set + /** + * Compares this and the provided quaternion componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Quaternion} [right] The right hand side quaternion. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + */ + Quaternion.prototype.equalsEpsilon = function(right, epsilon) { + return Quaternion.equalsEpsilon(this, right, epsilon); + }; - return protocol !== a.protocol || host !== a.host; - } + /** + * Returns a string representing this quaternion in the format (x, y, z, w). + * + * @returns {String} A string representing this Quaternion. + */ + Quaternion.prototype.toString = function() { + return '(' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ')'; + }; - return isCrossOriginUrl; + return Quaternion; }); -define('Core/TaskProcessor',[ +define('Core/Transforms',[ '../ThirdParty/when', - './buildModuleUrl', + './Cartesian2', + './Cartesian3', + './Cartesian4', + './Cartographic', + './Check', './defaultValue', './defined', - './destroyObject', './DeveloperError', - './getAbsoluteUri', - './isCrossOriginUrl', - './RuntimeError', - 'require' + './EarthOrientationParameters', + './EarthOrientationParametersSample', + './Ellipsoid', + './Iau2006XysData', + './Iau2006XysSample', + './JulianDate', + './Math', + './Matrix3', + './Matrix4', + './Quaternion', + './TimeConstants' ], function( when, - buildModuleUrl, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + Check, defaultValue, defined, - destroyObject, DeveloperError, - getAbsoluteUri, - isCrossOriginUrl, - RuntimeError, - require) { + EarthOrientationParameters, + EarthOrientationParametersSample, + Ellipsoid, + Iau2006XysData, + Iau2006XysSample, + JulianDate, + CesiumMath, + Matrix3, + Matrix4, + Quaternion, + TimeConstants) { 'use strict'; - function canTransferArrayBuffer() { - if (!defined(TaskProcessor._canTransferArrayBuffer)) { - var worker = new Worker(getWorkerUrl('Workers/transferTypedArrayTest.js')); - worker.postMessage = defaultValue(worker.webkitPostMessage, worker.postMessage); - - var value = 99; - var array = new Int8Array([value]); - - try { - // postMessage might fail with a DataCloneError - // if transferring array buffers is not supported. - worker.postMessage({ - array : array - }, [array.buffer]); - } catch (e) { - TaskProcessor._canTransferArrayBuffer = false; - return TaskProcessor._canTransferArrayBuffer; - } - - var deferred = when.defer(); + /** + * Contains functions for transforming positions to various reference frames. + * + * @exports Transforms + */ + var Transforms = {}; - worker.onmessage = function(event) { - var array = event.data.array; + var vectorProductLocalFrame = { + up : { + south : 'east', + north : 'west', + west : 'south', + east : 'north' + }, + down : { + south : 'west', + north : 'east', + west : 'north', + east : 'south' + }, + south : { + up : 'west', + down : 'east', + west : 'down', + east : 'up' + }, + north : { + up : 'east', + down : 'west', + west : 'up', + east : 'down' + }, + west : { + up : 'north', + down : 'south', + north : 'down', + south : 'up' + }, + east : { + up : 'south', + down : 'north', + north : 'up', + south : 'down' + } + }; - // some versions of Firefox silently fail to transfer typed arrays. - // https://bugzilla.mozilla.org/show_bug.cgi?id=841904 - // Check to make sure the value round-trips successfully. - var result = defined(array) && array[0] === value; - deferred.resolve(result); + var degeneratePositionLocalFrame = { + north : [-1, 0, 0], + east : [0, 1, 0], + up : [0, 0, 1], + south : [1, 0, 0], + west : [0, -1, 0], + down : [0, 0, -1] + }; - worker.terminate(); + var localFrameToFixedFrameCache = {}; - TaskProcessor._canTransferArrayBuffer = result; - }; + var scratchCalculateCartesian = { + east : new Cartesian3(), + north : new Cartesian3(), + up : new Cartesian3(), + west : new Cartesian3(), + south : new Cartesian3(), + down : new Cartesian3() + }; + var scratchFirstCartesian = new Cartesian3(); + var scratchSecondCartesian = new Cartesian3(); + var scratchThirdCartesian = new Cartesian3(); + /** + * Generates a function that computes a 4x4 transformation matrix from a reference frame + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * @param {String} firstAxis name of the first axis of the local reference frame. Must be + * 'east', 'north', 'up', 'west', 'south' or 'down'. + * @param {String} secondAxis name of the second axis of the local reference frame. Must be + * 'east', 'north', 'up', 'west', 'south' or 'down'. + * @return {localFrameToFixedFrameGenerator~resultat} The function that will computes a + * 4x4 transformation matrix from a reference frame, with first axis and second axis compliant with the parameters, + */ + Transforms.localFrameToFixedFrameGenerator = function( firstAxis, secondAxis) { + if (!vectorProductLocalFrame.hasOwnProperty(firstAxis) || !vectorProductLocalFrame[firstAxis].hasOwnProperty(secondAxis)) { + throw new DeveloperError('firstAxis and secondAxis must be east, north, up, west, south or down.'); + } + var thirdAxis = vectorProductLocalFrame[firstAxis][secondAxis]; - TaskProcessor._canTransferArrayBuffer = deferred.promise; - } + /** + * Computes a 4x4 transformation matrix from a reference frame + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * @callback Transforms~LocalFrameToFixedFrame + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + */ + var resultat; + var hashAxis = firstAxis + secondAxis; + if (defined(localFrameToFixedFrameCache[hashAxis])) { + resultat = localFrameToFixedFrameCache[hashAxis]; + } else { + resultat = function(origin, ellipsoid, result) { + if (!defined(origin)) { + throw new DeveloperError('origin is required.'); + } + if (!defined(result)) { + result = new Matrix4(); + } + // If x and y are zero, assume origin is at a pole, which is a special case. + if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { + var sign = CesiumMath.sign(origin.z); - return TaskProcessor._canTransferArrayBuffer; - } + Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian); + if (firstAxis !== 'east' && firstAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchFirstCartesian, sign, scratchFirstCartesian); + } - function completeTask(processor, data) { - --processor._activeTasks; + Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, scratchSecondCartesian); + if (secondAxis !== 'east' && secondAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchSecondCartesian, sign, scratchSecondCartesian); + } - var id = data.id; - if (!defined(id)) { - // This is not one of ours. - return; - } + Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, scratchThirdCartesian); + if (thirdAxis !== 'east' && thirdAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchThirdCartesian, sign, scratchThirdCartesian); + } + } else { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + ellipsoid.geodeticSurfaceNormal(origin, scratchCalculateCartesian.up); - var deferreds = processor._deferreds; - var deferred = deferreds[id]; + var up = scratchCalculateCartesian.up; + var east = scratchCalculateCartesian.east; + east.x = -origin.y; + east.y = origin.x; + east.z = 0.0; + Cartesian3.normalize(east, scratchCalculateCartesian.east); + Cartesian3.cross(up, east, scratchCalculateCartesian.north); - if (defined(data.error)) { - var error = data.error; - if (error.name === 'RuntimeError') { - error = new RuntimeError(data.error.message); - error.stack = data.error.stack; - } else if (error.name === 'DeveloperError') { - error = new DeveloperError(data.error.message); - error.stack = data.error.stack; - } - deferred.reject(error); - } else { - deferred.resolve(data.result); - } + Cartesian3.multiplyByScalar(scratchCalculateCartesian.up, -1, scratchCalculateCartesian.down); + Cartesian3.multiplyByScalar(scratchCalculateCartesian.east, -1, scratchCalculateCartesian.west); + Cartesian3.multiplyByScalar(scratchCalculateCartesian.north, -1, scratchCalculateCartesian.south); - delete deferreds[id]; - } + scratchFirstCartesian = scratchCalculateCartesian[firstAxis]; + scratchSecondCartesian = scratchCalculateCartesian[secondAxis]; + scratchThirdCartesian = scratchCalculateCartesian[thirdAxis]; + } + result[0] = scratchFirstCartesian.x; + result[1] = scratchFirstCartesian.y; + result[2] = scratchFirstCartesian.z; + result[3] = 0.0; + result[4] = scratchSecondCartesian.x; + result[5] = scratchSecondCartesian.y; + result[6] = scratchSecondCartesian.z; + result[7] = 0.0; + result[8] = scratchThirdCartesian.x; + result[9] = scratchThirdCartesian.y; + result[10] = scratchThirdCartesian.z; + result[11] = 0.0; + result[12] = origin.x; + result[13] = origin.y; + result[14] = origin.z; + result[15] = 1.0; + return result; + }; + localFrameToFixedFrameCache[hashAxis] = resultat; + } + return resultat; + }; - function getWorkerUrl(moduleID) { - var url = buildModuleUrl(moduleID); + /** + * Computes a 4x4 transformation matrix from a reference frame with an east-north-up axes + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * The local axes are defined as: + * <ul> + * <li>The <code>x</code> axis points in the local east direction.</li> + * <li>The <code>y</code> axis points in the local north direction.</li> + * <li>The <code>z</code> axis points in the direction of the ellipsoid surface normal which passes through the position.</li> + * </ul> + * + * @function + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + * + * @example + * // Get the transform from local east-north-up at cartographic (0.0, 0.0) to Earth's fixed frame. + * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); + */ + Transforms.eastNorthUpToFixedFrame = Transforms.localFrameToFixedFrameGenerator('east','north'); - if (isCrossOriginUrl(url)) { - //to load cross-origin, create a shim worker from a blob URL - var script = 'importScripts("' + url + '");'; + /** + * Computes a 4x4 transformation matrix from a reference frame with an north-east-down axes + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * The local axes are defined as: + * <ul> + * <li>The <code>x</code> axis points in the local north direction.</li> + * <li>The <code>y</code> axis points in the local east direction.</li> + * <li>The <code>z</code> axis points in the opposite direction of the ellipsoid surface normal which passes through the position.</li> + * </ul> + * + * @function + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + * + * @example + * // Get the transform from local north-east-down at cartographic (0.0, 0.0) to Earth's fixed frame. + * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var transform = Cesium.Transforms.northEastDownToFixedFrame(center); + */ + Transforms.northEastDownToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','east'); - var blob; - try { - blob = new Blob([script], { - type : 'application/javascript' - }); - } catch (e) { - var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; - var blobBuilder = new BlobBuilder(); - blobBuilder.append(script); - blob = blobBuilder.getBlob('application/javascript'); - } + /** + * Computes a 4x4 transformation matrix from a reference frame with an north-up-east axes + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * The local axes are defined as: + * <ul> + * <li>The <code>x</code> axis points in the local north direction.</li> + * <li>The <code>y</code> axis points in the direction of the ellipsoid surface normal which passes through the position.</li> + * <li>The <code>z</code> axis points in the local east direction.</li> + * </ul> + * + * @function + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + * + * @example + * // Get the transform from local north-up-east at cartographic (0.0, 0.0) to Earth's fixed frame. + * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var transform = Cesium.Transforms.northUpEastToFixedFrame(center); + */ + Transforms.northUpEastToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','up'); - var URL = window.URL || window.webkitURL; - url = URL.createObjectURL(blob); - } + /** + * Computes a 4x4 transformation matrix from a reference frame with an north-west-up axes + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * The local axes are defined as: + * <ul> + * <li>The <code>x</code> axis points in the local north direction.</li> + * <li>The <code>y</code> axis points in the local west direction.</li> + * <li>The <code>z</code> axis points in the direction of the ellipsoid surface normal which passes through the position.</li> + * </ul> + * + * @function + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + * + * @example + * // Get the transform from local north-West-Up at cartographic (0.0, 0.0) to Earth's fixed frame. + * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var transform = Cesium.Transforms.northWestUpToFixedFrame(center); + */ + Transforms.northWestUpToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','west'); - return url; - } + var scratchHPRQuaternion = new Quaternion(); + var scratchScale = new Cartesian3(1.0, 1.0, 1.0); + var scratchHPRMatrix4 = new Matrix4(); - var bootstrapperUrlResult; - function getBootstrapperUrl() { - if (!defined(bootstrapperUrlResult)) { - bootstrapperUrlResult = getWorkerUrl('Workers/cesiumWorkerBootstrapper.js'); - } - return bootstrapperUrlResult; - } + /** + * Computes a 4x4 transformation matrix from a reference frame with axes computed from the heading-pitch-roll angles + * centered at the provided origin to the provided ellipsoid's fixed reference frame. Heading is the rotation from the local north + * direction where a positive angle is increasing eastward. Pitch is the rotation from the local east-north plane. Positive pitch angles + * are above the plane. Negative pitch angles are below the plane. Roll is the first rotation applied about the local east axis. + * + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Transforms~LocalFrameToFixedFrame} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation + * matrix from a reference frame to the provided ellipsoid's fixed reference frame + * @param {Matrix4} [result] The object onto which to store the result. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided. + * + * @example + * // Get the transform from local heading-pitch-roll at cartographic (0.0, 0.0) to Earth's fixed frame. + * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var heading = -Cesium.Math.PI_OVER_TWO; + * var pitch = Cesium.Math.PI_OVER_FOUR; + * var roll = 0.0; + * var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + * var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, hpr); + */ + Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { + Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); + + fixedFrameTransform = defaultValue(fixedFrameTransform, Transforms.eastNorthUpToFixedFrame); + var hprQuaternion = Quaternion.fromHeadingPitchRoll(headingPitchRoll, scratchHPRQuaternion); + var hprMatrix = Matrix4.fromTranslationQuaternionRotationScale(Cartesian3.ZERO, hprQuaternion, scratchScale, scratchHPRMatrix4); + result = fixedFrameTransform(origin, ellipsoid, result); + return Matrix4.multiply(result, hprMatrix, result); + }; - function createWorker(processor) { - var worker = new Worker(getBootstrapperUrl()); - worker.postMessage = defaultValue(worker.webkitPostMessage, worker.postMessage); + var scratchENUMatrix4 = new Matrix4(); + var scratchHPRMatrix3 = new Matrix3(); - var bootstrapMessage = { - loaderConfig : {}, - workerModule : TaskProcessor._workerModulePrefix + processor._workerName - }; + /** + * Computes a quaternion from a reference frame with axes computed from the heading-pitch-roll angles + * centered at the provided origin. Heading is the rotation from the local north + * direction where a positive angle is increasing eastward. Pitch is the rotation from the local east-north plane. Positive pitch angles + * are above the plane. Negative pitch angles are below the plane. Roll is the first rotation applied about the local east axis. + * + * @param {Cartesian3} origin The center point of the local reference frame. + * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {Transforms~LocalFrameToFixedFrame} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation + * matrix from a reference frame to the provided ellipsoid's fixed reference frame + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new Quaternion instance if none was provided. + * + * @example + * // Get the quaternion from local heading-pitch-roll at cartographic (0.0, 0.0) to Earth's fixed frame. + * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var heading = -Cesium.Math.PI_OVER_TWO; + * var pitch = Cesium.Math.PI_OVER_FOUR; + * var roll = 0.0; + * var hpr = new HeadingPitchRoll(heading, pitch, roll); + * var quaternion = Cesium.Transforms.headingPitchRollQuaternion(center, hpr); + */ + Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { + Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); + + var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, scratchENUMatrix4); + var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3); + return Quaternion.fromRotationMatrix(rotation, result); + }; - if (defined(TaskProcessor._loaderConfig)) { - bootstrapMessage.loaderConfig = TaskProcessor._loaderConfig; - } else if (defined(define.amd) && !define.amd.toUrlUndefined && defined(require.toUrl)) { - bootstrapMessage.loaderConfig.baseUrl = - getAbsoluteUri('..', buildModuleUrl('Workers/cesiumWorkerBootstrapper.js')); + var gmstConstant0 = 6 * 3600 + 41 * 60 + 50.54841; + var gmstConstant1 = 8640184.812866; + var gmstConstant2 = 0.093104; + var gmstConstant3 = -6.2E-6; + var rateCoef = 1.1772758384668e-19; + var wgs84WRPrecessing = 7.2921158553E-5; + var twoPiOverSecondsInDay = CesiumMath.TWO_PI / 86400.0; + var dateInUtc = new JulianDate(); + + /** + * Computes a rotation matrix to transform a point or vector from True Equator Mean Equinox (TEME) axes to the + * pseudo-fixed axes at a given time. This method treats the UT1 time standard as equivalent to UTC. + * + * @param {JulianDate} date The time at which to compute the rotation matrix. + * @param {Matrix3} [result] The object onto which to store the result. + * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if none was provided. + * + * @example + * //Set the view to in the inertial frame. + * scene.postUpdate.addEventListener(function(scene, time) { + * var now = Cesium.JulianDate.now(); + * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); + * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); + * var inverseTransform = Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()); + * Cesium.Matrix4.multiplyByPoint(inverseTransform, offset, offset); + * camera.lookAtTransform(transform, offset); + * }); + */ + Transforms.computeTemeToPseudoFixedMatrix = function (date, result) { + if (!defined(date)) { + throw new DeveloperError('date is required.'); + } + + // GMST is actually computed using UT1. We're using UTC as an approximation of UT1. + // We do not want to use the function like convertTaiToUtc in JulianDate because + // we explicitly do not want to fail when inside the leap second. + + dateInUtc = JulianDate.addSeconds(date, -JulianDate.computeTaiMinusUtc(date), dateInUtc); + var utcDayNumber = dateInUtc.dayNumber; + var utcSecondsIntoDay = dateInUtc.secondsOfDay; + + var t; + var diffDays = utcDayNumber - 2451545; + if (utcSecondsIntoDay >= 43200.0) { + t = (diffDays + 0.5) / TimeConstants.DAYS_PER_JULIAN_CENTURY; } else { - bootstrapMessage.loaderConfig.paths = { - 'Workers' : buildModuleUrl('Workers') - }; + t = (diffDays - 0.5) / TimeConstants.DAYS_PER_JULIAN_CENTURY; } - worker.postMessage(bootstrapMessage); + var gmst0 = gmstConstant0 + t * (gmstConstant1 + t * (gmstConstant2 + t * gmstConstant3)); + var angle = (gmst0 * twoPiOverSecondsInDay) % CesiumMath.TWO_PI; + var ratio = wgs84WRPrecessing + rateCoef * (utcDayNumber - 2451545.5); + var secondsSinceMidnight = (utcSecondsIntoDay + TimeConstants.SECONDS_PER_DAY * 0.5) % TimeConstants.SECONDS_PER_DAY; + var gha = angle + (ratio * secondsSinceMidnight); + var cosGha = Math.cos(gha); + var sinGha = Math.sin(gha); - worker.onmessage = function(event) { - completeTask(processor, event.data); - }; + if (!defined(result)) { + return new Matrix3(cosGha, sinGha, 0.0, + -sinGha, cosGha, 0.0, + 0.0, 0.0, 1.0); + } + result[0] = cosGha; + result[1] = -sinGha; + result[2] = 0.0; + result[3] = sinGha; + result[4] = cosGha; + result[5] = 0.0; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 1.0; + return result; + }; - return worker; - } + /** + * The source of IAU 2006 XYS data, used for computing the transformation between the + * Fixed and ICRF axes. + * @type {Iau2006XysData} + * + * @see Transforms.computeIcrfToFixedMatrix + * @see Transforms.computeFixedToIcrfMatrix + * + * @private + */ + Transforms.iau2006XysData = new Iau2006XysData(); /** - * A wrapper around a web worker that allows scheduling tasks for a given worker, - * returning results asynchronously via a promise. + * The source of Earth Orientation Parameters (EOP) data, used for computing the transformation + * between the Fixed and ICRF axes. By default, zero values are used for all EOP values, + * yielding a reasonable but not completely accurate representation of the ICRF axes. + * @type {EarthOrientationParameters} * - * The Worker is not constructed until a task is scheduled. + * @see Transforms.computeIcrfToFixedMatrix + * @see Transforms.computeFixedToIcrfMatrix * - * @alias TaskProcessor - * @constructor + * @private + */ + Transforms.earthOrientationParameters = EarthOrientationParameters.NONE; + + var ttMinusTai = 32.184; + var j2000ttDays = 2451545.0; + + /** + * Preloads the data necessary to transform between the ICRF and Fixed axes, in either + * direction, over a given interval. This function returns a promise that, when resolved, + * indicates that the preload has completed. * - * @param {String} workerName The name of the worker. This is expected to be a script - * in the Workers folder. - * @param {Number} [maximumActiveTasks=5] The maximum number of active tasks. Once exceeded, - * scheduleTask will not queue any more tasks, allowing - * work to be rescheduled in future frames. + * @param {TimeInterval} timeInterval The interval to preload. + * @returns {Promise.<undefined>} A promise that, when resolved, indicates that the preload has completed + * and evaluation of the transformation between the fixed and ICRF axes will + * no longer return undefined for a time inside the interval. + * + * + * @example + * var interval = new Cesium.TimeInterval(...); + * when(Cesium.Transforms.preloadIcrfFixed(interval), function() { + * // the data is now loaded + * }); + * + * @see Transforms.computeIcrfToFixedMatrix + * @see Transforms.computeFixedToIcrfMatrix + * @see when */ - function TaskProcessor(workerName, maximumActiveTasks) { - this._workerName = workerName; - this._maximumActiveTasks = defaultValue(maximumActiveTasks, 5); - this._activeTasks = 0; - this._deferreds = {}; - this._nextID = 0; - } + Transforms.preloadIcrfFixed = function(timeInterval) { + var startDayTT = timeInterval.start.dayNumber; + var startSecondTT = timeInterval.start.secondsOfDay + ttMinusTai; + var stopDayTT = timeInterval.stop.dayNumber; + var stopSecondTT = timeInterval.stop.secondsOfDay + ttMinusTai; - var emptyTransferableObjectArray = []; + var xysPromise = Transforms.iau2006XysData.preload(startDayTT, startSecondTT, stopDayTT, stopSecondTT); + var eopPromise = Transforms.earthOrientationParameters.getPromiseToLoad(); + + return when.all([xysPromise, eopPromise]); + }; /** - * Schedule a task to be processed by the web worker asynchronously. If there are currently more - * tasks active than the maximum set by the constructor, will immediately return undefined. - * Otherwise, returns a promise that will resolve to the result posted back by the worker when - * finished. + * Computes a rotation matrix to transform a point or vector from the International Celestial + * Reference Frame (GCRF/ICRF) inertial frame axes to the Earth-Fixed frame axes (ITRF) + * at a given time. This function may return undefined if the data necessary to + * do the transformation is not yet loaded. + * + * @param {JulianDate} date The time at which to compute the rotation matrix. + * @param {Matrix3} [result] The object onto which to store the result. If this parameter is + * not specified, a new instance is created and returned. + * @returns {Matrix3} The rotation matrix, or undefined if the data necessary to do the + * transformation is not yet loaded. * - * @param {*} parameters Any input data that will be posted to the worker. - * @param {Object[]} [transferableObjects] An array of objects contained in parameters that should be - * transferred to the worker instead of copied. - * @returns {Promise.<Object>|undefined} Either a promise that will resolve to the result when available, or undefined - * if there are too many active tasks, * * @example - * var taskProcessor = new Cesium.TaskProcessor('myWorkerName'); - * var promise = taskProcessor.scheduleTask({ - * someParameter : true, - * another : 'hello' + * scene.postUpdate.addEventListener(function(scene, time) { + * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); + * if (Cesium.defined(icrfToFixed)) { + * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); + * var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed) + * var inverseTransform = Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()); + * Cesium.Matrix4.multiplyByPoint(inverseTransform, offset, offset); + * camera.lookAtTransform(transform, offset); + * } * }); - * if (!Cesium.defined(promise)) { - * // too many active tasks - try again later - * } else { - * Cesium.when(promise, function(result) { - * // use the result of the task - * }); + * + * @see Transforms.preloadIcrfFixed + */ + Transforms.computeIcrfToFixedMatrix = function(date, result) { + if (!defined(date)) { + throw new DeveloperError('date is required.'); + } + if (!defined(result)) { + result = new Matrix3(); + } + + var fixedToIcrfMtx = Transforms.computeFixedToIcrfMatrix(date, result); + if (!defined(fixedToIcrfMtx)) { + return undefined; + } + + return Matrix3.transpose(fixedToIcrfMtx, result); + }; + + var xysScratch = new Iau2006XysSample(0.0, 0.0, 0.0); + var eopScratch = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + var rotation1Scratch = new Matrix3(); + var rotation2Scratch = new Matrix3(); + + /** + * Computes a rotation matrix to transform a point or vector from the Earth-Fixed frame axes (ITRF) + * to the International Celestial Reference Frame (GCRF/ICRF) inertial frame axes + * at a given time. This function may return undefined if the data necessary to + * do the transformation is not yet loaded. + * + * @param {JulianDate} date The time at which to compute the rotation matrix. + * @param {Matrix3} [result] The object onto which to store the result. If this parameter is + * not specified, a new instance is created and returned. + * @returns {Matrix3} The rotation matrix, or undefined if the data necessary to do the + * transformation is not yet loaded. + * + * + * @example + * // Transform a point from the ICRF axes to the Fixed axes. + * var now = Cesium.JulianDate.now(); + * var pointInFixed = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var fixedToIcrf = Cesium.Transforms.computeIcrfToFixedMatrix(now); + * var pointInInertial = new Cesium.Cartesian3(); + * if (Cesium.defined(fixedToIcrf)) { + * pointInInertial = Cesium.Matrix3.multiplyByVector(fixedToIcrf, pointInFixed, pointInInertial); * } + * + * @see Transforms.preloadIcrfFixed */ - TaskProcessor.prototype.scheduleTask = function(parameters, transferableObjects) { - if (!defined(this._worker)) { - this._worker = createWorker(this); + Transforms.computeFixedToIcrfMatrix = function(date, result) { + if (!defined(date)) { + throw new DeveloperError('date is required.'); + } + + if (!defined(result)) { + result = new Matrix3(); } - if (this._activeTasks >= this._maximumActiveTasks) { + // Compute pole wander + var eop = Transforms.earthOrientationParameters.compute(date, eopScratch); + if (!defined(eop)) { return undefined; } - ++this._activeTasks; + // There is no external conversion to Terrestrial Time (TT). + // So use International Atomic Time (TAI) and convert using offsets. + // Here we are assuming that dayTT and secondTT are positive + var dayTT = date.dayNumber; + // It's possible here that secondTT could roll over 86400 + // This does not seem to affect the precision (unit tests check for this) + var secondTT = date.secondsOfDay + ttMinusTai; - var processor = this; - return when(canTransferArrayBuffer(), function(canTransferArrayBuffer) { - if (!defined(transferableObjects)) { - transferableObjects = emptyTransferableObjectArray; - } else if (!canTransferArrayBuffer) { - transferableObjects.length = 0; - } + var xys = Transforms.iau2006XysData.computeXysRadians(dayTT, secondTT, xysScratch); + if (!defined(xys)) { + return undefined; + } - var id = processor._nextID++; - var deferred = when.defer(); - processor._deferreds[id] = deferred; + var x = xys.x + eop.xPoleOffset; + var y = xys.y + eop.yPoleOffset; - processor._worker.postMessage({ - id : id, - parameters : parameters, - canTransferArrayBuffer : canTransferArrayBuffer - }, transferableObjects); + // Compute XYS rotation + var a = 1.0 / (1.0 + Math.sqrt(1.0 - x * x - y * y)); - return deferred.promise; - }); + var rotation1 = rotation1Scratch; + rotation1[0] = 1.0 - a * x * x; + rotation1[3] = -a * x * y; + rotation1[6] = x; + rotation1[1] = -a * x * y; + rotation1[4] = 1 - a * y * y; + rotation1[7] = y; + rotation1[2] = -x; + rotation1[5] = -y; + rotation1[8] = 1 - a * (x * x + y * y); + + var rotation2 = Matrix3.fromRotationZ(-xys.s, rotation2Scratch); + var matrixQ = Matrix3.multiply(rotation1, rotation2, rotation1Scratch); + + // Similar to TT conversions above + // It's possible here that secondTT could roll over 86400 + // This does not seem to affect the precision (unit tests check for this) + var dateUt1day = date.dayNumber; + var dateUt1sec = date.secondsOfDay - JulianDate.computeTaiMinusUtc(date) + eop.ut1MinusUtc; + + // Compute Earth rotation angle + // The IERS standard for era is + // era = 0.7790572732640 + 1.00273781191135448 * Tu + // where + // Tu = JulianDateInUt1 - 2451545.0 + // However, you get much more precision if you make the following simplification + // era = a + (1 + b) * (JulianDayNumber + FractionOfDay - 2451545) + // era = a + (JulianDayNumber - 2451545) + FractionOfDay + b (JulianDayNumber - 2451545 + FractionOfDay) + // era = a + FractionOfDay + b (JulianDayNumber - 2451545 + FractionOfDay) + // since (JulianDayNumber - 2451545) represents an integer number of revolutions which will be discarded anyway. + var daysSinceJ2000 = dateUt1day - 2451545; + var fractionOfDay = dateUt1sec / TimeConstants.SECONDS_PER_DAY; + var era = 0.7790572732640 + fractionOfDay + 0.00273781191135448 * (daysSinceJ2000 + fractionOfDay); + era = (era % 1.0) * CesiumMath.TWO_PI; + + var earthRotation = Matrix3.fromRotationZ(era, rotation2Scratch); + + // pseudoFixed to ICRF + var pfToIcrf = Matrix3.multiply(matrixQ, earthRotation, rotation1Scratch); + + // Compute pole wander matrix + var cosxp = Math.cos(eop.xPoleWander); + var cosyp = Math.cos(eop.yPoleWander); + var sinxp = Math.sin(eop.xPoleWander); + var sinyp = Math.sin(eop.yPoleWander); + + var ttt = (dayTT - j2000ttDays) + secondTT / TimeConstants.SECONDS_PER_DAY; + ttt /= 36525.0; + + // approximate sp value in rad + var sp = -47.0e-6 * ttt * CesiumMath.RADIANS_PER_DEGREE / 3600.0; + var cossp = Math.cos(sp); + var sinsp = Math.sin(sp); + + var fToPfMtx = rotation2Scratch; + fToPfMtx[0] = cosxp * cossp; + fToPfMtx[1] = cosxp * sinsp; + fToPfMtx[2] = sinxp; + fToPfMtx[3] = -cosyp * sinsp + sinyp * sinxp * cossp; + fToPfMtx[4] = cosyp * cossp + sinyp * sinxp * sinsp; + fToPfMtx[5] = -sinyp * cosxp; + fToPfMtx[6] = -sinyp * sinsp - cosyp * sinxp * cossp; + fToPfMtx[7] = sinyp * cossp - cosyp * sinxp * sinsp; + fToPfMtx[8] = cosyp * cosxp; + + return Matrix3.multiply(pfToIcrf, fToPfMtx, result); }; + var pointToWindowCoordinatesTemp = new Cartesian4(); + /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * Transform a point from model coordinates to window coordinates. * - * @see TaskProcessor#destroy + * @param {Matrix4} modelViewProjectionMatrix The 4x4 model-view-projection matrix. + * @param {Matrix4} viewportTransformation The 4x4 viewport transformation. + * @param {Cartesian3} point The point to transform. + * @param {Cartesian2} [result] The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. */ - TaskProcessor.prototype.isDestroyed = function() { - return false; + Transforms.pointToWindowCoordinates = function (modelViewProjectionMatrix, viewportTransformation, point, result) { + result = Transforms.pointToGLWindowCoordinates(modelViewProjectionMatrix, viewportTransformation, point, result); + result.y = 2.0 * viewportTransformation[5] - result.y; + return result; }; /** - * Destroys this object. This will immediately terminate the Worker. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {undefined} + * @private */ - TaskProcessor.prototype.destroy = function() { - if (defined(this._worker)) { - this._worker.terminate(); + Transforms.pointToGLWindowCoordinates = function(modelViewProjectionMatrix, viewportTransformation, point, result) { + if (!defined(modelViewProjectionMatrix)) { + throw new DeveloperError('modelViewProjectionMatrix is required.'); } - return destroyObject(this); - }; - // exposed for testing purposes - TaskProcessor._defaultWorkerModulePrefix = 'Workers/'; - TaskProcessor._workerModulePrefix = TaskProcessor._defaultWorkerModulePrefix; - TaskProcessor._loaderConfig = undefined; - TaskProcessor._canTransferArrayBuffer = undefined; + if (!defined(viewportTransformation)) { + throw new DeveloperError('viewportTransformation is required.'); + } - return TaskProcessor; -}); + if (!defined(point)) { + throw new DeveloperError('point is required.'); + } + + if (!defined(result)) { + result = new Cartesian2(); + } -define('Core/TerrainMesh',[ - './defaultValue' - ], function( - defaultValue) { - 'use strict'; + var tmp = pointToWindowCoordinatesTemp; + + Matrix4.multiplyByVector(modelViewProjectionMatrix, Cartesian4.fromElements(point.x, point.y, point.z, 1, tmp), tmp); + Cartesian4.multiplyByScalar(tmp, 1.0 / tmp.w, tmp); + Matrix4.multiplyByVector(viewportTransformation, tmp, tmp); + return Cartesian2.fromCartesian4(tmp, result); + }; + + var normalScratch = new Cartesian3(); + var rightScratch = new Cartesian3(); + var upScratch = new Cartesian3(); /** - * A mesh plus related metadata for a single tile of terrain. Instances of this type are - * usually created from raw {@link TerrainData}. - * - * @alias TerrainMesh - * @constructor - * - * @param {Cartesian3} center The center of the tile. Vertex positions are specified relative to this center. - * @param {Float32Array} vertices The vertex data, including positions, texture coordinates, and heights. - * The vertex data is in the order [X, Y, Z, H, U, V], where X, Y, and Z represent - * the Cartesian position of the vertex, H is the height above the ellipsoid, and - * U and V are the texture coordinates. - * @param {Uint16Array|Uint32Array} indices The indices describing how the vertices are connected to form triangles. - * @param {Number} minimumHeight The lowest height in the tile, in meters above the ellipsoid. - * @param {Number} maximumHeight The highest height in the tile, in meters above the ellipsoid. - * @param {BoundingSphere} boundingSphere3D A bounding sphere that completely contains the tile. - * @param {Cartesian3} occludeePointInScaledSpace The occludee point of the tile, represented in ellipsoid- - * scaled space, and used for horizon culling. If this point is below the horizon, - * the tile is considered to be entirely below the horizon. - * @param {Number} [vertexStride=6] The number of components in each vertex. - * @param {OrientedBoundingBox} [orientedBoundingBox] A bounding box that completely contains the tile. - * @param {TerrainEncoding} encoding Information used to decode the mesh. - * @param {Number} exaggeration The amount that this mesh was exaggerated. - * - * @private - */ - function TerrainMesh(center, vertices, indices, minimumHeight, maximumHeight, boundingSphere3D, occludeePointInScaledSpace, vertexStride, orientedBoundingBox, encoding, exaggeration) { - /** - * The center of the tile. Vertex positions are specified relative to this center. - * @type {Cartesian3} - */ - this.center = center; + * @private + */ + Transforms.rotationMatrixFromPositionVelocity = function(position, velocity, ellipsoid, result) { + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } - /** - * The vertex data, including positions, texture coordinates, and heights. - * The vertex data is in the order [X, Y, Z, H, U, V], where X, Y, and Z represent - * the Cartesian position of the vertex, H is the height above the ellipsoid, and - * U and V are the texture coordinates. The vertex data may have additional attributes after those - * mentioned above when the {@link TerrainMesh#stride} is greater than 6. - * @type {Float32Array} - */ - this.vertices = vertices; + if (!defined(velocity)) { + throw new DeveloperError('velocity is required.'); + } + + var normal = defaultValue(ellipsoid, Ellipsoid.WGS84).geodeticSurfaceNormal(position, normalScratch); + var right = Cartesian3.cross(velocity, normal, rightScratch); + if (Cartesian3.equalsEpsilon(right, Cartesian3.ZERO, CesiumMath.EPSILON6)) { + right = Cartesian3.clone(Cartesian3.UNIT_X, right); + } - /** - * The number of components in each vertex. Typically this is 6 for the 6 components - * [X, Y, Z, H, U, V], but if each vertex has additional data (such as a vertex normal), this value - * may be higher. - * @type {Number} - */ - this.stride = defaultValue(vertexStride, 6); + var up = Cartesian3.cross(right, velocity, upScratch); + Cartesian3.cross(velocity, up, right); + Cartesian3.negate(right, right); - /** - * The indices describing how the vertices are connected to form triangles. - * @type {Uint16Array|Uint32Array} - */ - this.indices = indices; + if (!defined(result)) { + result = new Matrix3(); + } - /** - * The lowest height in the tile, in meters above the ellipsoid. - * @type {Number} - */ - this.minimumHeight = minimumHeight; + result[0] = velocity.x; + result[1] = velocity.y; + result[2] = velocity.z; + result[3] = right.x; + result[4] = right.y; + result[5] = right.z; + result[6] = up.x; + result[7] = up.y; + result[8] = up.z; - /** - * The highest height in the tile, in meters above the ellipsoid. - * @type {Number} - */ - this.maximumHeight = maximumHeight; + return result; + }; - /** - * A bounding sphere that completely contains the tile. - * @type {BoundingSphere} - */ - this.boundingSphere3D = boundingSphere3D; + var swizzleMatrix = new Matrix4( + 0.0, 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + ); - /** - * The occludee point of the tile, represented in ellipsoid- - * scaled space, and used for horizon culling. If this point is below the horizon, - * the tile is considered to be entirely below the horizon. - * @type {Cartesian3} - */ - this.occludeePointInScaledSpace = occludeePointInScaledSpace; + var scratchCartographic = new Cartographic(); + var scratchCartesian3Projection = new Cartesian3(); + var scratchCenter = new Cartesian3(); + var scratchRotation = new Matrix3(); + var scratchFromENU = new Matrix4(); + var scratchToENU = new Matrix4(); - /** - * A bounding box that completely contains the tile. - * @type {OrientedBoundingBox} - */ - this.orientedBoundingBox = orientedBoundingBox; + /** + * @private + */ + Transforms.basisTo2D = function(projection, matrix, result) { + if (!defined(projection)) { + throw new DeveloperError('projection is required.'); + } + if (!defined(matrix)) { + throw new DeveloperError('matrix is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var rtcCenter = Matrix4.getTranslation(matrix, scratchCenter); + var ellipsoid = projection.ellipsoid; - /** - * Information for decoding the mesh vertices. - * @type {TerrainEncoding} - */ - this.encoding = encoding; + // Get the 2D Center + var cartographic = ellipsoid.cartesianToCartographic(rtcCenter, scratchCartographic); + var projectedPosition = projection.project(cartographic, scratchCartesian3Projection); + Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, projectedPosition); - /** - * The amount that this mesh was exaggerated. - * @type {Number} - */ - this.exaggeration = exaggeration; - } + // Assuming the instance are positioned in WGS84, invert the WGS84 transform to get the local transform and then convert to 2D + var fromENU = Transforms.eastNorthUpToFixedFrame(rtcCenter, ellipsoid, scratchFromENU); + var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU); + var rotation = Matrix4.getRotation(matrix, scratchRotation); + var local = Matrix4.multiplyByMatrix3(toENU, rotation, result); + Matrix4.multiply(swizzleMatrix, local, result); // Swap x, y, z for 2D + Matrix4.setTranslation(result, projectedPosition, result); // Use the projected center - return TerrainMesh; + return result; + }; + + /** + * @private + */ + Transforms.wgs84To2DModelMatrix = function(projection, center, result) { + if (!defined(projection)) { + throw new DeveloperError('projection is required.'); + } + if (!defined(center)) { + throw new DeveloperError('center is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var ellipsoid = projection.ellipsoid; + + var fromENU = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, scratchFromENU); + var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU); + + var cartographic = ellipsoid.cartesianToCartographic(center, scratchCartographic); + var projectedPosition = projection.project(cartographic, scratchCartesian3Projection); + Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, projectedPosition); + + var translation = Matrix4.fromTranslation(projectedPosition, scratchFromENU); + Matrix4.multiply(swizzleMatrix, toENU, result); + Matrix4.multiply(translation, result, result); + + return result; + }; + + return Transforms; }); -define('Core/TerrainProvider',[ +define('Core/EllipsoidTangentPlane',[ + './AxisAlignedBoundingBox', + './Cartesian2', + './Cartesian3', + './Cartesian4', + './defaultValue', './defined', './defineProperties', './DeveloperError', - './Math' + './Ellipsoid', + './IntersectionTests', + './Matrix4', + './Plane', + './Ray', + './Transforms' ], function( + AxisAlignedBoundingBox, + Cartesian2, + Cartesian3, + Cartesian4, + defaultValue, defined, defineProperties, DeveloperError, - CesiumMath) { + Ellipsoid, + IntersectionTests, + Matrix4, + Plane, + Ray, + Transforms) { 'use strict'; + var scratchCart4 = new Cartesian4(); /** - * Provides terrain or other geometry for the surface of an ellipsoid. The surface geometry is - * organized into a pyramid of tiles according to a {@link TilingScheme}. This type describes an - * interface and is not intended to be instantiated directly. + * A plane tangent to the provided ellipsoid at the provided origin. + * If origin is not on the surface of the ellipsoid, it's surface projection will be used. + * If origin is at the center of the ellipsoid, an exception will be thrown. + * @alias EllipsoidTangentPlane + * @constructor * - * @alias TerrainProvider - * @constructor + * @param {Cartesian3} origin The point on the surface of the ellipsoid where the tangent plane touches. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use. * - * @see EllipsoidTerrainProvider - * @see CesiumTerrainProvider - * @see VRTheWorldTerrainProvider - * @see GoogleEarthEnterpriseTerrainProvider + * @exception {DeveloperError} origin must not be at the center of the ellipsoid. */ - function TerrainProvider() { - DeveloperError.throwInstantiationError(); - } + function EllipsoidTangentPlane(origin, ellipsoid) { + if (!defined(origin)) { + throw new DeveloperError('origin is required.'); + } + + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + origin = ellipsoid.scaleToGeodeticSurface(origin); - defineProperties(TerrainProvider.prototype, { - /** - * Gets an event that is raised when the terrain provider encounters an asynchronous error.. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof TerrainProvider.prototype - * @type {Event} - */ - errorEvent : { - get : DeveloperError.throwInstantiationError - }, + if (!defined(origin)) { + throw new DeveloperError('origin must not be at the center of the ellipsoid.'); + } + + var eastNorthUp = Transforms.eastNorthUpToFixedFrame(origin, ellipsoid); + this._ellipsoid = ellipsoid; + this._origin = origin; + this._xAxis = Cartesian3.fromCartesian4(Matrix4.getColumn(eastNorthUp, 0, scratchCart4)); + this._yAxis = Cartesian3.fromCartesian4(Matrix4.getColumn(eastNorthUp, 1, scratchCart4)); - /** - * Gets the credit to display when this terrain provider is active. Typically this is used to credit - * the source of the terrain. This function should - * not be called before {@link TerrainProvider#ready} returns true. - * @memberof TerrainProvider.prototype - * @type {Credit} - */ - credit : { - get : DeveloperError.throwInstantiationError - }, + var normal = Cartesian3.fromCartesian4(Matrix4.getColumn(eastNorthUp, 2, scratchCart4)); + this._plane = Plane.fromPointNormal(origin, normal); + } + defineProperties(EllipsoidTangentPlane.prototype, { /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link TerrainProvider#ready} returns true. - * @memberof TerrainProvider.prototype - * @type {TilingScheme} + * Gets the ellipsoid. + * @memberof EllipsoidTangentPlane.prototype + * @type {Ellipsoid} */ - tilingScheme : { - get : DeveloperError.throwInstantiationError + ellipsoid : { + get : function() { + return this._ellipsoid; + } }, /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof TerrainProvider.prototype - * @type {Boolean} + * Gets the origin. + * @memberof EllipsoidTangentPlane.prototype + * @type {Cartesian3} */ - ready : { - get : DeveloperError.throwInstantiationError + origin : { + get : function() { + return this._origin; + } }, /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof TerrainProvider.prototype - * @type {Promise.<Boolean>} + * Gets the plane which is tangent to the ellipsoid. + * @memberof EllipsoidTangentPlane.prototype * @readonly + * @type {Plane} */ - readyPromise : { - get : DeveloperError.throwInstantiationError + plane : { + get : function() { + return this._plane; + } }, /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. This function should not be - * called before {@link TerrainProvider#ready} returns true. - * @memberof TerrainProvider.prototype - * @type {Boolean} + * Gets the local X-axis (east) of the tangent plane. + * @memberof EllipsoidTangentPlane.prototype + * @readonly + * @type {Cartesian3} */ - hasWaterMask : { - get : DeveloperError.throwInstantiationError + xAxis : { + get : function() { + return this._xAxis; + } }, /** - * Gets a value indicating whether or not the requested tiles include vertex normals. - * This function should not be called before {@link TerrainProvider#ready} returns true. - * @memberof TerrainProvider.prototype - * @type {Boolean} + * Gets the local Y-axis (north) of the tangent plane. + * @memberof EllipsoidTangentPlane.prototype + * @readonly + * @type {Cartesian3} */ - hasVertexNormals : { - get : DeveloperError.throwInstantiationError + yAxis : { + get : function() { + return this._yAxis; + } }, /** - * Gets an object that can be used to determine availability of terrain from this provider, such as - * at points and in rectangles. This function should not be called before - * {@link TerrainProvider#ready} returns true. This property may be undefined if availability - * information is not available. - * @memberof TerrainProvider.prototype - * @type {TileAvailability} + * Gets the local Z-axis (up) of the tangent plane. + * @member EllipsoidTangentPlane.prototype + * @readonly + * @type {Cartesian3} */ - availability : { - get : DeveloperError.throwInstantiationError + zAxis : { + get : function() { + return this._plane.normal; + } } }); - var regularGridIndexArrays = []; - + var tmp = new AxisAlignedBoundingBox(); /** - * Gets a list of indices for a triangle mesh representing a regular grid. Calling - * this function multiple times with the same grid width and height returns the - * same list of indices. The total number of vertices must be less than or equal - * to 65536. + * Creates a new instance from the provided ellipsoid and the center + * point of the provided Cartesians. * - * @param {Number} width The number of vertices in the regular grid in the horizontal direction. - * @param {Number} height The number of vertices in the regular grid in the vertical direction. - * @returns {Uint16Array} The list of indices. + * @param {Ellipsoid} ellipsoid The ellipsoid to use. + * @param {Cartesian3} cartesians The list of positions surrounding the center point. */ - TerrainProvider.getRegularGridIndices = function(width, height) { - if (width * height >= CesiumMath.SIXTY_FOUR_KILOBYTES) { - throw new DeveloperError('The total number of vertices (width * height) must be less than 65536.'); + EllipsoidTangentPlane.fromPoints = function(cartesians, ellipsoid) { + if (!defined(cartesians)) { + throw new DeveloperError('cartesians is required.'); } - var byWidth = regularGridIndexArrays[width]; - if (!defined(byWidth)) { - regularGridIndexArrays[width] = byWidth = []; - } + var box = AxisAlignedBoundingBox.fromPoints(cartesians, tmp); + return new EllipsoidTangentPlane(box.center, ellipsoid); + }; - var indices = byWidth[height]; - if (!defined(indices)) { - indices = byWidth[height] = new Uint16Array((width - 1) * (height - 1) * 6); + var scratchProjectPointOntoPlaneRay = new Ray(); + var scratchProjectPointOntoPlaneCartesian3 = new Cartesian3(); - var index = 0; - var indicesIndex = 0; - for (var j = 0; j < height - 1; ++j) { - for (var i = 0; i < width - 1; ++i) { - var upperLeft = index; - var lowerLeft = upperLeft + width; - var lowerRight = lowerLeft + 1; - var upperRight = upperLeft + 1; + /** + * Computes the projection of the provided 3D position onto the 2D plane, radially outward from the {@link EllipsoidTangentPlane.ellipsoid} coordinate system origin. + * + * @param {Cartesian3} cartesian The point to project. + * @param {Cartesian2} [result] The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. Undefined if there is no intersection point + */ + EllipsoidTangentPlane.prototype.projectPointOntoPlane = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + + var ray = scratchProjectPointOntoPlaneRay; + ray.origin = cartesian; + Cartesian3.normalize(cartesian, ray.direction); - indices[indicesIndex++] = upperLeft; - indices[indicesIndex++] = lowerLeft; - indices[indicesIndex++] = upperRight; - indices[indicesIndex++] = upperRight; - indices[indicesIndex++] = lowerLeft; - indices[indicesIndex++] = lowerRight; + var intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); + if (!defined(intersectionPoint)) { + Cartesian3.negate(ray.direction, ray.direction); + intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); + } - ++index; - } - ++index; + if (defined(intersectionPoint)) { + var v = Cartesian3.subtract(intersectionPoint, this._origin, intersectionPoint); + var x = Cartesian3.dot(this._xAxis, v); + var y = Cartesian3.dot(this._yAxis, v); + + if (!defined(result)) { + return new Cartesian2(x, y); } + result.x = x; + result.y = y; + return result; } - - return indices; + return undefined; }; /** - * Specifies the quality of terrain created from heightmaps. A value of 1.0 will - * ensure that adjacent heightmap vertices are separated by no more than - * {@link Globe.maximumScreenSpaceError} screen pixels and will probably go very slowly. - * A value of 0.5 will cut the estimated level zero geometric error in half, allowing twice the - * screen pixels between adjacent heightmap vertices and thus rendering more quickly. - * @type {Number} + * Computes the projection of the provided 3D positions onto the 2D plane (where possible), radially outward from the global origin. + * The resulting array may be shorter than the input array - if a single projection is impossible it will not be included. + * + * @see EllipsoidTangentPlane.projectPointOntoPlane + * + * @param {Cartesian3[]} cartesians The array of points to project. + * @param {Cartesian2[]} [result] The array of Cartesian2 instances onto which to store results. + * @returns {Cartesian2[]} The modified result parameter or a new array of Cartesian2 instances if none was provided. */ - TerrainProvider.heightmapTerrainQuality = 0.25; + EllipsoidTangentPlane.prototype.projectPointsOntoPlane = function(cartesians, result) { + if (!defined(cartesians)) { + throw new DeveloperError('cartesians is required.'); + } + + if (!defined(result)) { + result = []; + } + + var count = 0; + var length = cartesians.length; + for ( var i = 0; i < length; i++) { + var p = this.projectPointOntoPlane(cartesians[i], result[count]); + if (defined(p)) { + result[count] = p; + count++; + } + } + result.length = count; + return result; + }; /** - * Determines an appropriate geometric error estimate when the geometry comes from a heightmap. + * Computes the projection of the provided 3D position onto the 2D plane, along the plane normal. * - * @param {Ellipsoid} ellipsoid The ellipsoid to which the terrain is attached. - * @param {Number} tileImageWidth The width, in pixels, of the heightmap associated with a single tile. - * @param {Number} numberOfTilesAtLevelZero The number of tiles in the horizontal direction at tile level zero. - * @returns {Number} An estimated geometric error. + * @param {Cartesian3} cartesian The point to project. + * @param {Cartesian2} [result] The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. */ - TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap = function(ellipsoid, tileImageWidth, numberOfTilesAtLevelZero) { - return ellipsoid.maximumRadius * 2 * Math.PI * TerrainProvider.heightmapTerrainQuality / (tileImageWidth * numberOfTilesAtLevelZero); + EllipsoidTangentPlane.prototype.projectPointToNearestOnPlane = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + + if (!defined(result)) { + result = new Cartesian2(); + } + + var ray = scratchProjectPointOntoPlaneRay; + ray.origin = cartesian; + Cartesian3.clone(this._plane.normal, ray.direction); + + var intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); + if (!defined(intersectionPoint)) { + Cartesian3.negate(ray.direction, ray.direction); + intersectionPoint = IntersectionTests.rayPlane(ray, this._plane, scratchProjectPointOntoPlaneCartesian3); + } + + var v = Cartesian3.subtract(intersectionPoint, this._origin, intersectionPoint); + var x = Cartesian3.dot(this._xAxis, v); + var y = Cartesian3.dot(this._yAxis, v); + + result.x = x; + result.y = y; + return result; }; /** - * Requests the geometry for a given tile. This function should not be called before - * {@link TerrainProvider#ready} returns true. The result must include terrain data and - * may optionally include a water mask and an indication of which child tiles are available. - * @function + * Computes the projection of the provided 3D positions onto the 2D plane, along the plane normal. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @param {Request} [request] The request object. Intended for internal use only. + * @see EllipsoidTangentPlane.projectPointToNearestOnPlane * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method - * returns undefined instead of a promise, it is an indication that too many requests are already - * pending and the request will be retried later. + * @param {Cartesian3[]} cartesians The array of points to project. + * @param {Cartesian2[]} [result] The array of Cartesian2 instances onto which to store results. + * @returns {Cartesian2[]} The modified result parameter or a new array of Cartesian2 instances if none was provided. This will have the same length as <code>cartesians</code>. */ - TerrainProvider.prototype.requestTileGeometry = DeveloperError.throwInstantiationError; + EllipsoidTangentPlane.prototype.projectPointsToNearestOnPlane = function(cartesians, result) { + if (!defined(cartesians)) { + throw new DeveloperError('cartesians is required.'); + } + + if (!defined(result)) { + result = []; + } - /** - * Gets the maximum geometric error allowed in a tile at a given level. This function should not be - * called before {@link TerrainProvider#ready} returns true. - * @function - * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. - */ - TerrainProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; + var length = cartesians.length; + result.length = length; + for (var i = 0; i < length; i++) { + result[i] = this.projectPointToNearestOnPlane(cartesians[i], result[i]); + } + return result; + }; + var projectPointsOntoEllipsoidScratch = new Cartesian3(); /** - * Determines whether data for a tile is available to be loaded. - * @function + * Computes the projection of the provided 2D positions onto the 3D ellipsoid. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean} Undefined if not supported by the terrain provider, otherwise true or false. + * @param {Cartesian2[]} cartesians The array of points to project. + * @param {Cartesian3[]} [result] The array of Cartesian3 instances onto which to store results. + * @returns {Cartesian3[]} The modified result parameter or a new array of Cartesian3 instances if none was provided. */ - TerrainProvider.prototype.getTileDataAvailable = DeveloperError.throwInstantiationError; + EllipsoidTangentPlane.prototype.projectPointsOntoEllipsoid = function(cartesians, result) { + if (!defined(cartesians)) { + throw new DeveloperError('cartesians is required.'); + } + + var length = cartesians.length; + if (!defined(result)) { + result = new Array(length); + } else { + result.length = length; + } - return TerrainProvider; + var ellipsoid = this._ellipsoid; + var origin = this._origin; + var xAxis = this._xAxis; + var yAxis = this._yAxis; + var tmp = projectPointsOntoEllipsoidScratch; + + for ( var i = 0; i < length; ++i) { + var position = cartesians[i]; + Cartesian3.multiplyByScalar(xAxis, position.x, tmp); + if (!defined(result[i])) { + result[i] = new Cartesian3(); + } + var point = Cartesian3.add(origin, tmp, result[i]); + Cartesian3.multiplyByScalar(yAxis, position.y, tmp); + Cartesian3.add(point, tmp, point); + ellipsoid.scaleToGeocentricSurface(point, point); + } + + return result; + }; + + return EllipsoidTangentPlane; }); -define('Core/HeightmapTerrainData',[ - '../ThirdParty/when', +define('Core/OrientedBoundingBox',[ + './BoundingSphere', + './Cartesian2', + './Cartesian3', + './Cartographic', + './Check', './defaultValue', './defined', - './defineProperties', './DeveloperError', - './GeographicTilingScheme', - './HeightmapTessellator', + './Ellipsoid', + './EllipsoidTangentPlane', + './Intersect', + './Interval', './Math', - './Rectangle', - './TaskProcessor', - './TerrainEncoding', - './TerrainMesh', - './TerrainProvider' + './Matrix3', + './Plane', + './Rectangle' ], function( - when, + BoundingSphere, + Cartesian2, + Cartesian3, + Cartographic, + Check, defaultValue, defined, - defineProperties, DeveloperError, - GeographicTilingScheme, - HeightmapTessellator, + Ellipsoid, + EllipsoidTangentPlane, + Intersect, + Interval, CesiumMath, - Rectangle, - TaskProcessor, - TerrainEncoding, - TerrainMesh, - TerrainProvider) { + Matrix3, + Plane, + Rectangle) { 'use strict'; /** - * Terrain data for a single tile where the terrain data is represented as a heightmap. A heightmap - * is a rectangular array of heights in row-major order from south to north and west to east. - * - * @alias HeightmapTerrainData + * Creates an instance of an OrientedBoundingBox. + * An OrientedBoundingBox of some object is a closed and convex cuboid. It can provide a tighter bounding volume than {@link BoundingSphere} or {@link AxisAlignedBoundingBox} in many cases. + * @alias OrientedBoundingBox * @constructor * - * @param {Object} options Object with the following properties: - * @param {TypedArray} options.buffer The buffer containing height data. - * @param {Number} options.width The width (longitude direction) of the heightmap, in samples. - * @param {Number} options.height The height (latitude direction) of the heightmap, in samples. - * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. - * If a child's bit is set, geometry will be requested for that tile as well when it - * is needed. If the bit is cleared, the child tile is not requested and geometry is - * instead upsampled from the parent. The bit values are as follows: - * <table> - * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> - * <tr><td>0</td><td>1</td><td>Southwest</td></tr> - * <tr><td>1</td><td>2</td><td>Southeast</td></tr> - * <tr><td>2</td><td>4</td><td>Northwest</td></tr> - * <tr><td>3</td><td>8</td><td>Northeast</td></tr> - * </table> - * @param {Object} [options.structure] An object describing the structure of the height data. - * @param {Number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain - * the height above the heightOffset, in meters. The heightOffset is added to the resulting - * height after multiplying by the scale. - * @param {Number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final - * height in meters. The offset is added after the height sample is multiplied by the - * heightScale. - * @param {Number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height - * sample. This is usually 1, indicating that each element is a separate height sample. If - * it is greater than 1, that number of elements together form the height sample, which is - * computed according to the structure.elementMultiplier and structure.isBigEndian properties. - * @param {Number} [options.structure.stride=1] The number of elements to skip to get from the first element of - * one height to the first element of the next height. - * @param {Number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the - * stride property is greater than 1. For example, if the stride is 4 and the strideMultiplier - * is 256, the height is computed as follows: - * `height = buffer[index] + buffer[index + 1] * 256 + buffer[index + 2] * 256 * 256 + buffer[index + 3] * 256 * 256 * 256` - * This is assuming that the isBigEndian property is false. If it is true, the order of the - * elements is reversed. - * @param {Boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the - * stride property is greater than 1. If this property is false, the first element is the - * low-order element. If it is true, the first element is the high-order element. - * @param {Number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower - * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height - * buffer is a `Uint16Array`, this value should be 0 because a `Uint16Array` cannot store negative numbers. If this parameter is - * not specified, no minimum value is enforced. - * @param {Number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher - * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height - * buffer is a `Uint16Array`, this value should be `256 * 256 - 1` or 65535 because a `Uint16Array` cannot store numbers larger - * than 65535. If this parameter is not specified, no maximum value is enforced. - * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; - * otherwise, false. + * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. + * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. + * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 + * cube centered at the origin. * * * @example - * var buffer = ... - * var heightBuffer = new Uint16Array(buffer, 0, that._heightmapWidth * that._heightmapWidth); - * var childTileMask = new Uint8Array(buffer, heightBuffer.byteLength, 1)[0]; - * var waterMask = new Uint8Array(buffer, heightBuffer.byteLength + 1, buffer.byteLength - heightBuffer.byteLength - 1); - * var terrainData = new Cesium.HeightmapTerrainData({ - * buffer : heightBuffer, - * width : 65, - * height : 65, - * childTileMask : childTileMask, - * waterMask : waterMask - * }); + * // Create an OrientedBoundingBox using a transformation matrix, a position where the box will be translated, and a scale. + * var center = new Cesium.Cartesian3(1.0, 0.0, 0.0); + * var halfAxes = Cesium.Matrix3.fromScale(new Cesium.Cartesian3(1.0, 3.0, 2.0), new Cesium.Matrix3()); * - * @see TerrainData - * @see QuantizedMeshTerrainData + * var obb = new Cesium.OrientedBoundingBox(center, halfAxes); + * + * @see BoundingSphere + * @see BoundingRectangle */ - function HeightmapTerrainData(options) { - if (!defined(options) || !defined(options.buffer)) { - throw new DeveloperError('options.buffer is required.'); - } - if (!defined(options.width)) { - throw new DeveloperError('options.width is required.'); - } - if (!defined(options.height)) { - throw new DeveloperError('options.height is required.'); - } - - this._buffer = options.buffer; - this._width = options.width; - this._height = options.height; - this._childTileMask = defaultValue(options.childTileMask, 15); - - var defaultStructure = HeightmapTessellator.DEFAULT_STRUCTURE; - var structure = options.structure; - if (!defined(structure)) { - structure = defaultStructure; - } else if (structure !== defaultStructure) { - structure.heightScale = defaultValue(structure.heightScale, defaultStructure.heightScale); - structure.heightOffset = defaultValue(structure.heightOffset, defaultStructure.heightOffset); - structure.elementsPerHeight = defaultValue(structure.elementsPerHeight, defaultStructure.elementsPerHeight); - structure.stride = defaultValue(structure.stride, defaultStructure.stride); - structure.elementMultiplier = defaultValue(structure.elementMultiplier, defaultStructure.elementMultiplier); - structure.isBigEndian = defaultValue(structure.isBigEndian, defaultStructure.isBigEndian); - } - - this._structure = structure; - this._createdByUpsampling = defaultValue(options.createdByUpsampling, false); - this._waterMask = options.waterMask; - - this._skirtHeight = undefined; - this._bufferType = this._buffer.constructor; - this._mesh = undefined; - } - - defineProperties(HeightmapTerrainData.prototype, { + function OrientedBoundingBox(center, halfAxes) { /** - * An array of credits for this tile. - * @memberof HeightmapTerrainData.prototype - * @type {Credit[]} + * The center of the box. + * @type {Cartesian3} + * @default {@link Cartesian3.ZERO} */ - credits : { - get : function() { - return undefined; - } - }, + this.center = Cartesian3.clone(defaultValue(center, Cartesian3.ZERO)); /** - * The water mask included in this terrain data, if any. A water mask is a rectangular - * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. - * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. - * @memberof HeightmapTerrainData.prototype - * @type {Uint8Array|Image|Canvas} + * The transformation matrix, to rotate the box to the right position. + * @type {Matrix3} + * @default {@link Matrix3.ZERO} */ - waterMask : { - get : function() { - return this._waterMask; - } - } - }); - + this.halfAxes = Matrix3.clone(defaultValue(halfAxes, Matrix3.ZERO)); + } - var taskProcessor = new TaskProcessor('createVerticesFromHeightmap'); + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + OrientedBoundingBox.packedLength = Cartesian3.packedLength + Matrix3.packedLength; /** - * Creates a {@link TerrainMesh} from this terrain data. + * Stores the provided instance into the provided array. * - * @private + * @param {OrientedBoundingBox} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many - * asynchronous mesh creations are already in progress and the operation should - * be retried later. + * @returns {Number[]} The array that was packed into */ - HeightmapTerrainData.prototype.createMesh = function(tilingScheme, x, y, level, exaggeration) { - if (!defined(tilingScheme)) { - throw new DeveloperError('tilingScheme is required.'); - } - if (!defined(x)) { - throw new DeveloperError('x is required.'); - } - if (!defined(y)) { - throw new DeveloperError('y is required.'); - } - if (!defined(level)) { - throw new DeveloperError('level is required.'); - } + OrientedBoundingBox.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); - var ellipsoid = tilingScheme.ellipsoid; - var nativeRectangle = tilingScheme.tileXYToNativeRectangle(x, y, level); - var rectangle = tilingScheme.tileXYToRectangle(x, y, level); - exaggeration = defaultValue(exaggeration, 1.0); - - // Compute the center of the tile for RTC rendering. - var center = ellipsoid.cartographicToCartesian(Rectangle.center(rectangle)); - - var structure = this._structure; - - var levelZeroMaxError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(ellipsoid, this._width, tilingScheme.getNumberOfXTilesAtLevel(0)); - var thisLevelMaxError = levelZeroMaxError / (1 << level); - this._skirtHeight = Math.min(thisLevelMaxError * 4.0, 1000.0); - - var verticesPromise = taskProcessor.scheduleTask({ - heightmap : this._buffer, - structure : structure, - includeWebMercatorT : true, - width : this._width, - height : this._height, - nativeRectangle : nativeRectangle, - rectangle : rectangle, - relativeToCenter : center, - ellipsoid : ellipsoid, - skirtHeight : this._skirtHeight, - isGeographic : tilingScheme instanceof GeographicTilingScheme, - exaggeration : exaggeration - }); - - if (!defined(verticesPromise)) { - // Postponed - return undefined; - } + startingIndex = defaultValue(startingIndex, 0); - var that = this; - return when(verticesPromise, function(result) { - that._mesh = new TerrainMesh( - center, - new Float32Array(result.vertices), - TerrainProvider.getRegularGridIndices(result.gridWidth, result.gridHeight), - result.minimumHeight, - result.maximumHeight, - result.boundingSphere3D, - result.occludeePointInScaledSpace, - result.numberOfAttributes, - result.orientedBoundingBox, - TerrainEncoding.clone(result.encoding), - exaggeration); + Cartesian3.pack(value.center, array, startingIndex); + Matrix3.pack(value.halfAxes, array, startingIndex + Cartesian3.packedLength); - // Free memory received from server after mesh is created. - that._buffer = undefined; - return that._mesh; - }); + return array; }; /** - * Computes the terrain height at a specified longitude and latitude. + * Retrieves an instance from a packed array. * - * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. If the position - * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly - * incorrect for positions far outside the rectangle. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrientedBoundingBox} [result] The object into which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. */ - HeightmapTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) { - var width = this._width; - var height = this._height; - - var structure = this._structure; - var stride = structure.stride; - var elementsPerHeight = structure.elementsPerHeight; - var elementMultiplier = structure.elementMultiplier; - var isBigEndian = structure.isBigEndian; - var heightOffset = structure.heightOffset; - var heightScale = structure.heightScale; + OrientedBoundingBox.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - var heightSample; - if (defined(this._mesh)) { - var buffer = this._mesh.vertices; - var encoding = this._mesh.encoding; - var skirtHeight = this._skirtHeight; - var exaggeration = this._mesh.exaggeration; - heightSample = interpolateMeshHeight(buffer, encoding, heightOffset, heightScale, skirtHeight, rectangle, width, height, longitude, latitude, exaggeration); - } else { - heightSample = interpolateHeight(this._buffer, elementsPerHeight, elementMultiplier, stride, isBigEndian, rectangle, width, height, longitude, latitude); - heightSample = heightSample * heightScale + heightOffset; + if (!defined(result)) { + result = new OrientedBoundingBox(); } - return heightSample; + Cartesian3.unpack(array, startingIndex, result.center); + Matrix3.unpack(array, startingIndex + Cartesian3.packedLength, result.halfAxes); + return result; + }; + + var scratchCartesian1 = new Cartesian3(); + var scratchCartesian2 = new Cartesian3(); + var scratchCartesian3 = new Cartesian3(); + var scratchCartesian4 = new Cartesian3(); + var scratchCartesian5 = new Cartesian3(); + var scratchCartesian6 = new Cartesian3(); + var scratchCovarianceResult = new Matrix3(); + var scratchEigenResult = { + unitary : new Matrix3(), + diagonal : new Matrix3() }; /** - * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the - * height samples in this instance, interpolated if necessary. + * Computes an instance of an OrientedBoundingBox of the given positions. + * This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis). + * Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf * - * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, - * or undefined if too many asynchronous upsample operations are in progress and the request has been - * deferred. + * @param {Cartesian3[]} [positions] List of {@link Cartesian3} points that the bounding box will enclose. + * @param {OrientedBoundingBox} [result] The object onto which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + * + * @example + * // Compute an object oriented bounding box enclosing two points. + * var box = Cesium.OrientedBoundingBox.fromPoints([new Cesium.Cartesian3(2, 0, 0), new Cesium.Cartesian3(-2, 0, 0)]); */ - HeightmapTerrainData.prototype.upsample = function(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) { - if (!defined(tilingScheme)) { - throw new DeveloperError('tilingScheme is required.'); - } - if (!defined(thisX)) { - throw new DeveloperError('thisX is required.'); - } - if (!defined(thisY)) { - throw new DeveloperError('thisY is required.'); - } - if (!defined(thisLevel)) { - throw new DeveloperError('thisLevel is required.'); - } - if (!defined(descendantX)) { - throw new DeveloperError('descendantX is required.'); - } - if (!defined(descendantY)) { - throw new DeveloperError('descendantY is required.'); - } - if (!defined(descendantLevel)) { - throw new DeveloperError('descendantLevel is required.'); + OrientedBoundingBox.fromPoints = function(positions, result) { + if (!defined(result)) { + result = new OrientedBoundingBox(); } - var levelDifference = descendantLevel - thisLevel; - if (levelDifference > 1) { - throw new DeveloperError('Upsampling through more than one level at a time is not currently supported.'); + + if (!defined(positions) || positions.length === 0) { + result.halfAxes = Matrix3.ZERO; + result.center = Cartesian3.ZERO; + return result; } - - var width = this._width; - var height = this._height; - var structure = this._structure; - var skirtHeight = this._skirtHeight; - var stride = structure.stride; - var heights = new this._bufferType(width * height * stride); - var meshData = this._mesh; - if (!defined(meshData)) { - return undefined; + var i; + var length = positions.length; + + var meanPoint = Cartesian3.clone(positions[0], scratchCartesian1); + for (i = 1; i < length; i++) { + Cartesian3.add(meanPoint, positions[i], meanPoint); } + var invLength = 1.0 / length; + Cartesian3.multiplyByScalar(meanPoint, invLength, meanPoint); - var buffer = meshData.vertices; - var encoding = meshData.encoding; + var exx = 0.0; + var exy = 0.0; + var exz = 0.0; + var eyy = 0.0; + var eyz = 0.0; + var ezz = 0.0; + var p; - // PERFORMANCE_IDEA: don't recompute these rectangles - the caller already knows them. - var sourceRectangle = tilingScheme.tileXYToRectangle(thisX, thisY, thisLevel); - var destinationRectangle = tilingScheme.tileXYToRectangle(descendantX, descendantY, descendantLevel); + for (i = 0; i < length; i++) { + p = Cartesian3.subtract(positions[i], meanPoint, scratchCartesian2); + exx += p.x * p.x; + exy += p.x * p.y; + exz += p.x * p.z; + eyy += p.y * p.y; + eyz += p.y * p.z; + ezz += p.z * p.z; + } - var heightOffset = structure.heightOffset; - var heightScale = structure.heightScale; - var exaggeration = meshData.exaggeration; + exx *= invLength; + exy *= invLength; + exz *= invLength; + eyy *= invLength; + eyz *= invLength; + ezz *= invLength; - var elementsPerHeight = structure.elementsPerHeight; - var elementMultiplier = structure.elementMultiplier; - var isBigEndian = structure.isBigEndian; + var covarianceMatrix = scratchCovarianceResult; + covarianceMatrix[0] = exx; + covarianceMatrix[1] = exy; + covarianceMatrix[2] = exz; + covarianceMatrix[3] = exy; + covarianceMatrix[4] = eyy; + covarianceMatrix[5] = eyz; + covarianceMatrix[6] = exz; + covarianceMatrix[7] = eyz; + covarianceMatrix[8] = ezz; - var divisor = Math.pow(elementMultiplier, elementsPerHeight - 1); + var eigenDecomposition = Matrix3.computeEigenDecomposition(covarianceMatrix, scratchEigenResult); + var rotation = Matrix3.clone(eigenDecomposition.unitary, result.halfAxes); - for (var j = 0; j < height; ++j) { - var latitude = CesiumMath.lerp(destinationRectangle.north, destinationRectangle.south, j / (height - 1)); - for (var i = 0; i < width; ++i) { - var longitude = CesiumMath.lerp(destinationRectangle.west, destinationRectangle.east, i / (width - 1)); - var heightSample = interpolateMeshHeight(buffer, encoding, heightOffset, heightScale, skirtHeight, sourceRectangle, width, height, longitude, latitude, exaggeration); + var v1 = Matrix3.getColumn(rotation, 0, scratchCartesian4); + var v2 = Matrix3.getColumn(rotation, 1, scratchCartesian5); + var v3 = Matrix3.getColumn(rotation, 2, scratchCartesian6); - // Use conditionals here instead of Math.min and Math.max so that an undefined - // lowestEncodedHeight or highestEncodedHeight has no effect. - heightSample = heightSample < structure.lowestEncodedHeight ? structure.lowestEncodedHeight : heightSample; - heightSample = heightSample > structure.highestEncodedHeight ? structure.highestEncodedHeight : heightSample; + var u1 = -Number.MAX_VALUE; + var u2 = -Number.MAX_VALUE; + var u3 = -Number.MAX_VALUE; + var l1 = Number.MAX_VALUE; + var l2 = Number.MAX_VALUE; + var l3 = Number.MAX_VALUE; - setHeight(heights, elementsPerHeight, elementMultiplier, divisor, stride, isBigEndian, j * width + i, heightSample); - } + for (i = 0; i < length; i++) { + p = positions[i]; + u1 = Math.max(Cartesian3.dot(v1, p), u1); + u2 = Math.max(Cartesian3.dot(v2, p), u2); + u3 = Math.max(Cartesian3.dot(v3, p), u3); + + l1 = Math.min(Cartesian3.dot(v1, p), l1); + l2 = Math.min(Cartesian3.dot(v2, p), l2); + l3 = Math.min(Cartesian3.dot(v3, p), l3); } - return new HeightmapTerrainData({ - buffer : heights, - width : width, - height : height, - childTileMask : 0, - structure : this._structure, - createdByUpsampling : true - }); - }; + v1 = Cartesian3.multiplyByScalar(v1, 0.5 * (l1 + u1), v1); + v2 = Cartesian3.multiplyByScalar(v2, 0.5 * (l2 + u2), v2); + v3 = Cartesian3.multiplyByScalar(v3, 0.5 * (l3 + u3), v3); - /** - * Determines if a given child tile is available, based on the - * {@link HeightmapTerrainData.childTileMask}. The given child tile coordinates are assumed - * to be one of the four children of this tile. If non-child tile coordinates are - * given, the availability of the southeast child tile is returned. - * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. - */ - HeightmapTerrainData.prototype.isChildAvailable = function(thisX, thisY, childX, childY) { - if (!defined(thisX)) { - throw new DeveloperError('thisX is required.'); - } - if (!defined(thisY)) { - throw new DeveloperError('thisY is required.'); - } - if (!defined(childX)) { - throw new DeveloperError('childX is required.'); - } - if (!defined(childY)) { - throw new DeveloperError('childY is required.'); - } - - var bitNumber = 2; // northwest child - if (childX !== thisX * 2) { - ++bitNumber; // east child - } - if (childY !== thisY * 2) { - bitNumber -= 2; // south child - } + var center = Cartesian3.add(v1, v2, result.center); + Cartesian3.add(center, v3, center); - return (this._childTileMask & (1 << bitNumber)) !== 0; + var scale = scratchCartesian3; + scale.x = u1 - l1; + scale.y = u2 - l2; + scale.z = u3 - l3; + Cartesian3.multiplyByScalar(scale, 0.5, scale); + Matrix3.multiplyByScale(result.halfAxes, scale, result.halfAxes); + + return result; }; + var scratchOffset = new Cartesian3(); + var scratchScale = new Cartesian3(); /** - * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution - * terrain data. If this value is false, the data was obtained from some other source, such - * as by downloading it from a remote server. This method should return true for instances - * returned from a call to {@link HeightmapTerrainData#upsample}. + * Computes an OrientedBoundingBox given extents in the east-north-up space of the tangent plane. * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + * @param {Plane} tangentPlane The tangent place corresponding to east-north-up. + * @param {Number} minimumX Minimum X extent in tangent plane space. + * @param {Number} maximumX Maximum X extent in tangent plane space. + * @param {Number} minimumY Minimum Y extent in tangent plane space. + * @param {Number} maximumY Maximum Y extent in tangent plane space. + * @param {Number} minimumZ Minimum Z extent in tangent plane space. + * @param {Number} maximumZ Maximum Z extent in tangent plane space. + * @param {OrientedBoundingBox} [result] The object onto which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. */ - HeightmapTerrainData.prototype.wasCreatedByUpsampling = function() { - return this._createdByUpsampling; - }; - - function interpolateHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, sourceRectangle, width, height, longitude, latitude) { - var fromWest = (longitude - sourceRectangle.west) * (width - 1) / (sourceRectangle.east - sourceRectangle.west); - var fromSouth = (latitude - sourceRectangle.south) * (height - 1) / (sourceRectangle.north - sourceRectangle.south); - - var westInteger = fromWest | 0; - var eastInteger = westInteger + 1; - if (eastInteger >= width) { - eastInteger = width - 1; - westInteger = width - 2; + function fromTangentPlaneExtents(tangentPlane, minimumX, maximumX, minimumY, maximumY, minimumZ, maximumZ, result) { + if (!defined(minimumX) || + !defined(maximumX) || + !defined(minimumY) || + !defined(maximumY) || + !defined(minimumZ) || + !defined(maximumZ)) { + throw new DeveloperError('all extents (minimum/maximum X/Y/Z) are required.'); } - - var southInteger = fromSouth | 0; - var northInteger = southInteger + 1; - if (northInteger >= height) { - northInteger = height - 1; - southInteger = height - 2; + + if (!defined(result)) { + result = new OrientedBoundingBox(); } - var dx = fromWest - westInteger; - var dy = fromSouth - southInteger; - - southInteger = height - 1 - southInteger; - northInteger = height - 1 - northInteger; + var halfAxes = result.halfAxes; + Matrix3.setColumn(halfAxes, 0, tangentPlane.xAxis, halfAxes); + Matrix3.setColumn(halfAxes, 1, tangentPlane.yAxis, halfAxes); + Matrix3.setColumn(halfAxes, 2, tangentPlane.zAxis, halfAxes); - var southwestHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, southInteger * width + westInteger); - var southeastHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, southInteger * width + eastInteger); - var northwestHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, northInteger * width + westInteger); - var northeastHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, northInteger * width + eastInteger); + var centerOffset = scratchOffset; + centerOffset.x = (minimumX + maximumX) / 2.0; + centerOffset.y = (minimumY + maximumY) / 2.0; + centerOffset.z = (minimumZ + maximumZ) / 2.0; - return triangleInterpolateHeight(dx, dy, southwestHeight, southeastHeight, northwestHeight, northeastHeight); - } + var scale = scratchScale; + scale.x = (maximumX - minimumX) / 2.0; + scale.y = (maximumY - minimumY) / 2.0; + scale.z = (maximumZ - minimumZ) / 2.0; - function interpolateMeshHeight(buffer, encoding, heightOffset, heightScale, skirtHeight, sourceRectangle, width, height, longitude, latitude, exaggeration) { - // returns a height encoded according to the structure's heightScale and heightOffset. - var fromWest = (longitude - sourceRectangle.west) * (width - 1) / (sourceRectangle.east - sourceRectangle.west); - var fromSouth = (latitude - sourceRectangle.south) * (height - 1) / (sourceRectangle.north - sourceRectangle.south); + var center = result.center; + centerOffset = Matrix3.multiplyByVector(halfAxes, centerOffset, centerOffset); + Cartesian3.add(tangentPlane.origin, centerOffset, center); + Matrix3.multiplyByScale(halfAxes, scale, halfAxes); - if (skirtHeight > 0) { - fromWest += 1.0; - fromSouth += 1.0; + return result; + } - width += 2; - height += 2; + var scratchRectangleCenterCartographic = new Cartographic(); + var scratchRectangleCenter = new Cartesian3(); + var perimeterCartographicScratch = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; + var perimeterCartesianScratch = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; + var perimeterProjectedScratch = [new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2(), new Cartesian2()]; + /** + * Computes an OrientedBoundingBox that bounds a {@link Rectangle} on the surface of an {@link Ellipsoid}. + * There are no guarantees about the orientation of the bounding box. + * + * @param {Rectangle} rectangle The cartographic rectangle on the surface of the ellipsoid. + * @param {Number} [minimumHeight=0.0] The minimum height (elevation) within the tile. + * @param {Number} [maximumHeight=0.0] The maximum height (elevation) within the tile. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle is defined. + * @param {OrientedBoundingBox} [result] The object onto which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. + * + * @exception {DeveloperError} rectangle.width must be between 0 and pi. + * @exception {DeveloperError} rectangle.height must be between 0 and pi. + * @exception {DeveloperError} ellipsoid must be an ellipsoid of revolution (<code>radii.x == radii.y</code>) + */ + OrientedBoundingBox.fromRectangle = function(rectangle, minimumHeight, maximumHeight, ellipsoid, result) { + if (!defined(rectangle)) { + throw new DeveloperError('rectangle is required'); } - - var widthEdge = (skirtHeight > 0) ? width - 1 : width; - var westInteger = fromWest | 0; - var eastInteger = westInteger + 1; - if (eastInteger >= widthEdge) { - eastInteger = width - 1; - westInteger = width - 2; + if (rectangle.width < 0.0 || rectangle.width > CesiumMath.TWO_PI) { + throw new DeveloperError('Rectangle width must be between 0 and 2*pi'); } + if (rectangle.height < 0.0 || rectangle.height > CesiumMath.PI) { + throw new DeveloperError('Rectangle height must be between 0 and pi'); + } + if (defined(ellipsoid) && !CesiumMath.equalsEpsilon(ellipsoid.radii.x, ellipsoid.radii.y, CesiumMath.EPSILON15)) { + throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)'); + } + + minimumHeight = defaultValue(minimumHeight, 0.0); + maximumHeight = defaultValue(maximumHeight, 0.0); + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - var heightEdge = (skirtHeight > 0) ? height - 1 : height; - var southInteger = fromSouth | 0; - var northInteger = southInteger + 1; - if (northInteger >= heightEdge) { - northInteger = height - 1; - southInteger = height - 2; + // The bounding box will be aligned with the tangent plane at the center of the rectangle. + var tangentPointCartographic = Rectangle.center(rectangle, scratchRectangleCenterCartographic); + var tangentPoint = ellipsoid.cartographicToCartesian(tangentPointCartographic, scratchRectangleCenter); + var tangentPlane = new EllipsoidTangentPlane(tangentPoint, ellipsoid); + var plane = tangentPlane.plane; + + // Corner arrangement: + // N/+y + // [0] [1] [2] + // W/-x [7] [3] E/+x + // [6] [5] [4] + // S/-y + // "C" refers to the central lat/long, which by default aligns with the tangent point (above). + // If the rectangle spans the equator, CW and CE are instead aligned with the equator. + var perimeterNW = perimeterCartographicScratch[0]; + var perimeterNC = perimeterCartographicScratch[1]; + var perimeterNE = perimeterCartographicScratch[2]; + var perimeterCE = perimeterCartographicScratch[3]; + var perimeterSE = perimeterCartographicScratch[4]; + var perimeterSC = perimeterCartographicScratch[5]; + var perimeterSW = perimeterCartographicScratch[6]; + var perimeterCW = perimeterCartographicScratch[7]; + + var lonCenter = tangentPointCartographic.longitude; + var latCenter = (rectangle.south < 0.0 && rectangle.north > 0.0) ? 0.0 : tangentPointCartographic.latitude; + perimeterSW.latitude = perimeterSC.latitude = perimeterSE.latitude = rectangle.south; + perimeterCW.latitude = perimeterCE.latitude = latCenter; + perimeterNW.latitude = perimeterNC.latitude = perimeterNE.latitude = rectangle.north; + perimeterSW.longitude = perimeterCW.longitude = perimeterNW.longitude = rectangle.west; + perimeterSC.longitude = perimeterNC.longitude = lonCenter; + perimeterSE.longitude = perimeterCE.longitude = perimeterNE.longitude = rectangle.east; + + // Compute XY extents using the rectangle at maximum height + perimeterNE.height = perimeterNC.height = perimeterNW.height = perimeterCW.height = perimeterSW.height = perimeterSC.height = perimeterSE.height = perimeterCE.height = maximumHeight; + + ellipsoid.cartographicArrayToCartesianArray(perimeterCartographicScratch, perimeterCartesianScratch); + tangentPlane.projectPointsToNearestOnPlane(perimeterCartesianScratch, perimeterProjectedScratch); + // See the `perimeterXX` definitions above for what these are + var minX = Math.min(perimeterProjectedScratch[6].x, perimeterProjectedScratch[7].x, perimeterProjectedScratch[0].x); + var maxX = Math.max(perimeterProjectedScratch[2].x, perimeterProjectedScratch[3].x, perimeterProjectedScratch[4].x); + var minY = Math.min(perimeterProjectedScratch[4].y, perimeterProjectedScratch[5].y, perimeterProjectedScratch[6].y); + var maxY = Math.max(perimeterProjectedScratch[0].y, perimeterProjectedScratch[1].y, perimeterProjectedScratch[2].y); + + // Compute minimum Z using the rectangle at minimum height + perimeterNE.height = perimeterNW.height = perimeterSE.height = perimeterSW.height = minimumHeight; + ellipsoid.cartographicArrayToCartesianArray(perimeterCartographicScratch, perimeterCartesianScratch); + var minZ = Math.min(Plane.getPointDistance(plane, perimeterCartesianScratch[0]), + Plane.getPointDistance(plane, perimeterCartesianScratch[2]), + Plane.getPointDistance(plane, perimeterCartesianScratch[4]), + Plane.getPointDistance(plane, perimeterCartesianScratch[6])); + var maxZ = maximumHeight; // Since the tangent plane touches the surface at height = 0, this is okay + + return fromTangentPlaneExtents(tangentPlane, minX, maxX, minY, maxY, minZ, maxZ, result); + }; + + /** + * Duplicates a OrientedBoundingBox instance. + * + * @param {OrientedBoundingBox} box The bounding box to duplicate. + * @param {OrientedBoundingBox} [result] The object onto which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. (Returns undefined if box is undefined) + */ + OrientedBoundingBox.clone = function(box, result) { + if (!defined(box)) { + return undefined; } - var dx = fromWest - westInteger; - var dy = fromSouth - southInteger; + if (!defined(result)) { + return new OrientedBoundingBox(box.center, box.halfAxes); + } - southInteger = height - 1 - southInteger; - northInteger = height - 1 - northInteger; + Cartesian3.clone(box.center, result.center); + Matrix3.clone(box.halfAxes, result.halfAxes); - var southwestHeight = (encoding.decodeHeight(buffer, southInteger * width + westInteger) / exaggeration - heightOffset) / heightScale; - var southeastHeight = (encoding.decodeHeight(buffer, southInteger * width + eastInteger) / exaggeration - heightOffset) / heightScale; - var northwestHeight = (encoding.decodeHeight(buffer, northInteger * width + westInteger) / exaggeration - heightOffset) / heightScale; - var northeastHeight = (encoding.decodeHeight(buffer, northInteger * width + eastInteger) / exaggeration - heightOffset) / heightScale; + return result; + }; - return triangleInterpolateHeight(dx, dy, southwestHeight, southeastHeight, northwestHeight, northeastHeight); - } + /** + * Determines which side of a plane the oriented bounding box is located. + * + * @param {OrientedBoundingBox} box The oriented bounding box to test. + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is + * on the opposite side, and {@link Intersect.INTERSECTING} if the box + * intersects the plane. + */ + OrientedBoundingBox.intersectPlane = function(box, plane) { + if (!defined(box)) { + throw new DeveloperError('box is required.'); + } - function triangleInterpolateHeight(dX, dY, southwestHeight, southeastHeight, northwestHeight, northeastHeight) { - // The HeightmapTessellator bisects the quad from southwest to northeast. - if (dY < dX) { - // Lower right triangle - return southwestHeight + (dX * (southeastHeight - southwestHeight)) + (dY * (northeastHeight - southeastHeight)); + if (!defined(plane)) { + throw new DeveloperError('plane is required.'); } + + var center = box.center; + var normal = plane.normal; + var halfAxes = box.halfAxes; + var normalX = normal.x, normalY = normal.y, normalZ = normal.z; + // plane is used as if it is its normal; the first three components are assumed to be normalized + var radEffective = Math.abs(normalX * halfAxes[Matrix3.COLUMN0ROW0] + normalY * halfAxes[Matrix3.COLUMN0ROW1] + normalZ * halfAxes[Matrix3.COLUMN0ROW2]) + + Math.abs(normalX * halfAxes[Matrix3.COLUMN1ROW0] + normalY * halfAxes[Matrix3.COLUMN1ROW1] + normalZ * halfAxes[Matrix3.COLUMN1ROW2]) + + Math.abs(normalX * halfAxes[Matrix3.COLUMN2ROW0] + normalY * halfAxes[Matrix3.COLUMN2ROW1] + normalZ * halfAxes[Matrix3.COLUMN2ROW2]); + var distanceToPlane = Cartesian3.dot(normal, center) + plane.distance; - // Upper left triangle - return southwestHeight + (dX * (northeastHeight - northwestHeight)) + (dY * (northwestHeight - southwestHeight)); - } + if (distanceToPlane <= -radEffective) { + // The entire box is on the negative side of the plane normal + return Intersect.OUTSIDE; + } else if (distanceToPlane >= radEffective) { + // The entire box is on the positive side of the plane normal + return Intersect.INSIDE; + } + return Intersect.INTERSECTING; + }; - function getHeight(heights, elementsPerHeight, elementMultiplier, stride, isBigEndian, index) { - index *= stride; + var scratchCartesianU = new Cartesian3(); + var scratchCartesianV = new Cartesian3(); + var scratchCartesianW = new Cartesian3(); + var scratchPPrime = new Cartesian3(); - var height = 0; - var i; + /** + * Computes the estimated distance squared from the closest point on a bounding box to a point. + * + * @param {OrientedBoundingBox} box The box. + * @param {Cartesian3} cartesian The point + * @returns {Number} The estimated distance squared from the bounding sphere to the point. + * + * @example + * // Sort bounding boxes from back to front + * boxes.sort(function(a, b) { + * return Cesium.OrientedBoundingBox.distanceSquaredTo(b, camera.positionWC) - Cesium.OrientedBoundingBox.distanceSquaredTo(a, camera.positionWC); + * }); + */ + OrientedBoundingBox.distanceSquaredTo = function(box, cartesian) { + // See Geometric Tools for Computer Graphics 10.4.2 - if (isBigEndian) { - for (i = 0; i < elementsPerHeight; ++i) { - height = (height * elementMultiplier) + heights[index + i]; - } - } else { - for (i = elementsPerHeight - 1; i >= 0; --i) { - height = (height * elementMultiplier) + heights[index + i]; - } + if (!defined(box)) { + throw new DeveloperError('box is required.'); + } + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); } + + var offset = Cartesian3.subtract(cartesian, box.center, scratchOffset); - return height; - } + var halfAxes = box.halfAxes; + var u = Matrix3.getColumn(halfAxes, 0, scratchCartesianU); + var v = Matrix3.getColumn(halfAxes, 1, scratchCartesianV); + var w = Matrix3.getColumn(halfAxes, 2, scratchCartesianW); - function setHeight(heights, elementsPerHeight, elementMultiplier, divisor, stride, isBigEndian, index, height) { - index *= stride; + var uHalf = Cartesian3.magnitude(u); + var vHalf = Cartesian3.magnitude(v); + var wHalf = Cartesian3.magnitude(w); - var i; - if (isBigEndian) { - for (i = 0; i < elementsPerHeight - 1; ++i) { - heights[index + i] = (height / divisor) | 0; - height -= heights[index + i] * divisor; - divisor /= elementMultiplier; - } - } else { - for (i = elementsPerHeight - 1; i > 0; --i) { - heights[index + i] = (height / divisor) | 0; - height -= heights[index + i] * divisor; - divisor /= elementMultiplier; - } + Cartesian3.normalize(u, u); + Cartesian3.normalize(v, v); + Cartesian3.normalize(w, w); + + var pPrime = scratchPPrime; + pPrime.x = Cartesian3.dot(offset, u); + pPrime.y = Cartesian3.dot(offset, v); + pPrime.z = Cartesian3.dot(offset, w); + + var distanceSquared = 0.0; + var d; + + if (pPrime.x < -uHalf) { + d = pPrime.x + uHalf; + distanceSquared += d * d; + } else if (pPrime.x > uHalf) { + d = pPrime.x - uHalf; + distanceSquared += d * d; } - heights[index + i] = height; - } - return HeightmapTerrainData; -}); + if (pPrime.y < -vHalf) { + d = pPrime.y + vHalf; + distanceSquared += d * d; + } else if (pPrime.y > vHalf) { + d = pPrime.y - vHalf; + distanceSquared += d * d; + } -define('Core/IndexDatatype',[ - './defined', - './DeveloperError', - './freezeObject', - './Math', - './WebGLConstants' - ], function( - defined, - DeveloperError, - freezeObject, - CesiumMath, - WebGLConstants) { - 'use strict'; + if (pPrime.z < -wHalf) { + d = pPrime.z + wHalf; + distanceSquared += d * d; + } else if (pPrime.z > wHalf) { + d = pPrime.z - wHalf; + distanceSquared += d * d; + } + + return distanceSquared; + }; + + var scratchCorner = new Cartesian3(); + var scratchToCenter = new Cartesian3(); /** - * Constants for WebGL index datatypes. These corresponds to the - * <code>type</code> parameter of {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glDrawElements.xml|drawElements}. + * The distances calculated by the vector from the center of the bounding box to position projected onto direction. + * <br> + * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the + * closest and farthest planes from position that intersect the bounding box. * - * @exports IndexDatatype + * @param {OrientedBoundingBox} box The bounding box to calculate the distance to. + * @param {Cartesian3} position The position to calculate the distance from. + * @param {Cartesian3} direction The direction from position. + * @param {Interval} [result] A Interval to store the nearest and farthest distances. + * @returns {Interval} The nearest and farthest distances on the bounding box from position in direction. */ - var IndexDatatype = { - /** - * 8-bit unsigned byte corresponding to <code>UNSIGNED_BYTE</code> and the type - * of an element in <code>Uint8Array</code>. - * - * @type {Number} - * @constant - */ - UNSIGNED_BYTE : WebGLConstants.UNSIGNED_BYTE, + OrientedBoundingBox.computePlaneDistances = function(box, position, direction, result) { + if (!defined(box)) { + throw new DeveloperError('box is required.'); + } - /** - * 16-bit unsigned short corresponding to <code>UNSIGNED_SHORT</code> and the type - * of an element in <code>Uint16Array</code>. - * - * @type {Number} - * @constant - */ - UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT, + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } - /** - * 32-bit unsigned int corresponding to <code>UNSIGNED_INT</code> and the type - * of an element in <code>Uint32Array</code>. - * - * @type {Number} - * @constant - */ - UNSIGNED_INT : WebGLConstants.UNSIGNED_INT + if (!defined(direction)) { + throw new DeveloperError('direction is required.'); + } + + if (!defined(result)) { + result = new Interval(); + } + + var minDist = Number.POSITIVE_INFINITY; + var maxDist = Number.NEGATIVE_INFINITY; + + var center = box.center; + var halfAxes = box.halfAxes; + + var u = Matrix3.getColumn(halfAxes, 0, scratchCartesianU); + var v = Matrix3.getColumn(halfAxes, 1, scratchCartesianV); + var w = Matrix3.getColumn(halfAxes, 2, scratchCartesianW); + + // project first corner + var corner = Cartesian3.add(u, v, scratchCorner); + Cartesian3.add(corner, w, corner); + Cartesian3.add(corner, center, corner); + + var toCenter = Cartesian3.subtract(corner, position, scratchToCenter); + var mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project second corner + Cartesian3.add(center, u, corner); + Cartesian3.add(corner, v, corner); + Cartesian3.subtract(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project third corner + Cartesian3.add(center, u, corner); + Cartesian3.subtract(corner, v, corner); + Cartesian3.add(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project fourth corner + Cartesian3.add(center, u, corner); + Cartesian3.subtract(corner, v, corner); + Cartesian3.subtract(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project fifth corner + Cartesian3.subtract(center, u, corner); + Cartesian3.add(corner, v, corner); + Cartesian3.add(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project sixth corner + Cartesian3.subtract(center, u, corner); + Cartesian3.add(corner, v, corner); + Cartesian3.subtract(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project seventh corner + Cartesian3.subtract(center, u, corner); + Cartesian3.subtract(corner, v, corner); + Cartesian3.add(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + // project eighth corner + Cartesian3.subtract(center, u, corner); + Cartesian3.subtract(corner, v, corner); + Cartesian3.subtract(corner, w, corner); + + Cartesian3.subtract(corner, position, toCenter); + mag = Cartesian3.dot(direction, toCenter); + + minDist = Math.min(mag, minDist); + maxDist = Math.max(mag, maxDist); + + result.start = minDist; + result.stop = maxDist; + return result; }; + var scratchBoundingSphere = new BoundingSphere(); + /** - * Returns the size, in bytes, of the corresponding datatype. - * - * @param {IndexDatatype} indexDatatype The index datatype to get the size of. - * @returns {Number} The size in bytes. + * Determines whether or not a bounding box is hidden from view by the occluder. * - * @example - * // Returns 2 - * var size = Cesium.IndexDatatype.getSizeInBytes(Cesium.IndexDatatype.UNSIGNED_SHORT); + * @param {OrientedBoundingBox} box The bounding box surrounding the occludee object. + * @param {Occluder} occluder The occluder. + * @returns {Boolean} <code>true</code> if the box is not visible; otherwise <code>false</code>. */ - IndexDatatype.getSizeInBytes = function(indexDatatype) { - switch(indexDatatype) { - case IndexDatatype.UNSIGNED_BYTE: - return Uint8Array.BYTES_PER_ELEMENT; - case IndexDatatype.UNSIGNED_SHORT: - return Uint16Array.BYTES_PER_ELEMENT; - case IndexDatatype.UNSIGNED_INT: - return Uint32Array.BYTES_PER_ELEMENT; + OrientedBoundingBox.isOccluded = function(box, occluder) { + if (!defined(box)) { + throw new DeveloperError('box is required.'); + } + if (!defined(occluder)) { + throw new DeveloperError('occluder is required.'); } + + var sphere = BoundingSphere.fromOrientedBoundingBox(box, scratchBoundingSphere); - throw new DeveloperError('indexDatatype is required and must be a valid IndexDatatype constant.'); - }; + return !occluder.isBoundingSphereVisible(sphere); + }; /** - * Validates that the provided index datatype is a valid {@link IndexDatatype}. - * - * @param {IndexDatatype} indexDatatype The index datatype to validate. - * @returns {Boolean} <code>true</code> if the provided index datatype is a valid value; otherwise, <code>false</code>. + * Determines which side of a plane the oriented bounding box is located. * - * @example - * if (!Cesium.IndexDatatype.validate(indexDatatype)) { - * throw new Cesium.DeveloperError('indexDatatype must be a valid value.'); - * } + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is + * on the opposite side, and {@link Intersect.INTERSECTING} if the box + * intersects the plane. */ - IndexDatatype.validate = function(indexDatatype) { - return defined(indexDatatype) && - (indexDatatype === IndexDatatype.UNSIGNED_BYTE || - indexDatatype === IndexDatatype.UNSIGNED_SHORT || - indexDatatype === IndexDatatype.UNSIGNED_INT); + OrientedBoundingBox.prototype.intersectPlane = function(plane) { + return OrientedBoundingBox.intersectPlane(this, plane); }; /** - * Creates a typed array that will store indices, using either <code><Uint16Array</code> - * or <code>Uint32Array</code> depending on the number of vertices. + * Computes the estimated distance squared from the closest point on a bounding box to a point. * - * @param {Number} numberOfVertices Number of vertices that the indices will reference. - * @param {*} indicesLengthOrArray Passed through to the typed array constructor. - * @returns {Uint16Array|Uint32Array} A <code>Uint16Array</code> or <code>Uint32Array</code> constructed with <code>indicesLengthOrArray</code>. + * @param {Cartesian3} cartesian The point + * @returns {Number} The estimated distance squared from the bounding sphere to the point. * * @example - * this.indices = Cesium.IndexDatatype.createTypedArray(positions.length / 3, numberOfIndices); + * // Sort bounding boxes from back to front + * boxes.sort(function(a, b) { + * return b.distanceSquaredTo(camera.positionWC) - a.distanceSquaredTo(camera.positionWC); + * }); */ - IndexDatatype.createTypedArray = function(numberOfVertices, indicesLengthOrArray) { - if (!defined(numberOfVertices)) { - throw new DeveloperError('numberOfVertices is required.'); - } - - if (numberOfVertices >= CesiumMath.SIXTY_FOUR_KILOBYTES) { - return new Uint32Array(indicesLengthOrArray); - } + OrientedBoundingBox.prototype.distanceSquaredTo = function(cartesian) { + return OrientedBoundingBox.distanceSquaredTo(this, cartesian); + }; - return new Uint16Array(indicesLengthOrArray); + /** + * The distances calculated by the vector from the center of the bounding box to position projected onto direction. + * <br> + * If you imagine the infinite number of planes with normal direction, this computes the smallest distance to the + * closest and farthest planes from position that intersect the bounding box. + * + * @param {Cartesian3} position The position to calculate the distance from. + * @param {Cartesian3} direction The direction from position. + * @param {Interval} [result] A Interval to store the nearest and farthest distances. + * @returns {Interval} The nearest and farthest distances on the bounding box from position in direction. + */ + OrientedBoundingBox.prototype.computePlaneDistances = function(position, direction, result) { + return OrientedBoundingBox.computePlaneDistances(this, position, direction, result); }; /** - * Creates a typed array from a source array buffer. The resulting typed array will store indices, using either <code><Uint16Array</code> - * or <code>Uint32Array</code> depending on the number of vertices. + * Determines whether or not a bounding box is hidden from view by the occluder. * - * @param {Number} numberOfVertices Number of vertices that the indices will reference. - * @param {ArrayBuffer} sourceArray Passed through to the typed array constructor. - * @param {Number} byteOffset Passed through to the typed array constructor. - * @param {Number} length Passed through to the typed array constructor. - * @returns {Uint16Array|Uint32Array} A <code>Uint16Array</code> or <code>Uint32Array</code> constructed with <code>sourceArray</code>, <code>byteOffset</code>, and <code>length</code>. + * @param {Occluder} occluder The occluder. + * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. + */ + OrientedBoundingBox.prototype.isOccluded = function(occluder) { + return OrientedBoundingBox.isOccluded(this, occluder); + }; + + /** + * Compares the provided OrientedBoundingBox componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * + * @param {OrientedBoundingBox} left The first OrientedBoundingBox. + * @param {OrientedBoundingBox} right The second OrientedBoundingBox. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - IndexDatatype.createTypedArrayFromArrayBuffer = function(numberOfVertices, sourceArray, byteOffset, length) { - if (!defined(numberOfVertices)) { - throw new DeveloperError('numberOfVertices is required.'); - } - if (!defined(sourceArray)) { - throw new DeveloperError('sourceArray is required.'); - } - if (!defined(byteOffset)) { - throw new DeveloperError('byteOffset is required.'); - } - - if (numberOfVertices >= CesiumMath.SIXTY_FOUR_KILOBYTES) { - return new Uint32Array(sourceArray, byteOffset, length); - } + OrientedBoundingBox.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + Cartesian3.equals(left.center, right.center) && + Matrix3.equals(left.halfAxes, right.halfAxes)); + }; - return new Uint16Array(sourceArray, byteOffset, length); + /** + * Duplicates this OrientedBoundingBox instance. + * + * @param {OrientedBoundingBox} [result] The object onto which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + */ + OrientedBoundingBox.prototype.clone = function(result) { + return OrientedBoundingBox.clone(this, result); }; - return freezeObject(IndexDatatype); + /** + * Compares this OrientedBoundingBox against the provided OrientedBoundingBox componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {OrientedBoundingBox} [right] The right hand side OrientedBoundingBox. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + OrientedBoundingBox.prototype.equals = function(right) { + return OrientedBoundingBox.equals(this, right); + }; + + return OrientedBoundingBox; }); -define('Core/loadArrayBuffer',[ - './loadWithXhr' +define('Core/TerrainQuantization',[ + './freezeObject' ], function( - loadWithXhr) { + freezeObject) { 'use strict'; /** - * Asynchronously loads the given URL as raw binary data. Returns a promise that will resolve to - * an ArrayBuffer once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadArrayBuffer - * - * @param {String} url The URL of the binary data. - * @param {Object} [headers] HTTP headers to send with the requests. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * This enumerated type is used to determine how the vertices of the terrain mesh are compressed. * - * @example - * // load a single URL asynchronously - * Cesium.loadArrayBuffer('some/url').then(function(arrayBuffer) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * @exports TerrainQuantization * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadArrayBuffer(url, headers, request) { - return loadWithXhr({ - url : url, - responseType : 'arraybuffer', - headers : headers, - request : request - }); - } + var TerrainQuantization = { + /** + * The vertices are not compressed. + * + * @type {Number} + * @constant + */ + NONE : 0, - return loadArrayBuffer; + /** + * The vertices are compressed to 12 bits. + * + * @type {Number} + * @constant + */ + BITS12 : 1 + }; + + return freezeObject(TerrainQuantization); }); -define('Core/Intersections2D',[ +define('Core/TerrainEncoding',[ + './AttributeCompression', + './Cartesian2', './Cartesian3', + './ComponentDatatype', + './defaultValue', './defined', - './DeveloperError' + './Math', + './Matrix4', + './TerrainQuantization' ], function( + AttributeCompression, + Cartesian2, Cartesian3, + ComponentDatatype, + defaultValue, defined, - DeveloperError) { + CesiumMath, + Matrix4, + TerrainQuantization) { 'use strict'; - /** - * Contains functions for operating on 2D triangles. - * - * @exports Intersections2D - */ - var Intersections2D = {}; + var cartesian3Scratch = new Cartesian3(); + var cartesian3DimScratch = new Cartesian3(); + var cartesian2Scratch = new Cartesian2(); + var matrix4Scratch = new Matrix4(); + var matrix4Scratch2 = new Matrix4(); + + var SHIFT_LEFT_12 = Math.pow(2.0, 12.0); /** - * Splits a 2D triangle at given axis-aligned threshold value and returns the resulting - * polygon on a given side of the threshold. The resulting polygon may have 0, 1, 2, - * 3, or 4 vertices. + * Data used to quantize and pack the terrain mesh. The position can be unpacked for picking and all attributes + * are unpacked in the vertex shader. * - * @param {Number} threshold The threshold coordinate value at which to clip the triangle. - * @param {Boolean} keepAbove true to keep the portion of the triangle above the threshold, or false - * to keep the portion below. - * @param {Number} u0 The coordinate of the first vertex in the triangle, in counter-clockwise order. - * @param {Number} u1 The coordinate of the second vertex in the triangle, in counter-clockwise order. - * @param {Number} u2 The coordinate of the third vertex in the triangle, in counter-clockwise order. - * @param {Number[]} [result] The array into which to copy the result. If this parameter is not supplied, - * a new array is constructed and returned. - * @returns {Number[]} The polygon that results after the clip, specified as a list of - * vertices. The vertices are specified in counter-clockwise order. - * Each vertex is either an index from the existing list (identified as - * a 0, 1, or 2) or -1 indicating a new vertex not in the original triangle. - * For new vertices, the -1 is followed by three additional numbers: the - * index of each of the two original vertices forming the line segment that - * the new vertex lies on, and the fraction of the distance from the first - * vertex to the second one. + * @alias TerrainEncoding + * @constructor * - * @example - * var result = Cesium.Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, false, 0.2, 0.6, 0.4); - * // result === [2, 0, -1, 1, 0, 0.25, -1, 1, 2, 0.5] + * @param {AxisAlignedBoundingBox} axisAlignedBoundingBox The bounds of the tile in the east-north-up coordinates at the tiles center. + * @param {Number} minimumHeight The minimum height. + * @param {Number} maximumHeight The maximum height. + * @param {Matrix4} fromENU The east-north-up to fixed frame matrix at the center of the terrain mesh. + * @param {Boolean} hasVertexNormals If the mesh has vertex normals. + * @param {Boolean} [hasWebMercatorT=false] true if the terrain data includes a Web Mercator texture coordinate; otherwise, false. + * + * @private */ - Intersections2D.clipTriangleAtAxisAlignedThreshold = function(threshold, keepAbove, u0, u1, u2, result) { - if (!defined(threshold)) { - throw new DeveloperError('threshold is required.'); - } - if (!defined(keepAbove)) { - throw new DeveloperError('keepAbove is required.'); - } - if (!defined(u0)) { - throw new DeveloperError('u0 is required.'); - } - if (!defined(u1)) { - throw new DeveloperError('u1 is required.'); - } - if (!defined(u2)) { - throw new DeveloperError('u2 is required.'); - } - - if (!defined(result)) { - result = []; - } else { - result.length = 0; - } + function TerrainEncoding(axisAlignedBoundingBox, minimumHeight, maximumHeight, fromENU, hasVertexNormals, hasWebMercatorT) { + var quantization; + var center; + var toENU; + var matrix; - var u0Behind; - var u1Behind; - var u2Behind; - if (keepAbove) { - u0Behind = u0 < threshold; - u1Behind = u1 < threshold; - u2Behind = u2 < threshold; - } else { - u0Behind = u0 > threshold; - u1Behind = u1 > threshold; - u2Behind = u2 > threshold; - } + if (defined(axisAlignedBoundingBox) && defined(minimumHeight) && defined(maximumHeight) && defined(fromENU)) { + var minimum = axisAlignedBoundingBox.minimum; + var maximum = axisAlignedBoundingBox.maximum; - var numBehind = u0Behind + u1Behind + u2Behind; + var dimensions = Cartesian3.subtract(maximum, minimum, cartesian3DimScratch); + var hDim = maximumHeight - minimumHeight; + var maxDim = Math.max(Cartesian3.maximumComponent(dimensions), hDim); - var u01Ratio; - var u02Ratio; - var u12Ratio; - var u10Ratio; - var u20Ratio; - var u21Ratio; + if (maxDim < SHIFT_LEFT_12 - 1.0) { + quantization = TerrainQuantization.BITS12; + } else { + quantization = TerrainQuantization.NONE; + } - if (numBehind === 1) { - if (u0Behind) { - u01Ratio = (threshold - u0) / (u1 - u0); - u02Ratio = (threshold - u0) / (u2 - u0); + center = axisAlignedBoundingBox.center; + toENU = Matrix4.inverseTransformation(fromENU, new Matrix4()); - result.push(1); + var translation = Cartesian3.negate(minimum, cartesian3Scratch); + Matrix4.multiply(Matrix4.fromTranslation(translation, matrix4Scratch), toENU, toENU); - result.push(2); + var scale = cartesian3Scratch; + scale.x = 1.0 / dimensions.x; + scale.y = 1.0 / dimensions.y; + scale.z = 1.0 / dimensions.z; + Matrix4.multiply(Matrix4.fromScale(scale, matrix4Scratch), toENU, toENU); - if (u02Ratio !== 1.0) { - result.push(-1); - result.push(0); - result.push(2); - result.push(u02Ratio); - } + matrix = Matrix4.clone(fromENU); + Matrix4.setTranslation(matrix, Cartesian3.ZERO, matrix); - if (u01Ratio !== 1.0) { - result.push(-1); - result.push(0); - result.push(1); - result.push(u01Ratio); - } - } else if (u1Behind) { - u12Ratio = (threshold - u1) / (u2 - u1); - u10Ratio = (threshold - u1) / (u0 - u1); + fromENU = Matrix4.clone(fromENU, new Matrix4()); - result.push(2); + var translationMatrix = Matrix4.fromTranslation(minimum, matrix4Scratch); + var scaleMatrix = Matrix4.fromScale(dimensions, matrix4Scratch2); + var st = Matrix4.multiply(translationMatrix, scaleMatrix,matrix4Scratch); - result.push(0); + Matrix4.multiply(fromENU, st, fromENU); + Matrix4.multiply(matrix, st, matrix); + } - if (u10Ratio !== 1.0) { - result.push(-1); - result.push(1); - result.push(0); - result.push(u10Ratio); - } + /** + * How the vertices of the mesh were compressed. + * @type {TerrainQuantization} + */ + this.quantization = quantization; - if (u12Ratio !== 1.0) { - result.push(-1); - result.push(1); - result.push(2); - result.push(u12Ratio); - } - } else if (u2Behind) { - u20Ratio = (threshold - u2) / (u0 - u2); - u21Ratio = (threshold - u2) / (u1 - u2); + /** + * The minimum height of the tile including the skirts. + * @type {Number} + */ + this.minimumHeight = minimumHeight; - result.push(0); + /** + * The maximum height of the tile. + * @type {Number} + */ + this.maximumHeight = maximumHeight; - result.push(1); + /** + * The center of the tile. + * @type {Cartesian3} + */ + this.center = center; - if (u21Ratio !== 1.0) { - result.push(-1); - result.push(2); - result.push(1); - result.push(u21Ratio); - } + /** + * A matrix that takes a vertex from the tile, transforms it to east-north-up at the center and scales + * it so each component is in the [0, 1] range. + * @type {Matrix4} + */ + this.toScaledENU = toENU; - if (u20Ratio !== 1.0) { - result.push(-1); - result.push(2); - result.push(0); - result.push(u20Ratio); - } - } - } else if (numBehind === 2) { - if (!u0Behind && u0 !== threshold) { - u10Ratio = (threshold - u1) / (u0 - u1); - u20Ratio = (threshold - u2) / (u0 - u2); + /** + * A matrix that restores a vertex transformed with toScaledENU back to the earth fixed reference frame + * @type {Matrix4} + */ + this.fromScaledENU = fromENU; - result.push(0); + /** + * The matrix used to decompress the terrain vertices in the shader for RTE rendering. + * @type {Matrix4} + */ + this.matrix = matrix; - result.push(-1); - result.push(1); - result.push(0); - result.push(u10Ratio); + /** + * The terrain mesh contains normals. + * @type {Boolean} + */ + this.hasVertexNormals = hasVertexNormals; - result.push(-1); - result.push(2); - result.push(0); - result.push(u20Ratio); - } else if (!u1Behind && u1 !== threshold) { - u21Ratio = (threshold - u2) / (u1 - u2); - u01Ratio = (threshold - u0) / (u1 - u0); + /** + * The terrain mesh contains a vertical texture coordinate following the Web Mercator projection. + * @type {Boolean} + */ + this.hasWebMercatorT = defaultValue(hasWebMercatorT, false); + } - result.push(1); + TerrainEncoding.prototype.encode = function(vertexBuffer, bufferIndex, position, uv, height, normalToPack, webMercatorT) { + var u = uv.x; + var v = uv.y; - result.push(-1); - result.push(2); - result.push(1); - result.push(u21Ratio); + if (this.quantization === TerrainQuantization.BITS12) { + position = Matrix4.multiplyByPoint(this.toScaledENU, position, cartesian3Scratch); - result.push(-1); - result.push(0); - result.push(1); - result.push(u01Ratio); - } else if (!u2Behind && u2 !== threshold) { - u02Ratio = (threshold - u0) / (u2 - u0); - u12Ratio = (threshold - u1) / (u2 - u1); + position.x = CesiumMath.clamp(position.x, 0.0, 1.0); + position.y = CesiumMath.clamp(position.y, 0.0, 1.0); + position.z = CesiumMath.clamp(position.z, 0.0, 1.0); - result.push(2); + var hDim = this.maximumHeight - this.minimumHeight; + var h = CesiumMath.clamp((height - this.minimumHeight) / hDim, 0.0, 1.0); - result.push(-1); - result.push(0); - result.push(2); - result.push(u02Ratio); + Cartesian2.fromElements(position.x, position.y, cartesian2Scratch); + var compressed0 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); - result.push(-1); - result.push(1); - result.push(2); - result.push(u12Ratio); + Cartesian2.fromElements(position.z, h, cartesian2Scratch); + var compressed1 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); + + Cartesian2.fromElements(u, v, cartesian2Scratch); + var compressed2 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); + + vertexBuffer[bufferIndex++] = compressed0; + vertexBuffer[bufferIndex++] = compressed1; + vertexBuffer[bufferIndex++] = compressed2; + + if (this.hasWebMercatorT) { + Cartesian2.fromElements(webMercatorT, 0.0, cartesian2Scratch); + var compressed3 = AttributeCompression.compressTextureCoordinates(cartesian2Scratch); + vertexBuffer[bufferIndex++] = compressed3; } - } else if (numBehind !== 3) { - // Completely in front of threshold - result.push(0); - result.push(1); - result.push(2); - } - // else Completely behind threshold + } else { + Cartesian3.subtract(position, this.center, cartesian3Scratch); - return result; - }; + vertexBuffer[bufferIndex++] = cartesian3Scratch.x; + vertexBuffer[bufferIndex++] = cartesian3Scratch.y; + vertexBuffer[bufferIndex++] = cartesian3Scratch.z; + vertexBuffer[bufferIndex++] = height; + vertexBuffer[bufferIndex++] = u; + vertexBuffer[bufferIndex++] = v; - /** - * Compute the barycentric coordinates of a 2D position within a 2D triangle. - * - * @param {Number} x The x coordinate of the position for which to find the barycentric coordinates. - * @param {Number} y The y coordinate of the position for which to find the barycentric coordinates. - * @param {Number} x1 The x coordinate of the triangle's first vertex. - * @param {Number} y1 The y coordinate of the triangle's first vertex. - * @param {Number} x2 The x coordinate of the triangle's second vertex. - * @param {Number} y2 The y coordinate of the triangle's second vertex. - * @param {Number} x3 The x coordinate of the triangle's third vertex. - * @param {Number} y3 The y coordinate of the triangle's third vertex. - * @param {Cartesian3} [result] The instance into to which to copy the result. If this parameter - * is undefined, a new instance is created and returned. - * @returns {Cartesian3} The barycentric coordinates of the position within the triangle. - * - * @example - * var result = Cesium.Intersections2D.computeBarycentricCoordinates(0.0, 0.0, 0.0, 1.0, -1, -0.5, 1, -0.5); - * // result === new Cesium.Cartesian3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0); - */ - Intersections2D.computeBarycentricCoordinates = function(x, y, x1, y1, x2, y2, x3, y3, result) { - if (!defined(x)) { - throw new DeveloperError('x is required.'); - } - if (!defined(y)) { - throw new DeveloperError('y is required.'); - } - if (!defined(x1)) { - throw new DeveloperError('x1 is required.'); - } - if (!defined(y1)) { - throw new DeveloperError('y1 is required.'); - } - if (!defined(x2)) { - throw new DeveloperError('x2 is required.'); - } - if (!defined(y2)) { - throw new DeveloperError('y2 is required.'); + if (this.hasWebMercatorT) { + vertexBuffer[bufferIndex++] = webMercatorT; + } } - if (!defined(x3)) { - throw new DeveloperError('x3 is required.'); + + if (this.hasVertexNormals) { + vertexBuffer[bufferIndex++] = AttributeCompression.octPackFloat(normalToPack); } - if (!defined(y3)) { - throw new DeveloperError('y3 is required.'); + + return bufferIndex; + }; + + TerrainEncoding.prototype.decodePosition = function(buffer, index, result) { + if (!defined(result)) { + result = new Cartesian3(); } - - var x1mx3 = x1 - x3; - var x3mx2 = x3 - x2; - var y2my3 = y2 - y3; - var y1my3 = y1 - y3; - var inverseDeterminant = 1.0 / (y2my3 * x1mx3 + x3mx2 * y1my3); - var ymy3 = y - y3; - var xmx3 = x - x3; - var l1 = (y2my3 * xmx3 + x3mx2 * ymy3) * inverseDeterminant; - var l2 = (-y1my3 * xmx3 + x1mx3 * ymy3) * inverseDeterminant; - var l3 = 1.0 - l1 - l2; - if (defined(result)) { - result.x = l1; - result.y = l2; - result.z = l3; - return result; + index *= this.getStride(); + + if (this.quantization === TerrainQuantization.BITS12) { + var xy = AttributeCompression.decompressTextureCoordinates(buffer[index], cartesian2Scratch); + result.x = xy.x; + result.y = xy.y; + + var zh = AttributeCompression.decompressTextureCoordinates(buffer[index + 1], cartesian2Scratch); + result.z = zh.x; + + return Matrix4.multiplyByPoint(this.fromScaledENU, result, result); } - return new Cartesian3(l1, l2, l3); + + result.x = buffer[index]; + result.y = buffer[index + 1]; + result.z = buffer[index + 2]; + return Cartesian3.add(result, this.center, result); }; - return Intersections2D; -}); - -define('Core/QuantizedMeshTerrainData',[ - '../ThirdParty/when', - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './IndexDatatype', - './Intersections2D', - './Math', - './OrientedBoundingBox', - './TaskProcessor', - './TerrainEncoding', - './TerrainMesh' - ], function( - when, - BoundingSphere, - Cartesian2, - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - IndexDatatype, - Intersections2D, - CesiumMath, - OrientedBoundingBox, - TaskProcessor, - TerrainEncoding, - TerrainMesh) { - 'use strict'; - - /** - * Terrain data for a single tile where the terrain data is represented as a quantized mesh. A quantized - * mesh consists of three vertex attributes, longitude, latitude, and height. All attributes are expressed - * as 16-bit values in the range 0 to 32767. Longitude and latitude are zero at the southwest corner - * of the tile and 32767 at the northeast corner. Height is zero at the minimum height in the tile - * and 32767 at the maximum height in the tile. - * - * @alias QuantizedMeshTerrainData - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Uint16Array} options.quantizedVertices The buffer containing the quantized mesh. - * @param {Uint16Array|Uint32Array} options.indices The indices specifying how the quantized vertices are linked - * together into triangles. Each three indices specifies one triangle. - * @param {Number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid. - * @param {Number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid. - * @param {BoundingSphere} options.boundingSphere A sphere bounding all of the vertices in the mesh. - * @param {OrientedBoundingBox} [options.orientedBoundingBox] An OrientedBoundingBox bounding all of the vertices in the mesh. - * @param {Cartesian3} options.horizonOcclusionPoint The horizon occlusion point of the mesh. If this point - * is below the horizon, the entire tile is assumed to be below the horizon as well. - * The point is expressed in ellipsoid-scaled coordinates. - * @param {Number[]} options.westIndices The indices of the vertices on the western edge of the tile. - * @param {Number[]} options.southIndices The indices of the vertices on the southern edge of the tile. - * @param {Number[]} options.eastIndices The indices of the vertices on the eastern edge of the tile. - * @param {Number[]} options.northIndices The indices of the vertices on the northern edge of the tile. - * @param {Number} options.westSkirtHeight The height of the skirt to add on the western edge of the tile. - * @param {Number} options.southSkirtHeight The height of the skirt to add on the southern edge of the tile. - * @param {Number} options.eastSkirtHeight The height of the skirt to add on the eastern edge of the tile. - * @param {Number} options.northSkirtHeight The height of the skirt to add on the northern edge of the tile. - * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. - * If a child's bit is set, geometry will be requested for that tile as well when it - * is needed. If the bit is cleared, the child tile is not requested and geometry is - * instead upsampled from the parent. The bit values are as follows: - * <table> - * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> - * <tr><td>0</td><td>1</td><td>Southwest</td></tr> - * <tr><td>1</td><td>2</td><td>Southeast</td></tr> - * <tr><td>2</td><td>4</td><td>Northwest</td></tr> - * <tr><td>3</td><td>8</td><td>Northeast</td></tr> - * </table> - * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; - * otherwise, false. - * @param {Uint8Array} [options.encodedNormals] The buffer containing per vertex normals, encoded using 'oct' encoding - * @param {Uint8Array} [options.waterMask] The buffer containing the watermask. - * @param {Credit[]} [options.credits] Array of credits for this tile. - * - * - * @example - * var data = new Cesium.QuantizedMeshTerrainData({ - * minimumHeight : -100, - * maximumHeight : 2101, - * quantizedVertices : new Uint16Array([// order is SW NW SE NE - * // longitude - * 0, 0, 32767, 32767, - * // latitude - * 0, 32767, 0, 32767, - * // heights - * 16384, 0, 32767, 16384]), - * indices : new Uint16Array([0, 3, 1, - * 0, 2, 3]), - * boundingSphere : new Cesium.BoundingSphere(new Cesium.Cartesian3(1.0, 2.0, 3.0), 10000), - * orientedBoundingBox : new Cesium.OrientedBoundingBox(new Cesium.Cartesian3(1.0, 2.0, 3.0), Cesium.Matrix3.fromRotationX(Cesium.Math.PI, new Cesium.Matrix3())), - * horizonOcclusionPoint : new Cesium.Cartesian3(3.0, 2.0, 1.0), - * westIndices : [0, 1], - * southIndices : [0, 1], - * eastIndices : [2, 3], - * northIndices : [1, 3], - * westSkirtHeight : 1.0, - * southSkirtHeight : 1.0, - * eastSkirtHeight : 1.0, - * northSkirtHeight : 1.0 - * }); - * - * @see TerrainData - * @see HeightmapTerrainData - */ - function QuantizedMeshTerrainData(options) { - if (!defined(options) || !defined(options.quantizedVertices)) { - throw new DeveloperError('options.quantizedVertices is required.'); - } - if (!defined(options.indices)) { - throw new DeveloperError('options.indices is required.'); - } - if (!defined(options.minimumHeight)) { - throw new DeveloperError('options.minimumHeight is required.'); - } - if (!defined(options.maximumHeight)) { - throw new DeveloperError('options.maximumHeight is required.'); - } - if (!defined(options.maximumHeight)) { - throw new DeveloperError('options.maximumHeight is required.'); - } - if (!defined(options.boundingSphere)) { - throw new DeveloperError('options.boundingSphere is required.'); - } - if (!defined(options.horizonOcclusionPoint)) { - throw new DeveloperError('options.horizonOcclusionPoint is required.'); - } - if (!defined(options.westIndices)) { - throw new DeveloperError('options.westIndices is required.'); - } - if (!defined(options.southIndices)) { - throw new DeveloperError('options.southIndices is required.'); - } - if (!defined(options.eastIndices)) { - throw new DeveloperError('options.eastIndices is required.'); - } - if (!defined(options.northIndices)) { - throw new DeveloperError('options.northIndices is required.'); - } - if (!defined(options.westSkirtHeight)) { - throw new DeveloperError('options.westSkirtHeight is required.'); - } - if (!defined(options.southSkirtHeight)) { - throw new DeveloperError('options.southSkirtHeight is required.'); - } - if (!defined(options.eastSkirtHeight)) { - throw new DeveloperError('options.eastSkirtHeight is required.'); - } - if (!defined(options.northSkirtHeight)) { - throw new DeveloperError('options.northSkirtHeight is required.'); + TerrainEncoding.prototype.decodeTextureCoordinates = function(buffer, index, result) { + if (!defined(result)) { + result = new Cartesian2(); } - - this._quantizedVertices = options.quantizedVertices; - this._encodedNormals = options.encodedNormals; - this._indices = options.indices; - this._minimumHeight = options.minimumHeight; - this._maximumHeight = options.maximumHeight; - this._boundingSphere = options.boundingSphere; - this._orientedBoundingBox = options.orientedBoundingBox; - this._horizonOcclusionPoint = options.horizonOcclusionPoint; - this._credits = options.credits; - - var vertexCount = this._quantizedVertices.length / 3; - var uValues = this._uValues = this._quantizedVertices.subarray(0, vertexCount); - var vValues = this._vValues = this._quantizedVertices.subarray(vertexCount, 2 * vertexCount); - this._heightValues = this._quantizedVertices.subarray(2 * vertexCount, 3 * vertexCount); - // We don't assume that we can count on the edge vertices being sorted by u or v. - function sortByV(a, b) { - return vValues[a] - vValues[b]; - } + index *= this.getStride(); - function sortByU(a, b) { - return uValues[a] - uValues[b]; + if (this.quantization === TerrainQuantization.BITS12) { + return AttributeCompression.decompressTextureCoordinates(buffer[index + 2], result); } - this._westIndices = sortIndicesIfNecessary(options.westIndices, sortByV, vertexCount); - this._southIndices = sortIndicesIfNecessary(options.southIndices, sortByU, vertexCount); - this._eastIndices = sortIndicesIfNecessary(options.eastIndices, sortByV, vertexCount); - this._northIndices = sortIndicesIfNecessary(options.northIndices, sortByU, vertexCount); - - this._westSkirtHeight = options.westSkirtHeight; - this._southSkirtHeight = options.southSkirtHeight; - this._eastSkirtHeight = options.eastSkirtHeight; - this._northSkirtHeight = options.northSkirtHeight; - - this._childTileMask = defaultValue(options.childTileMask, 15); - - this._createdByUpsampling = defaultValue(options.createdByUpsampling, false); - this._waterMask = options.waterMask; + return Cartesian2.fromElements(buffer[index + 4], buffer[index + 5], result); + }; - this._mesh = undefined; - } + TerrainEncoding.prototype.decodeHeight = function(buffer, index) { + index *= this.getStride(); - defineProperties(QuantizedMeshTerrainData.prototype, { - /** - * An array of credits for this tile. - * @memberof QuantizedMeshTerrainData.prototype - * @type {Credit[]} - */ - credits : { - get : function() { - return this._credits; - } - }, - /** - * The water mask included in this terrain data, if any. A water mask is a rectangular - * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. - * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. - * @memberof QuantizedMeshTerrainData.prototype - * @type {Uint8Array|Image|Canvas} - */ - waterMask : { - get : function() { - return this._waterMask; - } + if (this.quantization === TerrainQuantization.BITS12) { + var zh = AttributeCompression.decompressTextureCoordinates(buffer[index + 1], cartesian2Scratch); + return zh.y * (this.maximumHeight - this.minimumHeight) + this.minimumHeight; } - }); - var arrayScratch = []; + return buffer[index + 3]; + }; - function sortIndicesIfNecessary(indices, sortFunction, vertexCount) { - arrayScratch.length = indices.length; + TerrainEncoding.prototype.getOctEncodedNormal = function(buffer, index, result) { + var stride = this.getStride(); + index = (index + 1) * stride - 1; - var needsSort = false; - for (var i = 0, len = indices.length; i < len; ++i) { - arrayScratch[i] = indices[i]; - needsSort = needsSort || (i > 0 && sortFunction(indices[i - 1], indices[i]) > 0); - } + var temp = buffer[index] / 256.0; + var x = Math.floor(temp); + var y = (temp - x) * 256.0; - if (needsSort) { - arrayScratch.sort(sortFunction); - return IndexDatatype.createTypedArray(vertexCount, arrayScratch); - } - return indices; - } + return Cartesian2.fromElements(x, y, result); + }; - var createMeshTaskProcessor = new TaskProcessor('createVerticesFromQuantizedTerrainMesh'); + TerrainEncoding.prototype.getStride = function() { + var vertexStride; - /** - * Creates a {@link TerrainMesh} from this terrain data. - * - * @private - * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many - * asynchronous mesh creations are already in progress and the operation should - * be retried later. - */ - QuantizedMeshTerrainData.prototype.createMesh = function(tilingScheme, x, y, level, exaggeration) { - if (!defined(tilingScheme)) { - throw new DeveloperError('tilingScheme is required.'); - } - if (!defined(x)) { - throw new DeveloperError('x is required.'); - } - if (!defined(y)) { - throw new DeveloperError('y is required.'); - } - if (!defined(level)) { - throw new DeveloperError('level is required.'); + switch (this.quantization) { + case TerrainQuantization.BITS12: + vertexStride = 3; + break; + default: + vertexStride = 6; } - - var ellipsoid = tilingScheme.ellipsoid; - var rectangle = tilingScheme.tileXYToRectangle(x, y, level); - exaggeration = defaultValue(exaggeration, 1.0); - - var verticesPromise = createMeshTaskProcessor.scheduleTask({ - minimumHeight : this._minimumHeight, - maximumHeight : this._maximumHeight, - quantizedVertices : this._quantizedVertices, - octEncodedNormals : this._encodedNormals, - includeWebMercatorT : true, - indices : this._indices, - westIndices : this._westIndices, - southIndices : this._southIndices, - eastIndices : this._eastIndices, - northIndices : this._northIndices, - westSkirtHeight : this._westSkirtHeight, - southSkirtHeight : this._southSkirtHeight, - eastSkirtHeight : this._eastSkirtHeight, - northSkirtHeight : this._northSkirtHeight, - rectangle : rectangle, - relativeToCenter : this._boundingSphere.center, - ellipsoid : ellipsoid, - exaggeration : exaggeration - }); - if (!defined(verticesPromise)) { - // Postponed - return undefined; + if (this.hasWebMercatorT) { + ++vertexStride; } - var that = this; - return when(verticesPromise, function(result) { - var vertexCount = that._quantizedVertices.length / 3; - vertexCount += that._westIndices.length + that._southIndices.length + that._eastIndices.length + that._northIndices.length; - var indicesTypedArray = IndexDatatype.createTypedArray(vertexCount, result.indices); - - var vertices = new Float32Array(result.vertices); - var rtc = result.center; - var minimumHeight = result.minimumHeight; - var maximumHeight = result.maximumHeight; - var boundingSphere = defaultValue(result.boundingSphere, that._boundingSphere); - var obb = defaultValue(result.orientedBoundingBox, that._orientedBoundingBox); - var occlusionPoint = that._horizonOcclusionPoint; - var stride = result.vertexStride; - var terrainEncoding = TerrainEncoding.clone(result.encoding); - - that._skirtIndex = result.skirtIndex; - that._vertexCountWithoutSkirts = that._quantizedVertices.length / 3; - - that._mesh = new TerrainMesh( - rtc, - vertices, - indicesTypedArray, - minimumHeight, - maximumHeight, - boundingSphere, - occlusionPoint, - stride, - obb, - terrainEncoding, - exaggeration); - - // Free memory received from server after mesh is created. - that._quantizedVertices = undefined; - that._encodedNormals = undefined; - that._indices = undefined; - - that._uValues = undefined; - that._vValues = undefined; - that._heightValues = undefined; - - that._westIndices = undefined; - that._southIndices = undefined; - that._eastIndices = undefined; - that._northIndices = undefined; - - return that._mesh; - }); - }; - - var upsampleTaskProcessor = new TaskProcessor('upsampleQuantizedTerrainMesh'); - - /** - * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the - * vertices in this instance, interpolated if necessary. - * - * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<QuantizedMeshTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, - * or undefined if too many asynchronous upsample operations are in progress and the request has been - * deferred. - */ - QuantizedMeshTerrainData.prototype.upsample = function(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) { - if (!defined(tilingScheme)) { - throw new DeveloperError('tilingScheme is required.'); - } - if (!defined(thisX)) { - throw new DeveloperError('thisX is required.'); - } - if (!defined(thisY)) { - throw new DeveloperError('thisY is required.'); - } - if (!defined(thisLevel)) { - throw new DeveloperError('thisLevel is required.'); - } - if (!defined(descendantX)) { - throw new DeveloperError('descendantX is required.'); - } - if (!defined(descendantY)) { - throw new DeveloperError('descendantY is required.'); - } - if (!defined(descendantLevel)) { - throw new DeveloperError('descendantLevel is required.'); - } - var levelDifference = descendantLevel - thisLevel; - if (levelDifference > 1) { - throw new DeveloperError('Upsampling through more than one level at a time is not currently supported.'); - } - - var mesh = this._mesh; - if (!defined(this._mesh)) { - return undefined; + if (this.hasVertexNormals) { + ++vertexStride; } - var isEastChild = thisX * 2 !== descendantX; - var isNorthChild = thisY * 2 === descendantY; - - var ellipsoid = tilingScheme.ellipsoid; - var childRectangle = tilingScheme.tileXYToRectangle(descendantX, descendantY, descendantLevel); - - var upsamplePromise = upsampleTaskProcessor.scheduleTask({ - vertices : mesh.vertices, - vertexCountWithoutSkirts : this._vertexCountWithoutSkirts, - indices : mesh.indices, - skirtIndex : this._skirtIndex, - encoding : mesh.encoding, - minimumHeight : this._minimumHeight, - maximumHeight : this._maximumHeight, - isEastChild : isEastChild, - isNorthChild : isNorthChild, - childRectangle : childRectangle, - ellipsoid : ellipsoid, - exaggeration : mesh.exaggeration - }); + return vertexStride; + }; - if (!defined(upsamplePromise)) { - // Postponed - return undefined; - } + var attributesNone = { + position3DAndHeight : 0, + textureCoordAndEncodedNormals : 1 + }; + var attributes = { + compressed0 : 0, + compressed1 : 1 + }; - var shortestSkirt = Math.min(this._westSkirtHeight, this._eastSkirtHeight); - shortestSkirt = Math.min(shortestSkirt, this._southSkirtHeight); - shortestSkirt = Math.min(shortestSkirt, this._northSkirtHeight); + TerrainEncoding.prototype.getAttributes = function(buffer) { + var datatype = ComponentDatatype.FLOAT; + var sizeInBytes = ComponentDatatype.getSizeInBytes(datatype); + var stride; - var westSkirtHeight = isEastChild ? (shortestSkirt * 0.5) : this._westSkirtHeight; - var southSkirtHeight = isNorthChild ? (shortestSkirt * 0.5) : this._southSkirtHeight; - var eastSkirtHeight = isEastChild ? this._eastSkirtHeight : (shortestSkirt * 0.5); - var northSkirtHeight = isNorthChild ? this._northSkirtHeight : (shortestSkirt * 0.5); + if (this.quantization === TerrainQuantization.NONE) { + var position3DAndHeightLength = 4; + var numTexCoordComponents = 2; - return when(upsamplePromise, function(result) { - var quantizedVertices = new Uint16Array(result.vertices); - var indicesTypedArray = IndexDatatype.createTypedArray(quantizedVertices.length / 3, result.indices); - var encodedNormals; - if (defined(result.encodedNormals)) { - encodedNormals = new Uint8Array(result.encodedNormals); + if (this.hasWebMercatorT) { + ++numTexCoordComponents; } - return new QuantizedMeshTerrainData({ - quantizedVertices : quantizedVertices, - indices : indicesTypedArray, - encodedNormals : encodedNormals, - minimumHeight : result.minimumHeight, - maximumHeight : result.maximumHeight, - boundingSphere : BoundingSphere.clone(result.boundingSphere), - orientedBoundingBox : OrientedBoundingBox.clone(result.orientedBoundingBox), - horizonOcclusionPoint : Cartesian3.clone(result.horizonOcclusionPoint), - westIndices : result.westIndices, - southIndices : result.southIndices, - eastIndices : result.eastIndices, - northIndices : result.northIndices, - westSkirtHeight : westSkirtHeight, - southSkirtHeight : southSkirtHeight, - eastSkirtHeight : eastSkirtHeight, - northSkirtHeight : northSkirtHeight, - childTileMask : 0, - createdByUpsampling : true - }); - }); - }; - - var maxShort = 32767; - var barycentricCoordinateScratch = new Cartesian3(); + if (this.hasVertexNormals) { + ++numTexCoordComponents; + } - /** - * Computes the terrain height at a specified longitude and latitude. - * - * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. The position is clamped to - * the rectangle, so expect incorrect results for positions far outside the rectangle. - */ - QuantizedMeshTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) { - var u = CesiumMath.clamp((longitude - rectangle.west) / rectangle.width, 0.0, 1.0); - u *= maxShort; - var v = CesiumMath.clamp((latitude - rectangle.south) / rectangle.height, 0.0, 1.0); - v *= maxShort; + stride = (position3DAndHeightLength + numTexCoordComponents) * sizeInBytes; - if (!defined(this._mesh)) { - return interpolateHeight(this, u, v); + return [{ + index : attributesNone.position3DAndHeight, + vertexBuffer : buffer, + componentDatatype : datatype, + componentsPerAttribute : position3DAndHeightLength, + offsetInBytes : 0, + strideInBytes : stride + }, { + index : attributesNone.textureCoordAndEncodedNormals, + vertexBuffer : buffer, + componentDatatype : datatype, + componentsPerAttribute : numTexCoordComponents, + offsetInBytes : position3DAndHeightLength * sizeInBytes, + strideInBytes : stride + }]; } - return interpolateMeshHeight(this, u, v); - }; - - var texCoordScratch0 = new Cartesian2(); - var texCoordScratch1 = new Cartesian2(); - var texCoordScratch2 = new Cartesian2(); - - function interpolateMeshHeight(terrainData, u, v) { - var mesh = terrainData._mesh; - var vertices = mesh.vertices; - var encoding = mesh.encoding; - var indices = mesh.indices; - - for (var i = 0, len = indices.length; i < len; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - - var uv0 = encoding.decodeTextureCoordinates(vertices, i0, texCoordScratch0); - var uv1 = encoding.decodeTextureCoordinates(vertices, i1, texCoordScratch1); - var uv2 = encoding.decodeTextureCoordinates(vertices, i2, texCoordScratch2); + var numCompressed0 = 3; + var numCompressed1 = 0; - var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, barycentricCoordinateScratch); - if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { - var h0 = encoding.decodeHeight(vertices, i0); - var h1 = encoding.decodeHeight(vertices, i1); - var h2 = encoding.decodeHeight(vertices, i2); - return barycentric.x * h0 + barycentric.y * h1 + barycentric.z * h2; - } + if (this.hasWebMercatorT || this.hasVertexNormals) { + ++numCompressed0; } - // Position does not lie in any triangle in this mesh. - return undefined; - } - - function interpolateHeight(terrainData, u, v) { - var uBuffer = terrainData._uValues; - var vBuffer = terrainData._vValues; - var heightBuffer = terrainData._heightValues; - - var indices = terrainData._indices; - for (var i = 0, len = indices.length; i < len; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - - var u0 = uBuffer[i0]; - var u1 = uBuffer[i1]; - var u2 = uBuffer[i2]; + if (this.hasWebMercatorT && this.hasVertexNormals) { + ++numCompressed1; - var v0 = vBuffer[i0]; - var v1 = vBuffer[i1]; - var v2 = vBuffer[i2]; + stride = (numCompressed0 + numCompressed1) * sizeInBytes; - var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, u0, v0, u1, v1, u2, v2, barycentricCoordinateScratch); - if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { - var quantizedHeight = barycentric.x * heightBuffer[i0] + - barycentric.y * heightBuffer[i1] + - barycentric.z * heightBuffer[i2]; - return CesiumMath.lerp(terrainData._minimumHeight, terrainData._maximumHeight, quantizedHeight / maxShort); - } + return [{ + index : attributes.compressed0, + vertexBuffer : buffer, + componentDatatype : datatype, + componentsPerAttribute : numCompressed0, + offsetInBytes : 0, + strideInBytes : stride + }, { + index : attributes.compressed1, + vertexBuffer : buffer, + componentDatatype : datatype, + componentsPerAttribute : numCompressed1, + offsetInBytes : numCompressed0 * sizeInBytes, + strideInBytes : stride + }]; } + return [{ + index : attributes.compressed0, + vertexBuffer : buffer, + componentDatatype : datatype, + componentsPerAttribute : numCompressed0 + }]; + }; - // Position does not lie in any triangle in this mesh. - return undefined; - } - - /** - * Determines if a given child tile is available, based on the - * {@link HeightmapTerrainData.childTileMask}. The given child tile coordinates are assumed - * to be one of the four children of this tile. If non-child tile coordinates are - * given, the availability of the southeast child tile is returned. - * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. - */ - QuantizedMeshTerrainData.prototype.isChildAvailable = function(thisX, thisY, childX, childY) { - if (!defined(thisX)) { - throw new DeveloperError('thisX is required.'); - } - if (!defined(thisY)) { - throw new DeveloperError('thisY is required.'); - } - if (!defined(childX)) { - throw new DeveloperError('childX is required.'); - } - if (!defined(childY)) { - throw new DeveloperError('childY is required.'); - } - - var bitNumber = 2; // northwest child - if (childX !== thisX * 2) { - ++bitNumber; // east child - } - if (childY !== thisY * 2) { - bitNumber -= 2; // south child + TerrainEncoding.prototype.getAttributeLocations = function() { + if (this.quantization === TerrainQuantization.NONE) { + return attributesNone; } - - return (this._childTileMask & (1 << bitNumber)) !== 0; + return attributes; }; - /** - * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution - * terrain data. If this value is false, the data was obtained from some other source, such - * as by downloading it from a remote server. This method should return true for instances - * returned from a call to {@link HeightmapTerrainData#upsample}. - * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. - */ - QuantizedMeshTerrainData.prototype.wasCreatedByUpsampling = function() { - return this._createdByUpsampling; + TerrainEncoding.clone = function(encoding, result) { + if (!defined(result)) { + result = new TerrainEncoding(); + } + + result.quantization = encoding.quantization; + result.minimumHeight = encoding.minimumHeight; + result.maximumHeight = encoding.maximumHeight; + result.center = Cartesian3.clone(encoding.center); + result.toScaledENU = Matrix4.clone(encoding.toScaledENU); + result.fromScaledENU = Matrix4.clone(encoding.fromScaledENU); + result.matrix = Matrix4.clone(encoding.matrix); + result.hasVertexNormals = encoding.hasVertexNormals; + result.hasWebMercatorT = encoding.hasWebMercatorT; + return result; }; - return QuantizedMeshTerrainData; + return TerrainEncoding; }); -define('Core/TileAvailability',[ - './binarySearch', +define('Core/WebMercatorProjection',[ + './Cartesian3', './Cartographic', + './defaultValue', './defined', './defineProperties', './DeveloperError', - './Rectangle' + './Ellipsoid', + './Math' ], function( - binarySearch, + Cartesian3, Cartographic, + defaultValue, defined, defineProperties, DeveloperError, - Rectangle) { + Ellipsoid, + CesiumMath) { 'use strict'; /** - * Reports the availability of tiles in a {@link TilingScheme}. + * The map projection used by Google Maps, Bing Maps, and most of ArcGIS Online, EPSG:3857. This + * projection use longitude and latitude expressed with the WGS84 and transforms them to Mercator using + * the spherical (rather than ellipsoidal) equations. * - * @alias TileAvailability + * @alias WebMercatorProjection * @constructor * - * @param {TilingScheme} tilingScheme The tiling scheme in which to report availability. - * @param {Number} maximumLevel The maximum tile level that is potentially available. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid. + * + * @see GeographicProjection */ - function TileAvailability(tilingScheme, maximumLevel) { - this._tilingScheme = tilingScheme; - this._maximumLevel = maximumLevel; + function WebMercatorProjection(ellipsoid) { + this._ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + this._semimajorAxis = this._ellipsoid.maximumRadius; + this._oneOverSemimajorAxis = 1.0 / this._semimajorAxis; + } - this._rootNodes = []; - for (var y = 0; y < tilingScheme.getNumberOfYTilesAtLevel(); ++y) { - for (var x = 0; x < tilingScheme.getNumberOfXTilesAtLevel(); ++x) { - this._rootNodes.push(new QuadtreeNode(tilingScheme, undefined, 0, x, y)); + defineProperties(WebMercatorProjection.prototype, { + /** + * Gets the {@link Ellipsoid}. + * + * @memberof WebMercatorProjection.prototype + * + * @type {Ellipsoid} + * @readonly + */ + ellipsoid : { + get : function() { + return this._ellipsoid; } } - } - - var rectangleScratch = new Rectangle(); + }); /** - * Marks a rectangular range of tiles in a particular level as being available. For best performance, - * add your ranges in order of increasing level. + * Converts a Mercator angle, in the range -PI to PI, to a geodetic latitude + * in the range -PI/2 to PI/2. * - * @param {Number} level The level. - * @param {Number} startX The X coordinate of the first available tiles at the level. - * @param {Number} startY The Y coordinate of the first available tiles at the level. - * @param {Number} endX The X coordinate of the last available tiles at the level. - * @param {Number} endY The Y coordinate of the last available tiles at the level. + * @param {Number} mercatorAngle The angle to convert. + * @returns {Number} The geodetic latitude in radians. */ - TileAvailability.prototype.addAvailableTileRange = function(level, startX, startY, endX, endY) { - var tilingScheme = this._tilingScheme; - - tilingScheme.tileXYToRectangle(startX, startY, level, rectangleScratch); - var west = rectangleScratch.west; - var north = rectangleScratch.north; - - tilingScheme.tileXYToRectangle(endX, endY, level, rectangleScratch); - var east = rectangleScratch.east; - var south = rectangleScratch.south; - - var rectangleWithLevel = new RectangleWithLevel(level, west, south, east, north); - - for (var i = 0; i < this._rootNodes.length; ++i) { - var rootNode = this._rootNodes[i]; - if (rectanglesOverlap(rootNode.extent, rectangleWithLevel)) { - putRectangleInQuadtree(this._maximumLevel, rootNode, rectangleWithLevel); - } - } + WebMercatorProjection.mercatorAngleToGeodeticLatitude = function(mercatorAngle) { + return CesiumMath.PI_OVER_TWO - (2.0 * Math.atan(Math.exp(-mercatorAngle))); }; /** - * Determines the level of the most detailed tile covering the position. This function - * usually completes in time logarithmic to the number of rectangles added with - * {@link TileAvailability#addAvailableTileRange}. + * Converts a geodetic latitude in radians, in the range -PI/2 to PI/2, to a Mercator + * angle in the range -PI to PI. * - * @param {Cartographic} position The position for which to determine the maximum available level. The height component is ignored. - * @return {Number} The level of the most detailed tile covering the position. - * @throws {DeveloperError} If position is outside any tile according to the tiling scheme. + * @param {Number} latitude The geodetic latitude in radians. + * @returns {Number} The Mercator angle. */ - TileAvailability.prototype.computeMaximumLevelAtPosition = function(position) { - // Find the root node that contains this position. - var node; - for (var nodeIndex = 0; nodeIndex < this._rootNodes.length; ++nodeIndex) { - var rootNode = this._rootNodes[nodeIndex]; - if (rectangleContainsPosition(rootNode.extent, position)) { - node = rootNode; - break; - } - } - - if (!defined(node)) { - throw new DeveloperError('The specified position does not exist in any root node of the tiling scheme.'); + WebMercatorProjection.geodeticLatitudeToMercatorAngle = function(latitude) { + // Clamp the latitude coordinate to the valid Mercator bounds. + if (latitude > WebMercatorProjection.MaximumLatitude) { + latitude = WebMercatorProjection.MaximumLatitude; + } else if (latitude < -WebMercatorProjection.MaximumLatitude) { + latitude = -WebMercatorProjection.MaximumLatitude; } - - return findMaxLevelFromNode(undefined, node, position); + var sinLatitude = Math.sin(latitude); + return 0.5 * Math.log((1.0 + sinLatitude) / (1.0 - sinLatitude)); }; - var rectanglesScratch = []; - var remainingToCoverByLevelScratch = []; - var westScratch = new Rectangle(); - var eastScratch = new Rectangle(); + /** + * The maximum latitude (both North and South) supported by a Web Mercator + * (EPSG:3857) projection. Technically, the Mercator projection is defined + * for any latitude up to (but not including) 90 degrees, but it makes sense + * to cut it off sooner because it grows exponentially with increasing latitude. + * The logic behind this particular cutoff value, which is the one used by + * Google Maps, Bing Maps, and Esri, is that it makes the projection + * square. That is, the rectangle is equal in the X and Y directions. + * + * The constant value is computed by calling: + * WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI) + * + * @type {Number} + */ + WebMercatorProjection.MaximumLatitude = WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI); /** - * Finds the most detailed level that is available _everywhere_ within a given rectangle. More detailed - * tiles may be available in parts of the rectangle, but not the whole thing. The return value of this - * function may be safely passed to {@link sampleTerrain} for any position within the rectangle. This function - * usually completes in time logarithmic to the number of rectangles added with - * {@link TileAvailability#addAvailableTileRange}. + * Converts geodetic ellipsoid coordinates, in radians, to the equivalent Web Mercator + * X, Y, Z coordinates expressed in meters and returned in a {@link Cartesian3}. The height + * is copied unmodified to the Z coordinate. * - * @param {Rectangle} rectangle The rectangle. - * @return {Number} The best available level for the entire rectangle. + * @param {Cartographic} cartographic The cartographic coordinates in radians. + * @param {Cartesian3} [result] The instance to which to copy the result, or undefined if a + * new instance should be created. + * @returns {Cartesian3} The equivalent web mercator X, Y, Z coordinates, in meters. */ - TileAvailability.prototype.computeBestAvailableLevelOverRectangle = function(rectangle) { - var rectangles = rectanglesScratch; - rectangles.length = 0; + WebMercatorProjection.prototype.project = function(cartographic, result) { + var semimajorAxis = this._semimajorAxis; + var x = cartographic.longitude * semimajorAxis; + var y = WebMercatorProjection.geodeticLatitudeToMercatorAngle(cartographic.latitude) * semimajorAxis; + var z = cartographic.height; - if (rectangle.east < rectangle.west) { - // Rectangle crosses the IDL, make it two rectangles. - rectangles.push(Rectangle.fromRadians(-Math.PI, rectangle.south, rectangle.east, rectangle.north, westScratch)); - rectangles.push(Rectangle.fromRadians(rectangle.west, rectangle.south, Math.PI, rectangle.north, eastScratch)); - } else { - rectangles.push(rectangle); + if (!defined(result)) { + return new Cartesian3(x, y, z); } - var remainingToCoverByLevel = remainingToCoverByLevelScratch; - remainingToCoverByLevel.length = 0; + result.x = x; + result.y = y; + result.z = z; + return result; + }; - var i; - for (i = 0; i < this._rootNodes.length; ++i) { - updateCoverageWithNode(remainingToCoverByLevel, this._rootNodes[i], rectangles); + /** + * Converts Web Mercator X, Y coordinates, expressed in meters, to a {@link Cartographic} + * containing geodetic ellipsoid coordinates. The Z coordinate is copied unmodified to the + * height. + * + * @param {Cartesian3} cartesian The web mercator Cartesian position to unrproject with height (z) in meters. + * @param {Cartographic} [result] The instance to which to copy the result, or undefined if a + * new instance should be created. + * @returns {Cartographic} The equivalent cartographic coordinates. + */ + WebMercatorProjection.prototype.unproject = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required'); } + + var oneOverEarthSemimajorAxis = this._oneOverSemimajorAxis; + var longitude = cartesian.x * oneOverEarthSemimajorAxis; + var latitude = WebMercatorProjection.mercatorAngleToGeodeticLatitude(cartesian.y * oneOverEarthSemimajorAxis); + var height = cartesian.z; - for (i = remainingToCoverByLevel.length - 1; i >= 0; --i) { - if (defined(remainingToCoverByLevel[i]) && remainingToCoverByLevel[i].length === 0) { - return i; - } + if (!defined(result)) { + return new Cartographic(longitude, latitude, height); } - return 0; + result.longitude = longitude; + result.latitude = latitude; + result.height = height; + return result; }; - var cartographicScratch = new Cartographic(); + return WebMercatorProjection; +}); + +define('Core/HeightmapTessellator',[ + './AxisAlignedBoundingBox', + './BoundingSphere', + './Cartesian2', + './Cartesian3', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './EllipsoidalOccluder', + './freezeObject', + './Math', + './Matrix4', + './OrientedBoundingBox', + './Rectangle', + './TerrainEncoding', + './Transforms', + './WebMercatorProjection' + ], function( + AxisAlignedBoundingBox, + BoundingSphere, + Cartesian2, + Cartesian3, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + EllipsoidalOccluder, + freezeObject, + CesiumMath, + Matrix4, + OrientedBoundingBox, + Rectangle, + TerrainEncoding, + Transforms, + WebMercatorProjection) { + 'use strict'; /** - * Determines if a particular tile is available. - * @param {Number} level The tile level to check. - * @param {Number} x The X coordinate of the tile to check. - * @param {Number} y The Y coordinate of the tile to check. - * @return {Boolean} True if the tile is available; otherwise, false. + * Contains functions to create a mesh from a heightmap image. + * + * @exports HeightmapTessellator + * + * @private */ - TileAvailability.prototype.isTileAvailable = function(level, x, y) { - // Get the center of the tile and find the maximum level at that position. - // Because availability is by tile, if the level is available at that point, it - // is sure to be available for the whole tile. We assume that if a tile at level n exists, - // then all its parent tiles back to level 0 exist too. This isn't really enforced - // anywhere, but Cesium would never load a tile for which this is not true. - var rectangle = this._tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); - Rectangle.center(rectangle, cartographicScratch); - return this.computeMaximumLevelAtPosition(cartographicScratch) >= level; - }; + var HeightmapTessellator = {}; /** - * Computes a bit mask indicating which of a tile's four children exist. - * If a child's bit is set, a tile is available for that child. If it is cleared, - * the tile is not available. The bit values are as follows: - * <table> - * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> - * <tr><td>0</td><td>1</td><td>Southwest</td></tr> - * <tr><td>1</td><td>2</td><td>Southeast</td></tr> - * <tr><td>2</td><td>4</td><td>Northwest</td></tr> - * <tr><td>3</td><td>8</td><td>Northeast</td></tr> - * </table> + * The default structure of a heightmap, as given to {@link HeightmapTessellator.computeVertices}. * - * @param {Number} level The level of the parent tile. - * @param {Number} x The X coordinate of the parent tile. - * @param {Number} y The Y coordinate of the parent tile. - * @return {Number} The bit mask indicating child availability. + * @constant */ - TileAvailability.prototype.computeChildMaskForTile = function(level, x, y) { - var childLevel = level + 1; - if (childLevel >= this._maximumLevel) { - return 0; - } - - var mask = 0; - - mask |= this.isTileAvailable(childLevel, 2 * x, 2 * y + 1) ? 1 : 0; - mask |= this.isTileAvailable(childLevel, 2 * x + 1, 2 * y + 1) ? 2 : 0; - mask |= this.isTileAvailable(childLevel, 2 * x, 2 * y) ? 4 : 0; - mask |= this.isTileAvailable(childLevel, 2 * x + 1, 2 * y) ? 8 : 0; - - return mask; - }; - - function QuadtreeNode(tilingScheme, parent, level, x, y) { - this.tilingScheme = tilingScheme; - this.parent = parent; - this.level = level; - this.x = x; - this.y = y; - this.extent = tilingScheme.tileXYToRectangle(x, y, level); - - this.rectangles = []; - this._sw = undefined; - this._se = undefined; - this._nw = undefined; - this._ne = undefined; - } + HeightmapTessellator.DEFAULT_STRUCTURE = freezeObject({ + heightScale : 1.0, + heightOffset : 0.0, + elementsPerHeight : 1, + stride : 1, + elementMultiplier : 256.0, + isBigEndian : false + }); - defineProperties(QuadtreeNode.prototype, { - nw: { - get: function() { - if (!this._nw) { - this._nw = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2, this.y * 2); - } - return this._nw; - } - }, + var cartesian3Scratch = new Cartesian3(); + var matrix4Scratch = new Matrix4(); + var minimumScratch = new Cartesian3(); + var maximumScratch = new Cartesian3(); - ne: { - get: function() { - if (!this._ne) { - this._ne = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2 + 1, this.y * 2); - } - return this._ne; - } - }, + /** + * Fills an array of vertices from a heightmap image. + * + * @param {Object} options Object with the following properties: + * @param {TypedArray} options.heightmap The heightmap to tessellate. + * @param {Number} options.width The width of the heightmap, in height samples. + * @param {Number} options.height The height of the heightmap, in height samples. + * @param {Number} options.skirtHeight The height of skirts to drape at the edges of the heightmap. + * @param {Rectangle} options.nativeRectangle A rectangle in the native coordinates of the heightmap's projection. For + * a heightmap with a geographic projection, this is degrees. For the web mercator + * projection, this is meters. + * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {Rectangle} [options.rectangle] The rectangle covered by the heightmap, in geodetic coordinates with north, south, east and + * west properties in radians. Either rectangle or nativeRectangle must be provided. If both + * are provided, they're assumed to be consistent. + * @param {Boolean} [options.isGeographic=true] True if the heightmap uses a {@link GeographicProjection}, or false if it uses + * a {@link WebMercatorProjection}. + * @param {Cartesian3} [options.relativeToCenter=Cartesian3.ZERO] The positions will be computed as <code>Cartesian3.subtract(worldPosition, relativeToCenter)</code>. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to which the heightmap applies. + * @param {Object} [options.structure] An object describing the structure of the height data. + * @param {Number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain + * the height above the heightOffset, in meters. The heightOffset is added to the resulting + * height after multiplying by the scale. + * @param {Number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final + * height in meters. The offset is added after the height sample is multiplied by the + * heightScale. + * @param {Number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height + * sample. This is usually 1, indicating that each element is a separate height sample. If + * it is greater than 1, that number of elements together form the height sample, which is + * computed according to the structure.elementMultiplier and structure.isBigEndian properties. + * @param {Number} [options.structure.stride=1] The number of elements to skip to get from the first element of + * one height to the first element of the next height. + * @param {Number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the + * stride property is greater than 1. For example, if the stride is 4 and the strideMultiplier + * is 256, the height is computed as follows: + * `height = buffer[index] + buffer[index + 1] * 256 + buffer[index + 2] * 256 * 256 + buffer[index + 3] * 256 * 256 * 256` + * This is assuming that the isBigEndian property is false. If it is true, the order of the + * elements is reversed. + * @param {Number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower + * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height + * buffer is a `Uint16Array`, this value should be 0 because a `Uint16Array` cannot store negative numbers. If this parameter is + * not specified, no minimum value is enforced. + * @param {Number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher + * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height + * buffer is a `Uint16Array`, this value should be `256 * 256 - 1` or 65535 because a `Uint16Array` cannot store numbers larger + * than 65535. If this parameter is not specified, no maximum value is enforced. + * @param {Boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the + * stride property is greater than 1. If this property is false, the first element is the + * low-order element. If it is true, the first element is the high-order element. + * + * @example + * var width = 5; + * var height = 5; + * var statistics = Cesium.HeightmapTessellator.computeVertices({ + * heightmap : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], + * width : width, + * height : height, + * skirtHeight : 0.0, + * nativeRectangle : { + * west : 10.0, + * east : 20.0, + * south : 30.0, + * north : 40.0 + * } + * }); + * + * var encoding = statistics.encoding; + * var position = encoding.decodePosition(statistics.vertices, index * encoding.getStride()); + */ + HeightmapTessellator.computeVertices = function(options) { + if (!defined(options) || !defined(options.heightmap)) { + throw new DeveloperError('options.heightmap is required.'); + } + if (!defined(options.width) || !defined(options.height)) { + throw new DeveloperError('options.width and options.height are required.'); + } + if (!defined(options.nativeRectangle)) { + throw new DeveloperError('options.nativeRectangle is required.'); + } + if (!defined(options.skirtHeight)) { + throw new DeveloperError('options.skirtHeight is required.'); + } + + // This function tends to be a performance hotspot for terrain rendering, + // so it employs a lot of inlining and unrolling as an optimization. + // In particular, the functionality of Ellipsoid.cartographicToCartesian + // is inlined. - sw: { - get: function() { - if (!this._sw) { - this._sw = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2, this.y * 2 + 1); - } - return this._sw; - } - }, + var cos = Math.cos; + var sin = Math.sin; + var sqrt = Math.sqrt; + var atan = Math.atan; + var exp = Math.exp; + var piOverTwo = CesiumMath.PI_OVER_TWO; + var toRadians = CesiumMath.toRadians; - se: { - get: function() { - if (!this._se) { - this._se = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2 + 1, this.y * 2 + 1); - } - return this._se; - } - } - }); + var heightmap = options.heightmap; + var width = options.width; + var height = options.height; + var skirtHeight = options.skirtHeight; - function RectangleWithLevel(level, west, south, east, north) { - this.level = level; - this.west = west; - this.south = south; - this.east = east; - this.north = north; - } + var isGeographic = defaultValue(options.isGeographic, true); + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - function rectanglesOverlap(rectangle1, rectangle2) { - var west = Math.max(rectangle1.west, rectangle2.west); - var south = Math.max(rectangle1.south, rectangle2.south); - var east = Math.min(rectangle1.east, rectangle2.east); - var north = Math.min(rectangle1.north, rectangle2.north); - return south < north && west < east; - } + var oneOverGlobeSemimajorAxis = 1.0 / ellipsoid.maximumRadius; - function putRectangleInQuadtree(maxDepth, node, rectangle) { - while (node.level < maxDepth) { - if (rectangleFullyContainsRectangle(node.nw.extent, rectangle)) { - node = node.nw; - } else if (rectangleFullyContainsRectangle(node.ne.extent, rectangle)) { - node = node.ne; - } else if (rectangleFullyContainsRectangle(node.sw.extent, rectangle)) { - node = node.sw; - } else if (rectangleFullyContainsRectangle(node.se.extent, rectangle)) { - node = node.se; + var nativeRectangle = options.nativeRectangle; + + var geographicWest; + var geographicSouth; + var geographicEast; + var geographicNorth; + + var rectangle = options.rectangle; + if (!defined(rectangle)) { + if (isGeographic) { + geographicWest = toRadians(nativeRectangle.west); + geographicSouth = toRadians(nativeRectangle.south); + geographicEast = toRadians(nativeRectangle.east); + geographicNorth = toRadians(nativeRectangle.north); } else { - break; + geographicWest = nativeRectangle.west * oneOverGlobeSemimajorAxis; + geographicSouth = piOverTwo - (2.0 * atan(exp(-nativeRectangle.south * oneOverGlobeSemimajorAxis))); + geographicEast = nativeRectangle.east * oneOverGlobeSemimajorAxis; + geographicNorth = piOverTwo - (2.0 * atan(exp(-nativeRectangle.north * oneOverGlobeSemimajorAxis))); } - } - - if (node.rectangles.length === 0 || node.rectangles[node.rectangles.length - 1].level <= rectangle.level) { - node.rectangles.push(rectangle); } else { - // Maintain ordering by level when inserting. - var index = binarySearch(node.rectangles, rectangle.level, rectangleLevelComparator); - if (index <= 0) { - index = ~index; - } - node.rectangles.splice(index, 0, rectangle); + geographicWest = rectangle.west; + geographicSouth = rectangle.south; + geographicEast = rectangle.east; + geographicNorth = rectangle.north; } - } - - function rectangleLevelComparator(a, b) { - return a.level - b; - } - function rectangleFullyContainsRectangle(potentialContainer, rectangleToTest) { - return rectangleToTest.west >= potentialContainer.west && - rectangleToTest.east <= potentialContainer.east && - rectangleToTest.south >= potentialContainer.south && - rectangleToTest.north <= potentialContainer.north; - } + var relativeToCenter = options.relativeToCenter; + var hasRelativeToCenter = defined(relativeToCenter); + relativeToCenter = hasRelativeToCenter ? relativeToCenter : Cartesian3.ZERO; + var exaggeration = defaultValue(options.exaggeration, 1.0); + var includeWebMercatorT = defaultValue(options.includeWebMercatorT, false); - function rectangleContainsPosition(potentialContainer, positionToTest) { - return positionToTest.longitude >= potentialContainer.west && - positionToTest.longitude <= potentialContainer.east && - positionToTest.latitude >= potentialContainer.south && - positionToTest.latitude <= potentialContainer.north; - } + var structure = defaultValue(options.structure, HeightmapTessellator.DEFAULT_STRUCTURE); + var heightScale = defaultValue(structure.heightScale, HeightmapTessellator.DEFAULT_STRUCTURE.heightScale); + var heightOffset = defaultValue(structure.heightOffset, HeightmapTessellator.DEFAULT_STRUCTURE.heightOffset); + var elementsPerHeight = defaultValue(structure.elementsPerHeight, HeightmapTessellator.DEFAULT_STRUCTURE.elementsPerHeight); + var stride = defaultValue(structure.stride, HeightmapTessellator.DEFAULT_STRUCTURE.stride); + var elementMultiplier = defaultValue(structure.elementMultiplier, HeightmapTessellator.DEFAULT_STRUCTURE.elementMultiplier); + var isBigEndian = defaultValue(structure.isBigEndian, HeightmapTessellator.DEFAULT_STRUCTURE.isBigEndian); - function findMaxLevelFromNode(stopNode, node, position) { - var maxLevel = 0; + var rectangleWidth = Rectangle.computeWidth(nativeRectangle); + var rectangleHeight = Rectangle.computeHeight(nativeRectangle); - // Find the deepest quadtree node containing this point. - var found = false; - while (!found) { - var nw = node._nw && rectangleContainsPosition(node._nw.extent, position); - var ne = node._ne && rectangleContainsPosition(node._ne.extent, position); - var sw = node._sw && rectangleContainsPosition(node._sw.extent, position); - var se = node._se && rectangleContainsPosition(node._se.extent, position); + var granularityX = rectangleWidth / (width - 1); + var granularityY = rectangleHeight / (height - 1); - // The common scenario is that the point is in only one quadrant and we can simply - // iterate down the tree. But if the point is on a boundary between tiles, it is - // in multiple tiles and we need to check all of them, so use recursion. - if (nw + ne + sw + se > 1) { - if (nw) { - maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._nw, position)); - } - if (ne) { - maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._ne, position)); - } - if (sw) { - maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._sw, position)); - } - if (se) { - maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._se, position)); - } - break; - } else if (nw) { - node = node._nw; - } else if (ne) { - node = node._ne; - } else if (sw) { - node = node._sw; - } else if (se) { - node = node._se; - } else { - found = true; - } + if (!isGeographic) { + rectangleWidth *= oneOverGlobeSemimajorAxis; + rectangleHeight *= oneOverGlobeSemimajorAxis; } - // Work up the tree until we find a rectangle that contains this point. - while (node !== stopNode) { - var rectangles = node.rectangles; + var radiiSquared = ellipsoid.radiiSquared; + var radiiSquaredX = radiiSquared.x; + var radiiSquaredY = radiiSquared.y; + var radiiSquaredZ = radiiSquared.z; - // Rectangles are sorted by level, lowest first. - for (var i = rectangles.length - 1; i >= 0 && rectangles[i].level > maxLevel; --i) { - var rectangle = rectangles[i]; - if (rectangleContainsPosition(rectangle, position)) { - maxLevel = rectangle.level; - } - } + var minimumHeight = 65536.0; + var maximumHeight = -65536.0; - node = node.parent; + var fromENU = Transforms.eastNorthUpToFixedFrame(relativeToCenter, ellipsoid); + var toENU = Matrix4.inverseTransformation(fromENU, matrix4Scratch); + + var southMercatorY; + var oneOverMercatorHeight; + if (includeWebMercatorT) { + southMercatorY = WebMercatorProjection.geodeticLatitudeToMercatorAngle(geographicSouth); + oneOverMercatorHeight = 1.0 / (WebMercatorProjection.geodeticLatitudeToMercatorAngle(geographicNorth) - southMercatorY); } - return maxLevel; - } + var minimum = minimumScratch; + minimum.x = Number.POSITIVE_INFINITY; + minimum.y = Number.POSITIVE_INFINITY; + minimum.z = Number.POSITIVE_INFINITY; - function updateCoverageWithNode(remainingToCoverByLevel, node, rectanglesToCover) { - if (!node) { - return; - } + var maximum = maximumScratch; + maximum.x = Number.NEGATIVE_INFINITY; + maximum.y = Number.NEGATIVE_INFINITY; + maximum.z = Number.NEGATIVE_INFINITY; - var i; - var anyOverlap = false; - for (i = 0; i < rectanglesToCover.length; ++i) { - anyOverlap = anyOverlap || rectanglesOverlap(node.extent, rectanglesToCover[i]); - } + var hMin = Number.POSITIVE_INFINITY; - if (!anyOverlap) { - // This node is not applicable to the rectangle(s). - return; + var arrayWidth = width + (skirtHeight > 0.0 ? 2.0 : 0.0); + var arrayHeight = height + (skirtHeight > 0.0 ? 2.0 : 0.0); + var size = arrayWidth * arrayHeight; + var positions = new Array(size); + var heights = new Array(size); + var uvs = new Array(size); + var webMercatorTs = includeWebMercatorT ? new Array(size) : []; + + var startRow = 0; + var endRow = height; + var startCol = 0; + var endCol = width; + + if (skirtHeight > 0) { + --startRow; + ++endRow; + --startCol; + ++endCol; } - var rectangles = node.rectangles; - for (i = 0; i < rectangles.length; ++i) { - var rectangle = rectangles[i]; + var index = 0; - if (!remainingToCoverByLevel[rectangle.level]) { - remainingToCoverByLevel[rectangle.level] = rectanglesToCover; + for (var rowIndex = startRow; rowIndex < endRow; ++rowIndex) { + var row = rowIndex; + if (row < 0) { + row = 0; + } + if (row >= height) { + row = height - 1; } - remainingToCoverByLevel[rectangle.level] = subtractRectangle(remainingToCoverByLevel[rectangle.level], rectangle); - } - - // Update with child nodes. - updateCoverageWithNode(remainingToCoverByLevel, node._nw, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node._ne, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node._sw, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node._se, rectanglesToCover); - } + var latitude = nativeRectangle.north - granularityY * row; - function subtractRectangle(rectangleList, rectangleToSubtract) { - var result = []; - for (var i = 0; i < rectangleList.length; ++i) { - var rectangle = rectangleList[i]; - if (!rectanglesOverlap(rectangle, rectangleToSubtract)) { - // Disjoint rectangles. Original rectangle is unmodified. - result.push(rectangle); + if (!isGeographic) { + latitude = piOverTwo - (2.0 * atan(exp(-latitude * oneOverGlobeSemimajorAxis))); } else { - // rectangleToSubtract partially or completely overlaps rectangle. - if (rectangle.west < rectangleToSubtract.west) { - result.push(new Rectangle(rectangle.west, rectangle.south, rectangleToSubtract.west, rectangle.north)); - } - if (rectangle.east > rectangleToSubtract.east) { - result.push(new Rectangle(rectangleToSubtract.east, rectangle.south, rectangle.east, rectangle.north)); + latitude = toRadians(latitude); + } + + var cosLatitude = cos(latitude); + var nZ = sin(latitude); + var kZ = radiiSquaredZ * nZ; + + var v = (latitude - geographicSouth) / (geographicNorth - geographicSouth); + v = CesiumMath.clamp(v, 0.0, 1.0); + + var webMercatorT; + if (includeWebMercatorT) { + webMercatorT = (WebMercatorProjection.geodeticLatitudeToMercatorAngle(latitude) - southMercatorY) * oneOverMercatorHeight; + } + + for (var colIndex = startCol; colIndex < endCol; ++colIndex) { + var col = colIndex; + if (col < 0) { + col = 0; } - if (rectangle.south < rectangleToSubtract.south) { - result.push(new Rectangle(Math.max(rectangleToSubtract.west, rectangle.west), rectangle.south, Math.min(rectangleToSubtract.east, rectangle.east), rectangleToSubtract.south)); + if (col >= width) { + col = width - 1; } - if (rectangle.north > rectangleToSubtract.north) { - result.push(new Rectangle(Math.max(rectangleToSubtract.west, rectangle.west), rectangleToSubtract.north, Math.min(rectangleToSubtract.east, rectangle.east), rectangle.north)); + + var longitude = nativeRectangle.west + granularityX * col; + + if (!isGeographic) { + longitude = longitude * oneOverGlobeSemimajorAxis; + } else { + longitude = toRadians(longitude); } - } - } - return result; - } + var terrainOffset = row * (width * stride) + col * stride; - return TileAvailability; -}); + var heightSample; + if (elementsPerHeight === 1) { + heightSample = heightmap[terrainOffset]; + } else { + heightSample = 0; -define('Core/formatError',[ - './defined' - ], function( - defined) { - 'use strict'; + var elementOffset; + if (isBigEndian) { + for (elementOffset = 0; elementOffset < elementsPerHeight; ++elementOffset) { + heightSample = (heightSample * elementMultiplier) + heightmap[terrainOffset + elementOffset]; + } + } else { + for (elementOffset = elementsPerHeight - 1; elementOffset >= 0; --elementOffset) { + heightSample = (heightSample * elementMultiplier) + heightmap[terrainOffset + elementOffset]; + } + } + } - /** - * Formats an error object into a String. If available, uses name, message, and stack - * properties, otherwise, falls back on toString(). - * - * @exports formatError - * - * @param {Object} object The item to find in the array. - * @returns {String} A string containing the formatted error. - */ - function formatError(object) { - var result; + heightSample = (heightSample * heightScale + heightOffset) * exaggeration; - var name = object.name; - var message = object.message; - if (defined(name) && defined(message)) { - result = name + ': ' + message; - } else { - result = object.toString(); - } + var u = (longitude - geographicWest) / (geographicEast - geographicWest); + u = CesiumMath.clamp(u, 0.0, 1.0); + uvs[index] = new Cartesian2(u, v); - var stack = object.stack; - if (defined(stack)) { - result += '\n' + stack; - } + maximumHeight = Math.max(maximumHeight, heightSample); + minimumHeight = Math.min(minimumHeight, heightSample); - return result; - } + if (colIndex !== col || rowIndex !== row) { + var percentage = 0.00001; + if (colIndex < 0) { + longitude -= percentage * rectangleWidth; + } else { + longitude += percentage * rectangleWidth; + } + if (rowIndex < 0) { + latitude += percentage * rectangleHeight; + } else { + latitude -= percentage * rectangleHeight; + } - return formatError; -}); + cosLatitude = cos(latitude); + nZ = sin(latitude); + kZ = radiiSquaredZ * nZ; + heightSample -= skirtHeight; + } -define('Core/TileProviderError',[ - './defaultValue', - './defined', - './formatError' - ], function( - defaultValue, - defined, - formatError) { - 'use strict'; + var nX = cosLatitude * cos(longitude); + var nY = cosLatitude * sin(longitude); - /** - * Provides details about an error that occurred in an {@link ImageryProvider} or a {@link TerrainProvider}. - * - * @alias TileProviderError - * @constructor - * - * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that experienced the error. - * @param {String} message A message describing the error. - * @param {Number} [x] The X coordinate of the tile that experienced the error, or undefined if the error - * is not specific to a particular tile. - * @param {Number} [y] The Y coordinate of the tile that experienced the error, or undefined if the error - * is not specific to a particular tile. - * @param {Number} [level] The level of the tile that experienced the error, or undefined if the error - * is not specific to a particular tile. - * @param {Number} [timesRetried=0] The number of times this operation has been retried. - * @param {Error} [error] The error or exception that occurred, if any. - */ - function TileProviderError(provider, message, x, y, level, timesRetried, error) { - /** - * The {@link ImageryProvider} or {@link TerrainProvider} that experienced the error. - * @type {ImageryProvider|TerrainProvider} - */ - this.provider = provider; + var kX = radiiSquaredX * nX; + var kY = radiiSquaredY * nY; - /** - * The message describing the error. - * @type {String} - */ - this.message = message; + var gamma = sqrt((kX * nX) + (kY * nY) + (kZ * nZ)); + var oneOverGamma = 1.0 / gamma; - /** - * The X coordinate of the tile that experienced the error. If the error is not specific - * to a particular tile, this property will be undefined. - * @type {Number} - */ - this.x = x; + var rSurfaceX = kX * oneOverGamma; + var rSurfaceY = kY * oneOverGamma; + var rSurfaceZ = kZ * oneOverGamma; - /** - * The Y coordinate of the tile that experienced the error. If the error is not specific - * to a particular tile, this property will be undefined. - * @type {Number} - */ - this.y = y; + var position = new Cartesian3(); + position.x = rSurfaceX + nX * heightSample; + position.y = rSurfaceY + nY * heightSample; + position.z = rSurfaceZ + nZ * heightSample; - /** - * The level-of-detail of the tile that experienced the error. If the error is not specific - * to a particular tile, this property will be undefined. - * @type {Number} - */ - this.level = level; + positions[index] = position; + heights[index] = heightSample; - /** - * The number of times this operation has been retried. - * @type {Number} - * @default 0 - */ - this.timesRetried = defaultValue(timesRetried, 0); + if (includeWebMercatorT) { + webMercatorTs[index] = webMercatorT; + } - /** - * True if the failed operation should be retried; otherwise, false. The imagery or terrain provider - * will set the initial value of this property before raising the event, but any listeners - * can change it. The value after the last listener is invoked will be acted upon. - * @type {Boolean} - * @default false - */ - this.retry = false; + index++; - /** - * The error or exception that occurred, if any. - * @type {Error} - */ - this.error = error; - } + Matrix4.multiplyByPoint(toENU, position, cartesian3Scratch); - /** - * Handles an error in an {@link ImageryProvider} or {@link TerrainProvider} by raising an event if it has any listeners, or by - * logging the error to the console if the event has no listeners. This method also tracks the number - * of times the operation has been retried and will automatically retry if requested to do so by the - * event listeners. - * - * @param {TileProviderError} previousError The error instance returned by this function the last - * time it was called for this error, or undefined if this is the first time this error has - * occurred. - * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that encountered the error. - * @param {Event} event The event to raise to inform listeners of the error. - * @param {String} message The message describing the error. - * @param {Number} x The X coordinate of the tile that experienced the error, or undefined if the - * error is not specific to a particular tile. - * @param {Number} y The Y coordinate of the tile that experienced the error, or undefined if the - * error is not specific to a particular tile. - * @param {Number} level The level-of-detail of the tile that experienced the error, or undefined if the - * error is not specific to a particular tile. - * @param {TileProviderError~RetryFunction} retryFunction The function to call to retry the operation. If undefined, the - * operation will not be retried. - * @param {Error} [errorDetails] The error or exception that occurred, if any. - * @returns {TileProviderError} The error instance that was passed to the event listeners and that - * should be passed to this function the next time it is called for the same error in order - * to track retry counts. - */ - TileProviderError.handleError = function(previousError, provider, event, message, x, y, level, retryFunction, errorDetails) { - var error = previousError; - if (!defined(previousError)) { - error = new TileProviderError(provider, message, x, y, level, 0, errorDetails); - } else { - error.provider = provider; - error.message = message; - error.x = x; - error.y = y; - error.level = level; - error.retry = false; - error.error = errorDetails; - ++error.timesRetried; + Cartesian3.minimumByComponent(cartesian3Scratch, minimum, minimum); + Cartesian3.maximumByComponent(cartesian3Scratch, maximum, maximum); + hMin = Math.min(hMin, heightSample); + } } - if (event.numberOfListeners > 0) { - event.raiseEvent(error); - } else { - console.log('An error occurred in "' + provider.constructor.name + '": ' + formatError(message)); + var boundingSphere3D = BoundingSphere.fromPoints(positions); + var orientedBoundingBox; + if (defined(rectangle) && rectangle.width < CesiumMath.PI_OVER_TWO + CesiumMath.EPSILON5) { + // Here, rectangle.width < pi/2, and rectangle.height < pi + // (though it would still work with rectangle.width up to pi) + orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, ellipsoid); } - if (error.retry && defined(retryFunction)) { - retryFunction(); + var occludeePointInScaledSpace; + if (hasRelativeToCenter) { + var occluder = new EllipsoidalOccluder(ellipsoid); + occludeePointInScaledSpace = occluder.computeHorizonCullingPoint(relativeToCenter, positions); } - return error; + var aaBox = new AxisAlignedBoundingBox(minimum, maximum, relativeToCenter); + var encoding = new TerrainEncoding(aaBox, hMin, maximumHeight, fromENU, false, includeWebMercatorT); + var vertices = new Float32Array(size * encoding.getStride()); + + var bufferIndex = 0; + for (var j = 0; j < size; ++j) { + bufferIndex = encoding.encode(vertices, bufferIndex, positions[j], uvs[j], heights[j], undefined, webMercatorTs[j]); + } + + return { + vertices : vertices, + maximumHeight : maximumHeight, + minimumHeight : minimumHeight, + encoding : encoding, + boundingSphere3D : boundingSphere3D, + orientedBoundingBox : orientedBoundingBox, + occludeePointInScaledSpace : occludeePointInScaledSpace + }; }; + return HeightmapTessellator; +}); + +define('Core/destroyObject',[ + './defaultValue', + './DeveloperError' + ], function( + defaultValue, + DeveloperError) { + 'use strict'; + + function returnTrue() { + return true; + } + /** - * Handles success of an operation by resetting the retry count of a previous error, if any. This way, - * if the error occurs again in the future, the listeners will be informed that it has not yet been retried. + * Destroys an object. Each of the object's functions, including functions in its prototype, + * is replaced with a function that throws a {@link DeveloperError}, except for the object's + * <code>isDestroyed</code> function, which is set to a function that returns <code>true</code>. + * The object's properties are removed with <code>delete</code>. + * <br /><br /> + * This function is used by objects that hold native resources, e.g., WebGL resources, which + * need to be explicitly released. Client code calls an object's <code>destroy</code> function, + * which then releases the native resource and calls <code>destroyObject</code> to put itself + * in a destroyed state. * - * @param {TileProviderError} previousError The previous error, or undefined if this operation has - * not previously resulted in an error. + * @exports destroyObject + * + * @param {Object} object The object to destroy. + * @param {String} [message] The message to include in the exception that is thrown if + * a destroyed object's function is called. + * + * + * @example + * // How a texture would destroy itself. + * this.destroy = function () { + * _gl.deleteTexture(_texture); + * return Cesium.destroyObject(this); + * }; + * + * @see DeveloperError */ - TileProviderError.handleSuccess = function(previousError) { - if (defined(previousError)) { - previousError.timesRetried = -1; + function destroyObject(object, message) { + message = defaultValue(message, 'This object was destroyed, i.e., destroy() was called.'); + + function throwOnDestroyed() { + throw new DeveloperError(message); + } + + for ( var key in object) { + if (typeof object[key] === 'function') { + object[key] = throwOnDestroyed; + } } - }; - /** - * A function that will be called to retry the operation. - * @callback TileProviderError~RetryFunction - */ + object.isDestroyed = returnTrue; - return TileProviderError; + return undefined; + } + + return destroyObject; }); -define('Core/CesiumTerrainProvider',[ - '../ThirdParty/Uri', +define('Core/TaskProcessor',[ '../ThirdParty/when', - './BoundingSphere', - './Cartesian3', - './Credit', + './buildModuleUrl', './defaultValue', './defined', - './defineProperties', + './destroyObject', './DeveloperError', './Event', - './GeographicTilingScheme', - './HeightmapTerrainData', - './IndexDatatype', - './joinUrls', - './loadArrayBuffer', - './loadJson', - './Math', - './OrientedBoundingBox', - './QuantizedMeshTerrainData', + './getAbsoluteUri', + './isCrossOriginUrl', './RuntimeError', - './TerrainProvider', - './TileAvailability', - './TileProviderError' + 'require' ], function( - Uri, when, - BoundingSphere, - Cartesian3, - Credit, + buildModuleUrl, defaultValue, defined, - defineProperties, + destroyObject, DeveloperError, Event, - GeographicTilingScheme, - HeightmapTerrainData, - IndexDatatype, - joinUrls, - loadArrayBuffer, - loadJson, - CesiumMath, - OrientedBoundingBox, - QuantizedMeshTerrainData, + getAbsoluteUri, + isCrossOriginUrl, RuntimeError, - TerrainProvider, - TileAvailability, - TileProviderError) { + require) { 'use strict'; - function LayerInformation(layer) { - this.isHeightmap = layer.isHeightmap; - this.tileUrlTemplates = layer.tileUrlTemplates; - this.availability = layer.availability; - this.hasVertexNormals = layer.hasVertexNormals; - this.hasWaterMask = layer.hasWaterMask; - this.littleEndianExtensionSize = layer.littleEndianExtensionSize; - } + function canTransferArrayBuffer() { + if (!defined(TaskProcessor._canTransferArrayBuffer)) { + var worker = new Worker(getWorkerUrl('Workers/transferTypedArrayTest.js')); + worker.postMessage = defaultValue(worker.webkitPostMessage, worker.postMessage); - /** - * A {@link TerrainProvider} that accesses terrain data in a Cesium terrain format. - * The format is described on the - * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Cesium-Terrain-Server|Cesium wiki}. - * - * @alias CesiumTerrainProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the Cesium terrain server. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed. - * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available. - * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server, if available. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * - * - * @example - * // Construct a terrain provider that uses per vertex normals for lighting - * // to add shading detail to an imagery provider. - * var terrainProvider = new Cesium.CesiumTerrainProvider({ - * url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles', - * requestVertexNormals : true - * }); - * - * // Terrain geometry near the surface of the globe is difficult to view when using NaturalEarthII imagery, - * // unless the TerrainProvider provides additional lighting information to shade the terrain (as shown above). - * var imageryProvider = Cesium.createTileMapServiceImageryProvider({ - * url : 'http://localhost:8080/Source/Assets/Textures/NaturalEarthII', - * fileExtension : 'jpg' - * }); - * - * var viewer = new Cesium.Viewer('cesiumContainer', { - * imageryProvider : imageryProvider, - * baseLayerPicker : false, - * terrainProvider : terrainProvider - * }); - * - * // The globe must enable lighting to make use of the terrain's vertex normals - * viewer.scene.globe.enableLighting = true; - * - * @see TerrainProvider - */ - function CesiumTerrainProvider(options) { - if (!defined(options) || !defined(options.url)) { - throw new DeveloperError('options.url is required.'); - } - - this._url = options.url; - this._proxy = options.proxy; + var value = 99; + var array = new Int8Array([value]); - this._tilingScheme = new GeographicTilingScheme({ - numberOfLevelZeroTilesX : 2, - numberOfLevelZeroTilesY : 1, - ellipsoid : options.ellipsoid - }); + try { + // postMessage might fail with a DataCloneError + // if transferring array buffers is not supported. + worker.postMessage({ + array : array + }, [array.buffer]); + } catch (e) { + TaskProcessor._canTransferArrayBuffer = false; + return TaskProcessor._canTransferArrayBuffer; + } - this._heightmapWidth = 65; - this._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid, this._heightmapWidth, this._tilingScheme.getNumberOfXTilesAtLevel(0)); + var deferred = when.defer(); - this._heightmapStructure = undefined; - this._hasWaterMask = false; - this._hasVertexNormals = false; + worker.onmessage = function(event) { + var array = event.data.array; - /** - * Boolean flag that indicates if the client should request vertex normals from the server. - * @type {Boolean} - * @default false - * @private - */ - this._requestVertexNormals = defaultValue(options.requestVertexNormals, false); + // some versions of Firefox silently fail to transfer typed arrays. + // https://bugzilla.mozilla.org/show_bug.cgi?id=841904 + // Check to make sure the value round-trips successfully. + var result = defined(array) && array[0] === value; + deferred.resolve(result); - /** - * Boolean flag that indicates if the client should request tile watermasks from the server. - * @type {Boolean} - * @default false - * @private - */ - this._requestWaterMask = defaultValue(options.requestWaterMask, false); + worker.terminate(); - this._errorEvent = new Event(); + TaskProcessor._canTransferArrayBuffer = result; + }; - var credit = options.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); + TaskProcessor._canTransferArrayBuffer = deferred.promise; } - this._credit = credit; - this._availability = undefined; + return TaskProcessor._canTransferArrayBuffer; + } - this._ready = false; - this._readyPromise = when.defer(); + var taskCompletedEvent = new Event(); + + function completeTask(processor, data) { + --processor._activeTasks; - var lastUrl = this._url; - var metadataUrl = joinUrls(this._url, 'layer.json'); - if (defined(this._proxy)) { - metadataUrl = this._proxy.getURL(metadataUrl); + var id = data.id; + if (!defined(id)) { + // This is not one of ours. + return; } - var that = this; - var metadataError; + var deferreds = processor._deferreds; + var deferred = deferreds[id]; - var layers = this._layers = []; - var attribution = ''; - var overallAvailability = []; + if (defined(data.error)) { + var error = data.error; + if (error.name === 'RuntimeError') { + error = new RuntimeError(data.error.message); + error.stack = data.error.stack; + } else if (error.name === 'DeveloperError') { + error = new DeveloperError(data.error.message); + error.stack = data.error.stack; + } + taskCompletedEvent.raiseEvent(error); + deferred.reject(error); + } else { + taskCompletedEvent.raiseEvent(); + deferred.resolve(data.result); + } - function parseMetadataSuccess(data) { - var message; + delete deferreds[id]; + } - if (!data.format) { - message = 'The tile format is not specified in the layer.json file.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - return; - } + function getWorkerUrl(moduleID) { + var url = buildModuleUrl(moduleID); - if (!data.tiles || data.tiles.length === 0) { - message = 'The layer.json file does not specify any tile URL templates.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - return; - } + if (isCrossOriginUrl(url)) { + //to load cross-origin, create a shim worker from a blob URL + var script = 'importScripts("' + url + '");'; - var hasVertexNormals = false; - var hasWaterMask = false; - var littleEndianExtensionSize = true; - var isHeightmap = false; - if (data.format === 'heightmap-1.0') { - isHeightmap = true; - if (!defined(that._heightmapStructure)) { - that._heightmapStructure = { - heightScale : 1.0 / 5.0, - heightOffset : -1000.0, - elementsPerHeight : 1, - stride : 1, - elementMultiplier : 256.0, - isBigEndian : false, - lowestEncodedHeight : 0, - highestEncodedHeight : 256 * 256 - 1 - }; - } - hasWaterMask = true; - that._requestWaterMask = true; - } else if (data.format.indexOf('quantized-mesh-1.') !== 0) { - message = 'The tile format "' + data.format + '" is invalid or not supported.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - return; + var blob; + try { + blob = new Blob([script], { + type : 'application/javascript' + }); + } catch (e) { + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var blobBuilder = new BlobBuilder(); + blobBuilder.append(script); + blob = blobBuilder.getBlob('application/javascript'); } - var tileUrlTemplates = data.tiles; - for (var i = 0; i < tileUrlTemplates.length; ++i) { - var template = new Uri(tileUrlTemplates[i]); - var baseUri = new Uri(lastUrl); - if (template.authority && !baseUri.authority) { - baseUri.authority = template.authority; - baseUri.scheme = template.scheme; - } - tileUrlTemplates[i] = joinUrls(baseUri, template).toString().replace('{version}', data.version); - } + var URL = window.URL || window.webkitURL; + url = URL.createObjectURL(blob); + } - var availableTiles = data.available; - var availability; - if (defined(availableTiles)) { - availability = new TileAvailability(that._tilingScheme, availableTiles.length); + return url; + } - for (var level = 0; level < availableTiles.length; ++level) { - var rangesAtLevel = availableTiles[level]; - var yTiles = that._tilingScheme.getNumberOfYTilesAtLevel(level); - if (!defined(overallAvailability[level])) { - overallAvailability[level] = []; - } + var bootstrapperUrlResult; + function getBootstrapperUrl() { + if (!defined(bootstrapperUrlResult)) { + bootstrapperUrlResult = getWorkerUrl('Workers/cesiumWorkerBootstrapper.js'); + } + return bootstrapperUrlResult; + } - for (var rangeIndex = 0; rangeIndex < rangesAtLevel.length; ++rangeIndex) { - var range = rangesAtLevel[rangeIndex]; - var yStart = yTiles - range.endY - 1; - var yEnd = yTiles - range.startY - 1; - overallAvailability[level].push([range.startX, yStart, range.endX, yEnd]); - availability.addAvailableTileRange(level, range.startX, yStart, range.endX, yEnd); - } - } - } + function createWorker(processor) { + var worker = new Worker(getBootstrapperUrl()); + worker.postMessage = defaultValue(worker.webkitPostMessage, worker.postMessage); - // The vertex normals defined in the 'octvertexnormals' extension is identical to the original - // contents of the original 'vertexnormals' extension. 'vertexnormals' extension is now - // deprecated, as the extensionLength for this extension was incorrectly using big endian. - // We maintain backwards compatibility with the legacy 'vertexnormal' implementation - // by setting the _littleEndianExtensionSize to false. Always prefer 'octvertexnormals' - // over 'vertexnormals' if both extensions are supported by the server. - if (defined(data.extensions) && data.extensions.indexOf('octvertexnormals') !== -1) { - hasVertexNormals = true; - } else if (defined(data.extensions) && data.extensions.indexOf('vertexnormals') !== -1) { - hasVertexNormals = true; - littleEndianExtensionSize = false; - } - if (defined(data.extensions) && data.extensions.indexOf('watermask') !== -1) { - hasWaterMask = true; - } + var bootstrapMessage = { + loaderConfig : {}, + workerModule : TaskProcessor._workerModulePrefix + processor._workerName + }; - that._hasWaterMask = that._hasWaterMask || hasWaterMask; - that._hasVertexNormals = that._hasVertexNormals || hasVertexNormals; - if (defined(data.attribution)) { - if (attribution.length > 0) { - attribution += ' '; - } - attribution += data.attribution; - } + if (defined(TaskProcessor._loaderConfig)) { + bootstrapMessage.loaderConfig = TaskProcessor._loaderConfig; + } else if (defined(define.amd) && !define.amd.toUrlUndefined && defined(require.toUrl)) { + bootstrapMessage.loaderConfig.baseUrl = + getAbsoluteUri('..', buildModuleUrl('Workers/cesiumWorkerBootstrapper.js')); + } else { + bootstrapMessage.loaderConfig.paths = { + 'Workers' : buildModuleUrl('Workers') + }; + } - layers.push(new LayerInformation({ - isHeightmap: isHeightmap, - tileUrlTemplates: tileUrlTemplates, - availability: availability, - hasVertexNormals: hasVertexNormals, - hasWaterMask: hasWaterMask, - littleEndianExtensionSize: littleEndianExtensionSize - })); - - var parentUrl = data.parentUrl; - if (defined(parentUrl)) { - if (!defined(availability)) { - console.log('A layer.json can\'t have a parentUrl if it does\'t have an available array.'); - return when.resolve(); - } - lastUrl = joinUrls(lastUrl, parentUrl); - metadataUrl = joinUrls(lastUrl, 'layer.json'); - if (defined(that._proxy)) { - metadataUrl = that._proxy.getURL(metadataUrl); - } - var parentMetadata = loadJson(metadataUrl); - return when(parentMetadata, parseMetadataSuccess, parseMetadataFailure); - } - - return when.resolve(); - } - - function parseMetadataFailure(data) { - var message = 'An error occurred while accessing ' + metadataUrl + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - } - - function metadataSuccess(data) { - parseMetadataSuccess(data) - .then(function() { - if (defined(metadataError)) { - return; - } - - var length = overallAvailability.length; - if (length > 0) { - var availability = that._availability = new TileAvailability(that._tilingScheme, length); - for (var level = 0; level < length; ++level) { - var levelRanges = overallAvailability[level]; - for (var i = 0; i < levelRanges.length; ++i) { - var range = levelRanges[i]; - availability.addAvailableTileRange(level, range[0], range[1], range[2], range[3]); - } - } - } - - if (!defined(that._credit) && attribution.length > 0) { - that._credit = new Credit({text: attribution}); - } - - that._ready = true; - that._readyPromise.resolve(true); - }); - } - - function metadataFailure(data) { - // If the metadata is not found, assume this is a pre-metadata heightmap tileset. - if (defined(data) && data.statusCode === 404) { - metadataSuccess({ - tilejson: '2.1.0', - format : 'heightmap-1.0', - version : '1.0.0', - scheme : 'tms', - tiles : [ - '{z}/{x}/{y}.terrain?v={version}' - ] - }); - return; - } - parseMetadataFailure(data); - } + worker.postMessage(bootstrapMessage); - function requestMetadata() { - var metadata = loadJson(metadataUrl); - when(metadata, metadataSuccess, metadataFailure); - } + worker.onmessage = function(event) { + completeTask(processor, event.data); + }; - requestMetadata(); + return worker; } /** - * When using the Quantized-Mesh format, a tile may be returned that includes additional extensions, such as PerVertexNormals, watermask, etc. - * This enumeration defines the unique identifiers for each type of extension data that has been appended to the standard mesh data. + * A wrapper around a web worker that allows scheduling tasks for a given worker, + * returning results asynchronously via a promise. * - * @exports QuantizedMeshExtensionIds - * @see CesiumTerrainProvider - * @private + * The Worker is not constructed until a task is scheduled. + * + * @alias TaskProcessor + * @constructor + * + * @param {String} workerName The name of the worker. This is expected to be a script + * in the Workers folder. + * @param {Number} [maximumActiveTasks=5] The maximum number of active tasks. Once exceeded, + * scheduleTask will not queue any more tasks, allowing + * work to be rescheduled in future frames. */ - var QuantizedMeshExtensionIds = { - /** - * Oct-Encoded Per-Vertex Normals are included as an extension to the tile mesh - * - * @type {Number} - * @constant - * @default 1 - */ - OCT_VERTEX_NORMALS: 1, - /** - * A watermask is included as an extension to the tile mesh - * - * @type {Number} - * @constant - * @default 2 - */ - WATER_MASK: 2 - }; - - function getRequestHeader(extensionsList) { - if (!defined(extensionsList) || extensionsList.length === 0) { - return { - Accept : 'application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01' - }; - } - var extensions = extensionsList.join('-'); - return { - Accept : 'application/vnd.quantized-mesh;extensions=' + extensions + ',application/octet-stream;q=0.9,*/*;q=0.01' - }; - } - - function createHeightmapTerrainData(provider, buffer, level, x, y, tmsY) { - var heightBuffer = new Uint16Array(buffer, 0, provider._heightmapWidth * provider._heightmapWidth); - return new HeightmapTerrainData({ - buffer : heightBuffer, - childTileMask : new Uint8Array(buffer, heightBuffer.byteLength, 1)[0], - waterMask : new Uint8Array(buffer, heightBuffer.byteLength + 1, buffer.byteLength - heightBuffer.byteLength - 1), - width : provider._heightmapWidth, - height : provider._heightmapWidth, - structure : provider._heightmapStructure - }); + function TaskProcessor(workerName, maximumActiveTasks) { + this._workerName = workerName; + this._maximumActiveTasks = defaultValue(maximumActiveTasks, 5); + this._activeTasks = 0; + this._deferreds = {}; + this._nextID = 0; } - function createQuantizedMeshTerrainData(provider, buffer, level, x, y, tmsY, littleEndianExtensionSize) { - var pos = 0; - var cartesian3Elements = 3; - var boundingSphereElements = cartesian3Elements + 1; - var cartesian3Length = Float64Array.BYTES_PER_ELEMENT * cartesian3Elements; - var boundingSphereLength = Float64Array.BYTES_PER_ELEMENT * boundingSphereElements; - var encodedVertexElements = 3; - var encodedVertexLength = Uint16Array.BYTES_PER_ELEMENT * encodedVertexElements; - var triangleElements = 3; - var bytesPerIndex = Uint16Array.BYTES_PER_ELEMENT; - var triangleLength = bytesPerIndex * triangleElements; + var emptyTransferableObjectArray = []; - var view = new DataView(buffer); - var center = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)); - pos += cartesian3Length; + /** + * Schedule a task to be processed by the web worker asynchronously. If there are currently more + * tasks active than the maximum set by the constructor, will immediately return undefined. + * Otherwise, returns a promise that will resolve to the result posted back by the worker when + * finished. + * + * @param {*} parameters Any input data that will be posted to the worker. + * @param {Object[]} [transferableObjects] An array of objects contained in parameters that should be + * transferred to the worker instead of copied. + * @returns {Promise.<Object>|undefined} Either a promise that will resolve to the result when available, or undefined + * if there are too many active tasks, + * + * @example + * var taskProcessor = new Cesium.TaskProcessor('myWorkerName'); + * var promise = taskProcessor.scheduleTask({ + * someParameter : true, + * another : 'hello' + * }); + * if (!Cesium.defined(promise)) { + * // too many active tasks - try again later + * } else { + * Cesium.when(promise, function(result) { + * // use the result of the task + * }); + * } + */ + TaskProcessor.prototype.scheduleTask = function(parameters, transferableObjects) { + if (!defined(this._worker)) { + this._worker = createWorker(this); + } - var minimumHeight = view.getFloat32(pos, true); - pos += Float32Array.BYTES_PER_ELEMENT; - var maximumHeight = view.getFloat32(pos, true); - pos += Float32Array.BYTES_PER_ELEMENT; + if (this._activeTasks >= this._maximumActiveTasks) { + return undefined; + } - var boundingSphere = new BoundingSphere( - new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)), - view.getFloat64(pos + cartesian3Length, true)); - pos += boundingSphereLength; + ++this._activeTasks; - var horizonOcclusionPoint = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)); - pos += cartesian3Length; + var processor = this; + return when(canTransferArrayBuffer(), function(canTransferArrayBuffer) { + if (!defined(transferableObjects)) { + transferableObjects = emptyTransferableObjectArray; + } else if (!canTransferArrayBuffer) { + transferableObjects.length = 0; + } - var vertexCount = view.getUint32(pos, true); - pos += Uint32Array.BYTES_PER_ELEMENT; - var encodedVertexBuffer = new Uint16Array(buffer, pos, vertexCount * 3); - pos += vertexCount * encodedVertexLength; + var id = processor._nextID++; + var deferred = when.defer(); + processor._deferreds[id] = deferred; - if (vertexCount > 64 * 1024) { - // More than 64k vertices, so indices are 32-bit. - bytesPerIndex = Uint32Array.BYTES_PER_ELEMENT; - triangleLength = bytesPerIndex * triangleElements; - } + processor._worker.postMessage({ + id : id, + parameters : parameters, + canTransferArrayBuffer : canTransferArrayBuffer + }, transferableObjects); - // Decode the vertex buffer. - var uBuffer = encodedVertexBuffer.subarray(0, vertexCount); - var vBuffer = encodedVertexBuffer.subarray(vertexCount, 2 * vertexCount); - var heightBuffer = encodedVertexBuffer.subarray(vertexCount * 2, 3 * vertexCount); + return deferred.promise; + }); + }; - var i; - var u = 0; - var v = 0; - var height = 0; + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see TaskProcessor#destroy + */ + TaskProcessor.prototype.isDestroyed = function() { + return false; + }; - function zigZagDecode(value) { - return (value >> 1) ^ (-(value & 1)); + /** + * Destroys this object. This will immediately terminate the Worker. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {undefined} + */ + TaskProcessor.prototype.destroy = function() { + if (defined(this._worker)) { + this._worker.terminate(); } + return destroyObject(this); + }; - for (i = 0; i < vertexCount; ++i) { - u += zigZagDecode(uBuffer[i]); - v += zigZagDecode(vBuffer[i]); - height += zigZagDecode(heightBuffer[i]); + /** + * An event that's raised when a task is completed successfully. Event handlers are passed + * the error object is a task fails. + * + * @type {Event} + * + * @private + */ + TaskProcessor.taskCompletedEvent = taskCompletedEvent; - uBuffer[i] = u; - vBuffer[i] = v; - heightBuffer[i] = height; - } + // exposed for testing purposes + TaskProcessor._defaultWorkerModulePrefix = 'Workers/'; + TaskProcessor._workerModulePrefix = TaskProcessor._defaultWorkerModulePrefix; + TaskProcessor._loaderConfig = undefined; + TaskProcessor._canTransferArrayBuffer = undefined; - // skip over any additional padding that was added for 2/4 byte alignment - if (pos % bytesPerIndex !== 0) { - pos += (bytesPerIndex - (pos % bytesPerIndex)); - } + return TaskProcessor; +}); - var triangleCount = view.getUint32(pos, true); - pos += Uint32Array.BYTES_PER_ELEMENT; - var indices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, triangleCount * triangleElements); - pos += triangleCount * triangleLength; +define('Core/TerrainMesh',[ + './defaultValue' + ], function( + defaultValue) { + 'use strict'; - // High water mark decoding based on decompressIndices_ in webgl-loader's loader.js. - // https://code.google.com/p/webgl-loader/source/browse/trunk/samples/loader.js?r=99#55 - // Copyright 2012 Google Inc., Apache 2.0 license. - var highest = 0; - for (i = 0; i < indices.length; ++i) { - var code = indices[i]; - indices[i] = highest - code; - if (code === 0) { - ++highest; - } - } + /** + * A mesh plus related metadata for a single tile of terrain. Instances of this type are + * usually created from raw {@link TerrainData}. + * + * @alias TerrainMesh + * @constructor + * + * @param {Cartesian3} center The center of the tile. Vertex positions are specified relative to this center. + * @param {Float32Array} vertices The vertex data, including positions, texture coordinates, and heights. + * The vertex data is in the order [X, Y, Z, H, U, V], where X, Y, and Z represent + * the Cartesian position of the vertex, H is the height above the ellipsoid, and + * U and V are the texture coordinates. + * @param {Uint16Array|Uint32Array} indices The indices describing how the vertices are connected to form triangles. + * @param {Number} minimumHeight The lowest height in the tile, in meters above the ellipsoid. + * @param {Number} maximumHeight The highest height in the tile, in meters above the ellipsoid. + * @param {BoundingSphere} boundingSphere3D A bounding sphere that completely contains the tile. + * @param {Cartesian3} occludeePointInScaledSpace The occludee point of the tile, represented in ellipsoid- + * scaled space, and used for horizon culling. If this point is below the horizon, + * the tile is considered to be entirely below the horizon. + * @param {Number} [vertexStride=6] The number of components in each vertex. + * @param {OrientedBoundingBox} [orientedBoundingBox] A bounding box that completely contains the tile. + * @param {TerrainEncoding} encoding Information used to decode the mesh. + * @param {Number} exaggeration The amount that this mesh was exaggerated. + * + * @private + */ + function TerrainMesh(center, vertices, indices, minimumHeight, maximumHeight, boundingSphere3D, occludeePointInScaledSpace, vertexStride, orientedBoundingBox, encoding, exaggeration) { + /** + * The center of the tile. Vertex positions are specified relative to this center. + * @type {Cartesian3} + */ + this.center = center; - var westVertexCount = view.getUint32(pos, true); - pos += Uint32Array.BYTES_PER_ELEMENT; - var westIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, westVertexCount); - pos += westVertexCount * bytesPerIndex; + /** + * The vertex data, including positions, texture coordinates, and heights. + * The vertex data is in the order [X, Y, Z, H, U, V], where X, Y, and Z represent + * the Cartesian position of the vertex, H is the height above the ellipsoid, and + * U and V are the texture coordinates. The vertex data may have additional attributes after those + * mentioned above when the {@link TerrainMesh#stride} is greater than 6. + * @type {Float32Array} + */ + this.vertices = vertices; - var southVertexCount = view.getUint32(pos, true); - pos += Uint32Array.BYTES_PER_ELEMENT; - var southIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, southVertexCount); - pos += southVertexCount * bytesPerIndex; + /** + * The number of components in each vertex. Typically this is 6 for the 6 components + * [X, Y, Z, H, U, V], but if each vertex has additional data (such as a vertex normal), this value + * may be higher. + * @type {Number} + */ + this.stride = defaultValue(vertexStride, 6); - var eastVertexCount = view.getUint32(pos, true); - pos += Uint32Array.BYTES_PER_ELEMENT; - var eastIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, eastVertexCount); - pos += eastVertexCount * bytesPerIndex; + /** + * The indices describing how the vertices are connected to form triangles. + * @type {Uint16Array|Uint32Array} + */ + this.indices = indices; - var northVertexCount = view.getUint32(pos, true); - pos += Uint32Array.BYTES_PER_ELEMENT; - var northIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, northVertexCount); - pos += northVertexCount * bytesPerIndex; + /** + * The lowest height in the tile, in meters above the ellipsoid. + * @type {Number} + */ + this.minimumHeight = minimumHeight; - var encodedNormalBuffer; - var waterMaskBuffer; - while (pos < view.byteLength) { - var extensionId = view.getUint8(pos, true); - pos += Uint8Array.BYTES_PER_ELEMENT; - var extensionLength = view.getUint32(pos, littleEndianExtensionSize); - pos += Uint32Array.BYTES_PER_ELEMENT; + /** + * The highest height in the tile, in meters above the ellipsoid. + * @type {Number} + */ + this.maximumHeight = maximumHeight; - if (extensionId === QuantizedMeshExtensionIds.OCT_VERTEX_NORMALS && provider._requestVertexNormals) { - encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); - } else if (extensionId === QuantizedMeshExtensionIds.WATER_MASK && provider._requestWaterMask) { - waterMaskBuffer = new Uint8Array(buffer, pos, extensionLength); - } - pos += extensionLength; - } + /** + * A bounding sphere that completely contains the tile. + * @type {BoundingSphere} + */ + this.boundingSphere3D = boundingSphere3D; - var skirtHeight = provider.getLevelMaximumGeometricError(level) * 5.0; + /** + * The occludee point of the tile, represented in ellipsoid- + * scaled space, and used for horizon culling. If this point is below the horizon, + * the tile is considered to be entirely below the horizon. + * @type {Cartesian3} + */ + this.occludeePointInScaledSpace = occludeePointInScaledSpace; - var rectangle = provider._tilingScheme.tileXYToRectangle(x, y, level); - var orientedBoundingBox; - if (rectangle.width < CesiumMath.PI_OVER_TWO + CesiumMath.EPSILON5) { - // Here, rectangle.width < pi/2, and rectangle.height < pi - // (though it would still work with rectangle.width up to pi) + /** + * A bounding box that completely contains the tile. + * @type {OrientedBoundingBox} + */ + this.orientedBoundingBox = orientedBoundingBox; - // The skirt is not included in the OBB computation. If this ever - // causes any rendering artifacts (cracks), they are expected to be - // minor and in the corners of the screen. It's possible that this - // might need to be changed - just change to `minimumHeight - skirtHeight` - // A similar change might also be needed in `upsampleQuantizedTerrainMesh.js`. - orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, provider._tilingScheme.ellipsoid); - } + /** + * Information for decoding the mesh vertices. + * @type {TerrainEncoding} + */ + this.encoding = encoding; - return new QuantizedMeshTerrainData({ - center : center, - minimumHeight : minimumHeight, - maximumHeight : maximumHeight, - boundingSphere : boundingSphere, - orientedBoundingBox : orientedBoundingBox, - horizonOcclusionPoint : horizonOcclusionPoint, - quantizedVertices : encodedVertexBuffer, - encodedNormals : encodedNormalBuffer, - indices : indices, - westIndices : westIndices, - southIndices : southIndices, - eastIndices : eastIndices, - northIndices : northIndices, - westSkirtHeight : skirtHeight, - southSkirtHeight : skirtHeight, - eastSkirtHeight : skirtHeight, - northSkirtHeight : skirtHeight, - childTileMask: provider.availability.computeChildMaskForTile(level, x, y), - waterMask: waterMaskBuffer - }); + /** + * The amount that this mesh was exaggerated. + * @type {Number} + */ + this.exaggeration = exaggeration; } + return TerrainMesh; +}); + +define('Core/TerrainProvider',[ + './defined', + './defineProperties', + './DeveloperError', + './Math' + ], function( + defined, + defineProperties, + DeveloperError, + CesiumMath) { + 'use strict'; + /** - * Requests the geometry for a given tile. This function should not be called before - * {@link CesiumTerrainProvider#ready} returns true. The result must include terrain data and - * may optionally include a water mask and an indication of which child tiles are available. - * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @param {Request} [request] The request object. Intended for internal use only. + * Provides terrain or other geometry for the surface of an ellipsoid. The surface geometry is + * organized into a pyramid of tiles according to a {@link TilingScheme}. This type describes an + * interface and is not intended to be instantiated directly. * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method - * returns undefined instead of a promise, it is an indication that too many requests are already - * pending and the request will be retried later. + * @alias TerrainProvider + * @constructor * - * @exception {DeveloperError} This function must not be called before {@link CesiumTerrainProvider#ready} - * returns true. + * @see EllipsoidTerrainProvider + * @see CesiumTerrainProvider + * @see VRTheWorldTerrainProvider + * @see GoogleEarthEnterpriseTerrainProvider */ - CesiumTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestTileGeometry must not be called before the terrain provider is ready.'); - } - - var layers = this._layers; - var layerToUse; - var layerCount = layers.length; - - if (layerCount === 1) { // Optimized path for single layers - layerToUse = layers[0]; - } else { - for (var i = 0; i < layerCount; ++i) { - var layer = layers[i]; - if (!defined(layer.availability) || layer.availability.isTileAvailable(level, x, y)) { - layerToUse = layer; - break; - } - } - } - - if (!defined(layerToUse)) { - return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); - } - - var urlTemplates = layerToUse.tileUrlTemplates; - if (urlTemplates.length === 0) { - return undefined; - } - - var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level); - - var tmsY = (yTiles - y - 1); - - var url = urlTemplates[(x + tmsY + level) % urlTemplates.length].replace('{z}', level).replace('{x}', x).replace('{y}', tmsY); - - var proxy = this._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } - - var extensionList = []; - if (this._requestVertexNormals && layerToUse.hasVertexNormals) { - extensionList.push(layerToUse.littleEndianExtensionSize ? 'octvertexnormals' : 'vertexnormals'); - } - if (this._requestWaterMask && layerToUse.hasWaterMask) { - extensionList.push('watermask'); - } - - var promise = loadArrayBuffer(url, getRequestHeader(extensionList), request); - - if (!defined(promise)) { - return undefined; - } - - var that = this; - return when(promise, function(buffer) { - if (defined(that._heightmapStructure)) { - return createHeightmapTerrainData(that, buffer, level, x, y, tmsY); - } - return createQuantizedMeshTerrainData(that, buffer, level, x, y, tmsY, layerToUse.littleEndianExtensionSize); - }); - }; + function TerrainProvider() { + DeveloperError.throwInstantiationError(); + } - defineProperties(CesiumTerrainProvider.prototype, { + defineProperties(TerrainProvider.prototype, { /** - * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing + * Gets an event that is raised when the terrain provider encounters an asynchronous error.. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners * are passed an instance of {@link TileProviderError}. - * @memberof CesiumTerrainProvider.prototype + * @memberof TerrainProvider.prototype * @type {Event} */ errorEvent : { - get : function() { - return this._errorEvent; - } + get : DeveloperError.throwInstantiationError }, /** * Gets the credit to display when this terrain provider is active. Typically this is used to credit - * the source of the terrain. This function should not be called before {@link CesiumTerrainProvider#ready} returns true. - * @memberof CesiumTerrainProvider.prototype + * the source of the terrain. This function should + * not be called before {@link TerrainProvider#ready} returns true. + * @memberof TerrainProvider.prototype * @type {Credit} */ credit : { - get : function() { - if (!this._ready) { - throw new DeveloperError('credit must not be called before the terrain provider is ready.'); - } - - return this._credit; - } + get : DeveloperError.throwInstantiationError }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link CesiumTerrainProvider#ready} returns true. - * @memberof CesiumTerrainProvider.prototype - * @type {GeographicTilingScheme} + * Gets the tiling scheme used by the provider. This function should + * not be called before {@link TerrainProvider#ready} returns true. + * @memberof TerrainProvider.prototype + * @type {TilingScheme} */ tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the terrain provider is ready.'); - } - - return this._tilingScheme; - } + get : DeveloperError.throwInstantiationError }, /** * Gets a value indicating whether or not the provider is ready for use. - * @memberof CesiumTerrainProvider.prototype + * @memberof TerrainProvider.prototype * @type {Boolean} */ ready : { - get : function() { - return this._ready; - } + get : DeveloperError.throwInstantiationError }, /** * Gets a promise that resolves to true when the provider is ready for use. - * @memberof CesiumTerrainProvider.prototype + * @memberof TerrainProvider.prototype * @type {Promise.<Boolean>} * @readonly */ readyPromise : { - get : function() { - return this._readyPromise.promise; - } + get : DeveloperError.throwInstantiationError }, /** * Gets a value indicating whether or not the provider includes a water mask. The water mask * indicates which areas of the globe are water rather than land, so they can be rendered * as a reflective surface with animated waves. This function should not be - * called before {@link CesiumTerrainProvider#ready} returns true. - * @memberof CesiumTerrainProvider.prototype + * called before {@link TerrainProvider#ready} returns true. + * @memberof TerrainProvider.prototype * @type {Boolean} - * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} */ hasWaterMask : { - get : function() { - if (!this._ready) { - throw new DeveloperError('hasWaterMask must not be called before the terrain provider is ready.'); - } - - return this._hasWaterMask && this._requestWaterMask; - } + get : DeveloperError.throwInstantiationError }, /** * Gets a value indicating whether or not the requested tiles include vertex normals. - * This function should not be called before {@link CesiumTerrainProvider#ready} returns true. - * @memberof CesiumTerrainProvider.prototype + * This function should not be called before {@link TerrainProvider#ready} returns true. + * @memberof TerrainProvider.prototype * @type {Boolean} - * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} */ hasVertexNormals : { - get : function() { - if (!this._ready) { - throw new DeveloperError('hasVertexNormals must not be called before the terrain provider is ready.'); - } - - // returns true if we can request vertex normals from the server - return this._hasVertexNormals && this._requestVertexNormals; - } - }, - - /** - * Boolean flag that indicates if the client should request vertex normals from the server. - * Vertex normals data is appended to the standard tile mesh data only if the client requests the vertex normals and - * if the server provides vertex normals. - * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} - */ - requestVertexNormals : { - get : function() { - return this._requestVertexNormals; - } - }, - - /** - * Boolean flag that indicates if the client should request a watermask from the server. - * Watermask data is appended to the standard tile mesh data only if the client requests the watermask and - * if the server provides a watermask. - * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} - */ - requestWaterMask : { - get : function() { - return this._requestWaterMask; - } + get : DeveloperError.throwInstantiationError }, /** * Gets an object that can be used to determine availability of terrain from this provider, such as * at points and in rectangles. This function should not be called before - * {@link CesiumTerrainProvider#ready} returns true. This property may be undefined if availability + * {@link TerrainProvider#ready} returns true. This property may be undefined if availability * information is not available. - * @memberof CesiumTerrainProvider.prototype + * @memberof TerrainProvider.prototype * @type {TileAvailability} */ availability : { - get : function() { - if (!this._ready) { - throw new DeveloperError('availability must not be called before the terrain provider is ready.'); + get : DeveloperError.throwInstantiationError + } + }); + + var regularGridIndexArrays = []; + + /** + * Gets a list of indices for a triangle mesh representing a regular grid. Calling + * this function multiple times with the same grid width and height returns the + * same list of indices. The total number of vertices must be less than or equal + * to 65536. + * + * @param {Number} width The number of vertices in the regular grid in the horizontal direction. + * @param {Number} height The number of vertices in the regular grid in the vertical direction. + * @returns {Uint16Array} The list of indices. + */ + TerrainProvider.getRegularGridIndices = function(width, height) { + if (width * height >= CesiumMath.SIXTY_FOUR_KILOBYTES) { + throw new DeveloperError('The total number of vertices (width * height) must be less than 65536.'); + } + + var byWidth = regularGridIndexArrays[width]; + if (!defined(byWidth)) { + regularGridIndexArrays[width] = byWidth = []; + } + + var indices = byWidth[height]; + if (!defined(indices)) { + indices = byWidth[height] = new Uint16Array((width - 1) * (height - 1) * 6); + + var index = 0; + var indicesIndex = 0; + for (var j = 0; j < height - 1; ++j) { + for (var i = 0; i < width - 1; ++i) { + var upperLeft = index; + var lowerLeft = upperLeft + width; + var lowerRight = lowerLeft + 1; + var upperRight = upperLeft + 1; + + indices[indicesIndex++] = upperLeft; + indices[indicesIndex++] = lowerLeft; + indices[indicesIndex++] = upperRight; + indices[indicesIndex++] = upperRight; + indices[indicesIndex++] = lowerLeft; + indices[indicesIndex++] = lowerRight; + + ++index; } - return this._availability; + ++index; } } - }); + + return indices; + }; /** - * Gets the maximum geometric error allowed in a tile at a given level. + * Specifies the quality of terrain created from heightmaps. A value of 1.0 will + * ensure that adjacent heightmap vertices are separated by no more than + * {@link Globe.maximumScreenSpaceError} screen pixels and will probably go very slowly. + * A value of 0.5 will cut the estimated level zero geometric error in half, allowing twice the + * screen pixels between adjacent heightmap vertices and thus rendering more quickly. + * @type {Number} + */ + TerrainProvider.heightmapTerrainQuality = 0.25; + + /** + * Determines an appropriate geometric error estimate when the geometry comes from a heightmap. + * + * @param {Ellipsoid} ellipsoid The ellipsoid to which the terrain is attached. + * @param {Number} tileImageWidth The width, in pixels, of the heightmap associated with a single tile. + * @param {Number} numberOfTilesAtLevelZero The number of tiles in the horizontal direction at tile level zero. + * @returns {Number} An estimated geometric error. + */ + TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap = function(ellipsoid, tileImageWidth, numberOfTilesAtLevelZero) { + return ellipsoid.maximumRadius * 2 * Math.PI * TerrainProvider.heightmapTerrainQuality / (tileImageWidth * numberOfTilesAtLevelZero); + }; + + /** + * Requests the geometry for a given tile. This function should not be called before + * {@link TerrainProvider#ready} returns true. The result must include terrain data and + * may optionally include a water mask and an indication of which child tiles are available. + * @function + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @param {Request} [request] The request object. Intended for internal use only. + * + * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * returns undefined instead of a promise, it is an indication that too many requests are already + * pending and the request will be retried later. + */ + TerrainProvider.prototype.requestTileGeometry = DeveloperError.throwInstantiationError; + + /** + * Gets the maximum geometric error allowed in a tile at a given level. This function should not be + * called before {@link TerrainProvider#ready} returns true. + * @function * * @param {Number} level The tile level for which to get the maximum geometric error. * @returns {Number} The maximum geometric error. */ - CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { - return this._levelZeroMaximumGeometricError / (1 << level); - }; + TerrainProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; /** * Determines whether data for a tile is available to be loaded. + * @function * * @param {Number} x The X coordinate of the tile for which to request geometry. * @param {Number} y The Y coordinate of the tile for which to request geometry. * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean} Undefined if not supported, otherwise true or false. + * @returns {Boolean} Undefined if not supported by the terrain provider, otherwise true or false. */ - CesiumTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { - if (!defined(this._availability)) { - return undefined; - } - - return this._availability.isTileAvailable(level, x, y); - }; + TerrainProvider.prototype.getTileDataAvailable = DeveloperError.throwInstantiationError; - return CesiumTerrainProvider; + return TerrainProvider; }); -define('Core/EllipseGeometryLibrary',[ - './Cartesian3', +define('Core/HeightmapTerrainData',[ + '../ThirdParty/when', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './GeographicTilingScheme', + './HeightmapTessellator', './Math', - './Matrix3', - './Quaternion' + './Rectangle', + './TaskProcessor', + './TerrainEncoding', + './TerrainMesh', + './TerrainProvider' ], function( - Cartesian3, + when, + defaultValue, + defined, + defineProperties, + DeveloperError, + GeographicTilingScheme, + HeightmapTessellator, CesiumMath, - Matrix3, - Quaternion) { + Rectangle, + TaskProcessor, + TerrainEncoding, + TerrainMesh, + TerrainProvider) { 'use strict'; - var EllipseGeometryLibrary = {}; - - var rotAxis = new Cartesian3(); - var tempVec = new Cartesian3(); - var unitQuat = new Quaternion(); - var rotMtx = new Matrix3(); - - function pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) { - var azimuth = theta + rotation; + /** + * Terrain data for a single tile where the terrain data is represented as a heightmap. A heightmap + * is a rectangular array of heights in row-major order from south to north and west to east. + * + * @alias HeightmapTerrainData + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {TypedArray} options.buffer The buffer containing height data. + * @param {Number} options.width The width (longitude direction) of the heightmap, in samples. + * @param {Number} options.height The height (latitude direction) of the heightmap, in samples. + * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. + * If a child's bit is set, geometry will be requested for that tile as well when it + * is needed. If the bit is cleared, the child tile is not requested and geometry is + * instead upsampled from the parent. The bit values are as follows: + * <table> + * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> + * <tr><td>0</td><td>1</td><td>Southwest</td></tr> + * <tr><td>1</td><td>2</td><td>Southeast</td></tr> + * <tr><td>2</td><td>4</td><td>Northwest</td></tr> + * <tr><td>3</td><td>8</td><td>Northeast</td></tr> + * </table> + * @param {Object} [options.structure] An object describing the structure of the height data. + * @param {Number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain + * the height above the heightOffset, in meters. The heightOffset is added to the resulting + * height after multiplying by the scale. + * @param {Number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final + * height in meters. The offset is added after the height sample is multiplied by the + * heightScale. + * @param {Number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height + * sample. This is usually 1, indicating that each element is a separate height sample. If + * it is greater than 1, that number of elements together form the height sample, which is + * computed according to the structure.elementMultiplier and structure.isBigEndian properties. + * @param {Number} [options.structure.stride=1] The number of elements to skip to get from the first element of + * one height to the first element of the next height. + * @param {Number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the + * stride property is greater than 1. For example, if the stride is 4 and the strideMultiplier + * is 256, the height is computed as follows: + * `height = buffer[index] + buffer[index + 1] * 256 + buffer[index + 2] * 256 * 256 + buffer[index + 3] * 256 * 256 * 256` + * This is assuming that the isBigEndian property is false. If it is true, the order of the + * elements is reversed. + * @param {Boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the + * stride property is greater than 1. If this property is false, the first element is the + * low-order element. If it is true, the first element is the high-order element. + * @param {Number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower + * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height + * buffer is a `Uint16Array`, this value should be 0 because a `Uint16Array` cannot store negative numbers. If this parameter is + * not specified, no minimum value is enforced. + * @param {Number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher + * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height + * buffer is a `Uint16Array`, this value should be `256 * 256 - 1` or 65535 because a `Uint16Array` cannot store numbers larger + * than 65535. If this parameter is not specified, no maximum value is enforced. + * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; + * otherwise, false. + * + * + * @example + * var buffer = ... + * var heightBuffer = new Uint16Array(buffer, 0, that._heightmapWidth * that._heightmapWidth); + * var childTileMask = new Uint8Array(buffer, heightBuffer.byteLength, 1)[0]; + * var waterMask = new Uint8Array(buffer, heightBuffer.byteLength + 1, buffer.byteLength - heightBuffer.byteLength - 1); + * var terrainData = new Cesium.HeightmapTerrainData({ + * buffer : heightBuffer, + * width : 65, + * height : 65, + * childTileMask : childTileMask, + * waterMask : waterMask + * }); + * + * @see TerrainData + * @see QuantizedMeshTerrainData + */ + function HeightmapTerrainData(options) { + if (!defined(options) || !defined(options.buffer)) { + throw new DeveloperError('options.buffer is required.'); + } + if (!defined(options.width)) { + throw new DeveloperError('options.width is required.'); + } + if (!defined(options.height)) { + throw new DeveloperError('options.height is required.'); + } + + this._buffer = options.buffer; + this._width = options.width; + this._height = options.height; + this._childTileMask = defaultValue(options.childTileMask, 15); - Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis); - Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec); - Cartesian3.add(rotAxis, tempVec, rotAxis); + var defaultStructure = HeightmapTessellator.DEFAULT_STRUCTURE; + var structure = options.structure; + if (!defined(structure)) { + structure = defaultStructure; + } else if (structure !== defaultStructure) { + structure.heightScale = defaultValue(structure.heightScale, defaultStructure.heightScale); + structure.heightOffset = defaultValue(structure.heightOffset, defaultStructure.heightOffset); + structure.elementsPerHeight = defaultValue(structure.elementsPerHeight, defaultStructure.elementsPerHeight); + structure.stride = defaultValue(structure.stride, defaultStructure.stride); + structure.elementMultiplier = defaultValue(structure.elementMultiplier, defaultStructure.elementMultiplier); + structure.isBigEndian = defaultValue(structure.isBigEndian, defaultStructure.isBigEndian); + } - var cosThetaSquared = Math.cos(theta); - cosThetaSquared = cosThetaSquared * cosThetaSquared; + this._structure = structure; + this._createdByUpsampling = defaultValue(options.createdByUpsampling, false); + this._waterMask = options.waterMask; - var sinThetaSquared = Math.sin(theta); - sinThetaSquared = sinThetaSquared * sinThetaSquared; + this._skirtHeight = undefined; + this._bufferType = this._buffer.constructor; + this._mesh = undefined; + } - var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared); - var angle = radius / mag; + defineProperties(HeightmapTerrainData.prototype, { + /** + * An array of credits for this tile. + * @memberof HeightmapTerrainData.prototype + * @type {Credit[]} + */ + credits : { + get : function() { + return undefined; + } + }, + /** + * The water mask included in this terrain data, if any. A water mask is a rectangular + * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. + * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. + * @memberof HeightmapTerrainData.prototype + * @type {Uint8Array|Image|Canvas} + */ + waterMask : { + get : function() { + return this._waterMask; + } + } + }); - // Create the quaternion to rotate the position vector to the boundary of the ellipse. - Quaternion.fromAxisAngle(rotAxis, angle, unitQuat); - Matrix3.fromQuaternion(unitQuat, rotMtx); - Matrix3.multiplyByVector(rotMtx, unitPos, result); - Cartesian3.normalize(result, result); - Cartesian3.multiplyByScalar(result, mag, result); - return result; - } + var taskProcessor = new TaskProcessor('createVerticesFromHeightmap'); - var scratchCartesian1 = new Cartesian3(); - var scratchCartesian2 = new Cartesian3(); - var scratchCartesian3 = new Cartesian3(); - var scratchNormal = new Cartesian3(); /** - * Returns the positions raised to the given heights + * Creates a {@link TerrainMesh} from this terrain data. + * * @private + * + * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} x The X coordinate of the tile for which to create the terrain data. + * @param {Number} y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} level The level of the tile for which to create the terrain data. + * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. + * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * asynchronous mesh creations are already in progress and the operation should + * be retried later. */ - EllipseGeometryLibrary.raisePositionsToHeight = function(positions, options, extrude) { - var ellipsoid = options.ellipsoid; - var height = options.height; - var extrudedHeight = options.extrudedHeight; - var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3; - - var finalPositions = new Float64Array(size * 3); + HeightmapTerrainData.prototype.createMesh = function(tilingScheme, x, y, level, exaggeration) { + if (!defined(tilingScheme)) { + throw new DeveloperError('tilingScheme is required.'); + } + if (!defined(x)) { + throw new DeveloperError('x is required.'); + } + if (!defined(y)) { + throw new DeveloperError('y is required.'); + } + if (!defined(level)) { + throw new DeveloperError('level is required.'); + } + + var ellipsoid = tilingScheme.ellipsoid; + var nativeRectangle = tilingScheme.tileXYToNativeRectangle(x, y, level); + var rectangle = tilingScheme.tileXYToRectangle(x, y, level); + exaggeration = defaultValue(exaggeration, 1.0); - var length = positions.length; - var bottomOffset = (extrude) ? length : 0; - for (var i = 0; i < length; i += 3) { - var i1 = i + 1; - var i2 = i + 2; + // Compute the center of the tile for RTC rendering. + var center = ellipsoid.cartographicToCartesian(Rectangle.center(rectangle)); - var position = Cartesian3.fromArray(positions, i, scratchCartesian1); - ellipsoid.scaleToGeodeticSurface(position, position); + var structure = this._structure; - var extrudedPosition = Cartesian3.clone(position, scratchCartesian2); - var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal); - var scaledNormal = Cartesian3.multiplyByScalar(normal, height, scratchCartesian3); - Cartesian3.add(position, scaledNormal, position); + var levelZeroMaxError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(ellipsoid, this._width, tilingScheme.getNumberOfXTilesAtLevel(0)); + var thisLevelMaxError = levelZeroMaxError / (1 << level); + this._skirtHeight = Math.min(thisLevelMaxError * 4.0, 1000.0); - if (extrude) { - Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal); - Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition); + var verticesPromise = taskProcessor.scheduleTask({ + heightmap : this._buffer, + structure : structure, + includeWebMercatorT : true, + width : this._width, + height : this._height, + nativeRectangle : nativeRectangle, + rectangle : rectangle, + relativeToCenter : center, + ellipsoid : ellipsoid, + skirtHeight : this._skirtHeight, + isGeographic : tilingScheme instanceof GeographicTilingScheme, + exaggeration : exaggeration + }); - finalPositions[i + bottomOffset] = extrudedPosition.x; - finalPositions[i1 + bottomOffset] = extrudedPosition.y; - finalPositions[i2 + bottomOffset] = extrudedPosition.z; - } + if (!defined(verticesPromise)) { + // Postponed + return undefined; + } - finalPositions[i] = position.x; - finalPositions[i1] = position.y; - finalPositions[i2] = position.z; + var that = this; + return when(verticesPromise, function(result) { + that._mesh = new TerrainMesh( + center, + new Float32Array(result.vertices), + TerrainProvider.getRegularGridIndices(result.gridWidth, result.gridHeight), + result.minimumHeight, + result.maximumHeight, + result.boundingSphere3D, + result.occludeePointInScaledSpace, + result.numberOfAttributes, + result.orientedBoundingBox, + TerrainEncoding.clone(result.encoding), + exaggeration); + + // Free memory received from server after mesh is created. + that._buffer = undefined; + return that._mesh; + }); + }; + + /** + * Computes the terrain height at a specified longitude and latitude. + * + * @param {Rectangle} rectangle The rectangle covered by this terrain data. + * @param {Number} longitude The longitude in radians. + * @param {Number} latitude The latitude in radians. + * @returns {Number} The terrain height at the specified position. If the position + * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly + * incorrect for positions far outside the rectangle. + */ + HeightmapTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) { + var width = this._width; + var height = this._height; + + var structure = this._structure; + var stride = structure.stride; + var elementsPerHeight = structure.elementsPerHeight; + var elementMultiplier = structure.elementMultiplier; + var isBigEndian = structure.isBigEndian; + var heightOffset = structure.heightOffset; + var heightScale = structure.heightScale; + + var heightSample; + if (defined(this._mesh)) { + var buffer = this._mesh.vertices; + var encoding = this._mesh.encoding; + var skirtHeight = this._skirtHeight; + var exaggeration = this._mesh.exaggeration; + heightSample = interpolateMeshHeight(buffer, encoding, heightOffset, heightScale, skirtHeight, rectangle, width, height, longitude, latitude, exaggeration); + } else { + heightSample = interpolateHeight(this._buffer, elementsPerHeight, elementMultiplier, stride, isBigEndian, rectangle, width, height, longitude, latitude); + heightSample = heightSample * heightScale + heightOffset; } - return finalPositions; + return heightSample; }; - var unitPosScratch = new Cartesian3(); - var eastVecScratch = new Cartesian3(); - var northVecScratch = new Cartesian3(); /** - * Returns an array of positions that make up the ellipse. - * @private + * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the + * height samples in this instance, interpolated if necessary. + * + * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. + * @param {Number} thisX The X coordinate of this tile in the tiling scheme. + * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {Number} thisLevel The level of this tile in the tiling scheme. + * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise.<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, + * or undefined if too many asynchronous upsample operations are in progress and the request has been + * deferred. */ - EllipseGeometryLibrary.computeEllipsePositions = function(options, addFillPositions, addEdgePositions) { - var semiMinorAxis = options.semiMinorAxis; - var semiMajorAxis = options.semiMajorAxis; - var rotation = options.rotation; - var center = options.center; + HeightmapTerrainData.prototype.upsample = function(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) { + if (!defined(tilingScheme)) { + throw new DeveloperError('tilingScheme is required.'); + } + if (!defined(thisX)) { + throw new DeveloperError('thisX is required.'); + } + if (!defined(thisY)) { + throw new DeveloperError('thisY is required.'); + } + if (!defined(thisLevel)) { + throw new DeveloperError('thisLevel is required.'); + } + if (!defined(descendantX)) { + throw new DeveloperError('descendantX is required.'); + } + if (!defined(descendantY)) { + throw new DeveloperError('descendantY is required.'); + } + if (!defined(descendantLevel)) { + throw new DeveloperError('descendantLevel is required.'); + } + var levelDifference = descendantLevel - thisLevel; + if (levelDifference > 1) { + throw new DeveloperError('Upsampling through more than one level at a time is not currently supported.'); + } + + var width = this._width; + var height = this._height; + var structure = this._structure; + var skirtHeight = this._skirtHeight; + var stride = structure.stride; - // Computing the arc-length of the ellipse is too expensive to be practical. Estimating it using the - // arc length of the sphere is too inaccurate and creates sharp edges when either the semi-major or - // semi-minor axis is much bigger than the other. Instead, scale the angle delta to make - // the distance along the ellipse boundary more closely match the granularity. - var granularity = options.granularity * 8.0; + var heights = new this._bufferType(width * height * stride); + var meshData = this._mesh; + if (!defined(meshData)) { + return undefined; + } - var aSqr = semiMinorAxis * semiMinorAxis; - var bSqr = semiMajorAxis * semiMajorAxis; - var ab = semiMajorAxis * semiMinorAxis; + var buffer = meshData.vertices; + var encoding = meshData.encoding; - var mag = Cartesian3.magnitude(center); + // PERFORMANCE_IDEA: don't recompute these rectangles - the caller already knows them. + var sourceRectangle = tilingScheme.tileXYToRectangle(thisX, thisY, thisLevel); + var destinationRectangle = tilingScheme.tileXYToRectangle(descendantX, descendantY, descendantLevel); - var unitPos = Cartesian3.normalize(center, unitPosScratch); - var eastVec = Cartesian3.cross(Cartesian3.UNIT_Z, center, eastVecScratch); - eastVec = Cartesian3.normalize(eastVec, eastVec); - var northVec = Cartesian3.cross(unitPos, eastVec, northVecScratch); + var heightOffset = structure.heightOffset; + var heightScale = structure.heightScale; + var exaggeration = meshData.exaggeration; - // The number of points in the first quadrant - var numPts = 1 + Math.ceil(CesiumMath.PI_OVER_TWO / granularity); + var elementsPerHeight = structure.elementsPerHeight; + var elementMultiplier = structure.elementMultiplier; + var isBigEndian = structure.isBigEndian; - var deltaTheta = CesiumMath.PI_OVER_TWO / (numPts - 1); - var theta = CesiumMath.PI_OVER_TWO - numPts * deltaTheta; - if (theta < 0.0) { - numPts -= Math.ceil(Math.abs(theta) / deltaTheta); - } + var divisor = Math.pow(elementMultiplier, elementsPerHeight - 1); - // If the number of points were three, the ellipse - // would be tessellated like below: - // - // *---* - // / | \ | \ - // *---*---*---* - // / | \ | \ | \ | \ - // / .*---*---*---*. \ - // * ` | \ | \ | \ | `* - // \`.*---*---*---*.`/ - // \ | \ | \ | \ | / - // *---*---*---* - // \ | \ | / - // *---* - // The first and last column have one position and fan to connect to the adjacent column. - // Each other vertical column contains an even number of positions. - var size = 2 * (numPts * (numPts + 2)); - var positions = (addFillPositions) ? new Array(size * 3) : undefined; - var positionIndex = 0; - var position = scratchCartesian1; - var reflectedPosition = scratchCartesian2; + for (var j = 0; j < height; ++j) { + var latitude = CesiumMath.lerp(destinationRectangle.north, destinationRectangle.south, j / (height - 1)); + for (var i = 0; i < width; ++i) { + var longitude = CesiumMath.lerp(destinationRectangle.west, destinationRectangle.east, i / (width - 1)); + var heightSample = interpolateMeshHeight(buffer, encoding, heightOffset, heightScale, skirtHeight, sourceRectangle, width, height, longitude, latitude, exaggeration); - var outerPositionsLength = (numPts * 4) * 3; - var outerRightIndex = outerPositionsLength - 1; - var outerLeftIndex = 0; - var outerPositions = (addEdgePositions) ? new Array(outerPositionsLength) : undefined; + // Use conditionals here instead of Math.min and Math.max so that an undefined + // lowestEncodedHeight or highestEncodedHeight has no effect. + heightSample = heightSample < structure.lowestEncodedHeight ? structure.lowestEncodedHeight : heightSample; + heightSample = heightSample > structure.highestEncodedHeight ? structure.highestEncodedHeight : heightSample; - var i; - var j; - var numInterior; - var t; - var interiorPosition; + setHeight(heights, elementsPerHeight, elementMultiplier, divisor, stride, isBigEndian, j * width + i, heightSample); + } + } - // Compute points in the 'eastern' half of the ellipse - theta = CesiumMath.PI_OVER_TWO; - position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); - if (addFillPositions) { - positions[positionIndex++] = position.x; - positions[positionIndex++] = position.y; - positions[positionIndex++] = position.z; + return new HeightmapTerrainData({ + buffer : heights, + width : width, + height : height, + childTileMask : 0, + structure : this._structure, + createdByUpsampling : true + }); + }; + + /** + * Determines if a given child tile is available, based on the + * {@link HeightmapTerrainData.childTileMask}. The given child tile coordinates are assumed + * to be one of the four children of this tile. If non-child tile coordinates are + * given, the availability of the southeast child tile is returned. + * + * @param {Number} thisX The tile X coordinate of this (the parent) tile. + * @param {Number} thisY The tile Y coordinate of this (the parent) tile. + * @param {Number} childX The tile X coordinate of the child tile to check for availability. + * @param {Number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {Boolean} True if the child tile is available; otherwise, false. + */ + HeightmapTerrainData.prototype.isChildAvailable = function(thisX, thisY, childX, childY) { + if (!defined(thisX)) { + throw new DeveloperError('thisX is required.'); } - if (addEdgePositions) { - outerPositions[outerRightIndex--] = position.z; - outerPositions[outerRightIndex--] = position.y; - outerPositions[outerRightIndex--] = position.x; + if (!defined(thisY)) { + throw new DeveloperError('thisY is required.'); + } + if (!defined(childX)) { + throw new DeveloperError('childX is required.'); + } + if (!defined(childY)) { + throw new DeveloperError('childY is required.'); + } + + var bitNumber = 2; // northwest child + if (childX !== thisX * 2) { + ++bitNumber; // east child + } + if (childY !== thisY * 2) { + bitNumber -= 2; // south child } - theta = CesiumMath.PI_OVER_TWO - deltaTheta; - for (i = 1; i < numPts + 1; ++i) { - position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); - reflectedPosition = pointOnEllipsoid(Math.PI - theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition); - if (addFillPositions) { - positions[positionIndex++] = position.x; - positions[positionIndex++] = position.y; - positions[positionIndex++] = position.z; + return (this._childTileMask & (1 << bitNumber)) !== 0; + }; - numInterior = 2 * i + 2; - for (j = 1; j < numInterior - 1; ++j) { - t = j / (numInterior - 1); - interiorPosition = Cartesian3.lerp(position, reflectedPosition, t, scratchCartesian3); - positions[positionIndex++] = interiorPosition.x; - positions[positionIndex++] = interiorPosition.y; - positions[positionIndex++] = interiorPosition.z; - } + /** + * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution + * terrain data. If this value is false, the data was obtained from some other source, such + * as by downloading it from a remote server. This method should return true for instances + * returned from a call to {@link HeightmapTerrainData#upsample}. + * + * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + */ + HeightmapTerrainData.prototype.wasCreatedByUpsampling = function() { + return this._createdByUpsampling; + }; - positions[positionIndex++] = reflectedPosition.x; - positions[positionIndex++] = reflectedPosition.y; - positions[positionIndex++] = reflectedPosition.z; - } + function interpolateHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, sourceRectangle, width, height, longitude, latitude) { + var fromWest = (longitude - sourceRectangle.west) * (width - 1) / (sourceRectangle.east - sourceRectangle.west); + var fromSouth = (latitude - sourceRectangle.south) * (height - 1) / (sourceRectangle.north - sourceRectangle.south); - if (addEdgePositions) { - outerPositions[outerRightIndex--] = position.z; - outerPositions[outerRightIndex--] = position.y; - outerPositions[outerRightIndex--] = position.x; - outerPositions[outerLeftIndex++] = reflectedPosition.x; - outerPositions[outerLeftIndex++] = reflectedPosition.y; - outerPositions[outerLeftIndex++] = reflectedPosition.z; - } + var westInteger = fromWest | 0; + var eastInteger = westInteger + 1; + if (eastInteger >= width) { + eastInteger = width - 1; + westInteger = width - 2; + } - theta = CesiumMath.PI_OVER_TWO - (i + 1) * deltaTheta; + var southInteger = fromSouth | 0; + var northInteger = southInteger + 1; + if (northInteger >= height) { + northInteger = height - 1; + southInteger = height - 2; } - // Compute points in the 'western' half of the ellipse - for (i = numPts; i > 1; --i) { - theta = CesiumMath.PI_OVER_TWO - (i - 1) * deltaTheta; + var dx = fromWest - westInteger; + var dy = fromSouth - southInteger; - position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); - reflectedPosition = pointOnEllipsoid(theta + Math.PI, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition); + southInteger = height - 1 - southInteger; + northInteger = height - 1 - northInteger; - if (addFillPositions) { - positions[positionIndex++] = position.x; - positions[positionIndex++] = position.y; - positions[positionIndex++] = position.z; + var southwestHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, southInteger * width + westInteger); + var southeastHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, southInteger * width + eastInteger); + var northwestHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, northInteger * width + westInteger); + var northeastHeight = getHeight(sourceHeights, elementsPerHeight, elementMultiplier, stride, isBigEndian, northInteger * width + eastInteger); - numInterior = 2 * (i - 1) + 2; - for (j = 1; j < numInterior - 1; ++j) { - t = j / (numInterior - 1); - interiorPosition = Cartesian3.lerp(position, reflectedPosition, t, scratchCartesian3); - positions[positionIndex++] = interiorPosition.x; - positions[positionIndex++] = interiorPosition.y; - positions[positionIndex++] = interiorPosition.z; - } + return triangleInterpolateHeight(dx, dy, southwestHeight, southeastHeight, northwestHeight, northeastHeight); + } - positions[positionIndex++] = reflectedPosition.x; - positions[positionIndex++] = reflectedPosition.y; - positions[positionIndex++] = reflectedPosition.z; - } + function interpolateMeshHeight(buffer, encoding, heightOffset, heightScale, skirtHeight, sourceRectangle, width, height, longitude, latitude, exaggeration) { + // returns a height encoded according to the structure's heightScale and heightOffset. + var fromWest = (longitude - sourceRectangle.west) * (width - 1) / (sourceRectangle.east - sourceRectangle.west); + var fromSouth = (latitude - sourceRectangle.south) * (height - 1) / (sourceRectangle.north - sourceRectangle.south); - if (addEdgePositions) { - outerPositions[outerRightIndex--] = position.z; - outerPositions[outerRightIndex--] = position.y; - outerPositions[outerRightIndex--] = position.x; - outerPositions[outerLeftIndex++] = reflectedPosition.x; - outerPositions[outerLeftIndex++] = reflectedPosition.y; - outerPositions[outerLeftIndex++] = reflectedPosition.z; - } + if (skirtHeight > 0) { + fromWest += 1.0; + fromSouth += 1.0; + + width += 2; + height += 2; } - theta = CesiumMath.PI_OVER_TWO; - position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); + var widthEdge = (skirtHeight > 0) ? width - 1 : width; + var westInteger = fromWest | 0; + var eastInteger = westInteger + 1; + if (eastInteger >= widthEdge) { + eastInteger = width - 1; + westInteger = width - 2; + } - var r = {}; - if (addFillPositions) { - positions[positionIndex++] = position.x; - positions[positionIndex++] = position.y; - positions[positionIndex++] = position.z; - r.positions = positions; - r.numPts = numPts; + var heightEdge = (skirtHeight > 0) ? height - 1 : height; + var southInteger = fromSouth | 0; + var northInteger = southInteger + 1; + if (northInteger >= heightEdge) { + northInteger = height - 1; + southInteger = height - 2; } - if (addEdgePositions) { - outerPositions[outerRightIndex--] = position.z; - outerPositions[outerRightIndex--] = position.y; - outerPositions[outerRightIndex--] = position.x; - r.outerPositions = outerPositions; + + var dx = fromWest - westInteger; + var dy = fromSouth - southInteger; + + southInteger = height - 1 - southInteger; + northInteger = height - 1 - northInteger; + + var southwestHeight = (encoding.decodeHeight(buffer, southInteger * width + westInteger) / exaggeration - heightOffset) / heightScale; + var southeastHeight = (encoding.decodeHeight(buffer, southInteger * width + eastInteger) / exaggeration - heightOffset) / heightScale; + var northwestHeight = (encoding.decodeHeight(buffer, northInteger * width + westInteger) / exaggeration - heightOffset) / heightScale; + var northeastHeight = (encoding.decodeHeight(buffer, northInteger * width + eastInteger) / exaggeration - heightOffset) / heightScale; + + return triangleInterpolateHeight(dx, dy, southwestHeight, southeastHeight, northwestHeight, northeastHeight); + } + + function triangleInterpolateHeight(dX, dY, southwestHeight, southeastHeight, northwestHeight, northeastHeight) { + // The HeightmapTessellator bisects the quad from southwest to northeast. + if (dY < dX) { + // Lower right triangle + return southwestHeight + (dX * (southeastHeight - southwestHeight)) + (dY * (northeastHeight - southeastHeight)); } - return r; - }; + // Upper left triangle + return southwestHeight + (dX * (northeastHeight - northwestHeight)) + (dY * (northwestHeight - southwestHeight)); + } - return EllipseGeometryLibrary; + function getHeight(heights, elementsPerHeight, elementMultiplier, stride, isBigEndian, index) { + index *= stride; + + var height = 0; + var i; + + if (isBigEndian) { + for (i = 0; i < elementsPerHeight; ++i) { + height = (height * elementMultiplier) + heights[index + i]; + } + } else { + for (i = elementsPerHeight - 1; i >= 0; --i) { + height = (height * elementMultiplier) + heights[index + i]; + } + } + + return height; + } + + function setHeight(heights, elementsPerHeight, elementMultiplier, divisor, stride, isBigEndian, index, height) { + index *= stride; + + var i; + if (isBigEndian) { + for (i = 0; i < elementsPerHeight - 1; ++i) { + heights[index + i] = (height / divisor) | 0; + height -= heights[index + i] * divisor; + divisor /= elementMultiplier; + } + } else { + for (i = elementsPerHeight - 1; i > 0; --i) { + heights[index + i] = (height / divisor) | 0; + height -= heights[index + i] * divisor; + divisor /= elementMultiplier; + } + } + heights[index + i] = height; + } + + return HeightmapTerrainData; }); -define('Core/GeometryInstance',[ - './defaultValue', +define('Core/IndexDatatype',[ './defined', './DeveloperError', - './Matrix4' + './freezeObject', + './Math', + './WebGLConstants' ], function( - defaultValue, defined, DeveloperError, - Matrix4) { + freezeObject, + CesiumMath, + WebGLConstants) { 'use strict'; /** - * Geometry instancing allows one {@link Geometry} object to be positions in several - * different locations and colored uniquely. For example, one {@link BoxGeometry} can - * be instanced several times, each with a different <code>modelMatrix</code> to change - * its position, rotation, and scale. - * - * @alias GeometryInstance - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Geometry} options.geometry The geometry to instance. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix that transforms to transform the geometry from model to world coordinates. - * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} or get/set per-instance attributes with {@link Primitive#getGeometryInstanceAttributes}. - * @param {Object} [options.attributes] Per-instance attributes like a show or color attribute shown in the example below. - * - * - * @example - * // Create geometry for a box, and two instances that refer to it. - * // One instance positions the box on the bottom and colored aqua. - * // The other instance positions the box on the top and color white. - * var geometry = Cesium.BoxGeometry.fromDimensions({ - * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL, - * dimensions : new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0) - * }); - * var instanceBottom = new Cesium.GeometryInstance({ - * geometry : geometry, - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) - * }, - * id : 'bottom' - * }); - * var instanceTop = new Cesium.GeometryInstance({ - * geometry : geometry, - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 3000000.0), new Cesium.Matrix4()), - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) - * }, - * id : 'top' - * }); + * Constants for WebGL index datatypes. These corresponds to the + * <code>type</code> parameter of {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glDrawElements.xml|drawElements}. * - * @see Geometry + * @exports IndexDatatype */ - function GeometryInstance(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (!defined(options.geometry)) { - throw new DeveloperError('options.geometry is required.'); - } - - /** - * The geometry being instanced. - * - * @type Geometry - * - * @default undefined - */ - this.geometry = options.geometry; - - /** - * The 4x4 transformation matrix that transforms the geometry from model to world coordinates. - * When this is the identity matrix, the geometry is drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. - * - * @type Matrix4 - * - * @default Matrix4.IDENTITY - */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - + var IndexDatatype = { /** - * User-defined object returned when the instance is picked or used to get/set per-instance attributes. - * - * @type Object - * - * @default undefined + * 8-bit unsigned byte corresponding to <code>UNSIGNED_BYTE</code> and the type + * of an element in <code>Uint8Array</code>. * - * @see Scene#pick - * @see Primitive#getGeometryInstanceAttributes + * @type {Number} + * @constant */ - this.id = options.id; + UNSIGNED_BYTE : WebGLConstants.UNSIGNED_BYTE, /** - * Used for picking primitives that wrap geometry instances. + * 16-bit unsigned short corresponding to <code>UNSIGNED_SHORT</code> and the type + * of an element in <code>Uint16Array</code>. * - * @private + * @type {Number} + * @constant */ - this.pickPrimitive = options.pickPrimitive; + UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT, /** - * Per-instance attributes like {@link ColorGeometryInstanceAttribute} or {@link ShowGeometryInstanceAttribute}. - * {@link Geometry} attributes varying per vertex; these attributes are constant for the entire instance. - * - * @type Object + * 32-bit unsigned int corresponding to <code>UNSIGNED_INT</code> and the type + * of an element in <code>Uint32Array</code>. * - * @default undefined - */ - this.attributes = defaultValue(options.attributes, {}); - - /** - * @private - */ - this.westHemisphereGeometry = undefined; - /** - * @private + * @type {Number} + * @constant */ - this.eastHemisphereGeometry = undefined; - } - - return GeometryInstance; -}); - -define('Core/EncodedCartesian3',[ - './Cartesian3', - './Check', - './defined' - ], function( - Cartesian3, - Check, - defined) { - 'use strict'; + UNSIGNED_INT : WebGLConstants.UNSIGNED_INT + }; /** - * A fixed-point encoding of a {@link Cartesian3} with 64-bit floating-point components, as two {@link Cartesian3} - * values that, when converted to 32-bit floating-point and added, approximate the original input. - * <p> - * This is used to encode positions in vertex buffers for rendering without jittering artifacts - * as described in {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. - * </p> + * Returns the size, in bytes, of the corresponding datatype. * - * @alias EncodedCartesian3 - * @constructor + * @param {IndexDatatype} indexDatatype The index datatype to get the size of. + * @returns {Number} The size in bytes. * - * @private + * @example + * // Returns 2 + * var size = Cesium.IndexDatatype.getSizeInBytes(Cesium.IndexDatatype.UNSIGNED_SHORT); */ - function EncodedCartesian3() { - /** - * The high bits for each component. Bits 0 to 22 store the whole value. Bits 23 to 31 are not used. - * - * @type {Cartesian3} - * @default {@link Cartesian3.ZERO} - */ - this.high = Cartesian3.clone(Cartesian3.ZERO); + IndexDatatype.getSizeInBytes = function(indexDatatype) { + switch(indexDatatype) { + case IndexDatatype.UNSIGNED_BYTE: + return Uint8Array.BYTES_PER_ELEMENT; + case IndexDatatype.UNSIGNED_SHORT: + return Uint16Array.BYTES_PER_ELEMENT; + case IndexDatatype.UNSIGNED_INT: + return Uint32Array.BYTES_PER_ELEMENT; + } - /** - * The low bits for each component. Bits 7 to 22 store the whole value, and bits 0 to 6 store the fraction. Bits 23 to 31 are not used. - * - * @type {Cartesian3} - * @default {@link Cartesian3.ZERO} - */ - this.low = Cartesian3.clone(Cartesian3.ZERO); - } + throw new DeveloperError('indexDatatype is required and must be a valid IndexDatatype constant.'); + }; /** - * Encodes a 64-bit floating-point value as two floating-point values that, when converted to - * 32-bit floating-point and added, approximate the original input. The returned object - * has <code>high</code> and <code>low</code> properties for the high and low bits, respectively. - * <p> - * The fixed-point encoding follows {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. - * </p> + * Validates that the provided index datatype is a valid {@link IndexDatatype}. * - * @param {Number} value The floating-point value to encode. - * @param {Object} [result] The object onto which to store the result. - * @returns {Object} The modified result parameter or a new instance if one was not provided. + * @param {IndexDatatype} indexDatatype The index datatype to validate. + * @returns {Boolean} <code>true</code> if the provided index datatype is a valid value; otherwise, <code>false</code>. * * @example - * var value = 1234567.1234567; - * var splitValue = Cesium.EncodedCartesian3.encode(value); + * if (!Cesium.IndexDatatype.validate(indexDatatype)) { + * throw new Cesium.DeveloperError('indexDatatype must be a valid value.'); + * } */ - EncodedCartesian3.encode = function(value, result) { - Check.typeOf.number('value', value); - - if (!defined(result)) { - result = { - high : 0.0, - low : 0.0 - }; - } - - var doubleHigh; - if (value >= 0.0) { - doubleHigh = Math.floor(value / 65536.0) * 65536.0; - result.high = doubleHigh; - result.low = value - doubleHigh; - } else { - doubleHigh = Math.floor(-value / 65536.0) * 65536.0; - result.high = -doubleHigh; - result.low = value + doubleHigh; - } - - return result; - }; - - var scratchEncode = { - high : 0.0, - low : 0.0 + IndexDatatype.validate = function(indexDatatype) { + return defined(indexDatatype) && + (indexDatatype === IndexDatatype.UNSIGNED_BYTE || + indexDatatype === IndexDatatype.UNSIGNED_SHORT || + indexDatatype === IndexDatatype.UNSIGNED_INT); }; /** - * Encodes a {@link Cartesian3} with 64-bit floating-point components as two {@link Cartesian3} - * values that, when converted to 32-bit floating-point and added, approximate the original input. - * <p> - * The fixed-point encoding follows {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. - * </p> + * Creates a typed array that will store indices, using either <code><Uint16Array</code> + * or <code>Uint32Array</code> depending on the number of vertices. * - * @param {Cartesian3} cartesian The cartesian to encode. - * @param {EncodedCartesian3} [result] The object onto which to store the result. - * @returns {EncodedCartesian3} The modified result parameter or a new EncodedCartesian3 instance if one was not provided. + * @param {Number} numberOfVertices Number of vertices that the indices will reference. + * @param {*} indicesLengthOrArray Passed through to the typed array constructor. + * @returns {Uint16Array|Uint32Array} A <code>Uint16Array</code> or <code>Uint32Array</code> constructed with <code>indicesLengthOrArray</code>. * * @example - * var cart = new Cesium.Cartesian3(-10000000.0, 0.0, 10000000.0); - * var encoded = Cesium.EncodedCartesian3.fromCartesian(cart); + * this.indices = Cesium.IndexDatatype.createTypedArray(positions.length / 3, numberOfIndices); */ - EncodedCartesian3.fromCartesian = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); + IndexDatatype.createTypedArray = function(numberOfVertices, indicesLengthOrArray) { + if (!defined(numberOfVertices)) { + throw new DeveloperError('numberOfVertices is required.'); + } - if (!defined(result)) { - result = new EncodedCartesian3(); + if (numberOfVertices >= CesiumMath.SIXTY_FOUR_KILOBYTES) { + return new Uint32Array(indicesLengthOrArray); } - var high = result.high; - var low = result.low; - - EncodedCartesian3.encode(cartesian.x, scratchEncode); - high.x = scratchEncode.high; - low.x = scratchEncode.low; - - EncodedCartesian3.encode(cartesian.y, scratchEncode); - high.y = scratchEncode.high; - low.y = scratchEncode.low; - - EncodedCartesian3.encode(cartesian.z, scratchEncode); - high.z = scratchEncode.high; - low.z = scratchEncode.low; - - return result; + return new Uint16Array(indicesLengthOrArray); }; - var encodedP = new EncodedCartesian3(); - /** - * Encodes the provided <code>cartesian</code>, and writes it to an array with <code>high</code> - * components followed by <code>low</code> components, i.e. <code>[high.x, high.y, high.z, low.x, low.y, low.z]</code>. - * <p> - * This is used to create interleaved high-precision position vertex attributes. - * </p> - * - * @param {Cartesian3} cartesian The cartesian to encode. - * @param {Number[]} cartesianArray The array to write to. - * @param {Number} index The index into the array to start writing. Six elements will be written. + * Creates a typed array from a source array buffer. The resulting typed array will store indices, using either <code><Uint16Array</code> + * or <code>Uint32Array</code> depending on the number of vertices. * - * @exception {DeveloperError} index must be a number greater than or equal to 0. + * @param {Number} numberOfVertices Number of vertices that the indices will reference. + * @param {ArrayBuffer} sourceArray Passed through to the typed array constructor. + * @param {Number} byteOffset Passed through to the typed array constructor. + * @param {Number} length Passed through to the typed array constructor. + * @returns {Uint16Array|Uint32Array} A <code>Uint16Array</code> or <code>Uint32Array</code> constructed with <code>sourceArray</code>, <code>byteOffset</code>, and <code>length</code>. * - * @example - * var positions = [ - * new Cesium.Cartesian3(), - * // ... - * ]; - * var encodedPositions = new Float32Array(2 * 3 * positions.length); - * var j = 0; - * for (var i = 0; i < positions.length; ++i) { - * Cesium.EncodedCartesian3.writeElement(positions[i], encodedPositions, j); - * j += 6; - * } */ - EncodedCartesian3.writeElements = function(cartesian, cartesianArray, index) { - Check.defined('cartesianArray', cartesianArray); - Check.typeOf.number('index', index); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); + IndexDatatype.createTypedArrayFromArrayBuffer = function(numberOfVertices, sourceArray, byteOffset, length) { + if (!defined(numberOfVertices)) { + throw new DeveloperError('numberOfVertices is required.'); + } + if (!defined(sourceArray)) { + throw new DeveloperError('sourceArray is required.'); + } + if (!defined(byteOffset)) { + throw new DeveloperError('byteOffset is required.'); + } - EncodedCartesian3.fromCartesian(cartesian, encodedP); - var high = encodedP.high; - var low = encodedP.low; + if (numberOfVertices >= CesiumMath.SIXTY_FOUR_KILOBYTES) { + return new Uint32Array(sourceArray, byteOffset, length); + } - cartesianArray[index] = high.x; - cartesianArray[index + 1] = high.y; - cartesianArray[index + 2] = high.z; - cartesianArray[index + 3] = low.x; - cartesianArray[index + 4] = low.y; - cartesianArray[index + 5] = low.z; + return new Uint16Array(sourceArray, byteOffset, length); }; - return EncodedCartesian3; + return freezeObject(IndexDatatype); }); -define('Core/Tipsify',[ - './defaultValue', +define('Core/Intersections2D',[ + './Cartesian3', './defined', './DeveloperError' ], function( - defaultValue, + Cartesian3, defined, DeveloperError) { 'use strict'; /** - * Encapsulates an algorithm to optimize triangles for the post - * vertex-shader cache. This is based on the 2007 SIGGRAPH paper - * 'Fast Triangle Reordering for Vertex Locality and Reduced Overdraw.' - * The runtime is linear but several passes are made. - * - * @exports Tipsify - * - * @see <a href='http://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf'> - * Fast Triangle Reordering for Vertex Locality and Reduced Overdraw</a> - * by Sander, Nehab, and Barczak + * Contains functions for operating on 2D triangles. * - * @private + * @exports Intersections2D */ - var Tipsify = {}; + var Intersections2D = {}; /** - * Calculates the average cache miss ratio (ACMR) for a given set of indices. - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices - * in the vertex buffer that define the geometry's triangles. - * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. - * If not supplied, this value will be computed. - * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. - * @returns {Number} The average cache miss ratio (ACMR). + * Splits a 2D triangle at given axis-aligned threshold value and returns the resulting + * polygon on a given side of the threshold. The resulting polygon may have 0, 1, 2, + * 3, or 4 vertices. * - * @exception {DeveloperError} indices length must be a multiple of three. - * @exception {DeveloperError} cacheSize must be greater than two. + * @param {Number} threshold The threshold coordinate value at which to clip the triangle. + * @param {Boolean} keepAbove true to keep the portion of the triangle above the threshold, or false + * to keep the portion below. + * @param {Number} u0 The coordinate of the first vertex in the triangle, in counter-clockwise order. + * @param {Number} u1 The coordinate of the second vertex in the triangle, in counter-clockwise order. + * @param {Number} u2 The coordinate of the third vertex in the triangle, in counter-clockwise order. + * @param {Number[]} [result] The array into which to copy the result. If this parameter is not supplied, + * a new array is constructed and returned. + * @returns {Number[]} The polygon that results after the clip, specified as a list of + * vertices. The vertices are specified in counter-clockwise order. + * Each vertex is either an index from the existing list (identified as + * a 0, 1, or 2) or -1 indicating a new vertex not in the original triangle. + * For new vertices, the -1 is followed by three additional numbers: the + * index of each of the two original vertices forming the line segment that + * the new vertex lies on, and the fraction of the distance from the first + * vertex to the second one. * * @example - * var indices = [0, 1, 2, 3, 4, 5]; - * var maxIndex = 5; - * var cacheSize = 3; - * var acmr = Cesium.Tipsify.calculateACMR({indices : indices, maxIndex : maxIndex, cacheSize : cacheSize}); + * var result = Cesium.Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, false, 0.2, 0.6, 0.4); + * // result === [2, 0, -1, 1, 0, 0.25, -1, 1, 2, 0.5] */ - Tipsify.calculateACMR = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var indices = options.indices; - var maximumIndex = options.maximumIndex; - var cacheSize = defaultValue(options.cacheSize, 24); - - if (!defined(indices)) { - throw new DeveloperError('indices is required.'); + Intersections2D.clipTriangleAtAxisAlignedThreshold = function(threshold, keepAbove, u0, u1, u2, result) { + if (!defined(threshold)) { + throw new DeveloperError('threshold is required.'); } - - var numIndices = indices.length; - - if (numIndices < 3 || numIndices % 3 !== 0) { - throw new DeveloperError('indices length must be a multiple of three.'); + if (!defined(keepAbove)) { + throw new DeveloperError('keepAbove is required.'); } - if (maximumIndex <= 0) { - throw new DeveloperError('maximumIndex must be greater than zero.'); + if (!defined(u0)) { + throw new DeveloperError('u0 is required.'); } - if (cacheSize < 3) { - throw new DeveloperError('cacheSize must be greater than two.'); + if (!defined(u1)) { + throw new DeveloperError('u1 is required.'); + } + if (!defined(u2)) { + throw new DeveloperError('u2 is required.'); } - // Compute the maximumIndex if not given - if (!defined(maximumIndex)) { - maximumIndex = 0; - var currentIndex = 0; - var intoIndices = indices[currentIndex]; - while (currentIndex < numIndices) { - if (intoIndices > maximumIndex) { - maximumIndex = intoIndices; - } - ++currentIndex; - intoIndices = indices[currentIndex]; - } + if (!defined(result)) { + result = []; + } else { + result.length = 0; } - // Vertex time stamps - var vertexTimeStamps = []; - for ( var i = 0; i < maximumIndex + 1; i++) { - vertexTimeStamps[i] = 0; + var u0Behind; + var u1Behind; + var u2Behind; + if (keepAbove) { + u0Behind = u0 < threshold; + u1Behind = u1 < threshold; + u2Behind = u2 < threshold; + } else { + u0Behind = u0 > threshold; + u1Behind = u1 > threshold; + u2Behind = u2 > threshold; } - // Cache processing - var s = cacheSize + 1; - for ( var j = 0; j < numIndices; ++j) { - if ((s - vertexTimeStamps[indices[j]]) > cacheSize) { - vertexTimeStamps[indices[j]] = s; - ++s; - } - } + var numBehind = u0Behind + u1Behind + u2Behind; - return (s - cacheSize + 1) / (numIndices / 3); - }; + var u01Ratio; + var u02Ratio; + var u12Ratio; + var u10Ratio; + var u20Ratio; + var u21Ratio; - /** - * Optimizes triangles for the post-vertex shader cache. - * - * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices - * in the vertex buffer that define the geometry's triangles. - * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. - * If not supplied, this value will be computed. - * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. - * @returns {Number[]} A list of the input indices in an optimized order. - * - * @exception {DeveloperError} indices length must be a multiple of three. - * @exception {DeveloperError} cacheSize must be greater than two. - * - * @example - * var indices = [0, 1, 2, 3, 4, 5]; - * var maxIndex = 5; - * var cacheSize = 3; - * var reorderedIndices = Cesium.Tipsify.tipsify({indices : indices, maxIndex : maxIndex, cacheSize : cacheSize}); - */ - Tipsify.tipsify = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var indices = options.indices; - var maximumIndex = options.maximumIndex; - var cacheSize = defaultValue(options.cacheSize, 24); + if (numBehind === 1) { + if (u0Behind) { + u01Ratio = (threshold - u0) / (u1 - u0); + u02Ratio = (threshold - u0) / (u2 - u0); - var cursor; + result.push(1); - function skipDeadEnd(vertices, deadEnd, indices, maximumIndexPlusOne) { - while (deadEnd.length >= 1) { - // while the stack is not empty - var d = deadEnd[deadEnd.length - 1]; // top of the stack - deadEnd.splice(deadEnd.length - 1, 1); // pop the stack + result.push(2); - if (vertices[d].numLiveTriangles > 0) { - return d; + if (u02Ratio !== 1.0) { + result.push(-1); + result.push(0); + result.push(2); + result.push(u02Ratio); } - } - while (cursor < maximumIndexPlusOne) { - if (vertices[cursor].numLiveTriangles > 0) { - ++cursor; - return cursor - 1; + if (u01Ratio !== 1.0) { + result.push(-1); + result.push(0); + result.push(1); + result.push(u01Ratio); } - ++cursor; - } - return -1; - } + } else if (u1Behind) { + u12Ratio = (threshold - u1) / (u2 - u1); + u10Ratio = (threshold - u1) / (u0 - u1); - function getNextVertex(indices, cacheSize, oneRing, vertices, s, deadEnd, maximumIndexPlusOne) { - var n = -1; - var p; - var m = -1; - var itOneRing = 0; - while (itOneRing < oneRing.length) { - var index = oneRing[itOneRing]; - if (vertices[index].numLiveTriangles) { - p = 0; - if ((s - vertices[index].timeStamp + (2 * vertices[index].numLiveTriangles)) <= cacheSize) { - p = s - vertices[index].timeStamp; - } - if ((p > m) || (m === -1)) { - m = p; - n = index; - } - } - ++itOneRing; - } - if (n === -1) { - return skipDeadEnd(vertices, deadEnd, indices, maximumIndexPlusOne); - } - return n; - } + result.push(2); - if (!defined(indices)) { - throw new DeveloperError('indices is required.'); - } - - var numIndices = indices.length; + result.push(0); - if (numIndices < 3 || numIndices % 3 !== 0) { - throw new DeveloperError('indices length must be a multiple of three.'); - } - if (maximumIndex <= 0) { - throw new DeveloperError('maximumIndex must be greater than zero.'); - } - if (cacheSize < 3) { - throw new DeveloperError('cacheSize must be greater than two.'); - } - - // Determine maximum index - var maximumIndexPlusOne = 0; - var currentIndex = 0; - var intoIndices = indices[currentIndex]; - var endIndex = numIndices; - if (defined(maximumIndex)) { - maximumIndexPlusOne = maximumIndex + 1; - } else { - while (currentIndex < endIndex) { - if (intoIndices > maximumIndexPlusOne) { - maximumIndexPlusOne = intoIndices; + if (u10Ratio !== 1.0) { + result.push(-1); + result.push(1); + result.push(0); + result.push(u10Ratio); + } + + if (u12Ratio !== 1.0) { + result.push(-1); + result.push(1); + result.push(2); + result.push(u12Ratio); + } + } else if (u2Behind) { + u20Ratio = (threshold - u2) / (u0 - u2); + u21Ratio = (threshold - u2) / (u1 - u2); + + result.push(0); + + result.push(1); + + if (u21Ratio !== 1.0) { + result.push(-1); + result.push(2); + result.push(1); + result.push(u21Ratio); + } + + if (u20Ratio !== 1.0) { + result.push(-1); + result.push(2); + result.push(0); + result.push(u20Ratio); } - ++currentIndex; - intoIndices = indices[currentIndex]; - } - if (maximumIndexPlusOne === -1) { - return 0; } - ++maximumIndexPlusOne; - } + } else if (numBehind === 2) { + if (!u0Behind && u0 !== threshold) { + u10Ratio = (threshold - u1) / (u0 - u1); + u20Ratio = (threshold - u2) / (u0 - u2); - // Vertices - var vertices = []; - var i; - for (i = 0; i < maximumIndexPlusOne; i++) { - vertices[i] = { - numLiveTriangles : 0, - timeStamp : 0, - vertexTriangles : [] - }; - } - currentIndex = 0; - var triangle = 0; - while (currentIndex < endIndex) { - vertices[indices[currentIndex]].vertexTriangles.push(triangle); - ++(vertices[indices[currentIndex]]).numLiveTriangles; - vertices[indices[currentIndex + 1]].vertexTriangles.push(triangle); - ++(vertices[indices[currentIndex + 1]]).numLiveTriangles; - vertices[indices[currentIndex + 2]].vertexTriangles.push(triangle); - ++(vertices[indices[currentIndex + 2]]).numLiveTriangles; - ++triangle; - currentIndex += 3; - } + result.push(0); - // Starting index - var f = 0; + result.push(-1); + result.push(1); + result.push(0); + result.push(u10Ratio); - // Time Stamp - var s = cacheSize + 1; - cursor = 1; + result.push(-1); + result.push(2); + result.push(0); + result.push(u20Ratio); + } else if (!u1Behind && u1 !== threshold) { + u21Ratio = (threshold - u2) / (u1 - u2); + u01Ratio = (threshold - u0) / (u1 - u0); - // Process - var oneRing = []; - var deadEnd = []; //Stack - var vertex; - var intoVertices; - var currentOutputIndex = 0; - var outputIndices = []; - var numTriangles = numIndices / 3; - var triangleEmitted = []; - for (i = 0; i < numTriangles; i++) { - triangleEmitted[i] = false; - } - var index; - var limit; - while (f !== -1) { - oneRing = []; - intoVertices = vertices[f]; - limit = intoVertices.vertexTriangles.length; - for ( var k = 0; k < limit; ++k) { - triangle = intoVertices.vertexTriangles[k]; - if (!triangleEmitted[triangle]) { - triangleEmitted[triangle] = true; - currentIndex = triangle + triangle + triangle; - for ( var j = 0; j < 3; ++j) { - // Set this index as a possible next index - index = indices[currentIndex]; - oneRing.push(index); - deadEnd.push(index); + result.push(1); - // Output index - outputIndices[currentOutputIndex] = index; - ++currentOutputIndex; + result.push(-1); + result.push(2); + result.push(1); + result.push(u21Ratio); - // Cache processing - vertex = vertices[index]; - --vertex.numLiveTriangles; - if ((s - vertex.timeStamp) > cacheSize) { - vertex.timeStamp = s; - ++s; - } - ++currentIndex; - } - } + result.push(-1); + result.push(0); + result.push(1); + result.push(u01Ratio); + } else if (!u2Behind && u2 !== threshold) { + u02Ratio = (threshold - u0) / (u2 - u0); + u12Ratio = (threshold - u1) / (u2 - u1); + + result.push(2); + + result.push(-1); + result.push(0); + result.push(2); + result.push(u02Ratio); + + result.push(-1); + result.push(1); + result.push(2); + result.push(u12Ratio); } - f = getNextVertex(indices, cacheSize, oneRing, vertices, s, deadEnd, maximumIndexPlusOne); + } else if (numBehind !== 3) { + // Completely in front of threshold + result.push(0); + result.push(1); + result.push(2); } + // else Completely behind threshold - return outputIndices; + return result; }; - return Tipsify; + /** + * Compute the barycentric coordinates of a 2D position within a 2D triangle. + * + * @param {Number} x The x coordinate of the position for which to find the barycentric coordinates. + * @param {Number} y The y coordinate of the position for which to find the barycentric coordinates. + * @param {Number} x1 The x coordinate of the triangle's first vertex. + * @param {Number} y1 The y coordinate of the triangle's first vertex. + * @param {Number} x2 The x coordinate of the triangle's second vertex. + * @param {Number} y2 The y coordinate of the triangle's second vertex. + * @param {Number} x3 The x coordinate of the triangle's third vertex. + * @param {Number} y3 The y coordinate of the triangle's third vertex. + * @param {Cartesian3} [result] The instance into to which to copy the result. If this parameter + * is undefined, a new instance is created and returned. + * @returns {Cartesian3} The barycentric coordinates of the position within the triangle. + * + * @example + * var result = Cesium.Intersections2D.computeBarycentricCoordinates(0.0, 0.0, 0.0, 1.0, -1, -0.5, 1, -0.5); + * // result === new Cesium.Cartesian3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0); + */ + Intersections2D.computeBarycentricCoordinates = function(x, y, x1, y1, x2, y2, x3, y3, result) { + if (!defined(x)) { + throw new DeveloperError('x is required.'); + } + if (!defined(y)) { + throw new DeveloperError('y is required.'); + } + if (!defined(x1)) { + throw new DeveloperError('x1 is required.'); + } + if (!defined(y1)) { + throw new DeveloperError('y1 is required.'); + } + if (!defined(x2)) { + throw new DeveloperError('x2 is required.'); + } + if (!defined(y2)) { + throw new DeveloperError('y2 is required.'); + } + if (!defined(x3)) { + throw new DeveloperError('x3 is required.'); + } + if (!defined(y3)) { + throw new DeveloperError('y3 is required.'); + } + + var x1mx3 = x1 - x3; + var x3mx2 = x3 - x2; + var y2my3 = y2 - y3; + var y1my3 = y1 - y3; + var inverseDeterminant = 1.0 / (y2my3 * x1mx3 + x3mx2 * y1my3); + var ymy3 = y - y3; + var xmx3 = x - x3; + var l1 = (y2my3 * xmx3 + x3mx2 * ymy3) * inverseDeterminant; + var l2 = (-y1my3 * xmx3 + x1mx3 * ymy3) * inverseDeterminant; + var l3 = 1.0 - l1 - l2; + + if (defined(result)) { + result.x = l1; + result.y = l2; + result.z = l3; + return result; + } + return new Cartesian3(l1, l2, l3); + }; + + return Intersections2D; }); -define('Core/GeometryPipeline',[ - './AttributeCompression', - './barycentricCoordinates', +define('Core/QuantizedMeshTerrainData',[ + '../ThirdParty/when', './BoundingSphere', './Cartesian2', './Cartesian3', - './Cartesian4', - './Cartographic', - './ComponentDatatype', './defaultValue', './defined', + './defineProperties', './DeveloperError', - './EncodedCartesian3', - './GeographicProjection', - './Geometry', - './GeometryAttribute', - './GeometryType', './IndexDatatype', - './Intersect', - './IntersectionTests', + './Intersections2D', './Math', - './Matrix3', - './Matrix4', - './Plane', - './PrimitiveType', - './Tipsify' + './OrientedBoundingBox', + './TaskProcessor', + './TerrainEncoding', + './TerrainMesh' ], function( - AttributeCompression, - barycentricCoordinates, + when, BoundingSphere, Cartesian2, Cartesian3, - Cartesian4, - Cartographic, - ComponentDatatype, defaultValue, defined, + defineProperties, DeveloperError, - EncodedCartesian3, - GeographicProjection, - Geometry, - GeometryAttribute, - GeometryType, IndexDatatype, - Intersect, - IntersectionTests, + Intersections2D, CesiumMath, - Matrix3, - Matrix4, - Plane, - PrimitiveType, - Tipsify) { + OrientedBoundingBox, + TaskProcessor, + TerrainEncoding, + TerrainMesh) { 'use strict'; /** - * Content pipeline functions for geometries. + * Terrain data for a single tile where the terrain data is represented as a quantized mesh. A quantized + * mesh consists of three vertex attributes, longitude, latitude, and height. All attributes are expressed + * as 16-bit values in the range 0 to 32767. Longitude and latitude are zero at the southwest corner + * of the tile and 32767 at the northeast corner. Height is zero at the minimum height in the tile + * and 32767 at the maximum height in the tile. * - * @exports GeometryPipeline + * @alias QuantizedMeshTerrainData + * @constructor * - * @see Geometry + * @param {Object} options Object with the following properties: + * @param {Uint16Array} options.quantizedVertices The buffer containing the quantized mesh. + * @param {Uint16Array|Uint32Array} options.indices The indices specifying how the quantized vertices are linked + * together into triangles. Each three indices specifies one triangle. + * @param {Number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid. + * @param {Number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid. + * @param {BoundingSphere} options.boundingSphere A sphere bounding all of the vertices in the mesh. + * @param {OrientedBoundingBox} [options.orientedBoundingBox] An OrientedBoundingBox bounding all of the vertices in the mesh. + * @param {Cartesian3} options.horizonOcclusionPoint The horizon occlusion point of the mesh. If this point + * is below the horizon, the entire tile is assumed to be below the horizon as well. + * The point is expressed in ellipsoid-scaled coordinates. + * @param {Number[]} options.westIndices The indices of the vertices on the western edge of the tile. + * @param {Number[]} options.southIndices The indices of the vertices on the southern edge of the tile. + * @param {Number[]} options.eastIndices The indices of the vertices on the eastern edge of the tile. + * @param {Number[]} options.northIndices The indices of the vertices on the northern edge of the tile. + * @param {Number} options.westSkirtHeight The height of the skirt to add on the western edge of the tile. + * @param {Number} options.southSkirtHeight The height of the skirt to add on the southern edge of the tile. + * @param {Number} options.eastSkirtHeight The height of the skirt to add on the eastern edge of the tile. + * @param {Number} options.northSkirtHeight The height of the skirt to add on the northern edge of the tile. + * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. + * If a child's bit is set, geometry will be requested for that tile as well when it + * is needed. If the bit is cleared, the child tile is not requested and geometry is + * instead upsampled from the parent. The bit values are as follows: + * <table> + * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> + * <tr><td>0</td><td>1</td><td>Southwest</td></tr> + * <tr><td>1</td><td>2</td><td>Southeast</td></tr> + * <tr><td>2</td><td>4</td><td>Northwest</td></tr> + * <tr><td>3</td><td>8</td><td>Northeast</td></tr> + * </table> + * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; + * otherwise, false. + * @param {Uint8Array} [options.encodedNormals] The buffer containing per vertex normals, encoded using 'oct' encoding + * @param {Uint8Array} [options.waterMask] The buffer containing the watermask. + * @param {Credit[]} [options.credits] Array of credits for this tile. + * + * + * @example + * var data = new Cesium.QuantizedMeshTerrainData({ + * minimumHeight : -100, + * maximumHeight : 2101, + * quantizedVertices : new Uint16Array([// order is SW NW SE NE + * // longitude + * 0, 0, 32767, 32767, + * // latitude + * 0, 32767, 0, 32767, + * // heights + * 16384, 0, 32767, 16384]), + * indices : new Uint16Array([0, 3, 1, + * 0, 2, 3]), + * boundingSphere : new Cesium.BoundingSphere(new Cesium.Cartesian3(1.0, 2.0, 3.0), 10000), + * orientedBoundingBox : new Cesium.OrientedBoundingBox(new Cesium.Cartesian3(1.0, 2.0, 3.0), Cesium.Matrix3.fromRotationX(Cesium.Math.PI, new Cesium.Matrix3())), + * horizonOcclusionPoint : new Cesium.Cartesian3(3.0, 2.0, 1.0), + * westIndices : [0, 1], + * southIndices : [0, 1], + * eastIndices : [2, 3], + * northIndices : [1, 3], + * westSkirtHeight : 1.0, + * southSkirtHeight : 1.0, + * eastSkirtHeight : 1.0, + * northSkirtHeight : 1.0 + * }); + * + * @see TerrainData + * @see HeightmapTerrainData */ - var GeometryPipeline = {}; + function QuantizedMeshTerrainData(options) { + if (!defined(options) || !defined(options.quantizedVertices)) { + throw new DeveloperError('options.quantizedVertices is required.'); + } + if (!defined(options.indices)) { + throw new DeveloperError('options.indices is required.'); + } + if (!defined(options.minimumHeight)) { + throw new DeveloperError('options.minimumHeight is required.'); + } + if (!defined(options.maximumHeight)) { + throw new DeveloperError('options.maximumHeight is required.'); + } + if (!defined(options.maximumHeight)) { + throw new DeveloperError('options.maximumHeight is required.'); + } + if (!defined(options.boundingSphere)) { + throw new DeveloperError('options.boundingSphere is required.'); + } + if (!defined(options.horizonOcclusionPoint)) { + throw new DeveloperError('options.horizonOcclusionPoint is required.'); + } + if (!defined(options.westIndices)) { + throw new DeveloperError('options.westIndices is required.'); + } + if (!defined(options.southIndices)) { + throw new DeveloperError('options.southIndices is required.'); + } + if (!defined(options.eastIndices)) { + throw new DeveloperError('options.eastIndices is required.'); + } + if (!defined(options.northIndices)) { + throw new DeveloperError('options.northIndices is required.'); + } + if (!defined(options.westSkirtHeight)) { + throw new DeveloperError('options.westSkirtHeight is required.'); + } + if (!defined(options.southSkirtHeight)) { + throw new DeveloperError('options.southSkirtHeight is required.'); + } + if (!defined(options.eastSkirtHeight)) { + throw new DeveloperError('options.eastSkirtHeight is required.'); + } + if (!defined(options.northSkirtHeight)) { + throw new DeveloperError('options.northSkirtHeight is required.'); + } + + this._quantizedVertices = options.quantizedVertices; + this._encodedNormals = options.encodedNormals; + this._indices = options.indices; + this._minimumHeight = options.minimumHeight; + this._maximumHeight = options.maximumHeight; + this._boundingSphere = options.boundingSphere; + this._orientedBoundingBox = options.orientedBoundingBox; + this._horizonOcclusionPoint = options.horizonOcclusionPoint; + this._credits = options.credits; - function addTriangle(lines, index, i0, i1, i2) { - lines[index++] = i0; - lines[index++] = i1; + var vertexCount = this._quantizedVertices.length / 3; + var uValues = this._uValues = this._quantizedVertices.subarray(0, vertexCount); + var vValues = this._vValues = this._quantizedVertices.subarray(vertexCount, 2 * vertexCount); + this._heightValues = this._quantizedVertices.subarray(2 * vertexCount, 3 * vertexCount); - lines[index++] = i1; - lines[index++] = i2; + // We don't assume that we can count on the edge vertices being sorted by u or v. + function sortByV(a, b) { + return vValues[a] - vValues[b]; + } - lines[index++] = i2; - lines[index] = i0; - } + function sortByU(a, b) { + return uValues[a] - uValues[b]; + } - function trianglesToLines(triangles) { - var count = triangles.length; - var size = (count / 3) * 6; - var lines = IndexDatatype.createTypedArray(count, size); + this._westIndices = sortIndicesIfNecessary(options.westIndices, sortByV, vertexCount); + this._southIndices = sortIndicesIfNecessary(options.southIndices, sortByU, vertexCount); + this._eastIndices = sortIndicesIfNecessary(options.eastIndices, sortByV, vertexCount); + this._northIndices = sortIndicesIfNecessary(options.northIndices, sortByU, vertexCount); - var index = 0; - for ( var i = 0; i < count; i += 3, index += 6) { - addTriangle(lines, index, triangles[i], triangles[i + 1], triangles[i + 2]); - } + this._westSkirtHeight = options.westSkirtHeight; + this._southSkirtHeight = options.southSkirtHeight; + this._eastSkirtHeight = options.eastSkirtHeight; + this._northSkirtHeight = options.northSkirtHeight; - return lines; - } + this._childTileMask = defaultValue(options.childTileMask, 15); - function triangleStripToLines(triangles) { - var count = triangles.length; - if (count >= 3) { - var size = (count - 2) * 6; - var lines = IndexDatatype.createTypedArray(count, size); + this._createdByUpsampling = defaultValue(options.createdByUpsampling, false); + this._waterMask = options.waterMask; - addTriangle(lines, 0, triangles[0], triangles[1], triangles[2]); - var index = 6; + this._mesh = undefined; + } - for ( var i = 3; i < count; ++i, index += 6) { - addTriangle(lines, index, triangles[i - 1], triangles[i], triangles[i - 2]); + defineProperties(QuantizedMeshTerrainData.prototype, { + /** + * An array of credits for this tile. + * @memberof QuantizedMeshTerrainData.prototype + * @type {Credit[]} + */ + credits : { + get : function() { + return this._credits; + } + }, + /** + * The water mask included in this terrain data, if any. A water mask is a rectangular + * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. + * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. + * @memberof QuantizedMeshTerrainData.prototype + * @type {Uint8Array|Image|Canvas} + */ + waterMask : { + get : function() { + return this._waterMask; } - - return lines; } + }); - return new Uint16Array(); - } - - function triangleFanToLines(triangles) { - if (triangles.length > 0) { - var count = triangles.length - 1; - var size = (count - 1) * 6; - var lines = IndexDatatype.createTypedArray(count, size); + var arrayScratch = []; - var base = triangles[0]; - var index = 0; - for ( var i = 1; i < count; ++i, index += 6) { - addTriangle(lines, index, base, triangles[i], triangles[i + 1]); - } + function sortIndicesIfNecessary(indices, sortFunction, vertexCount) { + arrayScratch.length = indices.length; - return lines; + var needsSort = false; + for (var i = 0, len = indices.length; i < len; ++i) { + arrayScratch[i] = indices[i]; + needsSort = needsSort || (i > 0 && sortFunction(indices[i - 1], indices[i]) > 0); } - return new Uint16Array(); + if (needsSort) { + arrayScratch.sort(sortFunction); + return IndexDatatype.createTypedArray(vertexCount, arrayScratch); + } + return indices; } + var createMeshTaskProcessor = new TaskProcessor('createVerticesFromQuantizedTerrainMesh'); + /** - * Converts a geometry's triangle indices to line indices. If the geometry has an <code>indices</code> - * and its <code>primitiveType</code> is <code>TRIANGLES</code>, <code>TRIANGLE_STRIP</code>, - * <code>TRIANGLE_FAN</code>, it is converted to <code>LINES</code>; otherwise, the geometry is not changed. - * <p> - * This is commonly used to create a wireframe geometry for visual debugging. - * </p> - * - * @param {Geometry} geometry The geometry to modify. - * @returns {Geometry} The modified <code>geometry</code> argument, with its triangle indices converted to lines. + * Creates a {@link TerrainMesh} from this terrain data. * - * @exception {DeveloperError} geometry.primitiveType must be TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN. + * @private * - * @example - * geometry = Cesium.GeometryPipeline.toWireframe(geometry); + * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} x The X coordinate of the tile for which to create the terrain data. + * @param {Number} y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} level The level of the tile for which to create the terrain data. + * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. + * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * asynchronous mesh creations are already in progress and the operation should + * be retried later. */ - GeometryPipeline.toWireframe = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); + QuantizedMeshTerrainData.prototype.createMesh = function(tilingScheme, x, y, level, exaggeration) { + if (!defined(tilingScheme)) { + throw new DeveloperError('tilingScheme is required.'); + } + if (!defined(x)) { + throw new DeveloperError('x is required.'); + } + if (!defined(y)) { + throw new DeveloperError('y is required.'); + } + if (!defined(level)) { + throw new DeveloperError('level is required.'); } - var indices = geometry.indices; - if (defined(indices)) { - switch (geometry.primitiveType) { - case PrimitiveType.TRIANGLES: - geometry.indices = trianglesToLines(indices); - break; - case PrimitiveType.TRIANGLE_STRIP: - geometry.indices = triangleStripToLines(indices); - break; - case PrimitiveType.TRIANGLE_FAN: - geometry.indices = triangleFanToLines(indices); - break; - default: - throw new DeveloperError('geometry.primitiveType must be TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN.'); - } + var ellipsoid = tilingScheme.ellipsoid; + var rectangle = tilingScheme.tileXYToRectangle(x, y, level); + exaggeration = defaultValue(exaggeration, 1.0); - geometry.primitiveType = PrimitiveType.LINES; + var verticesPromise = createMeshTaskProcessor.scheduleTask({ + minimumHeight : this._minimumHeight, + maximumHeight : this._maximumHeight, + quantizedVertices : this._quantizedVertices, + octEncodedNormals : this._encodedNormals, + includeWebMercatorT : true, + indices : this._indices, + westIndices : this._westIndices, + southIndices : this._southIndices, + eastIndices : this._eastIndices, + northIndices : this._northIndices, + westSkirtHeight : this._westSkirtHeight, + southSkirtHeight : this._southSkirtHeight, + eastSkirtHeight : this._eastSkirtHeight, + northSkirtHeight : this._northSkirtHeight, + rectangle : rectangle, + relativeToCenter : this._boundingSphere.center, + ellipsoid : ellipsoid, + exaggeration : exaggeration + }); + + if (!defined(verticesPromise)) { + // Postponed + return undefined; } - return geometry; + var that = this; + return when(verticesPromise, function(result) { + var vertexCount = that._quantizedVertices.length / 3; + vertexCount += that._westIndices.length + that._southIndices.length + that._eastIndices.length + that._northIndices.length; + var indicesTypedArray = IndexDatatype.createTypedArray(vertexCount, result.indices); + + var vertices = new Float32Array(result.vertices); + var rtc = result.center; + var minimumHeight = result.minimumHeight; + var maximumHeight = result.maximumHeight; + var boundingSphere = defaultValue(result.boundingSphere, that._boundingSphere); + var obb = defaultValue(result.orientedBoundingBox, that._orientedBoundingBox); + var occlusionPoint = that._horizonOcclusionPoint; + var stride = result.vertexStride; + var terrainEncoding = TerrainEncoding.clone(result.encoding); + + that._skirtIndex = result.skirtIndex; + that._vertexCountWithoutSkirts = that._quantizedVertices.length / 3; + + that._mesh = new TerrainMesh( + rtc, + vertices, + indicesTypedArray, + minimumHeight, + maximumHeight, + boundingSphere, + occlusionPoint, + stride, + obb, + terrainEncoding, + exaggeration); + + // Free memory received from server after mesh is created. + that._quantizedVertices = undefined; + that._encodedNormals = undefined; + that._indices = undefined; + + that._uValues = undefined; + that._vValues = undefined; + that._heightValues = undefined; + + that._westIndices = undefined; + that._southIndices = undefined; + that._eastIndices = undefined; + that._northIndices = undefined; + + return that._mesh; + }); }; + var upsampleTaskProcessor = new TaskProcessor('upsampleQuantizedTerrainMesh'); + /** - * Creates a new {@link Geometry} with <code>LINES</code> representing the provided - * attribute (<code>attributeName</code>) for the provided geometry. This is used to - * visualize vector attributes like normals, tangents, and bitangents. - * - * @param {Geometry} geometry The <code>Geometry</code> instance with the attribute. - * @param {String} [attributeName='normal'] The name of the attribute. - * @param {Number} [length=10000.0] The length of each line segment in meters. This can be negative to point the vector in the opposite direction. - * @returns {Geometry} A new <code>Geometry</code> instance with line segments for the vector. - * - * @exception {DeveloperError} geometry.attributes must have an attribute with the same name as the attributeName parameter. + * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the + * vertices in this instance, interpolated if necessary. * - * @example - * var geometry = Cesium.GeometryPipeline.createLineSegmentsForVectors(instance.geometry, 'bitangent', 100000.0); + * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. + * @param {Number} thisX The X coordinate of this tile in the tiling scheme. + * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {Number} thisLevel The level of this tile in the tiling scheme. + * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise.<QuantizedMeshTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, + * or undefined if too many asynchronous upsample operations are in progress and the request has been + * deferred. */ - GeometryPipeline.createLineSegmentsForVectors = function(geometry, attributeName, length) { - attributeName = defaultValue(attributeName, 'normal'); - - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); + QuantizedMeshTerrainData.prototype.upsample = function(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) { + if (!defined(tilingScheme)) { + throw new DeveloperError('tilingScheme is required.'); } - if (!defined(geometry.attributes.position)) { - throw new DeveloperError('geometry.attributes.position is required.'); + if (!defined(thisX)) { + throw new DeveloperError('thisX is required.'); } - if (!defined(geometry.attributes[attributeName])) { - throw new DeveloperError('geometry.attributes must have an attribute with the same name as the attributeName parameter, ' + attributeName + '.'); + if (!defined(thisY)) { + throw new DeveloperError('thisY is required.'); + } + if (!defined(thisLevel)) { + throw new DeveloperError('thisLevel is required.'); + } + if (!defined(descendantX)) { + throw new DeveloperError('descendantX is required.'); + } + if (!defined(descendantY)) { + throw new DeveloperError('descendantY is required.'); + } + if (!defined(descendantLevel)) { + throw new DeveloperError('descendantLevel is required.'); + } + var levelDifference = descendantLevel - thisLevel; + if (levelDifference > 1) { + throw new DeveloperError('Upsampling through more than one level at a time is not currently supported.'); } - length = defaultValue(length, 10000.0); + var mesh = this._mesh; + if (!defined(this._mesh)) { + return undefined; + } - var positions = geometry.attributes.position.values; - var vectors = geometry.attributes[attributeName].values; - var positionsLength = positions.length; + var isEastChild = thisX * 2 !== descendantX; + var isNorthChild = thisY * 2 === descendantY; - var newPositions = new Float64Array(2 * positionsLength); + var ellipsoid = tilingScheme.ellipsoid; + var childRectangle = tilingScheme.tileXYToRectangle(descendantX, descendantY, descendantLevel); - var j = 0; - for (var i = 0; i < positionsLength; i += 3) { - newPositions[j++] = positions[i]; - newPositions[j++] = positions[i + 1]; - newPositions[j++] = positions[i + 2]; + var upsamplePromise = upsampleTaskProcessor.scheduleTask({ + vertices : mesh.vertices, + vertexCountWithoutSkirts : this._vertexCountWithoutSkirts, + indices : mesh.indices, + skirtIndex : this._skirtIndex, + encoding : mesh.encoding, + minimumHeight : this._minimumHeight, + maximumHeight : this._maximumHeight, + isEastChild : isEastChild, + isNorthChild : isNorthChild, + childRectangle : childRectangle, + ellipsoid : ellipsoid, + exaggeration : mesh.exaggeration + }); - newPositions[j++] = positions[i] + (vectors[i] * length); - newPositions[j++] = positions[i + 1] + (vectors[i + 1] * length); - newPositions[j++] = positions[i + 2] + (vectors[i + 2] * length); + if (!defined(upsamplePromise)) { + // Postponed + return undefined; } - var newBoundingSphere; - var bs = geometry.boundingSphere; - if (defined(bs)) { - newBoundingSphere = new BoundingSphere(bs.center, bs.radius + length); - } + var shortestSkirt = Math.min(this._westSkirtHeight, this._eastSkirtHeight); + shortestSkirt = Math.min(shortestSkirt, this._southSkirtHeight); + shortestSkirt = Math.min(shortestSkirt, this._northSkirtHeight); - return new Geometry({ - attributes : { - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : newPositions - }) - }, - primitiveType : PrimitiveType.LINES, - boundingSphere : newBoundingSphere + var westSkirtHeight = isEastChild ? (shortestSkirt * 0.5) : this._westSkirtHeight; + var southSkirtHeight = isNorthChild ? (shortestSkirt * 0.5) : this._southSkirtHeight; + var eastSkirtHeight = isEastChild ? this._eastSkirtHeight : (shortestSkirt * 0.5); + var northSkirtHeight = isNorthChild ? this._northSkirtHeight : (shortestSkirt * 0.5); + + return when(upsamplePromise, function(result) { + var quantizedVertices = new Uint16Array(result.vertices); + var indicesTypedArray = IndexDatatype.createTypedArray(quantizedVertices.length / 3, result.indices); + var encodedNormals; + if (defined(result.encodedNormals)) { + encodedNormals = new Uint8Array(result.encodedNormals); + } + + return new QuantizedMeshTerrainData({ + quantizedVertices : quantizedVertices, + indices : indicesTypedArray, + encodedNormals : encodedNormals, + minimumHeight : result.minimumHeight, + maximumHeight : result.maximumHeight, + boundingSphere : BoundingSphere.clone(result.boundingSphere), + orientedBoundingBox : OrientedBoundingBox.clone(result.orientedBoundingBox), + horizonOcclusionPoint : Cartesian3.clone(result.horizonOcclusionPoint), + westIndices : result.westIndices, + southIndices : result.southIndices, + eastIndices : result.eastIndices, + northIndices : result.northIndices, + westSkirtHeight : westSkirtHeight, + southSkirtHeight : southSkirtHeight, + eastSkirtHeight : eastSkirtHeight, + northSkirtHeight : northSkirtHeight, + childTileMask : 0, + createdByUpsampling : true + }); }); }; + var maxShort = 32767; + var barycentricCoordinateScratch = new Cartesian3(); + /** - * Creates an object that maps attribute names to unique locations (indices) - * for matching vertex attributes and shader programs. - * - * @param {Geometry} geometry The geometry, which is not modified, to create the object for. - * @returns {Object} An object with attribute name / index pairs. + * Computes the terrain height at a specified longitude and latitude. * - * @example - * var attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry); - * // Example output - * // { - * // 'position' : 0, - * // 'normal' : 1 - * // } + * @param {Rectangle} rectangle The rectangle covered by this terrain data. + * @param {Number} longitude The longitude in radians. + * @param {Number} latitude The latitude in radians. + * @returns {Number} The terrain height at the specified position. The position is clamped to + * the rectangle, so expect incorrect results for positions far outside the rectangle. */ - GeometryPipeline.createAttributeLocations = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - - // There can be a WebGL performance hit when attribute 0 is disabled, so - // assign attribute locations to well-known attributes. - var semantics = [ - 'position', - 'positionHigh', - 'positionLow', - - // From VertexFormat.position - after 2D projection and high-precision encoding - 'position3DHigh', - 'position3DLow', - 'position2DHigh', - 'position2DLow', + QuantizedMeshTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) { + var u = CesiumMath.clamp((longitude - rectangle.west) / rectangle.width, 0.0, 1.0); + u *= maxShort; + var v = CesiumMath.clamp((latitude - rectangle.south) / rectangle.height, 0.0, 1.0); + v *= maxShort; - // From Primitive - 'pickColor', + if (!defined(this._mesh)) { + return interpolateHeight(this, u, v); + } - // From VertexFormat - 'normal', - 'st', - 'tangent', - 'bitangent', + return interpolateMeshHeight(this, u, v); + }; - // For shadow volumes - 'extrudeDirection', + var texCoordScratch0 = new Cartesian2(); + var texCoordScratch1 = new Cartesian2(); + var texCoordScratch2 = new Cartesian2(); - // From compressing texture coordinates and normals - 'compressedAttributes' - ]; + function interpolateMeshHeight(terrainData, u, v) { + var mesh = terrainData._mesh; + var vertices = mesh.vertices; + var encoding = mesh.encoding; + var indices = mesh.indices; - var attributes = geometry.attributes; - var indices = {}; - var j = 0; - var i; - var len = semantics.length; + for (var i = 0, len = indices.length; i < len; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; - // Attribute locations for well-known attributes - for (i = 0; i < len; ++i) { - var semantic = semantics[i]; + var uv0 = encoding.decodeTextureCoordinates(vertices, i0, texCoordScratch0); + var uv1 = encoding.decodeTextureCoordinates(vertices, i1, texCoordScratch1); + var uv2 = encoding.decodeTextureCoordinates(vertices, i2, texCoordScratch2); - if (defined(attributes[semantic])) { - indices[semantic] = j++; + var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, barycentricCoordinateScratch); + if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { + var h0 = encoding.decodeHeight(vertices, i0); + var h1 = encoding.decodeHeight(vertices, i1); + var h2 = encoding.decodeHeight(vertices, i2); + return barycentric.x * h0 + barycentric.y * h1 + barycentric.z * h2; } } - // Locations for custom attributes - for (var name in attributes) { - if (attributes.hasOwnProperty(name) && (!defined(indices[name]))) { - indices[name] = j++; + // Position does not lie in any triangle in this mesh. + return undefined; + } + + function interpolateHeight(terrainData, u, v) { + var uBuffer = terrainData._uValues; + var vBuffer = terrainData._vValues; + var heightBuffer = terrainData._heightValues; + + var indices = terrainData._indices; + for (var i = 0, len = indices.length; i < len; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; + + var u0 = uBuffer[i0]; + var u1 = uBuffer[i1]; + var u2 = uBuffer[i2]; + + var v0 = vBuffer[i0]; + var v1 = vBuffer[i1]; + var v2 = vBuffer[i2]; + + var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, u0, v0, u1, v1, u2, v2, barycentricCoordinateScratch); + if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { + var quantizedHeight = barycentric.x * heightBuffer[i0] + + barycentric.y * heightBuffer[i1] + + barycentric.z * heightBuffer[i2]; + return CesiumMath.lerp(terrainData._minimumHeight, terrainData._maximumHeight, quantizedHeight / maxShort); } } - return indices; - }; + // Position does not lie in any triangle in this mesh. + return undefined; + } /** - * Reorders a geometry's attributes and <code>indices</code> to achieve better performance from the GPU's pre-vertex-shader cache. - * - * @param {Geometry} geometry The geometry to modify. - * @returns {Geometry} The modified <code>geometry</code> argument, with its attributes and indices reordered for the GPU's pre-vertex-shader cache. - * - * @exception {DeveloperError} Each attribute array in geometry.attributes must have the same number of attributes. - * - * - * @example - * geometry = Cesium.GeometryPipeline.reorderForPreVertexCache(geometry); + * Determines if a given child tile is available, based on the + * {@link HeightmapTerrainData.childTileMask}. The given child tile coordinates are assumed + * to be one of the four children of this tile. If non-child tile coordinates are + * given, the availability of the southeast child tile is returned. * - * @see GeometryPipeline.reorderForPostVertexCache + * @param {Number} thisX The tile X coordinate of this (the parent) tile. + * @param {Number} thisY The tile Y coordinate of this (the parent) tile. + * @param {Number} childX The tile X coordinate of the child tile to check for availability. + * @param {Number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {Boolean} True if the child tile is available; otherwise, false. */ - GeometryPipeline.reorderForPreVertexCache = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); + QuantizedMeshTerrainData.prototype.isChildAvailable = function(thisX, thisY, childX, childY) { + if (!defined(thisX)) { + throw new DeveloperError('thisX is required.'); + } + if (!defined(thisY)) { + throw new DeveloperError('thisY is required.'); + } + if (!defined(childX)) { + throw new DeveloperError('childX is required.'); + } + if (!defined(childY)) { + throw new DeveloperError('childY is required.'); } - var numVertices = Geometry.computeNumberOfVertices(geometry); - - var indices = geometry.indices; - if (defined(indices)) { - var indexCrossReferenceOldToNew = new Int32Array(numVertices); - for ( var i = 0; i < numVertices; i++) { - indexCrossReferenceOldToNew[i] = -1; - } + var bitNumber = 2; // northwest child + if (childX !== thisX * 2) { + ++bitNumber; // east child + } + if (childY !== thisY * 2) { + bitNumber -= 2; // south child + } - // Construct cross reference and reorder indices - var indicesIn = indices; - var numIndices = indicesIn.length; - var indicesOut = IndexDatatype.createTypedArray(numVertices, numIndices); + return (this._childTileMask & (1 << bitNumber)) !== 0; + }; - var intoIndicesIn = 0; - var intoIndicesOut = 0; - var nextIndex = 0; - var tempIndex; - while (intoIndicesIn < numIndices) { - tempIndex = indexCrossReferenceOldToNew[indicesIn[intoIndicesIn]]; - if (tempIndex !== -1) { - indicesOut[intoIndicesOut] = tempIndex; - } else { - tempIndex = indicesIn[intoIndicesIn]; - indexCrossReferenceOldToNew[tempIndex] = nextIndex; + /** + * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution + * terrain data. If this value is false, the data was obtained from some other source, such + * as by downloading it from a remote server. This method should return true for instances + * returned from a call to {@link HeightmapTerrainData#upsample}. + * + * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + */ + QuantizedMeshTerrainData.prototype.wasCreatedByUpsampling = function() { + return this._createdByUpsampling; + }; - indicesOut[intoIndicesOut] = nextIndex; - ++nextIndex; - } - ++intoIndicesIn; - ++intoIndicesOut; - } - geometry.indices = indicesOut; + return QuantizedMeshTerrainData; +}); - // Reorder attributes - var attributes = geometry.attributes; - for ( var property in attributes) { - if (attributes.hasOwnProperty(property) && - defined(attributes[property]) && - defined(attributes[property].values)) { - - var attribute = attributes[property]; - var elementsIn = attribute.values; - var intoElementsIn = 0; - var numComponents = attribute.componentsPerAttribute; - var elementsOut = ComponentDatatype.createTypedArray(attribute.componentDatatype, nextIndex * numComponents); - while (intoElementsIn < numVertices) { - var temp = indexCrossReferenceOldToNew[intoElementsIn]; - if (temp !== -1) { - for (var j = 0; j < numComponents; j++) { - elementsOut[numComponents * temp + j] = elementsIn[numComponents * intoElementsIn + j]; - } - } - ++intoElementsIn; - } - attribute.values = elementsOut; - } - } - } - - return geometry; - }; +define('Core/TileAvailability',[ + './binarySearch', + './Cartographic', + './defined', + './defineProperties', + './DeveloperError', + './Rectangle' + ], function( + binarySearch, + Cartographic, + defined, + defineProperties, + DeveloperError, + Rectangle) { + 'use strict'; /** - * Reorders a geometry's <code>indices</code> to achieve better performance from the GPU's - * post vertex-shader cache by using the Tipsify algorithm. If the geometry <code>primitiveType</code> - * is not <code>TRIANGLES</code> or the geometry does not have an <code>indices</code>, this function has no effect. - * - * @param {Geometry} geometry The geometry to modify. - * @param {Number} [cacheCapacity=24] The number of vertices that can be held in the GPU's vertex cache. - * @returns {Geometry} The modified <code>geometry</code> argument, with its indices reordered for the post-vertex-shader cache. - * - * @exception {DeveloperError} cacheCapacity must be greater than two. - * + * Reports the availability of tiles in a {@link TilingScheme}. * - * @example - * geometry = Cesium.GeometryPipeline.reorderForPostVertexCache(geometry); + * @alias TileAvailability + * @constructor * - * @see GeometryPipeline.reorderForPreVertexCache - * @see {@link http://gfx.cs.princ0eton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf|Fast Triangle Reordering for Vertex Locality and Reduced Overdraw} - * by Sander, Nehab, and Barczak + * @param {TilingScheme} tilingScheme The tiling scheme in which to report availability. + * @param {Number} maximumLevel The maximum tile level that is potentially available. */ - GeometryPipeline.reorderForPostVertexCache = function(geometry, cacheCapacity) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - - var indices = geometry.indices; - if ((geometry.primitiveType === PrimitiveType.TRIANGLES) && (defined(indices))) { - var numIndices = indices.length; - var maximumIndex = 0; - for ( var j = 0; j < numIndices; j++) { - if (indices[j] > maximumIndex) { - maximumIndex = indices[j]; - } - } - geometry.indices = Tipsify.tipsify({ - indices : indices, - maximumIndex : maximumIndex, - cacheSize : cacheCapacity - }); - } - - return geometry; - }; - - function copyAttributesDescriptions(attributes) { - var newAttributes = {}; - - for ( var attribute in attributes) { - if (attributes.hasOwnProperty(attribute) && - defined(attributes[attribute]) && - defined(attributes[attribute].values)) { + function TileAvailability(tilingScheme, maximumLevel) { + this._tilingScheme = tilingScheme; + this._maximumLevel = maximumLevel; - var attr = attributes[attribute]; - newAttributes[attribute] = new GeometryAttribute({ - componentDatatype : attr.componentDatatype, - componentsPerAttribute : attr.componentsPerAttribute, - normalize : attr.normalize, - values : [] - }); + this._rootNodes = []; + for (var y = 0; y < tilingScheme.getNumberOfYTilesAtLevel(); ++y) { + for (var x = 0; x < tilingScheme.getNumberOfXTilesAtLevel(); ++x) { + this._rootNodes.push(new QuadtreeNode(tilingScheme, undefined, 0, x, y)); } } - - return newAttributes; } - function copyVertex(destinationAttributes, sourceAttributes, index) { - for ( var attribute in sourceAttributes) { - if (sourceAttributes.hasOwnProperty(attribute) && - defined(sourceAttributes[attribute]) && - defined(sourceAttributes[attribute].values)) { - - var attr = sourceAttributes[attribute]; - - for ( var k = 0; k < attr.componentsPerAttribute; ++k) { - destinationAttributes[attribute].values.push(attr.values[(index * attr.componentsPerAttribute) + k]); - } - } - } - } + var rectangleScratch = new Rectangle(); /** - * Splits a geometry into multiple geometries, if necessary, to ensure that indices in the - * <code>indices</code> fit into unsigned shorts. This is used to meet the WebGL requirements - * when unsigned int indices are not supported. - * <p> - * If the geometry does not have any <code>indices</code>, this function has no effect. - * </p> - * - * @param {Geometry} geometry The geometry to be split into multiple geometries. - * @returns {Geometry[]} An array of geometries, each with indices that fit into unsigned shorts. - * - * @exception {DeveloperError} geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS - * @exception {DeveloperError} All geometry attribute lists must have the same number of attributes. + * Marks a rectangular range of tiles in a particular level as being available. For best performance, + * add your ranges in order of increasing level. * - * @example - * var geometries = Cesium.GeometryPipeline.fitToUnsignedShortIndices(geometry); + * @param {Number} level The level. + * @param {Number} startX The X coordinate of the first available tiles at the level. + * @param {Number} startY The Y coordinate of the first available tiles at the level. + * @param {Number} endX The X coordinate of the last available tiles at the level. + * @param {Number} endY The Y coordinate of the last available tiles at the level. */ - GeometryPipeline.fitToUnsignedShortIndices = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - if ((defined(geometry.indices)) && - ((geometry.primitiveType !== PrimitiveType.TRIANGLES) && - (geometry.primitiveType !== PrimitiveType.LINES) && - (geometry.primitiveType !== PrimitiveType.POINTS))) { - throw new DeveloperError('geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS.'); - } - - var geometries = []; - - // If there's an index list and more than 64K attributes, it is possible that - // some indices are outside the range of unsigned short [0, 64K - 1] - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - if (defined(geometry.indices) && (numberOfVertices >= CesiumMath.SIXTY_FOUR_KILOBYTES)) { - var oldToNewIndex = []; - var newIndices = []; - var currentIndex = 0; - var newAttributes = copyAttributesDescriptions(geometry.attributes); - - var originalIndices = geometry.indices; - var numberOfIndices = originalIndices.length; - - var indicesPerPrimitive; - - if (geometry.primitiveType === PrimitiveType.TRIANGLES) { - indicesPerPrimitive = 3; - } else if (geometry.primitiveType === PrimitiveType.LINES) { - indicesPerPrimitive = 2; - } else if (geometry.primitiveType === PrimitiveType.POINTS) { - indicesPerPrimitive = 1; - } + TileAvailability.prototype.addAvailableTileRange = function(level, startX, startY, endX, endY) { + var tilingScheme = this._tilingScheme; - for ( var j = 0; j < numberOfIndices; j += indicesPerPrimitive) { - for (var k = 0; k < indicesPerPrimitive; ++k) { - var x = originalIndices[j + k]; - var i = oldToNewIndex[x]; - if (!defined(i)) { - i = currentIndex++; - oldToNewIndex[x] = i; - copyVertex(newAttributes, geometry.attributes, x); - } - newIndices.push(i); - } + tilingScheme.tileXYToRectangle(startX, startY, level, rectangleScratch); + var west = rectangleScratch.west; + var north = rectangleScratch.north; - if (currentIndex + indicesPerPrimitive >= CesiumMath.SIXTY_FOUR_KILOBYTES) { - geometries.push(new Geometry({ - attributes : newAttributes, - indices : newIndices, - primitiveType : geometry.primitiveType, - boundingSphere : geometry.boundingSphere, - boundingSphereCV : geometry.boundingSphereCV - })); + tilingScheme.tileXYToRectangle(endX, endY, level, rectangleScratch); + var east = rectangleScratch.east; + var south = rectangleScratch.south; - // Reset for next vertex-array - oldToNewIndex = []; - newIndices = []; - currentIndex = 0; - newAttributes = copyAttributesDescriptions(geometry.attributes); - } - } + var rectangleWithLevel = new RectangleWithLevel(level, west, south, east, north); - if (newIndices.length !== 0) { - geometries.push(new Geometry({ - attributes : newAttributes, - indices : newIndices, - primitiveType : geometry.primitiveType, - boundingSphere : geometry.boundingSphere, - boundingSphereCV : geometry.boundingSphereCV - })); + for (var i = 0; i < this._rootNodes.length; ++i) { + var rootNode = this._rootNodes[i]; + if (rectanglesOverlap(rootNode.extent, rectangleWithLevel)) { + putRectangleInQuadtree(this._maximumLevel, rootNode, rectangleWithLevel); } - } else { - // No need to split into multiple geometries - geometries.push(geometry); } - - return geometries; }; - var scratchProjectTo2DCartesian3 = new Cartesian3(); - var scratchProjectTo2DCartographic = new Cartographic(); - /** - * Projects a geometry's 3D <code>position</code> attribute to 2D, replacing the <code>position</code> - * attribute with separate <code>position3D</code> and <code>position2D</code> attributes. - * <p> - * If the geometry does not have a <code>position</code>, this function has no effect. - * </p> - * - * @param {Geometry} geometry The geometry to modify. - * @param {String} attributeName The name of the attribute. - * @param {String} attributeName3D The name of the attribute in 3D. - * @param {String} attributeName2D The name of the attribute in 2D. - * @param {Object} [projection=new GeographicProjection()] The projection to use. - * @returns {Geometry} The modified <code>geometry</code> argument with <code>position3D</code> and <code>position2D</code> attributes. - * - * @exception {DeveloperError} geometry must have attribute matching the attributeName argument. - * @exception {DeveloperError} The attribute componentDatatype must be ComponentDatatype.DOUBLE. - * @exception {DeveloperError} Could not project a point to 2D. + * Determines the level of the most detailed tile covering the position. This function + * usually completes in time logarithmic to the number of rectangles added with + * {@link TileAvailability#addAvailableTileRange}. * - * @example - * geometry = Cesium.GeometryPipeline.projectTo2D(geometry, 'position', 'position3D', 'position2D'); + * @param {Cartographic} position The position for which to determine the maximum available level. The height component is ignored. + * @return {Number} The level of the most detailed tile covering the position. + * @throws {DeveloperError} If position is outside any tile according to the tiling scheme. */ - GeometryPipeline.projectTo2D = function(geometry, attributeName, attributeName3D, attributeName2D, projection) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - if (!defined(attributeName)) { - throw new DeveloperError('attributeName is required.'); - } - if (!defined(attributeName3D)) { - throw new DeveloperError('attributeName3D is required.'); - } - if (!defined(attributeName2D)) { - throw new DeveloperError('attributeName2D is required.'); - } - if (!defined(geometry.attributes[attributeName])) { - throw new DeveloperError('geometry must have attribute matching the attributeName argument: ' + attributeName + '.'); - } - if (geometry.attributes[attributeName].componentDatatype !== ComponentDatatype.DOUBLE) { - throw new DeveloperError('The attribute componentDatatype must be ComponentDatatype.DOUBLE.'); - } - - var attribute = geometry.attributes[attributeName]; - projection = (defined(projection)) ? projection : new GeographicProjection(); - var ellipsoid = projection.ellipsoid; - - // Project original values to 2D. - var values3D = attribute.values; - var projectedValues = new Float64Array(values3D.length); - var index = 0; - - for ( var i = 0; i < values3D.length; i += 3) { - var value = Cartesian3.fromArray(values3D, i, scratchProjectTo2DCartesian3); - - var lonLat = ellipsoid.cartesianToCartographic(value, scratchProjectTo2DCartographic); - if (!defined(lonLat)) { - throw new DeveloperError('Could not project point (' + value.x + ', ' + value.y + ', ' + value.z + ') to 2D.'); + TileAvailability.prototype.computeMaximumLevelAtPosition = function(position) { + // Find the root node that contains this position. + var node; + for (var nodeIndex = 0; nodeIndex < this._rootNodes.length; ++nodeIndex) { + var rootNode = this._rootNodes[nodeIndex]; + if (rectangleContainsPosition(rootNode.extent, position)) { + node = rootNode; + break; } - - var projectedLonLat = projection.project(lonLat, scratchProjectTo2DCartesian3); - - projectedValues[index++] = projectedLonLat.x; - projectedValues[index++] = projectedLonLat.y; - projectedValues[index++] = projectedLonLat.z; } - // Rename original cartesians to WGS84 cartesians. - geometry.attributes[attributeName3D] = attribute; - - // Replace original cartesians with 2D projected cartesians - geometry.attributes[attributeName2D] = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : projectedValues - }); - delete geometry.attributes[attributeName]; - - return geometry; + if (!defined(node)) { + throw new DeveloperError('The specified position does not exist in any root node of the tiling scheme.'); + } + + return findMaxLevelFromNode(undefined, node, position); }; - var encodedResult = { - high : 0.0, - low : 0.0 - }; + var rectanglesScratch = []; + var remainingToCoverByLevelScratch = []; + var westScratch = new Rectangle(); + var eastScratch = new Rectangle(); /** - * Encodes floating-point geometry attribute values as two separate attributes to improve - * rendering precision. - * <p> - * This is commonly used to create high-precision position vertex attributes. - * </p> - * - * @param {Geometry} geometry The geometry to modify. - * @param {String} attributeName The name of the attribute. - * @param {String} attributeHighName The name of the attribute for the encoded high bits. - * @param {String} attributeLowName The name of the attribute for the encoded low bits. - * @returns {Geometry} The modified <code>geometry</code> argument, with its encoded attribute. - * - * @exception {DeveloperError} geometry must have attribute matching the attributeName argument. - * @exception {DeveloperError} The attribute componentDatatype must be ComponentDatatype.DOUBLE. + * Finds the most detailed level that is available _everywhere_ within a given rectangle. More detailed + * tiles may be available in parts of the rectangle, but not the whole thing. The return value of this + * function may be safely passed to {@link sampleTerrain} for any position within the rectangle. This function + * usually completes in time logarithmic to the number of rectangles added with + * {@link TileAvailability#addAvailableTileRange}. * - * @example - * geometry = Cesium.GeometryPipeline.encodeAttribute(geometry, 'position3D', 'position3DHigh', 'position3DLow'); + * @param {Rectangle} rectangle The rectangle. + * @return {Number} The best available level for the entire rectangle. */ - GeometryPipeline.encodeAttribute = function(geometry, attributeName, attributeHighName, attributeLowName) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - if (!defined(attributeName)) { - throw new DeveloperError('attributeName is required.'); - } - if (!defined(attributeHighName)) { - throw new DeveloperError('attributeHighName is required.'); - } - if (!defined(attributeLowName)) { - throw new DeveloperError('attributeLowName is required.'); - } - if (!defined(geometry.attributes[attributeName])) { - throw new DeveloperError('geometry must have attribute matching the attributeName argument: ' + attributeName + '.'); - } - if (geometry.attributes[attributeName].componentDatatype !== ComponentDatatype.DOUBLE) { - throw new DeveloperError('The attribute componentDatatype must be ComponentDatatype.DOUBLE.'); - } - - var attribute = geometry.attributes[attributeName]; - var values = attribute.values; - var length = values.length; - var highValues = new Float32Array(length); - var lowValues = new Float32Array(length); + TileAvailability.prototype.computeBestAvailableLevelOverRectangle = function(rectangle) { + var rectangles = rectanglesScratch; + rectangles.length = 0; - for (var i = 0; i < length; ++i) { - EncodedCartesian3.encode(values[i], encodedResult); - highValues[i] = encodedResult.high; - lowValues[i] = encodedResult.low; + if (rectangle.east < rectangle.west) { + // Rectangle crosses the IDL, make it two rectangles. + rectangles.push(Rectangle.fromRadians(-Math.PI, rectangle.south, rectangle.east, rectangle.north, westScratch)); + rectangles.push(Rectangle.fromRadians(rectangle.west, rectangle.south, Math.PI, rectangle.north, eastScratch)); + } else { + rectangles.push(rectangle); } - var componentsPerAttribute = attribute.componentsPerAttribute; - - geometry.attributes[attributeHighName] = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : componentsPerAttribute, - values : highValues - }); - geometry.attributes[attributeLowName] = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : componentsPerAttribute, - values : lowValues - }); - delete geometry.attributes[attributeName]; - - return geometry; - }; - - var scratchCartesian3 = new Cartesian3(); + var remainingToCoverByLevel = remainingToCoverByLevelScratch; + remainingToCoverByLevel.length = 0; - function transformPoint(matrix, attribute) { - if (defined(attribute)) { - var values = attribute.values; - var length = values.length; - for (var i = 0; i < length; i += 3) { - Cartesian3.unpack(values, i, scratchCartesian3); - Matrix4.multiplyByPoint(matrix, scratchCartesian3, scratchCartesian3); - Cartesian3.pack(scratchCartesian3, values, i); - } + var i; + for (i = 0; i < this._rootNodes.length; ++i) { + updateCoverageWithNode(remainingToCoverByLevel, this._rootNodes[i], rectangles); } - } - function transformVector(matrix, attribute) { - if (defined(attribute)) { - var values = attribute.values; - var length = values.length; - for (var i = 0; i < length; i += 3) { - Cartesian3.unpack(values, i, scratchCartesian3); - Matrix3.multiplyByVector(matrix, scratchCartesian3, scratchCartesian3); - scratchCartesian3 = Cartesian3.normalize(scratchCartesian3, scratchCartesian3); - Cartesian3.pack(scratchCartesian3, values, i); + for (i = remainingToCoverByLevel.length - 1; i >= 0; --i) { + if (defined(remainingToCoverByLevel[i]) && remainingToCoverByLevel[i].length === 0) { + return i; } } - } - var inverseTranspose = new Matrix4(); - var normalMatrix = new Matrix3(); + return 0; + }; + + var cartographicScratch = new Cartographic(); /** - * Transforms a geometry instance to world coordinates. This changes - * the instance's <code>modelMatrix</code> to {@link Matrix4.IDENTITY} and transforms the - * following attributes if they are present: <code>position</code>, <code>normal</code>, - * <code>tangent</code>, and <code>bitangent</code>. - * - * @param {GeometryInstance} instance The geometry instance to modify. - * @returns {GeometryInstance} The modified <code>instance</code> argument, with its attributes transforms to world coordinates. - * - * @example - * Cesium.GeometryPipeline.transformToWorldCoordinates(instance); + * Determines if a particular tile is available. + * @param {Number} level The tile level to check. + * @param {Number} x The X coordinate of the tile to check. + * @param {Number} y The Y coordinate of the tile to check. + * @return {Boolean} True if the tile is available; otherwise, false. */ - GeometryPipeline.transformToWorldCoordinates = function(instance) { - if (!defined(instance)) { - throw new DeveloperError('instance is required.'); - } - - var modelMatrix = instance.modelMatrix; - - if (Matrix4.equals(modelMatrix, Matrix4.IDENTITY)) { - // Already in world coordinates - return instance; - } - - var attributes = instance.geometry.attributes; - - // Transform attributes in known vertex formats - transformPoint(modelMatrix, attributes.position); - transformPoint(modelMatrix, attributes.prevPosition); - transformPoint(modelMatrix, attributes.nextPosition); - - if ((defined(attributes.normal)) || - (defined(attributes.tangent)) || - (defined(attributes.bitangent))) { - - Matrix4.inverse(modelMatrix, inverseTranspose); - Matrix4.transpose(inverseTranspose, inverseTranspose); - Matrix4.getRotation(inverseTranspose, normalMatrix); + TileAvailability.prototype.isTileAvailable = function(level, x, y) { + // Get the center of the tile and find the maximum level at that position. + // Because availability is by tile, if the level is available at that point, it + // is sure to be available for the whole tile. We assume that if a tile at level n exists, + // then all its parent tiles back to level 0 exist too. This isn't really enforced + // anywhere, but Cesium would never load a tile for which this is not true. + var rectangle = this._tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); + Rectangle.center(rectangle, cartographicScratch); + return this.computeMaximumLevelAtPosition(cartographicScratch) >= level; + }; - transformVector(normalMatrix, attributes.normal); - transformVector(normalMatrix, attributes.tangent); - transformVector(normalMatrix, attributes.bitangent); + /** + * Computes a bit mask indicating which of a tile's four children exist. + * If a child's bit is set, a tile is available for that child. If it is cleared, + * the tile is not available. The bit values are as follows: + * <table> + * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> + * <tr><td>0</td><td>1</td><td>Southwest</td></tr> + * <tr><td>1</td><td>2</td><td>Southeast</td></tr> + * <tr><td>2</td><td>4</td><td>Northwest</td></tr> + * <tr><td>3</td><td>8</td><td>Northeast</td></tr> + * </table> + * + * @param {Number} level The level of the parent tile. + * @param {Number} x The X coordinate of the parent tile. + * @param {Number} y The Y coordinate of the parent tile. + * @return {Number} The bit mask indicating child availability. + */ + TileAvailability.prototype.computeChildMaskForTile = function(level, x, y) { + var childLevel = level + 1; + if (childLevel >= this._maximumLevel) { + return 0; } - var boundingSphere = instance.geometry.boundingSphere; - - if (defined(boundingSphere)) { - instance.geometry.boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix, boundingSphere); - } + var mask = 0; - instance.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + mask |= this.isTileAvailable(childLevel, 2 * x, 2 * y + 1) ? 1 : 0; + mask |= this.isTileAvailable(childLevel, 2 * x + 1, 2 * y + 1) ? 2 : 0; + mask |= this.isTileAvailable(childLevel, 2 * x, 2 * y) ? 4 : 0; + mask |= this.isTileAvailable(childLevel, 2 * x + 1, 2 * y) ? 8 : 0; - return instance; + return mask; }; - function findAttributesInAllGeometries(instances, propertyName) { - var length = instances.length; - - var attributesInAllGeometries = {}; - - var attributes0 = instances[0][propertyName].attributes; - var name; - - for (name in attributes0) { - if (attributes0.hasOwnProperty(name) && - defined(attributes0[name]) && - defined(attributes0[name].values)) { - - var attribute = attributes0[name]; - var numberOfComponents = attribute.values.length; - var inAllGeometries = true; + function QuadtreeNode(tilingScheme, parent, level, x, y) { + this.tilingScheme = tilingScheme; + this.parent = parent; + this.level = level; + this.x = x; + this.y = y; + this.extent = tilingScheme.tileXYToRectangle(x, y, level); - // Does this same attribute exist in all geometries? - for (var i = 1; i < length; ++i) { - var otherAttribute = instances[i][propertyName].attributes[name]; + this.rectangles = []; + this._sw = undefined; + this._se = undefined; + this._nw = undefined; + this._ne = undefined; + } - if ((!defined(otherAttribute)) || - (attribute.componentDatatype !== otherAttribute.componentDatatype) || - (attribute.componentsPerAttribute !== otherAttribute.componentsPerAttribute) || - (attribute.normalize !== otherAttribute.normalize)) { + defineProperties(QuadtreeNode.prototype, { + nw: { + get: function() { + if (!this._nw) { + this._nw = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2, this.y * 2); + } + return this._nw; + } + }, - inAllGeometries = false; - break; - } + ne: { + get: function() { + if (!this._ne) { + this._ne = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2 + 1, this.y * 2); + } + return this._ne; + } + }, - numberOfComponents += otherAttribute.values.length; + sw: { + get: function() { + if (!this._sw) { + this._sw = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2, this.y * 2 + 1); } + return this._sw; + } + }, - if (inAllGeometries) { - attributesInAllGeometries[name] = new GeometryAttribute({ - componentDatatype : attribute.componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize, - values : ComponentDatatype.createTypedArray(attribute.componentDatatype, numberOfComponents) - }); + se: { + get: function() { + if (!this._se) { + this._se = new QuadtreeNode(this.tilingScheme, this, this.level + 1, this.x * 2 + 1, this.y * 2 + 1); } + return this._se; } } + }); - return attributesInAllGeometries; + function RectangleWithLevel(level, west, south, east, north) { + this.level = level; + this.west = west; + this.south = south; + this.east = east; + this.north = north; } - var tempScratch = new Cartesian3(); - - function combineGeometries(instances, propertyName) { - var length = instances.length; - - var name; - var i; - var j; - var k; - - var m = instances[0].modelMatrix; - var haveIndices = (defined(instances[0][propertyName].indices)); - var primitiveType = instances[0][propertyName].primitiveType; + function rectanglesOverlap(rectangle1, rectangle2) { + var west = Math.max(rectangle1.west, rectangle2.west); + var south = Math.max(rectangle1.south, rectangle2.south); + var east = Math.min(rectangle1.east, rectangle2.east); + var north = Math.min(rectangle1.north, rectangle2.north); + return south < north && west < east; + } - for (i = 1; i < length; ++i) { - if (!Matrix4.equals(instances[i].modelMatrix, m)) { - throw new DeveloperError('All instances must have the same modelMatrix.'); - } - if ((defined(instances[i][propertyName].indices)) !== haveIndices) { - throw new DeveloperError('All instance geometries must have an indices or not have one.'); + function putRectangleInQuadtree(maxDepth, node, rectangle) { + while (node.level < maxDepth) { + if (rectangleFullyContainsRectangle(node.nw.extent, rectangle)) { + node = node.nw; + } else if (rectangleFullyContainsRectangle(node.ne.extent, rectangle)) { + node = node.ne; + } else if (rectangleFullyContainsRectangle(node.sw.extent, rectangle)) { + node = node.sw; + } else if (rectangleFullyContainsRectangle(node.se.extent, rectangle)) { + node = node.se; + } else { + break; } - if (instances[i][propertyName].primitiveType !== primitiveType) { - throw new DeveloperError('All instance geometries must have the same primitiveType.'); + } + + if (node.rectangles.length === 0 || node.rectangles[node.rectangles.length - 1].level <= rectangle.level) { + node.rectangles.push(rectangle); + } else { + // Maintain ordering by level when inserting. + var index = binarySearch(node.rectangles, rectangle.level, rectangleLevelComparator); + if (index <= 0) { + index = ~index; } + node.rectangles.splice(index, 0, rectangle); } - - // Find subset of attributes in all geometries - var attributes = findAttributesInAllGeometries(instances, propertyName); - var values; - var sourceValues; - var sourceValuesLength; + } - // Combine attributes from each geometry into a single typed array - for (name in attributes) { - if (attributes.hasOwnProperty(name)) { - values = attributes[name].values; + function rectangleLevelComparator(a, b) { + return a.level - b; + } - k = 0; - for (i = 0; i < length; ++i) { - sourceValues = instances[i][propertyName].attributes[name].values; - sourceValuesLength = sourceValues.length; + function rectangleFullyContainsRectangle(potentialContainer, rectangleToTest) { + return rectangleToTest.west >= potentialContainer.west && + rectangleToTest.east <= potentialContainer.east && + rectangleToTest.south >= potentialContainer.south && + rectangleToTest.north <= potentialContainer.north; + } - for (j = 0; j < sourceValuesLength; ++j) { - values[k++] = sourceValues[j]; - } + function rectangleContainsPosition(potentialContainer, positionToTest) { + return positionToTest.longitude >= potentialContainer.west && + positionToTest.longitude <= potentialContainer.east && + positionToTest.latitude >= potentialContainer.south && + positionToTest.latitude <= potentialContainer.north; + } + + function findMaxLevelFromNode(stopNode, node, position) { + var maxLevel = 0; + + // Find the deepest quadtree node containing this point. + var found = false; + while (!found) { + var nw = node._nw && rectangleContainsPosition(node._nw.extent, position); + var ne = node._ne && rectangleContainsPosition(node._ne.extent, position); + var sw = node._sw && rectangleContainsPosition(node._sw.extent, position); + var se = node._se && rectangleContainsPosition(node._se.extent, position); + + // The common scenario is that the point is in only one quadrant and we can simply + // iterate down the tree. But if the point is on a boundary between tiles, it is + // in multiple tiles and we need to check all of them, so use recursion. + if (nw + ne + sw + se > 1) { + if (nw) { + maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._nw, position)); + } + if (ne) { + maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._ne, position)); + } + if (sw) { + maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._sw, position)); } + if (se) { + maxLevel = Math.max(maxLevel, findMaxLevelFromNode(node, node._se, position)); + } + break; + } else if (nw) { + node = node._nw; + } else if (ne) { + node = node._ne; + } else if (sw) { + node = node._sw; + } else if (se) { + node = node._se; + } else { + found = true; } } - // Combine index lists - var indices; + // Work up the tree until we find a rectangle that contains this point. + while (node !== stopNode) { + var rectangles = node.rectangles; - if (haveIndices) { - var numberOfIndices = 0; - for (i = 0; i < length; ++i) { - numberOfIndices += instances[i][propertyName].indices.length; + // Rectangles are sorted by level, lowest first. + for (var i = rectangles.length - 1; i >= 0 && rectangles[i].level > maxLevel; --i) { + var rectangle = rectangles[i]; + if (rectangleContainsPosition(rectangle, position)) { + maxLevel = rectangle.level; + } } - var numberOfVertices = Geometry.computeNumberOfVertices(new Geometry({ - attributes : attributes, - primitiveType : PrimitiveType.POINTS - })); - var destIndices = IndexDatatype.createTypedArray(numberOfVertices, numberOfIndices); - - var destOffset = 0; - var offset = 0; + node = node.parent; + } - for (i = 0; i < length; ++i) { - var sourceIndices = instances[i][propertyName].indices; - var sourceIndicesLen = sourceIndices.length; + return maxLevel; + } - for (k = 0; k < sourceIndicesLen; ++k) { - destIndices[destOffset++] = offset + sourceIndices[k]; - } + function updateCoverageWithNode(remainingToCoverByLevel, node, rectanglesToCover) { + if (!node) { + return; + } - offset += Geometry.computeNumberOfVertices(instances[i][propertyName]); - } + var i; + var anyOverlap = false; + for (i = 0; i < rectanglesToCover.length; ++i) { + anyOverlap = anyOverlap || rectanglesOverlap(node.extent, rectanglesToCover[i]); + } - indices = destIndices; + if (!anyOverlap) { + // This node is not applicable to the rectangle(s). + return; } - // Create bounding sphere that includes all instances - var center = new Cartesian3(); - var radius = 0.0; - var bs; + var rectangles = node.rectangles; + for (i = 0; i < rectangles.length; ++i) { + var rectangle = rectangles[i]; - for (i = 0; i < length; ++i) { - bs = instances[i][propertyName].boundingSphere; - if (!defined(bs)) { - // If any geometries have an undefined bounding sphere, then so does the combined geometry - center = undefined; - break; + if (!remainingToCoverByLevel[rectangle.level]) { + remainingToCoverByLevel[rectangle.level] = rectanglesToCover; } - Cartesian3.add(bs.center, center, center); + remainingToCoverByLevel[rectangle.level] = subtractRectangle(remainingToCoverByLevel[rectangle.level], rectangle); } - if (defined(center)) { - Cartesian3.divideByScalar(center, length, center); - - for (i = 0; i < length; ++i) { - bs = instances[i][propertyName].boundingSphere; - var tempRadius = Cartesian3.magnitude(Cartesian3.subtract(bs.center, center, tempScratch)) + bs.radius; + // Update with child nodes. + updateCoverageWithNode(remainingToCoverByLevel, node._nw, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._ne, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._sw, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._se, rectanglesToCover); + } - if (tempRadius > radius) { - radius = tempRadius; + function subtractRectangle(rectangleList, rectangleToSubtract) { + var result = []; + for (var i = 0; i < rectangleList.length; ++i) { + var rectangle = rectangleList[i]; + if (!rectanglesOverlap(rectangle, rectangleToSubtract)) { + // Disjoint rectangles. Original rectangle is unmodified. + result.push(rectangle); + } else { + // rectangleToSubtract partially or completely overlaps rectangle. + if (rectangle.west < rectangleToSubtract.west) { + result.push(new Rectangle(rectangle.west, rectangle.south, rectangleToSubtract.west, rectangle.north)); + } + if (rectangle.east > rectangleToSubtract.east) { + result.push(new Rectangle(rectangleToSubtract.east, rectangle.south, rectangle.east, rectangle.north)); + } + if (rectangle.south < rectangleToSubtract.south) { + result.push(new Rectangle(Math.max(rectangleToSubtract.west, rectangle.west), rectangle.south, Math.min(rectangleToSubtract.east, rectangle.east), rectangleToSubtract.south)); + } + if (rectangle.north > rectangleToSubtract.north) { + result.push(new Rectangle(Math.max(rectangleToSubtract.west, rectangle.west), rectangleToSubtract.north, Math.min(rectangleToSubtract.east, rectangle.east), rectangle.north)); } } } - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : primitiveType, - boundingSphere : (defined(center)) ? new BoundingSphere(center, radius) : undefined - }); + return result; } + return TileAvailability; +}); + +define('Core/formatError',[ + './defined' + ], function( + defined) { + 'use strict'; + /** - * Combines geometry from several {@link GeometryInstance} objects into one geometry. - * This concatenates the attributes, concatenates and adjusts the indices, and creates - * a bounding sphere encompassing all instances. - * <p> - * If the instances do not have the same attributes, a subset of attributes common - * to all instances is used, and the others are ignored. - * </p> - * <p> - * This is used by {@link Primitive} to efficiently render a large amount of static data. - * </p> - * - * @private - * - * @param {GeometryInstance[]} [instances] The array of {@link GeometryInstance} objects whose geometry will be combined. - * @returns {Geometry} A single geometry created from the provided geometry instances. - * - * @exception {DeveloperError} All instances must have the same modelMatrix. - * @exception {DeveloperError} All instance geometries must have an indices or not have one. - * @exception {DeveloperError} All instance geometries must have the same primitiveType. - * + * Formats an error object into a String. If available, uses name, message, and stack + * properties, otherwise, falls back on toString(). * - * @example - * for (var i = 0; i < instances.length; ++i) { - * Cesium.GeometryPipeline.transformToWorldCoordinates(instances[i]); - * } - * var geometries = Cesium.GeometryPipeline.combineInstances(instances); + * @exports formatError * - * @see GeometryPipeline.transformToWorldCoordinates + * @param {Object} object The item to find in the array. + * @returns {String} A string containing the formatted error. */ - GeometryPipeline.combineInstances = function(instances) { - if ((!defined(instances)) || (instances.length < 1)) { - throw new DeveloperError('instances is required and must have length greater than zero.'); - } - - var instanceGeometry = []; - var instanceSplitGeometry = []; - var length = instances.length; - for (var i = 0; i < length; ++i) { - var instance = instances[i]; - if (defined(instance.geometry)) { - instanceGeometry.push(instance); - } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { - instanceSplitGeometry.push(instance); - } - } + function formatError(object) { + var result; - var geometries = []; - if (instanceGeometry.length > 0) { - geometries.push(combineGeometries(instanceGeometry, 'geometry')); + var name = object.name; + var message = object.message; + if (defined(name) && defined(message)) { + result = name + ': ' + message; + } else { + result = object.toString(); } - if (instanceSplitGeometry.length > 0) { - geometries.push(combineGeometries(instanceSplitGeometry, 'westHemisphereGeometry')); - geometries.push(combineGeometries(instanceSplitGeometry, 'eastHemisphereGeometry')); + var stack = object.stack; + if (defined(stack)) { + result += '\n' + stack; } - return geometries; - }; + return result; + } - var normal = new Cartesian3(); - var v0 = new Cartesian3(); - var v1 = new Cartesian3(); - var v2 = new Cartesian3(); + return formatError; +}); + +define('Core/TileProviderError',[ + './defaultValue', + './defined', + './formatError' + ], function( + defaultValue, + defined, + formatError) { + 'use strict'; /** - * Computes per-vertex normals for a geometry containing <code>TRIANGLES</code> by averaging the normals of - * all triangles incident to the vertex. The result is a new <code>normal</code> attribute added to the geometry. - * This assumes a counter-clockwise winding order. - * - * @param {Geometry} geometry The geometry to modify. - * @returns {Geometry} The modified <code>geometry</code> argument with the computed <code>normal</code> attribute. + * Provides details about an error that occurred in an {@link ImageryProvider} or a {@link TerrainProvider}. * - * @exception {DeveloperError} geometry.indices length must be greater than 0 and be a multiple of 3. - * @exception {DeveloperError} geometry.primitiveType must be {@link PrimitiveType.TRIANGLES}. + * @alias TileProviderError + * @constructor * - * @example - * Cesium.GeometryPipeline.computeNormal(geometry); + * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that experienced the error. + * @param {String} message A message describing the error. + * @param {Number} [x] The X coordinate of the tile that experienced the error, or undefined if the error + * is not specific to a particular tile. + * @param {Number} [y] The Y coordinate of the tile that experienced the error, or undefined if the error + * is not specific to a particular tile. + * @param {Number} [level] The level of the tile that experienced the error, or undefined if the error + * is not specific to a particular tile. + * @param {Number} [timesRetried=0] The number of times this operation has been retried. + * @param {Error} [error] The error or exception that occurred, if any. */ - GeometryPipeline.computeNormal = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - if (!defined(geometry.attributes.position) || !defined(geometry.attributes.position.values)) { - throw new DeveloperError('geometry.attributes.position.values is required.'); - } - if (!defined(geometry.indices)) { - throw new DeveloperError('geometry.indices is required.'); - } - if (geometry.indices.length < 2 || geometry.indices.length % 3 !== 0) { - throw new DeveloperError('geometry.indices length must be greater than 0 and be a multiple of 3.'); - } - if (geometry.primitiveType !== PrimitiveType.TRIANGLES) { - throw new DeveloperError('geometry.primitiveType must be PrimitiveType.TRIANGLES.'); - } - - var indices = geometry.indices; - var attributes = geometry.attributes; - var vertices = attributes.position.values; - var numVertices = attributes.position.values.length / 3; - var numIndices = indices.length; - var normalsPerVertex = new Array(numVertices); - var normalsPerTriangle = new Array(numIndices / 3); - var normalIndices = new Array(numIndices); - var i; - for ( i = 0; i < numVertices; i++) { - normalsPerVertex[i] = { - indexOffset : 0, - count : 0, - currentCount : 0 - }; - } - - var j = 0; - for (i = 0; i < numIndices; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - var i03 = i0 * 3; - var i13 = i1 * 3; - var i23 = i2 * 3; + function TileProviderError(provider, message, x, y, level, timesRetried, error) { + /** + * The {@link ImageryProvider} or {@link TerrainProvider} that experienced the error. + * @type {ImageryProvider|TerrainProvider} + */ + this.provider = provider; - v0.x = vertices[i03]; - v0.y = vertices[i03 + 1]; - v0.z = vertices[i03 + 2]; - v1.x = vertices[i13]; - v1.y = vertices[i13 + 1]; - v1.z = vertices[i13 + 2]; - v2.x = vertices[i23]; - v2.y = vertices[i23 + 1]; - v2.z = vertices[i23 + 2]; + /** + * The message describing the error. + * @type {String} + */ + this.message = message; - normalsPerVertex[i0].count++; - normalsPerVertex[i1].count++; - normalsPerVertex[i2].count++; + /** + * The X coordinate of the tile that experienced the error. If the error is not specific + * to a particular tile, this property will be undefined. + * @type {Number} + */ + this.x = x; - Cartesian3.subtract(v1, v0, v1); - Cartesian3.subtract(v2, v0, v2); - normalsPerTriangle[j] = Cartesian3.cross(v1, v2, new Cartesian3()); - j++; - } + /** + * The Y coordinate of the tile that experienced the error. If the error is not specific + * to a particular tile, this property will be undefined. + * @type {Number} + */ + this.y = y; - var indexOffset = 0; - for (i = 0; i < numVertices; i++) { - normalsPerVertex[i].indexOffset += indexOffset; - indexOffset += normalsPerVertex[i].count; - } + /** + * The level-of-detail of the tile that experienced the error. If the error is not specific + * to a particular tile, this property will be undefined. + * @type {Number} + */ + this.level = level; - j = 0; - var vertexNormalData; - for (i = 0; i < numIndices; i += 3) { - vertexNormalData = normalsPerVertex[indices[i]]; - var index = vertexNormalData.indexOffset + vertexNormalData.currentCount; - normalIndices[index] = j; - vertexNormalData.currentCount++; + /** + * The number of times this operation has been retried. + * @type {Number} + * @default 0 + */ + this.timesRetried = defaultValue(timesRetried, 0); - vertexNormalData = normalsPerVertex[indices[i + 1]]; - index = vertexNormalData.indexOffset + vertexNormalData.currentCount; - normalIndices[index] = j; - vertexNormalData.currentCount++; + /** + * True if the failed operation should be retried; otherwise, false. The imagery or terrain provider + * will set the initial value of this property before raising the event, but any listeners + * can change it. The value after the last listener is invoked will be acted upon. + * @type {Boolean} + * @default false + */ + this.retry = false; - vertexNormalData = normalsPerVertex[indices[i + 2]]; - index = vertexNormalData.indexOffset + vertexNormalData.currentCount; - normalIndices[index] = j; - vertexNormalData.currentCount++; + /** + * The error or exception that occurred, if any. + * @type {Error} + */ + this.error = error; + } - j++; + /** + * Handles an error in an {@link ImageryProvider} or {@link TerrainProvider} by raising an event if it has any listeners, or by + * logging the error to the console if the event has no listeners. This method also tracks the number + * of times the operation has been retried and will automatically retry if requested to do so by the + * event listeners. + * + * @param {TileProviderError} previousError The error instance returned by this function the last + * time it was called for this error, or undefined if this is the first time this error has + * occurred. + * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that encountered the error. + * @param {Event} event The event to raise to inform listeners of the error. + * @param {String} message The message describing the error. + * @param {Number} x The X coordinate of the tile that experienced the error, or undefined if the + * error is not specific to a particular tile. + * @param {Number} y The Y coordinate of the tile that experienced the error, or undefined if the + * error is not specific to a particular tile. + * @param {Number} level The level-of-detail of the tile that experienced the error, or undefined if the + * error is not specific to a particular tile. + * @param {TileProviderError~RetryFunction} retryFunction The function to call to retry the operation. If undefined, the + * operation will not be retried. + * @param {Error} [errorDetails] The error or exception that occurred, if any. + * @returns {TileProviderError} The error instance that was passed to the event listeners and that + * should be passed to this function the next time it is called for the same error in order + * to track retry counts. + */ + TileProviderError.handleError = function(previousError, provider, event, message, x, y, level, retryFunction, errorDetails) { + var error = previousError; + if (!defined(previousError)) { + error = new TileProviderError(provider, message, x, y, level, 0, errorDetails); + } else { + error.provider = provider; + error.message = message; + error.x = x; + error.y = y; + error.level = level; + error.retry = false; + error.error = errorDetails; + ++error.timesRetried; } - var normalValues = new Float32Array(numVertices * 3); - for (i = 0; i < numVertices; i++) { - var i3 = i * 3; - vertexNormalData = normalsPerVertex[i]; - Cartesian3.clone(Cartesian3.ZERO, normal); - if (vertexNormalData.count > 0) { - for (j = 0; j < vertexNormalData.count; j++) { - Cartesian3.add(normal, normalsPerTriangle[normalIndices[vertexNormalData.indexOffset + j]], normal); - } + if (event.numberOfListeners > 0) { + event.raiseEvent(error); + } else { + console.log('An error occurred in "' + provider.constructor.name + '": ' + formatError(message)); + } - // We can run into an issue where a vertex is used with 2 primitives that have opposite winding order. - if (Cartesian3.equalsEpsilon(Cartesian3.ZERO, normal, CesiumMath.EPSILON10)) { - Cartesian3.clone(normalsPerTriangle[normalIndices[vertexNormalData.indexOffset]], normal); - } - } + if (error.retry && defined(retryFunction)) { + retryFunction(); + } - // We end up with a zero vector probably because of a degenerate triangle - if (Cartesian3.equalsEpsilon(Cartesian3.ZERO, normal, CesiumMath.EPSILON10)) { - // Default to (0,0,1) - normal.z = 1.0; - } + return error; + }; - Cartesian3.normalize(normal, normal); - normalValues[i3] = normal.x; - normalValues[i3 + 1] = normal.y; - normalValues[i3 + 2] = normal.z; + /** + * Handles success of an operation by resetting the retry count of a previous error, if any. This way, + * if the error occurs again in the future, the listeners will be informed that it has not yet been retried. + * + * @param {TileProviderError} previousError The previous error, or undefined if this operation has + * not previously resulted in an error. + */ + TileProviderError.handleSuccess = function(previousError) { + if (defined(previousError)) { + previousError.timesRetried = -1; } + }; - geometry.attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normalValues - }); + /** + * A function that will be called to retry the operation. + * @callback TileProviderError~RetryFunction + */ - return geometry; - }; + return TileProviderError; +}); - var normalScratch = new Cartesian3(); - var normalScale = new Cartesian3(); - var tScratch = new Cartesian3(); +define('Core/CesiumTerrainProvider',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './AttributeCompression', + './BoundingSphere', + './Cartesian3', + './Credit', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './Event', + './GeographicTilingScheme', + './HeightmapTerrainData', + './IndexDatatype', + './Math', + './OrientedBoundingBox', + './QuantizedMeshTerrainData', + './Resource', + './RuntimeError', + './TerrainProvider', + './TileAvailability', + './TileProviderError' + ], function( + Uri, + when, + AttributeCompression, + BoundingSphere, + Cartesian3, + Credit, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Event, + GeographicTilingScheme, + HeightmapTerrainData, + IndexDatatype, + CesiumMath, + OrientedBoundingBox, + QuantizedMeshTerrainData, + Resource, + RuntimeError, + TerrainProvider, + TileAvailability, + TileProviderError) { + 'use strict'; + + function LayerInformation(layer) { + this.resource = layer.resource; + this.version = layer.version; + this.isHeightmap = layer.isHeightmap; + this.tileUrlTemplates = layer.tileUrlTemplates; + this.availability = layer.availability; + this.hasVertexNormals = layer.hasVertexNormals; + this.hasWaterMask = layer.hasWaterMask; + this.littleEndianExtensionSize = layer.littleEndianExtensionSize; + } /** - * Computes per-vertex tangents and bitangents for a geometry containing <code>TRIANGLES</code>. - * The result is new <code>tangent</code> and <code>bitangent</code> attributes added to the geometry. - * This assumes a counter-clockwise winding order. - * <p> - * Based on <a href="http://www.terathon.com/code/tangent.html">Computing Tangent Space Basis Vectors - * for an Arbitrary Mesh</a> by Eric Lengyel. - * </p> + * A {@link TerrainProvider} that accesses terrain data in a Cesium terrain format. + * The format is described on the + * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Cesium-Terrain-Server|Cesium wiki}. * - * @param {Geometry} geometry The geometry to modify. - * @returns {Geometry} The modified <code>geometry</code> argument with the computed <code>tangent</code> and <code>bitangent</code> attributes. + * @alias CesiumTerrainProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The URL of the Cesium terrain server. + * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available. + * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server, if available. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * - * @exception {DeveloperError} geometry.indices length must be greater than 0 and be a multiple of 3. - * @exception {DeveloperError} geometry.primitiveType must be {@link PrimitiveType.TRIANGLES}. * * @example - * Cesium.GeometryPipeline.computeTangentAndBiTangent(geometry); + * // Construct a terrain provider that uses per vertex normals for lighting + * // to add shading detail to an imagery provider. + * var terrainProvider = new Cesium.CesiumTerrainProvider({ + * url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles', + * requestVertexNormals : true + * }); + * + * // Terrain geometry near the surface of the globe is difficult to view when using NaturalEarthII imagery, + * // unless the TerrainProvider provides additional lighting information to shade the terrain (as shown above). + * var imageryProvider = Cesium.createTileMapServiceImageryProvider({ + * url : 'http://localhost:8080/Source/Assets/Textures/NaturalEarthII', + * fileExtension : 'jpg' + * }); + * + * var viewer = new Cesium.Viewer('cesiumContainer', { + * imageryProvider : imageryProvider, + * baseLayerPicker : false, + * terrainProvider : terrainProvider + * }); + * + * // The globe must enable lighting to make use of the terrain's vertex normals + * viewer.scene.globe.enableLighting = true; + * + * @see TerrainProvider */ - GeometryPipeline.computeTangentAndBitangent = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); + function CesiumTerrainProvider(options) { + if (!defined(options) || !defined(options.url)) { + throw new DeveloperError('options.url is required.'); } - var attributes = geometry.attributes; - var indices = geometry.indices; - - if (!defined(attributes.position) || !defined(attributes.position.values)) { - throw new DeveloperError('geometry.attributes.position.values is required.'); - } - if (!defined(attributes.normal) || !defined(attributes.normal.values)) { - throw new DeveloperError('geometry.attributes.normal.values is required.'); - } - if (!defined(attributes.st) || !defined(attributes.st.values)) { - throw new DeveloperError('geometry.attributes.st.values is required.'); - } - if (!defined(indices)) { - throw new DeveloperError('geometry.indices is required.'); - } - if (indices.length < 2 || indices.length % 3 !== 0) { - throw new DeveloperError('geometry.indices length must be greater than 0 and be a multiple of 3.'); + if (defined(options.proxy)) { + deprecationWarning('CesiumTerrainProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - if (geometry.primitiveType !== PrimitiveType.TRIANGLES) { - throw new DeveloperError('geometry.primitiveType must be PrimitiveType.TRIANGLES.'); - } - - var vertices = geometry.attributes.position.values; - var normals = geometry.attributes.normal.values; - var st = geometry.attributes.st.values; - - var numVertices = geometry.attributes.position.values.length / 3; - var numIndices = indices.length; - var tan1 = new Array(numVertices * 3); - var i; - for ( i = 0; i < tan1.length; i++) { - tan1[i] = 0; - } + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); + resource.appendForwardSlash(); - var i03; - var i13; - var i23; - for (i = 0; i < numIndices; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - i03 = i0 * 3; - i13 = i1 * 3; - i23 = i2 * 3; - var i02 = i0 * 2; - var i12 = i1 * 2; - var i22 = i2 * 2; + this._tilingScheme = new GeographicTilingScheme({ + numberOfLevelZeroTilesX : 2, + numberOfLevelZeroTilesY : 1, + ellipsoid : options.ellipsoid + }); - var ux = vertices[i03]; - var uy = vertices[i03 + 1]; - var uz = vertices[i03 + 2]; + this._heightmapWidth = 65; + this._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid, this._heightmapWidth, this._tilingScheme.getNumberOfXTilesAtLevel(0)); - var wx = st[i02]; - var wy = st[i02 + 1]; - var t1 = st[i12 + 1] - wy; - var t2 = st[i22 + 1] - wy; + this._heightmapStructure = undefined; + this._hasWaterMask = false; + this._hasVertexNormals = false; - var r = 1.0 / ((st[i12] - wx) * t2 - (st[i22] - wx) * t1); - var sdirx = (t2 * (vertices[i13] - ux) - t1 * (vertices[i23] - ux)) * r; - var sdiry = (t2 * (vertices[i13 + 1] - uy) - t1 * (vertices[i23 + 1] - uy)) * r; - var sdirz = (t2 * (vertices[i13 + 2] - uz) - t1 * (vertices[i23 + 2] - uz)) * r; + /** + * Boolean flag that indicates if the client should request vertex normals from the server. + * @type {Boolean} + * @default false + * @private + */ + this._requestVertexNormals = defaultValue(options.requestVertexNormals, false); - tan1[i03] += sdirx; - tan1[i03 + 1] += sdiry; - tan1[i03 + 2] += sdirz; + /** + * Boolean flag that indicates if the client should request tile watermasks from the server. + * @type {Boolean} + * @default false + * @private + */ + this._requestWaterMask = defaultValue(options.requestWaterMask, false); - tan1[i13] += sdirx; - tan1[i13 + 1] += sdiry; - tan1[i13 + 2] += sdirz; + this._errorEvent = new Event(); - tan1[i23] += sdirx; - tan1[i23 + 1] += sdiry; - tan1[i23 + 2] += sdirz; + var credit = options.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); } + this._credit = credit; - var tangentValues = new Float32Array(numVertices * 3); - var bitangentValues = new Float32Array(numVertices * 3); - - for (i = 0; i < numVertices; i++) { - i03 = i * 3; - i13 = i03 + 1; - i23 = i03 + 2; - - var n = Cartesian3.fromArray(normals, i03, normalScratch); - var t = Cartesian3.fromArray(tan1, i03, tScratch); - var scalar = Cartesian3.dot(n, t); - Cartesian3.multiplyByScalar(n, scalar, normalScale); - Cartesian3.normalize(Cartesian3.subtract(t, normalScale, t), t); - - tangentValues[i03] = t.x; - tangentValues[i13] = t.y; - tangentValues[i23] = t.z; - - Cartesian3.normalize(Cartesian3.cross(n, t, t), t); + this._availability = undefined; - bitangentValues[i03] = t.x; - bitangentValues[i13] = t.y; - bitangentValues[i23] = t.z; - } + this._ready = false; + this._readyPromise = when.defer(); - geometry.attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangentValues + var lastResource = resource; + var metadataResource = lastResource.getDerivedResource({ + url: 'layer.json' }); - geometry.attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangentValues - }); + var that = this; + var metadataError; - return geometry; - }; + var layers = this._layers = []; + var attribution = ''; + var overallAvailability = []; - var scratchCartesian2 = new Cartesian2(); - var toEncode1 = new Cartesian3(); - var toEncode2 = new Cartesian3(); - var toEncode3 = new Cartesian3(); - var encodeResult2 = new Cartesian2(); - /** - * Compresses and packs geometry normal attribute values to save memory. - * - * @param {Geometry} geometry The geometry to modify. - * @returns {Geometry} The modified <code>geometry</code> argument, with its normals compressed and packed. - * - * @example - * geometry = Cesium.GeometryPipeline.compressVertices(geometry); - */ - GeometryPipeline.compressVertices = function(geometry) { - if (!defined(geometry)) { - throw new DeveloperError('geometry is required.'); - } - - var extrudeAttribute = geometry.attributes.extrudeDirection; - var i; - var numVertices; - if (defined(extrudeAttribute)) { - //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes - var extrudeDirections = extrudeAttribute.values; - numVertices = extrudeDirections.length / 3.0; - var compressedDirections = new Float32Array(numVertices * 2); + function parseMetadataSuccess(data) { + var message; - var i2 = 0; - for (i = 0; i < numVertices; ++i) { - Cartesian3.fromArray(extrudeDirections, i * 3.0, toEncode1); - if (Cartesian3.equals(toEncode1, Cartesian3.ZERO)) { - i2 += 2; - continue; - } - encodeResult2 = AttributeCompression.octEncodeInRange(toEncode1, 65535, encodeResult2); - compressedDirections[i2++] = encodeResult2.x; - compressedDirections[i2++] = encodeResult2.y; + if (!data.format) { + message = 'The tile format is not specified in the layer.json file.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + return; } - geometry.attributes.compressedAttributes = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : compressedDirections - }); - delete geometry.attributes.extrudeDirection; - return geometry; - } - - var normalAttribute = geometry.attributes.normal; - var stAttribute = geometry.attributes.st; - - var hasNormal = defined(normalAttribute); - var hasSt = defined(stAttribute); - if (!hasNormal && !hasSt) { - return geometry; - } - - var tangentAttribute = geometry.attributes.tangent; - var bitangentAttribute = geometry.attributes.bitangent; - - var hasTangent = defined(tangentAttribute); - var hasBitangent = defined(bitangentAttribute); - - var normals; - var st; - var tangents; - var bitangents; + if (!data.tiles || data.tiles.length === 0) { + message = 'The layer.json file does not specify any tile URL templates.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + return; + } - if (hasNormal) { - normals = normalAttribute.values; - } - if (hasSt) { - st = stAttribute.values; - } - if (hasTangent) { - tangents = tangentAttribute.values; - } - if (hasBitangent) { - bitangents = bitangentAttribute.values; - } + var hasVertexNormals = false; + var hasWaterMask = false; + var littleEndianExtensionSize = true; + var isHeightmap = false; + if (data.format === 'heightmap-1.0') { + isHeightmap = true; + if (!defined(that._heightmapStructure)) { + that._heightmapStructure = { + heightScale : 1.0 / 5.0, + heightOffset : -1000.0, + elementsPerHeight : 1, + stride : 1, + elementMultiplier : 256.0, + isBigEndian : false, + lowestEncodedHeight : 0, + highestEncodedHeight : 256 * 256 - 1 + }; + } + hasWaterMask = true; + that._requestWaterMask = true; + } else if (data.format.indexOf('quantized-mesh-1.') !== 0) { + message = 'The tile format "' + data.format + '" is invalid or not supported.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + return; + } - var length = hasNormal ? normals.length : st.length; - var numComponents = hasNormal ? 3.0 : 2.0; - numVertices = length / numComponents; + var tileUrlTemplates = data.tiles; - var compressedLength = numVertices; - var numCompressedComponents = hasSt && hasNormal ? 2.0 : 1.0; - numCompressedComponents += hasTangent || hasBitangent ? 1.0 : 0.0; - compressedLength *= numCompressedComponents; + var availableTiles = data.available; + var availability; + if (defined(availableTiles)) { + availability = new TileAvailability(that._tilingScheme, availableTiles.length); - var compressedAttributes = new Float32Array(compressedLength); + for (var level = 0; level < availableTiles.length; ++level) { + var rangesAtLevel = availableTiles[level]; + var yTiles = that._tilingScheme.getNumberOfYTilesAtLevel(level); + if (!defined(overallAvailability[level])) { + overallAvailability[level] = []; + } - var normalIndex = 0; - for (i = 0; i < numVertices; ++i) { - if (hasSt) { - Cartesian2.fromArray(st, i * 2.0, scratchCartesian2); - compressedAttributes[normalIndex++] = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + for (var rangeIndex = 0; rangeIndex < rangesAtLevel.length; ++rangeIndex) { + var range = rangesAtLevel[rangeIndex]; + var yStart = yTiles - range.endY - 1; + var yEnd = yTiles - range.startY - 1; + overallAvailability[level].push([range.startX, yStart, range.endX, yEnd]); + availability.addAvailableTileRange(level, range.startX, yStart, range.endX, yEnd); + } + } } - var index = i * 3.0; - if (hasNormal && defined(tangents) && defined(bitangents)) { - Cartesian3.fromArray(normals, index, toEncode1); - Cartesian3.fromArray(tangents, index, toEncode2); - Cartesian3.fromArray(bitangents, index, toEncode3); + // The vertex normals defined in the 'octvertexnormals' extension is identical to the original + // contents of the original 'vertexnormals' extension. 'vertexnormals' extension is now + // deprecated, as the extensionLength for this extension was incorrectly using big endian. + // We maintain backwards compatibility with the legacy 'vertexnormal' implementation + // by setting the _littleEndianExtensionSize to false. Always prefer 'octvertexnormals' + // over 'vertexnormals' if both extensions are supported by the server. + if (defined(data.extensions) && data.extensions.indexOf('octvertexnormals') !== -1) { + hasVertexNormals = true; + } else if (defined(data.extensions) && data.extensions.indexOf('vertexnormals') !== -1) { + hasVertexNormals = true; + littleEndianExtensionSize = false; + } + if (defined(data.extensions) && data.extensions.indexOf('watermask') !== -1) { + hasWaterMask = true; + } - AttributeCompression.octPack(toEncode1, toEncode2, toEncode3, scratchCartesian2); - compressedAttributes[normalIndex++] = scratchCartesian2.x; - compressedAttributes[normalIndex++] = scratchCartesian2.y; - } else { - if (hasNormal) { - Cartesian3.fromArray(normals, index, toEncode1); - compressedAttributes[normalIndex++] = AttributeCompression.octEncodeFloat(toEncode1); + that._hasWaterMask = that._hasWaterMask || hasWaterMask; + that._hasVertexNormals = that._hasVertexNormals || hasVertexNormals; + if (defined(data.attribution)) { + if (attribution.length > 0) { + attribution += ' '; } + attribution += data.attribution; + } - if (hasTangent) { - Cartesian3.fromArray(tangents, index, toEncode1); - compressedAttributes[normalIndex++] = AttributeCompression.octEncodeFloat(toEncode1); - } + layers.push(new LayerInformation({ + resource: lastResource, + version: data.version, + isHeightmap: isHeightmap, + tileUrlTemplates: tileUrlTemplates, + availability: availability, + hasVertexNormals: hasVertexNormals, + hasWaterMask: hasWaterMask, + littleEndianExtensionSize: littleEndianExtensionSize + })); - if (hasBitangent) { - Cartesian3.fromArray(bitangents, index, toEncode1); - compressedAttributes[normalIndex++] = AttributeCompression.octEncodeFloat(toEncode1); + var parentUrl = data.parentUrl; + if (defined(parentUrl)) { + if (!defined(availability)) { + console.log('A layer.json can\'t have a parentUrl if it does\'t have an available array.'); + return when.resolve(); } + lastResource = lastResource.getDerivedResource({ + url: parentUrl + }); + lastResource.appendForwardSlash(); // Terrain always expects a directory + metadataResource = lastResource.getDerivedResource({ + url: 'layer.json' + }); + var parentMetadata = metadataResource.fetchJson(); + return when(parentMetadata, parseMetadataSuccess, parseMetadataFailure); } - } - - geometry.attributes.compressedAttributes = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : numCompressedComponents, - values : compressedAttributes - }); - - if (hasNormal) { - delete geometry.attributes.normal; - } - if (hasSt) { - delete geometry.attributes.st; - } - if (hasBitangent) { - delete geometry.attributes.bitangent; - } - if (hasTangent) { - delete geometry.attributes.tangent; - } - - return geometry; - }; - - function indexTriangles(geometry) { - if (defined(geometry.indices)) { - return geometry; - } - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - - if (numberOfVertices < 3) { - throw new DeveloperError('The number of vertices must be at least three.'); - } - if (numberOfVertices % 3 !== 0) { - throw new DeveloperError('The number of vertices must be a multiple of three.'); - } - - var indices = IndexDatatype.createTypedArray(numberOfVertices, numberOfVertices); - for (var i = 0; i < numberOfVertices; ++i) { - indices[i] = i; - } - - geometry.indices = indices; - return geometry; - } - - function indexTriangleFan(geometry) { - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - if (numberOfVertices < 3) { - throw new DeveloperError('The number of vertices must be at least three.'); + return when.resolve(); } - - var indices = IndexDatatype.createTypedArray(numberOfVertices, (numberOfVertices - 2) * 3); - indices[0] = 1; - indices[1] = 0; - indices[2] = 2; - var indicesIndex = 3; - for (var i = 3; i < numberOfVertices; ++i) { - indices[indicesIndex++] = i - 1; - indices[indicesIndex++] = 0; - indices[indicesIndex++] = i; + function parseMetadataFailure(data) { + var message = 'An error occurred while accessing ' + metadataResource.url + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); } - geometry.indices = indices; - geometry.primitiveType = PrimitiveType.TRIANGLES; - return geometry; - } + function metadataSuccess(data) { + parseMetadataSuccess(data) + .then(function() { + if (defined(metadataError)) { + return; + } - function indexTriangleStrip(geometry) { - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + var length = overallAvailability.length; + if (length > 0) { + var availability = that._availability = new TileAvailability(that._tilingScheme, length); + for (var level = 0; level < length; ++level) { + var levelRanges = overallAvailability[level]; + for (var i = 0; i < levelRanges.length; ++i) { + var range = levelRanges[i]; + availability.addAvailableTileRange(level, range[0], range[1], range[2], range[3]); + } + } + } - if (numberOfVertices < 3) { - throw new DeveloperError('The number of vertices must be at least 3.'); - } - - var indices = IndexDatatype.createTypedArray(numberOfVertices, (numberOfVertices - 2) * 3); - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; + if (!defined(that._credit) && attribution.length > 0) { + that._credit = new Credit({text: attribution}); + } - if (numberOfVertices > 3) { - indices[3] = 0; - indices[4] = 2; - indices[5] = 3; + that._ready = true; + that._readyPromise.resolve(true); + }); } - var indicesIndex = 6; - for (var i = 3; i < numberOfVertices - 1; i += 2) { - indices[indicesIndex++] = i; - indices[indicesIndex++] = i - 1; - indices[indicesIndex++] = i + 1; - - if (i + 2 < numberOfVertices) { - indices[indicesIndex++] = i; - indices[indicesIndex++] = i + 1; - indices[indicesIndex++] = i + 2; + function metadataFailure(data) { + // If the metadata is not found, assume this is a pre-metadata heightmap tileset. + if (defined(data) && data.statusCode === 404) { + metadataSuccess({ + tilejson: '2.1.0', + format : 'heightmap-1.0', + version : '1.0.0', + scheme : 'tms', + tiles : [ + '{z}/{x}/{y}.terrain?v={version}' + ] + }); + return; } + parseMetadataFailure(data); } - geometry.indices = indices; - geometry.primitiveType = PrimitiveType.TRIANGLES; - return geometry; - } - - function indexLines(geometry) { - if (defined(geometry.indices)) { - return geometry; - } - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - - if (numberOfVertices < 2) { - throw new DeveloperError('The number of vertices must be at least two.'); - } - if (numberOfVertices % 2 !== 0) { - throw new DeveloperError('The number of vertices must be a multiple of 2.'); - } - - var indices = IndexDatatype.createTypedArray(numberOfVertices, numberOfVertices); - for (var i = 0; i < numberOfVertices; ++i) { - indices[i] = i; + function requestMetadata() { + var metadata = metadataResource.fetchJson(); + when(metadata, metadataSuccess, metadataFailure); } - geometry.indices = indices; - return geometry; + requestMetadata(); } - function indexLineStrip(geometry) { - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + /** + * When using the Quantized-Mesh format, a tile may be returned that includes additional extensions, such as PerVertexNormals, watermask, etc. + * This enumeration defines the unique identifiers for each type of extension data that has been appended to the standard mesh data. + * + * @exports QuantizedMeshExtensionIds + * @see CesiumTerrainProvider + * @private + */ + var QuantizedMeshExtensionIds = { + /** + * Oct-Encoded Per-Vertex Normals are included as an extension to the tile mesh + * + * @type {Number} + * @constant + * @default 1 + */ + OCT_VERTEX_NORMALS: 1, + /** + * A watermask is included as an extension to the tile mesh + * + * @type {Number} + * @constant + * @default 2 + */ + WATER_MASK: 2 + }; - if (numberOfVertices < 2) { - throw new DeveloperError('The number of vertices must be at least two.'); - } - - var indices = IndexDatatype.createTypedArray(numberOfVertices, (numberOfVertices - 1) * 2); - indices[0] = 0; - indices[1] = 1; - var indicesIndex = 2; - for (var i = 2; i < numberOfVertices; ++i) { - indices[indicesIndex++] = i - 1; - indices[indicesIndex++] = i; + function getRequestHeader(extensionsList) { + if (!defined(extensionsList) || extensionsList.length === 0) { + return { + Accept : 'application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01' + }; } + var extensions = extensionsList.join('-'); + return { + Accept : 'application/vnd.quantized-mesh;extensions=' + extensions + ',application/octet-stream;q=0.9,*/*;q=0.01' + }; + } - geometry.indices = indices; - geometry.primitiveType = PrimitiveType.LINES; - return geometry; + function createHeightmapTerrainData(provider, buffer, level, x, y, tmsY) { + var heightBuffer = new Uint16Array(buffer, 0, provider._heightmapWidth * provider._heightmapWidth); + return new HeightmapTerrainData({ + buffer : heightBuffer, + childTileMask : new Uint8Array(buffer, heightBuffer.byteLength, 1)[0], + waterMask : new Uint8Array(buffer, heightBuffer.byteLength + 1, buffer.byteLength - heightBuffer.byteLength - 1), + width : provider._heightmapWidth, + height : provider._heightmapWidth, + structure : provider._heightmapStructure + }); } - function indexLineLoop(geometry) { - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + function createQuantizedMeshTerrainData(provider, buffer, level, x, y, tmsY, littleEndianExtensionSize) { + var pos = 0; + var cartesian3Elements = 3; + var boundingSphereElements = cartesian3Elements + 1; + var cartesian3Length = Float64Array.BYTES_PER_ELEMENT * cartesian3Elements; + var boundingSphereLength = Float64Array.BYTES_PER_ELEMENT * boundingSphereElements; + var encodedVertexElements = 3; + var encodedVertexLength = Uint16Array.BYTES_PER_ELEMENT * encodedVertexElements; + var triangleElements = 3; + var bytesPerIndex = Uint16Array.BYTES_PER_ELEMENT; + var triangleLength = bytesPerIndex * triangleElements; - if (numberOfVertices < 2) { - throw new DeveloperError('The number of vertices must be at least two.'); - } - - var indices = IndexDatatype.createTypedArray(numberOfVertices, numberOfVertices * 2); + var view = new DataView(buffer); + var center = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)); + pos += cartesian3Length; - indices[0] = 0; - indices[1] = 1; + var minimumHeight = view.getFloat32(pos, true); + pos += Float32Array.BYTES_PER_ELEMENT; + var maximumHeight = view.getFloat32(pos, true); + pos += Float32Array.BYTES_PER_ELEMENT; - var indicesIndex = 2; - for (var i = 2; i < numberOfVertices; ++i) { - indices[indicesIndex++] = i - 1; - indices[indicesIndex++] = i; - } + var boundingSphere = new BoundingSphere( + new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)), + view.getFloat64(pos + cartesian3Length, true)); + pos += boundingSphereLength; - indices[indicesIndex++] = numberOfVertices - 1; - indices[indicesIndex] = 0; + var horizonOcclusionPoint = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)); + pos += cartesian3Length; - geometry.indices = indices; - geometry.primitiveType = PrimitiveType.LINES; - return geometry; - } + var vertexCount = view.getUint32(pos, true); + pos += Uint32Array.BYTES_PER_ELEMENT; + var encodedVertexBuffer = new Uint16Array(buffer, pos, vertexCount * 3); + pos += vertexCount * encodedVertexLength; - function indexPrimitive(geometry) { - switch (geometry.primitiveType) { - case PrimitiveType.TRIANGLE_FAN: - return indexTriangleFan(geometry); - case PrimitiveType.TRIANGLE_STRIP: - return indexTriangleStrip(geometry); - case PrimitiveType.TRIANGLES: - return indexTriangles(geometry); - case PrimitiveType.LINE_STRIP: - return indexLineStrip(geometry); - case PrimitiveType.LINE_LOOP: - return indexLineLoop(geometry); - case PrimitiveType.LINES: - return indexLines(geometry); + if (vertexCount > 64 * 1024) { + // More than 64k vertices, so indices are 32-bit. + bytesPerIndex = Uint32Array.BYTES_PER_ELEMENT; + triangleLength = bytesPerIndex * triangleElements; } - return geometry; - } + // Decode the vertex buffer. + var uBuffer = encodedVertexBuffer.subarray(0, vertexCount); + var vBuffer = encodedVertexBuffer.subarray(vertexCount, 2 * vertexCount); + var heightBuffer = encodedVertexBuffer.subarray(vertexCount * 2, 3 * vertexCount); - function offsetPointFromXZPlane(p, isBehind) { - if (Math.abs(p.y) < CesiumMath.EPSILON6){ - if (isBehind) { - p.y = -CesiumMath.EPSILON6; - } else { - p.y = CesiumMath.EPSILON6; - } - } - } + AttributeCompression.zigZagDeltaDecode(uBuffer, vBuffer, heightBuffer); - function offsetTriangleFromXZPlane(p0, p1, p2) { - if (p0.y !== 0.0 && p1.y !== 0.0 && p2.y !== 0.0) { - offsetPointFromXZPlane(p0, p0.y < 0.0); - offsetPointFromXZPlane(p1, p1.y < 0.0); - offsetPointFromXZPlane(p2, p2.y < 0.0); - return; + // skip over any additional padding that was added for 2/4 byte alignment + if (pos % bytesPerIndex !== 0) { + pos += (bytesPerIndex - (pos % bytesPerIndex)); } - var p0y = Math.abs(p0.y); - var p1y = Math.abs(p1.y); - var p2y = Math.abs(p2.y); + var triangleCount = view.getUint32(pos, true); + pos += Uint32Array.BYTES_PER_ELEMENT; + var indices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, triangleCount * triangleElements); + pos += triangleCount * triangleLength; - var sign; - if (p0y > p1y) { - if (p0y > p2y) { - sign = CesiumMath.sign(p0.y); - } else { - sign = CesiumMath.sign(p2.y); + // High water mark decoding based on decompressIndices_ in webgl-loader's loader.js. + // https://code.google.com/p/webgl-loader/source/browse/trunk/samples/loader.js?r=99#55 + // Copyright 2012 Google Inc., Apache 2.0 license. + var highest = 0; + var length = indices.length; + for (var i = 0; i < length; ++i) { + var code = indices[i]; + indices[i] = highest - code; + if (code === 0) { + ++highest; } - } else if (p1y > p2y) { - sign = CesiumMath.sign(p1.y); - } else { - sign = CesiumMath.sign(p2.y); } - var isBehind = sign < 0.0; - offsetPointFromXZPlane(p0, isBehind); - offsetPointFromXZPlane(p1, isBehind); - offsetPointFromXZPlane(p2, isBehind); - } + var westVertexCount = view.getUint32(pos, true); + pos += Uint32Array.BYTES_PER_ELEMENT; + var westIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, westVertexCount); + pos += westVertexCount * bytesPerIndex; - var c3 = new Cartesian3(); - function getXZIntersectionOffsetPoints(p, p1, u1, v1) { - Cartesian3.add(p, Cartesian3.multiplyByScalar(Cartesian3.subtract(p1, p, c3), p.y/(p.y-p1.y), c3), u1); - Cartesian3.clone(u1, v1); - offsetPointFromXZPlane(u1, true); - offsetPointFromXZPlane(v1, false); - } + var southVertexCount = view.getUint32(pos, true); + pos += Uint32Array.BYTES_PER_ELEMENT; + var southIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, southVertexCount); + pos += southVertexCount * bytesPerIndex; - var u1 = new Cartesian3(); - var u2 = new Cartesian3(); - var q1 = new Cartesian3(); - var q2 = new Cartesian3(); + var eastVertexCount = view.getUint32(pos, true); + pos += Uint32Array.BYTES_PER_ELEMENT; + var eastIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, eastVertexCount); + pos += eastVertexCount * bytesPerIndex; - var splitTriangleResult = { - positions : new Array(7), - indices : new Array(3 * 3) - }; + var northVertexCount = view.getUint32(pos, true); + pos += Uint32Array.BYTES_PER_ELEMENT; + var northIndices = IndexDatatype.createTypedArrayFromArrayBuffer(vertexCount, buffer, pos, northVertexCount); + pos += northVertexCount * bytesPerIndex; - function splitTriangle(p0, p1, p2) { - // In WGS84 coordinates, for a triangle approximately on the - // ellipsoid to cross the IDL, first it needs to be on the - // negative side of the plane x = 0. - if ((p0.x >= 0.0) || (p1.x >= 0.0) || (p2.x >= 0.0)) { - return undefined; - } + var encodedNormalBuffer; + var waterMaskBuffer; + while (pos < view.byteLength) { + var extensionId = view.getUint8(pos, true); + pos += Uint8Array.BYTES_PER_ELEMENT; + var extensionLength = view.getUint32(pos, littleEndianExtensionSize); + pos += Uint32Array.BYTES_PER_ELEMENT; - offsetTriangleFromXZPlane(p0, p1, p2); + if (extensionId === QuantizedMeshExtensionIds.OCT_VERTEX_NORMALS && provider._requestVertexNormals) { + encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); + } else if (extensionId === QuantizedMeshExtensionIds.WATER_MASK && provider._requestWaterMask) { + waterMaskBuffer = new Uint8Array(buffer, pos, extensionLength); + } + pos += extensionLength; + } - var p0Behind = p0.y < 0.0; - var p1Behind = p1.y < 0.0; - var p2Behind = p2.y < 0.0; + var skirtHeight = provider.getLevelMaximumGeometricError(level) * 5.0; - var numBehind = 0; - numBehind += p0Behind ? 1 : 0; - numBehind += p1Behind ? 1 : 0; - numBehind += p2Behind ? 1 : 0; + var rectangle = provider._tilingScheme.tileXYToRectangle(x, y, level); + var orientedBoundingBox; + if (rectangle.width < CesiumMath.PI_OVER_TWO + CesiumMath.EPSILON5) { + // Here, rectangle.width < pi/2, and rectangle.height < pi + // (though it would still work with rectangle.width up to pi) - var indices = splitTriangleResult.indices; + // The skirt is not included in the OBB computation. If this ever + // causes any rendering artifacts (cracks), they are expected to be + // minor and in the corners of the screen. It's possible that this + // might need to be changed - just change to `minimumHeight - skirtHeight` + // A similar change might also be needed in `upsampleQuantizedTerrainMesh.js`. + orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, provider._tilingScheme.ellipsoid); + } - if (numBehind === 1) { - indices[1] = 3; - indices[2] = 4; - indices[5] = 6; - indices[7] = 6; - indices[8] = 5; - - if (p0Behind) { - getXZIntersectionOffsetPoints(p0, p1, u1, q1); - getXZIntersectionOffsetPoints(p0, p2, u2, q2); - - indices[0] = 0; - indices[3] = 1; - indices[4] = 2; - indices[6] = 1; - } else if (p1Behind) { - getXZIntersectionOffsetPoints(p1, p2, u1, q1); - getXZIntersectionOffsetPoints(p1, p0, u2, q2); - - indices[0] = 1; - indices[3] = 2; - indices[4] = 0; - indices[6] = 2; - } else if (p2Behind) { - getXZIntersectionOffsetPoints(p2, p0, u1, q1); - getXZIntersectionOffsetPoints(p2, p1, u2, q2); - - indices[0] = 2; - indices[3] = 0; - indices[4] = 1; - indices[6] = 0; - } - } else if (numBehind === 2) { - indices[2] = 4; - indices[4] = 4; - indices[5] = 3; - indices[7] = 5; - indices[8] = 6; - - if (!p0Behind) { - getXZIntersectionOffsetPoints(p0, p1, u1, q1); - getXZIntersectionOffsetPoints(p0, p2, u2, q2); - - indices[0] = 1; - indices[1] = 2; - indices[3] = 1; - indices[6] = 0; - } else if (!p1Behind) { - getXZIntersectionOffsetPoints(p1, p2, u1, q1); - getXZIntersectionOffsetPoints(p1, p0, u2, q2); + return new QuantizedMeshTerrainData({ + center : center, + minimumHeight : minimumHeight, + maximumHeight : maximumHeight, + boundingSphere : boundingSphere, + orientedBoundingBox : orientedBoundingBox, + horizonOcclusionPoint : horizonOcclusionPoint, + quantizedVertices : encodedVertexBuffer, + encodedNormals : encodedNormalBuffer, + indices : indices, + westIndices : westIndices, + southIndices : southIndices, + eastIndices : eastIndices, + northIndices : northIndices, + westSkirtHeight : skirtHeight, + southSkirtHeight : skirtHeight, + eastSkirtHeight : skirtHeight, + northSkirtHeight : skirtHeight, + childTileMask: provider.availability.computeChildMaskForTile(level, x, y), + waterMask: waterMaskBuffer + }); + } - indices[0] = 2; - indices[1] = 0; - indices[3] = 2; - indices[6] = 1; - } else if (!p2Behind) { - getXZIntersectionOffsetPoints(p2, p0, u1, q1); - getXZIntersectionOffsetPoints(p2, p1, u2, q2); + /** + * Requests the geometry for a given tile. This function should not be called before + * {@link CesiumTerrainProvider#ready} returns true. The result must include terrain data and + * may optionally include a water mask and an indication of which child tiles are available. + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @param {Request} [request] The request object. Intended for internal use only. + * + * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * returns undefined instead of a promise, it is an indication that too many requests are already + * pending and the request will be retried later. + * + * @exception {DeveloperError} This function must not be called before {@link CesiumTerrainProvider#ready} + * returns true. + */ + CesiumTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestTileGeometry must not be called before the terrain provider is ready.'); + } + + var layers = this._layers; + var layerToUse; + var layerCount = layers.length; - indices[0] = 0; - indices[1] = 1; - indices[3] = 0; - indices[6] = 2; + if (layerCount === 1) { // Optimized path for single layers + layerToUse = layers[0]; + } else { + for (var i = 0; i < layerCount; ++i) { + var layer = layers[i]; + if (!defined(layer.availability) || layer.availability.isTileAvailable(level, x, y)) { + layerToUse = layer; + break; + } } } - var positions = splitTriangleResult.positions; - positions[0] = p0; - positions[1] = p1; - positions[2] = p2; - positions.length = 3; - - if (numBehind === 1 || numBehind === 2) { - positions[3] = u1; - positions[4] = u2; - positions[5] = q1; - positions[6] = q2; - positions.length = 7; + if (!defined(layerToUse)) { + return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); } - return splitTriangleResult; - } - - function updateGeometryAfterSplit(geometry, computeBoundingSphere) { - var attributes = geometry.attributes; - - if (attributes.position.values.length === 0) { + var urlTemplates = layerToUse.tileUrlTemplates; + if (urlTemplates.length === 0) { return undefined; } - for (var property in attributes) { - if (attributes.hasOwnProperty(property) && - defined(attributes[property]) && - defined(attributes[property].values)) { - - var attribute = attributes[property]; - attribute.values = ComponentDatatype.createTypedArray(attribute.componentDatatype, attribute.values); - } - } + var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level); - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - geometry.indices = IndexDatatype.createTypedArray(numberOfVertices, geometry.indices); + var tmsY = (yTiles - y - 1); - if (computeBoundingSphere) { - geometry.boundingSphere = BoundingSphere.fromVertices(attributes.position.values); + var extensionList = []; + if (this._requestVertexNormals && layerToUse.hasVertexNormals) { + extensionList.push(layerToUse.littleEndianExtensionSize ? 'octvertexnormals' : 'vertexnormals'); } - - return geometry; - } - - function copyGeometryForSplit(geometry) { - var attributes = geometry.attributes; - var copiedAttributes = {}; - - for (var property in attributes) { - if (attributes.hasOwnProperty(property) && - defined(attributes[property]) && - defined(attributes[property].values)) { - - var attribute = attributes[property]; - copiedAttributes[property] = new GeometryAttribute({ - componentDatatype : attribute.componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize, - values : [] - }); - } + if (this._requestWaterMask && layerToUse.hasWaterMask) { + extensionList.push('watermask'); } - return new Geometry({ - attributes : copiedAttributes, - indices : [], - primitiveType : geometry.primitiveType + var resource = layerToUse.resource.getDerivedResource({ + url: urlTemplates[(x + tmsY + level) % urlTemplates.length], + templateValues: { + version: layerToUse.version, + z: level, + x: x, + y: tmsY + }, + headers: getRequestHeader(extensionList), + request: request }); - } - - function updateInstanceAfterSplit(instance, westGeometry, eastGeometry) { - var computeBoundingSphere = defined(instance.geometry.boundingSphere); - westGeometry = updateGeometryAfterSplit(westGeometry, computeBoundingSphere); - eastGeometry = updateGeometryAfterSplit(eastGeometry, computeBoundingSphere); + var promise = resource.fetchArrayBuffer(); - if (defined(eastGeometry) && !defined(westGeometry)) { - instance.geometry = eastGeometry; - } else if (!defined(eastGeometry) && defined(westGeometry)) { - instance.geometry = westGeometry; - } else { - instance.westHemisphereGeometry = westGeometry; - instance.eastHemisphereGeometry = eastGeometry; - instance.geometry = undefined; + if (!defined(promise)) { + return undefined; } - } - - var p0Scratch = new Cartesian3(); - var p1Scratch = new Cartesian3(); - var p2Scratch = new Cartesian3(); - var barycentricScratch = new Cartesian3(); - var s0Scratch = new Cartesian2(); - var s1Scratch = new Cartesian2(); - var s2Scratch = new Cartesian2(); - function computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex) { - if (!defined(normals) && !defined(tangents) && !defined(bitangents) && !defined(texCoords) && !defined(extrudeDirections)) { - return; - } + var that = this; + return when(promise, function(buffer) { + if (defined(that._heightmapStructure)) { + return createHeightmapTerrainData(that, buffer, level, x, y, tmsY); + } + return createQuantizedMeshTerrainData(that, buffer, level, x, y, tmsY, layerToUse.littleEndianExtensionSize); + }); + }; - var p0 = Cartesian3.fromArray(positions, i0 * 3, p0Scratch); - var p1 = Cartesian3.fromArray(positions, i1 * 3, p1Scratch); - var p2 = Cartesian3.fromArray(positions, i2 * 3, p2Scratch); - var coords = barycentricCoordinates(point, p0, p1, p2, barycentricScratch); + defineProperties(CesiumTerrainProvider.prototype, { + /** + * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof CesiumTerrainProvider.prototype + * @type {Event} + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, - if (defined(normals)) { - var n0 = Cartesian3.fromArray(normals, i0 * 3, p0Scratch); - var n1 = Cartesian3.fromArray(normals, i1 * 3, p1Scratch); - var n2 = Cartesian3.fromArray(normals, i2 * 3, p2Scratch); + /** + * Gets the credit to display when this terrain provider is active. Typically this is used to credit + * the source of the terrain. This function should not be called before {@link CesiumTerrainProvider#ready} returns true. + * @memberof CesiumTerrainProvider.prototype + * @type {Credit} + */ + credit : { + get : function() { + if (!this._ready) { + throw new DeveloperError('credit must not be called before the terrain provider is ready.'); + } + + return this._credit; + } + }, - Cartesian3.multiplyByScalar(n0, coords.x, n0); - Cartesian3.multiplyByScalar(n1, coords.y, n1); - Cartesian3.multiplyByScalar(n2, coords.z, n2); + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link CesiumTerrainProvider#ready} returns true. + * @memberof CesiumTerrainProvider.prototype + * @type {GeographicTilingScheme} + */ + tilingScheme : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the terrain provider is ready.'); + } + + return this._tilingScheme; + } + }, - var normal = Cartesian3.add(n0, n1, n0); - Cartesian3.add(normal, n2, normal); - Cartesian3.normalize(normal, normal); + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + */ + ready : { + get : function() { + return this._ready; + } + }, - Cartesian3.pack(normal, currentAttributes.normal.values, insertedIndex * 3); - } + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof CesiumTerrainProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + }, - if (defined(extrudeDirections)) { - var d0 = Cartesian3.fromArray(extrudeDirections, i0 * 3, p0Scratch); - var d1 = Cartesian3.fromArray(extrudeDirections, i1 * 3, p1Scratch); - var d2 = Cartesian3.fromArray(extrudeDirections, i2 * 3, p2Scratch); + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link CesiumTerrainProvider#ready} returns true. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} + */ + hasWaterMask : { + get : function() { + if (!this._ready) { + throw new DeveloperError('hasWaterMask must not be called before the terrain provider is ready.'); + } + + return this._hasWaterMask && this._requestWaterMask; + } + }, - Cartesian3.multiplyByScalar(d0, coords.x, d0); - Cartesian3.multiplyByScalar(d1, coords.y, d1); - Cartesian3.multiplyByScalar(d2, coords.z, d2); + /** + * Gets a value indicating whether or not the requested tiles include vertex normals. + * This function should not be called before {@link CesiumTerrainProvider#ready} returns true. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} + */ + hasVertexNormals : { + get : function() { + if (!this._ready) { + throw new DeveloperError('hasVertexNormals must not be called before the terrain provider is ready.'); + } + + // returns true if we can request vertex normals from the server + return this._hasVertexNormals && this._requestVertexNormals; + } + }, - var direction; - if (!Cartesian3.equals(d0, Cartesian3.ZERO) || !Cartesian3.equals(d1, Cartesian3.ZERO) || !Cartesian3.equals(d2, Cartesian3.ZERO)) { - direction = Cartesian3.add(d0, d1, d0); - Cartesian3.add(direction, d2, direction); - Cartesian3.normalize(direction, direction); - } else { - direction = p0Scratch; - direction.x = 0; - direction.y = 0; - direction.z = 0; + /** + * Boolean flag that indicates if the client should request vertex normals from the server. + * Vertex normals data is appended to the standard tile mesh data only if the client requests the vertex normals and + * if the server provides vertex normals. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + */ + requestVertexNormals : { + get : function() { + return this._requestVertexNormals; } - Cartesian3.pack(direction, currentAttributes.extrudeDirection.values, insertedIndex * 3); - } + }, - if (defined(tangents)) { - var t0 = Cartesian3.fromArray(tangents, i0 * 3, p0Scratch); - var t1 = Cartesian3.fromArray(tangents, i1 * 3, p1Scratch); - var t2 = Cartesian3.fromArray(tangents, i2 * 3, p2Scratch); + /** + * Boolean flag that indicates if the client should request a watermask from the server. + * Watermask data is appended to the standard tile mesh data only if the client requests the watermask and + * if the server provides a watermask. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + */ + requestWaterMask : { + get : function() { + return this._requestWaterMask; + } + }, - Cartesian3.multiplyByScalar(t0, coords.x, t0); - Cartesian3.multiplyByScalar(t1, coords.y, t1); - Cartesian3.multiplyByScalar(t2, coords.z, t2); + /** + * Gets an object that can be used to determine availability of terrain from this provider, such as + * at points and in rectangles. This function should not be called before + * {@link CesiumTerrainProvider#ready} returns true. This property may be undefined if availability + * information is not available. + * @memberof CesiumTerrainProvider.prototype + * @type {TileAvailability} + */ + availability : { + get : function() { + if (!this._ready) { + throw new DeveloperError('availability must not be called before the terrain provider is ready.'); + } + return this._availability; + } + } + }); - var tangent = Cartesian3.add(t0, t1, t0); - Cartesian3.add(tangent, t2, tangent); - Cartesian3.normalize(tangent, tangent); + /** + * Gets the maximum geometric error allowed in a tile at a given level. + * + * @param {Number} level The tile level for which to get the maximum geometric error. + * @returns {Number} The maximum geometric error. + */ + CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { + return this._levelZeroMaximumGeometricError / (1 << level); + }; - Cartesian3.pack(tangent, currentAttributes.tangent.values, insertedIndex * 3); + /** + * Determines whether data for a tile is available to be loaded. + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @returns {Boolean} Undefined if not supported, otherwise true or false. + */ + CesiumTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + if (!defined(this._availability)) { + return undefined; } - if (defined(bitangents)) { - var b0 = Cartesian3.fromArray(bitangents, i0 * 3, p0Scratch); - var b1 = Cartesian3.fromArray(bitangents, i1 * 3, p1Scratch); - var b2 = Cartesian3.fromArray(bitangents, i2 * 3, p2Scratch); - - Cartesian3.multiplyByScalar(b0, coords.x, b0); - Cartesian3.multiplyByScalar(b1, coords.y, b1); - Cartesian3.multiplyByScalar(b2, coords.z, b2); + return this._availability.isTileAvailable(level, x, y); + }; - var bitangent = Cartesian3.add(b0, b1, b0); - Cartesian3.add(bitangent, b2, bitangent); - Cartesian3.normalize(bitangent, bitangent); + return CesiumTerrainProvider; +}); - Cartesian3.pack(bitangent, currentAttributes.bitangent.values, insertedIndex * 3); - } +define('Core/EllipseGeometryLibrary',[ + './Cartesian3', + './Math', + './Matrix3', + './Quaternion' + ], function( + Cartesian3, + CesiumMath, + Matrix3, + Quaternion) { + 'use strict'; - if (defined(texCoords)) { - var s0 = Cartesian2.fromArray(texCoords, i0 * 2, s0Scratch); - var s1 = Cartesian2.fromArray(texCoords, i1 * 2, s1Scratch); - var s2 = Cartesian2.fromArray(texCoords, i2 * 2, s2Scratch); + var EllipseGeometryLibrary = {}; - Cartesian2.multiplyByScalar(s0, coords.x, s0); - Cartesian2.multiplyByScalar(s1, coords.y, s1); - Cartesian2.multiplyByScalar(s2, coords.z, s2); + var rotAxis = new Cartesian3(); + var tempVec = new Cartesian3(); + var unitQuat = new Quaternion(); + var rotMtx = new Matrix3(); - var texCoord = Cartesian2.add(s0, s1, s0); - Cartesian2.add(texCoord, s2, texCoord); + function pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) { + var azimuth = theta + rotation; - Cartesian2.pack(texCoord, currentAttributes.st.values, insertedIndex * 2); - } - } + Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis); + Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec); + Cartesian3.add(rotAxis, tempVec, rotAxis); - function insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, currentIndex, point) { - var insertIndex = currentAttributes.position.values.length / 3; + var cosThetaSquared = Math.cos(theta); + cosThetaSquared = cosThetaSquared * cosThetaSquared; - if (currentIndex !== -1) { - var prevIndex = indices[currentIndex]; - var newIndex = currentIndexMap[prevIndex]; + var sinThetaSquared = Math.sin(theta); + sinThetaSquared = sinThetaSquared * sinThetaSquared; - if (newIndex === -1) { - currentIndexMap[prevIndex] = insertIndex; - currentAttributes.position.values.push(point.x, point.y, point.z); - currentIndices.push(insertIndex); - return insertIndex; - } + var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared); + var angle = radius / mag; - currentIndices.push(newIndex); - return newIndex; - } + // Create the quaternion to rotate the position vector to the boundary of the ellipse. + Quaternion.fromAxisAngle(rotAxis, angle, unitQuat); + Matrix3.fromQuaternion(unitQuat, rotMtx); - currentAttributes.position.values.push(point.x, point.y, point.z); - currentIndices.push(insertIndex); - return insertIndex; + Matrix3.multiplyByVector(rotMtx, unitPos, result); + Cartesian3.normalize(result, result); + Cartesian3.multiplyByScalar(result, mag, result); + return result; } - function splitLongitudeTriangles(instance) { - var geometry = instance.geometry; - var attributes = geometry.attributes; - var positions = attributes.position.values; - var normals = (defined(attributes.normal)) ? attributes.normal.values : undefined; - var bitangents = (defined(attributes.bitangent)) ? attributes.bitangent.values : undefined; - var tangents = (defined(attributes.tangent)) ? attributes.tangent.values : undefined; - var texCoords = (defined(attributes.st)) ? attributes.st.values : undefined; - var extrudeDirections = (defined(attributes.extrudeDirection)) ? attributes.extrudeDirection.values : undefined; - var indices = geometry.indices; + var scratchCartesian1 = new Cartesian3(); + var scratchCartesian2 = new Cartesian3(); + var scratchCartesian3 = new Cartesian3(); + var scratchNormal = new Cartesian3(); + /** + * Returns the positions raised to the given heights + * @private + */ + EllipseGeometryLibrary.raisePositionsToHeight = function(positions, options, extrude) { + var ellipsoid = options.ellipsoid; + var height = options.height; + var extrudedHeight = options.extrudedHeight; + var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3; - var eastGeometry = copyGeometryForSplit(geometry); - var westGeometry = copyGeometryForSplit(geometry); + var finalPositions = new Float64Array(size * 3); - var currentAttributes; - var currentIndices; - var currentIndexMap; - var insertedIndex; - var i; + var length = positions.length; + var bottomOffset = (extrude) ? length : 0; + for (var i = 0; i < length; i += 3) { + var i1 = i + 1; + var i2 = i + 2; - var westGeometryIndexMap = []; - westGeometryIndexMap.length = positions.length / 3; + var position = Cartesian3.fromArray(positions, i, scratchCartesian1); + ellipsoid.scaleToGeodeticSurface(position, position); - var eastGeometryIndexMap = []; - eastGeometryIndexMap.length = positions.length / 3; + var extrudedPosition = Cartesian3.clone(position, scratchCartesian2); + var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal); + var scaledNormal = Cartesian3.multiplyByScalar(normal, height, scratchCartesian3); + Cartesian3.add(position, scaledNormal, position); - for (i = 0; i < westGeometryIndexMap.length; ++i) { - westGeometryIndexMap[i] = -1; - eastGeometryIndexMap[i] = -1; - } + if (extrude) { + Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal); + Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition); - var len = indices.length; - for (i = 0; i < len; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; + finalPositions[i + bottomOffset] = extrudedPosition.x; + finalPositions[i1 + bottomOffset] = extrudedPosition.y; + finalPositions[i2 + bottomOffset] = extrudedPosition.z; + } - var p0 = Cartesian3.fromArray(positions, i0 * 3); - var p1 = Cartesian3.fromArray(positions, i1 * 3); - var p2 = Cartesian3.fromArray(positions, i2 * 3); + finalPositions[i] = position.x; + finalPositions[i1] = position.y; + finalPositions[i2] = position.z; + } - var result = splitTriangle(p0, p1, p2); - if (defined(result) && result.positions.length > 3) { - var resultPositions = result.positions; - var resultIndices = result.indices; - var resultLength = resultIndices.length; + return finalPositions; + }; - for (var j = 0; j < resultLength; ++j) { - var resultIndex = resultIndices[j]; - var point = resultPositions[resultIndex]; + var unitPosScratch = new Cartesian3(); + var eastVecScratch = new Cartesian3(); + var northVecScratch = new Cartesian3(); + /** + * Returns an array of positions that make up the ellipse. + * @private + */ + EllipseGeometryLibrary.computeEllipsePositions = function(options, addFillPositions, addEdgePositions) { + var semiMinorAxis = options.semiMinorAxis; + var semiMajorAxis = options.semiMajorAxis; + var rotation = options.rotation; + var center = options.center; - if (point.y < 0.0) { - currentAttributes = westGeometry.attributes; - currentIndices = westGeometry.indices; - currentIndexMap = westGeometryIndexMap; - } else { - currentAttributes = eastGeometry.attributes; - currentIndices = eastGeometry.indices; - currentIndexMap = eastGeometryIndexMap; - } + // Computing the arc-length of the ellipse is too expensive to be practical. Estimating it using the + // arc length of the sphere is too inaccurate and creates sharp edges when either the semi-major or + // semi-minor axis is much bigger than the other. Instead, scale the angle delta to make + // the distance along the ellipse boundary more closely match the granularity. + var granularity = options.granularity * 8.0; - insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, resultIndex < 3 ? i + resultIndex : -1, point); - computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); - } - } else { - if (defined(result)) { - p0 = result.positions[0]; - p1 = result.positions[1]; - p2 = result.positions[2]; - } + var aSqr = semiMinorAxis * semiMinorAxis; + var bSqr = semiMajorAxis * semiMajorAxis; + var ab = semiMajorAxis * semiMinorAxis; - if (p0.y < 0.0) { - currentAttributes = westGeometry.attributes; - currentIndices = westGeometry.indices; - currentIndexMap = westGeometryIndexMap; - } else { - currentAttributes = eastGeometry.attributes; - currentIndices = eastGeometry.indices; - currentIndexMap = eastGeometryIndexMap; - } + var mag = Cartesian3.magnitude(center); - insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i, p0); - computeTriangleAttributes(i0, i1, i2, p0, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); + var unitPos = Cartesian3.normalize(center, unitPosScratch); + var eastVec = Cartesian3.cross(Cartesian3.UNIT_Z, center, eastVecScratch); + eastVec = Cartesian3.normalize(eastVec, eastVec); + var northVec = Cartesian3.cross(unitPos, eastVec, northVecScratch); - insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 1, p1); - computeTriangleAttributes(i0, i1, i2, p1, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); + // The number of points in the first quadrant + var numPts = 1 + Math.ceil(CesiumMath.PI_OVER_TWO / granularity); - insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 2, p2); - computeTriangleAttributes(i0, i1, i2, p2, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); - } + var deltaTheta = CesiumMath.PI_OVER_TWO / (numPts - 1); + var theta = CesiumMath.PI_OVER_TWO - numPts * deltaTheta; + if (theta < 0.0) { + numPts -= Math.ceil(Math.abs(theta) / deltaTheta); } - updateInstanceAfterSplit(instance, westGeometry, eastGeometry); - } - - var xzPlane = Plane.fromPointNormal(Cartesian3.ZERO, Cartesian3.UNIT_Y); - - var offsetScratch = new Cartesian3(); - var offsetPointScratch = new Cartesian3(); - - function splitLongitudeLines(instance) { - var geometry = instance.geometry; - var attributes = geometry.attributes; - var positions = attributes.position.values; - var indices = geometry.indices; + // If the number of points were three, the ellipse + // would be tessellated like below: + // + // *---* + // / | \ | \ + // *---*---*---* + // / | \ | \ | \ | \ + // / .*---*---*---*. \ + // * ` | \ | \ | \ | `* + // \`.*---*---*---*.`/ + // \ | \ | \ | \ | / + // *---*---*---* + // \ | \ | / + // *---* + // The first and last column have one position and fan to connect to the adjacent column. + // Each other vertical column contains an even number of positions. + var size = 2 * (numPts * (numPts + 2)); + var positions = (addFillPositions) ? new Array(size * 3) : undefined; + var positionIndex = 0; + var position = scratchCartesian1; + var reflectedPosition = scratchCartesian2; - var eastGeometry = copyGeometryForSplit(geometry); - var westGeometry = copyGeometryForSplit(geometry); + var outerPositionsLength = (numPts * 4) * 3; + var outerRightIndex = outerPositionsLength - 1; + var outerLeftIndex = 0; + var outerPositions = (addEdgePositions) ? new Array(outerPositionsLength) : undefined; var i; - var length = indices.length; - - var westGeometryIndexMap = []; - westGeometryIndexMap.length = positions.length / 3; - - var eastGeometryIndexMap = []; - eastGeometryIndexMap.length = positions.length / 3; + var j; + var numInterior; + var t; + var interiorPosition; - for (i = 0; i < westGeometryIndexMap.length; ++i) { - westGeometryIndexMap[i] = -1; - eastGeometryIndexMap[i] = -1; + // Compute points in the 'eastern' half of the ellipse + theta = CesiumMath.PI_OVER_TWO; + position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); + if (addFillPositions) { + positions[positionIndex++] = position.x; + positions[positionIndex++] = position.y; + positions[positionIndex++] = position.z; } + if (addEdgePositions) { + outerPositions[outerRightIndex--] = position.z; + outerPositions[outerRightIndex--] = position.y; + outerPositions[outerRightIndex--] = position.x; + } + theta = CesiumMath.PI_OVER_TWO - deltaTheta; + for (i = 1; i < numPts + 1; ++i) { + position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); + reflectedPosition = pointOnEllipsoid(Math.PI - theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition); - for (i = 0; i < length; i += 2) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - - var p0 = Cartesian3.fromArray(positions, i0 * 3, p0Scratch); - var p1 = Cartesian3.fromArray(positions, i1 * 3, p1Scratch); + if (addFillPositions) { + positions[positionIndex++] = position.x; + positions[positionIndex++] = position.y; + positions[positionIndex++] = position.z; - if (Math.abs(p0.y) < CesiumMath.EPSILON6){ - if (p0.y < 0.0) { - p0.y = -CesiumMath.EPSILON6; - } else { - p0.y = CesiumMath.EPSILON6; + numInterior = 2 * i + 2; + for (j = 1; j < numInterior - 1; ++j) { + t = j / (numInterior - 1); + interiorPosition = Cartesian3.lerp(position, reflectedPosition, t, scratchCartesian3); + positions[positionIndex++] = interiorPosition.x; + positions[positionIndex++] = interiorPosition.y; + positions[positionIndex++] = interiorPosition.z; } - } - if (Math.abs(p1.y) < CesiumMath.EPSILON6){ - if (p1.y < 0.0) { - p1.y = -CesiumMath.EPSILON6; - } else { - p1.y = CesiumMath.EPSILON6; - } + positions[positionIndex++] = reflectedPosition.x; + positions[positionIndex++] = reflectedPosition.y; + positions[positionIndex++] = reflectedPosition.z; } - var p0Attributes = eastGeometry.attributes; - var p0Indices = eastGeometry.indices; - var p0IndexMap = eastGeometryIndexMap; - var p1Attributes = westGeometry.attributes; - var p1Indices = westGeometry.indices; - var p1IndexMap = westGeometryIndexMap; + if (addEdgePositions) { + outerPositions[outerRightIndex--] = position.z; + outerPositions[outerRightIndex--] = position.y; + outerPositions[outerRightIndex--] = position.x; + outerPositions[outerLeftIndex++] = reflectedPosition.x; + outerPositions[outerLeftIndex++] = reflectedPosition.y; + outerPositions[outerLeftIndex++] = reflectedPosition.z; + } - var intersection = IntersectionTests.lineSegmentPlane(p0, p1, xzPlane, p2Scratch); - if (defined(intersection)) { - // move point on the xz-plane slightly away from the plane - var offset = Cartesian3.multiplyByScalar(Cartesian3.UNIT_Y, 5.0 * CesiumMath.EPSILON9, offsetScratch); - if (p0.y < 0.0) { - Cartesian3.negate(offset, offset); + theta = CesiumMath.PI_OVER_TWO - (i + 1) * deltaTheta; + } - p0Attributes = westGeometry.attributes; - p0Indices = westGeometry.indices; - p0IndexMap = westGeometryIndexMap; - p1Attributes = eastGeometry.attributes; - p1Indices = eastGeometry.indices; - p1IndexMap = eastGeometryIndexMap; - } + // Compute points in the 'western' half of the ellipse + for (i = numPts; i > 1; --i) { + theta = CesiumMath.PI_OVER_TWO - (i - 1) * deltaTheta; - var offsetPoint = Cartesian3.add(intersection, offset, offsetPointScratch); - insertSplitPoint(p0Attributes, p0Indices, p0IndexMap, indices, i, p0); - insertSplitPoint(p0Attributes, p0Indices, p0IndexMap, indices, -1, offsetPoint); + position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); + reflectedPosition = pointOnEllipsoid(theta + Math.PI, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition); - Cartesian3.negate(offset, offset); - Cartesian3.add(intersection, offset, offsetPoint); - insertSplitPoint(p1Attributes, p1Indices, p1IndexMap, indices, -1, offsetPoint); - insertSplitPoint(p1Attributes, p1Indices, p1IndexMap, indices, i + 1, p1); - } else { - var currentAttributes; - var currentIndices; - var currentIndexMap; + if (addFillPositions) { + positions[positionIndex++] = position.x; + positions[positionIndex++] = position.y; + positions[positionIndex++] = position.z; - if (p0.y < 0.0) { - currentAttributes = westGeometry.attributes; - currentIndices = westGeometry.indices; - currentIndexMap = westGeometryIndexMap; - } else { - currentAttributes = eastGeometry.attributes; - currentIndices = eastGeometry.indices; - currentIndexMap = eastGeometryIndexMap; + numInterior = 2 * (i - 1) + 2; + for (j = 1; j < numInterior - 1; ++j) { + t = j / (numInterior - 1); + interiorPosition = Cartesian3.lerp(position, reflectedPosition, t, scratchCartesian3); + positions[positionIndex++] = interiorPosition.x; + positions[positionIndex++] = interiorPosition.y; + positions[positionIndex++] = interiorPosition.z; } - insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i, p0); - insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 1, p1); + positions[positionIndex++] = reflectedPosition.x; + positions[positionIndex++] = reflectedPosition.y; + positions[positionIndex++] = reflectedPosition.z; } - } - - updateInstanceAfterSplit(instance, westGeometry, eastGeometry); - } - - var cartesian2Scratch0 = new Cartesian2(); - var cartesian2Scratch1 = new Cartesian2(); - - var cartesian3Scratch0 = new Cartesian3(); - var cartesian3Scratch2 = new Cartesian3(); - var cartesian3Scratch3 = new Cartesian3(); - var cartesian3Scratch4 = new Cartesian3(); - var cartesian3Scratch5 = new Cartesian3(); - var cartesian3Scratch6 = new Cartesian3(); - - var cartesian4Scratch0 = new Cartesian4(); - - function updateAdjacencyAfterSplit(geometry) { - var attributes = geometry.attributes; - var positions = attributes.position.values; - var prevPositions = attributes.prevPosition.values; - var nextPositions = attributes.nextPosition.values; - var length = positions.length; - for (var j = 0; j < length; j += 3) { - var position = Cartesian3.unpack(positions, j, cartesian3Scratch0); - if (position.x > 0.0) { - continue; + if (addEdgePositions) { + outerPositions[outerRightIndex--] = position.z; + outerPositions[outerRightIndex--] = position.y; + outerPositions[outerRightIndex--] = position.x; + outerPositions[outerLeftIndex++] = reflectedPosition.x; + outerPositions[outerLeftIndex++] = reflectedPosition.y; + outerPositions[outerLeftIndex++] = reflectedPosition.z; } + } - var prevPosition = Cartesian3.unpack(prevPositions, j, cartesian3Scratch2); - if ((position.y < 0.0 && prevPosition.y > 0.0) || (position.y > 0.0 && prevPosition.y < 0.0)) { - if (j - 3 > 0) { - prevPositions[j] = positions[j - 3]; - prevPositions[j + 1] = positions[j - 2]; - prevPositions[j + 2] = positions[j - 1]; - } else { - Cartesian3.pack(position, prevPositions, j); - } - } + theta = CesiumMath.PI_OVER_TWO; + position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position); - var nextPosition = Cartesian3.unpack(nextPositions, j, cartesian3Scratch3); - if ((position.y < 0.0 && nextPosition.y > 0.0) || (position.y > 0.0 && nextPosition.y < 0.0)) { - if (j + 3 < length) { - nextPositions[j] = positions[j + 3]; - nextPositions[j + 1] = positions[j + 4]; - nextPositions[j + 2] = positions[j + 5]; - } else { - Cartesian3.pack(position, nextPositions, j); - } - } + var r = {}; + if (addFillPositions) { + positions[positionIndex++] = position.x; + positions[positionIndex++] = position.y; + positions[positionIndex++] = position.z; + r.positions = positions; + r.numPts = numPts; + } + if (addEdgePositions) { + outerPositions[outerRightIndex--] = position.z; + outerPositions[outerRightIndex--] = position.y; + outerPositions[outerRightIndex--] = position.x; + r.outerPositions = outerPositions; } - } - var offsetScalar = 5.0 * CesiumMath.EPSILON9; - var coplanarOffset = CesiumMath.EPSILON6; + return r; + }; - function splitLongitudePolyline(instance) { - var geometry = instance.geometry; - var attributes = geometry.attributes; - var positions = attributes.position.values; - var prevPositions = attributes.prevPosition.values; - var nextPositions = attributes.nextPosition.values; - var expandAndWidths = attributes.expandAndWidth.values; + return EllipseGeometryLibrary; +}); - var texCoords = (defined(attributes.st)) ? attributes.st.values : undefined; - var colors = (defined(attributes.color)) ? attributes.color.values : undefined; +define('Core/GeometryInstance',[ + './defaultValue', + './defined', + './DeveloperError', + './Matrix4' + ], function( + defaultValue, + defined, + DeveloperError, + Matrix4) { + 'use strict'; - var eastGeometry = copyGeometryForSplit(geometry); - var westGeometry = copyGeometryForSplit(geometry); + /** + * Geometry instancing allows one {@link Geometry} object to be positions in several + * different locations and colored uniquely. For example, one {@link BoxGeometry} can + * be instanced several times, each with a different <code>modelMatrix</code> to change + * its position, rotation, and scale. + * + * @alias GeometryInstance + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Geometry} options.geometry The geometry to instance. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix that transforms to transform the geometry from model to world coordinates. + * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} or get/set per-instance attributes with {@link Primitive#getGeometryInstanceAttributes}. + * @param {Object} [options.attributes] Per-instance attributes like a show or color attribute shown in the example below. + * + * + * @example + * // Create geometry for a box, and two instances that refer to it. + * // One instance positions the box on the bottom and colored aqua. + * // The other instance positions the box on the top and color white. + * var geometry = Cesium.BoxGeometry.fromDimensions({ + * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL, + * dimensions : new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0) + * }); + * var instanceBottom = new Cesium.GeometryInstance({ + * geometry : geometry, + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) + * }, + * id : 'bottom' + * }); + * var instanceTop = new Cesium.GeometryInstance({ + * geometry : geometry, + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 3000000.0), new Cesium.Matrix4()), + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) + * }, + * id : 'top' + * }); + * + * @see Geometry + */ + function GeometryInstance(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var i; - var j; - var index; + if (!defined(options.geometry)) { + throw new DeveloperError('options.geometry is required.'); + } + + /** + * The geometry being instanced. + * + * @type Geometry + * + * @default undefined + */ + this.geometry = options.geometry; - var intersectionFound = false; + /** + * The 4x4 transformation matrix that transforms the geometry from model to world coordinates. + * When this is the identity matrix, the geometry is drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. + * + * @type Matrix4 + * + * @default Matrix4.IDENTITY + */ + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - var length = positions.length / 3; - for (i = 0; i < length; i += 4) { - var i0 = i; - var i2 = i + 2; + /** + * User-defined object returned when the instance is picked or used to get/set per-instance attributes. + * + * @type Object + * + * @default undefined + * + * @see Scene#pick + * @see Primitive#getGeometryInstanceAttributes + */ + this.id = options.id; - var p0 = Cartesian3.fromArray(positions, i0 * 3, cartesian3Scratch0); - var p2 = Cartesian3.fromArray(positions, i2 * 3, cartesian3Scratch2); + /** + * Used for picking primitives that wrap geometry instances. + * + * @private + */ + this.pickPrimitive = options.pickPrimitive; - // Offset points that are close to the 180 longitude and change the previous/next point - // to be the same offset point so it can be projected to 2D. There is special handling in the - // shader for when position == prevPosition || position == nextPosition. - if (Math.abs(p0.y) < coplanarOffset) { - p0.y = coplanarOffset * (p2.y < 0.0 ? -1.0 : 1.0); - positions[i * 3 + 1] = p0.y; - positions[(i + 1) * 3 + 1] = p0.y; + /** + * Per-instance attributes like {@link ColorGeometryInstanceAttribute} or {@link ShowGeometryInstanceAttribute}. + * {@link Geometry} attributes varying per vertex; these attributes are constant for the entire instance. + * + * @type Object + * + * @default undefined + */ + this.attributes = defaultValue(options.attributes, {}); - for (j = i0 * 3; j < i0 * 3 + 4 * 3; j += 3) { - prevPositions[j] = positions[i * 3]; - prevPositions[j + 1] = positions[i * 3 + 1]; - prevPositions[j + 2] = positions[i * 3 + 2]; - } - } + /** + * @private + */ + this.westHemisphereGeometry = undefined; + /** + * @private + */ + this.eastHemisphereGeometry = undefined; + } - // Do the same but for when the line crosses 180 longitude in the opposite direction. - if (Math.abs(p2.y) < coplanarOffset) { - p2.y = coplanarOffset * (p0.y < 0.0 ? -1.0 : 1.0); - positions[(i + 2) * 3 + 1] = p2.y; - positions[(i + 3) * 3 + 1] = p2.y; + return GeometryInstance; +}); - for (j = i0 * 3; j < i0 * 3 + 4 * 3; j += 3) { - nextPositions[j] = positions[(i + 2) * 3]; - nextPositions[j + 1] = positions[(i + 2) * 3 + 1]; - nextPositions[j + 2] = positions[(i + 2) * 3 + 2]; - } - } +define('Core/EncodedCartesian3',[ + './Cartesian3', + './Check', + './defined' + ], function( + Cartesian3, + Check, + defined) { + 'use strict'; - var p0Attributes = eastGeometry.attributes; - var p0Indices = eastGeometry.indices; - var p2Attributes = westGeometry.attributes; - var p2Indices = westGeometry.indices; + /** + * A fixed-point encoding of a {@link Cartesian3} with 64-bit floating-point components, as two {@link Cartesian3} + * values that, when converted to 32-bit floating-point and added, approximate the original input. + * <p> + * This is used to encode positions in vertex buffers for rendering without jittering artifacts + * as described in {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. + * </p> + * + * @alias EncodedCartesian3 + * @constructor + * + * @private + */ + function EncodedCartesian3() { + /** + * The high bits for each component. Bits 0 to 22 store the whole value. Bits 23 to 31 are not used. + * + * @type {Cartesian3} + * @default {@link Cartesian3.ZERO} + */ + this.high = Cartesian3.clone(Cartesian3.ZERO); - var intersection = IntersectionTests.lineSegmentPlane(p0, p2, xzPlane, cartesian3Scratch4); - if (defined(intersection)) { - intersectionFound = true; + /** + * The low bits for each component. Bits 7 to 22 store the whole value, and bits 0 to 6 store the fraction. Bits 23 to 31 are not used. + * + * @type {Cartesian3} + * @default {@link Cartesian3.ZERO} + */ + this.low = Cartesian3.clone(Cartesian3.ZERO); + } - // move point on the xz-plane slightly away from the plane - var offset = Cartesian3.multiplyByScalar(Cartesian3.UNIT_Y, offsetScalar, cartesian3Scratch5); - if (p0.y < 0.0) { - Cartesian3.negate(offset, offset); - p0Attributes = westGeometry.attributes; - p0Indices = westGeometry.indices; - p2Attributes = eastGeometry.attributes; - p2Indices = eastGeometry.indices; - } + /** + * Encodes a 64-bit floating-point value as two floating-point values that, when converted to + * 32-bit floating-point and added, approximate the original input. The returned object + * has <code>high</code> and <code>low</code> properties for the high and low bits, respectively. + * <p> + * The fixed-point encoding follows {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. + * </p> + * + * @param {Number} value The floating-point value to encode. + * @param {Object} [result] The object onto which to store the result. + * @returns {Object} The modified result parameter or a new instance if one was not provided. + * + * @example + * var value = 1234567.1234567; + * var splitValue = Cesium.EncodedCartesian3.encode(value); + */ + EncodedCartesian3.encode = function(value, result) { + Check.typeOf.number('value', value); + + if (!defined(result)) { + result = { + high : 0.0, + low : 0.0 + }; + } - var offsetPoint = Cartesian3.add(intersection, offset, cartesian3Scratch6); - p0Attributes.position.values.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z); - p0Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p0Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + var doubleHigh; + if (value >= 0.0) { + doubleHigh = Math.floor(value / 65536.0) * 65536.0; + result.high = doubleHigh; + result.low = value - doubleHigh; + } else { + doubleHigh = Math.floor(-value / 65536.0) * 65536.0; + result.high = -doubleHigh; + result.low = value + doubleHigh; + } - p0Attributes.prevPosition.values.push(prevPositions[i0 * 3], prevPositions[i0 * 3 + 1], prevPositions[i0 * 3 + 2]); - p0Attributes.prevPosition.values.push(prevPositions[i0 * 3 + 3], prevPositions[i0 * 3 + 4], prevPositions[i0 * 3 + 5]); - p0Attributes.prevPosition.values.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z); + return result; + }; - p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + var scratchEncode = { + high : 0.0, + low : 0.0 + }; - Cartesian3.negate(offset, offset); - Cartesian3.add(intersection, offset, offsetPoint); - p2Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p2Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p2Attributes.position.values.push(p2.x, p2.y, p2.z, p2.x, p2.y, p2.z); + /** + * Encodes a {@link Cartesian3} with 64-bit floating-point components as two {@link Cartesian3} + * values that, when converted to 32-bit floating-point and added, approximate the original input. + * <p> + * The fixed-point encoding follows {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. + * </p> + * + * @param {Cartesian3} cartesian The cartesian to encode. + * @param {EncodedCartesian3} [result] The object onto which to store the result. + * @returns {EncodedCartesian3} The modified result parameter or a new EncodedCartesian3 instance if one was not provided. + * + * @example + * var cart = new Cesium.Cartesian3(-10000000.0, 0.0, 10000000.0); + * var encoded = Cesium.EncodedCartesian3.fromCartesian(cart); + */ + EncodedCartesian3.fromCartesian = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + + if (!defined(result)) { + result = new EncodedCartesian3(); + } - p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + var high = result.high; + var low = result.low; - p2Attributes.nextPosition.values.push(p2.x, p2.y, p2.z, p2.x, p2.y, p2.z); - p2Attributes.nextPosition.values.push(nextPositions[i2 * 3], nextPositions[i2 * 3 + 1], nextPositions[i2 * 3 + 2]); - p2Attributes.nextPosition.values.push(nextPositions[i2 * 3 + 3], nextPositions[i2 * 3 + 4], nextPositions[i2 * 3 + 5]); + EncodedCartesian3.encode(cartesian.x, scratchEncode); + high.x = scratchEncode.high; + low.x = scratchEncode.low; - var ew0 = Cartesian2.fromArray(expandAndWidths, i0 * 2, cartesian2Scratch0); - var width = Math.abs(ew0.y); + EncodedCartesian3.encode(cartesian.y, scratchEncode); + high.y = scratchEncode.high; + low.y = scratchEncode.low; - p0Attributes.expandAndWidth.values.push(-1, width, 1, width); - p0Attributes.expandAndWidth.values.push(-1, -width, 1, -width); - p2Attributes.expandAndWidth.values.push(-1, width, 1, width); - p2Attributes.expandAndWidth.values.push(-1, -width, 1, -width); + EncodedCartesian3.encode(cartesian.z, scratchEncode); + high.z = scratchEncode.high; + low.z = scratchEncode.low; - var t = Cartesian3.magnitudeSquared(Cartesian3.subtract(intersection, p0, cartesian3Scratch3)); - t /= Cartesian3.magnitudeSquared(Cartesian3.subtract(p2, p0, cartesian3Scratch3)); + return result; + }; - if (defined(colors)) { - var c0 = Cartesian4.fromArray(colors, i0 * 4, cartesian4Scratch0); - var c2 = Cartesian4.fromArray(colors, i2 * 4, cartesian4Scratch0); + var encodedP = new EncodedCartesian3(); - var r = CesiumMath.lerp(c0.x, c2.x, t); - var g = CesiumMath.lerp(c0.y, c2.y, t); - var b = CesiumMath.lerp(c0.z, c2.z, t); - var a = CesiumMath.lerp(c0.w, c2.w, t); + /** + * Encodes the provided <code>cartesian</code>, and writes it to an array with <code>high</code> + * components followed by <code>low</code> components, i.e. <code>[high.x, high.y, high.z, low.x, low.y, low.z]</code>. + * <p> + * This is used to create interleaved high-precision position vertex attributes. + * </p> + * + * @param {Cartesian3} cartesian The cartesian to encode. + * @param {Number[]} cartesianArray The array to write to. + * @param {Number} index The index into the array to start writing. Six elements will be written. + * + * @exception {DeveloperError} index must be a number greater than or equal to 0. + * + * @example + * var positions = [ + * new Cesium.Cartesian3(), + * // ... + * ]; + * var encodedPositions = new Float32Array(2 * 3 * positions.length); + * var j = 0; + * for (var i = 0; i < positions.length; ++i) { + * Cesium.EncodedCartesian3.writeElement(positions[i], encodedPositions, j); + * j += 6; + * } + */ + EncodedCartesian3.writeElements = function(cartesian, cartesianArray, index) { + Check.defined('cartesianArray', cartesianArray); + Check.typeOf.number('index', index); + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + + EncodedCartesian3.fromCartesian(cartesian, encodedP); + var high = encodedP.high; + var low = encodedP.low; - for (j = i0 * 4; j < i0 * 4 + 2 * 4; ++j) { - p0Attributes.color.values.push(colors[j]); - } - p0Attributes.color.values.push(r, g, b, a); - p0Attributes.color.values.push(r, g, b, a); - p2Attributes.color.values.push(r, g, b, a); - p2Attributes.color.values.push(r, g, b, a); - for (j = i2 * 4; j < i2 * 4 + 2 * 4; ++j) { - p2Attributes.color.values.push(colors[j]); - } - } + cartesianArray[index] = high.x; + cartesianArray[index + 1] = high.y; + cartesianArray[index + 2] = high.z; + cartesianArray[index + 3] = low.x; + cartesianArray[index + 4] = low.y; + cartesianArray[index + 5] = low.z; + }; - if (defined(texCoords)) { - var s0 = Cartesian2.fromArray(texCoords, i0 * 2, cartesian2Scratch0); - var s3 = Cartesian2.fromArray(texCoords, (i + 3) * 2, cartesian2Scratch1); + return EncodedCartesian3; +}); - var sx = CesiumMath.lerp(s0.x, s3.x, t); +define('Core/Tipsify',[ + './defaultValue', + './defined', + './DeveloperError' + ], function( + defaultValue, + defined, + DeveloperError) { + 'use strict'; - for (j = i0 * 2; j < i0 * 2 + 2 * 2; ++j) { - p0Attributes.st.values.push(texCoords[j]); - } - p0Attributes.st.values.push(sx, s0.y); - p0Attributes.st.values.push(sx, s3.y); - p2Attributes.st.values.push(sx, s0.y); - p2Attributes.st.values.push(sx, s3.y); - for (j = i2 * 2; j < i2 * 2 + 2 * 2; ++j) { - p2Attributes.st.values.push(texCoords[j]); - } - } + /** + * Encapsulates an algorithm to optimize triangles for the post + * vertex-shader cache. This is based on the 2007 SIGGRAPH paper + * 'Fast Triangle Reordering for Vertex Locality and Reduced Overdraw.' + * The runtime is linear but several passes are made. + * + * @exports Tipsify + * + * @see <a href='http://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf'> + * Fast Triangle Reordering for Vertex Locality and Reduced Overdraw</a> + * by Sander, Nehab, and Barczak + * + * @private + */ + var Tipsify = {}; - index = p0Attributes.position.values.length / 3 - 4; - p0Indices.push(index, index + 2, index + 1); - p0Indices.push(index + 1, index + 2, index + 3); + /** + * Calculates the average cache miss ratio (ACMR) for a given set of indices. + * + * @param {Object} options Object with the following properties: + * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices + * in the vertex buffer that define the geometry's triangles. + * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. + * If not supplied, this value will be computed. + * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. + * @returns {Number} The average cache miss ratio (ACMR). + * + * @exception {DeveloperError} indices length must be a multiple of three. + * @exception {DeveloperError} cacheSize must be greater than two. + * + * @example + * var indices = [0, 1, 2, 3, 4, 5]; + * var maxIndex = 5; + * var cacheSize = 3; + * var acmr = Cesium.Tipsify.calculateACMR({indices : indices, maxIndex : maxIndex, cacheSize : cacheSize}); + */ + Tipsify.calculateACMR = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var indices = options.indices; + var maximumIndex = options.maximumIndex; + var cacheSize = defaultValue(options.cacheSize, 24); - index = p2Attributes.position.values.length / 3 - 4; - p2Indices.push(index, index + 2, index + 1); - p2Indices.push(index + 1, index + 2, index + 3); - } else { - var currentAttributes; - var currentIndices; + if (!defined(indices)) { + throw new DeveloperError('indices is required.'); + } + + var numIndices = indices.length; - if (p0.y < 0.0) { - currentAttributes = westGeometry.attributes; - currentIndices = westGeometry.indices; - } else { - currentAttributes = eastGeometry.attributes; - currentIndices = eastGeometry.indices; + if (numIndices < 3 || numIndices % 3 !== 0) { + throw new DeveloperError('indices length must be a multiple of three.'); + } + if (maximumIndex <= 0) { + throw new DeveloperError('maximumIndex must be greater than zero.'); + } + if (cacheSize < 3) { + throw new DeveloperError('cacheSize must be greater than two.'); + } + + // Compute the maximumIndex if not given + if (!defined(maximumIndex)) { + maximumIndex = 0; + var currentIndex = 0; + var intoIndices = indices[currentIndex]; + while (currentIndex < numIndices) { + if (intoIndices > maximumIndex) { + maximumIndex = intoIndices; } + ++currentIndex; + intoIndices = indices[currentIndex]; + } + } - currentAttributes.position.values.push(p0.x, p0.y, p0.z); - currentAttributes.position.values.push(p0.x, p0.y, p0.z); - currentAttributes.position.values.push(p2.x, p2.y, p2.z); - currentAttributes.position.values.push(p2.x, p2.y, p2.z); + // Vertex time stamps + var vertexTimeStamps = []; + for ( var i = 0; i < maximumIndex + 1; i++) { + vertexTimeStamps[i] = 0; + } - for (j = i * 3; j < i * 3 + 4 * 3; ++j) { - currentAttributes.prevPosition.values.push(prevPositions[j]); - currentAttributes.nextPosition.values.push(nextPositions[j]); + // Cache processing + var s = cacheSize + 1; + for ( var j = 0; j < numIndices; ++j) { + if ((s - vertexTimeStamps[indices[j]]) > cacheSize) { + vertexTimeStamps[indices[j]] = s; + ++s; + } + } + + return (s - cacheSize + 1) / (numIndices / 3); + }; + + /** + * Optimizes triangles for the post-vertex shader cache. + * + * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices + * in the vertex buffer that define the geometry's triangles. + * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. + * If not supplied, this value will be computed. + * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. + * @returns {Number[]} A list of the input indices in an optimized order. + * + * @exception {DeveloperError} indices length must be a multiple of three. + * @exception {DeveloperError} cacheSize must be greater than two. + * + * @example + * var indices = [0, 1, 2, 3, 4, 5]; + * var maxIndex = 5; + * var cacheSize = 3; + * var reorderedIndices = Cesium.Tipsify.tipsify({indices : indices, maxIndex : maxIndex, cacheSize : cacheSize}); + */ + Tipsify.tipsify = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var indices = options.indices; + var maximumIndex = options.maximumIndex; + var cacheSize = defaultValue(options.cacheSize, 24); + + var cursor; + + function skipDeadEnd(vertices, deadEnd, indices, maximumIndexPlusOne) { + while (deadEnd.length >= 1) { + // while the stack is not empty + var d = deadEnd[deadEnd.length - 1]; // top of the stack + deadEnd.splice(deadEnd.length - 1, 1); // pop the stack + + if (vertices[d].numLiveTriangles > 0) { + return d; } + } - for (j = i * 2; j < i * 2 + 4 * 2; ++j) { - currentAttributes.expandAndWidth.values.push(expandAndWidths[j]); - if (defined(texCoords)) { - currentAttributes.st.values.push(texCoords[j]); - } + while (cursor < maximumIndexPlusOne) { + if (vertices[cursor].numLiveTriangles > 0) { + ++cursor; + return cursor - 1; } + ++cursor; + } + return -1; + } - if (defined(colors)) { - for (j = i * 4; j < i * 4 + 4 * 4; ++j) { - currentAttributes.color.values.push(colors[j]); + function getNextVertex(indices, cacheSize, oneRing, vertices, s, deadEnd, maximumIndexPlusOne) { + var n = -1; + var p; + var m = -1; + var itOneRing = 0; + while (itOneRing < oneRing.length) { + var index = oneRing[itOneRing]; + if (vertices[index].numLiveTriangles) { + p = 0; + if ((s - vertices[index].timeStamp + (2 * vertices[index].numLiveTriangles)) <= cacheSize) { + p = s - vertices[index].timeStamp; + } + if ((p > m) || (m === -1)) { + m = p; + n = index; } } - - index = currentAttributes.position.values.length / 3 - 4; - currentIndices.push(index, index + 2, index + 1); - currentIndices.push(index + 1, index + 2, index + 3); + ++itOneRing; } + if (n === -1) { + return skipDeadEnd(vertices, deadEnd, indices, maximumIndexPlusOne); + } + return n; } - if (intersectionFound) { - updateAdjacencyAfterSplit(westGeometry); - updateAdjacencyAfterSplit(eastGeometry); + if (!defined(indices)) { + throw new DeveloperError('indices is required.'); } + + var numIndices = indices.length; - updateInstanceAfterSplit(instance, westGeometry, eastGeometry); - } - - /** - * Splits the instances's geometry, by introducing new vertices and indices,that - * intersect the International Date Line and Prime Meridian so that no primitives cross longitude - * -180/180 degrees. This is not required for 3D drawing, but is required for - * correcting drawing in 2D and Columbus view. - * - * @private - * - * @param {GeometryInstance} instance The instance to modify. - * @returns {GeometryInstance} The modified <code>instance</code> argument, with it's geometry split at the International Date Line. - * - * @example - * instance = Cesium.GeometryPipeline.splitLongitude(instance); - */ - GeometryPipeline.splitLongitude = function(instance) { - if (!defined(instance)) { - throw new DeveloperError('instance is required.'); + if (numIndices < 3 || numIndices % 3 !== 0) { + throw new DeveloperError('indices length must be a multiple of three.'); + } + if (maximumIndex <= 0) { + throw new DeveloperError('maximumIndex must be greater than zero.'); + } + if (cacheSize < 3) { + throw new DeveloperError('cacheSize must be greater than two.'); } - var geometry = instance.geometry; - var boundingSphere = geometry.boundingSphere; - if (defined(boundingSphere)) { - var minX = boundingSphere.center.x - boundingSphere.radius; - if (minX > 0 || BoundingSphere.intersectPlane(boundingSphere, Plane.ORIGIN_ZX_PLANE) !== Intersect.INTERSECTING) { - return instance; + // Determine maximum index + var maximumIndexPlusOne = 0; + var currentIndex = 0; + var intoIndices = indices[currentIndex]; + var endIndex = numIndices; + if (defined(maximumIndex)) { + maximumIndexPlusOne = maximumIndex + 1; + } else { + while (currentIndex < endIndex) { + if (intoIndices > maximumIndexPlusOne) { + maximumIndexPlusOne = intoIndices; + } + ++currentIndex; + intoIndices = indices[currentIndex]; + } + if (maximumIndexPlusOne === -1) { + return 0; } + ++maximumIndexPlusOne; } - if (geometry.geometryType !== GeometryType.NONE) { - switch (geometry.geometryType) { - case GeometryType.POLYLINES: - splitLongitudePolyline(instance); - break; - case GeometryType.TRIANGLES: - splitLongitudeTriangles(instance); - break; - case GeometryType.LINES: - splitLongitudeLines(instance); - break; - } - } else { - indexPrimitive(geometry); - if (geometry.primitiveType === PrimitiveType.TRIANGLES) { - splitLongitudeTriangles(instance); - } else if (geometry.primitiveType === PrimitiveType.LINES) { - splitLongitudeLines(instance); + // Vertices + var vertices = []; + var i; + for (i = 0; i < maximumIndexPlusOne; i++) { + vertices[i] = { + numLiveTriangles : 0, + timeStamp : 0, + vertexTriangles : [] + }; + } + currentIndex = 0; + var triangle = 0; + while (currentIndex < endIndex) { + vertices[indices[currentIndex]].vertexTriangles.push(triangle); + ++(vertices[indices[currentIndex]]).numLiveTriangles; + vertices[indices[currentIndex + 1]].vertexTriangles.push(triangle); + ++(vertices[indices[currentIndex + 1]]).numLiveTriangles; + vertices[indices[currentIndex + 2]].vertexTriangles.push(triangle); + ++(vertices[indices[currentIndex + 2]]).numLiveTriangles; + ++triangle; + currentIndex += 3; + } + + // Starting index + var f = 0; + + // Time Stamp + var s = cacheSize + 1; + cursor = 1; + + // Process + var oneRing = []; + var deadEnd = []; //Stack + var vertex; + var intoVertices; + var currentOutputIndex = 0; + var outputIndices = []; + var numTriangles = numIndices / 3; + var triangleEmitted = []; + for (i = 0; i < numTriangles; i++) { + triangleEmitted[i] = false; + } + var index; + var limit; + while (f !== -1) { + oneRing = []; + intoVertices = vertices[f]; + limit = intoVertices.vertexTriangles.length; + for ( var k = 0; k < limit; ++k) { + triangle = intoVertices.vertexTriangles[k]; + if (!triangleEmitted[triangle]) { + triangleEmitted[triangle] = true; + currentIndex = triangle + triangle + triangle; + for ( var j = 0; j < 3; ++j) { + // Set this index as a possible next index + index = indices[currentIndex]; + oneRing.push(index); + deadEnd.push(index); + + // Output index + outputIndices[currentOutputIndex] = index; + ++currentOutputIndex; + + // Cache processing + vertex = vertices[index]; + --vertex.numLiveTriangles; + if ((s - vertex.timeStamp) > cacheSize) { + vertex.timeStamp = s; + ++s; + } + ++currentIndex; + } + } } + f = getNextVertex(indices, cacheSize, oneRing, vertices, s, deadEnd, maximumIndexPlusOne); } - return instance; + return outputIndices; }; - return GeometryPipeline; + return Tipsify; }); -define('Core/EllipseGeometry',[ +define('Core/GeometryPipeline',[ + './AttributeCompression', + './barycentricCoordinates', './BoundingSphere', './Cartesian2', './Cartesian3', + './Cartesian4', './Cartographic', './ComponentDatatype', './defaultValue', './defined', - './defineProperties', './DeveloperError', - './EllipseGeometryLibrary', - './Ellipsoid', + './EncodedCartesian3', './GeographicProjection', './Geometry', './GeometryAttribute', - './GeometryAttributes', - './GeometryInstance', - './GeometryPipeline', + './GeometryType', './IndexDatatype', + './Intersect', + './IntersectionTests', './Math', './Matrix3', './Matrix4', + './Plane', './PrimitiveType', - './Quaternion', - './Rectangle', - './Transforms', - './VertexFormat' + './Tipsify' ], function( + AttributeCompression, + barycentricCoordinates, BoundingSphere, Cartesian2, Cartesian3, + Cartesian4, Cartographic, ComponentDatatype, defaultValue, defined, - defineProperties, DeveloperError, - EllipseGeometryLibrary, - Ellipsoid, + EncodedCartesian3, GeographicProjection, Geometry, GeometryAttribute, - GeometryAttributes, - GeometryInstance, - GeometryPipeline, + GeometryType, IndexDatatype, + Intersect, + IntersectionTests, CesiumMath, Matrix3, Matrix4, + Plane, PrimitiveType, - Quaternion, - Rectangle, - Transforms, - VertexFormat) { + Tipsify) { 'use strict'; - var scratchCartesian1 = new Cartesian3(); - var scratchCartesian2 = new Cartesian3(); - var scratchCartesian3 = new Cartesian3(); - var scratchCartesian4 = new Cartesian3(); - var texCoordScratch = new Cartesian2(); - var textureMatrixScratch = new Matrix3(); - var quaternionScratch = new Quaternion(); - - var scratchNormal = new Cartesian3(); - var scratchTangent = new Cartesian3(); - var scratchBitangent = new Cartesian3(); - - var scratchCartographic = new Cartographic(); - var projectedCenterScratch = new Cartesian3(); - - var scratchMinTexCoord = new Cartesian2(); - var scratchMaxTexCoord = new Cartesian2(); - - function computeTopBottomAttributes(positions, options, extrude) { - var vertexFormat = options.vertexFormat; - var center = options.center; - var semiMajorAxis = options.semiMajorAxis; - var semiMinorAxis = options.semiMinorAxis; - var ellipsoid = options.ellipsoid; - var stRotation = options.stRotation; - var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3; - var shadowVolume = options.shadowVolume; - - var textureCoordinates = (vertexFormat.st) ? new Float32Array(size * 2) : undefined; - var normals = (vertexFormat.normal) ? new Float32Array(size * 3) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(size * 3) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(size * 3) : undefined; - - var extrudeNormals = (shadowVolume) ? new Float32Array(size * 3) : undefined; - - var textureCoordIndex = 0; - - // Raise positions to a height above the ellipsoid and compute the - // texture coordinates, normals, tangents, and bitangents. - var normal = scratchNormal; - var tangent = scratchTangent; - var bitangent = scratchBitangent; + /** + * Content pipeline functions for geometries. + * + * @exports GeometryPipeline + * + * @see Geometry + */ + var GeometryPipeline = {}; - var projection = new GeographicProjection(ellipsoid); - var projectedCenter = projection.project(ellipsoid.cartesianToCartographic(center, scratchCartographic), projectedCenterScratch); + function addTriangle(lines, index, i0, i1, i2) { + lines[index++] = i0; + lines[index++] = i1; - var geodeticNormal = ellipsoid.scaleToGeodeticSurface(center, scratchCartesian1); - ellipsoid.geodeticSurfaceNormal(geodeticNormal, geodeticNormal); - var rotation = Quaternion.fromAxisAngle(geodeticNormal, stRotation, quaternionScratch); - var textureMatrix = Matrix3.fromQuaternion(rotation, textureMatrixScratch); + lines[index++] = i1; + lines[index++] = i2; - var minTexCoord = Cartesian2.fromElements(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, scratchMinTexCoord); - var maxTexCoord = Cartesian2.fromElements(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, scratchMaxTexCoord); + lines[index++] = i2; + lines[index] = i0; + } - var length = positions.length; - var bottomOffset = (extrude) ? length : 0; - var stOffset = bottomOffset / 3 * 2; - for (var i = 0; i < length; i += 3) { - var i1 = i + 1; - var i2 = i + 2; - var position = Cartesian3.fromArray(positions, i, scratchCartesian1); + function trianglesToLines(triangles) { + var count = triangles.length; + var size = (count / 3) * 6; + var lines = IndexDatatype.createTypedArray(count, size); - if (vertexFormat.st) { - var rotatedPoint = Matrix3.multiplyByVector(textureMatrix, position, scratchCartesian2); - var projectedPoint = projection.project(ellipsoid.cartesianToCartographic(rotatedPoint, scratchCartographic), scratchCartesian3); - Cartesian3.subtract(projectedPoint, projectedCenter, projectedPoint); + var index = 0; + for ( var i = 0; i < count; i += 3, index += 6) { + addTriangle(lines, index, triangles[i], triangles[i + 1], triangles[i + 2]); + } - texCoordScratch.x = (projectedPoint.x + semiMajorAxis) / (2.0 * semiMajorAxis); - texCoordScratch.y = (projectedPoint.y + semiMinorAxis) / (2.0 * semiMinorAxis); + return lines; + } - minTexCoord.x = Math.min(texCoordScratch.x, minTexCoord.x); - minTexCoord.y = Math.min(texCoordScratch.y, minTexCoord.y); - maxTexCoord.x = Math.max(texCoordScratch.x, maxTexCoord.x); - maxTexCoord.y = Math.max(texCoordScratch.y, maxTexCoord.y); + function triangleStripToLines(triangles) { + var count = triangles.length; + if (count >= 3) { + var size = (count - 2) * 6; + var lines = IndexDatatype.createTypedArray(count, size); - if (extrude) { - textureCoordinates[textureCoordIndex + stOffset] = texCoordScratch.x; - textureCoordinates[textureCoordIndex + 1 + stOffset] = texCoordScratch.y; - } + addTriangle(lines, 0, triangles[0], triangles[1], triangles[2]); + var index = 6; - textureCoordinates[textureCoordIndex++] = texCoordScratch.x; - textureCoordinates[textureCoordIndex++] = texCoordScratch.y; + for ( var i = 3; i < count; ++i, index += 6) { + addTriangle(lines, index, triangles[i - 1], triangles[i], triangles[i - 2]); } - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) { - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - - if (shadowVolume) { - extrudeNormals[i + bottomOffset] = -normal.x; - extrudeNormals[i1 + bottomOffset] = -normal.y; - extrudeNormals[i2 + bottomOffset] = -normal.z; - } + return lines; + } - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - if (vertexFormat.tangent || vertexFormat.bitangent) { - tangent = Cartesian3.normalize(Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent), tangent); - Matrix3.multiplyByVector(textureMatrix, tangent, tangent); - } - if (vertexFormat.normal) { - normals[i] = normal.x; - normals[i1] = normal.y; - normals[i2] = normal.z; - if (extrude) { - normals[i + bottomOffset] = -normal.x; - normals[i1 + bottomOffset] = -normal.y; - normals[i2 + bottomOffset] = -normal.z; - } - } + return new Uint16Array(); + } - if (vertexFormat.tangent) { - tangents[i] = tangent.x; - tangents[i1] = tangent.y; - tangents[i2] = tangent.z; - if (extrude) { - tangents[i + bottomOffset] = -tangent.x; - tangents[i1 + bottomOffset] = -tangent.y; - tangents[i2 + bottomOffset] = -tangent.z; - } - } + function triangleFanToLines(triangles) { + if (triangles.length > 0) { + var count = triangles.length - 1; + var size = (count - 1) * 6; + var lines = IndexDatatype.createTypedArray(count, size); - if (vertexFormat.bitangent) { - bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); - bitangents[i ] = bitangent.x; - bitangents[i1] = bitangent.y; - bitangents[i2] = bitangent.z; - if (extrude) { - bitangents[i + bottomOffset] = bitangent.x; - bitangents[i1 + bottomOffset] = bitangent.y; - bitangents[i2 + bottomOffset] = bitangent.z; - } - } - } + var base = triangles[0]; + var index = 0; + for ( var i = 1; i < count; ++i, index += 6) { + addTriangle(lines, index, base, triangles[i], triangles[i + 1]); } - } - if (vertexFormat.st) { - length = textureCoordinates.length; - for (var k = 0; k < length; k += 2) { - textureCoordinates[k] = (textureCoordinates[k] - minTexCoord.x) / (maxTexCoord.x - minTexCoord.x); - textureCoordinates[k + 1] = (textureCoordinates[k + 1] - minTexCoord.y) / (maxTexCoord.y - minTexCoord.y); - } + return lines; } - var attributes = new GeometryAttributes(); + return new Uint16Array(); + } - if (vertexFormat.position) { - var finalPositions = EllipseGeometryLibrary.raisePositionsToHeight(positions, options, extrude); - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : finalPositions - }); + /** + * Converts a geometry's triangle indices to line indices. If the geometry has an <code>indices</code> + * and its <code>primitiveType</code> is <code>TRIANGLES</code>, <code>TRIANGLE_STRIP</code>, + * <code>TRIANGLE_FAN</code>, it is converted to <code>LINES</code>; otherwise, the geometry is not changed. + * <p> + * This is commonly used to create a wireframe geometry for visual debugging. + * </p> + * + * @param {Geometry} geometry The geometry to modify. + * @returns {Geometry} The modified <code>geometry</code> argument, with its triangle indices converted to lines. + * + * @exception {DeveloperError} geometry.primitiveType must be TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN. + * + * @example + * geometry = Cesium.GeometryPipeline.toWireframe(geometry); + */ + GeometryPipeline.toWireframe = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } + + var indices = geometry.indices; + if (defined(indices)) { + switch (geometry.primitiveType) { + case PrimitiveType.TRIANGLES: + geometry.indices = trianglesToLines(indices); + break; + case PrimitiveType.TRIANGLE_STRIP: + geometry.indices = triangleStripToLines(indices); + break; + case PrimitiveType.TRIANGLE_FAN: + geometry.indices = triangleFanToLines(indices); + break; + default: + throw new DeveloperError('geometry.primitiveType must be TRIANGLES, TRIANGLE_STRIP, or TRIANGLE_FAN.'); + } - if (vertexFormat.st) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : textureCoordinates - }); + geometry.primitiveType = PrimitiveType.LINES; } - if (vertexFormat.normal) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } + return geometry; + }; - if (vertexFormat.tangent) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); - } + /** + * Creates a new {@link Geometry} with <code>LINES</code> representing the provided + * attribute (<code>attributeName</code>) for the provided geometry. This is used to + * visualize vector attributes like normals, tangents, and bitangents. + * + * @param {Geometry} geometry The <code>Geometry</code> instance with the attribute. + * @param {String} [attributeName='normal'] The name of the attribute. + * @param {Number} [length=10000.0] The length of each line segment in meters. This can be negative to point the vector in the opposite direction. + * @returns {Geometry} A new <code>Geometry</code> instance with line segments for the vector. + * + * @exception {DeveloperError} geometry.attributes must have an attribute with the same name as the attributeName parameter. + * + * @example + * var geometry = Cesium.GeometryPipeline.createLineSegmentsForVectors(instance.geometry, 'bitangent', 100000.0); + */ + GeometryPipeline.createLineSegmentsForVectors = function(geometry, attributeName, length) { + attributeName = defaultValue(attributeName, 'normal'); - if (vertexFormat.bitangent) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } - - if (shadowVolume) { - attributes.extrudeDirection = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : extrudeNormals - }); + if (!defined(geometry.attributes.position)) { + throw new DeveloperError('geometry.attributes.position is required.'); } - - return attributes; - } - - function topIndices(numPts) { - // numTriangles in half = 3 + 8 + 12 + ... = -1 + 4 + (4 + 4) + (4 + 4 + 4) + ... = -1 + 4 * (1 + 2 + 3 + ...) - // = -1 + 4 * ((n * ( n + 1)) / 2) - // total triangles = 2 * numTrangles in half - // indices = total triangles * 3; - // Substitute numPts for n above - - var indices = new Array(12 * (numPts * ( numPts + 1)) - 6); - var indicesIndex = 0; - var prevIndex; - var numInterior; - var positionIndex; - var i; - var j; - // Indices triangles to the 'right' of the north vector - - prevIndex = 0; - positionIndex = 1; - for (i = 0; i < 3; i++) { - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; + if (!defined(geometry.attributes[attributeName])) { + throw new DeveloperError('geometry.attributes must have an attribute with the same name as the attributeName parameter, ' + attributeName + '.'); } + + length = defaultValue(length, 10000.0); - for (i = 2; i < numPts + 1; ++i) { - positionIndex = i * (i + 1) - 1; - prevIndex = (i - 1) * i - 1; - - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; - - numInterior = 2 * i; - for (j = 0; j < numInterior - 1; ++j) { + var positions = geometry.attributes.position.values; + var vectors = geometry.attributes[attributeName].values; + var positionsLength = positions.length; - indices[indicesIndex++] = positionIndex; - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; + var newPositions = new Float64Array(2 * positionsLength); - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; - } + var j = 0; + for (var i = 0; i < positionsLength; i += 3) { + newPositions[j++] = positions[i]; + newPositions[j++] = positions[i + 1]; + newPositions[j++] = positions[i + 2]; - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; + newPositions[j++] = positions[i] + (vectors[i] * length); + newPositions[j++] = positions[i + 1] + (vectors[i + 1] * length); + newPositions[j++] = positions[i + 2] + (vectors[i + 2] * length); } - // Indices for center column of triangles - numInterior = numPts * 2; - ++positionIndex; - ++prevIndex; - for (i = 0; i < numInterior - 1; ++i) { - indices[indicesIndex++] = positionIndex; - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; - - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; + var newBoundingSphere; + var bs = geometry.boundingSphere; + if (defined(bs)) { + newBoundingSphere = new BoundingSphere(bs.center, bs.radius + length); } - indices[indicesIndex++] = positionIndex; - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; - - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; - - // Reverse the process creating indices to the 'left' of the north vector - ++prevIndex; - for (i = numPts - 1; i > 1; --i) { - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; - - numInterior = 2 * i; - for (j = 0; j < numInterior - 1; ++j) { - indices[indicesIndex++] = positionIndex; - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; - - indices[indicesIndex++] = positionIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; - } - - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = positionIndex++; - } + return new Geometry({ + attributes : { + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : newPositions + }) + }, + primitiveType : PrimitiveType.LINES, + boundingSphere : newBoundingSphere + }); + }; - for (i = 0; i < 3; i++) { - indices[indicesIndex++] = prevIndex++; - indices[indicesIndex++] = prevIndex; - indices[indicesIndex++] = positionIndex; + /** + * Creates an object that maps attribute names to unique locations (indices) + * for matching vertex attributes and shader programs. + * + * @param {Geometry} geometry The geometry, which is not modified, to create the object for. + * @returns {Object} An object with attribute name / index pairs. + * + * @example + * var attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry); + * // Example output + * // { + * // 'position' : 0, + * // 'normal' : 1 + * // } + */ + GeometryPipeline.createAttributeLocations = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } - return indices; - } - - var boundingSphereCenter = new Cartesian3(); - - function computeEllipse(options) { - var center = options.center; - boundingSphereCenter = Cartesian3.multiplyByScalar(options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter), options.height, boundingSphereCenter); - boundingSphereCenter = Cartesian3.add(center, boundingSphereCenter, boundingSphereCenter); - var boundingSphere = new BoundingSphere(boundingSphereCenter, options.semiMajorAxis); - var cep = EllipseGeometryLibrary.computeEllipsePositions(options, true, false); - var positions = cep.positions; - var numPts = cep.numPts; - var attributes = computeTopBottomAttributes(positions, options, false); - var indices = topIndices(numPts); - indices = IndexDatatype.createTypedArray(positions.length / 3, indices); - return { - boundingSphere : boundingSphere, - attributes : attributes, - indices : indices - }; - } - - function computeWallAttributes(positions, options) { - var vertexFormat = options.vertexFormat; - var center = options.center; - var semiMajorAxis = options.semiMajorAxis; - var semiMinorAxis = options.semiMinorAxis; - var ellipsoid = options.ellipsoid; - var height = options.height; - var extrudedHeight = options.extrudedHeight; - var stRotation = options.stRotation; - var size = positions.length / 3 * 2; - - var finalPositions = new Float64Array(size * 3); - var textureCoordinates = (vertexFormat.st) ? new Float32Array(size * 2) : undefined; - var normals = (vertexFormat.normal) ? new Float32Array(size * 3) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(size * 3) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(size * 3) : undefined; - - var shadowVolume = options.shadowVolume; - var extrudeNormals = (shadowVolume) ? new Float32Array(size * 3) : undefined; - - var textureCoordIndex = 0; - - // Raise positions to a height above the ellipsoid and compute the - // texture coordinates, normals, tangents, and bitangents. - var normal = scratchNormal; - var tangent = scratchTangent; - var bitangent = scratchBitangent; - - var projection = new GeographicProjection(ellipsoid); - var projectedCenter = projection.project(ellipsoid.cartesianToCartographic(center, scratchCartographic), projectedCenterScratch); + + // There can be a WebGL performance hit when attribute 0 is disabled, so + // assign attribute locations to well-known attributes. + var semantics = [ + 'position', + 'positionHigh', + 'positionLow', - var geodeticNormal = ellipsoid.scaleToGeodeticSurface(center, scratchCartesian1); - ellipsoid.geodeticSurfaceNormal(geodeticNormal, geodeticNormal); - var rotation = Quaternion.fromAxisAngle(geodeticNormal, stRotation, quaternionScratch); - var textureMatrix = Matrix3.fromQuaternion(rotation, textureMatrixScratch); + // From VertexFormat.position - after 2D projection and high-precision encoding + 'position3DHigh', + 'position3DLow', + 'position2DHigh', + 'position2DLow', - var minTexCoord = Cartesian2.fromElements(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, scratchMinTexCoord); - var maxTexCoord = Cartesian2.fromElements(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, scratchMaxTexCoord); + // From Primitive + 'pickColor', - var length = positions.length; - var stOffset = length / 3 * 2; - for (var i = 0; i < length; i += 3) { - var i1 = i + 1; - var i2 = i + 2; - var position = Cartesian3.fromArray(positions, i, scratchCartesian1); - var extrudedPosition; + // From VertexFormat + 'normal', + 'st', + 'tangent', + 'bitangent', - if (vertexFormat.st) { - var rotatedPoint = Matrix3.multiplyByVector(textureMatrix, position, scratchCartesian2); - var projectedPoint = projection.project(ellipsoid.cartesianToCartographic(rotatedPoint, scratchCartographic), scratchCartesian3); - Cartesian3.subtract(projectedPoint, projectedCenter, projectedPoint); + // For shadow volumes + 'extrudeDirection', - texCoordScratch.x = (projectedPoint.x + semiMajorAxis) / (2.0 * semiMajorAxis); - texCoordScratch.y = (projectedPoint.y + semiMinorAxis) / (2.0 * semiMinorAxis); + // From compressing texture coordinates and normals + 'compressedAttributes' + ]; - minTexCoord.x = Math.min(texCoordScratch.x, minTexCoord.x); - minTexCoord.y = Math.min(texCoordScratch.y, minTexCoord.y); - maxTexCoord.x = Math.max(texCoordScratch.x, maxTexCoord.x); - maxTexCoord.y = Math.max(texCoordScratch.y, maxTexCoord.y); + var attributes = geometry.attributes; + var indices = {}; + var j = 0; + var i; + var len = semantics.length; - textureCoordinates[textureCoordIndex + stOffset] = texCoordScratch.x; - textureCoordinates[textureCoordIndex + 1 + stOffset] = texCoordScratch.y; + // Attribute locations for well-known attributes + for (i = 0; i < len; ++i) { + var semantic = semantics[i]; - textureCoordinates[textureCoordIndex++] = texCoordScratch.x; - textureCoordinates[textureCoordIndex++] = texCoordScratch.y; + if (defined(attributes[semantic])) { + indices[semantic] = j++; } + } - position = ellipsoid.scaleToGeodeticSurface(position, position); - extrudedPosition = Cartesian3.clone(position, scratchCartesian2); - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - - if (shadowVolume) { - extrudeNormals[i + length] = -normal.x; - extrudeNormals[i1 + length] = -normal.y; - extrudeNormals[i2 + length] = -normal.z; + // Locations for custom attributes + for (var name in attributes) { + if (attributes.hasOwnProperty(name) && (!defined(indices[name]))) { + indices[name] = j++; } + } - var scaledNormal = Cartesian3.multiplyByScalar(normal, height, scratchCartesian4); - position = Cartesian3.add(position, scaledNormal, position); - scaledNormal = Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal); - extrudedPosition = Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition); + return indices; + }; - if (vertexFormat.position) { - finalPositions[i + length] = extrudedPosition.x; - finalPositions[i1 + length] = extrudedPosition.y; - finalPositions[i2 + length] = extrudedPosition.z; + /** + * Reorders a geometry's attributes and <code>indices</code> to achieve better performance from the GPU's pre-vertex-shader cache. + * + * @param {Geometry} geometry The geometry to modify. + * @returns {Geometry} The modified <code>geometry</code> argument, with its attributes and indices reordered for the GPU's pre-vertex-shader cache. + * + * @exception {DeveloperError} Each attribute array in geometry.attributes must have the same number of attributes. + * + * + * @example + * geometry = Cesium.GeometryPipeline.reorderForPreVertexCache(geometry); + * + * @see GeometryPipeline.reorderForPostVertexCache + */ + GeometryPipeline.reorderForPreVertexCache = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); + } + + var numVertices = Geometry.computeNumberOfVertices(geometry); - finalPositions[i] = position.x; - finalPositions[i1] = position.y; - finalPositions[i2] = position.z; + var indices = geometry.indices; + if (defined(indices)) { + var indexCrossReferenceOldToNew = new Int32Array(numVertices); + for ( var i = 0; i < numVertices; i++) { + indexCrossReferenceOldToNew[i] = -1; } - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - - bitangent = Cartesian3.clone(normal, bitangent); - var next = Cartesian3.fromArray(positions, (i + 3) % length, scratchCartesian4); - Cartesian3.subtract(next, position, next); - var bottom = Cartesian3.subtract(extrudedPosition, position, scratchCartesian3); - - normal = Cartesian3.normalize(Cartesian3.cross(bottom, next, normal), normal); - - if (vertexFormat.normal) { - normals[i] = normal.x; - normals[i1] = normal.y; - normals[i2] = normal.z; - - normals[i + length] = normal.x; - normals[i1 + length] = normal.y; - normals[i2 + length] = normal.z; - } + // Construct cross reference and reorder indices + var indicesIn = indices; + var numIndices = indicesIn.length; + var indicesOut = IndexDatatype.createTypedArray(numVertices, numIndices); - if (vertexFormat.tangent) { - tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); - tangents[i] = tangent.x; - tangents[i1] = tangent.y; - tangents[i2] = tangent.z; + var intoIndicesIn = 0; + var intoIndicesOut = 0; + var nextIndex = 0; + var tempIndex; + while (intoIndicesIn < numIndices) { + tempIndex = indexCrossReferenceOldToNew[indicesIn[intoIndicesIn]]; + if (tempIndex !== -1) { + indicesOut[intoIndicesOut] = tempIndex; + } else { + tempIndex = indicesIn[intoIndicesIn]; + indexCrossReferenceOldToNew[tempIndex] = nextIndex; - tangents[i + length] = tangent.x; - tangents[i + 1 + length] = tangent.y; - tangents[i + 2 + length] = tangent.z; + indicesOut[intoIndicesOut] = nextIndex; + ++nextIndex; } + ++intoIndicesIn; + ++intoIndicesOut; + } + geometry.indices = indicesOut; - if (vertexFormat.bitangent) { - bitangents[i ] = bitangent.x; - bitangents[i1] = bitangent.y; - bitangents[i2] = bitangent.z; + // Reorder attributes + var attributes = geometry.attributes; + for ( var property in attributes) { + if (attributes.hasOwnProperty(property) && + defined(attributes[property]) && + defined(attributes[property].values)) { - bitangents[i + length] = bitangent.x; - bitangents[i1 + length] = bitangent.y; - bitangents[i2 + length] = bitangent.z; + var attribute = attributes[property]; + var elementsIn = attribute.values; + var intoElementsIn = 0; + var numComponents = attribute.componentsPerAttribute; + var elementsOut = ComponentDatatype.createTypedArray(attribute.componentDatatype, nextIndex * numComponents); + while (intoElementsIn < numVertices) { + var temp = indexCrossReferenceOldToNew[intoElementsIn]; + if (temp !== -1) { + for (var j = 0; j < numComponents; j++) { + elementsOut[numComponents * temp + j] = elementsIn[numComponents * intoElementsIn + j]; + } + } + ++intoElementsIn; + } + attribute.values = elementsOut; } } } - if (vertexFormat.st) { - length = textureCoordinates.length; - for (var k = 0; k < length; k += 2) { - textureCoordinates[k] = (textureCoordinates[k] - minTexCoord.x) / (maxTexCoord.x - minTexCoord.x); - textureCoordinates[k + 1] = (textureCoordinates[k + 1] - minTexCoord.y) / (maxTexCoord.y - minTexCoord.y); - } - } - - var attributes = new GeometryAttributes(); - - if (vertexFormat.position) { - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : finalPositions - }); - } - - if (vertexFormat.st) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : textureCoordinates - }); - } + return geometry; + }; - if (vertexFormat.normal) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); + /** + * Reorders a geometry's <code>indices</code> to achieve better performance from the GPU's + * post vertex-shader cache by using the Tipsify algorithm. If the geometry <code>primitiveType</code> + * is not <code>TRIANGLES</code> or the geometry does not have an <code>indices</code>, this function has no effect. + * + * @param {Geometry} geometry The geometry to modify. + * @param {Number} [cacheCapacity=24] The number of vertices that can be held in the GPU's vertex cache. + * @returns {Geometry} The modified <code>geometry</code> argument, with its indices reordered for the post-vertex-shader cache. + * + * @exception {DeveloperError} cacheCapacity must be greater than two. + * + * + * @example + * geometry = Cesium.GeometryPipeline.reorderForPostVertexCache(geometry); + * + * @see GeometryPipeline.reorderForPreVertexCache + * @see {@link http://gfx.cs.princ0eton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf|Fast Triangle Reordering for Vertex Locality and Reduced Overdraw} + * by Sander, Nehab, and Barczak + */ + GeometryPipeline.reorderForPostVertexCache = function(geometry, cacheCapacity) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } - - if (vertexFormat.tangent) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents + + var indices = geometry.indices; + if ((geometry.primitiveType === PrimitiveType.TRIANGLES) && (defined(indices))) { + var numIndices = indices.length; + var maximumIndex = 0; + for ( var j = 0; j < numIndices; j++) { + if (indices[j] > maximumIndex) { + maximumIndex = indices[j]; + } + } + geometry.indices = Tipsify.tipsify({ + indices : indices, + maximumIndex : maximumIndex, + cacheSize : cacheCapacity }); } - if (vertexFormat.bitangent) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } + return geometry; + }; - if (shadowVolume) { - attributes.extrudeDirection = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : extrudeNormals - }); - } + function copyAttributesDescriptions(attributes) { + var newAttributes = {}; - return attributes; - } + for ( var attribute in attributes) { + if (attributes.hasOwnProperty(attribute) && + defined(attributes[attribute]) && + defined(attributes[attribute].values)) { - function computeWallIndices(positions) { - var length = positions.length / 3; - var indices = IndexDatatype.createTypedArray(length, length * 6); - var index = 0; - for (var i = 0; i < length; i++) { - var UL = i; - var LL = i + length; - var UR = (UL + 1) % length; - var LR = UR + length; - indices[index++] = UL; - indices[index++] = LL; - indices[index++] = UR; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + var attr = attributes[attribute]; + newAttributes[attribute] = new GeometryAttribute({ + componentDatatype : attr.componentDatatype, + componentsPerAttribute : attr.componentsPerAttribute, + normalize : attr.normalize, + values : [] + }); + } } - return indices; + return newAttributes; } - var topBoundingSphere = new BoundingSphere(); - var bottomBoundingSphere = new BoundingSphere(); - - function computeExtrudedEllipse(options) { - var center = options.center; - var ellipsoid = options.ellipsoid; - var semiMajorAxis = options.semiMajorAxis; - var scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1), options.height, scratchCartesian1); - topBoundingSphere.center = Cartesian3.add(center, scaledNormal, topBoundingSphere.center); - topBoundingSphere.radius = semiMajorAxis; + function copyVertex(destinationAttributes, sourceAttributes, index) { + for ( var attribute in sourceAttributes) { + if (sourceAttributes.hasOwnProperty(attribute) && + defined(sourceAttributes[attribute]) && + defined(sourceAttributes[attribute].values)) { - scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scaledNormal), options.extrudedHeight, scaledNormal); - bottomBoundingSphere.center = Cartesian3.add(center, scaledNormal, bottomBoundingSphere.center); - bottomBoundingSphere.radius = semiMajorAxis; + var attr = sourceAttributes[attribute]; - var cep = EllipseGeometryLibrary.computeEllipsePositions(options, true, true); - var positions = cep.positions; - var numPts = cep.numPts; - var outerPositions = cep.outerPositions; - var boundingSphere = BoundingSphere.union(topBoundingSphere, bottomBoundingSphere); - var topBottomAttributes = computeTopBottomAttributes(positions, options, true); - var indices = topIndices(numPts); - var length = indices.length; - indices.length = length * 2; - var posLength = positions.length / 3; - for (var i = 0; i < length; i += 3) { - indices[i + length] = indices[i + 2] + posLength; - indices[i + 1 + length] = indices[i + 1] + posLength; - indices[i + 2 + length] = indices[i] + posLength; + for ( var k = 0; k < attr.componentsPerAttribute; ++k) { + destinationAttributes[attribute].values.push(attr.values[(index * attr.componentsPerAttribute) + k]); + } + } } + } - var topBottomIndices = IndexDatatype.createTypedArray(posLength * 2 / 3, indices); + /** + * Splits a geometry into multiple geometries, if necessary, to ensure that indices in the + * <code>indices</code> fit into unsigned shorts. This is used to meet the WebGL requirements + * when unsigned int indices are not supported. + * <p> + * If the geometry does not have any <code>indices</code>, this function has no effect. + * </p> + * + * @param {Geometry} geometry The geometry to be split into multiple geometries. + * @returns {Geometry[]} An array of geometries, each with indices that fit into unsigned shorts. + * + * @exception {DeveloperError} geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS + * @exception {DeveloperError} All geometry attribute lists must have the same number of attributes. + * + * @example + * var geometries = Cesium.GeometryPipeline.fitToUnsignedShortIndices(geometry); + */ + GeometryPipeline.fitToUnsignedShortIndices = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); + } + if ((defined(geometry.indices)) && + ((geometry.primitiveType !== PrimitiveType.TRIANGLES) && + (geometry.primitiveType !== PrimitiveType.LINES) && + (geometry.primitiveType !== PrimitiveType.POINTS))) { + throw new DeveloperError('geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS.'); + } + + var geometries = []; - var topBottomGeo = new Geometry({ - attributes : topBottomAttributes, - indices : topBottomIndices, - primitiveType : PrimitiveType.TRIANGLES - }); + // If there's an index list and more than 64K attributes, it is possible that + // some indices are outside the range of unsigned short [0, 64K - 1] + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + if (defined(geometry.indices) && (numberOfVertices >= CesiumMath.SIXTY_FOUR_KILOBYTES)) { + var oldToNewIndex = []; + var newIndices = []; + var currentIndex = 0; + var newAttributes = copyAttributesDescriptions(geometry.attributes); - var wallAttributes = computeWallAttributes(outerPositions, options); - indices = computeWallIndices(outerPositions); - var wallIndices = IndexDatatype.createTypedArray(outerPositions.length * 2 / 3, indices); + var originalIndices = geometry.indices; + var numberOfIndices = originalIndices.length; - var wallGeo = new Geometry({ - attributes : wallAttributes, - indices : wallIndices, - primitiveType : PrimitiveType.TRIANGLES - }); + var indicesPerPrimitive; - var geo = GeometryPipeline.combineInstances([ - new GeometryInstance({ - geometry : topBottomGeo - }), - new GeometryInstance({ - geometry : wallGeo - }) - ]); + if (geometry.primitiveType === PrimitiveType.TRIANGLES) { + indicesPerPrimitive = 3; + } else if (geometry.primitiveType === PrimitiveType.LINES) { + indicesPerPrimitive = 2; + } else if (geometry.primitiveType === PrimitiveType.POINTS) { + indicesPerPrimitive = 1; + } - return { - boundingSphere : boundingSphere, - attributes : geo[0].attributes, - indices : geo[0].indices - }; - } + for ( var j = 0; j < numberOfIndices; j += indicesPerPrimitive) { + for (var k = 0; k < indicesPerPrimitive; ++k) { + var x = originalIndices[j + k]; + var i = oldToNewIndex[x]; + if (!defined(i)) { + i = currentIndex++; + oldToNewIndex[x] = i; + copyVertex(newAttributes, geometry.attributes, x); + } + newIndices.push(i); + } - var scratchEnuToFixedMatrix = new Matrix4(); - var scratchFixedToEnuMatrix = new Matrix4(); - var scratchRotationMatrix = new Matrix3(); - var scratchRectanglePoints = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; - var scratchCartographicPoints = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; + if (currentIndex + indicesPerPrimitive >= CesiumMath.SIXTY_FOUR_KILOBYTES) { + geometries.push(new Geometry({ + attributes : newAttributes, + indices : newIndices, + primitiveType : geometry.primitiveType, + boundingSphere : geometry.boundingSphere, + boundingSphereCV : geometry.boundingSphereCV + })); - function computeRectangle(center, ellipsoid, semiMajorAxis, semiMinorAxis, rotation) { - Transforms.eastNorthUpToFixedFrame(center, ellipsoid, scratchEnuToFixedMatrix); - Matrix4.inverseTransformation(scratchEnuToFixedMatrix, scratchFixedToEnuMatrix); + // Reset for next vertex-array + oldToNewIndex = []; + newIndices = []; + currentIndex = 0; + newAttributes = copyAttributesDescriptions(geometry.attributes); + } + } - // Find the 4 extreme points of the ellipse in ENU - var i; - for (i = 0; i < 4; ++i) { - Cartesian3.clone(Cartesian3.ZERO, scratchRectanglePoints[i]); + if (newIndices.length !== 0) { + geometries.push(new Geometry({ + attributes : newAttributes, + indices : newIndices, + primitiveType : geometry.primitiveType, + boundingSphere : geometry.boundingSphere, + boundingSphereCV : geometry.boundingSphereCV + })); + } + } else { + // No need to split into multiple geometries + geometries.push(geometry); } - scratchRectanglePoints[0].x += semiMajorAxis; - scratchRectanglePoints[1].x -= semiMajorAxis; - scratchRectanglePoints[2].y += semiMinorAxis; - scratchRectanglePoints[3].y -= semiMinorAxis; - - Matrix3.fromRotationZ(rotation, scratchRotationMatrix); - for (i = 0; i < 4; ++i) { - // Apply the rotation - Matrix3.multiplyByVector(scratchRotationMatrix, scratchRectanglePoints[i], scratchRectanglePoints[i]); - // Convert back to fixed and then to cartographic - Matrix4.multiplyByPoint(scratchEnuToFixedMatrix, scratchRectanglePoints[i], scratchRectanglePoints[i]); - ellipsoid.cartesianToCartographic(scratchRectanglePoints[i], scratchCartographicPoints[i]); - } + return geometries; + }; - return Rectangle.fromCartographicArray(scratchCartographicPoints); - } + var scratchProjectTo2DCartesian3 = new Cartesian3(); + var scratchProjectTo2DCartographic = new Cartographic(); /** - * A description of an ellipse on an ellipsoid. Ellipse geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. - * - * @alias EllipseGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. - * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. - * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. - * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates counter-clockwise from north. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * Projects a geometry's 3D <code>position</code> attribute to 2D, replacing the <code>position</code> + * attribute with separate <code>position3D</code> and <code>position2D</code> attributes. + * <p> + * If the geometry does not have a <code>position</code>, this function has no effect. + * </p> * - * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero. - * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis. - * @exception {DeveloperError} granularity must be greater than zero. + * @param {Geometry} geometry The geometry to modify. + * @param {String} attributeName The name of the attribute. + * @param {String} attributeName3D The name of the attribute in 3D. + * @param {String} attributeName2D The name of the attribute in 2D. + * @param {Object} [projection=new GeographicProjection()] The projection to use. + * @returns {Geometry} The modified <code>geometry</code> argument with <code>position3D</code> and <code>position2D</code> attributes. * + * @exception {DeveloperError} geometry must have attribute matching the attributeName argument. + * @exception {DeveloperError} The attribute componentDatatype must be ComponentDatatype.DOUBLE. + * @exception {DeveloperError} Could not project a point to 2D. * * @example - * // Create an ellipse. - * var ellipse = new Cesium.EllipseGeometry({ - * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), - * semiMajorAxis : 500000.0, - * semiMinorAxis : 300000.0, - * rotation : Cesium.Math.toRadians(60.0) - * }); - * var geometry = Cesium.EllipseGeometry.createGeometry(ellipse); - * - * @see EllipseGeometry.createGeometry + * geometry = Cesium.GeometryPipeline.projectTo2D(geometry, 'position', 'position3D', 'position2D'); */ - function EllipseGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var center = options.center; - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var semiMajorAxis = options.semiMajorAxis; - var semiMinorAxis = options.semiMinorAxis; - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var height = defaultValue(options.height, 0.0); - var extrudedHeight = options.extrudedHeight; - var extrude = (defined(extrudedHeight) && Math.abs(height - extrudedHeight) > 1.0); - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); - - if (!defined(center)) { - throw new DeveloperError('center is required.'); - } - if (!defined(semiMajorAxis)) { - throw new DeveloperError('semiMajorAxis is required.'); + GeometryPipeline.projectTo2D = function(geometry, attributeName, attributeName3D, attributeName2D, projection) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } - if (!defined(semiMinorAxis)) { - throw new DeveloperError('semiMinorAxis is required.'); + if (!defined(attributeName)) { + throw new DeveloperError('attributeName is required.'); } - if (semiMajorAxis < semiMinorAxis) { - throw new DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.'); + if (!defined(attributeName3D)) { + throw new DeveloperError('attributeName3D is required.'); } - if (granularity <= 0.0) { - throw new DeveloperError('granularity must be greater than zero.'); + if (!defined(attributeName2D)) { + throw new DeveloperError('attributeName2D is required.'); } - - this._center = Cartesian3.clone(center); - this._semiMajorAxis = semiMajorAxis; - this._semiMinorAxis = semiMinorAxis; - this._ellipsoid = Ellipsoid.clone(ellipsoid); - this._rotation = defaultValue(options.rotation, 0.0); - this._stRotation = defaultValue(options.stRotation, 0.0); - this._height = height; - this._granularity = granularity; - this._vertexFormat = VertexFormat.clone(vertexFormat); - this._extrudedHeight = defaultValue(extrudedHeight, height); - this._extrude = extrude; - this._shadowVolume = defaultValue(options.shadowVolume, false); - this._workerName = 'createEllipseGeometry'; - - this._rectangle = computeRectangle(this._center, this._ellipsoid, semiMajorAxis, semiMinorAxis, this._rotation); - } - - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - EllipseGeometry.packedLength = Cartesian3.packedLength + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 9; - - /** - * Stores the provided instance into the provided array. - * - * @param {EllipseGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - EllipseGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); + if (!defined(geometry.attributes[attributeName])) { + throw new DeveloperError('geometry must have attribute matching the attributeName argument: ' + attributeName + '.'); } - if (!defined(array)) { - throw new DeveloperError('array is required'); + if (geometry.attributes[attributeName].componentDatatype !== ComponentDatatype.DOUBLE) { + throw new DeveloperError('The attribute componentDatatype must be ComponentDatatype.DOUBLE.'); } - startingIndex = defaultValue(startingIndex, 0); + var attribute = geometry.attributes[attributeName]; + projection = (defined(projection)) ? projection : new GeographicProjection(); + var ellipsoid = projection.ellipsoid; - Cartesian3.pack(value._center, array, startingIndex); - startingIndex += Cartesian3.packedLength; + // Project original values to 2D. + var values3D = attribute.values; + var projectedValues = new Float64Array(values3D.length); + var index = 0; - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + for ( var i = 0; i < values3D.length; i += 3) { + var value = Cartesian3.fromArray(values3D, i, scratchProjectTo2DCartesian3); - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; + var lonLat = ellipsoid.cartesianToCartographic(value, scratchProjectTo2DCartographic); + if (!defined(lonLat)) { + throw new DeveloperError('Could not project point (' + value.x + ', ' + value.y + ', ' + value.z + ') to 2D.'); + } + + var projectedLonLat = projection.project(lonLat, scratchProjectTo2DCartesian3); - Rectangle.pack(value._rectangle, array, startingIndex); - startingIndex += Rectangle.packedLength; + projectedValues[index++] = projectedLonLat.x; + projectedValues[index++] = projectedLonLat.y; + projectedValues[index++] = projectedLonLat.z; + } - array[startingIndex++] = value._semiMajorAxis; - array[startingIndex++] = value._semiMinorAxis; - array[startingIndex++] = value._rotation; - array[startingIndex++] = value._stRotation; - array[startingIndex++] = value._height; - array[startingIndex++] = value._granularity; - array[startingIndex++] = value._extrudedHeight; - array[startingIndex++] = value._extrude ? 1.0 : 0.0; - array[startingIndex] = value._shadowVolume ? 1.0 : 0.0; + // Rename original cartesians to WGS84 cartesians. + geometry.attributes[attributeName3D] = attribute; - return array; + // Replace original cartesians with 2D projected cartesians + geometry.attributes[attributeName2D] = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : projectedValues + }); + delete geometry.attributes[attributeName]; + + return geometry; }; - var scratchCenter = new Cartesian3(); - var scratchEllipsoid = new Ellipsoid(); - var scratchVertexFormat = new VertexFormat(); - var scratchRectangle = new Rectangle(); - var scratchOptions = { - center : scratchCenter, - ellipsoid : scratchEllipsoid, - vertexFormat : scratchVertexFormat, - semiMajorAxis : undefined, - semiMinorAxis : undefined, - rotation : undefined, - stRotation : undefined, - height : undefined, - granularity : undefined, - extrudedHeight : undefined, - shadowVolume: undefined + var encodedResult = { + high : 0.0, + low : 0.0 }; /** - * Retrieves an instance from a packed array. + * Encodes floating-point geometry attribute values as two separate attributes to improve + * rendering precision. + * <p> + * This is commonly used to create high-precision position vertex attributes. + * </p> * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {EllipseGeometry} [result] The object into which to store the result. - * @returns {EllipseGeometry} The modified result parameter or a new EllipseGeometry instance if one was not provided. + * @param {Geometry} geometry The geometry to modify. + * @param {String} attributeName The name of the attribute. + * @param {String} attributeHighName The name of the attribute for the encoded high bits. + * @param {String} attributeLowName The name of the attribute for the encoded low bits. + * @returns {Geometry} The modified <code>geometry</code> argument, with its encoded attribute. + * + * @exception {DeveloperError} geometry must have attribute matching the attributeName argument. + * @exception {DeveloperError} The attribute componentDatatype must be ComponentDatatype.DOUBLE. + * + * @example + * geometry = Cesium.GeometryPipeline.encodeAttribute(geometry, 'position3D', 'position3DHigh', 'position3DLow'); */ - EllipseGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + GeometryPipeline.encodeAttribute = function(geometry, attributeName, attributeHighName, attributeLowName) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); + } + if (!defined(attributeName)) { + throw new DeveloperError('attributeName is required.'); + } + if (!defined(attributeHighName)) { + throw new DeveloperError('attributeHighName is required.'); + } + if (!defined(attributeLowName)) { + throw new DeveloperError('attributeLowName is required.'); + } + if (!defined(geometry.attributes[attributeName])) { + throw new DeveloperError('geometry must have attribute matching the attributeName argument: ' + attributeName + '.'); + } + if (geometry.attributes[attributeName].componentDatatype !== ComponentDatatype.DOUBLE) { + throw new DeveloperError('The attribute componentDatatype must be ComponentDatatype.DOUBLE.'); } - startingIndex = defaultValue(startingIndex, 0); + var attribute = geometry.attributes[attributeName]; + var values = attribute.values; + var length = values.length; + var highValues = new Float32Array(length); + var lowValues = new Float32Array(length); - var center = Cartesian3.unpack(array, startingIndex, scratchCenter); - startingIndex += Cartesian3.packedLength; + for (var i = 0; i < length; ++i) { + EncodedCartesian3.encode(values[i], encodedResult); + highValues[i] = encodedResult.high; + lowValues[i] = encodedResult.low; + } - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + var componentsPerAttribute = attribute.componentsPerAttribute; - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + geometry.attributes[attributeHighName] = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : componentsPerAttribute, + values : highValues + }); + geometry.attributes[attributeLowName] = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : componentsPerAttribute, + values : lowValues + }); + delete geometry.attributes[attributeName]; - var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); - startingIndex += Rectangle.packedLength; + return geometry; + }; - var semiMajorAxis = array[startingIndex++]; - var semiMinorAxis = array[startingIndex++]; - var rotation = array[startingIndex++]; - var stRotation = array[startingIndex++]; - var height = array[startingIndex++]; - var granularity = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var extrude = array[startingIndex++] === 1.0; - var shadowVolume = array[startingIndex] === 1.0; + var scratchCartesian3 = new Cartesian3(); - if (!defined(result)) { - scratchOptions.height = height; - scratchOptions.extrudedHeight = extrudedHeight; - scratchOptions.granularity = granularity; - scratchOptions.stRotation = stRotation; - scratchOptions.rotation = rotation; - scratchOptions.semiMajorAxis = semiMajorAxis; - scratchOptions.semiMinorAxis = semiMinorAxis; - scratchOptions.shadowVolume = shadowVolume; - return new EllipseGeometry(scratchOptions); + function transformPoint(matrix, attribute) { + if (defined(attribute)) { + var values = attribute.values; + var length = values.length; + for (var i = 0; i < length; i += 3) { + Cartesian3.unpack(values, i, scratchCartesian3); + Matrix4.multiplyByPoint(matrix, scratchCartesian3, scratchCartesian3); + Cartesian3.pack(scratchCartesian3, values, i); + } } + } - result._center = Cartesian3.clone(center, result._center); - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._semiMajorAxis = semiMajorAxis; - result._semiMinorAxis = semiMinorAxis; - result._rotation = rotation; - result._stRotation = stRotation; - result._height = height; - result._granularity = granularity; - result._extrudedHeight = extrudedHeight; - result._extrude = extrude; - result._shadowVolume = shadowVolume; - result._rectangle = Rectangle.clone(rectangle); + function transformVector(matrix, attribute) { + if (defined(attribute)) { + var values = attribute.values; + var length = values.length; + for (var i = 0; i < length; i += 3) { + Cartesian3.unpack(values, i, scratchCartesian3); + Matrix3.multiplyByVector(matrix, scratchCartesian3, scratchCartesian3); + scratchCartesian3 = Cartesian3.normalize(scratchCartesian3, scratchCartesian3); + Cartesian3.pack(scratchCartesian3, values, i); + } + } + } - return result; - }; + var inverseTranspose = new Matrix4(); + var normalMatrix = new Matrix3(); /** - * Computes the geometric representation of a ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere. + * Transforms a geometry instance to world coordinates. This changes + * the instance's <code>modelMatrix</code> to {@link Matrix4.IDENTITY} and transforms the + * following attributes if they are present: <code>position</code>, <code>normal</code>, + * <code>tangent</code>, and <code>bitangent</code>. * - * @param {EllipseGeometry} ellipseGeometry A description of the ellipse. - * @returns {Geometry|undefined} The computed vertices and indices. + * @param {GeometryInstance} instance The geometry instance to modify. + * @returns {GeometryInstance} The modified <code>instance</code> argument, with its attributes transforms to world coordinates. + * + * @example + * Cesium.GeometryPipeline.transformToWorldCoordinates(instance); */ - EllipseGeometry.createGeometry = function(ellipseGeometry) { - if ((ellipseGeometry._semiMajorAxis <= 0.0) || (ellipseGeometry._semiMinorAxis <= 0.0)) { - return; + GeometryPipeline.transformToWorldCoordinates = function(instance) { + if (!defined(instance)) { + throw new DeveloperError('instance is required.'); } + + var modelMatrix = instance.modelMatrix; - ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(ellipseGeometry._center, ellipseGeometry._center); - var options = { - center : ellipseGeometry._center, - semiMajorAxis : ellipseGeometry._semiMajorAxis, - semiMinorAxis : ellipseGeometry._semiMinorAxis, - ellipsoid : ellipseGeometry._ellipsoid, - rotation : ellipseGeometry._rotation, - height : ellipseGeometry._height, - extrudedHeight : ellipseGeometry._extrudedHeight, - granularity : ellipseGeometry._granularity, - vertexFormat : ellipseGeometry._vertexFormat, - stRotation : ellipseGeometry._stRotation - }; - var geometry; - if (ellipseGeometry._extrude) { - options.extrudedHeight = Math.min(ellipseGeometry._extrudedHeight, ellipseGeometry._height); - options.height = Math.max(ellipseGeometry._extrudedHeight, ellipseGeometry._height); - options.shadowVolume = ellipseGeometry._shadowVolume; - geometry = computeExtrudedEllipse(options); - } else { - geometry = computeEllipse(options); + if (Matrix4.equals(modelMatrix, Matrix4.IDENTITY)) { + // Already in world coordinates + return instance; } - return new Geometry({ - attributes : geometry.attributes, - indices : geometry.indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : geometry.boundingSphere - }); - }; + var attributes = instance.geometry.attributes; - /** - * @private - */ - EllipseGeometry.createShadowVolume = function(ellipseGeometry, minHeightFunc, maxHeightFunc) { - var granularity = ellipseGeometry._granularity; - var ellipsoid = ellipseGeometry._ellipsoid; + // Transform attributes in known vertex formats + transformPoint(modelMatrix, attributes.position); + transformPoint(modelMatrix, attributes.prevPosition); + transformPoint(modelMatrix, attributes.nextPosition); - var minHeight = minHeightFunc(granularity, ellipsoid); - var maxHeight = maxHeightFunc(granularity, ellipsoid); + if ((defined(attributes.normal)) || + (defined(attributes.tangent)) || + (defined(attributes.bitangent))) { - return new EllipseGeometry({ - center : ellipseGeometry._center, - semiMajorAxis : ellipseGeometry._semiMajorAxis, - semiMinorAxis : ellipseGeometry._semiMinorAxis, - ellipsoid : ellipsoid, - rotation : ellipseGeometry._rotation, - stRotation : ellipseGeometry._stRotation, - granularity : granularity, - extrudedHeight : minHeight, - height : maxHeight, - vertexFormat : VertexFormat.POSITION_ONLY, - shadowVolume: true - }); - }; + Matrix4.inverse(modelMatrix, inverseTranspose); + Matrix4.transpose(inverseTranspose, inverseTranspose); + Matrix4.getRotation(inverseTranspose, normalMatrix); - defineProperties(EllipseGeometry.prototype, { - /** - * @private - */ - rectangle : { - get : function() { - return this._rectangle; - } + transformVector(normalMatrix, attributes.normal); + transformVector(normalMatrix, attributes.tangent); + transformVector(normalMatrix, attributes.bitangent); } - }); - return EllipseGeometry; -}); + var boundingSphere = instance.geometry.boundingSphere; -define('Core/CircleGeometry',[ - './Cartesian3', - './Check', - './defaultValue', - './defined', - './defineProperties', - './EllipseGeometry', - './Ellipsoid', - './VertexFormat' - ], function( - Cartesian3, - Check, - defaultValue, - defined, - defineProperties, - EllipseGeometry, - Ellipsoid, - VertexFormat) { - 'use strict'; + if (defined(boundingSphere)) { + instance.geometry.boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix, boundingSphere); + } - /** - * A description of a circle on the ellipsoid. Circle geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. - * - * @alias CircleGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.center The circle's center point in the fixed frame. - * @param {Number} options.radius The radius in meters. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the circle will be on. - * @param {Number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. - * @param {Number} [options.granularity=0.02] The angular distance between points on the circle in radians. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. - * - * @exception {DeveloperError} radius must be greater than zero. - * @exception {DeveloperError} granularity must be greater than zero. - * - * @see CircleGeometry.createGeometry - * @see Packable - * - * @example - * // Create a circle. - * var circle = new Cesium.CircleGeometry({ - * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), - * radius : 100000.0 - * }); - * var geometry = Cesium.CircleGeometry.createGeometry(circle); - */ - function CircleGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var radius = options.radius; + instance.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); - Check.typeOf.number('radius', radius); - - var ellipseGeometryOptions = { - center : options.center, - semiMajorAxis : radius, - semiMinorAxis : radius, - ellipsoid : options.ellipsoid, - height : options.height, - extrudedHeight : options.extrudedHeight, - granularity : options.granularity, - vertexFormat : options.vertexFormat, - stRotation : options.stRotation, - shadowVolume: options.shadowVolume - }; - this._ellipseGeometry = new EllipseGeometry(ellipseGeometryOptions); - this._workerName = 'createCircleGeometry'; - } + return instance; + }; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - CircleGeometry.packedLength = EllipseGeometry.packedLength; + function findAttributesInAllGeometries(instances, propertyName) { + var length = instances.length; - /** - * Stores the provided instance into the provided array. - * - * @param {CircleGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - CircleGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - return EllipseGeometry.pack(value._ellipseGeometry, array, startingIndex); - }; + var attributesInAllGeometries = {}; - var scratchEllipseGeometry = new EllipseGeometry({ - center : new Cartesian3(), - semiMajorAxis : 1.0, - semiMinorAxis : 1.0 - }); - var scratchOptions = { - center : new Cartesian3(), - radius : undefined, - ellipsoid : Ellipsoid.clone(Ellipsoid.UNIT_SPHERE), - height : undefined, - extrudedHeight : undefined, - granularity : undefined, - vertexFormat : new VertexFormat(), - stRotation : undefined, - semiMajorAxis : undefined, - semiMinorAxis : undefined, - shadowVolume: undefined - }; + var attributes0 = instances[0][propertyName].attributes; + var name; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {CircleGeometry} [result] The object into which to store the result. - * @returns {CircleGeometry} The modified result parameter or a new CircleGeometry instance if one was not provided. - */ - CircleGeometry.unpack = function(array, startingIndex, result) { - var ellipseGeometry = EllipseGeometry.unpack(array, startingIndex, scratchEllipseGeometry); - scratchOptions.center = Cartesian3.clone(ellipseGeometry._center, scratchOptions.center); - scratchOptions.ellipsoid = Ellipsoid.clone(ellipseGeometry._ellipsoid, scratchOptions.ellipsoid); - scratchOptions.height = ellipseGeometry._height; - scratchOptions.extrudedHeight = ellipseGeometry._extrudedHeight; - scratchOptions.granularity = ellipseGeometry._granularity; - scratchOptions.vertexFormat = VertexFormat.clone(ellipseGeometry._vertexFormat, scratchOptions.vertexFormat); - scratchOptions.stRotation = ellipseGeometry._stRotation; - scratchOptions.shadowVolume = ellipseGeometry._shadowVolume; + for (name in attributes0) { + if (attributes0.hasOwnProperty(name) && + defined(attributes0[name]) && + defined(attributes0[name].values)) { - if (!defined(result)) { - scratchOptions.radius = ellipseGeometry._semiMajorAxis; - return new CircleGeometry(scratchOptions); + var attribute = attributes0[name]; + var numberOfComponents = attribute.values.length; + var inAllGeometries = true; + + // Does this same attribute exist in all geometries? + for (var i = 1; i < length; ++i) { + var otherAttribute = instances[i][propertyName].attributes[name]; + + if ((!defined(otherAttribute)) || + (attribute.componentDatatype !== otherAttribute.componentDatatype) || + (attribute.componentsPerAttribute !== otherAttribute.componentsPerAttribute) || + (attribute.normalize !== otherAttribute.normalize)) { + + inAllGeometries = false; + break; + } + + numberOfComponents += otherAttribute.values.length; + } + + if (inAllGeometries) { + attributesInAllGeometries[name] = new GeometryAttribute({ + componentDatatype : attribute.componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize, + values : ComponentDatatype.createTypedArray(attribute.componentDatatype, numberOfComponents) + }); + } + } } - scratchOptions.semiMajorAxis = ellipseGeometry._semiMajorAxis; - scratchOptions.semiMinorAxis = ellipseGeometry._semiMinorAxis; - result._ellipseGeometry = new EllipseGeometry(scratchOptions); - return result; - }; + return attributesInAllGeometries; + } - /** - * Computes the geometric representation of a circle on an ellipsoid, including its vertices, indices, and a bounding sphere. - * - * @param {CircleGeometry} circleGeometry A description of the circle. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - CircleGeometry.createGeometry = function(circleGeometry) { - return EllipseGeometry.createGeometry(circleGeometry._ellipseGeometry); - }; + var tempScratch = new Cartesian3(); - /** - * @private - */ - CircleGeometry.createShadowVolume = function(circleGeometry, minHeightFunc, maxHeightFunc) { - var granularity = circleGeometry._ellipseGeometry._granularity; - var ellipsoid = circleGeometry._ellipseGeometry._ellipsoid; + function combineGeometries(instances, propertyName) { + var length = instances.length; - var minHeight = minHeightFunc(granularity, ellipsoid); - var maxHeight = maxHeightFunc(granularity, ellipsoid); + var name; + var i; + var j; + var k; - return new CircleGeometry({ - center : circleGeometry._ellipseGeometry._center, - radius : circleGeometry._ellipseGeometry._semiMajorAxis, - ellipsoid : ellipsoid, - stRotation : circleGeometry._ellipseGeometry._stRotation, - granularity : granularity, - extrudedHeight : minHeight, - height : maxHeight, - vertexFormat : VertexFormat.POSITION_ONLY, - shadowVolume: true - }); - }; + var m = instances[0].modelMatrix; + var haveIndices = (defined(instances[0][propertyName].indices)); + var primitiveType = instances[0][propertyName].primitiveType; - defineProperties(CircleGeometry.prototype, { - /** - * @private - */ - rectangle : { - get : function() { - return this._ellipseGeometry.rectangle; + for (i = 1; i < length; ++i) { + if (!Matrix4.equals(instances[i].modelMatrix, m)) { + throw new DeveloperError('All instances must have the same modelMatrix.'); + } + if ((defined(instances[i][propertyName].indices)) !== haveIndices) { + throw new DeveloperError('All instance geometries must have an indices or not have one.'); + } + if (instances[i][propertyName].primitiveType !== primitiveType) { + throw new DeveloperError('All instance geometries must have the same primitiveType.'); } } - }); + + // Find subset of attributes in all geometries + var attributes = findAttributesInAllGeometries(instances, propertyName); + var values; + var sourceValues; + var sourceValuesLength; - return CircleGeometry; -}); + // Combine attributes from each geometry into a single typed array + for (name in attributes) { + if (attributes.hasOwnProperty(name)) { + values = attributes[name].values; -define('Core/EllipseOutlineGeometry',[ - './BoundingSphere', - './Cartesian3', - './ComponentDatatype', - './defaultValue', - './defined', - './DeveloperError', - './EllipseGeometryLibrary', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PrimitiveType' - ], function( - BoundingSphere, - Cartesian3, - ComponentDatatype, - defaultValue, - defined, - DeveloperError, - EllipseGeometryLibrary, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PrimitiveType) { - 'use strict'; + k = 0; + for (i = 0; i < length; ++i) { + sourceValues = instances[i][propertyName].attributes[name].values; + sourceValuesLength = sourceValues.length; - var scratchCartesian1 = new Cartesian3(); - var boundingSphereCenter = new Cartesian3(); + for (j = 0; j < sourceValuesLength; ++j) { + values[k++] = sourceValues[j]; + } + } + } + } - function computeEllipse(options) { - var center = options.center; - boundingSphereCenter = Cartesian3.multiplyByScalar(options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter), options.height, boundingSphereCenter); - boundingSphereCenter = Cartesian3.add(center, boundingSphereCenter, boundingSphereCenter); - var boundingSphere = new BoundingSphere(boundingSphereCenter, options.semiMajorAxis); - var positions = EllipseGeometryLibrary.computeEllipsePositions(options, false, true).outerPositions; + // Combine index lists + var indices; - var attributes = new GeometryAttributes({ - position: new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : EllipseGeometryLibrary.raisePositionsToHeight(positions, options, false) - }) - }); + if (haveIndices) { + var numberOfIndices = 0; + for (i = 0; i < length; ++i) { + numberOfIndices += instances[i][propertyName].indices.length; + } - var length = positions.length / 3; - var indices = IndexDatatype.createTypedArray(length, length * 2); - var index = 0; - for ( var i = 0; i < length; ++i) { - indices[index++] = i; - indices[index++] = (i + 1) % length; - } + var numberOfVertices = Geometry.computeNumberOfVertices(new Geometry({ + attributes : attributes, + primitiveType : PrimitiveType.POINTS + })); + var destIndices = IndexDatatype.createTypedArray(numberOfVertices, numberOfIndices); - return { - boundingSphere : boundingSphere, - attributes : attributes, - indices : indices - }; - } + var destOffset = 0; + var offset = 0; - var topBoundingSphere = new BoundingSphere(); - var bottomBoundingSphere = new BoundingSphere(); - function computeExtrudedEllipse(options) { - var center = options.center; - var ellipsoid = options.ellipsoid; - var semiMajorAxis = options.semiMajorAxis; - var scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1), options.height, scratchCartesian1); - topBoundingSphere.center = Cartesian3.add(center, scaledNormal, topBoundingSphere.center); - topBoundingSphere.radius = semiMajorAxis; + for (i = 0; i < length; ++i) { + var sourceIndices = instances[i][propertyName].indices; + var sourceIndicesLen = sourceIndices.length; - scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scaledNormal), options.extrudedHeight, scaledNormal); - bottomBoundingSphere.center = Cartesian3.add(center, scaledNormal, bottomBoundingSphere.center); - bottomBoundingSphere.radius = semiMajorAxis; + for (k = 0; k < sourceIndicesLen; ++k) { + destIndices[destOffset++] = offset + sourceIndices[k]; + } - var positions = EllipseGeometryLibrary.computeEllipsePositions(options, false, true).outerPositions; - var attributes = new GeometryAttributes({ - position: new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : EllipseGeometryLibrary.raisePositionsToHeight(positions, options, true) - }) - }); + offset += Geometry.computeNumberOfVertices(instances[i][propertyName]); + } - positions = attributes.position.values; - var boundingSphere = BoundingSphere.union(topBoundingSphere, bottomBoundingSphere); - var length = positions.length/3; - var numberOfVerticalLines = defaultValue(options.numberOfVerticalLines, 16); - numberOfVerticalLines = CesiumMath.clamp(numberOfVerticalLines, 0, length/2); + indices = destIndices; + } - var indices = IndexDatatype.createTypedArray(length, length * 2 + numberOfVerticalLines * 2); + // Create bounding sphere that includes all instances + var center = new Cartesian3(); + var radius = 0.0; + var bs; - length /= 2; - var index = 0; - var i; for (i = 0; i < length; ++i) { - indices[index++] = i; - indices[index++] = (i + 1) % length; - indices[index++] = i + length; - indices[index++] = ((i + 1) % length) + length; + bs = instances[i][propertyName].boundingSphere; + if (!defined(bs)) { + // If any geometries have an undefined bounding sphere, then so does the combined geometry + center = undefined; + break; + } + + Cartesian3.add(bs.center, center, center); } - var numSide; - if (numberOfVerticalLines > 0) { - var numSideLines = Math.min(numberOfVerticalLines, length); - numSide = Math.round(length / numSideLines); + if (defined(center)) { + Cartesian3.divideByScalar(center, length, center); - var maxI = Math.min(numSide * numberOfVerticalLines, length); - for (i = 0; i < maxI; i += numSide) { - indices[index++] = i; - indices[index++] = i + length; + for (i = 0; i < length; ++i) { + bs = instances[i][propertyName].boundingSphere; + var tempRadius = Cartesian3.magnitude(Cartesian3.subtract(bs.center, center, tempScratch)) + bs.radius; + + if (tempRadius > radius) { + radius = tempRadius; + } } } - return { - boundingSphere : boundingSphere, + return new Geometry({ attributes : attributes, - indices : indices - }; + indices : indices, + primitiveType : primitiveType, + boundingSphere : (defined(center)) ? new BoundingSphere(center, radius) : undefined + }); } /** - * A description of the outline of an ellipse on an ellipsoid. + * Combines geometry from several {@link GeometryInstance} objects into one geometry. + * This concatenates the attributes, concatenates and adjusts the indices, and creates + * a bounding sphere encompassing all instances. + * <p> + * If the instances do not have the same attributes, a subset of attributes common + * to all instances is used, and the others are ignored. + * </p> + * <p> + * This is used by {@link Primitive} to efficiently render a large amount of static data. + * </p> * - * @alias EllipseOutlineGeometry - * @constructor + * @private * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. - * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. - * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. - * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The angle from north (counter-clockwise) in radians. - * @param {Number} [options.granularity=0.02] The angular distance between points on the ellipse in radians. - * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surface of an extruded ellipse. + * @param {GeometryInstance[]} [instances] The array of {@link GeometryInstance} objects whose geometry will be combined. + * @returns {Geometry} A single geometry created from the provided geometry instances. * - * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero. - * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis. - * @exception {DeveloperError} granularity must be greater than zero. + * @exception {DeveloperError} All instances must have the same modelMatrix. + * @exception {DeveloperError} All instance geometries must have an indices or not have one. + * @exception {DeveloperError} All instance geometries must have the same primitiveType. * - * @see EllipseOutlineGeometry.createGeometry * * @example - * var ellipse = new Cesium.EllipseOutlineGeometry({ - * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), - * semiMajorAxis : 500000.0, - * semiMinorAxis : 300000.0, - * rotation : Cesium.Math.toRadians(60.0) - * }); - * var geometry = Cesium.EllipseOutlineGeometry.createGeometry(ellipse); + * for (var i = 0; i < instances.length; ++i) { + * Cesium.GeometryPipeline.transformToWorldCoordinates(instances[i]); + * } + * var geometries = Cesium.GeometryPipeline.combineInstances(instances); + * + * @see GeometryPipeline.transformToWorldCoordinates */ - function EllipseOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var center = options.center; - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var semiMajorAxis = options.semiMajorAxis; - var semiMinorAxis = options.semiMinorAxis; - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var height = defaultValue(options.height, 0.0); - var extrudedHeight = options.extrudedHeight; - var extrude = (defined(extrudedHeight) && Math.abs(height - extrudedHeight) > 1.0); - - if (!defined(center)) { - throw new DeveloperError('center is required.'); - } - if (!defined(semiMajorAxis)) { - throw new DeveloperError('semiMajorAxis is required.'); + GeometryPipeline.combineInstances = function(instances) { + if ((!defined(instances)) || (instances.length < 1)) { + throw new DeveloperError('instances is required and must have length greater than zero.'); } - if (!defined(semiMinorAxis)) { - throw new DeveloperError('semiMinorAxis is required.'); + + var instanceGeometry = []; + var instanceSplitGeometry = []; + var length = instances.length; + for (var i = 0; i < length; ++i) { + var instance = instances[i]; + if (defined(instance.geometry)) { + instanceGeometry.push(instance); + } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { + instanceSplitGeometry.push(instance); + } } - if (semiMajorAxis < semiMinorAxis) { - throw new DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.'); + + var geometries = []; + if (instanceGeometry.length > 0) { + geometries.push(combineGeometries(instanceGeometry, 'geometry')); } - if (granularity <= 0.0) { - throw new DeveloperError('granularity must be greater than zero.'); + + if (instanceSplitGeometry.length > 0) { + geometries.push(combineGeometries(instanceSplitGeometry, 'westHemisphereGeometry')); + geometries.push(combineGeometries(instanceSplitGeometry, 'eastHemisphereGeometry')); } - - this._center = Cartesian3.clone(center); - this._semiMajorAxis = semiMajorAxis; - this._semiMinorAxis = semiMinorAxis; - this._ellipsoid = Ellipsoid.clone(ellipsoid); - this._rotation = defaultValue(options.rotation, 0.0); - this._height = height; - this._granularity = granularity; - this._extrudedHeight = extrudedHeight; - this._extrude = extrude; - this._numberOfVerticalLines = Math.max(defaultValue(options.numberOfVerticalLines, 16), 0); - this._workerName = 'createEllipseOutlineGeometry'; - } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - EllipseOutlineGeometry.packedLength = Cartesian3.packedLength + Ellipsoid.packedLength + 9; + return geometries; + }; + + var normal = new Cartesian3(); + var v0 = new Cartesian3(); + var v1 = new Cartesian3(); + var v2 = new Cartesian3(); /** - * Stores the provided instance into the provided array. + * Computes per-vertex normals for a geometry containing <code>TRIANGLES</code> by averaging the normals of + * all triangles incident to the vertex. The result is a new <code>normal</code> attribute added to the geometry. + * This assumes a counter-clockwise winding order. * - * @param {EllipseOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {Geometry} geometry The geometry to modify. + * @returns {Geometry} The modified <code>geometry</code> argument with the computed <code>normal</code> attribute. * - * @returns {Number[]} The array that was packed into + * @exception {DeveloperError} geometry.indices length must be greater than 0 and be a multiple of 3. + * @exception {DeveloperError} geometry.primitiveType must be {@link PrimitiveType.TRIANGLES}. + * + * @example + * Cesium.GeometryPipeline.computeNormal(geometry); */ - EllipseOutlineGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); + GeometryPipeline.computeNormal = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } - if (!defined(array)) { - throw new DeveloperError('array is required'); + if (!defined(geometry.attributes.position) || !defined(geometry.attributes.position.values)) { + throw new DeveloperError('geometry.attributes.position.values is required.'); + } + if (!defined(geometry.indices)) { + throw new DeveloperError('geometry.indices is required.'); + } + if (geometry.indices.length < 2 || geometry.indices.length % 3 !== 0) { + throw new DeveloperError('geometry.indices length must be greater than 0 and be a multiple of 3.'); + } + if (geometry.primitiveType !== PrimitiveType.TRIANGLES) { + throw new DeveloperError('geometry.primitiveType must be PrimitiveType.TRIANGLES.'); } - startingIndex = defaultValue(startingIndex, 0); - - Cartesian3.pack(value._center, array, startingIndex); - startingIndex += Cartesian3.packedLength; + var indices = geometry.indices; + var attributes = geometry.attributes; + var vertices = attributes.position.values; + var numVertices = attributes.position.values.length / 3; + var numIndices = indices.length; + var normalsPerVertex = new Array(numVertices); + var normalsPerTriangle = new Array(numIndices / 3); + var normalIndices = new Array(numIndices); + var i; + for ( i = 0; i < numVertices; i++) { + normalsPerVertex[i] = { + indexOffset : 0, + count : 0, + currentCount : 0 + }; + } - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + var j = 0; + for (i = 0; i < numIndices; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; + var i03 = i0 * 3; + var i13 = i1 * 3; + var i23 = i2 * 3; - array[startingIndex++] = value._semiMajorAxis; - array[startingIndex++] = value._semiMinorAxis; - array[startingIndex++] = value._rotation; - array[startingIndex++] = value._height; - array[startingIndex++] = value._granularity; - array[startingIndex++] = defined(value._extrudedHeight) ? 1.0 : 0.0; - array[startingIndex++] = defaultValue(value._extrudedHeight, 0.0); - array[startingIndex++] = value._extrude ? 1.0 : 0.0; - array[startingIndex] = value._numberOfVerticalLines; + v0.x = vertices[i03]; + v0.y = vertices[i03 + 1]; + v0.z = vertices[i03 + 2]; + v1.x = vertices[i13]; + v1.y = vertices[i13 + 1]; + v1.z = vertices[i13 + 2]; + v2.x = vertices[i23]; + v2.y = vertices[i23 + 1]; + v2.z = vertices[i23 + 2]; - return array; - }; + normalsPerVertex[i0].count++; + normalsPerVertex[i1].count++; + normalsPerVertex[i2].count++; - var scratchCenter = new Cartesian3(); - var scratchEllipsoid = new Ellipsoid(); - var scratchOptions = { - center : scratchCenter, - ellipsoid : scratchEllipsoid, - semiMajorAxis : undefined, - semiMinorAxis : undefined, - rotation : undefined, - height : undefined, - granularity : undefined, - extrudedHeight : undefined, - numberOfVerticalLines : undefined - }; + Cartesian3.subtract(v1, v0, v1); + Cartesian3.subtract(v2, v0, v2); + normalsPerTriangle[j] = Cartesian3.cross(v1, v2, new Cartesian3()); + j++; + } - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {EllipseOutlineGeometry} [result] The object into which to store the result. - * @returns {EllipseOutlineGeometry} The modified result parameter or a new EllipseOutlineGeometry instance if one was not provided. - */ - EllipseOutlineGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + var indexOffset = 0; + for (i = 0; i < numVertices; i++) { + normalsPerVertex[i].indexOffset += indexOffset; + indexOffset += normalsPerVertex[i].count; } - - startingIndex = defaultValue(startingIndex, 0); - var center = Cartesian3.unpack(array, startingIndex, scratchCenter); - startingIndex += Cartesian3.packedLength; + j = 0; + var vertexNormalData; + for (i = 0; i < numIndices; i += 3) { + vertexNormalData = normalsPerVertex[indices[i]]; + var index = vertexNormalData.indexOffset + vertexNormalData.currentCount; + normalIndices[index] = j; + vertexNormalData.currentCount++; - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + vertexNormalData = normalsPerVertex[indices[i + 1]]; + index = vertexNormalData.indexOffset + vertexNormalData.currentCount; + normalIndices[index] = j; + vertexNormalData.currentCount++; - var semiMajorAxis = array[startingIndex++]; - var semiMinorAxis = array[startingIndex++]; - var rotation = array[startingIndex++]; - var height = array[startingIndex++]; - var granularity = array[startingIndex++]; - var hasExtrudedHeight = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var extrude = array[startingIndex++] === 1.0; - var numberOfVerticalLines = array[startingIndex]; + vertexNormalData = normalsPerVertex[indices[i + 2]]; + index = vertexNormalData.indexOffset + vertexNormalData.currentCount; + normalIndices[index] = j; + vertexNormalData.currentCount++; - if (!defined(result)) { - scratchOptions.height = height; - scratchOptions.extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; - scratchOptions.granularity = granularity; - scratchOptions.rotation = rotation; - scratchOptions.semiMajorAxis = semiMajorAxis; - scratchOptions.semiMinorAxis = semiMinorAxis; - scratchOptions.numberOfVerticalLines = numberOfVerticalLines; - return new EllipseOutlineGeometry(scratchOptions); + j++; } - result._center = Cartesian3.clone(center, result._center); - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._semiMajorAxis = semiMajorAxis; - result._semiMinorAxis = semiMinorAxis; - result._rotation = rotation; - result._height = height; - result._granularity = granularity; - result._extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; - result._extrude = extrude; - result._numberOfVerticalLines = numberOfVerticalLines; + var normalValues = new Float32Array(numVertices * 3); + for (i = 0; i < numVertices; i++) { + var i3 = i * 3; + vertexNormalData = normalsPerVertex[i]; + Cartesian3.clone(Cartesian3.ZERO, normal); + if (vertexNormalData.count > 0) { + for (j = 0; j < vertexNormalData.count; j++) { + Cartesian3.add(normal, normalsPerTriangle[normalIndices[vertexNormalData.indexOffset + j]], normal); + } - return result; - }; + // We can run into an issue where a vertex is used with 2 primitives that have opposite winding order. + if (Cartesian3.equalsEpsilon(Cartesian3.ZERO, normal, CesiumMath.EPSILON10)) { + Cartesian3.clone(normalsPerTriangle[normalIndices[vertexNormalData.indexOffset]], normal); + } + } - /** - * Computes the geometric representation of an outline of an ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere. - * - * @param {EllipseOutlineGeometry} ellipseGeometry A description of the ellipse. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - EllipseOutlineGeometry.createGeometry = function(ellipseGeometry) { - if ((ellipseGeometry._semiMajorAxis <= 0.0) || (ellipseGeometry._semiMinorAxis <= 0.0)) { - return; - } + // We end up with a zero vector probably because of a degenerate triangle + if (Cartesian3.equalsEpsilon(Cartesian3.ZERO, normal, CesiumMath.EPSILON10)) { + // Default to (0,0,1) + normal.z = 1.0; + } - ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(ellipseGeometry._center, ellipseGeometry._center); - var options = { - center : ellipseGeometry._center, - semiMajorAxis : ellipseGeometry._semiMajorAxis, - semiMinorAxis : ellipseGeometry._semiMinorAxis, - ellipsoid : ellipseGeometry._ellipsoid, - rotation : ellipseGeometry._rotation, - height : ellipseGeometry._height, - extrudedHeight : ellipseGeometry._extrudedHeight, - granularity : ellipseGeometry._granularity, - numberOfVerticalLines : ellipseGeometry._numberOfVerticalLines - }; - var geometry; - if (ellipseGeometry._extrude) { - options.extrudedHeight = Math.min(ellipseGeometry._extrudedHeight, ellipseGeometry._height); - options.height = Math.max(ellipseGeometry._extrudedHeight, ellipseGeometry._height); - geometry = computeExtrudedEllipse(options); - } else { - geometry = computeEllipse(options); + Cartesian3.normalize(normal, normal); + normalValues[i3] = normal.x; + normalValues[i3 + 1] = normal.y; + normalValues[i3 + 2] = normal.z; } - return new Geometry({ - attributes : geometry.attributes, - indices : geometry.indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : geometry.boundingSphere + geometry.attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normalValues }); - }; - return EllipseOutlineGeometry; -}); + return geometry; + }; -define('Core/CircleOutlineGeometry',[ - './Cartesian3', - './Check', - './defaultValue', - './defined', - './EllipseOutlineGeometry', - './Ellipsoid' - ], function( - Cartesian3, - Check, - defaultValue, - defined, - EllipseOutlineGeometry, - Ellipsoid) { - 'use strict'; + var normalScratch = new Cartesian3(); + var normalScale = new Cartesian3(); + var tScratch = new Cartesian3(); /** - * A description of the outline of a circle on the ellipsoid. - * - * @alias CircleOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3} options.center The circle's center point in the fixed frame. - * @param {Number} options.radius The radius in meters. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the circle will be on. - * @param {Number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. - * @param {Number} [options.granularity=0.02] The angular distance between points on the circle in radians. - * @param {Number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. - * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom of an extruded circle. + * Computes per-vertex tangents and bitangents for a geometry containing <code>TRIANGLES</code>. + * The result is new <code>tangent</code> and <code>bitangent</code> attributes added to the geometry. + * This assumes a counter-clockwise winding order. + * <p> + * Based on <a href="http://www.terathon.com/code/tangent.html">Computing Tangent Space Basis Vectors + * for an Arbitrary Mesh</a> by Eric Lengyel. + * </p> * - * @exception {DeveloperError} radius must be greater than zero. - * @exception {DeveloperError} granularity must be greater than zero. + * @param {Geometry} geometry The geometry to modify. + * @returns {Geometry} The modified <code>geometry</code> argument with the computed <code>tangent</code> and <code>bitangent</code> attributes. * - * @see CircleOutlineGeometry.createGeometry - * @see Packable + * @exception {DeveloperError} geometry.indices length must be greater than 0 and be a multiple of 3. + * @exception {DeveloperError} geometry.primitiveType must be {@link PrimitiveType.TRIANGLES}. * * @example - * // Create a circle. - * var circle = new Cesium.CircleOutlineGeometry({ - * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), - * radius : 100000.0 - * }); - * var geometry = Cesium.CircleOutlineGeometry.createGeometry(circle); + * Cesium.GeometryPipeline.computeTangentAndBiTangent(geometry); */ - function CircleOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var radius = options.radius; + GeometryPipeline.computeTangentAndBitangent = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); + } + + var attributes = geometry.attributes; + var indices = geometry.indices; - Check.typeOf.number('radius', radius); + if (!defined(attributes.position) || !defined(attributes.position.values)) { + throw new DeveloperError('geometry.attributes.position.values is required.'); + } + if (!defined(attributes.normal) || !defined(attributes.normal.values)) { + throw new DeveloperError('geometry.attributes.normal.values is required.'); + } + if (!defined(attributes.st) || !defined(attributes.st.values)) { + throw new DeveloperError('geometry.attributes.st.values is required.'); + } + if (!defined(indices)) { + throw new DeveloperError('geometry.indices is required.'); + } + if (indices.length < 2 || indices.length % 3 !== 0) { + throw new DeveloperError('geometry.indices length must be greater than 0 and be a multiple of 3.'); + } + if (geometry.primitiveType !== PrimitiveType.TRIANGLES) { + throw new DeveloperError('geometry.primitiveType must be PrimitiveType.TRIANGLES.'); + } - var ellipseGeometryOptions = { - center : options.center, - semiMajorAxis : radius, - semiMinorAxis : radius, - ellipsoid : options.ellipsoid, - height : options.height, - extrudedHeight : options.extrudedHeight, - granularity : options.granularity, - numberOfVerticalLines : options.numberOfVerticalLines - }; - this._ellipseGeometry = new EllipseOutlineGeometry(ellipseGeometryOptions); - this._workerName = 'createCircleOutlineGeometry'; - } + var vertices = geometry.attributes.position.values; + var normals = geometry.attributes.normal.values; + var st = geometry.attributes.st.values; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - CircleOutlineGeometry.packedLength = EllipseOutlineGeometry.packedLength; + var numVertices = geometry.attributes.position.values.length / 3; + var numIndices = indices.length; + var tan1 = new Array(numVertices * 3); - /** - * Stores the provided instance into the provided array. - * - * @param {CircleOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - CircleOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - return EllipseOutlineGeometry.pack(value._ellipseGeometry, array, startingIndex); - }; + var i; + for ( i = 0; i < tan1.length; i++) { + tan1[i] = 0; + } - var scratchEllipseGeometry = new EllipseOutlineGeometry({ - center : new Cartesian3(), - semiMajorAxis : 1.0, - semiMinorAxis : 1.0 - }); - var scratchOptions = { - center : new Cartesian3(), - radius : undefined, - ellipsoid : Ellipsoid.clone(Ellipsoid.UNIT_SPHERE), - height : undefined, - extrudedHeight : undefined, - granularity : undefined, - numberOfVerticalLines : undefined, - semiMajorAxis : undefined, - semiMinorAxis : undefined - }; + var i03; + var i13; + var i23; + for (i = 0; i < numIndices; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; + i03 = i0 * 3; + i13 = i1 * 3; + i23 = i2 * 3; + var i02 = i0 * 2; + var i12 = i1 * 2; + var i22 = i2 * 2; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {CircleOutlineGeometry} [result] The object into which to store the result. - * @returns {CircleOutlineGeometry} The modified result parameter or a new CircleOutlineGeometry instance if one was not provided. - */ - CircleOutlineGeometry.unpack = function(array, startingIndex, result) { - var ellipseGeometry = EllipseOutlineGeometry.unpack(array, startingIndex, scratchEllipseGeometry); - scratchOptions.center = Cartesian3.clone(ellipseGeometry._center, scratchOptions.center); - scratchOptions.ellipsoid = Ellipsoid.clone(ellipseGeometry._ellipsoid, scratchOptions.ellipsoid); - scratchOptions.height = ellipseGeometry._height; - scratchOptions.extrudedHeight = ellipseGeometry._extrudedHeight; - scratchOptions.granularity = ellipseGeometry._granularity; - scratchOptions.numberOfVerticalLines = ellipseGeometry._numberOfVerticalLines; + var ux = vertices[i03]; + var uy = vertices[i03 + 1]; + var uz = vertices[i03 + 2]; - if (!defined(result)) { - scratchOptions.radius = ellipseGeometry._semiMajorAxis; - return new CircleOutlineGeometry(scratchOptions); + var wx = st[i02]; + var wy = st[i02 + 1]; + var t1 = st[i12 + 1] - wy; + var t2 = st[i22 + 1] - wy; + + var r = 1.0 / ((st[i12] - wx) * t2 - (st[i22] - wx) * t1); + var sdirx = (t2 * (vertices[i13] - ux) - t1 * (vertices[i23] - ux)) * r; + var sdiry = (t2 * (vertices[i13 + 1] - uy) - t1 * (vertices[i23 + 1] - uy)) * r; + var sdirz = (t2 * (vertices[i13 + 2] - uz) - t1 * (vertices[i23 + 2] - uz)) * r; + + tan1[i03] += sdirx; + tan1[i03 + 1] += sdiry; + tan1[i03 + 2] += sdirz; + + tan1[i13] += sdirx; + tan1[i13 + 1] += sdiry; + tan1[i13 + 2] += sdirz; + + tan1[i23] += sdirx; + tan1[i23 + 1] += sdiry; + tan1[i23 + 2] += sdirz; } - scratchOptions.semiMajorAxis = ellipseGeometry._semiMajorAxis; - scratchOptions.semiMinorAxis = ellipseGeometry._semiMinorAxis; - result._ellipseGeometry = new EllipseOutlineGeometry(scratchOptions); - return result; - }; + var tangentValues = new Float32Array(numVertices * 3); + var bitangentValues = new Float32Array(numVertices * 3); - /** - * Computes the geometric representation of an outline of a circle on an ellipsoid, including its vertices, indices, and a bounding sphere. - * - * @param {CircleOutlineGeometry} circleGeometry A description of the circle. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - CircleOutlineGeometry.createGeometry = function(circleGeometry) { - return EllipseOutlineGeometry.createGeometry(circleGeometry._ellipseGeometry); - }; + for (i = 0; i < numVertices; i++) { + i03 = i * 3; + i13 = i03 + 1; + i23 = i03 + 2; - return CircleOutlineGeometry; -}); + var n = Cartesian3.fromArray(normals, i03, normalScratch); + var t = Cartesian3.fromArray(tan1, i03, tScratch); + var scalar = Cartesian3.dot(n, t); + Cartesian3.multiplyByScalar(n, scalar, normalScale); + Cartesian3.normalize(Cartesian3.subtract(t, normalScale, t), t); -define('Core/Color',[ - './Check', - './defaultValue', - './defined', - './FeatureDetection', - './freezeObject', - './Math' - ], function( - Check, - defaultValue, - defined, - FeatureDetection, - freezeObject, - CesiumMath) { - 'use strict'; + tangentValues[i03] = t.x; + tangentValues[i13] = t.y; + tangentValues[i23] = t.z; - function hue2rgb(m1, m2, h) { - if (h < 0) { - h += 1; - } - if (h > 1) { - h -= 1; - } - if (h * 6 < 1) { - return m1 + (m2 - m1) * 6 * h; - } - if (h * 2 < 1) { - return m2; - } - if (h * 3 < 2) { - return m1 + (m2 - m1) * (2 / 3 - h) * 6; + Cartesian3.normalize(Cartesian3.cross(n, t, t), t); + + bitangentValues[i03] = t.x; + bitangentValues[i13] = t.y; + bitangentValues[i23] = t.z; } - return m1; - } - /** - * A color, specified using red, green, blue, and alpha values, - * which range from <code>0</code> (no intensity) to <code>1.0</code> (full intensity). - * @param {Number} [red=1.0] The red component. - * @param {Number} [green=1.0] The green component. - * @param {Number} [blue=1.0] The blue component. - * @param {Number} [alpha=1.0] The alpha component. - * - * @constructor - * @alias Color - * - * @see Packable - */ - function Color(red, green, blue, alpha) { - /** - * The red component. - * @type {Number} - * @default 1.0 - */ - this.red = defaultValue(red, 1.0); - /** - * The green component. - * @type {Number} - * @default 1.0 - */ - this.green = defaultValue(green, 1.0); - /** - * The blue component. - * @type {Number} - * @default 1.0 - */ - this.blue = defaultValue(blue, 1.0); - /** - * The alpha component. - * @type {Number} - * @default 1.0 - */ - this.alpha = defaultValue(alpha, 1.0); - } + geometry.attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangentValues + }); - /** - * Creates a Color instance from a {@link Cartesian4}. <code>x</code>, <code>y</code>, <code>z</code>, - * and <code>w</code> map to <code>red</code>, <code>green</code>, <code>blue</code>, and <code>alpha</code>, respectively. - * - * @param {Cartesian4} cartesian The source cartesian. - * @param {Color} [result] The object onto which to store the result. - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. - */ - Color.fromCartesian4 = function(cartesian, result) { - Check.typeOf.object('cartesian', cartesian); - - if (!defined(result)) { - return new Color(cartesian.x, cartesian.y, cartesian.z, cartesian.w); - } + geometry.attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangentValues + }); - result.red = cartesian.x; - result.green = cartesian.y; - result.blue = cartesian.z; - result.alpha = cartesian.w; - return result; + return geometry; }; + var scratchCartesian2 = new Cartesian2(); + var toEncode1 = new Cartesian3(); + var toEncode2 = new Cartesian3(); + var toEncode3 = new Cartesian3(); + var encodeResult2 = new Cartesian2(); /** - * Creates a new Color specified using red, green, blue, and alpha values - * that are in the range of 0 to 255, converting them internally to a range of 0.0 to 1.0. + * Compresses and packs geometry normal attribute values to save memory. * - * @param {Number} [red=255] The red component. - * @param {Number} [green=255] The green component. - * @param {Number} [blue=255] The blue component. - * @param {Number} [alpha=255] The alpha component. - * @param {Color} [result] The object onto which to store the result. - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + * @param {Geometry} geometry The geometry to modify. + * @returns {Geometry} The modified <code>geometry</code> argument, with its normals compressed and packed. + * + * @example + * geometry = Cesium.GeometryPipeline.compressVertices(geometry); */ - Color.fromBytes = function(red, green, blue, alpha, result) { - red = Color.byteToFloat(defaultValue(red, 255.0)); - green = Color.byteToFloat(defaultValue(green, 255.0)); - blue = Color.byteToFloat(defaultValue(blue, 255.0)); - alpha = Color.byteToFloat(defaultValue(alpha, 255.0)); - - if (!defined(result)) { - return new Color(red, green, blue, alpha); + GeometryPipeline.compressVertices = function(geometry) { + if (!defined(geometry)) { + throw new DeveloperError('geometry is required.'); } + + var extrudeAttribute = geometry.attributes.extrudeDirection; + var i; + var numVertices; + if (defined(extrudeAttribute)) { + //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes + var extrudeDirections = extrudeAttribute.values; + numVertices = extrudeDirections.length / 3.0; + var compressedDirections = new Float32Array(numVertices * 2); - result.red = red; - result.green = green; - result.blue = blue; - result.alpha = alpha; - return result; - }; + var i2 = 0; + for (i = 0; i < numVertices; ++i) { + Cartesian3.fromArray(extrudeDirections, i * 3.0, toEncode1); + if (Cartesian3.equals(toEncode1, Cartesian3.ZERO)) { + i2 += 2; + continue; + } + encodeResult2 = AttributeCompression.octEncodeInRange(toEncode1, 65535, encodeResult2); + compressedDirections[i2++] = encodeResult2.x; + compressedDirections[i2++] = encodeResult2.y; + } - /** - * Creates a new Color that has the same red, green, and blue components - * of the specified color, but with the specified alpha value. - * - * @param {Color} color The base color - * @param {Number} alpha The new alpha component. - * @param {Color} [result] The object onto which to store the result. - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. - * - * @example var translucentRed = Cesium.Color.fromAlpha(Cesium.Color.RED, 0.9); - */ - Color.fromAlpha = function(color, alpha, result) { - Check.typeOf.object('color', color); - Check.typeOf.number('alpha', alpha); - - if (!defined(result)) { - return new Color(color.red, color.green, color.blue, alpha); + geometry.attributes.compressedAttributes = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : compressedDirections + }); + delete geometry.attributes.extrudeDirection; + return geometry; } - result.red = color.red; - result.green = color.green; - result.blue = color.blue; - result.alpha = alpha; - return result; - }; - - var scratchArrayBuffer; - var scratchUint32Array; - var scratchUint8Array; - if (FeatureDetection.supportsTypedArrays()) { - scratchArrayBuffer = new ArrayBuffer(4); - scratchUint32Array = new Uint32Array(scratchArrayBuffer); - scratchUint8Array = new Uint8Array(scratchArrayBuffer); - } + var normalAttribute = geometry.attributes.normal; + var stAttribute = geometry.attributes.st; - /** - * Creates a new Color from a single numeric unsigned 32-bit RGBA value, using the endianness - * of the system. - * - * @param {Number} rgba A single numeric unsigned 32-bit RGBA value. - * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. - * @returns {Color} The color object. - * - * @example - * var color = Cesium.Color.fromRgba(0x67ADDFFF); - * - * @see Color#toRgba - */ - Color.fromRgba = function(rgba, result) { - // scratchUint32Array and scratchUint8Array share an underlying array buffer - scratchUint32Array[0] = rgba; - return Color.fromBytes(scratchUint8Array[0], scratchUint8Array[1], scratchUint8Array[2], scratchUint8Array[3], result); - }; + var hasNormal = defined(normalAttribute); + var hasSt = defined(stAttribute); + if (!hasNormal && !hasSt) { + return geometry; + } - /** - * Creates a Color instance from hue, saturation, and lightness. - * - * @param {Number} [hue=0] The hue angle 0...1 - * @param {Number} [saturation=0] The saturation value 0...1 - * @param {Number} [lightness=0] The lightness value 0...1 - * @param {Number} [alpha=1.0] The alpha component 0...1 - * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. - * @returns {Color} The color object. - * - * @see {@link http://www.w3.org/TR/css3-color/#hsl-color|CSS color values} - */ - Color.fromHsl = function(hue, saturation, lightness, alpha, result) { - hue = defaultValue(hue, 0.0) % 1.0; - saturation = defaultValue(saturation, 0.0); - lightness = defaultValue(lightness, 0.0); - alpha = defaultValue(alpha, 1.0); + var tangentAttribute = geometry.attributes.tangent; + var bitangentAttribute = geometry.attributes.bitangent; - var red = lightness; - var green = lightness; - var blue = lightness; + var hasTangent = defined(tangentAttribute); + var hasBitangent = defined(bitangentAttribute); - if (saturation !== 0) { - var m2; - if (lightness < 0.5) { - m2 = lightness * (1 + saturation); - } else { - m2 = lightness + saturation - lightness * saturation; - } + var normals; + var st; + var tangents; + var bitangents; - var m1 = 2.0 * lightness - m2; - red = hue2rgb(m1, m2, hue + 1 / 3); - green = hue2rgb(m1, m2, hue); - blue = hue2rgb(m1, m2, hue - 1 / 3); + if (hasNormal) { + normals = normalAttribute.values; } - - if (!defined(result)) { - return new Color(red, green, blue, alpha); + if (hasSt) { + st = stAttribute.values; + } + if (hasTangent) { + tangents = tangentAttribute.values; + } + if (hasBitangent) { + bitangents = bitangentAttribute.values; } - result.red = red; - result.green = green; - result.blue = blue; - result.alpha = alpha; - return result; - }; + var length = hasNormal ? normals.length : st.length; + var numComponents = hasNormal ? 3.0 : 2.0; + numVertices = length / numComponents; - /** - * Creates a random color using the provided options. For reproducible random colors, you should - * call {@link CesiumMath#setRandomNumberSeed} once at the beginning of your application. - * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.red] If specified, the red component to use instead of a randomized value. - * @param {Number} [options.minimumRed=0.0] The maximum red value to generate if none was specified. - * @param {Number} [options.maximumRed=1.0] The minimum red value to generate if none was specified. - * @param {Number} [options.green] If specified, the green component to use instead of a randomized value. - * @param {Number} [options.minimumGreen=0.0] The maximum green value to generate if none was specified. - * @param {Number} [options.maximumGreen=1.0] The minimum green value to generate if none was specified. - * @param {Number} [options.blue] If specified, the blue component to use instead of a randomized value. - * @param {Number} [options.minimumBlue=0.0] The maximum blue value to generate if none was specified. - * @param {Number} [options.maximumBlue=1.0] The minimum blue value to generate if none was specified. - * @param {Number} [options.alpha] If specified, the alpha component to use instead of a randomized value. - * @param {Number} [options.minimumAlpha=0.0] The maximum alpha value to generate if none was specified. - * @param {Number} [options.maximumAlpha=1.0] The minimum alpha value to generate if none was specified. - * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. - * @returns {Color} The modified result parameter or a new instance if result was undefined. - * - * @exception {DeveloperError} minimumRed must be less than or equal to maximumRed. - * @exception {DeveloperError} minimumGreen must be less than or equal to maximumGreen. - * @exception {DeveloperError} minimumBlue must be less than or equal to maximumBlue. - * @exception {DeveloperError} minimumAlpha must be less than or equal to maximumAlpha. - * - * @example - * //Create a completely random color - * var color = Cesium.Color.fromRandom(); - * - * //Create a random shade of yellow. - * var color = Cesium.Color.fromRandom({ - * red : 1.0, - * green : 1.0, - * alpha : 1.0 - * }); - * - * //Create a random bright color. - * var color = Cesium.Color.fromRandom({ - * minimumRed : 0.75, - * minimumGreen : 0.75, - * minimumBlue : 0.75, - * alpha : 1.0 - * }); - */ - Color.fromRandom = function(options, result) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var compressedLength = numVertices; + var numCompressedComponents = hasSt && hasNormal ? 2.0 : 1.0; + numCompressedComponents += hasTangent || hasBitangent ? 1.0 : 0.0; + compressedLength *= numCompressedComponents; - var red = options.red; - if (!defined(red)) { - var minimumRed = defaultValue(options.minimumRed, 0); - var maximumRed = defaultValue(options.maximumRed, 1.0); + var compressedAttributes = new Float32Array(compressedLength); - Check.typeOf.number.lessThanOrEquals('minimumRed', minimumRed, maximumRed); - - red = minimumRed + (CesiumMath.nextRandomNumber() * (maximumRed - minimumRed)); - } + var normalIndex = 0; + for (i = 0; i < numVertices; ++i) { + if (hasSt) { + Cartesian2.fromArray(st, i * 2.0, scratchCartesian2); + compressedAttributes[normalIndex++] = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + } - var green = options.green; - if (!defined(green)) { - var minimumGreen = defaultValue(options.minimumGreen, 0); - var maximumGreen = defaultValue(options.maximumGreen, 1.0); + var index = i * 3.0; + if (hasNormal && defined(tangents) && defined(bitangents)) { + Cartesian3.fromArray(normals, index, toEncode1); + Cartesian3.fromArray(tangents, index, toEncode2); + Cartesian3.fromArray(bitangents, index, toEncode3); - Check.typeOf.number.lessThanOrEquals('minimumGreen', minimumGreen, maximumGreen); - green = minimumGreen + (CesiumMath.nextRandomNumber() * (maximumGreen - minimumGreen)); - } + AttributeCompression.octPack(toEncode1, toEncode2, toEncode3, scratchCartesian2); + compressedAttributes[normalIndex++] = scratchCartesian2.x; + compressedAttributes[normalIndex++] = scratchCartesian2.y; + } else { + if (hasNormal) { + Cartesian3.fromArray(normals, index, toEncode1); + compressedAttributes[normalIndex++] = AttributeCompression.octEncodeFloat(toEncode1); + } - var blue = options.blue; - if (!defined(blue)) { - var minimumBlue = defaultValue(options.minimumBlue, 0); - var maximumBlue = defaultValue(options.maximumBlue, 1.0); + if (hasTangent) { + Cartesian3.fromArray(tangents, index, toEncode1); + compressedAttributes[normalIndex++] = AttributeCompression.octEncodeFloat(toEncode1); + } - Check.typeOf.number.lessThanOrEquals('minimumBlue', minimumBlue, maximumBlue); - - blue = minimumBlue + (CesiumMath.nextRandomNumber() * (maximumBlue - minimumBlue)); + if (hasBitangent) { + Cartesian3.fromArray(bitangents, index, toEncode1); + compressedAttributes[normalIndex++] = AttributeCompression.octEncodeFloat(toEncode1); + } + } } - var alpha = options.alpha; - if (!defined(alpha)) { - var minimumAlpha = defaultValue(options.minimumAlpha, 0); - var maximumAlpha = defaultValue(options.maximumAlpha, 1.0); + geometry.attributes.compressedAttributes = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : numCompressedComponents, + values : compressedAttributes + }); - Check.typeOf.number.lessThanOrEquals('minumumAlpha', minimumAlpha, maximumAlpha); - - alpha = minimumAlpha + (CesiumMath.nextRandomNumber() * (maximumAlpha - minimumAlpha)); + if (hasNormal) { + delete geometry.attributes.normal; } - - if (!defined(result)) { - return new Color(red, green, blue, alpha); + if (hasSt) { + delete geometry.attributes.st; + } + if (hasBitangent) { + delete geometry.attributes.bitangent; + } + if (hasTangent) { + delete geometry.attributes.tangent; } - result.red = red; - result.green = green; - result.blue = blue; - result.alpha = alpha; - return result; + return geometry; }; - //#rgb - var rgbMatcher = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i; - //#rrggbb - var rrggbbMatcher = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i; - //rgb(), rgba(), or rgb%() - var rgbParenthesesMatcher = /^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i; - //hsl(), hsla(), or hsl%() - var hslParenthesesMatcher = /^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i; + function indexTriangles(geometry) { + if (defined(geometry.indices)) { + return geometry; + } + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - /** - * Creates a Color instance from a CSS color value. - * - * @param {String} color The CSS color value in #rgb, #rrggbb, rgb(), rgba(), hsl(), or hsla() format. - * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. - * @returns {Color} The color object, or undefined if the string was not a valid CSS color. - * - * - * @example - * var cesiumBlue = Cesium.Color.fromCssColorString('#67ADDF'); - * var green = Cesium.Color.fromCssColorString('green'); - * - * @see {@link http://www.w3.org/TR/css3-color|CSS color values} - */ - Color.fromCssColorString = function(color, result) { - Check.typeOf.string('color', color); + if (numberOfVertices < 3) { + throw new DeveloperError('The number of vertices must be at least three.'); + } + if (numberOfVertices % 3 !== 0) { + throw new DeveloperError('The number of vertices must be a multiple of three.'); + } - if (!defined(result)) { - result = new Color(); + var indices = IndexDatatype.createTypedArray(numberOfVertices, numberOfVertices); + for (var i = 0; i < numberOfVertices; ++i) { + indices[i] = i; } - var namedColor = Color[color.toUpperCase()]; - if (defined(namedColor)) { - Color.clone(namedColor, result); - return result; + geometry.indices = indices; + return geometry; + } + + function indexTriangleFan(geometry) { + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + + if (numberOfVertices < 3) { + throw new DeveloperError('The number of vertices must be at least three.'); } + + var indices = IndexDatatype.createTypedArray(numberOfVertices, (numberOfVertices - 2) * 3); + indices[0] = 1; + indices[1] = 0; + indices[2] = 2; - var matches = rgbMatcher.exec(color); - if (matches !== null) { - result.red = parseInt(matches[1], 16) / 15; - result.green = parseInt(matches[2], 16) / 15.0; - result.blue = parseInt(matches[3], 16) / 15.0; - result.alpha = 1.0; - return result; + var indicesIndex = 3; + for (var i = 3; i < numberOfVertices; ++i) { + indices[indicesIndex++] = i - 1; + indices[indicesIndex++] = 0; + indices[indicesIndex++] = i; } - matches = rrggbbMatcher.exec(color); - if (matches !== null) { - result.red = parseInt(matches[1], 16) / 255.0; - result.green = parseInt(matches[2], 16) / 255.0; - result.blue = parseInt(matches[3], 16) / 255.0; - result.alpha = 1.0; - return result; + geometry.indices = indices; + geometry.primitiveType = PrimitiveType.TRIANGLES; + return geometry; + } + + function indexTriangleStrip(geometry) { + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + + if (numberOfVertices < 3) { + throw new DeveloperError('The number of vertices must be at least 3.'); } + + var indices = IndexDatatype.createTypedArray(numberOfVertices, (numberOfVertices - 2) * 3); + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; - matches = rgbParenthesesMatcher.exec(color); - if (matches !== null) { - result.red = parseFloat(matches[1]) / ('%' === matches[1].substr(-1) ? 100.0 : 255.0); - result.green = parseFloat(matches[2]) / ('%' === matches[2].substr(-1) ? 100.0 : 255.0); - result.blue = parseFloat(matches[3]) / ('%' === matches[3].substr(-1) ? 100.0 : 255.0); - result.alpha = parseFloat(defaultValue(matches[4], '1.0')); - return result; + if (numberOfVertices > 3) { + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; } - matches = hslParenthesesMatcher.exec(color); - if (matches !== null) { - return Color.fromHsl(parseFloat(matches[1]) / 360.0, - parseFloat(matches[2]) / 100.0, - parseFloat(matches[3]) / 100.0, - parseFloat(defaultValue(matches[4], '1.0')), result); + var indicesIndex = 6; + for (var i = 3; i < numberOfVertices - 1; i += 2) { + indices[indicesIndex++] = i; + indices[indicesIndex++] = i - 1; + indices[indicesIndex++] = i + 1; + + if (i + 2 < numberOfVertices) { + indices[indicesIndex++] = i; + indices[indicesIndex++] = i + 1; + indices[indicesIndex++] = i + 2; + } } - result = undefined; - return result; - }; + geometry.indices = indices; + geometry.primitiveType = PrimitiveType.TRIANGLES; + return geometry; + } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - Color.packedLength = 4; + function indexLines(geometry) { + if (defined(geometry.indices)) { + return geometry; + } + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - /** - * Stores the provided instance into the provided array. - * - * @param {Color} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - Color.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + if (numberOfVertices < 2) { + throw new DeveloperError('The number of vertices must be at least two.'); + } + if (numberOfVertices % 2 !== 0) { + throw new DeveloperError('The number of vertices must be a multiple of 2.'); + } - startingIndex = defaultValue(startingIndex, 0); - array[startingIndex++] = value.red; - array[startingIndex++] = value.green; - array[startingIndex++] = value.blue; - array[startingIndex] = value.alpha; + var indices = IndexDatatype.createTypedArray(numberOfVertices, numberOfVertices); + for (var i = 0; i < numberOfVertices; ++i) { + indices[i] = i; + } - return array; - }; + geometry.indices = indices; + return geometry; + } - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Color} [result] The object into which to store the result. - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. - */ - Color.unpack = function(array, startingIndex, result) { - Check.defined('array', array); + function indexLineStrip(geometry) { + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + + if (numberOfVertices < 2) { + throw new DeveloperError('The number of vertices must be at least two.'); + } - startingIndex = defaultValue(startingIndex, 0); - if (!defined(result)) { - result = new Color(); + var indices = IndexDatatype.createTypedArray(numberOfVertices, (numberOfVertices - 1) * 2); + indices[0] = 0; + indices[1] = 1; + var indicesIndex = 2; + for (var i = 2; i < numberOfVertices; ++i) { + indices[indicesIndex++] = i - 1; + indices[indicesIndex++] = i; } - result.red = array[startingIndex++]; - result.green = array[startingIndex++]; - result.blue = array[startingIndex++]; - result.alpha = array[startingIndex]; - return result; - }; - /** - * Converts a 'byte' color component in the range of 0 to 255 into - * a 'float' color component in the range of 0 to 1.0. - * - * @param {Number} number The number to be converted. - * @returns {Number} The converted number. - */ - Color.byteToFloat = function(number) { - return number / 255.0; - }; + geometry.indices = indices; + geometry.primitiveType = PrimitiveType.LINES; + return geometry; + } - /** - * Converts a 'float' color component in the range of 0 to 1.0 into - * a 'byte' color component in the range of 0 to 255. - * - * @param {Number} number The number to be converted. - * @returns {Number} The converted number. - */ - Color.floatToByte = function(number) { - return number === 1.0 ? 255.0 : (number * 256.0) | 0; - }; + function indexLineLoop(geometry) { + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - /** - * Duplicates a Color. - * - * @param {Color} color The Color to duplicate. - * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. - * @returns {Color} The modified result parameter or a new instance if result was undefined. (Returns undefined if color is undefined) - */ - Color.clone = function(color, result) { - if (!defined(color)) { - return undefined; - } - if (!defined(result)) { - return new Color(color.red, color.green, color.blue, color.alpha); + if (numberOfVertices < 2) { + throw new DeveloperError('The number of vertices must be at least two.'); } - result.red = color.red; - result.green = color.green; - result.blue = color.blue; - result.alpha = color.alpha; - return result; - }; + + var indices = IndexDatatype.createTypedArray(numberOfVertices, numberOfVertices * 2); - /** - * Returns true if the first Color equals the second color. - * - * @param {Color} left The first Color to compare for equality. - * @param {Color} right The second Color to compare for equality. - * @returns {Boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. - */ - Color.equals = function(left, right) { - return (left === right) || // - (defined(left) && // - defined(right) && // - left.red === right.red && // - left.green === right.green && // - left.blue === right.blue && // - left.alpha === right.alpha); - }; + indices[0] = 0; + indices[1] = 1; - /** - * @private - */ - Color.equalsArray = function(color, array, offset) { - return color.red === array[offset] && - color.green === array[offset + 1] && - color.blue === array[offset + 2] && - color.alpha === array[offset + 3]; - }; + var indicesIndex = 2; + for (var i = 2; i < numberOfVertices; ++i) { + indices[indicesIndex++] = i - 1; + indices[indicesIndex++] = i; + } - /** - * Returns a duplicate of a Color instance. - * - * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. - * @returns {Color} The modified result parameter or a new instance if result was undefined. - */ - Color.prototype.clone = function(result) { - return Color.clone(this, result); - }; + indices[indicesIndex++] = numberOfVertices - 1; + indices[indicesIndex] = 0; - /** - * Returns true if this Color equals other. - * - * @param {Color} other The Color to compare for equality. - * @returns {Boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. - */ - Color.prototype.equals = function(other) { - return Color.equals(this, other); - }; + geometry.indices = indices; + geometry.primitiveType = PrimitiveType.LINES; + return geometry; + } - /** - * Returns <code>true</code> if this Color equals other componentwise within the specified epsilon. - * - * @param {Color} other The Color to compare for equality. - * @param {Number} [epsilon=0.0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if the Colors are equal within the specified epsilon; otherwise, <code>false</code>. - */ - Color.prototype.equalsEpsilon = function(other, epsilon) { - return (this === other) || // - ((defined(other)) && // - (Math.abs(this.red - other.red) <= epsilon) && // - (Math.abs(this.green - other.green) <= epsilon) && // - (Math.abs(this.blue - other.blue) <= epsilon) && // - (Math.abs(this.alpha - other.alpha) <= epsilon)); - }; + function indexPrimitive(geometry) { + switch (geometry.primitiveType) { + case PrimitiveType.TRIANGLE_FAN: + return indexTriangleFan(geometry); + case PrimitiveType.TRIANGLE_STRIP: + return indexTriangleStrip(geometry); + case PrimitiveType.TRIANGLES: + return indexTriangles(geometry); + case PrimitiveType.LINE_STRIP: + return indexLineStrip(geometry); + case PrimitiveType.LINE_LOOP: + return indexLineLoop(geometry); + case PrimitiveType.LINES: + return indexLines(geometry); + } - /** - * Creates a string representing this Color in the format '(red, green, blue, alpha)'. - * - * @returns {String} A string representing this Color in the format '(red, green, blue, alpha)'. - */ - Color.prototype.toString = function() { - return '(' + this.red + ', ' + this.green + ', ' + this.blue + ', ' + this.alpha + ')'; - }; + return geometry; + } - /** - * Creates a string containing the CSS color value for this color. - * - * @returns {String} The CSS equivalent of this color. - * - * @see {@link http://www.w3.org/TR/css3-color/#rgba-color|CSS RGB or RGBA color values} - */ - Color.prototype.toCssColorString = function() { - var red = Color.floatToByte(this.red); - var green = Color.floatToByte(this.green); - var blue = Color.floatToByte(this.blue); - if (this.alpha === 1) { - return 'rgb(' + red + ',' + green + ',' + blue + ')'; + function offsetPointFromXZPlane(p, isBehind) { + if (Math.abs(p.y) < CesiumMath.EPSILON6){ + if (isBehind) { + p.y = -CesiumMath.EPSILON6; + } else { + p.y = CesiumMath.EPSILON6; + } } - return 'rgba(' + red + ',' + green + ',' + blue + ',' + this.alpha + ')'; - }; + } - /** - * Converts this color to an array of red, green, blue, and alpha values - * that are in the range of 0 to 255. - * - * @param {Number[]} [result] The array to store the result in, if undefined a new instance will be created. - * @returns {Number[]} The modified result parameter or a new instance if result was undefined. - */ - Color.prototype.toBytes = function(result) { - var red = Color.floatToByte(this.red); - var green = Color.floatToByte(this.green); - var blue = Color.floatToByte(this.blue); - var alpha = Color.floatToByte(this.alpha); + function offsetTriangleFromXZPlane(p0, p1, p2) { + if (p0.y !== 0.0 && p1.y !== 0.0 && p2.y !== 0.0) { + offsetPointFromXZPlane(p0, p0.y < 0.0); + offsetPointFromXZPlane(p1, p1.y < 0.0); + offsetPointFromXZPlane(p2, p2.y < 0.0); + return; + } - if (!defined(result)) { - return [red, green, blue, alpha]; + var p0y = Math.abs(p0.y); + var p1y = Math.abs(p1.y); + var p2y = Math.abs(p2.y); + + var sign; + if (p0y > p1y) { + if (p0y > p2y) { + sign = CesiumMath.sign(p0.y); + } else { + sign = CesiumMath.sign(p2.y); + } + } else if (p1y > p2y) { + sign = CesiumMath.sign(p1.y); + } else { + sign = CesiumMath.sign(p2.y); } - result[0] = red; - result[1] = green; - result[2] = blue; - result[3] = alpha; - return result; - }; - /** - * Converts this color to a single numeric unsigned 32-bit RGBA value, using the endianness - * of the system. - * - * @returns {Number} A single numeric unsigned 32-bit RGBA value. - * - * - * @example - * var rgba = Cesium.Color.BLUE.toRgba(); - * - * @see Color.fromRgba - */ - Color.prototype.toRgba = function() { - // scratchUint32Array and scratchUint8Array share an underlying array buffer - scratchUint8Array[0] = Color.floatToByte(this.red); - scratchUint8Array[1] = Color.floatToByte(this.green); - scratchUint8Array[2] = Color.floatToByte(this.blue); - scratchUint8Array[3] = Color.floatToByte(this.alpha); - return scratchUint32Array[0]; - }; + var isBehind = sign < 0.0; + offsetPointFromXZPlane(p0, isBehind); + offsetPointFromXZPlane(p1, isBehind); + offsetPointFromXZPlane(p2, isBehind); + } - /** - * Brightens this color by the provided magnitude. - * - * @param {Number} magnitude A positive number indicating the amount to brighten. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - * - * @example - * var brightBlue = Cesium.Color.BLUE.brighten(0.5, new Cesium.Color()); - */ - Color.prototype.brighten = function(magnitude, result) { - Check.typeOf.number('magnitude', magnitude); - Check.typeOf.number.greaterThanOrEquals('magnitude', magnitude, 0.0); - Check.typeOf.object('result', result); - - magnitude = (1.0 - magnitude); - result.red = 1.0 - ((1.0 - this.red) * magnitude); - result.green = 1.0 - ((1.0 - this.green) * magnitude); - result.blue = 1.0 - ((1.0 - this.blue) * magnitude); - result.alpha = this.alpha; - return result; - }; + var c3 = new Cartesian3(); + function getXZIntersectionOffsetPoints(p, p1, u1, v1) { + Cartesian3.add(p, Cartesian3.multiplyByScalar(Cartesian3.subtract(p1, p, c3), p.y/(p.y-p1.y), c3), u1); + Cartesian3.clone(u1, v1); + offsetPointFromXZPlane(u1, true); + offsetPointFromXZPlane(v1, false); + } - /** - * Darkens this color by the provided magnitude. - * - * @param {Number} magnitude A positive number indicating the amount to darken. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - * - * @example - * var darkBlue = Cesium.Color.BLUE.darken(0.5, new Cesium.Color()); - */ - Color.prototype.darken = function(magnitude, result) { - Check.typeOf.number('magnitude', magnitude); - Check.typeOf.number.greaterThanOrEquals('magnitude', magnitude, 0.0); - Check.typeOf.object('result', result); - - magnitude = (1.0 - magnitude); - result.red = this.red * magnitude; - result.green = this.green * magnitude; - result.blue = this.blue * magnitude; - result.alpha = this.alpha; - return result; - }; + var u1 = new Cartesian3(); + var u2 = new Cartesian3(); + var q1 = new Cartesian3(); + var q2 = new Cartesian3(); - /** - * Creates a new Color that has the same red, green, and blue components - * as this Color, but with the specified alpha value. - * - * @param {Number} alpha The new alpha component. - * @param {Color} [result] The object onto which to store the result. - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. - * - * @example var translucentRed = Cesium.Color.RED.withAlpha(0.9); - */ - Color.prototype.withAlpha = function(alpha, result) { - return Color.fromAlpha(this, alpha, result); + var splitTriangleResult = { + positions : new Array(7), + indices : new Array(3 * 3) }; - /** - * Computes the componentwise sum of two Colors. - * - * @param {Color} left The first Color. - * @param {Color} right The second Color. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.add = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.red = left.red + right.red; - result.green = left.green + right.green; - result.blue = left.blue + right.blue; - result.alpha = left.alpha + right.alpha; - return result; - }; + function splitTriangle(p0, p1, p2) { + // In WGS84 coordinates, for a triangle approximately on the + // ellipsoid to cross the IDL, first it needs to be on the + // negative side of the plane x = 0. + if ((p0.x >= 0.0) || (p1.x >= 0.0) || (p2.x >= 0.0)) { + return undefined; + } - /** - * Computes the componentwise difference of two Colors. - * - * @param {Color} left The first Color. - * @param {Color} right The second Color. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.subtract = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.red = left.red - right.red; - result.green = left.green - right.green; - result.blue = left.blue - right.blue; - result.alpha = left.alpha - right.alpha; - return result; - }; + offsetTriangleFromXZPlane(p0, p1, p2); - /** - * Computes the componentwise product of two Colors. - * - * @param {Color} left The first Color. - * @param {Color} right The second Color. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.multiply = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.red = left.red * right.red; - result.green = left.green * right.green; - result.blue = left.blue * right.blue; - result.alpha = left.alpha * right.alpha; - return result; - }; + var p0Behind = p0.y < 0.0; + var p1Behind = p1.y < 0.0; + var p2Behind = p2.y < 0.0; - /** - * Computes the componentwise quotient of two Colors. - * - * @param {Color} left The first Color. - * @param {Color} right The second Color. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.divide = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.red = left.red / right.red; - result.green = left.green / right.green; - result.blue = left.blue / right.blue; - result.alpha = left.alpha / right.alpha; - return result; - }; + var numBehind = 0; + numBehind += p0Behind ? 1 : 0; + numBehind += p1Behind ? 1 : 0; + numBehind += p2Behind ? 1 : 0; - /** - * Computes the componentwise modulus of two Colors. - * - * @param {Color} left The first Color. - * @param {Color} right The second Color. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.mod = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result.red = left.red % right.red; - result.green = left.green % right.green; - result.blue = left.blue % right.blue; - result.alpha = left.alpha % right.alpha; - return result; - }; + var indices = splitTriangleResult.indices; - /** - * Multiplies the provided Color componentwise by the provided scalar. - * - * @param {Color} color The Color to be scaled. - * @param {Number} scalar The scalar to multiply with. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.multiplyByScalar = function(color, scalar, result) { - Check.typeOf.object('color', color); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result.red = color.red * scalar; - result.green = color.green * scalar; - result.blue = color.blue * scalar; - result.alpha = color.alpha * scalar; - return result; - }; + if (numBehind === 1) { + indices[1] = 3; + indices[2] = 4; + indices[5] = 6; + indices[7] = 6; + indices[8] = 5; - /** - * Divides the provided Color componentwise by the provided scalar. - * - * @param {Color} color The Color to be divided. - * @param {Number} scalar The scalar to divide with. - * @param {Color} result The object onto which to store the result. - * @returns {Color} The modified result parameter. - */ - Color.divideByScalar = function(color, scalar, result) { - Check.typeOf.object('color', color); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); - - result.red = color.red / scalar; - result.green = color.green / scalar; - result.blue = color.blue / scalar; - result.alpha = color.alpha / scalar; - return result; - }; + if (p0Behind) { + getXZIntersectionOffsetPoints(p0, p1, u1, q1); + getXZIntersectionOffsetPoints(p0, p2, u2, q2); - /** - * An immutable Color instance initialized to CSS color #F0F8FF - * <span class="colorSwath" style="background: #F0F8FF;"></span> - * - * @constant - * @type {Color} - */ - Color.ALICEBLUE = freezeObject(Color.fromCssColorString('#F0F8FF')); + indices[0] = 0; + indices[3] = 1; + indices[4] = 2; + indices[6] = 1; + } else if (p1Behind) { + getXZIntersectionOffsetPoints(p1, p2, u1, q1); + getXZIntersectionOffsetPoints(p1, p0, u2, q2); - /** - * An immutable Color instance initialized to CSS color #FAEBD7 - * <span class="colorSwath" style="background: #FAEBD7;"></span> - * - * @constant - * @type {Color} - */ - Color.ANTIQUEWHITE = freezeObject(Color.fromCssColorString('#FAEBD7')); + indices[0] = 1; + indices[3] = 2; + indices[4] = 0; + indices[6] = 2; + } else if (p2Behind) { + getXZIntersectionOffsetPoints(p2, p0, u1, q1); + getXZIntersectionOffsetPoints(p2, p1, u2, q2); - /** - * An immutable Color instance initialized to CSS color #00FFFF - * <span class="colorSwath" style="background: #00FFFF;"></span> - * - * @constant - * @type {Color} - */ - Color.AQUA = freezeObject(Color.fromCssColorString('#00FFFF')); + indices[0] = 2; + indices[3] = 0; + indices[4] = 1; + indices[6] = 0; + } + } else if (numBehind === 2) { + indices[2] = 4; + indices[4] = 4; + indices[5] = 3; + indices[7] = 5; + indices[8] = 6; - /** - * An immutable Color instance initialized to CSS color #7FFFD4 - * <span class="colorSwath" style="background: #7FFFD4;"></span> - * - * @constant - * @type {Color} - */ - Color.AQUAMARINE = freezeObject(Color.fromCssColorString('#7FFFD4')); + if (!p0Behind) { + getXZIntersectionOffsetPoints(p0, p1, u1, q1); + getXZIntersectionOffsetPoints(p0, p2, u2, q2); - /** - * An immutable Color instance initialized to CSS color #F0FFFF - * <span class="colorSwath" style="background: #F0FFFF;"></span> - * - * @constant - * @type {Color} - */ - Color.AZURE = freezeObject(Color.fromCssColorString('#F0FFFF')); + indices[0] = 1; + indices[1] = 2; + indices[3] = 1; + indices[6] = 0; + } else if (!p1Behind) { + getXZIntersectionOffsetPoints(p1, p2, u1, q1); + getXZIntersectionOffsetPoints(p1, p0, u2, q2); - /** - * An immutable Color instance initialized to CSS color #F5F5DC - * <span class="colorSwath" style="background: #F5F5DC;"></span> - * - * @constant - * @type {Color} - */ - Color.BEIGE = freezeObject(Color.fromCssColorString('#F5F5DC')); + indices[0] = 2; + indices[1] = 0; + indices[3] = 2; + indices[6] = 1; + } else if (!p2Behind) { + getXZIntersectionOffsetPoints(p2, p0, u1, q1); + getXZIntersectionOffsetPoints(p2, p1, u2, q2); - /** - * An immutable Color instance initialized to CSS color #FFE4C4 - * <span class="colorSwath" style="background: #FFE4C4;"></span> - * - * @constant - * @type {Color} - */ - Color.BISQUE = freezeObject(Color.fromCssColorString('#FFE4C4')); + indices[0] = 0; + indices[1] = 1; + indices[3] = 0; + indices[6] = 2; + } + } - /** - * An immutable Color instance initialized to CSS color #000000 - * <span class="colorSwath" style="background: #000000;"></span> - * - * @constant - * @type {Color} - */ - Color.BLACK = freezeObject(Color.fromCssColorString('#000000')); + var positions = splitTriangleResult.positions; + positions[0] = p0; + positions[1] = p1; + positions[2] = p2; + positions.length = 3; - /** - * An immutable Color instance initialized to CSS color #FFEBCD - * <span class="colorSwath" style="background: #FFEBCD;"></span> - * - * @constant - * @type {Color} - */ - Color.BLANCHEDALMOND = freezeObject(Color.fromCssColorString('#FFEBCD')); + if (numBehind === 1 || numBehind === 2) { + positions[3] = u1; + positions[4] = u2; + positions[5] = q1; + positions[6] = q2; + positions.length = 7; + } - /** - * An immutable Color instance initialized to CSS color #0000FF - * <span class="colorSwath" style="background: #0000FF;"></span> - * - * @constant - * @type {Color} - */ - Color.BLUE = freezeObject(Color.fromCssColorString('#0000FF')); + return splitTriangleResult; + } - /** - * An immutable Color instance initialized to CSS color #8A2BE2 - * <span class="colorSwath" style="background: #8A2BE2;"></span> - * - * @constant - * @type {Color} - */ - Color.BLUEVIOLET = freezeObject(Color.fromCssColorString('#8A2BE2')); + function updateGeometryAfterSplit(geometry, computeBoundingSphere) { + var attributes = geometry.attributes; - /** - * An immutable Color instance initialized to CSS color #A52A2A - * <span class="colorSwath" style="background: #A52A2A;"></span> - * - * @constant - * @type {Color} - */ - Color.BROWN = freezeObject(Color.fromCssColorString('#A52A2A')); + if (attributes.position.values.length === 0) { + return undefined; + } - /** - * An immutable Color instance initialized to CSS color #DEB887 - * <span class="colorSwath" style="background: #DEB887;"></span> - * - * @constant - * @type {Color} - */ - Color.BURLYWOOD = freezeObject(Color.fromCssColorString('#DEB887')); + for (var property in attributes) { + if (attributes.hasOwnProperty(property) && + defined(attributes[property]) && + defined(attributes[property].values)) { - /** - * An immutable Color instance initialized to CSS color #5F9EA0 - * <span class="colorSwath" style="background: #5F9EA0;"></span> - * - * @constant - * @type {Color} - */ - Color.CADETBLUE = freezeObject(Color.fromCssColorString('#5F9EA0')); - /** - * An immutable Color instance initialized to CSS color #7FFF00 - * <span class="colorSwath" style="background: #7FFF00;"></span> - * - * @constant - * @type {Color} - */ - Color.CHARTREUSE = freezeObject(Color.fromCssColorString('#7FFF00')); + var attribute = attributes[property]; + attribute.values = ComponentDatatype.createTypedArray(attribute.componentDatatype, attribute.values); + } + } - /** - * An immutable Color instance initialized to CSS color #D2691E - * <span class="colorSwath" style="background: #D2691E;"></span> - * - * @constant - * @type {Color} - */ - Color.CHOCOLATE = freezeObject(Color.fromCssColorString('#D2691E')); + var numberOfVertices = Geometry.computeNumberOfVertices(geometry); + geometry.indices = IndexDatatype.createTypedArray(numberOfVertices, geometry.indices); - /** - * An immutable Color instance initialized to CSS color #FF7F50 - * <span class="colorSwath" style="background: #FF7F50;"></span> - * - * @constant - * @type {Color} - */ - Color.CORAL = freezeObject(Color.fromCssColorString('#FF7F50')); + if (computeBoundingSphere) { + geometry.boundingSphere = BoundingSphere.fromVertices(attributes.position.values); + } - /** - * An immutable Color instance initialized to CSS color #6495ED - * <span class="colorSwath" style="background: #6495ED;"></span> - * - * @constant - * @type {Color} - */ - Color.CORNFLOWERBLUE = freezeObject(Color.fromCssColorString('#6495ED')); + return geometry; + } - /** - * An immutable Color instance initialized to CSS color #FFF8DC - * <span class="colorSwath" style="background: #FFF8DC;"></span> - * - * @constant - * @type {Color} - */ - Color.CORNSILK = freezeObject(Color.fromCssColorString('#FFF8DC')); + function copyGeometryForSplit(geometry) { + var attributes = geometry.attributes; + var copiedAttributes = {}; - /** - * An immutable Color instance initialized to CSS color #DC143C - * <span class="colorSwath" style="background: #DC143C;"></span> - * - * @constant - * @type {Color} - */ - Color.CRIMSON = freezeObject(Color.fromCssColorString('#DC143C')); + for (var property in attributes) { + if (attributes.hasOwnProperty(property) && + defined(attributes[property]) && + defined(attributes[property].values)) { - /** - * An immutable Color instance initialized to CSS color #00FFFF - * <span class="colorSwath" style="background: #00FFFF;"></span> - * - * @constant - * @type {Color} - */ - Color.CYAN = freezeObject(Color.fromCssColorString('#00FFFF')); + var attribute = attributes[property]; + copiedAttributes[property] = new GeometryAttribute({ + componentDatatype : attribute.componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize, + values : [] + }); + } + } - /** - * An immutable Color instance initialized to CSS color #00008B - * <span class="colorSwath" style="background: #00008B;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKBLUE = freezeObject(Color.fromCssColorString('#00008B')); + return new Geometry({ + attributes : copiedAttributes, + indices : [], + primitiveType : geometry.primitiveType + }); + } - /** - * An immutable Color instance initialized to CSS color #008B8B - * <span class="colorSwath" style="background: #008B8B;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKCYAN = freezeObject(Color.fromCssColorString('#008B8B')); + function updateInstanceAfterSplit(instance, westGeometry, eastGeometry) { + var computeBoundingSphere = defined(instance.geometry.boundingSphere); - /** - * An immutable Color instance initialized to CSS color #B8860B - * <span class="colorSwath" style="background: #B8860B;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKGOLDENROD = freezeObject(Color.fromCssColorString('#B8860B')); + westGeometry = updateGeometryAfterSplit(westGeometry, computeBoundingSphere); + eastGeometry = updateGeometryAfterSplit(eastGeometry, computeBoundingSphere); - /** - * An immutable Color instance initialized to CSS color #A9A9A9 - * <span class="colorSwath" style="background: #A9A9A9;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKGRAY = freezeObject(Color.fromCssColorString('#A9A9A9')); + if (defined(eastGeometry) && !defined(westGeometry)) { + instance.geometry = eastGeometry; + } else if (!defined(eastGeometry) && defined(westGeometry)) { + instance.geometry = westGeometry; + } else { + instance.westHemisphereGeometry = westGeometry; + instance.eastHemisphereGeometry = eastGeometry; + instance.geometry = undefined; + } + } - /** - * An immutable Color instance initialized to CSS color #006400 - * <span class="colorSwath" style="background: #006400;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKGREEN = freezeObject(Color.fromCssColorString('#006400')); + var p0Scratch = new Cartesian3(); + var p1Scratch = new Cartesian3(); + var p2Scratch = new Cartesian3(); + var barycentricScratch = new Cartesian3(); + var s0Scratch = new Cartesian2(); + var s1Scratch = new Cartesian2(); + var s2Scratch = new Cartesian2(); - /** - * An immutable Color instance initialized to CSS color #A9A9A9 - * <span class="colorSwath" style="background: #A9A9A9;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKGREY = Color.DARKGRAY; + function computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex) { + if (!defined(normals) && !defined(tangents) && !defined(bitangents) && !defined(texCoords) && !defined(extrudeDirections)) { + return; + } - /** - * An immutable Color instance initialized to CSS color #BDB76B - * <span class="colorSwath" style="background: #BDB76B;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKKHAKI = freezeObject(Color.fromCssColorString('#BDB76B')); + var p0 = Cartesian3.fromArray(positions, i0 * 3, p0Scratch); + var p1 = Cartesian3.fromArray(positions, i1 * 3, p1Scratch); + var p2 = Cartesian3.fromArray(positions, i2 * 3, p2Scratch); + var coords = barycentricCoordinates(point, p0, p1, p2, barycentricScratch); - /** - * An immutable Color instance initialized to CSS color #8B008B - * <span class="colorSwath" style="background: #8B008B;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKMAGENTA = freezeObject(Color.fromCssColorString('#8B008B')); + if (defined(normals)) { + var n0 = Cartesian3.fromArray(normals, i0 * 3, p0Scratch); + var n1 = Cartesian3.fromArray(normals, i1 * 3, p1Scratch); + var n2 = Cartesian3.fromArray(normals, i2 * 3, p2Scratch); - /** - * An immutable Color instance initialized to CSS color #556B2F - * <span class="colorSwath" style="background: #556B2F;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKOLIVEGREEN = freezeObject(Color.fromCssColorString('#556B2F')); + Cartesian3.multiplyByScalar(n0, coords.x, n0); + Cartesian3.multiplyByScalar(n1, coords.y, n1); + Cartesian3.multiplyByScalar(n2, coords.z, n2); - /** - * An immutable Color instance initialized to CSS color #FF8C00 - * <span class="colorSwath" style="background: #FF8C00;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKORANGE = freezeObject(Color.fromCssColorString('#FF8C00')); + var normal = Cartesian3.add(n0, n1, n0); + Cartesian3.add(normal, n2, normal); + Cartesian3.normalize(normal, normal); - /** - * An immutable Color instance initialized to CSS color #9932CC - * <span class="colorSwath" style="background: #9932CC;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKORCHID = freezeObject(Color.fromCssColorString('#9932CC')); + Cartesian3.pack(normal, currentAttributes.normal.values, insertedIndex * 3); + } - /** - * An immutable Color instance initialized to CSS color #8B0000 - * <span class="colorSwath" style="background: #8B0000;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKRED = freezeObject(Color.fromCssColorString('#8B0000')); + if (defined(extrudeDirections)) { + var d0 = Cartesian3.fromArray(extrudeDirections, i0 * 3, p0Scratch); + var d1 = Cartesian3.fromArray(extrudeDirections, i1 * 3, p1Scratch); + var d2 = Cartesian3.fromArray(extrudeDirections, i2 * 3, p2Scratch); - /** - * An immutable Color instance initialized to CSS color #E9967A - * <span class="colorSwath" style="background: #E9967A;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKSALMON = freezeObject(Color.fromCssColorString('#E9967A')); + Cartesian3.multiplyByScalar(d0, coords.x, d0); + Cartesian3.multiplyByScalar(d1, coords.y, d1); + Cartesian3.multiplyByScalar(d2, coords.z, d2); - /** - * An immutable Color instance initialized to CSS color #8FBC8F - * <span class="colorSwath" style="background: #8FBC8F;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKSEAGREEN = freezeObject(Color.fromCssColorString('#8FBC8F')); + var direction; + if (!Cartesian3.equals(d0, Cartesian3.ZERO) || !Cartesian3.equals(d1, Cartesian3.ZERO) || !Cartesian3.equals(d2, Cartesian3.ZERO)) { + direction = Cartesian3.add(d0, d1, d0); + Cartesian3.add(direction, d2, direction); + Cartesian3.normalize(direction, direction); + } else { + direction = p0Scratch; + direction.x = 0; + direction.y = 0; + direction.z = 0; + } + Cartesian3.pack(direction, currentAttributes.extrudeDirection.values, insertedIndex * 3); + } - /** - * An immutable Color instance initialized to CSS color #483D8B - * <span class="colorSwath" style="background: #483D8B;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKSLATEBLUE = freezeObject(Color.fromCssColorString('#483D8B')); + if (defined(tangents)) { + var t0 = Cartesian3.fromArray(tangents, i0 * 3, p0Scratch); + var t1 = Cartesian3.fromArray(tangents, i1 * 3, p1Scratch); + var t2 = Cartesian3.fromArray(tangents, i2 * 3, p2Scratch); - /** - * An immutable Color instance initialized to CSS color #2F4F4F - * <span class="colorSwath" style="background: #2F4F4F;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKSLATEGRAY = freezeObject(Color.fromCssColorString('#2F4F4F')); + Cartesian3.multiplyByScalar(t0, coords.x, t0); + Cartesian3.multiplyByScalar(t1, coords.y, t1); + Cartesian3.multiplyByScalar(t2, coords.z, t2); - /** - * An immutable Color instance initialized to CSS color #2F4F4F - * <span class="colorSwath" style="background: #2F4F4F;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKSLATEGREY = Color.DARKSLATEGRAY; + var tangent = Cartesian3.add(t0, t1, t0); + Cartesian3.add(tangent, t2, tangent); + Cartesian3.normalize(tangent, tangent); - /** - * An immutable Color instance initialized to CSS color #00CED1 - * <span class="colorSwath" style="background: #00CED1;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKTURQUOISE = freezeObject(Color.fromCssColorString('#00CED1')); + Cartesian3.pack(tangent, currentAttributes.tangent.values, insertedIndex * 3); + } - /** - * An immutable Color instance initialized to CSS color #9400D3 - * <span class="colorSwath" style="background: #9400D3;"></span> - * - * @constant - * @type {Color} - */ - Color.DARKVIOLET = freezeObject(Color.fromCssColorString('#9400D3')); + if (defined(bitangents)) { + var b0 = Cartesian3.fromArray(bitangents, i0 * 3, p0Scratch); + var b1 = Cartesian3.fromArray(bitangents, i1 * 3, p1Scratch); + var b2 = Cartesian3.fromArray(bitangents, i2 * 3, p2Scratch); - /** - * An immutable Color instance initialized to CSS color #FF1493 - * <span class="colorSwath" style="background: #FF1493;"></span> - * - * @constant - * @type {Color} - */ - Color.DEEPPINK = freezeObject(Color.fromCssColorString('#FF1493')); + Cartesian3.multiplyByScalar(b0, coords.x, b0); + Cartesian3.multiplyByScalar(b1, coords.y, b1); + Cartesian3.multiplyByScalar(b2, coords.z, b2); - /** - * An immutable Color instance initialized to CSS color #00BFFF - * <span class="colorSwath" style="background: #00BFFF;"></span> - * - * @constant - * @type {Color} - */ - Color.DEEPSKYBLUE = freezeObject(Color.fromCssColorString('#00BFFF')); + var bitangent = Cartesian3.add(b0, b1, b0); + Cartesian3.add(bitangent, b2, bitangent); + Cartesian3.normalize(bitangent, bitangent); - /** - * An immutable Color instance initialized to CSS color #696969 - * <span class="colorSwath" style="background: #696969;"></span> - * - * @constant - * @type {Color} - */ - Color.DIMGRAY = freezeObject(Color.fromCssColorString('#696969')); + Cartesian3.pack(bitangent, currentAttributes.bitangent.values, insertedIndex * 3); + } - /** - * An immutable Color instance initialized to CSS color #696969 - * <span class="colorSwath" style="background: #696969;"></span> - * - * @constant - * @type {Color} - */ - Color.DIMGREY = Color.DIMGRAY; + if (defined(texCoords)) { + var s0 = Cartesian2.fromArray(texCoords, i0 * 2, s0Scratch); + var s1 = Cartesian2.fromArray(texCoords, i1 * 2, s1Scratch); + var s2 = Cartesian2.fromArray(texCoords, i2 * 2, s2Scratch); - /** - * An immutable Color instance initialized to CSS color #1E90FF - * <span class="colorSwath" style="background: #1E90FF;"></span> - * - * @constant - * @type {Color} - */ - Color.DODGERBLUE = freezeObject(Color.fromCssColorString('#1E90FF')); + Cartesian2.multiplyByScalar(s0, coords.x, s0); + Cartesian2.multiplyByScalar(s1, coords.y, s1); + Cartesian2.multiplyByScalar(s2, coords.z, s2); - /** - * An immutable Color instance initialized to CSS color #B22222 - * <span class="colorSwath" style="background: #B22222;"></span> - * - * @constant - * @type {Color} - */ - Color.FIREBRICK = freezeObject(Color.fromCssColorString('#B22222')); + var texCoord = Cartesian2.add(s0, s1, s0); + Cartesian2.add(texCoord, s2, texCoord); - /** - * An immutable Color instance initialized to CSS color #FFFAF0 - * <span class="colorSwath" style="background: #FFFAF0;"></span> - * - * @constant - * @type {Color} - */ - Color.FLORALWHITE = freezeObject(Color.fromCssColorString('#FFFAF0')); + Cartesian2.pack(texCoord, currentAttributes.st.values, insertedIndex * 2); + } + } - /** - * An immutable Color instance initialized to CSS color #228B22 - * <span class="colorSwath" style="background: #228B22;"></span> - * - * @constant - * @type {Color} - */ - Color.FORESTGREEN = freezeObject(Color.fromCssColorString('#228B22')); + function insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, currentIndex, point) { + var insertIndex = currentAttributes.position.values.length / 3; - /** - * An immutable Color instance initialized to CSS color #FF00FF - * <span class="colorSwath" style="background: #FF00FF;"></span> - * - * @constant - * @type {Color} - */ - Color.FUCHSIA = freezeObject(Color.fromCssColorString('#FF00FF')); + if (currentIndex !== -1) { + var prevIndex = indices[currentIndex]; + var newIndex = currentIndexMap[prevIndex]; - /** - * An immutable Color instance initialized to CSS color #DCDCDC - * <span class="colorSwath" style="background: #DCDCDC;"></span> - * - * @constant - * @type {Color} - */ - Color.GAINSBORO = freezeObject(Color.fromCssColorString('#DCDCDC')); + if (newIndex === -1) { + currentIndexMap[prevIndex] = insertIndex; + currentAttributes.position.values.push(point.x, point.y, point.z); + currentIndices.push(insertIndex); + return insertIndex; + } - /** - * An immutable Color instance initialized to CSS color #F8F8FF - * <span class="colorSwath" style="background: #F8F8FF;"></span> - * - * @constant - * @type {Color} - */ - Color.GHOSTWHITE = freezeObject(Color.fromCssColorString('#F8F8FF')); + currentIndices.push(newIndex); + return newIndex; + } - /** - * An immutable Color instance initialized to CSS color #FFD700 - * <span class="colorSwath" style="background: #FFD700;"></span> - * - * @constant - * @type {Color} - */ - Color.GOLD = freezeObject(Color.fromCssColorString('#FFD700')); + currentAttributes.position.values.push(point.x, point.y, point.z); + currentIndices.push(insertIndex); + return insertIndex; + } - /** - * An immutable Color instance initialized to CSS color #DAA520 - * <span class="colorSwath" style="background: #DAA520;"></span> - * - * @constant - * @type {Color} - */ - Color.GOLDENROD = freezeObject(Color.fromCssColorString('#DAA520')); + function splitLongitudeTriangles(instance) { + var geometry = instance.geometry; + var attributes = geometry.attributes; + var positions = attributes.position.values; + var normals = (defined(attributes.normal)) ? attributes.normal.values : undefined; + var bitangents = (defined(attributes.bitangent)) ? attributes.bitangent.values : undefined; + var tangents = (defined(attributes.tangent)) ? attributes.tangent.values : undefined; + var texCoords = (defined(attributes.st)) ? attributes.st.values : undefined; + var extrudeDirections = (defined(attributes.extrudeDirection)) ? attributes.extrudeDirection.values : undefined; + var indices = geometry.indices; - /** - * An immutable Color instance initialized to CSS color #808080 - * <span class="colorSwath" style="background: #808080;"></span> - * - * @constant - * @type {Color} - */ - Color.GRAY = freezeObject(Color.fromCssColorString('#808080')); + var eastGeometry = copyGeometryForSplit(geometry); + var westGeometry = copyGeometryForSplit(geometry); - /** - * An immutable Color instance initialized to CSS color #008000 - * <span class="colorSwath" style="background: #008000;"></span> - * - * @constant - * @type {Color} - */ - Color.GREEN = freezeObject(Color.fromCssColorString('#008000')); + var currentAttributes; + var currentIndices; + var currentIndexMap; + var insertedIndex; + var i; - /** - * An immutable Color instance initialized to CSS color #ADFF2F - * <span class="colorSwath" style="background: #ADFF2F;"></span> - * - * @constant - * @type {Color} - */ - Color.GREENYELLOW = freezeObject(Color.fromCssColorString('#ADFF2F')); + var westGeometryIndexMap = []; + westGeometryIndexMap.length = positions.length / 3; - /** - * An immutable Color instance initialized to CSS color #808080 - * <span class="colorSwath" style="background: #808080;"></span> - * - * @constant - * @type {Color} - */ - Color.GREY = Color.GRAY; + var eastGeometryIndexMap = []; + eastGeometryIndexMap.length = positions.length / 3; - /** - * An immutable Color instance initialized to CSS color #F0FFF0 - * <span class="colorSwath" style="background: #F0FFF0;"></span> - * - * @constant - * @type {Color} - */ - Color.HONEYDEW = freezeObject(Color.fromCssColorString('#F0FFF0')); + for (i = 0; i < westGeometryIndexMap.length; ++i) { + westGeometryIndexMap[i] = -1; + eastGeometryIndexMap[i] = -1; + } - /** - * An immutable Color instance initialized to CSS color #FF69B4 - * <span class="colorSwath" style="background: #FF69B4;"></span> - * - * @constant - * @type {Color} - */ - Color.HOTPINK = freezeObject(Color.fromCssColorString('#FF69B4')); + var len = indices.length; + for (i = 0; i < len; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; - /** - * An immutable Color instance initialized to CSS color #CD5C5C - * <span class="colorSwath" style="background: #CD5C5C;"></span> - * - * @constant - * @type {Color} - */ - Color.INDIANRED = freezeObject(Color.fromCssColorString('#CD5C5C')); + var p0 = Cartesian3.fromArray(positions, i0 * 3); + var p1 = Cartesian3.fromArray(positions, i1 * 3); + var p2 = Cartesian3.fromArray(positions, i2 * 3); - /** - * An immutable Color instance initialized to CSS color #4B0082 - * <span class="colorSwath" style="background: #4B0082;"></span> - * - * @constant - * @type {Color} - */ - Color.INDIGO = freezeObject(Color.fromCssColorString('#4B0082')); + var result = splitTriangle(p0, p1, p2); + if (defined(result) && result.positions.length > 3) { + var resultPositions = result.positions; + var resultIndices = result.indices; + var resultLength = resultIndices.length; - /** - * An immutable Color instance initialized to CSS color #FFFFF0 - * <span class="colorSwath" style="background: #FFFFF0;"></span> - * - * @constant - * @type {Color} - */ - Color.IVORY = freezeObject(Color.fromCssColorString('#FFFFF0')); + for (var j = 0; j < resultLength; ++j) { + var resultIndex = resultIndices[j]; + var point = resultPositions[resultIndex]; - /** - * An immutable Color instance initialized to CSS color #F0E68C - * <span class="colorSwath" style="background: #F0E68C;"></span> - * - * @constant - * @type {Color} - */ - Color.KHAKI = freezeObject(Color.fromCssColorString('#F0E68C')); + if (point.y < 0.0) { + currentAttributes = westGeometry.attributes; + currentIndices = westGeometry.indices; + currentIndexMap = westGeometryIndexMap; + } else { + currentAttributes = eastGeometry.attributes; + currentIndices = eastGeometry.indices; + currentIndexMap = eastGeometryIndexMap; + } - /** - * An immutable Color instance initialized to CSS color #E6E6FA - * <span class="colorSwath" style="background: #E6E6FA;"></span> - * - * @constant - * @type {Color} - */ - Color.LAVENDER = freezeObject(Color.fromCssColorString('#E6E6FA')); + insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, resultIndex < 3 ? i + resultIndex : -1, point); + computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); + } + } else { + if (defined(result)) { + p0 = result.positions[0]; + p1 = result.positions[1]; + p2 = result.positions[2]; + } - /** - * An immutable Color instance initialized to CSS color #FFF0F5 - * <span class="colorSwath" style="background: #FFF0F5;"></span> - * - * @constant - * @type {Color} - */ - Color.LAVENDAR_BLUSH = freezeObject(Color.fromCssColorString('#FFF0F5')); + if (p0.y < 0.0) { + currentAttributes = westGeometry.attributes; + currentIndices = westGeometry.indices; + currentIndexMap = westGeometryIndexMap; + } else { + currentAttributes = eastGeometry.attributes; + currentIndices = eastGeometry.indices; + currentIndexMap = eastGeometryIndexMap; + } - /** - * An immutable Color instance initialized to CSS color #7CFC00 - * <span class="colorSwath" style="background: #7CFC00;"></span> - * - * @constant - * @type {Color} - */ - Color.LAWNGREEN = freezeObject(Color.fromCssColorString('#7CFC00')); + insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i, p0); + computeTriangleAttributes(i0, i1, i2, p0, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); - /** - * An immutable Color instance initialized to CSS color #FFFACD - * <span class="colorSwath" style="background: #FFFACD;"></span> - * - * @constant - * @type {Color} - */ - Color.LEMONCHIFFON = freezeObject(Color.fromCssColorString('#FFFACD')); + insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 1, p1); + computeTriangleAttributes(i0, i1, i2, p1, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); - /** - * An immutable Color instance initialized to CSS color #ADD8E6 - * <span class="colorSwath" style="background: #ADD8E6;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTBLUE = freezeObject(Color.fromCssColorString('#ADD8E6')); + insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 2, p2); + computeTriangleAttributes(i0, i1, i2, p2, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex); + } + } - /** - * An immutable Color instance initialized to CSS color #F08080 - * <span class="colorSwath" style="background: #F08080;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTCORAL = freezeObject(Color.fromCssColorString('#F08080')); + updateInstanceAfterSplit(instance, westGeometry, eastGeometry); + } - /** - * An immutable Color instance initialized to CSS color #E0FFFF - * <span class="colorSwath" style="background: #E0FFFF;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTCYAN = freezeObject(Color.fromCssColorString('#E0FFFF')); + var xzPlane = Plane.fromPointNormal(Cartesian3.ZERO, Cartesian3.UNIT_Y); - /** - * An immutable Color instance initialized to CSS color #FAFAD2 - * <span class="colorSwath" style="background: #FAFAD2;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTGOLDENRODYELLOW = freezeObject(Color.fromCssColorString('#FAFAD2')); + var offsetScratch = new Cartesian3(); + var offsetPointScratch = new Cartesian3(); - /** - * An immutable Color instance initialized to CSS color #D3D3D3 - * <span class="colorSwath" style="background: #D3D3D3;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTGRAY = freezeObject(Color.fromCssColorString('#D3D3D3')); + function splitLongitudeLines(instance) { + var geometry = instance.geometry; + var attributes = geometry.attributes; + var positions = attributes.position.values; + var indices = geometry.indices; - /** - * An immutable Color instance initialized to CSS color #90EE90 - * <span class="colorSwath" style="background: #90EE90;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTGREEN = freezeObject(Color.fromCssColorString('#90EE90')); + var eastGeometry = copyGeometryForSplit(geometry); + var westGeometry = copyGeometryForSplit(geometry); - /** - * An immutable Color instance initialized to CSS color #D3D3D3 - * <span class="colorSwath" style="background: #D3D3D3;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTGREY = Color.LIGHTGRAY; + var i; + var length = indices.length; - /** - * An immutable Color instance initialized to CSS color #FFB6C1 - * <span class="colorSwath" style="background: #FFB6C1;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTPINK = freezeObject(Color.fromCssColorString('#FFB6C1')); + var westGeometryIndexMap = []; + westGeometryIndexMap.length = positions.length / 3; - /** - * An immutable Color instance initialized to CSS color #20B2AA - * <span class="colorSwath" style="background: #20B2AA;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTSEAGREEN = freezeObject(Color.fromCssColorString('#20B2AA')); + var eastGeometryIndexMap = []; + eastGeometryIndexMap.length = positions.length / 3; - /** - * An immutable Color instance initialized to CSS color #87CEFA - * <span class="colorSwath" style="background: #87CEFA;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTSKYBLUE = freezeObject(Color.fromCssColorString('#87CEFA')); + for (i = 0; i < westGeometryIndexMap.length; ++i) { + westGeometryIndexMap[i] = -1; + eastGeometryIndexMap[i] = -1; + } - /** - * An immutable Color instance initialized to CSS color #778899 - * <span class="colorSwath" style="background: #778899;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTSLATEGRAY = freezeObject(Color.fromCssColorString('#778899')); + for (i = 0; i < length; i += 2) { + var i0 = indices[i]; + var i1 = indices[i + 1]; - /** - * An immutable Color instance initialized to CSS color #778899 - * <span class="colorSwath" style="background: #778899;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTSLATEGREY = Color.LIGHTSLATEGRAY; + var p0 = Cartesian3.fromArray(positions, i0 * 3, p0Scratch); + var p1 = Cartesian3.fromArray(positions, i1 * 3, p1Scratch); - /** - * An immutable Color instance initialized to CSS color #B0C4DE - * <span class="colorSwath" style="background: #B0C4DE;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTSTEELBLUE = freezeObject(Color.fromCssColorString('#B0C4DE')); + if (Math.abs(p0.y) < CesiumMath.EPSILON6){ + if (p0.y < 0.0) { + p0.y = -CesiumMath.EPSILON6; + } else { + p0.y = CesiumMath.EPSILON6; + } + } - /** - * An immutable Color instance initialized to CSS color #FFFFE0 - * <span class="colorSwath" style="background: #FFFFE0;"></span> - * - * @constant - * @type {Color} - */ - Color.LIGHTYELLOW = freezeObject(Color.fromCssColorString('#FFFFE0')); + if (Math.abs(p1.y) < CesiumMath.EPSILON6){ + if (p1.y < 0.0) { + p1.y = -CesiumMath.EPSILON6; + } else { + p1.y = CesiumMath.EPSILON6; + } + } - /** - * An immutable Color instance initialized to CSS color #00FF00 - * <span class="colorSwath" style="background: #00FF00;"></span> - * - * @constant - * @type {Color} - */ - Color.LIME = freezeObject(Color.fromCssColorString('#00FF00')); + var p0Attributes = eastGeometry.attributes; + var p0Indices = eastGeometry.indices; + var p0IndexMap = eastGeometryIndexMap; + var p1Attributes = westGeometry.attributes; + var p1Indices = westGeometry.indices; + var p1IndexMap = westGeometryIndexMap; - /** - * An immutable Color instance initialized to CSS color #32CD32 - * <span class="colorSwath" style="background: #32CD32;"></span> - * - * @constant - * @type {Color} - */ - Color.LIMEGREEN = freezeObject(Color.fromCssColorString('#32CD32')); - - /** - * An immutable Color instance initialized to CSS color #FAF0E6 - * <span class="colorSwath" style="background: #FAF0E6;"></span> - * - * @constant - * @type {Color} - */ - Color.LINEN = freezeObject(Color.fromCssColorString('#FAF0E6')); - - /** - * An immutable Color instance initialized to CSS color #FF00FF - * <span class="colorSwath" style="background: #FF00FF;"></span> - * - * @constant - * @type {Color} - */ - Color.MAGENTA = freezeObject(Color.fromCssColorString('#FF00FF')); - - /** - * An immutable Color instance initialized to CSS color #800000 - * <span class="colorSwath" style="background: #800000;"></span> - * - * @constant - * @type {Color} - */ - Color.MAROON = freezeObject(Color.fromCssColorString('#800000')); - - /** - * An immutable Color instance initialized to CSS color #66CDAA - * <span class="colorSwath" style="background: #66CDAA;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMAQUAMARINE = freezeObject(Color.fromCssColorString('#66CDAA')); - - /** - * An immutable Color instance initialized to CSS color #0000CD - * <span class="colorSwath" style="background: #0000CD;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMBLUE = freezeObject(Color.fromCssColorString('#0000CD')); - - /** - * An immutable Color instance initialized to CSS color #BA55D3 - * <span class="colorSwath" style="background: #BA55D3;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMORCHID = freezeObject(Color.fromCssColorString('#BA55D3')); + var intersection = IntersectionTests.lineSegmentPlane(p0, p1, xzPlane, p2Scratch); + if (defined(intersection)) { + // move point on the xz-plane slightly away from the plane + var offset = Cartesian3.multiplyByScalar(Cartesian3.UNIT_Y, 5.0 * CesiumMath.EPSILON9, offsetScratch); + if (p0.y < 0.0) { + Cartesian3.negate(offset, offset); - /** - * An immutable Color instance initialized to CSS color #9370DB - * <span class="colorSwath" style="background: #9370DB;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMPURPLE = freezeObject(Color.fromCssColorString('#9370DB')); + p0Attributes = westGeometry.attributes; + p0Indices = westGeometry.indices; + p0IndexMap = westGeometryIndexMap; + p1Attributes = eastGeometry.attributes; + p1Indices = eastGeometry.indices; + p1IndexMap = eastGeometryIndexMap; + } - /** - * An immutable Color instance initialized to CSS color #3CB371 - * <span class="colorSwath" style="background: #3CB371;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMSEAGREEN = freezeObject(Color.fromCssColorString('#3CB371')); + var offsetPoint = Cartesian3.add(intersection, offset, offsetPointScratch); + insertSplitPoint(p0Attributes, p0Indices, p0IndexMap, indices, i, p0); + insertSplitPoint(p0Attributes, p0Indices, p0IndexMap, indices, -1, offsetPoint); - /** - * An immutable Color instance initialized to CSS color #7B68EE - * <span class="colorSwath" style="background: #7B68EE;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMSLATEBLUE = freezeObject(Color.fromCssColorString('#7B68EE')); + Cartesian3.negate(offset, offset); + Cartesian3.add(intersection, offset, offsetPoint); + insertSplitPoint(p1Attributes, p1Indices, p1IndexMap, indices, -1, offsetPoint); + insertSplitPoint(p1Attributes, p1Indices, p1IndexMap, indices, i + 1, p1); + } else { + var currentAttributes; + var currentIndices; + var currentIndexMap; - /** - * An immutable Color instance initialized to CSS color #00FA9A - * <span class="colorSwath" style="background: #00FA9A;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMSPRINGGREEN = freezeObject(Color.fromCssColorString('#00FA9A')); + if (p0.y < 0.0) { + currentAttributes = westGeometry.attributes; + currentIndices = westGeometry.indices; + currentIndexMap = westGeometryIndexMap; + } else { + currentAttributes = eastGeometry.attributes; + currentIndices = eastGeometry.indices; + currentIndexMap = eastGeometryIndexMap; + } - /** - * An immutable Color instance initialized to CSS color #48D1CC - * <span class="colorSwath" style="background: #48D1CC;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMTURQUOISE = freezeObject(Color.fromCssColorString('#48D1CC')); + insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i, p0); + insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 1, p1); + } + } - /** - * An immutable Color instance initialized to CSS color #C71585 - * <span class="colorSwath" style="background: #C71585;"></span> - * - * @constant - * @type {Color} - */ - Color.MEDIUMVIOLETRED = freezeObject(Color.fromCssColorString('#C71585')); + updateInstanceAfterSplit(instance, westGeometry, eastGeometry); + } - /** - * An immutable Color instance initialized to CSS color #191970 - * <span class="colorSwath" style="background: #191970;"></span> - * - * @constant - * @type {Color} - */ - Color.MIDNIGHTBLUE = freezeObject(Color.fromCssColorString('#191970')); + var cartesian2Scratch0 = new Cartesian2(); + var cartesian2Scratch1 = new Cartesian2(); - /** - * An immutable Color instance initialized to CSS color #F5FFFA - * <span class="colorSwath" style="background: #F5FFFA;"></span> - * - * @constant - * @type {Color} - */ - Color.MINTCREAM = freezeObject(Color.fromCssColorString('#F5FFFA')); + var cartesian3Scratch0 = new Cartesian3(); + var cartesian3Scratch2 = new Cartesian3(); + var cartesian3Scratch3 = new Cartesian3(); + var cartesian3Scratch4 = new Cartesian3(); + var cartesian3Scratch5 = new Cartesian3(); + var cartesian3Scratch6 = new Cartesian3(); - /** - * An immutable Color instance initialized to CSS color #FFE4E1 - * <span class="colorSwath" style="background: #FFE4E1;"></span> - * - * @constant - * @type {Color} - */ - Color.MISTYROSE = freezeObject(Color.fromCssColorString('#FFE4E1')); + var cartesian4Scratch0 = new Cartesian4(); - /** - * An immutable Color instance initialized to CSS color #FFE4B5 - * <span class="colorSwath" style="background: #FFE4B5;"></span> - * - * @constant - * @type {Color} - */ - Color.MOCCASIN = freezeObject(Color.fromCssColorString('#FFE4B5')); + function updateAdjacencyAfterSplit(geometry) { + var attributes = geometry.attributes; + var positions = attributes.position.values; + var prevPositions = attributes.prevPosition.values; + var nextPositions = attributes.nextPosition.values; - /** - * An immutable Color instance initialized to CSS color #FFDEAD - * <span class="colorSwath" style="background: #FFDEAD;"></span> - * - * @constant - * @type {Color} - */ - Color.NAVAJOWHITE = freezeObject(Color.fromCssColorString('#FFDEAD')); + var length = positions.length; + for (var j = 0; j < length; j += 3) { + var position = Cartesian3.unpack(positions, j, cartesian3Scratch0); + if (position.x > 0.0) { + continue; + } - /** - * An immutable Color instance initialized to CSS color #000080 - * <span class="colorSwath" style="background: #000080;"></span> - * - * @constant - * @type {Color} - */ - Color.NAVY = freezeObject(Color.fromCssColorString('#000080')); + var prevPosition = Cartesian3.unpack(prevPositions, j, cartesian3Scratch2); + if ((position.y < 0.0 && prevPosition.y > 0.0) || (position.y > 0.0 && prevPosition.y < 0.0)) { + if (j - 3 > 0) { + prevPositions[j] = positions[j - 3]; + prevPositions[j + 1] = positions[j - 2]; + prevPositions[j + 2] = positions[j - 1]; + } else { + Cartesian3.pack(position, prevPositions, j); + } + } - /** - * An immutable Color instance initialized to CSS color #FDF5E6 - * <span class="colorSwath" style="background: #FDF5E6;"></span> - * - * @constant - * @type {Color} - */ - Color.OLDLACE = freezeObject(Color.fromCssColorString('#FDF5E6')); + var nextPosition = Cartesian3.unpack(nextPositions, j, cartesian3Scratch3); + if ((position.y < 0.0 && nextPosition.y > 0.0) || (position.y > 0.0 && nextPosition.y < 0.0)) { + if (j + 3 < length) { + nextPositions[j] = positions[j + 3]; + nextPositions[j + 1] = positions[j + 4]; + nextPositions[j + 2] = positions[j + 5]; + } else { + Cartesian3.pack(position, nextPositions, j); + } + } + } + } - /** - * An immutable Color instance initialized to CSS color #808000 - * <span class="colorSwath" style="background: #808000;"></span> - * - * @constant - * @type {Color} - */ - Color.OLIVE = freezeObject(Color.fromCssColorString('#808000')); + var offsetScalar = 5.0 * CesiumMath.EPSILON9; + var coplanarOffset = CesiumMath.EPSILON6; - /** - * An immutable Color instance initialized to CSS color #6B8E23 - * <span class="colorSwath" style="background: #6B8E23;"></span> - * - * @constant - * @type {Color} - */ - Color.OLIVEDRAB = freezeObject(Color.fromCssColorString('#6B8E23')); + function splitLongitudePolyline(instance) { + var geometry = instance.geometry; + var attributes = geometry.attributes; + var positions = attributes.position.values; + var prevPositions = attributes.prevPosition.values; + var nextPositions = attributes.nextPosition.values; + var expandAndWidths = attributes.expandAndWidth.values; - /** - * An immutable Color instance initialized to CSS color #FFA500 - * <span class="colorSwath" style="background: #FFA500;"></span> - * - * @constant - * @type {Color} - */ - Color.ORANGE = freezeObject(Color.fromCssColorString('#FFA500')); + var texCoords = (defined(attributes.st)) ? attributes.st.values : undefined; + var colors = (defined(attributes.color)) ? attributes.color.values : undefined; - /** - * An immutable Color instance initialized to CSS color #FF4500 - * <span class="colorSwath" style="background: #FF4500;"></span> - * - * @constant - * @type {Color} - */ - Color.ORANGERED = freezeObject(Color.fromCssColorString('#FF4500')); + var eastGeometry = copyGeometryForSplit(geometry); + var westGeometry = copyGeometryForSplit(geometry); - /** - * An immutable Color instance initialized to CSS color #DA70D6 - * <span class="colorSwath" style="background: #DA70D6;"></span> - * - * @constant - * @type {Color} - */ - Color.ORCHID = freezeObject(Color.fromCssColorString('#DA70D6')); + var i; + var j; + var index; - /** - * An immutable Color instance initialized to CSS color #EEE8AA - * <span class="colorSwath" style="background: #EEE8AA;"></span> - * - * @constant - * @type {Color} - */ - Color.PALEGOLDENROD = freezeObject(Color.fromCssColorString('#EEE8AA')); + var intersectionFound = false; - /** - * An immutable Color instance initialized to CSS color #98FB98 - * <span class="colorSwath" style="background: #98FB98;"></span> - * - * @constant - * @type {Color} - */ - Color.PALEGREEN = freezeObject(Color.fromCssColorString('#98FB98')); + var length = positions.length / 3; + for (i = 0; i < length; i += 4) { + var i0 = i; + var i2 = i + 2; - /** - * An immutable Color instance initialized to CSS color #AFEEEE - * <span class="colorSwath" style="background: #AFEEEE;"></span> - * - * @constant - * @type {Color} - */ - Color.PALETURQUOISE = freezeObject(Color.fromCssColorString('#AFEEEE')); + var p0 = Cartesian3.fromArray(positions, i0 * 3, cartesian3Scratch0); + var p2 = Cartesian3.fromArray(positions, i2 * 3, cartesian3Scratch2); - /** - * An immutable Color instance initialized to CSS color #DB7093 - * <span class="colorSwath" style="background: #DB7093;"></span> - * - * @constant - * @type {Color} - */ - Color.PALEVIOLETRED = freezeObject(Color.fromCssColorString('#DB7093')); + // Offset points that are close to the 180 longitude and change the previous/next point + // to be the same offset point so it can be projected to 2D. There is special handling in the + // shader for when position == prevPosition || position == nextPosition. + if (Math.abs(p0.y) < coplanarOffset) { + p0.y = coplanarOffset * (p2.y < 0.0 ? -1.0 : 1.0); + positions[i * 3 + 1] = p0.y; + positions[(i + 1) * 3 + 1] = p0.y; - /** - * An immutable Color instance initialized to CSS color #FFEFD5 - * <span class="colorSwath" style="background: #FFEFD5;"></span> - * - * @constant - * @type {Color} - */ - Color.PAPAYAWHIP = freezeObject(Color.fromCssColorString('#FFEFD5')); + for (j = i0 * 3; j < i0 * 3 + 4 * 3; j += 3) { + prevPositions[j] = positions[i * 3]; + prevPositions[j + 1] = positions[i * 3 + 1]; + prevPositions[j + 2] = positions[i * 3 + 2]; + } + } - /** - * An immutable Color instance initialized to CSS color #FFDAB9 - * <span class="colorSwath" style="background: #FFDAB9;"></span> - * - * @constant - * @type {Color} - */ - Color.PEACHPUFF = freezeObject(Color.fromCssColorString('#FFDAB9')); + // Do the same but for when the line crosses 180 longitude in the opposite direction. + if (Math.abs(p2.y) < coplanarOffset) { + p2.y = coplanarOffset * (p0.y < 0.0 ? -1.0 : 1.0); + positions[(i + 2) * 3 + 1] = p2.y; + positions[(i + 3) * 3 + 1] = p2.y; - /** - * An immutable Color instance initialized to CSS color #CD853F - * <span class="colorSwath" style="background: #CD853F;"></span> - * - * @constant - * @type {Color} - */ - Color.PERU = freezeObject(Color.fromCssColorString('#CD853F')); + for (j = i0 * 3; j < i0 * 3 + 4 * 3; j += 3) { + nextPositions[j] = positions[(i + 2) * 3]; + nextPositions[j + 1] = positions[(i + 2) * 3 + 1]; + nextPositions[j + 2] = positions[(i + 2) * 3 + 2]; + } + } - /** - * An immutable Color instance initialized to CSS color #FFC0CB - * <span class="colorSwath" style="background: #FFC0CB;"></span> - * - * @constant - * @type {Color} - */ - Color.PINK = freezeObject(Color.fromCssColorString('#FFC0CB')); + var p0Attributes = eastGeometry.attributes; + var p0Indices = eastGeometry.indices; + var p2Attributes = westGeometry.attributes; + var p2Indices = westGeometry.indices; - /** - * An immutable Color instance initialized to CSS color #DDA0DD - * <span class="colorSwath" style="background: #DDA0DD;"></span> - * - * @constant - * @type {Color} - */ - Color.PLUM = freezeObject(Color.fromCssColorString('#DDA0DD')); + var intersection = IntersectionTests.lineSegmentPlane(p0, p2, xzPlane, cartesian3Scratch4); + if (defined(intersection)) { + intersectionFound = true; - /** - * An immutable Color instance initialized to CSS color #B0E0E6 - * <span class="colorSwath" style="background: #B0E0E6;"></span> - * - * @constant - * @type {Color} - */ - Color.POWDERBLUE = freezeObject(Color.fromCssColorString('#B0E0E6')); + // move point on the xz-plane slightly away from the plane + var offset = Cartesian3.multiplyByScalar(Cartesian3.UNIT_Y, offsetScalar, cartesian3Scratch5); + if (p0.y < 0.0) { + Cartesian3.negate(offset, offset); + p0Attributes = westGeometry.attributes; + p0Indices = westGeometry.indices; + p2Attributes = eastGeometry.attributes; + p2Indices = eastGeometry.indices; + } - /** - * An immutable Color instance initialized to CSS color #800080 - * <span class="colorSwath" style="background: #800080;"></span> - * - * @constant - * @type {Color} - */ - Color.PURPLE = freezeObject(Color.fromCssColorString('#800080')); + var offsetPoint = Cartesian3.add(intersection, offset, cartesian3Scratch6); + p0Attributes.position.values.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z); + p0Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p0Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - /** - * An immutable Color instance initialized to CSS color #FF0000 - * <span class="colorSwath" style="background: #FF0000;"></span> - * - * @constant - * @type {Color} - */ - Color.RED = freezeObject(Color.fromCssColorString('#FF0000')); + p0Attributes.prevPosition.values.push(prevPositions[i0 * 3], prevPositions[i0 * 3 + 1], prevPositions[i0 * 3 + 2]); + p0Attributes.prevPosition.values.push(prevPositions[i0 * 3 + 3], prevPositions[i0 * 3 + 4], prevPositions[i0 * 3 + 5]); + p0Attributes.prevPosition.values.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z); - /** - * An immutable Color instance initialized to CSS color #BC8F8F - * <span class="colorSwath" style="background: #BC8F8F;"></span> - * - * @constant - * @type {Color} - */ - Color.ROSYBROWN = freezeObject(Color.fromCssColorString('#BC8F8F')); + p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p0Attributes.nextPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - /** - * An immutable Color instance initialized to CSS color #4169E1 - * <span class="colorSwath" style="background: #4169E1;"></span> - * - * @constant - * @type {Color} - */ - Color.ROYALBLUE = freezeObject(Color.fromCssColorString('#4169E1')); + Cartesian3.negate(offset, offset); + Cartesian3.add(intersection, offset, offsetPoint); + p2Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p2Attributes.position.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p2Attributes.position.values.push(p2.x, p2.y, p2.z, p2.x, p2.y, p2.z); - /** - * An immutable Color instance initialized to CSS color #8B4513 - * <span class="colorSwath" style="background: #8B4513;"></span> - * - * @constant - * @type {Color} - */ - Color.SADDLEBROWN = freezeObject(Color.fromCssColorString('#8B4513')); + p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); + p2Attributes.prevPosition.values.push(offsetPoint.x, offsetPoint.y, offsetPoint.z); - /** - * An immutable Color instance initialized to CSS color #FA8072 - * <span class="colorSwath" style="background: #FA8072;"></span> - * - * @constant - * @type {Color} - */ - Color.SALMON = freezeObject(Color.fromCssColorString('#FA8072')); + p2Attributes.nextPosition.values.push(p2.x, p2.y, p2.z, p2.x, p2.y, p2.z); + p2Attributes.nextPosition.values.push(nextPositions[i2 * 3], nextPositions[i2 * 3 + 1], nextPositions[i2 * 3 + 2]); + p2Attributes.nextPosition.values.push(nextPositions[i2 * 3 + 3], nextPositions[i2 * 3 + 4], nextPositions[i2 * 3 + 5]); - /** - * An immutable Color instance initialized to CSS color #F4A460 - * <span class="colorSwath" style="background: #F4A460;"></span> - * - * @constant - * @type {Color} - */ - Color.SANDYBROWN = freezeObject(Color.fromCssColorString('#F4A460')); + var ew0 = Cartesian2.fromArray(expandAndWidths, i0 * 2, cartesian2Scratch0); + var width = Math.abs(ew0.y); - /** - * An immutable Color instance initialized to CSS color #2E8B57 - * <span class="colorSwath" style="background: #2E8B57;"></span> - * - * @constant - * @type {Color} - */ - Color.SEAGREEN = freezeObject(Color.fromCssColorString('#2E8B57')); + p0Attributes.expandAndWidth.values.push(-1, width, 1, width); + p0Attributes.expandAndWidth.values.push(-1, -width, 1, -width); + p2Attributes.expandAndWidth.values.push(-1, width, 1, width); + p2Attributes.expandAndWidth.values.push(-1, -width, 1, -width); - /** - * An immutable Color instance initialized to CSS color #FFF5EE - * <span class="colorSwath" style="background: #FFF5EE;"></span> - * - * @constant - * @type {Color} - */ - Color.SEASHELL = freezeObject(Color.fromCssColorString('#FFF5EE')); + var t = Cartesian3.magnitudeSquared(Cartesian3.subtract(intersection, p0, cartesian3Scratch3)); + t /= Cartesian3.magnitudeSquared(Cartesian3.subtract(p2, p0, cartesian3Scratch3)); - /** - * An immutable Color instance initialized to CSS color #A0522D - * <span class="colorSwath" style="background: #A0522D;"></span> - * - * @constant - * @type {Color} - */ - Color.SIENNA = freezeObject(Color.fromCssColorString('#A0522D')); + if (defined(colors)) { + var c0 = Cartesian4.fromArray(colors, i0 * 4, cartesian4Scratch0); + var c2 = Cartesian4.fromArray(colors, i2 * 4, cartesian4Scratch0); - /** - * An immutable Color instance initialized to CSS color #C0C0C0 - * <span class="colorSwath" style="background: #C0C0C0;"></span> - * - * @constant - * @type {Color} - */ - Color.SILVER = freezeObject(Color.fromCssColorString('#C0C0C0')); + var r = CesiumMath.lerp(c0.x, c2.x, t); + var g = CesiumMath.lerp(c0.y, c2.y, t); + var b = CesiumMath.lerp(c0.z, c2.z, t); + var a = CesiumMath.lerp(c0.w, c2.w, t); - /** - * An immutable Color instance initialized to CSS color #87CEEB - * <span class="colorSwath" style="background: #87CEEB;"></span> - * - * @constant - * @type {Color} - */ - Color.SKYBLUE = freezeObject(Color.fromCssColorString('#87CEEB')); + for (j = i0 * 4; j < i0 * 4 + 2 * 4; ++j) { + p0Attributes.color.values.push(colors[j]); + } + p0Attributes.color.values.push(r, g, b, a); + p0Attributes.color.values.push(r, g, b, a); + p2Attributes.color.values.push(r, g, b, a); + p2Attributes.color.values.push(r, g, b, a); + for (j = i2 * 4; j < i2 * 4 + 2 * 4; ++j) { + p2Attributes.color.values.push(colors[j]); + } + } - /** - * An immutable Color instance initialized to CSS color #6A5ACD - * <span class="colorSwath" style="background: #6A5ACD;"></span> - * - * @constant - * @type {Color} - */ - Color.SLATEBLUE = freezeObject(Color.fromCssColorString('#6A5ACD')); + if (defined(texCoords)) { + var s0 = Cartesian2.fromArray(texCoords, i0 * 2, cartesian2Scratch0); + var s3 = Cartesian2.fromArray(texCoords, (i + 3) * 2, cartesian2Scratch1); - /** - * An immutable Color instance initialized to CSS color #708090 - * <span class="colorSwath" style="background: #708090;"></span> - * - * @constant - * @type {Color} - */ - Color.SLATEGRAY = freezeObject(Color.fromCssColorString('#708090')); + var sx = CesiumMath.lerp(s0.x, s3.x, t); - /** - * An immutable Color instance initialized to CSS color #708090 - * <span class="colorSwath" style="background: #708090;"></span> - * - * @constant - * @type {Color} - */ - Color.SLATEGREY = Color.SLATEGRAY; + for (j = i0 * 2; j < i0 * 2 + 2 * 2; ++j) { + p0Attributes.st.values.push(texCoords[j]); + } + p0Attributes.st.values.push(sx, s0.y); + p0Attributes.st.values.push(sx, s3.y); + p2Attributes.st.values.push(sx, s0.y); + p2Attributes.st.values.push(sx, s3.y); + for (j = i2 * 2; j < i2 * 2 + 2 * 2; ++j) { + p2Attributes.st.values.push(texCoords[j]); + } + } - /** - * An immutable Color instance initialized to CSS color #FFFAFA - * <span class="colorSwath" style="background: #FFFAFA;"></span> - * - * @constant - * @type {Color} - */ - Color.SNOW = freezeObject(Color.fromCssColorString('#FFFAFA')); + index = p0Attributes.position.values.length / 3 - 4; + p0Indices.push(index, index + 2, index + 1); + p0Indices.push(index + 1, index + 2, index + 3); - /** - * An immutable Color instance initialized to CSS color #00FF7F - * <span class="colorSwath" style="background: #00FF7F;"></span> - * - * @constant - * @type {Color} - */ - Color.SPRINGGREEN = freezeObject(Color.fromCssColorString('#00FF7F')); + index = p2Attributes.position.values.length / 3 - 4; + p2Indices.push(index, index + 2, index + 1); + p2Indices.push(index + 1, index + 2, index + 3); + } else { + var currentAttributes; + var currentIndices; - /** - * An immutable Color instance initialized to CSS color #4682B4 - * <span class="colorSwath" style="background: #4682B4;"></span> - * - * @constant - * @type {Color} - */ - Color.STEELBLUE = freezeObject(Color.fromCssColorString('#4682B4')); + if (p0.y < 0.0) { + currentAttributes = westGeometry.attributes; + currentIndices = westGeometry.indices; + } else { + currentAttributes = eastGeometry.attributes; + currentIndices = eastGeometry.indices; + } - /** - * An immutable Color instance initialized to CSS color #D2B48C - * <span class="colorSwath" style="background: #D2B48C;"></span> - * - * @constant - * @type {Color} - */ - Color.TAN = freezeObject(Color.fromCssColorString('#D2B48C')); + currentAttributes.position.values.push(p0.x, p0.y, p0.z); + currentAttributes.position.values.push(p0.x, p0.y, p0.z); + currentAttributes.position.values.push(p2.x, p2.y, p2.z); + currentAttributes.position.values.push(p2.x, p2.y, p2.z); - /** - * An immutable Color instance initialized to CSS color #008080 - * <span class="colorSwath" style="background: #008080;"></span> - * - * @constant - * @type {Color} - */ - Color.TEAL = freezeObject(Color.fromCssColorString('#008080')); + for (j = i * 3; j < i * 3 + 4 * 3; ++j) { + currentAttributes.prevPosition.values.push(prevPositions[j]); + currentAttributes.nextPosition.values.push(nextPositions[j]); + } - /** - * An immutable Color instance initialized to CSS color #D8BFD8 - * <span class="colorSwath" style="background: #D8BFD8;"></span> - * - * @constant - * @type {Color} - */ - Color.THISTLE = freezeObject(Color.fromCssColorString('#D8BFD8')); + for (j = i * 2; j < i * 2 + 4 * 2; ++j) { + currentAttributes.expandAndWidth.values.push(expandAndWidths[j]); + if (defined(texCoords)) { + currentAttributes.st.values.push(texCoords[j]); + } + } - /** - * An immutable Color instance initialized to CSS color #FF6347 - * <span class="colorSwath" style="background: #FF6347;"></span> - * - * @constant - * @type {Color} - */ - Color.TOMATO = freezeObject(Color.fromCssColorString('#FF6347')); + if (defined(colors)) { + for (j = i * 4; j < i * 4 + 4 * 4; ++j) { + currentAttributes.color.values.push(colors[j]); + } + } - /** - * An immutable Color instance initialized to CSS color #40E0D0 - * <span class="colorSwath" style="background: #40E0D0;"></span> - * - * @constant - * @type {Color} - */ - Color.TURQUOISE = freezeObject(Color.fromCssColorString('#40E0D0')); + index = currentAttributes.position.values.length / 3 - 4; + currentIndices.push(index, index + 2, index + 1); + currentIndices.push(index + 1, index + 2, index + 3); + } + } - /** - * An immutable Color instance initialized to CSS color #EE82EE - * <span class="colorSwath" style="background: #EE82EE;"></span> - * - * @constant - * @type {Color} - */ - Color.VIOLET = freezeObject(Color.fromCssColorString('#EE82EE')); + if (intersectionFound) { + updateAdjacencyAfterSplit(westGeometry); + updateAdjacencyAfterSplit(eastGeometry); + } - /** - * An immutable Color instance initialized to CSS color #F5DEB3 - * <span class="colorSwath" style="background: #F5DEB3;"></span> - * - * @constant - * @type {Color} - */ - Color.WHEAT = freezeObject(Color.fromCssColorString('#F5DEB3')); + updateInstanceAfterSplit(instance, westGeometry, eastGeometry); + } /** - * An immutable Color instance initialized to CSS color #FFFFFF - * <span class="colorSwath" style="background: #FFFFFF;"></span> + * Splits the instances's geometry, by introducing new vertices and indices,that + * intersect the International Date Line and Prime Meridian so that no primitives cross longitude + * -180/180 degrees. This is not required for 3D drawing, but is required for + * correcting drawing in 2D and Columbus view. * - * @constant - * @type {Color} - */ - Color.WHITE = freezeObject(Color.fromCssColorString('#FFFFFF')); - - /** - * An immutable Color instance initialized to CSS color #F5F5F5 - * <span class="colorSwath" style="background: #F5F5F5;"></span> + * @private * - * @constant - * @type {Color} - */ - Color.WHITESMOKE = freezeObject(Color.fromCssColorString('#F5F5F5')); - - /** - * An immutable Color instance initialized to CSS color #FFFF00 - * <span class="colorSwath" style="background: #FFFF00;"></span> + * @param {GeometryInstance} instance The instance to modify. + * @returns {GeometryInstance} The modified <code>instance</code> argument, with it's geometry split at the International Date Line. * - * @constant - * @type {Color} + * @example + * instance = Cesium.GeometryPipeline.splitLongitude(instance); */ - Color.YELLOW = freezeObject(Color.fromCssColorString('#FFFF00')); + GeometryPipeline.splitLongitude = function(instance) { + if (!defined(instance)) { + throw new DeveloperError('instance is required.'); + } + + var geometry = instance.geometry; + var boundingSphere = geometry.boundingSphere; + if (defined(boundingSphere)) { + var minX = boundingSphere.center.x - boundingSphere.radius; + if (minX > 0 || BoundingSphere.intersectPlane(boundingSphere, Plane.ORIGIN_ZX_PLANE) !== Intersect.INTERSECTING) { + return instance; + } + } - /** - * An immutable Color instance initialized to CSS color #9ACD32 - * <span class="colorSwath" style="background: #9ACD32;"></span> - * - * @constant - * @type {Color} - */ - Color.YELLOWGREEN = freezeObject(Color.fromCssColorString('#9ACD32')); + if (geometry.geometryType !== GeometryType.NONE) { + switch (geometry.geometryType) { + case GeometryType.POLYLINES: + splitLongitudePolyline(instance); + break; + case GeometryType.TRIANGLES: + splitLongitudeTriangles(instance); + break; + case GeometryType.LINES: + splitLongitudeLines(instance); + break; + } + } else { + indexPrimitive(geometry); + if (geometry.primitiveType === PrimitiveType.TRIANGLES) { + splitLongitudeTriangles(instance); + } else if (geometry.primitiveType === PrimitiveType.LINES) { + splitLongitudeLines(instance); + } + } - /** - * An immutable Color instance initialized to CSS transparent. - * <span class="colorSwath" style="background: transparent;"></span> - * - * @constant - * @type {Color} - */ - Color.TRANSPARENT = freezeObject(new Color(0, 0, 0, 0)); + return instance; + }; - return Color; + return GeometryPipeline; }); -define('Core/ClippingPlaneCollection',[ +define('Core/EllipseGeometry',[ + './BoundingSphere', + './Cartesian2', './Cartesian3', - './Cartesian4', - './Check', - './Color', + './Cartographic', + './ComponentDatatype', './defaultValue', './defined', './defineProperties', './DeveloperError', - './Intersect', + './EllipseGeometryLibrary', + './Ellipsoid', + './GeographicProjection', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './GeometryInstance', + './GeometryPipeline', + './IndexDatatype', + './Math', + './Matrix3', './Matrix4', - './Plane' + './PrimitiveType', + './Quaternion', + './Rectangle', + './Transforms', + './VertexFormat' ], function( + BoundingSphere, + Cartesian2, Cartesian3, - Cartesian4, - Check, - Color, + Cartographic, + ComponentDatatype, defaultValue, defined, defineProperties, DeveloperError, - Intersect, + EllipseGeometryLibrary, + Ellipsoid, + GeographicProjection, + Geometry, + GeometryAttribute, + GeometryAttributes, + GeometryInstance, + GeometryPipeline, + IndexDatatype, + CesiumMath, + Matrix3, Matrix4, - Plane) { + PrimitiveType, + Quaternion, + Rectangle, + Transforms, + VertexFormat) { 'use strict'; - /** - * Specifies a set of clipping planes. Clipping planes selectively disable rendering in a region on the - * outside of the specified list of {@link Plane} objects. - * - * @alias ClippingPlaneCollection - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Plane[]} [options.planes=[]] An array of up to 6 {@link Plane} objects used to selectively disable rendering on the outside of each plane. - * @param {Boolean} [options.enabled=true] Determines whether the clipping planes are active. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix specifying an additional transform relative to the clipping planes original coordinate system. - * @param {Boolean} [options.unionClippingRegions=false] If true, a region will be clipped if included in any plane in the collection. Otherwise, the region to be clipped must intersect the regions defined by all planes in this collection. - * @param {Color} [options.edgeColor=Color.WHITE] The color applied to highlight the edge along which an object is clipped. - * @param {Number} [options.edgeWidth=0.0] The width, in pixels, of the highlight applied to the edge along which an object is clipped. - */ - function ClippingPlaneCollection(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var scratchCartesian1 = new Cartesian3(); + var scratchCartesian2 = new Cartesian3(); + var scratchCartesian3 = new Cartesian3(); + var scratchCartesian4 = new Cartesian3(); + var texCoordScratch = new Cartesian2(); + var textureMatrixScratch = new Matrix3(); + var quaternionScratch = new Quaternion(); - var planes = options.planes; - if (defined(planes)) { - this._planes = planes.slice(0); - } else { - this._planes = []; - } + var scratchNormal = new Cartesian3(); + var scratchTangent = new Cartesian3(); + var scratchBitangent = new Cartesian3(); - /** - * Determines whether the clipping planes are active. - * - * @type {Boolean} - * @default true - */ - this.enabled = defaultValue(options.enabled, true); + var scratchCartographic = new Cartographic(); + var projectedCenterScratch = new Cartesian3(); - /** - * The 4x4 transformation matrix specifying an additional transform relative to the clipping planes - * original coordinate system. - * - * @type {Matrix4} - * @default Matrix4.IDENTITY - */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + var scratchMinTexCoord = new Cartesian2(); + var scratchMaxTexCoord = new Cartesian2(); - /** - * The color applied to highlight the edge along which an object is clipped. - * - * @type {Color} - * @default Color.WHITE - */ - this.edgeColor = Color.clone(defaultValue(options.edgeColor, Color.WHITE)); + function computeTopBottomAttributes(positions, options, extrude) { + var vertexFormat = options.vertexFormat; + var center = options.center; + var semiMajorAxis = options.semiMajorAxis; + var semiMinorAxis = options.semiMinorAxis; + var ellipsoid = options.ellipsoid; + var stRotation = options.stRotation; + var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3; + var shadowVolume = options.shadowVolume; - /** - * The width, in pixels, of the highlight applied to the edge along which an object is clipped. - * - * @type {Number} - * @default 0.0 - */ - this.edgeWidth = defaultValue(options.edgeWidth, 0.0); + var textureCoordinates = (vertexFormat.st) ? new Float32Array(size * 2) : undefined; + var normals = (vertexFormat.normal) ? new Float32Array(size * 3) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(size * 3) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(size * 3) : undefined; - this._testIntersection = undefined; - this._unionClippingRegions = undefined; - this.unionClippingRegions = defaultValue(options.unionClippingRegions, false); - } + var extrudeNormals = (shadowVolume) ? new Float32Array(size * 3) : undefined; - function unionIntersectFunction(value) { - return (value === Intersect.OUTSIDE); - } + var textureCoordIndex = 0; - function defaultIntersectFunction(value) { - return (value === Intersect.INSIDE); - } + // Raise positions to a height above the ellipsoid and compute the + // texture coordinates, normals, tangents, and bitangents. + var normal = scratchNormal; + var tangent = scratchTangent; + var bitangent = scratchBitangent; - defineProperties(ClippingPlaneCollection.prototype, { - /** - * Returns the number of planes in this collection. This is commonly used with - * {@link ClippingPlaneCollection#get} to iterate over all the planes - * in the collection. - * - * @memberof ClippingPlaneCollection.prototype - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._planes.length; - } - }, + var projection = new GeographicProjection(ellipsoid); + var projectedCenter = projection.project(ellipsoid.cartesianToCartographic(center, scratchCartographic), projectedCenterScratch); - /** - * If true, a region will be clipped if included in any plane in the collection. Otherwise, the region - * to be clipped must intersect the regions defined by all planes in this collection. - * - * @memberof ClippingPlaneCollection.prototype - * @type {Boolean} - * @default true - */ - unionClippingRegions : { - get : function() { - return this._unionClippingRegions; - }, - set : function(value) { - if (this._unionClippingRegions !== value) { - this._unionClippingRegions = value; - this._testIntersection = value ? unionIntersectFunction : defaultIntersectFunction; - } - } - } - }); + var geodeticNormal = ellipsoid.scaleToGeodeticSurface(center, scratchCartesian1); + ellipsoid.geodeticSurfaceNormal(geodeticNormal, geodeticNormal); + var rotation = Quaternion.fromAxisAngle(geodeticNormal, stRotation, quaternionScratch); + var textureMatrix = Matrix3.fromQuaternion(rotation, textureMatrixScratch); - /** - * Adds the specified {@link Plane} to the collection to be used to selectively disable rendering - * on the outside of each plane. Use {@link ClippingPlaneCollection#unionClippingRegions} to modify - * how modify the clipping behavior of multiple planes. - * - * @param {Plane} plane The plane to add to the collection. - * - * @exception {DeveloperError} The plane added exceeds the maximum number of supported clipping planes. - * - * @see ClippingPlaneCollection#unionClippingRegions - * @see ClippingPlaneCollection#remove - * @see ClippingPlaneCollection#removeAll - */ - ClippingPlaneCollection.prototype.add = function(plane) { - if (this.length >= ClippingPlaneCollection.MAX_CLIPPING_PLANES) { - throw new DeveloperError('The maximum number of clipping planes supported is ' + ClippingPlaneCollection.MAX_CLIPPING_PLANES); - } - - this._planes.push(plane); - }; + var minTexCoord = Cartesian2.fromElements(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, scratchMinTexCoord); + var maxTexCoord = Cartesian2.fromElements(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, scratchMaxTexCoord); - /** - * Returns the plane in the collection at the specified index. Indices are zero-based - * and increase as planes are added. Removing a plane shifts all planes after - * it to the left, changing their indices. This function is commonly used with - * {@link ClippingPlaneCollection#length} to iterate over all the planes - * in the collection. - * - * @param {Number} index The zero-based index of the plane. - * @returns {Plane} The plane at the specified index. - * - * @see ClippingPlaneCollection#length - */ - ClippingPlaneCollection.prototype.get = function(index) { - Check.typeOf.number('index', index); - - return this._planes[index]; - }; + var length = positions.length; + var bottomOffset = (extrude) ? length : 0; + var stOffset = bottomOffset / 3 * 2; + for (var i = 0; i < length; i += 3) { + var i1 = i + 1; + var i2 = i + 2; + var position = Cartesian3.fromArray(positions, i, scratchCartesian1); - function indexOf(planes, plane) { - var length = planes.length; - for (var i = 0; i < length; ++i) { - if (Plane.equals(planes[i], plane)) { - return i; - } - } + if (vertexFormat.st) { + var rotatedPoint = Matrix3.multiplyByVector(textureMatrix, position, scratchCartesian2); + var projectedPoint = projection.project(ellipsoid.cartesianToCartographic(rotatedPoint, scratchCartographic), scratchCartesian3); + Cartesian3.subtract(projectedPoint, projectedCenter, projectedPoint); - return -1; - } + texCoordScratch.x = (projectedPoint.x + semiMajorAxis) / (2.0 * semiMajorAxis); + texCoordScratch.y = (projectedPoint.y + semiMinorAxis) / (2.0 * semiMinorAxis); - /** - * Checks whether this collection contains the given plane. - * - * @param {Plane} [plane] The plane to check for. - * @returns {Boolean} true if this collection contains the plane, false otherwise. - * - * @see ClippingPlaneCollection#get - */ - ClippingPlaneCollection.prototype.contains = function(plane) { - return indexOf(this._planes, plane) !== -1; - }; + minTexCoord.x = Math.min(texCoordScratch.x, minTexCoord.x); + minTexCoord.y = Math.min(texCoordScratch.y, minTexCoord.y); + maxTexCoord.x = Math.max(texCoordScratch.x, maxTexCoord.x); + maxTexCoord.y = Math.max(texCoordScratch.y, maxTexCoord.y); - /** - * Removes the first occurrence of the given plane from the collection. - * - * @param {Plane} plane - * @returns {Boolean} <code>true</code> if the plane was removed; <code>false</code> if the plane was not found in the collection. - * - * @see ClippingPlaneCollection#add - * @see ClippingPlaneCollection#contains - * @see ClippingPlaneCollection#removeAll - */ - ClippingPlaneCollection.prototype.remove = function(plane) { - var planes = this._planes; - var index = indexOf(planes, plane); + if (extrude) { + textureCoordinates[textureCoordIndex + stOffset] = texCoordScratch.x; + textureCoordinates[textureCoordIndex + 1 + stOffset] = texCoordScratch.y; + } - if (index === -1) { - return false; - } + textureCoordinates[textureCoordIndex++] = texCoordScratch.x; + textureCoordinates[textureCoordIndex++] = texCoordScratch.y; + } - var length = planes.length - 1; - for (var i = index; i < length; ++i) { - planes[i] = planes[i + 1]; - } - planes.length = length; + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) { + normal = ellipsoid.geodeticSurfaceNormal(position, normal); - return true; - }; + if (shadowVolume) { + extrudeNormals[i + bottomOffset] = -normal.x; + extrudeNormals[i1 + bottomOffset] = -normal.y; + extrudeNormals[i2 + bottomOffset] = -normal.z; + } - /** - * Removes all planes from the collection. - * - * @see ClippingPlaneCollection#add - * @see ClippingPlaneCollection#remove - */ - ClippingPlaneCollection.prototype.removeAll = function() { - this._planes = []; - }; + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { + if (vertexFormat.tangent || vertexFormat.bitangent) { + tangent = Cartesian3.normalize(Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent), tangent); + Matrix3.multiplyByVector(textureMatrix, tangent, tangent); + } + if (vertexFormat.normal) { + normals[i] = normal.x; + normals[i1] = normal.y; + normals[i2] = normal.z; + if (extrude) { + normals[i + bottomOffset] = -normal.x; + normals[i1 + bottomOffset] = -normal.y; + normals[i2 + bottomOffset] = -normal.z; + } + } - var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); - var scratchMatrix = new Matrix4(); - /** - * Applies the transformations to each plane and packs it into an array. - * @private - * - * @param {Matrix4} viewMatrix The 4x4 matrix to transform the plane into eyespace. - * @param {Cartesian4[]} [array] The array into which the planes will be packed. - * @returns {Cartesian4[]} The array of packed planes. - */ - ClippingPlaneCollection.prototype.transformAndPackPlanes = function(viewMatrix, array) { - Check.typeOf.object('viewMatrix', viewMatrix); - - var planes = this._planes; - var length = planes.length; + if (vertexFormat.tangent) { + tangents[i] = tangent.x; + tangents[i1] = tangent.y; + tangents[i2] = tangent.z; + if (extrude) { + tangents[i + bottomOffset] = -tangent.x; + tangents[i1 + bottomOffset] = -tangent.y; + tangents[i2 + bottomOffset] = -tangent.z; + } + } - var index = 0; - if (!defined(array)) { - array = new Array(length); - } else { - index = array.length; - array.length = length; + if (vertexFormat.bitangent) { + bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); + bitangents[i ] = bitangent.x; + bitangents[i1] = bitangent.y; + bitangents[i2] = bitangent.z; + if (extrude) { + bitangents[i + bottomOffset] = bitangent.x; + bitangents[i1 + bottomOffset] = bitangent.y; + bitangents[i2 + bottomOffset] = bitangent.z; + } + } + } + } } - var i; - for (i = index; i < length; ++i) { - array[i] = new Cartesian4(); + if (vertexFormat.st) { + length = textureCoordinates.length; + for (var k = 0; k < length; k += 2) { + textureCoordinates[k] = (textureCoordinates[k] - minTexCoord.x) / (maxTexCoord.x - minTexCoord.x); + textureCoordinates[k + 1] = (textureCoordinates[k + 1] - minTexCoord.y) / (maxTexCoord.y - minTexCoord.y); + } } - var transform = Matrix4.multiply(viewMatrix, this.modelMatrix, scratchMatrix); - - for (i = 0; i < length; ++i) { - var plane = planes[i]; - var packedPlane = array[i]; - - Plane.transform(plane, transform, scratchPlane); + var attributes = new GeometryAttributes(); - Cartesian3.clone(scratchPlane.normal, packedPlane); - packedPlane.w = scratchPlane.distance; + if (vertexFormat.position) { + var finalPositions = EllipseGeometryLibrary.raisePositionsToHeight(positions, options, extrude); + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : finalPositions + }); } - return array; - }; + if (vertexFormat.st) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : textureCoordinates + }); + } - /** - * Duplicates this ClippingPlaneCollection instance. - * - * @param {ClippingPlaneCollection} [result] The object onto which to store the result. - * @returns {ClippingPlaneCollection} The modified result parameter or a new ClippingPlaneCollection instance if one was not provided. - */ - ClippingPlaneCollection.prototype.clone = function(result) { - if (!defined(result)) { - result = new ClippingPlaneCollection(); + if (vertexFormat.normal) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); } - var length = this.length; - var i; - if (result.length !== length) { - var planes = result._planes; - var index = planes.length; + if (vertexFormat.tangent) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } - planes.length = length; - for (i = index; i < length; ++i) { - result._planes[i] = new Plane(Cartesian3.UNIT_X, 0.0); - } + if (vertexFormat.bitangent) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); } - for (i = 0; i < length; ++i) { - Plane.clone(this._planes[i], result._planes[i]); + if (shadowVolume) { + attributes.extrudeDirection = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : extrudeNormals + }); } - result.enabled = this.enabled; - Matrix4.clone(this.modelMatrix, result.modelMatrix); - result.unionClippingRegions = this.unionClippingRegions; - Color.clone(this.edgeColor, result.edgeColor); - result.edgeWidth = this.edgeWidth; + return attributes; + } - return result; - }; + function topIndices(numPts) { + // numTriangles in half = 3 + 8 + 12 + ... = -1 + 4 + (4 + 4) + (4 + 4 + 4) + ... = -1 + 4 * (1 + 2 + 3 + ...) + // = -1 + 4 * ((n * ( n + 1)) / 2) + // total triangles = 2 * numTrangles in half + // indices = total triangles * 3; + // Substitute numPts for n above - /** - * Determines the type intersection with the planes of this ClippingPlaneCollection instance and the specified {@link BoundingVolume}. - * @private - * - * @param {Object} boundingVolume The volume to determine the intersection with the planes. - * @param {Matrix4} [transform] An optional, additional matrix to transform the plane to world coordinates. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire volume is on the side of the planes - * the normal is pointing and should be entirely rendered, {@link Intersect.OUTSIDE} - * if the entire volume is on the opposite side and should be clipped, and - * {@link Intersect.INTERSECTING} if the volume intersects the planes. - */ - ClippingPlaneCollection.prototype.computeIntersectionWithBoundingVolume = function(boundingVolume, transform) { - var planes = this._planes; - var length = planes.length; + var indices = new Array(12 * (numPts * ( numPts + 1)) - 6); + var indicesIndex = 0; + var prevIndex; + var numInterior; + var positionIndex; + var i; + var j; + // Indices triangles to the 'right' of the north vector - var modelMatrix = this.modelMatrix; - if (defined(transform)) { - modelMatrix = Matrix4.multiply(modelMatrix, transform, scratchMatrix); + prevIndex = 0; + positionIndex = 1; + for (i = 0; i < 3; i++) { + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; } - // If the collection is not set to union the clipping regions, the volume must be outside of all planes to be - // considered completely clipped. If the collection is set to union the clipping regions, if the volume can be - // outside any the planes, it is considered completely clipped. - // Lastly, if not completely clipped, if any plane is intersecting, more calculations must be performed. - var intersection = Intersect.INSIDE; - if (!this.unionClippingRegions && length > 0) { - intersection = Intersect.OUTSIDE; - } + for (i = 2; i < numPts + 1; ++i) { + positionIndex = i * (i + 1) - 1; + prevIndex = (i - 1) * i - 1; - for (var i = 0; i < length; ++i) { - var plane = planes[i]; + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; - Plane.transform(plane, modelMatrix, scratchPlane); + numInterior = 2 * i; + for (j = 0; j < numInterior - 1; ++j) { - var value = boundingVolume.intersectPlane(scratchPlane); - if (value === Intersect.INTERSECTING) { - intersection = value; - } else if (this._testIntersection(value)) { - return value; + indices[indicesIndex++] = positionIndex; + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; + + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; } + + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; } - return intersection; - }; + // Indices for center column of triangles + numInterior = numPts * 2; + ++positionIndex; + ++prevIndex; + for (i = 0; i < numInterior - 1; ++i) { + indices[indicesIndex++] = positionIndex; + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; - /** - * The maximum number of supported clipping planes. - * - * @type {number} - * @constant - */ - ClippingPlaneCollection.MAX_CLIPPING_PLANES = 6; + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; + } - return ClippingPlaneCollection; -}); + indices[indicesIndex++] = positionIndex; + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; -define('Core/ClockRange',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; - /** - * Constants used by {@link Clock#tick} to determine behavior - * when {@link Clock#startTime} or {@link Clock#stopTime} is reached. - * - * @exports ClockRange - * - * @see Clock - * @see ClockStep - */ - var ClockRange = { - /** - * {@link Clock#tick} will always advances the clock in its current direction. - * - * @type {Number} - * @constant - */ - UNBOUNDED : 0, + // Reverse the process creating indices to the 'left' of the north vector + ++prevIndex; + for (i = numPts - 1; i > 1; --i) { + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; - /** - * When {@link Clock#startTime} or {@link Clock#stopTime} is reached, - * {@link Clock#tick} will not advance {@link Clock#currentTime} any further. - * - * @type {Number} - * @constant - */ - CLAMPED : 1, + numInterior = 2 * i; + for (j = 0; j < numInterior - 1; ++j) { + indices[indicesIndex++] = positionIndex; + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; - /** - * When {@link Clock#stopTime} is reached, {@link Clock#tick} will advance - * {@link Clock#currentTime} to the opposite end of the interval. When - * time is moving backwards, {@link Clock#tick} will not advance past - * {@link Clock#startTime} - * - * @type {Number} - * @constant - */ - LOOP_STOP : 2 - }; + indices[indicesIndex++] = positionIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; + } - return freezeObject(ClockRange); -}); + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = positionIndex++; + } -define('Core/ClockStep',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + for (i = 0; i < 3; i++) { + indices[indicesIndex++] = prevIndex++; + indices[indicesIndex++] = prevIndex; + indices[indicesIndex++] = positionIndex; + } + return indices; + } - /** - * Constants to determine how much time advances with each call - * to {@link Clock#tick}. - * - * @exports ClockStep - * - * @see Clock - * @see ClockRange - */ - var ClockStep = { - /** - * {@link Clock#tick} advances the current time by a fixed step, - * which is the number of seconds specified by {@link Clock#multiplier}. - * - * @type {Number} - * @constant - */ - TICK_DEPENDENT : 0, + var boundingSphereCenter = new Cartesian3(); - /** - * {@link Clock#tick} advances the current time by the amount of system - * time elapsed since the previous call multiplied by {@link Clock#multiplier}. - * - * @type {Number} - * @constant - */ - SYSTEM_CLOCK_MULTIPLIER : 1, + function computeEllipse(options) { + var center = options.center; + boundingSphereCenter = Cartesian3.multiplyByScalar(options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter), options.height, boundingSphereCenter); + boundingSphereCenter = Cartesian3.add(center, boundingSphereCenter, boundingSphereCenter); + var boundingSphere = new BoundingSphere(boundingSphereCenter, options.semiMajorAxis); + var cep = EllipseGeometryLibrary.computeEllipsePositions(options, true, false); + var positions = cep.positions; + var numPts = cep.numPts; + var attributes = computeTopBottomAttributes(positions, options, false); + var indices = topIndices(numPts); + indices = IndexDatatype.createTypedArray(positions.length / 3, indices); + return { + boundingSphere : boundingSphere, + attributes : attributes, + indices : indices + }; + } - /** - * {@link Clock#tick} sets the clock to the current system time; - * ignoring all other settings. - * - * @type {Number} - * @constant - */ - SYSTEM_CLOCK : 2 - }; + function computeWallAttributes(positions, options) { + var vertexFormat = options.vertexFormat; + var center = options.center; + var semiMajorAxis = options.semiMajorAxis; + var semiMinorAxis = options.semiMinorAxis; + var ellipsoid = options.ellipsoid; + var height = options.height; + var extrudedHeight = options.extrudedHeight; + var stRotation = options.stRotation; + var size = positions.length / 3 * 2; - return freezeObject(ClockStep); -}); + var finalPositions = new Float64Array(size * 3); + var textureCoordinates = (vertexFormat.st) ? new Float32Array(size * 2) : undefined; + var normals = (vertexFormat.normal) ? new Float32Array(size * 3) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(size * 3) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(size * 3) : undefined; -define('Core/getTimestamp',[ - './defined' - ], function( - defined) { - 'use strict'; - /*global performance*/ + var shadowVolume = options.shadowVolume; + var extrudeNormals = (shadowVolume) ? new Float32Array(size * 3) : undefined; - /** - * Gets a timestamp that can be used in measuring the time between events. Timestamps - * are expressed in milliseconds, but it is not specified what the milliseconds are - * measured from. This function uses performance.now() if it is available, or Date.now() - * otherwise. - * - * @exports getTimestamp - * - * @returns {Number} The timestamp in milliseconds since some unspecified reference time. - */ - var getTimestamp; + var textureCoordIndex = 0; - if (typeof performance !== 'undefined' && defined(performance.now)) { - getTimestamp = function() { - return performance.now(); - }; - } else { - getTimestamp = function() { - return Date.now(); - }; - } + // Raise positions to a height above the ellipsoid and compute the + // texture coordinates, normals, tangents, and bitangents. + var normal = scratchNormal; + var tangent = scratchTangent; + var bitangent = scratchBitangent; - return getTimestamp; -}); + var projection = new GeographicProjection(ellipsoid); + var projectedCenter = projection.project(ellipsoid.cartesianToCartographic(center, scratchCartographic), projectedCenterScratch); -define('Core/Clock',[ - './ClockRange', - './ClockStep', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Event', - './getTimestamp', - './JulianDate' - ], function( - ClockRange, - ClockStep, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - getTimestamp, - JulianDate) { - 'use strict'; + var geodeticNormal = ellipsoid.scaleToGeodeticSurface(center, scratchCartesian1); + ellipsoid.geodeticSurfaceNormal(geodeticNormal, geodeticNormal); + var rotation = Quaternion.fromAxisAngle(geodeticNormal, stRotation, quaternionScratch); + var textureMatrix = Matrix3.fromQuaternion(rotation, textureMatrixScratch); - /** - * A simple clock for keeping track of simulated time. - * - * @alias Clock - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {JulianDate} [options.startTime] The start time of the clock. - * @param {JulianDate} [options.stopTime] The stop time of the clock. - * @param {JulianDate} [options.currentTime] The current time. - * @param {Number} [options.multiplier=1.0] Determines how much time advances when {@link Clock#tick} is called, negative values allow for advancing backwards. - * @param {ClockStep} [options.clockStep=ClockStep.SYSTEM_CLOCK_MULTIPLIER] Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent. - * @param {ClockRange} [options.clockRange=ClockRange.UNBOUNDED] Determines how the clock should behave when {@link Clock#startTime} or {@link Clock#stopTime} is reached. - * @param {Boolean} [options.canAnimate=true] Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, for example. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. - * @param {Boolean} [options.shouldAnimate=true] Indicates whether {@link Clock#tick} should attempt to advance time. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. - * - * @exception {DeveloperError} startTime must come before stopTime. - * - * - * @example - * // Create a clock that loops on Christmas day 2013 and runs in real-time. - * var clock = new Cesium.Clock({ - * startTime : Cesium.JulianDate.fromIso8601("2013-12-25"), - * currentTime : Cesium.JulianDate.fromIso8601("2013-12-25"), - * stopTime : Cesium.JulianDate.fromIso8601("2013-12-26"), - * clockRange : Cesium.ClockRange.LOOP_STOP, - * clockStep : Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER - * }); - * - * @see ClockStep - * @see ClockRange - * @see JulianDate - */ - function Clock(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var minTexCoord = Cartesian2.fromElements(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, scratchMinTexCoord); + var maxTexCoord = Cartesian2.fromElements(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, scratchMaxTexCoord); - var currentTime = options.currentTime; - var startTime = options.startTime; - var stopTime = options.stopTime; + var length = positions.length; + var stOffset = length / 3 * 2; + for (var i = 0; i < length; i += 3) { + var i1 = i + 1; + var i2 = i + 2; + var position = Cartesian3.fromArray(positions, i, scratchCartesian1); + var extrudedPosition; - if (!defined(currentTime)) { - // if not specified, current time is the start time, - // or if that is not specified, 1 day before the stop time, - // or if that is not specified, then now. - if (defined(startTime)) { - currentTime = JulianDate.clone(startTime); - } else if (defined(stopTime)) { - currentTime = JulianDate.addDays(stopTime, -1.0, new JulianDate()); - } else { - currentTime = JulianDate.now(); - } - } else { - currentTime = JulianDate.clone(currentTime); - } + if (vertexFormat.st) { + var rotatedPoint = Matrix3.multiplyByVector(textureMatrix, position, scratchCartesian2); + var projectedPoint = projection.project(ellipsoid.cartesianToCartographic(rotatedPoint, scratchCartographic), scratchCartesian3); + Cartesian3.subtract(projectedPoint, projectedCenter, projectedPoint); - if (!defined(startTime)) { - // if not specified, start time is the current time - // (as determined above) - startTime = JulianDate.clone(currentTime); - } else { - startTime = JulianDate.clone(startTime); - } + texCoordScratch.x = (projectedPoint.x + semiMajorAxis) / (2.0 * semiMajorAxis); + texCoordScratch.y = (projectedPoint.y + semiMinorAxis) / (2.0 * semiMinorAxis); - if (!defined(stopTime)) { - // if not specified, stop time is 1 day after the start time - // (as determined above) - stopTime = JulianDate.addDays(startTime, 1.0, new JulianDate()); - } else { - stopTime = JulianDate.clone(stopTime); - } + minTexCoord.x = Math.min(texCoordScratch.x, minTexCoord.x); + minTexCoord.y = Math.min(texCoordScratch.y, minTexCoord.y); + maxTexCoord.x = Math.max(texCoordScratch.x, maxTexCoord.x); + maxTexCoord.y = Math.max(texCoordScratch.y, maxTexCoord.y); - if (JulianDate.greaterThan(startTime, stopTime)) { - throw new DeveloperError('startTime must come before stopTime.'); - } - - /** - * The start time of the clock. - * @type {JulianDate} - */ - this.startTime = startTime; + textureCoordinates[textureCoordIndex + stOffset] = texCoordScratch.x; + textureCoordinates[textureCoordIndex + 1 + stOffset] = texCoordScratch.y; - /** - * The stop time of the clock. - * @type {JulianDate} - */ - this.stopTime = stopTime; + textureCoordinates[textureCoordIndex++] = texCoordScratch.x; + textureCoordinates[textureCoordIndex++] = texCoordScratch.y; + } - /** - * Determines how the clock should behave when - * {@link Clock#startTime} or {@link Clock#stopTime} - * is reached. - * @type {ClockRange} - * @default {@link ClockRange.UNBOUNDED} - */ - this.clockRange = defaultValue(options.clockRange, ClockRange.UNBOUNDED); + position = ellipsoid.scaleToGeodeticSurface(position, position); + extrudedPosition = Cartesian3.clone(position, scratchCartesian2); + normal = ellipsoid.geodeticSurfaceNormal(position, normal); - /** - * Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, - * for example. The clock will only advance time when both - * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. - * @type {Boolean} - * @default true - */ - this.canAnimate = defaultValue(options.canAnimate, true); + if (shadowVolume) { + extrudeNormals[i + length] = -normal.x; + extrudeNormals[i1 + length] = -normal.y; + extrudeNormals[i2 + length] = -normal.z; + } - /** - * An {@link Event} that is fired whenever {@link Clock#tick} is called. - * @type {Event} - */ - this.onTick = new Event(); + var scaledNormal = Cartesian3.multiplyByScalar(normal, height, scratchCartesian4); + position = Cartesian3.add(position, scaledNormal, position); + scaledNormal = Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal); + extrudedPosition = Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition); - this._currentTime = undefined; - this._multiplier = undefined; - this._clockStep = undefined; - this._shouldAnimate = undefined; - this._lastSystemTime = getTimestamp(); + if (vertexFormat.position) { + finalPositions[i + length] = extrudedPosition.x; + finalPositions[i1 + length] = extrudedPosition.y; + finalPositions[i2 + length] = extrudedPosition.z; - // set values using the property setters to - // make values consistent. + finalPositions[i] = position.x; + finalPositions[i1] = position.y; + finalPositions[i2] = position.z; + } - this.currentTime = currentTime; - this.multiplier = defaultValue(options.multiplier, 1.0); - this.clockStep = defaultValue(options.clockStep, ClockStep.SYSTEM_CLOCK_MULTIPLIER); - this.shouldAnimate = defaultValue(options.shouldAnimate, true); - } + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - defineProperties(Clock.prototype, { - /** - * The current time. - * Changing this property will change - * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to - * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. - * @memberof Clock.prototype - * @type {JulianDate} - */ - currentTime : { - get : function() { - return this._currentTime; - }, - set : function(value) { - if (JulianDate.equals(this._currentTime, value)) { - return; - } + bitangent = Cartesian3.clone(normal, bitangent); + var next = Cartesian3.fromArray(positions, (i + 3) % length, scratchCartesian4); + Cartesian3.subtract(next, position, next); + var bottom = Cartesian3.subtract(extrudedPosition, position, scratchCartesian3); - if (this._clockStep === ClockStep.SYSTEM_CLOCK) { - this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; - } + normal = Cartesian3.normalize(Cartesian3.cross(bottom, next, normal), normal); - this._currentTime = value; - } - }, + if (vertexFormat.normal) { + normals[i] = normal.x; + normals[i1] = normal.y; + normals[i2] = normal.z; - /** - * Gets or sets how much time advances when {@link Clock#tick} is called. Negative values allow for advancing backwards. - * If {@link Clock#clockStep} is set to {@link ClockStep.TICK_DEPENDENT}, this is the number of seconds to advance. - * If {@link Clock#clockStep} is set to {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}, this value is multiplied by the - * elapsed system time since the last call to {@link Clock#tick}. - * Changing this property will change - * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to - * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. - * @memberof Clock.prototype - * @type {Number} - * @default 1.0 - */ - multiplier : { - get : function() { - return this._multiplier; - }, - set : function(value) { - if (this._multiplier === value) { - return; + normals[i + length] = normal.x; + normals[i1 + length] = normal.y; + normals[i2 + length] = normal.z; } - if (this._clockStep === ClockStep.SYSTEM_CLOCK) { - this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; + if (vertexFormat.tangent) { + tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); + tangents[i] = tangent.x; + tangents[i1] = tangent.y; + tangents[i2] = tangent.z; + + tangents[i + length] = tangent.x; + tangents[i + 1 + length] = tangent.y; + tangents[i + 2 + length] = tangent.z; } - this._multiplier = value; - } - }, + if (vertexFormat.bitangent) { + bitangents[i ] = bitangent.x; + bitangents[i1] = bitangent.y; + bitangents[i2] = bitangent.z; - /** - * Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent. - * Changing this property to {@link ClockStep.SYSTEM_CLOCK} will set - * {@link Clock#multiplier} to 1.0, {@link Clock#shouldAnimate} to true, and - * {@link Clock#currentTime} to the current system clock time. - * @memberof Clock.prototype - * @type ClockStep - * @default {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER} - */ - clockStep : { - get : function() { - return this._clockStep; - }, - set : function(value) { - if (value === ClockStep.SYSTEM_CLOCK) { - this._multiplier = 1.0; - this._shouldAnimate = true; - this._currentTime = JulianDate.now(); + bitangents[i + length] = bitangent.x; + bitangents[i1 + length] = bitangent.y; + bitangents[i2 + length] = bitangent.z; } + } + } - this._clockStep = value; + if (vertexFormat.st) { + length = textureCoordinates.length; + for (var k = 0; k < length; k += 2) { + textureCoordinates[k] = (textureCoordinates[k] - minTexCoord.x) / (maxTexCoord.x - minTexCoord.x); + textureCoordinates[k + 1] = (textureCoordinates[k + 1] - minTexCoord.y) / (maxTexCoord.y - minTexCoord.y); } - }, + } + var attributes = new GeometryAttributes(); - /** - * Indicates whether {@link Clock#tick} should attempt to advance time. - * The clock will only advance time when both - * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. - * Changing this property will change - * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to - * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. - * @memberof Clock.prototype - * @type {Boolean} - * @default true - */ - shouldAnimate : { - get : function() { - return this._shouldAnimate; - }, - set : function(value) { - if (this._shouldAnimate === value) { - return; - } + if (vertexFormat.position) { + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : finalPositions + }); + } - if (this._clockStep === ClockStep.SYSTEM_CLOCK) { - this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; - } + if (vertexFormat.st) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : textureCoordinates + }); + } - this._shouldAnimate = value; - } + if (vertexFormat.normal) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); } - }); - /** - * Advances the clock from the current time based on the current configuration options. - * tick should be called every frame, regardless of whether animation is taking place - * or not. To control animation, use the {@link Clock#shouldAnimate} property. - * - * @returns {JulianDate} The new value of the {@link Clock#currentTime} property. - */ - Clock.prototype.tick = function() { - var currentSystemTime = getTimestamp(); - var currentTime = JulianDate.clone(this._currentTime); + if (vertexFormat.tangent) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } - if (this.canAnimate && this._shouldAnimate) { - var clockStep = this._clockStep; - if (clockStep === ClockStep.SYSTEM_CLOCK) { - currentTime = JulianDate.now(currentTime); - } else { - var multiplier = this._multiplier; + if (vertexFormat.bitangent) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } - if (clockStep === ClockStep.TICK_DEPENDENT) { - currentTime = JulianDate.addSeconds(currentTime, multiplier, currentTime); - } else { - var milliseconds = currentSystemTime - this._lastSystemTime; - currentTime = JulianDate.addSeconds(currentTime, multiplier * (milliseconds / 1000.0), currentTime); - } + if (shadowVolume) { + attributes.extrudeDirection = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : extrudeNormals + }); + } - var clockRange = this.clockRange; - var startTime = this.startTime; - var stopTime = this.stopTime; + return attributes; + } - if (clockRange === ClockRange.CLAMPED) { - if (JulianDate.lessThan(currentTime, startTime)) { - currentTime = JulianDate.clone(startTime, currentTime); - } else if (JulianDate.greaterThan(currentTime, stopTime)) { - currentTime = JulianDate.clone(stopTime, currentTime); - } - } else if (clockRange === ClockRange.LOOP_STOP) { - if (JulianDate.lessThan(currentTime, startTime)) { - currentTime = JulianDate.clone(startTime, currentTime); - } - while (JulianDate.greaterThan(currentTime, stopTime)) { - currentTime = JulianDate.addSeconds(startTime, JulianDate.secondsDifference(currentTime, stopTime), currentTime); - } - } - } + function computeWallIndices(positions) { + var length = positions.length / 3; + var indices = IndexDatatype.createTypedArray(length, length * 6); + var index = 0; + for (var i = 0; i < length; i++) { + var UL = i; + var LL = i + length; + var UR = (UL + 1) % length; + var LR = UR + length; + indices[index++] = UL; + indices[index++] = LL; + indices[index++] = UR; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; } - this._currentTime = currentTime; - this._lastSystemTime = currentSystemTime; - this.onTick.raiseEvent(this); - return currentTime; - }; + return indices; + } - return Clock; -}); + var topBoundingSphere = new BoundingSphere(); + var bottomBoundingSphere = new BoundingSphere(); -define('Core/ColorGeometryInstanceAttribute',[ - './Color', - './ComponentDatatype', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError' - ], function( - Color, - ComponentDatatype, - defaultValue, - defined, - defineProperties, - DeveloperError) { - 'use strict'; + function computeExtrudedEllipse(options) { + var center = options.center; + var ellipsoid = options.ellipsoid; + var semiMajorAxis = options.semiMajorAxis; + var scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1), options.height, scratchCartesian1); + topBoundingSphere.center = Cartesian3.add(center, scaledNormal, topBoundingSphere.center); + topBoundingSphere.radius = semiMajorAxis; - /** - * Value and type information for per-instance geometry color. - * - * @alias ColorGeometryInstanceAttribute - * @constructor - * - * @param {Number} [red=1.0] The red component. - * @param {Number} [green=1.0] The green component. - * @param {Number} [blue=1.0] The blue component. - * @param {Number} [alpha=1.0] The alpha component. - * - * - * @example - * var instance = new Cesium.GeometryInstance({ - * geometry : Cesium.BoxGeometry.fromDimensions({ - * dimensions : new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0) - * }), - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(0.0, 0.0)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), - * id : 'box', - * attributes : { - * color : new Cesium.ColorGeometryInstanceAttribute(red, green, blue, alpha) - * } - * }); - * - * @see GeometryInstance - * @see GeometryInstanceAttribute - */ - function ColorGeometryInstanceAttribute(red, green, blue, alpha) { - red = defaultValue(red, 1.0); - green = defaultValue(green, 1.0); - blue = defaultValue(blue, 1.0); - alpha = defaultValue(alpha, 1.0); + scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scaledNormal), options.extrudedHeight, scaledNormal); + bottomBoundingSphere.center = Cartesian3.add(center, scaledNormal, bottomBoundingSphere.center); + bottomBoundingSphere.radius = semiMajorAxis; - /** - * The values for the attributes stored in a typed array. - * - * @type Uint8Array - * - * @default [255, 255, 255, 255] - */ - this.value = new Uint8Array([ - Color.floatToByte(red), - Color.floatToByte(green), - Color.floatToByte(blue), - Color.floatToByte(alpha) - ]); - } + var cep = EllipseGeometryLibrary.computeEllipsePositions(options, true, true); + var positions = cep.positions; + var numPts = cep.numPts; + var outerPositions = cep.outerPositions; + var boundingSphere = BoundingSphere.union(topBoundingSphere, bottomBoundingSphere); + var topBottomAttributes = computeTopBottomAttributes(positions, options, true); + var indices = topIndices(numPts); + var length = indices.length; + indices.length = length * 2; + var posLength = positions.length / 3; + for (var i = 0; i < length; i += 3) { + indices[i + length] = indices[i + 2] + posLength; + indices[i + 1 + length] = indices[i + 1] + posLength; + indices[i + 2 + length] = indices[i] + posLength; + } - defineProperties(ColorGeometryInstanceAttribute.prototype, { - /** - * The datatype of each component in the attribute, e.g., individual elements in - * {@link ColorGeometryInstanceAttribute#value}. - * - * @memberof ColorGeometryInstanceAttribute.prototype - * - * @type {ComponentDatatype} - * @readonly - * - * @default {@link ComponentDatatype.UNSIGNED_BYTE} - */ - componentDatatype : { - get : function() { - return ComponentDatatype.UNSIGNED_BYTE; - } - }, + var topBottomIndices = IndexDatatype.createTypedArray(posLength * 2 / 3, indices); - /** - * The number of components in the attributes, i.e., {@link ColorGeometryInstanceAttribute#value}. - * - * @memberof ColorGeometryInstanceAttribute.prototype - * - * @type {Number} - * @readonly - * - * @default 4 - */ - componentsPerAttribute : { - get : function() { - return 4; - } - }, + var topBottomGeo = new Geometry({ + attributes : topBottomAttributes, + indices : topBottomIndices, + primitiveType : PrimitiveType.TRIANGLES + }); - /** - * When <code>true</code> and <code>componentDatatype</code> is an integer format, - * indicate that the components should be mapped to the range [0, 1] (unsigned) - * or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * - * @memberof ColorGeometryInstanceAttribute.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - normalize : { - get : function() { - return true; - } + var wallAttributes = computeWallAttributes(outerPositions, options); + indices = computeWallIndices(outerPositions); + var wallIndices = IndexDatatype.createTypedArray(outerPositions.length * 2 / 3, indices); + + var wallGeo = new Geometry({ + attributes : wallAttributes, + indices : wallIndices, + primitiveType : PrimitiveType.TRIANGLES + }); + + var geo = GeometryPipeline.combineInstances([ + new GeometryInstance({ + geometry : topBottomGeo + }), + new GeometryInstance({ + geometry : wallGeo + }) + ]); + + return { + boundingSphere : boundingSphere, + attributes : geo[0].attributes, + indices : geo[0].indices + }; + } + + var scratchEnuToFixedMatrix = new Matrix4(); + var scratchFixedToEnuMatrix = new Matrix4(); + var scratchRotationMatrix = new Matrix3(); + var scratchRectanglePoints = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; + var scratchCartographicPoints = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; + + function computeRectangle(center, ellipsoid, semiMajorAxis, semiMinorAxis, rotation) { + Transforms.eastNorthUpToFixedFrame(center, ellipsoid, scratchEnuToFixedMatrix); + Matrix4.inverseTransformation(scratchEnuToFixedMatrix, scratchFixedToEnuMatrix); + + // Find the 4 extreme points of the ellipse in ENU + var i; + for (i = 0; i < 4; ++i) { + Cartesian3.clone(Cartesian3.ZERO, scratchRectanglePoints[i]); + } + scratchRectanglePoints[0].x += semiMajorAxis; + scratchRectanglePoints[1].x -= semiMajorAxis; + scratchRectanglePoints[2].y += semiMinorAxis; + scratchRectanglePoints[3].y -= semiMinorAxis; + + Matrix3.fromRotationZ(rotation, scratchRotationMatrix); + for (i = 0; i < 4; ++i) { + // Apply the rotation + Matrix3.multiplyByVector(scratchRotationMatrix, scratchRectanglePoints[i], scratchRectanglePoints[i]); + + // Convert back to fixed and then to cartographic + Matrix4.multiplyByPoint(scratchEnuToFixedMatrix, scratchRectanglePoints[i], scratchRectanglePoints[i]); + ellipsoid.cartesianToCartographic(scratchRectanglePoints[i], scratchCartographicPoints[i]); } - }); + + return Rectangle.fromCartographicArray(scratchCartographicPoints); + } /** - * Creates a new {@link ColorGeometryInstanceAttribute} instance given the provided {@link Color}. + * A description of an ellipse on an ellipsoid. Ellipse geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * + * @alias EllipseGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. + * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. + * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. + * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. + * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. + * @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north. + * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates counter-clockwise from north. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * + * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero. + * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis. + * @exception {DeveloperError} granularity must be greater than zero. * - * @param {Color} color The color. - * @returns {ColorGeometryInstanceAttribute} The new {@link ColorGeometryInstanceAttribute} instance. * * @example - * var instance = new Cesium.GeometryInstance({ - * geometry : geometry, - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CORNFLOWERBLUE), - * } + * // Create an ellipse. + * var ellipse = new Cesium.EllipseGeometry({ + * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), + * semiMajorAxis : 500000.0, + * semiMinorAxis : 300000.0, + * rotation : Cesium.Math.toRadians(60.0) * }); + * var geometry = Cesium.EllipseGeometry.createGeometry(ellipse); + * + * @see EllipseGeometry.createGeometry */ - ColorGeometryInstanceAttribute.fromColor = function(color) { - if (!defined(color)) { - throw new DeveloperError('color is required.'); + function EllipseGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var center = options.center; + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var semiMajorAxis = options.semiMajorAxis; + var semiMinorAxis = options.semiMinorAxis; + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var height = defaultValue(options.height, 0.0); + var extrudedHeight = options.extrudedHeight; + var extrude = (defined(extrudedHeight) && Math.abs(height - extrudedHeight) > 1.0); + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + + if (!defined(center)) { + throw new DeveloperError('center is required.'); + } + if (!defined(semiMajorAxis)) { + throw new DeveloperError('semiMajorAxis is required.'); + } + if (!defined(semiMinorAxis)) { + throw new DeveloperError('semiMinorAxis is required.'); + } + if (semiMajorAxis < semiMinorAxis) { + throw new DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.'); + } + if (granularity <= 0.0) { + throw new DeveloperError('granularity must be greater than zero.'); } - return new ColorGeometryInstanceAttribute(color.red, color.green, color.blue, color.alpha); - }; + this._center = Cartesian3.clone(center); + this._semiMajorAxis = semiMajorAxis; + this._semiMinorAxis = semiMinorAxis; + this._ellipsoid = Ellipsoid.clone(ellipsoid); + this._rotation = defaultValue(options.rotation, 0.0); + this._stRotation = defaultValue(options.stRotation, 0.0); + this._height = height; + this._granularity = granularity; + this._vertexFormat = VertexFormat.clone(vertexFormat); + this._extrudedHeight = defaultValue(extrudedHeight, height); + this._extrude = extrude; + this._shadowVolume = defaultValue(options.shadowVolume, false); + this._workerName = 'createEllipseGeometry'; + + this._rectangle = computeRectangle(this._center, this._ellipsoid, semiMajorAxis, semiMinorAxis, this._rotation); + } /** - * Converts a color to a typed array that can be used to assign a color attribute. - * - * @param {Color} color The color. - * @param {Uint8Array} [result] The array to store the result in, if undefined a new instance will be created. + * The number of elements used to pack the object into an array. + * @type {Number} + */ + EllipseGeometry.packedLength = Cartesian3.packedLength + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 9; + + /** + * Stores the provided instance into the provided array. * - * @returns {Uint8Array} The modified result parameter or a new instance if result was undefined. + * @param {EllipseGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @example - * var attributes = primitive.getGeometryInstanceAttributes('an id'); - * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA, attributes.color); + * @returns {Number[]} The array that was packed into */ - ColorGeometryInstanceAttribute.toValue = function(color, result) { - if (!defined(color)) { - throw new DeveloperError('color is required.'); + EllipseGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); } - - if (!defined(result)) { - return new Uint8Array(color.toBytes()); + if (!defined(array)) { + throw new DeveloperError('array is required'); } - return color.toBytes(result); + + startingIndex = defaultValue(startingIndex, 0); + + Cartesian3.pack(value._center, array, startingIndex); + startingIndex += Cartesian3.packedLength; + + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; + + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + + Rectangle.pack(value._rectangle, array, startingIndex); + startingIndex += Rectangle.packedLength; + + array[startingIndex++] = value._semiMajorAxis; + array[startingIndex++] = value._semiMinorAxis; + array[startingIndex++] = value._rotation; + array[startingIndex++] = value._stRotation; + array[startingIndex++] = value._height; + array[startingIndex++] = value._granularity; + array[startingIndex++] = value._extrudedHeight; + array[startingIndex++] = value._extrude ? 1.0 : 0.0; + array[startingIndex] = value._shadowVolume ? 1.0 : 0.0; + + return array; + }; + + var scratchCenter = new Cartesian3(); + var scratchEllipsoid = new Ellipsoid(); + var scratchVertexFormat = new VertexFormat(); + var scratchRectangle = new Rectangle(); + var scratchOptions = { + center : scratchCenter, + ellipsoid : scratchEllipsoid, + vertexFormat : scratchVertexFormat, + semiMajorAxis : undefined, + semiMinorAxis : undefined, + rotation : undefined, + stRotation : undefined, + height : undefined, + granularity : undefined, + extrudedHeight : undefined, + shadowVolume: undefined }; /** - * Compares the provided ColorGeometryInstanceAttributes and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Retrieves an instance from a packed array. * - * @param {ColorGeometryInstanceAttribute} [left] The first ColorGeometryInstanceAttribute. - * @param {ColorGeometryInstanceAttribute} [right] The second ColorGeometryInstanceAttribute. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {EllipseGeometry} [result] The object into which to store the result. + * @returns {EllipseGeometry} The modified result parameter or a new EllipseGeometry instance if one was not provided. */ - ColorGeometryInstanceAttribute.equals = function(left, right) { - return (left === right) || - (defined(left) && - defined(right) && - left.value[0] === right.value[0] && - left.value[1] === right.value[1] && - left.value[2] === right.value[2] && - left.value[3] === right.value[3]); - }; + EllipseGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - return ColorGeometryInstanceAttribute; -}); + var center = Cartesian3.unpack(array, startingIndex, scratchCenter); + startingIndex += Cartesian3.packedLength; -define('Core/CompressedTextureBuffer',[ - './defined', - './defineProperties' - ], function( - defined, - defineProperties) { - 'use strict'; + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - /** - * Describes a compressed texture and contains a compressed texture buffer. - * - * @param {PixelFormat} internalFormat The pixel format of the compressed texture. - * @param {Number} width The width of the texture. - * @param {Number} height The height of the texture. - * @param {Uint8Array} buffer The compressed texture buffer. - */ - function CompressedTextureBuffer(internalFormat, width, height, buffer) { - this._format = internalFormat; - this._width = width; - this._height = height; - this._buffer = buffer; - } + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; - defineProperties(CompressedTextureBuffer.prototype, { - /** - * The format of the compressed texture. - * @type PixelFormat - * @readonly - */ - internalFormat : { - get : function() { - return this._format; - } - }, - /** - * The width of the texture. - * @type Number - * @readonly - */ - width : { - get : function() { - return this._width; - } - }, - /** - * The height of the texture. - * @type Number - * @readonly - */ - height : { - get : function() { - return this._height; - } - }, - /** - * The compressed texture buffer. - * @type Uint8Array - * @readonly - */ - bufferView : { - get : function() { - return this._buffer; - } - } - }); + var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); + startingIndex += Rectangle.packedLength; - /** - * Creates a shallow clone of a compressed texture buffer. - * - * @param {CompressedTextureBuffer} object The compressed texture buffer to be cloned. - * @return {CompressedTextureBuffer} A shallow clone of the compressed texture buffer. - */ - CompressedTextureBuffer.clone = function(object) { - if (!defined(object)) { - return undefined; + var semiMajorAxis = array[startingIndex++]; + var semiMinorAxis = array[startingIndex++]; + var rotation = array[startingIndex++]; + var stRotation = array[startingIndex++]; + var height = array[startingIndex++]; + var granularity = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var extrude = array[startingIndex++] === 1.0; + var shadowVolume = array[startingIndex] === 1.0; + + if (!defined(result)) { + scratchOptions.height = height; + scratchOptions.extrudedHeight = extrudedHeight; + scratchOptions.granularity = granularity; + scratchOptions.stRotation = stRotation; + scratchOptions.rotation = rotation; + scratchOptions.semiMajorAxis = semiMajorAxis; + scratchOptions.semiMinorAxis = semiMinorAxis; + scratchOptions.shadowVolume = shadowVolume; + return new EllipseGeometry(scratchOptions); } - return new CompressedTextureBuffer(object._format, object._width, object._height, object._buffer); + result._center = Cartesian3.clone(center, result._center); + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._semiMajorAxis = semiMajorAxis; + result._semiMinorAxis = semiMinorAxis; + result._rotation = rotation; + result._stRotation = stRotation; + result._height = height; + result._granularity = granularity; + result._extrudedHeight = extrudedHeight; + result._extrude = extrude; + result._shadowVolume = shadowVolume; + result._rectangle = Rectangle.clone(rectangle); + + return result; }; /** - * Creates a shallow clone of this compressed texture buffer. + * Computes the geometric representation of a ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere. * - * @return {CompressedTextureBuffer} A shallow clone of the compressed texture buffer. + * @param {EllipseGeometry} ellipseGeometry A description of the ellipse. + * @returns {Geometry|undefined} The computed vertices and indices. */ - CompressedTextureBuffer.prototype.clone = function() { - return CompressedTextureBuffer.clone(this); - }; + EllipseGeometry.createGeometry = function(ellipseGeometry) { + if ((ellipseGeometry._semiMajorAxis <= 0.0) || (ellipseGeometry._semiMinorAxis <= 0.0)) { + return; + } - return CompressedTextureBuffer; -}); + ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(ellipseGeometry._center, ellipseGeometry._center); + var options = { + center : ellipseGeometry._center, + semiMajorAxis : ellipseGeometry._semiMajorAxis, + semiMinorAxis : ellipseGeometry._semiMinorAxis, + ellipsoid : ellipseGeometry._ellipsoid, + rotation : ellipseGeometry._rotation, + height : ellipseGeometry._height, + extrudedHeight : ellipseGeometry._extrudedHeight, + granularity : ellipseGeometry._granularity, + vertexFormat : ellipseGeometry._vertexFormat, + stRotation : ellipseGeometry._stRotation + }; + var geometry; + if (ellipseGeometry._extrude) { + options.extrudedHeight = Math.min(ellipseGeometry._extrudedHeight, ellipseGeometry._height); + options.height = Math.max(ellipseGeometry._extrudedHeight, ellipseGeometry._height); + options.shadowVolume = ellipseGeometry._shadowVolume; + geometry = computeExtrudedEllipse(options); + } else { + geometry = computeEllipse(options); + } -define('Core/CornerType',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + return new Geometry({ + attributes : geometry.attributes, + indices : geometry.indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : geometry.boundingSphere + }); + }; /** - * Style options for corners. - * - * @demo The {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} - * demonstrates the three corner types, as used by {@link CorridorGraphics}. - * - * @exports CornerType + * @private */ - var CornerType = { - /** - * <img src="Images/CornerTypeRounded.png" style="vertical-align: middle;" width="186" height="189" /> - * - * Corner has a smooth edge. - * @type {Number} - * @constant - */ - ROUNDED : 0, + EllipseGeometry.createShadowVolume = function(ellipseGeometry, minHeightFunc, maxHeightFunc) { + var granularity = ellipseGeometry._granularity; + var ellipsoid = ellipseGeometry._ellipsoid; - /** - * <img src="Images/CornerTypeMitered.png" style="vertical-align: middle;" width="186" height="189" /> - * - * Corner point is the intersection of adjacent edges. - * @type {Number} - * @constant - */ - MITERED : 1, + var minHeight = minHeightFunc(granularity, ellipsoid); + var maxHeight = maxHeightFunc(granularity, ellipsoid); + + return new EllipseGeometry({ + center : ellipseGeometry._center, + semiMajorAxis : ellipseGeometry._semiMajorAxis, + semiMinorAxis : ellipseGeometry._semiMinorAxis, + ellipsoid : ellipsoid, + rotation : ellipseGeometry._rotation, + stRotation : ellipseGeometry._stRotation, + granularity : granularity, + extrudedHeight : minHeight, + height : maxHeight, + vertexFormat : VertexFormat.POSITION_ONLY, + shadowVolume: true + }); + }; + defineProperties(EllipseGeometry.prototype, { /** - * <img src="Images/CornerTypeBeveled.png" style="vertical-align: middle;" width="186" height="189" /> - * - * Corner is clipped. - * @type {Number} - * @constant + * @private */ - BEVELED : 2 - }; + rectangle : { + get : function() { + return this._rectangle; + } + } + }); - return freezeObject(CornerType); + return EllipseGeometry; }); -define('Core/EllipsoidGeodesic',[ +define('Core/CircleGeometry',[ './Cartesian3', - './Cartographic', './Check', './defaultValue', './defined', './defineProperties', + './EllipseGeometry', './Ellipsoid', - './Math' + './VertexFormat' ], function( Cartesian3, - Cartographic, Check, defaultValue, defined, defineProperties, + EllipseGeometry, Ellipsoid, - CesiumMath) { + VertexFormat) { 'use strict'; - function setConstants(ellipsoidGeodesic) { - var uSquared = ellipsoidGeodesic._uSquared; - var a = ellipsoidGeodesic._ellipsoid.maximumRadius; - var b = ellipsoidGeodesic._ellipsoid.minimumRadius; - var f = (a - b) / a; - - var cosineHeading = Math.cos(ellipsoidGeodesic._startHeading); - var sineHeading = Math.sin(ellipsoidGeodesic._startHeading); - - var tanU = (1 - f) * Math.tan(ellipsoidGeodesic._start.latitude); - - var cosineU = 1.0 / Math.sqrt(1.0 + tanU * tanU); - var sineU = cosineU * tanU; - - var sigma = Math.atan2(tanU, cosineHeading); - - var sineAlpha = cosineU * sineHeading; - var sineSquaredAlpha = sineAlpha * sineAlpha; - - var cosineSquaredAlpha = 1.0 - sineSquaredAlpha; - var cosineAlpha = Math.sqrt(cosineSquaredAlpha); - - var u2Over4 = uSquared / 4.0; - var u4Over16 = u2Over4 * u2Over4; - var u6Over64 = u4Over16 * u2Over4; - var u8Over256 = u4Over16 * u4Over16; - - var a0 = (1.0 + u2Over4 - 3.0 * u4Over16 / 4.0 + 5.0 * u6Over64 / 4.0 - 175.0 * u8Over256 / 64.0); - var a1 = (1.0 - u2Over4 + 15.0 * u4Over16 / 8.0 - 35.0 * u6Over64 / 8.0); - var a2 = (1.0 - 3.0 * u2Over4 + 35.0 * u4Over16 / 4.0); - var a3 = (1.0 - 5.0 * u2Over4); - - var distanceRatio = a0 * sigma - a1 * Math.sin(2.0 * sigma) * u2Over4 / 2.0 - a2 * Math.sin(4.0 * sigma) * u4Over16 / 16.0 - - a3 * Math.sin(6.0 * sigma) * u6Over64 / 48.0 - Math.sin(8.0 * sigma) * 5.0 * u8Over256 / 512; - - var constants = ellipsoidGeodesic._constants; - - constants.a = a; - constants.b = b; - constants.f = f; - constants.cosineHeading = cosineHeading; - constants.sineHeading = sineHeading; - constants.tanU = tanU; - constants.cosineU = cosineU; - constants.sineU = sineU; - constants.sigma = sigma; - constants.sineAlpha = sineAlpha; - constants.sineSquaredAlpha = sineSquaredAlpha; - constants.cosineSquaredAlpha = cosineSquaredAlpha; - constants.cosineAlpha = cosineAlpha; - constants.u2Over4 = u2Over4; - constants.u4Over16 = u4Over16; - constants.u6Over64 = u6Over64; - constants.u8Over256 = u8Over256; - constants.a0 = a0; - constants.a1 = a1; - constants.a2 = a2; - constants.a3 = a3; - constants.distanceRatio = distanceRatio; - } + /** + * A description of a circle on the ellipsoid. Circle geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * + * @alias CircleGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.center The circle's center point in the fixed frame. + * @param {Number} options.radius The radius in meters. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the circle will be on. + * @param {Number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. + * @param {Number} [options.granularity=0.02] The angular distance between points on the circle in radians. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {Number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. + * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * + * @exception {DeveloperError} radius must be greater than zero. + * @exception {DeveloperError} granularity must be greater than zero. + * + * @see CircleGeometry.createGeometry + * @see Packable + * + * @example + * // Create a circle. + * var circle = new Cesium.CircleGeometry({ + * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), + * radius : 100000.0 + * }); + * var geometry = Cesium.CircleGeometry.createGeometry(circle); + */ + function CircleGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var radius = options.radius; - function computeC(f, cosineSquaredAlpha) { - return f * cosineSquaredAlpha * (4.0 + f * (4.0 - 3.0 * cosineSquaredAlpha)) / 16.0; + Check.typeOf.number('radius', radius); + + var ellipseGeometryOptions = { + center : options.center, + semiMajorAxis : radius, + semiMinorAxis : radius, + ellipsoid : options.ellipsoid, + height : options.height, + extrudedHeight : options.extrudedHeight, + granularity : options.granularity, + vertexFormat : options.vertexFormat, + stRotation : options.stRotation, + shadowVolume: options.shadowVolume + }; + this._ellipseGeometry = new EllipseGeometry(ellipseGeometryOptions); + this._workerName = 'createCircleGeometry'; } - function computeDeltaLambda(f, sineAlpha, cosineSquaredAlpha, sigma, sineSigma, cosineSigma, cosineTwiceSigmaMidpoint) { - var C = computeC(f, cosineSquaredAlpha); + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + CircleGeometry.packedLength = EllipseGeometry.packedLength; - return (1.0 - C) * f * sineAlpha * (sigma + C * sineSigma * (cosineTwiceSigmaMidpoint + - C * cosineSigma * (2.0 * cosineTwiceSigmaMidpoint * cosineTwiceSigmaMidpoint - 1.0))); - } + /** + * Stores the provided instance into the provided array. + * + * @param {CircleGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + CircleGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + return EllipseGeometry.pack(value._ellipseGeometry, array, startingIndex); + }; - function vincentyInverseFormula(ellipsoidGeodesic, major, minor, firstLongitude, firstLatitude, secondLongitude, secondLatitude) { - var eff = (major - minor) / major; - var l = secondLongitude - firstLongitude; + var scratchEllipseGeometry = new EllipseGeometry({ + center : new Cartesian3(), + semiMajorAxis : 1.0, + semiMinorAxis : 1.0 + }); + var scratchOptions = { + center : new Cartesian3(), + radius : undefined, + ellipsoid : Ellipsoid.clone(Ellipsoid.UNIT_SPHERE), + height : undefined, + extrudedHeight : undefined, + granularity : undefined, + vertexFormat : new VertexFormat(), + stRotation : undefined, + semiMajorAxis : undefined, + semiMinorAxis : undefined, + shadowVolume: undefined + }; - var u1 = Math.atan((1 - eff) * Math.tan(firstLatitude)); - var u2 = Math.atan((1 - eff) * Math.tan(secondLatitude)); + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {CircleGeometry} [result] The object into which to store the result. + * @returns {CircleGeometry} The modified result parameter or a new CircleGeometry instance if one was not provided. + */ + CircleGeometry.unpack = function(array, startingIndex, result) { + var ellipseGeometry = EllipseGeometry.unpack(array, startingIndex, scratchEllipseGeometry); + scratchOptions.center = Cartesian3.clone(ellipseGeometry._center, scratchOptions.center); + scratchOptions.ellipsoid = Ellipsoid.clone(ellipseGeometry._ellipsoid, scratchOptions.ellipsoid); + scratchOptions.height = ellipseGeometry._height; + scratchOptions.extrudedHeight = ellipseGeometry._extrudedHeight; + scratchOptions.granularity = ellipseGeometry._granularity; + scratchOptions.vertexFormat = VertexFormat.clone(ellipseGeometry._vertexFormat, scratchOptions.vertexFormat); + scratchOptions.stRotation = ellipseGeometry._stRotation; + scratchOptions.shadowVolume = ellipseGeometry._shadowVolume; - var cosineU1 = Math.cos(u1); - var sineU1 = Math.sin(u1); - var cosineU2 = Math.cos(u2); - var sineU2 = Math.sin(u2); + if (!defined(result)) { + scratchOptions.radius = ellipseGeometry._semiMajorAxis; + return new CircleGeometry(scratchOptions); + } - var cc = cosineU1 * cosineU2; - var cs = cosineU1 * sineU2; - var ss = sineU1 * sineU2; - var sc = sineU1 * cosineU2; + scratchOptions.semiMajorAxis = ellipseGeometry._semiMajorAxis; + scratchOptions.semiMinorAxis = ellipseGeometry._semiMinorAxis; + result._ellipseGeometry = new EllipseGeometry(scratchOptions); + return result; + }; - var lambda = l; - var lambdaDot = CesiumMath.TWO_PI; + /** + * Computes the geometric representation of a circle on an ellipsoid, including its vertices, indices, and a bounding sphere. + * + * @param {CircleGeometry} circleGeometry A description of the circle. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + CircleGeometry.createGeometry = function(circleGeometry) { + return EllipseGeometry.createGeometry(circleGeometry._ellipseGeometry); + }; - var cosineLambda = Math.cos(lambda); - var sineLambda = Math.sin(lambda); + /** + * @private + */ + CircleGeometry.createShadowVolume = function(circleGeometry, minHeightFunc, maxHeightFunc) { + var granularity = circleGeometry._ellipseGeometry._granularity; + var ellipsoid = circleGeometry._ellipseGeometry._ellipsoid; - var sigma; - var cosineSigma; - var sineSigma; - var cosineSquaredAlpha; - var cosineTwiceSigmaMidpoint; + var minHeight = minHeightFunc(granularity, ellipsoid); + var maxHeight = maxHeightFunc(granularity, ellipsoid); - do { - cosineLambda = Math.cos(lambda); - sineLambda = Math.sin(lambda); + return new CircleGeometry({ + center : circleGeometry._ellipseGeometry._center, + radius : circleGeometry._ellipseGeometry._semiMajorAxis, + ellipsoid : ellipsoid, + stRotation : circleGeometry._ellipseGeometry._stRotation, + granularity : granularity, + extrudedHeight : minHeight, + height : maxHeight, + vertexFormat : VertexFormat.POSITION_ONLY, + shadowVolume: true + }); + }; - var temp = cs - sc * cosineLambda; - sineSigma = Math.sqrt(cosineU2 * cosineU2 * sineLambda * sineLambda + temp * temp); - cosineSigma = ss + cc * cosineLambda; + defineProperties(CircleGeometry.prototype, { + /** + * @private + */ + rectangle : { + get : function() { + return this._ellipseGeometry.rectangle; + } + } + }); - sigma = Math.atan2(sineSigma, cosineSigma); + return CircleGeometry; +}); - var sineAlpha; +define('Core/EllipseOutlineGeometry',[ + './BoundingSphere', + './Cartesian3', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './EllipseGeometryLibrary', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PrimitiveType' + ], function( + BoundingSphere, + Cartesian3, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + EllipseGeometryLibrary, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PrimitiveType) { + 'use strict'; - if (sineSigma === 0.0) { - sineAlpha = 0.0; - cosineSquaredAlpha = 1.0; - } else { - sineAlpha = cc * sineLambda / sineSigma; - cosineSquaredAlpha = 1.0 - sineAlpha * sineAlpha; - } + var scratchCartesian1 = new Cartesian3(); + var boundingSphereCenter = new Cartesian3(); - lambdaDot = lambda; + function computeEllipse(options) { + var center = options.center; + boundingSphereCenter = Cartesian3.multiplyByScalar(options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter), options.height, boundingSphereCenter); + boundingSphereCenter = Cartesian3.add(center, boundingSphereCenter, boundingSphereCenter); + var boundingSphere = new BoundingSphere(boundingSphereCenter, options.semiMajorAxis); + var positions = EllipseGeometryLibrary.computeEllipsePositions(options, false, true).outerPositions; - cosineTwiceSigmaMidpoint = cosineSigma - 2.0 * ss / cosineSquaredAlpha; + var attributes = new GeometryAttributes({ + position: new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : EllipseGeometryLibrary.raisePositionsToHeight(positions, options, false) + }) + }); - if (isNaN(cosineTwiceSigmaMidpoint)) { - cosineTwiceSigmaMidpoint = 0.0; - } + var length = positions.length / 3; + var indices = IndexDatatype.createTypedArray(length, length * 2); + var index = 0; + for ( var i = 0; i < length; ++i) { + indices[index++] = i; + indices[index++] = (i + 1) % length; + } - lambda = l + computeDeltaLambda(eff, sineAlpha, cosineSquaredAlpha, - sigma, sineSigma, cosineSigma, cosineTwiceSigmaMidpoint); - } while (Math.abs(lambda - lambdaDot) > CesiumMath.EPSILON12); + return { + boundingSphere : boundingSphere, + attributes : attributes, + indices : indices + }; + } - var uSquared = cosineSquaredAlpha * (major * major - minor * minor) / (minor * minor); - var A = 1.0 + uSquared * (4096.0 + uSquared * (uSquared * (320.0 - 175.0 * uSquared) - 768.0)) / 16384.0; - var B = uSquared * (256.0 + uSquared * (uSquared * (74.0 - 47.0 * uSquared) - 128.0)) / 1024.0; + var topBoundingSphere = new BoundingSphere(); + var bottomBoundingSphere = new BoundingSphere(); + function computeExtrudedEllipse(options) { + var center = options.center; + var ellipsoid = options.ellipsoid; + var semiMajorAxis = options.semiMajorAxis; + var scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1), options.height, scratchCartesian1); + topBoundingSphere.center = Cartesian3.add(center, scaledNormal, topBoundingSphere.center); + topBoundingSphere.radius = semiMajorAxis; - var cosineSquaredTwiceSigmaMidpoint = cosineTwiceSigmaMidpoint * cosineTwiceSigmaMidpoint; - var deltaSigma = B * sineSigma * (cosineTwiceSigmaMidpoint + B * (cosineSigma * - (2.0 * cosineSquaredTwiceSigmaMidpoint - 1.0) - B * cosineTwiceSigmaMidpoint * - (4.0 * sineSigma * sineSigma - 3.0) * (4.0 * cosineSquaredTwiceSigmaMidpoint - 3.0) / 6.0) / 4.0); + scaledNormal = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scaledNormal), options.extrudedHeight, scaledNormal); + bottomBoundingSphere.center = Cartesian3.add(center, scaledNormal, bottomBoundingSphere.center); + bottomBoundingSphere.radius = semiMajorAxis; - var distance = minor * A * (sigma - deltaSigma); + var positions = EllipseGeometryLibrary.computeEllipsePositions(options, false, true).outerPositions; + var attributes = new GeometryAttributes({ + position: new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : EllipseGeometryLibrary.raisePositionsToHeight(positions, options, true) + }) + }); - var startHeading = Math.atan2(cosineU2 * sineLambda, cs - sc * cosineLambda); - var endHeading = Math.atan2(cosineU1 * sineLambda, cs * cosineLambda - sc); + positions = attributes.position.values; + var boundingSphere = BoundingSphere.union(topBoundingSphere, bottomBoundingSphere); + var length = positions.length/3; + var numberOfVerticalLines = defaultValue(options.numberOfVerticalLines, 16); + numberOfVerticalLines = CesiumMath.clamp(numberOfVerticalLines, 0, length/2); - ellipsoidGeodesic._distance = distance; - ellipsoidGeodesic._startHeading = startHeading; - ellipsoidGeodesic._endHeading = endHeading; - ellipsoidGeodesic._uSquared = uSquared; - } + var indices = IndexDatatype.createTypedArray(length, length * 2 + numberOfVerticalLines * 2); - var scratchCart1 = new Cartesian3(); - var scratchCart2 = new Cartesian3(); - function computeProperties(ellipsoidGeodesic, start, end, ellipsoid) { - var firstCartesian = Cartesian3.normalize(ellipsoid.cartographicToCartesian(start, scratchCart2), scratchCart1); - var lastCartesian = Cartesian3.normalize(ellipsoid.cartographicToCartesian(end, scratchCart2), scratchCart2); + length /= 2; + var index = 0; + var i; + for (i = 0; i < length; ++i) { + indices[index++] = i; + indices[index++] = (i + 1) % length; + indices[index++] = i + length; + indices[index++] = ((i + 1) % length) + length; + } - Check.typeOf.number.greaterThanOrEquals('value', Math.abs(Math.abs(Cartesian3.angleBetween(firstCartesian, lastCartesian)) - Math.PI), 0.0125); - - vincentyInverseFormula(ellipsoidGeodesic, ellipsoid.maximumRadius, ellipsoid.minimumRadius, - start.longitude, start.latitude, end.longitude, end.latitude); + var numSide; + if (numberOfVerticalLines > 0) { + var numSideLines = Math.min(numberOfVerticalLines, length); + numSide = Math.round(length / numSideLines); - ellipsoidGeodesic._start = Cartographic.clone(start, ellipsoidGeodesic._start); - ellipsoidGeodesic._end = Cartographic.clone(end, ellipsoidGeodesic._end); - ellipsoidGeodesic._start.height = 0; - ellipsoidGeodesic._end.height = 0; + var maxI = Math.min(numSide * numberOfVerticalLines, length); + for (i = 0; i < maxI; i += numSide) { + indices[index++] = i; + indices[index++] = i + length; + } + } - setConstants(ellipsoidGeodesic); + return { + boundingSphere : boundingSphere, + attributes : attributes, + indices : indices + }; } /** - * Initializes a geodesic on the ellipsoid connecting the two provided planetodetic points. + * A description of the outline of an ellipse on an ellipsoid. * - * @alias EllipsoidGeodesic + * @alias EllipseOutlineGeometry * @constructor * - * @param {Cartographic} [start] The initial planetodetic point on the path. - * @param {Cartographic} [end] The final planetodetic point on the path. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the geodesic lies. + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. + * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. + * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. + * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. + * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. + * @param {Number} [options.rotation=0.0] The angle from north (counter-clockwise) in radians. + * @param {Number} [options.granularity=0.02] The angular distance between points on the ellipse in radians. + * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surface of an extruded ellipse. + * + * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero. + * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis. + * @exception {DeveloperError} granularity must be greater than zero. + * + * @see EllipseOutlineGeometry.createGeometry + * + * @example + * var ellipse = new Cesium.EllipseOutlineGeometry({ + * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), + * semiMajorAxis : 500000.0, + * semiMinorAxis : 300000.0, + * rotation : Cesium.Math.toRadians(60.0) + * }); + * var geometry = Cesium.EllipseOutlineGeometry.createGeometry(ellipse); */ - function EllipsoidGeodesic(start, end, ellipsoid) { - var e = defaultValue(ellipsoid, Ellipsoid.WGS84); - this._ellipsoid = e; - this._start = new Cartographic(); - this._end = new Cartographic(); + function EllipseOutlineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._constants = {}; - this._startHeading = undefined; - this._endHeading = undefined; - this._distance = undefined; - this._uSquared = undefined; + var center = options.center; + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var semiMajorAxis = options.semiMajorAxis; + var semiMinorAxis = options.semiMinorAxis; + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var height = defaultValue(options.height, 0.0); + var extrudedHeight = options.extrudedHeight; + var extrude = (defined(extrudedHeight) && Math.abs(height - extrudedHeight) > 1.0); - if (defined(start) && defined(end)) { - computeProperties(this, start, end, e); + if (!defined(center)) { + throw new DeveloperError('center is required.'); } - } - - defineProperties(EllipsoidGeodesic.prototype, { - /** - * Gets the ellipsoid. - * @memberof EllipsoidGeodesic.prototype - * @type {Ellipsoid} - * @readonly - */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } - }, - - /** - * Gets the surface distance between the start and end point - * @memberof EllipsoidGeodesic.prototype - * @type {Number} - * @readonly - */ - surfaceDistance : { - get : function() { - Check.defined('distance', this._distance); - - return this._distance; - } - }, - - /** - * Gets the initial planetodetic point on the path. - * @memberof EllipsoidGeodesic.prototype - * @type {Cartographic} - * @readonly - */ - start : { - get : function() { - return this._start; - } - }, - - /** - * Gets the final planetodetic point on the path. - * @memberof EllipsoidGeodesic.prototype - * @type {Cartographic} - * @readonly - */ - end : { - get : function() { - return this._end; - } - }, - - /** - * Gets the heading at the initial point. - * @memberof EllipsoidGeodesic.prototype - * @type {Number} - * @readonly - */ - startHeading : { - get : function() { - Check.defined('distance', this._distance); - - return this._startHeading; - } - }, - - /** - * Gets the heading at the final point. - * @memberof EllipsoidGeodesic.prototype - * @type {Number} - * @readonly - */ - endHeading : { - get : function() { - Check.defined('distance', this._distance); - - return this._endHeading; - } + if (!defined(semiMajorAxis)) { + throw new DeveloperError('semiMajorAxis is required.'); + } + if (!defined(semiMinorAxis)) { + throw new DeveloperError('semiMinorAxis is required.'); + } + if (semiMajorAxis < semiMinorAxis) { + throw new DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.'); + } + if (granularity <= 0.0) { + throw new DeveloperError('granularity must be greater than zero.'); } - }); - - /** - * Sets the start and end points of the geodesic - * - * @param {Cartographic} start The initial planetodetic point on the path. - * @param {Cartographic} end The final planetodetic point on the path. - */ - EllipsoidGeodesic.prototype.setEndPoints = function(start, end) { - Check.defined('start', start); - Check.defined('end', end); - computeProperties(this, start, end, this._ellipsoid); - }; + this._center = Cartesian3.clone(center); + this._semiMajorAxis = semiMajorAxis; + this._semiMinorAxis = semiMinorAxis; + this._ellipsoid = Ellipsoid.clone(ellipsoid); + this._rotation = defaultValue(options.rotation, 0.0); + this._height = height; + this._granularity = granularity; + this._extrudedHeight = extrudedHeight; + this._extrude = extrude; + this._numberOfVerticalLines = Math.max(defaultValue(options.numberOfVerticalLines, 16), 0); + this._workerName = 'createEllipseOutlineGeometry'; + } /** - * Provides the location of a point at the indicated portion along the geodesic. - * - * @param {Number} fraction The portion of the distance between the initial and final points. - * @param {Cartographic} result The object in which to store the result. - * @returns {Cartographic} The location of the point along the geodesic. + * The number of elements used to pack the object into an array. + * @type {Number} */ - EllipsoidGeodesic.prototype.interpolateUsingFraction = function(fraction, result) { - return this.interpolateUsingSurfaceDistance(this._distance * fraction, result); - }; + EllipseOutlineGeometry.packedLength = Cartesian3.packedLength + Ellipsoid.packedLength + 9; /** - * Provides the location of a point at the indicated distance along the geodesic. + * Stores the provided instance into the provided array. * - * @param {Number} distance The distance from the inital point to the point of interest along the geodesic - * @param {Cartographic} result The object in which to store the result. - * @returns {Cartographic} The location of the point along the geodesic. + * @param {EllipseOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @exception {DeveloperError} start and end must be set before calling function interpolateUsingSurfaceDistance + * @returns {Number[]} The array that was packed into */ - EllipsoidGeodesic.prototype.interpolateUsingSurfaceDistance = function(distance, result) { - Check.defined('distance', this._distance); + EllipseOutlineGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } - var constants = this._constants; + startingIndex = defaultValue(startingIndex, 0); - var s = constants.distanceRatio + distance / constants.b; + Cartesian3.pack(value._center, array, startingIndex); + startingIndex += Cartesian3.packedLength; - var cosine2S = Math.cos(2.0 * s); - var cosine4S = Math.cos(4.0 * s); - var cosine6S = Math.cos(6.0 * s); - var sine2S = Math.sin(2.0 * s); - var sine4S = Math.sin(4.0 * s); - var sine6S = Math.sin(6.0 * s); - var sine8S = Math.sin(8.0 * s); + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - var s2 = s * s; - var s3 = s * s2; + array[startingIndex++] = value._semiMajorAxis; + array[startingIndex++] = value._semiMinorAxis; + array[startingIndex++] = value._rotation; + array[startingIndex++] = value._height; + array[startingIndex++] = value._granularity; + array[startingIndex++] = defined(value._extrudedHeight) ? 1.0 : 0.0; + array[startingIndex++] = defaultValue(value._extrudedHeight, 0.0); + array[startingIndex++] = value._extrude ? 1.0 : 0.0; + array[startingIndex] = value._numberOfVerticalLines; - var u8Over256 = constants.u8Over256; - var u2Over4 = constants.u2Over4; - var u6Over64 = constants.u6Over64; - var u4Over16 = constants.u4Over16; - var sigma = 2.0 * s3 * u8Over256 * cosine2S / 3.0 + - s * (1.0 - u2Over4 + 7.0 * u4Over16 / 4.0 - 15.0 * u6Over64 / 4.0 + 579.0 * u8Over256 / 64.0 - - (u4Over16 - 15.0 * u6Over64 / 4.0 + 187.0 * u8Over256 / 16.0) * cosine2S - - (5.0 * u6Over64 / 4.0 - 115.0 * u8Over256 / 16.0) * cosine4S - - 29.0 * u8Over256 * cosine6S / 16.0) + - (u2Over4 / 2.0 - u4Over16 + 71.0 * u6Over64 / 32.0 - 85.0 * u8Over256 / 16.0) * sine2S + - (5.0 * u4Over16 / 16.0 - 5.0 * u6Over64 / 4.0 + 383.0 * u8Over256 / 96.0) * sine4S - - s2 * ((u6Over64 - 11.0 * u8Over256 / 2.0) * sine2S + 5.0 * u8Over256 * sine4S / 2.0) + - (29.0 * u6Over64 / 96.0 - 29.0 * u8Over256 / 16.0) * sine6S + - 539.0 * u8Over256 * sine8S / 1536.0; + return array; + }; - var theta = Math.asin(Math.sin(sigma) * constants.cosineAlpha); - var latitude = Math.atan(constants.a / constants.b * Math.tan(theta)); + var scratchCenter = new Cartesian3(); + var scratchEllipsoid = new Ellipsoid(); + var scratchOptions = { + center : scratchCenter, + ellipsoid : scratchEllipsoid, + semiMajorAxis : undefined, + semiMinorAxis : undefined, + rotation : undefined, + height : undefined, + granularity : undefined, + extrudedHeight : undefined, + numberOfVerticalLines : undefined + }; - // Redefine in terms of relative argument of latitude. - sigma = sigma - constants.sigma; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {EllipseOutlineGeometry} [result] The object into which to store the result. + * @returns {EllipseOutlineGeometry} The modified result parameter or a new EllipseOutlineGeometry instance if one was not provided. + */ + EllipseOutlineGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - var cosineTwiceSigmaMidpoint = Math.cos(2.0 * constants.sigma + sigma); + var center = Cartesian3.unpack(array, startingIndex, scratchCenter); + startingIndex += Cartesian3.packedLength; - var sineSigma = Math.sin(sigma); - var cosineSigma = Math.cos(sigma); + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - var cc = constants.cosineU * cosineSigma; - var ss = constants.sineU * sineSigma; + var semiMajorAxis = array[startingIndex++]; + var semiMinorAxis = array[startingIndex++]; + var rotation = array[startingIndex++]; + var height = array[startingIndex++]; + var granularity = array[startingIndex++]; + var hasExtrudedHeight = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var extrude = array[startingIndex++] === 1.0; + var numberOfVerticalLines = array[startingIndex]; - var lambda = Math.atan2(sineSigma * constants.sineHeading, cc - ss * constants.cosineHeading); + if (!defined(result)) { + scratchOptions.height = height; + scratchOptions.extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; + scratchOptions.granularity = granularity; + scratchOptions.rotation = rotation; + scratchOptions.semiMajorAxis = semiMajorAxis; + scratchOptions.semiMinorAxis = semiMinorAxis; + scratchOptions.numberOfVerticalLines = numberOfVerticalLines; + return new EllipseOutlineGeometry(scratchOptions); + } - var l = lambda - computeDeltaLambda(constants.f, constants.sineAlpha, constants.cosineSquaredAlpha, - sigma, sineSigma, cosineSigma, cosineTwiceSigmaMidpoint); + result._center = Cartesian3.clone(center, result._center); + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._semiMajorAxis = semiMajorAxis; + result._semiMinorAxis = semiMinorAxis; + result._rotation = rotation; + result._height = height; + result._granularity = granularity; + result._extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; + result._extrude = extrude; + result._numberOfVerticalLines = numberOfVerticalLines; - if (defined(result)) { - result.longitude = this._start.longitude + l; - result.latitude = latitude; - result.height = 0.0; - return result; + return result; + }; + + /** + * Computes the geometric representation of an outline of an ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere. + * + * @param {EllipseOutlineGeometry} ellipseGeometry A description of the ellipse. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + EllipseOutlineGeometry.createGeometry = function(ellipseGeometry) { + if ((ellipseGeometry._semiMajorAxis <= 0.0) || (ellipseGeometry._semiMinorAxis <= 0.0)) { + return; } - return new Cartographic(this._start.longitude + l, latitude, 0.0); + ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(ellipseGeometry._center, ellipseGeometry._center); + var options = { + center : ellipseGeometry._center, + semiMajorAxis : ellipseGeometry._semiMajorAxis, + semiMinorAxis : ellipseGeometry._semiMinorAxis, + ellipsoid : ellipseGeometry._ellipsoid, + rotation : ellipseGeometry._rotation, + height : ellipseGeometry._height, + extrudedHeight : ellipseGeometry._extrudedHeight, + granularity : ellipseGeometry._granularity, + numberOfVerticalLines : ellipseGeometry._numberOfVerticalLines + }; + var geometry; + if (ellipseGeometry._extrude) { + options.extrudedHeight = Math.min(ellipseGeometry._extrudedHeight, ellipseGeometry._height); + options.height = Math.max(ellipseGeometry._extrudedHeight, ellipseGeometry._height); + geometry = computeExtrudedEllipse(options); + } else { + geometry = computeEllipse(options); + } + + return new Geometry({ + attributes : geometry.attributes, + indices : geometry.indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : geometry.boundingSphere + }); }; - return EllipsoidGeodesic; + return EllipseOutlineGeometry; }); -define('Core/PolylinePipeline',[ +define('Core/CircleOutlineGeometry',[ './Cartesian3', - './Cartographic', + './Check', './defaultValue', './defined', - './DeveloperError', - './Ellipsoid', - './EllipsoidGeodesic', - './IntersectionTests', - './isArray', - './Math', - './Matrix4', - './Plane' + './EllipseOutlineGeometry', + './Ellipsoid' ], function( Cartesian3, - Cartographic, + Check, defaultValue, defined, - DeveloperError, - Ellipsoid, - EllipsoidGeodesic, - IntersectionTests, - isArray, - CesiumMath, - Matrix4, - Plane) { + EllipseOutlineGeometry, + Ellipsoid) { 'use strict'; /** - * @private + * A description of the outline of a circle on the ellipsoid. + * + * @alias CircleOutlineGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3} options.center The circle's center point in the fixed frame. + * @param {Number} options.radius The radius in meters. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the circle will be on. + * @param {Number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. + * @param {Number} [options.granularity=0.02] The angular distance between points on the circle in radians. + * @param {Number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. + * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom of an extruded circle. + * + * @exception {DeveloperError} radius must be greater than zero. + * @exception {DeveloperError} granularity must be greater than zero. + * + * @see CircleOutlineGeometry.createGeometry + * @see Packable + * + * @example + * // Create a circle. + * var circle = new Cesium.CircleOutlineGeometry({ + * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), + * radius : 100000.0 + * }); + * var geometry = Cesium.CircleOutlineGeometry.createGeometry(circle); */ - var PolylinePipeline = {}; + function CircleOutlineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var radius = options.radius; - PolylinePipeline.numberOfPoints = function(p0, p1, minDistance) { - var distance = Cartesian3.distance(p0, p1); - return Math.ceil(distance / minDistance); + Check.typeOf.number('radius', radius); + + var ellipseGeometryOptions = { + center : options.center, + semiMajorAxis : radius, + semiMinorAxis : radius, + ellipsoid : options.ellipsoid, + height : options.height, + extrudedHeight : options.extrudedHeight, + granularity : options.granularity, + numberOfVerticalLines : options.numberOfVerticalLines + }; + this._ellipseGeometry = new EllipseOutlineGeometry(ellipseGeometryOptions); + this._workerName = 'createCircleOutlineGeometry'; + } + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + CircleOutlineGeometry.packedLength = EllipseOutlineGeometry.packedLength; + + /** + * Stores the provided instance into the provided array. + * + * @param {CircleOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + CircleOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + return EllipseOutlineGeometry.pack(value._ellipseGeometry, array, startingIndex); }; - var cartoScratch = new Cartographic(); - PolylinePipeline.extractHeights = function(positions, ellipsoid) { - var length = positions.length; - var heights = new Array(length); - for (var i = 0; i < length; i++) { - var p = positions[i]; - heights[i] = ellipsoid.cartesianToCartographic(p, cartoScratch).height; - } - return heights; + var scratchEllipseGeometry = new EllipseOutlineGeometry({ + center : new Cartesian3(), + semiMajorAxis : 1.0, + semiMinorAxis : 1.0 + }); + var scratchOptions = { + center : new Cartesian3(), + radius : undefined, + ellipsoid : Ellipsoid.clone(Ellipsoid.UNIT_SPHERE), + height : undefined, + extrudedHeight : undefined, + granularity : undefined, + numberOfVerticalLines : undefined, + semiMajorAxis : undefined, + semiMinorAxis : undefined }; - var wrapLongitudeInversMatrix = new Matrix4(); - var wrapLongitudeOrigin = new Cartesian3(); - var wrapLongitudeXZNormal = new Cartesian3(); - var wrapLongitudeXZPlane = new Plane(Cartesian3.UNIT_X, 0.0); - var wrapLongitudeYZNormal = new Cartesian3(); - var wrapLongitudeYZPlane = new Plane(Cartesian3.UNIT_X, 0.0); - var wrapLongitudeIntersection = new Cartesian3(); - var wrapLongitudeOffset = new Cartesian3(); + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {CircleOutlineGeometry} [result] The object into which to store the result. + * @returns {CircleOutlineGeometry} The modified result parameter or a new CircleOutlineGeometry instance if one was not provided. + */ + CircleOutlineGeometry.unpack = function(array, startingIndex, result) { + var ellipseGeometry = EllipseOutlineGeometry.unpack(array, startingIndex, scratchEllipseGeometry); + scratchOptions.center = Cartesian3.clone(ellipseGeometry._center, scratchOptions.center); + scratchOptions.ellipsoid = Ellipsoid.clone(ellipseGeometry._ellipsoid, scratchOptions.ellipsoid); + scratchOptions.height = ellipseGeometry._height; + scratchOptions.extrudedHeight = ellipseGeometry._extrudedHeight; + scratchOptions.granularity = ellipseGeometry._granularity; + scratchOptions.numberOfVerticalLines = ellipseGeometry._numberOfVerticalLines; - var subdivideHeightsScratchArray = []; + if (!defined(result)) { + scratchOptions.radius = ellipseGeometry._semiMajorAxis; + return new CircleOutlineGeometry(scratchOptions); + } - function subdivideHeights(numPoints, h0, h1) { - var heights = subdivideHeightsScratchArray; - heights.length = numPoints; + scratchOptions.semiMajorAxis = ellipseGeometry._semiMajorAxis; + scratchOptions.semiMinorAxis = ellipseGeometry._semiMinorAxis; + result._ellipseGeometry = new EllipseOutlineGeometry(scratchOptions); + return result; + }; - var i; - if (h0 === h1) { - for (i = 0; i < numPoints; i++) { - heights[i] = h0; - } - return heights; - } + /** + * Computes the geometric representation of an outline of a circle on an ellipsoid, including its vertices, indices, and a bounding sphere. + * + * @param {CircleOutlineGeometry} circleGeometry A description of the circle. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + CircleOutlineGeometry.createGeometry = function(circleGeometry) { + return EllipseOutlineGeometry.createGeometry(circleGeometry._ellipseGeometry); + }; - var dHeight = h1 - h0; - var heightPerVertex = dHeight / numPoints; + return CircleOutlineGeometry; +}); - for (i = 0; i < numPoints; i++) { - var h = h0 + i*heightPerVertex; - heights[i] = h; +define('Core/Color',[ + './Check', + './defaultValue', + './defined', + './FeatureDetection', + './freezeObject', + './Math' + ], function( + Check, + defaultValue, + defined, + FeatureDetection, + freezeObject, + CesiumMath) { + 'use strict'; + + function hue2rgb(m1, m2, h) { + if (h < 0) { + h += 1; + } + if (h > 1) { + h -= 1; + } + if (h * 6 < 1) { + return m1 + (m2 - m1) * 6 * h; + } + if (h * 2 < 1) { + return m2; + } + if (h * 3 < 2) { + return m1 + (m2 - m1) * (2 / 3 - h) * 6; } + return m1; + } - return heights; + /** + * A color, specified using red, green, blue, and alpha values, + * which range from <code>0</code> (no intensity) to <code>1.0</code> (full intensity). + * @param {Number} [red=1.0] The red component. + * @param {Number} [green=1.0] The green component. + * @param {Number} [blue=1.0] The blue component. + * @param {Number} [alpha=1.0] The alpha component. + * + * @constructor + * @alias Color + * + * @see Packable + */ + function Color(red, green, blue, alpha) { + /** + * The red component. + * @type {Number} + * @default 1.0 + */ + this.red = defaultValue(red, 1.0); + /** + * The green component. + * @type {Number} + * @default 1.0 + */ + this.green = defaultValue(green, 1.0); + /** + * The blue component. + * @type {Number} + * @default 1.0 + */ + this.blue = defaultValue(blue, 1.0); + /** + * The alpha component. + * @type {Number} + * @default 1.0 + */ + this.alpha = defaultValue(alpha, 1.0); } - var carto1 = new Cartographic(); - var carto2 = new Cartographic(); - var cartesian = new Cartesian3(); - var scaleFirst = new Cartesian3(); - var scaleLast = new Cartesian3(); - var ellipsoidGeodesic = new EllipsoidGeodesic(); + /** + * Creates a Color instance from a {@link Cartesian4}. <code>x</code>, <code>y</code>, <code>z</code>, + * and <code>w</code> map to <code>red</code>, <code>green</code>, <code>blue</code>, and <code>alpha</code>, respectively. + * + * @param {Cartesian4} cartesian The source cartesian. + * @param {Color} [result] The object onto which to store the result. + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + */ + Color.fromCartesian4 = function(cartesian, result) { + Check.typeOf.object('cartesian', cartesian); + + if (!defined(result)) { + return new Color(cartesian.x, cartesian.y, cartesian.z, cartesian.w); + } - //Returns subdivided line scaled to ellipsoid surface starting at p1 and ending at p2. - //Result includes p1, but not include p2. This function is called for a sequence of line segments, - //and this prevents duplication of end point. - function generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, array, offset) { - var first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst); - var last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast); - var numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance); - var start = ellipsoid.cartesianToCartographic(first, carto1); - var end = ellipsoid.cartesianToCartographic(last, carto2); - var heights = subdivideHeights(numPoints, h0, h1); + result.red = cartesian.x; + result.green = cartesian.y; + result.blue = cartesian.z; + result.alpha = cartesian.w; + return result; + }; - ellipsoidGeodesic.setEndPoints(start, end); - var surfaceDistanceBetweenPoints = ellipsoidGeodesic.surfaceDistance / numPoints; + /** + * Creates a new Color specified using red, green, blue, and alpha values + * that are in the range of 0 to 255, converting them internally to a range of 0.0 to 1.0. + * + * @param {Number} [red=255] The red component. + * @param {Number} [green=255] The green component. + * @param {Number} [blue=255] The blue component. + * @param {Number} [alpha=255] The alpha component. + * @param {Color} [result] The object onto which to store the result. + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + */ + Color.fromBytes = function(red, green, blue, alpha, result) { + red = Color.byteToFloat(defaultValue(red, 255.0)); + green = Color.byteToFloat(defaultValue(green, 255.0)); + blue = Color.byteToFloat(defaultValue(blue, 255.0)); + alpha = Color.byteToFloat(defaultValue(alpha, 255.0)); - var index = offset; - start.height = h0; - var cart = ellipsoid.cartographicToCartesian(start, cartesian); - Cartesian3.pack(cart, array, index); - index += 3; + if (!defined(result)) { + return new Color(red, green, blue, alpha); + } - for (var i = 1; i < numPoints; i++) { - var carto = ellipsoidGeodesic.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2); - carto.height = heights[i]; - cart = ellipsoid.cartographicToCartesian(carto, cartesian); - Cartesian3.pack(cart, array, index); - index += 3; + result.red = red; + result.green = green; + result.blue = blue; + result.alpha = alpha; + return result; + }; + + /** + * Creates a new Color that has the same red, green, and blue components + * of the specified color, but with the specified alpha value. + * + * @param {Color} color The base color + * @param {Number} alpha The new alpha component. + * @param {Color} [result] The object onto which to store the result. + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + * + * @example var translucentRed = Cesium.Color.fromAlpha(Cesium.Color.RED, 0.9); + */ + Color.fromAlpha = function(color, alpha, result) { + Check.typeOf.object('color', color); + Check.typeOf.number('alpha', alpha); + + if (!defined(result)) { + return new Color(color.red, color.green, color.blue, alpha); } - return index; + result.red = color.red; + result.green = color.green; + result.blue = color.blue; + result.alpha = alpha; + return result; + }; + + var scratchArrayBuffer; + var scratchUint32Array; + var scratchUint8Array; + if (FeatureDetection.supportsTypedArrays()) { + scratchArrayBuffer = new ArrayBuffer(4); + scratchUint32Array = new Uint32Array(scratchArrayBuffer); + scratchUint8Array = new Uint8Array(scratchArrayBuffer); } /** - * Breaks a {@link Polyline} into segments such that it does not cross the ±180 degree meridian of an ellipsoid. - * - * @param {Cartesian3[]} positions The polyline's Cartesian positions. - * @param {Matrix4} [modelMatrix=Matrix4.IDENTITY] The polyline's model matrix. Assumed to be an affine - * transformation matrix, where the upper left 3x3 elements are a rotation matrix, and - * the upper three elements in the fourth column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. - * The matrix is not verified to be in the proper form. - * @returns {Object} An object with a <code>positions</code> property that is an array of positions and a - * <code>segments</code> property. + * Creates a new Color from a single numeric unsigned 32-bit RGBA value, using the endianness + * of the system. * + * @param {Number} rgba A single numeric unsigned 32-bit RGBA value. + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The color object. * * @example - * var polylines = new Cesium.PolylineCollection(); - * var polyline = polylines.add(...); - * var positions = polyline.positions; - * var modelMatrix = polylines.modelMatrix; - * var segments = Cesium.PolylinePipeline.wrapLongitude(positions, modelMatrix); + * var color = Cesium.Color.fromRgba(0x67ADDFFF); * - * @see PolygonPipeline.wrapLongitude - * @see Polyline - * @see PolylineCollection + * @see Color#toRgba */ - PolylinePipeline.wrapLongitude = function(positions, modelMatrix) { - var cartesians = []; - var segments = []; - - if (defined(positions) && positions.length > 0) { - modelMatrix = defaultValue(modelMatrix, Matrix4.IDENTITY); - var inverseModelMatrix = Matrix4.inverseTransformation(modelMatrix, wrapLongitudeInversMatrix); - - var origin = Matrix4.multiplyByPoint(inverseModelMatrix, Cartesian3.ZERO, wrapLongitudeOrigin); - var xzNormal = Cartesian3.normalize(Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian3.UNIT_Y, wrapLongitudeXZNormal), wrapLongitudeXZNormal); - var xzPlane = Plane.fromPointNormal(origin, xzNormal, wrapLongitudeXZPlane); - var yzNormal = Cartesian3.normalize(Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian3.UNIT_X, wrapLongitudeYZNormal), wrapLongitudeYZNormal); - var yzPlane = Plane.fromPointNormal(origin, yzNormal, wrapLongitudeYZPlane); - - var count = 1; - cartesians.push(Cartesian3.clone(positions[0])); - var prev = cartesians[0]; - - var length = positions.length; - for (var i = 1; i < length; ++i) { - var cur = positions[i]; - - // intersects the IDL if either endpoint is on the negative side of the yz-plane - if (Plane.getPointDistance(yzPlane, prev) < 0.0 || Plane.getPointDistance(yzPlane, cur) < 0.0) { - // and intersects the xz-plane - var intersection = IntersectionTests.lineSegmentPlane(prev, cur, xzPlane, wrapLongitudeIntersection); - if (defined(intersection)) { - // move point on the xz-plane slightly away from the plane - var offset = Cartesian3.multiplyByScalar(xzNormal, 5.0e-9, wrapLongitudeOffset); - if (Plane.getPointDistance(xzPlane, prev) < 0.0) { - Cartesian3.negate(offset, offset); - } - - cartesians.push(Cartesian3.add(intersection, offset, new Cartesian3())); - segments.push(count + 1); + Color.fromRgba = function(rgba, result) { + // scratchUint32Array and scratchUint8Array share an underlying array buffer + scratchUint32Array[0] = rgba; + return Color.fromBytes(scratchUint8Array[0], scratchUint8Array[1], scratchUint8Array[2], scratchUint8Array[3], result); + }; - Cartesian3.negate(offset, offset); - cartesians.push(Cartesian3.add(intersection, offset, new Cartesian3())); - count = 1; - } - } + /** + * Creates a Color instance from hue, saturation, and lightness. + * + * @param {Number} [hue=0] The hue angle 0...1 + * @param {Number} [saturation=0] The saturation value 0...1 + * @param {Number} [lightness=0] The lightness value 0...1 + * @param {Number} [alpha=1.0] The alpha component 0...1 + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The color object. + * + * @see {@link http://www.w3.org/TR/css3-color/#hsl-color|CSS color values} + */ + Color.fromHsl = function(hue, saturation, lightness, alpha, result) { + hue = defaultValue(hue, 0.0) % 1.0; + saturation = defaultValue(saturation, 0.0); + lightness = defaultValue(lightness, 0.0); + alpha = defaultValue(alpha, 1.0); - cartesians.push(Cartesian3.clone(positions[i])); - count++; + var red = lightness; + var green = lightness; + var blue = lightness; - prev = cur; + if (saturation !== 0) { + var m2; + if (lightness < 0.5) { + m2 = lightness * (1 + saturation); + } else { + m2 = lightness + saturation - lightness * saturation; } - segments.push(count); + var m1 = 2.0 * lightness - m2; + red = hue2rgb(m1, m2, hue + 1 / 3); + green = hue2rgb(m1, m2, hue); + blue = hue2rgb(m1, m2, hue - 1 / 3); } - return { - positions : cartesians, - lengths : segments - }; + if (!defined(result)) { + return new Color(red, green, blue, alpha); + } + + result.red = red; + result.green = green; + result.blue = blue; + result.alpha = alpha; + return result; }; /** - * Subdivides polyline and raises all points to the specified height. Returns an array of numbers to represent the positions. - * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. - * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. - * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. - * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid. + * Creates a random color using the provided options. For reproducible random colors, you should + * call {@link CesiumMath#setRandomNumberSeed} once at the beginning of your application. + * + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.red] If specified, the red component to use instead of a randomized value. + * @param {Number} [options.minimumRed=0.0] The maximum red value to generate if none was specified. + * @param {Number} [options.maximumRed=1.0] The minimum red value to generate if none was specified. + * @param {Number} [options.green] If specified, the green component to use instead of a randomized value. + * @param {Number} [options.minimumGreen=0.0] The maximum green value to generate if none was specified. + * @param {Number} [options.maximumGreen=1.0] The minimum green value to generate if none was specified. + * @param {Number} [options.blue] If specified, the blue component to use instead of a randomized value. + * @param {Number} [options.minimumBlue=0.0] The maximum blue value to generate if none was specified. + * @param {Number} [options.maximumBlue=1.0] The minimum blue value to generate if none was specified. + * @param {Number} [options.alpha] If specified, the alpha component to use instead of a randomized value. + * @param {Number} [options.minimumAlpha=0.0] The maximum alpha value to generate if none was specified. + * @param {Number} [options.maximumAlpha=1.0] The minimum alpha value to generate if none was specified. + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The modified result parameter or a new instance if result was undefined. + * + * @exception {DeveloperError} minimumRed must be less than or equal to maximumRed. + * @exception {DeveloperError} minimumGreen must be less than or equal to maximumGreen. + * @exception {DeveloperError} minimumBlue must be less than or equal to maximumBlue. + * @exception {DeveloperError} minimumAlpha must be less than or equal to maximumAlpha. * * @example - * var positions = Cesium.Cartesian3.fromDegreesArray([ - * -105.0, 40.0, - * -100.0, 38.0, - * -105.0, 35.0, - * -100.0, 32.0 - * ]); - * var surfacePositions = Cesium.PolylinePipeline.generateArc({ - * positons: positions + * //Create a completely random color + * var color = Cesium.Color.fromRandom(); + * + * //Create a random shade of yellow. + * var color = Cesium.Color.fromRandom({ + * red : 1.0, + * green : 1.0, + * alpha : 1.0 + * }); + * + * //Create a random bright color. + * var color = Cesium.Color.fromRandom({ + * minimumRed : 0.75, + * minimumGreen : 0.75, + * minimumBlue : 0.75, + * alpha : 1.0 * }); */ - PolylinePipeline.generateArc = function(options) { - if (!defined(options)) { - options = {}; - } - var positions = options.positions; - if (!defined(positions)) { - throw new DeveloperError('options.positions is required.'); - } - - var length = positions.length; - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var height = defaultValue(options.height, 0); - var hasHeightArray = isArray(height); - - if (length < 1) { - return []; - } else if (length === 1) { - var p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst); - height = hasHeightArray ? height[0] : height; - if (height !== 0) { - var n = ellipsoid.geodeticSurfaceNormal(p, cartesian); - Cartesian3.multiplyByScalar(n, height, n); - Cartesian3.add(p, n, p); - } + Color.fromRandom = function(options, result) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - return [p.x, p.y, p.z]; - } + var red = options.red; + if (!defined(red)) { + var minimumRed = defaultValue(options.minimumRed, 0); + var maximumRed = defaultValue(options.maximumRed, 1.0); - var minDistance = options.minDistance; - if (!defined(minDistance)) { - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + Check.typeOf.number.lessThanOrEquals('minimumRed', minimumRed, maximumRed); + + red = minimumRed + (CesiumMath.nextRandomNumber() * (maximumRed - minimumRed)); } - var numPoints = 0; - var i; + var green = options.green; + if (!defined(green)) { + var minimumGreen = defaultValue(options.minimumGreen, 0); + var maximumGreen = defaultValue(options.maximumGreen, 1.0); - for (i = 0; i < length -1; i++) { - numPoints += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance); + Check.typeOf.number.lessThanOrEquals('minimumGreen', minimumGreen, maximumGreen); + green = minimumGreen + (CesiumMath.nextRandomNumber() * (maximumGreen - minimumGreen)); } - var arrayLength = (numPoints + 1) * 3; - var newPositions = new Array(arrayLength); - var offset = 0; + var blue = options.blue; + if (!defined(blue)) { + var minimumBlue = defaultValue(options.minimumBlue, 0); + var maximumBlue = defaultValue(options.maximumBlue, 1.0); - for (i = 0; i < length - 1; i++) { - var p0 = positions[i]; - var p1 = positions[i + 1]; + Check.typeOf.number.lessThanOrEquals('minimumBlue', minimumBlue, maximumBlue); + + blue = minimumBlue + (CesiumMath.nextRandomNumber() * (maximumBlue - minimumBlue)); + } - var h0 = hasHeightArray ? height[i] : height; - var h1 = hasHeightArray ? height[i + 1] : height; + var alpha = options.alpha; + if (!defined(alpha)) { + var minimumAlpha = defaultValue(options.minimumAlpha, 0); + var maximumAlpha = defaultValue(options.maximumAlpha, 1.0); - offset = generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, newPositions, offset); + Check.typeOf.number.lessThanOrEquals('minumumAlpha', minimumAlpha, maximumAlpha); + + alpha = minimumAlpha + (CesiumMath.nextRandomNumber() * (maximumAlpha - minimumAlpha)); } - subdivideHeightsScratchArray.length = 0; - - var lastPoint = positions[length - 1]; - var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1); - carto.height = hasHeightArray ? height[length - 1] : height; - var cart = ellipsoid.cartographicToCartesian(carto, cartesian); - Cartesian3.pack(cart, newPositions, arrayLength - 3); + if (!defined(result)) { + return new Color(red, green, blue, alpha); + } - return newPositions; + result.red = red; + result.green = green; + result.blue = blue; + result.alpha = alpha; + return result; }; + //#rgb + var rgbMatcher = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i; + //#rrggbb + var rrggbbMatcher = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i; + //rgb(), rgba(), or rgb%() + var rgbParenthesesMatcher = /^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i; + //hsl(), hsla(), or hsl%() + var hslParenthesesMatcher = /^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i; + /** - * Subdivides polyline and raises all points to the specified height. Returns an array of new {Cartesian3} positions. - * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. - * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. - * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. - * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid. + * Creates a Color instance from a CSS color value. + * + * @param {String} color The CSS color value in #rgb, #rrggbb, rgb(), rgba(), hsl(), or hsla() format. + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The color object, or undefined if the string was not a valid CSS color. + * * * @example - * var positions = Cesium.Cartesian3.fromDegreesArray([ - * -105.0, 40.0, - * -100.0, 38.0, - * -105.0, 35.0, - * -100.0, 32.0 - * ]); - * var surfacePositions = Cesium.PolylinePipeline.generateCartesianArc({ - * positons: positions - * }); + * var cesiumBlue = Cesium.Color.fromCssColorString('#67ADDF'); + * var green = Cesium.Color.fromCssColorString('green'); + * + * @see {@link http://www.w3.org/TR/css3-color|CSS color values} */ - PolylinePipeline.generateCartesianArc = function(options) { - var numberArray = PolylinePipeline.generateArc(options); - var size = numberArray.length/3; - var newPositions = new Array(size); - for (var i = 0; i < size; i++) { - newPositions[i] = Cartesian3.unpack(numberArray, i*3); + Color.fromCssColorString = function(color, result) { + Check.typeOf.string('color', color); + + if (!defined(result)) { + result = new Color(); } - return newPositions; - }; - return PolylinePipeline; -}); + var namedColor = Color[color.toUpperCase()]; + if (defined(namedColor)) { + Color.clone(namedColor, result); + return result; + } -define('Core/PolylineVolumeGeometryLibrary',[ - './Cartesian2', - './Cartesian3', - './Cartesian4', - './Cartographic', - './CornerType', - './EllipsoidTangentPlane', - './Math', - './Matrix3', - './Matrix4', - './PolylinePipeline', - './Quaternion', - './Transforms' - ], function( - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - CornerType, - EllipsoidTangentPlane, - CesiumMath, - Matrix3, - Matrix4, - PolylinePipeline, - Quaternion, - Transforms) { - 'use strict'; + var matches = rgbMatcher.exec(color); + if (matches !== null) { + result.red = parseInt(matches[1], 16) / 15; + result.green = parseInt(matches[2], 16) / 15.0; + result.blue = parseInt(matches[3], 16) / 15.0; + result.alpha = 1.0; + return result; + } - var scratch2Array = [new Cartesian3(), new Cartesian3()]; - var scratchCartesian1 = new Cartesian3(); - var scratchCartesian2 = new Cartesian3(); - var scratchCartesian3 = new Cartesian3(); - var scratchCartesian4 = new Cartesian3(); - var scratchCartesian5 = new Cartesian3(); - var scratchCartesian6 = new Cartesian3(); - var scratchCartesian7 = new Cartesian3(); - var scratchCartesian8 = new Cartesian3(); - var scratchCartesian9 = new Cartesian3(); + matches = rrggbbMatcher.exec(color); + if (matches !== null) { + result.red = parseInt(matches[1], 16) / 255.0; + result.green = parseInt(matches[2], 16) / 255.0; + result.blue = parseInt(matches[3], 16) / 255.0; + result.alpha = 1.0; + return result; + } - var scratch1 = new Cartesian3(); - var scratch2 = new Cartesian3(); + matches = rgbParenthesesMatcher.exec(color); + if (matches !== null) { + result.red = parseFloat(matches[1]) / ('%' === matches[1].substr(-1) ? 100.0 : 255.0); + result.green = parseFloat(matches[2]) / ('%' === matches[2].substr(-1) ? 100.0 : 255.0); + result.blue = parseFloat(matches[3]) / ('%' === matches[3].substr(-1) ? 100.0 : 255.0); + result.alpha = parseFloat(defaultValue(matches[4], '1.0')); + return result; + } - /** - * @private - */ - var PolylineVolumeGeometryLibrary = {}; - - var cartographic = new Cartographic(); - function scaleToSurface(positions, ellipsoid) { - var heights = new Array(positions.length); - for (var i = 0; i < positions.length; i++) { - var pos = positions[i]; - cartographic = ellipsoid.cartesianToCartographic(pos, cartographic); - heights[i] = cartographic.height; - positions[i] = ellipsoid.scaleToGeodeticSurface(pos, pos); - } - return heights; - } - - function subdivideHeights(points, h0, h1, granularity) { - var p0 = points[0]; - var p1 = points[1]; - var angleBetween = Cartesian3.angleBetween(p0, p1); - var numPoints = Math.ceil(angleBetween / granularity); - var heights = new Array(numPoints); - var i; - if (h0 === h1) { - for (i = 0; i < numPoints; i++) { - heights[i] = h0; - } - heights.push(h1); - return heights; - } - - var dHeight = h1 - h0; - var heightPerVertex = dHeight / (numPoints); - - for (i = 1; i < numPoints; i++) { - var h = h0 + i * heightPerVertex; - heights[i] = h; + matches = hslParenthesesMatcher.exec(color); + if (matches !== null) { + return Color.fromHsl(parseFloat(matches[1]) / 360.0, + parseFloat(matches[2]) / 100.0, + parseFloat(matches[3]) / 100.0, + parseFloat(defaultValue(matches[4], '1.0')), result); } - heights[0] = h0; - heights.push(h1); - return heights; - } - - var nextScratch = new Cartesian3(); - var prevScratch = new Cartesian3(); - - function computeRotationAngle(start, end, position, ellipsoid) { - var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); - var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, start, nextScratch), nextScratch); - var prev = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, end, prevScratch), prevScratch); - var angle = Cartesian2.angleBetween(next, prev); - - return (prev.x * next.y - prev.y * next.x >= 0.0) ? -angle : angle; - } - - var negativeX = new Cartesian3(-1, 0, 0); - var transform = new Matrix4(); - var translation = new Matrix4(); - var rotationZ = new Matrix3(); - var scaleMatrix = Matrix3.IDENTITY.clone(); - var westScratch = new Cartesian3(); - var finalPosScratch = new Cartesian4(); - var heightCartesian = new Cartesian3(); - function addPosition(center, left, shape, finalPositions, ellipsoid, height, xScalar, repeat) { - var west = westScratch; - var finalPosition = finalPosScratch; - transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, transform); - - west = Matrix4.multiplyByPointAsVector(transform, negativeX, west); - west = Cartesian3.normalize(west, west); - var angle = computeRotationAngle(west, left, center, ellipsoid); - rotationZ = Matrix3.fromRotationZ(angle, rotationZ); + result = undefined; + return result; + }; - heightCartesian.z = height; - transform = Matrix4.multiplyTransformation(transform, Matrix4.fromRotationTranslation(rotationZ, heightCartesian, translation), transform); - var scale = scaleMatrix; - scale[0] = xScalar; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + Color.packedLength = 4; - for (var j = 0; j < repeat; j++) { - for (var i = 0; i < shape.length; i += 3) { - finalPosition = Cartesian3.fromArray(shape, i, finalPosition); - finalPosition = Matrix3.multiplyByVector(scale, finalPosition, finalPosition); - finalPosition = Matrix4.multiplyByPoint(transform, finalPosition, finalPosition); - finalPositions.push(finalPosition.x, finalPosition.y, finalPosition.z); - } - } + /** + * Stores the provided instance into the provided array. + * + * @param {Color} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + Color.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + array[startingIndex++] = value.red; + array[startingIndex++] = value.green; + array[startingIndex++] = value.blue; + array[startingIndex] = value.alpha; - return finalPositions; - } + return array; + }; - var centerScratch = new Cartesian3(); - function addPositions(centers, left, shape, finalPositions, ellipsoid, heights, xScalar) { - for (var i = 0; i < centers.length; i += 3) { - var center = Cartesian3.fromArray(centers, i, centerScratch); - finalPositions = addPosition(center, left, shape, finalPositions, ellipsoid, heights[i / 3], xScalar, 1); + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Color} [result] The object into which to store the result. + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + */ + Color.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + if (!defined(result)) { + result = new Color(); } - return finalPositions; - } + result.red = array[startingIndex++]; + result.green = array[startingIndex++]; + result.blue = array[startingIndex++]; + result.alpha = array[startingIndex]; + return result; + }; - function convertShapeTo3DDuplicate(shape2D, boundingRectangle) { //orientate 2D shape to XZ plane center at (0, 0, 0), duplicate points - var length = shape2D.length; - var shape = new Array(length * 6); - var index = 0; - var xOffset = boundingRectangle.x + boundingRectangle.width / 2; - var yOffset = boundingRectangle.y + boundingRectangle.height / 2; + /** + * Converts a 'byte' color component in the range of 0 to 255 into + * a 'float' color component in the range of 0 to 1.0. + * + * @param {Number} number The number to be converted. + * @returns {Number} The converted number. + */ + Color.byteToFloat = function(number) { + return number / 255.0; + }; - var point = shape2D[0]; - shape[index++] = point.x - xOffset; - shape[index++] = 0.0; - shape[index++] = point.y - yOffset; - for (var i = 1; i < length; i++) { - point = shape2D[i]; - var x = point.x - xOffset; - var z = point.y - yOffset; - shape[index++] = x; - shape[index++] = 0.0; - shape[index++] = z; + /** + * Converts a 'float' color component in the range of 0 to 1.0 into + * a 'byte' color component in the range of 0 to 255. + * + * @param {Number} number The number to be converted. + * @returns {Number} The converted number. + */ + Color.floatToByte = function(number) { + return number === 1.0 ? 255.0 : (number * 256.0) | 0; + }; - shape[index++] = x; - shape[index++] = 0.0; - shape[index++] = z; + /** + * Duplicates a Color. + * + * @param {Color} color The Color to duplicate. + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The modified result parameter or a new instance if result was undefined. (Returns undefined if color is undefined) + */ + Color.clone = function(color, result) { + if (!defined(color)) { + return undefined; } - point = shape2D[0]; - shape[index++] = point.x - xOffset; - shape[index++] = 0.0; - shape[index++] = point.y - yOffset; - - return shape; - } - - function convertShapeTo3D(shape2D, boundingRectangle) { //orientate 2D shape to XZ plane center at (0, 0, 0) - var length = shape2D.length; - var shape = new Array(length * 3); - var index = 0; - var xOffset = boundingRectangle.x + boundingRectangle.width / 2; - var yOffset = boundingRectangle.y + boundingRectangle.height / 2; - - for (var i = 0; i < length; i++) { - shape[index++] = shape2D[i].x - xOffset; - shape[index++] = 0; - shape[index++] = shape2D[i].y - yOffset; + if (!defined(result)) { + return new Color(color.red, color.green, color.blue, color.alpha); } + result.red = color.red; + result.green = color.green; + result.blue = color.blue; + result.alpha = color.alpha; + return result; + }; - return shape; - } - - var quaterion = new Quaternion(); - var startPointScratch = new Cartesian3(); - var rotMatrix = new Matrix3(); - function computeRoundCorner(pivot, startPoint, endPoint, cornerType, leftIsOutside, ellipsoid, finalPositions, shape, height, duplicatePoints) { - var angle = Cartesian3.angleBetween(Cartesian3.subtract(startPoint, pivot, scratch1), Cartesian3.subtract(endPoint, pivot, scratch2)); - var granularity = (cornerType === CornerType.BEVELED) ? 0 : Math.ceil(angle / CesiumMath.toRadians(5)); + /** + * Returns true if the first Color equals the second color. + * + * @param {Color} left The first Color to compare for equality. + * @param {Color} right The second Color to compare for equality. + * @returns {Boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. + */ + Color.equals = function(left, right) { + return (left === right) || // + (defined(left) && // + defined(right) && // + left.red === right.red && // + left.green === right.green && // + left.blue === right.blue && // + left.alpha === right.alpha); + }; - var m; - if (leftIsOutside) { - m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(Cartesian3.negate(pivot, scratch1), angle / (granularity + 1), quaterion), rotMatrix); - } else { - m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(pivot, angle / (granularity + 1), quaterion), rotMatrix); - } + /** + * @private + */ + Color.equalsArray = function(color, array, offset) { + return color.red === array[offset] && + color.green === array[offset + 1] && + color.blue === array[offset + 2] && + color.alpha === array[offset + 3]; + }; - var left; - var surfacePoint; - startPoint = Cartesian3.clone(startPoint, startPointScratch); - if (granularity > 0) { - var repeat = duplicatePoints ? 2 : 1; - for (var i = 0; i < granularity; i++) { - startPoint = Matrix3.multiplyByVector(m, startPoint, startPoint); - left = Cartesian3.subtract(startPoint, pivot, scratch1); - left = Cartesian3.normalize(left, left); - if (!leftIsOutside) { - left = Cartesian3.negate(left, left); - } - surfacePoint = ellipsoid.scaleToGeodeticSurface(startPoint, scratch2); - finalPositions = addPosition(surfacePoint, left, shape, finalPositions, ellipsoid, height, 1, repeat); - } - } else { - left = Cartesian3.subtract(startPoint, pivot, scratch1); - left = Cartesian3.normalize(left, left); - if (!leftIsOutside) { - left = Cartesian3.negate(left, left); - } - surfacePoint = ellipsoid.scaleToGeodeticSurface(startPoint, scratch2); - finalPositions = addPosition(surfacePoint, left, shape, finalPositions, ellipsoid, height, 1, 1); + /** + * Returns a duplicate of a Color instance. + * + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The modified result parameter or a new instance if result was undefined. + */ + Color.prototype.clone = function(result) { + return Color.clone(this, result); + }; - endPoint = Cartesian3.clone(endPoint, startPointScratch); - left = Cartesian3.subtract(endPoint, pivot, scratch1); - left = Cartesian3.normalize(left, left); - if (!leftIsOutside) { - left = Cartesian3.negate(left, left); - } - surfacePoint = ellipsoid.scaleToGeodeticSurface(endPoint, scratch2); - finalPositions = addPosition(surfacePoint, left, shape, finalPositions, ellipsoid, height, 1, 1); - } + /** + * Returns true if this Color equals other. + * + * @param {Color} other The Color to compare for equality. + * @returns {Boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. + */ + Color.prototype.equals = function(other) { + return Color.equals(this, other); + }; - return finalPositions; - } + /** + * Returns <code>true</code> if this Color equals other componentwise within the specified epsilon. + * + * @param {Color} other The Color to compare for equality. + * @param {Number} [epsilon=0.0] The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if the Colors are equal within the specified epsilon; otherwise, <code>false</code>. + */ + Color.prototype.equalsEpsilon = function(other, epsilon) { + return (this === other) || // + ((defined(other)) && // + (Math.abs(this.red - other.red) <= epsilon) && // + (Math.abs(this.green - other.green) <= epsilon) && // + (Math.abs(this.blue - other.blue) <= epsilon) && // + (Math.abs(this.alpha - other.alpha) <= epsilon)); + }; - PolylineVolumeGeometryLibrary.removeDuplicatesFromShape = function(shapePositions) { - var length = shapePositions.length; - var cleanedPositions = []; - for (var i0 = length - 1, i1 = 0; i1 < length; i0 = i1++) { - var v0 = shapePositions[i0]; - var v1 = shapePositions[i1]; + /** + * Creates a string representing this Color in the format '(red, green, blue, alpha)'. + * + * @returns {String} A string representing this Color in the format '(red, green, blue, alpha)'. + */ + Color.prototype.toString = function() { + return '(' + this.red + ', ' + this.green + ', ' + this.blue + ', ' + this.alpha + ')'; + }; - if (!Cartesian2.equals(v0, v1)) { - cleanedPositions.push(v1); // Shallow copy! - } + /** + * Creates a string containing the CSS color value for this color. + * + * @returns {String} The CSS equivalent of this color. + * + * @see {@link http://www.w3.org/TR/css3-color/#rgba-color|CSS RGB or RGBA color values} + */ + Color.prototype.toCssColorString = function() { + var red = Color.floatToByte(this.red); + var green = Color.floatToByte(this.green); + var blue = Color.floatToByte(this.blue); + if (this.alpha === 1) { + return 'rgb(' + red + ',' + green + ',' + blue + ')'; } - - return cleanedPositions; + return 'rgba(' + red + ',' + green + ',' + blue + ',' + this.alpha + ')'; }; - PolylineVolumeGeometryLibrary.angleIsGreaterThanPi = function(forward, backward, position, ellipsoid) { - var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); - var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, forward, nextScratch), nextScratch); - var prev = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, backward, prevScratch), prevScratch); + /** + * Converts this color to an array of red, green, blue, and alpha values + * that are in the range of 0 to 255. + * + * @param {Number[]} [result] The array to store the result in, if undefined a new instance will be created. + * @returns {Number[]} The modified result parameter or a new instance if result was undefined. + */ + Color.prototype.toBytes = function(result) { + var red = Color.floatToByte(this.red); + var green = Color.floatToByte(this.green); + var blue = Color.floatToByte(this.blue); + var alpha = Color.floatToByte(this.alpha); - return ((prev.x * next.y) - (prev.y * next.x)) >= 0.0; + if (!defined(result)) { + return [red, green, blue, alpha]; + } + result[0] = red; + result[1] = green; + result[2] = blue; + result[3] = alpha; + return result; }; - var scratchForwardProjection = new Cartesian3(); - var scratchBackwardProjection = new Cartesian3(); + /** + * Converts this color to a single numeric unsigned 32-bit RGBA value, using the endianness + * of the system. + * + * @returns {Number} A single numeric unsigned 32-bit RGBA value. + * + * + * @example + * var rgba = Cesium.Color.BLUE.toRgba(); + * + * @see Color.fromRgba + */ + Color.prototype.toRgba = function() { + // scratchUint32Array and scratchUint8Array share an underlying array buffer + scratchUint8Array[0] = Color.floatToByte(this.red); + scratchUint8Array[1] = Color.floatToByte(this.green); + scratchUint8Array[2] = Color.floatToByte(this.blue); + scratchUint8Array[3] = Color.floatToByte(this.alpha); + return scratchUint32Array[0]; + }; - PolylineVolumeGeometryLibrary.computePositions = function(positions, shape2D, boundingRectangle, geometry, duplicatePoints) { - var ellipsoid = geometry._ellipsoid; - var heights = scaleToSurface(positions, ellipsoid); - var granularity = geometry._granularity; - var cornerType = geometry._cornerType; - var shapeForSides = duplicatePoints ? convertShapeTo3DDuplicate(shape2D, boundingRectangle) : convertShapeTo3D(shape2D, boundingRectangle); - var shapeForEnds = duplicatePoints ? convertShapeTo3D(shape2D, boundingRectangle) : undefined; - var heightOffset = boundingRectangle.height / 2; - var width = boundingRectangle.width / 2; - var length = positions.length; - var finalPositions = []; - var ends = duplicatePoints ? [] : undefined; + /** + * Brightens this color by the provided magnitude. + * + * @param {Number} magnitude A positive number indicating the amount to brighten. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + * + * @example + * var brightBlue = Cesium.Color.BLUE.brighten(0.5, new Cesium.Color()); + */ + Color.prototype.brighten = function(magnitude, result) { + Check.typeOf.number('magnitude', magnitude); + Check.typeOf.number.greaterThanOrEquals('magnitude', magnitude, 0.0); + Check.typeOf.object('result', result); + + magnitude = (1.0 - magnitude); + result.red = 1.0 - ((1.0 - this.red) * magnitude); + result.green = 1.0 - ((1.0 - this.green) * magnitude); + result.blue = 1.0 - ((1.0 - this.blue) * magnitude); + result.alpha = this.alpha; + return result; + }; - var forward = scratchCartesian1; - var backward = scratchCartesian2; - var cornerDirection = scratchCartesian3; - var surfaceNormal = scratchCartesian4; - var pivot = scratchCartesian5; - var start = scratchCartesian6; - var end = scratchCartesian7; - var left = scratchCartesian8; - var previousPosition = scratchCartesian9; + /** + * Darkens this color by the provided magnitude. + * + * @param {Number} magnitude A positive number indicating the amount to darken. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + * + * @example + * var darkBlue = Cesium.Color.BLUE.darken(0.5, new Cesium.Color()); + */ + Color.prototype.darken = function(magnitude, result) { + Check.typeOf.number('magnitude', magnitude); + Check.typeOf.number.greaterThanOrEquals('magnitude', magnitude, 0.0); + Check.typeOf.object('result', result); + + magnitude = (1.0 - magnitude); + result.red = this.red * magnitude; + result.green = this.green * magnitude; + result.blue = this.blue * magnitude; + result.alpha = this.alpha; + return result; + }; - var position = positions[0]; - var nextPosition = positions[1]; - surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, surfaceNormal); - forward = Cartesian3.subtract(nextPosition, position, forward); - forward = Cartesian3.normalize(forward, forward); - left = Cartesian3.cross(surfaceNormal, forward, left); - left = Cartesian3.normalize(left, left); - var h0 = heights[0]; - var h1 = heights[1]; - if (duplicatePoints) { - ends = addPosition(position, left, shapeForEnds, ends, ellipsoid, h0 + heightOffset, 1, 1); - } - previousPosition = Cartesian3.clone(position, previousPosition); - position = nextPosition; - backward = Cartesian3.negate(forward, backward); - var subdividedHeights; - var subdividedPositions; - for (var i = 1; i < length - 1; i++) { - var repeat = duplicatePoints ? 2 : 1; - nextPosition = positions[i + 1]; - forward = Cartesian3.subtract(nextPosition, position, forward); - forward = Cartesian3.normalize(forward, forward); - cornerDirection = Cartesian3.add(forward, backward, cornerDirection); - cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); - surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, surfaceNormal); + /** + * Creates a new Color that has the same red, green, and blue components + * as this Color, but with the specified alpha value. + * + * @param {Number} alpha The new alpha component. + * @param {Color} [result] The object onto which to store the result. + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + * + * @example var translucentRed = Cesium.Color.RED.withAlpha(0.9); + */ + Color.prototype.withAlpha = function(alpha, result) { + return Color.fromAlpha(this, alpha, result); + }; - var forwardProjection = Cartesian3.multiplyByScalar(surfaceNormal, Cartesian3.dot(forward, surfaceNormal), scratchForwardProjection); - Cartesian3.subtract(forward, forwardProjection, forwardProjection); - Cartesian3.normalize(forwardProjection, forwardProjection); + /** + * Computes the componentwise sum of two Colors. + * + * @param {Color} left The first Color. + * @param {Color} right The second Color. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.add = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.red = left.red + right.red; + result.green = left.green + right.green; + result.blue = left.blue + right.blue; + result.alpha = left.alpha + right.alpha; + return result; + }; - var backwardProjection = Cartesian3.multiplyByScalar(surfaceNormal, Cartesian3.dot(backward, surfaceNormal), scratchBackwardProjection); - Cartesian3.subtract(backward, backwardProjection, backwardProjection); - Cartesian3.normalize(backwardProjection, backwardProjection); + /** + * Computes the componentwise difference of two Colors. + * + * @param {Color} left The first Color. + * @param {Color} right The second Color. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.subtract = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.red = left.red - right.red; + result.green = left.green - right.green; + result.blue = left.blue - right.blue; + result.alpha = left.alpha - right.alpha; + return result; + }; - var doCorner = !CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(forwardProjection, backwardProjection)), 1.0, CesiumMath.EPSILON7); + /** + * Computes the componentwise product of two Colors. + * + * @param {Color} left The first Color. + * @param {Color} right The second Color. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.multiply = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.red = left.red * right.red; + result.green = left.green * right.green; + result.blue = left.blue * right.blue; + result.alpha = left.alpha * right.alpha; + return result; + }; - if (doCorner) { - cornerDirection = Cartesian3.cross(cornerDirection, surfaceNormal, cornerDirection); - cornerDirection = Cartesian3.cross(surfaceNormal, cornerDirection, cornerDirection); - cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); - var scalar = 1 / Math.max(0.25, (Cartesian3.magnitude(Cartesian3.cross(cornerDirection, backward, scratch1)))); - var leftIsOutside = PolylineVolumeGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); - if (leftIsOutside) { - pivot = Cartesian3.add(position, Cartesian3.multiplyByScalar(cornerDirection, scalar * width, cornerDirection), pivot); - start = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, width, start), start); - scratch2Array[0] = Cartesian3.clone(previousPosition, scratch2Array[0]); - scratch2Array[1] = Cartesian3.clone(start, scratch2Array[1]); - subdividedHeights = subdivideHeights(scratch2Array, h0 + heightOffset, h1 + heightOffset, granularity); - subdividedPositions = PolylinePipeline.generateArc({ - positions: scratch2Array, - granularity: granularity, - ellipsoid: ellipsoid - }); - finalPositions = addPositions(subdividedPositions, left, shapeForSides, finalPositions, ellipsoid, subdividedHeights, 1); - left = Cartesian3.cross(surfaceNormal, forward, left); - left = Cartesian3.normalize(left, left); - end = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, width, end), end); - if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { - computeRoundCorner(pivot, start, end, cornerType, leftIsOutside, ellipsoid, finalPositions, shapeForSides, h1 + heightOffset, duplicatePoints); - } else { - cornerDirection = Cartesian3.negate(cornerDirection, cornerDirection); - finalPositions = addPosition(position, cornerDirection, shapeForSides, finalPositions, ellipsoid, h1 + heightOffset, scalar, repeat); - } - previousPosition = Cartesian3.clone(end, previousPosition); - } else { - pivot = Cartesian3.add(position, Cartesian3.multiplyByScalar(cornerDirection, scalar * width, cornerDirection), pivot); - start = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, -width, start), start); - scratch2Array[0] = Cartesian3.clone(previousPosition, scratch2Array[0]); - scratch2Array[1] = Cartesian3.clone(start, scratch2Array[1]); - subdividedHeights = subdivideHeights(scratch2Array, h0 + heightOffset, h1 + heightOffset, granularity); - subdividedPositions = PolylinePipeline.generateArc({ - positions: scratch2Array, - granularity: granularity, - ellipsoid: ellipsoid - }); - finalPositions = addPositions(subdividedPositions, left, shapeForSides, finalPositions, ellipsoid, subdividedHeights, 1); - left = Cartesian3.cross(surfaceNormal, forward, left); - left = Cartesian3.normalize(left, left); - end = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, -width, end), end); - if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { - computeRoundCorner(pivot, start, end, cornerType, leftIsOutside, ellipsoid, finalPositions, shapeForSides, h1 + heightOffset, duplicatePoints); - } else { - finalPositions = addPosition(position, cornerDirection, shapeForSides, finalPositions, ellipsoid, h1 + heightOffset, scalar, repeat); - } - previousPosition = Cartesian3.clone(end, previousPosition); - } - backward = Cartesian3.negate(forward, backward); - } else { - finalPositions = addPosition(previousPosition, left, shapeForSides, finalPositions, ellipsoid, h0 + heightOffset, 1, 1); - previousPosition = position; - } - h0 = h1; - h1 = heights[i + 1]; - position = nextPosition; - } + /** + * Computes the componentwise quotient of two Colors. + * + * @param {Color} left The first Color. + * @param {Color} right The second Color. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.divide = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.red = left.red / right.red; + result.green = left.green / right.green; + result.blue = left.blue / right.blue; + result.alpha = left.alpha / right.alpha; + return result; + }; - scratch2Array[0] = Cartesian3.clone(previousPosition, scratch2Array[0]); - scratch2Array[1] = Cartesian3.clone(position, scratch2Array[1]); - subdividedHeights = subdivideHeights(scratch2Array, h0 + heightOffset, h1 + heightOffset, granularity); - subdividedPositions = PolylinePipeline.generateArc({ - positions: scratch2Array, - granularity: granularity, - ellipsoid: ellipsoid - }); - finalPositions = addPositions(subdividedPositions, left, shapeForSides, finalPositions, ellipsoid, subdividedHeights, 1); - if (duplicatePoints) { - ends = addPosition(position, left, shapeForEnds, ends, ellipsoid, h1 + heightOffset, 1, 1); - } + /** + * Computes the componentwise modulus of two Colors. + * + * @param {Color} left The first Color. + * @param {Color} right The second Color. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.mod = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result.red = left.red % right.red; + result.green = left.green % right.green; + result.blue = left.blue % right.blue; + result.alpha = left.alpha % right.alpha; + return result; + }; - length = finalPositions.length; - var posLength = duplicatePoints ? length + ends.length : length; - var combinedPositions = new Float64Array(posLength); - combinedPositions.set(finalPositions); - if (duplicatePoints) { - combinedPositions.set(ends, length); - } + /** + * Multiplies the provided Color componentwise by the provided scalar. + * + * @param {Color} color The Color to be scaled. + * @param {Number} scalar The scalar to multiply with. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.multiplyByScalar = function(color, scalar, result) { + Check.typeOf.object('color', color); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result.red = color.red * scalar; + result.green = color.green * scalar; + result.blue = color.blue * scalar; + result.alpha = color.alpha * scalar; + return result; + }; - return combinedPositions; + /** + * Divides the provided Color componentwise by the provided scalar. + * + * @param {Color} color The Color to be divided. + * @param {Number} scalar The scalar to divide with. + * @param {Color} result The object onto which to store the result. + * @returns {Color} The modified result parameter. + */ + Color.divideByScalar = function(color, scalar, result) { + Check.typeOf.object('color', color); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result.red = color.red / scalar; + result.green = color.green / scalar; + result.blue = color.blue / scalar; + result.alpha = color.alpha / scalar; + return result; }; - return PolylineVolumeGeometryLibrary; -}); + /** + * An immutable Color instance initialized to CSS color #F0F8FF + * <span class="colorSwath" style="background: #F0F8FF;"></span> + * + * @constant + * @type {Color} + */ + Color.ALICEBLUE = freezeObject(Color.fromCssColorString('#F0F8FF')); -define('Core/CorridorGeometryLibrary',[ - './Cartesian3', - './CornerType', - './defined', - './Math', - './Matrix3', - './PolylinePipeline', - './PolylineVolumeGeometryLibrary', - './Quaternion' - ], function( - Cartesian3, - CornerType, - defined, - CesiumMath, - Matrix3, - PolylinePipeline, - PolylineVolumeGeometryLibrary, - Quaternion) { - 'use strict'; + /** + * An immutable Color instance initialized to CSS color #FAEBD7 + * <span class="colorSwath" style="background: #FAEBD7;"></span> + * + * @constant + * @type {Color} + */ + Color.ANTIQUEWHITE = freezeObject(Color.fromCssColorString('#FAEBD7')); /** - * @private + * An immutable Color instance initialized to CSS color #00FFFF + * <span class="colorSwath" style="background: #00FFFF;"></span> + * + * @constant + * @type {Color} */ - var CorridorGeometryLibrary = {}; + Color.AQUA = freezeObject(Color.fromCssColorString('#00FFFF')); - var scratch1 = new Cartesian3(); - var scratch2 = new Cartesian3(); - var scratch3 = new Cartesian3(); - var scratch4 = new Cartesian3(); + /** + * An immutable Color instance initialized to CSS color #7FFFD4 + * <span class="colorSwath" style="background: #7FFFD4;"></span> + * + * @constant + * @type {Color} + */ + Color.AQUAMARINE = freezeObject(Color.fromCssColorString('#7FFFD4')); - var scaleArray2 = [new Cartesian3(), new Cartesian3()]; + /** + * An immutable Color instance initialized to CSS color #F0FFFF + * <span class="colorSwath" style="background: #F0FFFF;"></span> + * + * @constant + * @type {Color} + */ + Color.AZURE = freezeObject(Color.fromCssColorString('#F0FFFF')); - var cartesian1 = new Cartesian3(); - var cartesian2 = new Cartesian3(); - var cartesian3 = new Cartesian3(); - var cartesian4 = new Cartesian3(); - var cartesian5 = new Cartesian3(); - var cartesian6 = new Cartesian3(); - var cartesian7 = new Cartesian3(); - var cartesian8 = new Cartesian3(); - var cartesian9 = new Cartesian3(); - var cartesian10 = new Cartesian3(); + /** + * An immutable Color instance initialized to CSS color #F5F5DC + * <span class="colorSwath" style="background: #F5F5DC;"></span> + * + * @constant + * @type {Color} + */ + Color.BEIGE = freezeObject(Color.fromCssColorString('#F5F5DC')); - var quaterion = new Quaternion(); - var rotMatrix = new Matrix3(); - function computeRoundCorner(cornerPoint, startPoint, endPoint, cornerType, leftIsOutside) { - var angle = Cartesian3.angleBetween(Cartesian3.subtract(startPoint, cornerPoint, scratch1), Cartesian3.subtract(endPoint, cornerPoint, scratch2)); - var granularity = (cornerType === CornerType.BEVELED) ? 1 : Math.ceil(angle / CesiumMath.toRadians(5)) + 1; + /** + * An immutable Color instance initialized to CSS color #FFE4C4 + * <span class="colorSwath" style="background: #FFE4C4;"></span> + * + * @constant + * @type {Color} + */ + Color.BISQUE = freezeObject(Color.fromCssColorString('#FFE4C4')); - var size = granularity * 3; - var array = new Array(size); + /** + * An immutable Color instance initialized to CSS color #000000 + * <span class="colorSwath" style="background: #000000;"></span> + * + * @constant + * @type {Color} + */ + Color.BLACK = freezeObject(Color.fromCssColorString('#000000')); - array[size - 3] = endPoint.x; - array[size - 2] = endPoint.y; - array[size - 1] = endPoint.z; + /** + * An immutable Color instance initialized to CSS color #FFEBCD + * <span class="colorSwath" style="background: #FFEBCD;"></span> + * + * @constant + * @type {Color} + */ + Color.BLANCHEDALMOND = freezeObject(Color.fromCssColorString('#FFEBCD')); - var m; - if (leftIsOutside) { - m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(Cartesian3.negate(cornerPoint, scratch1), angle / granularity, quaterion), rotMatrix); - } else { - m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(cornerPoint, angle / granularity, quaterion), rotMatrix); - } + /** + * An immutable Color instance initialized to CSS color #0000FF + * <span class="colorSwath" style="background: #0000FF;"></span> + * + * @constant + * @type {Color} + */ + Color.BLUE = freezeObject(Color.fromCssColorString('#0000FF')); - var index = 0; - startPoint = Cartesian3.clone(startPoint, scratch1); - for (var i = 0; i < granularity; i++) { - startPoint = Matrix3.multiplyByVector(m, startPoint, startPoint); - array[index++] = startPoint.x; - array[index++] = startPoint.y; - array[index++] = startPoint.z; - } + /** + * An immutable Color instance initialized to CSS color #8A2BE2 + * <span class="colorSwath" style="background: #8A2BE2;"></span> + * + * @constant + * @type {Color} + */ + Color.BLUEVIOLET = freezeObject(Color.fromCssColorString('#8A2BE2')); - return array; - } + /** + * An immutable Color instance initialized to CSS color #A52A2A + * <span class="colorSwath" style="background: #A52A2A;"></span> + * + * @constant + * @type {Color} + */ + Color.BROWN = freezeObject(Color.fromCssColorString('#A52A2A')); - function addEndCaps(calculatedPositions) { - var cornerPoint = cartesian1; - var startPoint = cartesian2; - var endPoint = cartesian3; + /** + * An immutable Color instance initialized to CSS color #DEB887 + * <span class="colorSwath" style="background: #DEB887;"></span> + * + * @constant + * @type {Color} + */ + Color.BURLYWOOD = freezeObject(Color.fromCssColorString('#DEB887')); - var leftEdge = calculatedPositions[1]; - startPoint = Cartesian3.fromArray(calculatedPositions[1], leftEdge.length - 3, startPoint); - endPoint = Cartesian3.fromArray(calculatedPositions[0], 0, endPoint); - cornerPoint = Cartesian3.multiplyByScalar(Cartesian3.add(startPoint, endPoint, cornerPoint), 0.5, cornerPoint); - var firstEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false); + /** + * An immutable Color instance initialized to CSS color #5F9EA0 + * <span class="colorSwath" style="background: #5F9EA0;"></span> + * + * @constant + * @type {Color} + */ + Color.CADETBLUE = freezeObject(Color.fromCssColorString('#5F9EA0')); + /** + * An immutable Color instance initialized to CSS color #7FFF00 + * <span class="colorSwath" style="background: #7FFF00;"></span> + * + * @constant + * @type {Color} + */ + Color.CHARTREUSE = freezeObject(Color.fromCssColorString('#7FFF00')); - var length = calculatedPositions.length - 1; - var rightEdge = calculatedPositions[length - 1]; - leftEdge = calculatedPositions[length]; - startPoint = Cartesian3.fromArray(rightEdge, rightEdge.length - 3, startPoint); - endPoint = Cartesian3.fromArray(leftEdge, 0, endPoint); - cornerPoint = Cartesian3.multiplyByScalar(Cartesian3.add(startPoint, endPoint, cornerPoint), 0.5, cornerPoint); - var lastEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false); + /** + * An immutable Color instance initialized to CSS color #D2691E + * <span class="colorSwath" style="background: #D2691E;"></span> + * + * @constant + * @type {Color} + */ + Color.CHOCOLATE = freezeObject(Color.fromCssColorString('#D2691E')); - return [firstEndCap, lastEndCap]; - } + /** + * An immutable Color instance initialized to CSS color #FF7F50 + * <span class="colorSwath" style="background: #FF7F50;"></span> + * + * @constant + * @type {Color} + */ + Color.CORAL = freezeObject(Color.fromCssColorString('#FF7F50')); - function computeMiteredCorner(position, leftCornerDirection, lastPoint, leftIsOutside) { - var cornerPoint = scratch1; - if (leftIsOutside) { - cornerPoint = Cartesian3.add(position, leftCornerDirection, cornerPoint); - } else { - leftCornerDirection = Cartesian3.negate(leftCornerDirection, leftCornerDirection); - cornerPoint = Cartesian3.add(position, leftCornerDirection, cornerPoint); - } - return [cornerPoint.x, cornerPoint.y, cornerPoint.z, lastPoint.x, lastPoint.y, lastPoint.z]; - } + /** + * An immutable Color instance initialized to CSS color #6495ED + * <span class="colorSwath" style="background: #6495ED;"></span> + * + * @constant + * @type {Color} + */ + Color.CORNFLOWERBLUE = freezeObject(Color.fromCssColorString('#6495ED')); - function addShiftedPositions(positions, left, scalar, calculatedPositions) { - var rightPositions = new Array(positions.length); - var leftPositions = new Array(positions.length); - var scaledLeft = Cartesian3.multiplyByScalar(left, scalar, scratch1); - var scaledRight = Cartesian3.negate(scaledLeft, scratch2); - var rightIndex = 0; - var leftIndex = positions.length - 1; + /** + * An immutable Color instance initialized to CSS color #FFF8DC + * <span class="colorSwath" style="background: #FFF8DC;"></span> + * + * @constant + * @type {Color} + */ + Color.CORNSILK = freezeObject(Color.fromCssColorString('#FFF8DC')); - for (var i = 0; i < positions.length; i += 3) { - var pos = Cartesian3.fromArray(positions, i, scratch3); - var rightPos = Cartesian3.add(pos, scaledRight, scratch4); - rightPositions[rightIndex++] = rightPos.x; - rightPositions[rightIndex++] = rightPos.y; - rightPositions[rightIndex++] = rightPos.z; + /** + * An immutable Color instance initialized to CSS color #DC143C + * <span class="colorSwath" style="background: #DC143C;"></span> + * + * @constant + * @type {Color} + */ + Color.CRIMSON = freezeObject(Color.fromCssColorString('#DC143C')); - var leftPos = Cartesian3.add(pos, scaledLeft, scratch4); - leftPositions[leftIndex--] = leftPos.z; - leftPositions[leftIndex--] = leftPos.y; - leftPositions[leftIndex--] = leftPos.x; - } - calculatedPositions.push(rightPositions, leftPositions); + /** + * An immutable Color instance initialized to CSS color #00FFFF + * <span class="colorSwath" style="background: #00FFFF;"></span> + * + * @constant + * @type {Color} + */ + Color.CYAN = freezeObject(Color.fromCssColorString('#00FFFF')); - return calculatedPositions; - } + /** + * An immutable Color instance initialized to CSS color #00008B + * <span class="colorSwath" style="background: #00008B;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKBLUE = freezeObject(Color.fromCssColorString('#00008B')); /** - * @private + * An immutable Color instance initialized to CSS color #008B8B + * <span class="colorSwath" style="background: #008B8B;"></span> + * + * @constant + * @type {Color} */ - CorridorGeometryLibrary.addAttribute = function(attribute, value, front, back) { - var x = value.x; - var y = value.y; - var z = value.z; - if (defined(front)) { - attribute[front] = x; - attribute[front + 1] = y; - attribute[front + 2] = z; - } - if (defined(back)) { - attribute[back] = z; - attribute[back - 1] = y; - attribute[back - 2] = x; - } - }; - - var scratchForwardProjection = new Cartesian3(); - var scratchBackwardProjection = new Cartesian3(); + Color.DARKCYAN = freezeObject(Color.fromCssColorString('#008B8B')); /** - * @private + * An immutable Color instance initialized to CSS color #B8860B + * <span class="colorSwath" style="background: #B8860B;"></span> + * + * @constant + * @type {Color} */ - CorridorGeometryLibrary.computePositions = function(params) { - var granularity = params.granularity; - var positions = params.positions; - var ellipsoid = params.ellipsoid; - var width = params.width / 2; - var cornerType = params.cornerType; - var saveAttributes = params.saveAttributes; - var normal = cartesian1; - var forward = cartesian2; - var backward = cartesian3; - var left = cartesian4; - var cornerDirection = cartesian5; - var startPoint = cartesian6; - var previousPos = cartesian7; - var rightPos = cartesian8; - var leftPos = cartesian9; - var center = cartesian10; - var calculatedPositions = []; - var calculatedLefts = (saveAttributes) ? [] : undefined; - var calculatedNormals = (saveAttributes) ? [] : undefined; - var position = positions[0]; //add first point - var nextPosition = positions[1]; - - forward = Cartesian3.normalize(Cartesian3.subtract(nextPosition, position, forward), forward); - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - left = Cartesian3.normalize(Cartesian3.cross(normal, forward, left), left); - if (saveAttributes) { - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - } - previousPos = Cartesian3.clone(position, previousPos); - position = nextPosition; - backward = Cartesian3.negate(forward, backward); - - var subdividedPositions; - var corners = []; - var i; - var length = positions.length; - for (i = 1; i < length - 1; i++) { // add middle points and corners - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - nextPosition = positions[i + 1]; - forward = Cartesian3.normalize(Cartesian3.subtract(nextPosition, position, forward), forward); - cornerDirection = Cartesian3.normalize(Cartesian3.add(forward, backward, cornerDirection), cornerDirection); + Color.DARKGOLDENROD = freezeObject(Color.fromCssColorString('#B8860B')); - var forwardProjection = Cartesian3.multiplyByScalar(normal, Cartesian3.dot(forward, normal), scratchForwardProjection); - Cartesian3.subtract(forward, forwardProjection, forwardProjection); - Cartesian3.normalize(forwardProjection, forwardProjection); + /** + * An immutable Color instance initialized to CSS color #A9A9A9 + * <span class="colorSwath" style="background: #A9A9A9;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKGRAY = freezeObject(Color.fromCssColorString('#A9A9A9')); - var backwardProjection = Cartesian3.multiplyByScalar(normal, Cartesian3.dot(backward, normal), scratchBackwardProjection); - Cartesian3.subtract(backward, backwardProjection, backwardProjection); - Cartesian3.normalize(backwardProjection, backwardProjection); + /** + * An immutable Color instance initialized to CSS color #006400 + * <span class="colorSwath" style="background: #006400;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKGREEN = freezeObject(Color.fromCssColorString('#006400')); - var doCorner = !CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(forwardProjection, backwardProjection)), 1.0, CesiumMath.EPSILON7); + /** + * An immutable Color instance initialized to CSS color #A9A9A9 + * <span class="colorSwath" style="background: #A9A9A9;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKGREY = Color.DARKGRAY; - if (doCorner) { - cornerDirection = Cartesian3.cross(cornerDirection, normal, cornerDirection); - cornerDirection = Cartesian3.cross(normal, cornerDirection, cornerDirection); - cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); - var scalar = width / Math.max(0.25, Cartesian3.magnitude(Cartesian3.cross(cornerDirection, backward, scratch1))); - var leftIsOutside = PolylineVolumeGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); - cornerDirection = Cartesian3.multiplyByScalar(cornerDirection, scalar, cornerDirection); - if (leftIsOutside) { - rightPos = Cartesian3.add(position, cornerDirection, rightPos); - center = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width, center), center); - leftPos = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width * 2, leftPos), leftPos); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); - subdividedPositions = PolylinePipeline.generateArc({ - positions: scaleArray2, - granularity: granularity, - ellipsoid: ellipsoid - }); - calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - if (saveAttributes) { - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - } - startPoint = Cartesian3.clone(leftPos, startPoint); - left = Cartesian3.normalize(Cartesian3.cross(normal, forward, left), left); - leftPos = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width * 2, leftPos), leftPos); - previousPos = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width, previousPos), previousPos); - if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { - corners.push({ - leftPositions : computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside) - }); - } else { - corners.push({ - leftPositions : computeMiteredCorner(position, Cartesian3.negate(cornerDirection, cornerDirection), leftPos, leftIsOutside) - }); - } - } else { - leftPos = Cartesian3.add(position, cornerDirection, leftPos); - center = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width, center), center), center); - rightPos = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width * 2, rightPos), rightPos), rightPos); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); - subdividedPositions = PolylinePipeline.generateArc({ - positions: scaleArray2, - granularity: granularity, - ellipsoid: ellipsoid - }); - calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - if (saveAttributes) { - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - } - startPoint = Cartesian3.clone(rightPos, startPoint); - left = Cartesian3.normalize(Cartesian3.cross(normal, forward, left), left); - rightPos = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width * 2, rightPos), rightPos), rightPos); - previousPos = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width, previousPos), previousPos), previousPos); - if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { - corners.push({ - rightPositions : computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside) - }); - } else { - corners.push({ - rightPositions : computeMiteredCorner(position, cornerDirection, rightPos, leftIsOutside) - }); - } - } - backward = Cartesian3.negate(forward, backward); - } - position = nextPosition; - } + /** + * An immutable Color instance initialized to CSS color #BDB76B + * <span class="colorSwath" style="background: #BDB76B;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKKHAKI = freezeObject(Color.fromCssColorString('#BDB76B')); - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(position, scaleArray2[1]); - subdividedPositions = PolylinePipeline.generateArc({ - positions: scaleArray2, - granularity: granularity, - ellipsoid: ellipsoid - }); - calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - if (saveAttributes) { - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - } + /** + * An immutable Color instance initialized to CSS color #8B008B + * <span class="colorSwath" style="background: #8B008B;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKMAGENTA = freezeObject(Color.fromCssColorString('#8B008B')); - var endPositions; - if (cornerType === CornerType.ROUNDED) { - endPositions = addEndCaps(calculatedPositions); - } + /** + * An immutable Color instance initialized to CSS color #556B2F + * <span class="colorSwath" style="background: #556B2F;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKOLIVEGREEN = freezeObject(Color.fromCssColorString('#556B2F')); - return { - positions : calculatedPositions, - corners : corners, - lefts : calculatedLefts, - normals : calculatedNormals, - endPositions : endPositions - }; - }; + /** + * An immutable Color instance initialized to CSS color #FF8C00 + * <span class="colorSwath" style="background: #FF8C00;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKORANGE = freezeObject(Color.fromCssColorString('#FF8C00')); - return CorridorGeometryLibrary; -}); + /** + * An immutable Color instance initialized to CSS color #9932CC + * <span class="colorSwath" style="background: #9932CC;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKORCHID = freezeObject(Color.fromCssColorString('#9932CC')); -define('ThirdParty/earcut-2.1.1',[], function() { - 'use strict'; + /** + * An immutable Color instance initialized to CSS color #8B0000 + * <span class="colorSwath" style="background: #8B0000;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKRED = freezeObject(Color.fromCssColorString('#8B0000')); -function earcut(data, holeIndices, dim) { + /** + * An immutable Color instance initialized to CSS color #E9967A + * <span class="colorSwath" style="background: #E9967A;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKSALMON = freezeObject(Color.fromCssColorString('#E9967A')); - dim = dim || 2; + /** + * An immutable Color instance initialized to CSS color #8FBC8F + * <span class="colorSwath" style="background: #8FBC8F;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKSEAGREEN = freezeObject(Color.fromCssColorString('#8FBC8F')); - var hasHoles = holeIndices && holeIndices.length, - outerLen = hasHoles ? holeIndices[0] * dim : data.length, - outerNode = linkedList(data, 0, outerLen, dim, true), - triangles = []; + /** + * An immutable Color instance initialized to CSS color #483D8B + * <span class="colorSwath" style="background: #483D8B;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKSLATEBLUE = freezeObject(Color.fromCssColorString('#483D8B')); - if (!outerNode) return triangles; + /** + * An immutable Color instance initialized to CSS color #2F4F4F + * <span class="colorSwath" style="background: #2F4F4F;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKSLATEGRAY = freezeObject(Color.fromCssColorString('#2F4F4F')); - var minX, minY, maxX, maxY, x, y, size; + /** + * An immutable Color instance initialized to CSS color #2F4F4F + * <span class="colorSwath" style="background: #2F4F4F;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKSLATEGREY = Color.DARKSLATEGRAY; - if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); + /** + * An immutable Color instance initialized to CSS color #00CED1 + * <span class="colorSwath" style="background: #00CED1;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKTURQUOISE = freezeObject(Color.fromCssColorString('#00CED1')); - // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - if (data.length > 80 * dim) { - minX = maxX = data[0]; - minY = maxY = data[1]; + /** + * An immutable Color instance initialized to CSS color #9400D3 + * <span class="colorSwath" style="background: #9400D3;"></span> + * + * @constant + * @type {Color} + */ + Color.DARKVIOLET = freezeObject(Color.fromCssColorString('#9400D3')); - for (var i = dim; i < outerLen; i += dim) { - x = data[i]; - y = data[i + 1]; - if (x < minX) minX = x; - if (y < minY) minY = y; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - } + /** + * An immutable Color instance initialized to CSS color #FF1493 + * <span class="colorSwath" style="background: #FF1493;"></span> + * + * @constant + * @type {Color} + */ + Color.DEEPPINK = freezeObject(Color.fromCssColorString('#FF1493')); - // minX, minY and size are later used to transform coords into integers for z-order calculation - size = Math.max(maxX - minX, maxY - minY); - } + /** + * An immutable Color instance initialized to CSS color #00BFFF + * <span class="colorSwath" style="background: #00BFFF;"></span> + * + * @constant + * @type {Color} + */ + Color.DEEPSKYBLUE = freezeObject(Color.fromCssColorString('#00BFFF')); - earcutLinked(outerNode, triangles, dim, minX, minY, size); + /** + * An immutable Color instance initialized to CSS color #696969 + * <span class="colorSwath" style="background: #696969;"></span> + * + * @constant + * @type {Color} + */ + Color.DIMGRAY = freezeObject(Color.fromCssColorString('#696969')); - return triangles; -} + /** + * An immutable Color instance initialized to CSS color #696969 + * <span class="colorSwath" style="background: #696969;"></span> + * + * @constant + * @type {Color} + */ + Color.DIMGREY = Color.DIMGRAY; -// create a circular doubly linked list from polygon points in the specified winding order -function linkedList(data, start, end, dim, clockwise) { - var i, last; + /** + * An immutable Color instance initialized to CSS color #1E90FF + * <span class="colorSwath" style="background: #1E90FF;"></span> + * + * @constant + * @type {Color} + */ + Color.DODGERBLUE = freezeObject(Color.fromCssColorString('#1E90FF')); - if (clockwise === (signedArea(data, start, end, dim) > 0)) { - for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); - } else { - for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); - } + /** + * An immutable Color instance initialized to CSS color #B22222 + * <span class="colorSwath" style="background: #B22222;"></span> + * + * @constant + * @type {Color} + */ + Color.FIREBRICK = freezeObject(Color.fromCssColorString('#B22222')); - if (last && equals(last, last.next)) { - removeNode(last); - last = last.next; - } + /** + * An immutable Color instance initialized to CSS color #FFFAF0 + * <span class="colorSwath" style="background: #FFFAF0;"></span> + * + * @constant + * @type {Color} + */ + Color.FLORALWHITE = freezeObject(Color.fromCssColorString('#FFFAF0')); - return last; -} + /** + * An immutable Color instance initialized to CSS color #228B22 + * <span class="colorSwath" style="background: #228B22;"></span> + * + * @constant + * @type {Color} + */ + Color.FORESTGREEN = freezeObject(Color.fromCssColorString('#228B22')); -// eliminate colinear or duplicate points -function filterPoints(start, end) { - if (!start) return start; - if (!end) end = start; + /** + * An immutable Color instance initialized to CSS color #FF00FF + * <span class="colorSwath" style="background: #FF00FF;"></span> + * + * @constant + * @type {Color} + */ + Color.FUCHSIA = freezeObject(Color.fromCssColorString('#FF00FF')); - var p = start, - again; - do { - again = false; + /** + * An immutable Color instance initialized to CSS color #DCDCDC + * <span class="colorSwath" style="background: #DCDCDC;"></span> + * + * @constant + * @type {Color} + */ + Color.GAINSBORO = freezeObject(Color.fromCssColorString('#DCDCDC')); - if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { - removeNode(p); - p = end = p.prev; - if (p === p.next) return null; - again = true; + /** + * An immutable Color instance initialized to CSS color #F8F8FF + * <span class="colorSwath" style="background: #F8F8FF;"></span> + * + * @constant + * @type {Color} + */ + Color.GHOSTWHITE = freezeObject(Color.fromCssColorString('#F8F8FF')); - } else { - p = p.next; - } - } while (again || p !== end); + /** + * An immutable Color instance initialized to CSS color #FFD700 + * <span class="colorSwath" style="background: #FFD700;"></span> + * + * @constant + * @type {Color} + */ + Color.GOLD = freezeObject(Color.fromCssColorString('#FFD700')); - return end; -} + /** + * An immutable Color instance initialized to CSS color #DAA520 + * <span class="colorSwath" style="background: #DAA520;"></span> + * + * @constant + * @type {Color} + */ + Color.GOLDENROD = freezeObject(Color.fromCssColorString('#DAA520')); -// main ear slicing loop which triangulates a polygon (given as a linked list) -function earcutLinked(ear, triangles, dim, minX, minY, size, pass) { - if (!ear) return; + /** + * An immutable Color instance initialized to CSS color #808080 + * <span class="colorSwath" style="background: #808080;"></span> + * + * @constant + * @type {Color} + */ + Color.GRAY = freezeObject(Color.fromCssColorString('#808080')); - // interlink polygon nodes in z-order - if (!pass && size) indexCurve(ear, minX, minY, size); + /** + * An immutable Color instance initialized to CSS color #008000 + * <span class="colorSwath" style="background: #008000;"></span> + * + * @constant + * @type {Color} + */ + Color.GREEN = freezeObject(Color.fromCssColorString('#008000')); - var stop = ear, - prev, next; + /** + * An immutable Color instance initialized to CSS color #ADFF2F + * <span class="colorSwath" style="background: #ADFF2F;"></span> + * + * @constant + * @type {Color} + */ + Color.GREENYELLOW = freezeObject(Color.fromCssColorString('#ADFF2F')); - // iterate through ears, slicing them one by one - while (ear.prev !== ear.next) { - prev = ear.prev; - next = ear.next; + /** + * An immutable Color instance initialized to CSS color #808080 + * <span class="colorSwath" style="background: #808080;"></span> + * + * @constant + * @type {Color} + */ + Color.GREY = Color.GRAY; - if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) { - // cut off the triangle - triangles.push(prev.i / dim); - triangles.push(ear.i / dim); - triangles.push(next.i / dim); + /** + * An immutable Color instance initialized to CSS color #F0FFF0 + * <span class="colorSwath" style="background: #F0FFF0;"></span> + * + * @constant + * @type {Color} + */ + Color.HONEYDEW = freezeObject(Color.fromCssColorString('#F0FFF0')); - removeNode(ear); + /** + * An immutable Color instance initialized to CSS color #FF69B4 + * <span class="colorSwath" style="background: #FF69B4;"></span> + * + * @constant + * @type {Color} + */ + Color.HOTPINK = freezeObject(Color.fromCssColorString('#FF69B4')); - // skipping the next vertice leads to less sliver triangles - ear = next.next; - stop = next.next; + /** + * An immutable Color instance initialized to CSS color #CD5C5C + * <span class="colorSwath" style="background: #CD5C5C;"></span> + * + * @constant + * @type {Color} + */ + Color.INDIANRED = freezeObject(Color.fromCssColorString('#CD5C5C')); - continue; - } + /** + * An immutable Color instance initialized to CSS color #4B0082 + * <span class="colorSwath" style="background: #4B0082;"></span> + * + * @constant + * @type {Color} + */ + Color.INDIGO = freezeObject(Color.fromCssColorString('#4B0082')); - ear = next; + /** + * An immutable Color instance initialized to CSS color #FFFFF0 + * <span class="colorSwath" style="background: #FFFFF0;"></span> + * + * @constant + * @type {Color} + */ + Color.IVORY = freezeObject(Color.fromCssColorString('#FFFFF0')); - // if we looped through the whole remaining polygon and can't find any more ears - if (ear === stop) { - // try filtering points and slicing again - if (!pass) { - earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1); + /** + * An immutable Color instance initialized to CSS color #F0E68C + * <span class="colorSwath" style="background: #F0E68C;"></span> + * + * @constant + * @type {Color} + */ + Color.KHAKI = freezeObject(Color.fromCssColorString('#F0E68C')); - // if this didn't work, try curing all small self-intersections locally - } else if (pass === 1) { - ear = cureLocalIntersections(ear, triangles, dim); - earcutLinked(ear, triangles, dim, minX, minY, size, 2); + /** + * An immutable Color instance initialized to CSS color #E6E6FA + * <span class="colorSwath" style="background: #E6E6FA;"></span> + * + * @constant + * @type {Color} + */ + Color.LAVENDER = freezeObject(Color.fromCssColorString('#E6E6FA')); - // as a last resort, try splitting the remaining polygon into two - } else if (pass === 2) { - splitEarcut(ear, triangles, dim, minX, minY, size); - } + /** + * An immutable Color instance initialized to CSS color #FFF0F5 + * <span class="colorSwath" style="background: #FFF0F5;"></span> + * + * @constant + * @type {Color} + */ + Color.LAVENDAR_BLUSH = freezeObject(Color.fromCssColorString('#FFF0F5')); - break; - } - } -} + /** + * An immutable Color instance initialized to CSS color #7CFC00 + * <span class="colorSwath" style="background: #7CFC00;"></span> + * + * @constant + * @type {Color} + */ + Color.LAWNGREEN = freezeObject(Color.fromCssColorString('#7CFC00')); -// check whether a polygon node forms a valid ear with adjacent nodes -function isEar(ear) { - var a = ear.prev, - b = ear, - c = ear.next; + /** + * An immutable Color instance initialized to CSS color #FFFACD + * <span class="colorSwath" style="background: #FFFACD;"></span> + * + * @constant + * @type {Color} + */ + Color.LEMONCHIFFON = freezeObject(Color.fromCssColorString('#FFFACD')); - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + /** + * An immutable Color instance initialized to CSS color #ADD8E6 + * <span class="colorSwath" style="background: #ADD8E6;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTBLUE = freezeObject(Color.fromCssColorString('#ADD8E6')); - // now make sure we don't have other points inside the potential ear - var p = ear.next.next; + /** + * An immutable Color instance initialized to CSS color #F08080 + * <span class="colorSwath" style="background: #F08080;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTCORAL = freezeObject(Color.fromCssColorString('#F08080')); - while (p !== ear.prev) { - if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && - area(p.prev, p, p.next) >= 0) return false; - p = p.next; - } + /** + * An immutable Color instance initialized to CSS color #E0FFFF + * <span class="colorSwath" style="background: #E0FFFF;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTCYAN = freezeObject(Color.fromCssColorString('#E0FFFF')); - return true; -} + /** + * An immutable Color instance initialized to CSS color #FAFAD2 + * <span class="colorSwath" style="background: #FAFAD2;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTGOLDENRODYELLOW = freezeObject(Color.fromCssColorString('#FAFAD2')); -function isEarHashed(ear, minX, minY, size) { - var a = ear.prev, - b = ear, - c = ear.next; + /** + * An immutable Color instance initialized to CSS color #D3D3D3 + * <span class="colorSwath" style="background: #D3D3D3;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTGRAY = freezeObject(Color.fromCssColorString('#D3D3D3')); - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + /** + * An immutable Color instance initialized to CSS color #90EE90 + * <span class="colorSwath" style="background: #90EE90;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTGREEN = freezeObject(Color.fromCssColorString('#90EE90')); - // triangle bbox; min & max are calculated like this for speed - var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), - minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), - maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), - maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); + /** + * An immutable Color instance initialized to CSS color #D3D3D3 + * <span class="colorSwath" style="background: #D3D3D3;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTGREY = Color.LIGHTGRAY; - // z-order range for the current triangle bbox; - var minZ = zOrder(minTX, minTY, minX, minY, size), - maxZ = zOrder(maxTX, maxTY, minX, minY, size); + /** + * An immutable Color instance initialized to CSS color #FFB6C1 + * <span class="colorSwath" style="background: #FFB6C1;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTPINK = freezeObject(Color.fromCssColorString('#FFB6C1')); - // first look for points inside the triangle in increasing z-order - var p = ear.nextZ; + /** + * An immutable Color instance initialized to CSS color #20B2AA + * <span class="colorSwath" style="background: #20B2AA;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTSEAGREEN = freezeObject(Color.fromCssColorString('#20B2AA')); - while (p && p.z <= maxZ) { - if (p !== ear.prev && p !== ear.next && - pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && - area(p.prev, p, p.next) >= 0) return false; - p = p.nextZ; - } + /** + * An immutable Color instance initialized to CSS color #87CEFA + * <span class="colorSwath" style="background: #87CEFA;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTSKYBLUE = freezeObject(Color.fromCssColorString('#87CEFA')); - // then look for points in decreasing z-order - p = ear.prevZ; + /** + * An immutable Color instance initialized to CSS color #778899 + * <span class="colorSwath" style="background: #778899;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTSLATEGRAY = freezeObject(Color.fromCssColorString('#778899')); - while (p && p.z >= minZ) { - if (p !== ear.prev && p !== ear.next && - pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && - area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; - } + /** + * An immutable Color instance initialized to CSS color #778899 + * <span class="colorSwath" style="background: #778899;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTSLATEGREY = Color.LIGHTSLATEGRAY; - return true; -} + /** + * An immutable Color instance initialized to CSS color #B0C4DE + * <span class="colorSwath" style="background: #B0C4DE;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTSTEELBLUE = freezeObject(Color.fromCssColorString('#B0C4DE')); -// go through all polygon nodes and cure small local self-intersections -function cureLocalIntersections(start, triangles, dim) { - var p = start; - do { - var a = p.prev, - b = p.next.next; + /** + * An immutable Color instance initialized to CSS color #FFFFE0 + * <span class="colorSwath" style="background: #FFFFE0;"></span> + * + * @constant + * @type {Color} + */ + Color.LIGHTYELLOW = freezeObject(Color.fromCssColorString('#FFFFE0')); - if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + /** + * An immutable Color instance initialized to CSS color #00FF00 + * <span class="colorSwath" style="background: #00FF00;"></span> + * + * @constant + * @type {Color} + */ + Color.LIME = freezeObject(Color.fromCssColorString('#00FF00')); - triangles.push(a.i / dim); - triangles.push(p.i / dim); - triangles.push(b.i / dim); + /** + * An immutable Color instance initialized to CSS color #32CD32 + * <span class="colorSwath" style="background: #32CD32;"></span> + * + * @constant + * @type {Color} + */ + Color.LIMEGREEN = freezeObject(Color.fromCssColorString('#32CD32')); - // remove two nodes involved - removeNode(p); - removeNode(p.next); + /** + * An immutable Color instance initialized to CSS color #FAF0E6 + * <span class="colorSwath" style="background: #FAF0E6;"></span> + * + * @constant + * @type {Color} + */ + Color.LINEN = freezeObject(Color.fromCssColorString('#FAF0E6')); - p = start = b; - } - p = p.next; - } while (p !== start); + /** + * An immutable Color instance initialized to CSS color #FF00FF + * <span class="colorSwath" style="background: #FF00FF;"></span> + * + * @constant + * @type {Color} + */ + Color.MAGENTA = freezeObject(Color.fromCssColorString('#FF00FF')); - return p; -} + /** + * An immutable Color instance initialized to CSS color #800000 + * <span class="colorSwath" style="background: #800000;"></span> + * + * @constant + * @type {Color} + */ + Color.MAROON = freezeObject(Color.fromCssColorString('#800000')); -// try splitting polygon into two and triangulate them independently -function splitEarcut(start, triangles, dim, minX, minY, size) { - // look for a valid diagonal that divides the polygon into two - var a = start; - do { - var b = a.next.next; - while (b !== a.prev) { - if (a.i !== b.i && isValidDiagonal(a, b)) { - // split the polygon in two by the diagonal - var c = splitPolygon(a, b); + /** + * An immutable Color instance initialized to CSS color #66CDAA + * <span class="colorSwath" style="background: #66CDAA;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMAQUAMARINE = freezeObject(Color.fromCssColorString('#66CDAA')); - // filter colinear points around the cuts - a = filterPoints(a, a.next); - c = filterPoints(c, c.next); + /** + * An immutable Color instance initialized to CSS color #0000CD + * <span class="colorSwath" style="background: #0000CD;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMBLUE = freezeObject(Color.fromCssColorString('#0000CD')); - // run earcut on each half - earcutLinked(a, triangles, dim, minX, minY, size); - earcutLinked(c, triangles, dim, minX, minY, size); - return; - } - b = b.next; - } - a = a.next; - } while (a !== start); -} + /** + * An immutable Color instance initialized to CSS color #BA55D3 + * <span class="colorSwath" style="background: #BA55D3;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMORCHID = freezeObject(Color.fromCssColorString('#BA55D3')); -// link every hole into the outer loop, producing a single-ring polygon without holes -function eliminateHoles(data, holeIndices, outerNode, dim) { - var queue = [], - i, len, start, end, list; + /** + * An immutable Color instance initialized to CSS color #9370DB + * <span class="colorSwath" style="background: #9370DB;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMPURPLE = freezeObject(Color.fromCssColorString('#9370DB')); - for (i = 0, len = holeIndices.length; i < len; i++) { - start = holeIndices[i] * dim; - end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; - list = linkedList(data, start, end, dim, false); - if (list === list.next) list.steiner = true; - queue.push(getLeftmost(list)); - } + /** + * An immutable Color instance initialized to CSS color #3CB371 + * <span class="colorSwath" style="background: #3CB371;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMSEAGREEN = freezeObject(Color.fromCssColorString('#3CB371')); - queue.sort(compareX); + /** + * An immutable Color instance initialized to CSS color #7B68EE + * <span class="colorSwath" style="background: #7B68EE;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMSLATEBLUE = freezeObject(Color.fromCssColorString('#7B68EE')); - // process holes from left to right - for (i = 0; i < queue.length; i++) { - eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode.next); - } + /** + * An immutable Color instance initialized to CSS color #00FA9A + * <span class="colorSwath" style="background: #00FA9A;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMSPRINGGREEN = freezeObject(Color.fromCssColorString('#00FA9A')); - return outerNode; -} + /** + * An immutable Color instance initialized to CSS color #48D1CC + * <span class="colorSwath" style="background: #48D1CC;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMTURQUOISE = freezeObject(Color.fromCssColorString('#48D1CC')); -function compareX(a, b) { - return a.x - b.x; -} + /** + * An immutable Color instance initialized to CSS color #C71585 + * <span class="colorSwath" style="background: #C71585;"></span> + * + * @constant + * @type {Color} + */ + Color.MEDIUMVIOLETRED = freezeObject(Color.fromCssColorString('#C71585')); -// find a bridge between vertices that connects hole with an outer ring and and link it -function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); - if (outerNode) { - var b = splitPolygon(outerNode, hole); - filterPoints(b, b.next); - } -} + /** + * An immutable Color instance initialized to CSS color #191970 + * <span class="colorSwath" style="background: #191970;"></span> + * + * @constant + * @type {Color} + */ + Color.MIDNIGHTBLUE = freezeObject(Color.fromCssColorString('#191970')); -// David Eberly's algorithm for finding a bridge between hole and outer polygon -function findHoleBridge(hole, outerNode) { - var p = outerNode, - hx = hole.x, - hy = hole.y, - qx = -Infinity, - m; + /** + * An immutable Color instance initialized to CSS color #F5FFFA + * <span class="colorSwath" style="background: #F5FFFA;"></span> + * + * @constant + * @type {Color} + */ + Color.MINTCREAM = freezeObject(Color.fromCssColorString('#F5FFFA')); - // find a segment intersected by a ray from the hole's leftmost point to the left; - // segment's endpoint with lesser x will be potential connection point - do { - if (hy <= p.y && hy >= p.next.y) { - var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); - if (x <= hx && x > qx) { - qx = x; - if (x === hx) { - if (hy === p.y) return p; - if (hy === p.next.y) return p.next; - } - m = p.x < p.next.x ? p : p.next; - } - } - p = p.next; - } while (p !== outerNode); + /** + * An immutable Color instance initialized to CSS color #FFE4E1 + * <span class="colorSwath" style="background: #FFE4E1;"></span> + * + * @constant + * @type {Color} + */ + Color.MISTYROSE = freezeObject(Color.fromCssColorString('#FFE4E1')); - if (!m) return null; + /** + * An immutable Color instance initialized to CSS color #FFE4B5 + * <span class="colorSwath" style="background: #FFE4B5;"></span> + * + * @constant + * @type {Color} + */ + Color.MOCCASIN = freezeObject(Color.fromCssColorString('#FFE4B5')); - if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint + /** + * An immutable Color instance initialized to CSS color #FFDEAD + * <span class="colorSwath" style="background: #FFDEAD;"></span> + * + * @constant + * @type {Color} + */ + Color.NAVAJOWHITE = freezeObject(Color.fromCssColorString('#FFDEAD')); - // look for points inside the triangle of hole point, segment intersection and endpoint; - // if there are no points found, we have a valid connection; - // otherwise choose the point of the minimum angle with the ray as connection point - - var stop = m, - mx = m.x, - my = m.y, - tanMin = Infinity, - tan; - - p = m.next; - - while (p !== stop) { - if (hx >= p.x && p.x >= mx && - pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + /** + * An immutable Color instance initialized to CSS color #000080 + * <span class="colorSwath" style="background: #000080;"></span> + * + * @constant + * @type {Color} + */ + Color.NAVY = freezeObject(Color.fromCssColorString('#000080')); - tan = Math.abs(hy - p.y) / (hx - p.x); // tangential + /** + * An immutable Color instance initialized to CSS color #FDF5E6 + * <span class="colorSwath" style="background: #FDF5E6;"></span> + * + * @constant + * @type {Color} + */ + Color.OLDLACE = freezeObject(Color.fromCssColorString('#FDF5E6')); - if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { - m = p; - tanMin = tan; - } - } + /** + * An immutable Color instance initialized to CSS color #808000 + * <span class="colorSwath" style="background: #808000;"></span> + * + * @constant + * @type {Color} + */ + Color.OLIVE = freezeObject(Color.fromCssColorString('#808000')); - p = p.next; - } + /** + * An immutable Color instance initialized to CSS color #6B8E23 + * <span class="colorSwath" style="background: #6B8E23;"></span> + * + * @constant + * @type {Color} + */ + Color.OLIVEDRAB = freezeObject(Color.fromCssColorString('#6B8E23')); - return m; -} + /** + * An immutable Color instance initialized to CSS color #FFA500 + * <span class="colorSwath" style="background: #FFA500;"></span> + * + * @constant + * @type {Color} + */ + Color.ORANGE = freezeObject(Color.fromCssColorString('#FFA500')); -// interlink polygon nodes in z-order -function indexCurve(start, minX, minY, size) { - var p = start; - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; - } while (p !== start); + /** + * An immutable Color instance initialized to CSS color #FF4500 + * <span class="colorSwath" style="background: #FF4500;"></span> + * + * @constant + * @type {Color} + */ + Color.ORANGERED = freezeObject(Color.fromCssColorString('#FF4500')); - p.prevZ.nextZ = null; - p.prevZ = null; + /** + * An immutable Color instance initialized to CSS color #DA70D6 + * <span class="colorSwath" style="background: #DA70D6;"></span> + * + * @constant + * @type {Color} + */ + Color.ORCHID = freezeObject(Color.fromCssColorString('#DA70D6')); - sortLinked(p); -} + /** + * An immutable Color instance initialized to CSS color #EEE8AA + * <span class="colorSwath" style="background: #EEE8AA;"></span> + * + * @constant + * @type {Color} + */ + Color.PALEGOLDENROD = freezeObject(Color.fromCssColorString('#EEE8AA')); -// Simon Tatham's linked list merge sort algorithm -// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html -function sortLinked(list) { - var i, p, q, e, tail, numMerges, pSize, qSize, - inSize = 1; + /** + * An immutable Color instance initialized to CSS color #98FB98 + * <span class="colorSwath" style="background: #98FB98;"></span> + * + * @constant + * @type {Color} + */ + Color.PALEGREEN = freezeObject(Color.fromCssColorString('#98FB98')); - do { - p = list; - list = null; - tail = null; - numMerges = 0; + /** + * An immutable Color instance initialized to CSS color #AFEEEE + * <span class="colorSwath" style="background: #AFEEEE;"></span> + * + * @constant + * @type {Color} + */ + Color.PALETURQUOISE = freezeObject(Color.fromCssColorString('#AFEEEE')); - while (p) { - numMerges++; - q = p; - pSize = 0; - for (i = 0; i < inSize; i++) { - pSize++; - q = q.nextZ; - if (!q) break; - } + /** + * An immutable Color instance initialized to CSS color #DB7093 + * <span class="colorSwath" style="background: #DB7093;"></span> + * + * @constant + * @type {Color} + */ + Color.PALEVIOLETRED = freezeObject(Color.fromCssColorString('#DB7093')); - qSize = inSize; + /** + * An immutable Color instance initialized to CSS color #FFEFD5 + * <span class="colorSwath" style="background: #FFEFD5;"></span> + * + * @constant + * @type {Color} + */ + Color.PAPAYAWHIP = freezeObject(Color.fromCssColorString('#FFEFD5')); - while (pSize > 0 || (qSize > 0 && q)) { + /** + * An immutable Color instance initialized to CSS color #FFDAB9 + * <span class="colorSwath" style="background: #FFDAB9;"></span> + * + * @constant + * @type {Color} + */ + Color.PEACHPUFF = freezeObject(Color.fromCssColorString('#FFDAB9')); - if (pSize === 0) { - e = q; - q = q.nextZ; - qSize--; - } else if (qSize === 0 || !q) { - e = p; - p = p.nextZ; - pSize--; - } else if (p.z <= q.z) { - e = p; - p = p.nextZ; - pSize--; - } else { - e = q; - q = q.nextZ; - qSize--; - } + /** + * An immutable Color instance initialized to CSS color #CD853F + * <span class="colorSwath" style="background: #CD853F;"></span> + * + * @constant + * @type {Color} + */ + Color.PERU = freezeObject(Color.fromCssColorString('#CD853F')); - if (tail) tail.nextZ = e; - else list = e; + /** + * An immutable Color instance initialized to CSS color #FFC0CB + * <span class="colorSwath" style="background: #FFC0CB;"></span> + * + * @constant + * @type {Color} + */ + Color.PINK = freezeObject(Color.fromCssColorString('#FFC0CB')); - e.prevZ = tail; - tail = e; - } + /** + * An immutable Color instance initialized to CSS color #DDA0DD + * <span class="colorSwath" style="background: #DDA0DD;"></span> + * + * @constant + * @type {Color} + */ + Color.PLUM = freezeObject(Color.fromCssColorString('#DDA0DD')); - p = q; - } + /** + * An immutable Color instance initialized to CSS color #B0E0E6 + * <span class="colorSwath" style="background: #B0E0E6;"></span> + * + * @constant + * @type {Color} + */ + Color.POWDERBLUE = freezeObject(Color.fromCssColorString('#B0E0E6')); - tail.nextZ = null; - inSize *= 2; + /** + * An immutable Color instance initialized to CSS color #800080 + * <span class="colorSwath" style="background: #800080;"></span> + * + * @constant + * @type {Color} + */ + Color.PURPLE = freezeObject(Color.fromCssColorString('#800080')); - } while (numMerges > 1); + /** + * An immutable Color instance initialized to CSS color #FF0000 + * <span class="colorSwath" style="background: #FF0000;"></span> + * + * @constant + * @type {Color} + */ + Color.RED = freezeObject(Color.fromCssColorString('#FF0000')); - return list; -} + /** + * An immutable Color instance initialized to CSS color #BC8F8F + * <span class="colorSwath" style="background: #BC8F8F;"></span> + * + * @constant + * @type {Color} + */ + Color.ROSYBROWN = freezeObject(Color.fromCssColorString('#BC8F8F')); -// z-order of a point given coords and size of the data bounding box -function zOrder(x, y, minX, minY, size) { - // coords are transformed into non-negative 15-bit integer range - x = 32767 * (x - minX) / size; - y = 32767 * (y - minY) / size; + /** + * An immutable Color instance initialized to CSS color #4169E1 + * <span class="colorSwath" style="background: #4169E1;"></span> + * + * @constant + * @type {Color} + */ + Color.ROYALBLUE = freezeObject(Color.fromCssColorString('#4169E1')); - x = (x | (x << 8)) & 0x00FF00FF; - x = (x | (x << 4)) & 0x0F0F0F0F; - x = (x | (x << 2)) & 0x33333333; - x = (x | (x << 1)) & 0x55555555; + /** + * An immutable Color instance initialized to CSS color #8B4513 + * <span class="colorSwath" style="background: #8B4513;"></span> + * + * @constant + * @type {Color} + */ + Color.SADDLEBROWN = freezeObject(Color.fromCssColorString('#8B4513')); - y = (y | (y << 8)) & 0x00FF00FF; - y = (y | (y << 4)) & 0x0F0F0F0F; - y = (y | (y << 2)) & 0x33333333; - y = (y | (y << 1)) & 0x55555555; + /** + * An immutable Color instance initialized to CSS color #FA8072 + * <span class="colorSwath" style="background: #FA8072;"></span> + * + * @constant + * @type {Color} + */ + Color.SALMON = freezeObject(Color.fromCssColorString('#FA8072')); - return x | (y << 1); -} + /** + * An immutable Color instance initialized to CSS color #F4A460 + * <span class="colorSwath" style="background: #F4A460;"></span> + * + * @constant + * @type {Color} + */ + Color.SANDYBROWN = freezeObject(Color.fromCssColorString('#F4A460')); -// find the leftmost node of a polygon ring -function getLeftmost(start) { - var p = start, - leftmost = start; - do { - if (p.x < leftmost.x) leftmost = p; - p = p.next; - } while (p !== start); + /** + * An immutable Color instance initialized to CSS color #2E8B57 + * <span class="colorSwath" style="background: #2E8B57;"></span> + * + * @constant + * @type {Color} + */ + Color.SEAGREEN = freezeObject(Color.fromCssColorString('#2E8B57')); - return leftmost; -} + /** + * An immutable Color instance initialized to CSS color #FFF5EE + * <span class="colorSwath" style="background: #FFF5EE;"></span> + * + * @constant + * @type {Color} + */ + Color.SEASHELL = freezeObject(Color.fromCssColorString('#FFF5EE')); -// check if a point lies within a convex triangle -function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { - return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && - (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && - (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; -} + /** + * An immutable Color instance initialized to CSS color #A0522D + * <span class="colorSwath" style="background: #A0522D;"></span> + * + * @constant + * @type {Color} + */ + Color.SIENNA = freezeObject(Color.fromCssColorString('#A0522D')); -// check if a diagonal between two polygon nodes is valid (lies in polygon interior) -function isValidDiagonal(a, b) { - return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && - locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); -} + /** + * An immutable Color instance initialized to CSS color #C0C0C0 + * <span class="colorSwath" style="background: #C0C0C0;"></span> + * + * @constant + * @type {Color} + */ + Color.SILVER = freezeObject(Color.fromCssColorString('#C0C0C0')); -// signed area of a triangle -function area(p, q, r) { - return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); -} + /** + * An immutable Color instance initialized to CSS color #87CEEB + * <span class="colorSwath" style="background: #87CEEB;"></span> + * + * @constant + * @type {Color} + */ + Color.SKYBLUE = freezeObject(Color.fromCssColorString('#87CEEB')); -// check if two points are equal -function equals(p1, p2) { - return p1.x === p2.x && p1.y === p2.y; -} + /** + * An immutable Color instance initialized to CSS color #6A5ACD + * <span class="colorSwath" style="background: #6A5ACD;"></span> + * + * @constant + * @type {Color} + */ + Color.SLATEBLUE = freezeObject(Color.fromCssColorString('#6A5ACD')); -// check if two segments intersect -function intersects(p1, q1, p2, q2) { - if ((equals(p1, q1) && equals(p2, q2)) || - (equals(p1, q2) && equals(p2, q1))) return true; - return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && - area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; -} + /** + * An immutable Color instance initialized to CSS color #708090 + * <span class="colorSwath" style="background: #708090;"></span> + * + * @constant + * @type {Color} + */ + Color.SLATEGRAY = freezeObject(Color.fromCssColorString('#708090')); -// check if a polygon diagonal intersects any polygon segments -function intersectsPolygon(a, b) { - var p = a; - do { - if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && - intersects(p, p.next, a, b)) return true; - p = p.next; - } while (p !== a); + /** + * An immutable Color instance initialized to CSS color #708090 + * <span class="colorSwath" style="background: #708090;"></span> + * + * @constant + * @type {Color} + */ + Color.SLATEGREY = Color.SLATEGRAY; - return false; -} + /** + * An immutable Color instance initialized to CSS color #FFFAFA + * <span class="colorSwath" style="background: #FFFAFA;"></span> + * + * @constant + * @type {Color} + */ + Color.SNOW = freezeObject(Color.fromCssColorString('#FFFAFA')); -// check if a polygon diagonal is locally inside the polygon -function locallyInside(a, b) { - return area(a.prev, a, a.next) < 0 ? - area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : - area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; -} + /** + * An immutable Color instance initialized to CSS color #00FF7F + * <span class="colorSwath" style="background: #00FF7F;"></span> + * + * @constant + * @type {Color} + */ + Color.SPRINGGREEN = freezeObject(Color.fromCssColorString('#00FF7F')); -// check if the middle point of a polygon diagonal is inside the polygon -function middleInside(a, b) { - var p = a, - inside = false, - px = (a.x + b.x) / 2, - py = (a.y + b.y) / 2; - do { - if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) - inside = !inside; - p = p.next; - } while (p !== a); + /** + * An immutable Color instance initialized to CSS color #4682B4 + * <span class="colorSwath" style="background: #4682B4;"></span> + * + * @constant + * @type {Color} + */ + Color.STEELBLUE = freezeObject(Color.fromCssColorString('#4682B4')); - return inside; -} + /** + * An immutable Color instance initialized to CSS color #D2B48C + * <span class="colorSwath" style="background: #D2B48C;"></span> + * + * @constant + * @type {Color} + */ + Color.TAN = freezeObject(Color.fromCssColorString('#D2B48C')); -// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; -// if one belongs to the outer ring and another to a hole, it merges it into a single ring -function splitPolygon(a, b) { - var a2 = new Node(a.i, a.x, a.y), - b2 = new Node(b.i, b.x, b.y), - an = a.next, - bp = b.prev; + /** + * An immutable Color instance initialized to CSS color #008080 + * <span class="colorSwath" style="background: #008080;"></span> + * + * @constant + * @type {Color} + */ + Color.TEAL = freezeObject(Color.fromCssColorString('#008080')); - a.next = b; - b.prev = a; + /** + * An immutable Color instance initialized to CSS color #D8BFD8 + * <span class="colorSwath" style="background: #D8BFD8;"></span> + * + * @constant + * @type {Color} + */ + Color.THISTLE = freezeObject(Color.fromCssColorString('#D8BFD8')); - a2.next = an; - an.prev = a2; + /** + * An immutable Color instance initialized to CSS color #FF6347 + * <span class="colorSwath" style="background: #FF6347;"></span> + * + * @constant + * @type {Color} + */ + Color.TOMATO = freezeObject(Color.fromCssColorString('#FF6347')); - b2.next = a2; - a2.prev = b2; + /** + * An immutable Color instance initialized to CSS color #40E0D0 + * <span class="colorSwath" style="background: #40E0D0;"></span> + * + * @constant + * @type {Color} + */ + Color.TURQUOISE = freezeObject(Color.fromCssColorString('#40E0D0')); - bp.next = b2; - b2.prev = bp; + /** + * An immutable Color instance initialized to CSS color #EE82EE + * <span class="colorSwath" style="background: #EE82EE;"></span> + * + * @constant + * @type {Color} + */ + Color.VIOLET = freezeObject(Color.fromCssColorString('#EE82EE')); - return b2; -} + /** + * An immutable Color instance initialized to CSS color #F5DEB3 + * <span class="colorSwath" style="background: #F5DEB3;"></span> + * + * @constant + * @type {Color} + */ + Color.WHEAT = freezeObject(Color.fromCssColorString('#F5DEB3')); -// create a node and optionally link it with previous one (in a circular doubly linked list) -function insertNode(i, x, y, last) { - var p = new Node(i, x, y); + /** + * An immutable Color instance initialized to CSS color #FFFFFF + * <span class="colorSwath" style="background: #FFFFFF;"></span> + * + * @constant + * @type {Color} + */ + Color.WHITE = freezeObject(Color.fromCssColorString('#FFFFFF')); - if (!last) { - p.prev = p; - p.next = p; + /** + * An immutable Color instance initialized to CSS color #F5F5F5 + * <span class="colorSwath" style="background: #F5F5F5;"></span> + * + * @constant + * @type {Color} + */ + Color.WHITESMOKE = freezeObject(Color.fromCssColorString('#F5F5F5')); - } else { - p.next = last.next; - p.prev = last; - last.next.prev = p; - last.next = p; - } - return p; -} + /** + * An immutable Color instance initialized to CSS color #FFFF00 + * <span class="colorSwath" style="background: #FFFF00;"></span> + * + * @constant + * @type {Color} + */ + Color.YELLOW = freezeObject(Color.fromCssColorString('#FFFF00')); -function removeNode(p) { - p.next.prev = p.prev; - p.prev.next = p.next; + /** + * An immutable Color instance initialized to CSS color #9ACD32 + * <span class="colorSwath" style="background: #9ACD32;"></span> + * + * @constant + * @type {Color} + */ + Color.YELLOWGREEN = freezeObject(Color.fromCssColorString('#9ACD32')); - if (p.prevZ) p.prevZ.nextZ = p.nextZ; - if (p.nextZ) p.nextZ.prevZ = p.prevZ; -} + /** + * An immutable Color instance initialized to CSS transparent. + * <span class="colorSwath" style="background: transparent;"></span> + * + * @constant + * @type {Color} + */ + Color.TRANSPARENT = freezeObject(new Color(0, 0, 0, 0)); -function Node(i, x, y) { - // vertice index in coordinates array - this.i = i; + return Color; +}); - // vertex coordinates - this.x = x; - this.y = y; +define('Core/ClippingPlaneCollection',[ + './Cartesian3', + './Cartesian4', + './Check', + './Color', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './FeatureDetection', + './Intersect', + './Matrix4', + './Plane' + ], function( + Cartesian3, + Cartesian4, + Check, + Color, + defaultValue, + defined, + defineProperties, + DeveloperError, + FeatureDetection, + Intersect, + Matrix4, + Plane) { + 'use strict'; - // previous and next vertice nodes in a polygon ring - this.prev = null; - this.next = null; + /** + * Specifies a set of clipping planes. Clipping planes selectively disable rendering in a region on the + * outside of the specified list of {@link Plane} objects. + * + * @alias ClippingPlaneCollection + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Plane[]} [options.planes=[]] An array of up to 6 {@link Plane} objects used to selectively disable rendering on the outside of each plane. + * @param {Boolean} [options.enabled=true] Determines whether the clipping planes are active. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix specifying an additional transform relative to the clipping planes original coordinate system. + * @param {Boolean} [options.unionClippingRegions=false] If true, a region will be clipped if included in any plane in the collection. Otherwise, the region to be clipped must intersect the regions defined by all planes in this collection. + * @param {Color} [options.edgeColor=Color.WHITE] The color applied to highlight the edge along which an object is clipped. + * @param {Number} [options.edgeWidth=0.0] The width, in pixels, of the highlight applied to the edge along which an object is clipped. + */ + function ClippingPlaneCollection(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - // z-order curve value - this.z = null; + var planes = options.planes; + if (defined(planes)) { + this._planes = planes.slice(0); + } else { + this._planes = []; + } - // previous and next nodes in z-order - this.prevZ = null; - this.nextZ = null; + /** + * Determines whether the clipping planes are active. + * + * @type {Boolean} + * @default true + */ + this.enabled = defaultValue(options.enabled, true); - // indicates whether this is a steiner point - this.steiner = false; -} + /** + * The 4x4 transformation matrix specifying an additional transform relative to the clipping planes + * original coordinate system. + * + * @type {Matrix4} + * @default Matrix4.IDENTITY + */ + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); -// return a percentage difference between the polygon area and its triangulation area; -// used to verify correctness of triangulation -earcut.deviation = function (data, holeIndices, dim, triangles) { - var hasHoles = holeIndices && holeIndices.length; - var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + /** + * The color applied to highlight the edge along which an object is clipped. + * + * @type {Color} + * @default Color.WHITE + */ + this.edgeColor = Color.clone(defaultValue(options.edgeColor, Color.WHITE)); - var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); - if (hasHoles) { - for (var i = 0, len = holeIndices.length; i < len; i++) { - var start = holeIndices[i] * dim; - var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; - polygonArea -= Math.abs(signedArea(data, start, end, dim)); - } - } + /** + * The width, in pixels, of the highlight applied to the edge along which an object is clipped. + * + * @type {Number} + * @default 0.0 + */ + this.edgeWidth = defaultValue(options.edgeWidth, 0.0); - var trianglesArea = 0; - for (i = 0; i < triangles.length; i += 3) { - var a = triangles[i] * dim; - var b = triangles[i + 1] * dim; - var c = triangles[i + 2] * dim; - trianglesArea += Math.abs( - (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - - (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + this._testIntersection = undefined; + this._unionClippingRegions = undefined; + this.unionClippingRegions = defaultValue(options.unionClippingRegions, false); } - return polygonArea === 0 && trianglesArea === 0 ? 0 : - Math.abs((trianglesArea - polygonArea) / polygonArea); -}; - -function signedArea(data, start, end, dim) { - var sum = 0; - for (var i = start, j = end - dim; i < end; i += dim) { - sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); - j = i; + function unionIntersectFunction(value) { + return (value === Intersect.OUTSIDE); } - return sum; -} - -// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts -earcut.flatten = function (data) { - var dim = data[0][0].length, - result = {vertices: [], holes: [], dimensions: dim}, - holeIndex = 0; - for (var i = 0; i < data.length; i++) { - for (var j = 0; j < data[i].length; j++) { - for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); - } - if (i > 0) { - holeIndex += data[i - 1].length; - result.holes.push(holeIndex); - } + function defaultIntersectFunction(value) { + return (value === Intersect.INSIDE); } - return result; -}; - -return earcut; -}); - -define('Core/WindingOrder',[ - './freezeObject', - './WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; - /** - * Winding order defines the order of vertices for a triangle to be considered front-facing. - * - * @exports WindingOrder - */ - var WindingOrder = { + defineProperties(ClippingPlaneCollection.prototype, { /** - * Vertices are in clockwise order. + * Returns the number of planes in this collection. This is commonly used with + * {@link ClippingPlaneCollection#get} to iterate over all the planes + * in the collection. * + * @memberof ClippingPlaneCollection.prototype * @type {Number} - * @constant + * @readonly */ - CLOCKWISE : WebGLConstants.CW, + length : { + get : function() { + return this._planes.length; + } + }, /** - * Vertices are in counter-clockwise order. + * If true, a region will be clipped if included in any plane in the collection. Otherwise, the region + * to be clipped must intersect the regions defined by all planes in this collection. * - * @type {Number} - * @constant + * @memberof ClippingPlaneCollection.prototype + * @type {Boolean} + * @default false */ - COUNTER_CLOCKWISE : WebGLConstants.CCW, + unionClippingRegions : { + get : function() { + return this._unionClippingRegions; + }, + set : function(value) { + if (this._unionClippingRegions !== value) { + this._unionClippingRegions = value; + this._testIntersection = value ? unionIntersectFunction : defaultIntersectFunction; + } + } + } + }); - /** - * @private - */ - validate : function(windingOrder) { - return windingOrder === WindingOrder.CLOCKWISE || - windingOrder === WindingOrder.COUNTER_CLOCKWISE; + /** + * Adds the specified {@link Plane} to the collection to be used to selectively disable rendering + * on the outside of each plane. Use {@link ClippingPlaneCollection#unionClippingRegions} to modify + * how modify the clipping behavior of multiple planes. + * + * @param {Plane} plane The plane to add to the collection. + * + * @exception {DeveloperError} The plane added exceeds the maximum number of supported clipping planes. + * + * @see ClippingPlaneCollection#unionClippingRegions + * @see ClippingPlaneCollection#remove + * @see ClippingPlaneCollection#removeAll + */ + ClippingPlaneCollection.prototype.add = function(plane) { + if (this.length >= ClippingPlaneCollection.MAX_CLIPPING_PLANES) { + throw new DeveloperError('The maximum number of clipping planes supported is ' + ClippingPlaneCollection.MAX_CLIPPING_PLANES); } + + this._planes.push(plane); }; - return freezeObject(WindingOrder); -}); + /** + * Returns the plane in the collection at the specified index. Indices are zero-based + * and increase as planes are added. Removing a plane shifts all planes after + * it to the left, changing their indices. This function is commonly used with + * {@link ClippingPlaneCollection#length} to iterate over all the planes + * in the collection. + * + * @param {Number} index The zero-based index of the plane. + * @returns {Plane} The plane at the specified index. + * + * @see ClippingPlaneCollection#length + */ + ClippingPlaneCollection.prototype.get = function(index) { + Check.typeOf.number('index', index); + + return this._planes[index]; + }; -define('Core/PolygonPipeline',[ - '../ThirdParty/earcut-2.1.1', - './Cartesian2', - './Cartesian3', - './Check', - './ComponentDatatype', - './defaultValue', - './defined', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './Math', - './PrimitiveType', - './WindingOrder' - ], function( - earcut, - Cartesian2, - Cartesian3, - Check, - ComponentDatatype, - defaultValue, - defined, - Ellipsoid, - Geometry, - GeometryAttribute, - CesiumMath, - PrimitiveType, - WindingOrder) { - 'use strict'; + function indexOf(planes, plane) { + var length = planes.length; + for (var i = 0; i < length; ++i) { + if (Plane.equals(planes[i], plane)) { + return i; + } + } - var scaleToGeodeticHeightN = new Cartesian3(); - var scaleToGeodeticHeightP = new Cartesian3(); + return -1; + } /** - * @private + * Checks whether this collection contains the given plane. + * + * @param {Plane} [plane] The plane to check for. + * @returns {Boolean} true if this collection contains the plane, false otherwise. + * + * @see ClippingPlaneCollection#get */ - var PolygonPipeline = {}; + ClippingPlaneCollection.prototype.contains = function(plane) { + return indexOf(this._planes, plane) !== -1; + }; /** - * @exception {DeveloperError} At least three positions are required. + * Removes the first occurrence of the given plane from the collection. + * + * @param {Plane} plane + * @returns {Boolean} <code>true</code> if the plane was removed; <code>false</code> if the plane was not found in the collection. + * + * @see ClippingPlaneCollection#add + * @see ClippingPlaneCollection#contains + * @see ClippingPlaneCollection#removeAll */ - PolygonPipeline.computeArea2D = function(positions) { - Check.defined('positions', positions); - Check.typeOf.number.greaterThanOrEquals('positions.length', positions.length, 3); - - var length = positions.length; - var area = 0.0; + ClippingPlaneCollection.prototype.remove = function(plane) { + var planes = this._planes; + var index = indexOf(planes, plane); - for ( var i0 = length - 1, i1 = 0; i1 < length; i0 = i1++) { - var v0 = positions[i0]; - var v1 = positions[i1]; + if (index === -1) { + return false; + } - area += (v0.x * v1.y) - (v1.x * v0.y); + var length = planes.length - 1; + for (var i = index; i < length; ++i) { + planes[i] = planes[i + 1]; } + planes.length = length; - return area * 0.5; + return true; }; /** - * @returns {WindingOrder} The winding order. + * Removes all planes from the collection. * - * @exception {DeveloperError} At least three positions are required. + * @see ClippingPlaneCollection#add + * @see ClippingPlaneCollection#remove */ - PolygonPipeline.computeWindingOrder2D = function(positions) { - var area = PolygonPipeline.computeArea2D(positions); - return (area > 0.0) ? WindingOrder.COUNTER_CLOCKWISE : WindingOrder.CLOCKWISE; + ClippingPlaneCollection.prototype.removeAll = function() { + this._planes = []; }; + var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); + var scratchMatrix = new Matrix4(); /** - * Triangulate a polygon. + * Applies the transformations to each plane and packs it into an array. + * @private * - * @param {Cartesian2[]} positions Cartesian2 array containing the vertices of the polygon - * @param {Number[]} [holes] An array of the staring indices of the holes. - * @returns {Number[]} Index array representing triangles that fill the polygon + * @param {Matrix4} viewMatrix The 4x4 matrix to transform the plane into eyespace. + * @param {Cartesian4[]} [array] The array into which the planes will be packed. + * @returns {Cartesian4[]} The array of packed planes. */ - PolygonPipeline.triangulate = function(positions, holes) { - Check.defined('positions', positions); + ClippingPlaneCollection.prototype.transformAndPackPlanes = function(viewMatrix, array) { + Check.typeOf.object('viewMatrix', viewMatrix); - var flattenedPositions = Cartesian2.packArray(positions); - return earcut(flattenedPositions, holes, 2); - }; - - var subdivisionV0Scratch = new Cartesian3(); - var subdivisionV1Scratch = new Cartesian3(); - var subdivisionV2Scratch = new Cartesian3(); - var subdivisionS0Scratch = new Cartesian3(); - var subdivisionS1Scratch = new Cartesian3(); - var subdivisionS2Scratch = new Cartesian3(); - var subdivisionMidScratch = new Cartesian3(); - - /** - * Subdivides positions and raises points to the surface of the ellipsoid. - * - * @param {Ellipsoid} ellipsoid The ellipsoid the polygon in on. - * @param {Cartesian3[]} positions An array of {@link Cartesian3} positions of the polygon. - * @param {Number[]} indices An array of indices that determines the triangles in the polygon. - * @param {Number} [granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * - * @exception {DeveloperError} At least three indices are required. - * @exception {DeveloperError} The number of indices must be divisable by three. - * @exception {DeveloperError} Granularity must be greater than zero. - */ - PolygonPipeline.computeSubdivision = function(ellipsoid, positions, indices, granularity) { - granularity = defaultValue(granularity, CesiumMath.RADIANS_PER_DEGREE); + var planes = this._planes; + var length = planes.length; - Check.typeOf.object('ellipsoid', ellipsoid); - Check.defined('positions', positions); - Check.defined('indices', indices); - Check.typeOf.number.greaterThanOrEquals('indices.length', indices.length, 3); - Check.typeOf.number.equals('indices.length % 3', '0', indices.length % 3, 0); - Check.typeOf.number.greaterThan('granularity', granularity, 0.0); - - // triangles that need (or might need) to be subdivided. - var triangles = indices.slice(0); + var index = 0; + if (!defined(array)) { + array = new Array(length); + } else { + index = array.length; + array.length = length; + } - // New positions due to edge splits are appended to the positions list. var i; - var length = positions.length; - var subdividedPositions = new Array(length * 3); - var q = 0; - for (i = 0; i < length; i++) { - var item = positions[i]; - subdividedPositions[q++] = item.x; - subdividedPositions[q++] = item.y; - subdividedPositions[q++] = item.z; + for (i = index; i < length; ++i) { + array[i] = new Cartesian4(); } - var subdividedIndices = []; - - // Used to make sure shared edges are not split more than once. - var edges = {}; - - var radius = ellipsoid.maximumRadius; - var minDistance = CesiumMath.chordLength(granularity, radius); - var minDistanceSqrd = minDistance * minDistance; + var transform = Matrix4.multiply(viewMatrix, this.modelMatrix, scratchMatrix); - while (triangles.length > 0) { - var i2 = triangles.pop(); - var i1 = triangles.pop(); - var i0 = triangles.pop(); + for (i = 0; i < length; ++i) { + var plane = planes[i]; + var packedPlane = array[i]; - var v0 = Cartesian3.fromArray(subdividedPositions, i0 * 3, subdivisionV0Scratch); - var v1 = Cartesian3.fromArray(subdividedPositions, i1 * 3, subdivisionV1Scratch); - var v2 = Cartesian3.fromArray(subdividedPositions, i2 * 3, subdivisionV2Scratch); + Plane.transform(plane, transform, scratchPlane); - var s0 = Cartesian3.multiplyByScalar(Cartesian3.normalize(v0, subdivisionS0Scratch), radius, subdivisionS0Scratch); - var s1 = Cartesian3.multiplyByScalar(Cartesian3.normalize(v1, subdivisionS1Scratch), radius, subdivisionS1Scratch); - var s2 = Cartesian3.multiplyByScalar(Cartesian3.normalize(v2, subdivisionS2Scratch), radius, subdivisionS2Scratch); + Cartesian3.clone(scratchPlane.normal, packedPlane); + packedPlane.w = scratchPlane.distance; + } - var g0 = Cartesian3.magnitudeSquared(Cartesian3.subtract(s0, s1, subdivisionMidScratch)); - var g1 = Cartesian3.magnitudeSquared(Cartesian3.subtract(s1, s2, subdivisionMidScratch)); - var g2 = Cartesian3.magnitudeSquared(Cartesian3.subtract(s2, s0, subdivisionMidScratch)); + return array; + }; - var max = Math.max(g0, g1, g2); - var edge; - var mid; + /** + * Duplicates this ClippingPlaneCollection instance. + * + * @param {ClippingPlaneCollection} [result] The object onto which to store the result. + * @returns {ClippingPlaneCollection} The modified result parameter or a new ClippingPlaneCollection instance if one was not provided. + */ + ClippingPlaneCollection.prototype.clone = function(result) { + if (!defined(result)) { + result = new ClippingPlaneCollection(); + } - // if the max length squared of a triangle edge is greater than the chord length of squared - // of the granularity, subdivide the triangle - if (max > minDistanceSqrd) { - if (g0 === max) { - edge = Math.min(i0, i1) + ' ' + Math.max(i0, i1); + var length = this.length; + var i; + if (result.length !== length) { + var planes = result._planes; + var index = planes.length; - i = edges[edge]; - if (!defined(i)) { - mid = Cartesian3.add(v0, v1, subdivisionMidScratch); - Cartesian3.multiplyByScalar(mid, 0.5, mid); - subdividedPositions.push(mid.x, mid.y, mid.z); - i = subdividedPositions.length / 3 - 1; - edges[edge] = i; - } + planes.length = length; + for (i = index; i < length; ++i) { + result._planes[i] = new Plane(Cartesian3.UNIT_X, 0.0); + } + } - triangles.push(i0, i, i2); - triangles.push(i, i1, i2); - } else if (g1 === max) { - edge = Math.min(i1, i2) + ' ' + Math.max(i1, i2); + for (i = 0; i < length; ++i) { + Plane.clone(this._planes[i], result._planes[i]); + } - i = edges[edge]; - if (!defined(i)) { - mid = Cartesian3.add(v1, v2, subdivisionMidScratch); - Cartesian3.multiplyByScalar(mid, 0.5, mid); - subdividedPositions.push(mid.x, mid.y, mid.z); - i = subdividedPositions.length / 3 - 1; - edges[edge] = i; - } + result.enabled = this.enabled; + Matrix4.clone(this.modelMatrix, result.modelMatrix); + result.unionClippingRegions = this.unionClippingRegions; + Color.clone(this.edgeColor, result.edgeColor); + result.edgeWidth = this.edgeWidth; - triangles.push(i1, i, i0); - triangles.push(i, i2, i0); - } else if (g2 === max) { - edge = Math.min(i2, i0) + ' ' + Math.max(i2, i0); + return result; + }; - i = edges[edge]; - if (!defined(i)) { - mid = Cartesian3.add(v2, v0, subdivisionMidScratch); - Cartesian3.multiplyByScalar(mid, 0.5, mid); - subdividedPositions.push(mid.x, mid.y, mid.z); - i = subdividedPositions.length / 3 - 1; - edges[edge] = i; - } + /** + * Determines the type intersection with the planes of this ClippingPlaneCollection instance and the specified {@link BoundingVolume}. + * @private + * + * @param {Object} boundingVolume The volume to determine the intersection with the planes. + * @param {Matrix4} [transform] An optional, additional matrix to transform the plane to world coordinates. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire volume is on the side of the planes + * the normal is pointing and should be entirely rendered, {@link Intersect.OUTSIDE} + * if the entire volume is on the opposite side and should be clipped, and + * {@link Intersect.INTERSECTING} if the volume intersects the planes. + */ + ClippingPlaneCollection.prototype.computeIntersectionWithBoundingVolume = function(boundingVolume, transform) { + var planes = this._planes; + var length = planes.length; - triangles.push(i2, i, i1); - triangles.push(i, i0, i1); - } - } else { - subdividedIndices.push(i0); - subdividedIndices.push(i1); - subdividedIndices.push(i2); + var modelMatrix = this.modelMatrix; + if (defined(transform)) { + modelMatrix = Matrix4.multiply(modelMatrix, transform, scratchMatrix); + } + + // If the collection is not set to union the clipping regions, the volume must be outside of all planes to be + // considered completely clipped. If the collection is set to union the clipping regions, if the volume can be + // outside any the planes, it is considered completely clipped. + // Lastly, if not completely clipped, if any plane is intersecting, more calculations must be performed. + var intersection = Intersect.INSIDE; + if (!this.unionClippingRegions && length > 0) { + intersection = Intersect.OUTSIDE; + } + + for (var i = 0; i < length; ++i) { + var plane = planes[i]; + + Plane.transform(plane, modelMatrix, scratchPlane); + + var value = boundingVolume.intersectPlane(scratchPlane); + if (value === Intersect.INTERSECTING) { + intersection = value; + } else if (this._testIntersection(value)) { + return value; } } - return new Geometry({ - attributes : { - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : subdividedPositions - }) - }, - indices : subdividedIndices, - primitiveType : PrimitiveType.TRIANGLES - }); + return intersection; }; /** - * Scales each position of a geometry's position attribute to a height, in place. + * Determines if rendering with clipping planes is supported. * - * @param {Number[]} positions The array of numbers representing the positions to be scaled - * @param {Number} [height=0.0] The desired height to add to the positions - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. - * @param {Boolean} [scaleToSurface=true] <code>true</code> if the positions need to be scaled to the surface before the height is added. - * @returns {Number[]} The input array of positions, scaled to height + * @returns {Boolean} <code>true</code> if ClippingPlaneCollections are supported; otherwise, returns <code>false</code> */ - PolygonPipeline.scaleToGeodeticHeight = function(positions, height, ellipsoid, scaleToSurface) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + ClippingPlaneCollection.isSupported = function() { + return !FeatureDetection.isInternetExplorer(); + }; - var n = scaleToGeodeticHeightN; - var p = scaleToGeodeticHeightP; + /** + * The maximum number of supported clipping planes. + * + * @type {number} + * @constant + */ + ClippingPlaneCollection.MAX_CLIPPING_PLANES = 6; - height = defaultValue(height, 0.0); - scaleToSurface = defaultValue(scaleToSurface, true); + return ClippingPlaneCollection; +}); - if (defined(positions)) { - var length = positions.length; +define('Core/ClockRange',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; - for ( var i = 0; i < length; i += 3) { - Cartesian3.fromArray(positions, i, p); + /** + * Constants used by {@link Clock#tick} to determine behavior + * when {@link Clock#startTime} or {@link Clock#stopTime} is reached. + * + * @exports ClockRange + * + * @see Clock + * @see ClockStep + */ + var ClockRange = { + /** + * {@link Clock#tick} will always advances the clock in its current direction. + * + * @type {Number} + * @constant + */ + UNBOUNDED : 0, - if (scaleToSurface) { - p = ellipsoid.scaleToGeodeticSurface(p, p); - } + /** + * When {@link Clock#startTime} or {@link Clock#stopTime} is reached, + * {@link Clock#tick} will not advance {@link Clock#currentTime} any further. + * + * @type {Number} + * @constant + */ + CLAMPED : 1, - if (height !== 0) { - n = ellipsoid.geodeticSurfaceNormal(p, n); + /** + * When {@link Clock#stopTime} is reached, {@link Clock#tick} will advance + * {@link Clock#currentTime} to the opposite end of the interval. When + * time is moving backwards, {@link Clock#tick} will not advance past + * {@link Clock#startTime} + * + * @type {Number} + * @constant + */ + LOOP_STOP : 2 + }; - Cartesian3.multiplyByScalar(n, height, n); - Cartesian3.add(p, n, p); - } + return freezeObject(ClockRange); +}); - positions[i] = p.x; - positions[i + 1] = p.y; - positions[i + 2] = p.z; - } - } +define('Core/ClockStep',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; - return positions; + /** + * Constants to determine how much time advances with each call + * to {@link Clock#tick}. + * + * @exports ClockStep + * + * @see Clock + * @see ClockRange + */ + var ClockStep = { + /** + * {@link Clock#tick} advances the current time by a fixed step, + * which is the number of seconds specified by {@link Clock#multiplier}. + * + * @type {Number} + * @constant + */ + TICK_DEPENDENT : 0, + + /** + * {@link Clock#tick} advances the current time by the amount of system + * time elapsed since the previous call multiplied by {@link Clock#multiplier}. + * + * @type {Number} + * @constant + */ + SYSTEM_CLOCK_MULTIPLIER : 1, + + /** + * {@link Clock#tick} sets the clock to the current system time; + * ignoring all other settings. + * + * @type {Number} + * @constant + */ + SYSTEM_CLOCK : 2 }; - return PolygonPipeline; + return freezeObject(ClockStep); }); -define('Core/CorridorGeometry',[ - './arrayRemoveDuplicates', - './BoundingSphere', - './Cartesian3', - './Cartographic', - './ComponentDatatype', - './CornerType', - './CorridorGeometryLibrary', +define('Core/getTimestamp',[ + './defined' + ], function( + defined) { + 'use strict'; + /*global performance*/ + + /** + * Gets a timestamp that can be used in measuring the time between events. Timestamps + * are expressed in milliseconds, but it is not specified what the milliseconds are + * measured from. This function uses performance.now() if it is available, or Date.now() + * otherwise. + * + * @exports getTimestamp + * + * @returns {Number} The timestamp in milliseconds since some unspecified reference time. + */ + var getTimestamp; + + if (typeof performance !== 'undefined' && typeof performance.now === 'function' && isFinite(performance.now())) { + getTimestamp = function() { + return performance.now(); + }; + } else { + getTimestamp = function() { + return Date.now(); + }; + } + + return getTimestamp; +}); + +define('Core/Clock',[ + './ClockRange', + './ClockStep', './defaultValue', './defined', './defineProperties', './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PolygonPipeline', - './PrimitiveType', - './Rectangle', - './VertexFormat' + './Event', + './getTimestamp', + './JulianDate' ], function( - arrayRemoveDuplicates, - BoundingSphere, - Cartesian3, - Cartographic, - ComponentDatatype, - CornerType, - CorridorGeometryLibrary, + ClockRange, + ClockStep, defaultValue, defined, defineProperties, DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PolygonPipeline, - PrimitiveType, - Rectangle, - VertexFormat) { + Event, + getTimestamp, + JulianDate) { 'use strict'; - var cartesian1 = new Cartesian3(); - var cartesian2 = new Cartesian3(); - var cartesian3 = new Cartesian3(); - var cartesian4 = new Cartesian3(); - var cartesian5 = new Cartesian3(); - var cartesian6 = new Cartesian3(); + /** + * A simple clock for keeping track of simulated time. + * + * @alias Clock + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {JulianDate} [options.startTime] The start time of the clock. + * @param {JulianDate} [options.stopTime] The stop time of the clock. + * @param {JulianDate} [options.currentTime] The current time. + * @param {Number} [options.multiplier=1.0] Determines how much time advances when {@link Clock#tick} is called, negative values allow for advancing backwards. + * @param {ClockStep} [options.clockStep=ClockStep.SYSTEM_CLOCK_MULTIPLIER] Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent. + * @param {ClockRange} [options.clockRange=ClockRange.UNBOUNDED] Determines how the clock should behave when {@link Clock#startTime} or {@link Clock#stopTime} is reached. + * @param {Boolean} [options.canAnimate=true] Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, for example. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. + * @param {Boolean} [options.shouldAnimate=false] Indicates whether {@link Clock#tick} should attempt to advance time. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. + * + * @exception {DeveloperError} startTime must come before stopTime. + * + * + * @example + * // Create a clock that loops on Christmas day 2013 and runs in real-time. + * var clock = new Cesium.Clock({ + * startTime : Cesium.JulianDate.fromIso8601("2013-12-25"), + * currentTime : Cesium.JulianDate.fromIso8601("2013-12-25"), + * stopTime : Cesium.JulianDate.fromIso8601("2013-12-26"), + * clockRange : Cesium.ClockRange.LOOP_STOP, + * clockStep : Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER + * }); + * + * @see ClockStep + * @see ClockRange + * @see JulianDate + */ + function Clock(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var scratch1 = new Cartesian3(); - var scratch2 = new Cartesian3(); + var currentTime = options.currentTime; + var startTime = options.startTime; + var stopTime = options.stopTime; - function scaleToSurface(positions, ellipsoid) { - for (var i = 0; i < positions.length; i++) { - positions[i] = ellipsoid.scaleToGeodeticSurface(positions[i], positions[i]); + if (!defined(currentTime)) { + // if not specified, current time is the start time, + // or if that is not specified, 1 day before the stop time, + // or if that is not specified, then now. + if (defined(startTime)) { + currentTime = JulianDate.clone(startTime); + } else if (defined(stopTime)) { + currentTime = JulianDate.addDays(stopTime, -1.0, new JulianDate()); + } else { + currentTime = JulianDate.now(); + } + } else { + currentTime = JulianDate.clone(currentTime); } - return positions; - } - function addNormals(attr, normal, left, front, back, vertexFormat) { - var normals = attr.normals; - var tangents = attr.tangents; - var bitangents = attr.bitangents; - var forward = Cartesian3.normalize(Cartesian3.cross(left, normal, scratch1), scratch1); - if (vertexFormat.normal) { - CorridorGeometryLibrary.addAttribute(normals, normal, front, back); - } - if (vertexFormat.tangent) { - CorridorGeometryLibrary.addAttribute(tangents, forward, front, back); - } - if (vertexFormat.bitangent) { - CorridorGeometryLibrary.addAttribute(bitangents, left, front, back); + if (!defined(startTime)) { + // if not specified, start time is the current time + // (as determined above) + startTime = JulianDate.clone(currentTime); + } else { + startTime = JulianDate.clone(startTime); } - } - function combine(computedPositions, vertexFormat, ellipsoid) { - var positions = computedPositions.positions; - var corners = computedPositions.corners; - var endPositions = computedPositions.endPositions; - var computedLefts = computedPositions.lefts; - var computedNormals = computedPositions.normals; - var attributes = new GeometryAttributes(); - var corner; - var leftCount = 0; - var rightCount = 0; - var i; - var indicesLength = 0; - var length; - for (i = 0; i < positions.length; i += 2) { - length = positions[i].length - 3; - leftCount += length; //subtracting 3 to account for duplicate points at corners - indicesLength += length*2; - rightCount += positions[i + 1].length - 3; - } - leftCount += 3; //add back count for end positions - rightCount += 3; - for (i = 0; i < corners.length; i++) { - corner = corners[i]; - var leftSide = corners[i].leftPositions; - if (defined(leftSide)) { - length = leftSide.length; - leftCount += length; - indicesLength += length; - } else { - length = corners[i].rightPositions.length; - rightCount += length; - indicesLength += length; - } + if (!defined(stopTime)) { + // if not specified, stop time is 1 day after the start time + // (as determined above) + stopTime = JulianDate.addDays(startTime, 1.0, new JulianDate()); + } else { + stopTime = JulianDate.clone(stopTime); } - var addEndPositions = defined(endPositions); - var endPositionLength; - if (addEndPositions) { - endPositionLength = endPositions[0].length - 3; - leftCount += endPositionLength; - rightCount += endPositionLength; - endPositionLength /= 3; - indicesLength += endPositionLength * 6; + if (JulianDate.greaterThan(startTime, stopTime)) { + throw new DeveloperError('startTime must come before stopTime.'); } - var size = leftCount + rightCount; - var finalPositions = new Float64Array(size); - var normals = (vertexFormat.normal) ? new Float32Array(size) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(size) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(size) : undefined; - var attr = { - normals : normals, - tangents : tangents, - bitangents : bitangents - }; - var front = 0; - var back = size - 1; - var UL, LL, UR, LR; - var normal = cartesian1; - var left = cartesian2; - var rightPos, leftPos; - var halfLength = endPositionLength / 2; + + /** + * The start time of the clock. + * @type {JulianDate} + */ + this.startTime = startTime; - var indices = IndexDatatype.createTypedArray(size / 3, indicesLength); - var index = 0; - if (addEndPositions) { // add rounded end - leftPos = cartesian3; - rightPos = cartesian4; - var firstEndPositions = endPositions[0]; - normal = Cartesian3.fromArray(computedNormals, 0, normal); - left = Cartesian3.fromArray(computedLefts, 0, left); - for (i = 0; i < halfLength; i++) { - leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); - rightPos = Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos); - CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); - CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); - addNormals(attr, normal, left, front, back, vertexFormat); + /** + * The stop time of the clock. + * @type {JulianDate} + */ + this.stopTime = stopTime; - LL = front / 3; - LR = LL + 1; - UL = (back - 2) / 3; - UR = UL - 1; - indices[index++] = UL; - indices[index++] = LL; - indices[index++] = UR; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + /** + * Determines how the clock should behave when + * {@link Clock#startTime} or {@link Clock#stopTime} + * is reached. + * @type {ClockRange} + * @default {@link ClockRange.UNBOUNDED} + */ + this.clockRange = defaultValue(options.clockRange, ClockRange.UNBOUNDED); - front += 3; - back -= 3; - } - } + /** + * Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, + * for example. The clock will only advance time when both + * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. + * @type {Boolean} + * @default true + */ + this.canAnimate = defaultValue(options.canAnimate, true); - var posIndex = 0; - var compIndex = 0; - var rightEdge = positions[posIndex++]; //add first two edges - var leftEdge = positions[posIndex++]; - finalPositions.set(rightEdge, front); - finalPositions.set(leftEdge, back - leftEdge.length + 1); + /** + * An {@link Event} that is fired whenever {@link Clock#tick} is called. + * @type {Event} + */ + this.onTick = new Event(); - left = Cartesian3.fromArray(computedLefts, compIndex, left); - var rightNormal; - var leftNormal; - length = leftEdge.length - 3; - for (i = 0; i < length; i += 3) { - rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(rightEdge, i, scratch1), scratch1); - leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(leftEdge, length - i, scratch2), scratch2); - normal = Cartesian3.normalize(Cartesian3.add(rightNormal, leftNormal, normal), normal); - addNormals(attr, normal, left, front, back, vertexFormat); + this._currentTime = undefined; + this._multiplier = undefined; + this._clockStep = undefined; + this._shouldAnimate = undefined; + this._lastSystemTime = getTimestamp(); - LL = front / 3; - LR = LL + 1; - UL = (back - 2) / 3; - UR = UL - 1; - indices[index++] = UL; - indices[index++] = LL; - indices[index++] = UR; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + // set values using the property setters to + // make values consistent. - front += 3; - back -= 3; - } + this.currentTime = currentTime; + this.multiplier = defaultValue(options.multiplier, 1.0); + this.shouldAnimate = defaultValue(options.shouldAnimate, false); + this.clockStep = defaultValue(options.clockStep, ClockStep.SYSTEM_CLOCK_MULTIPLIER); + } - rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(rightEdge, length, scratch1), scratch1); - leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(leftEdge, length, scratch2), scratch2); - normal = Cartesian3.normalize(Cartesian3.add(rightNormal, leftNormal, normal), normal); - compIndex += 3; - for (i = 0; i < corners.length; i++) { - var j; - corner = corners[i]; - var l = corner.leftPositions; - var r = corner.rightPositions; - var pivot; - var start; - var outsidePoint = cartesian6; - var previousPoint = cartesian3; - var nextPoint = cartesian4; - normal = Cartesian3.fromArray(computedNormals, compIndex, normal); - if (defined(l)) { - addNormals(attr, normal, left, undefined, back, vertexFormat); - back -= 3; - pivot = LR; - start = UR; - for (j = 0; j < l.length / 3; j++) { - outsidePoint = Cartesian3.fromArray(l, j * 3, outsidePoint); - indices[index++] = pivot; - indices[index++] = start - j - 1; - indices[index++] = start - j; - CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); - previousPoint = Cartesian3.fromArray(finalPositions, (start - j - 1) * 3, previousPoint); - nextPoint = Cartesian3.fromArray(finalPositions, pivot * 3, nextPoint); - left = Cartesian3.normalize(Cartesian3.subtract(previousPoint, nextPoint, left), left); - addNormals(attr, normal, left, undefined, back, vertexFormat); - back -= 3; + defineProperties(Clock.prototype, { + /** + * The current time. + * Changing this property will change + * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to + * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. + * @memberof Clock.prototype + * @type {JulianDate} + */ + currentTime : { + get : function() { + return this._currentTime; + }, + set : function(value) { + if (JulianDate.equals(this._currentTime, value)) { + return; } - outsidePoint = Cartesian3.fromArray(finalPositions, pivot * 3, outsidePoint); - previousPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, (start) * 3, previousPoint), outsidePoint, previousPoint); - nextPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, (start - j) * 3, nextPoint), outsidePoint, nextPoint); - left = Cartesian3.normalize(Cartesian3.add(previousPoint, nextPoint, left), left); - addNormals(attr, normal, left, front, undefined, vertexFormat); - front += 3; - } else { - addNormals(attr, normal, left, front, undefined, vertexFormat); - front += 3; - pivot = UR; - start = LR; - for (j = 0; j < r.length / 3; j++) { - outsidePoint = Cartesian3.fromArray(r, j * 3, outsidePoint); - indices[index++] = pivot; - indices[index++] = start + j; - indices[index++] = start + j + 1; - CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); - previousPoint = Cartesian3.fromArray(finalPositions, pivot * 3, previousPoint); - nextPoint = Cartesian3.fromArray(finalPositions, (start + j) * 3, nextPoint); - left = Cartesian3.normalize(Cartesian3.subtract(previousPoint, nextPoint, left), left); - addNormals(attr, normal, left, front, undefined, vertexFormat); - front += 3; + + if (this._clockStep === ClockStep.SYSTEM_CLOCK) { + this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; } - outsidePoint = Cartesian3.fromArray(finalPositions, pivot * 3, outsidePoint); - previousPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, (start + j) * 3, previousPoint), outsidePoint, previousPoint); - nextPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, start * 3, nextPoint), outsidePoint, nextPoint); - left = Cartesian3.normalize(Cartesian3.negate(Cartesian3.add(nextPoint, previousPoint, left), left), left); - addNormals(attr, normal, left, undefined, back, vertexFormat); - back -= 3; + + this._currentTime = value; } - rightEdge = positions[posIndex++]; - leftEdge = positions[posIndex++]; - rightEdge.splice(0, 3); //remove duplicate points added by corner - leftEdge.splice(leftEdge.length - 3, 3); - finalPositions.set(rightEdge, front); - finalPositions.set(leftEdge, back - leftEdge.length + 1); - length = leftEdge.length - 3; + }, - compIndex += 3; - left = Cartesian3.fromArray(computedLefts, compIndex, left); - for (j = 0; j < leftEdge.length; j += 3) { - rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(rightEdge, j, scratch1), scratch1); - leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(leftEdge, length - j, scratch2), scratch2); - normal = Cartesian3.normalize(Cartesian3.add(rightNormal, leftNormal, normal), normal); - addNormals(attr, normal, left, front, back, vertexFormat); + /** + * Gets or sets how much time advances when {@link Clock#tick} is called. Negative values allow for advancing backwards. + * If {@link Clock#clockStep} is set to {@link ClockStep.TICK_DEPENDENT}, this is the number of seconds to advance. + * If {@link Clock#clockStep} is set to {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}, this value is multiplied by the + * elapsed system time since the last call to {@link Clock#tick}. + * Changing this property will change + * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to + * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. + * @memberof Clock.prototype + * @type {Number} + * @default 1.0 + */ + multiplier : { + get : function() { + return this._multiplier; + }, + set : function(value) { + if (this._multiplier === value) { + return; + } - LR = front / 3; - LL = LR - 1; - UR = (back - 2) / 3; - UL = UR + 1; - indices[index++] = UL; - indices[index++] = LL; - indices[index++] = UR; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + if (this._clockStep === ClockStep.SYSTEM_CLOCK) { + this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; + } - front += 3; - back -= 3; + this._multiplier = value; } - front -= 3; - back += 3; - } - normal = Cartesian3.fromArray(computedNormals, computedNormals.length - 3, normal); - addNormals(attr, normal, left, front, back, vertexFormat); - - if (addEndPositions) { // add rounded end - front += 3; - back -= 3; - leftPos = cartesian3; - rightPos = cartesian4; - var lastEndPositions = endPositions[1]; - for (i = 0; i < halfLength; i++) { - leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); - rightPos = Cartesian3.fromArray(lastEndPositions, i * 3, rightPos); - CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); - CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); - addNormals(attr, normal, left, front, back, vertexFormat); + }, - LR = front / 3; - LL = LR - 1; - UR = (back - 2) / 3; - UL = UR + 1; - indices[index++] = UL; - indices[index++] = LL; - indices[index++] = UR; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + /** + * Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent. + * Changing this property to {@link ClockStep.SYSTEM_CLOCK} will set + * {@link Clock#multiplier} to 1.0, {@link Clock#shouldAnimate} to true, and + * {@link Clock#currentTime} to the current system clock time. + * @memberof Clock.prototype + * @type ClockStep + * @default {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER} + */ + clockStep : { + get : function() { + return this._clockStep; + }, + set : function(value) { + if (value === ClockStep.SYSTEM_CLOCK) { + this._multiplier = 1.0; + this._shouldAnimate = true; + this._currentTime = JulianDate.now(); + } - front += 3; - back -= 3; + this._clockStep = value; } - } + }, - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : finalPositions - }); - if (vertexFormat.st) { - var st = new Float32Array(size / 3 * 2); - var rightSt; - var leftSt; - var stIndex = 0; - if (addEndPositions) { - leftCount /= 3; - rightCount /= 3; - var theta = Math.PI / (endPositionLength + 1); - leftSt = 1 / (leftCount - endPositionLength + 1); - rightSt = 1 / (rightCount - endPositionLength + 1); - var a; - var halfEndPos = endPositionLength / 2; - for (i = halfEndPos + 1; i < endPositionLength + 1; i++) { // lower left rounded end - a = CesiumMath.PI_OVER_TWO + theta * i; - st[stIndex++] = rightSt * (1 + Math.cos(a)); - st[stIndex++] = 0.5 * (1 + Math.sin(a)); - } - for (i = 1; i < rightCount - endPositionLength + 1; i++) { // bottom edge - st[stIndex++] = i * rightSt; - st[stIndex++] = 0; - } - for (i = endPositionLength; i > halfEndPos; i--) { // lower right rounded end - a = CesiumMath.PI_OVER_TWO - i * theta; - st[stIndex++] = 1 - rightSt * (1 + Math.cos(a)); - st[stIndex++] = 0.5 * (1 + Math.sin(a)); - } - for (i = halfEndPos; i > 0; i--) { // upper right rounded end - a = CesiumMath.PI_OVER_TWO - theta * i; - st[stIndex++] = 1 - leftSt * (1 + Math.cos(a)); - st[stIndex++] = 0.5 * (1 + Math.sin(a)); - } - for (i = leftCount - endPositionLength; i > 0; i--) { // top edge - st[stIndex++] = i * leftSt; - st[stIndex++] = 1; - } - for (i = 1; i < halfEndPos + 1; i++) { // upper left rounded end - a = CesiumMath.PI_OVER_TWO + theta * i; - st[stIndex++] = leftSt * (1 + Math.cos(a)); - st[stIndex++] = 0.5 * (1 + Math.sin(a)); - } - } else { - leftCount /= 3; - rightCount /= 3; - leftSt = 1 / (leftCount - 1); - rightSt = 1 / (rightCount - 1); - for (i = 0; i < rightCount; i++) { // bottom edge - st[stIndex++] = i * rightSt; - st[stIndex++] = 0; + /** + * Indicates whether {@link Clock#tick} should attempt to advance time. + * The clock will only advance time when both + * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. + * Changing this property will change + * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to + * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. + * @memberof Clock.prototype + * @type {Boolean} + * @default true + */ + shouldAnimate : { + get : function() { + return this._shouldAnimate; + }, + set : function(value) { + if (this._shouldAnimate === value) { + return; } - for (i = leftCount; i > 0; i--) { // top edge - st[stIndex++] = (i - 1) * leftSt; - st[stIndex++] = 1; + + if (this._clockStep === ClockStep.SYSTEM_CLOCK) { + this._clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; } - } - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : st - }); + this._shouldAnimate = value; + } } + }); - if (vertexFormat.normal) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : attr.normals - }); - } + /** + * Advances the clock from the current time based on the current configuration options. + * tick should be called every frame, regardless of whether animation is taking place + * or not. To control animation, use the {@link Clock#shouldAnimate} property. + * + * @returns {JulianDate} The new value of the {@link Clock#currentTime} property. + */ + Clock.prototype.tick = function() { + var currentSystemTime = getTimestamp(); + var currentTime = JulianDate.clone(this._currentTime); - if (vertexFormat.tangent) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : attr.tangents - }); - } + if (this.canAnimate && this._shouldAnimate) { + var clockStep = this._clockStep; + if (clockStep === ClockStep.SYSTEM_CLOCK) { + currentTime = JulianDate.now(currentTime); + } else { + var multiplier = this._multiplier; - if (vertexFormat.bitangent) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : attr.bitangents - }); - } + if (clockStep === ClockStep.TICK_DEPENDENT) { + currentTime = JulianDate.addSeconds(currentTime, multiplier, currentTime); + } else { + var milliseconds = currentSystemTime - this._lastSystemTime; + currentTime = JulianDate.addSeconds(currentTime, multiplier * (milliseconds / 1000.0), currentTime); + } - return { - attributes : attributes, - indices : indices - }; - } + var clockRange = this.clockRange; + var startTime = this.startTime; + var stopTime = this.stopTime; - function extrudedAttributes(attributes, vertexFormat) { - if (!vertexFormat.normal && !vertexFormat.tangent && !vertexFormat.bitangent && !vertexFormat.st) { - return attributes; - } - var positions = attributes.position.values; - var topNormals; - var topBitangents; - if (vertexFormat.normal || vertexFormat.bitangent) { - topNormals = attributes.normal.values; - topBitangents = attributes.bitangent.values; - } - var size = attributes.position.values.length / 18; - var threeSize = size * 3; - var twoSize = size * 2; - var sixSize = threeSize * 2; - var i; - if (vertexFormat.normal || vertexFormat.bitangent || vertexFormat.tangent) { - var normals = (vertexFormat.normal) ? new Float32Array(threeSize * 6) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(threeSize * 6) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(threeSize * 6) : undefined; - var topPosition = cartesian1; - var bottomPosition = cartesian2; - var previousPosition = cartesian3; - var normal = cartesian4; - var tangent = cartesian5; - var bitangent = cartesian6; - var attrIndex = sixSize; - for (i = 0; i < threeSize; i += 3) { - var attrIndexOffset = attrIndex + sixSize; - topPosition = Cartesian3.fromArray(positions, i, topPosition); - bottomPosition = Cartesian3.fromArray(positions, i + threeSize, bottomPosition); - previousPosition = Cartesian3.fromArray(positions, (i + 3) % threeSize, previousPosition); - bottomPosition = Cartesian3.subtract(bottomPosition, topPosition, bottomPosition); - previousPosition = Cartesian3.subtract(previousPosition, topPosition, previousPosition); - normal = Cartesian3.normalize(Cartesian3.cross(bottomPosition, previousPosition, normal), normal); - if (vertexFormat.normal) { - CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset); - CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset + 3); - CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex); - CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex + 3); - } - if (vertexFormat.tangent || vertexFormat.bitangent) { - bitangent = Cartesian3.fromArray(topNormals, i, bitangent); - if (vertexFormat.bitangent) { - CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndexOffset); - CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndexOffset + 3); - CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndex); - CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndex + 3); + if (clockRange === ClockRange.CLAMPED) { + if (JulianDate.lessThan(currentTime, startTime)) { + currentTime = JulianDate.clone(startTime, currentTime); + } else if (JulianDate.greaterThan(currentTime, stopTime)) { + currentTime = JulianDate.clone(stopTime, currentTime); } - - if (vertexFormat.tangent) { - tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); - CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset); - CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset + 3); - CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex); - CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex + 3); + } else if (clockRange === ClockRange.LOOP_STOP) { + if (JulianDate.lessThan(currentTime, startTime)) { + currentTime = JulianDate.clone(startTime, currentTime); + } + while (JulianDate.greaterThan(currentTime, stopTime)) { + currentTime = JulianDate.addSeconds(startTime, JulianDate.secondsDifference(currentTime, stopTime), currentTime); } } - attrIndex += 6; - } - - if (vertexFormat.normal) { - normals.set(topNormals); //top - for (i = 0; i < threeSize; i += 3) { //bottom normals - normals[i + threeSize] = -topNormals[i]; - normals[i + threeSize + 1] = -topNormals[i + 1]; - normals[i + threeSize + 2] = -topNormals[i + 2]; - } - attributes.normal.values = normals; - } else { - attributes.normal = undefined; - } - - if (vertexFormat.bitangent) { - bitangents.set(topBitangents); //top - bitangents.set(topBitangents, threeSize); //bottom - attributes.bitangent.values = bitangents; - } else { - attributes.bitangent = undefined; - } - - if (vertexFormat.tangent) { - var topTangents = attributes.tangent.values; - tangents.set(topTangents); //top - tangents.set(topTangents, threeSize); //bottom - attributes.tangent.values = tangents; } } - if (vertexFormat.st) { - var topSt = attributes.st.values; - var st = new Float32Array(twoSize * 6); - st.set(topSt); //top - st.set(topSt, twoSize); //bottom - var index = twoSize * 2; - for ( var j = 0; j < 2; j++) { - st[index++] = topSt[0]; - st[index++] = topSt[1]; - for (i = 2; i < twoSize; i += 2) { - var s = topSt[i]; - var t = topSt[i + 1]; - st[index++] = s; - st[index++] = t; - st[index++] = s; - st[index++] = t; - } - st[index++] = topSt[0]; - st[index++] = topSt[1]; - } - attributes.st.values = st; - } + this._currentTime = currentTime; + this._lastSystemTime = currentSystemTime; + this.onTick.raiseEvent(this); + return currentTime; + }; - return attributes; - } + return Clock; +}); - function addWallPositions(positions, index, wallPositions) { - wallPositions[index++] = positions[0]; - wallPositions[index++] = positions[1]; - wallPositions[index++] = positions[2]; - for ( var i = 3; i < positions.length; i += 3) { - var x = positions[i]; - var y = positions[i + 1]; - var z = positions[i + 2]; - wallPositions[index++] = x; - wallPositions[index++] = y; - wallPositions[index++] = z; - wallPositions[index++] = x; - wallPositions[index++] = y; - wallPositions[index++] = z; - } - wallPositions[index++] = positions[0]; - wallPositions[index++] = positions[1]; - wallPositions[index++] = positions[2]; - - return wallPositions; - } - - function computePositionsExtruded(params, vertexFormat) { - var topVertexFormat = new VertexFormat({ - position : vertexFormat.position, - normal : (vertexFormat.normal || vertexFormat.bitangent || params.shadowVolume), - tangent : vertexFormat.tangent, - bitangent : (vertexFormat.normal || vertexFormat.bitangent), - st : vertexFormat.st - }); - var ellipsoid = params.ellipsoid; - var computedPositions = CorridorGeometryLibrary.computePositions(params); - var attr = combine(computedPositions, topVertexFormat, ellipsoid); - var height = params.height; - var extrudedHeight = params.extrudedHeight; - var attributes = attr.attributes; - var indices = attr.indices; - var positions = attributes.position.values; - var length = positions.length; - var newPositions = new Float64Array(length * 6); - var extrudedPositions = new Float64Array(length); - extrudedPositions.set(positions); - var wallPositions = new Float64Array(length * 4); - - positions = PolygonPipeline.scaleToGeodeticHeight(positions, height, ellipsoid); - wallPositions = addWallPositions(positions, 0, wallPositions); - extrudedPositions = PolygonPipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); - wallPositions = addWallPositions(extrudedPositions, length * 2, wallPositions); - newPositions.set(positions); - newPositions.set(extrudedPositions, length); - newPositions.set(wallPositions, length * 2); - attributes.position.values = newPositions; - - attributes = extrudedAttributes(attributes, vertexFormat); - var i; - var size = length / 3; - if (params.shadowVolume) { - var topNormals = attributes.normal.values; - length = topNormals.length; - - var extrudeNormals = new Float32Array(length * 6); - for (i = 0; i < length; i ++) { - topNormals[i] = -topNormals[i]; - } - //only get normals for bottom layer that's going to be pushed down - extrudeNormals.set(topNormals, length); //bottom face - extrudeNormals = addWallPositions(topNormals, length*4, extrudeNormals); //bottom wall - attributes.extrudeDirection = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : extrudeNormals - }); - if (!vertexFormat.normal) { - attributes.normal = undefined; - } - } - - var iLength = indices.length; - var twoSize = size + size; - var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, iLength * 2 + twoSize * 3); - newIndices.set(indices); - var index = iLength; - for (i = 0; i < iLength; i += 3) { // bottom indices - var v0 = indices[i]; - var v1 = indices[i + 1]; - var v2 = indices[i + 2]; - newIndices[index++] = v2 + size; - newIndices[index++] = v1 + size; - newIndices[index++] = v0 + size; - } - - var UL, LL, UR, LR; - - for (i = 0; i < twoSize; i += 2) { //wall indices - UL = i + twoSize; - LL = UL + twoSize; - UR = UL + 1; - LR = LL + 1; - newIndices[index++] = UL; - newIndices[index++] = LL; - newIndices[index++] = UR; - newIndices[index++] = UR; - newIndices[index++] = LL; - newIndices[index++] = LR; - } - - return { - attributes : attributes, - indices : newIndices - }; - } - - var scratchCartesian1 = new Cartesian3(); - var scratchCartesian2 = new Cartesian3(); - var scratchCartographic = new Cartographic(); - - function computeOffsetPoints(position1, position2, ellipsoid, halfWidth, min, max) { - // Compute direction of offset the point - var direction = Cartesian3.subtract(position2, position1, scratchCartesian1); - Cartesian3.normalize(direction, direction); - var normal = ellipsoid.geodeticSurfaceNormal(position1, scratchCartesian2); - var offsetDirection = Cartesian3.cross(direction, normal, scratchCartesian1); - Cartesian3.multiplyByScalar(offsetDirection, halfWidth, offsetDirection); - - var minLat = min.latitude; - var minLon = min.longitude; - var maxLat = max.latitude; - var maxLon = max.longitude; - - // Compute 2 offset points - Cartesian3.add(position1, offsetDirection, scratchCartesian2); - ellipsoid.cartesianToCartographic(scratchCartesian2, scratchCartographic); - - var lat = scratchCartographic.latitude; - var lon = scratchCartographic.longitude; - minLat = Math.min(minLat, lat); - minLon = Math.min(minLon, lon); - maxLat = Math.max(maxLat, lat); - maxLon = Math.max(maxLon, lon); - - Cartesian3.subtract(position1, offsetDirection, scratchCartesian2); - ellipsoid.cartesianToCartographic(scratchCartesian2, scratchCartographic); - - lat = scratchCartographic.latitude; - lon = scratchCartographic.longitude; - minLat = Math.min(minLat, lat); - minLon = Math.min(minLon, lon); - maxLat = Math.max(maxLat, lat); - maxLon = Math.max(maxLon, lon); - - min.latitude = minLat; - min.longitude = minLon; - max.latitude = maxLat; - max.longitude = maxLon; - } - - var scratchCartesianOffset = new Cartesian3(); - var scratchCartesianEnds = new Cartesian3(); - var scratchCartographicMin = new Cartographic(); - var scratchCartographicMax = new Cartographic(); - - function computeRectangle(positions, ellipsoid, width, cornerType) { - positions = scaleToSurface(positions, ellipsoid); - var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - var length = cleanPositions.length; - if (length < 2 || width <= 0) { - return new Rectangle(); - } - var halfWidth = width * 0.5; - - scratchCartographicMin.latitude = Number.POSITIVE_INFINITY; - scratchCartographicMin.longitude = Number.POSITIVE_INFINITY; - scratchCartographicMax.latitude = Number.NEGATIVE_INFINITY; - scratchCartographicMax.longitude = Number.NEGATIVE_INFINITY; - - var lat, lon; - if (cornerType === CornerType.ROUNDED) { - // Compute start cap - var first = cleanPositions[0]; - Cartesian3.subtract(first, cleanPositions[1], scratchCartesianOffset); - Cartesian3.normalize(scratchCartesianOffset, scratchCartesianOffset); - Cartesian3.multiplyByScalar(scratchCartesianOffset, halfWidth, scratchCartesianOffset); - Cartesian3.add(first, scratchCartesianOffset, scratchCartesianEnds); - - ellipsoid.cartesianToCartographic(scratchCartesianEnds, scratchCartographic); - lat = scratchCartographic.latitude; - lon = scratchCartographic.longitude; - scratchCartographicMin.latitude = Math.min(scratchCartographicMin.latitude, lat); - scratchCartographicMin.longitude = Math.min(scratchCartographicMin.longitude, lon); - scratchCartographicMax.latitude = Math.max(scratchCartographicMax.latitude, lat); - scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon); - } - - // Compute the rest - for (var i = 0; i < length-1; ++i) { - computeOffsetPoints(cleanPositions[i], cleanPositions[i+1], ellipsoid, halfWidth, - scratchCartographicMin, scratchCartographicMax); - } - - // Compute ending point - var last = cleanPositions[length-1]; - Cartesian3.subtract(last, cleanPositions[length-2], scratchCartesianOffset); - Cartesian3.normalize(scratchCartesianOffset, scratchCartesianOffset); - Cartesian3.multiplyByScalar(scratchCartesianOffset, halfWidth, scratchCartesianOffset); - Cartesian3.add(last, scratchCartesianOffset, scratchCartesianEnds); - computeOffsetPoints(last, scratchCartesianEnds, ellipsoid, halfWidth, - scratchCartographicMin, scratchCartographicMax); - - if (cornerType === CornerType.ROUNDED) { - // Compute end cap - ellipsoid.cartesianToCartographic(scratchCartesianEnds, scratchCartographic); - lat = scratchCartographic.latitude; - lon = scratchCartographic.longitude; - scratchCartographicMin.latitude = Math.min(scratchCartographicMin.latitude, lat); - scratchCartographicMin.longitude = Math.min(scratchCartographicMin.longitude, lon); - scratchCartographicMax.latitude = Math.max(scratchCartographicMax.latitude, lat); - scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon); - } - - var rectangle = new Rectangle(); - rectangle.north = scratchCartographicMax.latitude; - rectangle.south = scratchCartographicMin.latitude; - rectangle.east = scratchCartographicMax.longitude; - rectangle.west = scratchCartographicMin.longitude; - - return rectangle; - } +define('Core/ColorGeometryInstanceAttribute',[ + './Color', + './ComponentDatatype', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError' + ], function( + Color, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + DeveloperError) { + 'use strict'; /** - * A description of a corridor. Corridor geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * Value and type information for per-instance geometry color. * - * @alias CorridorGeometry + * @alias ColorGeometryInstanceAttribute * @constructor * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor. - * @param {Number} options.width The distance between the edges of the corridor in meters. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0] The distance in meters between the ellipsoid surface and the positions. - * @param {Number} [options.extrudedHeight] The distance in meters between the ellipsoid surface and the extruded face. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. - * - * @see CorridorGeometry.createGeometry - * @see Packable + * @param {Number} [red=1.0] The red component. + * @param {Number} [green=1.0] The green component. + * @param {Number} [blue=1.0] The blue component. + * @param {Number} [alpha=1.0] The alpha component. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo} * * @example - * var corridor = new Cesium.CorridorGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, - * positions : Cesium.Cartesian3.fromDegreesArray([-72.0, 40.0, -70.0, 35.0]), - * width : 100000 + * var instance = new Cesium.GeometryInstance({ + * geometry : Cesium.BoxGeometry.fromDimensions({ + * dimensions : new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0) + * }), + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(0.0, 0.0)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), + * id : 'box', + * attributes : { + * color : new Cesium.ColorGeometryInstanceAttribute(red, green, blue, alpha) + * } * }); + * + * @see GeometryInstance + * @see GeometryInstanceAttribute */ - function CorridorGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.positions; - var width = options.width; + function ColorGeometryInstanceAttribute(red, green, blue, alpha) { + red = defaultValue(red, 1.0); + green = defaultValue(green, 1.0); + blue = defaultValue(blue, 1.0); + alpha = defaultValue(alpha, 1.0); - if (!defined(positions)) { - throw new DeveloperError('options.positions is required.'); - } - if (!defined(width)) { - throw new DeveloperError('options.width is required.'); - } - - this._positions = positions; - this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); - this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); - this._width = width; - this._height = defaultValue(options.height, 0); - this._extrudedHeight = defaultValue(options.extrudedHeight, this._height); - this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); - this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._shadowVolume = defaultValue(options.shadowVolume, false); - this._workerName = 'createCorridorGeometry'; - this._rectangle = computeRectangle(positions, this._ellipsoid, width, this._cornerType); + /** + * The values for the attributes stored in a typed array. + * + * @type Uint8Array + * + * @default [255, 255, 255, 255] + */ + this.value = new Uint8Array([ + Color.floatToByte(red), + Color.floatToByte(green), + Color.floatToByte(blue), + Color.floatToByte(alpha) + ]); + } + + defineProperties(ColorGeometryInstanceAttribute.prototype, { + /** + * The datatype of each component in the attribute, e.g., individual elements in + * {@link ColorGeometryInstanceAttribute#value}. + * + * @memberof ColorGeometryInstanceAttribute.prototype + * + * @type {ComponentDatatype} + * @readonly + * + * @default {@link ComponentDatatype.UNSIGNED_BYTE} + */ + componentDatatype : { + get : function() { + return ComponentDatatype.UNSIGNED_BYTE; + } + }, /** - * The number of elements used to pack the object into an array. + * The number of components in the attributes, i.e., {@link ColorGeometryInstanceAttribute#value}. + * + * @memberof ColorGeometryInstanceAttribute.prototype + * * @type {Number} + * @readonly + * + * @default 4 */ - this.packedLength = 1 + positions.length * Cartesian3.packedLength + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 6; - } + componentsPerAttribute : { + get : function() { + return 4; + } + }, + + /** + * When <code>true</code> and <code>componentDatatype</code> is an integer format, + * indicate that the components should be mapped to the range [0, 1] (unsigned) + * or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * + * @memberof ColorGeometryInstanceAttribute.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + normalize : { + get : function() { + return true; + } + } + }); /** - * Stores the provided instance into the provided array. + * Creates a new {@link ColorGeometryInstanceAttribute} instance given the provided {@link Color}. * - * @param {CorridorGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {Color} color The color. + * @returns {ColorGeometryInstanceAttribute} The new {@link ColorGeometryInstanceAttribute} instance. * - * @returns {Number[]} The array that was packed into + * @example + * var instance = new Cesium.GeometryInstance({ + * geometry : geometry, + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CORNFLOWERBLUE), + * } + * }); */ - CorridorGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); + ColorGeometryInstanceAttribute.fromColor = function(color) { + if (!defined(color)) { + throw new DeveloperError('color is required.'); } - startingIndex = defaultValue(startingIndex, 0); - - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; - - for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); - } - - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; - - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - - Rectangle.pack(value._rectangle, array, startingIndex); - startingIndex += Rectangle.packedLength; - - array[startingIndex++] = value._width; - array[startingIndex++] = value._height; - array[startingIndex++] = value._extrudedHeight; - array[startingIndex++] = value._cornerType; - array[startingIndex++] = value._granularity; - array[startingIndex] = value._shadowVolume ? 1.0 : 0.0; - - return array; - }; - - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchVertexFormat = new VertexFormat(); - var scratchRectangle = new Rectangle(); - var scratchOptions = { - positions : undefined, - ellipsoid : scratchEllipsoid, - vertexFormat : scratchVertexFormat, - width : undefined, - height : undefined, - extrudedHeight : undefined, - cornerType : undefined, - granularity : undefined, - shadowVolume: undefined + return new ColorGeometryInstanceAttribute(color.red, color.green, color.blue, color.alpha); }; /** - * Retrieves an instance from a packed array. + * Converts a color to a typed array that can be used to assign a color attribute. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {CorridorGeometry} [result] The object into which to store the result. - * @returns {CorridorGeometry} The modified result parameter or a new CorridorGeometry instance if one was not provided. + * @param {Color} color The color. + * @param {Uint8Array} [result] The array to store the result in, if undefined a new instance will be created. + * + * @returns {Uint8Array} The modified result parameter or a new instance if result was undefined. + * + * @example + * var attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA, attributes.color); */ - CorridorGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + ColorGeometryInstanceAttribute.toValue = function(color, result) { + if (!defined(color)) { + throw new DeveloperError('color is required.'); } - startingIndex = defaultValue(startingIndex, 0); - - var length = array[startingIndex++]; - var positions = new Array(length); - - for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); + if (!defined(result)) { + return new Uint8Array(color.toBytes()); } + return color.toBytes(result); + }; - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + /** + * Compares the provided ColorGeometryInstanceAttributes and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {ColorGeometryInstanceAttribute} [left] The first ColorGeometryInstanceAttribute. + * @param {ColorGeometryInstanceAttribute} [right] The second ColorGeometryInstanceAttribute. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + ColorGeometryInstanceAttribute.equals = function(left, right) { + return (left === right) || + (defined(left) && + defined(right) && + left.value[0] === right.value[0] && + left.value[1] === right.value[1] && + left.value[2] === right.value[2] && + left.value[3] === right.value[3]); + }; - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + return ColorGeometryInstanceAttribute; +}); - var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); - startingIndex += Rectangle.packedLength; +define('Core/CompressedTextureBuffer',[ + './defined', + './defineProperties' + ], function( + defined, + defineProperties) { + 'use strict'; - var width = array[startingIndex++]; - var height = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var cornerType = array[startingIndex++]; - var granularity = array[startingIndex++]; - var shadowVolume = array[startingIndex] === 1.0; + /** + * Describes a compressed texture and contains a compressed texture buffer. + * + * @param {PixelFormat} internalFormat The pixel format of the compressed texture. + * @param {Number} width The width of the texture. + * @param {Number} height The height of the texture. + * @param {Uint8Array} buffer The compressed texture buffer. + */ + function CompressedTextureBuffer(internalFormat, width, height, buffer) { + this._format = internalFormat; + this._width = width; + this._height = height; + this._buffer = buffer; + } - if (!defined(result)) { - scratchOptions.positions = positions; - scratchOptions.width = width; - scratchOptions.height = height; - scratchOptions.extrudedHeight = extrudedHeight; - scratchOptions.cornerType = cornerType; - scratchOptions.granularity = granularity; - scratchOptions.shadowVolume = shadowVolume; - return new CorridorGeometry(scratchOptions); + defineProperties(CompressedTextureBuffer.prototype, { + /** + * The format of the compressed texture. + * @type PixelFormat + * @readonly + */ + internalFormat : { + get : function() { + return this._format; + } + }, + /** + * The width of the texture. + * @type Number + * @readonly + */ + width : { + get : function() { + return this._width; + } + }, + /** + * The height of the texture. + * @type Number + * @readonly + */ + height : { + get : function() { + return this._height; + } + }, + /** + * The compressed texture buffer. + * @type Uint8Array + * @readonly + */ + bufferView : { + get : function() { + return this._buffer; + } } + }); - result._positions = positions; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._width = width; - result._height = height; - result._extrudedHeight = extrudedHeight; - result._cornerType = cornerType; - result._granularity = granularity; - result._rectangle = Rectangle.clone(rectangle); - result._shadowVolume = shadowVolume; + /** + * Creates a shallow clone of a compressed texture buffer. + * + * @param {CompressedTextureBuffer} object The compressed texture buffer to be cloned. + * @return {CompressedTextureBuffer} A shallow clone of the compressed texture buffer. + */ + CompressedTextureBuffer.clone = function(object) { + if (!defined(object)) { + return undefined; + } - return result; + return new CompressedTextureBuffer(object._format, object._width, object._height, object._buffer); }; /** - * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. + * Creates a shallow clone of this compressed texture buffer. * - * @param {CorridorGeometry} corridorGeometry A description of the corridor. - * @returns {Geometry|undefined} The computed vertices and indices. + * @return {CompressedTextureBuffer} A shallow clone of the compressed texture buffer. */ - CorridorGeometry.createGeometry = function(corridorGeometry) { - var positions = corridorGeometry._positions; - var height = corridorGeometry._height; - var width = corridorGeometry._width; - var extrudedHeight = corridorGeometry._extrudedHeight; - var extrude = (height !== extrudedHeight); - var ellipsoid = corridorGeometry._ellipsoid; - - positions = scaleToSurface(positions, ellipsoid); - var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - - if ((cleanPositions.length < 2) || (width <= 0)) { - return; - } + CompressedTextureBuffer.prototype.clone = function() { + return CompressedTextureBuffer.clone(this); + }; - var vertexFormat = corridorGeometry._vertexFormat; - var params = { - ellipsoid : ellipsoid, - positions : cleanPositions, - width : width, - cornerType : corridorGeometry._cornerType, - granularity : corridorGeometry._granularity, - saveAttributes: true - }; - var attr; - if (extrude) { - var h = Math.max(height, extrudedHeight); - extrudedHeight = Math.min(height, extrudedHeight); - height = h; - params.height = height; - params.extrudedHeight = extrudedHeight; - params.shadowVolume = corridorGeometry._shadowVolume; - attr = computePositionsExtruded(params, vertexFormat); - } else { - var computedPositions = CorridorGeometryLibrary.computePositions(params); - attr = combine(computedPositions, vertexFormat, ellipsoid); - attr.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid); - } - var attributes = attr.attributes; - var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); - if (!vertexFormat.position) { - attr.attributes.position.values = undefined; - } + return CompressedTextureBuffer; +}); - return new Geometry({ - attributes : attributes, - indices : attr.indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : boundingSphere - }); - }; +define('Core/CornerType',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; /** - * @private + * Style options for corners. + * + * @demo The {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} + * demonstrates the three corner types, as used by {@link CorridorGraphics}. + * + * @exports CornerType */ - CorridorGeometry.createShadowVolume = function(corridorGeometry, minHeightFunc, maxHeightFunc) { - var granularity = corridorGeometry._granularity; - var ellipsoid = corridorGeometry._ellipsoid; - - var minHeight = minHeightFunc(granularity, ellipsoid); - var maxHeight = maxHeightFunc(granularity, ellipsoid); + var CornerType = { + /** + * <img src="Images/CornerTypeRounded.png" style="vertical-align: middle;" width="186" height="189" /> + * + * Corner has a smooth edge. + * @type {Number} + * @constant + */ + ROUNDED : 0, - return new CorridorGeometry({ - positions : corridorGeometry._positions, - width : corridorGeometry._width, - cornerType : corridorGeometry._cornerType, - ellipsoid : ellipsoid, - granularity : granularity, - extrudedHeight : minHeight, - height : maxHeight, - vertexFormat : VertexFormat.POSITION_ONLY, - shadowVolume: true - }); - }; + /** + * <img src="Images/CornerTypeMitered.png" style="vertical-align: middle;" width="186" height="189" /> + * + * Corner point is the intersection of adjacent edges. + * @type {Number} + * @constant + */ + MITERED : 1, - defineProperties(CorridorGeometry.prototype, { /** - * @private + * <img src="Images/CornerTypeBeveled.png" style="vertical-align: middle;" width="186" height="189" /> + * + * Corner is clipped. + * @type {Number} + * @constant */ - rectangle : { - get : function() { - return this._rectangle; - } - } - }); + BEVELED : 2 + }; - return CorridorGeometry; + return freezeObject(CornerType); }); -define('Core/CorridorOutlineGeometry',[ - './arrayRemoveDuplicates', - './BoundingSphere', +define('Core/EllipsoidGeodesic',[ './Cartesian3', + './Cartographic', './Check', - './ComponentDatatype', - './CornerType', - './CorridorGeometryLibrary', './defaultValue', './defined', + './defineProperties', './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PolygonPipeline', - './PrimitiveType' + './Math' ], function( - arrayRemoveDuplicates, - BoundingSphere, Cartesian3, + Cartographic, Check, - ComponentDatatype, - CornerType, - CorridorGeometryLibrary, defaultValue, defined, + defineProperties, Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PolygonPipeline, - PrimitiveType) { + CesiumMath) { 'use strict'; - var cartesian1 = new Cartesian3(); - var cartesian2 = new Cartesian3(); - var cartesian3 = new Cartesian3(); + function setConstants(ellipsoidGeodesic) { + var uSquared = ellipsoidGeodesic._uSquared; + var a = ellipsoidGeodesic._ellipsoid.maximumRadius; + var b = ellipsoidGeodesic._ellipsoid.minimumRadius; + var f = (a - b) / a; - function scaleToSurface(positions, ellipsoid) { - for (var i = 0; i < positions.length; i++) { - positions[i] = ellipsoid.scaleToGeodeticSurface(positions[i], positions[i]); - } - return positions; - } + var cosineHeading = Math.cos(ellipsoidGeodesic._startHeading); + var sineHeading = Math.sin(ellipsoidGeodesic._startHeading); - function combine(computedPositions, cornerType) { - var wallIndices = []; - var positions = computedPositions.positions; - var corners = computedPositions.corners; - var endPositions = computedPositions.endPositions; - var attributes = new GeometryAttributes(); - var corner; - var leftCount = 0; - var rightCount = 0; - var i; - var indicesLength = 0; - var length; - for (i = 0; i < positions.length; i += 2) { - length = positions[i].length - 3; - leftCount += length; //subtracting 3 to account for duplicate points at corners - indicesLength += length / 3 * 4; - rightCount += positions[i + 1].length - 3; - } - leftCount += 3; //add back count for end positions - rightCount += 3; - for (i = 0; i < corners.length; i++) { - corner = corners[i]; - var leftSide = corners[i].leftPositions; - if (defined(leftSide)) { - length = leftSide.length; - leftCount += length; - indicesLength += length / 3 * 2; - } else { - length = corners[i].rightPositions.length; - rightCount += length; - indicesLength += length / 3 * 2; - } - } + var tanU = (1 - f) * Math.tan(ellipsoidGeodesic._start.latitude); - var addEndPositions = defined(endPositions); - var endPositionLength; - if (addEndPositions) { - endPositionLength = endPositions[0].length - 3; - leftCount += endPositionLength; - rightCount += endPositionLength; - endPositionLength /= 3; - indicesLength += endPositionLength * 4; - } - var size = leftCount + rightCount; - var finalPositions = new Float64Array(size); - var front = 0; - var back = size - 1; - var UL, LL, UR, LR; - var rightPos, leftPos; - var halfLength = endPositionLength / 2; + var cosineU = 1.0 / Math.sqrt(1.0 + tanU * tanU); + var sineU = cosineU * tanU; - var indices = IndexDatatype.createTypedArray(size / 3, indicesLength + 4); - var index = 0; + var sigma = Math.atan2(tanU, cosineHeading); - indices[index++] = front / 3; - indices[index++] = (back - 2) / 3; - if (addEndPositions) { // add rounded end - wallIndices.push(front / 3); - leftPos = cartesian1; - rightPos = cartesian2; - var firstEndPositions = endPositions[0]; - for (i = 0; i < halfLength; i++) { - leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); - rightPos = Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos); - CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); - CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + var sineAlpha = cosineU * sineHeading; + var sineSquaredAlpha = sineAlpha * sineAlpha; - LL = front / 3; - LR = LL + 1; - UL = (back - 2) / 3; - UR = UL - 1; - indices[index++] = UL; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + var cosineSquaredAlpha = 1.0 - sineSquaredAlpha; + var cosineAlpha = Math.sqrt(cosineSquaredAlpha); - front += 3; - back -= 3; - } - } + var u2Over4 = uSquared / 4.0; + var u4Over16 = u2Over4 * u2Over4; + var u6Over64 = u4Over16 * u2Over4; + var u8Over256 = u4Over16 * u4Over16; - var posIndex = 0; - var rightEdge = positions[posIndex++]; //add first two edges - var leftEdge = positions[posIndex++]; - finalPositions.set(rightEdge, front); - finalPositions.set(leftEdge, back - leftEdge.length + 1); + var a0 = (1.0 + u2Over4 - 3.0 * u4Over16 / 4.0 + 5.0 * u6Over64 / 4.0 - 175.0 * u8Over256 / 64.0); + var a1 = (1.0 - u2Over4 + 15.0 * u4Over16 / 8.0 - 35.0 * u6Over64 / 8.0); + var a2 = (1.0 - 3.0 * u2Over4 + 35.0 * u4Over16 / 4.0); + var a3 = (1.0 - 5.0 * u2Over4); - length = leftEdge.length - 3; - wallIndices.push(front / 3, (back - 2) / 3); - for (i = 0; i < length; i += 3) { - LL = front / 3; - LR = LL + 1; - UL = (back - 2) / 3; - UR = UL - 1; - indices[index++] = UL; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + var distanceRatio = a0 * sigma - a1 * Math.sin(2.0 * sigma) * u2Over4 / 2.0 - a2 * Math.sin(4.0 * sigma) * u4Over16 / 16.0 - + a3 * Math.sin(6.0 * sigma) * u6Over64 / 48.0 - Math.sin(8.0 * sigma) * 5.0 * u8Over256 / 512; - front += 3; - back -= 3; - } + var constants = ellipsoidGeodesic._constants; - for (i = 0; i < corners.length; i++) { - var j; - corner = corners[i]; - var l = corner.leftPositions; - var r = corner.rightPositions; - var start; - var outsidePoint = cartesian3; - if (defined(l)) { - back -= 3; - start = UR; - wallIndices.push(LR); - for (j = 0; j < l.length / 3; j++) { - outsidePoint = Cartesian3.fromArray(l, j * 3, outsidePoint); - indices[index++] = start - j - 1; - indices[index++] = start - j; - CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); - back -= 3; - } - wallIndices.push(start - Math.floor(l.length / 6)); - if (cornerType === CornerType.BEVELED) { - wallIndices.push((back - 2) / 3 + 1); - } - front += 3; - } else { - front += 3; - start = LR; - wallIndices.push(UR); - for (j = 0; j < r.length / 3; j++) { - outsidePoint = Cartesian3.fromArray(r, j * 3, outsidePoint); - indices[index++] = start + j; - indices[index++] = start + j + 1; - CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); - front += 3; - } - wallIndices.push(start + Math.floor(r.length / 6)); - if (cornerType === CornerType.BEVELED) { - wallIndices.push(front / 3 - 1); - } - back -= 3; - } - rightEdge = positions[posIndex++]; - leftEdge = positions[posIndex++]; - rightEdge.splice(0, 3); //remove duplicate points added by corner - leftEdge.splice(leftEdge.length - 3, 3); - finalPositions.set(rightEdge, front); - finalPositions.set(leftEdge, back - leftEdge.length + 1); - length = leftEdge.length - 3; + constants.a = a; + constants.b = b; + constants.f = f; + constants.cosineHeading = cosineHeading; + constants.sineHeading = sineHeading; + constants.tanU = tanU; + constants.cosineU = cosineU; + constants.sineU = sineU; + constants.sigma = sigma; + constants.sineAlpha = sineAlpha; + constants.sineSquaredAlpha = sineSquaredAlpha; + constants.cosineSquaredAlpha = cosineSquaredAlpha; + constants.cosineAlpha = cosineAlpha; + constants.u2Over4 = u2Over4; + constants.u4Over16 = u4Over16; + constants.u6Over64 = u6Over64; + constants.u8Over256 = u8Over256; + constants.a0 = a0; + constants.a1 = a1; + constants.a2 = a2; + constants.a3 = a3; + constants.distanceRatio = distanceRatio; + } - for (j = 0; j < leftEdge.length; j += 3) { - LR = front / 3; - LL = LR - 1; - UR = (back - 2) / 3; - UL = UR + 1; - indices[index++] = UL; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; - front += 3; - back -= 3; - } - front -= 3; - back += 3; - wallIndices.push(front / 3, (back - 2) / 3); - } + function computeC(f, cosineSquaredAlpha) { + return f * cosineSquaredAlpha * (4.0 + f * (4.0 - 3.0 * cosineSquaredAlpha)) / 16.0; + } - if (addEndPositions) { // add rounded end - front += 3; - back -= 3; - leftPos = cartesian1; - rightPos = cartesian2; - var lastEndPositions = endPositions[1]; - for (i = 0; i < halfLength; i++) { - leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); - rightPos = Cartesian3.fromArray(lastEndPositions, i * 3, rightPos); - CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); - CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + function computeDeltaLambda(f, sineAlpha, cosineSquaredAlpha, sigma, sineSigma, cosineSigma, cosineTwiceSigmaMidpoint) { + var C = computeC(f, cosineSquaredAlpha); - LR = front / 3; - LL = LR - 1; - UR = (back - 2) / 3; - UL = UR + 1; - indices[index++] = UL; - indices[index++] = UR; - indices[index++] = LL; - indices[index++] = LR; + return (1.0 - C) * f * sineAlpha * (sigma + C * sineSigma * (cosineTwiceSigmaMidpoint + + C * cosineSigma * (2.0 * cosineTwiceSigmaMidpoint * cosineTwiceSigmaMidpoint - 1.0))); + } - front += 3; - back -= 3; - } + function vincentyInverseFormula(ellipsoidGeodesic, major, minor, firstLongitude, firstLatitude, secondLongitude, secondLatitude) { + var eff = (major - minor) / major; + var l = secondLongitude - firstLongitude; - wallIndices.push(front / 3); - } else { - wallIndices.push(front / 3, (back - 2) / 3); - } - indices[index++] = front / 3; - indices[index++] = (back - 2) / 3; + var u1 = Math.atan((1 - eff) * Math.tan(firstLatitude)); + var u2 = Math.atan((1 - eff) * Math.tan(secondLatitude)); - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : finalPositions - }); + var cosineU1 = Math.cos(u1); + var sineU1 = Math.sin(u1); + var cosineU2 = Math.cos(u2); + var sineU2 = Math.sin(u2); - return { - attributes : attributes, - indices : indices, - wallIndices : wallIndices - }; - } + var cc = cosineU1 * cosineU2; + var cs = cosineU1 * sineU2; + var ss = sineU1 * sineU2; + var sc = sineU1 * cosineU2; - function computePositionsExtruded(params) { - var ellipsoid = params.ellipsoid; - var computedPositions = CorridorGeometryLibrary.computePositions(params); - var attr = combine(computedPositions, params.cornerType); - var wallIndices = attr.wallIndices; - var height = params.height; - var extrudedHeight = params.extrudedHeight; - var attributes = attr.attributes; - var indices = attr.indices; - var positions = attributes.position.values; - var length = positions.length; - var extrudedPositions = new Float64Array(length); - extrudedPositions.set(positions); - var newPositions = new Float64Array(length * 2); + var lambda = l; + var lambdaDot = CesiumMath.TWO_PI; - positions = PolygonPipeline.scaleToGeodeticHeight(positions, height, ellipsoid); - extrudedPositions = PolygonPipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); - newPositions.set(positions); - newPositions.set(extrudedPositions, length); - attributes.position.values = newPositions; + var cosineLambda = Math.cos(lambda); + var sineLambda = Math.sin(lambda); - length /= 3; - var i; - var iLength = indices.length; - var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, (iLength + wallIndices.length) * 2); - newIndices.set(indices); - var index = iLength; - for (i = 0; i < iLength; i += 2) { // bottom indices - var v0 = indices[i]; - var v1 = indices[i + 1]; - newIndices[index++] = v0 + length; - newIndices[index++] = v1 + length; - } + var sigma; + var cosineSigma; + var sineSigma; + var cosineSquaredAlpha; + var cosineTwiceSigmaMidpoint; - var UL, LL; - for (i = 0; i < wallIndices.length; i++) { //wall indices - UL = wallIndices[i]; - LL = UL + length; - newIndices[index++] = UL; - newIndices[index++] = LL; - } + do { + cosineLambda = Math.cos(lambda); + sineLambda = Math.sin(lambda); - return { - attributes : attributes, - indices : newIndices - }; + var temp = cs - sc * cosineLambda; + sineSigma = Math.sqrt(cosineU2 * cosineU2 * sineLambda * sineLambda + temp * temp); + cosineSigma = ss + cc * cosineLambda; + + sigma = Math.atan2(sineSigma, cosineSigma); + + var sineAlpha; + + if (sineSigma === 0.0) { + sineAlpha = 0.0; + cosineSquaredAlpha = 1.0; + } else { + sineAlpha = cc * sineLambda / sineSigma; + cosineSquaredAlpha = 1.0 - sineAlpha * sineAlpha; + } + + lambdaDot = lambda; + + cosineTwiceSigmaMidpoint = cosineSigma - 2.0 * ss / cosineSquaredAlpha; + + if (isNaN(cosineTwiceSigmaMidpoint)) { + cosineTwiceSigmaMidpoint = 0.0; + } + + lambda = l + computeDeltaLambda(eff, sineAlpha, cosineSquaredAlpha, + sigma, sineSigma, cosineSigma, cosineTwiceSigmaMidpoint); + } while (Math.abs(lambda - lambdaDot) > CesiumMath.EPSILON12); + + var uSquared = cosineSquaredAlpha * (major * major - minor * minor) / (minor * minor); + var A = 1.0 + uSquared * (4096.0 + uSquared * (uSquared * (320.0 - 175.0 * uSquared) - 768.0)) / 16384.0; + var B = uSquared * (256.0 + uSquared * (uSquared * (74.0 - 47.0 * uSquared) - 128.0)) / 1024.0; + + var cosineSquaredTwiceSigmaMidpoint = cosineTwiceSigmaMidpoint * cosineTwiceSigmaMidpoint; + var deltaSigma = B * sineSigma * (cosineTwiceSigmaMidpoint + B * (cosineSigma * + (2.0 * cosineSquaredTwiceSigmaMidpoint - 1.0) - B * cosineTwiceSigmaMidpoint * + (4.0 * sineSigma * sineSigma - 3.0) * (4.0 * cosineSquaredTwiceSigmaMidpoint - 3.0) / 6.0) / 4.0); + + var distance = minor * A * (sigma - deltaSigma); + + var startHeading = Math.atan2(cosineU2 * sineLambda, cs - sc * cosineLambda); + var endHeading = Math.atan2(cosineU1 * sineLambda, cs * cosineLambda - sc); + + ellipsoidGeodesic._distance = distance; + ellipsoidGeodesic._startHeading = startHeading; + ellipsoidGeodesic._endHeading = endHeading; + ellipsoidGeodesic._uSquared = uSquared; } - /** - * A description of a corridor outline. - * - * @alias CorridorOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor outline. - * @param {Number} options.width The distance between the edges of the corridor outline. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0] The distance in meters between the positions and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the extruded face and the ellipsoid surface. - * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. - * - * @see CorridorOutlineGeometry.createGeometry - * - * @example - * var corridor = new Cesium.CorridorOutlineGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArray([-72.0, 40.0, -70.0, 35.0]), - * width : 100000 - * }); - */ - function CorridorOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.positions; - var width = options.width; + var scratchCart1 = new Cartesian3(); + var scratchCart2 = new Cartesian3(); + function computeProperties(ellipsoidGeodesic, start, end, ellipsoid) { + var firstCartesian = Cartesian3.normalize(ellipsoid.cartographicToCartesian(start, scratchCart2), scratchCart1); + var lastCartesian = Cartesian3.normalize(ellipsoid.cartographicToCartesian(end, scratchCart2), scratchCart2); - Check.typeOf.object('options.positions', positions); - Check.typeOf.number('options.width', width); + Check.typeOf.number.greaterThanOrEquals('value', Math.abs(Math.abs(Cartesian3.angleBetween(firstCartesian, lastCartesian)) - Math.PI), 0.0125); - this._positions = positions; - this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); - this._width = width; - this._height = defaultValue(options.height, 0); - this._extrudedHeight = defaultValue(options.extrudedHeight, this._height); - this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); - this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._workerName = 'createCorridorOutlineGeometry'; + vincentyInverseFormula(ellipsoidGeodesic, ellipsoid.maximumRadius, ellipsoid.minimumRadius, + start.longitude, start.latitude, end.longitude, end.latitude); - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = 1 + positions.length * Cartesian3.packedLength + Ellipsoid.packedLength + 5; + ellipsoidGeodesic._start = Cartographic.clone(start, ellipsoidGeodesic._start); + ellipsoidGeodesic._end = Cartographic.clone(end, ellipsoidGeodesic._end); + ellipsoidGeodesic._start.height = 0; + ellipsoidGeodesic._end.height = 0; + + setConstants(ellipsoidGeodesic); } /** - * Stores the provided instance into the provided array. + * Initializes a geodesic on the ellipsoid connecting the two provided planetodetic points. * - * @param {CorridorOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @alias EllipsoidGeodesic + * @constructor * - * @returns {Number[]} The array that was packed into + * @param {Cartographic} [start] The initial planetodetic point on the path. + * @param {Cartographic} [end] The final planetodetic point on the path. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the geodesic lies. */ - CorridorOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.typeOf.object('array', array); - - startingIndex = defaultValue(startingIndex, 0); + function EllipsoidGeodesic(start, end, ellipsoid) { + var e = defaultValue(ellipsoid, Ellipsoid.WGS84); + this._ellipsoid = e; + this._start = new Cartographic(); + this._end = new Cartographic(); - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; + this._constants = {}; + this._startHeading = undefined; + this._endHeading = undefined; + this._distance = undefined; + this._uSquared = undefined; - for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); + if (defined(start) && defined(end)) { + computeProperties(this, start, end, e); } + } - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + defineProperties(EllipsoidGeodesic.prototype, { + /** + * Gets the ellipsoid. + * @memberof EllipsoidGeodesic.prototype + * @type {Ellipsoid} + * @readonly + */ + ellipsoid : { + get : function() { + return this._ellipsoid; + } + }, - array[startingIndex++] = value._width; - array[startingIndex++] = value._height; - array[startingIndex++] = value._extrudedHeight; - array[startingIndex++] = value._cornerType; - array[startingIndex] = value._granularity; + /** + * Gets the surface distance between the start and end point + * @memberof EllipsoidGeodesic.prototype + * @type {Number} + * @readonly + */ + surfaceDistance : { + get : function() { + Check.defined('distance', this._distance); + + return this._distance; + } + }, - return array; + /** + * Gets the initial planetodetic point on the path. + * @memberof EllipsoidGeodesic.prototype + * @type {Cartographic} + * @readonly + */ + start : { + get : function() { + return this._start; + } + }, + + /** + * Gets the final planetodetic point on the path. + * @memberof EllipsoidGeodesic.prototype + * @type {Cartographic} + * @readonly + */ + end : { + get : function() { + return this._end; + } + }, + + /** + * Gets the heading at the initial point. + * @memberof EllipsoidGeodesic.prototype + * @type {Number} + * @readonly + */ + startHeading : { + get : function() { + Check.defined('distance', this._distance); + + return this._startHeading; + } + }, + + /** + * Gets the heading at the final point. + * @memberof EllipsoidGeodesic.prototype + * @type {Number} + * @readonly + */ + endHeading : { + get : function() { + Check.defined('distance', this._distance); + + return this._endHeading; + } + } + }); + + /** + * Sets the start and end points of the geodesic + * + * @param {Cartographic} start The initial planetodetic point on the path. + * @param {Cartographic} end The final planetodetic point on the path. + */ + EllipsoidGeodesic.prototype.setEndPoints = function(start, end) { + Check.defined('start', start); + Check.defined('end', end); + + computeProperties(this, start, end, this._ellipsoid); }; - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchOptions = { - positions : undefined, - ellipsoid : scratchEllipsoid, - width : undefined, - height : undefined, - extrudedHeight : undefined, - cornerType : undefined, - granularity : undefined + /** + * Provides the location of a point at the indicated portion along the geodesic. + * + * @param {Number} fraction The portion of the distance between the initial and final points. + * @param {Cartographic} result The object in which to store the result. + * @returns {Cartographic} The location of the point along the geodesic. + */ + EllipsoidGeodesic.prototype.interpolateUsingFraction = function(fraction, result) { + return this.interpolateUsingSurfaceDistance(this._distance * fraction, result); }; /** - * Retrieves an instance from a packed array. + * Provides the location of a point at the indicated distance along the geodesic. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {CorridorOutlineGeometry} [result] The object into which to store the result. - * @returns {CorridorOutlineGeometry} The modified result parameter or a new CorridorOutlineGeometry instance if one was not provided. + * @param {Number} distance The distance from the inital point to the point of interest along the geodesic + * @param {Cartographic} result The object in which to store the result. + * @returns {Cartographic} The location of the point along the geodesic. + * + * @exception {DeveloperError} start and end must be set before calling function interpolateUsingSurfaceDistance */ - CorridorOutlineGeometry.unpack = function(array, startingIndex, result) { - Check.typeOf.object('array', array); + EllipsoidGeodesic.prototype.interpolateUsingSurfaceDistance = function(distance, result) { + Check.defined('distance', this._distance); - startingIndex = defaultValue(startingIndex, 0); + var constants = this._constants; - var length = array[startingIndex++]; - var positions = new Array(length); + var s = constants.distanceRatio + distance / constants.b; - for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); - } + var cosine2S = Math.cos(2.0 * s); + var cosine4S = Math.cos(4.0 * s); + var cosine6S = Math.cos(6.0 * s); + var sine2S = Math.sin(2.0 * s); + var sine4S = Math.sin(4.0 * s); + var sine6S = Math.sin(6.0 * s); + var sine8S = Math.sin(8.0 * s); - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + var s2 = s * s; + var s3 = s * s2; - var width = array[startingIndex++]; - var height = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var cornerType = array[startingIndex++]; - var granularity = array[startingIndex]; + var u8Over256 = constants.u8Over256; + var u2Over4 = constants.u2Over4; + var u6Over64 = constants.u6Over64; + var u4Over16 = constants.u4Over16; + var sigma = 2.0 * s3 * u8Over256 * cosine2S / 3.0 + + s * (1.0 - u2Over4 + 7.0 * u4Over16 / 4.0 - 15.0 * u6Over64 / 4.0 + 579.0 * u8Over256 / 64.0 - + (u4Over16 - 15.0 * u6Over64 / 4.0 + 187.0 * u8Over256 / 16.0) * cosine2S - + (5.0 * u6Over64 / 4.0 - 115.0 * u8Over256 / 16.0) * cosine4S - + 29.0 * u8Over256 * cosine6S / 16.0) + + (u2Over4 / 2.0 - u4Over16 + 71.0 * u6Over64 / 32.0 - 85.0 * u8Over256 / 16.0) * sine2S + + (5.0 * u4Over16 / 16.0 - 5.0 * u6Over64 / 4.0 + 383.0 * u8Over256 / 96.0) * sine4S - + s2 * ((u6Over64 - 11.0 * u8Over256 / 2.0) * sine2S + 5.0 * u8Over256 * sine4S / 2.0) + + (29.0 * u6Over64 / 96.0 - 29.0 * u8Over256 / 16.0) * sine6S + + 539.0 * u8Over256 * sine8S / 1536.0; - if (!defined(result)) { - scratchOptions.positions = positions; - scratchOptions.width = width; - scratchOptions.height = height; - scratchOptions.extrudedHeight = extrudedHeight; - scratchOptions.cornerType = cornerType; - scratchOptions.granularity = granularity; - return new CorridorOutlineGeometry(scratchOptions); - } + var theta = Math.asin(Math.sin(sigma) * constants.cosineAlpha); + var latitude = Math.atan(constants.a / constants.b * Math.tan(theta)); - result._positions = positions; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._width = width; - result._height = height; - result._extrudedHeight = extrudedHeight; - result._cornerType = cornerType; - result._granularity = granularity; + // Redefine in terms of relative argument of latitude. + sigma = sigma - constants.sigma; - return result; - }; + var cosineTwiceSigmaMidpoint = Math.cos(2.0 * constants.sigma + sigma); - /** - * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. - * - * @param {CorridorOutlineGeometry} corridorOutlineGeometry A description of the corridor. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - CorridorOutlineGeometry.createGeometry = function(corridorOutlineGeometry) { - var positions = corridorOutlineGeometry._positions; - var height = corridorOutlineGeometry._height; - var width = corridorOutlineGeometry._width; - var extrudedHeight = corridorOutlineGeometry._extrudedHeight; - var extrude = (height !== extrudedHeight); - var ellipsoid = corridorOutlineGeometry._ellipsoid; + var sineSigma = Math.sin(sigma); + var cosineSigma = Math.cos(sigma); - positions = scaleToSurface(positions, ellipsoid); - var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); + var cc = constants.cosineU * cosineSigma; + var ss = constants.sineU * sineSigma; - if ((cleanPositions.length < 2) || (width <= 0)) { - return; - } + var lambda = Math.atan2(sineSigma * constants.sineHeading, cc - ss * constants.cosineHeading); - var params = { - ellipsoid : ellipsoid, - positions : cleanPositions, - width : width, - cornerType : corridorOutlineGeometry._cornerType, - granularity : corridorOutlineGeometry._granularity, - saveAttributes : false - }; - var attr; - if (extrude) { - var h = Math.max(height, extrudedHeight); - extrudedHeight = Math.min(height, extrudedHeight); - height = h; - params.height = height; - params.extrudedHeight = extrudedHeight; - attr = computePositionsExtruded(params); - } else { - var computedPositions = CorridorGeometryLibrary.computePositions(params); - attr = combine(computedPositions, params.cornerType); - attr.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid); + var l = lambda - computeDeltaLambda(constants.f, constants.sineAlpha, constants.cosineSquaredAlpha, + sigma, sineSigma, cosineSigma, cosineTwiceSigmaMidpoint); + + if (defined(result)) { + result.longitude = this._start.longitude + l; + result.latitude = latitude; + result.height = 0.0; + return result; } - var attributes = attr.attributes; - var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); - return new Geometry({ - attributes : attributes, - indices : attr.indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : boundingSphere - }); + return new Cartographic(this._start.longitude + l, latitude, 0.0); }; - return CorridorOutlineGeometry; -}); - -define('Core/createGuid',[],function() { - 'use strict'; - - /** - * Creates a Globally unique identifier (GUID) string. A GUID is 128 bits long, and can guarantee uniqueness across space and time. - * - * @exports createGuid - * - * @returns {String} - * - * - * @example - * this.guid = Cesium.createGuid(); - * - * @see {@link http://www.ietf.org/rfc/rfc4122.txt|RFC 4122 A Universally Unique IDentifier (UUID) URN Namespace} - */ - function createGuid() { - // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random() * 16 | 0; - var v = c === 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - } - - return createGuid; + return EllipsoidGeodesic; }); -define('Core/CullingVolume',[ +define('Core/PolylinePipeline',[ './Cartesian3', - './Cartesian4', + './Cartographic', './defaultValue', './defined', './DeveloperError', - './Intersect', + './Ellipsoid', + './EllipsoidGeodesic', + './IntersectionTests', + './isArray', + './Math', + './Matrix4', './Plane' ], function( Cartesian3, - Cartesian4, + Cartographic, defaultValue, defined, DeveloperError, - Intersect, + Ellipsoid, + EllipsoidGeodesic, + IntersectionTests, + isArray, + CesiumMath, + Matrix4, Plane) { 'use strict'; /** - * The culling volume defined by planes. - * - * @alias CullingVolume - * @constructor - * - * @param {Cartesian4[]} [planes] An array of clipping planes. + * @private */ - function CullingVolume(planes) { - /** - * Each plane is represented by a Cartesian4 object, where the x, y, and z components - * define the unit vector normal to the plane, and the w component is the distance of the - * plane from the origin. - * @type {Cartesian4[]} - * @default [] - */ - this.planes = defaultValue(planes, []); - } - - var faces = [new Cartesian3(), new Cartesian3(), new Cartesian3()]; - Cartesian3.clone(Cartesian3.UNIT_X, faces[0]); - Cartesian3.clone(Cartesian3.UNIT_Y, faces[1]); - Cartesian3.clone(Cartesian3.UNIT_Z, faces[2]); + var PolylinePipeline = {}; - var scratchPlaneCenter = new Cartesian3(); - var scratchPlaneNormal = new Cartesian3(); - var scratchPlane = new Plane(new Cartesian3(1.0, 0.0, 0.0), 0.0); + PolylinePipeline.numberOfPoints = function(p0, p1, minDistance) { + var distance = Cartesian3.distance(p0, p1); + return Math.ceil(distance / minDistance); + }; - /** - * Constructs a culling volume from a bounding sphere. Creates six planes that create a box containing the sphere. - * The planes are aligned to the x, y, and z axes in world coordinates. - * - * @param {BoundingSphere} boundingSphere The bounding sphere used to create the culling volume. - * @param {CullingVolume} [result] The object onto which to store the result. - * @returns {CullingVolume} The culling volume created from the bounding sphere. - */ - CullingVolume.fromBoundingSphere = function(boundingSphere, result) { - if (!defined(boundingSphere)) { - throw new DeveloperError('boundingSphere is required.'); - } - - if (!defined(result)) { - result = new CullingVolume(); + var cartoScratch = new Cartographic(); + PolylinePipeline.extractHeights = function(positions, ellipsoid) { + var length = positions.length; + var heights = new Array(length); + for (var i = 0; i < length; i++) { + var p = positions[i]; + heights[i] = ellipsoid.cartesianToCartographic(p, cartoScratch).height; } + return heights; + }; - var length = faces.length; - var planes = result.planes; - planes.length = 2 * length; + var wrapLongitudeInversMatrix = new Matrix4(); + var wrapLongitudeOrigin = new Cartesian3(); + var wrapLongitudeXZNormal = new Cartesian3(); + var wrapLongitudeXZPlane = new Plane(Cartesian3.UNIT_X, 0.0); + var wrapLongitudeYZNormal = new Cartesian3(); + var wrapLongitudeYZPlane = new Plane(Cartesian3.UNIT_X, 0.0); + var wrapLongitudeIntersection = new Cartesian3(); + var wrapLongitudeOffset = new Cartesian3(); - var center = boundingSphere.center; - var radius = boundingSphere.radius; + var subdivideHeightsScratchArray = []; - var planeIndex = 0; + function subdivideHeights(numPoints, h0, h1) { + var heights = subdivideHeightsScratchArray; + heights.length = numPoints; - for (var i = 0; i < length; ++i) { - var faceNormal = faces[i]; + var i; + if (h0 === h1) { + for (i = 0; i < numPoints; i++) { + heights[i] = h0; + } + return heights; + } - var plane0 = planes[planeIndex]; - var plane1 = planes[planeIndex + 1]; + var dHeight = h1 - h0; + var heightPerVertex = dHeight / numPoints; - if (!defined(plane0)) { - plane0 = planes[planeIndex] = new Cartesian4(); - } - if (!defined(plane1)) { - plane1 = planes[planeIndex + 1] = new Cartesian4(); - } + for (i = 0; i < numPoints; i++) { + var h = h0 + i*heightPerVertex; + heights[i] = h; + } - Cartesian3.multiplyByScalar(faceNormal, -radius, scratchPlaneCenter); - Cartesian3.add(center, scratchPlaneCenter, scratchPlaneCenter); + return heights; + } - plane0.x = faceNormal.x; - plane0.y = faceNormal.y; - plane0.z = faceNormal.z; - plane0.w = -Cartesian3.dot(faceNormal, scratchPlaneCenter); + var carto1 = new Cartographic(); + var carto2 = new Cartographic(); + var cartesian = new Cartesian3(); + var scaleFirst = new Cartesian3(); + var scaleLast = new Cartesian3(); + var ellipsoidGeodesic = new EllipsoidGeodesic(); - Cartesian3.multiplyByScalar(faceNormal, radius, scratchPlaneCenter); - Cartesian3.add(center, scratchPlaneCenter, scratchPlaneCenter); + //Returns subdivided line scaled to ellipsoid surface starting at p1 and ending at p2. + //Result includes p1, but not include p2. This function is called for a sequence of line segments, + //and this prevents duplication of end point. + function generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, array, offset) { + var first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst); + var last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast); + var numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance); + var start = ellipsoid.cartesianToCartographic(first, carto1); + var end = ellipsoid.cartesianToCartographic(last, carto2); + var heights = subdivideHeights(numPoints, h0, h1); - plane1.x = -faceNormal.x; - plane1.y = -faceNormal.y; - plane1.z = -faceNormal.z; - plane1.w = -Cartesian3.dot(Cartesian3.negate(faceNormal, scratchPlaneNormal), scratchPlaneCenter); + ellipsoidGeodesic.setEndPoints(start, end); + var surfaceDistanceBetweenPoints = ellipsoidGeodesic.surfaceDistance / numPoints; - planeIndex += 2; + var index = offset; + start.height = h0; + var cart = ellipsoid.cartographicToCartesian(start, cartesian); + Cartesian3.pack(cart, array, index); + index += 3; + + for (var i = 1; i < numPoints; i++) { + var carto = ellipsoidGeodesic.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2); + carto.height = heights[i]; + cart = ellipsoid.cartographicToCartesian(carto, cartesian); + Cartesian3.pack(cart, array, index); + index += 3; } - return result; - }; + return index; + } /** - * Determines whether a bounding volume intersects the culling volume. + * Breaks a {@link Polyline} into segments such that it does not cross the ±180 degree meridian of an ellipsoid. * - * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. - * @returns {Intersect} Intersect.OUTSIDE, Intersect.INTERSECTING, or Intersect.INSIDE. + * @param {Cartesian3[]} positions The polyline's Cartesian positions. + * @param {Matrix4} [modelMatrix=Matrix4.IDENTITY] The polyline's model matrix. Assumed to be an affine + * transformation matrix, where the upper left 3x3 elements are a rotation matrix, and + * the upper three elements in the fourth column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. + * The matrix is not verified to be in the proper form. + * @returns {Object} An object with a <code>positions</code> property that is an array of positions and a + * <code>segments</code> property. + * + * + * @example + * var polylines = new Cesium.PolylineCollection(); + * var polyline = polylines.add(...); + * var positions = polyline.positions; + * var modelMatrix = polylines.modelMatrix; + * var segments = Cesium.PolylinePipeline.wrapLongitude(positions, modelMatrix); + * + * @see PolygonPipeline.wrapLongitude + * @see Polyline + * @see PolylineCollection */ - CullingVolume.prototype.computeVisibility = function(boundingVolume) { - if (!defined(boundingVolume)) { - throw new DeveloperError('boundingVolume is required.'); - } - - var planes = this.planes; - var intersecting = false; - for (var k = 0, len = planes.length; k < len; ++k) { - var result = boundingVolume.intersectPlane(Plane.fromCartesian4(planes[k], scratchPlane)); - if (result === Intersect.OUTSIDE) { - return Intersect.OUTSIDE; - } else if (result === Intersect.INTERSECTING) { - intersecting = true; + PolylinePipeline.wrapLongitude = function(positions, modelMatrix) { + var cartesians = []; + var segments = []; + + if (defined(positions) && positions.length > 0) { + modelMatrix = defaultValue(modelMatrix, Matrix4.IDENTITY); + var inverseModelMatrix = Matrix4.inverseTransformation(modelMatrix, wrapLongitudeInversMatrix); + + var origin = Matrix4.multiplyByPoint(inverseModelMatrix, Cartesian3.ZERO, wrapLongitudeOrigin); + var xzNormal = Cartesian3.normalize(Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian3.UNIT_Y, wrapLongitudeXZNormal), wrapLongitudeXZNormal); + var xzPlane = Plane.fromPointNormal(origin, xzNormal, wrapLongitudeXZPlane); + var yzNormal = Cartesian3.normalize(Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian3.UNIT_X, wrapLongitudeYZNormal), wrapLongitudeYZNormal); + var yzPlane = Plane.fromPointNormal(origin, yzNormal, wrapLongitudeYZPlane); + + var count = 1; + cartesians.push(Cartesian3.clone(positions[0])); + var prev = cartesians[0]; + + var length = positions.length; + for (var i = 1; i < length; ++i) { + var cur = positions[i]; + + // intersects the IDL if either endpoint is on the negative side of the yz-plane + if (Plane.getPointDistance(yzPlane, prev) < 0.0 || Plane.getPointDistance(yzPlane, cur) < 0.0) { + // and intersects the xz-plane + var intersection = IntersectionTests.lineSegmentPlane(prev, cur, xzPlane, wrapLongitudeIntersection); + if (defined(intersection)) { + // move point on the xz-plane slightly away from the plane + var offset = Cartesian3.multiplyByScalar(xzNormal, 5.0e-9, wrapLongitudeOffset); + if (Plane.getPointDistance(xzPlane, prev) < 0.0) { + Cartesian3.negate(offset, offset); + } + + cartesians.push(Cartesian3.add(intersection, offset, new Cartesian3())); + segments.push(count + 1); + + Cartesian3.negate(offset, offset); + cartesians.push(Cartesian3.add(intersection, offset, new Cartesian3())); + count = 1; + } + } + + cartesians.push(Cartesian3.clone(positions[i])); + count++; + + prev = cur; } + + segments.push(count); } - return intersecting ? Intersect.INTERSECTING : Intersect.INSIDE; + return { + positions : cartesians, + lengths : segments + }; }; /** - * Determines whether a bounding volume intersects the culling volume. - * - * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. - * @param {Number} parentPlaneMask A bit mask from the boundingVolume's parent's check against the same culling - * volume, such that if (planeMask & (1 << planeIndex) === 0), for k < 31, then - * the parent (and therefore this) volume is completely inside plane[planeIndex] - * and that plane check can be skipped. - * @returns {Number} A plane mask as described above (which can be applied to this boundingVolume's children). + * Subdivides polyline and raises all points to the specified height. Returns an array of numbers to represent the positions. + * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. + * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. + * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. + * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid. * - * @private + * @example + * var positions = Cesium.Cartesian3.fromDegreesArray([ + * -105.0, 40.0, + * -100.0, 38.0, + * -105.0, 35.0, + * -100.0, 32.0 + * ]); + * var surfacePositions = Cesium.PolylinePipeline.generateArc({ + * positons: positions + * }); */ - CullingVolume.prototype.computeVisibilityWithPlaneMask = function(boundingVolume, parentPlaneMask) { - if (!defined(boundingVolume)) { - throw new DeveloperError('boundingVolume is required.'); + PolylinePipeline.generateArc = function(options) { + if (!defined(options)) { + options = {}; } - if (!defined(parentPlaneMask)) { - throw new DeveloperError('parentPlaneMask is required.'); + var positions = options.positions; + if (!defined(positions)) { + throw new DeveloperError('options.positions is required.'); } - if (parentPlaneMask === CullingVolume.MASK_OUTSIDE || parentPlaneMask === CullingVolume.MASK_INSIDE) { - // parent is completely outside or completely inside, so this child is as well. - return parentPlaneMask; - } - - // Start with MASK_INSIDE (all zeros) so that after the loop, the return value can be compared with MASK_INSIDE. - // (Because if there are fewer than 31 planes, the upper bits wont be changed.) - var mask = CullingVolume.MASK_INSIDE; + var length = positions.length; + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var height = defaultValue(options.height, 0); + var hasHeightArray = isArray(height); - var planes = this.planes; - for (var k = 0, len = planes.length; k < len; ++k) { - // For k greater than 31 (since 31 is the maximum number of INSIDE/INTERSECTING bits we can store), skip the optimization. - var flag = (k < 31) ? (1 << k) : 0; - if (k < 31 && (parentPlaneMask & flag) === 0) { - // boundingVolume is known to be INSIDE this plane. - continue; + if (length < 1) { + return []; + } else if (length === 1) { + var p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst); + height = hasHeightArray ? height[0] : height; + if (height !== 0) { + var n = ellipsoid.geodeticSurfaceNormal(p, cartesian); + Cartesian3.multiplyByScalar(n, height, n); + Cartesian3.add(p, n, p); } - var result = boundingVolume.intersectPlane(Plane.fromCartesian4(planes[k], scratchPlane)); - if (result === Intersect.OUTSIDE) { - return CullingVolume.MASK_OUTSIDE; - } else if (result === Intersect.INTERSECTING) { - mask |= flag; - } + return [p.x, p.y, p.z]; } - return mask; - }; - - /** - * For plane masks (as used in {@link CullingVolume#computeVisibilityWithPlaneMask}), this special value - * represents the case where the object bounding volume is entirely outside the culling volume. - * - * @type {Number} - * @private - */ - CullingVolume.MASK_OUTSIDE = 0xffffffff; + var minDistance = options.minDistance; + if (!defined(minDistance)) { + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + } - /** - * For plane masks (as used in {@link CullingVolume.prototype.computeVisibilityWithPlaneMask}), this value - * represents the case where the object bounding volume is entirely inside the culling volume. - * - * @type {Number} - * @private - */ - CullingVolume.MASK_INSIDE = 0x00000000; + var numPoints = 0; + var i; - /** - * For plane masks (as used in {@link CullingVolume.prototype.computeVisibilityWithPlaneMask}), this value - * represents the case where the object bounding volume (may) intersect all planes of the culling volume. - * - * @type {Number} - * @private - */ - CullingVolume.MASK_INDETERMINATE = 0x7fffffff; + for (i = 0; i < length -1; i++) { + numPoints += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance); + } - return CullingVolume; -}); + var arrayLength = (numPoints + 1) * 3; + var newPositions = new Array(arrayLength); + var offset = 0; -define('Core/CylinderGeometryLibrary',[ - './Math' - ], function( - CesiumMath) { - 'use strict'; + for (i = 0; i < length - 1; i++) { + var p0 = positions[i]; + var p1 = positions[i + 1]; - /** - * @private - */ - var CylinderGeometryLibrary = {}; + var h0 = hasHeightArray ? height[i] : height; + var h1 = hasHeightArray ? height[i + 1] : height; - /** - * @private - */ - CylinderGeometryLibrary.computePositions = function(length, topRadius, bottomRadius, slices, fill){ - var topZ = length * 0.5; - var bottomZ = -topZ; + offset = generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, newPositions, offset); + } - var twoSlice = slices + slices; - var size = (fill) ? 2 * twoSlice : twoSlice; - var positions = new Float64Array(size*3); - var i; - var index = 0; - var tbIndex = 0; - var bottomOffset = (fill) ? twoSlice*3 : 0; - var topOffset = (fill) ? (twoSlice + slices)*3 : slices*3; + subdivideHeightsScratchArray.length = 0; - for (i = 0; i < slices; i++) { - var angle = i / slices * CesiumMath.TWO_PI; - var x = Math.cos(angle); - var y = Math.sin(angle); - var bottomX = x * bottomRadius; - var bottomY = y * bottomRadius; - var topX = x * topRadius; - var topY = y * topRadius; + var lastPoint = positions[length - 1]; + var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1); + carto.height = hasHeightArray ? height[length - 1] : height; + var cart = ellipsoid.cartographicToCartesian(carto, cartesian); + Cartesian3.pack(cart, newPositions, arrayLength - 3); - positions[tbIndex + bottomOffset] = bottomX; - positions[tbIndex + bottomOffset + 1] = bottomY; - positions[tbIndex + bottomOffset + 2] = bottomZ; + return newPositions; + }; - positions[tbIndex + topOffset] = topX; - positions[tbIndex + topOffset + 1] = topY; - positions[tbIndex + topOffset + 2] = topZ; - tbIndex += 3; - if (fill) { - positions[index++] = bottomX; - positions[index++] = bottomY; - positions[index++] = bottomZ; - positions[index++] = topX; - positions[index++] = topY; - positions[index++] = topZ; - } + /** + * Subdivides polyline and raises all points to the specified height. Returns an array of new {Cartesian3} positions. + * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. + * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. + * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. + * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid. + * + * @example + * var positions = Cesium.Cartesian3.fromDegreesArray([ + * -105.0, 40.0, + * -100.0, 38.0, + * -105.0, 35.0, + * -100.0, 32.0 + * ]); + * var surfacePositions = Cesium.PolylinePipeline.generateCartesianArc({ + * positons: positions + * }); + */ + PolylinePipeline.generateCartesianArc = function(options) { + var numberArray = PolylinePipeline.generateArc(options); + var size = numberArray.length/3; + var newPositions = new Array(size); + for (var i = 0; i < size; i++) { + newPositions[i] = Cartesian3.unpack(numberArray, i*3); } - - return positions; + return newPositions; }; - return CylinderGeometryLibrary; + return PolylinePipeline; }); -define('Core/CylinderGeometry',[ - './BoundingSphere', +define('Core/PolylineVolumeGeometryLibrary',[ './Cartesian2', './Cartesian3', - './ComponentDatatype', - './CylinderGeometryLibrary', - './defaultValue', - './defined', - './DeveloperError', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', + './Cartesian4', + './Cartographic', + './CornerType', + './EllipsoidTangentPlane', './Math', - './PrimitiveType', - './VertexFormat' + './Matrix3', + './Matrix4', + './PolylinePipeline', + './Quaternion', + './Transforms' ], function( - BoundingSphere, Cartesian2, Cartesian3, - ComponentDatatype, - CylinderGeometryLibrary, - defaultValue, - defined, - DeveloperError, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, + Cartesian4, + Cartographic, + CornerType, + EllipsoidTangentPlane, CesiumMath, - PrimitiveType, - VertexFormat) { + Matrix3, + Matrix4, + PolylinePipeline, + Quaternion, + Transforms) { 'use strict'; - var radiusScratch = new Cartesian2(); - var normalScratch = new Cartesian3(); - var bitangentScratch = new Cartesian3(); - var tangentScratch = new Cartesian3(); - var positionScratch = new Cartesian3(); + var scratch2Array = [new Cartesian3(), new Cartesian3()]; + var scratchCartesian1 = new Cartesian3(); + var scratchCartesian2 = new Cartesian3(); + var scratchCartesian3 = new Cartesian3(); + var scratchCartesian4 = new Cartesian3(); + var scratchCartesian5 = new Cartesian3(); + var scratchCartesian6 = new Cartesian3(); + var scratchCartesian7 = new Cartesian3(); + var scratchCartesian8 = new Cartesian3(); + var scratchCartesian9 = new Cartesian3(); + var scratch1 = new Cartesian3(); + var scratch2 = new Cartesian3(); /** - * A description of a cylinder. - * - * @alias CylinderGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Number} options.length The length of the cylinder. - * @param {Number} options.topRadius The radius of the top of the cylinder. - * @param {Number} options.bottomRadius The radius of the bottom of the cylinder. - * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * - * @exception {DeveloperError} options.length must be greater than 0. - * @exception {DeveloperError} options.topRadius must be greater than 0. - * @exception {DeveloperError} options.bottomRadius must be greater than 0. - * @exception {DeveloperError} bottomRadius and topRadius cannot both equal 0. - * @exception {DeveloperError} options.slices must be greater than or equal to 3. - * - * @see CylinderGeometry.createGeometry - * - * @example - * // create cylinder geometry - * var cylinder = new Cesium.CylinderGeometry({ - * length: 200000, - * topRadius: 80000, - * bottomRadius: 200000, - * }); - * var geometry = Cesium.CylinderGeometry.createGeometry(cylinder); + * @private */ - function CylinderGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var PolylineVolumeGeometryLibrary = {}; - var length = options.length; - var topRadius = options.topRadius; - var bottomRadius = options.bottomRadius; - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); - var slices = defaultValue(options.slices, 128); - - if (!defined(length)) { - throw new DeveloperError('options.length must be defined.'); - } - if (!defined(topRadius)) { - throw new DeveloperError('options.topRadius must be defined.'); - } - if (!defined(bottomRadius)) { - throw new DeveloperError('options.bottomRadius must be defined.'); - } - if (slices < 3) { - throw new DeveloperError('options.slices must be greater than or equal to 3.'); + var cartographic = new Cartographic(); + function scaleToSurface(positions, ellipsoid) { + var heights = new Array(positions.length); + for (var i = 0; i < positions.length; i++) { + var pos = positions[i]; + cartographic = ellipsoid.cartesianToCartographic(pos, cartographic); + heights[i] = cartographic.height; + positions[i] = ellipsoid.scaleToGeodeticSurface(pos, pos); } - - this._length = length; - this._topRadius = topRadius; - this._bottomRadius = bottomRadius; - this._vertexFormat = VertexFormat.clone(vertexFormat); - this._slices = slices; - this._workerName = 'createCylinderGeometry'; + return heights; } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - CylinderGeometry.packedLength = VertexFormat.packedLength + 4; - - /** - * Stores the provided instance into the provided array. - * - * @param {CylinderGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - CylinderGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); + function subdivideHeights(points, h0, h1, granularity) { + var p0 = points[0]; + var p1 = points[1]; + var angleBetween = Cartesian3.angleBetween(p0, p1); + var numPoints = Math.ceil(angleBetween / granularity); + var heights = new Array(numPoints); + var i; + if (h0 === h1) { + for (i = 0; i < numPoints; i++) { + heights[i] = h0; + } + heights.push(h1); + return heights; } - - startingIndex = defaultValue(startingIndex, 0); - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - - array[startingIndex++] = value._length; - array[startingIndex++] = value._topRadius; - array[startingIndex++] = value._bottomRadius; - array[startingIndex] = value._slices; - - return array; - }; - - var scratchVertexFormat = new VertexFormat(); - var scratchOptions = { - vertexFormat : scratchVertexFormat, - length : undefined, - topRadius : undefined, - bottomRadius : undefined, - slices : undefined - }; + var dHeight = h1 - h0; + var heightPerVertex = dHeight / (numPoints); - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {CylinderGeometry} [result] The object into which to store the result. - * @returns {CylinderGeometry} The modified result parameter or a new CylinderGeometry instance if one was not provided. - */ - CylinderGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + for (i = 1; i < numPoints; i++) { + var h = h0 + i * heightPerVertex; + heights[i] = h; } - - startingIndex = defaultValue(startingIndex, 0); - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + heights[0] = h0; + heights.push(h1); + return heights; + } - var length = array[startingIndex++]; - var topRadius = array[startingIndex++]; - var bottomRadius = array[startingIndex++]; - var slices = array[startingIndex]; + var nextScratch = new Cartesian3(); + var prevScratch = new Cartesian3(); - if (!defined(result)) { - scratchOptions.length = length; - scratchOptions.topRadius = topRadius; - scratchOptions.bottomRadius = bottomRadius; - scratchOptions.slices = slices; - return new CylinderGeometry(scratchOptions); - } + function computeRotationAngle(start, end, position, ellipsoid) { + var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); + var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, start, nextScratch), nextScratch); + var prev = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, end, prevScratch), prevScratch); + var angle = Cartesian2.angleBetween(next, prev); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._length = length; - result._topRadius = topRadius; - result._bottomRadius = bottomRadius; - result._slices = slices; + return (prev.x * next.y - prev.y * next.x >= 0.0) ? -angle : angle; + } - return result; - }; + var negativeX = new Cartesian3(-1, 0, 0); + var transform = new Matrix4(); + var translation = new Matrix4(); + var rotationZ = new Matrix3(); + var scaleMatrix = Matrix3.IDENTITY.clone(); + var westScratch = new Cartesian3(); + var finalPosScratch = new Cartesian4(); + var heightCartesian = new Cartesian3(); + function addPosition(center, left, shape, finalPositions, ellipsoid, height, xScalar, repeat) { + var west = westScratch; + var finalPosition = finalPosScratch; + transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, transform); - /** - * Computes the geometric representation of a cylinder, including its vertices, indices, and a bounding sphere. - * - * @param {CylinderGeometry} cylinderGeometry A description of the cylinder. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - CylinderGeometry.createGeometry = function(cylinderGeometry) { - var length = cylinderGeometry._length; - var topRadius = cylinderGeometry._topRadius; - var bottomRadius = cylinderGeometry._bottomRadius; - var vertexFormat = cylinderGeometry._vertexFormat; - var slices = cylinderGeometry._slices; + west = Matrix4.multiplyByPointAsVector(transform, negativeX, west); + west = Cartesian3.normalize(west, west); + var angle = computeRotationAngle(west, left, center, ellipsoid); + rotationZ = Matrix3.fromRotationZ(angle, rotationZ); - if ((length <= 0) || (topRadius < 0) || (bottomRadius < 0) || ((topRadius === 0) && (bottomRadius === 0))) { - return; + heightCartesian.z = height; + transform = Matrix4.multiplyTransformation(transform, Matrix4.fromRotationTranslation(rotationZ, heightCartesian, translation), transform); + var scale = scaleMatrix; + scale[0] = xScalar; + + for (var j = 0; j < repeat; j++) { + for (var i = 0; i < shape.length; i += 3) { + finalPosition = Cartesian3.fromArray(shape, i, finalPosition); + finalPosition = Matrix3.multiplyByVector(scale, finalPosition, finalPosition); + finalPosition = Matrix4.multiplyByPoint(transform, finalPosition, finalPosition); + finalPositions.push(finalPosition.x, finalPosition.y, finalPosition.z); + } } - var twoSlices = slices + slices; - var threeSlices = slices + twoSlices; - var numVertices = twoSlices + twoSlices; + return finalPositions; + } - var positions = CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, true); + var centerScratch = new Cartesian3(); + function addPositions(centers, left, shape, finalPositions, ellipsoid, heights, xScalar) { + for (var i = 0; i < centers.length; i += 3) { + var center = Cartesian3.fromArray(centers, i, centerScratch); + finalPositions = addPosition(center, left, shape, finalPositions, ellipsoid, heights[i / 3], xScalar, 1); + } + return finalPositions; + } - var st = (vertexFormat.st) ? new Float32Array(numVertices * 2) : undefined; - var normals = (vertexFormat.normal) ? new Float32Array(numVertices * 3) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(numVertices * 3) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(numVertices * 3) : undefined; + function convertShapeTo3DDuplicate(shape2D, boundingRectangle) { //orientate 2D shape to XZ plane center at (0, 0, 0), duplicate points + var length = shape2D.length; + var shape = new Array(length * 6); + var index = 0; + var xOffset = boundingRectangle.x + boundingRectangle.width / 2; + var yOffset = boundingRectangle.y + boundingRectangle.height / 2; - var i; - var computeNormal = (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent); + var point = shape2D[0]; + shape[index++] = point.x - xOffset; + shape[index++] = 0.0; + shape[index++] = point.y - yOffset; + for (var i = 1; i < length; i++) { + point = shape2D[i]; + var x = point.x - xOffset; + var z = point.y - yOffset; + shape[index++] = x; + shape[index++] = 0.0; + shape[index++] = z; - if (computeNormal) { - var computeTangent = (vertexFormat.tangent || vertexFormat.bitangent); + shape[index++] = x; + shape[index++] = 0.0; + shape[index++] = z; + } + point = shape2D[0]; + shape[index++] = point.x - xOffset; + shape[index++] = 0.0; + shape[index++] = point.y - yOffset; - var normalIndex = 0; - var tangentIndex = 0; - var bitangentIndex = 0; + return shape; + } - var normal = normalScratch; - normal.z = 0; - var tangent = tangentScratch; - var bitangent = bitangentScratch; + function convertShapeTo3D(shape2D, boundingRectangle) { //orientate 2D shape to XZ plane center at (0, 0, 0) + var length = shape2D.length; + var shape = new Array(length * 3); + var index = 0; + var xOffset = boundingRectangle.x + boundingRectangle.width / 2; + var yOffset = boundingRectangle.y + boundingRectangle.height / 2; - for (i = 0; i < slices; i++) { - var angle = i / slices * CesiumMath.TWO_PI; - var x = Math.cos(angle); - var y = Math.sin(angle); - if (computeNormal) { - normal.x = x; - normal.y = y; + for (var i = 0; i < length; i++) { + shape[index++] = shape2D[i].x - xOffset; + shape[index++] = 0; + shape[index++] = shape2D[i].y - yOffset; + } - if (computeTangent) { - tangent = Cartesian3.normalize(Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent), tangent); - } + return shape; + } - if (vertexFormat.normal) { - normals[normalIndex++] = x; - normals[normalIndex++] = y; - normals[normalIndex++] = 0; - normals[normalIndex++] = x; - normals[normalIndex++] = y; - normals[normalIndex++] = 0; - } + var quaterion = new Quaternion(); + var startPointScratch = new Cartesian3(); + var rotMatrix = new Matrix3(); + function computeRoundCorner(pivot, startPoint, endPoint, cornerType, leftIsOutside, ellipsoid, finalPositions, shape, height, duplicatePoints) { + var angle = Cartesian3.angleBetween(Cartesian3.subtract(startPoint, pivot, scratch1), Cartesian3.subtract(endPoint, pivot, scratch2)); + var granularity = (cornerType === CornerType.BEVELED) ? 0 : Math.ceil(angle / CesiumMath.toRadians(5)); - if (vertexFormat.tangent) { - tangents[tangentIndex++] = tangent.x; - tangents[tangentIndex++] = tangent.y; - tangents[tangentIndex++] = tangent.z; - tangents[tangentIndex++] = tangent.x; - tangents[tangentIndex++] = tangent.y; - tangents[tangentIndex++] = tangent.z; - } + var m; + if (leftIsOutside) { + m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(Cartesian3.negate(pivot, scratch1), angle / (granularity + 1), quaterion), rotMatrix); + } else { + m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(pivot, angle / (granularity + 1), quaterion), rotMatrix); + } - if (vertexFormat.bitangent) { - bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); - bitangents[bitangentIndex++] = bitangent.x; - bitangents[bitangentIndex++] = bitangent.y; - bitangents[bitangentIndex++] = bitangent.z; - bitangents[bitangentIndex++] = bitangent.x; - bitangents[bitangentIndex++] = bitangent.y; - bitangents[bitangentIndex++] = bitangent.z; - } + var left; + var surfacePoint; + startPoint = Cartesian3.clone(startPoint, startPointScratch); + if (granularity > 0) { + var repeat = duplicatePoints ? 2 : 1; + for (var i = 0; i < granularity; i++) { + startPoint = Matrix3.multiplyByVector(m, startPoint, startPoint); + left = Cartesian3.subtract(startPoint, pivot, scratch1); + left = Cartesian3.normalize(left, left); + if (!leftIsOutside) { + left = Cartesian3.negate(left, left); } + surfacePoint = ellipsoid.scaleToGeodeticSurface(startPoint, scratch2); + finalPositions = addPosition(surfacePoint, left, shape, finalPositions, ellipsoid, height, 1, repeat); } - - for (i = 0; i < slices; i++) { - if (vertexFormat.normal) { - normals[normalIndex++] = 0; - normals[normalIndex++] = 0; - normals[normalIndex++] = -1; - } - if (vertexFormat.tangent) { - tangents[tangentIndex++] = 1; - tangents[tangentIndex++] = 0; - tangents[tangentIndex++] = 0; - } - if (vertexFormat.bitangent) { - bitangents[bitangentIndex++] = 0; - bitangents[bitangentIndex++] = -1; - bitangents[bitangentIndex++] = 0; - } + } else { + left = Cartesian3.subtract(startPoint, pivot, scratch1); + left = Cartesian3.normalize(left, left); + if (!leftIsOutside) { + left = Cartesian3.negate(left, left); } + surfacePoint = ellipsoid.scaleToGeodeticSurface(startPoint, scratch2); + finalPositions = addPosition(surfacePoint, left, shape, finalPositions, ellipsoid, height, 1, 1); - for (i = 0; i < slices; i++) { - if (vertexFormat.normal) { - normals[normalIndex++] = 0; - normals[normalIndex++] = 0; - normals[normalIndex++] = 1; - } - if (vertexFormat.tangent) { - tangents[tangentIndex++] = 1; - tangents[tangentIndex++] = 0; - tangents[tangentIndex++] = 0; - } - if (vertexFormat.bitangent) { - bitangents[bitangentIndex++] = 0; - bitangents[bitangentIndex++] = 1; - bitangents[bitangentIndex++] = 0; - } + endPoint = Cartesian3.clone(endPoint, startPointScratch); + left = Cartesian3.subtract(endPoint, pivot, scratch1); + left = Cartesian3.normalize(left, left); + if (!leftIsOutside) { + left = Cartesian3.negate(left, left); } + surfacePoint = ellipsoid.scaleToGeodeticSurface(endPoint, scratch2); + finalPositions = addPosition(surfacePoint, left, shape, finalPositions, ellipsoid, height, 1, 1); } - var numIndices = 12 * slices - 12; - var indices = IndexDatatype.createTypedArray(numVertices, numIndices); - var index = 0; - var j = 0; - for (i = 0; i < slices - 1; i++) { - indices[index++] = j; - indices[index++] = j + 2; - indices[index++] = j + 3; + return finalPositions; + } - indices[index++] = j; - indices[index++] = j + 3; - indices[index++] = j + 1; + PolylineVolumeGeometryLibrary.removeDuplicatesFromShape = function(shapePositions) { + var length = shapePositions.length; + var cleanedPositions = []; + for (var i0 = length - 1, i1 = 0; i1 < length; i0 = i1++) { + var v0 = shapePositions[i0]; + var v1 = shapePositions[i1]; - j += 2; + if (!Cartesian2.equals(v0, v1)) { + cleanedPositions.push(v1); // Shallow copy! + } } - indices[index++] = twoSlices - 2; - indices[index++] = 0; - indices[index++] = 1; - indices[index++] = twoSlices - 2; - indices[index++] = 1; - indices[index++] = twoSlices - 1; + return cleanedPositions; + }; - for (i = 1; i < slices - 1; i++) { - indices[index++] = twoSlices + i + 1; - indices[index++] = twoSlices + i; - indices[index++] = twoSlices; - } + PolylineVolumeGeometryLibrary.angleIsGreaterThanPi = function(forward, backward, position, ellipsoid) { + var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); + var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, forward, nextScratch), nextScratch); + var prev = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, backward, prevScratch), prevScratch); - for (i = 1; i < slices - 1; i++) { - indices[index++] = threeSlices; - indices[index++] = threeSlices + i; - indices[index++] = threeSlices + i + 1; - } + return ((prev.x * next.y) - (prev.y * next.x)) >= 0.0; + }; - var textureCoordIndex = 0; - if (vertexFormat.st) { - var rad = Math.max(topRadius, bottomRadius); - for (i = 0; i < numVertices; i++) { - var position = Cartesian3.fromArray(positions, i * 3, positionScratch); - st[textureCoordIndex++] = (position.x + rad) / (2.0 * rad); - st[textureCoordIndex++] = (position.y + rad) / (2.0 * rad); - } - } + var scratchForwardProjection = new Cartesian3(); + var scratchBackwardProjection = new Cartesian3(); - var attributes = new GeometryAttributes(); - if (vertexFormat.position) { - attributes.position = new GeometryAttribute({ - componentDatatype: ComponentDatatype.DOUBLE, - componentsPerAttribute: 3, - values: positions - }); - } + PolylineVolumeGeometryLibrary.computePositions = function(positions, shape2D, boundingRectangle, geometry, duplicatePoints) { + var ellipsoid = geometry._ellipsoid; + var heights = scaleToSurface(positions, ellipsoid); + var granularity = geometry._granularity; + var cornerType = geometry._cornerType; + var shapeForSides = duplicatePoints ? convertShapeTo3DDuplicate(shape2D, boundingRectangle) : convertShapeTo3D(shape2D, boundingRectangle); + var shapeForEnds = duplicatePoints ? convertShapeTo3D(shape2D, boundingRectangle) : undefined; + var heightOffset = boundingRectangle.height / 2; + var width = boundingRectangle.width / 2; + var length = positions.length; + var finalPositions = []; + var ends = duplicatePoints ? [] : undefined; - if (vertexFormat.normal) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } + var forward = scratchCartesian1; + var backward = scratchCartesian2; + var cornerDirection = scratchCartesian3; + var surfaceNormal = scratchCartesian4; + var pivot = scratchCartesian5; + var start = scratchCartesian6; + var end = scratchCartesian7; + var left = scratchCartesian8; + var previousPosition = scratchCartesian9; - if (vertexFormat.tangent) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); + var position = positions[0]; + var nextPosition = positions[1]; + surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, surfaceNormal); + forward = Cartesian3.subtract(nextPosition, position, forward); + forward = Cartesian3.normalize(forward, forward); + left = Cartesian3.cross(surfaceNormal, forward, left); + left = Cartesian3.normalize(left, left); + var h0 = heights[0]; + var h1 = heights[1]; + if (duplicatePoints) { + ends = addPosition(position, left, shapeForEnds, ends, ellipsoid, h0 + heightOffset, 1, 1); } + previousPosition = Cartesian3.clone(position, previousPosition); + position = nextPosition; + backward = Cartesian3.negate(forward, backward); + var subdividedHeights; + var subdividedPositions; + for (var i = 1; i < length - 1; i++) { + var repeat = duplicatePoints ? 2 : 1; + nextPosition = positions[i + 1]; + forward = Cartesian3.subtract(nextPosition, position, forward); + forward = Cartesian3.normalize(forward, forward); + cornerDirection = Cartesian3.add(forward, backward, cornerDirection); + cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); + surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, surfaceNormal); - if (vertexFormat.bitangent) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } + var forwardProjection = Cartesian3.multiplyByScalar(surfaceNormal, Cartesian3.dot(forward, surfaceNormal), scratchForwardProjection); + Cartesian3.subtract(forward, forwardProjection, forwardProjection); + Cartesian3.normalize(forwardProjection, forwardProjection); - if (vertexFormat.st) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : st - }); - } + var backwardProjection = Cartesian3.multiplyByScalar(surfaceNormal, Cartesian3.dot(backward, surfaceNormal), scratchBackwardProjection); + Cartesian3.subtract(backward, backwardProjection, backwardProjection); + Cartesian3.normalize(backwardProjection, backwardProjection); - radiusScratch.x = length * 0.5; - radiusScratch.y = Math.max(bottomRadius, topRadius); + var doCorner = !CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(forwardProjection, backwardProjection)), 1.0, CesiumMath.EPSILON7); - var boundingSphere = new BoundingSphere(Cartesian3.ZERO, Cartesian2.magnitude(radiusScratch)); + if (doCorner) { + cornerDirection = Cartesian3.cross(cornerDirection, surfaceNormal, cornerDirection); + cornerDirection = Cartesian3.cross(surfaceNormal, cornerDirection, cornerDirection); + cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); + var scalar = 1 / Math.max(0.25, (Cartesian3.magnitude(Cartesian3.cross(cornerDirection, backward, scratch1)))); + var leftIsOutside = PolylineVolumeGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); + if (leftIsOutside) { + pivot = Cartesian3.add(position, Cartesian3.multiplyByScalar(cornerDirection, scalar * width, cornerDirection), pivot); + start = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, width, start), start); + scratch2Array[0] = Cartesian3.clone(previousPosition, scratch2Array[0]); + scratch2Array[1] = Cartesian3.clone(start, scratch2Array[1]); + subdividedHeights = subdivideHeights(scratch2Array, h0 + heightOffset, h1 + heightOffset, granularity); + subdividedPositions = PolylinePipeline.generateArc({ + positions: scratch2Array, + granularity: granularity, + ellipsoid: ellipsoid + }); + finalPositions = addPositions(subdividedPositions, left, shapeForSides, finalPositions, ellipsoid, subdividedHeights, 1); + left = Cartesian3.cross(surfaceNormal, forward, left); + left = Cartesian3.normalize(left, left); + end = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, width, end), end); + if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { + computeRoundCorner(pivot, start, end, cornerType, leftIsOutside, ellipsoid, finalPositions, shapeForSides, h1 + heightOffset, duplicatePoints); + } else { + cornerDirection = Cartesian3.negate(cornerDirection, cornerDirection); + finalPositions = addPosition(position, cornerDirection, shapeForSides, finalPositions, ellipsoid, h1 + heightOffset, scalar, repeat); + } + previousPosition = Cartesian3.clone(end, previousPosition); + } else { + pivot = Cartesian3.add(position, Cartesian3.multiplyByScalar(cornerDirection, scalar * width, cornerDirection), pivot); + start = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, -width, start), start); + scratch2Array[0] = Cartesian3.clone(previousPosition, scratch2Array[0]); + scratch2Array[1] = Cartesian3.clone(start, scratch2Array[1]); + subdividedHeights = subdivideHeights(scratch2Array, h0 + heightOffset, h1 + heightOffset, granularity); + subdividedPositions = PolylinePipeline.generateArc({ + positions: scratch2Array, + granularity: granularity, + ellipsoid: ellipsoid + }); + finalPositions = addPositions(subdividedPositions, left, shapeForSides, finalPositions, ellipsoid, subdividedHeights, 1); + left = Cartesian3.cross(surfaceNormal, forward, left); + left = Cartesian3.normalize(left, left); + end = Cartesian3.add(pivot, Cartesian3.multiplyByScalar(left, -width, end), end); + if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { + computeRoundCorner(pivot, start, end, cornerType, leftIsOutside, ellipsoid, finalPositions, shapeForSides, h1 + heightOffset, duplicatePoints); + } else { + finalPositions = addPosition(position, cornerDirection, shapeForSides, finalPositions, ellipsoid, h1 + heightOffset, scalar, repeat); + } + previousPosition = Cartesian3.clone(end, previousPosition); + } + backward = Cartesian3.negate(forward, backward); + } else { + finalPositions = addPosition(previousPosition, left, shapeForSides, finalPositions, ellipsoid, h0 + heightOffset, 1, 1); + previousPosition = position; + } + h0 = h1; + h1 = heights[i + 1]; + position = nextPosition; + } - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : boundingSphere + scratch2Array[0] = Cartesian3.clone(previousPosition, scratch2Array[0]); + scratch2Array[1] = Cartesian3.clone(position, scratch2Array[1]); + subdividedHeights = subdivideHeights(scratch2Array, h0 + heightOffset, h1 + heightOffset, granularity); + subdividedPositions = PolylinePipeline.generateArc({ + positions: scratch2Array, + granularity: granularity, + ellipsoid: ellipsoid }); + finalPositions = addPositions(subdividedPositions, left, shapeForSides, finalPositions, ellipsoid, subdividedHeights, 1); + if (duplicatePoints) { + ends = addPosition(position, left, shapeForEnds, ends, ellipsoid, h1 + heightOffset, 1, 1); + } + + length = finalPositions.length; + var posLength = duplicatePoints ? length + ends.length : length; + var combinedPositions = new Float64Array(posLength); + combinedPositions.set(finalPositions); + if (duplicatePoints) { + combinedPositions.set(ends, length); + } + + return combinedPositions; }; - return CylinderGeometry; + return PolylineVolumeGeometryLibrary; }); - -define('Core/CylinderOutlineGeometry',[ - './BoundingSphere', - './Cartesian2', +define('Core/CorridorGeometryLibrary',[ './Cartesian3', - './Check', - './ComponentDatatype', - './CylinderGeometryLibrary', - './defaultValue', + './CornerType', './defined', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './PrimitiveType' + './Math', + './Matrix3', + './PolylinePipeline', + './PolylineVolumeGeometryLibrary', + './Quaternion' ], function( - BoundingSphere, - Cartesian2, Cartesian3, - Check, - ComponentDatatype, - CylinderGeometryLibrary, - defaultValue, + CornerType, defined, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - PrimitiveType) { + CesiumMath, + Matrix3, + PolylinePipeline, + PolylineVolumeGeometryLibrary, + Quaternion) { 'use strict'; - var radiusScratch = new Cartesian2(); - /** - * A description of the outline of a cylinder. - * - * @alias CylinderOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Number} options.length The length of the cylinder. - * @param {Number} options.topRadius The radius of the top of the cylinder. - * @param {Number} options.bottomRadius The radius of the bottom of the cylinder. - * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder. - * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surfaces of the cylinder. - * - * @exception {DeveloperError} options.length must be greater than 0. - * @exception {DeveloperError} options.topRadius must be greater than 0. - * @exception {DeveloperError} options.bottomRadius must be greater than 0. - * @exception {DeveloperError} bottomRadius and topRadius cannot both equal 0. - * @exception {DeveloperError} options.slices must be greater than or equal to 3. - * - * @see CylinderOutlineGeometry.createGeometry - * - * @example - * // create cylinder geometry - * var cylinder = new Cesium.CylinderOutlineGeometry({ - * length: 200000, - * topRadius: 80000, - * bottomRadius: 200000, - * }); - * var geometry = Cesium.CylinderOutlineGeometry.createGeometry(cylinder); + * @private */ - function CylinderOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var length = options.length; - var topRadius = options.topRadius; - var bottomRadius = options.bottomRadius; - var slices = defaultValue(options.slices, 128); - var numberOfVerticalLines = Math.max(defaultValue(options.numberOfVerticalLines, 16), 0); - - Check.typeOf.number('options.positions', length); - Check.typeOf.number('options.topRadius', topRadius); - Check.typeOf.number('options.bottomRadius', bottomRadius); - Check.typeOf.number.greaterThanOrEquals('options.slices', slices, 3); - - this._length = length; - this._topRadius = topRadius; - this._bottomRadius = bottomRadius; - this._slices = slices; - this._numberOfVerticalLines = numberOfVerticalLines; - this._workerName = 'createCylinderOutlineGeometry'; - } + var CorridorGeometryLibrary = {}; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - CylinderOutlineGeometry.packedLength = 5; + var scratch1 = new Cartesian3(); + var scratch2 = new Cartesian3(); + var scratch3 = new Cartesian3(); + var scratch4 = new Cartesian3(); - /** - * Stores the provided instance into the provided array. - * - * @param {CylinderOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - CylinderOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + var scaleArray2 = [new Cartesian3(), new Cartesian3()]; - array[startingIndex++] = value._length; - array[startingIndex++] = value._topRadius; - array[startingIndex++] = value._bottomRadius; - array[startingIndex++] = value._slices; - array[startingIndex] = value._numberOfVerticalLines; + var cartesian1 = new Cartesian3(); + var cartesian2 = new Cartesian3(); + var cartesian3 = new Cartesian3(); + var cartesian4 = new Cartesian3(); + var cartesian5 = new Cartesian3(); + var cartesian6 = new Cartesian3(); + var cartesian7 = new Cartesian3(); + var cartesian8 = new Cartesian3(); + var cartesian9 = new Cartesian3(); + var cartesian10 = new Cartesian3(); - return array; - }; + var quaterion = new Quaternion(); + var rotMatrix = new Matrix3(); + function computeRoundCorner(cornerPoint, startPoint, endPoint, cornerType, leftIsOutside) { + var angle = Cartesian3.angleBetween(Cartesian3.subtract(startPoint, cornerPoint, scratch1), Cartesian3.subtract(endPoint, cornerPoint, scratch2)); + var granularity = (cornerType === CornerType.BEVELED) ? 1 : Math.ceil(angle / CesiumMath.toRadians(5)) + 1; - var scratchOptions = { - length : undefined, - topRadius : undefined, - bottomRadius : undefined, - slices : undefined, - numberOfVerticalLines : undefined - }; + var size = granularity * 3; + var array = new Array(size); - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {CylinderOutlineGeometry} [result] The object into which to store the result. - * @returns {CylinderOutlineGeometry} The modified result parameter or a new CylinderOutlineGeometry instance if one was not provided. - */ - CylinderOutlineGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + array[size - 3] = endPoint.x; + array[size - 2] = endPoint.y; + array[size - 1] = endPoint.z; - var length = array[startingIndex++]; - var topRadius = array[startingIndex++]; - var bottomRadius = array[startingIndex++]; - var slices = array[startingIndex++]; - var numberOfVerticalLines = array[startingIndex]; + var m; + if (leftIsOutside) { + m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(Cartesian3.negate(cornerPoint, scratch1), angle / granularity, quaterion), rotMatrix); + } else { + m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(cornerPoint, angle / granularity, quaterion), rotMatrix); + } - if (!defined(result)) { - scratchOptions.length = length; - scratchOptions.topRadius = topRadius; - scratchOptions.bottomRadius = bottomRadius; - scratchOptions.slices = slices; - scratchOptions.numberOfVerticalLines = numberOfVerticalLines; - return new CylinderOutlineGeometry(scratchOptions); + var index = 0; + startPoint = Cartesian3.clone(startPoint, scratch1); + for (var i = 0; i < granularity; i++) { + startPoint = Matrix3.multiplyByVector(m, startPoint, startPoint); + array[index++] = startPoint.x; + array[index++] = startPoint.y; + array[index++] = startPoint.z; } - result._length = length; - result._topRadius = topRadius; - result._bottomRadius = bottomRadius; - result._slices = slices; - result._numberOfVerticalLines = numberOfVerticalLines; + return array; + } - return result; - }; + function addEndCaps(calculatedPositions) { + var cornerPoint = cartesian1; + var startPoint = cartesian2; + var endPoint = cartesian3; - /** - * Computes the geometric representation of an outline of a cylinder, including its vertices, indices, and a bounding sphere. - * - * @param {CylinderOutlineGeometry} cylinderGeometry A description of the cylinder outline. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - CylinderOutlineGeometry.createGeometry = function(cylinderGeometry) { - var length = cylinderGeometry._length; - var topRadius = cylinderGeometry._topRadius; - var bottomRadius = cylinderGeometry._bottomRadius; - var slices = cylinderGeometry._slices; - var numberOfVerticalLines = cylinderGeometry._numberOfVerticalLines; + var leftEdge = calculatedPositions[1]; + startPoint = Cartesian3.fromArray(calculatedPositions[1], leftEdge.length - 3, startPoint); + endPoint = Cartesian3.fromArray(calculatedPositions[0], 0, endPoint); + cornerPoint = Cartesian3.multiplyByScalar(Cartesian3.add(startPoint, endPoint, cornerPoint), 0.5, cornerPoint); + var firstEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false); - if ((length <= 0) || (topRadius < 0) || (bottomRadius < 0) || ((topRadius === 0) && (bottomRadius === 0))) { - return; - } + var length = calculatedPositions.length - 1; + var rightEdge = calculatedPositions[length - 1]; + leftEdge = calculatedPositions[length]; + startPoint = Cartesian3.fromArray(rightEdge, rightEdge.length - 3, startPoint); + endPoint = Cartesian3.fromArray(leftEdge, 0, endPoint); + cornerPoint = Cartesian3.multiplyByScalar(Cartesian3.add(startPoint, endPoint, cornerPoint), 0.5, cornerPoint); + var lastEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false); - var numVertices = slices * 2; + return [firstEndCap, lastEndCap]; + } - var positions = CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, false); - var numIndices = slices * 2; - var numSide; - if (numberOfVerticalLines > 0) { - var numSideLines = Math.min(numberOfVerticalLines, slices); - numSide = Math.round(slices / numSideLines); - numIndices += numSideLines; + function computeMiteredCorner(position, leftCornerDirection, lastPoint, leftIsOutside) { + var cornerPoint = scratch1; + if (leftIsOutside) { + cornerPoint = Cartesian3.add(position, leftCornerDirection, cornerPoint); + } else { + leftCornerDirection = Cartesian3.negate(leftCornerDirection, leftCornerDirection); + cornerPoint = Cartesian3.add(position, leftCornerDirection, cornerPoint); } + return [cornerPoint.x, cornerPoint.y, cornerPoint.z, lastPoint.x, lastPoint.y, lastPoint.z]; + } - var indices = IndexDatatype.createTypedArray(numVertices, numIndices * 2); - var index = 0; - var i; - for (i = 0; i < slices - 1; i++) { - indices[index++] = i; - indices[index++] = i + 1; - indices[index++] = i + slices; - indices[index++] = i + 1 + slices; - } + function addShiftedPositions(positions, left, scalar, calculatedPositions) { + var rightPositions = new Array(positions.length); + var leftPositions = new Array(positions.length); + var scaledLeft = Cartesian3.multiplyByScalar(left, scalar, scratch1); + var scaledRight = Cartesian3.negate(scaledLeft, scratch2); + var rightIndex = 0; + var leftIndex = positions.length - 1; - indices[index++] = slices - 1; - indices[index++] = 0; - indices[index++] = slices + slices - 1; - indices[index++] = slices; + for (var i = 0; i < positions.length; i += 3) { + var pos = Cartesian3.fromArray(positions, i, scratch3); + var rightPos = Cartesian3.add(pos, scaledRight, scratch4); + rightPositions[rightIndex++] = rightPos.x; + rightPositions[rightIndex++] = rightPos.y; + rightPositions[rightIndex++] = rightPos.z; - if (numberOfVerticalLines > 0) { - for (i = 0; i < slices; i += numSide) { - indices[index++] = i; - indices[index++] = i + slices; - } + var leftPos = Cartesian3.add(pos, scaledLeft, scratch4); + leftPositions[leftIndex--] = leftPos.z; + leftPositions[leftIndex--] = leftPos.y; + leftPositions[leftIndex--] = leftPos.x; } + calculatedPositions.push(rightPositions, leftPositions); - var attributes = new GeometryAttributes(); - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - - radiusScratch.x = length * 0.5; - radiusScratch.y = Math.max(bottomRadius, topRadius); - - var boundingSphere = new BoundingSphere(Cartesian3.ZERO, Cartesian2.magnitude(radiusScratch)); - - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : boundingSphere - }); - }; - - return CylinderOutlineGeometry; -}); - -define('Core/decodeGoogleEarthEnterpriseData',[ - './Check', - './RuntimeError' - ], function( - Check, - RuntimeError) { - 'use strict'; - - var compressedMagic = 0x7468dead; - var compressedMagicSwap = 0xadde6874; + return calculatedPositions; + } /** - * Decodes data that is received from the Google Earth Enterprise server. - * - * @param {ArrayBuffer} key The key used during decoding. - * @param {ArrayBuffer} data The data to be decoded. - * * @private */ - function decodeGoogleEarthEnterpriseData(key, data) { - if (decodeGoogleEarthEnterpriseData.passThroughDataForTesting) { - return data; + CorridorGeometryLibrary.addAttribute = function(attribute, value, front, back) { + var x = value.x; + var y = value.y; + var z = value.z; + if (defined(front)) { + attribute[front] = x; + attribute[front + 1] = y; + attribute[front + 2] = z; } - - Check.typeOf.object('key', key); - Check.typeOf.object('data', data); - - var keyLength = key.byteLength; - if (keyLength === 0 || (keyLength % 4) !== 0) { - throw new RuntimeError('The length of key must be greater than 0 and a multiple of 4.'); + if (defined(back)) { + attribute[back] = z; + attribute[back - 1] = y; + attribute[back - 2] = x; } + }; - var dataView = new DataView(data); - var magic = dataView.getUint32(0, true); - if (magic === compressedMagic || magic === compressedMagicSwap) { - // Occasionally packets don't come back encoded, so just return - return data; - } + var scratchForwardProjection = new Cartesian3(); + var scratchBackwardProjection = new Cartesian3(); - var keyView = new DataView(key); + /** + * @private + */ + CorridorGeometryLibrary.computePositions = function(params) { + var granularity = params.granularity; + var positions = params.positions; + var ellipsoid = params.ellipsoid; + var width = params.width / 2; + var cornerType = params.cornerType; + var saveAttributes = params.saveAttributes; + var normal = cartesian1; + var forward = cartesian2; + var backward = cartesian3; + var left = cartesian4; + var cornerDirection = cartesian5; + var startPoint = cartesian6; + var previousPos = cartesian7; + var rightPos = cartesian8; + var leftPos = cartesian9; + var center = cartesian10; + var calculatedPositions = []; + var calculatedLefts = (saveAttributes) ? [] : undefined; + var calculatedNormals = (saveAttributes) ? [] : undefined; + var position = positions[0]; //add first point + var nextPosition = positions[1]; - var dp = 0; - var dpend = data.byteLength; - var dpend64 = dpend - (dpend % 8); - var kpend = keyLength; - var kp; - var off = 8; + forward = Cartesian3.normalize(Cartesian3.subtract(nextPosition, position, forward), forward); + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + left = Cartesian3.normalize(Cartesian3.cross(normal, forward, left), left); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + previousPos = Cartesian3.clone(position, previousPos); + position = nextPosition; + backward = Cartesian3.negate(forward, backward); - // This algorithm is intentionally asymmetric to make it more difficult to - // guess. Security through obscurity. :-( + var subdividedPositions; + var corners = []; + var i; + var length = positions.length; + for (i = 1; i < length - 1; i++) { // add middle points and corners + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + nextPosition = positions[i + 1]; + forward = Cartesian3.normalize(Cartesian3.subtract(nextPosition, position, forward), forward); + cornerDirection = Cartesian3.normalize(Cartesian3.add(forward, backward, cornerDirection), cornerDirection); - // while we have a full uint64 (8 bytes) left to do - // assumes buffer is 64bit aligned (or processor doesn't care) - while (dp < dpend64) { - // rotate the key each time through by using the offets 16,0,8,16,0,8,... - off = (off + 8) % 24; - kp = off; + var forwardProjection = Cartesian3.multiplyByScalar(normal, Cartesian3.dot(forward, normal), scratchForwardProjection); + Cartesian3.subtract(forward, forwardProjection, forwardProjection); + Cartesian3.normalize(forwardProjection, forwardProjection); - // run through one key length xor'ing one uint64 at a time - // then drop out to rotate the key for the next bit - while ((dp < dpend64) && (kp < kpend)) { - dataView.setUint32(dp, dataView.getUint32(dp, true) ^ keyView.getUint32(kp, true), true); - dataView.setUint32(dp + 4, dataView.getUint32(dp + 4, true) ^ keyView.getUint32(kp + 4, true), true); - dp += 8; - kp += 24; - } - } + var backwardProjection = Cartesian3.multiplyByScalar(normal, Cartesian3.dot(backward, normal), scratchBackwardProjection); + Cartesian3.subtract(backward, backwardProjection, backwardProjection); + Cartesian3.normalize(backwardProjection, backwardProjection); - // now the remaining 1 to 7 bytes - if (dp < dpend) { - if (kp >= kpend) { - // rotate the key one last time (if necessary) - off = (off + 8) % 24; - kp = off; - } + var doCorner = !CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(forwardProjection, backwardProjection)), 1.0, CesiumMath.EPSILON7); - while (dp < dpend) { - dataView.setUint8(dp, dataView.getUint8(dp) ^ keyView.getUint8(kp)); - dp++; - kp++; + if (doCorner) { + cornerDirection = Cartesian3.cross(cornerDirection, normal, cornerDirection); + cornerDirection = Cartesian3.cross(normal, cornerDirection, cornerDirection); + cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); + var scalar = width / Math.max(0.25, Cartesian3.magnitude(Cartesian3.cross(cornerDirection, backward, scratch1))); + var leftIsOutside = PolylineVolumeGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); + cornerDirection = Cartesian3.multiplyByScalar(cornerDirection, scalar, cornerDirection); + if (leftIsOutside) { + rightPos = Cartesian3.add(position, cornerDirection, rightPos); + center = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width, center), center); + leftPos = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width * 2, leftPos), leftPos); + scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); + scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); + subdividedPositions = PolylinePipeline.generateArc({ + positions: scaleArray2, + granularity: granularity, + ellipsoid: ellipsoid + }); + calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + startPoint = Cartesian3.clone(leftPos, startPoint); + left = Cartesian3.normalize(Cartesian3.cross(normal, forward, left), left); + leftPos = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width * 2, leftPos), leftPos); + previousPos = Cartesian3.add(rightPos, Cartesian3.multiplyByScalar(left, width, previousPos), previousPos); + if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { + corners.push({ + leftPositions : computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside) + }); + } else { + corners.push({ + leftPositions : computeMiteredCorner(position, Cartesian3.negate(cornerDirection, cornerDirection), leftPos, leftIsOutside) + }); + } + } else { + leftPos = Cartesian3.add(position, cornerDirection, leftPos); + center = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width, center), center), center); + rightPos = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width * 2, rightPos), rightPos), rightPos); + scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); + scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); + subdividedPositions = PolylinePipeline.generateArc({ + positions: scaleArray2, + granularity: granularity, + ellipsoid: ellipsoid + }); + calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + startPoint = Cartesian3.clone(rightPos, startPoint); + left = Cartesian3.normalize(Cartesian3.cross(normal, forward, left), left); + rightPos = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width * 2, rightPos), rightPos), rightPos); + previousPos = Cartesian3.add(leftPos, Cartesian3.negate(Cartesian3.multiplyByScalar(left, width, previousPos), previousPos), previousPos); + if (cornerType === CornerType.ROUNDED || cornerType === CornerType.BEVELED) { + corners.push({ + rightPositions : computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside) + }); + } else { + corners.push({ + rightPositions : computeMiteredCorner(position, cornerDirection, rightPos, leftIsOutside) + }); + } + } + backward = Cartesian3.negate(forward, backward); } + position = nextPosition; } - } - - decodeGoogleEarthEnterpriseData.passThroughDataForTesting = false; - - return decodeGoogleEarthEnterpriseData; -}); -define('Core/DefaultProxy',[],function() { - 'use strict'; + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); + scaleArray2[1] = Cartesian3.clone(position, scaleArray2[1]); + subdividedPositions = PolylinePipeline.generateArc({ + positions: scaleArray2, + granularity: granularity, + ellipsoid: ellipsoid + }); + calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } - /** - * A simple proxy that appends the desired resource as the sole query parameter - * to the given proxy URL. - * - * @alias DefaultProxy - * @constructor - * - * @param {String} proxy The proxy URL that will be used to requests all resources. - */ - function DefaultProxy(proxy) { - this.proxy = proxy; - } + var endPositions; + if (cornerType === CornerType.ROUNDED) { + endPositions = addEndCaps(calculatedPositions); + } - /** - * Get the final URL to use to request a given resource. - * - * @param {String} resource The resource to request. - * @returns {String} proxied resource - */ - DefaultProxy.prototype.getURL = function(resource) { - var prefix = this.proxy.indexOf('?') === -1 ? '?' : ''; - return this.proxy + prefix + encodeURIComponent(resource); + return { + positions : calculatedPositions, + corners : corners, + lefts : calculatedLefts, + normals : calculatedNormals, + endPositions : endPositions + }; }; - return DefaultProxy; + return CorridorGeometryLibrary; }); -define('Core/oneTimeWarning',[ - './defaultValue', - './defined', - './DeveloperError' - ], function( - defaultValue, - defined, - DeveloperError) { +define('ThirdParty/earcut-2.1.1',[], function() { 'use strict'; - var warnings = {}; +function earcut(data, holeIndices, dim) { - /** - * Logs a one time message to the console. Use this function instead of - * <code>console.log</code> directly since this does not log duplicate messages - * unless it is called from multiple workers. - * - * @exports oneTimeWarning - * - * @param {String} identifier The unique identifier for this warning. - * @param {String} [message=identifier] The message to log to the console. - * - * @example - * for(var i=0;i<foo.length;++i) { - * if (!defined(foo[i].bar)) { - * // Something that can be recovered from but may happen a lot - * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); - * foo[i].bar = 0; - * // ... - * } - * } - * - * @private - */ - function oneTimeWarning(identifier, message) { - if (!defined(identifier)) { - throw new DeveloperError('identifier is required.'); - } - - if (!defined(warnings[identifier])) { - warnings[identifier] = true; - console.warn(defaultValue(message, identifier)); - } - } + dim = dim || 2; - oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; + var hasHoles = holeIndices && holeIndices.length, + outerLen = hasHoles ? holeIndices[0] * dim : data.length, + outerNode = linkedList(data, 0, outerLen, dim, true), + triangles = []; - return oneTimeWarning; -}); + if (!outerNode) return triangles; -define('Core/deprecationWarning',[ - './defined', - './DeveloperError', - './oneTimeWarning' - ], function( - defined, - DeveloperError, - oneTimeWarning) { - 'use strict'; + var minX, minY, maxX, maxY, x, y, size; - /** - * Logs a deprecation message to the console. Use this function instead of - * <code>console.log</code> directly since this does not log duplicate messages - * unless it is called from multiple workers. - * - * @exports deprecationWarning - * - * @param {String} identifier The unique identifier for this deprecated API. - * @param {String} message The message to log to the console. - * - * @example - * // Deprecated function or class - * function Foo() { - * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); - * // ... - * } - * - * // Deprecated function - * Bar.prototype.func = function() { - * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); - * // ... - * }; - * - * // Deprecated property - * defineProperties(Bar.prototype, { - * prop : { - * get : function() { - * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); - * // ... - * }, - * set : function(value) { - * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); - * // ... - * } - * } - * }); - * - * @private - */ - function deprecationWarning(identifier, message) { - if (!defined(identifier) || !defined(message)) { - throw new DeveloperError('identifier and message are required.'); + if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); + + // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; + + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; } - - oneTimeWarning(identifier, message); + + // minX, minY and size are later used to transform coords into integers for z-order calculation + size = Math.max(maxX - minX, maxY - minY); } - return deprecationWarning; -}); + earcutLinked(outerNode, triangles, dim, minX, minY, size); -define('Core/DistanceDisplayCondition',[ - './defaultValue', - './defined', - './defineProperties', - './DeveloperError' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError) { - 'use strict'; + return triangles; +} - /** - * Determines visibility based on the distance to the camera. - * - * @alias DistanceDisplayCondition - * @constructor - * - * @param {Number} [near=0.0] The smallest distance in the interval where the object is visible. - * @param {Number} [far=Number.MAX_VALUE] The largest distance in the interval where the object is visible. - * - * @example - * // Make a billboard that is only visible when the distance to the camera is between 10 and 20 meters. - * billboard.distanceDisplayCondition = new DistanceDisplayCondition(10.0 20.0); - */ - function DistanceDisplayCondition(near, far) { - near = defaultValue(near, 0.0); - this._near = near; +// create a circular doubly linked list from polygon points in the specified winding order +function linkedList(data, start, end, dim, clockwise) { + var i, last; - far = defaultValue(far, Number.MAX_VALUE); - this._far = far; + if (clockwise === (signedArea(data, start, end, dim) > 0)) { + for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); + } else { + for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); } - defineProperties(DistanceDisplayCondition.prototype, { - /** - * The smallest distance in the interval where the object is visible. - * @memberof DistanceDisplayCondition.prototype - * @type {Number} - * @default 0.0 - */ - near: { - get: function() { - return this._near; - }, - set: function(value) { - this._near = value; - } - }, - /** - * The largest distance in the interval where the object is visible. - * @memberof DistanceDisplayCondition.prototype - * @type {Number} - * @default Number.MAX_VALUE - */ - far: { - get: function() { - return this._far; - }, - set: function(value) { - this._far = value; - } - } - }); - - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - DistanceDisplayCondition.packedLength = 2; + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } - /** - * Stores the provided instance into the provided array. - * - * @param {DistanceDisplayCondition} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - DistanceDisplayCondition.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + return last; +} - array[startingIndex++] = value.near; - array[startingIndex] = value.far; +// eliminate colinear or duplicate points +function filterPoints(start, end) { + if (!start) return start; + if (!end) end = start; - return array; - }; + var p = start, + again; + do { + again = false; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {DistanceDisplayCondition} [result] The object into which to store the result. - * @returns {DistanceDisplayCondition} The modified result parameter or a new DistanceDisplayCondition instance if one was not provided. - */ - DistanceDisplayCondition.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { + removeNode(p); + p = end = p.prev; + if (p === p.next) return null; + again = true; - if (!defined(result)) { - result = new DistanceDisplayCondition(); + } else { + p = p.next; } - result.near = array[startingIndex++]; - result.far = array[startingIndex]; - return result; - }; - - /** - * Determines if two distance display conditions are equal. - * - * @param {DistanceDisplayCondition} left A distance display condition. - * @param {DistanceDisplayCondition} right Another distance display condition. - * @return {Boolean} Whether the two distance display conditions are equal. - */ - DistanceDisplayCondition.equals = function(left, right) { - return left === right || - (defined(left) && - defined(right) && - left.near === right.near && - left.far === right.far); - }; + } while (again || p !== end); - /** - * Duplicates a distance display condition instance. - * - * @param {DistanceDisplayCondition} [value] The distance display condition to duplicate. - * @param {DistanceDisplayCondition} [result] The result onto which to store the result. - * @return {DistanceDisplayCondition} The duplicated instance. - */ - DistanceDisplayCondition.clone = function(value, result) { - if (!defined(value)) { - return undefined; - } + return end; +} - if (!defined(result)) { - result = new DistanceDisplayCondition(); - } +// main ear slicing loop which triangulates a polygon (given as a linked list) +function earcutLinked(ear, triangles, dim, minX, minY, size, pass) { + if (!ear) return; - result.near = value.near; - result.far = value.far; - return result; - }; + // interlink polygon nodes in z-order + if (!pass && size) indexCurve(ear, minX, minY, size); - /** - * Duplicates this instance. - * - * @param {DistanceDisplayCondition} [result] The result onto which to store the result. - * @return {DistanceDisplayCondition} The duplicated instance. - */ - DistanceDisplayCondition.prototype.clone = function(result) { - return DistanceDisplayCondition.clone(this, result); - }; + var stop = ear, + prev, next; - /** - * Determines if this distance display condition is equal to another. - * - * @param {DistanceDisplayCondition} other Another distance display condition. - * @return {Boolean} Whether this distance display condition is equal to the other. - */ - DistanceDisplayCondition.prototype.equals = function(other) { - return DistanceDisplayCondition.equals(this, other); - }; + // iterate through ears, slicing them one by one + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; - return DistanceDisplayCondition; -}); + if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) { + // cut off the triangle + triangles.push(prev.i / dim); + triangles.push(ear.i / dim); + triangles.push(next.i / dim); -define('Core/DistanceDisplayConditionGeometryInstanceAttribute',[ - './ComponentDatatype', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError' - ], function( - ComponentDatatype, - defaultValue, - defined, - defineProperties, - DeveloperError) { - 'use strict'; + removeNode(ear); - /** - * Value and type information for per-instance geometry attribute that determines if the geometry instance has a distance display condition. - * - * @alias DistanceDisplayConditionGeometryInstanceAttribute - * @constructor - * - * @param {Number} [near=0.0] The near distance. - * @param {Number} [far=Number.MAX_VALUE] The far distance. - * - * @exception {DeveloperError} far must be greater than near. - * - * @example - * var instance = new Cesium.GeometryInstance({ - * geometry : new Cesium.BoxGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL, - * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0), - * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0) - * }), - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), - * id : 'box', - * attributes : { - * show : new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(100.0, 10000.0) - * } - * }); - * - * @see GeometryInstance - * @see GeometryInstanceAttribute - */ - function DistanceDisplayConditionGeometryInstanceAttribute(near, far) { - near = defaultValue(near, 0.0); - far = defaultValue(far, Number.MAX_VALUE); + // skipping the next vertice leads to less sliver triangles + ear = next.next; + stop = next.next; - if (far <= near) { - throw new DeveloperError('far distance must be greater than near distance.'); + continue; } - - /** - * The values for the attributes stored in a typed array. - * - * @type Float32Array - * - * @default [0.0, 0.0, Number.MAX_VALUE] - */ - this.value = new Float32Array([near, far]); - } - defineProperties(DistanceDisplayConditionGeometryInstanceAttribute.prototype, { - /** - * The datatype of each component in the attribute, e.g., individual elements in - * {@link DistanceDisplayConditionGeometryInstanceAttribute#value}. - * - * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype - * - * @type {ComponentDatatype} - * @readonly - * - * @default {@link ComponentDatatype.FLOAT} - */ - componentDatatype : { - get : function() { - return ComponentDatatype.FLOAT; - } - }, + ear = next; - /** - * The number of components in the attributes, i.e., {@link DistanceDisplayConditionGeometryInstanceAttribute#value}. - * - * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype - * - * @type {Number} - * @readonly - * - * @default 3 - */ - componentsPerAttribute : { - get : function() { - return 2; - } - }, + // if we looped through the whole remaining polygon and can't find any more ears + if (ear === stop) { + // try filtering points and slicing again + if (!pass) { + earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1); - /** - * When <code>true</code> and <code>componentDatatype</code> is an integer format, - * indicate that the components should be mapped to the range [0, 1] (unsigned) - * or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * - * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype - * - * @type {Boolean} - * @readonly - * - * @default false - */ - normalize : { - get : function() { - return false; + // if this didn't work, try curing all small self-intersections locally + } else if (pass === 1) { + ear = cureLocalIntersections(ear, triangles, dim); + earcutLinked(ear, triangles, dim, minX, minY, size, 2); + + // as a last resort, try splitting the remaining polygon into two + } else if (pass === 2) { + splitEarcut(ear, triangles, dim, minX, minY, size); } - } - }); - /** - * Creates a new {@link DistanceDisplayConditionGeometryInstanceAttribute} instance given the provided an enabled flag and {@link DistanceDisplayCondition}. - * - * @param {DistanceDisplayCondition} distanceDisplayCondition The distance display condition. - * @returns {DistanceDisplayConditionGeometryInstanceAttribute} The new {@link DistanceDisplayConditionGeometryInstanceAttribute} instance. - * - * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near - * - * @example - * var instance = new Cesium.GeometryInstance({ - * geometry : geometry, - * attributes : { - * color : Cesium.DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition), - * } - * }); - */ - DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition = function(distanceDisplayCondition) { - if (!defined(distanceDisplayCondition)) { - throw new DeveloperError('distanceDisplayCondition is required.'); - } - if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far distance must be greater than distanceDisplayCondition.near distance.'); + break; } - - return new DistanceDisplayConditionGeometryInstanceAttribute(distanceDisplayCondition.near, distanceDisplayCondition.far); - }; + } +} - /** - * Converts a distance display condition to a typed array that can be used to assign a distance display condition attribute. - * - * @param {DistanceDisplayCondition} distanceDisplayCondition The distance display condition value. - * @param {Float32Array} [result] The array to store the result in, if undefined a new instance will be created. - * @returns {Float32Array} The modified result parameter or a new instance if result was undefined. - * - * @example - * var attributes = primitive.getGeometryInstanceAttributes('an id'); - * attributes.distanceDisplayCondition = Cesium.DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); - */ - DistanceDisplayConditionGeometryInstanceAttribute.toValue = function(distanceDisplayCondition, result) { - if (!defined(distanceDisplayCondition)) { - throw new DeveloperError('distanceDisplayCondition is required.'); - } - - if (!defined(result)) { - return new Float32Array([distanceDisplayCondition.near, distanceDisplayCondition.far]); - } - result[0] = distanceDisplayCondition.near; - result[1] = distanceDisplayCondition.far; - return result; - }; +// check whether a polygon node forms a valid ear with adjacent nodes +function isEar(ear) { + var a = ear.prev, + b = ear, + c = ear.next; - return DistanceDisplayConditionGeometryInstanceAttribute; -}); + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear -define('Core/DoublyLinkedList',[ - '../Core/defined', - '../Core/defineProperties' - ], function( - defined, - defineProperties) { - 'use strict'; + // now make sure we don't have other points inside the potential ear + var p = ear.next.next; - /** - * @private - */ - function DoublyLinkedList() { - this.head = undefined; - this.tail = undefined; - this._length = 0; + while (p !== ear.prev) { + if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.next; } - defineProperties(DoublyLinkedList.prototype, { - length : { - get : function() { - return this._length; - } - } - }); - - function DoublyLinkedListNode(item, previous, next) { - this.item = item; - this.previous = previous; - this.next = next; - } + return true; +} - DoublyLinkedList.prototype.add = function(item) { - var node = new DoublyLinkedListNode(item, this.tail, undefined); +function isEarHashed(ear, minX, minY, size) { + var a = ear.prev, + b = ear, + c = ear.next; - if (defined(this.tail)) { - this.tail.next = node; - this.tail = node; - } else { - // Insert into empty linked list - this.head = node; - this.tail = node; - } + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - ++this._length; + // triangle bbox; min & max are calculated like this for speed + var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), + minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), + maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), + maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); - return node; - }; + // z-order range for the current triangle bbox; + var minZ = zOrder(minTX, minTY, minX, minY, size), + maxZ = zOrder(maxTX, maxTY, minX, minY, size); - function remove(list, node) { - if (defined(node.previous) && defined(node.next)) { - node.previous.next = node.next; - node.next.previous = node.previous; - } else if (defined(node.previous)) { - // Remove last node - node.previous.next = undefined; - list.tail = node.previous; - } else if (defined(node.next)) { - // Remove first node - node.next.previous = undefined; - list.head = node.next; - } else { - // Remove last node in the linked list - list.head = undefined; - list.tail = undefined; - } + // first look for points inside the triangle in increasing z-order + var p = ear.nextZ; - node.next = undefined; - node.previous = undefined; + while (p && p.z <= maxZ) { + if (p !== ear.prev && p !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.nextZ; } - DoublyLinkedList.prototype.remove = function(node) { - if (!defined(node)) { - return; - } + // then look for points in decreasing z-order + p = ear.prevZ; - remove(this, node); + while (p && p.z >= minZ) { + if (p !== ear.prev && p !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + } - --this._length; - }; + return true; +} - DoublyLinkedList.prototype.splice = function(node, nextNode) { - if (node === nextNode) { - return; - } +// go through all polygon nodes and cure small local self-intersections +function cureLocalIntersections(start, triangles, dim) { + var p = start; + do { + var a = p.prev, + b = p.next.next; - // Remove nextNode, then insert after node - remove(this, nextNode); + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { - var oldNodeNext = node.next; - node.next = nextNode; + triangles.push(a.i / dim); + triangles.push(p.i / dim); + triangles.push(b.i / dim); - // nextNode is the new tail - if (this.tail === node) { - this.tail = nextNode; - } else { - oldNodeNext.previous = nextNode; - } + // remove two nodes involved + removeNode(p); + removeNode(p.next); - nextNode.next = oldNodeNext; - nextNode.previous = node; - }; + p = start = b; + } + p = p.next; + } while (p !== start); - return DoublyLinkedList; -}); + return p; +} -/** -@license -tween.js - https://github.com/sole/tween.js +// try splitting polygon into two and triangulate them independently +function splitEarcut(start, triangles, dim, minX, minY, size) { + // look for a valid diagonal that divides the polygon into two + var a = start; + do { + var b = a.next.next; + while (b !== a.prev) { + if (a.i !== b.i && isValidDiagonal(a, b)) { + // split the polygon in two by the diagonal + var c = splitPolygon(a, b); -Copyright (c) 2010-2012 Tween.js authors. + // filter colinear points around the cuts + a = filterPoints(a, a.next); + c = filterPoints(c, c.next); -Easing equations Copyright (c) 2001 Robert Penner http://robertpenner.com/easing/ + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, size); + earcutLinked(c, triangles, dim, minX, minY, size); + return; + } + b = b.next; + } + a = a.next; + } while (a !== start); +} -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: +// link every hole into the outer loop, producing a single-ring polygon without holes +function eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = [], + i, len, start, end, list; -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = linkedList(data, start, end, dim, false); + if (list === list.next) list.steiner = true; + queue.push(getLeftmost(list)); + } -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. -*/ + queue.sort(compareX); -/** - * @author sole / http://soledadpenades.com - * @author mrdoob / http://mrdoob.com - * @author Robert Eisele / http://www.xarg.org - * @author Philippe / http://philippe.elsass.me - * @author Robert Penner / http://www.robertpenner.com/easing_terms_of_use.html - * @author Paul Lewis / http://www.aerotwist.com/ - * @author lechecacharro - * @author Josh Faul / http://jocafa.com/ - * @author egraether / http://egraether.com/ - * @author endel / http://endel.me - * @author Ben Delarre / http://delarre.net - */ + // process holes from left to right + for (i = 0; i < queue.length; i++) { + eliminateHole(queue[i], outerNode); + outerNode = filterPoints(outerNode, outerNode.next); + } -define('ThirdParty/Tween',[],function() { + return outerNode; +} - // Date.now shim for (ahem) Internet Explo(d|r)er - if ( Date.now === undefined ) { +function compareX(a, b) { + return a.x - b.x; +} - Date.now = function () { +// find a bridge between vertices that connects hole with an outer ring and and link it +function eliminateHole(hole, outerNode) { + outerNode = findHoleBridge(hole, outerNode); + if (outerNode) { + var b = splitPolygon(outerNode, hole); + filterPoints(b, b.next); + } +} - return new Date().valueOf(); +// David Eberly's algorithm for finding a bridge between hole and outer polygon +function findHoleBridge(hole, outerNode) { + var p = outerNode, + hx = hole.x, + hy = hole.y, + qx = -Infinity, + m; - }; + // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point + do { + if (hy <= p.y && hy >= p.next.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); + if (x <= hx && x > qx) { + qx = x; + if (x === hx) { + if (hy === p.y) return p; + if (hy === p.next.y) return p.next; + } + m = p.x < p.next.x ? p : p.next; + } + } + p = p.next; + } while (p !== outerNode); - } + if (!m) return null; - var TWEEN = TWEEN || ( function () { + if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint - var _tweens = []; + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point - return { + var stop = m, + mx = m.x, + my = m.y, + tanMin = Infinity, + tan; - REVISION: '13', + p = m.next; - getAll: function () { + while (p !== stop) { + if (hx >= p.x && p.x >= mx && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { - return _tweens; + tan = Math.abs(hy - p.y) / (hx - p.x); // tangential - }, + if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { + m = p; + tanMin = tan; + } + } - removeAll: function () { + p = p.next; + } - _tweens = []; + return m; +} - }, +// interlink polygon nodes in z-order +function indexCurve(start, minX, minY, size) { + var p = start; + do { + if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); - add: function ( tween ) { + p.prevZ.nextZ = null; + p.prevZ = null; - _tweens.push( tween ); + sortLinked(p); +} - }, +// Simon Tatham's linked list merge sort algorithm +// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html +function sortLinked(list) { + var i, p, q, e, tail, numMerges, pSize, qSize, + inSize = 1; - remove: function ( tween ) { + do { + p = list; + list = null; + tail = null; + numMerges = 0; - var i = _tweens.indexOf( tween ); + while (p) { + numMerges++; + q = p; + pSize = 0; + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) break; + } - if ( i !== -1 ) { + qSize = inSize; - _tweens.splice( i, 1 ); + while (pSize > 0 || (qSize > 0 && q)) { + if (pSize === 0) { + e = q; + q = q.nextZ; + qSize--; + } else if (qSize === 0 || !q) { + e = p; + p = p.nextZ; + pSize--; + } else if (p.z <= q.z) { + e = p; + p = p.nextZ; + pSize--; + } else { + e = q; + q = q.nextZ; + qSize--; } - }, - - update: function ( time ) { + if (tail) tail.nextZ = e; + else list = e; - if ( _tweens.length === 0 ) return false; + e.prevZ = tail; + tail = e; + } - var i = 0; + p = q; + } - time = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() ); + tail.nextZ = null; + inSize *= 2; - while ( i < _tweens.length ) { + } while (numMerges > 1); - if ( _tweens[ i ].update( time ) ) { + return list; +} - i++; +// z-order of a point given coords and size of the data bounding box +function zOrder(x, y, minX, minY, size) { + // coords are transformed into non-negative 15-bit integer range + x = 32767 * (x - minX) / size; + y = 32767 * (y - minY) / size; - } else { + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; - _tweens.splice( i, 1 ); - - } + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; - } + return x | (y << 1); +} - return true; +// find the leftmost node of a polygon ring +function getLeftmost(start) { + var p = start, + leftmost = start; + do { + if (p.x < leftmost.x) leftmost = p; + p = p.next; + } while (p !== start); - } - }; + return leftmost; +} - } )(); +// check if a point lies within a convex triangle +function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && + (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && + (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; +} - TWEEN.Tween = function ( object ) { +// check if a diagonal between two polygon nodes is valid (lies in polygon interior) +function isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && + locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); +} - 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; +// signed area of a triangle +function area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); +} - // Set all starting values present on the target object - for ( var field in object ) { +// check if two points are equal +function equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; +} - _valuesStart[ field ] = parseFloat(object[field], 10); +// check if two segments intersect +function intersects(p1, q1, p2, q2) { + if ((equals(p1, q1) && equals(p2, q2)) || + (equals(p1, q2) && equals(p2, q1))) return true; + return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && + area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; +} - } +// check if a polygon diagonal intersects any polygon segments +function intersectsPolygon(a, b) { + var p = a; + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + intersects(p, p.next, a, b)) return true; + p = p.next; + } while (p !== a); - this.to = function ( properties, duration ) { + return false; +} - if ( duration !== undefined ) { +// check if a polygon diagonal is locally inside the polygon +function locallyInside(a, b) { + return area(a.prev, a, a.next) < 0 ? + area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : + area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; +} - _duration = duration; +// check if the middle point of a polygon diagonal is inside the polygon +function middleInside(a, b) { + var p = a, + inside = false, + px = (a.x + b.x) / 2, + py = (a.y + b.y) / 2; + do { + if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) + inside = !inside; + p = p.next; + } while (p !== a); - } + return inside; +} - _valuesEnd = properties; +// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; +// if one belongs to the outer ring and another to a hole, it merges it into a single ring +function splitPolygon(a, b) { + var a2 = new Node(a.i, a.x, a.y), + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; - return this; + a.next = b; + b.prev = a; - }; + a2.next = an; + an.prev = a2; - this.start = function ( time ) { + b2.next = a2; + a2.prev = b2; - TWEEN.add( this ); + bp.next = b2; + b2.prev = bp; - _isPlaying = true; + return b2; +} - _onStartCallbackFired = false; +// create a node and optionally link it with previous one (in a circular doubly linked list) +function insertNode(i, x, y, last) { + var p = new Node(i, x, y); - _startTime = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() ); - _startTime += _delayTime; + if (!last) { + p.prev = p; + p.next = p; - for ( var property in _valuesEnd ) { + } else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; + } + return p; +} - // check if an Array was provided as property value - if ( _valuesEnd[ property ] instanceof Array ) { +function removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; - if ( _valuesEnd[ property ].length === 0 ) { + if (p.prevZ) p.prevZ.nextZ = p.nextZ; + if (p.nextZ) p.nextZ.prevZ = p.prevZ; +} - continue; +function Node(i, x, y) { + // vertice index in coordinates array + this.i = i; - } + // vertex coordinates + this.x = x; + this.y = y; - // create a local copy of the Array with the start value at the front - _valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] ); + // previous and next vertice nodes in a polygon ring + this.prev = null; + this.next = null; - } + // z-order curve value + this.z = null; - _valuesStart[ property ] = _object[ property ]; + // previous and next nodes in z-order + this.prevZ = null; + this.nextZ = null; - if( ( _valuesStart[ property ] instanceof Array ) === false ) { - _valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings - } + // indicates whether this is a steiner point + this.steiner = false; +} - _valuesStartRepeat[ property ] = _valuesStart[ property ] || 0; +// return a percentage difference between the polygon area and its triangulation area; +// used to verify correctness of triangulation +earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; - } + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); + } + } - return this; + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } - }; + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); +}; - this.stop = function () { +function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; +} - if ( !_isPlaying ) { - return this; - } +// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts +earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; - TWEEN.remove( this ); - _isPlaying = false; + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + return result; +}; - if ( _onStopCallback !== null ) { +return earcut; +}); - _onStopCallback.call( _object ); +define('Core/WindingOrder',[ + './freezeObject', + './WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; - } + /** + * Winding order defines the order of vertices for a triangle to be considered front-facing. + * + * @exports WindingOrder + */ + var WindingOrder = { + /** + * Vertices are in clockwise order. + * + * @type {Number} + * @constant + */ + CLOCKWISE : WebGLConstants.CW, - this.stopChainedTweens(); - return this; + /** + * Vertices are in counter-clockwise order. + * + * @type {Number} + * @constant + */ + COUNTER_CLOCKWISE : WebGLConstants.CCW, - }; + /** + * @private + */ + validate : function(windingOrder) { + return windingOrder === WindingOrder.CLOCKWISE || + windingOrder === WindingOrder.COUNTER_CLOCKWISE; + } + }; - this.stopChainedTweens = function () { + return freezeObject(WindingOrder); +}); - for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) { +define('Core/PolygonPipeline',[ + '../ThirdParty/earcut-2.1.1', + './Cartesian2', + './Cartesian3', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './Math', + './PrimitiveType', + './WindingOrder' + ], function( + earcut, + Cartesian2, + Cartesian3, + Check, + ComponentDatatype, + defaultValue, + defined, + Ellipsoid, + Geometry, + GeometryAttribute, + CesiumMath, + PrimitiveType, + WindingOrder) { + 'use strict'; - _chainedTweens[ i ].stop(); + var scaleToGeodeticHeightN = new Cartesian3(); + var scaleToGeodeticHeightP = new Cartesian3(); - } + /** + * @private + */ + var PolygonPipeline = {}; - }; + /** + * @exception {DeveloperError} At least three positions are required. + */ + PolygonPipeline.computeArea2D = function(positions) { + Check.defined('positions', positions); + Check.typeOf.number.greaterThanOrEquals('positions.length', positions.length, 3); + + var length = positions.length; + var area = 0.0; - this.delay = function ( amount ) { + for ( var i0 = length - 1, i1 = 0; i1 < length; i0 = i1++) { + var v0 = positions[i0]; + var v1 = positions[i1]; - _delayTime = amount; - return this; + area += (v0.x * v1.y) - (v1.x * v0.y); + } - }; + return area * 0.5; + }; - this.repeat = function ( times ) { + /** + * @returns {WindingOrder} The winding order. + * + * @exception {DeveloperError} At least three positions are required. + */ + PolygonPipeline.computeWindingOrder2D = function(positions) { + var area = PolygonPipeline.computeArea2D(positions); + return (area > 0.0) ? WindingOrder.COUNTER_CLOCKWISE : WindingOrder.CLOCKWISE; + }; - _repeat = times; - return this; + /** + * Triangulate a polygon. + * + * @param {Cartesian2[]} positions Cartesian2 array containing the vertices of the polygon + * @param {Number[]} [holes] An array of the staring indices of the holes. + * @returns {Number[]} Index array representing triangles that fill the polygon + */ + PolygonPipeline.triangulate = function(positions, holes) { + Check.defined('positions', positions); + + var flattenedPositions = Cartesian2.packArray(positions); + return earcut(flattenedPositions, holes, 2); + }; - }; + var subdivisionV0Scratch = new Cartesian3(); + var subdivisionV1Scratch = new Cartesian3(); + var subdivisionV2Scratch = new Cartesian3(); + var subdivisionS0Scratch = new Cartesian3(); + var subdivisionS1Scratch = new Cartesian3(); + var subdivisionS2Scratch = new Cartesian3(); + var subdivisionMidScratch = new Cartesian3(); - this.yoyo = function( yoyo ) { + /** + * Subdivides positions and raises points to the surface of the ellipsoid. + * + * @param {Ellipsoid} ellipsoid The ellipsoid the polygon in on. + * @param {Cartesian3[]} positions An array of {@link Cartesian3} positions of the polygon. + * @param {Number[]} indices An array of indices that determines the triangles in the polygon. + * @param {Number} [granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * + * @exception {DeveloperError} At least three indices are required. + * @exception {DeveloperError} The number of indices must be divisable by three. + * @exception {DeveloperError} Granularity must be greater than zero. + */ + PolygonPipeline.computeSubdivision = function(ellipsoid, positions, indices, granularity) { + granularity = defaultValue(granularity, CesiumMath.RADIANS_PER_DEGREE); - _yoyo = yoyo; - return this; + Check.typeOf.object('ellipsoid', ellipsoid); + Check.defined('positions', positions); + Check.defined('indices', indices); + Check.typeOf.number.greaterThanOrEquals('indices.length', indices.length, 3); + Check.typeOf.number.equals('indices.length % 3', '0', indices.length % 3, 0); + Check.typeOf.number.greaterThan('granularity', granularity, 0.0); + + // triangles that need (or might need) to be subdivided. + var triangles = indices.slice(0); - }; + // New positions due to edge splits are appended to the positions list. + var i; + var length = positions.length; + var subdividedPositions = new Array(length * 3); + var q = 0; + for (i = 0; i < length; i++) { + var item = positions[i]; + subdividedPositions[q++] = item.x; + subdividedPositions[q++] = item.y; + subdividedPositions[q++] = item.z; + } + var subdividedIndices = []; - this.easing = function ( easing ) { + // Used to make sure shared edges are not split more than once. + var edges = {}; - _easingFunction = easing; - return this; + var radius = ellipsoid.maximumRadius; + var minDistance = CesiumMath.chordLength(granularity, radius); + var minDistanceSqrd = minDistance * minDistance; - }; + while (triangles.length > 0) { + var i2 = triangles.pop(); + var i1 = triangles.pop(); + var i0 = triangles.pop(); - this.interpolation = function ( interpolation ) { + var v0 = Cartesian3.fromArray(subdividedPositions, i0 * 3, subdivisionV0Scratch); + var v1 = Cartesian3.fromArray(subdividedPositions, i1 * 3, subdivisionV1Scratch); + var v2 = Cartesian3.fromArray(subdividedPositions, i2 * 3, subdivisionV2Scratch); - _interpolationFunction = interpolation; - return this; + var s0 = Cartesian3.multiplyByScalar(Cartesian3.normalize(v0, subdivisionS0Scratch), radius, subdivisionS0Scratch); + var s1 = Cartesian3.multiplyByScalar(Cartesian3.normalize(v1, subdivisionS1Scratch), radius, subdivisionS1Scratch); + var s2 = Cartesian3.multiplyByScalar(Cartesian3.normalize(v2, subdivisionS2Scratch), radius, subdivisionS2Scratch); - }; + var g0 = Cartesian3.magnitudeSquared(Cartesian3.subtract(s0, s1, subdivisionMidScratch)); + var g1 = Cartesian3.magnitudeSquared(Cartesian3.subtract(s1, s2, subdivisionMidScratch)); + var g2 = Cartesian3.magnitudeSquared(Cartesian3.subtract(s2, s0, subdivisionMidScratch)); - this.chain = function () { + var max = Math.max(g0, g1, g2); + var edge; + var mid; - _chainedTweens = arguments; - return this; + // if the max length squared of a triangle edge is greater than the chord length of squared + // of the granularity, subdivide the triangle + if (max > minDistanceSqrd) { + if (g0 === max) { + edge = Math.min(i0, i1) + ' ' + Math.max(i0, i1); - }; + i = edges[edge]; + if (!defined(i)) { + mid = Cartesian3.add(v0, v1, subdivisionMidScratch); + Cartesian3.multiplyByScalar(mid, 0.5, mid); + subdividedPositions.push(mid.x, mid.y, mid.z); + i = subdividedPositions.length / 3 - 1; + edges[edge] = i; + } - this.onStart = function ( callback ) { + triangles.push(i0, i, i2); + triangles.push(i, i1, i2); + } else if (g1 === max) { + edge = Math.min(i1, i2) + ' ' + Math.max(i1, i2); - _onStartCallback = callback; - return this; + i = edges[edge]; + if (!defined(i)) { + mid = Cartesian3.add(v1, v2, subdivisionMidScratch); + Cartesian3.multiplyByScalar(mid, 0.5, mid); + subdividedPositions.push(mid.x, mid.y, mid.z); + i = subdividedPositions.length / 3 - 1; + edges[edge] = i; + } - }; + triangles.push(i1, i, i0); + triangles.push(i, i2, i0); + } else if (g2 === max) { + edge = Math.min(i2, i0) + ' ' + Math.max(i2, i0); - this.onUpdate = function ( callback ) { + i = edges[edge]; + if (!defined(i)) { + mid = Cartesian3.add(v2, v0, subdivisionMidScratch); + Cartesian3.multiplyByScalar(mid, 0.5, mid); + subdividedPositions.push(mid.x, mid.y, mid.z); + i = subdividedPositions.length / 3 - 1; + edges[edge] = i; + } - _onUpdateCallback = callback; - return this; + triangles.push(i2, i, i1); + triangles.push(i, i0, i1); + } + } else { + subdividedIndices.push(i0); + subdividedIndices.push(i1); + subdividedIndices.push(i2); + } + } - }; + return new Geometry({ + attributes : { + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : subdividedPositions + }) + }, + indices : subdividedIndices, + primitiveType : PrimitiveType.TRIANGLES + }); + }; - this.onComplete = function ( callback ) { + /** + * Scales each position of a geometry's position attribute to a height, in place. + * + * @param {Number[]} positions The array of numbers representing the positions to be scaled + * @param {Number} [height=0.0] The desired height to add to the positions + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. + * @param {Boolean} [scaleToSurface=true] <code>true</code> if the positions need to be scaled to the surface before the height is added. + * @returns {Number[]} The input array of positions, scaled to height + */ + PolygonPipeline.scaleToGeodeticHeight = function(positions, height, ellipsoid, scaleToSurface) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - _onCompleteCallback = callback; - return this; + var n = scaleToGeodeticHeightN; + var p = scaleToGeodeticHeightP; - }; + height = defaultValue(height, 0.0); + scaleToSurface = defaultValue(scaleToSurface, true); - this.onStop = function ( callback ) { + if (defined(positions)) { + var length = positions.length; - _onStopCallback = callback; - return this; + for ( var i = 0; i < length; i += 3) { + Cartesian3.fromArray(positions, i, p); - }; + if (scaleToSurface) { + p = ellipsoid.scaleToGeodeticSurface(p, p); + } - this.update = function ( time ) { + if (height !== 0) { + n = ellipsoid.geodeticSurfaceNormal(p, n); - var property; + Cartesian3.multiplyByScalar(n, height, n); + Cartesian3.add(p, n, p); + } - if ( time < _startTime ) { + positions[i] = p.x; + positions[i + 1] = p.y; + positions[i + 2] = p.z; + } + } - return true; + return positions; + }; - } + return PolygonPipeline; +}); - if ( _onStartCallbackFired === false ) { +define('Core/CorridorGeometry',[ + './arrayRemoveDuplicates', + './BoundingSphere', + './Cartesian3', + './Cartographic', + './ComponentDatatype', + './CornerType', + './CorridorGeometryLibrary', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PolygonPipeline', + './PrimitiveType', + './Rectangle', + './VertexFormat' + ], function( + arrayRemoveDuplicates, + BoundingSphere, + Cartesian3, + Cartographic, + ComponentDatatype, + CornerType, + CorridorGeometryLibrary, + defaultValue, + defined, + defineProperties, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PolygonPipeline, + PrimitiveType, + Rectangle, + VertexFormat) { + 'use strict'; - if ( _onStartCallback !== null ) { + var cartesian1 = new Cartesian3(); + var cartesian2 = new Cartesian3(); + var cartesian3 = new Cartesian3(); + var cartesian4 = new Cartesian3(); + var cartesian5 = new Cartesian3(); + var cartesian6 = new Cartesian3(); - _onStartCallback.call( _object ); + var scratch1 = new Cartesian3(); + var scratch2 = new Cartesian3(); - } + function scaleToSurface(positions, ellipsoid) { + for (var i = 0; i < positions.length; i++) { + positions[i] = ellipsoid.scaleToGeodeticSurface(positions[i], positions[i]); + } + return positions; + } - _onStartCallbackFired = true; + function addNormals(attr, normal, left, front, back, vertexFormat) { + var normals = attr.normals; + var tangents = attr.tangents; + var bitangents = attr.bitangents; + var forward = Cartesian3.normalize(Cartesian3.cross(left, normal, scratch1), scratch1); + if (vertexFormat.normal) { + CorridorGeometryLibrary.addAttribute(normals, normal, front, back); + } + if (vertexFormat.tangent) { + CorridorGeometryLibrary.addAttribute(tangents, forward, front, back); + } + if (vertexFormat.bitangent) { + CorridorGeometryLibrary.addAttribute(bitangents, left, front, back); + } + } + function combine(computedPositions, vertexFormat, ellipsoid) { + var positions = computedPositions.positions; + var corners = computedPositions.corners; + var endPositions = computedPositions.endPositions; + var computedLefts = computedPositions.lefts; + var computedNormals = computedPositions.normals; + var attributes = new GeometryAttributes(); + var corner; + var leftCount = 0; + var rightCount = 0; + var i; + var indicesLength = 0; + var length; + for (i = 0; i < positions.length; i += 2) { + length = positions[i].length - 3; + leftCount += length; //subtracting 3 to account for duplicate points at corners + indicesLength += length*2; + rightCount += positions[i + 1].length - 3; + } + leftCount += 3; //add back count for end positions + rightCount += 3; + for (i = 0; i < corners.length; i++) { + corner = corners[i]; + var leftSide = corners[i].leftPositions; + if (defined(leftSide)) { + length = leftSide.length; + leftCount += length; + indicesLength += length; + } else { + length = corners[i].rightPositions.length; + rightCount += length; + indicesLength += length; } + } - var elapsed = ( time - _startTime ) / _duration; - elapsed = elapsed > 1 ? 1 : elapsed; - - var value = _easingFunction( elapsed ); + var addEndPositions = defined(endPositions); + var endPositionLength; + if (addEndPositions) { + endPositionLength = endPositions[0].length - 3; + leftCount += endPositionLength; + rightCount += endPositionLength; + endPositionLength /= 3; + indicesLength += endPositionLength * 6; + } + var size = leftCount + rightCount; + var finalPositions = new Float64Array(size); + var normals = (vertexFormat.normal) ? new Float32Array(size) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(size) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(size) : undefined; + var attr = { + normals : normals, + tangents : tangents, + bitangents : bitangents + }; + var front = 0; + var back = size - 1; + var UL, LL, UR, LR; + var normal = cartesian1; + var left = cartesian2; + var rightPos, leftPos; + var halfLength = endPositionLength / 2; - for ( property in _valuesEnd ) { + var indices = IndexDatatype.createTypedArray(size / 3, indicesLength); + var index = 0; + if (addEndPositions) { // add rounded end + leftPos = cartesian3; + rightPos = cartesian4; + var firstEndPositions = endPositions[0]; + normal = Cartesian3.fromArray(computedNormals, 0, normal); + left = Cartesian3.fromArray(computedLefts, 0, left); + for (i = 0; i < halfLength; i++) { + leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); + rightPos = Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos); + CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + addNormals(attr, normal, left, front, back, vertexFormat); - var start = _valuesStart[ property ] || 0; - var end = _valuesEnd[ property ]; + LL = front / 3; + LR = LL + 1; + UL = (back - 2) / 3; + UR = UL - 1; + indices[index++] = UL; + indices[index++] = LL; + indices[index++] = UR; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; - if ( end instanceof Array ) { + front += 3; + back -= 3; + } + } - _object[ property ] = _interpolationFunction( end, value ); + var posIndex = 0; + var compIndex = 0; + var rightEdge = positions[posIndex++]; //add first two edges + var leftEdge = positions[posIndex++]; + finalPositions.set(rightEdge, front); + finalPositions.set(leftEdge, back - leftEdge.length + 1); - } else { + left = Cartesian3.fromArray(computedLefts, compIndex, left); + var rightNormal; + var leftNormal; + length = leftEdge.length - 3; + for (i = 0; i < length; i += 3) { + rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(rightEdge, i, scratch1), scratch1); + leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(leftEdge, length - i, scratch2), scratch2); + normal = Cartesian3.normalize(Cartesian3.add(rightNormal, leftNormal, normal), normal); + addNormals(attr, normal, left, front, back, vertexFormat); - // Parses relative end values with start as base (e.g.: +10, -3) - if ( typeof(end) === "string" ) { - end = start + parseFloat(end, 10); - } + LL = front / 3; + LR = LL + 1; + UL = (back - 2) / 3; + UR = UL - 1; + indices[index++] = UL; + indices[index++] = LL; + indices[index++] = UR; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; - // protect against non numeric properties. - if ( typeof(end) === "number" ) { - _object[ property ] = start + ( end - start ) * value; - } + front += 3; + back -= 3; + } + rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(rightEdge, length, scratch1), scratch1); + leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(leftEdge, length, scratch2), scratch2); + normal = Cartesian3.normalize(Cartesian3.add(rightNormal, leftNormal, normal), normal); + compIndex += 3; + for (i = 0; i < corners.length; i++) { + var j; + corner = corners[i]; + var l = corner.leftPositions; + var r = corner.rightPositions; + var pivot; + var start; + var outsidePoint = cartesian6; + var previousPoint = cartesian3; + var nextPoint = cartesian4; + normal = Cartesian3.fromArray(computedNormals, compIndex, normal); + if (defined(l)) { + addNormals(attr, normal, left, undefined, back, vertexFormat); + back -= 3; + pivot = LR; + start = UR; + for (j = 0; j < l.length / 3; j++) { + outsidePoint = Cartesian3.fromArray(l, j * 3, outsidePoint); + indices[index++] = pivot; + indices[index++] = start - j - 1; + indices[index++] = start - j; + CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); + previousPoint = Cartesian3.fromArray(finalPositions, (start - j - 1) * 3, previousPoint); + nextPoint = Cartesian3.fromArray(finalPositions, pivot * 3, nextPoint); + left = Cartesian3.normalize(Cartesian3.subtract(previousPoint, nextPoint, left), left); + addNormals(attr, normal, left, undefined, back, vertexFormat); + back -= 3; } - + outsidePoint = Cartesian3.fromArray(finalPositions, pivot * 3, outsidePoint); + previousPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, (start) * 3, previousPoint), outsidePoint, previousPoint); + nextPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, (start - j) * 3, nextPoint), outsidePoint, nextPoint); + left = Cartesian3.normalize(Cartesian3.add(previousPoint, nextPoint, left), left); + addNormals(attr, normal, left, front, undefined, vertexFormat); + front += 3; + } else { + addNormals(attr, normal, left, front, undefined, vertexFormat); + front += 3; + pivot = UR; + start = LR; + for (j = 0; j < r.length / 3; j++) { + outsidePoint = Cartesian3.fromArray(r, j * 3, outsidePoint); + indices[index++] = pivot; + indices[index++] = start + j; + indices[index++] = start + j + 1; + CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); + previousPoint = Cartesian3.fromArray(finalPositions, pivot * 3, previousPoint); + nextPoint = Cartesian3.fromArray(finalPositions, (start + j) * 3, nextPoint); + left = Cartesian3.normalize(Cartesian3.subtract(previousPoint, nextPoint, left), left); + addNormals(attr, normal, left, front, undefined, vertexFormat); + front += 3; + } + outsidePoint = Cartesian3.fromArray(finalPositions, pivot * 3, outsidePoint); + previousPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, (start + j) * 3, previousPoint), outsidePoint, previousPoint); + nextPoint = Cartesian3.subtract(Cartesian3.fromArray(finalPositions, start * 3, nextPoint), outsidePoint, nextPoint); + left = Cartesian3.normalize(Cartesian3.negate(Cartesian3.add(nextPoint, previousPoint, left), left), left); + addNormals(attr, normal, left, undefined, back, vertexFormat); + back -= 3; } + rightEdge = positions[posIndex++]; + leftEdge = positions[posIndex++]; + rightEdge.splice(0, 3); //remove duplicate points added by corner + leftEdge.splice(leftEdge.length - 3, 3); + finalPositions.set(rightEdge, front); + finalPositions.set(leftEdge, back - leftEdge.length + 1); + length = leftEdge.length - 3; - if ( _onUpdateCallback !== null ) { + compIndex += 3; + left = Cartesian3.fromArray(computedLefts, compIndex, left); + for (j = 0; j < leftEdge.length; j += 3) { + rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(rightEdge, j, scratch1), scratch1); + leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian3.fromArray(leftEdge, length - j, scratch2), scratch2); + normal = Cartesian3.normalize(Cartesian3.add(rightNormal, leftNormal, normal), normal); + addNormals(attr, normal, left, front, back, vertexFormat); - _onUpdateCallback.call( _object, value ); + LR = front / 3; + LL = LR - 1; + UR = (back - 2) / 3; + UL = UR + 1; + indices[index++] = UL; + indices[index++] = LL; + indices[index++] = UR; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; + front += 3; + back -= 3; } + front -= 3; + back += 3; + } + normal = Cartesian3.fromArray(computedNormals, computedNormals.length - 3, normal); + addNormals(attr, normal, left, front, back, vertexFormat); - 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 (addEndPositions) { // add rounded end + front += 3; + back -= 3; + leftPos = cartesian3; + rightPos = cartesian4; + var lastEndPositions = endPositions[1]; + for (i = 0; i < halfLength; i++) { + leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); + rightPos = Cartesian3.fromArray(lastEndPositions, i * 3, rightPos); + CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + addNormals(attr, normal, left, front, back, vertexFormat); - } + LR = front / 3; + LL = LR - 1; + UR = (back - 2) / 3; + UL = UR + 1; + indices[index++] = UL; + indices[index++] = LL; + indices[index++] = UR; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; - if (_yoyo) { - _reversed = !_reversed; - } + front += 3; + back -= 3; + } + } - _startTime = time + _delayTime; + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : finalPositions + }); - return true; + if (vertexFormat.st) { + var st = new Float32Array(size / 3 * 2); + var rightSt; + var leftSt; + var stIndex = 0; + if (addEndPositions) { + leftCount /= 3; + rightCount /= 3; + var theta = Math.PI / (endPositionLength + 1); + leftSt = 1 / (leftCount - endPositionLength + 1); + rightSt = 1 / (rightCount - endPositionLength + 1); + var a; + var halfEndPos = endPositionLength / 2; + for (i = halfEndPos + 1; i < endPositionLength + 1; i++) { // lower left rounded end + a = CesiumMath.PI_OVER_TWO + theta * i; + st[stIndex++] = rightSt * (1 + Math.cos(a)); + st[stIndex++] = 0.5 * (1 + Math.sin(a)); + } + for (i = 1; i < rightCount - endPositionLength + 1; i++) { // bottom edge + st[stIndex++] = i * rightSt; + st[stIndex++] = 0; + } + for (i = endPositionLength; i > halfEndPos; i--) { // lower right rounded end + a = CesiumMath.PI_OVER_TWO - i * theta; + st[stIndex++] = 1 - rightSt * (1 + Math.cos(a)); + st[stIndex++] = 0.5 * (1 + Math.sin(a)); + } + for (i = halfEndPos; i > 0; i--) { // upper right rounded end + a = CesiumMath.PI_OVER_TWO - theta * i; + st[stIndex++] = 1 - leftSt * (1 + Math.cos(a)); + st[stIndex++] = 0.5 * (1 + Math.sin(a)); + } + for (i = leftCount - endPositionLength; i > 0; i--) { // top edge + st[stIndex++] = i * leftSt; + st[stIndex++] = 1; + } + for (i = 1; i < halfEndPos + 1; i++) { // upper left rounded end + a = CesiumMath.PI_OVER_TWO + theta * i; + st[stIndex++] = leftSt * (1 + Math.cos(a)); + st[stIndex++] = 0.5 * (1 + Math.sin(a)); + } + } else { + leftCount /= 3; + rightCount /= 3; + leftSt = 1 / (leftCount - 1); + rightSt = 1 / (rightCount - 1); + for (i = 0; i < rightCount; i++) { // bottom edge + st[stIndex++] = i * rightSt; + st[stIndex++] = 0; + } + for (i = leftCount; i > 0; i--) { // top edge + st[stIndex++] = (i - 1) * leftSt; + st[stIndex++] = 1; + } + } - } else { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : st + }); + } - if ( _onCompleteCallback !== null ) { + if (vertexFormat.normal) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : attr.normals + }); + } - _onCompleteCallback.call( _object ); + if (vertexFormat.tangent) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : attr.tangents + }); + } - } + if (vertexFormat.bitangent) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : attr.bitangents + }); + } - for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) { - - _chainedTweens[ i ].start( time ); + return { + attributes : attributes, + indices : indices + }; + } + function extrudedAttributes(attributes, vertexFormat) { + if (!vertexFormat.normal && !vertexFormat.tangent && !vertexFormat.bitangent && !vertexFormat.st) { + return attributes; + } + var positions = attributes.position.values; + var topNormals; + var topBitangents; + if (vertexFormat.normal || vertexFormat.bitangent) { + topNormals = attributes.normal.values; + topBitangents = attributes.bitangent.values; + } + var size = attributes.position.values.length / 18; + var threeSize = size * 3; + var twoSize = size * 2; + var sixSize = threeSize * 2; + var i; + if (vertexFormat.normal || vertexFormat.bitangent || vertexFormat.tangent) { + var normals = (vertexFormat.normal) ? new Float32Array(threeSize * 6) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(threeSize * 6) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(threeSize * 6) : undefined; + var topPosition = cartesian1; + var bottomPosition = cartesian2; + var previousPosition = cartesian3; + var normal = cartesian4; + var tangent = cartesian5; + var bitangent = cartesian6; + var attrIndex = sixSize; + for (i = 0; i < threeSize; i += 3) { + var attrIndexOffset = attrIndex + sixSize; + topPosition = Cartesian3.fromArray(positions, i, topPosition); + bottomPosition = Cartesian3.fromArray(positions, i + threeSize, bottomPosition); + previousPosition = Cartesian3.fromArray(positions, (i + 3) % threeSize, previousPosition); + bottomPosition = Cartesian3.subtract(bottomPosition, topPosition, bottomPosition); + previousPosition = Cartesian3.subtract(previousPosition, topPosition, previousPosition); + normal = Cartesian3.normalize(Cartesian3.cross(bottomPosition, previousPosition, normal), normal); + if (vertexFormat.normal) { + CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset); + CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset + 3); + CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex); + CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex + 3); + } + if (vertexFormat.tangent || vertexFormat.bitangent) { + bitangent = Cartesian3.fromArray(topNormals, i, bitangent); + if (vertexFormat.bitangent) { + CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndexOffset); + CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndexOffset + 3); + CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndex); + CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndex + 3); } - return false; + if (vertexFormat.tangent) { + tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); + CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset); + CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset + 3); + CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex); + CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex + 3); + } + } + attrIndex += 6; + } + if (vertexFormat.normal) { + normals.set(topNormals); //top + for (i = 0; i < threeSize; i += 3) { //bottom normals + normals[i + threeSize] = -topNormals[i]; + normals[i + threeSize + 1] = -topNormals[i + 1]; + normals[i + threeSize + 2] = -topNormals[i + 2]; } + attributes.normal.values = normals; + } else { + attributes.normal = undefined; + } + if (vertexFormat.bitangent) { + bitangents.set(topBitangents); //top + bitangents.set(topBitangents, threeSize); //bottom + attributes.bitangent.values = bitangents; + } else { + attributes.bitangent = undefined; } - return true; + if (vertexFormat.tangent) { + var topTangents = attributes.tangent.values; + tangents.set(topTangents); //top + tangents.set(topTangents, threeSize); //bottom + attributes.tangent.values = tangents; + } + } + if (vertexFormat.st) { + var topSt = attributes.st.values; + var st = new Float32Array(twoSize * 6); + st.set(topSt); //top + st.set(topSt, twoSize); //bottom + var index = twoSize * 2; - }; + for ( var j = 0; j < 2; j++) { + st[index++] = topSt[0]; + st[index++] = topSt[1]; + for (i = 2; i < twoSize; i += 2) { + var s = topSt[i]; + var t = topSt[i + 1]; + st[index++] = s; + st[index++] = t; + st[index++] = s; + st[index++] = t; + } + st[index++] = topSt[0]; + st[index++] = topSt[1]; + } + attributes.st.values = st; + } - }; + return attributes; + } + function addWallPositions(positions, index, wallPositions) { + wallPositions[index++] = positions[0]; + wallPositions[index++] = positions[1]; + wallPositions[index++] = positions[2]; + for ( var i = 3; i < positions.length; i += 3) { + var x = positions[i]; + var y = positions[i + 1]; + var z = positions[i + 2]; + wallPositions[index++] = x; + wallPositions[index++] = y; + wallPositions[index++] = z; + wallPositions[index++] = x; + wallPositions[index++] = y; + wallPositions[index++] = z; + } + wallPositions[index++] = positions[0]; + wallPositions[index++] = positions[1]; + wallPositions[index++] = positions[2]; - TWEEN.Easing = { + return wallPositions; + } - Linear: { + function computePositionsExtruded(params, vertexFormat) { + var topVertexFormat = new VertexFormat({ + position : vertexFormat.position, + normal : (vertexFormat.normal || vertexFormat.bitangent || params.shadowVolume), + tangent : vertexFormat.tangent, + bitangent : (vertexFormat.normal || vertexFormat.bitangent), + st : vertexFormat.st + }); + var ellipsoid = params.ellipsoid; + var computedPositions = CorridorGeometryLibrary.computePositions(params); + var attr = combine(computedPositions, topVertexFormat, ellipsoid); + var height = params.height; + var extrudedHeight = params.extrudedHeight; + var attributes = attr.attributes; + var indices = attr.indices; + var positions = attributes.position.values; + var length = positions.length; + var newPositions = new Float64Array(length * 6); + var extrudedPositions = new Float64Array(length); + extrudedPositions.set(positions); + var wallPositions = new Float64Array(length * 4); - None: function ( k ) { + positions = PolygonPipeline.scaleToGeodeticHeight(positions, height, ellipsoid); + wallPositions = addWallPositions(positions, 0, wallPositions); + extrudedPositions = PolygonPipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); + wallPositions = addWallPositions(extrudedPositions, length * 2, wallPositions); + newPositions.set(positions); + newPositions.set(extrudedPositions, length); + newPositions.set(wallPositions, length * 2); + attributes.position.values = newPositions; - return k; + attributes = extrudedAttributes(attributes, vertexFormat); + var i; + var size = length / 3; + if (params.shadowVolume) { + var topNormals = attributes.normal.values; + length = topNormals.length; + var extrudeNormals = new Float32Array(length * 6); + for (i = 0; i < length; i ++) { + topNormals[i] = -topNormals[i]; } + //only get normals for bottom layer that's going to be pushed down + extrudeNormals.set(topNormals, length); //bottom face + extrudeNormals = addWallPositions(topNormals, length*4, extrudeNormals); //bottom wall + attributes.extrudeDirection = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : extrudeNormals + }); + if (!vertexFormat.normal) { + attributes.normal = undefined; + } + } - }, - - Quadratic: { - - In: function ( k ) { + var iLength = indices.length; + var twoSize = size + size; + var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, iLength * 2 + twoSize * 3); + newIndices.set(indices); + var index = iLength; + for (i = 0; i < iLength; i += 3) { // bottom indices + var v0 = indices[i]; + var v1 = indices[i + 1]; + var v2 = indices[i + 2]; + newIndices[index++] = v2 + size; + newIndices[index++] = v1 + size; + newIndices[index++] = v0 + size; + } - return k * k; + var UL, LL, UR, LR; - }, + for (i = 0; i < twoSize; i += 2) { //wall indices + UL = i + twoSize; + LL = UL + twoSize; + UR = UL + 1; + LR = LL + 1; + newIndices[index++] = UL; + newIndices[index++] = LL; + newIndices[index++] = UR; + newIndices[index++] = UR; + newIndices[index++] = LL; + newIndices[index++] = LR; + } - Out: function ( k ) { + return { + attributes : attributes, + indices : newIndices + }; + } - return k * ( 2 - k ); + var scratchCartesian1 = new Cartesian3(); + var scratchCartesian2 = new Cartesian3(); + var scratchCartographic = new Cartographic(); - }, + function computeOffsetPoints(position1, position2, ellipsoid, halfWidth, min, max) { + // Compute direction of offset the point + var direction = Cartesian3.subtract(position2, position1, scratchCartesian1); + Cartesian3.normalize(direction, direction); + var normal = ellipsoid.geodeticSurfaceNormal(position1, scratchCartesian2); + var offsetDirection = Cartesian3.cross(direction, normal, scratchCartesian1); + Cartesian3.multiplyByScalar(offsetDirection, halfWidth, offsetDirection); - InOut: function ( k ) { + var minLat = min.latitude; + var minLon = min.longitude; + var maxLat = max.latitude; + var maxLon = max.longitude; - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k; - return - 0.5 * ( --k * ( k - 2 ) - 1 ); + // Compute 2 offset points + Cartesian3.add(position1, offsetDirection, scratchCartesian2); + ellipsoid.cartesianToCartographic(scratchCartesian2, scratchCartographic); - } + var lat = scratchCartographic.latitude; + var lon = scratchCartographic.longitude; + minLat = Math.min(minLat, lat); + minLon = Math.min(minLon, lon); + maxLat = Math.max(maxLat, lat); + maxLon = Math.max(maxLon, lon); - }, + Cartesian3.subtract(position1, offsetDirection, scratchCartesian2); + ellipsoid.cartesianToCartographic(scratchCartesian2, scratchCartographic); - Cubic: { + lat = scratchCartographic.latitude; + lon = scratchCartographic.longitude; + minLat = Math.min(minLat, lat); + minLon = Math.min(minLon, lon); + maxLat = Math.max(maxLat, lat); + maxLon = Math.max(maxLon, lon); - In: function ( k ) { + min.latitude = minLat; + min.longitude = minLon; + max.latitude = maxLat; + max.longitude = maxLon; + } - return k * k * k; + var scratchCartesianOffset = new Cartesian3(); + var scratchCartesianEnds = new Cartesian3(); + var scratchCartographicMin = new Cartographic(); + var scratchCartographicMax = new Cartographic(); - }, + function computeRectangle(positions, ellipsoid, width, cornerType) { + positions = scaleToSurface(positions, ellipsoid); + var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); + var length = cleanPositions.length; + if (length < 2 || width <= 0) { + return new Rectangle(); + } + var halfWidth = width * 0.5; - Out: function ( k ) { + scratchCartographicMin.latitude = Number.POSITIVE_INFINITY; + scratchCartographicMin.longitude = Number.POSITIVE_INFINITY; + scratchCartographicMax.latitude = Number.NEGATIVE_INFINITY; + scratchCartographicMax.longitude = Number.NEGATIVE_INFINITY; - return --k * k * k + 1; + var lat, lon; + if (cornerType === CornerType.ROUNDED) { + // Compute start cap + var first = cleanPositions[0]; + Cartesian3.subtract(first, cleanPositions[1], scratchCartesianOffset); + Cartesian3.normalize(scratchCartesianOffset, scratchCartesianOffset); + Cartesian3.multiplyByScalar(scratchCartesianOffset, halfWidth, scratchCartesianOffset); + Cartesian3.add(first, scratchCartesianOffset, scratchCartesianEnds); - }, + ellipsoid.cartesianToCartographic(scratchCartesianEnds, scratchCartographic); + lat = scratchCartographic.latitude; + lon = scratchCartographic.longitude; + scratchCartographicMin.latitude = Math.min(scratchCartographicMin.latitude, lat); + scratchCartographicMin.longitude = Math.min(scratchCartographicMin.longitude, lon); + scratchCartographicMax.latitude = Math.max(scratchCartographicMax.latitude, lat); + scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon); + } - InOut: function ( k ) { + // Compute the rest + for (var i = 0; i < length-1; ++i) { + computeOffsetPoints(cleanPositions[i], cleanPositions[i+1], ellipsoid, halfWidth, + scratchCartographicMin, scratchCartographicMax); + } - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k; - return 0.5 * ( ( k -= 2 ) * k * k + 2 ); + // Compute ending point + var last = cleanPositions[length-1]; + Cartesian3.subtract(last, cleanPositions[length-2], scratchCartesianOffset); + Cartesian3.normalize(scratchCartesianOffset, scratchCartesianOffset); + Cartesian3.multiplyByScalar(scratchCartesianOffset, halfWidth, scratchCartesianOffset); + Cartesian3.add(last, scratchCartesianOffset, scratchCartesianEnds); + computeOffsetPoints(last, scratchCartesianEnds, ellipsoid, halfWidth, + scratchCartographicMin, scratchCartographicMax); - } + if (cornerType === CornerType.ROUNDED) { + // Compute end cap + ellipsoid.cartesianToCartographic(scratchCartesianEnds, scratchCartographic); + lat = scratchCartographic.latitude; + lon = scratchCartographic.longitude; + scratchCartographicMin.latitude = Math.min(scratchCartographicMin.latitude, lat); + scratchCartographicMin.longitude = Math.min(scratchCartographicMin.longitude, lon); + scratchCartographicMax.latitude = Math.max(scratchCartographicMax.latitude, lat); + scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon); + } - }, + var rectangle = new Rectangle(); + rectangle.north = scratchCartographicMax.latitude; + rectangle.south = scratchCartographicMin.latitude; + rectangle.east = scratchCartographicMax.longitude; + rectangle.west = scratchCartographicMin.longitude; - Quartic: { + return rectangle; + } - In: function ( k ) { + /** + * A description of a corridor. Corridor geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * + * @alias CorridorGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor. + * @param {Number} options.width The distance between the edges of the corridor in meters. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number} [options.height=0] The distance in meters between the ellipsoid surface and the positions. + * @param {Number} [options.extrudedHeight] The distance in meters between the ellipsoid surface and the extruded face. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. + * + * @see CorridorGeometry.createGeometry + * @see Packable + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo} + * + * @example + * var corridor = new Cesium.CorridorGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, + * positions : Cesium.Cartesian3.fromDegreesArray([-72.0, 40.0, -70.0, 35.0]), + * width : 100000 + * }); + */ + function CorridorGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.positions; + var width = options.width; - return k * k * k * k; + if (!defined(positions)) { + throw new DeveloperError('options.positions is required.'); + } + if (!defined(width)) { + throw new DeveloperError('options.width is required.'); + } + + this._positions = positions; + this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); + this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); + this._width = width; + this._height = defaultValue(options.height, 0); + this._extrudedHeight = defaultValue(options.extrudedHeight, this._height); + this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._shadowVolume = defaultValue(options.shadowVolume, false); + this._workerName = 'createCorridorGeometry'; + this._rectangle = computeRectangle(positions, this._ellipsoid, width, this._cornerType); - }, + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = 1 + positions.length * Cartesian3.packedLength + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 6; + } - Out: function ( k ) { + /** + * Stores the provided instance into the provided array. + * + * @param {CorridorGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + CorridorGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - return 1 - ( --k * k * k * k ); + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; - }, + for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); + } - InOut: function ( k ) { + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k; - return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 ); + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; - } + Rectangle.pack(value._rectangle, array, startingIndex); + startingIndex += Rectangle.packedLength; - }, + array[startingIndex++] = value._width; + array[startingIndex++] = value._height; + array[startingIndex++] = value._extrudedHeight; + array[startingIndex++] = value._cornerType; + array[startingIndex++] = value._granularity; + array[startingIndex] = value._shadowVolume ? 1.0 : 0.0; - Quintic: { + return array; + }; - In: function ( k ) { + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchVertexFormat = new VertexFormat(); + var scratchRectangle = new Rectangle(); + var scratchOptions = { + positions : undefined, + ellipsoid : scratchEllipsoid, + vertexFormat : scratchVertexFormat, + width : undefined, + height : undefined, + extrudedHeight : undefined, + cornerType : undefined, + granularity : undefined, + shadowVolume: undefined + }; - return k * k * k * k * k; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {CorridorGeometry} [result] The object into which to store the result. + * @returns {CorridorGeometry} The modified result parameter or a new CorridorGeometry instance if one was not provided. + */ + CorridorGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - }, + var length = array[startingIndex++]; + var positions = new Array(length); - Out: function ( k ) { + for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); + } - return --k * k * k * k * k + 1; + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - }, + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; - InOut: function ( k ) { + var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); + startingIndex += Rectangle.packedLength; - if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k; - return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 ); + var width = array[startingIndex++]; + var height = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var cornerType = array[startingIndex++]; + var granularity = array[startingIndex++]; + var shadowVolume = array[startingIndex] === 1.0; - } + if (!defined(result)) { + scratchOptions.positions = positions; + scratchOptions.width = width; + scratchOptions.height = height; + scratchOptions.extrudedHeight = extrudedHeight; + scratchOptions.cornerType = cornerType; + scratchOptions.granularity = granularity; + scratchOptions.shadowVolume = shadowVolume; + return new CorridorGeometry(scratchOptions); + } - }, + result._positions = positions; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._width = width; + result._height = height; + result._extrudedHeight = extrudedHeight; + result._cornerType = cornerType; + result._granularity = granularity; + result._rectangle = Rectangle.clone(rectangle); + result._shadowVolume = shadowVolume; - Sinusoidal: { + return result; + }; - In: function ( k ) { + /** + * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. + * + * @param {CorridorGeometry} corridorGeometry A description of the corridor. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + CorridorGeometry.createGeometry = function(corridorGeometry) { + var positions = corridorGeometry._positions; + var height = corridorGeometry._height; + var width = corridorGeometry._width; + var extrudedHeight = corridorGeometry._extrudedHeight; + var extrude = (height !== extrudedHeight); + var ellipsoid = corridorGeometry._ellipsoid; - return 1 - Math.cos( k * Math.PI / 2 ); + positions = scaleToSurface(positions, ellipsoid); + var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - }, + if ((cleanPositions.length < 2) || (width <= 0)) { + return; + } - Out: function ( k ) { + var vertexFormat = corridorGeometry._vertexFormat; + var params = { + ellipsoid : ellipsoid, + positions : cleanPositions, + width : width, + cornerType : corridorGeometry._cornerType, + granularity : corridorGeometry._granularity, + saveAttributes: true + }; + var attr; + if (extrude) { + var h = Math.max(height, extrudedHeight); + extrudedHeight = Math.min(height, extrudedHeight); + height = h; + params.height = height; + params.extrudedHeight = extrudedHeight; + params.shadowVolume = corridorGeometry._shadowVolume; + attr = computePositionsExtruded(params, vertexFormat); + } else { + var computedPositions = CorridorGeometryLibrary.computePositions(params); + attr = combine(computedPositions, vertexFormat, ellipsoid); + attr.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid); + } + var attributes = attr.attributes; + var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); + if (!vertexFormat.position) { + attr.attributes.position.values = undefined; + } - return Math.sin( k * Math.PI / 2 ); + return new Geometry({ + attributes : attributes, + indices : attr.indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : boundingSphere + }); + }; - }, + /** + * @private + */ + CorridorGeometry.createShadowVolume = function(corridorGeometry, minHeightFunc, maxHeightFunc) { + var granularity = corridorGeometry._granularity; + var ellipsoid = corridorGeometry._ellipsoid; - InOut: function ( k ) { + var minHeight = minHeightFunc(granularity, ellipsoid); + var maxHeight = maxHeightFunc(granularity, ellipsoid); - return 0.5 * ( 1 - Math.cos( Math.PI * k ) ); + return new CorridorGeometry({ + positions : corridorGeometry._positions, + width : corridorGeometry._width, + cornerType : corridorGeometry._cornerType, + ellipsoid : ellipsoid, + granularity : granularity, + extrudedHeight : minHeight, + height : maxHeight, + vertexFormat : VertexFormat.POSITION_ONLY, + shadowVolume: true + }); + }; + defineProperties(CorridorGeometry.prototype, { + /** + * @private + */ + rectangle : { + get : function() { + return this._rectangle; } + } + }); - }, - - Exponential: { + return CorridorGeometry; +}); - In: function ( k ) { +define('Core/CorridorOutlineGeometry',[ + './arrayRemoveDuplicates', + './BoundingSphere', + './Cartesian3', + './Check', + './ComponentDatatype', + './CornerType', + './CorridorGeometryLibrary', + './defaultValue', + './defined', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PolygonPipeline', + './PrimitiveType' + ], function( + arrayRemoveDuplicates, + BoundingSphere, + Cartesian3, + Check, + ComponentDatatype, + CornerType, + CorridorGeometryLibrary, + defaultValue, + defined, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PolygonPipeline, + PrimitiveType) { + 'use strict'; - return k === 0 ? 0 : Math.pow( 1024, k - 1 ); + var cartesian1 = new Cartesian3(); + var cartesian2 = new Cartesian3(); + var cartesian3 = new Cartesian3(); - }, + function scaleToSurface(positions, ellipsoid) { + for (var i = 0; i < positions.length; i++) { + positions[i] = ellipsoid.scaleToGeodeticSurface(positions[i], positions[i]); + } + return positions; + } - Out: function ( k ) { + function combine(computedPositions, cornerType) { + var wallIndices = []; + var positions = computedPositions.positions; + var corners = computedPositions.corners; + var endPositions = computedPositions.endPositions; + var attributes = new GeometryAttributes(); + var corner; + var leftCount = 0; + var rightCount = 0; + var i; + var indicesLength = 0; + var length; + for (i = 0; i < positions.length; i += 2) { + length = positions[i].length - 3; + leftCount += length; //subtracting 3 to account for duplicate points at corners + indicesLength += length / 3 * 4; + rightCount += positions[i + 1].length - 3; + } + leftCount += 3; //add back count for end positions + rightCount += 3; + for (i = 0; i < corners.length; i++) { + corner = corners[i]; + var leftSide = corners[i].leftPositions; + if (defined(leftSide)) { + length = leftSide.length; + leftCount += length; + indicesLength += length / 3 * 2; + } else { + length = corners[i].rightPositions.length; + rightCount += length; + indicesLength += length / 3 * 2; + } + } - return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k ); + var addEndPositions = defined(endPositions); + var endPositionLength; + if (addEndPositions) { + endPositionLength = endPositions[0].length - 3; + leftCount += endPositionLength; + rightCount += endPositionLength; + endPositionLength /= 3; + indicesLength += endPositionLength * 4; + } + var size = leftCount + rightCount; + var finalPositions = new Float64Array(size); + var front = 0; + var back = size - 1; + var UL, LL, UR, LR; + var rightPos, leftPos; + var halfLength = endPositionLength / 2; - }, + var indices = IndexDatatype.createTypedArray(size / 3, indicesLength + 4); + var index = 0; - InOut: function ( k ) { + indices[index++] = front / 3; + indices[index++] = (back - 2) / 3; + if (addEndPositions) { // add rounded end + wallIndices.push(front / 3); + leftPos = cartesian1; + rightPos = cartesian2; + var firstEndPositions = endPositions[0]; + for (i = 0; i < halfLength; i++) { + leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); + rightPos = Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos); + CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); - 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 ); + LL = front / 3; + LR = LL + 1; + UL = (back - 2) / 3; + UR = UL - 1; + indices[index++] = UL; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; + front += 3; + back -= 3; } + } - }, - - Circular: { - - In: function ( k ) { - - return 1 - Math.sqrt( 1 - k * k ); + var posIndex = 0; + var rightEdge = positions[posIndex++]; //add first two edges + var leftEdge = positions[posIndex++]; + finalPositions.set(rightEdge, front); + finalPositions.set(leftEdge, back - leftEdge.length + 1); - }, + length = leftEdge.length - 3; + wallIndices.push(front / 3, (back - 2) / 3); + for (i = 0; i < length; i += 3) { + LL = front / 3; + LR = LL + 1; + UL = (back - 2) / 3; + UR = UL - 1; + indices[index++] = UL; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; - Out: function ( k ) { + front += 3; + back -= 3; + } - return Math.sqrt( 1 - ( --k * k ) ); + for (i = 0; i < corners.length; i++) { + var j; + corner = corners[i]; + var l = corner.leftPositions; + var r = corner.rightPositions; + var start; + var outsidePoint = cartesian3; + if (defined(l)) { + back -= 3; + start = UR; + wallIndices.push(LR); + for (j = 0; j < l.length / 3; j++) { + outsidePoint = Cartesian3.fromArray(l, j * 3, outsidePoint); + indices[index++] = start - j - 1; + indices[index++] = start - j; + CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); + back -= 3; + } + wallIndices.push(start - Math.floor(l.length / 6)); + if (cornerType === CornerType.BEVELED) { + wallIndices.push((back - 2) / 3 + 1); + } + front += 3; + } else { + front += 3; + start = LR; + wallIndices.push(UR); + for (j = 0; j < r.length / 3; j++) { + outsidePoint = Cartesian3.fromArray(r, j * 3, outsidePoint); + indices[index++] = start + j; + indices[index++] = start + j + 1; + CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); + front += 3; + } + wallIndices.push(start + Math.floor(r.length / 6)); + if (cornerType === CornerType.BEVELED) { + wallIndices.push(front / 3 - 1); + } + back -= 3; + } + rightEdge = positions[posIndex++]; + leftEdge = positions[posIndex++]; + rightEdge.splice(0, 3); //remove duplicate points added by corner + leftEdge.splice(leftEdge.length - 3, 3); + finalPositions.set(rightEdge, front); + finalPositions.set(leftEdge, back - leftEdge.length + 1); + length = leftEdge.length - 3; - }, + for (j = 0; j < leftEdge.length; j += 3) { + LR = front / 3; + LL = LR - 1; + UR = (back - 2) / 3; + UL = UR + 1; + indices[index++] = UL; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; + front += 3; + back -= 3; + } + front -= 3; + back += 3; + wallIndices.push(front / 3, (back - 2) / 3); + } - InOut: function ( k ) { + if (addEndPositions) { // add rounded end + front += 3; + back -= 3; + leftPos = cartesian1; + rightPos = cartesian2; + var lastEndPositions = endPositions[1]; + for (i = 0; i < halfLength; i++) { + leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); + rightPos = Cartesian3.fromArray(lastEndPositions, i * 3, rightPos); + CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); - if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1); - return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1); + LR = front / 3; + LL = LR - 1; + UR = (back - 2) / 3; + UL = UR + 1; + indices[index++] = UL; + indices[index++] = UR; + indices[index++] = LL; + indices[index++] = LR; + front += 3; + back -= 3; } - }, + wallIndices.push(front / 3); + } else { + wallIndices.push(front / 3, (back - 2) / 3); + } + indices[index++] = front / 3; + indices[index++] = (back - 2) / 3; - Elastic: { + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : finalPositions + }); - In: function ( k ) { + return { + attributes : attributes, + indices : indices, + wallIndices : wallIndices + }; + } - 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 ) ); + function computePositionsExtruded(params) { + var ellipsoid = params.ellipsoid; + var computedPositions = CorridorGeometryLibrary.computePositions(params); + var attr = combine(computedPositions, params.cornerType); + var wallIndices = attr.wallIndices; + var height = params.height; + var extrudedHeight = params.extrudedHeight; + var attributes = attr.attributes; + var indices = attr.indices; + var positions = attributes.position.values; + var length = positions.length; + var extrudedPositions = new Float64Array(length); + extrudedPositions.set(positions); + var newPositions = new Float64Array(length * 2); - }, + positions = PolygonPipeline.scaleToGeodeticHeight(positions, height, ellipsoid); + extrudedPositions = PolygonPipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); + newPositions.set(positions); + newPositions.set(extrudedPositions, length); + attributes.position.values = newPositions; - Out: function ( k ) { + length /= 3; + var i; + var iLength = indices.length; + var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, (iLength + wallIndices.length) * 2); + newIndices.set(indices); + var index = iLength; + for (i = 0; i < iLength; i += 2) { // bottom indices + var v0 = indices[i]; + var v1 = indices[i + 1]; + newIndices[index++] = v0 + length; + newIndices[index++] = v1 + length; + } - 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 ); + var UL, LL; + for (i = 0; i < wallIndices.length; i++) { //wall indices + UL = wallIndices[i]; + LL = UL + length; + newIndices[index++] = UL; + newIndices[index++] = LL; + } - }, + return { + attributes : attributes, + indices : newIndices + }; + } - InOut: function ( k ) { + /** + * A description of a corridor outline. + * + * @alias CorridorOutlineGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor outline. + * @param {Number} options.width The distance between the edges of the corridor outline. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number} [options.height=0] The distance in meters between the positions and the ellipsoid surface. + * @param {Number} [options.extrudedHeight] The distance in meters between the extruded face and the ellipsoid surface. + * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. + * + * @see CorridorOutlineGeometry.createGeometry + * + * @example + * var corridor = new Cesium.CorridorOutlineGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArray([-72.0, 40.0, -70.0, 35.0]), + * width : 100000 + * }); + */ + function CorridorOutlineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.positions; + var width = options.width; - 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; + Check.typeOf.object('options.positions', positions); + Check.typeOf.number('options.width', width); + + this._positions = positions; + this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); + this._width = width; + this._height = defaultValue(options.height, 0); + this._extrudedHeight = defaultValue(options.extrudedHeight, this._height); + this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._workerName = 'createCorridorOutlineGeometry'; - } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = 1 + positions.length * Cartesian3.packedLength + Ellipsoid.packedLength + 5; + } - }, + /** + * Stores the provided instance into the provided array. + * + * @param {CorridorOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + CorridorOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.typeOf.object('array', array); + + startingIndex = defaultValue(startingIndex, 0); - Back: { + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; - In: function ( k ) { + for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); + } - 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 ); - - }, + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - Out: function ( k ) { + array[startingIndex++] = value._width; + array[startingIndex++] = value._height; + array[startingIndex++] = value._extrudedHeight; + array[startingIndex++] = value._cornerType; + array[startingIndex] = value._granularity; - if ( k < ( 1 / 2.75 ) ) { + return array; + }; - return 7.5625 * k * k; + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchOptions = { + positions : undefined, + ellipsoid : scratchEllipsoid, + width : undefined, + height : undefined, + extrudedHeight : undefined, + cornerType : undefined, + granularity : undefined + }; - } else if ( k < ( 2 / 2.75 ) ) { + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {CorridorOutlineGeometry} [result] The object into which to store the result. + * @returns {CorridorOutlineGeometry} The modified result parameter or a new CorridorOutlineGeometry instance if one was not provided. + */ + CorridorOutlineGeometry.unpack = function(array, startingIndex, result) { + Check.typeOf.object('array', array); + + startingIndex = defaultValue(startingIndex, 0); - return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; + var length = array[startingIndex++]; + var positions = new Array(length); - } else if ( k < ( 2.5 / 2.75 ) ) { + for (var i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); + } - return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - } else { + var width = array[startingIndex++]; + var height = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var cornerType = array[startingIndex++]; + var granularity = array[startingIndex]; - return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; + if (!defined(result)) { + scratchOptions.positions = positions; + scratchOptions.width = width; + scratchOptions.height = height; + scratchOptions.extrudedHeight = extrudedHeight; + scratchOptions.cornerType = cornerType; + scratchOptions.granularity = granularity; + return new CorridorOutlineGeometry(scratchOptions); + } - } + result._positions = positions; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._width = width; + result._height = height; + result._extrudedHeight = extrudedHeight; + result._cornerType = cornerType; + result._granularity = granularity; - }, + return result; + }; - InOut: function ( k ) { + /** + * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. + * + * @param {CorridorOutlineGeometry} corridorOutlineGeometry A description of the corridor. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + CorridorOutlineGeometry.createGeometry = function(corridorOutlineGeometry) { + var positions = corridorOutlineGeometry._positions; + var height = corridorOutlineGeometry._height; + var width = corridorOutlineGeometry._width; + var extrudedHeight = corridorOutlineGeometry._extrudedHeight; + var extrude = (height !== extrudedHeight); + var ellipsoid = corridorOutlineGeometry._ellipsoid; - 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; + positions = scaleToSurface(positions, ellipsoid); + var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - } + if ((cleanPositions.length < 2) || (width <= 0)) { + return; + } + var params = { + ellipsoid : ellipsoid, + positions : cleanPositions, + width : width, + cornerType : corridorOutlineGeometry._cornerType, + granularity : corridorOutlineGeometry._granularity, + saveAttributes : false + }; + var attr; + if (extrude) { + var h = Math.max(height, extrudedHeight); + extrudedHeight = Math.min(height, extrudedHeight); + height = h; + params.height = height; + params.extrudedHeight = extrudedHeight; + attr = computePositionsExtruded(params); + } else { + var computedPositions = CorridorGeometryLibrary.computePositions(params); + attr = combine(computedPositions, params.cornerType); + attr.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid); } + var attributes = attr.attributes; + var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); + return new Geometry({ + attributes : attributes, + indices : attr.indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : boundingSphere + }); }; - 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 ); - - }, + return CorridorOutlineGeometry; +}); - Bezier: function ( v, k ) { +define('Core/createGuid',[],function() { + 'use strict'; - var b = 0, n = v.length - 1, pw = Math.pow, bn = TWEEN.Interpolation.Utils.Bernstein, i; + /** + * Creates a Globally unique identifier (GUID) string. A GUID is 128 bits long, and can guarantee uniqueness across space and time. + * + * @exports createGuid + * + * @returns {String} + * + * + * @example + * this.guid = Cesium.createGuid(); + * + * @see {@link http://www.ietf.org/rfc/rfc4122.txt|RFC 4122 A Universally Unique IDentifier (UUID) URN Namespace} + */ + function createGuid() { + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0; + var v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } - for ( i = 0; i <= n; i++ ) { - b += pw( 1 - k, n - i ) * pw( k, i ) * v[ i ] * bn( n, i ); - } + return createGuid; +}); - return b; +define('Core/CullingVolume',[ + './Cartesian3', + './Cartesian4', + './defaultValue', + './defined', + './DeveloperError', + './Intersect', + './Plane' + ], function( + Cartesian3, + Cartesian4, + defaultValue, + defined, + DeveloperError, + Intersect, + Plane) { + 'use strict'; - }, + /** + * The culling volume defined by planes. + * + * @alias CullingVolume + * @constructor + * + * @param {Cartesian4[]} [planes] An array of clipping planes. + */ + function CullingVolume(planes) { + /** + * Each plane is represented by a Cartesian4 object, where the x, y, and z components + * define the unit vector normal to the plane, and the w component is the distance of the + * plane from the origin. + * @type {Cartesian4[]} + * @default [] + */ + this.planes = defaultValue(planes, []); + } - CatmullRom: function ( v, k ) { + var faces = [new Cartesian3(), new Cartesian3(), new Cartesian3()]; + Cartesian3.clone(Cartesian3.UNIT_X, faces[0]); + Cartesian3.clone(Cartesian3.UNIT_Y, faces[1]); + Cartesian3.clone(Cartesian3.UNIT_Z, faces[2]); - var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.CatmullRom; + var scratchPlaneCenter = new Cartesian3(); + var scratchPlaneNormal = new Cartesian3(); + var scratchPlane = new Plane(new Cartesian3(1.0, 0.0, 0.0), 0.0); - if ( v[ 0 ] === v[ m ] ) { + /** + * Constructs a culling volume from a bounding sphere. Creates six planes that create a box containing the sphere. + * The planes are aligned to the x, y, and z axes in world coordinates. + * + * @param {BoundingSphere} boundingSphere The bounding sphere used to create the culling volume. + * @param {CullingVolume} [result] The object onto which to store the result. + * @returns {CullingVolume} The culling volume created from the bounding sphere. + */ + CullingVolume.fromBoundingSphere = function(boundingSphere, result) { + if (!defined(boundingSphere)) { + throw new DeveloperError('boundingSphere is required.'); + } + + if (!defined(result)) { + result = new CullingVolume(); + } - if ( k < 0 ) i = Math.floor( f = m * ( 1 + k ) ); + var length = faces.length; + var planes = result.planes; + planes.length = 2 * length; - return fn( v[ ( i - 1 + m ) % m ], v[ i ], v[ ( i + 1 ) % m ], v[ ( i + 2 ) % m ], f - i ); + var center = boundingSphere.center; + var radius = boundingSphere.radius; - } else { + var planeIndex = 0; - 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 ] ); + for (var i = 0; i < length; ++i) { + var faceNormal = faces[i]; - 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 ); + var plane0 = planes[planeIndex]; + var plane1 = planes[planeIndex + 1]; + if (!defined(plane0)) { + plane0 = planes[planeIndex] = new Cartesian4(); + } + if (!defined(plane1)) { + plane1 = planes[planeIndex + 1] = new Cartesian4(); } - }, - - 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 ); + Cartesian3.multiplyByScalar(faceNormal, -radius, scratchPlaneCenter); + Cartesian3.add(center, scratchPlaneCenter, scratchPlaneCenter); - }, + plane0.x = faceNormal.x; + plane0.y = faceNormal.y; + plane0.z = faceNormal.z; + plane0.w = -Cartesian3.dot(faceNormal, scratchPlaneCenter); - Factorial: ( function () { + Cartesian3.multiplyByScalar(faceNormal, radius, scratchPlaneCenter); + Cartesian3.add(center, scratchPlaneCenter, scratchPlaneCenter); - var a = [ 1 ]; + plane1.x = -faceNormal.x; + plane1.y = -faceNormal.y; + plane1.z = -faceNormal.z; + plane1.w = -Cartesian3.dot(Cartesian3.negate(faceNormal, scratchPlaneNormal), scratchPlaneCenter); - return function ( n ) { + planeIndex += 2; + } - var s = 1, i; - if ( a[ n ] ) return a[ n ]; - for ( i = n; i > 1; i-- ) s *= i; - return a[ n ] = s; + return result; + }; - }; + /** + * Determines whether a bounding volume intersects the culling volume. + * + * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. + * @returns {Intersect} Intersect.OUTSIDE, Intersect.INTERSECTING, or Intersect.INSIDE. + */ + CullingVolume.prototype.computeVisibility = function(boundingVolume) { + if (!defined(boundingVolume)) { + throw new DeveloperError('boundingVolume is required.'); + } + + var planes = this.planes; + var intersecting = false; + for (var k = 0, len = planes.length; k < len; ++k) { + var result = boundingVolume.intersectPlane(Plane.fromCartesian4(planes[k], scratchPlane)); + if (result === Intersect.OUTSIDE) { + return Intersect.OUTSIDE; + } else if (result === Intersect.INTERSECTING) { + intersecting = true; + } + } - } )(), + return intersecting ? Intersect.INTERSECTING : Intersect.INSIDE; + }; - CatmullRom: function ( p0, p1, p2, p3, t ) { + /** + * Determines whether a bounding volume intersects the culling volume. + * + * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. + * @param {Number} parentPlaneMask A bit mask from the boundingVolume's parent's check against the same culling + * volume, such that if (planeMask & (1 << planeIndex) === 0), for k < 31, then + * the parent (and therefore this) volume is completely inside plane[planeIndex] + * and that plane check can be skipped. + * @returns {Number} A plane mask as described above (which can be applied to this boundingVolume's children). + * + * @private + */ + CullingVolume.prototype.computeVisibilityWithPlaneMask = function(boundingVolume, parentPlaneMask) { + if (!defined(boundingVolume)) { + throw new DeveloperError('boundingVolume is required.'); + } + if (!defined(parentPlaneMask)) { + throw new DeveloperError('parentPlaneMask is required.'); + } + + if (parentPlaneMask === CullingVolume.MASK_OUTSIDE || parentPlaneMask === CullingVolume.MASK_INSIDE) { + // parent is completely outside or completely inside, so this child is as well. + return parentPlaneMask; + } - 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; + // Start with MASK_INSIDE (all zeros) so that after the loop, the return value can be compared with MASK_INSIDE. + // (Because if there are fewer than 31 planes, the upper bits wont be changed.) + var mask = CullingVolume.MASK_INSIDE; + var planes = this.planes; + for (var k = 0, len = planes.length; k < len; ++k) { + // For k greater than 31 (since 31 is the maximum number of INSIDE/INTERSECTING bits we can store), skip the optimization. + var flag = (k < 31) ? (1 << k) : 0; + if (k < 31 && (parentPlaneMask & flag) === 0) { + // boundingVolume is known to be INSIDE this plane. + continue; } + var result = boundingVolume.intersectPlane(Plane.fromCartesian4(planes[k], scratchPlane)); + if (result === Intersect.OUTSIDE) { + return CullingVolume.MASK_OUTSIDE; + } else if (result === Intersect.INTERSECTING) { + mask |= flag; + } } + return mask; }; -return TWEEN; -}); - -define('Core/EasingFunction',[ - '../ThirdParty/Tween', - './freezeObject' - ], function( - Tween, - freezeObject) { - 'use strict'; + /** + * For plane masks (as used in {@link CullingVolume#computeVisibilityWithPlaneMask}), this special value + * represents the case where the object bounding volume is entirely outside the culling volume. + * + * @type {Number} + * @private + */ + CullingVolume.MASK_OUTSIDE = 0xffffffff; /** - * Easing functions for use with {@link TweenCollection}. These function are from - * {@link https://github.com/sole/tween.js/|Tween.js} and Robert Penner. See the - * {@link http://sole.github.io/tween.js/examples/03_graphs.html|Tween.js graphs for each function}. + * For plane masks (as used in {@link CullingVolume.prototype.computeVisibilityWithPlaneMask}), this value + * represents the case where the object bounding volume is entirely inside the culling volume. * - * @exports EasingFunction + * @type {Number} + * @private */ - var EasingFunction = { - /** - * Linear easing. - * - * @type {EasingFunction~Callback} - * @constant - */ - LINEAR_NONE : Tween.Easing.Linear.None, + CullingVolume.MASK_INSIDE = 0x00000000; - /** - * Quadratic in. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUADRACTIC_IN : Tween.Easing.Quadratic.In, - /** - * Quadratic out. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUADRACTIC_OUT : Tween.Easing.Quadratic.Out, - /** - * Quadratic in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUADRACTIC_IN_OUT : Tween.Easing.Quadratic.InOut, + /** + * For plane masks (as used in {@link CullingVolume.prototype.computeVisibilityWithPlaneMask}), this value + * represents the case where the object bounding volume (may) intersect all planes of the culling volume. + * + * @type {Number} + * @private + */ + CullingVolume.MASK_INDETERMINATE = 0x7fffffff; - /** - * Cubic in. - * - * @type {EasingFunction~Callback} - * @constant - */ - CUBIC_IN : Tween.Easing.Cubic.In, - /** - * Cubic out. - * - * @type {EasingFunction~Callback} - * @constant - */ - CUBIC_OUT : Tween.Easing.Cubic.Out, - /** - * Cubic in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - CUBIC_IN_OUT : Tween.Easing.Cubic.InOut, + return CullingVolume; +}); - /** - * Quartic in. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUARTIC_IN : Tween.Easing.Quartic.In, - /** - * Quartic out. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUARTIC_OUT : Tween.Easing.Quartic.Out, - /** - * Quartic in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUARTIC_IN_OUT : Tween.Easing.Quartic.InOut, +define('Core/CylinderGeometryLibrary',[ + './Math' + ], function( + CesiumMath) { + 'use strict'; - /** - * Quintic in. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUINTIC_IN : Tween.Easing.Quintic.In, - /** - * Quintic out. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUINTIC_OUT : Tween.Easing.Quintic.Out, - /** - * Quintic in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - QUINTIC_IN_OUT : Tween.Easing.Quintic.InOut, + /** + * @private + */ + var CylinderGeometryLibrary = {}; - /** - * Sinusoidal in. - * - * @type {EasingFunction~Callback} - * @constant - */ - SINUSOIDAL_IN : Tween.Easing.Sinusoidal.In, - /** - * Sinusoidal out. - * - * @type {EasingFunction~Callback} - * @constant - */ - SINUSOIDAL_OUT : Tween.Easing.Sinusoidal.Out, - /** - * Sinusoidal in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - SINUSOIDAL_IN_OUT : Tween.Easing.Sinusoidal.InOut, + /** + * @private + */ + CylinderGeometryLibrary.computePositions = function(length, topRadius, bottomRadius, slices, fill){ + var topZ = length * 0.5; + var bottomZ = -topZ; - /** - * Exponential in. - * - * @type {EasingFunction~Callback} - * @constant - */ - EXPONENTIAL_IN : Tween.Easing.Exponential.In, - /** - * Exponential out. - * - * @type {EasingFunction~Callback} - * @constant - */ - EXPONENTIAL_OUT : Tween.Easing.Exponential.Out, - /** - * Exponential in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - EXPONENTIAL_IN_OUT : Tween.Easing.Exponential.InOut, + var twoSlice = slices + slices; + var size = (fill) ? 2 * twoSlice : twoSlice; + var positions = new Float64Array(size*3); + var i; + var index = 0; + var tbIndex = 0; + var bottomOffset = (fill) ? twoSlice*3 : 0; + var topOffset = (fill) ? (twoSlice + slices)*3 : slices*3; - /** - * Circular in. - * - * @type {EasingFunction~Callback} - * @constant - */ - CIRCULAR_IN : Tween.Easing.Circular.In, - /** - * Circular out. - * - * @type {EasingFunction~Callback} - * @constant - */ - CIRCULAR_OUT : Tween.Easing.Circular.Out, - /** - * Circular in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - CIRCULAR_IN_OUT : Tween.Easing.Circular.InOut, + for (i = 0; i < slices; i++) { + var angle = i / slices * CesiumMath.TWO_PI; + var x = Math.cos(angle); + var y = Math.sin(angle); + var bottomX = x * bottomRadius; + var bottomY = y * bottomRadius; + var topX = x * topRadius; + var topY = y * topRadius; - /** - * Elastic in. - * - * @type {EasingFunction~Callback} - * @constant - */ - ELASTIC_IN : Tween.Easing.Elastic.In, - /** - * Elastic out. - * - * @type {EasingFunction~Callback} - * @constant - */ - ELASTIC_OUT : Tween.Easing.Elastic.Out, - /** - * Elastic in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - ELASTIC_IN_OUT : Tween.Easing.Elastic.InOut, + positions[tbIndex + bottomOffset] = bottomX; + positions[tbIndex + bottomOffset + 1] = bottomY; + positions[tbIndex + bottomOffset + 2] = bottomZ; - /** - * Back in. - * - * @type {EasingFunction~Callback} - * @constant - */ - BACK_IN : Tween.Easing.Back.In, - /** - * Back out. - * - * @type {EasingFunction~Callback} - * @constant - */ - BACK_OUT : Tween.Easing.Back.Out, - /** - * Back in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - BACK_IN_OUT : Tween.Easing.Back.InOut, + positions[tbIndex + topOffset] = topX; + positions[tbIndex + topOffset + 1] = topY; + positions[tbIndex + topOffset + 2] = topZ; + tbIndex += 3; + if (fill) { + positions[index++] = bottomX; + positions[index++] = bottomY; + positions[index++] = bottomZ; + positions[index++] = topX; + positions[index++] = topY; + positions[index++] = topZ; + } + } - /** - * Bounce in. - * - * @type {EasingFunction~Callback} - * @constant - */ - BOUNCE_IN : Tween.Easing.Bounce.In, - /** - * Bounce out. - * - * @type {EasingFunction~Callback} - * @constant - */ - BOUNCE_OUT : Tween.Easing.Bounce.Out, - /** - * Bounce in then out. - * - * @type {EasingFunction~Callback} - * @constant - */ - BOUNCE_IN_OUT : Tween.Easing.Bounce.InOut + return positions; }; - /** - * Function interface for implementing a custom easing function. - * @callback EasingFunction~Callback - * @param {Number} time The time in the range <code>[0, 1]</code>. - * @returns {Number} The value of the function at the given time. - * - * @example - * function quadraticIn(time) { - * return time * time; - * } - * - * @example - * function quadraticOut(time) { - * return time * (2.0 - time); - * } - */ - - return freezeObject(EasingFunction); + return CylinderGeometryLibrary; }); -define('Core/EllipsoidGeometry',[ +define('Core/CylinderGeometry',[ './BoundingSphere', './Cartesian2', './Cartesian3', './ComponentDatatype', + './CylinderGeometryLibrary', './defaultValue', './defined', './DeveloperError', - './Ellipsoid', './Geometry', './GeometryAttribute', './GeometryAttributes', @@ -49022,10 +48002,10 @@ define('Core/EllipsoidGeometry',[ Cartesian2, Cartesian3, ComponentDatatype, + CylinderGeometryLibrary, defaultValue, defined, DeveloperError, - Ellipsoid, Geometry, GeometryAttribute, GeometryAttributes, @@ -49035,78 +48015,89 @@ define('Core/EllipsoidGeometry',[ VertexFormat) { 'use strict'; - var scratchPosition = new Cartesian3(); - var scratchNormal = new Cartesian3(); - var scratchTangent = new Cartesian3(); - var scratchBitangent = new Cartesian3(); - var scratchNormalST = new Cartesian3(); - var defaultRadii = new Cartesian3(1.0, 1.0, 1.0); + var radiusScratch = new Cartesian2(); + var normalScratch = new Cartesian3(); + var bitangentScratch = new Cartesian3(); + var tangentScratch = new Cartesian3(); + var positionScratch = new Cartesian3(); - var cos = Math.cos; - var sin = Math.sin; /** - * A description of an ellipsoid centered at the origin. + * A description of a cylinder. * - * @alias EllipsoidGeometry + * @alias CylinderGeometry * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions. - * @param {Number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. - * @param {Number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. + * @param {Object} options Object with the following properties: + * @param {Number} options.length The length of the cylinder. + * @param {Number} options.topRadius The radius of the top of the cylinder. + * @param {Number} options.bottomRadius The radius of the bottom of the cylinder. + * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * - * @exception {DeveloperError} options.slicePartitions cannot be less than three. - * @exception {DeveloperError} options.stackPartitions cannot be less than three. + * @exception {DeveloperError} options.length must be greater than 0. + * @exception {DeveloperError} options.topRadius must be greater than 0. + * @exception {DeveloperError} options.bottomRadius must be greater than 0. + * @exception {DeveloperError} bottomRadius and topRadius cannot both equal 0. + * @exception {DeveloperError} options.slices must be greater than or equal to 3. * - * @see EllipsoidGeometry#createGeometry + * @see CylinderGeometry.createGeometry * * @example - * var ellipsoid = new Cesium.EllipsoidGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, - * radii : new Cesium.Cartesian3(1000000.0, 500000.0, 500000.0) + * // create cylinder geometry + * var cylinder = new Cesium.CylinderGeometry({ + * length: 200000, + * topRadius: 80000, + * bottomRadius: 200000, * }); - * var geometry = Cesium.EllipsoidGeometry.createGeometry(ellipsoid); + * var geometry = Cesium.CylinderGeometry.createGeometry(cylinder); */ - function EllipsoidGeometry(options) { + function CylinderGeometry(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var radii = defaultValue(options.radii, defaultRadii); - var stackPartitions = Math.round(defaultValue(options.stackPartitions, 64)); - var slicePartitions = Math.round(defaultValue(options.slicePartitions, 64)); + var length = options.length; + var topRadius = options.topRadius; + var bottomRadius = options.bottomRadius; var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + var slices = defaultValue(options.slices, 128); - if (slicePartitions < 3) { - throw new DeveloperError ('options.slicePartitions cannot be less than three.'); + if (!defined(length)) { + throw new DeveloperError('options.length must be defined.'); } - if (stackPartitions < 3) { - throw new DeveloperError('options.stackPartitions cannot be less than three.'); + if (!defined(topRadius)) { + throw new DeveloperError('options.topRadius must be defined.'); + } + if (!defined(bottomRadius)) { + throw new DeveloperError('options.bottomRadius must be defined.'); + } + if (slices < 3) { + throw new DeveloperError('options.slices must be greater than or equal to 3.'); } - this._radii = Cartesian3.clone(radii); - this._stackPartitions = stackPartitions; - this._slicePartitions = slicePartitions; + this._length = length; + this._topRadius = topRadius; + this._bottomRadius = bottomRadius; this._vertexFormat = VertexFormat.clone(vertexFormat); - this._workerName = 'createEllipsoidGeometry'; + this._slices = slices; + this._workerName = 'createCylinderGeometry'; } /** * The number of elements used to pack the object into an array. * @type {Number} */ - EllipsoidGeometry.packedLength = Cartesian3.packedLength + VertexFormat.packedLength + 2; + CylinderGeometry.packedLength = VertexFormat.packedLength + 4; /** * Stores the provided instance into the provided array. * - * @param {EllipsoidGeometry} value The value to pack. + * @param {CylinderGeometry} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - EllipsoidGeometry.pack = function(value, array, startingIndex) { + CylinderGeometry.pack = function(value, array, startingIndex) { if (!defined(value)) { throw new DeveloperError('value is required'); } @@ -49116,25 +48107,24 @@ define('Core/EllipsoidGeometry',[ startingIndex = defaultValue(startingIndex, 0); - Cartesian3.pack(value._radii, array, startingIndex); - startingIndex += Cartesian3.packedLength; - VertexFormat.pack(value._vertexFormat, array, startingIndex); startingIndex += VertexFormat.packedLength; - array[startingIndex++] = value._stackPartitions; - array[startingIndex] = value._slicePartitions; + array[startingIndex++] = value._length; + array[startingIndex++] = value._topRadius; + array[startingIndex++] = value._bottomRadius; + array[startingIndex] = value._slices; return array; }; - var scratchRadii = new Cartesian3(); var scratchVertexFormat = new VertexFormat(); var scratchOptions = { - radii : scratchRadii, vertexFormat : scratchVertexFormat, - stackPartitions : undefined, - slicePartitions : undefined + length : undefined, + topRadius : undefined, + bottomRadius : undefined, + slices : undefined }; /** @@ -49142,179 +48132,119 @@ define('Core/EllipsoidGeometry',[ * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {EllipsoidGeometry} [result] The object into which to store the result. - * @returns {EllipsoidGeometry} The modified result parameter or a new EllipsoidGeometry instance if one was not provided. + * @param {CylinderGeometry} [result] The object into which to store the result. + * @returns {CylinderGeometry} The modified result parameter or a new CylinderGeometry instance if one was not provided. */ - EllipsoidGeometry.unpack = function(array, startingIndex, result) { + CylinderGeometry.unpack = function(array, startingIndex, result) { if (!defined(array)) { throw new DeveloperError('array is required'); } startingIndex = defaultValue(startingIndex, 0); - var radii = Cartesian3.unpack(array, startingIndex, scratchRadii); - startingIndex += Cartesian3.packedLength; - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); startingIndex += VertexFormat.packedLength; - var stackPartitions = array[startingIndex++]; - var slicePartitions = array[startingIndex]; + var length = array[startingIndex++]; + var topRadius = array[startingIndex++]; + var bottomRadius = array[startingIndex++]; + var slices = array[startingIndex]; if (!defined(result)) { - scratchOptions.stackPartitions = stackPartitions; - scratchOptions.slicePartitions = slicePartitions; - return new EllipsoidGeometry(scratchOptions); + scratchOptions.length = length; + scratchOptions.topRadius = topRadius; + scratchOptions.bottomRadius = bottomRadius; + scratchOptions.slices = slices; + return new CylinderGeometry(scratchOptions); } - result._radii = Cartesian3.clone(radii, result._radii); result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._stackPartitions = stackPartitions; - result._slicePartitions = slicePartitions; + result._length = length; + result._topRadius = topRadius; + result._bottomRadius = bottomRadius; + result._slices = slices; return result; }; /** - * Computes the geometric representation of an ellipsoid, including its vertices, indices, and a bounding sphere. + * Computes the geometric representation of a cylinder, including its vertices, indices, and a bounding sphere. * - * @param {EllipsoidGeometry} ellipsoidGeometry A description of the ellipsoid. + * @param {CylinderGeometry} cylinderGeometry A description of the cylinder. * @returns {Geometry|undefined} The computed vertices and indices. */ - EllipsoidGeometry.createGeometry = function(ellipsoidGeometry) { - var radii = ellipsoidGeometry._radii; + CylinderGeometry.createGeometry = function(cylinderGeometry) { + var length = cylinderGeometry._length; + var topRadius = cylinderGeometry._topRadius; + var bottomRadius = cylinderGeometry._bottomRadius; + var vertexFormat = cylinderGeometry._vertexFormat; + var slices = cylinderGeometry._slices; - if ((radii.x <= 0) || (radii.y <= 0) || (radii.z <= 0)) { + if ((length <= 0) || (topRadius < 0) || (bottomRadius < 0) || ((topRadius === 0) && (bottomRadius === 0))) { return; } - var ellipsoid = Ellipsoid.fromCartesian3(radii); - var vertexFormat = ellipsoidGeometry._vertexFormat; - - // The extra slice and stack are for duplicating points at the x axis and poles. - // We need the texture coordinates to interpolate from (2 * pi - delta) to 2 * pi instead of - // (2 * pi - delta) to 0. - var slicePartitions = ellipsoidGeometry._slicePartitions + 1; - var stackPartitions = ellipsoidGeometry._stackPartitions + 1; - - var vertexCount = stackPartitions * slicePartitions; - var positions = new Float64Array(vertexCount * 3); - - var numIndices = 6 * (slicePartitions - 1) * (stackPartitions - 2); - var indices = IndexDatatype.createTypedArray(vertexCount, numIndices); + var twoSlices = slices + slices; + var threeSlices = slices + twoSlices; + var numVertices = twoSlices + twoSlices; - var normals = (vertexFormat.normal) ? new Float32Array(vertexCount * 3) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(vertexCount * 3) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(vertexCount * 3) : undefined; - var st = (vertexFormat.st) ? new Float32Array(vertexCount * 2) : undefined; + var positions = CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, true); - var cosTheta = new Array(slicePartitions); - var sinTheta = new Array(slicePartitions); + var st = (vertexFormat.st) ? new Float32Array(numVertices * 2) : undefined; + var normals = (vertexFormat.normal) ? new Float32Array(numVertices * 3) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(numVertices * 3) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(numVertices * 3) : undefined; var i; - var j; - var index = 0; - - for (i = 0; i < slicePartitions; i++) { - var theta = CesiumMath.TWO_PI * i / (slicePartitions - 1); - cosTheta[i] = cos(theta); - sinTheta[i] = sin(theta); - - // duplicate first point for correct - // texture coordinates at the north pole. - positions[index++] = 0.0; - positions[index++] = 0.0; - positions[index++] = radii.z; - } - - for (i = 1; i < stackPartitions - 1; i++) { - var phi = Math.PI * i / (stackPartitions - 1); - var sinPhi = sin(phi); - - var xSinPhi = radii.x * sinPhi; - var ySinPhi = radii.y * sinPhi; - var zCosPhi = radii.z * cos(phi); - - for (j = 0; j < slicePartitions; j++) { - positions[index++] = cosTheta[j] * xSinPhi; - positions[index++] = sinTheta[j] * ySinPhi; - positions[index++] = zCosPhi; - } - } - - for (i = 0; i < slicePartitions; i++) { - // duplicate first point for correct - // texture coordinates at the south pole. - positions[index++] = 0.0; - positions[index++] = 0.0; - positions[index++] = -radii.z; - } - - var attributes = new GeometryAttributes(); + var computeNormal = (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent); - if (vertexFormat.position) { - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - } + if (computeNormal) { + var computeTangent = (vertexFormat.tangent || vertexFormat.bitangent); - var stIndex = 0; - var normalIndex = 0; - var tangentIndex = 0; - var bitangentIndex = 0; + var normalIndex = 0; + var tangentIndex = 0; + var bitangentIndex = 0; - if (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - for( i = 0; i < vertexCount; i++) { - var position = Cartesian3.fromArray(positions, i * 3, scratchPosition); - var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal); + var normal = normalScratch; + normal.z = 0; + var tangent = tangentScratch; + var bitangent = bitangentScratch; - if (vertexFormat.st) { - var normalST = Cartesian2.negate(normal, scratchNormalST); + for (i = 0; i < slices; i++) { + var angle = i / slices * CesiumMath.TWO_PI; + var x = Math.cos(angle); + var y = Math.sin(angle); + if (computeNormal) { + normal.x = x; + normal.y = y; - // if the point is at or close to the pole, find a point along the same longitude - // close to the xy-plane for the s coordinate. - if (Cartesian2.magnitude(normalST) < CesiumMath.EPSILON6) { - index = (i + slicePartitions * Math.floor(stackPartitions * 0.5)) * 3; - if (index > positions.length) { - index = (i - slicePartitions * Math.floor(stackPartitions * 0.5)) * 3; - } - Cartesian3.fromArray(positions, index, normalST); - ellipsoid.geodeticSurfaceNormal(normalST, normalST); - Cartesian2.negate(normalST, normalST); + if (computeTangent) { + tangent = Cartesian3.normalize(Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent), tangent); } - st[stIndex++] = (Math.atan2(normalST.y, normalST.x) / CesiumMath.TWO_PI) + 0.5; - st[stIndex++] = (Math.asin(normal.z) / Math.PI) + 0.5; - } - - if (vertexFormat.normal) { - normals[normalIndex++] = normal.x; - normals[normalIndex++] = normal.y; - normals[normalIndex++] = normal.z; - } - - if (vertexFormat.tangent || vertexFormat.bitangent) { - var tangent = scratchTangent; - if (i < slicePartitions || i > vertexCount - slicePartitions - 1) { - Cartesian3.cross(Cartesian3.UNIT_X, normal, tangent); - Cartesian3.normalize(tangent, tangent); - } else { - Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent); - Cartesian3.normalize(tangent, tangent); + if (vertexFormat.normal) { + normals[normalIndex++] = x; + normals[normalIndex++] = y; + normals[normalIndex++] = 0; + normals[normalIndex++] = x; + normals[normalIndex++] = y; + normals[normalIndex++] = 0; } if (vertexFormat.tangent) { tangents[tangentIndex++] = tangent.x; tangents[tangentIndex++] = tangent.y; tangents[tangentIndex++] = tangent.z; + tangents[tangentIndex++] = tangent.x; + tangents[tangentIndex++] = tangent.y; + tangents[tangentIndex++] = tangent.z; } if (vertexFormat.bitangent) { - var bitangent = Cartesian3.cross(normal, tangent, scratchBitangent); - Cartesian3.normalize(bitangent, bitangent); - + bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); + bitangents[bitangentIndex++] = bitangent.x; + bitangents[bitangentIndex++] = bitangent.y; + bitangents[bitangentIndex++] = bitangent.z; bitangents[bitangentIndex++] = bitangent.x; bitangents[bitangentIndex++] = bitangent.y; bitangents[bitangentIndex++] = bitangent.z; @@ -49322,208 +48252,286 @@ define('Core/EllipsoidGeometry',[ } } - if (vertexFormat.st) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : st - }); - } - - if (vertexFormat.normal) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } - - if (vertexFormat.tangent) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); + for (i = 0; i < slices; i++) { + if (vertexFormat.normal) { + normals[normalIndex++] = 0; + normals[normalIndex++] = 0; + normals[normalIndex++] = -1; + } + if (vertexFormat.tangent) { + tangents[tangentIndex++] = 1; + tangents[tangentIndex++] = 0; + tangents[tangentIndex++] = 0; + } + if (vertexFormat.bitangent) { + bitangents[bitangentIndex++] = 0; + bitangents[bitangentIndex++] = -1; + bitangents[bitangentIndex++] = 0; + } } - if (vertexFormat.bitangent) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); + for (i = 0; i < slices; i++) { + if (vertexFormat.normal) { + normals[normalIndex++] = 0; + normals[normalIndex++] = 0; + normals[normalIndex++] = 1; + } + if (vertexFormat.tangent) { + tangents[tangentIndex++] = 1; + tangents[tangentIndex++] = 0; + tangents[tangentIndex++] = 0; + } + if (vertexFormat.bitangent) { + bitangents[bitangentIndex++] = 0; + bitangents[bitangentIndex++] = 1; + bitangents[bitangentIndex++] = 0; + } } } - index = 0; - for (j = 0; j < slicePartitions - 1; j++) { - indices[index++] = slicePartitions + j; - indices[index++] = slicePartitions + j + 1; + var numIndices = 12 * slices - 12; + var indices = IndexDatatype.createTypedArray(numVertices, numIndices); + var index = 0; + var j = 0; + for (i = 0; i < slices - 1; i++) { + indices[index++] = j; + indices[index++] = j + 2; + indices[index++] = j + 3; + + indices[index++] = j; + indices[index++] = j + 3; indices[index++] = j + 1; + + j += 2; } - var topOffset; - var bottomOffset; - for (i = 1; i < stackPartitions - 2; i++) { - topOffset = i * slicePartitions; - bottomOffset = (i + 1) * slicePartitions; + indices[index++] = twoSlices - 2; + indices[index++] = 0; + indices[index++] = 1; + indices[index++] = twoSlices - 2; + indices[index++] = 1; + indices[index++] = twoSlices - 1; - for (j = 0; j < slicePartitions - 1; j++) { - indices[index++] = bottomOffset + j; - indices[index++] = bottomOffset + j + 1; - indices[index++] = topOffset + j + 1; + for (i = 1; i < slices - 1; i++) { + indices[index++] = twoSlices + i + 1; + indices[index++] = twoSlices + i; + indices[index++] = twoSlices; + } - indices[index++] = bottomOffset + j; - indices[index++] = topOffset + j + 1; - indices[index++] = topOffset + j; + for (i = 1; i < slices - 1; i++) { + indices[index++] = threeSlices; + indices[index++] = threeSlices + i; + indices[index++] = threeSlices + i + 1; + } + + var textureCoordIndex = 0; + if (vertexFormat.st) { + var rad = Math.max(topRadius, bottomRadius); + for (i = 0; i < numVertices; i++) { + var position = Cartesian3.fromArray(positions, i * 3, positionScratch); + st[textureCoordIndex++] = (position.x + rad) / (2.0 * rad); + st[textureCoordIndex++] = (position.y + rad) / (2.0 * rad); } } - i = stackPartitions - 2; - topOffset = i * slicePartitions; - bottomOffset = (i + 1) * slicePartitions; + var attributes = new GeometryAttributes(); + if (vertexFormat.position) { + attributes.position = new GeometryAttribute({ + componentDatatype: ComponentDatatype.DOUBLE, + componentsPerAttribute: 3, + values: positions + }); + } - for (j = 0; j < slicePartitions - 1; j++) { - indices[index++] = bottomOffset + j; - indices[index++] = topOffset + j + 1; - indices[index++] = topOffset + j; + if (vertexFormat.normal) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); + } + + if (vertexFormat.tangent) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } + + if (vertexFormat.bitangent) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } + + if (vertexFormat.st) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : st + }); } + radiusScratch.x = length * 0.5; + radiusScratch.y = Math.max(bottomRadius, topRadius); + + var boundingSphere = new BoundingSphere(Cartesian3.ZERO, Cartesian2.magnitude(radiusScratch)); + return new Geometry({ attributes : attributes, indices : indices, primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : BoundingSphere.fromEllipsoid(ellipsoid) + boundingSphere : boundingSphere }); }; - return EllipsoidGeometry; + var unitCylinderGeometry; + + /** + * Returns the geometric representation of a unit cylinder, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private + */ + CylinderGeometry.getUnitCylinder = function() { + if (!defined(unitCylinderGeometry)) { + unitCylinderGeometry = CylinderGeometry.createGeometry(new CylinderGeometry({ + topRadius : 1.0, + bottomRadius : 1.0, + length : 1.0, + vertexFormat : VertexFormat.POSITION_ONLY + })); + } + return unitCylinderGeometry; + }; + + return CylinderGeometry; }); -define('Core/EllipsoidOutlineGeometry',[ + +define('Core/CylinderOutlineGeometry',[ './BoundingSphere', + './Cartesian2', './Cartesian3', + './Check', './ComponentDatatype', + './CylinderGeometryLibrary', './defaultValue', './defined', - './DeveloperError', - './Ellipsoid', './Geometry', './GeometryAttribute', './GeometryAttributes', './IndexDatatype', - './Math', './PrimitiveType' ], function( BoundingSphere, + Cartesian2, Cartesian3, + Check, ComponentDatatype, + CylinderGeometryLibrary, defaultValue, defined, - DeveloperError, - Ellipsoid, Geometry, GeometryAttribute, GeometryAttributes, IndexDatatype, - CesiumMath, PrimitiveType) { 'use strict'; - var defaultRadii = new Cartesian3(1.0, 1.0, 1.0); - var cos = Math.cos; - var sin = Math.sin; + var radiusScratch = new Cartesian2(); /** - * A description of the outline of an ellipsoid centered at the origin. + * A description of the outline of a cylinder. * - * @alias EllipsoidOutlineGeometry + * @alias CylinderOutlineGeometry * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions. - * @param {Number} [options.stackPartitions=10] The count of stacks for the ellipsoid (1 greater than the number of parallel lines). - * @param {Number} [options.slicePartitions=8] The count of slices for the ellipsoid (Equal to the number of radial lines). - * @param {Number} [options.subdivisions=128] The number of points per line, determining the granularity of the curvature. + * @param {Object} options Object with the following properties: + * @param {Number} options.length The length of the cylinder. + * @param {Number} options.topRadius The radius of the top of the cylinder. + * @param {Number} options.bottomRadius The radius of the bottom of the cylinder. + * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder. + * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surfaces of the cylinder. * - * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one. - * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero. - * @exception {DeveloperError} options.subdivisions must be greater than or equal to zero. + * @exception {DeveloperError} options.length must be greater than 0. + * @exception {DeveloperError} options.topRadius must be greater than 0. + * @exception {DeveloperError} options.bottomRadius must be greater than 0. + * @exception {DeveloperError} bottomRadius and topRadius cannot both equal 0. + * @exception {DeveloperError} options.slices must be greater than or equal to 3. + * + * @see CylinderOutlineGeometry.createGeometry * * @example - * var ellipsoid = new Cesium.EllipsoidOutlineGeometry({ - * radii : new Cesium.Cartesian3(1000000.0, 500000.0, 500000.0), - * stackPartitions: 6, - * slicePartitions: 5 + * // create cylinder geometry + * var cylinder = new Cesium.CylinderOutlineGeometry({ + * length: 200000, + * topRadius: 80000, + * bottomRadius: 200000, * }); - * var geometry = Cesium.EllipsoidOutlineGeometry.createGeometry(ellipsoid); + * var geometry = Cesium.CylinderOutlineGeometry.createGeometry(cylinder); */ - function EllipsoidOutlineGeometry(options) { + function CylinderOutlineGeometry(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var radii = defaultValue(options.radii, defaultRadii); - var stackPartitions = Math.round(defaultValue(options.stackPartitions, 10)); - var slicePartitions = Math.round(defaultValue(options.slicePartitions, 8)); - var subdivisions = Math.round(defaultValue(options.subdivisions, 128)); + var length = options.length; + var topRadius = options.topRadius; + var bottomRadius = options.bottomRadius; + var slices = defaultValue(options.slices, 128); + var numberOfVerticalLines = Math.max(defaultValue(options.numberOfVerticalLines, 16), 0); - if (stackPartitions < 1) { - throw new DeveloperError('options.stackPartitions cannot be less than 1'); - } - if (slicePartitions < 0) { - throw new DeveloperError('options.slicePartitions cannot be less than 0'); - } - if (subdivisions < 0) { - throw new DeveloperError('options.subdivisions must be greater than or equal to zero.'); - } + Check.typeOf.number('options.positions', length); + Check.typeOf.number('options.topRadius', topRadius); + Check.typeOf.number('options.bottomRadius', bottomRadius); + Check.typeOf.number.greaterThanOrEquals('options.slices', slices, 3); - this._radii = Cartesian3.clone(radii); - this._stackPartitions = stackPartitions; - this._slicePartitions = slicePartitions; - this._subdivisions = subdivisions; - this._workerName = 'createEllipsoidOutlineGeometry'; + this._length = length; + this._topRadius = topRadius; + this._bottomRadius = bottomRadius; + this._slices = slices; + this._numberOfVerticalLines = numberOfVerticalLines; + this._workerName = 'createCylinderOutlineGeometry'; } /** * The number of elements used to pack the object into an array. * @type {Number} */ - EllipsoidOutlineGeometry.packedLength = Cartesian3.packedLength + 3; + CylinderOutlineGeometry.packedLength = 5; /** * Stores the provided instance into the provided array. * - * @param {EllipsoidOutlineGeometry} value The value to pack. + * @param {CylinderOutlineGeometry} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - EllipsoidOutlineGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); - } + CylinderOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); startingIndex = defaultValue(startingIndex, 0); - Cartesian3.pack(value._radii, array, startingIndex); - startingIndex += Cartesian3.packedLength; - - array[startingIndex++] = value._stackPartitions; - array[startingIndex++] = value._slicePartitions; - array[startingIndex] = value._subdivisions; + array[startingIndex++] = value._length; + array[startingIndex++] = value._topRadius; + array[startingIndex++] = value._bottomRadius; + array[startingIndex++] = value._slices; + array[startingIndex] = value._numberOfVerticalLines; return array; }; - var scratchRadii = new Cartesian3(); var scratchOptions = { - radii : scratchRadii, - stackPartitions : undefined, - slicePartitions : undefined, - subdivisions : undefined + length : undefined, + topRadius : undefined, + bottomRadius : undefined, + slices : undefined, + numberOfVerticalLines : undefined }; /** @@ -49531,10714 +48539,8477 @@ define('Core/EllipsoidOutlineGeometry',[ * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {EllipsoidOutlineGeometry} [result] The object into which to store the result. - * @returns {EllipsoidOutlineGeometry} The modified result parameter or a new EllipsoidOutlineGeometry instance if one was not provided. + * @param {CylinderOutlineGeometry} [result] The object into which to store the result. + * @returns {CylinderOutlineGeometry} The modified result parameter or a new CylinderOutlineGeometry instance if one was not provided. */ - EllipsoidOutlineGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); - } + CylinderOutlineGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); startingIndex = defaultValue(startingIndex, 0); - var radii = Cartesian3.unpack(array, startingIndex, scratchRadii); - startingIndex += Cartesian3.packedLength; - - var stackPartitions = array[startingIndex++]; - var slicePartitions = array[startingIndex++]; - var subdivisions = array[startingIndex++]; + var length = array[startingIndex++]; + var topRadius = array[startingIndex++]; + var bottomRadius = array[startingIndex++]; + var slices = array[startingIndex++]; + var numberOfVerticalLines = array[startingIndex]; if (!defined(result)) { - scratchOptions.stackPartitions = stackPartitions; - scratchOptions.slicePartitions = slicePartitions; - scratchOptions.subdivisions = subdivisions; - return new EllipsoidOutlineGeometry(scratchOptions); + scratchOptions.length = length; + scratchOptions.topRadius = topRadius; + scratchOptions.bottomRadius = bottomRadius; + scratchOptions.slices = slices; + scratchOptions.numberOfVerticalLines = numberOfVerticalLines; + return new CylinderOutlineGeometry(scratchOptions); } - result._radii = Cartesian3.clone(radii, result._radii); - result._stackPartitions = stackPartitions; - result._slicePartitions = slicePartitions; - result._subdivisions = subdivisions; + result._length = length; + result._topRadius = topRadius; + result._bottomRadius = bottomRadius; + result._slices = slices; + result._numberOfVerticalLines = numberOfVerticalLines; return result; }; /** - * Computes the geometric representation of an outline of an ellipsoid, including its vertices, indices, and a bounding sphere. + * Computes the geometric representation of an outline of a cylinder, including its vertices, indices, and a bounding sphere. * - * @param {EllipsoidOutlineGeometry} ellipsoidGeometry A description of the ellipsoid outline. + * @param {CylinderOutlineGeometry} cylinderGeometry A description of the cylinder outline. * @returns {Geometry|undefined} The computed vertices and indices. */ - EllipsoidOutlineGeometry.createGeometry = function(ellipsoidGeometry) { - var radii = ellipsoidGeometry._radii; + CylinderOutlineGeometry.createGeometry = function(cylinderGeometry) { + var length = cylinderGeometry._length; + var topRadius = cylinderGeometry._topRadius; + var bottomRadius = cylinderGeometry._bottomRadius; + var slices = cylinderGeometry._slices; + var numberOfVerticalLines = cylinderGeometry._numberOfVerticalLines; - if ((radii.x <= 0) || (radii.y <= 0) || (radii.z <= 0)) { + if ((length <= 0) || (topRadius < 0) || (bottomRadius < 0) || ((topRadius === 0) && (bottomRadius === 0))) { return; } - var ellipsoid = Ellipsoid.fromCartesian3(radii); - var stackPartitions = ellipsoidGeometry._stackPartitions; - var slicePartitions = ellipsoidGeometry._slicePartitions; - var subdivisions = ellipsoidGeometry._subdivisions; - - var indicesSize = subdivisions * (stackPartitions + slicePartitions - 1); - var positionSize = indicesSize - slicePartitions + 2; - var positions = new Float64Array(positionSize * 3); - var indices = IndexDatatype.createTypedArray(positionSize, indicesSize * 2); - - var i; - var j; - var theta; - var phi; - var cosPhi; - var sinPhi; - var index = 0; - - var cosTheta = new Array(subdivisions); - var sinTheta = new Array(subdivisions); - for (i = 0; i < subdivisions; i++) { - theta = CesiumMath.TWO_PI * i / subdivisions; - cosTheta[i] = cos(theta); - sinTheta[i] = sin(theta); - } - - for (i = 1; i < stackPartitions; i++) { - phi = Math.PI * i / stackPartitions; - cosPhi = cos(phi); - sinPhi = sin(phi); - - for (j = 0; j < subdivisions; j++) { - positions[index++] = radii.x * cosTheta[j] * sinPhi; - positions[index++] = radii.y * sinTheta[j] * sinPhi; - positions[index++] = radii.z * cosPhi; - } - } + var numVertices = slices * 2; - cosTheta.length = slicePartitions; - sinTheta.length = slicePartitions; - for (i = 0; i < slicePartitions; i++) { - theta = CesiumMath.TWO_PI * i / slicePartitions; - cosTheta[i] = cos(theta); - sinTheta[i] = sin(theta); + var positions = CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, false); + var numIndices = slices * 2; + var numSide; + if (numberOfVerticalLines > 0) { + var numSideLines = Math.min(numberOfVerticalLines, slices); + numSide = Math.round(slices / numSideLines); + numIndices += numSideLines; } - positions[index++] = 0; - positions[index++] = 0; - positions[index++] = radii.z; - - for (i = 1; i < subdivisions; i++) { - phi = Math.PI * i / subdivisions; - cosPhi = cos(phi); - sinPhi = sin(phi); - - for (j = 0; j < slicePartitions; j++) { - positions[index++] = radii.x * cosTheta[j] * sinPhi; - positions[index++] = radii.y * sinTheta[j] * sinPhi; - positions[index++] = radii.z * cosPhi; - } + var indices = IndexDatatype.createTypedArray(numVertices, numIndices * 2); + var index = 0; + var i; + for (i = 0; i < slices - 1; i++) { + indices[index++] = i; + indices[index++] = i + 1; + indices[index++] = i + slices; + indices[index++] = i + 1 + slices; } - positions[index++] = 0; - positions[index++] = 0; - positions[index++] = -radii.z; + indices[index++] = slices - 1; + indices[index++] = 0; + indices[index++] = slices + slices - 1; + indices[index++] = slices; - index = 0; - for (i = 0; i < stackPartitions - 1; ++i) { - var topRowOffset = (i * subdivisions); - for (j = 0; j < subdivisions - 1; ++j) { - indices[index++] = topRowOffset + j; - indices[index++] = topRowOffset + j + 1; + if (numberOfVerticalLines > 0) { + for (i = 0; i < slices; i += numSide) { + indices[index++] = i; + indices[index++] = i + slices; } - - indices[index++] = topRowOffset + subdivisions - 1; - indices[index++] = topRowOffset; - } - - var sliceOffset = subdivisions * (stackPartitions - 1); - for (j = 1; j < slicePartitions + 1; ++j) { - indices[index++] = sliceOffset; - indices[index++] = sliceOffset + j; } - for (i = 0; i < subdivisions - 2; ++i) { - var topOffset = (i * slicePartitions) + 1 + sliceOffset; - var bottomOffset = ((i + 1) * slicePartitions) + 1 + sliceOffset; - - for (j = 0; j < slicePartitions - 1; ++j) { - indices[index++] = bottomOffset + j; - indices[index++] = topOffset + j; - } - - indices[index++] = bottomOffset + slicePartitions - 1; - indices[index++] = topOffset + slicePartitions - 1; - } + var attributes = new GeometryAttributes(); + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); - var lastPosition = positions.length / 3 - 1; - for (j = lastPosition - 1; j > lastPosition - slicePartitions - 1; --j) { - indices[index++] = lastPosition; - indices[index++] = j; - } + radiusScratch.x = length * 0.5; + radiusScratch.y = Math.max(bottomRadius, topRadius); - var attributes = new GeometryAttributes({ - position: new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }) - }); + var boundingSphere = new BoundingSphere(Cartesian3.ZERO, Cartesian2.magnitude(radiusScratch)); return new Geometry({ attributes : attributes, indices : indices, primitiveType : PrimitiveType.LINES, - boundingSphere : BoundingSphere.fromEllipsoid(ellipsoid) + boundingSphere : boundingSphere }); }; - return EllipsoidOutlineGeometry; + return CylinderOutlineGeometry; }); -define('Core/EllipsoidTerrainProvider',[ - '../ThirdParty/when', - './defaultValue', - './defined', - './defineProperties', - './Ellipsoid', - './Event', - './GeographicTilingScheme', - './HeightmapTerrainData', - './TerrainProvider' +define('Core/decodeGoogleEarthEnterpriseData',[ + './Check', + './RuntimeError' ], function( - when, - defaultValue, - defined, - defineProperties, - Ellipsoid, - Event, - GeographicTilingScheme, - HeightmapTerrainData, - TerrainProvider) { + Check, + RuntimeError) { 'use strict'; + var compressedMagic = 0x7468dead; + var compressedMagicSwap = 0xadde6874; + /** - * A very simple {@link TerrainProvider} that produces geometry by tessellating an ellipsoidal - * surface. - * - * @alias EllipsoidTerrainProvider - * @constructor + * Decodes data that is received from the Google Earth Enterprise server. * - * @param {Object} [options] Object with the following properties: - * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal - * surface is broken into tiles. If this parameter is not provided, a {@link GeographicTilingScheme} - * is used. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. + * @param {ArrayBuffer} key The key used during decoding. + * @param {ArrayBuffer} data The data to be decoded. * - * @see TerrainProvider + * @private */ - function EllipsoidTerrainProvider(options) { - options = defaultValue(options, {}); - - this._tilingScheme = options.tilingScheme; - if (!defined(this._tilingScheme)) { - this._tilingScheme = new GeographicTilingScheme({ - ellipsoid : defaultValue(options.ellipsoid, Ellipsoid.WGS84) - }); + function decodeGoogleEarthEnterpriseData(key, data) { + if (decodeGoogleEarthEnterpriseData.passThroughDataForTesting) { + return data; } - // Note: the 64 below does NOT need to match the actual vertex dimensions, because - // the ellipsoid is significantly smoother than actual terrain. - this._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid, 64, this._tilingScheme.getNumberOfXTilesAtLevel(0)); + Check.typeOf.object('key', key); + Check.typeOf.object('data', data); + + var keyLength = key.byteLength; + if (keyLength === 0 || (keyLength % 4) !== 0) { + throw new RuntimeError('The length of key must be greater than 0 and a multiple of 4.'); + } - this._errorEvent = new Event(); - this._readyPromise = when.resolve(true); - } + var dataView = new DataView(data); + var magic = dataView.getUint32(0, true); + if (magic === compressedMagic || magic === compressedMagicSwap) { + // Occasionally packets don't come back encoded, so just return + return data; + } - defineProperties(EllipsoidTerrainProvider.prototype, { - /** - * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof EllipsoidTerrainProvider.prototype - * @type {Event} - */ - errorEvent : { - get : function() { - return this._errorEvent; - } - }, + var keyView = new DataView(key); - /** - * Gets the credit to display when this terrain provider is active. Typically this is used to credit - * the source of the terrain. This function should not be called before {@link EllipsoidTerrainProvider#ready} returns true. - * @memberof EllipsoidTerrainProvider.prototype - * @type {Credit} - */ - credit : { - get : function() { - return undefined; - } - }, + var dp = 0; + var dpend = data.byteLength; + var dpend64 = dpend - (dpend % 8); + var kpend = keyLength; + var kp; + var off = 8; - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link EllipsoidTerrainProvider#ready} returns true. - * @memberof EllipsoidTerrainProvider.prototype - * @type {GeographicTilingScheme} - */ - tilingScheme : { - get : function() { - return this._tilingScheme; - } - }, + // This algorithm is intentionally asymmetric to make it more difficult to + // guess. Security through obscurity. :-( - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof EllipsoidTerrainProvider.prototype - * @type {Boolean} - */ - ready : { - get : function() { - return true; - } - }, + // while we have a full uint64 (8 bytes) left to do + // assumes buffer is 64bit aligned (or processor doesn't care) + while (dp < dpend64) { + // rotate the key each time through by using the offets 16,0,8,16,0,8,... + off = (off + 8) % 24; + kp = off; - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof EllipsoidTerrainProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise; + // run through one key length xor'ing one uint64 at a time + // then drop out to rotate the key for the next bit + while ((dp < dpend64) && (kp < kpend)) { + dataView.setUint32(dp, dataView.getUint32(dp, true) ^ keyView.getUint32(kp, true), true); + dataView.setUint32(dp + 4, dataView.getUint32(dp + 4, true) ^ keyView.getUint32(kp + 4, true), true); + dp += 8; + kp += 24; } - }, + } - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. This function should not be - * called before {@link EllipsoidTerrainProvider#ready} returns true. - * @memberof EllipsoidTerrainProvider.prototype - * @type {Boolean} - */ - hasWaterMask : { - get : function() { - return false; + // now the remaining 1 to 7 bytes + if (dp < dpend) { + if (kp >= kpend) { + // rotate the key one last time (if necessary) + off = (off + 8) % 24; + kp = off; } - }, - /** - * Gets a value indicating whether or not the requested tiles include vertex normals. - * This function should not be called before {@link EllipsoidTerrainProvider#ready} returns true. - * @memberof EllipsoidTerrainProvider.prototype - * @type {Boolean} - */ - hasVertexNormals : { - get : function() { - return false; + while (dp < dpend) { + dataView.setUint8(dp, dataView.getUint8(dp) ^ keyView.getUint8(kp)); + dp++; + kp++; } } - }); + } - /** - * Requests the geometry for a given tile. This function should not be called before - * {@link TerrainProvider#ready} returns true. The result includes terrain - * data and indicates that all child tiles are available. - * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @param {Request} [request] The request object. Intended for internal use only. - * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method - * returns undefined instead of a promise, it is an indication that too many requests are already - * pending and the request will be retried later. - */ - EllipsoidTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { - var width = 16; - var height = 16; - return new HeightmapTerrainData({ - buffer : new Uint8Array(width * height), - width : width, - height : height - }); - }; + decodeGoogleEarthEnterpriseData.passThroughDataForTesting = false; + + return decodeGoogleEarthEnterpriseData; +}); + +define('Core/DefaultProxy',[],function() { + 'use strict'; /** - * Gets the maximum geometric error allowed in a tile at a given level. + * A simple proxy that appends the desired resource as the sole query parameter + * to the given proxy URL. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @alias DefaultProxy + * @constructor + * + * @param {String} proxy The proxy URL that will be used to requests all resources. */ - EllipsoidTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { - return this._levelZeroMaximumGeometricError / (1 << level); - }; + function DefaultProxy(proxy) { + this.proxy = proxy; + } /** - * Determines whether data for a tile is available to be loaded. + * Get the final URL to use to request a given resource. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean} Undefined if not supported, otherwise true or false. + * @param {String} resource The resource to request. + * @returns {String} proxied resource */ - EllipsoidTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { - return undefined; + DefaultProxy.prototype.getURL = function(resource) { + var prefix = this.proxy.indexOf('?') === -1 ? '?' : ''; + return this.proxy + prefix + encodeURIComponent(resource); }; - return EllipsoidTerrainProvider; + return DefaultProxy; }); -define('Core/EventHelper',[ +define('Core/DistanceDisplayCondition',[ + './defaultValue', './defined', + './defineProperties', './DeveloperError' ], function( + defaultValue, defined, + defineProperties, DeveloperError) { 'use strict'; /** - * A convenience object that simplifies the common pattern of attaching event listeners - * to several events, then removing all those listeners at once later, for example, in - * a destroy method. + * Determines visibility based on the distance to the camera. * - * @alias EventHelper + * @alias DistanceDisplayCondition * @constructor * + * @param {Number} [near=0.0] The smallest distance in the interval where the object is visible. + * @param {Number} [far=Number.MAX_VALUE] The largest distance in the interval where the object is visible. * * @example - * var helper = new Cesium.EventHelper(); - * - * helper.add(someObject.event, listener1, this); - * helper.add(otherObject.event, listener2, this); - * - * // later... - * helper.removeAll(); - * - * @see Event + * // Make a billboard that is only visible when the distance to the camera is between 10 and 20 meters. + * billboard.distanceDisplayCondition = new DistanceDisplayCondition(10.0 20.0); */ - function EventHelper() { - this._removalFunctions = []; + function DistanceDisplayCondition(near, far) { + near = defaultValue(near, 0.0); + this._near = near; + + far = defaultValue(far, Number.MAX_VALUE); + this._far = far; } + defineProperties(DistanceDisplayCondition.prototype, { + /** + * The smallest distance in the interval where the object is visible. + * @memberof DistanceDisplayCondition.prototype + * @type {Number} + * @default 0.0 + */ + near: { + get: function() { + return this._near; + }, + set: function(value) { + this._near = value; + } + }, + /** + * The largest distance in the interval where the object is visible. + * @memberof DistanceDisplayCondition.prototype + * @type {Number} + * @default Number.MAX_VALUE + */ + far: { + get: function() { + return this._far; + }, + set: function(value) { + this._far = value; + } + } + }); + /** - * Adds a listener to an event, and records the registration to be cleaned up later. + * The number of elements used to pack the object into an array. + * @type {Number} + */ + DistanceDisplayCondition.packedLength = 2; + + /** + * Stores the provided instance into the provided array. * - * @param {Event} event The event to attach to. - * @param {Function} listener The function to be executed when the event is raised. - * @param {Object} [scope] An optional object scope to serve as the <code>this</code> - * pointer in which the listener function will execute. - * @returns {EventHelper~RemoveCallback} A function that will remove this event listener when invoked. + * @param {DistanceDisplayCondition} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @see Event#addEventListener + * @returns {Number[]} The array that was packed into */ - EventHelper.prototype.add = function(event, listener, scope) { - if (!defined(event)) { - throw new DeveloperError('event is required'); + DistanceDisplayCondition.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); } - var removalFunction = event.addEventListener(listener, scope); - this._removalFunctions.push(removalFunction); + startingIndex = defaultValue(startingIndex, 0); - var that = this; - return function() { - removalFunction(); - var removalFunctions = that._removalFunctions; - removalFunctions.splice(removalFunctions.indexOf(removalFunction), 1); - }; + array[startingIndex++] = value.near; + array[startingIndex] = value.far; + + return array; }; /** - * Unregisters all previously added listeners. + * Retrieves an instance from a packed array. * - * @see Event#removeEventListener + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {DistanceDisplayCondition} [result] The object into which to store the result. + * @returns {DistanceDisplayCondition} The modified result parameter or a new DistanceDisplayCondition instance if one was not provided. */ - EventHelper.prototype.removeAll = function() { - var removalFunctions = this._removalFunctions; - for (var i = 0, len = removalFunctions.length; i < len; ++i) { - removalFunctions[i](); + DistanceDisplayCondition.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); } - removalFunctions.length = 0; + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new DistanceDisplayCondition(); + } + result.near = array[startingIndex++]; + result.far = array[startingIndex]; + return result; }; /** - * A function that removes a listener. - * @callback EventHelper~RemoveCallback + * Determines if two distance display conditions are equal. + * + * @param {DistanceDisplayCondition} left A distance display condition. + * @param {DistanceDisplayCondition} right Another distance display condition. + * @return {Boolean} Whether the two distance display conditions are equal. */ + DistanceDisplayCondition.equals = function(left, right) { + return left === right || + (defined(left) && + defined(right) && + left.near === right.near && + left.far === right.far); + }; - return EventHelper; -}); + /** + * Duplicates a distance display condition instance. + * + * @param {DistanceDisplayCondition} [value] The distance display condition to duplicate. + * @param {DistanceDisplayCondition} [result] The result onto which to store the result. + * @return {DistanceDisplayCondition} The duplicated instance. + */ + DistanceDisplayCondition.clone = function(value, result) { + if (!defined(value)) { + return undefined; + } -define('Core/ExtrapolationType',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + if (!defined(result)) { + result = new DistanceDisplayCondition(); + } + + result.near = value.near; + result.far = value.far; + return result; + }; /** - * Constants to determine how an interpolated value is extrapolated - * when querying outside the bounds of available data. - * - * @exports ExtrapolationType + * Duplicates this instance. * - * @see SampledProperty + * @param {DistanceDisplayCondition} [result] The result onto which to store the result. + * @return {DistanceDisplayCondition} The duplicated instance. */ - var ExtrapolationType = { - /** - * No extrapolation occurs. - * - * @type {Number} - * @constant - */ - NONE : 0, - - /** - * The first or last value is used when outside the range of sample data. - * - * @type {Number} - * @constant - */ - HOLD : 1, + DistanceDisplayCondition.prototype.clone = function(result) { + return DistanceDisplayCondition.clone(this, result); + }; - /** - * The value is extrapolated. - * - * @type {Number} - * @constant - */ - EXTRAPOLATE : 2 + /** + * Determines if this distance display condition is equal to another. + * + * @param {DistanceDisplayCondition} other Another distance display condition. + * @return {Boolean} Whether this distance display condition is equal to the other. + */ + DistanceDisplayCondition.prototype.equals = function(other) { + return DistanceDisplayCondition.equals(this, other); }; - return freezeObject(ExtrapolationType); + return DistanceDisplayCondition; }); -define('Core/OrthographicOffCenterFrustum',[ - './Cartesian3', - './Cartesian4', - './CullingVolume', +define('Core/DistanceDisplayConditionGeometryInstanceAttribute',[ + './ComponentDatatype', './defaultValue', './defined', './defineProperties', - './DeveloperError', - './Matrix4' + './DeveloperError' ], function( - Cartesian3, - Cartesian4, - CullingVolume, + ComponentDatatype, defaultValue, defined, defineProperties, - DeveloperError, - Matrix4) { + DeveloperError) { 'use strict'; /** - * The viewing frustum is defined by 6 planes. - * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components - * define the unit vector normal to the plane, and the w component is the distance of the - * plane from the origin/camera position. + * Value and type information for per-instance geometry attribute that determines if the geometry instance has a distance display condition. * - * @alias OrthographicOffCenterFrustum + * @alias DistanceDisplayConditionGeometryInstanceAttribute * @constructor * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.left] The left clipping plane distance. - * @param {Number} [options.right] The right clipping plane distance. - * @param {Number} [options.top] The top clipping plane distance. - * @param {Number} [options.bottom] The bottom clipping plane distance. - * @param {Number} [options.near=1.0] The near clipping plane distance. - * @param {Number} [options.far=500000000.0] The far clipping plane distance. + * @param {Number} [near=0.0] The near distance. + * @param {Number} [far=Number.MAX_VALUE] The far distance. + * + * @exception {DeveloperError} far must be greater than near. * * @example - * var maxRadii = ellipsoid.maximumRadius; + * var instance = new Cesium.GeometryInstance({ + * geometry : new Cesium.BoxGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL, + * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0), + * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0) + * }), + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), + * id : 'box', + * attributes : { + * show : new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(100.0, 10000.0) + * } + * }); * - * var frustum = new Cesium.OrthographicOffCenterFrustum(); - * frustum.right = maxRadii * Cesium.Math.PI; - * frustum.left = -c.frustum.right; - * frustum.top = c.frustum.right * (canvas.clientHeight / canvas.clientWidth); - * frustum.bottom = -c.frustum.top; - * frustum.near = 0.01 * maxRadii; - * frustum.far = 50.0 * maxRadii; + * @see GeometryInstance + * @see GeometryInstanceAttribute */ - function OrthographicOffCenterFrustum(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function DistanceDisplayConditionGeometryInstanceAttribute(near, far) { + near = defaultValue(near, 0.0); + far = defaultValue(far, Number.MAX_VALUE); + if (far <= near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + /** - * The left clipping plane. - * @type {Number} - * @default undefined + * The values for the attributes stored in a typed array. + * + * @type Float32Array + * + * @default [0.0, 0.0, Number.MAX_VALUE] */ - this.left = options.left; - this._left = undefined; + this.value = new Float32Array([near, far]); + } + defineProperties(DistanceDisplayConditionGeometryInstanceAttribute.prototype, { /** - * The right clipping plane. - * @type {Number} - * @default undefined + * The datatype of each component in the attribute, e.g., individual elements in + * {@link DistanceDisplayConditionGeometryInstanceAttribute#value}. + * + * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype + * + * @type {ComponentDatatype} + * @readonly + * + * @default {@link ComponentDatatype.FLOAT} */ - this.right = options.right; - this._right = undefined; - - /** - * The top clipping plane. - * @type {Number} - * @default undefined - */ - this.top = options.top; - this._top = undefined; - - /** - * The bottom clipping plane. - * @type {Number} - * @default undefined - */ - this.bottom = options.bottom; - this._bottom = undefined; - - /** - * The distance of the near plane. - * @type {Number} - * @default 1.0 - */ - this.near = defaultValue(options.near, 1.0); - this._near = this.near; + componentDatatype : { + get : function() { + return ComponentDatatype.FLOAT; + } + }, /** - * The distance of the far plane. + * The number of components in the attributes, i.e., {@link DistanceDisplayConditionGeometryInstanceAttribute#value}. + * + * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype + * * @type {Number} - * @default 500000000.0; + * @readonly + * + * @default 3 */ - this.far = defaultValue(options.far, 500000000.0); - this._far = this.far; - - this._cullingVolume = new CullingVolume(); - this._orthographicMatrix = new Matrix4(); - } - - function update(frustum) { - if (!defined(frustum.right) || !defined(frustum.left) || - !defined(frustum.top) || !defined(frustum.bottom) || - !defined(frustum.near) || !defined(frustum.far)) { - throw new DeveloperError('right, left, top, bottom, near, or far parameters are not set.'); - } - - if (frustum.top !== frustum._top || frustum.bottom !== frustum._bottom || - frustum.left !== frustum._left || frustum.right !== frustum._right || - frustum.near !== frustum._near || frustum.far !== frustum._far) { - - if (frustum.left > frustum.right) { - throw new DeveloperError('right must be greater than left.'); - } - if (frustum.bottom > frustum.top) { - throw new DeveloperError('top must be greater than bottom.'); - } - if (frustum.near <= 0 || frustum.near > frustum.far) { - throw new DeveloperError('near must be greater than zero and less than far.'); + componentsPerAttribute : { + get : function() { + return 2; } - - frustum._left = frustum.left; - frustum._right = frustum.right; - frustum._top = frustum.top; - frustum._bottom = frustum.bottom; - frustum._near = frustum.near; - frustum._far = frustum.far; - frustum._orthographicMatrix = Matrix4.computeOrthographicOffCenter(frustum.left, frustum.right, frustum.bottom, frustum.top, frustum.near, frustum.far, frustum._orthographicMatrix); - } - } + }, - defineProperties(OrthographicOffCenterFrustum.prototype, { /** - * Gets the orthographic projection matrix computed from the view frustum. - * @memberof OrthographicOffCenterFrustum.prototype - * @type {Matrix4} + * When <code>true</code> and <code>componentDatatype</code> is an integer format, + * indicate that the components should be mapped to the range [0, 1] (unsigned) + * or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * + * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype + * + * @type {Boolean} * @readonly + * + * @default false */ - projectionMatrix : { + normalize : { get : function() { - update(this); - return this._orthographicMatrix; + return false; } } }); - var getPlanesRight = new Cartesian3(); - var getPlanesNearCenter = new Cartesian3(); - var getPlanesPoint = new Cartesian3(); - var negateScratch = new Cartesian3(); - /** - * Creates a culling volume for this frustum. + * Creates a new {@link DistanceDisplayConditionGeometryInstanceAttribute} instance given the provided an enabled flag and {@link DistanceDisplayCondition}. * - * @param {Cartesian3} position The eye position. - * @param {Cartesian3} direction The view direction. - * @param {Cartesian3} up The up direction. - * @returns {CullingVolume} A culling volume at the given position and orientation. + * @param {DistanceDisplayCondition} distanceDisplayCondition The distance display condition. + * @returns {DistanceDisplayConditionGeometryInstanceAttribute} The new {@link DistanceDisplayConditionGeometryInstanceAttribute} instance. + * + * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near * * @example - * // Check if a bounding volume intersects the frustum. - * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); - * var intersect = cullingVolume.computeVisibility(boundingVolume); + * var instance = new Cesium.GeometryInstance({ + * geometry : geometry, + * attributes : { + * color : Cesium.DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition), + * } + * }); */ - OrthographicOffCenterFrustum.prototype.computeCullingVolume = function(position, direction, up) { - if (!defined(position)) { - throw new DeveloperError('position is required.'); + DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition = function(distanceDisplayCondition) { + if (!defined(distanceDisplayCondition)) { + throw new DeveloperError('distanceDisplayCondition is required.'); } - if (!defined(direction)) { - throw new DeveloperError('direction is required.'); + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far distance must be greater than distanceDisplayCondition.near distance.'); } - if (!defined(up)) { - throw new DeveloperError('up is required.'); + + return new DistanceDisplayConditionGeometryInstanceAttribute(distanceDisplayCondition.near, distanceDisplayCondition.far); + }; + + /** + * Converts a distance display condition to a typed array that can be used to assign a distance display condition attribute. + * + * @param {DistanceDisplayCondition} distanceDisplayCondition The distance display condition value. + * @param {Float32Array} [result] The array to store the result in, if undefined a new instance will be created. + * @returns {Float32Array} The modified result parameter or a new instance if result was undefined. + * + * @example + * var attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.distanceDisplayCondition = Cesium.DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); + */ + DistanceDisplayConditionGeometryInstanceAttribute.toValue = function(distanceDisplayCondition, result) { + if (!defined(distanceDisplayCondition)) { + throw new DeveloperError('distanceDisplayCondition is required.'); } - var planes = this._cullingVolume.planes; - var t = this.top; - var b = this.bottom; - var r = this.right; - var l = this.left; - var n = this.near; - var f = this.far; + if (!defined(result)) { + return new Float32Array([distanceDisplayCondition.near, distanceDisplayCondition.far]); + } + result[0] = distanceDisplayCondition.near; + result[1] = distanceDisplayCondition.far; + return result; + }; - var right = Cartesian3.cross(direction, up, getPlanesRight); - Cartesian3.normalize(right, right); - var nearCenter = getPlanesNearCenter; - Cartesian3.multiplyByScalar(direction, n, nearCenter); - Cartesian3.add(position, nearCenter, nearCenter); + return DistanceDisplayConditionGeometryInstanceAttribute; +}); - var point = getPlanesPoint; +define('Core/DoublyLinkedList',[ + '../Core/defined', + '../Core/defineProperties' + ], function( + defined, + defineProperties) { + 'use strict'; - // Left plane - Cartesian3.multiplyByScalar(right, l, point); - Cartesian3.add(nearCenter, point, point); + /** + * @private + */ + function DoublyLinkedList() { + this.head = undefined; + this.tail = undefined; + this._length = 0; + } - var plane = planes[0]; - if (!defined(plane)) { - plane = planes[0] = new Cartesian4(); + defineProperties(DoublyLinkedList.prototype, { + length : { + get : function() { + return this._length; + } } - plane.x = right.x; - plane.y = right.y; - plane.z = right.z; - plane.w = -Cartesian3.dot(right, point); + }); - // Right plane - Cartesian3.multiplyByScalar(right, r, point); - Cartesian3.add(nearCenter, point, point); + function DoublyLinkedListNode(item, previous, next) { + this.item = item; + this.previous = previous; + this.next = next; + } - plane = planes[1]; - if (!defined(plane)) { - plane = planes[1] = new Cartesian4(); + DoublyLinkedList.prototype.add = function(item) { + var node = new DoublyLinkedListNode(item, this.tail, undefined); + + if (defined(this.tail)) { + this.tail.next = node; + this.tail = node; + } else { + // Insert into empty linked list + this.head = node; + this.tail = node; } - plane.x = -right.x; - plane.y = -right.y; - plane.z = -right.z; - plane.w = -Cartesian3.dot(Cartesian3.negate(right, negateScratch), point); - // Bottom plane - Cartesian3.multiplyByScalar(up, b, point); - Cartesian3.add(nearCenter, point, point); + ++this._length; - plane = planes[2]; - if (!defined(plane)) { - plane = planes[2] = new Cartesian4(); + return node; + }; + + function remove(list, node) { + if (defined(node.previous) && defined(node.next)) { + node.previous.next = node.next; + node.next.previous = node.previous; + } else if (defined(node.previous)) { + // Remove last node + node.previous.next = undefined; + list.tail = node.previous; + } else if (defined(node.next)) { + // Remove first node + node.next.previous = undefined; + list.head = node.next; + } else { + // Remove last node in the linked list + list.head = undefined; + list.tail = undefined; } - plane.x = up.x; - plane.y = up.y; - plane.z = up.z; - plane.w = -Cartesian3.dot(up, point); - // Top plane - Cartesian3.multiplyByScalar(up, t, point); - Cartesian3.add(nearCenter, point, point); + node.next = undefined; + node.previous = undefined; + } - plane = planes[3]; - if (!defined(plane)) { - plane = planes[3] = new Cartesian4(); + DoublyLinkedList.prototype.remove = function(node) { + if (!defined(node)) { + return; } - plane.x = -up.x; - plane.y = -up.y; - plane.z = -up.z; - plane.w = -Cartesian3.dot(Cartesian3.negate(up, negateScratch), point); - // Near plane - plane = planes[4]; - if (!defined(plane)) { - plane = planes[4] = new Cartesian4(); - } - plane.x = direction.x; - plane.y = direction.y; - plane.z = direction.z; - plane.w = -Cartesian3.dot(direction, nearCenter); + remove(this, node); - // Far plane - Cartesian3.multiplyByScalar(direction, f, point); - Cartesian3.add(position, point, point); + --this._length; + }; - plane = planes[5]; - if (!defined(plane)) { - plane = planes[5] = new Cartesian4(); + DoublyLinkedList.prototype.splice = function(node, nextNode) { + if (node === nextNode) { + return; } - plane.x = -direction.x; - plane.y = -direction.y; - plane.z = -direction.z; - plane.w = -Cartesian3.dot(Cartesian3.negate(direction, negateScratch), point); - return this._cullingVolume; - }; + // Remove nextNode, then insert after node + remove(this, nextNode); - /** - * Returns the pixel's width and height in meters. - * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. - * - * @exception {DeveloperError} drawingBufferWidth must be greater than zero. - * @exception {DeveloperError} drawingBufferHeight must be greater than zero. - * - * @example - * // Example 1 - * // Get the width and height of a pixel. - * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 0.0, new Cesium.Cartesian2()); - */ - OrthographicOffCenterFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { - update(this); + var oldNodeNext = node.next; + node.next = nextNode; - if (!defined(drawingBufferWidth) || !defined(drawingBufferHeight)) { - throw new DeveloperError('Both drawingBufferWidth and drawingBufferHeight are required.'); - } - if (drawingBufferWidth <= 0) { - throw new DeveloperError('drawingBufferWidth must be greater than zero.'); - } - if (drawingBufferHeight <= 0) { - throw new DeveloperError('drawingBufferHeight must be greater than zero.'); - } - if (!defined(distance)) { - throw new DeveloperError('distance is required.'); - } - if (!defined(result)) { - throw new DeveloperError('A result object is required.'); + // nextNode is the new tail + if (this.tail === node) { + this.tail = nextNode; + } else { + oldNodeNext.previous = nextNode; } - - var frustumWidth = this.right - this.left; - var frustumHeight = this.top - this.bottom; - var pixelWidth = frustumWidth / drawingBufferWidth; - var pixelHeight = frustumHeight / drawingBufferHeight; - result.x = pixelWidth; - result.y = pixelHeight; - return result; + nextNode.next = oldNodeNext; + nextNode.previous = node; }; - /** - * Returns a duplicate of a OrthographicOffCenterFrustum instance. - * - * @param {OrthographicOffCenterFrustum} [result] The object onto which to store the result. - * @returns {OrthographicOffCenterFrustum} The modified result parameter or a new OrthographicOffCenterFrustum instance if one was not provided. - */ - OrthographicOffCenterFrustum.prototype.clone = function(result) { - if (!defined(result)) { - result = new OrthographicOffCenterFrustum(); - } + return DoublyLinkedList; +}); - result.left = this.left; - result.right = this.right; - result.top = this.top; - result.bottom = this.bottom; - result.near = this.near; - result.far = this.far; +/** +@license +tween.js - https://github.com/sole/tween.js - // force update of clone to compute matrices - result._left = undefined; - result._right = undefined; - result._top = undefined; - result._bottom = undefined; - result._near = undefined; - result._far = undefined; +Copyright (c) 2010-2012 Tween.js authors. - return result; - }; +Easing equations Copyright (c) 2001 Robert Penner http://robertpenner.com/easing/ - /** - * Compares the provided OrthographicOffCenterFrustum componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {OrthographicOffCenterFrustum} [other] The right hand side OrthographicOffCenterFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - OrthographicOffCenterFrustum.prototype.equals = function(other) { - return (defined(other) && - this.right === other.right && - this.left === other.left && - this.top === other.top && - this.bottom === other.bottom && - this.near === other.near && - this.far === other.far); - }; +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: - return OrthographicOffCenterFrustum; -}); +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -define('Core/OrthographicFrustum',[ - './Check', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './OrthographicOffCenterFrustum' - ], function( - Check, - defaultValue, - defined, - defineProperties, - DeveloperError, - OrthographicOffCenterFrustum) { - 'use strict'; +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. +*/ - /** - * The viewing frustum is defined by 6 planes. - * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components - * define the unit vector normal to the plane, and the w component is the distance of the - * plane from the origin/camera position. - * - * @alias OrthographicFrustum - * @constructor - * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.width] The width of the frustum in meters. - * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. - * @param {Number} [options.near=1.0] The distance of the near plane. - * @param {Number} [options.far=500000000.0] The distance of the far plane. - * - * @example - * var maxRadii = ellipsoid.maximumRadius; - * - * var frustum = new Cesium.OrthographicFrustum(); - * frustum.near = 0.01 * maxRadii; - * frustum.far = 50.0 * maxRadii; - */ - function OrthographicFrustum(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); +/** + * @author sole / http://soledadpenades.com + * @author mrdoob / http://mrdoob.com + * @author Robert Eisele / http://www.xarg.org + * @author Philippe / http://philippe.elsass.me + * @author Robert Penner / http://www.robertpenner.com/easing_terms_of_use.html + * @author Paul Lewis / http://www.aerotwist.com/ + * @author lechecacharro + * @author Josh Faul / http://jocafa.com/ + * @author egraether / http://egraether.com/ + * @author endel / http://endel.me + * @author Ben Delarre / http://delarre.net + */ - this._offCenterFrustum = new OrthographicOffCenterFrustum(); +define('ThirdParty/Tween',[],function() { - /** - * The horizontal width of the frustum in meters. - * @type {Number} - * @default undefined - */ - this.width = options.width; - this._width = undefined; + // Date.now shim for (ahem) Internet Explo(d|r)er + if ( Date.now === undefined ) { - /** - * The aspect ratio of the frustum's width to it's height. - * @type {Number} - * @default undefined - */ - this.aspectRatio = options.aspectRatio; - this._aspectRatio = undefined; + Date.now = function () { - /** - * The distance of the near plane. - * @type {Number} - * @default 1.0 - */ - this.near = defaultValue(options.near, 1.0); - this._near = this.near; + return new Date().valueOf(); + + }; - /** - * The distance of the far plane. - * @type {Number} - * @default 500000000.0; - */ - this.far = defaultValue(options.far, 500000000.0); - this._far = this.far; } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - OrthographicFrustum.packedLength = 4; + var TWEEN = TWEEN || ( function () { - /** - * Stores the provided instance into the provided array. - * - * @param {OrthographicFrustum} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - OrthographicFrustum.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + var _tweens = []; - array[startingIndex++] = value.width; - array[startingIndex++] = value.aspectRatio; - array[startingIndex++] = value.near; - array[startingIndex] = value.far; + return { - return array; - }; + REVISION: '13', - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {OrthographicFrustum} [result] The object into which to store the result. - * @returns {OrthographicFrustum} The modified result parameter or a new OrthographicFrustum instance if one was not provided. - */ - OrthographicFrustum.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + getAll: function () { - if (!defined(result)) { - result = new OrthographicFrustum(); - } + return _tweens; - result.width = array[startingIndex++]; - result.aspectRatio = array[startingIndex++]; - result.near = array[startingIndex++]; - result.far = array[startingIndex]; + }, - return result; - }; + removeAll: function () { - function update(frustum) { - if (!defined(frustum.width) || !defined(frustum.aspectRatio) || !defined(frustum.near) || !defined(frustum.far)) { - throw new DeveloperError('width, aspectRatio, near, or far parameters are not set.'); - } - - var f = frustum._offCenterFrustum; + _tweens = []; - if (frustum.width !== frustum._width || frustum.aspectRatio !== frustum._aspectRatio || - frustum.near !== frustum._near || frustum.far !== frustum._far) { - if (frustum.aspectRatio < 0) { - throw new DeveloperError('aspectRatio must be positive.'); - } - if (frustum.near < 0 || frustum.near > frustum.far) { - throw new DeveloperError('near must be greater than zero and less than far.'); - } - - frustum._aspectRatio = frustum.aspectRatio; - frustum._width = frustum.width; - frustum._near = frustum.near; - frustum._far = frustum.far; + }, - var ratio = 1.0 / frustum.aspectRatio; - f.right = frustum.width * 0.5; - f.left = -f.right; - f.top = ratio * f.right; - f.bottom = -f.top; - f.near = frustum.near; - f.far = frustum.far; + add: function ( tween ) { - } - } + _tweens.push( tween ); - defineProperties(OrthographicFrustum.prototype, { - /** - * Gets the orthographic projection matrix computed from the view frustum. - * @memberof OrthographicFrustum.prototype - * @type {Matrix4} - * @readonly - */ - projectionMatrix : { - get : function() { - update(this); - return this._offCenterFrustum.projectionMatrix; - } - } + }, - }); + remove: function ( tween ) { - /** - * Creates a culling volume for this frustum. - * - * @param {Cartesian3} position The eye position. - * @param {Cartesian3} direction The view direction. - * @param {Cartesian3} up The up direction. - * @returns {CullingVolume} A culling volume at the given position and orientation. - * - * @example - * // Check if a bounding volume intersects the frustum. - * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); - * var intersect = cullingVolume.computeVisibility(boundingVolume); - */ - OrthographicFrustum.prototype.computeCullingVolume = function(position, direction, up) { - update(this); - return this._offCenterFrustum.computeCullingVolume(position, direction, up); - }; + var i = _tweens.indexOf( tween ); - /** - * Returns the pixel's width and height in meters. - * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. - * - * @exception {DeveloperError} drawingBufferWidth must be greater than zero. - * @exception {DeveloperError} drawingBufferHeight must be greater than zero. - * - * @example - * // Example 1 - * // Get the width and height of a pixel. - * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 0.0, new Cesium.Cartesian2()); - */ - OrthographicFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { - update(this); - return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result); - }; + if ( i !== -1 ) { - /** - * Returns a duplicate of a OrthographicFrustum instance. - * - * @param {OrthographicFrustum} [result] The object onto which to store the result. - * @returns {OrthographicFrustum} The modified result parameter or a new OrthographicFrustum instance if one was not provided. - */ - OrthographicFrustum.prototype.clone = function(result) { - if (!defined(result)) { - result = new OrthographicFrustum(); - } + _tweens.splice( i, 1 ); - result.aspectRatio = this.aspectRatio; - result.width = this.width; - result.near = this.near; - result.far = this.far; + } - // force update of clone to compute matrices - result._aspectRatio = undefined; - result._width = undefined; - result._near = undefined; - result._far = undefined; + }, - this._offCenterFrustum.clone(result._offCenterFrustum); + update: function ( time ) { - return result; - }; + if ( _tweens.length === 0 ) return false; - /** - * Compares the provided OrthographicFrustum componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {OrthographicFrustum} [other] The right hand side OrthographicFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - OrthographicFrustum.prototype.equals = function(other) { - if (!defined(other)) { - return false; - } + var i = 0; - update(this); - update(other); + time = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() ); - return (this.width === other.width && - this.aspectRatio === other.aspectRatio && - this.near === other.near && - this.far === other.far && - this._offCenterFrustum.equals(other._offCenterFrustum)); - }; + while ( i < _tweens.length ) { - return OrthographicFrustum; -}); + if ( _tweens[ i ].update( time ) ) { -define('Core/PerspectiveOffCenterFrustum',[ - './Cartesian3', - './Cartesian4', - './CullingVolume', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Matrix4' - ], function( - Cartesian3, - Cartesian4, - CullingVolume, - defaultValue, - defined, - defineProperties, - DeveloperError, - Matrix4) { - 'use strict'; + i++; - /** - * The viewing frustum is defined by 6 planes. - * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components - * define the unit vector normal to the plane, and the w component is the distance of the - * plane from the origin/camera position. - * - * @alias PerspectiveOffCenterFrustum - * @constructor - * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.left] The left clipping plane distance. - * @param {Number} [options.right] The right clipping plane distance. - * @param {Number} [options.top] The top clipping plane distance. - * @param {Number} [options.bottom] The bottom clipping plane distance. - * @param {Number} [options.near=1.0] The near clipping plane distance. - * @param {Number} [options.far=500000000.0] The far clipping plane distance. - * - * @example - * var frustum = new Cesium.PerspectiveOffCenterFrustum({ - * left : -1.0, - * right : 1.0, - * top : 1.0, - * bottom : -1.0, - * near : 1.0, - * far : 100.0 - * }); - * - * @see PerspectiveFrustum - */ - function PerspectiveOffCenterFrustum(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + } else { - /** - * Defines the left clipping plane. - * @type {Number} - * @default undefined - */ - this.left = options.left; - this._left = undefined; + _tweens.splice( i, 1 ); - /** - * Defines the right clipping plane. - * @type {Number} - * @default undefined - */ - this.right = options.right; - this._right = undefined; + } - /** - * Defines the top clipping plane. - * @type {Number} - * @default undefined - */ - this.top = options.top; - this._top = undefined; + } - /** - * Defines the bottom clipping plane. - * @type {Number} - * @default undefined - */ - this.bottom = options.bottom; - this._bottom = undefined; + return true; - /** - * The distance of the near plane. - * @type {Number} - * @default 1.0 - */ - this.near = defaultValue(options.near, 1.0); - this._near = this.near; + } + }; - /** - * The distance of the far plane. - * @type {Number} - * @default 500000000.0 - */ - this.far = defaultValue(options.far, 500000000.0); - this._far = this.far; + } )(); - this._cullingVolume = new CullingVolume(); - this._perspectiveMatrix = new Matrix4(); - this._infinitePerspective = new Matrix4(); - } + TWEEN.Tween = function ( object ) { - function update(frustum) { - if (!defined(frustum.right) || !defined(frustum.left) || - !defined(frustum.top) || !defined(frustum.bottom) || - !defined(frustum.near) || !defined(frustum.far)) { - throw new DeveloperError('right, left, top, bottom, near, or far parameters are not set.'); - } - - var t = frustum.top; - var b = frustum.bottom; - var r = frustum.right; - var l = frustum.left; - var n = frustum.near; - var f = frustum.far; + 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; - if (t !== frustum._top || b !== frustum._bottom || - l !== frustum._left || r !== frustum._right || - n !== frustum._near || f !== frustum._far) { + // Set all starting values present on the target object + for ( var field in object ) { + + _valuesStart[ field ] = parseFloat(object[field], 10); - if (frustum.near <= 0 || frustum.near > frustum.far) { - throw new DeveloperError('near must be greater than zero and less than far.'); - } - - frustum._left = l; - frustum._right = r; - frustum._top = t; - frustum._bottom = b; - frustum._near = n; - frustum._far = f; - frustum._perspectiveMatrix = Matrix4.computePerspectiveOffCenter(l, r, b, t, n, f, frustum._perspectiveMatrix); - frustum._infinitePerspective = Matrix4.computeInfinitePerspectiveOffCenter(l, r, b, t, n, frustum._infinitePerspective); } - } - defineProperties(PerspectiveOffCenterFrustum.prototype, { - /** - * Gets the perspective projection matrix computed from the view frustum. - * @memberof PerspectiveOffCenterFrustum.prototype - * @type {Matrix4} - * @readonly - * - * @see PerspectiveOffCenterFrustum#infiniteProjectionMatrix - */ - projectionMatrix : { - get : function() { - update(this); - return this._perspectiveMatrix; - } - }, + this.to = function ( properties, duration ) { - /** - * Gets the perspective projection matrix computed from the view frustum with an infinite far plane. - * @memberof PerspectiveOffCenterFrustum.prototype - * @type {Matrix4} - * @readonly - * - * @see PerspectiveOffCenterFrustum#projectionMatrix - */ - infiniteProjectionMatrix : { - get : function() { - update(this); - return this._infinitePerspective; - } - } - }); + if ( duration !== undefined ) { - var getPlanesRight = new Cartesian3(); - var getPlanesNearCenter = new Cartesian3(); - var getPlanesFarCenter = new Cartesian3(); - var getPlanesNormal = new Cartesian3(); - /** - * Creates a culling volume for this frustum. - * - * @param {Cartesian3} position The eye position. - * @param {Cartesian3} direction The view direction. - * @param {Cartesian3} up The up direction. - * @returns {CullingVolume} A culling volume at the given position and orientation. - * - * @example - * // Check if a bounding volume intersects the frustum. - * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); - * var intersect = cullingVolume.computeVisibility(boundingVolume); - */ - PerspectiveOffCenterFrustum.prototype.computeCullingVolume = function(position, direction, up) { - if (!defined(position)) { - throw new DeveloperError('position is required.'); - } + _duration = duration; - if (!defined(direction)) { - throw new DeveloperError('direction is required.'); - } + } - if (!defined(up)) { - throw new DeveloperError('up is required.'); - } - - var planes = this._cullingVolume.planes; + _valuesEnd = properties; - var t = this.top; - var b = this.bottom; - var r = this.right; - var l = this.left; - var n = this.near; - var f = this.far; + return this; - var right = Cartesian3.cross(direction, up, getPlanesRight); + }; - var nearCenter = getPlanesNearCenter; - Cartesian3.multiplyByScalar(direction, n, nearCenter); - Cartesian3.add(position, nearCenter, nearCenter); + this.start = function ( time ) { - var farCenter = getPlanesFarCenter; - Cartesian3.multiplyByScalar(direction, f, farCenter); - Cartesian3.add(position, farCenter, farCenter); + TWEEN.add( this ); - var normal = getPlanesNormal; + _isPlaying = true; - //Left plane computation - Cartesian3.multiplyByScalar(right, l, normal); - Cartesian3.add(nearCenter, normal, normal); - Cartesian3.subtract(normal, position, normal); - Cartesian3.normalize(normal, normal); - Cartesian3.cross(normal, up, normal); - Cartesian3.normalize(normal, normal); + _onStartCallbackFired = false; - var plane = planes[0]; - if (!defined(plane)) { - plane = planes[0] = new Cartesian4(); - } - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -Cartesian3.dot(normal, position); + _startTime = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() ); + _startTime += _delayTime; - //Right plane computation - Cartesian3.multiplyByScalar(right, r, normal); - Cartesian3.add(nearCenter, normal, normal); - Cartesian3.subtract(normal, position, normal); - Cartesian3.cross(up, normal, normal); - Cartesian3.normalize(normal, normal); + for ( var property in _valuesEnd ) { - plane = planes[1]; - if (!defined(plane)) { - plane = planes[1] = new Cartesian4(); - } - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -Cartesian3.dot(normal, position); + // check if an Array was provided as property value + if ( _valuesEnd[ property ] instanceof Array ) { - //Bottom plane computation - Cartesian3.multiplyByScalar(up, b, normal); - Cartesian3.add(nearCenter, normal, normal); - Cartesian3.subtract(normal, position, normal); - Cartesian3.cross(right, normal, normal); - Cartesian3.normalize(normal, normal); + if ( _valuesEnd[ property ].length === 0 ) { - plane = planes[2]; - if (!defined(plane)) { - plane = planes[2] = new Cartesian4(); - } - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -Cartesian3.dot(normal, position); + continue; - //Top plane computation - Cartesian3.multiplyByScalar(up, t, normal); - Cartesian3.add(nearCenter, normal, normal); - Cartesian3.subtract(normal, position, normal); - Cartesian3.cross(normal, right, normal); - Cartesian3.normalize(normal, normal); + } - plane = planes[3]; - if (!defined(plane)) { - plane = planes[3] = new Cartesian4(); - } - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -Cartesian3.dot(normal, position); + // create a local copy of the Array with the start value at the front + _valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] ); - //Near plane computation - plane = planes[4]; - if (!defined(plane)) { - plane = planes[4] = new Cartesian4(); - } - plane.x = direction.x; - plane.y = direction.y; - plane.z = direction.z; - plane.w = -Cartesian3.dot(direction, nearCenter); + } - //Far plane computation - Cartesian3.negate(direction, normal); + _valuesStart[ property ] = _object[ property ]; - plane = planes[5]; - if (!defined(plane)) { - plane = planes[5] = new Cartesian4(); - } - plane.x = normal.x; - plane.y = normal.y; - plane.z = normal.z; - plane.w = -Cartesian3.dot(normal, farCenter); + if( ( _valuesStart[ property ] instanceof Array ) === false ) { + _valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings + } - return this._cullingVolume; - }; + _valuesStartRepeat[ property ] = _valuesStart[ property ] || 0; - /** - * Returns the pixel's width and height in meters. - * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. - * - * @exception {DeveloperError} drawingBufferWidth must be greater than zero. - * @exception {DeveloperError} drawingBufferHeight must be greater than zero. - * - * @example - * // Example 1 - * // Get the width and height of a pixel. - * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 1.0, new Cesium.Cartesian2()); - * - * @example - * // Example 2 - * // Get the width and height of a pixel if the near plane was set to 'distance'. - * // For example, get the size of a pixel of an image on a billboard. - * var position = camera.position; - * var direction = camera.direction; - * var toCenter = Cesium.Cartesian3.subtract(primitive.boundingVolume.center, position, new Cesium.Cartesian3()); // vector from camera to a primitive - * var toCenterProj = Cesium.Cartesian3.multiplyByScalar(direction, Cesium.Cartesian3.dot(direction, toCenter), new Cesium.Cartesian3()); // project vector onto camera direction vector - * var distance = Cesium.Cartesian3.magnitude(toCenterProj); - * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, distance, new Cesium.Cartesian2()); - */ - PerspectiveOffCenterFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { - update(this); + } - if (!defined(drawingBufferWidth) || !defined(drawingBufferHeight)) { - throw new DeveloperError('Both drawingBufferWidth and drawingBufferHeight are required.'); - } - if (drawingBufferWidth <= 0) { - throw new DeveloperError('drawingBufferWidth must be greater than zero.'); - } - if (drawingBufferHeight <= 0) { - throw new DeveloperError('drawingBufferHeight must be greater than zero.'); - } - if (!defined(distance)) { - throw new DeveloperError('distance is required.'); - } - if (!defined(result)) { - throw new DeveloperError('A result object is required.'); - } - - var inverseNear = 1.0 / this.near; - var tanTheta = this.top * inverseNear; - var pixelHeight = 2.0 * distance * tanTheta / drawingBufferHeight; - tanTheta = this.right * inverseNear; - var pixelWidth = 2.0 * distance * tanTheta / drawingBufferWidth; + return this; - result.x = pixelWidth; - result.y = pixelHeight; - return result; - }; + }; - /** - * Returns a duplicate of a PerspectiveOffCenterFrustum instance. - * - * @param {PerspectiveOffCenterFrustum} [result] The object onto which to store the result. - * @returns {PerspectiveOffCenterFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. - */ - PerspectiveOffCenterFrustum.prototype.clone = function(result) { - if (!defined(result)) { - result = new PerspectiveOffCenterFrustum(); - } + this.stop = function () { - result.right = this.right; - result.left = this.left; - result.top = this.top; - result.bottom = this.bottom; - result.near = this.near; - result.far = this.far; + if ( !_isPlaying ) { + return this; + } - // force update of clone to compute matrices - result._left = undefined; - result._right = undefined; - result._top = undefined; - result._bottom = undefined; - result._near = undefined; - result._far = undefined; + TWEEN.remove( this ); + _isPlaying = false; - return result; - }; + if ( _onStopCallback !== null ) { - /** - * Compares the provided PerspectiveOffCenterFrustum componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {PerspectiveOffCenterFrustum} [other] The right hand side PerspectiveOffCenterFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - PerspectiveOffCenterFrustum.prototype.equals = function(other) { - return (defined(other) && - this.right === other.right && - this.left === other.left && - this.top === other.top && - this.bottom === other.bottom && - this.near === other.near && - this.far === other.far); - }; + _onStopCallback.call( _object ); - return PerspectiveOffCenterFrustum; -}); + } -define('Core/PerspectiveFrustum',[ - './Check', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './PerspectiveOffCenterFrustum' - ], function( - Check, - defaultValue, - defined, - defineProperties, - DeveloperError, - PerspectiveOffCenterFrustum) { - 'use strict'; + this.stopChainedTweens(); + return this; - /** - * The viewing frustum is defined by 6 planes. - * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components - * define the unit vector normal to the plane, and the w component is the distance of the - * plane from the origin/camera position. - * - * @alias PerspectiveFrustum - * @constructor - * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.fov] The angle of the field of view (FOV), in radians. - * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. - * @param {Number} [options.near=1.0] The distance of the near plane. - * @param {Number} [options.far=500000000.0] The distance of the far plane. - * @param {Number} [options.xOffset=0.0] The offset in the x direction. - * @param {Number} [options.yOffset=0.0] The offset in the y direction. - * - * @example - * var frustum = new Cesium.PerspectiveFrustum({ - * fov : Cesium.Math.PI_OVER_THREE, - * aspectRatio : canvas.clientWidth / canvas.clientHeight - * near : 1.0, - * far : 1000.0 - * }); - * - * @see PerspectiveOffCenterFrustum - */ - function PerspectiveFrustum(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + }; - this._offCenterFrustum = new PerspectiveOffCenterFrustum(); + this.stopChainedTweens = function () { - /** - * The angle of the field of view (FOV), in radians. This angle will be used - * as the horizontal FOV if the width is greater than the height, otherwise - * it will be the vertical FOV. - * @type {Number} - * @default undefined - */ - this.fov = options.fov; - this._fov = undefined; - this._fovy = undefined; + for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) { - this._sseDenominator = undefined; + _chainedTweens[ i ].stop(); - /** - * The aspect ratio of the frustum's width to it's height. - * @type {Number} - * @default undefined - */ - this.aspectRatio = options.aspectRatio; - this._aspectRatio = undefined; + } - /** - * The distance of the near plane. - * @type {Number} - * @default 1.0 - */ - this.near = defaultValue(options.near, 1.0); - this._near = this.near; + }; - /** - * The distance of the far plane. - * @type {Number} - * @default 500000000.0 - */ - this.far = defaultValue(options.far, 500000000.0); - this._far = this.far; + this.delay = function ( amount ) { - /** - * Offsets the frustum in the x direction. - * @type {Number} - * @default 0.0 - */ - this.xOffset = defaultValue(options.xOffset, 0.0); - this._xOffset = this.xOffset; + _delayTime = amount; + return this; - /** - * Offsets the frustum in the y direction. - * @type {Number} - * @default 0.0 - */ - this.yOffset = defaultValue(options.yOffset, 0.0); - this._yOffset = this.yOffset; - } + }; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - PerspectiveFrustum.packedLength = 6; + this.repeat = function ( times ) { - /** - * Stores the provided instance into the provided array. - * - * @param {PerspectiveFrustum} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - PerspectiveFrustum.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + _repeat = times; + return this; - array[startingIndex++] = value.fov; - array[startingIndex++] = value.aspectRatio; - array[startingIndex++] = value.near; - array[startingIndex++] = value.far; - array[startingIndex++] = value.xOffset; - array[startingIndex] = value.yOffset; + }; - return array; - }; + this.yoyo = function( yoyo ) { - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PerspectiveFrustum} [result] The object into which to store the result. - * @returns {PerspectiveFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. - */ - PerspectiveFrustum.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + _yoyo = yoyo; + return this; - if (!defined(result)) { - result = new PerspectiveFrustum(); - } + }; - result.fov = array[startingIndex++]; - result.aspectRatio = array[startingIndex++]; - result.near = array[startingIndex++]; - result.far = array[startingIndex++]; - result.xOffset = array[startingIndex++]; - result.yOffset = array[startingIndex]; - return result; - }; + this.easing = function ( easing ) { - function update(frustum) { - if (!defined(frustum.fov) || !defined(frustum.aspectRatio) || !defined(frustum.near) || !defined(frustum.far)) { - throw new DeveloperError('fov, aspectRatio, near, or far parameters are not set.'); - } - - var f = frustum._offCenterFrustum; + _easingFunction = easing; + return this; - if (frustum.fov !== frustum._fov || frustum.aspectRatio !== frustum._aspectRatio || - frustum.near !== frustum._near || frustum.far !== frustum._far || - frustum.xOffset !== frustum._xOffset || frustum.yOffset !== frustum._yOffset) { - if (frustum.fov < 0 || frustum.fov >= Math.PI) { - throw new DeveloperError('fov must be in the range [0, PI).'); - } + }; - if (frustum.aspectRatio < 0) { - throw new DeveloperError('aspectRatio must be positive.'); - } + this.interpolation = function ( interpolation ) { - if (frustum.near < 0 || frustum.near > frustum.far) { - throw new DeveloperError('near must be greater than zero and less than far.'); - } - - frustum._aspectRatio = frustum.aspectRatio; - frustum._fov = frustum.fov; - frustum._fovy = (frustum.aspectRatio <= 1) ? frustum.fov : Math.atan(Math.tan(frustum.fov * 0.5) / frustum.aspectRatio) * 2.0; - frustum._near = frustum.near; - frustum._far = frustum.far; - frustum._sseDenominator = 2.0 * Math.tan(0.5 * frustum._fovy); - frustum._xOffset = frustum.xOffset; - frustum._yOffset = frustum.yOffset; + _interpolationFunction = interpolation; + return this; - f.top = frustum.near * Math.tan(0.5 * frustum._fovy); - f.bottom = -f.top; - f.right = frustum.aspectRatio * f.top; - f.left = -f.right; - f.near = frustum.near; - f.far = frustum.far; + }; - f.right += frustum.xOffset; - f.left += frustum.xOffset; - f.top += frustum.yOffset; - f.bottom += frustum.yOffset; - } - } + this.chain = function () { - defineProperties(PerspectiveFrustum.prototype, { - /** - * Gets the perspective projection matrix computed from the view frustum. - * @memberof PerspectiveFrustum.prototype - * @type {Matrix4} - * @readonly - * - * @see PerspectiveFrustum#infiniteProjectionMatrix - */ - projectionMatrix : { - get : function() { - update(this); - return this._offCenterFrustum.projectionMatrix; - } - }, + _chainedTweens = arguments; + return this; - /** - * The perspective projection matrix computed from the view frustum with an infinite far plane. - * @memberof PerspectiveFrustum.prototype - * @type {Matrix4} - * @readonly - * - * @see PerspectiveFrustum#projectionMatrix - */ - infiniteProjectionMatrix : { - get : function() { - update(this); - return this._offCenterFrustum.infiniteProjectionMatrix; - } - }, + }; - /** - * Gets the angle of the vertical field of view, in radians. - * @memberof PerspectiveFrustum.prototype - * @type {Number} - * @readonly - * @default undefined - */ - fovy : { - get : function() { - update(this); - return this._fovy; - } - }, + this.onStart = function ( callback ) { - /** - * @readonly - * @private - */ - sseDenominator : { - get : function () { - update(this); - return this._sseDenominator; - } - } - }); + _onStartCallback = callback; + return this; - /** - * Creates a culling volume for this frustum. - * - * @param {Cartesian3} position The eye position. - * @param {Cartesian3} direction The view direction. - * @param {Cartesian3} up The up direction. - * @returns {CullingVolume} A culling volume at the given position and orientation. - * - * @example - * // Check if a bounding volume intersects the frustum. - * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); - * var intersect = cullingVolume.computeVisibility(boundingVolume); - */ - PerspectiveFrustum.prototype.computeCullingVolume = function(position, direction, up) { - update(this); - return this._offCenterFrustum.computeCullingVolume(position, direction, up); - }; + }; - /** - * Returns the pixel's width and height in meters. - * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. - * - * @exception {DeveloperError} drawingBufferWidth must be greater than zero. - * @exception {DeveloperError} drawingBufferHeight must be greater than zero. - * - * @example - * // Example 1 - * // Get the width and height of a pixel. - * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 1.0, new Cesium.Cartesian2()); - * - * @example - * // Example 2 - * // Get the width and height of a pixel if the near plane was set to 'distance'. - * // For example, get the size of a pixel of an image on a billboard. - * var position = camera.position; - * var direction = camera.direction; - * var toCenter = Cesium.Cartesian3.subtract(primitive.boundingVolume.center, position, new Cesium.Cartesian3()); // vector from camera to a primitive - * var toCenterProj = Cesium.Cartesian3.multiplyByScalar(direction, Cesium.Cartesian3.dot(direction, toCenter), new Cesium.Cartesian3()); // project vector onto camera direction vector - * var distance = Cesium.Cartesian3.magnitude(toCenterProj); - * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, distance, new Cesium.Cartesian2()); - */ - PerspectiveFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { - update(this); - return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result); - }; + this.onUpdate = function ( callback ) { - /** - * Returns a duplicate of a PerspectiveFrustum instance. - * - * @param {PerspectiveFrustum} [result] The object onto which to store the result. - * @returns {PerspectiveFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. - */ - PerspectiveFrustum.prototype.clone = function(result) { - if (!defined(result)) { - result = new PerspectiveFrustum(); - } + _onUpdateCallback = callback; + return this; - result.aspectRatio = this.aspectRatio; - result.fov = this.fov; - result.near = this.near; - result.far = this.far; + }; - // force update of clone to compute matrices - result._aspectRatio = undefined; - result._fov = undefined; - result._near = undefined; - result._far = undefined; + this.onComplete = function ( callback ) { - this._offCenterFrustum.clone(result._offCenterFrustum); + _onCompleteCallback = callback; + return this; - return result; - }; + }; - /** - * Compares the provided PerspectiveFrustum componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {PerspectiveFrustum} [other] The right hand side PerspectiveFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - PerspectiveFrustum.prototype.equals = function(other) { - if (!defined(other)) { - return false; - } + this.onStop = function ( callback ) { - update(this); - update(other); + _onStopCallback = callback; + return this; - return (this.fov === other.fov && - this.aspectRatio === other.aspectRatio && - this.near === other.near && - this.far === other.far && - this._offCenterFrustum.equals(other._offCenterFrustum)); - }; + }; - return PerspectiveFrustum; -}); + this.update = function ( time ) { -define('Core/FrustumGeometry',[ - './BoundingSphere', - './Cartesian3', - './Cartesian4', - './Check', - './ComponentDatatype', - './defaultValue', - './defined', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './Matrix3', - './Matrix4', - './OrthographicFrustum', - './PerspectiveFrustum', - './PrimitiveType', - './Quaternion', - './VertexFormat' - ], function( - BoundingSphere, - Cartesian3, - Cartesian4, - Check, - ComponentDatatype, - defaultValue, - defined, - Geometry, - GeometryAttribute, - GeometryAttributes, - Matrix3, - Matrix4, - OrthographicFrustum, - PerspectiveFrustum, - PrimitiveType, - Quaternion, - VertexFormat) { - 'use strict'; + var property; - var PERSPECTIVE = 0; - var ORTHOGRAPHIC = 1; + if ( time < _startTime ) { - /** - * Describes a frustum at the given the origin and orientation. - * - * @alias FrustumGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. - * @param {Cartesian3} options.origin The origin of the frustum. - * @param {Quaternion} options.orientation The orientation of the frustum. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - */ - function FrustumGeometry(options) { - Check.typeOf.object('options', options); - Check.typeOf.object('options.frustum', options.frustum); - Check.typeOf.object('options.origin', options.origin); - Check.typeOf.object('options.orientation', options.orientation); - - var frustum = options.frustum; - var orientation = options.orientation; - var origin = options.origin; - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + return true; - // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by - // creating multiple FrustumGeometrys. This way the near plane of one frustum doesn't overlap - // the far plane of another. - var drawNearPlane = defaultValue(options._drawNearPlane, true); + } - var frustumType; - var frustumPackedLength; - if (frustum instanceof PerspectiveFrustum) { - frustumType = PERSPECTIVE; - frustumPackedLength = PerspectiveFrustum.packedLength; - } else if (frustum instanceof OrthographicFrustum) { - frustumType = ORTHOGRAPHIC; - frustumPackedLength = OrthographicFrustum.packedLength; - } + if ( _onStartCallbackFired === false ) { - this._frustumType = frustumType; - this._frustum = frustum.clone(); - this._origin = Cartesian3.clone(origin); - this._orientation = Quaternion.clone(orientation); - this._drawNearPlane = drawNearPlane; - this._vertexFormat = vertexFormat; - this._workerName = 'createFrustumGeometry'; + if ( _onStartCallback !== null ) { - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength + VertexFormat.packedLength; - } + _onStartCallback.call( _object ); - /** - * Stores the provided instance into the provided array. - * - * @param {FrustumGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - FrustumGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + } - var frustumType = value._frustumType; - var frustum = value._frustum; + _onStartCallbackFired = true; - array[startingIndex++] = frustumType; + } - if (frustumType === PERSPECTIVE) { - PerspectiveFrustum.pack(frustum, array, startingIndex); - startingIndex += PerspectiveFrustum.packedLength; - } else { - OrthographicFrustum.pack(frustum, array, startingIndex); - startingIndex += OrthographicFrustum.packedLength; - } + var elapsed = ( time - _startTime ) / _duration; + elapsed = elapsed > 1 ? 1 : elapsed; - Cartesian3.pack(value._origin, array, startingIndex); - startingIndex += Cartesian3.packedLength; - Quaternion.pack(value._orientation, array, startingIndex); - startingIndex += Quaternion.packedLength; - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0; + var value = _easingFunction( elapsed ); - return array; - }; + for ( property in _valuesEnd ) { - var scratchPackPerspective = new PerspectiveFrustum(); - var scratchPackOrthographic = new OrthographicFrustum(); - var scratchPackQuaternion = new Quaternion(); - var scratchPackorigin = new Cartesian3(); - var scratchVertexFormat = new VertexFormat(); + var start = _valuesStart[ property ] || 0; + var end = _valuesEnd[ property ]; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {FrustumGeometry} [result] The object into which to store the result. - */ - FrustumGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + if ( end instanceof Array ) { - var frustumType = array[startingIndex++]; + _object[ property ] = _interpolationFunction( end, value ); - var frustum; - if (frustumType === PERSPECTIVE) { - frustum = PerspectiveFrustum.unpack(array, startingIndex, scratchPackPerspective); - startingIndex += PerspectiveFrustum.packedLength; - } else { - frustum = OrthographicFrustum.unpack(array, startingIndex, scratchPackOrthographic); - startingIndex += OrthographicFrustum.packedLength; - } + } else { - var origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin); - startingIndex += Cartesian3.packedLength; - var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); - startingIndex += Quaternion.packedLength; - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; - var drawNearPlane = array[startingIndex] === 1.0; + // Parses relative end values with start as base (e.g.: +10, -3) + if ( typeof(end) === "string" ) { + end = start + parseFloat(end, 10); + } - if (!defined(result)) { - return new FrustumGeometry({ - frustum : frustum, - origin : origin, - orientation : orientation, - vertexFormat : vertexFormat, - _drawNearPlane : drawNearPlane - }); - } + // protect against non numeric properties. + if ( typeof(end) === "number" ) { + _object[ property ] = start + ( end - start ) * value; + } - var frustumResult = frustumType === result._frustumType ? result._frustum : undefined; - result._frustum = frustum.clone(frustumResult); + } - result._frustumType = frustumType; - result._origin = Cartesian3.clone(origin, result._origin); - result._orientation = Quaternion.clone(orientation, result._orientation); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._drawNearPlane = drawNearPlane; + } - return result; - }; + if ( _onUpdateCallback !== null ) { - function getAttributes(offset, normals, tangents, bitangents, st, normal, tangent, bitangent) { - var stOffset = offset / 3 * 2; + _onUpdateCallback.call( _object, value ); - for (var i = 0; i < 4; ++i) { - if (defined(normals)) { - normals[offset] = normal.x; - normals[offset + 1] = normal.y; - normals[offset + 2] = normal.z; - } - if (defined(tangents)) { - tangents[offset] = tangent.x; - tangents[offset + 1] = tangent.y; - tangents[offset + 2] = tangent.z; - } - if (defined(bitangents)) { - bitangents[offset] = bitangent.x; - bitangents[offset + 1] = bitangent.y; - bitangents[offset + 2] = bitangent.z; } - offset += 3; - } - st[stOffset] = 0.0; - st[stOffset + 1] = 0.0; - st[stOffset + 2] = 1.0; - st[stOffset + 3] = 0.0; - st[stOffset + 4] = 1.0; - st[stOffset + 5] = 1.0; - st[stOffset + 6] = 0.0; - st[stOffset + 7] = 1.0; - } + if ( elapsed == 1 ) { - var scratchRotationMatrix = new Matrix3(); - var scratchViewMatrix = new Matrix4(); - var scratchInverseMatrix = new Matrix4(); + if ( _repeat > 0 ) { - var scratchXDirection = new Cartesian3(); - var scratchYDirection = new Cartesian3(); - var scratchZDirection = new Cartesian3(); - var scratchNegativeX = new Cartesian3(); - var scratchNegativeY = new Cartesian3(); - var scratchNegativeZ = new Cartesian3(); + if( isFinite( _repeat ) ) { + _repeat--; + } - var frustumSplits = new Array(3); + // reassign starting values, restart by making startTime = now + for( property in _valuesStartRepeat ) { - var frustumCornersNDC = new Array(4); - frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0); - frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); + if ( typeof( _valuesEnd[ property ] ) === "string" ) { + _valuesStartRepeat[ property ] = _valuesStartRepeat[ property ] + parseFloat(_valuesEnd[ property ], 10); + } - var scratchFrustumCorners = new Array(4); - for (var i = 0; i < 4; ++i) { - scratchFrustumCorners[i] = new Cartesian4(); - } + if (_yoyo) { + var tmp = _valuesStartRepeat[ property ]; + _valuesStartRepeat[ property ] = _valuesEnd[ property ]; + _valuesEnd[ property ] = tmp; + } - FrustumGeometry._computeNearFarPlanes = function(origin, orientation, frustumType, frustum, positions, xDirection, yDirection, zDirection) { - var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); - var x = defaultValue(xDirection, scratchXDirection); - var y = defaultValue(yDirection, scratchYDirection); - var z = defaultValue(zDirection, scratchZDirection); + _valuesStart[ property ] = _valuesStartRepeat[ property ]; - x = Matrix3.getColumn(rotationMatrix, 0, x); - y = Matrix3.getColumn(rotationMatrix, 1, y); - z = Matrix3.getColumn(rotationMatrix, 2, z); + } - Cartesian3.normalize(x, x); - Cartesian3.normalize(y, y); - Cartesian3.normalize(z, z); + if (_yoyo) { + _reversed = !_reversed; + } - Cartesian3.negate(x, x); + _startTime = time + _delayTime; - var view = Matrix4.computeView(origin, z, y, x, scratchViewMatrix); + return true; - var inverseView; - var inverseViewProjection; - if (frustumType === PERSPECTIVE) { - var projection = frustum.projectionMatrix; - var viewProjection = Matrix4.multiply(projection, view, scratchInverseMatrix); - inverseViewProjection = Matrix4.inverse(viewProjection, scratchInverseMatrix); - } else { - inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); - } + } else { - if (defined(inverseViewProjection)) { - frustumSplits[0] = frustum.near; - frustumSplits[1] = frustum.far; - } else { - frustumSplits[0] = 0.0; - frustumSplits[1] = frustum.near; - frustumSplits[2] = frustum.far; - } + if ( _onCompleteCallback !== null ) { - for (var i = 0; i < 2; ++i) { - for (var j = 0; j < 4; ++j) { - var corner = Cartesian4.clone(frustumCornersNDC[j], scratchFrustumCorners[j]); + _onCompleteCallback.call( _object ); - if (!defined(inverseViewProjection)) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; } - var near = frustumSplits[i]; - var far = frustumSplits[i + 1]; - - corner.x = (corner.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; - corner.y = (corner.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; - corner.z = (corner.z * (near - far) - near - far) * 0.5; - corner.w = 1.0; + for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) { - Matrix4.multiplyByVector(inverseView, corner, corner); - } else { - corner = Matrix4.multiplyByVector(inverseViewProjection, corner, corner); + _chainedTweens[ i ].start( time ); - // Reverse perspective divide - var w = 1.0 / corner.w; - Cartesian3.multiplyByScalar(corner, w, corner); + } - Cartesian3.subtract(corner, origin, corner); - Cartesian3.normalize(corner, corner); + return false; - var fac = Cartesian3.dot(z, corner); - Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); - Cartesian3.add(corner, origin, corner); } - positions[12 * i + j * 3] = corner.x; - positions[12 * i + j * 3 + 1] = corner.y; - positions[12 * i + j * 3 + 2] = corner.z; } - } + + return true; + + }; + }; - /** - * Computes the geometric representation of a frustum, including its vertices, indices, and a bounding sphere. - * - * @param {FrustumGeometry} frustumGeometry A description of the frustum. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - FrustumGeometry.createGeometry = function(frustumGeometry) { - var frustumType = frustumGeometry._frustumType; - var frustum = frustumGeometry._frustum; - var origin = frustumGeometry._origin; - var orientation = frustumGeometry._orientation; - var drawNearPlane = frustumGeometry._drawNearPlane; - var vertexFormat = frustumGeometry._vertexFormat; - var numberOfPlanes = drawNearPlane ? 6 : 5; - var positions = new Float64Array(3 * 4 * 6); - FrustumGeometry._computeNearFarPlanes(origin, orientation, frustumType, frustum, positions); + TWEEN.Easing = { - // -x plane - var offset = 3 * 4 * 2; - positions[offset] = positions[3 * 4]; - positions[offset + 1] = positions[3 * 4 + 1]; - positions[offset + 2] = positions[3 * 4 + 2]; - positions[offset + 3] = positions[0]; - positions[offset + 4] = positions[1]; - positions[offset + 5] = positions[2]; - positions[offset + 6] = positions[3 * 3]; - positions[offset + 7] = positions[3 * 3 + 1]; - positions[offset + 8] = positions[3 * 3 + 2]; - positions[offset + 9] = positions[3 * 7]; - positions[offset + 10] = positions[3 * 7 + 1]; - positions[offset + 11] = positions[3 * 7 + 2]; + Linear: { - // -y plane - offset += 3 * 4; - positions[offset] = positions[3 * 5]; - positions[offset + 1] = positions[3 * 5 + 1]; - positions[offset + 2] = positions[3 * 5 + 2]; - positions[offset + 3] = positions[3]; - positions[offset + 4] = positions[3 + 1]; - positions[offset + 5] = positions[3 + 2]; - positions[offset + 6] = positions[0]; - positions[offset + 7] = positions[1]; - positions[offset + 8] = positions[2]; - positions[offset + 9] = positions[3 * 4]; - positions[offset + 10] = positions[3 * 4 + 1]; - positions[offset + 11] = positions[3 * 4 + 2]; + None: function ( k ) { - // +x plane - offset += 3 * 4; - positions[offset] = positions[3]; - positions[offset + 1] = positions[3 + 1]; - positions[offset + 2] = positions[3 + 2]; - positions[offset + 3] = positions[3 * 5]; - positions[offset + 4] = positions[3 * 5 + 1]; - positions[offset + 5] = positions[3 * 5 + 2]; - positions[offset + 6] = positions[3 * 6]; - positions[offset + 7] = positions[3 * 6 + 1]; - positions[offset + 8] = positions[3 * 6 + 2]; - positions[offset + 9] = positions[3 * 2]; - positions[offset + 10] = positions[3 * 2 + 1]; - positions[offset + 11] = positions[3 * 2 + 2]; + return k; - // +y plane - offset += 3 * 4; - positions[offset] = positions[3 * 2]; - positions[offset + 1] = positions[3 * 2 + 1]; - positions[offset + 2] = positions[3 * 2 + 2]; - positions[offset + 3] = positions[3 * 6]; - positions[offset + 4] = positions[3 * 6 + 1]; - positions[offset + 5] = positions[3 * 6 + 2]; - positions[offset + 6] = positions[3 * 7]; - positions[offset + 7] = positions[3 * 7 + 1]; - positions[offset + 8] = positions[3 * 7 + 2]; - positions[offset + 9] = positions[3 * 3]; - positions[offset + 10] = positions[3 * 3 + 1]; - positions[offset + 11] = positions[3 * 3 + 2]; + } - if (!drawNearPlane) { - positions = positions.subarray(3 * 4); - } + }, - var attributes = new GeometryAttributes({ - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }) - }); + Quadratic: { - if (defined(vertexFormat.normal) || defined(vertexFormat.tangent) || defined(vertexFormat.bitangent) || defined(vertexFormat.st)) { - var normals = defined(vertexFormat.normal) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; - var tangents = defined(vertexFormat.tangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; - var bitangents = defined(vertexFormat.bitangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; - var st = defined(vertexFormat.st) ? new Float32Array(2 * 4 * numberOfPlanes) : undefined; + In: function ( k ) { - var x = scratchXDirection; - var y = scratchYDirection; - var z = scratchZDirection; + return k * k; - var negativeX = Cartesian3.negate(x, scratchNegativeX); - var negativeY = Cartesian3.negate(y, scratchNegativeY); - var negativeZ = Cartesian3.negate(z, scratchNegativeZ); + }, - offset = 0; - if (drawNearPlane) { - getAttributes(offset, normals, tangents, bitangents, st, negativeZ, x, y); // near - offset += 3 * 4; - } - getAttributes(offset, normals, tangents, bitangents, st, z, negativeX, y); // far - offset += 3 * 4; - getAttributes(offset, normals, tangents, bitangents, st, negativeX, negativeZ, y); // -x - offset += 3 * 4; - getAttributes(offset, normals, tangents, bitangents, st, negativeY, negativeZ, negativeX); // -y - offset += 3 * 4; - getAttributes(offset, normals, tangents, bitangents, st, x, z, y); // +x - offset += 3 * 4; - getAttributes(offset, normals, tangents, bitangents, st, y, z, negativeX); // +y + 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 ); - if (defined(normals)) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } - if (defined(tangents)) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); - } - if (defined(bitangents)) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } - if (defined(st)) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : st - }); } - } - var indices = new Uint16Array(6 * numberOfPlanes); - for (var i = 0; i < numberOfPlanes; ++i) { - var indexOffset = i * 6; - var index = i * 4; + }, - indices[indexOffset] = index; - indices[indexOffset + 1] = index + 1; - indices[indexOffset + 2] = index + 2; - indices[indexOffset + 3] = index; - indices[indexOffset + 4] = index + 2; - indices[indexOffset + 5] = index + 3; - } + Cubic: { - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : BoundingSphere.fromVertices(positions) - }); - }; + In: function ( k ) { - return FrustumGeometry; -}); + return k * k * k; -define('Core/FrustumOutlineGeometry',[ - './BoundingSphere', - './Cartesian3', - './Check', - './ComponentDatatype', - './defaultValue', - './defined', - './FrustumGeometry', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './OrthographicFrustum', - './PerspectiveFrustum', - './PrimitiveType', - './Quaternion' - ], function( - BoundingSphere, - Cartesian3, - Check, - ComponentDatatype, - defaultValue, - defined, - FrustumGeometry, - Geometry, - GeometryAttribute, - GeometryAttributes, - OrthographicFrustum, - PerspectiveFrustum, - PrimitiveType, - Quaternion) { - 'use strict'; + }, - var PERSPECTIVE = 0; - var ORTHOGRAPHIC = 1; + Out: function ( k ) { - /** - * A description of the outline of a frustum with the given the origin and orientation. - * - * @alias FrustumOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. - * @param {Cartesian3} options.origin The origin of the frustum. - * @param {Quaternion} options.orientation The orientation of the frustum. - */ - function FrustumOutlineGeometry(options) { - Check.typeOf.object('options', options); - Check.typeOf.object('options.frustum', options.frustum); - Check.typeOf.object('options.origin', options.origin); - Check.typeOf.object('options.orientation', options.orientation); - - var frustum = options.frustum; - var orientation = options.orientation; - var origin = options.origin; + return --k * k * k + 1; - // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by - // creating multiple FrustumOutlineGeometrys. This way the near plane of one frustum doesn't overlap - // the far plane of another. - var drawNearPlane = defaultValue(options._drawNearPlane, true); + }, - var frustumType; - var frustumPackedLength; - if (frustum instanceof PerspectiveFrustum) { - frustumType = PERSPECTIVE; - frustumPackedLength = PerspectiveFrustum.packedLength; - } else if (frustum instanceof OrthographicFrustum) { - frustumType = ORTHOGRAPHIC; - frustumPackedLength = OrthographicFrustum.packedLength; - } + InOut: function ( k ) { - this._frustumType = frustumType; - this._frustum = frustum.clone(); - this._origin = Cartesian3.clone(origin); - this._orientation = Quaternion.clone(orientation); - this._drawNearPlane = drawNearPlane; - this._workerName = 'createFrustumOutlineGeometry'; + if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k; + return 0.5 * ( ( k -= 2 ) * k * k + 2 ); - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength; - } + } - /** - * Stores the provided instance into the provided array. - * - * @param {FrustumOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - FrustumOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + }, - var frustumType = value._frustumType; - var frustum = value._frustum; + Quartic: { - array[startingIndex++] = frustumType; + In: function ( k ) { - if (frustumType === PERSPECTIVE) { - PerspectiveFrustum.pack(frustum, array, startingIndex); - startingIndex += PerspectiveFrustum.packedLength; - } else { - OrthographicFrustum.pack(frustum, array, startingIndex); - startingIndex += OrthographicFrustum.packedLength; - } + return k * k * k * k; - Cartesian3.pack(value._origin, array, startingIndex); - startingIndex += Cartesian3.packedLength; - Quaternion.pack(value._orientation, array, startingIndex); - startingIndex += Quaternion.packedLength; - array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0; + }, - return array; - }; + Out: function ( k ) { - var scratchPackPerspective = new PerspectiveFrustum(); - var scratchPackOrthographic = new OrthographicFrustum(); - var scratchPackQuaternion = new Quaternion(); - var scratchPackorigin = new Cartesian3(); + return 1 - ( --k * k * k * k ); - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {FrustumOutlineGeometry} [result] The object into which to store the result. - */ - FrustumOutlineGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + }, - var frustumType = array[startingIndex++]; + InOut: function ( k ) { - var frustum; - if (frustumType === PERSPECTIVE) { - frustum = PerspectiveFrustum.unpack(array, startingIndex, scratchPackPerspective); - startingIndex += PerspectiveFrustum.packedLength; - } else { - frustum = OrthographicFrustum.unpack(array, startingIndex, scratchPackOrthographic); - startingIndex += OrthographicFrustum.packedLength; - } + if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k; + return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 ); - var origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin); - startingIndex += Cartesian3.packedLength; - var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); - startingIndex += Quaternion.packedLength; - var drawNearPlane = array[startingIndex] === 1.0; + } - if (!defined(result)) { - return new FrustumOutlineGeometry({ - frustum : frustum, - origin : origin, - orientation : orientation, - _drawNearPlane : drawNearPlane - }); - } + }, - var frustumResult = frustumType === result._frustumType ? result._frustum : undefined; - result._frustum = frustum.clone(frustumResult); + Quintic: { - result._frustumType = frustumType; - result._origin = Cartesian3.clone(origin, result._origin); - result._orientation = Quaternion.clone(orientation, result._orientation); - result._drawNearPlane = drawNearPlane; + In: function ( k ) { - return result; - }; + return k * k * k * k * k; - /** - * Computes the geometric representation of a frustum outline, including its vertices, indices, and a bounding sphere. - * - * @param {FrustumOutlineGeometry} frustumGeometry A description of the frustum. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - FrustumOutlineGeometry.createGeometry = function(frustumGeometry) { - var frustumType = frustumGeometry._frustumType; - var frustum = frustumGeometry._frustum; - var origin = frustumGeometry._origin; - var orientation = frustumGeometry._orientation; - var drawNearPlane = frustumGeometry._drawNearPlane; + }, - var positions = new Float64Array(3 * 4 * 2); - FrustumGeometry._computeNearFarPlanes(origin, orientation, frustumType, frustum, positions); + Out: function ( k ) { - var attributes = new GeometryAttributes({ - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }) - }); + return --k * k * k * k * k + 1; - var offset; - var index; + }, - var numberOfPlanes = drawNearPlane ? 2 : 1; - var indices = new Uint16Array(8 * (numberOfPlanes + 1)); + InOut: function ( k ) { - // Build the near/far planes - var i = drawNearPlane ? 0 : 1; - for (; i < 2; ++i) { - offset = drawNearPlane ? i * 8 : 0; - index = i * 4; + if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k; + return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 ); - indices[offset] = index; - indices[offset + 1] = index + 1; - indices[offset + 2] = index + 1; - indices[offset + 3] = index + 2; - indices[offset + 4] = index + 2; - indices[offset + 5] = index + 3; - indices[offset + 6] = index + 3; - indices[offset + 7] = index; - } + } - // Build the sides of the frustums - for (i = 0; i < 2; ++i) { - offset = (numberOfPlanes + i) * 8; - index = i * 4; + }, - indices[offset] = index; - indices[offset + 1] = index + 4; - indices[offset + 2] = index + 1; - indices[offset + 3] = index + 5; - indices[offset + 4] = index + 2; - indices[offset + 5] = index + 6; - indices[offset + 6] = index + 3; - indices[offset + 7] = index + 7; - } + Sinusoidal: { - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : BoundingSphere.fromVertices(positions) - }); - }; + In: function ( k ) { - return FrustumOutlineGeometry; -}); + return 1 - Math.cos( k * Math.PI / 2 ); -define('Core/GeocoderService',[ - './DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + }, - /** - * @typedef {Object} GeocoderResult - * @property {String} displayName The display name for a location - * @property {Rectangle|Cartesian3} destination The bounding box for a location - */ + Out: function ( k ) { - /** - * Provides geocoding through an external service. This type describes an interface and - * is not intended to be used. - * @alias GeocoderService - * @constructor - * - * @see BingMapsGeocoderService - */ - function GeocoderService() { - } + return Math.sin( k * Math.PI / 2 ); - /** - * @function - * - * @param {String} query The query to be sent to the geocoder service - * @returns {Promise<GeocoderResult[]>} - */ - GeocoderService.prototype.geocode = DeveloperError.throwInstantiationError; + }, - return GeocoderService; -}); + InOut: function ( k ) { -define('Core/GeometryInstanceAttribute',[ - './defaultValue', - './defined', - './DeveloperError' - ], function( - defaultValue, - defined, - DeveloperError) { - 'use strict'; + return 0.5 * ( 1 - Math.cos( Math.PI * k ) ); - /** - * Values and type information for per-instance geometry attributes. - * - * @alias GeometryInstanceAttribute - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {ComponentDatatype} [options.componentDatatype] The datatype of each component in the attribute, e.g., individual elements in values. - * @param {Number} [options.componentsPerAttribute] A number between 1 and 4 that defines the number of components in an attributes. - * @param {Boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * @param {Number[]} [options.value] The value for the attribute. - * - * @exception {DeveloperError} options.componentsPerAttribute must be between 1 and 4. - * - * - * @example - * var instance = new Cesium.GeometryInstance({ - * geometry : Cesium.BoxGeometry.fromDimensions({ - * dimensions : new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0) - * }), - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(0.0, 0.0)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), - * id : 'box', - * attributes : { - * color : new Cesium.GeometryInstanceAttribute({ - * componentDatatype : Cesium.ComponentDatatype.UNSIGNED_BYTE, - * componentsPerAttribute : 4, - * normalize : true, - * value : [255, 255, 0, 255] - * }) - * } - * }); - * - * @see ColorGeometryInstanceAttribute - * @see ShowGeometryInstanceAttribute - * @see DistanceDisplayConditionGeometryInstanceAttribute - */ - function GeometryInstanceAttribute(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + } - if (!defined(options.componentDatatype)) { - throw new DeveloperError('options.componentDatatype is required.'); - } - if (!defined(options.componentsPerAttribute)) { - throw new DeveloperError('options.componentsPerAttribute is required.'); - } - if (options.componentsPerAttribute < 1 || options.componentsPerAttribute > 4) { - throw new DeveloperError('options.componentsPerAttribute must be between 1 and 4.'); - } - if (!defined(options.value)) { - throw new DeveloperError('options.value is required.'); - } - - /** - * The datatype of each component in the attribute, e.g., individual elements in - * {@link GeometryInstanceAttribute#value}. - * - * @type ComponentDatatype - * - * @default undefined - */ - this.componentDatatype = options.componentDatatype; + }, - /** - * A number between 1 and 4 that defines the number of components in an attributes. - * For example, a position attribute with x, y, and z components would have 3 as - * shown in the code example. - * - * @type Number - * - * @default undefined - * - * @example - * show : new Cesium.GeometryInstanceAttribute({ - * componentDatatype : Cesium.ComponentDatatype.UNSIGNED_BYTE, - * componentsPerAttribute : 1, - * normalize : true, - * value : [1.0] - * }) - */ - this.componentsPerAttribute = options.componentsPerAttribute; + Exponential: { - /** - * When <code>true</code> and <code>componentDatatype</code> is an integer format, - * indicate that the components should be mapped to the range [0, 1] (unsigned) - * or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * <p> - * This is commonly used when storing colors using {@link ComponentDatatype.UNSIGNED_BYTE}. - * </p> - * - * @type Boolean - * - * @default false - * - * @example - * attribute.componentDatatype = Cesium.ComponentDatatype.UNSIGNED_BYTE; - * attribute.componentsPerAttribute = 4; - * attribute.normalize = true; - * attribute.value = [ - * Cesium.Color.floatToByte(color.red), - * Cesium.Color.floatToByte(color.green), - * Cesium.Color.floatToByte(color.blue), - * Cesium.Color.floatToByte(color.alpha) - * ]; - */ - this.normalize = defaultValue(options.normalize, false); + In: function ( k ) { - /** - * The values for the attributes stored in a typed array. In the code example, - * every three elements in <code>values</code> defines one attributes since - * <code>componentsPerAttribute</code> is 3. - * - * @type {Number[]} - * - * @default undefined - * - * @example - * show : new Cesium.GeometryInstanceAttribute({ - * componentDatatype : Cesium.ComponentDatatype.UNSIGNED_BYTE, - * componentsPerAttribute : 1, - * normalize : true, - * value : [1.0] - * }) - */ - this.value = options.value; - } + return k === 0 ? 0 : Math.pow( 1024, k - 1 ); - return GeometryInstanceAttribute; -}); + }, -define('Core/getBaseUri',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + Out: function ( k ) { - /** - * Given a URI, returns the base path of the URI. - * @exports getBaseUri - * - * @param {String} uri The Uri. - * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri - * @returns {String} The base path of the Uri. - * - * @example - * // basePath will be "/Gallery/"; - * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); - * - * // basePath will be "/Gallery/?value=true&example=false"; - * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); - */ - function getBaseUri(uri, includeQuery) { - if (!defined(uri)) { - throw new DeveloperError('uri is required.'); - } - - var basePath = ''; - var i = uri.lastIndexOf('/'); - if (i !== -1) { - basePath = uri.substring(0, i + 1); - } + return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k ); - if (!includeQuery) { - return basePath; - } + }, - uri = new Uri(uri); - if (defined(uri.query)) { - basePath += '?' + uri.query; - } - if (defined(uri.fragment)){ - basePath += '#' + uri.fragment; - } + InOut: function ( k ) { - return basePath; - } + 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 ); - return getBaseUri; -}); + } -define('Core/getExtensionFromUri',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + }, - /** - * Given a URI, returns the extension of the URI. - * @exports getExtensionFromUri - * - * @param {String} uri The Uri. - * @returns {String} The extension of the Uri. - * - * @example - * //extension will be "czml"; - * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); - */ - function getExtensionFromUri(uri) { - if (!defined(uri)) { - throw new DeveloperError('uri is required.'); - } - - var uriObject = new Uri(uri); - uriObject.normalize(); - var path = uriObject.path; - var index = path.lastIndexOf('/'); - if (index !== -1) { - path = path.substr(index + 1); - } - index = path.lastIndexOf('.'); - if (index === -1) { - path = ''; - } else { - path = path.substr(index + 1); - } - return path; - } + Circular: { - return getExtensionFromUri; -}); + In: function ( k ) { -define('Core/getFilenameFromUri',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + return 1 - Math.sqrt( 1 - k * k ); - /** - * Given a URI, returns the last segment of the URI, removing any path or query information. - * @exports getFilenameFromUri - * - * @param {String} uri The Uri. - * @returns {String} The last segment of the Uri. - * - * @example - * //fileName will be"simple.czml"; - * var fileName = Cesium.getFilenameFromUri('/Gallery/simple.czml?value=true&example=false'); - */ - function getFilenameFromUri(uri) { - if (!defined(uri)) { - throw new DeveloperError('uri is required.'); - } - - var uriObject = new Uri(uri); - uriObject.normalize(); - var path = uriObject.path; - var index = path.lastIndexOf('/'); - if (index !== -1) { - path = path.substr(index + 1); - } - return path; - } + }, - return getFilenameFromUri; -}); + Out: function ( k ) { -define('Core/getImagePixels',[ - './defined' - ], function( - defined) { - 'use strict'; + return Math.sqrt( 1 - ( --k * k ) ); - var context2DsByWidthAndHeight = {}; + }, - /** - * Extract a pixel array from a loaded image. Draws the image - * into a canvas so it can read the pixels back. - * - * @exports getImagePixels - * - * @param {Image} image The image to extract pixels from. - * @param {Number} width The width of the image. If not defined, then image.width is assigned. - * @param {Number} height The height of the image. If not defined, then image.height is assigned. - * @returns {CanvasPixelArray} The pixels of the image. - */ - function getImagePixels(image, width, height) { - if (!defined(width)) { - width = image.width; - } - if (!defined(height)) { - height = image.height; - } + InOut: function ( k ) { - var context2DsByHeight = context2DsByWidthAndHeight[width]; - if (!defined(context2DsByHeight)) { - context2DsByHeight = {}; - context2DsByWidthAndHeight[width] = context2DsByHeight; - } + if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1); + return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1); - var context2d = context2DsByHeight[height]; - if (!defined(context2d)) { - var canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - context2d = canvas.getContext('2d'); - context2d.globalCompositeOperation = 'copy'; - context2DsByHeight[height] = context2d; - } + } - context2d.drawImage(image, 0, 0, width, height); - return context2d.getImageData(0, 0, width, height).data; - } + }, - return getImagePixels; -}); + Elastic: { -define('Core/getStringFromTypedArray',[ - './defaultValue', - './defined', - './DeveloperError', - './RuntimeError' - ], function( - defaultValue, - defined, - DeveloperError, - RuntimeError) { - 'use strict'; + In: function ( k ) { - /** - * @private - */ - function getStringFromTypedArray(uint8Array, byteOffset, byteLength) { - if (!defined(uint8Array)) { - throw new DeveloperError('uint8Array is required.'); - } - if (byteOffset < 0) { - throw new DeveloperError('byteOffset cannot be negative.'); - } - if (byteLength < 0) { - throw new DeveloperError('byteLength cannot be negative.'); - } - if ((byteOffset + byteLength) > uint8Array.byteLength) { - throw new DeveloperError('sub-region exceeds array bounds.'); - } - - byteOffset = defaultValue(byteOffset, 0); - byteLength = defaultValue(byteLength, uint8Array.byteLength - byteOffset); + 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 ) ); - uint8Array = uint8Array.subarray(byteOffset, byteOffset + byteLength); + }, - return getStringFromTypedArray.decode(uint8Array); - } + Out: function ( k ) { - // Exposed functions for testing - getStringFromTypedArray.decodeWithTextDecoder = function(view) { - var decoder = new TextDecoder('utf-8'); - return decoder.decode(view); - }; + 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; - getStringFromTypedArray.decodeWithFromCharCode = function(view) { - var result = ''; - var codePoints = utf8Handler(view); - var length = codePoints.length; - for (var i = 0; i < length; ++i) { - var cp = codePoints[i]; - if (cp <= 0xFFFF) { - result += String.fromCharCode(cp); - } else { - cp -= 0x10000; - result += String.fromCharCode((cp >> 10) + 0xD800, - (cp & 0x3FF) + 0xDC00); } - } - return result; - }; + }, - function inRange(a, min, max) { - return min <= a && a <= max; - } + Back: { - // This code is inspired by public domain code found here: https://github.com/inexorabletash/text-encoding - function utf8Handler(utfBytes) { - var codePoint = 0; - var bytesSeen = 0; - var bytesNeeded = 0; - var lowerBoundary = 0x80; - var upperBoundary = 0xBF; + In: function ( k ) { - var codePoints = []; - var length = utfBytes.length; - for (var i = 0; i < length; ++i) { - var currentByte = utfBytes[i]; + var s = 1.70158; + return k * k * ( ( s + 1 ) * k - s ); - // If bytesNeeded = 0, then we are starting a new character - if (bytesNeeded === 0) { - // 1 Byte Ascii character - if (inRange(currentByte, 0x00, 0x7F)) { - // Return a code point whose value is byte. - codePoints.push(currentByte); - continue; - } + }, - // 2 Byte character - if (inRange(currentByte, 0xC2, 0xDF)) { - bytesNeeded = 1; - codePoint = currentByte & 0x1F; - continue; - } + Out: function ( k ) { - // 3 Byte character - if (inRange(currentByte, 0xE0, 0xEF)) { - // If byte is 0xE0, set utf-8 lower boundary to 0xA0. - if (currentByte === 0xE0) { - lowerBoundary = 0xA0; - } - // If byte is 0xED, set utf-8 upper boundary to 0x9F. - if (currentByte === 0xED) { - upperBoundary = 0x9F; - } + var s = 1.70158; + return --k * k * ( ( s + 1 ) * k + s ) + 1; - bytesNeeded = 2; - codePoint = currentByte & 0xF; - continue; - } + }, - // 4 Byte character - if (inRange(currentByte, 0xF0, 0xF4)) { - // If byte is 0xF0, set utf-8 lower boundary to 0x90. - if (currentByte === 0xF0) { - lowerBoundary = 0x90; - } - // If byte is 0xF4, set utf-8 upper boundary to 0x8F. - if (currentByte === 0xF4) { - upperBoundary = 0x8F; - } + InOut: function ( k ) { - bytesNeeded = 3; - codePoint = currentByte & 0x7; - continue; - } + 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 ); - throw new RuntimeError('String decoding failed.'); } - // Out of range, so ignore the first part(s) of the character and continue with this byte on its own - if (!inRange(currentByte, lowerBoundary, upperBoundary)) { - codePoint = bytesNeeded = bytesSeen = 0; - lowerBoundary = 0x80; - upperBoundary = 0xBF; - --i; - continue; - } + }, - // Set appropriate boundaries, since we've now checked byte 2 of a potential longer character - lowerBoundary = 0x80; - upperBoundary = 0xBF; + Bounce: { - // Add byte to code point - codePoint = (codePoint << 6) | (currentByte & 0x3F); + In: function ( k ) { - // We have the correct number of bytes, so push and reset for next character - ++bytesSeen; - if (bytesSeen === bytesNeeded) { - codePoints.push(codePoint); - codePoint = bytesNeeded = bytesSeen = 0; - } - } + return 1 - TWEEN.Easing.Bounce.Out( 1 - k ); - return codePoints; - } + }, - if (typeof TextDecoder !== 'undefined') { - getStringFromTypedArray.decode = getStringFromTypedArray.decodeWithTextDecoder; - } else { - getStringFromTypedArray.decode = getStringFromTypedArray.decodeWithFromCharCode; - } + Out: function ( k ) { - return getStringFromTypedArray; -}); + if ( k < ( 1 / 2.75 ) ) { -define('Core/getMagic',[ - './defaultValue', - './getStringFromTypedArray' - ], function( - defaultValue, - getStringFromTypedArray) { - 'use strict'; + return 7.5625 * k * k; - /** - * @private - */ - function getMagic(uint8Array, byteOffset) { - byteOffset = defaultValue(byteOffset, 0); - return getStringFromTypedArray(uint8Array, byteOffset, Math.min(4, uint8Array.length)); - } + } else if ( k < ( 2 / 2.75 ) ) { - return getMagic; -}); + return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; -/*! - * protobuf.js v6.7.0 (c) 2016, Daniel Wirtz - * Compiled Wed, 22 Mar 2017 17:30:26 UTC - * Licensed under the BSD-3-Clause License - * see: https://github.com/dcodeIO/protobuf.js for details - */ -(function(global,undefined){"use strict";(function prelude(modules, cache, entries) { + } else if ( k < ( 2.5 / 2.75 ) ) { - // This is the prelude used to bundle protobuf.js for the browser. Wraps up the CommonJS - // sources through a conflict-free require shim and is again wrapped within an iife that - // provides a unified `global` and a minification-friendly `undefined` var plus a global - // "use strict" directive so that minification can remove the directives of each module. + return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; - function $require(name) { - var $module = cache[name]; - if (!$module) - modules[name][0].call($module = cache[name] = { exports: {} }, $require, $module, $module.exports); - return $module.exports; - } + } else { - // Expose globally - var protobuf = global.protobuf = $require(entries[0]); + return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; - // Be nice to AMD - if (typeof define === "function" && define.amd) - define('ThirdParty/protobuf-minimal',[], function() { - protobuf.configure(); - return protobuf; - }); + } - // Be nice to CommonJS - if (typeof module === "object" && module && module.exports) - module.exports = protobuf; + }, -})/* end of prelude */({1:[function(require,module,exports){ -"use strict"; -module.exports = asPromise; + 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; -/** - * Returns a promise from a node-style callback function. - * @memberof util - * @param {function(?Error, ...*)} fn Function to call - * @param {*} ctx Function context - * @param {...*} params Function arguments - * @returns {Promise<*>} Promisified function - */ -function asPromise(fn, ctx/*, varargs */) { - var params = []; - for (var i = 2; i < arguments.length;) - params.push(arguments[i++]); - var pending = true; - return new Promise(function asPromiseExecutor(resolve, reject) { - params.push(function asPromiseCallback(err/*, varargs */) { - if (pending) { - pending = false; - if (err) - reject(err); - else { - var args = []; - for (var i = 1; i < arguments.length;) - args.push(arguments[i++]); - resolve.apply(null, args); - } - } - }); - try { - fn.apply(ctx || this, params); // eslint-disable-line no-invalid-this - } catch (err) { - if (pending) { - pending = false; - reject(err); } - } - }); -} -},{}],2:[function(require,module,exports){ -"use strict"; + } -/** - * A minimal base64 implementation for number arrays. - * @memberof util - * @namespace - */ -var base64 = exports; + }; -/** - * Calculates the byte length of a base64 encoded string. - * @param {string} string Base64 encoded string - * @returns {number} Byte length - */ -base64.length = function length(string) { - var p = string.length; - if (!p) - return 0; - var n = 0; - while (--p % 4 > 1 && string.charAt(p) === "=") - ++n; - return Math.ceil(string.length * 3) / 4 - n; -}; + TWEEN.Interpolation = { -// Base64 encoding table -var b64 = new Array(64); + Linear: function ( v, k ) { -// Base64 decoding table -var s64 = new Array(123); + var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.Linear; -// 65..90, 97..122, 48..57, 43, 47 -for (var i = 0; i < 64;) - s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; + if ( k < 0 ) return fn( v[ 0 ], v[ 1 ], f ); + if ( k > 1 ) return fn( v[ m ], v[ m - 1 ], m - f ); -/** - * Encodes a buffer to a base64 encoded string. - * @param {Uint8Array} buffer Source buffer - * @param {number} start Source start - * @param {number} end Source end - * @returns {string} Base64 encoded string - */ -base64.encode = function encode(buffer, start, end) { - var string = []; // alt: new Array(Math.ceil((end - start) / 3) * 4); - var i = 0, // output index - j = 0, // goto index - t; // temporary - while (start < end) { - var b = buffer[start++]; - switch (j) { - case 0: - string[i++] = b64[b >> 2]; - t = (b & 3) << 4; - j = 1; - break; - case 1: - string[i++] = b64[t | b >> 4]; - t = (b & 15) << 2; - j = 2; - break; - case 2: - string[i++] = b64[t | b >> 6]; - string[i++] = b64[b & 63]; - j = 0; - break; - } - } - if (j) { - string[i++] = b64[t]; - string[i ] = 61; - if (j === 1) - string[i + 1] = 61; - } - return String.fromCharCode.apply(String, string); -}; + return fn( v[ i ], v[ i + 1 > m ? m : i + 1 ], f - i ); -var invalidEncoding = "invalid encoding"; + }, -/** - * Decodes a base64 encoded string to a buffer. - * @param {string} string Source string - * @param {Uint8Array} buffer Destination buffer - * @param {number} offset Destination offset - * @returns {number} Number of bytes written - * @throws {Error} If encoding is invalid - */ -base64.decode = function decode(string, buffer, offset) { - var start = offset; - var j = 0, // goto index - t; // temporary - for (var i = 0; i < string.length;) { - var c = string.charCodeAt(i++); - if (c === 61 && j > 1) - break; - if ((c = s64[c]) === undefined) - throw Error(invalidEncoding); - switch (j) { - case 0: - t = c; - j = 1; - break; - case 1: - buffer[offset++] = t << 2 | (c & 48) >> 4; - t = c; - j = 2; - break; - case 2: - buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2; - t = c; - j = 3; - break; - case 3: - buffer[offset++] = (t & 3) << 6 | c; - j = 0; - break; - } - } - if (j === 1) - throw Error(invalidEncoding); - return offset - start; -}; + Bezier: function ( v, k ) { -/** - * Tests if the specified string appears to be base64 encoded. - * @param {string} string String to test - * @returns {boolean} `true` if probably base64 encoded, otherwise false - */ -base64.test = function test(string) { - return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string); -}; + var b = 0, n = v.length - 1, pw = Math.pow, bn = TWEEN.Interpolation.Utils.Bernstein, i; -},{}],3:[function(require,module,exports){ -"use strict"; -module.exports = EventEmitter; + for ( i = 0; i <= n; i++ ) { + b += pw( 1 - k, n - i ) * pw( k, i ) * v[ i ] * bn( n, i ); + } -/** - * Constructs a new event emitter instance. - * @classdesc A minimal event emitter. - * @memberof util - * @constructor - */ -function EventEmitter() { + return b; - /** - * Registered listeners. - * @type {Object.<string,*>} - * @private - */ - this._listeners = {}; -} + }, -/** - * Registers an event listener. - * @param {string} evt Event name - * @param {function} fn Listener - * @param {*} [ctx] Listener context - * @returns {util.EventEmitter} `this` - */ -EventEmitter.prototype.on = function on(evt, fn, ctx) { - (this._listeners[evt] || (this._listeners[evt] = [])).push({ - fn : fn, - ctx : ctx || this - }); - return this; -}; + CatmullRom: function ( v, k ) { -/** - * Removes an event listener or any matching listeners if arguments are omitted. - * @param {string} [evt] Event name. Removes all listeners if omitted. - * @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted. - * @returns {util.EventEmitter} `this` - */ -EventEmitter.prototype.off = function off(evt, fn) { - if (evt === undefined) - this._listeners = {}; - else { - if (fn === undefined) - this._listeners[evt] = []; - else { - var listeners = this._listeners[evt]; - for (var i = 0; i < listeners.length;) - if (listeners[i].fn === fn) - listeners.splice(i, 1); - else - ++i; - } - } - return this; -}; + var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.CatmullRom; -/** - * Emits an event by calling its listeners with the specified arguments. - * @param {string} evt Event name - * @param {...*} args Arguments - * @returns {util.EventEmitter} `this` - */ -EventEmitter.prototype.emit = function emit(evt) { - var listeners = this._listeners[evt]; - if (listeners) { - var args = [], - i = 1; - for (; i < arguments.length;) - args.push(arguments[i++]); - for (i = 0; i < listeners.length;) - listeners[i].fn.apply(listeners[i++].ctx, args); - } - return this; -}; + if ( v[ 0 ] === v[ m ] ) { -},{}],4:[function(require,module,exports){ -"use strict"; -module.exports = inquire; + if ( k < 0 ) i = Math.floor( f = m * ( 1 + k ) ); -/** - * Requires a module only if available. - * @memberof util - * @param {string} moduleName Module to require - * @returns {?Object} Required module if available and not empty, otherwise `null` - */ -function inquire(moduleName) { - try { - var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval - if (mod && (mod.length || Object.keys(mod).length)) - return mod; - } catch (e) {} // eslint-disable-line no-empty - return null; -} + return fn( v[ ( i - 1 + m ) % m ], v[ i ], v[ ( i + 1 ) % m ], v[ ( i + 2 ) % m ], f - i ); -},{}],5:[function(require,module,exports){ -"use strict"; -module.exports = pool; + } else { -/** - * An allocator as used by {@link util.pool}. - * @typedef PoolAllocator - * @type {function} - * @param {number} size Buffer size - * @returns {Uint8Array} Buffer - */ + 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 ] ); -/** - * A slicer as used by {@link util.pool}. - * @typedef PoolSlicer - * @type {function} - * @param {number} start Start offset - * @param {number} end End offset - * @returns {Uint8Array} Buffer slice - * @this {Uint8Array} - */ + 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 ); -/** - * A general purpose buffer pool. - * @memberof util - * @function - * @param {PoolAllocator} alloc Allocator - * @param {PoolSlicer} slice Slicer - * @param {number} [size=8192] Slab size - * @returns {PoolAllocator} Pooled allocator - */ -function pool(alloc, slice, size) { - var SIZE = size || 8192; - var MAX = SIZE >>> 1; - var slab = null; - var offset = SIZE; - return function pool_alloc(size) { - if (size < 1 || size > MAX) - return alloc(size); - if (offset + size > SIZE) { - slab = alloc(SIZE); - offset = 0; - } - var buf = slice.call(slab, offset, offset += size); - if (offset & 7) // align to 32 bit - offset = (offset | 7) + 1; - return buf; - }; -} + } -},{}],6:[function(require,module,exports){ -"use strict"; + }, -/** - * A minimal UTF8 implementation for number arrays. - * @memberof util - * @namespace - */ -var utf8 = exports; + Utils: { -/** - * Calculates the UTF8 byte length of a string. - * @param {string} string String - * @returns {number} Byte length - */ -utf8.length = function utf8_length(string) { - var len = 0, - c = 0; - for (var i = 0; i < string.length; ++i) { - c = string.charCodeAt(i); - if (c < 128) - len += 1; - else if (c < 2048) - len += 2; - else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) { - ++i; - len += 4; - } else - len += 3; - } - return len; -}; + Linear: function ( p0, p1, t ) { -/** - * Reads UTF8 bytes as a string. - * @param {Uint8Array} buffer Source buffer - * @param {number} start Source start - * @param {number} end Source end - * @returns {string} String read - */ -utf8.read = function utf8_read(buffer, start, end) { - var len = end - start; - if (len < 1) - return ""; - var parts = null, - chunk = [], - i = 0, // char offset - t; // temporary - while (start < end) { - t = buffer[start++]; - if (t < 128) - chunk[i++] = t; - else if (t > 191 && t < 224) - chunk[i++] = (t & 31) << 6 | buffer[start++] & 63; - else if (t > 239 && t < 365) { - t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000; - chunk[i++] = 0xD800 + (t >> 10); - chunk[i++] = 0xDC00 + (t & 1023); - } else - chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63; - if (i > 8191) { - (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); - i = 0; - } - } - if (parts) { - if (i) - parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); - return parts.join(""); - } - return String.fromCharCode.apply(String, chunk.slice(0, i)); -}; + return ( p1 - p0 ) * t + p0; -/** - * Writes a string as UTF8 bytes. - * @param {string} string Source string - * @param {Uint8Array} buffer Destination buffer - * @param {number} offset Destination offset - * @returns {number} Bytes written - */ -utf8.write = function utf8_write(string, buffer, offset) { - var start = offset, - c1, // character 1 - c2; // character 2 - for (var i = 0; i < string.length; ++i) { - c1 = string.charCodeAt(i); - if (c1 < 128) { - buffer[offset++] = c1; - } else if (c1 < 2048) { - buffer[offset++] = c1 >> 6 | 192; - buffer[offset++] = c1 & 63 | 128; - } else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) { - c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF); - ++i; - buffer[offset++] = c1 >> 18 | 240; - buffer[offset++] = c1 >> 12 & 63 | 128; - buffer[offset++] = c1 >> 6 & 63 | 128; - buffer[offset++] = c1 & 63 | 128; - } else { - buffer[offset++] = c1 >> 12 | 224; - buffer[offset++] = c1 >> 6 & 63 | 128; - buffer[offset++] = c1 & 63 | 128; - } - } - return offset - start; -}; + }, -},{}],7:[function(require,module,exports){ -"use strict"; -var protobuf = exports; + Bernstein: function ( n , i ) { -/** - * Build type, one of `"full"`, `"light"` or `"minimal"`. - * @name build - * @type {string} - * @const - */ -protobuf.build = "minimal"; + var fc = TWEEN.Interpolation.Utils.Factorial; + return fc( n ) / fc( i ) / fc( n - i ); -/** - * Named roots. - * This is where pbjs stores generated structures (the option `-r, --root` specifies a name). - * Can also be used manually to make roots available accross modules. - * @name roots - * @type {Object.<string,Root>} - * @example - * // pbjs -r myroot -o compiled.js ... - * - * // in another module: - * require("./compiled.js"); - * - * // in any subsequent module: - * var root = protobuf.roots["myroot"]; - */ -protobuf.roots = {}; + }, -// Serialization -protobuf.Writer = require(14); -protobuf.BufferWriter = require(15); -protobuf.Reader = require(8); -protobuf.BufferReader = require(9); + Factorial: ( function () { -// Utility -protobuf.util = require(13); -protobuf.rpc = require(10); -protobuf.configure = configure; + var a = [ 1 ]; -/* istanbul ignore next */ -/** - * Reconfigures the library according to the environment. - * @returns {undefined} - */ -function configure() { - protobuf.Reader._configure(protobuf.BufferReader); - protobuf.util._configure(); -} + return function ( n ) { -// Configure serialization -protobuf.Writer._configure(protobuf.BufferWriter); -configure(); + var s = 1, i; + if ( a[ n ] ) return a[ n ]; + for ( i = n; i > 1; i-- ) s *= i; + return a[ n ] = s; -},{"10":10,"13":13,"14":14,"15":15,"8":8,"9":9}],8:[function(require,module,exports){ -"use strict"; -module.exports = Reader; + }; -var util = require(13); + } )(), -var BufferReader; // cyclic + CatmullRom: function ( p0, p1, p2, p3, t ) { -var LongBits = util.LongBits, - utf8 = util.utf8; + 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; -/* istanbul ignore next */ -function indexOutOfRange(reader, writeLength) { - return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len); -} + } -/** - * Constructs a new reader instance using the specified buffer. - * @classdesc Wire format reader using `Uint8Array` if available, otherwise `Array`. - * @constructor - * @param {Uint8Array} buffer Buffer to read from - */ -function Reader(buffer) { + } - /** - * Read buffer. - * @type {Uint8Array} - */ - this.buf = buffer; + }; - /** - * Read buffer position. - * @type {number} - */ - this.pos = 0; +return TWEEN; +}); + +define('Core/EasingFunction',[ + '../ThirdParty/Tween', + './freezeObject' + ], function( + Tween, + freezeObject) { + 'use strict'; /** - * Read buffer length. - * @type {number} + * Easing functions for use with {@link TweenCollection}. These function are from + * {@link https://github.com/sole/tween.js/|Tween.js} and Robert Penner. See the + * {@link http://sole.github.io/tween.js/examples/03_graphs.html|Tween.js graphs for each function}. + * + * @exports EasingFunction */ - this.len = buffer.length; -} + var EasingFunction = { + /** + * Linear easing. + * + * @type {EasingFunction~Callback} + * @constant + */ + LINEAR_NONE : Tween.Easing.Linear.None, -var create_array = typeof Uint8Array !== "undefined" - ? function create_typed_array(buffer) { - if (buffer instanceof Uint8Array || Array.isArray(buffer)) - return new Reader(buffer); - throw Error("illegal buffer"); - } - /* istanbul ignore next */ - : function create_array(buffer) { - if (Array.isArray(buffer)) - return new Reader(buffer); - throw Error("illegal buffer"); - }; + /** + * Quadratic in. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUADRACTIC_IN : Tween.Easing.Quadratic.In, + /** + * Quadratic out. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUADRACTIC_OUT : Tween.Easing.Quadratic.Out, + /** + * Quadratic in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUADRACTIC_IN_OUT : Tween.Easing.Quadratic.InOut, -/** - * Creates a new reader using the specified buffer. - * @function - * @param {Uint8Array|Buffer} buffer Buffer to read from - * @returns {Reader|BufferReader} A {@link BufferReader} if `buffer` is a Buffer, otherwise a {@link Reader} - * @throws {Error} If `buffer` is not a valid buffer - */ -Reader.create = util.Buffer - ? function create_buffer_setup(buffer) { - return (Reader.create = function create_buffer(buffer) { - return util.Buffer.isBuffer(buffer) - ? new BufferReader(buffer) - /* istanbul ignore next */ - : create_array(buffer); - })(buffer); - } - /* istanbul ignore next */ - : create_array; + /** + * Cubic in. + * + * @type {EasingFunction~Callback} + * @constant + */ + CUBIC_IN : Tween.Easing.Cubic.In, + /** + * Cubic out. + * + * @type {EasingFunction~Callback} + * @constant + */ + CUBIC_OUT : Tween.Easing.Cubic.Out, + /** + * Cubic in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + CUBIC_IN_OUT : Tween.Easing.Cubic.InOut, -Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice; + /** + * Quartic in. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUARTIC_IN : Tween.Easing.Quartic.In, + /** + * Quartic out. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUARTIC_OUT : Tween.Easing.Quartic.Out, + /** + * Quartic in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUARTIC_IN_OUT : Tween.Easing.Quartic.InOut, -/** - * Reads a varint as an unsigned 32 bit value. - * @function - * @returns {number} Value read - */ -Reader.prototype.uint32 = (function read_uint32_setup() { - var value = 4294967295; // optimizer type-hint, tends to deopt otherwise (?!) - return function read_uint32() { - value = ( this.buf[this.pos] & 127 ) >>> 0; if (this.buf[this.pos++] < 128) return value; - value = (value | (this.buf[this.pos] & 127) << 7) >>> 0; if (this.buf[this.pos++] < 128) return value; - value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; if (this.buf[this.pos++] < 128) return value; - value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; if (this.buf[this.pos++] < 128) return value; - value = (value | (this.buf[this.pos] & 15) << 28) >>> 0; if (this.buf[this.pos++] < 128) return value; + /** + * Quintic in. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUINTIC_IN : Tween.Easing.Quintic.In, + /** + * Quintic out. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUINTIC_OUT : Tween.Easing.Quintic.Out, + /** + * Quintic in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + QUINTIC_IN_OUT : Tween.Easing.Quintic.InOut, - /* istanbul ignore next */ - if ((this.pos += 5) > this.len) { - this.pos = this.len; - throw indexOutOfRange(this, 10); - } - return value; + /** + * Sinusoidal in. + * + * @type {EasingFunction~Callback} + * @constant + */ + SINUSOIDAL_IN : Tween.Easing.Sinusoidal.In, + /** + * Sinusoidal out. + * + * @type {EasingFunction~Callback} + * @constant + */ + SINUSOIDAL_OUT : Tween.Easing.Sinusoidal.Out, + /** + * Sinusoidal in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + SINUSOIDAL_IN_OUT : Tween.Easing.Sinusoidal.InOut, + + /** + * Exponential in. + * + * @type {EasingFunction~Callback} + * @constant + */ + EXPONENTIAL_IN : Tween.Easing.Exponential.In, + /** + * Exponential out. + * + * @type {EasingFunction~Callback} + * @constant + */ + EXPONENTIAL_OUT : Tween.Easing.Exponential.Out, + /** + * Exponential in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + EXPONENTIAL_IN_OUT : Tween.Easing.Exponential.InOut, + + /** + * Circular in. + * + * @type {EasingFunction~Callback} + * @constant + */ + CIRCULAR_IN : Tween.Easing.Circular.In, + /** + * Circular out. + * + * @type {EasingFunction~Callback} + * @constant + */ + CIRCULAR_OUT : Tween.Easing.Circular.Out, + /** + * Circular in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + CIRCULAR_IN_OUT : Tween.Easing.Circular.InOut, + + /** + * Elastic in. + * + * @type {EasingFunction~Callback} + * @constant + */ + ELASTIC_IN : Tween.Easing.Elastic.In, + /** + * Elastic out. + * + * @type {EasingFunction~Callback} + * @constant + */ + ELASTIC_OUT : Tween.Easing.Elastic.Out, + /** + * Elastic in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + ELASTIC_IN_OUT : Tween.Easing.Elastic.InOut, + + /** + * Back in. + * + * @type {EasingFunction~Callback} + * @constant + */ + BACK_IN : Tween.Easing.Back.In, + /** + * Back out. + * + * @type {EasingFunction~Callback} + * @constant + */ + BACK_OUT : Tween.Easing.Back.Out, + /** + * Back in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + BACK_IN_OUT : Tween.Easing.Back.InOut, + + /** + * Bounce in. + * + * @type {EasingFunction~Callback} + * @constant + */ + BOUNCE_IN : Tween.Easing.Bounce.In, + /** + * Bounce out. + * + * @type {EasingFunction~Callback} + * @constant + */ + BOUNCE_OUT : Tween.Easing.Bounce.Out, + /** + * Bounce in then out. + * + * @type {EasingFunction~Callback} + * @constant + */ + BOUNCE_IN_OUT : Tween.Easing.Bounce.InOut }; -})(); -/** - * Reads a varint as a signed 32 bit value. - * @returns {number} Value read - */ -Reader.prototype.int32 = function read_int32() { - return this.uint32() | 0; -}; + /** + * Function interface for implementing a custom easing function. + * @callback EasingFunction~Callback + * @param {Number} time The time in the range <code>[0, 1]</code>. + * @returns {Number} The value of the function at the given time. + * + * @example + * function quadraticIn(time) { + * return time * time; + * } + * + * @example + * function quadraticOut(time) { + * return time * (2.0 - time); + * } + */ -/** - * Reads a zig-zag encoded varint as a signed 32 bit value. - * @returns {number} Value read - */ -Reader.prototype.sint32 = function read_sint32() { - var value = this.uint32(); - return value >>> 1 ^ -(value & 1) | 0; -}; + return freezeObject(EasingFunction); +}); -/* eslint-disable no-invalid-this */ +define('Core/EllipsoidGeometry',[ + './BoundingSphere', + './Cartesian2', + './Cartesian3', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PrimitiveType', + './VertexFormat' + ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PrimitiveType, + VertexFormat) { + 'use strict'; -function readLongVarint() { - // tends to deopt with local vars for octet etc. - var bits = new LongBits(0, 0); - var i = 0; - if (this.len - this.pos > 4) { // fast route (lo) - for (; i < 4; ++i) { - // 1st..4th - bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; - if (this.buf[this.pos++] < 128) - return bits; + var scratchPosition = new Cartesian3(); + var scratchNormal = new Cartesian3(); + var scratchTangent = new Cartesian3(); + var scratchBitangent = new Cartesian3(); + var scratchNormalST = new Cartesian3(); + var defaultRadii = new Cartesian3(1.0, 1.0, 1.0); + + var cos = Math.cos; + var sin = Math.sin; + + /** + * A description of an ellipsoid centered at the origin. + * + * @alias EllipsoidGeometry + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions. + * @param {Number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. + * @param {Number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * + * @exception {DeveloperError} options.slicePartitions cannot be less than three. + * @exception {DeveloperError} options.stackPartitions cannot be less than three. + * + * @see EllipsoidGeometry#createGeometry + * + * @example + * var ellipsoid = new Cesium.EllipsoidGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, + * radii : new Cesium.Cartesian3(1000000.0, 500000.0, 500000.0) + * }); + * var geometry = Cesium.EllipsoidGeometry.createGeometry(ellipsoid); + */ + function EllipsoidGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var radii = defaultValue(options.radii, defaultRadii); + var stackPartitions = Math.round(defaultValue(options.stackPartitions, 64)); + var slicePartitions = Math.round(defaultValue(options.slicePartitions, 64)); + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + + if (slicePartitions < 3) { + throw new DeveloperError ('options.slicePartitions cannot be less than three.'); } - // 5th - bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0; - bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0; - if (this.buf[this.pos++] < 128) - return bits; - i = 0; - } else { - for (; i < 3; ++i) { - /* istanbul ignore next */ - if (this.pos >= this.len) - throw indexOutOfRange(this); - // 1st..3th - bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; - if (this.buf[this.pos++] < 128) - return bits; + if (stackPartitions < 3) { + throw new DeveloperError('options.stackPartitions cannot be less than three.'); } - // 4th - bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0; - return bits; + + this._radii = Cartesian3.clone(radii); + this._stackPartitions = stackPartitions; + this._slicePartitions = slicePartitions; + this._vertexFormat = VertexFormat.clone(vertexFormat); + this._workerName = 'createEllipsoidGeometry'; } - if (this.len - this.pos > 4) { // fast route (hi) - for (; i < 5; ++i) { - // 6th..10th - bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; - if (this.buf[this.pos++] < 128) - return bits; + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + EllipsoidGeometry.packedLength = Cartesian3.packedLength + VertexFormat.packedLength + 2; + + /** + * Stores the provided instance into the provided array. + * + * @param {EllipsoidGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + EllipsoidGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); } - } else { - for (; i < 5; ++i) { - /* istanbul ignore next */ - if (this.pos >= this.len) - throw indexOutOfRange(this); - // 6th..10th - bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; - if (this.buf[this.pos++] < 128) - return bits; + if (!defined(array)) { + throw new DeveloperError('array is required'); } - } - /* istanbul ignore next */ - throw Error("invalid varint encoding"); -} + + startingIndex = defaultValue(startingIndex, 0); -/* eslint-enable no-invalid-this */ + Cartesian3.pack(value._radii, array, startingIndex); + startingIndex += Cartesian3.packedLength; -/** - * Reads a varint as a signed 64 bit value. - * @name Reader#int64 - * @function - * @returns {Long|number} Value read - */ + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; -/** - * Reads a varint as an unsigned 64 bit value. - * @name Reader#uint64 - * @function - * @returns {Long|number} Value read - */ + array[startingIndex++] = value._stackPartitions; + array[startingIndex] = value._slicePartitions; -/** - * Reads a zig-zag encoded varint as a signed 64 bit value. - * @name Reader#sint64 - * @function - * @returns {Long|number} Value read - */ + return array; + }; -/** - * Reads a varint as a boolean. - * @returns {boolean} Value read - */ -Reader.prototype.bool = function read_bool() { - return this.uint32() !== 0; -}; + var scratchRadii = new Cartesian3(); + var scratchVertexFormat = new VertexFormat(); + var scratchOptions = { + radii : scratchRadii, + vertexFormat : scratchVertexFormat, + stackPartitions : undefined, + slicePartitions : undefined + }; -function readFixed32(buf, end) { - return (buf[end - 4] - | buf[end - 3] << 8 - | buf[end - 2] << 16 - | buf[end - 1] << 24) >>> 0; -} + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {EllipsoidGeometry} [result] The object into which to store the result. + * @returns {EllipsoidGeometry} The modified result parameter or a new EllipsoidGeometry instance if one was not provided. + */ + EllipsoidGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); -/** - * Reads fixed 32 bits as an unsigned 32 bit integer. - * @returns {number} Value read - */ -Reader.prototype.fixed32 = function read_fixed32() { + var radii = Cartesian3.unpack(array, startingIndex, scratchRadii); + startingIndex += Cartesian3.packedLength; - /* istanbul ignore next */ - if (this.pos + 4 > this.len) - throw indexOutOfRange(this, 4); + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; - return readFixed32(this.buf, this.pos += 4); -}; + var stackPartitions = array[startingIndex++]; + var slicePartitions = array[startingIndex]; -/** - * Reads fixed 32 bits as a signed 32 bit integer. - * @returns {number} Value read - */ -Reader.prototype.sfixed32 = function read_sfixed32() { + if (!defined(result)) { + scratchOptions.stackPartitions = stackPartitions; + scratchOptions.slicePartitions = slicePartitions; + return new EllipsoidGeometry(scratchOptions); + } - /* istanbul ignore next */ - if (this.pos + 4 > this.len) - throw indexOutOfRange(this, 4); + result._radii = Cartesian3.clone(radii, result._radii); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._stackPartitions = stackPartitions; + result._slicePartitions = slicePartitions; - return readFixed32(this.buf, this.pos += 4) | 0; -}; + return result; + }; -/* eslint-disable no-invalid-this */ + /** + * Computes the geometric representation of an ellipsoid, including its vertices, indices, and a bounding sphere. + * + * @param {EllipsoidGeometry} ellipsoidGeometry A description of the ellipsoid. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + EllipsoidGeometry.createGeometry = function(ellipsoidGeometry) { + var radii = ellipsoidGeometry._radii; -function readFixed64(/* this: Reader */) { + if ((radii.x <= 0) || (radii.y <= 0) || (radii.z <= 0)) { + return; + } - /* istanbul ignore next */ - if (this.pos + 8 > this.len) - throw indexOutOfRange(this, 8); + var ellipsoid = Ellipsoid.fromCartesian3(radii); + var vertexFormat = ellipsoidGeometry._vertexFormat; - return new LongBits(readFixed32(this.buf, this.pos += 4), readFixed32(this.buf, this.pos += 4)); -} + // The extra slice and stack are for duplicating points at the x axis and poles. + // We need the texture coordinates to interpolate from (2 * pi - delta) to 2 * pi instead of + // (2 * pi - delta) to 0. + var slicePartitions = ellipsoidGeometry._slicePartitions + 1; + var stackPartitions = ellipsoidGeometry._stackPartitions + 1; -/* eslint-enable no-invalid-this */ + var vertexCount = stackPartitions * slicePartitions; + var positions = new Float64Array(vertexCount * 3); -/** - * Reads fixed 64 bits. - * @name Reader#fixed64 - * @function - * @returns {Long|number} Value read - */ + var numIndices = 6 * (slicePartitions - 1) * (stackPartitions - 2); + var indices = IndexDatatype.createTypedArray(vertexCount, numIndices); -/** - * Reads zig-zag encoded fixed 64 bits. - * @name Reader#sfixed64 - * @function - * @returns {Long|number} Value read - */ + var normals = (vertexFormat.normal) ? new Float32Array(vertexCount * 3) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(vertexCount * 3) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(vertexCount * 3) : undefined; + var st = (vertexFormat.st) ? new Float32Array(vertexCount * 2) : undefined; -var readFloat = typeof Float32Array !== "undefined" - ? (function() { - var f32 = new Float32Array(1), - f8b = new Uint8Array(f32.buffer); - f32[0] = -0; - return f8b[3] // already le? - ? function readFloat_f32(buf, pos) { - f8b[0] = buf[pos ]; - f8b[1] = buf[pos + 1]; - f8b[2] = buf[pos + 2]; - f8b[3] = buf[pos + 3]; - return f32[0]; - } - /* istanbul ignore next */ - : function readFloat_f32_le(buf, pos) { - f8b[0] = buf[pos + 3]; - f8b[1] = buf[pos + 2]; - f8b[2] = buf[pos + 1]; - f8b[3] = buf[pos ]; - return f32[0]; - }; - })() - /* istanbul ignore next */ - : function readFloat_ieee754(buf, pos) { - var uint = readFixed32(buf, pos + 4), - sign = (uint >> 31) * 2 + 1, - exponent = uint >>> 23 & 255, - mantissa = uint & 8388607; - return exponent === 255 - ? mantissa - ? NaN - : sign * Infinity - : exponent === 0 // denormal - ? sign * 1.401298464324817e-45 * mantissa - : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608); - }; + var cosTheta = new Array(slicePartitions); + var sinTheta = new Array(slicePartitions); -/** - * Reads a float (32 bit) as a number. - * @function - * @returns {number} Value read - */ -Reader.prototype.float = function read_float() { + var i; + var j; + var index = 0; - /* istanbul ignore next */ - if (this.pos + 4 > this.len) - throw indexOutOfRange(this, 4); + for (i = 0; i < slicePartitions; i++) { + var theta = CesiumMath.TWO_PI * i / (slicePartitions - 1); + cosTheta[i] = cos(theta); + sinTheta[i] = sin(theta); - var value = readFloat(this.buf, this.pos); - this.pos += 4; - return value; -}; + // duplicate first point for correct + // texture coordinates at the north pole. + positions[index++] = 0.0; + positions[index++] = 0.0; + positions[index++] = radii.z; + } -var readDouble = typeof Float64Array !== "undefined" - ? (function() { - var f64 = new Float64Array(1), - f8b = new Uint8Array(f64.buffer); - f64[0] = -0; - return f8b[7] // already le? - ? function readDouble_f64(buf, pos) { - f8b[0] = buf[pos ]; - f8b[1] = buf[pos + 1]; - f8b[2] = buf[pos + 2]; - f8b[3] = buf[pos + 3]; - f8b[4] = buf[pos + 4]; - f8b[5] = buf[pos + 5]; - f8b[6] = buf[pos + 6]; - f8b[7] = buf[pos + 7]; - return f64[0]; + for (i = 1; i < stackPartitions - 1; i++) { + var phi = Math.PI * i / (stackPartitions - 1); + var sinPhi = sin(phi); + + var xSinPhi = radii.x * sinPhi; + var ySinPhi = radii.y * sinPhi; + var zCosPhi = radii.z * cos(phi); + + for (j = 0; j < slicePartitions; j++) { + positions[index++] = cosTheta[j] * xSinPhi; + positions[index++] = sinTheta[j] * ySinPhi; + positions[index++] = zCosPhi; } - /* istanbul ignore next */ - : function readDouble_f64_le(buf, pos) { - f8b[0] = buf[pos + 7]; - f8b[1] = buf[pos + 6]; - f8b[2] = buf[pos + 5]; - f8b[3] = buf[pos + 4]; - f8b[4] = buf[pos + 3]; - f8b[5] = buf[pos + 2]; - f8b[6] = buf[pos + 1]; - f8b[7] = buf[pos ]; - return f64[0]; - }; - })() - /* istanbul ignore next */ - : function readDouble_ieee754(buf, pos) { - var lo = readFixed32(buf, pos + 4), - hi = readFixed32(buf, pos + 8); - var sign = (hi >> 31) * 2 + 1, - exponent = hi >>> 20 & 2047, - mantissa = 4294967296 * (hi & 1048575) + lo; - return exponent === 2047 - ? mantissa - ? NaN - : sign * Infinity - : exponent === 0 // denormal - ? sign * 5e-324 * mantissa - : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496); - }; + } -/** - * Reads a double (64 bit float) as a number. - * @function - * @returns {number} Value read - */ -Reader.prototype.double = function read_double() { + for (i = 0; i < slicePartitions; i++) { + // duplicate first point for correct + // texture coordinates at the south pole. + positions[index++] = 0.0; + positions[index++] = 0.0; + positions[index++] = -radii.z; + } - /* istanbul ignore next */ - if (this.pos + 8 > this.len) - throw indexOutOfRange(this, 4); + var attributes = new GeometryAttributes(); - var value = readDouble(this.buf, this.pos); - this.pos += 8; - return value; -}; + if (vertexFormat.position) { + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); + } -/** - * Reads a sequence of bytes preceeded by its length as a varint. - * @returns {Uint8Array} Value read - */ -Reader.prototype.bytes = function read_bytes() { - var length = this.uint32(), - start = this.pos, - end = this.pos + length; + var stIndex = 0; + var normalIndex = 0; + var tangentIndex = 0; + var bitangentIndex = 0; - /* istanbul ignore next */ - if (end > this.len) - throw indexOutOfRange(this, length); + if (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { + for( i = 0; i < vertexCount; i++) { + var position = Cartesian3.fromArray(positions, i * 3, scratchPosition); + var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal); - this.pos += length; - return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1 - ? new this.buf.constructor(0) - : this._slice.call(this.buf, start, end); -}; + if (vertexFormat.st) { + var normalST = Cartesian2.negate(normal, scratchNormalST); -/** - * Reads a string preceeded by its byte length as a varint. - * @returns {string} Value read - */ -Reader.prototype.string = function read_string() { - var bytes = this.bytes(); - return utf8.read(bytes, 0, bytes.length); -}; + // if the point is at or close to the pole, find a point along the same longitude + // close to the xy-plane for the s coordinate. + if (Cartesian2.magnitude(normalST) < CesiumMath.EPSILON6) { + index = (i + slicePartitions * Math.floor(stackPartitions * 0.5)) * 3; + if (index > positions.length) { + index = (i - slicePartitions * Math.floor(stackPartitions * 0.5)) * 3; + } + Cartesian3.fromArray(positions, index, normalST); + ellipsoid.geodeticSurfaceNormal(normalST, normalST); + Cartesian2.negate(normalST, normalST); + } -/** - * Skips the specified number of bytes if specified, otherwise skips a varint. - * @param {number} [length] Length if known, otherwise a varint is assumed - * @returns {Reader} `this` - */ -Reader.prototype.skip = function skip(length) { - if (typeof length === "number") { - /* istanbul ignore next */ - if (this.pos + length > this.len) - throw indexOutOfRange(this, length); - this.pos += length; - } else { - /* istanbul ignore next */ - do { - if (this.pos >= this.len) - throw indexOutOfRange(this); - } while (this.buf[this.pos++] & 128); - } - return this; -}; + st[stIndex++] = (Math.atan2(normalST.y, normalST.x) / CesiumMath.TWO_PI) + 0.5; + st[stIndex++] = (Math.asin(normal.z) / Math.PI) + 0.5; + } -/** - * Skips the next element of the specified wire type. - * @param {number} wireType Wire type received - * @returns {Reader} `this` - */ -Reader.prototype.skipType = function(wireType) { - switch (wireType) { - case 0: - this.skip(); - break; - case 1: - this.skip(8); - break; - case 2: - this.skip(this.uint32()); - break; - case 3: - do { // eslint-disable-line no-constant-condition - if ((wireType = this.uint32() & 7) === 4) - break; - this.skipType(wireType); - } while (true); - break; - case 5: - this.skip(4); - break; + if (vertexFormat.normal) { + normals[normalIndex++] = normal.x; + normals[normalIndex++] = normal.y; + normals[normalIndex++] = normal.z; + } - /* istanbul ignore next */ - default: - throw Error("invalid wire type " + wireType + " at offset " + this.pos); - } - return this; -}; + if (vertexFormat.tangent || vertexFormat.bitangent) { + var tangent = scratchTangent; + if (i < slicePartitions || i > vertexCount - slicePartitions - 1) { + Cartesian3.cross(Cartesian3.UNIT_X, normal, tangent); + Cartesian3.normalize(tangent, tangent); + } else { + Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent); + Cartesian3.normalize(tangent, tangent); + } -Reader._configure = function(BufferReader_) { - BufferReader = BufferReader_; + if (vertexFormat.tangent) { + tangents[tangentIndex++] = tangent.x; + tangents[tangentIndex++] = tangent.y; + tangents[tangentIndex++] = tangent.z; + } - var fn = util.Long ? "toLong" : /* istanbul ignore next */ "toNumber"; - util.merge(Reader.prototype, { + if (vertexFormat.bitangent) { + var bitangent = Cartesian3.cross(normal, tangent, scratchBitangent); + Cartesian3.normalize(bitangent, bitangent); - int64: function read_int64() { - return readLongVarint.call(this)[fn](false); - }, + bitangents[bitangentIndex++] = bitangent.x; + bitangents[bitangentIndex++] = bitangent.y; + bitangents[bitangentIndex++] = bitangent.z; + } + } + } - uint64: function read_uint64() { - return readLongVarint.call(this)[fn](true); - }, + if (vertexFormat.st) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : st + }); + } - sint64: function read_sint64() { - return readLongVarint.call(this).zzDecode()[fn](false); - }, + if (vertexFormat.normal) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); + } - fixed64: function read_fixed64() { - return readFixed64.call(this)[fn](true); - }, + if (vertexFormat.tangent) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } - sfixed64: function read_sfixed64() { - return readFixed64.call(this)[fn](false); + if (vertexFormat.bitangent) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } } - }); -}; + index = 0; + for (j = 0; j < slicePartitions - 1; j++) { + indices[index++] = slicePartitions + j; + indices[index++] = slicePartitions + j + 1; + indices[index++] = j + 1; + } -},{"13":13}],9:[function(require,module,exports){ -"use strict"; -module.exports = BufferReader; + var topOffset; + var bottomOffset; + for (i = 1; i < stackPartitions - 2; i++) { + topOffset = i * slicePartitions; + bottomOffset = (i + 1) * slicePartitions; -// extends Reader -var Reader = require(8); -(BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader; + for (j = 0; j < slicePartitions - 1; j++) { + indices[index++] = bottomOffset + j; + indices[index++] = bottomOffset + j + 1; + indices[index++] = topOffset + j + 1; -var util = require(13); + indices[index++] = bottomOffset + j; + indices[index++] = topOffset + j + 1; + indices[index++] = topOffset + j; + } + } -/** - * Constructs a new buffer reader instance. - * @classdesc Wire format reader using node buffers. - * @extends Reader - * @constructor - * @param {Buffer} buffer Buffer to read from - */ -function BufferReader(buffer) { - Reader.call(this, buffer); + i = stackPartitions - 2; + topOffset = i * slicePartitions; + bottomOffset = (i + 1) * slicePartitions; + + for (j = 0; j < slicePartitions - 1; j++) { + indices[index++] = bottomOffset + j; + indices[index++] = topOffset + j + 1; + indices[index++] = topOffset + j; + } + + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : BoundingSphere.fromEllipsoid(ellipsoid) + }); + }; + + var unitEllipsoidGeometry; /** - * Read buffer. - * @name BufferReader#buf - * @type {Buffer} + * Returns the geometric representation of a unit ellipsoid, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private */ -} + EllipsoidGeometry.getUnitEllipsoid = function() { + if (!defined(unitEllipsoidGeometry)) { + unitEllipsoidGeometry = EllipsoidGeometry.createGeometry((new EllipsoidGeometry({ + radii : new Cartesian3(1.0, 1.0, 1.0), + vertexFormat : VertexFormat.POSITION_ONLY + }))); + } + return unitEllipsoidGeometry; + }; -/* istanbul ignore else */ -if (util.Buffer) - BufferReader.prototype._slice = util.Buffer.prototype.slice; + return EllipsoidGeometry; +}); -/** - * @override - */ -BufferReader.prototype.string = function read_string_buffer() { - var len = this.uint32(); // modifies pos - return this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)); -}; +define('Core/EllipsoidOutlineGeometry',[ + './BoundingSphere', + './Cartesian3', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PrimitiveType' + ], function( + BoundingSphere, + Cartesian3, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PrimitiveType) { + 'use strict'; -/** - * Reads a sequence of bytes preceeded by its length as a varint. - * @name BufferReader#bytes - * @function - * @returns {Buffer} Value read - */ + var defaultRadii = new Cartesian3(1.0, 1.0, 1.0); + var cos = Math.cos; + var sin = Math.sin; -},{"13":13,"8":8}],10:[function(require,module,exports){ -"use strict"; + /** + * A description of the outline of an ellipsoid centered at the origin. + * + * @alias EllipsoidOutlineGeometry + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions. + * @param {Number} [options.stackPartitions=10] The count of stacks for the ellipsoid (1 greater than the number of parallel lines). + * @param {Number} [options.slicePartitions=8] The count of slices for the ellipsoid (Equal to the number of radial lines). + * @param {Number} [options.subdivisions=128] The number of points per line, determining the granularity of the curvature. + * + * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one. + * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero. + * @exception {DeveloperError} options.subdivisions must be greater than or equal to zero. + * + * @example + * var ellipsoid = new Cesium.EllipsoidOutlineGeometry({ + * radii : new Cesium.Cartesian3(1000000.0, 500000.0, 500000.0), + * stackPartitions: 6, + * slicePartitions: 5 + * }); + * var geometry = Cesium.EllipsoidOutlineGeometry.createGeometry(ellipsoid); + */ + function EllipsoidOutlineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); -/** - * Streaming RPC helpers. - * @namespace - */ -var rpc = exports; + var radii = defaultValue(options.radii, defaultRadii); + var stackPartitions = Math.round(defaultValue(options.stackPartitions, 10)); + var slicePartitions = Math.round(defaultValue(options.slicePartitions, 8)); + var subdivisions = Math.round(defaultValue(options.subdivisions, 128)); -/** - * RPC implementation passed to {@link Service#create} performing a service request on network level, i.e. by utilizing http requests or websockets. - * @typedef RPCImpl - * @type {function} - * @param {Method|rpc.ServiceMethod} method Reflected or static method being called - * @param {Uint8Array} requestData Request data - * @param {RPCImplCallback} callback Callback function - * @returns {undefined} - * @example - * function rpcImpl(method, requestData, callback) { - * if (protobuf.util.lcFirst(method.name) !== "myMethod") // compatible with static code - * throw Error("no such method"); - * asynchronouslyObtainAResponse(requestData, function(err, responseData) { - * callback(err, responseData); - * }); - * } - */ + if (stackPartitions < 1) { + throw new DeveloperError('options.stackPartitions cannot be less than 1'); + } + if (slicePartitions < 0) { + throw new DeveloperError('options.slicePartitions cannot be less than 0'); + } + if (subdivisions < 0) { + throw new DeveloperError('options.subdivisions must be greater than or equal to zero.'); + } + + this._radii = Cartesian3.clone(radii); + this._stackPartitions = stackPartitions; + this._slicePartitions = slicePartitions; + this._subdivisions = subdivisions; + this._workerName = 'createEllipsoidOutlineGeometry'; + } -/** - * Node-style callback as used by {@link RPCImpl}. - * @typedef RPCImplCallback - * @type {function} - * @param {?Error} error Error, if any, otherwise `null` - * @param {?Uint8Array} [response] Response data or `null` to signal end of stream, if there hasn't been an error - * @returns {undefined} - */ + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + EllipsoidOutlineGeometry.packedLength = Cartesian3.packedLength + 3; -rpc.Service = require(11); + /** + * Stores the provided instance into the provided array. + * + * @param {EllipsoidOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + EllipsoidOutlineGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); -},{"11":11}],11:[function(require,module,exports){ -"use strict"; -module.exports = Service; + Cartesian3.pack(value._radii, array, startingIndex); + startingIndex += Cartesian3.packedLength; -var util = require(13); + array[startingIndex++] = value._stackPartitions; + array[startingIndex++] = value._slicePartitions; + array[startingIndex] = value._subdivisions; -// Extends EventEmitter -(Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service; + return array; + }; -/** - * A service method callback as used by {@link rpc.ServiceMethod|ServiceMethod}. - * - * Differs from {@link RPCImplCallback} in that it is an actual callback of a service method which may not return `response = null`. - * @typedef rpc.ServiceMethodCallback - * @type {function} - * @param {?Error} error Error, if any - * @param {?Message} [response] Response message - * @returns {undefined} - */ + var scratchRadii = new Cartesian3(); + var scratchOptions = { + radii : scratchRadii, + stackPartitions : undefined, + slicePartitions : undefined, + subdivisions : undefined + }; -/** - * A service method part of a {@link rpc.ServiceMethodMixin|ServiceMethodMixin} and thus {@link rpc.Service} as created by {@link Service.create}. - * @typedef rpc.ServiceMethod - * @type {function} - * @param {Message|Object.<string,*>} request Request message or plain object - * @param {rpc.ServiceMethodCallback} [callback] Node-style callback called with the error, if any, and the response message - * @returns {Promise<Message>} Promise if `callback` has been omitted, otherwise `undefined` - */ + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {EllipsoidOutlineGeometry} [result] The object into which to store the result. + * @returns {EllipsoidOutlineGeometry} The modified result parameter or a new EllipsoidOutlineGeometry instance if one was not provided. + */ + EllipsoidOutlineGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); -/** - * A service method mixin. - * - * When using TypeScript, mixed in service methods are only supported directly with a type definition of a static module (used with reflection). Otherwise, explicit casting is required. - * @typedef rpc.ServiceMethodMixin - * @type {Object.<string,rpc.ServiceMethod>} - * @example - * // Explicit casting with TypeScript - * (myRpcService["myMethod"] as protobuf.rpc.ServiceMethod)(...) - */ + var radii = Cartesian3.unpack(array, startingIndex, scratchRadii); + startingIndex += Cartesian3.packedLength; -/** - * Constructs a new RPC service instance. - * @classdesc An RPC service as returned by {@link Service#create}. - * @exports rpc.Service - * @extends util.EventEmitter - * @augments rpc.ServiceMethodMixin - * @constructor - * @param {RPCImpl} rpcImpl RPC implementation - * @param {boolean} [requestDelimited=false] Whether requests are length-delimited - * @param {boolean} [responseDelimited=false] Whether responses are length-delimited - */ -function Service(rpcImpl, requestDelimited, responseDelimited) { + var stackPartitions = array[startingIndex++]; + var slicePartitions = array[startingIndex++]; + var subdivisions = array[startingIndex++]; - if (typeof rpcImpl !== "function") - throw TypeError("rpcImpl must be a function"); + if (!defined(result)) { + scratchOptions.stackPartitions = stackPartitions; + scratchOptions.slicePartitions = slicePartitions; + scratchOptions.subdivisions = subdivisions; + return new EllipsoidOutlineGeometry(scratchOptions); + } - util.EventEmitter.call(this); + result._radii = Cartesian3.clone(radii, result._radii); + result._stackPartitions = stackPartitions; + result._slicePartitions = slicePartitions; + result._subdivisions = subdivisions; - /** - * RPC implementation. Becomes `null` once the service is ended. - * @type {?RPCImpl} - */ - this.rpcImpl = rpcImpl; + return result; + }; /** - * Whether requests are length-delimited. - * @type {boolean} + * Computes the geometric representation of an outline of an ellipsoid, including its vertices, indices, and a bounding sphere. + * + * @param {EllipsoidOutlineGeometry} ellipsoidGeometry A description of the ellipsoid outline. + * @returns {Geometry|undefined} The computed vertices and indices. */ - this.requestDelimited = Boolean(requestDelimited); + EllipsoidOutlineGeometry.createGeometry = function(ellipsoidGeometry) { + var radii = ellipsoidGeometry._radii; - /** - * Whether responses are length-delimited. - * @type {boolean} - */ - this.responseDelimited = Boolean(responseDelimited); -} + if ((radii.x <= 0) || (radii.y <= 0) || (radii.z <= 0)) { + return; + } -/** - * Calls a service method through {@link rpc.Service#rpcImpl|rpcImpl}. - * @param {Method|rpc.ServiceMethod} method Reflected or static method - * @param {function} requestCtor Request constructor - * @param {function} responseCtor Response constructor - * @param {Message|Object.<string,*>} request Request message or plain object - * @param {rpc.ServiceMethodCallback} callback Service callback - * @returns {undefined} - */ -Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) { + var ellipsoid = Ellipsoid.fromCartesian3(radii); + var stackPartitions = ellipsoidGeometry._stackPartitions; + var slicePartitions = ellipsoidGeometry._slicePartitions; + var subdivisions = ellipsoidGeometry._subdivisions; - if (!request) - throw TypeError("request must be specified"); + var indicesSize = subdivisions * (stackPartitions + slicePartitions - 1); + var positionSize = indicesSize - slicePartitions + 2; + var positions = new Float64Array(positionSize * 3); + var indices = IndexDatatype.createTypedArray(positionSize, indicesSize * 2); - var self = this; - if (!callback) - return util.asPromise(rpcCall, self, method, requestCtor, responseCtor, request); + var i; + var j; + var theta; + var phi; + var cosPhi; + var sinPhi; + var index = 0; - if (!self.rpcImpl) { - setTimeout(function() { callback(Error("already ended")); }, 0); - return undefined; - } + var cosTheta = new Array(subdivisions); + var sinTheta = new Array(subdivisions); + for (i = 0; i < subdivisions; i++) { + theta = CesiumMath.TWO_PI * i / subdivisions; + cosTheta[i] = cos(theta); + sinTheta[i] = sin(theta); + } - try { - return self.rpcImpl( - method, - requestCtor[self.requestDelimited ? "encodeDelimited" : "encode"](request).finish(), - function rpcCallback(err, response) { + for (i = 1; i < stackPartitions; i++) { + phi = Math.PI * i / stackPartitions; + cosPhi = cos(phi); + sinPhi = sin(phi); - if (err) { - self.emit("error", err, method); - return callback(err); - } + for (j = 0; j < subdivisions; j++) { + positions[index++] = radii.x * cosTheta[j] * sinPhi; + positions[index++] = radii.y * sinTheta[j] * sinPhi; + positions[index++] = radii.z * cosPhi; + } + } - if (response === null) { - self.end(/* endedByRPC */ true); - return undefined; - } + cosTheta.length = slicePartitions; + sinTheta.length = slicePartitions; + for (i = 0; i < slicePartitions; i++) { + theta = CesiumMath.TWO_PI * i / slicePartitions; + cosTheta[i] = cos(theta); + sinTheta[i] = sin(theta); + } - if (!(response instanceof responseCtor)) { - try { - response = responseCtor[self.responseDelimited ? "decodeDelimited" : "decode"](response); - } catch (err) { - self.emit("error", err, method); - return callback(err); - } - } + positions[index++] = 0; + positions[index++] = 0; + positions[index++] = radii.z; - self.emit("data", response, method); - return callback(null, response); + for (i = 1; i < subdivisions; i++) { + phi = Math.PI * i / subdivisions; + cosPhi = cos(phi); + sinPhi = sin(phi); + + for (j = 0; j < slicePartitions; j++) { + positions[index++] = radii.x * cosTheta[j] * sinPhi; + positions[index++] = radii.y * sinTheta[j] * sinPhi; + positions[index++] = radii.z * cosPhi; } - ); - } catch (err) { - self.emit("error", err, method); - setTimeout(function() { callback(err); }, 0); - return undefined; - } -}; + } -/** - * Ends this service and emits the `end` event. - * @param {boolean} [endedByRPC=false] Whether the service has been ended by the RPC implementation. - * @returns {rpc.Service} `this` - */ -Service.prototype.end = function end(endedByRPC) { - if (this.rpcImpl) { - if (!endedByRPC) // signal end to rpcImpl - this.rpcImpl(null, null, null); - this.rpcImpl = null; - this.emit("end").off(); - } - return this; -}; + positions[index++] = 0; + positions[index++] = 0; + positions[index++] = -radii.z; -},{"13":13}],12:[function(require,module,exports){ -"use strict"; -module.exports = LongBits; + index = 0; + for (i = 0; i < stackPartitions - 1; ++i) { + var topRowOffset = (i * subdivisions); + for (j = 0; j < subdivisions - 1; ++j) { + indices[index++] = topRowOffset + j; + indices[index++] = topRowOffset + j + 1; + } -var util = require(13); + indices[index++] = topRowOffset + subdivisions - 1; + indices[index++] = topRowOffset; + } -/** - * Any compatible Long instance. - * - * This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js. - * @typedef Long - * @type {Object} - * @property {number} low Low bits - * @property {number} high High bits - * @property {boolean} unsigned Whether unsigned or not - */ + var sliceOffset = subdivisions * (stackPartitions - 1); + for (j = 1; j < slicePartitions + 1; ++j) { + indices[index++] = sliceOffset; + indices[index++] = sliceOffset + j; + } -/** - * Constructs new long bits. - * @classdesc Helper class for working with the low and high bits of a 64 bit value. - * @memberof util - * @constructor - * @param {number} lo Low 32 bits, unsigned - * @param {number} hi High 32 bits, unsigned - */ -function LongBits(lo, hi) { + for (i = 0; i < subdivisions - 2; ++i) { + var topOffset = (i * slicePartitions) + 1 + sliceOffset; + var bottomOffset = ((i + 1) * slicePartitions) + 1 + sliceOffset; - // note that the casts below are theoretically unnecessary as of today, but older statically - // generated converter code might still call the ctor with signed 32bits. kept for compat. + for (j = 0; j < slicePartitions - 1; ++j) { + indices[index++] = bottomOffset + j; + indices[index++] = topOffset + j; + } - /** - * Low bits. - * @type {number} - */ - this.lo = lo >>> 0; + indices[index++] = bottomOffset + slicePartitions - 1; + indices[index++] = topOffset + slicePartitions - 1; + } - /** - * High bits. - * @type {number} - */ - this.hi = hi >>> 0; -} + var lastPosition = positions.length / 3 - 1; + for (j = lastPosition - 1; j > lastPosition - slicePartitions - 1; --j) { + indices[index++] = lastPosition; + indices[index++] = j; + } -/** - * Zero bits. - * @memberof util.LongBits - * @type {util.LongBits} - */ -var zero = LongBits.zero = new LongBits(0, 0); + var attributes = new GeometryAttributes({ + position: new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }) + }); -zero.toNumber = function() { return 0; }; -zero.zzEncode = zero.zzDecode = function() { return this; }; -zero.length = function() { return 1; }; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : BoundingSphere.fromEllipsoid(ellipsoid) + }); + }; -/** - * Zero hash. - * @memberof util.LongBits - * @type {string} - */ -var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0"; + return EllipsoidOutlineGeometry; +}); -/** - * Constructs new long bits from the specified number. - * @param {number} value Value - * @returns {util.LongBits} Instance - */ -LongBits.fromNumber = function fromNumber(value) { - if (value === 0) - return zero; - var sign = value < 0; - if (sign) - value = -value; - var lo = value >>> 0, - hi = (value - lo) / 4294967296 >>> 0; - if (sign) { - hi = ~hi >>> 0; - lo = ~lo >>> 0; - if (++lo > 4294967295) { - lo = 0; - if (++hi > 4294967295) - hi = 0; +define('Core/EllipsoidTerrainProvider',[ + '../ThirdParty/when', + './defaultValue', + './defined', + './defineProperties', + './Ellipsoid', + './Event', + './GeographicTilingScheme', + './HeightmapTerrainData', + './TerrainProvider' + ], function( + when, + defaultValue, + defined, + defineProperties, + Ellipsoid, + Event, + GeographicTilingScheme, + HeightmapTerrainData, + TerrainProvider) { + 'use strict'; + + /** + * A very simple {@link TerrainProvider} that produces geometry by tessellating an ellipsoidal + * surface. + * + * @alias EllipsoidTerrainProvider + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal + * surface is broken into tiles. If this parameter is not provided, a {@link GeographicTilingScheme} + * is used. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * + * @see TerrainProvider + */ + function EllipsoidTerrainProvider(options) { + options = defaultValue(options, {}); + + this._tilingScheme = options.tilingScheme; + if (!defined(this._tilingScheme)) { + this._tilingScheme = new GeographicTilingScheme({ + ellipsoid : defaultValue(options.ellipsoid, Ellipsoid.WGS84) + }); } - } - return new LongBits(lo, hi); -}; -/** - * Constructs new long bits from a number, long or string. - * @param {Long|number|string} value Value - * @returns {util.LongBits} Instance - */ -LongBits.from = function from(value) { - if (typeof value === "number") - return LongBits.fromNumber(value); - if (util.isString(value)) { - /* istanbul ignore else */ - if (util.Long) - value = util.Long.fromString(value); - else - return LongBits.fromNumber(parseInt(value, 10)); - } - return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero; -}; + // Note: the 64 below does NOT need to match the actual vertex dimensions, because + // the ellipsoid is significantly smoother than actual terrain. + this._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(this._tilingScheme.ellipsoid, 64, this._tilingScheme.getNumberOfXTilesAtLevel(0)); -/** - * Converts this long bits to a possibly unsafe JavaScript number. - * @param {boolean} [unsigned=false] Whether unsigned or not - * @returns {number} Possibly unsafe number - */ -LongBits.prototype.toNumber = function toNumber(unsigned) { - if (!unsigned && this.hi >>> 31) { - var lo = ~this.lo + 1 >>> 0, - hi = ~this.hi >>> 0; - if (!lo) - hi = hi + 1 >>> 0; - return -(lo + hi * 4294967296); + this._errorEvent = new Event(); + this._readyPromise = when.resolve(true); } - return this.lo + this.hi * 4294967296; -}; - -/** - * Converts this long bits to a long. - * @param {boolean} [unsigned=false] Whether unsigned or not - * @returns {Long} Long - */ -LongBits.prototype.toLong = function toLong(unsigned) { - return util.Long - ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) - /* istanbul ignore next */ - : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) }; -}; -var charCodeAt = String.prototype.charCodeAt; + defineProperties(EllipsoidTerrainProvider.prototype, { + /** + * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Event} + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, -/** - * Constructs new long bits from the specified 8 characters long hash. - * @param {string} hash Hash - * @returns {util.LongBits} Bits - */ -LongBits.fromHash = function fromHash(hash) { - if (hash === zeroHash) - return zero; - return new LongBits( - ( charCodeAt.call(hash, 0) - | charCodeAt.call(hash, 1) << 8 - | charCodeAt.call(hash, 2) << 16 - | charCodeAt.call(hash, 3) << 24) >>> 0 - , - ( charCodeAt.call(hash, 4) - | charCodeAt.call(hash, 5) << 8 - | charCodeAt.call(hash, 6) << 16 - | charCodeAt.call(hash, 7) << 24) >>> 0 - ); -}; + /** + * Gets the credit to display when this terrain provider is active. Typically this is used to credit + * the source of the terrain. This function should not be called before {@link EllipsoidTerrainProvider#ready} returns true. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Credit} + */ + credit : { + get : function() { + return undefined; + } + }, -/** - * Converts this long bits to a 8 characters long hash. - * @returns {string} Hash - */ -LongBits.prototype.toHash = function toHash() { - return String.fromCharCode( - this.lo & 255, - this.lo >>> 8 & 255, - this.lo >>> 16 & 255, - this.lo >>> 24 , - this.hi & 255, - this.hi >>> 8 & 255, - this.hi >>> 16 & 255, - this.hi >>> 24 - ); -}; + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link EllipsoidTerrainProvider#ready} returns true. + * @memberof EllipsoidTerrainProvider.prototype + * @type {GeographicTilingScheme} + */ + tilingScheme : { + get : function() { + return this._tilingScheme; + } + }, -/** - * Zig-zag encodes this long bits. - * @returns {util.LongBits} `this` - */ -LongBits.prototype.zzEncode = function zzEncode() { - var mask = this.hi >> 31; - this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0; - this.lo = ( this.lo << 1 ^ mask) >>> 0; - return this; -}; + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Boolean} + */ + ready : { + get : function() { + return true; + } + }, -/** - * Zig-zag decodes this long bits. - * @returns {util.LongBits} `this` - */ -LongBits.prototype.zzDecode = function zzDecode() { - var mask = -(this.lo & 1); - this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0; - this.hi = ( this.hi >>> 1 ^ mask) >>> 0; - return this; -}; + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise; + } + }, -/** - * Calculates the length of this longbits when encoded as a varint. - * @returns {number} Length - */ -LongBits.prototype.length = function length() { - var part0 = this.lo, - part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, - part2 = this.hi >>> 24; - return part2 === 0 - ? part1 === 0 - ? part0 < 16384 - ? part0 < 128 ? 1 : 2 - : part0 < 2097152 ? 3 : 4 - : part1 < 16384 - ? part1 < 128 ? 5 : 6 - : part1 < 2097152 ? 7 : 8 - : part2 < 128 ? 9 : 10; -}; + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link EllipsoidTerrainProvider#ready} returns true. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Boolean} + */ + hasWaterMask : { + get : function() { + return false; + } + }, -},{"13":13}],13:[function(require,module,exports){ -"use strict"; -var util = exports; + /** + * Gets a value indicating whether or not the requested tiles include vertex normals. + * This function should not be called before {@link EllipsoidTerrainProvider#ready} returns true. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { + get : function() { + return false; + } + } + }); -// used to return a Promise where callback is omitted -util.asPromise = require(1); + /** + * Requests the geometry for a given tile. This function should not be called before + * {@link TerrainProvider#ready} returns true. The result includes terrain + * data and indicates that all child tiles are available. + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @param {Request} [request] The request object. Intended for internal use only. + * + * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * returns undefined instead of a promise, it is an indication that too many requests are already + * pending and the request will be retried later. + */ + EllipsoidTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { + var width = 16; + var height = 16; + return new HeightmapTerrainData({ + buffer : new Uint8Array(width * height), + width : width, + height : height + }); + }; -// converts to / from base64 encoded strings -util.base64 = require(2); + /** + * Gets the maximum geometric error allowed in a tile at a given level. + * + * @param {Number} level The tile level for which to get the maximum geometric error. + * @returns {Number} The maximum geometric error. + */ + EllipsoidTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { + return this._levelZeroMaximumGeometricError / (1 << level); + }; -// base class of rpc.Service -util.EventEmitter = require(3); + /** + * Determines whether data for a tile is available to be loaded. + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @returns {Boolean} Undefined if not supported, otherwise true or false. + */ + EllipsoidTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + return undefined; + }; -// requires modules optionally and hides the call from bundlers -util.inquire = require(4); + return EllipsoidTerrainProvider; +}); -// converts to / from utf8 encoded strings -util.utf8 = require(6); +define('Core/EventHelper',[ + './defined', + './DeveloperError' + ], function( + defined, + DeveloperError) { + 'use strict'; -// provides a node-like buffer pool in the browser -util.pool = require(5); + /** + * A convenience object that simplifies the common pattern of attaching event listeners + * to several events, then removing all those listeners at once later, for example, in + * a destroy method. + * + * @alias EventHelper + * @constructor + * + * + * @example + * var helper = new Cesium.EventHelper(); + * + * helper.add(someObject.event, listener1, this); + * helper.add(otherObject.event, listener2, this); + * + * // later... + * helper.removeAll(); + * + * @see Event + */ + function EventHelper() { + this._removalFunctions = []; + } -// utility to work with the low and high bits of a 64 bit value -util.LongBits = require(12); + /** + * Adds a listener to an event, and records the registration to be cleaned up later. + * + * @param {Event} event The event to attach to. + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {EventHelper~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#addEventListener + */ + EventHelper.prototype.add = function(event, listener, scope) { + if (!defined(event)) { + throw new DeveloperError('event is required'); + } + + var removalFunction = event.addEventListener(listener, scope); + this._removalFunctions.push(removalFunction); -/** - * An immuable empty array. - * @memberof util - * @type {Array.<*>} - */ -util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes + var that = this; + return function() { + removalFunction(); + var removalFunctions = that._removalFunctions; + removalFunctions.splice(removalFunctions.indexOf(removalFunction), 1); + }; + }; -/** - * An immutable empty object. - * @type {Object} - */ -util.emptyObject = Object.freeze ? Object.freeze({}) : /* istanbul ignore next */ {}; // used on prototypes + /** + * Unregisters all previously added listeners. + * + * @see Event#removeEventListener + */ + EventHelper.prototype.removeAll = function() { + var removalFunctions = this._removalFunctions; + for (var i = 0, len = removalFunctions.length; i < len; ++i) { + removalFunctions[i](); + } + removalFunctions.length = 0; + }; -/** - * Whether running within node or not. - * @memberof util - * @type {boolean} - */ -util.isNode = Boolean(global.process && global.process.versions && global.process.versions.node); + /** + * A function that removes a listener. + * @callback EventHelper~RemoveCallback + */ -/** - * Tests if the specified value is an integer. - * @function - * @param {*} value Value to test - * @returns {boolean} `true` if the value is an integer - */ -util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) { - return typeof value === "number" && isFinite(value) && Math.floor(value) === value; -}; + return EventHelper; +}); -/** - * Tests if the specified value is a string. - * @param {*} value Value to test - * @returns {boolean} `true` if the value is a string - */ -util.isString = function isString(value) { - return typeof value === "string" || value instanceof String; -}; +define('Core/ExtrapolationType',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; -/** - * Tests if the specified value is a non-null object. - * @param {*} value Value to test - * @returns {boolean} `true` if the value is a non-null object - */ -util.isObject = function isObject(value) { - return value && typeof value === "object"; -}; + /** + * Constants to determine how an interpolated value is extrapolated + * when querying outside the bounds of available data. + * + * @exports ExtrapolationType + * + * @see SampledProperty + */ + var ExtrapolationType = { + /** + * No extrapolation occurs. + * + * @type {Number} + * @constant + */ + NONE : 0, -/** - * Node's Buffer class if available. - * @type {?function(new: Buffer)} - */ -util.Buffer = (function() { - try { - var Buffer = util.inquire("buffer").Buffer; - // refuse to use non-node buffers if not explicitly assigned (perf reasons): - return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null; - } catch (e) { - /* istanbul ignore next */ - return null; - } -})(); + /** + * The first or last value is used when outside the range of sample data. + * + * @type {Number} + * @constant + */ + HOLD : 1, -/** - * Internal alias of or polyfull for Buffer.from. - * @type {?function} - * @param {string|number[]} value Value - * @param {string} [encoding] Encoding if value is a string - * @returns {Uint8Array} - * @private - */ -util._Buffer_from = null; + /** + * The value is extrapolated. + * + * @type {Number} + * @constant + */ + EXTRAPOLATE : 2 + }; -/** - * Internal alias of or polyfill for Buffer.allocUnsafe. - * @type {?function} - * @param {number} size Buffer size - * @returns {Uint8Array} - * @private - */ -util._Buffer_allocUnsafe = null; + return freezeObject(ExtrapolationType); +}); -/** - * Creates a new buffer of whatever type supported by the environment. - * @param {number|number[]} [sizeOrArray=0] Buffer size or number array - * @returns {Uint8Array|Buffer} Buffer - */ -util.newBuffer = function newBuffer(sizeOrArray) { - /* istanbul ignore next */ - return typeof sizeOrArray === "number" - ? util.Buffer - ? util._Buffer_allocUnsafe(sizeOrArray) - : new util.Array(sizeOrArray) - : util.Buffer - ? util._Buffer_from(sizeOrArray) - : typeof Uint8Array === "undefined" - ? sizeOrArray - : new Uint8Array(sizeOrArray); -}; +define('Core/OrthographicOffCenterFrustum',[ + './Cartesian3', + './Cartesian4', + './CullingVolume', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Matrix4' + ], function( + Cartesian3, + Cartesian4, + CullingVolume, + defaultValue, + defined, + defineProperties, + DeveloperError, + Matrix4) { + 'use strict'; -/** - * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`. - * @type {?function(new: Uint8Array, *)} - */ -util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array; + /** + * The viewing frustum is defined by 6 planes. + * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components + * define the unit vector normal to the plane, and the w component is the distance of the + * plane from the origin/camera position. + * + * @alias OrthographicOffCenterFrustum + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.left] The left clipping plane distance. + * @param {Number} [options.right] The right clipping plane distance. + * @param {Number} [options.top] The top clipping plane distance. + * @param {Number} [options.bottom] The bottom clipping plane distance. + * @param {Number} [options.near=1.0] The near clipping plane distance. + * @param {Number} [options.far=500000000.0] The far clipping plane distance. + * + * @example + * var maxRadii = ellipsoid.maximumRadius; + * + * var frustum = new Cesium.OrthographicOffCenterFrustum(); + * frustum.right = maxRadii * Cesium.Math.PI; + * frustum.left = -c.frustum.right; + * frustum.top = c.frustum.right * (canvas.clientHeight / canvas.clientWidth); + * frustum.bottom = -c.frustum.top; + * frustum.near = 0.01 * maxRadii; + * frustum.far = 50.0 * maxRadii; + */ + function OrthographicOffCenterFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); -/** - * Long.js's Long class if available. - * @type {?function(new: Long)} - */ -util.Long = /* istanbul ignore next */ global.dcodeIO && /* istanbul ignore next */ global.dcodeIO.Long || util.inquire("long"); + /** + * The left clipping plane. + * @type {Number} + * @default undefined + */ + this.left = options.left; + this._left = undefined; -/** - * Regular expression used to verify 2 bit (`bool`) map keys. - * @type {RegExp} - */ -util.key2Re = /^true|false|0|1$/; + /** + * The right clipping plane. + * @type {Number} + * @default undefined + */ + this.right = options.right; + this._right = undefined; -/** - * Regular expression used to verify 32 bit (`int32` etc.) map keys. - * @type {RegExp} - */ -util.key32Re = /^-?(?:0|[1-9][0-9]*)$/; + /** + * The top clipping plane. + * @type {Number} + * @default undefined + */ + this.top = options.top; + this._top = undefined; -/** - * Regular expression used to verify 64 bit (`int64` etc.) map keys. - * @type {RegExp} - */ -util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/; + /** + * The bottom clipping plane. + * @type {Number} + * @default undefined + */ + this.bottom = options.bottom; + this._bottom = undefined; -/** - * Converts a number or long to an 8 characters long hash string. - * @param {Long|number} value Value to convert - * @returns {string} Hash - */ -util.longToHash = function longToHash(value) { - return value - ? util.LongBits.from(value).toHash() - : util.LongBits.zeroHash; -}; + /** + * The distance of the near plane. + * @type {Number} + * @default 1.0 + */ + this.near = defaultValue(options.near, 1.0); + this._near = this.near; -/** - * Converts an 8 characters long hash string to a long or number. - * @param {string} hash Hash - * @param {boolean} [unsigned=false] Whether unsigned or not - * @returns {Long|number} Original value - */ -util.longFromHash = function longFromHash(hash, unsigned) { - var bits = util.LongBits.fromHash(hash); - if (util.Long) - return util.Long.fromBits(bits.lo, bits.hi, unsigned); - return bits.toNumber(Boolean(unsigned)); -}; + /** + * The distance of the far plane. + * @type {Number} + * @default 500000000.0; + */ + this.far = defaultValue(options.far, 500000000.0); + this._far = this.far; -/** - * Merges the properties of the source object into the destination object. - * @memberof util - * @param {Object.<string,*>} dst Destination object - * @param {Object.<string,*>} src Source object - * @param {boolean} [ifNotSet=false] Merges only if the key is not already set - * @returns {Object.<string,*>} Destination object - */ -function merge(dst, src, ifNotSet) { // used by converters - for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) - if (dst[keys[i]] === undefined || !ifNotSet) - dst[keys[i]] = src[keys[i]]; - return dst; -} + this._cullingVolume = new CullingVolume(); + this._orthographicMatrix = new Matrix4(); + } -util.merge = merge; + function update(frustum) { + if (!defined(frustum.right) || !defined(frustum.left) || + !defined(frustum.top) || !defined(frustum.bottom) || + !defined(frustum.near) || !defined(frustum.far)) { + throw new DeveloperError('right, left, top, bottom, near, or far parameters are not set.'); + } + + if (frustum.top !== frustum._top || frustum.bottom !== frustum._bottom || + frustum.left !== frustum._left || frustum.right !== frustum._right || + frustum.near !== frustum._near || frustum.far !== frustum._far) { -/** - * Converts the first character of a string to lower case. - * @param {string} str String to convert - * @returns {string} Converted string - */ -util.lcFirst = function lcFirst(str) { - return str.charAt(0).toLowerCase() + str.substring(1); -}; + if (frustum.left > frustum.right) { + throw new DeveloperError('right must be greater than left.'); + } + if (frustum.bottom > frustum.top) { + throw new DeveloperError('top must be greater than bottom.'); + } + if (frustum.near <= 0 || frustum.near > frustum.far) { + throw new DeveloperError('near must be greater than zero and less than far.'); + } + + frustum._left = frustum.left; + frustum._right = frustum.right; + frustum._top = frustum.top; + frustum._bottom = frustum.bottom; + frustum._near = frustum.near; + frustum._far = frustum.far; + frustum._orthographicMatrix = Matrix4.computeOrthographicOffCenter(frustum.left, frustum.right, frustum.bottom, frustum.top, frustum.near, frustum.far, frustum._orthographicMatrix); + } + } -/** - * Creates a custom error constructor. - * @memberof util - * @param {string} name Error name - * @returns {function} Custom error constructor - */ -function newError(name) { + defineProperties(OrthographicOffCenterFrustum.prototype, { + /** + * Gets the orthographic projection matrix computed from the view frustum. + * @memberof OrthographicOffCenterFrustum.prototype + * @type {Matrix4} + * @readonly + */ + projectionMatrix : { + get : function() { + update(this); + return this._orthographicMatrix; + } + } + }); - function CustomError(message, properties) { + var getPlanesRight = new Cartesian3(); + var getPlanesNearCenter = new Cartesian3(); + var getPlanesPoint = new Cartesian3(); + var negateScratch = new Cartesian3(); - if (!(this instanceof CustomError)) - return new CustomError(message, properties); + /** + * Creates a culling volume for this frustum. + * + * @param {Cartesian3} position The eye position. + * @param {Cartesian3} direction The view direction. + * @param {Cartesian3} up The up direction. + * @returns {CullingVolume} A culling volume at the given position and orientation. + * + * @example + * // Check if a bounding volume intersects the frustum. + * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); + * var intersect = cullingVolume.computeVisibility(boundingVolume); + */ + OrthographicOffCenterFrustum.prototype.computeCullingVolume = function(position, direction, up) { + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } + if (!defined(direction)) { + throw new DeveloperError('direction is required.'); + } + if (!defined(up)) { + throw new DeveloperError('up is required.'); + } + + var planes = this._cullingVolume.planes; + var t = this.top; + var b = this.bottom; + var r = this.right; + var l = this.left; + var n = this.near; + var f = this.far; - // Error.call(this, message); - // ^ just returns a new error instance because the ctor can be called as a function + var right = Cartesian3.cross(direction, up, getPlanesRight); + Cartesian3.normalize(right, right); + var nearCenter = getPlanesNearCenter; + Cartesian3.multiplyByScalar(direction, n, nearCenter); + Cartesian3.add(position, nearCenter, nearCenter); - Object.defineProperty(this, "message", { get: function() { return message; } }); + var point = getPlanesPoint; - /* istanbul ignore next */ - if (Error.captureStackTrace) // node - Error.captureStackTrace(this, CustomError); - else - Object.defineProperty(this, "stack", { value: (new Error()).stack || "" }); + // Left plane + Cartesian3.multiplyByScalar(right, l, point); + Cartesian3.add(nearCenter, point, point); - if (properties) - merge(this, properties); - } + var plane = planes[0]; + if (!defined(plane)) { + plane = planes[0] = new Cartesian4(); + } + plane.x = right.x; + plane.y = right.y; + plane.z = right.z; + plane.w = -Cartesian3.dot(right, point); - (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError; + // Right plane + Cartesian3.multiplyByScalar(right, r, point); + Cartesian3.add(nearCenter, point, point); - Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } }); + plane = planes[1]; + if (!defined(plane)) { + plane = planes[1] = new Cartesian4(); + } + plane.x = -right.x; + plane.y = -right.y; + plane.z = -right.z; + plane.w = -Cartesian3.dot(Cartesian3.negate(right, negateScratch), point); - CustomError.prototype.toString = function toString() { - return this.name + ": " + this.message; - }; + // Bottom plane + Cartesian3.multiplyByScalar(up, b, point); + Cartesian3.add(nearCenter, point, point); - return CustomError; -} + plane = planes[2]; + if (!defined(plane)) { + plane = planes[2] = new Cartesian4(); + } + plane.x = up.x; + plane.y = up.y; + plane.z = up.z; + plane.w = -Cartesian3.dot(up, point); -util.newError = newError; + // Top plane + Cartesian3.multiplyByScalar(up, t, point); + Cartesian3.add(nearCenter, point, point); -/** - * Constructs a new protocol error. - * @classdesc Error subclass indicating a protocol specifc error. - * @memberof util - * @extends Error - * @constructor - * @param {string} message Error message - * @param {Object.<string,*>=} properties Additional properties - * @example - * try { - * MyMessage.decode(someBuffer); // throws if required fields are missing - * } catch (e) { - * if (e instanceof ProtocolError && e.instance) - * console.log("decoded so far: " + JSON.stringify(e.instance)); - * } - */ -util.ProtocolError = newError("ProtocolError"); + plane = planes[3]; + if (!defined(plane)) { + plane = planes[3] = new Cartesian4(); + } + plane.x = -up.x; + plane.y = -up.y; + plane.z = -up.z; + plane.w = -Cartesian3.dot(Cartesian3.negate(up, negateScratch), point); -/** - * So far decoded message instance. - * @name util.ProtocolError#instance - * @type {Message} - */ + // Near plane + plane = planes[4]; + if (!defined(plane)) { + plane = planes[4] = new Cartesian4(); + } + plane.x = direction.x; + plane.y = direction.y; + plane.z = direction.z; + plane.w = -Cartesian3.dot(direction, nearCenter); -/** - * Builds a getter for a oneof's present field name. - * @param {string[]} fieldNames Field names - * @returns {function():string|undefined} Unbound getter - */ -util.oneOfGetter = function getOneOf(fieldNames) { - var fieldMap = {}; - for (var i = 0; i < fieldNames.length; ++i) - fieldMap[fieldNames[i]] = 1; + // Far plane + Cartesian3.multiplyByScalar(direction, f, point); + Cartesian3.add(position, point, point); - /** - * @returns {string|undefined} Set field name, if any - * @this Object - * @ignore - */ - return function() { // eslint-disable-line consistent-return - for (var keys = Object.keys(this), i = keys.length - 1; i > -1; --i) - if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null) - return keys[i]; - }; -}; + plane = planes[5]; + if (!defined(plane)) { + plane = planes[5] = new Cartesian4(); + } + plane.x = -direction.x; + plane.y = -direction.y; + plane.z = -direction.z; + plane.w = -Cartesian3.dot(Cartesian3.negate(direction, negateScratch), point); -/** - * Builds a setter for a oneof's present field name. - * @param {string[]} fieldNames Field names - * @returns {function(?string):undefined} Unbound setter - */ -util.oneOfSetter = function setOneOf(fieldNames) { + return this._cullingVolume; + }; /** - * @param {string} name Field name - * @returns {undefined} - * @this Object - * @ignore + * Returns the pixel's width and height in meters. + * + * @param {Number} drawingBufferWidth The width of the drawing buffer. + * @param {Number} drawingBufferHeight The height of the drawing buffer. + * @param {Number} distance The distance to the near plane in meters. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. + * + * @exception {DeveloperError} drawingBufferWidth must be greater than zero. + * @exception {DeveloperError} drawingBufferHeight must be greater than zero. + * + * @example + * // Example 1 + * // Get the width and height of a pixel. + * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 0.0, new Cesium.Cartesian2()); */ - return function(name) { - for (var i = 0; i < fieldNames.length; ++i) - if (fieldNames[i] !== name) - delete this[fieldNames[i]]; - }; -}; + OrthographicOffCenterFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { + update(this); -/** - * Lazily resolves fully qualified type names against the specified root. - * @param {Root} root Root instanceof - * @param {Object.<number,string|ReflectionObject>} lazyTypes Type names - * @returns {undefined} - */ -util.lazyResolve = function lazyResolve(root, lazyTypes) { - for (var i = 0; i < lazyTypes.length; ++i) { - for (var keys = Object.keys(lazyTypes[i]), j = 0; j < keys.length; ++j) { - var path = lazyTypes[i][keys[j]].split("."), - ptr = root; - while (path.length) - ptr = ptr[path.shift()]; - lazyTypes[i][keys[j]] = ptr; + if (!defined(drawingBufferWidth) || !defined(drawingBufferHeight)) { + throw new DeveloperError('Both drawingBufferWidth and drawingBufferHeight are required.'); } - } -}; - -/** - * Default conversion options used for {@link Message#toJSON} implementations. Longs, enums and bytes are converted to strings by default. - * @type {ConversionOptions} - */ -util.toJSONOptions = { - longs: String, - enums: String, - bytes: String -}; - -util._configure = function() { - var Buffer = util.Buffer; - /* istanbul ignore if */ - if (!Buffer) { - util._Buffer_from = util._Buffer_allocUnsafe = null; - return; - } - // because node 4.x buffers are incompatible & immutable - // see: https://github.com/dcodeIO/protobuf.js/pull/665 - util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from || - /* istanbul ignore next */ - function Buffer_from(value, encoding) { - return new Buffer(value, encoding); - }; - util._Buffer_allocUnsafe = Buffer.allocUnsafe || - /* istanbul ignore next */ - function Buffer_allocUnsafe(size) { - return new Buffer(size); - }; -}; - -},{"1":1,"12":12,"2":2,"3":3,"4":4,"5":5,"6":6}],14:[function(require,module,exports){ -"use strict"; -module.exports = Writer; - -var util = require(13); - -var BufferWriter; // cyclic - -var LongBits = util.LongBits, - base64 = util.base64, - utf8 = util.utf8; + if (drawingBufferWidth <= 0) { + throw new DeveloperError('drawingBufferWidth must be greater than zero.'); + } + if (drawingBufferHeight <= 0) { + throw new DeveloperError('drawingBufferHeight must be greater than zero.'); + } + if (!defined(distance)) { + throw new DeveloperError('distance is required.'); + } + if (!defined(result)) { + throw new DeveloperError('A result object is required.'); + } + + var frustumWidth = this.right - this.left; + var frustumHeight = this.top - this.bottom; + var pixelWidth = frustumWidth / drawingBufferWidth; + var pixelHeight = frustumHeight / drawingBufferHeight; -/** - * Constructs a new writer operation instance. - * @classdesc Scheduled writer operation. - * @constructor - * @param {function(*, Uint8Array, number)} fn Function to call - * @param {number} len Value byte length - * @param {*} val Value to write - * @ignore - */ -function Op(fn, len, val) { + result.x = pixelWidth; + result.y = pixelHeight; + return result; + }; /** - * Function to call. - * @type {function(Uint8Array, number, *)} + * Returns a duplicate of a OrthographicOffCenterFrustum instance. + * + * @param {OrthographicOffCenterFrustum} [result] The object onto which to store the result. + * @returns {OrthographicOffCenterFrustum} The modified result parameter or a new OrthographicOffCenterFrustum instance if one was not provided. */ - this.fn = fn; + OrthographicOffCenterFrustum.prototype.clone = function(result) { + if (!defined(result)) { + result = new OrthographicOffCenterFrustum(); + } - /** - * Value byte length. - * @type {number} - */ - this.len = len; + result.left = this.left; + result.right = this.right; + result.top = this.top; + result.bottom = this.bottom; + result.near = this.near; + result.far = this.far; - /** - * Next operation. - * @type {Writer.Op|undefined} - */ - this.next = undefined; + // force update of clone to compute matrices + result._left = undefined; + result._right = undefined; + result._top = undefined; + result._bottom = undefined; + result._near = undefined; + result._far = undefined; + + return result; + }; /** - * Value to write. - * @type {*} + * Compares the provided OrthographicOffCenterFrustum componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {OrthographicOffCenterFrustum} [other] The right hand side OrthographicOffCenterFrustum. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ - this.val = val; // type varies -} + OrthographicOffCenterFrustum.prototype.equals = function(other) { + return (defined(other) && + this.right === other.right && + this.left === other.left && + this.top === other.top && + this.bottom === other.bottom && + this.near === other.near && + this.far === other.far); + }; -/* istanbul ignore next */ -function noop() {} // eslint-disable-line no-empty-function + return OrthographicOffCenterFrustum; +}); -/** - * Constructs a new writer state instance. - * @classdesc Copied writer state. - * @memberof Writer - * @constructor - * @param {Writer} writer Writer to copy state from - * @private - * @ignore - */ -function State(writer) { +define('Core/OrthographicFrustum',[ + './Check', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './OrthographicOffCenterFrustum' + ], function( + Check, + defaultValue, + defined, + defineProperties, + DeveloperError, + OrthographicOffCenterFrustum) { + 'use strict'; /** - * Current head. - * @type {Writer.Op} + * The viewing frustum is defined by 6 planes. + * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components + * define the unit vector normal to the plane, and the w component is the distance of the + * plane from the origin/camera position. + * + * @alias OrthographicFrustum + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.width] The width of the frustum in meters. + * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. + * @param {Number} [options.near=1.0] The distance of the near plane. + * @param {Number} [options.far=500000000.0] The distance of the far plane. + * + * @example + * var maxRadii = ellipsoid.maximumRadius; + * + * var frustum = new Cesium.OrthographicFrustum(); + * frustum.near = 0.01 * maxRadii; + * frustum.far = 50.0 * maxRadii; */ - this.head = writer.head; + function OrthographicFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * Current tail. - * @type {Writer.Op} - */ - this.tail = writer.tail; + this._offCenterFrustum = new OrthographicOffCenterFrustum(); - /** - * Current buffer length. - * @type {number} - */ - this.len = writer.len; + /** + * The horizontal width of the frustum in meters. + * @type {Number} + * @default undefined + */ + this.width = options.width; + this._width = undefined; - /** - * Next state. - * @type {?State} - */ - this.next = writer.states; -} + /** + * The aspect ratio of the frustum's width to it's height. + * @type {Number} + * @default undefined + */ + this.aspectRatio = options.aspectRatio; + this._aspectRatio = undefined; -/** - * Constructs a new writer instance. - * @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`. - * @constructor - */ -function Writer() { + /** + * The distance of the near plane. + * @type {Number} + * @default 1.0 + */ + this.near = defaultValue(options.near, 1.0); + this._near = this.near; - /** - * Current length. - * @type {number} - */ - this.len = 0; + /** + * The distance of the far plane. + * @type {Number} + * @default 500000000.0; + */ + this.far = defaultValue(options.far, 500000000.0); + this._far = this.far; + } /** - * Operations head. - * @type {Object} + * The number of elements used to pack the object into an array. + * @type {Number} */ - this.head = new Op(noop, 0, 0); + OrthographicFrustum.packedLength = 4; /** - * Operations tail - * @type {Object} - */ - this.tail = this.head; - - /** - * Linked forked states. - * @type {?Object} + * Stores the provided instance into the provided array. + * + * @param {OrthographicFrustum} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - this.states = null; + OrthographicFrustum.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - // When a value is written, the writer calculates its byte length and puts it into a linked - // list of operations to perform when finish() is called. This both allows us to allocate - // buffers of the exact required size and reduces the amount of work we have to do compared - // to first calculating over objects and then encoding over objects. In our case, the encoding - // part is just a linked list walk calling operations with already prepared values. -} + array[startingIndex++] = value.width; + array[startingIndex++] = value.aspectRatio; + array[startingIndex++] = value.near; + array[startingIndex] = value.far; -/** - * Creates a new writer. - * @function - * @returns {BufferWriter|Writer} A {@link BufferWriter} when Buffers are supported, otherwise a {@link Writer} - */ -Writer.create = util.Buffer - ? function create_buffer_setup() { - return (Writer.create = function create_buffer() { - return new BufferWriter(); - })(); - } - /* istanbul ignore next */ - : function create_array() { - return new Writer(); + return array; }; -/** - * Allocates a buffer of the specified size. - * @param {number} size Buffer size - * @returns {Uint8Array} Buffer - */ -Writer.alloc = function alloc(size) { - return new util.Array(size); -}; - -// Use Uint8Array buffer pool in the browser, just like node does with buffers -/* istanbul ignore else */ -if (util.Array !== Array) - Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray); - -/** - * Pushes a new operation to the queue. - * @param {function(Uint8Array, number, *)} fn Function to call - * @param {number} len Value byte length - * @param {number} val Value to write - * @returns {Writer} `this` - */ -Writer.prototype.push = function push(fn, len, val) { - this.tail = this.tail.next = new Op(fn, len, val); - this.len += len; - return this; -}; - -function writeByte(val, buf, pos) { - buf[pos] = val & 255; -} + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrthographicFrustum} [result] The object into which to store the result. + * @returns {OrthographicFrustum} The modified result parameter or a new OrthographicFrustum instance if one was not provided. + */ + OrthographicFrustum.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); -function writeVarint32(val, buf, pos) { - while (val > 127) { - buf[pos++] = val & 127 | 128; - val >>>= 7; - } - buf[pos] = val; -} + if (!defined(result)) { + result = new OrthographicFrustum(); + } -/** - * Constructs a new varint writer operation instance. - * @classdesc Scheduled varint writer operation. - * @extends Op - * @constructor - * @param {number} len Value byte length - * @param {number} val Value to write - * @ignore - */ -function VarintOp(len, val) { - this.len = len; - this.next = undefined; - this.val = val; -} + result.width = array[startingIndex++]; + result.aspectRatio = array[startingIndex++]; + result.near = array[startingIndex++]; + result.far = array[startingIndex]; -VarintOp.prototype = Object.create(Op.prototype); -VarintOp.prototype.fn = writeVarint32; + return result; + }; -/** - * Writes an unsigned 32 bit value as a varint. - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.uint32 = function write_uint32(value) { - // here, the call to this.push has been inlined and a varint specific Op subclass is used. - // uint32 is by far the most frequently used operation and benefits significantly from this. - this.len += (this.tail = this.tail.next = new VarintOp( - (value = value >>> 0) - < 128 ? 1 - : value < 16384 ? 2 - : value < 2097152 ? 3 - : value < 268435456 ? 4 - : 5, - value)).len; - return this; -}; + function update(frustum) { + if (!defined(frustum.width) || !defined(frustum.aspectRatio) || !defined(frustum.near) || !defined(frustum.far)) { + throw new DeveloperError('width, aspectRatio, near, or far parameters are not set.'); + } + + var f = frustum._offCenterFrustum; -/** - * Writes a signed 32 bit value as a varint. - * @function - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.int32 = function write_int32(value) { - return value < 0 - ? this.push(writeVarint64, 10, LongBits.fromNumber(value)) // 10 bytes per spec - : this.uint32(value); -}; + if (frustum.width !== frustum._width || frustum.aspectRatio !== frustum._aspectRatio || + frustum.near !== frustum._near || frustum.far !== frustum._far) { + if (frustum.aspectRatio < 0) { + throw new DeveloperError('aspectRatio must be positive.'); + } + if (frustum.near < 0 || frustum.near > frustum.far) { + throw new DeveloperError('near must be greater than zero and less than far.'); + } + + frustum._aspectRatio = frustum.aspectRatio; + frustum._width = frustum.width; + frustum._near = frustum.near; + frustum._far = frustum.far; -/** - * Writes a 32 bit value as a varint, zig-zag encoded. - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.sint32 = function write_sint32(value) { - return this.uint32((value << 1 ^ value >> 31) >>> 0); -}; + var ratio = 1.0 / frustum.aspectRatio; + f.right = frustum.width * 0.5; + f.left = -f.right; + f.top = ratio * f.right; + f.bottom = -f.top; + f.near = frustum.near; + f.far = frustum.far; -function writeVarint64(val, buf, pos) { - while (val.hi) { - buf[pos++] = val.lo & 127 | 128; - val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0; - val.hi >>>= 7; - } - while (val.lo > 127) { - buf[pos++] = val.lo & 127 | 128; - val.lo = val.lo >>> 7; + } } - buf[pos++] = val.lo; -} -/** - * Writes an unsigned 64 bit value as a varint. - * @param {Long|number|string} value Value to write - * @returns {Writer} `this` - * @throws {TypeError} If `value` is a string and no long library is present. - */ -Writer.prototype.uint64 = function write_uint64(value) { - var bits = LongBits.from(value); - return this.push(writeVarint64, bits.length(), bits); -}; - -/** - * Writes a signed 64 bit value as a varint. - * @function - * @param {Long|number|string} value Value to write - * @returns {Writer} `this` - * @throws {TypeError} If `value` is a string and no long library is present. - */ -Writer.prototype.int64 = Writer.prototype.uint64; + defineProperties(OrthographicFrustum.prototype, { + /** + * Gets the orthographic projection matrix computed from the view frustum. + * @memberof OrthographicFrustum.prototype + * @type {Matrix4} + * @readonly + */ + projectionMatrix : { + get : function() { + update(this); + return this._offCenterFrustum.projectionMatrix; + } + } -/** - * Writes a signed 64 bit value as a varint, zig-zag encoded. - * @param {Long|number|string} value Value to write - * @returns {Writer} `this` - * @throws {TypeError} If `value` is a string and no long library is present. - */ -Writer.prototype.sint64 = function write_sint64(value) { - var bits = LongBits.from(value).zzEncode(); - return this.push(writeVarint64, bits.length(), bits); -}; + }); -/** - * Writes a boolish value as a varint. - * @param {boolean} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.bool = function write_bool(value) { - return this.push(writeByte, 1, value ? 1 : 0); -}; + /** + * Creates a culling volume for this frustum. + * + * @param {Cartesian3} position The eye position. + * @param {Cartesian3} direction The view direction. + * @param {Cartesian3} up The up direction. + * @returns {CullingVolume} A culling volume at the given position and orientation. + * + * @example + * // Check if a bounding volume intersects the frustum. + * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); + * var intersect = cullingVolume.computeVisibility(boundingVolume); + */ + OrthographicFrustum.prototype.computeCullingVolume = function(position, direction, up) { + update(this); + return this._offCenterFrustum.computeCullingVolume(position, direction, up); + }; -function writeFixed32(val, buf, pos) { - buf[pos++] = val & 255; - buf[pos++] = val >>> 8 & 255; - buf[pos++] = val >>> 16 & 255; - buf[pos ] = val >>> 24; -} + /** + * Returns the pixel's width and height in meters. + * + * @param {Number} drawingBufferWidth The width of the drawing buffer. + * @param {Number} drawingBufferHeight The height of the drawing buffer. + * @param {Number} distance The distance to the near plane in meters. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. + * + * @exception {DeveloperError} drawingBufferWidth must be greater than zero. + * @exception {DeveloperError} drawingBufferHeight must be greater than zero. + * + * @example + * // Example 1 + * // Get the width and height of a pixel. + * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 0.0, new Cesium.Cartesian2()); + */ + OrthographicFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { + update(this); + return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result); + }; -/** - * Writes an unsigned 32 bit value as fixed 32 bits. - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.fixed32 = function write_fixed32(value) { - return this.push(writeFixed32, 4, value >>> 0); -}; + /** + * Returns a duplicate of a OrthographicFrustum instance. + * + * @param {OrthographicFrustum} [result] The object onto which to store the result. + * @returns {OrthographicFrustum} The modified result parameter or a new OrthographicFrustum instance if one was not provided. + */ + OrthographicFrustum.prototype.clone = function(result) { + if (!defined(result)) { + result = new OrthographicFrustum(); + } -/** - * Writes a signed 32 bit value as fixed 32 bits. - * @function - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.sfixed32 = Writer.prototype.fixed32; + result.aspectRatio = this.aspectRatio; + result.width = this.width; + result.near = this.near; + result.far = this.far; -/** - * Writes an unsigned 64 bit value as fixed 64 bits. - * @param {Long|number|string} value Value to write - * @returns {Writer} `this` - * @throws {TypeError} If `value` is a string and no long library is present. - */ -Writer.prototype.fixed64 = function write_fixed64(value) { - var bits = LongBits.from(value); - return this.push(writeFixed32, 4, bits.lo).push(writeFixed32, 4, bits.hi); -}; + // force update of clone to compute matrices + result._aspectRatio = undefined; + result._width = undefined; + result._near = undefined; + result._far = undefined; -/** - * Writes a signed 64 bit value as fixed 64 bits. - * @function - * @param {Long|number|string} value Value to write - * @returns {Writer} `this` - * @throws {TypeError} If `value` is a string and no long library is present. - */ -Writer.prototype.sfixed64 = Writer.prototype.fixed64; + this._offCenterFrustum.clone(result._offCenterFrustum); -var writeFloat = typeof Float32Array !== "undefined" - ? (function() { - var f32 = new Float32Array(1), - f8b = new Uint8Array(f32.buffer); - f32[0] = -0; - return f8b[3] // already le? - ? function writeFloat_f32(val, buf, pos) { - f32[0] = val; - buf[pos++] = f8b[0]; - buf[pos++] = f8b[1]; - buf[pos++] = f8b[2]; - buf[pos ] = f8b[3]; - } - /* istanbul ignore next */ - : function writeFloat_f32_le(val, buf, pos) { - f32[0] = val; - buf[pos++] = f8b[3]; - buf[pos++] = f8b[2]; - buf[pos++] = f8b[1]; - buf[pos ] = f8b[0]; - }; - })() - /* istanbul ignore next */ - : function writeFloat_ieee754(value, buf, pos) { - var sign = value < 0 ? 1 : 0; - if (sign) - value = -value; - if (value === 0) - writeFixed32(1 / value > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos); - else if (isNaN(value)) - writeFixed32(2147483647, buf, pos); - else if (value > 3.4028234663852886e+38) // +-Infinity - writeFixed32((sign << 31 | 2139095040) >>> 0, buf, pos); - else if (value < 1.1754943508222875e-38) // denormal - writeFixed32((sign << 31 | Math.round(value / 1.401298464324817e-45)) >>> 0, buf, pos); - else { - var exponent = Math.floor(Math.log(value) / Math.LN2), - mantissa = Math.round(value * Math.pow(2, -exponent) * 8388608) & 8388607; - writeFixed32((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos); - } + return result; }; -/** - * Writes a float (32 bit). - * @function - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.float = function write_float(value) { - return this.push(writeFloat, 4, value); -}; - -var writeDouble = typeof Float64Array !== "undefined" - ? (function() { - var f64 = new Float64Array(1), - f8b = new Uint8Array(f64.buffer); - f64[0] = -0; - return f8b[7] // already le? - ? function writeDouble_f64(val, buf, pos) { - f64[0] = val; - buf[pos++] = f8b[0]; - buf[pos++] = f8b[1]; - buf[pos++] = f8b[2]; - buf[pos++] = f8b[3]; - buf[pos++] = f8b[4]; - buf[pos++] = f8b[5]; - buf[pos++] = f8b[6]; - buf[pos ] = f8b[7]; - } - /* istanbul ignore next */ - : function writeDouble_f64_le(val, buf, pos) { - f64[0] = val; - buf[pos++] = f8b[7]; - buf[pos++] = f8b[6]; - buf[pos++] = f8b[5]; - buf[pos++] = f8b[4]; - buf[pos++] = f8b[3]; - buf[pos++] = f8b[2]; - buf[pos++] = f8b[1]; - buf[pos ] = f8b[0]; - }; - })() - /* istanbul ignore next */ - : function writeDouble_ieee754(value, buf, pos) { - var sign = value < 0 ? 1 : 0; - if (sign) - value = -value; - if (value === 0) { - writeFixed32(0, buf, pos); - writeFixed32(1 / value > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos + 4); - } else if (isNaN(value)) { - writeFixed32(4294967295, buf, pos); - writeFixed32(2147483647, buf, pos + 4); - } else if (value > 1.7976931348623157e+308) { // +-Infinity - writeFixed32(0, buf, pos); - writeFixed32((sign << 31 | 2146435072) >>> 0, buf, pos + 4); - } else { - var mantissa; - if (value < 2.2250738585072014e-308) { // denormal - mantissa = value / 5e-324; - writeFixed32(mantissa >>> 0, buf, pos); - writeFixed32((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + 4); - } else { - var exponent = Math.floor(Math.log(value) / Math.LN2); - if (exponent === 1024) - exponent = 1023; - mantissa = value * Math.pow(2, -exponent); - writeFixed32(mantissa * 4503599627370496 >>> 0, buf, pos); - writeFixed32((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + 4); - } + /** + * Compares the provided OrthographicFrustum componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {OrthographicFrustum} [other] The right hand side OrthographicFrustum. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + OrthographicFrustum.prototype.equals = function(other) { + if (!defined(other)) { + return false; } - }; -/** - * Writes a double (64 bit float). - * @function - * @param {number} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.double = function write_double(value) { - return this.push(writeDouble, 8, value); -}; + update(this); + update(other); -var writeBytes = util.Array.prototype.set - ? function writeBytes_set(val, buf, pos) { - buf.set(val, pos); // also works for plain array values - } - /* istanbul ignore next */ - : function writeBytes_for(val, buf, pos) { - for (var i = 0; i < val.length; ++i) - buf[pos + i] = val[i]; + return (this.width === other.width && + this.aspectRatio === other.aspectRatio && + this.near === other.near && + this.far === other.far && + this._offCenterFrustum.equals(other._offCenterFrustum)); }; -/** - * Writes a sequence of bytes. - * @param {Uint8Array|string} value Buffer or base64 encoded string to write - * @returns {Writer} `this` - */ -Writer.prototype.bytes = function write_bytes(value) { - var len = value.length >>> 0; - if (!len) - return this.push(writeByte, 1, 0); - if (util.isString(value)) { - var buf = Writer.alloc(len = base64.length(value)); - base64.decode(value, buf, 0); - value = buf; - } - return this.uint32(len).push(writeBytes, len, value); -}; - -/** - * Writes a string. - * @param {string} value Value to write - * @returns {Writer} `this` - */ -Writer.prototype.string = function write_string(value) { - var len = utf8.length(value); - return len - ? this.uint32(len).push(utf8.write, len, value) - : this.push(writeByte, 1, 0); -}; - -/** - * Forks this writer's state by pushing it to a stack. - * Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state. - * @returns {Writer} `this` - */ -Writer.prototype.fork = function fork() { - this.states = new State(this); - this.head = this.tail = new Op(noop, 0, 0); - this.len = 0; - return this; -}; - -/** - * Resets this instance to the last state. - * @returns {Writer} `this` - */ -Writer.prototype.reset = function reset() { - if (this.states) { - this.head = this.states.head; - this.tail = this.states.tail; - this.len = this.states.len; - this.states = this.states.next; - } else { - this.head = this.tail = new Op(noop, 0, 0); - this.len = 0; - } - return this; -}; - -/** - * Resets to the last state and appends the fork state's current write length as a varint followed by its operations. - * @returns {Writer} `this` - */ -Writer.prototype.ldelim = function ldelim() { - var head = this.head, - tail = this.tail, - len = this.len; - this.reset().uint32(len); - if (len) { - this.tail.next = head.next; // skip noop - this.tail = tail; - this.len += len; - } - return this; -}; + return OrthographicFrustum; +}); -/** - * Finishes the write operation. - * @returns {Uint8Array} Finished buffer - */ -Writer.prototype.finish = function finish() { - var head = this.head.next, // skip noop - buf = this.constructor.alloc(this.len), - pos = 0; - while (head) { - head.fn(head.val, buf, pos); - pos += head.len; - head = head.next; - } - // this.head = this.tail = null; - return buf; -}; +define('Core/PerspectiveOffCenterFrustum',[ + './Cartesian3', + './Cartesian4', + './CullingVolume', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Matrix4' + ], function( + Cartesian3, + Cartesian4, + CullingVolume, + defaultValue, + defined, + defineProperties, + DeveloperError, + Matrix4) { + 'use strict'; -Writer._configure = function(BufferWriter_) { - BufferWriter = BufferWriter_; -}; + /** + * The viewing frustum is defined by 6 planes. + * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components + * define the unit vector normal to the plane, and the w component is the distance of the + * plane from the origin/camera position. + * + * @alias PerspectiveOffCenterFrustum + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.left] The left clipping plane distance. + * @param {Number} [options.right] The right clipping plane distance. + * @param {Number} [options.top] The top clipping plane distance. + * @param {Number} [options.bottom] The bottom clipping plane distance. + * @param {Number} [options.near=1.0] The near clipping plane distance. + * @param {Number} [options.far=500000000.0] The far clipping plane distance. + * + * @example + * var frustum = new Cesium.PerspectiveOffCenterFrustum({ + * left : -1.0, + * right : 1.0, + * top : 1.0, + * bottom : -1.0, + * near : 1.0, + * far : 100.0 + * }); + * + * @see PerspectiveFrustum + */ + function PerspectiveOffCenterFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); -},{"13":13}],15:[function(require,module,exports){ -"use strict"; -module.exports = BufferWriter; + /** + * Defines the left clipping plane. + * @type {Number} + * @default undefined + */ + this.left = options.left; + this._left = undefined; -// extends Writer -var Writer = require(14); -(BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter; + /** + * Defines the right clipping plane. + * @type {Number} + * @default undefined + */ + this.right = options.right; + this._right = undefined; -var util = require(13); + /** + * Defines the top clipping plane. + * @type {Number} + * @default undefined + */ + this.top = options.top; + this._top = undefined; -var Buffer = util.Buffer; + /** + * Defines the bottom clipping plane. + * @type {Number} + * @default undefined + */ + this.bottom = options.bottom; + this._bottom = undefined; -/** - * Constructs a new buffer writer instance. - * @classdesc Wire format writer using node buffers. - * @extends Writer - * @constructor - */ -function BufferWriter() { - Writer.call(this); -} + /** + * The distance of the near plane. + * @type {Number} + * @default 1.0 + */ + this.near = defaultValue(options.near, 1.0); + this._near = this.near; -/** - * Allocates a buffer of the specified size. - * @param {number} size Buffer size - * @returns {Buffer} Buffer - */ -BufferWriter.alloc = function alloc_buffer(size) { - return (BufferWriter.alloc = util._Buffer_allocUnsafe)(size); -}; + /** + * The distance of the far plane. + * @type {Number} + * @default 500000000.0 + */ + this.far = defaultValue(options.far, 500000000.0); + this._far = this.far; -var writeBytesBuffer = Buffer && Buffer.prototype instanceof Uint8Array && Buffer.prototype.set.name === "set" - ? function writeBytesBuffer_set(val, buf, pos) { - buf.set(val, pos); // faster than copy (requires node >= 4 where Buffers extend Uint8Array and set is properly inherited) - // also works for plain array values + this._cullingVolume = new CullingVolume(); + this._perspectiveMatrix = new Matrix4(); + this._infinitePerspective = new Matrix4(); } - /* istanbul ignore next */ - : function writeBytesBuffer_copy(val, buf, pos) { - if (val.copy) // Buffer values - val.copy(buf, pos, 0, val.length); - else for (var i = 0; i < val.length;) // plain array values - buf[pos++] = val[i++]; - }; - -/** - * @override - */ -BufferWriter.prototype.bytes = function write_bytes_buffer(value) { - if (util.isString(value)) - value = util._Buffer_from(value, "base64"); - var len = value.length >>> 0; - this.uint32(len); - if (len) - this.push(writeBytesBuffer, len, value); - return this; -}; - -function writeStringBuffer(val, buf, pos) { - if (val.length < 40) // plain js is faster for short strings (probably due to redundant assertions) - util.utf8.write(val, buf, pos); - else - buf.utf8Write(val, pos); -} -/** - * @override - */ -BufferWriter.prototype.string = function write_string_buffer(value) { - var len = Buffer.byteLength(value); - this.uint32(len); - if (len) - this.push(writeStringBuffer, len, value); - return this; -}; + function update(frustum) { + if (!defined(frustum.right) || !defined(frustum.left) || + !defined(frustum.top) || !defined(frustum.bottom) || + !defined(frustum.near) || !defined(frustum.far)) { + throw new DeveloperError('right, left, top, bottom, near, or far parameters are not set.'); + } + + var t = frustum.top; + var b = frustum.bottom; + var r = frustum.right; + var l = frustum.left; + var n = frustum.near; + var f = frustum.far; + if (t !== frustum._top || b !== frustum._bottom || + l !== frustum._left || r !== frustum._right || + n !== frustum._near || f !== frustum._far) { -/** - * Finishes the write operation. - * @name BufferWriter#finish - * @function - * @returns {Buffer} Finished buffer - */ + if (frustum.near <= 0 || frustum.near > frustum.far) { + throw new DeveloperError('near must be greater than zero and less than far.'); + } + + frustum._left = l; + frustum._right = r; + frustum._top = t; + frustum._bottom = b; + frustum._near = n; + frustum._far = f; + frustum._perspectiveMatrix = Matrix4.computePerspectiveOffCenter(l, r, b, t, n, f, frustum._perspectiveMatrix); + frustum._infinitePerspective = Matrix4.computeInfinitePerspectiveOffCenter(l, r, b, t, n, frustum._infinitePerspective); + } + } -},{"13":13,"14":14}]},{},[7]) + defineProperties(PerspectiveOffCenterFrustum.prototype, { + /** + * Gets the perspective projection matrix computed from the view frustum. + * @memberof PerspectiveOffCenterFrustum.prototype + * @type {Matrix4} + * @readonly + * + * @see PerspectiveOffCenterFrustum#infiniteProjectionMatrix + */ + projectionMatrix : { + get : function() { + update(this); + return this._perspectiveMatrix; + } + }, -})(typeof window==="object"&&window||typeof self==="object"&&self||this); -//# sourceMappingURL=protobuf.js.map -; -define('ThirdParty/google-earth-dbroot-parser',[ - './protobuf-minimal' -], function( - $protobuf) { - /* jshint curly: false, sub: true, newcap: false, shadow: true, unused: false*/ - 'use strict'; + /** + * Gets the perspective projection matrix computed from the view frustum with an infinite far plane. + * @memberof PerspectiveOffCenterFrustum.prototype + * @type {Matrix4} + * @readonly + * + * @see PerspectiveOffCenterFrustum#projectionMatrix + */ + infiniteProjectionMatrix : { + get : function() { + update(this); + return this._infinitePerspective; + } + } + }); - // - // Creates a parser for a dbroot protocol buffer - // Below code is generated using protobufjs with the following command - // - // ./pbjs --no-encode --no-create --no-comments --no-delimited -w amd -t static dbroot_v2.proto - // - // .proto file can be found here: https://github.com/google/earthenterprise/blob/master/earth_enterprise/src/keyhole/proto/dbroot/dbroot_v2.proto + var getPlanesRight = new Cartesian3(); + var getPlanesNearCenter = new Cartesian3(); + var getPlanesFarCenter = new Cartesian3(); + var getPlanesNormal = new Cartesian3(); + /** + * Creates a culling volume for this frustum. + * + * @param {Cartesian3} position The eye position. + * @param {Cartesian3} direction The view direction. + * @param {Cartesian3} up The up direction. + * @returns {CullingVolume} A culling volume at the given position and orientation. + * + * @example + * // Check if a bounding volume intersects the frustum. + * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); + * var intersect = cullingVolume.computeVisibility(boundingVolume); + */ + PerspectiveOffCenterFrustum.prototype.computeCullingVolume = function(position, direction, up) { + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } - var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util; + if (!defined(direction)) { + throw new DeveloperError('direction is required.'); + } - var $lazyTypes = []; + if (!defined(up)) { + throw new DeveloperError('up is required.'); + } + + var planes = this._cullingVolume.planes; - var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + var t = this.top; + var b = this.bottom; + var r = this.right; + var l = this.left; + var n = this.near; + var f = this.far; - $root.keyhole = (function() { + var right = Cartesian3.cross(direction, up, getPlanesRight); - var keyhole = {}; + var nearCenter = getPlanesNearCenter; + Cartesian3.multiplyByScalar(direction, n, nearCenter); + Cartesian3.add(position, nearCenter, nearCenter); - keyhole.dbroot = (function() { + var farCenter = getPlanesFarCenter; + Cartesian3.multiplyByScalar(direction, f, farCenter); + Cartesian3.add(position, farCenter, farCenter); - var dbroot = {}; + var normal = getPlanesNormal; - dbroot.StringEntryProto = (function() { + //Left plane computation + Cartesian3.multiplyByScalar(right, l, normal); + Cartesian3.add(nearCenter, normal, normal); + Cartesian3.subtract(normal, position, normal); + Cartesian3.normalize(normal, normal); + Cartesian3.cross(normal, up, normal); + Cartesian3.normalize(normal, normal); - function StringEntryProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + var plane = planes[0]; + if (!defined(plane)) { + plane = planes[0] = new Cartesian4(); + } + plane.x = normal.x; + plane.y = normal.y; + plane.z = normal.z; + plane.w = -Cartesian3.dot(normal, position); - StringEntryProto.prototype.stringId = 0; - StringEntryProto.prototype.stringValue = ""; + //Right plane computation + Cartesian3.multiplyByScalar(right, r, normal); + Cartesian3.add(nearCenter, normal, normal); + Cartesian3.subtract(normal, position, normal); + Cartesian3.cross(up, normal, normal); + Cartesian3.normalize(normal, normal); - StringEntryProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.StringEntryProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.stringId = reader.fixed32(); - break; - case 2: - message.stringValue = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + plane = planes[1]; + if (!defined(plane)) { + plane = planes[1] = new Cartesian4(); + } + plane.x = normal.x; + plane.y = normal.y; + plane.z = normal.z; + plane.w = -Cartesian3.dot(normal, position); - StringEntryProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isInteger(message.stringId)) - return "stringId: integer expected"; - if (!$util.isString(message.stringValue)) - return "stringValue: string expected"; - return null; - }; + //Bottom plane computation + Cartesian3.multiplyByScalar(up, b, normal); + Cartesian3.add(nearCenter, normal, normal); + Cartesian3.subtract(normal, position, normal); + Cartesian3.cross(right, normal, normal); + Cartesian3.normalize(normal, normal); - StringEntryProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.StringEntryProto) - return object; - var message = new $root.keyhole.dbroot.StringEntryProto(); - if (object.stringId !== undefined && object.stringId !== null) - message.stringId = object.stringId >>> 0; - if (object.stringValue !== undefined && object.stringValue !== null) - message.stringValue = String(object.stringValue); - return message; - }; + plane = planes[2]; + if (!defined(plane)) { + plane = planes[2] = new Cartesian4(); + } + plane.x = normal.x; + plane.y = normal.y; + plane.z = normal.z; + plane.w = -Cartesian3.dot(normal, position); - StringEntryProto.from = StringEntryProto.fromObject; + //Top plane computation + Cartesian3.multiplyByScalar(up, t, normal); + Cartesian3.add(nearCenter, normal, normal); + Cartesian3.subtract(normal, position, normal); + Cartesian3.cross(normal, right, normal); + Cartesian3.normalize(normal, normal); - StringEntryProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.stringId = 0; - object.stringValue = ""; - } - if (message.stringId !== undefined && message.stringId !== null && message.hasOwnProperty("stringId")) - object.stringId = message.stringId; - if (message.stringValue !== undefined && message.stringValue !== null && message.hasOwnProperty("stringValue")) - object.stringValue = message.stringValue; - return object; - }; + plane = planes[3]; + if (!defined(plane)) { + plane = planes[3] = new Cartesian4(); + } + plane.x = normal.x; + plane.y = normal.y; + plane.z = normal.z; + plane.w = -Cartesian3.dot(normal, position); - StringEntryProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + //Near plane computation + plane = planes[4]; + if (!defined(plane)) { + plane = planes[4] = new Cartesian4(); + } + plane.x = direction.x; + plane.y = direction.y; + plane.z = direction.z; + plane.w = -Cartesian3.dot(direction, nearCenter); - StringEntryProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + //Far plane computation + Cartesian3.negate(direction, normal); - return StringEntryProto; - })(); + plane = planes[5]; + if (!defined(plane)) { + plane = planes[5] = new Cartesian4(); + } + plane.x = normal.x; + plane.y = normal.y; + plane.z = normal.z; + plane.w = -Cartesian3.dot(normal, farCenter); - dbroot.StringIdOrValueProto = (function() { + return this._cullingVolume; + }; - function StringIdOrValueProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + /** + * Returns the pixel's width and height in meters. + * + * @param {Number} drawingBufferWidth The width of the drawing buffer. + * @param {Number} drawingBufferHeight The height of the drawing buffer. + * @param {Number} distance The distance to the near plane in meters. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. + * + * @exception {DeveloperError} drawingBufferWidth must be greater than zero. + * @exception {DeveloperError} drawingBufferHeight must be greater than zero. + * + * @example + * // Example 1 + * // Get the width and height of a pixel. + * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 1.0, new Cesium.Cartesian2()); + * + * @example + * // Example 2 + * // Get the width and height of a pixel if the near plane was set to 'distance'. + * // For example, get the size of a pixel of an image on a billboard. + * var position = camera.position; + * var direction = camera.direction; + * var toCenter = Cesium.Cartesian3.subtract(primitive.boundingVolume.center, position, new Cesium.Cartesian3()); // vector from camera to a primitive + * var toCenterProj = Cesium.Cartesian3.multiplyByScalar(direction, Cesium.Cartesian3.dot(direction, toCenter), new Cesium.Cartesian3()); // project vector onto camera direction vector + * var distance = Cesium.Cartesian3.magnitude(toCenterProj); + * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, distance, new Cesium.Cartesian2()); + */ + PerspectiveOffCenterFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { + update(this); - StringIdOrValueProto.prototype.stringId = 0; - StringIdOrValueProto.prototype.value = ""; + if (!defined(drawingBufferWidth) || !defined(drawingBufferHeight)) { + throw new DeveloperError('Both drawingBufferWidth and drawingBufferHeight are required.'); + } + if (drawingBufferWidth <= 0) { + throw new DeveloperError('drawingBufferWidth must be greater than zero.'); + } + if (drawingBufferHeight <= 0) { + throw new DeveloperError('drawingBufferHeight must be greater than zero.'); + } + if (!defined(distance)) { + throw new DeveloperError('distance is required.'); + } + if (!defined(result)) { + throw new DeveloperError('A result object is required.'); + } + + var inverseNear = 1.0 / this.near; + var tanTheta = this.top * inverseNear; + var pixelHeight = 2.0 * distance * tanTheta / drawingBufferHeight; + tanTheta = this.right * inverseNear; + var pixelWidth = 2.0 * distance * tanTheta / drawingBufferWidth; - StringIdOrValueProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.StringIdOrValueProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.stringId = reader.fixed32(); - break; - case 2: - message.value = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + result.x = pixelWidth; + result.y = pixelHeight; + return result; + }; - StringIdOrValueProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.stringId !== undefined) - if (!$util.isInteger(message.stringId)) - return "stringId: integer expected"; - if (message.value !== undefined) - if (!$util.isString(message.value)) - return "value: string expected"; - return null; - }; + /** + * Returns a duplicate of a PerspectiveOffCenterFrustum instance. + * + * @param {PerspectiveOffCenterFrustum} [result] The object onto which to store the result. + * @returns {PerspectiveOffCenterFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. + */ + PerspectiveOffCenterFrustum.prototype.clone = function(result) { + if (!defined(result)) { + result = new PerspectiveOffCenterFrustum(); + } - StringIdOrValueProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.StringIdOrValueProto) - return object; - var message = new $root.keyhole.dbroot.StringIdOrValueProto(); - if (object.stringId !== undefined && object.stringId !== null) - message.stringId = object.stringId >>> 0; - if (object.value !== undefined && object.value !== null) - message.value = String(object.value); - return message; - }; + result.right = this.right; + result.left = this.left; + result.top = this.top; + result.bottom = this.bottom; + result.near = this.near; + result.far = this.far; - StringIdOrValueProto.from = StringIdOrValueProto.fromObject; + // force update of clone to compute matrices + result._left = undefined; + result._right = undefined; + result._top = undefined; + result._bottom = undefined; + result._near = undefined; + result._far = undefined; - StringIdOrValueProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.stringId = 0; - object.value = ""; - } - if (message.stringId !== undefined && message.stringId !== null && message.hasOwnProperty("stringId")) - object.stringId = message.stringId; - if (message.value !== undefined && message.value !== null && message.hasOwnProperty("value")) - object.value = message.value; - return object; - }; + return result; + }; - StringIdOrValueProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + /** + * Compares the provided PerspectiveOffCenterFrustum componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {PerspectiveOffCenterFrustum} [other] The right hand side PerspectiveOffCenterFrustum. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + PerspectiveOffCenterFrustum.prototype.equals = function(other) { + return (defined(other) && + this.right === other.right && + this.left === other.left && + this.top === other.top && + this.bottom === other.bottom && + this.near === other.near && + this.far === other.far); + }; - StringIdOrValueProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + return PerspectiveOffCenterFrustum; +}); - return StringIdOrValueProto; - })(); +define('Core/PerspectiveFrustum',[ + './Check', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './PerspectiveOffCenterFrustum' + ], function( + Check, + defaultValue, + defined, + defineProperties, + DeveloperError, + PerspectiveOffCenterFrustum) { + 'use strict'; - dbroot.PlanetModelProto = (function() { + /** + * The viewing frustum is defined by 6 planes. + * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components + * define the unit vector normal to the plane, and the w component is the distance of the + * plane from the origin/camera position. + * + * @alias PerspectiveFrustum + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.fov] The angle of the field of view (FOV), in radians. + * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. + * @param {Number} [options.near=1.0] The distance of the near plane. + * @param {Number} [options.far=500000000.0] The distance of the far plane. + * @param {Number} [options.xOffset=0.0] The offset in the x direction. + * @param {Number} [options.yOffset=0.0] The offset in the y direction. + * + * @example + * var frustum = new Cesium.PerspectiveFrustum({ + * fov : Cesium.Math.PI_OVER_THREE, + * aspectRatio : canvas.clientWidth / canvas.clientHeight + * near : 1.0, + * far : 1000.0 + * }); + * + * @see PerspectiveOffCenterFrustum + */ + function PerspectiveFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - function PlanetModelProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + this._offCenterFrustum = new PerspectiveOffCenterFrustum(); - PlanetModelProto.prototype.radius = 6378.137; - PlanetModelProto.prototype.flattening = 0.00335281066474748; - PlanetModelProto.prototype.elevationBias = 0; - PlanetModelProto.prototype.negativeAltitudeExponentBias = 0; - PlanetModelProto.prototype.compressedNegativeAltitudeThreshold = 0; + /** + * The angle of the field of view (FOV), in radians. This angle will be used + * as the horizontal FOV if the width is greater than the height, otherwise + * it will be the vertical FOV. + * @type {Number} + * @default undefined + */ + this.fov = options.fov; + this._fov = undefined; + this._fovy = undefined; - PlanetModelProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.PlanetModelProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.radius = reader.double(); - break; - case 2: - message.flattening = reader.double(); - break; - case 4: - message.elevationBias = reader.double(); - break; - case 5: - message.negativeAltitudeExponentBias = reader.int32(); - break; - case 6: - message.compressedNegativeAltitudeThreshold = reader.double(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + this._sseDenominator = undefined; - PlanetModelProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.radius !== undefined) - if (typeof message.radius !== "number") - return "radius: number expected"; - if (message.flattening !== undefined) - if (typeof message.flattening !== "number") - return "flattening: number expected"; - if (message.elevationBias !== undefined) - if (typeof message.elevationBias !== "number") - return "elevationBias: number expected"; - if (message.negativeAltitudeExponentBias !== undefined) - if (!$util.isInteger(message.negativeAltitudeExponentBias)) - return "negativeAltitudeExponentBias: integer expected"; - if (message.compressedNegativeAltitudeThreshold !== undefined) - if (typeof message.compressedNegativeAltitudeThreshold !== "number") - return "compressedNegativeAltitudeThreshold: number expected"; - return null; - }; + /** + * The aspect ratio of the frustum's width to it's height. + * @type {Number} + * @default undefined + */ + this.aspectRatio = options.aspectRatio; + this._aspectRatio = undefined; - PlanetModelProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.PlanetModelProto) - return object; - var message = new $root.keyhole.dbroot.PlanetModelProto(); - if (object.radius !== undefined && object.radius !== null) - message.radius = Number(object.radius); - if (object.flattening !== undefined && object.flattening !== null) - message.flattening = Number(object.flattening); - if (object.elevationBias !== undefined && object.elevationBias !== null) - message.elevationBias = Number(object.elevationBias); - if (object.negativeAltitudeExponentBias !== undefined && object.negativeAltitudeExponentBias !== null) - message.negativeAltitudeExponentBias = object.negativeAltitudeExponentBias | 0; - if (object.compressedNegativeAltitudeThreshold !== undefined && object.compressedNegativeAltitudeThreshold !== null) - message.compressedNegativeAltitudeThreshold = Number(object.compressedNegativeAltitudeThreshold); - return message; - }; + /** + * The distance of the near plane. + * @type {Number} + * @default 1.0 + */ + this.near = defaultValue(options.near, 1.0); + this._near = this.near; - PlanetModelProto.from = PlanetModelProto.fromObject; + /** + * The distance of the far plane. + * @type {Number} + * @default 500000000.0 + */ + this.far = defaultValue(options.far, 500000000.0); + this._far = this.far; - PlanetModelProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.radius = 6378.137; - object.flattening = 0.00335281066474748; - object.elevationBias = 0; - object.negativeAltitudeExponentBias = 0; - object.compressedNegativeAltitudeThreshold = 0; - } - if (message.radius !== undefined && message.radius !== null && message.hasOwnProperty("radius")) - object.radius = message.radius; - if (message.flattening !== undefined && message.flattening !== null && message.hasOwnProperty("flattening")) - object.flattening = message.flattening; - if (message.elevationBias !== undefined && message.elevationBias !== null && message.hasOwnProperty("elevationBias")) - object.elevationBias = message.elevationBias; - if (message.negativeAltitudeExponentBias !== undefined && message.negativeAltitudeExponentBias !== null && message.hasOwnProperty("negativeAltitudeExponentBias")) - object.negativeAltitudeExponentBias = message.negativeAltitudeExponentBias; - if (message.compressedNegativeAltitudeThreshold !== undefined && message.compressedNegativeAltitudeThreshold !== null && message.hasOwnProperty("compressedNegativeAltitudeThreshold")) - object.compressedNegativeAltitudeThreshold = message.compressedNegativeAltitudeThreshold; - return object; - }; + /** + * Offsets the frustum in the x direction. + * @type {Number} + * @default 0.0 + */ + this.xOffset = defaultValue(options.xOffset, 0.0); + this._xOffset = this.xOffset; - PlanetModelProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + /** + * Offsets the frustum in the y direction. + * @type {Number} + * @default 0.0 + */ + this.yOffset = defaultValue(options.yOffset, 0.0); + this._yOffset = this.yOffset; + } - PlanetModelProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + PerspectiveFrustum.packedLength = 6; - return PlanetModelProto; - })(); + /** + * Stores the provided instance into the provided array. + * + * @param {PerspectiveFrustum} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + PerspectiveFrustum.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - dbroot.ProviderInfoProto = (function() { + array[startingIndex++] = value.fov; + array[startingIndex++] = value.aspectRatio; + array[startingIndex++] = value.near; + array[startingIndex++] = value.far; + array[startingIndex++] = value.xOffset; + array[startingIndex] = value.yOffset; - function ProviderInfoProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + return array; + }; - ProviderInfoProto.prototype.providerId = 0; - ProviderInfoProto.prototype.copyrightString = null; - ProviderInfoProto.prototype.verticalPixelOffset = -1; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {PerspectiveFrustum} [result] The object into which to store the result. + * @returns {PerspectiveFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. + */ + PerspectiveFrustum.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - var $types = { - 1 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); + if (!defined(result)) { + result = new PerspectiveFrustum(); + } - ProviderInfoProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ProviderInfoProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.providerId = reader.int32(); - break; - case 2: - message.copyrightString = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.verticalPixelOffset = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + result.fov = array[startingIndex++]; + result.aspectRatio = array[startingIndex++]; + result.near = array[startingIndex++]; + result.far = array[startingIndex++]; + result.xOffset = array[startingIndex++]; + result.yOffset = array[startingIndex]; - ProviderInfoProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isInteger(message.providerId)) - return "providerId: integer expected"; - if (message.copyrightString !== undefined && message.copyrightString !== null) { - var error = $types[1].verify(message.copyrightString); - if (error) - return "copyrightString." + error; - } - if (message.verticalPixelOffset !== undefined) - if (!$util.isInteger(message.verticalPixelOffset)) - return "verticalPixelOffset: integer expected"; - return null; - }; + return result; + }; - ProviderInfoProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ProviderInfoProto) - return object; - var message = new $root.keyhole.dbroot.ProviderInfoProto(); - if (object.providerId !== undefined && object.providerId !== null) - message.providerId = object.providerId | 0; - if (object.copyrightString !== undefined && object.copyrightString !== null) { - if (typeof object.copyrightString !== "object") - throw TypeError(".keyhole.dbroot.ProviderInfoProto.copyrightString: object expected"); - message.copyrightString = $types[1].fromObject(object.copyrightString); - } - if (object.verticalPixelOffset !== undefined && object.verticalPixelOffset !== null) - message.verticalPixelOffset = object.verticalPixelOffset | 0; - return message; - }; + function update(frustum) { + if (!defined(frustum.fov) || !defined(frustum.aspectRatio) || !defined(frustum.near) || !defined(frustum.far)) { + throw new DeveloperError('fov, aspectRatio, near, or far parameters are not set.'); + } + + var f = frustum._offCenterFrustum; - ProviderInfoProto.from = ProviderInfoProto.fromObject; + if (frustum.fov !== frustum._fov || frustum.aspectRatio !== frustum._aspectRatio || + frustum.near !== frustum._near || frustum.far !== frustum._far || + frustum.xOffset !== frustum._xOffset || frustum.yOffset !== frustum._yOffset) { + if (frustum.fov < 0 || frustum.fov >= Math.PI) { + throw new DeveloperError('fov must be in the range [0, PI).'); + } - ProviderInfoProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.providerId = 0; - object.copyrightString = null; - object.verticalPixelOffset = -1; - } - if (message.providerId !== undefined && message.providerId !== null && message.hasOwnProperty("providerId")) - object.providerId = message.providerId; - if (message.copyrightString !== undefined && message.copyrightString !== null && message.hasOwnProperty("copyrightString")) - object.copyrightString = $types[1].toObject(message.copyrightString, options); - if (message.verticalPixelOffset !== undefined && message.verticalPixelOffset !== null && message.hasOwnProperty("verticalPixelOffset")) - object.verticalPixelOffset = message.verticalPixelOffset; - return object; - }; + if (frustum.aspectRatio < 0) { + throw new DeveloperError('aspectRatio must be positive.'); + } - ProviderInfoProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + if (frustum.near < 0 || frustum.near > frustum.far) { + throw new DeveloperError('near must be greater than zero and less than far.'); + } + + frustum._aspectRatio = frustum.aspectRatio; + frustum._fov = frustum.fov; + frustum._fovy = (frustum.aspectRatio <= 1) ? frustum.fov : Math.atan(Math.tan(frustum.fov * 0.5) / frustum.aspectRatio) * 2.0; + frustum._near = frustum.near; + frustum._far = frustum.far; + frustum._sseDenominator = 2.0 * Math.tan(0.5 * frustum._fovy); + frustum._xOffset = frustum.xOffset; + frustum._yOffset = frustum.yOffset; - ProviderInfoProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + f.top = frustum.near * Math.tan(0.5 * frustum._fovy); + f.bottom = -f.top; + f.right = frustum.aspectRatio * f.top; + f.left = -f.right; + f.near = frustum.near; + f.far = frustum.far; - return ProviderInfoProto; - })(); + f.right += frustum.xOffset; + f.left += frustum.xOffset; + f.top += frustum.yOffset; + f.bottom += frustum.yOffset; + } + } - dbroot.PopUpProto = (function() { + defineProperties(PerspectiveFrustum.prototype, { + /** + * Gets the perspective projection matrix computed from the view frustum. + * @memberof PerspectiveFrustum.prototype + * @type {Matrix4} + * @readonly + * + * @see PerspectiveFrustum#infiniteProjectionMatrix + */ + projectionMatrix : { + get : function() { + update(this); + return this._offCenterFrustum.projectionMatrix; + } + }, - function PopUpProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + /** + * The perspective projection matrix computed from the view frustum with an infinite far plane. + * @memberof PerspectiveFrustum.prototype + * @type {Matrix4} + * @readonly + * + * @see PerspectiveFrustum#projectionMatrix + */ + infiniteProjectionMatrix : { + get : function() { + update(this); + return this._offCenterFrustum.infiniteProjectionMatrix; + } + }, - PopUpProto.prototype.isBalloonStyle = false; - PopUpProto.prototype.text = null; - PopUpProto.prototype.backgroundColorAbgr = 4294967295; - PopUpProto.prototype.textColorAbgr = 4278190080; + /** + * Gets the angle of the vertical field of view, in radians. + * @memberof PerspectiveFrustum.prototype + * @type {Number} + * @readonly + * @default undefined + */ + fovy : { + get : function() { + update(this); + return this._fovy; + } + }, - var $types = { - 1 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); + /** + * @readonly + * @private + */ + sseDenominator : { + get : function () { + update(this); + return this._sseDenominator; + } + } + }); - PopUpProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.PopUpProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.isBalloonStyle = reader.bool(); - break; - case 2: - message.text = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.backgroundColorAbgr = reader.fixed32(); - break; - case 4: - message.textColorAbgr = reader.fixed32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + /** + * Creates a culling volume for this frustum. + * + * @param {Cartesian3} position The eye position. + * @param {Cartesian3} direction The view direction. + * @param {Cartesian3} up The up direction. + * @returns {CullingVolume} A culling volume at the given position and orientation. + * + * @example + * // Check if a bounding volume intersects the frustum. + * var cullingVolume = frustum.computeCullingVolume(cameraPosition, cameraDirection, cameraUp); + * var intersect = cullingVolume.computeVisibility(boundingVolume); + */ + PerspectiveFrustum.prototype.computeCullingVolume = function(position, direction, up) { + update(this); + return this._offCenterFrustum.computeCullingVolume(position, direction, up); + }; - PopUpProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.isBalloonStyle !== undefined) - if (typeof message.isBalloonStyle !== "boolean") - return "isBalloonStyle: boolean expected"; - if (message.text !== undefined && message.text !== null) { - var error = $types[1].verify(message.text); - if (error) - return "text." + error; - } - if (message.backgroundColorAbgr !== undefined) - if (!$util.isInteger(message.backgroundColorAbgr)) - return "backgroundColorAbgr: integer expected"; - if (message.textColorAbgr !== undefined) - if (!$util.isInteger(message.textColorAbgr)) - return "textColorAbgr: integer expected"; - return null; - }; + /** + * Returns the pixel's width and height in meters. + * + * @param {Number} drawingBufferWidth The width of the drawing buffer. + * @param {Number} drawingBufferHeight The height of the drawing buffer. + * @param {Number} distance The distance to the near plane in meters. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. + * + * @exception {DeveloperError} drawingBufferWidth must be greater than zero. + * @exception {DeveloperError} drawingBufferHeight must be greater than zero. + * + * @example + * // Example 1 + * // Get the width and height of a pixel. + * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, 1.0, new Cesium.Cartesian2()); + * + * @example + * // Example 2 + * // Get the width and height of a pixel if the near plane was set to 'distance'. + * // For example, get the size of a pixel of an image on a billboard. + * var position = camera.position; + * var direction = camera.direction; + * var toCenter = Cesium.Cartesian3.subtract(primitive.boundingVolume.center, position, new Cesium.Cartesian3()); // vector from camera to a primitive + * var toCenterProj = Cesium.Cartesian3.multiplyByScalar(direction, Cesium.Cartesian3.dot(direction, toCenter), new Cesium.Cartesian3()); // project vector onto camera direction vector + * var distance = Cesium.Cartesian3.magnitude(toCenterProj); + * var pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, distance, new Cesium.Cartesian2()); + */ + PerspectiveFrustum.prototype.getPixelDimensions = function(drawingBufferWidth, drawingBufferHeight, distance, result) { + update(this); + return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result); + }; - PopUpProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.PopUpProto) - return object; - var message = new $root.keyhole.dbroot.PopUpProto(); - if (object.isBalloonStyle !== undefined && object.isBalloonStyle !== null) - message.isBalloonStyle = Boolean(object.isBalloonStyle); - if (object.text !== undefined && object.text !== null) { - if (typeof object.text !== "object") - throw TypeError(".keyhole.dbroot.PopUpProto.text: object expected"); - message.text = $types[1].fromObject(object.text); - } - if (object.backgroundColorAbgr !== undefined && object.backgroundColorAbgr !== null) - message.backgroundColorAbgr = object.backgroundColorAbgr >>> 0; - if (object.textColorAbgr !== undefined && object.textColorAbgr !== null) - message.textColorAbgr = object.textColorAbgr >>> 0; - return message; - }; + /** + * Returns a duplicate of a PerspectiveFrustum instance. + * + * @param {PerspectiveFrustum} [result] The object onto which to store the result. + * @returns {PerspectiveFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. + */ + PerspectiveFrustum.prototype.clone = function(result) { + if (!defined(result)) { + result = new PerspectiveFrustum(); + } - PopUpProto.from = PopUpProto.fromObject; + result.aspectRatio = this.aspectRatio; + result.fov = this.fov; + result.near = this.near; + result.far = this.far; - PopUpProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.isBalloonStyle = false; - object.text = null; - object.backgroundColorAbgr = 4294967295; - object.textColorAbgr = 4278190080; - } - if (message.isBalloonStyle !== undefined && message.isBalloonStyle !== null && message.hasOwnProperty("isBalloonStyle")) - object.isBalloonStyle = message.isBalloonStyle; - if (message.text !== undefined && message.text !== null && message.hasOwnProperty("text")) - object.text = $types[1].toObject(message.text, options); - if (message.backgroundColorAbgr !== undefined && message.backgroundColorAbgr !== null && message.hasOwnProperty("backgroundColorAbgr")) - object.backgroundColorAbgr = message.backgroundColorAbgr; - if (message.textColorAbgr !== undefined && message.textColorAbgr !== null && message.hasOwnProperty("textColorAbgr")) - object.textColorAbgr = message.textColorAbgr; - return object; - }; + // force update of clone to compute matrices + result._aspectRatio = undefined; + result._fov = undefined; + result._near = undefined; + result._far = undefined; - PopUpProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + this._offCenterFrustum.clone(result._offCenterFrustum); - PopUpProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + return result; + }; - return PopUpProto; - })(); + /** + * Compares the provided PerspectiveFrustum componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {PerspectiveFrustum} [other] The right hand side PerspectiveFrustum. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + PerspectiveFrustum.prototype.equals = function(other) { + if (!defined(other)) { + return false; + } - dbroot.StyleAttributeProto = (function() { + update(this); + update(other); - function StyleAttributeProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + return (this.fov === other.fov && + this.aspectRatio === other.aspectRatio && + this.near === other.near && + this.far === other.far && + this._offCenterFrustum.equals(other._offCenterFrustum)); + }; - StyleAttributeProto.prototype.styleId = ""; - StyleAttributeProto.prototype.providerId = 0; - StyleAttributeProto.prototype.polyColorAbgr = 4294967295; - StyleAttributeProto.prototype.lineColorAbgr = 4294967295; - StyleAttributeProto.prototype.lineWidth = 1; - StyleAttributeProto.prototype.labelColorAbgr = 4294967295; - StyleAttributeProto.prototype.labelScale = 1; - StyleAttributeProto.prototype.placemarkIconColorAbgr = 4294967295; - StyleAttributeProto.prototype.placemarkIconScale = 1; - StyleAttributeProto.prototype.placemarkIconPath = null; - StyleAttributeProto.prototype.placemarkIconX = 0; - StyleAttributeProto.prototype.placemarkIconY = 0; - StyleAttributeProto.prototype.placemarkIconWidth = 32; - StyleAttributeProto.prototype.placemarkIconHeight = 32; - StyleAttributeProto.prototype.popUp = null; - StyleAttributeProto.prototype.drawFlag = $util.emptyArray; + return PerspectiveFrustum; +}); - var $types = { - 9 : "keyhole.dbroot.StringIdOrValueProto", - 14 : "keyhole.dbroot.PopUpProto", - 15 : "keyhole.dbroot.DrawFlagProto" - }; - $lazyTypes.push($types); +define('Core/FrustumGeometry',[ + './BoundingSphere', + './Cartesian3', + './Cartesian4', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './Matrix3', + './Matrix4', + './OrthographicFrustum', + './PerspectiveFrustum', + './PrimitiveType', + './Quaternion', + './VertexFormat' + ], function( + BoundingSphere, + Cartesian3, + Cartesian4, + Check, + ComponentDatatype, + defaultValue, + defined, + Geometry, + GeometryAttribute, + GeometryAttributes, + Matrix3, + Matrix4, + OrthographicFrustum, + PerspectiveFrustum, + PrimitiveType, + Quaternion, + VertexFormat) { + 'use strict'; - StyleAttributeProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.StyleAttributeProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.styleId = reader.string(); - break; - case 3: - message.providerId = reader.int32(); - break; - case 4: - message.polyColorAbgr = reader.fixed32(); - break; - case 5: - message.lineColorAbgr = reader.fixed32(); - break; - case 6: - message.lineWidth = reader.float(); - break; - case 7: - message.labelColorAbgr = reader.fixed32(); - break; - case 8: - message.labelScale = reader.float(); - break; - case 9: - message.placemarkIconColorAbgr = reader.fixed32(); - break; - case 10: - message.placemarkIconScale = reader.float(); - break; - case 11: - message.placemarkIconPath = $types[9].decode(reader, reader.uint32()); - break; - case 12: - message.placemarkIconX = reader.int32(); - break; - case 13: - message.placemarkIconY = reader.int32(); - break; - case 14: - message.placemarkIconWidth = reader.int32(); - break; - case 15: - message.placemarkIconHeight = reader.int32(); - break; - case 16: - message.popUp = $types[14].decode(reader, reader.uint32()); - break; - case 17: - if (!(message.drawFlag && message.drawFlag.length)) - message.drawFlag = []; - message.drawFlag.push($types[15].decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + var PERSPECTIVE = 0; + var ORTHOGRAPHIC = 1; - StyleAttributeProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isString(message.styleId)) - return "styleId: string expected"; - if (message.providerId !== undefined) - if (!$util.isInteger(message.providerId)) - return "providerId: integer expected"; - if (message.polyColorAbgr !== undefined) - if (!$util.isInteger(message.polyColorAbgr)) - return "polyColorAbgr: integer expected"; - if (message.lineColorAbgr !== undefined) - if (!$util.isInteger(message.lineColorAbgr)) - return "lineColorAbgr: integer expected"; - if (message.lineWidth !== undefined) - if (typeof message.lineWidth !== "number") - return "lineWidth: number expected"; - if (message.labelColorAbgr !== undefined) - if (!$util.isInteger(message.labelColorAbgr)) - return "labelColorAbgr: integer expected"; - if (message.labelScale !== undefined) - if (typeof message.labelScale !== "number") - return "labelScale: number expected"; - if (message.placemarkIconColorAbgr !== undefined) - if (!$util.isInteger(message.placemarkIconColorAbgr)) - return "placemarkIconColorAbgr: integer expected"; - if (message.placemarkIconScale !== undefined) - if (typeof message.placemarkIconScale !== "number") - return "placemarkIconScale: number expected"; - if (message.placemarkIconPath !== undefined && message.placemarkIconPath !== null) { - var error = $types[9].verify(message.placemarkIconPath); - if (error) - return "placemarkIconPath." + error; - } - if (message.placemarkIconX !== undefined) - if (!$util.isInteger(message.placemarkIconX)) - return "placemarkIconX: integer expected"; - if (message.placemarkIconY !== undefined) - if (!$util.isInteger(message.placemarkIconY)) - return "placemarkIconY: integer expected"; - if (message.placemarkIconWidth !== undefined) - if (!$util.isInteger(message.placemarkIconWidth)) - return "placemarkIconWidth: integer expected"; - if (message.placemarkIconHeight !== undefined) - if (!$util.isInteger(message.placemarkIconHeight)) - return "placemarkIconHeight: integer expected"; - if (message.popUp !== undefined && message.popUp !== null) { - var error = $types[14].verify(message.popUp); - if (error) - return "popUp." + error; - } - if (message.drawFlag !== undefined) { - if (!Array.isArray(message.drawFlag)) - return "drawFlag: array expected"; - for (var i = 0; i < message.drawFlag.length; ++i) { - var error = $types[15].verify(message.drawFlag[i]); - if (error) - return "drawFlag." + error; - } - } - return null; - }; + /** + * Describes a frustum at the given the origin and orientation. + * + * @alias FrustumGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. + * @param {Cartesian3} options.origin The origin of the frustum. + * @param {Quaternion} options.orientation The orientation of the frustum. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + */ + function FrustumGeometry(options) { + Check.typeOf.object('options', options); + Check.typeOf.object('options.frustum', options.frustum); + Check.typeOf.object('options.origin', options.origin); + Check.typeOf.object('options.orientation', options.orientation); + + var frustum = options.frustum; + var orientation = options.orientation; + var origin = options.origin; + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); - StyleAttributeProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.StyleAttributeProto) - return object; - var message = new $root.keyhole.dbroot.StyleAttributeProto(); - if (object.styleId !== undefined && object.styleId !== null) - message.styleId = String(object.styleId); - if (object.providerId !== undefined && object.providerId !== null) - message.providerId = object.providerId | 0; - if (object.polyColorAbgr !== undefined && object.polyColorAbgr !== null) - message.polyColorAbgr = object.polyColorAbgr >>> 0; - if (object.lineColorAbgr !== undefined && object.lineColorAbgr !== null) - message.lineColorAbgr = object.lineColorAbgr >>> 0; - if (object.lineWidth !== undefined && object.lineWidth !== null) - message.lineWidth = Number(object.lineWidth); - if (object.labelColorAbgr !== undefined && object.labelColorAbgr !== null) - message.labelColorAbgr = object.labelColorAbgr >>> 0; - if (object.labelScale !== undefined && object.labelScale !== null) - message.labelScale = Number(object.labelScale); - if (object.placemarkIconColorAbgr !== undefined && object.placemarkIconColorAbgr !== null) - message.placemarkIconColorAbgr = object.placemarkIconColorAbgr >>> 0; - if (object.placemarkIconScale !== undefined && object.placemarkIconScale !== null) - message.placemarkIconScale = Number(object.placemarkIconScale); - if (object.placemarkIconPath !== undefined && object.placemarkIconPath !== null) { - if (typeof object.placemarkIconPath !== "object") - throw TypeError(".keyhole.dbroot.StyleAttributeProto.placemarkIconPath: object expected"); - message.placemarkIconPath = $types[9].fromObject(object.placemarkIconPath); - } - if (object.placemarkIconX !== undefined && object.placemarkIconX !== null) - message.placemarkIconX = object.placemarkIconX | 0; - if (object.placemarkIconY !== undefined && object.placemarkIconY !== null) - message.placemarkIconY = object.placemarkIconY | 0; - if (object.placemarkIconWidth !== undefined && object.placemarkIconWidth !== null) - message.placemarkIconWidth = object.placemarkIconWidth | 0; - if (object.placemarkIconHeight !== undefined && object.placemarkIconHeight !== null) - message.placemarkIconHeight = object.placemarkIconHeight | 0; - if (object.popUp !== undefined && object.popUp !== null) { - if (typeof object.popUp !== "object") - throw TypeError(".keyhole.dbroot.StyleAttributeProto.popUp: object expected"); - message.popUp = $types[14].fromObject(object.popUp); - } - if (object.drawFlag) { - if (!Array.isArray(object.drawFlag)) - throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: array expected"); - message.drawFlag = []; - for (var i = 0; i < object.drawFlag.length; ++i) { - if (typeof object.drawFlag[i] !== "object") - throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: object expected"); - message.drawFlag[i] = $types[15].fromObject(object.drawFlag[i]); - } - } - return message; - }; - - StyleAttributeProto.from = StyleAttributeProto.fromObject; + // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by + // creating multiple FrustumGeometrys. This way the near plane of one frustum doesn't overlap + // the far plane of another. + var drawNearPlane = defaultValue(options._drawNearPlane, true); - StyleAttributeProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.drawFlag = []; - if (options.defaults) { - object.styleId = ""; - object.providerId = 0; - object.polyColorAbgr = 4294967295; - object.lineColorAbgr = 4294967295; - object.lineWidth = 1; - object.labelColorAbgr = 4294967295; - object.labelScale = 1; - object.placemarkIconColorAbgr = 4294967295; - object.placemarkIconScale = 1; - object.placemarkIconPath = null; - object.placemarkIconX = 0; - object.placemarkIconY = 0; - object.placemarkIconWidth = 32; - object.placemarkIconHeight = 32; - object.popUp = null; - } - if (message.styleId !== undefined && message.styleId !== null && message.hasOwnProperty("styleId")) - object.styleId = message.styleId; - if (message.providerId !== undefined && message.providerId !== null && message.hasOwnProperty("providerId")) - object.providerId = message.providerId; - if (message.polyColorAbgr !== undefined && message.polyColorAbgr !== null && message.hasOwnProperty("polyColorAbgr")) - object.polyColorAbgr = message.polyColorAbgr; - if (message.lineColorAbgr !== undefined && message.lineColorAbgr !== null && message.hasOwnProperty("lineColorAbgr")) - object.lineColorAbgr = message.lineColorAbgr; - if (message.lineWidth !== undefined && message.lineWidth !== null && message.hasOwnProperty("lineWidth")) - object.lineWidth = message.lineWidth; - if (message.labelColorAbgr !== undefined && message.labelColorAbgr !== null && message.hasOwnProperty("labelColorAbgr")) - object.labelColorAbgr = message.labelColorAbgr; - if (message.labelScale !== undefined && message.labelScale !== null && message.hasOwnProperty("labelScale")) - object.labelScale = message.labelScale; - if (message.placemarkIconColorAbgr !== undefined && message.placemarkIconColorAbgr !== null && message.hasOwnProperty("placemarkIconColorAbgr")) - object.placemarkIconColorAbgr = message.placemarkIconColorAbgr; - if (message.placemarkIconScale !== undefined && message.placemarkIconScale !== null && message.hasOwnProperty("placemarkIconScale")) - object.placemarkIconScale = message.placemarkIconScale; - if (message.placemarkIconPath !== undefined && message.placemarkIconPath !== null && message.hasOwnProperty("placemarkIconPath")) - object.placemarkIconPath = $types[9].toObject(message.placemarkIconPath, options); - if (message.placemarkIconX !== undefined && message.placemarkIconX !== null && message.hasOwnProperty("placemarkIconX")) - object.placemarkIconX = message.placemarkIconX; - if (message.placemarkIconY !== undefined && message.placemarkIconY !== null && message.hasOwnProperty("placemarkIconY")) - object.placemarkIconY = message.placemarkIconY; - if (message.placemarkIconWidth !== undefined && message.placemarkIconWidth !== null && message.hasOwnProperty("placemarkIconWidth")) - object.placemarkIconWidth = message.placemarkIconWidth; - if (message.placemarkIconHeight !== undefined && message.placemarkIconHeight !== null && message.hasOwnProperty("placemarkIconHeight")) - object.placemarkIconHeight = message.placemarkIconHeight; - if (message.popUp !== undefined && message.popUp !== null && message.hasOwnProperty("popUp")) - object.popUp = $types[14].toObject(message.popUp, options); - if (message.drawFlag !== undefined && message.drawFlag !== null && message.hasOwnProperty("drawFlag")) { - object.drawFlag = []; - for (var j = 0; j < message.drawFlag.length; ++j) - object.drawFlag[j] = $types[15].toObject(message.drawFlag[j], options); - } - return object; - }; + var frustumType; + var frustumPackedLength; + if (frustum instanceof PerspectiveFrustum) { + frustumType = PERSPECTIVE; + frustumPackedLength = PerspectiveFrustum.packedLength; + } else if (frustum instanceof OrthographicFrustum) { + frustumType = ORTHOGRAPHIC; + frustumPackedLength = OrthographicFrustum.packedLength; + } - StyleAttributeProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + this._frustumType = frustumType; + this._frustum = frustum.clone(); + this._origin = Cartesian3.clone(origin); + this._orientation = Quaternion.clone(orientation); + this._drawNearPlane = drawNearPlane; + this._vertexFormat = vertexFormat; + this._workerName = 'createFrustumGeometry'; - StyleAttributeProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength + VertexFormat.packedLength; + } - return StyleAttributeProto; - })(); + /** + * Stores the provided instance into the provided array. + * + * @param {FrustumGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + FrustumGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - dbroot.StyleMapProto = (function() { + var frustumType = value._frustumType; + var frustum = value._frustum; - function StyleMapProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + array[startingIndex++] = frustumType; - StyleMapProto.prototype.styleMapId = 0; - StyleMapProto.prototype.channelId = $util.emptyArray; - StyleMapProto.prototype.normalStyleAttribute = 0; - StyleMapProto.prototype.highlightStyleAttribute = 0; + if (frustumType === PERSPECTIVE) { + PerspectiveFrustum.pack(frustum, array, startingIndex); + startingIndex += PerspectiveFrustum.packedLength; + } else { + OrthographicFrustum.pack(frustum, array, startingIndex); + startingIndex += OrthographicFrustum.packedLength; + } - StyleMapProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.StyleMapProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.styleMapId = reader.int32(); - break; - case 2: - if (!(message.channelId && message.channelId.length)) - message.channelId = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) - message.channelId.push(reader.int32()); - } else - message.channelId.push(reader.int32()); - break; - case 3: - message.normalStyleAttribute = reader.int32(); - break; - case 4: - message.highlightStyleAttribute = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + Cartesian3.pack(value._origin, array, startingIndex); + startingIndex += Cartesian3.packedLength; + Quaternion.pack(value._orientation, array, startingIndex); + startingIndex += Quaternion.packedLength; + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0; - StyleMapProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isInteger(message.styleMapId)) - return "styleMapId: integer expected"; - if (message.channelId !== undefined) { - if (!Array.isArray(message.channelId)) - return "channelId: array expected"; - for (var i = 0; i < message.channelId.length; ++i) - if (!$util.isInteger(message.channelId[i])) - return "channelId: integer[] expected"; - } - if (message.normalStyleAttribute !== undefined) - if (!$util.isInteger(message.normalStyleAttribute)) - return "normalStyleAttribute: integer expected"; - if (message.highlightStyleAttribute !== undefined) - if (!$util.isInteger(message.highlightStyleAttribute)) - return "highlightStyleAttribute: integer expected"; - return null; - }; + return array; + }; - StyleMapProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.StyleMapProto) - return object; - var message = new $root.keyhole.dbroot.StyleMapProto(); - if (object.styleMapId !== undefined && object.styleMapId !== null) - message.styleMapId = object.styleMapId | 0; - if (object.channelId) { - if (!Array.isArray(object.channelId)) - throw TypeError(".keyhole.dbroot.StyleMapProto.channelId: array expected"); - message.channelId = []; - for (var i = 0; i < object.channelId.length; ++i) - message.channelId[i] = object.channelId[i] | 0; - } - if (object.normalStyleAttribute !== undefined && object.normalStyleAttribute !== null) - message.normalStyleAttribute = object.normalStyleAttribute | 0; - if (object.highlightStyleAttribute !== undefined && object.highlightStyleAttribute !== null) - message.highlightStyleAttribute = object.highlightStyleAttribute | 0; - return message; - }; + var scratchPackPerspective = new PerspectiveFrustum(); + var scratchPackOrthographic = new OrthographicFrustum(); + var scratchPackQuaternion = new Quaternion(); + var scratchPackorigin = new Cartesian3(); + var scratchVertexFormat = new VertexFormat(); - StyleMapProto.from = StyleMapProto.fromObject; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {FrustumGeometry} [result] The object into which to store the result. + */ + FrustumGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - StyleMapProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.channelId = []; - if (options.defaults) { - object.styleMapId = 0; - object.normalStyleAttribute = 0; - object.highlightStyleAttribute = 0; - } - if (message.styleMapId !== undefined && message.styleMapId !== null && message.hasOwnProperty("styleMapId")) - object.styleMapId = message.styleMapId; - if (message.channelId !== undefined && message.channelId !== null && message.hasOwnProperty("channelId")) { - object.channelId = []; - for (var j = 0; j < message.channelId.length; ++j) - object.channelId[j] = message.channelId[j]; - } - if (message.normalStyleAttribute !== undefined && message.normalStyleAttribute !== null && message.hasOwnProperty("normalStyleAttribute")) - object.normalStyleAttribute = message.normalStyleAttribute; - if (message.highlightStyleAttribute !== undefined && message.highlightStyleAttribute !== null && message.hasOwnProperty("highlightStyleAttribute")) - object.highlightStyleAttribute = message.highlightStyleAttribute; - return object; - }; + var frustumType = array[startingIndex++]; - StyleMapProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + var frustum; + if (frustumType === PERSPECTIVE) { + frustum = PerspectiveFrustum.unpack(array, startingIndex, scratchPackPerspective); + startingIndex += PerspectiveFrustum.packedLength; + } else { + frustum = OrthographicFrustum.unpack(array, startingIndex, scratchPackOrthographic); + startingIndex += OrthographicFrustum.packedLength; + } - StyleMapProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + var origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin); + startingIndex += Cartesian3.packedLength; + var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); + startingIndex += Quaternion.packedLength; + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; + var drawNearPlane = array[startingIndex] === 1.0; - return StyleMapProto; - })(); + if (!defined(result)) { + return new FrustumGeometry({ + frustum : frustum, + origin : origin, + orientation : orientation, + vertexFormat : vertexFormat, + _drawNearPlane : drawNearPlane + }); + } - dbroot.ZoomRangeProto = (function() { + var frustumResult = frustumType === result._frustumType ? result._frustum : undefined; + result._frustum = frustum.clone(frustumResult); - function ZoomRangeProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + result._frustumType = frustumType; + result._origin = Cartesian3.clone(origin, result._origin); + result._orientation = Quaternion.clone(orientation, result._orientation); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._drawNearPlane = drawNearPlane; - ZoomRangeProto.prototype.minZoom = 0; - ZoomRangeProto.prototype.maxZoom = 0; + return result; + }; - ZoomRangeProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ZoomRangeProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.minZoom = reader.int32(); - break; - case 2: - message.maxZoom = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + function getAttributes(offset, normals, tangents, bitangents, st, normal, tangent, bitangent) { + var stOffset = offset / 3 * 2; - ZoomRangeProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isInteger(message.minZoom)) - return "minZoom: integer expected"; - if (!$util.isInteger(message.maxZoom)) - return "maxZoom: integer expected"; - return null; - }; + for (var i = 0; i < 4; ++i) { + if (defined(normals)) { + normals[offset] = normal.x; + normals[offset + 1] = normal.y; + normals[offset + 2] = normal.z; + } + if (defined(tangents)) { + tangents[offset] = tangent.x; + tangents[offset + 1] = tangent.y; + tangents[offset + 2] = tangent.z; + } + if (defined(bitangents)) { + bitangents[offset] = bitangent.x; + bitangents[offset + 1] = bitangent.y; + bitangents[offset + 2] = bitangent.z; + } + offset += 3; + } - ZoomRangeProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ZoomRangeProto) - return object; - var message = new $root.keyhole.dbroot.ZoomRangeProto(); - if (object.minZoom !== undefined && object.minZoom !== null) - message.minZoom = object.minZoom | 0; - if (object.maxZoom !== undefined && object.maxZoom !== null) - message.maxZoom = object.maxZoom | 0; - return message; - }; + st[stOffset] = 0.0; + st[stOffset + 1] = 0.0; + st[stOffset + 2] = 1.0; + st[stOffset + 3] = 0.0; + st[stOffset + 4] = 1.0; + st[stOffset + 5] = 1.0; + st[stOffset + 6] = 0.0; + st[stOffset + 7] = 1.0; + } - ZoomRangeProto.from = ZoomRangeProto.fromObject; + var scratchRotationMatrix = new Matrix3(); + var scratchViewMatrix = new Matrix4(); + var scratchInverseMatrix = new Matrix4(); - ZoomRangeProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.minZoom = 0; - object.maxZoom = 0; - } - if (message.minZoom !== undefined && message.minZoom !== null && message.hasOwnProperty("minZoom")) - object.minZoom = message.minZoom; - if (message.maxZoom !== undefined && message.maxZoom !== null && message.hasOwnProperty("maxZoom")) - object.maxZoom = message.maxZoom; - return object; - }; + var scratchXDirection = new Cartesian3(); + var scratchYDirection = new Cartesian3(); + var scratchZDirection = new Cartesian3(); + var scratchNegativeX = new Cartesian3(); + var scratchNegativeY = new Cartesian3(); + var scratchNegativeZ = new Cartesian3(); - ZoomRangeProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + var frustumSplits = new Array(3); - ZoomRangeProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + var frustumCornersNDC = new Array(4); + frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0); + frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); - return ZoomRangeProto; - })(); + var scratchFrustumCorners = new Array(4); + for (var i = 0; i < 4; ++i) { + scratchFrustumCorners[i] = new Cartesian4(); + } - dbroot.DrawFlagProto = (function() { + FrustumGeometry._computeNearFarPlanes = function(origin, orientation, frustumType, frustum, positions, xDirection, yDirection, zDirection) { + var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); + var x = defaultValue(xDirection, scratchXDirection); + var y = defaultValue(yDirection, scratchYDirection); + var z = defaultValue(zDirection, scratchZDirection); - function DrawFlagProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + x = Matrix3.getColumn(rotationMatrix, 0, x); + y = Matrix3.getColumn(rotationMatrix, 1, y); + z = Matrix3.getColumn(rotationMatrix, 2, z); - DrawFlagProto.prototype.drawFlagType = 1; + Cartesian3.normalize(x, x); + Cartesian3.normalize(y, y); + Cartesian3.normalize(z, z); - var $types = { - 0 : "keyhole.dbroot.DrawFlagProto.DrawFlagType" - }; - $lazyTypes.push($types); + Cartesian3.negate(x, x); - DrawFlagProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.DrawFlagProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.drawFlagType = reader.uint32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + var view = Matrix4.computeView(origin, z, y, x, scratchViewMatrix); - DrawFlagProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - switch (message.drawFlagType) { - default: - return "drawFlagType: enum value expected"; - case 1: - case 2: - case 3: - case 4: - case 5: - break; - } - return null; - }; + var inverseView; + var inverseViewProjection; + if (frustumType === PERSPECTIVE) { + var projection = frustum.projectionMatrix; + var viewProjection = Matrix4.multiply(projection, view, scratchInverseMatrix); + inverseViewProjection = Matrix4.inverse(viewProjection, scratchInverseMatrix); + } else { + inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); + } - DrawFlagProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.DrawFlagProto) - return object; - var message = new $root.keyhole.dbroot.DrawFlagProto(); - switch (object.drawFlagType) { - case "TYPE_FILL_ONLY": - case 1: - message.drawFlagType = 1; - break; - case "TYPE_OUTLINE_ONLY": - case 2: - message.drawFlagType = 2; - break; - case "TYPE_FILL_AND_OUTLINE": - case 3: - message.drawFlagType = 3; - break; - case "TYPE_ANTIALIASING": - case 4: - message.drawFlagType = 4; - break; - case "TYPE_CENTER_LABEL": - case 5: - message.drawFlagType = 5; - break; - } - return message; - }; + if (defined(inverseViewProjection)) { + frustumSplits[0] = frustum.near; + frustumSplits[1] = frustum.far; + } else { + frustumSplits[0] = 0.0; + frustumSplits[1] = frustum.near; + frustumSplits[2] = frustum.far; + } - DrawFlagProto.from = DrawFlagProto.fromObject; + for (var i = 0; i < 2; ++i) { + for (var j = 0; j < 4; ++j) { + var corner = Cartesian4.clone(frustumCornersNDC[j], scratchFrustumCorners[j]); - DrawFlagProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.drawFlagType = options.enums === String ? "TYPE_FILL_ONLY" : 1; - if (message.drawFlagType !== undefined && message.drawFlagType !== null && message.hasOwnProperty("drawFlagType")) - object.drawFlagType = options.enums === String ? $types[0][message.drawFlagType] : message.drawFlagType; - return object; - }; + if (!defined(inverseViewProjection)) { + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } - DrawFlagProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + var near = frustumSplits[i]; + var far = frustumSplits[i + 1]; - DrawFlagProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + corner.x = (corner.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; + corner.y = (corner.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; + corner.z = (corner.z * (near - far) - near - far) * 0.5; + corner.w = 1.0; - DrawFlagProto.DrawFlagType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values["TYPE_FILL_ONLY"] = 1; - values["TYPE_OUTLINE_ONLY"] = 2; - values["TYPE_FILL_AND_OUTLINE"] = 3; - values["TYPE_ANTIALIASING"] = 4; - values["TYPE_CENTER_LABEL"] = 5; - return values; - })(); + Matrix4.multiplyByVector(inverseView, corner, corner); + } else { + corner = Matrix4.multiplyByVector(inverseViewProjection, corner, corner); - return DrawFlagProto; - })(); + // Reverse perspective divide + var w = 1.0 / corner.w; + Cartesian3.multiplyByScalar(corner, w, corner); - dbroot.LayerProto = (function() { + Cartesian3.subtract(corner, origin, corner); + Cartesian3.normalize(corner, corner); - function LayerProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; + var fac = Cartesian3.dot(z, corner); + Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); + Cartesian3.add(corner, origin, corner); } - LayerProto.prototype.zoomRange = $util.emptyArray; - LayerProto.prototype.preserveTextLevel = 30; - LayerProto.prototype.lodBeginTransition = false; - LayerProto.prototype.lodEndTransition = false; - - var $types = { - 0 : "keyhole.dbroot.ZoomRangeProto" - }; - $lazyTypes.push($types); + positions[12 * i + j * 3] = corner.x; + positions[12 * i + j * 3 + 1] = corner.y; + positions[12 * i + j * 3 + 2] = corner.z; + } + } + }; - LayerProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.LayerProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (!(message.zoomRange && message.zoomRange.length)) - message.zoomRange = []; - message.zoomRange.push($types[0].decode(reader, reader.uint32())); - break; - case 2: - message.preserveTextLevel = reader.int32(); - break; - case 4: - message.lodBeginTransition = reader.bool(); - break; - case 5: - message.lodEndTransition = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + /** + * Computes the geometric representation of a frustum, including its vertices, indices, and a bounding sphere. + * + * @param {FrustumGeometry} frustumGeometry A description of the frustum. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + FrustumGeometry.createGeometry = function(frustumGeometry) { + var frustumType = frustumGeometry._frustumType; + var frustum = frustumGeometry._frustum; + var origin = frustumGeometry._origin; + var orientation = frustumGeometry._orientation; + var drawNearPlane = frustumGeometry._drawNearPlane; + var vertexFormat = frustumGeometry._vertexFormat; - LayerProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.zoomRange !== undefined) { - if (!Array.isArray(message.zoomRange)) - return "zoomRange: array expected"; - for (var i = 0; i < message.zoomRange.length; ++i) { - var error = $types[0].verify(message.zoomRange[i]); - if (error) - return "zoomRange." + error; - } - } - if (message.preserveTextLevel !== undefined) - if (!$util.isInteger(message.preserveTextLevel)) - return "preserveTextLevel: integer expected"; - if (message.lodBeginTransition !== undefined) - if (typeof message.lodBeginTransition !== "boolean") - return "lodBeginTransition: boolean expected"; - if (message.lodEndTransition !== undefined) - if (typeof message.lodEndTransition !== "boolean") - return "lodEndTransition: boolean expected"; - return null; - }; + var numberOfPlanes = drawNearPlane ? 6 : 5; + var positions = new Float64Array(3 * 4 * 6); + FrustumGeometry._computeNearFarPlanes(origin, orientation, frustumType, frustum, positions); - LayerProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.LayerProto) - return object; - var message = new $root.keyhole.dbroot.LayerProto(); - if (object.zoomRange) { - if (!Array.isArray(object.zoomRange)) - throw TypeError(".keyhole.dbroot.LayerProto.zoomRange: array expected"); - message.zoomRange = []; - for (var i = 0; i < object.zoomRange.length; ++i) { - if (typeof object.zoomRange[i] !== "object") - throw TypeError(".keyhole.dbroot.LayerProto.zoomRange: object expected"); - message.zoomRange[i] = $types[0].fromObject(object.zoomRange[i]); - } - } - if (object.preserveTextLevel !== undefined && object.preserveTextLevel !== null) - message.preserveTextLevel = object.preserveTextLevel | 0; - if (object.lodBeginTransition !== undefined && object.lodBeginTransition !== null) - message.lodBeginTransition = Boolean(object.lodBeginTransition); - if (object.lodEndTransition !== undefined && object.lodEndTransition !== null) - message.lodEndTransition = Boolean(object.lodEndTransition); - return message; - }; + // -x plane + var offset = 3 * 4 * 2; + positions[offset] = positions[3 * 4]; + positions[offset + 1] = positions[3 * 4 + 1]; + positions[offset + 2] = positions[3 * 4 + 2]; + positions[offset + 3] = positions[0]; + positions[offset + 4] = positions[1]; + positions[offset + 5] = positions[2]; + positions[offset + 6] = positions[3 * 3]; + positions[offset + 7] = positions[3 * 3 + 1]; + positions[offset + 8] = positions[3 * 3 + 2]; + positions[offset + 9] = positions[3 * 7]; + positions[offset + 10] = positions[3 * 7 + 1]; + positions[offset + 11] = positions[3 * 7 + 2]; - LayerProto.from = LayerProto.fromObject; + // -y plane + offset += 3 * 4; + positions[offset] = positions[3 * 5]; + positions[offset + 1] = positions[3 * 5 + 1]; + positions[offset + 2] = positions[3 * 5 + 2]; + positions[offset + 3] = positions[3]; + positions[offset + 4] = positions[3 + 1]; + positions[offset + 5] = positions[3 + 2]; + positions[offset + 6] = positions[0]; + positions[offset + 7] = positions[1]; + positions[offset + 8] = positions[2]; + positions[offset + 9] = positions[3 * 4]; + positions[offset + 10] = positions[3 * 4 + 1]; + positions[offset + 11] = positions[3 * 4 + 2]; - LayerProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.zoomRange = []; - if (options.defaults) { - object.preserveTextLevel = 30; - object.lodBeginTransition = false; - object.lodEndTransition = false; - } - if (message.zoomRange !== undefined && message.zoomRange !== null && message.hasOwnProperty("zoomRange")) { - object.zoomRange = []; - for (var j = 0; j < message.zoomRange.length; ++j) - object.zoomRange[j] = $types[0].toObject(message.zoomRange[j], options); - } - if (message.preserveTextLevel !== undefined && message.preserveTextLevel !== null && message.hasOwnProperty("preserveTextLevel")) - object.preserveTextLevel = message.preserveTextLevel; - if (message.lodBeginTransition !== undefined && message.lodBeginTransition !== null && message.hasOwnProperty("lodBeginTransition")) - object.lodBeginTransition = message.lodBeginTransition; - if (message.lodEndTransition !== undefined && message.lodEndTransition !== null && message.hasOwnProperty("lodEndTransition")) - object.lodEndTransition = message.lodEndTransition; - return object; - }; + // +x plane + offset += 3 * 4; + positions[offset] = positions[3]; + positions[offset + 1] = positions[3 + 1]; + positions[offset + 2] = positions[3 + 2]; + positions[offset + 3] = positions[3 * 5]; + positions[offset + 4] = positions[3 * 5 + 1]; + positions[offset + 5] = positions[3 * 5 + 2]; + positions[offset + 6] = positions[3 * 6]; + positions[offset + 7] = positions[3 * 6 + 1]; + positions[offset + 8] = positions[3 * 6 + 2]; + positions[offset + 9] = positions[3 * 2]; + positions[offset + 10] = positions[3 * 2 + 1]; + positions[offset + 11] = positions[3 * 2 + 2]; - LayerProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + // +y plane + offset += 3 * 4; + positions[offset] = positions[3 * 2]; + positions[offset + 1] = positions[3 * 2 + 1]; + positions[offset + 2] = positions[3 * 2 + 2]; + positions[offset + 3] = positions[3 * 6]; + positions[offset + 4] = positions[3 * 6 + 1]; + positions[offset + 5] = positions[3 * 6 + 2]; + positions[offset + 6] = positions[3 * 7]; + positions[offset + 7] = positions[3 * 7 + 1]; + positions[offset + 8] = positions[3 * 7 + 2]; + positions[offset + 9] = positions[3 * 3]; + positions[offset + 10] = positions[3 * 3 + 1]; + positions[offset + 11] = positions[3 * 3 + 2]; - LayerProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + if (!drawNearPlane) { + positions = positions.subarray(3 * 4); + } - return LayerProto; - })(); + var attributes = new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }) + }); - dbroot.FolderProto = (function() { + if (defined(vertexFormat.normal) || defined(vertexFormat.tangent) || defined(vertexFormat.bitangent) || defined(vertexFormat.st)) { + var normals = defined(vertexFormat.normal) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; + var tangents = defined(vertexFormat.tangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; + var bitangents = defined(vertexFormat.bitangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; + var st = defined(vertexFormat.st) ? new Float32Array(2 * 4 * numberOfPlanes) : undefined; - function FolderProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + var x = scratchXDirection; + var y = scratchYDirection; + var z = scratchZDirection; - FolderProto.prototype.isExpandable = true; + var negativeX = Cartesian3.negate(x, scratchNegativeX); + var negativeY = Cartesian3.negate(y, scratchNegativeY); + var negativeZ = Cartesian3.negate(z, scratchNegativeZ); - FolderProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.FolderProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.isExpandable = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + offset = 0; + if (drawNearPlane) { + getAttributes(offset, normals, tangents, bitangents, st, negativeZ, x, y); // near + offset += 3 * 4; + } + getAttributes(offset, normals, tangents, bitangents, st, z, negativeX, y); // far + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, negativeX, negativeZ, y); // -x + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, negativeY, negativeZ, negativeX); // -y + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, x, z, y); // +x + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, y, z, negativeX); // +y - FolderProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.isExpandable !== undefined) - if (typeof message.isExpandable !== "boolean") - return "isExpandable: boolean expected"; - return null; - }; + if (defined(normals)) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); + } + if (defined(tangents)) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } + if (defined(bitangents)) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } + if (defined(st)) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : st + }); + } + } - FolderProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.FolderProto) - return object; - var message = new $root.keyhole.dbroot.FolderProto(); - if (object.isExpandable !== undefined && object.isExpandable !== null) - message.isExpandable = Boolean(object.isExpandable); - return message; - }; + var indices = new Uint16Array(6 * numberOfPlanes); + for (var i = 0; i < numberOfPlanes; ++i) { + var indexOffset = i * 6; + var index = i * 4; - FolderProto.from = FolderProto.fromObject; + indices[indexOffset] = index; + indices[indexOffset + 1] = index + 1; + indices[indexOffset + 2] = index + 2; + indices[indexOffset + 3] = index; + indices[indexOffset + 4] = index + 2; + indices[indexOffset + 5] = index + 3; + } - FolderProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.isExpandable = true; - if (message.isExpandable !== undefined && message.isExpandable !== null && message.hasOwnProperty("isExpandable")) - object.isExpandable = message.isExpandable; - return object; - }; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : BoundingSphere.fromVertices(positions) + }); + }; - FolderProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + return FrustumGeometry; +}); - FolderProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +define('Core/FrustumOutlineGeometry',[ + './BoundingSphere', + './Cartesian3', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './FrustumGeometry', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './OrthographicFrustum', + './PerspectiveFrustum', + './PrimitiveType', + './Quaternion' + ], function( + BoundingSphere, + Cartesian3, + Check, + ComponentDatatype, + defaultValue, + defined, + FrustumGeometry, + Geometry, + GeometryAttribute, + GeometryAttributes, + OrthographicFrustum, + PerspectiveFrustum, + PrimitiveType, + Quaternion) { + 'use strict'; - return FolderProto; - })(); + var PERSPECTIVE = 0; + var ORTHOGRAPHIC = 1; - dbroot.RequirementProto = (function() { + /** + * A description of the outline of a frustum with the given the origin and orientation. + * + * @alias FrustumOutlineGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. + * @param {Cartesian3} options.origin The origin of the frustum. + * @param {Quaternion} options.orientation The orientation of the frustum. + */ + function FrustumOutlineGeometry(options) { + Check.typeOf.object('options', options); + Check.typeOf.object('options.frustum', options.frustum); + Check.typeOf.object('options.origin', options.origin); + Check.typeOf.object('options.orientation', options.orientation); + + var frustum = options.frustum; + var orientation = options.orientation; + var origin = options.origin; - function RequirementProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by + // creating multiple FrustumOutlineGeometrys. This way the near plane of one frustum doesn't overlap + // the far plane of another. + var drawNearPlane = defaultValue(options._drawNearPlane, true); - RequirementProto.prototype.requiredVram = ""; - RequirementProto.prototype.requiredClientVer = ""; - RequirementProto.prototype.probability = ""; - RequirementProto.prototype.requiredUserAgent = ""; - RequirementProto.prototype.requiredClientCapabilities = ""; + var frustumType; + var frustumPackedLength; + if (frustum instanceof PerspectiveFrustum) { + frustumType = PERSPECTIVE; + frustumPackedLength = PerspectiveFrustum.packedLength; + } else if (frustum instanceof OrthographicFrustum) { + frustumType = ORTHOGRAPHIC; + frustumPackedLength = OrthographicFrustum.packedLength; + } - RequirementProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.RequirementProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 3: - message.requiredVram = reader.string(); - break; - case 4: - message.requiredClientVer = reader.string(); - break; - case 5: - message.probability = reader.string(); - break; - case 6: - message.requiredUserAgent = reader.string(); - break; - case 7: - message.requiredClientCapabilities = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + this._frustumType = frustumType; + this._frustum = frustum.clone(); + this._origin = Cartesian3.clone(origin); + this._orientation = Quaternion.clone(orientation); + this._drawNearPlane = drawNearPlane; + this._workerName = 'createFrustumOutlineGeometry'; - RequirementProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.requiredVram !== undefined) - if (!$util.isString(message.requiredVram)) - return "requiredVram: string expected"; - if (message.requiredClientVer !== undefined) - if (!$util.isString(message.requiredClientVer)) - return "requiredClientVer: string expected"; - if (message.probability !== undefined) - if (!$util.isString(message.probability)) - return "probability: string expected"; - if (message.requiredUserAgent !== undefined) - if (!$util.isString(message.requiredUserAgent)) - return "requiredUserAgent: string expected"; - if (message.requiredClientCapabilities !== undefined) - if (!$util.isString(message.requiredClientCapabilities)) - return "requiredClientCapabilities: string expected"; - return null; - }; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength; + } - RequirementProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.RequirementProto) - return object; - var message = new $root.keyhole.dbroot.RequirementProto(); - if (object.requiredVram !== undefined && object.requiredVram !== null) - message.requiredVram = String(object.requiredVram); - if (object.requiredClientVer !== undefined && object.requiredClientVer !== null) - message.requiredClientVer = String(object.requiredClientVer); - if (object.probability !== undefined && object.probability !== null) - message.probability = String(object.probability); - if (object.requiredUserAgent !== undefined && object.requiredUserAgent !== null) - message.requiredUserAgent = String(object.requiredUserAgent); - if (object.requiredClientCapabilities !== undefined && object.requiredClientCapabilities !== null) - message.requiredClientCapabilities = String(object.requiredClientCapabilities); - return message; - }; + /** + * Stores the provided instance into the provided array. + * + * @param {FrustumOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + FrustumOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - RequirementProto.from = RequirementProto.fromObject; + var frustumType = value._frustumType; + var frustum = value._frustum; - RequirementProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.requiredVram = ""; - object.requiredClientVer = ""; - object.probability = ""; - object.requiredUserAgent = ""; - object.requiredClientCapabilities = ""; - } - if (message.requiredVram !== undefined && message.requiredVram !== null && message.hasOwnProperty("requiredVram")) - object.requiredVram = message.requiredVram; - if (message.requiredClientVer !== undefined && message.requiredClientVer !== null && message.hasOwnProperty("requiredClientVer")) - object.requiredClientVer = message.requiredClientVer; - if (message.probability !== undefined && message.probability !== null && message.hasOwnProperty("probability")) - object.probability = message.probability; - if (message.requiredUserAgent !== undefined && message.requiredUserAgent !== null && message.hasOwnProperty("requiredUserAgent")) - object.requiredUserAgent = message.requiredUserAgent; - if (message.requiredClientCapabilities !== undefined && message.requiredClientCapabilities !== null && message.hasOwnProperty("requiredClientCapabilities")) - object.requiredClientCapabilities = message.requiredClientCapabilities; - return object; - }; + array[startingIndex++] = frustumType; - RequirementProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + if (frustumType === PERSPECTIVE) { + PerspectiveFrustum.pack(frustum, array, startingIndex); + startingIndex += PerspectiveFrustum.packedLength; + } else { + OrthographicFrustum.pack(frustum, array, startingIndex); + startingIndex += OrthographicFrustum.packedLength; + } - RequirementProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + Cartesian3.pack(value._origin, array, startingIndex); + startingIndex += Cartesian3.packedLength; + Quaternion.pack(value._orientation, array, startingIndex); + startingIndex += Quaternion.packedLength; + array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0; - return RequirementProto; - })(); + return array; + }; - dbroot.LookAtProto = (function() { + var scratchPackPerspective = new PerspectiveFrustum(); + var scratchPackOrthographic = new OrthographicFrustum(); + var scratchPackQuaternion = new Quaternion(); + var scratchPackorigin = new Cartesian3(); - function LookAtProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {FrustumOutlineGeometry} [result] The object into which to store the result. + */ + FrustumOutlineGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - LookAtProto.prototype.longitude = 0; - LookAtProto.prototype.latitude = 0; - LookAtProto.prototype.range = 0; - LookAtProto.prototype.tilt = 0; - LookAtProto.prototype.heading = 0; + var frustumType = array[startingIndex++]; - LookAtProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.LookAtProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.longitude = reader.float(); - break; - case 2: - message.latitude = reader.float(); - break; - case 3: - message.range = reader.float(); - break; - case 4: - message.tilt = reader.float(); - break; - case 5: - message.heading = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + var frustum; + if (frustumType === PERSPECTIVE) { + frustum = PerspectiveFrustum.unpack(array, startingIndex, scratchPackPerspective); + startingIndex += PerspectiveFrustum.packedLength; + } else { + frustum = OrthographicFrustum.unpack(array, startingIndex, scratchPackOrthographic); + startingIndex += OrthographicFrustum.packedLength; + } - LookAtProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (typeof message.longitude !== "number") - return "longitude: number expected"; - if (typeof message.latitude !== "number") - return "latitude: number expected"; - if (message.range !== undefined) - if (typeof message.range !== "number") - return "range: number expected"; - if (message.tilt !== undefined) - if (typeof message.tilt !== "number") - return "tilt: number expected"; - if (message.heading !== undefined) - if (typeof message.heading !== "number") - return "heading: number expected"; - return null; - }; + var origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin); + startingIndex += Cartesian3.packedLength; + var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); + startingIndex += Quaternion.packedLength; + var drawNearPlane = array[startingIndex] === 1.0; - LookAtProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.LookAtProto) - return object; - var message = new $root.keyhole.dbroot.LookAtProto(); - if (object.longitude !== undefined && object.longitude !== null) - message.longitude = Number(object.longitude); - if (object.latitude !== undefined && object.latitude !== null) - message.latitude = Number(object.latitude); - if (object.range !== undefined && object.range !== null) - message.range = Number(object.range); - if (object.tilt !== undefined && object.tilt !== null) - message.tilt = Number(object.tilt); - if (object.heading !== undefined && object.heading !== null) - message.heading = Number(object.heading); - return message; - }; + if (!defined(result)) { + return new FrustumOutlineGeometry({ + frustum : frustum, + origin : origin, + orientation : orientation, + _drawNearPlane : drawNearPlane + }); + } - LookAtProto.from = LookAtProto.fromObject; + var frustumResult = frustumType === result._frustumType ? result._frustum : undefined; + result._frustum = frustum.clone(frustumResult); - LookAtProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.longitude = 0; - object.latitude = 0; - object.range = 0; - object.tilt = 0; - object.heading = 0; - } - if (message.longitude !== undefined && message.longitude !== null && message.hasOwnProperty("longitude")) - object.longitude = message.longitude; - if (message.latitude !== undefined && message.latitude !== null && message.hasOwnProperty("latitude")) - object.latitude = message.latitude; - if (message.range !== undefined && message.range !== null && message.hasOwnProperty("range")) - object.range = message.range; - if (message.tilt !== undefined && message.tilt !== null && message.hasOwnProperty("tilt")) - object.tilt = message.tilt; - if (message.heading !== undefined && message.heading !== null && message.hasOwnProperty("heading")) - object.heading = message.heading; - return object; - }; + result._frustumType = frustumType; + result._origin = Cartesian3.clone(origin, result._origin); + result._orientation = Quaternion.clone(orientation, result._orientation); + result._drawNearPlane = drawNearPlane; - LookAtProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + return result; + }; - LookAtProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + /** + * Computes the geometric representation of a frustum outline, including its vertices, indices, and a bounding sphere. + * + * @param {FrustumOutlineGeometry} frustumGeometry A description of the frustum. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + FrustumOutlineGeometry.createGeometry = function(frustumGeometry) { + var frustumType = frustumGeometry._frustumType; + var frustum = frustumGeometry._frustum; + var origin = frustumGeometry._origin; + var orientation = frustumGeometry._orientation; + var drawNearPlane = frustumGeometry._drawNearPlane; - return LookAtProto; - })(); + var positions = new Float64Array(3 * 4 * 2); + FrustumGeometry._computeNearFarPlanes(origin, orientation, frustumType, frustum, positions); - dbroot.NestedFeatureProto = (function() { + var attributes = new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }) + }); - function NestedFeatureProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + var offset; + var index; - NestedFeatureProto.prototype.featureType = 1; - NestedFeatureProto.prototype.kmlUrl = null; - NestedFeatureProto.prototype.databaseUrl = ""; - NestedFeatureProto.prototype.layer = null; - NestedFeatureProto.prototype.folder = null; - NestedFeatureProto.prototype.requirement = null; - NestedFeatureProto.prototype.channelId = 0; - NestedFeatureProto.prototype.displayName = null; - NestedFeatureProto.prototype.isVisible = true; - NestedFeatureProto.prototype.isEnabled = true; - NestedFeatureProto.prototype.isChecked = false; - NestedFeatureProto.prototype.layerMenuIconPath = "icons/773_l.png"; - NestedFeatureProto.prototype.description = null; - NestedFeatureProto.prototype.lookAt = null; - NestedFeatureProto.prototype.assetUuid = ""; - NestedFeatureProto.prototype.isSaveLocked = true; - NestedFeatureProto.prototype.children = $util.emptyArray; - NestedFeatureProto.prototype.clientConfigScriptName = ""; - NestedFeatureProto.prototype.dioramaDataChannelBase = -1; - NestedFeatureProto.prototype.replicaDataChannelBase = -1; + var numberOfPlanes = drawNearPlane ? 2 : 1; + var indices = new Uint16Array(8 * (numberOfPlanes + 1)); - var $types = { - 0 : "keyhole.dbroot.NestedFeatureProto.FeatureType", - 1 : "keyhole.dbroot.StringIdOrValueProto", - 3 : "keyhole.dbroot.LayerProto", - 4 : "keyhole.dbroot.FolderProto", - 5 : "keyhole.dbroot.RequirementProto", - 7 : "keyhole.dbroot.StringIdOrValueProto", - 12 : "keyhole.dbroot.StringIdOrValueProto", - 13 : "keyhole.dbroot.LookAtProto", - 16 : "keyhole.dbroot.NestedFeatureProto" - }; - $lazyTypes.push($types); + // Build the near/far planes + var i = drawNearPlane ? 0 : 1; + for (; i < 2; ++i) { + offset = drawNearPlane ? i * 8 : 0; + index = i * 4; - NestedFeatureProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.NestedFeatureProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.featureType = reader.uint32(); - break; - case 2: - message.kmlUrl = $types[1].decode(reader, reader.uint32()); - break; - case 21: - message.databaseUrl = reader.string(); - break; - case 3: - message.layer = $types[3].decode(reader, reader.uint32()); - break; - case 4: - message.folder = $types[4].decode(reader, reader.uint32()); - break; - case 5: - message.requirement = $types[5].decode(reader, reader.uint32()); - break; - case 6: - message.channelId = reader.int32(); - break; - case 7: - message.displayName = $types[7].decode(reader, reader.uint32()); - break; - case 8: - message.isVisible = reader.bool(); - break; - case 9: - message.isEnabled = reader.bool(); - break; - case 10: - message.isChecked = reader.bool(); - break; - case 11: - message.layerMenuIconPath = reader.string(); - break; - case 12: - message.description = $types[12].decode(reader, reader.uint32()); - break; - case 13: - message.lookAt = $types[13].decode(reader, reader.uint32()); - break; - case 15: - message.assetUuid = reader.string(); - break; - case 16: - message.isSaveLocked = reader.bool(); - break; - case 17: - if (!(message.children && message.children.length)) - message.children = []; - message.children.push($types[16].decode(reader, reader.uint32())); - break; - case 18: - message.clientConfigScriptName = reader.string(); - break; - case 19: - message.dioramaDataChannelBase = reader.int32(); - break; - case 20: - message.replicaDataChannelBase = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + indices[offset] = index; + indices[offset + 1] = index + 1; + indices[offset + 2] = index + 1; + indices[offset + 3] = index + 2; + indices[offset + 4] = index + 2; + indices[offset + 5] = index + 3; + indices[offset + 6] = index + 3; + indices[offset + 7] = index; + } - NestedFeatureProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.featureType !== undefined) - switch (message.featureType) { - default: - return "featureType: enum value expected"; - case 1: - case 2: - case 3: - case 4: - break; - } - if (message.kmlUrl !== undefined && message.kmlUrl !== null) { - var error = $types[1].verify(message.kmlUrl); - if (error) - return "kmlUrl." + error; - } - if (message.databaseUrl !== undefined) - if (!$util.isString(message.databaseUrl)) - return "databaseUrl: string expected"; - if (message.layer !== undefined && message.layer !== null) { - var error = $types[3].verify(message.layer); - if (error) - return "layer." + error; - } - if (message.folder !== undefined && message.folder !== null) { - var error = $types[4].verify(message.folder); - if (error) - return "folder." + error; - } - if (message.requirement !== undefined && message.requirement !== null) { - var error = $types[5].verify(message.requirement); - if (error) - return "requirement." + error; - } - if (!$util.isInteger(message.channelId)) - return "channelId: integer expected"; - if (message.displayName !== undefined && message.displayName !== null) { - var error = $types[7].verify(message.displayName); - if (error) - return "displayName." + error; - } - if (message.isVisible !== undefined) - if (typeof message.isVisible !== "boolean") - return "isVisible: boolean expected"; - if (message.isEnabled !== undefined) - if (typeof message.isEnabled !== "boolean") - return "isEnabled: boolean expected"; - if (message.isChecked !== undefined) - if (typeof message.isChecked !== "boolean") - return "isChecked: boolean expected"; - if (message.layerMenuIconPath !== undefined) - if (!$util.isString(message.layerMenuIconPath)) - return "layerMenuIconPath: string expected"; - if (message.description !== undefined && message.description !== null) { - var error = $types[12].verify(message.description); - if (error) - return "description." + error; - } - if (message.lookAt !== undefined && message.lookAt !== null) { - var error = $types[13].verify(message.lookAt); - if (error) - return "lookAt." + error; - } - if (message.assetUuid !== undefined) - if (!$util.isString(message.assetUuid)) - return "assetUuid: string expected"; - if (message.isSaveLocked !== undefined) - if (typeof message.isSaveLocked !== "boolean") - return "isSaveLocked: boolean expected"; - if (message.children !== undefined) { - if (!Array.isArray(message.children)) - return "children: array expected"; - for (var i = 0; i < message.children.length; ++i) { - var error = $types[16].verify(message.children[i]); - if (error) - return "children." + error; - } - } - if (message.clientConfigScriptName !== undefined) - if (!$util.isString(message.clientConfigScriptName)) - return "clientConfigScriptName: string expected"; - if (message.dioramaDataChannelBase !== undefined) - if (!$util.isInteger(message.dioramaDataChannelBase)) - return "dioramaDataChannelBase: integer expected"; - if (message.replicaDataChannelBase !== undefined) - if (!$util.isInteger(message.replicaDataChannelBase)) - return "replicaDataChannelBase: integer expected"; - return null; - }; + // Build the sides of the frustums + for (i = 0; i < 2; ++i) { + offset = (numberOfPlanes + i) * 8; + index = i * 4; - NestedFeatureProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.NestedFeatureProto) - return object; - var message = new $root.keyhole.dbroot.NestedFeatureProto(); - switch (object.featureType) { - case "TYPE_POINT_Z": - case 1: - message.featureType = 1; - break; - case "TYPE_POLYGON_Z": - case 2: - message.featureType = 2; - break; - case "TYPE_LINE_Z": - case 3: - message.featureType = 3; - break; - case "TYPE_TERRAIN": - case 4: - message.featureType = 4; - break; - } - if (object.kmlUrl !== undefined && object.kmlUrl !== null) { - if (typeof object.kmlUrl !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.kmlUrl: object expected"); - message.kmlUrl = $types[1].fromObject(object.kmlUrl); - } - if (object.databaseUrl !== undefined && object.databaseUrl !== null) - message.databaseUrl = String(object.databaseUrl); - if (object.layer !== undefined && object.layer !== null) { - if (typeof object.layer !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.layer: object expected"); - message.layer = $types[3].fromObject(object.layer); - } - if (object.folder !== undefined && object.folder !== null) { - if (typeof object.folder !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.folder: object expected"); - message.folder = $types[4].fromObject(object.folder); - } - if (object.requirement !== undefined && object.requirement !== null) { - if (typeof object.requirement !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.requirement: object expected"); - message.requirement = $types[5].fromObject(object.requirement); - } - if (object.channelId !== undefined && object.channelId !== null) - message.channelId = object.channelId | 0; - if (object.displayName !== undefined && object.displayName !== null) { - if (typeof object.displayName !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.displayName: object expected"); - message.displayName = $types[7].fromObject(object.displayName); - } - if (object.isVisible !== undefined && object.isVisible !== null) - message.isVisible = Boolean(object.isVisible); - if (object.isEnabled !== undefined && object.isEnabled !== null) - message.isEnabled = Boolean(object.isEnabled); - if (object.isChecked !== undefined && object.isChecked !== null) - message.isChecked = Boolean(object.isChecked); - if (object.layerMenuIconPath !== undefined && object.layerMenuIconPath !== null) - message.layerMenuIconPath = String(object.layerMenuIconPath); - if (object.description !== undefined && object.description !== null) { - if (typeof object.description !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.description: object expected"); - message.description = $types[12].fromObject(object.description); - } - if (object.lookAt !== undefined && object.lookAt !== null) { - if (typeof object.lookAt !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.lookAt: object expected"); - message.lookAt = $types[13].fromObject(object.lookAt); - } - if (object.assetUuid !== undefined && object.assetUuid !== null) - message.assetUuid = String(object.assetUuid); - if (object.isSaveLocked !== undefined && object.isSaveLocked !== null) - message.isSaveLocked = Boolean(object.isSaveLocked); - if (object.children) { - if (!Array.isArray(object.children)) - throw TypeError(".keyhole.dbroot.NestedFeatureProto.children: array expected"); - message.children = []; - for (var i = 0; i < object.children.length; ++i) { - if (typeof object.children[i] !== "object") - throw TypeError(".keyhole.dbroot.NestedFeatureProto.children: object expected"); - message.children[i] = $types[16].fromObject(object.children[i]); - } - } - if (object.clientConfigScriptName !== undefined && object.clientConfigScriptName !== null) - message.clientConfigScriptName = String(object.clientConfigScriptName); - if (object.dioramaDataChannelBase !== undefined && object.dioramaDataChannelBase !== null) - message.dioramaDataChannelBase = object.dioramaDataChannelBase | 0; - if (object.replicaDataChannelBase !== undefined && object.replicaDataChannelBase !== null) - message.replicaDataChannelBase = object.replicaDataChannelBase | 0; - return message; - }; + indices[offset] = index; + indices[offset + 1] = index + 4; + indices[offset + 2] = index + 1; + indices[offset + 3] = index + 5; + indices[offset + 4] = index + 2; + indices[offset + 5] = index + 6; + indices[offset + 6] = index + 3; + indices[offset + 7] = index + 7; + } - NestedFeatureProto.from = NestedFeatureProto.fromObject; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : BoundingSphere.fromVertices(positions) + }); + }; - NestedFeatureProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.children = []; - if (options.defaults) { - object.featureType = options.enums === String ? "TYPE_POINT_Z" : 1; - object.kmlUrl = null; - object.databaseUrl = ""; - object.layer = null; - object.folder = null; - object.requirement = null; - object.channelId = 0; - object.displayName = null; - object.isVisible = true; - object.isEnabled = true; - object.isChecked = false; - object.layerMenuIconPath = "icons/773_l.png"; - object.description = null; - object.lookAt = null; - object.assetUuid = ""; - object.isSaveLocked = true; - object.clientConfigScriptName = ""; - object.dioramaDataChannelBase = -1; - object.replicaDataChannelBase = -1; - } - if (message.featureType !== undefined && message.featureType !== null && message.hasOwnProperty("featureType")) - object.featureType = options.enums === String ? $types[0][message.featureType] : message.featureType; - if (message.kmlUrl !== undefined && message.kmlUrl !== null && message.hasOwnProperty("kmlUrl")) - object.kmlUrl = $types[1].toObject(message.kmlUrl, options); - if (message.databaseUrl !== undefined && message.databaseUrl !== null && message.hasOwnProperty("databaseUrl")) - object.databaseUrl = message.databaseUrl; - if (message.layer !== undefined && message.layer !== null && message.hasOwnProperty("layer")) - object.layer = $types[3].toObject(message.layer, options); - if (message.folder !== undefined && message.folder !== null && message.hasOwnProperty("folder")) - object.folder = $types[4].toObject(message.folder, options); - if (message.requirement !== undefined && message.requirement !== null && message.hasOwnProperty("requirement")) - object.requirement = $types[5].toObject(message.requirement, options); - if (message.channelId !== undefined && message.channelId !== null && message.hasOwnProperty("channelId")) - object.channelId = message.channelId; - if (message.displayName !== undefined && message.displayName !== null && message.hasOwnProperty("displayName")) - object.displayName = $types[7].toObject(message.displayName, options); - if (message.isVisible !== undefined && message.isVisible !== null && message.hasOwnProperty("isVisible")) - object.isVisible = message.isVisible; - if (message.isEnabled !== undefined && message.isEnabled !== null && message.hasOwnProperty("isEnabled")) - object.isEnabled = message.isEnabled; - if (message.isChecked !== undefined && message.isChecked !== null && message.hasOwnProperty("isChecked")) - object.isChecked = message.isChecked; - if (message.layerMenuIconPath !== undefined && message.layerMenuIconPath !== null && message.hasOwnProperty("layerMenuIconPath")) - object.layerMenuIconPath = message.layerMenuIconPath; - if (message.description !== undefined && message.description !== null && message.hasOwnProperty("description")) - object.description = $types[12].toObject(message.description, options); - if (message.lookAt !== undefined && message.lookAt !== null && message.hasOwnProperty("lookAt")) - object.lookAt = $types[13].toObject(message.lookAt, options); - if (message.assetUuid !== undefined && message.assetUuid !== null && message.hasOwnProperty("assetUuid")) - object.assetUuid = message.assetUuid; - if (message.isSaveLocked !== undefined && message.isSaveLocked !== null && message.hasOwnProperty("isSaveLocked")) - object.isSaveLocked = message.isSaveLocked; - if (message.children !== undefined && message.children !== null && message.hasOwnProperty("children")) { - object.children = []; - for (var j = 0; j < message.children.length; ++j) - object.children[j] = $types[16].toObject(message.children[j], options); - } - if (message.clientConfigScriptName !== undefined && message.clientConfigScriptName !== null && message.hasOwnProperty("clientConfigScriptName")) - object.clientConfigScriptName = message.clientConfigScriptName; - if (message.dioramaDataChannelBase !== undefined && message.dioramaDataChannelBase !== null && message.hasOwnProperty("dioramaDataChannelBase")) - object.dioramaDataChannelBase = message.dioramaDataChannelBase; - if (message.replicaDataChannelBase !== undefined && message.replicaDataChannelBase !== null && message.hasOwnProperty("replicaDataChannelBase")) - object.replicaDataChannelBase = message.replicaDataChannelBase; - return object; - }; + return FrustumOutlineGeometry; +}); - NestedFeatureProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +define('Core/GeocoderService',[ + './DeveloperError' + ], function( + DeveloperError) { + 'use strict'; - NestedFeatureProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + /** + * @typedef {Object} GeocoderResult + * @property {String} displayName The display name for a location + * @property {Rectangle|Cartesian3} destination The bounding box for a location + */ - NestedFeatureProto.FeatureType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values["TYPE_POINT_Z"] = 1; - values["TYPE_POLYGON_Z"] = 2; - values["TYPE_LINE_Z"] = 3; - values["TYPE_TERRAIN"] = 4; - return values; - })(); + /** + * Provides geocoding through an external service. This type describes an interface and + * is not intended to be used. + * @alias GeocoderService + * @constructor + * + * @see BingMapsGeocoderService + */ + function GeocoderService() { + } - return NestedFeatureProto; - })(); + /** + * @function + * + * @param {String} query The query to be sent to the geocoder service + * @returns {Promise<GeocoderResult[]>} + */ + GeocoderService.prototype.geocode = DeveloperError.throwInstantiationError; - dbroot.MfeDomainFeaturesProto = (function() { + return GeocoderService; +}); - function MfeDomainFeaturesProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +define('Core/GeometryInstanceAttribute',[ + './defaultValue', + './defined', + './DeveloperError' + ], function( + defaultValue, + defined, + DeveloperError) { + 'use strict'; - MfeDomainFeaturesProto.prototype.countryCode = ""; - MfeDomainFeaturesProto.prototype.domainName = ""; - MfeDomainFeaturesProto.prototype.supportedFeatures = $util.emptyArray; + /** + * Values and type information for per-instance geometry attributes. + * + * @alias GeometryInstanceAttribute + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {ComponentDatatype} [options.componentDatatype] The datatype of each component in the attribute, e.g., individual elements in values. + * @param {Number} [options.componentsPerAttribute] A number between 1 and 4 that defines the number of components in an attributes. + * @param {Boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * @param {Number[]} [options.value] The value for the attribute. + * + * @exception {DeveloperError} options.componentsPerAttribute must be between 1 and 4. + * + * + * @example + * var instance = new Cesium.GeometryInstance({ + * geometry : Cesium.BoxGeometry.fromDimensions({ + * dimensions : new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0) + * }), + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(0.0, 0.0)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), + * id : 'box', + * attributes : { + * color : new Cesium.GeometryInstanceAttribute({ + * componentDatatype : Cesium.ComponentDatatype.UNSIGNED_BYTE, + * componentsPerAttribute : 4, + * normalize : true, + * value : [255, 255, 0, 255] + * }) + * } + * }); + * + * @see ColorGeometryInstanceAttribute + * @see ShowGeometryInstanceAttribute + * @see DistanceDisplayConditionGeometryInstanceAttribute + */ + function GeometryInstanceAttribute(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var $types = { - 2 : "keyhole.dbroot.MfeDomainFeaturesProto.SupportedFeature" - }; - $lazyTypes.push($types); + if (!defined(options.componentDatatype)) { + throw new DeveloperError('options.componentDatatype is required.'); + } + if (!defined(options.componentsPerAttribute)) { + throw new DeveloperError('options.componentsPerAttribute is required.'); + } + if (options.componentsPerAttribute < 1 || options.componentsPerAttribute > 4) { + throw new DeveloperError('options.componentsPerAttribute must be between 1 and 4.'); + } + if (!defined(options.value)) { + throw new DeveloperError('options.value is required.'); + } + + /** + * The datatype of each component in the attribute, e.g., individual elements in + * {@link GeometryInstanceAttribute#value}. + * + * @type ComponentDatatype + * + * @default undefined + */ + this.componentDatatype = options.componentDatatype; - MfeDomainFeaturesProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.MfeDomainFeaturesProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.countryCode = reader.string(); - break; - case 2: - message.domainName = reader.string(); - break; - case 3: - if (!(message.supportedFeatures && message.supportedFeatures.length)) - message.supportedFeatures = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) - message.supportedFeatures.push(reader.uint32()); - } else - message.supportedFeatures.push(reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + /** + * A number between 1 and 4 that defines the number of components in an attributes. + * For example, a position attribute with x, y, and z components would have 3 as + * shown in the code example. + * + * @type Number + * + * @default undefined + * + * @example + * show : new Cesium.GeometryInstanceAttribute({ + * componentDatatype : Cesium.ComponentDatatype.UNSIGNED_BYTE, + * componentsPerAttribute : 1, + * normalize : true, + * value : [1.0] + * }) + */ + this.componentsPerAttribute = options.componentsPerAttribute; - MfeDomainFeaturesProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isString(message.countryCode)) - return "countryCode: string expected"; - if (!$util.isString(message.domainName)) - return "domainName: string expected"; - if (message.supportedFeatures !== undefined) { - if (!Array.isArray(message.supportedFeatures)) - return "supportedFeatures: array expected"; - for (var i = 0; i < message.supportedFeatures.length; ++i) - switch (message.supportedFeatures[i]) { - default: - return "supportedFeatures: enum value[] expected"; - case 0: - case 1: - case 2: - break; - } - } - return null; - }; + /** + * When <code>true</code> and <code>componentDatatype</code> is an integer format, + * indicate that the components should be mapped to the range [0, 1] (unsigned) + * or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * <p> + * This is commonly used when storing colors using {@link ComponentDatatype.UNSIGNED_BYTE}. + * </p> + * + * @type Boolean + * + * @default false + * + * @example + * attribute.componentDatatype = Cesium.ComponentDatatype.UNSIGNED_BYTE; + * attribute.componentsPerAttribute = 4; + * attribute.normalize = true; + * attribute.value = [ + * Cesium.Color.floatToByte(color.red), + * Cesium.Color.floatToByte(color.green), + * Cesium.Color.floatToByte(color.blue), + * Cesium.Color.floatToByte(color.alpha) + * ]; + */ + this.normalize = defaultValue(options.normalize, false); - MfeDomainFeaturesProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.MfeDomainFeaturesProto) - return object; - var message = new $root.keyhole.dbroot.MfeDomainFeaturesProto(); - if (object.countryCode !== undefined && object.countryCode !== null) - message.countryCode = String(object.countryCode); - if (object.domainName !== undefined && object.domainName !== null) - message.domainName = String(object.domainName); - if (object.supportedFeatures) { - if (!Array.isArray(object.supportedFeatures)) - throw TypeError(".keyhole.dbroot.MfeDomainFeaturesProto.supportedFeatures: array expected"); - message.supportedFeatures = []; - for (var i = 0; i < object.supportedFeatures.length; ++i) - switch (object.supportedFeatures[i]) { - default: - case "GEOCODING": - case 0: - message.supportedFeatures[i] = 0; - break; - case "LOCAL_SEARCH": - case 1: - message.supportedFeatures[i] = 1; - break; - case "DRIVING_DIRECTIONS": - case 2: - message.supportedFeatures[i] = 2; - break; - } - } - return message; - }; + /** + * The values for the attributes stored in a typed array. In the code example, + * every three elements in <code>values</code> defines one attributes since + * <code>componentsPerAttribute</code> is 3. + * + * @type {Number[]} + * + * @default undefined + * + * @example + * show : new Cesium.GeometryInstanceAttribute({ + * componentDatatype : Cesium.ComponentDatatype.UNSIGNED_BYTE, + * componentsPerAttribute : 1, + * normalize : true, + * value : [1.0] + * }) + */ + this.value = options.value; + } - MfeDomainFeaturesProto.from = MfeDomainFeaturesProto.fromObject; + return GeometryInstanceAttribute; +}); - MfeDomainFeaturesProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.supportedFeatures = []; - if (options.defaults) { - object.countryCode = ""; - object.domainName = ""; - } - if (message.countryCode !== undefined && message.countryCode !== null && message.hasOwnProperty("countryCode")) - object.countryCode = message.countryCode; - if (message.domainName !== undefined && message.domainName !== null && message.hasOwnProperty("domainName")) - object.domainName = message.domainName; - if (message.supportedFeatures !== undefined && message.supportedFeatures !== null && message.hasOwnProperty("supportedFeatures")) { - object.supportedFeatures = []; - for (var j = 0; j < message.supportedFeatures.length; ++j) - object.supportedFeatures[j] = options.enums === String ? $types[2][message.supportedFeatures[j]] : message.supportedFeatures[j]; - } - return object; - }; - - MfeDomainFeaturesProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - MfeDomainFeaturesProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - MfeDomainFeaturesProto.SupportedFeature = (function() { - var valuesById = {}, values = Object.create(valuesById); - values["GEOCODING"] = 0; - values["LOCAL_SEARCH"] = 1; - values["DRIVING_DIRECTIONS"] = 2; - return values; - })(); +define('Core/getFilenameFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; - return MfeDomainFeaturesProto; - })(); + /** + * Given a URI, returns the last segment of the URI, removing any path or query information. + * @exports getFilenameFromUri + * + * @param {String} uri The Uri. + * @returns {String} The last segment of the Uri. + * + * @example + * //fileName will be"simple.czml"; + * var fileName = Cesium.getFilenameFromUri('/Gallery/simple.czml?value=true&example=false'); + */ + function getFilenameFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + return path; + } - dbroot.ClientOptionsProto = (function() { + return getFilenameFromUri; +}); - function ClientOptionsProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +define('Core/getImagePixels',[ + './defined' + ], function( + defined) { + 'use strict'; - ClientOptionsProto.prototype.disableDiskCache = false; - ClientOptionsProto.prototype.disableEmbeddedBrowserVista = false; - ClientOptionsProto.prototype.drawAtmosphere = true; - ClientOptionsProto.prototype.drawStars = true; - ClientOptionsProto.prototype.shaderFilePrefix = ""; - ClientOptionsProto.prototype.useProtobufQuadtreePackets = false; - ClientOptionsProto.prototype.useExtendedCopyrightIds = true; - ClientOptionsProto.prototype.precipitationsOptions = null; - ClientOptionsProto.prototype.captureOptions = null; - ClientOptionsProto.prototype.show_2dMapsIcon = true; - ClientOptionsProto.prototype.disableInternalBrowser = false; - ClientOptionsProto.prototype.internalBrowserBlacklist = ""; - ClientOptionsProto.prototype.internalBrowserOriginWhitelist = "*"; - ClientOptionsProto.prototype.polarTileMergingLevel = 0; - ClientOptionsProto.prototype.jsBridgeRequestWhitelist = "http://*.google.com/*"; - ClientOptionsProto.prototype.mapsOptions = null; + var context2DsByWidthAndHeight = {}; - var $types = { - 7 : "keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions", - 8 : "keyhole.dbroot.ClientOptionsProto.CaptureOptions", - 15 : "keyhole.dbroot.ClientOptionsProto.MapsOptions" - }; - $lazyTypes.push($types); + /** + * Extract a pixel array from a loaded image. Draws the image + * into a canvas so it can read the pixels back. + * + * @exports getImagePixels + * + * @param {Image} image The image to extract pixels from. + * @param {Number} width The width of the image. If not defined, then image.width is assigned. + * @param {Number} height The height of the image. If not defined, then image.height is assigned. + * @returns {CanvasPixelArray} The pixels of the image. + */ + function getImagePixels(image, width, height) { + if (!defined(width)) { + width = image.width; + } + if (!defined(height)) { + height = image.height; + } - ClientOptionsProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ClientOptionsProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.disableDiskCache = reader.bool(); - break; - case 2: - message.disableEmbeddedBrowserVista = reader.bool(); - break; - case 3: - message.drawAtmosphere = reader.bool(); - break; - case 4: - message.drawStars = reader.bool(); - break; - case 5: - message.shaderFilePrefix = reader.string(); - break; - case 6: - message.useProtobufQuadtreePackets = reader.bool(); - break; - case 7: - message.useExtendedCopyrightIds = reader.bool(); - break; - case 8: - message.precipitationsOptions = $types[7].decode(reader, reader.uint32()); - break; - case 9: - message.captureOptions = $types[8].decode(reader, reader.uint32()); - break; - case 10: - message.show_2dMapsIcon = reader.bool(); - break; - case 11: - message.disableInternalBrowser = reader.bool(); - break; - case 12: - message.internalBrowserBlacklist = reader.string(); - break; - case 13: - message.internalBrowserOriginWhitelist = reader.string(); - break; - case 14: - message.polarTileMergingLevel = reader.int32(); - break; - case 15: - message.jsBridgeRequestWhitelist = reader.string(); - break; - case 16: - message.mapsOptions = $types[15].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + var context2DsByHeight = context2DsByWidthAndHeight[width]; + if (!defined(context2DsByHeight)) { + context2DsByHeight = {}; + context2DsByWidthAndHeight[width] = context2DsByHeight; + } - ClientOptionsProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.disableDiskCache !== undefined) - if (typeof message.disableDiskCache !== "boolean") - return "disableDiskCache: boolean expected"; - if (message.disableEmbeddedBrowserVista !== undefined) - if (typeof message.disableEmbeddedBrowserVista !== "boolean") - return "disableEmbeddedBrowserVista: boolean expected"; - if (message.drawAtmosphere !== undefined) - if (typeof message.drawAtmosphere !== "boolean") - return "drawAtmosphere: boolean expected"; - if (message.drawStars !== undefined) - if (typeof message.drawStars !== "boolean") - return "drawStars: boolean expected"; - if (message.shaderFilePrefix !== undefined) - if (!$util.isString(message.shaderFilePrefix)) - return "shaderFilePrefix: string expected"; - if (message.useProtobufQuadtreePackets !== undefined) - if (typeof message.useProtobufQuadtreePackets !== "boolean") - return "useProtobufQuadtreePackets: boolean expected"; - if (message.useExtendedCopyrightIds !== undefined) - if (typeof message.useExtendedCopyrightIds !== "boolean") - return "useExtendedCopyrightIds: boolean expected"; - if (message.precipitationsOptions !== undefined && message.precipitationsOptions !== null) { - var error = $types[7].verify(message.precipitationsOptions); - if (error) - return "precipitationsOptions." + error; - } - if (message.captureOptions !== undefined && message.captureOptions !== null) { - var error = $types[8].verify(message.captureOptions); - if (error) - return "captureOptions." + error; - } - if (message.show_2dMapsIcon !== undefined) - if (typeof message.show_2dMapsIcon !== "boolean") - return "show_2dMapsIcon: boolean expected"; - if (message.disableInternalBrowser !== undefined) - if (typeof message.disableInternalBrowser !== "boolean") - return "disableInternalBrowser: boolean expected"; - if (message.internalBrowserBlacklist !== undefined) - if (!$util.isString(message.internalBrowserBlacklist)) - return "internalBrowserBlacklist: string expected"; - if (message.internalBrowserOriginWhitelist !== undefined) - if (!$util.isString(message.internalBrowserOriginWhitelist)) - return "internalBrowserOriginWhitelist: string expected"; - if (message.polarTileMergingLevel !== undefined) - if (!$util.isInteger(message.polarTileMergingLevel)) - return "polarTileMergingLevel: integer expected"; - if (message.jsBridgeRequestWhitelist !== undefined) - if (!$util.isString(message.jsBridgeRequestWhitelist)) - return "jsBridgeRequestWhitelist: string expected"; - if (message.mapsOptions !== undefined && message.mapsOptions !== null) { - var error = $types[15].verify(message.mapsOptions); - if (error) - return "mapsOptions." + error; - } - return null; - }; + var context2d = context2DsByHeight[height]; + if (!defined(context2d)) { + var canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + context2d = canvas.getContext('2d'); + context2d.globalCompositeOperation = 'copy'; + context2DsByHeight[height] = context2d; + } - ClientOptionsProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ClientOptionsProto) - return object; - var message = new $root.keyhole.dbroot.ClientOptionsProto(); - if (object.disableDiskCache !== undefined && object.disableDiskCache !== null) - message.disableDiskCache = Boolean(object.disableDiskCache); - if (object.disableEmbeddedBrowserVista !== undefined && object.disableEmbeddedBrowserVista !== null) - message.disableEmbeddedBrowserVista = Boolean(object.disableEmbeddedBrowserVista); - if (object.drawAtmosphere !== undefined && object.drawAtmosphere !== null) - message.drawAtmosphere = Boolean(object.drawAtmosphere); - if (object.drawStars !== undefined && object.drawStars !== null) - message.drawStars = Boolean(object.drawStars); - if (object.shaderFilePrefix !== undefined && object.shaderFilePrefix !== null) - message.shaderFilePrefix = String(object.shaderFilePrefix); - if (object.useProtobufQuadtreePackets !== undefined && object.useProtobufQuadtreePackets !== null) - message.useProtobufQuadtreePackets = Boolean(object.useProtobufQuadtreePackets); - if (object.useExtendedCopyrightIds !== undefined && object.useExtendedCopyrightIds !== null) - message.useExtendedCopyrightIds = Boolean(object.useExtendedCopyrightIds); - if (object.precipitationsOptions !== undefined && object.precipitationsOptions !== null) { - if (typeof object.precipitationsOptions !== "object") - throw TypeError(".keyhole.dbroot.ClientOptionsProto.precipitationsOptions: object expected"); - message.precipitationsOptions = $types[7].fromObject(object.precipitationsOptions); - } - if (object.captureOptions !== undefined && object.captureOptions !== null) { - if (typeof object.captureOptions !== "object") - throw TypeError(".keyhole.dbroot.ClientOptionsProto.captureOptions: object expected"); - message.captureOptions = $types[8].fromObject(object.captureOptions); - } - if (object.show_2dMapsIcon !== undefined && object.show_2dMapsIcon !== null) - message.show_2dMapsIcon = Boolean(object.show_2dMapsIcon); - if (object.disableInternalBrowser !== undefined && object.disableInternalBrowser !== null) - message.disableInternalBrowser = Boolean(object.disableInternalBrowser); - if (object.internalBrowserBlacklist !== undefined && object.internalBrowserBlacklist !== null) - message.internalBrowserBlacklist = String(object.internalBrowserBlacklist); - if (object.internalBrowserOriginWhitelist !== undefined && object.internalBrowserOriginWhitelist !== null) - message.internalBrowserOriginWhitelist = String(object.internalBrowserOriginWhitelist); - if (object.polarTileMergingLevel !== undefined && object.polarTileMergingLevel !== null) - message.polarTileMergingLevel = object.polarTileMergingLevel | 0; - if (object.jsBridgeRequestWhitelist !== undefined && object.jsBridgeRequestWhitelist !== null) - message.jsBridgeRequestWhitelist = String(object.jsBridgeRequestWhitelist); - if (object.mapsOptions !== undefined && object.mapsOptions !== null) { - if (typeof object.mapsOptions !== "object") - throw TypeError(".keyhole.dbroot.ClientOptionsProto.mapsOptions: object expected"); - message.mapsOptions = $types[15].fromObject(object.mapsOptions); - } - return message; - }; + context2d.drawImage(image, 0, 0, width, height); + return context2d.getImageData(0, 0, width, height).data; + } - ClientOptionsProto.from = ClientOptionsProto.fromObject; + return getImagePixels; +}); - ClientOptionsProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.disableDiskCache = false; - object.disableEmbeddedBrowserVista = false; - object.drawAtmosphere = true; - object.drawStars = true; - object.shaderFilePrefix = ""; - object.useProtobufQuadtreePackets = false; - object.useExtendedCopyrightIds = true; - object.precipitationsOptions = null; - object.captureOptions = null; - object.show_2dMapsIcon = true; - object.disableInternalBrowser = false; - object.internalBrowserBlacklist = ""; - object.internalBrowserOriginWhitelist = "*"; - object.polarTileMergingLevel = 0; - object.jsBridgeRequestWhitelist = "http://*.google.com/*"; - object.mapsOptions = null; - } - if (message.disableDiskCache !== undefined && message.disableDiskCache !== null && message.hasOwnProperty("disableDiskCache")) - object.disableDiskCache = message.disableDiskCache; - if (message.disableEmbeddedBrowserVista !== undefined && message.disableEmbeddedBrowserVista !== null && message.hasOwnProperty("disableEmbeddedBrowserVista")) - object.disableEmbeddedBrowserVista = message.disableEmbeddedBrowserVista; - if (message.drawAtmosphere !== undefined && message.drawAtmosphere !== null && message.hasOwnProperty("drawAtmosphere")) - object.drawAtmosphere = message.drawAtmosphere; - if (message.drawStars !== undefined && message.drawStars !== null && message.hasOwnProperty("drawStars")) - object.drawStars = message.drawStars; - if (message.shaderFilePrefix !== undefined && message.shaderFilePrefix !== null && message.hasOwnProperty("shaderFilePrefix")) - object.shaderFilePrefix = message.shaderFilePrefix; - if (message.useProtobufQuadtreePackets !== undefined && message.useProtobufQuadtreePackets !== null && message.hasOwnProperty("useProtobufQuadtreePackets")) - object.useProtobufQuadtreePackets = message.useProtobufQuadtreePackets; - if (message.useExtendedCopyrightIds !== undefined && message.useExtendedCopyrightIds !== null && message.hasOwnProperty("useExtendedCopyrightIds")) - object.useExtendedCopyrightIds = message.useExtendedCopyrightIds; - if (message.precipitationsOptions !== undefined && message.precipitationsOptions !== null && message.hasOwnProperty("precipitationsOptions")) - object.precipitationsOptions = $types[7].toObject(message.precipitationsOptions, options); - if (message.captureOptions !== undefined && message.captureOptions !== null && message.hasOwnProperty("captureOptions")) - object.captureOptions = $types[8].toObject(message.captureOptions, options); - if (message.show_2dMapsIcon !== undefined && message.show_2dMapsIcon !== null && message.hasOwnProperty("show_2dMapsIcon")) - object.show_2dMapsIcon = message.show_2dMapsIcon; - if (message.disableInternalBrowser !== undefined && message.disableInternalBrowser !== null && message.hasOwnProperty("disableInternalBrowser")) - object.disableInternalBrowser = message.disableInternalBrowser; - if (message.internalBrowserBlacklist !== undefined && message.internalBrowserBlacklist !== null && message.hasOwnProperty("internalBrowserBlacklist")) - object.internalBrowserBlacklist = message.internalBrowserBlacklist; - if (message.internalBrowserOriginWhitelist !== undefined && message.internalBrowserOriginWhitelist !== null && message.hasOwnProperty("internalBrowserOriginWhitelist")) - object.internalBrowserOriginWhitelist = message.internalBrowserOriginWhitelist; - if (message.polarTileMergingLevel !== undefined && message.polarTileMergingLevel !== null && message.hasOwnProperty("polarTileMergingLevel")) - object.polarTileMergingLevel = message.polarTileMergingLevel; - if (message.jsBridgeRequestWhitelist !== undefined && message.jsBridgeRequestWhitelist !== null && message.hasOwnProperty("jsBridgeRequestWhitelist")) - object.jsBridgeRequestWhitelist = message.jsBridgeRequestWhitelist; - if (message.mapsOptions !== undefined && message.mapsOptions !== null && message.hasOwnProperty("mapsOptions")) - object.mapsOptions = $types[15].toObject(message.mapsOptions, options); - return object; - }; +define('Core/getStringFromTypedArray',[ + './defaultValue', + './defined', + './DeveloperError', + './RuntimeError' + ], function( + defaultValue, + defined, + DeveloperError, + RuntimeError) { + 'use strict'; - ClientOptionsProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + /** + * @private + */ + function getStringFromTypedArray(uint8Array, byteOffset, byteLength) { + if (!defined(uint8Array)) { + throw new DeveloperError('uint8Array is required.'); + } + if (byteOffset < 0) { + throw new DeveloperError('byteOffset cannot be negative.'); + } + if (byteLength < 0) { + throw new DeveloperError('byteLength cannot be negative.'); + } + if ((byteOffset + byteLength) > uint8Array.byteLength) { + throw new DeveloperError('sub-region exceeds array bounds.'); + } + + byteOffset = defaultValue(byteOffset, 0); + byteLength = defaultValue(byteLength, uint8Array.byteLength - byteOffset); - ClientOptionsProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + uint8Array = uint8Array.subarray(byteOffset, byteOffset + byteLength); - ClientOptionsProto.PrecipitationsOptions = (function() { + return getStringFromTypedArray.decode(uint8Array); + } - function PrecipitationsOptions(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + // Exposed functions for testing + getStringFromTypedArray.decodeWithTextDecoder = function(view) { + var decoder = new TextDecoder('utf-8'); + return decoder.decode(view); + }; - PrecipitationsOptions.prototype.imageUrl = ""; - PrecipitationsOptions.prototype.imageExpireTime = 900; - PrecipitationsOptions.prototype.maxColorDistance = 20; - PrecipitationsOptions.prototype.imageLevel = 5; - PrecipitationsOptions.prototype.weatherMapping = $util.emptyArray; - PrecipitationsOptions.prototype.cloudsLayerUrl = ""; - PrecipitationsOptions.prototype.animationDecelerationDelay = 20; - var $types = { - 4 : "keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping" - }; - $lazyTypes.push($types); + getStringFromTypedArray.decodeWithFromCharCode = function(view) { + var result = ''; + var codePoints = utf8Handler(view); + var length = codePoints.length; + for (var i = 0; i < length; ++i) { + var cp = codePoints[i]; + if (cp <= 0xFFFF) { + result += String.fromCharCode(cp); + } else { + cp -= 0x10000; + result += String.fromCharCode((cp >> 10) + 0xD800, + (cp & 0x3FF) + 0xDC00); + } - PrecipitationsOptions.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.imageUrl = reader.string(); - break; - case 2: - message.imageExpireTime = reader.int32(); - break; - case 3: - message.maxColorDistance = reader.int32(); - break; - case 4: - message.imageLevel = reader.int32(); - break; - case 5: - if (!(message.weatherMapping && message.weatherMapping.length)) - message.weatherMapping = []; - message.weatherMapping.push($types[4].decode(reader, reader.uint32())); - break; - case 6: - message.cloudsLayerUrl = reader.string(); - break; - case 7: - message.animationDecelerationDelay = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + } + return result; + }; - PrecipitationsOptions.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.imageUrl !== undefined) - if (!$util.isString(message.imageUrl)) - return "imageUrl: string expected"; - if (message.imageExpireTime !== undefined) - if (!$util.isInteger(message.imageExpireTime)) - return "imageExpireTime: integer expected"; - if (message.maxColorDistance !== undefined) - if (!$util.isInteger(message.maxColorDistance)) - return "maxColorDistance: integer expected"; - if (message.imageLevel !== undefined) - if (!$util.isInteger(message.imageLevel)) - return "imageLevel: integer expected"; - if (message.weatherMapping !== undefined) { - if (!Array.isArray(message.weatherMapping)) - return "weatherMapping: array expected"; - for (var i = 0; i < message.weatherMapping.length; ++i) { - var error = $types[4].verify(message.weatherMapping[i]); - if (error) - return "weatherMapping." + error; - } - } - if (message.cloudsLayerUrl !== undefined) - if (!$util.isString(message.cloudsLayerUrl)) - return "cloudsLayerUrl: string expected"; - if (message.animationDecelerationDelay !== undefined) - if (typeof message.animationDecelerationDelay !== "number") - return "animationDecelerationDelay: number expected"; - return null; - }; + function inRange(a, min, max) { + return min <= a && a <= max; + } - PrecipitationsOptions.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions) - return object; - var message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions(); - if (object.imageUrl !== undefined && object.imageUrl !== null) - message.imageUrl = String(object.imageUrl); - if (object.imageExpireTime !== undefined && object.imageExpireTime !== null) - message.imageExpireTime = object.imageExpireTime | 0; - if (object.maxColorDistance !== undefined && object.maxColorDistance !== null) - message.maxColorDistance = object.maxColorDistance | 0; - if (object.imageLevel !== undefined && object.imageLevel !== null) - message.imageLevel = object.imageLevel | 0; - if (object.weatherMapping) { - if (!Array.isArray(object.weatherMapping)) - throw TypeError(".keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.weatherMapping: array expected"); - message.weatherMapping = []; - for (var i = 0; i < object.weatherMapping.length; ++i) { - if (typeof object.weatherMapping[i] !== "object") - throw TypeError(".keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.weatherMapping: object expected"); - message.weatherMapping[i] = $types[4].fromObject(object.weatherMapping[i]); - } - } - if (object.cloudsLayerUrl !== undefined && object.cloudsLayerUrl !== null) - message.cloudsLayerUrl = String(object.cloudsLayerUrl); - if (object.animationDecelerationDelay !== undefined && object.animationDecelerationDelay !== null) - message.animationDecelerationDelay = Number(object.animationDecelerationDelay); - return message; - }; + // This code is inspired by public domain code found here: https://github.com/inexorabletash/text-encoding + function utf8Handler(utfBytes) { + var codePoint = 0; + var bytesSeen = 0; + var bytesNeeded = 0; + var lowerBoundary = 0x80; + var upperBoundary = 0xBF; - PrecipitationsOptions.from = PrecipitationsOptions.fromObject; + var codePoints = []; + var length = utfBytes.length; + for (var i = 0; i < length; ++i) { + var currentByte = utfBytes[i]; - PrecipitationsOptions.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.weatherMapping = []; - if (options.defaults) { - object.imageUrl = ""; - object.imageExpireTime = 900; - object.maxColorDistance = 20; - object.imageLevel = 5; - object.cloudsLayerUrl = ""; - object.animationDecelerationDelay = 20; - } - if (message.imageUrl !== undefined && message.imageUrl !== null && message.hasOwnProperty("imageUrl")) - object.imageUrl = message.imageUrl; - if (message.imageExpireTime !== undefined && message.imageExpireTime !== null && message.hasOwnProperty("imageExpireTime")) - object.imageExpireTime = message.imageExpireTime; - if (message.maxColorDistance !== undefined && message.maxColorDistance !== null && message.hasOwnProperty("maxColorDistance")) - object.maxColorDistance = message.maxColorDistance; - if (message.imageLevel !== undefined && message.imageLevel !== null && message.hasOwnProperty("imageLevel")) - object.imageLevel = message.imageLevel; - if (message.weatherMapping !== undefined && message.weatherMapping !== null && message.hasOwnProperty("weatherMapping")) { - object.weatherMapping = []; - for (var j = 0; j < message.weatherMapping.length; ++j) - object.weatherMapping[j] = $types[4].toObject(message.weatherMapping[j], options); - } - if (message.cloudsLayerUrl !== undefined && message.cloudsLayerUrl !== null && message.hasOwnProperty("cloudsLayerUrl")) - object.cloudsLayerUrl = message.cloudsLayerUrl; - if (message.animationDecelerationDelay !== undefined && message.animationDecelerationDelay !== null && message.hasOwnProperty("animationDecelerationDelay")) - object.animationDecelerationDelay = message.animationDecelerationDelay; - return object; - }; + // If bytesNeeded = 0, then we are starting a new character + if (bytesNeeded === 0) { + // 1 Byte Ascii character + if (inRange(currentByte, 0x00, 0x7F)) { + // Return a code point whose value is byte. + codePoints.push(currentByte); + continue; + } - PrecipitationsOptions.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + // 2 Byte character + if (inRange(currentByte, 0xC2, 0xDF)) { + bytesNeeded = 1; + codePoint = currentByte & 0x1F; + continue; + } - PrecipitationsOptions.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + // 3 Byte character + if (inRange(currentByte, 0xE0, 0xEF)) { + // If byte is 0xE0, set utf-8 lower boundary to 0xA0. + if (currentByte === 0xE0) { + lowerBoundary = 0xA0; + } + // If byte is 0xED, set utf-8 upper boundary to 0x9F. + if (currentByte === 0xED) { + upperBoundary = 0x9F; + } - PrecipitationsOptions.WeatherMapping = (function() { + bytesNeeded = 2; + codePoint = currentByte & 0xF; + continue; + } - function WeatherMapping(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + // 4 Byte character + if (inRange(currentByte, 0xF0, 0xF4)) { + // If byte is 0xF0, set utf-8 lower boundary to 0x90. + if (currentByte === 0xF0) { + lowerBoundary = 0x90; + } + // If byte is 0xF4, set utf-8 upper boundary to 0x8F. + if (currentByte === 0xF4) { + upperBoundary = 0x8F; + } - WeatherMapping.prototype.colorAbgr = 0; - WeatherMapping.prototype.weatherType = 0; - WeatherMapping.prototype.elongation = 1; - WeatherMapping.prototype.opacity = 0; - WeatherMapping.prototype.fogDensity = 0; - WeatherMapping.prototype.speed0 = 0; - WeatherMapping.prototype.speed1 = 0; - WeatherMapping.prototype.speed2 = 0; - WeatherMapping.prototype.speed3 = 0; + bytesNeeded = 3; + codePoint = currentByte & 0x7; + continue; + } - var $types = { - 1 : "keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping.WeatherType" - }; - $lazyTypes.push($types); + throw new RuntimeError('String decoding failed.'); + } - WeatherMapping.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.colorAbgr = reader.uint32(); - break; - case 2: - message.weatherType = reader.uint32(); - break; - case 3: - message.elongation = reader.float(); - break; - case 4: - message.opacity = reader.float(); - break; - case 5: - message.fogDensity = reader.float(); - break; - case 6: - message.speed0 = reader.float(); - break; - case 7: - message.speed1 = reader.float(); - break; - case 8: - message.speed2 = reader.float(); - break; - case 9: - message.speed3 = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + // Out of range, so ignore the first part(s) of the character and continue with this byte on its own + if (!inRange(currentByte, lowerBoundary, upperBoundary)) { + codePoint = bytesNeeded = bytesSeen = 0; + lowerBoundary = 0x80; + upperBoundary = 0xBF; + --i; + continue; + } - WeatherMapping.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isInteger(message.colorAbgr)) - return "colorAbgr: integer expected"; - switch (message.weatherType) { - default: - return "weatherType: enum value expected"; - case 0: - case 1: - case 2: - break; - } - if (message.elongation !== undefined) - if (typeof message.elongation !== "number") - return "elongation: number expected"; - if (message.opacity !== undefined) - if (typeof message.opacity !== "number") - return "opacity: number expected"; - if (message.fogDensity !== undefined) - if (typeof message.fogDensity !== "number") - return "fogDensity: number expected"; - if (message.speed0 !== undefined) - if (typeof message.speed0 !== "number") - return "speed0: number expected"; - if (message.speed1 !== undefined) - if (typeof message.speed1 !== "number") - return "speed1: number expected"; - if (message.speed2 !== undefined) - if (typeof message.speed2 !== "number") - return "speed2: number expected"; - if (message.speed3 !== undefined) - if (typeof message.speed3 !== "number") - return "speed3: number expected"; - return null; - }; + // Set appropriate boundaries, since we've now checked byte 2 of a potential longer character + lowerBoundary = 0x80; + upperBoundary = 0xBF; - WeatherMapping.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping) - return object; - var message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping(); - if (object.colorAbgr !== undefined && object.colorAbgr !== null) - message.colorAbgr = object.colorAbgr >>> 0; - switch (object.weatherType) { - case "NO_PRECIPITATION": - case 0: - message.weatherType = 0; - break; - case "RAIN": - case 1: - message.weatherType = 1; - break; - case "SNOW": - case 2: - message.weatherType = 2; - break; - } - if (object.elongation !== undefined && object.elongation !== null) - message.elongation = Number(object.elongation); - if (object.opacity !== undefined && object.opacity !== null) - message.opacity = Number(object.opacity); - if (object.fogDensity !== undefined && object.fogDensity !== null) - message.fogDensity = Number(object.fogDensity); - if (object.speed0 !== undefined && object.speed0 !== null) - message.speed0 = Number(object.speed0); - if (object.speed1 !== undefined && object.speed1 !== null) - message.speed1 = Number(object.speed1); - if (object.speed2 !== undefined && object.speed2 !== null) - message.speed2 = Number(object.speed2); - if (object.speed3 !== undefined && object.speed3 !== null) - message.speed3 = Number(object.speed3); - return message; - }; + // Add byte to code point + codePoint = (codePoint << 6) | (currentByte & 0x3F); - WeatherMapping.from = WeatherMapping.fromObject; + // We have the correct number of bytes, so push and reset for next character + ++bytesSeen; + if (bytesSeen === bytesNeeded) { + codePoints.push(codePoint); + codePoint = bytesNeeded = bytesSeen = 0; + } + } - WeatherMapping.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.colorAbgr = 0; - object.weatherType = options.enums === String ? "NO_PRECIPITATION" : 0; - object.elongation = 1; - object.opacity = 0; - object.fogDensity = 0; - object.speed0 = 0; - object.speed1 = 0; - object.speed2 = 0; - object.speed3 = 0; - } - if (message.colorAbgr !== undefined && message.colorAbgr !== null && message.hasOwnProperty("colorAbgr")) - object.colorAbgr = message.colorAbgr; - if (message.weatherType !== undefined && message.weatherType !== null && message.hasOwnProperty("weatherType")) - object.weatherType = options.enums === String ? $types[1][message.weatherType] : message.weatherType; - if (message.elongation !== undefined && message.elongation !== null && message.hasOwnProperty("elongation")) - object.elongation = message.elongation; - if (message.opacity !== undefined && message.opacity !== null && message.hasOwnProperty("opacity")) - object.opacity = message.opacity; - if (message.fogDensity !== undefined && message.fogDensity !== null && message.hasOwnProperty("fogDensity")) - object.fogDensity = message.fogDensity; - if (message.speed0 !== undefined && message.speed0 !== null && message.hasOwnProperty("speed0")) - object.speed0 = message.speed0; - if (message.speed1 !== undefined && message.speed1 !== null && message.hasOwnProperty("speed1")) - object.speed1 = message.speed1; - if (message.speed2 !== undefined && message.speed2 !== null && message.hasOwnProperty("speed2")) - object.speed2 = message.speed2; - if (message.speed3 !== undefined && message.speed3 !== null && message.hasOwnProperty("speed3")) - object.speed3 = message.speed3; - return object; - }; + return codePoints; + } - WeatherMapping.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + if (typeof TextDecoder !== 'undefined') { + getStringFromTypedArray.decode = getStringFromTypedArray.decodeWithTextDecoder; + } else { + getStringFromTypedArray.decode = getStringFromTypedArray.decodeWithFromCharCode; + } - WeatherMapping.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + return getStringFromTypedArray; +}); - WeatherMapping.WeatherType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values["NO_PRECIPITATION"] = 0; - values["RAIN"] = 1; - values["SNOW"] = 2; - return values; - })(); +define('Core/getMagic',[ + './defaultValue', + './getStringFromTypedArray' + ], function( + defaultValue, + getStringFromTypedArray) { + 'use strict'; - return WeatherMapping; - })(); + /** + * @private + */ + function getMagic(uint8Array, byteOffset) { + byteOffset = defaultValue(byteOffset, 0); + return getStringFromTypedArray(uint8Array, byteOffset, Math.min(4, uint8Array.length)); + } - return PrecipitationsOptions; - })(); + return getMagic; +}); - ClientOptionsProto.CaptureOptions = (function() { +/*! + * protobuf.js v6.7.0 (c) 2016, Daniel Wirtz + * Compiled Wed, 22 Mar 2017 17:30:26 UTC + * Licensed under the BSD-3-Clause License + * see: https://github.com/dcodeIO/protobuf.js for details + */ +(function(global,undefined){"use strict";(function prelude(modules, cache, entries) { - function CaptureOptions(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + // This is the prelude used to bundle protobuf.js for the browser. Wraps up the CommonJS + // sources through a conflict-free require shim and is again wrapped within an iife that + // provides a unified `global` and a minification-friendly `undefined` var plus a global + // "use strict" directive so that minification can remove the directives of each module. - CaptureOptions.prototype.allowSaveAsImage = true; - CaptureOptions.prototype.maxFreeCaptureRes = 2400; - CaptureOptions.prototype.maxPremiumCaptureRes = 4800; + function $require(name) { + var $module = cache[name]; + if (!$module) + modules[name][0].call($module = cache[name] = { exports: {} }, $require, $module, $module.exports); + return $module.exports; + } - CaptureOptions.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ClientOptionsProto.CaptureOptions(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.allowSaveAsImage = reader.bool(); - break; - case 2: - message.maxFreeCaptureRes = reader.int32(); - break; - case 3: - message.maxPremiumCaptureRes = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + // Expose globally + var protobuf = global.protobuf = $require(entries[0]); - CaptureOptions.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.allowSaveAsImage !== undefined) - if (typeof message.allowSaveAsImage !== "boolean") - return "allowSaveAsImage: boolean expected"; - if (message.maxFreeCaptureRes !== undefined) - if (!$util.isInteger(message.maxFreeCaptureRes)) - return "maxFreeCaptureRes: integer expected"; - if (message.maxPremiumCaptureRes !== undefined) - if (!$util.isInteger(message.maxPremiumCaptureRes)) - return "maxPremiumCaptureRes: integer expected"; - return null; - }; + // Be nice to AMD + if (typeof define === "function" && define.amd) + define('ThirdParty/protobuf-minimal',[], function() { + protobuf.configure(); + return protobuf; + }); - CaptureOptions.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.CaptureOptions) - return object; - var message = new $root.keyhole.dbroot.ClientOptionsProto.CaptureOptions(); - if (object.allowSaveAsImage !== undefined && object.allowSaveAsImage !== null) - message.allowSaveAsImage = Boolean(object.allowSaveAsImage); - if (object.maxFreeCaptureRes !== undefined && object.maxFreeCaptureRes !== null) - message.maxFreeCaptureRes = object.maxFreeCaptureRes | 0; - if (object.maxPremiumCaptureRes !== undefined && object.maxPremiumCaptureRes !== null) - message.maxPremiumCaptureRes = object.maxPremiumCaptureRes | 0; - return message; - }; + // Be nice to CommonJS + if (typeof module === "object" && module && module.exports) + module.exports = protobuf; - CaptureOptions.from = CaptureOptions.fromObject; +})/* end of prelude */({1:[function(require,module,exports){ +"use strict"; +module.exports = asPromise; - CaptureOptions.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.allowSaveAsImage = true; - object.maxFreeCaptureRes = 2400; - object.maxPremiumCaptureRes = 4800; - } - if (message.allowSaveAsImage !== undefined && message.allowSaveAsImage !== null && message.hasOwnProperty("allowSaveAsImage")) - object.allowSaveAsImage = message.allowSaveAsImage; - if (message.maxFreeCaptureRes !== undefined && message.maxFreeCaptureRes !== null && message.hasOwnProperty("maxFreeCaptureRes")) - object.maxFreeCaptureRes = message.maxFreeCaptureRes; - if (message.maxPremiumCaptureRes !== undefined && message.maxPremiumCaptureRes !== null && message.hasOwnProperty("maxPremiumCaptureRes")) - object.maxPremiumCaptureRes = message.maxPremiumCaptureRes; - return object; - }; +/** + * Returns a promise from a node-style callback function. + * @memberof util + * @param {function(?Error, ...*)} fn Function to call + * @param {*} ctx Function context + * @param {...*} params Function arguments + * @returns {Promise<*>} Promisified function + */ +function asPromise(fn, ctx/*, varargs */) { + var params = []; + for (var i = 2; i < arguments.length;) + params.push(arguments[i++]); + var pending = true; + return new Promise(function asPromiseExecutor(resolve, reject) { + params.push(function asPromiseCallback(err/*, varargs */) { + if (pending) { + pending = false; + if (err) + reject(err); + else { + var args = []; + for (var i = 1; i < arguments.length;) + args.push(arguments[i++]); + resolve.apply(null, args); + } + } + }); + try { + fn.apply(ctx || this, params); // eslint-disable-line no-invalid-this + } catch (err) { + if (pending) { + pending = false; + reject(err); + } + } + }); +} - CaptureOptions.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +},{}],2:[function(require,module,exports){ +"use strict"; - CaptureOptions.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +/** + * A minimal base64 implementation for number arrays. + * @memberof util + * @namespace + */ +var base64 = exports; - return CaptureOptions; - })(); - - ClientOptionsProto.MapsOptions = (function() { - - function MapsOptions(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Calculates the byte length of a base64 encoded string. + * @param {string} string Base64 encoded string + * @returns {number} Byte length + */ +base64.length = function length(string) { + var p = string.length; + if (!p) + return 0; + var n = 0; + while (--p % 4 > 1 && string.charAt(p) === "=") + ++n; + return Math.ceil(string.length * 3) / 4 - n; +}; - MapsOptions.prototype.enableMaps = false; - MapsOptions.prototype.docsAutoDownloadEnabled = false; - MapsOptions.prototype.docsAutoDownloadInterval = 0; - MapsOptions.prototype.docsAutoUploadEnabled = false; - MapsOptions.prototype.docsAutoUploadDelay = 0; +// Base64 encoding table +var b64 = new Array(64); - MapsOptions.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ClientOptionsProto.MapsOptions(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.enableMaps = reader.bool(); - break; - case 2: - message.docsAutoDownloadEnabled = reader.bool(); - break; - case 3: - message.docsAutoDownloadInterval = reader.int32(); - break; - case 4: - message.docsAutoUploadEnabled = reader.bool(); - break; - case 5: - message.docsAutoUploadDelay = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +// Base64 decoding table +var s64 = new Array(123); - MapsOptions.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.enableMaps !== undefined) - if (typeof message.enableMaps !== "boolean") - return "enableMaps: boolean expected"; - if (message.docsAutoDownloadEnabled !== undefined) - if (typeof message.docsAutoDownloadEnabled !== "boolean") - return "docsAutoDownloadEnabled: boolean expected"; - if (message.docsAutoDownloadInterval !== undefined) - if (!$util.isInteger(message.docsAutoDownloadInterval)) - return "docsAutoDownloadInterval: integer expected"; - if (message.docsAutoUploadEnabled !== undefined) - if (typeof message.docsAutoUploadEnabled !== "boolean") - return "docsAutoUploadEnabled: boolean expected"; - if (message.docsAutoUploadDelay !== undefined) - if (!$util.isInteger(message.docsAutoUploadDelay)) - return "docsAutoUploadDelay: integer expected"; - return null; - }; +// 65..90, 97..122, 48..57, 43, 47 +for (var i = 0; i < 64;) + s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; - MapsOptions.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.MapsOptions) - return object; - var message = new $root.keyhole.dbroot.ClientOptionsProto.MapsOptions(); - if (object.enableMaps !== undefined && object.enableMaps !== null) - message.enableMaps = Boolean(object.enableMaps); - if (object.docsAutoDownloadEnabled !== undefined && object.docsAutoDownloadEnabled !== null) - message.docsAutoDownloadEnabled = Boolean(object.docsAutoDownloadEnabled); - if (object.docsAutoDownloadInterval !== undefined && object.docsAutoDownloadInterval !== null) - message.docsAutoDownloadInterval = object.docsAutoDownloadInterval | 0; - if (object.docsAutoUploadEnabled !== undefined && object.docsAutoUploadEnabled !== null) - message.docsAutoUploadEnabled = Boolean(object.docsAutoUploadEnabled); - if (object.docsAutoUploadDelay !== undefined && object.docsAutoUploadDelay !== null) - message.docsAutoUploadDelay = object.docsAutoUploadDelay | 0; - return message; - }; +/** + * Encodes a buffer to a base64 encoded string. + * @param {Uint8Array} buffer Source buffer + * @param {number} start Source start + * @param {number} end Source end + * @returns {string} Base64 encoded string + */ +base64.encode = function encode(buffer, start, end) { + var string = []; // alt: new Array(Math.ceil((end - start) / 3) * 4); + var i = 0, // output index + j = 0, // goto index + t; // temporary + while (start < end) { + var b = buffer[start++]; + switch (j) { + case 0: + string[i++] = b64[b >> 2]; + t = (b & 3) << 4; + j = 1; + break; + case 1: + string[i++] = b64[t | b >> 4]; + t = (b & 15) << 2; + j = 2; + break; + case 2: + string[i++] = b64[t | b >> 6]; + string[i++] = b64[b & 63]; + j = 0; + break; + } + } + if (j) { + string[i++] = b64[t]; + string[i ] = 61; + if (j === 1) + string[i + 1] = 61; + } + return String.fromCharCode.apply(String, string); +}; - MapsOptions.from = MapsOptions.fromObject; +var invalidEncoding = "invalid encoding"; - MapsOptions.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.enableMaps = false; - object.docsAutoDownloadEnabled = false; - object.docsAutoDownloadInterval = 0; - object.docsAutoUploadEnabled = false; - object.docsAutoUploadDelay = 0; - } - if (message.enableMaps !== undefined && message.enableMaps !== null && message.hasOwnProperty("enableMaps")) - object.enableMaps = message.enableMaps; - if (message.docsAutoDownloadEnabled !== undefined && message.docsAutoDownloadEnabled !== null && message.hasOwnProperty("docsAutoDownloadEnabled")) - object.docsAutoDownloadEnabled = message.docsAutoDownloadEnabled; - if (message.docsAutoDownloadInterval !== undefined && message.docsAutoDownloadInterval !== null && message.hasOwnProperty("docsAutoDownloadInterval")) - object.docsAutoDownloadInterval = message.docsAutoDownloadInterval; - if (message.docsAutoUploadEnabled !== undefined && message.docsAutoUploadEnabled !== null && message.hasOwnProperty("docsAutoUploadEnabled")) - object.docsAutoUploadEnabled = message.docsAutoUploadEnabled; - if (message.docsAutoUploadDelay !== undefined && message.docsAutoUploadDelay !== null && message.hasOwnProperty("docsAutoUploadDelay")) - object.docsAutoUploadDelay = message.docsAutoUploadDelay; - return object; - }; +/** + * Decodes a base64 encoded string to a buffer. + * @param {string} string Source string + * @param {Uint8Array} buffer Destination buffer + * @param {number} offset Destination offset + * @returns {number} Number of bytes written + * @throws {Error} If encoding is invalid + */ +base64.decode = function decode(string, buffer, offset) { + var start = offset; + var j = 0, // goto index + t; // temporary + for (var i = 0; i < string.length;) { + var c = string.charCodeAt(i++); + if (c === 61 && j > 1) + break; + if ((c = s64[c]) === undefined) + throw Error(invalidEncoding); + switch (j) { + case 0: + t = c; + j = 1; + break; + case 1: + buffer[offset++] = t << 2 | (c & 48) >> 4; + t = c; + j = 2; + break; + case 2: + buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2; + t = c; + j = 3; + break; + case 3: + buffer[offset++] = (t & 3) << 6 | c; + j = 0; + break; + } + } + if (j === 1) + throw Error(invalidEncoding); + return offset - start; +}; - MapsOptions.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * Tests if the specified string appears to be base64 encoded. + * @param {string} string String to test + * @returns {boolean} `true` if probably base64 encoded, otherwise false + */ +base64.test = function test(string) { + return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string); +}; - MapsOptions.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +},{}],3:[function(require,module,exports){ +"use strict"; +module.exports = EventEmitter; - return MapsOptions; - })(); +/** + * Constructs a new event emitter instance. + * @classdesc A minimal event emitter. + * @memberof util + * @constructor + */ +function EventEmitter() { - return ClientOptionsProto; - })(); + /** + * Registered listeners. + * @type {Object.<string,*>} + * @private + */ + this._listeners = {}; +} - dbroot.FetchingOptionsProto = (function() { +/** + * Registers an event listener. + * @param {string} evt Event name + * @param {function} fn Listener + * @param {*} [ctx] Listener context + * @returns {util.EventEmitter} `this` + */ +EventEmitter.prototype.on = function on(evt, fn, ctx) { + (this._listeners[evt] || (this._listeners[evt] = [])).push({ + fn : fn, + ctx : ctx || this + }); + return this; +}; - function FetchingOptionsProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Removes an event listener or any matching listeners if arguments are omitted. + * @param {string} [evt] Event name. Removes all listeners if omitted. + * @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted. + * @returns {util.EventEmitter} `this` + */ +EventEmitter.prototype.off = function off(evt, fn) { + if (evt === undefined) + this._listeners = {}; + else { + if (fn === undefined) + this._listeners[evt] = []; + else { + var listeners = this._listeners[evt]; + for (var i = 0; i < listeners.length;) + if (listeners[i].fn === fn) + listeners.splice(i, 1); + else + ++i; + } + } + return this; +}; - FetchingOptionsProto.prototype.maxRequestsPerQuery = 1; - FetchingOptionsProto.prototype.forceMaxRequestsPerQuery = false; - FetchingOptionsProto.prototype.sortBatches = false; - FetchingOptionsProto.prototype.maxDrawable = 2; - FetchingOptionsProto.prototype.maxImagery = 2; - FetchingOptionsProto.prototype.maxTerrain = 5; - FetchingOptionsProto.prototype.maxQuadtree = 5; - FetchingOptionsProto.prototype.maxDioramaMetadata = 1; - FetchingOptionsProto.prototype.maxDioramaData = 0; - FetchingOptionsProto.prototype.maxConsumerFetchRatio = 1; - FetchingOptionsProto.prototype.maxProEcFetchRatio = 0; - FetchingOptionsProto.prototype.safeOverallQps = 0; - FetchingOptionsProto.prototype.safeImageryQps = 0; - FetchingOptionsProto.prototype.domainsForHttps = "google.com gstatic.com"; - FetchingOptionsProto.prototype.hostsForHttp = ""; +/** + * Emits an event by calling its listeners with the specified arguments. + * @param {string} evt Event name + * @param {...*} args Arguments + * @returns {util.EventEmitter} `this` + */ +EventEmitter.prototype.emit = function emit(evt) { + var listeners = this._listeners[evt]; + if (listeners) { + var args = [], + i = 1; + for (; i < arguments.length;) + args.push(arguments[i++]); + for (i = 0; i < listeners.length;) + listeners[i].fn.apply(listeners[i++].ctx, args); + } + return this; +}; - FetchingOptionsProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.FetchingOptionsProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.maxRequestsPerQuery = reader.int32(); - break; - case 12: - message.forceMaxRequestsPerQuery = reader.bool(); - break; - case 13: - message.sortBatches = reader.bool(); - break; - case 2: - message.maxDrawable = reader.int32(); - break; - case 3: - message.maxImagery = reader.int32(); - break; - case 4: - message.maxTerrain = reader.int32(); - break; - case 5: - message.maxQuadtree = reader.int32(); - break; - case 6: - message.maxDioramaMetadata = reader.int32(); - break; - case 7: - message.maxDioramaData = reader.int32(); - break; - case 8: - message.maxConsumerFetchRatio = reader.float(); - break; - case 9: - message.maxProEcFetchRatio = reader.float(); - break; - case 10: - message.safeOverallQps = reader.float(); - break; - case 11: - message.safeImageryQps = reader.float(); - break; - case 14: - message.domainsForHttps = reader.string(); - break; - case 15: - message.hostsForHttp = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +},{}],4:[function(require,module,exports){ +"use strict"; +module.exports = inquire; - FetchingOptionsProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.maxRequestsPerQuery !== undefined) - if (!$util.isInteger(message.maxRequestsPerQuery)) - return "maxRequestsPerQuery: integer expected"; - if (message.forceMaxRequestsPerQuery !== undefined) - if (typeof message.forceMaxRequestsPerQuery !== "boolean") - return "forceMaxRequestsPerQuery: boolean expected"; - if (message.sortBatches !== undefined) - if (typeof message.sortBatches !== "boolean") - return "sortBatches: boolean expected"; - if (message.maxDrawable !== undefined) - if (!$util.isInteger(message.maxDrawable)) - return "maxDrawable: integer expected"; - if (message.maxImagery !== undefined) - if (!$util.isInteger(message.maxImagery)) - return "maxImagery: integer expected"; - if (message.maxTerrain !== undefined) - if (!$util.isInteger(message.maxTerrain)) - return "maxTerrain: integer expected"; - if (message.maxQuadtree !== undefined) - if (!$util.isInteger(message.maxQuadtree)) - return "maxQuadtree: integer expected"; - if (message.maxDioramaMetadata !== undefined) - if (!$util.isInteger(message.maxDioramaMetadata)) - return "maxDioramaMetadata: integer expected"; - if (message.maxDioramaData !== undefined) - if (!$util.isInteger(message.maxDioramaData)) - return "maxDioramaData: integer expected"; - if (message.maxConsumerFetchRatio !== undefined) - if (typeof message.maxConsumerFetchRatio !== "number") - return "maxConsumerFetchRatio: number expected"; - if (message.maxProEcFetchRatio !== undefined) - if (typeof message.maxProEcFetchRatio !== "number") - return "maxProEcFetchRatio: number expected"; - if (message.safeOverallQps !== undefined) - if (typeof message.safeOverallQps !== "number") - return "safeOverallQps: number expected"; - if (message.safeImageryQps !== undefined) - if (typeof message.safeImageryQps !== "number") - return "safeImageryQps: number expected"; - if (message.domainsForHttps !== undefined) - if (!$util.isString(message.domainsForHttps)) - return "domainsForHttps: string expected"; - if (message.hostsForHttp !== undefined) - if (!$util.isString(message.hostsForHttp)) - return "hostsForHttp: string expected"; - return null; - }; +/** + * Requires a module only if available. + * @memberof util + * @param {string} moduleName Module to require + * @returns {?Object} Required module if available and not empty, otherwise `null` + */ +function inquire(moduleName) { + try { + var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval + if (mod && (mod.length || Object.keys(mod).length)) + return mod; + } catch (e) {} // eslint-disable-line no-empty + return null; +} - FetchingOptionsProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.FetchingOptionsProto) - return object; - var message = new $root.keyhole.dbroot.FetchingOptionsProto(); - if (object.maxRequestsPerQuery !== undefined && object.maxRequestsPerQuery !== null) - message.maxRequestsPerQuery = object.maxRequestsPerQuery | 0; - if (object.forceMaxRequestsPerQuery !== undefined && object.forceMaxRequestsPerQuery !== null) - message.forceMaxRequestsPerQuery = Boolean(object.forceMaxRequestsPerQuery); - if (object.sortBatches !== undefined && object.sortBatches !== null) - message.sortBatches = Boolean(object.sortBatches); - if (object.maxDrawable !== undefined && object.maxDrawable !== null) - message.maxDrawable = object.maxDrawable | 0; - if (object.maxImagery !== undefined && object.maxImagery !== null) - message.maxImagery = object.maxImagery | 0; - if (object.maxTerrain !== undefined && object.maxTerrain !== null) - message.maxTerrain = object.maxTerrain | 0; - if (object.maxQuadtree !== undefined && object.maxQuadtree !== null) - message.maxQuadtree = object.maxQuadtree | 0; - if (object.maxDioramaMetadata !== undefined && object.maxDioramaMetadata !== null) - message.maxDioramaMetadata = object.maxDioramaMetadata | 0; - if (object.maxDioramaData !== undefined && object.maxDioramaData !== null) - message.maxDioramaData = object.maxDioramaData | 0; - if (object.maxConsumerFetchRatio !== undefined && object.maxConsumerFetchRatio !== null) - message.maxConsumerFetchRatio = Number(object.maxConsumerFetchRatio); - if (object.maxProEcFetchRatio !== undefined && object.maxProEcFetchRatio !== null) - message.maxProEcFetchRatio = Number(object.maxProEcFetchRatio); - if (object.safeOverallQps !== undefined && object.safeOverallQps !== null) - message.safeOverallQps = Number(object.safeOverallQps); - if (object.safeImageryQps !== undefined && object.safeImageryQps !== null) - message.safeImageryQps = Number(object.safeImageryQps); - if (object.domainsForHttps !== undefined && object.domainsForHttps !== null) - message.domainsForHttps = String(object.domainsForHttps); - if (object.hostsForHttp !== undefined && object.hostsForHttp !== null) - message.hostsForHttp = String(object.hostsForHttp); - return message; - }; +},{}],5:[function(require,module,exports){ +"use strict"; +module.exports = pool; - FetchingOptionsProto.from = FetchingOptionsProto.fromObject; +/** + * An allocator as used by {@link util.pool}. + * @typedef PoolAllocator + * @type {function} + * @param {number} size Buffer size + * @returns {Uint8Array} Buffer + */ - FetchingOptionsProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.maxRequestsPerQuery = 1; - object.forceMaxRequestsPerQuery = false; - object.sortBatches = false; - object.maxDrawable = 2; - object.maxImagery = 2; - object.maxTerrain = 5; - object.maxQuadtree = 5; - object.maxDioramaMetadata = 1; - object.maxDioramaData = 0; - object.maxConsumerFetchRatio = 1; - object.maxProEcFetchRatio = 0; - object.safeOverallQps = 0; - object.safeImageryQps = 0; - object.domainsForHttps = "google.com gstatic.com"; - object.hostsForHttp = ""; - } - if (message.maxRequestsPerQuery !== undefined && message.maxRequestsPerQuery !== null && message.hasOwnProperty("maxRequestsPerQuery")) - object.maxRequestsPerQuery = message.maxRequestsPerQuery; - if (message.forceMaxRequestsPerQuery !== undefined && message.forceMaxRequestsPerQuery !== null && message.hasOwnProperty("forceMaxRequestsPerQuery")) - object.forceMaxRequestsPerQuery = message.forceMaxRequestsPerQuery; - if (message.sortBatches !== undefined && message.sortBatches !== null && message.hasOwnProperty("sortBatches")) - object.sortBatches = message.sortBatches; - if (message.maxDrawable !== undefined && message.maxDrawable !== null && message.hasOwnProperty("maxDrawable")) - object.maxDrawable = message.maxDrawable; - if (message.maxImagery !== undefined && message.maxImagery !== null && message.hasOwnProperty("maxImagery")) - object.maxImagery = message.maxImagery; - if (message.maxTerrain !== undefined && message.maxTerrain !== null && message.hasOwnProperty("maxTerrain")) - object.maxTerrain = message.maxTerrain; - if (message.maxQuadtree !== undefined && message.maxQuadtree !== null && message.hasOwnProperty("maxQuadtree")) - object.maxQuadtree = message.maxQuadtree; - if (message.maxDioramaMetadata !== undefined && message.maxDioramaMetadata !== null && message.hasOwnProperty("maxDioramaMetadata")) - object.maxDioramaMetadata = message.maxDioramaMetadata; - if (message.maxDioramaData !== undefined && message.maxDioramaData !== null && message.hasOwnProperty("maxDioramaData")) - object.maxDioramaData = message.maxDioramaData; - if (message.maxConsumerFetchRatio !== undefined && message.maxConsumerFetchRatio !== null && message.hasOwnProperty("maxConsumerFetchRatio")) - object.maxConsumerFetchRatio = message.maxConsumerFetchRatio; - if (message.maxProEcFetchRatio !== undefined && message.maxProEcFetchRatio !== null && message.hasOwnProperty("maxProEcFetchRatio")) - object.maxProEcFetchRatio = message.maxProEcFetchRatio; - if (message.safeOverallQps !== undefined && message.safeOverallQps !== null && message.hasOwnProperty("safeOverallQps")) - object.safeOverallQps = message.safeOverallQps; - if (message.safeImageryQps !== undefined && message.safeImageryQps !== null && message.hasOwnProperty("safeImageryQps")) - object.safeImageryQps = message.safeImageryQps; - if (message.domainsForHttps !== undefined && message.domainsForHttps !== null && message.hasOwnProperty("domainsForHttps")) - object.domainsForHttps = message.domainsForHttps; - if (message.hostsForHttp !== undefined && message.hostsForHttp !== null && message.hasOwnProperty("hostsForHttp")) - object.hostsForHttp = message.hostsForHttp; - return object; - }; +/** + * A slicer as used by {@link util.pool}. + * @typedef PoolSlicer + * @type {function} + * @param {number} start Start offset + * @param {number} end End offset + * @returns {Uint8Array} Buffer slice + * @this {Uint8Array} + */ - FetchingOptionsProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * A general purpose buffer pool. + * @memberof util + * @function + * @param {PoolAllocator} alloc Allocator + * @param {PoolSlicer} slice Slicer + * @param {number} [size=8192] Slab size + * @returns {PoolAllocator} Pooled allocator + */ +function pool(alloc, slice, size) { + var SIZE = size || 8192; + var MAX = SIZE >>> 1; + var slab = null; + var offset = SIZE; + return function pool_alloc(size) { + if (size < 1 || size > MAX) + return alloc(size); + if (offset + size > SIZE) { + slab = alloc(SIZE); + offset = 0; + } + var buf = slice.call(slab, offset, offset += size); + if (offset & 7) // align to 32 bit + offset = (offset | 7) + 1; + return buf; + }; +} - FetchingOptionsProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +},{}],6:[function(require,module,exports){ +"use strict"; - return FetchingOptionsProto; - })(); +/** + * A minimal UTF8 implementation for number arrays. + * @memberof util + * @namespace + */ +var utf8 = exports; - dbroot.TimeMachineOptionsProto = (function() { +/** + * Calculates the UTF8 byte length of a string. + * @param {string} string String + * @returns {number} Byte length + */ +utf8.length = function utf8_length(string) { + var len = 0, + c = 0; + for (var i = 0; i < string.length; ++i) { + c = string.charCodeAt(i); + if (c < 128) + len += 1; + else if (c < 2048) + len += 2; + else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) { + ++i; + len += 4; + } else + len += 3; + } + return len; +}; - function TimeMachineOptionsProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Reads UTF8 bytes as a string. + * @param {Uint8Array} buffer Source buffer + * @param {number} start Source start + * @param {number} end Source end + * @returns {string} String read + */ +utf8.read = function utf8_read(buffer, start, end) { + var len = end - start; + if (len < 1) + return ""; + var parts = null, + chunk = [], + i = 0, // char offset + t; // temporary + while (start < end) { + t = buffer[start++]; + if (t < 128) + chunk[i++] = t; + else if (t > 191 && t < 224) + chunk[i++] = (t & 31) << 6 | buffer[start++] & 63; + else if (t > 239 && t < 365) { + t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000; + chunk[i++] = 0xD800 + (t >> 10); + chunk[i++] = 0xDC00 + (t & 1023); + } else + chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63; + if (i > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i = 0; + } + } + if (parts) { + if (i) + parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); + return parts.join(""); + } + return String.fromCharCode.apply(String, chunk.slice(0, i)); +}; - TimeMachineOptionsProto.prototype.serverUrl = ""; - TimeMachineOptionsProto.prototype.isTimemachine = false; - TimeMachineOptionsProto.prototype.dwellTimeMs = 500; - TimeMachineOptionsProto.prototype.discoverabilityAltitudeMeters = 15000; +/** + * Writes a string as UTF8 bytes. + * @param {string} string Source string + * @param {Uint8Array} buffer Destination buffer + * @param {number} offset Destination offset + * @returns {number} Bytes written + */ +utf8.write = function utf8_write(string, buffer, offset) { + var start = offset, + c1, // character 1 + c2; // character 2 + for (var i = 0; i < string.length; ++i) { + c1 = string.charCodeAt(i); + if (c1 < 128) { + buffer[offset++] = c1; + } else if (c1 < 2048) { + buffer[offset++] = c1 >> 6 | 192; + buffer[offset++] = c1 & 63 | 128; + } else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) { + c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF); + ++i; + buffer[offset++] = c1 >> 18 | 240; + buffer[offset++] = c1 >> 12 & 63 | 128; + buffer[offset++] = c1 >> 6 & 63 | 128; + buffer[offset++] = c1 & 63 | 128; + } else { + buffer[offset++] = c1 >> 12 | 224; + buffer[offset++] = c1 >> 6 & 63 | 128; + buffer[offset++] = c1 & 63 | 128; + } + } + return offset - start; +}; - TimeMachineOptionsProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.TimeMachineOptionsProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.serverUrl = reader.string(); - break; - case 2: - message.isTimemachine = reader.bool(); - break; - case 3: - message.dwellTimeMs = reader.int32(); - break; - case 4: - message.discoverabilityAltitudeMeters = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +},{}],7:[function(require,module,exports){ +"use strict"; +var protobuf = exports; - TimeMachineOptionsProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.serverUrl !== undefined) - if (!$util.isString(message.serverUrl)) - return "serverUrl: string expected"; - if (message.isTimemachine !== undefined) - if (typeof message.isTimemachine !== "boolean") - return "isTimemachine: boolean expected"; - if (message.dwellTimeMs !== undefined) - if (!$util.isInteger(message.dwellTimeMs)) - return "dwellTimeMs: integer expected"; - if (message.discoverabilityAltitudeMeters !== undefined) - if (!$util.isInteger(message.discoverabilityAltitudeMeters)) - return "discoverabilityAltitudeMeters: integer expected"; - return null; - }; +/** + * Build type, one of `"full"`, `"light"` or `"minimal"`. + * @name build + * @type {string} + * @const + */ +protobuf.build = "minimal"; - TimeMachineOptionsProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.TimeMachineOptionsProto) - return object; - var message = new $root.keyhole.dbroot.TimeMachineOptionsProto(); - if (object.serverUrl !== undefined && object.serverUrl !== null) - message.serverUrl = String(object.serverUrl); - if (object.isTimemachine !== undefined && object.isTimemachine !== null) - message.isTimemachine = Boolean(object.isTimemachine); - if (object.dwellTimeMs !== undefined && object.dwellTimeMs !== null) - message.dwellTimeMs = object.dwellTimeMs | 0; - if (object.discoverabilityAltitudeMeters !== undefined && object.discoverabilityAltitudeMeters !== null) - message.discoverabilityAltitudeMeters = object.discoverabilityAltitudeMeters | 0; - return message; - }; +/** + * Named roots. + * This is where pbjs stores generated structures (the option `-r, --root` specifies a name). + * Can also be used manually to make roots available accross modules. + * @name roots + * @type {Object.<string,Root>} + * @example + * // pbjs -r myroot -o compiled.js ... + * + * // in another module: + * require("./compiled.js"); + * + * // in any subsequent module: + * var root = protobuf.roots["myroot"]; + */ +protobuf.roots = {}; - TimeMachineOptionsProto.from = TimeMachineOptionsProto.fromObject; +// Serialization +protobuf.Writer = require(14); +protobuf.BufferWriter = require(15); +protobuf.Reader = require(8); +protobuf.BufferReader = require(9); - TimeMachineOptionsProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.serverUrl = ""; - object.isTimemachine = false; - object.dwellTimeMs = 500; - object.discoverabilityAltitudeMeters = 15000; - } - if (message.serverUrl !== undefined && message.serverUrl !== null && message.hasOwnProperty("serverUrl")) - object.serverUrl = message.serverUrl; - if (message.isTimemachine !== undefined && message.isTimemachine !== null && message.hasOwnProperty("isTimemachine")) - object.isTimemachine = message.isTimemachine; - if (message.dwellTimeMs !== undefined && message.dwellTimeMs !== null && message.hasOwnProperty("dwellTimeMs")) - object.dwellTimeMs = message.dwellTimeMs; - if (message.discoverabilityAltitudeMeters !== undefined && message.discoverabilityAltitudeMeters !== null && message.hasOwnProperty("discoverabilityAltitudeMeters")) - object.discoverabilityAltitudeMeters = message.discoverabilityAltitudeMeters; - return object; - }; +// Utility +protobuf.util = require(13); +protobuf.rpc = require(10); +protobuf.configure = configure; - TimeMachineOptionsProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/* istanbul ignore next */ +/** + * Reconfigures the library according to the environment. + * @returns {undefined} + */ +function configure() { + protobuf.Reader._configure(protobuf.BufferReader); + protobuf.util._configure(); +} - TimeMachineOptionsProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +// Configure serialization +protobuf.Writer._configure(protobuf.BufferWriter); +configure(); - return TimeMachineOptionsProto; - })(); +},{"10":10,"13":13,"14":14,"15":15,"8":8,"9":9}],8:[function(require,module,exports){ +"use strict"; +module.exports = Reader; - dbroot.AutopiaOptionsProto = (function() { +var util = require(13); - function AutopiaOptionsProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +var BufferReader; // cyclic - AutopiaOptionsProto.prototype.metadataServerUrl = "http://cbk0.google.com/cbk"; - AutopiaOptionsProto.prototype.depthmapServerUrl = "http://cbk0.google.com/cbk"; - AutopiaOptionsProto.prototype.coverageOverlayUrl = ""; - AutopiaOptionsProto.prototype.maxImageryQps = 0; - AutopiaOptionsProto.prototype.maxMetadataDepthmapQps = 0; +var LongBits = util.LongBits, + utf8 = util.utf8; - AutopiaOptionsProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.AutopiaOptionsProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.metadataServerUrl = reader.string(); - break; - case 2: - message.depthmapServerUrl = reader.string(); - break; - case 3: - message.coverageOverlayUrl = reader.string(); - break; - case 4: - message.maxImageryQps = reader.float(); - break; - case 5: - message.maxMetadataDepthmapQps = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +/* istanbul ignore next */ +function indexOutOfRange(reader, writeLength) { + return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len); +} - AutopiaOptionsProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.metadataServerUrl !== undefined) - if (!$util.isString(message.metadataServerUrl)) - return "metadataServerUrl: string expected"; - if (message.depthmapServerUrl !== undefined) - if (!$util.isString(message.depthmapServerUrl)) - return "depthmapServerUrl: string expected"; - if (message.coverageOverlayUrl !== undefined) - if (!$util.isString(message.coverageOverlayUrl)) - return "coverageOverlayUrl: string expected"; - if (message.maxImageryQps !== undefined) - if (typeof message.maxImageryQps !== "number") - return "maxImageryQps: number expected"; - if (message.maxMetadataDepthmapQps !== undefined) - if (typeof message.maxMetadataDepthmapQps !== "number") - return "maxMetadataDepthmapQps: number expected"; - return null; - }; +/** + * Constructs a new reader instance using the specified buffer. + * @classdesc Wire format reader using `Uint8Array` if available, otherwise `Array`. + * @constructor + * @param {Uint8Array} buffer Buffer to read from + */ +function Reader(buffer) { - AutopiaOptionsProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.AutopiaOptionsProto) - return object; - var message = new $root.keyhole.dbroot.AutopiaOptionsProto(); - if (object.metadataServerUrl !== undefined && object.metadataServerUrl !== null) - message.metadataServerUrl = String(object.metadataServerUrl); - if (object.depthmapServerUrl !== undefined && object.depthmapServerUrl !== null) - message.depthmapServerUrl = String(object.depthmapServerUrl); - if (object.coverageOverlayUrl !== undefined && object.coverageOverlayUrl !== null) - message.coverageOverlayUrl = String(object.coverageOverlayUrl); - if (object.maxImageryQps !== undefined && object.maxImageryQps !== null) - message.maxImageryQps = Number(object.maxImageryQps); - if (object.maxMetadataDepthmapQps !== undefined && object.maxMetadataDepthmapQps !== null) - message.maxMetadataDepthmapQps = Number(object.maxMetadataDepthmapQps); - return message; - }; + /** + * Read buffer. + * @type {Uint8Array} + */ + this.buf = buffer; - AutopiaOptionsProto.from = AutopiaOptionsProto.fromObject; + /** + * Read buffer position. + * @type {number} + */ + this.pos = 0; - AutopiaOptionsProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.metadataServerUrl = "http://cbk0.google.com/cbk"; - object.depthmapServerUrl = "http://cbk0.google.com/cbk"; - object.coverageOverlayUrl = ""; - object.maxImageryQps = 0; - object.maxMetadataDepthmapQps = 0; - } - if (message.metadataServerUrl !== undefined && message.metadataServerUrl !== null && message.hasOwnProperty("metadataServerUrl")) - object.metadataServerUrl = message.metadataServerUrl; - if (message.depthmapServerUrl !== undefined && message.depthmapServerUrl !== null && message.hasOwnProperty("depthmapServerUrl")) - object.depthmapServerUrl = message.depthmapServerUrl; - if (message.coverageOverlayUrl !== undefined && message.coverageOverlayUrl !== null && message.hasOwnProperty("coverageOverlayUrl")) - object.coverageOverlayUrl = message.coverageOverlayUrl; - if (message.maxImageryQps !== undefined && message.maxImageryQps !== null && message.hasOwnProperty("maxImageryQps")) - object.maxImageryQps = message.maxImageryQps; - if (message.maxMetadataDepthmapQps !== undefined && message.maxMetadataDepthmapQps !== null && message.hasOwnProperty("maxMetadataDepthmapQps")) - object.maxMetadataDepthmapQps = message.maxMetadataDepthmapQps; - return object; - }; + /** + * Read buffer length. + * @type {number} + */ + this.len = buffer.length; +} - AutopiaOptionsProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +var create_array = typeof Uint8Array !== "undefined" + ? function create_typed_array(buffer) { + if (buffer instanceof Uint8Array || Array.isArray(buffer)) + return new Reader(buffer); + throw Error("illegal buffer"); + } + /* istanbul ignore next */ + : function create_array(buffer) { + if (Array.isArray(buffer)) + return new Reader(buffer); + throw Error("illegal buffer"); + }; - AutopiaOptionsProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +/** + * Creates a new reader using the specified buffer. + * @function + * @param {Uint8Array|Buffer} buffer Buffer to read from + * @returns {Reader|BufferReader} A {@link BufferReader} if `buffer` is a Buffer, otherwise a {@link Reader} + * @throws {Error} If `buffer` is not a valid buffer + */ +Reader.create = util.Buffer + ? function create_buffer_setup(buffer) { + return (Reader.create = function create_buffer(buffer) { + return util.Buffer.isBuffer(buffer) + ? new BufferReader(buffer) + /* istanbul ignore next */ + : create_array(buffer); + })(buffer); + } + /* istanbul ignore next */ + : create_array; - return AutopiaOptionsProto; - })(); +Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice; - dbroot.CSIOptionsProto = (function() { +/** + * Reads a varint as an unsigned 32 bit value. + * @function + * @returns {number} Value read + */ +Reader.prototype.uint32 = (function read_uint32_setup() { + var value = 4294967295; // optimizer type-hint, tends to deopt otherwise (?!) + return function read_uint32() { + value = ( this.buf[this.pos] & 127 ) >>> 0; if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 127) << 7) >>> 0; if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 15) << 28) >>> 0; if (this.buf[this.pos++] < 128) return value; - function CSIOptionsProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + /* istanbul ignore next */ + if ((this.pos += 5) > this.len) { + this.pos = this.len; + throw indexOutOfRange(this, 10); + } + return value; + }; +})(); - CSIOptionsProto.prototype.samplingPercentage = 0; - CSIOptionsProto.prototype.experimentId = ""; +/** + * Reads a varint as a signed 32 bit value. + * @returns {number} Value read + */ +Reader.prototype.int32 = function read_int32() { + return this.uint32() | 0; +}; - CSIOptionsProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.CSIOptionsProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.samplingPercentage = reader.int32(); - break; - case 2: - message.experimentId = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +/** + * Reads a zig-zag encoded varint as a signed 32 bit value. + * @returns {number} Value read + */ +Reader.prototype.sint32 = function read_sint32() { + var value = this.uint32(); + return value >>> 1 ^ -(value & 1) | 0; +}; - CSIOptionsProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.samplingPercentage !== undefined) - if (!$util.isInteger(message.samplingPercentage)) - return "samplingPercentage: integer expected"; - if (message.experimentId !== undefined) - if (!$util.isString(message.experimentId)) - return "experimentId: string expected"; - return null; - }; +/* eslint-disable no-invalid-this */ - CSIOptionsProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.CSIOptionsProto) - return object; - var message = new $root.keyhole.dbroot.CSIOptionsProto(); - if (object.samplingPercentage !== undefined && object.samplingPercentage !== null) - message.samplingPercentage = object.samplingPercentage | 0; - if (object.experimentId !== undefined && object.experimentId !== null) - message.experimentId = String(object.experimentId); - return message; - }; +function readLongVarint() { + // tends to deopt with local vars for octet etc. + var bits = new LongBits(0, 0); + var i = 0; + if (this.len - this.pos > 4) { // fast route (lo) + for (; i < 4; ++i) { + // 1st..4th + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + // 5th + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0; + bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + i = 0; + } else { + for (; i < 3; ++i) { + /* istanbul ignore next */ + if (this.pos >= this.len) + throw indexOutOfRange(this); + // 1st..3th + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + // 4th + bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0; + return bits; + } + if (this.len - this.pos > 4) { // fast route (hi) + for (; i < 5; ++i) { + // 6th..10th + bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + } else { + for (; i < 5; ++i) { + /* istanbul ignore next */ + if (this.pos >= this.len) + throw indexOutOfRange(this); + // 6th..10th + bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + } + /* istanbul ignore next */ + throw Error("invalid varint encoding"); +} - CSIOptionsProto.from = CSIOptionsProto.fromObject; +/* eslint-enable no-invalid-this */ - CSIOptionsProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.samplingPercentage = 0; - object.experimentId = ""; - } - if (message.samplingPercentage !== undefined && message.samplingPercentage !== null && message.hasOwnProperty("samplingPercentage")) - object.samplingPercentage = message.samplingPercentage; - if (message.experimentId !== undefined && message.experimentId !== null && message.hasOwnProperty("experimentId")) - object.experimentId = message.experimentId; - return object; - }; +/** + * Reads a varint as a signed 64 bit value. + * @name Reader#int64 + * @function + * @returns {Long|number} Value read + */ - CSIOptionsProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * Reads a varint as an unsigned 64 bit value. + * @name Reader#uint64 + * @function + * @returns {Long|number} Value read + */ - CSIOptionsProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +/** + * Reads a zig-zag encoded varint as a signed 64 bit value. + * @name Reader#sint64 + * @function + * @returns {Long|number} Value read + */ - return CSIOptionsProto; - })(); +/** + * Reads a varint as a boolean. + * @returns {boolean} Value read + */ +Reader.prototype.bool = function read_bool() { + return this.uint32() !== 0; +}; - dbroot.SearchTabProto = (function() { +function readFixed32(buf, end) { + return (buf[end - 4] + | buf[end - 3] << 8 + | buf[end - 2] << 16 + | buf[end - 1] << 24) >>> 0; +} - function SearchTabProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Reads fixed 32 bits as an unsigned 32 bit integer. + * @returns {number} Value read + */ +Reader.prototype.fixed32 = function read_fixed32() { - SearchTabProto.prototype.isVisible = false; - SearchTabProto.prototype.tabLabel = null; - SearchTabProto.prototype.baseUrl = ""; - SearchTabProto.prototype.viewportPrefix = ""; - SearchTabProto.prototype.inputBox = $util.emptyArray; - SearchTabProto.prototype.requirement = null; + /* istanbul ignore next */ + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); - var $types = { - 1 : "keyhole.dbroot.StringIdOrValueProto", - 4 : "keyhole.dbroot.SearchTabProto.InputBoxInfo", - 5 : "keyhole.dbroot.RequirementProto" - }; - $lazyTypes.push($types); + return readFixed32(this.buf, this.pos += 4); +}; - SearchTabProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.SearchTabProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.isVisible = reader.bool(); - break; - case 2: - message.tabLabel = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.baseUrl = reader.string(); - break; - case 4: - message.viewportPrefix = reader.string(); - break; - case 5: - if (!(message.inputBox && message.inputBox.length)) - message.inputBox = []; - message.inputBox.push($types[4].decode(reader, reader.uint32())); - break; - case 6: - message.requirement = $types[5].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +/** + * Reads fixed 32 bits as a signed 32 bit integer. + * @returns {number} Value read + */ +Reader.prototype.sfixed32 = function read_sfixed32() { - SearchTabProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (typeof message.isVisible !== "boolean") - return "isVisible: boolean expected"; - if (message.tabLabel !== undefined && message.tabLabel !== null) { - var error = $types[1].verify(message.tabLabel); - if (error) - return "tabLabel." + error; - } - if (message.baseUrl !== undefined) - if (!$util.isString(message.baseUrl)) - return "baseUrl: string expected"; - if (message.viewportPrefix !== undefined) - if (!$util.isString(message.viewportPrefix)) - return "viewportPrefix: string expected"; - if (message.inputBox !== undefined) { - if (!Array.isArray(message.inputBox)) - return "inputBox: array expected"; - for (var i = 0; i < message.inputBox.length; ++i) { - var error = $types[4].verify(message.inputBox[i]); - if (error) - return "inputBox." + error; - } - } - if (message.requirement !== undefined && message.requirement !== null) { - var error = $types[5].verify(message.requirement); - if (error) - return "requirement." + error; - } - return null; - }; + /* istanbul ignore next */ + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); - SearchTabProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.SearchTabProto) - return object; - var message = new $root.keyhole.dbroot.SearchTabProto(); - if (object.isVisible !== undefined && object.isVisible !== null) - message.isVisible = Boolean(object.isVisible); - if (object.tabLabel !== undefined && object.tabLabel !== null) { - if (typeof object.tabLabel !== "object") - throw TypeError(".keyhole.dbroot.SearchTabProto.tabLabel: object expected"); - message.tabLabel = $types[1].fromObject(object.tabLabel); - } - if (object.baseUrl !== undefined && object.baseUrl !== null) - message.baseUrl = String(object.baseUrl); - if (object.viewportPrefix !== undefined && object.viewportPrefix !== null) - message.viewportPrefix = String(object.viewportPrefix); - if (object.inputBox) { - if (!Array.isArray(object.inputBox)) - throw TypeError(".keyhole.dbroot.SearchTabProto.inputBox: array expected"); - message.inputBox = []; - for (var i = 0; i < object.inputBox.length; ++i) { - if (typeof object.inputBox[i] !== "object") - throw TypeError(".keyhole.dbroot.SearchTabProto.inputBox: object expected"); - message.inputBox[i] = $types[4].fromObject(object.inputBox[i]); - } - } - if (object.requirement !== undefined && object.requirement !== null) { - if (typeof object.requirement !== "object") - throw TypeError(".keyhole.dbroot.SearchTabProto.requirement: object expected"); - message.requirement = $types[5].fromObject(object.requirement); - } - return message; - }; + return readFixed32(this.buf, this.pos += 4) | 0; +}; - SearchTabProto.from = SearchTabProto.fromObject; +/* eslint-disable no-invalid-this */ - SearchTabProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.inputBox = []; - if (options.defaults) { - object.isVisible = false; - object.tabLabel = null; - object.baseUrl = ""; - object.viewportPrefix = ""; - object.requirement = null; - } - if (message.isVisible !== undefined && message.isVisible !== null && message.hasOwnProperty("isVisible")) - object.isVisible = message.isVisible; - if (message.tabLabel !== undefined && message.tabLabel !== null && message.hasOwnProperty("tabLabel")) - object.tabLabel = $types[1].toObject(message.tabLabel, options); - if (message.baseUrl !== undefined && message.baseUrl !== null && message.hasOwnProperty("baseUrl")) - object.baseUrl = message.baseUrl; - if (message.viewportPrefix !== undefined && message.viewportPrefix !== null && message.hasOwnProperty("viewportPrefix")) - object.viewportPrefix = message.viewportPrefix; - if (message.inputBox !== undefined && message.inputBox !== null && message.hasOwnProperty("inputBox")) { - object.inputBox = []; - for (var j = 0; j < message.inputBox.length; ++j) - object.inputBox[j] = $types[4].toObject(message.inputBox[j], options); - } - if (message.requirement !== undefined && message.requirement !== null && message.hasOwnProperty("requirement")) - object.requirement = $types[5].toObject(message.requirement, options); - return object; - }; +function readFixed64(/* this: Reader */) { - SearchTabProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + /* istanbul ignore next */ + if (this.pos + 8 > this.len) + throw indexOutOfRange(this, 8); - SearchTabProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + return new LongBits(readFixed32(this.buf, this.pos += 4), readFixed32(this.buf, this.pos += 4)); +} - SearchTabProto.InputBoxInfo = (function() { +/* eslint-enable no-invalid-this */ - function InputBoxInfo(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Reads fixed 64 bits. + * @name Reader#fixed64 + * @function + * @returns {Long|number} Value read + */ - InputBoxInfo.prototype.label = null; - InputBoxInfo.prototype.queryVerb = ""; - InputBoxInfo.prototype.queryPrepend = ""; +/** + * Reads zig-zag encoded fixed 64 bits. + * @name Reader#sfixed64 + * @function + * @returns {Long|number} Value read + */ - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); +var readFloat = typeof Float32Array !== "undefined" + ? (function() { + var f32 = new Float32Array(1), + f8b = new Uint8Array(f32.buffer); + f32[0] = -0; + return f8b[3] // already le? + ? function readFloat_f32(buf, pos) { + f8b[0] = buf[pos ]; + f8b[1] = buf[pos + 1]; + f8b[2] = buf[pos + 2]; + f8b[3] = buf[pos + 3]; + return f32[0]; + } + /* istanbul ignore next */ + : function readFloat_f32_le(buf, pos) { + f8b[0] = buf[pos + 3]; + f8b[1] = buf[pos + 2]; + f8b[2] = buf[pos + 1]; + f8b[3] = buf[pos ]; + return f32[0]; + }; + })() + /* istanbul ignore next */ + : function readFloat_ieee754(buf, pos) { + var uint = readFixed32(buf, pos + 4), + sign = (uint >> 31) * 2 + 1, + exponent = uint >>> 23 & 255, + mantissa = uint & 8388607; + return exponent === 255 + ? mantissa + ? NaN + : sign * Infinity + : exponent === 0 // denormal + ? sign * 1.401298464324817e-45 * mantissa + : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608); + }; - InputBoxInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.SearchTabProto.InputBoxInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.label = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.queryVerb = reader.string(); - break; - case 3: - message.queryPrepend = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +/** + * Reads a float (32 bit) as a number. + * @function + * @returns {number} Value read + */ +Reader.prototype.float = function read_float() { - InputBoxInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var error = $types[0].verify(message.label); - if (error) - return "label." + error; - if (!$util.isString(message.queryVerb)) - return "queryVerb: string expected"; - if (message.queryPrepend !== undefined) - if (!$util.isString(message.queryPrepend)) - return "queryPrepend: string expected"; - return null; - }; + /* istanbul ignore next */ + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); - InputBoxInfo.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.SearchTabProto.InputBoxInfo) - return object; - var message = new $root.keyhole.dbroot.SearchTabProto.InputBoxInfo(); - if (object.label !== undefined && object.label !== null) { - if (typeof object.label !== "object") - throw TypeError(".keyhole.dbroot.SearchTabProto.InputBoxInfo.label: object expected"); - message.label = $types[0].fromObject(object.label); - } - if (object.queryVerb !== undefined && object.queryVerb !== null) - message.queryVerb = String(object.queryVerb); - if (object.queryPrepend !== undefined && object.queryPrepend !== null) - message.queryPrepend = String(object.queryPrepend); - return message; - }; + var value = readFloat(this.buf, this.pos); + this.pos += 4; + return value; +}; - InputBoxInfo.from = InputBoxInfo.fromObject; +var readDouble = typeof Float64Array !== "undefined" + ? (function() { + var f64 = new Float64Array(1), + f8b = new Uint8Array(f64.buffer); + f64[0] = -0; + return f8b[7] // already le? + ? function readDouble_f64(buf, pos) { + f8b[0] = buf[pos ]; + f8b[1] = buf[pos + 1]; + f8b[2] = buf[pos + 2]; + f8b[3] = buf[pos + 3]; + f8b[4] = buf[pos + 4]; + f8b[5] = buf[pos + 5]; + f8b[6] = buf[pos + 6]; + f8b[7] = buf[pos + 7]; + return f64[0]; + } + /* istanbul ignore next */ + : function readDouble_f64_le(buf, pos) { + f8b[0] = buf[pos + 7]; + f8b[1] = buf[pos + 6]; + f8b[2] = buf[pos + 5]; + f8b[3] = buf[pos + 4]; + f8b[4] = buf[pos + 3]; + f8b[5] = buf[pos + 2]; + f8b[6] = buf[pos + 1]; + f8b[7] = buf[pos ]; + return f64[0]; + }; + })() + /* istanbul ignore next */ + : function readDouble_ieee754(buf, pos) { + var lo = readFixed32(buf, pos + 4), + hi = readFixed32(buf, pos + 8); + var sign = (hi >> 31) * 2 + 1, + exponent = hi >>> 20 & 2047, + mantissa = 4294967296 * (hi & 1048575) + lo; + return exponent === 2047 + ? mantissa + ? NaN + : sign * Infinity + : exponent === 0 // denormal + ? sign * 5e-324 * mantissa + : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496); + }; - InputBoxInfo.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.label = null; - object.queryVerb = ""; - object.queryPrepend = ""; - } - if (message.label !== undefined && message.label !== null && message.hasOwnProperty("label")) - object.label = $types[0].toObject(message.label, options); - if (message.queryVerb !== undefined && message.queryVerb !== null && message.hasOwnProperty("queryVerb")) - object.queryVerb = message.queryVerb; - if (message.queryPrepend !== undefined && message.queryPrepend !== null && message.hasOwnProperty("queryPrepend")) - object.queryPrepend = message.queryPrepend; - return object; - }; +/** + * Reads a double (64 bit float) as a number. + * @function + * @returns {number} Value read + */ +Reader.prototype.double = function read_double() { - InputBoxInfo.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + /* istanbul ignore next */ + if (this.pos + 8 > this.len) + throw indexOutOfRange(this, 4); - InputBoxInfo.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + var value = readDouble(this.buf, this.pos); + this.pos += 8; + return value; +}; - return InputBoxInfo; - })(); +/** + * Reads a sequence of bytes preceeded by its length as a varint. + * @returns {Uint8Array} Value read + */ +Reader.prototype.bytes = function read_bytes() { + var length = this.uint32(), + start = this.pos, + end = this.pos + length; - return SearchTabProto; - })(); + /* istanbul ignore next */ + if (end > this.len) + throw indexOutOfRange(this, length); - dbroot.CobrandProto = (function() { + this.pos += length; + return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1 + ? new this.buf.constructor(0) + : this._slice.call(this.buf, start, end); +}; - function CobrandProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Reads a string preceeded by its byte length as a varint. + * @returns {string} Value read + */ +Reader.prototype.string = function read_string() { + var bytes = this.bytes(); + return utf8.read(bytes, 0, bytes.length); +}; - CobrandProto.prototype.logoUrl = ""; - CobrandProto.prototype.xCoord = null; - CobrandProto.prototype.yCoord = null; - CobrandProto.prototype.tiePoint = 6; - CobrandProto.prototype.screenSize = 0; +/** + * Skips the specified number of bytes if specified, otherwise skips a varint. + * @param {number} [length] Length if known, otherwise a varint is assumed + * @returns {Reader} `this` + */ +Reader.prototype.skip = function skip(length) { + if (typeof length === "number") { + /* istanbul ignore next */ + if (this.pos + length > this.len) + throw indexOutOfRange(this, length); + this.pos += length; + } else { + /* istanbul ignore next */ + do { + if (this.pos >= this.len) + throw indexOutOfRange(this); + } while (this.buf[this.pos++] & 128); + } + return this; +}; - var $types = { - 1 : "keyhole.dbroot.CobrandProto.Coord", - 2 : "keyhole.dbroot.CobrandProto.Coord", - 3 : "keyhole.dbroot.CobrandProto.TiePoint" - }; - $lazyTypes.push($types); +/** + * Skips the next element of the specified wire type. + * @param {number} wireType Wire type received + * @returns {Reader} `this` + */ +Reader.prototype.skipType = function(wireType) { + switch (wireType) { + case 0: + this.skip(); + break; + case 1: + this.skip(8); + break; + case 2: + this.skip(this.uint32()); + break; + case 3: + do { // eslint-disable-line no-constant-condition + if ((wireType = this.uint32() & 7) === 4) + break; + this.skipType(wireType); + } while (true); + break; + case 5: + this.skip(4); + break; - CobrandProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.CobrandProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.logoUrl = reader.string(); - break; - case 2: - message.xCoord = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.yCoord = $types[2].decode(reader, reader.uint32()); - break; - case 4: - message.tiePoint = reader.uint32(); - break; - case 5: - message.screenSize = reader.double(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + /* istanbul ignore next */ + default: + throw Error("invalid wire type " + wireType + " at offset " + this.pos); + } + return this; +}; - CobrandProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isString(message.logoUrl)) - return "logoUrl: string expected"; - if (message.xCoord !== undefined && message.xCoord !== null) { - var error = $types[1].verify(message.xCoord); - if (error) - return "xCoord." + error; - } - if (message.yCoord !== undefined && message.yCoord !== null) { - var error = $types[2].verify(message.yCoord); - if (error) - return "yCoord." + error; - } - if (message.tiePoint !== undefined) - switch (message.tiePoint) { - default: - return "tiePoint: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - break; - } - if (message.screenSize !== undefined) - if (typeof message.screenSize !== "number") - return "screenSize: number expected"; - return null; - }; +Reader._configure = function(BufferReader_) { + BufferReader = BufferReader_; - CobrandProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.CobrandProto) - return object; - var message = new $root.keyhole.dbroot.CobrandProto(); - if (object.logoUrl !== undefined && object.logoUrl !== null) - message.logoUrl = String(object.logoUrl); - if (object.xCoord !== undefined && object.xCoord !== null) { - if (typeof object.xCoord !== "object") - throw TypeError(".keyhole.dbroot.CobrandProto.xCoord: object expected"); - message.xCoord = $types[1].fromObject(object.xCoord); - } - if (object.yCoord !== undefined && object.yCoord !== null) { - if (typeof object.yCoord !== "object") - throw TypeError(".keyhole.dbroot.CobrandProto.yCoord: object expected"); - message.yCoord = $types[2].fromObject(object.yCoord); - } - switch (object.tiePoint) { - case "TOP_LEFT": - case 0: - message.tiePoint = 0; - break; - case "TOP_CENTER": - case 1: - message.tiePoint = 1; - break; - case "TOP_RIGHT": - case 2: - message.tiePoint = 2; - break; - case "MID_LEFT": - case 3: - message.tiePoint = 3; - break; - case "MID_CENTER": - case 4: - message.tiePoint = 4; - break; - case "MID_RIGHT": - case 5: - message.tiePoint = 5; - break; - case "BOTTOM_LEFT": - case 6: - message.tiePoint = 6; - break; - case "BOTTOM_CENTER": - case 7: - message.tiePoint = 7; - break; - case "BOTTOM_RIGHT": - case 8: - message.tiePoint = 8; - break; - } - if (object.screenSize !== undefined && object.screenSize !== null) - message.screenSize = Number(object.screenSize); - return message; - }; + var fn = util.Long ? "toLong" : /* istanbul ignore next */ "toNumber"; + util.merge(Reader.prototype, { - CobrandProto.from = CobrandProto.fromObject; + int64: function read_int64() { + return readLongVarint.call(this)[fn](false); + }, - CobrandProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.logoUrl = ""; - object.xCoord = null; - object.yCoord = null; - object.tiePoint = options.enums === String ? "BOTTOM_LEFT" : 6; - object.screenSize = 0; - } - if (message.logoUrl !== undefined && message.logoUrl !== null && message.hasOwnProperty("logoUrl")) - object.logoUrl = message.logoUrl; - if (message.xCoord !== undefined && message.xCoord !== null && message.hasOwnProperty("xCoord")) - object.xCoord = $types[1].toObject(message.xCoord, options); - if (message.yCoord !== undefined && message.yCoord !== null && message.hasOwnProperty("yCoord")) - object.yCoord = $types[2].toObject(message.yCoord, options); - if (message.tiePoint !== undefined && message.tiePoint !== null && message.hasOwnProperty("tiePoint")) - object.tiePoint = options.enums === String ? $types[3][message.tiePoint] : message.tiePoint; - if (message.screenSize !== undefined && message.screenSize !== null && message.hasOwnProperty("screenSize")) - object.screenSize = message.screenSize; - return object; - }; + uint64: function read_uint64() { + return readLongVarint.call(this)[fn](true); + }, - CobrandProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + sint64: function read_sint64() { + return readLongVarint.call(this).zzDecode()[fn](false); + }, - CobrandProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + fixed64: function read_fixed64() { + return readFixed64.call(this)[fn](true); + }, - CobrandProto.Coord = (function() { + sfixed64: function read_sfixed64() { + return readFixed64.call(this)[fn](false); + } - function Coord(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + }); +}; - Coord.prototype.value = 0; - Coord.prototype.isRelative = false; +},{"13":13}],9:[function(require,module,exports){ +"use strict"; +module.exports = BufferReader; - Coord.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.CobrandProto.Coord(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.value = reader.double(); - break; - case 2: - message.isRelative = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +// extends Reader +var Reader = require(8); +(BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader; - Coord.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (typeof message.value !== "number") - return "value: number expected"; - if (message.isRelative !== undefined) - if (typeof message.isRelative !== "boolean") - return "isRelative: boolean expected"; - return null; - }; +var util = require(13); - Coord.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.CobrandProto.Coord) - return object; - var message = new $root.keyhole.dbroot.CobrandProto.Coord(); - if (object.value !== undefined && object.value !== null) - message.value = Number(object.value); - if (object.isRelative !== undefined && object.isRelative !== null) - message.isRelative = Boolean(object.isRelative); - return message; - }; +/** + * Constructs a new buffer reader instance. + * @classdesc Wire format reader using node buffers. + * @extends Reader + * @constructor + * @param {Buffer} buffer Buffer to read from + */ +function BufferReader(buffer) { + Reader.call(this, buffer); - Coord.from = Coord.fromObject; + /** + * Read buffer. + * @name BufferReader#buf + * @type {Buffer} + */ +} - Coord.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.value = 0; - object.isRelative = false; - } - if (message.value !== undefined && message.value !== null && message.hasOwnProperty("value")) - object.value = message.value; - if (message.isRelative !== undefined && message.isRelative !== null && message.hasOwnProperty("isRelative")) - object.isRelative = message.isRelative; - return object; - }; +/* istanbul ignore else */ +if (util.Buffer) + BufferReader.prototype._slice = util.Buffer.prototype.slice; - Coord.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * @override + */ +BufferReader.prototype.string = function read_string_buffer() { + var len = this.uint32(); // modifies pos + return this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)); +}; - Coord.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +/** + * Reads a sequence of bytes preceeded by its length as a varint. + * @name BufferReader#bytes + * @function + * @returns {Buffer} Value read + */ - return Coord; - })(); +},{"13":13,"8":8}],10:[function(require,module,exports){ +"use strict"; - CobrandProto.TiePoint = (function() { - var valuesById = {}, values = Object.create(valuesById); - values["TOP_LEFT"] = 0; - values["TOP_CENTER"] = 1; - values["TOP_RIGHT"] = 2; - values["MID_LEFT"] = 3; - values["MID_CENTER"] = 4; - values["MID_RIGHT"] = 5; - values["BOTTOM_LEFT"] = 6; - values["BOTTOM_CENTER"] = 7; - values["BOTTOM_RIGHT"] = 8; - return values; - })(); +/** + * Streaming RPC helpers. + * @namespace + */ +var rpc = exports; - return CobrandProto; - })(); +/** + * RPC implementation passed to {@link Service#create} performing a service request on network level, i.e. by utilizing http requests or websockets. + * @typedef RPCImpl + * @type {function} + * @param {Method|rpc.ServiceMethod} method Reflected or static method being called + * @param {Uint8Array} requestData Request data + * @param {RPCImplCallback} callback Callback function + * @returns {undefined} + * @example + * function rpcImpl(method, requestData, callback) { + * if (protobuf.util.lcFirst(method.name) !== "myMethod") // compatible with static code + * throw Error("no such method"); + * asynchronouslyObtainAResponse(requestData, function(err, responseData) { + * callback(err, responseData); + * }); + * } + */ - dbroot.DatabaseDescriptionProto = (function() { +/** + * Node-style callback as used by {@link RPCImpl}. + * @typedef RPCImplCallback + * @type {function} + * @param {?Error} error Error, if any, otherwise `null` + * @param {?Uint8Array} [response] Response data or `null` to signal end of stream, if there hasn't been an error + * @returns {undefined} + */ - function DatabaseDescriptionProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +rpc.Service = require(11); - DatabaseDescriptionProto.prototype.databaseName = null; - DatabaseDescriptionProto.prototype.databaseUrl = ""; +},{"11":11}],11:[function(require,module,exports){ +"use strict"; +module.exports = Service; - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); +var util = require(13); - DatabaseDescriptionProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.DatabaseDescriptionProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.databaseName = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.databaseUrl = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +// Extends EventEmitter +(Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service; - DatabaseDescriptionProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.databaseName !== undefined && message.databaseName !== null) { - var error = $types[0].verify(message.databaseName); - if (error) - return "databaseName." + error; - } - if (!$util.isString(message.databaseUrl)) - return "databaseUrl: string expected"; - return null; - }; +/** + * A service method callback as used by {@link rpc.ServiceMethod|ServiceMethod}. + * + * Differs from {@link RPCImplCallback} in that it is an actual callback of a service method which may not return `response = null`. + * @typedef rpc.ServiceMethodCallback + * @type {function} + * @param {?Error} error Error, if any + * @param {?Message} [response] Response message + * @returns {undefined} + */ - DatabaseDescriptionProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.DatabaseDescriptionProto) - return object; - var message = new $root.keyhole.dbroot.DatabaseDescriptionProto(); - if (object.databaseName !== undefined && object.databaseName !== null) { - if (typeof object.databaseName !== "object") - throw TypeError(".keyhole.dbroot.DatabaseDescriptionProto.databaseName: object expected"); - message.databaseName = $types[0].fromObject(object.databaseName); - } - if (object.databaseUrl !== undefined && object.databaseUrl !== null) - message.databaseUrl = String(object.databaseUrl); - return message; - }; +/** + * A service method part of a {@link rpc.ServiceMethodMixin|ServiceMethodMixin} and thus {@link rpc.Service} as created by {@link Service.create}. + * @typedef rpc.ServiceMethod + * @type {function} + * @param {Message|Object.<string,*>} request Request message or plain object + * @param {rpc.ServiceMethodCallback} [callback] Node-style callback called with the error, if any, and the response message + * @returns {Promise<Message>} Promise if `callback` has been omitted, otherwise `undefined` + */ - DatabaseDescriptionProto.from = DatabaseDescriptionProto.fromObject; +/** + * A service method mixin. + * + * When using TypeScript, mixed in service methods are only supported directly with a type definition of a static module (used with reflection). Otherwise, explicit casting is required. + * @typedef rpc.ServiceMethodMixin + * @type {Object.<string,rpc.ServiceMethod>} + * @example + * // Explicit casting with TypeScript + * (myRpcService["myMethod"] as protobuf.rpc.ServiceMethod)(...) + */ - DatabaseDescriptionProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.databaseName = null; - object.databaseUrl = ""; - } - if (message.databaseName !== undefined && message.databaseName !== null && message.hasOwnProperty("databaseName")) - object.databaseName = $types[0].toObject(message.databaseName, options); - if (message.databaseUrl !== undefined && message.databaseUrl !== null && message.hasOwnProperty("databaseUrl")) - object.databaseUrl = message.databaseUrl; - return object; - }; +/** + * Constructs a new RPC service instance. + * @classdesc An RPC service as returned by {@link Service#create}. + * @exports rpc.Service + * @extends util.EventEmitter + * @augments rpc.ServiceMethodMixin + * @constructor + * @param {RPCImpl} rpcImpl RPC implementation + * @param {boolean} [requestDelimited=false] Whether requests are length-delimited + * @param {boolean} [responseDelimited=false] Whether responses are length-delimited + */ +function Service(rpcImpl, requestDelimited, responseDelimited) { - DatabaseDescriptionProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + if (typeof rpcImpl !== "function") + throw TypeError("rpcImpl must be a function"); - DatabaseDescriptionProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + util.EventEmitter.call(this); - return DatabaseDescriptionProto; - })(); + /** + * RPC implementation. Becomes `null` once the service is ended. + * @type {?RPCImpl} + */ + this.rpcImpl = rpcImpl; - dbroot.ConfigScriptProto = (function() { + /** + * Whether requests are length-delimited. + * @type {boolean} + */ + this.requestDelimited = Boolean(requestDelimited); - function ConfigScriptProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; + /** + * Whether responses are length-delimited. + * @type {boolean} + */ + this.responseDelimited = Boolean(responseDelimited); +} + +/** + * Calls a service method through {@link rpc.Service#rpcImpl|rpcImpl}. + * @param {Method|rpc.ServiceMethod} method Reflected or static method + * @param {function} requestCtor Request constructor + * @param {function} responseCtor Response constructor + * @param {Message|Object.<string,*>} request Request message or plain object + * @param {rpc.ServiceMethodCallback} callback Service callback + * @returns {undefined} + */ +Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) { + + if (!request) + throw TypeError("request must be specified"); + + var self = this; + if (!callback) + return util.asPromise(rpcCall, self, method, requestCtor, responseCtor, request); + + if (!self.rpcImpl) { + setTimeout(function() { callback(Error("already ended")); }, 0); + return undefined; + } + + try { + return self.rpcImpl( + method, + requestCtor[self.requestDelimited ? "encodeDelimited" : "encode"](request).finish(), + function rpcCallback(err, response) { + + if (err) { + self.emit("error", err, method); + return callback(err); } - ConfigScriptProto.prototype.scriptName = ""; - ConfigScriptProto.prototype.scriptData = ""; + if (response === null) { + self.end(/* endedByRPC */ true); + return undefined; + } - ConfigScriptProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.ConfigScriptProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.scriptName = reader.string(); - break; - case 2: - message.scriptData = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } + if (!(response instanceof responseCtor)) { + try { + response = responseCtor[self.responseDelimited ? "decodeDelimited" : "decode"](response); + } catch (err) { + self.emit("error", err, method); + return callback(err); } - return message; - }; + } - ConfigScriptProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isString(message.scriptName)) - return "scriptName: string expected"; - if (!$util.isString(message.scriptData)) - return "scriptData: string expected"; - return null; - }; + self.emit("data", response, method); + return callback(null, response); + } + ); + } catch (err) { + self.emit("error", err, method); + setTimeout(function() { callback(err); }, 0); + return undefined; + } +}; - ConfigScriptProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.ConfigScriptProto) - return object; - var message = new $root.keyhole.dbroot.ConfigScriptProto(); - if (object.scriptName !== undefined && object.scriptName !== null) - message.scriptName = String(object.scriptName); - if (object.scriptData !== undefined && object.scriptData !== null) - message.scriptData = String(object.scriptData); - return message; - }; +/** + * Ends this service and emits the `end` event. + * @param {boolean} [endedByRPC=false] Whether the service has been ended by the RPC implementation. + * @returns {rpc.Service} `this` + */ +Service.prototype.end = function end(endedByRPC) { + if (this.rpcImpl) { + if (!endedByRPC) // signal end to rpcImpl + this.rpcImpl(null, null, null); + this.rpcImpl = null; + this.emit("end").off(); + } + return this; +}; - ConfigScriptProto.from = ConfigScriptProto.fromObject; +},{"13":13}],12:[function(require,module,exports){ +"use strict"; +module.exports = LongBits; - ConfigScriptProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.scriptName = ""; - object.scriptData = ""; - } - if (message.scriptName !== undefined && message.scriptName !== null && message.hasOwnProperty("scriptName")) - object.scriptName = message.scriptName; - if (message.scriptData !== undefined && message.scriptData !== null && message.hasOwnProperty("scriptData")) - object.scriptData = message.scriptData; - return object; - }; +var util = require(13); - ConfigScriptProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * Any compatible Long instance. + * + * This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js. + * @typedef Long + * @type {Object} + * @property {number} low Low bits + * @property {number} high High bits + * @property {boolean} unsigned Whether unsigned or not + */ - ConfigScriptProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +/** + * Constructs new long bits. + * @classdesc Helper class for working with the low and high bits of a 64 bit value. + * @memberof util + * @constructor + * @param {number} lo Low 32 bits, unsigned + * @param {number} hi High 32 bits, unsigned + */ +function LongBits(lo, hi) { - return ConfigScriptProto; - })(); + // note that the casts below are theoretically unnecessary as of today, but older statically + // generated converter code might still call the ctor with signed 32bits. kept for compat. - dbroot.SwoopParamsProto = (function() { + /** + * Low bits. + * @type {number} + */ + this.lo = lo >>> 0; - function SwoopParamsProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + /** + * High bits. + * @type {number} + */ + this.hi = hi >>> 0; +} - SwoopParamsProto.prototype.startDistInMeters = 0; +/** + * Zero bits. + * @memberof util.LongBits + * @type {util.LongBits} + */ +var zero = LongBits.zero = new LongBits(0, 0); - SwoopParamsProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.SwoopParamsProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.startDistInMeters = reader.double(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +zero.toNumber = function() { return 0; }; +zero.zzEncode = zero.zzDecode = function() { return this; }; +zero.length = function() { return 1; }; - SwoopParamsProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.startDistInMeters !== undefined) - if (typeof message.startDistInMeters !== "number") - return "startDistInMeters: number expected"; - return null; - }; +/** + * Zero hash. + * @memberof util.LongBits + * @type {string} + */ +var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0"; - SwoopParamsProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.SwoopParamsProto) - return object; - var message = new $root.keyhole.dbroot.SwoopParamsProto(); - if (object.startDistInMeters !== undefined && object.startDistInMeters !== null) - message.startDistInMeters = Number(object.startDistInMeters); - return message; - }; +/** + * Constructs new long bits from the specified number. + * @param {number} value Value + * @returns {util.LongBits} Instance + */ +LongBits.fromNumber = function fromNumber(value) { + if (value === 0) + return zero; + var sign = value < 0; + if (sign) + value = -value; + var lo = value >>> 0, + hi = (value - lo) / 4294967296 >>> 0; + if (sign) { + hi = ~hi >>> 0; + lo = ~lo >>> 0; + if (++lo > 4294967295) { + lo = 0; + if (++hi > 4294967295) + hi = 0; + } + } + return new LongBits(lo, hi); +}; - SwoopParamsProto.from = SwoopParamsProto.fromObject; +/** + * Constructs new long bits from a number, long or string. + * @param {Long|number|string} value Value + * @returns {util.LongBits} Instance + */ +LongBits.from = function from(value) { + if (typeof value === "number") + return LongBits.fromNumber(value); + if (util.isString(value)) { + /* istanbul ignore else */ + if (util.Long) + value = util.Long.fromString(value); + else + return LongBits.fromNumber(parseInt(value, 10)); + } + return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero; +}; - SwoopParamsProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.startDistInMeters = 0; - if (message.startDistInMeters !== undefined && message.startDistInMeters !== null && message.hasOwnProperty("startDistInMeters")) - object.startDistInMeters = message.startDistInMeters; - return object; - }; +/** + * Converts this long bits to a possibly unsafe JavaScript number. + * @param {boolean} [unsigned=false] Whether unsigned or not + * @returns {number} Possibly unsafe number + */ +LongBits.prototype.toNumber = function toNumber(unsigned) { + if (!unsigned && this.hi >>> 31) { + var lo = ~this.lo + 1 >>> 0, + hi = ~this.hi >>> 0; + if (!lo) + hi = hi + 1 >>> 0; + return -(lo + hi * 4294967296); + } + return this.lo + this.hi * 4294967296; +}; - SwoopParamsProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * Converts this long bits to a long. + * @param {boolean} [unsigned=false] Whether unsigned or not + * @returns {Long} Long + */ +LongBits.prototype.toLong = function toLong(unsigned) { + return util.Long + ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) + /* istanbul ignore next */ + : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) }; +}; - SwoopParamsProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +var charCodeAt = String.prototype.charCodeAt; - return SwoopParamsProto; - })(); +/** + * Constructs new long bits from the specified 8 characters long hash. + * @param {string} hash Hash + * @returns {util.LongBits} Bits + */ +LongBits.fromHash = function fromHash(hash) { + if (hash === zeroHash) + return zero; + return new LongBits( + ( charCodeAt.call(hash, 0) + | charCodeAt.call(hash, 1) << 8 + | charCodeAt.call(hash, 2) << 16 + | charCodeAt.call(hash, 3) << 24) >>> 0 + , + ( charCodeAt.call(hash, 4) + | charCodeAt.call(hash, 5) << 8 + | charCodeAt.call(hash, 6) << 16 + | charCodeAt.call(hash, 7) << 24) >>> 0 + ); +}; - dbroot.PostingServerProto = (function() { +/** + * Converts this long bits to a 8 characters long hash. + * @returns {string} Hash + */ +LongBits.prototype.toHash = function toHash() { + return String.fromCharCode( + this.lo & 255, + this.lo >>> 8 & 255, + this.lo >>> 16 & 255, + this.lo >>> 24 , + this.hi & 255, + this.hi >>> 8 & 255, + this.hi >>> 16 & 255, + this.hi >>> 24 + ); +}; - function PostingServerProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Zig-zag encodes this long bits. + * @returns {util.LongBits} `this` + */ +LongBits.prototype.zzEncode = function zzEncode() { + var mask = this.hi >> 31; + this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0; + this.lo = ( this.lo << 1 ^ mask) >>> 0; + return this; +}; - PostingServerProto.prototype.name = null; - PostingServerProto.prototype.baseUrl = null; - PostingServerProto.prototype.postWizardPath = null; - PostingServerProto.prototype.fileSubmitPath = null; +/** + * Zig-zag decodes this long bits. + * @returns {util.LongBits} `this` + */ +LongBits.prototype.zzDecode = function zzDecode() { + var mask = -(this.lo & 1); + this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0; + this.hi = ( this.hi >>> 1 ^ mask) >>> 0; + return this; +}; - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 1 : "keyhole.dbroot.StringIdOrValueProto", - 2 : "keyhole.dbroot.StringIdOrValueProto", - 3 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); +/** + * Calculates the length of this longbits when encoded as a varint. + * @returns {number} Length + */ +LongBits.prototype.length = function length() { + var part0 = this.lo, + part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, + part2 = this.hi >>> 24; + return part2 === 0 + ? part1 === 0 + ? part0 < 16384 + ? part0 < 128 ? 1 : 2 + : part0 < 2097152 ? 3 : 4 + : part1 < 16384 + ? part1 < 128 ? 5 : 6 + : part1 < 2097152 ? 7 : 8 + : part2 < 128 ? 9 : 10; +}; - PostingServerProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.PostingServerProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.name = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.baseUrl = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.postWizardPath = $types[2].decode(reader, reader.uint32()); - break; - case 4: - message.fileSubmitPath = $types[3].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +},{"13":13}],13:[function(require,module,exports){ +"use strict"; +var util = exports; - PostingServerProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.name !== undefined && message.name !== null) { - var error = $types[0].verify(message.name); - if (error) - return "name." + error; - } - if (message.baseUrl !== undefined && message.baseUrl !== null) { - var error = $types[1].verify(message.baseUrl); - if (error) - return "baseUrl." + error; - } - if (message.postWizardPath !== undefined && message.postWizardPath !== null) { - var error = $types[2].verify(message.postWizardPath); - if (error) - return "postWizardPath." + error; - } - if (message.fileSubmitPath !== undefined && message.fileSubmitPath !== null) { - var error = $types[3].verify(message.fileSubmitPath); - if (error) - return "fileSubmitPath." + error; - } - return null; - }; +// used to return a Promise where callback is omitted +util.asPromise = require(1); - PostingServerProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.PostingServerProto) - return object; - var message = new $root.keyhole.dbroot.PostingServerProto(); - if (object.name !== undefined && object.name !== null) { - if (typeof object.name !== "object") - throw TypeError(".keyhole.dbroot.PostingServerProto.name: object expected"); - message.name = $types[0].fromObject(object.name); - } - if (object.baseUrl !== undefined && object.baseUrl !== null) { - if (typeof object.baseUrl !== "object") - throw TypeError(".keyhole.dbroot.PostingServerProto.baseUrl: object expected"); - message.baseUrl = $types[1].fromObject(object.baseUrl); - } - if (object.postWizardPath !== undefined && object.postWizardPath !== null) { - if (typeof object.postWizardPath !== "object") - throw TypeError(".keyhole.dbroot.PostingServerProto.postWizardPath: object expected"); - message.postWizardPath = $types[2].fromObject(object.postWizardPath); - } - if (object.fileSubmitPath !== undefined && object.fileSubmitPath !== null) { - if (typeof object.fileSubmitPath !== "object") - throw TypeError(".keyhole.dbroot.PostingServerProto.fileSubmitPath: object expected"); - message.fileSubmitPath = $types[3].fromObject(object.fileSubmitPath); - } - return message; - }; +// converts to / from base64 encoded strings +util.base64 = require(2); - PostingServerProto.from = PostingServerProto.fromObject; +// base class of rpc.Service +util.EventEmitter = require(3); - PostingServerProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.name = null; - object.baseUrl = null; - object.postWizardPath = null; - object.fileSubmitPath = null; - } - if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) - object.name = $types[0].toObject(message.name, options); - if (message.baseUrl !== undefined && message.baseUrl !== null && message.hasOwnProperty("baseUrl")) - object.baseUrl = $types[1].toObject(message.baseUrl, options); - if (message.postWizardPath !== undefined && message.postWizardPath !== null && message.hasOwnProperty("postWizardPath")) - object.postWizardPath = $types[2].toObject(message.postWizardPath, options); - if (message.fileSubmitPath !== undefined && message.fileSubmitPath !== null && message.hasOwnProperty("fileSubmitPath")) - object.fileSubmitPath = $types[3].toObject(message.fileSubmitPath, options); - return object; - }; +// requires modules optionally and hides the call from bundlers +util.inquire = require(4); - PostingServerProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +// converts to / from utf8 encoded strings +util.utf8 = require(6); - PostingServerProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +// provides a node-like buffer pool in the browser +util.pool = require(5); - return PostingServerProto; - })(); +// utility to work with the low and high bits of a 64 bit value +util.LongBits = require(12); - dbroot.PlanetaryDatabaseProto = (function() { +/** + * An immuable empty array. + * @memberof util + * @type {Array.<*>} + */ +util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes - function PlanetaryDatabaseProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * An immutable empty object. + * @type {Object} + */ +util.emptyObject = Object.freeze ? Object.freeze({}) : /* istanbul ignore next */ {}; // used on prototypes - PlanetaryDatabaseProto.prototype.url = null; - PlanetaryDatabaseProto.prototype.name = null; +/** + * Whether running within node or not. + * @memberof util + * @type {boolean} + */ +util.isNode = Boolean(global.process && global.process.versions && global.process.versions.node); - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 1 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); +/** + * Tests if the specified value is an integer. + * @function + * @param {*} value Value to test + * @returns {boolean} `true` if the value is an integer + */ +util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) { + return typeof value === "number" && isFinite(value) && Math.floor(value) === value; +}; - PlanetaryDatabaseProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.PlanetaryDatabaseProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.url = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.name = $types[1].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +/** + * Tests if the specified value is a string. + * @param {*} value Value to test + * @returns {boolean} `true` if the value is a string + */ +util.isString = function isString(value) { + return typeof value === "string" || value instanceof String; +}; - PlanetaryDatabaseProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var error = $types[0].verify(message.url); - if (error) - return "url." + error; - var error = $types[1].verify(message.name); - if (error) - return "name." + error; - return null; - }; +/** + * Tests if the specified value is a non-null object. + * @param {*} value Value to test + * @returns {boolean} `true` if the value is a non-null object + */ +util.isObject = function isObject(value) { + return value && typeof value === "object"; +}; - PlanetaryDatabaseProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.PlanetaryDatabaseProto) - return object; - var message = new $root.keyhole.dbroot.PlanetaryDatabaseProto(); - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.url: object expected"); - message.url = $types[0].fromObject(object.url); - } - if (object.name !== undefined && object.name !== null) { - if (typeof object.name !== "object") - throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.name: object expected"); - message.name = $types[1].fromObject(object.name); - } - return message; - }; +/** + * Node's Buffer class if available. + * @type {?function(new: Buffer)} + */ +util.Buffer = (function() { + try { + var Buffer = util.inquire("buffer").Buffer; + // refuse to use non-node buffers if not explicitly assigned (perf reasons): + return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null; + } catch (e) { + /* istanbul ignore next */ + return null; + } +})(); - PlanetaryDatabaseProto.from = PlanetaryDatabaseProto.fromObject; +/** + * Internal alias of or polyfull for Buffer.from. + * @type {?function} + * @param {string|number[]} value Value + * @param {string} [encoding] Encoding if value is a string + * @returns {Uint8Array} + * @private + */ +util._Buffer_from = null; - PlanetaryDatabaseProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.url = null; - object.name = null; - } - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[0].toObject(message.url, options); - if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) - object.name = $types[1].toObject(message.name, options); - return object; - }; +/** + * Internal alias of or polyfill for Buffer.allocUnsafe. + * @type {?function} + * @param {number} size Buffer size + * @returns {Uint8Array} + * @private + */ +util._Buffer_allocUnsafe = null; - PlanetaryDatabaseProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; +/** + * Creates a new buffer of whatever type supported by the environment. + * @param {number|number[]} [sizeOrArray=0] Buffer size or number array + * @returns {Uint8Array|Buffer} Buffer + */ +util.newBuffer = function newBuffer(sizeOrArray) { + /* istanbul ignore next */ + return typeof sizeOrArray === "number" + ? util.Buffer + ? util._Buffer_allocUnsafe(sizeOrArray) + : new util.Array(sizeOrArray) + : util.Buffer + ? util._Buffer_from(sizeOrArray) + : typeof Uint8Array === "undefined" + ? sizeOrArray + : new Uint8Array(sizeOrArray); +}; - PlanetaryDatabaseProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; +/** + * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`. + * @type {?function(new: Uint8Array, *)} + */ +util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array; - return PlanetaryDatabaseProto; - })(); +/** + * Long.js's Long class if available. + * @type {?function(new: Long)} + */ +util.Long = /* istanbul ignore next */ global.dcodeIO && /* istanbul ignore next */ global.dcodeIO.Long || util.inquire("long"); - dbroot.LogServerProto = (function() { +/** + * Regular expression used to verify 2 bit (`bool`) map keys. + * @type {RegExp} + */ +util.key2Re = /^true|false|0|1$/; - function LogServerProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } +/** + * Regular expression used to verify 32 bit (`int32` etc.) map keys. + * @type {RegExp} + */ +util.key32Re = /^-?(?:0|[1-9][0-9]*)$/; - LogServerProto.prototype.url = null; - LogServerProto.prototype.enable = false; - LogServerProto.prototype.throttlingFactor = 1; +/** + * Regular expression used to verify 64 bit (`int64` etc.) map keys. + * @type {RegExp} + */ +util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/; - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); +/** + * Converts a number or long to an 8 characters long hash string. + * @param {Long|number} value Value to convert + * @returns {string} Hash + */ +util.longToHash = function longToHash(value) { + return value + ? util.LongBits.from(value).toHash() + : util.LongBits.zeroHash; +}; - LogServerProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.LogServerProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.url = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.enable = reader.bool(); - break; - case 3: - message.throttlingFactor = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; +/** + * Converts an 8 characters long hash string to a long or number. + * @param {string} hash Hash + * @param {boolean} [unsigned=false] Whether unsigned or not + * @returns {Long|number} Original value + */ +util.longFromHash = function longFromHash(hash, unsigned) { + var bits = util.LongBits.fromHash(hash); + if (util.Long) + return util.Long.fromBits(bits.lo, bits.hi, unsigned); + return bits.toNumber(Boolean(unsigned)); +}; - LogServerProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.url !== undefined && message.url !== null) { - var error = $types[0].verify(message.url); - if (error) - return "url." + error; - } - if (message.enable !== undefined) - if (typeof message.enable !== "boolean") - return "enable: boolean expected"; - if (message.throttlingFactor !== undefined) - if (!$util.isInteger(message.throttlingFactor)) - return "throttlingFactor: integer expected"; - return null; - }; +/** + * Merges the properties of the source object into the destination object. + * @memberof util + * @param {Object.<string,*>} dst Destination object + * @param {Object.<string,*>} src Source object + * @param {boolean} [ifNotSet=false] Merges only if the key is not already set + * @returns {Object.<string,*>} Destination object + */ +function merge(dst, src, ifNotSet) { // used by converters + for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) + if (dst[keys[i]] === undefined || !ifNotSet) + dst[keys[i]] = src[keys[i]]; + return dst; +} - LogServerProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.LogServerProto) - return object; - var message = new $root.keyhole.dbroot.LogServerProto(); - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.LogServerProto.url: object expected"); - message.url = $types[0].fromObject(object.url); - } - if (object.enable !== undefined && object.enable !== null) - message.enable = Boolean(object.enable); - if (object.throttlingFactor !== undefined && object.throttlingFactor !== null) - message.throttlingFactor = object.throttlingFactor | 0; - return message; - }; +util.merge = merge; - LogServerProto.from = LogServerProto.fromObject; +/** + * Converts the first character of a string to lower case. + * @param {string} str String to convert + * @returns {string} Converted string + */ +util.lcFirst = function lcFirst(str) { + return str.charAt(0).toLowerCase() + str.substring(1); +}; - LogServerProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.url = null; - object.enable = false; - object.throttlingFactor = 1; - } - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[0].toObject(message.url, options); - if (message.enable !== undefined && message.enable !== null && message.hasOwnProperty("enable")) - object.enable = message.enable; - if (message.throttlingFactor !== undefined && message.throttlingFactor !== null && message.hasOwnProperty("throttlingFactor")) - object.throttlingFactor = message.throttlingFactor; - return object; - }; +/** + * Creates a custom error constructor. + * @memberof util + * @param {string} name Error name + * @returns {function} Custom error constructor + */ +function newError(name) { - LogServerProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + function CustomError(message, properties) { - LogServerProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + if (!(this instanceof CustomError)) + return new CustomError(message, properties); - return LogServerProto; - })(); + // Error.call(this, message); + // ^ just returns a new error instance because the ctor can be called as a function - dbroot.EndSnippetProto = (function() { + Object.defineProperty(this, "message", { get: function() { return message; } }); - function EndSnippetProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + /* istanbul ignore next */ + if (Error.captureStackTrace) // node + Error.captureStackTrace(this, CustomError); + else + Object.defineProperty(this, "stack", { value: (new Error()).stack || "" }); - EndSnippetProto.prototype.model = null; - EndSnippetProto.prototype.authServerUrl = null; - EndSnippetProto.prototype.disableAuthentication = false; - EndSnippetProto.prototype.mfeDomains = $util.emptyArray; - EndSnippetProto.prototype.mfeLangParam = "hl=$5Bhl5D"; - EndSnippetProto.prototype.adsUrlPatterns = ""; - EndSnippetProto.prototype.reverseGeocoderUrl = null; - EndSnippetProto.prototype.reverseGeocoderProtocolVersion = 3; - EndSnippetProto.prototype.skyDatabaseIsAvailable = true; - EndSnippetProto.prototype.skyDatabaseUrl = null; - EndSnippetProto.prototype.defaultWebPageIntlUrl = null; - EndSnippetProto.prototype.numStartUpTips = 17; - EndSnippetProto.prototype.startUpTipsUrl = null; - EndSnippetProto.prototype.numProStartUpTips = 0; - EndSnippetProto.prototype.proStartUpTipsUrl = null; - EndSnippetProto.prototype.startupTipsIntlUrl = null; - EndSnippetProto.prototype.userGuideIntlUrl = null; - EndSnippetProto.prototype.supportCenterIntlUrl = null; - EndSnippetProto.prototype.businessListingIntlUrl = null; - EndSnippetProto.prototype.supportAnswerIntlUrl = null; - EndSnippetProto.prototype.supportTopicIntlUrl = null; - EndSnippetProto.prototype.supportRequestIntlUrl = null; - EndSnippetProto.prototype.earthIntlUrl = null; - EndSnippetProto.prototype.addContentUrl = null; - EndSnippetProto.prototype.sketchupNotInstalledUrl = null; - EndSnippetProto.prototype.sketchupErrorUrl = null; - EndSnippetProto.prototype.freeLicenseUrl = null; - EndSnippetProto.prototype.proLicenseUrl = null; - EndSnippetProto.prototype.tutorialUrl = null; - EndSnippetProto.prototype.keyboardShortcutsUrl = null; - EndSnippetProto.prototype.releaseNotesUrl = null; - EndSnippetProto.prototype.hideUserData = false; - EndSnippetProto.prototype.useGeLogo = true; - EndSnippetProto.prototype.dioramaDescriptionUrlBase = null; - EndSnippetProto.prototype.dioramaDefaultColor = 4291281607; - EndSnippetProto.prototype.dioramaBlacklistUrl = null; - EndSnippetProto.prototype.clientOptions = null; - EndSnippetProto.prototype.fetchingOptions = null; - EndSnippetProto.prototype.timeMachineOptions = null; - EndSnippetProto.prototype.csiOptions = null; - EndSnippetProto.prototype.searchTab = $util.emptyArray; - EndSnippetProto.prototype.cobrandInfo = $util.emptyArray; - EndSnippetProto.prototype.validDatabase = $util.emptyArray; - EndSnippetProto.prototype.configScript = $util.emptyArray; - EndSnippetProto.prototype.deauthServerUrl = null; - EndSnippetProto.prototype.swoopParameters = null; - EndSnippetProto.prototype.bbsServerInfo = null; - EndSnippetProto.prototype.dataErrorServerInfo = null; - EndSnippetProto.prototype.planetaryDatabase = $util.emptyArray; - EndSnippetProto.prototype.logServer = null; - EndSnippetProto.prototype.autopiaOptions = null; - EndSnippetProto.prototype.searchConfig = null; - EndSnippetProto.prototype.searchInfo = null; - EndSnippetProto.prototype.elevationServiceBaseUrl = "http://maps.google.com/maps/api/elevation/"; - EndSnippetProto.prototype.elevationProfileQueryDelay = 500; - EndSnippetProto.prototype.proUpgradeUrl = null; - EndSnippetProto.prototype.earthCommunityUrl = null; - EndSnippetProto.prototype.googleMapsUrl = null; - EndSnippetProto.prototype.sharingUrl = null; - EndSnippetProto.prototype.privacyPolicyUrl = null; - EndSnippetProto.prototype.doGplusUserCheck = false; - EndSnippetProto.prototype.rocktreeDataProto = null; - EndSnippetProto.prototype.filmstripConfig = $util.emptyArray; - EndSnippetProto.prototype.showSigninButton = false; - EndSnippetProto.prototype.proMeasureUpsellUrl = null; - EndSnippetProto.prototype.proPrintUpsellUrl = null; - EndSnippetProto.prototype.starDataProto = null; - EndSnippetProto.prototype.feedbackUrl = null; - EndSnippetProto.prototype.oauth2LoginUrl = null; + if (properties) + merge(this, properties); + } - var $types = { - 0 : "keyhole.dbroot.PlanetModelProto", - 1 : "keyhole.dbroot.StringIdOrValueProto", - 3 : "keyhole.dbroot.MfeDomainFeaturesProto", - 6 : "keyhole.dbroot.StringIdOrValueProto", - 9 : "keyhole.dbroot.StringIdOrValueProto", - 10 : "keyhole.dbroot.StringIdOrValueProto", - 12 : "keyhole.dbroot.StringIdOrValueProto", - 14 : "keyhole.dbroot.StringIdOrValueProto", - 15 : "keyhole.dbroot.StringIdOrValueProto", - 16 : "keyhole.dbroot.StringIdOrValueProto", - 17 : "keyhole.dbroot.StringIdOrValueProto", - 18 : "keyhole.dbroot.StringIdOrValueProto", - 19 : "keyhole.dbroot.StringIdOrValueProto", - 20 : "keyhole.dbroot.StringIdOrValueProto", - 21 : "keyhole.dbroot.StringIdOrValueProto", - 22 : "keyhole.dbroot.StringIdOrValueProto", - 23 : "keyhole.dbroot.StringIdOrValueProto", - 24 : "keyhole.dbroot.StringIdOrValueProto", - 25 : "keyhole.dbroot.StringIdOrValueProto", - 26 : "keyhole.dbroot.StringIdOrValueProto", - 27 : "keyhole.dbroot.StringIdOrValueProto", - 28 : "keyhole.dbroot.StringIdOrValueProto", - 29 : "keyhole.dbroot.StringIdOrValueProto", - 30 : "keyhole.dbroot.StringIdOrValueProto", - 33 : "keyhole.dbroot.StringIdOrValueProto", - 35 : "keyhole.dbroot.StringIdOrValueProto", - 36 : "keyhole.dbroot.ClientOptionsProto", - 37 : "keyhole.dbroot.FetchingOptionsProto", - 38 : "keyhole.dbroot.TimeMachineOptionsProto", - 39 : "keyhole.dbroot.CSIOptionsProto", - 40 : "keyhole.dbroot.SearchTabProto", - 41 : "keyhole.dbroot.CobrandProto", - 42 : "keyhole.dbroot.DatabaseDescriptionProto", - 43 : "keyhole.dbroot.ConfigScriptProto", - 44 : "keyhole.dbroot.StringIdOrValueProto", - 45 : "keyhole.dbroot.SwoopParamsProto", - 46 : "keyhole.dbroot.PostingServerProto", - 47 : "keyhole.dbroot.PostingServerProto", - 48 : "keyhole.dbroot.PlanetaryDatabaseProto", - 49 : "keyhole.dbroot.LogServerProto", - 50 : "keyhole.dbroot.AutopiaOptionsProto", - 51 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto", - 52 : "keyhole.dbroot.EndSnippetProto.SearchInfoProto", - 55 : "keyhole.dbroot.StringIdOrValueProto", - 56 : "keyhole.dbroot.StringIdOrValueProto", - 57 : "keyhole.dbroot.StringIdOrValueProto", - 58 : "keyhole.dbroot.StringIdOrValueProto", - 59 : "keyhole.dbroot.StringIdOrValueProto", - 61 : "keyhole.dbroot.EndSnippetProto.RockTreeDataProto", - 62 : "keyhole.dbroot.EndSnippetProto.FilmstripConfigProto", - 64 : "keyhole.dbroot.StringIdOrValueProto", - 65 : "keyhole.dbroot.StringIdOrValueProto", - 66 : "keyhole.dbroot.EndSnippetProto.StarDataProto", - 67 : "keyhole.dbroot.StringIdOrValueProto", - 68 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); + (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError; - EndSnippetProto.decode = function decode(reader, length) { + Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } }); + + CustomError.prototype.toString = function toString() { + return this.name + ": " + this.message; + }; + + return CustomError; +} + +util.newError = newError; + +/** + * Constructs a new protocol error. + * @classdesc Error subclass indicating a protocol specifc error. + * @memberof util + * @extends Error + * @constructor + * @param {string} message Error message + * @param {Object.<string,*>=} properties Additional properties + * @example + * try { + * MyMessage.decode(someBuffer); // throws if required fields are missing + * } catch (e) { + * if (e instanceof ProtocolError && e.instance) + * console.log("decoded so far: " + JSON.stringify(e.instance)); + * } + */ +util.ProtocolError = newError("ProtocolError"); + +/** + * So far decoded message instance. + * @name util.ProtocolError#instance + * @type {Message} + */ + +/** + * Builds a getter for a oneof's present field name. + * @param {string[]} fieldNames Field names + * @returns {function():string|undefined} Unbound getter + */ +util.oneOfGetter = function getOneOf(fieldNames) { + var fieldMap = {}; + for (var i = 0; i < fieldNames.length; ++i) + fieldMap[fieldNames[i]] = 1; + + /** + * @returns {string|undefined} Set field name, if any + * @this Object + * @ignore + */ + return function() { // eslint-disable-line consistent-return + for (var keys = Object.keys(this), i = keys.length - 1; i > -1; --i) + if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null) + return keys[i]; + }; +}; + +/** + * Builds a setter for a oneof's present field name. + * @param {string[]} fieldNames Field names + * @returns {function(?string):undefined} Unbound setter + */ +util.oneOfSetter = function setOneOf(fieldNames) { + + /** + * @param {string} name Field name + * @returns {undefined} + * @this Object + * @ignore + */ + return function(name) { + for (var i = 0; i < fieldNames.length; ++i) + if (fieldNames[i] !== name) + delete this[fieldNames[i]]; + }; +}; + +/** + * Lazily resolves fully qualified type names against the specified root. + * @param {Root} root Root instanceof + * @param {Object.<number,string|ReflectionObject>} lazyTypes Type names + * @returns {undefined} + */ +util.lazyResolve = function lazyResolve(root, lazyTypes) { + for (var i = 0; i < lazyTypes.length; ++i) { + for (var keys = Object.keys(lazyTypes[i]), j = 0; j < keys.length; ++j) { + var path = lazyTypes[i][keys[j]].split("."), + ptr = root; + while (path.length) + ptr = ptr[path.shift()]; + lazyTypes[i][keys[j]] = ptr; + } + } +}; + +/** + * Default conversion options used for {@link Message#toJSON} implementations. Longs, enums and bytes are converted to strings by default. + * @type {ConversionOptions} + */ +util.toJSONOptions = { + longs: String, + enums: String, + bytes: String +}; + +util._configure = function() { + var Buffer = util.Buffer; + /* istanbul ignore if */ + if (!Buffer) { + util._Buffer_from = util._Buffer_allocUnsafe = null; + return; + } + // because node 4.x buffers are incompatible & immutable + // see: https://github.com/dcodeIO/protobuf.js/pull/665 + util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from || + /* istanbul ignore next */ + function Buffer_from(value, encoding) { + return new Buffer(value, encoding); + }; + util._Buffer_allocUnsafe = Buffer.allocUnsafe || + /* istanbul ignore next */ + function Buffer_allocUnsafe(size) { + return new Buffer(size); + }; +}; + +},{"1":1,"12":12,"2":2,"3":3,"4":4,"5":5,"6":6}],14:[function(require,module,exports){ +"use strict"; +module.exports = Writer; + +var util = require(13); + +var BufferWriter; // cyclic + +var LongBits = util.LongBits, + base64 = util.base64, + utf8 = util.utf8; + +/** + * Constructs a new writer operation instance. + * @classdesc Scheduled writer operation. + * @constructor + * @param {function(*, Uint8Array, number)} fn Function to call + * @param {number} len Value byte length + * @param {*} val Value to write + * @ignore + */ +function Op(fn, len, val) { + + /** + * Function to call. + * @type {function(Uint8Array, number, *)} + */ + this.fn = fn; + + /** + * Value byte length. + * @type {number} + */ + this.len = len; + + /** + * Next operation. + * @type {Writer.Op|undefined} + */ + this.next = undefined; + + /** + * Value to write. + * @type {*} + */ + this.val = val; // type varies +} + +/* istanbul ignore next */ +function noop() {} // eslint-disable-line no-empty-function + +/** + * Constructs a new writer state instance. + * @classdesc Copied writer state. + * @memberof Writer + * @constructor + * @param {Writer} writer Writer to copy state from + * @private + * @ignore + */ +function State(writer) { + + /** + * Current head. + * @type {Writer.Op} + */ + this.head = writer.head; + + /** + * Current tail. + * @type {Writer.Op} + */ + this.tail = writer.tail; + + /** + * Current buffer length. + * @type {number} + */ + this.len = writer.len; + + /** + * Next state. + * @type {?State} + */ + this.next = writer.states; +} + +/** + * Constructs a new writer instance. + * @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`. + * @constructor + */ +function Writer() { + + /** + * Current length. + * @type {number} + */ + this.len = 0; + + /** + * Operations head. + * @type {Object} + */ + this.head = new Op(noop, 0, 0); + + /** + * Operations tail + * @type {Object} + */ + this.tail = this.head; + + /** + * Linked forked states. + * @type {?Object} + */ + this.states = null; + + // When a value is written, the writer calculates its byte length and puts it into a linked + // list of operations to perform when finish() is called. This both allows us to allocate + // buffers of the exact required size and reduces the amount of work we have to do compared + // to first calculating over objects and then encoding over objects. In our case, the encoding + // part is just a linked list walk calling operations with already prepared values. +} + +/** + * Creates a new writer. + * @function + * @returns {BufferWriter|Writer} A {@link BufferWriter} when Buffers are supported, otherwise a {@link Writer} + */ +Writer.create = util.Buffer + ? function create_buffer_setup() { + return (Writer.create = function create_buffer() { + return new BufferWriter(); + })(); + } + /* istanbul ignore next */ + : function create_array() { + return new Writer(); + }; + +/** + * Allocates a buffer of the specified size. + * @param {number} size Buffer size + * @returns {Uint8Array} Buffer + */ +Writer.alloc = function alloc(size) { + return new util.Array(size); +}; + +// Use Uint8Array buffer pool in the browser, just like node does with buffers +/* istanbul ignore else */ +if (util.Array !== Array) + Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray); + +/** + * Pushes a new operation to the queue. + * @param {function(Uint8Array, number, *)} fn Function to call + * @param {number} len Value byte length + * @param {number} val Value to write + * @returns {Writer} `this` + */ +Writer.prototype.push = function push(fn, len, val) { + this.tail = this.tail.next = new Op(fn, len, val); + this.len += len; + return this; +}; + +function writeByte(val, buf, pos) { + buf[pos] = val & 255; +} + +function writeVarint32(val, buf, pos) { + while (val > 127) { + buf[pos++] = val & 127 | 128; + val >>>= 7; + } + buf[pos] = val; +} + +/** + * Constructs a new varint writer operation instance. + * @classdesc Scheduled varint writer operation. + * @extends Op + * @constructor + * @param {number} len Value byte length + * @param {number} val Value to write + * @ignore + */ +function VarintOp(len, val) { + this.len = len; + this.next = undefined; + this.val = val; +} + +VarintOp.prototype = Object.create(Op.prototype); +VarintOp.prototype.fn = writeVarint32; + +/** + * Writes an unsigned 32 bit value as a varint. + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.uint32 = function write_uint32(value) { + // here, the call to this.push has been inlined and a varint specific Op subclass is used. + // uint32 is by far the most frequently used operation and benefits significantly from this. + this.len += (this.tail = this.tail.next = new VarintOp( + (value = value >>> 0) + < 128 ? 1 + : value < 16384 ? 2 + : value < 2097152 ? 3 + : value < 268435456 ? 4 + : 5, + value)).len; + return this; +}; + +/** + * Writes a signed 32 bit value as a varint. + * @function + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.int32 = function write_int32(value) { + return value < 0 + ? this.push(writeVarint64, 10, LongBits.fromNumber(value)) // 10 bytes per spec + : this.uint32(value); +}; + +/** + * Writes a 32 bit value as a varint, zig-zag encoded. + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.sint32 = function write_sint32(value) { + return this.uint32((value << 1 ^ value >> 31) >>> 0); +}; + +function writeVarint64(val, buf, pos) { + while (val.hi) { + buf[pos++] = val.lo & 127 | 128; + val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0; + val.hi >>>= 7; + } + while (val.lo > 127) { + buf[pos++] = val.lo & 127 | 128; + val.lo = val.lo >>> 7; + } + buf[pos++] = val.lo; +} + +/** + * Writes an unsigned 64 bit value as a varint. + * @param {Long|number|string} value Value to write + * @returns {Writer} `this` + * @throws {TypeError} If `value` is a string and no long library is present. + */ +Writer.prototype.uint64 = function write_uint64(value) { + var bits = LongBits.from(value); + return this.push(writeVarint64, bits.length(), bits); +}; + +/** + * Writes a signed 64 bit value as a varint. + * @function + * @param {Long|number|string} value Value to write + * @returns {Writer} `this` + * @throws {TypeError} If `value` is a string and no long library is present. + */ +Writer.prototype.int64 = Writer.prototype.uint64; + +/** + * Writes a signed 64 bit value as a varint, zig-zag encoded. + * @param {Long|number|string} value Value to write + * @returns {Writer} `this` + * @throws {TypeError} If `value` is a string and no long library is present. + */ +Writer.prototype.sint64 = function write_sint64(value) { + var bits = LongBits.from(value).zzEncode(); + return this.push(writeVarint64, bits.length(), bits); +}; + +/** + * Writes a boolish value as a varint. + * @param {boolean} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.bool = function write_bool(value) { + return this.push(writeByte, 1, value ? 1 : 0); +}; + +function writeFixed32(val, buf, pos) { + buf[pos++] = val & 255; + buf[pos++] = val >>> 8 & 255; + buf[pos++] = val >>> 16 & 255; + buf[pos ] = val >>> 24; +} + +/** + * Writes an unsigned 32 bit value as fixed 32 bits. + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.fixed32 = function write_fixed32(value) { + return this.push(writeFixed32, 4, value >>> 0); +}; + +/** + * Writes a signed 32 bit value as fixed 32 bits. + * @function + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.sfixed32 = Writer.prototype.fixed32; + +/** + * Writes an unsigned 64 bit value as fixed 64 bits. + * @param {Long|number|string} value Value to write + * @returns {Writer} `this` + * @throws {TypeError} If `value` is a string and no long library is present. + */ +Writer.prototype.fixed64 = function write_fixed64(value) { + var bits = LongBits.from(value); + return this.push(writeFixed32, 4, bits.lo).push(writeFixed32, 4, bits.hi); +}; + +/** + * Writes a signed 64 bit value as fixed 64 bits. + * @function + * @param {Long|number|string} value Value to write + * @returns {Writer} `this` + * @throws {TypeError} If `value` is a string and no long library is present. + */ +Writer.prototype.sfixed64 = Writer.prototype.fixed64; + +var writeFloat = typeof Float32Array !== "undefined" + ? (function() { + var f32 = new Float32Array(1), + f8b = new Uint8Array(f32.buffer); + f32[0] = -0; + return f8b[3] // already le? + ? function writeFloat_f32(val, buf, pos) { + f32[0] = val; + buf[pos++] = f8b[0]; + buf[pos++] = f8b[1]; + buf[pos++] = f8b[2]; + buf[pos ] = f8b[3]; + } + /* istanbul ignore next */ + : function writeFloat_f32_le(val, buf, pos) { + f32[0] = val; + buf[pos++] = f8b[3]; + buf[pos++] = f8b[2]; + buf[pos++] = f8b[1]; + buf[pos ] = f8b[0]; + }; + })() + /* istanbul ignore next */ + : function writeFloat_ieee754(value, buf, pos) { + var sign = value < 0 ? 1 : 0; + if (sign) + value = -value; + if (value === 0) + writeFixed32(1 / value > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos); + else if (isNaN(value)) + writeFixed32(2147483647, buf, pos); + else if (value > 3.4028234663852886e+38) // +-Infinity + writeFixed32((sign << 31 | 2139095040) >>> 0, buf, pos); + else if (value < 1.1754943508222875e-38) // denormal + writeFixed32((sign << 31 | Math.round(value / 1.401298464324817e-45)) >>> 0, buf, pos); + else { + var exponent = Math.floor(Math.log(value) / Math.LN2), + mantissa = Math.round(value * Math.pow(2, -exponent) * 8388608) & 8388607; + writeFixed32((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos); + } + }; + +/** + * Writes a float (32 bit). + * @function + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.float = function write_float(value) { + return this.push(writeFloat, 4, value); +}; + +var writeDouble = typeof Float64Array !== "undefined" + ? (function() { + var f64 = new Float64Array(1), + f8b = new Uint8Array(f64.buffer); + f64[0] = -0; + return f8b[7] // already le? + ? function writeDouble_f64(val, buf, pos) { + f64[0] = val; + buf[pos++] = f8b[0]; + buf[pos++] = f8b[1]; + buf[pos++] = f8b[2]; + buf[pos++] = f8b[3]; + buf[pos++] = f8b[4]; + buf[pos++] = f8b[5]; + buf[pos++] = f8b[6]; + buf[pos ] = f8b[7]; + } + /* istanbul ignore next */ + : function writeDouble_f64_le(val, buf, pos) { + f64[0] = val; + buf[pos++] = f8b[7]; + buf[pos++] = f8b[6]; + buf[pos++] = f8b[5]; + buf[pos++] = f8b[4]; + buf[pos++] = f8b[3]; + buf[pos++] = f8b[2]; + buf[pos++] = f8b[1]; + buf[pos ] = f8b[0]; + }; + })() + /* istanbul ignore next */ + : function writeDouble_ieee754(value, buf, pos) { + var sign = value < 0 ? 1 : 0; + if (sign) + value = -value; + if (value === 0) { + writeFixed32(0, buf, pos); + writeFixed32(1 / value > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos + 4); + } else if (isNaN(value)) { + writeFixed32(4294967295, buf, pos); + writeFixed32(2147483647, buf, pos + 4); + } else if (value > 1.7976931348623157e+308) { // +-Infinity + writeFixed32(0, buf, pos); + writeFixed32((sign << 31 | 2146435072) >>> 0, buf, pos + 4); + } else { + var mantissa; + if (value < 2.2250738585072014e-308) { // denormal + mantissa = value / 5e-324; + writeFixed32(mantissa >>> 0, buf, pos); + writeFixed32((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + 4); + } else { + var exponent = Math.floor(Math.log(value) / Math.LN2); + if (exponent === 1024) + exponent = 1023; + mantissa = value * Math.pow(2, -exponent); + writeFixed32(mantissa * 4503599627370496 >>> 0, buf, pos); + writeFixed32((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + 4); + } + } + }; + +/** + * Writes a double (64 bit float). + * @function + * @param {number} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.double = function write_double(value) { + return this.push(writeDouble, 8, value); +}; + +var writeBytes = util.Array.prototype.set + ? function writeBytes_set(val, buf, pos) { + buf.set(val, pos); // also works for plain array values + } + /* istanbul ignore next */ + : function writeBytes_for(val, buf, pos) { + for (var i = 0; i < val.length; ++i) + buf[pos + i] = val[i]; + }; + +/** + * Writes a sequence of bytes. + * @param {Uint8Array|string} value Buffer or base64 encoded string to write + * @returns {Writer} `this` + */ +Writer.prototype.bytes = function write_bytes(value) { + var len = value.length >>> 0; + if (!len) + return this.push(writeByte, 1, 0); + if (util.isString(value)) { + var buf = Writer.alloc(len = base64.length(value)); + base64.decode(value, buf, 0); + value = buf; + } + return this.uint32(len).push(writeBytes, len, value); +}; + +/** + * Writes a string. + * @param {string} value Value to write + * @returns {Writer} `this` + */ +Writer.prototype.string = function write_string(value) { + var len = utf8.length(value); + return len + ? this.uint32(len).push(utf8.write, len, value) + : this.push(writeByte, 1, 0); +}; + +/** + * Forks this writer's state by pushing it to a stack. + * Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state. + * @returns {Writer} `this` + */ +Writer.prototype.fork = function fork() { + this.states = new State(this); + this.head = this.tail = new Op(noop, 0, 0); + this.len = 0; + return this; +}; + +/** + * Resets this instance to the last state. + * @returns {Writer} `this` + */ +Writer.prototype.reset = function reset() { + if (this.states) { + this.head = this.states.head; + this.tail = this.states.tail; + this.len = this.states.len; + this.states = this.states.next; + } else { + this.head = this.tail = new Op(noop, 0, 0); + this.len = 0; + } + return this; +}; + +/** + * Resets to the last state and appends the fork state's current write length as a varint followed by its operations. + * @returns {Writer} `this` + */ +Writer.prototype.ldelim = function ldelim() { + var head = this.head, + tail = this.tail, + len = this.len; + this.reset().uint32(len); + if (len) { + this.tail.next = head.next; // skip noop + this.tail = tail; + this.len += len; + } + return this; +}; + +/** + * Finishes the write operation. + * @returns {Uint8Array} Finished buffer + */ +Writer.prototype.finish = function finish() { + var head = this.head.next, // skip noop + buf = this.constructor.alloc(this.len), + pos = 0; + while (head) { + head.fn(head.val, buf, pos); + pos += head.len; + head = head.next; + } + // this.head = this.tail = null; + return buf; +}; + +Writer._configure = function(BufferWriter_) { + BufferWriter = BufferWriter_; +}; + +},{"13":13}],15:[function(require,module,exports){ +"use strict"; +module.exports = BufferWriter; + +// extends Writer +var Writer = require(14); +(BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter; + +var util = require(13); + +var Buffer = util.Buffer; + +/** + * Constructs a new buffer writer instance. + * @classdesc Wire format writer using node buffers. + * @extends Writer + * @constructor + */ +function BufferWriter() { + Writer.call(this); +} + +/** + * Allocates a buffer of the specified size. + * @param {number} size Buffer size + * @returns {Buffer} Buffer + */ +BufferWriter.alloc = function alloc_buffer(size) { + return (BufferWriter.alloc = util._Buffer_allocUnsafe)(size); +}; + +var writeBytesBuffer = Buffer && Buffer.prototype instanceof Uint8Array && Buffer.prototype.set.name === "set" + ? function writeBytesBuffer_set(val, buf, pos) { + buf.set(val, pos); // faster than copy (requires node >= 4 where Buffers extend Uint8Array and set is properly inherited) + // also works for plain array values + } + /* istanbul ignore next */ + : function writeBytesBuffer_copy(val, buf, pos) { + if (val.copy) // Buffer values + val.copy(buf, pos, 0, val.length); + else for (var i = 0; i < val.length;) // plain array values + buf[pos++] = val[i++]; + }; + +/** + * @override + */ +BufferWriter.prototype.bytes = function write_bytes_buffer(value) { + if (util.isString(value)) + value = util._Buffer_from(value, "base64"); + var len = value.length >>> 0; + this.uint32(len); + if (len) + this.push(writeBytesBuffer, len, value); + return this; +}; + +function writeStringBuffer(val, buf, pos) { + if (val.length < 40) // plain js is faster for short strings (probably due to redundant assertions) + util.utf8.write(val, buf, pos); + else + buf.utf8Write(val, pos); +} + +/** + * @override + */ +BufferWriter.prototype.string = function write_string_buffer(value) { + var len = Buffer.byteLength(value); + this.uint32(len); + if (len) + this.push(writeStringBuffer, len, value); + return this; +}; + + +/** + * Finishes the write operation. + * @name BufferWriter#finish + * @function + * @returns {Buffer} Finished buffer + */ + +},{"13":13,"14":14}]},{},[7]) + +})(typeof window==="object"&&window||typeof self==="object"&&self||this); +//# sourceMappingURL=protobuf.js.map +; +define('ThirdParty/google-earth-dbroot-parser',[ + './protobuf-minimal' +], function( + $protobuf) { + /* jshint curly: false, sub: true, newcap: false, shadow: true, unused: false*/ + 'use strict'; + + // + // Creates a parser for a dbroot protocol buffer + // Below code is generated using protobufjs with the following command + // + // ./pbjs --no-encode --no-create --no-comments --no-delimited -w amd -t static dbroot_v2.proto + // + // .proto file can be found here: https://github.com/google/earthenterprise/blob/master/earth_enterprise/src/keyhole/proto/dbroot/dbroot_v2.proto + + var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util; + + var $lazyTypes = []; + + var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + + $root.keyhole = (function() { + + var keyhole = {}; + + keyhole.dbroot = (function() { + + var dbroot = {}; + + dbroot.StringEntryProto = (function() { + + function StringEntryProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + StringEntryProto.prototype.stringId = 0; + StringEntryProto.prototype.stringValue = ""; + + StringEntryProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto(); + message = new $root.keyhole.dbroot.StringEntryProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.model = $types[0].decode(reader, reader.uint32()); + message.stringId = reader.fixed32(); break; case 2: - message.authServerUrl = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.disableAuthentication = reader.bool(); - break; - case 4: - if (!(message.mfeDomains && message.mfeDomains.length)) - message.mfeDomains = []; - message.mfeDomains.push($types[3].decode(reader, reader.uint32())); - break; - case 5: - message.mfeLangParam = reader.string(); - break; - case 6: - message.adsUrlPatterns = reader.string(); - break; - case 7: - message.reverseGeocoderUrl = $types[6].decode(reader, reader.uint32()); - break; - case 8: - message.reverseGeocoderProtocolVersion = reader.int32(); - break; - case 9: - message.skyDatabaseIsAvailable = reader.bool(); - break; - case 10: - message.skyDatabaseUrl = $types[9].decode(reader, reader.uint32()); - break; - case 11: - message.defaultWebPageIntlUrl = $types[10].decode(reader, reader.uint32()); - break; - case 12: - message.numStartUpTips = reader.int32(); - break; - case 13: - message.startUpTipsUrl = $types[12].decode(reader, reader.uint32()); - break; - case 51: - message.numProStartUpTips = reader.int32(); - break; - case 52: - message.proStartUpTipsUrl = $types[14].decode(reader, reader.uint32()); - break; - case 64: - message.startupTipsIntlUrl = $types[15].decode(reader, reader.uint32()); - break; - case 14: - message.userGuideIntlUrl = $types[16].decode(reader, reader.uint32()); - break; - case 15: - message.supportCenterIntlUrl = $types[17].decode(reader, reader.uint32()); - break; - case 16: - message.businessListingIntlUrl = $types[18].decode(reader, reader.uint32()); - break; - case 17: - message.supportAnswerIntlUrl = $types[19].decode(reader, reader.uint32()); - break; - case 18: - message.supportTopicIntlUrl = $types[20].decode(reader, reader.uint32()); - break; - case 19: - message.supportRequestIntlUrl = $types[21].decode(reader, reader.uint32()); - break; - case 20: - message.earthIntlUrl = $types[22].decode(reader, reader.uint32()); - break; - case 21: - message.addContentUrl = $types[23].decode(reader, reader.uint32()); - break; - case 22: - message.sketchupNotInstalledUrl = $types[24].decode(reader, reader.uint32()); + message.stringValue = reader.string(); break; - case 23: - message.sketchupErrorUrl = $types[25].decode(reader, reader.uint32()); + default: + reader.skipType(tag & 7); break; - case 24: - message.freeLicenseUrl = $types[26].decode(reader, reader.uint32()); - break; - case 25: - message.proLicenseUrl = $types[27].decode(reader, reader.uint32()); - break; - case 48: - message.tutorialUrl = $types[28].decode(reader, reader.uint32()); - break; - case 49: - message.keyboardShortcutsUrl = $types[29].decode(reader, reader.uint32()); - break; - case 50: - message.releaseNotesUrl = $types[30].decode(reader, reader.uint32()); - break; - case 26: - message.hideUserData = reader.bool(); - break; - case 27: - message.useGeLogo = reader.bool(); - break; - case 28: - message.dioramaDescriptionUrlBase = $types[33].decode(reader, reader.uint32()); - break; - case 29: - message.dioramaDefaultColor = reader.uint32(); - break; - case 53: - message.dioramaBlacklistUrl = $types[35].decode(reader, reader.uint32()); + } + } + return message; + }; + + StringEntryProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isInteger(message.stringId)) + return "stringId: integer expected"; + if (!$util.isString(message.stringValue)) + return "stringValue: string expected"; + return null; + }; + + StringEntryProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.StringEntryProto) + return object; + var message = new $root.keyhole.dbroot.StringEntryProto(); + if (object.stringId !== undefined && object.stringId !== null) + message.stringId = object.stringId >>> 0; + if (object.stringValue !== undefined && object.stringValue !== null) + message.stringValue = String(object.stringValue); + return message; + }; + + StringEntryProto.from = StringEntryProto.fromObject; + + StringEntryProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.stringId = 0; + object.stringValue = ""; + } + if (message.stringId !== undefined && message.stringId !== null && message.hasOwnProperty("stringId")) + object.stringId = message.stringId; + if (message.stringValue !== undefined && message.stringValue !== null && message.hasOwnProperty("stringValue")) + object.stringValue = message.stringValue; + return object; + }; + + StringEntryProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + StringEntryProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StringEntryProto; + })(); + + dbroot.StringIdOrValueProto = (function() { + + function StringIdOrValueProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + StringIdOrValueProto.prototype.stringId = 0; + StringIdOrValueProto.prototype.value = ""; + + StringIdOrValueProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.StringIdOrValueProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.stringId = reader.fixed32(); break; - case 30: - message.clientOptions = $types[36].decode(reader, reader.uint32()); + case 2: + message.value = reader.string(); break; - case 31: - message.fetchingOptions = $types[37].decode(reader, reader.uint32()); + default: + reader.skipType(tag & 7); break; - case 32: - message.timeMachineOptions = $types[38].decode(reader, reader.uint32()); + } + } + return message; + }; + + StringIdOrValueProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.stringId !== undefined) + if (!$util.isInteger(message.stringId)) + return "stringId: integer expected"; + if (message.value !== undefined) + if (!$util.isString(message.value)) + return "value: string expected"; + return null; + }; + + StringIdOrValueProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.StringIdOrValueProto) + return object; + var message = new $root.keyhole.dbroot.StringIdOrValueProto(); + if (object.stringId !== undefined && object.stringId !== null) + message.stringId = object.stringId >>> 0; + if (object.value !== undefined && object.value !== null) + message.value = String(object.value); + return message; + }; + + StringIdOrValueProto.from = StringIdOrValueProto.fromObject; + + StringIdOrValueProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.stringId = 0; + object.value = ""; + } + if (message.stringId !== undefined && message.stringId !== null && message.hasOwnProperty("stringId")) + object.stringId = message.stringId; + if (message.value !== undefined && message.value !== null && message.hasOwnProperty("value")) + object.value = message.value; + return object; + }; + + StringIdOrValueProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + StringIdOrValueProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StringIdOrValueProto; + })(); + + dbroot.PlanetModelProto = (function() { + + function PlanetModelProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + PlanetModelProto.prototype.radius = 6378.137; + PlanetModelProto.prototype.flattening = 0.00335281066474748; + PlanetModelProto.prototype.elevationBias = 0; + PlanetModelProto.prototype.negativeAltitudeExponentBias = 0; + PlanetModelProto.prototype.compressedNegativeAltitudeThreshold = 0; + + PlanetModelProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.PlanetModelProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.radius = reader.double(); break; - case 33: - message.csiOptions = $types[39].decode(reader, reader.uint32()); + case 2: + message.flattening = reader.double(); break; - case 34: - if (!(message.searchTab && message.searchTab.length)) - message.searchTab = []; - message.searchTab.push($types[40].decode(reader, reader.uint32())); + case 4: + message.elevationBias = reader.double(); break; - case 35: - if (!(message.cobrandInfo && message.cobrandInfo.length)) - message.cobrandInfo = []; - message.cobrandInfo.push($types[41].decode(reader, reader.uint32())); + case 5: + message.negativeAltitudeExponentBias = reader.int32(); break; - case 36: - if (!(message.validDatabase && message.validDatabase.length)) - message.validDatabase = []; - message.validDatabase.push($types[42].decode(reader, reader.uint32())); + case 6: + message.compressedNegativeAltitudeThreshold = reader.double(); break; - case 37: - if (!(message.configScript && message.configScript.length)) - message.configScript = []; - message.configScript.push($types[43].decode(reader, reader.uint32())); + default: + reader.skipType(tag & 7); break; - case 38: - message.deauthServerUrl = $types[44].decode(reader, reader.uint32()); + } + } + return message; + }; + + PlanetModelProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.radius !== undefined) + if (typeof message.radius !== "number") + return "radius: number expected"; + if (message.flattening !== undefined) + if (typeof message.flattening !== "number") + return "flattening: number expected"; + if (message.elevationBias !== undefined) + if (typeof message.elevationBias !== "number") + return "elevationBias: number expected"; + if (message.negativeAltitudeExponentBias !== undefined) + if (!$util.isInteger(message.negativeAltitudeExponentBias)) + return "negativeAltitudeExponentBias: integer expected"; + if (message.compressedNegativeAltitudeThreshold !== undefined) + if (typeof message.compressedNegativeAltitudeThreshold !== "number") + return "compressedNegativeAltitudeThreshold: number expected"; + return null; + }; + + PlanetModelProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.PlanetModelProto) + return object; + var message = new $root.keyhole.dbroot.PlanetModelProto(); + if (object.radius !== undefined && object.radius !== null) + message.radius = Number(object.radius); + if (object.flattening !== undefined && object.flattening !== null) + message.flattening = Number(object.flattening); + if (object.elevationBias !== undefined && object.elevationBias !== null) + message.elevationBias = Number(object.elevationBias); + if (object.negativeAltitudeExponentBias !== undefined && object.negativeAltitudeExponentBias !== null) + message.negativeAltitudeExponentBias = object.negativeAltitudeExponentBias | 0; + if (object.compressedNegativeAltitudeThreshold !== undefined && object.compressedNegativeAltitudeThreshold !== null) + message.compressedNegativeAltitudeThreshold = Number(object.compressedNegativeAltitudeThreshold); + return message; + }; + + PlanetModelProto.from = PlanetModelProto.fromObject; + + PlanetModelProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.radius = 6378.137; + object.flattening = 0.00335281066474748; + object.elevationBias = 0; + object.negativeAltitudeExponentBias = 0; + object.compressedNegativeAltitudeThreshold = 0; + } + if (message.radius !== undefined && message.radius !== null && message.hasOwnProperty("radius")) + object.radius = message.radius; + if (message.flattening !== undefined && message.flattening !== null && message.hasOwnProperty("flattening")) + object.flattening = message.flattening; + if (message.elevationBias !== undefined && message.elevationBias !== null && message.hasOwnProperty("elevationBias")) + object.elevationBias = message.elevationBias; + if (message.negativeAltitudeExponentBias !== undefined && message.negativeAltitudeExponentBias !== null && message.hasOwnProperty("negativeAltitudeExponentBias")) + object.negativeAltitudeExponentBias = message.negativeAltitudeExponentBias; + if (message.compressedNegativeAltitudeThreshold !== undefined && message.compressedNegativeAltitudeThreshold !== null && message.hasOwnProperty("compressedNegativeAltitudeThreshold")) + object.compressedNegativeAltitudeThreshold = message.compressedNegativeAltitudeThreshold; + return object; + }; + + PlanetModelProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + PlanetModelProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PlanetModelProto; + })(); + + dbroot.ProviderInfoProto = (function() { + + function ProviderInfoProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + ProviderInfoProto.prototype.providerId = 0; + ProviderInfoProto.prototype.copyrightString = null; + ProviderInfoProto.prototype.verticalPixelOffset = -1; + + var $types = { + 1 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); + + ProviderInfoProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.ProviderInfoProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.providerId = reader.int32(); break; - case 39: - message.swoopParameters = $types[45].decode(reader, reader.uint32()); + case 2: + message.copyrightString = $types[1].decode(reader, reader.uint32()); break; - case 40: - message.bbsServerInfo = $types[46].decode(reader, reader.uint32()); + case 3: + message.verticalPixelOffset = reader.int32(); break; - case 41: - message.dataErrorServerInfo = $types[47].decode(reader, reader.uint32()); + default: + reader.skipType(tag & 7); break; - case 42: - if (!(message.planetaryDatabase && message.planetaryDatabase.length)) - message.planetaryDatabase = []; - message.planetaryDatabase.push($types[48].decode(reader, reader.uint32())); + } + } + return message; + }; + + ProviderInfoProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isInteger(message.providerId)) + return "providerId: integer expected"; + if (message.copyrightString !== undefined && message.copyrightString !== null) { + var error = $types[1].verify(message.copyrightString); + if (error) + return "copyrightString." + error; + } + if (message.verticalPixelOffset !== undefined) + if (!$util.isInteger(message.verticalPixelOffset)) + return "verticalPixelOffset: integer expected"; + return null; + }; + + ProviderInfoProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ProviderInfoProto) + return object; + var message = new $root.keyhole.dbroot.ProviderInfoProto(); + if (object.providerId !== undefined && object.providerId !== null) + message.providerId = object.providerId | 0; + if (object.copyrightString !== undefined && object.copyrightString !== null) { + if (typeof object.copyrightString !== "object") + throw TypeError(".keyhole.dbroot.ProviderInfoProto.copyrightString: object expected"); + message.copyrightString = $types[1].fromObject(object.copyrightString); + } + if (object.verticalPixelOffset !== undefined && object.verticalPixelOffset !== null) + message.verticalPixelOffset = object.verticalPixelOffset | 0; + return message; + }; + + ProviderInfoProto.from = ProviderInfoProto.fromObject; + + ProviderInfoProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.providerId = 0; + object.copyrightString = null; + object.verticalPixelOffset = -1; + } + if (message.providerId !== undefined && message.providerId !== null && message.hasOwnProperty("providerId")) + object.providerId = message.providerId; + if (message.copyrightString !== undefined && message.copyrightString !== null && message.hasOwnProperty("copyrightString")) + object.copyrightString = $types[1].toObject(message.copyrightString, options); + if (message.verticalPixelOffset !== undefined && message.verticalPixelOffset !== null && message.hasOwnProperty("verticalPixelOffset")) + object.verticalPixelOffset = message.verticalPixelOffset; + return object; + }; + + ProviderInfoProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + ProviderInfoProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ProviderInfoProto; + })(); + + dbroot.PopUpProto = (function() { + + function PopUpProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + PopUpProto.prototype.isBalloonStyle = false; + PopUpProto.prototype.text = null; + PopUpProto.prototype.backgroundColorAbgr = 4294967295; + PopUpProto.prototype.textColorAbgr = 4278190080; + + var $types = { + 1 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); + + PopUpProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.PopUpProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.isBalloonStyle = reader.bool(); break; - case 43: - message.logServer = $types[49].decode(reader, reader.uint32()); + case 2: + message.text = $types[1].decode(reader, reader.uint32()); break; - case 44: - message.autopiaOptions = $types[50].decode(reader, reader.uint32()); + case 3: + message.backgroundColorAbgr = reader.fixed32(); break; - case 54: - message.searchConfig = $types[51].decode(reader, reader.uint32()); + case 4: + message.textColorAbgr = reader.fixed32(); break; - case 45: - message.searchInfo = $types[52].decode(reader, reader.uint32()); + default: + reader.skipType(tag & 7); break; - case 46: - message.elevationServiceBaseUrl = reader.string(); + } + } + return message; + }; + + PopUpProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.isBalloonStyle !== undefined) + if (typeof message.isBalloonStyle !== "boolean") + return "isBalloonStyle: boolean expected"; + if (message.text !== undefined && message.text !== null) { + var error = $types[1].verify(message.text); + if (error) + return "text." + error; + } + if (message.backgroundColorAbgr !== undefined) + if (!$util.isInteger(message.backgroundColorAbgr)) + return "backgroundColorAbgr: integer expected"; + if (message.textColorAbgr !== undefined) + if (!$util.isInteger(message.textColorAbgr)) + return "textColorAbgr: integer expected"; + return null; + }; + + PopUpProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.PopUpProto) + return object; + var message = new $root.keyhole.dbroot.PopUpProto(); + if (object.isBalloonStyle !== undefined && object.isBalloonStyle !== null) + message.isBalloonStyle = Boolean(object.isBalloonStyle); + if (object.text !== undefined && object.text !== null) { + if (typeof object.text !== "object") + throw TypeError(".keyhole.dbroot.PopUpProto.text: object expected"); + message.text = $types[1].fromObject(object.text); + } + if (object.backgroundColorAbgr !== undefined && object.backgroundColorAbgr !== null) + message.backgroundColorAbgr = object.backgroundColorAbgr >>> 0; + if (object.textColorAbgr !== undefined && object.textColorAbgr !== null) + message.textColorAbgr = object.textColorAbgr >>> 0; + return message; + }; + + PopUpProto.from = PopUpProto.fromObject; + + PopUpProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.isBalloonStyle = false; + object.text = null; + object.backgroundColorAbgr = 4294967295; + object.textColorAbgr = 4278190080; + } + if (message.isBalloonStyle !== undefined && message.isBalloonStyle !== null && message.hasOwnProperty("isBalloonStyle")) + object.isBalloonStyle = message.isBalloonStyle; + if (message.text !== undefined && message.text !== null && message.hasOwnProperty("text")) + object.text = $types[1].toObject(message.text, options); + if (message.backgroundColorAbgr !== undefined && message.backgroundColorAbgr !== null && message.hasOwnProperty("backgroundColorAbgr")) + object.backgroundColorAbgr = message.backgroundColorAbgr; + if (message.textColorAbgr !== undefined && message.textColorAbgr !== null && message.hasOwnProperty("textColorAbgr")) + object.textColorAbgr = message.textColorAbgr; + return object; + }; + + PopUpProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + PopUpProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PopUpProto; + })(); + + dbroot.StyleAttributeProto = (function() { + + function StyleAttributeProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + StyleAttributeProto.prototype.styleId = ""; + StyleAttributeProto.prototype.providerId = 0; + StyleAttributeProto.prototype.polyColorAbgr = 4294967295; + StyleAttributeProto.prototype.lineColorAbgr = 4294967295; + StyleAttributeProto.prototype.lineWidth = 1; + StyleAttributeProto.prototype.labelColorAbgr = 4294967295; + StyleAttributeProto.prototype.labelScale = 1; + StyleAttributeProto.prototype.placemarkIconColorAbgr = 4294967295; + StyleAttributeProto.prototype.placemarkIconScale = 1; + StyleAttributeProto.prototype.placemarkIconPath = null; + StyleAttributeProto.prototype.placemarkIconX = 0; + StyleAttributeProto.prototype.placemarkIconY = 0; + StyleAttributeProto.prototype.placemarkIconWidth = 32; + StyleAttributeProto.prototype.placemarkIconHeight = 32; + StyleAttributeProto.prototype.popUp = null; + StyleAttributeProto.prototype.drawFlag = $util.emptyArray; + + var $types = { + 9 : "keyhole.dbroot.StringIdOrValueProto", + 14 : "keyhole.dbroot.PopUpProto", + 15 : "keyhole.dbroot.DrawFlagProto" + }; + $lazyTypes.push($types); + + StyleAttributeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.StyleAttributeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.styleId = reader.string(); break; - case 47: - message.elevationProfileQueryDelay = reader.int32(); + case 3: + message.providerId = reader.int32(); break; - case 55: - message.proUpgradeUrl = $types[55].decode(reader, reader.uint32()); + case 4: + message.polyColorAbgr = reader.fixed32(); break; - case 56: - message.earthCommunityUrl = $types[56].decode(reader, reader.uint32()); + case 5: + message.lineColorAbgr = reader.fixed32(); break; - case 57: - message.googleMapsUrl = $types[57].decode(reader, reader.uint32()); + case 6: + message.lineWidth = reader.float(); break; - case 58: - message.sharingUrl = $types[58].decode(reader, reader.uint32()); + case 7: + message.labelColorAbgr = reader.fixed32(); break; - case 59: - message.privacyPolicyUrl = $types[59].decode(reader, reader.uint32()); + case 8: + message.labelScale = reader.float(); break; - case 60: - message.doGplusUserCheck = reader.bool(); + case 9: + message.placemarkIconColorAbgr = reader.fixed32(); break; - case 61: - message.rocktreeDataProto = $types[61].decode(reader, reader.uint32()); + case 10: + message.placemarkIconScale = reader.float(); break; - case 62: - if (!(message.filmstripConfig && message.filmstripConfig.length)) - message.filmstripConfig = []; - message.filmstripConfig.push($types[62].decode(reader, reader.uint32())); + case 11: + message.placemarkIconPath = $types[9].decode(reader, reader.uint32()); break; - case 63: - message.showSigninButton = reader.bool(); + case 12: + message.placemarkIconX = reader.int32(); break; - case 65: - message.proMeasureUpsellUrl = $types[64].decode(reader, reader.uint32()); + case 13: + message.placemarkIconY = reader.int32(); break; - case 66: - message.proPrintUpsellUrl = $types[65].decode(reader, reader.uint32()); + case 14: + message.placemarkIconWidth = reader.int32(); break; - case 67: - message.starDataProto = $types[66].decode(reader, reader.uint32()); + case 15: + message.placemarkIconHeight = reader.int32(); break; - case 68: - message.feedbackUrl = $types[67].decode(reader, reader.uint32()); + case 16: + message.popUp = $types[14].decode(reader, reader.uint32()); break; - case 69: - message.oauth2LoginUrl = $types[68].decode(reader, reader.uint32()); + case 17: + if (!(message.drawFlag && message.drawFlag.length)) + message.drawFlag = []; + message.drawFlag.push($types[15].decode(reader, reader.uint32())); break; default: reader.skipType(tag & 7); @@ -60248,1224 +57019,2000 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - EndSnippetProto.verify = function verify(message) { + StyleAttributeProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.model !== undefined && message.model !== null) { - var error = $types[0].verify(message.model); + if (!$util.isString(message.styleId)) + return "styleId: string expected"; + if (message.providerId !== undefined) + if (!$util.isInteger(message.providerId)) + return "providerId: integer expected"; + if (message.polyColorAbgr !== undefined) + if (!$util.isInteger(message.polyColorAbgr)) + return "polyColorAbgr: integer expected"; + if (message.lineColorAbgr !== undefined) + if (!$util.isInteger(message.lineColorAbgr)) + return "lineColorAbgr: integer expected"; + if (message.lineWidth !== undefined) + if (typeof message.lineWidth !== "number") + return "lineWidth: number expected"; + if (message.labelColorAbgr !== undefined) + if (!$util.isInteger(message.labelColorAbgr)) + return "labelColorAbgr: integer expected"; + if (message.labelScale !== undefined) + if (typeof message.labelScale !== "number") + return "labelScale: number expected"; + if (message.placemarkIconColorAbgr !== undefined) + if (!$util.isInteger(message.placemarkIconColorAbgr)) + return "placemarkIconColorAbgr: integer expected"; + if (message.placemarkIconScale !== undefined) + if (typeof message.placemarkIconScale !== "number") + return "placemarkIconScale: number expected"; + if (message.placemarkIconPath !== undefined && message.placemarkIconPath !== null) { + var error = $types[9].verify(message.placemarkIconPath); if (error) - return "model." + error; + return "placemarkIconPath." + error; } - if (message.authServerUrl !== undefined && message.authServerUrl !== null) { - var error = $types[1].verify(message.authServerUrl); + if (message.placemarkIconX !== undefined) + if (!$util.isInteger(message.placemarkIconX)) + return "placemarkIconX: integer expected"; + if (message.placemarkIconY !== undefined) + if (!$util.isInteger(message.placemarkIconY)) + return "placemarkIconY: integer expected"; + if (message.placemarkIconWidth !== undefined) + if (!$util.isInteger(message.placemarkIconWidth)) + return "placemarkIconWidth: integer expected"; + if (message.placemarkIconHeight !== undefined) + if (!$util.isInteger(message.placemarkIconHeight)) + return "placemarkIconHeight: integer expected"; + if (message.popUp !== undefined && message.popUp !== null) { + var error = $types[14].verify(message.popUp); if (error) - return "authServerUrl." + error; + return "popUp." + error; } - if (message.disableAuthentication !== undefined) - if (typeof message.disableAuthentication !== "boolean") - return "disableAuthentication: boolean expected"; - if (message.mfeDomains !== undefined) { - if (!Array.isArray(message.mfeDomains)) - return "mfeDomains: array expected"; - for (var i = 0; i < message.mfeDomains.length; ++i) { - var error = $types[3].verify(message.mfeDomains[i]); + if (message.drawFlag !== undefined) { + if (!Array.isArray(message.drawFlag)) + return "drawFlag: array expected"; + for (var i = 0; i < message.drawFlag.length; ++i) { + var error = $types[15].verify(message.drawFlag[i]); if (error) - return "mfeDomains." + error; + return "drawFlag." + error; } } - if (message.mfeLangParam !== undefined) - if (!$util.isString(message.mfeLangParam)) - return "mfeLangParam: string expected"; - if (message.adsUrlPatterns !== undefined) - if (!$util.isString(message.adsUrlPatterns)) - return "adsUrlPatterns: string expected"; - if (message.reverseGeocoderUrl !== undefined && message.reverseGeocoderUrl !== null) { - var error = $types[6].verify(message.reverseGeocoderUrl); - if (error) - return "reverseGeocoderUrl." + error; - } - if (message.reverseGeocoderProtocolVersion !== undefined) - if (!$util.isInteger(message.reverseGeocoderProtocolVersion)) - return "reverseGeocoderProtocolVersion: integer expected"; - if (message.skyDatabaseIsAvailable !== undefined) - if (typeof message.skyDatabaseIsAvailable !== "boolean") - return "skyDatabaseIsAvailable: boolean expected"; - if (message.skyDatabaseUrl !== undefined && message.skyDatabaseUrl !== null) { - var error = $types[9].verify(message.skyDatabaseUrl); - if (error) - return "skyDatabaseUrl." + error; - } - if (message.defaultWebPageIntlUrl !== undefined && message.defaultWebPageIntlUrl !== null) { - var error = $types[10].verify(message.defaultWebPageIntlUrl); - if (error) - return "defaultWebPageIntlUrl." + error; - } - if (message.numStartUpTips !== undefined) - if (!$util.isInteger(message.numStartUpTips)) - return "numStartUpTips: integer expected"; - if (message.startUpTipsUrl !== undefined && message.startUpTipsUrl !== null) { - var error = $types[12].verify(message.startUpTipsUrl); - if (error) - return "startUpTipsUrl." + error; - } - if (message.numProStartUpTips !== undefined) - if (!$util.isInteger(message.numProStartUpTips)) - return "numProStartUpTips: integer expected"; - if (message.proStartUpTipsUrl !== undefined && message.proStartUpTipsUrl !== null) { - var error = $types[14].verify(message.proStartUpTipsUrl); - if (error) - return "proStartUpTipsUrl." + error; - } - if (message.startupTipsIntlUrl !== undefined && message.startupTipsIntlUrl !== null) { - var error = $types[15].verify(message.startupTipsIntlUrl); - if (error) - return "startupTipsIntlUrl." + error; + return null; + }; + + StyleAttributeProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.StyleAttributeProto) + return object; + var message = new $root.keyhole.dbroot.StyleAttributeProto(); + if (object.styleId !== undefined && object.styleId !== null) + message.styleId = String(object.styleId); + if (object.providerId !== undefined && object.providerId !== null) + message.providerId = object.providerId | 0; + if (object.polyColorAbgr !== undefined && object.polyColorAbgr !== null) + message.polyColorAbgr = object.polyColorAbgr >>> 0; + if (object.lineColorAbgr !== undefined && object.lineColorAbgr !== null) + message.lineColorAbgr = object.lineColorAbgr >>> 0; + if (object.lineWidth !== undefined && object.lineWidth !== null) + message.lineWidth = Number(object.lineWidth); + if (object.labelColorAbgr !== undefined && object.labelColorAbgr !== null) + message.labelColorAbgr = object.labelColorAbgr >>> 0; + if (object.labelScale !== undefined && object.labelScale !== null) + message.labelScale = Number(object.labelScale); + if (object.placemarkIconColorAbgr !== undefined && object.placemarkIconColorAbgr !== null) + message.placemarkIconColorAbgr = object.placemarkIconColorAbgr >>> 0; + if (object.placemarkIconScale !== undefined && object.placemarkIconScale !== null) + message.placemarkIconScale = Number(object.placemarkIconScale); + if (object.placemarkIconPath !== undefined && object.placemarkIconPath !== null) { + if (typeof object.placemarkIconPath !== "object") + throw TypeError(".keyhole.dbroot.StyleAttributeProto.placemarkIconPath: object expected"); + message.placemarkIconPath = $types[9].fromObject(object.placemarkIconPath); } - if (message.userGuideIntlUrl !== undefined && message.userGuideIntlUrl !== null) { - var error = $types[16].verify(message.userGuideIntlUrl); - if (error) - return "userGuideIntlUrl." + error; + if (object.placemarkIconX !== undefined && object.placemarkIconX !== null) + message.placemarkIconX = object.placemarkIconX | 0; + if (object.placemarkIconY !== undefined && object.placemarkIconY !== null) + message.placemarkIconY = object.placemarkIconY | 0; + if (object.placemarkIconWidth !== undefined && object.placemarkIconWidth !== null) + message.placemarkIconWidth = object.placemarkIconWidth | 0; + if (object.placemarkIconHeight !== undefined && object.placemarkIconHeight !== null) + message.placemarkIconHeight = object.placemarkIconHeight | 0; + if (object.popUp !== undefined && object.popUp !== null) { + if (typeof object.popUp !== "object") + throw TypeError(".keyhole.dbroot.StyleAttributeProto.popUp: object expected"); + message.popUp = $types[14].fromObject(object.popUp); } - if (message.supportCenterIntlUrl !== undefined && message.supportCenterIntlUrl !== null) { - var error = $types[17].verify(message.supportCenterIntlUrl); - if (error) - return "supportCenterIntlUrl." + error; + if (object.drawFlag) { + if (!Array.isArray(object.drawFlag)) + throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: array expected"); + message.drawFlag = []; + for (var i = 0; i < object.drawFlag.length; ++i) { + if (typeof object.drawFlag[i] !== "object") + throw TypeError(".keyhole.dbroot.StyleAttributeProto.drawFlag: object expected"); + message.drawFlag[i] = $types[15].fromObject(object.drawFlag[i]); + } } - if (message.businessListingIntlUrl !== undefined && message.businessListingIntlUrl !== null) { - var error = $types[18].verify(message.businessListingIntlUrl); - if (error) - return "businessListingIntlUrl." + error; + return message; + }; + + StyleAttributeProto.from = StyleAttributeProto.fromObject; + + StyleAttributeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.drawFlag = []; + if (options.defaults) { + object.styleId = ""; + object.providerId = 0; + object.polyColorAbgr = 4294967295; + object.lineColorAbgr = 4294967295; + object.lineWidth = 1; + object.labelColorAbgr = 4294967295; + object.labelScale = 1; + object.placemarkIconColorAbgr = 4294967295; + object.placemarkIconScale = 1; + object.placemarkIconPath = null; + object.placemarkIconX = 0; + object.placemarkIconY = 0; + object.placemarkIconWidth = 32; + object.placemarkIconHeight = 32; + object.popUp = null; } - if (message.supportAnswerIntlUrl !== undefined && message.supportAnswerIntlUrl !== null) { - var error = $types[19].verify(message.supportAnswerIntlUrl); - if (error) - return "supportAnswerIntlUrl." + error; + if (message.styleId !== undefined && message.styleId !== null && message.hasOwnProperty("styleId")) + object.styleId = message.styleId; + if (message.providerId !== undefined && message.providerId !== null && message.hasOwnProperty("providerId")) + object.providerId = message.providerId; + if (message.polyColorAbgr !== undefined && message.polyColorAbgr !== null && message.hasOwnProperty("polyColorAbgr")) + object.polyColorAbgr = message.polyColorAbgr; + if (message.lineColorAbgr !== undefined && message.lineColorAbgr !== null && message.hasOwnProperty("lineColorAbgr")) + object.lineColorAbgr = message.lineColorAbgr; + if (message.lineWidth !== undefined && message.lineWidth !== null && message.hasOwnProperty("lineWidth")) + object.lineWidth = message.lineWidth; + if (message.labelColorAbgr !== undefined && message.labelColorAbgr !== null && message.hasOwnProperty("labelColorAbgr")) + object.labelColorAbgr = message.labelColorAbgr; + if (message.labelScale !== undefined && message.labelScale !== null && message.hasOwnProperty("labelScale")) + object.labelScale = message.labelScale; + if (message.placemarkIconColorAbgr !== undefined && message.placemarkIconColorAbgr !== null && message.hasOwnProperty("placemarkIconColorAbgr")) + object.placemarkIconColorAbgr = message.placemarkIconColorAbgr; + if (message.placemarkIconScale !== undefined && message.placemarkIconScale !== null && message.hasOwnProperty("placemarkIconScale")) + object.placemarkIconScale = message.placemarkIconScale; + if (message.placemarkIconPath !== undefined && message.placemarkIconPath !== null && message.hasOwnProperty("placemarkIconPath")) + object.placemarkIconPath = $types[9].toObject(message.placemarkIconPath, options); + if (message.placemarkIconX !== undefined && message.placemarkIconX !== null && message.hasOwnProperty("placemarkIconX")) + object.placemarkIconX = message.placemarkIconX; + if (message.placemarkIconY !== undefined && message.placemarkIconY !== null && message.hasOwnProperty("placemarkIconY")) + object.placemarkIconY = message.placemarkIconY; + if (message.placemarkIconWidth !== undefined && message.placemarkIconWidth !== null && message.hasOwnProperty("placemarkIconWidth")) + object.placemarkIconWidth = message.placemarkIconWidth; + if (message.placemarkIconHeight !== undefined && message.placemarkIconHeight !== null && message.hasOwnProperty("placemarkIconHeight")) + object.placemarkIconHeight = message.placemarkIconHeight; + if (message.popUp !== undefined && message.popUp !== null && message.hasOwnProperty("popUp")) + object.popUp = $types[14].toObject(message.popUp, options); + if (message.drawFlag !== undefined && message.drawFlag !== null && message.hasOwnProperty("drawFlag")) { + object.drawFlag = []; + for (var j = 0; j < message.drawFlag.length; ++j) + object.drawFlag[j] = $types[15].toObject(message.drawFlag[j], options); } - if (message.supportTopicIntlUrl !== undefined && message.supportTopicIntlUrl !== null) { - var error = $types[20].verify(message.supportTopicIntlUrl); - if (error) - return "supportTopicIntlUrl." + error; + return object; + }; + + StyleAttributeProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + StyleAttributeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StyleAttributeProto; + })(); + + dbroot.StyleMapProto = (function() { + + function StyleMapProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + StyleMapProto.prototype.styleMapId = 0; + StyleMapProto.prototype.channelId = $util.emptyArray; + StyleMapProto.prototype.normalStyleAttribute = 0; + StyleMapProto.prototype.highlightStyleAttribute = 0; + + StyleMapProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.StyleMapProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.styleMapId = reader.int32(); + break; + case 2: + if (!(message.channelId && message.channelId.length)) + message.channelId = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.channelId.push(reader.int32()); + } else + message.channelId.push(reader.int32()); + break; + case 3: + message.normalStyleAttribute = reader.int32(); + break; + case 4: + message.highlightStyleAttribute = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } } - if (message.supportRequestIntlUrl !== undefined && message.supportRequestIntlUrl !== null) { - var error = $types[21].verify(message.supportRequestIntlUrl); - if (error) - return "supportRequestIntlUrl." + error; + return message; + }; + + StyleMapProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isInteger(message.styleMapId)) + return "styleMapId: integer expected"; + if (message.channelId !== undefined) { + if (!Array.isArray(message.channelId)) + return "channelId: array expected"; + for (var i = 0; i < message.channelId.length; ++i) + if (!$util.isInteger(message.channelId[i])) + return "channelId: integer[] expected"; } - if (message.earthIntlUrl !== undefined && message.earthIntlUrl !== null) { - var error = $types[22].verify(message.earthIntlUrl); - if (error) - return "earthIntlUrl." + error; + if (message.normalStyleAttribute !== undefined) + if (!$util.isInteger(message.normalStyleAttribute)) + return "normalStyleAttribute: integer expected"; + if (message.highlightStyleAttribute !== undefined) + if (!$util.isInteger(message.highlightStyleAttribute)) + return "highlightStyleAttribute: integer expected"; + return null; + }; + + StyleMapProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.StyleMapProto) + return object; + var message = new $root.keyhole.dbroot.StyleMapProto(); + if (object.styleMapId !== undefined && object.styleMapId !== null) + message.styleMapId = object.styleMapId | 0; + if (object.channelId) { + if (!Array.isArray(object.channelId)) + throw TypeError(".keyhole.dbroot.StyleMapProto.channelId: array expected"); + message.channelId = []; + for (var i = 0; i < object.channelId.length; ++i) + message.channelId[i] = object.channelId[i] | 0; } - if (message.addContentUrl !== undefined && message.addContentUrl !== null) { - var error = $types[23].verify(message.addContentUrl); - if (error) - return "addContentUrl." + error; + if (object.normalStyleAttribute !== undefined && object.normalStyleAttribute !== null) + message.normalStyleAttribute = object.normalStyleAttribute | 0; + if (object.highlightStyleAttribute !== undefined && object.highlightStyleAttribute !== null) + message.highlightStyleAttribute = object.highlightStyleAttribute | 0; + return message; + }; + + StyleMapProto.from = StyleMapProto.fromObject; + + StyleMapProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.channelId = []; + if (options.defaults) { + object.styleMapId = 0; + object.normalStyleAttribute = 0; + object.highlightStyleAttribute = 0; } - if (message.sketchupNotInstalledUrl !== undefined && message.sketchupNotInstalledUrl !== null) { - var error = $types[24].verify(message.sketchupNotInstalledUrl); - if (error) - return "sketchupNotInstalledUrl." + error; + if (message.styleMapId !== undefined && message.styleMapId !== null && message.hasOwnProperty("styleMapId")) + object.styleMapId = message.styleMapId; + if (message.channelId !== undefined && message.channelId !== null && message.hasOwnProperty("channelId")) { + object.channelId = []; + for (var j = 0; j < message.channelId.length; ++j) + object.channelId[j] = message.channelId[j]; } - if (message.sketchupErrorUrl !== undefined && message.sketchupErrorUrl !== null) { - var error = $types[25].verify(message.sketchupErrorUrl); - if (error) - return "sketchupErrorUrl." + error; - } - if (message.freeLicenseUrl !== undefined && message.freeLicenseUrl !== null) { - var error = $types[26].verify(message.freeLicenseUrl); - if (error) - return "freeLicenseUrl." + error; - } - if (message.proLicenseUrl !== undefined && message.proLicenseUrl !== null) { - var error = $types[27].verify(message.proLicenseUrl); - if (error) - return "proLicenseUrl." + error; - } - if (message.tutorialUrl !== undefined && message.tutorialUrl !== null) { - var error = $types[28].verify(message.tutorialUrl); - if (error) - return "tutorialUrl." + error; - } - if (message.keyboardShortcutsUrl !== undefined && message.keyboardShortcutsUrl !== null) { - var error = $types[29].verify(message.keyboardShortcutsUrl); - if (error) - return "keyboardShortcutsUrl." + error; - } - if (message.releaseNotesUrl !== undefined && message.releaseNotesUrl !== null) { - var error = $types[30].verify(message.releaseNotesUrl); - if (error) - return "releaseNotesUrl." + error; - } - if (message.hideUserData !== undefined) - if (typeof message.hideUserData !== "boolean") - return "hideUserData: boolean expected"; - if (message.useGeLogo !== undefined) - if (typeof message.useGeLogo !== "boolean") - return "useGeLogo: boolean expected"; - if (message.dioramaDescriptionUrlBase !== undefined && message.dioramaDescriptionUrlBase !== null) { - var error = $types[33].verify(message.dioramaDescriptionUrlBase); - if (error) - return "dioramaDescriptionUrlBase." + error; - } - if (message.dioramaDefaultColor !== undefined) - if (!$util.isInteger(message.dioramaDefaultColor)) - return "dioramaDefaultColor: integer expected"; - if (message.dioramaBlacklistUrl !== undefined && message.dioramaBlacklistUrl !== null) { - var error = $types[35].verify(message.dioramaBlacklistUrl); - if (error) - return "dioramaBlacklistUrl." + error; + if (message.normalStyleAttribute !== undefined && message.normalStyleAttribute !== null && message.hasOwnProperty("normalStyleAttribute")) + object.normalStyleAttribute = message.normalStyleAttribute; + if (message.highlightStyleAttribute !== undefined && message.highlightStyleAttribute !== null && message.hasOwnProperty("highlightStyleAttribute")) + object.highlightStyleAttribute = message.highlightStyleAttribute; + return object; + }; + + StyleMapProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + StyleMapProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StyleMapProto; + })(); + + dbroot.ZoomRangeProto = (function() { + + function ZoomRangeProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + ZoomRangeProto.prototype.minZoom = 0; + ZoomRangeProto.prototype.maxZoom = 0; + + ZoomRangeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.ZoomRangeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.minZoom = reader.int32(); + break; + case 2: + message.maxZoom = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } } - if (message.clientOptions !== undefined && message.clientOptions !== null) { - var error = $types[36].verify(message.clientOptions); - if (error) - return "clientOptions." + error; + return message; + }; + + ZoomRangeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isInteger(message.minZoom)) + return "minZoom: integer expected"; + if (!$util.isInteger(message.maxZoom)) + return "maxZoom: integer expected"; + return null; + }; + + ZoomRangeProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ZoomRangeProto) + return object; + var message = new $root.keyhole.dbroot.ZoomRangeProto(); + if (object.minZoom !== undefined && object.minZoom !== null) + message.minZoom = object.minZoom | 0; + if (object.maxZoom !== undefined && object.maxZoom !== null) + message.maxZoom = object.maxZoom | 0; + return message; + }; + + ZoomRangeProto.from = ZoomRangeProto.fromObject; + + ZoomRangeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.minZoom = 0; + object.maxZoom = 0; } - if (message.fetchingOptions !== undefined && message.fetchingOptions !== null) { - var error = $types[37].verify(message.fetchingOptions); - if (error) - return "fetchingOptions." + error; + if (message.minZoom !== undefined && message.minZoom !== null && message.hasOwnProperty("minZoom")) + object.minZoom = message.minZoom; + if (message.maxZoom !== undefined && message.maxZoom !== null && message.hasOwnProperty("maxZoom")) + object.maxZoom = message.maxZoom; + return object; + }; + + ZoomRangeProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + ZoomRangeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ZoomRangeProto; + })(); + + dbroot.DrawFlagProto = (function() { + + function DrawFlagProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + DrawFlagProto.prototype.drawFlagType = 1; + + var $types = { + 0 : "keyhole.dbroot.DrawFlagProto.DrawFlagType" + }; + $lazyTypes.push($types); + + DrawFlagProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.DrawFlagProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.drawFlagType = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } } - if (message.timeMachineOptions !== undefined && message.timeMachineOptions !== null) { - var error = $types[38].verify(message.timeMachineOptions); - if (error) - return "timeMachineOptions." + error; + return message; + }; + + DrawFlagProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + switch (message.drawFlagType) { + default: + return "drawFlagType: enum value expected"; + case 1: + case 2: + case 3: + case 4: + case 5: + break; } - if (message.csiOptions !== undefined && message.csiOptions !== null) { - var error = $types[39].verify(message.csiOptions); - if (error) - return "csiOptions." + error; + return null; + }; + + DrawFlagProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.DrawFlagProto) + return object; + var message = new $root.keyhole.dbroot.DrawFlagProto(); + switch (object.drawFlagType) { + case "TYPE_FILL_ONLY": + case 1: + message.drawFlagType = 1; + break; + case "TYPE_OUTLINE_ONLY": + case 2: + message.drawFlagType = 2; + break; + case "TYPE_FILL_AND_OUTLINE": + case 3: + message.drawFlagType = 3; + break; + case "TYPE_ANTIALIASING": + case 4: + message.drawFlagType = 4; + break; + case "TYPE_CENTER_LABEL": + case 5: + message.drawFlagType = 5; + break; } - if (message.searchTab !== undefined) { - if (!Array.isArray(message.searchTab)) - return "searchTab: array expected"; - for (var i = 0; i < message.searchTab.length; ++i) { - var error = $types[40].verify(message.searchTab[i]); - if (error) - return "searchTab." + error; + return message; + }; + + DrawFlagProto.from = DrawFlagProto.fromObject; + + DrawFlagProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.drawFlagType = options.enums === String ? "TYPE_FILL_ONLY" : 1; + if (message.drawFlagType !== undefined && message.drawFlagType !== null && message.hasOwnProperty("drawFlagType")) + object.drawFlagType = options.enums === String ? $types[0][message.drawFlagType] : message.drawFlagType; + return object; + }; + + DrawFlagProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + DrawFlagProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + DrawFlagProto.DrawFlagType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values["TYPE_FILL_ONLY"] = 1; + values["TYPE_OUTLINE_ONLY"] = 2; + values["TYPE_FILL_AND_OUTLINE"] = 3; + values["TYPE_ANTIALIASING"] = 4; + values["TYPE_CENTER_LABEL"] = 5; + return values; + })(); + + return DrawFlagProto; + })(); + + dbroot.LayerProto = (function() { + + function LayerProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + LayerProto.prototype.zoomRange = $util.emptyArray; + LayerProto.prototype.preserveTextLevel = 30; + LayerProto.prototype.lodBeginTransition = false; + LayerProto.prototype.lodEndTransition = false; + + var $types = { + 0 : "keyhole.dbroot.ZoomRangeProto" + }; + $lazyTypes.push($types); + + LayerProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.LayerProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.zoomRange && message.zoomRange.length)) + message.zoomRange = []; + message.zoomRange.push($types[0].decode(reader, reader.uint32())); + break; + case 2: + message.preserveTextLevel = reader.int32(); + break; + case 4: + message.lodBeginTransition = reader.bool(); + break; + case 5: + message.lodEndTransition = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; } } - if (message.cobrandInfo !== undefined) { - if (!Array.isArray(message.cobrandInfo)) - return "cobrandInfo: array expected"; - for (var i = 0; i < message.cobrandInfo.length; ++i) { - var error = $types[41].verify(message.cobrandInfo[i]); + return message; + }; + + LayerProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.zoomRange !== undefined) { + if (!Array.isArray(message.zoomRange)) + return "zoomRange: array expected"; + for (var i = 0; i < message.zoomRange.length; ++i) { + var error = $types[0].verify(message.zoomRange[i]); if (error) - return "cobrandInfo." + error; + return "zoomRange." + error; } } - if (message.validDatabase !== undefined) { - if (!Array.isArray(message.validDatabase)) - return "validDatabase: array expected"; - for (var i = 0; i < message.validDatabase.length; ++i) { - var error = $types[42].verify(message.validDatabase[i]); - if (error) - return "validDatabase." + error; + if (message.preserveTextLevel !== undefined) + if (!$util.isInteger(message.preserveTextLevel)) + return "preserveTextLevel: integer expected"; + if (message.lodBeginTransition !== undefined) + if (typeof message.lodBeginTransition !== "boolean") + return "lodBeginTransition: boolean expected"; + if (message.lodEndTransition !== undefined) + if (typeof message.lodEndTransition !== "boolean") + return "lodEndTransition: boolean expected"; + return null; + }; + + LayerProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.LayerProto) + return object; + var message = new $root.keyhole.dbroot.LayerProto(); + if (object.zoomRange) { + if (!Array.isArray(object.zoomRange)) + throw TypeError(".keyhole.dbroot.LayerProto.zoomRange: array expected"); + message.zoomRange = []; + for (var i = 0; i < object.zoomRange.length; ++i) { + if (typeof object.zoomRange[i] !== "object") + throw TypeError(".keyhole.dbroot.LayerProto.zoomRange: object expected"); + message.zoomRange[i] = $types[0].fromObject(object.zoomRange[i]); } } - if (message.configScript !== undefined) { - if (!Array.isArray(message.configScript)) - return "configScript: array expected"; - for (var i = 0; i < message.configScript.length; ++i) { - var error = $types[43].verify(message.configScript[i]); - if (error) - return "configScript." + error; - } + if (object.preserveTextLevel !== undefined && object.preserveTextLevel !== null) + message.preserveTextLevel = object.preserveTextLevel | 0; + if (object.lodBeginTransition !== undefined && object.lodBeginTransition !== null) + message.lodBeginTransition = Boolean(object.lodBeginTransition); + if (object.lodEndTransition !== undefined && object.lodEndTransition !== null) + message.lodEndTransition = Boolean(object.lodEndTransition); + return message; + }; + + LayerProto.from = LayerProto.fromObject; + + LayerProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.zoomRange = []; + if (options.defaults) { + object.preserveTextLevel = 30; + object.lodBeginTransition = false; + object.lodEndTransition = false; } - if (message.deauthServerUrl !== undefined && message.deauthServerUrl !== null) { - var error = $types[44].verify(message.deauthServerUrl); - if (error) - return "deauthServerUrl." + error; + if (message.zoomRange !== undefined && message.zoomRange !== null && message.hasOwnProperty("zoomRange")) { + object.zoomRange = []; + for (var j = 0; j < message.zoomRange.length; ++j) + object.zoomRange[j] = $types[0].toObject(message.zoomRange[j], options); } - if (message.swoopParameters !== undefined && message.swoopParameters !== null) { - var error = $types[45].verify(message.swoopParameters); - if (error) - return "swoopParameters." + error; + if (message.preserveTextLevel !== undefined && message.preserveTextLevel !== null && message.hasOwnProperty("preserveTextLevel")) + object.preserveTextLevel = message.preserveTextLevel; + if (message.lodBeginTransition !== undefined && message.lodBeginTransition !== null && message.hasOwnProperty("lodBeginTransition")) + object.lodBeginTransition = message.lodBeginTransition; + if (message.lodEndTransition !== undefined && message.lodEndTransition !== null && message.hasOwnProperty("lodEndTransition")) + object.lodEndTransition = message.lodEndTransition; + return object; + }; + + LayerProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + LayerProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LayerProto; + })(); + + dbroot.FolderProto = (function() { + + function FolderProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + FolderProto.prototype.isExpandable = true; + + FolderProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.FolderProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.isExpandable = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } } - if (message.bbsServerInfo !== undefined && message.bbsServerInfo !== null) { - var error = $types[46].verify(message.bbsServerInfo); - if (error) - return "bbsServerInfo." + error; + return message; + }; + + FolderProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.isExpandable !== undefined) + if (typeof message.isExpandable !== "boolean") + return "isExpandable: boolean expected"; + return null; + }; + + FolderProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.FolderProto) + return object; + var message = new $root.keyhole.dbroot.FolderProto(); + if (object.isExpandable !== undefined && object.isExpandable !== null) + message.isExpandable = Boolean(object.isExpandable); + return message; + }; + + FolderProto.from = FolderProto.fromObject; + + FolderProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.isExpandable = true; + if (message.isExpandable !== undefined && message.isExpandable !== null && message.hasOwnProperty("isExpandable")) + object.isExpandable = message.isExpandable; + return object; + }; + + FolderProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + FolderProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return FolderProto; + })(); + + dbroot.RequirementProto = (function() { + + function RequirementProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + RequirementProto.prototype.requiredVram = ""; + RequirementProto.prototype.requiredClientVer = ""; + RequirementProto.prototype.probability = ""; + RequirementProto.prototype.requiredUserAgent = ""; + RequirementProto.prototype.requiredClientCapabilities = ""; + + RequirementProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.RequirementProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 3: + message.requiredVram = reader.string(); + break; + case 4: + message.requiredClientVer = reader.string(); + break; + case 5: + message.probability = reader.string(); + break; + case 6: + message.requiredUserAgent = reader.string(); + break; + case 7: + message.requiredClientCapabilities = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } } - if (message.dataErrorServerInfo !== undefined && message.dataErrorServerInfo !== null) { - var error = $types[47].verify(message.dataErrorServerInfo); - if (error) - return "dataErrorServerInfo." + error; + return message; + }; + + RequirementProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.requiredVram !== undefined) + if (!$util.isString(message.requiredVram)) + return "requiredVram: string expected"; + if (message.requiredClientVer !== undefined) + if (!$util.isString(message.requiredClientVer)) + return "requiredClientVer: string expected"; + if (message.probability !== undefined) + if (!$util.isString(message.probability)) + return "probability: string expected"; + if (message.requiredUserAgent !== undefined) + if (!$util.isString(message.requiredUserAgent)) + return "requiredUserAgent: string expected"; + if (message.requiredClientCapabilities !== undefined) + if (!$util.isString(message.requiredClientCapabilities)) + return "requiredClientCapabilities: string expected"; + return null; + }; + + RequirementProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.RequirementProto) + return object; + var message = new $root.keyhole.dbroot.RequirementProto(); + if (object.requiredVram !== undefined && object.requiredVram !== null) + message.requiredVram = String(object.requiredVram); + if (object.requiredClientVer !== undefined && object.requiredClientVer !== null) + message.requiredClientVer = String(object.requiredClientVer); + if (object.probability !== undefined && object.probability !== null) + message.probability = String(object.probability); + if (object.requiredUserAgent !== undefined && object.requiredUserAgent !== null) + message.requiredUserAgent = String(object.requiredUserAgent); + if (object.requiredClientCapabilities !== undefined && object.requiredClientCapabilities !== null) + message.requiredClientCapabilities = String(object.requiredClientCapabilities); + return message; + }; + + RequirementProto.from = RequirementProto.fromObject; + + RequirementProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.requiredVram = ""; + object.requiredClientVer = ""; + object.probability = ""; + object.requiredUserAgent = ""; + object.requiredClientCapabilities = ""; } - if (message.planetaryDatabase !== undefined) { - if (!Array.isArray(message.planetaryDatabase)) - return "planetaryDatabase: array expected"; - for (var i = 0; i < message.planetaryDatabase.length; ++i) { - var error = $types[48].verify(message.planetaryDatabase[i]); - if (error) - return "planetaryDatabase." + error; + if (message.requiredVram !== undefined && message.requiredVram !== null && message.hasOwnProperty("requiredVram")) + object.requiredVram = message.requiredVram; + if (message.requiredClientVer !== undefined && message.requiredClientVer !== null && message.hasOwnProperty("requiredClientVer")) + object.requiredClientVer = message.requiredClientVer; + if (message.probability !== undefined && message.probability !== null && message.hasOwnProperty("probability")) + object.probability = message.probability; + if (message.requiredUserAgent !== undefined && message.requiredUserAgent !== null && message.hasOwnProperty("requiredUserAgent")) + object.requiredUserAgent = message.requiredUserAgent; + if (message.requiredClientCapabilities !== undefined && message.requiredClientCapabilities !== null && message.hasOwnProperty("requiredClientCapabilities")) + object.requiredClientCapabilities = message.requiredClientCapabilities; + return object; + }; + + RequirementProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + RequirementProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RequirementProto; + })(); + + dbroot.LookAtProto = (function() { + + function LookAtProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + LookAtProto.prototype.longitude = 0; + LookAtProto.prototype.latitude = 0; + LookAtProto.prototype.range = 0; + LookAtProto.prototype.tilt = 0; + LookAtProto.prototype.heading = 0; + + LookAtProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.LookAtProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.longitude = reader.float(); + break; + case 2: + message.latitude = reader.float(); + break; + case 3: + message.range = reader.float(); + break; + case 4: + message.tilt = reader.float(); + break; + case 5: + message.heading = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; } } - if (message.logServer !== undefined && message.logServer !== null) { - var error = $types[49].verify(message.logServer); - if (error) - return "logServer." + error; - } - if (message.autopiaOptions !== undefined && message.autopiaOptions !== null) { - var error = $types[50].verify(message.autopiaOptions); - if (error) - return "autopiaOptions." + error; + return message; + }; + + LookAtProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (typeof message.longitude !== "number") + return "longitude: number expected"; + if (typeof message.latitude !== "number") + return "latitude: number expected"; + if (message.range !== undefined) + if (typeof message.range !== "number") + return "range: number expected"; + if (message.tilt !== undefined) + if (typeof message.tilt !== "number") + return "tilt: number expected"; + if (message.heading !== undefined) + if (typeof message.heading !== "number") + return "heading: number expected"; + return null; + }; + + LookAtProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.LookAtProto) + return object; + var message = new $root.keyhole.dbroot.LookAtProto(); + if (object.longitude !== undefined && object.longitude !== null) + message.longitude = Number(object.longitude); + if (object.latitude !== undefined && object.latitude !== null) + message.latitude = Number(object.latitude); + if (object.range !== undefined && object.range !== null) + message.range = Number(object.range); + if (object.tilt !== undefined && object.tilt !== null) + message.tilt = Number(object.tilt); + if (object.heading !== undefined && object.heading !== null) + message.heading = Number(object.heading); + return message; + }; + + LookAtProto.from = LookAtProto.fromObject; + + LookAtProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.longitude = 0; + object.latitude = 0; + object.range = 0; + object.tilt = 0; + object.heading = 0; } - if (message.searchConfig !== undefined && message.searchConfig !== null) { - var error = $types[51].verify(message.searchConfig); - if (error) - return "searchConfig." + error; + if (message.longitude !== undefined && message.longitude !== null && message.hasOwnProperty("longitude")) + object.longitude = message.longitude; + if (message.latitude !== undefined && message.latitude !== null && message.hasOwnProperty("latitude")) + object.latitude = message.latitude; + if (message.range !== undefined && message.range !== null && message.hasOwnProperty("range")) + object.range = message.range; + if (message.tilt !== undefined && message.tilt !== null && message.hasOwnProperty("tilt")) + object.tilt = message.tilt; + if (message.heading !== undefined && message.heading !== null && message.hasOwnProperty("heading")) + object.heading = message.heading; + return object; + }; + + LookAtProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + LookAtProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LookAtProto; + })(); + + dbroot.NestedFeatureProto = (function() { + + function NestedFeatureProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + NestedFeatureProto.prototype.featureType = 1; + NestedFeatureProto.prototype.kmlUrl = null; + NestedFeatureProto.prototype.databaseUrl = ""; + NestedFeatureProto.prototype.layer = null; + NestedFeatureProto.prototype.folder = null; + NestedFeatureProto.prototype.requirement = null; + NestedFeatureProto.prototype.channelId = 0; + NestedFeatureProto.prototype.displayName = null; + NestedFeatureProto.prototype.isVisible = true; + NestedFeatureProto.prototype.isEnabled = true; + NestedFeatureProto.prototype.isChecked = false; + NestedFeatureProto.prototype.layerMenuIconPath = "icons/773_l.png"; + NestedFeatureProto.prototype.description = null; + NestedFeatureProto.prototype.lookAt = null; + NestedFeatureProto.prototype.assetUuid = ""; + NestedFeatureProto.prototype.isSaveLocked = true; + NestedFeatureProto.prototype.children = $util.emptyArray; + NestedFeatureProto.prototype.clientConfigScriptName = ""; + NestedFeatureProto.prototype.dioramaDataChannelBase = -1; + NestedFeatureProto.prototype.replicaDataChannelBase = -1; + + var $types = { + 0 : "keyhole.dbroot.NestedFeatureProto.FeatureType", + 1 : "keyhole.dbroot.StringIdOrValueProto", + 3 : "keyhole.dbroot.LayerProto", + 4 : "keyhole.dbroot.FolderProto", + 5 : "keyhole.dbroot.RequirementProto", + 7 : "keyhole.dbroot.StringIdOrValueProto", + 12 : "keyhole.dbroot.StringIdOrValueProto", + 13 : "keyhole.dbroot.LookAtProto", + 16 : "keyhole.dbroot.NestedFeatureProto" + }; + $lazyTypes.push($types); + + NestedFeatureProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.NestedFeatureProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.featureType = reader.uint32(); + break; + case 2: + message.kmlUrl = $types[1].decode(reader, reader.uint32()); + break; + case 21: + message.databaseUrl = reader.string(); + break; + case 3: + message.layer = $types[3].decode(reader, reader.uint32()); + break; + case 4: + message.folder = $types[4].decode(reader, reader.uint32()); + break; + case 5: + message.requirement = $types[5].decode(reader, reader.uint32()); + break; + case 6: + message.channelId = reader.int32(); + break; + case 7: + message.displayName = $types[7].decode(reader, reader.uint32()); + break; + case 8: + message.isVisible = reader.bool(); + break; + case 9: + message.isEnabled = reader.bool(); + break; + case 10: + message.isChecked = reader.bool(); + break; + case 11: + message.layerMenuIconPath = reader.string(); + break; + case 12: + message.description = $types[12].decode(reader, reader.uint32()); + break; + case 13: + message.lookAt = $types[13].decode(reader, reader.uint32()); + break; + case 15: + message.assetUuid = reader.string(); + break; + case 16: + message.isSaveLocked = reader.bool(); + break; + case 17: + if (!(message.children && message.children.length)) + message.children = []; + message.children.push($types[16].decode(reader, reader.uint32())); + break; + case 18: + message.clientConfigScriptName = reader.string(); + break; + case 19: + message.dioramaDataChannelBase = reader.int32(); + break; + case 20: + message.replicaDataChannelBase = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } } - if (message.searchInfo !== undefined && message.searchInfo !== null) { - var error = $types[52].verify(message.searchInfo); + return message; + }; + + NestedFeatureProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.featureType !== undefined) + switch (message.featureType) { + default: + return "featureType: enum value expected"; + case 1: + case 2: + case 3: + case 4: + break; + } + if (message.kmlUrl !== undefined && message.kmlUrl !== null) { + var error = $types[1].verify(message.kmlUrl); if (error) - return "searchInfo." + error; + return "kmlUrl." + error; } - if (message.elevationServiceBaseUrl !== undefined) - if (!$util.isString(message.elevationServiceBaseUrl)) - return "elevationServiceBaseUrl: string expected"; - if (message.elevationProfileQueryDelay !== undefined) - if (!$util.isInteger(message.elevationProfileQueryDelay)) - return "elevationProfileQueryDelay: integer expected"; - if (message.proUpgradeUrl !== undefined && message.proUpgradeUrl !== null) { - var error = $types[55].verify(message.proUpgradeUrl); + if (message.databaseUrl !== undefined) + if (!$util.isString(message.databaseUrl)) + return "databaseUrl: string expected"; + if (message.layer !== undefined && message.layer !== null) { + var error = $types[3].verify(message.layer); if (error) - return "proUpgradeUrl." + error; + return "layer." + error; } - if (message.earthCommunityUrl !== undefined && message.earthCommunityUrl !== null) { - var error = $types[56].verify(message.earthCommunityUrl); + if (message.folder !== undefined && message.folder !== null) { + var error = $types[4].verify(message.folder); if (error) - return "earthCommunityUrl." + error; + return "folder." + error; } - if (message.googleMapsUrl !== undefined && message.googleMapsUrl !== null) { - var error = $types[57].verify(message.googleMapsUrl); + if (message.requirement !== undefined && message.requirement !== null) { + var error = $types[5].verify(message.requirement); if (error) - return "googleMapsUrl." + error; + return "requirement." + error; } - if (message.sharingUrl !== undefined && message.sharingUrl !== null) { - var error = $types[58].verify(message.sharingUrl); + if (!$util.isInteger(message.channelId)) + return "channelId: integer expected"; + if (message.displayName !== undefined && message.displayName !== null) { + var error = $types[7].verify(message.displayName); if (error) - return "sharingUrl." + error; + return "displayName." + error; } - if (message.privacyPolicyUrl !== undefined && message.privacyPolicyUrl !== null) { - var error = $types[59].verify(message.privacyPolicyUrl); + if (message.isVisible !== undefined) + if (typeof message.isVisible !== "boolean") + return "isVisible: boolean expected"; + if (message.isEnabled !== undefined) + if (typeof message.isEnabled !== "boolean") + return "isEnabled: boolean expected"; + if (message.isChecked !== undefined) + if (typeof message.isChecked !== "boolean") + return "isChecked: boolean expected"; + if (message.layerMenuIconPath !== undefined) + if (!$util.isString(message.layerMenuIconPath)) + return "layerMenuIconPath: string expected"; + if (message.description !== undefined && message.description !== null) { + var error = $types[12].verify(message.description); if (error) - return "privacyPolicyUrl." + error; + return "description." + error; } - if (message.doGplusUserCheck !== undefined) - if (typeof message.doGplusUserCheck !== "boolean") - return "doGplusUserCheck: boolean expected"; - if (message.rocktreeDataProto !== undefined && message.rocktreeDataProto !== null) { - var error = $types[61].verify(message.rocktreeDataProto); + if (message.lookAt !== undefined && message.lookAt !== null) { + var error = $types[13].verify(message.lookAt); if (error) - return "rocktreeDataProto." + error; + return "lookAt." + error; } - if (message.filmstripConfig !== undefined) { - if (!Array.isArray(message.filmstripConfig)) - return "filmstripConfig: array expected"; - for (var i = 0; i < message.filmstripConfig.length; ++i) { - var error = $types[62].verify(message.filmstripConfig[i]); + if (message.assetUuid !== undefined) + if (!$util.isString(message.assetUuid)) + return "assetUuid: string expected"; + if (message.isSaveLocked !== undefined) + if (typeof message.isSaveLocked !== "boolean") + return "isSaveLocked: boolean expected"; + if (message.children !== undefined) { + if (!Array.isArray(message.children)) + return "children: array expected"; + for (var i = 0; i < message.children.length; ++i) { + var error = $types[16].verify(message.children[i]); if (error) - return "filmstripConfig." + error; + return "children." + error; } } - if (message.showSigninButton !== undefined) - if (typeof message.showSigninButton !== "boolean") - return "showSigninButton: boolean expected"; - if (message.proMeasureUpsellUrl !== undefined && message.proMeasureUpsellUrl !== null) { - var error = $types[64].verify(message.proMeasureUpsellUrl); - if (error) - return "proMeasureUpsellUrl." + error; - } - if (message.proPrintUpsellUrl !== undefined && message.proPrintUpsellUrl !== null) { - var error = $types[65].verify(message.proPrintUpsellUrl); - if (error) - return "proPrintUpsellUrl." + error; - } - if (message.starDataProto !== undefined && message.starDataProto !== null) { - var error = $types[66].verify(message.starDataProto); - if (error) - return "starDataProto." + error; - } - if (message.feedbackUrl !== undefined && message.feedbackUrl !== null) { - var error = $types[67].verify(message.feedbackUrl); - if (error) - return "feedbackUrl." + error; - } - if (message.oauth2LoginUrl !== undefined && message.oauth2LoginUrl !== null) { - var error = $types[68].verify(message.oauth2LoginUrl); - if (error) - return "oauth2LoginUrl." + error; - } + if (message.clientConfigScriptName !== undefined) + if (!$util.isString(message.clientConfigScriptName)) + return "clientConfigScriptName: string expected"; + if (message.dioramaDataChannelBase !== undefined) + if (!$util.isInteger(message.dioramaDataChannelBase)) + return "dioramaDataChannelBase: integer expected"; + if (message.replicaDataChannelBase !== undefined) + if (!$util.isInteger(message.replicaDataChannelBase)) + return "replicaDataChannelBase: integer expected"; return null; }; - EndSnippetProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto) + NestedFeatureProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.NestedFeatureProto) return object; - var message = new $root.keyhole.dbroot.EndSnippetProto(); - if (object.model !== undefined && object.model !== null) { - if (typeof object.model !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.model: object expected"); - message.model = $types[0].fromObject(object.model); - } - if (object.authServerUrl !== undefined && object.authServerUrl !== null) { - if (typeof object.authServerUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.authServerUrl: object expected"); - message.authServerUrl = $types[1].fromObject(object.authServerUrl); - } - if (object.disableAuthentication !== undefined && object.disableAuthentication !== null) - message.disableAuthentication = Boolean(object.disableAuthentication); - if (object.mfeDomains) { - if (!Array.isArray(object.mfeDomains)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.mfeDomains: array expected"); - message.mfeDomains = []; - for (var i = 0; i < object.mfeDomains.length; ++i) { - if (typeof object.mfeDomains[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.mfeDomains: object expected"); - message.mfeDomains[i] = $types[3].fromObject(object.mfeDomains[i]); - } - } - if (object.mfeLangParam !== undefined && object.mfeLangParam !== null) - message.mfeLangParam = String(object.mfeLangParam); - if (object.adsUrlPatterns !== undefined && object.adsUrlPatterns !== null) - message.adsUrlPatterns = String(object.adsUrlPatterns); - if (object.reverseGeocoderUrl !== undefined && object.reverseGeocoderUrl !== null) { - if (typeof object.reverseGeocoderUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.reverseGeocoderUrl: object expected"); - message.reverseGeocoderUrl = $types[6].fromObject(object.reverseGeocoderUrl); - } - if (object.reverseGeocoderProtocolVersion !== undefined && object.reverseGeocoderProtocolVersion !== null) - message.reverseGeocoderProtocolVersion = object.reverseGeocoderProtocolVersion | 0; - if (object.skyDatabaseIsAvailable !== undefined && object.skyDatabaseIsAvailable !== null) - message.skyDatabaseIsAvailable = Boolean(object.skyDatabaseIsAvailable); - if (object.skyDatabaseUrl !== undefined && object.skyDatabaseUrl !== null) { - if (typeof object.skyDatabaseUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.skyDatabaseUrl: object expected"); - message.skyDatabaseUrl = $types[9].fromObject(object.skyDatabaseUrl); - } - if (object.defaultWebPageIntlUrl !== undefined && object.defaultWebPageIntlUrl !== null) { - if (typeof object.defaultWebPageIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.defaultWebPageIntlUrl: object expected"); - message.defaultWebPageIntlUrl = $types[10].fromObject(object.defaultWebPageIntlUrl); - } - if (object.numStartUpTips !== undefined && object.numStartUpTips !== null) - message.numStartUpTips = object.numStartUpTips | 0; - if (object.startUpTipsUrl !== undefined && object.startUpTipsUrl !== null) { - if (typeof object.startUpTipsUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.startUpTipsUrl: object expected"); - message.startUpTipsUrl = $types[12].fromObject(object.startUpTipsUrl); - } - if (object.numProStartUpTips !== undefined && object.numProStartUpTips !== null) - message.numProStartUpTips = object.numProStartUpTips | 0; - if (object.proStartUpTipsUrl !== undefined && object.proStartUpTipsUrl !== null) { - if (typeof object.proStartUpTipsUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.proStartUpTipsUrl: object expected"); - message.proStartUpTipsUrl = $types[14].fromObject(object.proStartUpTipsUrl); - } - if (object.startupTipsIntlUrl !== undefined && object.startupTipsIntlUrl !== null) { - if (typeof object.startupTipsIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.startupTipsIntlUrl: object expected"); - message.startupTipsIntlUrl = $types[15].fromObject(object.startupTipsIntlUrl); - } - if (object.userGuideIntlUrl !== undefined && object.userGuideIntlUrl !== null) { - if (typeof object.userGuideIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.userGuideIntlUrl: object expected"); - message.userGuideIntlUrl = $types[16].fromObject(object.userGuideIntlUrl); - } - if (object.supportCenterIntlUrl !== undefined && object.supportCenterIntlUrl !== null) { - if (typeof object.supportCenterIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.supportCenterIntlUrl: object expected"); - message.supportCenterIntlUrl = $types[17].fromObject(object.supportCenterIntlUrl); - } - if (object.businessListingIntlUrl !== undefined && object.businessListingIntlUrl !== null) { - if (typeof object.businessListingIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.businessListingIntlUrl: object expected"); - message.businessListingIntlUrl = $types[18].fromObject(object.businessListingIntlUrl); - } - if (object.supportAnswerIntlUrl !== undefined && object.supportAnswerIntlUrl !== null) { - if (typeof object.supportAnswerIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.supportAnswerIntlUrl: object expected"); - message.supportAnswerIntlUrl = $types[19].fromObject(object.supportAnswerIntlUrl); - } - if (object.supportTopicIntlUrl !== undefined && object.supportTopicIntlUrl !== null) { - if (typeof object.supportTopicIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.supportTopicIntlUrl: object expected"); - message.supportTopicIntlUrl = $types[20].fromObject(object.supportTopicIntlUrl); - } - if (object.supportRequestIntlUrl !== undefined && object.supportRequestIntlUrl !== null) { - if (typeof object.supportRequestIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.supportRequestIntlUrl: object expected"); - message.supportRequestIntlUrl = $types[21].fromObject(object.supportRequestIntlUrl); - } - if (object.earthIntlUrl !== undefined && object.earthIntlUrl !== null) { - if (typeof object.earthIntlUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.earthIntlUrl: object expected"); - message.earthIntlUrl = $types[22].fromObject(object.earthIntlUrl); - } - if (object.addContentUrl !== undefined && object.addContentUrl !== null) { - if (typeof object.addContentUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.addContentUrl: object expected"); - message.addContentUrl = $types[23].fromObject(object.addContentUrl); - } - if (object.sketchupNotInstalledUrl !== undefined && object.sketchupNotInstalledUrl !== null) { - if (typeof object.sketchupNotInstalledUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.sketchupNotInstalledUrl: object expected"); - message.sketchupNotInstalledUrl = $types[24].fromObject(object.sketchupNotInstalledUrl); - } - if (object.sketchupErrorUrl !== undefined && object.sketchupErrorUrl !== null) { - if (typeof object.sketchupErrorUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.sketchupErrorUrl: object expected"); - message.sketchupErrorUrl = $types[25].fromObject(object.sketchupErrorUrl); - } - if (object.freeLicenseUrl !== undefined && object.freeLicenseUrl !== null) { - if (typeof object.freeLicenseUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.freeLicenseUrl: object expected"); - message.freeLicenseUrl = $types[26].fromObject(object.freeLicenseUrl); - } - if (object.proLicenseUrl !== undefined && object.proLicenseUrl !== null) { - if (typeof object.proLicenseUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.proLicenseUrl: object expected"); - message.proLicenseUrl = $types[27].fromObject(object.proLicenseUrl); - } - if (object.tutorialUrl !== undefined && object.tutorialUrl !== null) { - if (typeof object.tutorialUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.tutorialUrl: object expected"); - message.tutorialUrl = $types[28].fromObject(object.tutorialUrl); - } - if (object.keyboardShortcutsUrl !== undefined && object.keyboardShortcutsUrl !== null) { - if (typeof object.keyboardShortcutsUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.keyboardShortcutsUrl: object expected"); - message.keyboardShortcutsUrl = $types[29].fromObject(object.keyboardShortcutsUrl); - } - if (object.releaseNotesUrl !== undefined && object.releaseNotesUrl !== null) { - if (typeof object.releaseNotesUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.releaseNotesUrl: object expected"); - message.releaseNotesUrl = $types[30].fromObject(object.releaseNotesUrl); - } - if (object.hideUserData !== undefined && object.hideUserData !== null) - message.hideUserData = Boolean(object.hideUserData); - if (object.useGeLogo !== undefined && object.useGeLogo !== null) - message.useGeLogo = Boolean(object.useGeLogo); - if (object.dioramaDescriptionUrlBase !== undefined && object.dioramaDescriptionUrlBase !== null) { - if (typeof object.dioramaDescriptionUrlBase !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaDescriptionUrlBase: object expected"); - message.dioramaDescriptionUrlBase = $types[33].fromObject(object.dioramaDescriptionUrlBase); - } - if (object.dioramaDefaultColor !== undefined && object.dioramaDefaultColor !== null) - message.dioramaDefaultColor = object.dioramaDefaultColor >>> 0; - if (object.dioramaBlacklistUrl !== undefined && object.dioramaBlacklistUrl !== null) { - if (typeof object.dioramaBlacklistUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaBlacklistUrl: object expected"); - message.dioramaBlacklistUrl = $types[35].fromObject(object.dioramaBlacklistUrl); - } - if (object.clientOptions !== undefined && object.clientOptions !== null) { - if (typeof object.clientOptions !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.clientOptions: object expected"); - message.clientOptions = $types[36].fromObject(object.clientOptions); - } - if (object.fetchingOptions !== undefined && object.fetchingOptions !== null) { - if (typeof object.fetchingOptions !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.fetchingOptions: object expected"); - message.fetchingOptions = $types[37].fromObject(object.fetchingOptions); - } - if (object.timeMachineOptions !== undefined && object.timeMachineOptions !== null) { - if (typeof object.timeMachineOptions !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.timeMachineOptions: object expected"); - message.timeMachineOptions = $types[38].fromObject(object.timeMachineOptions); - } - if (object.csiOptions !== undefined && object.csiOptions !== null) { - if (typeof object.csiOptions !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.csiOptions: object expected"); - message.csiOptions = $types[39].fromObject(object.csiOptions); - } - if (object.searchTab) { - if (!Array.isArray(object.searchTab)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: array expected"); - message.searchTab = []; - for (var i = 0; i < object.searchTab.length; ++i) { - if (typeof object.searchTab[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: object expected"); - message.searchTab[i] = $types[40].fromObject(object.searchTab[i]); - } - } - if (object.cobrandInfo) { - if (!Array.isArray(object.cobrandInfo)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.cobrandInfo: array expected"); - message.cobrandInfo = []; - for (var i = 0; i < object.cobrandInfo.length; ++i) { - if (typeof object.cobrandInfo[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.cobrandInfo: object expected"); - message.cobrandInfo[i] = $types[41].fromObject(object.cobrandInfo[i]); - } - } - if (object.validDatabase) { - if (!Array.isArray(object.validDatabase)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.validDatabase: array expected"); - message.validDatabase = []; - for (var i = 0; i < object.validDatabase.length; ++i) { - if (typeof object.validDatabase[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.validDatabase: object expected"); - message.validDatabase[i] = $types[42].fromObject(object.validDatabase[i]); - } - } - if (object.configScript) { - if (!Array.isArray(object.configScript)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.configScript: array expected"); - message.configScript = []; - for (var i = 0; i < object.configScript.length; ++i) { - if (typeof object.configScript[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.configScript: object expected"); - message.configScript[i] = $types[43].fromObject(object.configScript[i]); - } - } - if (object.deauthServerUrl !== undefined && object.deauthServerUrl !== null) { - if (typeof object.deauthServerUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.deauthServerUrl: object expected"); - message.deauthServerUrl = $types[44].fromObject(object.deauthServerUrl); - } - if (object.swoopParameters !== undefined && object.swoopParameters !== null) { - if (typeof object.swoopParameters !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.swoopParameters: object expected"); - message.swoopParameters = $types[45].fromObject(object.swoopParameters); - } - if (object.bbsServerInfo !== undefined && object.bbsServerInfo !== null) { - if (typeof object.bbsServerInfo !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.bbsServerInfo: object expected"); - message.bbsServerInfo = $types[46].fromObject(object.bbsServerInfo); - } - if (object.dataErrorServerInfo !== undefined && object.dataErrorServerInfo !== null) { - if (typeof object.dataErrorServerInfo !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.dataErrorServerInfo: object expected"); - message.dataErrorServerInfo = $types[47].fromObject(object.dataErrorServerInfo); - } - if (object.planetaryDatabase) { - if (!Array.isArray(object.planetaryDatabase)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.planetaryDatabase: array expected"); - message.planetaryDatabase = []; - for (var i = 0; i < object.planetaryDatabase.length; ++i) { - if (typeof object.planetaryDatabase[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.planetaryDatabase: object expected"); - message.planetaryDatabase[i] = $types[48].fromObject(object.planetaryDatabase[i]); - } - } - if (object.logServer !== undefined && object.logServer !== null) { - if (typeof object.logServer !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.logServer: object expected"); - message.logServer = $types[49].fromObject(object.logServer); - } - if (object.autopiaOptions !== undefined && object.autopiaOptions !== null) { - if (typeof object.autopiaOptions !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.autopiaOptions: object expected"); - message.autopiaOptions = $types[50].fromObject(object.autopiaOptions); - } - if (object.searchConfig !== undefined && object.searchConfig !== null) { - if (typeof object.searchConfig !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.searchConfig: object expected"); - message.searchConfig = $types[51].fromObject(object.searchConfig); + var message = new $root.keyhole.dbroot.NestedFeatureProto(); + switch (object.featureType) { + case "TYPE_POINT_Z": + case 1: + message.featureType = 1; + break; + case "TYPE_POLYGON_Z": + case 2: + message.featureType = 2; + break; + case "TYPE_LINE_Z": + case 3: + message.featureType = 3; + break; + case "TYPE_TERRAIN": + case 4: + message.featureType = 4; + break; } - if (object.searchInfo !== undefined && object.searchInfo !== null) { - if (typeof object.searchInfo !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.searchInfo: object expected"); - message.searchInfo = $types[52].fromObject(object.searchInfo); + if (object.kmlUrl !== undefined && object.kmlUrl !== null) { + if (typeof object.kmlUrl !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.kmlUrl: object expected"); + message.kmlUrl = $types[1].fromObject(object.kmlUrl); } - if (object.elevationServiceBaseUrl !== undefined && object.elevationServiceBaseUrl !== null) - message.elevationServiceBaseUrl = String(object.elevationServiceBaseUrl); - if (object.elevationProfileQueryDelay !== undefined && object.elevationProfileQueryDelay !== null) - message.elevationProfileQueryDelay = object.elevationProfileQueryDelay | 0; - if (object.proUpgradeUrl !== undefined && object.proUpgradeUrl !== null) { - if (typeof object.proUpgradeUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.proUpgradeUrl: object expected"); - message.proUpgradeUrl = $types[55].fromObject(object.proUpgradeUrl); + if (object.databaseUrl !== undefined && object.databaseUrl !== null) + message.databaseUrl = String(object.databaseUrl); + if (object.layer !== undefined && object.layer !== null) { + if (typeof object.layer !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.layer: object expected"); + message.layer = $types[3].fromObject(object.layer); } - if (object.earthCommunityUrl !== undefined && object.earthCommunityUrl !== null) { - if (typeof object.earthCommunityUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.earthCommunityUrl: object expected"); - message.earthCommunityUrl = $types[56].fromObject(object.earthCommunityUrl); + if (object.folder !== undefined && object.folder !== null) { + if (typeof object.folder !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.folder: object expected"); + message.folder = $types[4].fromObject(object.folder); } - if (object.googleMapsUrl !== undefined && object.googleMapsUrl !== null) { - if (typeof object.googleMapsUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.googleMapsUrl: object expected"); - message.googleMapsUrl = $types[57].fromObject(object.googleMapsUrl); + if (object.requirement !== undefined && object.requirement !== null) { + if (typeof object.requirement !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.requirement: object expected"); + message.requirement = $types[5].fromObject(object.requirement); } - if (object.sharingUrl !== undefined && object.sharingUrl !== null) { - if (typeof object.sharingUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.sharingUrl: object expected"); - message.sharingUrl = $types[58].fromObject(object.sharingUrl); + if (object.channelId !== undefined && object.channelId !== null) + message.channelId = object.channelId | 0; + if (object.displayName !== undefined && object.displayName !== null) { + if (typeof object.displayName !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.displayName: object expected"); + message.displayName = $types[7].fromObject(object.displayName); } - if (object.privacyPolicyUrl !== undefined && object.privacyPolicyUrl !== null) { - if (typeof object.privacyPolicyUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.privacyPolicyUrl: object expected"); - message.privacyPolicyUrl = $types[59].fromObject(object.privacyPolicyUrl); + if (object.isVisible !== undefined && object.isVisible !== null) + message.isVisible = Boolean(object.isVisible); + if (object.isEnabled !== undefined && object.isEnabled !== null) + message.isEnabled = Boolean(object.isEnabled); + if (object.isChecked !== undefined && object.isChecked !== null) + message.isChecked = Boolean(object.isChecked); + if (object.layerMenuIconPath !== undefined && object.layerMenuIconPath !== null) + message.layerMenuIconPath = String(object.layerMenuIconPath); + if (object.description !== undefined && object.description !== null) { + if (typeof object.description !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.description: object expected"); + message.description = $types[12].fromObject(object.description); } - if (object.doGplusUserCheck !== undefined && object.doGplusUserCheck !== null) - message.doGplusUserCheck = Boolean(object.doGplusUserCheck); - if (object.rocktreeDataProto !== undefined && object.rocktreeDataProto !== null) { - if (typeof object.rocktreeDataProto !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.rocktreeDataProto: object expected"); - message.rocktreeDataProto = $types[61].fromObject(object.rocktreeDataProto); + if (object.lookAt !== undefined && object.lookAt !== null) { + if (typeof object.lookAt !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.lookAt: object expected"); + message.lookAt = $types[13].fromObject(object.lookAt); } - if (object.filmstripConfig) { - if (!Array.isArray(object.filmstripConfig)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.filmstripConfig: array expected"); - message.filmstripConfig = []; - for (var i = 0; i < object.filmstripConfig.length; ++i) { - if (typeof object.filmstripConfig[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.filmstripConfig: object expected"); - message.filmstripConfig[i] = $types[62].fromObject(object.filmstripConfig[i]); + if (object.assetUuid !== undefined && object.assetUuid !== null) + message.assetUuid = String(object.assetUuid); + if (object.isSaveLocked !== undefined && object.isSaveLocked !== null) + message.isSaveLocked = Boolean(object.isSaveLocked); + if (object.children) { + if (!Array.isArray(object.children)) + throw TypeError(".keyhole.dbroot.NestedFeatureProto.children: array expected"); + message.children = []; + for (var i = 0; i < object.children.length; ++i) { + if (typeof object.children[i] !== "object") + throw TypeError(".keyhole.dbroot.NestedFeatureProto.children: object expected"); + message.children[i] = $types[16].fromObject(object.children[i]); } } - if (object.showSigninButton !== undefined && object.showSigninButton !== null) - message.showSigninButton = Boolean(object.showSigninButton); - if (object.proMeasureUpsellUrl !== undefined && object.proMeasureUpsellUrl !== null) { - if (typeof object.proMeasureUpsellUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.proMeasureUpsellUrl: object expected"); - message.proMeasureUpsellUrl = $types[64].fromObject(object.proMeasureUpsellUrl); - } - if (object.proPrintUpsellUrl !== undefined && object.proPrintUpsellUrl !== null) { - if (typeof object.proPrintUpsellUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.proPrintUpsellUrl: object expected"); - message.proPrintUpsellUrl = $types[65].fromObject(object.proPrintUpsellUrl); - } - if (object.starDataProto !== undefined && object.starDataProto !== null) { - if (typeof object.starDataProto !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.starDataProto: object expected"); - message.starDataProto = $types[66].fromObject(object.starDataProto); - } - if (object.feedbackUrl !== undefined && object.feedbackUrl !== null) { - if (typeof object.feedbackUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.feedbackUrl: object expected"); - message.feedbackUrl = $types[67].fromObject(object.feedbackUrl); - } - if (object.oauth2LoginUrl !== undefined && object.oauth2LoginUrl !== null) { - if (typeof object.oauth2LoginUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.oauth2LoginUrl: object expected"); - message.oauth2LoginUrl = $types[68].fromObject(object.oauth2LoginUrl); - } + if (object.clientConfigScriptName !== undefined && object.clientConfigScriptName !== null) + message.clientConfigScriptName = String(object.clientConfigScriptName); + if (object.dioramaDataChannelBase !== undefined && object.dioramaDataChannelBase !== null) + message.dioramaDataChannelBase = object.dioramaDataChannelBase | 0; + if (object.replicaDataChannelBase !== undefined && object.replicaDataChannelBase !== null) + message.replicaDataChannelBase = object.replicaDataChannelBase | 0; return message; }; - EndSnippetProto.from = EndSnippetProto.fromObject; + NestedFeatureProto.from = NestedFeatureProto.fromObject; - EndSnippetProto.toObject = function toObject(message, options) { + NestedFeatureProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) { - object.mfeDomains = []; - object.searchTab = []; - object.cobrandInfo = []; - object.validDatabase = []; - object.configScript = []; - object.planetaryDatabase = []; - object.filmstripConfig = []; - } + if (options.arrays || options.defaults) + object.children = []; if (options.defaults) { - object.model = null; - object.authServerUrl = null; - object.disableAuthentication = false; - object.mfeLangParam = "hl=$5Bhl5D"; - object.adsUrlPatterns = ""; - object.reverseGeocoderUrl = null; - object.reverseGeocoderProtocolVersion = 3; - object.skyDatabaseIsAvailable = true; - object.skyDatabaseUrl = null; - object.defaultWebPageIntlUrl = null; - object.numStartUpTips = 17; - object.startUpTipsUrl = null; - object.numProStartUpTips = 0; - object.proStartUpTipsUrl = null; - object.startupTipsIntlUrl = null; - object.userGuideIntlUrl = null; - object.supportCenterIntlUrl = null; - object.businessListingIntlUrl = null; - object.supportAnswerIntlUrl = null; - object.supportTopicIntlUrl = null; - object.supportRequestIntlUrl = null; - object.earthIntlUrl = null; - object.addContentUrl = null; - object.sketchupNotInstalledUrl = null; - object.sketchupErrorUrl = null; - object.freeLicenseUrl = null; - object.proLicenseUrl = null; - object.tutorialUrl = null; - object.keyboardShortcutsUrl = null; - object.releaseNotesUrl = null; - object.hideUserData = false; - object.useGeLogo = true; - object.dioramaDescriptionUrlBase = null; - object.dioramaDefaultColor = 4291281607; - object.dioramaBlacklistUrl = null; - object.clientOptions = null; - object.fetchingOptions = null; - object.timeMachineOptions = null; - object.csiOptions = null; - object.deauthServerUrl = null; - object.swoopParameters = null; - object.bbsServerInfo = null; - object.dataErrorServerInfo = null; - object.logServer = null; - object.autopiaOptions = null; - object.searchConfig = null; - object.searchInfo = null; - object.elevationServiceBaseUrl = "http://maps.google.com/maps/api/elevation/"; - object.elevationProfileQueryDelay = 500; - object.proUpgradeUrl = null; - object.earthCommunityUrl = null; - object.googleMapsUrl = null; - object.sharingUrl = null; - object.privacyPolicyUrl = null; - object.doGplusUserCheck = false; - object.rocktreeDataProto = null; - object.showSigninButton = false; - object.proMeasureUpsellUrl = null; - object.proPrintUpsellUrl = null; - object.starDataProto = null; - object.feedbackUrl = null; - object.oauth2LoginUrl = null; - } - if (message.model !== undefined && message.model !== null && message.hasOwnProperty("model")) - object.model = $types[0].toObject(message.model, options); - if (message.authServerUrl !== undefined && message.authServerUrl !== null && message.hasOwnProperty("authServerUrl")) - object.authServerUrl = $types[1].toObject(message.authServerUrl, options); - if (message.disableAuthentication !== undefined && message.disableAuthentication !== null && message.hasOwnProperty("disableAuthentication")) - object.disableAuthentication = message.disableAuthentication; - if (message.mfeDomains !== undefined && message.mfeDomains !== null && message.hasOwnProperty("mfeDomains")) { - object.mfeDomains = []; - for (var j = 0; j < message.mfeDomains.length; ++j) - object.mfeDomains[j] = $types[3].toObject(message.mfeDomains[j], options); - } - if (message.mfeLangParam !== undefined && message.mfeLangParam !== null && message.hasOwnProperty("mfeLangParam")) - object.mfeLangParam = message.mfeLangParam; - if (message.adsUrlPatterns !== undefined && message.adsUrlPatterns !== null && message.hasOwnProperty("adsUrlPatterns")) - object.adsUrlPatterns = message.adsUrlPatterns; - if (message.reverseGeocoderUrl !== undefined && message.reverseGeocoderUrl !== null && message.hasOwnProperty("reverseGeocoderUrl")) - object.reverseGeocoderUrl = $types[6].toObject(message.reverseGeocoderUrl, options); - if (message.reverseGeocoderProtocolVersion !== undefined && message.reverseGeocoderProtocolVersion !== null && message.hasOwnProperty("reverseGeocoderProtocolVersion")) - object.reverseGeocoderProtocolVersion = message.reverseGeocoderProtocolVersion; - if (message.skyDatabaseIsAvailable !== undefined && message.skyDatabaseIsAvailable !== null && message.hasOwnProperty("skyDatabaseIsAvailable")) - object.skyDatabaseIsAvailable = message.skyDatabaseIsAvailable; - if (message.skyDatabaseUrl !== undefined && message.skyDatabaseUrl !== null && message.hasOwnProperty("skyDatabaseUrl")) - object.skyDatabaseUrl = $types[9].toObject(message.skyDatabaseUrl, options); - if (message.defaultWebPageIntlUrl !== undefined && message.defaultWebPageIntlUrl !== null && message.hasOwnProperty("defaultWebPageIntlUrl")) - object.defaultWebPageIntlUrl = $types[10].toObject(message.defaultWebPageIntlUrl, options); - if (message.numStartUpTips !== undefined && message.numStartUpTips !== null && message.hasOwnProperty("numStartUpTips")) - object.numStartUpTips = message.numStartUpTips; - if (message.startUpTipsUrl !== undefined && message.startUpTipsUrl !== null && message.hasOwnProperty("startUpTipsUrl")) - object.startUpTipsUrl = $types[12].toObject(message.startUpTipsUrl, options); - if (message.numProStartUpTips !== undefined && message.numProStartUpTips !== null && message.hasOwnProperty("numProStartUpTips")) - object.numProStartUpTips = message.numProStartUpTips; - if (message.proStartUpTipsUrl !== undefined && message.proStartUpTipsUrl !== null && message.hasOwnProperty("proStartUpTipsUrl")) - object.proStartUpTipsUrl = $types[14].toObject(message.proStartUpTipsUrl, options); - if (message.startupTipsIntlUrl !== undefined && message.startupTipsIntlUrl !== null && message.hasOwnProperty("startupTipsIntlUrl")) - object.startupTipsIntlUrl = $types[15].toObject(message.startupTipsIntlUrl, options); - if (message.userGuideIntlUrl !== undefined && message.userGuideIntlUrl !== null && message.hasOwnProperty("userGuideIntlUrl")) - object.userGuideIntlUrl = $types[16].toObject(message.userGuideIntlUrl, options); - if (message.supportCenterIntlUrl !== undefined && message.supportCenterIntlUrl !== null && message.hasOwnProperty("supportCenterIntlUrl")) - object.supportCenterIntlUrl = $types[17].toObject(message.supportCenterIntlUrl, options); - if (message.businessListingIntlUrl !== undefined && message.businessListingIntlUrl !== null && message.hasOwnProperty("businessListingIntlUrl")) - object.businessListingIntlUrl = $types[18].toObject(message.businessListingIntlUrl, options); - if (message.supportAnswerIntlUrl !== undefined && message.supportAnswerIntlUrl !== null && message.hasOwnProperty("supportAnswerIntlUrl")) - object.supportAnswerIntlUrl = $types[19].toObject(message.supportAnswerIntlUrl, options); - if (message.supportTopicIntlUrl !== undefined && message.supportTopicIntlUrl !== null && message.hasOwnProperty("supportTopicIntlUrl")) - object.supportTopicIntlUrl = $types[20].toObject(message.supportTopicIntlUrl, options); - if (message.supportRequestIntlUrl !== undefined && message.supportRequestIntlUrl !== null && message.hasOwnProperty("supportRequestIntlUrl")) - object.supportRequestIntlUrl = $types[21].toObject(message.supportRequestIntlUrl, options); - if (message.earthIntlUrl !== undefined && message.earthIntlUrl !== null && message.hasOwnProperty("earthIntlUrl")) - object.earthIntlUrl = $types[22].toObject(message.earthIntlUrl, options); - if (message.addContentUrl !== undefined && message.addContentUrl !== null && message.hasOwnProperty("addContentUrl")) - object.addContentUrl = $types[23].toObject(message.addContentUrl, options); - if (message.sketchupNotInstalledUrl !== undefined && message.sketchupNotInstalledUrl !== null && message.hasOwnProperty("sketchupNotInstalledUrl")) - object.sketchupNotInstalledUrl = $types[24].toObject(message.sketchupNotInstalledUrl, options); - if (message.sketchupErrorUrl !== undefined && message.sketchupErrorUrl !== null && message.hasOwnProperty("sketchupErrorUrl")) - object.sketchupErrorUrl = $types[25].toObject(message.sketchupErrorUrl, options); - if (message.freeLicenseUrl !== undefined && message.freeLicenseUrl !== null && message.hasOwnProperty("freeLicenseUrl")) - object.freeLicenseUrl = $types[26].toObject(message.freeLicenseUrl, options); - if (message.proLicenseUrl !== undefined && message.proLicenseUrl !== null && message.hasOwnProperty("proLicenseUrl")) - object.proLicenseUrl = $types[27].toObject(message.proLicenseUrl, options); - if (message.tutorialUrl !== undefined && message.tutorialUrl !== null && message.hasOwnProperty("tutorialUrl")) - object.tutorialUrl = $types[28].toObject(message.tutorialUrl, options); - if (message.keyboardShortcutsUrl !== undefined && message.keyboardShortcutsUrl !== null && message.hasOwnProperty("keyboardShortcutsUrl")) - object.keyboardShortcutsUrl = $types[29].toObject(message.keyboardShortcutsUrl, options); - if (message.releaseNotesUrl !== undefined && message.releaseNotesUrl !== null && message.hasOwnProperty("releaseNotesUrl")) - object.releaseNotesUrl = $types[30].toObject(message.releaseNotesUrl, options); - if (message.hideUserData !== undefined && message.hideUserData !== null && message.hasOwnProperty("hideUserData")) - object.hideUserData = message.hideUserData; - if (message.useGeLogo !== undefined && message.useGeLogo !== null && message.hasOwnProperty("useGeLogo")) - object.useGeLogo = message.useGeLogo; - if (message.dioramaDescriptionUrlBase !== undefined && message.dioramaDescriptionUrlBase !== null && message.hasOwnProperty("dioramaDescriptionUrlBase")) - object.dioramaDescriptionUrlBase = $types[33].toObject(message.dioramaDescriptionUrlBase, options); - if (message.dioramaDefaultColor !== undefined && message.dioramaDefaultColor !== null && message.hasOwnProperty("dioramaDefaultColor")) - object.dioramaDefaultColor = message.dioramaDefaultColor; - if (message.dioramaBlacklistUrl !== undefined && message.dioramaBlacklistUrl !== null && message.hasOwnProperty("dioramaBlacklistUrl")) - object.dioramaBlacklistUrl = $types[35].toObject(message.dioramaBlacklistUrl, options); - if (message.clientOptions !== undefined && message.clientOptions !== null && message.hasOwnProperty("clientOptions")) - object.clientOptions = $types[36].toObject(message.clientOptions, options); - if (message.fetchingOptions !== undefined && message.fetchingOptions !== null && message.hasOwnProperty("fetchingOptions")) - object.fetchingOptions = $types[37].toObject(message.fetchingOptions, options); - if (message.timeMachineOptions !== undefined && message.timeMachineOptions !== null && message.hasOwnProperty("timeMachineOptions")) - object.timeMachineOptions = $types[38].toObject(message.timeMachineOptions, options); - if (message.csiOptions !== undefined && message.csiOptions !== null && message.hasOwnProperty("csiOptions")) - object.csiOptions = $types[39].toObject(message.csiOptions, options); - if (message.searchTab !== undefined && message.searchTab !== null && message.hasOwnProperty("searchTab")) { - object.searchTab = []; - for (var j = 0; j < message.searchTab.length; ++j) - object.searchTab[j] = $types[40].toObject(message.searchTab[j], options); - } - if (message.cobrandInfo !== undefined && message.cobrandInfo !== null && message.hasOwnProperty("cobrandInfo")) { - object.cobrandInfo = []; - for (var j = 0; j < message.cobrandInfo.length; ++j) - object.cobrandInfo[j] = $types[41].toObject(message.cobrandInfo[j], options); - } - if (message.validDatabase !== undefined && message.validDatabase !== null && message.hasOwnProperty("validDatabase")) { - object.validDatabase = []; - for (var j = 0; j < message.validDatabase.length; ++j) - object.validDatabase[j] = $types[42].toObject(message.validDatabase[j], options); - } - if (message.configScript !== undefined && message.configScript !== null && message.hasOwnProperty("configScript")) { - object.configScript = []; - for (var j = 0; j < message.configScript.length; ++j) - object.configScript[j] = $types[43].toObject(message.configScript[j], options); - } - if (message.deauthServerUrl !== undefined && message.deauthServerUrl !== null && message.hasOwnProperty("deauthServerUrl")) - object.deauthServerUrl = $types[44].toObject(message.deauthServerUrl, options); - if (message.swoopParameters !== undefined && message.swoopParameters !== null && message.hasOwnProperty("swoopParameters")) - object.swoopParameters = $types[45].toObject(message.swoopParameters, options); - if (message.bbsServerInfo !== undefined && message.bbsServerInfo !== null && message.hasOwnProperty("bbsServerInfo")) - object.bbsServerInfo = $types[46].toObject(message.bbsServerInfo, options); - if (message.dataErrorServerInfo !== undefined && message.dataErrorServerInfo !== null && message.hasOwnProperty("dataErrorServerInfo")) - object.dataErrorServerInfo = $types[47].toObject(message.dataErrorServerInfo, options); - if (message.planetaryDatabase !== undefined && message.planetaryDatabase !== null && message.hasOwnProperty("planetaryDatabase")) { - object.planetaryDatabase = []; - for (var j = 0; j < message.planetaryDatabase.length; ++j) - object.planetaryDatabase[j] = $types[48].toObject(message.planetaryDatabase[j], options); + object.featureType = options.enums === String ? "TYPE_POINT_Z" : 1; + object.kmlUrl = null; + object.databaseUrl = ""; + object.layer = null; + object.folder = null; + object.requirement = null; + object.channelId = 0; + object.displayName = null; + object.isVisible = true; + object.isEnabled = true; + object.isChecked = false; + object.layerMenuIconPath = "icons/773_l.png"; + object.description = null; + object.lookAt = null; + object.assetUuid = ""; + object.isSaveLocked = true; + object.clientConfigScriptName = ""; + object.dioramaDataChannelBase = -1; + object.replicaDataChannelBase = -1; } - if (message.logServer !== undefined && message.logServer !== null && message.hasOwnProperty("logServer")) - object.logServer = $types[49].toObject(message.logServer, options); - if (message.autopiaOptions !== undefined && message.autopiaOptions !== null && message.hasOwnProperty("autopiaOptions")) - object.autopiaOptions = $types[50].toObject(message.autopiaOptions, options); - if (message.searchConfig !== undefined && message.searchConfig !== null && message.hasOwnProperty("searchConfig")) - object.searchConfig = $types[51].toObject(message.searchConfig, options); - if (message.searchInfo !== undefined && message.searchInfo !== null && message.hasOwnProperty("searchInfo")) - object.searchInfo = $types[52].toObject(message.searchInfo, options); - if (message.elevationServiceBaseUrl !== undefined && message.elevationServiceBaseUrl !== null && message.hasOwnProperty("elevationServiceBaseUrl")) - object.elevationServiceBaseUrl = message.elevationServiceBaseUrl; - if (message.elevationProfileQueryDelay !== undefined && message.elevationProfileQueryDelay !== null && message.hasOwnProperty("elevationProfileQueryDelay")) - object.elevationProfileQueryDelay = message.elevationProfileQueryDelay; - if (message.proUpgradeUrl !== undefined && message.proUpgradeUrl !== null && message.hasOwnProperty("proUpgradeUrl")) - object.proUpgradeUrl = $types[55].toObject(message.proUpgradeUrl, options); - if (message.earthCommunityUrl !== undefined && message.earthCommunityUrl !== null && message.hasOwnProperty("earthCommunityUrl")) - object.earthCommunityUrl = $types[56].toObject(message.earthCommunityUrl, options); - if (message.googleMapsUrl !== undefined && message.googleMapsUrl !== null && message.hasOwnProperty("googleMapsUrl")) - object.googleMapsUrl = $types[57].toObject(message.googleMapsUrl, options); - if (message.sharingUrl !== undefined && message.sharingUrl !== null && message.hasOwnProperty("sharingUrl")) - object.sharingUrl = $types[58].toObject(message.sharingUrl, options); - if (message.privacyPolicyUrl !== undefined && message.privacyPolicyUrl !== null && message.hasOwnProperty("privacyPolicyUrl")) - object.privacyPolicyUrl = $types[59].toObject(message.privacyPolicyUrl, options); - if (message.doGplusUserCheck !== undefined && message.doGplusUserCheck !== null && message.hasOwnProperty("doGplusUserCheck")) - object.doGplusUserCheck = message.doGplusUserCheck; - if (message.rocktreeDataProto !== undefined && message.rocktreeDataProto !== null && message.hasOwnProperty("rocktreeDataProto")) - object.rocktreeDataProto = $types[61].toObject(message.rocktreeDataProto, options); - if (message.filmstripConfig !== undefined && message.filmstripConfig !== null && message.hasOwnProperty("filmstripConfig")) { - object.filmstripConfig = []; - for (var j = 0; j < message.filmstripConfig.length; ++j) - object.filmstripConfig[j] = $types[62].toObject(message.filmstripConfig[j], options); + if (message.featureType !== undefined && message.featureType !== null && message.hasOwnProperty("featureType")) + object.featureType = options.enums === String ? $types[0][message.featureType] : message.featureType; + if (message.kmlUrl !== undefined && message.kmlUrl !== null && message.hasOwnProperty("kmlUrl")) + object.kmlUrl = $types[1].toObject(message.kmlUrl, options); + if (message.databaseUrl !== undefined && message.databaseUrl !== null && message.hasOwnProperty("databaseUrl")) + object.databaseUrl = message.databaseUrl; + if (message.layer !== undefined && message.layer !== null && message.hasOwnProperty("layer")) + object.layer = $types[3].toObject(message.layer, options); + if (message.folder !== undefined && message.folder !== null && message.hasOwnProperty("folder")) + object.folder = $types[4].toObject(message.folder, options); + if (message.requirement !== undefined && message.requirement !== null && message.hasOwnProperty("requirement")) + object.requirement = $types[5].toObject(message.requirement, options); + if (message.channelId !== undefined && message.channelId !== null && message.hasOwnProperty("channelId")) + object.channelId = message.channelId; + if (message.displayName !== undefined && message.displayName !== null && message.hasOwnProperty("displayName")) + object.displayName = $types[7].toObject(message.displayName, options); + if (message.isVisible !== undefined && message.isVisible !== null && message.hasOwnProperty("isVisible")) + object.isVisible = message.isVisible; + if (message.isEnabled !== undefined && message.isEnabled !== null && message.hasOwnProperty("isEnabled")) + object.isEnabled = message.isEnabled; + if (message.isChecked !== undefined && message.isChecked !== null && message.hasOwnProperty("isChecked")) + object.isChecked = message.isChecked; + if (message.layerMenuIconPath !== undefined && message.layerMenuIconPath !== null && message.hasOwnProperty("layerMenuIconPath")) + object.layerMenuIconPath = message.layerMenuIconPath; + if (message.description !== undefined && message.description !== null && message.hasOwnProperty("description")) + object.description = $types[12].toObject(message.description, options); + if (message.lookAt !== undefined && message.lookAt !== null && message.hasOwnProperty("lookAt")) + object.lookAt = $types[13].toObject(message.lookAt, options); + if (message.assetUuid !== undefined && message.assetUuid !== null && message.hasOwnProperty("assetUuid")) + object.assetUuid = message.assetUuid; + if (message.isSaveLocked !== undefined && message.isSaveLocked !== null && message.hasOwnProperty("isSaveLocked")) + object.isSaveLocked = message.isSaveLocked; + if (message.children !== undefined && message.children !== null && message.hasOwnProperty("children")) { + object.children = []; + for (var j = 0; j < message.children.length; ++j) + object.children[j] = $types[16].toObject(message.children[j], options); } - if (message.showSigninButton !== undefined && message.showSigninButton !== null && message.hasOwnProperty("showSigninButton")) - object.showSigninButton = message.showSigninButton; - if (message.proMeasureUpsellUrl !== undefined && message.proMeasureUpsellUrl !== null && message.hasOwnProperty("proMeasureUpsellUrl")) - object.proMeasureUpsellUrl = $types[64].toObject(message.proMeasureUpsellUrl, options); - if (message.proPrintUpsellUrl !== undefined && message.proPrintUpsellUrl !== null && message.hasOwnProperty("proPrintUpsellUrl")) - object.proPrintUpsellUrl = $types[65].toObject(message.proPrintUpsellUrl, options); - if (message.starDataProto !== undefined && message.starDataProto !== null && message.hasOwnProperty("starDataProto")) - object.starDataProto = $types[66].toObject(message.starDataProto, options); - if (message.feedbackUrl !== undefined && message.feedbackUrl !== null && message.hasOwnProperty("feedbackUrl")) - object.feedbackUrl = $types[67].toObject(message.feedbackUrl, options); - if (message.oauth2LoginUrl !== undefined && message.oauth2LoginUrl !== null && message.hasOwnProperty("oauth2LoginUrl")) - object.oauth2LoginUrl = $types[68].toObject(message.oauth2LoginUrl, options); + if (message.clientConfigScriptName !== undefined && message.clientConfigScriptName !== null && message.hasOwnProperty("clientConfigScriptName")) + object.clientConfigScriptName = message.clientConfigScriptName; + if (message.dioramaDataChannelBase !== undefined && message.dioramaDataChannelBase !== null && message.hasOwnProperty("dioramaDataChannelBase")) + object.dioramaDataChannelBase = message.dioramaDataChannelBase; + if (message.replicaDataChannelBase !== undefined && message.replicaDataChannelBase !== null && message.hasOwnProperty("replicaDataChannelBase")) + object.replicaDataChannelBase = message.replicaDataChannelBase; return object; }; - EndSnippetProto.prototype.toObject = function toObject(options) { + NestedFeatureProto.prototype.toObject = function toObject(options) { return this.constructor.toObject(this, options); }; - EndSnippetProto.prototype.toJSON = function toJSON() { + NestedFeatureProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - EndSnippetProto.SearchConfigProto = (function() { + NestedFeatureProto.FeatureType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values["TYPE_POINT_Z"] = 1; + values["TYPE_POLYGON_Z"] = 2; + values["TYPE_LINE_Z"] = 3; + values["TYPE_TERRAIN"] = 4; + return values; + })(); - function SearchConfigProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + return NestedFeatureProto; + })(); - SearchConfigProto.prototype.searchServer = $util.emptyArray; - SearchConfigProto.prototype.oneboxService = $util.emptyArray; - SearchConfigProto.prototype.kmlSearchUrl = null; - SearchConfigProto.prototype.kmlRenderUrl = null; - SearchConfigProto.prototype.searchHistoryUrl = null; - SearchConfigProto.prototype.errorPageUrl = null; + dbroot.MfeDomainFeaturesProto = (function() { - var $types = { - 0 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer", - 1 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto", - 2 : "keyhole.dbroot.StringIdOrValueProto", - 3 : "keyhole.dbroot.StringIdOrValueProto", - 4 : "keyhole.dbroot.StringIdOrValueProto", - 5 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); + function MfeDomainFeaturesProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - SearchConfigProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { + MfeDomainFeaturesProto.prototype.countryCode = ""; + MfeDomainFeaturesProto.prototype.domainName = ""; + MfeDomainFeaturesProto.prototype.supportedFeatures = $util.emptyArray; + + var $types = { + 2 : "keyhole.dbroot.MfeDomainFeaturesProto.SupportedFeature" + }; + $lazyTypes.push($types); + + MfeDomainFeaturesProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.MfeDomainFeaturesProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.countryCode = reader.string(); + break; + case 2: + message.domainName = reader.string(); + break; + case 3: + if (!(message.supportedFeatures && message.supportedFeatures.length)) + message.supportedFeatures = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.supportedFeatures.push(reader.uint32()); + } else + message.supportedFeatures.push(reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + MfeDomainFeaturesProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.countryCode)) + return "countryCode: string expected"; + if (!$util.isString(message.domainName)) + return "domainName: string expected"; + if (message.supportedFeatures !== undefined) { + if (!Array.isArray(message.supportedFeatures)) + return "supportedFeatures: array expected"; + for (var i = 0; i < message.supportedFeatures.length; ++i) + switch (message.supportedFeatures[i]) { + default: + return "supportedFeatures: enum value[] expected"; + case 0: case 1: - if (!(message.searchServer && message.searchServer.length)) - message.searchServer = []; - message.searchServer.push($types[0].decode(reader, reader.uint32())); - break; case 2: - if (!(message.oneboxService && message.oneboxService.length)) - message.oneboxService = []; - message.oneboxService.push($types[1].decode(reader, reader.uint32())); break; - case 3: - message.kmlSearchUrl = $types[2].decode(reader, reader.uint32()); - break; - case 4: - message.kmlRenderUrl = $types[3].decode(reader, reader.uint32()); - break; - case 6: - message.searchHistoryUrl = $types[4].decode(reader, reader.uint32()); + } + } + return null; + }; + + MfeDomainFeaturesProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.MfeDomainFeaturesProto) + return object; + var message = new $root.keyhole.dbroot.MfeDomainFeaturesProto(); + if (object.countryCode !== undefined && object.countryCode !== null) + message.countryCode = String(object.countryCode); + if (object.domainName !== undefined && object.domainName !== null) + message.domainName = String(object.domainName); + if (object.supportedFeatures) { + if (!Array.isArray(object.supportedFeatures)) + throw TypeError(".keyhole.dbroot.MfeDomainFeaturesProto.supportedFeatures: array expected"); + message.supportedFeatures = []; + for (var i = 0; i < object.supportedFeatures.length; ++i) + switch (object.supportedFeatures[i]) { + default: + case "GEOCODING": + case 0: + message.supportedFeatures[i] = 0; break; - case 5: - message.errorPageUrl = $types[5].decode(reader, reader.uint32()); + case "LOCAL_SEARCH": + case 1: + message.supportedFeatures[i] = 1; break; - default: - reader.skipType(tag & 7); + case "DRIVING_DIRECTIONS": + case 2: + message.supportedFeatures[i] = 2; break; } - } - return message; - }; + } + return message; + }; - SearchConfigProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.searchServer !== undefined) { - if (!Array.isArray(message.searchServer)) - return "searchServer: array expected"; - for (var i = 0; i < message.searchServer.length; ++i) { - var error = $types[0].verify(message.searchServer[i]); - if (error) - return "searchServer." + error; - } - } - if (message.oneboxService !== undefined) { - if (!Array.isArray(message.oneboxService)) - return "oneboxService: array expected"; - for (var i = 0; i < message.oneboxService.length; ++i) { - var error = $types[1].verify(message.oneboxService[i]); - if (error) - return "oneboxService." + error; - } - } - if (message.kmlSearchUrl !== undefined && message.kmlSearchUrl !== null) { - var error = $types[2].verify(message.kmlSearchUrl); - if (error) - return "kmlSearchUrl." + error; - } - if (message.kmlRenderUrl !== undefined && message.kmlRenderUrl !== null) { - var error = $types[3].verify(message.kmlRenderUrl); - if (error) - return "kmlRenderUrl." + error; - } - if (message.searchHistoryUrl !== undefined && message.searchHistoryUrl !== null) { - var error = $types[4].verify(message.searchHistoryUrl); - if (error) - return "searchHistoryUrl." + error; - } - if (message.errorPageUrl !== undefined && message.errorPageUrl !== null) { - var error = $types[5].verify(message.errorPageUrl); - if (error) - return "errorPageUrl." + error; - } - return null; - }; + MfeDomainFeaturesProto.from = MfeDomainFeaturesProto.fromObject; - SearchConfigProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto(); - if (object.searchServer) { - if (!Array.isArray(object.searchServer)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchServer: array expected"); - message.searchServer = []; - for (var i = 0; i < object.searchServer.length; ++i) { - if (typeof object.searchServer[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchServer: object expected"); - message.searchServer[i] = $types[0].fromObject(object.searchServer[i]); - } - } - if (object.oneboxService) { - if (!Array.isArray(object.oneboxService)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.oneboxService: array expected"); - message.oneboxService = []; - for (var i = 0; i < object.oneboxService.length; ++i) { - if (typeof object.oneboxService[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.oneboxService: object expected"); - message.oneboxService[i] = $types[1].fromObject(object.oneboxService[i]); - } - } - if (object.kmlSearchUrl !== undefined && object.kmlSearchUrl !== null) { - if (typeof object.kmlSearchUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.kmlSearchUrl: object expected"); - message.kmlSearchUrl = $types[2].fromObject(object.kmlSearchUrl); - } - if (object.kmlRenderUrl !== undefined && object.kmlRenderUrl !== null) { - if (typeof object.kmlRenderUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.kmlRenderUrl: object expected"); - message.kmlRenderUrl = $types[3].fromObject(object.kmlRenderUrl); - } - if (object.searchHistoryUrl !== undefined && object.searchHistoryUrl !== null) { - if (typeof object.searchHistoryUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchHistoryUrl: object expected"); - message.searchHistoryUrl = $types[4].fromObject(object.searchHistoryUrl); - } - if (object.errorPageUrl !== undefined && object.errorPageUrl !== null) { - if (typeof object.errorPageUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.errorPageUrl: object expected"); - message.errorPageUrl = $types[5].fromObject(object.errorPageUrl); - } - return message; - }; + MfeDomainFeaturesProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.supportedFeatures = []; + if (options.defaults) { + object.countryCode = ""; + object.domainName = ""; + } + if (message.countryCode !== undefined && message.countryCode !== null && message.hasOwnProperty("countryCode")) + object.countryCode = message.countryCode; + if (message.domainName !== undefined && message.domainName !== null && message.hasOwnProperty("domainName")) + object.domainName = message.domainName; + if (message.supportedFeatures !== undefined && message.supportedFeatures !== null && message.hasOwnProperty("supportedFeatures")) { + object.supportedFeatures = []; + for (var j = 0; j < message.supportedFeatures.length; ++j) + object.supportedFeatures[j] = options.enums === String ? $types[2][message.supportedFeatures[j]] : message.supportedFeatures[j]; + } + return object; + }; - SearchConfigProto.from = SearchConfigProto.fromObject; + MfeDomainFeaturesProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - SearchConfigProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.searchServer = []; - object.oneboxService = []; - } - if (options.defaults) { - object.kmlSearchUrl = null; - object.kmlRenderUrl = null; - object.searchHistoryUrl = null; - object.errorPageUrl = null; - } - if (message.searchServer !== undefined && message.searchServer !== null && message.hasOwnProperty("searchServer")) { - object.searchServer = []; - for (var j = 0; j < message.searchServer.length; ++j) - object.searchServer[j] = $types[0].toObject(message.searchServer[j], options); - } - if (message.oneboxService !== undefined && message.oneboxService !== null && message.hasOwnProperty("oneboxService")) { - object.oneboxService = []; - for (var j = 0; j < message.oneboxService.length; ++j) - object.oneboxService[j] = $types[1].toObject(message.oneboxService[j], options); - } - if (message.kmlSearchUrl !== undefined && message.kmlSearchUrl !== null && message.hasOwnProperty("kmlSearchUrl")) - object.kmlSearchUrl = $types[2].toObject(message.kmlSearchUrl, options); - if (message.kmlRenderUrl !== undefined && message.kmlRenderUrl !== null && message.hasOwnProperty("kmlRenderUrl")) - object.kmlRenderUrl = $types[3].toObject(message.kmlRenderUrl, options); - if (message.searchHistoryUrl !== undefined && message.searchHistoryUrl !== null && message.hasOwnProperty("searchHistoryUrl")) - object.searchHistoryUrl = $types[4].toObject(message.searchHistoryUrl, options); - if (message.errorPageUrl !== undefined && message.errorPageUrl !== null && message.hasOwnProperty("errorPageUrl")) - object.errorPageUrl = $types[5].toObject(message.errorPageUrl, options); - return object; - }; + MfeDomainFeaturesProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - SearchConfigProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + MfeDomainFeaturesProto.SupportedFeature = (function() { + var valuesById = {}, values = Object.create(valuesById); + values["GEOCODING"] = 0; + values["LOCAL_SEARCH"] = 1; + values["DRIVING_DIRECTIONS"] = 2; + return values; + })(); - SearchConfigProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + return MfeDomainFeaturesProto; + })(); - SearchConfigProto.SearchServer = (function() { + dbroot.ClientOptionsProto = (function() { - function SearchServer(properties) { + function ClientOptionsProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + ClientOptionsProto.prototype.disableDiskCache = false; + ClientOptionsProto.prototype.disableEmbeddedBrowserVista = false; + ClientOptionsProto.prototype.drawAtmosphere = true; + ClientOptionsProto.prototype.drawStars = true; + ClientOptionsProto.prototype.shaderFilePrefix = ""; + ClientOptionsProto.prototype.useProtobufQuadtreePackets = false; + ClientOptionsProto.prototype.useExtendedCopyrightIds = true; + ClientOptionsProto.prototype.precipitationsOptions = null; + ClientOptionsProto.prototype.captureOptions = null; + ClientOptionsProto.prototype.show_2dMapsIcon = true; + ClientOptionsProto.prototype.disableInternalBrowser = false; + ClientOptionsProto.prototype.internalBrowserBlacklist = ""; + ClientOptionsProto.prototype.internalBrowserOriginWhitelist = "*"; + ClientOptionsProto.prototype.polarTileMergingLevel = 0; + ClientOptionsProto.prototype.jsBridgeRequestWhitelist = "http://*.google.com/*"; + ClientOptionsProto.prototype.mapsOptions = null; + + var $types = { + 7 : "keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions", + 8 : "keyhole.dbroot.ClientOptionsProto.CaptureOptions", + 15 : "keyhole.dbroot.ClientOptionsProto.MapsOptions" + }; + $lazyTypes.push($types); + + ClientOptionsProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.ClientOptionsProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.disableDiskCache = reader.bool(); + break; + case 2: + message.disableEmbeddedBrowserVista = reader.bool(); + break; + case 3: + message.drawAtmosphere = reader.bool(); + break; + case 4: + message.drawStars = reader.bool(); + break; + case 5: + message.shaderFilePrefix = reader.string(); + break; + case 6: + message.useProtobufQuadtreePackets = reader.bool(); + break; + case 7: + message.useExtendedCopyrightIds = reader.bool(); + break; + case 8: + message.precipitationsOptions = $types[7].decode(reader, reader.uint32()); + break; + case 9: + message.captureOptions = $types[8].decode(reader, reader.uint32()); + break; + case 10: + message.show_2dMapsIcon = reader.bool(); + break; + case 11: + message.disableInternalBrowser = reader.bool(); + break; + case 12: + message.internalBrowserBlacklist = reader.string(); + break; + case 13: + message.internalBrowserOriginWhitelist = reader.string(); + break; + case 14: + message.polarTileMergingLevel = reader.int32(); + break; + case 15: + message.jsBridgeRequestWhitelist = reader.string(); + break; + case 16: + message.mapsOptions = $types[15].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + ClientOptionsProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.disableDiskCache !== undefined) + if (typeof message.disableDiskCache !== "boolean") + return "disableDiskCache: boolean expected"; + if (message.disableEmbeddedBrowserVista !== undefined) + if (typeof message.disableEmbeddedBrowserVista !== "boolean") + return "disableEmbeddedBrowserVista: boolean expected"; + if (message.drawAtmosphere !== undefined) + if (typeof message.drawAtmosphere !== "boolean") + return "drawAtmosphere: boolean expected"; + if (message.drawStars !== undefined) + if (typeof message.drawStars !== "boolean") + return "drawStars: boolean expected"; + if (message.shaderFilePrefix !== undefined) + if (!$util.isString(message.shaderFilePrefix)) + return "shaderFilePrefix: string expected"; + if (message.useProtobufQuadtreePackets !== undefined) + if (typeof message.useProtobufQuadtreePackets !== "boolean") + return "useProtobufQuadtreePackets: boolean expected"; + if (message.useExtendedCopyrightIds !== undefined) + if (typeof message.useExtendedCopyrightIds !== "boolean") + return "useExtendedCopyrightIds: boolean expected"; + if (message.precipitationsOptions !== undefined && message.precipitationsOptions !== null) { + var error = $types[7].verify(message.precipitationsOptions); + if (error) + return "precipitationsOptions." + error; + } + if (message.captureOptions !== undefined && message.captureOptions !== null) { + var error = $types[8].verify(message.captureOptions); + if (error) + return "captureOptions." + error; + } + if (message.show_2dMapsIcon !== undefined) + if (typeof message.show_2dMapsIcon !== "boolean") + return "show_2dMapsIcon: boolean expected"; + if (message.disableInternalBrowser !== undefined) + if (typeof message.disableInternalBrowser !== "boolean") + return "disableInternalBrowser: boolean expected"; + if (message.internalBrowserBlacklist !== undefined) + if (!$util.isString(message.internalBrowserBlacklist)) + return "internalBrowserBlacklist: string expected"; + if (message.internalBrowserOriginWhitelist !== undefined) + if (!$util.isString(message.internalBrowserOriginWhitelist)) + return "internalBrowserOriginWhitelist: string expected"; + if (message.polarTileMergingLevel !== undefined) + if (!$util.isInteger(message.polarTileMergingLevel)) + return "polarTileMergingLevel: integer expected"; + if (message.jsBridgeRequestWhitelist !== undefined) + if (!$util.isString(message.jsBridgeRequestWhitelist)) + return "jsBridgeRequestWhitelist: string expected"; + if (message.mapsOptions !== undefined && message.mapsOptions !== null) { + var error = $types[15].verify(message.mapsOptions); + if (error) + return "mapsOptions." + error; + } + return null; + }; + + ClientOptionsProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ClientOptionsProto) + return object; + var message = new $root.keyhole.dbroot.ClientOptionsProto(); + if (object.disableDiskCache !== undefined && object.disableDiskCache !== null) + message.disableDiskCache = Boolean(object.disableDiskCache); + if (object.disableEmbeddedBrowserVista !== undefined && object.disableEmbeddedBrowserVista !== null) + message.disableEmbeddedBrowserVista = Boolean(object.disableEmbeddedBrowserVista); + if (object.drawAtmosphere !== undefined && object.drawAtmosphere !== null) + message.drawAtmosphere = Boolean(object.drawAtmosphere); + if (object.drawStars !== undefined && object.drawStars !== null) + message.drawStars = Boolean(object.drawStars); + if (object.shaderFilePrefix !== undefined && object.shaderFilePrefix !== null) + message.shaderFilePrefix = String(object.shaderFilePrefix); + if (object.useProtobufQuadtreePackets !== undefined && object.useProtobufQuadtreePackets !== null) + message.useProtobufQuadtreePackets = Boolean(object.useProtobufQuadtreePackets); + if (object.useExtendedCopyrightIds !== undefined && object.useExtendedCopyrightIds !== null) + message.useExtendedCopyrightIds = Boolean(object.useExtendedCopyrightIds); + if (object.precipitationsOptions !== undefined && object.precipitationsOptions !== null) { + if (typeof object.precipitationsOptions !== "object") + throw TypeError(".keyhole.dbroot.ClientOptionsProto.precipitationsOptions: object expected"); + message.precipitationsOptions = $types[7].fromObject(object.precipitationsOptions); + } + if (object.captureOptions !== undefined && object.captureOptions !== null) { + if (typeof object.captureOptions !== "object") + throw TypeError(".keyhole.dbroot.ClientOptionsProto.captureOptions: object expected"); + message.captureOptions = $types[8].fromObject(object.captureOptions); + } + if (object.show_2dMapsIcon !== undefined && object.show_2dMapsIcon !== null) + message.show_2dMapsIcon = Boolean(object.show_2dMapsIcon); + if (object.disableInternalBrowser !== undefined && object.disableInternalBrowser !== null) + message.disableInternalBrowser = Boolean(object.disableInternalBrowser); + if (object.internalBrowserBlacklist !== undefined && object.internalBrowserBlacklist !== null) + message.internalBrowserBlacklist = String(object.internalBrowserBlacklist); + if (object.internalBrowserOriginWhitelist !== undefined && object.internalBrowserOriginWhitelist !== null) + message.internalBrowserOriginWhitelist = String(object.internalBrowserOriginWhitelist); + if (object.polarTileMergingLevel !== undefined && object.polarTileMergingLevel !== null) + message.polarTileMergingLevel = object.polarTileMergingLevel | 0; + if (object.jsBridgeRequestWhitelist !== undefined && object.jsBridgeRequestWhitelist !== null) + message.jsBridgeRequestWhitelist = String(object.jsBridgeRequestWhitelist); + if (object.mapsOptions !== undefined && object.mapsOptions !== null) { + if (typeof object.mapsOptions !== "object") + throw TypeError(".keyhole.dbroot.ClientOptionsProto.mapsOptions: object expected"); + message.mapsOptions = $types[15].fromObject(object.mapsOptions); + } + return message; + }; + + ClientOptionsProto.from = ClientOptionsProto.fromObject; + + ClientOptionsProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.disableDiskCache = false; + object.disableEmbeddedBrowserVista = false; + object.drawAtmosphere = true; + object.drawStars = true; + object.shaderFilePrefix = ""; + object.useProtobufQuadtreePackets = false; + object.useExtendedCopyrightIds = true; + object.precipitationsOptions = null; + object.captureOptions = null; + object.show_2dMapsIcon = true; + object.disableInternalBrowser = false; + object.internalBrowserBlacklist = ""; + object.internalBrowserOriginWhitelist = "*"; + object.polarTileMergingLevel = 0; + object.jsBridgeRequestWhitelist = "http://*.google.com/*"; + object.mapsOptions = null; + } + if (message.disableDiskCache !== undefined && message.disableDiskCache !== null && message.hasOwnProperty("disableDiskCache")) + object.disableDiskCache = message.disableDiskCache; + if (message.disableEmbeddedBrowserVista !== undefined && message.disableEmbeddedBrowserVista !== null && message.hasOwnProperty("disableEmbeddedBrowserVista")) + object.disableEmbeddedBrowserVista = message.disableEmbeddedBrowserVista; + if (message.drawAtmosphere !== undefined && message.drawAtmosphere !== null && message.hasOwnProperty("drawAtmosphere")) + object.drawAtmosphere = message.drawAtmosphere; + if (message.drawStars !== undefined && message.drawStars !== null && message.hasOwnProperty("drawStars")) + object.drawStars = message.drawStars; + if (message.shaderFilePrefix !== undefined && message.shaderFilePrefix !== null && message.hasOwnProperty("shaderFilePrefix")) + object.shaderFilePrefix = message.shaderFilePrefix; + if (message.useProtobufQuadtreePackets !== undefined && message.useProtobufQuadtreePackets !== null && message.hasOwnProperty("useProtobufQuadtreePackets")) + object.useProtobufQuadtreePackets = message.useProtobufQuadtreePackets; + if (message.useExtendedCopyrightIds !== undefined && message.useExtendedCopyrightIds !== null && message.hasOwnProperty("useExtendedCopyrightIds")) + object.useExtendedCopyrightIds = message.useExtendedCopyrightIds; + if (message.precipitationsOptions !== undefined && message.precipitationsOptions !== null && message.hasOwnProperty("precipitationsOptions")) + object.precipitationsOptions = $types[7].toObject(message.precipitationsOptions, options); + if (message.captureOptions !== undefined && message.captureOptions !== null && message.hasOwnProperty("captureOptions")) + object.captureOptions = $types[8].toObject(message.captureOptions, options); + if (message.show_2dMapsIcon !== undefined && message.show_2dMapsIcon !== null && message.hasOwnProperty("show_2dMapsIcon")) + object.show_2dMapsIcon = message.show_2dMapsIcon; + if (message.disableInternalBrowser !== undefined && message.disableInternalBrowser !== null && message.hasOwnProperty("disableInternalBrowser")) + object.disableInternalBrowser = message.disableInternalBrowser; + if (message.internalBrowserBlacklist !== undefined && message.internalBrowserBlacklist !== null && message.hasOwnProperty("internalBrowserBlacklist")) + object.internalBrowserBlacklist = message.internalBrowserBlacklist; + if (message.internalBrowserOriginWhitelist !== undefined && message.internalBrowserOriginWhitelist !== null && message.hasOwnProperty("internalBrowserOriginWhitelist")) + object.internalBrowserOriginWhitelist = message.internalBrowserOriginWhitelist; + if (message.polarTileMergingLevel !== undefined && message.polarTileMergingLevel !== null && message.hasOwnProperty("polarTileMergingLevel")) + object.polarTileMergingLevel = message.polarTileMergingLevel; + if (message.jsBridgeRequestWhitelist !== undefined && message.jsBridgeRequestWhitelist !== null && message.hasOwnProperty("jsBridgeRequestWhitelist")) + object.jsBridgeRequestWhitelist = message.jsBridgeRequestWhitelist; + if (message.mapsOptions !== undefined && message.mapsOptions !== null && message.hasOwnProperty("mapsOptions")) + object.mapsOptions = $types[15].toObject(message.mapsOptions, options); + return object; + }; + + ClientOptionsProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + ClientOptionsProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + ClientOptionsProto.PrecipitationsOptions = (function() { + + function PrecipitationsOptions(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + PrecipitationsOptions.prototype.imageUrl = ""; + PrecipitationsOptions.prototype.imageExpireTime = 900; + PrecipitationsOptions.prototype.maxColorDistance = 20; + PrecipitationsOptions.prototype.imageLevel = 5; + PrecipitationsOptions.prototype.weatherMapping = $util.emptyArray; + PrecipitationsOptions.prototype.cloudsLayerUrl = ""; + PrecipitationsOptions.prototype.animationDecelerationDelay = 20; + + var $types = { + 4 : "keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping" + }; + $lazyTypes.push($types); + + PrecipitationsOptions.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.imageUrl = reader.string(); + break; + case 2: + message.imageExpireTime = reader.int32(); + break; + case 3: + message.maxColorDistance = reader.int32(); + break; + case 4: + message.imageLevel = reader.int32(); + break; + case 5: + if (!(message.weatherMapping && message.weatherMapping.length)) + message.weatherMapping = []; + message.weatherMapping.push($types[4].decode(reader, reader.uint32())); + break; + case 6: + message.cloudsLayerUrl = reader.string(); + break; + case 7: + message.animationDecelerationDelay = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + PrecipitationsOptions.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.imageUrl !== undefined) + if (!$util.isString(message.imageUrl)) + return "imageUrl: string expected"; + if (message.imageExpireTime !== undefined) + if (!$util.isInteger(message.imageExpireTime)) + return "imageExpireTime: integer expected"; + if (message.maxColorDistance !== undefined) + if (!$util.isInteger(message.maxColorDistance)) + return "maxColorDistance: integer expected"; + if (message.imageLevel !== undefined) + if (!$util.isInteger(message.imageLevel)) + return "imageLevel: integer expected"; + if (message.weatherMapping !== undefined) { + if (!Array.isArray(message.weatherMapping)) + return "weatherMapping: array expected"; + for (var i = 0; i < message.weatherMapping.length; ++i) { + var error = $types[4].verify(message.weatherMapping[i]); + if (error) + return "weatherMapping." + error; + } + } + if (message.cloudsLayerUrl !== undefined) + if (!$util.isString(message.cloudsLayerUrl)) + return "cloudsLayerUrl: string expected"; + if (message.animationDecelerationDelay !== undefined) + if (typeof message.animationDecelerationDelay !== "number") + return "animationDecelerationDelay: number expected"; + return null; + }; + + PrecipitationsOptions.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions) + return object; + var message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions(); + if (object.imageUrl !== undefined && object.imageUrl !== null) + message.imageUrl = String(object.imageUrl); + if (object.imageExpireTime !== undefined && object.imageExpireTime !== null) + message.imageExpireTime = object.imageExpireTime | 0; + if (object.maxColorDistance !== undefined && object.maxColorDistance !== null) + message.maxColorDistance = object.maxColorDistance | 0; + if (object.imageLevel !== undefined && object.imageLevel !== null) + message.imageLevel = object.imageLevel | 0; + if (object.weatherMapping) { + if (!Array.isArray(object.weatherMapping)) + throw TypeError(".keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.weatherMapping: array expected"); + message.weatherMapping = []; + for (var i = 0; i < object.weatherMapping.length; ++i) { + if (typeof object.weatherMapping[i] !== "object") + throw TypeError(".keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.weatherMapping: object expected"); + message.weatherMapping[i] = $types[4].fromObject(object.weatherMapping[i]); + } + } + if (object.cloudsLayerUrl !== undefined && object.cloudsLayerUrl !== null) + message.cloudsLayerUrl = String(object.cloudsLayerUrl); + if (object.animationDecelerationDelay !== undefined && object.animationDecelerationDelay !== null) + message.animationDecelerationDelay = Number(object.animationDecelerationDelay); + return message; + }; + + PrecipitationsOptions.from = PrecipitationsOptions.fromObject; + + PrecipitationsOptions.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.weatherMapping = []; + if (options.defaults) { + object.imageUrl = ""; + object.imageExpireTime = 900; + object.maxColorDistance = 20; + object.imageLevel = 5; + object.cloudsLayerUrl = ""; + object.animationDecelerationDelay = 20; + } + if (message.imageUrl !== undefined && message.imageUrl !== null && message.hasOwnProperty("imageUrl")) + object.imageUrl = message.imageUrl; + if (message.imageExpireTime !== undefined && message.imageExpireTime !== null && message.hasOwnProperty("imageExpireTime")) + object.imageExpireTime = message.imageExpireTime; + if (message.maxColorDistance !== undefined && message.maxColorDistance !== null && message.hasOwnProperty("maxColorDistance")) + object.maxColorDistance = message.maxColorDistance; + if (message.imageLevel !== undefined && message.imageLevel !== null && message.hasOwnProperty("imageLevel")) + object.imageLevel = message.imageLevel; + if (message.weatherMapping !== undefined && message.weatherMapping !== null && message.hasOwnProperty("weatherMapping")) { + object.weatherMapping = []; + for (var j = 0; j < message.weatherMapping.length; ++j) + object.weatherMapping[j] = $types[4].toObject(message.weatherMapping[j], options); + } + if (message.cloudsLayerUrl !== undefined && message.cloudsLayerUrl !== null && message.hasOwnProperty("cloudsLayerUrl")) + object.cloudsLayerUrl = message.cloudsLayerUrl; + if (message.animationDecelerationDelay !== undefined && message.animationDecelerationDelay !== null && message.hasOwnProperty("animationDecelerationDelay")) + object.animationDecelerationDelay = message.animationDecelerationDelay; + return object; + }; + + PrecipitationsOptions.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + PrecipitationsOptions.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + PrecipitationsOptions.WeatherMapping = (function() { + + function WeatherMapping(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) this[keys[i]] = properties[keys[i]]; } - SearchServer.prototype.name = null; - SearchServer.prototype.url = null; - SearchServer.prototype.type = 0; - SearchServer.prototype.htmlTransformUrl = null; - SearchServer.prototype.kmlTransformUrl = null; - SearchServer.prototype.supplementalUi = null; - SearchServer.prototype.suggestion = $util.emptyArray; - SearchServer.prototype.searchlet = $util.emptyArray; - SearchServer.prototype.requirements = null; - SearchServer.prototype.suggestServer = null; + WeatherMapping.prototype.colorAbgr = 0; + WeatherMapping.prototype.weatherType = 0; + WeatherMapping.prototype.elongation = 1; + WeatherMapping.prototype.opacity = 0; + WeatherMapping.prototype.fogDensity = 0; + WeatherMapping.prototype.speed0 = 0; + WeatherMapping.prototype.speed1 = 0; + WeatherMapping.prototype.speed2 = 0; + WeatherMapping.prototype.speed3 = 0; var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 1 : "keyhole.dbroot.StringIdOrValueProto", - 2 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.ResultType", - 3 : "keyhole.dbroot.StringIdOrValueProto", - 4 : "keyhole.dbroot.StringIdOrValueProto", - 5 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi", - 6 : "keyhole.dbroot.StringIdOrValueProto", - 7 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto", - 8 : "keyhole.dbroot.RequirementProto", - 9 : "keyhole.dbroot.StringIdOrValueProto" + 1 : "keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping.WeatherType" }; $lazyTypes.push($types); - SearchServer.decode = function decode(reader, length) { + WeatherMapping.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer(); + message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.name = $types[0].decode(reader, reader.uint32()); + message.colorAbgr = reader.uint32(); break; case 2: - message.url = $types[1].decode(reader, reader.uint32()); + message.weatherType = reader.uint32(); break; case 3: - message.type = reader.uint32(); + message.elongation = reader.float(); break; case 4: - message.htmlTransformUrl = $types[3].decode(reader, reader.uint32()); + message.opacity = reader.float(); break; case 5: - message.kmlTransformUrl = $types[4].decode(reader, reader.uint32()); + message.fogDensity = reader.float(); break; case 6: - message.supplementalUi = $types[5].decode(reader, reader.uint32()); - break; - case 9: - if (!(message.suggestion && message.suggestion.length)) - message.suggestion = []; - message.suggestion.push($types[6].decode(reader, reader.uint32())); + message.speed0 = reader.float(); break; case 7: - if (!(message.searchlet && message.searchlet.length)) - message.searchlet = []; - message.searchlet.push($types[7].decode(reader, reader.uint32())); + message.speed1 = reader.float(); break; case 8: - message.requirements = $types[8].decode(reader, reader.uint32()); + message.speed2 = reader.float(); break; - case 10: - message.suggestServer = $types[9].decode(reader, reader.uint32()); + case 9: + message.speed3 = reader.float(); break; default: reader.skipType(tag & 7); @@ -61475,780 +59022,272 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - SearchServer.verify = function verify(message) { + WeatherMapping.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.name !== undefined && message.name !== null) { - var error = $types[0].verify(message.name); - if (error) - return "name." + error; - } - if (message.url !== undefined && message.url !== null) { - var error = $types[1].verify(message.url); - if (error) - return "url." + error; - } - if (message.type !== undefined) - switch (message.type) { - default: - return "type: enum value expected"; - case 0: - case 1: - break; - } - if (message.htmlTransformUrl !== undefined && message.htmlTransformUrl !== null) { - var error = $types[3].verify(message.htmlTransformUrl); - if (error) - return "htmlTransformUrl." + error; - } - if (message.kmlTransformUrl !== undefined && message.kmlTransformUrl !== null) { - var error = $types[4].verify(message.kmlTransformUrl); - if (error) - return "kmlTransformUrl." + error; - } - if (message.supplementalUi !== undefined && message.supplementalUi !== null) { - var error = $types[5].verify(message.supplementalUi); - if (error) - return "supplementalUi." + error; - } - if (message.suggestion !== undefined) { - if (!Array.isArray(message.suggestion)) - return "suggestion: array expected"; - for (var i = 0; i < message.suggestion.length; ++i) { - var error = $types[6].verify(message.suggestion[i]); - if (error) - return "suggestion." + error; - } - } - if (message.searchlet !== undefined) { - if (!Array.isArray(message.searchlet)) - return "searchlet: array expected"; - for (var i = 0; i < message.searchlet.length; ++i) { - var error = $types[7].verify(message.searchlet[i]); - if (error) - return "searchlet." + error; - } - } - if (message.requirements !== undefined && message.requirements !== null) { - var error = $types[8].verify(message.requirements); - if (error) - return "requirements." + error; - } - if (message.suggestServer !== undefined && message.suggestServer !== null) { - var error = $types[9].verify(message.suggestServer); - if (error) - return "suggestServer." + error; + if (!$util.isInteger(message.colorAbgr)) + return "colorAbgr: integer expected"; + switch (message.weatherType) { + default: + return "weatherType: enum value expected"; + case 0: + case 1: + case 2: + break; } + if (message.elongation !== undefined) + if (typeof message.elongation !== "number") + return "elongation: number expected"; + if (message.opacity !== undefined) + if (typeof message.opacity !== "number") + return "opacity: number expected"; + if (message.fogDensity !== undefined) + if (typeof message.fogDensity !== "number") + return "fogDensity: number expected"; + if (message.speed0 !== undefined) + if (typeof message.speed0 !== "number") + return "speed0: number expected"; + if (message.speed1 !== undefined) + if (typeof message.speed1 !== "number") + return "speed1: number expected"; + if (message.speed2 !== undefined) + if (typeof message.speed2 !== "number") + return "speed2: number expected"; + if (message.speed3 !== undefined) + if (typeof message.speed3 !== "number") + return "speed3: number expected"; return null; }; - SearchServer.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer) + WeatherMapping.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping) return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer(); - if (object.name !== undefined && object.name !== null) { - if (typeof object.name !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.name: object expected"); - message.name = $types[0].fromObject(object.name); - } - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.url: object expected"); - message.url = $types[1].fromObject(object.url); - } - switch (object.type) { - case "RESULT_TYPE_KML": + var message = new $root.keyhole.dbroot.ClientOptionsProto.PrecipitationsOptions.WeatherMapping(); + if (object.colorAbgr !== undefined && object.colorAbgr !== null) + message.colorAbgr = object.colorAbgr >>> 0; + switch (object.weatherType) { + case "NO_PRECIPITATION": case 0: - message.type = 0; + message.weatherType = 0; break; - case "RESULT_TYPE_XML": + case "RAIN": case 1: - message.type = 1; + message.weatherType = 1; + break; + case "SNOW": + case 2: + message.weatherType = 2; break; } - if (object.htmlTransformUrl !== undefined && object.htmlTransformUrl !== null) { - if (typeof object.htmlTransformUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.htmlTransformUrl: object expected"); - message.htmlTransformUrl = $types[3].fromObject(object.htmlTransformUrl); - } - if (object.kmlTransformUrl !== undefined && object.kmlTransformUrl !== null) { - if (typeof object.kmlTransformUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.kmlTransformUrl: object expected"); - message.kmlTransformUrl = $types[4].fromObject(object.kmlTransformUrl); - } - if (object.supplementalUi !== undefined && object.supplementalUi !== null) { - if (typeof object.supplementalUi !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.supplementalUi: object expected"); - message.supplementalUi = $types[5].fromObject(object.supplementalUi); - } - if (object.suggestion) { - if (!Array.isArray(object.suggestion)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestion: array expected"); - message.suggestion = []; - for (var i = 0; i < object.suggestion.length; ++i) { - if (typeof object.suggestion[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestion: object expected"); - message.suggestion[i] = $types[6].fromObject(object.suggestion[i]); - } - } - if (object.searchlet) { - if (!Array.isArray(object.searchlet)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.searchlet: array expected"); - message.searchlet = []; - for (var i = 0; i < object.searchlet.length; ++i) { - if (typeof object.searchlet[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.searchlet: object expected"); - message.searchlet[i] = $types[7].fromObject(object.searchlet[i]); - } - } - if (object.requirements !== undefined && object.requirements !== null) { - if (typeof object.requirements !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.requirements: object expected"); - message.requirements = $types[8].fromObject(object.requirements); - } - if (object.suggestServer !== undefined && object.suggestServer !== null) { - if (typeof object.suggestServer !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestServer: object expected"); - message.suggestServer = $types[9].fromObject(object.suggestServer); - } + if (object.elongation !== undefined && object.elongation !== null) + message.elongation = Number(object.elongation); + if (object.opacity !== undefined && object.opacity !== null) + message.opacity = Number(object.opacity); + if (object.fogDensity !== undefined && object.fogDensity !== null) + message.fogDensity = Number(object.fogDensity); + if (object.speed0 !== undefined && object.speed0 !== null) + message.speed0 = Number(object.speed0); + if (object.speed1 !== undefined && object.speed1 !== null) + message.speed1 = Number(object.speed1); + if (object.speed2 !== undefined && object.speed2 !== null) + message.speed2 = Number(object.speed2); + if (object.speed3 !== undefined && object.speed3 !== null) + message.speed3 = Number(object.speed3); return message; }; - SearchServer.from = SearchServer.fromObject; + WeatherMapping.from = WeatherMapping.fromObject; - SearchServer.toObject = function toObject(message, options) { + WeatherMapping.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) { - object.suggestion = []; - object.searchlet = []; - } if (options.defaults) { - object.name = null; - object.url = null; - object.type = options.enums === String ? "RESULT_TYPE_KML" : 0; - object.htmlTransformUrl = null; - object.kmlTransformUrl = null; - object.supplementalUi = null; - object.requirements = null; - object.suggestServer = null; - } - if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) - object.name = $types[0].toObject(message.name, options); - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[1].toObject(message.url, options); - if (message.type !== undefined && message.type !== null && message.hasOwnProperty("type")) - object.type = options.enums === String ? $types[2][message.type] : message.type; - if (message.htmlTransformUrl !== undefined && message.htmlTransformUrl !== null && message.hasOwnProperty("htmlTransformUrl")) - object.htmlTransformUrl = $types[3].toObject(message.htmlTransformUrl, options); - if (message.kmlTransformUrl !== undefined && message.kmlTransformUrl !== null && message.hasOwnProperty("kmlTransformUrl")) - object.kmlTransformUrl = $types[4].toObject(message.kmlTransformUrl, options); - if (message.supplementalUi !== undefined && message.supplementalUi !== null && message.hasOwnProperty("supplementalUi")) - object.supplementalUi = $types[5].toObject(message.supplementalUi, options); - if (message.suggestion !== undefined && message.suggestion !== null && message.hasOwnProperty("suggestion")) { - object.suggestion = []; - for (var j = 0; j < message.suggestion.length; ++j) - object.suggestion[j] = $types[6].toObject(message.suggestion[j], options); - } - if (message.searchlet !== undefined && message.searchlet !== null && message.hasOwnProperty("searchlet")) { - object.searchlet = []; - for (var j = 0; j < message.searchlet.length; ++j) - object.searchlet[j] = $types[7].toObject(message.searchlet[j], options); + object.colorAbgr = 0; + object.weatherType = options.enums === String ? "NO_PRECIPITATION" : 0; + object.elongation = 1; + object.opacity = 0; + object.fogDensity = 0; + object.speed0 = 0; + object.speed1 = 0; + object.speed2 = 0; + object.speed3 = 0; } - if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) - object.requirements = $types[8].toObject(message.requirements, options); - if (message.suggestServer !== undefined && message.suggestServer !== null && message.hasOwnProperty("suggestServer")) - object.suggestServer = $types[9].toObject(message.suggestServer, options); + if (message.colorAbgr !== undefined && message.colorAbgr !== null && message.hasOwnProperty("colorAbgr")) + object.colorAbgr = message.colorAbgr; + if (message.weatherType !== undefined && message.weatherType !== null && message.hasOwnProperty("weatherType")) + object.weatherType = options.enums === String ? $types[1][message.weatherType] : message.weatherType; + if (message.elongation !== undefined && message.elongation !== null && message.hasOwnProperty("elongation")) + object.elongation = message.elongation; + if (message.opacity !== undefined && message.opacity !== null && message.hasOwnProperty("opacity")) + object.opacity = message.opacity; + if (message.fogDensity !== undefined && message.fogDensity !== null && message.hasOwnProperty("fogDensity")) + object.fogDensity = message.fogDensity; + if (message.speed0 !== undefined && message.speed0 !== null && message.hasOwnProperty("speed0")) + object.speed0 = message.speed0; + if (message.speed1 !== undefined && message.speed1 !== null && message.hasOwnProperty("speed1")) + object.speed1 = message.speed1; + if (message.speed2 !== undefined && message.speed2 !== null && message.hasOwnProperty("speed2")) + object.speed2 = message.speed2; + if (message.speed3 !== undefined && message.speed3 !== null && message.hasOwnProperty("speed3")) + object.speed3 = message.speed3; return object; }; - SearchServer.prototype.toObject = function toObject(options) { + WeatherMapping.prototype.toObject = function toObject(options) { return this.constructor.toObject(this, options); }; - SearchServer.prototype.toJSON = function toJSON() { + WeatherMapping.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - SearchServer.ResultType = (function() { + WeatherMapping.WeatherType = (function() { var valuesById = {}, values = Object.create(valuesById); - values["RESULT_TYPE_KML"] = 0; - values["RESULT_TYPE_XML"] = 1; + values["NO_PRECIPITATION"] = 0; + values["RAIN"] = 1; + values["SNOW"] = 2; return values; })(); - SearchServer.SupplementalUi = (function() { - - function SupplementalUi(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - SupplementalUi.prototype.url = null; - SupplementalUi.prototype.label = null; - SupplementalUi.prototype.height = 160; + return WeatherMapping; + })(); - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 1 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); + return PrecipitationsOptions; + })(); - SupplementalUi.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.url = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.label = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.height = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + ClientOptionsProto.CaptureOptions = (function() { - SupplementalUi.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.url !== undefined && message.url !== null) { - var error = $types[0].verify(message.url); - if (error) - return "url." + error; - } - if (message.label !== undefined && message.label !== null) { - var error = $types[1].verify(message.label); - if (error) - return "label." + error; - } - if (message.height !== undefined) - if (!$util.isInteger(message.height)) - return "height: integer expected"; - return null; - }; + function CaptureOptions(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - SupplementalUi.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi(); - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.url: object expected"); - message.url = $types[0].fromObject(object.url); - } - if (object.label !== undefined && object.label !== null) { - if (typeof object.label !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.label: object expected"); - message.label = $types[1].fromObject(object.label); - } - if (object.height !== undefined && object.height !== null) - message.height = object.height | 0; - return message; - }; + CaptureOptions.prototype.allowSaveAsImage = true; + CaptureOptions.prototype.maxFreeCaptureRes = 2400; + CaptureOptions.prototype.maxPremiumCaptureRes = 4800; - SupplementalUi.from = SupplementalUi.fromObject; + CaptureOptions.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.ClientOptionsProto.CaptureOptions(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.allowSaveAsImage = reader.bool(); + break; + case 2: + message.maxFreeCaptureRes = reader.int32(); + break; + case 3: + message.maxPremiumCaptureRes = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - SupplementalUi.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.url = null; - object.label = null; - object.height = 160; - } - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[0].toObject(message.url, options); - if (message.label !== undefined && message.label !== null && message.hasOwnProperty("label")) - object.label = $types[1].toObject(message.label, options); - if (message.height !== undefined && message.height !== null && message.hasOwnProperty("height")) - object.height = message.height; - return object; - }; + CaptureOptions.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.allowSaveAsImage !== undefined) + if (typeof message.allowSaveAsImage !== "boolean") + return "allowSaveAsImage: boolean expected"; + if (message.maxFreeCaptureRes !== undefined) + if (!$util.isInteger(message.maxFreeCaptureRes)) + return "maxFreeCaptureRes: integer expected"; + if (message.maxPremiumCaptureRes !== undefined) + if (!$util.isInteger(message.maxPremiumCaptureRes)) + return "maxPremiumCaptureRes: integer expected"; + return null; + }; - SupplementalUi.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; + CaptureOptions.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.CaptureOptions) + return object; + var message = new $root.keyhole.dbroot.ClientOptionsProto.CaptureOptions(); + if (object.allowSaveAsImage !== undefined && object.allowSaveAsImage !== null) + message.allowSaveAsImage = Boolean(object.allowSaveAsImage); + if (object.maxFreeCaptureRes !== undefined && object.maxFreeCaptureRes !== null) + message.maxFreeCaptureRes = object.maxFreeCaptureRes | 0; + if (object.maxPremiumCaptureRes !== undefined && object.maxPremiumCaptureRes !== null) + message.maxPremiumCaptureRes = object.maxPremiumCaptureRes | 0; + return message; + }; - SupplementalUi.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; + CaptureOptions.from = CaptureOptions.fromObject; - return SupplementalUi; - })(); + CaptureOptions.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.allowSaveAsImage = true; + object.maxFreeCaptureRes = 2400; + object.maxPremiumCaptureRes = 4800; + } + if (message.allowSaveAsImage !== undefined && message.allowSaveAsImage !== null && message.hasOwnProperty("allowSaveAsImage")) + object.allowSaveAsImage = message.allowSaveAsImage; + if (message.maxFreeCaptureRes !== undefined && message.maxFreeCaptureRes !== null && message.hasOwnProperty("maxFreeCaptureRes")) + object.maxFreeCaptureRes = message.maxFreeCaptureRes; + if (message.maxPremiumCaptureRes !== undefined && message.maxPremiumCaptureRes !== null && message.hasOwnProperty("maxPremiumCaptureRes")) + object.maxPremiumCaptureRes = message.maxPremiumCaptureRes; + return object; + }; - SearchServer.SearchletProto = (function() { + CaptureOptions.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - function SearchletProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } + CaptureOptions.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - SearchletProto.prototype.url = null; - SearchletProto.prototype.name = null; - SearchletProto.prototype.requirements = null; + return CaptureOptions; + })(); - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 1 : "keyhole.dbroot.StringIdOrValueProto", - 2 : "keyhole.dbroot.RequirementProto" - }; - $lazyTypes.push($types); + ClientOptionsProto.MapsOptions = (function() { - SearchletProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.url = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.name = $types[1].decode(reader, reader.uint32()); - break; - case 3: - message.requirements = $types[2].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; + function MapsOptions(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - SearchletProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.url !== undefined && message.url !== null) { - var error = $types[0].verify(message.url); - if (error) - return "url." + error; - } - if (message.name !== undefined && message.name !== null) { - var error = $types[1].verify(message.name); - if (error) - return "name." + error; - } - if (message.requirements !== undefined && message.requirements !== null) { - var error = $types[2].verify(message.requirements); - if (error) - return "requirements." + error; - } - return null; - }; + MapsOptions.prototype.enableMaps = false; + MapsOptions.prototype.docsAutoDownloadEnabled = false; + MapsOptions.prototype.docsAutoDownloadInterval = 0; + MapsOptions.prototype.docsAutoUploadEnabled = false; + MapsOptions.prototype.docsAutoUploadDelay = 0; - SearchletProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto(); - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.url: object expected"); - message.url = $types[0].fromObject(object.url); - } - if (object.name !== undefined && object.name !== null) { - if (typeof object.name !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.name: object expected"); - message.name = $types[1].fromObject(object.name); - } - if (object.requirements !== undefined && object.requirements !== null) { - if (typeof object.requirements !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.requirements: object expected"); - message.requirements = $types[2].fromObject(object.requirements); - } - return message; - }; - - SearchletProto.from = SearchletProto.fromObject; - - SearchletProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.url = null; - object.name = null; - object.requirements = null; - } - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[0].toObject(message.url, options); - if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) - object.name = $types[1].toObject(message.name, options); - if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) - object.requirements = $types[2].toObject(message.requirements, options); - return object; - }; - - SearchletProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - SearchletProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SearchletProto; - })(); - - return SearchServer; - })(); - - SearchConfigProto.OneboxServiceProto = (function() { - - function OneboxServiceProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - OneboxServiceProto.prototype.serviceUrl = null; - OneboxServiceProto.prototype.requirements = null; - - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 1 : "keyhole.dbroot.RequirementProto" - }; - $lazyTypes.push($types); - - OneboxServiceProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.serviceUrl = $types[0].decode(reader, reader.uint32()); - break; - case 2: - message.requirements = $types[1].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - OneboxServiceProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.serviceUrl !== undefined && message.serviceUrl !== null) { - var error = $types[0].verify(message.serviceUrl); - if (error) - return "serviceUrl." + error; - } - if (message.requirements !== undefined && message.requirements !== null) { - var error = $types[1].verify(message.requirements); - if (error) - return "requirements." + error; - } - return null; - }; - - OneboxServiceProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto(); - if (object.serviceUrl !== undefined && object.serviceUrl !== null) { - if (typeof object.serviceUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.serviceUrl: object expected"); - message.serviceUrl = $types[0].fromObject(object.serviceUrl); - } - if (object.requirements !== undefined && object.requirements !== null) { - if (typeof object.requirements !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.requirements: object expected"); - message.requirements = $types[1].fromObject(object.requirements); - } - return message; - }; - - OneboxServiceProto.from = OneboxServiceProto.fromObject; - - OneboxServiceProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.serviceUrl = null; - object.requirements = null; - } - if (message.serviceUrl !== undefined && message.serviceUrl !== null && message.hasOwnProperty("serviceUrl")) - object.serviceUrl = $types[0].toObject(message.serviceUrl, options); - if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) - object.requirements = $types[1].toObject(message.requirements, options); - return object; - }; - - OneboxServiceProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - OneboxServiceProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return OneboxServiceProto; - })(); - - return SearchConfigProto; - })(); - - EndSnippetProto.SearchInfoProto = (function() { - - function SearchInfoProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - SearchInfoProto.prototype.defaultUrl = "http://maps.google.com/maps"; - SearchInfoProto.prototype.geocodeParam = "q"; - - SearchInfoProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.SearchInfoProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.defaultUrl = reader.string(); - break; - case 2: - message.geocodeParam = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - SearchInfoProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.defaultUrl !== undefined) - if (!$util.isString(message.defaultUrl)) - return "defaultUrl: string expected"; - if (message.geocodeParam !== undefined) - if (!$util.isString(message.geocodeParam)) - return "geocodeParam: string expected"; - return null; - }; - - SearchInfoProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchInfoProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.SearchInfoProto(); - if (object.defaultUrl !== undefined && object.defaultUrl !== null) - message.defaultUrl = String(object.defaultUrl); - if (object.geocodeParam !== undefined && object.geocodeParam !== null) - message.geocodeParam = String(object.geocodeParam); - return message; - }; - - SearchInfoProto.from = SearchInfoProto.fromObject; - - SearchInfoProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.defaultUrl = "http://maps.google.com/maps"; - object.geocodeParam = "q"; - } - if (message.defaultUrl !== undefined && message.defaultUrl !== null && message.hasOwnProperty("defaultUrl")) - object.defaultUrl = message.defaultUrl; - if (message.geocodeParam !== undefined && message.geocodeParam !== null && message.hasOwnProperty("geocodeParam")) - object.geocodeParam = message.geocodeParam; - return object; - }; - - SearchInfoProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - SearchInfoProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SearchInfoProto; - })(); - - EndSnippetProto.RockTreeDataProto = (function() { - - function RockTreeDataProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - RockTreeDataProto.prototype.url = null; - - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); - - RockTreeDataProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.RockTreeDataProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.url = $types[0].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - RockTreeDataProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.url !== undefined && message.url !== null) { - var error = $types[0].verify(message.url); - if (error) - return "url." + error; - } - return null; - }; - - RockTreeDataProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.RockTreeDataProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.RockTreeDataProto(); - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.RockTreeDataProto.url: object expected"); - message.url = $types[0].fromObject(object.url); - } - return message; - }; - - RockTreeDataProto.from = RockTreeDataProto.fromObject; - - RockTreeDataProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.url = null; - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[0].toObject(message.url, options); - return object; - }; - - RockTreeDataProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - RockTreeDataProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return RockTreeDataProto; - })(); - - EndSnippetProto.FilmstripConfigProto = (function() { - - function FilmstripConfigProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - FilmstripConfigProto.prototype.requirements = null; - FilmstripConfigProto.prototype.alleycatUrlTemplate = null; - FilmstripConfigProto.prototype.fallbackAlleycatUrlTemplate = null; - FilmstripConfigProto.prototype.metadataUrlTemplate = null; - FilmstripConfigProto.prototype.thumbnailUrlTemplate = null; - FilmstripConfigProto.prototype.kmlUrlTemplate = null; - FilmstripConfigProto.prototype.featuredToursUrl = null; - FilmstripConfigProto.prototype.enableViewportFallback = false; - FilmstripConfigProto.prototype.viewportFallbackDistance = 0; - FilmstripConfigProto.prototype.imageryType = $util.emptyArray; - - var $types = { - 0 : "keyhole.dbroot.RequirementProto", - 1 : "keyhole.dbroot.StringIdOrValueProto", - 2 : "keyhole.dbroot.StringIdOrValueProto", - 3 : "keyhole.dbroot.StringIdOrValueProto", - 4 : "keyhole.dbroot.StringIdOrValueProto", - 5 : "keyhole.dbroot.StringIdOrValueProto", - 6 : "keyhole.dbroot.StringIdOrValueProto", - 9 : "keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto" - }; - $lazyTypes.push($types); - - FilmstripConfigProto.decode = function decode(reader, length) { + MapsOptions.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto(); + message = new $root.keyhole.dbroot.ClientOptionsProto.MapsOptions(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.requirements = $types[0].decode(reader, reader.uint32()); + message.enableMaps = reader.bool(); break; case 2: - message.alleycatUrlTemplate = $types[1].decode(reader, reader.uint32()); - break; - case 9: - message.fallbackAlleycatUrlTemplate = $types[2].decode(reader, reader.uint32()); + message.docsAutoDownloadEnabled = reader.bool(); break; case 3: - message.metadataUrlTemplate = $types[3].decode(reader, reader.uint32()); + message.docsAutoDownloadInterval = reader.int32(); break; case 4: - message.thumbnailUrlTemplate = $types[4].decode(reader, reader.uint32()); + message.docsAutoUploadEnabled = reader.bool(); break; case 5: - message.kmlUrlTemplate = $types[5].decode(reader, reader.uint32()); - break; - case 6: - message.featuredToursUrl = $types[6].decode(reader, reader.uint32()); - break; - case 7: - message.enableViewportFallback = reader.bool(); - break; - case 8: - message.viewportFallbackDistance = reader.uint32(); - break; - case 10: - if (!(message.imageryType && message.imageryType.length)) - message.imageryType = []; - message.imageryType.push($types[9].decode(reader, reader.uint32())); + message.docsAutoUploadDelay = reader.int32(); break; default: reader.skipType(tag & 7); @@ -62258,433 +59297,160 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - FilmstripConfigProto.verify = function verify(message) { + MapsOptions.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.requirements !== undefined && message.requirements !== null) { - var error = $types[0].verify(message.requirements); - if (error) - return "requirements." + error; - } - if (message.alleycatUrlTemplate !== undefined && message.alleycatUrlTemplate !== null) { - var error = $types[1].verify(message.alleycatUrlTemplate); - if (error) - return "alleycatUrlTemplate." + error; - } - if (message.fallbackAlleycatUrlTemplate !== undefined && message.fallbackAlleycatUrlTemplate !== null) { - var error = $types[2].verify(message.fallbackAlleycatUrlTemplate); - if (error) - return "fallbackAlleycatUrlTemplate." + error; - } - if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null) { - var error = $types[3].verify(message.metadataUrlTemplate); - if (error) - return "metadataUrlTemplate." + error; - } - if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null) { - var error = $types[4].verify(message.thumbnailUrlTemplate); - if (error) - return "thumbnailUrlTemplate." + error; - } - if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null) { - var error = $types[5].verify(message.kmlUrlTemplate); - if (error) - return "kmlUrlTemplate." + error; - } - if (message.featuredToursUrl !== undefined && message.featuredToursUrl !== null) { - var error = $types[6].verify(message.featuredToursUrl); - if (error) - return "featuredToursUrl." + error; - } - if (message.enableViewportFallback !== undefined) - if (typeof message.enableViewportFallback !== "boolean") - return "enableViewportFallback: boolean expected"; - if (message.viewportFallbackDistance !== undefined) - if (!$util.isInteger(message.viewportFallbackDistance)) - return "viewportFallbackDistance: integer expected"; - if (message.imageryType !== undefined) { - if (!Array.isArray(message.imageryType)) - return "imageryType: array expected"; - for (var i = 0; i < message.imageryType.length; ++i) { - var error = $types[9].verify(message.imageryType[i]); - if (error) - return "imageryType." + error; - } - } + if (message.enableMaps !== undefined) + if (typeof message.enableMaps !== "boolean") + return "enableMaps: boolean expected"; + if (message.docsAutoDownloadEnabled !== undefined) + if (typeof message.docsAutoDownloadEnabled !== "boolean") + return "docsAutoDownloadEnabled: boolean expected"; + if (message.docsAutoDownloadInterval !== undefined) + if (!$util.isInteger(message.docsAutoDownloadInterval)) + return "docsAutoDownloadInterval: integer expected"; + if (message.docsAutoUploadEnabled !== undefined) + if (typeof message.docsAutoUploadEnabled !== "boolean") + return "docsAutoUploadEnabled: boolean expected"; + if (message.docsAutoUploadDelay !== undefined) + if (!$util.isInteger(message.docsAutoUploadDelay)) + return "docsAutoUploadDelay: integer expected"; return null; }; - FilmstripConfigProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto) + MapsOptions.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ClientOptionsProto.MapsOptions) return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto(); - if (object.requirements !== undefined && object.requirements !== null) { - if (typeof object.requirements !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.requirements: object expected"); - message.requirements = $types[0].fromObject(object.requirements); - } - if (object.alleycatUrlTemplate !== undefined && object.alleycatUrlTemplate !== null) { - if (typeof object.alleycatUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.alleycatUrlTemplate: object expected"); - message.alleycatUrlTemplate = $types[1].fromObject(object.alleycatUrlTemplate); - } - if (object.fallbackAlleycatUrlTemplate !== undefined && object.fallbackAlleycatUrlTemplate !== null) { - if (typeof object.fallbackAlleycatUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.fallbackAlleycatUrlTemplate: object expected"); - message.fallbackAlleycatUrlTemplate = $types[2].fromObject(object.fallbackAlleycatUrlTemplate); - } - if (object.metadataUrlTemplate !== undefined && object.metadataUrlTemplate !== null) { - if (typeof object.metadataUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.metadataUrlTemplate: object expected"); - message.metadataUrlTemplate = $types[3].fromObject(object.metadataUrlTemplate); - } - if (object.thumbnailUrlTemplate !== undefined && object.thumbnailUrlTemplate !== null) { - if (typeof object.thumbnailUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.thumbnailUrlTemplate: object expected"); - message.thumbnailUrlTemplate = $types[4].fromObject(object.thumbnailUrlTemplate); - } - if (object.kmlUrlTemplate !== undefined && object.kmlUrlTemplate !== null) { - if (typeof object.kmlUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.kmlUrlTemplate: object expected"); - message.kmlUrlTemplate = $types[5].fromObject(object.kmlUrlTemplate); - } - if (object.featuredToursUrl !== undefined && object.featuredToursUrl !== null) { - if (typeof object.featuredToursUrl !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.featuredToursUrl: object expected"); - message.featuredToursUrl = $types[6].fromObject(object.featuredToursUrl); - } - if (object.enableViewportFallback !== undefined && object.enableViewportFallback !== null) - message.enableViewportFallback = Boolean(object.enableViewportFallback); - if (object.viewportFallbackDistance !== undefined && object.viewportFallbackDistance !== null) - message.viewportFallbackDistance = object.viewportFallbackDistance >>> 0; - if (object.imageryType) { - if (!Array.isArray(object.imageryType)) - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: array expected"); - message.imageryType = []; - for (var i = 0; i < object.imageryType.length; ++i) { - if (typeof object.imageryType[i] !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: object expected"); - message.imageryType[i] = $types[9].fromObject(object.imageryType[i]); - } - } + var message = new $root.keyhole.dbroot.ClientOptionsProto.MapsOptions(); + if (object.enableMaps !== undefined && object.enableMaps !== null) + message.enableMaps = Boolean(object.enableMaps); + if (object.docsAutoDownloadEnabled !== undefined && object.docsAutoDownloadEnabled !== null) + message.docsAutoDownloadEnabled = Boolean(object.docsAutoDownloadEnabled); + if (object.docsAutoDownloadInterval !== undefined && object.docsAutoDownloadInterval !== null) + message.docsAutoDownloadInterval = object.docsAutoDownloadInterval | 0; + if (object.docsAutoUploadEnabled !== undefined && object.docsAutoUploadEnabled !== null) + message.docsAutoUploadEnabled = Boolean(object.docsAutoUploadEnabled); + if (object.docsAutoUploadDelay !== undefined && object.docsAutoUploadDelay !== null) + message.docsAutoUploadDelay = object.docsAutoUploadDelay | 0; return message; }; - FilmstripConfigProto.from = FilmstripConfigProto.fromObject; + MapsOptions.from = MapsOptions.fromObject; - FilmstripConfigProto.toObject = function toObject(message, options) { + MapsOptions.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) - object.imageryType = []; if (options.defaults) { - object.requirements = null; - object.alleycatUrlTemplate = null; - object.fallbackAlleycatUrlTemplate = null; - object.metadataUrlTemplate = null; - object.thumbnailUrlTemplate = null; - object.kmlUrlTemplate = null; - object.featuredToursUrl = null; - object.enableViewportFallback = false; - object.viewportFallbackDistance = 0; - } - if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) - object.requirements = $types[0].toObject(message.requirements, options); - if (message.alleycatUrlTemplate !== undefined && message.alleycatUrlTemplate !== null && message.hasOwnProperty("alleycatUrlTemplate")) - object.alleycatUrlTemplate = $types[1].toObject(message.alleycatUrlTemplate, options); - if (message.fallbackAlleycatUrlTemplate !== undefined && message.fallbackAlleycatUrlTemplate !== null && message.hasOwnProperty("fallbackAlleycatUrlTemplate")) - object.fallbackAlleycatUrlTemplate = $types[2].toObject(message.fallbackAlleycatUrlTemplate, options); - if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null && message.hasOwnProperty("metadataUrlTemplate")) - object.metadataUrlTemplate = $types[3].toObject(message.metadataUrlTemplate, options); - if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null && message.hasOwnProperty("thumbnailUrlTemplate")) - object.thumbnailUrlTemplate = $types[4].toObject(message.thumbnailUrlTemplate, options); - if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null && message.hasOwnProperty("kmlUrlTemplate")) - object.kmlUrlTemplate = $types[5].toObject(message.kmlUrlTemplate, options); - if (message.featuredToursUrl !== undefined && message.featuredToursUrl !== null && message.hasOwnProperty("featuredToursUrl")) - object.featuredToursUrl = $types[6].toObject(message.featuredToursUrl, options); - if (message.enableViewportFallback !== undefined && message.enableViewportFallback !== null && message.hasOwnProperty("enableViewportFallback")) - object.enableViewportFallback = message.enableViewportFallback; - if (message.viewportFallbackDistance !== undefined && message.viewportFallbackDistance !== null && message.hasOwnProperty("viewportFallbackDistance")) - object.viewportFallbackDistance = message.viewportFallbackDistance; - if (message.imageryType !== undefined && message.imageryType !== null && message.hasOwnProperty("imageryType")) { - object.imageryType = []; - for (var j = 0; j < message.imageryType.length; ++j) - object.imageryType[j] = $types[9].toObject(message.imageryType[j], options); - } - return object; - }; - - FilmstripConfigProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - FilmstripConfigProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - FilmstripConfigProto.AlleycatImageryTypeProto = (function() { - - function AlleycatImageryTypeProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - AlleycatImageryTypeProto.prototype.imageryTypeId = 0; - AlleycatImageryTypeProto.prototype.imageryTypeLabel = ""; - AlleycatImageryTypeProto.prototype.metadataUrlTemplate = null; - AlleycatImageryTypeProto.prototype.thumbnailUrlTemplate = null; - AlleycatImageryTypeProto.prototype.kmlUrlTemplate = null; - - var $types = { - 2 : "keyhole.dbroot.StringIdOrValueProto", - 3 : "keyhole.dbroot.StringIdOrValueProto", - 4 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); - - AlleycatImageryTypeProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.imageryTypeId = reader.int32(); - break; - case 2: - message.imageryTypeLabel = reader.string(); - break; - case 3: - message.metadataUrlTemplate = $types[2].decode(reader, reader.uint32()); - break; - case 4: - message.thumbnailUrlTemplate = $types[3].decode(reader, reader.uint32()); - break; - case 5: - message.kmlUrlTemplate = $types[4].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - AlleycatImageryTypeProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.imageryTypeId !== undefined) - if (!$util.isInteger(message.imageryTypeId)) - return "imageryTypeId: integer expected"; - if (message.imageryTypeLabel !== undefined) - if (!$util.isString(message.imageryTypeLabel)) - return "imageryTypeLabel: string expected"; - if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null) { - var error = $types[2].verify(message.metadataUrlTemplate); - if (error) - return "metadataUrlTemplate." + error; - } - if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null) { - var error = $types[3].verify(message.thumbnailUrlTemplate); - if (error) - return "thumbnailUrlTemplate." + error; - } - if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null) { - var error = $types[4].verify(message.kmlUrlTemplate); - if (error) - return "kmlUrlTemplate." + error; - } - return null; - }; - - AlleycatImageryTypeProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto(); - if (object.imageryTypeId !== undefined && object.imageryTypeId !== null) - message.imageryTypeId = object.imageryTypeId | 0; - if (object.imageryTypeLabel !== undefined && object.imageryTypeLabel !== null) - message.imageryTypeLabel = String(object.imageryTypeLabel); - if (object.metadataUrlTemplate !== undefined && object.metadataUrlTemplate !== null) { - if (typeof object.metadataUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.metadataUrlTemplate: object expected"); - message.metadataUrlTemplate = $types[2].fromObject(object.metadataUrlTemplate); - } - if (object.thumbnailUrlTemplate !== undefined && object.thumbnailUrlTemplate !== null) { - if (typeof object.thumbnailUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.thumbnailUrlTemplate: object expected"); - message.thumbnailUrlTemplate = $types[3].fromObject(object.thumbnailUrlTemplate); - } - if (object.kmlUrlTemplate !== undefined && object.kmlUrlTemplate !== null) { - if (typeof object.kmlUrlTemplate !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.kmlUrlTemplate: object expected"); - message.kmlUrlTemplate = $types[4].fromObject(object.kmlUrlTemplate); - } - return message; - }; - - AlleycatImageryTypeProto.from = AlleycatImageryTypeProto.fromObject; - - AlleycatImageryTypeProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.imageryTypeId = 0; - object.imageryTypeLabel = ""; - object.metadataUrlTemplate = null; - object.thumbnailUrlTemplate = null; - object.kmlUrlTemplate = null; - } - if (message.imageryTypeId !== undefined && message.imageryTypeId !== null && message.hasOwnProperty("imageryTypeId")) - object.imageryTypeId = message.imageryTypeId; - if (message.imageryTypeLabel !== undefined && message.imageryTypeLabel !== null && message.hasOwnProperty("imageryTypeLabel")) - object.imageryTypeLabel = message.imageryTypeLabel; - if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null && message.hasOwnProperty("metadataUrlTemplate")) - object.metadataUrlTemplate = $types[2].toObject(message.metadataUrlTemplate, options); - if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null && message.hasOwnProperty("thumbnailUrlTemplate")) - object.thumbnailUrlTemplate = $types[3].toObject(message.thumbnailUrlTemplate, options); - if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null && message.hasOwnProperty("kmlUrlTemplate")) - object.kmlUrlTemplate = $types[4].toObject(message.kmlUrlTemplate, options); - return object; - }; - - AlleycatImageryTypeProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - AlleycatImageryTypeProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return AlleycatImageryTypeProto; - })(); - - return FilmstripConfigProto; - })(); - - EndSnippetProto.StarDataProto = (function() { - - function StarDataProto(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - this[keys[i]] = properties[keys[i]]; - } - - StarDataProto.prototype.url = null; - - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto" - }; - $lazyTypes.push($types); - - StarDataProto.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EndSnippetProto.StarDataProto(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.url = $types[0].decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - StarDataProto.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.url !== undefined && message.url !== null) { - var error = $types[0].verify(message.url); - if (error) - return "url." + error; - } - return null; - }; - - StarDataProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EndSnippetProto.StarDataProto) - return object; - var message = new $root.keyhole.dbroot.EndSnippetProto.StarDataProto(); - if (object.url !== undefined && object.url !== null) { - if (typeof object.url !== "object") - throw TypeError(".keyhole.dbroot.EndSnippetProto.StarDataProto.url: object expected"); - message.url = $types[0].fromObject(object.url); + object.enableMaps = false; + object.docsAutoDownloadEnabled = false; + object.docsAutoDownloadInterval = 0; + object.docsAutoUploadEnabled = false; + object.docsAutoUploadDelay = 0; } - return message; - }; - - StarDataProto.from = StarDataProto.fromObject; - - StarDataProto.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.url = null; - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = $types[0].toObject(message.url, options); + if (message.enableMaps !== undefined && message.enableMaps !== null && message.hasOwnProperty("enableMaps")) + object.enableMaps = message.enableMaps; + if (message.docsAutoDownloadEnabled !== undefined && message.docsAutoDownloadEnabled !== null && message.hasOwnProperty("docsAutoDownloadEnabled")) + object.docsAutoDownloadEnabled = message.docsAutoDownloadEnabled; + if (message.docsAutoDownloadInterval !== undefined && message.docsAutoDownloadInterval !== null && message.hasOwnProperty("docsAutoDownloadInterval")) + object.docsAutoDownloadInterval = message.docsAutoDownloadInterval; + if (message.docsAutoUploadEnabled !== undefined && message.docsAutoUploadEnabled !== null && message.hasOwnProperty("docsAutoUploadEnabled")) + object.docsAutoUploadEnabled = message.docsAutoUploadEnabled; + if (message.docsAutoUploadDelay !== undefined && message.docsAutoUploadDelay !== null && message.hasOwnProperty("docsAutoUploadDelay")) + object.docsAutoUploadDelay = message.docsAutoUploadDelay; return object; }; - StarDataProto.prototype.toObject = function toObject(options) { + MapsOptions.prototype.toObject = function toObject(options) { return this.constructor.toObject(this, options); }; - StarDataProto.prototype.toJSON = function toJSON() { + MapsOptions.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return StarDataProto; + return MapsOptions; })(); - return EndSnippetProto; + return ClientOptionsProto; })(); - dbroot.DbRootRefProto = (function() { + dbroot.FetchingOptionsProto = (function() { - function DbRootRefProto(properties) { + function FetchingOptionsProto(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) this[keys[i]] = properties[keys[i]]; } - DbRootRefProto.prototype.url = ""; - DbRootRefProto.prototype.isCritical = false; - DbRootRefProto.prototype.requirements = null; - - var $types = { - 2 : "keyhole.dbroot.RequirementProto" - }; - $lazyTypes.push($types); + FetchingOptionsProto.prototype.maxRequestsPerQuery = 1; + FetchingOptionsProto.prototype.forceMaxRequestsPerQuery = false; + FetchingOptionsProto.prototype.sortBatches = false; + FetchingOptionsProto.prototype.maxDrawable = 2; + FetchingOptionsProto.prototype.maxImagery = 2; + FetchingOptionsProto.prototype.maxTerrain = 5; + FetchingOptionsProto.prototype.maxQuadtree = 5; + FetchingOptionsProto.prototype.maxDioramaMetadata = 1; + FetchingOptionsProto.prototype.maxDioramaData = 0; + FetchingOptionsProto.prototype.maxConsumerFetchRatio = 1; + FetchingOptionsProto.prototype.maxProEcFetchRatio = 0; + FetchingOptionsProto.prototype.safeOverallQps = 0; + FetchingOptionsProto.prototype.safeImageryQps = 0; + FetchingOptionsProto.prototype.domainsForHttps = "google.com gstatic.com"; + FetchingOptionsProto.prototype.hostsForHttp = ""; - DbRootRefProto.decode = function decode(reader, length) { + FetchingOptionsProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.DbRootRefProto(); + message = new $root.keyhole.dbroot.FetchingOptionsProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 2: - message.url = reader.string(); - break; case 1: - message.isCritical = reader.bool(); + message.maxRequestsPerQuery = reader.int32(); + break; + case 12: + message.forceMaxRequestsPerQuery = reader.bool(); + break; + case 13: + message.sortBatches = reader.bool(); + break; + case 2: + message.maxDrawable = reader.int32(); break; case 3: - message.requirements = $types[2].decode(reader, reader.uint32()); + message.maxImagery = reader.int32(); + break; + case 4: + message.maxTerrain = reader.int32(); + break; + case 5: + message.maxQuadtree = reader.int32(); + break; + case 6: + message.maxDioramaMetadata = reader.int32(); + break; + case 7: + message.maxDioramaData = reader.int32(); + break; + case 8: + message.maxConsumerFetchRatio = reader.float(); + break; + case 9: + message.maxProEcFetchRatio = reader.float(); + break; + case 10: + message.safeOverallQps = reader.float(); + break; + case 11: + message.safeImageryQps = reader.float(); + break; + case 14: + message.domainsForHttps = reader.string(); + break; + case 15: + message.hostsForHttp = reader.string(); break; default: reader.skipType(tag & 7); @@ -62694,89 +59460,193 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - DbRootRefProto.verify = function verify(message) { + FetchingOptionsProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (!$util.isString(message.url)) - return "url: string expected"; - if (message.isCritical !== undefined) - if (typeof message.isCritical !== "boolean") - return "isCritical: boolean expected"; - if (message.requirements !== undefined && message.requirements !== null) { - var error = $types[2].verify(message.requirements); - if (error) - return "requirements." + error; - } + if (message.maxRequestsPerQuery !== undefined) + if (!$util.isInteger(message.maxRequestsPerQuery)) + return "maxRequestsPerQuery: integer expected"; + if (message.forceMaxRequestsPerQuery !== undefined) + if (typeof message.forceMaxRequestsPerQuery !== "boolean") + return "forceMaxRequestsPerQuery: boolean expected"; + if (message.sortBatches !== undefined) + if (typeof message.sortBatches !== "boolean") + return "sortBatches: boolean expected"; + if (message.maxDrawable !== undefined) + if (!$util.isInteger(message.maxDrawable)) + return "maxDrawable: integer expected"; + if (message.maxImagery !== undefined) + if (!$util.isInteger(message.maxImagery)) + return "maxImagery: integer expected"; + if (message.maxTerrain !== undefined) + if (!$util.isInteger(message.maxTerrain)) + return "maxTerrain: integer expected"; + if (message.maxQuadtree !== undefined) + if (!$util.isInteger(message.maxQuadtree)) + return "maxQuadtree: integer expected"; + if (message.maxDioramaMetadata !== undefined) + if (!$util.isInteger(message.maxDioramaMetadata)) + return "maxDioramaMetadata: integer expected"; + if (message.maxDioramaData !== undefined) + if (!$util.isInteger(message.maxDioramaData)) + return "maxDioramaData: integer expected"; + if (message.maxConsumerFetchRatio !== undefined) + if (typeof message.maxConsumerFetchRatio !== "number") + return "maxConsumerFetchRatio: number expected"; + if (message.maxProEcFetchRatio !== undefined) + if (typeof message.maxProEcFetchRatio !== "number") + return "maxProEcFetchRatio: number expected"; + if (message.safeOverallQps !== undefined) + if (typeof message.safeOverallQps !== "number") + return "safeOverallQps: number expected"; + if (message.safeImageryQps !== undefined) + if (typeof message.safeImageryQps !== "number") + return "safeImageryQps: number expected"; + if (message.domainsForHttps !== undefined) + if (!$util.isString(message.domainsForHttps)) + return "domainsForHttps: string expected"; + if (message.hostsForHttp !== undefined) + if (!$util.isString(message.hostsForHttp)) + return "hostsForHttp: string expected"; return null; }; - DbRootRefProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.DbRootRefProto) + FetchingOptionsProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.FetchingOptionsProto) return object; - var message = new $root.keyhole.dbroot.DbRootRefProto(); - if (object.url !== undefined && object.url !== null) - message.url = String(object.url); - if (object.isCritical !== undefined && object.isCritical !== null) - message.isCritical = Boolean(object.isCritical); - if (object.requirements !== undefined && object.requirements !== null) { - if (typeof object.requirements !== "object") - throw TypeError(".keyhole.dbroot.DbRootRefProto.requirements: object expected"); - message.requirements = $types[2].fromObject(object.requirements); - } + var message = new $root.keyhole.dbroot.FetchingOptionsProto(); + if (object.maxRequestsPerQuery !== undefined && object.maxRequestsPerQuery !== null) + message.maxRequestsPerQuery = object.maxRequestsPerQuery | 0; + if (object.forceMaxRequestsPerQuery !== undefined && object.forceMaxRequestsPerQuery !== null) + message.forceMaxRequestsPerQuery = Boolean(object.forceMaxRequestsPerQuery); + if (object.sortBatches !== undefined && object.sortBatches !== null) + message.sortBatches = Boolean(object.sortBatches); + if (object.maxDrawable !== undefined && object.maxDrawable !== null) + message.maxDrawable = object.maxDrawable | 0; + if (object.maxImagery !== undefined && object.maxImagery !== null) + message.maxImagery = object.maxImagery | 0; + if (object.maxTerrain !== undefined && object.maxTerrain !== null) + message.maxTerrain = object.maxTerrain | 0; + if (object.maxQuadtree !== undefined && object.maxQuadtree !== null) + message.maxQuadtree = object.maxQuadtree | 0; + if (object.maxDioramaMetadata !== undefined && object.maxDioramaMetadata !== null) + message.maxDioramaMetadata = object.maxDioramaMetadata | 0; + if (object.maxDioramaData !== undefined && object.maxDioramaData !== null) + message.maxDioramaData = object.maxDioramaData | 0; + if (object.maxConsumerFetchRatio !== undefined && object.maxConsumerFetchRatio !== null) + message.maxConsumerFetchRatio = Number(object.maxConsumerFetchRatio); + if (object.maxProEcFetchRatio !== undefined && object.maxProEcFetchRatio !== null) + message.maxProEcFetchRatio = Number(object.maxProEcFetchRatio); + if (object.safeOverallQps !== undefined && object.safeOverallQps !== null) + message.safeOverallQps = Number(object.safeOverallQps); + if (object.safeImageryQps !== undefined && object.safeImageryQps !== null) + message.safeImageryQps = Number(object.safeImageryQps); + if (object.domainsForHttps !== undefined && object.domainsForHttps !== null) + message.domainsForHttps = String(object.domainsForHttps); + if (object.hostsForHttp !== undefined && object.hostsForHttp !== null) + message.hostsForHttp = String(object.hostsForHttp); return message; }; - DbRootRefProto.from = DbRootRefProto.fromObject; + FetchingOptionsProto.from = FetchingOptionsProto.fromObject; - DbRootRefProto.toObject = function toObject(message, options) { + FetchingOptionsProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.url = ""; - object.isCritical = false; - object.requirements = null; + object.maxRequestsPerQuery = 1; + object.forceMaxRequestsPerQuery = false; + object.sortBatches = false; + object.maxDrawable = 2; + object.maxImagery = 2; + object.maxTerrain = 5; + object.maxQuadtree = 5; + object.maxDioramaMetadata = 1; + object.maxDioramaData = 0; + object.maxConsumerFetchRatio = 1; + object.maxProEcFetchRatio = 0; + object.safeOverallQps = 0; + object.safeImageryQps = 0; + object.domainsForHttps = "google.com gstatic.com"; + object.hostsForHttp = ""; } - if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) - object.url = message.url; - if (message.isCritical !== undefined && message.isCritical !== null && message.hasOwnProperty("isCritical")) - object.isCritical = message.isCritical; - if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) - object.requirements = $types[2].toObject(message.requirements, options); - return object; - }; - - DbRootRefProto.prototype.toObject = function toObject(options) { - return this.constructor.toObject(this, options); - }; - - DbRootRefProto.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return DbRootRefProto; - })(); - - dbroot.DatabaseVersionProto = (function() { + if (message.maxRequestsPerQuery !== undefined && message.maxRequestsPerQuery !== null && message.hasOwnProperty("maxRequestsPerQuery")) + object.maxRequestsPerQuery = message.maxRequestsPerQuery; + if (message.forceMaxRequestsPerQuery !== undefined && message.forceMaxRequestsPerQuery !== null && message.hasOwnProperty("forceMaxRequestsPerQuery")) + object.forceMaxRequestsPerQuery = message.forceMaxRequestsPerQuery; + if (message.sortBatches !== undefined && message.sortBatches !== null && message.hasOwnProperty("sortBatches")) + object.sortBatches = message.sortBatches; + if (message.maxDrawable !== undefined && message.maxDrawable !== null && message.hasOwnProperty("maxDrawable")) + object.maxDrawable = message.maxDrawable; + if (message.maxImagery !== undefined && message.maxImagery !== null && message.hasOwnProperty("maxImagery")) + object.maxImagery = message.maxImagery; + if (message.maxTerrain !== undefined && message.maxTerrain !== null && message.hasOwnProperty("maxTerrain")) + object.maxTerrain = message.maxTerrain; + if (message.maxQuadtree !== undefined && message.maxQuadtree !== null && message.hasOwnProperty("maxQuadtree")) + object.maxQuadtree = message.maxQuadtree; + if (message.maxDioramaMetadata !== undefined && message.maxDioramaMetadata !== null && message.hasOwnProperty("maxDioramaMetadata")) + object.maxDioramaMetadata = message.maxDioramaMetadata; + if (message.maxDioramaData !== undefined && message.maxDioramaData !== null && message.hasOwnProperty("maxDioramaData")) + object.maxDioramaData = message.maxDioramaData; + if (message.maxConsumerFetchRatio !== undefined && message.maxConsumerFetchRatio !== null && message.hasOwnProperty("maxConsumerFetchRatio")) + object.maxConsumerFetchRatio = message.maxConsumerFetchRatio; + if (message.maxProEcFetchRatio !== undefined && message.maxProEcFetchRatio !== null && message.hasOwnProperty("maxProEcFetchRatio")) + object.maxProEcFetchRatio = message.maxProEcFetchRatio; + if (message.safeOverallQps !== undefined && message.safeOverallQps !== null && message.hasOwnProperty("safeOverallQps")) + object.safeOverallQps = message.safeOverallQps; + if (message.safeImageryQps !== undefined && message.safeImageryQps !== null && message.hasOwnProperty("safeImageryQps")) + object.safeImageryQps = message.safeImageryQps; + if (message.domainsForHttps !== undefined && message.domainsForHttps !== null && message.hasOwnProperty("domainsForHttps")) + object.domainsForHttps = message.domainsForHttps; + if (message.hostsForHttp !== undefined && message.hostsForHttp !== null && message.hasOwnProperty("hostsForHttp")) + object.hostsForHttp = message.hostsForHttp; + return object; + }; - function DatabaseVersionProto(properties) { + FetchingOptionsProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + FetchingOptionsProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return FetchingOptionsProto; + })(); + + dbroot.TimeMachineOptionsProto = (function() { + + function TimeMachineOptionsProto(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) this[keys[i]] = properties[keys[i]]; } - DatabaseVersionProto.prototype.quadtreeVersion = 0; + TimeMachineOptionsProto.prototype.serverUrl = ""; + TimeMachineOptionsProto.prototype.isTimemachine = false; + TimeMachineOptionsProto.prototype.dwellTimeMs = 500; + TimeMachineOptionsProto.prototype.discoverabilityAltitudeMeters = 15000; - DatabaseVersionProto.decode = function decode(reader, length) { + TimeMachineOptionsProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.DatabaseVersionProto(); + message = new $root.keyhole.dbroot.TimeMachineOptionsProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.quadtreeVersion = reader.uint32(); + message.serverUrl = reader.string(); + break; + case 2: + message.isTimemachine = reader.bool(); + break; + case 3: + message.dwellTimeMs = reader.int32(); + break; + case 4: + message.discoverabilityAltitudeMeters = reader.int32(); break; default: reader.skipType(tag & 7); @@ -62786,148 +59656,326 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - DatabaseVersionProto.verify = function verify(message) { + TimeMachineOptionsProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (!$util.isInteger(message.quadtreeVersion)) - return "quadtreeVersion: integer expected"; + if (message.serverUrl !== undefined) + if (!$util.isString(message.serverUrl)) + return "serverUrl: string expected"; + if (message.isTimemachine !== undefined) + if (typeof message.isTimemachine !== "boolean") + return "isTimemachine: boolean expected"; + if (message.dwellTimeMs !== undefined) + if (!$util.isInteger(message.dwellTimeMs)) + return "dwellTimeMs: integer expected"; + if (message.discoverabilityAltitudeMeters !== undefined) + if (!$util.isInteger(message.discoverabilityAltitudeMeters)) + return "discoverabilityAltitudeMeters: integer expected"; return null; }; - DatabaseVersionProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.DatabaseVersionProto) + TimeMachineOptionsProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.TimeMachineOptionsProto) return object; - var message = new $root.keyhole.dbroot.DatabaseVersionProto(); - if (object.quadtreeVersion !== undefined && object.quadtreeVersion !== null) - message.quadtreeVersion = object.quadtreeVersion >>> 0; + var message = new $root.keyhole.dbroot.TimeMachineOptionsProto(); + if (object.serverUrl !== undefined && object.serverUrl !== null) + message.serverUrl = String(object.serverUrl); + if (object.isTimemachine !== undefined && object.isTimemachine !== null) + message.isTimemachine = Boolean(object.isTimemachine); + if (object.dwellTimeMs !== undefined && object.dwellTimeMs !== null) + message.dwellTimeMs = object.dwellTimeMs | 0; + if (object.discoverabilityAltitudeMeters !== undefined && object.discoverabilityAltitudeMeters !== null) + message.discoverabilityAltitudeMeters = object.discoverabilityAltitudeMeters | 0; return message; }; - DatabaseVersionProto.from = DatabaseVersionProto.fromObject; + TimeMachineOptionsProto.from = TimeMachineOptionsProto.fromObject; - DatabaseVersionProto.toObject = function toObject(message, options) { + TimeMachineOptionsProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.defaults) - object.quadtreeVersion = 0; - if (message.quadtreeVersion !== undefined && message.quadtreeVersion !== null && message.hasOwnProperty("quadtreeVersion")) - object.quadtreeVersion = message.quadtreeVersion; + if (options.defaults) { + object.serverUrl = ""; + object.isTimemachine = false; + object.dwellTimeMs = 500; + object.discoverabilityAltitudeMeters = 15000; + } + if (message.serverUrl !== undefined && message.serverUrl !== null && message.hasOwnProperty("serverUrl")) + object.serverUrl = message.serverUrl; + if (message.isTimemachine !== undefined && message.isTimemachine !== null && message.hasOwnProperty("isTimemachine")) + object.isTimemachine = message.isTimemachine; + if (message.dwellTimeMs !== undefined && message.dwellTimeMs !== null && message.hasOwnProperty("dwellTimeMs")) + object.dwellTimeMs = message.dwellTimeMs; + if (message.discoverabilityAltitudeMeters !== undefined && message.discoverabilityAltitudeMeters !== null && message.hasOwnProperty("discoverabilityAltitudeMeters")) + object.discoverabilityAltitudeMeters = message.discoverabilityAltitudeMeters; return object; }; - DatabaseVersionProto.prototype.toObject = function toObject(options) { + TimeMachineOptionsProto.prototype.toObject = function toObject(options) { return this.constructor.toObject(this, options); }; - DatabaseVersionProto.prototype.toJSON = function toJSON() { + TimeMachineOptionsProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return DatabaseVersionProto; + return TimeMachineOptionsProto; })(); - dbroot.DbRootProto = (function() { + dbroot.AutopiaOptionsProto = (function() { - function DbRootProto(properties) { + function AutopiaOptionsProto(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) this[keys[i]] = properties[keys[i]]; } - DbRootProto.prototype.databaseName = null; - DbRootProto.prototype.imageryPresent = true; - DbRootProto.prototype.protoImagery = false; - DbRootProto.prototype.terrainPresent = false; - DbRootProto.prototype.providerInfo = $util.emptyArray; - DbRootProto.prototype.nestedFeature = $util.emptyArray; - DbRootProto.prototype.styleAttribute = $util.emptyArray; - DbRootProto.prototype.styleMap = $util.emptyArray; - DbRootProto.prototype.endSnippet = null; - DbRootProto.prototype.translationEntry = $util.emptyArray; - DbRootProto.prototype.language = "en"; - DbRootProto.prototype.version = 5; - DbRootProto.prototype.dbrootReference = $util.emptyArray; - DbRootProto.prototype.databaseVersion = null; - DbRootProto.prototype.refreshTimeout = 0; - - var $types = { - 0 : "keyhole.dbroot.StringIdOrValueProto", - 4 : "keyhole.dbroot.ProviderInfoProto", - 5 : "keyhole.dbroot.NestedFeatureProto", - 6 : "keyhole.dbroot.StyleAttributeProto", - 7 : "keyhole.dbroot.StyleMapProto", - 8 : "keyhole.dbroot.EndSnippetProto", - 9 : "keyhole.dbroot.StringEntryProto", - 12 : "keyhole.dbroot.DbRootRefProto", - 13 : "keyhole.dbroot.DatabaseVersionProto" - }; - $lazyTypes.push($types); + AutopiaOptionsProto.prototype.metadataServerUrl = "http://cbk0.google.com/cbk"; + AutopiaOptionsProto.prototype.depthmapServerUrl = "http://cbk0.google.com/cbk"; + AutopiaOptionsProto.prototype.coverageOverlayUrl = ""; + AutopiaOptionsProto.prototype.maxImageryQps = 0; + AutopiaOptionsProto.prototype.maxMetadataDepthmapQps = 0; - DbRootProto.decode = function decode(reader, length) { + AutopiaOptionsProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.DbRootProto(); + message = new $root.keyhole.dbroot.AutopiaOptionsProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 15: - message.databaseName = $types[0].decode(reader, reader.uint32()); - break; case 1: - message.imageryPresent = reader.bool(); - break; - case 14: - message.protoImagery = reader.bool(); + message.metadataServerUrl = reader.string(); break; case 2: - message.terrainPresent = reader.bool(); + message.depthmapServerUrl = reader.string(); break; case 3: - if (!(message.providerInfo && message.providerInfo.length)) - message.providerInfo = []; - message.providerInfo.push($types[4].decode(reader, reader.uint32())); + message.coverageOverlayUrl = reader.string(); break; case 4: - if (!(message.nestedFeature && message.nestedFeature.length)) - message.nestedFeature = []; - message.nestedFeature.push($types[5].decode(reader, reader.uint32())); + message.maxImageryQps = reader.float(); break; case 5: - if (!(message.styleAttribute && message.styleAttribute.length)) - message.styleAttribute = []; - message.styleAttribute.push($types[6].decode(reader, reader.uint32())); + message.maxMetadataDepthmapQps = reader.float(); break; - case 6: - if (!(message.styleMap && message.styleMap.length)) - message.styleMap = []; - message.styleMap.push($types[7].decode(reader, reader.uint32())); + default: + reader.skipType(tag & 7); break; - case 7: - message.endSnippet = $types[8].decode(reader, reader.uint32()); + } + } + return message; + }; + + AutopiaOptionsProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.metadataServerUrl !== undefined) + if (!$util.isString(message.metadataServerUrl)) + return "metadataServerUrl: string expected"; + if (message.depthmapServerUrl !== undefined) + if (!$util.isString(message.depthmapServerUrl)) + return "depthmapServerUrl: string expected"; + if (message.coverageOverlayUrl !== undefined) + if (!$util.isString(message.coverageOverlayUrl)) + return "coverageOverlayUrl: string expected"; + if (message.maxImageryQps !== undefined) + if (typeof message.maxImageryQps !== "number") + return "maxImageryQps: number expected"; + if (message.maxMetadataDepthmapQps !== undefined) + if (typeof message.maxMetadataDepthmapQps !== "number") + return "maxMetadataDepthmapQps: number expected"; + return null; + }; + + AutopiaOptionsProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.AutopiaOptionsProto) + return object; + var message = new $root.keyhole.dbroot.AutopiaOptionsProto(); + if (object.metadataServerUrl !== undefined && object.metadataServerUrl !== null) + message.metadataServerUrl = String(object.metadataServerUrl); + if (object.depthmapServerUrl !== undefined && object.depthmapServerUrl !== null) + message.depthmapServerUrl = String(object.depthmapServerUrl); + if (object.coverageOverlayUrl !== undefined && object.coverageOverlayUrl !== null) + message.coverageOverlayUrl = String(object.coverageOverlayUrl); + if (object.maxImageryQps !== undefined && object.maxImageryQps !== null) + message.maxImageryQps = Number(object.maxImageryQps); + if (object.maxMetadataDepthmapQps !== undefined && object.maxMetadataDepthmapQps !== null) + message.maxMetadataDepthmapQps = Number(object.maxMetadataDepthmapQps); + return message; + }; + + AutopiaOptionsProto.from = AutopiaOptionsProto.fromObject; + + AutopiaOptionsProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.metadataServerUrl = "http://cbk0.google.com/cbk"; + object.depthmapServerUrl = "http://cbk0.google.com/cbk"; + object.coverageOverlayUrl = ""; + object.maxImageryQps = 0; + object.maxMetadataDepthmapQps = 0; + } + if (message.metadataServerUrl !== undefined && message.metadataServerUrl !== null && message.hasOwnProperty("metadataServerUrl")) + object.metadataServerUrl = message.metadataServerUrl; + if (message.depthmapServerUrl !== undefined && message.depthmapServerUrl !== null && message.hasOwnProperty("depthmapServerUrl")) + object.depthmapServerUrl = message.depthmapServerUrl; + if (message.coverageOverlayUrl !== undefined && message.coverageOverlayUrl !== null && message.hasOwnProperty("coverageOverlayUrl")) + object.coverageOverlayUrl = message.coverageOverlayUrl; + if (message.maxImageryQps !== undefined && message.maxImageryQps !== null && message.hasOwnProperty("maxImageryQps")) + object.maxImageryQps = message.maxImageryQps; + if (message.maxMetadataDepthmapQps !== undefined && message.maxMetadataDepthmapQps !== null && message.hasOwnProperty("maxMetadataDepthmapQps")) + object.maxMetadataDepthmapQps = message.maxMetadataDepthmapQps; + return object; + }; + + AutopiaOptionsProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + AutopiaOptionsProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return AutopiaOptionsProto; + })(); + + dbroot.CSIOptionsProto = (function() { + + function CSIOptionsProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + CSIOptionsProto.prototype.samplingPercentage = 0; + CSIOptionsProto.prototype.experimentId = ""; + + CSIOptionsProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.CSIOptionsProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.samplingPercentage = reader.int32(); break; - case 8: - if (!(message.translationEntry && message.translationEntry.length)) - message.translationEntry = []; - message.translationEntry.push($types[9].decode(reader, reader.uint32())); + case 2: + message.experimentId = reader.string(); break; - case 9: - message.language = reader.string(); + default: + reader.skipType(tag & 7); break; - case 10: - message.version = reader.int32(); + } + } + return message; + }; + + CSIOptionsProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.samplingPercentage !== undefined) + if (!$util.isInteger(message.samplingPercentage)) + return "samplingPercentage: integer expected"; + if (message.experimentId !== undefined) + if (!$util.isString(message.experimentId)) + return "experimentId: string expected"; + return null; + }; + + CSIOptionsProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.CSIOptionsProto) + return object; + var message = new $root.keyhole.dbroot.CSIOptionsProto(); + if (object.samplingPercentage !== undefined && object.samplingPercentage !== null) + message.samplingPercentage = object.samplingPercentage | 0; + if (object.experimentId !== undefined && object.experimentId !== null) + message.experimentId = String(object.experimentId); + return message; + }; + + CSIOptionsProto.from = CSIOptionsProto.fromObject; + + CSIOptionsProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.samplingPercentage = 0; + object.experimentId = ""; + } + if (message.samplingPercentage !== undefined && message.samplingPercentage !== null && message.hasOwnProperty("samplingPercentage")) + object.samplingPercentage = message.samplingPercentage; + if (message.experimentId !== undefined && message.experimentId !== null && message.hasOwnProperty("experimentId")) + object.experimentId = message.experimentId; + return object; + }; + + CSIOptionsProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + CSIOptionsProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return CSIOptionsProto; + })(); + + dbroot.SearchTabProto = (function() { + + function SearchTabProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + SearchTabProto.prototype.isVisible = false; + SearchTabProto.prototype.tabLabel = null; + SearchTabProto.prototype.baseUrl = ""; + SearchTabProto.prototype.viewportPrefix = ""; + SearchTabProto.prototype.inputBox = $util.emptyArray; + SearchTabProto.prototype.requirement = null; + + var $types = { + 1 : "keyhole.dbroot.StringIdOrValueProto", + 4 : "keyhole.dbroot.SearchTabProto.InputBoxInfo", + 5 : "keyhole.dbroot.RequirementProto" + }; + $lazyTypes.push($types); + + SearchTabProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.SearchTabProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.isVisible = reader.bool(); break; - case 11: - if (!(message.dbrootReference && message.dbrootReference.length)) - message.dbrootReference = []; - message.dbrootReference.push($types[12].decode(reader, reader.uint32())); + case 2: + message.tabLabel = $types[1].decode(reader, reader.uint32()); break; - case 13: - message.databaseVersion = $types[13].decode(reader, reader.uint32()); + case 3: + message.baseUrl = reader.string(); break; - case 16: - message.refreshTimeout = reader.int32(); + case 4: + message.viewportPrefix = reader.string(); + break; + case 5: + if (!(message.inputBox && message.inputBox.length)) + message.inputBox = []; + message.inputBox.push($types[4].decode(reader, reader.uint32())); + break; + case 6: + message.requirement = $types[5].decode(reader, reader.uint32()); break; default: reader.skipType(tag & 7); @@ -62937,313 +59985,262 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - DbRootProto.verify = function verify(message) { + SearchTabProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.databaseName !== undefined && message.databaseName !== null) { - var error = $types[0].verify(message.databaseName); - if (error) - return "databaseName." + error; - } - if (message.imageryPresent !== undefined) - if (typeof message.imageryPresent !== "boolean") - return "imageryPresent: boolean expected"; - if (message.protoImagery !== undefined) - if (typeof message.protoImagery !== "boolean") - return "protoImagery: boolean expected"; - if (message.terrainPresent !== undefined) - if (typeof message.terrainPresent !== "boolean") - return "terrainPresent: boolean expected"; - if (message.providerInfo !== undefined) { - if (!Array.isArray(message.providerInfo)) - return "providerInfo: array expected"; - for (var i = 0; i < message.providerInfo.length; ++i) { - var error = $types[4].verify(message.providerInfo[i]); - if (error) - return "providerInfo." + error; - } - } - if (message.nestedFeature !== undefined) { - if (!Array.isArray(message.nestedFeature)) - return "nestedFeature: array expected"; - for (var i = 0; i < message.nestedFeature.length; ++i) { - var error = $types[5].verify(message.nestedFeature[i]); - if (error) - return "nestedFeature." + error; - } - } - if (message.styleAttribute !== undefined) { - if (!Array.isArray(message.styleAttribute)) - return "styleAttribute: array expected"; - for (var i = 0; i < message.styleAttribute.length; ++i) { - var error = $types[6].verify(message.styleAttribute[i]); - if (error) - return "styleAttribute." + error; - } - } - if (message.styleMap !== undefined) { - if (!Array.isArray(message.styleMap)) - return "styleMap: array expected"; - for (var i = 0; i < message.styleMap.length; ++i) { - var error = $types[7].verify(message.styleMap[i]); - if (error) - return "styleMap." + error; - } - } - if (message.endSnippet !== undefined && message.endSnippet !== null) { - var error = $types[8].verify(message.endSnippet); + if (typeof message.isVisible !== "boolean") + return "isVisible: boolean expected"; + if (message.tabLabel !== undefined && message.tabLabel !== null) { + var error = $types[1].verify(message.tabLabel); if (error) - return "endSnippet." + error; - } - if (message.translationEntry !== undefined) { - if (!Array.isArray(message.translationEntry)) - return "translationEntry: array expected"; - for (var i = 0; i < message.translationEntry.length; ++i) { - var error = $types[9].verify(message.translationEntry[i]); - if (error) - return "translationEntry." + error; - } + return "tabLabel." + error; } - if (message.language !== undefined) - if (!$util.isString(message.language)) - return "language: string expected"; - if (message.version !== undefined) - if (!$util.isInteger(message.version)) - return "version: integer expected"; - if (message.dbrootReference !== undefined) { - if (!Array.isArray(message.dbrootReference)) - return "dbrootReference: array expected"; - for (var i = 0; i < message.dbrootReference.length; ++i) { - var error = $types[12].verify(message.dbrootReference[i]); + if (message.baseUrl !== undefined) + if (!$util.isString(message.baseUrl)) + return "baseUrl: string expected"; + if (message.viewportPrefix !== undefined) + if (!$util.isString(message.viewportPrefix)) + return "viewportPrefix: string expected"; + if (message.inputBox !== undefined) { + if (!Array.isArray(message.inputBox)) + return "inputBox: array expected"; + for (var i = 0; i < message.inputBox.length; ++i) { + var error = $types[4].verify(message.inputBox[i]); if (error) - return "dbrootReference." + error; + return "inputBox." + error; } } - if (message.databaseVersion !== undefined && message.databaseVersion !== null) { - var error = $types[13].verify(message.databaseVersion); + if (message.requirement !== undefined && message.requirement !== null) { + var error = $types[5].verify(message.requirement); if (error) - return "databaseVersion." + error; + return "requirement." + error; } - if (message.refreshTimeout !== undefined) - if (!$util.isInteger(message.refreshTimeout)) - return "refreshTimeout: integer expected"; return null; }; - DbRootProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.DbRootProto) + SearchTabProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.SearchTabProto) return object; - var message = new $root.keyhole.dbroot.DbRootProto(); - if (object.databaseName !== undefined && object.databaseName !== null) { - if (typeof object.databaseName !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.databaseName: object expected"); - message.databaseName = $types[0].fromObject(object.databaseName); - } - if (object.imageryPresent !== undefined && object.imageryPresent !== null) - message.imageryPresent = Boolean(object.imageryPresent); - if (object.protoImagery !== undefined && object.protoImagery !== null) - message.protoImagery = Boolean(object.protoImagery); - if (object.terrainPresent !== undefined && object.terrainPresent !== null) - message.terrainPresent = Boolean(object.terrainPresent); - if (object.providerInfo) { - if (!Array.isArray(object.providerInfo)) - throw TypeError(".keyhole.dbroot.DbRootProto.providerInfo: array expected"); - message.providerInfo = []; - for (var i = 0; i < object.providerInfo.length; ++i) { - if (typeof object.providerInfo[i] !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.providerInfo: object expected"); - message.providerInfo[i] = $types[4].fromObject(object.providerInfo[i]); - } - } - if (object.nestedFeature) { - if (!Array.isArray(object.nestedFeature)) - throw TypeError(".keyhole.dbroot.DbRootProto.nestedFeature: array expected"); - message.nestedFeature = []; - for (var i = 0; i < object.nestedFeature.length; ++i) { - if (typeof object.nestedFeature[i] !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.nestedFeature: object expected"); - message.nestedFeature[i] = $types[5].fromObject(object.nestedFeature[i]); - } - } - if (object.styleAttribute) { - if (!Array.isArray(object.styleAttribute)) - throw TypeError(".keyhole.dbroot.DbRootProto.styleAttribute: array expected"); - message.styleAttribute = []; - for (var i = 0; i < object.styleAttribute.length; ++i) { - if (typeof object.styleAttribute[i] !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.styleAttribute: object expected"); - message.styleAttribute[i] = $types[6].fromObject(object.styleAttribute[i]); - } - } - if (object.styleMap) { - if (!Array.isArray(object.styleMap)) - throw TypeError(".keyhole.dbroot.DbRootProto.styleMap: array expected"); - message.styleMap = []; - for (var i = 0; i < object.styleMap.length; ++i) { - if (typeof object.styleMap[i] !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.styleMap: object expected"); - message.styleMap[i] = $types[7].fromObject(object.styleMap[i]); - } - } - if (object.endSnippet !== undefined && object.endSnippet !== null) { - if (typeof object.endSnippet !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.endSnippet: object expected"); - message.endSnippet = $types[8].fromObject(object.endSnippet); - } - if (object.translationEntry) { - if (!Array.isArray(object.translationEntry)) - throw TypeError(".keyhole.dbroot.DbRootProto.translationEntry: array expected"); - message.translationEntry = []; - for (var i = 0; i < object.translationEntry.length; ++i) { - if (typeof object.translationEntry[i] !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.translationEntry: object expected"); - message.translationEntry[i] = $types[9].fromObject(object.translationEntry[i]); - } + var message = new $root.keyhole.dbroot.SearchTabProto(); + if (object.isVisible !== undefined && object.isVisible !== null) + message.isVisible = Boolean(object.isVisible); + if (object.tabLabel !== undefined && object.tabLabel !== null) { + if (typeof object.tabLabel !== "object") + throw TypeError(".keyhole.dbroot.SearchTabProto.tabLabel: object expected"); + message.tabLabel = $types[1].fromObject(object.tabLabel); } - if (object.language !== undefined && object.language !== null) - message.language = String(object.language); - if (object.version !== undefined && object.version !== null) - message.version = object.version | 0; - if (object.dbrootReference) { - if (!Array.isArray(object.dbrootReference)) - throw TypeError(".keyhole.dbroot.DbRootProto.dbrootReference: array expected"); - message.dbrootReference = []; - for (var i = 0; i < object.dbrootReference.length; ++i) { - if (typeof object.dbrootReference[i] !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.dbrootReference: object expected"); - message.dbrootReference[i] = $types[12].fromObject(object.dbrootReference[i]); + if (object.baseUrl !== undefined && object.baseUrl !== null) + message.baseUrl = String(object.baseUrl); + if (object.viewportPrefix !== undefined && object.viewportPrefix !== null) + message.viewportPrefix = String(object.viewportPrefix); + if (object.inputBox) { + if (!Array.isArray(object.inputBox)) + throw TypeError(".keyhole.dbroot.SearchTabProto.inputBox: array expected"); + message.inputBox = []; + for (var i = 0; i < object.inputBox.length; ++i) { + if (typeof object.inputBox[i] !== "object") + throw TypeError(".keyhole.dbroot.SearchTabProto.inputBox: object expected"); + message.inputBox[i] = $types[4].fromObject(object.inputBox[i]); } } - if (object.databaseVersion !== undefined && object.databaseVersion !== null) { - if (typeof object.databaseVersion !== "object") - throw TypeError(".keyhole.dbroot.DbRootProto.databaseVersion: object expected"); - message.databaseVersion = $types[13].fromObject(object.databaseVersion); + if (object.requirement !== undefined && object.requirement !== null) { + if (typeof object.requirement !== "object") + throw TypeError(".keyhole.dbroot.SearchTabProto.requirement: object expected"); + message.requirement = $types[5].fromObject(object.requirement); } - if (object.refreshTimeout !== undefined && object.refreshTimeout !== null) - message.refreshTimeout = object.refreshTimeout | 0; return message; }; - DbRootProto.from = DbRootProto.fromObject; + SearchTabProto.from = SearchTabProto.fromObject; - DbRootProto.toObject = function toObject(message, options) { + SearchTabProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) { - object.providerInfo = []; - object.nestedFeature = []; - object.styleAttribute = []; - object.styleMap = []; - object.translationEntry = []; - object.dbrootReference = []; - } + if (options.arrays || options.defaults) + object.inputBox = []; if (options.defaults) { - object.databaseName = null; - object.imageryPresent = true; - object.protoImagery = false; - object.terrainPresent = false; - object.endSnippet = null; - object.language = "en"; - object.version = 5; - object.databaseVersion = null; - object.refreshTimeout = 0; - } - if (message.databaseName !== undefined && message.databaseName !== null && message.hasOwnProperty("databaseName")) - object.databaseName = $types[0].toObject(message.databaseName, options); - if (message.imageryPresent !== undefined && message.imageryPresent !== null && message.hasOwnProperty("imageryPresent")) - object.imageryPresent = message.imageryPresent; - if (message.protoImagery !== undefined && message.protoImagery !== null && message.hasOwnProperty("protoImagery")) - object.protoImagery = message.protoImagery; - if (message.terrainPresent !== undefined && message.terrainPresent !== null && message.hasOwnProperty("terrainPresent")) - object.terrainPresent = message.terrainPresent; - if (message.providerInfo !== undefined && message.providerInfo !== null && message.hasOwnProperty("providerInfo")) { - object.providerInfo = []; - for (var j = 0; j < message.providerInfo.length; ++j) - object.providerInfo[j] = $types[4].toObject(message.providerInfo[j], options); - } - if (message.nestedFeature !== undefined && message.nestedFeature !== null && message.hasOwnProperty("nestedFeature")) { - object.nestedFeature = []; - for (var j = 0; j < message.nestedFeature.length; ++j) - object.nestedFeature[j] = $types[5].toObject(message.nestedFeature[j], options); - } - if (message.styleAttribute !== undefined && message.styleAttribute !== null && message.hasOwnProperty("styleAttribute")) { - object.styleAttribute = []; - for (var j = 0; j < message.styleAttribute.length; ++j) - object.styleAttribute[j] = $types[6].toObject(message.styleAttribute[j], options); - } - if (message.styleMap !== undefined && message.styleMap !== null && message.hasOwnProperty("styleMap")) { - object.styleMap = []; - for (var j = 0; j < message.styleMap.length; ++j) - object.styleMap[j] = $types[7].toObject(message.styleMap[j], options); - } - if (message.endSnippet !== undefined && message.endSnippet !== null && message.hasOwnProperty("endSnippet")) - object.endSnippet = $types[8].toObject(message.endSnippet, options); - if (message.translationEntry !== undefined && message.translationEntry !== null && message.hasOwnProperty("translationEntry")) { - object.translationEntry = []; - for (var j = 0; j < message.translationEntry.length; ++j) - object.translationEntry[j] = $types[9].toObject(message.translationEntry[j], options); + object.isVisible = false; + object.tabLabel = null; + object.baseUrl = ""; + object.viewportPrefix = ""; + object.requirement = null; } - if (message.language !== undefined && message.language !== null && message.hasOwnProperty("language")) - object.language = message.language; - if (message.version !== undefined && message.version !== null && message.hasOwnProperty("version")) - object.version = message.version; - if (message.dbrootReference !== undefined && message.dbrootReference !== null && message.hasOwnProperty("dbrootReference")) { - object.dbrootReference = []; - for (var j = 0; j < message.dbrootReference.length; ++j) - object.dbrootReference[j] = $types[12].toObject(message.dbrootReference[j], options); + if (message.isVisible !== undefined && message.isVisible !== null && message.hasOwnProperty("isVisible")) + object.isVisible = message.isVisible; + if (message.tabLabel !== undefined && message.tabLabel !== null && message.hasOwnProperty("tabLabel")) + object.tabLabel = $types[1].toObject(message.tabLabel, options); + if (message.baseUrl !== undefined && message.baseUrl !== null && message.hasOwnProperty("baseUrl")) + object.baseUrl = message.baseUrl; + if (message.viewportPrefix !== undefined && message.viewportPrefix !== null && message.hasOwnProperty("viewportPrefix")) + object.viewportPrefix = message.viewportPrefix; + if (message.inputBox !== undefined && message.inputBox !== null && message.hasOwnProperty("inputBox")) { + object.inputBox = []; + for (var j = 0; j < message.inputBox.length; ++j) + object.inputBox[j] = $types[4].toObject(message.inputBox[j], options); } - if (message.databaseVersion !== undefined && message.databaseVersion !== null && message.hasOwnProperty("databaseVersion")) - object.databaseVersion = $types[13].toObject(message.databaseVersion, options); - if (message.refreshTimeout !== undefined && message.refreshTimeout !== null && message.hasOwnProperty("refreshTimeout")) - object.refreshTimeout = message.refreshTimeout; + if (message.requirement !== undefined && message.requirement !== null && message.hasOwnProperty("requirement")) + object.requirement = $types[5].toObject(message.requirement, options); return object; }; - DbRootProto.prototype.toObject = function toObject(options) { + SearchTabProto.prototype.toObject = function toObject(options) { return this.constructor.toObject(this, options); }; - DbRootProto.prototype.toJSON = function toJSON() { + SearchTabProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return DbRootProto; + SearchTabProto.InputBoxInfo = (function() { + + function InputBoxInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } + + InputBoxInfo.prototype.label = null; + InputBoxInfo.prototype.queryVerb = ""; + InputBoxInfo.prototype.queryPrepend = ""; + + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); + + InputBoxInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.SearchTabProto.InputBoxInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.label = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.queryVerb = reader.string(); + break; + case 3: + message.queryPrepend = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + InputBoxInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var error = $types[0].verify(message.label); + if (error) + return "label." + error; + if (!$util.isString(message.queryVerb)) + return "queryVerb: string expected"; + if (message.queryPrepend !== undefined) + if (!$util.isString(message.queryPrepend)) + return "queryPrepend: string expected"; + return null; + }; + + InputBoxInfo.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.SearchTabProto.InputBoxInfo) + return object; + var message = new $root.keyhole.dbroot.SearchTabProto.InputBoxInfo(); + if (object.label !== undefined && object.label !== null) { + if (typeof object.label !== "object") + throw TypeError(".keyhole.dbroot.SearchTabProto.InputBoxInfo.label: object expected"); + message.label = $types[0].fromObject(object.label); + } + if (object.queryVerb !== undefined && object.queryVerb !== null) + message.queryVerb = String(object.queryVerb); + if (object.queryPrepend !== undefined && object.queryPrepend !== null) + message.queryPrepend = String(object.queryPrepend); + return message; + }; + + InputBoxInfo.from = InputBoxInfo.fromObject; + + InputBoxInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.label = null; + object.queryVerb = ""; + object.queryPrepend = ""; + } + if (message.label !== undefined && message.label !== null && message.hasOwnProperty("label")) + object.label = $types[0].toObject(message.label, options); + if (message.queryVerb !== undefined && message.queryVerb !== null && message.hasOwnProperty("queryVerb")) + object.queryVerb = message.queryVerb; + if (message.queryPrepend !== undefined && message.queryPrepend !== null && message.hasOwnProperty("queryPrepend")) + object.queryPrepend = message.queryPrepend; + return object; + }; + + InputBoxInfo.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; + + InputBoxInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return InputBoxInfo; + })(); + + return SearchTabProto; })(); - dbroot.EncryptedDbRootProto = (function() { + dbroot.CobrandProto = (function() { - function EncryptedDbRootProto(properties) { + function CobrandProto(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) this[keys[i]] = properties[keys[i]]; } - EncryptedDbRootProto.prototype.encryptionType = 0; - EncryptedDbRootProto.prototype.encryptionData = $util.newBuffer([]); - EncryptedDbRootProto.prototype.dbrootData = $util.newBuffer([]); + CobrandProto.prototype.logoUrl = ""; + CobrandProto.prototype.xCoord = null; + CobrandProto.prototype.yCoord = null; + CobrandProto.prototype.tiePoint = 6; + CobrandProto.prototype.screenSize = 0; var $types = { - 0 : "keyhole.dbroot.EncryptedDbRootProto.EncryptionType" + 1 : "keyhole.dbroot.CobrandProto.Coord", + 2 : "keyhole.dbroot.CobrandProto.Coord", + 3 : "keyhole.dbroot.CobrandProto.TiePoint" }; $lazyTypes.push($types); - EncryptedDbRootProto.decode = function decode(reader, length) { + CobrandProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === undefined ? reader.len : reader.pos + length, - message = new $root.keyhole.dbroot.EncryptedDbRootProto(); + message = new $root.keyhole.dbroot.CobrandProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.encryptionType = reader.uint32(); + message.logoUrl = reader.string(); break; case 2: - message.encryptionData = reader.bytes(); + message.xCoord = $types[1].decode(reader, reader.uint32()); break; case 3: - message.dbrootData = reader.bytes(); + message.yCoord = $types[2].decode(reader, reader.uint32()); + break; + case 4: + message.tiePoint = reader.uint32(); + break; + case 5: + message.screenSize = reader.double(); break; default: reader.skipType(tag & 7); @@ -63253,9711 +60250,10289 @@ define('ThirdParty/google-earth-dbroot-parser',[ return message; }; - EncryptedDbRootProto.verify = function verify(message) { + CobrandProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.encryptionType !== undefined) - switch (message.encryptionType) { + if (!$util.isString(message.logoUrl)) + return "logoUrl: string expected"; + if (message.xCoord !== undefined && message.xCoord !== null) { + var error = $types[1].verify(message.xCoord); + if (error) + return "xCoord." + error; + } + if (message.yCoord !== undefined && message.yCoord !== null) { + var error = $types[2].verify(message.yCoord); + if (error) + return "yCoord." + error; + } + if (message.tiePoint !== undefined) + switch (message.tiePoint) { default: - return "encryptionType: enum value expected"; + return "tiePoint: enum value expected"; case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: break; } - if (message.encryptionData !== undefined) - if (!(message.encryptionData && typeof message.encryptionData.length === "number" || $util.isString(message.encryptionData))) - return "encryptionData: buffer expected"; - if (message.dbrootData !== undefined) - if (!(message.dbrootData && typeof message.dbrootData.length === "number" || $util.isString(message.dbrootData))) - return "dbrootData: buffer expected"; + if (message.screenSize !== undefined) + if (typeof message.screenSize !== "number") + return "screenSize: number expected"; return null; }; - EncryptedDbRootProto.fromObject = function fromObject(object) { - if (object instanceof $root.keyhole.dbroot.EncryptedDbRootProto) + CobrandProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.CobrandProto) return object; - var message = new $root.keyhole.dbroot.EncryptedDbRootProto(); - switch (object.encryptionType) { - case "ENCRYPTION_XOR": + var message = new $root.keyhole.dbroot.CobrandProto(); + if (object.logoUrl !== undefined && object.logoUrl !== null) + message.logoUrl = String(object.logoUrl); + if (object.xCoord !== undefined && object.xCoord !== null) { + if (typeof object.xCoord !== "object") + throw TypeError(".keyhole.dbroot.CobrandProto.xCoord: object expected"); + message.xCoord = $types[1].fromObject(object.xCoord); + } + if (object.yCoord !== undefined && object.yCoord !== null) { + if (typeof object.yCoord !== "object") + throw TypeError(".keyhole.dbroot.CobrandProto.yCoord: object expected"); + message.yCoord = $types[2].fromObject(object.yCoord); + } + switch (object.tiePoint) { + case "TOP_LEFT": case 0: - message.encryptionType = 0; + message.tiePoint = 0; + break; + case "TOP_CENTER": + case 1: + message.tiePoint = 1; + break; + case "TOP_RIGHT": + case 2: + message.tiePoint = 2; + break; + case "MID_LEFT": + case 3: + message.tiePoint = 3; + break; + case "MID_CENTER": + case 4: + message.tiePoint = 4; + break; + case "MID_RIGHT": + case 5: + message.tiePoint = 5; + break; + case "BOTTOM_LEFT": + case 6: + message.tiePoint = 6; + break; + case "BOTTOM_CENTER": + case 7: + message.tiePoint = 7; + break; + case "BOTTOM_RIGHT": + case 8: + message.tiePoint = 8; break; } - if (object.encryptionData !== undefined && object.encryptionData !== null) - if (typeof object.encryptionData === "string") - $util.base64.decode(object.encryptionData, message.encryptionData = $util.newBuffer($util.base64.length(object.encryptionData)), 0); - else if (object.encryptionData.length) - message.encryptionData = object.encryptionData; - if (object.dbrootData !== undefined && object.dbrootData !== null) - if (typeof object.dbrootData === "string") - $util.base64.decode(object.dbrootData, message.dbrootData = $util.newBuffer($util.base64.length(object.dbrootData)), 0); - else if (object.dbrootData.length) - message.dbrootData = object.dbrootData; + if (object.screenSize !== undefined && object.screenSize !== null) + message.screenSize = Number(object.screenSize); return message; }; - EncryptedDbRootProto.from = EncryptedDbRootProto.fromObject; + CobrandProto.from = CobrandProto.fromObject; - EncryptedDbRootProto.toObject = function toObject(message, options) { + CobrandProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.encryptionType = options.enums === String ? "ENCRYPTION_XOR" : 0; - object.encryptionData = options.bytes === String ? "" : []; - object.dbrootData = options.bytes === String ? "" : []; + object.logoUrl = ""; + object.xCoord = null; + object.yCoord = null; + object.tiePoint = options.enums === String ? "BOTTOM_LEFT" : 6; + object.screenSize = 0; } - if (message.encryptionType !== undefined && message.encryptionType !== null && message.hasOwnProperty("encryptionType")) - object.encryptionType = options.enums === String ? $types[0][message.encryptionType] : message.encryptionType; - if (message.encryptionData !== undefined && message.encryptionData !== null && message.hasOwnProperty("encryptionData")) - object.encryptionData = options.bytes === String ? $util.base64.encode(message.encryptionData, 0, message.encryptionData.length) : options.bytes === Array ? Array.prototype.slice.call(message.encryptionData) : message.encryptionData; - if (message.dbrootData !== undefined && message.dbrootData !== null && message.hasOwnProperty("dbrootData")) - object.dbrootData = options.bytes === String ? $util.base64.encode(message.dbrootData, 0, message.dbrootData.length) : options.bytes === Array ? Array.prototype.slice.call(message.dbrootData) : message.dbrootData; + if (message.logoUrl !== undefined && message.logoUrl !== null && message.hasOwnProperty("logoUrl")) + object.logoUrl = message.logoUrl; + if (message.xCoord !== undefined && message.xCoord !== null && message.hasOwnProperty("xCoord")) + object.xCoord = $types[1].toObject(message.xCoord, options); + if (message.yCoord !== undefined && message.yCoord !== null && message.hasOwnProperty("yCoord")) + object.yCoord = $types[2].toObject(message.yCoord, options); + if (message.tiePoint !== undefined && message.tiePoint !== null && message.hasOwnProperty("tiePoint")) + object.tiePoint = options.enums === String ? $types[3][message.tiePoint] : message.tiePoint; + if (message.screenSize !== undefined && message.screenSize !== null && message.hasOwnProperty("screenSize")) + object.screenSize = message.screenSize; return object; }; - EncryptedDbRootProto.prototype.toObject = function toObject(options) { + CobrandProto.prototype.toObject = function toObject(options) { return this.constructor.toObject(this, options); }; - EncryptedDbRootProto.prototype.toJSON = function toJSON() { + CobrandProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - EncryptedDbRootProto.EncryptionType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values["ENCRYPTION_XOR"] = 0; - return values; - })(); - - return EncryptedDbRootProto; - })(); - - return dbroot; - })(); + CobrandProto.Coord = (function() { - return keyhole; - })(); + function Coord(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - $util.lazyResolve($root, $lazyTypes); + Coord.prototype.value = 0; + Coord.prototype.isRelative = false; - // End generated code - - return $root.keyhole.dbroot; -}); - -define('Core/isBitSet',[], function() { - 'use strict'; - - /** - * @private - */ - function isBitSet(bits, mask) { - return ((bits & mask) !== 0); - } - - return isBitSet; -}); + Coord.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.CobrandProto.Coord(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.value = reader.double(); + break; + case 2: + message.isRelative = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; -define('Core/GoogleEarthEnterpriseTileInformation',[ - './defined', - './isBitSet' - ], function( - defined, - isBitSet) { - 'use strict'; + Coord.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (typeof message.value !== "number") + return "value: number expected"; + if (message.isRelative !== undefined) + if (typeof message.isRelative !== "boolean") + return "isRelative: boolean expected"; + return null; + }; - // Bitmask for checking tile properties - var childrenBitmasks = [0x01, 0x02, 0x04, 0x08]; - var anyChildBitmask = 0x0F; - var cacheFlagBitmask = 0x10; // True if there is a child subtree - var imageBitmask = 0x40; - var terrainBitmask = 0x80; + Coord.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.CobrandProto.Coord) + return object; + var message = new $root.keyhole.dbroot.CobrandProto.Coord(); + if (object.value !== undefined && object.value !== null) + message.value = Number(object.value); + if (object.isRelative !== undefined && object.isRelative !== null) + message.isRelative = Boolean(object.isRelative); + return message; + }; - /** - * Contains information about each tile from a Google Earth Enterprise server - * - * @param {Number} bits Bitmask that contains the type of data and available children for each tile. - * @param {Number} cnodeVersion Version of the request for subtree metadata. - * @param {Number} imageryVersion Version of the request for imagery tile. - * @param {Number} terrainVersion Version of the request for terrain tile. - * @param {Number} imageryProvider Id of imagery provider. - * @param {Number} terrainProvider Id of terrain provider. - * - * @private - */ - function GoogleEarthEnterpriseTileInformation(bits, cnodeVersion, imageryVersion, terrainVersion, imageryProvider, terrainProvider) { - this._bits = bits; - this.cnodeVersion = cnodeVersion; - this.imageryVersion = imageryVersion; - this.terrainVersion = terrainVersion; - this.imageryProvider = imageryProvider; - this.terrainProvider = terrainProvider; - this.ancestorHasTerrain = false; // Set it later once we find its parent - this.terrainState = undefined; - } + Coord.from = Coord.fromObject; - /** - * Creates GoogleEarthEnterpriseTileInformation from an object - * - * @param {Object} info Object to be cloned - * @param {GoogleEarthEnterpriseTileInformation} [result] The object onto which to store the result. - * @returns {GoogleEarthEnterpriseTileInformation} The modified result parameter or a new GoogleEarthEnterpriseTileInformation instance if none was provided. - */ - GoogleEarthEnterpriseTileInformation.clone = function(info, result) { - if (!defined(result)) { - result = new GoogleEarthEnterpriseTileInformation(info._bits, info.cnodeVersion, info.imageryVersion, info.terrainVersion, - info.imageryProvider, info.terrainProvider); - } else { - result._bits = info._bits; - result.cnodeVersion = info.cnodeVersion; - result.imageryVersion = info.imageryVersion; - result.terrainVersion = info.terrainVersion; - result.imageryProvider = info.imageryProvider; - result.terrainProvider = info.terrainProvider; - } - result.ancestorHasTerrain = info.ancestorHasTerrain; - result.terrainState = info.terrainState; + Coord.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.value = 0; + object.isRelative = false; + } + if (message.value !== undefined && message.value !== null && message.hasOwnProperty("value")) + object.value = message.value; + if (message.isRelative !== undefined && message.isRelative !== null && message.hasOwnProperty("isRelative")) + object.isRelative = message.isRelative; + return object; + }; - return result; - }; + Coord.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - /** - * Sets the parent for the tile - * - * @param {GoogleEarthEnterpriseTileInformation} parent Parent tile - */ - GoogleEarthEnterpriseTileInformation.prototype.setParent = function(parent) { - this.ancestorHasTerrain = parent.ancestorHasTerrain || this.hasTerrain(); - }; + Coord.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * Gets whether a subtree is available - * - * @returns {Boolean} true if subtree is available, false otherwise. - */ - GoogleEarthEnterpriseTileInformation.prototype.hasSubtree = function() { - return isBitSet(this._bits, cacheFlagBitmask); - }; + return Coord; + })(); - /** - * Gets whether imagery is available - * - * @returns {Boolean} true if imagery is available, false otherwise. - */ - GoogleEarthEnterpriseTileInformation.prototype.hasImagery = function() { - return isBitSet(this._bits, imageBitmask); - }; + CobrandProto.TiePoint = (function() { + var valuesById = {}, values = Object.create(valuesById); + values["TOP_LEFT"] = 0; + values["TOP_CENTER"] = 1; + values["TOP_RIGHT"] = 2; + values["MID_LEFT"] = 3; + values["MID_CENTER"] = 4; + values["MID_RIGHT"] = 5; + values["BOTTOM_LEFT"] = 6; + values["BOTTOM_CENTER"] = 7; + values["BOTTOM_RIGHT"] = 8; + return values; + })(); - /** - * Gets whether terrain is available - * - * @returns {Boolean} true if terrain is available, false otherwise. - */ - GoogleEarthEnterpriseTileInformation.prototype.hasTerrain = function() { - return isBitSet(this._bits, terrainBitmask); - }; + return CobrandProto; + })(); - /** - * Gets whether any children are present - * - * @returns {Boolean} true if any children are available, false otherwise. - */ - GoogleEarthEnterpriseTileInformation.prototype.hasChildren = function() { - return isBitSet(this._bits, anyChildBitmask); - }; + dbroot.DatabaseDescriptionProto = (function() { - /** - * Gets whether a specified child is available - * - * @param {Number} index Index of child tile - * - * @returns {Boolean} true if child is available, false otherwise - */ - GoogleEarthEnterpriseTileInformation.prototype.hasChild = function(index) { - return isBitSet(this._bits, childrenBitmasks[index]); - }; + function DatabaseDescriptionProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * Gets bitmask containing children - * - * @returns {Number} Children bitmask - */ - GoogleEarthEnterpriseTileInformation.prototype.getChildBitmask = function() { - return this._bits & anyChildBitmask; - }; + DatabaseDescriptionProto.prototype.databaseName = null; + DatabaseDescriptionProto.prototype.databaseUrl = ""; - return GoogleEarthEnterpriseTileInformation; -}); + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); -define('Core/GoogleEarthEnterpriseMetadata',[ - '../ThirdParty/google-earth-dbroot-parser', - '../ThirdParty/when', - './appendForwardSlash', - './Check', - './Credit', - './defaultValue', - './defined', - './defineProperties', - './GoogleEarthEnterpriseTileInformation', - './isBitSet', - './joinUrls', - './loadArrayBuffer', - './Math', - './Request', - './RuntimeError', - './TaskProcessor' - ], function( - dbrootParser, - when, - appendForwardSlash, - Check, - Credit, - defaultValue, - defined, - defineProperties, - GoogleEarthEnterpriseTileInformation, - isBitSet, - joinUrls, - loadArrayBuffer, - CesiumMath, - Request, - RuntimeError, - TaskProcessor) { - 'use strict'; + DatabaseDescriptionProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.DatabaseDescriptionProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.databaseName = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.databaseUrl = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - function stringToBuffer(str) { - var len = str.length; - var buffer = new ArrayBuffer(len); - var ui8 = new Uint8Array(buffer); - for (var i = 0; i < len; ++i) { - ui8[i] = str.charCodeAt(i); - } + DatabaseDescriptionProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.databaseName !== undefined && message.databaseName !== null) { + var error = $types[0].verify(message.databaseName); + if (error) + return "databaseName." + error; + } + if (!$util.isString(message.databaseUrl)) + return "databaseUrl: string expected"; + return null; + }; - return buffer; - } + DatabaseDescriptionProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.DatabaseDescriptionProto) + return object; + var message = new $root.keyhole.dbroot.DatabaseDescriptionProto(); + if (object.databaseName !== undefined && object.databaseName !== null) { + if (typeof object.databaseName !== "object") + throw TypeError(".keyhole.dbroot.DatabaseDescriptionProto.databaseName: object expected"); + message.databaseName = $types[0].fromObject(object.databaseName); + } + if (object.databaseUrl !== undefined && object.databaseUrl !== null) + message.databaseUrl = String(object.databaseUrl); + return message; + }; - // Decodes packet with a key that has been around since the beginning of Google Earth Enterprise - var defaultKey = stringToBuffer('\x45\xf4\xbd\x0b\x79\xe2\x6a\x45\x22\x05\x92\x2c\x17\xcd\x06\x71\xf8\x49\x10\x46\x67\x51\x00\x42\x25\xc6\xe8\x61\x2c\x66\x29\x08\xc6\x34\xdc\x6a\x62\x25\x79\x0a\x77\x1d\x6d\x69\xd6\xf0\x9c\x6b\x93\xa1\xbd\x4e\x75\xe0\x41\x04\x5b\xdf\x40\x56\x0c\xd9\xbb\x72\x9b\x81\x7c\x10\x33\x53\xee\x4f\x6c\xd4\x71\x05\xb0\x7b\xc0\x7f\x45\x03\x56\x5a\xad\x77\x55\x65\x0b\x33\x92\x2a\xac\x19\x6c\x35\x14\xc5\x1d\x30\x73\xf8\x33\x3e\x6d\x46\x38\x4a\xb4\xdd\xf0\x2e\xdd\x17\x75\x16\xda\x8c\x44\x74\x22\x06\xfa\x61\x22\x0c\x33\x22\x53\x6f\xaf\x39\x44\x0b\x8c\x0e\x39\xd9\x39\x13\x4c\xb9\xbf\x7f\xab\x5c\x8c\x50\x5f\x9f\x22\x75\x78\x1f\xe9\x07\x71\x91\x68\x3b\xc1\xc4\x9b\x7f\xf0\x3c\x56\x71\x48\x82\x05\x27\x55\x66\x59\x4e\x65\x1d\x98\x75\xa3\x61\x46\x7d\x61\x3f\x15\x41\x00\x9f\x14\x06\xd7\xb4\x34\x4d\xce\x13\x87\x46\xb0\x1a\xd5\x05\x1c\xb8\x8a\x27\x7b\x8b\xdc\x2b\xbb\x4d\x67\x30\xc8\xd1\xf6\x5c\x8f\x50\xfa\x5b\x2f\x46\x9b\x6e\x35\x18\x2f\x27\x43\x2e\xeb\x0a\x0c\x5e\x10\x05\x10\xa5\x73\x1b\x65\x34\xe5\x6c\x2e\x6a\x43\x27\x63\x14\x23\x55\xa9\x3f\x71\x7b\x67\x43\x7d\x3a\xaf\xcd\xe2\x54\x55\x9c\xfd\x4b\xc6\xe2\x9f\x2f\x28\xed\xcb\x5c\xc6\x2d\x66\x07\x88\xa7\x3b\x2f\x18\x2a\x22\x4e\x0e\xb0\x6b\x2e\xdd\x0d\x95\x7d\x7d\x47\xba\x43\xb2\x11\xb2\x2b\x3e\x4d\xaa\x3e\x7d\xe6\xce\x49\x89\xc6\xe6\x78\x0c\x61\x31\x05\x2d\x01\xa4\x4f\xa5\x7e\x71\x20\x88\xec\x0d\x31\xe8\x4e\x0b\x00\x6e\x50\x68\x7d\x17\x3d\x08\x0d\x17\x95\xa6\x6e\xa3\x68\x97\x24\x5b\x6b\xf3\x17\x23\xf3\xb6\x73\xb3\x0d\x0b\x40\xc0\x9f\xd8\x04\x51\x5d\xfa\x1a\x17\x22\x2e\x15\x6a\xdf\x49\x00\xb9\xa0\x77\x55\xc6\xef\x10\x6a\xbf\x7b\x47\x4c\x7f\x83\x17\x05\xee\xdc\xdc\x46\x85\xa9\xad\x53\x07\x2b\x53\x34\x06\x07\xff\x14\x94\x59\x19\x02\xe4\x38\xe8\x31\x83\x4e\xb9\x58\x46\x6b\xcb\x2d\x23\x86\x92\x70\x00\x35\x88\x22\xcf\x31\xb2\x26\x2f\xe7\xc3\x75\x2d\x36\x2c\x72\x74\xb0\x23\x47\xb7\xd3\xd1\x26\x16\x85\x37\x72\xe2\x00\x8c\x44\xcf\x10\xda\x33\x2d\x1a\xde\x60\x86\x69\x23\x69\x2a\x7c\xcd\x4b\x51\x0d\x95\x54\x39\x77\x2e\x29\xea\x1b\xa6\x50\xa2\x6a\x8f\x6f\x50\x99\x5c\x3e\x54\xfb\xef\x50\x5b\x0b\x07\x45\x17\x89\x6d\x28\x13\x77\x37\x1d\xdb\x8e\x1e\x4a\x05\x66\x4a\x6f\x99\x20\xe5\x70\xe2\xb9\x71\x7e\x0c\x6d\x49\x04\x2d\x7a\xfe\x72\xc7\xf2\x59\x30\x8f\xbb\x02\x5d\x73\xe5\xc9\x20\xea\x78\xec\x20\x90\xf0\x8a\x7f\x42\x17\x7c\x47\x19\x60\xb0\x16\xbd\x26\xb7\x71\xb6\xc7\x9f\x0e\xd1\x33\x82\x3d\xd3\xab\xee\x63\x99\xc8\x2b\x53\xa0\x44\x5c\x71\x01\xc6\xcc\x44\x1f\x32\x4f\x3c\xca\xc0\x29\x3d\x52\xd3\x61\x19\x58\xa9\x7d\x65\xb4\xdc\xcf\x0d\xf4\x3d\xf1\x08\xa9\x42\xda\x23\x09\xd8\xbf\x5e\x50\x49\xf8\x4d\xc0\xcb\x47\x4c\x1c\x4f\xf7\x7b\x2b\xd8\x16\x18\xc5\x31\x92\x3b\xb5\x6f\xdc\x6c\x0d\x92\x88\x16\xd1\x9e\xdb\x3f\xe2\xe9\xda\x5f\xd4\x84\xe2\x46\x61\x5a\xde\x1c\x55\xcf\xa4\x00\xbe\xfd\xce\x67\xf1\x4a\x69\x1c\x97\xe6\x20\x48\xd8\x5d\x7f\x7e\xae\x71\x20\x0e\x4e\xae\xc0\x56\xa9\x91\x01\x3c\x82\x1d\x0f\x72\xe7\x76\xec\x29\x49\xd6\x5d\x2d\x83\xe3\xdb\x36\x06\xa9\x3b\x66\x13\x97\x87\x6a\xd5\xb6\x3d\x50\x5e\x52\xb9\x4b\xc7\x73\x57\x78\xc9\xf4\x2e\x59\x07\x95\x93\x6f\xd0\x4b\x17\x57\x19\x3e\x27\x27\xc7\x60\xdb\x3b\xed\x9a\x0e\x53\x44\x16\x3e\x3f\x8d\x92\x6d\x77\xa2\x0a\xeb\x3f\x52\xa8\xc6\x55\x5e\x31\x49\x37\x85\xf4\xc5\x1f\x26\x2d\xa9\x1c\xbf\x8b\x27\x54\xda\xc3\x6a\x20\xe5\x2a\x78\x04\xb0\xd6\x90\x70\x72\xaa\x8b\x68\xbd\x88\xf7\x02\x5f\x48\xb1\x7e\xc0\x58\x4c\x3f\x66\x1a\xf9\x3e\xe1\x65\xc0\x70\xa7\xcf\x38\x69\xaf\xf0\x56\x6c\x64\x49\x9c\x27\xad\x78\x74\x4f\xc2\x87\xde\x56\x39\x00\xda\x77\x0b\xcb\x2d\x1b\x89\xfb\x35\x4f\x02\xf5\x08\x51\x13\x60\xc1\x0a\x5a\x47\x4d\x26\x1c\x33\x30\x78\xda\xc0\x9c\x46\x47\xe2\x5b\x79\x60\x49\x6e\x37\x67\x53\x0a\x3e\xe9\xec\x46\x39\xb2\xf1\x34\x0d\xc6\x84\x53\x75\x6e\xe1\x0c\x59\xd9\x1e\xde\x29\x85\x10\x7b\x49\x49\xa5\x77\x79\xbe\x49\x56\x2e\x36\xe7\x0b\x3a\xbb\x4f\x03\x62\x7b\xd2\x4d\x31\x95\x2f\xbd\x38\x7b\xa8\x4f\x21\xe1\xec\x46\x70\x76\x95\x7d\x29\x22\x78\x88\x0a\x90\xdd\x9d\x5c\xda\xde\x19\x51\xcf\xf0\xfc\x59\x52\x65\x7c\x33\x13\xdf\xf3\x48\xda\xbb\x2a\x75\xdb\x60\xb2\x02\x15\xd4\xfc\x19\xed\x1b\xec\x7f\x35\xa8\xff\x28\x31\x07\x2d\x12\xc8\xdc\x88\x46\x7c\x8a\x5b\x22'); + DatabaseDescriptionProto.from = DatabaseDescriptionProto.fromObject; - /** - * Provides metadata using the Google Earth Enterprise REST API. This is used by the GoogleEarthEnterpriseImageryProvider - * and GoogleEarthEnterpriseTerrainProvider to share metadata requests. - * - * @alias GoogleEarthEnterpriseMetadata - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url of the Google Earth Enterprise server hosting the imagery. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * - * @see GoogleEarthEnterpriseImageryProvider - * @see GoogleEarthEnterpriseTerrainProvider - * - */ - function GoogleEarthEnterpriseMetadata(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - Check.typeOf.string('options.url', options.url); - - /** - * True if imagery is available. - * @type {Boolean} - * @default true - */ - this.imageryPresent = true; + DatabaseDescriptionProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.databaseName = null; + object.databaseUrl = ""; + } + if (message.databaseName !== undefined && message.databaseName !== null && message.hasOwnProperty("databaseName")) + object.databaseName = $types[0].toObject(message.databaseName, options); + if (message.databaseUrl !== undefined && message.databaseUrl !== null && message.hasOwnProperty("databaseUrl")) + object.databaseUrl = message.databaseUrl; + return object; + }; - /** - * True if imagery is sent as a protocol buffer, false if sent as plain images. If undefined we will try both. - * @type {Boolean} - * @default undefined - */ - this.protoImagery = undefined; + DatabaseDescriptionProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - /** - * True if terrain is available. - * @type {Boolean} - * @default true - */ - this.terrainPresent = true; + DatabaseDescriptionProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * Exponent used to compute constant to calculate negative height values. - * @type {Number} - * @default 32 - */ - this.negativeAltitudeExponentBias = 32; + return DatabaseDescriptionProto; + })(); - /** - * Threshold where any numbers smaller are actually negative values. They are multiplied by -2^negativeAltitudeExponentBias. - * @type {Number} - * @default EPSILON12 - */ - this.negativeAltitudeThreshold = CesiumMath.EPSILON12; + dbroot.ConfigScriptProto = (function() { - /** - * Dictionary of provider id to copyright strings. - * @type {Object} - * @default {} - */ - this.providers = {}; + function ConfigScriptProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * Key used to decode packets - * @type {ArrayBuffer} - */ - this.key = undefined; + ConfigScriptProto.prototype.scriptName = ""; + ConfigScriptProto.prototype.scriptData = ""; - this._quadPacketVersion = 1; + ConfigScriptProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.ConfigScriptProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.scriptName = reader.string(); + break; + case 2: + message.scriptData = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - this._url = appendForwardSlash(options.url); - this._proxy = options.proxy; + ConfigScriptProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.scriptName)) + return "scriptName: string expected"; + if (!$util.isString(message.scriptData)) + return "scriptData: string expected"; + return null; + }; - this._tileInfo = {}; - this._subtreePromises = {}; + ConfigScriptProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.ConfigScriptProto) + return object; + var message = new $root.keyhole.dbroot.ConfigScriptProto(); + if (object.scriptName !== undefined && object.scriptName !== null) + message.scriptName = String(object.scriptName); + if (object.scriptData !== undefined && object.scriptData !== null) + message.scriptData = String(object.scriptData); + return message; + }; - var that = this; - this._readyPromise = requestDbRoot(this) - .then(function() { - return that.getQuadTreePacket('', that._quadPacketVersion); - }) - .then(function() { - return true; - }) - .otherwise(function(e) { - var message = 'An error occurred while accessing ' + getMetadataUrl(that, '', 1) + '.'; - return when.reject(new RuntimeError(message)); - }); - } + ConfigScriptProto.from = ConfigScriptProto.fromObject; - defineProperties(GoogleEarthEnterpriseMetadata.prototype, { - /** - * Gets the name of the Google Earth Enterprise server. - * @memberof GoogleEarthEnterpriseMetadata.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; - } - }, + ConfigScriptProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.scriptName = ""; + object.scriptData = ""; + } + if (message.scriptName !== undefined && message.scriptName !== null && message.hasOwnProperty("scriptName")) + object.scriptName = message.scriptName; + if (message.scriptData !== undefined && message.scriptData !== null && message.hasOwnProperty("scriptData")) + object.scriptData = message.scriptData; + return object; + }; - /** - * Gets the proxy used for metadata requests. - * @memberof GoogleEarthEnterpriseMetadata.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._proxy; - } - }, + ConfigScriptProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - /** - * Gets a promise that resolves to true when the metadata is ready for use. - * @memberof GoogleEarthEnterpriseMetadata.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise; - } - } - }); + ConfigScriptProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * Converts a tiles (x, y, level) position into a quadkey used to request an image - * from a Google Earth Enterprise server. - * - * @param {Number} x The tile's x coordinate. - * @param {Number} y The tile's y coordinate. - * @param {Number} level The tile's zoom level. - * - * @see GoogleEarthEnterpriseMetadata#quadKeyToTileXY - */ - GoogleEarthEnterpriseMetadata.tileXYToQuadKey = function(x, y, level) { - var quadkey = ''; - for (var i = level; i >= 0; --i) { - var bitmask = 1 << i; - var digit = 0; + return ConfigScriptProto; + })(); - // Tile Layout - // ___ ___ - //| | | - //| 3 | 2 | - //|-------| - //| 0 | 1 | - //|___|___| - // + dbroot.SwoopParamsProto = (function() { - if (!isBitSet(y, bitmask)) { // Top Row - digit |= 2; - if (!isBitSet(x, bitmask)) { // Right to left - digit |= 1; + function SwoopParamsProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; } - } else if (isBitSet(x, bitmask)) { // Left to right - digit |= 1; - } - quadkey += digit; - } - return quadkey; - }; + SwoopParamsProto.prototype.startDistInMeters = 0; - /** - * Converts a tile's quadkey used to request an image from a Google Earth Enterprise server into the - * (x, y, level) position. - * - * @param {String} quadkey The tile's quad key - * - * @see GoogleEarthEnterpriseMetadata#tileXYToQuadKey - */ - GoogleEarthEnterpriseMetadata.quadKeyToTileXY = function(quadkey) { - var x = 0; - var y = 0; - var level = quadkey.length - 1; - for (var i = level; i >= 0; --i) { - var bitmask = 1 << i; - var digit = +quadkey[level - i]; + SwoopParamsProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.SwoopParamsProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.startDistInMeters = reader.double(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - if (isBitSet(digit, 2)) { // Top Row - if (!isBitSet(digit, 1)) { // // Right to left - x |= bitmask; - } - } else { - y |= bitmask; - if (isBitSet(digit, 1)) { // Left to right - x |= bitmask; - } - } - } - return { - x : x, - y : y, - level : level - }; - }; + SwoopParamsProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.startDistInMeters !== undefined) + if (typeof message.startDistInMeters !== "number") + return "startDistInMeters: number expected"; + return null; + }; - GoogleEarthEnterpriseMetadata.prototype.isValid = function(quadKey) { - var info = this.getTileInformationFromQuadKey(quadKey); - if (defined(info)) { - return info !== null; - } + SwoopParamsProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.SwoopParamsProto) + return object; + var message = new $root.keyhole.dbroot.SwoopParamsProto(); + if (object.startDistInMeters !== undefined && object.startDistInMeters !== null) + message.startDistInMeters = Number(object.startDistInMeters); + return message; + }; - var valid = true; - var q = quadKey; - var last; - while (q.length > 1) { - last = q.substring(q.length - 1); - q = q.substring(0, q.length - 1); - info = this.getTileInformationFromQuadKey(q); - if (defined(info)) { - if (!info.hasSubtree() && - !info.hasChild(parseInt(last))) { - // We have no subtree or child available at some point in this node's ancestry - valid = false; - } + SwoopParamsProto.from = SwoopParamsProto.fromObject; - break; - } else if (info === null) { - // Some node in the ancestry was loaded and said there wasn't a subtree - valid = false; - break; - } - } + SwoopParamsProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.startDistInMeters = 0; + if (message.startDistInMeters !== undefined && message.startDistInMeters !== null && message.hasOwnProperty("startDistInMeters")) + object.startDistInMeters = message.startDistInMeters; + return object; + }; - return valid; - }; + SwoopParamsProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - var taskProcessor = new TaskProcessor('decodeGoogleEarthEnterprisePacket', Number.POSITIVE_INFINITY); + SwoopParamsProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * Retrieves a Google Earth Enterprise quadtree packet. - * - * @param {String} [quadKey=''] The quadkey to retrieve the packet for. - * @param {Number} [version=1] The cnode version to be used in the request. - * @param {Request} [request] The request object. Intended for internal use only. - * - * @private - */ - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket = function(quadKey, version, request) { - version = defaultValue(version, 1); - quadKey = defaultValue(quadKey, ''); - var url = getMetadataUrl(this, quadKey, version); - var proxy = this._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } + return SwoopParamsProto; + })(); - var promise = loadArrayBuffer(url, undefined, request); + dbroot.PostingServerProto = (function() { - if (!defined(promise)) { - return undefined; // Throttled - } + function PostingServerProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - var tileInfo = this._tileInfo; - var key = this.key; - return promise - .then(function(metadata) { - var decodePromise = taskProcessor.scheduleTask({ - buffer : metadata, - quadKey : quadKey, - type : 'Metadata', - key: key - }, [metadata]); + PostingServerProto.prototype.name = null; + PostingServerProto.prototype.baseUrl = null; + PostingServerProto.prototype.postWizardPath = null; + PostingServerProto.prototype.fileSubmitPath = null; - return decodePromise - .then(function(result) { - var root; - var topLevelKeyLength = -1; - if (quadKey !== '') { - // Root tile has no data except children bits, so put them into the tile info - topLevelKeyLength = quadKey.length + 1; - var top = result[quadKey]; - root = tileInfo[quadKey]; - root._bits |= top._bits; + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 1 : "keyhole.dbroot.StringIdOrValueProto", + 2 : "keyhole.dbroot.StringIdOrValueProto", + 3 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - delete result[quadKey]; + PostingServerProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.PostingServerProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.baseUrl = $types[1].decode(reader, reader.uint32()); + break; + case 3: + message.postWizardPath = $types[2].decode(reader, reader.uint32()); + break; + case 4: + message.fileSubmitPath = $types[3].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; } + } + return message; + }; - // Copy the resulting objects into tileInfo - // Make sure we start with shorter quadkeys first, so we know the parents have - // already been processed. Otherwise we can lose ancestorHasTerrain along the way. - var keys = Object.keys(result); - keys.sort(function(a, b) { - return a.length - b.length; - }); - var keysLength = keys.length; - for (var i = 0; i < keysLength; ++i) { - var key = keys[i]; - var r = result[key]; - if (r !== null) { - var info = GoogleEarthEnterpriseTileInformation.clone(result[key]); - var keyLength = key.length; - if (keyLength === topLevelKeyLength) { - info.setParent(root); - } else if(keyLength > 1){ - var parent = tileInfo[key.substring(0, key.length - 1)]; - info.setParent(parent); - } - tileInfo[key] = info; - } else { - tileInfo[key] = null; - } - } - }); - }); - }; + PostingServerProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name !== undefined && message.name !== null) { + var error = $types[0].verify(message.name); + if (error) + return "name." + error; + } + if (message.baseUrl !== undefined && message.baseUrl !== null) { + var error = $types[1].verify(message.baseUrl); + if (error) + return "baseUrl." + error; + } + if (message.postWizardPath !== undefined && message.postWizardPath !== null) { + var error = $types[2].verify(message.postWizardPath); + if (error) + return "postWizardPath." + error; + } + if (message.fileSubmitPath !== undefined && message.fileSubmitPath !== null) { + var error = $types[3].verify(message.fileSubmitPath); + if (error) + return "fileSubmitPath." + error; + } + return null; + }; - /** - * Populates the metadata subtree down to the specified tile. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * - * @returns {Promise<GoogleEarthEnterpriseTileInformation>} A promise that resolves to the tile info for the requested quad key - * - * @private - */ - GoogleEarthEnterpriseMetadata.prototype.populateSubtree = function(x, y, level, request) { - var quadkey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - return populateSubtree(this, quadkey, request); - }; + PostingServerProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.PostingServerProto) + return object; + var message = new $root.keyhole.dbroot.PostingServerProto(); + if (object.name !== undefined && object.name !== null) { + if (typeof object.name !== "object") + throw TypeError(".keyhole.dbroot.PostingServerProto.name: object expected"); + message.name = $types[0].fromObject(object.name); + } + if (object.baseUrl !== undefined && object.baseUrl !== null) { + if (typeof object.baseUrl !== "object") + throw TypeError(".keyhole.dbroot.PostingServerProto.baseUrl: object expected"); + message.baseUrl = $types[1].fromObject(object.baseUrl); + } + if (object.postWizardPath !== undefined && object.postWizardPath !== null) { + if (typeof object.postWizardPath !== "object") + throw TypeError(".keyhole.dbroot.PostingServerProto.postWizardPath: object expected"); + message.postWizardPath = $types[2].fromObject(object.postWizardPath); + } + if (object.fileSubmitPath !== undefined && object.fileSubmitPath !== null) { + if (typeof object.fileSubmitPath !== "object") + throw TypeError(".keyhole.dbroot.PostingServerProto.fileSubmitPath: object expected"); + message.fileSubmitPath = $types[3].fromObject(object.fileSubmitPath); + } + return message; + }; - function populateSubtree(that, quadKey, request) { - var tileInfo = that._tileInfo; - var q = quadKey; - var t = tileInfo[q]; - // If we have tileInfo make sure sure it is not a node with a subtree that's not loaded - if (defined(t) && (!t.hasSubtree() || t.hasChildren())) { - return t; - } + PostingServerProto.from = PostingServerProto.fromObject; - while ((t === undefined) && q.length > 1) { - q = q.substring(0, q.length - 1); - t = tileInfo[q]; - } + PostingServerProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.name = null; + object.baseUrl = null; + object.postWizardPath = null; + object.fileSubmitPath = null; + } + if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) + object.name = $types[0].toObject(message.name, options); + if (message.baseUrl !== undefined && message.baseUrl !== null && message.hasOwnProperty("baseUrl")) + object.baseUrl = $types[1].toObject(message.baseUrl, options); + if (message.postWizardPath !== undefined && message.postWizardPath !== null && message.hasOwnProperty("postWizardPath")) + object.postWizardPath = $types[2].toObject(message.postWizardPath, options); + if (message.fileSubmitPath !== undefined && message.fileSubmitPath !== null && message.hasOwnProperty("fileSubmitPath")) + object.fileSubmitPath = $types[3].toObject(message.fileSubmitPath, options); + return object; + }; - var subtreeRequest; - var subtreePromises = that._subtreePromises; - var promise = subtreePromises[q]; - if (defined(promise)) { - return promise - .then(function() { - // Recursively call this in case we need multiple subtree requests - subtreeRequest = new Request({ - throttle : request.throttle, - throttleByServer : request.throttleByServer, - type : request.type, - priorityFunction : request.priorityFunction - }); - return populateSubtree(that, quadKey, subtreeRequest); - }); - } + PostingServerProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - // t is either - // null so one of its parents was a leaf node, so this tile doesn't exist - // exists but doesn't have a subtree to request - // undefined so no parent exists - this shouldn't ever happen once the provider is ready - if (!defined(t) || !t.hasSubtree()) { - return when.reject(new RuntimeError('Couldn\'t load metadata for tile ' + quadKey)); - } + PostingServerProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - // We need to split up the promise here because when will execute syncronously if getQuadTreePacket - // is already resolved (like in the tests), so subtreePromises will never get cleared out. - // Only the initial request will also remove the promise from subtreePromises. - promise = that.getQuadTreePacket(q, t.cnodeVersion, request); - if (!defined(promise)) { - return undefined; - } - subtreePromises[q] = promise; + return PostingServerProto; + })(); - return promise - .then(function() { - // Recursively call this in case we need multiple subtree requests - subtreeRequest = new Request({ - throttle : request.throttle, - throttleByServer : request.throttleByServer, - type : request.type, - priorityFunction : request.priorityFunction - }); - return populateSubtree(that, quadKey, subtreeRequest); - }) - .always(function() { - delete subtreePromises[q]; - }); - } + dbroot.PlanetaryDatabaseProto = (function() { - /** - * Gets information about a tile - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @returns {GoogleEarthEnterpriseTileInformation|undefined} Information about the tile or undefined if it isn't loaded. - * - * @private - */ - GoogleEarthEnterpriseMetadata.prototype.getTileInformation = function(x, y, level) { - var quadkey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - return this._tileInfo[quadkey]; - }; + function PlanetaryDatabaseProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * Gets information about a tile from a quadKey - * - * @param {String} quadkey The quadkey for the tile - * @returns {GoogleEarthEnterpriseTileInformation|undefined} Information about the tile or undefined if it isn't loaded. - * - * @private - */ - GoogleEarthEnterpriseMetadata.prototype.getTileInformationFromQuadKey = function(quadkey) { - return this._tileInfo[quadkey]; - }; + PlanetaryDatabaseProto.prototype.url = null; + PlanetaryDatabaseProto.prototype.name = null; - function getMetadataUrl(that, quadKey, version) { - return joinUrls(that._url, 'flatfile?q2-0' + quadKey + '-q.' + version.toString()); - } + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 1 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - function requestDbRoot(that) { - var url = joinUrls(that._url, 'dbRoot.v5?output=proto'); - var proxy = that._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } + PlanetaryDatabaseProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.PlanetaryDatabaseProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.name = $types[1].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - var promise = loadArrayBuffer(url) - .then(function(buf) { - var encryptedDbRootProto = dbrootParser.EncryptedDbRootProto.decode(new Uint8Array(buf)); + PlanetaryDatabaseProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var error = $types[0].verify(message.url); + if (error) + return "url." + error; + var error = $types[1].verify(message.name); + if (error) + return "name." + error; + return null; + }; - var byteArray = encryptedDbRootProto.encryptionData; - var offset = byteArray.byteOffset; - var end = offset + byteArray.byteLength; - var key = that.key = byteArray.buffer.slice(offset, end); + PlanetaryDatabaseProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.PlanetaryDatabaseProto) + return object; + var message = new $root.keyhole.dbroot.PlanetaryDatabaseProto(); + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.url: object expected"); + message.url = $types[0].fromObject(object.url); + } + if (object.name !== undefined && object.name !== null) { + if (typeof object.name !== "object") + throw TypeError(".keyhole.dbroot.PlanetaryDatabaseProto.name: object expected"); + message.name = $types[1].fromObject(object.name); + } + return message; + }; - byteArray = encryptedDbRootProto.dbrootData; - offset = byteArray.byteOffset; - end = offset + byteArray.byteLength; - var dbRootCompressed = byteArray.buffer.slice(offset, end); - return taskProcessor.scheduleTask({ - buffer : dbRootCompressed, - type : 'DbRoot', - key: key - }, [dbRootCompressed]); - }) - .then(function(result) { - var dbRoot = dbrootParser.DbRootProto.decode(new Uint8Array(result.buffer)); - that.imageryPresent = defaultValue(dbRoot.imageryPresent, that.imageryPresent); - that.protoImagery = dbRoot.protoImagery; - that.terrainPresent = defaultValue(dbRoot.terrainPresent, that.terrainPresent); - if (defined(dbRoot.endSnippet) && defined(dbRoot.endSnippet.model)) { - var model = dbRoot.endSnippet.model; - that.negativeAltitudeExponentBias = defaultValue(model.negativeAltitudeExponentBias, that.negativeAltitudeExponentBias); - that.negativeAltitudeThreshold = defaultValue(model.compressedNegativeAltitudeThreshold, that.negativeAltitudeThreshold); - } - if (defined(dbRoot.databaseVersion)) { - that._quadPacketVersion = defaultValue(dbRoot.databaseVersion.quadtreeVersion, that._quadPacketVersion); - } - var providers = that.providers; - var providerInfo = defaultValue(dbRoot.providerInfo, []); - var count = providerInfo.length; - for(var i=0;i<count;++i) { - var provider = providerInfo[i]; - var copyrightString = provider.copyrightString; - if (defined(copyrightString)) { - providers[provider.providerId] = new Credit({text: copyrightString.value}); - } - } - }) - .otherwise(function() { - // Just eat the error and use the default values. - console.log('Failed to retrieve ' + url + '. Using defaults.'); - that.key = defaultKey; - }); - - - return promise; - } - - return GoogleEarthEnterpriseMetadata; -}); - -define('Core/GoogleEarthEnterpriseTerrainData',[ - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './Check', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './IndexDatatype', - './Intersections2D', - './Math', - './OrientedBoundingBox', - './QuantizedMeshTerrainData', - './Rectangle', - './TaskProcessor', - './TerrainEncoding', - './TerrainMesh' - ], function( - BoundingSphere, - Cartesian2, - Cartesian3, - Check, - defaultValue, - defined, - defineProperties, - DeveloperError, - IndexDatatype, - Intersections2D, - CesiumMath, - OrientedBoundingBox, - QuantizedMeshTerrainData, - Rectangle, - TaskProcessor, - TerrainEncoding, - TerrainMesh) { - 'use strict'; - - /** - * Terrain data for a single tile from a Google Earth Enterprise server. - * - * @alias GoogleEarthEnterpriseTerrainData - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {ArrayBuffer} options.buffer The buffer containing terrain data. - * @param {Number} options.negativeAltitudeExponentBias Multiplier for negative terrain heights that are encoded as very small positive values. - * @param {Number} options.negativeElevationThreshold Threshold for negative values - * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. - * If a child's bit is set, geometry will be requested for that tile as well when it - * is needed. If the bit is cleared, the child tile is not requested and geometry is - * instead upsampled from the parent. The bit values are as follows: - * <table> - * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> - * <tr><td>0</td><td>1</td><td>Southwest</td></tr> - * <tr><td>1</td><td>2</td><td>Southeast</td></tr> - * <tr><td>2</td><td>4</td><td>Northeast</td></tr> - * <tr><td>3</td><td>8</td><td>Northwest</td></tr> - * </table> - * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; - * otherwise, false. - * @param {Credit[]} [options.credits] Array of credits for this tile. - * - * - * @example - * var buffer = ... - * var childTileMask = ... - * var terrainData = new Cesium.GoogleEarthEnterpriseTerrainData({ - * buffer : heightBuffer, - * childTileMask : childTileMask - * }); - * - * @see TerrainData - * @see HeightTerrainData - * @see QuantizedMeshTerrainData - */ - function GoogleEarthEnterpriseTerrainData(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - Check.typeOf.object('options.buffer', options.buffer); - Check.typeOf.number('options.negativeAltitudeExponentBias', options.negativeAltitudeExponentBias); - Check.typeOf.number('options.negativeElevationThreshold', options.negativeElevationThreshold); - - this._buffer = options.buffer; - this._credits = options.credits; - this._negativeAltitudeExponentBias = options.negativeAltitudeExponentBias; - this._negativeElevationThreshold = options.negativeElevationThreshold; - - // Convert from google layout to layout of other providers - // 3 2 -> 2 3 - // 0 1 -> 0 1 - var googleChildTileMask = defaultValue(options.childTileMask, 15); - var childTileMask = googleChildTileMask & 3; // Bottom row is identical - childTileMask |= (googleChildTileMask & 4) ? 8 : 0; // NE - childTileMask |= (googleChildTileMask & 8) ? 4 : 0; // NW - - this._childTileMask = childTileMask; - - this._createdByUpsampling = defaultValue(options.createdByUpsampling, false); - - this._skirtHeight = undefined; - this._bufferType = this._buffer.constructor; - this._mesh = undefined; - this._minimumHeight = undefined; - this._maximumHeight = undefined; - this._vertexCountWithoutSkirts = undefined; - this._skirtIndex = undefined; - } - - defineProperties(GoogleEarthEnterpriseTerrainData.prototype, { - /** - * An array of credits for this tile - * @memberof GoogleEarthEnterpriseTerrainData.prototype - * @type {Credit[]} - */ - credits : { - get : function() { - return this._credits; - } - }, - /** - * The water mask included in this terrain data, if any. A water mask is a rectangular - * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. - * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. - * @memberof GoogleEarthEnterpriseTerrainData.prototype - * @type {Uint8Array|Image|Canvas} - */ - waterMask : { - get : function() { - return undefined; - } - } - }); - - var taskProcessor = new TaskProcessor('createVerticesFromGoogleEarthEnterpriseBuffer'); - - var nativeRectangleScratch = new Rectangle(); - var rectangleScratch = new Rectangle(); - - /** - * Creates a {@link TerrainMesh} from this terrain data. - * - * @private - * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many - * asynchronous mesh creations are already in progress and the operation should - * be retried later. - */ - GoogleEarthEnterpriseTerrainData.prototype.createMesh = function(tilingScheme, x, y, level, exaggeration) { - Check.typeOf.object('tilingScheme', tilingScheme); - Check.typeOf.number('x', x); - Check.typeOf.number('y', y); - Check.typeOf.number('level', level); - - var ellipsoid = tilingScheme.ellipsoid; - tilingScheme.tileXYToNativeRectangle(x, y, level, nativeRectangleScratch); - tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); - exaggeration = defaultValue(exaggeration, 1.0); - - // Compute the center of the tile for RTC rendering. - var center = ellipsoid.cartographicToCartesian(Rectangle.center(rectangleScratch)); - - var levelZeroMaxError = 40075.16; // From Google's Doc - var thisLevelMaxError = levelZeroMaxError / (1 << level); - this._skirtHeight = Math.min(thisLevelMaxError * 8.0, 1000.0); - - var verticesPromise = taskProcessor.scheduleTask({ - buffer : this._buffer, - nativeRectangle : nativeRectangleScratch, - rectangle : rectangleScratch, - relativeToCenter : center, - ellipsoid : ellipsoid, - skirtHeight : this._skirtHeight, - exaggeration : exaggeration, - includeWebMercatorT : true, - negativeAltitudeExponentBias: this._negativeAltitudeExponentBias, - negativeElevationThreshold: this._negativeElevationThreshold - }); - - if (!defined(verticesPromise)) { - // Postponed - return undefined; - } - - var that = this; - return verticesPromise - .then(function(result) { - that._mesh = new TerrainMesh( - center, - new Float32Array(result.vertices), - new Uint16Array(result.indices), - result.minimumHeight, - result.maximumHeight, - result.boundingSphere3D, - result.occludeePointInScaledSpace, - result.numberOfAttributes, - result.orientedBoundingBox, - TerrainEncoding.clone(result.encoding), - exaggeration); - - that._vertexCountWithoutSkirts = result.vertexCountWithoutSkirts; - that._skirtIndex = result.skirtIndex; - that._minimumHeight = result.minimumHeight; - that._maximumHeight = result.maximumHeight; - - // Free memory received from server after mesh is created. - that._buffer = undefined; - return that._mesh; - }); - }; - - /** - * Computes the terrain height at a specified longitude and latitude. - * - * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. If the position - * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly - * incorrect for positions far outside the rectangle. - */ - GoogleEarthEnterpriseTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) { - var u = CesiumMath.clamp((longitude - rectangle.west) / rectangle.width, 0.0, 1.0); - var v = CesiumMath.clamp((latitude - rectangle.south) / rectangle.height, 0.0, 1.0); - - if (!defined(this._mesh)) { - return interpolateHeight(this, u, v, rectangle); - } - - return interpolateMeshHeight(this, u, v); - }; - - var upsampleTaskProcessor = new TaskProcessor('upsampleQuantizedTerrainMesh'); - - /** - * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the - * height samples in this instance, interpolated if necessary. - * - * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, - * or undefined if too many asynchronous upsample operations are in progress and the request has been - * deferred. - */ - GoogleEarthEnterpriseTerrainData.prototype.upsample = function(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) { - Check.typeOf.object('tilingScheme', tilingScheme); - Check.typeOf.number('thisX', thisX); - Check.typeOf.number('thisY', thisY); - Check.typeOf.number('thisLevel', thisLevel); - Check.typeOf.number('descendantX', descendantX); - Check.typeOf.number('descendantY', descendantY); - Check.typeOf.number('descendantLevel', descendantLevel); - var levelDifference = descendantLevel - thisLevel; - if (levelDifference > 1) { - throw new DeveloperError('Upsampling through more than one level at a time is not currently supported.'); - } - - var mesh = this._mesh; - if (!defined(this._mesh)) { - return undefined; - } - - var isEastChild = thisX * 2 !== descendantX; - var isNorthChild = thisY * 2 === descendantY; - - var ellipsoid = tilingScheme.ellipsoid; - var childRectangle = tilingScheme.tileXYToRectangle(descendantX, descendantY, descendantLevel); - - var upsamplePromise = upsampleTaskProcessor.scheduleTask({ - vertices : mesh.vertices, - vertexCountWithoutSkirts : this._vertexCountWithoutSkirts, - indices : mesh.indices, - skirtIndex : this._skirtIndex, - encoding : mesh.encoding, - minimumHeight : this._minimumHeight, - maximumHeight : this._maximumHeight, - isEastChild : isEastChild, - isNorthChild : isNorthChild, - childRectangle : childRectangle, - ellipsoid : ellipsoid, - exaggeration : mesh.exaggeration - }); - - if (!defined(upsamplePromise)) { - // Postponed - return undefined; - } - - var that = this; - return upsamplePromise - .then(function(result) { - var quantizedVertices = new Uint16Array(result.vertices); - var indicesTypedArray = IndexDatatype.createTypedArray(quantizedVertices.length / 3, result.indices); - - var skirtHeight = that._skirtHeight; - - // Use QuantizedMeshTerrainData since we have what we need already parsed - return new QuantizedMeshTerrainData({ - quantizedVertices : quantizedVertices, - indices : indicesTypedArray, - minimumHeight : result.minimumHeight, - maximumHeight : result.maximumHeight, - boundingSphere : BoundingSphere.clone(result.boundingSphere), - orientedBoundingBox : OrientedBoundingBox.clone(result.orientedBoundingBox), - horizonOcclusionPoint : Cartesian3.clone(result.horizonOcclusionPoint), - westIndices : result.westIndices, - southIndices : result.southIndices, - eastIndices : result.eastIndices, - northIndices : result.northIndices, - westSkirtHeight : skirtHeight, - southSkirtHeight : skirtHeight, - eastSkirtHeight : skirtHeight, - northSkirtHeight : skirtHeight, - childTileMask : 0, - createdByUpsampling : true, - credits : that._credits - }); - }); - }; - - /** - * Determines if a given child tile is available, based on the - * {@link HeightmapTerrainData.childTileMask}. The given child tile coordinates are assumed - * to be one of the four children of this tile. If non-child tile coordinates are - * given, the availability of the southeast child tile is returned. - * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. - */ - GoogleEarthEnterpriseTerrainData.prototype.isChildAvailable = function(thisX, thisY, childX, childY) { - Check.typeOf.number('thisX', thisX); - Check.typeOf.number('thisY', thisY); - Check.typeOf.number('childX', childX); - Check.typeOf.number('childY', childY); - - var bitNumber = 2; // northwest child - if (childX !== thisX * 2) { - ++bitNumber; // east child - } - if (childY !== thisY * 2) { - bitNumber -= 2; // south child - } - - return (this._childTileMask & (1 << bitNumber)) !== 0; - }; - - /** - * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution - * terrain data. If this value is false, the data was obtained from some other source, such - * as by downloading it from a remote server. This method should return true for instances - * returned from a call to {@link HeightmapTerrainData#upsample}. - * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. - */ - GoogleEarthEnterpriseTerrainData.prototype.wasCreatedByUpsampling = function() { - return this._createdByUpsampling; - }; - - var texCoordScratch0 = new Cartesian2(); - var texCoordScratch1 = new Cartesian2(); - var texCoordScratch2 = new Cartesian2(); - var barycentricCoordinateScratch = new Cartesian3(); - - function interpolateMeshHeight(terrainData, u, v) { - var mesh = terrainData._mesh; - var vertices = mesh.vertices; - var encoding = mesh.encoding; - var indices = mesh.indices; - - for (var i = 0, len = indices.length; i < len; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - - var uv0 = encoding.decodeTextureCoordinates(vertices, i0, texCoordScratch0); - var uv1 = encoding.decodeTextureCoordinates(vertices, i1, texCoordScratch1); - var uv2 = encoding.decodeTextureCoordinates(vertices, i2, texCoordScratch2); - - var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, barycentricCoordinateScratch); - if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { - var h0 = encoding.decodeHeight(vertices, i0); - var h1 = encoding.decodeHeight(vertices, i1); - var h2 = encoding.decodeHeight(vertices, i2); - return barycentric.x * h0 + barycentric.y * h1 + barycentric.z * h2; - } - } - - // Position does not lie in any triangle in this mesh. - return undefined; - } - - var sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT; - var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - var sizeOfInt32 = Int32Array.BYTES_PER_ELEMENT; - var sizeOfFloat = Float32Array.BYTES_PER_ELEMENT; - var sizeOfDouble = Float64Array.BYTES_PER_ELEMENT; - - function interpolateHeight(terrainData, u, v, rectangle) { - var buffer = terrainData._buffer; - var quad = 0; // SW - var uStart = 0.0; - var vStart = 0.0; - if (v > 0.5) { // Upper row - if (u > 0.5) { // NE - quad = 2; - uStart = 0.5; - } else { // NW - quad = 3; - } - vStart = 0.5; - } else if (u > 0.5) { // SE - quad = 1; - uStart = 0.5; - } - - var dv = new DataView(buffer); - var offset = 0; - for (var q = 0; q < quad; ++q) { - offset += dv.getUint32(offset, true); - offset += sizeOfUint32; - } - offset += sizeOfUint32; // Skip length of quad - offset += 2 * sizeOfDouble; // Skip origin - - // Read sizes - var xSize = CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0); - offset += sizeOfDouble; - var ySize = CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0); - offset += sizeOfDouble; - - // Samples per quad - var xScale = rectangle.width / xSize / 2; - var yScale = rectangle.height / ySize / 2; - - // Number of points - var numPoints = dv.getInt32(offset, true); - offset += sizeOfInt32; - - // Number of faces - var numIndices = dv.getInt32(offset, true) * 3; - offset += sizeOfInt32; - - offset += sizeOfInt32; // Skip Level - - var uBuffer = new Array(numPoints); - var vBuffer = new Array(numPoints); - var heights = new Array(numPoints); - var i; - for (i = 0; i < numPoints; ++i) { - uBuffer[i] = uStart + (dv.getUint8(offset++) * xScale); - vBuffer[i] = vStart + (dv.getUint8(offset++) * yScale); - - // Height is stored in units of (1/EarthRadius) or (1/6371010.0) - heights[i] = (dv.getFloat32(offset, true) * 6371010.0); - offset += sizeOfFloat; - } - - var indices = new Array(numIndices); - for (i = 0; i < numIndices; ++i) { - indices[i] = dv.getUint16(offset, true); - offset += sizeOfUint16; - } - - for (i = 0; i < numIndices; i += 3) { - var i0 = indices[i]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - - var u0 = uBuffer[i0]; - var u1 = uBuffer[i1]; - var u2 = uBuffer[i2]; - - var v0 = vBuffer[i0]; - var v1 = vBuffer[i1]; - var v2 = vBuffer[i2]; - - var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, u0, v0, u1, v1, u2, v2, barycentricCoordinateScratch); - if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { - return barycentric.x * heights[i0] + - barycentric.y * heights[i1] + - barycentric.z * heights[i2]; - } - } - - // Position does not lie in any triangle in this mesh. - return undefined; - } - - return GoogleEarthEnterpriseTerrainData; -}); - -define('Core/GoogleEarthEnterpriseTerrainProvider',[ - '../ThirdParty/when', - './Credit', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Event', - './GeographicTilingScheme', - './GoogleEarthEnterpriseMetadata', - './GoogleEarthEnterpriseTerrainData', - './HeightmapTerrainData', - './JulianDate', - './loadArrayBuffer', - './Math', - './Rectangle', - './Request', - './RequestState', - './RequestType', - './RuntimeError', - './TaskProcessor', - './TileProviderError' - ], function( - when, - Credit, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - GeographicTilingScheme, - GoogleEarthEnterpriseMetadata, - GoogleEarthEnterpriseTerrainData, - HeightmapTerrainData, - JulianDate, - loadArrayBuffer, - CesiumMath, - Rectangle, - Request, - RequestState, - RequestType, - RuntimeError, - TaskProcessor, - TileProviderError) { - 'use strict'; + PlanetaryDatabaseProto.from = PlanetaryDatabaseProto.fromObject; - var TerrainState = { - UNKNOWN : 0, - NONE : 1, - SELF : 2, - PARENT : 3 - }; + PlanetaryDatabaseProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.url = null; + object.name = null; + } + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[0].toObject(message.url, options); + if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) + object.name = $types[1].toObject(message.name, options); + return object; + }; - var julianDateScratch = new JulianDate(); + PlanetaryDatabaseProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - function TerrainCache() { - this._terrainCache = {}; - this._lastTidy = JulianDate.now(); - } + PlanetaryDatabaseProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - TerrainCache.prototype.add = function(quadKey, buffer) { - this._terrainCache[quadKey] = { - buffer : buffer, - timestamp : JulianDate.now() - }; - }; + return PlanetaryDatabaseProto; + })(); - TerrainCache.prototype.get = function(quadKey) { - var terrainCache = this._terrainCache; - var result = terrainCache[quadKey]; - if (defined(result)) { - delete this._terrainCache[quadKey]; - return result.buffer; - } - }; + dbroot.LogServerProto = (function() { - TerrainCache.prototype.tidy = function() { - JulianDate.now(julianDateScratch); - if (JulianDate.secondsDifference(julianDateScratch, this._lastTidy) > 10) { - var terrainCache = this._terrainCache; - var keys = Object.keys(terrainCache); - var count = keys.length; - for (var i = 0; i < count; ++i) { - var k = keys[i]; - var e = terrainCache[k]; - if (JulianDate.secondsDifference(julianDateScratch, e.timestamp) > 10) { - delete terrainCache[k]; + function LogServerProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; } - } - - JulianDate.clone(julianDateScratch, this._lastTidy); - } - }; - /** - * Provides tiled terrain using the Google Earth Enterprise REST API. - * - * @alias GoogleEarthEnterpriseTerrainProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url of the Google Earth Enterprise server hosting the imagery. - * @param {GoogleEarthEnterpriseMetadata} options.metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseImageryProvider. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * - * @see GoogleEarthEnterpriseImageryProvider - * @see CesiumTerrainProvider - * - * @example - * var geeMetadata = new GoogleEarthEnterpriseMetadata('http://www.earthenterprise.org/3d'); - * var gee = new Cesium.GoogleEarthEnterpriseTerrainProvider({ - * metadata : geeMetadata - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - */ - function GoogleEarthEnterpriseTerrainProvider(options) { - options = defaultValue(options, {}); + LogServerProto.prototype.url = null; + LogServerProto.prototype.enable = false; + LogServerProto.prototype.throttlingFactor = 1; - if (!(defined(options.url) || defined(options.metadata))) { - throw new DeveloperError('options.url or options.metadata is required.'); - } - - var metadata; - if (defined(options.metadata)) { - metadata = this._metadata = options.metadata; - } else { - metadata = this._metadata = new GoogleEarthEnterpriseMetadata({ - url : options.url, - proxy : options.proxy - }); - } - this._proxy = defaultValue(options.proxy, this._metadata.proxy); + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - this._tilingScheme = new GeographicTilingScheme({ - numberOfLevelZeroTilesX : 2, - numberOfLevelZeroTilesY : 2, - rectangle : new Rectangle(-CesiumMath.PI, -CesiumMath.PI, CesiumMath.PI, CesiumMath.PI), - ellipsoid : options.ellipsoid - }); + LogServerProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.LogServerProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.enable = reader.bool(); + break; + case 3: + message.throttlingFactor = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - var credit = options.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); - } - this._credit = credit; + LogServerProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.url !== undefined && message.url !== null) { + var error = $types[0].verify(message.url); + if (error) + return "url." + error; + } + if (message.enable !== undefined) + if (typeof message.enable !== "boolean") + return "enable: boolean expected"; + if (message.throttlingFactor !== undefined) + if (!$util.isInteger(message.throttlingFactor)) + return "throttlingFactor: integer expected"; + return null; + }; - // Pulled from Google's documentation - this._levelZeroMaximumGeometricError = 40075.16; + LogServerProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.LogServerProto) + return object; + var message = new $root.keyhole.dbroot.LogServerProto(); + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.LogServerProto.url: object expected"); + message.url = $types[0].fromObject(object.url); + } + if (object.enable !== undefined && object.enable !== null) + message.enable = Boolean(object.enable); + if (object.throttlingFactor !== undefined && object.throttlingFactor !== null) + message.throttlingFactor = object.throttlingFactor | 0; + return message; + }; - this._terrainCache = new TerrainCache(); - this._terrainPromises = {}; - this._terrainRequests = {}; + LogServerProto.from = LogServerProto.fromObject; - this._errorEvent = new Event(); + LogServerProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.url = null; + object.enable = false; + object.throttlingFactor = 1; + } + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[0].toObject(message.url, options); + if (message.enable !== undefined && message.enable !== null && message.hasOwnProperty("enable")) + object.enable = message.enable; + if (message.throttlingFactor !== undefined && message.throttlingFactor !== null && message.hasOwnProperty("throttlingFactor")) + object.throttlingFactor = message.throttlingFactor; + return object; + }; - this._ready = false; - var that = this; - var metadataError; - this._readyPromise = metadata.readyPromise - .then(function(result) { - if (!metadata.terrainPresent) { - var e = new RuntimeError('The server ' + metadata.url + ' doesn\'t have terrain'); - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); - return when.reject(e); - } + LogServerProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - TileProviderError.handleSuccess(metadataError); - that._ready = result; - return result; - }) - .otherwise(function(e) { - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); - return when.reject(e); - }); - } + LogServerProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { - /** - * Gets the name of the Google Earth Enterprise server url hosting the imagery. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._metadata.url; - } - }, + return LogServerProto; + })(); - /** - * Gets the proxy used by this provider. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._proxy; - } - }, + dbroot.EndSnippetProto = (function() { - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + function EndSnippetProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; } - - return this._tilingScheme; - } - }, - - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._errorEvent; - } - }, - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, + EndSnippetProto.prototype.model = null; + EndSnippetProto.prototype.authServerUrl = null; + EndSnippetProto.prototype.disableAuthentication = false; + EndSnippetProto.prototype.mfeDomains = $util.emptyArray; + EndSnippetProto.prototype.mfeLangParam = "hl=$5Bhl5D"; + EndSnippetProto.prototype.adsUrlPatterns = ""; + EndSnippetProto.prototype.reverseGeocoderUrl = null; + EndSnippetProto.prototype.reverseGeocoderProtocolVersion = 3; + EndSnippetProto.prototype.skyDatabaseIsAvailable = true; + EndSnippetProto.prototype.skyDatabaseUrl = null; + EndSnippetProto.prototype.defaultWebPageIntlUrl = null; + EndSnippetProto.prototype.numStartUpTips = 17; + EndSnippetProto.prototype.startUpTipsUrl = null; + EndSnippetProto.prototype.numProStartUpTips = 0; + EndSnippetProto.prototype.proStartUpTipsUrl = null; + EndSnippetProto.prototype.startupTipsIntlUrl = null; + EndSnippetProto.prototype.userGuideIntlUrl = null; + EndSnippetProto.prototype.supportCenterIntlUrl = null; + EndSnippetProto.prototype.businessListingIntlUrl = null; + EndSnippetProto.prototype.supportAnswerIntlUrl = null; + EndSnippetProto.prototype.supportTopicIntlUrl = null; + EndSnippetProto.prototype.supportRequestIntlUrl = null; + EndSnippetProto.prototype.earthIntlUrl = null; + EndSnippetProto.prototype.addContentUrl = null; + EndSnippetProto.prototype.sketchupNotInstalledUrl = null; + EndSnippetProto.prototype.sketchupErrorUrl = null; + EndSnippetProto.prototype.freeLicenseUrl = null; + EndSnippetProto.prototype.proLicenseUrl = null; + EndSnippetProto.prototype.tutorialUrl = null; + EndSnippetProto.prototype.keyboardShortcutsUrl = null; + EndSnippetProto.prototype.releaseNotesUrl = null; + EndSnippetProto.prototype.hideUserData = false; + EndSnippetProto.prototype.useGeLogo = true; + EndSnippetProto.prototype.dioramaDescriptionUrlBase = null; + EndSnippetProto.prototype.dioramaDefaultColor = 4291281607; + EndSnippetProto.prototype.dioramaBlacklistUrl = null; + EndSnippetProto.prototype.clientOptions = null; + EndSnippetProto.prototype.fetchingOptions = null; + EndSnippetProto.prototype.timeMachineOptions = null; + EndSnippetProto.prototype.csiOptions = null; + EndSnippetProto.prototype.searchTab = $util.emptyArray; + EndSnippetProto.prototype.cobrandInfo = $util.emptyArray; + EndSnippetProto.prototype.validDatabase = $util.emptyArray; + EndSnippetProto.prototype.configScript = $util.emptyArray; + EndSnippetProto.prototype.deauthServerUrl = null; + EndSnippetProto.prototype.swoopParameters = null; + EndSnippetProto.prototype.bbsServerInfo = null; + EndSnippetProto.prototype.dataErrorServerInfo = null; + EndSnippetProto.prototype.planetaryDatabase = $util.emptyArray; + EndSnippetProto.prototype.logServer = null; + EndSnippetProto.prototype.autopiaOptions = null; + EndSnippetProto.prototype.searchConfig = null; + EndSnippetProto.prototype.searchInfo = null; + EndSnippetProto.prototype.elevationServiceBaseUrl = "http://maps.google.com/maps/api/elevation/"; + EndSnippetProto.prototype.elevationProfileQueryDelay = 500; + EndSnippetProto.prototype.proUpgradeUrl = null; + EndSnippetProto.prototype.earthCommunityUrl = null; + EndSnippetProto.prototype.googleMapsUrl = null; + EndSnippetProto.prototype.sharingUrl = null; + EndSnippetProto.prototype.privacyPolicyUrl = null; + EndSnippetProto.prototype.doGplusUserCheck = false; + EndSnippetProto.prototype.rocktreeDataProto = null; + EndSnippetProto.prototype.filmstripConfig = $util.emptyArray; + EndSnippetProto.prototype.showSigninButton = false; + EndSnippetProto.prototype.proMeasureUpsellUrl = null; + EndSnippetProto.prototype.proPrintUpsellUrl = null; + EndSnippetProto.prototype.starDataProto = null; + EndSnippetProto.prototype.feedbackUrl = null; + EndSnippetProto.prototype.oauth2LoginUrl = null; - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise; - } - }, + var $types = { + 0 : "keyhole.dbroot.PlanetModelProto", + 1 : "keyhole.dbroot.StringIdOrValueProto", + 3 : "keyhole.dbroot.MfeDomainFeaturesProto", + 6 : "keyhole.dbroot.StringIdOrValueProto", + 9 : "keyhole.dbroot.StringIdOrValueProto", + 10 : "keyhole.dbroot.StringIdOrValueProto", + 12 : "keyhole.dbroot.StringIdOrValueProto", + 14 : "keyhole.dbroot.StringIdOrValueProto", + 15 : "keyhole.dbroot.StringIdOrValueProto", + 16 : "keyhole.dbroot.StringIdOrValueProto", + 17 : "keyhole.dbroot.StringIdOrValueProto", + 18 : "keyhole.dbroot.StringIdOrValueProto", + 19 : "keyhole.dbroot.StringIdOrValueProto", + 20 : "keyhole.dbroot.StringIdOrValueProto", + 21 : "keyhole.dbroot.StringIdOrValueProto", + 22 : "keyhole.dbroot.StringIdOrValueProto", + 23 : "keyhole.dbroot.StringIdOrValueProto", + 24 : "keyhole.dbroot.StringIdOrValueProto", + 25 : "keyhole.dbroot.StringIdOrValueProto", + 26 : "keyhole.dbroot.StringIdOrValueProto", + 27 : "keyhole.dbroot.StringIdOrValueProto", + 28 : "keyhole.dbroot.StringIdOrValueProto", + 29 : "keyhole.dbroot.StringIdOrValueProto", + 30 : "keyhole.dbroot.StringIdOrValueProto", + 33 : "keyhole.dbroot.StringIdOrValueProto", + 35 : "keyhole.dbroot.StringIdOrValueProto", + 36 : "keyhole.dbroot.ClientOptionsProto", + 37 : "keyhole.dbroot.FetchingOptionsProto", + 38 : "keyhole.dbroot.TimeMachineOptionsProto", + 39 : "keyhole.dbroot.CSIOptionsProto", + 40 : "keyhole.dbroot.SearchTabProto", + 41 : "keyhole.dbroot.CobrandProto", + 42 : "keyhole.dbroot.DatabaseDescriptionProto", + 43 : "keyhole.dbroot.ConfigScriptProto", + 44 : "keyhole.dbroot.StringIdOrValueProto", + 45 : "keyhole.dbroot.SwoopParamsProto", + 46 : "keyhole.dbroot.PostingServerProto", + 47 : "keyhole.dbroot.PostingServerProto", + 48 : "keyhole.dbroot.PlanetaryDatabaseProto", + 49 : "keyhole.dbroot.LogServerProto", + 50 : "keyhole.dbroot.AutopiaOptionsProto", + 51 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto", + 52 : "keyhole.dbroot.EndSnippetProto.SearchInfoProto", + 55 : "keyhole.dbroot.StringIdOrValueProto", + 56 : "keyhole.dbroot.StringIdOrValueProto", + 57 : "keyhole.dbroot.StringIdOrValueProto", + 58 : "keyhole.dbroot.StringIdOrValueProto", + 59 : "keyhole.dbroot.StringIdOrValueProto", + 61 : "keyhole.dbroot.EndSnippetProto.RockTreeDataProto", + 62 : "keyhole.dbroot.EndSnippetProto.FilmstripConfigProto", + 64 : "keyhole.dbroot.StringIdOrValueProto", + 65 : "keyhole.dbroot.StringIdOrValueProto", + 66 : "keyhole.dbroot.EndSnippetProto.StarDataProto", + 67 : "keyhole.dbroot.StringIdOrValueProto", + 68 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - /** - * Gets the credit to display when this terrain provider is active. Typically this is used to credit - * the source of the terrain. This function should not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return this._credit; - } - }, - - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. This function should not be - * called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Boolean} - */ - hasWaterMask : { - get : function() { - return false; - } - }, - - /** - * Gets a value indicating whether or not the requested tiles include vertex normals. - * This function should not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Boolean} - */ - hasVertexNormals : { - get : function() { - return false; - } - }, - - /** - * Gets an object that can be used to determine availability of terrain from this provider, such as - * at points and in rectangles. This function should not be called before - * {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. This property may be undefined if availability - * information is not available. - * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {TileAvailability} - */ - availability : { - get : function() { - return undefined; - } - } - }); - - var taskProcessor = new TaskProcessor('decodeGoogleEarthEnterprisePacket', Number.POSITIVE_INFINITY); - - // If the tile has its own terrain, then you can just use its child bitmask. If it was requested using it's parent - // then you need to check all of its children to see if they have terrain. - function computeChildMask(quadKey, info, metadata) { - var childMask = info.getChildBitmask(); - if (info.terrainState === TerrainState.PARENT) { - childMask = 0; - for (var i = 0; i < 4; ++i) { - var child = metadata.getTileInformationFromQuadKey(quadKey + i.toString()); - if (defined(child) && child.hasTerrain()) { - childMask |= (1 << i); - } - } - } - - return childMask; - } - - /** - * Requests the geometry for a given tile. This function should not be called before - * {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. The result must include terrain data and - * may optionally include a water mask and an indication of which child tiles are available. - * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method - * returns undefined instead of a promise, it is an indication that too many requests are already - * pending and the request will be retried later. - * - * @exception {DeveloperError} This function must not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} - * returns true. - */ - GoogleEarthEnterpriseTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestTileGeometry must not be called before the terrain provider is ready.'); - } - - var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - var terrainCache = this._terrainCache; - var metadata = this._metadata; - var info = metadata.getTileInformationFromQuadKey(quadKey); - - // Check if this tile is even possibly available - if (!defined(info)) { - return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); - } - - var terrainState = info.terrainState; - if (!defined(terrainState)) { - // First time we have tried to load this tile, so set terrain state to UNKNOWN - terrainState = info.terrainState = TerrainState.UNKNOWN; - } - - // If its in the cache, return it - var buffer = terrainCache.get(quadKey); - if (defined(buffer)) { - var credit = metadata.providers[info.terrainProvider]; - return new GoogleEarthEnterpriseTerrainData({ - buffer : buffer, - childTileMask : computeChildMask(quadKey, info, metadata), - credits : defined(credit) ? [credit] : undefined, - negativeAltitudeExponentBias: metadata.negativeAltitudeExponentBias, - negativeElevationThreshold: metadata.negativeAltitudeThreshold - }); - } - - // Clean up the cache - terrainCache.tidy(); - - // We have a tile, check to see if no ancestors have terrain or that we know for sure it doesn't - if (!info.ancestorHasTerrain) { - // We haven't reached a level with terrain, so return the ellipsoid - return new HeightmapTerrainData({ - buffer : new Uint8Array(16 * 16), - width : 16, - height : 16 - }); - } else if (terrainState === TerrainState.NONE) { - // Already have info and there isn't any terrain here - return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); - } - - // Figure out where we are getting the terrain and what version - var parentInfo; - var q = quadKey; - var terrainVersion = -1; - switch (terrainState) { - case TerrainState.SELF: // We have terrain and have retrieved it before - terrainVersion = info.terrainVersion; - break; - case TerrainState.PARENT: // We have terrain in our parent - q = q.substring(0, q.length - 1); - parentInfo = metadata.getTileInformationFromQuadKey(q); - terrainVersion = parentInfo.terrainVersion; - break; - case TerrainState.UNKNOWN: // We haven't tried to retrieve terrain yet - if (info.hasTerrain()) { - terrainVersion = info.terrainVersion; // We should have terrain - } else { - q = q.substring(0, q.length - 1); - parentInfo = metadata.getTileInformationFromQuadKey(q); - if (defined(parentInfo) && parentInfo.hasTerrain()) { - terrainVersion = parentInfo.terrainVersion; // Try checking in the parent + EndSnippetProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.model = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.authServerUrl = $types[1].decode(reader, reader.uint32()); + break; + case 3: + message.disableAuthentication = reader.bool(); + break; + case 4: + if (!(message.mfeDomains && message.mfeDomains.length)) + message.mfeDomains = []; + message.mfeDomains.push($types[3].decode(reader, reader.uint32())); + break; + case 5: + message.mfeLangParam = reader.string(); + break; + case 6: + message.adsUrlPatterns = reader.string(); + break; + case 7: + message.reverseGeocoderUrl = $types[6].decode(reader, reader.uint32()); + break; + case 8: + message.reverseGeocoderProtocolVersion = reader.int32(); + break; + case 9: + message.skyDatabaseIsAvailable = reader.bool(); + break; + case 10: + message.skyDatabaseUrl = $types[9].decode(reader, reader.uint32()); + break; + case 11: + message.defaultWebPageIntlUrl = $types[10].decode(reader, reader.uint32()); + break; + case 12: + message.numStartUpTips = reader.int32(); + break; + case 13: + message.startUpTipsUrl = $types[12].decode(reader, reader.uint32()); + break; + case 51: + message.numProStartUpTips = reader.int32(); + break; + case 52: + message.proStartUpTipsUrl = $types[14].decode(reader, reader.uint32()); + break; + case 64: + message.startupTipsIntlUrl = $types[15].decode(reader, reader.uint32()); + break; + case 14: + message.userGuideIntlUrl = $types[16].decode(reader, reader.uint32()); + break; + case 15: + message.supportCenterIntlUrl = $types[17].decode(reader, reader.uint32()); + break; + case 16: + message.businessListingIntlUrl = $types[18].decode(reader, reader.uint32()); + break; + case 17: + message.supportAnswerIntlUrl = $types[19].decode(reader, reader.uint32()); + break; + case 18: + message.supportTopicIntlUrl = $types[20].decode(reader, reader.uint32()); + break; + case 19: + message.supportRequestIntlUrl = $types[21].decode(reader, reader.uint32()); + break; + case 20: + message.earthIntlUrl = $types[22].decode(reader, reader.uint32()); + break; + case 21: + message.addContentUrl = $types[23].decode(reader, reader.uint32()); + break; + case 22: + message.sketchupNotInstalledUrl = $types[24].decode(reader, reader.uint32()); + break; + case 23: + message.sketchupErrorUrl = $types[25].decode(reader, reader.uint32()); + break; + case 24: + message.freeLicenseUrl = $types[26].decode(reader, reader.uint32()); + break; + case 25: + message.proLicenseUrl = $types[27].decode(reader, reader.uint32()); + break; + case 48: + message.tutorialUrl = $types[28].decode(reader, reader.uint32()); + break; + case 49: + message.keyboardShortcutsUrl = $types[29].decode(reader, reader.uint32()); + break; + case 50: + message.releaseNotesUrl = $types[30].decode(reader, reader.uint32()); + break; + case 26: + message.hideUserData = reader.bool(); + break; + case 27: + message.useGeLogo = reader.bool(); + break; + case 28: + message.dioramaDescriptionUrlBase = $types[33].decode(reader, reader.uint32()); + break; + case 29: + message.dioramaDefaultColor = reader.uint32(); + break; + case 53: + message.dioramaBlacklistUrl = $types[35].decode(reader, reader.uint32()); + break; + case 30: + message.clientOptions = $types[36].decode(reader, reader.uint32()); + break; + case 31: + message.fetchingOptions = $types[37].decode(reader, reader.uint32()); + break; + case 32: + message.timeMachineOptions = $types[38].decode(reader, reader.uint32()); + break; + case 33: + message.csiOptions = $types[39].decode(reader, reader.uint32()); + break; + case 34: + if (!(message.searchTab && message.searchTab.length)) + message.searchTab = []; + message.searchTab.push($types[40].decode(reader, reader.uint32())); + break; + case 35: + if (!(message.cobrandInfo && message.cobrandInfo.length)) + message.cobrandInfo = []; + message.cobrandInfo.push($types[41].decode(reader, reader.uint32())); + break; + case 36: + if (!(message.validDatabase && message.validDatabase.length)) + message.validDatabase = []; + message.validDatabase.push($types[42].decode(reader, reader.uint32())); + break; + case 37: + if (!(message.configScript && message.configScript.length)) + message.configScript = []; + message.configScript.push($types[43].decode(reader, reader.uint32())); + break; + case 38: + message.deauthServerUrl = $types[44].decode(reader, reader.uint32()); + break; + case 39: + message.swoopParameters = $types[45].decode(reader, reader.uint32()); + break; + case 40: + message.bbsServerInfo = $types[46].decode(reader, reader.uint32()); + break; + case 41: + message.dataErrorServerInfo = $types[47].decode(reader, reader.uint32()); + break; + case 42: + if (!(message.planetaryDatabase && message.planetaryDatabase.length)) + message.planetaryDatabase = []; + message.planetaryDatabase.push($types[48].decode(reader, reader.uint32())); + break; + case 43: + message.logServer = $types[49].decode(reader, reader.uint32()); + break; + case 44: + message.autopiaOptions = $types[50].decode(reader, reader.uint32()); + break; + case 54: + message.searchConfig = $types[51].decode(reader, reader.uint32()); + break; + case 45: + message.searchInfo = $types[52].decode(reader, reader.uint32()); + break; + case 46: + message.elevationServiceBaseUrl = reader.string(); + break; + case 47: + message.elevationProfileQueryDelay = reader.int32(); + break; + case 55: + message.proUpgradeUrl = $types[55].decode(reader, reader.uint32()); + break; + case 56: + message.earthCommunityUrl = $types[56].decode(reader, reader.uint32()); + break; + case 57: + message.googleMapsUrl = $types[57].decode(reader, reader.uint32()); + break; + case 58: + message.sharingUrl = $types[58].decode(reader, reader.uint32()); + break; + case 59: + message.privacyPolicyUrl = $types[59].decode(reader, reader.uint32()); + break; + case 60: + message.doGplusUserCheck = reader.bool(); + break; + case 61: + message.rocktreeDataProto = $types[61].decode(reader, reader.uint32()); + break; + case 62: + if (!(message.filmstripConfig && message.filmstripConfig.length)) + message.filmstripConfig = []; + message.filmstripConfig.push($types[62].decode(reader, reader.uint32())); + break; + case 63: + message.showSigninButton = reader.bool(); + break; + case 65: + message.proMeasureUpsellUrl = $types[64].decode(reader, reader.uint32()); + break; + case 66: + message.proPrintUpsellUrl = $types[65].decode(reader, reader.uint32()); + break; + case 67: + message.starDataProto = $types[66].decode(reader, reader.uint32()); + break; + case 68: + message.feedbackUrl = $types[67].decode(reader, reader.uint32()); + break; + case 69: + message.oauth2LoginUrl = $types[68].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } } - } - break; - } - - // We can't figure out where to get the terrain - if (terrainVersion < 0) { - return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); - } - - // Load that terrain - var terrainPromises = this._terrainPromises; - var terrainRequests = this._terrainRequests; - var url = buildTerrainUrl(this, q, terrainVersion); - var sharedPromise; - var sharedRequest; - if (defined(terrainPromises[q])) { // Already being loaded possibly from another child, so return existing promise - sharedPromise = terrainPromises[q]; - sharedRequest = terrainRequests[q]; - } else { // Create new request for terrain - sharedRequest = request; - var requestPromise = loadArrayBuffer(url, undefined, sharedRequest); - - if (!defined(requestPromise)) { - return undefined; // Throttled - } - - sharedPromise = requestPromise - .then(function(terrain) { - if (defined(terrain)) { - return taskProcessor.scheduleTask({ - buffer : terrain, - type : 'Terrain', - key : metadata.key - }, [terrain]) - .then(function(terrainTiles) { - // Add requested tile and mark it as SELF - var requestedInfo = metadata.getTileInformationFromQuadKey(q); - requestedInfo.terrainState = TerrainState.SELF; - terrainCache.add(q, terrainTiles[0]); - var provider = requestedInfo.terrainProvider; + return message; + }; - // Add children to cache - var count = terrainTiles.length - 1; - for (var j = 0; j < count; ++j) { - var childKey = q + j.toString(); - var child = metadata.getTileInformationFromQuadKey(childKey); - if (defined(child)) { - terrainCache.add(childKey, terrainTiles[j + 1]); - child.terrainState = TerrainState.PARENT; - if (child.terrainProvider === 0) { - child.terrainProvider = provider; - } - } - } - }); + EndSnippetProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.model !== undefined && message.model !== null) { + var error = $types[0].verify(message.model); + if (error) + return "model." + error; } - - return when.reject(new RuntimeError('Failed to load terrain.')); - }); - - terrainPromises[q] = sharedPromise; // Store promise without delete from terrainPromises - terrainRequests[q] = sharedRequest; - - // Set promise so we remove from terrainPromises just one time - sharedPromise = sharedPromise - .always(function() { - delete terrainPromises[q]; - delete terrainRequests[q]; - }); - } - - return sharedPromise - .then(function() { - var buffer = terrainCache.get(quadKey); - if (defined(buffer)) { - var credit = metadata.providers[info.terrainProvider]; - return new GoogleEarthEnterpriseTerrainData({ - buffer : buffer, - childTileMask : computeChildMask(quadKey, info, metadata), - credits : defined(credit) ? [credit] : undefined, - negativeAltitudeExponentBias: metadata.negativeAltitudeExponentBias, - negativeElevationThreshold: metadata.negativeAltitudeThreshold - }); - } - - return when.reject(new RuntimeError('Failed to load terrain.')); - }) - .otherwise(function(error) { - if (sharedRequest.state === RequestState.CANCELLED) { - request.state = sharedRequest.state; - return when.reject(error); - } - info.terrainState = TerrainState.NONE; - return when.reject(error); - }); - }; - - /** - * Gets the maximum geometric error allowed in a tile at a given level. - * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. - */ - GoogleEarthEnterpriseTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { - return this._levelZeroMaximumGeometricError / (1 << level); - }; - - /** - * Determines whether data for a tile is available to be loaded. - * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean} Undefined if not supported, otherwise true or false. - */ - GoogleEarthEnterpriseTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { - var metadata = this._metadata; - var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - - var info = metadata.getTileInformation(x, y, level); - if (info === null) { - return false; - } - - if (defined(info)) { - if (!info.ancestorHasTerrain) { - return true; // We'll just return the ellipsoid - } - - var terrainState = info.terrainState; - if (terrainState === TerrainState.NONE) { - return false; // Terrain is not available - } - - if (!defined(terrainState) || (terrainState === TerrainState.UNKNOWN)) { - info.terrainState = TerrainState.UNKNOWN; - if (!info.hasTerrain()) { - quadKey = quadKey.substring(0, quadKey.length - 1); - var parentInfo = metadata.getTileInformationFromQuadKey(quadKey); - if (!defined(parentInfo) || !parentInfo.hasTerrain()) { - return false; + if (message.authServerUrl !== undefined && message.authServerUrl !== null) { + var error = $types[1].verify(message.authServerUrl); + if (error) + return "authServerUrl." + error; } - } - } - - return true; - } - - if (metadata.isValid(quadKey)) { - // We will need this tile, so request metadata and return false for now - var request = new Request({ - throttle : true, - throttleByServer : true, - type : RequestType.TERRAIN - }); - metadata.populateSubtree(x, y, level, request); - } - return false; - }; - - // - // Functions to handle imagery packets - // - function buildTerrainUrl(terrainProvider, quadKey, version) { - version = (defined(version) && version > 0) ? version : 1; - var terrainUrl = terrainProvider.url + 'flatfile?f1c-0' + quadKey + '-t.' + version.toString(); - - var proxy = terrainProvider._proxy; - if (defined(proxy)) { - terrainUrl = proxy.getURL(terrainUrl); - } - - return terrainUrl; - } - - return GoogleEarthEnterpriseTerrainProvider; -}); - -define('Core/HeadingPitchRange',[ - './defaultValue', - './defined' - ], function( - defaultValue, - defined) { - 'use strict'; - - /** - * Defines a heading angle, pitch angle, and range in a local frame. - * Heading is the rotation from the local north direction where a positive angle is increasing eastward. - * Pitch is the rotation from the local xy-plane. Positive pitch angles are above the plane. Negative pitch - * angles are below the plane. Range is the distance from the center of the frame. - * @alias HeadingPitchRange - * @constructor - * - * @param {Number} [heading=0.0] The heading angle in radians. - * @param {Number} [pitch=0.0] The pitch angle in radians. - * @param {Number} [range=0.0] The distance from the center in meters. - */ - function HeadingPitchRange(heading, pitch, range) { - /** - * Heading is the rotation from the local north direction where a positive angle is increasing eastward. - * @type {Number} - */ - this.heading = defaultValue(heading, 0.0); - - /** - * Pitch is the rotation from the local xy-plane. Positive pitch angles - * are above the plane. Negative pitch angles are below the plane. - * @type {Number} - */ - this.pitch = defaultValue(pitch, 0.0); - - /** - * Range is the distance from the center of the local frame. - * @type {Number} - */ - this.range = defaultValue(range, 0.0); - } - - /** - * Duplicates a HeadingPitchRange instance. - * - * @param {HeadingPitchRange} hpr The HeadingPitchRange to duplicate. - * @param {HeadingPitchRange} [result] The object onto which to store the result. - * @returns {HeadingPitchRange} The modified result parameter or a new HeadingPitchRange instance if one was not provided. (Returns undefined if hpr is undefined) - */ - HeadingPitchRange.clone = function(hpr, result) { - if (!defined(hpr)) { - return undefined; - } - if (!defined(result)) { - result = new HeadingPitchRange(); - } - - result.heading = hpr.heading; - result.pitch = hpr.pitch; - result.range = hpr.range; - return result; - }; - - return HeadingPitchRange; -}); - -define('Core/HeadingPitchRoll',[ - './defaultValue', - './defined', - './DeveloperError', - './Math' - ], function( - defaultValue, - defined, - DeveloperError, - CesiumMath) { - 'use strict'; - - /** - * A rotation expressed as a heading, pitch, and roll. Heading is the rotation about the - * negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about - * the positive x axis. - * @alias HeadingPitchRoll - * @constructor - * - * @param {Number} [heading=0.0] The heading component in radians. - * @param {Number} [pitch=0.0] The pitch component in radians. - * @param {Number} [roll=0.0] The roll component in radians. - */ - function HeadingPitchRoll(heading, pitch, roll) { - this.heading = defaultValue(heading, 0.0); - this.pitch = defaultValue(pitch, 0.0); - this.roll = defaultValue(roll, 0.0); - } - - /** - * Computes the heading, pitch and roll from a quaternion (see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles ) - * - * @param {Quaternion} quaternion The quaternion from which to retrieve heading, pitch, and roll, all expressed in radians. - * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned. - * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. - */ - HeadingPitchRoll.fromQuaternion = function(quaternion, result) { - if (!defined(quaternion)) { - throw new DeveloperError('quaternion is required'); - } - if (!defined(result)) { - result = new HeadingPitchRoll(); - } - var test = 2 * (quaternion.w * quaternion.y - quaternion.z * quaternion.x); - var denominatorRoll = 1 - 2 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y); - var numeratorRoll = 2 * (quaternion.w * quaternion.x + quaternion.y * quaternion.z); - var denominatorHeading = 1 - 2 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z); - var numeratorHeading = 2 * (quaternion.w * quaternion.z + quaternion.x * quaternion.y); - result.heading = -Math.atan2(numeratorHeading, denominatorHeading); - result.roll = Math.atan2(numeratorRoll, denominatorRoll); - result.pitch = -Math.asin(test); - return result; - }; - - /** - * Returns a new HeadingPitchRoll instance from angles given in degrees. - * - * @param {Number} heading the heading in degrees - * @param {Number} pitch the pitch in degrees - * @param {Number} roll the heading in degrees - * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned. - * @returns {HeadingPitchRoll} A new HeadingPitchRoll instance - */ - HeadingPitchRoll.fromDegrees = function(heading, pitch, roll, result) { - if (!defined(heading)) { - throw new DeveloperError('heading is required'); - } - if (!defined(pitch)) { - throw new DeveloperError('pitch is required'); - } - if (!defined(roll)) { - throw new DeveloperError('roll is required'); - } - if (!defined(result)) { - result = new HeadingPitchRoll(); - } - result.heading = heading * CesiumMath.RADIANS_PER_DEGREE; - result.pitch = pitch * CesiumMath.RADIANS_PER_DEGREE; - result.roll = roll * CesiumMath.RADIANS_PER_DEGREE; - return result; - }; - - /** - * Duplicates a HeadingPitchRoll instance. - * - * @param {HeadingPitchRoll} headingPitchRoll The HeadingPitchRoll to duplicate. - * @param {HeadingPitchRoll} [result] The object onto which to store the result. - * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. (Returns undefined if headingPitchRoll is undefined) - */ - HeadingPitchRoll.clone = function(headingPitchRoll, result) { - if (!defined(headingPitchRoll)) { - return undefined; - } - if (!defined(result)) { - return new HeadingPitchRoll(headingPitchRoll.heading, headingPitchRoll.pitch, headingPitchRoll.roll); - } - result.heading = headingPitchRoll.heading; - result.pitch = headingPitchRoll.pitch; - result.roll = headingPitchRoll.roll; - return result; - }; - - /** - * Compares the provided HeadingPitchRolls componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll. - * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - HeadingPitchRoll.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.heading === right.heading) && - (left.pitch === right.pitch) && - (left.roll === right.roll)); - }; - - /** - * Compares the provided HeadingPitchRolls componentwise and returns - * <code>true</code> if they pass an absolute or relative tolerance test, - * <code>false</code> otherwise. - * - * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll. - * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. - */ - HeadingPitchRoll.equalsEpsilon = function(left, right, relativeEpsilon, absoluteEpsilon) { - return (left === right) || - (defined(left) && - defined(right) && - CesiumMath.equalsEpsilon(left.heading, right.heading, relativeEpsilon, absoluteEpsilon) && - CesiumMath.equalsEpsilon(left.pitch, right.pitch, relativeEpsilon, absoluteEpsilon) && - CesiumMath.equalsEpsilon(left.roll, right.roll, relativeEpsilon, absoluteEpsilon)); - }; - - /** - * Duplicates this HeadingPitchRoll instance. - * - * @param {HeadingPitchRoll} [result] The object onto which to store the result. - * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. - */ - HeadingPitchRoll.prototype.clone = function(result) { - return HeadingPitchRoll.clone(this, result); - }; - - /** - * Compares this HeadingPitchRoll against the provided HeadingPitchRoll componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - HeadingPitchRoll.prototype.equals = function(right) { - return HeadingPitchRoll.equals(this, right); - }; - - /** - * Compares this HeadingPitchRoll against the provided HeadingPitchRoll componentwise and returns - * <code>true</code> if they pass an absolute or relative tolerance test, - * <code>false</code> otherwise. - * - * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. - */ - HeadingPitchRoll.prototype.equalsEpsilon = function(right, relativeEpsilon, absoluteEpsilon) { - return HeadingPitchRoll.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); - }; - - /** - * Creates a string representing this HeadingPitchRoll in the format '(heading, pitch, roll)' in radians. - * - * @returns {String} A string representing the provided HeadingPitchRoll in the format '(heading, pitch, roll)'. - */ - HeadingPitchRoll.prototype.toString = function() { - return '(' + this.heading + ', ' + this.pitch + ', ' + this.roll + ')'; - }; - - return HeadingPitchRoll; -}); - -define('Core/HermitePolynomialApproximation',[ - './defaultValue', - './defined', - './DeveloperError', - './Math' - ], function( - defaultValue, - defined, - DeveloperError, - CesiumMath) { - 'use strict'; - - var factorial = CesiumMath.factorial; - - function calculateCoefficientTerm(x, zIndices, xTable, derivOrder, termOrder, reservedIndices) { - var result = 0; - var reserved; - var i; - var j; - - if (derivOrder > 0) { - for (i = 0; i < termOrder; i++) { - reserved = false; - for (j = 0; j < reservedIndices.length && !reserved; j++) { - if (i === reservedIndices[j]) { - reserved = true; + if (message.disableAuthentication !== undefined) + if (typeof message.disableAuthentication !== "boolean") + return "disableAuthentication: boolean expected"; + if (message.mfeDomains !== undefined) { + if (!Array.isArray(message.mfeDomains)) + return "mfeDomains: array expected"; + for (var i = 0; i < message.mfeDomains.length; ++i) { + var error = $types[3].verify(message.mfeDomains[i]); + if (error) + return "mfeDomains." + error; + } } - } - - if (!reserved) { - reservedIndices.push(i); - result += calculateCoefficientTerm(x, zIndices, xTable, derivOrder - 1, termOrder, reservedIndices); - reservedIndices.splice(reservedIndices.length - 1, 1); - } - } - - return result; - } - - result = 1; - for (i = 0; i < termOrder; i++) { - reserved = false; - for (j = 0; j < reservedIndices.length && !reserved; j++) { - if (i === reservedIndices[j]) { - reserved = true; - } - } - - if (!reserved) { - result *= x - xTable[zIndices[i]]; - } - } - - return result; - } - - /** - * An {@link InterpolationAlgorithm} for performing Hermite interpolation. - * - * @exports HermitePolynomialApproximation - */ - var HermitePolynomialApproximation = { - type : 'Hermite' - }; - - /** - * Given the desired degree, returns the number of data points required for interpolation. - * - * @param {Number} degree The desired degree of interpolation. - * @param {Number} [inputOrder=0] The order of the inputs (0 means just the data, 1 means the data and its derivative, etc). - * @returns {Number} The number of required data points needed for the desired degree of interpolation. - * @exception {DeveloperError} degree must be 0 or greater. - * @exception {DeveloperError} inputOrder must be 0 or greater. - */ - HermitePolynomialApproximation.getRequiredDataPoints = function(degree, inputOrder) { - inputOrder = defaultValue(inputOrder, 0); - - if (!defined(degree)) { - throw new DeveloperError('degree is required.'); - } - if (degree < 0) { - throw new DeveloperError('degree must be 0 or greater.'); - } - if (inputOrder < 0) { - throw new DeveloperError('inputOrder must be 0 or greater.'); - } - - return Math.max(Math.floor((degree + 1) / (inputOrder + 1)), 2); - }; - - /** - * Interpolates values using Hermite Polynomial Approximation. - * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values - * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three - * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to - * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. - */ - HermitePolynomialApproximation.interpolateOrderZero = function(x, xTable, yTable, yStride, result) { - if (!defined(result)) { - result = new Array(yStride); - } - - var i; - var j; - var d; - var s; - var len; - var index; - var length = xTable.length; - var coefficients = new Array(yStride); - - for (i = 0; i < yStride; i++) { - result[i] = 0; - - var l = new Array(length); - coefficients[i] = l; - for (j = 0; j < length; j++) { - l[j] = []; - } - } - - var zIndicesLength = length, zIndices = new Array(zIndicesLength); - - for (i = 0; i < zIndicesLength; i++) { - zIndices[i] = i; - } - - var highestNonZeroCoef = length - 1; - for (s = 0; s < yStride; s++) { - for (j = 0; j < zIndicesLength; j++) { - index = zIndices[j] * yStride + s; - coefficients[s][0].push(yTable[index]); - } - - for (i = 1; i < zIndicesLength; i++) { - var nonZeroCoefficients = false; - for (j = 0; j < zIndicesLength - i; j++) { - var zj = xTable[zIndices[j]]; - var zn = xTable[zIndices[j + i]]; - - var numerator; - if (zn - zj <= 0) { - index = zIndices[j] * yStride + yStride * i + s; - numerator = yTable[index]; - coefficients[s][i].push(numerator / factorial(i)); - } else { - numerator = (coefficients[s][i - 1][j + 1] - coefficients[s][i - 1][j]); - coefficients[s][i].push(numerator / (zn - zj)); + if (message.mfeLangParam !== undefined) + if (!$util.isString(message.mfeLangParam)) + return "mfeLangParam: string expected"; + if (message.adsUrlPatterns !== undefined) + if (!$util.isString(message.adsUrlPatterns)) + return "adsUrlPatterns: string expected"; + if (message.reverseGeocoderUrl !== undefined && message.reverseGeocoderUrl !== null) { + var error = $types[6].verify(message.reverseGeocoderUrl); + if (error) + return "reverseGeocoderUrl." + error; } - nonZeroCoefficients = nonZeroCoefficients || (numerator !== 0); - } - - if (!nonZeroCoefficients) { - highestNonZeroCoef = i - 1; - } - } - } - - for (d = 0, len = 0; d <= len; d++) { - for (i = d; i <= highestNonZeroCoef; i++) { - var tempTerm = calculateCoefficientTerm(x, zIndices, xTable, d, i, []); - for (s = 0; s < yStride; s++) { - var coeff = coefficients[s][i][0]; - result[s + d * yStride] += coeff * tempTerm; - } - } - } - - return result; - }; - - var arrayScratch = []; - - /** - * Interpolates values using Hermite Polynomial Approximation. - * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values - * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three - * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to - * each independent variable value in xTable. - * @param {Number} inputOrder The number of derivatives supplied for input. - * @param {Number} outputOrder The number of derivatives desired for output. - * @param {Number[]} [result] An existing array into which to store the result. - * - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. - */ - HermitePolynomialApproximation.interpolate = function(x, xTable, yTable, yStride, inputOrder, outputOrder, result) { - var resultLength = yStride * (outputOrder + 1); - if (!defined(result)) { - result = new Array(resultLength); - } - for (var r = 0; r < resultLength; r++) { - result[r] = 0; - } - - var length = xTable.length; - // The zIndices array holds copies of the addresses of the xTable values - // in the range we're looking at. Even though this just holds information already - // available in xTable this is a much more convenient format. - var zIndices = new Array(length * (inputOrder + 1)); - var i; - for (i = 0; i < length; i++) { - for (var j = 0; j < (inputOrder + 1); j++) { - zIndices[i * (inputOrder + 1) + j] = i; - } - } - - var zIndiceslength = zIndices.length; - var coefficients = arrayScratch; - var highestNonZeroCoef = fillCoefficientList(coefficients, zIndices, xTable, yTable, yStride, inputOrder); - var reservedIndices = []; - - var tmp = zIndiceslength * (zIndiceslength + 1) / 2; - var loopStop = Math.min(highestNonZeroCoef, outputOrder); - for (var d = 0; d <= loopStop; d++) { - for (i = d; i <= highestNonZeroCoef; i++) { - reservedIndices.length = 0; - var tempTerm = calculateCoefficientTerm(x, zIndices, xTable, d, i, reservedIndices); - var dimTwo = Math.floor(i * (1 - i) / 2) + (zIndiceslength * i); - - for (var s = 0; s < yStride; s++) { - var dimOne = Math.floor(s * tmp); - var coef = coefficients[dimOne + dimTwo]; - result[s + d * yStride] += coef * tempTerm; - } - } - } + if (message.reverseGeocoderProtocolVersion !== undefined) + if (!$util.isInteger(message.reverseGeocoderProtocolVersion)) + return "reverseGeocoderProtocolVersion: integer expected"; + if (message.skyDatabaseIsAvailable !== undefined) + if (typeof message.skyDatabaseIsAvailable !== "boolean") + return "skyDatabaseIsAvailable: boolean expected"; + if (message.skyDatabaseUrl !== undefined && message.skyDatabaseUrl !== null) { + var error = $types[9].verify(message.skyDatabaseUrl); + if (error) + return "skyDatabaseUrl." + error; + } + if (message.defaultWebPageIntlUrl !== undefined && message.defaultWebPageIntlUrl !== null) { + var error = $types[10].verify(message.defaultWebPageIntlUrl); + if (error) + return "defaultWebPageIntlUrl." + error; + } + if (message.numStartUpTips !== undefined) + if (!$util.isInteger(message.numStartUpTips)) + return "numStartUpTips: integer expected"; + if (message.startUpTipsUrl !== undefined && message.startUpTipsUrl !== null) { + var error = $types[12].verify(message.startUpTipsUrl); + if (error) + return "startUpTipsUrl." + error; + } + if (message.numProStartUpTips !== undefined) + if (!$util.isInteger(message.numProStartUpTips)) + return "numProStartUpTips: integer expected"; + if (message.proStartUpTipsUrl !== undefined && message.proStartUpTipsUrl !== null) { + var error = $types[14].verify(message.proStartUpTipsUrl); + if (error) + return "proStartUpTipsUrl." + error; + } + if (message.startupTipsIntlUrl !== undefined && message.startupTipsIntlUrl !== null) { + var error = $types[15].verify(message.startupTipsIntlUrl); + if (error) + return "startupTipsIntlUrl." + error; + } + if (message.userGuideIntlUrl !== undefined && message.userGuideIntlUrl !== null) { + var error = $types[16].verify(message.userGuideIntlUrl); + if (error) + return "userGuideIntlUrl." + error; + } + if (message.supportCenterIntlUrl !== undefined && message.supportCenterIntlUrl !== null) { + var error = $types[17].verify(message.supportCenterIntlUrl); + if (error) + return "supportCenterIntlUrl." + error; + } + if (message.businessListingIntlUrl !== undefined && message.businessListingIntlUrl !== null) { + var error = $types[18].verify(message.businessListingIntlUrl); + if (error) + return "businessListingIntlUrl." + error; + } + if (message.supportAnswerIntlUrl !== undefined && message.supportAnswerIntlUrl !== null) { + var error = $types[19].verify(message.supportAnswerIntlUrl); + if (error) + return "supportAnswerIntlUrl." + error; + } + if (message.supportTopicIntlUrl !== undefined && message.supportTopicIntlUrl !== null) { + var error = $types[20].verify(message.supportTopicIntlUrl); + if (error) + return "supportTopicIntlUrl." + error; + } + if (message.supportRequestIntlUrl !== undefined && message.supportRequestIntlUrl !== null) { + var error = $types[21].verify(message.supportRequestIntlUrl); + if (error) + return "supportRequestIntlUrl." + error; + } + if (message.earthIntlUrl !== undefined && message.earthIntlUrl !== null) { + var error = $types[22].verify(message.earthIntlUrl); + if (error) + return "earthIntlUrl." + error; + } + if (message.addContentUrl !== undefined && message.addContentUrl !== null) { + var error = $types[23].verify(message.addContentUrl); + if (error) + return "addContentUrl." + error; + } + if (message.sketchupNotInstalledUrl !== undefined && message.sketchupNotInstalledUrl !== null) { + var error = $types[24].verify(message.sketchupNotInstalledUrl); + if (error) + return "sketchupNotInstalledUrl." + error; + } + if (message.sketchupErrorUrl !== undefined && message.sketchupErrorUrl !== null) { + var error = $types[25].verify(message.sketchupErrorUrl); + if (error) + return "sketchupErrorUrl." + error; + } + if (message.freeLicenseUrl !== undefined && message.freeLicenseUrl !== null) { + var error = $types[26].verify(message.freeLicenseUrl); + if (error) + return "freeLicenseUrl." + error; + } + if (message.proLicenseUrl !== undefined && message.proLicenseUrl !== null) { + var error = $types[27].verify(message.proLicenseUrl); + if (error) + return "proLicenseUrl." + error; + } + if (message.tutorialUrl !== undefined && message.tutorialUrl !== null) { + var error = $types[28].verify(message.tutorialUrl); + if (error) + return "tutorialUrl." + error; + } + if (message.keyboardShortcutsUrl !== undefined && message.keyboardShortcutsUrl !== null) { + var error = $types[29].verify(message.keyboardShortcutsUrl); + if (error) + return "keyboardShortcutsUrl." + error; + } + if (message.releaseNotesUrl !== undefined && message.releaseNotesUrl !== null) { + var error = $types[30].verify(message.releaseNotesUrl); + if (error) + return "releaseNotesUrl." + error; + } + if (message.hideUserData !== undefined) + if (typeof message.hideUserData !== "boolean") + return "hideUserData: boolean expected"; + if (message.useGeLogo !== undefined) + if (typeof message.useGeLogo !== "boolean") + return "useGeLogo: boolean expected"; + if (message.dioramaDescriptionUrlBase !== undefined && message.dioramaDescriptionUrlBase !== null) { + var error = $types[33].verify(message.dioramaDescriptionUrlBase); + if (error) + return "dioramaDescriptionUrlBase." + error; + } + if (message.dioramaDefaultColor !== undefined) + if (!$util.isInteger(message.dioramaDefaultColor)) + return "dioramaDefaultColor: integer expected"; + if (message.dioramaBlacklistUrl !== undefined && message.dioramaBlacklistUrl !== null) { + var error = $types[35].verify(message.dioramaBlacklistUrl); + if (error) + return "dioramaBlacklistUrl." + error; + } + if (message.clientOptions !== undefined && message.clientOptions !== null) { + var error = $types[36].verify(message.clientOptions); + if (error) + return "clientOptions." + error; + } + if (message.fetchingOptions !== undefined && message.fetchingOptions !== null) { + var error = $types[37].verify(message.fetchingOptions); + if (error) + return "fetchingOptions." + error; + } + if (message.timeMachineOptions !== undefined && message.timeMachineOptions !== null) { + var error = $types[38].verify(message.timeMachineOptions); + if (error) + return "timeMachineOptions." + error; + } + if (message.csiOptions !== undefined && message.csiOptions !== null) { + var error = $types[39].verify(message.csiOptions); + if (error) + return "csiOptions." + error; + } + if (message.searchTab !== undefined) { + if (!Array.isArray(message.searchTab)) + return "searchTab: array expected"; + for (var i = 0; i < message.searchTab.length; ++i) { + var error = $types[40].verify(message.searchTab[i]); + if (error) + return "searchTab." + error; + } + } + if (message.cobrandInfo !== undefined) { + if (!Array.isArray(message.cobrandInfo)) + return "cobrandInfo: array expected"; + for (var i = 0; i < message.cobrandInfo.length; ++i) { + var error = $types[41].verify(message.cobrandInfo[i]); + if (error) + return "cobrandInfo." + error; + } + } + if (message.validDatabase !== undefined) { + if (!Array.isArray(message.validDatabase)) + return "validDatabase: array expected"; + for (var i = 0; i < message.validDatabase.length; ++i) { + var error = $types[42].verify(message.validDatabase[i]); + if (error) + return "validDatabase." + error; + } + } + if (message.configScript !== undefined) { + if (!Array.isArray(message.configScript)) + return "configScript: array expected"; + for (var i = 0; i < message.configScript.length; ++i) { + var error = $types[43].verify(message.configScript[i]); + if (error) + return "configScript." + error; + } + } + if (message.deauthServerUrl !== undefined && message.deauthServerUrl !== null) { + var error = $types[44].verify(message.deauthServerUrl); + if (error) + return "deauthServerUrl." + error; + } + if (message.swoopParameters !== undefined && message.swoopParameters !== null) { + var error = $types[45].verify(message.swoopParameters); + if (error) + return "swoopParameters." + error; + } + if (message.bbsServerInfo !== undefined && message.bbsServerInfo !== null) { + var error = $types[46].verify(message.bbsServerInfo); + if (error) + return "bbsServerInfo." + error; + } + if (message.dataErrorServerInfo !== undefined && message.dataErrorServerInfo !== null) { + var error = $types[47].verify(message.dataErrorServerInfo); + if (error) + return "dataErrorServerInfo." + error; + } + if (message.planetaryDatabase !== undefined) { + if (!Array.isArray(message.planetaryDatabase)) + return "planetaryDatabase: array expected"; + for (var i = 0; i < message.planetaryDatabase.length; ++i) { + var error = $types[48].verify(message.planetaryDatabase[i]); + if (error) + return "planetaryDatabase." + error; + } + } + if (message.logServer !== undefined && message.logServer !== null) { + var error = $types[49].verify(message.logServer); + if (error) + return "logServer." + error; + } + if (message.autopiaOptions !== undefined && message.autopiaOptions !== null) { + var error = $types[50].verify(message.autopiaOptions); + if (error) + return "autopiaOptions." + error; + } + if (message.searchConfig !== undefined && message.searchConfig !== null) { + var error = $types[51].verify(message.searchConfig); + if (error) + return "searchConfig." + error; + } + if (message.searchInfo !== undefined && message.searchInfo !== null) { + var error = $types[52].verify(message.searchInfo); + if (error) + return "searchInfo." + error; + } + if (message.elevationServiceBaseUrl !== undefined) + if (!$util.isString(message.elevationServiceBaseUrl)) + return "elevationServiceBaseUrl: string expected"; + if (message.elevationProfileQueryDelay !== undefined) + if (!$util.isInteger(message.elevationProfileQueryDelay)) + return "elevationProfileQueryDelay: integer expected"; + if (message.proUpgradeUrl !== undefined && message.proUpgradeUrl !== null) { + var error = $types[55].verify(message.proUpgradeUrl); + if (error) + return "proUpgradeUrl." + error; + } + if (message.earthCommunityUrl !== undefined && message.earthCommunityUrl !== null) { + var error = $types[56].verify(message.earthCommunityUrl); + if (error) + return "earthCommunityUrl." + error; + } + if (message.googleMapsUrl !== undefined && message.googleMapsUrl !== null) { + var error = $types[57].verify(message.googleMapsUrl); + if (error) + return "googleMapsUrl." + error; + } + if (message.sharingUrl !== undefined && message.sharingUrl !== null) { + var error = $types[58].verify(message.sharingUrl); + if (error) + return "sharingUrl." + error; + } + if (message.privacyPolicyUrl !== undefined && message.privacyPolicyUrl !== null) { + var error = $types[59].verify(message.privacyPolicyUrl); + if (error) + return "privacyPolicyUrl." + error; + } + if (message.doGplusUserCheck !== undefined) + if (typeof message.doGplusUserCheck !== "boolean") + return "doGplusUserCheck: boolean expected"; + if (message.rocktreeDataProto !== undefined && message.rocktreeDataProto !== null) { + var error = $types[61].verify(message.rocktreeDataProto); + if (error) + return "rocktreeDataProto." + error; + } + if (message.filmstripConfig !== undefined) { + if (!Array.isArray(message.filmstripConfig)) + return "filmstripConfig: array expected"; + for (var i = 0; i < message.filmstripConfig.length; ++i) { + var error = $types[62].verify(message.filmstripConfig[i]); + if (error) + return "filmstripConfig." + error; + } + } + if (message.showSigninButton !== undefined) + if (typeof message.showSigninButton !== "boolean") + return "showSigninButton: boolean expected"; + if (message.proMeasureUpsellUrl !== undefined && message.proMeasureUpsellUrl !== null) { + var error = $types[64].verify(message.proMeasureUpsellUrl); + if (error) + return "proMeasureUpsellUrl." + error; + } + if (message.proPrintUpsellUrl !== undefined && message.proPrintUpsellUrl !== null) { + var error = $types[65].verify(message.proPrintUpsellUrl); + if (error) + return "proPrintUpsellUrl." + error; + } + if (message.starDataProto !== undefined && message.starDataProto !== null) { + var error = $types[66].verify(message.starDataProto); + if (error) + return "starDataProto." + error; + } + if (message.feedbackUrl !== undefined && message.feedbackUrl !== null) { + var error = $types[67].verify(message.feedbackUrl); + if (error) + return "feedbackUrl." + error; + } + if (message.oauth2LoginUrl !== undefined && message.oauth2LoginUrl !== null) { + var error = $types[68].verify(message.oauth2LoginUrl); + if (error) + return "oauth2LoginUrl." + error; + } + return null; + }; - return result; - }; + EndSnippetProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto(); + if (object.model !== undefined && object.model !== null) { + if (typeof object.model !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.model: object expected"); + message.model = $types[0].fromObject(object.model); + } + if (object.authServerUrl !== undefined && object.authServerUrl !== null) { + if (typeof object.authServerUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.authServerUrl: object expected"); + message.authServerUrl = $types[1].fromObject(object.authServerUrl); + } + if (object.disableAuthentication !== undefined && object.disableAuthentication !== null) + message.disableAuthentication = Boolean(object.disableAuthentication); + if (object.mfeDomains) { + if (!Array.isArray(object.mfeDomains)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.mfeDomains: array expected"); + message.mfeDomains = []; + for (var i = 0; i < object.mfeDomains.length; ++i) { + if (typeof object.mfeDomains[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.mfeDomains: object expected"); + message.mfeDomains[i] = $types[3].fromObject(object.mfeDomains[i]); + } + } + if (object.mfeLangParam !== undefined && object.mfeLangParam !== null) + message.mfeLangParam = String(object.mfeLangParam); + if (object.adsUrlPatterns !== undefined && object.adsUrlPatterns !== null) + message.adsUrlPatterns = String(object.adsUrlPatterns); + if (object.reverseGeocoderUrl !== undefined && object.reverseGeocoderUrl !== null) { + if (typeof object.reverseGeocoderUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.reverseGeocoderUrl: object expected"); + message.reverseGeocoderUrl = $types[6].fromObject(object.reverseGeocoderUrl); + } + if (object.reverseGeocoderProtocolVersion !== undefined && object.reverseGeocoderProtocolVersion !== null) + message.reverseGeocoderProtocolVersion = object.reverseGeocoderProtocolVersion | 0; + if (object.skyDatabaseIsAvailable !== undefined && object.skyDatabaseIsAvailable !== null) + message.skyDatabaseIsAvailable = Boolean(object.skyDatabaseIsAvailable); + if (object.skyDatabaseUrl !== undefined && object.skyDatabaseUrl !== null) { + if (typeof object.skyDatabaseUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.skyDatabaseUrl: object expected"); + message.skyDatabaseUrl = $types[9].fromObject(object.skyDatabaseUrl); + } + if (object.defaultWebPageIntlUrl !== undefined && object.defaultWebPageIntlUrl !== null) { + if (typeof object.defaultWebPageIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.defaultWebPageIntlUrl: object expected"); + message.defaultWebPageIntlUrl = $types[10].fromObject(object.defaultWebPageIntlUrl); + } + if (object.numStartUpTips !== undefined && object.numStartUpTips !== null) + message.numStartUpTips = object.numStartUpTips | 0; + if (object.startUpTipsUrl !== undefined && object.startUpTipsUrl !== null) { + if (typeof object.startUpTipsUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.startUpTipsUrl: object expected"); + message.startUpTipsUrl = $types[12].fromObject(object.startUpTipsUrl); + } + if (object.numProStartUpTips !== undefined && object.numProStartUpTips !== null) + message.numProStartUpTips = object.numProStartUpTips | 0; + if (object.proStartUpTipsUrl !== undefined && object.proStartUpTipsUrl !== null) { + if (typeof object.proStartUpTipsUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.proStartUpTipsUrl: object expected"); + message.proStartUpTipsUrl = $types[14].fromObject(object.proStartUpTipsUrl); + } + if (object.startupTipsIntlUrl !== undefined && object.startupTipsIntlUrl !== null) { + if (typeof object.startupTipsIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.startupTipsIntlUrl: object expected"); + message.startupTipsIntlUrl = $types[15].fromObject(object.startupTipsIntlUrl); + } + if (object.userGuideIntlUrl !== undefined && object.userGuideIntlUrl !== null) { + if (typeof object.userGuideIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.userGuideIntlUrl: object expected"); + message.userGuideIntlUrl = $types[16].fromObject(object.userGuideIntlUrl); + } + if (object.supportCenterIntlUrl !== undefined && object.supportCenterIntlUrl !== null) { + if (typeof object.supportCenterIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.supportCenterIntlUrl: object expected"); + message.supportCenterIntlUrl = $types[17].fromObject(object.supportCenterIntlUrl); + } + if (object.businessListingIntlUrl !== undefined && object.businessListingIntlUrl !== null) { + if (typeof object.businessListingIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.businessListingIntlUrl: object expected"); + message.businessListingIntlUrl = $types[18].fromObject(object.businessListingIntlUrl); + } + if (object.supportAnswerIntlUrl !== undefined && object.supportAnswerIntlUrl !== null) { + if (typeof object.supportAnswerIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.supportAnswerIntlUrl: object expected"); + message.supportAnswerIntlUrl = $types[19].fromObject(object.supportAnswerIntlUrl); + } + if (object.supportTopicIntlUrl !== undefined && object.supportTopicIntlUrl !== null) { + if (typeof object.supportTopicIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.supportTopicIntlUrl: object expected"); + message.supportTopicIntlUrl = $types[20].fromObject(object.supportTopicIntlUrl); + } + if (object.supportRequestIntlUrl !== undefined && object.supportRequestIntlUrl !== null) { + if (typeof object.supportRequestIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.supportRequestIntlUrl: object expected"); + message.supportRequestIntlUrl = $types[21].fromObject(object.supportRequestIntlUrl); + } + if (object.earthIntlUrl !== undefined && object.earthIntlUrl !== null) { + if (typeof object.earthIntlUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.earthIntlUrl: object expected"); + message.earthIntlUrl = $types[22].fromObject(object.earthIntlUrl); + } + if (object.addContentUrl !== undefined && object.addContentUrl !== null) { + if (typeof object.addContentUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.addContentUrl: object expected"); + message.addContentUrl = $types[23].fromObject(object.addContentUrl); + } + if (object.sketchupNotInstalledUrl !== undefined && object.sketchupNotInstalledUrl !== null) { + if (typeof object.sketchupNotInstalledUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.sketchupNotInstalledUrl: object expected"); + message.sketchupNotInstalledUrl = $types[24].fromObject(object.sketchupNotInstalledUrl); + } + if (object.sketchupErrorUrl !== undefined && object.sketchupErrorUrl !== null) { + if (typeof object.sketchupErrorUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.sketchupErrorUrl: object expected"); + message.sketchupErrorUrl = $types[25].fromObject(object.sketchupErrorUrl); + } + if (object.freeLicenseUrl !== undefined && object.freeLicenseUrl !== null) { + if (typeof object.freeLicenseUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.freeLicenseUrl: object expected"); + message.freeLicenseUrl = $types[26].fromObject(object.freeLicenseUrl); + } + if (object.proLicenseUrl !== undefined && object.proLicenseUrl !== null) { + if (typeof object.proLicenseUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.proLicenseUrl: object expected"); + message.proLicenseUrl = $types[27].fromObject(object.proLicenseUrl); + } + if (object.tutorialUrl !== undefined && object.tutorialUrl !== null) { + if (typeof object.tutorialUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.tutorialUrl: object expected"); + message.tutorialUrl = $types[28].fromObject(object.tutorialUrl); + } + if (object.keyboardShortcutsUrl !== undefined && object.keyboardShortcutsUrl !== null) { + if (typeof object.keyboardShortcutsUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.keyboardShortcutsUrl: object expected"); + message.keyboardShortcutsUrl = $types[29].fromObject(object.keyboardShortcutsUrl); + } + if (object.releaseNotesUrl !== undefined && object.releaseNotesUrl !== null) { + if (typeof object.releaseNotesUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.releaseNotesUrl: object expected"); + message.releaseNotesUrl = $types[30].fromObject(object.releaseNotesUrl); + } + if (object.hideUserData !== undefined && object.hideUserData !== null) + message.hideUserData = Boolean(object.hideUserData); + if (object.useGeLogo !== undefined && object.useGeLogo !== null) + message.useGeLogo = Boolean(object.useGeLogo); + if (object.dioramaDescriptionUrlBase !== undefined && object.dioramaDescriptionUrlBase !== null) { + if (typeof object.dioramaDescriptionUrlBase !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaDescriptionUrlBase: object expected"); + message.dioramaDescriptionUrlBase = $types[33].fromObject(object.dioramaDescriptionUrlBase); + } + if (object.dioramaDefaultColor !== undefined && object.dioramaDefaultColor !== null) + message.dioramaDefaultColor = object.dioramaDefaultColor >>> 0; + if (object.dioramaBlacklistUrl !== undefined && object.dioramaBlacklistUrl !== null) { + if (typeof object.dioramaBlacklistUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.dioramaBlacklistUrl: object expected"); + message.dioramaBlacklistUrl = $types[35].fromObject(object.dioramaBlacklistUrl); + } + if (object.clientOptions !== undefined && object.clientOptions !== null) { + if (typeof object.clientOptions !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.clientOptions: object expected"); + message.clientOptions = $types[36].fromObject(object.clientOptions); + } + if (object.fetchingOptions !== undefined && object.fetchingOptions !== null) { + if (typeof object.fetchingOptions !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.fetchingOptions: object expected"); + message.fetchingOptions = $types[37].fromObject(object.fetchingOptions); + } + if (object.timeMachineOptions !== undefined && object.timeMachineOptions !== null) { + if (typeof object.timeMachineOptions !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.timeMachineOptions: object expected"); + message.timeMachineOptions = $types[38].fromObject(object.timeMachineOptions); + } + if (object.csiOptions !== undefined && object.csiOptions !== null) { + if (typeof object.csiOptions !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.csiOptions: object expected"); + message.csiOptions = $types[39].fromObject(object.csiOptions); + } + if (object.searchTab) { + if (!Array.isArray(object.searchTab)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: array expected"); + message.searchTab = []; + for (var i = 0; i < object.searchTab.length; ++i) { + if (typeof object.searchTab[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.searchTab: object expected"); + message.searchTab[i] = $types[40].fromObject(object.searchTab[i]); + } + } + if (object.cobrandInfo) { + if (!Array.isArray(object.cobrandInfo)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.cobrandInfo: array expected"); + message.cobrandInfo = []; + for (var i = 0; i < object.cobrandInfo.length; ++i) { + if (typeof object.cobrandInfo[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.cobrandInfo: object expected"); + message.cobrandInfo[i] = $types[41].fromObject(object.cobrandInfo[i]); + } + } + if (object.validDatabase) { + if (!Array.isArray(object.validDatabase)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.validDatabase: array expected"); + message.validDatabase = []; + for (var i = 0; i < object.validDatabase.length; ++i) { + if (typeof object.validDatabase[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.validDatabase: object expected"); + message.validDatabase[i] = $types[42].fromObject(object.validDatabase[i]); + } + } + if (object.configScript) { + if (!Array.isArray(object.configScript)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.configScript: array expected"); + message.configScript = []; + for (var i = 0; i < object.configScript.length; ++i) { + if (typeof object.configScript[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.configScript: object expected"); + message.configScript[i] = $types[43].fromObject(object.configScript[i]); + } + } + if (object.deauthServerUrl !== undefined && object.deauthServerUrl !== null) { + if (typeof object.deauthServerUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.deauthServerUrl: object expected"); + message.deauthServerUrl = $types[44].fromObject(object.deauthServerUrl); + } + if (object.swoopParameters !== undefined && object.swoopParameters !== null) { + if (typeof object.swoopParameters !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.swoopParameters: object expected"); + message.swoopParameters = $types[45].fromObject(object.swoopParameters); + } + if (object.bbsServerInfo !== undefined && object.bbsServerInfo !== null) { + if (typeof object.bbsServerInfo !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.bbsServerInfo: object expected"); + message.bbsServerInfo = $types[46].fromObject(object.bbsServerInfo); + } + if (object.dataErrorServerInfo !== undefined && object.dataErrorServerInfo !== null) { + if (typeof object.dataErrorServerInfo !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.dataErrorServerInfo: object expected"); + message.dataErrorServerInfo = $types[47].fromObject(object.dataErrorServerInfo); + } + if (object.planetaryDatabase) { + if (!Array.isArray(object.planetaryDatabase)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.planetaryDatabase: array expected"); + message.planetaryDatabase = []; + for (var i = 0; i < object.planetaryDatabase.length; ++i) { + if (typeof object.planetaryDatabase[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.planetaryDatabase: object expected"); + message.planetaryDatabase[i] = $types[48].fromObject(object.planetaryDatabase[i]); + } + } + if (object.logServer !== undefined && object.logServer !== null) { + if (typeof object.logServer !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.logServer: object expected"); + message.logServer = $types[49].fromObject(object.logServer); + } + if (object.autopiaOptions !== undefined && object.autopiaOptions !== null) { + if (typeof object.autopiaOptions !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.autopiaOptions: object expected"); + message.autopiaOptions = $types[50].fromObject(object.autopiaOptions); + } + if (object.searchConfig !== undefined && object.searchConfig !== null) { + if (typeof object.searchConfig !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.searchConfig: object expected"); + message.searchConfig = $types[51].fromObject(object.searchConfig); + } + if (object.searchInfo !== undefined && object.searchInfo !== null) { + if (typeof object.searchInfo !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.searchInfo: object expected"); + message.searchInfo = $types[52].fromObject(object.searchInfo); + } + if (object.elevationServiceBaseUrl !== undefined && object.elevationServiceBaseUrl !== null) + message.elevationServiceBaseUrl = String(object.elevationServiceBaseUrl); + if (object.elevationProfileQueryDelay !== undefined && object.elevationProfileQueryDelay !== null) + message.elevationProfileQueryDelay = object.elevationProfileQueryDelay | 0; + if (object.proUpgradeUrl !== undefined && object.proUpgradeUrl !== null) { + if (typeof object.proUpgradeUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.proUpgradeUrl: object expected"); + message.proUpgradeUrl = $types[55].fromObject(object.proUpgradeUrl); + } + if (object.earthCommunityUrl !== undefined && object.earthCommunityUrl !== null) { + if (typeof object.earthCommunityUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.earthCommunityUrl: object expected"); + message.earthCommunityUrl = $types[56].fromObject(object.earthCommunityUrl); + } + if (object.googleMapsUrl !== undefined && object.googleMapsUrl !== null) { + if (typeof object.googleMapsUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.googleMapsUrl: object expected"); + message.googleMapsUrl = $types[57].fromObject(object.googleMapsUrl); + } + if (object.sharingUrl !== undefined && object.sharingUrl !== null) { + if (typeof object.sharingUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.sharingUrl: object expected"); + message.sharingUrl = $types[58].fromObject(object.sharingUrl); + } + if (object.privacyPolicyUrl !== undefined && object.privacyPolicyUrl !== null) { + if (typeof object.privacyPolicyUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.privacyPolicyUrl: object expected"); + message.privacyPolicyUrl = $types[59].fromObject(object.privacyPolicyUrl); + } + if (object.doGplusUserCheck !== undefined && object.doGplusUserCheck !== null) + message.doGplusUserCheck = Boolean(object.doGplusUserCheck); + if (object.rocktreeDataProto !== undefined && object.rocktreeDataProto !== null) { + if (typeof object.rocktreeDataProto !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.rocktreeDataProto: object expected"); + message.rocktreeDataProto = $types[61].fromObject(object.rocktreeDataProto); + } + if (object.filmstripConfig) { + if (!Array.isArray(object.filmstripConfig)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.filmstripConfig: array expected"); + message.filmstripConfig = []; + for (var i = 0; i < object.filmstripConfig.length; ++i) { + if (typeof object.filmstripConfig[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.filmstripConfig: object expected"); + message.filmstripConfig[i] = $types[62].fromObject(object.filmstripConfig[i]); + } + } + if (object.showSigninButton !== undefined && object.showSigninButton !== null) + message.showSigninButton = Boolean(object.showSigninButton); + if (object.proMeasureUpsellUrl !== undefined && object.proMeasureUpsellUrl !== null) { + if (typeof object.proMeasureUpsellUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.proMeasureUpsellUrl: object expected"); + message.proMeasureUpsellUrl = $types[64].fromObject(object.proMeasureUpsellUrl); + } + if (object.proPrintUpsellUrl !== undefined && object.proPrintUpsellUrl !== null) { + if (typeof object.proPrintUpsellUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.proPrintUpsellUrl: object expected"); + message.proPrintUpsellUrl = $types[65].fromObject(object.proPrintUpsellUrl); + } + if (object.starDataProto !== undefined && object.starDataProto !== null) { + if (typeof object.starDataProto !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.starDataProto: object expected"); + message.starDataProto = $types[66].fromObject(object.starDataProto); + } + if (object.feedbackUrl !== undefined && object.feedbackUrl !== null) { + if (typeof object.feedbackUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.feedbackUrl: object expected"); + message.feedbackUrl = $types[67].fromObject(object.feedbackUrl); + } + if (object.oauth2LoginUrl !== undefined && object.oauth2LoginUrl !== null) { + if (typeof object.oauth2LoginUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.oauth2LoginUrl: object expected"); + message.oauth2LoginUrl = $types[68].fromObject(object.oauth2LoginUrl); + } + return message; + }; - function fillCoefficientList(coefficients, zIndices, xTable, yTable, yStride, inputOrder) { - var j; - var index; - var highestNonZero = -1; - var zIndiceslength = zIndices.length; - var tmp = zIndiceslength * (zIndiceslength + 1) / 2; + EndSnippetProto.from = EndSnippetProto.fromObject; - for (var s = 0; s < yStride; s++) { - var dimOne = Math.floor(s * tmp); + EndSnippetProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.mfeDomains = []; + object.searchTab = []; + object.cobrandInfo = []; + object.validDatabase = []; + object.configScript = []; + object.planetaryDatabase = []; + object.filmstripConfig = []; + } + if (options.defaults) { + object.model = null; + object.authServerUrl = null; + object.disableAuthentication = false; + object.mfeLangParam = "hl=$5Bhl5D"; + object.adsUrlPatterns = ""; + object.reverseGeocoderUrl = null; + object.reverseGeocoderProtocolVersion = 3; + object.skyDatabaseIsAvailable = true; + object.skyDatabaseUrl = null; + object.defaultWebPageIntlUrl = null; + object.numStartUpTips = 17; + object.startUpTipsUrl = null; + object.numProStartUpTips = 0; + object.proStartUpTipsUrl = null; + object.startupTipsIntlUrl = null; + object.userGuideIntlUrl = null; + object.supportCenterIntlUrl = null; + object.businessListingIntlUrl = null; + object.supportAnswerIntlUrl = null; + object.supportTopicIntlUrl = null; + object.supportRequestIntlUrl = null; + object.earthIntlUrl = null; + object.addContentUrl = null; + object.sketchupNotInstalledUrl = null; + object.sketchupErrorUrl = null; + object.freeLicenseUrl = null; + object.proLicenseUrl = null; + object.tutorialUrl = null; + object.keyboardShortcutsUrl = null; + object.releaseNotesUrl = null; + object.hideUserData = false; + object.useGeLogo = true; + object.dioramaDescriptionUrlBase = null; + object.dioramaDefaultColor = 4291281607; + object.dioramaBlacklistUrl = null; + object.clientOptions = null; + object.fetchingOptions = null; + object.timeMachineOptions = null; + object.csiOptions = null; + object.deauthServerUrl = null; + object.swoopParameters = null; + object.bbsServerInfo = null; + object.dataErrorServerInfo = null; + object.logServer = null; + object.autopiaOptions = null; + object.searchConfig = null; + object.searchInfo = null; + object.elevationServiceBaseUrl = "http://maps.google.com/maps/api/elevation/"; + object.elevationProfileQueryDelay = 500; + object.proUpgradeUrl = null; + object.earthCommunityUrl = null; + object.googleMapsUrl = null; + object.sharingUrl = null; + object.privacyPolicyUrl = null; + object.doGplusUserCheck = false; + object.rocktreeDataProto = null; + object.showSigninButton = false; + object.proMeasureUpsellUrl = null; + object.proPrintUpsellUrl = null; + object.starDataProto = null; + object.feedbackUrl = null; + object.oauth2LoginUrl = null; + } + if (message.model !== undefined && message.model !== null && message.hasOwnProperty("model")) + object.model = $types[0].toObject(message.model, options); + if (message.authServerUrl !== undefined && message.authServerUrl !== null && message.hasOwnProperty("authServerUrl")) + object.authServerUrl = $types[1].toObject(message.authServerUrl, options); + if (message.disableAuthentication !== undefined && message.disableAuthentication !== null && message.hasOwnProperty("disableAuthentication")) + object.disableAuthentication = message.disableAuthentication; + if (message.mfeDomains !== undefined && message.mfeDomains !== null && message.hasOwnProperty("mfeDomains")) { + object.mfeDomains = []; + for (var j = 0; j < message.mfeDomains.length; ++j) + object.mfeDomains[j] = $types[3].toObject(message.mfeDomains[j], options); + } + if (message.mfeLangParam !== undefined && message.mfeLangParam !== null && message.hasOwnProperty("mfeLangParam")) + object.mfeLangParam = message.mfeLangParam; + if (message.adsUrlPatterns !== undefined && message.adsUrlPatterns !== null && message.hasOwnProperty("adsUrlPatterns")) + object.adsUrlPatterns = message.adsUrlPatterns; + if (message.reverseGeocoderUrl !== undefined && message.reverseGeocoderUrl !== null && message.hasOwnProperty("reverseGeocoderUrl")) + object.reverseGeocoderUrl = $types[6].toObject(message.reverseGeocoderUrl, options); + if (message.reverseGeocoderProtocolVersion !== undefined && message.reverseGeocoderProtocolVersion !== null && message.hasOwnProperty("reverseGeocoderProtocolVersion")) + object.reverseGeocoderProtocolVersion = message.reverseGeocoderProtocolVersion; + if (message.skyDatabaseIsAvailable !== undefined && message.skyDatabaseIsAvailable !== null && message.hasOwnProperty("skyDatabaseIsAvailable")) + object.skyDatabaseIsAvailable = message.skyDatabaseIsAvailable; + if (message.skyDatabaseUrl !== undefined && message.skyDatabaseUrl !== null && message.hasOwnProperty("skyDatabaseUrl")) + object.skyDatabaseUrl = $types[9].toObject(message.skyDatabaseUrl, options); + if (message.defaultWebPageIntlUrl !== undefined && message.defaultWebPageIntlUrl !== null && message.hasOwnProperty("defaultWebPageIntlUrl")) + object.defaultWebPageIntlUrl = $types[10].toObject(message.defaultWebPageIntlUrl, options); + if (message.numStartUpTips !== undefined && message.numStartUpTips !== null && message.hasOwnProperty("numStartUpTips")) + object.numStartUpTips = message.numStartUpTips; + if (message.startUpTipsUrl !== undefined && message.startUpTipsUrl !== null && message.hasOwnProperty("startUpTipsUrl")) + object.startUpTipsUrl = $types[12].toObject(message.startUpTipsUrl, options); + if (message.numProStartUpTips !== undefined && message.numProStartUpTips !== null && message.hasOwnProperty("numProStartUpTips")) + object.numProStartUpTips = message.numProStartUpTips; + if (message.proStartUpTipsUrl !== undefined && message.proStartUpTipsUrl !== null && message.hasOwnProperty("proStartUpTipsUrl")) + object.proStartUpTipsUrl = $types[14].toObject(message.proStartUpTipsUrl, options); + if (message.startupTipsIntlUrl !== undefined && message.startupTipsIntlUrl !== null && message.hasOwnProperty("startupTipsIntlUrl")) + object.startupTipsIntlUrl = $types[15].toObject(message.startupTipsIntlUrl, options); + if (message.userGuideIntlUrl !== undefined && message.userGuideIntlUrl !== null && message.hasOwnProperty("userGuideIntlUrl")) + object.userGuideIntlUrl = $types[16].toObject(message.userGuideIntlUrl, options); + if (message.supportCenterIntlUrl !== undefined && message.supportCenterIntlUrl !== null && message.hasOwnProperty("supportCenterIntlUrl")) + object.supportCenterIntlUrl = $types[17].toObject(message.supportCenterIntlUrl, options); + if (message.businessListingIntlUrl !== undefined && message.businessListingIntlUrl !== null && message.hasOwnProperty("businessListingIntlUrl")) + object.businessListingIntlUrl = $types[18].toObject(message.businessListingIntlUrl, options); + if (message.supportAnswerIntlUrl !== undefined && message.supportAnswerIntlUrl !== null && message.hasOwnProperty("supportAnswerIntlUrl")) + object.supportAnswerIntlUrl = $types[19].toObject(message.supportAnswerIntlUrl, options); + if (message.supportTopicIntlUrl !== undefined && message.supportTopicIntlUrl !== null && message.hasOwnProperty("supportTopicIntlUrl")) + object.supportTopicIntlUrl = $types[20].toObject(message.supportTopicIntlUrl, options); + if (message.supportRequestIntlUrl !== undefined && message.supportRequestIntlUrl !== null && message.hasOwnProperty("supportRequestIntlUrl")) + object.supportRequestIntlUrl = $types[21].toObject(message.supportRequestIntlUrl, options); + if (message.earthIntlUrl !== undefined && message.earthIntlUrl !== null && message.hasOwnProperty("earthIntlUrl")) + object.earthIntlUrl = $types[22].toObject(message.earthIntlUrl, options); + if (message.addContentUrl !== undefined && message.addContentUrl !== null && message.hasOwnProperty("addContentUrl")) + object.addContentUrl = $types[23].toObject(message.addContentUrl, options); + if (message.sketchupNotInstalledUrl !== undefined && message.sketchupNotInstalledUrl !== null && message.hasOwnProperty("sketchupNotInstalledUrl")) + object.sketchupNotInstalledUrl = $types[24].toObject(message.sketchupNotInstalledUrl, options); + if (message.sketchupErrorUrl !== undefined && message.sketchupErrorUrl !== null && message.hasOwnProperty("sketchupErrorUrl")) + object.sketchupErrorUrl = $types[25].toObject(message.sketchupErrorUrl, options); + if (message.freeLicenseUrl !== undefined && message.freeLicenseUrl !== null && message.hasOwnProperty("freeLicenseUrl")) + object.freeLicenseUrl = $types[26].toObject(message.freeLicenseUrl, options); + if (message.proLicenseUrl !== undefined && message.proLicenseUrl !== null && message.hasOwnProperty("proLicenseUrl")) + object.proLicenseUrl = $types[27].toObject(message.proLicenseUrl, options); + if (message.tutorialUrl !== undefined && message.tutorialUrl !== null && message.hasOwnProperty("tutorialUrl")) + object.tutorialUrl = $types[28].toObject(message.tutorialUrl, options); + if (message.keyboardShortcutsUrl !== undefined && message.keyboardShortcutsUrl !== null && message.hasOwnProperty("keyboardShortcutsUrl")) + object.keyboardShortcutsUrl = $types[29].toObject(message.keyboardShortcutsUrl, options); + if (message.releaseNotesUrl !== undefined && message.releaseNotesUrl !== null && message.hasOwnProperty("releaseNotesUrl")) + object.releaseNotesUrl = $types[30].toObject(message.releaseNotesUrl, options); + if (message.hideUserData !== undefined && message.hideUserData !== null && message.hasOwnProperty("hideUserData")) + object.hideUserData = message.hideUserData; + if (message.useGeLogo !== undefined && message.useGeLogo !== null && message.hasOwnProperty("useGeLogo")) + object.useGeLogo = message.useGeLogo; + if (message.dioramaDescriptionUrlBase !== undefined && message.dioramaDescriptionUrlBase !== null && message.hasOwnProperty("dioramaDescriptionUrlBase")) + object.dioramaDescriptionUrlBase = $types[33].toObject(message.dioramaDescriptionUrlBase, options); + if (message.dioramaDefaultColor !== undefined && message.dioramaDefaultColor !== null && message.hasOwnProperty("dioramaDefaultColor")) + object.dioramaDefaultColor = message.dioramaDefaultColor; + if (message.dioramaBlacklistUrl !== undefined && message.dioramaBlacklistUrl !== null && message.hasOwnProperty("dioramaBlacklistUrl")) + object.dioramaBlacklistUrl = $types[35].toObject(message.dioramaBlacklistUrl, options); + if (message.clientOptions !== undefined && message.clientOptions !== null && message.hasOwnProperty("clientOptions")) + object.clientOptions = $types[36].toObject(message.clientOptions, options); + if (message.fetchingOptions !== undefined && message.fetchingOptions !== null && message.hasOwnProperty("fetchingOptions")) + object.fetchingOptions = $types[37].toObject(message.fetchingOptions, options); + if (message.timeMachineOptions !== undefined && message.timeMachineOptions !== null && message.hasOwnProperty("timeMachineOptions")) + object.timeMachineOptions = $types[38].toObject(message.timeMachineOptions, options); + if (message.csiOptions !== undefined && message.csiOptions !== null && message.hasOwnProperty("csiOptions")) + object.csiOptions = $types[39].toObject(message.csiOptions, options); + if (message.searchTab !== undefined && message.searchTab !== null && message.hasOwnProperty("searchTab")) { + object.searchTab = []; + for (var j = 0; j < message.searchTab.length; ++j) + object.searchTab[j] = $types[40].toObject(message.searchTab[j], options); + } + if (message.cobrandInfo !== undefined && message.cobrandInfo !== null && message.hasOwnProperty("cobrandInfo")) { + object.cobrandInfo = []; + for (var j = 0; j < message.cobrandInfo.length; ++j) + object.cobrandInfo[j] = $types[41].toObject(message.cobrandInfo[j], options); + } + if (message.validDatabase !== undefined && message.validDatabase !== null && message.hasOwnProperty("validDatabase")) { + object.validDatabase = []; + for (var j = 0; j < message.validDatabase.length; ++j) + object.validDatabase[j] = $types[42].toObject(message.validDatabase[j], options); + } + if (message.configScript !== undefined && message.configScript !== null && message.hasOwnProperty("configScript")) { + object.configScript = []; + for (var j = 0; j < message.configScript.length; ++j) + object.configScript[j] = $types[43].toObject(message.configScript[j], options); + } + if (message.deauthServerUrl !== undefined && message.deauthServerUrl !== null && message.hasOwnProperty("deauthServerUrl")) + object.deauthServerUrl = $types[44].toObject(message.deauthServerUrl, options); + if (message.swoopParameters !== undefined && message.swoopParameters !== null && message.hasOwnProperty("swoopParameters")) + object.swoopParameters = $types[45].toObject(message.swoopParameters, options); + if (message.bbsServerInfo !== undefined && message.bbsServerInfo !== null && message.hasOwnProperty("bbsServerInfo")) + object.bbsServerInfo = $types[46].toObject(message.bbsServerInfo, options); + if (message.dataErrorServerInfo !== undefined && message.dataErrorServerInfo !== null && message.hasOwnProperty("dataErrorServerInfo")) + object.dataErrorServerInfo = $types[47].toObject(message.dataErrorServerInfo, options); + if (message.planetaryDatabase !== undefined && message.planetaryDatabase !== null && message.hasOwnProperty("planetaryDatabase")) { + object.planetaryDatabase = []; + for (var j = 0; j < message.planetaryDatabase.length; ++j) + object.planetaryDatabase[j] = $types[48].toObject(message.planetaryDatabase[j], options); + } + if (message.logServer !== undefined && message.logServer !== null && message.hasOwnProperty("logServer")) + object.logServer = $types[49].toObject(message.logServer, options); + if (message.autopiaOptions !== undefined && message.autopiaOptions !== null && message.hasOwnProperty("autopiaOptions")) + object.autopiaOptions = $types[50].toObject(message.autopiaOptions, options); + if (message.searchConfig !== undefined && message.searchConfig !== null && message.hasOwnProperty("searchConfig")) + object.searchConfig = $types[51].toObject(message.searchConfig, options); + if (message.searchInfo !== undefined && message.searchInfo !== null && message.hasOwnProperty("searchInfo")) + object.searchInfo = $types[52].toObject(message.searchInfo, options); + if (message.elevationServiceBaseUrl !== undefined && message.elevationServiceBaseUrl !== null && message.hasOwnProperty("elevationServiceBaseUrl")) + object.elevationServiceBaseUrl = message.elevationServiceBaseUrl; + if (message.elevationProfileQueryDelay !== undefined && message.elevationProfileQueryDelay !== null && message.hasOwnProperty("elevationProfileQueryDelay")) + object.elevationProfileQueryDelay = message.elevationProfileQueryDelay; + if (message.proUpgradeUrl !== undefined && message.proUpgradeUrl !== null && message.hasOwnProperty("proUpgradeUrl")) + object.proUpgradeUrl = $types[55].toObject(message.proUpgradeUrl, options); + if (message.earthCommunityUrl !== undefined && message.earthCommunityUrl !== null && message.hasOwnProperty("earthCommunityUrl")) + object.earthCommunityUrl = $types[56].toObject(message.earthCommunityUrl, options); + if (message.googleMapsUrl !== undefined && message.googleMapsUrl !== null && message.hasOwnProperty("googleMapsUrl")) + object.googleMapsUrl = $types[57].toObject(message.googleMapsUrl, options); + if (message.sharingUrl !== undefined && message.sharingUrl !== null && message.hasOwnProperty("sharingUrl")) + object.sharingUrl = $types[58].toObject(message.sharingUrl, options); + if (message.privacyPolicyUrl !== undefined && message.privacyPolicyUrl !== null && message.hasOwnProperty("privacyPolicyUrl")) + object.privacyPolicyUrl = $types[59].toObject(message.privacyPolicyUrl, options); + if (message.doGplusUserCheck !== undefined && message.doGplusUserCheck !== null && message.hasOwnProperty("doGplusUserCheck")) + object.doGplusUserCheck = message.doGplusUserCheck; + if (message.rocktreeDataProto !== undefined && message.rocktreeDataProto !== null && message.hasOwnProperty("rocktreeDataProto")) + object.rocktreeDataProto = $types[61].toObject(message.rocktreeDataProto, options); + if (message.filmstripConfig !== undefined && message.filmstripConfig !== null && message.hasOwnProperty("filmstripConfig")) { + object.filmstripConfig = []; + for (var j = 0; j < message.filmstripConfig.length; ++j) + object.filmstripConfig[j] = $types[62].toObject(message.filmstripConfig[j], options); + } + if (message.showSigninButton !== undefined && message.showSigninButton !== null && message.hasOwnProperty("showSigninButton")) + object.showSigninButton = message.showSigninButton; + if (message.proMeasureUpsellUrl !== undefined && message.proMeasureUpsellUrl !== null && message.hasOwnProperty("proMeasureUpsellUrl")) + object.proMeasureUpsellUrl = $types[64].toObject(message.proMeasureUpsellUrl, options); + if (message.proPrintUpsellUrl !== undefined && message.proPrintUpsellUrl !== null && message.hasOwnProperty("proPrintUpsellUrl")) + object.proPrintUpsellUrl = $types[65].toObject(message.proPrintUpsellUrl, options); + if (message.starDataProto !== undefined && message.starDataProto !== null && message.hasOwnProperty("starDataProto")) + object.starDataProto = $types[66].toObject(message.starDataProto, options); + if (message.feedbackUrl !== undefined && message.feedbackUrl !== null && message.hasOwnProperty("feedbackUrl")) + object.feedbackUrl = $types[67].toObject(message.feedbackUrl, options); + if (message.oauth2LoginUrl !== undefined && message.oauth2LoginUrl !== null && message.hasOwnProperty("oauth2LoginUrl")) + object.oauth2LoginUrl = $types[68].toObject(message.oauth2LoginUrl, options); + return object; + }; - for (j = 0; j < zIndiceslength; j++) { - index = zIndices[j] * yStride * (inputOrder + 1) + s; - coefficients[dimOne + j] = yTable[index]; - } + EndSnippetProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - for (var i = 1; i < zIndiceslength; i++) { - var coefIndex = 0; - var dimTwo = Math.floor(i * (1 - i) / 2) + (zIndiceslength * i); - var nonZeroCoefficients = false; + EndSnippetProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - for (j = 0; j < zIndiceslength - i; j++) { - var zj = xTable[zIndices[j]]; - var zn = xTable[zIndices[j + i]]; + EndSnippetProto.SearchConfigProto = (function() { - var numerator; - var coefficient; - if (zn - zj <= 0) { - index = zIndices[j] * yStride * (inputOrder + 1) + yStride * i + s; - numerator = yTable[index]; - coefficient = (numerator / CesiumMath.factorial(i)); - coefficients[dimOne + dimTwo + coefIndex] = coefficient; - coefIndex++; - } else { - var dimTwoMinusOne = Math.floor((i - 1) * (2 - i) / 2) + (zIndiceslength * (i - 1)); - numerator = coefficients[dimOne + dimTwoMinusOne + j + 1] - coefficients[dimOne + dimTwoMinusOne + j]; - coefficient = (numerator / (zn - zj)); - coefficients[dimOne + dimTwo + coefIndex] = coefficient; - coefIndex++; + function SearchConfigProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; } - nonZeroCoefficients = nonZeroCoefficients || (numerator !== 0.0); - } - - if (nonZeroCoefficients) { - highestNonZero = Math.max(highestNonZero, i); - } - } - } - return highestNonZero; - } + SearchConfigProto.prototype.searchServer = $util.emptyArray; + SearchConfigProto.prototype.oneboxService = $util.emptyArray; + SearchConfigProto.prototype.kmlSearchUrl = null; + SearchConfigProto.prototype.kmlRenderUrl = null; + SearchConfigProto.prototype.searchHistoryUrl = null; + SearchConfigProto.prototype.errorPageUrl = null; - return HermitePolynomialApproximation; -}); + var $types = { + 0 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer", + 1 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto", + 2 : "keyhole.dbroot.StringIdOrValueProto", + 3 : "keyhole.dbroot.StringIdOrValueProto", + 4 : "keyhole.dbroot.StringIdOrValueProto", + 5 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); -define('Core/IauOrientationParameters',[],function() { - 'use strict'; + SearchConfigProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.searchServer && message.searchServer.length)) + message.searchServer = []; + message.searchServer.push($types[0].decode(reader, reader.uint32())); + break; + case 2: + if (!(message.oneboxService && message.oneboxService.length)) + message.oneboxService = []; + message.oneboxService.push($types[1].decode(reader, reader.uint32())); + break; + case 3: + message.kmlSearchUrl = $types[2].decode(reader, reader.uint32()); + break; + case 4: + message.kmlRenderUrl = $types[3].decode(reader, reader.uint32()); + break; + case 6: + message.searchHistoryUrl = $types[4].decode(reader, reader.uint32()); + break; + case 5: + message.errorPageUrl = $types[5].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - /** - * A structure containing the orientation data computed at a particular time. The data - * represents the direction of the pole of rotation and the rotation about that pole. - * <p> - * These parameters correspond to the parameters in the Report from the IAU/IAG Working Group - * except that they are expressed in radians. - * </p> - * - * @exports IauOrientationParameters - * - * @private - */ - function IauOrientationParameters(rightAscension, declination, rotation, rotationRate) { - /** - * The right ascension of the north pole of the body with respect to - * the International Celestial Reference Frame, in radians. - * @type {Number} - * - * @private - */ - this.rightAscension = rightAscension; + SearchConfigProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.searchServer !== undefined) { + if (!Array.isArray(message.searchServer)) + return "searchServer: array expected"; + for (var i = 0; i < message.searchServer.length; ++i) { + var error = $types[0].verify(message.searchServer[i]); + if (error) + return "searchServer." + error; + } + } + if (message.oneboxService !== undefined) { + if (!Array.isArray(message.oneboxService)) + return "oneboxService: array expected"; + for (var i = 0; i < message.oneboxService.length; ++i) { + var error = $types[1].verify(message.oneboxService[i]); + if (error) + return "oneboxService." + error; + } + } + if (message.kmlSearchUrl !== undefined && message.kmlSearchUrl !== null) { + var error = $types[2].verify(message.kmlSearchUrl); + if (error) + return "kmlSearchUrl." + error; + } + if (message.kmlRenderUrl !== undefined && message.kmlRenderUrl !== null) { + var error = $types[3].verify(message.kmlRenderUrl); + if (error) + return "kmlRenderUrl." + error; + } + if (message.searchHistoryUrl !== undefined && message.searchHistoryUrl !== null) { + var error = $types[4].verify(message.searchHistoryUrl); + if (error) + return "searchHistoryUrl." + error; + } + if (message.errorPageUrl !== undefined && message.errorPageUrl !== null) { + var error = $types[5].verify(message.errorPageUrl); + if (error) + return "errorPageUrl." + error; + } + return null; + }; - /** - * The declination of the north pole of the body with respect to - * the International Celestial Reference Frame, in radians. - * @type {Number} - * - * @private - */ - this.declination = declination; + SearchConfigProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto(); + if (object.searchServer) { + if (!Array.isArray(object.searchServer)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchServer: array expected"); + message.searchServer = []; + for (var i = 0; i < object.searchServer.length; ++i) { + if (typeof object.searchServer[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchServer: object expected"); + message.searchServer[i] = $types[0].fromObject(object.searchServer[i]); + } + } + if (object.oneboxService) { + if (!Array.isArray(object.oneboxService)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.oneboxService: array expected"); + message.oneboxService = []; + for (var i = 0; i < object.oneboxService.length; ++i) { + if (typeof object.oneboxService[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.oneboxService: object expected"); + message.oneboxService[i] = $types[1].fromObject(object.oneboxService[i]); + } + } + if (object.kmlSearchUrl !== undefined && object.kmlSearchUrl !== null) { + if (typeof object.kmlSearchUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.kmlSearchUrl: object expected"); + message.kmlSearchUrl = $types[2].fromObject(object.kmlSearchUrl); + } + if (object.kmlRenderUrl !== undefined && object.kmlRenderUrl !== null) { + if (typeof object.kmlRenderUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.kmlRenderUrl: object expected"); + message.kmlRenderUrl = $types[3].fromObject(object.kmlRenderUrl); + } + if (object.searchHistoryUrl !== undefined && object.searchHistoryUrl !== null) { + if (typeof object.searchHistoryUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.searchHistoryUrl: object expected"); + message.searchHistoryUrl = $types[4].fromObject(object.searchHistoryUrl); + } + if (object.errorPageUrl !== undefined && object.errorPageUrl !== null) { + if (typeof object.errorPageUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.errorPageUrl: object expected"); + message.errorPageUrl = $types[5].fromObject(object.errorPageUrl); + } + return message; + }; - /** - * The rotation about the north pole used to align a set of axes with - * the meridian defined by the IAU report, in radians. - * @type {Number} - * - * @private - */ - this.rotation = rotation; + SearchConfigProto.from = SearchConfigProto.fromObject; - /** - * The instantaneous rotation rate about the north pole, in radians per second. - * @type {Number} - * - * @private - */ - this.rotationRate = rotationRate; - } + SearchConfigProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.searchServer = []; + object.oneboxService = []; + } + if (options.defaults) { + object.kmlSearchUrl = null; + object.kmlRenderUrl = null; + object.searchHistoryUrl = null; + object.errorPageUrl = null; + } + if (message.searchServer !== undefined && message.searchServer !== null && message.hasOwnProperty("searchServer")) { + object.searchServer = []; + for (var j = 0; j < message.searchServer.length; ++j) + object.searchServer[j] = $types[0].toObject(message.searchServer[j], options); + } + if (message.oneboxService !== undefined && message.oneboxService !== null && message.hasOwnProperty("oneboxService")) { + object.oneboxService = []; + for (var j = 0; j < message.oneboxService.length; ++j) + object.oneboxService[j] = $types[1].toObject(message.oneboxService[j], options); + } + if (message.kmlSearchUrl !== undefined && message.kmlSearchUrl !== null && message.hasOwnProperty("kmlSearchUrl")) + object.kmlSearchUrl = $types[2].toObject(message.kmlSearchUrl, options); + if (message.kmlRenderUrl !== undefined && message.kmlRenderUrl !== null && message.hasOwnProperty("kmlRenderUrl")) + object.kmlRenderUrl = $types[3].toObject(message.kmlRenderUrl, options); + if (message.searchHistoryUrl !== undefined && message.searchHistoryUrl !== null && message.hasOwnProperty("searchHistoryUrl")) + object.searchHistoryUrl = $types[4].toObject(message.searchHistoryUrl, options); + if (message.errorPageUrl !== undefined && message.errorPageUrl !== null && message.hasOwnProperty("errorPageUrl")) + object.errorPageUrl = $types[5].toObject(message.errorPageUrl, options); + return object; + }; - return IauOrientationParameters; -}); + SearchConfigProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; -define('Core/Iau2000Orientation',[ - './defined', - './IauOrientationParameters', - './JulianDate', - './Math', - './TimeConstants' - ], function( - defined, - IauOrientationParameters, - JulianDate, - CesiumMath, - TimeConstants) { - 'use strict'; + SearchConfigProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * This is a collection of the orientation information available for central bodies. - * The data comes from the Report of the IAU/IAG Working Group on Cartographic - * Coordinates and Rotational Elements: 2000. - * - * @exports Iau2000Orientation - * - * @private - */ - var Iau2000Orientation = {}; + SearchConfigProto.SearchServer = (function() { - var TdtMinusTai = 32.184; - var J2000d = 2451545.0; + function SearchServer(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - var c1 = -0.0529921; - var c2 = -0.1059842; - var c3 = 13.0120009; - var c4 = 13.3407154; - var c5 = 0.9856003; - var c6 = 26.4057084; - var c7 = 13.0649930; - var c8 = 0.3287146; - var c9 = 1.7484877; - var c10 = -0.1589763; - var c11 = 0.0036096; - var c12 = 0.1643573; - var c13 = 12.9590088; - var dateTT = new JulianDate(); + SearchServer.prototype.name = null; + SearchServer.prototype.url = null; + SearchServer.prototype.type = 0; + SearchServer.prototype.htmlTransformUrl = null; + SearchServer.prototype.kmlTransformUrl = null; + SearchServer.prototype.supplementalUi = null; + SearchServer.prototype.suggestion = $util.emptyArray; + SearchServer.prototype.searchlet = $util.emptyArray; + SearchServer.prototype.requirements = null; + SearchServer.prototype.suggestServer = null; - /** - * Compute the orientation parameters for the Moon. - * - * @param {JulianDate} [date=JulianDate.now()] The date to evaluate the parameters. - * @param {IauOrientationParameters} [result] The object onto which to store the result. - * @returns {IauOrientationParameters} The modified result parameter or a new instance representing the orientation of the Earth's Moon. - */ - Iau2000Orientation.ComputeMoon = function(date, result) { - if (!defined(date)) { - date = JulianDate.now(); - } + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 1 : "keyhole.dbroot.StringIdOrValueProto", + 2 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.ResultType", + 3 : "keyhole.dbroot.StringIdOrValueProto", + 4 : "keyhole.dbroot.StringIdOrValueProto", + 5 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi", + 6 : "keyhole.dbroot.StringIdOrValueProto", + 7 : "keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto", + 8 : "keyhole.dbroot.RequirementProto", + 9 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - dateTT = JulianDate.addSeconds(date, TdtMinusTai, dateTT); - var d = JulianDate.totalDays(dateTT) - J2000d; - var T = d / TimeConstants.DAYS_PER_JULIAN_CENTURY; + SearchServer.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.url = $types[1].decode(reader, reader.uint32()); + break; + case 3: + message.type = reader.uint32(); + break; + case 4: + message.htmlTransformUrl = $types[3].decode(reader, reader.uint32()); + break; + case 5: + message.kmlTransformUrl = $types[4].decode(reader, reader.uint32()); + break; + case 6: + message.supplementalUi = $types[5].decode(reader, reader.uint32()); + break; + case 9: + if (!(message.suggestion && message.suggestion.length)) + message.suggestion = []; + message.suggestion.push($types[6].decode(reader, reader.uint32())); + break; + case 7: + if (!(message.searchlet && message.searchlet.length)) + message.searchlet = []; + message.searchlet.push($types[7].decode(reader, reader.uint32())); + break; + case 8: + message.requirements = $types[8].decode(reader, reader.uint32()); + break; + case 10: + message.suggestServer = $types[9].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - var E1 = (125.045 + c1 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E2 = (250.089 + c2 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E3 = (260.008 + c3 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E4 = (176.625 + c4 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E5 = (357.529 + c5 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E6 = (311.589 + c6 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E7 = (134.963 + c7 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E8 = (276.617 + c8 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E9 = (34.226 + c9 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E10 = (15.134 + c10 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E11 = (119.743 + c11 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E12 = (239.961 + c12 * d) * CesiumMath.RADIANS_PER_DEGREE; - var E13 = (25.053 + c13 * d) * CesiumMath.RADIANS_PER_DEGREE; + SearchServer.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name !== undefined && message.name !== null) { + var error = $types[0].verify(message.name); + if (error) + return "name." + error; + } + if (message.url !== undefined && message.url !== null) { + var error = $types[1].verify(message.url); + if (error) + return "url." + error; + } + if (message.type !== undefined) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + break; + } + if (message.htmlTransformUrl !== undefined && message.htmlTransformUrl !== null) { + var error = $types[3].verify(message.htmlTransformUrl); + if (error) + return "htmlTransformUrl." + error; + } + if (message.kmlTransformUrl !== undefined && message.kmlTransformUrl !== null) { + var error = $types[4].verify(message.kmlTransformUrl); + if (error) + return "kmlTransformUrl." + error; + } + if (message.supplementalUi !== undefined && message.supplementalUi !== null) { + var error = $types[5].verify(message.supplementalUi); + if (error) + return "supplementalUi." + error; + } + if (message.suggestion !== undefined) { + if (!Array.isArray(message.suggestion)) + return "suggestion: array expected"; + for (var i = 0; i < message.suggestion.length; ++i) { + var error = $types[6].verify(message.suggestion[i]); + if (error) + return "suggestion." + error; + } + } + if (message.searchlet !== undefined) { + if (!Array.isArray(message.searchlet)) + return "searchlet: array expected"; + for (var i = 0; i < message.searchlet.length; ++i) { + var error = $types[7].verify(message.searchlet[i]); + if (error) + return "searchlet." + error; + } + } + if (message.requirements !== undefined && message.requirements !== null) { + var error = $types[8].verify(message.requirements); + if (error) + return "requirements." + error; + } + if (message.suggestServer !== undefined && message.suggestServer !== null) { + var error = $types[9].verify(message.suggestServer); + if (error) + return "suggestServer." + error; + } + return null; + }; - var sinE1 = Math.sin(E1); - var sinE2 = Math.sin(E2); - var sinE3 = Math.sin(E3); - var sinE4 = Math.sin(E4); - var sinE5 = Math.sin(E5); - var sinE6 = Math.sin(E6); - var sinE7 = Math.sin(E7); - var sinE8 = Math.sin(E8); - var sinE9 = Math.sin(E9); - var sinE10 = Math.sin(E10); - var sinE11 = Math.sin(E11); - var sinE12 = Math.sin(E12); - var sinE13 = Math.sin(E13); + SearchServer.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer(); + if (object.name !== undefined && object.name !== null) { + if (typeof object.name !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.name: object expected"); + message.name = $types[0].fromObject(object.name); + } + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.url: object expected"); + message.url = $types[1].fromObject(object.url); + } + switch (object.type) { + case "RESULT_TYPE_KML": + case 0: + message.type = 0; + break; + case "RESULT_TYPE_XML": + case 1: + message.type = 1; + break; + } + if (object.htmlTransformUrl !== undefined && object.htmlTransformUrl !== null) { + if (typeof object.htmlTransformUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.htmlTransformUrl: object expected"); + message.htmlTransformUrl = $types[3].fromObject(object.htmlTransformUrl); + } + if (object.kmlTransformUrl !== undefined && object.kmlTransformUrl !== null) { + if (typeof object.kmlTransformUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.kmlTransformUrl: object expected"); + message.kmlTransformUrl = $types[4].fromObject(object.kmlTransformUrl); + } + if (object.supplementalUi !== undefined && object.supplementalUi !== null) { + if (typeof object.supplementalUi !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.supplementalUi: object expected"); + message.supplementalUi = $types[5].fromObject(object.supplementalUi); + } + if (object.suggestion) { + if (!Array.isArray(object.suggestion)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestion: array expected"); + message.suggestion = []; + for (var i = 0; i < object.suggestion.length; ++i) { + if (typeof object.suggestion[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestion: object expected"); + message.suggestion[i] = $types[6].fromObject(object.suggestion[i]); + } + } + if (object.searchlet) { + if (!Array.isArray(object.searchlet)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.searchlet: array expected"); + message.searchlet = []; + for (var i = 0; i < object.searchlet.length; ++i) { + if (typeof object.searchlet[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.searchlet: object expected"); + message.searchlet[i] = $types[7].fromObject(object.searchlet[i]); + } + } + if (object.requirements !== undefined && object.requirements !== null) { + if (typeof object.requirements !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.requirements: object expected"); + message.requirements = $types[8].fromObject(object.requirements); + } + if (object.suggestServer !== undefined && object.suggestServer !== null) { + if (typeof object.suggestServer !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.suggestServer: object expected"); + message.suggestServer = $types[9].fromObject(object.suggestServer); + } + return message; + }; - var cosE1 = Math.cos(E1); - var cosE2 = Math.cos(E2); - var cosE3 = Math.cos(E3); - var cosE4 = Math.cos(E4); - var cosE5 = Math.cos(E5); - var cosE6 = Math.cos(E6); - var cosE7 = Math.cos(E7); - var cosE8 = Math.cos(E8); - var cosE9 = Math.cos(E9); - var cosE10 = Math.cos(E10); - var cosE11 = Math.cos(E11); - var cosE12 = Math.cos(E12); - var cosE13 = Math.cos(E13); + SearchServer.from = SearchServer.fromObject; - var rightAscension = (269.9949 + 0.0031 * T - 3.8787 * sinE1 - 0.1204 * sinE2 + - 0.0700 * sinE3 - 0.0172 * sinE4 + 0.0072 * sinE6 - - 0.0052 * sinE10 + 0.0043 * sinE13) * - CesiumMath.RADIANS_PER_DEGREE; - var declination = (66.5392 + 0.013 * T + 1.5419 * cosE1 + 0.0239 * cosE2 - - 0.0278 * cosE3 + 0.0068 * cosE4 - 0.0029 * cosE6 + - 0.0009 * cosE7 + 0.0008 * cosE10 - 0.0009 * cosE13) * - CesiumMath.RADIANS_PER_DEGREE; - var rotation = (38.3213 + 13.17635815 * d - 1.4e-12 * d * d + 3.5610 * sinE1 + - 0.1208 * sinE2 - 0.0642 * sinE3 + 0.0158 * sinE4 + - 0.0252 * sinE5 - 0.0066 * sinE6 - 0.0047 * sinE7 - - 0.0046 * sinE8 + 0.0028 * sinE9 + 0.0052 * sinE10 + - 0.004 * sinE11 + 0.0019 * sinE12 - 0.0044 * sinE13) * - CesiumMath.RADIANS_PER_DEGREE; + SearchServer.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.suggestion = []; + object.searchlet = []; + } + if (options.defaults) { + object.name = null; + object.url = null; + object.type = options.enums === String ? "RESULT_TYPE_KML" : 0; + object.htmlTransformUrl = null; + object.kmlTransformUrl = null; + object.supplementalUi = null; + object.requirements = null; + object.suggestServer = null; + } + if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) + object.name = $types[0].toObject(message.name, options); + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[1].toObject(message.url, options); + if (message.type !== undefined && message.type !== null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $types[2][message.type] : message.type; + if (message.htmlTransformUrl !== undefined && message.htmlTransformUrl !== null && message.hasOwnProperty("htmlTransformUrl")) + object.htmlTransformUrl = $types[3].toObject(message.htmlTransformUrl, options); + if (message.kmlTransformUrl !== undefined && message.kmlTransformUrl !== null && message.hasOwnProperty("kmlTransformUrl")) + object.kmlTransformUrl = $types[4].toObject(message.kmlTransformUrl, options); + if (message.supplementalUi !== undefined && message.supplementalUi !== null && message.hasOwnProperty("supplementalUi")) + object.supplementalUi = $types[5].toObject(message.supplementalUi, options); + if (message.suggestion !== undefined && message.suggestion !== null && message.hasOwnProperty("suggestion")) { + object.suggestion = []; + for (var j = 0; j < message.suggestion.length; ++j) + object.suggestion[j] = $types[6].toObject(message.suggestion[j], options); + } + if (message.searchlet !== undefined && message.searchlet !== null && message.hasOwnProperty("searchlet")) { + object.searchlet = []; + for (var j = 0; j < message.searchlet.length; ++j) + object.searchlet[j] = $types[7].toObject(message.searchlet[j], options); + } + if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) + object.requirements = $types[8].toObject(message.requirements, options); + if (message.suggestServer !== undefined && message.suggestServer !== null && message.hasOwnProperty("suggestServer")) + object.suggestServer = $types[9].toObject(message.suggestServer, options); + return object; + }; - var rotationRate = ((13.17635815 - 1.4e-12 * (2.0 * d)) + - 3.5610 * cosE1 * c1 + - 0.1208 * cosE2*c2 - 0.0642 * cosE3*c3 + 0.0158 * cosE4*c4 + - 0.0252 * cosE5*c5 - 0.0066 * cosE6*c6 - 0.0047 * cosE7*c7 - - 0.0046 * cosE8*c8 + 0.0028 * cosE9*c9 + 0.0052 * cosE10*c10 + - 0.004 * cosE11*c11 + 0.0019 * cosE12*c12 - 0.0044 * cosE13*c13) / - 86400.0 * CesiumMath.RADIANS_PER_DEGREE; + SearchServer.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - if (!defined(result)) { - result = new IauOrientationParameters(); - } + SearchServer.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - result.rightAscension = rightAscension; - result.declination = declination; - result.rotation = rotation; - result.rotationRate = rotationRate; + SearchServer.ResultType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values["RESULT_TYPE_KML"] = 0; + values["RESULT_TYPE_XML"] = 1; + return values; + })(); - return result; - }; + SearchServer.SupplementalUi = (function() { - return Iau2000Orientation; -}); + function SupplementalUi(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } -define('Core/IauOrientationAxes',[ - './Cartesian3', - './defined', - './Iau2000Orientation', - './JulianDate', - './Math', - './Matrix3', - './Quaternion' - ], function( - Cartesian3, - defined, - Iau2000Orientation, - JulianDate, - CesiumMath, - Matrix3, - Quaternion) { - 'use strict'; + SupplementalUi.prototype.url = null; + SupplementalUi.prototype.label = null; + SupplementalUi.prototype.height = 160; - /** - * The Axes representing the orientation of a Globe as represented by the data - * from the IAU/IAG Working Group reports on rotational elements. - * @alias IauOrientationAxes - * @constructor - * - * @param {IauOrientationAxes~ComputeFunction} [computeFunction] The function that computes the {@link IauOrientationParameters} given a {@link JulianDate}. - * - * @see Iau2000Orientation - * - * @private - */ - function IauOrientationAxes(computeFunction) { - if (!defined(computeFunction) || typeof computeFunction !== 'function') { - computeFunction = Iau2000Orientation.ComputeMoon; - } + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 1 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - this._computeFunction = computeFunction; - } + SupplementalUi.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.label = $types[1].decode(reader, reader.uint32()); + break; + case 3: + message.height = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - var xAxisScratch = new Cartesian3(); - var yAxisScratch = new Cartesian3(); - var zAxisScratch = new Cartesian3(); + SupplementalUi.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.url !== undefined && message.url !== null) { + var error = $types[0].verify(message.url); + if (error) + return "url." + error; + } + if (message.label !== undefined && message.label !== null) { + var error = $types[1].verify(message.label); + if (error) + return "label." + error; + } + if (message.height !== undefined) + if (!$util.isInteger(message.height)) + return "height: integer expected"; + return null; + }; - function computeRotationMatrix(alpha, delta, result) { - var xAxis = xAxisScratch; - xAxis.x = Math.cos(alpha + CesiumMath.PI_OVER_TWO); - xAxis.y = Math.sin(alpha + CesiumMath.PI_OVER_TWO); - xAxis.z = 0.0; + SupplementalUi.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi(); + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.url: object expected"); + message.url = $types[0].fromObject(object.url); + } + if (object.label !== undefined && object.label !== null) { + if (typeof object.label !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SupplementalUi.label: object expected"); + message.label = $types[1].fromObject(object.label); + } + if (object.height !== undefined && object.height !== null) + message.height = object.height | 0; + return message; + }; - var cosDec = Math.cos(delta); + SupplementalUi.from = SupplementalUi.fromObject; - var zAxis = zAxisScratch; - zAxis.x = cosDec * Math.cos(alpha); - zAxis.y = cosDec * Math.sin(alpha); - zAxis.z = Math.sin(delta); + SupplementalUi.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.url = null; + object.label = null; + object.height = 160; + } + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[0].toObject(message.url, options); + if (message.label !== undefined && message.label !== null && message.hasOwnProperty("label")) + object.label = $types[1].toObject(message.label, options); + if (message.height !== undefined && message.height !== null && message.hasOwnProperty("height")) + object.height = message.height; + return object; + }; - var yAxis = Cartesian3.cross(zAxis, xAxis, yAxisScratch); + SupplementalUi.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - if (!defined(result)) { - result = new Matrix3(); - } + SupplementalUi.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - result[0] = xAxis.x; - result[1] = yAxis.x; - result[2] = zAxis.x; - result[3] = xAxis.y; - result[4] = yAxis.y; - result[5] = zAxis.y; - result[6] = xAxis.z; - result[7] = yAxis.z; - result[8] = zAxis.z; + return SupplementalUi; + })(); - return result; - } + SearchServer.SearchletProto = (function() { - var rotMtxScratch = new Matrix3(); - var quatScratch = new Quaternion(); + function SearchletProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * Computes a rotation from ICRF to a Globe's Fixed axes. - * - * @param {JulianDate} date The date to evaluate the matrix. - * @param {Matrix3} result The object onto which to store the result. - * @returns {Matrix} The modified result parameter or a new instance of the rotation from ICRF to Fixed. - */ - IauOrientationAxes.prototype.evaluate = function(date, result) { - if (!defined(date)) { - date = JulianDate.now(); - } + SearchletProto.prototype.url = null; + SearchletProto.prototype.name = null; + SearchletProto.prototype.requirements = null; - var alphaDeltaW = this._computeFunction(date); - var precMtx = computeRotationMatrix(alphaDeltaW.rightAscension, alphaDeltaW.declination, result); + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 1 : "keyhole.dbroot.StringIdOrValueProto", + 2 : "keyhole.dbroot.RequirementProto" + }; + $lazyTypes.push($types); - var rot = CesiumMath.zeroToTwoPi(alphaDeltaW.rotation); - var quat = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, rot, quatScratch); - var rotMtx = Matrix3.fromQuaternion(Quaternion.conjugate(quat, quat), rotMtxScratch); + SearchletProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.name = $types[1].decode(reader, reader.uint32()); + break; + case 3: + message.requirements = $types[2].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - var cbi2cbf = Matrix3.multiply(rotMtx, precMtx, precMtx); - return cbi2cbf; - }; + SearchletProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.url !== undefined && message.url !== null) { + var error = $types[0].verify(message.url); + if (error) + return "url." + error; + } + if (message.name !== undefined && message.name !== null) { + var error = $types[1].verify(message.name); + if (error) + return "name." + error; + } + if (message.requirements !== undefined && message.requirements !== null) { + var error = $types[2].verify(message.requirements); + if (error) + return "requirements." + error; + } + return null; + }; - /** - * A function that computes the {@link IauOrientationParameters} for a {@link JulianDate}. - * @callback IauOrientationAxes~ComputeFunction - * @param {JulianDate} date The date to evaluate the parameters. - * @returns {IauOrientationParameters} The orientation parameters. - */ + SearchletProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto(); + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.url: object expected"); + message.url = $types[0].fromObject(object.url); + } + if (object.name !== undefined && object.name !== null) { + if (typeof object.name !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.name: object expected"); + message.name = $types[1].fromObject(object.name); + } + if (object.requirements !== undefined && object.requirements !== null) { + if (typeof object.requirements !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.SearchServer.SearchletProto.requirements: object expected"); + message.requirements = $types[2].fromObject(object.requirements); + } + return message; + }; - return IauOrientationAxes; -}); + SearchletProto.from = SearchletProto.fromObject; -define('Core/InterpolationAlgorithm',[ - './DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + SearchletProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.url = null; + object.name = null; + object.requirements = null; + } + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[0].toObject(message.url, options); + if (message.name !== undefined && message.name !== null && message.hasOwnProperty("name")) + object.name = $types[1].toObject(message.name, options); + if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) + object.requirements = $types[2].toObject(message.requirements, options); + return object; + }; - /** - * The interface for interpolation algorithms. - * - * @exports InterpolationAlgorithm - * - * @see LagrangePolynomialApproximation - * @see LinearApproximation - * @see HermitePolynomialApproximation - */ - var InterpolationAlgorithm = {}; + SearchletProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - /** - * Gets the name of this interpolation algorithm. - * @type {String} - */ - InterpolationAlgorithm.type = undefined; + SearchletProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * Given the desired degree, returns the number of data points required for interpolation. - * @function - * - * @param {Number} degree The desired degree of interpolation. - * @returns {Number} The number of required data points needed for the desired degree of interpolation. - */ - InterpolationAlgorithm.getRequiredDataPoints = DeveloperError.throwInstantiationError; + return SearchletProto; + })(); - /** - * Performs zero order interpolation. - * @function - * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values - * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three - * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to - * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. - */ - InterpolationAlgorithm.interpolateOrderZero = DeveloperError.throwInstantiationError; + return SearchServer; + })(); - /** - * Performs higher order interpolation. Not all interpolators need to support high-order interpolation, - * if this function remains undefined on implementing objects, interpolateOrderZero will be used instead. - * @function - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values - * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three - * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to - * each independent variable value in xTable. - * @param {Number} inputOrder The number of derivatives supplied for input. - * @param {Number} outputOrder The number of derivatives desired for output. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. - */ - InterpolationAlgorithm.interpolate = DeveloperError.throwInstantiationError; + SearchConfigProto.OneboxServiceProto = (function() { - return InterpolationAlgorithm; -}); + function OneboxServiceProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } -define('Core/TimeInterval',[ - './Check', - './defaultValue', - './defined', - './defineProperties', - './freezeObject', - './JulianDate' - ], function( - Check, - defaultValue, - defined, - defineProperties, - freezeObject, - JulianDate) { - 'use strict'; + OneboxServiceProto.prototype.serviceUrl = null; + OneboxServiceProto.prototype.requirements = null; - /** - * An interval defined by a start and a stop time; optionally including those times as part of the interval. - * Arbitrary data can optionally be associated with each instance for used with {@link TimeIntervalCollection}. - * - * @alias TimeInterval - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {JulianDate} [options.start=new JulianDate()] The start time of the interval. - * @param {JulianDate} [options.stop=new JulianDate()] The stop time of the interval. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. - * @param {Object} [options.data] Arbitrary data associated with this interval. - * - * @example - * // Create an instance that spans August 1st, 1980 and is associated - * // with a Cartesian position. - * var timeInterval = new Cesium.TimeInterval({ - * start : Cesium.JulianDate.fromIso8601('1980-08-01T00:00:00Z'), - * stop : Cesium.JulianDate.fromIso8601('1980-08-02T00:00:00Z'), - * isStartIncluded : true, - * isStopIncluded : false, - * data : Cesium.Cartesian3.fromDegrees(39.921037, -75.170082) - * }); - * - * @example - * // Create two instances from ISO 8601 intervals with associated numeric data - * // then compute their intersection, summing the data they contain. - * var left = Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2000/2010', - * data : 2 - * }); - * - * var right = Cesium.TimeInterval.fromIso8601({ - * iso8601 : '1995/2005', - * data : 3 - * }); - * - * //The result of the below intersection will be an interval equivalent to - * //var intersection = Cesium.TimeInterval.fromIso8601({ - * // iso8601 : '2000/2005', - * // data : 5 - * //}); - * var intersection = new Cesium.TimeInterval(); - * Cesium.TimeInterval.intersect(left, right, intersection, function(leftData, rightData) { - * return leftData + rightData; - * }); - * - * @example - * // Check if an interval contains a specific time. - * var dateToCheck = Cesium.JulianDate.fromIso8601('1982-09-08T11:30:00Z'); - * var containsDate = Cesium.TimeInterval.contains(timeInterval, dateToCheck); - */ - function TimeInterval(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * Gets or sets the start time of this interval. - * @type {JulianDate} - */ - this.start = defined(options.start) ? JulianDate.clone(options.start) : new JulianDate(); - - /** - * Gets or sets the stop time of this interval. - * @type {JulianDate} - */ - this.stop = defined(options.stop) ? JulianDate.clone(options.stop) : new JulianDate(); + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 1 : "keyhole.dbroot.RequirementProto" + }; + $lazyTypes.push($types); - /** - * Gets or sets the data associated with this interval. - * @type {Object} - */ - this.data = options.data; + OneboxServiceProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.serviceUrl = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.requirements = $types[1].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - /** - * Gets or sets whether or not the start time is included in this interval. - * @type {Boolean} - * @default true - */ - this.isStartIncluded = defaultValue(options.isStartIncluded, true); + OneboxServiceProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.serviceUrl !== undefined && message.serviceUrl !== null) { + var error = $types[0].verify(message.serviceUrl); + if (error) + return "serviceUrl." + error; + } + if (message.requirements !== undefined && message.requirements !== null) { + var error = $types[1].verify(message.requirements); + if (error) + return "requirements." + error; + } + return null; + }; - /** - * Gets or sets whether or not the stop time is included in this interval. - * @type {Boolean} - * @default true - */ - this.isStopIncluded = defaultValue(options.isStopIncluded, true); - } + OneboxServiceProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto(); + if (object.serviceUrl !== undefined && object.serviceUrl !== null) { + if (typeof object.serviceUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.serviceUrl: object expected"); + message.serviceUrl = $types[0].fromObject(object.serviceUrl); + } + if (object.requirements !== undefined && object.requirements !== null) { + if (typeof object.requirements !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.SearchConfigProto.OneboxServiceProto.requirements: object expected"); + message.requirements = $types[1].fromObject(object.requirements); + } + return message; + }; - defineProperties(TimeInterval.prototype, { - /** - * Gets whether or not this interval is empty. - * @memberof TimeInterval.prototype - * @type {Boolean} - * @readonly - */ - isEmpty : { - get : function() { - var stopComparedToStart = JulianDate.compare(this.stop, this.start); - return stopComparedToStart < 0 || (stopComparedToStart === 0 && (!this.isStartIncluded || !this.isStopIncluded)); - } - } - }); + OneboxServiceProto.from = OneboxServiceProto.fromObject; - var scratchInterval = { - start : undefined, - stop : undefined, - isStartIncluded : undefined, - isStopIncluded : undefined, - data : undefined - }; + OneboxServiceProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.serviceUrl = null; + object.requirements = null; + } + if (message.serviceUrl !== undefined && message.serviceUrl !== null && message.hasOwnProperty("serviceUrl")) + object.serviceUrl = $types[0].toObject(message.serviceUrl, options); + if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) + object.requirements = $types[1].toObject(message.requirements, options); + return object; + }; - /** - * Creates a new instance from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} interval. - * - * @param {Object} options Object with the following properties: - * @param {String} options.iso8601 An ISO 8601 interval. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. - * @param {Object} [options.data] Arbitrary data associated with this interval. - * @param {TimeInterval} [result] An existing instance to use for the result. - * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. - */ - TimeInterval.fromIso8601 = function(options, result) { - Check.typeOf.object('options', options); - Check.typeOf.string('options.iso8601', options.iso8601); - - var dates = options.iso8601.split('/'); - var start = JulianDate.fromIso8601(dates[0]); - var stop = JulianDate.fromIso8601(dates[1]); - var isStartIncluded = defaultValue(options.isStartIncluded, true); - var isStopIncluded = defaultValue(options.isStopIncluded, true); - var data = options.data; + OneboxServiceProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - if (!defined(result)) { - scratchInterval.start = start; - scratchInterval.stop = stop; - scratchInterval.isStartIncluded = isStartIncluded; - scratchInterval.isStopIncluded = isStopIncluded; - scratchInterval.data = data; - return new TimeInterval(scratchInterval); - } + OneboxServiceProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - result.start = start; - result.stop = stop; - result.isStartIncluded = isStartIncluded; - result.isStopIncluded = isStopIncluded; - result.data = data; - return result; - }; + return OneboxServiceProto; + })(); - /** - * Creates an ISO8601 representation of the provided interval. - * - * @param {TimeInterval} timeInterval The interval to be converted. - * @param {Number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. - * @returns {String} The ISO8601 representation of the provided interval. - */ - TimeInterval.toIso8601 = function(timeInterval, precision) { - Check.typeOf.object('timeInterval', timeInterval); - - return JulianDate.toIso8601(timeInterval.start, precision) + '/' + JulianDate.toIso8601(timeInterval.stop, precision); - }; + return SearchConfigProto; + })(); - /** - * Duplicates the provided instance. - * - * @param {TimeInterval} [timeInterval] The instance to clone. - * @param {TimeInterval} [result] An existing instance to use for the result. - * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. - */ - TimeInterval.clone = function(timeInterval, result) { - if (!defined(timeInterval)) { - return undefined; - } - if (!defined(result)) { - return new TimeInterval(timeInterval); - } - result.start = timeInterval.start; - result.stop = timeInterval.stop; - result.isStartIncluded = timeInterval.isStartIncluded; - result.isStopIncluded = timeInterval.isStopIncluded; - result.data = timeInterval.data; - return result; - }; + EndSnippetProto.SearchInfoProto = (function() { - /** - * Compares two instances and returns <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {TimeInterval} [left] The first instance. - * @param {TimeInterval} [right] The second instance. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. - */ - TimeInterval.equals = function(left, right, dataComparer) { - return left === right || - defined(left) && defined(right) && - (left.isEmpty && right.isEmpty || - left.isStartIncluded === right.isStartIncluded && - left.isStopIncluded === right.isStopIncluded && - JulianDate.equals(left.start, right.start) && - JulianDate.equals(left.stop, right.stop) && - (left.data === right.data || (defined(dataComparer) && dataComparer(left.data, right.data)))); - }; + function SearchInfoProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * Compares two instances and returns <code>true</code> if they are within <code>epsilon</code> seconds of - * each other. That is, in order for the dates to be considered equal (and for - * this function to return <code>true</code>), the absolute value of the difference between them, in - * seconds, must be less than <code>epsilon</code>. - * - * @param {TimeInterval} [left] The first instance. - * @param {TimeInterval} [right] The second instance. - * @param {Number} epsilon The maximum number of seconds that should separate the two instances. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. - */ - TimeInterval.equalsEpsilon = function(left, right, epsilon, dataComparer) { - Check.typeOf.number('epsilon', epsilon); - - return left === right || - defined(left) && defined(right) && - (left.isEmpty && right.isEmpty || - left.isStartIncluded === right.isStartIncluded && - left.isStopIncluded === right.isStopIncluded && - JulianDate.equalsEpsilon(left.start, right.start, epsilon) && - JulianDate.equalsEpsilon(left.stop, right.stop, epsilon) && - (left.data === right.data || (defined(dataComparer) && dataComparer(left.data, right.data)))); - }; + SearchInfoProto.prototype.defaultUrl = "http://maps.google.com/maps"; + SearchInfoProto.prototype.geocodeParam = "q"; - /** - * Computes the intersection of two intervals, optionally merging their data. - * - * @param {TimeInterval} left The first interval. - * @param {TimeInterval} [right] The second interval. - * @param {TimeInterval} result An existing instance to use for the result. - * @param {TimeInterval~MergeCallback} [mergeCallback] A function which merges the data of the two intervals. If omitted, the data from the left interval will be used. - * @returns {TimeInterval} The modified result parameter. - */ - TimeInterval.intersect = function(left, right, result, mergeCallback) { - Check.typeOf.object('left', left); - Check.typeOf.object('result', result); - - if (!defined(right)) { - return TimeInterval.clone(TimeInterval.EMPTY, result); - } + SearchInfoProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.SearchInfoProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.defaultUrl = reader.string(); + break; + case 2: + message.geocodeParam = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - var leftStart = left.start; - var leftStop = left.stop; + SearchInfoProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.defaultUrl !== undefined) + if (!$util.isString(message.defaultUrl)) + return "defaultUrl: string expected"; + if (message.geocodeParam !== undefined) + if (!$util.isString(message.geocodeParam)) + return "geocodeParam: string expected"; + return null; + }; - var rightStart = right.start; - var rightStop = right.stop; + SearchInfoProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.SearchInfoProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.SearchInfoProto(); + if (object.defaultUrl !== undefined && object.defaultUrl !== null) + message.defaultUrl = String(object.defaultUrl); + if (object.geocodeParam !== undefined && object.geocodeParam !== null) + message.geocodeParam = String(object.geocodeParam); + return message; + }; - var intersectsStartRight = JulianDate.greaterThanOrEquals(rightStart, leftStart) && JulianDate.greaterThanOrEquals(leftStop, rightStart); - var intersectsStartLeft = !intersectsStartRight && JulianDate.lessThanOrEquals(rightStart, leftStart) && JulianDate.lessThanOrEquals(leftStart, rightStop); + SearchInfoProto.from = SearchInfoProto.fromObject; - if (!intersectsStartRight && !intersectsStartLeft) { - return TimeInterval.clone(TimeInterval.EMPTY, result); - } + SearchInfoProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.defaultUrl = "http://maps.google.com/maps"; + object.geocodeParam = "q"; + } + if (message.defaultUrl !== undefined && message.defaultUrl !== null && message.hasOwnProperty("defaultUrl")) + object.defaultUrl = message.defaultUrl; + if (message.geocodeParam !== undefined && message.geocodeParam !== null && message.hasOwnProperty("geocodeParam")) + object.geocodeParam = message.geocodeParam; + return object; + }; - var leftIsStartIncluded = left.isStartIncluded; - var leftIsStopIncluded = left.isStopIncluded; - var rightIsStartIncluded = right.isStartIncluded; - var rightIsStopIncluded = right.isStopIncluded; - var leftLessThanRight = JulianDate.lessThan(leftStop, rightStop); + SearchInfoProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - result.start = intersectsStartRight ? rightStart : leftStart; - result.isStartIncluded = (leftIsStartIncluded && rightIsStartIncluded) || (!JulianDate.equals(rightStart, leftStart) && ((intersectsStartRight && rightIsStartIncluded) || (intersectsStartLeft && leftIsStartIncluded))); - result.stop = leftLessThanRight ? leftStop : rightStop; - result.isStopIncluded = leftLessThanRight ? leftIsStopIncluded : (leftIsStopIncluded && rightIsStopIncluded) || (!JulianDate.equals(rightStop, leftStop) && rightIsStopIncluded); - result.data = defined(mergeCallback) ? mergeCallback(left.data, right.data) : left.data; - return result; - }; + SearchInfoProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * Checks if the specified date is inside the provided interval. - * - * @param {TimeInterval} timeInterval The interval. - * @param {JulianDate} julianDate The date to check. - * @returns {Boolean} <code>true</code> if the interval contains the specified date, <code>false</code> otherwise. - */ - TimeInterval.contains = function(timeInterval, julianDate) { - Check.typeOf.object('timeInterval', timeInterval); - Check.typeOf.object('julianDate', julianDate); - - if (timeInterval.isEmpty) { - return false; - } + return SearchInfoProto; + })(); - var startComparedToDate = JulianDate.compare(timeInterval.start, julianDate); - if (startComparedToDate === 0) { - return timeInterval.isStartIncluded; - } + EndSnippetProto.RockTreeDataProto = (function() { - var dateComparedToStop = JulianDate.compare(julianDate, timeInterval.stop); - if (dateComparedToStop === 0) { - return timeInterval.isStopIncluded; - } + function RockTreeDataProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - return startComparedToDate < 0 && dateComparedToStop < 0; - }; + RockTreeDataProto.prototype.url = null; - /** - * Duplicates this instance. - * - * @param {TimeInterval} [result] An existing instance to use for the result. - * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. - */ - TimeInterval.prototype.clone = function(result) { - return TimeInterval.clone(this, result); - }; + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - /** - * Compares this instance against the provided instance componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {TimeInterval} [right] The right hand side interval. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - TimeInterval.prototype.equals = function(right, dataComparer) { - return TimeInterval.equals(this, right, dataComparer); - }; + RockTreeDataProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.RockTreeDataProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = $types[0].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - /** - * Compares this instance against the provided instance componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {TimeInterval} [right] The right hand side interval. - * @param {Number} epsilon The epsilon to use for equality testing. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. - */ - TimeInterval.prototype.equalsEpsilon = function(right, epsilon, dataComparer) { - return TimeInterval.equalsEpsilon(this, right, epsilon, dataComparer); - }; + RockTreeDataProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.url !== undefined && message.url !== null) { + var error = $types[0].verify(message.url); + if (error) + return "url." + error; + } + return null; + }; - /** - * Creates a string representing this TimeInterval in ISO8601 format. - * - * @returns {String} A string representing this TimeInterval in ISO8601 format. - */ - TimeInterval.prototype.toString = function() { - return TimeInterval.toIso8601(this); - }; + RockTreeDataProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.RockTreeDataProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.RockTreeDataProto(); + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.RockTreeDataProto.url: object expected"); + message.url = $types[0].fromObject(object.url); + } + return message; + }; - /** - * An immutable empty interval. - * - * @type {TimeInterval} - * @constant - */ - TimeInterval.EMPTY = freezeObject(new TimeInterval({ - start : new JulianDate(), - stop : new JulianDate(), - isStartIncluded : false, - isStopIncluded : false - })); + RockTreeDataProto.from = RockTreeDataProto.fromObject; - /** - * Function interface for merging interval data. - * @callback TimeInterval~MergeCallback - * - * @param {Object} leftData The first data instance. - * @param {Object} rightData The second data instance. - * @returns {Object} The result of merging the two data instances. - */ + RockTreeDataProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.url = null; + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[0].toObject(message.url, options); + return object; + }; - /** - * Function interface for comparing interval data. - * @callback TimeInterval~DataComparer - * @param {Object} leftData The first data instance. - * @param {Object} rightData The second data instance. - * @returns {Boolean} <code>true</code> if the provided instances are equal, <code>false</code> otherwise. - */ + RockTreeDataProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - return TimeInterval; -}); + RockTreeDataProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; -define('Core/Iso8601',[ - './freezeObject', - './JulianDate', - './TimeInterval' - ], function( - freezeObject, - JulianDate, - TimeInterval) { - 'use strict'; + return RockTreeDataProto; + })(); - var MINIMUM_VALUE = freezeObject(JulianDate.fromIso8601('0000-01-01T00:00:00Z')); - var MAXIMUM_VALUE = freezeObject(JulianDate.fromIso8601('9999-12-31T24:00:00Z')); - var MAXIMUM_INTERVAL = freezeObject(new TimeInterval({ - start : MINIMUM_VALUE, - stop : MAXIMUM_VALUE - })); + EndSnippetProto.FilmstripConfigProto = (function() { - /** - * Constants related to ISO8601 support. - * - * @exports Iso8601 - * - * @see {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601 on Wikipedia} - * @see JulianDate - * @see TimeInterval - */ - var Iso8601 = { - /** - * A {@link JulianDate} representing the earliest time representable by an ISO8601 date. - * This is equivalent to the date string '0000-01-01T00:00:00Z' - * - * @type {JulianDate} - * @constant - */ - MINIMUM_VALUE : MINIMUM_VALUE, + function FilmstripConfigProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * A {@link JulianDate} representing the latest time representable by an ISO8601 date. - * This is equivalent to the date string '9999-12-31T24:00:00Z' - * - * @type {JulianDate} - * @constant - */ - MAXIMUM_VALUE : MAXIMUM_VALUE, + FilmstripConfigProto.prototype.requirements = null; + FilmstripConfigProto.prototype.alleycatUrlTemplate = null; + FilmstripConfigProto.prototype.fallbackAlleycatUrlTemplate = null; + FilmstripConfigProto.prototype.metadataUrlTemplate = null; + FilmstripConfigProto.prototype.thumbnailUrlTemplate = null; + FilmstripConfigProto.prototype.kmlUrlTemplate = null; + FilmstripConfigProto.prototype.featuredToursUrl = null; + FilmstripConfigProto.prototype.enableViewportFallback = false; + FilmstripConfigProto.prototype.viewportFallbackDistance = 0; + FilmstripConfigProto.prototype.imageryType = $util.emptyArray; - /** - * A {@link TimeInterval} representing the largest interval representable by an ISO8601 interval. - * This is equivalent to the interval string '0000-01-01T00:00:00Z/9999-12-31T24:00:00Z' - * - * @type {JulianDate} - * @constant - */ - MAXIMUM_INTERVAL : MAXIMUM_INTERVAL - }; + var $types = { + 0 : "keyhole.dbroot.RequirementProto", + 1 : "keyhole.dbroot.StringIdOrValueProto", + 2 : "keyhole.dbroot.StringIdOrValueProto", + 3 : "keyhole.dbroot.StringIdOrValueProto", + 4 : "keyhole.dbroot.StringIdOrValueProto", + 5 : "keyhole.dbroot.StringIdOrValueProto", + 6 : "keyhole.dbroot.StringIdOrValueProto", + 9 : "keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto" + }; + $lazyTypes.push($types); - return Iso8601; -}); + FilmstripConfigProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.requirements = $types[0].decode(reader, reader.uint32()); + break; + case 2: + message.alleycatUrlTemplate = $types[1].decode(reader, reader.uint32()); + break; + case 9: + message.fallbackAlleycatUrlTemplate = $types[2].decode(reader, reader.uint32()); + break; + case 3: + message.metadataUrlTemplate = $types[3].decode(reader, reader.uint32()); + break; + case 4: + message.thumbnailUrlTemplate = $types[4].decode(reader, reader.uint32()); + break; + case 5: + message.kmlUrlTemplate = $types[5].decode(reader, reader.uint32()); + break; + case 6: + message.featuredToursUrl = $types[6].decode(reader, reader.uint32()); + break; + case 7: + message.enableViewportFallback = reader.bool(); + break; + case 8: + message.viewportFallbackDistance = reader.uint32(); + break; + case 10: + if (!(message.imageryType && message.imageryType.length)) + message.imageryType = []; + message.imageryType.push($types[9].decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; -define('Core/KeyboardEventModifier',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + FilmstripConfigProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.requirements !== undefined && message.requirements !== null) { + var error = $types[0].verify(message.requirements); + if (error) + return "requirements." + error; + } + if (message.alleycatUrlTemplate !== undefined && message.alleycatUrlTemplate !== null) { + var error = $types[1].verify(message.alleycatUrlTemplate); + if (error) + return "alleycatUrlTemplate." + error; + } + if (message.fallbackAlleycatUrlTemplate !== undefined && message.fallbackAlleycatUrlTemplate !== null) { + var error = $types[2].verify(message.fallbackAlleycatUrlTemplate); + if (error) + return "fallbackAlleycatUrlTemplate." + error; + } + if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null) { + var error = $types[3].verify(message.metadataUrlTemplate); + if (error) + return "metadataUrlTemplate." + error; + } + if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null) { + var error = $types[4].verify(message.thumbnailUrlTemplate); + if (error) + return "thumbnailUrlTemplate." + error; + } + if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null) { + var error = $types[5].verify(message.kmlUrlTemplate); + if (error) + return "kmlUrlTemplate." + error; + } + if (message.featuredToursUrl !== undefined && message.featuredToursUrl !== null) { + var error = $types[6].verify(message.featuredToursUrl); + if (error) + return "featuredToursUrl." + error; + } + if (message.enableViewportFallback !== undefined) + if (typeof message.enableViewportFallback !== "boolean") + return "enableViewportFallback: boolean expected"; + if (message.viewportFallbackDistance !== undefined) + if (!$util.isInteger(message.viewportFallbackDistance)) + return "viewportFallbackDistance: integer expected"; + if (message.imageryType !== undefined) { + if (!Array.isArray(message.imageryType)) + return "imageryType: array expected"; + for (var i = 0; i < message.imageryType.length; ++i) { + var error = $types[9].verify(message.imageryType[i]); + if (error) + return "imageryType." + error; + } + } + return null; + }; - /** - * This enumerated type is for representing keyboard modifiers. These are keys - * that are held down in addition to other event types. - * - * @exports KeyboardEventModifier - */ - var KeyboardEventModifier = { - /** - * Represents the shift key being held down. - * - * @type {Number} - * @constant - */ - SHIFT : 0, + FilmstripConfigProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto(); + if (object.requirements !== undefined && object.requirements !== null) { + if (typeof object.requirements !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.requirements: object expected"); + message.requirements = $types[0].fromObject(object.requirements); + } + if (object.alleycatUrlTemplate !== undefined && object.alleycatUrlTemplate !== null) { + if (typeof object.alleycatUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.alleycatUrlTemplate: object expected"); + message.alleycatUrlTemplate = $types[1].fromObject(object.alleycatUrlTemplate); + } + if (object.fallbackAlleycatUrlTemplate !== undefined && object.fallbackAlleycatUrlTemplate !== null) { + if (typeof object.fallbackAlleycatUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.fallbackAlleycatUrlTemplate: object expected"); + message.fallbackAlleycatUrlTemplate = $types[2].fromObject(object.fallbackAlleycatUrlTemplate); + } + if (object.metadataUrlTemplate !== undefined && object.metadataUrlTemplate !== null) { + if (typeof object.metadataUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.metadataUrlTemplate: object expected"); + message.metadataUrlTemplate = $types[3].fromObject(object.metadataUrlTemplate); + } + if (object.thumbnailUrlTemplate !== undefined && object.thumbnailUrlTemplate !== null) { + if (typeof object.thumbnailUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.thumbnailUrlTemplate: object expected"); + message.thumbnailUrlTemplate = $types[4].fromObject(object.thumbnailUrlTemplate); + } + if (object.kmlUrlTemplate !== undefined && object.kmlUrlTemplate !== null) { + if (typeof object.kmlUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.kmlUrlTemplate: object expected"); + message.kmlUrlTemplate = $types[5].fromObject(object.kmlUrlTemplate); + } + if (object.featuredToursUrl !== undefined && object.featuredToursUrl !== null) { + if (typeof object.featuredToursUrl !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.featuredToursUrl: object expected"); + message.featuredToursUrl = $types[6].fromObject(object.featuredToursUrl); + } + if (object.enableViewportFallback !== undefined && object.enableViewportFallback !== null) + message.enableViewportFallback = Boolean(object.enableViewportFallback); + if (object.viewportFallbackDistance !== undefined && object.viewportFallbackDistance !== null) + message.viewportFallbackDistance = object.viewportFallbackDistance >>> 0; + if (object.imageryType) { + if (!Array.isArray(object.imageryType)) + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: array expected"); + message.imageryType = []; + for (var i = 0; i < object.imageryType.length; ++i) { + if (typeof object.imageryType[i] !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.imageryType: object expected"); + message.imageryType[i] = $types[9].fromObject(object.imageryType[i]); + } + } + return message; + }; - /** - * Represents the control key being held down. - * - * @type {Number} - * @constant - */ - CTRL : 1, + FilmstripConfigProto.from = FilmstripConfigProto.fromObject; - /** - * Represents the alt key being held down. - * - * @type {Number} - * @constant - */ - ALT : 2 - }; + FilmstripConfigProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.imageryType = []; + if (options.defaults) { + object.requirements = null; + object.alleycatUrlTemplate = null; + object.fallbackAlleycatUrlTemplate = null; + object.metadataUrlTemplate = null; + object.thumbnailUrlTemplate = null; + object.kmlUrlTemplate = null; + object.featuredToursUrl = null; + object.enableViewportFallback = false; + object.viewportFallbackDistance = 0; + } + if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) + object.requirements = $types[0].toObject(message.requirements, options); + if (message.alleycatUrlTemplate !== undefined && message.alleycatUrlTemplate !== null && message.hasOwnProperty("alleycatUrlTemplate")) + object.alleycatUrlTemplate = $types[1].toObject(message.alleycatUrlTemplate, options); + if (message.fallbackAlleycatUrlTemplate !== undefined && message.fallbackAlleycatUrlTemplate !== null && message.hasOwnProperty("fallbackAlleycatUrlTemplate")) + object.fallbackAlleycatUrlTemplate = $types[2].toObject(message.fallbackAlleycatUrlTemplate, options); + if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null && message.hasOwnProperty("metadataUrlTemplate")) + object.metadataUrlTemplate = $types[3].toObject(message.metadataUrlTemplate, options); + if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null && message.hasOwnProperty("thumbnailUrlTemplate")) + object.thumbnailUrlTemplate = $types[4].toObject(message.thumbnailUrlTemplate, options); + if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null && message.hasOwnProperty("kmlUrlTemplate")) + object.kmlUrlTemplate = $types[5].toObject(message.kmlUrlTemplate, options); + if (message.featuredToursUrl !== undefined && message.featuredToursUrl !== null && message.hasOwnProperty("featuredToursUrl")) + object.featuredToursUrl = $types[6].toObject(message.featuredToursUrl, options); + if (message.enableViewportFallback !== undefined && message.enableViewportFallback !== null && message.hasOwnProperty("enableViewportFallback")) + object.enableViewportFallback = message.enableViewportFallback; + if (message.viewportFallbackDistance !== undefined && message.viewportFallbackDistance !== null && message.hasOwnProperty("viewportFallbackDistance")) + object.viewportFallbackDistance = message.viewportFallbackDistance; + if (message.imageryType !== undefined && message.imageryType !== null && message.hasOwnProperty("imageryType")) { + object.imageryType = []; + for (var j = 0; j < message.imageryType.length; ++j) + object.imageryType[j] = $types[9].toObject(message.imageryType[j], options); + } + return object; + }; - return freezeObject(KeyboardEventModifier); -}); + FilmstripConfigProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; -define('Core/LagrangePolynomialApproximation',[ - './defined' - ], function( - defined) { - 'use strict'; + FilmstripConfigProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * An {@link InterpolationAlgorithm} for performing Lagrange interpolation. - * - * @exports LagrangePolynomialApproximation - */ - var LagrangePolynomialApproximation = { - type : 'Lagrange' - }; + FilmstripConfigProto.AlleycatImageryTypeProto = (function() { - /** - * Given the desired degree, returns the number of data points required for interpolation. - * - * @param {Number} degree The desired degree of interpolation. - * @returns {Number} The number of required data points needed for the desired degree of interpolation. - */ - LagrangePolynomialApproximation.getRequiredDataPoints = function(degree) { - return Math.max(degree + 1.0, 2); - }; + function AlleycatImageryTypeProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * Interpolates values using Lagrange Polynomial Approximation. - * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values - * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three - * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to - * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. - */ - LagrangePolynomialApproximation.interpolateOrderZero = function(x, xTable, yTable, yStride, result) { - if (!defined(result)) { - result = new Array(yStride); - } + AlleycatImageryTypeProto.prototype.imageryTypeId = 0; + AlleycatImageryTypeProto.prototype.imageryTypeLabel = ""; + AlleycatImageryTypeProto.prototype.metadataUrlTemplate = null; + AlleycatImageryTypeProto.prototype.thumbnailUrlTemplate = null; + AlleycatImageryTypeProto.prototype.kmlUrlTemplate = null; - var i; - var j; - var length = xTable.length; + var $types = { + 2 : "keyhole.dbroot.StringIdOrValueProto", + 3 : "keyhole.dbroot.StringIdOrValueProto", + 4 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - for (i = 0; i < yStride; i++) { - result[i] = 0; - } + AlleycatImageryTypeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.imageryTypeId = reader.int32(); + break; + case 2: + message.imageryTypeLabel = reader.string(); + break; + case 3: + message.metadataUrlTemplate = $types[2].decode(reader, reader.uint32()); + break; + case 4: + message.thumbnailUrlTemplate = $types[3].decode(reader, reader.uint32()); + break; + case 5: + message.kmlUrlTemplate = $types[4].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - for (i = 0; i < length; i++) { - var coefficient = 1; + AlleycatImageryTypeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.imageryTypeId !== undefined) + if (!$util.isInteger(message.imageryTypeId)) + return "imageryTypeId: integer expected"; + if (message.imageryTypeLabel !== undefined) + if (!$util.isString(message.imageryTypeLabel)) + return "imageryTypeLabel: string expected"; + if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null) { + var error = $types[2].verify(message.metadataUrlTemplate); + if (error) + return "metadataUrlTemplate." + error; + } + if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null) { + var error = $types[3].verify(message.thumbnailUrlTemplate); + if (error) + return "thumbnailUrlTemplate." + error; + } + if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null) { + var error = $types[4].verify(message.kmlUrlTemplate); + if (error) + return "kmlUrlTemplate." + error; + } + return null; + }; - for (j = 0; j < length; j++) { - if (j !== i) { - var diffX = xTable[i] - xTable[j]; - coefficient *= (x - xTable[j]) / diffX; - } - } + AlleycatImageryTypeProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto(); + if (object.imageryTypeId !== undefined && object.imageryTypeId !== null) + message.imageryTypeId = object.imageryTypeId | 0; + if (object.imageryTypeLabel !== undefined && object.imageryTypeLabel !== null) + message.imageryTypeLabel = String(object.imageryTypeLabel); + if (object.metadataUrlTemplate !== undefined && object.metadataUrlTemplate !== null) { + if (typeof object.metadataUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.metadataUrlTemplate: object expected"); + message.metadataUrlTemplate = $types[2].fromObject(object.metadataUrlTemplate); + } + if (object.thumbnailUrlTemplate !== undefined && object.thumbnailUrlTemplate !== null) { + if (typeof object.thumbnailUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.thumbnailUrlTemplate: object expected"); + message.thumbnailUrlTemplate = $types[3].fromObject(object.thumbnailUrlTemplate); + } + if (object.kmlUrlTemplate !== undefined && object.kmlUrlTemplate !== null) { + if (typeof object.kmlUrlTemplate !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.FilmstripConfigProto.AlleycatImageryTypeProto.kmlUrlTemplate: object expected"); + message.kmlUrlTemplate = $types[4].fromObject(object.kmlUrlTemplate); + } + return message; + }; - for (j = 0; j < yStride; j++) { - result[j] += coefficient * yTable[i * yStride + j]; - } - } + AlleycatImageryTypeProto.from = AlleycatImageryTypeProto.fromObject; - return result; - }; + AlleycatImageryTypeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.imageryTypeId = 0; + object.imageryTypeLabel = ""; + object.metadataUrlTemplate = null; + object.thumbnailUrlTemplate = null; + object.kmlUrlTemplate = null; + } + if (message.imageryTypeId !== undefined && message.imageryTypeId !== null && message.hasOwnProperty("imageryTypeId")) + object.imageryTypeId = message.imageryTypeId; + if (message.imageryTypeLabel !== undefined && message.imageryTypeLabel !== null && message.hasOwnProperty("imageryTypeLabel")) + object.imageryTypeLabel = message.imageryTypeLabel; + if (message.metadataUrlTemplate !== undefined && message.metadataUrlTemplate !== null && message.hasOwnProperty("metadataUrlTemplate")) + object.metadataUrlTemplate = $types[2].toObject(message.metadataUrlTemplate, options); + if (message.thumbnailUrlTemplate !== undefined && message.thumbnailUrlTemplate !== null && message.hasOwnProperty("thumbnailUrlTemplate")) + object.thumbnailUrlTemplate = $types[3].toObject(message.thumbnailUrlTemplate, options); + if (message.kmlUrlTemplate !== undefined && message.kmlUrlTemplate !== null && message.hasOwnProperty("kmlUrlTemplate")) + object.kmlUrlTemplate = $types[4].toObject(message.kmlUrlTemplate, options); + return object; + }; - return LagrangePolynomialApproximation; -}); + AlleycatImageryTypeProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; -define('Core/LinearApproximation',[ - './defined', - './DeveloperError' - ], function( - defined, - DeveloperError) { - 'use strict'; + AlleycatImageryTypeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * An {@link InterpolationAlgorithm} for performing linear interpolation. - * - * @exports LinearApproximation - */ - var LinearApproximation = { - type : 'Linear' - }; + return AlleycatImageryTypeProto; + })(); - /** - * Given the desired degree, returns the number of data points required for interpolation. - * Since linear interpolation can only generate a first degree polynomial, this function - * always returns 2. - * @param {Number} degree The desired degree of interpolation. - * @returns {Number} This function always returns 2. - * - */ - LinearApproximation.getRequiredDataPoints = function(degree) { - return 2; - }; + return FilmstripConfigProto; + })(); - /** - * Interpolates values using linear approximation. - * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values - * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three - * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to - * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. - */ - LinearApproximation.interpolateOrderZero = function(x, xTable, yTable, yStride, result) { - if (xTable.length !== 2) { - throw new DeveloperError('The xTable provided to the linear interpolator must have exactly two elements.'); - } else if (yStride <= 0) { - throw new DeveloperError('There must be at least 1 dependent variable for each independent variable.'); - } - - if (!defined(result)) { - result = new Array(yStride); - } + EndSnippetProto.StarDataProto = (function() { - var i; - var y0; - var y1; - var x0 = xTable[0]; - var x1 = xTable[1]; + function StarDataProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - if (x0 === x1) { - throw new DeveloperError('Divide by zero error: xTable[0] and xTable[1] are equal'); - } - - for (i = 0; i < yStride; i++) { - y0 = yTable[i]; - y1 = yTable[i + yStride]; - result[i] = (((y1 - y0) * x) + (x1 * y0) - (x0 * y1)) / (x1 - x0); - } + StarDataProto.prototype.url = null; - return result; - }; + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto" + }; + $lazyTypes.push($types); - return LinearApproximation; -}); + StarDataProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EndSnippetProto.StarDataProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = $types[0].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; -define('Core/loadBlob',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + StarDataProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.url !== undefined && message.url !== null) { + var error = $types[0].verify(message.url); + if (error) + return "url." + error; + } + return null; + }; - /** - * Asynchronously loads the given URL as a blob. Returns a promise that will resolve to - * a Blob once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadBlob - * - * @param {String} url The URL of the data. - * @param {Object} [headers] HTTP headers to send with the requests. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * @example - * // load a single URL asynchronously - * Cesium.loadBlob('some/url').then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - */ - function loadBlob(url, headers, request) { - return loadWithXhr({ - url : url, - responseType : 'blob', - headers : headers, - request : request - }); - } + StarDataProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EndSnippetProto.StarDataProto) + return object; + var message = new $root.keyhole.dbroot.EndSnippetProto.StarDataProto(); + if (object.url !== undefined && object.url !== null) { + if (typeof object.url !== "object") + throw TypeError(".keyhole.dbroot.EndSnippetProto.StarDataProto.url: object expected"); + message.url = $types[0].fromObject(object.url); + } + return message; + }; - return loadBlob; -}); + StarDataProto.from = StarDataProto.fromObject; -define('Core/loadCRN',[ - '../ThirdParty/when', - './CompressedTextureBuffer', - './defined', - './DeveloperError', - './loadArrayBuffer', - './TaskProcessor' - ], function( - when, - CompressedTextureBuffer, - defined, - DeveloperError, - loadArrayBuffer, - TaskProcessor) { - 'use strict'; + StarDataProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.url = null; + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = $types[0].toObject(message.url, options); + return object; + }; - var transcodeTaskProcessor = new TaskProcessor('transcodeCRNToDXT', Number.POSITIVE_INFINITY); + StarDataProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - /** - * Asynchronously loads and parses the given URL to a CRN file or parses the raw binary data of a CRN file. - * Returns a promise that will resolve to an object containing the image buffer, width, height and format once loaded, - * or reject if the URL failed to load or failed to parse the data. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadCRN - * - * @param {String|ArrayBuffer} urlOrBuffer The URL of the binary data or an ArrayBuffer. - * @param {Object} [headers] HTTP headers to send with the requests. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<CompressedTextureBuffer>|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * @exception {RuntimeError} Unsupported compressed format. - * - * @example - * // load a single URL asynchronously - * Cesium.loadCRN('some/url').then(function(textureData) { - * var width = textureData.width; - * var height = textureData.height; - * var format = textureData.internalFormat; - * var arrayBufferView = textureData.bufferView; - * // use the data to create a texture - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://github.com/BinomialLLC/crunch|crunch DXTc texture compression and transcoding library} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - */ - function loadCRN(urlOrBuffer, headers, request) { - if (!defined(urlOrBuffer)) { - throw new DeveloperError('urlOrBuffer is required.'); - } - - var loadPromise; - if (urlOrBuffer instanceof ArrayBuffer || ArrayBuffer.isView(urlOrBuffer)) { - loadPromise = when.resolve(urlOrBuffer); - } else { - loadPromise = loadArrayBuffer(urlOrBuffer, headers, request); - } + StarDataProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - if (!defined(loadPromise)) { - return undefined; - } + return StarDataProto; + })(); - return loadPromise.then(function(data) { - if (!defined(data)) { - return; - } - var transferrableObjects = []; - if (data instanceof ArrayBuffer) { - transferrableObjects.push(data); - } else if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) { - transferrableObjects.push(data.buffer); - } else { - // data is a view of an array buffer. need to copy so it is transferrable to web worker - data = data.slice(0, data.length); - transferrableObjects.push(data.buffer); - } + return EndSnippetProto; + })(); - return transcodeTaskProcessor.scheduleTask(data, transferrableObjects); - }).then(function(compressedTextureBuffer) { - return CompressedTextureBuffer.clone(compressedTextureBuffer); - }); - } + dbroot.DbRootRefProto = (function() { - return loadCRN; -}); + function DbRootRefProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } -define('Core/loadImage',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './isCrossOriginUrl', - './isDataUri', - './Request', - './RequestScheduler', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - isCrossOriginUrl, - isDataUri, - Request, - RequestScheduler, - TrustedServers) { - 'use strict'; + DbRootRefProto.prototype.url = ""; + DbRootRefProto.prototype.isCritical = false; + DbRootRefProto.prototype.requirements = null; - /** - * Asynchronously loads the given image URL. Returns a promise that will resolve to - * an {@link Image} once loaded, or reject if the image failed to load. - * - * @exports loadImage - * - * @param {String} url The source URL of the image. - * @param {Boolean} [allowCrossOrigin=true] Whether to request the image using Cross-Origin - * Resource Sharing (CORS). CORS is only actually used if the image URL is actually cross-origin. - * Data URIs are never requested using CORS. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load a single image asynchronously - * Cesium.loadImage('some/image/url.png').then(function(image) { - * // use the loaded image - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * // load several images in parallel - * when.all([loadImage('image1.png'), loadImage('image2.png')]).then(function(images) { - * // images is an array containing all the loaded images - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - */ - function loadImage(url, allowCrossOrigin, request) { - Check.defined('url', url); - - allowCrossOrigin = defaultValue(allowCrossOrigin, true); + var $types = { + 2 : "keyhole.dbroot.RequirementProto" + }; + $lazyTypes.push($types); - request = defined(request) ? request : new Request(); - request.url = url; - request.requestFunction = function() { - var crossOrigin; + DbRootRefProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.DbRootRefProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.url = reader.string(); + break; + case 1: + message.isCritical = reader.bool(); + break; + case 3: + message.requirements = $types[2].decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - // data URIs can't have allowCrossOrigin set. - if (isDataUri(url) || !allowCrossOrigin) { - crossOrigin = false; - } else { - crossOrigin = isCrossOriginUrl(url); - } + DbRootRefProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.url)) + return "url: string expected"; + if (message.isCritical !== undefined) + if (typeof message.isCritical !== "boolean") + return "isCritical: boolean expected"; + if (message.requirements !== undefined && message.requirements !== null) { + var error = $types[2].verify(message.requirements); + if (error) + return "requirements." + error; + } + return null; + }; - var deferred = when.defer(); + DbRootRefProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.DbRootRefProto) + return object; + var message = new $root.keyhole.dbroot.DbRootRefProto(); + if (object.url !== undefined && object.url !== null) + message.url = String(object.url); + if (object.isCritical !== undefined && object.isCritical !== null) + message.isCritical = Boolean(object.isCritical); + if (object.requirements !== undefined && object.requirements !== null) { + if (typeof object.requirements !== "object") + throw TypeError(".keyhole.dbroot.DbRootRefProto.requirements: object expected"); + message.requirements = $types[2].fromObject(object.requirements); + } + return message; + }; - loadImage.createImage(url, crossOrigin, deferred); + DbRootRefProto.from = DbRootRefProto.fromObject; - return deferred.promise; - }; + DbRootRefProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.url = ""; + object.isCritical = false; + object.requirements = null; + } + if (message.url !== undefined && message.url !== null && message.hasOwnProperty("url")) + object.url = message.url; + if (message.isCritical !== undefined && message.isCritical !== null && message.hasOwnProperty("isCritical")) + object.isCritical = message.isCritical; + if (message.requirements !== undefined && message.requirements !== null && message.hasOwnProperty("requirements")) + object.requirements = $types[2].toObject(message.requirements, options); + return object; + }; - return RequestScheduler.request(request); - } + DbRootRefProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadImage.createImage = function(url, crossOrigin, deferred) { - var image = new Image(); + DbRootRefProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - image.onload = function() { - deferred.resolve(image); - }; + return DbRootRefProto; + })(); - image.onerror = function(e) { - deferred.reject(e); - }; + dbroot.DatabaseVersionProto = (function() { - if (crossOrigin) { - if (TrustedServers.contains(url)) { - image.crossOrigin = 'use-credentials'; - } else { - image.crossOrigin = ''; - } - } + function DatabaseVersionProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - image.src = url; - }; + DatabaseVersionProto.prototype.quadtreeVersion = 0; - loadImage.defaultCreateImage = loadImage.createImage; + DatabaseVersionProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.DatabaseVersionProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.quadtreeVersion = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - return loadImage; -}); + DatabaseVersionProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isInteger(message.quadtreeVersion)) + return "quadtreeVersion: integer expected"; + return null; + }; -define('Core/loadImageFromTypedArray',[ - '../ThirdParty/when', - './Check', - './loadImage' - ], function( - when, - Check, - loadImage) { - 'use strict'; + DatabaseVersionProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.DatabaseVersionProto) + return object; + var message = new $root.keyhole.dbroot.DatabaseVersionProto(); + if (object.quadtreeVersion !== undefined && object.quadtreeVersion !== null) + message.quadtreeVersion = object.quadtreeVersion >>> 0; + return message; + }; - /** - * @private - */ - function loadImageFromTypedArray(uint8Array, format, request) { - Check.typeOf.object('uint8Array', uint8Array); - Check.typeOf.string('format', format); - - var blob = new Blob([uint8Array], { - type : format - }); + DatabaseVersionProto.from = DatabaseVersionProto.fromObject; - var blobUrl = window.URL.createObjectURL(blob); - return loadImage(blobUrl, false, request).then(function(image) { - window.URL.revokeObjectURL(blobUrl); - return image; - }, function(error) { - window.URL.revokeObjectURL(blobUrl); - return when.reject(error); - }); - } + DatabaseVersionProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.quadtreeVersion = 0; + if (message.quadtreeVersion !== undefined && message.quadtreeVersion !== null && message.hasOwnProperty("quadtreeVersion")) + object.quadtreeVersion = message.quadtreeVersion; + return object; + }; - return loadImageFromTypedArray; -}); + DatabaseVersionProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; -define('Core/loadImageViaBlob',[ - '../ThirdParty/when', - './defined', - './isDataUri', - './loadBlob', - './loadImage' - ], function( - when, - defined, - isDataUri, - loadBlob, - loadImage) { - 'use strict'; + DatabaseVersionProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - var xhrBlobSupported = (function() { - try { - var xhr = new XMLHttpRequest(); - xhr.open('GET', '#', true); - xhr.responseType = 'blob'; - return xhr.responseType === 'blob'; - } catch (e) { - return false; - } - })(); + return DatabaseVersionProto; + })(); - /** - * Asynchronously loads the given image URL by first downloading it as a blob using - * XMLHttpRequest and then loading the image from the buffer via a blob URL. - * This allows access to more information that is not accessible via normal - * Image-based downloading, such as the size of the response. This function - * returns a promise that will resolve to - * an {@link Image} once loaded, or reject if the image failed to load. The - * returned image will have a "blob" property with the Blob itself. If the browser - * does not support an XMLHttpRequests with a responseType of 'blob', or if the - * provided URI is a data URI, this function is equivalent to calling {@link loadImage}, - * and the extra blob property will not be present. - * - * @exports loadImageViaBlob - * - * @param {String} url The source URL of the image. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load a single image asynchronously - * Cesium.loadImageViaBlob('some/image/url.png').then(function(image) { - * var blob = image.blob; - * // use the loaded image or XHR - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * // load several images in parallel - * when.all([loadImageViaBlob('image1.png'), loadImageViaBlob('image2.png')]).then(function(images) { - * // images is an array containing all the loaded images - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - */ - function loadImageViaBlob(url, request) { - if (!xhrBlobSupported || isDataUri(url)) { - return loadImage(url, undefined, request); - } + dbroot.DbRootProto = (function() { - var blobPromise = loadBlob(url, undefined, request); - if (!defined(blobPromise)) { - return undefined; - } + function DbRootProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - return blobPromise.then(function(blob) { - if (!defined(blob)) { - return; - } - var blobUrl = window.URL.createObjectURL(blob); + DbRootProto.prototype.databaseName = null; + DbRootProto.prototype.imageryPresent = true; + DbRootProto.prototype.protoImagery = false; + DbRootProto.prototype.terrainPresent = false; + DbRootProto.prototype.providerInfo = $util.emptyArray; + DbRootProto.prototype.nestedFeature = $util.emptyArray; + DbRootProto.prototype.styleAttribute = $util.emptyArray; + DbRootProto.prototype.styleMap = $util.emptyArray; + DbRootProto.prototype.endSnippet = null; + DbRootProto.prototype.translationEntry = $util.emptyArray; + DbRootProto.prototype.language = "en"; + DbRootProto.prototype.version = 5; + DbRootProto.prototype.dbrootReference = $util.emptyArray; + DbRootProto.prototype.databaseVersion = null; + DbRootProto.prototype.refreshTimeout = 0; - return loadImage(blobUrl, false).then(function(image) { - image.blob = blob; - window.URL.revokeObjectURL(blobUrl); - return image; - }, function(error) { - window.URL.revokeObjectURL(blobUrl); - return when.reject(error); - }); - }); - } + var $types = { + 0 : "keyhole.dbroot.StringIdOrValueProto", + 4 : "keyhole.dbroot.ProviderInfoProto", + 5 : "keyhole.dbroot.NestedFeatureProto", + 6 : "keyhole.dbroot.StyleAttributeProto", + 7 : "keyhole.dbroot.StyleMapProto", + 8 : "keyhole.dbroot.EndSnippetProto", + 9 : "keyhole.dbroot.StringEntryProto", + 12 : "keyhole.dbroot.DbRootRefProto", + 13 : "keyhole.dbroot.DatabaseVersionProto" + }; + $lazyTypes.push($types); - return loadImageViaBlob; -}); + DbRootProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.DbRootProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 15: + message.databaseName = $types[0].decode(reader, reader.uint32()); + break; + case 1: + message.imageryPresent = reader.bool(); + break; + case 14: + message.protoImagery = reader.bool(); + break; + case 2: + message.terrainPresent = reader.bool(); + break; + case 3: + if (!(message.providerInfo && message.providerInfo.length)) + message.providerInfo = []; + message.providerInfo.push($types[4].decode(reader, reader.uint32())); + break; + case 4: + if (!(message.nestedFeature && message.nestedFeature.length)) + message.nestedFeature = []; + message.nestedFeature.push($types[5].decode(reader, reader.uint32())); + break; + case 5: + if (!(message.styleAttribute && message.styleAttribute.length)) + message.styleAttribute = []; + message.styleAttribute.push($types[6].decode(reader, reader.uint32())); + break; + case 6: + if (!(message.styleMap && message.styleMap.length)) + message.styleMap = []; + message.styleMap.push($types[7].decode(reader, reader.uint32())); + break; + case 7: + message.endSnippet = $types[8].decode(reader, reader.uint32()); + break; + case 8: + if (!(message.translationEntry && message.translationEntry.length)) + message.translationEntry = []; + message.translationEntry.push($types[9].decode(reader, reader.uint32())); + break; + case 9: + message.language = reader.string(); + break; + case 10: + message.version = reader.int32(); + break; + case 11: + if (!(message.dbrootReference && message.dbrootReference.length)) + message.dbrootReference = []; + message.dbrootReference.push($types[12].decode(reader, reader.uint32())); + break; + case 13: + message.databaseVersion = $types[13].decode(reader, reader.uint32()); + break; + case 16: + message.refreshTimeout = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; -define('Renderer/PixelDatatype',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + DbRootProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.databaseName !== undefined && message.databaseName !== null) { + var error = $types[0].verify(message.databaseName); + if (error) + return "databaseName." + error; + } + if (message.imageryPresent !== undefined) + if (typeof message.imageryPresent !== "boolean") + return "imageryPresent: boolean expected"; + if (message.protoImagery !== undefined) + if (typeof message.protoImagery !== "boolean") + return "protoImagery: boolean expected"; + if (message.terrainPresent !== undefined) + if (typeof message.terrainPresent !== "boolean") + return "terrainPresent: boolean expected"; + if (message.providerInfo !== undefined) { + if (!Array.isArray(message.providerInfo)) + return "providerInfo: array expected"; + for (var i = 0; i < message.providerInfo.length; ++i) { + var error = $types[4].verify(message.providerInfo[i]); + if (error) + return "providerInfo." + error; + } + } + if (message.nestedFeature !== undefined) { + if (!Array.isArray(message.nestedFeature)) + return "nestedFeature: array expected"; + for (var i = 0; i < message.nestedFeature.length; ++i) { + var error = $types[5].verify(message.nestedFeature[i]); + if (error) + return "nestedFeature." + error; + } + } + if (message.styleAttribute !== undefined) { + if (!Array.isArray(message.styleAttribute)) + return "styleAttribute: array expected"; + for (var i = 0; i < message.styleAttribute.length; ++i) { + var error = $types[6].verify(message.styleAttribute[i]); + if (error) + return "styleAttribute." + error; + } + } + if (message.styleMap !== undefined) { + if (!Array.isArray(message.styleMap)) + return "styleMap: array expected"; + for (var i = 0; i < message.styleMap.length; ++i) { + var error = $types[7].verify(message.styleMap[i]); + if (error) + return "styleMap." + error; + } + } + if (message.endSnippet !== undefined && message.endSnippet !== null) { + var error = $types[8].verify(message.endSnippet); + if (error) + return "endSnippet." + error; + } + if (message.translationEntry !== undefined) { + if (!Array.isArray(message.translationEntry)) + return "translationEntry: array expected"; + for (var i = 0; i < message.translationEntry.length; ++i) { + var error = $types[9].verify(message.translationEntry[i]); + if (error) + return "translationEntry." + error; + } + } + if (message.language !== undefined) + if (!$util.isString(message.language)) + return "language: string expected"; + if (message.version !== undefined) + if (!$util.isInteger(message.version)) + return "version: integer expected"; + if (message.dbrootReference !== undefined) { + if (!Array.isArray(message.dbrootReference)) + return "dbrootReference: array expected"; + for (var i = 0; i < message.dbrootReference.length; ++i) { + var error = $types[12].verify(message.dbrootReference[i]); + if (error) + return "dbrootReference." + error; + } + } + if (message.databaseVersion !== undefined && message.databaseVersion !== null) { + var error = $types[13].verify(message.databaseVersion); + if (error) + return "databaseVersion." + error; + } + if (message.refreshTimeout !== undefined) + if (!$util.isInteger(message.refreshTimeout)) + return "refreshTimeout: integer expected"; + return null; + }; - /** - * @private - */ - var PixelDatatype = { - UNSIGNED_BYTE : WebGLConstants.UNSIGNED_BYTE, - UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT, - UNSIGNED_INT : WebGLConstants.UNSIGNED_INT, - FLOAT : WebGLConstants.FLOAT, - UNSIGNED_INT_24_8 : WebGLConstants.UNSIGNED_INT_24_8, - UNSIGNED_SHORT_4_4_4_4 : WebGLConstants.UNSIGNED_SHORT_4_4_4_4, - UNSIGNED_SHORT_5_5_5_1 : WebGLConstants.UNSIGNED_SHORT_5_5_5_1, - UNSIGNED_SHORT_5_6_5 : WebGLConstants.UNSIGNED_SHORT_5_6_5, + DbRootProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.DbRootProto) + return object; + var message = new $root.keyhole.dbroot.DbRootProto(); + if (object.databaseName !== undefined && object.databaseName !== null) { + if (typeof object.databaseName !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.databaseName: object expected"); + message.databaseName = $types[0].fromObject(object.databaseName); + } + if (object.imageryPresent !== undefined && object.imageryPresent !== null) + message.imageryPresent = Boolean(object.imageryPresent); + if (object.protoImagery !== undefined && object.protoImagery !== null) + message.protoImagery = Boolean(object.protoImagery); + if (object.terrainPresent !== undefined && object.terrainPresent !== null) + message.terrainPresent = Boolean(object.terrainPresent); + if (object.providerInfo) { + if (!Array.isArray(object.providerInfo)) + throw TypeError(".keyhole.dbroot.DbRootProto.providerInfo: array expected"); + message.providerInfo = []; + for (var i = 0; i < object.providerInfo.length; ++i) { + if (typeof object.providerInfo[i] !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.providerInfo: object expected"); + message.providerInfo[i] = $types[4].fromObject(object.providerInfo[i]); + } + } + if (object.nestedFeature) { + if (!Array.isArray(object.nestedFeature)) + throw TypeError(".keyhole.dbroot.DbRootProto.nestedFeature: array expected"); + message.nestedFeature = []; + for (var i = 0; i < object.nestedFeature.length; ++i) { + if (typeof object.nestedFeature[i] !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.nestedFeature: object expected"); + message.nestedFeature[i] = $types[5].fromObject(object.nestedFeature[i]); + } + } + if (object.styleAttribute) { + if (!Array.isArray(object.styleAttribute)) + throw TypeError(".keyhole.dbroot.DbRootProto.styleAttribute: array expected"); + message.styleAttribute = []; + for (var i = 0; i < object.styleAttribute.length; ++i) { + if (typeof object.styleAttribute[i] !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.styleAttribute: object expected"); + message.styleAttribute[i] = $types[6].fromObject(object.styleAttribute[i]); + } + } + if (object.styleMap) { + if (!Array.isArray(object.styleMap)) + throw TypeError(".keyhole.dbroot.DbRootProto.styleMap: array expected"); + message.styleMap = []; + for (var i = 0; i < object.styleMap.length; ++i) { + if (typeof object.styleMap[i] !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.styleMap: object expected"); + message.styleMap[i] = $types[7].fromObject(object.styleMap[i]); + } + } + if (object.endSnippet !== undefined && object.endSnippet !== null) { + if (typeof object.endSnippet !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.endSnippet: object expected"); + message.endSnippet = $types[8].fromObject(object.endSnippet); + } + if (object.translationEntry) { + if (!Array.isArray(object.translationEntry)) + throw TypeError(".keyhole.dbroot.DbRootProto.translationEntry: array expected"); + message.translationEntry = []; + for (var i = 0; i < object.translationEntry.length; ++i) { + if (typeof object.translationEntry[i] !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.translationEntry: object expected"); + message.translationEntry[i] = $types[9].fromObject(object.translationEntry[i]); + } + } + if (object.language !== undefined && object.language !== null) + message.language = String(object.language); + if (object.version !== undefined && object.version !== null) + message.version = object.version | 0; + if (object.dbrootReference) { + if (!Array.isArray(object.dbrootReference)) + throw TypeError(".keyhole.dbroot.DbRootProto.dbrootReference: array expected"); + message.dbrootReference = []; + for (var i = 0; i < object.dbrootReference.length; ++i) { + if (typeof object.dbrootReference[i] !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.dbrootReference: object expected"); + message.dbrootReference[i] = $types[12].fromObject(object.dbrootReference[i]); + } + } + if (object.databaseVersion !== undefined && object.databaseVersion !== null) { + if (typeof object.databaseVersion !== "object") + throw TypeError(".keyhole.dbroot.DbRootProto.databaseVersion: object expected"); + message.databaseVersion = $types[13].fromObject(object.databaseVersion); + } + if (object.refreshTimeout !== undefined && object.refreshTimeout !== null) + message.refreshTimeout = object.refreshTimeout | 0; + return message; + }; - isPacked : function(pixelDatatype) { - return pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8 || - pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4 || - pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1 || - pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5; - }, + DbRootProto.from = DbRootProto.fromObject; - sizeInBytes : function(pixelDatatype) { - switch (pixelDatatype) { - case PixelDatatype.UNSIGNED_BYTE: - return 1; - case PixelDatatype.UNSIGNED_SHORT: - case PixelDatatype.UNSIGNED_SHORT_4_4_4_4: - case PixelDatatype.UNSIGNED_SHORT_5_5_5_1: - case PixelDatatype.UNSIGNED_SHORT_5_6_5: - return 2; - case PixelDatatype.UNSIGNED_INT: - case PixelDatatype.FLOAT: - case PixelDatatype.UNSIGNED_INT_24_8: - return 4; - } - }, + DbRootProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.providerInfo = []; + object.nestedFeature = []; + object.styleAttribute = []; + object.styleMap = []; + object.translationEntry = []; + object.dbrootReference = []; + } + if (options.defaults) { + object.databaseName = null; + object.imageryPresent = true; + object.protoImagery = false; + object.terrainPresent = false; + object.endSnippet = null; + object.language = "en"; + object.version = 5; + object.databaseVersion = null; + object.refreshTimeout = 0; + } + if (message.databaseName !== undefined && message.databaseName !== null && message.hasOwnProperty("databaseName")) + object.databaseName = $types[0].toObject(message.databaseName, options); + if (message.imageryPresent !== undefined && message.imageryPresent !== null && message.hasOwnProperty("imageryPresent")) + object.imageryPresent = message.imageryPresent; + if (message.protoImagery !== undefined && message.protoImagery !== null && message.hasOwnProperty("protoImagery")) + object.protoImagery = message.protoImagery; + if (message.terrainPresent !== undefined && message.terrainPresent !== null && message.hasOwnProperty("terrainPresent")) + object.terrainPresent = message.terrainPresent; + if (message.providerInfo !== undefined && message.providerInfo !== null && message.hasOwnProperty("providerInfo")) { + object.providerInfo = []; + for (var j = 0; j < message.providerInfo.length; ++j) + object.providerInfo[j] = $types[4].toObject(message.providerInfo[j], options); + } + if (message.nestedFeature !== undefined && message.nestedFeature !== null && message.hasOwnProperty("nestedFeature")) { + object.nestedFeature = []; + for (var j = 0; j < message.nestedFeature.length; ++j) + object.nestedFeature[j] = $types[5].toObject(message.nestedFeature[j], options); + } + if (message.styleAttribute !== undefined && message.styleAttribute !== null && message.hasOwnProperty("styleAttribute")) { + object.styleAttribute = []; + for (var j = 0; j < message.styleAttribute.length; ++j) + object.styleAttribute[j] = $types[6].toObject(message.styleAttribute[j], options); + } + if (message.styleMap !== undefined && message.styleMap !== null && message.hasOwnProperty("styleMap")) { + object.styleMap = []; + for (var j = 0; j < message.styleMap.length; ++j) + object.styleMap[j] = $types[7].toObject(message.styleMap[j], options); + } + if (message.endSnippet !== undefined && message.endSnippet !== null && message.hasOwnProperty("endSnippet")) + object.endSnippet = $types[8].toObject(message.endSnippet, options); + if (message.translationEntry !== undefined && message.translationEntry !== null && message.hasOwnProperty("translationEntry")) { + object.translationEntry = []; + for (var j = 0; j < message.translationEntry.length; ++j) + object.translationEntry[j] = $types[9].toObject(message.translationEntry[j], options); + } + if (message.language !== undefined && message.language !== null && message.hasOwnProperty("language")) + object.language = message.language; + if (message.version !== undefined && message.version !== null && message.hasOwnProperty("version")) + object.version = message.version; + if (message.dbrootReference !== undefined && message.dbrootReference !== null && message.hasOwnProperty("dbrootReference")) { + object.dbrootReference = []; + for (var j = 0; j < message.dbrootReference.length; ++j) + object.dbrootReference[j] = $types[12].toObject(message.dbrootReference[j], options); + } + if (message.databaseVersion !== undefined && message.databaseVersion !== null && message.hasOwnProperty("databaseVersion")) + object.databaseVersion = $types[13].toObject(message.databaseVersion, options); + if (message.refreshTimeout !== undefined && message.refreshTimeout !== null && message.hasOwnProperty("refreshTimeout")) + object.refreshTimeout = message.refreshTimeout; + return object; + }; - validate : function(pixelDatatype) { - return ((pixelDatatype === PixelDatatype.UNSIGNED_BYTE) || - (pixelDatatype === PixelDatatype.UNSIGNED_SHORT) || - (pixelDatatype === PixelDatatype.UNSIGNED_INT) || - (pixelDatatype === PixelDatatype.FLOAT) || - (pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8) || - (pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4) || - (pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1) || - (pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5)); - } - }; + DbRootProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - return freezeObject(PixelDatatype); -}); + DbRootProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; -define('Core/PixelFormat',[ - '../Renderer/PixelDatatype', - './freezeObject', - './WebGLConstants' - ], function( - PixelDatatype, - freezeObject, - WebGLConstants) { - 'use strict'; - - /** - * The format of a pixel, i.e., the number of components it has and what they represent. - * - * @exports PixelFormat - */ - var PixelFormat = { - /** - * A pixel format containing a depth value. - * - * @type {Number} - * @constant - */ - DEPTH_COMPONENT : WebGLConstants.DEPTH_COMPONENT, - - /** - * A pixel format containing a depth and stencil value, most often used with {@link PixelDatatype.UNSIGNED_INT_24_8}. - * - * @type {Number} - * @constant - */ - DEPTH_STENCIL : WebGLConstants.DEPTH_STENCIL, - - /** - * A pixel format containing an alpha channel. - * - * @type {Number} - * @constant - */ - ALPHA : WebGLConstants.ALPHA, - - /** - * A pixel format containing red, green, and blue channels. - * - * @type {Number} - * @constant - */ - RGB : WebGLConstants.RGB, - - /** - * A pixel format containing red, green, blue, and alpha channels. - * - * @type {Number} - * @constant - */ - RGBA : WebGLConstants.RGBA, - - /** - * A pixel format containing a luminance (intensity) channel. - * - * @type {Number} - * @constant - */ - LUMINANCE : WebGLConstants.LUMINANCE, - - /** - * A pixel format containing luminance (intensity) and alpha channels. - * - * @type {Number} - * @constant - */ - LUMINANCE_ALPHA : WebGLConstants.LUMINANCE_ALPHA, - - /** - * A pixel format containing red, green, and blue channels that is DXT1 compressed. - * - * @type {Number} - * @constant - */ - RGB_DXT1 : WebGLConstants.COMPRESSED_RGB_S3TC_DXT1_EXT, - - /** - * A pixel format containing red, green, blue, and alpha channels that is DXT1 compressed. - * - * @type {Number} - * @constant - */ - RGBA_DXT1 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT1_EXT, - - /** - * A pixel format containing red, green, blue, and alpha channels that is DXT3 compressed. - * - * @type {Number} - * @constant - */ - RGBA_DXT3 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT3_EXT, - - /** - * A pixel format containing red, green, blue, and alpha channels that is DXT5 compressed. - * - * @type {Number} - * @constant - */ - RGBA_DXT5 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT5_EXT, - - /** - * A pixel format containing red, green, and blue channels that is PVR 4bpp compressed. - * - * @type {Number} - * @constant - */ - RGB_PVRTC_4BPPV1 : WebGLConstants.COMPRESSED_RGB_PVRTC_4BPPV1_IMG, - - /** - * A pixel format containing red, green, and blue channels that is PVR 2bpp compressed. - * - * @type {Number} - * @constant - */ - RGB_PVRTC_2BPPV1 : WebGLConstants.COMPRESSED_RGB_PVRTC_2BPPV1_IMG, + return DbRootProto; + })(); - /** - * A pixel format containing red, green, blue, and alpha channels that is PVR 4bpp compressed. - * - * @type {Number} - * @constant - */ - RGBA_PVRTC_4BPPV1 : WebGLConstants.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, + dbroot.EncryptedDbRootProto = (function() { - /** - * A pixel format containing red, green, blue, and alpha channels that is PVR 2bpp compressed. - * - * @type {Number} - * @constant - */ - RGBA_PVRTC_2BPPV1 : WebGLConstants.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, + function EncryptedDbRootProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + this[keys[i]] = properties[keys[i]]; + } - /** - * A pixel format containing red, green, and blue channels that is ETC1 compressed. - * - * @type {Number} - * @constant - */ - RGB_ETC1 : WebGLConstants.COMPRESSED_RGB_ETC1_WEBGL, + EncryptedDbRootProto.prototype.encryptionType = 0; + EncryptedDbRootProto.prototype.encryptionData = $util.newBuffer([]); + EncryptedDbRootProto.prototype.dbrootData = $util.newBuffer([]); - /** - * @private - */ - componentsLength : function(pixelFormat) { - switch (pixelFormat) { - // Many GPUs store RGB as RGBA internally - // https://devtalk.nvidia.com/default/topic/699479/general-graphics-programming/rgb-auto-converted-to-rgba/post/4142379/#4142379 - case PixelFormat.RGB: - case PixelFormat.RGBA: - return 4; - case PixelFormat.LUMINANCE_ALPHA: - return 2; - case PixelFormat.ALPHA: - case PixelFormat.LUMINANCE: - return 1; - default: - return 1; - } - }, + var $types = { + 0 : "keyhole.dbroot.EncryptedDbRootProto.EncryptionType" + }; + $lazyTypes.push($types); - /** - * @private - */ - validate : function(pixelFormat) { - return pixelFormat === PixelFormat.DEPTH_COMPONENT || - pixelFormat === PixelFormat.DEPTH_STENCIL || - pixelFormat === PixelFormat.ALPHA || - pixelFormat === PixelFormat.RGB || - pixelFormat === PixelFormat.RGBA || - pixelFormat === PixelFormat.LUMINANCE || - pixelFormat === PixelFormat.LUMINANCE_ALPHA || - pixelFormat === PixelFormat.RGB_DXT1 || - pixelFormat === PixelFormat.RGBA_DXT1 || - pixelFormat === PixelFormat.RGBA_DXT3 || - pixelFormat === PixelFormat.RGBA_DXT5 || - pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 || - pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || - pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGB_ETC1; - }, + EncryptedDbRootProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.keyhole.dbroot.EncryptedDbRootProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.encryptionType = reader.uint32(); + break; + case 2: + message.encryptionData = reader.bytes(); + break; + case 3: + message.dbrootData = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; - /** - * @private - */ - isColorFormat : function(pixelFormat) { - return pixelFormat === PixelFormat.ALPHA || - pixelFormat === PixelFormat.RGB || - pixelFormat === PixelFormat.RGBA || - pixelFormat === PixelFormat.LUMINANCE || - pixelFormat === PixelFormat.LUMINANCE_ALPHA; - }, + EncryptedDbRootProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.encryptionType !== undefined) + switch (message.encryptionType) { + default: + return "encryptionType: enum value expected"; + case 0: + break; + } + if (message.encryptionData !== undefined) + if (!(message.encryptionData && typeof message.encryptionData.length === "number" || $util.isString(message.encryptionData))) + return "encryptionData: buffer expected"; + if (message.dbrootData !== undefined) + if (!(message.dbrootData && typeof message.dbrootData.length === "number" || $util.isString(message.dbrootData))) + return "dbrootData: buffer expected"; + return null; + }; - /** - * @private - */ - isDepthFormat : function(pixelFormat) { - return pixelFormat === PixelFormat.DEPTH_COMPONENT || - pixelFormat === PixelFormat.DEPTH_STENCIL; - }, + EncryptedDbRootProto.fromObject = function fromObject(object) { + if (object instanceof $root.keyhole.dbroot.EncryptedDbRootProto) + return object; + var message = new $root.keyhole.dbroot.EncryptedDbRootProto(); + switch (object.encryptionType) { + case "ENCRYPTION_XOR": + case 0: + message.encryptionType = 0; + break; + } + if (object.encryptionData !== undefined && object.encryptionData !== null) + if (typeof object.encryptionData === "string") + $util.base64.decode(object.encryptionData, message.encryptionData = $util.newBuffer($util.base64.length(object.encryptionData)), 0); + else if (object.encryptionData.length) + message.encryptionData = object.encryptionData; + if (object.dbrootData !== undefined && object.dbrootData !== null) + if (typeof object.dbrootData === "string") + $util.base64.decode(object.dbrootData, message.dbrootData = $util.newBuffer($util.base64.length(object.dbrootData)), 0); + else if (object.dbrootData.length) + message.dbrootData = object.dbrootData; + return message; + }; - /** - * @private - */ - isCompressedFormat : function(pixelFormat) { - return pixelFormat === PixelFormat.RGB_DXT1 || - pixelFormat === PixelFormat.RGBA_DXT1 || - pixelFormat === PixelFormat.RGBA_DXT3 || - pixelFormat === PixelFormat.RGBA_DXT5 || - pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 || - pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || - pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGB_ETC1; - }, + EncryptedDbRootProto.from = EncryptedDbRootProto.fromObject; - /** - * @private - */ - isDXTFormat : function(pixelFormat) { - return pixelFormat === PixelFormat.RGB_DXT1 || - pixelFormat === PixelFormat.RGBA_DXT1 || - pixelFormat === PixelFormat.RGBA_DXT3 || - pixelFormat === PixelFormat.RGBA_DXT5; - }, + EncryptedDbRootProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.encryptionType = options.enums === String ? "ENCRYPTION_XOR" : 0; + object.encryptionData = options.bytes === String ? "" : []; + object.dbrootData = options.bytes === String ? "" : []; + } + if (message.encryptionType !== undefined && message.encryptionType !== null && message.hasOwnProperty("encryptionType")) + object.encryptionType = options.enums === String ? $types[0][message.encryptionType] : message.encryptionType; + if (message.encryptionData !== undefined && message.encryptionData !== null && message.hasOwnProperty("encryptionData")) + object.encryptionData = options.bytes === String ? $util.base64.encode(message.encryptionData, 0, message.encryptionData.length) : options.bytes === Array ? Array.prototype.slice.call(message.encryptionData) : message.encryptionData; + if (message.dbrootData !== undefined && message.dbrootData !== null && message.hasOwnProperty("dbrootData")) + object.dbrootData = options.bytes === String ? $util.base64.encode(message.dbrootData, 0, message.dbrootData.length) : options.bytes === Array ? Array.prototype.slice.call(message.dbrootData) : message.dbrootData; + return object; + }; - /** - * @private - */ - isPVRTCFormat : function(pixelFormat) { - return pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 || - pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || - pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1; - }, + EncryptedDbRootProto.prototype.toObject = function toObject(options) { + return this.constructor.toObject(this, options); + }; - /** - * @private - */ - isETC1Format : function(pixelFormat) { - return pixelFormat === PixelFormat.RGB_ETC1; - }, + EncryptedDbRootProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - /** - * @private - */ - compressedTextureSizeInBytes : function(pixelFormat, width, height) { - switch (pixelFormat) { - case PixelFormat.RGB_DXT1: - case PixelFormat.RGBA_DXT1: - case PixelFormat.RGB_ETC1: - return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; + EncryptedDbRootProto.EncryptionType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values["ENCRYPTION_XOR"] = 0; + return values; + })(); - case PixelFormat.RGBA_DXT3: - case PixelFormat.RGBA_DXT5: - return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; + return EncryptedDbRootProto; + })(); - case PixelFormat.RGB_PVRTC_4BPPV1: - case PixelFormat.RGBA_PVRTC_4BPPV1: - return Math.floor((Math.max(width, 8) * Math.max(height, 8) * 4 + 7) / 8); + return dbroot; + })(); - case PixelFormat.RGB_PVRTC_2BPPV1: - case PixelFormat.RGBA_PVRTC_2BPPV1: - return Math.floor((Math.max(width, 16) * Math.max(height, 8) * 2 + 7) / 8); + return keyhole; + })(); - default: - return 0; - } - }, + $util.lazyResolve($root, $lazyTypes); - /** - * @private - */ - textureSizeInBytes : function(pixelFormat, pixelDatatype, width, height) { - var componentsLength = PixelFormat.componentsLength(pixelFormat); - if (PixelDatatype.isPacked(pixelDatatype)) { - componentsLength = 1; - } - return componentsLength * PixelDatatype.sizeInBytes(pixelDatatype) * width * height; - } - }; + // End generated code - return freezeObject(PixelFormat); + return $root.keyhole.dbroot; }); -define('Core/loadKTX',[ - '../ThirdParty/when', - './Check', - './CompressedTextureBuffer', - './defined', - './loadArrayBuffer', - './PixelFormat', - './RuntimeError' - ], function( - when, - Check, - CompressedTextureBuffer, - defined, - loadArrayBuffer, - PixelFormat, - RuntimeError) { +define('Core/isBitSet',[], function() { 'use strict'; /** - * Asynchronously loads and parses the given URL to a KTX file or parses the raw binary data of a KTX file. - * Returns a promise that will resolve to an object containing the image buffer, width, height and format once loaded, - * or reject if the URL failed to load or failed to parse the data. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * <p> - * The following are part of the KTX format specification but are not supported: - * <ul> - * <li>Big-endian files</li> - * <li>Metadata</li> - * <li>3D textures</li> - * <li>Texture Arrays</li> - * <li>Cubemaps</li> - * <li>Mipmaps</li> - * </ul> - * </p> - * - * @exports loadKTX - * - * @param {String|ArrayBuffer} urlOrBuffer The URL of the binary data or an ArrayBuffer. - * @param {Object} [headers] HTTP headers to send with the requests. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<CompressedTextureBuffer>|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * @exception {RuntimeError} Invalid KTX file. - * @exception {RuntimeError} File is the wrong endianness. - * @exception {RuntimeError} glInternalFormat is not a valid format. - * @exception {RuntimeError} glType must be zero when the texture is compressed. - * @exception {RuntimeError} The type size for compressed textures must be 1. - * @exception {RuntimeError} glFormat must be zero when the texture is compressed. - * @exception {RuntimeError} Generating mipmaps for a compressed texture is unsupported. - * @exception {RuntimeError} The base internal format must be the same as the format for uncompressed textures. - * @exception {RuntimeError} 3D textures are not supported. - * @exception {RuntimeError} Texture arrays are not supported. - * @exception {RuntimeError} Cubemaps are not supported. - * - * @example - * // load a single URL asynchronously - * Cesium.loadKTX('some/url').then(function(ktxData) { - * var width = ktxData.width; - * var height = ktxData.height; - * var format = ktxData.internalFormat; - * var arrayBufferView = ktxData.bufferView; - * // use the data to create a texture - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/|KTX file format} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadKTX(urlOrBuffer, headers, request) { - Check.defined('urlOrBuffer', urlOrBuffer); - - var loadPromise; - if (urlOrBuffer instanceof ArrayBuffer || ArrayBuffer.isView(urlOrBuffer)) { - loadPromise = when.resolve(urlOrBuffer); - } else { - loadPromise = loadArrayBuffer(urlOrBuffer, headers, request); - } - - if (!defined(loadPromise)) { - return undefined; - } - - return loadPromise.then(function(data) { - if (defined(data)) { - return parseKTX(data); - } - }); - } - - var fileIdentifier = [0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A]; - var endiannessTest = 0x04030201; - - var sizeOfUint32 = 4; - - function parseKTX(data) { - var byteBuffer = new Uint8Array(data); - - var isKTX = true; - for (var i = 0; i < fileIdentifier.length; ++i) { - if (fileIdentifier[i] !== byteBuffer[i]) { - isKTX = false; - break; - } - } - - if (!isKTX) { - throw new RuntimeError('Invalid KTX file.'); - } - - var view; - var byteOffset; - - if (defined(data.buffer)) { - view = new DataView(data.buffer); - byteOffset = data.byteOffset; - } else { - view = new DataView(data); - byteOffset = 0; - } - - byteOffset += 12; // skip identifier - - var endianness = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - if (endianness !== endiannessTest) { - throw new RuntimeError('File is the wrong endianness.'); - } - - var glType = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glTypeSize = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glFormat = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glInternalFormat = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glBaseInternalFormat = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var pixelWidth = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var pixelHeight = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var pixelDepth = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var numberOfArrayElements = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var numberOfFaces = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var numberOfMipmapLevels = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var bytesOfKeyValueByteSize = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - - // skip metadata - byteOffset += bytesOfKeyValueByteSize; - - var imageSize = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - - var texture; - if (defined(data.buffer)) { - texture = new Uint8Array(data.buffer, byteOffset, imageSize); - } else { - texture = new Uint8Array(data, byteOffset, imageSize); - } - - // Some tools use a sized internal format. - // See table 2: https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml - if (glInternalFormat === 0x8051) { // GL_RGB8 - glInternalFormat = PixelFormat.RGB; - } else if (glInternalFormat === 0x8058) { // GL_RGBA8 - glInternalFormat = PixelFormat.RGBA; - } - - if (!PixelFormat.validate(glInternalFormat)) { - throw new RuntimeError('glInternalFormat is not a valid format.'); - } - - if (PixelFormat.isCompressedFormat(glInternalFormat)) { - if (glType !== 0) { - throw new RuntimeError('glType must be zero when the texture is compressed.'); - } - if (glTypeSize !== 1) { - throw new RuntimeError('The type size for compressed textures must be 1.'); - } - if (glFormat !== 0) { - throw new RuntimeError('glFormat must be zero when the texture is compressed.'); - } - } else if (glBaseInternalFormat !== glFormat) { - throw new RuntimeError('The base internal format must be the same as the format for uncompressed textures.'); - } - - if (pixelDepth !== 0) { - throw new RuntimeError('3D textures are unsupported.'); - } - - if (numberOfArrayElements !== 0) { - throw new RuntimeError('Texture arrays are unsupported.'); - } - if (numberOfFaces !== 1) { - throw new RuntimeError('Cubemaps are unsupported.'); - } - - // Only use the level 0 mipmap - if (numberOfMipmapLevels > 1) { - var levelSize = PixelFormat.isCompressedFormat(glInternalFormat) ? - PixelFormat.compressedTextureSizeInBytes(glInternalFormat, pixelWidth, pixelHeight) : - PixelFormat.textureSizeInBytes(glInternalFormat, pixelWidth, pixelHeight); - texture = new Uint8Array(texture.buffer, texture.byteOffset, levelSize); - } - - return new CompressedTextureBuffer(glInternalFormat, pixelWidth, pixelHeight, texture); + function isBitSet(bits, mask) { + return ((bits & mask) !== 0); } - return loadKTX; + return isBitSet; }); -define('Core/loadXML',[ - './loadWithXhr' +define('Core/GoogleEarthEnterpriseTileInformation',[ + './defined', + './isBitSet' ], function( - loadWithXhr) { + defined, + isBitSet) { 'use strict'; - /** - * Asynchronously loads the given URL as XML. Returns a promise that will resolve to - * an XML Document once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadXML - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load XML from a URL, setting a custom header - * Cesium.loadXML('http://someUrl.com/someXML.xml', { - * 'X-Custom-Header' : 'some value' - * }).then(function(document) { - * // Do something with the document - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - */ - function loadXML(url, headers, request) { - return loadWithXhr({ - url : url, - responseType : 'document', - headers : headers, - overrideMimeType : 'text/xml', - request : request - }); - } - - return loadXML; -}); - -define('Core/ManagedArray',[ - './Check', - './defaultValue', - './defineProperties' - ], function( - Check, - defaultValue, - defineProperties) { - 'use strict'; + // Bitmask for checking tile properties + var childrenBitmasks = [0x01, 0x02, 0x04, 0x08]; + var anyChildBitmask = 0x0F; + var cacheFlagBitmask = 0x10; // True if there is a child subtree + var imageBitmask = 0x40; + var terrainBitmask = 0x80; /** - * A wrapper around arrays so that the internal length of the array can be manually managed. + * Contains information about each tile from a Google Earth Enterprise server * - * @alias ManagedArray - * @constructor - * @private + * @param {Number} bits Bitmask that contains the type of data and available children for each tile. + * @param {Number} cnodeVersion Version of the request for subtree metadata. + * @param {Number} imageryVersion Version of the request for imagery tile. + * @param {Number} terrainVersion Version of the request for terrain tile. + * @param {Number} imageryProvider Id of imagery provider. + * @param {Number} terrainProvider Id of terrain provider. * - * @param {Number} [length=0] The initial length of the array. + * @private */ - function ManagedArray(length) { - length = defaultValue(length, 0); - this._array = new Array(length); - this._length = length; + function GoogleEarthEnterpriseTileInformation(bits, cnodeVersion, imageryVersion, terrainVersion, imageryProvider, terrainProvider) { + this._bits = bits; + this.cnodeVersion = cnodeVersion; + this.imageryVersion = imageryVersion; + this.terrainVersion = terrainVersion; + this.imageryProvider = imageryProvider; + this.terrainProvider = terrainProvider; + this.ancestorHasTerrain = false; // Set it later once we find its parent + this.terrainState = undefined; } - defineProperties(ManagedArray.prototype, { - /** - * Gets or sets the length of the array. - * If the set length is greater than the length of the internal array, the internal array is resized. - * - * @type Number - */ - length : { - get : function() { - return this._length; - }, - set : function(length) { - this._length = length; - if (length > this._array.length) { - this._array.length = length; - } - } - }, - - /** - * Gets the internal array. - * - * @type Array - * @readonly - */ - values : { - get : function() { - return this._array; - } - } - }); - - /** - * Gets the element at an index. - * - * @param {Number} index The index to get. - */ - ManagedArray.prototype.get = function(index) { - Check.typeOf.number.lessThan('index', index, this._array.length); - - return this._array[index]; - }; - /** - * Sets the element at an index. Resizes the array if index is greater than the length of the array. + * Creates GoogleEarthEnterpriseTileInformation from an object * - * @param {Number} index The index to set. - * @param {*} value The value to set at index. + * @param {Object} info Object to be cloned + * @param {GoogleEarthEnterpriseTileInformation} [result] The object onto which to store the result. + * @returns {GoogleEarthEnterpriseTileInformation} The modified result parameter or a new GoogleEarthEnterpriseTileInformation instance if none was provided. */ - ManagedArray.prototype.set = function(index, value) { - Check.typeOf.number('index', index); - - if (index >= this.length) { - this.length = index + 1; + GoogleEarthEnterpriseTileInformation.clone = function(info, result) { + if (!defined(result)) { + result = new GoogleEarthEnterpriseTileInformation(info._bits, info.cnodeVersion, info.imageryVersion, info.terrainVersion, + info.imageryProvider, info.terrainProvider); + } else { + result._bits = info._bits; + result.cnodeVersion = info.cnodeVersion; + result.imageryVersion = info.imageryVersion; + result.terrainVersion = info.terrainVersion; + result.imageryProvider = info.imageryProvider; + result.terrainProvider = info.terrainProvider; } - this._array[index] = value; - }; + result.ancestorHasTerrain = info.ancestorHasTerrain; + result.terrainState = info.terrainState; - /** - * Push an element into the array. - */ - ManagedArray.prototype.push = function(element) { - var index = this.length++; - this._array[index] = element; + return result; }; /** - * Pop an element from the array. + * Sets the parent for the tile * - * @returns {*} The last element in the array. + * @param {GoogleEarthEnterpriseTileInformation} parent Parent tile */ - ManagedArray.prototype.pop = function() { - return this._array[--this.length]; + GoogleEarthEnterpriseTileInformation.prototype.setParent = function(parent) { + this.ancestorHasTerrain = parent.ancestorHasTerrain || this.hasTerrain(); }; /** - * Resize the internal array if length > _array.length. + * Gets whether a subtree is available * - * @param {Number} length The length. + * @returns {Boolean} true if subtree is available, false otherwise. */ - ManagedArray.prototype.reserve = function(length) { - Check.typeOf.number.greaterThanOrEquals('length', length, 0); - - if (length > this._array.length) { - this._array.length = length; - } + GoogleEarthEnterpriseTileInformation.prototype.hasSubtree = function() { + return isBitSet(this._bits, cacheFlagBitmask); }; /** - * Resize the array. + * Gets whether imagery is available * - * @param {Number} length The length. + * @returns {Boolean} true if imagery is available, false otherwise. */ - ManagedArray.prototype.resize = function(length) { - Check.typeOf.number.greaterThanOrEquals('length', length, 0); - - this.length = length; + GoogleEarthEnterpriseTileInformation.prototype.hasImagery = function() { + return isBitSet(this._bits, imageBitmask); }; /** - * Trim the internal array to the specified length. Defaults to the current length. + * Gets whether terrain is available * - * @param {Number} [length] The length. + * @returns {Boolean} true if terrain is available, false otherwise. */ - ManagedArray.prototype.trim = function(length) { - length = defaultValue(length, this.length); - this._array.length = length; + GoogleEarthEnterpriseTileInformation.prototype.hasTerrain = function() { + return isBitSet(this._bits, terrainBitmask); }; - return ManagedArray; -}); - -define('Core/MapboxApi',[ - './Credit', - './defined' -], function( - Credit, - defined) { - 'use strict'; - - var MapboxApi = {}; - /** - * The default Mapbox API access token to use if one is not provided to the - * constructor of an object that uses the Mapbox API. If this property is undefined, - * Cesium's default access token is used, which is only suitable for use early in development. - * Please supply your own access token as soon as possible and prior to deployment. - * Visit {@link https://www.mapbox.com/help/create-api-access-token/} for details. - * When Cesium's default access token is used, a message is printed to the console the first - * time the Mapbox API is used. + * Gets whether any children are present * - * @type {String} + * @returns {Boolean} true if any children are available, false otherwise. */ - MapboxApi.defaultAccessToken = undefined; - - var printedMapboxWarning = false; - var errorCredit; - var errorString = 'This application is using Cesium\'s default Mapbox access token. Please create a new access token for the application as soon as possible and prior to deployment by visiting https://www.mapbox.com/account/apps/, and provide your token to Cesium by setting the Cesium.MapboxApi.defaultAccessToken property before constructing the CesiumWidget or any other object that uses the Mapbox API.'; - - MapboxApi.getAccessToken = function(providedToken) { - if (defined(providedToken)) { - return providedToken; - } - - if (!defined(MapboxApi.defaultAccessToken)) { - if (!printedMapboxWarning) { - console.log(errorString); - printedMapboxWarning = true; - } - return 'pk.eyJ1IjoiYW5hbHl0aWNhbGdyYXBoaWNzIiwiYSI6ImNpd204Zm4wejAwNzYyeW5uNjYyZmFwdWEifQ.7i-VIZZWX8pd1bTfxIVj9g'; - } - - return MapboxApi.defaultAccessToken; - }; - - MapboxApi.getErrorCredit = function(providedToken) { - if (defined(providedToken) || defined(MapboxApi.defaultAccessToken)) { - return undefined; - } - - if (!defined(errorCredit)) { - errorCredit = new Credit({ - text : errorString, - showOnScreen : true - }); - } - - return errorCredit; + GoogleEarthEnterpriseTileInformation.prototype.hasChildren = function() { + return isBitSet(this._bits, anyChildBitmask); }; - return MapboxApi; -}); - -define('Core/MapProjection',[ - './defineProperties', - './DeveloperError' - ], function( - defineProperties, - DeveloperError) { - 'use strict'; - /** - * Defines how geodetic ellipsoid coordinates ({@link Cartographic}) project to a - * flat map like Cesium's 2D and Columbus View modes. - * - * @alias MapProjection - * @constructor - * - * @see GeographicProjection - * @see WebMercatorProjection - */ - function MapProjection() { - DeveloperError.throwInstantiationError(); - } - - defineProperties(MapProjection.prototype, { - /** - * Gets the {@link Ellipsoid}. - * - * @memberof MapProjection.prototype - * - * @type {Ellipsoid} - * @readonly - */ - ellipsoid : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Projects {@link Cartographic} coordinates, in radians, to projection-specific map coordinates, in meters. + * Gets whether a specified child is available * - * @memberof MapProjection - * @function + * @param {Number} index Index of child tile * - * @param {Cartographic} cartographic The coordinates to project. - * @param {Cartesian3} [result] An instance into which to copy the result. If this parameter is - * undefined, a new instance is created and returned. - * @returns {Cartesian3} The projected coordinates. If the result parameter is not undefined, the - * coordinates are copied there and that instance is returned. Otherwise, a new instance is - * created and returned. + * @returns {Boolean} true if child is available, false otherwise */ - MapProjection.prototype.project = DeveloperError.throwInstantiationError; + GoogleEarthEnterpriseTileInformation.prototype.hasChild = function(index) { + return isBitSet(this._bits, childrenBitmasks[index]); + }; /** - * Unprojects projection-specific map {@link Cartesian3} coordinates, in meters, to {@link Cartographic} - * coordinates, in radians. - * - * @memberof MapProjection - * @function + * Gets bitmask containing children * - * @param {Cartesian3} cartesian The Cartesian position to unproject with height (z) in meters. - * @param {Cartographic} [result] An instance into which to copy the result. If this parameter is - * undefined, a new instance is created and returned. - * @returns {Cartographic} The unprojected coordinates. If the result parameter is not undefined, the - * coordinates are copied there and that instance is returned. Otherwise, a new instance is - * created and returned. + * @returns {Number} Children bitmask */ - MapProjection.prototype.unproject = DeveloperError.throwInstantiationError; + GoogleEarthEnterpriseTileInformation.prototype.getChildBitmask = function() { + return this._bits & anyChildBitmask; + }; - return MapProjection; + return GoogleEarthEnterpriseTileInformation; }); -define('Core/Matrix2',[ - './Cartesian2', +define('Core/GoogleEarthEnterpriseMetadata',[ + '../ThirdParty/google-earth-dbroot-parser', + '../ThirdParty/when', + './appendForwardSlash', './Check', + './Credit', './defaultValue', './defined', './defineProperties', - './freezeObject' + './deprecationWarning', + './GoogleEarthEnterpriseTileInformation', + './isBitSet', + './Math', + './Request', + './Resource', + './RuntimeError', + './TaskProcessor' ], function( - Cartesian2, + dbrootParser, + when, + appendForwardSlash, Check, + Credit, defaultValue, defined, defineProperties, - freezeObject) { + deprecationWarning, + GoogleEarthEnterpriseTileInformation, + isBitSet, + CesiumMath, + Request, + Resource, + RuntimeError, + TaskProcessor) { 'use strict'; - /** - * A 2x2 matrix, indexable as a column-major order array. - * Constructor parameters are in row-major order for code readability. - * @alias Matrix2 - * @constructor - * - * @param {Number} [column0Row0=0.0] The value for column 0, row 0. - * @param {Number} [column1Row0=0.0] The value for column 1, row 0. - * @param {Number} [column0Row1=0.0] The value for column 0, row 1. - * @param {Number} [column1Row1=0.0] The value for column 1, row 1. - * - * @see Matrix2.fromColumnMajorArray - * @see Matrix2.fromRowMajorArray - * @see Matrix2.fromScale - * @see Matrix2.fromUniformScale - * @see Matrix3 - * @see Matrix4 - */ - function Matrix2(column0Row0, column1Row0, column0Row1, column1Row1) { - this[0] = defaultValue(column0Row0, 0.0); - this[1] = defaultValue(column0Row1, 0.0); - this[2] = defaultValue(column1Row0, 0.0); - this[3] = defaultValue(column1Row1, 0.0); + function stringToBuffer(str) { + var len = str.length; + var buffer = new ArrayBuffer(len); + var ui8 = new Uint8Array(buffer); + for (var i = 0; i < len; ++i) { + ui8[i] = str.charCodeAt(i); + } + + return buffer; } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - Matrix2.packedLength = 4; + // Decodes packet with a key that has been around since the beginning of Google Earth Enterprise + var defaultKey = stringToBuffer('\x45\xf4\xbd\x0b\x79\xe2\x6a\x45\x22\x05\x92\x2c\x17\xcd\x06\x71\xf8\x49\x10\x46\x67\x51\x00\x42\x25\xc6\xe8\x61\x2c\x66\x29\x08\xc6\x34\xdc\x6a\x62\x25\x79\x0a\x77\x1d\x6d\x69\xd6\xf0\x9c\x6b\x93\xa1\xbd\x4e\x75\xe0\x41\x04\x5b\xdf\x40\x56\x0c\xd9\xbb\x72\x9b\x81\x7c\x10\x33\x53\xee\x4f\x6c\xd4\x71\x05\xb0\x7b\xc0\x7f\x45\x03\x56\x5a\xad\x77\x55\x65\x0b\x33\x92\x2a\xac\x19\x6c\x35\x14\xc5\x1d\x30\x73\xf8\x33\x3e\x6d\x46\x38\x4a\xb4\xdd\xf0\x2e\xdd\x17\x75\x16\xda\x8c\x44\x74\x22\x06\xfa\x61\x22\x0c\x33\x22\x53\x6f\xaf\x39\x44\x0b\x8c\x0e\x39\xd9\x39\x13\x4c\xb9\xbf\x7f\xab\x5c\x8c\x50\x5f\x9f\x22\x75\x78\x1f\xe9\x07\x71\x91\x68\x3b\xc1\xc4\x9b\x7f\xf0\x3c\x56\x71\x48\x82\x05\x27\x55\x66\x59\x4e\x65\x1d\x98\x75\xa3\x61\x46\x7d\x61\x3f\x15\x41\x00\x9f\x14\x06\xd7\xb4\x34\x4d\xce\x13\x87\x46\xb0\x1a\xd5\x05\x1c\xb8\x8a\x27\x7b\x8b\xdc\x2b\xbb\x4d\x67\x30\xc8\xd1\xf6\x5c\x8f\x50\xfa\x5b\x2f\x46\x9b\x6e\x35\x18\x2f\x27\x43\x2e\xeb\x0a\x0c\x5e\x10\x05\x10\xa5\x73\x1b\x65\x34\xe5\x6c\x2e\x6a\x43\x27\x63\x14\x23\x55\xa9\x3f\x71\x7b\x67\x43\x7d\x3a\xaf\xcd\xe2\x54\x55\x9c\xfd\x4b\xc6\xe2\x9f\x2f\x28\xed\xcb\x5c\xc6\x2d\x66\x07\x88\xa7\x3b\x2f\x18\x2a\x22\x4e\x0e\xb0\x6b\x2e\xdd\x0d\x95\x7d\x7d\x47\xba\x43\xb2\x11\xb2\x2b\x3e\x4d\xaa\x3e\x7d\xe6\xce\x49\x89\xc6\xe6\x78\x0c\x61\x31\x05\x2d\x01\xa4\x4f\xa5\x7e\x71\x20\x88\xec\x0d\x31\xe8\x4e\x0b\x00\x6e\x50\x68\x7d\x17\x3d\x08\x0d\x17\x95\xa6\x6e\xa3\x68\x97\x24\x5b\x6b\xf3\x17\x23\xf3\xb6\x73\xb3\x0d\x0b\x40\xc0\x9f\xd8\x04\x51\x5d\xfa\x1a\x17\x22\x2e\x15\x6a\xdf\x49\x00\xb9\xa0\x77\x55\xc6\xef\x10\x6a\xbf\x7b\x47\x4c\x7f\x83\x17\x05\xee\xdc\xdc\x46\x85\xa9\xad\x53\x07\x2b\x53\x34\x06\x07\xff\x14\x94\x59\x19\x02\xe4\x38\xe8\x31\x83\x4e\xb9\x58\x46\x6b\xcb\x2d\x23\x86\x92\x70\x00\x35\x88\x22\xcf\x31\xb2\x26\x2f\xe7\xc3\x75\x2d\x36\x2c\x72\x74\xb0\x23\x47\xb7\xd3\xd1\x26\x16\x85\x37\x72\xe2\x00\x8c\x44\xcf\x10\xda\x33\x2d\x1a\xde\x60\x86\x69\x23\x69\x2a\x7c\xcd\x4b\x51\x0d\x95\x54\x39\x77\x2e\x29\xea\x1b\xa6\x50\xa2\x6a\x8f\x6f\x50\x99\x5c\x3e\x54\xfb\xef\x50\x5b\x0b\x07\x45\x17\x89\x6d\x28\x13\x77\x37\x1d\xdb\x8e\x1e\x4a\x05\x66\x4a\x6f\x99\x20\xe5\x70\xe2\xb9\x71\x7e\x0c\x6d\x49\x04\x2d\x7a\xfe\x72\xc7\xf2\x59\x30\x8f\xbb\x02\x5d\x73\xe5\xc9\x20\xea\x78\xec\x20\x90\xf0\x8a\x7f\x42\x17\x7c\x47\x19\x60\xb0\x16\xbd\x26\xb7\x71\xb6\xc7\x9f\x0e\xd1\x33\x82\x3d\xd3\xab\xee\x63\x99\xc8\x2b\x53\xa0\x44\x5c\x71\x01\xc6\xcc\x44\x1f\x32\x4f\x3c\xca\xc0\x29\x3d\x52\xd3\x61\x19\x58\xa9\x7d\x65\xb4\xdc\xcf\x0d\xf4\x3d\xf1\x08\xa9\x42\xda\x23\x09\xd8\xbf\x5e\x50\x49\xf8\x4d\xc0\xcb\x47\x4c\x1c\x4f\xf7\x7b\x2b\xd8\x16\x18\xc5\x31\x92\x3b\xb5\x6f\xdc\x6c\x0d\x92\x88\x16\xd1\x9e\xdb\x3f\xe2\xe9\xda\x5f\xd4\x84\xe2\x46\x61\x5a\xde\x1c\x55\xcf\xa4\x00\xbe\xfd\xce\x67\xf1\x4a\x69\x1c\x97\xe6\x20\x48\xd8\x5d\x7f\x7e\xae\x71\x20\x0e\x4e\xae\xc0\x56\xa9\x91\x01\x3c\x82\x1d\x0f\x72\xe7\x76\xec\x29\x49\xd6\x5d\x2d\x83\xe3\xdb\x36\x06\xa9\x3b\x66\x13\x97\x87\x6a\xd5\xb6\x3d\x50\x5e\x52\xb9\x4b\xc7\x73\x57\x78\xc9\xf4\x2e\x59\x07\x95\x93\x6f\xd0\x4b\x17\x57\x19\x3e\x27\x27\xc7\x60\xdb\x3b\xed\x9a\x0e\x53\x44\x16\x3e\x3f\x8d\x92\x6d\x77\xa2\x0a\xeb\x3f\x52\xa8\xc6\x55\x5e\x31\x49\x37\x85\xf4\xc5\x1f\x26\x2d\xa9\x1c\xbf\x8b\x27\x54\xda\xc3\x6a\x20\xe5\x2a\x78\x04\xb0\xd6\x90\x70\x72\xaa\x8b\x68\xbd\x88\xf7\x02\x5f\x48\xb1\x7e\xc0\x58\x4c\x3f\x66\x1a\xf9\x3e\xe1\x65\xc0\x70\xa7\xcf\x38\x69\xaf\xf0\x56\x6c\x64\x49\x9c\x27\xad\x78\x74\x4f\xc2\x87\xde\x56\x39\x00\xda\x77\x0b\xcb\x2d\x1b\x89\xfb\x35\x4f\x02\xf5\x08\x51\x13\x60\xc1\x0a\x5a\x47\x4d\x26\x1c\x33\x30\x78\xda\xc0\x9c\x46\x47\xe2\x5b\x79\x60\x49\x6e\x37\x67\x53\x0a\x3e\xe9\xec\x46\x39\xb2\xf1\x34\x0d\xc6\x84\x53\x75\x6e\xe1\x0c\x59\xd9\x1e\xde\x29\x85\x10\x7b\x49\x49\xa5\x77\x79\xbe\x49\x56\x2e\x36\xe7\x0b\x3a\xbb\x4f\x03\x62\x7b\xd2\x4d\x31\x95\x2f\xbd\x38\x7b\xa8\x4f\x21\xe1\xec\x46\x70\x76\x95\x7d\x29\x22\x78\x88\x0a\x90\xdd\x9d\x5c\xda\xde\x19\x51\xcf\xf0\xfc\x59\x52\x65\x7c\x33\x13\xdf\xf3\x48\xda\xbb\x2a\x75\xdb\x60\xb2\x02\x15\xd4\xfc\x19\xed\x1b\xec\x7f\x35\xa8\xff\x28\x31\x07\x2d\x12\xc8\xdc\x88\x46\x7c\x8a\x5b\x22'); /** - * Stores the provided instance into the provided array. + * Provides metadata using the Google Earth Enterprise REST API. This is used by the GoogleEarthEnterpriseImageryProvider + * and GoogleEarthEnterpriseTerrainProvider to share metadata requests. * - * @param {Matrix2} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @alias GoogleEarthEnterpriseMetadata + * @constructor + * + * @param {Resource|String} resourceOrUrl The url of the Google Earth Enterprise server hosting the imagery + * + * @see GoogleEarthEnterpriseImageryProvider + * @see GoogleEarthEnterpriseTerrainProvider * - * @returns {Number[]} The array that was packed into */ - Matrix2.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + function GoogleEarthEnterpriseMetadata(resourceOrUrl) { + Check.defined('resourceOrUrl', resourceOrUrl); - startingIndex = defaultValue(startingIndex, 0); + var url = resourceOrUrl; + var proxy; + if (typeof url !== 'string' && !(url instanceof Resource)) { + Check.typeOf.string('resourceOrUrl.url', resourceOrUrl.url); + + if (defined(resourceOrUrl.proxy)) { + deprecationWarning('GoogleEarthEnterpriseMetadata', 'The options.url & options.proxy parameters have been deprecated. Specify a URL string or a Resource as the only parameter.'); + } - array[startingIndex++] = value[0]; - array[startingIndex++] = value[1]; - array[startingIndex++] = value[2]; - array[startingIndex++] = value[3]; + url = resourceOrUrl.url; + proxy = resourceOrUrl.proxy; + } - return array; - }; + var resource = Resource.createIfNeeded(url, { + proxy: proxy + }); + resource.appendForwardSlash(); + this._resource = resource; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Matrix2} [result] The object into which to store the result. - * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. - */ - Matrix2.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + /** + * True if imagery is available. + * @type {Boolean} + * @default true + */ + this.imageryPresent = true; - if (!defined(result)) { - result = new Matrix2(); - } + /** + * True if imagery is sent as a protocol buffer, false if sent as plain images. If undefined we will try both. + * @type {Boolean} + * @default undefined + */ + this.protoImagery = undefined; - result[0] = array[startingIndex++]; - result[1] = array[startingIndex++]; - result[2] = array[startingIndex++]; - result[3] = array[startingIndex++]; - return result; - }; + /** + * True if terrain is available. + * @type {Boolean} + * @default true + */ + this.terrainPresent = true; - /** - * Duplicates a Matrix2 instance. - * - * @param {Matrix2} matrix The matrix to duplicate. - * @param {Matrix2} [result] The object onto which to store the result. - * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. (Returns undefined if matrix is undefined) - */ - Matrix2.clone = function(matrix, result) { - if (!defined(matrix)) { - return undefined; - } - if (!defined(result)) { - return new Matrix2(matrix[0], matrix[2], - matrix[1], matrix[3]); + /** + * Exponent used to compute constant to calculate negative height values. + * @type {Number} + * @default 32 + */ + this.negativeAltitudeExponentBias = 32; + + /** + * Threshold where any numbers smaller are actually negative values. They are multiplied by -2^negativeAltitudeExponentBias. + * @type {Number} + * @default EPSILON12 + */ + this.negativeAltitudeThreshold = CesiumMath.EPSILON12; + + /** + * Dictionary of provider id to copyright strings. + * @type {Object} + * @default {} + */ + this.providers = {}; + + /** + * Key used to decode packets + * @type {ArrayBuffer} + */ + this.key = undefined; + + this._quadPacketVersion = 1; + + this._tileInfo = {}; + this._subtreePromises = {}; + + var that = this; + this._readyPromise = requestDbRoot(this) + .then(function() { + return that.getQuadTreePacket('', that._quadPacketVersion); + }) + .then(function() { + return true; + }) + .otherwise(function(e) { + var message = 'An error occurred while accessing ' + getMetadataResource(that, '', 1).url + '.'; + return when.reject(new RuntimeError(message)); + }); + } + + defineProperties(GoogleEarthEnterpriseMetadata.prototype, { + /** + * Gets the name of the Google Earth Enterprise server. + * @memberof GoogleEarthEnterpriseMetadata.prototype + * @type {String} + * @readonly + */ + url : { + get : function() { + return this._resource.url; + } + }, + + /** + * Gets the proxy used for metadata requests. + * @memberof GoogleEarthEnterpriseMetadata.prototype + * @type {Proxy} + * @readonly + */ + proxy : { + get : function() { + return this._resource.proxy; + } + }, + + /** + * Gets the resource used for metadata requests. + * @memberof GoogleEarthEnterpriseMetadata.prototype + * @type {Resource} + * @readonly + */ + resource: { + get: function() { + return this._resource; + } + }, + + /** + * Gets a promise that resolves to true when the metadata is ready for use. + * @memberof GoogleEarthEnterpriseMetadata.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise; + } } - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[3]; - return result; - }; + }); /** - * Creates a Matrix2 from 4 consecutive elements in an array. - * - * @param {Number[]} array The array whose 4 consecutive elements correspond to the positions of the matrix. Assumes column-major order. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. - * @param {Matrix2} [result] The object onto which to store the result. - * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. - * - * @example - * // Create the Matrix2: - * // [1.0, 2.0] - * // [1.0, 2.0] + * Converts a tiles (x, y, level) position into a quadkey used to request an image + * from a Google Earth Enterprise server. * - * var v = [1.0, 1.0, 2.0, 2.0]; - * var m = Cesium.Matrix2.fromArray(v); + * @param {Number} x The tile's x coordinate. + * @param {Number} y The tile's y coordinate. + * @param {Number} level The tile's zoom level. * - * // Create same Matrix2 with using an offset into an array - * var v2 = [0.0, 0.0, 1.0, 1.0, 2.0, 2.0]; - * var m2 = Cesium.Matrix2.fromArray(v2, 2); + * @see GoogleEarthEnterpriseMetadata#quadKeyToTileXY */ - Matrix2.fromArray = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + GoogleEarthEnterpriseMetadata.tileXYToQuadKey = function(x, y, level) { + var quadkey = ''; + for (var i = level; i >= 0; --i) { + var bitmask = 1 << i; + var digit = 0; - if (!defined(result)) { - result = new Matrix2(); - } + // Tile Layout + // ___ ___ + //| | | + //| 3 | 2 | + //|-------| + //| 0 | 1 | + //|___|___| + // - result[0] = array[startingIndex]; - result[1] = array[startingIndex + 1]; - result[2] = array[startingIndex + 2]; - result[3] = array[startingIndex + 3]; - return result; - }; + if (!isBitSet(y, bitmask)) { // Top Row + digit |= 2; + if (!isBitSet(x, bitmask)) { // Right to left + digit |= 1; + } + } else if (isBitSet(x, bitmask)) { // Left to right + digit |= 1; + } - /** - * Creates a Matrix2 instance from a column-major order array. - * - * @param {Number[]} values The column-major order array. - * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. - */ - Matrix2.fromColumnMajorArray = function(values, result) { - Check.defined('values', values); - - return Matrix2.clone(values, result); + quadkey += digit; + } + return quadkey; }; /** - * Creates a Matrix2 instance from a row-major order array. - * The resulting matrix will be in column-major order. + * Converts a tile's quadkey used to request an image from a Google Earth Enterprise server into the + * (x, y, level) position. * - * @param {Number[]} values The row-major order array. - * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + * @param {String} quadkey The tile's quad key + * + * @see GoogleEarthEnterpriseMetadata#tileXYToQuadKey */ - Matrix2.fromRowMajorArray = function(values, result) { - Check.defined('values', values); - - if (!defined(result)) { - return new Matrix2(values[0], values[1], - values[2], values[3]); + GoogleEarthEnterpriseMetadata.quadKeyToTileXY = function(quadkey) { + var x = 0; + var y = 0; + var level = quadkey.length - 1; + for (var i = level; i >= 0; --i) { + var bitmask = 1 << i; + var digit = +quadkey[level - i]; + + if (isBitSet(digit, 2)) { // Top Row + if (!isBitSet(digit, 1)) { // // Right to left + x |= bitmask; + } + } else { + y |= bitmask; + if (isBitSet(digit, 1)) { // Left to right + x |= bitmask; + } + } } - result[0] = values[0]; - result[1] = values[2]; - result[2] = values[1]; - result[3] = values[3]; - return result; + return { + x : x, + y : y, + level : level + }; }; - /** - * Computes a Matrix2 instance representing a non-uniform scale. - * - * @param {Cartesian2} scale The x and y scale factors. - * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. - * - * @example - * // Creates - * // [7.0, 0.0] - * // [0.0, 8.0] - * var m = Cesium.Matrix2.fromScale(new Cesium.Cartesian2(7.0, 8.0)); - */ - Matrix2.fromScale = function(scale, result) { - Check.typeOf.object('scale', scale); - - if (!defined(result)) { - return new Matrix2( - scale.x, 0.0, - 0.0, scale.y); + GoogleEarthEnterpriseMetadata.prototype.isValid = function(quadKey) { + var info = this.getTileInformationFromQuadKey(quadKey); + if (defined(info)) { + return info !== null; } - result[0] = scale.x; - result[1] = 0.0; - result[2] = 0.0; - result[3] = scale.y; - return result; + var valid = true; + var q = quadKey; + var last; + while (q.length > 1) { + last = q.substring(q.length - 1); + q = q.substring(0, q.length - 1); + info = this.getTileInformationFromQuadKey(q); + if (defined(info)) { + if (!info.hasSubtree() && + !info.hasChild(parseInt(last))) { + // We have no subtree or child available at some point in this node's ancestry + valid = false; + } + + break; + } else if (info === null) { + // Some node in the ancestry was loaded and said there wasn't a subtree + valid = false; + break; + } + } + + return valid; }; + var taskProcessor = new TaskProcessor('decodeGoogleEarthEnterprisePacket', Number.POSITIVE_INFINITY); + /** - * Computes a Matrix2 instance representing a uniform scale. + * Retrieves a Google Earth Enterprise quadtree packet. * - * @param {Number} scale The uniform scale factor. - * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + * @param {String} [quadKey=''] The quadkey to retrieve the packet for. + * @param {Number} [version=1] The cnode version to be used in the request. + * @param {Request} [request] The request object. Intended for internal use only. * - * @example - * // Creates - * // [2.0, 0.0] - * // [0.0, 2.0] - * var m = Cesium.Matrix2.fromUniformScale(2.0); + * @private */ - Matrix2.fromUniformScale = function(scale, result) { - Check.typeOf.number('scale', scale); - - if (!defined(result)) { - return new Matrix2( - scale, 0.0, - 0.0, scale); + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket = function(quadKey, version, request) { + version = defaultValue(version, 1); + quadKey = defaultValue(quadKey, ''); + var resource = getMetadataResource(this, quadKey, version, request); + + var promise = resource.fetchArrayBuffer(); + + if (!defined(promise)) { + return undefined; // Throttled } - result[0] = scale; - result[1] = 0.0; - result[2] = 0.0; - result[3] = scale; - return result; + var tileInfo = this._tileInfo; + var key = this.key; + return promise + .then(function(metadata) { + var decodePromise = taskProcessor.scheduleTask({ + buffer : metadata, + quadKey : quadKey, + type : 'Metadata', + key: key + }, [metadata]); + + return decodePromise + .then(function(result) { + var root; + var topLevelKeyLength = -1; + if (quadKey !== '') { + // Root tile has no data except children bits, so put them into the tile info + topLevelKeyLength = quadKey.length + 1; + var top = result[quadKey]; + root = tileInfo[quadKey]; + root._bits |= top._bits; + + delete result[quadKey]; + } + + // Copy the resulting objects into tileInfo + // Make sure we start with shorter quadkeys first, so we know the parents have + // already been processed. Otherwise we can lose ancestorHasTerrain along the way. + var keys = Object.keys(result); + keys.sort(function(a, b) { + return a.length - b.length; + }); + var keysLength = keys.length; + for (var i = 0; i < keysLength; ++i) { + var key = keys[i]; + var r = result[key]; + if (r !== null) { + var info = GoogleEarthEnterpriseTileInformation.clone(result[key]); + var keyLength = key.length; + if (keyLength === topLevelKeyLength) { + info.setParent(root); + } else if(keyLength > 1){ + var parent = tileInfo[key.substring(0, key.length - 1)]; + info.setParent(parent); + } + tileInfo[key] = info; + } else { + tileInfo[key] = null; + } + } + }); + }); }; /** - * Creates a rotation matrix. + * Populates the metadata subtree down to the specified tile. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. - * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. * - * @example - * // Rotate a point 45 degrees counterclockwise. - * var p = new Cesium.Cartesian2(5, 6); - * var m = Cesium.Matrix2.fromRotation(Cesium.Math.toRadians(45.0)); - * var rotated = Cesium.Matrix2.multiplyByVector(m, p, new Cesium.Cartesian2()); + * @returns {Promise<GoogleEarthEnterpriseTileInformation>} A promise that resolves to the tile info for the requested quad key + * + * @private */ - Matrix2.fromRotation = function(angle, result) { - Check.typeOf.number('angle', angle); - - var cosAngle = Math.cos(angle); - var sinAngle = Math.sin(angle); + GoogleEarthEnterpriseMetadata.prototype.populateSubtree = function(x, y, level, request) { + var quadkey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); + return populateSubtree(this, quadkey, request); + }; - if (!defined(result)) { - return new Matrix2( - cosAngle, -sinAngle, - sinAngle, cosAngle); + function populateSubtree(that, quadKey, request) { + var tileInfo = that._tileInfo; + var q = quadKey; + var t = tileInfo[q]; + // If we have tileInfo make sure sure it is not a node with a subtree that's not loaded + if (defined(t) && (!t.hasSubtree() || t.hasChildren())) { + return t; } - result[0] = cosAngle; - result[1] = sinAngle; - result[2] = -sinAngle; - result[3] = cosAngle; - return result; - }; - /** - * Creates an Array from the provided Matrix2 instance. - * The array will be in column-major order. - * - * @param {Matrix2} matrix The matrix to use.. - * @param {Number[]} [result] The Array onto which to store the result. - * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. - */ - Matrix2.toArray = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - - if (!defined(result)) { - return [matrix[0], matrix[1], matrix[2], matrix[3]]; + while ((t === undefined) && q.length > 1) { + q = q.substring(0, q.length - 1); + t = tileInfo[q]; } - result[0] = matrix[0]; - result[1] = matrix[1]; - result[2] = matrix[2]; - result[3] = matrix[3]; - return result; - }; + + var subtreeRequest; + var subtreePromises = that._subtreePromises; + var promise = subtreePromises[q]; + if (defined(promise)) { + return promise + .then(function() { + // Recursively call this in case we need multiple subtree requests + subtreeRequest = new Request({ + throttle : request.throttle, + throttleByServer : request.throttleByServer, + type : request.type, + priorityFunction : request.priorityFunction + }); + return populateSubtree(that, quadKey, subtreeRequest); + }); + } + + // t is either + // null so one of its parents was a leaf node, so this tile doesn't exist + // exists but doesn't have a subtree to request + // undefined so no parent exists - this shouldn't ever happen once the provider is ready + if (!defined(t) || !t.hasSubtree()) { + return when.reject(new RuntimeError('Couldn\'t load metadata for tile ' + quadKey)); + } + + // We need to split up the promise here because when will execute syncronously if getQuadTreePacket + // is already resolved (like in the tests), so subtreePromises will never get cleared out. + // Only the initial request will also remove the promise from subtreePromises. + promise = that.getQuadTreePacket(q, t.cnodeVersion, request); + if (!defined(promise)) { + return undefined; + } + subtreePromises[q] = promise; + + return promise + .then(function() { + // Recursively call this in case we need multiple subtree requests + subtreeRequest = new Request({ + throttle : request.throttle, + throttleByServer : request.throttleByServer, + type : request.type, + priorityFunction : request.priorityFunction + }); + return populateSubtree(that, quadKey, subtreeRequest); + }) + .always(function() { + delete subtreePromises[q]; + }); + } /** - * Computes the array index of the element at the provided row and column. - * - * @param {Number} row The zero-based index of the row. - * @param {Number} column The zero-based index of the column. - * @returns {Number} The index of the element at the provided row and column. + * Gets information about a tile * - * @exception {DeveloperError} row must be 0 or 1. - * @exception {DeveloperError} column must be 0 or 1. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @returns {GoogleEarthEnterpriseTileInformation|undefined} Information about the tile or undefined if it isn't loaded. * - * @example - * var myMatrix = new Cesium.Matrix2(); - * var column1Row0Index = Cesium.Matrix2.getElementIndex(1, 0); - * var column1Row0 = myMatrix[column1Row0Index] - * myMatrix[column1Row0Index] = 10.0; + * @private */ - Matrix2.getElementIndex = function(column, row) { - Check.typeOf.number.greaterThanOrEquals('row', row, 0); - Check.typeOf.number.lessThanOrEquals('row', row, 1); - - Check.typeOf.number.greaterThanOrEquals('column', column, 0); - Check.typeOf.number.lessThanOrEquals('column', column, 1); - - return column * 2 + row; + GoogleEarthEnterpriseMetadata.prototype.getTileInformation = function(x, y, level) { + var quadkey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); + return this._tileInfo[quadkey]; }; /** - * Retrieves a copy of the matrix column at the provided index as a Cartesian2 instance. + * Gets information about a tile from a quadKey * - * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to retrieve. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter. + * @param {String} quadkey The quadkey for the tile + * @returns {GoogleEarthEnterpriseTileInformation|undefined} Information about the tile or undefined if it isn't loaded. * - * @exception {DeveloperError} index must be 0 or 1. + * @private */ - Matrix2.getColumn = function(matrix, index, result) { - Check.typeOf.object('matrix', matrix); + GoogleEarthEnterpriseMetadata.prototype.getTileInformationFromQuadKey = function(quadkey) { + return this._tileInfo[quadkey]; + }; - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 1); + function getMetadataResource(that, quadKey, version, request) { + return that._resource.getDerivedResource({ + url: 'flatfile?q2-0' + quadKey + '-q.' + version.toString(), + request: request + }); + } - Check.typeOf.object('result', result); - - var startIndex = index * 2; - var x = matrix[startIndex]; - var y = matrix[startIndex + 1]; + function requestDbRoot(that) { + var resource = that._resource.getDerivedResource({ + url: 'dbRoot.v5', + queryParameters: { + output: 'proto' + } + }); - result.x = x; - result.y = y; - return result; - }; + return resource.fetchArrayBuffer() + .then(function(buf) { + var encryptedDbRootProto = dbrootParser.EncryptedDbRootProto.decode(new Uint8Array(buf)); - /** - * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian2 instance. - * - * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to set. - * @param {Cartesian2} cartesian The Cartesian whose values will be assigned to the specified column. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - * - * @exception {DeveloperError} index must be 0 or 1. - */ - Matrix2.setColumn = function(matrix, index, cartesian, result) { - Check.typeOf.object('matrix', matrix); + var byteArray = encryptedDbRootProto.encryptionData; + var offset = byteArray.byteOffset; + var end = offset + byteArray.byteLength; + var key = that.key = byteArray.buffer.slice(offset, end); - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 1); + byteArray = encryptedDbRootProto.dbrootData; + offset = byteArray.byteOffset; + end = offset + byteArray.byteLength; + var dbRootCompressed = byteArray.buffer.slice(offset, end); + return taskProcessor.scheduleTask({ + buffer : dbRootCompressed, + type : 'DbRoot', + key: key + }, [dbRootCompressed]); + }) + .then(function(result) { + var dbRoot = dbrootParser.DbRootProto.decode(new Uint8Array(result.buffer)); + that.imageryPresent = defaultValue(dbRoot.imageryPresent, that.imageryPresent); + that.protoImagery = dbRoot.protoImagery; + that.terrainPresent = defaultValue(dbRoot.terrainPresent, that.terrainPresent); + if (defined(dbRoot.endSnippet) && defined(dbRoot.endSnippet.model)) { + var model = dbRoot.endSnippet.model; + that.negativeAltitudeExponentBias = defaultValue(model.negativeAltitudeExponentBias, that.negativeAltitudeExponentBias); + that.negativeAltitudeThreshold = defaultValue(model.compressedNegativeAltitudeThreshold, that.negativeAltitudeThreshold); + } + if (defined(dbRoot.databaseVersion)) { + that._quadPacketVersion = defaultValue(dbRoot.databaseVersion.quadtreeVersion, that._quadPacketVersion); + } + var providers = that.providers; + var providerInfo = defaultValue(dbRoot.providerInfo, []); + var count = providerInfo.length; + for(var i=0;i<count;++i) { + var provider = providerInfo[i]; + var copyrightString = provider.copyrightString; + if (defined(copyrightString)) { + providers[provider.providerId] = new Credit({text: copyrightString.value}); + } + } + }) + .otherwise(function() { + // Just eat the error and use the default values. + console.log('Failed to retrieve ' + resource.url + '. Using defaults.'); + that.key = defaultKey; + }); + } - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - result = Matrix2.clone(matrix, result); - var startIndex = index * 2; - result[startIndex] = cartesian.x; - result[startIndex + 1] = cartesian.y; - return result; - }; + return GoogleEarthEnterpriseMetadata; +}); + +define('Core/GoogleEarthEnterpriseTerrainData',[ + './BoundingSphere', + './Cartesian2', + './Cartesian3', + './Check', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './IndexDatatype', + './Intersections2D', + './Math', + './OrientedBoundingBox', + './QuantizedMeshTerrainData', + './Rectangle', + './TaskProcessor', + './TerrainEncoding', + './TerrainMesh' + ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Check, + defaultValue, + defined, + defineProperties, + DeveloperError, + IndexDatatype, + Intersections2D, + CesiumMath, + OrientedBoundingBox, + QuantizedMeshTerrainData, + Rectangle, + TaskProcessor, + TerrainEncoding, + TerrainMesh) { + 'use strict'; /** - * Retrieves a copy of the matrix row at the provided index as a Cartesian2 instance. + * Terrain data for a single tile from a Google Earth Enterprise server. * - * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to retrieve. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter. + * @alias GoogleEarthEnterpriseTerrainData + * @constructor * - * @exception {DeveloperError} index must be 0 or 1. + * @param {Object} options Object with the following properties: + * @param {ArrayBuffer} options.buffer The buffer containing terrain data. + * @param {Number} options.negativeAltitudeExponentBias Multiplier for negative terrain heights that are encoded as very small positive values. + * @param {Number} options.negativeElevationThreshold Threshold for negative values + * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. + * If a child's bit is set, geometry will be requested for that tile as well when it + * is needed. If the bit is cleared, the child tile is not requested and geometry is + * instead upsampled from the parent. The bit values are as follows: + * <table> + * <tr><th>Bit Position</th><th>Bit Value</th><th>Child Tile</th></tr> + * <tr><td>0</td><td>1</td><td>Southwest</td></tr> + * <tr><td>1</td><td>2</td><td>Southeast</td></tr> + * <tr><td>2</td><td>4</td><td>Northeast</td></tr> + * <tr><td>3</td><td>8</td><td>Northwest</td></tr> + * </table> + * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; + * otherwise, false. + * @param {Credit[]} [options.credits] Array of credits for this tile. + * + * + * @example + * var buffer = ... + * var childTileMask = ... + * var terrainData = new Cesium.GoogleEarthEnterpriseTerrainData({ + * buffer : heightBuffer, + * childTileMask : childTileMask + * }); + * + * @see TerrainData + * @see HeightTerrainData + * @see QuantizedMeshTerrainData */ - Matrix2.getRow = function(matrix, index, result) { - Check.typeOf.object('matrix', matrix); + function GoogleEarthEnterpriseTerrainData(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Check.typeOf.object('options.buffer', options.buffer); + Check.typeOf.number('options.negativeAltitudeExponentBias', options.negativeAltitudeExponentBias); + Check.typeOf.number('options.negativeElevationThreshold', options.negativeElevationThreshold); + + this._buffer = options.buffer; + this._credits = options.credits; + this._negativeAltitudeExponentBias = options.negativeAltitudeExponentBias; + this._negativeElevationThreshold = options.negativeElevationThreshold; - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 1); + // Convert from google layout to layout of other providers + // 3 2 -> 2 3 + // 0 1 -> 0 1 + var googleChildTileMask = defaultValue(options.childTileMask, 15); + var childTileMask = googleChildTileMask & 3; // Bottom row is identical + childTileMask |= (googleChildTileMask & 4) ? 8 : 0; // NE + childTileMask |= (googleChildTileMask & 8) ? 4 : 0; // NW - Check.typeOf.object('result', result); - - var x = matrix[index]; - var y = matrix[index + 2]; + this._childTileMask = childTileMask; - result.x = x; - result.y = y; - return result; - }; + this._createdByUpsampling = defaultValue(options.createdByUpsampling, false); - /** - * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian2 instance. - * - * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to set. - * @param {Cartesian2} cartesian The Cartesian whose values will be assigned to the specified row. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - * - * @exception {DeveloperError} index must be 0 or 1. - */ - Matrix2.setRow = function(matrix, index, cartesian, result) { - Check.typeOf.object('matrix', matrix); + this._skirtHeight = undefined; + this._bufferType = this._buffer.constructor; + this._mesh = undefined; + this._minimumHeight = undefined; + this._maximumHeight = undefined; + this._vertexCountWithoutSkirts = undefined; + this._skirtIndex = undefined; + } - Check.typeOf.number.greaterThanOrEquals('index', index, 0); - Check.typeOf.number.lessThanOrEquals('index', index, 1); + defineProperties(GoogleEarthEnterpriseTerrainData.prototype, { + /** + * An array of credits for this tile + * @memberof GoogleEarthEnterpriseTerrainData.prototype + * @type {Credit[]} + */ + credits : { + get : function() { + return this._credits; + } + }, + /** + * The water mask included in this terrain data, if any. A water mask is a rectangular + * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. + * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. + * @memberof GoogleEarthEnterpriseTerrainData.prototype + * @type {Uint8Array|Image|Canvas} + */ + waterMask : { + get : function() { + return undefined; + } + } + }); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - result = Matrix2.clone(matrix, result); - result[index] = cartesian.x; - result[index + 2] = cartesian.y; - return result; - }; + var taskProcessor = new TaskProcessor('createVerticesFromGoogleEarthEnterpriseBuffer'); - var scratchColumn = new Cartesian2(); + var nativeRectangleScratch = new Rectangle(); + var rectangleScratch = new Rectangle(); /** - * Extracts the non-uniform scale assuming the matrix is an affine transformation. + * Creates a {@link TerrainMesh} from this terrain data. * - * @param {Matrix2} matrix The matrix. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter. + * @private + * + * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} x The X coordinate of the tile for which to create the terrain data. + * @param {Number} y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} level The level of the tile for which to create the terrain data. + * @param {Number} [exaggeration=1.0] The scale used to exaggerate the terrain. + * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * asynchronous mesh creations are already in progress and the operation should + * be retried later. */ - Matrix2.getScale = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); + GoogleEarthEnterpriseTerrainData.prototype.createMesh = function(tilingScheme, x, y, level, exaggeration) { + Check.typeOf.object('tilingScheme', tilingScheme); + Check.typeOf.number('x', x); + Check.typeOf.number('y', y); + Check.typeOf.number('level', level); - result.x = Cartesian2.magnitude(Cartesian2.fromElements(matrix[0], matrix[1], scratchColumn)); - result.y = Cartesian2.magnitude(Cartesian2.fromElements(matrix[2], matrix[3], scratchColumn)); - return result; - }; + var ellipsoid = tilingScheme.ellipsoid; + tilingScheme.tileXYToNativeRectangle(x, y, level, nativeRectangleScratch); + tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); + exaggeration = defaultValue(exaggeration, 1.0); - var scratchScale = new Cartesian2(); + // Compute the center of the tile for RTC rendering. + var center = ellipsoid.cartographicToCartesian(Rectangle.center(rectangleScratch)); - /** - * Computes the maximum scale assuming the matrix is an affine transformation. - * The maximum scale is the maximum length of the column vectors. - * - * @param {Matrix2} matrix The matrix. - * @returns {Number} The maximum scale. - */ - Matrix2.getMaximumScale = function(matrix) { - Matrix2.getScale(matrix, scratchScale); - return Cartesian2.maximumComponent(scratchScale); - }; + var levelZeroMaxError = 40075.16; // From Google's Doc + var thisLevelMaxError = levelZeroMaxError / (1 << level); + this._skirtHeight = Math.min(thisLevelMaxError * 8.0, 1000.0); - /** - * Computes the product of two matrices. - * - * @param {Matrix2} left The first matrix. - * @param {Matrix2} right The second matrix. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - */ - Matrix2.multiply = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - var column0Row0 = left[0] * right[0] + left[2] * right[1]; - var column1Row0 = left[0] * right[2] + left[2] * right[3]; - var column0Row1 = left[1] * right[0] + left[3] * right[1]; - var column1Row1 = left[1] * right[2] + left[3] * right[3]; + var verticesPromise = taskProcessor.scheduleTask({ + buffer : this._buffer, + nativeRectangle : nativeRectangleScratch, + rectangle : rectangleScratch, + relativeToCenter : center, + ellipsoid : ellipsoid, + skirtHeight : this._skirtHeight, + exaggeration : exaggeration, + includeWebMercatorT : true, + negativeAltitudeExponentBias: this._negativeAltitudeExponentBias, + negativeElevationThreshold: this._negativeElevationThreshold + }); - result[0] = column0Row0; - result[1] = column0Row1; - result[2] = column1Row0; - result[3] = column1Row1; - return result; - }; + if (!defined(verticesPromise)) { + // Postponed + return undefined; + } - /** - * Computes the sum of two matrices. - * - * @param {Matrix2} left The first matrix. - * @param {Matrix2} right The second matrix. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - */ - Matrix2.add = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result[0] = left[0] + right[0]; - result[1] = left[1] + right[1]; - result[2] = left[2] + right[2]; - result[3] = left[3] + right[3]; - return result; - }; + var that = this; + return verticesPromise + .then(function(result) { + that._mesh = new TerrainMesh( + center, + new Float32Array(result.vertices), + new Uint16Array(result.indices), + result.minimumHeight, + result.maximumHeight, + result.boundingSphere3D, + result.occludeePointInScaledSpace, + result.numberOfAttributes, + result.orientedBoundingBox, + TerrainEncoding.clone(result.encoding), + exaggeration); - /** - * Computes the difference of two matrices. - * - * @param {Matrix2} left The first matrix. - * @param {Matrix2} right The second matrix. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - */ - Matrix2.subtract = function(left, right, result) { - Check.typeOf.object('left', left); - Check.typeOf.object('right', right); - Check.typeOf.object('result', result); - - result[0] = left[0] - right[0]; - result[1] = left[1] - right[1]; - result[2] = left[2] - right[2]; - result[3] = left[3] - right[3]; - return result; + that._vertexCountWithoutSkirts = result.vertexCountWithoutSkirts; + that._skirtIndex = result.skirtIndex; + that._minimumHeight = result.minimumHeight; + that._maximumHeight = result.maximumHeight; + + // Free memory received from server after mesh is created. + that._buffer = undefined; + return that._mesh; + }); }; /** - * Computes the product of a matrix and a column vector. + * Computes the terrain height at a specified longitude and latitude. * - * @param {Matrix2} matrix The matrix. - * @param {Cartesian2} cartesian The column. - * @param {Cartesian2} result The object onto which to store the result. - * @returns {Cartesian2} The modified result parameter. + * @param {Rectangle} rectangle The rectangle covered by this terrain data. + * @param {Number} longitude The longitude in radians. + * @param {Number} latitude The latitude in radians. + * @returns {Number} The terrain height at the specified position. If the position + * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly + * incorrect for positions far outside the rectangle. */ - Matrix2.multiplyByVector = function(matrix, cartesian, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('cartesian', cartesian); - Check.typeOf.object('result', result); - - var x = matrix[0] * cartesian.x + matrix[2] * cartesian.y; - var y = matrix[1] * cartesian.x + matrix[3] * cartesian.y; + GoogleEarthEnterpriseTerrainData.prototype.interpolateHeight = function(rectangle, longitude, latitude) { + var u = CesiumMath.clamp((longitude - rectangle.west) / rectangle.width, 0.0, 1.0); + var v = CesiumMath.clamp((latitude - rectangle.south) / rectangle.height, 0.0, 1.0); - result.x = x; - result.y = y; - return result; + if (!defined(this._mesh)) { + return interpolateHeight(this, u, v, rectangle); + } + + return interpolateMeshHeight(this, u, v); }; + var upsampleTaskProcessor = new TaskProcessor('upsampleQuantizedTerrainMesh'); + /** - * Computes the product of a matrix and a scalar. + * Upsamples this terrain data for use by a descendant tile. The resulting instance will contain a subset of the + * height samples in this instance, interpolated if necessary. * - * @param {Matrix2} matrix The matrix. - * @param {Number} scalar The number to multiply by. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. + * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. + * @param {Number} thisX The X coordinate of this tile in the tiling scheme. + * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {Number} thisLevel The level of this tile in the tiling scheme. + * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise.<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, + * or undefined if too many asynchronous upsample operations are in progress and the request has been + * deferred. */ - Matrix2.multiplyByScalar = function(matrix, scalar, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.number('scalar', scalar); - Check.typeOf.object('result', result); + GoogleEarthEnterpriseTerrainData.prototype.upsample = function(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) { + Check.typeOf.object('tilingScheme', tilingScheme); + Check.typeOf.number('thisX', thisX); + Check.typeOf.number('thisY', thisY); + Check.typeOf.number('thisLevel', thisLevel); + Check.typeOf.number('descendantX', descendantX); + Check.typeOf.number('descendantY', descendantY); + Check.typeOf.number('descendantLevel', descendantLevel); + var levelDifference = descendantLevel - thisLevel; + if (levelDifference > 1) { + throw new DeveloperError('Upsampling through more than one level at a time is not currently supported.'); + } - result[0] = matrix[0] * scalar; - result[1] = matrix[1] * scalar; - result[2] = matrix[2] * scalar; - result[3] = matrix[3] * scalar; - return result; - }; - - /** - * Computes the product of a matrix times a (non-uniform) scale, as if the scale were a scale matrix. - * - * @param {Matrix2} matrix The matrix on the left-hand side. - * @param {Cartesian2} scale The non-uniform scale on the right-hand side. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - * - * - * @example - * // Instead of Cesium.Matrix2.multiply(m, Cesium.Matrix2.fromScale(scale), m); - * Cesium.Matrix2.multiplyByScale(m, scale, m); - * - * @see Matrix2.fromScale - * @see Matrix2.multiplyByUniformScale - */ - Matrix2.multiplyByScale = function(matrix, scale, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('scale', scale); - Check.typeOf.object('result', result); - - result[0] = matrix[0] * scale.x; - result[1] = matrix[1] * scale.x; - result[2] = matrix[2] * scale.y; - result[3] = matrix[3] * scale.y; - return result; - }; + var mesh = this._mesh; + if (!defined(this._mesh)) { + return undefined; + } - /** - * Creates a negated copy of the provided matrix. - * - * @param {Matrix2} matrix The matrix to negate. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - */ - Matrix2.negate = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result[0] = -matrix[0]; - result[1] = -matrix[1]; - result[2] = -matrix[2]; - result[3] = -matrix[3]; - return result; - }; + var isEastChild = thisX * 2 !== descendantX; + var isNorthChild = thisY * 2 === descendantY; - /** - * Computes the transpose of the provided matrix. - * - * @param {Matrix2} matrix The matrix to transpose. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - */ - Matrix2.transpose = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - var column0Row0 = matrix[0]; - var column0Row1 = matrix[2]; - var column1Row0 = matrix[1]; - var column1Row1 = matrix[3]; + var ellipsoid = tilingScheme.ellipsoid; + var childRectangle = tilingScheme.tileXYToRectangle(descendantX, descendantY, descendantLevel); - result[0] = column0Row0; - result[1] = column0Row1; - result[2] = column1Row0; - result[3] = column1Row1; - return result; - }; + var upsamplePromise = upsampleTaskProcessor.scheduleTask({ + vertices : mesh.vertices, + vertexCountWithoutSkirts : this._vertexCountWithoutSkirts, + indices : mesh.indices, + skirtIndex : this._skirtIndex, + encoding : mesh.encoding, + minimumHeight : this._minimumHeight, + maximumHeight : this._maximumHeight, + isEastChild : isEastChild, + isNorthChild : isNorthChild, + childRectangle : childRectangle, + ellipsoid : ellipsoid, + exaggeration : mesh.exaggeration + }); - /** - * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements. - * - * @param {Matrix2} matrix The matrix with signed elements. - * @param {Matrix2} result The object onto which to store the result. - * @returns {Matrix2} The modified result parameter. - */ - Matrix2.abs = function(matrix, result) { - Check.typeOf.object('matrix', matrix); - Check.typeOf.object('result', result); - - result[0] = Math.abs(matrix[0]); - result[1] = Math.abs(matrix[1]); - result[2] = Math.abs(matrix[2]); - result[3] = Math.abs(matrix[3]); + if (!defined(upsamplePromise)) { + // Postponed + return undefined; + } - return result; - }; + var that = this; + return upsamplePromise + .then(function(result) { + var quantizedVertices = new Uint16Array(result.vertices); + var indicesTypedArray = IndexDatatype.createTypedArray(quantizedVertices.length / 3, result.indices); - /** - * Compares the provided matrices componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Matrix2} [left] The first matrix. - * @param {Matrix2} [right] The second matrix. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Matrix2.equals = function(left, right) { - return (left === right) || - (defined(left) && - defined(right) && - left[0] === right[0] && - left[1] === right[1] && - left[2] === right[2] && - left[3] === right[3]); - }; + var skirtHeight = that._skirtHeight; - /** - * @private - */ - Matrix2.equalsArray = function(matrix, array, offset) { - return matrix[0] === array[offset] && - matrix[1] === array[offset + 1] && - matrix[2] === array[offset + 2] && - matrix[3] === array[offset + 3]; + // Use QuantizedMeshTerrainData since we have what we need already parsed + return new QuantizedMeshTerrainData({ + quantizedVertices : quantizedVertices, + indices : indicesTypedArray, + minimumHeight : result.minimumHeight, + maximumHeight : result.maximumHeight, + boundingSphere : BoundingSphere.clone(result.boundingSphere), + orientedBoundingBox : OrientedBoundingBox.clone(result.orientedBoundingBox), + horizonOcclusionPoint : Cartesian3.clone(result.horizonOcclusionPoint), + westIndices : result.westIndices, + southIndices : result.southIndices, + eastIndices : result.eastIndices, + northIndices : result.northIndices, + westSkirtHeight : skirtHeight, + southSkirtHeight : skirtHeight, + eastSkirtHeight : skirtHeight, + northSkirtHeight : skirtHeight, + childTileMask : 0, + createdByUpsampling : true, + credits : that._credits + }); + }); }; /** - * Compares the provided matrices componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. + * Determines if a given child tile is available, based on the + * {@link HeightmapTerrainData.childTileMask}. The given child tile coordinates are assumed + * to be one of the four children of this tile. If non-child tile coordinates are + * given, the availability of the southeast child tile is returned. * - * @param {Matrix2} [left] The first matrix. - * @param {Matrix2} [right] The second matrix. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {Number} thisX The tile X coordinate of this (the parent) tile. + * @param {Number} thisY The tile Y coordinate of this (the parent) tile. + * @param {Number} childX The tile X coordinate of the child tile to check for availability. + * @param {Number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {Boolean} True if the child tile is available; otherwise, false. */ - Matrix2.equalsEpsilon = function(left, right, epsilon) { - Check.typeOf.number('epsilon', epsilon); + GoogleEarthEnterpriseTerrainData.prototype.isChildAvailable = function(thisX, thisY, childX, childY) { + Check.typeOf.number('thisX', thisX); + Check.typeOf.number('thisY', thisY); + Check.typeOf.number('childX', childX); + Check.typeOf.number('childY', childY); - return (left === right) || - (defined(left) && - defined(right) && - Math.abs(left[0] - right[0]) <= epsilon && - Math.abs(left[1] - right[1]) <= epsilon && - Math.abs(left[2] - right[2]) <= epsilon && - Math.abs(left[3] - right[3]) <= epsilon); - }; + var bitNumber = 2; // northwest child + if (childX !== thisX * 2) { + ++bitNumber; // east child + } + if (childY !== thisY * 2) { + bitNumber -= 2; // south child + } - /** - * An immutable Matrix2 instance initialized to the identity matrix. - * - * @type {Matrix2} - * @constant - */ - Matrix2.IDENTITY = freezeObject(new Matrix2(1.0, 0.0, - 0.0, 1.0)); + return (this._childTileMask & (1 << bitNumber)) !== 0; + }; /** - * An immutable Matrix2 instance initialized to the zero matrix. + * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution + * terrain data. If this value is false, the data was obtained from some other source, such + * as by downloading it from a remote server. This method should return true for instances + * returned from a call to {@link HeightmapTerrainData#upsample}. * - * @type {Matrix2} - * @constant + * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. */ - Matrix2.ZERO = freezeObject(new Matrix2(0.0, 0.0, - 0.0, 0.0)); + GoogleEarthEnterpriseTerrainData.prototype.wasCreatedByUpsampling = function() { + return this._createdByUpsampling; + }; - /** - * The index into Matrix2 for column 0, row 0. - * - * @type {Number} - * @constant - * - * @example - * var matrix = new Cesium.Matrix2(); - * matrix[Cesium.Matrix2.COLUMN0ROW0] = 5.0; // set column 0, row 0 to 5.0 - */ - Matrix2.COLUMN0ROW0 = 0; + var texCoordScratch0 = new Cartesian2(); + var texCoordScratch1 = new Cartesian2(); + var texCoordScratch2 = new Cartesian2(); + var barycentricCoordinateScratch = new Cartesian3(); - /** - * The index into Matrix2 for column 0, row 1. - * - * @type {Number} - * @constant - * - * @example - * var matrix = new Cesium.Matrix2(); - * matrix[Cesium.Matrix2.COLUMN0ROW1] = 5.0; // set column 0, row 1 to 5.0 - */ - Matrix2.COLUMN0ROW1 = 1; + function interpolateMeshHeight(terrainData, u, v) { + var mesh = terrainData._mesh; + var vertices = mesh.vertices; + var encoding = mesh.encoding; + var indices = mesh.indices; - /** - * The index into Matrix2 for column 1, row 0. - * - * @type {Number} - * @constant - * - * @example - * var matrix = new Cesium.Matrix2(); - * matrix[Cesium.Matrix2.COLUMN1ROW0] = 5.0; // set column 1, row 0 to 5.0 - */ - Matrix2.COLUMN1ROW0 = 2; + for (var i = 0, len = indices.length; i < len; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; - /** - * The index into Matrix2 for column 1, row 1. - * - * @type {Number} - * @constant - * - * @example - * var matrix = new Cesium.Matrix2(); - * matrix[Cesium.Matrix2.COLUMN1ROW1] = 5.0; // set column 1, row 1 to 5.0 - */ - Matrix2.COLUMN1ROW1 = 3; + var uv0 = encoding.decodeTextureCoordinates(vertices, i0, texCoordScratch0); + var uv1 = encoding.decodeTextureCoordinates(vertices, i1, texCoordScratch1); + var uv2 = encoding.decodeTextureCoordinates(vertices, i2, texCoordScratch2); - defineProperties(Matrix2.prototype, { - /** - * Gets the number of items in the collection. - * @memberof Matrix2.prototype - * - * @type {Number} - */ - length : { - get : function() { - return Matrix2.packedLength; + var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, barycentricCoordinateScratch); + if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { + var h0 = encoding.decodeHeight(vertices, i0); + var h1 = encoding.decodeHeight(vertices, i1); + var h2 = encoding.decodeHeight(vertices, i2); + return barycentric.x * h0 + barycentric.y * h1 + barycentric.z * h2; } } - }); - /** - * Duplicates the provided Matrix2 instance. - * - * @param {Matrix2} [result] The object onto which to store the result. - * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. - */ - Matrix2.prototype.clone = function(result) { - return Matrix2.clone(this, result); - }; + // Position does not lie in any triangle in this mesh. + return undefined; + } - /** - * Compares this matrix to the provided matrix componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Matrix2} [right] The right hand side matrix. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - Matrix2.prototype.equals = function(right) { - return Matrix2.equals(this, right); - }; + var sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT; + var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; + var sizeOfInt32 = Int32Array.BYTES_PER_ELEMENT; + var sizeOfFloat = Float32Array.BYTES_PER_ELEMENT; + var sizeOfDouble = Float64Array.BYTES_PER_ELEMENT; - /** - * Compares this matrix to the provided matrix componentwise and returns - * <code>true</code> if they are within the provided epsilon, - * <code>false</code> otherwise. - * - * @param {Matrix2} [right] The right hand side matrix. - * @param {Number} epsilon The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. - */ - Matrix2.prototype.equalsEpsilon = function(right, epsilon) { - return Matrix2.equalsEpsilon(this, right, epsilon); - }; + function interpolateHeight(terrainData, u, v, rectangle) { + var buffer = terrainData._buffer; + var quad = 0; // SW + var uStart = 0.0; + var vStart = 0.0; + if (v > 0.5) { // Upper row + if (u > 0.5) { // NE + quad = 2; + uStart = 0.5; + } else { // NW + quad = 3; + } + vStart = 0.5; + } else if (u > 0.5) { // SE + quad = 1; + uStart = 0.5; + } - /** - * Creates a string representing this Matrix with each row being - * on a separate line and in the format '(column0, column1)'. - * - * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1)'. - */ - Matrix2.prototype.toString = function() { - return '(' + this[0] + ', ' + this[2] + ')\n' + - '(' + this[1] + ', ' + this[3] + ')'; - }; + var dv = new DataView(buffer); + var offset = 0; + for (var q = 0; q < quad; ++q) { + offset += dv.getUint32(offset, true); + offset += sizeOfUint32; + } + offset += sizeOfUint32; // Skip length of quad + offset += 2 * sizeOfDouble; // Skip origin - return Matrix2; -}); + // Read sizes + var xSize = CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0); + offset += sizeOfDouble; + var ySize = CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0); + offset += sizeOfDouble; -define('Core/mergeSort',[ - './defined', - './DeveloperError' - ], function( - defined, - DeveloperError) { - 'use strict'; + // Samples per quad + var xScale = rectangle.width / xSize / 2; + var yScale = rectangle.height / ySize / 2; - var leftScratchArray = []; - var rightScratchArray = []; + // Number of points + var numPoints = dv.getInt32(offset, true); + offset += sizeOfInt32; - function merge(array, compare, userDefinedObject, start, middle, end) { - var leftLength = middle - start + 1; - var rightLength = end - middle; + // Number of faces + var numIndices = dv.getInt32(offset, true) * 3; + offset += sizeOfInt32; - var left = leftScratchArray; - var right = rightScratchArray; + offset += sizeOfInt32; // Skip Level + var uBuffer = new Array(numPoints); + var vBuffer = new Array(numPoints); + var heights = new Array(numPoints); var i; - var j; + for (i = 0; i < numPoints; ++i) { + uBuffer[i] = uStart + (dv.getUint8(offset++) * xScale); + vBuffer[i] = vStart + (dv.getUint8(offset++) * yScale); - for (i = 0; i < leftLength; ++i) { - left[i] = array[start + i]; + // Height is stored in units of (1/EarthRadius) or (1/6371010.0) + heights[i] = (dv.getFloat32(offset, true) * 6371010.0); + offset += sizeOfFloat; } - for (j = 0; j < rightLength; ++j) { - right[j] = array[middle + j + 1]; + var indices = new Array(numIndices); + for (i = 0; i < numIndices; ++i) { + indices[i] = dv.getUint16(offset, true); + offset += sizeOfUint16; } - i = 0; - j = 0; - for (var k = start; k <= end; ++k) { - var leftElement = left[i]; - var rightElement = right[j]; - if (i < leftLength && (j >= rightLength || compare(leftElement, rightElement, userDefinedObject) <= 0)) { - array[k] = leftElement; - ++i; - } else if (j < rightLength) { - array[k] = rightElement; - ++j; - } - } - } + for (i = 0; i < numIndices; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; - function sort(array, compare, userDefinedObject, start, end) { - if (start >= end) { - return; - } + var u0 = uBuffer[i0]; + var u1 = uBuffer[i1]; + var u2 = uBuffer[i2]; - var middle = Math.floor((start + end) * 0.5); - sort(array, compare, userDefinedObject, start, middle); - sort(array, compare, userDefinedObject, middle + 1, end); - merge(array, compare, userDefinedObject, start, middle, end); - } + var v0 = vBuffer[i0]; + var v1 = vBuffer[i1]; + var v2 = vBuffer[i2]; - /** - * A stable merge sort. - * - * @exports mergeSort - * - * @param {Array} array The array to sort. - * @param {mergeSort~Comparator} comparator The function to use to compare elements in the array. - * @param {Object} [userDefinedObject] An object to pass as the third parameter to <code>comparator</code>. - * - * @example - * // Assume array contains BoundingSpheres in world coordinates. - * // Sort them in ascending order of distance from the camera. - * var position = camera.positionWC; - * Cesium.mergeSort(array, function(a, b, position) { - * return Cesium.BoundingSphere.distanceSquaredTo(b, position) - Cesium.BoundingSphere.distanceSquaredTo(a, position); - * }, position); - */ - function mergeSort(array, comparator, userDefinedObject) { - if (!defined(array)) { - throw new DeveloperError('array is required.'); - } - if (!defined(comparator)) { - throw new DeveloperError('comparator is required.'); + var barycentric = Intersections2D.computeBarycentricCoordinates(u, v, u0, v0, u1, v1, u2, v2, barycentricCoordinateScratch); + if (barycentric.x >= -1e-15 && barycentric.y >= -1e-15 && barycentric.z >= -1e-15) { + return barycentric.x * heights[i0] + + barycentric.y * heights[i1] + + barycentric.z * heights[i2]; + } } - - var length = array.length; - var scratchLength = Math.ceil(length * 0.5); - - // preallocate space in scratch arrays - leftScratchArray.length = scratchLength; - rightScratchArray.length = scratchLength; - sort(array, comparator, userDefinedObject, 0, length - 1); - - // trim scratch arrays - leftScratchArray.length = 0; - rightScratchArray.length = 0; + // Position does not lie in any triangle in this mesh. + return undefined; } - /** - * A function used to compare two items while performing a merge sort. - * @callback mergeSort~Comparator - * - * @param {Object} a An item in the array. - * @param {Object} b An item in the array. - * @param {Object} [userDefinedObject] An object that was passed to {@link mergeSort}. - * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, - * a positive value if <code>a</code> is greater than <code>b</code>, or - * 0 if <code>a</code> is equal to <code>b</code>. - * - * @example - * function compareNumbers(a, b, userDefinedObject) { - * return a - b; - * } - */ - - return mergeSort; + return GoogleEarthEnterpriseTerrainData; }); -define('Core/NearFarScalar',[ +define('Core/GoogleEarthEnterpriseTerrainProvider',[ + '../ThirdParty/when', + './Credit', './defaultValue', './defined', - './DeveloperError' + './defineProperties', + './deprecationWarning', + './DeveloperError', + './Event', + './GeographicTilingScheme', + './GoogleEarthEnterpriseMetadata', + './GoogleEarthEnterpriseTerrainData', + './HeightmapTerrainData', + './JulianDate', + './Math', + './Rectangle', + './Request', + './RequestState', + './RequestType', + './Resource', + './RuntimeError', + './TaskProcessor', + './TileProviderError' ], function( + when, + Credit, defaultValue, defined, - DeveloperError) { + defineProperties, + deprecationWarning, + DeveloperError, + Event, + GeographicTilingScheme, + GoogleEarthEnterpriseMetadata, + GoogleEarthEnterpriseTerrainData, + HeightmapTerrainData, + JulianDate, + CesiumMath, + Rectangle, + Request, + RequestState, + RequestType, + Resource, + RuntimeError, + TaskProcessor, + TileProviderError) { 'use strict'; - /** - * Represents a scalar value's lower and upper bound at a near distance and far distance in eye space. - * @alias NearFarScalar - * @constructor - * - * @param {Number} [near=0.0] The lower bound of the camera range. - * @param {Number} [nearValue=0.0] The value at the lower bound of the camera range. - * @param {Number} [far=1.0] The upper bound of the camera range. - * @param {Number} [farValue=0.0] The value at the upper bound of the camera range. - * - * @see Packable - */ - function NearFarScalar(near, nearValue, far, farValue) { - /** - * The lower bound of the camera range. - * @type {Number} - * @default 0.0 - */ - this.near = defaultValue(near, 0.0); - /** - * The value at the lower bound of the camera range. - * @type {Number} - * @default 0.0 - */ - this.nearValue = defaultValue(nearValue, 0.0); - /** - * The upper bound of the camera range. - * @type {Number} - * @default 1.0 - */ - this.far = defaultValue(far, 1.0); - /** - * The value at the upper bound of the camera range. - * @type {Number} - * @default 0.0 - */ - this.farValue = defaultValue(farValue, 0.0); - } + var TerrainState = { + UNKNOWN : 0, + NONE : 1, + SELF : 2, + PARENT : 3 + }; - /** - * Duplicates a NearFarScalar instance. - * - * @param {NearFarScalar} nearFarScalar The NearFarScalar to duplicate. - * @param {NearFarScalar} [result] The object onto which to store the result. - * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. (Returns undefined if nearFarScalar is undefined) - */ - NearFarScalar.clone = function(nearFarScalar, result) { - if (!defined(nearFarScalar)) { - return undefined; - } + var julianDateScratch = new JulianDate(); - if (!defined(result)) { - return new NearFarScalar(nearFarScalar.near, nearFarScalar.nearValue, nearFarScalar.far, nearFarScalar.farValue); - } + function TerrainCache() { + this._terrainCache = {}; + this._lastTidy = JulianDate.now(); + } - result.near = nearFarScalar.near; - result.nearValue = nearFarScalar.nearValue; - result.far = nearFarScalar.far; - result.farValue = nearFarScalar.farValue; - return result; + TerrainCache.prototype.add = function(quadKey, buffer) { + this._terrainCache[quadKey] = { + buffer : buffer, + timestamp : JulianDate.now() + }; }; - - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - NearFarScalar.packedLength = 4; - - /** - * Stores the provided instance into the provided array. - * - * @param {NearFarScalar} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - NearFarScalar.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); + TerrainCache.prototype.get = function(quadKey) { + var terrainCache = this._terrainCache; + var result = terrainCache[quadKey]; + if (defined(result)) { + delete this._terrainCache[quadKey]; + return result.buffer; } - - startingIndex = defaultValue(startingIndex, 0); - - array[startingIndex++] = value.near; - array[startingIndex++] = value.nearValue; - array[startingIndex++] = value.far; - array[startingIndex] = value.farValue; - - return array; }; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {NearFarScalar} [result] The object into which to store the result. - * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. - */ - NearFarScalar.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + TerrainCache.prototype.tidy = function() { + JulianDate.now(julianDateScratch); + if (JulianDate.secondsDifference(julianDateScratch, this._lastTidy) > 10) { + var terrainCache = this._terrainCache; + var keys = Object.keys(terrainCache); + var count = keys.length; + for (var i = 0; i < count; ++i) { + var k = keys[i]; + var e = terrainCache[k]; + if (JulianDate.secondsDifference(julianDateScratch, e.timestamp) > 10) { + delete terrainCache[k]; + } + } - if (!defined(result)) { - result = new NearFarScalar(); + JulianDate.clone(julianDateScratch, this._lastTidy); } - result.near = array[startingIndex++]; - result.nearValue = array[startingIndex++]; - result.far = array[startingIndex++]; - result.farValue = array[startingIndex]; - return result; }; /** - * Compares the provided NearFarScalar and returns <code>true</code> if they are equal, - * <code>false</code> otherwise. + * Provides tiled terrain using the Google Earth Enterprise REST API. * - * @param {NearFarScalar} [left] The first NearFarScalar. - * @param {NearFarScalar} [right] The second NearFarScalar. - * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. - */ - NearFarScalar.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.near === right.near) && - (left.nearValue === right.nearValue) && - (left.far === right.far) && - (left.farValue === right.farValue)); - }; - - /** - * Duplicates this instance. + * @alias GoogleEarthEnterpriseTerrainProvider + * @constructor * - * @param {NearFarScalar} [result] The object onto which to store the result. - * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. - */ - NearFarScalar.prototype.clone = function(result) { - return NearFarScalar.clone(this, result); - }; - - /** - * Compares this instance to the provided NearFarScalar and returns <code>true</code> if they are equal, - * <code>false</code> otherwise. + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url of the Google Earth Enterprise server hosting the imagery. + * @param {GoogleEarthEnterpriseMetadata} options.metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseImageryProvider. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * - * @param {NearFarScalar} [right] The right hand side NearFarScalar. - * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. + * @see GoogleEarthEnterpriseImageryProvider + * @see CesiumTerrainProvider + * + * @example + * var geeMetadata = new GoogleEarthEnterpriseMetadata('http://www.earthenterprise.org/3d'); + * var gee = new Cesium.GoogleEarthEnterpriseTerrainProvider({ + * metadata : geeMetadata + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ - NearFarScalar.prototype.equals = function(right) { - return NearFarScalar.equals(this, right); - }; - - return NearFarScalar; -}); + function GoogleEarthEnterpriseTerrainProvider(options) { + options = defaultValue(options, {}); -define('Core/Visibility',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + if (!(defined(options.url) || defined(options.metadata))) { + throw new DeveloperError('options.url or options.metadata is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('GoogleEarthEnterpriseTerrainProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); + } - /** - * This enumerated type is used in determining to what extent an object, the occludee, - * is visible during horizon culling. An occluder may fully block an occludee, in which case - * it has no visibility, may partially block an occludee from view, or may not block it at all, - * leading to full visibility. - * - * @exports Visibility - */ - var Visibility = { - /** - * Represents that no part of an object is visible. - * - * @type {Number} - * @constant - */ - NONE : -1, + var metadata; + if (defined(options.metadata)) { + metadata = options.metadata; + } else { + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); + metadata = new GoogleEarthEnterpriseMetadata(resource); + } - /** - * Represents that part, but not all, of an object is visible - * - * @type {Number} - * @constant - */ - PARTIAL : 0, + this._metadata = metadata; + this._tilingScheme = new GeographicTilingScheme({ + numberOfLevelZeroTilesX : 2, + numberOfLevelZeroTilesY : 2, + rectangle : new Rectangle(-CesiumMath.PI, -CesiumMath.PI, CesiumMath.PI, CesiumMath.PI), + ellipsoid : options.ellipsoid + }); - /** - * Represents that an object is visible in its entirety. - * - * @type {Number} - * @constant - */ - FULL : 1 - }; + var credit = options.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); + } + this._credit = credit; - return freezeObject(Visibility); -}); + // Pulled from Google's documentation + this._levelZeroMaximumGeometricError = 40075.16; -define('Core/Occluder',[ - './BoundingSphere', - './Cartesian3', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid', - './Math', - './Rectangle', - './Visibility' - ], function( - BoundingSphere, - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Ellipsoid, - CesiumMath, - Rectangle, - Visibility) { - 'use strict'; + this._terrainCache = new TerrainCache(); + this._terrainPromises = {}; + this._terrainRequests = {}; - /** - * Creates an Occluder derived from an object's position and radius, as well as the camera position. - * The occluder can be used to determine whether or not other objects are visible or hidden behind the - * visible horizon defined by the occluder and camera position. - * - * @alias Occluder - * - * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. - * @param {Cartesian3} cameraPosition The coordinate of the viewer/camera. - * - * @constructor - * - * @example - * // Construct an occluder one unit away from the origin with a radius of one. - * var cameraPosition = Cesium.Cartesian3.ZERO; - * var occluderBoundingSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1), 1); - * var occluder = new Cesium.Occluder(occluderBoundingSphere, cameraPosition); - */ - function Occluder(occluderBoundingSphere, cameraPosition) { - if (!defined(occluderBoundingSphere)) { - throw new DeveloperError('occluderBoundingSphere is required.'); - } - if (!defined(cameraPosition)) { - throw new DeveloperError('camera position is required.'); - } - - this._occluderPosition = Cartesian3.clone(occluderBoundingSphere.center); - this._occluderRadius = occluderBoundingSphere.radius; + this._errorEvent = new Event(); - this._horizonDistance = 0.0; - this._horizonPlaneNormal = undefined; - this._horizonPlanePosition = undefined; - this._cameraPosition = undefined; + this._ready = false; + var that = this; + var metadataError; + this._readyPromise = metadata.readyPromise + .then(function(result) { + if (!metadata.terrainPresent) { + var e = new RuntimeError('The server ' + metadata.url + ' doesn\'t have terrain'); + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); + return when.reject(e); + } - // cameraPosition fills in the above values - this.cameraPosition = cameraPosition; + TileProviderError.handleSuccess(metadataError); + that._ready = result; + return result; + }) + .otherwise(function(e) { + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); + return when.reject(e); + }); } - var scratchCartesian3 = new Cartesian3(); - - defineProperties(Occluder.prototype, { + defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { /** - * The position of the occluder. - * @memberof Occluder.prototype - * @type {Cartesian3} + * Gets the name of the Google Earth Enterprise server url hosting the imagery. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {String} + * @readonly */ - position: { - get: function() { - return this._occluderPosition; + url : { + get : function() { + return this._metadata.url; } }, /** - * The radius of the occluder. - * @memberof Occluder.prototype - * @type {Number} + * Gets the proxy used by this provider. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Proxy} + * @readonly */ - radius: { - get: function() { - return this._occluderRadius; + proxy : { + get : function() { + return this._metadata.proxy; } }, /** - * The position of the camera. - * @memberof Occluder.prototype - * @type {Cartesian3} + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {TilingScheme} + * @readonly */ - cameraPosition: { - set: function(cameraPosition) { - if (!defined(cameraPosition)) { - throw new DeveloperError('cameraPosition is required.'); + tilingScheme : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); } - cameraPosition = Cartesian3.clone(cameraPosition, this._cameraPosition); - - var cameraToOccluderVec = Cartesian3.subtract(this._occluderPosition, cameraPosition, scratchCartesian3); - var invCameraToOccluderDistance = Cartesian3.magnitudeSquared(cameraToOccluderVec); - var occluderRadiusSqrd = this._occluderRadius * this._occluderRadius; + return this._tilingScheme; + } + }, - var horizonDistance; - var horizonPlaneNormal; - var horizonPlanePosition; - if (invCameraToOccluderDistance > occluderRadiusSqrd) { - horizonDistance = Math.sqrt(invCameraToOccluderDistance - occluderRadiusSqrd); - invCameraToOccluderDistance = 1.0 / Math.sqrt(invCameraToOccluderDistance); - horizonPlaneNormal = Cartesian3.multiplyByScalar(cameraToOccluderVec, invCameraToOccluderDistance, scratchCartesian3); - var nearPlaneDistance = horizonDistance * horizonDistance * invCameraToOccluderDistance; - horizonPlanePosition = Cartesian3.add(cameraPosition, Cartesian3.multiplyByScalar(horizonPlaneNormal, nearPlaneDistance, scratchCartesian3), scratchCartesian3); - } else { - horizonDistance = Number.MAX_VALUE; - } + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, - this._horizonDistance = horizonDistance; - this._horizonPlaneNormal = horizonPlaneNormal; - this._horizonPlanePosition = horizonPlanePosition; - this._cameraPosition = cameraPosition; + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; } - } - }); + }, - /** - * Creates an occluder from a bounding sphere and the camera position. - * - * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. - * @param {Cartesian3} cameraPosition The coordinate of the viewer/camera. - * @param {Occluder} [result] The object onto which to store the result. - * @returns {Occluder} The occluder derived from an object's position and radius, as well as the camera position. - */ - Occluder.fromBoundingSphere = function(occluderBoundingSphere, cameraPosition, result) { - if (!defined(occluderBoundingSphere)) { - throw new DeveloperError('occluderBoundingSphere is required.'); - } + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise; + } + }, - if (!defined(cameraPosition)) { - throw new DeveloperError('camera position is required.'); - } - - if (!defined(result)) { - return new Occluder(occluderBoundingSphere, cameraPosition); - } - - Cartesian3.clone(occluderBoundingSphere.center, result._occluderPosition); - result._occluderRadius = occluderBoundingSphere.radius; - result.cameraPosition = cameraPosition; - - return result; - }; + /** + * Gets the credit to display when this terrain provider is active. Typically this is used to credit + * the source of the terrain. This function should not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return this._credit; + } + }, + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Boolean} + */ + hasWaterMask : { + get : function() { + return false; + } + }, - var tempVecScratch = new Cartesian3(); + /** + * Gets a value indicating whether or not the requested tiles include vertex normals. + * This function should not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { + get : function() { + return false; + } + }, - /** - * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder. - * - * @param {Cartesian3} occludee The point surrounding the occludee object. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. - * - * - * @example - * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); - * var littleSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1), 0.25); - * var occluder = new Cesium.Occluder(littleSphere, cameraPosition); - * var point = new Cesium.Cartesian3(0, 0, -3); - * occluder.isPointVisible(point); //returns true - * - * @see Occluder#computeVisibility - */ - Occluder.prototype.isPointVisible = function(occludee) { - if (this._horizonDistance !== Number.MAX_VALUE) { - var tempVec = Cartesian3.subtract(occludee, this._occluderPosition, tempVecScratch); - var temp = this._occluderRadius; - temp = Cartesian3.magnitudeSquared(tempVec) - (temp * temp); - if (temp > 0.0) { - temp = Math.sqrt(temp) + this._horizonDistance; - tempVec = Cartesian3.subtract(occludee, this._cameraPosition, tempVec); - return temp * temp > Cartesian3.magnitudeSquared(tempVec); + /** + * Gets an object that can be used to determine availability of terrain from this provider, such as + * at points and in rectangles. This function should not be called before + * {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. This property may be undefined if availability + * information is not available. + * @memberof GoogleEarthEnterpriseTerrainProvider.prototype + * @type {TileAvailability} + */ + availability : { + get : function() { + return undefined; } } - return false; - }; - - var occludeePositionScratch = new Cartesian3(); - - /** - * Determines whether or not a sphere, the <code>occludee</code>, is hidden from view by the occluder. - * - * @param {BoundingSphere} occludee The bounding sphere surrounding the occludee object. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. - * - * - * @example - * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); - * var littleSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1), 0.25); - * var occluder = new Cesium.Occluder(littleSphere, cameraPosition); - * var bigSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -3), 1); - * occluder.isBoundingSphereVisible(bigSphere); //returns true - * - * @see Occluder#computeVisibility - */ - Occluder.prototype.isBoundingSphereVisible = function(occludee) { - var occludeePosition = Cartesian3.clone(occludee.center, occludeePositionScratch); - var occludeeRadius = occludee.radius; + }); - if (this._horizonDistance !== Number.MAX_VALUE) { - var tempVec = Cartesian3.subtract(occludeePosition, this._occluderPosition, tempVecScratch); - var temp = this._occluderRadius - occludeeRadius; - temp = Cartesian3.magnitudeSquared(tempVec) - (temp * temp); - if (occludeeRadius < this._occluderRadius) { - if (temp > 0.0) { - temp = Math.sqrt(temp) + this._horizonDistance; - tempVec = Cartesian3.subtract(occludeePosition, this._cameraPosition, tempVec); - return ((temp * temp) + (occludeeRadius * occludeeRadius)) > Cartesian3.magnitudeSquared(tempVec); - } - return false; - } + var taskProcessor = new TaskProcessor('decodeGoogleEarthEnterprisePacket', Number.POSITIVE_INFINITY); - // Prevent against the case where the occludee radius is larger than the occluder's; since this is - // an uncommon case, the following code should rarely execute. - if (temp > 0.0) { - tempVec = Cartesian3.subtract(occludeePosition, this._cameraPosition, tempVec); - var tempVecMagnitudeSquared = Cartesian3.magnitudeSquared(tempVec); - var occluderRadiusSquared = this._occluderRadius * this._occluderRadius; - var occludeeRadiusSquared = occludeeRadius * occludeeRadius; - if ((((this._horizonDistance * this._horizonDistance) + occluderRadiusSquared) * occludeeRadiusSquared) > - (tempVecMagnitudeSquared * occluderRadiusSquared)) { - // The occludee is close enough that the occluder cannot possible occlude the occludee - return true; + // If the tile has its own terrain, then you can just use its child bitmask. If it was requested using it's parent + // then you need to check all of its children to see if they have terrain. + function computeChildMask(quadKey, info, metadata) { + var childMask = info.getChildBitmask(); + if (info.terrainState === TerrainState.PARENT) { + childMask = 0; + for (var i = 0; i < 4; ++i) { + var child = metadata.getTileInformationFromQuadKey(quadKey + i.toString()); + if (defined(child) && child.hasTerrain()) { + childMask |= (1 << i); } - temp = Math.sqrt(temp) + this._horizonDistance; - return ((temp * temp) + occludeeRadiusSquared) > tempVecMagnitudeSquared; } - - // The occludee completely encompasses the occluder - return true; } - return false; - }; + return childMask; + } - var tempScratch = new Cartesian3(); /** - * Determine to what extent an occludee is visible (not visible, partially visible, or fully visible). - * - * @param {BoundingSphere} occludeeBS The bounding sphere of the occludee. - * @returns {Number} Visibility.NONE if the occludee is not visible, - * Visibility.PARTIAL if the occludee is partially visible, or - * Visibility.FULL if the occludee is fully visible. - * + * Requests the geometry for a given tile. This function should not be called before + * {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. The result must include terrain data and + * may optionally include a water mask and an indication of which child tiles are available. * - * @example - * var sphere1 = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1.5), 0.5); - * var sphere2 = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -2.5), 0.5); - * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); - * var occluder = new Cesium.Occluder(sphere1, cameraPosition); - * occluder.computeVisibility(sphere2); //returns Visibility.NONE + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * returns undefined instead of a promise, it is an indication that too many requests are already + * pending and the request will be retried later. * - * @see Occluder#isVisible + * @exception {DeveloperError} This function must not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} + * returns true. */ - Occluder.prototype.computeVisibility = function(occludeeBS) { - if (!defined(occludeeBS)) { - throw new DeveloperError('occludeeBS is required.'); + GoogleEarthEnterpriseTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestTileGeometry must not be called before the terrain provider is ready.'); } - // If the occludee radius is larger than the occluders, this will return that - // the entire ocludee is visible, even though that may not be the case, though this should - // not occur too often. - var occludeePosition = Cartesian3.clone(occludeeBS.center); - var occludeeRadius = occludeeBS.radius; + var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); + var terrainCache = this._terrainCache; + var metadata = this._metadata; + var info = metadata.getTileInformationFromQuadKey(quadKey); - if (occludeeRadius > this._occluderRadius) { - return Visibility.FULL; + // Check if this tile is even possibly available + if (!defined(info)) { + return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); } - if (this._horizonDistance !== Number.MAX_VALUE) { - // The camera is outside the occluder - var tempVec = Cartesian3.subtract(occludeePosition, this._occluderPosition, tempScratch); - var temp = this._occluderRadius - occludeeRadius; - var occluderToOccludeeDistSqrd = Cartesian3.magnitudeSquared(tempVec); - temp = occluderToOccludeeDistSqrd - (temp * temp); - if (temp > 0.0) { - // The occludee is not completely inside the occluder - // Check to see if the occluder completely hides the occludee - temp = Math.sqrt(temp) + this._horizonDistance; - tempVec = Cartesian3.subtract(occludeePosition, this._cameraPosition, tempVec); - var cameraToOccludeeDistSqrd = Cartesian3.magnitudeSquared(tempVec); - if (((temp * temp) + (occludeeRadius * occludeeRadius)) < cameraToOccludeeDistSqrd) { - return Visibility.NONE; - } - - // Check to see whether the occluder is fully or partially visible - // when the occludee does not intersect the occluder - temp = this._occluderRadius + occludeeRadius; - temp = occluderToOccludeeDistSqrd - (temp * temp); - if (temp > 0.0) { - // The occludee does not intersect the occluder. - temp = Math.sqrt(temp) + this._horizonDistance; - return (cameraToOccludeeDistSqrd < ((temp * temp)) + (occludeeRadius * occludeeRadius)) ? Visibility.FULL : Visibility.PARTIAL; - } - - //Check to see if the occluder is fully or partially visible when the occludee DOES - //intersect the occluder - tempVec = Cartesian3.subtract(occludeePosition, this._horizonPlanePosition, tempVec); - return (Cartesian3.dot(tempVec, this._horizonPlaneNormal) > -occludeeRadius) ? Visibility.PARTIAL : Visibility.FULL; - } + var terrainState = info.terrainState; + if (!defined(terrainState)) { + // First time we have tried to load this tile, so set terrain state to UNKNOWN + terrainState = info.terrainState = TerrainState.UNKNOWN; } - return Visibility.NONE; - }; - var occludeePointScratch = new Cartesian3(); - /** - * Computes a point that can be used as the occludee position to the visibility functions. - * Use a radius of zero for the occludee radius. Typically, a user computes a bounding sphere around - * an object that is used for visibility; however it is also possible to compute a point that if - * seen/not seen would also indicate if an object is visible/not visible. This function is better - * called for objects that do not move relative to the occluder and is large, such as a chunk of - * terrain. You are better off not calling this and using the object's bounding sphere for objects - * such as a satellite or ground vehicle. - * - * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. - * @param {Cartesian3} occludeePosition The point where the occludee (bounding sphere of radius 0) is located. - * @param {Cartesian3[]} positions List of altitude points on the horizon near the surface of the occluder. - * @returns {Object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> - * which is a boolean value. - * - * @exception {DeveloperError} <code>positions</code> must contain at least one element. - * @exception {DeveloperError} <code>occludeePosition</code> must have a value other than <code>occluderBoundingSphere.center</code>. - * - * @example - * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); - * var occluderBoundingSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -8), 2); - * var occluder = new Cesium.Occluder(occluderBoundingSphere, cameraPosition); - * var positions = [new Cesium.Cartesian3(-0.25, 0, -5.3), new Cesium.Cartesian3(0.25, 0, -5.3)]; - * var tileOccluderSphere = Cesium.BoundingSphere.fromPoints(positions); - * var occludeePosition = tileOccluderSphere.center; - * var occludeePt = Cesium.Occluder.computeOccludeePoint(occluderBoundingSphere, occludeePosition, positions); - */ - Occluder.computeOccludeePoint = function(occluderBoundingSphere, occludeePosition, positions) { - if (!defined(occluderBoundingSphere)) { - throw new DeveloperError('occluderBoundingSphere is required.'); - } - if (!defined(positions)) { - throw new DeveloperError('positions is required.'); + // If its in the cache, return it + var buffer = terrainCache.get(quadKey); + if (defined(buffer)) { + var credit = metadata.providers[info.terrainProvider]; + return new GoogleEarthEnterpriseTerrainData({ + buffer : buffer, + childTileMask : computeChildMask(quadKey, info, metadata), + credits : defined(credit) ? [credit] : undefined, + negativeAltitudeExponentBias: metadata.negativeAltitudeExponentBias, + negativeElevationThreshold: metadata.negativeAltitudeThreshold + }); } - if (positions.length === 0) { - throw new DeveloperError('positions must contain at least one element'); + + // Clean up the cache + terrainCache.tidy(); + + // We have a tile, check to see if no ancestors have terrain or that we know for sure it doesn't + if (!info.ancestorHasTerrain) { + // We haven't reached a level with terrain, so return the ellipsoid + return new HeightmapTerrainData({ + buffer : new Uint8Array(16 * 16), + width : 16, + height : 16 + }); + } else if (terrainState === TerrainState.NONE) { + // Already have info and there isn't any terrain here + return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); } - - var occludeePos = Cartesian3.clone(occludeePosition); - var occluderPosition = Cartesian3.clone(occluderBoundingSphere.center); - var occluderRadius = occluderBoundingSphere.radius; - var numPositions = positions.length; - if (Cartesian3.equals(occluderPosition, occludeePosition)) { - throw new DeveloperError('occludeePosition must be different than occluderBoundingSphere.center'); + // Figure out where we are getting the terrain and what version + var parentInfo; + var q = quadKey; + var terrainVersion = -1; + switch (terrainState) { + case TerrainState.SELF: // We have terrain and have retrieved it before + terrainVersion = info.terrainVersion; + break; + case TerrainState.PARENT: // We have terrain in our parent + q = q.substring(0, q.length - 1); + parentInfo = metadata.getTileInformationFromQuadKey(q); + terrainVersion = parentInfo.terrainVersion; + break; + case TerrainState.UNKNOWN: // We haven't tried to retrieve terrain yet + if (info.hasTerrain()) { + terrainVersion = info.terrainVersion; // We should have terrain + } else { + q = q.substring(0, q.length - 1); + parentInfo = metadata.getTileInformationFromQuadKey(q); + if (defined(parentInfo) && parentInfo.hasTerrain()) { + terrainVersion = parentInfo.terrainVersion; // Try checking in the parent + } + } + break; } - - // Compute a plane with a normal from the occluder to the occludee position. - var occluderPlaneNormal = Cartesian3.normalize(Cartesian3.subtract(occludeePos, occluderPosition, occludeePointScratch), occludeePointScratch); - var occluderPlaneD = -(Cartesian3.dot(occluderPlaneNormal, occluderPosition)); - //For each position, determine the horizon intersection. Choose the position and intersection - //that results in the greatest angle with the occcluder plane. - var aRotationVector = Occluder._anyRotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD); - var dot = Occluder._horizonToPlaneNormalDotProduct(occluderBoundingSphere, occluderPlaneNormal, occluderPlaneD, aRotationVector, positions[0]); - if (!dot) { - //The position is inside the mimimum radius, which is invalid - return undefined; + // We can't figure out where to get the terrain + if (terrainVersion < 0) { + return when.reject(new RuntimeError('Terrain tile doesn\'t exist')); } - var tempDot; - for ( var i = 1; i < numPositions; ++i) { - tempDot = Occluder._horizonToPlaneNormalDotProduct(occluderBoundingSphere, occluderPlaneNormal, occluderPlaneD, aRotationVector, positions[i]); - if (!tempDot) { - //The position is inside the minimum radius, which is invalid - return undefined; - } - if (tempDot < dot) { - dot = tempDot; + + // Load that terrain + var terrainPromises = this._terrainPromises; + var terrainRequests = this._terrainRequests; + var sharedPromise; + var sharedRequest; + if (defined(terrainPromises[q])) { // Already being loaded possibly from another child, so return existing promise + sharedPromise = terrainPromises[q]; + sharedRequest = terrainRequests[q]; + } else { // Create new request for terrain + sharedRequest = request; + var requestPromise = buildTerrainResource(this, q, terrainVersion, sharedRequest).fetchArrayBuffer(); + + if (!defined(requestPromise)) { + return undefined; // Throttled } - } - //Verify that the dot is not near 90 degress - if (dot < 0.00174532836589830883577820272085) { - return undefined; - } - var distance = occluderRadius / dot; - return Cartesian3.add(occluderPosition, Cartesian3.multiplyByScalar(occluderPlaneNormal, distance, occludeePointScratch), occludeePointScratch); - }; + sharedPromise = requestPromise + .then(function(terrain) { + if (defined(terrain)) { + return taskProcessor.scheduleTask({ + buffer : terrain, + type : 'Terrain', + key : metadata.key + }, [terrain]) + .then(function(terrainTiles) { + // Add requested tile and mark it as SELF + var requestedInfo = metadata.getTileInformationFromQuadKey(q); + requestedInfo.terrainState = TerrainState.SELF; + terrainCache.add(q, terrainTiles[0]); + var provider = requestedInfo.terrainProvider; - var computeOccludeePointFromRectangleScratch = []; - /** - * Computes a point that can be used as the occludee position to the visibility functions from a rectangle. - * - * @param {Rectangle} rectangle The rectangle used to create a bounding sphere. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle. - * @returns {Object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> - * which is a boolean value. - */ - Occluder.computeOccludeePointFromRectangle = function(rectangle, ellipsoid) { - if (!defined(rectangle)) { - throw new DeveloperError('rectangle is required.'); - } - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - var positions = Rectangle.subsample(rectangle, ellipsoid, 0.0, computeOccludeePointFromRectangleScratch); - var bs = BoundingSphere.fromPoints(positions); + // Add children to cache + var count = terrainTiles.length - 1; + for (var j = 0; j < count; ++j) { + var childKey = q + j.toString(); + var child = metadata.getTileInformationFromQuadKey(childKey); + if (defined(child)) { + terrainCache.add(childKey, terrainTiles[j + 1]); + child.terrainState = TerrainState.PARENT; + if (child.terrainProvider === 0) { + child.terrainProvider = provider; + } + } + } + }); + } - // TODO: get correct ellipsoid center - var ellipsoidCenter = Cartesian3.ZERO; - if (!Cartesian3.equals(ellipsoidCenter, bs.center)) { - return Occluder.computeOccludeePoint(new BoundingSphere(ellipsoidCenter, ellipsoid.minimumRadius), bs.center, positions); - } + return when.reject(new RuntimeError('Failed to load terrain.')); + }); - return undefined; - }; + terrainPromises[q] = sharedPromise; // Store promise without delete from terrainPromises + terrainRequests[q] = sharedRequest; - var tempVec0Scratch = new Cartesian3(); - Occluder._anyRotationVector = function(occluderPosition, occluderPlaneNormal, occluderPlaneD) { - var tempVec0 = Cartesian3.abs(occluderPlaneNormal, tempVec0Scratch); - var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1; - if (((majorAxis === 0) && (tempVec0.z > tempVec0.x)) || ((majorAxis === 1) && (tempVec0.z > tempVec0.y))) { - majorAxis = 2; - } - var tempVec = new Cartesian3(); - var tempVec1; - if (majorAxis === 0) { - tempVec0.x = occluderPosition.x; - tempVec0.y = occluderPosition.y + 1.0; - tempVec0.z = occluderPosition.z + 1.0; - tempVec1 = Cartesian3.UNIT_X; - } else if (majorAxis === 1) { - tempVec0.x = occluderPosition.x + 1.0; - tempVec0.y = occluderPosition.y; - tempVec0.z = occluderPosition.z + 1.0; - tempVec1 = Cartesian3.UNIT_Y; - } else { - tempVec0.x = occluderPosition.x + 1.0; - tempVec0.y = occluderPosition.y + 1.0; - tempVec0.z = occluderPosition.z; - tempVec1 = Cartesian3.UNIT_Z; + // Set promise so we remove from terrainPromises just one time + sharedPromise = sharedPromise + .always(function() { + delete terrainPromises[q]; + delete terrainRequests[q]; + }); } - var u = (Cartesian3.dot(occluderPlaneNormal, tempVec0) + occluderPlaneD) / -(Cartesian3.dot(occluderPlaneNormal, tempVec1)); - return Cartesian3.normalize(Cartesian3.subtract(Cartesian3.add(tempVec0, Cartesian3.multiplyByScalar(tempVec1, u, tempVec), tempVec0), occluderPosition, tempVec0), tempVec0); + + return sharedPromise + .then(function() { + var buffer = terrainCache.get(quadKey); + if (defined(buffer)) { + var credit = metadata.providers[info.terrainProvider]; + return new GoogleEarthEnterpriseTerrainData({ + buffer : buffer, + childTileMask : computeChildMask(quadKey, info, metadata), + credits : defined(credit) ? [credit] : undefined, + negativeAltitudeExponentBias: metadata.negativeAltitudeExponentBias, + negativeElevationThreshold: metadata.negativeAltitudeThreshold + }); + } + + return when.reject(new RuntimeError('Failed to load terrain.')); + }) + .otherwise(function(error) { + if (sharedRequest.state === RequestState.CANCELLED) { + request.state = sharedRequest.state; + return when.reject(error); + } + info.terrainState = TerrainState.NONE; + return when.reject(error); + }); }; - var posDirectionScratch = new Cartesian3(); - Occluder._rotationVector = function(occluderPosition, occluderPlaneNormal, occluderPlaneD, position, anyRotationVector) { - //Determine the angle between the occluder plane normal and the position direction - var positionDirection = Cartesian3.subtract(position, occluderPosition, posDirectionScratch); - positionDirection = Cartesian3.normalize(positionDirection, positionDirection); - if (Cartesian3.dot(occluderPlaneNormal, positionDirection) < 0.99999998476912904932780850903444) { - var crossProduct = Cartesian3.cross(occluderPlaneNormal, positionDirection, positionDirection); - var length = Cartesian3.magnitude(crossProduct); - if (length > CesiumMath.EPSILON13) { - return Cartesian3.normalize(crossProduct, new Cartesian3()); - } - } - //The occluder plane normal and the position direction are colinear. Use any - //vector in the occluder plane as the rotation vector - return anyRotationVector; + /** + * Gets the maximum geometric error allowed in a tile at a given level. + * + * @param {Number} level The tile level for which to get the maximum geometric error. + * @returns {Number} The maximum geometric error. + */ + GoogleEarthEnterpriseTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { + return this._levelZeroMaximumGeometricError / (1 << level); }; - var posScratch1 = new Cartesian3(); - var occluerPosScratch = new Cartesian3(); - var posScratch2 = new Cartesian3(); - var horizonPlanePosScratch = new Cartesian3(); - Occluder._horizonToPlaneNormalDotProduct = function(occluderBS, occluderPlaneNormal, occluderPlaneD, anyRotationVector, position) { - var pos = Cartesian3.clone(position, posScratch1); - var occluderPosition = Cartesian3.clone(occluderBS.center, occluerPosScratch); - var occluderRadius = occluderBS.radius; + /** + * Determines whether data for a tile is available to be loaded. + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @returns {Boolean} Undefined if not supported, otherwise true or false. + */ + GoogleEarthEnterpriseTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + var metadata = this._metadata; + var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - //Verify that the position is outside the occluder - var positionToOccluder = Cartesian3.subtract(occluderPosition, pos, posScratch2); - var occluderToPositionDistanceSquared = Cartesian3.magnitudeSquared(positionToOccluder); - var occluderRadiusSquared = occluderRadius * occluderRadius; - if (occluderToPositionDistanceSquared < occluderRadiusSquared) { + var info = metadata.getTileInformation(x, y, level); + if (info === null) { return false; } - //Horizon parameters - var horizonDistanceSquared = occluderToPositionDistanceSquared - occluderRadiusSquared; - var horizonDistance = Math.sqrt(horizonDistanceSquared); - var occluderToPositionDistance = Math.sqrt(occluderToPositionDistanceSquared); - var invOccluderToPositionDistance = 1.0 / occluderToPositionDistance; - var cosTheta = horizonDistance * invOccluderToPositionDistance; - var horizonPlaneDistance = cosTheta * horizonDistance; - positionToOccluder = Cartesian3.normalize(positionToOccluder, positionToOccluder); - var horizonPlanePosition = Cartesian3.add(pos, Cartesian3.multiplyByScalar(positionToOccluder, horizonPlaneDistance, horizonPlanePosScratch), horizonPlanePosScratch); - var horizonCrossDistance = Math.sqrt(horizonDistanceSquared - (horizonPlaneDistance * horizonPlaneDistance)); + if (defined(info)) { + if (!info.ancestorHasTerrain) { + return true; // We'll just return the ellipsoid + } - //Rotate the position to occluder vector 90 degrees - var tempVec = this._rotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD, pos, anyRotationVector); - var horizonCrossDirection = Cartesian3.fromElements( - (tempVec.x * tempVec.x * positionToOccluder.x) + ((tempVec.x * tempVec.y - tempVec.z) * positionToOccluder.y) + ((tempVec.x * tempVec.z + tempVec.y) * positionToOccluder.z), - ((tempVec.x * tempVec.y + tempVec.z) * positionToOccluder.x) + (tempVec.y * tempVec.y * positionToOccluder.y) + ((tempVec.y * tempVec.z - tempVec.x) * positionToOccluder.z), - ((tempVec.x * tempVec.z - tempVec.y) * positionToOccluder.x) + ((tempVec.y * tempVec.z + tempVec.x) * positionToOccluder.y) + (tempVec.z * tempVec.z * positionToOccluder.z), - posScratch1); - horizonCrossDirection = Cartesian3.normalize(horizonCrossDirection, horizonCrossDirection); + var terrainState = info.terrainState; + if (terrainState === TerrainState.NONE) { + return false; // Terrain is not available + } - //Horizon positions - var offset = Cartesian3.multiplyByScalar(horizonCrossDirection, horizonCrossDistance, posScratch1); - tempVec = Cartesian3.normalize(Cartesian3.subtract(Cartesian3.add(horizonPlanePosition, offset, posScratch2), occluderPosition, posScratch2), posScratch2); - var dot0 = Cartesian3.dot(occluderPlaneNormal, tempVec); - tempVec = Cartesian3.normalize(Cartesian3.subtract(Cartesian3.subtract(horizonPlanePosition, offset, tempVec), occluderPosition, tempVec), tempVec); - var dot1 = Cartesian3.dot(occluderPlaneNormal, tempVec); - return (dot0 < dot1) ? dot0 : dot1; + if (!defined(terrainState) || (terrainState === TerrainState.UNKNOWN)) { + info.terrainState = TerrainState.UNKNOWN; + if (!info.hasTerrain()) { + quadKey = quadKey.substring(0, quadKey.length - 1); + var parentInfo = metadata.getTileInformationFromQuadKey(quadKey); + if (!defined(parentInfo) || !parentInfo.hasTerrain()) { + return false; + } + } + } + + return true; + } + + if (metadata.isValid(quadKey)) { + // We will need this tile, so request metadata and return false for now + var request = new Request({ + throttle : true, + throttleByServer : true, + type : RequestType.TERRAIN + }); + metadata.populateSubtree(x, y, level, request); + } + return false; }; - return Occluder; + // + // Functions to handle imagery packets + // + function buildTerrainResource(terrainProvider, quadKey, version, request) { + version = (defined(version) && version > 0) ? version : 1; + return terrainProvider._metadata.resource.getDerivedResource({ + url: 'flatfile?f1c-0' + quadKey + '-t.' + version.toString(), + request: request + }); + } + + return GoogleEarthEnterpriseTerrainProvider; }); -define('Core/Packable',[ - './DeveloperError' +define('Core/HeadingPitchRange',[ + './defaultValue', + './defined' ], function( - DeveloperError) { + defaultValue, + defined) { 'use strict'; /** - * Static interface for types which can store their values as packed - * elements in an array. These methods and properties are expected to be - * defined on a constructor function. - * - * @exports Packable + * Defines a heading angle, pitch angle, and range in a local frame. + * Heading is the rotation from the local north direction where a positive angle is increasing eastward. + * Pitch is the rotation from the local xy-plane. Positive pitch angles are above the plane. Negative pitch + * angles are below the plane. Range is the distance from the center of the frame. + * @alias HeadingPitchRange + * @constructor * - * @see PackableForInterpolation + * @param {Number} [heading=0.0] The heading angle in radians. + * @param {Number} [pitch=0.0] The pitch angle in radians. + * @param {Number} [range=0.0] The distance from the center in meters. */ - var Packable = { + function HeadingPitchRange(heading, pitch, range) { /** - * The number of elements used to pack the object into an array. + * Heading is the rotation from the local north direction where a positive angle is increasing eastward. * @type {Number} */ - packedLength : undefined, + this.heading = defaultValue(heading, 0.0); /** - * Stores the provided instance into the provided array. - * @function - * - * @param {Object} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * Pitch is the rotation from the local xy-plane. Positive pitch angles + * are above the plane. Negative pitch angles are below the plane. + * @type {Number} */ - pack : DeveloperError.throwInstantiationError, + this.pitch = defaultValue(pitch, 0.0); /** - * Retrieves an instance from a packed array. - * @function - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Object} [result] The object into which to store the result. - * @returns {Object} The modified result parameter or a new Object instance if one was not provided. + * Range is the distance from the center of the local frame. + * @type {Number} */ - unpack : DeveloperError.throwInstantiationError + this.range = defaultValue(range, 0.0); + } + + /** + * Duplicates a HeadingPitchRange instance. + * + * @param {HeadingPitchRange} hpr The HeadingPitchRange to duplicate. + * @param {HeadingPitchRange} [result] The object onto which to store the result. + * @returns {HeadingPitchRange} The modified result parameter or a new HeadingPitchRange instance if one was not provided. (Returns undefined if hpr is undefined) + */ + HeadingPitchRange.clone = function(hpr, result) { + if (!defined(hpr)) { + return undefined; + } + if (!defined(result)) { + result = new HeadingPitchRange(); + } + + result.heading = hpr.heading; + result.pitch = hpr.pitch; + result.range = hpr.range; + return result; }; - return Packable; + return HeadingPitchRange; }); -define('Core/PackableForInterpolation',[ - './DeveloperError' +define('Core/HeadingPitchRoll',[ + './defaultValue', + './defined', + './DeveloperError', + './Math' ], function( - DeveloperError) { + defaultValue, + defined, + DeveloperError, + CesiumMath) { 'use strict'; /** - * Static interface for {@link Packable} types which are interpolated in a - * different representation than their packed value. These methods and - * properties are expected to be defined on a constructor function. - * - * @exports PackableForInterpolation + * A rotation expressed as a heading, pitch, and roll. Heading is the rotation about the + * negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about + * the positive x axis. + * @alias HeadingPitchRoll + * @constructor * - * @see Packable + * @param {Number} [heading=0.0] The heading component in radians. + * @param {Number} [pitch=0.0] The pitch component in radians. + * @param {Number} [roll=0.0] The roll component in radians. */ - var PackableForInterpolation = { - /** - * The number of elements used to store the object into an array in its interpolatable form. - * @type {Number} - */ - packedInterpolationLength : undefined, + function HeadingPitchRoll(heading, pitch, roll) { + this.heading = defaultValue(heading, 0.0); + this.pitch = defaultValue(pitch, 0.0); + this.roll = defaultValue(roll, 0.0); + } - /** - * Converts a packed array into a form suitable for interpolation. - * @function - * - * @param {Number[]} packedArray The packed array. - * @param {Number} [startingIndex=0] The index of the first element to be converted. - * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. - * @param {Number[]} result The object into which to store the result. - */ - convertPackedArrayForInterpolation : DeveloperError.throwInstantiationError, + /** + * Computes the heading, pitch and roll from a quaternion (see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles ) + * + * @param {Quaternion} quaternion The quaternion from which to retrieve heading, pitch, and roll, all expressed in radians. + * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned. + * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. + */ + HeadingPitchRoll.fromQuaternion = function(quaternion, result) { + if (!defined(quaternion)) { + throw new DeveloperError('quaternion is required'); + } + if (!defined(result)) { + result = new HeadingPitchRoll(); + } + var test = 2 * (quaternion.w * quaternion.y - quaternion.z * quaternion.x); + var denominatorRoll = 1 - 2 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y); + var numeratorRoll = 2 * (quaternion.w * quaternion.x + quaternion.y * quaternion.z); + var denominatorHeading = 1 - 2 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z); + var numeratorHeading = 2 * (quaternion.w * quaternion.z + quaternion.x * quaternion.y); + result.heading = -Math.atan2(numeratorHeading, denominatorHeading); + result.roll = Math.atan2(numeratorRoll, denominatorRoll); + result.pitch = -Math.asin(test); + return result; + }; - /** - * Retrieves an instance from a packed array converted with {@link PackableForInterpolation.convertPackedArrayForInterpolation}. - * @function - * - * @param {Number[]} array The array previously packed for interpolation. - * @param {Number[]} sourceArray The original packed array. - * @param {Number} [startingIndex=0] The startingIndex used to convert the array. - * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. - * @param {Object} [result] The object into which to store the result. - * @returns {Object} The modified result parameter or a new Object instance if one was not provided. - */ - unpackInterpolationResult : DeveloperError.throwInstantiationError + /** + * Returns a new HeadingPitchRoll instance from angles given in degrees. + * + * @param {Number} heading the heading in degrees + * @param {Number} pitch the pitch in degrees + * @param {Number} roll the heading in degrees + * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned. + * @returns {HeadingPitchRoll} A new HeadingPitchRoll instance + */ + HeadingPitchRoll.fromDegrees = function(heading, pitch, roll, result) { + if (!defined(heading)) { + throw new DeveloperError('heading is required'); + } + if (!defined(pitch)) { + throw new DeveloperError('pitch is required'); + } + if (!defined(roll)) { + throw new DeveloperError('roll is required'); + } + if (!defined(result)) { + result = new HeadingPitchRoll(); + } + result.heading = heading * CesiumMath.RADIANS_PER_DEGREE; + result.pitch = pitch * CesiumMath.RADIANS_PER_DEGREE; + result.roll = roll * CesiumMath.RADIANS_PER_DEGREE; + return result; }; - return PackableForInterpolation; -}); + /** + * Duplicates a HeadingPitchRoll instance. + * + * @param {HeadingPitchRoll} headingPitchRoll The HeadingPitchRoll to duplicate. + * @param {HeadingPitchRoll} [result] The object onto which to store the result. + * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. (Returns undefined if headingPitchRoll is undefined) + */ + HeadingPitchRoll.clone = function(headingPitchRoll, result) { + if (!defined(headingPitchRoll)) { + return undefined; + } + if (!defined(result)) { + return new HeadingPitchRoll(headingPitchRoll.heading, headingPitchRoll.pitch, headingPitchRoll.roll); + } + result.heading = headingPitchRoll.heading; + result.pitch = headingPitchRoll.pitch; + result.roll = headingPitchRoll.roll; + return result; + }; -/* - This library rewrites the Canvas2D "measureText" function - so that it returns a more complete metrics object. + /** + * Compares the provided HeadingPitchRolls componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll. + * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + HeadingPitchRoll.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + (left.heading === right.heading) && + (left.pitch === right.pitch) && + (left.roll === right.roll)); + }; -** ----------------------------------------------------------------------------- + /** + * Compares the provided HeadingPitchRolls componentwise and returns + * <code>true</code> if they pass an absolute or relative tolerance test, + * <code>false</code> otherwise. + * + * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll. + * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + */ + HeadingPitchRoll.equalsEpsilon = function(left, right, relativeEpsilon, absoluteEpsilon) { + return (left === right) || + (defined(left) && + defined(right) && + CesiumMath.equalsEpsilon(left.heading, right.heading, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(left.pitch, right.pitch, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(left.roll, right.roll, relativeEpsilon, absoluteEpsilon)); + }; - CHANGELOG: + /** + * Duplicates this HeadingPitchRoll instance. + * + * @param {HeadingPitchRoll} [result] The object onto which to store the result. + * @returns {HeadingPitchRoll} The modified result parameter or a new HeadingPitchRoll instance if one was not provided. + */ + HeadingPitchRoll.prototype.clone = function(result) { + return HeadingPitchRoll.clone(this, result); + }; - 2012-01-21 - Whitespace handling added by Joe Turner - (https://github.com/oampo) + /** + * Compares this HeadingPitchRoll against the provided HeadingPitchRoll componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + HeadingPitchRoll.prototype.equals = function(right) { + return HeadingPitchRoll.equals(this, right); + }; -** ----------------------------------------------------------------------------- -*/ -/** - @license - fontmetrics.js - https://github.com/Pomax/fontmetrics.js + /** + * Compares this HeadingPitchRoll against the provided HeadingPitchRoll componentwise and returns + * <code>true</code> if they pass an absolute or relative tolerance test, + * <code>false</code> otherwise. + * + * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + */ + HeadingPitchRoll.prototype.equalsEpsilon = function(right, relativeEpsilon, absoluteEpsilon) { + return HeadingPitchRoll.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); + }; - Copyright (C) 2011 by Mike "Pomax" Kamermans + /** + * Creates a string representing this HeadingPitchRoll in the format '(heading, pitch, roll)' in radians. + * + * @returns {String} A string representing the provided HeadingPitchRoll in the format '(heading, pitch, roll)'. + */ + HeadingPitchRoll.prototype.toString = function() { + return '(' + this.heading + ', ' + this.pitch + ', ' + this.roll + ')'; + }; - 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: + return HeadingPitchRoll; +}); - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. +define('Core/HermitePolynomialApproximation',[ + './defaultValue', + './defined', + './DeveloperError', + './Math' + ], function( + defaultValue, + defined, + DeveloperError, + CesiumMath) { + 'use strict'; - 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. -**/ -define('ThirdParty/measureText',[],function() { - /*jshint strict:false*/ -/* - var NAME = "FontMetrics Library" - var VERSION = "1-2012.0121.1300"; + var factorial = CesiumMath.factorial; - // if there is no getComputedStyle, this library won't work. - if(!document.defaultView.getComputedStyle) { - throw("ERROR: 'document.defaultView.getComputedStyle' not found. This library only works in browsers that can report computed CSS values."); - } + function calculateCoefficientTerm(x, zIndices, xTable, derivOrder, termOrder, reservedIndices) { + var result = 0; + var reserved; + var i; + var j; - // store the old text metrics function on the Canvas2D prototype - CanvasRenderingContext2D.prototype.measureTextWidth = CanvasRenderingContext2D.prototype.measureText; -*/ - /** - * shortcut function for getting computed CSS values - */ - var getCSSValue = function(element, property) { - return document.defaultView.getComputedStyle(element,null).getPropertyValue(property); - }; -/* - // debug function - var show = function(canvas, ctx, xstart, w, h, metrics) - { - document.body.appendChild(canvas); - ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; + if (derivOrder > 0) { + for (i = 0; i < termOrder; i++) { + reserved = false; + for (j = 0; j < reservedIndices.length && !reserved; j++) { + if (i === reservedIndices[j]) { + reserved = true; + } + } - ctx.beginPath(); - ctx.moveTo(xstart,0); - ctx.lineTo(xstart,h); - ctx.closePath(); - ctx.stroke(); + if (!reserved) { + reservedIndices.push(i); + result += calculateCoefficientTerm(x, zIndices, xTable, derivOrder - 1, termOrder, reservedIndices); + reservedIndices.splice(reservedIndices.length - 1, 1); + } + } - ctx.beginPath(); - ctx.moveTo(xstart+metrics.bounds.maxx,0); - ctx.lineTo(xstart+metrics.bounds.maxx,h); - ctx.closePath(); - ctx.stroke(); + return result; + } - ctx.beginPath(); - ctx.moveTo(0,h/2-metrics.ascent); - ctx.lineTo(w,h/2-metrics.ascent); - ctx.closePath(); - ctx.stroke(); + result = 1; + for (i = 0; i < termOrder; i++) { + reserved = false; + for (j = 0; j < reservedIndices.length && !reserved; j++) { + if (i === reservedIndices[j]) { + reserved = true; + } + } - ctx.beginPath(); - ctx.moveTo(0,h/2+metrics.descent); - ctx.lineTo(w,h/2+metrics.descent); - ctx.closePath(); - ctx.stroke(); - } -*/ - /** - * The new text metrics function - */ - var measureText = function(context2D, textstring, stroke, fill) { - var metrics = context2D.measureText(textstring), - fontFamily = getCSSValue(context2D.canvas,"font-family"), - fontSize = getCSSValue(context2D.canvas,"font-size").replace("px",""), - fontStyle = getCSSValue(context2D.canvas,"font-style"), - fontWeight = getCSSValue(context2D.canvas,"font-weight"), - isSpace = !(/\S/.test(textstring)); - metrics.fontsize = fontSize; + if (!reserved) { + result *= x - xTable[zIndices[i]]; + } + } - // for text lead values, we meaure a multiline text container. - var leadDiv = document.createElement("div"); - leadDiv.style.position = "absolute"; - leadDiv.style.opacity = 0; - leadDiv.style.font = fontStyle + " " + fontWeight + " " + fontSize + "px " + fontFamily; - leadDiv.innerHTML = textstring + "<br/>" + textstring; - document.body.appendChild(leadDiv); + return result; + } - // make some initial guess at the text leading (using the standard TeX ratio) - metrics.leading = 1.2 * fontSize; - - // then we try to get the real value from the browser - var leadDivHeight = getCSSValue(leadDiv,"height"); - leadDivHeight = leadDivHeight.replace("px",""); - if (leadDivHeight >= fontSize * 2) { metrics.leading = (leadDivHeight/2) | 0; } - document.body.removeChild(leadDiv); - - // if we're not dealing with white space, we can compute metrics - if (!isSpace) { - // Have characters, so measure the text - var canvas = document.createElement("canvas"); - var padding = 100; - canvas.width = metrics.width + padding; - canvas.height = 3*fontSize; - canvas.style.opacity = 1; - canvas.style.fontFamily = fontFamily; - canvas.style.fontSize = fontSize; - canvas.style.fontStyle = fontStyle; - canvas.style.fontWeight = fontWeight; - var ctx = canvas.getContext("2d"); - ctx.font = fontStyle + " " + fontWeight + " " + fontSize + "px " + fontFamily; - - var w = canvas.width, - h = canvas.height, - baseline = h/2; + /** + * An {@link InterpolationAlgorithm} for performing Hermite interpolation. + * + * @exports HermitePolynomialApproximation + */ + var HermitePolynomialApproximation = { + type : 'Hermite' + }; - // Set all canvas pixeldata values to 255, with all the content - // data being 0. This lets us scan for data[i] != 255. - ctx.fillStyle = "white"; - ctx.fillRect(-1, -1, w + 2, h + 2); + /** + * Given the desired degree, returns the number of data points required for interpolation. + * + * @param {Number} degree The desired degree of interpolation. + * @param {Number} [inputOrder=0] The order of the inputs (0 means just the data, 1 means the data and its derivative, etc). + * @returns {Number} The number of required data points needed for the desired degree of interpolation. + * @exception {DeveloperError} degree must be 0 or greater. + * @exception {DeveloperError} inputOrder must be 0 or greater. + */ + HermitePolynomialApproximation.getRequiredDataPoints = function(degree, inputOrder) { + inputOrder = defaultValue(inputOrder, 0); - if (stroke) { - ctx.strokeStyle = "black"; - ctx.lineWidth = context2D.lineWidth; - ctx.strokeText(textstring, (padding / 2), baseline); + if (!defined(degree)) { + throw new DeveloperError('degree is required.'); + } + if (degree < 0) { + throw new DeveloperError('degree must be 0 or greater.'); + } + if (inputOrder < 0) { + throw new DeveloperError('inputOrder must be 0 or greater.'); } + + return Math.max(Math.floor((degree + 1) / (inputOrder + 1)), 2); + }; - if (fill) { - ctx.fillStyle = "black"; - ctx.fillText(textstring, padding / 2, baseline); + /** + * Interpolates values using Hermite Polynomial Approximation. + * + * @param {Number} x The independent variable for which the dependent variables will be interpolated. + * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * in this array must be in increasing order and the same value must not occur twice in the array. + * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. + * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * each independent variable value in xTable. + * @param {Number[]} [result] An existing array into which to store the result. + * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + */ + HermitePolynomialApproximation.interpolateOrderZero = function(x, xTable, yTable, yStride, result) { + if (!defined(result)) { + result = new Array(yStride); } - var pixelData = ctx.getImageData(0, 0, w, h).data; + var i; + var j; + var d; + var s; + var len; + var index; + var length = xTable.length; + var coefficients = new Array(yStride); - // canvas pixel data is w*4 by h*4, because R, G, B and A are separate, - // consecutive values in the array, rather than stored as 32 bit ints. - var i = 0, - w4 = w * 4, - len = pixelData.length; + for (i = 0; i < yStride; i++) { + result[i] = 0; - // Finding the ascent uses a normal, forward scanline - while (++i < len && pixelData[i] === 255) {} - var ascent = (i/w4)|0; + var l = new Array(length); + coefficients[i] = l; + for (j = 0; j < length; j++) { + l[j] = []; + } + } - // Finding the descent uses a reverse scanline - i = len - 1; - while (--i > 0 && pixelData[i] === 255) {} - var descent = (i/w4)|0; + var zIndicesLength = length, zIndices = new Array(zIndicesLength); - // find the min-x coordinate - for(i = 0; i<len && pixelData[i] === 255; ) { - i += w4; - if(i>=len) { i = (i-len) + 4; }} - var minx = ((i%w4)/4) | 0; + for (i = 0; i < zIndicesLength; i++) { + zIndices[i] = i; + } - // find the max-x coordinate - var step = 1; - for(i = len-3; i>=0 && pixelData[i] === 255; ) { - i -= w4; - if(i<0) { i = (len - 3) - (step++)*4; }} - var maxx = ((i%w4)/4) + 1 | 0; + var highestNonZeroCoef = length - 1; + for (s = 0; s < yStride; s++) { + for (j = 0; j < zIndicesLength; j++) { + index = zIndices[j] * yStride + s; + coefficients[s][0].push(yTable[index]); + } - // set font metrics - metrics.ascent = (baseline - ascent); - metrics.descent = (descent - baseline); - metrics.bounds = { minx: minx - (padding/2), - maxx: maxx - (padding/2), - miny: 0, - maxy: descent-ascent }; - metrics.height = 1+(descent - ascent); - } + for (i = 1; i < zIndicesLength; i++) { + var nonZeroCoefficients = false; + for (j = 0; j < zIndicesLength - i; j++) { + var zj = xTable[zIndices[j]]; + var zn = xTable[zIndices[j + i]]; - // if we ARE dealing with whitespace, most values will just be zero. - else { - // Only whitespace, so we can't measure the text - metrics.ascent = 0; - metrics.descent = 0; - metrics.bounds = { minx: 0, - maxx: metrics.width, // Best guess - miny: 0, - maxy: 0 }; - metrics.height = 0; - } - return metrics; - }; + var numerator; + if (zn - zj <= 0) { + index = zIndices[j] * yStride + yStride * i + s; + numerator = yTable[index]; + coefficients[s][i].push(numerator / factorial(i)); + } else { + numerator = (coefficients[s][i - 1][j + 1] - coefficients[s][i - 1][j]); + coefficients[s][i].push(numerator / (zn - zj)); + } + nonZeroCoefficients = nonZeroCoefficients || (numerator !== 0); + } - return measureText; -}); + if (!nonZeroCoefficients) { + highestNonZeroCoef = i - 1; + } + } + } -define('Core/writeTextToCanvas',[ - '../ThirdParty/measureText', - './Color', - './defaultValue', - './defined', - './DeveloperError' - ], function( - measureText, - Color, - defaultValue, - defined, - DeveloperError) { - 'use strict'; + for (d = 0, len = 0; d <= len; d++) { + for (i = d; i <= highestNonZeroCoef; i++) { + var tempTerm = calculateCoefficientTerm(x, zIndices, xTable, d, i, []); + for (s = 0; s < yStride; s++) { + var coeff = coefficients[s][i][0]; + result[s + d * yStride] += coeff * tempTerm; + } + } + } - var imageSmoothingEnabledName; + return result; + }; + + var arrayScratch = []; /** - * Writes the given text into a new canvas. The canvas will be sized to fit the text. - * If text is blank, returns undefined. + * Interpolates values using Hermite Polynomial Approximation. * - * @param {String} text The text to write. - * @param {Object} [options] Object with the following properties: - * @param {String} [options.font='10px sans-serif'] The CSS font to use. - * @param {String} [options.textBaseline='bottom'] The baseline of the text. - * @param {Boolean} [options.fill=true] Whether to fill the text. - * @param {Boolean} [options.stroke=false] Whether to stroke the text. - * @param {Color} [options.fillColor=Color.WHITE] The fill color. - * @param {Color} [options.strokeColor=Color.BLACK] The stroke color. - * @param {Number} [options.strokeWidth=1] The stroke width. - * @param {Color} [options.backgroundColor=Color.TRANSPARENT] The background color of the canvas. - * @param {Number} [options.padding=0] The pixel size of the padding to add around the text. - * @returns {Canvas} A new canvas with the given text drawn into it. The dimensions object - * from measureText will also be added to the returned canvas. If text is - * blank, returns undefined. + * @param {Number} x The independent variable for which the dependent variables will be interpolated. + * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * in this array must be in increasing order and the same value must not occur twice in the array. + * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. + * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * each independent variable value in xTable. + * @param {Number} inputOrder The number of derivatives supplied for input. + * @param {Number} outputOrder The number of derivatives desired for output. + * @param {Number[]} [result] An existing array into which to store the result. + * + * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. */ - function writeTextToCanvas(text, options) { - if (!defined(text)) { - throw new DeveloperError('text is required.'); + HermitePolynomialApproximation.interpolate = function(x, xTable, yTable, yStride, inputOrder, outputOrder, result) { + var resultLength = yStride * (outputOrder + 1); + if (!defined(result)) { + result = new Array(resultLength); } - if (text === '') { - return undefined; + for (var r = 0; r < resultLength; r++) { + result[r] = 0; } - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var font = defaultValue(options.font, '10px sans-serif'); - var stroke = defaultValue(options.stroke, false); - var fill = defaultValue(options.fill, true); - var strokeWidth = defaultValue(options.strokeWidth, 1); - var backgroundColor = defaultValue(options.backgroundColor, Color.TRANSPARENT); - var padding = defaultValue(options.padding, 0); - var doublePadding = padding * 2.0; + var length = xTable.length; + // The zIndices array holds copies of the addresses of the xTable values + // in the range we're looking at. Even though this just holds information already + // available in xTable this is a much more convenient format. + var zIndices = new Array(length * (inputOrder + 1)); + var i; + for (i = 0; i < length; i++) { + for (var j = 0; j < (inputOrder + 1); j++) { + zIndices[i * (inputOrder + 1) + j] = i; + } + } - var canvas = document.createElement('canvas'); - canvas.width = 1; - canvas.height = 1; - canvas.style.font = font; + var zIndiceslength = zIndices.length; + var coefficients = arrayScratch; + var highestNonZeroCoef = fillCoefficientList(coefficients, zIndices, xTable, yTable, yStride, inputOrder); + var reservedIndices = []; - var context2D = canvas.getContext('2d'); + var tmp = zIndiceslength * (zIndiceslength + 1) / 2; + var loopStop = Math.min(highestNonZeroCoef, outputOrder); + for (var d = 0; d <= loopStop; d++) { + for (i = d; i <= highestNonZeroCoef; i++) { + reservedIndices.length = 0; + var tempTerm = calculateCoefficientTerm(x, zIndices, xTable, d, i, reservedIndices); + var dimTwo = Math.floor(i * (1 - i) / 2) + (zIndiceslength * i); - if (!defined(imageSmoothingEnabledName)) { - if (defined(context2D.imageSmoothingEnabled)) { - imageSmoothingEnabledName = 'imageSmoothingEnabled'; - } else if (defined(context2D.mozImageSmoothingEnabled)) { - imageSmoothingEnabledName = 'mozImageSmoothingEnabled'; - } else if (defined(context2D.webkitImageSmoothingEnabled)) { - imageSmoothingEnabledName = 'webkitImageSmoothingEnabled'; - } else if (defined(context2D.msImageSmoothingEnabled)) { - imageSmoothingEnabledName = 'msImageSmoothingEnabled'; + for (var s = 0; s < yStride; s++) { + var dimOne = Math.floor(s * tmp); + var coef = coefficients[dimOne + dimTwo]; + result[s + d * yStride] += coef * tempTerm; + } } } - context2D.font = font; - context2D.lineJoin = 'round'; - context2D.lineWidth = strokeWidth; - context2D[imageSmoothingEnabledName] = false; + return result; + }; - // textBaseline needs to be set before the measureText call. It won't work otherwise. - // It's magic. - context2D.textBaseline = defaultValue(options.textBaseline, 'bottom'); + function fillCoefficientList(coefficients, zIndices, xTable, yTable, yStride, inputOrder) { + var j; + var index; + var highestNonZero = -1; + var zIndiceslength = zIndices.length; + var tmp = zIndiceslength * (zIndiceslength + 1) / 2; - // in order for measureText to calculate style, the canvas has to be - // (temporarily) added to the DOM. - canvas.style.visibility = 'hidden'; - document.body.appendChild(canvas); + for (var s = 0; s < yStride; s++) { + var dimOne = Math.floor(s * tmp); - var dimensions = measureText(context2D, text, stroke, fill); - canvas.dimensions = dimensions; + for (j = 0; j < zIndiceslength; j++) { + index = zIndices[j] * yStride * (inputOrder + 1) + s; + coefficients[dimOne + j] = yTable[index]; + } - document.body.removeChild(canvas); - canvas.style.visibility = ''; + for (var i = 1; i < zIndiceslength; i++) { + var coefIndex = 0; + var dimTwo = Math.floor(i * (1 - i) / 2) + (zIndiceslength * i); + var nonZeroCoefficients = false; - //Some characters, such as the letter j, have a non-zero starting position. - //This value is used for kerning later, but we need to take it into account - //now in order to draw the text completely on the canvas - var x = -dimensions.bounds.minx; + for (j = 0; j < zIndiceslength - i; j++) { + var zj = xTable[zIndices[j]]; + var zn = xTable[zIndices[j + i]]; - //Expand the width to include the starting position. - var width = Math.ceil(dimensions.width) + x + doublePadding; + var numerator; + var coefficient; + if (zn - zj <= 0) { + index = zIndices[j] * yStride * (inputOrder + 1) + yStride * i + s; + numerator = yTable[index]; + coefficient = (numerator / CesiumMath.factorial(i)); + coefficients[dimOne + dimTwo + coefIndex] = coefficient; + coefIndex++; + } else { + var dimTwoMinusOne = Math.floor((i - 1) * (2 - i) / 2) + (zIndiceslength * (i - 1)); + numerator = coefficients[dimOne + dimTwoMinusOne + j + 1] - coefficients[dimOne + dimTwoMinusOne + j]; + coefficient = (numerator / (zn - zj)); + coefficients[dimOne + dimTwo + coefIndex] = coefficient; + coefIndex++; + } + nonZeroCoefficients = nonZeroCoefficients || (numerator !== 0.0); + } - //While the height of the letter is correct, we need to adjust - //where we start drawing it so that letters like j and y properly dip - //below the line. - var height = dimensions.height + doublePadding; - var baseline = height - dimensions.ascent + doublePadding; - var y = height - baseline + doublePadding; + if (nonZeroCoefficients) { + highestNonZero = Math.max(highestNonZero, i); + } + } + } - canvas.width = width; - canvas.height = height; + return highestNonZero; + } - // Properties must be explicitly set again after changing width and height - context2D.font = font; - context2D.lineJoin = 'round'; - context2D.lineWidth = strokeWidth; - context2D[imageSmoothingEnabledName] = false; + return HermitePolynomialApproximation; +}); - // Draw background - if (backgroundColor !== Color.TRANSPARENT) { - context2D.fillStyle = backgroundColor.toCssColorString(); - context2D.fillRect(0, 0, canvas.width, canvas.height); - } +define('Core/IauOrientationParameters',[],function() { + 'use strict'; - if (stroke) { - var strokeColor = defaultValue(options.strokeColor, Color.BLACK); - context2D.strokeStyle = strokeColor.toCssColorString(); - context2D.strokeText(text, x + padding, y); - } + /** + * A structure containing the orientation data computed at a particular time. The data + * represents the direction of the pole of rotation and the rotation about that pole. + * <p> + * These parameters correspond to the parameters in the Report from the IAU/IAG Working Group + * except that they are expressed in radians. + * </p> + * + * @exports IauOrientationParameters + * + * @private + */ + function IauOrientationParameters(rightAscension, declination, rotation, rotationRate) { + /** + * The right ascension of the north pole of the body with respect to + * the International Celestial Reference Frame, in radians. + * @type {Number} + * + * @private + */ + this.rightAscension = rightAscension; - if (fill) { - var fillColor = defaultValue(options.fillColor, Color.WHITE); - context2D.fillStyle = fillColor.toCssColorString(); - context2D.fillText(text, x + padding, y); - } + /** + * The declination of the north pole of the body with respect to + * the International Celestial Reference Frame, in radians. + * @type {Number} + * + * @private + */ + this.declination = declination; - return canvas; + /** + * The rotation about the north pole used to align a set of axes with + * the meridian defined by the IAU report, in radians. + * @type {Number} + * + * @private + */ + this.rotation = rotation; + + /** + * The instantaneous rotation rate about the north pole, in radians per second. + * @type {Number} + * + * @private + */ + this.rotationRate = rotationRate; } - return writeTextToCanvas; + return IauOrientationParameters; }); -define('Core/PinBuilder',[ - './buildModuleUrl', - './Color', +define('Core/Iau2000Orientation',[ './defined', - './DeveloperError', - './loadImage', - './writeTextToCanvas' + './IauOrientationParameters', + './JulianDate', + './Math', + './TimeConstants' ], function( - buildModuleUrl, - Color, defined, - DeveloperError, - loadImage, - writeTextToCanvas) { + IauOrientationParameters, + JulianDate, + CesiumMath, + TimeConstants) { 'use strict'; /** - * A utility class for generating custom map pins as canvas elements. - * <br /><br /> - * <div align='center'> - * <img src='Images/PinBuilder.png' width='500'/><br /> - * Example pins generated using both the maki icon set, which ships with Cesium, and single character text. - * </div> - * - * @alias PinBuilder - * @constructor + * This is a collection of the orientation information available for central bodies. + * The data comes from the Report of the IAU/IAG Working Group on Cartographic + * Coordinates and Rotational Elements: 2000. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Map%20Pins.html|Cesium Sandcastle PinBuilder Demo} - */ - function PinBuilder() { - this._cache = {}; - } - - /** - * Creates an empty pin of the specified color and size. + * @exports Iau2000Orientation * - * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. - * @returns {Canvas} The canvas element that represents the generated pin. + * @private */ - PinBuilder.prototype.fromColor = function(color, size) { - if (!defined(color)) { - throw new DeveloperError('color is required'); - } - if (!defined(size)) { - throw new DeveloperError('size is required'); - } - return createPin(undefined, undefined, color, size, this._cache); - }; + var Iau2000Orientation = {}; - /** - * Creates a pin with the specified icon, color, and size. - * - * @param {String} url The url of the image to be stamped onto the pin. - * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. - * @returns {Canvas|Promise.<Canvas>} The canvas element or a Promise to the canvas element that represents the generated pin. - */ - PinBuilder.prototype.fromUrl = function(url, color, size) { - if (!defined(url)) { - throw new DeveloperError('url is required'); - } - if (!defined(color)) { - throw new DeveloperError('color is required'); - } - if (!defined(size)) { - throw new DeveloperError('size is required'); - } - return createPin(url, undefined, color, size, this._cache); - }; + var TdtMinusTai = 32.184; + var J2000d = 2451545.0; - /** - * Creates a pin with the specified {@link https://www.mapbox.com/maki/|maki} icon identifier, color, and size. - * - * @param {String} id The id of the maki icon to be stamped onto the pin. - * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. - * @returns {Canvas|Promise.<Canvas>} The canvas element or a Promise to the canvas element that represents the generated pin. - */ - PinBuilder.prototype.fromMakiIconId = function(id, color, size) { - if (!defined(id)) { - throw new DeveloperError('id is required'); - } - if (!defined(color)) { - throw new DeveloperError('color is required'); - } - if (!defined(size)) { - throw new DeveloperError('size is required'); - } - return createPin(buildModuleUrl('Assets/Textures/maki/' + encodeURIComponent(id) + '.png'), undefined, color, size, this._cache); - }; + var c1 = -0.0529921; + var c2 = -0.1059842; + var c3 = 13.0120009; + var c4 = 13.3407154; + var c5 = 0.9856003; + var c6 = 26.4057084; + var c7 = 13.0649930; + var c8 = 0.3287146; + var c9 = 1.7484877; + var c10 = -0.1589763; + var c11 = 0.0036096; + var c12 = 0.1643573; + var c13 = 12.9590088; + var dateTT = new JulianDate(); /** - * Creates a pin with the specified text, color, and size. The text will be sized to be as large as possible - * while still being contained completely within the pin. + * Compute the orientation parameters for the Moon. * - * @param {String} text The text to be stamped onto the pin. - * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. - * @returns {Canvas} The canvas element that represents the generated pin. + * @param {JulianDate} [date=JulianDate.now()] The date to evaluate the parameters. + * @param {IauOrientationParameters} [result] The object onto which to store the result. + * @returns {IauOrientationParameters} The modified result parameter or a new instance representing the orientation of the Earth's Moon. */ - PinBuilder.prototype.fromText = function(text, color, size) { - if (!defined(text)) { - throw new DeveloperError('text is required'); - } - if (!defined(color)) { - throw new DeveloperError('color is required'); - } - if (!defined(size)) { - throw new DeveloperError('size is required'); - } - - return createPin(undefined, text, color, size, this._cache); - }; - - var colorScratch = new Color(); - - //This function (except for the 3 commented lines) was auto-generated from an online tool, - //http://www.professorcloud.com/svg-to-canvas/, using Assets/Textures/pin.svg as input. - //The reason we simply can't load and draw the SVG directly to the canvas is because - //it taints the canvas in Internet Explorer (and possibly some other browsers); making - //it impossible to create a WebGL texture from the result. - function drawPin(context2D, color, size) { - context2D.save(); - context2D.scale(size / 24, size / 24); //Added to auto-generated code to scale up to desired size. - context2D.fillStyle = color.toCssColorString(); //Modified from auto-generated code. - context2D.strokeStyle = color.brighten(0.6, colorScratch).toCssColorString(); //Modified from auto-generated code. - context2D.lineWidth = 0.846; - context2D.beginPath(); - context2D.moveTo(6.72, 0.422); - context2D.lineTo(17.28, 0.422); - context2D.bezierCurveTo(18.553, 0.422, 19.577, 1.758, 19.577, 3.415); - context2D.lineTo(19.577, 10.973); - context2D.bezierCurveTo(19.577, 12.63, 18.553, 13.966, 17.282, 13.966); - context2D.lineTo(14.386, 14.008); - context2D.lineTo(11.826, 23.578); - context2D.lineTo(9.614, 14.008); - context2D.lineTo(6.719, 13.965); - context2D.bezierCurveTo(5.446, 13.983, 4.422, 12.629, 4.422, 10.972); - context2D.lineTo(4.422, 3.416); - context2D.bezierCurveTo(4.423, 1.76, 5.447, 0.423, 6.718, 0.423); - context2D.closePath(); - context2D.fill(); - context2D.stroke(); - context2D.restore(); - } - - //This function takes an image or canvas and uses it as a template - //to "stamp" the pin with a white image outlined in black. The color - //values of the input image are ignored completely and only the alpha - //values are used. - function drawIcon(context2D, image, size) { - //Size is the largest image that looks good inside of pin box. - var imageSize = size / 2.5; - var sizeX = imageSize; - var sizeY = imageSize; - - if (image.width > image.height) { - sizeY = imageSize * (image.height / image.width); - } else if (image.width < image.height) { - sizeX = imageSize * (image.width / image.height); + Iau2000Orientation.ComputeMoon = function(date, result) { + if (!defined(date)) { + date = JulianDate.now(); } - //x and y are the center of the pin box - var x = Math.round((size - sizeX) / 2); - var y = Math.round(((7 / 24) * size) - (sizeY / 2)); + dateTT = JulianDate.addSeconds(date, TdtMinusTai, dateTT); + var d = JulianDate.totalDays(dateTT) - J2000d; + var T = d / TimeConstants.DAYS_PER_JULIAN_CENTURY; - context2D.globalCompositeOperation = 'destination-out'; - context2D.drawImage(image, x - 1, y, sizeX, sizeY); - context2D.drawImage(image, x, y - 1, sizeX, sizeY); - context2D.drawImage(image, x + 1, y, sizeX, sizeY); - context2D.drawImage(image, x, y + 1, sizeX, sizeY); + var E1 = (125.045 + c1 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E2 = (250.089 + c2 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E3 = (260.008 + c3 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E4 = (176.625 + c4 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E5 = (357.529 + c5 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E6 = (311.589 + c6 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E7 = (134.963 + c7 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E8 = (276.617 + c8 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E9 = (34.226 + c9 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E10 = (15.134 + c10 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E11 = (119.743 + c11 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E12 = (239.961 + c12 * d) * CesiumMath.RADIANS_PER_DEGREE; + var E13 = (25.053 + c13 * d) * CesiumMath.RADIANS_PER_DEGREE; - context2D.globalCompositeOperation = 'destination-over'; - context2D.fillStyle = Color.BLACK.toCssColorString(); - context2D.fillRect(x - 1, y - 1, sizeX + 2, sizeY + 2); + var sinE1 = Math.sin(E1); + var sinE2 = Math.sin(E2); + var sinE3 = Math.sin(E3); + var sinE4 = Math.sin(E4); + var sinE5 = Math.sin(E5); + var sinE6 = Math.sin(E6); + var sinE7 = Math.sin(E7); + var sinE8 = Math.sin(E8); + var sinE9 = Math.sin(E9); + var sinE10 = Math.sin(E10); + var sinE11 = Math.sin(E11); + var sinE12 = Math.sin(E12); + var sinE13 = Math.sin(E13); - context2D.globalCompositeOperation = 'destination-out'; - context2D.drawImage(image, x, y, sizeX, sizeY); + var cosE1 = Math.cos(E1); + var cosE2 = Math.cos(E2); + var cosE3 = Math.cos(E3); + var cosE4 = Math.cos(E4); + var cosE5 = Math.cos(E5); + var cosE6 = Math.cos(E6); + var cosE7 = Math.cos(E7); + var cosE8 = Math.cos(E8); + var cosE9 = Math.cos(E9); + var cosE10 = Math.cos(E10); + var cosE11 = Math.cos(E11); + var cosE12 = Math.cos(E12); + var cosE13 = Math.cos(E13); - context2D.globalCompositeOperation = 'destination-over'; - context2D.fillStyle = Color.WHITE.toCssColorString(); - context2D.fillRect(x - 1, y - 2, sizeX + 2, sizeY + 2); - } + var rightAscension = (269.9949 + 0.0031 * T - 3.8787 * sinE1 - 0.1204 * sinE2 + + 0.0700 * sinE3 - 0.0172 * sinE4 + 0.0072 * sinE6 - + 0.0052 * sinE10 + 0.0043 * sinE13) * + CesiumMath.RADIANS_PER_DEGREE; + var declination = (66.5392 + 0.013 * T + 1.5419 * cosE1 + 0.0239 * cosE2 - + 0.0278 * cosE3 + 0.0068 * cosE4 - 0.0029 * cosE6 + + 0.0009 * cosE7 + 0.0008 * cosE10 - 0.0009 * cosE13) * + CesiumMath.RADIANS_PER_DEGREE; + var rotation = (38.3213 + 13.17635815 * d - 1.4e-12 * d * d + 3.5610 * sinE1 + + 0.1208 * sinE2 - 0.0642 * sinE3 + 0.0158 * sinE4 + + 0.0252 * sinE5 - 0.0066 * sinE6 - 0.0047 * sinE7 - + 0.0046 * sinE8 + 0.0028 * sinE9 + 0.0052 * sinE10 + + 0.004 * sinE11 + 0.0019 * sinE12 - 0.0044 * sinE13) * + CesiumMath.RADIANS_PER_DEGREE; - var stringifyScratch = new Array(4); - function createPin(url, label, color, size, cache) { - //Use the parameters as a unique ID for caching. - stringifyScratch[0] = url; - stringifyScratch[1] = label; - stringifyScratch[2] = color; - stringifyScratch[3] = size; - var id = JSON.stringify(stringifyScratch); + var rotationRate = ((13.17635815 - 1.4e-12 * (2.0 * d)) + + 3.5610 * cosE1 * c1 + + 0.1208 * cosE2*c2 - 0.0642 * cosE3*c3 + 0.0158 * cosE4*c4 + + 0.0252 * cosE5*c5 - 0.0066 * cosE6*c6 - 0.0047 * cosE7*c7 - + 0.0046 * cosE8*c8 + 0.0028 * cosE9*c9 + 0.0052 * cosE10*c10 + + 0.004 * cosE11*c11 + 0.0019 * cosE12*c12 - 0.0044 * cosE13*c13) / + 86400.0 * CesiumMath.RADIANS_PER_DEGREE; - var item = cache[id]; - if (defined(item)) { - return item; + if (!defined(result)) { + result = new IauOrientationParameters(); } - var canvas = document.createElement('canvas'); - canvas.width = size; - canvas.height = size; - - var context2D = canvas.getContext('2d'); - drawPin(context2D, color, size); - - if (defined(url)) { - //If we have an image url, load it and then stamp the pin. - var promise = loadImage(url).then(function(image) { - drawIcon(context2D, image, size); - cache[id] = canvas; - return canvas; - }); - cache[id] = promise; - return promise; - } else if (defined(label)) { - //If we have a label, write it to a canvas and then stamp the pin. - var image = writeTextToCanvas(label, { - font : 'bold ' + size + 'px sans-serif' - }); - drawIcon(context2D, image, size); - } + result.rightAscension = rightAscension; + result.declination = declination; + result.rotation = rotation; + result.rotationRate = rotationRate; - cache[id] = canvas; - return canvas; - } + return result; + }; - return PinBuilder; + return Iau2000Orientation; }); -define('Core/PlaneGeometry',[ - './BoundingSphere', +define('Core/IauOrientationAxes',[ './Cartesian3', - './Check', - './ComponentDatatype', - './defaultValue', './defined', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './PrimitiveType', - './VertexFormat' + './Iau2000Orientation', + './JulianDate', + './Math', + './Matrix3', + './Quaternion' ], function( - BoundingSphere, Cartesian3, - Check, - ComponentDatatype, - defaultValue, defined, - Geometry, - GeometryAttribute, - GeometryAttributes, - PrimitiveType, - VertexFormat) { + Iau2000Orientation, + JulianDate, + CesiumMath, + Matrix3, + Quaternion) { 'use strict'; /** - * Describes geometry representing a plane centered at the origin, with a unit width and length. - * - * @alias PlaneGeometry + * The Axes representing the orientation of a Globe as represented by the data + * from the IAU/IAG Working Group reports on rotational elements. + * @alias IauOrientationAxes * @constructor * - * @param {Object} options Object with the following properties: - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {IauOrientationAxes~ComputeFunction} [computeFunction] The function that computes the {@link IauOrientationParameters} given a {@link JulianDate}. * - * @example - * var planeGeometry = new Cesium.PlaneGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY - * }); + * @see Iau2000Orientation + * + * @private */ - function PlaneGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + function IauOrientationAxes(computeFunction) { + if (!defined(computeFunction) || typeof computeFunction !== 'function') { + computeFunction = Iau2000Orientation.ComputeMoon; + } - this._vertexFormat = vertexFormat; - this._workerName = 'createPlaneGeometry'; + this._computeFunction = computeFunction; } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - PlaneGeometry.packedLength = VertexFormat.packedLength; - - /** - * Stores the provided instance into the provided array. - * - * @param {PlaneGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - PlaneGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); - - VertexFormat.pack(value._vertexFormat, array, startingIndex); + var xAxisScratch = new Cartesian3(); + var yAxisScratch = new Cartesian3(); + var zAxisScratch = new Cartesian3(); - return array; - }; + function computeRotationMatrix(alpha, delta, result) { + var xAxis = xAxisScratch; + xAxis.x = Math.cos(alpha + CesiumMath.PI_OVER_TWO); + xAxis.y = Math.sin(alpha + CesiumMath.PI_OVER_TWO); + xAxis.z = 0.0; - var scratchVertexFormat = new VertexFormat(); - var scratchOptions = { - vertexFormat: scratchVertexFormat - }; + var cosDec = Math.cos(delta); - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PlaneGeometry} [result] The object into which to store the result. - * @returns {PlaneGeometry} The modified result parameter or a new PlaneGeometry instance if one was not provided. - */ - PlaneGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); - - startingIndex = defaultValue(startingIndex, 0); + var zAxis = zAxisScratch; + zAxis.x = cosDec * Math.cos(alpha); + zAxis.y = cosDec * Math.sin(alpha); + zAxis.z = Math.sin(delta); - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + var yAxis = Cartesian3.cross(zAxis, xAxis, yAxisScratch); if (!defined(result)) { - return new PlaneGeometry(scratchOptions); + result = new Matrix3(); } - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result[0] = xAxis.x; + result[1] = yAxis.x; + result[2] = zAxis.x; + result[3] = xAxis.y; + result[4] = yAxis.y; + result[5] = zAxis.y; + result[6] = xAxis.z; + result[7] = yAxis.z; + result[8] = zAxis.z; return result; - }; + } - var min = new Cartesian3(-0.5, -0.5, 0.0); - var max = new Cartesian3( 0.5, 0.5, 0.0); + var rotMtxScratch = new Matrix3(); + var quatScratch = new Quaternion(); /** - * Computes the geometric representation of a plane, including its vertices, indices, and a bounding sphere. + * Computes a rotation from ICRF to a Globe's Fixed axes. * - * @param {PlaneGeometry} planeGeometry A description of the plane. - * @returns {Geometry|undefined} The computed vertices and indices. + * @param {JulianDate} date The date to evaluate the matrix. + * @param {Matrix3} result The object onto which to store the result. + * @returns {Matrix} The modified result parameter or a new instance of the rotation from ICRF to Fixed. */ - PlaneGeometry.createGeometry = function(planeGeometry) { - var vertexFormat = planeGeometry._vertexFormat; - - var attributes = new GeometryAttributes(); - var indices; - var positions; + IauOrientationAxes.prototype.evaluate = function(date, result) { + if (!defined(date)) { + date = JulianDate.now(); + } - if (vertexFormat.position) { - // 4 corner points. Duplicated 3 times each for each incident edge/face. - positions = new Float64Array(4 * 3); + var alphaDeltaW = this._computeFunction(date); + var precMtx = computeRotationMatrix(alphaDeltaW.rightAscension, alphaDeltaW.declination, result); - // +z face - positions[0] = min.x; - positions[1] = min.y; - positions[2] = 0.0; - positions[3] = max.x; - positions[4] = min.y; - positions[5] = 0.0; - positions[6] = max.x; - positions[7] = max.y; - positions[8] = 0.0; - positions[9] = min.x; - positions[10] = max.y; - positions[11] = 0.0; + var rot = CesiumMath.zeroToTwoPi(alphaDeltaW.rotation); + var quat = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, rot, quatScratch); + var rotMtx = Matrix3.fromQuaternion(Quaternion.conjugate(quat, quat), rotMtxScratch); - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); + var cbi2cbf = Matrix3.multiply(rotMtx, precMtx, precMtx); + return cbi2cbf; + }; - if (vertexFormat.normal) { - var normals = new Float32Array(4 * 3); + /** + * A function that computes the {@link IauOrientationParameters} for a {@link JulianDate}. + * @callback IauOrientationAxes~ComputeFunction + * @param {JulianDate} date The date to evaluate the parameters. + * @returns {IauOrientationParameters} The orientation parameters. + */ - // +z face - normals[0] = 0.0; - normals[1] = 0.0; - normals[2] = 1.0; - normals[3] = 0.0; - normals[4] = 0.0; - normals[5] = 1.0; - normals[6] = 0.0; - normals[7] = 0.0; - normals[8] = 1.0; - normals[9] = 0.0; - normals[10] = 0.0; - normals[11] = 1.0; + return IauOrientationAxes; +}); - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } +define('Core/InterpolationAlgorithm',[ + './DeveloperError' + ], function( + DeveloperError) { + 'use strict'; - if (vertexFormat.st) { - var texCoords = new Float32Array(4 * 2); + /** + * The interface for interpolation algorithms. + * + * @exports InterpolationAlgorithm + * + * @see LagrangePolynomialApproximation + * @see LinearApproximation + * @see HermitePolynomialApproximation + */ + var InterpolationAlgorithm = {}; - // +z face - texCoords[0] = 0.0; - texCoords[1] = 0.0; - texCoords[2] = 1.0; - texCoords[3] = 0.0; - texCoords[4] = 1.0; - texCoords[5] = 1.0; - texCoords[6] = 0.0; - texCoords[7] = 1.0; + /** + * Gets the name of this interpolation algorithm. + * @type {String} + */ + InterpolationAlgorithm.type = undefined; - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : texCoords - }); - } + /** + * Given the desired degree, returns the number of data points required for interpolation. + * @function + * + * @param {Number} degree The desired degree of interpolation. + * @returns {Number} The number of required data points needed for the desired degree of interpolation. + */ + InterpolationAlgorithm.getRequiredDataPoints = DeveloperError.throwInstantiationError; - if (vertexFormat.tangent) { - var tangents = new Float32Array(4 * 3); + /** + * Performs zero order interpolation. + * @function + * + * @param {Number} x The independent variable for which the dependent variables will be interpolated. + * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * in this array must be in increasing order and the same value must not occur twice in the array. + * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. + * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * each independent variable value in xTable. + * @param {Number[]} [result] An existing array into which to store the result. + * + * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + */ + InterpolationAlgorithm.interpolateOrderZero = DeveloperError.throwInstantiationError; - // +z face - tangents[0] = 1.0; - tangents[1] = 0.0; - tangents[2] = 0.0; - tangents[3] = 1.0; - tangents[4] = 0.0; - tangents[5] = 0.0; - tangents[6] = 1.0; - tangents[7] = 0.0; - tangents[8] = 0.0; - tangents[9] = 1.0; - tangents[10] = 0.0; - tangents[11] = 0.0; - - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); - } - - if (vertexFormat.bitangent) { - var bitangents = new Float32Array(4 * 3); - - // +z face - bitangents[0] = 0.0; - bitangents[1] = 1.0; - bitangents[2] = 0.0; - bitangents[3] = 0.0; - bitangents[4] = 1.0; - bitangents[5] = 0.0; - bitangents[6] = 0.0; - bitangents[7] = 1.0; - bitangents[8] = 0.0; - bitangents[9] = 0.0; - bitangents[10] = 1.0; - bitangents[11] = 0.0; - - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } - - // 2 triangles - indices = new Uint16Array(2 * 3); - - // +z face - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 0; - indices[4] = 2; - indices[5] = 3; - } - - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : new BoundingSphere(Cartesian3.ZERO, Math.sqrt(2.0)) - }); - }; + /** + * Performs higher order interpolation. Not all interpolators need to support high-order interpolation, + * if this function remains undefined on implementing objects, interpolateOrderZero will be used instead. + * @function + * @param {Number} x The independent variable for which the dependent variables will be interpolated. + * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * in this array must be in increasing order and the same value must not occur twice in the array. + * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. + * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * each independent variable value in xTable. + * @param {Number} inputOrder The number of derivatives supplied for input. + * @param {Number} outputOrder The number of derivatives desired for output. + * @param {Number[]} [result] An existing array into which to store the result. + * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + */ + InterpolationAlgorithm.interpolate = DeveloperError.throwInstantiationError; - return PlaneGeometry; + return InterpolationAlgorithm; }); -define('Core/PlaneOutlineGeometry',[ - './BoundingSphere', - './Cartesian3', +define('Core/TimeInterval',[ './Check', - './ComponentDatatype', './defaultValue', './defined', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './PrimitiveType' + './defineProperties', + './freezeObject', + './JulianDate' ], function( - BoundingSphere, - Cartesian3, Check, - ComponentDatatype, defaultValue, defined, - Geometry, - GeometryAttribute, - GeometryAttributes, - PrimitiveType) { + defineProperties, + freezeObject, + JulianDate) { 'use strict'; /** - * Describes geometry representing the outline of a plane centered at the origin, with a unit width and length. + * An interval defined by a start and a stop time; optionally including those times as part of the interval. + * Arbitrary data can optionally be associated with each instance for used with {@link TimeIntervalCollection}. * - * @alias PlaneOutlineGeometry + * @alias TimeInterval * @constructor * + * @param {Object} [options] Object with the following properties: + * @param {JulianDate} [options.start=new JulianDate()] The start time of the interval. + * @param {JulianDate} [options.stop=new JulianDate()] The stop time of the interval. + * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. + * @param {Object} [options.data] Arbitrary data associated with this interval. + * + * @example + * // Create an instance that spans August 1st, 1980 and is associated + * // with a Cartesian position. + * var timeInterval = new Cesium.TimeInterval({ + * start : Cesium.JulianDate.fromIso8601('1980-08-01T00:00:00Z'), + * stop : Cesium.JulianDate.fromIso8601('1980-08-02T00:00:00Z'), + * isStartIncluded : true, + * isStopIncluded : false, + * data : Cesium.Cartesian3.fromDegrees(39.921037, -75.170082) + * }); + * + * @example + * // Create two instances from ISO 8601 intervals with associated numeric data + * // then compute their intersection, summing the data they contain. + * var left = Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2000/2010', + * data : 2 + * }); + * + * var right = Cesium.TimeInterval.fromIso8601({ + * iso8601 : '1995/2005', + * data : 3 + * }); + * + * //The result of the below intersection will be an interval equivalent to + * //var intersection = Cesium.TimeInterval.fromIso8601({ + * // iso8601 : '2000/2005', + * // data : 5 + * //}); + * var intersection = new Cesium.TimeInterval(); + * Cesium.TimeInterval.intersect(left, right, intersection, function(leftData, rightData) { + * return leftData + rightData; + * }); + * + * @example + * // Check if an interval contains a specific time. + * var dateToCheck = Cesium.JulianDate.fromIso8601('1982-09-08T11:30:00Z'); + * var containsDate = Cesium.TimeInterval.contains(timeInterval, dateToCheck); */ - function PlaneOutlineGeometry() { - this._workerName = 'createPlaneOutlineGeometry'; + function TimeInterval(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + /** + * Gets or sets the start time of this interval. + * @type {JulianDate} + */ + this.start = defined(options.start) ? JulianDate.clone(options.start) : new JulianDate(); + + /** + * Gets or sets the stop time of this interval. + * @type {JulianDate} + */ + this.stop = defined(options.stop) ? JulianDate.clone(options.stop) : new JulianDate(); + + /** + * Gets or sets the data associated with this interval. + * @type {Object} + */ + this.data = options.data; + + /** + * Gets or sets whether or not the start time is included in this interval. + * @type {Boolean} + * @default true + */ + this.isStartIncluded = defaultValue(options.isStartIncluded, true); + + /** + * Gets or sets whether or not the stop time is included in this interval. + * @type {Boolean} + * @default true + */ + this.isStopIncluded = defaultValue(options.isStopIncluded, true); } + defineProperties(TimeInterval.prototype, { + /** + * Gets whether or not this interval is empty. + * @memberof TimeInterval.prototype + * @type {Boolean} + * @readonly + */ + isEmpty : { + get : function() { + var stopComparedToStart = JulianDate.compare(this.stop, this.start); + return stopComparedToStart < 0 || (stopComparedToStart === 0 && (!this.isStartIncluded || !this.isStopIncluded)); + } + } + }); + + var scratchInterval = { + start : undefined, + stop : undefined, + isStartIncluded : undefined, + isStopIncluded : undefined, + data : undefined + }; + /** - * The number of elements used to pack the object into an array. - * @type {Number} + * Creates a new instance from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} interval. + * + * @param {Object} options Object with the following properties: + * @param {String} options.iso8601 An ISO 8601 interval. + * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. + * @param {Object} [options.data] Arbitrary data associated with this interval. + * @param {TimeInterval} [result] An existing instance to use for the result. + * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. */ - PlaneOutlineGeometry.packedLength = 0; + TimeInterval.fromIso8601 = function(options, result) { + Check.typeOf.object('options', options); + Check.typeOf.string('options.iso8601', options.iso8601); + + var dates = options.iso8601.split('/'); + var start = JulianDate.fromIso8601(dates[0]); + var stop = JulianDate.fromIso8601(dates[1]); + var isStartIncluded = defaultValue(options.isStartIncluded, true); + var isStopIncluded = defaultValue(options.isStopIncluded, true); + var data = options.data; + + if (!defined(result)) { + scratchInterval.start = start; + scratchInterval.stop = stop; + scratchInterval.isStartIncluded = isStartIncluded; + scratchInterval.isStopIncluded = isStopIncluded; + scratchInterval.data = data; + return new TimeInterval(scratchInterval); + } + + result.start = start; + result.stop = stop; + result.isStartIncluded = isStartIncluded; + result.isStopIncluded = isStopIncluded; + result.data = data; + return result; + }; /** - * Stores the provided instance into the provided array. + * Creates an ISO8601 representation of the provided interval. * - * @param {PlaneOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. + * @param {TimeInterval} timeInterval The interval to be converted. + * @param {Number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. + * @returns {String} The ISO8601 representation of the provided interval. + */ + TimeInterval.toIso8601 = function(timeInterval, precision) { + Check.typeOf.object('timeInterval', timeInterval); + + return JulianDate.toIso8601(timeInterval.start, precision) + '/' + JulianDate.toIso8601(timeInterval.stop, precision); + }; + + /** + * Duplicates the provided instance. * - * @returns {Number[]} The array that was packed into + * @param {TimeInterval} [timeInterval] The instance to clone. + * @param {TimeInterval} [result] An existing instance to use for the result. + * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. */ - PlaneOutlineGeometry.pack = function(value, array) { - Check.defined('value', value); - Check.defined('array', array); + TimeInterval.clone = function(timeInterval, result) { + if (!defined(timeInterval)) { + return undefined; + } + if (!defined(result)) { + return new TimeInterval(timeInterval); + } + result.start = timeInterval.start; + result.stop = timeInterval.stop; + result.isStartIncluded = timeInterval.isStartIncluded; + result.isStopIncluded = timeInterval.isStopIncluded; + result.data = timeInterval.data; + return result; + }; + + /** + * Compares two instances and returns <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {TimeInterval} [left] The first instance. + * @param {TimeInterval} [right] The second instance. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. + */ + TimeInterval.equals = function(left, right, dataComparer) { + return left === right || + defined(left) && defined(right) && + (left.isEmpty && right.isEmpty || + left.isStartIncluded === right.isStartIncluded && + left.isStopIncluded === right.isStopIncluded && + JulianDate.equals(left.start, right.start) && + JulianDate.equals(left.stop, right.stop) && + (left.data === right.data || (defined(dataComparer) && dataComparer(left.data, right.data)))); + }; + + /** + * Compares two instances and returns <code>true</code> if they are within <code>epsilon</code> seconds of + * each other. That is, in order for the dates to be considered equal (and for + * this function to return <code>true</code>), the absolute value of the difference between them, in + * seconds, must be less than <code>epsilon</code>. + * + * @param {TimeInterval} [left] The first instance. + * @param {TimeInterval} [right] The second instance. + * @param {Number} epsilon The maximum number of seconds that should separate the two instances. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. + */ + TimeInterval.equalsEpsilon = function(left, right, epsilon, dataComparer) { + Check.typeOf.number('epsilon', epsilon); - return array; + return left === right || + defined(left) && defined(right) && + (left.isEmpty && right.isEmpty || + left.isStartIncluded === right.isStartIncluded && + left.isStopIncluded === right.isStopIncluded && + JulianDate.equalsEpsilon(left.start, right.start, epsilon) && + JulianDate.equalsEpsilon(left.stop, right.stop, epsilon) && + (left.data === right.data || (defined(dataComparer) && dataComparer(left.data, right.data)))); }; /** - * Retrieves an instance from a packed array. + * Computes the intersection of two intervals, optionally merging their data. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PlaneOutlineGeometry} [result] The object into which to store the result. - * @returns {PlaneOutlineGeometry} The modified result parameter or a new PlaneOutlineGeometry instance if one was not provided. + * @param {TimeInterval} left The first interval. + * @param {TimeInterval} [right] The second interval. + * @param {TimeInterval} result An existing instance to use for the result. + * @param {TimeInterval~MergeCallback} [mergeCallback] A function which merges the data of the two intervals. If omitted, the data from the left interval will be used. + * @returns {TimeInterval} The modified result parameter. */ - PlaneOutlineGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); + TimeInterval.intersect = function(left, right, result, mergeCallback) { + Check.typeOf.object('left', left); + Check.typeOf.object('result', result); - if (!defined(result)) { - return new PlaneOutlineGeometry(); + if (!defined(right)) { + return TimeInterval.clone(TimeInterval.EMPTY, result); + } + + var leftStart = left.start; + var leftStop = left.stop; + + var rightStart = right.start; + var rightStop = right.stop; + + var intersectsStartRight = JulianDate.greaterThanOrEquals(rightStart, leftStart) && JulianDate.greaterThanOrEquals(leftStop, rightStart); + var intersectsStartLeft = !intersectsStartRight && JulianDate.lessThanOrEquals(rightStart, leftStart) && JulianDate.lessThanOrEquals(leftStart, rightStop); + + if (!intersectsStartRight && !intersectsStartLeft) { + return TimeInterval.clone(TimeInterval.EMPTY, result); } + var leftIsStartIncluded = left.isStartIncluded; + var leftIsStopIncluded = left.isStopIncluded; + var rightIsStartIncluded = right.isStartIncluded; + var rightIsStopIncluded = right.isStopIncluded; + var leftLessThanRight = JulianDate.lessThan(leftStop, rightStop); + + result.start = intersectsStartRight ? rightStart : leftStart; + result.isStartIncluded = (leftIsStartIncluded && rightIsStartIncluded) || (!JulianDate.equals(rightStart, leftStart) && ((intersectsStartRight && rightIsStartIncluded) || (intersectsStartLeft && leftIsStartIncluded))); + result.stop = leftLessThanRight ? leftStop : rightStop; + result.isStopIncluded = leftLessThanRight ? leftIsStopIncluded : (leftIsStopIncluded && rightIsStopIncluded) || (!JulianDate.equals(rightStop, leftStop) && rightIsStopIncluded); + result.data = defined(mergeCallback) ? mergeCallback(left.data, right.data) : left.data; return result; }; - var min = new Cartesian3(-0.5, -0.5, 0.0); - var max = new Cartesian3( 0.5, 0.5, 0.0); - /** - * Computes the geometric representation of an outline of a plane, including its vertices, indices, and a bounding sphere. + * Checks if the specified date is inside the provided interval. * - * @returns {Geometry|undefined} The computed vertices and indices. + * @param {TimeInterval} timeInterval The interval. + * @param {JulianDate} julianDate The date to check. + * @returns {Boolean} <code>true</code> if the interval contains the specified date, <code>false</code> otherwise. */ - PlaneOutlineGeometry.createGeometry = function() { - var attributes = new GeometryAttributes(); - var indices = new Uint16Array(4 * 2); - var positions = new Float64Array(4 * 3); + TimeInterval.contains = function(timeInterval, julianDate) { + Check.typeOf.object('timeInterval', timeInterval); + Check.typeOf.object('julianDate', julianDate); + + if (timeInterval.isEmpty) { + return false; + } - positions[0] = min.x; - positions[1] = min.y; - positions[2] = min.z; - positions[3] = max.x; - positions[4] = min.y; - positions[5] = min.z; - positions[6] = max.x; - positions[7] = max.y; - positions[8] = min.z; - positions[9] = min.x; - positions[10] = max.y; - positions[11] = min.z; + var startComparedToDate = JulianDate.compare(timeInterval.start, julianDate); + if (startComparedToDate === 0) { + return timeInterval.isStartIncluded; + } - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); + var dateComparedToStop = JulianDate.compare(julianDate, timeInterval.stop); + if (dateComparedToStop === 0) { + return timeInterval.isStopIncluded; + } - indices[0] = 0; - indices[1] = 1; - indices[2] = 1; - indices[3] = 2; - indices[4] = 2; - indices[5] = 3; - indices[6] = 3; - indices[7] = 0; + return startComparedToDate < 0 && dateComparedToStop < 0; + }; - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : new BoundingSphere(Cartesian3.ZERO, Math.sqrt(2.0)) - }); + /** + * Duplicates this instance. + * + * @param {TimeInterval} [result] An existing instance to use for the result. + * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. + */ + TimeInterval.prototype.clone = function(result) { + return TimeInterval.clone(this, result); }; - return PlaneOutlineGeometry; + /** + * Compares this instance against the provided instance componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {TimeInterval} [right] The right hand side interval. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + TimeInterval.prototype.equals = function(right, dataComparer) { + return TimeInterval.equals(this, right, dataComparer); + }; + + /** + * Compares this instance against the provided instance componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {TimeInterval} [right] The right hand side interval. + * @param {Number} epsilon The epsilon to use for equality testing. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + */ + TimeInterval.prototype.equalsEpsilon = function(right, epsilon, dataComparer) { + return TimeInterval.equalsEpsilon(this, right, epsilon, dataComparer); + }; + + /** + * Creates a string representing this TimeInterval in ISO8601 format. + * + * @returns {String} A string representing this TimeInterval in ISO8601 format. + */ + TimeInterval.prototype.toString = function() { + return TimeInterval.toIso8601(this); + }; + + /** + * An immutable empty interval. + * + * @type {TimeInterval} + * @constant + */ + TimeInterval.EMPTY = freezeObject(new TimeInterval({ + start : new JulianDate(), + stop : new JulianDate(), + isStartIncluded : false, + isStopIncluded : false + })); + + /** + * Function interface for merging interval data. + * @callback TimeInterval~MergeCallback + * + * @param {Object} leftData The first data instance. + * @param {Object} rightData The second data instance. + * @returns {Object} The result of merging the two data instances. + */ + + /** + * Function interface for comparing interval data. + * @callback TimeInterval~DataComparer + * @param {Object} leftData The first data instance. + * @param {Object} rightData The second data instance. + * @returns {Boolean} <code>true</code> if the provided instances are equal, <code>false</code> otherwise. + */ + + return TimeInterval; }); -define('Core/pointInsideTriangle',[ - './barycentricCoordinates', - './Cartesian3' +define('Core/Iso8601',[ + './freezeObject', + './JulianDate', + './TimeInterval' ], function( - barycentricCoordinates, - Cartesian3) { + freezeObject, + JulianDate, + TimeInterval) { 'use strict'; - var coords = new Cartesian3(); + var MINIMUM_VALUE = freezeObject(JulianDate.fromIso8601('0000-01-01T00:00:00Z')); + var MAXIMUM_VALUE = freezeObject(JulianDate.fromIso8601('9999-12-31T24:00:00Z')); + var MAXIMUM_INTERVAL = freezeObject(new TimeInterval({ + start : MINIMUM_VALUE, + stop : MAXIMUM_VALUE + })); /** - * Determines if a point is inside a triangle. - * - * @exports pointInsideTriangle + * Constants related to ISO8601 support. * - * @param {Cartesian2|Cartesian3} point The point to test. - * @param {Cartesian2|Cartesian3} p0 The first point of the triangle. - * @param {Cartesian2|Cartesian3} p1 The second point of the triangle. - * @param {Cartesian2|Cartesian3} p2 The third point of the triangle. - * @returns {Boolean} <code>true</code> if the point is inside the triangle; otherwise, <code>false</code>. + * @exports Iso8601 * - * @example - * // Returns true - * var p = new Cesium.Cartesian2(0.25, 0.25); - * var b = Cesium.pointInsideTriangle(p, - * new Cesium.Cartesian2(0.0, 0.0), - * new Cesium.Cartesian2(1.0, 0.0), - * new Cesium.Cartesian2(0.0, 1.0)); + * @see {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601 on Wikipedia} + * @see JulianDate + * @see TimeInterval */ - function pointInsideTriangle(point, p0, p1, p2) { - barycentricCoordinates(point, p0, p1, p2, coords); - return (coords.x > 0.0) && (coords.y > 0.0) && (coords.z > 0); - } + var Iso8601 = { + /** + * A {@link JulianDate} representing the earliest time representable by an ISO8601 date. + * This is equivalent to the date string '0000-01-01T00:00:00Z' + * + * @type {JulianDate} + * @constant + */ + MINIMUM_VALUE : MINIMUM_VALUE, - return pointInsideTriangle; + /** + * A {@link JulianDate} representing the latest time representable by an ISO8601 date. + * This is equivalent to the date string '9999-12-31T24:00:00Z' + * + * @type {JulianDate} + * @constant + */ + MAXIMUM_VALUE : MAXIMUM_VALUE, + + /** + * A {@link TimeInterval} representing the largest interval representable by an ISO8601 interval. + * This is equivalent to the interval string '0000-01-01T00:00:00Z/9999-12-31T24:00:00Z' + * + * @type {JulianDate} + * @constant + */ + MAXIMUM_INTERVAL : MAXIMUM_INTERVAL + }; + + return Iso8601; }); -define('Core/Queue',[ - './defineProperties' +define('Core/KeyboardEventModifier',[ + './freezeObject' ], function( - defineProperties) { + freezeObject) { 'use strict'; /** - * A queue that can enqueue items at the end, and dequeue items from the front. + * This enumerated type is for representing keyboard modifiers. These are keys + * that are held down in addition to other event types. * - * @alias Queue - * @constructor + * @exports KeyboardEventModifier */ - function Queue() { - this._array = []; - this._offset = 0; - this._length = 0; - } + var KeyboardEventModifier = { + /** + * Represents the shift key being held down. + * + * @type {Number} + * @constant + */ + SHIFT : 0, - defineProperties(Queue.prototype, { /** - * The length of the queue. + * Represents the control key being held down. * - * @memberof Queue.prototype + * @type {Number} + * @constant + */ + CTRL : 1, + + /** + * Represents the alt key being held down. * * @type {Number} - * @readonly + * @constant */ - length : { - get : function() { - return this._length; - } - } - }); + ALT : 2 + }; + + return freezeObject(KeyboardEventModifier); +}); + +define('Core/LagrangePolynomialApproximation',[ + './defined' + ], function( + defined) { + 'use strict'; /** - * Enqueues the specified item. + * An {@link InterpolationAlgorithm} for performing Lagrange interpolation. * - * @param {Object} item The item to enqueue. + * @exports LagrangePolynomialApproximation */ - Queue.prototype.enqueue = function(item) { - this._array.push(item); - this._length++; + var LagrangePolynomialApproximation = { + type : 'Lagrange' }; /** - * Dequeues an item. Returns undefined if the queue is empty. + * Given the desired degree, returns the number of data points required for interpolation. * - * @returns {Object} The the dequeued item. + * @param {Number} degree The desired degree of interpolation. + * @returns {Number} The number of required data points needed for the desired degree of interpolation. */ - Queue.prototype.dequeue = function() { - if (this._length === 0) { - return undefined; + LagrangePolynomialApproximation.getRequiredDataPoints = function(degree) { + return Math.max(degree + 1.0, 2); + }; + + /** + * Interpolates values using Lagrange Polynomial Approximation. + * + * @param {Number} x The independent variable for which the dependent variables will be interpolated. + * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * in this array must be in increasing order and the same value must not occur twice in the array. + * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. + * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * each independent variable value in xTable. + * @param {Number[]} [result] An existing array into which to store the result. + * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + */ + LagrangePolynomialApproximation.interpolateOrderZero = function(x, xTable, yTable, yStride, result) { + if (!defined(result)) { + result = new Array(yStride); } - var array = this._array; - var offset = this._offset; - var item = array[offset]; - array[offset] = undefined; + var i; + var j; + var length = xTable.length; - offset++; - if ((offset > 10) && (offset * 2 > array.length)) { - //compact array - this._array = array.slice(offset); - offset = 0; + for (i = 0; i < yStride; i++) { + result[i] = 0; } - this._offset = offset; - this._length--; + for (i = 0; i < length; i++) { + var coefficient = 1; - return item; - }; + for (j = 0; j < length; j++) { + if (j !== i) { + var diffX = xTable[i] - xTable[j]; + coefficient *= (x - xTable[j]) / diffX; + } + } - /** - * Returns the item at the front of the queue. Returns undefined if the queue is empty. - * - * @returns {Object} The item at the front of the queue. - */ - Queue.prototype.peek = function() { - if (this._length === 0) { - return undefined; + for (j = 0; j < yStride; j++) { + result[j] += coefficient * yTable[i * yStride + j]; + } } - return this._array[this._offset]; + return result; }; + return LagrangePolynomialApproximation; +}); + +define('Core/LinearApproximation',[ + './defined', + './DeveloperError' + ], function( + defined, + DeveloperError) { + 'use strict'; + /** - * Check whether this queue contains the specified item. + * An {@link InterpolationAlgorithm} for performing linear interpolation. * - * @param {Object} item The item to search for. + * @exports LinearApproximation */ - Queue.prototype.contains = function(item) { - return this._array.indexOf(item) !== -1; + var LinearApproximation = { + type : 'Linear' }; /** - * Remove all items from the queue. + * Given the desired degree, returns the number of data points required for interpolation. + * Since linear interpolation can only generate a first degree polynomial, this function + * always returns 2. + * @param {Number} degree The desired degree of interpolation. + * @returns {Number} This function always returns 2. + * */ - Queue.prototype.clear = function() { - this._array.length = this._offset = this._length = 0; + LinearApproximation.getRequiredDataPoints = function(degree) { + return 2; }; /** - * Sort the items in the queue in-place. + * Interpolates values using linear approximation. * - * @param {Queue~Comparator} compareFunction A function that defines the sort order. + * @param {Number} x The independent variable for which the dependent variables will be interpolated. + * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * in this array must be in increasing order and the same value must not occur twice in the array. + * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. + * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * each independent variable value in xTable. + * @param {Number[]} [result] An existing array into which to store the result. + * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. */ - Queue.prototype.sort = function(compareFunction) { - if (this._offset > 0) { - //compact array - this._array = this._array.slice(this._offset); - this._offset = 0; + LinearApproximation.interpolateOrderZero = function(x, xTable, yTable, yStride, result) { + if (xTable.length !== 2) { + throw new DeveloperError('The xTable provided to the linear interpolator must have exactly two elements.'); + } else if (yStride <= 0) { + throw new DeveloperError('There must be at least 1 dependent variable for each independent variable.'); + } + + if (!defined(result)) { + result = new Array(yStride); } - this._array.sort(compareFunction); + var i; + var y0; + var y1; + var x0 = xTable[0]; + var x1 = xTable[1]; + + if (x0 === x1) { + throw new DeveloperError('Divide by zero error: xTable[0] and xTable[1] are equal'); + } + + for (i = 0; i < yStride; i++) { + y0 = yTable[i]; + y1 = yTable[i + yStride]; + result[i] = (((y1 - y0) * x) + (x1 * y0) - (x0 * y1)) / (x1 - x0); + } + + return result; }; + return LinearApproximation; +}); + +define('Core/loadArrayBuffer',[ + './Check', + './defined', + './deprecationWarning', + './Resource' + ], function( + Check, + defined, + deprecationWarning, + Resource) { + 'use strict'; + /** - * A function used to compare two items while sorting a queue. - * @callback Queue~Comparator + * Asynchronously loads the given URL as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the URL failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} a An item in the array. - * @param {Object} b An item in the array. - * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, - * a positive value if <code>a</code> is greater than <code>b</code>, or - * 0 if <code>a</code> is equal to <code>b</code>. + * @exports loadArrayBuffer + * + * @param {Resource|String} urlOrResource The URL of the binary data. + * @param {Object} [headers] HTTP headers to send with the requests. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * @example - * function compareNumbers(a, b) { - * return a - b; - * } + * // load a single URL asynchronously + * Cesium.loadArrayBuffer('some/url').then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated */ + function loadArrayBuffer(urlOrResource, headers, request) { + Check.defined('urlOrResource', urlOrResource); + + deprecationWarning('loadArrayBuffer', 'loadArrayBuffer is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchArrayBuffer instead.'); - return Queue; + var resource = Resource.createIfNeeded(urlOrResource, { + headers: headers, + request: request + }); + + return resource.fetchArrayBuffer(); + } + + return loadArrayBuffer; }); -define('Core/PolygonGeometryLibrary',[ - './arrayRemoveDuplicates', - './Cartesian3', - './ComponentDatatype', - './defaultValue', +define('Core/loadBlob',[ + './Check', './defined', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './GeometryPipeline', - './IndexDatatype', - './Math', - './PolygonPipeline', - './PrimitiveType', - './Queue', - './WindingOrder' + './deprecationWarning', + './Resource' ], function( - arrayRemoveDuplicates, - Cartesian3, - ComponentDatatype, - defaultValue, + Check, defined, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - GeometryPipeline, - IndexDatatype, - CesiumMath, - PolygonPipeline, - PrimitiveType, - Queue, - WindingOrder) { + deprecationWarning, + Resource) { 'use strict'; /** - * @private + * Asynchronously loads the given URL as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the URL failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @exports loadBlob + * + * @param {Resource|String} urlOrResource The URL of the data. + * @param {Object} [headers] HTTP headers to send with the requests. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * Cesium.loadBlob('some/url').then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated */ - var PolygonGeometryLibrary = {}; + function loadBlob(urlOrResource, headers, request) { + Check.defined('urlOrResource', urlOrResource); + + deprecationWarning('loadBlob', 'loadBlob is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchBlob instead.'); - PolygonGeometryLibrary.computeHierarchyPackedLength = function(polygonHierarchy) { - var numComponents = 0; - var stack = [polygonHierarchy]; - while (stack.length > 0) { - var hierarchy = stack.pop(); - if (!defined(hierarchy)) { - continue; - } + var resource = Resource.createIfNeeded(urlOrResource, { + headers: headers, + request: request + }); - numComponents += 2; + return resource.fetchBlob(); + } - var positions = hierarchy.positions; - var holes = hierarchy.holes; + return loadBlob; +}); - if (defined(positions)) { - numComponents += positions.length * Cartesian3.packedLength; - } +define('Core/loadCRN',[ + '../ThirdParty/when', + './CompressedTextureBuffer', + './defined', + './deprecationWarning', + './DeveloperError', + './Resource', + './TaskProcessor' + ], function( + when, + CompressedTextureBuffer, + defined, + deprecationWarning, + DeveloperError, + Resource, + TaskProcessor) { + 'use strict'; - if (defined(holes)) { - var length = holes.length; - for (var i = 0; i < length; ++i) { - stack.push(holes[i]); - } - } + var transcodeTaskProcessor = new TaskProcessor('transcodeCRNToDXT', Number.POSITIVE_INFINITY); + + /** + * Asynchronously loads and parses the given URL to a CRN file or parses the raw binary data of a CRN file. + * Returns a promise that will resolve to an object containing the image buffer, width, height and format once loaded, + * or reject if the URL failed to load or failed to parse the data. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @exports loadCRN + * + * @param {Resource|String|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. + * @returns {Promise.<CompressedTextureBuffer>|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @exception {RuntimeError} Unsupported compressed format. + * + * @example + * // load a single URL asynchronously + * Cesium.loadCRN('some/url').then(function(textureData) { + * var width = textureData.width; + * var height = textureData.height; + * var format = textureData.internalFormat; + * var arrayBufferView = textureData.bufferView; + * // use the data to create a texture + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://github.com/BinomialLLC/crunch|crunch DXTc texture compression and transcoding library} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + function loadCRN(resourceOrUrlOrBuffer, headers, request) { + if (!defined(resourceOrUrlOrBuffer)) { + throw new DeveloperError('resourceOrUrlOrBuffer is required.'); + } + + if (defined(headers)) { + deprecationWarning('loadCRN.headers', 'The headers parameter has been deprecated. Set the headers property on the Resource parameter.'); } - return numComponents; - }; + if (defined(request)) { + deprecationWarning('loadCRN.request', 'The request parameter has been deprecated. Set the request property on the Resource parameter.'); + } - PolygonGeometryLibrary.packPolygonHierarchy = function(polygonHierarchy, array, startingIndex) { - var stack = [polygonHierarchy]; - while (stack.length > 0) { - var hierarchy = stack.pop(); - if (!defined(hierarchy)) { - continue; - } + var loadPromise; + if (resourceOrUrlOrBuffer instanceof ArrayBuffer || ArrayBuffer.isView(resourceOrUrlOrBuffer)) { + loadPromise = when.resolve(resourceOrUrlOrBuffer); + } else { + var resource = Resource.createIfNeeded(resourceOrUrlOrBuffer, { + headers: headers, + request: request + }); - var positions = hierarchy.positions; - var holes = hierarchy.holes; + loadPromise = resource.fetchArrayBuffer(); + } - array[startingIndex++] = defined(positions) ? positions.length : 0; - array[startingIndex++] = defined(holes) ? holes.length : 0; + if (!defined(loadPromise)) { + return undefined; + } - if (defined(positions)) { - var positionsLength = positions.length; - for (var i = 0; i < positionsLength; ++i, startingIndex += 3) { - Cartesian3.pack(positions[i], array, startingIndex); - } + return loadPromise.then(function(data) { + if (!defined(data)) { + return; } - - if (defined(holes)) { - var holesLength = holes.length; - for (var j = 0; j < holesLength; ++j) { - stack.push(holes[j]); - } + var transferrableObjects = []; + if (data instanceof ArrayBuffer) { + transferrableObjects.push(data); + } else if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) { + transferrableObjects.push(data.buffer); + } else { + // data is a view of an array buffer. need to copy so it is transferrable to web worker + data = data.slice(0, data.length); + transferrableObjects.push(data.buffer); } - } - - return startingIndex; - }; - PolygonGeometryLibrary.unpackPolygonHierarchy = function(array, startingIndex) { - var positionsLength = array[startingIndex++]; - var holesLength = array[startingIndex++]; - - var positions = new Array(positionsLength); - var holes = holesLength > 0 ? new Array(holesLength) : undefined; + return transcodeTaskProcessor.scheduleTask(data, transferrableObjects); + }).then(function(compressedTextureBuffer) { + return CompressedTextureBuffer.clone(compressedTextureBuffer); + }); + } - for (var i = 0; i < positionsLength; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); - } + return loadCRN; +}); - for (var j = 0; j < holesLength; ++j) { - holes[j] = PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex); - startingIndex = holes[j].startingIndex; - delete holes[j].startingIndex; - } +define('Core/loadImage',[ + './Check', + './defined', + './defineProperties', + './deprecationWarning', + './Resource' + ], function( + Check, + defined, + defineProperties, + deprecationWarning, + Resource) { + 'use strict'; - return { - positions : positions, - holes : holes, - startingIndex : startingIndex - }; - }; + /** + * Asynchronously loads the given image URL. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @exports loadImage + * + * @param {Resource|String} urlOrResource The source URL of the image. + * @param {Boolean} [allowCrossOrigin=true] Whether to request the image using Cross-Origin + * Resource Sharing (CORS). CORS is only actually used if the image URL is actually cross-origin. + * Data URIs are never requested using CORS. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * Cesium.loadImage('some/image/url.png').then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([loadImage('image1.png'), loadImage('image2.png')]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadImage(urlOrResource, allowCrossOrigin, request) { + Check.defined('urlOrResource', urlOrResource); + + deprecationWarning('loadImage', 'loadImage is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchImage instead.'); - var distanceScratch = new Cartesian3(); - function getPointAtDistance(p0, p1, distance, length) { - Cartesian3.subtract(p1, p0, distanceScratch); - Cartesian3.multiplyByScalar(distanceScratch, distance / length, distanceScratch); - Cartesian3.add(p0, distanceScratch, distanceScratch); - return [distanceScratch.x, distanceScratch.y, distanceScratch.z]; - } + var resource = Resource.createIfNeeded(urlOrResource, { + request: request + }); - PolygonGeometryLibrary.subdivideLineCount = function(p0, p1, minDistance) { - var distance = Cartesian3.distance(p0, p1); - var n = distance / minDistance; - var countDivide = Math.max(0, Math.ceil(Math.log(n) / Math.log(2))); - return Math.pow(2, countDivide); - }; + return resource.fetchImage(false, allowCrossOrigin); + } - PolygonGeometryLibrary.subdivideLine = function(p0, p1, minDistance, result) { - var numVertices = PolygonGeometryLibrary.subdivideLineCount(p0, p1, minDistance); - var length = Cartesian3.distance(p0, p1); - var distanceBetweenVertices = length / numVertices; + defineProperties(loadImage, { + createImage : { + get : function() { + return Resource._Implementations.createImage; + }, + set : function(value) { + Resource._Implementations.createImage = value; + } + }, - if (!defined(result)) { - result = []; + defaultCreateImage : { + get : function() { + return Resource._DefaultImplementations.createImage; + } } + }); - var positions = result; - positions.length = numVertices * 3; + return loadImage; +}); - var index = 0; - for ( var i = 0; i < numVertices; i++) { - var p = getPointAtDistance(p0, p1, i * distanceBetweenVertices, length); - positions[index++] = p[0]; - positions[index++] = p[1]; - positions[index++] = p[2]; - } +define('Core/loadImageFromTypedArray',[ + '../ThirdParty/when', + './Check', + './Resource' + ], function( + when, + Check, + Resource) { + 'use strict'; - return positions; - }; + /** + * @private + */ + function loadImageFromTypedArray(uint8Array, format, request) { + Check.typeOf.object('uint8Array', uint8Array); + Check.typeOf.string('format', format); + + var blob = new Blob([uint8Array], { + type : format + }); - var scaleToGeodeticHeightN1 = new Cartesian3(); - var scaleToGeodeticHeightN2 = new Cartesian3(); - var scaleToGeodeticHeightP1 = new Cartesian3(); - var scaleToGeodeticHeightP2 = new Cartesian3(); + var blobUrl = window.URL.createObjectURL(blob); + var resource = new Resource({ + url: blobUrl, + request: request + }); + return resource.fetchImage() + .then(function(image) { + window.URL.revokeObjectURL(blobUrl); + return image; + }, function(error) { + window.URL.revokeObjectURL(blobUrl); + return when.reject(error); + }); + } - PolygonGeometryLibrary.scaleToGeodeticHeightExtruded = function(geometry, maxHeight, minHeight, ellipsoid, perPositionHeight) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + return loadImageFromTypedArray; +}); - var n1 = scaleToGeodeticHeightN1; - var n2 = scaleToGeodeticHeightN2; - var p = scaleToGeodeticHeightP1; - var p2 = scaleToGeodeticHeightP2; +define('Core/loadImageViaBlob',[ + './Check', + './defined', + './deprecationWarning', + './Resource' + ], function( + Check, + defined, + deprecationWarning, + Resource) { + 'use strict'; - if (defined(geometry) && defined(geometry.attributes) && defined(geometry.attributes.position)) { - var positions = geometry.attributes.position.values; - var length = positions.length / 2; + /** + * Asynchronously loads the given image URL by first downloading it as a blob using + * XMLHttpRequest and then loading the image from the buffer via a blob URL. + * This allows access to more information that is not accessible via normal + * Image-based downloading, such as the size of the response. This function + * returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. The + * returned image will have a "blob" property with the Blob itself. If the browser + * does not support an XMLHttpRequests with a responseType of 'blob', or if the + * provided URI is a data URI, this function is equivalent to calling {@link loadImage}, + * and the extra blob property will not be present. + * + * @exports loadImageViaBlob + * + * @param {Resource|String} urlOrResource The source URL of the image. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * Cesium.loadImageViaBlob('some/image/url.png').then(function(image) { + * var blob = image.blob; + * // use the loaded image or XHR + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([loadImageViaBlob('image1.png'), loadImageViaBlob('image2.png')]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadImageViaBlob(urlOrResource, request) { + Check.defined('urlOrResource', urlOrResource); + + deprecationWarning('loadImageViaBlob', 'loadImageViaBlob is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchImage instead.'); - for ( var i = 0; i < length; i += 3) { - Cartesian3.fromArray(positions, i, p); + var resource = Resource.createIfNeeded(urlOrResource, { + request: request + }); - ellipsoid.geodeticSurfaceNormal(p, n1); - p2 = ellipsoid.scaleToGeodeticSurface(p, p2); - n2 = Cartesian3.multiplyByScalar(n1, minHeight, n2); - n2 = Cartesian3.add(p2, n2, n2); - positions[i + length] = n2.x; - positions[i + 1 + length] = n2.y; - positions[i + 2 + length] = n2.z; + return resource.fetchImage(true); + } - if (perPositionHeight) { - p2 = Cartesian3.clone(p, p2); - } - n2 = Cartesian3.multiplyByScalar(n1, maxHeight, n2); - n2 = Cartesian3.add(p2, n2, n2); - positions[i] = n2.x; - positions[i + 1] = n2.y; - positions[i + 2] = n2.z; - } + return loadImageViaBlob; +}); + +define('Core/loadJson',[ + './clone', + './defined', + './deprecationWarning', + './DeveloperError', + './Resource' + ], function( + clone, + defined, + deprecationWarning, + DeveloperError, + Resource) { + 'use strict'; + + // note: */* below is */* but that ends the comment block early + /** + * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the URL failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @exports loadJson + * + * @param {Resource|String} urlOrResource The URL to request. + * @param {Object} [headers] HTTP headers to send with the request. + * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically + * if not specified. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see loadText + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadJson(urlOrResource, headers, request) { + if (!defined(urlOrResource)) { + throw new DeveloperError('urlOrResource is required.'); } - return geometry; - }; + + deprecationWarning('loadJson', 'loadJson is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchJson instead.'); - PolygonGeometryLibrary.polygonsFromHierarchy = function(polygonHierarchy, perPositionHeight, tangentPlane, ellipsoid) { - // create from a polygon hierarchy - // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf - var hierarchy = []; - var polygons = []; + var resource = Resource.createIfNeeded(urlOrResource, { + headers: headers, + request: request + }); - var queue = new Queue(); - queue.enqueue(polygonHierarchy); + return resource.fetchJson(); + } - while (queue.length !== 0) { - var outerNode = queue.dequeue(); - var outerRing = outerNode.positions; - var holes = outerNode.holes; + return loadJson; +}); - outerRing = arrayRemoveDuplicates(outerRing, Cartesian3.equalsEpsilon, true); - if (outerRing.length < 3) { - continue; - } +define('Core/loadJsonp',[ + './clone', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './Resource' + ], function( + clone, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Resource) { + 'use strict'; - var positions2D = tangentPlane.projectPointsOntoPlane(outerRing); - var holeIndices = []; + /** + * Requests a resource using JSONP. + * + * @exports loadJsonp + * + * @param {Resource|String} urlOrResource The URL to request. + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadJsonp(urlOrResource, callbackParameterName, request) { + if (!defined(urlOrResource)) { + throw new DeveloperError('urlOrResource is required.'); + } + + deprecationWarning('loadJsonp', 'loadJsonp is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchJsonp instead.'); - var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); - if (originalWindingOrder === WindingOrder.CLOCKWISE) { - positions2D.reverse(); - outerRing = outerRing.slice().reverse(); + var proxy; + var queryParameters; + if (typeof callbackParameterName === 'object') { + var options = callbackParameterName; + if (defined(options.parameters)) { + queryParameters = clone(options.parameters); } + if (defined(options.proxy)) { + proxy = options.proxy; + } + callbackParameterName = options.callbackParameterName; + } - var positions = outerRing.slice(); - var numChildren = defined(holes) ? holes.length : 0; - var polygonHoles = []; - var i; - var j; + var resource = Resource.createIfNeeded(urlOrResource, { + proxy : proxy, + queryParameters : queryParameters, + request: request + }); - for (i = 0; i < numChildren; i++) { - var hole = holes[i]; - var holePositions = arrayRemoveDuplicates(hole.positions, Cartesian3.equalsEpsilon, true); - if (holePositions.length < 3) { - continue; - } + return resource.fetchJsonp(callbackParameterName); + } - var holePositions2D = tangentPlane.projectPointsOntoPlane(holePositions); + defineProperties(loadJsonp, { + loadAndExecuteScript : { + get : function() { + return Resource._Implementations.loadAndExecuteScript; + }, + set : function(value) { + Resource._Implementations.loadAndExecuteScript = value; + } + }, - originalWindingOrder = PolygonPipeline.computeWindingOrder2D(holePositions2D); - if (originalWindingOrder === WindingOrder.CLOCKWISE) { - holePositions2D.reverse(); - holePositions = holePositions.slice().reverse(); - } + defaultLoadAndExecuteScript : { + get : function() { + return Resource._DefaultImplementations.loadAndExecuteScript; + } + } + }); - polygonHoles.push(holePositions); - holeIndices.push(positions.length); - positions = positions.concat(holePositions); - positions2D = positions2D.concat(holePositions2D); + return loadJsonp; +}); - var numGrandchildren = 0; - if (defined(hole.holes)) { - numGrandchildren = hole.holes.length; - } +define('Renderer/PixelDatatype',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; - for (j = 0; j < numGrandchildren; j++) { - queue.enqueue(hole.holes[j]); - } - } + /** + * @private + */ + var PixelDatatype = { + UNSIGNED_BYTE : WebGLConstants.UNSIGNED_BYTE, + UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT, + UNSIGNED_INT : WebGLConstants.UNSIGNED_INT, + FLOAT : WebGLConstants.FLOAT, + UNSIGNED_INT_24_8 : WebGLConstants.UNSIGNED_INT_24_8, + UNSIGNED_SHORT_4_4_4_4 : WebGLConstants.UNSIGNED_SHORT_4_4_4_4, + UNSIGNED_SHORT_5_5_5_1 : WebGLConstants.UNSIGNED_SHORT_5_5_5_1, + UNSIGNED_SHORT_5_6_5 : WebGLConstants.UNSIGNED_SHORT_5_6_5, - if (!perPositionHeight) { - for (i = 0; i < outerRing.length; i++) { - ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]); - } - for (i = 0; i < polygonHoles.length; i++) { - var polygonHole = polygonHoles[i]; - for (j = 0; j < polygonHole.length; ++j) { - ellipsoid.scaleToGeodeticSurface(polygonHole[j], polygonHole[j]); - } - } + isPacked : function(pixelDatatype) { + return pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8 || + pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4 || + pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1 || + pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5; + }, + + sizeInBytes : function(pixelDatatype) { + switch (pixelDatatype) { + case PixelDatatype.UNSIGNED_BYTE: + return 1; + case PixelDatatype.UNSIGNED_SHORT: + case PixelDatatype.UNSIGNED_SHORT_4_4_4_4: + case PixelDatatype.UNSIGNED_SHORT_5_5_5_1: + case PixelDatatype.UNSIGNED_SHORT_5_6_5: + return 2; + case PixelDatatype.UNSIGNED_INT: + case PixelDatatype.FLOAT: + case PixelDatatype.UNSIGNED_INT_24_8: + return 4; } + }, - hierarchy.push({ - outerRing : outerRing, - holes : polygonHoles - }); - polygons.push({ - positions : positions, - positions2D : positions2D, - holes : holeIndices - }); + validate : function(pixelDatatype) { + return ((pixelDatatype === PixelDatatype.UNSIGNED_BYTE) || + (pixelDatatype === PixelDatatype.UNSIGNED_SHORT) || + (pixelDatatype === PixelDatatype.UNSIGNED_INT) || + (pixelDatatype === PixelDatatype.FLOAT) || + (pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8) || + (pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4) || + (pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1) || + (pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5)); } - - return { - hierarchy : hierarchy, - polygons : polygons - }; }; - PolygonGeometryLibrary.createGeometryFromPositions = function(ellipsoid, polygon, granularity, perPositionHeight, vertexFormat) { - var indices = PolygonPipeline.triangulate(polygon.positions2D, polygon.holes); + return freezeObject(PixelDatatype); +}); - /* If polygon is completely unrenderable, just use the first three vertices */ - if (indices.length < 3) { - indices = [0, 1, 2]; - } +define('Core/PixelFormat',[ + '../Renderer/PixelDatatype', + './freezeObject', + './WebGLConstants' + ], function( + PixelDatatype, + freezeObject, + WebGLConstants) { + 'use strict'; - var positions = polygon.positions; + /** + * The format of a pixel, i.e., the number of components it has and what they represent. + * + * @exports PixelFormat + */ + var PixelFormat = { + /** + * A pixel format containing a depth value. + * + * @type {Number} + * @constant + */ + DEPTH_COMPONENT : WebGLConstants.DEPTH_COMPONENT, - if (perPositionHeight) { - var length = positions.length; - var flattenedPositions = new Array(length * 3); - var index = 0; - for ( var i = 0; i < length; i++) { - var p = positions[i]; - flattenedPositions[index++] = p.x; - flattenedPositions[index++] = p.y; - flattenedPositions[index++] = p.z; - } - var geometry = new Geometry({ - attributes : { - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : flattenedPositions - }) - }, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES - }); + /** + * A pixel format containing a depth and stencil value, most often used with {@link PixelDatatype.UNSIGNED_INT_24_8}. + * + * @type {Number} + * @constant + */ + DEPTH_STENCIL : WebGLConstants.DEPTH_STENCIL, - if (vertexFormat.normal) { - return GeometryPipeline.computeNormal(geometry); - } + /** + * A pixel format containing an alpha channel. + * + * @type {Number} + * @constant + */ + ALPHA : WebGLConstants.ALPHA, - return geometry; - } + /** + * A pixel format containing red, green, and blue channels. + * + * @type {Number} + * @constant + */ + RGB : WebGLConstants.RGB, - return PolygonPipeline.computeSubdivision(ellipsoid, positions, indices, granularity); - }; + /** + * A pixel format containing red, green, blue, and alpha channels. + * + * @type {Number} + * @constant + */ + RGBA : WebGLConstants.RGBA, - var computeWallIndicesSubdivided = []; - var p1Scratch = new Cartesian3(); - var p2Scratch = new Cartesian3(); + /** + * A pixel format containing a luminance (intensity) channel. + * + * @type {Number} + * @constant + */ + LUMINANCE : WebGLConstants.LUMINANCE, - PolygonGeometryLibrary.computeWallGeometry = function(positions, ellipsoid, granularity, perPositionHeight) { - var edgePositions; - var topEdgeLength; - var i; - var p1; - var p2; + /** + * A pixel format containing luminance (intensity) and alpha channels. + * + * @type {Number} + * @constant + */ + LUMINANCE_ALPHA : WebGLConstants.LUMINANCE_ALPHA, - var length = positions.length; - var index = 0; + /** + * A pixel format containing red, green, and blue channels that is DXT1 compressed. + * + * @type {Number} + * @constant + */ + RGB_DXT1 : WebGLConstants.COMPRESSED_RGB_S3TC_DXT1_EXT, - if (!perPositionHeight) { - var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + /** + * A pixel format containing red, green, blue, and alpha channels that is DXT1 compressed. + * + * @type {Number} + * @constant + */ + RGBA_DXT1 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT1_EXT, - var numVertices = 0; - for (i = 0; i < length; i++) { - numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); - } + /** + * A pixel format containing red, green, blue, and alpha channels that is DXT3 compressed. + * + * @type {Number} + * @constant + */ + RGBA_DXT3 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT3_EXT, - topEdgeLength = (numVertices + length) * 3; - edgePositions = new Array(topEdgeLength * 2); - for (i = 0; i < length; i++) { - p1 = positions[i]; - p2 = positions[(i + 1) % length]; + /** + * A pixel format containing red, green, blue, and alpha channels that is DXT5 compressed. + * + * @type {Number} + * @constant + */ + RGBA_DXT5 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT5_EXT, - var tempPositions = PolygonGeometryLibrary.subdivideLine(p1, p2, minDistance, computeWallIndicesSubdivided); - var tempPositionsLength = tempPositions.length; - for (var j = 0; j < tempPositionsLength; ++j, ++index) { - edgePositions[index] = tempPositions[j]; - edgePositions[index + topEdgeLength] = tempPositions[j]; - } + /** + * A pixel format containing red, green, and blue channels that is PVR 4bpp compressed. + * + * @type {Number} + * @constant + */ + RGB_PVRTC_4BPPV1 : WebGLConstants.COMPRESSED_RGB_PVRTC_4BPPV1_IMG, - edgePositions[index] = p2.x; - edgePositions[index + topEdgeLength] = p2.x; - ++index; + /** + * A pixel format containing red, green, and blue channels that is PVR 2bpp compressed. + * + * @type {Number} + * @constant + */ + RGB_PVRTC_2BPPV1 : WebGLConstants.COMPRESSED_RGB_PVRTC_2BPPV1_IMG, - edgePositions[index] = p2.y; - edgePositions[index + topEdgeLength] = p2.y; - ++index; + /** + * A pixel format containing red, green, blue, and alpha channels that is PVR 4bpp compressed. + * + * @type {Number} + * @constant + */ + RGBA_PVRTC_4BPPV1 : WebGLConstants.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, - edgePositions[index] = p2.z; - edgePositions[index + topEdgeLength] = p2.z; - ++index; - } - } else { - topEdgeLength = length * 3 * 2; - edgePositions = new Array(topEdgeLength * 2); - for (i = 0; i < length; i++) { - p1 = positions[i]; - p2 = positions[(i + 1) % length]; - edgePositions[index] = edgePositions[index + topEdgeLength] = p1.x; - ++index; - edgePositions[index] = edgePositions[index + topEdgeLength] = p1.y; - ++index; - edgePositions[index] = edgePositions[index + topEdgeLength] = p1.z; - ++index; - edgePositions[index] = edgePositions[index + topEdgeLength] = p2.x; - ++index; - edgePositions[index] = edgePositions[index + topEdgeLength] = p2.y; - ++index; - edgePositions[index] = edgePositions[index + topEdgeLength] = p2.z; - ++index; + /** + * A pixel format containing red, green, blue, and alpha channels that is PVR 2bpp compressed. + * + * @type {Number} + * @constant + */ + RGBA_PVRTC_2BPPV1 : WebGLConstants.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, + + /** + * A pixel format containing red, green, and blue channels that is ETC1 compressed. + * + * @type {Number} + * @constant + */ + RGB_ETC1 : WebGLConstants.COMPRESSED_RGB_ETC1_WEBGL, + + /** + * @private + */ + componentsLength : function(pixelFormat) { + switch (pixelFormat) { + // Many GPUs store RGB as RGBA internally + // https://devtalk.nvidia.com/default/topic/699479/general-graphics-programming/rgb-auto-converted-to-rgba/post/4142379/#4142379 + case PixelFormat.RGB: + case PixelFormat.RGBA: + return 4; + case PixelFormat.LUMINANCE_ALPHA: + return 2; + case PixelFormat.ALPHA: + case PixelFormat.LUMINANCE: + return 1; + default: + return 1; } - } + }, - length = edgePositions.length; - var indices = IndexDatatype.createTypedArray(length / 3, length - positions.length * 6); - var edgeIndex = 0; - length /= 6; + /** + * @private + */ + validate : function(pixelFormat) { + return pixelFormat === PixelFormat.DEPTH_COMPONENT || + pixelFormat === PixelFormat.DEPTH_STENCIL || + pixelFormat === PixelFormat.ALPHA || + pixelFormat === PixelFormat.RGB || + pixelFormat === PixelFormat.RGBA || + pixelFormat === PixelFormat.LUMINANCE || + pixelFormat === PixelFormat.LUMINANCE_ALPHA || + pixelFormat === PixelFormat.RGB_DXT1 || + pixelFormat === PixelFormat.RGBA_DXT1 || + pixelFormat === PixelFormat.RGBA_DXT3 || + pixelFormat === PixelFormat.RGBA_DXT5 || + pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 || + pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || + pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || + pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 || + pixelFormat === PixelFormat.RGB_ETC1; + }, - for (i = 0; i < length; i++) { - var UL = i; - var UR = UL + 1; - var LL = UL + length; - var LR = LL + 1; + /** + * @private + */ + isColorFormat : function(pixelFormat) { + return pixelFormat === PixelFormat.ALPHA || + pixelFormat === PixelFormat.RGB || + pixelFormat === PixelFormat.RGBA || + pixelFormat === PixelFormat.LUMINANCE || + pixelFormat === PixelFormat.LUMINANCE_ALPHA; + }, - p1 = Cartesian3.fromArray(edgePositions, UL * 3, p1Scratch); - p2 = Cartesian3.fromArray(edgePositions, UR * 3, p2Scratch); - if (Cartesian3.equalsEpsilon(p1, p2, CesiumMath.EPSILON14)) { - continue; + /** + * @private + */ + isDepthFormat : function(pixelFormat) { + return pixelFormat === PixelFormat.DEPTH_COMPONENT || + pixelFormat === PixelFormat.DEPTH_STENCIL; + }, + + /** + * @private + */ + isCompressedFormat : function(pixelFormat) { + return pixelFormat === PixelFormat.RGB_DXT1 || + pixelFormat === PixelFormat.RGBA_DXT1 || + pixelFormat === PixelFormat.RGBA_DXT3 || + pixelFormat === PixelFormat.RGBA_DXT5 || + pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 || + pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || + pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || + pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 || + pixelFormat === PixelFormat.RGB_ETC1; + }, + + /** + * @private + */ + isDXTFormat : function(pixelFormat) { + return pixelFormat === PixelFormat.RGB_DXT1 || + pixelFormat === PixelFormat.RGBA_DXT1 || + pixelFormat === PixelFormat.RGBA_DXT3 || + pixelFormat === PixelFormat.RGBA_DXT5; + }, + + /** + * @private + */ + isPVRTCFormat : function(pixelFormat) { + return pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 || + pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || + pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || + pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1; + }, + + /** + * @private + */ + isETC1Format : function(pixelFormat) { + return pixelFormat === PixelFormat.RGB_ETC1; + }, + + /** + * @private + */ + compressedTextureSizeInBytes : function(pixelFormat, width, height) { + switch (pixelFormat) { + case PixelFormat.RGB_DXT1: + case PixelFormat.RGBA_DXT1: + case PixelFormat.RGB_ETC1: + return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; + + case PixelFormat.RGBA_DXT3: + case PixelFormat.RGBA_DXT5: + return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; + + case PixelFormat.RGB_PVRTC_4BPPV1: + case PixelFormat.RGBA_PVRTC_4BPPV1: + return Math.floor((Math.max(width, 8) * Math.max(height, 8) * 4 + 7) / 8); + + case PixelFormat.RGB_PVRTC_2BPPV1: + case PixelFormat.RGBA_PVRTC_2BPPV1: + return Math.floor((Math.max(width, 16) * Math.max(height, 8) * 2 + 7) / 8); + + default: + return 0; } + }, - indices[edgeIndex++] = UL; - indices[edgeIndex++] = LL; - indices[edgeIndex++] = UR; - indices[edgeIndex++] = UR; - indices[edgeIndex++] = LL; - indices[edgeIndex++] = LR; + /** + * @private + */ + textureSizeInBytes : function(pixelFormat, pixelDatatype, width, height) { + var componentsLength = PixelFormat.componentsLength(pixelFormat); + if (PixelDatatype.isPacked(pixelDatatype)) { + componentsLength = 1; + } + return componentsLength * PixelDatatype.sizeInBytes(pixelDatatype) * width * height; } - - return new Geometry({ - attributes : new GeometryAttributes({ - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : edgePositions - }) - }), - indices : indices, - primitiveType : PrimitiveType.TRIANGLES - }); }; - return PolygonGeometryLibrary; + return freezeObject(PixelFormat); }); -define('Core/PolygonGeometry',[ - './BoundingRectangle', - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './Cartographic', +define('Core/loadKTX',[ + '../ThirdParty/when', './Check', - './ComponentDatatype', - './defaultValue', + './CompressedTextureBuffer', './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid', - './EllipsoidTangentPlane', - './Geometry', - './GeometryAttribute', - './GeometryInstance', - './GeometryPipeline', - './IndexDatatype', - './Math', - './Matrix3', - './PolygonGeometryLibrary', - './PolygonPipeline', - './Quaternion', - './Rectangle', - './VertexFormat', - './WindingOrder' + './deprecationWarning', + './PixelFormat', + './Resource', + './RuntimeError' ], function( - BoundingRectangle, - BoundingSphere, - Cartesian2, - Cartesian3, - Cartographic, + when, Check, - ComponentDatatype, - defaultValue, + CompressedTextureBuffer, defined, - defineProperties, - DeveloperError, - Ellipsoid, - EllipsoidTangentPlane, - Geometry, - GeometryAttribute, - GeometryInstance, - GeometryPipeline, - IndexDatatype, - CesiumMath, - Matrix3, - PolygonGeometryLibrary, - PolygonPipeline, - Quaternion, - Rectangle, - VertexFormat, - WindingOrder) { + deprecationWarning, + PixelFormat, + Resource, + RuntimeError) { 'use strict'; - var computeBoundingRectangleCartesian2 = new Cartesian2(); - var computeBoundingRectangleCartesian3 = new Cartesian3(); - var computeBoundingRectangleQuaternion = new Quaternion(); - var computeBoundingRectangleMatrix3 = new Matrix3(); + /** + * Asynchronously loads and parses the given URL to a KTX file or parses the raw binary data of a KTX file. + * Returns a promise that will resolve to an object containing the image buffer, width, height and format once loaded, + * or reject if the URL failed to load or failed to parse the data. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * <p> + * The following are part of the KTX format specification but are not supported: + * <ul> + * <li>Big-endian files</li> + * <li>Metadata</li> + * <li>3D textures</li> + * <li>Texture Arrays</li> + * <li>Cubemaps</li> + * <li>Mipmaps</li> + * </ul> + * </p> + * + * @exports loadKTX + * + * @param {Resource|String|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. + * @returns {Promise.<CompressedTextureBuffer>|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @exception {RuntimeError} Invalid KTX file. + * @exception {RuntimeError} File is the wrong endianness. + * @exception {RuntimeError} glInternalFormat is not a valid format. + * @exception {RuntimeError} glType must be zero when the texture is compressed. + * @exception {RuntimeError} The type size for compressed textures must be 1. + * @exception {RuntimeError} glFormat must be zero when the texture is compressed. + * @exception {RuntimeError} Generating mipmaps for a compressed texture is unsupported. + * @exception {RuntimeError} The base internal format must be the same as the format for uncompressed textures. + * @exception {RuntimeError} 3D textures are not supported. + * @exception {RuntimeError} Texture arrays are not supported. + * @exception {RuntimeError} Cubemaps are not supported. + * + * @example + * // load a single URL asynchronously + * Cesium.loadKTX('some/url').then(function(ktxData) { + * var width = ktxData.width; + * var height = ktxData.height; + * var format = ktxData.internalFormat; + * var arrayBufferView = ktxData.bufferView; + * // use the data to create a texture + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/|KTX file format} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + function loadKTX(resourceOrUrlOrBuffer, headers, request) { + Check.defined('resourceOrUrlOrBuffer', resourceOrUrlOrBuffer); + + if (defined(headers)) { + deprecationWarning('loadCRN.headers', 'The headers parameter has been deprecated. Set the headers property on the Resource parameter.'); + } - function computeBoundingRectangle(tangentPlane, positions, angle, result) { - var rotation = Quaternion.fromAxisAngle(tangentPlane._plane.normal, angle, computeBoundingRectangleQuaternion); - var textureMatrix = Matrix3.fromQuaternion(rotation, computeBoundingRectangleMatrix3); + if (defined(request)) { + deprecationWarning('loadCRN.request', 'The request parameter has been deprecated. Set the request property on the Resource parameter.'); + } - var minX = Number.POSITIVE_INFINITY; - var maxX = Number.NEGATIVE_INFINITY; - var minY = Number.POSITIVE_INFINITY; - var maxY = Number.NEGATIVE_INFINITY; + var loadPromise; + if (resourceOrUrlOrBuffer instanceof ArrayBuffer || ArrayBuffer.isView(resourceOrUrlOrBuffer)) { + loadPromise = when.resolve(resourceOrUrlOrBuffer); + } else { + var resource = Resource.createIfNeeded(resourceOrUrlOrBuffer, { + headers: headers, + request: request + }); + loadPromise = resource.fetchArrayBuffer(); + } - var length = positions.length; - for ( var i = 0; i < length; ++i) { - var p = Cartesian3.clone(positions[i], computeBoundingRectangleCartesian3); - Matrix3.multiplyByVector(textureMatrix, p, p); - var st = tangentPlane.projectPointOntoPlane(p, computeBoundingRectangleCartesian2); + if (!defined(loadPromise)) { + return undefined; + } - if (defined(st)) { - minX = Math.min(minX, st.x); - maxX = Math.max(maxX, st.x); + return loadPromise.then(function(data) { + if (defined(data)) { + return parseKTX(data); + } + }); + } - minY = Math.min(minY, st.y); - maxY = Math.max(maxY, st.y); + var fileIdentifier = [0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A]; + var endiannessTest = 0x04030201; + + var sizeOfUint32 = 4; + + function parseKTX(data) { + var byteBuffer = new Uint8Array(data); + + var isKTX = true; + for (var i = 0; i < fileIdentifier.length; ++i) { + if (fileIdentifier[i] !== byteBuffer[i]) { + isKTX = false; + break; } } - result.x = minX; - result.y = minY; - result.width = maxX - minX; - result.height = maxY - minY; - return result; - } + if (!isKTX) { + throw new RuntimeError('Invalid KTX file.'); + } - var scratchCarto1 = new Cartographic(); - var scratchCarto2 = new Cartographic(); - function adjustPosHeightsForNormal(position, p1, p2, ellipsoid) { - var carto1 = ellipsoid.cartesianToCartographic(position, scratchCarto1); - var height = carto1.height; - var p1Carto = ellipsoid.cartesianToCartographic(p1, scratchCarto2); - p1Carto.height = height; - ellipsoid.cartographicToCartesian(p1Carto, p1); + var view; + var byteOffset; - var p2Carto = ellipsoid.cartesianToCartographic(p2, scratchCarto2); - p2Carto.height = height - 100; - ellipsoid.cartographicToCartesian(p2Carto, p2); - } + if (defined(data.buffer)) { + view = new DataView(data.buffer); + byteOffset = data.byteOffset; + } else { + view = new DataView(data); + byteOffset = 0; + } - var scratchBoundingRectangle = new BoundingRectangle(); - var scratchPosition = new Cartesian3(); - var scratchNormal = new Cartesian3(); - var scratchTangent = new Cartesian3(); - var scratchBitangent = new Cartesian3(); - var p1Scratch = new Cartesian3(); - var p2Scratch = new Cartesian3(); - var scratchPerPosNormal = new Cartesian3(); - var scratchPerPosTangent = new Cartesian3(); - var scratchPerPosBitangent = new Cartesian3(); + byteOffset += 12; // skip identifier - var appendTextureCoordinatesOrigin = new Cartesian2(); - var appendTextureCoordinatesCartesian2 = new Cartesian2(); - var appendTextureCoordinatesCartesian3 = new Cartesian3(); - var appendTextureCoordinatesQuaternion = new Quaternion(); - var appendTextureCoordinatesMatrix3 = new Matrix3(); + var endianness = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + if (endianness !== endiannessTest) { + throw new RuntimeError('File is the wrong endianness.'); + } - function computeAttributes(options) { - var vertexFormat = options.vertexFormat; - var geometry = options.geometry; - var shadowVolume = options.shadowVolume; - if (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) { - // PERFORMANCE_IDEA: Compute before subdivision, then just interpolate during subdivision. - // PERFORMANCE_IDEA: Compute with createGeometryFromPositions() for fast path when there's no holes. - var boundingRectangle = options.boundingRectangle; - var tangentPlane = options.tangentPlane; - var ellipsoid = options.ellipsoid; - var stRotation = options.stRotation; - var wall = options.wall; - var top = options.top || wall; - var bottom = options.bottom || wall; - var perPositionHeight = options.perPositionHeight; + var glType = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var glTypeSize = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var glFormat = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var glInternalFormat = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var glBaseInternalFormat = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var pixelWidth = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var pixelHeight = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var pixelDepth = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var numberOfArrayElements = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var numberOfFaces = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var numberOfMipmapLevels = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var bytesOfKeyValueByteSize = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - var origin = appendTextureCoordinatesOrigin; - origin.x = boundingRectangle.x; - origin.y = boundingRectangle.y; + // skip metadata + byteOffset += bytesOfKeyValueByteSize; - var flatPositions = geometry.attributes.position.values; - var length = flatPositions.length; + var imageSize = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - var textureCoordinates = vertexFormat.st ? new Float32Array(2 * (length / 3)) : undefined; - var normals; - if (vertexFormat.normal) { - if (perPositionHeight && top && !wall) { - normals = geometry.attributes.normal.values; - } else { - normals = new Float32Array(length); - } - } - var tangents = vertexFormat.tangent ? new Float32Array(length) : undefined; - var bitangents = vertexFormat.bitangent ? new Float32Array(length) : undefined; - var extrudeNormals = shadowVolume ? new Float32Array(length) : undefined; + var texture; + if (defined(data.buffer)) { + texture = new Uint8Array(data.buffer, byteOffset, imageSize); + } else { + texture = new Uint8Array(data, byteOffset, imageSize); + } - var textureCoordIndex = 0; - var attrIndex = 0; + // Some tools use a sized internal format. + // See table 2: https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml + if (glInternalFormat === 0x8051) { // GL_RGB8 + glInternalFormat = PixelFormat.RGB; + } else if (glInternalFormat === 0x8058) { // GL_RGBA8 + glInternalFormat = PixelFormat.RGBA; + } - var normal = scratchNormal; - var tangent = scratchTangent; - var bitangent = scratchBitangent; - var recomputeNormal = true; + if (!PixelFormat.validate(glInternalFormat)) { + throw new RuntimeError('glInternalFormat is not a valid format.'); + } - var rotation = Quaternion.fromAxisAngle(tangentPlane._plane.normal, stRotation, appendTextureCoordinatesQuaternion); - var textureMatrix = Matrix3.fromQuaternion(rotation, appendTextureCoordinatesMatrix3); + if (PixelFormat.isCompressedFormat(glInternalFormat)) { + if (glType !== 0) { + throw new RuntimeError('glType must be zero when the texture is compressed.'); + } + if (glTypeSize !== 1) { + throw new RuntimeError('The type size for compressed textures must be 1.'); + } + if (glFormat !== 0) { + throw new RuntimeError('glFormat must be zero when the texture is compressed.'); + } + } else if (glBaseInternalFormat !== glFormat) { + throw new RuntimeError('The base internal format must be the same as the format for uncompressed textures.'); + } - var bottomOffset = 0; - var bottomOffset2 = 0; + if (pixelDepth !== 0) { + throw new RuntimeError('3D textures are unsupported.'); + } - if (top && bottom) { - bottomOffset = length / 2; - bottomOffset2 = length / 3; + if (numberOfArrayElements !== 0) { + throw new RuntimeError('Texture arrays are unsupported.'); + } + if (numberOfFaces !== 1) { + throw new RuntimeError('Cubemaps are unsupported.'); + } - length /= 2; - } + // Only use the level 0 mipmap + if (numberOfMipmapLevels > 1) { + var levelSize = PixelFormat.isCompressedFormat(glInternalFormat) ? + PixelFormat.compressedTextureSizeInBytes(glInternalFormat, pixelWidth, pixelHeight) : + PixelFormat.textureSizeInBytes(glInternalFormat, pixelWidth, pixelHeight); + texture = new Uint8Array(texture.buffer, texture.byteOffset, levelSize); + } - for ( var i = 0; i < length; i += 3) { - var position = Cartesian3.fromArray(flatPositions, i, appendTextureCoordinatesCartesian3); + return new CompressedTextureBuffer(glInternalFormat, pixelWidth, pixelHeight, texture); + } - if (vertexFormat.st) { - var p = Matrix3.multiplyByVector(textureMatrix, position, scratchPosition); - p = ellipsoid.scaleToGeodeticSurface(p,p); - var st = tangentPlane.projectPointOntoPlane(p, appendTextureCoordinatesCartesian2); - Cartesian2.subtract(st, origin, st); + return loadKTX; +}); - var stx = CesiumMath.clamp(st.x / boundingRectangle.width, 0, 1); - var sty = CesiumMath.clamp(st.y / boundingRectangle.height, 0, 1); - if (bottom) { - textureCoordinates[textureCoordIndex + bottomOffset2] = stx; - textureCoordinates[textureCoordIndex + 1 + bottomOffset2] = sty; - } - if (top) { - textureCoordinates[textureCoordIndex] = stx; - textureCoordinates[textureCoordIndex + 1] = sty; - } +define('Core/loadText',[ + './Check', + './defined', + './deprecationWarning', + './Resource' + ], function( + Check, + defined, + deprecationWarning, + Resource) { + 'use strict'; - textureCoordIndex += 2; - } + /** + * Asynchronously loads the given URL as text. Returns a promise that will resolve to + * a String once loaded, or reject if the URL failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @exports loadText + * + * @param {Resource|String} urlOrResource The URL to request. + * @param {Object} [headers] HTTP headers to send with the requests. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * Cesium.loadText(resource).then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadText(urlOrResource, headers, request) { + Check.defined('urlOrResource', urlOrResource); + + deprecationWarning('loadText', 'loadText is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchText instead.'); - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) { - var attrIndex1 = attrIndex + 1; - var attrIndex2 = attrIndex + 2; + var resource = Resource.createIfNeeded(urlOrResource, { + headers: headers, + request: request + }); - if (wall) { - if (i + 3 < length) { - var p1 = Cartesian3.fromArray(flatPositions, i + 3, p1Scratch); + return resource.fetchText(); + } - if (recomputeNormal) { - var p2 = Cartesian3.fromArray(flatPositions, i + length, p2Scratch); - if (perPositionHeight) { - adjustPosHeightsForNormal(position, p1, p2, ellipsoid); - } - Cartesian3.subtract(p1, position, p1); - Cartesian3.subtract(p2, position, p2); - normal = Cartesian3.normalize(Cartesian3.cross(p2, p1, normal), normal); - recomputeNormal = false; - } + return loadText; +}); - if (Cartesian3.equalsEpsilon(p1, position, CesiumMath.EPSILON10)) { // if we've reached a corner - recomputeNormal = true; - } - } +define('Core/loadWithXhr',[ + '../ThirdParty/when', + './Check', + './defineProperties', + './deprecationWarning', + './Resource' + ], function( + when, + Check, + defineProperties, + deprecationWarning, + Resource) { + 'use strict'; - if (vertexFormat.tangent || vertexFormat.bitangent) { - bitangent = ellipsoid.geodeticSurfaceNormal(position, bitangent); - if (vertexFormat.tangent) { - tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); - } - } - } else { - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - if (vertexFormat.tangent || vertexFormat.bitangent) { - if (perPositionHeight) { - scratchPerPosNormal = Cartesian3.fromArray(normals, attrIndex, scratchPerPosNormal); - scratchPerPosTangent = Cartesian3.cross(Cartesian3.UNIT_Z, scratchPerPosNormal, scratchPerPosTangent); - scratchPerPosTangent = Cartesian3.normalize(Matrix3.multiplyByVector(textureMatrix, scratchPerPosTangent, scratchPerPosTangent), scratchPerPosTangent); - if (vertexFormat.bitangent) { - scratchPerPosBitangent = Cartesian3.normalize(Cartesian3.cross(scratchPerPosNormal, scratchPerPosTangent, scratchPerPosBitangent), scratchPerPosBitangent); - } - } + /** + * Asynchronously loads the given URL. Returns a promise that will resolve to + * the result once loaded, or reject if the URL failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @exports loadWithXhr + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The URL of the data. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.method='GET'] The HTTP method to use. + * @param {String} [options.data] The data to send with the request, if any. + * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @param {Request} [options.request] The request object. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single URL asynchronously. In real code, you should use loadBlob instead. + * Cesium.loadWithXhr({ + * url : 'some/url', + * responseType : 'blob' + * }).then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see loadArrayBuffer + * @see loadBlob + * @see loadJson + * @see loadText + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadWithXhr(options) { + Check.defined('options', options); + + deprecationWarning('loadWithXhr', 'loadWithXhr is deprecated and will be removed in Cesium 1.44. Please use Resource.fetch instead.'); - tangent = Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent); - tangent = Cartesian3.normalize(Matrix3.multiplyByVector(textureMatrix, tangent, tangent), tangent); - if (vertexFormat.bitangent) { - bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); - } - } - } + // Take advantage that most parameters are the same + var resource = new Resource(options); - if (vertexFormat.normal) { - if (options.wall) { - normals[attrIndex + bottomOffset] = normal.x; - normals[attrIndex1 + bottomOffset] = normal.y; - normals[attrIndex2 + bottomOffset] = normal.z; - } else if (bottom){ - normals[attrIndex + bottomOffset] = -normal.x; - normals[attrIndex1 + bottomOffset] = -normal.y; - normals[attrIndex2 + bottomOffset] = -normal.z; - } + return resource.fetch({ + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + } - if ((top && !perPositionHeight) || wall) { - normals[attrIndex] = normal.x; - normals[attrIndex1] = normal.y; - normals[attrIndex2] = normal.z; - } - } + defineProperties(loadWithXhr, { + load : { + get : function() { + return Resource._Implementations.loadWithXhr; + }, + set : function(value) { + Resource._Implementations.loadWithXhr = value; + } + }, - if (shadowVolume) { - if (wall) { - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - } - extrudeNormals[attrIndex + bottomOffset] = -normal.x; - extrudeNormals[attrIndex1 + bottomOffset] = -normal.y; - extrudeNormals[attrIndex2 + bottomOffset] = -normal.z; - } + defaultLoad : { + get : function() { + return Resource._DefaultImplementations.loadWithXhr; + } + } + }); - if (vertexFormat.tangent) { - if (options.wall) { - tangents[attrIndex + bottomOffset] = tangent.x; - tangents[attrIndex1 + bottomOffset] = tangent.y; - tangents[attrIndex2 + bottomOffset] = tangent.z; - } else if (bottom) { - tangents[attrIndex + bottomOffset] = -tangent.x; - tangents[attrIndex1 + bottomOffset] = -tangent.y; - tangents[attrIndex2 + bottomOffset] = -tangent.z; - } + return loadWithXhr; +}); - if(top) { - if (perPositionHeight) { - tangents[attrIndex] = scratchPerPosTangent.x; - tangents[attrIndex1] = scratchPerPosTangent.y; - tangents[attrIndex2] = scratchPerPosTangent.z; - } else { - tangents[attrIndex] = tangent.x; - tangents[attrIndex1] = tangent.y; - tangents[attrIndex2] = tangent.z; - } - } - } +define('Core/loadXML',[ + './Check', + './defined', + './deprecationWarning', + './Resource' + ], function( + Check, + defined, + deprecationWarning, + Resource) { + 'use strict'; - if (vertexFormat.bitangent) { - if (bottom) { - bitangents[attrIndex + bottomOffset] = bitangent.x; - bitangents[attrIndex1 + bottomOffset] = bitangent.y; - bitangents[attrIndex2 + bottomOffset] = bitangent.z; - } - if (top) { - if (perPositionHeight) { - bitangents[attrIndex] = scratchPerPosBitangent.x; - bitangents[attrIndex1] = scratchPerPosBitangent.y; - bitangents[attrIndex2] = scratchPerPosBitangent.z; - } else { - bitangents[attrIndex] = bitangent.x; - bitangents[attrIndex1] = bitangent.y; - bitangents[attrIndex2] = bitangent.z; - } - } - } - attrIndex += 3; - } - } + /** + * Asynchronously loads the given URL as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the URL failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @exports loadXML + * + * @param {Resource|String} urlOrResource The URL to request. + * @param {Object} [headers] HTTP headers to send with the requests. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @deprecated + */ + function loadXML(urlOrResource, headers, request) { + Check.defined('urlOrResource', urlOrResource); + + deprecationWarning('loadXML', 'loadXML is deprecated and will be removed in Cesium 1.44. Please use Resource.fetchXML instead.'); - if (vertexFormat.st) { - geometry.attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : textureCoordinates - }); - } + var resource = Resource.createIfNeeded(urlOrResource, { + headers: headers, + request: request + }); - if (vertexFormat.normal) { - geometry.attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } + return resource.fetchXML(); + } - if (vertexFormat.tangent) { - geometry.attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); - } + return loadXML; +}); - if (vertexFormat.bitangent) { - geometry.attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } +define('Core/ManagedArray',[ + './Check', + './defaultValue', + './defineProperties' + ], function( + Check, + defaultValue, + defineProperties) { + 'use strict'; - if (shadowVolume) { - geometry.attributes.extrudeDirection = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : extrudeNormals - }); - } - } - return geometry; + /** + * A wrapper around arrays so that the internal length of the array can be manually managed. + * + * @alias ManagedArray + * @constructor + * @private + * + * @param {Number} [length=0] The initial length of the array. + */ + function ManagedArray(length) { + length = defaultValue(length, 0); + this._array = new Array(length); + this._length = length; } - var createGeometryFromPositionsExtrudedPositions = []; + defineProperties(ManagedArray.prototype, { + /** + * Gets or sets the length of the array. + * If the set length is greater than the length of the internal array, the internal array is resized. + * + * @type Number + */ + length : { + get : function() { + return this._length; + }, + set : function(length) { + this._length = length; + if (length > this._array.length) { + this._array.length = length; + } + } + }, - function createGeometryFromPositionsExtruded(ellipsoid, polygon, granularity, hierarchy, perPositionHeight, closeTop, closeBottom, vertexFormat) { - var geos = { - walls : [] - }; - var i; + /** + * Gets the internal array. + * + * @type Array + * @readonly + */ + values : { + get : function() { + return this._array; + } + } + }); - if (closeTop || closeBottom) { - var topGeo = PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygon, granularity, perPositionHeight, vertexFormat); + /** + * Gets the element at an index. + * + * @param {Number} index The index to get. + */ + ManagedArray.prototype.get = function(index) { + Check.typeOf.number.lessThan('index', index, this._array.length); + + return this._array[index]; + }; - var edgePoints = topGeo.attributes.position.values; - var indices = topGeo.indices; - var numPositions; - var newIndices; + /** + * Sets the element at an index. Resizes the array if index is greater than the length of the array. + * + * @param {Number} index The index to set. + * @param {*} value The value to set at index. + */ + ManagedArray.prototype.set = function(index, value) { + Check.typeOf.number('index', index); + + if (index >= this.length) { + this.length = index + 1; + } + this._array[index] = value; + }; - if (closeTop && closeBottom) { - var topBottomPositions = edgePoints.concat(edgePoints); + /** + * Push an element into the array. + */ + ManagedArray.prototype.push = function(element) { + var index = this.length++; + this._array[index] = element; + }; - numPositions = topBottomPositions.length / 3; + /** + * Pop an element from the array. + * + * @returns {*} The last element in the array. + */ + ManagedArray.prototype.pop = function() { + return this._array[--this.length]; + }; - newIndices = IndexDatatype.createTypedArray(numPositions, indices.length * 2); - newIndices.set(indices); - var ilength = indices.length; + /** + * Resize the internal array if length > _array.length. + * + * @param {Number} length The length. + */ + ManagedArray.prototype.reserve = function(length) { + Check.typeOf.number.greaterThanOrEquals('length', length, 0); + + if (length > this._array.length) { + this._array.length = length; + } + }; - var length = numPositions / 2; + /** + * Resize the array. + * + * @param {Number} length The length. + */ + ManagedArray.prototype.resize = function(length) { + Check.typeOf.number.greaterThanOrEquals('length', length, 0); + + this.length = length; + }; - for (i = 0; i < ilength; i += 3) { - var i0 = newIndices[i] + length; - var i1 = newIndices[i + 1] + length; - var i2 = newIndices[i + 2] + length; + /** + * Trim the internal array to the specified length. Defaults to the current length. + * + * @param {Number} [length] The length. + */ + ManagedArray.prototype.trim = function(length) { + length = defaultValue(length, this.length); + this._array.length = length; + }; - newIndices[i + ilength] = i2; - newIndices[i + 1 + ilength] = i1; - newIndices[i + 2 + ilength] = i0; - } + return ManagedArray; +}); - topGeo.attributes.position.values = topBottomPositions; - if (perPositionHeight) { - var normals = topGeo.attributes.normal.values; - topGeo.attributes.normal.values = new Float32Array(topBottomPositions.length); - topGeo.attributes.normal.values.set(normals); - } - topGeo.indices = newIndices; - } else if (closeBottom) { - numPositions = edgePoints.length / 3; - newIndices = IndexDatatype.createTypedArray(numPositions, indices.length); +define('Core/MapboxApi',[ + './Credit', + './defined' +], function( + Credit, + defined) { + 'use strict'; - for (i = 0; i < indices.length; i += 3) { - newIndices[i] = indices[i + 2]; - newIndices[i + 1] = indices[i + 1]; - newIndices[i + 2] = indices[i]; - } + var MapboxApi = {}; - topGeo.indices = newIndices; - } + /** + * The default Mapbox API access token to use if one is not provided to the + * constructor of an object that uses the Mapbox API. If this property is undefined, + * Cesium's default access token is used, which is only suitable for use early in development. + * Please supply your own access token as soon as possible and prior to deployment. + * Visit {@link https://www.mapbox.com/help/create-api-access-token/} for details. + * When Cesium's default access token is used, a message is printed to the console the first + * time the Mapbox API is used. + * + * @type {String} + */ + MapboxApi.defaultAccessToken = undefined; - geos.topAndBottom = new GeometryInstance({ - geometry : topGeo - }); + var printedMapboxWarning = false; + var errorCredit; + var errorString = 'This application is using Cesium\'s default Mapbox access token. Please create a new access token for the application as soon as possible and prior to deployment by visiting https://www.mapbox.com/account/apps/, and provide your token to Cesium by setting the Cesium.MapboxApi.defaultAccessToken property before constructing the CesiumWidget or any other object that uses the Mapbox API.'; + MapboxApi.getAccessToken = function(providedToken) { + if (defined(providedToken)) { + return providedToken; } - var outerRing = hierarchy.outerRing; - var tangentPlane = EllipsoidTangentPlane.fromPoints(outerRing, ellipsoid); - var positions2D = tangentPlane.projectPointsOntoPlane(outerRing, createGeometryFromPositionsExtrudedPositions); - - var windingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); - if (windingOrder === WindingOrder.CLOCKWISE) { - outerRing = outerRing.slice().reverse(); + if (!defined(MapboxApi.defaultAccessToken)) { + if (!printedMapboxWarning) { + console.log(errorString); + printedMapboxWarning = true; + } + return 'pk.eyJ1IjoiYW5hbHl0aWNhbGdyYXBoaWNzIiwiYSI6ImNpd204Zm4wejAwNzYyeW5uNjYyZmFwdWEifQ.7i-VIZZWX8pd1bTfxIVj9g'; } - var wallGeo = PolygonGeometryLibrary.computeWallGeometry(outerRing, ellipsoid, granularity, perPositionHeight); - geos.walls.push(new GeometryInstance({ - geometry : wallGeo - })); + return MapboxApi.defaultAccessToken; + }; - var holes = hierarchy.holes; - for (i = 0; i < holes.length; i++) { - var hole = holes[i]; + MapboxApi.getErrorCredit = function(providedToken) { + if (defined(providedToken) || defined(MapboxApi.defaultAccessToken)) { + return undefined; + } - tangentPlane = EllipsoidTangentPlane.fromPoints(hole, ellipsoid); - positions2D = tangentPlane.projectPointsOntoPlane(hole, createGeometryFromPositionsExtrudedPositions); + if (!defined(errorCredit)) { + errorCredit = new Credit({ + text : errorString, + showOnScreen : true + }); + } - windingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); - if (windingOrder === WindingOrder.COUNTER_CLOCKWISE) { - hole = hole.slice().reverse(); - } + return errorCredit; + }; - wallGeo = PolygonGeometryLibrary.computeWallGeometry(hole, ellipsoid, granularity); - geos.walls.push(new GeometryInstance({ - geometry : wallGeo - })); - } + return MapboxApi; +}); - return geos; - } +define('Core/MapProjection',[ + './defineProperties', + './DeveloperError' + ], function( + defineProperties, + DeveloperError) { + 'use strict'; /** - * A description of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * Defines how geodetic ellipsoid coordinates ({@link Cartographic}) project to a + * flat map like Cesium's 2D and Columbus View modes. * - * @alias PolygonGeometry + * @alias MapProjection * @constructor * - * @param {Object} options Object with the following properties: - * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. - * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. - * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. - * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. - * - * @see PolygonGeometry#createGeometry - * @see PolygonGeometry#fromPositions + * @see GeographicProjection + * @see WebMercatorProjection + */ + function MapProjection() { + DeveloperError.throwInstantiationError(); + } + + defineProperties(MapProjection.prototype, { + /** + * Gets the {@link Ellipsoid}. + * + * @memberof MapProjection.prototype + * + * @type {Ellipsoid} + * @readonly + */ + ellipsoid : { + get : DeveloperError.throwInstantiationError + } + }); + + /** + * Projects {@link Cartographic} coordinates, in radians, to projection-specific map coordinates, in meters. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo} + * @memberof MapProjection + * @function * - * @example - * // 1. create a polygon from points - * var polygon = new Cesium.PolygonGeometry({ - * polygonHierarchy : new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ]) - * ) - * }); - * var geometry = Cesium.PolygonGeometry.createGeometry(polygon); + * @param {Cartographic} cartographic The coordinates to project. + * @param {Cartesian3} [result] An instance into which to copy the result. If this parameter is + * undefined, a new instance is created and returned. + * @returns {Cartesian3} The projected coordinates. If the result parameter is not undefined, the + * coordinates are copied there and that instance is returned. Otherwise, a new instance is + * created and returned. + */ + MapProjection.prototype.project = DeveloperError.throwInstantiationError; + + /** + * Unprojects projection-specific map {@link Cartesian3} coordinates, in meters, to {@link Cartographic} + * coordinates, in radians. * - * // 2. create a nested polygon with holes - * var polygonWithHole = new Cesium.PolygonGeometry({ - * polygonHierarchy : new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -109.0, 30.0, - * -95.0, 30.0, - * -95.0, 40.0, - * -109.0, 40.0 - * ]), - * [new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -107.0, 31.0, - * -107.0, 39.0, - * -97.0, 39.0, - * -97.0, 31.0 - * ]), - * [new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -105.0, 33.0, - * -99.0, 33.0, - * -99.0, 37.0, - * -105.0, 37.0 - * ]), - * [new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -103.0, 34.0, - * -101.0, 34.0, - * -101.0, 36.0, - * -103.0, 36.0 - * ]) - * )] - * )] - * )] - * ) - * }); - * var geometry = Cesium.PolygonGeometry.createGeometry(polygonWithHole); + * @memberof MapProjection + * @function * - * // 3. create extruded polygon - * var extrudedPolygon = new Cesium.PolygonGeometry({ - * polygonHierarchy : new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ]) - * ), - * extrudedHeight: 300000 - * }); - * var geometry = Cesium.PolygonGeometry.createGeometry(extrudedPolygon); + * @param {Cartesian3} cartesian The Cartesian position to unproject with height (z) in meters. + * @param {Cartographic} [result] An instance into which to copy the result. If this parameter is + * undefined, a new instance is created and returned. + * @returns {Cartographic} The unprojected coordinates. If the result parameter is not undefined, the + * coordinates are copied there and that instance is returned. Otherwise, a new instance is + * created and returned. */ - function PolygonGeometry(options) { - Check.typeOf.object('options', options); - Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy); - if (defined(options.perPositionHeight) && options.perPositionHeight && defined(options.height)) { - throw new DeveloperError('Cannot use both options.perPositionHeight and options.height'); - } - - var polygonHierarchy = options.polygonHierarchy; - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var stRotation = defaultValue(options.stRotation, 0.0); - var height = defaultValue(options.height, 0.0); - var perPositionHeight = defaultValue(options.perPositionHeight, false); - - var extrudedHeight = options.extrudedHeight; - var extrude = defined(extrudedHeight); - - if (!perPositionHeight && extrude) { - //Ignore extrudedHeight if it matches height - if (CesiumMath.equalsEpsilon(height, extrudedHeight, CesiumMath.EPSILON10)) { - extrudedHeight = undefined; - extrude = false; - } else { - var h = extrudedHeight; - extrudedHeight = Math.min(h, height); - height = Math.max(h, height); - } - } - - this._vertexFormat = VertexFormat.clone(vertexFormat); - this._ellipsoid = Ellipsoid.clone(ellipsoid); - this._granularity = granularity; - this._stRotation = stRotation; - this._height = height; - this._extrudedHeight = defaultValue(extrudedHeight, 0.0); - this._extrude = extrude; - this._closeTop = defaultValue(options.closeTop, true); - this._closeBottom = defaultValue(options.closeBottom, true); - this._polygonHierarchy = polygonHierarchy; - this._perPositionHeight = perPositionHeight; - this._shadowVolume = defaultValue(options.shadowVolume, false); - this._workerName = 'createPolygonGeometry'; + MapProjection.prototype.unproject = DeveloperError.throwInstantiationError; - var positions = polygonHierarchy.positions; - if (!defined(positions) || positions.length < 3) { - this._rectangle = new Rectangle(); - } else { - this._rectangle = Rectangle.fromCartesianArray(positions, ellipsoid); - } + return MapProjection; +}); - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 10; - } +define('Core/Matrix2',[ + './Cartesian2', + './Check', + './defaultValue', + './defined', + './defineProperties', + './freezeObject' + ], function( + Cartesian2, + Check, + defaultValue, + defined, + defineProperties, + freezeObject) { + 'use strict'; /** - * A description of a polygon from an array of positions. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. - * @param {Number} [options.height=0.0] The height of the polygon. - * @param {Number} [options.extrudedHeight] The height of the polygon extrusion. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. - * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. - * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. - * @returns {PolygonGeometry} - * + * A 2x2 matrix, indexable as a column-major order array. + * Constructor parameters are in row-major order for code readability. + * @alias Matrix2 + * @constructor * - * @example - * // create a polygon from points - * var polygon = Cesium.PolygonGeometry.fromPositions({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ]) - * }); - * var geometry = Cesium.PolygonGeometry.createGeometry(polygon); + * @param {Number} [column0Row0=0.0] The value for column 0, row 0. + * @param {Number} [column1Row0=0.0] The value for column 1, row 0. + * @param {Number} [column0Row1=0.0] The value for column 0, row 1. + * @param {Number} [column1Row1=0.0] The value for column 1, row 1. * - * @see PolygonGeometry#createGeometry + * @see Matrix2.fromColumnMajorArray + * @see Matrix2.fromRowMajorArray + * @see Matrix2.fromScale + * @see Matrix2.fromUniformScale + * @see Matrix3 + * @see Matrix4 */ - PolygonGeometry.fromPositions = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function Matrix2(column0Row0, column1Row0, column0Row1, column1Row1) { + this[0] = defaultValue(column0Row0, 0.0); + this[1] = defaultValue(column0Row1, 0.0); + this[2] = defaultValue(column1Row0, 0.0); + this[3] = defaultValue(column1Row1, 0.0); + } - Check.defined('options.positions', options.positions); - - var newOptions = { - polygonHierarchy : { - positions : options.positions - }, - height : options.height, - extrudedHeight : options.extrudedHeight, - vertexFormat : options.vertexFormat, - stRotation : options.stRotation, - ellipsoid : options.ellipsoid, - granularity : options.granularity, - perPositionHeight : options.perPositionHeight, - closeTop : options.closeTop, - closeBottom: options.closeBottom - }; - return new PolygonGeometry(newOptions); - }; + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + Matrix2.packedLength = 4; /** * Stores the provided instance into the provided array. * - * @param {PolygonGeometry} value The value to pack. + * @param {Matrix2} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - PolygonGeometry.pack = function(value, array, startingIndex) { + Matrix2.pack = function(value, array, startingIndex) { Check.typeOf.object('value', value); Check.defined('array', array); startingIndex = defaultValue(startingIndex, 0); - startingIndex = PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex); - - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; - - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - - Rectangle.pack(value._rectangle, array, startingIndex); - startingIndex += Rectangle.packedLength; - - array[startingIndex++] = value._height; - array[startingIndex++] = value._extrudedHeight; - array[startingIndex++] = value._granularity; - array[startingIndex++] = value._stRotation; - array[startingIndex++] = value._extrude ? 1.0 : 0.0; - array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0; - array[startingIndex++] = value._closeTop ? 1.0 : 0.0; - array[startingIndex++] = value._closeBottom ? 1.0 : 0.0; - array[startingIndex++] = value._shadowVolume ? 1.0 : 0.0; - array[startingIndex] = value.packedLength; + array[startingIndex++] = value[0]; + array[startingIndex++] = value[1]; + array[startingIndex++] = value[2]; + array[startingIndex++] = value[3]; return array; }; - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchVertexFormat = new VertexFormat(); - var scratchRectangle = new Rectangle(); - - //Only used to avoid inaability to default construct. - var dummyOptions = { - polygonHierarchy : {} - }; - /** * Retrieves an instance from a packed array. * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PolygonGeometry} [result] The object into which to store the result. + * @param {Matrix2} [result] The object into which to store the result. + * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. */ - PolygonGeometry.unpack = function(array, startingIndex, result) { + Matrix2.unpack = function(array, startingIndex, result) { Check.defined('array', array); startingIndex = defaultValue(startingIndex, 0); - var polygonHierarchy = PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex); - startingIndex = polygonHierarchy.startingIndex; - delete polygonHierarchy.startingIndex; - - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; - - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + if (!defined(result)) { + result = new Matrix2(); + } - var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); - startingIndex += Rectangle.packedLength; - - var height = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var granularity = array[startingIndex++]; - var stRotation = array[startingIndex++]; - var extrude = array[startingIndex++] === 1.0; - var perPositionHeight = array[startingIndex++] === 1.0; - var closeTop = array[startingIndex++] === 1.0; - var closeBottom = array[startingIndex++] === 1.0; - var shadowVolume = array[startingIndex++] === 1.0; - var packedLength = array[startingIndex]; + result[0] = array[startingIndex++]; + result[1] = array[startingIndex++]; + result[2] = array[startingIndex++]; + result[3] = array[startingIndex++]; + return result; + }; + /** + * Duplicates a Matrix2 instance. + * + * @param {Matrix2} matrix The matrix to duplicate. + * @param {Matrix2} [result] The object onto which to store the result. + * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. (Returns undefined if matrix is undefined) + */ + Matrix2.clone = function(matrix, result) { + if (!defined(matrix)) { + return undefined; + } if (!defined(result)) { - result = new PolygonGeometry(dummyOptions); + return new Matrix2(matrix[0], matrix[2], + matrix[1], matrix[3]); } - - result._polygonHierarchy = polygonHierarchy; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._height = height; - result._extrudedHeight = extrudedHeight; - result._granularity = granularity; - result._stRotation = stRotation; - result._extrude = extrude; - result._perPositionHeight = perPositionHeight; - result._closeTop = closeTop; - result._closeBottom = closeBottom; - result._rectangle = Rectangle.clone(rectangle); - result._shadowVolume = shadowVolume; - result.packedLength = packedLength; + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; return result; }; /** - * Computes the geometric representation of a polygon, including its vertices, indices, and a bounding sphere. + * Creates a Matrix2 from 4 consecutive elements in an array. * - * @param {PolygonGeometry} polygonGeometry A description of the polygon. - * @returns {Geometry|undefined} The computed vertices and indices. + * @param {Number[]} array The array whose 4 consecutive elements correspond to the positions of the matrix. Assumes column-major order. + * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. + * @param {Matrix2} [result] The object onto which to store the result. + * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. + * + * @example + * // Create the Matrix2: + * // [1.0, 2.0] + * // [1.0, 2.0] + * + * var v = [1.0, 1.0, 2.0, 2.0]; + * var m = Cesium.Matrix2.fromArray(v); + * + * // Create same Matrix2 with using an offset into an array + * var v2 = [0.0, 0.0, 1.0, 1.0, 2.0, 2.0]; + * var m2 = Cesium.Matrix2.fromArray(v2, 2); */ - PolygonGeometry.createGeometry = function(polygonGeometry) { - var vertexFormat = polygonGeometry._vertexFormat; - var ellipsoid = polygonGeometry._ellipsoid; - var granularity = polygonGeometry._granularity; - var stRotation = polygonGeometry._stRotation; - var height = polygonGeometry._height; - var extrudedHeight = polygonGeometry._extrudedHeight; - var extrude = polygonGeometry._extrude; - var polygonHierarchy = polygonGeometry._polygonHierarchy; - var perPositionHeight = polygonGeometry._perPositionHeight; - var closeTop = polygonGeometry._closeTop; - var closeBottom = polygonGeometry._closeBottom; - - var outerPositions = polygonHierarchy.positions; - if (outerPositions.length < 3) { - return; - } - - var tangentPlane = EllipsoidTangentPlane.fromPoints(outerPositions, ellipsoid); - - var results = PolygonGeometryLibrary.polygonsFromHierarchy(polygonHierarchy, perPositionHeight, tangentPlane, ellipsoid); - var hierarchy = results.hierarchy; - var polygons = results.polygons; - - if (hierarchy.length === 0) { - return; - } - - outerPositions = hierarchy[0].outerRing; - var boundingRectangle = computeBoundingRectangle(tangentPlane, outerPositions, stRotation, scratchBoundingRectangle); - - var geometry; - var geometries = []; - - var options = { - perPositionHeight: perPositionHeight, - vertexFormat: vertexFormat, - geometry: undefined, - tangentPlane: tangentPlane, - boundingRectangle: boundingRectangle, - ellipsoid: ellipsoid, - stRotation: stRotation, - bottom: false, - top: true, - wall: false - }; - - var i; - - if (extrude) { - options.top = closeTop; - options.bottom = closeBottom; - options.shadowVolume = polygonGeometry._shadowVolume; - for (i = 0; i < polygons.length; i++) { - geometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], granularity, hierarchy[i], perPositionHeight, closeTop, closeBottom, vertexFormat); - - var topAndBottom; - if (closeTop && closeBottom) { - topAndBottom = geometry.topAndBottom; - options.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(topAndBottom.geometry, height, extrudedHeight, ellipsoid, perPositionHeight); - } else if (closeTop) { - topAndBottom = geometry.topAndBottom; - topAndBottom.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(topAndBottom.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); - options.geometry = topAndBottom.geometry; - } else if (closeBottom) { - topAndBottom = geometry.topAndBottom; - topAndBottom.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(topAndBottom.geometry.attributes.position.values, extrudedHeight, ellipsoid, true); - options.geometry = topAndBottom.geometry; - } - if (closeTop || closeBottom) { - options.wall = false; - topAndBottom.geometry = computeAttributes(options); - geometries.push(topAndBottom); - } - - var walls = geometry.walls; - options.wall = true; - for ( var k = 0; k < walls.length; k++) { - var wall = walls[k]; - options.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(wall.geometry, height, extrudedHeight, ellipsoid, perPositionHeight); - wall.geometry = computeAttributes(options); - geometries.push(wall); - } - } - } else { - for (i = 0; i < polygons.length; i++) { - geometry = new GeometryInstance({ - geometry : PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygons[i], granularity, perPositionHeight, vertexFormat) - }); - geometry.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); - options.geometry = geometry.geometry; - geometry.geometry = computeAttributes(options); - geometries.push(geometry); - } - } - - geometry = GeometryPipeline.combineInstances(geometries)[0]; - geometry.attributes.position.values = new Float64Array(geometry.attributes.position.values); - geometry.indices = IndexDatatype.createTypedArray(geometry.attributes.position.values.length / 3, geometry.indices); - - var attributes = geometry.attributes; - var boundingSphere = BoundingSphere.fromVertices(attributes.position.values); + Matrix2.fromArray = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - if (!vertexFormat.position) { - delete attributes.position; + if (!defined(result)) { + result = new Matrix2(); } - return new Geometry({ - attributes : attributes, - indices : geometry.indices, - primitiveType : geometry.primitiveType, - boundingSphere : boundingSphere - }); + result[0] = array[startingIndex]; + result[1] = array[startingIndex + 1]; + result[2] = array[startingIndex + 2]; + result[3] = array[startingIndex + 3]; + return result; }; /** - * @private + * Creates a Matrix2 instance from a column-major order array. + * + * @param {Number[]} values The column-major order array. + * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. */ - PolygonGeometry.createShadowVolume = function(polygonGeometry, minHeightFunc, maxHeightFunc) { - var granularity = polygonGeometry._granularity; - var ellipsoid = polygonGeometry._ellipsoid; - - var minHeight = minHeightFunc(granularity, ellipsoid); - var maxHeight = maxHeightFunc(granularity, ellipsoid); - - return new PolygonGeometry({ - polygonHierarchy : polygonGeometry._polygonHierarchy, - ellipsoid : ellipsoid, - stRotation : polygonGeometry._stRotation, - granularity : granularity, - perPositionHeight : false, - extrudedHeight : minHeight, - height : maxHeight, - vertexFormat : VertexFormat.POSITION_ONLY, - shadowVolume: true - }); + Matrix2.fromColumnMajorArray = function(values, result) { + Check.defined('values', values); + + return Matrix2.clone(values, result); }; - defineProperties(PolygonGeometry.prototype, { - /** - * @private - */ - rectangle : { - get : function() { - return this._rectangle; - } + /** + * Creates a Matrix2 instance from a row-major order array. + * The resulting matrix will be in column-major order. + * + * @param {Number[]} values The row-major order array. + * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + */ + Matrix2.fromRowMajorArray = function(values, result) { + Check.defined('values', values); + + if (!defined(result)) { + return new Matrix2(values[0], values[1], + values[2], values[3]); } - }); - - return PolygonGeometry; -}); - -define('Core/PolygonHierarchy',[ - './defined' - ], function( - defined) { - 'use strict'; + result[0] = values[0]; + result[1] = values[2]; + result[2] = values[1]; + result[3] = values[3]; + return result; + }; /** - * An hierarchy of linear rings which define a polygon and its holes. - * The holes themselves may also have holes which nest inner polygons. - * @alias PolygonHierarchy - * @constructor + * Computes a Matrix2 instance representing a non-uniform scale. * - * @param {Cartesian3[]} [positions] A linear ring defining the outer boundary of the polygon or hole. - * @param {PolygonHierarchy[]} [holes] An array of polygon hierarchies defining holes in the polygon. + * @param {Cartesian2} scale The x and y scale factors. + * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + * + * @example + * // Creates + * // [7.0, 0.0] + * // [0.0, 8.0] + * var m = Cesium.Matrix2.fromScale(new Cesium.Cartesian2(7.0, 8.0)); */ - function PolygonHierarchy(positions, holes) { - /** - * A linear ring defining the outer boundary of the polygon or hole. - * @type {Cartesian3[]} - */ - this.positions = defined(positions) ? positions : []; - - /** - * An array of polygon hierarchies defining holes in the polygon. - * @type {PolygonHierarchy[]} - */ - this.holes = defined(holes) ? holes : []; - } - - return PolygonHierarchy; -}); - -define('Core/PolygonOutlineGeometry',[ - './arrayRemoveDuplicates', - './BoundingSphere', - './Cartesian3', - './Check', - './ComponentDatatype', - './defaultValue', - './defined', - './DeveloperError', - './Ellipsoid', - './EllipsoidTangentPlane', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './GeometryInstance', - './GeometryPipeline', - './IndexDatatype', - './Math', - './PolygonGeometryLibrary', - './PolygonPipeline', - './PrimitiveType', - './Queue', - './WindingOrder' - ], function( - arrayRemoveDuplicates, - BoundingSphere, - Cartesian3, - Check, - ComponentDatatype, - defaultValue, - defined, - DeveloperError, - Ellipsoid, - EllipsoidTangentPlane, - Geometry, - GeometryAttribute, - GeometryAttributes, - GeometryInstance, - GeometryPipeline, - IndexDatatype, - CesiumMath, - PolygonGeometryLibrary, - PolygonPipeline, - PrimitiveType, - Queue, - WindingOrder) { - 'use strict'; - var createGeometryFromPositionsPositions = []; - var createGeometryFromPositionsSubdivided = []; + Matrix2.fromScale = function(scale, result) { + Check.typeOf.object('scale', scale); + + if (!defined(result)) { + return new Matrix2( + scale.x, 0.0, + 0.0, scale.y); + } - function createGeometryFromPositions(ellipsoid, positions, minDistance, perPositionHeight) { - var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid); - var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions); + result[0] = scale.x; + result[1] = 0.0; + result[2] = 0.0; + result[3] = scale.y; + return result; + }; - var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); - if (originalWindingOrder === WindingOrder.CLOCKWISE) { - positions2D.reverse(); - positions = positions.slice().reverse(); + /** + * Computes a Matrix2 instance representing a uniform scale. + * + * @param {Number} scale The uniform scale factor. + * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + * + * @example + * // Creates + * // [2.0, 0.0] + * // [0.0, 2.0] + * var m = Cesium.Matrix2.fromUniformScale(2.0); + */ + Matrix2.fromUniformScale = function(scale, result) { + Check.typeOf.number('scale', scale); + + if (!defined(result)) { + return new Matrix2( + scale, 0.0, + 0.0, scale); } - var subdividedPositions; - var i; + result[0] = scale; + result[1] = 0.0; + result[2] = 0.0; + result[3] = scale; + return result; + }; - var length = positions.length; - var index = 0; + /** + * Creates a rotation matrix. + * + * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. + * + * @example + * // Rotate a point 45 degrees counterclockwise. + * var p = new Cesium.Cartesian2(5, 6); + * var m = Cesium.Matrix2.fromRotation(Cesium.Math.toRadians(45.0)); + * var rotated = Cesium.Matrix2.multiplyByVector(m, p, new Cesium.Cartesian2()); + */ + Matrix2.fromRotation = function(angle, result) { + Check.typeOf.number('angle', angle); + + var cosAngle = Math.cos(angle); + var sinAngle = Math.sin(angle); - if (!perPositionHeight) { - var numVertices = 0; - for (i = 0; i < length; i++) { - numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); - } - subdividedPositions = new Float64Array(numVertices * 3); - for (i = 0; i < length; i++) { - var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); - var tempPositionsLength = tempPositions.length; - for (var j = 0; j < tempPositionsLength; ++j) { - subdividedPositions[index++] = tempPositions[j]; - } - } - } else { - subdividedPositions = new Float64Array(length * 2 * 3); - for (i = 0; i < length; i++) { - var p0 = positions[i]; - var p1 = positions[(i + 1) % length]; - subdividedPositions[index++] = p0.x; - subdividedPositions[index++] = p0.y; - subdividedPositions[index++] = p0.z; - subdividedPositions[index++] = p1.x; - subdividedPositions[index++] = p1.y; - subdividedPositions[index++] = p1.z; - } + if (!defined(result)) { + return new Matrix2( + cosAngle, -sinAngle, + sinAngle, cosAngle); } + result[0] = cosAngle; + result[1] = sinAngle; + result[2] = -sinAngle; + result[3] = cosAngle; + return result; + }; - length = subdividedPositions.length / 3; - var indicesSize = length * 2; - var indices = IndexDatatype.createTypedArray(length, indicesSize); - index = 0; - for (i = 0; i < length - 1; i++) { - indices[index++] = i; - indices[index++] = i + 1; + /** + * Creates an Array from the provided Matrix2 instance. + * The array will be in column-major order. + * + * @param {Matrix2} matrix The matrix to use.. + * @param {Number[]} [result] The Array onto which to store the result. + * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. + */ + Matrix2.toArray = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + + if (!defined(result)) { + return [matrix[0], matrix[1], matrix[2], matrix[3]]; } - indices[index++] = length - 1; - indices[index++] = 0; + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + return result; + }; - return new GeometryInstance({ - geometry : new Geometry({ - attributes : new GeometryAttributes({ - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : subdividedPositions - }) - }), - indices : indices, - primitiveType : PrimitiveType.LINES - }) - }); - } + /** + * Computes the array index of the element at the provided row and column. + * + * @param {Number} row The zero-based index of the row. + * @param {Number} column The zero-based index of the column. + * @returns {Number} The index of the element at the provided row and column. + * + * @exception {DeveloperError} row must be 0 or 1. + * @exception {DeveloperError} column must be 0 or 1. + * + * @example + * var myMatrix = new Cesium.Matrix2(); + * var column1Row0Index = Cesium.Matrix2.getElementIndex(1, 0); + * var column1Row0 = myMatrix[column1Row0Index] + * myMatrix[column1Row0Index] = 10.0; + */ + Matrix2.getElementIndex = function(column, row) { + Check.typeOf.number.greaterThanOrEquals('row', row, 0); + Check.typeOf.number.lessThanOrEquals('row', row, 1); - function createGeometryFromPositionsExtruded(ellipsoid, positions, minDistance, perPositionHeight) { - var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid); - var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions); + Check.typeOf.number.greaterThanOrEquals('column', column, 0); + Check.typeOf.number.lessThanOrEquals('column', column, 1); + + return column * 2 + row; + }; - var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); - if (originalWindingOrder === WindingOrder.CLOCKWISE) { - positions2D.reverse(); - positions = positions.slice().reverse(); - } + /** + * Retrieves a copy of the matrix column at the provided index as a Cartesian2 instance. + * + * @param {Matrix2} matrix The matrix to use. + * @param {Number} index The zero-based index of the column to retrieve. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter. + * + * @exception {DeveloperError} index must be 0 or 1. + */ + Matrix2.getColumn = function(matrix, index, result) { + Check.typeOf.object('matrix', matrix); - var subdividedPositions; - var i; + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 1); - var length = positions.length; - var corners = new Array(length); - var index = 0; + Check.typeOf.object('result', result); + + var startIndex = index * 2; + var x = matrix[startIndex]; + var y = matrix[startIndex + 1]; - if (!perPositionHeight) { - var numVertices = 0; - for (i = 0; i < length; i++) { - numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); - } + result.x = x; + result.y = y; + return result; + }; - subdividedPositions = new Float64Array(numVertices * 3 * 2); - for (i = 0; i < length; ++i) { - corners[i] = index / 3; - var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); - var tempPositionsLength = tempPositions.length; - for (var j = 0; j < tempPositionsLength; ++j) { - subdividedPositions[index++] = tempPositions[j]; - } - } - } else { - subdividedPositions = new Float64Array(length * 2 * 3 * 2); - for (i = 0; i < length; ++i) { - corners[i] = index / 3; - var p0 = positions[i]; - var p1 = positions[(i + 1) % length]; + /** + * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian2 instance. + * + * @param {Matrix2} matrix The matrix to use. + * @param {Number} index The zero-based index of the column to set. + * @param {Cartesian2} cartesian The Cartesian whose values will be assigned to the specified column. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. + * + * @exception {DeveloperError} index must be 0 or 1. + */ + Matrix2.setColumn = function(matrix, index, cartesian, result) { + Check.typeOf.object('matrix', matrix); - subdividedPositions[index++] = p0.x; - subdividedPositions[index++] = p0.y; - subdividedPositions[index++] = p0.z; - subdividedPositions[index++] = p1.x; - subdividedPositions[index++] = p1.y; - subdividedPositions[index++] = p1.z; - } - } + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 1); - length = subdividedPositions.length / (3 * 2); - var cornersLength = corners.length; + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + result = Matrix2.clone(matrix, result); + var startIndex = index * 2; + result[startIndex] = cartesian.x; + result[startIndex + 1] = cartesian.y; + return result; + }; - var indicesSize = ((length * 2) + cornersLength) * 2; - var indices = IndexDatatype.createTypedArray(length, indicesSize); + /** + * Retrieves a copy of the matrix row at the provided index as a Cartesian2 instance. + * + * @param {Matrix2} matrix The matrix to use. + * @param {Number} index The zero-based index of the row to retrieve. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter. + * + * @exception {DeveloperError} index must be 0 or 1. + */ + Matrix2.getRow = function(matrix, index, result) { + Check.typeOf.object('matrix', matrix); - index = 0; - for (i = 0; i < length; ++i) { - indices[index++] = i; - indices[index++] = (i + 1) % length; - indices[index++] = i + length; - indices[index++] = ((i + 1) % length) + length; - } + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 1); - for (i = 0; i < cornersLength; i++) { - var corner = corners[i]; - indices[index++] = corner; - indices[index++] = corner + length; - } + Check.typeOf.object('result', result); + + var x = matrix[index]; + var y = matrix[index + 2]; - return new GeometryInstance({ - geometry : new Geometry({ - attributes : new GeometryAttributes({ - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : subdividedPositions - }) - }), - indices : indices, - primitiveType : PrimitiveType.LINES - }) - }); - } + result.x = x; + result.y = y; + return result; + }; /** - * A description of the outline of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy. - * - * @alias PolygonOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. - * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. - * - * @see PolygonOutlineGeometry#createGeometry - * @see PolygonOutlineGeometry#fromPositions - * - * @example - * // 1. create a polygon outline from points - * var polygon = new Cesium.PolygonOutlineGeometry({ - * polygonHierarchy : new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ]) - * ) - * }); - * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon); + * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian2 instance. * - * // 2. create a nested polygon with holes outline - * var polygonWithHole = new Cesium.PolygonOutlineGeometry({ - * polygonHierarchy : new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -109.0, 30.0, - * -95.0, 30.0, - * -95.0, 40.0, - * -109.0, 40.0 - * ]), - * [new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -107.0, 31.0, - * -107.0, 39.0, - * -97.0, 39.0, - * -97.0, 31.0 - * ]), - * [new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -105.0, 33.0, - * -99.0, 33.0, - * -99.0, 37.0, - * -105.0, 37.0 - * ]), - * [new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -103.0, 34.0, - * -101.0, 34.0, - * -101.0, 36.0, - * -103.0, 36.0 - * ]) - * )] - * )] - * )] - * ) - * }); - * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygonWithHole); + * @param {Matrix2} matrix The matrix to use. + * @param {Number} index The zero-based index of the row to set. + * @param {Cartesian2} cartesian The Cartesian whose values will be assigned to the specified row. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. * - * // 3. create extruded polygon outline - * var extrudedPolygon = new Cesium.PolygonOutlineGeometry({ - * polygonHierarchy : new Cesium.PolygonHierarchy( - * Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ]) - * ), - * extrudedHeight: 300000 - * }); - * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(extrudedPolygon); + * @exception {DeveloperError} index must be 0 or 1. */ - function PolygonOutlineGeometry(options) { - Check.typeOf.object('options', options); - Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy); - - if (defined(options.perPositionHeight) && options.perPositionHeight && defined(options.height)) { - throw new DeveloperError('Cannot use both options.perPositionHeight and options.height'); - } - - var polygonHierarchy = options.polygonHierarchy; - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var height = defaultValue(options.height, 0.0); - var perPositionHeight = defaultValue(options.perPositionHeight, false); + Matrix2.setRow = function(matrix, index, cartesian, result) { + Check.typeOf.object('matrix', matrix); - var extrudedHeight = options.extrudedHeight; - var extrude = defined(extrudedHeight); - if (extrude && !perPositionHeight) { - var h = extrudedHeight; - extrudedHeight = Math.min(h, height); - height = Math.max(h, height); - } + Check.typeOf.number.greaterThanOrEquals('index', index, 0); + Check.typeOf.number.lessThanOrEquals('index', index, 1); - this._ellipsoid = Ellipsoid.clone(ellipsoid); - this._granularity = granularity; - this._height = height; - this._extrudedHeight = defaultValue(extrudedHeight, 0.0); - this._extrude = extrude; - this._polygonHierarchy = polygonHierarchy; - this._perPositionHeight = perPositionHeight; - this._workerName = 'createPolygonOutlineGeometry'; + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + result = Matrix2.clone(matrix, result); + result[index] = cartesian.x; + result[index + 2] = cartesian.y; + return result; + }; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + Ellipsoid.packedLength + 6; - } + var scratchColumn = new Cartesian2(); /** - * Stores the provided instance into the provided array. - * - * @param {PolygonOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * Extracts the non-uniform scale assuming the matrix is an affine transformation. * - * @returns {Number[]} The array that was packed into + * @param {Matrix2} matrix The matrix. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter. */ - PolygonOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); - Check.defined('array', array); + Matrix2.getScale = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - startingIndex = defaultValue(startingIndex, 0); + result.x = Cartesian2.magnitude(Cartesian2.fromElements(matrix[0], matrix[1], scratchColumn)); + result.y = Cartesian2.magnitude(Cartesian2.fromElements(matrix[2], matrix[3], scratchColumn)); + return result; + }; - startingIndex = PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex); + var scratchScale = new Cartesian2(); - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + /** + * Computes the maximum scale assuming the matrix is an affine transformation. + * The maximum scale is the maximum length of the column vectors. + * + * @param {Matrix2} matrix The matrix. + * @returns {Number} The maximum scale. + */ + Matrix2.getMaximumScale = function(matrix) { + Matrix2.getScale(matrix, scratchScale); + return Cartesian2.maximumComponent(scratchScale); + }; - array[startingIndex++] = value._height; - array[startingIndex++] = value._extrudedHeight; - array[startingIndex++] = value._granularity; - array[startingIndex++] = value._extrude ? 1.0 : 0.0; - array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0; - array[startingIndex++] = value.packedLength; + /** + * Computes the product of two matrices. + * + * @param {Matrix2} left The first matrix. + * @param {Matrix2} right The second matrix. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. + */ + Matrix2.multiply = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + var column0Row0 = left[0] * right[0] + left[2] * right[1]; + var column1Row0 = left[0] * right[2] + left[2] * right[3]; + var column0Row1 = left[1] * right[0] + left[3] * right[1]; + var column1Row1 = left[1] * right[2] + left[3] * right[3]; - return array; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column1Row0; + result[3] = column1Row1; + return result; }; - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var dummyOptions = { - polygonHierarchy : {} + /** + * Computes the sum of two matrices. + * + * @param {Matrix2} left The first matrix. + * @param {Matrix2} right The second matrix. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. + */ + Matrix2.add = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); + + result[0] = left[0] + right[0]; + result[1] = left[1] + right[1]; + result[2] = left[2] + right[2]; + result[3] = left[3] + right[3]; + return result; }; /** - * Retrieves an instance from a packed array. + * Computes the difference of two matrices. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PolygonOutlineGeometry} [result] The object into which to store the result. - * @returns {PolygonOutlineGeometry} The modified result parameter or a new PolygonOutlineGeometry instance if one was not provided. + * @param {Matrix2} left The first matrix. + * @param {Matrix2} right The second matrix. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. */ - PolygonOutlineGeometry.unpack = function(array, startingIndex, result) { - Check.defined('array', array); + Matrix2.subtract = function(left, right, result) { + Check.typeOf.object('left', left); + Check.typeOf.object('right', right); + Check.typeOf.object('result', result); - startingIndex = defaultValue(startingIndex, 0); - - var polygonHierarchy = PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex); - startingIndex = polygonHierarchy.startingIndex; - delete polygonHierarchy.startingIndex; - - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; - - var height = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var granularity = array[startingIndex++]; - var extrude = array[startingIndex++] === 1.0; - var perPositionHeight = array[startingIndex++] === 1.0; - var packedLength = array[startingIndex++]; + result[0] = left[0] - right[0]; + result[1] = left[1] - right[1]; + result[2] = left[2] - right[2]; + result[3] = left[3] - right[3]; + return result; + }; - if (!defined(result)) { - result = new PolygonOutlineGeometry(dummyOptions); - } + /** + * Computes the product of a matrix and a column vector. + * + * @param {Matrix2} matrix The matrix. + * @param {Cartesian2} cartesian The column. + * @param {Cartesian2} result The object onto which to store the result. + * @returns {Cartesian2} The modified result parameter. + */ + Matrix2.multiplyByVector = function(matrix, cartesian, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('cartesian', cartesian); + Check.typeOf.object('result', result); + + var x = matrix[0] * cartesian.x + matrix[2] * cartesian.y; + var y = matrix[1] * cartesian.x + matrix[3] * cartesian.y; - result._polygonHierarchy = polygonHierarchy; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._height = height; - result._extrudedHeight = extrudedHeight; - result._granularity = granularity; - result._extrude = extrude; - result._perPositionHeight = perPositionHeight; - result.packedLength = packedLength; + result.x = x; + result.y = y; + return result; + }; + /** + * Computes the product of a matrix and a scalar. + * + * @param {Matrix2} matrix The matrix. + * @param {Number} scalar The number to multiply by. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. + */ + Matrix2.multiplyByScalar = function(matrix, scalar, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.number('scalar', scalar); + Check.typeOf.object('result', result); + + result[0] = matrix[0] * scalar; + result[1] = matrix[1] * scalar; + result[2] = matrix[2] * scalar; + result[3] = matrix[3] * scalar; return result; }; /** - * A description of a polygon outline from an array of positions. + * Computes the product of a matrix times a (non-uniform) scale, as if the scale were a scale matrix. * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. - * @param {Number} [options.height=0.0] The height of the polygon. - * @param {Number} [options.extrudedHeight] The height of the polygon extrusion. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. - * @returns {PolygonOutlineGeometry} + * @param {Matrix2} matrix The matrix on the left-hand side. + * @param {Cartesian2} scale The non-uniform scale on the right-hand side. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. * * * @example - * // create a polygon from points - * var polygon = Cesium.PolygonOutlineGeometry.fromPositions({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0, - * -75.0, 30.0, - * -70.0, 30.0, - * -68.0, 40.0 - * ]) - * }); - * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon); + * // Instead of Cesium.Matrix2.multiply(m, Cesium.Matrix2.fromScale(scale), m); + * Cesium.Matrix2.multiplyByScale(m, scale, m); * - * @see PolygonOutlineGeometry#createGeometry + * @see Matrix2.fromScale + * @see Matrix2.multiplyByUniformScale */ - PolygonOutlineGeometry.fromPositions = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Matrix2.multiplyByScale = function(matrix, scale, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('scale', scale); + Check.typeOf.object('result', result); + + result[0] = matrix[0] * scale.x; + result[1] = matrix[1] * scale.x; + result[2] = matrix[2] * scale.y; + result[3] = matrix[3] * scale.y; + return result; + }; - Check.defined('options.positions', options.positions); + /** + * Creates a negated copy of the provided matrix. + * + * @param {Matrix2} matrix The matrix to negate. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. + */ + Matrix2.negate = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); - var newOptions = { - polygonHierarchy : { - positions : options.positions - }, - height : options.height, - extrudedHeight : options.extrudedHeight, - ellipsoid : options.ellipsoid, - granularity : options.granularity, - perPositionHeight : options.perPositionHeight - }; - return new PolygonOutlineGeometry(newOptions); + result[0] = -matrix[0]; + result[1] = -matrix[1]; + result[2] = -matrix[2]; + result[3] = -matrix[3]; + return result; }; /** - * Computes the geometric representation of a polygon outline, including its vertices, indices, and a bounding sphere. + * Computes the transpose of the provided matrix. * - * @param {PolygonOutlineGeometry} polygonGeometry A description of the polygon outline. - * @returns {Geometry|undefined} The computed vertices and indices. + * @param {Matrix2} matrix The matrix to transpose. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. */ - PolygonOutlineGeometry.createGeometry = function(polygonGeometry) { - var ellipsoid = polygonGeometry._ellipsoid; - var granularity = polygonGeometry._granularity; - var height = polygonGeometry._height; - var extrudedHeight = polygonGeometry._extrudedHeight; - var extrude = polygonGeometry._extrude; - var polygonHierarchy = polygonGeometry._polygonHierarchy; - var perPositionHeight = polygonGeometry._perPositionHeight; + Matrix2.transpose = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); + + var column0Row0 = matrix[0]; + var column0Row1 = matrix[2]; + var column1Row0 = matrix[1]; + var column1Row1 = matrix[3]; - // create from a polygon hierarchy - // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf - var polygons = []; - var queue = new Queue(); - queue.enqueue(polygonHierarchy); - var i; - while (queue.length !== 0) { - var outerNode = queue.dequeue(); - var outerRing = outerNode.positions; - outerRing = arrayRemoveDuplicates(outerRing, Cartesian3.equalsEpsilon, true); - if (outerRing.length < 3) { - continue; - } + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column1Row0; + result[3] = column1Row1; + return result; + }; - var numChildren = outerNode.holes ? outerNode.holes.length : 0; - // The outer polygon contains inner polygons - for (i = 0; i < numChildren; i++) { - var hole = outerNode.holes[i]; - hole.positions = arrayRemoveDuplicates(hole.positions, Cartesian3.equalsEpsilon, true); - if (hole.positions.length < 3) { - continue; - } - polygons.push(hole.positions); + /** + * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements. + * + * @param {Matrix2} matrix The matrix with signed elements. + * @param {Matrix2} result The object onto which to store the result. + * @returns {Matrix2} The modified result parameter. + */ + Matrix2.abs = function(matrix, result) { + Check.typeOf.object('matrix', matrix); + Check.typeOf.object('result', result); + + result[0] = Math.abs(matrix[0]); + result[1] = Math.abs(matrix[1]); + result[2] = Math.abs(matrix[2]); + result[3] = Math.abs(matrix[3]); - var numGrandchildren = 0; - if (defined(hole.holes)) { - numGrandchildren = hole.holes.length; - } + return result; + }; - for ( var j = 0; j < numGrandchildren; j++) { - queue.enqueue(hole.holes[j]); - } - } + /** + * Compares the provided matrices componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Matrix2} [left] The first matrix. + * @param {Matrix2} [right] The second matrix. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + Matrix2.equals = function(left, right) { + return (left === right) || + (defined(left) && + defined(right) && + left[0] === right[0] && + left[1] === right[1] && + left[2] === right[2] && + left[3] === right[3]); + }; - polygons.push(outerRing); - } + /** + * @private + */ + Matrix2.equalsArray = function(matrix, array, offset) { + return matrix[0] === array[offset] && + matrix[1] === array[offset + 1] && + matrix[2] === array[offset + 2] && + matrix[3] === array[offset + 3]; + }; - if (polygons.length === 0) { - return undefined; - } + /** + * Compares the provided matrices componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Matrix2} [left] The first matrix. + * @param {Matrix2} [right] The second matrix. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + */ + Matrix2.equalsEpsilon = function(left, right, epsilon) { + Check.typeOf.number('epsilon', epsilon); + + return (left === right) || + (defined(left) && + defined(right) && + Math.abs(left[0] - right[0]) <= epsilon && + Math.abs(left[1] - right[1]) <= epsilon && + Math.abs(left[2] - right[2]) <= epsilon && + Math.abs(left[3] - right[3]) <= epsilon); + }; - var geometry; - var geometries = []; - var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + /** + * An immutable Matrix2 instance initialized to the identity matrix. + * + * @type {Matrix2} + * @constant + */ + Matrix2.IDENTITY = freezeObject(new Matrix2(1.0, 0.0, + 0.0, 1.0)); - if (extrude) { - for (i = 0; i < polygons.length; i++) { - geometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], minDistance, perPositionHeight); - geometry.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(geometry.geometry, height, extrudedHeight, ellipsoid, perPositionHeight); - geometries.push(geometry); - } - } else { - for (i = 0; i < polygons.length; i++) { - geometry = createGeometryFromPositions(ellipsoid, polygons[i], minDistance, perPositionHeight); - geometry.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); - geometries.push(geometry); + /** + * An immutable Matrix2 instance initialized to the zero matrix. + * + * @type {Matrix2} + * @constant + */ + Matrix2.ZERO = freezeObject(new Matrix2(0.0, 0.0, + 0.0, 0.0)); + + /** + * The index into Matrix2 for column 0, row 0. + * + * @type {Number} + * @constant + * + * @example + * var matrix = new Cesium.Matrix2(); + * matrix[Cesium.Matrix2.COLUMN0ROW0] = 5.0; // set column 0, row 0 to 5.0 + */ + Matrix2.COLUMN0ROW0 = 0; + + /** + * The index into Matrix2 for column 0, row 1. + * + * @type {Number} + * @constant + * + * @example + * var matrix = new Cesium.Matrix2(); + * matrix[Cesium.Matrix2.COLUMN0ROW1] = 5.0; // set column 0, row 1 to 5.0 + */ + Matrix2.COLUMN0ROW1 = 1; + + /** + * The index into Matrix2 for column 1, row 0. + * + * @type {Number} + * @constant + * + * @example + * var matrix = new Cesium.Matrix2(); + * matrix[Cesium.Matrix2.COLUMN1ROW0] = 5.0; // set column 1, row 0 to 5.0 + */ + Matrix2.COLUMN1ROW0 = 2; + + /** + * The index into Matrix2 for column 1, row 1. + * + * @type {Number} + * @constant + * + * @example + * var matrix = new Cesium.Matrix2(); + * matrix[Cesium.Matrix2.COLUMN1ROW1] = 5.0; // set column 1, row 1 to 5.0 + */ + Matrix2.COLUMN1ROW1 = 3; + + defineProperties(Matrix2.prototype, { + /** + * Gets the number of items in the collection. + * @memberof Matrix2.prototype + * + * @type {Number} + */ + length : { + get : function() { + return Matrix2.packedLength; } } + }); - geometry = GeometryPipeline.combineInstances(geometries)[0]; - var boundingSphere = BoundingSphere.fromVertices(geometry.attributes.position.values); + /** + * Duplicates the provided Matrix2 instance. + * + * @param {Matrix2} [result] The object onto which to store the result. + * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. + */ + Matrix2.prototype.clone = function(result) { + return Matrix2.clone(this, result); + }; - return new Geometry({ - attributes : geometry.attributes, - indices : geometry.indices, - primitiveType : geometry.primitiveType, - boundingSphere : boundingSphere - }); + /** + * Compares this matrix to the provided matrix componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Matrix2} [right] The right hand side matrix. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + Matrix2.prototype.equals = function(right) { + return Matrix2.equals(this, right); }; - return PolygonOutlineGeometry; + /** + * Compares this matrix to the provided matrix componentwise and returns + * <code>true</code> if they are within the provided epsilon, + * <code>false</code> otherwise. + * + * @param {Matrix2} [right] The right hand side matrix. + * @param {Number} epsilon The epsilon to use for equality testing. + * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + */ + Matrix2.prototype.equalsEpsilon = function(right, epsilon) { + return Matrix2.equalsEpsilon(this, right, epsilon); + }; + + /** + * Creates a string representing this Matrix with each row being + * on a separate line and in the format '(column0, column1)'. + * + * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1)'. + */ + Matrix2.prototype.toString = function() { + return '(' + this[0] + ', ' + this[2] + ')\n' + + '(' + this[1] + ', ' + this[3] + ')'; + }; + + return Matrix2; }); -define('Core/PolylineGeometry',[ - './arrayRemoveDuplicates', - './BoundingSphere', - './Cartesian3', - './Color', - './ComponentDatatype', - './defaultValue', +define('Core/mergeSort',[ './defined', - './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './GeometryType', - './IndexDatatype', - './Math', - './PolylinePipeline', - './PrimitiveType', - './VertexFormat' + './DeveloperError' ], function( - arrayRemoveDuplicates, - BoundingSphere, - Cartesian3, - Color, - ComponentDatatype, - defaultValue, defined, - DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - GeometryType, - IndexDatatype, - CesiumMath, - PolylinePipeline, - PrimitiveType, - VertexFormat) { + DeveloperError) { 'use strict'; - var scratchInterpolateColorsArray = []; + var leftScratchArray = []; + var rightScratchArray = []; + + function merge(array, compare, userDefinedObject, start, middle, end) { + var leftLength = middle - start + 1; + var rightLength = end - middle; + + var left = leftScratchArray; + var right = rightScratchArray; - function interpolateColors(p0, p1, color0, color1, numPoints) { - var colors = scratchInterpolateColorsArray; - colors.length = numPoints; var i; + var j; - var r0 = color0.red; - var g0 = color0.green; - var b0 = color0.blue; - var a0 = color0.alpha; + for (i = 0; i < leftLength; ++i) { + left[i] = array[start + i]; + } - var r1 = color1.red; - var g1 = color1.green; - var b1 = color1.blue; - var a1 = color1.alpha; + for (j = 0; j < rightLength; ++j) { + right[j] = array[middle + j + 1]; + } - if (Color.equals(color0, color1)) { - for (i = 0; i < numPoints; i++) { - colors[i] = Color.clone(color0); + i = 0; + j = 0; + for (var k = start; k <= end; ++k) { + var leftElement = left[i]; + var rightElement = right[j]; + if (i < leftLength && (j >= rightLength || compare(leftElement, rightElement, userDefinedObject) <= 0)) { + array[k] = leftElement; + ++i; + } else if (j < rightLength) { + array[k] = rightElement; + ++j; } - return colors; } + } - var redPerVertex = (r1 - r0) / numPoints; - var greenPerVertex = (g1 - g0) / numPoints; - var bluePerVertex = (b1 - b0) / numPoints; - var alphaPerVertex = (a1 - a0) / numPoints; - - for (i = 0; i < numPoints; i++) { - colors[i] = new Color(r0 + i * redPerVertex, g0 + i * greenPerVertex, b0 + i * bluePerVertex, a0 + i * alphaPerVertex); + function sort(array, compare, userDefinedObject, start, end) { + if (start >= end) { + return; } - return colors; + var middle = Math.floor((start + end) * 0.5); + sort(array, compare, userDefinedObject, start, middle); + sort(array, compare, userDefinedObject, middle + 1, end); + merge(array, compare, userDefinedObject, start, middle, end); } /** - * A description of a polyline modeled as a line strip; the first two positions define a line segment, - * and each additional position defines a line segment from the previous position. The polyline is capable of - * displaying with a material. - * - * @alias PolylineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of {@link Cartesian3} defining the positions in the polyline as a line strip. - * @param {Number} [options.width=1.0] The width in pixels. - * @param {Color[]} [options.colors] An Array of {@link Color} defining the per vertex or per segment colors. - * @param {Boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. - * @param {Boolean} [options.followSurface=true] A boolean that determines whether positions will be adjusted to the surface of the ellipsoid via a great arc. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.followSurface=true. Determines the number of positions in the buffer. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * - * @exception {DeveloperError} At least two positions are required. - * @exception {DeveloperError} width must be greater than or equal to one. - * @exception {DeveloperError} colors has an invalid length. + * A stable merge sort. * - * @see PolylineGeometry#createGeometry + * @exports mergeSort * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo} + * @param {Array} array The array to sort. + * @param {mergeSort~Comparator} comparator The function to use to compare elements in the array. + * @param {Object} [userDefinedObject] An object to pass as the third parameter to <code>comparator</code>. * * @example - * // A polyline with two connected line segments - * var polyline = new Cesium.PolylineGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * 0.0, 0.0, - * 5.0, 0.0, - * 5.0, 5.0 - * ]), - * width : 10.0 - * }); - * var geometry = Cesium.PolylineGeometry.createGeometry(polyline); + * // Assume array contains BoundingSpheres in world coordinates. + * // Sort them in ascending order of distance from the camera. + * var position = camera.positionWC; + * Cesium.mergeSort(array, function(a, b, position) { + * return Cesium.BoundingSphere.distanceSquaredTo(b, position) - Cesium.BoundingSphere.distanceSquaredTo(a, position); + * }, position); */ - function PolylineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.positions; - var colors = options.colors; - var width = defaultValue(options.width, 1.0); - var colorsPerVertex = defaultValue(options.colorsPerVertex, false); - - if ((!defined(positions)) || (positions.length < 2)) { - throw new DeveloperError('At least two positions are required.'); - } - if (typeof width !== 'number') { - throw new DeveloperError('width must be a number'); + function mergeSort(array, comparator, userDefinedObject) { + if (!defined(array)) { + throw new DeveloperError('array is required.'); } - if (defined(colors) && ((colorsPerVertex && colors.length < positions.length) || (!colorsPerVertex && colors.length < positions.length - 1))) { - throw new DeveloperError('colors has an invalid length.'); + if (!defined(comparator)) { + throw new DeveloperError('comparator is required.'); } - this._positions = positions; - this._colors = colors; - this._width = width; - this._colorsPerVertex = colorsPerVertex; - this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); - this._followSurface = defaultValue(options.followSurface, true); - this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); - this._workerName = 'createPolylineGeometry'; + var length = array.length; + var scratchLength = Math.ceil(length * 0.5); - var numComponents = 1 + positions.length * Cartesian3.packedLength; - numComponents += defined(colors) ? 1 + colors.length * Color.packedLength : 1; + // preallocate space in scratch arrays + leftScratchArray.length = scratchLength; + rightScratchArray.length = scratchLength; + + sort(array, comparator, userDefinedObject, 0, length - 1); + + // trim scratch arrays + leftScratchArray.length = 0; + rightScratchArray.length = 0; + } + + /** + * A function used to compare two items while performing a merge sort. + * @callback mergeSort~Comparator + * + * @param {Object} a An item in the array. + * @param {Object} b An item in the array. + * @param {Object} [userDefinedObject] An object that was passed to {@link mergeSort}. + * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, + * a positive value if <code>a</code> is greater than <code>b</code>, or + * 0 if <code>a</code> is equal to <code>b</code>. + * + * @example + * function compareNumbers(a, b, userDefinedObject) { + * return a - b; + * } + */ + + return mergeSort; +}); +define('Core/NearFarScalar',[ + './defaultValue', + './defined', + './DeveloperError' + ], function( + defaultValue, + defined, + DeveloperError) { + 'use strict'; + + /** + * Represents a scalar value's lower and upper bound at a near distance and far distance in eye space. + * @alias NearFarScalar + * @constructor + * + * @param {Number} [near=0.0] The lower bound of the camera range. + * @param {Number} [nearValue=0.0] The value at the lower bound of the camera range. + * @param {Number} [far=1.0] The upper bound of the camera range. + * @param {Number} [farValue=0.0] The value at the upper bound of the camera range. + * + * @see Packable + */ + function NearFarScalar(near, nearValue, far, farValue) { /** - * The number of elements used to pack the object into an array. + * The lower bound of the camera range. * @type {Number} + * @default 0.0 */ - this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 4; + this.near = defaultValue(near, 0.0); + /** + * The value at the lower bound of the camera range. + * @type {Number} + * @default 0.0 + */ + this.nearValue = defaultValue(nearValue, 0.0); + /** + * The upper bound of the camera range. + * @type {Number} + * @default 1.0 + */ + this.far = defaultValue(far, 1.0); + /** + * The value at the upper bound of the camera range. + * @type {Number} + * @default 0.0 + */ + this.farValue = defaultValue(farValue, 0.0); } + /** + * Duplicates a NearFarScalar instance. + * + * @param {NearFarScalar} nearFarScalar The NearFarScalar to duplicate. + * @param {NearFarScalar} [result] The object onto which to store the result. + * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. (Returns undefined if nearFarScalar is undefined) + */ + NearFarScalar.clone = function(nearFarScalar, result) { + if (!defined(nearFarScalar)) { + return undefined; + } + + if (!defined(result)) { + return new NearFarScalar(nearFarScalar.near, nearFarScalar.nearValue, nearFarScalar.far, nearFarScalar.farValue); + } + + result.near = nearFarScalar.near; + result.nearValue = nearFarScalar.nearValue; + result.far = nearFarScalar.far; + result.farValue = nearFarScalar.farValue; + return result; + }; + + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + NearFarScalar.packedLength = 4; + /** * Stores the provided instance into the provided array. * - * @param {PolylineGeometry} value The value to pack. + * @param {NearFarScalar} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - PolylineGeometry.pack = function(value, array, startingIndex) { + NearFarScalar.pack = function(value, array, startingIndex) { if (!defined(value)) { throw new DeveloperError('value is required'); } @@ -72967,4711 +70542,3870 @@ define('Core/PolylineGeometry',[ startingIndex = defaultValue(startingIndex, 0); - var i; - - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; - - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); - } - - var colors = value._colors; - length = defined(colors) ? colors.length : 0.0; - array[startingIndex++] = length; - - for (i = 0; i < length; ++i, startingIndex += Color.packedLength) { - Color.pack(colors[i], array, startingIndex); - } - - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; - - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - - array[startingIndex++] = value._width; - array[startingIndex++] = value._colorsPerVertex ? 1.0 : 0.0; - array[startingIndex++] = value._followSurface ? 1.0 : 0.0; - array[startingIndex] = value._granularity; + array[startingIndex++] = value.near; + array[startingIndex++] = value.nearValue; + array[startingIndex++] = value.far; + array[startingIndex] = value.farValue; return array; }; - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchVertexFormat = new VertexFormat(); - var scratchOptions = { - positions : undefined, - colors : undefined, - ellipsoid : scratchEllipsoid, - vertexFormat : scratchVertexFormat, - width : undefined, - colorsPerVertex : undefined, - followSurface : undefined, - granularity : undefined - }; - /** * Retrieves an instance from a packed array. * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PolylineGeometry} [result] The object into which to store the result. - * @returns {PolylineGeometry} The modified result parameter or a new PolylineGeometry instance if one was not provided. + * @param {NearFarScalar} [result] The object into which to store the result. + * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. */ - PolylineGeometry.unpack = function(array, startingIndex, result) { + NearFarScalar.unpack = function(array, startingIndex, result) { if (!defined(array)) { throw new DeveloperError('array is required'); } startingIndex = defaultValue(startingIndex, 0); - var i; - - var length = array[startingIndex++]; - var positions = new Array(length); - - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); - } - - length = array[startingIndex++]; - var colors = length > 0 ? new Array(length) : undefined; - - for (i = 0; i < length; ++i, startingIndex += Color.packedLength) { - colors[i] = Color.unpack(array, startingIndex); - } - - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; - - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; - - var width = array[startingIndex++]; - var colorsPerVertex = array[startingIndex++] === 1.0; - var followSurface = array[startingIndex++] === 1.0; - var granularity = array[startingIndex]; - if (!defined(result)) { - scratchOptions.positions = positions; - scratchOptions.colors = colors; - scratchOptions.width = width; - scratchOptions.colorsPerVertex = colorsPerVertex; - scratchOptions.followSurface = followSurface; - scratchOptions.granularity = granularity; - return new PolylineGeometry(scratchOptions); + result = new NearFarScalar(); } - - result._positions = positions; - result._colors = colors; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._width = width; - result._colorsPerVertex = colorsPerVertex; - result._followSurface = followSurface; - result._granularity = granularity; - + result.near = array[startingIndex++]; + result.nearValue = array[startingIndex++]; + result.far = array[startingIndex++]; + result.farValue = array[startingIndex]; return result; }; - var scratchCartesian3 = new Cartesian3(); - var scratchPosition = new Cartesian3(); - var scratchPrevPosition = new Cartesian3(); - var scratchNextPosition = new Cartesian3(); - /** - * Computes the geometric representation of a polyline, including its vertices, indices, and a bounding sphere. + * Compares the provided NearFarScalar and returns <code>true</code> if they are equal, + * <code>false</code> otherwise. * - * @param {PolylineGeometry} polylineGeometry A description of the polyline. - * @returns {Geometry|undefined} The computed vertices and indices. + * @param {NearFarScalar} [left] The first NearFarScalar. + * @param {NearFarScalar} [right] The second NearFarScalar. + * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. */ - PolylineGeometry.createGeometry = function(polylineGeometry) { - var width = polylineGeometry._width; - var vertexFormat = polylineGeometry._vertexFormat; - var colors = polylineGeometry._colors; - var colorsPerVertex = polylineGeometry._colorsPerVertex; - var followSurface = polylineGeometry._followSurface; - var granularity = polylineGeometry._granularity; - var ellipsoid = polylineGeometry._ellipsoid; - - var i; - var j; - var k; + NearFarScalar.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + (left.near === right.near) && + (left.nearValue === right.nearValue) && + (left.far === right.far) && + (left.farValue === right.farValue)); + }; - var positions = arrayRemoveDuplicates(polylineGeometry._positions, Cartesian3.equalsEpsilon); - var positionsLength = positions.length; + /** + * Duplicates this instance. + * + * @param {NearFarScalar} [result] The object onto which to store the result. + * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. + */ + NearFarScalar.prototype.clone = function(result) { + return NearFarScalar.clone(this, result); + }; - // A width of a pixel or less is not a valid geometry, but in order to support external data - // that may have errors we treat this as an empty geometry. - if (positionsLength < 2 || width <= 0.0) { - return undefined; - } + /** + * Compares this instance to the provided NearFarScalar and returns <code>true</code> if they are equal, + * <code>false</code> otherwise. + * + * @param {NearFarScalar} [right] The right hand side NearFarScalar. + * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. + */ + NearFarScalar.prototype.equals = function(right) { + return NearFarScalar.equals(this, right); + }; - if (followSurface) { - var heights = PolylinePipeline.extractHeights(positions, ellipsoid); - var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + return NearFarScalar; +}); - if (defined(colors)) { - var colorLength = 1; - for (i = 0; i < positionsLength - 1; ++i) { - colorLength += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance); - } +define('Core/Visibility',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; - var newColors = new Array(colorLength); - var newColorIndex = 0; + /** + * This enumerated type is used in determining to what extent an object, the occludee, + * is visible during horizon culling. An occluder may fully block an occludee, in which case + * it has no visibility, may partially block an occludee from view, or may not block it at all, + * leading to full visibility. + * + * @exports Visibility + */ + var Visibility = { + /** + * Represents that no part of an object is visible. + * + * @type {Number} + * @constant + */ + NONE : -1, - for (i = 0; i < positionsLength - 1; ++i) { - var p0 = positions[i]; - var p1 = positions[i+1]; - var c0 = colors[i]; + /** + * Represents that part, but not all, of an object is visible + * + * @type {Number} + * @constant + */ + PARTIAL : 0, - var numColors = PolylinePipeline.numberOfPoints(p0, p1, minDistance); - if (colorsPerVertex && i < colorLength) { - var c1 = colors[i+1]; - var interpolatedColors = interpolateColors(p0, p1, c0, c1, numColors); - var interpolatedColorsLength = interpolatedColors.length; - for (j = 0; j < interpolatedColorsLength; ++j) { - newColors[newColorIndex++] = interpolatedColors[j]; - } - } else { - for (j = 0; j < numColors; ++j) { - newColors[newColorIndex++] = Color.clone(c0); - } - } - } + /** + * Represents that an object is visible in its entirety. + * + * @type {Number} + * @constant + */ + FULL : 1 + }; - newColors[newColorIndex] = Color.clone(colors[colors.length-1]); - colors = newColors; + return freezeObject(Visibility); +}); - scratchInterpolateColorsArray.length = 0; - } +define('Core/Occluder',[ + './BoundingSphere', + './Cartesian3', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Ellipsoid', + './Math', + './Rectangle', + './Visibility' + ], function( + BoundingSphere, + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Ellipsoid, + CesiumMath, + Rectangle, + Visibility) { + 'use strict'; - positions = PolylinePipeline.generateCartesianArc({ - positions: positions, - minDistance: minDistance, - ellipsoid: ellipsoid, - height: heights - }); + /** + * Creates an Occluder derived from an object's position and radius, as well as the camera position. + * The occluder can be used to determine whether or not other objects are visible or hidden behind the + * visible horizon defined by the occluder and camera position. + * + * @alias Occluder + * + * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. + * @param {Cartesian3} cameraPosition The coordinate of the viewer/camera. + * + * @constructor + * + * @example + * // Construct an occluder one unit away from the origin with a radius of one. + * var cameraPosition = Cesium.Cartesian3.ZERO; + * var occluderBoundingSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1), 1); + * var occluder = new Cesium.Occluder(occluderBoundingSphere, cameraPosition); + */ + function Occluder(occluderBoundingSphere, cameraPosition) { + if (!defined(occluderBoundingSphere)) { + throw new DeveloperError('occluderBoundingSphere is required.'); + } + if (!defined(cameraPosition)) { + throw new DeveloperError('camera position is required.'); } + + this._occluderPosition = Cartesian3.clone(occluderBoundingSphere.center); + this._occluderRadius = occluderBoundingSphere.radius; - positionsLength = positions.length; - var size = positionsLength * 4.0 - 4.0; + this._horizonDistance = 0.0; + this._horizonPlaneNormal = undefined; + this._horizonPlanePosition = undefined; + this._cameraPosition = undefined; - var finalPositions = new Float64Array(size * 3); - var prevPositions = new Float64Array(size * 3); - var nextPositions = new Float64Array(size * 3); - var expandAndWidth = new Float32Array(size * 2); - var st = vertexFormat.st ? new Float32Array(size * 2) : undefined; - var finalColors = defined(colors) ? new Uint8Array(size * 4) : undefined; + // cameraPosition fills in the above values + this.cameraPosition = cameraPosition; + } - var positionIndex = 0; - var expandAndWidthIndex = 0; - var stIndex = 0; - var colorIndex = 0; - var position; + var scratchCartesian3 = new Cartesian3(); - for (j = 0; j < positionsLength; ++j) { - if (j === 0) { - position = scratchCartesian3; - Cartesian3.subtract(positions[0], positions[1], position); - Cartesian3.add(positions[0], position, position); - } else { - position = positions[j - 1]; + defineProperties(Occluder.prototype, { + /** + * The position of the occluder. + * @memberof Occluder.prototype + * @type {Cartesian3} + */ + position: { + get: function() { + return this._occluderPosition; } + }, - Cartesian3.clone(position, scratchPrevPosition); - Cartesian3.clone(positions[j], scratchPosition); - - if (j === positionsLength - 1) { - position = scratchCartesian3; - Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], position); - Cartesian3.add(positions[positionsLength - 1], position, position); - } else { - position = positions[j + 1]; + /** + * The radius of the occluder. + * @memberof Occluder.prototype + * @type {Number} + */ + radius: { + get: function() { + return this._occluderRadius; } + }, - Cartesian3.clone(position, scratchNextPosition); + /** + * The position of the camera. + * @memberof Occluder.prototype + * @type {Cartesian3} + */ + cameraPosition: { + set: function(cameraPosition) { + if (!defined(cameraPosition)) { + throw new DeveloperError('cameraPosition is required.'); + } + + cameraPosition = Cartesian3.clone(cameraPosition, this._cameraPosition); - var color0, color1; - if (defined(finalColors)) { - if (j !== 0 && !colorsPerVertex) { - color0 = colors[j - 1]; + var cameraToOccluderVec = Cartesian3.subtract(this._occluderPosition, cameraPosition, scratchCartesian3); + var invCameraToOccluderDistance = Cartesian3.magnitudeSquared(cameraToOccluderVec); + var occluderRadiusSqrd = this._occluderRadius * this._occluderRadius; + + var horizonDistance; + var horizonPlaneNormal; + var horizonPlanePosition; + if (invCameraToOccluderDistance > occluderRadiusSqrd) { + horizonDistance = Math.sqrt(invCameraToOccluderDistance - occluderRadiusSqrd); + invCameraToOccluderDistance = 1.0 / Math.sqrt(invCameraToOccluderDistance); + horizonPlaneNormal = Cartesian3.multiplyByScalar(cameraToOccluderVec, invCameraToOccluderDistance, scratchCartesian3); + var nearPlaneDistance = horizonDistance * horizonDistance * invCameraToOccluderDistance; + horizonPlanePosition = Cartesian3.add(cameraPosition, Cartesian3.multiplyByScalar(horizonPlaneNormal, nearPlaneDistance, scratchCartesian3), scratchCartesian3); } else { - color0 = colors[j]; + horizonDistance = Number.MAX_VALUE; } - if (j !== positionsLength - 1) { - color1 = colors[j]; - } + this._horizonDistance = horizonDistance; + this._horizonPlaneNormal = horizonPlaneNormal; + this._horizonPlanePosition = horizonPlanePosition; + this._cameraPosition = cameraPosition; } + } + }); - var startK = j === 0 ? 2 : 0; - var endK = j === positionsLength - 1 ? 2 : 4; + /** + * Creates an occluder from a bounding sphere and the camera position. + * + * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. + * @param {Cartesian3} cameraPosition The coordinate of the viewer/camera. + * @param {Occluder} [result] The object onto which to store the result. + * @returns {Occluder} The occluder derived from an object's position and radius, as well as the camera position. + */ + Occluder.fromBoundingSphere = function(occluderBoundingSphere, cameraPosition, result) { + if (!defined(occluderBoundingSphere)) { + throw new DeveloperError('occluderBoundingSphere is required.'); + } - for (k = startK; k < endK; ++k) { - Cartesian3.pack(scratchPosition, finalPositions, positionIndex); - Cartesian3.pack(scratchPrevPosition, prevPositions, positionIndex); - Cartesian3.pack(scratchNextPosition, nextPositions, positionIndex); - positionIndex += 3; + if (!defined(cameraPosition)) { + throw new DeveloperError('camera position is required.'); + } + + if (!defined(result)) { + return new Occluder(occluderBoundingSphere, cameraPosition); + } - var direction = (k - 2 < 0) ? -1.0 : 1.0; - expandAndWidth[expandAndWidthIndex++] = 2 * (k % 2) - 1; // expand direction - expandAndWidth[expandAndWidthIndex++] = direction * width; + Cartesian3.clone(occluderBoundingSphere.center, result._occluderPosition); + result._occluderRadius = occluderBoundingSphere.radius; + result.cameraPosition = cameraPosition; - if (vertexFormat.st) { - st[stIndex++] = j / (positionsLength - 1); - st[stIndex++] = Math.max(expandAndWidth[expandAndWidthIndex - 2], 0.0); - } + return result; + }; - if (defined(finalColors)) { - var color = (k < 2) ? color0 : color1; - finalColors[colorIndex++] = Color.floatToByte(color.red); - finalColors[colorIndex++] = Color.floatToByte(color.green); - finalColors[colorIndex++] = Color.floatToByte(color.blue); - finalColors[colorIndex++] = Color.floatToByte(color.alpha); - } + var tempVecScratch = new Cartesian3(); + + /** + * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder. + * + * @param {Cartesian3} occludee The point surrounding the occludee object. + * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * + * + * @example + * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); + * var littleSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1), 0.25); + * var occluder = new Cesium.Occluder(littleSphere, cameraPosition); + * var point = new Cesium.Cartesian3(0, 0, -3); + * occluder.isPointVisible(point); //returns true + * + * @see Occluder#computeVisibility + */ + Occluder.prototype.isPointVisible = function(occludee) { + if (this._horizonDistance !== Number.MAX_VALUE) { + var tempVec = Cartesian3.subtract(occludee, this._occluderPosition, tempVecScratch); + var temp = this._occluderRadius; + temp = Cartesian3.magnitudeSquared(tempVec) - (temp * temp); + if (temp > 0.0) { + temp = Math.sqrt(temp) + this._horizonDistance; + tempVec = Cartesian3.subtract(occludee, this._cameraPosition, tempVec); + return temp * temp > Cartesian3.magnitudeSquared(tempVec); } } + return false; + }; - var attributes = new GeometryAttributes(); - - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : finalPositions - }); - - attributes.prevPosition = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : prevPositions - }); - - attributes.nextPosition = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : nextPositions - }); + var occludeePositionScratch = new Cartesian3(); - attributes.expandAndWidth = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : expandAndWidth - }); - - if (vertexFormat.st) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : st - }); - } - - if (defined(finalColors)) { - attributes.color = new GeometryAttribute({ - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - componentsPerAttribute : 4, - values : finalColors, - normalize : true - }); - } - - var indices = IndexDatatype.createTypedArray(size, positionsLength * 6 - 6); - var index = 0; - var indicesIndex = 0; - var length = positionsLength - 1.0; - for (j = 0; j < length; ++j) { - indices[indicesIndex++] = index; - indices[indicesIndex++] = index + 2; - indices[indicesIndex++] = index + 1; - - indices[indicesIndex++] = index + 1; - indices[indicesIndex++] = index + 2; - indices[indicesIndex++] = index + 3; - - index += 4; - } - - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : BoundingSphere.fromPoints(positions), - geometryType : GeometryType.POLYLINES - }); - }; - - return PolylineGeometry; -}); - -define('Core/PolylineVolumeGeometry',[ - './arrayRemoveDuplicates', - './BoundingRectangle', - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './ComponentDatatype', - './CornerType', - './defaultValue', - './defined', - './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './GeometryPipeline', - './IndexDatatype', - './Math', - './oneTimeWarning', - './PolygonPipeline', - './PolylineVolumeGeometryLibrary', - './PrimitiveType', - './VertexFormat', - './WindingOrder' - ], function( - arrayRemoveDuplicates, - BoundingRectangle, - BoundingSphere, - Cartesian2, - Cartesian3, - ComponentDatatype, - CornerType, - defaultValue, - defined, - DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - GeometryPipeline, - IndexDatatype, - CesiumMath, - oneTimeWarning, - PolygonPipeline, - PolylineVolumeGeometryLibrary, - PrimitiveType, - VertexFormat, - WindingOrder) { - 'use strict'; - - function computeAttributes(combinedPositions, shape, boundingRectangle, vertexFormat) { - var attributes = new GeometryAttributes(); - if (vertexFormat.position) { - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : combinedPositions - }); - } - var shapeLength = shape.length; - var vertexCount = combinedPositions.length / 3; - var length = (vertexCount - shapeLength * 2) / (shapeLength * 2); - var firstEndIndices = PolygonPipeline.triangulate(shape); - - var indicesCount = (length - 1) * (shapeLength) * 6 + firstEndIndices.length * 2; - var indices = IndexDatatype.createTypedArray(vertexCount, indicesCount); - var i, j; - var ll, ul, ur, lr; - var offset = shapeLength * 2; - var index = 0; - for (i = 0; i < length - 1; i++) { - for (j = 0; j < shapeLength - 1; j++) { - ll = j * 2 + i * shapeLength * 2; - lr = ll + offset; - ul = ll + 1; - ur = ul + offset; - - indices[index++] = ul; - indices[index++] = ll; - indices[index++] = ur; - indices[index++] = ur; - indices[index++] = ll; - indices[index++] = lr; - } - ll = shapeLength * 2 - 2 + i * shapeLength * 2; - ul = ll + 1; - ur = ul + offset; - lr = ll + offset; - - indices[index++] = ul; - indices[index++] = ll; - indices[index++] = ur; - indices[index++] = ur; - indices[index++] = ll; - indices[index++] = lr; - } + /** + * Determines whether or not a sphere, the <code>occludee</code>, is hidden from view by the occluder. + * + * @param {BoundingSphere} occludee The bounding sphere surrounding the occludee object. + * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * + * + * @example + * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); + * var littleSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1), 0.25); + * var occluder = new Cesium.Occluder(littleSphere, cameraPosition); + * var bigSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -3), 1); + * occluder.isBoundingSphereVisible(bigSphere); //returns true + * + * @see Occluder#computeVisibility + */ + Occluder.prototype.isBoundingSphereVisible = function(occludee) { + var occludeePosition = Cartesian3.clone(occludee.center, occludeePositionScratch); + var occludeeRadius = occludee.radius; - if (vertexFormat.st || vertexFormat.tangent || vertexFormat.bitangent) { // st required for tangent/bitangent calculation - var st = new Float32Array(vertexCount * 2); - var lengthSt = 1 / (length - 1); - var heightSt = 1 / (boundingRectangle.height); - var heightOffset = boundingRectangle.height / 2; - var s, t; - var stindex = 0; - for (i = 0; i < length; i++) { - s = i * lengthSt; - t = heightSt * (shape[0].y + heightOffset); - st[stindex++] = s; - st[stindex++] = t; - for (j = 1; j < shapeLength; j++) { - t = heightSt * (shape[j].y + heightOffset); - st[stindex++] = s; - st[stindex++] = t; - st[stindex++] = s; - st[stindex++] = t; + if (this._horizonDistance !== Number.MAX_VALUE) { + var tempVec = Cartesian3.subtract(occludeePosition, this._occluderPosition, tempVecScratch); + var temp = this._occluderRadius - occludeeRadius; + temp = Cartesian3.magnitudeSquared(tempVec) - (temp * temp); + if (occludeeRadius < this._occluderRadius) { + if (temp > 0.0) { + temp = Math.sqrt(temp) + this._horizonDistance; + tempVec = Cartesian3.subtract(occludeePosition, this._cameraPosition, tempVec); + return ((temp * temp) + (occludeeRadius * occludeeRadius)) > Cartesian3.magnitudeSquared(tempVec); } - t = heightSt * (shape[0].y + heightOffset); - st[stindex++] = s; - st[stindex++] = t; - } - for (j = 0; j < shapeLength; j++) { - s = 0; - t = heightSt * (shape[j].y + heightOffset); - st[stindex++] = s; - st[stindex++] = t; - } - for (j = 0; j < shapeLength; j++) { - s = (length - 1) * lengthSt; - t = heightSt * (shape[j].y + heightOffset); - st[stindex++] = s; - st[stindex++] = t; + return false; } - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : new Float32Array(st) - }); - } - - var endOffset = vertexCount - shapeLength * 2; - for (i = 0; i < firstEndIndices.length; i += 3) { - var v0 = firstEndIndices[i] + endOffset; - var v1 = firstEndIndices[i + 1] + endOffset; - var v2 = firstEndIndices[i + 2] + endOffset; - - indices[index++] = v0; - indices[index++] = v1; - indices[index++] = v2; - indices[index++] = v2 + shapeLength; - indices[index++] = v1 + shapeLength; - indices[index++] = v0 + shapeLength; - } - - var geometry = new Geometry({ - attributes : attributes, - indices : indices, - boundingSphere : BoundingSphere.fromVertices(combinedPositions), - primitiveType : PrimitiveType.TRIANGLES - }); - - if (vertexFormat.normal) { - geometry = GeometryPipeline.computeNormal(geometry); - } - - if (vertexFormat.tangent || vertexFormat.bitangent) { - try { - geometry = GeometryPipeline.computeTangentAndBitangent(geometry); - } catch (e) { - oneTimeWarning('polyline-volume-tangent-bitangent', 'Unable to compute tangents and bitangents for polyline volume geometry'); - //TODO https://github.com/AnalyticalGraphicsInc/cesium/issues/3609 + // Prevent against the case where the occludee radius is larger than the occluder's; since this is + // an uncommon case, the following code should rarely execute. + if (temp > 0.0) { + tempVec = Cartesian3.subtract(occludeePosition, this._cameraPosition, tempVec); + var tempVecMagnitudeSquared = Cartesian3.magnitudeSquared(tempVec); + var occluderRadiusSquared = this._occluderRadius * this._occluderRadius; + var occludeeRadiusSquared = occludeeRadius * occludeeRadius; + if ((((this._horizonDistance * this._horizonDistance) + occluderRadiusSquared) * occludeeRadiusSquared) > + (tempVecMagnitudeSquared * occluderRadiusSquared)) { + // The occludee is close enough that the occluder cannot possible occlude the occludee + return true; + } + temp = Math.sqrt(temp) + this._horizonDistance; + return ((temp * temp) + occludeeRadiusSquared) > tempVecMagnitudeSquared; } - if (!vertexFormat.tangent) { - geometry.attributes.tangent = undefined; - } - if (!vertexFormat.bitangent) { - geometry.attributes.bitangent = undefined; - } - if (!vertexFormat.st) { - geometry.attributes.st = undefined; - } + // The occludee completely encompasses the occluder + return true; } - return geometry; - } + return false; + }; + var tempScratch = new Cartesian3(); /** - * A description of a polyline with a volume (a 2D shape extruded along a polyline). - * - * @alias PolylineVolumeGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.polylinePositions An array of {@link Cartesain3} positions that define the center of the polyline volume. - * @param {Cartesian2[]} options.shapePositions An array of {@link Cartesian2} positions that define the shape to be extruded along the polyline - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. + * Determine to what extent an occludee is visible (not visible, partially visible, or fully visible). * - * @see PolylineVolumeGeometry#createGeometry + * @param {BoundingSphere} occludeeBS The bounding sphere of the occludee. + * @returns {Number} Visibility.NONE if the occludee is not visible, + * Visibility.PARTIAL if the occludee is partially visible, or + * Visibility.FULL if the occludee is fully visible. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo} * * @example - * function computeCircle(radius) { - * var positions = []; - * for (var i = 0; i < 360; i++) { - * var radians = Cesium.Math.toRadians(i); - * positions.push(new Cesium.Cartesian2(radius * Math.cos(radians), radius * Math.sin(radians))); - * } - * return positions; - * } + * var sphere1 = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -1.5), 0.5); + * var sphere2 = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -2.5), 0.5); + * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); + * var occluder = new Cesium.Occluder(sphere1, cameraPosition); + * occluder.computeVisibility(sphere2); //returns Visibility.NONE * - * var volume = new Cesium.PolylineVolumeGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, - * polylinePositions : Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0 - * ]), - * shapePositions : computeCircle(100000.0) - * }); + * @see Occluder#isVisible */ - function PolylineVolumeGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.polylinePositions; - var shape = options.shapePositions; - - if (!defined(positions)) { - throw new DeveloperError('options.polylinePositions is required.'); - } - if (!defined(shape)) { - throw new DeveloperError('options.shapePositions is required.'); + Occluder.prototype.computeVisibility = function(occludeeBS) { + if (!defined(occludeeBS)) { + throw new DeveloperError('occludeeBS is required.'); } - this._positions = positions; - this._shape = shape; - this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); - this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); - this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); - this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._workerName = 'createPolylineVolumeGeometry'; + // If the occludee radius is larger than the occluders, this will return that + // the entire ocludee is visible, even though that may not be the case, though this should + // not occur too often. + var occludeePosition = Cartesian3.clone(occludeeBS.center); + var occludeeRadius = occludeeBS.radius; - var numComponents = 1 + positions.length * Cartesian3.packedLength; - numComponents += 1 + shape.length * Cartesian2.packedLength; + if (occludeeRadius > this._occluderRadius) { + return Visibility.FULL; + } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 2; - } + if (this._horizonDistance !== Number.MAX_VALUE) { + // The camera is outside the occluder + var tempVec = Cartesian3.subtract(occludeePosition, this._occluderPosition, tempScratch); + var temp = this._occluderRadius - occludeeRadius; + var occluderToOccludeeDistSqrd = Cartesian3.magnitudeSquared(tempVec); + temp = occluderToOccludeeDistSqrd - (temp * temp); + if (temp > 0.0) { + // The occludee is not completely inside the occluder + // Check to see if the occluder completely hides the occludee + temp = Math.sqrt(temp) + this._horizonDistance; + tempVec = Cartesian3.subtract(occludeePosition, this._cameraPosition, tempVec); + var cameraToOccludeeDistSqrd = Cartesian3.magnitudeSquared(tempVec); + if (((temp * temp) + (occludeeRadius * occludeeRadius)) < cameraToOccludeeDistSqrd) { + return Visibility.NONE; + } + + // Check to see whether the occluder is fully or partially visible + // when the occludee does not intersect the occluder + temp = this._occluderRadius + occludeeRadius; + temp = occluderToOccludeeDistSqrd - (temp * temp); + if (temp > 0.0) { + // The occludee does not intersect the occluder. + temp = Math.sqrt(temp) + this._horizonDistance; + return (cameraToOccludeeDistSqrd < ((temp * temp)) + (occludeeRadius * occludeeRadius)) ? Visibility.FULL : Visibility.PARTIAL; + } + + //Check to see if the occluder is fully or partially visible when the occludee DOES + //intersect the occluder + tempVec = Cartesian3.subtract(occludeePosition, this._horizonPlanePosition, tempVec); + return (Cartesian3.dot(tempVec, this._horizonPlaneNormal) > -occludeeRadius) ? Visibility.PARTIAL : Visibility.FULL; + } + } + return Visibility.NONE; + }; + var occludeePointScratch = new Cartesian3(); /** - * Stores the provided instance into the provided array. + * Computes a point that can be used as the occludee position to the visibility functions. + * Use a radius of zero for the occludee radius. Typically, a user computes a bounding sphere around + * an object that is used for visibility; however it is also possible to compute a point that if + * seen/not seen would also indicate if an object is visible/not visible. This function is better + * called for objects that do not move relative to the occluder and is large, such as a chunk of + * terrain. You are better off not calling this and using the object's bounding sphere for objects + * such as a satellite or ground vehicle. * - * @param {PolylineVolumeGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. + * @param {Cartesian3} occludeePosition The point where the occludee (bounding sphere of radius 0) is located. + * @param {Cartesian3[]} positions List of altitude points on the horizon near the surface of the occluder. + * @returns {Object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> + * which is a boolean value. * - * @returns {Number[]} The array that was packed into + * @exception {DeveloperError} <code>positions</code> must contain at least one element. + * @exception {DeveloperError} <code>occludeePosition</code> must have a value other than <code>occluderBoundingSphere.center</code>. + * + * @example + * var cameraPosition = new Cesium.Cartesian3(0, 0, 0); + * var occluderBoundingSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(0, 0, -8), 2); + * var occluder = new Cesium.Occluder(occluderBoundingSphere, cameraPosition); + * var positions = [new Cesium.Cartesian3(-0.25, 0, -5.3), new Cesium.Cartesian3(0.25, 0, -5.3)]; + * var tileOccluderSphere = Cesium.BoundingSphere.fromPoints(positions); + * var occludeePosition = tileOccluderSphere.center; + * var occludeePt = Cesium.Occluder.computeOccludeePoint(occluderBoundingSphere, occludeePosition, positions); */ - PolylineVolumeGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); + Occluder.computeOccludeePoint = function(occluderBoundingSphere, occludeePosition, positions) { + if (!defined(occluderBoundingSphere)) { + throw new DeveloperError('occluderBoundingSphere is required.'); } - if (!defined(array)) { - throw new DeveloperError('array is required'); + if (!defined(positions)) { + throw new DeveloperError('positions is required.'); + } + if (positions.length === 0) { + throw new DeveloperError('positions must contain at least one element'); } - startingIndex = defaultValue(startingIndex, 0); - - var i; - - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; + var occludeePos = Cartesian3.clone(occludeePosition); + var occluderPosition = Cartesian3.clone(occluderBoundingSphere.center); + var occluderRadius = occluderBoundingSphere.radius; + var numPositions = positions.length; - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); + if (Cartesian3.equals(occluderPosition, occludeePosition)) { + throw new DeveloperError('occludeePosition must be different than occluderBoundingSphere.center'); } + + // Compute a plane with a normal from the occluder to the occludee position. + var occluderPlaneNormal = Cartesian3.normalize(Cartesian3.subtract(occludeePos, occluderPosition, occludeePointScratch), occludeePointScratch); + var occluderPlaneD = -(Cartesian3.dot(occluderPlaneNormal, occluderPosition)); - var shape = value._shape; - length = shape.length; - array[startingIndex++] = length; - - for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { - Cartesian2.pack(shape[i], array, startingIndex); + //For each position, determine the horizon intersection. Choose the position and intersection + //that results in the greatest angle with the occcluder plane. + var aRotationVector = Occluder._anyRotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD); + var dot = Occluder._horizonToPlaneNormalDotProduct(occluderBoundingSphere, occluderPlaneNormal, occluderPlaneD, aRotationVector, positions[0]); + if (!dot) { + //The position is inside the mimimum radius, which is invalid + return undefined; + } + var tempDot; + for ( var i = 1; i < numPositions; ++i) { + tempDot = Occluder._horizonToPlaneNormalDotProduct(occluderBoundingSphere, occluderPlaneNormal, occluderPlaneD, aRotationVector, positions[i]); + if (!tempDot) { + //The position is inside the minimum radius, which is invalid + return undefined; + } + if (tempDot < dot) { + dot = tempDot; + } + } + //Verify that the dot is not near 90 degress + if (dot < 0.00174532836589830883577820272085) { + return undefined; } - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; - - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - - array[startingIndex++] = value._cornerType; - array[startingIndex] = value._granularity; - - return array; - }; - - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchVertexFormat = new VertexFormat(); - var scratchOptions = { - polylinePositions : undefined, - shapePositions : undefined, - ellipsoid : scratchEllipsoid, - vertexFormat : scratchVertexFormat, - cornerType : undefined, - granularity : undefined + var distance = occluderRadius / dot; + return Cartesian3.add(occluderPosition, Cartesian3.multiplyByScalar(occluderPlaneNormal, distance, occludeePointScratch), occludeePointScratch); }; + var computeOccludeePointFromRectangleScratch = []; /** - * Retrieves an instance from a packed array. + * Computes a point that can be used as the occludee position to the visibility functions from a rectangle. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PolylineVolumeGeometry} [result] The object into which to store the result. - * @returns {PolylineVolumeGeometry} The modified result parameter or a new PolylineVolumeGeometry instance if one was not provided. + * @param {Rectangle} rectangle The rectangle used to create a bounding sphere. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle. + * @returns {Object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> + * which is a boolean value. */ - PolylineVolumeGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + Occluder.computeOccludeePointFromRectangle = function(rectangle, ellipsoid) { + if (!defined(rectangle)) { + throw new DeveloperError('rectangle is required.'); } - startingIndex = defaultValue(startingIndex, 0); - - var i; - - var length = array[startingIndex++]; - var positions = new Array(length); + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + var positions = Rectangle.subsample(rectangle, ellipsoid, 0.0, computeOccludeePointFromRectangleScratch); + var bs = BoundingSphere.fromPoints(positions); - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); + // TODO: get correct ellipsoid center + var ellipsoidCenter = Cartesian3.ZERO; + if (!Cartesian3.equals(ellipsoidCenter, bs.center)) { + return Occluder.computeOccludeePoint(new BoundingSphere(ellipsoidCenter, ellipsoid.minimumRadius), bs.center, positions); } - length = array[startingIndex++]; - var shape = new Array(length); + return undefined; + }; - for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { - shape[i] = Cartesian2.unpack(array, startingIndex); + var tempVec0Scratch = new Cartesian3(); + Occluder._anyRotationVector = function(occluderPosition, occluderPlaneNormal, occluderPlaneD) { + var tempVec0 = Cartesian3.abs(occluderPlaneNormal, tempVec0Scratch); + var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1; + if (((majorAxis === 0) && (tempVec0.z > tempVec0.x)) || ((majorAxis === 1) && (tempVec0.z > tempVec0.y))) { + majorAxis = 2; } + var tempVec = new Cartesian3(); + var tempVec1; + if (majorAxis === 0) { + tempVec0.x = occluderPosition.x; + tempVec0.y = occluderPosition.y + 1.0; + tempVec0.z = occluderPosition.z + 1.0; + tempVec1 = Cartesian3.UNIT_X; + } else if (majorAxis === 1) { + tempVec0.x = occluderPosition.x + 1.0; + tempVec0.y = occluderPosition.y; + tempVec0.z = occluderPosition.z + 1.0; + tempVec1 = Cartesian3.UNIT_Y; + } else { + tempVec0.x = occluderPosition.x + 1.0; + tempVec0.y = occluderPosition.y + 1.0; + tempVec0.z = occluderPosition.z; + tempVec1 = Cartesian3.UNIT_Z; + } + var u = (Cartesian3.dot(occluderPlaneNormal, tempVec0) + occluderPlaneD) / -(Cartesian3.dot(occluderPlaneNormal, tempVec1)); + return Cartesian3.normalize(Cartesian3.subtract(Cartesian3.add(tempVec0, Cartesian3.multiplyByScalar(tempVec1, u, tempVec), tempVec0), occluderPosition, tempVec0), tempVec0); + }; - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; - - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + var posDirectionScratch = new Cartesian3(); + Occluder._rotationVector = function(occluderPosition, occluderPlaneNormal, occluderPlaneD, position, anyRotationVector) { + //Determine the angle between the occluder plane normal and the position direction + var positionDirection = Cartesian3.subtract(position, occluderPosition, posDirectionScratch); + positionDirection = Cartesian3.normalize(positionDirection, positionDirection); + if (Cartesian3.dot(occluderPlaneNormal, positionDirection) < 0.99999998476912904932780850903444) { + var crossProduct = Cartesian3.cross(occluderPlaneNormal, positionDirection, positionDirection); + var length = Cartesian3.magnitude(crossProduct); + if (length > CesiumMath.EPSILON13) { + return Cartesian3.normalize(crossProduct, new Cartesian3()); + } + } + //The occluder plane normal and the position direction are colinear. Use any + //vector in the occluder plane as the rotation vector + return anyRotationVector; + }; - var cornerType = array[startingIndex++]; - var granularity = array[startingIndex]; + var posScratch1 = new Cartesian3(); + var occluerPosScratch = new Cartesian3(); + var posScratch2 = new Cartesian3(); + var horizonPlanePosScratch = new Cartesian3(); + Occluder._horizonToPlaneNormalDotProduct = function(occluderBS, occluderPlaneNormal, occluderPlaneD, anyRotationVector, position) { + var pos = Cartesian3.clone(position, posScratch1); + var occluderPosition = Cartesian3.clone(occluderBS.center, occluerPosScratch); + var occluderRadius = occluderBS.radius; - if (!defined(result)) { - scratchOptions.polylinePositions = positions; - scratchOptions.shapePositions = shape; - scratchOptions.cornerType = cornerType; - scratchOptions.granularity = granularity; - return new PolylineVolumeGeometry(scratchOptions); + //Verify that the position is outside the occluder + var positionToOccluder = Cartesian3.subtract(occluderPosition, pos, posScratch2); + var occluderToPositionDistanceSquared = Cartesian3.magnitudeSquared(positionToOccluder); + var occluderRadiusSquared = occluderRadius * occluderRadius; + if (occluderToPositionDistanceSquared < occluderRadiusSquared) { + return false; } - result._positions = positions; - result._shape = shape; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._cornerType = cornerType; - result._granularity = granularity; + //Horizon parameters + var horizonDistanceSquared = occluderToPositionDistanceSquared - occluderRadiusSquared; + var horizonDistance = Math.sqrt(horizonDistanceSquared); + var occluderToPositionDistance = Math.sqrt(occluderToPositionDistanceSquared); + var invOccluderToPositionDistance = 1.0 / occluderToPositionDistance; + var cosTheta = horizonDistance * invOccluderToPositionDistance; + var horizonPlaneDistance = cosTheta * horizonDistance; + positionToOccluder = Cartesian3.normalize(positionToOccluder, positionToOccluder); + var horizonPlanePosition = Cartesian3.add(pos, Cartesian3.multiplyByScalar(positionToOccluder, horizonPlaneDistance, horizonPlanePosScratch), horizonPlanePosScratch); + var horizonCrossDistance = Math.sqrt(horizonDistanceSquared - (horizonPlaneDistance * horizonPlaneDistance)); - return result; + //Rotate the position to occluder vector 90 degrees + var tempVec = this._rotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD, pos, anyRotationVector); + var horizonCrossDirection = Cartesian3.fromElements( + (tempVec.x * tempVec.x * positionToOccluder.x) + ((tempVec.x * tempVec.y - tempVec.z) * positionToOccluder.y) + ((tempVec.x * tempVec.z + tempVec.y) * positionToOccluder.z), + ((tempVec.x * tempVec.y + tempVec.z) * positionToOccluder.x) + (tempVec.y * tempVec.y * positionToOccluder.y) + ((tempVec.y * tempVec.z - tempVec.x) * positionToOccluder.z), + ((tempVec.x * tempVec.z - tempVec.y) * positionToOccluder.x) + ((tempVec.y * tempVec.z + tempVec.x) * positionToOccluder.y) + (tempVec.z * tempVec.z * positionToOccluder.z), + posScratch1); + horizonCrossDirection = Cartesian3.normalize(horizonCrossDirection, horizonCrossDirection); + + //Horizon positions + var offset = Cartesian3.multiplyByScalar(horizonCrossDirection, horizonCrossDistance, posScratch1); + tempVec = Cartesian3.normalize(Cartesian3.subtract(Cartesian3.add(horizonPlanePosition, offset, posScratch2), occluderPosition, posScratch2), posScratch2); + var dot0 = Cartesian3.dot(occluderPlaneNormal, tempVec); + tempVec = Cartesian3.normalize(Cartesian3.subtract(Cartesian3.subtract(horizonPlanePosition, offset, tempVec), occluderPosition, tempVec), tempVec); + var dot1 = Cartesian3.dot(occluderPlaneNormal, tempVec); + return (dot0 < dot1) ? dot0 : dot1; }; - var brScratch = new BoundingRectangle(); + return Occluder; +}); + +define('Core/Packable',[ + './DeveloperError' + ], function( + DeveloperError) { + 'use strict'; /** - * Computes the geometric representation of a polyline with a volume, including its vertices, indices, and a bounding sphere. + * Static interface for types which can store their values as packed + * elements in an array. These methods and properties are expected to be + * defined on a constructor function. * - * @param {PolylineVolumeGeometry} polylineVolumeGeometry A description of the polyline volume. - * @returns {Geometry|undefined} The computed vertices and indices. + * @exports Packable + * + * @see PackableForInterpolation */ - PolylineVolumeGeometry.createGeometry = function(polylineVolumeGeometry) { - var positions = polylineVolumeGeometry._positions; - var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - var shape2D = polylineVolumeGeometry._shape; - shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D); - - if (cleanPositions.length < 2 || shape2D.length < 3) { - return undefined; - } + var Packable = { + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + packedLength : undefined, - if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) { - shape2D.reverse(); - } - var boundingRectangle = BoundingRectangle.fromPoints(shape2D, brScratch); + /** + * Stores the provided instance into the provided array. + * @function + * + * @param {Object} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + */ + pack : DeveloperError.throwInstantiationError, - var computedPositions = PolylineVolumeGeometryLibrary.computePositions(cleanPositions, shape2D, boundingRectangle, polylineVolumeGeometry, true); - return computeAttributes(computedPositions, shape2D, boundingRectangle, polylineVolumeGeometry._vertexFormat); + /** + * Retrieves an instance from a packed array. + * @function + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Object} [result] The object into which to store the result. + * @returns {Object} The modified result parameter or a new Object instance if one was not provided. + */ + unpack : DeveloperError.throwInstantiationError }; - return PolylineVolumeGeometry; + return Packable; }); -define('Core/PolylineVolumeOutlineGeometry',[ - './arrayRemoveDuplicates', - './BoundingRectangle', - './BoundingSphere', - './Cartesian2', - './Cartesian3', - './ComponentDatatype', - './CornerType', - './defaultValue', - './defined', - './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PolygonPipeline', - './PolylineVolumeGeometryLibrary', - './PrimitiveType', - './WindingOrder' +define('Core/PackableForInterpolation',[ + './DeveloperError' ], function( - arrayRemoveDuplicates, - BoundingRectangle, - BoundingSphere, - Cartesian2, - Cartesian3, - ComponentDatatype, - CornerType, - defaultValue, - defined, - DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PolygonPipeline, - PolylineVolumeGeometryLibrary, - PrimitiveType, - WindingOrder) { + DeveloperError) { 'use strict'; - function computeAttributes(positions, shape) { - var attributes = new GeometryAttributes(); - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - - var shapeLength = shape.length; - var vertexCount = attributes.position.values.length / 3; - var positionLength = positions.length / 3; - var shapeCount = positionLength / shapeLength; - var indices = IndexDatatype.createTypedArray(vertexCount, 2 * shapeLength * (shapeCount + 1)); - var i, j; - var index = 0; - i = 0; - var offset = i * shapeLength; - for (j = 0; j < shapeLength - 1; j++) { - indices[index++] = j + offset; - indices[index++] = j + offset + 1; - } - indices[index++] = shapeLength - 1 + offset; - indices[index++] = offset; - - i = shapeCount - 1; - offset = i * shapeLength; - for (j = 0; j < shapeLength - 1; j++) { - indices[index++] = j + offset; - indices[index++] = j + offset + 1; - } - indices[index++] = shapeLength - 1 + offset; - indices[index++] = offset; - - for (i = 0; i < shapeCount - 1; i++) { - var firstOffset = shapeLength * i; - var secondOffset = firstOffset + shapeLength; - for (j = 0; j < shapeLength; j++) { - indices[index++] = j + firstOffset; - indices[index++] = j + secondOffset; - } - } - - var geometry = new Geometry({ - attributes : attributes, - indices : IndexDatatype.createTypedArray(vertexCount, indices), - boundingSphere : BoundingSphere.fromVertices(positions), - primitiveType : PrimitiveType.LINES - }); - - return geometry; - } - /** - * A description of a polyline with a volume (a 2D shape extruded along a polyline). - * - * @alias PolylineVolumeOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.polylinePositions An array of positions that define the center of the polyline volume. - * @param {Cartesian2[]} options.shapePositions An array of positions that define the shape to be extruded along the polyline - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. - * - * @see PolylineVolumeOutlineGeometry#createGeometry + * Static interface for {@link Packable} types which are interpolated in a + * different representation than their packed value. These methods and + * properties are expected to be defined on a constructor function. * - * @example - * function computeCircle(radius) { - * var positions = []; - * for (var i = 0; i < 360; i++) { - * var radians = Cesium.Math.toRadians(i); - * positions.push(new Cesium.Cartesian2(radius * Math.cos(radians), radius * Math.sin(radians))); - * } - * return positions; - * } + * @exports PackableForInterpolation * - * var volumeOutline = new Cesium.PolylineVolumeOutlineGeometry({ - * polylinePositions : Cesium.Cartesian3.fromDegreesArray([ - * -72.0, 40.0, - * -70.0, 35.0 - * ]), - * shapePositions : computeCircle(100000.0) - * }); + * @see Packable */ - function PolylineVolumeOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.polylinePositions; - var shape = options.shapePositions; - - if (!defined(positions)) { - throw new DeveloperError('options.polylinePositions is required.'); - } - if (!defined(shape)) { - throw new DeveloperError('options.shapePositions is required.'); - } - - this._positions = positions; - this._shape = shape; - this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); - this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); - this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._workerName = 'createPolylineVolumeOutlineGeometry'; - - var numComponents = 1 + positions.length * Cartesian3.packedLength; - numComponents += 1 + shape.length * Cartesian2.packedLength; - + var PackableForInterpolation = { /** - * The number of elements used to pack the object into an array. + * The number of elements used to store the object into an array in its interpolatable form. * @type {Number} */ - this.packedLength = numComponents + Ellipsoid.packedLength + 2; - } + packedInterpolationLength : undefined, - /** - * Stores the provided instance into the provided array. - * - * @param {PolylineVolumeOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - PolylineVolumeOutlineGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + /** + * Converts a packed array into a form suitable for interpolation. + * @function + * + * @param {Number[]} packedArray The packed array. + * @param {Number} [startingIndex=0] The index of the first element to be converted. + * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. + * @param {Number[]} result The object into which to store the result. + */ + convertPackedArrayForInterpolation : DeveloperError.throwInstantiationError, - var i; + /** + * Retrieves an instance from a packed array converted with {@link PackableForInterpolation.convertPackedArrayForInterpolation}. + * @function + * + * @param {Number[]} array The array previously packed for interpolation. + * @param {Number[]} sourceArray The original packed array. + * @param {Number} [startingIndex=0] The startingIndex used to convert the array. + * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. + * @param {Object} [result] The object into which to store the result. + * @returns {Object} The modified result parameter or a new Object instance if one was not provided. + */ + unpackInterpolationResult : DeveloperError.throwInstantiationError + }; - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; + return PackableForInterpolation; +}); - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); - } +/* + This library rewrites the Canvas2D "measureText" function + so that it returns a more complete metrics object. - var shape = value._shape; - length = shape.length; - array[startingIndex++] = length; +** ----------------------------------------------------------------------------- - for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { - Cartesian2.pack(shape[i], array, startingIndex); - } + CHANGELOG: - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + 2012-01-21 - Whitespace handling added by Joe Turner + (https://github.com/oampo) - array[startingIndex++] = value._cornerType; - array[startingIndex] = value._granularity; +** ----------------------------------------------------------------------------- +*/ +/** + @license + fontmetrics.js - https://github.com/Pomax/fontmetrics.js - return array; - }; + Copyright (C) 2011 by Mike "Pomax" Kamermans - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchOptions = { - polylinePositions : undefined, - shapePositions : undefined, - ellipsoid : scratchEllipsoid, - height : undefined, - cornerType : undefined, - granularity : undefined - }; + 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: - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {PolylineVolumeOutlineGeometry} [result] The object into which to store the result. - * @returns {PolylineVolumeOutlineGeometry} The modified result parameter or a new PolylineVolumeOutlineGeometry instance if one was not provided. - */ - PolylineVolumeOutlineGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. - var i; + 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. +**/ +define('ThirdParty/measureText',[],function() { + /*jshint strict:false*/ +/* + var NAME = "FontMetrics Library" + var VERSION = "1-2012.0121.1300"; - var length = array[startingIndex++]; - var positions = new Array(length); + // if there is no getComputedStyle, this library won't work. + if(!document.defaultView.getComputedStyle) { + throw("ERROR: 'document.defaultView.getComputedStyle' not found. This library only works in browsers that can report computed CSS values."); + } - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); - } + // store the old text metrics function on the Canvas2D prototype + CanvasRenderingContext2D.prototype.measureTextWidth = CanvasRenderingContext2D.prototype.measureText; +*/ + /** + * shortcut function for getting computed CSS values + */ + var getCSSValue = function(element, property) { + return document.defaultView.getComputedStyle(element,null).getPropertyValue(property); + }; +/* + // debug function + var show = function(canvas, ctx, xstart, w, h, metrics) + { + document.body.appendChild(canvas); + ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; - length = array[startingIndex++]; - var shape = new Array(length); + ctx.beginPath(); + ctx.moveTo(xstart,0); + ctx.lineTo(xstart,h); + ctx.closePath(); + ctx.stroke(); - for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { - shape[i] = Cartesian2.unpack(array, startingIndex); - } + ctx.beginPath(); + ctx.moveTo(xstart+metrics.bounds.maxx,0); + ctx.lineTo(xstart+metrics.bounds.maxx,h); + ctx.closePath(); + ctx.stroke(); - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + ctx.beginPath(); + ctx.moveTo(0,h/2-metrics.ascent); + ctx.lineTo(w,h/2-metrics.ascent); + ctx.closePath(); + ctx.stroke(); - var cornerType = array[startingIndex++]; - var granularity = array[startingIndex]; + ctx.beginPath(); + ctx.moveTo(0,h/2+metrics.descent); + ctx.lineTo(w,h/2+metrics.descent); + ctx.closePath(); + ctx.stroke(); + } +*/ + /** + * The new text metrics function + */ + var measureText = function(context2D, textstring, stroke, fill) { + var metrics = context2D.measureText(textstring), + fontFamily = getCSSValue(context2D.canvas,"font-family"), + fontSize = getCSSValue(context2D.canvas,"font-size").replace("px",""), + fontStyle = getCSSValue(context2D.canvas,"font-style"), + fontWeight = getCSSValue(context2D.canvas,"font-weight"), + isSpace = !(/\S/.test(textstring)); + metrics.fontsize = fontSize; - if (!defined(result)) { - scratchOptions.polylinePositions = positions; - scratchOptions.shapePositions = shape; - scratchOptions.cornerType = cornerType; - scratchOptions.granularity = granularity; - return new PolylineVolumeOutlineGeometry(scratchOptions); - } + // for text lead values, we meaure a multiline text container. + var leadDiv = document.createElement("div"); + leadDiv.style.position = "absolute"; + leadDiv.style.opacity = 0; + leadDiv.style.font = fontStyle + " " + fontWeight + " " + fontSize + "px " + fontFamily; + leadDiv.innerHTML = textstring + "<br/>" + textstring; + document.body.appendChild(leadDiv); - result._positions = positions; - result._shape = shape; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._cornerType = cornerType; - result._granularity = granularity; + // make some initial guess at the text leading (using the standard TeX ratio) + metrics.leading = 1.2 * fontSize; - return result; - }; + // then we try to get the real value from the browser + var leadDivHeight = getCSSValue(leadDiv,"height"); + leadDivHeight = leadDivHeight.replace("px",""); + if (leadDivHeight >= fontSize * 2) { metrics.leading = (leadDivHeight/2) | 0; } + document.body.removeChild(leadDiv); - var brScratch = new BoundingRectangle(); + // if we're not dealing with white space, we can compute metrics + if (!isSpace) { + // Have characters, so measure the text + var canvas = document.createElement("canvas"); + var padding = 100; + canvas.width = metrics.width + padding; + canvas.height = 3*fontSize; + canvas.style.opacity = 1; + canvas.style.fontFamily = fontFamily; + canvas.style.fontSize = fontSize; + canvas.style.fontStyle = fontStyle; + canvas.style.fontWeight = fontWeight; + var ctx = canvas.getContext("2d"); + ctx.font = fontStyle + " " + fontWeight + " " + fontSize + "px " + fontFamily; - /** - * Computes the geometric representation of the outline of a polyline with a volume, including its vertices, indices, and a bounding sphere. - * - * @param {PolylineVolumeOutlineGeometry} polylineVolumeOutlineGeometry A description of the polyline volume outline. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - PolylineVolumeOutlineGeometry.createGeometry = function(polylineVolumeOutlineGeometry) { - var positions = polylineVolumeOutlineGeometry._positions; - var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - var shape2D = polylineVolumeOutlineGeometry._shape; - shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D); + var w = canvas.width, + h = canvas.height, + baseline = h/2; - if (cleanPositions.length < 2 || shape2D.length < 3) { - return undefined; + // Set all canvas pixeldata values to 255, with all the content + // data being 0. This lets us scan for data[i] != 255. + ctx.fillStyle = "white"; + ctx.fillRect(-1, -1, w + 2, h + 2); + + if (stroke) { + ctx.strokeStyle = "black"; + ctx.lineWidth = context2D.lineWidth; + ctx.strokeText(textstring, (padding / 2), baseline); } - if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) { - shape2D.reverse(); + if (fill) { + ctx.fillStyle = "black"; + ctx.fillText(textstring, padding / 2, baseline); } - var boundingRectangle = BoundingRectangle.fromPoints(shape2D, brScratch); - var computedPositions = PolylineVolumeGeometryLibrary.computePositions(cleanPositions, shape2D, boundingRectangle, polylineVolumeOutlineGeometry, false); - return computeAttributes(computedPositions, shape2D); - }; + var pixelData = ctx.getImageData(0, 0, w, h).data; - return PolylineVolumeOutlineGeometry; + // canvas pixel data is w*4 by h*4, because R, G, B and A are separate, + // consecutive values in the array, rather than stored as 32 bit ints. + var i = 0, + w4 = w * 4, + len = pixelData.length; + + // Finding the ascent uses a normal, forward scanline + while (++i < len && pixelData[i] === 255) {} + var ascent = (i/w4)|0; + + // Finding the descent uses a reverse scanline + i = len - 1; + while (--i > 0 && pixelData[i] === 255) {} + var descent = (i/w4)|0; + + // find the min-x coordinate + for(i = 0; i<len && pixelData[i] === 255; ) { + i += w4; + if(i>=len) { i = (i-len) + 4; }} + var minx = ((i%w4)/4) | 0; + + // find the max-x coordinate + var step = 1; + for(i = len-3; i>=0 && pixelData[i] === 255; ) { + i -= w4; + if(i<0) { i = (len - 3) - (step++)*4; }} + var maxx = ((i%w4)/4) + 1 | 0; + + // set font metrics + metrics.ascent = (baseline - ascent); + metrics.descent = (descent - baseline); + metrics.bounds = { minx: minx - (padding/2), + maxx: maxx - (padding/2), + miny: 0, + maxy: descent-ascent }; + metrics.height = 1+(descent - ascent); + } + + // if we ARE dealing with whitespace, most values will just be zero. + else { + // Only whitespace, so we can't measure the text + metrics.ascent = 0; + metrics.descent = 0; + metrics.bounds = { minx: 0, + maxx: metrics.width, // Best guess + miny: 0, + maxy: 0 }; + metrics.height = 0; + } + return metrics; + }; + + return measureText; }); -define('Core/QuaternionSpline',[ +define('Core/writeTextToCanvas',[ + '../ThirdParty/measureText', + './Color', './defaultValue', './defined', - './defineProperties', - './DeveloperError', - './Quaternion', - './Spline' + './DeveloperError' ], function( + measureText, + Color, defaultValue, defined, - defineProperties, - DeveloperError, - Quaternion, - Spline) { + DeveloperError) { 'use strict'; - function computeInnerQuadrangles(points, firstInnerQuadrangle, lastInnerQuadrangle) { - var length = points.length; - var quads = new Array(length); + var imageSmoothingEnabledName; + + /** + * Writes the given text into a new canvas. The canvas will be sized to fit the text. + * If text is blank, returns undefined. + * + * @param {String} text The text to write. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.font='10px sans-serif'] The CSS font to use. + * @param {String} [options.textBaseline='bottom'] The baseline of the text. + * @param {Boolean} [options.fill=true] Whether to fill the text. + * @param {Boolean} [options.stroke=false] Whether to stroke the text. + * @param {Color} [options.fillColor=Color.WHITE] The fill color. + * @param {Color} [options.strokeColor=Color.BLACK] The stroke color. + * @param {Number} [options.strokeWidth=1] The stroke width. + * @param {Color} [options.backgroundColor=Color.TRANSPARENT] The background color of the canvas. + * @param {Number} [options.padding=0] The pixel size of the padding to add around the text. + * @returns {Canvas} A new canvas with the given text drawn into it. The dimensions object + * from measureText will also be added to the returned canvas. If text is + * blank, returns undefined. + */ + function writeTextToCanvas(text, options) { + if (!defined(text)) { + throw new DeveloperError('text is required.'); + } + if (text === '') { + return undefined; + } + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var font = defaultValue(options.font, '10px sans-serif'); + var stroke = defaultValue(options.stroke, false); + var fill = defaultValue(options.fill, true); + var strokeWidth = defaultValue(options.strokeWidth, 1); + var backgroundColor = defaultValue(options.backgroundColor, Color.TRANSPARENT); + var padding = defaultValue(options.padding, 0); + var doublePadding = padding * 2.0; + + var canvas = document.createElement('canvas'); + canvas.width = 1; + canvas.height = 1; + canvas.style.font = font; - quads[0] = defined(firstInnerQuadrangle) ? firstInnerQuadrangle : points[0]; - quads[length - 1] = defined(lastInnerQuadrangle) ? lastInnerQuadrangle : points[length - 1]; + var context2D = canvas.getContext('2d'); - for (var i = 1; i < length - 1; ++i) { - quads[i] = Quaternion.computeInnerQuadrangle(points[i - 1], points[i], points[i + 1], new Quaternion()); + if (!defined(imageSmoothingEnabledName)) { + if (defined(context2D.imageSmoothingEnabled)) { + imageSmoothingEnabledName = 'imageSmoothingEnabled'; + } else if (defined(context2D.mozImageSmoothingEnabled)) { + imageSmoothingEnabledName = 'mozImageSmoothingEnabled'; + } else if (defined(context2D.webkitImageSmoothingEnabled)) { + imageSmoothingEnabledName = 'webkitImageSmoothingEnabled'; + } else if (defined(context2D.msImageSmoothingEnabled)) { + imageSmoothingEnabledName = 'msImageSmoothingEnabled'; + } } - return quads; - } + context2D.font = font; + context2D.lineJoin = 'round'; + context2D.lineWidth = strokeWidth; + context2D[imageSmoothingEnabledName] = false; - function createEvaluateFunction(spline) { - var points = spline.points; - var quads = spline.innerQuadrangles; - var times = spline.times; + // textBaseline needs to be set before the measureText call. It won't work otherwise. + // It's magic. + context2D.textBaseline = defaultValue(options.textBaseline, 'bottom'); - // use slerp interpolation for 2 points - if (points.length < 3) { - var t0 = times[0]; - var invSpan = 1.0 / (times[1] - t0); + // in order for measureText to calculate style, the canvas has to be + // (temporarily) added to the DOM. + canvas.style.visibility = 'hidden'; + document.body.appendChild(canvas); - var q0 = points[0]; - var q1 = points[1]; + var dimensions = measureText(context2D, text, stroke, fill); + canvas.dimensions = dimensions; - return function(time, result) { - if (!defined(result)){ - result = new Quaternion(); - } - var u = (time - t0) * invSpan; - return Quaternion.fastSlerp(q0, q1, u, result); - }; - } + document.body.removeChild(canvas); + canvas.style.visibility = ''; - // use quad interpolation for more than 3 points - return function(time, result) { - if (!defined(result)){ - result = new Quaternion(); - } - var i = spline._lastTimeIndex = spline.findTimeInterval(time, spline._lastTimeIndex); - var u = (time - times[i]) / (times[i + 1] - times[i]); + //Some characters, such as the letter j, have a non-zero starting position. + //This value is used for kerning later, but we need to take it into account + //now in order to draw the text completely on the canvas + var x = -dimensions.bounds.minx; - var q0 = points[i]; - var q1 = points[i + 1]; - var s0 = quads[i]; - var s1 = quads[i + 1]; + //Expand the width to include the starting position. + var width = Math.ceil(dimensions.width) + x + doublePadding; - return Quaternion.fastSquad(q0, q1, s0, s1, u, result); - }; - } + //While the height of the letter is correct, we need to adjust + //where we start drawing it so that letters like j and y properly dip + //below the line. + var height = dimensions.height + doublePadding; + var baseline = height - dimensions.ascent + doublePadding; + var y = height - baseline + doublePadding; - /** - * A spline that uses spherical quadrangle (squad) interpolation to create a quaternion curve. - * The generated curve is in the class C<sup>1</sup>. - * - * @alias QuaternionSpline - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. - * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Quaternion[]} options.points The array of {@link Quaternion} control points. - * @param {Quaternion} [options.firstInnerQuadrangle] The inner quadrangle of the curve at the first control point. - * If the inner quadrangle is not given, it will be estimated. - * @param {Quaternion} [options.lastInnerQuadrangle] The inner quadrangle of the curve at the last control point. - * If the inner quadrangle is not given, it will be estimated. - * - * @exception {DeveloperError} points.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be equal to points.length. - * - * @see HermiteSpline - * @see CatmullRomSpline - * @see LinearSpline - * @see WeightSpline - */ - function QuaternionSpline(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + canvas.width = width; + canvas.height = height; - var points = options.points; - var times = options.times; - var firstInnerQuadrangle = options.firstInnerQuadrangle; - var lastInnerQuadrangle = options.lastInnerQuadrangle; + // Properties must be explicitly set again after changing width and height + context2D.font = font; + context2D.lineJoin = 'round'; + context2D.lineWidth = strokeWidth; + context2D[imageSmoothingEnabledName] = false; - if (!defined(points) || !defined(times)) { - throw new DeveloperError('points and times are required.'); - } - if (points.length < 2) { - throw new DeveloperError('points.length must be greater than or equal to 2.'); + // Draw background + if (backgroundColor !== Color.TRANSPARENT) { + context2D.fillStyle = backgroundColor.toCssColorString(); + context2D.fillRect(0, 0, canvas.width, canvas.height); } - if (times.length !== points.length) { - throw new DeveloperError('times.length must be equal to points.length.'); + + if (stroke) { + var strokeColor = defaultValue(options.strokeColor, Color.BLACK); + context2D.strokeStyle = strokeColor.toCssColorString(); + context2D.strokeText(text, x + padding, y); } - - var innerQuadrangles = computeInnerQuadrangles(points, firstInnerQuadrangle, lastInnerQuadrangle); - this._times = times; - this._points = points; - this._innerQuadrangles = innerQuadrangles; + if (fill) { + var fillColor = defaultValue(options.fillColor, Color.WHITE); + context2D.fillStyle = fillColor.toCssColorString(); + context2D.fillText(text, x + padding, y); + } - this._evaluateFunction = createEvaluateFunction(this); - this._lastTimeIndex = 0; + return canvas; } - defineProperties(QuaternionSpline.prototype, { - /** - * An array of times for the control points. - * - * @memberof QuaternionSpline.prototype - * - * @type {Number[]} - * @readonly - */ - times : { - get : function() { - return this._times; - } - }, - - /** - * An array of {@link Quaternion} control points. - * - * @memberof QuaternionSpline.prototype - * - * @type {Quaternion[]} - * @readonly - */ - points : { - get : function() { - return this._points; - } - }, + return writeTextToCanvas; +}); - /** - * An array of {@link Quaternion} inner quadrangles for the control points. - * - * @memberof QuaternionSpline.prototype - * - * @type {Quaternion[]} - * @readonly - */ - innerQuadrangles : { - get : function() { - return this._innerQuadrangles; - } - } - }); +define('Core/PinBuilder',[ + './buildModuleUrl', + './Color', + './defined', + './DeveloperError', + './Resource', + './writeTextToCanvas' + ], function( + buildModuleUrl, + Color, + defined, + DeveloperError, + Resource, + writeTextToCanvas) { + 'use strict'; /** - * Finds an index <code>i</code> in <code>times</code> such that the parameter - * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. - * @function + * A utility class for generating custom map pins as canvas elements. + * <br /><br /> + * <div align='center'> + * <img src='Images/PinBuilder.png' width='500'/><br /> + * Example pins generated using both the maki icon set, which ships with Cesium, and single character text. + * </div> * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * @alias PinBuilder + * @constructor * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Map%20Pins.html|Cesium Sandcastle PinBuilder Demo} */ - QuaternionSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; + function PinBuilder() { + this._cache = {}; + } /** - * Wraps the given time to the period covered by the spline. - * @function + * Creates an empty pin of the specified color and size. * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {Color} color The color of the pin. + * @param {Number} size The size of the pin, in pixels. + * @returns {Canvas} The canvas element that represents the generated pin. */ - QuaternionSpline.prototype.wrapTime = Spline.prototype.wrapTime; + PinBuilder.prototype.fromColor = function(color, size) { + if (!defined(color)) { + throw new DeveloperError('color is required'); + } + if (!defined(size)) { + throw new DeveloperError('size is required'); + } + return createPin(undefined, undefined, color, size, this._cache); + }; /** - * Clamps the given time to the period covered by the spline. - * @function + * Creates a pin with the specified icon, color, and size. * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {Resource|String} url The url of the image to be stamped onto the pin. + * @param {Color} color The color of the pin. + * @param {Number} size The size of the pin, in pixels. + * @returns {Canvas|Promise.<Canvas>} The canvas element or a Promise to the canvas element that represents the generated pin. */ - QuaternionSpline.prototype.clampTime = Spline.prototype.clampTime; + PinBuilder.prototype.fromUrl = function(url, color, size) { + if (!defined(url)) { + throw new DeveloperError('url is required'); + } + if (!defined(color)) { + throw new DeveloperError('color is required'); + } + if (!defined(size)) { + throw new DeveloperError('size is required'); + } + return createPin(url, undefined, color, size, this._cache); + }; /** - * Evaluates the curve at a given time. + * Creates a pin with the specified {@link https://www.mapbox.com/maki/|maki} icon identifier, color, and size. * - * @param {Number} time The time at which to evaluate the curve. - * @param {Quaternion} [result] The object onto which to store the result. - * @returns {Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. + * @param {String} id The id of the maki icon to be stamped onto the pin. + * @param {Color} color The color of the pin. + * @param {Number} size The size of the pin, in pixels. + * @returns {Canvas|Promise.<Canvas>} The canvas element or a Promise to the canvas element that represents the generated pin. + */ + PinBuilder.prototype.fromMakiIconId = function(id, color, size) { + if (!defined(id)) { + throw new DeveloperError('id is required'); + } + if (!defined(color)) { + throw new DeveloperError('color is required'); + } + if (!defined(size)) { + throw new DeveloperError('size is required'); + } + return createPin(buildModuleUrl('Assets/Textures/maki/' + encodeURIComponent(id) + '.png'), undefined, color, size, this._cache); + }; + + /** + * Creates a pin with the specified text, color, and size. The text will be sized to be as large as possible + * while still being contained completely within the pin. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @param {String} text The text to be stamped onto the pin. + * @param {Color} color The color of the pin. + * @param {Number} size The size of the pin, in pixels. + * @returns {Canvas} The canvas element that represents the generated pin. */ - QuaternionSpline.prototype.evaluate = function(time, result) { - return this._evaluateFunction(time, result); + PinBuilder.prototype.fromText = function(text, color, size) { + if (!defined(text)) { + throw new DeveloperError('text is required'); + } + if (!defined(color)) { + throw new DeveloperError('color is required'); + } + if (!defined(size)) { + throw new DeveloperError('size is required'); + } + + return createPin(undefined, text, color, size, this._cache); }; - return QuaternionSpline; + var colorScratch = new Color(); + + //This function (except for the 3 commented lines) was auto-generated from an online tool, + //http://www.professorcloud.com/svg-to-canvas/, using Assets/Textures/pin.svg as input. + //The reason we simply can't load and draw the SVG directly to the canvas is because + //it taints the canvas in Internet Explorer (and possibly some other browsers); making + //it impossible to create a WebGL texture from the result. + function drawPin(context2D, color, size) { + context2D.save(); + context2D.scale(size / 24, size / 24); //Added to auto-generated code to scale up to desired size. + context2D.fillStyle = color.toCssColorString(); //Modified from auto-generated code. + context2D.strokeStyle = color.brighten(0.6, colorScratch).toCssColorString(); //Modified from auto-generated code. + context2D.lineWidth = 0.846; + context2D.beginPath(); + context2D.moveTo(6.72, 0.422); + context2D.lineTo(17.28, 0.422); + context2D.bezierCurveTo(18.553, 0.422, 19.577, 1.758, 19.577, 3.415); + context2D.lineTo(19.577, 10.973); + context2D.bezierCurveTo(19.577, 12.63, 18.553, 13.966, 17.282, 13.966); + context2D.lineTo(14.386, 14.008); + context2D.lineTo(11.826, 23.578); + context2D.lineTo(9.614, 14.008); + context2D.lineTo(6.719, 13.965); + context2D.bezierCurveTo(5.446, 13.983, 4.422, 12.629, 4.422, 10.972); + context2D.lineTo(4.422, 3.416); + context2D.bezierCurveTo(4.423, 1.76, 5.447, 0.423, 6.718, 0.423); + context2D.closePath(); + context2D.fill(); + context2D.stroke(); + context2D.restore(); + } + + //This function takes an image or canvas and uses it as a template + //to "stamp" the pin with a white image outlined in black. The color + //values of the input image are ignored completely and only the alpha + //values are used. + function drawIcon(context2D, image, size) { + //Size is the largest image that looks good inside of pin box. + var imageSize = size / 2.5; + var sizeX = imageSize; + var sizeY = imageSize; + + if (image.width > image.height) { + sizeY = imageSize * (image.height / image.width); + } else if (image.width < image.height) { + sizeX = imageSize * (image.width / image.height); + } + + //x and y are the center of the pin box + var x = Math.round((size - sizeX) / 2); + var y = Math.round(((7 / 24) * size) - (sizeY / 2)); + + context2D.globalCompositeOperation = 'destination-out'; + context2D.drawImage(image, x - 1, y, sizeX, sizeY); + context2D.drawImage(image, x, y - 1, sizeX, sizeY); + context2D.drawImage(image, x + 1, y, sizeX, sizeY); + context2D.drawImage(image, x, y + 1, sizeX, sizeY); + + context2D.globalCompositeOperation = 'destination-over'; + context2D.fillStyle = Color.BLACK.toCssColorString(); + context2D.fillRect(x - 1, y - 1, sizeX + 2, sizeY + 2); + + context2D.globalCompositeOperation = 'destination-out'; + context2D.drawImage(image, x, y, sizeX, sizeY); + + context2D.globalCompositeOperation = 'destination-over'; + context2D.fillStyle = Color.WHITE.toCssColorString(); + context2D.fillRect(x - 1, y - 2, sizeX + 2, sizeY + 2); + } + + var stringifyScratch = new Array(4); + function createPin(url, label, color, size, cache) { + //Use the parameters as a unique ID for caching. + stringifyScratch[0] = url; + stringifyScratch[1] = label; + stringifyScratch[2] = color; + stringifyScratch[3] = size; + var id = JSON.stringify(stringifyScratch); + + var item = cache[id]; + if (defined(item)) { + return item; + } + + var canvas = document.createElement('canvas'); + canvas.width = size; + canvas.height = size; + + var context2D = canvas.getContext('2d'); + drawPin(context2D, color, size); + + if (defined(url)) { + var resource = Resource.createIfNeeded(url); + + //If we have an image url, load it and then stamp the pin. + var promise = resource.fetchImage().then(function(image) { + drawIcon(context2D, image, size); + cache[id] = canvas; + return canvas; + }); + cache[id] = promise; + return promise; + } else if (defined(label)) { + //If we have a label, write it to a canvas and then stamp the pin. + var image = writeTextToCanvas(label, { + font : 'bold ' + size + 'px sans-serif' + }); + drawIcon(context2D, image, size); + } + + cache[id] = canvas; + return canvas; + } + + return PinBuilder; }); -define('Core/RectangleGeometryLibrary',[ +define('Core/PlaneGeometry',[ + './BoundingSphere', './Cartesian3', - './Cartographic', + './Check', + './ComponentDatatype', + './defaultValue', './defined', - './DeveloperError', - './GeographicProjection', - './Math', - './Matrix2', - './Rectangle' + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './PrimitiveType', + './VertexFormat' ], function( + BoundingSphere, Cartesian3, - Cartographic, + Check, + ComponentDatatype, + defaultValue, defined, - DeveloperError, - GeographicProjection, - CesiumMath, - Matrix2, - Rectangle) { + Geometry, + GeometryAttribute, + GeometryAttributes, + PrimitiveType, + VertexFormat) { 'use strict'; - var cos = Math.cos; - var sin = Math.sin; - var sqrt = Math.sqrt; - /** - * @private + * Describes geometry representing a plane centered at the origin, with a unit width and length. + * + * @alias PlaneGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * + * @example + * var planeGeometry = new Cesium.PlaneGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY + * }); */ - var RectangleGeometryLibrary = {}; + function PlaneGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + + this._vertexFormat = vertexFormat; + this._workerName = 'createPlaneGeometry'; + } /** - * @private + * The number of elements used to pack the object into an array. + * @type {Number} */ - RectangleGeometryLibrary.computePosition = function(options, row, col, position, st) { - var radiiSquared = options.ellipsoid.radiiSquared; - var nwCorner = options.nwCorner; - var rectangle = options.rectangle; + PlaneGeometry.packedLength = VertexFormat.packedLength; - var stLatitude = nwCorner.latitude - options.granYCos * row + col * options.granXSin; - var cosLatitude = cos(stLatitude); - var nZ = sin(stLatitude); - var kZ = radiiSquared.z * nZ; + /** + * Stores the provided instance into the provided array. + * + * @param {PlaneGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + PlaneGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - var stLongitude = nwCorner.longitude + row * options.granYSin + col * options.granXCos; - var nX = cosLatitude * cos(stLongitude); - var nY = cosLatitude * sin(stLongitude); + VertexFormat.pack(value._vertexFormat, array, startingIndex); - var kX = radiiSquared.x * nX; - var kY = radiiSquared.y * nY; + return array; + }; - var gamma = sqrt((kX * nX) + (kY * nY) + (kZ * nZ)); + var scratchVertexFormat = new VertexFormat(); + var scratchOptions = { + vertexFormat: scratchVertexFormat + }; - position.x = kX / gamma; - position.y = kY / gamma; - position.z = kZ / gamma; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {PlaneGeometry} [result] The object into which to store the result. + * @returns {PlaneGeometry} The modified result parameter or a new PlaneGeometry instance if one was not provided. + */ + PlaneGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - if (defined(options.vertexFormat) && options.vertexFormat.st) { - var stNwCorner = options.stNwCorner; - if (defined(stNwCorner)) { - stLatitude = stNwCorner.latitude - options.stGranYCos * row + col * options.stGranXSin; - stLongitude = stNwCorner.longitude + row * options.stGranYSin + col * options.stGranXCos; + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - st.x = (stLongitude - options.stWest) * options.lonScalar; - st.y = (stLatitude - options.stSouth) * options.latScalar; - } else { - st.x = (stLongitude - rectangle.west) * options.lonScalar; - st.y = (stLatitude - rectangle.south) * options.latScalar; - } + if (!defined(result)) { + return new PlaneGeometry(scratchOptions); } - }; - var rotationMatrixScratch = new Matrix2(); - var nwCartesian = new Cartesian3(); - var centerScratch = new Cartographic(); - var centerCartesian = new Cartesian3(); - var proj = new GeographicProjection(); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - function getRotationOptions(nwCorner, rotation, granularityX, granularityY, center, width, height) { - var cosRotation = Math.cos(rotation); - var granYCos = granularityY * cosRotation; - var granXCos = granularityX * cosRotation; + return result; + }; - var sinRotation = Math.sin(rotation); - var granYSin = granularityY * sinRotation; - var granXSin = granularityX * sinRotation; + var min = new Cartesian3(-0.5, -0.5, 0.0); + var max = new Cartesian3( 0.5, 0.5, 0.0); - nwCartesian = proj.project(nwCorner, nwCartesian); + /** + * Computes the geometric representation of a plane, including its vertices, indices, and a bounding sphere. + * + * @param {PlaneGeometry} planeGeometry A description of the plane. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + PlaneGeometry.createGeometry = function(planeGeometry) { + var vertexFormat = planeGeometry._vertexFormat; - nwCartesian = Cartesian3.subtract(nwCartesian, centerCartesian, nwCartesian); - var rotationMatrix = Matrix2.fromRotation(rotation, rotationMatrixScratch); - nwCartesian = Matrix2.multiplyByVector(rotationMatrix, nwCartesian, nwCartesian); - nwCartesian = Cartesian3.add(nwCartesian, centerCartesian, nwCartesian); - nwCorner = proj.unproject(nwCartesian, nwCorner); + var attributes = new GeometryAttributes(); + var indices; + var positions; - width -= 1; - height -= 1; + if (vertexFormat.position) { + // 4 corner points. Duplicated 3 times each for each incident edge/face. + positions = new Float64Array(4 * 3); - var latitude = nwCorner.latitude; - var latitude0 = latitude + width * granXSin; - var latitude1 = latitude - granYCos * height; - var latitude2 = latitude - granYCos * height + width * granXSin; + // +z face + positions[0] = min.x; + positions[1] = min.y; + positions[2] = 0.0; + positions[3] = max.x; + positions[4] = min.y; + positions[5] = 0.0; + positions[6] = max.x; + positions[7] = max.y; + positions[8] = 0.0; + positions[9] = min.x; + positions[10] = max.y; + positions[11] = 0.0; - var north = Math.max(latitude, latitude0, latitude1, latitude2); - var south = Math.min(latitude, latitude0, latitude1, latitude2); + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); - var longitude = nwCorner.longitude; - var longitude0 = longitude + width * granXCos; - var longitude1 = longitude + height * granYSin; - var longitude2 = longitude + height * granYSin + width * granXCos; + if (vertexFormat.normal) { + var normals = new Float32Array(4 * 3); - var east = Math.max(longitude, longitude0, longitude1, longitude2); - var west = Math.min(longitude, longitude0, longitude1, longitude2); + // +z face + normals[0] = 0.0; + normals[1] = 0.0; + normals[2] = 1.0; + normals[3] = 0.0; + normals[4] = 0.0; + normals[5] = 1.0; + normals[6] = 0.0; + normals[7] = 0.0; + normals[8] = 1.0; + normals[9] = 0.0; + normals[10] = 0.0; + normals[11] = 1.0; - return { - north: north, - south: south, - east: east, - west: west, - granYCos : granYCos, - granYSin : granYSin, - granXCos : granXCos, - granXSin : granXSin, - nwCorner : nwCorner - }; - } + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); + } - /** - * @private - */ - RectangleGeometryLibrary.computeOptions = function(geometry, rectangle, nwCorner, stNwCorner) { - var granularity = geometry._granularity; - var ellipsoid = geometry._ellipsoid; - var surfaceHeight = geometry._surfaceHeight; - var rotation = geometry._rotation; - var stRotation = geometry._stRotation; - var extrudedHeight = geometry._extrudedHeight; - var east = rectangle.east; - var west = rectangle.west; - var north = rectangle.north; - var south = rectangle.south; + if (vertexFormat.st) { + var texCoords = new Float32Array(4 * 2); - var width; - var height; - var granularityX; - var granularityY; - var dx; - var dy = north - south; - if (west > east) { - dx = (CesiumMath.TWO_PI - west + east); - width = Math.ceil(dx / granularity) + 1; - height = Math.ceil(dy / granularity) + 1; - granularityX = dx / (width - 1); - granularityY = dy / (height - 1); - } else { - dx = east - west; - width = Math.ceil(dx / granularity) + 1; - height = Math.ceil(dy / granularity) + 1; - granularityX = dx / (width - 1); - granularityY = dy / (height - 1); - } + // +z face + texCoords[0] = 0.0; + texCoords[1] = 0.0; + texCoords[2] = 1.0; + texCoords[3] = 0.0; + texCoords[4] = 1.0; + texCoords[5] = 1.0; + texCoords[6] = 0.0; + texCoords[7] = 1.0; - nwCorner = Rectangle.northwest(rectangle, nwCorner); - var center = Rectangle.center(rectangle, centerScratch); - if (rotation !== 0 || stRotation !== 0) { - if (center.longitude < nwCorner.longitude) { - center.longitude += CesiumMath.TWO_PI; + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : texCoords + }); } - centerCartesian = proj.project(center, centerCartesian); - } - - var granYCos = granularityY; - var granXCos = granularityX; - var granYSin = 0.0; - var granXSin = 0.0; - var options = { - granYCos : granYCos, - granYSin : granYSin, - granXCos : granXCos, - granXSin : granXSin, - ellipsoid : ellipsoid, - surfaceHeight : surfaceHeight, - extrudedHeight : extrudedHeight, - nwCorner : nwCorner, - rectangle : rectangle, - width: width, - height: height - }; + if (vertexFormat.tangent) { + var tangents = new Float32Array(4 * 3); - if (rotation !== 0) { - var rotationOptions = getRotationOptions(nwCorner, rotation, granularityX, granularityY, center, width, height); - north = rotationOptions.north; - south = rotationOptions.south; - east = rotationOptions.east; - west = rotationOptions.west; + // +z face + tangents[0] = 1.0; + tangents[1] = 0.0; + tangents[2] = 0.0; + tangents[3] = 1.0; + tangents[4] = 0.0; + tangents[5] = 0.0; + tangents[6] = 1.0; + tangents[7] = 0.0; + tangents[8] = 0.0; + tangents[9] = 1.0; + tangents[10] = 0.0; + tangents[11] = 0.0; - if (north < -CesiumMath.PI_OVER_TWO || north > CesiumMath.PI_OVER_TWO || - south < -CesiumMath.PI_OVER_TWO || south > CesiumMath.PI_OVER_TWO) { - throw new DeveloperError('Rotated rectangle is invalid. It crosses over either the north or south pole.'); + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); } - - options.granYCos = rotationOptions.granYCos; - options.granYSin = rotationOptions.granYSin; - options.granXCos = rotationOptions.granXCos; - options.granXSin = rotationOptions.granXSin; - rectangle.north = north; - rectangle.south = south; - rectangle.east = east; - rectangle.west = west; - } + if (vertexFormat.bitangent) { + var bitangents = new Float32Array(4 * 3); - if (stRotation !== 0) { - rotation = rotation - stRotation; - stNwCorner = Rectangle.northwest(rectangle, stNwCorner); + // +z face + bitangents[0] = 0.0; + bitangents[1] = 1.0; + bitangents[2] = 0.0; + bitangents[3] = 0.0; + bitangents[4] = 1.0; + bitangents[5] = 0.0; + bitangents[6] = 0.0; + bitangents[7] = 1.0; + bitangents[8] = 0.0; + bitangents[9] = 0.0; + bitangents[10] = 1.0; + bitangents[11] = 0.0; - var stRotationOptions = getRotationOptions(stNwCorner, rotation, granularityX, granularityY, center, width, height); + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } - options.stGranYCos = stRotationOptions.granYCos; - options.stGranXCos = stRotationOptions.granXCos; - options.stGranYSin = stRotationOptions.granYSin; - options.stGranXSin = stRotationOptions.granXSin; - options.stNwCorner = stNwCorner; - options.stWest = stRotationOptions.west; - options.stSouth = stRotationOptions.south; + // 2 triangles + indices = new Uint16Array(2 * 3); + + // +z face + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; } - return options; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : new BoundingSphere(Cartesian3.ZERO, Math.sqrt(2.0)) + }); }; - return RectangleGeometryLibrary; + return PlaneGeometry; }); -define('Core/RectangleGeometry',[ +define('Core/PlaneOutlineGeometry',[ './BoundingSphere', - './Cartesian2', './Cartesian3', - './Cartographic', './Check', './ComponentDatatype', './defaultValue', './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid', './Geometry', './GeometryAttribute', './GeometryAttributes', - './GeometryInstance', - './GeometryPipeline', - './IndexDatatype', - './Math', - './Matrix3', - './PolygonPipeline', - './PrimitiveType', - './Quaternion', - './Rectangle', - './RectangleGeometryLibrary', - './VertexFormat' + './PrimitiveType' ], function( BoundingSphere, - Cartesian2, Cartesian3, - Cartographic, Check, ComponentDatatype, defaultValue, defined, - defineProperties, - DeveloperError, - Ellipsoid, Geometry, GeometryAttribute, GeometryAttributes, - GeometryInstance, - GeometryPipeline, - IndexDatatype, - CesiumMath, - Matrix3, - PolygonPipeline, - PrimitiveType, - Quaternion, - Rectangle, - RectangleGeometryLibrary, - VertexFormat) { + PrimitiveType) { 'use strict'; - var positionScratch = new Cartesian3(); - var normalScratch = new Cartesian3(); - var tangentScratch = new Cartesian3(); - var bitangentScratch = new Cartesian3(); - var rectangleScratch = new Rectangle(); - var stScratch = new Cartesian2(); - var bottomBoundingSphere = new BoundingSphere(); - var topBoundingSphere = new BoundingSphere(); - - function createAttributes(vertexFormat, attributes) { - var geo = new Geometry({ - attributes : new GeometryAttributes(), - primitiveType : PrimitiveType.TRIANGLES - }); - - geo.attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : attributes.positions - }); - if (vertexFormat.normal) { - geo.attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : attributes.normals - }); - } - if (vertexFormat.tangent) { - geo.attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : attributes.tangents - }); - } - if (vertexFormat.bitangent) { - geo.attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : attributes.bitangents - }); - } - return geo; - } - - function calculateAttributes(positions, vertexFormat, ellipsoid, tangentRotationMatrix) { - var length = positions.length; - - var normals = (vertexFormat.normal) ? new Float32Array(length) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(length) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(length) : undefined; - - var attrIndex = 0; - var bitangent = bitangentScratch; - var tangent = tangentScratch; - var normal = normalScratch; - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - for (var i = 0; i < length; i += 3) { - var p = Cartesian3.fromArray(positions, i, positionScratch); - var attrIndex1 = attrIndex + 1; - var attrIndex2 = attrIndex + 2; - - normal = ellipsoid.geodeticSurfaceNormal(p, normal); - if (vertexFormat.tangent || vertexFormat.bitangent) { - Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent); - Matrix3.multiplyByVector(tangentRotationMatrix, tangent, tangent); - Cartesian3.normalize(tangent, tangent); - - if (vertexFormat.bitangent) { - Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); - } - } - - if (vertexFormat.normal) { - normals[attrIndex] = normal.x; - normals[attrIndex1] = normal.y; - normals[attrIndex2] = normal.z; - } - if (vertexFormat.tangent) { - tangents[attrIndex] = tangent.x; - tangents[attrIndex1] = tangent.y; - tangents[attrIndex2] = tangent.z; - } - if (vertexFormat.bitangent) { - bitangents[attrIndex] = bitangent.x; - bitangents[attrIndex1] = bitangent.y; - bitangents[attrIndex2] = bitangent.z; - } - attrIndex += 3; - } - } - return createAttributes(vertexFormat, { - positions : positions, - normals : normals, - tangents : tangents, - bitangents : bitangents - }); - } - - var v1Scratch = new Cartesian3(); - var v2Scratch = new Cartesian3(); - - function calculateAttributesWall(positions, vertexFormat, ellipsoid) { - var length = positions.length; - - var normals = (vertexFormat.normal) ? new Float32Array(length) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(length) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(length) : undefined; - - var normalIndex = 0; - var tangentIndex = 0; - var bitangentIndex = 0; - var recomputeNormal = true; - - var bitangent = bitangentScratch; - var tangent = tangentScratch; - var normal = normalScratch; - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - for (var i = 0; i < length; i += 6) { - var p = Cartesian3.fromArray(positions, i, positionScratch); - var p1 = Cartesian3.fromArray(positions, (i + 6) % length, v1Scratch); - if (recomputeNormal) { - var p2 = Cartesian3.fromArray(positions, (i + 3) % length, v2Scratch); - Cartesian3.subtract(p1, p, p1); - Cartesian3.subtract(p2, p, p2); - normal = Cartesian3.normalize(Cartesian3.cross(p2, p1, normal), normal); - recomputeNormal = false; - } - - if (Cartesian3.equalsEpsilon(p1, p, CesiumMath.EPSILON10)) { // if we've reached a corner - recomputeNormal = true; - } - - if (vertexFormat.tangent || vertexFormat.bitangent) { - bitangent = ellipsoid.geodeticSurfaceNormal(p, bitangent); - if (vertexFormat.tangent) { - tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); - } - } - - if (vertexFormat.normal) { - normals[normalIndex++] = normal.x; - normals[normalIndex++] = normal.y; - normals[normalIndex++] = normal.z; - normals[normalIndex++] = normal.x; - normals[normalIndex++] = normal.y; - normals[normalIndex++] = normal.z; - } - - if (vertexFormat.tangent) { - tangents[tangentIndex++] = tangent.x; - tangents[tangentIndex++] = tangent.y; - tangents[tangentIndex++] = tangent.z; - tangents[tangentIndex++] = tangent.x; - tangents[tangentIndex++] = tangent.y; - tangents[tangentIndex++] = tangent.z; - } - - if (vertexFormat.bitangent) { - bitangents[bitangentIndex++] = bitangent.x; - bitangents[bitangentIndex++] = bitangent.y; - bitangents[bitangentIndex++] = bitangent.z; - bitangents[bitangentIndex++] = bitangent.x; - bitangents[bitangentIndex++] = bitangent.y; - bitangents[bitangentIndex++] = bitangent.z; - } - } - } - - return createAttributes(vertexFormat, { - positions : positions, - normals : normals, - tangents : tangents, - bitangents : bitangents - }); - } - - function constructRectangle(options) { - var vertexFormat = options.vertexFormat; - var ellipsoid = options.ellipsoid; - var size = options.size; - var height = options.height; - var width = options.width; - - var positions = (vertexFormat.position) ? new Float64Array(size * 3) : undefined; - var textureCoordinates = (vertexFormat.st) ? new Float32Array(size * 2) : undefined; - - var posIndex = 0; - var stIndex = 0; - - var position = positionScratch; - var st = stScratch; - - var minX = Number.MAX_VALUE; - var minY = Number.MAX_VALUE; - var maxX = -Number.MAX_VALUE; - var maxY = -Number.MAX_VALUE; - - for (var row = 0; row < height; ++row) { - for (var col = 0; col < width; ++col) { - RectangleGeometryLibrary.computePosition(options, row, col, position, st); - - positions[posIndex++] = position.x; - positions[posIndex++] = position.y; - positions[posIndex++] = position.z; - - if (vertexFormat.st) { - textureCoordinates[stIndex++] = st.x; - textureCoordinates[stIndex++] = st.y; - - minX = Math.min(minX, st.x); - minY = Math.min(minY, st.y); - maxX = Math.max(maxX, st.x); - maxY = Math.max(maxY, st.y); - } - } - } - - if (vertexFormat.st && (minX < 0.0 || minY < 0.0 || maxX > 1.0 || maxY > 1.0)) { - for (var k = 0; k < textureCoordinates.length; k += 2) { - textureCoordinates[k] = (textureCoordinates[k] - minX) / (maxX - minX); - textureCoordinates[k + 1] = (textureCoordinates[k + 1] - minY) / (maxY - minY); - } - } - - var geo = calculateAttributes(positions, vertexFormat, ellipsoid, options.tangentRotationMatrix); - - var indicesSize = 6 * (width - 1) * (height - 1); - var indices = IndexDatatype.createTypedArray(size, indicesSize); - var index = 0; - var indicesIndex = 0; - for (var i = 0; i < height - 1; ++i) { - for (var j = 0; j < width - 1; ++j) { - var upperLeft = index; - var lowerLeft = upperLeft + width; - var lowerRight = lowerLeft + 1; - var upperRight = upperLeft + 1; - indices[indicesIndex++] = upperLeft; - indices[indicesIndex++] = lowerLeft; - indices[indicesIndex++] = upperRight; - indices[indicesIndex++] = upperRight; - indices[indicesIndex++] = lowerLeft; - indices[indicesIndex++] = lowerRight; - ++index; - } - ++index; - } - - geo.indices = indices; - if (vertexFormat.st) { - geo.attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : textureCoordinates - }); - } - - return geo; - } - - function addWallPositions(wallPositions, posIndex, i, topPositions, bottomPositions) { - wallPositions[posIndex++] = topPositions[i]; - wallPositions[posIndex++] = topPositions[i + 1]; - wallPositions[posIndex++] = topPositions[i + 2]; - wallPositions[posIndex++] = bottomPositions[i]; - wallPositions[posIndex++] = bottomPositions[i + 1]; - wallPositions[posIndex++] = bottomPositions[i + 2]; - return wallPositions; - } - - function addWallTextureCoordinates(wallTextures, stIndex, i, st) { - wallTextures[stIndex++] = st[i]; - wallTextures[stIndex++] = st[i + 1]; - wallTextures[stIndex++] = st[i]; - wallTextures[stIndex++] = st[i + 1]; - return wallTextures; - } - - var scratchVertexFormat = new VertexFormat(); - - function constructExtrudedRectangle(options) { - var shadowVolume = options.shadowVolume; - var vertexFormat = options.vertexFormat; - var surfaceHeight = options.surfaceHeight; - var extrudedHeight = options.extrudedHeight; - var minHeight = Math.min(extrudedHeight, surfaceHeight); - var maxHeight = Math.max(extrudedHeight, surfaceHeight); - - var height = options.height; - var width = options.width; - var ellipsoid = options.ellipsoid; - var i; - - if (shadowVolume) { - options.vertexFormat = VertexFormat.clone(vertexFormat, scratchVertexFormat); - options.vertexFormat.normal = true; - } - var topBottomGeo = constructRectangle(options); - if (CesiumMath.equalsEpsilon(minHeight, maxHeight, CesiumMath.EPSILON10)) { - return topBottomGeo; - } - - var topPositions = PolygonPipeline.scaleToGeodeticHeight(topBottomGeo.attributes.position.values, maxHeight, ellipsoid, false); - topPositions = new Float64Array(topPositions); - var length = topPositions.length; - var newLength = length * 2; - var positions = new Float64Array(newLength); - positions.set(topPositions); - var bottomPositions = PolygonPipeline.scaleToGeodeticHeight(topBottomGeo.attributes.position.values, minHeight, ellipsoid); - positions.set(bottomPositions, length); - topBottomGeo.attributes.position.values = positions; - - var normals = (vertexFormat.normal) ? new Float32Array(newLength) : undefined; - var tangents = (vertexFormat.tangent) ? new Float32Array(newLength) : undefined; - var bitangents = (vertexFormat.bitangent) ? new Float32Array(newLength) : undefined; - var textures = (vertexFormat.st) ? new Float32Array(newLength / 3 * 2) : undefined; - var topSt; - var topNormals; - if (vertexFormat.normal) { - topNormals = topBottomGeo.attributes.normal.values; - normals.set(topNormals); - for (i = 0; i < length; i++) { - topNormals[i] = -topNormals[i]; - } - normals.set(topNormals, length); - topBottomGeo.attributes.normal.values = normals; - } - if (shadowVolume) { - topNormals = topBottomGeo.attributes.normal.values; - if (!vertexFormat.normal) { - topBottomGeo.attributes.normal = undefined; - } - var extrudeNormals = new Float32Array(newLength); - for (i = 0; i < length; i++) { - topNormals[i] = -topNormals[i]; - } - extrudeNormals.set(topNormals, length); //only get normals for bottom layer that's going to be pushed down - topBottomGeo.attributes.extrudeDirection = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : extrudeNormals - }); - } - - if (vertexFormat.tangent) { - var topTangents = topBottomGeo.attributes.tangent.values; - tangents.set(topTangents); - for (i = 0; i < length; i++) { - topTangents[i] = -topTangents[i]; - } - tangents.set(topTangents, length); - topBottomGeo.attributes.tangent.values = tangents; - } - if (vertexFormat.bitangent) { - var topBitangents = topBottomGeo.attributes.bitangent.values; - bitangents.set(topBitangents); - bitangents.set(topBitangents, length); - topBottomGeo.attributes.bitangent.values = bitangents; - } - if (vertexFormat.st) { - topSt = topBottomGeo.attributes.st.values; - textures.set(topSt); - textures.set(topSt, length / 3 * 2); - topBottomGeo.attributes.st.values = textures; - } - - var indices = topBottomGeo.indices; - var indicesLength = indices.length; - var posLength = length / 3; - var newIndices = IndexDatatype.createTypedArray(newLength / 3, indicesLength * 2); - newIndices.set(indices); - for (i = 0; i < indicesLength; i += 3) { - newIndices[i + indicesLength] = indices[i + 2] + posLength; - newIndices[i + 1 + indicesLength] = indices[i + 1] + posLength; - newIndices[i + 2 + indicesLength] = indices[i] + posLength; - } - topBottomGeo.indices = newIndices; - - var perimeterPositions = 2 * width + 2 * height - 4; - var wallCount = (perimeterPositions + 4) * 2; - - var wallPositions = new Float64Array(wallCount * 3); - var wallExtrudeNormals = shadowVolume ? new Float32Array(wallCount * 3) : undefined; - var wallTextures = (vertexFormat.st) ? new Float32Array(wallCount * 2) : undefined; - - var posIndex = 0; - var stIndex = 0; - var extrudeNormalIndex = 0; - var area = width * height; - var threeI; - for (i = 0; i < area; i += width) { - threeI = i * 3; - wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); - posIndex += 6; - if (vertexFormat.st) { - wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); - stIndex += 4; - } - if (shadowVolume) { - extrudeNormalIndex += 3; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; - } - } - - for (i = area - width; i < area; i++) { - threeI = i * 3; - wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); - posIndex += 6; - if (vertexFormat.st) { - wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); - stIndex += 4; - } - if (shadowVolume) { - extrudeNormalIndex += 3; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; - } - } - - for (i = area - 1; i > 0; i -= width) { - threeI = i * 3; - wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); - posIndex += 6; - if (vertexFormat.st) { - wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); - stIndex += 4; - } - if (shadowVolume) { - extrudeNormalIndex += 3; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; - } - } - - for (i = width - 1; i >= 0; i--) { - threeI = i * 3; - wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); - posIndex += 6; - if (vertexFormat.st) { - wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); - stIndex += 4; - } - if (shadowVolume) { - extrudeNormalIndex += 3; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; - wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; - } - } - - var geo = calculateAttributesWall(wallPositions, vertexFormat, ellipsoid); - - if (vertexFormat.st) { - geo.attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : wallTextures - }); - } - if (shadowVolume) { - geo.attributes.extrudeDirection = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : wallExtrudeNormals - }); - } - - var wallIndices = IndexDatatype.createTypedArray(wallCount, perimeterPositions * 6); - - var upperLeft; - var lowerLeft; - var lowerRight; - var upperRight; - length = wallPositions.length / 3; - var index = 0; - for (i = 0; i < length - 1; i += 2) { - upperLeft = i; - upperRight = (upperLeft + 2) % length; - var p1 = Cartesian3.fromArray(wallPositions, upperLeft * 3, v1Scratch); - var p2 = Cartesian3.fromArray(wallPositions, upperRight * 3, v2Scratch); - if (Cartesian3.equalsEpsilon(p1, p2, CesiumMath.EPSILON10)) { - continue; - } - lowerLeft = (upperLeft + 1) % length; - lowerRight = (lowerLeft + 2) % length; - wallIndices[index++] = upperLeft; - wallIndices[index++] = lowerLeft; - wallIndices[index++] = upperRight; - wallIndices[index++] = upperRight; - wallIndices[index++] = lowerLeft; - wallIndices[index++] = lowerRight; - } - - geo.indices = wallIndices; - - geo = GeometryPipeline.combineInstances([ - new GeometryInstance({ - geometry : topBottomGeo - }), - new GeometryInstance({ - geometry : geo - }) - ]); - - return geo[0]; - } - - var scratchRotationMatrix = new Matrix3(); - var scratchCartesian3 = new Cartesian3(); - var scratchQuaternion = new Quaternion(); - var scratchRectanglePoints = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; - var scratchCartographicPoints = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; - - function computeRectangle(rectangle, ellipsoid, rotation) { - if (rotation === 0.0) { - return Rectangle.clone(rectangle); - } - - Rectangle.northeast(rectangle, scratchCartographicPoints[0]); - Rectangle.northwest(rectangle, scratchCartographicPoints[1]); - Rectangle.southeast(rectangle, scratchCartographicPoints[2]); - Rectangle.southwest(rectangle, scratchCartographicPoints[3]); - - ellipsoid.cartographicArrayToCartesianArray(scratchCartographicPoints, scratchRectanglePoints); - - var surfaceNormal = ellipsoid.geodeticSurfaceNormalCartographic(Rectangle.center(rectangle, scratchCartesian3)); - Quaternion.fromAxisAngle(surfaceNormal, rotation, scratchQuaternion); - - Matrix3.fromQuaternion(scratchQuaternion, scratchRotationMatrix); - for (var i = 0; i < 4; ++i) { - // Apply the rotation - Matrix3.multiplyByVector(scratchRotationMatrix, scratchRectanglePoints[i], scratchRectanglePoints[i]); - } - - ellipsoid.cartesianArrayToCartographicArray(scratchRectanglePoints, scratchCartographicPoints); - - return Rectangle.fromCartographicArray(scratchCartographicPoints); - } - /** - * A description of a cartographic rectangle on an ellipsoid centered at the origin. Rectangle geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * Describes geometry representing the outline of a plane centered at the origin, with a unit width and length. * - * @alias RectangleGeometry + * @alias PlaneOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: - * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. - * @param {Number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. - * @param {Boolean} [options.closeTop=true] Specifies whether the rectangle has a top cover when extruded. - * @param {Boolean} [options.closeBottom=true] Specifies whether the rectangle has a bottom cover when extruded. - * - * @exception {DeveloperError} <code>options.rectangle.north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. - * @exception {DeveloperError} <code>options.rectangle.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. - * @exception {DeveloperError} <code>options.rectangle.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. - * @exception {DeveloperError} <code>options.rectangle.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. - * @exception {DeveloperError} <code>options.rectangle.north</code> must be greater than <code>options.rectangle.south</code>. - * - * @see RectangleGeometry#createGeometry - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo} - * - * @example - * // 1. create a rectangle - * var rectangle = new Cesium.RectangleGeometry({ - * ellipsoid : Cesium.Ellipsoid.WGS84, - * rectangle : Cesium.Rectangle.fromDegrees(-80.0, 39.0, -74.0, 42.0), - * height : 10000.0 - * }); - * var geometry = Cesium.RectangleGeometry.createGeometry(rectangle); - * - * // 2. create an extruded rectangle without a top - * var rectangle = new Cesium.RectangleGeometry({ - * ellipsoid : Cesium.Ellipsoid.WGS84, - * rectangle : Cesium.Rectangle.fromDegrees(-80.0, 39.0, -74.0, 42.0), - * height : 10000.0, - * extrudedHeight: 300000, - * closeTop: false - * }); - * var geometry = Cesium.RectangleGeometry.createGeometry(rectangle); */ - function RectangleGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var rectangle = options.rectangle; - - Check.typeOf.object('rectangle', rectangle); - Rectangle.validate(rectangle); - if (rectangle.north < rectangle.south) { - throw new DeveloperError('options.rectangle.north must be greater than or equal to options.rectangle.south'); - } - - var rotation = defaultValue(options.rotation, 0.0); - this._rectangle = rectangle; - this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); - this._surfaceHeight = defaultValue(options.height, 0.0); - this._rotation = rotation; - this._stRotation = defaultValue(options.stRotation, 0.0); - this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); - this._extrudedHeight = defaultValue(options.extrudedHeight, 0.0); - this._extrude = defined(options.extrudedHeight); - this._closeTop = defaultValue(options.closeTop, true); - this._closeBottom = defaultValue(options.closeBottom, true); - this._shadowVolume = defaultValue(options.shadowVolume, false); - this._workerName = 'createRectangleGeometry'; - this._rotatedRectangle = computeRectangle(this._rectangle, this._ellipsoid, rotation); + function PlaneOutlineGeometry() { + this._workerName = 'createPlaneOutlineGeometry'; } /** * The number of elements used to pack the object into an array. * @type {Number} */ - RectangleGeometry.packedLength = Rectangle.packedLength + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 9; + PlaneOutlineGeometry.packedLength = 0; /** * Stores the provided instance into the provided array. * - * @param {RectangleGeometry} value The value to pack. + * @param {PlaneOutlineGeometry} value The value to pack. * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - RectangleGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); + PlaneOutlineGeometry.pack = function(value, array) { + Check.defined('value', value); Check.defined('array', array); - startingIndex = defaultValue(startingIndex, 0); - - Rectangle.pack(value._rectangle, array, startingIndex); - startingIndex += Rectangle.packedLength; - - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; - - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; - - Rectangle.pack(value._rotatedRectangle, array, startingIndex); - startingIndex += Rectangle.packedLength; - - array[startingIndex++] = value._granularity; - array[startingIndex++] = value._surfaceHeight; - array[startingIndex++] = value._rotation; - array[startingIndex++] = value._stRotation; - array[startingIndex++] = value._extrudedHeight; - array[startingIndex++] = value._extrude ? 1.0 : 0.0; - array[startingIndex++] = value._closeTop ? 1.0 : 0.0; - array[startingIndex++] = value._closeBottom ? 1.0 : 0.0; - array[startingIndex] = value._shadowVolume ? 1.0 : 0.0; - return array; }; - var scratchRectangle = new Rectangle(); - var scratchRotatedRectangle = new Rectangle(); - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchOptions = { - rectangle : scratchRectangle, - ellipsoid : scratchEllipsoid, - vertexFormat : scratchVertexFormat, - granularity : undefined, - height : undefined, - rotation : undefined, - stRotation : undefined, - extrudedHeight : undefined, - closeTop : undefined, - closeBottom : undefined, - shadowVolume : undefined - }; - /** * Retrieves an instance from a packed array. * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {RectangleGeometry} [result] The object into which to store the result. - * @returns {RectangleGeometry} The modified result parameter or a new RectangleGeometry instance if one was not provided. + * @param {PlaneOutlineGeometry} [result] The object into which to store the result. + * @returns {PlaneOutlineGeometry} The modified result parameter or a new PlaneOutlineGeometry instance if one was not provided. */ - RectangleGeometry.unpack = function(array, startingIndex, result) { + PlaneOutlineGeometry.unpack = function(array, startingIndex, result) { Check.defined('array', array); - startingIndex = defaultValue(startingIndex, 0); - - var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); - startingIndex += Rectangle.packedLength; + if (!defined(result)) { + return new PlaneOutlineGeometry(); + } - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + return result; + }; - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + var min = new Cartesian3(-0.5, -0.5, 0.0); + var max = new Cartesian3( 0.5, 0.5, 0.0); - var rotatedRectangle = Rectangle.unpack(array, startingIndex, scratchRotatedRectangle); - startingIndex += Rectangle.packedLength; + /** + * Computes the geometric representation of an outline of a plane, including its vertices, indices, and a bounding sphere. + * + * @returns {Geometry|undefined} The computed vertices and indices. + */ + PlaneOutlineGeometry.createGeometry = function() { + var attributes = new GeometryAttributes(); + var indices = new Uint16Array(4 * 2); + var positions = new Float64Array(4 * 3); - var granularity = array[startingIndex++]; - var surfaceHeight = array[startingIndex++]; - var rotation = array[startingIndex++]; - var stRotation = array[startingIndex++]; - var extrudedHeight = array[startingIndex++]; - var extrude = array[startingIndex++] === 1.0; - var closeTop = array[startingIndex++] === 1.0; - var closeBottom = array[startingIndex++] === 1.0; - var shadowVolume = array[startingIndex] === 1.0; + positions[0] = min.x; + positions[1] = min.y; + positions[2] = min.z; + positions[3] = max.x; + positions[4] = min.y; + positions[5] = min.z; + positions[6] = max.x; + positions[7] = max.y; + positions[8] = min.z; + positions[9] = min.x; + positions[10] = max.y; + positions[11] = min.z; - if (!defined(result)) { - scratchOptions.granularity = granularity; - scratchOptions.height = surfaceHeight; - scratchOptions.rotation = rotation; - scratchOptions.stRotation = stRotation; - scratchOptions.extrudedHeight = extrude ? extrudedHeight : undefined; - scratchOptions.closeTop = closeTop; - scratchOptions.closeBottom = closeBottom; - scratchOptions.shadowVolume = shadowVolume; - return new RectangleGeometry(scratchOptions); - } + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); - result._rectangle = Rectangle.clone(rectangle, result._rectangle); - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._granularity = granularity; - result._surfaceHeight = surfaceHeight; - result._rotation = rotation; - result._stRotation = stRotation; - result._extrudedHeight = extrude ? extrudedHeight : undefined; - result._extrude = extrude; - result._closeTop = closeTop; - result._closeBottom = closeBottom; - result._rotatedRectangle = rotatedRectangle; - result._shadowVolume = shadowVolume; + indices[0] = 0; + indices[1] = 1; + indices[2] = 1; + indices[3] = 2; + indices[4] = 2; + indices[5] = 3; + indices[6] = 3; + indices[7] = 0; - return result; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : new BoundingSphere(Cartesian3.ZERO, Math.sqrt(2.0)) + }); }; - var tangentRotationMatrixScratch = new Matrix3(); - var nwScratch = new Cartographic(); - var stNwScratch = new Cartographic(); - var quaternionScratch = new Quaternion(); - var centerScratch = new Cartographic(); + return PlaneOutlineGeometry; +}); + +define('Core/pointInsideTriangle',[ + './barycentricCoordinates', + './Cartesian3' + ], function( + barycentricCoordinates, + Cartesian3) { + 'use strict'; + + var coords = new Cartesian3(); + /** - * Computes the geometric representation of a rectangle, including its vertices, indices, and a bounding sphere. + * Determines if a point is inside a triangle. * - * @param {RectangleGeometry} rectangleGeometry A description of the rectangle. - * @returns {Geometry|undefined} The computed vertices and indices. + * @exports pointInsideTriangle * - * @exception {DeveloperError} Rotated rectangle is invalid. + * @param {Cartesian2|Cartesian3} point The point to test. + * @param {Cartesian2|Cartesian3} p0 The first point of the triangle. + * @param {Cartesian2|Cartesian3} p1 The second point of the triangle. + * @param {Cartesian2|Cartesian3} p2 The third point of the triangle. + * @returns {Boolean} <code>true</code> if the point is inside the triangle; otherwise, <code>false</code>. + * + * @example + * // Returns true + * var p = new Cesium.Cartesian2(0.25, 0.25); + * var b = Cesium.pointInsideTriangle(p, + * new Cesium.Cartesian2(0.0, 0.0), + * new Cesium.Cartesian2(1.0, 0.0), + * new Cesium.Cartesian2(0.0, 1.0)); */ - RectangleGeometry.createGeometry = function(rectangleGeometry) { - if ((CesiumMath.equalsEpsilon(rectangleGeometry._rectangle.north, rectangleGeometry._rectangle.south, CesiumMath.EPSILON10) || - (CesiumMath.equalsEpsilon(rectangleGeometry._rectangle.east, rectangleGeometry._rectangle.west, CesiumMath.EPSILON10)))) { - return undefined; - } + function pointInsideTriangle(point, p0, p1, p2) { + barycentricCoordinates(point, p0, p1, p2, coords); + return (coords.x > 0.0) && (coords.y > 0.0) && (coords.z > 0); + } - var rectangle = Rectangle.clone(rectangleGeometry._rectangle, rectangleScratch); - var ellipsoid = rectangleGeometry._ellipsoid; - var surfaceHeight = rectangleGeometry._surfaceHeight; - var extrude = rectangleGeometry._extrude; - var extrudedHeight = rectangleGeometry._extrudedHeight; - var rotation = rectangleGeometry._rotation; - var stRotation = rectangleGeometry._stRotation; - var vertexFormat = rectangleGeometry._vertexFormat; + return pointInsideTriangle; +}); - var options = RectangleGeometryLibrary.computeOptions(rectangleGeometry, rectangle, nwScratch, stNwScratch); +define('Core/Queue',[ + './defineProperties' + ], function( + defineProperties) { + 'use strict'; - var tangentRotationMatrix = tangentRotationMatrixScratch; - if (stRotation !== 0 || rotation !== 0) { - var center = Rectangle.center(rectangle, centerScratch); - var axis = ellipsoid.geodeticSurfaceNormalCartographic(center, v1Scratch); - Quaternion.fromAxisAngle(axis, -stRotation, quaternionScratch); - Matrix3.fromQuaternion(quaternionScratch, tangentRotationMatrix); - } else { - Matrix3.clone(Matrix3.IDENTITY, tangentRotationMatrix); + /** + * A queue that can enqueue items at the end, and dequeue items from the front. + * + * @alias Queue + * @constructor + */ + function Queue() { + this._array = []; + this._offset = 0; + this._length = 0; + } + + defineProperties(Queue.prototype, { + /** + * The length of the queue. + * + * @memberof Queue.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } } + }); - options.lonScalar = 1.0 / rectangleGeometry._rectangle.width; - options.latScalar = 1.0 / rectangleGeometry._rectangle.height; - options.vertexFormat = vertexFormat; - options.rotation = rotation; - options.stRotation = stRotation; - options.tangentRotationMatrix = tangentRotationMatrix; - options.size = options.width * options.height; + /** + * Enqueues the specified item. + * + * @param {Object} item The item to enqueue. + */ + Queue.prototype.enqueue = function(item) { + this._array.push(item); + this._length++; + }; - var geometry; - var boundingSphere; - rectangle = rectangleGeometry._rectangle; - if (extrude) { - options.shadowVolume = rectangleGeometry._shadowVolume; - geometry = constructExtrudedRectangle(options); - var topBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight, topBoundingSphere); - var bottomBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, extrudedHeight, bottomBoundingSphere); - boundingSphere = BoundingSphere.union(topBS, bottomBS); - } else { - geometry = constructRectangle(options); - geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.attributes.position.values, surfaceHeight, ellipsoid, false); - boundingSphere = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight); + /** + * Dequeues an item. Returns undefined if the queue is empty. + * + * @returns {Object} The the dequeued item. + */ + Queue.prototype.dequeue = function() { + if (this._length === 0) { + return undefined; } - if (!vertexFormat.position) { - delete geometry.attributes.position; + var array = this._array; + var offset = this._offset; + var item = array[offset]; + array[offset] = undefined; + + offset++; + if ((offset > 10) && (offset * 2 > array.length)) { + //compact array + this._array = array.slice(offset); + offset = 0; } - return new Geometry({ - attributes : geometry.attributes, - indices : geometry.indices, - primitiveType : geometry.primitiveType, - boundingSphere : boundingSphere - }); + this._offset = offset; + this._length--; + + return item; }; /** - * @private + * Returns the item at the front of the queue. Returns undefined if the queue is empty. + * + * @returns {Object} The item at the front of the queue. */ - RectangleGeometry.createShadowVolume = function(rectangleGeometry, minHeightFunc, maxHeightFunc) { - var granularity = rectangleGeometry._granularity; - var ellipsoid = rectangleGeometry._ellipsoid; + Queue.prototype.peek = function() { + if (this._length === 0) { + return undefined; + } - var minHeight = minHeightFunc(granularity, ellipsoid); - var maxHeight = maxHeightFunc(granularity, ellipsoid); + return this._array[this._offset]; + }; - // TODO: stRotation - return new RectangleGeometry({ - rectangle : rectangleGeometry._rectangle, - rotation : rectangleGeometry._rotation, - ellipsoid : ellipsoid, - stRotation : rectangleGeometry._stRotation, - granularity : granularity, - extrudedHeight : maxHeight, - height : minHeight, - closeTop : true, - closeBottom : true, - vertexFormat : VertexFormat.POSITION_ONLY, - shadowVolume : true - }); + /** + * Check whether this queue contains the specified item. + * + * @param {Object} item The item to search for. + */ + Queue.prototype.contains = function(item) { + return this._array.indexOf(item) !== -1; }; - defineProperties(RectangleGeometry.prototype, { - /** - * @private - */ - rectangle : { - get : function() { - return this._rotatedRectangle; - } + /** + * Remove all items from the queue. + */ + Queue.prototype.clear = function() { + this._array.length = this._offset = this._length = 0; + }; + + /** + * Sort the items in the queue in-place. + * + * @param {Queue~Comparator} compareFunction A function that defines the sort order. + */ + Queue.prototype.sort = function(compareFunction) { + if (this._offset > 0) { + //compact array + this._array = this._array.slice(this._offset); + this._offset = 0; } - }); - return RectangleGeometry; + this._array.sort(compareFunction); + }; + + /** + * A function used to compare two items while sorting a queue. + * @callback Queue~Comparator + * + * @param {Object} a An item in the array. + * @param {Object} b An item in the array. + * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, + * a positive value if <code>a</code> is greater than <code>b</code>, or + * 0 if <code>a</code> is equal to <code>b</code>. + * + * @example + * function compareNumbers(a, b) { + * return a - b; + * } + */ + + return Queue; }); -define('Core/RectangleOutlineGeometry',[ - './BoundingSphere', +define('Core/PolygonGeometryLibrary',[ + './arrayRemoveDuplicates', './Cartesian3', - './Cartographic', './ComponentDatatype', './defaultValue', './defined', - './DeveloperError', './Ellipsoid', './Geometry', './GeometryAttribute', './GeometryAttributes', + './GeometryPipeline', './IndexDatatype', './Math', './PolygonPipeline', './PrimitiveType', - './Rectangle', - './RectangleGeometryLibrary' + './Queue', + './WindingOrder' ], function( - BoundingSphere, + arrayRemoveDuplicates, Cartesian3, - Cartographic, ComponentDatatype, defaultValue, defined, - DeveloperError, Ellipsoid, Geometry, GeometryAttribute, GeometryAttributes, + GeometryPipeline, IndexDatatype, CesiumMath, PolygonPipeline, PrimitiveType, - Rectangle, - RectangleGeometryLibrary) { + Queue, + WindingOrder) { 'use strict'; - var bottomBoundingSphere = new BoundingSphere(); - var topBoundingSphere = new BoundingSphere(); - var positionScratch = new Cartesian3(); - var rectangleScratch = new Rectangle(); + /** + * @private + */ + var PolygonGeometryLibrary = {}; - function constructRectangle(options) { - var size = options.size; - var height = options.height; - var width = options.width; - var positions = new Float64Array(size * 3); + PolygonGeometryLibrary.computeHierarchyPackedLength = function(polygonHierarchy) { + var numComponents = 0; + var stack = [polygonHierarchy]; + while (stack.length > 0) { + var hierarchy = stack.pop(); + if (!defined(hierarchy)) { + continue; + } - var posIndex = 0; - var row = 0; - var col; - var position = positionScratch; - for (col = 0; col < width; col++) { - RectangleGeometryLibrary.computePosition(options, row, col, position); - positions[posIndex++] = position.x; - positions[posIndex++] = position.y; - positions[posIndex++] = position.z; - } + numComponents += 2; - col = width - 1; - for (row = 1; row < height; row++) { - RectangleGeometryLibrary.computePosition(options, row, col, position); - positions[posIndex++] = position.x; - positions[posIndex++] = position.y; - positions[posIndex++] = position.z; - } + var positions = hierarchy.positions; + var holes = hierarchy.holes; - row = height - 1; - for (col = width-2; col >=0; col--){ - RectangleGeometryLibrary.computePosition(options, row, col, position); - positions[posIndex++] = position.x; - positions[posIndex++] = position.y; - positions[posIndex++] = position.z; - } + if (defined(positions)) { + numComponents += positions.length * Cartesian3.packedLength; + } - col = 0; - for (row = height - 2; row > 0; row--) { - RectangleGeometryLibrary.computePosition(options, row, col, position); - positions[posIndex++] = position.x; - positions[posIndex++] = position.y; - positions[posIndex++] = position.z; + if (defined(holes)) { + var length = holes.length; + for (var i = 0; i < length; ++i) { + stack.push(holes[i]); + } + } } - var indicesSize = positions.length/3 * 2; - var indices = IndexDatatype.createTypedArray(positions.length / 3, indicesSize); + return numComponents; + }; - var index = 0; - for(var i = 0; i < (positions.length/3)-1; i++) { - indices[index++] = i; - indices[index++] = i+1; - } - indices[index++] = (positions.length/3)-1; - indices[index++] = 0; + PolygonGeometryLibrary.packPolygonHierarchy = function(polygonHierarchy, array, startingIndex) { + var stack = [polygonHierarchy]; + while (stack.length > 0) { + var hierarchy = stack.pop(); + if (!defined(hierarchy)) { + continue; + } - var geo = new Geometry({ - attributes : new GeometryAttributes(), - primitiveType : PrimitiveType.LINES - }); + var positions = hierarchy.positions; + var holes = hierarchy.holes; - geo.attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - geo.indices = indices; + array[startingIndex++] = defined(positions) ? positions.length : 0; + array[startingIndex++] = defined(holes) ? holes.length : 0; - return geo; - } + if (defined(positions)) { + var positionsLength = positions.length; + for (var i = 0; i < positionsLength; ++i, startingIndex += 3) { + Cartesian3.pack(positions[i], array, startingIndex); + } + } - function constructExtrudedRectangle(options) { - var surfaceHeight = options.surfaceHeight; - var extrudedHeight = options.extrudedHeight; - var ellipsoid = options.ellipsoid; - var minHeight = Math.min(extrudedHeight, surfaceHeight); - var maxHeight = Math.max(extrudedHeight, surfaceHeight); - var geo = constructRectangle(options); - if (CesiumMath.equalsEpsilon(minHeight, maxHeight, CesiumMath.EPSILON10)) { - return geo; + if (defined(holes)) { + var holesLength = holes.length; + for (var j = 0; j < holesLength; ++j) { + stack.push(holes[j]); + } + } } - var height = options.height; - var width = options.width; - var topPositions = PolygonPipeline.scaleToGeodeticHeight(geo.attributes.position.values, maxHeight, ellipsoid, false); - var length = topPositions.length; - var positions = new Float64Array(length*2); - positions.set(topPositions); - var bottomPositions = PolygonPipeline.scaleToGeodeticHeight(geo.attributes.position.values, minHeight, ellipsoid); - positions.set(bottomPositions, length); - geo.attributes.position.values = positions; + return startingIndex; + }; - var indicesSize = positions.length/3 * 2 + 8; - var indices = IndexDatatype.createTypedArray(positions.length / 3, indicesSize); - length = positions.length/6; - var index = 0; - for (var i = 0; i < length - 1; i++) { - indices[index++] = i; - indices[index++] =i+1; - indices[index++] = i + length; - indices[index++] = i + length + 1; + PolygonGeometryLibrary.unpackPolygonHierarchy = function(array, startingIndex) { + var positionsLength = array[startingIndex++]; + var holesLength = array[startingIndex++]; + + var positions = new Array(positionsLength); + var holes = holesLength > 0 ? new Array(holesLength) : undefined; + + for (var i = 0; i < positionsLength; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); } - indices[index++] = length - 1; - indices[index++] = 0; - indices[index++] = length + length - 1; - indices[index++] = length; - indices[index++] = 0; - indices[index++] = length; - indices[index++] = width-1; - indices[index++] = length + width-1; - indices[index++] = width + height - 2; - indices[index++] = width + height - 2 + length; - indices[index++] = 2*width + height - 3; - indices[index++] = 2*width + height - 3 + length; + for (var j = 0; j < holesLength; ++j) { + holes[j] = PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex); + startingIndex = holes[j].startingIndex; + delete holes[j].startingIndex; + } - geo.indices = indices; + return { + positions : positions, + holes : holes, + startingIndex : startingIndex + }; + }; - return geo; + var distanceScratch = new Cartesian3(); + function getPointAtDistance(p0, p1, distance, length) { + Cartesian3.subtract(p1, p0, distanceScratch); + Cartesian3.multiplyByScalar(distanceScratch, distance / length, distanceScratch); + Cartesian3.add(p0, distanceScratch, distanceScratch); + return [distanceScratch.x, distanceScratch.y, distanceScratch.z]; } - /** - * A description of the outline of a a cartographic rectangle on an ellipsoid centered at the origin. - * - * @alias RectangleOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. - * @param {Number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. - * - * @exception {DeveloperError} <code>options.rectangle.north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. - * @exception {DeveloperError} <code>options.rectangle.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. - * @exception {DeveloperError} <code>options.rectangle.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. - * @exception {DeveloperError} <code>options.rectangle.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. - * @exception {DeveloperError} <code>options.rectangle.north</code> must be greater than <code>rectangle.south</code>. - * - * @see RectangleOutlineGeometry#createGeometry - * - * @example - * var rectangle = new Cesium.RectangleOutlineGeometry({ - * ellipsoid : Cesium.Ellipsoid.WGS84, - * rectangle : Cesium.Rectangle.fromDegrees(-80.0, 39.0, -74.0, 42.0), - * height : 10000.0 - * }); - * var geometry = Cesium.RectangleOutlineGeometry.createGeometry(rectangle); - */ - function RectangleOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + PolygonGeometryLibrary.subdivideLineCount = function(p0, p1, minDistance) { + var distance = Cartesian3.distance(p0, p1); + var n = distance / minDistance; + var countDivide = Math.max(0, Math.ceil(Math.log(n) / Math.log(2))); + return Math.pow(2, countDivide); + }; - var rectangle = options.rectangle; - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var surfaceHeight = defaultValue(options.height, 0.0); - var rotation = defaultValue(options.rotation, 0.0); - var extrudedHeight = options.extrudedHeight; + PolygonGeometryLibrary.subdivideLine = function(p0, p1, minDistance, result) { + var numVertices = PolygonGeometryLibrary.subdivideLineCount(p0, p1, minDistance); + var length = Cartesian3.distance(p0, p1); + var distanceBetweenVertices = length / numVertices; - if (!defined(rectangle)) { - throw new DeveloperError('rectangle is required.'); - } - Rectangle.validate(rectangle); - if (rectangle.north < rectangle.south) { - throw new DeveloperError('options.rectangle.north must be greater than options.rectangle.south'); + if (!defined(result)) { + result = []; } - - this._rectangle = rectangle; - this._granularity = granularity; - this._ellipsoid = ellipsoid; - this._surfaceHeight = surfaceHeight; - this._rotation = rotation; - this._extrudedHeight = extrudedHeight; - this._workerName = 'createRectangleOutlineGeometry'; - } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - RectangleOutlineGeometry.packedLength = Rectangle.packedLength + Ellipsoid.packedLength + 5; + var positions = result; + positions.length = numVertices * 3; - /** - * Stores the provided instance into the provided array. - * - * @param {RectangleOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - RectangleOutlineGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); + var index = 0; + for ( var i = 0; i < numVertices; i++) { + var p = getPointAtDistance(p0, p1, i * distanceBetweenVertices, length); + positions[index++] = p[0]; + positions[index++] = p[1]; + positions[index++] = p[2]; } - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + return positions; + }; - Rectangle.pack(value._rectangle, array, startingIndex); - startingIndex += Rectangle.packedLength; + var scaleToGeodeticHeightN1 = new Cartesian3(); + var scaleToGeodeticHeightN2 = new Cartesian3(); + var scaleToGeodeticHeightP1 = new Cartesian3(); + var scaleToGeodeticHeightP2 = new Cartesian3(); - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + PolygonGeometryLibrary.scaleToGeodeticHeightExtruded = function(geometry, maxHeight, minHeight, ellipsoid, perPositionHeight) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - array[startingIndex++] = value._granularity; - array[startingIndex++] = value._surfaceHeight; - array[startingIndex++] = value._rotation; - array[startingIndex++] = defined(value._extrudedHeight) ? 1.0 : 0.0; - array[startingIndex] = defaultValue(value._extrudedHeight, 0.0); + var n1 = scaleToGeodeticHeightN1; + var n2 = scaleToGeodeticHeightN2; + var p = scaleToGeodeticHeightP1; + var p2 = scaleToGeodeticHeightP2; - return array; - }; + if (defined(geometry) && defined(geometry.attributes) && defined(geometry.attributes.position)) { + var positions = geometry.attributes.position.values; + var length = positions.length / 2; - var scratchRectangle = new Rectangle(); - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchOptions = { - rectangle : scratchRectangle, - ellipsoid : scratchEllipsoid, - granularity : undefined, - height : undefined, - rotation : undefined, - extrudedHeight : undefined - }; + for ( var i = 0; i < length; i += 3) { + Cartesian3.fromArray(positions, i, p); - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {RectangleOutlineGeometry} [result] The object into which to store the result. - * @returns {RectangleOutlineGeometry} The modified result parameter or a new Quaternion instance if one was not provided. - */ - RectangleOutlineGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + ellipsoid.geodeticSurfaceNormal(p, n1); + p2 = ellipsoid.scaleToGeodeticSurface(p, p2); + n2 = Cartesian3.multiplyByScalar(n1, minHeight, n2); + n2 = Cartesian3.add(p2, n2, n2); + positions[i + length] = n2.x; + positions[i + 1 + length] = n2.y; + positions[i + 2 + length] = n2.z; + + if (perPositionHeight) { + p2 = Cartesian3.clone(p, p2); + } + n2 = Cartesian3.multiplyByScalar(n1, maxHeight, n2); + n2 = Cartesian3.add(p2, n2, n2); + positions[i] = n2.x; + positions[i + 1] = n2.y; + positions[i + 2] = n2.z; + } } - - startingIndex = defaultValue(startingIndex, 0); + return geometry; + }; - var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); - startingIndex += Rectangle.packedLength; + PolygonGeometryLibrary.polygonsFromHierarchy = function(polygonHierarchy, perPositionHeight, tangentPlane, ellipsoid) { + // create from a polygon hierarchy + // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf + var hierarchy = []; + var polygons = []; - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + var queue = new Queue(); + queue.enqueue(polygonHierarchy); - var granularity = array[startingIndex++]; - var height = array[startingIndex++]; - var rotation = array[startingIndex++]; - var hasExtrudedHeight = array[startingIndex++]; - var extrudedHeight = array[startingIndex]; + while (queue.length !== 0) { + var outerNode = queue.dequeue(); + var outerRing = outerNode.positions; + var holes = outerNode.holes; - if (!defined(result)) { - scratchOptions.granularity = granularity; - scratchOptions.height = height; - scratchOptions.rotation = rotation; - scratchOptions.extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; - return new RectangleOutlineGeometry(scratchOptions); - } + outerRing = arrayRemoveDuplicates(outerRing, Cartesian3.equalsEpsilon, true); + if (outerRing.length < 3) { + continue; + } - result._rectangle = Rectangle.clone(rectangle, result._rectangle); - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._surfaceHeight = height; - result._rotation = rotation; - result._extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; + var positions2D = tangentPlane.projectPointsOntoPlane(outerRing); + var holeIndices = []; - return result; - }; + var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); + if (originalWindingOrder === WindingOrder.CLOCKWISE) { + positions2D.reverse(); + outerRing = outerRing.slice().reverse(); + } - var nwScratch = new Cartographic(); - /** - * Computes the geometric representation of an outline of a rectangle, including its vertices, indices, and a bounding sphere. - * - * @param {RectangleOutlineGeometry} rectangleGeometry A description of the rectangle outline. - * @returns {Geometry|undefined} The computed vertices and indices. - * - * @exception {DeveloperError} Rotated rectangle is invalid. - */ - RectangleOutlineGeometry.createGeometry = function(rectangleGeometry) { - var rectangle = Rectangle.clone(rectangleGeometry._rectangle, rectangleScratch); - var ellipsoid = rectangleGeometry._ellipsoid; - var surfaceHeight = rectangleGeometry._surfaceHeight; - var extrudedHeight = rectangleGeometry._extrudedHeight; + var positions = outerRing.slice(); + var numChildren = defined(holes) ? holes.length : 0; + var polygonHoles = []; + var i; + var j; - var options = RectangleGeometryLibrary.computeOptions(rectangleGeometry, rectangle, nwScratch); - options.size = 2*options.width + 2*options.height - 4; + for (i = 0; i < numChildren; i++) { + var hole = holes[i]; + var holePositions = arrayRemoveDuplicates(hole.positions, Cartesian3.equalsEpsilon, true); + if (holePositions.length < 3) { + continue; + } - var geometry; - var boundingSphere; - rectangle = rectangleGeometry._rectangle; + var holePositions2D = tangentPlane.projectPointsOntoPlane(holePositions); - if ((CesiumMath.equalsEpsilon(rectangle.north, rectangle.south, CesiumMath.EPSILON10) || - (CesiumMath.equalsEpsilon(rectangle.east, rectangle.west, CesiumMath.EPSILON10)))) { - return undefined; - } - if (defined(extrudedHeight)) { - geometry = constructExtrudedRectangle(options); - var topBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight, topBoundingSphere); - var bottomBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, extrudedHeight, bottomBoundingSphere); - boundingSphere = BoundingSphere.union(topBS, bottomBS); - } else { - geometry = constructRectangle(options); - geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.attributes.position.values, surfaceHeight, ellipsoid, false); - boundingSphere = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight); - } + originalWindingOrder = PolygonPipeline.computeWindingOrder2D(holePositions2D); + if (originalWindingOrder === WindingOrder.CLOCKWISE) { + holePositions2D.reverse(); + holePositions = holePositions.slice().reverse(); + } - return new Geometry({ - attributes : geometry.attributes, - indices : geometry.indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : boundingSphere - }); - }; + polygonHoles.push(holePositions); + holeIndices.push(positions.length); + positions = positions.concat(holePositions); + positions2D = positions2D.concat(holePositions2D); - return RectangleOutlineGeometry; -}); + var numGrandchildren = 0; + if (defined(hole.holes)) { + numGrandchildren = hole.holes.length; + } -define('Core/ReferenceFrame',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + for (j = 0; j < numGrandchildren; j++) { + queue.enqueue(hole.holes[j]); + } + } - /** - * Constants for identifying well-known reference frames. - * - * @exports ReferenceFrame - */ - var ReferenceFrame = { - /** - * The fixed frame. - * - * @type {Number} - * @constant - */ - FIXED : 0, + if (!perPositionHeight) { + for (i = 0; i < outerRing.length; i++) { + ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]); + } + for (i = 0; i < polygonHoles.length; i++) { + var polygonHole = polygonHoles[i]; + for (j = 0; j < polygonHole.length; ++j) { + ellipsoid.scaleToGeodeticSurface(polygonHole[j], polygonHole[j]); + } + } + } - /** - * The inertial frame. - * - * @type {Number} - * @constant - */ - INERTIAL : 1 + hierarchy.push({ + outerRing : outerRing, + holes : polygonHoles + }); + polygons.push({ + positions : positions, + positions2D : positions2D, + holes : holeIndices + }); + } + + return { + hierarchy : hierarchy, + polygons : polygons + }; }; - return freezeObject(ReferenceFrame); -}); + PolygonGeometryLibrary.createGeometryFromPositions = function(ellipsoid, polygon, granularity, perPositionHeight, vertexFormat) { + var indices = PolygonPipeline.triangulate(polygon.positions2D, polygon.holes); -define('Core/requestAnimationFrame',[ - './defined', - './getTimestamp' - ], function( - defined, - getTimestamp) { - 'use strict'; + /* If polygon is completely unrenderable, just use the first three vertices */ + if (indices.length < 3) { + indices = [0, 1, 2]; + } - if (typeof window === 'undefined') { - return; - } + var positions = polygon.positions; - var implementation = window.requestAnimationFrame; + if (perPositionHeight) { + var length = positions.length; + var flattenedPositions = new Array(length * 3); + var index = 0; + for ( var i = 0; i < length; i++) { + var p = positions[i]; + flattenedPositions[index++] = p.x; + flattenedPositions[index++] = p.y; + flattenedPositions[index++] = p.z; + } + var geometry = new Geometry({ + attributes : { + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : flattenedPositions + }) + }, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES + }); - (function() { - // look for vendor prefixed function - if (!defined(implementation)) { - var vendors = ['webkit', 'moz', 'ms', 'o']; - var i = 0; - var len = vendors.length; - while (i < len && !defined(implementation)) { - implementation = window[vendors[i] + 'RequestAnimationFrame']; - ++i; + if (vertexFormat.normal) { + return GeometryPipeline.computeNormal(geometry); } - } - // build an implementation based on setTimeout - if (!defined(implementation)) { - var msPerFrame = 1000.0 / 60.0; - var lastFrameTime = 0; - implementation = function(callback) { - var currentTime = getTimestamp(); + return geometry; + } - // schedule the callback to target 60fps, 16.7ms per frame, - // accounting for the time taken by the callback - var delay = Math.max(msPerFrame - (currentTime - lastFrameTime), 0); - lastFrameTime = currentTime + delay; + return PolygonPipeline.computeSubdivision(ellipsoid, positions, indices, granularity); + }; - return setTimeout(function() { - callback(lastFrameTime); - }, delay); - }; - } - })(); + var computeWallIndicesSubdivided = []; + var p1Scratch = new Cartesian3(); + var p2Scratch = new Cartesian3(); - /** - * A browser-independent function to request a new animation frame. This is used to create - * an application's draw loop as shown in the example below. - * - * @exports requestAnimationFrame - * - * @param {requestAnimationFrame~Callback} callback The function to call when the next frame should be drawn. - * @returns {Number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. - * - * - * @example - * // Create a draw loop using requestAnimationFrame. The - * // tick callback function is called for every animation frame. - * function tick() { - * scene.render(); - * Cesium.requestAnimationFrame(tick); - * } - * tick(); - * - * @see {@link https://www.w3.org/TR/html51/webappapis.html#animation-frames|The Web API Animation Frames interface} - */ - function requestAnimationFrame(callback) { - // we need this extra wrapper function because the native requestAnimationFrame - // functions must be invoked on the global scope (window), which is not the case - // if invoked as Cesium.requestAnimationFrame(callback) - return implementation(callback); - } + PolygonGeometryLibrary.computeWallGeometry = function(positions, ellipsoid, granularity, perPositionHeight) { + var edgePositions; + var topEdgeLength; + var i; + var p1; + var p2; - /** - * A function that will be called when the next frame should be drawn. - * @callback requestAnimationFrame~Callback - * - * @param {Number} timestamp A timestamp for the frame, in milliseconds. - */ + var length = positions.length; + var index = 0; - return requestAnimationFrame; -}); + if (!perPositionHeight) { + var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); -define('Core/sampleTerrain',[ - '../ThirdParty/when', - './Check' - ], function( - when, - Check) { - 'use strict'; + var numVertices = 0; + for (i = 0; i < length; i++) { + numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); + } - /** - * Initiates a terrain height query for an array of {@link Cartographic} positions by - * requesting tiles from a terrain provider, sampling, and interpolating. The interpolation - * matches the triangles used to render the terrain at the specified level. The query - * happens asynchronously, so this function returns a promise that is resolved when - * the query completes. Each point height is modified in place. If a height can not be - * determined because no terrain data is available for the specified level at that location, - * or another error occurs, the height is set to undefined. As is typical of the - * {@link Cartographic} type, the supplied height is a height above the reference ellipsoid - * (such as {@link Ellipsoid.WGS84}) rather than an altitude above mean sea level. In other - * words, it will not necessarily be 0.0 if sampled in the ocean. This function needs the - * terrain level of detail as input, if you need to get the altitude of the terrain as precisely - * as possible (i.e. with maximum level of detail) use {@link sampleTerrainMostDetailed}. - * - * @exports sampleTerrain - * - * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights. - * @param {Number} level The terrain level-of-detail from which to query terrain heights. - * @param {Cartographic[]} positions The positions to update with terrain heights. - * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. - * - * @see sampleTerrainMostDetailed - * - * @example - * // Query the terrain height of two Cartographic positions - * var terrainProvider = new Cesium.CesiumTerrainProvider({ - * url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles' - * }); - * var positions = [ - * Cesium.Cartographic.fromDegrees(86.925145, 27.988257), - * Cesium.Cartographic.fromDegrees(87.0, 28.0) - * ]; - * var promise = Cesium.sampleTerrain(terrainProvider, 11, positions); - * Cesium.when(promise, function(updatedPositions) { - * // positions[0].height and positions[1].height have been updated. - * // updatedPositions is just a reference to positions. - * }); - */ - function sampleTerrain(terrainProvider, level, positions) { - Check.typeOf.object('terrainProvider', terrainProvider); - Check.typeOf.number('level', level); - Check.defined('positions', positions); - - return terrainProvider.readyPromise.then(function() { return doSampling(terrainProvider, level, positions); }); - } + topEdgeLength = (numVertices + length) * 3; + edgePositions = new Array(topEdgeLength * 2); + for (i = 0; i < length; i++) { + p1 = positions[i]; + p2 = positions[(i + 1) % length]; - function doSampling(terrainProvider, level, positions) { - var tilingScheme = terrainProvider.tilingScheme; + var tempPositions = PolygonGeometryLibrary.subdivideLine(p1, p2, minDistance, computeWallIndicesSubdivided); + var tempPositionsLength = tempPositions.length; + for (var j = 0; j < tempPositionsLength; ++j, ++index) { + edgePositions[index] = tempPositions[j]; + edgePositions[index + topEdgeLength] = tempPositions[j]; + } - var i; + edgePositions[index] = p2.x; + edgePositions[index + topEdgeLength] = p2.x; + ++index; - // Sort points into a set of tiles - var tileRequests = []; // Result will be an Array as it's easier to work with - var tileRequestSet = {}; // A unique set - for (i = 0; i < positions.length; ++i) { - var xy = tilingScheme.positionToTileXY(positions[i], level); - var key = xy.toString(); + edgePositions[index] = p2.y; + edgePositions[index + topEdgeLength] = p2.y; + ++index; - if (!tileRequestSet.hasOwnProperty(key)) { - // When tile is requested for the first time - var value = { - x : xy.x, - y : xy.y, - level : level, - tilingScheme : tilingScheme, - terrainProvider : terrainProvider, - positions : [] - }; - tileRequestSet[key] = value; - tileRequests.push(value); + edgePositions[index] = p2.z; + edgePositions[index + topEdgeLength] = p2.z; + ++index; + } + } else { + topEdgeLength = length * 3 * 2; + edgePositions = new Array(topEdgeLength * 2); + for (i = 0; i < length; i++) { + p1 = positions[i]; + p2 = positions[(i + 1) % length]; + edgePositions[index] = edgePositions[index + topEdgeLength] = p1.x; + ++index; + edgePositions[index] = edgePositions[index + topEdgeLength] = p1.y; + ++index; + edgePositions[index] = edgePositions[index + topEdgeLength] = p1.z; + ++index; + edgePositions[index] = edgePositions[index + topEdgeLength] = p2.x; + ++index; + edgePositions[index] = edgePositions[index + topEdgeLength] = p2.y; + ++index; + edgePositions[index] = edgePositions[index + topEdgeLength] = p2.z; + ++index; } - - // Now append to array of points for the tile - tileRequestSet[key].positions.push(positions[i]); } - // Send request for each required tile - var tilePromises = []; - for (i = 0; i < tileRequests.length; ++i) { - var tileRequest = tileRequests[i]; - var requestPromise = tileRequest.terrainProvider.requestTileGeometry(tileRequest.x, tileRequest.y, tileRequest.level); - var tilePromise = when(requestPromise, createInterpolateFunction(tileRequest), createMarkFailedFunction(tileRequest)); - tilePromises.push(tilePromise); - } + length = edgePositions.length; + var indices = IndexDatatype.createTypedArray(length / 3, length - positions.length * 6); + var edgeIndex = 0; + length /= 6; - return when.all(tilePromises, function() { - return positions; - }); - } + for (i = 0; i < length; i++) { + var UL = i; + var UR = UL + 1; + var LL = UL + length; + var LR = LL + 1; - function createInterpolateFunction(tileRequest) { - var tilePositions = tileRequest.positions; - var rectangle = tileRequest.tilingScheme.tileXYToRectangle(tileRequest.x, tileRequest.y, tileRequest.level); - return function(terrainData) { - for (var i = 0; i < tilePositions.length; ++i) { - var position = tilePositions[i]; - position.height = terrainData.interpolateHeight(rectangle, position.longitude, position.latitude); + p1 = Cartesian3.fromArray(edgePositions, UL * 3, p1Scratch); + p2 = Cartesian3.fromArray(edgePositions, UR * 3, p2Scratch); + if (Cartesian3.equalsEpsilon(p1, p2, CesiumMath.EPSILON14)) { + continue; } - }; - } - function createMarkFailedFunction(tileRequest) { - var tilePositions = tileRequest.positions; - return function() { - for (var i = 0; i < tilePositions.length; ++i) { - var position = tilePositions[i]; - position.height = undefined; - } - }; - } + indices[edgeIndex++] = UL; + indices[edgeIndex++] = LL; + indices[edgeIndex++] = UR; + indices[edgeIndex++] = UR; + indices[edgeIndex++] = LL; + indices[edgeIndex++] = LR; + } - return sampleTerrain; + return new Geometry({ + attributes : new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : edgePositions + }) + }), + indices : indices, + primitiveType : PrimitiveType.TRIANGLES + }); + }; + + return PolygonGeometryLibrary; }); -define('Core/sampleTerrainMostDetailed',[ - '../ThirdParty/when', +define('Core/PolygonGeometry',[ + './BoundingRectangle', + './BoundingSphere', + './Cartesian2', + './Cartesian3', + './Cartographic', + './Check', + './ComponentDatatype', + './defaultValue', './defined', + './defineProperties', './DeveloperError', - './sampleTerrain' + './Ellipsoid', + './EllipsoidTangentPlane', + './Geometry', + './GeometryAttribute', + './GeometryInstance', + './GeometryPipeline', + './IndexDatatype', + './Math', + './Matrix3', + './PolygonGeometryLibrary', + './PolygonPipeline', + './Quaternion', + './Rectangle', + './VertexFormat', + './WindingOrder' ], function( - when, + BoundingRectangle, + BoundingSphere, + Cartesian2, + Cartesian3, + Cartographic, + Check, + ComponentDatatype, + defaultValue, defined, + defineProperties, DeveloperError, - sampleTerrain) { + Ellipsoid, + EllipsoidTangentPlane, + Geometry, + GeometryAttribute, + GeometryInstance, + GeometryPipeline, + IndexDatatype, + CesiumMath, + Matrix3, + PolygonGeometryLibrary, + PolygonPipeline, + Quaternion, + Rectangle, + VertexFormat, + WindingOrder) { 'use strict'; - /** - * Initiates a sampleTerrain() request at the maximum available tile level for a terrain dataset. - * - * @exports sampleTerrainMostDetailed - * - * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights. - * @param {Cartographic[]} positions The positions to update with terrain heights. - * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. This - * promise will reject if the terrain provider's `availability` property is undefined. - * - * @example - * // Query the terrain height of two Cartographic positions - * var terrainProvider = new Cesium.CesiumTerrainProvider({ - * url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles' - * }); - * var positions = [ - * Cesium.Cartographic.fromDegrees(86.925145, 27.988257), - * Cesium.Cartographic.fromDegrees(87.0, 28.0) - * ]; - * var promise = Cesium.sampleTerrainMostDetailed(terrainProvider, positions); - * Cesium.when(promise, function(updatedPositions) { - * // positions[0].height and positions[1].height have been updated. - * // updatedPositions is just a reference to positions. - * }); - */ - function sampleTerrainMostDetailed(terrainProvider, positions) { - if (!defined(terrainProvider)) { - throw new DeveloperError('terrainProvider is required.'); - } - if (!defined(positions)) { - throw new DeveloperError('positions is required.'); - } - - return terrainProvider.readyPromise.then(function() { - var byLevel = []; + var computeBoundingRectangleCartesian2 = new Cartesian2(); + var computeBoundingRectangleCartesian3 = new Cartesian3(); + var computeBoundingRectangleQuaternion = new Quaternion(); + var computeBoundingRectangleMatrix3 = new Matrix3(); - var availability = terrainProvider.availability; + function computeBoundingRectangle(tangentPlane, positions, angle, result) { + var rotation = Quaternion.fromAxisAngle(tangentPlane._plane.normal, angle, computeBoundingRectangleQuaternion); + var textureMatrix = Matrix3.fromQuaternion(rotation, computeBoundingRectangleMatrix3); - if (!defined(availability)) { - throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.'); - } - - for (var i = 0; i < positions.length; ++i) { - var position = positions[i]; - var maxLevel = availability.computeMaximumLevelAtPosition(position); + var minX = Number.POSITIVE_INFINITY; + var maxX = Number.NEGATIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + var maxY = Number.NEGATIVE_INFINITY; - var atLevel = byLevel[maxLevel]; - if (!defined(atLevel)) { - byLevel[maxLevel] = atLevel = []; - } - atLevel.push(position); - } + var length = positions.length; + for ( var i = 0; i < length; ++i) { + var p = Cartesian3.clone(positions[i], computeBoundingRectangleCartesian3); + Matrix3.multiplyByVector(textureMatrix, p, p); + var st = tangentPlane.projectPointOntoPlane(p, computeBoundingRectangleCartesian2); - return when.all(byLevel.map(function(positionsAtLevel, index) { - if (defined(positionsAtLevel)) { - return sampleTerrain(terrainProvider, index, positionsAtLevel); - } - })).then(function() { - return positions; - }); - }); - } + if (defined(st)) { + minX = Math.min(minX, st.x); + maxX = Math.max(maxX, st.x); - return sampleTerrainMostDetailed; -}); + minY = Math.min(minY, st.y); + maxY = Math.max(maxY, st.y); + } + } -define('Core/ScreenSpaceEventType',[ - './freezeObject' - ], function( - freezeObject) { - 'use strict'; + result.x = minX; + result.y = minY; + result.width = maxX - minX; + result.height = maxY - minY; + return result; + } - /** - * This enumerated type is for classifying mouse events: down, up, click, double click, move and move while a button is held down. - * - * @exports ScreenSpaceEventType - */ - var ScreenSpaceEventType = { - /** - * Represents a mouse left button down event. - * - * @type {Number} - * @constant - */ - LEFT_DOWN : 0, + var scratchCarto1 = new Cartographic(); + var scratchCarto2 = new Cartographic(); + function adjustPosHeightsForNormal(position, p1, p2, ellipsoid) { + var carto1 = ellipsoid.cartesianToCartographic(position, scratchCarto1); + var height = carto1.height; + var p1Carto = ellipsoid.cartesianToCartographic(p1, scratchCarto2); + p1Carto.height = height; + ellipsoid.cartographicToCartesian(p1Carto, p1); - /** - * Represents a mouse left button up event. - * - * @type {Number} - * @constant - */ - LEFT_UP : 1, + var p2Carto = ellipsoid.cartesianToCartographic(p2, scratchCarto2); + p2Carto.height = height - 100; + ellipsoid.cartographicToCartesian(p2Carto, p2); + } - /** - * Represents a mouse left click event. - * - * @type {Number} - * @constant - */ - LEFT_CLICK : 2, + var scratchBoundingRectangle = new BoundingRectangle(); + var scratchPosition = new Cartesian3(); + var scratchNormal = new Cartesian3(); + var scratchTangent = new Cartesian3(); + var scratchBitangent = new Cartesian3(); + var p1Scratch = new Cartesian3(); + var p2Scratch = new Cartesian3(); + var scratchPerPosNormal = new Cartesian3(); + var scratchPerPosTangent = new Cartesian3(); + var scratchPerPosBitangent = new Cartesian3(); - /** - * Represents a mouse left double click event. - * - * @type {Number} - * @constant - */ - LEFT_DOUBLE_CLICK : 3, + var appendTextureCoordinatesOrigin = new Cartesian2(); + var appendTextureCoordinatesCartesian2 = new Cartesian2(); + var appendTextureCoordinatesCartesian3 = new Cartesian3(); + var appendTextureCoordinatesQuaternion = new Quaternion(); + var appendTextureCoordinatesMatrix3 = new Matrix3(); - /** - * Represents a mouse left button down event. - * - * @type {Number} - * @constant - */ - RIGHT_DOWN : 5, - - /** - * Represents a mouse right button up event. - * - * @type {Number} - * @constant - */ - RIGHT_UP : 6, - - /** - * Represents a mouse right click event. - * - * @type {Number} - * @constant - */ - RIGHT_CLICK : 7, - - /** - * Represents a mouse middle button down event. - * - * @type {Number} - * @constant - */ - MIDDLE_DOWN : 10, + function computeAttributes(options) { + var vertexFormat = options.vertexFormat; + var geometry = options.geometry; + var shadowVolume = options.shadowVolume; + if (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) { + // PERFORMANCE_IDEA: Compute before subdivision, then just interpolate during subdivision. + // PERFORMANCE_IDEA: Compute with createGeometryFromPositions() for fast path when there's no holes. + var boundingRectangle = options.boundingRectangle; + var tangentPlane = options.tangentPlane; + var ellipsoid = options.ellipsoid; + var stRotation = options.stRotation; + var wall = options.wall; + var top = options.top || wall; + var bottom = options.bottom || wall; + var perPositionHeight = options.perPositionHeight; - /** - * Represents a mouse middle button up event. - * - * @type {Number} - * @constant - */ - MIDDLE_UP : 11, + var origin = appendTextureCoordinatesOrigin; + origin.x = boundingRectangle.x; + origin.y = boundingRectangle.y; - /** - * Represents a mouse middle click event. - * - * @type {Number} - * @constant - */ - MIDDLE_CLICK : 12, + var flatPositions = geometry.attributes.position.values; + var length = flatPositions.length; - /** - * Represents a mouse move event. - * - * @type {Number} - * @constant - */ - MOUSE_MOVE : 15, + var textureCoordinates = vertexFormat.st ? new Float32Array(2 * (length / 3)) : undefined; + var normals; + if (vertexFormat.normal) { + if (perPositionHeight && top && !wall) { + normals = geometry.attributes.normal.values; + } else { + normals = new Float32Array(length); + } + } + var tangents = vertexFormat.tangent ? new Float32Array(length) : undefined; + var bitangents = vertexFormat.bitangent ? new Float32Array(length) : undefined; + var extrudeNormals = shadowVolume ? new Float32Array(length) : undefined; - /** - * Represents a mouse wheel event. - * - * @type {Number} - * @constant - */ - WHEEL : 16, + var textureCoordIndex = 0; + var attrIndex = 0; - /** - * Represents the start of a two-finger event on a touch surface. - * - * @type {Number} - * @constant - */ - PINCH_START : 17, + var normal = scratchNormal; + var tangent = scratchTangent; + var bitangent = scratchBitangent; + var recomputeNormal = true; - /** - * Represents the end of a two-finger event on a touch surface. - * - * @type {Number} - * @constant - */ - PINCH_END : 18, + var rotation = Quaternion.fromAxisAngle(tangentPlane._plane.normal, stRotation, appendTextureCoordinatesQuaternion); + var textureMatrix = Matrix3.fromQuaternion(rotation, appendTextureCoordinatesMatrix3); - /** - * Represents a change of a two-finger event on a touch surface. - * - * @type {Number} - * @constant - */ - PINCH_MOVE : 19 - }; + var bottomOffset = 0; + var bottomOffset2 = 0; - return freezeObject(ScreenSpaceEventType); -}); + if (top && bottom) { + bottomOffset = length / 2; + bottomOffset2 = length / 3; -define('Core/ScreenSpaceEventHandler',[ - './AssociativeArray', - './Cartesian2', - './defaultValue', - './defined', - './destroyObject', - './DeveloperError', - './FeatureDetection', - './getTimestamp', - './KeyboardEventModifier', - './ScreenSpaceEventType' - ], function( - AssociativeArray, - Cartesian2, - defaultValue, - defined, - destroyObject, - DeveloperError, - FeatureDetection, - getTimestamp, - KeyboardEventModifier, - ScreenSpaceEventType) { - 'use strict'; + length /= 2; + } - function getPosition(screenSpaceEventHandler, event, result) { - var element = screenSpaceEventHandler._element; - if (element === document) { - result.x = event.clientX; - result.y = event.clientY; - return result; - } + for ( var i = 0; i < length; i += 3) { + var position = Cartesian3.fromArray(flatPositions, i, appendTextureCoordinatesCartesian3); - var rect = element.getBoundingClientRect(); - result.x = event.clientX - rect.left; - result.y = event.clientY - rect.top; - return result; - } + if (vertexFormat.st) { + var p = Matrix3.multiplyByVector(textureMatrix, position, scratchPosition); + p = ellipsoid.scaleToGeodeticSurface(p,p); + var st = tangentPlane.projectPointOntoPlane(p, appendTextureCoordinatesCartesian2); + Cartesian2.subtract(st, origin, st); - function getInputEventKey(type, modifier) { - var key = type; - if (defined(modifier)) { - key += '+' + modifier; - } - return key; - } + var stx = CesiumMath.clamp(st.x / boundingRectangle.width, 0, 1); + var sty = CesiumMath.clamp(st.y / boundingRectangle.height, 0, 1); + if (bottom) { + textureCoordinates[textureCoordIndex + bottomOffset2] = stx; + textureCoordinates[textureCoordIndex + 1 + bottomOffset2] = sty; + } + if (top) { + textureCoordinates[textureCoordIndex] = stx; + textureCoordinates[textureCoordIndex + 1] = sty; + } - function getModifier(event) { - if (event.shiftKey) { - return KeyboardEventModifier.SHIFT; - } else if (event.ctrlKey) { - return KeyboardEventModifier.CTRL; - } else if (event.altKey) { - return KeyboardEventModifier.ALT; - } + textureCoordIndex += 2; + } - return undefined; - } + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) { + var attrIndex1 = attrIndex + 1; + var attrIndex2 = attrIndex + 2; - var MouseButton = { - LEFT : 0, - MIDDLE : 1, - RIGHT : 2 - }; + if (wall) { + if (i + 3 < length) { + var p1 = Cartesian3.fromArray(flatPositions, i + 3, p1Scratch); - function registerListener(screenSpaceEventHandler, domType, element, callback) { - function listener(e) { - callback(screenSpaceEventHandler, e); - } - element.addEventListener(domType, listener, false); + if (recomputeNormal) { + var p2 = Cartesian3.fromArray(flatPositions, i + length, p2Scratch); + if (perPositionHeight) { + adjustPosHeightsForNormal(position, p1, p2, ellipsoid); + } + Cartesian3.subtract(p1, position, p1); + Cartesian3.subtract(p2, position, p2); + normal = Cartesian3.normalize(Cartesian3.cross(p2, p1, normal), normal); + recomputeNormal = false; + } - screenSpaceEventHandler._removalFunctions.push(function() { - element.removeEventListener(domType, listener, false); - }); - } + if (Cartesian3.equalsEpsilon(p1, position, CesiumMath.EPSILON10)) { // if we've reached a corner + recomputeNormal = true; + } + } - function registerListeners(screenSpaceEventHandler) { - var element = screenSpaceEventHandler._element; + if (vertexFormat.tangent || vertexFormat.bitangent) { + bitangent = ellipsoid.geodeticSurfaceNormal(position, bitangent); + if (vertexFormat.tangent) { + tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); + } + } + } else { + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + if (vertexFormat.tangent || vertexFormat.bitangent) { + if (perPositionHeight) { + scratchPerPosNormal = Cartesian3.fromArray(normals, attrIndex, scratchPerPosNormal); + scratchPerPosTangent = Cartesian3.cross(Cartesian3.UNIT_Z, scratchPerPosNormal, scratchPerPosTangent); + scratchPerPosTangent = Cartesian3.normalize(Matrix3.multiplyByVector(textureMatrix, scratchPerPosTangent, scratchPerPosTangent), scratchPerPosTangent); + if (vertexFormat.bitangent) { + scratchPerPosBitangent = Cartesian3.normalize(Cartesian3.cross(scratchPerPosNormal, scratchPerPosTangent, scratchPerPosBitangent), scratchPerPosBitangent); + } + } - // some listeners may be registered on the document, so we still get events even after - // leaving the bounds of element. - // this is affected by the existence of an undocumented disableRootEvents property on element. - var alternateElement = !defined(element.disableRootEvents) ? document : element; + tangent = Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent); + tangent = Cartesian3.normalize(Matrix3.multiplyByVector(textureMatrix, tangent, tangent), tangent); + if (vertexFormat.bitangent) { + bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); + } + } + } - if (FeatureDetection.supportsPointerEvents()) { - registerListener(screenSpaceEventHandler, 'pointerdown', element, handlePointerDown); - registerListener(screenSpaceEventHandler, 'pointerup', element, handlePointerUp); - registerListener(screenSpaceEventHandler, 'pointermove', element, handlePointerMove); - registerListener(screenSpaceEventHandler, 'pointercancel', element, handlePointerUp); - } else { - registerListener(screenSpaceEventHandler, 'mousedown', element, handleMouseDown); - registerListener(screenSpaceEventHandler, 'mouseup', alternateElement, handleMouseUp); - registerListener(screenSpaceEventHandler, 'mousemove', alternateElement, handleMouseMove); - registerListener(screenSpaceEventHandler, 'touchstart', element, handleTouchStart); - registerListener(screenSpaceEventHandler, 'touchend', alternateElement, handleTouchEnd); - registerListener(screenSpaceEventHandler, 'touchmove', alternateElement, handleTouchMove); - registerListener(screenSpaceEventHandler, 'touchcancel', alternateElement, handleTouchEnd); - } + if (vertexFormat.normal) { + if (options.wall) { + normals[attrIndex + bottomOffset] = normal.x; + normals[attrIndex1 + bottomOffset] = normal.y; + normals[attrIndex2 + bottomOffset] = normal.z; + } else if (bottom){ + normals[attrIndex + bottomOffset] = -normal.x; + normals[attrIndex1 + bottomOffset] = -normal.y; + normals[attrIndex2 + bottomOffset] = -normal.z; + } - registerListener(screenSpaceEventHandler, 'dblclick', element, handleDblClick); + if ((top && !perPositionHeight) || wall) { + normals[attrIndex] = normal.x; + normals[attrIndex1] = normal.y; + normals[attrIndex2] = normal.z; + } + } - // detect available wheel event - var wheelEvent; - if ('onwheel' in element) { - // spec event type - wheelEvent = 'wheel'; - } else if (document.onmousewheel !== undefined) { - // legacy event type - wheelEvent = 'mousewheel'; - } else { - // older Firefox - wheelEvent = 'DOMMouseScroll'; - } + if (shadowVolume) { + if (wall) { + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + } + extrudeNormals[attrIndex + bottomOffset] = -normal.x; + extrudeNormals[attrIndex1 + bottomOffset] = -normal.y; + extrudeNormals[attrIndex2 + bottomOffset] = -normal.z; + } - registerListener(screenSpaceEventHandler, wheelEvent, element, handleWheel); - } + if (vertexFormat.tangent) { + if (options.wall) { + tangents[attrIndex + bottomOffset] = tangent.x; + tangents[attrIndex1 + bottomOffset] = tangent.y; + tangents[attrIndex2 + bottomOffset] = tangent.z; + } else if (bottom) { + tangents[attrIndex + bottomOffset] = -tangent.x; + tangents[attrIndex1 + bottomOffset] = -tangent.y; + tangents[attrIndex2 + bottomOffset] = -tangent.z; + } - function unregisterListeners(screenSpaceEventHandler) { - var removalFunctions = screenSpaceEventHandler._removalFunctions; - for (var i = 0; i < removalFunctions.length; ++i) { - removalFunctions[i](); - } - } + if(top) { + if (perPositionHeight) { + tangents[attrIndex] = scratchPerPosTangent.x; + tangents[attrIndex1] = scratchPerPosTangent.y; + tangents[attrIndex2] = scratchPerPosTangent.z; + } else { + tangents[attrIndex] = tangent.x; + tangents[attrIndex1] = tangent.y; + tangents[attrIndex2] = tangent.z; + } + } + } - var mouseDownEvent = { - position : new Cartesian2() - }; + if (vertexFormat.bitangent) { + if (bottom) { + bitangents[attrIndex + bottomOffset] = bitangent.x; + bitangents[attrIndex1 + bottomOffset] = bitangent.y; + bitangents[attrIndex2 + bottomOffset] = bitangent.z; + } + if (top) { + if (perPositionHeight) { + bitangents[attrIndex] = scratchPerPosBitangent.x; + bitangents[attrIndex1] = scratchPerPosBitangent.y; + bitangents[attrIndex2] = scratchPerPosBitangent.z; + } else { + bitangents[attrIndex] = bitangent.x; + bitangents[attrIndex1] = bitangent.y; + bitangents[attrIndex2] = bitangent.z; + } + } + } + attrIndex += 3; + } + } - function gotTouchEvent(screenSpaceEventHandler) { - screenSpaceEventHandler._lastSeenTouchEvent = getTimestamp(); - } + if (vertexFormat.st) { + geometry.attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : textureCoordinates + }); + } - function canProcessMouseEvent(screenSpaceEventHandler) { - return (getTimestamp() - screenSpaceEventHandler._lastSeenTouchEvent) > ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds; - } + if (vertexFormat.normal) { + geometry.attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); + } - function handleMouseDown(screenSpaceEventHandler, event) { - if (!canProcessMouseEvent(screenSpaceEventHandler)) { - return; - } + if (vertexFormat.tangent) { + geometry.attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } - var button = event.button; - screenSpaceEventHandler._buttonDown = button; + if (vertexFormat.bitangent) { + geometry.attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } - var screenSpaceEventType; - if (button === MouseButton.LEFT) { - screenSpaceEventType = ScreenSpaceEventType.LEFT_DOWN; - } else if (button === MouseButton.MIDDLE) { - screenSpaceEventType = ScreenSpaceEventType.MIDDLE_DOWN; - } else if (button === MouseButton.RIGHT) { - screenSpaceEventType = ScreenSpaceEventType.RIGHT_DOWN; - } else { - return; + if (shadowVolume) { + geometry.attributes.extrudeDirection = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : extrudeNormals + }); + } } + return geometry; + } - var position = getPosition(screenSpaceEventHandler, event, screenSpaceEventHandler._primaryPosition); - Cartesian2.clone(position, screenSpaceEventHandler._primaryStartPosition); - Cartesian2.clone(position, screenSpaceEventHandler._primaryPreviousPosition); - - var modifier = getModifier(event); - - var action = screenSpaceEventHandler.getInputAction(screenSpaceEventType, modifier); + var createGeometryFromPositionsExtrudedPositions = []; - if (defined(action)) { - Cartesian2.clone(position, mouseDownEvent.position); + function createGeometryFromPositionsExtruded(ellipsoid, polygon, granularity, hierarchy, perPositionHeight, closeTop, closeBottom, vertexFormat) { + var geos = { + walls : [] + }; + var i; - action(mouseDownEvent); + if (closeTop || closeBottom) { + var topGeo = PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygon, granularity, perPositionHeight, vertexFormat); - event.preventDefault(); - } - } + var edgePoints = topGeo.attributes.position.values; + var indices = topGeo.indices; + var numPositions; + var newIndices; - var mouseUpEvent = { - position : new Cartesian2() - }; - var mouseClickEvent = { - position : new Cartesian2() - }; + if (closeTop && closeBottom) { + var topBottomPositions = edgePoints.concat(edgePoints); - function handleMouseUp(screenSpaceEventHandler, event) { - if (!canProcessMouseEvent(screenSpaceEventHandler)) { - return; - } + numPositions = topBottomPositions.length / 3; - var button = event.button; - screenSpaceEventHandler._buttonDown = undefined; + newIndices = IndexDatatype.createTypedArray(numPositions, indices.length * 2); + newIndices.set(indices); + var ilength = indices.length; - var screenSpaceEventType; - var clickScreenSpaceEventType; - if (button === MouseButton.LEFT) { - screenSpaceEventType = ScreenSpaceEventType.LEFT_UP; - clickScreenSpaceEventType = ScreenSpaceEventType.LEFT_CLICK; - } else if (button === MouseButton.MIDDLE) { - screenSpaceEventType = ScreenSpaceEventType.MIDDLE_UP; - clickScreenSpaceEventType = ScreenSpaceEventType.MIDDLE_CLICK; - } else if (button === MouseButton.RIGHT) { - screenSpaceEventType = ScreenSpaceEventType.RIGHT_UP; - clickScreenSpaceEventType = ScreenSpaceEventType.RIGHT_CLICK; - } else { - return; - } + var length = numPositions / 2; - var modifier = getModifier(event); + for (i = 0; i < ilength; i += 3) { + var i0 = newIndices[i] + length; + var i1 = newIndices[i + 1] + length; + var i2 = newIndices[i + 2] + length; - var action = screenSpaceEventHandler.getInputAction(screenSpaceEventType, modifier); - var clickAction = screenSpaceEventHandler.getInputAction(clickScreenSpaceEventType, modifier); + newIndices[i + ilength] = i2; + newIndices[i + 1 + ilength] = i1; + newIndices[i + 2 + ilength] = i0; + } - if (defined(action) || defined(clickAction)) { - var position = getPosition(screenSpaceEventHandler, event, screenSpaceEventHandler._primaryPosition); + topGeo.attributes.position.values = topBottomPositions; + if (perPositionHeight) { + var normals = topGeo.attributes.normal.values; + topGeo.attributes.normal.values = new Float32Array(topBottomPositions.length); + topGeo.attributes.normal.values.set(normals); + } + topGeo.indices = newIndices; + } else if (closeBottom) { + numPositions = edgePoints.length / 3; + newIndices = IndexDatatype.createTypedArray(numPositions, indices.length); - if (defined(action)) { - Cartesian2.clone(position, mouseUpEvent.position); + for (i = 0; i < indices.length; i += 3) { + newIndices[i] = indices[i + 2]; + newIndices[i + 1] = indices[i + 1]; + newIndices[i + 2] = indices[i]; + } - action(mouseUpEvent); + topGeo.indices = newIndices; } - if (defined(clickAction)) { - var startPosition = screenSpaceEventHandler._primaryStartPosition; - var xDiff = startPosition.x - position.x; - var yDiff = startPosition.y - position.y; - var totalPixels = Math.sqrt(xDiff * xDiff + yDiff * yDiff); - - if (totalPixels < screenSpaceEventHandler._clickPixelTolerance) { - Cartesian2.clone(position, mouseClickEvent.position); + geos.topAndBottom = new GeometryInstance({ + geometry : topGeo + }); - clickAction(mouseClickEvent); - } - } } - } - var mouseMoveEvent = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - }; + var outerRing = hierarchy.outerRing; + var tangentPlane = EllipsoidTangentPlane.fromPoints(outerRing, ellipsoid); + var positions2D = tangentPlane.projectPointsOntoPlane(outerRing, createGeometryFromPositionsExtrudedPositions); - function handleMouseMove(screenSpaceEventHandler, event) { - if (!canProcessMouseEvent(screenSpaceEventHandler)) { - return; + var windingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); + if (windingOrder === WindingOrder.CLOCKWISE) { + outerRing = outerRing.slice().reverse(); } - var modifier = getModifier(event); + var wallGeo = PolygonGeometryLibrary.computeWallGeometry(outerRing, ellipsoid, granularity, perPositionHeight); + geos.walls.push(new GeometryInstance({ + geometry : wallGeo + })); - var position = getPosition(screenSpaceEventHandler, event, screenSpaceEventHandler._primaryPosition); - var previousPosition = screenSpaceEventHandler._primaryPreviousPosition; + var holes = hierarchy.holes; + for (i = 0; i < holes.length; i++) { + var hole = holes[i]; - var action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.MOUSE_MOVE, modifier); + tangentPlane = EllipsoidTangentPlane.fromPoints(hole, ellipsoid); + positions2D = tangentPlane.projectPointsOntoPlane(hole, createGeometryFromPositionsExtrudedPositions); - if (defined(action)) { - Cartesian2.clone(previousPosition, mouseMoveEvent.startPosition); - Cartesian2.clone(position, mouseMoveEvent.endPosition); + windingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); + if (windingOrder === WindingOrder.COUNTER_CLOCKWISE) { + hole = hole.slice().reverse(); + } - action(mouseMoveEvent); + wallGeo = PolygonGeometryLibrary.computeWallGeometry(hole, ellipsoid, granularity); + geos.walls.push(new GeometryInstance({ + geometry : wallGeo + })); } - Cartesian2.clone(position, previousPosition); - - if (defined(screenSpaceEventHandler._buttonDown)) { - event.preventDefault(); - } + return geos; } - var mouseDblClickEvent = { - position : new Cartesian2() - }; - - function handleDblClick(screenSpaceEventHandler, event) { - var button = event.button; - - var screenSpaceEventType; - if (button === MouseButton.LEFT) { - screenSpaceEventType = ScreenSpaceEventType.LEFT_DOUBLE_CLICK; - } else { - return; + /** + * A description of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * + * @alias PolygonGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. + * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. + * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. + * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. + * + * @see PolygonGeometry#createGeometry + * @see PolygonGeometry#fromPositions + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo} + * + * @example + * // 1. create a polygon from points + * var polygon = new Cesium.PolygonGeometry({ + * polygonHierarchy : new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ]) + * ) + * }); + * var geometry = Cesium.PolygonGeometry.createGeometry(polygon); + * + * // 2. create a nested polygon with holes + * var polygonWithHole = new Cesium.PolygonGeometry({ + * polygonHierarchy : new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -109.0, 30.0, + * -95.0, 30.0, + * -95.0, 40.0, + * -109.0, 40.0 + * ]), + * [new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -107.0, 31.0, + * -107.0, 39.0, + * -97.0, 39.0, + * -97.0, 31.0 + * ]), + * [new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -105.0, 33.0, + * -99.0, 33.0, + * -99.0, 37.0, + * -105.0, 37.0 + * ]), + * [new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -103.0, 34.0, + * -101.0, 34.0, + * -101.0, 36.0, + * -103.0, 36.0 + * ]) + * )] + * )] + * )] + * ) + * }); + * var geometry = Cesium.PolygonGeometry.createGeometry(polygonWithHole); + * + * // 3. create extruded polygon + * var extrudedPolygon = new Cesium.PolygonGeometry({ + * polygonHierarchy : new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ]) + * ), + * extrudedHeight: 300000 + * }); + * var geometry = Cesium.PolygonGeometry.createGeometry(extrudedPolygon); + */ + function PolygonGeometry(options) { + Check.typeOf.object('options', options); + Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy); + if (defined(options.perPositionHeight) && options.perPositionHeight && defined(options.height)) { + throw new DeveloperError('Cannot use both options.perPositionHeight and options.height'); } + + var polygonHierarchy = options.polygonHierarchy; + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var stRotation = defaultValue(options.stRotation, 0.0); + var height = defaultValue(options.height, 0.0); + var perPositionHeight = defaultValue(options.perPositionHeight, false); - var modifier = getModifier(event); - - var action = screenSpaceEventHandler.getInputAction(screenSpaceEventType, modifier); - - if (defined(action)) { - getPosition(screenSpaceEventHandler, event, mouseDblClickEvent.position); + var extrudedHeight = options.extrudedHeight; + var extrude = defined(extrudedHeight); - action(mouseDblClickEvent); + if (!perPositionHeight && extrude) { + //Ignore extrudedHeight if it matches height + if (CesiumMath.equalsEpsilon(height, extrudedHeight, CesiumMath.EPSILON10)) { + extrudedHeight = undefined; + extrude = false; + } else { + var h = extrudedHeight; + extrudedHeight = Math.min(h, height); + height = Math.max(h, height); + } } - } - function handleWheel(screenSpaceEventHandler, event) { - // currently this event exposes the delta value in terms of - // the obsolete mousewheel event type. so, for now, we adapt the other - // values to that scheme. - var delta; + this._vertexFormat = VertexFormat.clone(vertexFormat); + this._ellipsoid = Ellipsoid.clone(ellipsoid); + this._granularity = granularity; + this._stRotation = stRotation; + this._height = height; + this._extrudedHeight = defaultValue(extrudedHeight, 0.0); + this._extrude = extrude; + this._closeTop = defaultValue(options.closeTop, true); + this._closeBottom = defaultValue(options.closeBottom, true); + this._polygonHierarchy = polygonHierarchy; + this._perPositionHeight = perPositionHeight; + this._shadowVolume = defaultValue(options.shadowVolume, false); + this._workerName = 'createPolygonGeometry'; - // standard wheel event uses deltaY. sign is opposite wheelDelta. - // deltaMode indicates what unit it is in. - if (defined(event.deltaY)) { - var deltaMode = event.deltaMode; - if (deltaMode === event.DOM_DELTA_PIXEL) { - delta = -event.deltaY; - } else if (deltaMode === event.DOM_DELTA_LINE) { - delta = -event.deltaY * 40; - } else { - // DOM_DELTA_PAGE - delta = -event.deltaY * 120; - } - } else if (event.detail > 0) { - // old Firefox versions use event.detail to count the number of clicks. The sign - // of the integer is the direction the wheel is scrolled. - delta = event.detail * -120; + var positions = polygonHierarchy.positions; + if (!defined(positions) || positions.length < 3) { + this._rectangle = new Rectangle(); } else { - delta = event.wheelDelta; + this._rectangle = Rectangle.fromCartesianArray(positions, ellipsoid); } - if (!defined(delta)) { - return; - } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 10; + } - var modifier = getModifier(event); - var action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.WHEEL, modifier); + /** + * A description of a polygon from an array of positions. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. + * @param {Number} [options.height=0.0] The height of the polygon. + * @param {Number} [options.extrudedHeight] The height of the polygon extrusion. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. + * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. + * @returns {PolygonGeometry} + * + * + * @example + * // create a polygon from points + * var polygon = Cesium.PolygonGeometry.fromPositions({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ]) + * }); + * var geometry = Cesium.PolygonGeometry.createGeometry(polygon); + * + * @see PolygonGeometry#createGeometry + */ + PolygonGeometry.fromPositions = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (defined(action)) { - action(delta); + Check.defined('options.positions', options.positions); + + var newOptions = { + polygonHierarchy : { + positions : options.positions + }, + height : options.height, + extrudedHeight : options.extrudedHeight, + vertexFormat : options.vertexFormat, + stRotation : options.stRotation, + ellipsoid : options.ellipsoid, + granularity : options.granularity, + perPositionHeight : options.perPositionHeight, + closeTop : options.closeTop, + closeBottom: options.closeBottom + }; + return new PolygonGeometry(newOptions); + }; - event.preventDefault(); - } - } + /** + * Stores the provided instance into the provided array. + * + * @param {PolygonGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + PolygonGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - function handleTouchStart(screenSpaceEventHandler, event) { - gotTouchEvent(screenSpaceEventHandler); + startingIndex = PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex); - var changedTouches = event.changedTouches; + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - var i; - var length = changedTouches.length; - var touch; - var identifier; - var positions = screenSpaceEventHandler._positions; + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; - for (i = 0; i < length; ++i) { - touch = changedTouches[i]; - identifier = touch.identifier; - positions.set(identifier, getPosition(screenSpaceEventHandler, touch, new Cartesian2())); - } + Rectangle.pack(value._rectangle, array, startingIndex); + startingIndex += Rectangle.packedLength; - fireTouchEvents(screenSpaceEventHandler, event); + array[startingIndex++] = value._height; + array[startingIndex++] = value._extrudedHeight; + array[startingIndex++] = value._granularity; + array[startingIndex++] = value._stRotation; + array[startingIndex++] = value._extrude ? 1.0 : 0.0; + array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0; + array[startingIndex++] = value._closeTop ? 1.0 : 0.0; + array[startingIndex++] = value._closeBottom ? 1.0 : 0.0; + array[startingIndex++] = value._shadowVolume ? 1.0 : 0.0; + array[startingIndex] = value.packedLength; - var previousPositions = screenSpaceEventHandler._previousPositions; + return array; + }; - for (i = 0; i < length; ++i) { - touch = changedTouches[i]; - identifier = touch.identifier; - previousPositions.set(identifier, Cartesian2.clone(positions.get(identifier))); - } - } + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchVertexFormat = new VertexFormat(); + var scratchRectangle = new Rectangle(); - function handleTouchEnd(screenSpaceEventHandler, event) { - gotTouchEvent(screenSpaceEventHandler); + //Only used to avoid inaability to default construct. + var dummyOptions = { + polygonHierarchy : {} + }; - var changedTouches = event.changedTouches; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {PolygonGeometry} [result] The object into which to store the result. + */ + PolygonGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); - var i; - var length = changedTouches.length; - var touch; - var identifier; - var positions = screenSpaceEventHandler._positions; + var polygonHierarchy = PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex); + startingIndex = polygonHierarchy.startingIndex; + delete polygonHierarchy.startingIndex; - for (i = 0; i < length; ++i) { - touch = changedTouches[i]; - identifier = touch.identifier; - positions.remove(identifier); - } + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - fireTouchEvents(screenSpaceEventHandler, event); + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; - var previousPositions = screenSpaceEventHandler._previousPositions; + var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); + startingIndex += Rectangle.packedLength; - for (i = 0; i < length; ++i) { - touch = changedTouches[i]; - identifier = touch.identifier; - previousPositions.remove(identifier); + var height = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var granularity = array[startingIndex++]; + var stRotation = array[startingIndex++]; + var extrude = array[startingIndex++] === 1.0; + var perPositionHeight = array[startingIndex++] === 1.0; + var closeTop = array[startingIndex++] === 1.0; + var closeBottom = array[startingIndex++] === 1.0; + var shadowVolume = array[startingIndex++] === 1.0; + var packedLength = array[startingIndex]; + + if (!defined(result)) { + result = new PolygonGeometry(dummyOptions); } - } - var touchStartEvent = { - position : new Cartesian2() - }; - var touch2StartEvent = { - position1 : new Cartesian2(), - position2 : new Cartesian2() - }; - var touchEndEvent = { - position : new Cartesian2() - }; - var touchClickEvent = { - position : new Cartesian2() + result._polygonHierarchy = polygonHierarchy; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._height = height; + result._extrudedHeight = extrudedHeight; + result._granularity = granularity; + result._stRotation = stRotation; + result._extrude = extrude; + result._perPositionHeight = perPositionHeight; + result._closeTop = closeTop; + result._closeBottom = closeBottom; + result._rectangle = Rectangle.clone(rectangle); + result._shadowVolume = shadowVolume; + result.packedLength = packedLength; + return result; }; - function fireTouchEvents(screenSpaceEventHandler, event) { - var modifier = getModifier(event); - var positions = screenSpaceEventHandler._positions; - var previousPositions = screenSpaceEventHandler._previousPositions; - var numberOfTouches = positions.length; - var action; - var clickAction; - - if (numberOfTouches !== 1 && screenSpaceEventHandler._buttonDown === MouseButton.LEFT) { - // transitioning from single touch, trigger UP and might trigger CLICK - screenSpaceEventHandler._buttonDown = undefined; - action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.LEFT_UP, modifier); + /** + * Computes the geometric representation of a polygon, including its vertices, indices, and a bounding sphere. + * + * @param {PolygonGeometry} polygonGeometry A description of the polygon. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + PolygonGeometry.createGeometry = function(polygonGeometry) { + var vertexFormat = polygonGeometry._vertexFormat; + var ellipsoid = polygonGeometry._ellipsoid; + var granularity = polygonGeometry._granularity; + var stRotation = polygonGeometry._stRotation; + var height = polygonGeometry._height; + var extrudedHeight = polygonGeometry._extrudedHeight; + var extrude = polygonGeometry._extrude; + var polygonHierarchy = polygonGeometry._polygonHierarchy; + var perPositionHeight = polygonGeometry._perPositionHeight; + var closeTop = polygonGeometry._closeTop; + var closeBottom = polygonGeometry._closeBottom; - if (defined(action)) { - Cartesian2.clone(screenSpaceEventHandler._primaryPosition, touchEndEvent.position); + var outerPositions = polygonHierarchy.positions; + if (outerPositions.length < 3) { + return; + } - action(touchEndEvent); - } + var tangentPlane = EllipsoidTangentPlane.fromPoints(outerPositions, ellipsoid); - if (numberOfTouches === 0) { - // releasing single touch, check for CLICK - clickAction = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.LEFT_CLICK, modifier); + var results = PolygonGeometryLibrary.polygonsFromHierarchy(polygonHierarchy, perPositionHeight, tangentPlane, ellipsoid); + var hierarchy = results.hierarchy; + var polygons = results.polygons; - if (defined(clickAction)) { - var startPosition = screenSpaceEventHandler._primaryStartPosition; - var endPosition = previousPositions.values[0]; - var xDiff = startPosition.x - endPosition.x; - var yDiff = startPosition.y - endPosition.y; - var totalPixels = Math.sqrt(xDiff * xDiff + yDiff * yDiff); + if (hierarchy.length === 0) { + return; + } - if (totalPixels < screenSpaceEventHandler._clickPixelTolerance) { - Cartesian2.clone(screenSpaceEventHandler._primaryPosition, touchClickEvent.position); + outerPositions = hierarchy[0].outerRing; + var boundingRectangle = computeBoundingRectangle(tangentPlane, outerPositions, stRotation, scratchBoundingRectangle); - clickAction(touchClickEvent); - } - } - } + var geometry; + var geometries = []; - // Otherwise don't trigger CLICK, because we are adding more touches. - } + var options = { + perPositionHeight: perPositionHeight, + vertexFormat: vertexFormat, + geometry: undefined, + tangentPlane: tangentPlane, + boundingRectangle: boundingRectangle, + ellipsoid: ellipsoid, + stRotation: stRotation, + bottom: false, + top: true, + wall: false + }; - if (numberOfTouches !== 2 && screenSpaceEventHandler._isPinching) { - // transitioning from pinch, trigger PINCH_END - screenSpaceEventHandler._isPinching = false; + var i; - action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.PINCH_END, modifier); + if (extrude) { + options.top = closeTop; + options.bottom = closeBottom; + options.shadowVolume = polygonGeometry._shadowVolume; + for (i = 0; i < polygons.length; i++) { + geometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], granularity, hierarchy[i], perPositionHeight, closeTop, closeBottom, vertexFormat); - if (defined(action)) { - action(); + var topAndBottom; + if (closeTop && closeBottom) { + topAndBottom = geometry.topAndBottom; + options.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(topAndBottom.geometry, height, extrudedHeight, ellipsoid, perPositionHeight); + } else if (closeTop) { + topAndBottom = geometry.topAndBottom; + topAndBottom.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(topAndBottom.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); + options.geometry = topAndBottom.geometry; + } else if (closeBottom) { + topAndBottom = geometry.topAndBottom; + topAndBottom.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(topAndBottom.geometry.attributes.position.values, extrudedHeight, ellipsoid, true); + options.geometry = topAndBottom.geometry; + } + if (closeTop || closeBottom) { + options.wall = false; + topAndBottom.geometry = computeAttributes(options); + geometries.push(topAndBottom); + } + + var walls = geometry.walls; + options.wall = true; + for ( var k = 0; k < walls.length; k++) { + var wall = walls[k]; + options.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(wall.geometry, height, extrudedHeight, ellipsoid, perPositionHeight); + wall.geometry = computeAttributes(options); + geometries.push(wall); + } + } + } else { + for (i = 0; i < polygons.length; i++) { + geometry = new GeometryInstance({ + geometry : PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygons[i], granularity, perPositionHeight, vertexFormat) + }); + geometry.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); + options.geometry = geometry.geometry; + geometry.geometry = computeAttributes(options); + geometries.push(geometry); } } - if (numberOfTouches === 1) { - // transitioning to single touch, trigger DOWN - var position = positions.values[0]; - Cartesian2.clone(position, screenSpaceEventHandler._primaryPosition); - Cartesian2.clone(position, screenSpaceEventHandler._primaryStartPosition); - Cartesian2.clone(position, screenSpaceEventHandler._primaryPreviousPosition); - - screenSpaceEventHandler._buttonDown = MouseButton.LEFT; - - action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.LEFT_DOWN, modifier); - - if (defined(action)) { - Cartesian2.clone(position, touchStartEvent.position); + geometry = GeometryPipeline.combineInstances(geometries)[0]; + geometry.attributes.position.values = new Float64Array(geometry.attributes.position.values); + geometry.indices = IndexDatatype.createTypedArray(geometry.attributes.position.values.length / 3, geometry.indices); - action(touchStartEvent); - } + var attributes = geometry.attributes; + var boundingSphere = BoundingSphere.fromVertices(attributes.position.values); - event.preventDefault(); + if (!vertexFormat.position) { + delete attributes.position; } - if (numberOfTouches === 2) { - // transitioning to pinch, trigger PINCH_START - screenSpaceEventHandler._isPinching = true; + return new Geometry({ + attributes : attributes, + indices : geometry.indices, + primitiveType : geometry.primitiveType, + boundingSphere : boundingSphere + }); + }; - action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.PINCH_START, modifier); + /** + * @private + */ + PolygonGeometry.createShadowVolume = function(polygonGeometry, minHeightFunc, maxHeightFunc) { + var granularity = polygonGeometry._granularity; + var ellipsoid = polygonGeometry._ellipsoid; - if (defined(action)) { - Cartesian2.clone(positions.values[0], touch2StartEvent.position1); - Cartesian2.clone(positions.values[1], touch2StartEvent.position2); + var minHeight = minHeightFunc(granularity, ellipsoid); + var maxHeight = maxHeightFunc(granularity, ellipsoid); - action(touch2StartEvent); + return new PolygonGeometry({ + polygonHierarchy : polygonGeometry._polygonHierarchy, + ellipsoid : ellipsoid, + stRotation : polygonGeometry._stRotation, + granularity : granularity, + perPositionHeight : false, + extrudedHeight : minHeight, + height : maxHeight, + vertexFormat : VertexFormat.POSITION_ONLY, + shadowVolume: true + }); + }; - // Touch-enabled devices, in particular iOS can have many default behaviours for - // "pinch" events, which can still be executed unless we prevent them here. - event.preventDefault(); + defineProperties(PolygonGeometry.prototype, { + /** + * @private + */ + rectangle : { + get : function() { + return this._rectangle; } } - } - - function handleTouchMove(screenSpaceEventHandler, event) { - gotTouchEvent(screenSpaceEventHandler); - - var changedTouches = event.changedTouches; - - var i; - var length = changedTouches.length; - var touch; - var identifier; - var positions = screenSpaceEventHandler._positions; + }); - for (i = 0; i < length; ++i) { - touch = changedTouches[i]; - identifier = touch.identifier; - var position = positions.get(identifier); - if (defined(position)) { - getPosition(screenSpaceEventHandler, touch, position); - } - } + return PolygonGeometry; +}); - fireTouchMoveEvents(screenSpaceEventHandler, event); +define('Core/PolygonHierarchy',[ + './defined' + ], function( + defined) { + 'use strict'; - var previousPositions = screenSpaceEventHandler._previousPositions; + /** + * An hierarchy of linear rings which define a polygon and its holes. + * The holes themselves may also have holes which nest inner polygons. + * @alias PolygonHierarchy + * @constructor + * + * @param {Cartesian3[]} [positions] A linear ring defining the outer boundary of the polygon or hole. + * @param {PolygonHierarchy[]} [holes] An array of polygon hierarchies defining holes in the polygon. + */ + function PolygonHierarchy(positions, holes) { + /** + * A linear ring defining the outer boundary of the polygon or hole. + * @type {Cartesian3[]} + */ + this.positions = defined(positions) ? positions : []; - for (i = 0; i < length; ++i) { - touch = changedTouches[i]; - identifier = touch.identifier; - Cartesian2.clone(positions.get(identifier), previousPositions.get(identifier)); - } + /** + * An array of polygon hierarchies defining holes in the polygon. + * @type {PolygonHierarchy[]} + */ + this.holes = defined(holes) ? holes : []; } - var touchMoveEvent = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - }; - var touchPinchMovementEvent = { - distance : { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - }, - angleAndHeight : { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - } - }; + return PolygonHierarchy; +}); - function fireTouchMoveEvents(screenSpaceEventHandler, event) { - var modifier = getModifier(event); - var positions = screenSpaceEventHandler._positions; - var previousPositions = screenSpaceEventHandler._previousPositions; - var numberOfTouches = positions.length; - var action; +define('Core/PolygonOutlineGeometry',[ + './arrayRemoveDuplicates', + './BoundingSphere', + './Cartesian3', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './EllipsoidTangentPlane', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './GeometryInstance', + './GeometryPipeline', + './IndexDatatype', + './Math', + './PolygonGeometryLibrary', + './PolygonPipeline', + './PrimitiveType', + './Queue', + './WindingOrder' + ], function( + arrayRemoveDuplicates, + BoundingSphere, + Cartesian3, + Check, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + EllipsoidTangentPlane, + Geometry, + GeometryAttribute, + GeometryAttributes, + GeometryInstance, + GeometryPipeline, + IndexDatatype, + CesiumMath, + PolygonGeometryLibrary, + PolygonPipeline, + PrimitiveType, + Queue, + WindingOrder) { + 'use strict'; + var createGeometryFromPositionsPositions = []; + var createGeometryFromPositionsSubdivided = []; - if (numberOfTouches === 1 && screenSpaceEventHandler._buttonDown === MouseButton.LEFT) { - // moving single touch - var position = positions.values[0]; - Cartesian2.clone(position, screenSpaceEventHandler._primaryPosition); + function createGeometryFromPositions(ellipsoid, positions, minDistance, perPositionHeight) { + var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid); + var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions); - var previousPosition = screenSpaceEventHandler._primaryPreviousPosition; + var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); + if (originalWindingOrder === WindingOrder.CLOCKWISE) { + positions2D.reverse(); + positions = positions.slice().reverse(); + } - action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.MOUSE_MOVE, modifier); + var subdividedPositions; + var i; - if (defined(action)) { - Cartesian2.clone(previousPosition, touchMoveEvent.startPosition); - Cartesian2.clone(position, touchMoveEvent.endPosition); + var length = positions.length; + var index = 0; - action(touchMoveEvent); + if (!perPositionHeight) { + var numVertices = 0; + for (i = 0; i < length; i++) { + numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); } - - Cartesian2.clone(position, previousPosition); - - event.preventDefault(); - } else if (numberOfTouches === 2 && screenSpaceEventHandler._isPinching) { - // moving pinch - - action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.PINCH_MOVE, modifier); - if (defined(action)) { - var position1 = positions.values[0]; - var position2 = positions.values[1]; - var previousPosition1 = previousPositions.values[0]; - var previousPosition2 = previousPositions.values[1]; - - var dX = position2.x - position1.x; - var dY = position2.y - position1.y; - var dist = Math.sqrt(dX * dX + dY * dY) * 0.25; - - var prevDX = previousPosition2.x - previousPosition1.x; - var prevDY = previousPosition2.y - previousPosition1.y; - var prevDist = Math.sqrt(prevDX * prevDX + prevDY * prevDY) * 0.25; - - var cY = (position2.y + position1.y) * 0.125; - var prevCY = (previousPosition2.y + previousPosition1.y) * 0.125; - var angle = Math.atan2(dY, dX); - var prevAngle = Math.atan2(prevDY, prevDX); - - Cartesian2.fromElements(0.0, prevDist, touchPinchMovementEvent.distance.startPosition); - Cartesian2.fromElements(0.0, dist, touchPinchMovementEvent.distance.endPosition); - - Cartesian2.fromElements(prevAngle, prevCY, touchPinchMovementEvent.angleAndHeight.startPosition); - Cartesian2.fromElements(angle, cY, touchPinchMovementEvent.angleAndHeight.endPosition); - - action(touchPinchMovementEvent); + subdividedPositions = new Float64Array(numVertices * 3); + for (i = 0; i < length; i++) { + var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); + var tempPositionsLength = tempPositions.length; + for (var j = 0; j < tempPositionsLength; ++j) { + subdividedPositions[index++] = tempPositions[j]; + } + } + } else { + subdividedPositions = new Float64Array(length * 2 * 3); + for (i = 0; i < length; i++) { + var p0 = positions[i]; + var p1 = positions[(i + 1) % length]; + subdividedPositions[index++] = p0.x; + subdividedPositions[index++] = p0.y; + subdividedPositions[index++] = p0.z; + subdividedPositions[index++] = p1.x; + subdividedPositions[index++] = p1.y; + subdividedPositions[index++] = p1.z; } } - } - - function handlePointerDown(screenSpaceEventHandler, event) { - event.target.setPointerCapture(event.pointerId); - if (event.pointerType === 'touch') { - var positions = screenSpaceEventHandler._positions; + length = subdividedPositions.length / 3; + var indicesSize = length * 2; + var indices = IndexDatatype.createTypedArray(length, indicesSize); + index = 0; + for (i = 0; i < length - 1; i++) { + indices[index++] = i; + indices[index++] = i + 1; + } + indices[index++] = length - 1; + indices[index++] = 0; - var identifier = event.pointerId; - positions.set(identifier, getPosition(screenSpaceEventHandler, event, new Cartesian2())); + return new GeometryInstance({ + geometry : new Geometry({ + attributes : new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : subdividedPositions + }) + }), + indices : indices, + primitiveType : PrimitiveType.LINES + }) + }); + } - fireTouchEvents(screenSpaceEventHandler, event); + function createGeometryFromPositionsExtruded(ellipsoid, positions, minDistance, perPositionHeight) { + var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid); + var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions); - var previousPositions = screenSpaceEventHandler._previousPositions; - previousPositions.set(identifier, Cartesian2.clone(positions.get(identifier))); - } else { - handleMouseDown(screenSpaceEventHandler, event); + var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); + if (originalWindingOrder === WindingOrder.CLOCKWISE) { + positions2D.reverse(); + positions = positions.slice().reverse(); } - } - function handlePointerUp(screenSpaceEventHandler, event) { - if (event.pointerType === 'touch') { - var positions = screenSpaceEventHandler._positions; + var subdividedPositions; + var i; - var identifier = event.pointerId; - positions.remove(identifier); + var length = positions.length; + var corners = new Array(length); + var index = 0; - fireTouchEvents(screenSpaceEventHandler, event); + if (!perPositionHeight) { + var numVertices = 0; + for (i = 0; i < length; i++) { + numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); + } - var previousPositions = screenSpaceEventHandler._previousPositions; - previousPositions.remove(identifier); + subdividedPositions = new Float64Array(numVertices * 3 * 2); + for (i = 0; i < length; ++i) { + corners[i] = index / 3; + var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); + var tempPositionsLength = tempPositions.length; + for (var j = 0; j < tempPositionsLength; ++j) { + subdividedPositions[index++] = tempPositions[j]; + } + } } else { - handleMouseUp(screenSpaceEventHandler, event); + subdividedPositions = new Float64Array(length * 2 * 3 * 2); + for (i = 0; i < length; ++i) { + corners[i] = index / 3; + var p0 = positions[i]; + var p1 = positions[(i + 1) % length]; + + subdividedPositions[index++] = p0.x; + subdividedPositions[index++] = p0.y; + subdividedPositions[index++] = p0.z; + subdividedPositions[index++] = p1.x; + subdividedPositions[index++] = p1.y; + subdividedPositions[index++] = p1.z; + } } - } - function handlePointerMove(screenSpaceEventHandler, event) { - if (event.pointerType === 'touch') { - var positions = screenSpaceEventHandler._positions; + length = subdividedPositions.length / (3 * 2); + var cornersLength = corners.length; - var identifier = event.pointerId; - var position = positions.get(identifier); - if(!defined(position)){ - return; - } + var indicesSize = ((length * 2) + cornersLength) * 2; + var indices = IndexDatatype.createTypedArray(length, indicesSize); - getPosition(screenSpaceEventHandler, event, position); - fireTouchMoveEvents(screenSpaceEventHandler, event); + index = 0; + for (i = 0; i < length; ++i) { + indices[index++] = i; + indices[index++] = (i + 1) % length; + indices[index++] = i + length; + indices[index++] = ((i + 1) % length) + length; + } - var previousPositions = screenSpaceEventHandler._previousPositions; - Cartesian2.clone(positions.get(identifier), previousPositions.get(identifier)); - } else { - handleMouseMove(screenSpaceEventHandler, event); + for (i = 0; i < cornersLength; i++) { + var corner = corners[i]; + indices[index++] = corner; + indices[index++] = corner + length; } + + return new GeometryInstance({ + geometry : new Geometry({ + attributes : new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : subdividedPositions + }) + }), + indices : indices, + primitiveType : PrimitiveType.LINES + }) + }); } /** - * Handles user input events. Custom functions can be added to be executed on - * when the user enters input. + * A description of the outline of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy. * - * @alias ScreenSpaceEventHandler + * @alias PolygonOutlineGeometry + * @constructor * - * @param {Canvas} [element=document] The element to add events to. + * @param {Object} options Object with the following properties: + * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. + * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. + * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. * - * @constructor + * @see PolygonOutlineGeometry#createGeometry + * @see PolygonOutlineGeometry#fromPositions + * + * @example + * // 1. create a polygon outline from points + * var polygon = new Cesium.PolygonOutlineGeometry({ + * polygonHierarchy : new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ]) + * ) + * }); + * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon); + * + * // 2. create a nested polygon with holes outline + * var polygonWithHole = new Cesium.PolygonOutlineGeometry({ + * polygonHierarchy : new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -109.0, 30.0, + * -95.0, 30.0, + * -95.0, 40.0, + * -109.0, 40.0 + * ]), + * [new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -107.0, 31.0, + * -107.0, 39.0, + * -97.0, 39.0, + * -97.0, 31.0 + * ]), + * [new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -105.0, 33.0, + * -99.0, 33.0, + * -99.0, 37.0, + * -105.0, 37.0 + * ]), + * [new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -103.0, 34.0, + * -101.0, 34.0, + * -101.0, 36.0, + * -103.0, 36.0 + * ]) + * )] + * )] + * )] + * ) + * }); + * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygonWithHole); + * + * // 3. create extruded polygon outline + * var extrudedPolygon = new Cesium.PolygonOutlineGeometry({ + * polygonHierarchy : new Cesium.PolygonHierarchy( + * Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ]) + * ), + * extrudedHeight: 300000 + * }); + * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(extrudedPolygon); */ - function ScreenSpaceEventHandler(element) { - this._inputEvents = {}; - this._buttonDown = undefined; - this._isPinching = false; - this._lastSeenTouchEvent = -ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds; - - this._primaryStartPosition = new Cartesian2(); - this._primaryPosition = new Cartesian2(); - this._primaryPreviousPosition = new Cartesian2(); - - this._positions = new AssociativeArray(); - this._previousPositions = new AssociativeArray(); + function PolygonOutlineGeometry(options) { + Check.typeOf.object('options', options); + Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy); - this._removalFunctions = []; + if (defined(options.perPositionHeight) && options.perPositionHeight && defined(options.height)) { + throw new DeveloperError('Cannot use both options.perPositionHeight and options.height'); + } + + var polygonHierarchy = options.polygonHierarchy; + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var height = defaultValue(options.height, 0.0); + var perPositionHeight = defaultValue(options.perPositionHeight, false); - // TODO: Revisit when doing mobile development. May need to be configurable - // or determined based on the platform? - this._clickPixelTolerance = 5; + var extrudedHeight = options.extrudedHeight; + var extrude = defined(extrudedHeight); + if (extrude && !perPositionHeight) { + var h = extrudedHeight; + extrudedHeight = Math.min(h, height); + height = Math.max(h, height); + } - this._element = defaultValue(element, document); + this._ellipsoid = Ellipsoid.clone(ellipsoid); + this._granularity = granularity; + this._height = height; + this._extrudedHeight = defaultValue(extrudedHeight, 0.0); + this._extrude = extrude; + this._polygonHierarchy = polygonHierarchy; + this._perPositionHeight = perPositionHeight; + this._workerName = 'createPolygonOutlineGeometry'; - registerListeners(this); + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + Ellipsoid.packedLength + 6; } /** - * Set a function to be executed on an input event. + * Stores the provided instance into the provided array. * - * @param {Function} action Function to be executed when the input event occurs. - * @param {Number} type The ScreenSpaceEventType of input event. - * @param {Number} [modifier] A KeyboardEventModifier key that is held when a <code>type</code> - * event occurs. + * @param {PolygonOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @see ScreenSpaceEventHandler#getInputAction - * @see ScreenSpaceEventHandler#removeInputAction + * @returns {Number[]} The array that was packed into */ - ScreenSpaceEventHandler.prototype.setInputAction = function(action, type, modifier) { - if (!defined(action)) { - throw new DeveloperError('action is required.'); - } - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } + PolygonOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); - var key = getInputEventKey(type, modifier); - this._inputEvents[key] = action; + startingIndex = defaultValue(startingIndex, 0); + + startingIndex = PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex); + + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; + + array[startingIndex++] = value._height; + array[startingIndex++] = value._extrudedHeight; + array[startingIndex++] = value._granularity; + array[startingIndex++] = value._extrude ? 1.0 : 0.0; + array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0; + array[startingIndex++] = value.packedLength; + + return array; }; - /** - * Returns the function to be executed on an input event. - * - * @param {Number} type The ScreenSpaceEventType of input event. - * @param {Number} [modifier] A KeyboardEventModifier key that is held when a <code>type</code> - * event occurs. - * - * @see ScreenSpaceEventHandler#setInputAction - * @see ScreenSpaceEventHandler#removeInputAction - */ - ScreenSpaceEventHandler.prototype.getInputAction = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - var key = getInputEventKey(type, modifier); - return this._inputEvents[key]; + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var dummyOptions = { + polygonHierarchy : {} }; /** - * Removes the function to be executed on an input event. - * - * @param {Number} type The ScreenSpaceEventType of input event. - * @param {Number} [modifier] A KeyboardEventModifier key that is held when a <code>type</code> - * event occurs. + * Retrieves an instance from a packed array. * - * @see ScreenSpaceEventHandler#getInputAction - * @see ScreenSpaceEventHandler#setInputAction + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {PolygonOutlineGeometry} [result] The object into which to store the result. + * @returns {PolygonOutlineGeometry} The modified result parameter or a new PolygonOutlineGeometry instance if one was not provided. */ - ScreenSpaceEventHandler.prototype.removeInputAction = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } + PolygonOutlineGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); - var key = getInputEventKey(type, modifier); - delete this._inputEvents[key]; - }; + startingIndex = defaultValue(startingIndex, 0); - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see ScreenSpaceEventHandler#destroy - */ - ScreenSpaceEventHandler.prototype.isDestroyed = function() { - return false; - }; + var polygonHierarchy = PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex); + startingIndex = polygonHierarchy.startingIndex; + delete polygonHierarchy.startingIndex; - /** - * Removes listeners held by this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * handler = handler && handler.destroy(); - * - * @see ScreenSpaceEventHandler#isDestroyed - */ - ScreenSpaceEventHandler.prototype.destroy = function() { - unregisterListeners(this); + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - return destroyObject(this); - }; + var height = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var granularity = array[startingIndex++]; + var extrude = array[startingIndex++] === 1.0; + var perPositionHeight = array[startingIndex++] === 1.0; + var packedLength = array[startingIndex++]; - /** - * The amount of time, in milliseconds, that mouse events will be disabled after - * receiving any touch events, such that any emulated mouse events will be ignored. - * @type {Number} - * @default 800 - */ - ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds = 800; + if (!defined(result)) { + result = new PolygonOutlineGeometry(dummyOptions); + } - return ScreenSpaceEventHandler; -}); + result._polygonHierarchy = polygonHierarchy; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._height = height; + result._extrudedHeight = extrudedHeight; + result._granularity = granularity; + result._extrude = extrude; + result._perPositionHeight = perPositionHeight; + result.packedLength = packedLength; -define('Core/ShowGeometryInstanceAttribute',[ - './ComponentDatatype', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError' - ], function( - ComponentDatatype, - defaultValue, - defined, - defineProperties, - DeveloperError) { - 'use strict'; + return result; + }; /** - * Value and type information for per-instance geometry attribute that determines if the geometry instance will be shown. - * - * @alias ShowGeometryInstanceAttribute - * @constructor + * A description of a polygon outline from an array of positions. * - * @param {Boolean} [show=true] Determines if the geometry instance will be shown. + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. + * @param {Number} [options.height=0.0] The height of the polygon. + * @param {Number} [options.extrudedHeight] The height of the polygon extrusion. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @returns {PolygonOutlineGeometry} * * * @example - * var instance = new Cesium.GeometryInstance({ - * geometry : new Cesium.BoxGeometry({ - * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL, - * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0), - * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0) - * }), - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), - * id : 'box', - * attributes : { - * show : new Cesium.ShowGeometryInstanceAttribute(false) - * } + * // create a polygon from points + * var polygon = Cesium.PolygonOutlineGeometry.fromPositions({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0, + * -75.0, 30.0, + * -70.0, 30.0, + * -68.0, 40.0 + * ]) * }); + * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon); * - * @see GeometryInstance - * @see GeometryInstanceAttribute + * @see PolygonOutlineGeometry#createGeometry */ - function ShowGeometryInstanceAttribute(show) { - show = defaultValue(show, true); + PolygonOutlineGeometry.fromPositions = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The values for the attributes stored in a typed array. - * - * @type Uint8Array - * - * @default [1.0] - */ - this.value = ShowGeometryInstanceAttribute.toValue(show); - } + Check.defined('options.positions', options.positions); + + var newOptions = { + polygonHierarchy : { + positions : options.positions + }, + height : options.height, + extrudedHeight : options.extrudedHeight, + ellipsoid : options.ellipsoid, + granularity : options.granularity, + perPositionHeight : options.perPositionHeight + }; + return new PolygonOutlineGeometry(newOptions); + }; - defineProperties(ShowGeometryInstanceAttribute.prototype, { - /** - * The datatype of each component in the attribute, e.g., individual elements in - * {@link ColorGeometryInstanceAttribute#value}. - * - * @memberof ShowGeometryInstanceAttribute.prototype - * - * @type {ComponentDatatype} - * @readonly - * - * @default {@link ComponentDatatype.UNSIGNED_BYTE} - */ - componentDatatype : { - get : function() { - return ComponentDatatype.UNSIGNED_BYTE; - } - }, + /** + * Computes the geometric representation of a polygon outline, including its vertices, indices, and a bounding sphere. + * + * @param {PolygonOutlineGeometry} polygonGeometry A description of the polygon outline. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + PolygonOutlineGeometry.createGeometry = function(polygonGeometry) { + var ellipsoid = polygonGeometry._ellipsoid; + var granularity = polygonGeometry._granularity; + var height = polygonGeometry._height; + var extrudedHeight = polygonGeometry._extrudedHeight; + var extrude = polygonGeometry._extrude; + var polygonHierarchy = polygonGeometry._polygonHierarchy; + var perPositionHeight = polygonGeometry._perPositionHeight; - /** - * The number of components in the attributes, i.e., {@link ColorGeometryInstanceAttribute#value}. - * - * @memberof ShowGeometryInstanceAttribute.prototype - * - * @type {Number} - * @readonly - * - * @default 1 - */ - componentsPerAttribute : { - get : function() { - return 1; + // create from a polygon hierarchy + // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf + var polygons = []; + var queue = new Queue(); + queue.enqueue(polygonHierarchy); + var i; + while (queue.length !== 0) { + var outerNode = queue.dequeue(); + var outerRing = outerNode.positions; + outerRing = arrayRemoveDuplicates(outerRing, Cartesian3.equalsEpsilon, true); + if (outerRing.length < 3) { + continue; } - }, - /** - * When <code>true</code> and <code>componentDatatype</code> is an integer format, - * indicate that the components should be mapped to the range [0, 1] (unsigned) - * or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * - * @memberof ShowGeometryInstanceAttribute.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - normalize : { - get : function() { - return false; + var numChildren = outerNode.holes ? outerNode.holes.length : 0; + // The outer polygon contains inner polygons + for (i = 0; i < numChildren; i++) { + var hole = outerNode.holes[i]; + hole.positions = arrayRemoveDuplicates(hole.positions, Cartesian3.equalsEpsilon, true); + if (hole.positions.length < 3) { + continue; + } + polygons.push(hole.positions); + + var numGrandchildren = 0; + if (defined(hole.holes)) { + numGrandchildren = hole.holes.length; + } + + for ( var j = 0; j < numGrandchildren; j++) { + queue.enqueue(hole.holes[j]); + } } + + polygons.push(outerRing); } - }); - /** - * Converts a boolean show to a typed array that can be used to assign a show attribute. - * - * @param {Boolean} show The show value. - * @param {Uint8Array} [result] The array to store the result in, if undefined a new instance will be created. - * @returns {Uint8Array} The modified result parameter or a new instance if result was undefined. - * - * @example - * var attributes = primitive.getGeometryInstanceAttributes('an id'); - * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true, attributes.show); - */ - ShowGeometryInstanceAttribute.toValue = function(show, result) { - if (!defined(show)) { - throw new DeveloperError('show is required.'); + if (polygons.length === 0) { + return undefined; } - - if (!defined(result)) { - return new Uint8Array([show]); + + var geometry; + var geometries = []; + var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + + if (extrude) { + for (i = 0; i < polygons.length; i++) { + geometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], minDistance, perPositionHeight); + geometry.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(geometry.geometry, height, extrudedHeight, ellipsoid, perPositionHeight); + geometries.push(geometry); + } + } else { + for (i = 0; i < polygons.length; i++) { + geometry = createGeometryFromPositions(ellipsoid, polygons[i], minDistance, perPositionHeight); + geometry.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); + geometries.push(geometry); + } } - result[0] = show; - return result; + + geometry = GeometryPipeline.combineInstances(geometries)[0]; + var boundingSphere = BoundingSphere.fromVertices(geometry.attributes.position.values); + + return new Geometry({ + attributes : geometry.attributes, + indices : geometry.indices, + primitiveType : geometry.primitiveType, + boundingSphere : boundingSphere + }); }; - return ShowGeometryInstanceAttribute; + return PolygonOutlineGeometry; }); -define('Core/Simon1994PlanetaryPositions',[ +define('Core/PolylineGeometry',[ + './arrayRemoveDuplicates', + './BoundingSphere', './Cartesian3', + './Color', + './ComponentDatatype', + './defaultValue', './defined', './DeveloperError', - './JulianDate', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './GeometryType', + './IndexDatatype', './Math', - './Matrix3', - './TimeConstants', - './TimeStandard' + './PolylinePipeline', + './PrimitiveType', + './VertexFormat' ], function( + arrayRemoveDuplicates, + BoundingSphere, Cartesian3, + Color, + ComponentDatatype, + defaultValue, defined, DeveloperError, - JulianDate, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + GeometryType, + IndexDatatype, CesiumMath, - Matrix3, - TimeConstants, - TimeStandard) { + PolylinePipeline, + PrimitiveType, + VertexFormat) { 'use strict'; - /** - * Contains functions for finding the Cartesian coordinates of the sun and the moon in the - * Earth-centered inertial frame. - * - * @exports Simon1994PlanetaryPositions - */ - var Simon1994PlanetaryPositions = {}; + var scratchInterpolateColorsArray = []; - function computeTdbMinusTtSpice(daysSinceJ2000InTerrestrialTime) { - /* STK Comments ------------------------------------------------------ - * This function uses constants designed to be consistent with - * the SPICE Toolkit from JPL version N0051 (unitim.c) - * M0 = 6.239996 - * M0Dot = 1.99096871e-7 rad/s = 0.01720197 rad/d - * EARTH_ECC = 1.671e-2 - * TDB_AMPL = 1.657e-3 secs - *--------------------------------------------------------------------*/ - - //* Values taken as specified in STK Comments except: 0.01720197 rad/day = 1.99096871e-7 rad/sec - //* Here we use the more precise value taken from the SPICE value 1.99096871e-7 rad/sec converted to rad/day - //* All other constants are consistent with the SPICE implementation of the TDB conversion - //* except where we treat the independent time parameter to be in TT instead of TDB. - //* This is an approximation made to facilitate performance due to the higher prevalance of - //* the TT2TDB conversion over TDB2TT in order to avoid having to iterate when converting to TDB for the JPL ephemeris. - //* Days are used instead of seconds to provide a slight improvement in numerical precision. - - //* For more information see: - //* http://www.cv.nrao.edu/~rfisher/Ephemerides/times.html#TDB - //* ftp://ssd.jpl.nasa.gov/pub/eph/planets/ioms/ExplSupplChap8.pdf - - var g = 6.239996 + (0.0172019696544) * daysSinceJ2000InTerrestrialTime; - return 1.657e-3 * Math.sin(g + 1.671e-2 * Math.sin(g)); - } - - var TdtMinusTai = 32.184; - var J2000d = 2451545; - function taiToTdb(date, result) { - //Converts TAI to TT - result = JulianDate.addSeconds(date, TdtMinusTai, result); - - //Converts TT to TDB - var days = JulianDate.totalDays(result) - J2000d; - result = JulianDate.addSeconds(result, computeTdbMinusTtSpice(days), result); - - return result; - } - - var epoch = new JulianDate(2451545, 0, TimeStandard.TAI); //Actually TDB (not TAI) - var MetersPerKilometer = 1000.0; - var RadiansPerDegree = CesiumMath.RADIANS_PER_DEGREE; - var RadiansPerArcSecond = CesiumMath.RADIANS_PER_ARCSECOND; - var MetersPerAstronomicalUnit = 1.49597870e+11; // IAU 1976 value - - var perifocalToEquatorial = new Matrix3(); - function elementsToCartesian(semimajorAxis, eccentricity, inclination, longitudeOfPerigee, longitudeOfNode, meanLongitude, result) { - if (inclination < 0.0) { - inclination = -inclination; - longitudeOfNode += CesiumMath.PI; - } - - if (inclination < 0 || inclination > CesiumMath.PI) { - throw new DeveloperError('The inclination is out of range. Inclination must be greater than or equal to zero and less than or equal to Pi radians.'); - } - - var radiusOfPeriapsis = semimajorAxis * (1.0 - eccentricity); - var argumentOfPeriapsis = longitudeOfPerigee - longitudeOfNode; - var rightAscensionOfAscendingNode = longitudeOfNode; - var trueAnomaly = meanAnomalyToTrueAnomaly(meanLongitude - longitudeOfPerigee, eccentricity); - var type = chooseOrbit(eccentricity, 0.0); - - if (type === 'Hyperbolic' && Math.abs(CesiumMath.negativePiToPi(trueAnomaly)) >= Math.acos(- 1.0 / eccentricity)) { - throw new DeveloperError('The true anomaly of the hyperbolic orbit lies outside of the bounds of the hyperbola.'); - } - - perifocalToCartesianMatrix(argumentOfPeriapsis, inclination, rightAscensionOfAscendingNode, perifocalToEquatorial); - var semilatus = radiusOfPeriapsis * (1.0 + eccentricity); - var costheta = Math.cos(trueAnomaly); - var sintheta = Math.sin(trueAnomaly); - - var denom = (1.0 + eccentricity * costheta); - - if (denom <= CesiumMath.Epsilon10) { - throw new DeveloperError('elements cannot be converted to cartesian'); - } - - var radius = semilatus / denom; - if (!defined(result)) { - result = new Cartesian3(radius * costheta, radius * sintheta, 0.0); - } else { - result.x = radius * costheta; - result.y = radius * sintheta; - result.z = 0.0; - } - - return Matrix3.multiplyByVector(perifocalToEquatorial, result, result); - } - - function chooseOrbit(eccentricity, tolerance) { - if (eccentricity < 0) { - throw new DeveloperError('eccentricity cannot be negative.'); - } - - if (eccentricity <= tolerance) { - return 'Circular'; - } else if (eccentricity < 1.0 - tolerance) { - return 'Elliptical'; - } else if (eccentricity <= 1.0 + tolerance) { - return 'Parabolic'; - } - return 'Hyperbolic'; - } - - // Calculates the true anomaly given the mean anomaly and the eccentricity. - function meanAnomalyToTrueAnomaly(meanAnomaly, eccentricity) { - if (eccentricity < 0.0 || eccentricity >= 1.0) { - throw new DeveloperError('eccentricity out of range.'); - } - - var eccentricAnomaly = meanAnomalyToEccentricAnomaly(meanAnomaly, eccentricity); - return eccentricAnomalyToTrueAnomaly(eccentricAnomaly, eccentricity); - } - - var maxIterationCount = 50; - var keplerEqConvergence = CesiumMath.EPSILON8; - // Calculates the eccentric anomaly given the mean anomaly and the eccentricity. - function meanAnomalyToEccentricAnomaly(meanAnomaly, eccentricity) { - if (eccentricity < 0.0 || eccentricity >= 1.0) { - throw new DeveloperError('eccentricity out of range.'); - } - - var revs = Math.floor(meanAnomaly / CesiumMath.TWO_PI); - - // Find angle in current revolution - meanAnomaly -= revs * CesiumMath.TWO_PI; - - // calculate starting value for iteration sequence - var iterationValue = meanAnomaly + (eccentricity * Math.sin(meanAnomaly)) / - (1.0 - Math.sin(meanAnomaly + eccentricity) + Math.sin(meanAnomaly)); - - // Perform Newton-Raphson iteration on Kepler's equation - var eccentricAnomaly = Number.MAX_VALUE; - - var count; - for (count = 0; - count < maxIterationCount && Math.abs(eccentricAnomaly - iterationValue) > keplerEqConvergence; - ++count) - { - eccentricAnomaly = iterationValue; - var NRfunction = eccentricAnomaly - eccentricity * Math.sin(eccentricAnomaly) - meanAnomaly; - var dNRfunction = 1 - eccentricity * Math.cos(eccentricAnomaly); - iterationValue = eccentricAnomaly - NRfunction / dNRfunction; - } - - if (count >= maxIterationCount) { - throw new DeveloperError('Kepler equation did not converge'); - // STK Components uses a numerical method to find the eccentric anomaly in the case that Kepler's - // equation does not converge. We don't expect that to ever be necessary for the reasonable orbits used here. - } - - eccentricAnomaly = iterationValue + revs * CesiumMath.TWO_PI; - return eccentricAnomaly; - } - - // Calculates the true anomaly given the eccentric anomaly and the eccentricity. - function eccentricAnomalyToTrueAnomaly(eccentricAnomaly, eccentricity) { - if (eccentricity < 0.0 || eccentricity >= 1.0) { - throw new DeveloperError('eccentricity out of range.'); - } - - // Calculate the number of previous revolutions - var revs = Math.floor(eccentricAnomaly / CesiumMath.TWO_PI); - - // Find angle in current revolution - eccentricAnomaly -= revs * CesiumMath.TWO_PI; - - // Calculate true anomaly from eccentric anomaly - var trueAnomalyX = Math.cos(eccentricAnomaly) - eccentricity; - var trueAnomalyY = Math.sin(eccentricAnomaly) * Math.sqrt(1 - eccentricity * eccentricity); - - var trueAnomaly = Math.atan2(trueAnomalyY, trueAnomalyX); - - // Ensure the correct quadrant - trueAnomaly = CesiumMath.zeroToTwoPi(trueAnomaly); - if (eccentricAnomaly < 0) - { - trueAnomaly -= CesiumMath.TWO_PI; - } - - // Add on previous revolutions - trueAnomaly += revs * CesiumMath.TWO_PI; - - return trueAnomaly; - } - - // Calculates the transformation matrix to convert from the perifocal (PQW) coordinate - // system to inertial cartesian coordinates. - function perifocalToCartesianMatrix(argumentOfPeriapsis, inclination, rightAscension, result) { - if (inclination < 0 || inclination > CesiumMath.PI) { - throw new DeveloperError('inclination out of range'); - } - - var cosap = Math.cos(argumentOfPeriapsis); - var sinap = Math.sin(argumentOfPeriapsis); - - var cosi = Math.cos(inclination); - var sini = Math.sin(inclination); - - var cosraan = Math.cos(rightAscension); - var sinraan = Math.sin(rightAscension); - if (!defined(result)) { - result = new Matrix3( - cosraan * cosap - sinraan * sinap * cosi, - -cosraan * sinap - sinraan * cosap * cosi, - sinraan * sini, - - sinraan * cosap + cosraan * sinap * cosi, - -sinraan * sinap + cosraan * cosap * cosi, - -cosraan * sini, - - sinap * sini, - cosap * sini, - cosi); - } else { - result[0] = cosraan * cosap - sinraan * sinap * cosi; - result[1] = sinraan * cosap + cosraan * sinap * cosi; - result[2] = sinap * sini; - result[3] = -cosraan * sinap - sinraan * cosap * cosi; - result[4] = -sinraan * sinap + cosraan * cosap * cosi; - result[5] = cosap * sini; - result[6] = sinraan * sini; - result[7] = -cosraan * sini; - result[8] = cosi; - } - return result; - } - - // From section 5.8 - var semiMajorAxis0 = 1.0000010178 * MetersPerAstronomicalUnit; - var meanLongitude0 = 100.46645683 * RadiansPerDegree; - var meanLongitude1 = 1295977422.83429 * RadiansPerArcSecond; - - // From table 6 - var p1u = 16002; - var p2u = 21863; - var p3u = 32004; - var p4u = 10931; - var p5u = 14529; - var p6u = 16368; - var p7u = 15318; - var p8u = 32794; - - var Ca1 = 64 * 1e-7 * MetersPerAstronomicalUnit; - var Ca2 = -152 * 1e-7 * MetersPerAstronomicalUnit; - var Ca3 = 62 * 1e-7 * MetersPerAstronomicalUnit; - var Ca4 = -8 * 1e-7 * MetersPerAstronomicalUnit; - var Ca5 = 32 * 1e-7 * MetersPerAstronomicalUnit; - var Ca6 = -41 * 1e-7 * MetersPerAstronomicalUnit; - var Ca7 = 19 * 1e-7 * MetersPerAstronomicalUnit; - var Ca8 = -11 * 1e-7 * MetersPerAstronomicalUnit; - - var Sa1 = -150 * 1e-7 * MetersPerAstronomicalUnit; - var Sa2 = -46 * 1e-7 * MetersPerAstronomicalUnit; - var Sa3 = 68 * 1e-7 * MetersPerAstronomicalUnit; - var Sa4 = 54 * 1e-7 * MetersPerAstronomicalUnit; - var Sa5 = 14 * 1e-7 * MetersPerAstronomicalUnit; - var Sa6 = 24 * 1e-7 * MetersPerAstronomicalUnit; - var Sa7 = -28 * 1e-7 * MetersPerAstronomicalUnit; - var Sa8 = 22 * 1e-7 * MetersPerAstronomicalUnit; - - var q1u = 10; - var q2u = 16002; - var q3u = 21863; - var q4u = 10931; - var q5u = 1473; - var q6u = 32004; - var q7u = 4387; - var q8u = 73; - - var Cl1 = -325 * 1e-7; - var Cl2 = -322 * 1e-7; - var Cl3 = -79 * 1e-7; - var Cl4 = 232 * 1e-7; - var Cl5 = -52 * 1e-7; - var Cl6 = 97 * 1e-7; - var Cl7 = 55 * 1e-7; - var Cl8 = -41 * 1e-7; - - var Sl1 = -105 * 1e-7; - var Sl2 = -137 * 1e-7; - var Sl3 = 258 * 1e-7; - var Sl4 = 35 * 1e-7; - var Sl5 = -116 * 1e-7; - var Sl6 = -88 * 1e-7; - var Sl7 = -112 * 1e-7; - var Sl8 = -80 * 1e-7; - - var scratchDate = new JulianDate(0, 0.0, TimeStandard.TAI); - /** - * Gets a point describing the motion of the Earth-Moon barycenter according to the equations - * described in section 6. - */ - - function computeSimonEarthMoonBarycenter(date, result) { - - // t is thousands of years from J2000 TDB - taiToTdb(date, scratchDate); - var x = (scratchDate.dayNumber - epoch.dayNumber) + ((scratchDate.secondsOfDay - epoch.secondsOfDay)/TimeConstants.SECONDS_PER_DAY); - var t = x / (TimeConstants.DAYS_PER_JULIAN_CENTURY * 10.0); - - var u = 0.35953620 * t; - var semimajorAxis = semiMajorAxis0 + - Ca1 * Math.cos(p1u * u) + Sa1 * Math.sin(p1u * u) + - Ca2 * Math.cos(p2u * u) + Sa2 * Math.sin(p2u * u) + - Ca3 * Math.cos(p3u * u) + Sa3 * Math.sin(p3u * u) + - Ca4 * Math.cos(p4u * u) + Sa4 * Math.sin(p4u * u) + - Ca5 * Math.cos(p5u * u) + Sa5 * Math.sin(p5u * u) + - Ca6 * Math.cos(p6u * u) + Sa6 * Math.sin(p6u * u) + - Ca7 * Math.cos(p7u * u) + Sa7 * Math.sin(p7u * u) + - Ca8 * Math.cos(p8u * u) + Sa8 * Math.sin(p8u * u); - var meanLongitude = meanLongitude0 + meanLongitude1 * t + - Cl1 * Math.cos(q1u * u) + Sl1 * Math.sin(q1u * u) + - Cl2 * Math.cos(q2u * u) + Sl2 * Math.sin(q2u * u) + - Cl3 * Math.cos(q3u * u) + Sl3 * Math.sin(q3u * u) + - Cl4 * Math.cos(q4u * u) + Sl4 * Math.sin(q4u * u) + - Cl5 * Math.cos(q5u * u) + Sl5 * Math.sin(q5u * u) + - Cl6 * Math.cos(q6u * u) + Sl6 * Math.sin(q6u * u) + - Cl7 * Math.cos(q7u * u) + Sl7 * Math.sin(q7u * u) + - Cl8 * Math.cos(q8u * u) + Sl8 * Math.sin(q8u * u); - - // All constants in this part are from section 5.8 - var eccentricity = 0.0167086342 - 0.0004203654 * t; - var longitudeOfPerigee = 102.93734808 * RadiansPerDegree + 11612.35290 * RadiansPerArcSecond * t; - var inclination = 469.97289 * RadiansPerArcSecond * t; - var longitudeOfNode = 174.87317577 * RadiansPerDegree - 8679.27034 * RadiansPerArcSecond * t; - - return elementsToCartesian(semimajorAxis, eccentricity, inclination, longitudeOfPerigee, - longitudeOfNode, meanLongitude, result); - } - - /** - * Gets a point describing the position of the moon according to the equations described in section 4. - */ - function computeSimonMoon(date, result) { - taiToTdb(date, scratchDate); - var x = (scratchDate.dayNumber - epoch.dayNumber) + ((scratchDate.secondsOfDay - epoch.secondsOfDay)/TimeConstants.SECONDS_PER_DAY); - var t = x / (TimeConstants.DAYS_PER_JULIAN_CENTURY); - var t2 = t * t; - var t3 = t2 * t; - var t4 = t3 * t; - - // Terms from section 3.4 (b.1) - var semimajorAxis = 383397.7725 + 0.0040 * t; - var eccentricity = 0.055545526 - 0.000000016 * t; - var inclinationConstant = 5.15668983 * RadiansPerDegree; - var inclinationSecPart = -0.00008 * t + 0.02966 * t2 - - 0.000042 * t3 - 0.00000013 * t4; - var longitudeOfPerigeeConstant = 83.35324312 * RadiansPerDegree; - var longitudeOfPerigeeSecPart = 14643420.2669 * t - 38.2702 * t2 - - 0.045047 * t3 + 0.00021301 * t4; - var longitudeOfNodeConstant = 125.04455501 * RadiansPerDegree; - var longitudeOfNodeSecPart = -6967919.3631 * t + 6.3602 * t2 + - 0.007625 * t3 - 0.00003586 * t4; - var meanLongitudeConstant = 218.31664563 * RadiansPerDegree; - var meanLongitudeSecPart = 1732559343.48470 * t - 6.3910 * t2 + - 0.006588 * t3 - 0.00003169 * t4; - - // Delaunay arguments from section 3.5 b - var D = 297.85019547 * RadiansPerDegree + RadiansPerArcSecond * - (1602961601.2090 * t - 6.3706 * t2 + 0.006593 * t3 - 0.00003169 * t4); - var F = 93.27209062 * RadiansPerDegree + RadiansPerArcSecond * - (1739527262.8478 * t - 12.7512 * t2 - 0.001037 * t3 + 0.00000417 * t4); - var l = 134.96340251 * RadiansPerDegree + RadiansPerArcSecond * - (1717915923.2178 * t + 31.8792 * t2 + 0.051635 * t3 - 0.00024470 * t4); - var lprime = 357.52910918 * RadiansPerDegree + RadiansPerArcSecond * - (129596581.0481 * t - 0.5532 * t2 + 0.000136 * t3 - 0.00001149 * t4); - var psi = 310.17137918 * RadiansPerDegree - RadiansPerArcSecond * - (6967051.4360 * t + 6.2068 * t2 + 0.007618 * t3 - 0.00003219 * t4); - - // Add terms from Table 4 - var twoD = 2.0 * D; - var fourD = 4.0 * D; - var sixD = 6.0 * D; - var twol = 2.0 * l; - var threel = 3.0 * l; - var fourl = 4.0 * l; - var twoF = 2.0 * F; - semimajorAxis += 3400.4 * Math.cos(twoD) - 635.6 * Math.cos(twoD - l) - - 235.6 * Math.cos(l) + 218.1 * Math.cos(twoD - lprime) + - 181.0 * Math.cos(twoD + l); - eccentricity += 0.014216 * Math.cos(twoD - l) + 0.008551 * Math.cos(twoD - twol) - - 0.001383 * Math.cos(l) + 0.001356 * Math.cos(twoD + l) - - 0.001147 * Math.cos(fourD - threel) - 0.000914 * Math.cos(fourD - twol) + - 0.000869 * Math.cos(twoD - lprime - l) - 0.000627 * Math.cos(twoD) - - 0.000394 * Math.cos(fourD - fourl) + 0.000282 * Math.cos(twoD - lprime - twol) - - 0.000279 * Math.cos(D - l) - 0.000236 * Math.cos(twol) + - 0.000231 * Math.cos(fourD) + 0.000229 * Math.cos(sixD - fourl) - - 0.000201 * Math.cos(twol - twoF); - inclinationSecPart += 486.26 * Math.cos(twoD - twoF) - 40.13 * Math.cos(twoD) + - 37.51 * Math.cos(twoF) + 25.73 * Math.cos(twol - twoF) + - 19.97 * Math.cos(twoD - lprime - twoF); - longitudeOfPerigeeSecPart += -55609 * Math.sin(twoD - l) - 34711 * Math.sin(twoD - twol) - - 9792 * Math.sin(l) + 9385 * Math.sin(fourD - threel) + - 7505 * Math.sin(fourD - twol) + 5318 * Math.sin(twoD + l) + - 3484 * Math.sin(fourD - fourl) - 3417 * Math.sin(twoD - lprime - l) - - 2530 * Math.sin(sixD - fourl) - 2376 * Math.sin(twoD) - - 2075 * Math.sin(twoD - threel) - 1883 * Math.sin(twol) - - 1736 * Math.sin(sixD - 5.0 * l) + 1626 * Math.sin(lprime) - - 1370 * Math.sin(sixD - threel); - longitudeOfNodeSecPart += -5392 * Math.sin(twoD - twoF) - 540 * Math.sin(lprime) - - 441 * Math.sin(twoD) + 423 * Math.sin(twoF) - - 288 * Math.sin(twol - twoF); - meanLongitudeSecPart += -3332.9 * Math.sin(twoD) + 1197.4 * Math.sin(twoD - l) - - 662.5 * Math.sin(lprime) + 396.3 * Math.sin(l) - - 218.0 * Math.sin(twoD - lprime); - - // Add terms from Table 5 - var twoPsi = 2.0 * psi; - var threePsi = 3.0 * psi; - inclinationSecPart += 46.997 * Math.cos(psi) * t - 0.614 * Math.cos(twoD - twoF + psi) * t + - 0.614 * Math.cos(twoD - twoF - psi) * t - 0.0297 * Math.cos(twoPsi) * t2 - - 0.0335 * Math.cos(psi) * t2 + 0.0012 * Math.cos(twoD - twoF + twoPsi) * t2 - - 0.00016 * Math.cos(psi) * t3 + 0.00004 * Math.cos(threePsi) * t3 + - 0.00004 * Math.cos(twoPsi) * t3; - var perigeeAndMean = 2.116 * Math.sin(psi) * t - 0.111 * Math.sin(twoD - twoF - psi) * t - - 0.0015 * Math.sin(psi) * t2; - longitudeOfPerigeeSecPart += perigeeAndMean; - meanLongitudeSecPart += perigeeAndMean; - longitudeOfNodeSecPart += -520.77 * Math.sin(psi) * t + 13.66 * Math.sin(twoD - twoF + psi) * t + - 1.12 * Math.sin(twoD - psi) * t - 1.06 * Math.sin(twoF - psi) * t + - 0.660 * Math.sin(twoPsi) * t2 + 0.371 * Math.sin(psi) * t2 - - 0.035 * Math.sin(twoD - twoF + twoPsi) * t2 - 0.015 * Math.sin(twoD - twoF + psi) * t2 + - 0.0014 * Math.sin(psi) * t3 - 0.0011 * Math.sin(threePsi) * t3 - - 0.0009 * Math.sin(twoPsi) * t3; - - // Add constants and convert units - semimajorAxis *= MetersPerKilometer; - var inclination = inclinationConstant + inclinationSecPart * RadiansPerArcSecond; - var longitudeOfPerigee = longitudeOfPerigeeConstant + longitudeOfPerigeeSecPart * RadiansPerArcSecond; - var meanLongitude = meanLongitudeConstant + meanLongitudeSecPart * RadiansPerArcSecond; - var longitudeOfNode = longitudeOfNodeConstant + longitudeOfNodeSecPart * RadiansPerArcSecond; - - return elementsToCartesian(semimajorAxis, eccentricity, inclination, longitudeOfPerigee, - longitudeOfNode, meanLongitude, result); - } - - /** - * Gets a point describing the motion of the Earth. This point uses the Moon point and - * the 1992 mu value (ratio between Moon and Earth masses) in Table 2 of the paper in order - * to determine the position of the Earth relative to the Earth-Moon barycenter. - */ - var moonEarthMassRatio = 0.012300034; // From 1992 mu value in Table 2 - var factor = moonEarthMassRatio / (moonEarthMassRatio + 1.0) * -1; - function computeSimonEarth(date, result) { - result = computeSimonMoon(date, result); - return Cartesian3.multiplyByScalar(result, factor, result); - } - - // Values for the <code>axesTransformation</code> needed for the rotation were found using the STK Components - // GreographicTransformer on the position of the sun center of mass point and the earth J2000 frame. - - var axesTransformation = new Matrix3(1.0000000000000002, 5.619723173785822e-16, 4.690511510146299e-19, - -5.154129427414611e-16, 0.9174820620691819, -0.39777715593191376, - -2.23970096136568e-16, 0.39777715593191376, 0.9174820620691819); - var translation = new Cartesian3(); - /** - * Computes the position of the Sun in the Earth-centered inertial frame - * - * @param {JulianDate} [julianDate] The time at which to compute the Sun's position, if not provided the current system time is used. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} Calculated sun position - */ - Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame= function(julianDate, result){ - if (!defined(julianDate)) { - julianDate = JulianDate.now(); - } - - if (!defined(result)) { - result = new Cartesian3(); - } - - //first forward transformation - translation = computeSimonEarthMoonBarycenter(julianDate, translation); - result = Cartesian3.negate(translation, result); - - //second forward transformation - computeSimonEarth(julianDate, translation); - - Cartesian3.subtract(result, translation, result); - Matrix3.multiplyByVector(axesTransformation, result, result); - - return result; - }; - - /** - * Computes the position of the Moon in the Earth-centered inertial frame - * - * @param {JulianDate} [julianDate] The time at which to compute the Sun's position, if not provided the current system time is used. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} Calculated moon position - */ - Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame = function(julianDate, result){ - if (!defined(julianDate)) { - julianDate = JulianDate.now(); - } - - result = computeSimonMoon(julianDate, result); - Matrix3.multiplyByVector(axesTransformation, result, result); - - return result; - }; - - return Simon1994PlanetaryPositions; -}); - -define('Core/SimplePolylineGeometry',[ - './BoundingSphere', - './Cartesian3', - './Color', - './ComponentDatatype', - './defaultValue', - './defined', - './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PolylinePipeline', - './PrimitiveType' - ], function( - BoundingSphere, - Cartesian3, - Color, - ComponentDatatype, - defaultValue, - defined, - DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PolylinePipeline, - PrimitiveType) { - 'use strict'; - - function interpolateColors(p0, p1, color0, color1, minDistance, array, offset) { - var numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance); + function interpolateColors(p0, p1, color0, color1, numPoints) { + var colors = scratchInterpolateColorsArray; + colors.length = numPoints; var i; var r0 = color0.red; @@ -77686,12 +74420,9 @@ define('Core/SimplePolylineGeometry',[ if (Color.equals(color0, color1)) { for (i = 0; i < numPoints; i++) { - array[offset++] = Color.floatToByte(r0); - array[offset++] = Color.floatToByte(g0); - array[offset++] = Color.floatToByte(b0); - array[offset++] = Color.floatToByte(a0); + colors[i] = Color.clone(color0); } - return offset; + return colors; } var redPerVertex = (r1 - r0) / numPoints; @@ -77699,68 +74430,77 @@ define('Core/SimplePolylineGeometry',[ var bluePerVertex = (b1 - b0) / numPoints; var alphaPerVertex = (a1 - a0) / numPoints; - var index = offset; for (i = 0; i < numPoints; i++) { - array[index++] = Color.floatToByte(r0 + i * redPerVertex); - array[index++] = Color.floatToByte(g0 + i * greenPerVertex); - array[index++] = Color.floatToByte(b0 + i * bluePerVertex); - array[index++] = Color.floatToByte(a0 + i * alphaPerVertex); + colors[i] = new Color(r0 + i * redPerVertex, g0 + i * greenPerVertex, b0 + i * bluePerVertex, a0 + i * alphaPerVertex); } - return index; + return colors; } /** * A description of a polyline modeled as a line strip; the first two positions define a line segment, - * and each additional position defines a line segment from the previous position. + * and each additional position defines a line segment from the previous position. The polyline is capable of + * displaying with a material. * - * @alias SimplePolylineGeometry + * @alias PolylineGeometry * @constructor * * @param {Object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of {@link Cartesian3} defining the positions in the polyline as a line strip. + * @param {Number} [options.width=1.0] The width in pixels. * @param {Color[]} [options.colors] An Array of {@link Color} defining the per vertex or per segment colors. * @param {Boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. * @param {Boolean} [options.followSurface=true] A boolean that determines whether positions will be adjusted to the surface of the ellipsoid via a great arc. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.followSurface=true. Determines the number of positions in the buffer. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * * @exception {DeveloperError} At least two positions are required. + * @exception {DeveloperError} width must be greater than or equal to one. * @exception {DeveloperError} colors has an invalid length. * - * @see SimplePolylineGeometry#createGeometry + * @see PolylineGeometry#createGeometry + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo} * * @example * // A polyline with two connected line segments - * var polyline = new Cesium.SimplePolylineGeometry({ + * var polyline = new Cesium.PolylineGeometry({ * positions : Cesium.Cartesian3.fromDegreesArray([ * 0.0, 0.0, * 5.0, 0.0, * 5.0, 5.0 - * ]) + * ]), + * width : 10.0 * }); - * var geometry = Cesium.SimplePolylineGeometry.createGeometry(polyline); + * var geometry = Cesium.PolylineGeometry.createGeometry(polyline); */ - function SimplePolylineGeometry(options) { + function PolylineGeometry(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); var positions = options.positions; var colors = options.colors; + var width = defaultValue(options.width, 1.0); var colorsPerVertex = defaultValue(options.colorsPerVertex, false); if ((!defined(positions)) || (positions.length < 2)) { throw new DeveloperError('At least two positions are required.'); } + if (typeof width !== 'number') { + throw new DeveloperError('width must be a number'); + } if (defined(colors) && ((colorsPerVertex && colors.length < positions.length) || (!colorsPerVertex && colors.length < positions.length - 1))) { throw new DeveloperError('colors has an invalid length.'); } this._positions = positions; this._colors = colors; + this._width = width; this._colorsPerVertex = colorsPerVertex; + this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); this._followSurface = defaultValue(options.followSurface, true); this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - this._workerName = 'createSimplePolylineGeometry'; + this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); + this._workerName = 'createPolylineGeometry'; var numComponents = 1 + positions.length * Cartesian3.packedLength; numComponents += defined(colors) ? 1 + colors.length * Color.packedLength : 1; @@ -77769,19 +74509,19 @@ define('Core/SimplePolylineGeometry',[ * The number of elements used to pack the object into an array. * @type {Number} */ - this.packedLength = numComponents + Ellipsoid.packedLength + 3; + this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 4; } /** * Stores the provided instance into the provided array. * - * @param {SimplePolylineGeometry} value The value to pack. + * @param {PolylineGeometry} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - SimplePolylineGeometry.pack = function(value, array, startingIndex) { + PolylineGeometry.pack = function(value, array, startingIndex) { if (!defined(value)) { throw new DeveloperError('value is required'); } @@ -77812,6 +74552,10 @@ define('Core/SimplePolylineGeometry',[ Ellipsoid.pack(value._ellipsoid, array, startingIndex); startingIndex += Ellipsoid.packedLength; + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + + array[startingIndex++] = value._width; array[startingIndex++] = value._colorsPerVertex ? 1.0 : 0.0; array[startingIndex++] = value._followSurface ? 1.0 : 0.0; array[startingIndex] = value._granularity; @@ -77819,15 +74563,28 @@ define('Core/SimplePolylineGeometry',[ return array; }; + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchVertexFormat = new VertexFormat(); + var scratchOptions = { + positions : undefined, + colors : undefined, + ellipsoid : scratchEllipsoid, + vertexFormat : scratchVertexFormat, + width : undefined, + colorsPerVertex : undefined, + followSurface : undefined, + granularity : undefined + }; + /** * Retrieves an instance from a packed array. * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {SimplePolylineGeometry} [result] The object into which to store the result. - * @returns {SimplePolylineGeometry} The modified result parameter or a new SimplePolylineGeometry instance if one was not provided. + * @param {PolylineGeometry} [result] The object into which to store the result. + * @returns {PolylineGeometry} The modified result parameter or a new PolylineGeometry instance if one was not provided. */ - SimplePolylineGeometry.unpack = function(array, startingIndex, result) { + PolylineGeometry.unpack = function(array, startingIndex, result) { if (!defined(array)) { throw new DeveloperError('array is required'); } @@ -77850,27 +74607,32 @@ define('Core/SimplePolylineGeometry',[ colors[i] = Color.unpack(array, startingIndex); } - var ellipsoid = Ellipsoid.unpack(array, startingIndex); + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); startingIndex += Ellipsoid.packedLength; + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; + + var width = array[startingIndex++]; var colorsPerVertex = array[startingIndex++] === 1.0; var followSurface = array[startingIndex++] === 1.0; var granularity = array[startingIndex]; if (!defined(result)) { - return new SimplePolylineGeometry({ - positions : positions, - colors : colors, - ellipsoid : ellipsoid, - colorsPerVertex : colorsPerVertex, - followSurface : followSurface, - granularity : granularity - }); + scratchOptions.positions = positions; + scratchOptions.colors = colors; + scratchOptions.width = width; + scratchOptions.colorsPerVertex = colorsPerVertex; + scratchOptions.followSurface = followSurface; + scratchOptions.granularity = granularity; + return new PolylineGeometry(scratchOptions); } result._positions = positions; result._colors = colors; - result._ellipsoid = ellipsoid; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._width = width; result._colorsPerVertex = colorsPerVertex; result._followSurface = followSurface; result._granularity = granularity; @@ -77878,264 +74640,549 @@ define('Core/SimplePolylineGeometry',[ return result; }; - var scratchArray1 = new Array(2); - var scratchArray2 = new Array(2); - var generateArcOptionsScratch = { - positions : scratchArray1, - height: scratchArray2, - ellipsoid: undefined, - minDistance : undefined - }; + var scratchCartesian3 = new Cartesian3(); + var scratchPosition = new Cartesian3(); + var scratchPrevPosition = new Cartesian3(); + var scratchNextPosition = new Cartesian3(); /** - * Computes the geometric representation of a simple polyline, including its vertices, indices, and a bounding sphere. + * Computes the geometric representation of a polyline, including its vertices, indices, and a bounding sphere. * - * @param {SimplePolylineGeometry} simplePolylineGeometry A description of the polyline. - * @returns {Geometry} The computed vertices and indices. + * @param {PolylineGeometry} polylineGeometry A description of the polyline. + * @returns {Geometry|undefined} The computed vertices and indices. */ - SimplePolylineGeometry.createGeometry = function(simplePolylineGeometry) { - var positions = simplePolylineGeometry._positions; - var colors = simplePolylineGeometry._colors; - var colorsPerVertex = simplePolylineGeometry._colorsPerVertex; - var followSurface = simplePolylineGeometry._followSurface; - var granularity = simplePolylineGeometry._granularity; - var ellipsoid = simplePolylineGeometry._ellipsoid; - - var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); - var perSegmentColors = defined(colors) && !colorsPerVertex; + PolylineGeometry.createGeometry = function(polylineGeometry) { + var width = polylineGeometry._width; + var vertexFormat = polylineGeometry._vertexFormat; + var colors = polylineGeometry._colors; + var colorsPerVertex = polylineGeometry._colorsPerVertex; + var followSurface = polylineGeometry._followSurface; + var granularity = polylineGeometry._granularity; + var ellipsoid = polylineGeometry._ellipsoid; var i; - var length = positions.length; + var j; + var k; - var positionValues; - var numberOfPositions; - var colorValues; - var color; - var offset = 0; + var positions = arrayRemoveDuplicates(polylineGeometry._positions, Cartesian3.equalsEpsilon); + var positionsLength = positions.length; + + // A width of a pixel or less is not a valid geometry, but in order to support external data + // that may have errors we treat this as an empty geometry. + if (positionsLength < 2 || width <= 0.0) { + return undefined; + } if (followSurface) { var heights = PolylinePipeline.extractHeights(positions, ellipsoid); - var generateArcOptions = generateArcOptionsScratch; - generateArcOptions.minDistance = minDistance; - generateArcOptions.ellipsoid = ellipsoid; + var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); - if (perSegmentColors) { - var positionCount = 0; - for (i = 0; i < length - 1; i++) { - positionCount += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance) + 1; + if (defined(colors)) { + var colorLength = 1; + for (i = 0; i < positionsLength - 1; ++i) { + colorLength += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance); } - positionValues = new Float64Array(positionCount * 3); - colorValues = new Uint8Array(positionCount * 4); + var newColors = new Array(colorLength); + var newColorIndex = 0; - generateArcOptions.positions = scratchArray1; - generateArcOptions.height= scratchArray2; + for (i = 0; i < positionsLength - 1; ++i) { + var p0 = positions[i]; + var p1 = positions[i+1]; + var c0 = colors[i]; - var ci = 0; - for (i = 0; i < length - 1; ++i) { - scratchArray1[0] = positions[i]; - scratchArray1[1] = positions[i + 1]; + var numColors = PolylinePipeline.numberOfPoints(p0, p1, minDistance); + if (colorsPerVertex && i < colorLength) { + var c1 = colors[i+1]; + var interpolatedColors = interpolateColors(p0, p1, c0, c1, numColors); + var interpolatedColorsLength = interpolatedColors.length; + for (j = 0; j < interpolatedColorsLength; ++j) { + newColors[newColorIndex++] = interpolatedColors[j]; + } + } else { + for (j = 0; j < numColors; ++j) { + newColors[newColorIndex++] = Color.clone(c0); + } + } + } - scratchArray2[0] = heights[i]; - scratchArray2[1] = heights[i + 1]; + newColors[newColorIndex] = Color.clone(colors[colors.length-1]); + colors = newColors; - var pos = PolylinePipeline.generateArc(generateArcOptions); + scratchInterpolateColorsArray.length = 0; + } - if (defined(colors)) { - var segLen = pos.length / 3; - color = colors[i]; - for(var k = 0; k < segLen; ++k) { - colorValues[ci++] = Color.floatToByte(color.red); - colorValues[ci++] = Color.floatToByte(color.green); - colorValues[ci++] = Color.floatToByte(color.blue); - colorValues[ci++] = Color.floatToByte(color.alpha); - } - } + positions = PolylinePipeline.generateCartesianArc({ + positions: positions, + minDistance: minDistance, + ellipsoid: ellipsoid, + height: heights + }); + } - positionValues.set(pos, offset); - offset += pos.length; - } - } else { - generateArcOptions.positions = positions; - generateArcOptions.height= heights; - positionValues = new Float64Array(PolylinePipeline.generateArc(generateArcOptions)); + positionsLength = positions.length; + var size = positionsLength * 4.0 - 4.0; - if (defined(colors)) { - colorValues = new Uint8Array(positionValues.length / 3 * 4); + var finalPositions = new Float64Array(size * 3); + var prevPositions = new Float64Array(size * 3); + var nextPositions = new Float64Array(size * 3); + var expandAndWidth = new Float32Array(size * 2); + var st = vertexFormat.st ? new Float32Array(size * 2) : undefined; + var finalColors = defined(colors) ? new Uint8Array(size * 4) : undefined; - for (i = 0; i < length - 1; ++i) { - var p0 = positions[i]; - var p1 = positions[i + 1]; - var c0 = colors[i]; - var c1 = colors[i + 1]; - offset = interpolateColors(p0, p1, c0, c1, minDistance, colorValues, offset); - } + var positionIndex = 0; + var expandAndWidthIndex = 0; + var stIndex = 0; + var colorIndex = 0; + var position; - var lastColor = colors[length - 1]; - colorValues[offset++] = Color.floatToByte(lastColor.red); - colorValues[offset++] = Color.floatToByte(lastColor.green); - colorValues[offset++] = Color.floatToByte(lastColor.blue); - colorValues[offset++] = Color.floatToByte(lastColor.alpha); - } + for (j = 0; j < positionsLength; ++j) { + if (j === 0) { + position = scratchCartesian3; + Cartesian3.subtract(positions[0], positions[1], position); + Cartesian3.add(positions[0], position, position); + } else { + position = positions[j - 1]; } - } else { - numberOfPositions = perSegmentColors ? length * 2 - 2 : length; - positionValues = new Float64Array(numberOfPositions * 3); - colorValues = defined(colors) ? new Uint8Array(numberOfPositions * 4) : undefined; - var positionIndex = 0; - var colorIndex = 0; + Cartesian3.clone(position, scratchPrevPosition); + Cartesian3.clone(positions[j], scratchPosition); - for (i = 0; i < length; ++i) { - var p = positions[i]; + if (j === positionsLength - 1) { + position = scratchCartesian3; + Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], position); + Cartesian3.add(positions[positionsLength - 1], position, position); + } else { + position = positions[j + 1]; + } - if (perSegmentColors && i > 0) { - Cartesian3.pack(p, positionValues, positionIndex); - positionIndex += 3; + Cartesian3.clone(position, scratchNextPosition); - color = colors[i - 1]; - colorValues[colorIndex++] = Color.floatToByte(color.red); - colorValues[colorIndex++] = Color.floatToByte(color.green); - colorValues[colorIndex++] = Color.floatToByte(color.blue); - colorValues[colorIndex++] = Color.floatToByte(color.alpha); + var color0, color1; + if (defined(finalColors)) { + if (j !== 0 && !colorsPerVertex) { + color0 = colors[j - 1]; + } else { + color0 = colors[j]; } - if (perSegmentColors && i === length - 1) { - break; + if (j !== positionsLength - 1) { + color1 = colors[j]; } + } - Cartesian3.pack(p, positionValues, positionIndex); + var startK = j === 0 ? 2 : 0; + var endK = j === positionsLength - 1 ? 2 : 4; + + for (k = startK; k < endK; ++k) { + Cartesian3.pack(scratchPosition, finalPositions, positionIndex); + Cartesian3.pack(scratchPrevPosition, prevPositions, positionIndex); + Cartesian3.pack(scratchNextPosition, nextPositions, positionIndex); positionIndex += 3; - if (defined(colors)) { - color = colors[i]; - colorValues[colorIndex++] = Color.floatToByte(color.red); - colorValues[colorIndex++] = Color.floatToByte(color.green); - colorValues[colorIndex++] = Color.floatToByte(color.blue); - colorValues[colorIndex++] = Color.floatToByte(color.alpha); + var direction = (k - 2 < 0) ? -1.0 : 1.0; + expandAndWidth[expandAndWidthIndex++] = 2 * (k % 2) - 1; // expand direction + expandAndWidth[expandAndWidthIndex++] = direction * width; + + if (vertexFormat.st) { + st[stIndex++] = j / (positionsLength - 1); + st[stIndex++] = Math.max(expandAndWidth[expandAndWidthIndex - 2], 0.0); + } + + if (defined(finalColors)) { + var color = (k < 2) ? color0 : color1; + + finalColors[colorIndex++] = Color.floatToByte(color.red); + finalColors[colorIndex++] = Color.floatToByte(color.green); + finalColors[colorIndex++] = Color.floatToByte(color.blue); + finalColors[colorIndex++] = Color.floatToByte(color.alpha); } } } var attributes = new GeometryAttributes(); + attributes.position = new GeometryAttribute({ componentDatatype : ComponentDatatype.DOUBLE, componentsPerAttribute : 3, - values : positionValues + values : finalPositions }); - if (defined(colors)) { + attributes.prevPosition = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : prevPositions + }); + + attributes.nextPosition = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : nextPositions + }); + + attributes.expandAndWidth = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : expandAndWidth + }); + + if (vertexFormat.st) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : st + }); + } + + if (defined(finalColors)) { attributes.color = new GeometryAttribute({ componentDatatype : ComponentDatatype.UNSIGNED_BYTE, componentsPerAttribute : 4, - values : colorValues, + values : finalColors, normalize : true }); } - numberOfPositions = positionValues.length / 3; - var numberOfIndices = (numberOfPositions - 1) * 2; - var indices = IndexDatatype.createTypedArray(numberOfPositions, numberOfIndices); - + var indices = IndexDatatype.createTypedArray(size, positionsLength * 6 - 6); var index = 0; - for (i = 0; i < numberOfPositions - 1; ++i) { - indices[index++] = i; - indices[index++] = i + 1; + var indicesIndex = 0; + var length = positionsLength - 1.0; + for (j = 0; j < length; ++j) { + indices[indicesIndex++] = index; + indices[indicesIndex++] = index + 2; + indices[indicesIndex++] = index + 1; + + indices[indicesIndex++] = index + 1; + indices[indicesIndex++] = index + 2; + indices[indicesIndex++] = index + 3; + + index += 4; } return new Geometry({ attributes : attributes, indices : indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : BoundingSphere.fromPoints(positions) + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : BoundingSphere.fromPoints(positions), + geometryType : GeometryType.POLYLINES }); }; - return SimplePolylineGeometry; + return PolylineGeometry; }); -define('Core/SphereGeometry',[ +define('Core/PolylineVolumeGeometry',[ + './arrayRemoveDuplicates', + './BoundingRectangle', + './BoundingSphere', + './Cartesian2', './Cartesian3', - './Check', + './ComponentDatatype', + './CornerType', './defaultValue', './defined', - './EllipsoidGeometry', - './VertexFormat' + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './GeometryPipeline', + './IndexDatatype', + './Math', + './oneTimeWarning', + './PolygonPipeline', + './PolylineVolumeGeometryLibrary', + './PrimitiveType', + './VertexFormat', + './WindingOrder' ], function( + arrayRemoveDuplicates, + BoundingRectangle, + BoundingSphere, + Cartesian2, Cartesian3, - Check, + ComponentDatatype, + CornerType, defaultValue, defined, - EllipsoidGeometry, - VertexFormat) { + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + GeometryPipeline, + IndexDatatype, + CesiumMath, + oneTimeWarning, + PolygonPipeline, + PolylineVolumeGeometryLibrary, + PrimitiveType, + VertexFormat, + WindingOrder) { 'use strict'; - /** - * A description of a sphere centered at the origin. - * - * @alias SphereGeometry - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.radius=1.0] The radius of the sphere. - * @param {Number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. - * @param {Number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * - * @exception {DeveloperError} options.slicePartitions cannot be less than three. - * @exception {DeveloperError} options.stackPartitions cannot be less than three. - * - * @see SphereGeometry#createGeometry - * - * @example - * var sphere = new Cesium.SphereGeometry({ - * radius : 100.0, - * vertexFormat : Cesium.VertexFormat.POSITION_ONLY - * }); - * var geometry = Cesium.SphereGeometry.createGeometry(sphere); - */ - function SphereGeometry(options) { - var radius = defaultValue(options.radius, 1.0); - var radii = new Cartesian3(radius, radius, radius); - var ellipsoidOptions = { - radii: radii, - stackPartitions: options.stackPartitions, - slicePartitions: options.slicePartitions, - vertexFormat: options.vertexFormat - }; - - this._ellipsoidGeometry = new EllipsoidGeometry(ellipsoidOptions); - this._workerName = 'createSphereGeometry'; - } + function computeAttributes(combinedPositions, shape, boundingRectangle, vertexFormat) { + var attributes = new GeometryAttributes(); + if (vertexFormat.position) { + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : combinedPositions + }); + } + var shapeLength = shape.length; + var vertexCount = combinedPositions.length / 3; + var length = (vertexCount - shapeLength * 2) / (shapeLength * 2); + var firstEndIndices = PolygonPipeline.triangulate(shape); - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - SphereGeometry.packedLength = EllipsoidGeometry.packedLength; + var indicesCount = (length - 1) * (shapeLength) * 6 + firstEndIndices.length * 2; + var indices = IndexDatatype.createTypedArray(vertexCount, indicesCount); + var i, j; + var ll, ul, ur, lr; + var offset = shapeLength * 2; + var index = 0; + for (i = 0; i < length - 1; i++) { + for (j = 0; j < shapeLength - 1; j++) { + ll = j * 2 + i * shapeLength * 2; + lr = ll + offset; + ul = ll + 1; + ur = ul + offset; + + indices[index++] = ul; + indices[index++] = ll; + indices[index++] = ur; + indices[index++] = ur; + indices[index++] = ll; + indices[index++] = lr; + } + ll = shapeLength * 2 - 2 + i * shapeLength * 2; + ul = ll + 1; + ur = ul + offset; + lr = ll + offset; + + indices[index++] = ul; + indices[index++] = ll; + indices[index++] = ur; + indices[index++] = ur; + indices[index++] = ll; + indices[index++] = lr; + } + + if (vertexFormat.st || vertexFormat.tangent || vertexFormat.bitangent) { // st required for tangent/bitangent calculation + var st = new Float32Array(vertexCount * 2); + var lengthSt = 1 / (length - 1); + var heightSt = 1 / (boundingRectangle.height); + var heightOffset = boundingRectangle.height / 2; + var s, t; + var stindex = 0; + for (i = 0; i < length; i++) { + s = i * lengthSt; + t = heightSt * (shape[0].y + heightOffset); + st[stindex++] = s; + st[stindex++] = t; + for (j = 1; j < shapeLength; j++) { + t = heightSt * (shape[j].y + heightOffset); + st[stindex++] = s; + st[stindex++] = t; + st[stindex++] = s; + st[stindex++] = t; + } + t = heightSt * (shape[0].y + heightOffset); + st[stindex++] = s; + st[stindex++] = t; + } + for (j = 0; j < shapeLength; j++) { + s = 0; + t = heightSt * (shape[j].y + heightOffset); + st[stindex++] = s; + st[stindex++] = t; + } + for (j = 0; j < shapeLength; j++) { + s = (length - 1) * lengthSt; + t = heightSt * (shape[j].y + heightOffset); + st[stindex++] = s; + st[stindex++] = t; + } + + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : new Float32Array(st) + }); + } + + var endOffset = vertexCount - shapeLength * 2; + for (i = 0; i < firstEndIndices.length; i += 3) { + var v0 = firstEndIndices[i] + endOffset; + var v1 = firstEndIndices[i + 1] + endOffset; + var v2 = firstEndIndices[i + 2] + endOffset; + + indices[index++] = v0; + indices[index++] = v1; + indices[index++] = v2; + indices[index++] = v2 + shapeLength; + indices[index++] = v1 + shapeLength; + indices[index++] = v0 + shapeLength; + } + + var geometry = new Geometry({ + attributes : attributes, + indices : indices, + boundingSphere : BoundingSphere.fromVertices(combinedPositions), + primitiveType : PrimitiveType.TRIANGLES + }); + + if (vertexFormat.normal) { + geometry = GeometryPipeline.computeNormal(geometry); + } + + if (vertexFormat.tangent || vertexFormat.bitangent) { + try { + geometry = GeometryPipeline.computeTangentAndBitangent(geometry); + } catch (e) { + oneTimeWarning('polyline-volume-tangent-bitangent', 'Unable to compute tangents and bitangents for polyline volume geometry'); + //TODO https://github.com/AnalyticalGraphicsInc/cesium/issues/3609 + } + + if (!vertexFormat.tangent) { + geometry.attributes.tangent = undefined; + } + if (!vertexFormat.bitangent) { + geometry.attributes.bitangent = undefined; + } + if (!vertexFormat.st) { + geometry.attributes.st = undefined; + } + } + + return geometry; + } + + /** + * A description of a polyline with a volume (a 2D shape extruded along a polyline). + * + * @alias PolylineVolumeGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.polylinePositions An array of {@link Cartesain3} positions that define the center of the polyline volume. + * @param {Cartesian2[]} options.shapePositions An array of {@link Cartesian2} positions that define the shape to be extruded along the polyline + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. + * + * @see PolylineVolumeGeometry#createGeometry + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo} + * + * @example + * function computeCircle(radius) { + * var positions = []; + * for (var i = 0; i < 360; i++) { + * var radians = Cesium.Math.toRadians(i); + * positions.push(new Cesium.Cartesian2(radius * Math.cos(radians), radius * Math.sin(radians))); + * } + * return positions; + * } + * + * var volume = new Cesium.PolylineVolumeGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY, + * polylinePositions : Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0 + * ]), + * shapePositions : computeCircle(100000.0) + * }); + */ + function PolylineVolumeGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.polylinePositions; + var shape = options.shapePositions; + + if (!defined(positions)) { + throw new DeveloperError('options.polylinePositions is required.'); + } + if (!defined(shape)) { + throw new DeveloperError('options.shapePositions is required.'); + } + + this._positions = positions; + this._shape = shape; + this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); + this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); + this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._workerName = 'createPolylineVolumeGeometry'; + + var numComponents = 1 + positions.length * Cartesian3.packedLength; + numComponents += 1 + shape.length * Cartesian2.packedLength; + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 2; + } /** * Stores the provided instance into the provided array. * - * @param {SphereGeometry} value The value to pack. + * @param {PolylineVolumeGeometry} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - SphereGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); + PolylineVolumeGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } - return EllipsoidGeometry.pack(value._ellipsoidGeometry, array, startingIndex); + startingIndex = defaultValue(startingIndex, 0); + + var i; + + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; + + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); + } + + var shape = value._shape; + length = shape.length; + array[startingIndex++] = length; + + for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { + Cartesian2.pack(shape[i], array, startingIndex); + } + + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; + + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + + array[startingIndex++] = value._cornerType; + array[startingIndex] = value._granularity; + + return array; }; - var scratchEllipsoidGeometry = new EllipsoidGeometry(); + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchVertexFormat = new VertexFormat(); var scratchOptions = { - radius : undefined, - radii : new Cartesian3(), - vertexFormat : new VertexFormat(), - stackPartitions : undefined, - slicePartitions : undefined + polylinePositions : undefined, + shapePositions : undefined, + ellipsoid : scratchEllipsoid, + vertexFormat : scratchVertexFormat, + cornerType : undefined, + granularity : undefined }; /** @@ -78143,21509 +75190,35303 @@ define('Core/SphereGeometry',[ * * @param {Number[]} array The packed array. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {SphereGeometry} [result] The object into which to store the result. - * @returns {SphereGeometry} The modified result parameter or a new SphereGeometry instance if one was not provided. + * @param {PolylineVolumeGeometry} [result] The object into which to store the result. + * @returns {PolylineVolumeGeometry} The modified result parameter or a new PolylineVolumeGeometry instance if one was not provided. */ - SphereGeometry.unpack = function(array, startingIndex, result) { - var ellipsoidGeometry = EllipsoidGeometry.unpack(array, startingIndex, scratchEllipsoidGeometry); - scratchOptions.vertexFormat = VertexFormat.clone(ellipsoidGeometry._vertexFormat, scratchOptions.vertexFormat); - scratchOptions.stackPartitions = ellipsoidGeometry._stackPartitions; - scratchOptions.slicePartitions = ellipsoidGeometry._slicePartitions; + PolylineVolumeGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); + + var i; + + var length = array[startingIndex++]; + var positions = new Array(length); + + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); + } + + length = array[startingIndex++]; + var shape = new Array(length); + + for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { + shape[i] = Cartesian2.unpack(array, startingIndex); + } + + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; + + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; + + var cornerType = array[startingIndex++]; + var granularity = array[startingIndex]; if (!defined(result)) { - scratchOptions.radius = ellipsoidGeometry._radii.x; - return new SphereGeometry(scratchOptions); + scratchOptions.polylinePositions = positions; + scratchOptions.shapePositions = shape; + scratchOptions.cornerType = cornerType; + scratchOptions.granularity = granularity; + return new PolylineVolumeGeometry(scratchOptions); } - Cartesian3.clone(ellipsoidGeometry._radii, scratchOptions.radii); - result._ellipsoidGeometry = new EllipsoidGeometry(scratchOptions); + result._positions = positions; + result._shape = shape; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._cornerType = cornerType; + result._granularity = granularity; + return result; }; + var brScratch = new BoundingRectangle(); + /** - * Computes the geometric representation of a sphere, including its vertices, indices, and a bounding sphere. + * Computes the geometric representation of a polyline with a volume, including its vertices, indices, and a bounding sphere. * - * @param {SphereGeometry} sphereGeometry A description of the sphere. - * @returns {Geometry} The computed vertices and indices. + * @param {PolylineVolumeGeometry} polylineVolumeGeometry A description of the polyline volume. + * @returns {Geometry|undefined} The computed vertices and indices. */ - SphereGeometry.createGeometry = function(sphereGeometry) { - return EllipsoidGeometry.createGeometry(sphereGeometry._ellipsoidGeometry); + PolylineVolumeGeometry.createGeometry = function(polylineVolumeGeometry) { + var positions = polylineVolumeGeometry._positions; + var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); + var shape2D = polylineVolumeGeometry._shape; + shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D); + + if (cleanPositions.length < 2 || shape2D.length < 3) { + return undefined; + } + + if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) { + shape2D.reverse(); + } + var boundingRectangle = BoundingRectangle.fromPoints(shape2D, brScratch); + + var computedPositions = PolylineVolumeGeometryLibrary.computePositions(cleanPositions, shape2D, boundingRectangle, polylineVolumeGeometry, true); + return computeAttributes(computedPositions, shape2D, boundingRectangle, polylineVolumeGeometry._vertexFormat); }; - return SphereGeometry; + return PolylineVolumeGeometry; }); -define('Core/SphereOutlineGeometry',[ +define('Core/PolylineVolumeOutlineGeometry',[ + './arrayRemoveDuplicates', + './BoundingRectangle', + './BoundingSphere', + './Cartesian2', './Cartesian3', - './Check', + './ComponentDatatype', + './CornerType', './defaultValue', './defined', - './EllipsoidOutlineGeometry' + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PolygonPipeline', + './PolylineVolumeGeometryLibrary', + './PrimitiveType', + './WindingOrder' ], function( + arrayRemoveDuplicates, + BoundingRectangle, + BoundingSphere, + Cartesian2, Cartesian3, - Check, + ComponentDatatype, + CornerType, defaultValue, defined, - EllipsoidOutlineGeometry) { + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PolygonPipeline, + PolylineVolumeGeometryLibrary, + PrimitiveType, + WindingOrder) { 'use strict'; + function computeAttributes(positions, shape) { + var attributes = new GeometryAttributes(); + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); + + var shapeLength = shape.length; + var vertexCount = attributes.position.values.length / 3; + var positionLength = positions.length / 3; + var shapeCount = positionLength / shapeLength; + var indices = IndexDatatype.createTypedArray(vertexCount, 2 * shapeLength * (shapeCount + 1)); + var i, j; + var index = 0; + i = 0; + var offset = i * shapeLength; + for (j = 0; j < shapeLength - 1; j++) { + indices[index++] = j + offset; + indices[index++] = j + offset + 1; + } + indices[index++] = shapeLength - 1 + offset; + indices[index++] = offset; + + i = shapeCount - 1; + offset = i * shapeLength; + for (j = 0; j < shapeLength - 1; j++) { + indices[index++] = j + offset; + indices[index++] = j + offset + 1; + } + indices[index++] = shapeLength - 1 + offset; + indices[index++] = offset; + + for (i = 0; i < shapeCount - 1; i++) { + var firstOffset = shapeLength * i; + var secondOffset = firstOffset + shapeLength; + for (j = 0; j < shapeLength; j++) { + indices[index++] = j + firstOffset; + indices[index++] = j + secondOffset; + } + } + + var geometry = new Geometry({ + attributes : attributes, + indices : IndexDatatype.createTypedArray(vertexCount, indices), + boundingSphere : BoundingSphere.fromVertices(positions), + primitiveType : PrimitiveType.LINES + }); + + return geometry; + } + /** - * A description of the outline of a sphere. + * A description of a polyline with a volume (a 2D shape extruded along a polyline). * - * @alias SphereOutlineGeometry + * @alias PolylineVolumeOutlineGeometry * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.radius=1.0] The radius of the sphere. - * @param {Number} [options.stackPartitions=10] The count of stacks for the sphere (1 greater than the number of parallel lines). - * @param {Number} [options.slicePartitions=8] The count of slices for the sphere (Equal to the number of radial lines). - * @param {Number} [options.subdivisions=200] The number of points per line, determining the granularity of the curvature . + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.polylinePositions An array of positions that define the center of the polyline volume. + * @param {Cartesian2[]} options.shapePositions An array of positions that define the shape to be extruded along the polyline + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. * - * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one. - * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero. - * @exception {DeveloperError} options.subdivisions must be greater than or equal to zero. + * @see PolylineVolumeOutlineGeometry#createGeometry * * @example - * var sphere = new Cesium.SphereOutlineGeometry({ - * radius : 100.0, - * stackPartitions : 6, - * slicePartitions: 5 + * function computeCircle(radius) { + * var positions = []; + * for (var i = 0; i < 360; i++) { + * var radians = Cesium.Math.toRadians(i); + * positions.push(new Cesium.Cartesian2(radius * Math.cos(radians), radius * Math.sin(radians))); + * } + * return positions; + * } + * + * var volumeOutline = new Cesium.PolylineVolumeOutlineGeometry({ + * polylinePositions : Cesium.Cartesian3.fromDegreesArray([ + * -72.0, 40.0, + * -70.0, 35.0 + * ]), + * shapePositions : computeCircle(100000.0) * }); - * var geometry = Cesium.SphereOutlineGeometry.createGeometry(sphere); */ - function SphereOutlineGeometry(options) { - var radius = defaultValue(options.radius, 1.0); - var radii = new Cartesian3(radius, radius, radius); - var ellipsoidOptions = { - radii: radii, - stackPartitions: options.stackPartitions, - slicePartitions: options.slicePartitions, - subdivisions: options.subdivisions - }; + function PolylineVolumeOutlineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.polylinePositions; + var shape = options.shapePositions; - this._ellipsoidGeometry = new EllipsoidOutlineGeometry(ellipsoidOptions); - this._workerName = 'createSphereOutlineGeometry'; - } + if (!defined(positions)) { + throw new DeveloperError('options.polylinePositions is required.'); + } + if (!defined(shape)) { + throw new DeveloperError('options.shapePositions is required.'); + } + + this._positions = positions; + this._shape = shape; + this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); + this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._workerName = 'createPolylineVolumeOutlineGeometry'; - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - SphereOutlineGeometry.packedLength = EllipsoidOutlineGeometry.packedLength; + var numComponents = 1 + positions.length * Cartesian3.packedLength; + numComponents += 1 + shape.length * Cartesian2.packedLength; + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = numComponents + Ellipsoid.packedLength + 2; + } /** * Stores the provided instance into the provided array. * - * @param {SphereOutlineGeometry} value The value to pack. + * @param {PolylineVolumeOutlineGeometry} value The value to pack. * @param {Number[]} array The array to pack into. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * * @returns {Number[]} The array that was packed into */ - SphereOutlineGeometry.pack = function(value, array, startingIndex) { - Check.typeOf.object('value', value); + PolylineVolumeOutlineGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } - return EllipsoidOutlineGeometry.pack(value._ellipsoidGeometry, array, startingIndex); - }; + startingIndex = defaultValue(startingIndex, 0); - var scratchEllipsoidGeometry = new EllipsoidOutlineGeometry(); - var scratchOptions = { - radius : undefined, - radii : new Cartesian3(), - stackPartitions : undefined, - slicePartitions : undefined, - subdivisions : undefined - }; + var i; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {SphereOutlineGeometry} [result] The object into which to store the result. - * @returns {SphereOutlineGeometry} The modified result parameter or a new SphereOutlineGeometry instance if one was not provided. - */ - SphereOutlineGeometry.unpack = function(array, startingIndex, result) { - var ellipsoidGeometry = EllipsoidOutlineGeometry.unpack(array, startingIndex, scratchEllipsoidGeometry); - scratchOptions.stackPartitions = ellipsoidGeometry._stackPartitions; - scratchOptions.slicePartitions = ellipsoidGeometry._slicePartitions; - scratchOptions.subdivisions = ellipsoidGeometry._subdivisions; + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; - if (!defined(result)) { - scratchOptions.radius = ellipsoidGeometry._radii.x; - return new SphereOutlineGeometry(scratchOptions); + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); } - Cartesian3.clone(ellipsoidGeometry._radii, scratchOptions.radii); - result._ellipsoidGeometry = new EllipsoidOutlineGeometry(scratchOptions); - return result; - }; + var shape = value._shape; + length = shape.length; + array[startingIndex++] = length; - /** - * Computes the geometric representation of an outline of a sphere, including its vertices, indices, and a bounding sphere. - * - * @param {SphereOutlineGeometry} sphereGeometry A description of the sphere outline. - * @returns {Geometry} The computed vertices and indices. - */ - SphereOutlineGeometry.createGeometry = function(sphereGeometry) { - return EllipsoidOutlineGeometry.createGeometry(sphereGeometry._ellipsoidGeometry); - }; + for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { + Cartesian2.pack(shape[i], array, startingIndex); + } - return SphereOutlineGeometry; -}); + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; -define('Core/Spherical',[ - './Check', - './defaultValue', - './defined' - ], function( - Check, - defaultValue, - defined) { - 'use strict'; + array[startingIndex++] = value._cornerType; + array[startingIndex] = value._granularity; - /** - * A set of curvilinear 3-dimensional coordinates. - * - * @alias Spherical - * @constructor - * - * @param {Number} [clock=0.0] The angular coordinate lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. - * @param {Number} [cone=0.0] The angular coordinate measured from the positive z-axis and toward the negative z-axis. - * @param {Number} [magnitude=1.0] The linear coordinate measured from the origin. - */ - function Spherical(clock, cone, magnitude) { - this.clock = defaultValue(clock, 0.0); - this.cone = defaultValue(cone, 0.0); - this.magnitude = defaultValue(magnitude, 1.0); - } + return array; + }; + + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchOptions = { + polylinePositions : undefined, + shapePositions : undefined, + ellipsoid : scratchEllipsoid, + height : undefined, + cornerType : undefined, + granularity : undefined + }; /** - * Converts the provided Cartesian3 into Spherical coordinates. + * Retrieves an instance from a packed array. * - * @param {Cartesian3} cartesian3 The Cartesian3 to be converted to Spherical. - * @param {Spherical} [result] The object in which the result will be stored, if undefined a new instance will be created. - * @returns {Spherical} The modified result parameter, or a new instance if one was not provided. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {PolylineVolumeOutlineGeometry} [result] The object into which to store the result. + * @returns {PolylineVolumeOutlineGeometry} The modified result parameter or a new PolylineVolumeOutlineGeometry instance if one was not provided. */ - Spherical.fromCartesian3 = function(cartesian3, result) { - Check.typeOf.object('cartesian3', cartesian3); + PolylineVolumeOutlineGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } - var x = cartesian3.x; - var y = cartesian3.y; - var z = cartesian3.z; - var radialSquared = x * x + y * y; + startingIndex = defaultValue(startingIndex, 0); - if (!defined(result)) { - result = new Spherical(); - } + var i; - result.clock = Math.atan2(y, x); - result.cone = Math.atan2(Math.sqrt(radialSquared), z); - result.magnitude = Math.sqrt(radialSquared + z * z); - return result; - }; + var length = array[startingIndex++]; + var positions = new Array(length); - /** - * Creates a duplicate of a Spherical. - * - * @param {Spherical} spherical The spherical to clone. - * @param {Spherical} [result] The object to store the result into, if undefined a new instance will be created. - * @returns {Spherical} The modified result parameter or a new instance if result was undefined. (Returns undefined if spherical is undefined) - */ - Spherical.clone = function(spherical, result) { - if (!defined(spherical)) { - return undefined; + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); } - if (!defined(result)) { - return new Spherical(spherical.clock, spherical.cone, spherical.magnitude); + length = array[startingIndex++]; + var shape = new Array(length); + + for (i = 0; i < length; ++i, startingIndex += Cartesian2.packedLength) { + shape[i] = Cartesian2.unpack(array, startingIndex); } - result.clock = spherical.clock; - result.cone = spherical.cone; - result.magnitude = spherical.magnitude; - return result; - }; + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; + + var cornerType = array[startingIndex++]; + var granularity = array[startingIndex]; - /** - * Computes the normalized version of the provided spherical. - * - * @param {Spherical} spherical The spherical to be normalized. - * @param {Spherical} [result] The object to store the result into, if undefined a new instance will be created. - * @returns {Spherical} The modified result parameter or a new instance if result was undefined. - */ - Spherical.normalize = function(spherical, result) { - Check.typeOf.object('spherical', spherical); - if (!defined(result)) { - return new Spherical(spherical.clock, spherical.cone, 1.0); + scratchOptions.polylinePositions = positions; + scratchOptions.shapePositions = shape; + scratchOptions.cornerType = cornerType; + scratchOptions.granularity = granularity; + return new PolylineVolumeOutlineGeometry(scratchOptions); } - result.clock = spherical.clock; - result.cone = spherical.cone; - result.magnitude = 1.0; - return result; - }; + result._positions = positions; + result._shape = shape; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._cornerType = cornerType; + result._granularity = granularity; - /** - * Returns true if the first spherical is equal to the second spherical, false otherwise. - * - * @param {Spherical} left The first Spherical to be compared. - * @param {Spherical} right The second Spherical to be compared. - * @returns {Boolean} true if the first spherical is equal to the second spherical, false otherwise. - */ - Spherical.equals = function(left, right) { - return (left === right) || - ((defined(left)) && - (defined(right)) && - (left.clock === right.clock) && - (left.cone === right.cone) && - (left.magnitude === right.magnitude)); + return result; }; - /** - * Returns true if the first spherical is within the provided epsilon of the second spherical, false otherwise. - * - * @param {Spherical} left The first Spherical to be compared. - * @param {Spherical} right The second Spherical to be compared. - * @param {Number} [epsilon=0.0] The epsilon to compare against. - * @returns {Boolean} true if the first spherical is within the provided epsilon of the second spherical, false otherwise. - */ - Spherical.equalsEpsilon = function(left, right, epsilon) { - epsilon = defaultValue(epsilon, 0.0); - return (left === right) || - ((defined(left)) && - (defined(right)) && - (Math.abs(left.clock - right.clock) <= epsilon) && - (Math.abs(left.cone - right.cone) <= epsilon) && - (Math.abs(left.magnitude - right.magnitude) <= epsilon)); - }; + var brScratch = new BoundingRectangle(); /** - * Returns true if this spherical is equal to the provided spherical, false otherwise. + * Computes the geometric representation of the outline of a polyline with a volume, including its vertices, indices, and a bounding sphere. * - * @param {Spherical} other The Spherical to be compared. - * @returns {Boolean} true if this spherical is equal to the provided spherical, false otherwise. + * @param {PolylineVolumeOutlineGeometry} polylineVolumeOutlineGeometry A description of the polyline volume outline. + * @returns {Geometry|undefined} The computed vertices and indices. */ - Spherical.prototype.equals = function(other) { - return Spherical.equals(this, other); - }; + PolylineVolumeOutlineGeometry.createGeometry = function(polylineVolumeOutlineGeometry) { + var positions = polylineVolumeOutlineGeometry._positions; + var cleanPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); + var shape2D = polylineVolumeOutlineGeometry._shape; + shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D); - /** - * Creates a duplicate of this Spherical. - * - * @param {Spherical} [result] The object to store the result into, if undefined a new instance will be created. - * @returns {Spherical} The modified result parameter or a new instance if result was undefined. - */ - Spherical.prototype.clone = function(result) { - return Spherical.clone(this, result); - }; + if (cleanPositions.length < 2 || shape2D.length < 3) { + return undefined; + } - /** - * Returns true if this spherical is within the provided epsilon of the provided spherical, false otherwise. - * - * @param {Spherical} other The Spherical to be compared. - * @param {Number} epsilon The epsilon to compare against. - * @returns {Boolean} true if this spherical is within the provided epsilon of the provided spherical, false otherwise. - */ - Spherical.prototype.equalsEpsilon = function(other, epsilon) { - return Spherical.equalsEpsilon(this, other, epsilon); - }; + if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) { + shape2D.reverse(); + } + var boundingRectangle = BoundingRectangle.fromPoints(shape2D, brScratch); - /** - * Returns a string representing this instance in the format (clock, cone, magnitude). - * - * @returns {String} A string representing this instance. - */ - Spherical.prototype.toString = function() { - return '(' + this.clock + ', ' + this.cone + ', ' + this.magnitude + ')'; + var computedPositions = PolylineVolumeGeometryLibrary.computePositions(cleanPositions, shape2D, boundingRectangle, polylineVolumeOutlineGeometry, false); + return computeAttributes(computedPositions, shape2D); }; - return Spherical; + return PolylineVolumeOutlineGeometry; }); -define('Core/subdivideArray',[ +define('Core/QuaternionSpline',[ + './defaultValue', './defined', - './DeveloperError' + './defineProperties', + './DeveloperError', + './Quaternion', + './Spline' ], function( + defaultValue, defined, - DeveloperError) { + defineProperties, + DeveloperError, + Quaternion, + Spline) { 'use strict'; - /** - * Subdivides an array into a number of smaller, equal sized arrays. - * - * @exports subdivideArray - * - * @param {Array} array The array to divide. - * @param {Number} numberOfArrays The number of arrays to divide the provided array into. - * - * @exception {DeveloperError} numberOfArrays must be greater than 0. - */ - function subdivideArray(array, numberOfArrays) { - if (!defined(array)) { - throw new DeveloperError('array is required.'); - } + function createEvaluateFunction(spline) { + var points = spline.points; + var times = spline.times; - if (!defined(numberOfArrays) || numberOfArrays < 1) { - throw new DeveloperError('numberOfArrays must be greater than 0.'); - } - - var result = []; - var len = array.length; - var i = 0; - while (i < len) { - var size = Math.ceil((len - i) / numberOfArrays--); - result.push(array.slice(i, i + size)); - i += size; - } - return result; - } + // use slerp interpolation + return function(time, result) { + if (!defined(result)){ + result = new Quaternion(); + } + var i = spline._lastTimeIndex = spline.findTimeInterval(time, spline._lastTimeIndex); + var u = (time - times[i]) / (times[i + 1] - times[i]); - return subdivideArray; -}); + var q0 = points[i]; + var q1 = points[i + 1]; -define('Core/TerrainData',[ - './defineProperties', - './DeveloperError' - ], function( - defineProperties, - DeveloperError) { - 'use strict'; + return Quaternion.fastSlerp(q0, q1, u, result); + }; + } /** - * Terrain data for a single tile. This type describes an - * interface and is not intended to be instantiated directly. + * A spline that uses spherical linear (slerp) interpolation to create a quaternion curve. + * The generated curve is in the class C<sup>1</sup>. * - * @alias TerrainData + * @alias QuaternionSpline * @constructor * - * @see HeightmapTerrainData - * @see QuantizedMeshTerrainData + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * The values are in no way connected to the clock time. They are the parameterization for the curve. + * @param {Quaternion[]} options.points The array of {@link Quaternion} control points. + * + * @exception {DeveloperError} points.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be equal to points.length. + * + * @see HermiteSpline + * @see CatmullRomSpline + * @see LinearSpline + * @see WeightSpline */ - function TerrainData() { - DeveloperError.throwInstantiationError(); + function QuaternionSpline(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var points = options.points; + var times = options.times; + + if (!defined(points) || !defined(times)) { + throw new DeveloperError('points and times are required.'); + } + if (points.length < 2) { + throw new DeveloperError('points.length must be greater than or equal to 2.'); + } + if (times.length !== points.length) { + throw new DeveloperError('times.length must be equal to points.length.'); + } + + this._times = times; + this._points = points; + + this._evaluateFunction = createEvaluateFunction(this); + this._lastTimeIndex = 0; } - defineProperties(TerrainData.prototype, { + defineProperties(QuaternionSpline.prototype, { /** - * An array of credits for this tile. - * @memberof TerrainData.prototype - * @type {Credit[]} + * An array of times for the control points. + * + * @memberof QuaternionSpline.prototype + * + * @type {Number[]} + * @readonly */ - credits : { - get : DeveloperError.throwInstantiationError + times : { + get : function() { + return this._times; + } }, + /** - * The water mask included in this terrain data, if any. A water mask is a rectangular - * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. - * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. - * @memberof TerrainData.prototype - * @type {Uint8Array|Image|Canvas} + * An array of {@link Quaternion} control points. + * + * @memberof QuaternionSpline.prototype + * + * @type {Quaternion[]} + * @readonly */ - waterMask : { - get : DeveloperError.throwInstantiationError + points : { + get : function() { + return this._points; + } } }); /** - * Computes the terrain height at a specified longitude and latitude. + * Finds an index <code>i</code> in <code>times</code> such that the parameter + * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. If the position - * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly - * incorrect for positions far outside the rectangle. - */ - TerrainData.prototype.interpolateHeight = DeveloperError.throwInstantiationError; - - /** - * Determines if a given child tile is available, based on the - * {@link TerrainData#childTileMask}. The given child tile coordinates are assumed - * to be one of the four children of this tile. If non-child tile coordinates are - * given, the availability of the southeast child tile is returned. - * @function + * @param {Number} time The time. + * @returns {Number} The index for the element at the start of the interval. * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - TerrainData.prototype.isChildAvailable = DeveloperError.throwInstantiationError; + QuaternionSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; /** - * Creates a {@link TerrainMesh} from this terrain data. + * Wraps the given time to the period covered by the spline. * @function * - * @private - * - * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} x The X coordinate of the tile for which to create the terrain data. - * @param {Number} y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} level The level of the tile for which to create the terrain data. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many - * asynchronous mesh creations are already in progress and the operation should - * be retried later. + * @param {Number} time The time. + * @return {Number} The time, wrapped around to the updated animation. */ - TerrainData.prototype.createMesh = DeveloperError.throwInstantiationError; + QuaternionSpline.prototype.wrapTime = Spline.prototype.wrapTime; /** - * Upsamples this terrain data for use by a descendant tile. + * Clamps the given time to the period covered by the spline. * @function * - * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<TerrainData>|undefined} A promise for upsampled terrain data for the descendant tile, - * or undefined if too many asynchronous upsample operations are in progress and the request has been - * deferred. + * @param {Number} time The time. + * @return {Number} The time, clamped to the animation period. */ - TerrainData.prototype.upsample = DeveloperError.throwInstantiationError; + QuaternionSpline.prototype.clampTime = Spline.prototype.clampTime; /** - * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution - * terrain data. If this value is false, the data was obtained from some other source, such - * as by downloading it from a remote server. This method should return true for instances - * returned from a call to {@link TerrainData#upsample}. - * @function + * Evaluates the curve at a given time. * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + * @param {Number} time The time at which to evaluate the curve. + * @param {Quaternion} [result] The object onto which to store the result. + * @returns {Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. + * + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - TerrainData.prototype.wasCreatedByUpsampling = DeveloperError.throwInstantiationError; + QuaternionSpline.prototype.evaluate = function(time, result) { + return this._evaluateFunction(time, result); + }; - return TerrainData; + return QuaternionSpline; }); -define('Core/TilingScheme',[ - './defineProperties', - './DeveloperError' +define('Core/RectangleGeometryLibrary',[ + './Cartesian3', + './Cartographic', + './defined', + './DeveloperError', + './GeographicProjection', + './Math', + './Matrix2', + './Rectangle' ], function( - defineProperties, - DeveloperError) { + Cartesian3, + Cartographic, + defined, + DeveloperError, + GeographicProjection, + CesiumMath, + Matrix2, + Rectangle) { 'use strict'; - /** - * A tiling scheme for geometry or imagery on the surface of an ellipsoid. At level-of-detail zero, - * the coarsest, least-detailed level, the number of tiles is configurable. - * At level of detail one, each of the level zero tiles has four children, two in each direction. - * At level of detail two, each of the level one tiles has four children, two in each direction. - * This continues for as many levels as are present in the geometry or imagery source. - * - * @alias TilingScheme - * @constructor - * - * @see WebMercatorTilingScheme - * @see GeographicTilingScheme + var cos = Math.cos; + var sin = Math.sin; + var sqrt = Math.sqrt; + + /** + * @private */ - function TilingScheme(options) { - throw new DeveloperError('This type should not be instantiated directly. Instead, use WebMercatorTilingScheme or GeographicTilingScheme.'); - } + var RectangleGeometryLibrary = {}; - defineProperties(TilingScheme.prototype, { - /** - * Gets the ellipsoid that is tiled by the tiling scheme. - * @memberof TilingScheme.prototype - * @type {Ellipsoid} - */ - ellipsoid: { - get : DeveloperError.throwInstantiationError - }, + /** + * @private + */ + RectangleGeometryLibrary.computePosition = function(options, row, col, position, st) { + var radiiSquared = options.ellipsoid.radiiSquared; + var nwCorner = options.nwCorner; + var rectangle = options.rectangle; - /** - * Gets the rectangle, in radians, covered by this tiling scheme. - * @memberof TilingScheme.prototype - * @type {Rectangle} - */ - rectangle : { - get : DeveloperError.throwInstantiationError - }, + var stLatitude = nwCorner.latitude - options.granYCos * row + col * options.granXSin; + var cosLatitude = cos(stLatitude); + var nZ = sin(stLatitude); + var kZ = radiiSquared.z * nZ; + var stLongitude = nwCorner.longitude + row * options.granYSin + col * options.granXCos; + var nX = cosLatitude * cos(stLongitude); + var nY = cosLatitude * sin(stLongitude); - /** - * Gets the map projection used by the tiling scheme. - * @memberof TilingScheme.prototype - * @type {MapProjection} - */ - projection : { - get : DeveloperError.throwInstantiationError + var kX = radiiSquared.x * nX; + var kY = radiiSquared.y * nY; + + var gamma = sqrt((kX * nX) + (kY * nY) + (kZ * nZ)); + + position.x = kX / gamma; + position.y = kY / gamma; + position.z = kZ / gamma; + + if (defined(options.vertexFormat) && options.vertexFormat.st) { + var stNwCorner = options.stNwCorner; + if (defined(stNwCorner)) { + stLatitude = stNwCorner.latitude - options.stGranYCos * row + col * options.stGranXSin; + stLongitude = stNwCorner.longitude + row * options.stGranYSin + col * options.stGranXCos; + + st.x = (stLongitude - options.stWest) * options.lonScalar; + st.y = (stLatitude - options.stSouth) * options.latScalar; + } else { + st.x = (stLongitude - rectangle.west) * options.lonScalar; + st.y = (stLatitude - rectangle.south) * options.latScalar; + } } - }); + }; - /** - * Gets the total number of tiles in the X direction at a specified level-of-detail. - * @function - * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the X direction at the given level. - */ - TilingScheme.prototype.getNumberOfXTilesAtLevel = DeveloperError.throwInstantiationError; + var rotationMatrixScratch = new Matrix2(); + var nwCartesian = new Cartesian3(); + var centerScratch = new Cartographic(); + var centerCartesian = new Cartesian3(); + var proj = new GeographicProjection(); - /** - * Gets the total number of tiles in the Y direction at a specified level-of-detail. - * @function - * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the Y direction at the given level. - */ - TilingScheme.prototype.getNumberOfYTilesAtLevel = DeveloperError.throwInstantiationError; + function getRotationOptions(nwCorner, rotation, granularityX, granularityY, center, width, height) { + var cosRotation = Math.cos(rotation); + var granYCos = granularityY * cosRotation; + var granXCos = granularityX * cosRotation; - /** - * Transforms a rectangle specified in geodetic radians to the native coordinate system - * of this tiling scheme. - * @function - * - * @param {Rectangle} rectangle The rectangle to transform. - * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result' - * is undefined. - */ - TilingScheme.prototype.rectangleToNativeRectangle = DeveloperError.throwInstantiationError; + var sinRotation = Math.sin(rotation); + var granYSin = granularityY * sinRotation; + var granXSin = granularityX * sinRotation; - /** - * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates - * of the tiling scheme. - * @function - * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the rectangle - * if 'result' is undefined. - */ - TilingScheme.prototype.tileXYToNativeRectangle = DeveloperError.throwInstantiationError; + nwCartesian = proj.project(nwCorner, nwCartesian); - /** - * Converts tile x, y coordinates and level to a cartographic rectangle in radians. - * @function - * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the rectangle - * if 'result' is undefined. - */ - TilingScheme.prototype.tileXYToRectangle = DeveloperError.throwInstantiationError; + nwCartesian = Cartesian3.subtract(nwCartesian, centerCartesian, nwCartesian); + var rotationMatrix = Matrix2.fromRotation(rotation, rotationMatrixScratch); + nwCartesian = Matrix2.multiplyByVector(rotationMatrix, nwCartesian, nwCartesian); + nwCartesian = Cartesian3.add(nwCartesian, centerCartesian, nwCartesian); + nwCorner = proj.unproject(nwCartesian, nwCorner); - /** - * Calculates the tile x, y coordinates of the tile containing - * a given cartographic position. - * @function - * - * @param {Cartographic} position The position. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates - * if 'result' is undefined. - */ - TilingScheme.prototype.positionToTileXY = DeveloperError.throwInstantiationError; + width -= 1; + height -= 1; - return TilingScheme; -}); + var latitude = nwCorner.latitude; + var latitude0 = latitude + width * granXSin; + var latitude1 = latitude - granYCos * height; + var latitude2 = latitude - granYCos * height + width * granXSin; -define('Core/TimeIntervalCollection',[ - './binarySearch', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Event', - './GregorianDate', - './isLeapYear', - './Iso8601', - './JulianDate', - './TimeInterval' - ], function( - binarySearch, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - GregorianDate, - isLeapYear, - Iso8601, - JulianDate, - TimeInterval) { - 'use strict'; + var north = Math.max(latitude, latitude0, latitude1, latitude2); + var south = Math.min(latitude, latitude0, latitude1, latitude2); - function compareIntervalStartTimes(left, right) { - return JulianDate.compare(left.start, right.start); + var longitude = nwCorner.longitude; + var longitude0 = longitude + width * granXCos; + var longitude1 = longitude + height * granYSin; + var longitude2 = longitude + height * granYSin + width * granXCos; + + var east = Math.max(longitude, longitude0, longitude1, longitude2); + var west = Math.min(longitude, longitude0, longitude1, longitude2); + + return { + north: north, + south: south, + east: east, + west: west, + granYCos : granYCos, + granYSin : granYSin, + granXCos : granXCos, + granXSin : granXSin, + nwCorner : nwCorner + }; } /** - * A non-overlapping collection of {@link TimeInterval} instances sorted by start time. - * @alias TimeIntervalCollection - * @constructor - * - * @param {TimeInterval[]} [intervals] An array of intervals to add to the collection. + * @private */ - function TimeIntervalCollection(intervals) { - this._intervals = []; - this._changedEvent = new Event(); + RectangleGeometryLibrary.computeOptions = function(geometry, rectangle, nwCorner, stNwCorner) { + var granularity = geometry._granularity; + var ellipsoid = geometry._ellipsoid; + var surfaceHeight = geometry._surfaceHeight; + var rotation = geometry._rotation; + var stRotation = geometry._stRotation; + var extrudedHeight = geometry._extrudedHeight; + var east = rectangle.east; + var west = rectangle.west; + var north = rectangle.north; + var south = rectangle.south; - if (defined(intervals)) { - var length = intervals.length; - for (var i = 0; i < length; i++) { - this.addInterval(intervals[i]); - } + var width; + var height; + var granularityX; + var granularityY; + var dx; + var dy = north - south; + if (west > east) { + dx = (CesiumMath.TWO_PI - west + east); + width = Math.ceil(dx / granularity) + 1; + height = Math.ceil(dy / granularity) + 1; + granularityX = dx / (width - 1); + granularityY = dy / (height - 1); + } else { + dx = east - west; + width = Math.ceil(dx / granularity) + 1; + height = Math.ceil(dy / granularity) + 1; + granularityX = dx / (width - 1); + granularityY = dy / (height - 1); } - } - - defineProperties(TimeIntervalCollection.prototype, { - /** - * Gets an event that is raised whenever the collection of intervals change. - * @memberof TimeIntervalCollection.prototype - * @type {Event} - * @readonly - */ - changedEvent : { - get : function() { - return this._changedEvent; - } - }, - /** - * Gets the start time of the collection. - * @memberof TimeIntervalCollection.prototype - * @type {JulianDate} - * @readonly - */ - start : { - get : function() { - var intervals = this._intervals; - return intervals.length === 0 ? undefined : intervals[0].start; + nwCorner = Rectangle.northwest(rectangle, nwCorner); + var center = Rectangle.center(rectangle, centerScratch); + if (rotation !== 0 || stRotation !== 0) { + if (center.longitude < nwCorner.longitude) { + center.longitude += CesiumMath.TWO_PI; } - }, + centerCartesian = proj.project(center, centerCartesian); + } - /** - * Gets whether or not the start time is included in the collection. - * @memberof TimeIntervalCollection.prototype - * @type {Boolean} - * @readonly - */ - isStartIncluded : { - get : function() { - var intervals = this._intervals; - return intervals.length === 0 ? false : intervals[0].isStartIncluded; - } - }, + var granYCos = granularityY; + var granXCos = granularityX; + var granYSin = 0.0; + var granXSin = 0.0; - /** - * Gets the stop time of the collection. - * @memberof TimeIntervalCollection.prototype - * @type {JulianDate} - * @readonly - */ - stop : { - get : function() { - var intervals = this._intervals; - var length = intervals.length; - return length === 0 ? undefined : intervals[length - 1].stop; - } - }, + var options = { + granYCos : granYCos, + granYSin : granYSin, + granXCos : granXCos, + granXSin : granXSin, + ellipsoid : ellipsoid, + surfaceHeight : surfaceHeight, + extrudedHeight : extrudedHeight, + nwCorner : nwCorner, + rectangle : rectangle, + width: width, + height: height + }; - /** - * Gets whether or not the stop time is included in the collection. - * @memberof TimeIntervalCollection.prototype - * @type {Boolean} - * @readonly - */ - isStopIncluded : { - get : function() { - var intervals = this._intervals; - var length = intervals.length; - return length === 0 ? false : intervals[length - 1].isStopIncluded; - } - }, + if (rotation !== 0) { + var rotationOptions = getRotationOptions(nwCorner, rotation, granularityX, granularityY, center, width, height); + north = rotationOptions.north; + south = rotationOptions.south; + east = rotationOptions.east; + west = rotationOptions.west; - /** - * Gets the number of intervals in the collection. - * @memberof TimeIntervalCollection.prototype - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._intervals.length; + if (north < -CesiumMath.PI_OVER_TWO || north > CesiumMath.PI_OVER_TWO || + south < -CesiumMath.PI_OVER_TWO || south > CesiumMath.PI_OVER_TWO) { + throw new DeveloperError('Rotated rectangle is invalid. It crosses over either the north or south pole.'); } - }, + + options.granYCos = rotationOptions.granYCos; + options.granYSin = rotationOptions.granYSin; + options.granXCos = rotationOptions.granXCos; + options.granXSin = rotationOptions.granXSin; - /** - * Gets whether or not the collection is empty. - * @memberof TimeIntervalCollection.prototype - * @type {Boolean} - * @readonly - */ - isEmpty : { - get : function() { - return this._intervals.length === 0; - } + rectangle.north = north; + rectangle.south = south; + rectangle.east = east; + rectangle.west = west; } - }); - /** - * Compares this instance against the provided instance componentwise and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {TimeIntervalCollection} [right] The right hand side collection. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - TimeIntervalCollection.prototype.equals = function(right, dataComparer) { - if (this === right) { - return true; - } - if (!(right instanceof TimeIntervalCollection)) { - return false; - } - var intervals = this._intervals; - var rightIntervals = right._intervals; - var length = intervals.length; - if (length !== rightIntervals.length) { - return false; - } - for (var i = 0; i < length; i++) { - if (!TimeInterval.equals(intervals[i], rightIntervals[i], dataComparer)) { - return false; - } - } - return true; - }; + if (stRotation !== 0) { + rotation = rotation - stRotation; + stNwCorner = Rectangle.northwest(rectangle, stNwCorner); - /** - * Gets the interval at the specified index. - * - * @param {Number} index The index of the interval to retrieve. - * @returns {TimeInterval} The interval at the specified index, or <code>undefined</code> if no interval exists as that index. - */ - TimeIntervalCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - return this._intervals[index]; - }; + var stRotationOptions = getRotationOptions(stNwCorner, rotation, granularityX, granularityY, center, width, height); - /** - * Removes all intervals from the collection. - */ - TimeIntervalCollection.prototype.removeAll = function() { - if (this._intervals.length > 0) { - this._intervals.length = 0; - this._changedEvent.raiseEvent(this); + options.stGranYCos = stRotationOptions.granYCos; + options.stGranXCos = stRotationOptions.granXCos; + options.stGranYSin = stRotationOptions.granYSin; + options.stGranXSin = stRotationOptions.granXSin; + options.stNwCorner = stNwCorner; + options.stWest = stRotationOptions.west; + options.stSouth = stRotationOptions.south; } - }; - /** - * Finds and returns the interval that contains the specified date. - * - * @param {JulianDate} date The date to search for. - * @returns {TimeInterval|undefined} The interval containing the specified date, <code>undefined</code> if no such interval exists. - */ - TimeIntervalCollection.prototype.findIntervalContainingDate = function(date) { - var index = this.indexOf(date); - return index >= 0 ? this._intervals[index] : undefined; + return options; }; - /** - * Finds and returns the data for the interval that contains the specified date. - * - * @param {JulianDate} date The date to search for. - * @returns {Object} The data for the interval containing the specified date, or <code>undefined</code> if no such interval exists. - */ - TimeIntervalCollection.prototype.findDataForIntervalContainingDate = function(date) { - var index = this.indexOf(date); - return index >= 0 ? this._intervals[index].data : undefined; - }; + return RectangleGeometryLibrary; +}); - /** - * Checks if the specified date is inside this collection. - * - * @param {JulianDate} julianDate The date to check. - * @returns {Boolean} <code>true</code> if the collection contains the specified date, <code>false</code> otherwise. - */ - TimeIntervalCollection.prototype.contains = function(julianDate) { - return this.indexOf(julianDate) >= 0; - }; +define('Core/RectangleGeometry',[ + './BoundingSphere', + './Cartesian2', + './Cartesian3', + './Cartographic', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './GeometryInstance', + './GeometryPipeline', + './IndexDatatype', + './Math', + './Matrix3', + './PolygonPipeline', + './PrimitiveType', + './Quaternion', + './Rectangle', + './RectangleGeometryLibrary', + './VertexFormat' + ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Cartographic, + Check, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + GeometryInstance, + GeometryPipeline, + IndexDatatype, + CesiumMath, + Matrix3, + PolygonPipeline, + PrimitiveType, + Quaternion, + Rectangle, + RectangleGeometryLibrary, + VertexFormat) { + 'use strict'; - var indexOfScratch = new TimeInterval(); + var positionScratch = new Cartesian3(); + var normalScratch = new Cartesian3(); + var tangentScratch = new Cartesian3(); + var bitangentScratch = new Cartesian3(); + var rectangleScratch = new Rectangle(); + var stScratch = new Cartesian2(); + var bottomBoundingSphere = new BoundingSphere(); + var topBoundingSphere = new BoundingSphere(); - /** - * Finds and returns the index of the interval in the collection that contains the specified date. - * - * @param {JulianDate} date The date to search for. - * @returns {Number} The index of the interval that contains the specified date, if no such interval exists, - * it returns a negative number which is the bitwise complement of the index of the next interval that - * starts after the date, or if no interval starts after the specified date, the bitwise complement of - * the length of the collection. - */ - TimeIntervalCollection.prototype.indexOf = function(date) { - if (!defined(date)) { - throw new DeveloperError('date is required'); - } - - var intervals = this._intervals; - indexOfScratch.start = date; - indexOfScratch.stop = date; - var index = binarySearch(intervals, indexOfScratch, compareIntervalStartTimes); - if (index >= 0) { - if (intervals[index].isStartIncluded) { - return index; - } + function createAttributes(vertexFormat, attributes) { + var geo = new Geometry({ + attributes : new GeometryAttributes(), + primitiveType : PrimitiveType.TRIANGLES + }); - if (index > 0 && intervals[index - 1].stop.equals(date) && intervals[index - 1].isStopIncluded) { - return index - 1; - } - return ~index; + geo.attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : attributes.positions + }); + if (vertexFormat.normal) { + geo.attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : attributes.normals + }); } - - index = ~index; - if (index > 0 && (index - 1) < intervals.length && TimeInterval.contains(intervals[index - 1], date)) { - return index - 1; + if (vertexFormat.tangent) { + geo.attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : attributes.tangents + }); } - return ~index; - }; - - /** - * Returns the first interval in the collection that matches the specified parameters. - * All parameters are optional and <code>undefined</code> parameters are treated as a don't care condition. - * - * @param {Object} [options] Object with the following properties: - * @param {JulianDate} [options.start] The start time of the interval. - * @param {JulianDate} [options.stop] The stop time of the interval. - * @param {Boolean} [options.isStartIncluded] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. - * @returns {TimeInterval} The first interval in the collection that matches the specified parameters. - */ - TimeIntervalCollection.prototype.findInterval = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var start = options.start; - var stop = options.stop; - var isStartIncluded = options.isStartIncluded; - var isStopIncluded = options.isStopIncluded; - - var intervals = this._intervals; - for (var i = 0, len = intervals.length; i < len; i++) { - var interval = intervals[i]; - if ((!defined(start) || interval.start.equals(start)) && - (!defined(stop) || interval.stop.equals(stop)) && - (!defined(isStartIncluded) || interval.isStartIncluded === isStartIncluded) && - (!defined(isStopIncluded) || interval.isStopIncluded === isStopIncluded)) { - return intervals[i]; - } + if (vertexFormat.bitangent) { + geo.attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : attributes.bitangents + }); } - return undefined; - }; + return geo; + } - /** - * Adds an interval to the collection, merging intervals that contain the same data and - * splitting intervals of different data as needed in order to maintain a non-overlapping collection. - * The data in the new interval takes precedence over any existing intervals in the collection. - * - * @param {TimeInterval} interval The interval to add. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - */ - TimeIntervalCollection.prototype.addInterval = function(interval, dataComparer) { - if (!defined(interval)) { - throw new DeveloperError('interval is required'); - } - - if (interval.isEmpty) { - return; - } + function calculateAttributes(positions, vertexFormat, ellipsoid, tangentRotationMatrix) { + var length = positions.length; - var comparison; - var index; - var intervals = this._intervals; + var normals = (vertexFormat.normal) ? new Float32Array(length) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(length) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(length) : undefined; - // Handle the common case quickly: we're adding a new interval which is after all existing intervals. - if (intervals.length === 0 || JulianDate.greaterThan(interval.start, intervals[intervals.length - 1].stop)) { - intervals.push(interval); - this._changedEvent.raiseEvent(this); - return; - } + var attrIndex = 0; + var bitangent = bitangentScratch; + var tangent = tangentScratch; + var normal = normalScratch; + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { + for (var i = 0; i < length; i += 3) { + var p = Cartesian3.fromArray(positions, i, positionScratch); + var attrIndex1 = attrIndex + 1; + var attrIndex2 = attrIndex + 2; - // Keep the list sorted by the start date - index = binarySearch(intervals, interval, compareIntervalStartTimes); - if (index < 0) { - index = ~index; - } else if (index > 0 && interval.isStartIncluded && intervals[index - 1].isStartIncluded && intervals[index - 1].start.equals(interval.start)) { - // interval's start date exactly equals the start date of at least one interval in the collection. - // It could actually equal the start date of two intervals if one of them does not actually - // include the date. In that case, the binary search could have found either. We need to - // look at the surrounding intervals and their IsStartIncluded properties in order to make sure - // we're working with the correct interval. - --index; - } else if (index < intervals.length && !interval.isStartIncluded && intervals[index].isStartIncluded && intervals[index].start.equals(interval.start)) { - ++index; - } + normal = ellipsoid.geodeticSurfaceNormal(p, normal); + if (vertexFormat.tangent || vertexFormat.bitangent) { + Cartesian3.cross(Cartesian3.UNIT_Z, normal, tangent); + Matrix3.multiplyByVector(tangentRotationMatrix, tangent, tangent); + Cartesian3.normalize(tangent, tangent); - if (index > 0) { - // Not the first thing in the list, so see if the interval before this one - // overlaps this one. - comparison = JulianDate.compare(intervals[index - 1].stop, interval.start); - if (comparison > 0 || (comparison === 0 && (intervals[index - 1].isStopIncluded || interval.isStartIncluded))) { - // There is an overlap - if (defined(dataComparer) ? dataComparer(intervals[index - 1].data, interval.data) : (intervals[index - 1].data === interval.data)) { - // Overlapping intervals have the same data, so combine them - if (JulianDate.greaterThan(interval.stop, intervals[index - 1].stop)) { - interval = new TimeInterval({ - start : intervals[index - 1].start, - stop : interval.stop, - isStartIncluded : intervals[index - 1].isStartIncluded, - isStopIncluded : interval.isStopIncluded, - data : interval.data - }); - } else { - interval = new TimeInterval({ - start : intervals[index - 1].start, - stop : intervals[index - 1].stop, - isStartIncluded : intervals[index - 1].isStartIncluded, - isStopIncluded : intervals[index - 1].isStopIncluded || (interval.stop.equals(intervals[index - 1].stop) && interval.isStopIncluded), - data : interval.data - }); - } - intervals.splice(index - 1, 1); - --index; - } else { - // Overlapping intervals have different data. The new interval - // being added 'wins' so truncate the previous interval. - // If the existing interval extends past the end of the new one, - // split the existing interval into two intervals. - comparison = JulianDate.compare(intervals[index - 1].stop, interval.stop); - if (comparison > 0 || (comparison === 0 && intervals[index - 1].isStopIncluded && !interval.isStopIncluded)) { - intervals.splice(index - 1, 1, new TimeInterval({ - start : intervals[index - 1].start, - stop : interval.start, - isStartIncluded : intervals[index - 1].isStartIncluded, - isStopIncluded : !interval.isStartIncluded, - data : intervals[index - 1].data - }), new TimeInterval({ - start : interval.stop, - stop : intervals[index - 1].stop, - isStartIncluded : !interval.isStopIncluded, - isStopIncluded : intervals[index - 1].isStopIncluded, - data : intervals[index - 1].data - })); - } else { - intervals[index - 1] = new TimeInterval({ - start : intervals[index - 1].start, - stop : interval.start, - isStartIncluded : intervals[index - 1].isStartIncluded, - isStopIncluded : !interval.isStartIncluded, - data : intervals[index - 1].data - }); + if (vertexFormat.bitangent) { + Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); } } + + if (vertexFormat.normal) { + normals[attrIndex] = normal.x; + normals[attrIndex1] = normal.y; + normals[attrIndex2] = normal.z; + } + if (vertexFormat.tangent) { + tangents[attrIndex] = tangent.x; + tangents[attrIndex1] = tangent.y; + tangents[attrIndex2] = tangent.z; + } + if (vertexFormat.bitangent) { + bitangents[attrIndex] = bitangent.x; + bitangents[attrIndex1] = bitangent.y; + bitangents[attrIndex2] = bitangent.z; + } + attrIndex += 3; } } + return createAttributes(vertexFormat, { + positions : positions, + normals : normals, + tangents : tangents, + bitangents : bitangents + }); + } - while (index < intervals.length) { - // Not the last thing in the list, so see if the intervals after this one overlap this one. - comparison = JulianDate.compare(interval.stop, intervals[index].start); - if (comparison > 0 || (comparison === 0 && (interval.isStopIncluded || intervals[index].isStartIncluded))) { - // There is an overlap - if (defined(dataComparer) ? dataComparer(intervals[index].data, interval.data) : intervals[index].data === interval.data) { - // Overlapping intervals have the same data, so combine them - interval = new TimeInterval({ - start : interval.start, - stop : JulianDate.greaterThan(intervals[index].stop, interval.stop) ? intervals[index].stop : interval.stop, - isStartIncluded : interval.isStartIncluded, - isStopIncluded : JulianDate.greaterThan(intervals[index].stop, interval.stop) ? intervals[index].isStopIncluded : interval.isStopIncluded, - data : interval.data - }); - intervals.splice(index, 1); - } else { - // Overlapping intervals have different data. The new interval - // being added 'wins' so truncate the next interval. - intervals[index] = new TimeInterval({ - start : interval.stop, - stop : intervals[index].stop, - isStartIncluded : !interval.isStopIncluded, - isStopIncluded : intervals[index].isStopIncluded, - data : intervals[index].data - }); - if (intervals[index].isEmpty) { - intervals.splice(index, 1); - } else { - // Found a partial span, so it is not possible for the next - // interval to be spanned at all. Stop looking. - break; + var v1Scratch = new Cartesian3(); + var v2Scratch = new Cartesian3(); + + function calculateAttributesWall(positions, vertexFormat, ellipsoid) { + var length = positions.length; + + var normals = (vertexFormat.normal) ? new Float32Array(length) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(length) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(length) : undefined; + + var normalIndex = 0; + var tangentIndex = 0; + var bitangentIndex = 0; + var recomputeNormal = true; + + var bitangent = bitangentScratch; + var tangent = tangentScratch; + var normal = normalScratch; + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { + for (var i = 0; i < length; i += 6) { + var p = Cartesian3.fromArray(positions, i, positionScratch); + var p1 = Cartesian3.fromArray(positions, (i + 6) % length, v1Scratch); + if (recomputeNormal) { + var p2 = Cartesian3.fromArray(positions, (i + 3) % length, v2Scratch); + Cartesian3.subtract(p1, p, p1); + Cartesian3.subtract(p2, p, p2); + normal = Cartesian3.normalize(Cartesian3.cross(p2, p1, normal), normal); + recomputeNormal = false; + } + + if (Cartesian3.equalsEpsilon(p1, p, CesiumMath.EPSILON10)) { // if we've reached a corner + recomputeNormal = true; + } + + if (vertexFormat.tangent || vertexFormat.bitangent) { + bitangent = ellipsoid.geodeticSurfaceNormal(p, bitangent); + if (vertexFormat.tangent) { + tangent = Cartesian3.normalize(Cartesian3.cross(bitangent, normal, tangent), tangent); } } - } else { - // Found the last one we're spanning, so stop looking. - break; + + if (vertexFormat.normal) { + normals[normalIndex++] = normal.x; + normals[normalIndex++] = normal.y; + normals[normalIndex++] = normal.z; + normals[normalIndex++] = normal.x; + normals[normalIndex++] = normal.y; + normals[normalIndex++] = normal.z; + } + + if (vertexFormat.tangent) { + tangents[tangentIndex++] = tangent.x; + tangents[tangentIndex++] = tangent.y; + tangents[tangentIndex++] = tangent.z; + tangents[tangentIndex++] = tangent.x; + tangents[tangentIndex++] = tangent.y; + tangents[tangentIndex++] = tangent.z; + } + + if (vertexFormat.bitangent) { + bitangents[bitangentIndex++] = bitangent.x; + bitangents[bitangentIndex++] = bitangent.y; + bitangents[bitangentIndex++] = bitangent.z; + bitangents[bitangentIndex++] = bitangent.x; + bitangents[bitangentIndex++] = bitangent.y; + bitangents[bitangentIndex++] = bitangent.z; + } } } - // Add the new interval - intervals.splice(index, 0, interval); - this._changedEvent.raiseEvent(this); - }; + return createAttributes(vertexFormat, { + positions : positions, + normals : normals, + tangents : tangents, + bitangents : bitangents + }); + } - /** - * Removes the specified interval from this interval collection, creating a hole over the specified interval. - * The data property of the input interval is ignored. - * - * @param {TimeInterval} interval The interval to remove. - * @returns <code>true</code> if the interval was removed, <code>false</code> if no part of the interval was in the collection. - */ - TimeIntervalCollection.prototype.removeInterval = function(interval) { - if (!defined(interval)) { - throw new DeveloperError('interval is required'); - } - - if (interval.isEmpty) { - return false; - } + function constructRectangle(options) { + var vertexFormat = options.vertexFormat; + var ellipsoid = options.ellipsoid; + var size = options.size; + var height = options.height; + var width = options.width; - var result = false; - var intervals = this._intervals; + var positions = (vertexFormat.position) ? new Float64Array(size * 3) : undefined; + var textureCoordinates = (vertexFormat.st) ? new Float32Array(size * 2) : undefined; - var index = binarySearch(intervals, interval, compareIntervalStartTimes); - if (index < 0) { - index = ~index; - } + var posIndex = 0; + var stIndex = 0; - var intervalStart = interval.start; - var intervalStop = interval.stop; - var intervalIsStartIncluded = interval.isStartIncluded; - var intervalIsStopIncluded = interval.isStopIncluded; + var position = positionScratch; + var st = stScratch; - // Check for truncation of the end of the previous interval. - if (index > 0) { - var indexMinus1 = intervals[index - 1]; - var indexMinus1Stop = indexMinus1.stop; - if (JulianDate.greaterThan(indexMinus1Stop, intervalStart) || - (TimeInterval.equals(indexMinus1Stop, intervalStart) && - indexMinus1.isStopIncluded && intervalIsStartIncluded)) { - result = true; + var minX = Number.MAX_VALUE; + var minY = Number.MAX_VALUE; + var maxX = -Number.MAX_VALUE; + var maxY = -Number.MAX_VALUE; - if (JulianDate.greaterThan(indexMinus1Stop, intervalStop) || - (indexMinus1.isStopIncluded && !intervalIsStopIncluded && TimeInterval.equals(indexMinus1Stop, intervalStop))) { - // Break the existing interval into two pieces - intervals.splice(index, 0, new TimeInterval({ - start : intervalStop, - stop : indexMinus1Stop, - isStartIncluded : !intervalIsStopIncluded, - isStopIncluded : indexMinus1.isStopIncluded, - data : indexMinus1.data - })); + for (var row = 0; row < height; ++row) { + for (var col = 0; col < width; ++col) { + RectangleGeometryLibrary.computePosition(options, row, col, position, st); + + positions[posIndex++] = position.x; + positions[posIndex++] = position.y; + positions[posIndex++] = position.z; + + if (vertexFormat.st) { + textureCoordinates[stIndex++] = st.x; + textureCoordinates[stIndex++] = st.y; + + minX = Math.min(minX, st.x); + minY = Math.min(minY, st.y); + maxX = Math.max(maxX, st.x); + maxY = Math.max(maxY, st.y); } - intervals[index - 1] = new TimeInterval({ - start : indexMinus1.start, - stop : intervalStart, - isStartIncluded : indexMinus1.isStartIncluded, - isStopIncluded : !intervalIsStartIncluded, - data : indexMinus1.data - }); } } - // Check if the Start of the current interval should remain because interval.start is the same but - // it is not included. - var indexInterval = intervals[index]; - if (index < intervals.length && - !intervalIsStartIncluded && - indexInterval.isStartIncluded && - intervalStart.equals(indexInterval.start)) { - result = true; + if (vertexFormat.st && (minX < 0.0 || minY < 0.0 || maxX > 1.0 || maxY > 1.0)) { + for (var k = 0; k < textureCoordinates.length; k += 2) { + textureCoordinates[k] = (textureCoordinates[k] - minX) / (maxX - minX); + textureCoordinates[k + 1] = (textureCoordinates[k + 1] - minY) / (maxY - minY); + } + } - intervals.splice(index, 0, new TimeInterval({ - start : indexInterval.start, - stop : indexInterval.start, - isStartIncluded : true, - isStopIncluded : true, - data : indexInterval.data - })); + var geo = calculateAttributes(positions, vertexFormat, ellipsoid, options.tangentRotationMatrix); + + var indicesSize = 6 * (width - 1) * (height - 1); + var indices = IndexDatatype.createTypedArray(size, indicesSize); + var index = 0; + var indicesIndex = 0; + for (var i = 0; i < height - 1; ++i) { + for (var j = 0; j < width - 1; ++j) { + var upperLeft = index; + var lowerLeft = upperLeft + width; + var lowerRight = lowerLeft + 1; + var upperRight = upperLeft + 1; + indices[indicesIndex++] = upperLeft; + indices[indicesIndex++] = lowerLeft; + indices[indicesIndex++] = upperRight; + indices[indicesIndex++] = upperRight; + indices[indicesIndex++] = lowerLeft; + indices[indicesIndex++] = lowerRight; + ++index; + } ++index; - indexInterval = intervals[index]; } - // Remove any intervals that are completely overlapped by the input interval. - while (index < intervals.length && JulianDate.greaterThan(intervalStop, indexInterval.stop)) { - result = true; - intervals.splice(index, 1); - indexInterval = intervals[index]; + geo.indices = indices; + if (vertexFormat.st) { + geo.attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : textureCoordinates + }); } - // Check for the case where the input interval ends on the same date - // as an existing interval. - if (index < intervals.length && intervalStop.equals(indexInterval.stop)) { - result = true; + return geo; + } - if (!intervalIsStopIncluded && indexInterval.isStopIncluded) { - // Last point of interval should remain because the stop date is included in - // the existing interval but is not included in the input interval. - if ((index + 1) < intervals.length && intervals[index + 1].start.equals(intervalStop) && indexInterval.data === intervals[index + 1].data) { - // Combine single point with the next interval - intervals.splice(index, 1); - indexInterval = new TimeInterval({ - start : indexInterval.start, - stop : indexInterval.stop, - isStartIncluded : true, - isStopIncluded : indexInterval.isStopIncluded, - data : indexInterval.data - }); - } else { - indexInterval = new TimeInterval({ - start : intervalStop, - stop : intervalStop, - isStartIncluded : true, - isStopIncluded : true, - data : indexInterval.data - }); - } - intervals[index] = indexInterval; - } else { - // Interval is completely overlapped - intervals.splice(index, 1); - } - } + function addWallPositions(wallPositions, posIndex, i, topPositions, bottomPositions) { + wallPositions[posIndex++] = topPositions[i]; + wallPositions[posIndex++] = topPositions[i + 1]; + wallPositions[posIndex++] = topPositions[i + 2]; + wallPositions[posIndex++] = bottomPositions[i]; + wallPositions[posIndex++] = bottomPositions[i + 1]; + wallPositions[posIndex++] = bottomPositions[i + 2]; + return wallPositions; + } - // Truncate any partially-overlapped intervals. - if (index < intervals.length && - (JulianDate.greaterThan(intervalStop, indexInterval.start) || - (intervalStop.equals(indexInterval.start) && - intervalIsStopIncluded && - indexInterval.isStartIncluded))) { - result = true; - intervals[index] = new TimeInterval({ - start : intervalStop, - stop : indexInterval.stop, - isStartIncluded : !intervalIsStopIncluded, - isStopIncluded : indexInterval.isStopIncluded, - data : indexInterval.data - }); - } + function addWallTextureCoordinates(wallTextures, stIndex, i, st) { + wallTextures[stIndex++] = st[i]; + wallTextures[stIndex++] = st[i + 1]; + wallTextures[stIndex++] = st[i]; + wallTextures[stIndex++] = st[i + 1]; + return wallTextures; + } - if (result) { - this._changedEvent.raiseEvent(this); - } + var scratchVertexFormat = new VertexFormat(); - return result; - }; + function constructExtrudedRectangle(options) { + var shadowVolume = options.shadowVolume; + var vertexFormat = options.vertexFormat; + var surfaceHeight = options.surfaceHeight; + var extrudedHeight = options.extrudedHeight; + var minHeight = Math.min(extrudedHeight, surfaceHeight); + var maxHeight = Math.max(extrudedHeight, surfaceHeight); - /** - * Creates a new instance that is the intersection of this collection and the provided collection. - * - * @param {TimeIntervalCollection} other The collection to intersect with. - * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @param {TimeInterval~MergeCallback} [mergeCallback] A function which merges the data of the two intervals. If omitted, the data from the left interval will be used. - * @returns {TimeIntervalCollection} A new TimeIntervalCollection which is the intersection of this collection and the provided collection. - */ - TimeIntervalCollection.prototype.intersect = function(other, dataComparer, mergeCallback) { - if (!defined(other)) { - throw new DeveloperError('other is required.'); - } - - var left = 0; - var right = 0; - var result = new TimeIntervalCollection(); - var intervals = this._intervals; - var otherIntervals = other._intervals; + var height = options.height; + var width = options.width; + var ellipsoid = options.ellipsoid; + var i; - while (left < intervals.length && right < otherIntervals.length) { - var leftInterval = intervals[left]; - var rightInterval = otherIntervals[right]; - if (JulianDate.lessThan(leftInterval.stop, rightInterval.start)) { - ++left; - } else if (JulianDate.lessThan(rightInterval.stop, leftInterval.start)) { - ++right; - } else { - // The following will return an intersection whose data is 'merged' if the callback is defined - if (defined(mergeCallback) || - ((defined(dataComparer) && dataComparer(leftInterval.data, rightInterval.data)) || - (!defined(dataComparer) && rightInterval.data === leftInterval.data))) { + if (shadowVolume) { + options.vertexFormat = VertexFormat.clone(vertexFormat, scratchVertexFormat); + options.vertexFormat.normal = true; + } + var topBottomGeo = constructRectangle(options); + if (CesiumMath.equalsEpsilon(minHeight, maxHeight, CesiumMath.EPSILON10)) { + return topBottomGeo; + } - var intersection = TimeInterval.intersect(leftInterval, rightInterval, new TimeInterval(), mergeCallback); - if (!intersection.isEmpty) { - // Since we start with an empty collection for 'result', and there are no overlapping intervals in 'this' (as a rule), - // the 'intersection' will never overlap with a previous interval in 'result'. So, no need to do any additional 'merging'. - result.addInterval(intersection, dataComparer); - } - } + var topPositions = PolygonPipeline.scaleToGeodeticHeight(topBottomGeo.attributes.position.values, maxHeight, ellipsoid, false); + topPositions = new Float64Array(topPositions); + var length = topPositions.length; + var newLength = length * 2; + var positions = new Float64Array(newLength); + positions.set(topPositions); + var bottomPositions = PolygonPipeline.scaleToGeodeticHeight(topBottomGeo.attributes.position.values, minHeight, ellipsoid); + positions.set(bottomPositions, length); + topBottomGeo.attributes.position.values = positions; - if (JulianDate.lessThan(leftInterval.stop, rightInterval.stop) || - (leftInterval.stop.equals(rightInterval.stop) && - !leftInterval.isStopIncluded && - rightInterval.isStopIncluded)) { - ++left; - } else { - ++right; - } + var normals = (vertexFormat.normal) ? new Float32Array(newLength) : undefined; + var tangents = (vertexFormat.tangent) ? new Float32Array(newLength) : undefined; + var bitangents = (vertexFormat.bitangent) ? new Float32Array(newLength) : undefined; + var textures = (vertexFormat.st) ? new Float32Array(newLength / 3 * 2) : undefined; + var topSt; + var topNormals; + if (vertexFormat.normal) { + topNormals = topBottomGeo.attributes.normal.values; + normals.set(topNormals); + for (i = 0; i < length; i++) { + topNormals[i] = -topNormals[i]; } + normals.set(topNormals, length); + topBottomGeo.attributes.normal.values = normals; + } + if (shadowVolume) { + topNormals = topBottomGeo.attributes.normal.values; + if (!vertexFormat.normal) { + topBottomGeo.attributes.normal = undefined; + } + var extrudeNormals = new Float32Array(newLength); + for (i = 0; i < length; i++) { + topNormals[i] = -topNormals[i]; + } + extrudeNormals.set(topNormals, length); //only get normals for bottom layer that's going to be pushed down + topBottomGeo.attributes.extrudeDirection = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : extrudeNormals + }); } - return result; - }; - /** - * Creates a new instance from a JulianDate array. - * - * @param {Object} options Object with the following properties: - * @param {JulianDate[]} options.julianDates An array of ISO 8601 dates. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. - * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. - * @param {TimeIntervalCollection} [result] An existing instance to use for the result. - * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. - */ - TimeIntervalCollection.fromJulianDateArray = function(options, result) { - if (!defined(options)) { - throw new DeveloperError('options is required.'); + if (vertexFormat.tangent) { + var topTangents = topBottomGeo.attributes.tangent.values; + tangents.set(topTangents); + for (i = 0; i < length; i++) { + topTangents[i] = -topTangents[i]; + } + tangents.set(topTangents, length); + topBottomGeo.attributes.tangent.values = tangents; } - if (!defined(options.julianDates)) { - throw new DeveloperError('options.iso8601Array is required.'); + if (vertexFormat.bitangent) { + var topBitangents = topBottomGeo.attributes.bitangent.values; + bitangents.set(topBitangents); + bitangents.set(topBitangents, length); + topBottomGeo.attributes.bitangent.values = bitangents; } - - if (!defined(result)) { - result = new TimeIntervalCollection(); + if (vertexFormat.st) { + topSt = topBottomGeo.attributes.st.values; + textures.set(topSt); + textures.set(topSt, length / 3 * 2); + topBottomGeo.attributes.st.values = textures; } - var julianDates = options.julianDates; - var length = julianDates.length; - var dataCallback = options.dataCallback; + var indices = topBottomGeo.indices; + var indicesLength = indices.length; + var posLength = length / 3; + var newIndices = IndexDatatype.createTypedArray(newLength / 3, indicesLength * 2); + newIndices.set(indices); + for (i = 0; i < indicesLength; i += 3) { + newIndices[i + indicesLength] = indices[i + 2] + posLength; + newIndices[i + 1 + indicesLength] = indices[i + 1] + posLength; + newIndices[i + 2 + indicesLength] = indices[i] + posLength; + } + topBottomGeo.indices = newIndices; - var isStartIncluded = defaultValue(options.isStartIncluded, true); - var isStopIncluded = defaultValue(options.isStopIncluded, true); - var leadingInterval = defaultValue(options.leadingInterval, false); - var trailingInterval = defaultValue(options.trailingInterval, false); - var interval; + var perimeterPositions = 2 * width + 2 * height - 4; + var wallCount = (perimeterPositions + 4) * 2; - // Add a default interval, which will only end up being used up to first interval - var startIndex = 0; - if (leadingInterval) { - ++startIndex; - interval = new TimeInterval({ - start : Iso8601.MINIMUM_VALUE, - stop : julianDates[0], - isStartIncluded : true, - isStopIncluded : !isStartIncluded - }); - interval.data = defined(dataCallback) ? dataCallback(interval, result.length) : result.length; - result.addInterval(interval); + var wallPositions = new Float64Array(wallCount * 3); + var wallExtrudeNormals = shadowVolume ? new Float32Array(wallCount * 3) : undefined; + var wallTextures = (vertexFormat.st) ? new Float32Array(wallCount * 2) : undefined; + + var posIndex = 0; + var stIndex = 0; + var extrudeNormalIndex = 0; + var area = width * height; + var threeI; + for (i = 0; i < area; i += width) { + threeI = i * 3; + wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); + posIndex += 6; + if (vertexFormat.st) { + wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); + stIndex += 4; + } + if (shadowVolume) { + extrudeNormalIndex += 3; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; + } } - for (var i = 0; i < length - 1; ++i) { - var startDate = julianDates[i]; - var endDate = julianDates[i + 1]; + for (i = area - width; i < area; i++) { + threeI = i * 3; + wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); + posIndex += 6; + if (vertexFormat.st) { + wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); + stIndex += 4; + } + if (shadowVolume) { + extrudeNormalIndex += 3; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; + } + } - interval = new TimeInterval({ - start : startDate, - stop : endDate, - isStartIncluded : (result.length === startIndex) ? isStartIncluded : true, - isStopIncluded : (i === (length - 2)) ? isStopIncluded : false - }); - interval.data = defined(dataCallback) ? dataCallback(interval, result.length) : result.length; - result.addInterval(interval); + for (i = area - 1; i > 0; i -= width) { + threeI = i * 3; + wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); + posIndex += 6; + if (vertexFormat.st) { + wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); + stIndex += 4; + } + if (shadowVolume) { + extrudeNormalIndex += 3; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; + } + } - startDate = endDate; + for (i = width - 1; i >= 0; i--) { + threeI = i * 3; + wallPositions = addWallPositions(wallPositions, posIndex, threeI, topPositions, bottomPositions); + posIndex += 6; + if (vertexFormat.st) { + wallTextures = addWallTextureCoordinates(wallTextures, stIndex, i * 2, topSt); + stIndex += 4; + } + if (shadowVolume) { + extrudeNormalIndex += 3; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 1]; + wallExtrudeNormals[extrudeNormalIndex++] = topNormals[threeI + 2]; + } } - if (trailingInterval) { - interval = new TimeInterval({ - start : julianDates[length - 1], - stop : Iso8601.MAXIMUM_VALUE, - isStartIncluded : !isStopIncluded, - isStopIncluded : true + var geo = calculateAttributesWall(wallPositions, vertexFormat, ellipsoid); + + if (vertexFormat.st) { + geo.attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : wallTextures + }); + } + if (shadowVolume) { + geo.attributes.extrudeDirection = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : wallExtrudeNormals }); - interval.data = defined(dataCallback) ? dataCallback(interval, result.length) : result.length; - result.addInterval(interval); } - return result; - }; - - var scratchGregorianDate = new GregorianDate(); - var monthLengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + var wallIndices = IndexDatatype.createTypedArray(wallCount, perimeterPositions * 6); - /** - * Adds duration represented as a GregorianDate to a JulianDate - * - * @param {JulianDate} julianDate The date. - * @param {GregorianDate} duration An duration represented as a GregorianDate. - * @param {JulianDate} result An existing instance to use for the result. - * @returns {JulianDate} The modified result parameter. - * - * @private - */ - function addToDate(julianDate, duration, result) { - if (!defined(result)) { - result = new JulianDate(); + var upperLeft; + var lowerLeft; + var lowerRight; + var upperRight; + length = wallPositions.length / 3; + var index = 0; + for (i = 0; i < length - 1; i += 2) { + upperLeft = i; + upperRight = (upperLeft + 2) % length; + var p1 = Cartesian3.fromArray(wallPositions, upperLeft * 3, v1Scratch); + var p2 = Cartesian3.fromArray(wallPositions, upperRight * 3, v2Scratch); + if (Cartesian3.equalsEpsilon(p1, p2, CesiumMath.EPSILON10)) { + continue; + } + lowerLeft = (upperLeft + 1) % length; + lowerRight = (lowerLeft + 2) % length; + wallIndices[index++] = upperLeft; + wallIndices[index++] = lowerLeft; + wallIndices[index++] = upperRight; + wallIndices[index++] = upperRight; + wallIndices[index++] = lowerLeft; + wallIndices[index++] = lowerRight; } - JulianDate.toGregorianDate(julianDate, scratchGregorianDate); - var millisecond = scratchGregorianDate.millisecond + duration.millisecond; - var second = scratchGregorianDate.second + duration.second; - var minute = scratchGregorianDate.minute + duration.minute; - var hour = scratchGregorianDate.hour + duration.hour; - var day = scratchGregorianDate.day + duration.day; - var month = scratchGregorianDate.month + duration.month; - var year = scratchGregorianDate.year + duration.year; + geo.indices = wallIndices; - if (millisecond >= 1000) { - second += Math.floor(millisecond / 1000); - millisecond = millisecond % 1000; - } + geo = GeometryPipeline.combineInstances([ + new GeometryInstance({ + geometry : topBottomGeo + }), + new GeometryInstance({ + geometry : geo + }) + ]); - if (second >= 60) { - minute += Math.floor(second / 60); - second = second % 60; - } + return geo[0]; + } - if (minute >= 60) { - hour += Math.floor(minute / 60); - minute = minute % 60; - } + var scratchRotationMatrix = new Matrix3(); + var scratchCartesian3 = new Cartesian3(); + var scratchQuaternion = new Quaternion(); + var scratchRectanglePoints = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; + var scratchCartographicPoints = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; - if (hour >= 24) { - day += Math.floor(hour / 24); - hour = hour % 24; + function computeRectangle(rectangle, ellipsoid, rotation) { + if (rotation === 0.0) { + return Rectangle.clone(rectangle); } - // If days is greater than the month's length we need to remove those number of days, - // readjust month and year and repeat until days is less than the month's length. - monthLengths[2] = isLeapYear(year) ? 29 : 28; - while ((day > monthLengths[month]) || (month >= 13)) { - if (day > monthLengths[month]) { - day -= monthLengths[month]; - ++month; - } + Rectangle.northeast(rectangle, scratchCartographicPoints[0]); + Rectangle.northwest(rectangle, scratchCartographicPoints[1]); + Rectangle.southeast(rectangle, scratchCartographicPoints[2]); + Rectangle.southwest(rectangle, scratchCartographicPoints[3]); - if (month >= 13) { - --month; - year += Math.floor(month / 12); - month = month % 12; - ++month; - } + ellipsoid.cartographicArrayToCartesianArray(scratchCartographicPoints, scratchRectanglePoints); - monthLengths[2] = isLeapYear(year) ? 29 : 28; + var surfaceNormal = ellipsoid.geodeticSurfaceNormalCartographic(Rectangle.center(rectangle, scratchCartesian3)); + Quaternion.fromAxisAngle(surfaceNormal, rotation, scratchQuaternion); + + Matrix3.fromQuaternion(scratchQuaternion, scratchRotationMatrix); + for (var i = 0; i < 4; ++i) { + // Apply the rotation + Matrix3.multiplyByVector(scratchRotationMatrix, scratchRectanglePoints[i], scratchRectanglePoints[i]); } - scratchGregorianDate.millisecond = millisecond; - scratchGregorianDate.second = second; - scratchGregorianDate.minute = minute; - scratchGregorianDate.hour = hour; - scratchGregorianDate.day = day; - scratchGregorianDate.month = month; - scratchGregorianDate.year = year; + ellipsoid.cartesianArrayToCartographicArray(scratchRectanglePoints, scratchCartographicPoints); - return JulianDate.fromGregorianDate(scratchGregorianDate, result); + return Rectangle.fromCartographicArray(scratchCartographicPoints); } - var scratchJulianDate = new JulianDate(); - var durationRegex = /P(?:([\d.,]+)Y)?(?:([\d.,]+)M)?(?:([\d.,]+)W)?(?:([\d.,]+)D)?(?:T(?:([\d.,]+)H)?(?:([\d.,]+)M)?(?:([\d.,]+)S)?)?/; - /** - * Parses ISO8601 duration string + * A description of a cartographic rectangle on an ellipsoid centered at the origin. Rectangle geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. * - * @param {String} iso8601 An ISO 8601 duration. - * @param {GregorianDate} result An existing instance to use for the result. - * @returns {Boolean} True is parsing succeeded, false otherwise + * @alias RectangleGeometry + * @constructor * - * @private + * @param {Object} options Object with the following properties: + * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. + * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. + * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {Number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. + * @param {Boolean} [options.closeTop=true] Specifies whether the rectangle has a top cover when extruded. + * @param {Boolean} [options.closeBottom=true] Specifies whether the rectangle has a bottom cover when extruded. + * + * @exception {DeveloperError} <code>options.rectangle.north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. + * @exception {DeveloperError} <code>options.rectangle.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. + * @exception {DeveloperError} <code>options.rectangle.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. + * @exception {DeveloperError} <code>options.rectangle.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. + * @exception {DeveloperError} <code>options.rectangle.north</code> must be greater than <code>options.rectangle.south</code>. + * + * @see RectangleGeometry#createGeometry + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo} + * + * @example + * // 1. create a rectangle + * var rectangle = new Cesium.RectangleGeometry({ + * ellipsoid : Cesium.Ellipsoid.WGS84, + * rectangle : Cesium.Rectangle.fromDegrees(-80.0, 39.0, -74.0, 42.0), + * height : 10000.0 + * }); + * var geometry = Cesium.RectangleGeometry.createGeometry(rectangle); + * + * // 2. create an extruded rectangle without a top + * var rectangle = new Cesium.RectangleGeometry({ + * ellipsoid : Cesium.Ellipsoid.WGS84, + * rectangle : Cesium.Rectangle.fromDegrees(-80.0, 39.0, -74.0, 42.0), + * height : 10000.0, + * extrudedHeight: 300000, + * closeTop: false + * }); + * var geometry = Cesium.RectangleGeometry.createGeometry(rectangle); */ - function parseDuration(iso8601, result) { - if (!defined(iso8601) || iso8601.length === 0) { - return false; - } + function RectangleGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - // Reset object - result.year = 0; - result.month = 0; - result.day = 0; - result.hour = 0; - result.minute = 0; - result.second = 0; - result.millisecond = 0; + var rectangle = options.rectangle; - if (iso8601[0] === 'P') { - var matches = iso8601.match(durationRegex); - if (!defined(matches)) { - return false; - } - if (defined(matches[1])) { // Years - result.year = Number(matches[1].replace(',', '.')); - } - if (defined(matches[2])) { // Months - result.month = Number(matches[2].replace(',', '.')); - } - if (defined(matches[3])) { // Weeks - result.day = Number(matches[3].replace(',', '.')) * 7; - } - if (defined(matches[4])) { // Days - result.day += Number(matches[4].replace(',', '.')); - } - if (defined(matches[5])) { // Hours - result.hour = Number(matches[5].replace(',', '.')); - } - if (defined(matches[6])) { // Weeks - result.minute = Number(matches[6].replace(',', '.')); - } - if (defined(matches[7])) { // Seconds - var seconds = Number(matches[7].replace(',', '.')); - result.second = Math.floor(seconds); - result.millisecond = (seconds % 1) * 1000; - } - } else { - // They can technically specify the duration as a normal date with some caveats. Try our best to load it. - if (iso8601[iso8601.length - 1] !== 'Z') { // It's not a date, its a duration, so it always has to be UTC - iso8601 += 'Z'; - } - JulianDate.toGregorianDate(JulianDate.fromIso8601(iso8601, scratchJulianDate), result); + Check.typeOf.object('rectangle', rectangle); + Rectangle.validate(rectangle); + if (rectangle.north < rectangle.south) { + throw new DeveloperError('options.rectangle.north must be greater than or equal to options.rectangle.south'); } - - // A duration of 0 will cause an infinite loop, so just make sure something is non-zero - return (result.year || result.month || result.day || result.hour || - result.minute || result.second || result.millisecond); + + var rotation = defaultValue(options.rotation, 0.0); + this._rectangle = rectangle; + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84)); + this._surfaceHeight = defaultValue(options.height, 0.0); + this._rotation = rotation; + this._stRotation = defaultValue(options.stRotation, 0.0); + this._vertexFormat = VertexFormat.clone(defaultValue(options.vertexFormat, VertexFormat.DEFAULT)); + this._extrudedHeight = defaultValue(options.extrudedHeight, 0.0); + this._extrude = defined(options.extrudedHeight); + this._closeTop = defaultValue(options.closeTop, true); + this._closeBottom = defaultValue(options.closeBottom, true); + this._shadowVolume = defaultValue(options.shadowVolume, false); + this._workerName = 'createRectangleGeometry'; + this._rotatedRectangle = computeRectangle(this._rectangle, this._ellipsoid, rotation); } - var scratchDuration = new GregorianDate(); /** - * Creates a new instance from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} time interval (start/end/duration). + * The number of elements used to pack the object into an array. + * @type {Number} + */ + RectangleGeometry.packedLength = Rectangle.packedLength + Ellipsoid.packedLength + VertexFormat.packedLength + Rectangle.packedLength + 9; + + /** + * Stores the provided instance into the provided array. * - * @param {Object} options Object with the following properties: - * @param {String} options.iso8601 An ISO 8601 interval. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. - * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. - * @param {TimeIntervalCollection} [result] An existing instance to use for the result. - * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. + * @param {RectangleGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - TimeIntervalCollection.fromIso8601 = function(options, result) { - if (!defined(options)) { - throw new DeveloperError('options is required.'); - } - if (!defined(options.iso8601)) { - throw new DeveloperError('options.iso8601 is required.'); - } + RectangleGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); - var dates = options.iso8601.split('/'); - var start = JulianDate.fromIso8601(dates[0]); - var stop = JulianDate.fromIso8601(dates[1]); - var julianDates = []; + startingIndex = defaultValue(startingIndex, 0); - if (!parseDuration(dates[2], scratchDuration)) { - julianDates.push(start, stop); - } else { - var date = JulianDate.clone(start); - julianDates.push(date); - while (JulianDate.compare(date, stop) < 0) { - date = addToDate(date, scratchDuration); - var afterStop = (JulianDate.compare(stop, date) <= 0); - if (afterStop) { - JulianDate.clone(stop, date); - } + Rectangle.pack(value._rectangle, array, startingIndex); + startingIndex += Rectangle.packedLength; - julianDates.push(date); - } - } + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - return TimeIntervalCollection.fromJulianDateArray({ - julianDates : julianDates, - isStartIncluded : options.isStartIncluded, - isStopIncluded : options.isStopIncluded, - leadingInterval : options.leadingInterval, - trailingInterval : options.trailingInterval, - dataCallback : options.dataCallback - }, result); + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + + Rectangle.pack(value._rotatedRectangle, array, startingIndex); + startingIndex += Rectangle.packedLength; + + array[startingIndex++] = value._granularity; + array[startingIndex++] = value._surfaceHeight; + array[startingIndex++] = value._rotation; + array[startingIndex++] = value._stRotation; + array[startingIndex++] = value._extrudedHeight; + array[startingIndex++] = value._extrude ? 1.0 : 0.0; + array[startingIndex++] = value._closeTop ? 1.0 : 0.0; + array[startingIndex++] = value._closeBottom ? 1.0 : 0.0; + array[startingIndex] = value._shadowVolume ? 1.0 : 0.0; + + return array; + }; + + var scratchRectangle = new Rectangle(); + var scratchRotatedRectangle = new Rectangle(); + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchOptions = { + rectangle : scratchRectangle, + ellipsoid : scratchEllipsoid, + vertexFormat : scratchVertexFormat, + granularity : undefined, + height : undefined, + rotation : undefined, + stRotation : undefined, + extrudedHeight : undefined, + closeTop : undefined, + closeBottom : undefined, + shadowVolume : undefined }; /** - * Creates a new instance from a {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} date array. + * Retrieves an instance from a packed array. * - * @param {Object} options Object with the following properties: - * @param {String[]} options.iso8601Dates An array of ISO 8601 dates. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. - * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. - * @param {TimeIntervalCollection} [result] An existing instance to use for the result. - * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {RectangleGeometry} [result] The object into which to store the result. + * @returns {RectangleGeometry} The modified result parameter or a new RectangleGeometry instance if one was not provided. */ - TimeIntervalCollection.fromIso8601DateArray = function(options, result) { - if (!defined(options)) { - throw new DeveloperError('options is required.'); - } - if (!defined(options.iso8601Dates)) { - throw new DeveloperError('options.iso8601Dates is required.'); - } + RectangleGeometry.unpack = function(array, startingIndex, result) { + Check.defined('array', array); - return TimeIntervalCollection.fromJulianDateArray({ - julianDates : options.iso8601Dates.map(function(date) { - return JulianDate.fromIso8601(date); - }), - isStartIncluded : options.isStartIncluded, - isStopIncluded : options.isStopIncluded, - leadingInterval : options.leadingInterval, - trailingInterval : options.trailingInterval, - dataCallback : options.dataCallback - }, result); + startingIndex = defaultValue(startingIndex, 0); + + var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); + startingIndex += Rectangle.packedLength; + + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; + + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; + + var rotatedRectangle = Rectangle.unpack(array, startingIndex, scratchRotatedRectangle); + startingIndex += Rectangle.packedLength; + + var granularity = array[startingIndex++]; + var surfaceHeight = array[startingIndex++]; + var rotation = array[startingIndex++]; + var stRotation = array[startingIndex++]; + var extrudedHeight = array[startingIndex++]; + var extrude = array[startingIndex++] === 1.0; + var closeTop = array[startingIndex++] === 1.0; + var closeBottom = array[startingIndex++] === 1.0; + var shadowVolume = array[startingIndex] === 1.0; + + if (!defined(result)) { + scratchOptions.granularity = granularity; + scratchOptions.height = surfaceHeight; + scratchOptions.rotation = rotation; + scratchOptions.stRotation = stRotation; + scratchOptions.extrudedHeight = extrude ? extrudedHeight : undefined; + scratchOptions.closeTop = closeTop; + scratchOptions.closeBottom = closeBottom; + scratchOptions.shadowVolume = shadowVolume; + return new RectangleGeometry(scratchOptions); + } + + result._rectangle = Rectangle.clone(rectangle, result._rectangle); + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._granularity = granularity; + result._surfaceHeight = surfaceHeight; + result._rotation = rotation; + result._stRotation = stRotation; + result._extrudedHeight = extrude ? extrudedHeight : undefined; + result._extrude = extrude; + result._closeTop = closeTop; + result._closeBottom = closeBottom; + result._rotatedRectangle = rotatedRectangle; + result._shadowVolume = shadowVolume; + + return result; }; + var tangentRotationMatrixScratch = new Matrix3(); + var nwScratch = new Cartographic(); + var stNwScratch = new Cartographic(); + var quaternionScratch = new Quaternion(); + var centerScratch = new Cartographic(); /** - * Creates a new instance from a {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} duration array. + * Computes the geometric representation of a rectangle, including its vertices, indices, and a bounding sphere. * - * @param {Object} options Object with the following properties: - * @param {JulianDate} options.epoch An date that the durations are relative to. - * @param {String} options.iso8601Durations An array of ISO 8601 durations. - * @param {Boolean} [options.relativeToPrevious=false] <code>true</code> if durations are relative to previous date, <code>false</code> if always relative to the epoch. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. - * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. - * @param {TimeIntervalCollection} [result] An existing instance to use for the result. - * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. + * @param {RectangleGeometry} rectangleGeometry A description of the rectangle. + * @returns {Geometry|undefined} The computed vertices and indices. + * + * @exception {DeveloperError} Rotated rectangle is invalid. */ - TimeIntervalCollection.fromIso8601DurationArray = function(options, result) { - if (!defined(options)) { - throw new DeveloperError('options is required.'); - } - if (!defined(options.epoch)) { - throw new DeveloperError('options.epoch is required.'); - } - if (!defined(options.iso8601Durations)) { - throw new DeveloperError('options.iso8601Durations is required.'); + RectangleGeometry.createGeometry = function(rectangleGeometry) { + if ((CesiumMath.equalsEpsilon(rectangleGeometry._rectangle.north, rectangleGeometry._rectangle.south, CesiumMath.EPSILON10) || + (CesiumMath.equalsEpsilon(rectangleGeometry._rectangle.east, rectangleGeometry._rectangle.west, CesiumMath.EPSILON10)))) { + return undefined; } - - var epoch = options.epoch; - var iso8601Durations = options.iso8601Durations; - var relativeToPrevious = defaultValue(options.relativeToPrevious, false); - var julianDates = []; - var date, previousDate; - var length = iso8601Durations.length; - for (var i = 0; i < length; ++i) { - // Allow a duration of 0 on the first iteration, because then it is just the epoch - if (parseDuration(iso8601Durations[i], scratchDuration) || i === 0) { - if (relativeToPrevious && defined(previousDate)) { - date = addToDate(previousDate, scratchDuration); - } else { - date = addToDate(epoch, scratchDuration); - } - julianDates.push(date); - previousDate = date; - } + var rectangle = Rectangle.clone(rectangleGeometry._rectangle, rectangleScratch); + var ellipsoid = rectangleGeometry._ellipsoid; + var surfaceHeight = rectangleGeometry._surfaceHeight; + var extrude = rectangleGeometry._extrude; + var extrudedHeight = rectangleGeometry._extrudedHeight; + var rotation = rectangleGeometry._rotation; + var stRotation = rectangleGeometry._stRotation; + var vertexFormat = rectangleGeometry._vertexFormat; + + var options = RectangleGeometryLibrary.computeOptions(rectangleGeometry, rectangle, nwScratch, stNwScratch); + + var tangentRotationMatrix = tangentRotationMatrixScratch; + if (stRotation !== 0 || rotation !== 0) { + var center = Rectangle.center(rectangle, centerScratch); + var axis = ellipsoid.geodeticSurfaceNormalCartographic(center, v1Scratch); + Quaternion.fromAxisAngle(axis, -stRotation, quaternionScratch); + Matrix3.fromQuaternion(quaternionScratch, tangentRotationMatrix); + } else { + Matrix3.clone(Matrix3.IDENTITY, tangentRotationMatrix); } - return TimeIntervalCollection.fromJulianDateArray({ - julianDates : julianDates, - isStartIncluded : options.isStartIncluded, - isStopIncluded : options.isStopIncluded, - leadingInterval : options.leadingInterval, - trailingInterval : options.trailingInterval, - dataCallback : options.dataCallback - }, result); - }; + options.lonScalar = 1.0 / rectangleGeometry._rectangle.width; + options.latScalar = 1.0 / rectangleGeometry._rectangle.height; + options.vertexFormat = vertexFormat; + options.rotation = rotation; + options.stRotation = stRotation; + options.tangentRotationMatrix = tangentRotationMatrix; + options.size = options.width * options.height; - return TimeIntervalCollection; -}); + var geometry; + var boundingSphere; + rectangle = rectangleGeometry._rectangle; + if (extrude) { + options.shadowVolume = rectangleGeometry._shadowVolume; + geometry = constructExtrudedRectangle(options); + var topBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight, topBoundingSphere); + var bottomBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, extrudedHeight, bottomBoundingSphere); + boundingSphere = BoundingSphere.union(topBS, bottomBS); + } else { + geometry = constructRectangle(options); + geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.attributes.position.values, surfaceHeight, ellipsoid, false); + boundingSphere = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight); + } -define('Core/TranslationRotationScale',[ - './Cartesian3', - './defaultValue', - './defined', - './Quaternion' - ], function( - Cartesian3, - defaultValue, - defined, - Quaternion) { - 'use strict'; + if (!vertexFormat.position) { + delete geometry.attributes.position; + } - var defaultScale = new Cartesian3(1.0, 1.0, 1.0); - var defaultTranslation = Cartesian3.ZERO; - var defaultRotation = Quaternion.IDENTITY; + return new Geometry({ + attributes : geometry.attributes, + indices : geometry.indices, + primitiveType : geometry.primitiveType, + boundingSphere : boundingSphere + }); + }; /** - * An affine transformation defined by a translation, rotation, and scale. - * @alias TranslationRotationScale - * @constructor - * - * @param {Cartesian3} [translation=Cartesian3.ZERO] A {@link Cartesian3} specifying the (x, y, z) translation to apply to the node. - * @param {Quaternion} [rotation=Quaternion.IDENTITY] A {@link Quaternion} specifying the (x, y, z, w) rotation to apply to the node. - * @param {Cartesian3} [scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} specifying the (x, y, z) scaling to apply to the node. + * @private */ - var TranslationRotationScale = function(translation, rotation, scale) { - /** - * Gets or sets the (x, y, z) translation to apply to the node. - * @type {Cartesian3} - * @default Cartesian3.ZERO - */ - this.translation = Cartesian3.clone(defaultValue(translation, defaultTranslation)); + RectangleGeometry.createShadowVolume = function(rectangleGeometry, minHeightFunc, maxHeightFunc) { + var granularity = rectangleGeometry._granularity; + var ellipsoid = rectangleGeometry._ellipsoid; - /** - * Gets or sets the (x, y, z, w) rotation to apply to the node. - * @type {Quaternion} - * @default Quaternion.IDENTITY - */ - this.rotation = Quaternion.clone(defaultValue(rotation, defaultRotation)); + var minHeight = minHeightFunc(granularity, ellipsoid); + var maxHeight = maxHeightFunc(granularity, ellipsoid); - /** - * Gets or sets the (x, y, z) scaling to apply to the node. - * @type {Cartesian3} - * @default new Cartesian3(1.0, 1.0, 1.0) - */ - this.scale = Cartesian3.clone(defaultValue(scale, defaultScale)); + // TODO: stRotation + return new RectangleGeometry({ + rectangle : rectangleGeometry._rectangle, + rotation : rectangleGeometry._rotation, + ellipsoid : ellipsoid, + stRotation : rectangleGeometry._stRotation, + granularity : granularity, + extrudedHeight : maxHeight, + height : minHeight, + closeTop : true, + closeBottom : true, + vertexFormat : VertexFormat.POSITION_ONLY, + shadowVolume : true + }); }; - /** - * Compares this instance against the provided instance and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {TranslationRotationScale} [right] The right hand side TranslationRotationScale. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. - */ - TranslationRotationScale.prototype.equals = function(right) { - return (this === right) || - (defined(right) && - Cartesian3.equals(this.translation, right.translation) && - Quaternion.equals(this.rotation, right.rotation) && - Cartesian3.equals(this.scale, right.scale)); - }; + defineProperties(RectangleGeometry.prototype, { + /** + * @private + */ + rectangle : { + get : function() { + return this._rotatedRectangle; + } + } + }); - return TranslationRotationScale; + return RectangleGeometry; }); -define('Core/VideoSynchronizer',[ +define('Core/RectangleOutlineGeometry',[ + './BoundingSphere', + './Cartesian3', + './Cartographic', + './ComponentDatatype', './defaultValue', './defined', - './defineProperties', - './destroyObject', - './Iso8601', - './JulianDate' + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PolygonPipeline', + './PrimitiveType', + './Rectangle', + './RectangleGeometryLibrary' ], function( + BoundingSphere, + Cartesian3, + Cartographic, + ComponentDatatype, defaultValue, defined, - defineProperties, - destroyObject, - Iso8601, - JulianDate) { + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PolygonPipeline, + PrimitiveType, + Rectangle, + RectangleGeometryLibrary) { 'use strict'; - /** - * Synchronizes a video element with a simulation clock. - * - * @alias VideoSynchronizer - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Clock} [options.clock] The clock instance used to drive the video. - * @param {HTMLVideoElement} [options.element] The video element to be synchronized. - * @param {JulianDate} [options.epoch=Iso8601.MINIMUM_VALUE] The simulation time that marks the start of the video. - * @param {Number} [options.tolerance=1.0] The maximum amount of time, in seconds, that the clock and video can diverge. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Video.html|Video Material Demo} - */ - function VideoSynchronizer(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._clock = undefined; - this._element = undefined; - this._clockSubscription = undefined; - this._seekFunction = undefined; - - this.clock = options.clock; - this.element = options.element; - - /** - * Gets or sets the simulation time that marks the start of the video. - * @type {JulianDate} - * @default Iso8601.MINIMUM_VALUE - */ - this.epoch = defaultValue(options.epoch, Iso8601.MINIMUM_VALUE); - - /** - * Gets or sets the amount of time in seconds the video's currentTime - * and the clock's currentTime can diverge before a video seek is performed. - * Lower values make the synchronization more accurate but video - * performance might suffer. Higher values provide better performance - * but at the cost of accuracy. - * @type {Number} - * @default 1.0 - */ - this.tolerance = defaultValue(options.tolerance, 1.0); - - this._seeking = false; - this._seekFunction = undefined; - this._firstTickAfterSeek = false; - } - - defineProperties(VideoSynchronizer.prototype, { - /** - * Gets or sets the clock used to drive the video element. - * - * @memberof VideoSynchronizer.prototype - * @type {Clock} - */ - clock : { - get : function() { - return this._clock; - }, - set : function(value) { - var oldValue = this._clock; - - if (oldValue === value) { - return; - } - - if (defined(oldValue)) { - this._clockSubscription(); - this._clockSubscription = undefined; - } - - if (defined(value)) { - this._clockSubscription = value.onTick.addEventListener(VideoSynchronizer.prototype._onTick, this); - } - - this._clock = value; - } - }, - /** - * Gets or sets the video element to synchronize. - * - * @memberof VideoSynchronizer.prototype - * @type {HTMLVideoElement} - */ - element : { - get : function() { - return this._element; - }, - set : function(value) { - var oldValue = this._element; - - if (oldValue === value) { - return; - } - - if (defined(oldValue)) { - oldValue.removeEventListener('seeked', this._seekFunction, false); - } + var bottomBoundingSphere = new BoundingSphere(); + var topBoundingSphere = new BoundingSphere(); + var positionScratch = new Cartesian3(); + var rectangleScratch = new Rectangle(); - if (defined(value)) { - this._seeking = false; - this._seekFunction = createSeekFunction(this); - value.addEventListener('seeked', this._seekFunction, false); - } + function constructRectangle(options) { + var size = options.size; + var height = options.height; + var width = options.width; + var positions = new Float64Array(size * 3); - this._element = value; - this._seeking = false; - this._firstTickAfterSeek = false; - } + var posIndex = 0; + var row = 0; + var col; + var position = positionScratch; + for (col = 0; col < width; col++) { + RectangleGeometryLibrary.computePosition(options, row, col, position); + positions[posIndex++] = position.x; + positions[posIndex++] = position.y; + positions[posIndex++] = position.z; } - }); - - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - VideoSynchronizer.prototype.destroy = function() { - this.element = undefined; - this.clock = undefined; - return destroyObject(this); - }; - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - VideoSynchronizer.prototype.isDestroyed = function() { - return false; - }; + col = width - 1; + for (row = 1; row < height; row++) { + RectangleGeometryLibrary.computePosition(options, row, col, position); + positions[posIndex++] = position.x; + positions[posIndex++] = position.y; + positions[posIndex++] = position.z; + } - VideoSynchronizer.prototype._onTick = function(clock) { - var element = this._element; - if (!defined(element) || element.readyState < 2) { - return; + row = height - 1; + for (col = width-2; col >=0; col--){ + RectangleGeometryLibrary.computePosition(options, row, col, position); + positions[posIndex++] = position.x; + positions[posIndex++] = position.y; + positions[posIndex++] = position.z; } - var paused = element.paused; - var shouldAnimate = clock.shouldAnimate; - if (shouldAnimate === paused) { - if (shouldAnimate) { - element.play(); - } else { - element.pause(); - } + col = 0; + for (row = height - 2; row > 0; row--) { + RectangleGeometryLibrary.computePosition(options, row, col, position); + positions[posIndex++] = position.x; + positions[posIndex++] = position.y; + positions[posIndex++] = position.z; } - //We need to avoid constant seeking or the video will - //never contain a complete frame for us to render. - //So don't do anything if we're seeing or on the first - //tick after a seek (the latter of which allows the frame - //to actually be rendered. - if (this._seeking || this._firstTickAfterSeek) { - this._firstTickAfterSeek = false; - return; + var indicesSize = positions.length/3 * 2; + var indices = IndexDatatype.createTypedArray(positions.length / 3, indicesSize); + + var index = 0; + for(var i = 0; i < (positions.length/3)-1; i++) { + indices[index++] = i; + indices[index++] = i+1; } + indices[index++] = (positions.length/3)-1; + indices[index++] = 0; - element.playbackRate = clock.multiplier; + var geo = new Geometry({ + attributes : new GeometryAttributes(), + primitiveType : PrimitiveType.LINES + }); - var clockTime = clock.currentTime; - var epoch = defaultValue(this.epoch, Iso8601.MINIMUM_VALUE); - var videoTime = JulianDate.secondsDifference(clockTime, epoch); + geo.attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); + geo.indices = indices; - var duration = element.duration; - var desiredTime; - var currentTime = element.currentTime; - if (element.loop) { - videoTime = videoTime % duration; - if (videoTime < 0.0) { - videoTime = duration - videoTime; - } - desiredTime = videoTime; - } else if (videoTime > duration) { - desiredTime = duration; - } else if (videoTime < 0.0) { - desiredTime = 0.0; - } else { - desiredTime = videoTime; - } + return geo; + } - //If the playing video's time and the scene's clock time - //ever drift too far apart, we want to set the video to match - var tolerance = shouldAnimate ? defaultValue(this.tolerance, 1.0) : 0.001; - if (Math.abs(desiredTime - currentTime) > tolerance) { - this._seeking = true; - element.currentTime = desiredTime; + function constructExtrudedRectangle(options) { + var surfaceHeight = options.surfaceHeight; + var extrudedHeight = options.extrudedHeight; + var ellipsoid = options.ellipsoid; + var minHeight = Math.min(extrudedHeight, surfaceHeight); + var maxHeight = Math.max(extrudedHeight, surfaceHeight); + var geo = constructRectangle(options); + if (CesiumMath.equalsEpsilon(minHeight, maxHeight, CesiumMath.EPSILON10)) { + return geo; } - }; + var height = options.height; + var width = options.width; - function createSeekFunction(that) { - return function() { - that._seeking = false; - that._firstTickAfterSeek = true; - }; - } + var topPositions = PolygonPipeline.scaleToGeodeticHeight(geo.attributes.position.values, maxHeight, ellipsoid, false); + var length = topPositions.length; + var positions = new Float64Array(length*2); + positions.set(topPositions); + var bottomPositions = PolygonPipeline.scaleToGeodeticHeight(geo.attributes.position.values, minHeight, ellipsoid); + positions.set(bottomPositions, length); + geo.attributes.position.values = positions; - return VideoSynchronizer; -}); + var indicesSize = positions.length/3 * 2 + 8; + var indices = IndexDatatype.createTypedArray(positions.length / 3, indicesSize); + length = positions.length/6; + var index = 0; + for (var i = 0; i < length - 1; i++) { + indices[index++] = i; + indices[index++] =i+1; + indices[index++] = i + length; + indices[index++] = i + length + 1; + } + indices[index++] = length - 1; + indices[index++] = 0; + indices[index++] = length + length - 1; + indices[index++] = length; -define('Core/VRTheWorldTerrainProvider',[ - '../ThirdParty/when', - './Credit', - './defaultValue', - './defined', - './defineProperties', - './DeveloperError', - './Ellipsoid', - './Event', - './GeographicTilingScheme', - './getImagePixels', - './HeightmapTerrainData', - './loadImage', - './loadXML', - './Math', - './Rectangle', - './TerrainProvider', - './TileProviderError' - ], function( - when, - Credit, - defaultValue, - defined, - defineProperties, - DeveloperError, - Ellipsoid, - Event, - GeographicTilingScheme, - getImagePixels, - HeightmapTerrainData, - loadImage, - loadXML, - CesiumMath, - Rectangle, - TerrainProvider, - TileProviderError) { - 'use strict'; + indices[index++] = 0; + indices[index++] = length; + indices[index++] = width-1; + indices[index++] = length + width-1; + indices[index++] = width + height - 2; + indices[index++] = width + height - 2 + length; + indices[index++] = 2*width + height - 3; + indices[index++] = 2*width + height - 3 + length; - function DataRectangle(rectangle, maxLevel) { - this.rectangle = rectangle; - this.maxLevel = maxLevel; + geo.indices = indices; + + return geo; } /** - * A {@link TerrainProvider} that produces terrain geometry by tessellating height maps - * retrieved from a {@link http://vr-theworld.com/|VT MÄK VR-TheWorld server}. + * A description of the outline of a a cartographic rectangle on an ellipsoid centered at the origin. * - * @alias VRTheWorldTerrainProvider + * @alias RectangleOutlineGeometry * @constructor * * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the VR-TheWorld TileMap. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid. If this parameter is not - * specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. + * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. + * @param {Number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. + * + * @exception {DeveloperError} <code>options.rectangle.north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. + * @exception {DeveloperError} <code>options.rectangle.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. + * @exception {DeveloperError} <code>options.rectangle.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. + * @exception {DeveloperError} <code>options.rectangle.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>]. + * @exception {DeveloperError} <code>options.rectangle.north</code> must be greater than <code>rectangle.south</code>. * + * @see RectangleOutlineGeometry#createGeometry * * @example - * var terrainProvider = new Cesium.VRTheWorldTerrainProvider({ - * url : 'https://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/' + * var rectangle = new Cesium.RectangleOutlineGeometry({ + * ellipsoid : Cesium.Ellipsoid.WGS84, + * rectangle : Cesium.Rectangle.fromDegrees(-80.0, 39.0, -74.0, 42.0), + * height : 10000.0 * }); - * viewer.terrainProvider = terrainProvider; - * - * @see TerrainProvider + * var geometry = Cesium.RectangleOutlineGeometry.createGeometry(rectangle); */ - function VRTheWorldTerrainProvider(options) { + function RectangleOutlineGeometry(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); + + var rectangle = options.rectangle; + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var surfaceHeight = defaultValue(options.height, 0.0); + var rotation = defaultValue(options.rotation, 0.0); + var extrudedHeight = options.extrudedHeight; + + if (!defined(rectangle)) { + throw new DeveloperError('rectangle is required.'); + } + Rectangle.validate(rectangle); + if (rectangle.north < rectangle.south) { + throw new DeveloperError('options.rectangle.north must be greater than options.rectangle.south'); } - this._url = options.url; - if (this._url.length > 0 && this._url[this._url.length - 1] !== '/') { - this._url += '/'; + this._rectangle = rectangle; + this._granularity = granularity; + this._ellipsoid = ellipsoid; + this._surfaceHeight = surfaceHeight; + this._rotation = rotation; + this._extrudedHeight = extrudedHeight; + this._workerName = 'createRectangleOutlineGeometry'; + } + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + RectangleOutlineGeometry.packedLength = Rectangle.packedLength + Ellipsoid.packedLength + 5; + + /** + * Stores the provided instance into the provided array. + * + * @param {RectangleOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + RectangleOutlineGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); } - this._errorEvent = new Event(); - this._ready = false; - this._readyPromise = when.defer(); + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - this._proxy = options.proxy; + Rectangle.pack(value._rectangle, array, startingIndex); + startingIndex += Rectangle.packedLength; - this._terrainDataStructure = { - heightScale : 1.0 / 1000.0, - heightOffset : -1000.0, - elementsPerHeight : 3, - stride : 4, - elementMultiplier : 256.0, - isBigEndian : true, - lowestEncodedHeight : 0, - highestEncodedHeight : 256 * 256 * 256 - 1 - }; + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - var credit = options.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); + array[startingIndex++] = value._granularity; + array[startingIndex++] = value._surfaceHeight; + array[startingIndex++] = value._rotation; + array[startingIndex++] = defined(value._extrudedHeight) ? 1.0 : 0.0; + array[startingIndex] = defaultValue(value._extrudedHeight, 0.0); + + return array; + }; + + var scratchRectangle = new Rectangle(); + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchOptions = { + rectangle : scratchRectangle, + ellipsoid : scratchEllipsoid, + granularity : undefined, + height : undefined, + rotation : undefined, + extrudedHeight : undefined + }; + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {RectangleOutlineGeometry} [result] The object into which to store the result. + * @returns {RectangleOutlineGeometry} The modified result parameter or a new Quaternion instance if one was not provided. + */ + RectangleOutlineGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); } - this._credit = credit; + + startingIndex = defaultValue(startingIndex, 0); - this._tilingScheme = undefined; - this._rectangles = []; + var rectangle = Rectangle.unpack(array, startingIndex, scratchRectangle); + startingIndex += Rectangle.packedLength; - var that = this; - var metadataError; - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - function metadataSuccess(xml) { - var srs = xml.getElementsByTagName('SRS')[0].textContent; - if (srs === 'EPSG:4326') { - that._tilingScheme = new GeographicTilingScheme({ ellipsoid : ellipsoid }); - } else { - metadataFailure('SRS ' + srs + ' is not supported.'); - return; - } + var granularity = array[startingIndex++]; + var height = array[startingIndex++]; + var rotation = array[startingIndex++]; + var hasExtrudedHeight = array[startingIndex++]; + var extrudedHeight = array[startingIndex]; - var tileFormat = xml.getElementsByTagName('TileFormat')[0]; - that._heightmapWidth = parseInt(tileFormat.getAttribute('width'), 10); - that._heightmapHeight = parseInt(tileFormat.getAttribute('height'), 10); - that._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(ellipsoid, Math.min(that._heightmapWidth, that._heightmapHeight), that._tilingScheme.getNumberOfXTilesAtLevel(0)); + if (!defined(result)) { + scratchOptions.granularity = granularity; + scratchOptions.height = height; + scratchOptions.rotation = rotation; + scratchOptions.extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; + return new RectangleOutlineGeometry(scratchOptions); + } - var dataRectangles = xml.getElementsByTagName('DataExtent'); + result._rectangle = Rectangle.clone(rectangle, result._rectangle); + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._surfaceHeight = height; + result._rotation = rotation; + result._extrudedHeight = hasExtrudedHeight ? extrudedHeight : undefined; - for (var i = 0; i < dataRectangles.length; ++i) { - var dataRectangle = dataRectangles[i]; + return result; + }; - var west = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('minx'))); - var south = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('miny'))); - var east = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('maxx'))); - var north = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('maxy'))); - var maxLevel = parseInt(dataRectangle.getAttribute('maxlevel'), 10); + var nwScratch = new Cartographic(); + /** + * Computes the geometric representation of an outline of a rectangle, including its vertices, indices, and a bounding sphere. + * + * @param {RectangleOutlineGeometry} rectangleGeometry A description of the rectangle outline. + * @returns {Geometry|undefined} The computed vertices and indices. + * + * @exception {DeveloperError} Rotated rectangle is invalid. + */ + RectangleOutlineGeometry.createGeometry = function(rectangleGeometry) { + var rectangle = Rectangle.clone(rectangleGeometry._rectangle, rectangleScratch); + var ellipsoid = rectangleGeometry._ellipsoid; + var surfaceHeight = rectangleGeometry._surfaceHeight; + var extrudedHeight = rectangleGeometry._extrudedHeight; - that._rectangles.push(new DataRectangle(new Rectangle(west, south, east, north), maxLevel)); - } + var options = RectangleGeometryLibrary.computeOptions(rectangleGeometry, rectangle, nwScratch); + options.size = 2*options.width + 2*options.height - 4; - that._ready = true; - that._readyPromise.resolve(true); - } + var geometry; + var boundingSphere; + rectangle = rectangleGeometry._rectangle; - function metadataFailure(e) { - var message = defaultValue(e, 'An error occurred while accessing ' + that._url + '.'); - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + if ((CesiumMath.equalsEpsilon(rectangle.north, rectangle.south, CesiumMath.EPSILON10) || + (CesiumMath.equalsEpsilon(rectangle.east, rectangle.west, CesiumMath.EPSILON10)))) { + return undefined; } - - function requestMetadata() { - when(loadXML(that._url), metadataSuccess, metadataFailure); + if (defined(extrudedHeight)) { + geometry = constructExtrudedRectangle(options); + var topBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight, topBoundingSphere); + var bottomBS = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, extrudedHeight, bottomBoundingSphere); + boundingSphere = BoundingSphere.union(topBS, bottomBS); + } else { + geometry = constructRectangle(options); + geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometry.attributes.position.values, surfaceHeight, ellipsoid, false); + boundingSphere = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, surfaceHeight); } - requestMetadata(); - } + return new Geometry({ + attributes : geometry.attributes, + indices : geometry.indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : boundingSphere + }); + }; - defineProperties(VRTheWorldTerrainProvider.prototype, { - /** - * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {Event} - */ - errorEvent : { - get : function() { - return this._errorEvent; - } - }, + return RectangleOutlineGeometry; +}); - /** - * Gets the credit to display when this terrain provider is active. Typically this is used to credit - * the source of the terrain. This function should not be called before {@link VRTheWorldTerrainProvider#ready} returns true. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {Credit} - */ - credit : { - get : function() { - return this._credit; - } - }, +define('Core/ReferenceFrame',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** + * Constants for identifying well-known reference frames. + * + * @exports ReferenceFrame + */ + var ReferenceFrame = { /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link VRTheWorldTerrainProvider#ready} returns true. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {GeographicTilingScheme} + * The fixed frame. + * + * @type {Number} + * @constant */ - tilingScheme : { - get : function() { - if (!this.ready) { - throw new DeveloperError('requestTileGeometry must not be called before ready returns true.'); - } - - return this._tilingScheme; - } - }, + FIXED : 0, /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {Boolean} + * The inertial frame. + * + * @type {Number} + * @constant */ - ready : { - get : function() { - return this._ready; - } - }, + INERTIAL : 1 + }; - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; - } - }, + return freezeObject(ReferenceFrame); +}); - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. This function should not be - * called before {@link VRTheWorldTerrainProvider#ready} returns true. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {Boolean} - */ - hasWaterMask : { - get : function() { - return false; - } - }, +define('Core/requestAnimationFrame',[ + './defined', + './getTimestamp' + ], function( + defined, + getTimestamp) { + 'use strict'; - /** - * Gets a value indicating whether or not the requested tiles include vertex normals. - * This function should not be called before {@link VRTheWorldTerrainProvider#ready} returns true. - * @memberof VRTheWorldTerrainProvider.prototype - * @type {Boolean} - */ - hasVertexNormals : { - get : function() { - return false; + if (typeof window === 'undefined') { + return; + } + + var implementation = window.requestAnimationFrame; + + (function() { + // look for vendor prefixed function + if (!defined(implementation)) { + var vendors = ['webkit', 'moz', 'ms', 'o']; + var i = 0; + var len = vendors.length; + while (i < len && !defined(implementation)) { + implementation = window[vendors[i] + 'RequestAnimationFrame']; + ++i; } } - }); + + // build an implementation based on setTimeout + if (!defined(implementation)) { + var msPerFrame = 1000.0 / 60.0; + var lastFrameTime = 0; + implementation = function(callback) { + var currentTime = getTimestamp(); + + // schedule the callback to target 60fps, 16.7ms per frame, + // accounting for the time taken by the callback + var delay = Math.max(msPerFrame - (currentTime - lastFrameTime), 0); + lastFrameTime = currentTime + delay; + + return setTimeout(function() { + callback(lastFrameTime); + }, delay); + }; + } + })(); /** - * Requests the geometry for a given tile. This function should not be called before - * {@link VRTheWorldTerrainProvider#ready} returns true. The result includes terrain - * data and indicates that all child tiles are available. + * A browser-independent function to request a new animation frame. This is used to create + * an application's draw loop as shown in the example below. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method - * returns undefined instead of a promise, it is an indication that too many requests are already - * pending and the request will be retried later. + * @exports requestAnimationFrame + * + * @param {requestAnimationFrame~Callback} callback The function to call when the next frame should be drawn. + * @returns {Number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. + * + * + * @example + * // Create a draw loop using requestAnimationFrame. The + * // tick callback function is called for every animation frame. + * function tick() { + * scene.render(); + * Cesium.requestAnimationFrame(tick); + * } + * tick(); + * + * @see {@link https://www.w3.org/TR/html51/webappapis.html#animation-frames|The Web API Animation Frames interface} */ - VRTheWorldTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { - if (!this.ready) { - throw new DeveloperError('requestTileGeometry must not be called before ready returns true.'); - } - - var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level); - var url = this._url + level + '/' + x + '/' + (yTiles - y - 1) + '.tif?cesium=true'; + function requestAnimationFrame(callback) { + // we need this extra wrapper function because the native requestAnimationFrame + // functions must be invoked on the global scope (window), which is not the case + // if invoked as Cesium.requestAnimationFrame(callback) + return implementation(callback); + } - var proxy = this._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } + /** + * A function that will be called when the next frame should be drawn. + * @callback requestAnimationFrame~Callback + * + * @param {Number} timestamp A timestamp for the frame, in milliseconds. + */ - var promise = loadImage(url, undefined, request); - if (!defined(promise)) { - return undefined; - } + return requestAnimationFrame; +}); - var that = this; - return when(promise, function(image) { - return new HeightmapTerrainData({ - buffer : getImagePixels(image), - width : that._heightmapWidth, - height : that._heightmapHeight, - childTileMask : getChildMask(that, x, y, level), - structure : that._terrainDataStructure - }); - }); - }; +define('Core/sampleTerrain',[ + '../ThirdParty/when', + './Check' + ], function( + when, + Check) { + 'use strict'; /** - * Gets the maximum geometric error allowed in a tile at a given level. + * Initiates a terrain height query for an array of {@link Cartographic} positions by + * requesting tiles from a terrain provider, sampling, and interpolating. The interpolation + * matches the triangles used to render the terrain at the specified level. The query + * happens asynchronously, so this function returns a promise that is resolved when + * the query completes. Each point height is modified in place. If a height can not be + * determined because no terrain data is available for the specified level at that location, + * or another error occurs, the height is set to undefined. As is typical of the + * {@link Cartographic} type, the supplied height is a height above the reference ellipsoid + * (such as {@link Ellipsoid.WGS84}) rather than an altitude above mean sea level. In other + * words, it will not necessarily be 0.0 if sampled in the ocean. This function needs the + * terrain level of detail as input, if you need to get the altitude of the terrain as precisely + * as possible (i.e. with maximum level of detail) use {@link sampleTerrainMostDetailed}. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @exports sampleTerrain + * + * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights. + * @param {Number} level The terrain level-of-detail from which to query terrain heights. + * @param {Cartographic[]} positions The positions to update with terrain heights. + * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. + * + * @see sampleTerrainMostDetailed + * + * @example + * // Query the terrain height of two Cartographic positions + * var terrainProvider = new Cesium.CesiumTerrainProvider({ + * url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles' + * }); + * var positions = [ + * Cesium.Cartographic.fromDegrees(86.925145, 27.988257), + * Cesium.Cartographic.fromDegrees(87.0, 28.0) + * ]; + * var promise = Cesium.sampleTerrain(terrainProvider, 11, positions); + * Cesium.when(promise, function(updatedPositions) { + * // positions[0].height and positions[1].height have been updated. + * // updatedPositions is just a reference to positions. + * }); */ - VRTheWorldTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { - if (!this.ready) { - throw new DeveloperError('requestTileGeometry must not be called before ready returns true.'); - } - return this._levelZeroMaximumGeometricError / (1 << level); - }; + function sampleTerrain(terrainProvider, level, positions) { + Check.typeOf.object('terrainProvider', terrainProvider); + Check.typeOf.number('level', level); + Check.defined('positions', positions); + + return terrainProvider.readyPromise.then(function() { return doSampling(terrainProvider, level, positions); }); + } - var rectangleScratch = new Rectangle(); + function doSampling(terrainProvider, level, positions) { + var tilingScheme = terrainProvider.tilingScheme; - function getChildMask(provider, x, y, level) { - var tilingScheme = provider._tilingScheme; - var rectangles = provider._rectangles; - var parentRectangle = tilingScheme.tileXYToRectangle(x, y, level); + var i; - var childMask = 0; + // Sort points into a set of tiles + var tileRequests = []; // Result will be an Array as it's easier to work with + var tileRequestSet = {}; // A unique set + for (i = 0; i < positions.length; ++i) { + var xy = tilingScheme.positionToTileXY(positions[i], level); + var key = xy.toString(); - for (var i = 0; i < rectangles.length && childMask !== 15; ++i) { - var rectangle = rectangles[i]; - if (rectangle.maxLevel <= level) { - continue; + if (!tileRequestSet.hasOwnProperty(key)) { + // When tile is requested for the first time + var value = { + x : xy.x, + y : xy.y, + level : level, + tilingScheme : tilingScheme, + terrainProvider : terrainProvider, + positions : [] + }; + tileRequestSet[key] = value; + tileRequests.push(value); } - var testRectangle = rectangle.rectangle; + // Now append to array of points for the tile + tileRequestSet[key].positions.push(positions[i]); + } - var intersection = Rectangle.intersection(testRectangle, parentRectangle, rectangleScratch); - if (defined(intersection)) { - // Parent tile is inside this rectangle, so at least one child is, too. - if (isTileInRectangle(tilingScheme, testRectangle, x * 2, y * 2, level + 1)) { - childMask |= 4; // northwest - } - if (isTileInRectangle(tilingScheme, testRectangle, x * 2 + 1, y * 2, level + 1)) { - childMask |= 8; // northeast - } - if (isTileInRectangle(tilingScheme, testRectangle, x * 2, y * 2 + 1, level + 1)) { - childMask |= 1; // southwest - } - if (isTileInRectangle(tilingScheme, testRectangle, x * 2 + 1, y * 2 + 1, level + 1)) { - childMask |= 2; // southeast - } - } + // Send request for each required tile + var tilePromises = []; + for (i = 0; i < tileRequests.length; ++i) { + var tileRequest = tileRequests[i]; + var requestPromise = tileRequest.terrainProvider.requestTileGeometry(tileRequest.x, tileRequest.y, tileRequest.level); + var tilePromise = when(requestPromise, createInterpolateFunction(tileRequest), createMarkFailedFunction(tileRequest)); + tilePromises.push(tilePromise); } - return childMask; + return when.all(tilePromises, function() { + return positions; + }); } - function isTileInRectangle(tilingScheme, rectangle, x, y, level) { - var tileRectangle = tilingScheme.tileXYToRectangle(x, y, level); - return defined(Rectangle.intersection(tileRectangle, rectangle, rectangleScratch)); + function createInterpolateFunction(tileRequest) { + var tilePositions = tileRequest.positions; + var rectangle = tileRequest.tilingScheme.tileXYToRectangle(tileRequest.x, tileRequest.y, tileRequest.level); + return function(terrainData) { + for (var i = 0; i < tilePositions.length; ++i) { + var position = tilePositions[i]; + position.height = terrainData.interpolateHeight(rectangle, position.longitude, position.latitude); + } + }; } - /** - * Determines whether data for a tile is available to be loaded. - * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean} Undefined if not supported, otherwise true or false. - */ - VRTheWorldTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { - return undefined; - }; + function createMarkFailedFunction(tileRequest) { + var tilePositions = tileRequest.positions; + return function() { + for (var i = 0; i < tilePositions.length; ++i) { + var position = tilePositions[i]; + position.height = undefined; + } + }; + } - return VRTheWorldTerrainProvider; + return sampleTerrain; }); -define('Core/WallGeometryLibrary',[ - './Cartographic', +define('Core/sampleTerrainMostDetailed',[ + '../ThirdParty/when', './defined', - './EllipsoidTangentPlane', - './Math', - './PolygonPipeline', - './PolylinePipeline', - './WindingOrder' + './DeveloperError', + './sampleTerrain' ], function( - Cartographic, + when, defined, - EllipsoidTangentPlane, - CesiumMath, - PolygonPipeline, - PolylinePipeline, - WindingOrder) { + DeveloperError, + sampleTerrain) { 'use strict'; /** - * private + * Initiates a sampleTerrain() request at the maximum available tile level for a terrain dataset. + * + * @exports sampleTerrainMostDetailed + * + * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights. + * @param {Cartographic[]} positions The positions to update with terrain heights. + * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. This + * promise will reject if the terrain provider's `availability` property is undefined. + * + * @example + * // Query the terrain height of two Cartographic positions + * var terrainProvider = new Cesium.CesiumTerrainProvider({ + * url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles' + * }); + * var positions = [ + * Cesium.Cartographic.fromDegrees(86.925145, 27.988257), + * Cesium.Cartographic.fromDegrees(87.0, 28.0) + * ]; + * var promise = Cesium.sampleTerrainMostDetailed(terrainProvider, positions); + * Cesium.when(promise, function(updatedPositions) { + * // positions[0].height and positions[1].height have been updated. + * // updatedPositions is just a reference to positions. + * }); */ - var WallGeometryLibrary = {}; - - function latLonEquals(c0, c1) { - return ((CesiumMath.equalsEpsilon(c0.latitude, c1.latitude, CesiumMath.EPSILON14)) && (CesiumMath.equalsEpsilon(c0.longitude, c1.longitude, CesiumMath.EPSILON14))); - } - - var scratchCartographic1 = new Cartographic(); - var scratchCartographic2 = new Cartographic(); - function removeDuplicates(ellipsoid, positions, topHeights, bottomHeights) { - var length = positions.length; - if (length < 2) { - return; + function sampleTerrainMostDetailed(terrainProvider, positions) { + if (!defined(terrainProvider)) { + throw new DeveloperError('terrainProvider is required.'); } - - var hasBottomHeights = defined(bottomHeights); - var hasTopHeights = defined(topHeights); - var hasAllZeroHeights = true; - - var cleanedPositions = new Array(length); - var cleanedTopHeights = new Array(length); - var cleanedBottomHeights = new Array(length); - - var v0 = positions[0]; - cleanedPositions[0] = v0; - - var c0 = ellipsoid.cartesianToCartographic(v0, scratchCartographic1); - if (hasTopHeights) { - c0.height = topHeights[0]; + if (!defined(positions)) { + throw new DeveloperError('positions is required.'); } + + return terrainProvider.readyPromise.then(function() { + var byLevel = []; - hasAllZeroHeights = hasAllZeroHeights && c0.height <= 0; - - cleanedTopHeights[0] = c0.height; - - if (hasBottomHeights) { - cleanedBottomHeights[0] = bottomHeights[0]; - } else { - cleanedBottomHeights[0] = 0.0; - } + var availability = terrainProvider.availability; - var index = 1; - for (var i = 1; i < length; ++i) { - var v1 = positions[i]; - var c1 = ellipsoid.cartesianToCartographic(v1, scratchCartographic2); - if (hasTopHeights) { - c1.height = topHeights[i]; + if (!defined(availability)) { + throw new DeveloperError('sampleTerrainMostDetailed requires a terrain provider that has tile availability.'); } - hasAllZeroHeights = hasAllZeroHeights && c1.height <= 0; - - if (!latLonEquals(c0, c1)) { - cleanedPositions[index] = v1; // Shallow copy! - cleanedTopHeights[index] = c1.height; + + for (var i = 0; i < positions.length; ++i) { + var position = positions[i]; + var maxLevel = availability.computeMaximumLevelAtPosition(position); - if (hasBottomHeights) { - cleanedBottomHeights[index] = bottomHeights[i]; - } else { - cleanedBottomHeights[index] = 0.0; + var atLevel = byLevel[maxLevel]; + if (!defined(atLevel)) { + byLevel[maxLevel] = atLevel = []; } - - Cartographic.clone(c1, c0); - ++index; - } else if (c0.height < c1.height) { - cleanedTopHeights[index - 1] = c1.height; + atLevel.push(position); } - } - if (hasAllZeroHeights || index < 2) { - return; - } - - cleanedPositions.length = index; - cleanedTopHeights.length = index; - cleanedBottomHeights.length = index; - - return { - positions: cleanedPositions, - topHeights: cleanedTopHeights, - bottomHeights: cleanedBottomHeights - }; + return when.all(byLevel.map(function(positionsAtLevel, index) { + if (defined(positionsAtLevel)) { + return sampleTerrain(terrainProvider, index, positionsAtLevel); + } + })).then(function() { + return positions; + }); + }); } - var positionsArrayScratch = new Array(2); - var heightsArrayScratch = new Array(2); - var generateArcOptionsScratch = { - positions : undefined, - height : undefined, - granularity : undefined, - ellipsoid : undefined - }; + return sampleTerrainMostDetailed; +}); + +define('Core/ScreenSpaceEventType',[ + './freezeObject' + ], function( + freezeObject) { + 'use strict'; /** - * @private + * This enumerated type is for classifying mouse events: down, up, click, double click, move and move while a button is held down. + * + * @exports ScreenSpaceEventType */ - WallGeometryLibrary.computePositions = function(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, duplicateCorners) { - var o = removeDuplicates(ellipsoid, wallPositions, maximumHeights, minimumHeights); - - if (!defined(o)) { - return; - } - - wallPositions = o.positions; - maximumHeights = o.topHeights; - minimumHeights = o.bottomHeights; - - if (wallPositions.length >= 3) { - // Order positions counter-clockwise - var tangentPlane = EllipsoidTangentPlane.fromPoints(wallPositions, ellipsoid); - var positions2D = tangentPlane.projectPointsOntoPlane(wallPositions); - - if (PolygonPipeline.computeWindingOrder2D(positions2D) === WindingOrder.CLOCKWISE) { - wallPositions.reverse(); - maximumHeights.reverse(); - minimumHeights.reverse(); - } - } - - var length = wallPositions.length; - var numCorners = length - 2; - var topPositions; - var bottomPositions; + var ScreenSpaceEventType = { + /** + * Represents a mouse left button down event. + * + * @type {Number} + * @constant + */ + LEFT_DOWN : 0, - var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + /** + * Represents a mouse left button up event. + * + * @type {Number} + * @constant + */ + LEFT_UP : 1, - var generateArcOptions = generateArcOptionsScratch; - generateArcOptions.minDistance = minDistance; - generateArcOptions.ellipsoid = ellipsoid; + /** + * Represents a mouse left click event. + * + * @type {Number} + * @constant + */ + LEFT_CLICK : 2, - if (duplicateCorners) { - var count = 0; - var i; + /** + * Represents a mouse left double click event. + * + * @type {Number} + * @constant + */ + LEFT_DOUBLE_CLICK : 3, - for (i = 0; i < length - 1; i++) { - count += PolylinePipeline.numberOfPoints(wallPositions[i], wallPositions[i+1], minDistance) + 1; - } + /** + * Represents a mouse left button down event. + * + * @type {Number} + * @constant + */ + RIGHT_DOWN : 5, - topPositions = new Float64Array(count * 3); - bottomPositions = new Float64Array(count * 3); + /** + * Represents a mouse right button up event. + * + * @type {Number} + * @constant + */ + RIGHT_UP : 6, - var generateArcPositions = positionsArrayScratch; - var generateArcHeights = heightsArrayScratch; - generateArcOptions.positions = generateArcPositions; - generateArcOptions.height = generateArcHeights; + /** + * Represents a mouse right click event. + * + * @type {Number} + * @constant + */ + RIGHT_CLICK : 7, - var offset = 0; - for (i = 0; i < length - 1; i++) { - generateArcPositions[0] = wallPositions[i]; - generateArcPositions[1] = wallPositions[i + 1]; + /** + * Represents a mouse middle button down event. + * + * @type {Number} + * @constant + */ + MIDDLE_DOWN : 10, - generateArcHeights[0] = maximumHeights[i]; - generateArcHeights[1] = maximumHeights[i + 1]; + /** + * Represents a mouse middle button up event. + * + * @type {Number} + * @constant + */ + MIDDLE_UP : 11, - var pos = PolylinePipeline.generateArc(generateArcOptions); - topPositions.set(pos, offset); + /** + * Represents a mouse middle click event. + * + * @type {Number} + * @constant + */ + MIDDLE_CLICK : 12, - generateArcHeights[0] = minimumHeights[i]; - generateArcHeights[1] = minimumHeights[i + 1]; + /** + * Represents a mouse move event. + * + * @type {Number} + * @constant + */ + MOUSE_MOVE : 15, - bottomPositions.set(PolylinePipeline.generateArc(generateArcOptions), offset); + /** + * Represents a mouse wheel event. + * + * @type {Number} + * @constant + */ + WHEEL : 16, - offset += pos.length; - } - } else { - generateArcOptions.positions = wallPositions; - generateArcOptions.height = maximumHeights; - topPositions = new Float64Array(PolylinePipeline.generateArc(generateArcOptions)); + /** + * Represents the start of a two-finger event on a touch surface. + * + * @type {Number} + * @constant + */ + PINCH_START : 17, - generateArcOptions.height = minimumHeights; - bottomPositions = new Float64Array(PolylinePipeline.generateArc(generateArcOptions)); - } + /** + * Represents the end of a two-finger event on a touch surface. + * + * @type {Number} + * @constant + */ + PINCH_END : 18, - return { - bottomPositions: bottomPositions, - topPositions: topPositions, - numCorners: numCorners - }; + /** + * Represents a change of a two-finger event on a touch surface. + * + * @type {Number} + * @constant + */ + PINCH_MOVE : 19 }; - return WallGeometryLibrary; + return freezeObject(ScreenSpaceEventType); }); -define('Core/WallGeometry',[ - './BoundingSphere', - './Cartesian3', - './ComponentDatatype', +define('Core/ScreenSpaceEventHandler',[ + './AssociativeArray', + './Cartesian2', './defaultValue', './defined', + './destroyObject', './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PrimitiveType', - './VertexFormat', - './WallGeometryLibrary' + './FeatureDetection', + './getTimestamp', + './KeyboardEventModifier', + './ScreenSpaceEventType' ], function( - BoundingSphere, - Cartesian3, - ComponentDatatype, + AssociativeArray, + Cartesian2, defaultValue, defined, + destroyObject, DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PrimitiveType, - VertexFormat, - WallGeometryLibrary) { + FeatureDetection, + getTimestamp, + KeyboardEventModifier, + ScreenSpaceEventType) { 'use strict'; - var scratchCartesian3Position1 = new Cartesian3(); - var scratchCartesian3Position2 = new Cartesian3(); - var scratchCartesian3Position3 = new Cartesian3(); - var scratchCartesian3Position4 = new Cartesian3(); - var scratchCartesian3Position5 = new Cartesian3(); - var scratchBitangent = new Cartesian3(); - var scratchTangent = new Cartesian3(); - var scratchNormal = new Cartesian3(); - - /** - * A description of a wall, which is similar to a KML line string. A wall is defined by a series of points, - * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. - * - * @alias WallGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the - * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the - * wall at <code>positions</code>. If undefined, the height at each position is 0.0. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * - * @exception {DeveloperError} positions length must be greater than or equal to 2. - * @exception {DeveloperError} positions and maximumHeights must have the same length. - * @exception {DeveloperError} positions and minimumHeights must have the same length. - * - * @see WallGeometry#createGeometry - * @see WallGeometry#fromConstantHeight - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo} - * - * @example - * // create a wall that spans from ground level to 10000 meters - * var wall = new Cesium.WallGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArrayHeights([ - * 19.0, 47.0, 10000.0, - * 19.0, 48.0, 10000.0, - * 20.0, 48.0, 10000.0, - * 20.0, 47.0, 10000.0, - * 19.0, 47.0, 10000.0 - * ]) - * }); - * var geometry = Cesium.WallGeometry.createGeometry(wall); - */ - function WallGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function getPosition(screenSpaceEventHandler, event, result) { + var element = screenSpaceEventHandler._element; + if (element === document) { + result.x = event.clientX; + result.y = event.clientY; + return result; + } - var wallPositions = options.positions; - var maximumHeights = options.maximumHeights; - var minimumHeights = options.minimumHeights; + var rect = element.getBoundingClientRect(); + result.x = event.clientX - rect.left; + result.y = event.clientY - rect.top; + return result; + } - if (!defined(wallPositions)) { - throw new DeveloperError('options.positions is required.'); + function getInputEventKey(type, modifier) { + var key = type; + if (defined(modifier)) { + key += '+' + modifier; } - if (defined(maximumHeights) && maximumHeights.length !== wallPositions.length) { - throw new DeveloperError('options.positions and options.maximumHeights must have the same length.'); + return key; + } + + function getModifier(event) { + if (event.shiftKey) { + return KeyboardEventModifier.SHIFT; + } else if (event.ctrlKey) { + return KeyboardEventModifier.CTRL; + } else if (event.altKey) { + return KeyboardEventModifier.ALT; } - if (defined(minimumHeights) && minimumHeights.length !== wallPositions.length) { - throw new DeveloperError('options.positions and options.minimumHeights must have the same length.'); + + return undefined; + } + + var MouseButton = { + LEFT : 0, + MIDDLE : 1, + RIGHT : 2 + }; + + function registerListener(screenSpaceEventHandler, domType, element, callback) { + function listener(e) { + callback(screenSpaceEventHandler, e); } - - var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + element.addEventListener(domType, listener, false); - this._positions = wallPositions; - this._minimumHeights = minimumHeights; - this._maximumHeights = maximumHeights; - this._vertexFormat = VertexFormat.clone(vertexFormat); - this._granularity = granularity; - this._ellipsoid = Ellipsoid.clone(ellipsoid); - this._workerName = 'createWallGeometry'; + screenSpaceEventHandler._removalFunctions.push(function() { + element.removeEventListener(domType, listener, false); + }); + } - var numComponents = 1 + wallPositions.length * Cartesian3.packedLength + 2; - if (defined(minimumHeights)) { - numComponents += minimumHeights.length; + function registerListeners(screenSpaceEventHandler) { + var element = screenSpaceEventHandler._element; + + // some listeners may be registered on the document, so we still get events even after + // leaving the bounds of element. + // this is affected by the existence of an undocumented disableRootEvents property on element. + var alternateElement = !defined(element.disableRootEvents) ? document : element; + + if (FeatureDetection.supportsPointerEvents()) { + registerListener(screenSpaceEventHandler, 'pointerdown', element, handlePointerDown); + registerListener(screenSpaceEventHandler, 'pointerup', element, handlePointerUp); + registerListener(screenSpaceEventHandler, 'pointermove', element, handlePointerMove); + registerListener(screenSpaceEventHandler, 'pointercancel', element, handlePointerUp); + } else { + registerListener(screenSpaceEventHandler, 'mousedown', element, handleMouseDown); + registerListener(screenSpaceEventHandler, 'mouseup', alternateElement, handleMouseUp); + registerListener(screenSpaceEventHandler, 'mousemove', alternateElement, handleMouseMove); + registerListener(screenSpaceEventHandler, 'touchstart', element, handleTouchStart); + registerListener(screenSpaceEventHandler, 'touchend', alternateElement, handleTouchEnd); + registerListener(screenSpaceEventHandler, 'touchmove', alternateElement, handleTouchMove); + registerListener(screenSpaceEventHandler, 'touchcancel', alternateElement, handleTouchEnd); } - if (defined(maximumHeights)) { - numComponents += maximumHeights.length; + + registerListener(screenSpaceEventHandler, 'dblclick', element, handleDblClick); + + // detect available wheel event + var wheelEvent; + if ('onwheel' in element) { + // spec event type + wheelEvent = 'wheel'; + } else if (document.onmousewheel !== undefined) { + // legacy event type + wheelEvent = 'mousewheel'; + } else { + // older Firefox + wheelEvent = 'DOMMouseScroll'; } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 1; + registerListener(screenSpaceEventHandler, wheelEvent, element, handleWheel); } - /** - * Stores the provided instance into the provided array. - * - * @param {WallGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - WallGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); + function unregisterListeners(screenSpaceEventHandler) { + var removalFunctions = screenSpaceEventHandler._removalFunctions; + for (var i = 0; i < removalFunctions.length; ++i) { + removalFunctions[i](); } - - startingIndex = defaultValue(startingIndex, 0); + } - var i; + var mouseDownEvent = { + position : new Cartesian2() + }; - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; + function gotTouchEvent(screenSpaceEventHandler) { + screenSpaceEventHandler._lastSeenTouchEvent = getTimestamp(); + } - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); + function canProcessMouseEvent(screenSpaceEventHandler) { + return (getTimestamp() - screenSpaceEventHandler._lastSeenTouchEvent) > ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds; + } + + function handleMouseDown(screenSpaceEventHandler, event) { + if (!canProcessMouseEvent(screenSpaceEventHandler)) { + return; } - var minimumHeights = value._minimumHeights; - length = defined(minimumHeights) ? minimumHeights.length : 0; - array[startingIndex++] = length; + var button = event.button; + screenSpaceEventHandler._buttonDown = button; - if (defined(minimumHeights)) { - for (i = 0; i < length; ++i) { - array[startingIndex++] = minimumHeights[i]; - } + var screenSpaceEventType; + if (button === MouseButton.LEFT) { + screenSpaceEventType = ScreenSpaceEventType.LEFT_DOWN; + } else if (button === MouseButton.MIDDLE) { + screenSpaceEventType = ScreenSpaceEventType.MIDDLE_DOWN; + } else if (button === MouseButton.RIGHT) { + screenSpaceEventType = ScreenSpaceEventType.RIGHT_DOWN; + } else { + return; } - var maximumHeights = value._maximumHeights; - length = defined(maximumHeights) ? maximumHeights.length : 0; - array[startingIndex++] = length; + var position = getPosition(screenSpaceEventHandler, event, screenSpaceEventHandler._primaryPosition); + Cartesian2.clone(position, screenSpaceEventHandler._primaryStartPosition); + Cartesian2.clone(position, screenSpaceEventHandler._primaryPreviousPosition); - if (defined(maximumHeights)) { - for (i = 0; i < length; ++i) { - array[startingIndex++] = maximumHeights[i]; - } - } + var modifier = getModifier(event); - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + var action = screenSpaceEventHandler.getInputAction(screenSpaceEventType, modifier); - VertexFormat.pack(value._vertexFormat, array, startingIndex); - startingIndex += VertexFormat.packedLength; + if (defined(action)) { + Cartesian2.clone(position, mouseDownEvent.position); - array[startingIndex] = value._granularity; + action(mouseDownEvent); - return array; - }; + event.preventDefault(); + } + } - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchVertexFormat = new VertexFormat(); - var scratchOptions = { - positions : undefined, - minimumHeights : undefined, - maximumHeights : undefined, - ellipsoid : scratchEllipsoid, - vertexFormat : scratchVertexFormat, - granularity : undefined + var mouseUpEvent = { + position : new Cartesian2() + }; + var mouseClickEvent = { + position : new Cartesian2() }; - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {WallGeometry} [result] The object into which to store the result. - * @returns {WallGeometry} The modified result parameter or a new WallGeometry instance if one was not provided. - */ - WallGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + function handleMouseUp(screenSpaceEventHandler, event) { + if (!canProcessMouseEvent(screenSpaceEventHandler)) { + return; } - - startingIndex = defaultValue(startingIndex, 0); - - var i; - var length = array[startingIndex++]; - var positions = new Array(length); + var button = event.button; + screenSpaceEventHandler._buttonDown = undefined; - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); + var screenSpaceEventType; + var clickScreenSpaceEventType; + if (button === MouseButton.LEFT) { + screenSpaceEventType = ScreenSpaceEventType.LEFT_UP; + clickScreenSpaceEventType = ScreenSpaceEventType.LEFT_CLICK; + } else if (button === MouseButton.MIDDLE) { + screenSpaceEventType = ScreenSpaceEventType.MIDDLE_UP; + clickScreenSpaceEventType = ScreenSpaceEventType.MIDDLE_CLICK; + } else if (button === MouseButton.RIGHT) { + screenSpaceEventType = ScreenSpaceEventType.RIGHT_UP; + clickScreenSpaceEventType = ScreenSpaceEventType.RIGHT_CLICK; + } else { + return; } - length = array[startingIndex++]; - var minimumHeights; + var modifier = getModifier(event); - if (length > 0) { - minimumHeights = new Array(length); - for (i = 0; i < length; ++i) { - minimumHeights[i] = array[startingIndex++]; + var action = screenSpaceEventHandler.getInputAction(screenSpaceEventType, modifier); + var clickAction = screenSpaceEventHandler.getInputAction(clickScreenSpaceEventType, modifier); + + if (defined(action) || defined(clickAction)) { + var position = getPosition(screenSpaceEventHandler, event, screenSpaceEventHandler._primaryPosition); + + if (defined(action)) { + Cartesian2.clone(position, mouseUpEvent.position); + + action(mouseUpEvent); } - } - length = array[startingIndex++]; - var maximumHeights; + if (defined(clickAction)) { + var startPosition = screenSpaceEventHandler._primaryStartPosition; + var xDiff = startPosition.x - position.x; + var yDiff = startPosition.y - position.y; + var totalPixels = Math.sqrt(xDiff * xDiff + yDiff * yDiff); - if (length > 0) { - maximumHeights = new Array(length); - for (i = 0; i < length; ++i) { - maximumHeights[i] = array[startingIndex++]; + if (totalPixels < screenSpaceEventHandler._clickPixelTolerance) { + Cartesian2.clone(position, mouseClickEvent.position); + + clickAction(mouseClickEvent); + } } } + } - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; + var mouseMoveEvent = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() + }; - var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); - startingIndex += VertexFormat.packedLength; + function handleMouseMove(screenSpaceEventHandler, event) { + if (!canProcessMouseEvent(screenSpaceEventHandler)) { + return; + } - var granularity = array[startingIndex]; + var modifier = getModifier(event); - if (!defined(result)) { - scratchOptions.positions = positions; - scratchOptions.minimumHeights = minimumHeights; - scratchOptions.maximumHeights = maximumHeights; - scratchOptions.granularity = granularity; - return new WallGeometry(scratchOptions); + var position = getPosition(screenSpaceEventHandler, event, screenSpaceEventHandler._primaryPosition); + var previousPosition = screenSpaceEventHandler._primaryPreviousPosition; + + var action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.MOUSE_MOVE, modifier); + + if (defined(action)) { + Cartesian2.clone(previousPosition, mouseMoveEvent.startPosition); + Cartesian2.clone(position, mouseMoveEvent.endPosition); + + action(mouseMoveEvent); } - result._positions = positions; - result._minimumHeights = minimumHeights; - result._maximumHeights = maximumHeights; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); - result._granularity = granularity; + Cartesian2.clone(position, previousPosition); - return result; + if (defined(screenSpaceEventHandler._buttonDown)) { + event.preventDefault(); + } + } + + var mouseDblClickEvent = { + position : new Cartesian2() }; - /** - * A description of a wall, which is similar to a KML line string. A wall is defined by a series of points, - * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.maximumHeight] A constant that defines the maximum height of the - * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number} [options.minimumHeight] A constant that defines the minimum height of the - * wall at <code>positions</code>. If undefined, the height at each position is 0.0. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation - * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @returns {WallGeometry} - * - * - * @example - * // create a wall that spans from 10000 meters to 20000 meters - * var wall = Cesium.WallGeometry.fromConstantHeights({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * 19.0, 47.0, - * 19.0, 48.0, - * 20.0, 48.0, - * 20.0, 47.0, - * 19.0, 47.0, - * ]), - * minimumHeight : 20000.0, - * maximumHeight : 10000.0 - * }); - * var geometry = Cesium.WallGeometry.createGeometry(wall); - * - * @see WallGeometry#createGeometry - */ - WallGeometry.fromConstantHeights = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.positions; + function handleDblClick(screenSpaceEventHandler, event) { + var button = event.button; - if (!defined(positions)) { - throw new DeveloperError('options.positions is required.'); + var screenSpaceEventType; + if (button === MouseButton.LEFT) { + screenSpaceEventType = ScreenSpaceEventType.LEFT_DOUBLE_CLICK; + } else { + return; } - - var minHeights; - var maxHeights; - var min = options.minimumHeight; - var max = options.maximumHeight; + var modifier = getModifier(event); - var doMin = defined(min); - var doMax = defined(max); - if (doMin || doMax) { - var length = positions.length; - minHeights = (doMin) ? new Array(length) : undefined; - maxHeights = (doMax) ? new Array(length) : undefined; + var action = screenSpaceEventHandler.getInputAction(screenSpaceEventType, modifier); - for (var i = 0; i < length; ++i) { - if (doMin) { - minHeights[i] = min; - } + if (defined(action)) { + getPosition(screenSpaceEventHandler, event, mouseDblClickEvent.position); - if (doMax) { - maxHeights[i] = max; - } - } + action(mouseDblClickEvent); } + } - var newOptions = { - positions : positions, - maximumHeights : maxHeights, - minimumHeights : minHeights, - ellipsoid : options.ellipsoid, - vertexFormat : options.vertexFormat - }; - return new WallGeometry(newOptions); - }; + function handleWheel(screenSpaceEventHandler, event) { + // currently this event exposes the delta value in terms of + // the obsolete mousewheel event type. so, for now, we adapt the other + // values to that scheme. + var delta; - /** - * Computes the geometric representation of a wall, including its vertices, indices, and a bounding sphere. - * - * @param {WallGeometry} wallGeometry A description of the wall. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - WallGeometry.createGeometry = function(wallGeometry) { - var wallPositions = wallGeometry._positions; - var minimumHeights = wallGeometry._minimumHeights; - var maximumHeights = wallGeometry._maximumHeights; - var vertexFormat = wallGeometry._vertexFormat; - var granularity = wallGeometry._granularity; - var ellipsoid = wallGeometry._ellipsoid; + // standard wheel event uses deltaY. sign is opposite wheelDelta. + // deltaMode indicates what unit it is in. + if (defined(event.deltaY)) { + var deltaMode = event.deltaMode; + if (deltaMode === event.DOM_DELTA_PIXEL) { + delta = -event.deltaY; + } else if (deltaMode === event.DOM_DELTA_LINE) { + delta = -event.deltaY * 40; + } else { + // DOM_DELTA_PAGE + delta = -event.deltaY * 120; + } + } else if (event.detail > 0) { + // old Firefox versions use event.detail to count the number of clicks. The sign + // of the integer is the direction the wheel is scrolled. + delta = event.detail * -120; + } else { + delta = event.wheelDelta; + } - var pos = WallGeometryLibrary.computePositions(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, true); - if (!defined(pos)) { + if (!defined(delta)) { return; } - var bottomPositions = pos.bottomPositions; - var topPositions = pos.topPositions; - var numCorners = pos.numCorners; + var modifier = getModifier(event); + var action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.WHEEL, modifier); - var length = topPositions.length; - var size = length * 2; + if (defined(action)) { + action(delta); - var positions = vertexFormat.position ? new Float64Array(size) : undefined; - var normals = vertexFormat.normal ? new Float32Array(size) : undefined; - var tangents = vertexFormat.tangent ? new Float32Array(size) : undefined; - var bitangents = vertexFormat.bitangent ? new Float32Array(size) : undefined; - var textureCoordinates = vertexFormat.st ? new Float32Array(size / 3 * 2) : undefined; + event.preventDefault(); + } + } - var positionIndex = 0; - var normalIndex = 0; - var bitangentIndex = 0; - var tangentIndex = 0; - var stIndex = 0; + function handleTouchStart(screenSpaceEventHandler, event) { + gotTouchEvent(screenSpaceEventHandler); - // add lower and upper points one after the other, lower - // points being even and upper points being odd - var normal = scratchNormal; - var tangent = scratchTangent; - var bitangent = scratchBitangent; - var recomputeNormal = true; - length /= 3; - var i; - var s = 0; - var ds = 1/(length - wallPositions.length + 1); - for (i = 0; i < length; ++i) { - var i3 = i * 3; - var topPosition = Cartesian3.fromArray(topPositions, i3, scratchCartesian3Position1); - var bottomPosition = Cartesian3.fromArray(bottomPositions, i3, scratchCartesian3Position2); - if (vertexFormat.position) { - // insert the lower point - positions[positionIndex++] = bottomPosition.x; - positions[positionIndex++] = bottomPosition.y; - positions[positionIndex++] = bottomPosition.z; + var changedTouches = event.changedTouches; - // insert the upper point - positions[positionIndex++] = topPosition.x; - positions[positionIndex++] = topPosition.y; - positions[positionIndex++] = topPosition.z; - } + var i; + var length = changedTouches.length; + var touch; + var identifier; + var positions = screenSpaceEventHandler._positions; - if (vertexFormat.st) { - textureCoordinates[stIndex++] = s; - textureCoordinates[stIndex++] = 0.0; + for (i = 0; i < length; ++i) { + touch = changedTouches[i]; + identifier = touch.identifier; + positions.set(identifier, getPosition(screenSpaceEventHandler, touch, new Cartesian2())); + } - textureCoordinates[stIndex++] = s; - textureCoordinates[stIndex++] = 1.0; - } + fireTouchEvents(screenSpaceEventHandler, event); - if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { - var nextPosition; - var nextTop = Cartesian3.clone(Cartesian3.ZERO, scratchCartesian3Position5); - var groundPosition = ellipsoid.scaleToGeodeticSurface(Cartesian3.fromArray(topPositions, i3, scratchCartesian3Position2), scratchCartesian3Position2); - if (i + 1 < length) { - nextPosition = ellipsoid.scaleToGeodeticSurface(Cartesian3.fromArray(topPositions, i3 + 3, scratchCartesian3Position3), scratchCartesian3Position3); - nextTop = Cartesian3.fromArray(topPositions, i3 + 3, scratchCartesian3Position5); - } + var previousPositions = screenSpaceEventHandler._previousPositions; - if (recomputeNormal) { - var scalednextPosition = Cartesian3.subtract(nextTop, topPosition, scratchCartesian3Position4); - var scaledGroundPosition = Cartesian3.subtract(groundPosition, topPosition, scratchCartesian3Position1); - normal = Cartesian3.normalize(Cartesian3.cross(scaledGroundPosition, scalednextPosition, normal), normal); - recomputeNormal = false; - } + for (i = 0; i < length; ++i) { + touch = changedTouches[i]; + identifier = touch.identifier; + previousPositions.set(identifier, Cartesian2.clone(positions.get(identifier))); + } + } - if (Cartesian3.equalsEpsilon(nextPosition, groundPosition, CesiumMath.EPSILON10)) { - recomputeNormal = true; - } else { - s += ds; - if (vertexFormat.tangent) { - tangent = Cartesian3.normalize(Cartesian3.subtract(nextPosition, groundPosition, tangent), tangent); - } - if (vertexFormat.bitangent) { - bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); - } - } + function handleTouchEnd(screenSpaceEventHandler, event) { + gotTouchEvent(screenSpaceEventHandler); - if (vertexFormat.normal) { - normals[normalIndex++] = normal.x; - normals[normalIndex++] = normal.y; - normals[normalIndex++] = normal.z; + var changedTouches = event.changedTouches; - normals[normalIndex++] = normal.x; - normals[normalIndex++] = normal.y; - normals[normalIndex++] = normal.z; - } + var i; + var length = changedTouches.length; + var touch; + var identifier; + var positions = screenSpaceEventHandler._positions; - if (vertexFormat.tangent) { - tangents[tangentIndex++] = tangent.x; - tangents[tangentIndex++] = tangent.y; - tangents[tangentIndex++] = tangent.z; + for (i = 0; i < length; ++i) { + touch = changedTouches[i]; + identifier = touch.identifier; + positions.remove(identifier); + } - tangents[tangentIndex++] = tangent.x; - tangents[tangentIndex++] = tangent.y; - tangents[tangentIndex++] = tangent.z; - } + fireTouchEvents(screenSpaceEventHandler, event); - if (vertexFormat.bitangent) { - bitangents[bitangentIndex++] = bitangent.x; - bitangents[bitangentIndex++] = bitangent.y; - bitangents[bitangentIndex++] = bitangent.z; + var previousPositions = screenSpaceEventHandler._previousPositions; - bitangents[bitangentIndex++] = bitangent.x; - bitangents[bitangentIndex++] = bitangent.y; - bitangents[bitangentIndex++] = bitangent.z; - } - } + for (i = 0; i < length; ++i) { + touch = changedTouches[i]; + identifier = touch.identifier; + previousPositions.remove(identifier); } + } - var attributes = new GeometryAttributes(); + var touchStartEvent = { + position : new Cartesian2() + }; + var touch2StartEvent = { + position1 : new Cartesian2(), + position2 : new Cartesian2() + }; + var touchEndEvent = { + position : new Cartesian2() + }; + var touchClickEvent = { + position : new Cartesian2() + }; - if (vertexFormat.position) { - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - } + function fireTouchEvents(screenSpaceEventHandler, event) { + var modifier = getModifier(event); + var positions = screenSpaceEventHandler._positions; + var previousPositions = screenSpaceEventHandler._previousPositions; + var numberOfTouches = positions.length; + var action; + var clickAction; - if (vertexFormat.normal) { - attributes.normal = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : normals - }); - } + if (numberOfTouches !== 1 && screenSpaceEventHandler._buttonDown === MouseButton.LEFT) { + // transitioning from single touch, trigger UP and might trigger CLICK + screenSpaceEventHandler._buttonDown = undefined; + action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.LEFT_UP, modifier); - if (vertexFormat.tangent) { - attributes.tangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : tangents - }); - } + if (defined(action)) { + Cartesian2.clone(screenSpaceEventHandler._primaryPosition, touchEndEvent.position); - if (vertexFormat.bitangent) { - attributes.bitangent = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3, - values : bitangents - }); - } + action(touchEndEvent); + } - if (vertexFormat.st) { - attributes.st = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : textureCoordinates - }); - } + if (numberOfTouches === 0) { + // releasing single touch, check for CLICK + clickAction = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.LEFT_CLICK, modifier); - // prepare the side walls, two triangles for each wall - // - // A (i+1) B (i+3) E - // +--------+-------+ - // | / | /| triangles: A C B - // | / | / | B C D - // | / | / | - // | / | / | - // | / | / | - // | / | / | - // +--------+-------+ - // C (i) D (i+2) F - // + if (defined(clickAction)) { + var startPosition = screenSpaceEventHandler._primaryStartPosition; + var endPosition = previousPositions.values[0]; + var xDiff = startPosition.x - endPosition.x; + var yDiff = startPosition.y - endPosition.y; + var totalPixels = Math.sqrt(xDiff * xDiff + yDiff * yDiff); - var numVertices = size / 3; - size -= 6 * (numCorners + 1); - var indices = IndexDatatype.createTypedArray(numVertices, size); + if (totalPixels < screenSpaceEventHandler._clickPixelTolerance) { + Cartesian2.clone(screenSpaceEventHandler._primaryPosition, touchClickEvent.position); - var edgeIndex = 0; - for (i = 0; i < numVertices - 2; i += 2) { - var LL = i; - var LR = i + 2; - var pl = Cartesian3.fromArray(positions, LL * 3, scratchCartesian3Position1); - var pr = Cartesian3.fromArray(positions, LR * 3, scratchCartesian3Position2); - if (Cartesian3.equalsEpsilon(pl, pr, CesiumMath.EPSILON10)) { - continue; + clickAction(touchClickEvent); + } + } } - var UL = i + 1; - var UR = i + 3; - indices[edgeIndex++] = UL; - indices[edgeIndex++] = LL; - indices[edgeIndex++] = UR; - indices[edgeIndex++] = UR; - indices[edgeIndex++] = LL; - indices[edgeIndex++] = LR; + // Otherwise don't trigger CLICK, because we are adding more touches. } - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : new BoundingSphere.fromVertices(positions) - }); - }; + if (numberOfTouches !== 2 && screenSpaceEventHandler._isPinching) { + // transitioning from pinch, trigger PINCH_END + screenSpaceEventHandler._isPinching = false; - return WallGeometry; -}); + action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.PINCH_END, modifier); -define('Core/WallOutlineGeometry',[ - './BoundingSphere', - './Cartesian3', - './ComponentDatatype', - './defaultValue', - './defined', - './DeveloperError', - './Ellipsoid', - './Geometry', - './GeometryAttribute', - './GeometryAttributes', - './IndexDatatype', - './Math', - './PrimitiveType', - './WallGeometryLibrary' - ], function( - BoundingSphere, - Cartesian3, - ComponentDatatype, - defaultValue, - defined, - DeveloperError, - Ellipsoid, - Geometry, - GeometryAttribute, - GeometryAttributes, - IndexDatatype, - CesiumMath, - PrimitiveType, - WallGeometryLibrary) { - 'use strict'; + if (defined(action)) { + action(); + } + } - var scratchCartesian3Position1 = new Cartesian3(); - var scratchCartesian3Position2 = new Cartesian3(); + if (numberOfTouches === 1) { + // transitioning to single touch, trigger DOWN + var position = positions.values[0]; + Cartesian2.clone(position, screenSpaceEventHandler._primaryPosition); + Cartesian2.clone(position, screenSpaceEventHandler._primaryStartPosition); + Cartesian2.clone(position, screenSpaceEventHandler._primaryPreviousPosition); - /** - * A description of a wall outline. A wall is defined by a series of points, - * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. - * - * @alias WallOutlineGeometry - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the - * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the - * wall at <code>positions</code>. If undefined, the height at each position is 0.0. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation - * - * @exception {DeveloperError} positions length must be greater than or equal to 2. - * @exception {DeveloperError} positions and maximumHeights must have the same length. - * @exception {DeveloperError} positions and minimumHeights must have the same length. - * - * @see WallGeometry#createGeometry - * @see WallGeometry#fromConstantHeight - * - * @example - * // create a wall outline that spans from ground level to 10000 meters - * var wall = new Cesium.WallOutlineGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArrayHeights([ - * 19.0, 47.0, 10000.0, - * 19.0, 48.0, 10000.0, - * 20.0, 48.0, 10000.0, - * 20.0, 47.0, 10000.0, - * 19.0, 47.0, 10000.0 - * ]) - * }); - * var geometry = Cesium.WallOutlineGeometry.createGeometry(wall); - */ - function WallOutlineGeometry(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + screenSpaceEventHandler._buttonDown = MouseButton.LEFT; - var wallPositions = options.positions; - var maximumHeights = options.maximumHeights; - var minimumHeights = options.minimumHeights; + action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.LEFT_DOWN, modifier); - if (!defined(wallPositions)) { - throw new DeveloperError('options.positions is required.'); - } - if (defined(maximumHeights) && maximumHeights.length !== wallPositions.length) { - throw new DeveloperError('options.positions and options.maximumHeights must have the same length.'); - } - if (defined(minimumHeights) && minimumHeights.length !== wallPositions.length) { - throw new DeveloperError('options.positions and options.minimumHeights must have the same length.'); - } - - var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + if (defined(action)) { + Cartesian2.clone(position, touchStartEvent.position); - this._positions = wallPositions; - this._minimumHeights = minimumHeights; - this._maximumHeights = maximumHeights; - this._granularity = granularity; - this._ellipsoid = Ellipsoid.clone(ellipsoid); - this._workerName = 'createWallOutlineGeometry'; + action(touchStartEvent); + } - var numComponents = 1 + wallPositions.length * Cartesian3.packedLength + 2; - if (defined(minimumHeights)) { - numComponents += minimumHeights.length; - } - if (defined(maximumHeights)) { - numComponents += maximumHeights.length; + event.preventDefault(); } - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - this.packedLength = numComponents + Ellipsoid.packedLength + 1; - } + if (numberOfTouches === 2) { + // transitioning to pinch, trigger PINCH_START + screenSpaceEventHandler._isPinching = true; - /** - * Stores the provided instance into the provided array. - * - * @param {WallOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - WallOutlineGeometry.pack = function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); - } - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - - startingIndex = defaultValue(startingIndex, 0); + action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.PINCH_START, modifier); - var i; + if (defined(action)) { + Cartesian2.clone(positions.values[0], touch2StartEvent.position1); + Cartesian2.clone(positions.values[1], touch2StartEvent.position2); - var positions = value._positions; - var length = positions.length; - array[startingIndex++] = length; + action(touch2StartEvent); - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - Cartesian3.pack(positions[i], array, startingIndex); + // Touch-enabled devices, in particular iOS can have many default behaviours for + // "pinch" events, which can still be executed unless we prevent them here. + event.preventDefault(); + } } + } - var minimumHeights = value._minimumHeights; - length = defined(minimumHeights) ? minimumHeights.length : 0; - array[startingIndex++] = length; + function handleTouchMove(screenSpaceEventHandler, event) { + gotTouchEvent(screenSpaceEventHandler); - if (defined(minimumHeights)) { - for (i = 0; i < length; ++i) { - array[startingIndex++] = minimumHeights[i]; - } - } + var changedTouches = event.changedTouches; - var maximumHeights = value._maximumHeights; - length = defined(maximumHeights) ? maximumHeights.length : 0; - array[startingIndex++] = length; + var i; + var length = changedTouches.length; + var touch; + var identifier; + var positions = screenSpaceEventHandler._positions; - if (defined(maximumHeights)) { - for (i = 0; i < length; ++i) { - array[startingIndex++] = maximumHeights[i]; + for (i = 0; i < length; ++i) { + touch = changedTouches[i]; + identifier = touch.identifier; + var position = positions.get(identifier); + if (defined(position)) { + getPosition(screenSpaceEventHandler, touch, position); } } - Ellipsoid.pack(value._ellipsoid, array, startingIndex); - startingIndex += Ellipsoid.packedLength; + fireTouchMoveEvents(screenSpaceEventHandler, event); - array[startingIndex] = value._granularity; + var previousPositions = screenSpaceEventHandler._previousPositions; - return array; - }; + for (i = 0; i < length; ++i) { + touch = changedTouches[i]; + identifier = touch.identifier; + Cartesian2.clone(positions.get(identifier), previousPositions.get(identifier)); + } + } - var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); - var scratchOptions = { - positions : undefined, - minimumHeights : undefined, - maximumHeights : undefined, - ellipsoid : scratchEllipsoid, - granularity : undefined + var touchMoveEvent = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() }; - - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {WallOutlineGeometry} [result] The object into which to store the result. - * @returns {WallOutlineGeometry} The modified result parameter or a new WallOutlineGeometry instance if one was not provided. - */ - WallOutlineGeometry.unpack = function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + var touchPinchMovementEvent = { + distance : { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() + }, + angleAndHeight : { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() } - - startingIndex = defaultValue(startingIndex, 0); - - var i; + }; - var length = array[startingIndex++]; - var positions = new Array(length); + function fireTouchMoveEvents(screenSpaceEventHandler, event) { + var modifier = getModifier(event); + var positions = screenSpaceEventHandler._positions; + var previousPositions = screenSpaceEventHandler._previousPositions; + var numberOfTouches = positions.length; + var action; - for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { - positions[i] = Cartesian3.unpack(array, startingIndex); - } + if (numberOfTouches === 1 && screenSpaceEventHandler._buttonDown === MouseButton.LEFT) { + // moving single touch + var position = positions.values[0]; + Cartesian2.clone(position, screenSpaceEventHandler._primaryPosition); - length = array[startingIndex++]; - var minimumHeights; + var previousPosition = screenSpaceEventHandler._primaryPreviousPosition; - if (length > 0) { - minimumHeights = new Array(length); - for (i = 0; i < length; ++i) { - minimumHeights[i] = array[startingIndex++]; - } - } + action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.MOUSE_MOVE, modifier); - length = array[startingIndex++]; - var maximumHeights; + if (defined(action)) { + Cartesian2.clone(previousPosition, touchMoveEvent.startPosition); + Cartesian2.clone(position, touchMoveEvent.endPosition); - if (length > 0) { - maximumHeights = new Array(length); - for (i = 0; i < length; ++i) { - maximumHeights[i] = array[startingIndex++]; + action(touchMoveEvent); } - } - - var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); - startingIndex += Ellipsoid.packedLength; - - var granularity = array[startingIndex]; - if (!defined(result)) { - scratchOptions.positions = positions; - scratchOptions.minimumHeights = minimumHeights; - scratchOptions.maximumHeights = maximumHeights; - scratchOptions.granularity = granularity; - return new WallOutlineGeometry(scratchOptions); - } + Cartesian2.clone(position, previousPosition); - result._positions = positions; - result._minimumHeights = minimumHeights; - result._maximumHeights = maximumHeights; - result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); - result._granularity = granularity; + event.preventDefault(); + } else if (numberOfTouches === 2 && screenSpaceEventHandler._isPinching) { + // moving pinch - return result; - }; + action = screenSpaceEventHandler.getInputAction(ScreenSpaceEventType.PINCH_MOVE, modifier); + if (defined(action)) { + var position1 = positions.values[0]; + var position2 = positions.values[1]; + var previousPosition1 = previousPositions.values[0]; + var previousPosition2 = previousPositions.values[1]; - /** - * A description of a walloutline. A wall is defined by a series of points, - * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.maximumHeight] A constant that defines the maximum height of the - * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number} [options.minimumHeight] A constant that defines the minimum height of the - * wall at <code>positions</code>. If undefined, the height at each position is 0.0. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation - * @returns {WallOutlineGeometry} - * - * - * @example - * // create a wall that spans from 10000 meters to 20000 meters - * var wall = Cesium.WallOutlineGeometry.fromConstantHeights({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * 19.0, 47.0, - * 19.0, 48.0, - * 20.0, 48.0, - * 20.0, 47.0, - * 19.0, 47.0, - * ]), - * minimumHeight : 20000.0, - * maximumHeight : 10000.0 - * }); - * var geometry = Cesium.WallOutlineGeometry.createGeometry(wall); - * - * @see WallOutlineGeometry#createGeometry - */ - WallOutlineGeometry.fromConstantHeights = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var positions = options.positions; + var dX = position2.x - position1.x; + var dY = position2.y - position1.y; + var dist = Math.sqrt(dX * dX + dY * dY) * 0.25; - if (!defined(positions)) { - throw new DeveloperError('options.positions is required.'); - } - - var minHeights; - var maxHeights; + var prevDX = previousPosition2.x - previousPosition1.x; + var prevDY = previousPosition2.y - previousPosition1.y; + var prevDist = Math.sqrt(prevDX * prevDX + prevDY * prevDY) * 0.25; - var min = options.minimumHeight; - var max = options.maximumHeight; + var cY = (position2.y + position1.y) * 0.125; + var prevCY = (previousPosition2.y + previousPosition1.y) * 0.125; + var angle = Math.atan2(dY, dX); + var prevAngle = Math.atan2(prevDY, prevDX); - var doMin = defined(min); - var doMax = defined(max); - if (doMin || doMax) { - var length = positions.length; - minHeights = (doMin) ? new Array(length) : undefined; - maxHeights = (doMax) ? new Array(length) : undefined; + Cartesian2.fromElements(0.0, prevDist, touchPinchMovementEvent.distance.startPosition); + Cartesian2.fromElements(0.0, dist, touchPinchMovementEvent.distance.endPosition); - for (var i = 0; i < length; ++i) { - if (doMin) { - minHeights[i] = min; - } + Cartesian2.fromElements(prevAngle, prevCY, touchPinchMovementEvent.angleAndHeight.startPosition); + Cartesian2.fromElements(angle, cY, touchPinchMovementEvent.angleAndHeight.endPosition); - if (doMax) { - maxHeights[i] = max; - } + action(touchPinchMovementEvent); } } + } - var newOptions = { - positions : positions, - maximumHeights : maxHeights, - minimumHeights : minHeights, - ellipsoid : options.ellipsoid - }; - return new WallOutlineGeometry(newOptions); - }; - - /** - * Computes the geometric representation of a wall outline, including its vertices, indices, and a bounding sphere. - * - * @param {WallOutlineGeometry} wallGeometry A description of the wall outline. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - WallOutlineGeometry.createGeometry = function(wallGeometry) { - var wallPositions = wallGeometry._positions; - var minimumHeights = wallGeometry._minimumHeights; - var maximumHeights = wallGeometry._maximumHeights; - var granularity = wallGeometry._granularity; - var ellipsoid = wallGeometry._ellipsoid; - - var pos = WallGeometryLibrary.computePositions(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, false); - if (!defined(pos)) { - return; - } - - var bottomPositions = pos.bottomPositions; - var topPositions = pos.topPositions; - - var length = topPositions.length; - var size = length * 2; + function handlePointerDown(screenSpaceEventHandler, event) { + event.target.setPointerCapture(event.pointerId); - var positions = new Float64Array(size); - var positionIndex = 0; + if (event.pointerType === 'touch') { + var positions = screenSpaceEventHandler._positions; - // add lower and upper points one after the other, lower - // points being even and upper points being odd - length /= 3; - var i; - for (i = 0; i < length; ++i) { - var i3 = i * 3; - var topPosition = Cartesian3.fromArray(topPositions, i3, scratchCartesian3Position1); - var bottomPosition = Cartesian3.fromArray(bottomPositions, i3, scratchCartesian3Position2); + var identifier = event.pointerId; + positions.set(identifier, getPosition(screenSpaceEventHandler, event, new Cartesian2())); - // insert the lower point - positions[positionIndex++] = bottomPosition.x; - positions[positionIndex++] = bottomPosition.y; - positions[positionIndex++] = bottomPosition.z; + fireTouchEvents(screenSpaceEventHandler, event); - // insert the upper point - positions[positionIndex++] = topPosition.x; - positions[positionIndex++] = topPosition.y; - positions[positionIndex++] = topPosition.z; + var previousPositions = screenSpaceEventHandler._previousPositions; + previousPositions.set(identifier, Cartesian2.clone(positions.get(identifier))); + } else { + handleMouseDown(screenSpaceEventHandler, event); } + } - var attributes = new GeometryAttributes({ - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }) - }); + function handlePointerUp(screenSpaceEventHandler, event) { + if (event.pointerType === 'touch') { + var positions = screenSpaceEventHandler._positions; - var numVertices = size / 3; - size = 2 * numVertices - 4 + numVertices; - var indices = IndexDatatype.createTypedArray(numVertices, size); + var identifier = event.pointerId; + positions.remove(identifier); - var edgeIndex = 0; - for (i = 0; i < numVertices - 2; i += 2) { - var LL = i; - var LR = i + 2; - var pl = Cartesian3.fromArray(positions, LL * 3, scratchCartesian3Position1); - var pr = Cartesian3.fromArray(positions, LR * 3, scratchCartesian3Position2); - if (Cartesian3.equalsEpsilon(pl, pr, CesiumMath.EPSILON10)) { - continue; - } - var UL = i + 1; - var UR = i + 3; + fireTouchEvents(screenSpaceEventHandler, event); - indices[edgeIndex++] = UL; - indices[edgeIndex++] = LL; - indices[edgeIndex++] = UL; - indices[edgeIndex++] = UR; - indices[edgeIndex++] = LL; - indices[edgeIndex++] = LR; + var previousPositions = screenSpaceEventHandler._previousPositions; + previousPositions.remove(identifier); + } else { + handleMouseUp(screenSpaceEventHandler, event); } + } - indices[edgeIndex++] = numVertices - 2; - indices[edgeIndex++] = numVertices - 1; + function handlePointerMove(screenSpaceEventHandler, event) { + if (event.pointerType === 'touch') { + var positions = screenSpaceEventHandler._positions; - return new Geometry({ - attributes : attributes, - indices : indices, - primitiveType : PrimitiveType.LINES, - boundingSphere : new BoundingSphere.fromVertices(positions) - }); - }; + var identifier = event.pointerId; + var position = positions.get(identifier); + if(!defined(position)){ + return; + } - return WallOutlineGeometry; -}); + getPosition(screenSpaceEventHandler, event, position); + fireTouchMoveEvents(screenSpaceEventHandler, event); -define('Core/WebMercatorTilingScheme',[ - './Cartesian2', - './defaultValue', - './defined', - './defineProperties', - './Ellipsoid', - './Rectangle', - './WebMercatorProjection' - ], function( - Cartesian2, - defaultValue, - defined, - defineProperties, - Ellipsoid, - Rectangle, - WebMercatorProjection) { - 'use strict'; + var previousPositions = screenSpaceEventHandler._previousPositions; + Cartesian2.clone(positions.get(identifier), previousPositions.get(identifier)); + } else { + handleMouseMove(screenSpaceEventHandler, event); + } + } /** - * A tiling scheme for geometry referenced to a {@link WebMercatorProjection}, EPSG:3857. This is - * the tiling scheme used by Google Maps, Microsoft Bing Maps, and most of ESRI ArcGIS Online. + * Handles user input events. Custom functions can be added to be executed on + * when the user enters input. * - * @alias WebMercatorTilingScheme - * @constructor + * @alias ScreenSpaceEventHandler * - * @param {Object} [options] Object with the following properties: - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to - * the WGS84 ellipsoid. - * @param {Number} [options.numberOfLevelZeroTilesX=1] The number of tiles in the X direction at level zero of - * the tile tree. - * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of - * the tile tree. - * @param {Cartesian2} [options.rectangleSouthwestInMeters] The southwest corner of the rectangle covered by the - * tiling scheme, in meters. If this parameter or rectangleNortheastInMeters is not specified, the entire - * globe is covered in the longitude direction and an equal distance is covered in the latitude - * direction, resulting in a square projection. - * @param {Cartesian2} [options.rectangleNortheastInMeters] The northeast corner of the rectangle covered by the - * tiling scheme, in meters. If this parameter or rectangleSouthwestInMeters is not specified, the entire - * globe is covered in the longitude direction and an equal distance is covered in the latitude - * direction, resulting in a square projection. + * @param {Canvas} [element=document] The element to add events to. + * + * @constructor */ - function WebMercatorTilingScheme(options) { - options = defaultValue(options, {}); - - this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 1); - this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1); + function ScreenSpaceEventHandler(element) { + this._inputEvents = {}; + this._buttonDown = undefined; + this._isPinching = false; + this._lastSeenTouchEvent = -ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds; - this._projection = new WebMercatorProjection(this._ellipsoid); + this._primaryStartPosition = new Cartesian2(); + this._primaryPosition = new Cartesian2(); + this._primaryPreviousPosition = new Cartesian2(); - if (defined(options.rectangleSouthwestInMeters) && - defined(options.rectangleNortheastInMeters)) { - this._rectangleSouthwestInMeters = options.rectangleSouthwestInMeters; - this._rectangleNortheastInMeters = options.rectangleNortheastInMeters; - } else { - var semimajorAxisTimesPi = this._ellipsoid.maximumRadius * Math.PI; - this._rectangleSouthwestInMeters = new Cartesian2(-semimajorAxisTimesPi, -semimajorAxisTimesPi); - this._rectangleNortheastInMeters = new Cartesian2(semimajorAxisTimesPi, semimajorAxisTimesPi); - } + this._positions = new AssociativeArray(); + this._previousPositions = new AssociativeArray(); - var southwest = this._projection.unproject(this._rectangleSouthwestInMeters); - var northeast = this._projection.unproject(this._rectangleNortheastInMeters); - this._rectangle = new Rectangle(southwest.longitude, southwest.latitude, - northeast.longitude, northeast.latitude); - } + this._removalFunctions = []; - defineProperties(WebMercatorTilingScheme.prototype, { - /** - * Gets the ellipsoid that is tiled by this tiling scheme. - * @memberof WebMercatorTilingScheme.prototype - * @type {Ellipsoid} - */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } - }, + // TODO: Revisit when doing mobile development. May need to be configurable + // or determined based on the platform? + this._clickPixelTolerance = 5; - /** - * Gets the rectangle, in radians, covered by this tiling scheme. - * @memberof WebMercatorTilingScheme.prototype - * @type {Rectangle} - */ - rectangle : { - get : function() { - return this._rectangle; - } - }, + this._element = defaultValue(element, document); - /** - * Gets the map projection used by this tiling scheme. - * @memberof WebMercatorTilingScheme.prototype - * @type {MapProjection} - */ - projection : { - get : function() { - return this._projection; - } - } - }); + registerListeners(this); + } /** - * Gets the total number of tiles in the X direction at a specified level-of-detail. + * Set a function to be executed on an input event. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the X direction at the given level. + * @param {Function} action Function to be executed when the input event occurs. + * @param {Number} type The ScreenSpaceEventType of input event. + * @param {Number} [modifier] A KeyboardEventModifier key that is held when a <code>type</code> + * event occurs. + * + * @see ScreenSpaceEventHandler#getInputAction + * @see ScreenSpaceEventHandler#removeInputAction */ - WebMercatorTilingScheme.prototype.getNumberOfXTilesAtLevel = function(level) { - return this._numberOfLevelZeroTilesX << level; + ScreenSpaceEventHandler.prototype.setInputAction = function(action, type, modifier) { + if (!defined(action)) { + throw new DeveloperError('action is required.'); + } + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + var key = getInputEventKey(type, modifier); + this._inputEvents[key] = action; }; /** - * Gets the total number of tiles in the Y direction at a specified level-of-detail. + * Returns the function to be executed on an input event. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the Y direction at the given level. + * @param {Number} type The ScreenSpaceEventType of input event. + * @param {Number} [modifier] A KeyboardEventModifier key that is held when a <code>type</code> + * event occurs. + * + * @see ScreenSpaceEventHandler#setInputAction + * @see ScreenSpaceEventHandler#removeInputAction */ - WebMercatorTilingScheme.prototype.getNumberOfYTilesAtLevel = function(level) { - return this._numberOfLevelZeroTilesY << level; + ScreenSpaceEventHandler.prototype.getInputAction = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + var key = getInputEventKey(type, modifier); + return this._inputEvents[key]; }; /** - * Transforms a rectangle specified in geodetic radians to the native coordinate system - * of this tiling scheme. + * Removes the function to be executed on an input event. * - * @param {Rectangle} rectangle The rectangle to transform. - * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result' - * is undefined. + * @param {Number} type The ScreenSpaceEventType of input event. + * @param {Number} [modifier] A KeyboardEventModifier key that is held when a <code>type</code> + * event occurs. + * + * @see ScreenSpaceEventHandler#getInputAction + * @see ScreenSpaceEventHandler#setInputAction */ - WebMercatorTilingScheme.prototype.rectangleToNativeRectangle = function(rectangle, result) { - var projection = this._projection; - var southwest = projection.project(Rectangle.southwest(rectangle)); - var northeast = projection.project(Rectangle.northeast(rectangle)); - - if (!defined(result)) { - return new Rectangle(southwest.x, southwest.y, northeast.x, northeast.y); + ScreenSpaceEventHandler.prototype.removeInputAction = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); } - - result.west = southwest.x; - result.south = southwest.y; - result.east = northeast.x; - result.north = northeast.y; - return result; + + var key = getInputEventKey(type, modifier); + delete this._inputEvents[key]; }; /** - * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates - * of the tiling scheme. + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the rectangle - * if 'result' is undefined. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see ScreenSpaceEventHandler#destroy */ - WebMercatorTilingScheme.prototype.tileXYToNativeRectangle = function(x, y, level, result) { - var xTiles = this.getNumberOfXTilesAtLevel(level); - var yTiles = this.getNumberOfYTilesAtLevel(level); - - var xTileWidth = (this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x) / xTiles; - var west = this._rectangleSouthwestInMeters.x + x * xTileWidth; - var east = this._rectangleSouthwestInMeters.x + (x + 1) * xTileWidth; - - var yTileHeight = (this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y) / yTiles; - var north = this._rectangleNortheastInMeters.y - y * yTileHeight; - var south = this._rectangleNortheastInMeters.y - (y + 1) * yTileHeight; - - if (!defined(result)) { - return new Rectangle(west, south, east, north); - } - - result.west = west; - result.south = south; - result.east = east; - result.north = north; - return result; + ScreenSpaceEventHandler.prototype.isDestroyed = function() { + return false; }; /** - * Converts tile x, y coordinates and level to a cartographic rectangle in radians. + * Removes listeners held by this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Rectangle} The specified 'result', or a new object containing the rectangle - * if 'result' is undefined. + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * handler = handler && handler.destroy(); + * + * @see ScreenSpaceEventHandler#isDestroyed */ - WebMercatorTilingScheme.prototype.tileXYToRectangle = function(x, y, level, result) { - var nativeRectangle = this.tileXYToNativeRectangle(x, y, level, result); - - var projection = this._projection; - var southwest = projection.unproject(new Cartesian2(nativeRectangle.west, nativeRectangle.south)); - var northeast = projection.unproject(new Cartesian2(nativeRectangle.east, nativeRectangle.north)); + ScreenSpaceEventHandler.prototype.destroy = function() { + unregisterListeners(this); - nativeRectangle.west = southwest.longitude; - nativeRectangle.south = southwest.latitude; - nativeRectangle.east = northeast.longitude; - nativeRectangle.north = northeast.latitude; - return nativeRectangle; + return destroyObject(this); }; /** - * Calculates the tile x, y coordinates of the tile containing - * a given cartographic position. - * - * @param {Cartographic} position The position. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance - * should be created. - * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates - * if 'result' is undefined. + * The amount of time, in milliseconds, that mouse events will be disabled after + * receiving any touch events, such that any emulated mouse events will be ignored. + * @type {Number} + * @default 800 */ - WebMercatorTilingScheme.prototype.positionToTileXY = function(position, level, result) { - var rectangle = this._rectangle; - if (!Rectangle.contains(rectangle, position)) { - // outside the bounds of the tiling scheme - return undefined; - } - - var xTiles = this.getNumberOfXTilesAtLevel(level); - var yTiles = this.getNumberOfYTilesAtLevel(level); - - var overallWidth = this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x; - var xTileWidth = overallWidth / xTiles; - var overallHeight = this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y; - var yTileHeight = overallHeight / yTiles; - - var projection = this._projection; - - var webMercatorPosition = projection.project(position); - var distanceFromWest = webMercatorPosition.x - this._rectangleSouthwestInMeters.x; - var distanceFromNorth = this._rectangleNortheastInMeters.y - webMercatorPosition.y; - - var xTileCoordinate = distanceFromWest / xTileWidth | 0; - if (xTileCoordinate >= xTiles) { - xTileCoordinate = xTiles - 1; - } - var yTileCoordinate = distanceFromNorth / yTileHeight | 0; - if (yTileCoordinate >= yTiles) { - yTileCoordinate = yTiles - 1; - } - - if (!defined(result)) { - return new Cartesian2(xTileCoordinate, yTileCoordinate); - } - - result.x = xTileCoordinate; - result.y = yTileCoordinate; - return result; - }; + ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds = 800; - return WebMercatorTilingScheme; + return ScreenSpaceEventHandler; }); -define('Core/WeightSpline',[ - './Check', +define('Core/ShowGeometryInstanceAttribute',[ + './ComponentDatatype', './defaultValue', './defined', './defineProperties', - './DeveloperError', - './Spline' -], function( - Check, + './DeveloperError' + ], function( + ComponentDatatype, defaultValue, defined, defineProperties, - DeveloperError, - Spline) { + DeveloperError) { 'use strict'; /** - * A spline that linearly interpolates over an array of weight values used by morph targets. + * Value and type information for per-instance geometry attribute that determines if the geometry instance will be shown. * - * @alias WeightSpline + * @alias ShowGeometryInstanceAttribute * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. - * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Number[]} options.weights The array of floating-point control weights given. The weights are ordered such - * that all weights for the targets are given in chronological order and order in which they appear in - * the glTF from which the morph targets come. This means for 2 targets, weights = [w(0,0), w(0,1), w(1,0), w(1,1) ...] - * where i and j in w(i,j) are the time indices and target indices, respectively. - * - * @exception {DeveloperError} weights.length must be greater than or equal to 2. - * @exception {DeveloperError} times.length must be a factor of weights.length. + * @param {Boolean} [show=true] Determines if the geometry instance will be shown. * * * @example - * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ]; - * var weights = [0.0, 1.0, 0.25, 0.75, 0.5, 0.5, 0.75, 0.25, 1.0, 0.0]; //Two targets - * var spline = new Cesium.WeightSpline({ - * times : times, - * weights : weights + * var instance = new Cesium.GeometryInstance({ + * geometry : new Cesium.BoxGeometry({ + * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL, + * minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0), + * maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0) + * }), + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()), + * id : 'box', + * attributes : { + * show : new Cesium.ShowGeometryInstanceAttribute(false) + * } * }); * - * var p0 = spline.evaluate(times[0]); - * - * @see LinearSpline - * @see HermiteSpline - * @see CatmullRomSpline - * @see QuaternionSpline + * @see GeometryInstance + * @see GeometryInstanceAttribute */ - function WeightSpline(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var weights = options.weights; - var times = options.times; - - Check.defined('weights', weights); - Check.defined('times', times); - Check.typeOf.number.greaterThanOrEquals('weights.length', weights.length, 3); - if (weights.length % times.length !== 0) { - throw new DeveloperError('times.length must be a factor of weights.length.'); - } - - this._times = times; - this._weights = weights; - this._count = weights.length / times.length; + function ShowGeometryInstanceAttribute(show) { + show = defaultValue(show, true); - this._lastTimeIndex = 0; + /** + * The values for the attributes stored in a typed array. + * + * @type Uint8Array + * + * @default [1.0] + */ + this.value = ShowGeometryInstanceAttribute.toValue(show); } - defineProperties(WeightSpline.prototype, { + defineProperties(ShowGeometryInstanceAttribute.prototype, { /** - * An array of times for the control weights. + * The datatype of each component in the attribute, e.g., individual elements in + * {@link ColorGeometryInstanceAttribute#value}. * - * @memberof WeightSpline.prototype + * @memberof ShowGeometryInstanceAttribute.prototype * - * @type {Number[]} + * @type {ComponentDatatype} + * @readonly + * + * @default {@link ComponentDatatype.UNSIGNED_BYTE} + */ + componentDatatype : { + get : function() { + return ComponentDatatype.UNSIGNED_BYTE; + } + }, + + /** + * The number of components in the attributes, i.e., {@link ColorGeometryInstanceAttribute#value}. + * + * @memberof ShowGeometryInstanceAttribute.prototype + * + * @type {Number} * @readonly + * + * @default 1 */ - times : { + componentsPerAttribute : { get : function() { - return this._times; + return 1; } }, /** - * An array of floating-point array control weights. + * When <code>true</code> and <code>componentDatatype</code> is an integer format, + * indicate that the components should be mapped to the range [0, 1] (unsigned) + * or [-1, 1] (signed) when they are accessed as floating-point for rendering. * - * @memberof WeightSpline.prototype + * @memberof ShowGeometryInstanceAttribute.prototype * - * @type {Number[]} + * @type {Boolean} * @readonly + * + * @default true */ - weights : { + normalize : { get : function() { - return this._weights; + return false; } } }); /** - * Finds an index <code>i</code> in <code>times</code> such that the parameter - * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. - * @function - * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. - * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. - */ - WeightSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; - - /** - * Wraps the given time to the period covered by the spline. - * @function - * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. - */ - WeightSpline.prototype.wrapTime = Spline.prototype.wrapTime; - - /** - * Clamps the given time to the period covered by the spline. - * @function - * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. - */ - WeightSpline.prototype.clampTime = Spline.prototype.clampTime; - - /** - * Evaluates the curve at a given time. + * Converts a boolean show to a typed array that can be used to assign a show attribute. * - * @param {Number} time The time at which to evaluate the curve. - * @param {Number[]} [result] The object onto which to store the result. - * @returns {Number[]} The modified result parameter or a new instance of the point on the curve at the given time. + * @param {Boolean} show The show value. + * @param {Uint8Array} [result] The array to store the result in, if undefined a new instance will be created. + * @returns {Uint8Array} The modified result parameter or a new instance if result was undefined. * - * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> - * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element - * in the array <code>times</code>. + * @example + * var attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true, attributes.show); */ - WeightSpline.prototype.evaluate = function(time, result) { - var weights = this.weights; - var times = this.times; - - var i = this._lastTimeIndex = this.findTimeInterval(time, this._lastTimeIndex); - var u = (time - times[i]) / (times[i + 1] - times[i]); - - if (!defined(result)) { - result = new Array(this._count); + ShowGeometryInstanceAttribute.toValue = function(show, result) { + if (!defined(show)) { + throw new DeveloperError('show is required.'); } - - for (var j = 0; j < this._count; j++) { - var index = (i * this._count) + j; - result[j] = weights[index] * (1.0 - u) + weights[index + this._count] * u; + + if (!defined(result)) { + return new Uint8Array([show]); } - + result[0] = show; return result; }; - return WeightSpline; + return ShowGeometryInstanceAttribute; }); -define('Core/wrapFunction',[ - './DeveloperError' +define('Core/Simon1994PlanetaryPositions',[ + './Cartesian3', + './defined', + './DeveloperError', + './JulianDate', + './Math', + './Matrix3', + './TimeConstants', + './TimeStandard' ], function( - DeveloperError) { + Cartesian3, + defined, + DeveloperError, + JulianDate, + CesiumMath, + Matrix3, + TimeConstants, + TimeStandard) { 'use strict'; /** - * Wraps a function on the provided objects with another function called in the - * object's context so that the new function is always called immediately - * before the old one. - * - * @private + * Contains functions for finding the Cartesian coordinates of the sun and the moon in the + * Earth-centered inertial frame. + * + * @exports Simon1994PlanetaryPositions */ - function wrapFunction(obj, oldFunction, newFunction) { - if (typeof oldFunction !== 'function') { - throw new DeveloperError('oldFunction is required to be a function.'); - } + var Simon1994PlanetaryPositions = {}; - if (typeof newFunction !== 'function') { - throw new DeveloperError('oldFunction is required to be a function.'); - } - - return function() { - newFunction.apply(obj, arguments); - oldFunction.apply(obj, arguments); - }; + function computeTdbMinusTtSpice(daysSinceJ2000InTerrestrialTime) { + /* STK Comments ------------------------------------------------------ + * This function uses constants designed to be consistent with + * the SPICE Toolkit from JPL version N0051 (unitim.c) + * M0 = 6.239996 + * M0Dot = 1.99096871e-7 rad/s = 0.01720197 rad/d + * EARTH_ECC = 1.671e-2 + * TDB_AMPL = 1.657e-3 secs + *--------------------------------------------------------------------*/ + + //* Values taken as specified in STK Comments except: 0.01720197 rad/day = 1.99096871e-7 rad/sec + //* Here we use the more precise value taken from the SPICE value 1.99096871e-7 rad/sec converted to rad/day + //* All other constants are consistent with the SPICE implementation of the TDB conversion + //* except where we treat the independent time parameter to be in TT instead of TDB. + //* This is an approximation made to facilitate performance due to the higher prevalance of + //* the TT2TDB conversion over TDB2TT in order to avoid having to iterate when converting to TDB for the JPL ephemeris. + //* Days are used instead of seconds to provide a slight improvement in numerical precision. + + //* For more information see: + //* http://www.cv.nrao.edu/~rfisher/Ephemerides/times.html#TDB + //* ftp://ssd.jpl.nasa.gov/pub/eph/planets/ioms/ExplSupplChap8.pdf + + var g = 6.239996 + (0.0172019696544) * daysSinceJ2000InTerrestrialTime; + return 1.657e-3 * Math.sin(g + 1.671e-2 * Math.sin(g)); } - return wrapFunction; -}); + var TdtMinusTai = 32.184; + var J2000d = 2451545; + function taiToTdb(date, result) { + //Converts TAI to TT + result = JulianDate.addSeconds(date, TdtMinusTai, result); -define('DataSources/ConstantProperty',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/Event' - ], function( - defined, - defineProperties, - Event) { - 'use strict'; + //Converts TT to TDB + var days = JulianDate.totalDays(result) - J2000d; + result = JulianDate.addSeconds(result, computeTdbMinusTtSpice(days), result); - /** - * A {@link Property} whose value does not change with respect to simulation time. - * - * @alias ConstantProperty - * @constructor - * - * @param {Object} [value] The property value. - * - * @see ConstantPositionProperty - */ - function ConstantProperty(value) { - this._value = undefined; - this._hasClone = false; - this._hasEquals = false; - this._definitionChanged = new Event(); - this.setValue(value); + return result; } - defineProperties(ConstantProperty.prototype, { - /** - * Gets a value indicating if this property is constant. - * This property always returns <code>true</code>. - * @memberof ConstantProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - value : true - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof ConstantProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } + var epoch = new JulianDate(2451545, 0, TimeStandard.TAI); //Actually TDB (not TAI) + var MetersPerKilometer = 1000.0; + var RadiansPerDegree = CesiumMath.RADIANS_PER_DEGREE; + var RadiansPerArcSecond = CesiumMath.RADIANS_PER_ARCSECOND; + var MetersPerAstronomicalUnit = 1.49597870e+11; // IAU 1976 value + + var perifocalToEquatorial = new Matrix3(); + function elementsToCartesian(semimajorAxis, eccentricity, inclination, longitudeOfPerigee, longitudeOfNode, meanLongitude, result) { + if (inclination < 0.0) { + inclination = -inclination; + longitudeOfNode += CesiumMath.PI; } - }); - /** - * Gets the value of the property. - * - * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ConstantProperty.prototype.getValue = function(time, result) { - return this._hasClone ? this._value.clone(result) : this._value; - }; + if (inclination < 0 || inclination > CesiumMath.PI) { + throw new DeveloperError('The inclination is out of range. Inclination must be greater than or equal to zero and less than or equal to Pi radians.'); + } + + var radiusOfPeriapsis = semimajorAxis * (1.0 - eccentricity); + var argumentOfPeriapsis = longitudeOfPerigee - longitudeOfNode; + var rightAscensionOfAscendingNode = longitudeOfNode; + var trueAnomaly = meanAnomalyToTrueAnomaly(meanLongitude - longitudeOfPerigee, eccentricity); + var type = chooseOrbit(eccentricity, 0.0); - /** - * Sets the value of the property. - * - * @param {Object} value The property value. - */ - ConstantProperty.prototype.setValue = function(value) { - var oldValue = this._value; - if (oldValue !== value) { - var isDefined = defined(value); - var hasClone = isDefined && typeof value.clone === 'function'; - var hasEquals = isDefined && typeof value.equals === 'function'; + if (type === 'Hyperbolic' && Math.abs(CesiumMath.negativePiToPi(trueAnomaly)) >= Math.acos(- 1.0 / eccentricity)) { + throw new DeveloperError('The true anomaly of the hyperbolic orbit lies outside of the bounds of the hyperbola.'); + } + + perifocalToCartesianMatrix(argumentOfPeriapsis, inclination, rightAscensionOfAscendingNode, perifocalToEquatorial); + var semilatus = radiusOfPeriapsis * (1.0 + eccentricity); + var costheta = Math.cos(trueAnomaly); + var sintheta = Math.sin(trueAnomaly); - var changed = !hasEquals || !value.equals(oldValue); - if (changed) { - this._hasClone = hasClone; - this._hasEquals = hasEquals; - this._value = !hasClone ? value : value.clone(this._value); - this._definitionChanged.raiseEvent(this); - } + var denom = (1.0 + eccentricity * costheta); + + if (denom <= CesiumMath.Epsilon10) { + throw new DeveloperError('elements cannot be converted to cartesian'); + } + + var radius = semilatus / denom; + if (!defined(result)) { + result = new Cartesian3(radius * costheta, radius * sintheta, 0.0); + } else { + result.x = radius * costheta; + result.y = radius * sintheta; + result.z = 0.0; } - }; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - ConstantProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof ConstantProperty && // - ((!this._hasEquals && (this._value === other._value)) || // - (this._hasEquals && this._value.equals(other._value)))); - }; + return Matrix3.multiplyByVector(perifocalToEquatorial, result, result); + } - /** - * Gets this property's value. - * - * @returns {*} This property's value. - */ - ConstantProperty.prototype.valueOf = function() { - return this._value; - }; + function chooseOrbit(eccentricity, tolerance) { + if (eccentricity < 0) { + throw new DeveloperError('eccentricity cannot be negative.'); + } + + if (eccentricity <= tolerance) { + return 'Circular'; + } else if (eccentricity < 1.0 - tolerance) { + return 'Elliptical'; + } else if (eccentricity <= 1.0 + tolerance) { + return 'Parabolic'; + } + return 'Hyperbolic'; + } - /** - * Creates a string representing this property's value. - * - * @returns {String} A string representing the property's value. - */ - ConstantProperty.prototype.toString = function() { - return String(this._value); - }; + // Calculates the true anomaly given the mean anomaly and the eccentricity. + function meanAnomalyToTrueAnomaly(meanAnomaly, eccentricity) { + if (eccentricity < 0.0 || eccentricity >= 1.0) { + throw new DeveloperError('eccentricity out of range.'); + } + + var eccentricAnomaly = meanAnomalyToEccentricAnomaly(meanAnomaly, eccentricity); + return eccentricAnomalyToTrueAnomaly(eccentricAnomaly, eccentricity); + } - return ConstantProperty; -}); + var maxIterationCount = 50; + var keplerEqConvergence = CesiumMath.EPSILON8; + // Calculates the eccentric anomaly given the mean anomaly and the eccentricity. + function meanAnomalyToEccentricAnomaly(meanAnomaly, eccentricity) { + if (eccentricity < 0.0 || eccentricity >= 1.0) { + throw new DeveloperError('eccentricity out of range.'); + } + + var revs = Math.floor(meanAnomaly / CesiumMath.TWO_PI); -define('DataSources/createPropertyDescriptor',[ - '../Core/defaultValue', - '../Core/defined', - './ConstantProperty' - ], function( - defaultValue, - defined, - ConstantProperty) { - 'use strict'; + // Find angle in current revolution + meanAnomaly -= revs * CesiumMath.TWO_PI; - function createProperty(name, privateName, subscriptionName, configurable, createPropertyCallback) { - return { - configurable : configurable, - get : function() { - return this[privateName]; - }, - set : function(value) { - var oldValue = this[privateName]; - var subscription = this[subscriptionName]; - if (defined(subscription)) { - subscription(); - this[subscriptionName] = undefined; - } + // calculate starting value for iteration sequence + var iterationValue = meanAnomaly + (eccentricity * Math.sin(meanAnomaly)) / + (1.0 - Math.sin(meanAnomaly + eccentricity) + Math.sin(meanAnomaly)); - var hasValue = value !== undefined; - if (hasValue && (!defined(value) || !defined(value.getValue)) && defined(createPropertyCallback)) { - value = createPropertyCallback(value); - } + // Perform Newton-Raphson iteration on Kepler's equation + var eccentricAnomaly = Number.MAX_VALUE; - if (oldValue !== value) { - this[privateName] = value; - this._definitionChanged.raiseEvent(this, name, value, oldValue); - } + var count; + for (count = 0; + count < maxIterationCount && Math.abs(eccentricAnomaly - iterationValue) > keplerEqConvergence; + ++count) + { + eccentricAnomaly = iterationValue; + var NRfunction = eccentricAnomaly - eccentricity * Math.sin(eccentricAnomaly) - meanAnomaly; + var dNRfunction = 1 - eccentricity * Math.cos(eccentricAnomaly); + iterationValue = eccentricAnomaly - NRfunction / dNRfunction; + } - if (defined(value) && defined(value.definitionChanged)) { - this[subscriptionName] = value.definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this, name, value, value); - }, this); - } - } - }; + if (count >= maxIterationCount) { + throw new DeveloperError('Kepler equation did not converge'); + // STK Components uses a numerical method to find the eccentric anomaly in the case that Kepler's + // equation does not converge. We don't expect that to ever be necessary for the reasonable orbits used here. + } + + eccentricAnomaly = iterationValue + revs * CesiumMath.TWO_PI; + return eccentricAnomaly; } - function createConstantProperty(value) { - return new ConstantProperty(value); - } + // Calculates the true anomaly given the eccentric anomaly and the eccentricity. + function eccentricAnomalyToTrueAnomaly(eccentricAnomaly, eccentricity) { + if (eccentricity < 0.0 || eccentricity >= 1.0) { + throw new DeveloperError('eccentricity out of range.'); + } + + // Calculate the number of previous revolutions + var revs = Math.floor(eccentricAnomaly / CesiumMath.TWO_PI); - /** - * Used to consistently define all DataSources graphics objects. - * This is broken into two functions because the Chrome profiler does a better - * job of optimizing lookups if it notices that the string is constant throughout the function. - * @private - */ - function createPropertyDescriptor(name, configurable, createPropertyCallback) { - //Safari 8.0.3 has a JavaScript bug that causes it to confuse two variables and treat them as the same. - //The two extra toString calls work around the issue. - return createProperty(name, '_' + name.toString(), '_' + name.toString() + 'Subscription', defaultValue(configurable, false), defaultValue(createPropertyCallback, createConstantProperty)); + // Find angle in current revolution + eccentricAnomaly -= revs * CesiumMath.TWO_PI; + + // Calculate true anomaly from eccentric anomaly + var trueAnomalyX = Math.cos(eccentricAnomaly) - eccentricity; + var trueAnomalyY = Math.sin(eccentricAnomaly) * Math.sqrt(1 - eccentricity * eccentricity); + + var trueAnomaly = Math.atan2(trueAnomalyY, trueAnomalyX); + + // Ensure the correct quadrant + trueAnomaly = CesiumMath.zeroToTwoPi(trueAnomaly); + if (eccentricAnomaly < 0) + { + trueAnomaly -= CesiumMath.TWO_PI; + } + + // Add on previous revolutions + trueAnomaly += revs * CesiumMath.TWO_PI; + + return trueAnomaly; } - return createPropertyDescriptor; -}); + // Calculates the transformation matrix to convert from the perifocal (PQW) coordinate + // system to inertial cartesian coordinates. + function perifocalToCartesianMatrix(argumentOfPeriapsis, inclination, rightAscension, result) { + if (inclination < 0 || inclination > CesiumMath.PI) { + throw new DeveloperError('inclination out of range'); + } + + var cosap = Math.cos(argumentOfPeriapsis); + var sinap = Math.sin(argumentOfPeriapsis); -define('DataSources/BillboardGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createPropertyDescriptor) { - 'use strict'; + var cosi = Math.cos(inclination); + var sini = Math.sin(inclination); - /** - * Describes a two dimensional icon located at the position of the containing {@link Entity}. - * <p> - * <div align='center'> - * <img src='Images/Billboard.png' width='400' height='300' /><br /> - * Example billboards - * </div> - * </p> - * - * @alias BillboardGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.image] A Property specifying the Image, URI, or Canvas to use for the billboard. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the billboard. - * @param {Property} [options.scale=1.0] A numeric Property specifying the scale to apply to the image size. - * @param {Property} [options.horizontalOrigin=HorizontalOrigin.CENTER] A Property specifying the {@link HorizontalOrigin}. - * @param {Property} [options.verticalOrigin=VerticalOrigin.CENTER] A Property specifying the {@link VerticalOrigin}. - * @param {Property} [options.eyeOffset=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the eye offset. - * @param {Property} [options.pixelOffset=Cartesian2.ZERO] A {@link Cartesian2} Property specifying the pixel offset. - * @param {Property} [options.rotation=0] A numeric Property specifying the rotation about the alignedAxis. - * @param {Property} [options.alignedAxis=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the unit vector axis of rotation. - * @param {Property} [options.width] A numeric Property specifying the width of the billboard in pixels, overriding the native size. - * @param {Property} [options.height] A numeric Property specifying the height of the billboard in pixels, overriding the native size. - * @param {Property} [options.color=Color.WHITE] A Property specifying the tint {@link Color} of the image. - * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to scale the point based on distance from the camera. - * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera. - * @param {Property} [options.pixelOffsetScaleByDistance] A {@link NearFarScalar} Property used to set pixelOffset based on distance from the camera. - * @param {Property} [options.imageSubRegion] A Property specifying a {@link BoundingRectangle} that defines a sub-region of the image to use for the billboard, rather than the entire image, measured in pixels from the bottom-left. - * @param {Property} [options.sizeInMeters] A boolean Property specifying whether this billboard's size should be measured in meters. - * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this billboard will be displayed. - * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Billboards.html|Cesium Sandcastle Billboard Demo} - */ - function BillboardGraphics(options) { - this._image = undefined; - this._imageSubscription = undefined; - this._imageSubRegion = undefined; - this._imageSubRegionSubscription = undefined; - this._width = undefined; - this._widthSubscription = undefined; - this._height = undefined; - this._heightSubscription = undefined; - this._scale = undefined; - this._scaleSubscription = undefined; - this._rotation = undefined; - this._rotationSubscription = undefined; - this._alignedAxis = undefined; - this._alignedAxisSubscription = undefined; - this._horizontalOrigin = undefined; - this._horizontalOriginSubscription = undefined; - this._verticalOrigin = undefined; - this._verticalOriginSubscription = undefined; - this._color = undefined; - this._colorSubscription = undefined; - this._eyeOffset = undefined; - this._eyeOffsetSubscription = undefined; - this._heightReference = undefined; - this._heightReferenceSubscription = undefined; - this._pixelOffset = undefined; - this._pixelOffsetSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._scaleByDistance = undefined; - this._scaleByDistanceSubscription = undefined; - this._translucencyByDistance = undefined; - this._translucencyByDistanceSubscription = undefined; - this._pixelOffsetScaleByDistance = undefined; - this._pixelOffsetScaleByDistanceSubscription = undefined; - this._sizeInMeters = undefined; - this._sizeInMetersSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._disableDepthTestDistance = undefined; - this._disableDepthTestDistanceSubscription = undefined; - this._definitionChanged = new Event(); + var cosraan = Math.cos(rightAscension); + var sinraan = Math.sin(rightAscension); + if (!defined(result)) { + result = new Matrix3( + cosraan * cosap - sinraan * sinap * cosi, + -cosraan * sinap - sinraan * cosap * cosi, + sinraan * sini, - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + sinraan * cosap + cosraan * sinap * cosi, + -sinraan * sinap + cosraan * cosap * cosi, + -cosraan * sini, + + sinap * sini, + cosap * sini, + cosi); + } else { + result[0] = cosraan * cosap - sinraan * sinap * cosi; + result[1] = sinraan * cosap + cosraan * sinap * cosi; + result[2] = sinap * sini; + result[3] = -cosraan * sinap - sinraan * cosap * cosi; + result[4] = -sinraan * sinap + cosraan * cosap * cosi; + result[5] = cosap * sini; + result[6] = sinraan * sini; + result[7] = -cosraan * sini; + result[8] = cosi; + } + return result; } - defineProperties(BillboardGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof BillboardGraphics.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + // From section 5.8 + var semiMajorAxis0 = 1.0000010178 * MetersPerAstronomicalUnit; + var meanLongitude0 = 100.46645683 * RadiansPerDegree; + var meanLongitude1 = 1295977422.83429 * RadiansPerArcSecond; - /** - * Gets or sets the Property specifying the Image, URI, or Canvas to use for the billboard. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - image : createPropertyDescriptor('image'), + // From table 6 + var p1u = 16002; + var p2u = 21863; + var p3u = 32004; + var p4u = 10931; + var p5u = 14529; + var p6u = 16368; + var p7u = 15318; + var p8u = 32794; - /** - * Gets or sets the Property specifying a {@link BoundingRectangle} that defines a - * sub-region of the <code>image</code> to use for the billboard, rather than the entire image, - * measured in pixels from the bottom-left. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - imageSubRegion : createPropertyDescriptor('imageSubRegion'), + var Ca1 = 64 * 1e-7 * MetersPerAstronomicalUnit; + var Ca2 = -152 * 1e-7 * MetersPerAstronomicalUnit; + var Ca3 = 62 * 1e-7 * MetersPerAstronomicalUnit; + var Ca4 = -8 * 1e-7 * MetersPerAstronomicalUnit; + var Ca5 = 32 * 1e-7 * MetersPerAstronomicalUnit; + var Ca6 = -41 * 1e-7 * MetersPerAstronomicalUnit; + var Ca7 = 19 * 1e-7 * MetersPerAstronomicalUnit; + var Ca8 = -11 * 1e-7 * MetersPerAstronomicalUnit; - /** - * Gets or sets the numeric Property specifying the uniform scale to apply to the image. - * A scale greater than <code>1.0</code> enlarges the billboard while a scale less than <code>1.0</code> shrinks it. - * <p> - * <div align='center'> - * <img src='Images/Billboard.setScale.png' width='400' height='300' /><br/> - * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, and <code>2.0</code>. - * </div> - * </p> - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default 1.0 - */ - scale : createPropertyDescriptor('scale'), + var Sa1 = -150 * 1e-7 * MetersPerAstronomicalUnit; + var Sa2 = -46 * 1e-7 * MetersPerAstronomicalUnit; + var Sa3 = 68 * 1e-7 * MetersPerAstronomicalUnit; + var Sa4 = 54 * 1e-7 * MetersPerAstronomicalUnit; + var Sa5 = 14 * 1e-7 * MetersPerAstronomicalUnit; + var Sa6 = 24 * 1e-7 * MetersPerAstronomicalUnit; + var Sa7 = -28 * 1e-7 * MetersPerAstronomicalUnit; + var Sa8 = 22 * 1e-7 * MetersPerAstronomicalUnit; - /** - * Gets or sets the numeric Property specifying the rotation of the image - * counter clockwise from the <code>alignedAxis</code>. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default 0 - */ - rotation : createPropertyDescriptor('rotation'), + var q1u = 10; + var q2u = 16002; + var q3u = 21863; + var q4u = 10931; + var q5u = 1473; + var q6u = 32004; + var q7u = 4387; + var q8u = 73; - /** - * Gets or sets the {@link Cartesian3} Property specifying the unit vector axis of rotation - * in the fixed frame. When set to Cartesian3.ZERO the rotation is from the top of the screen. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default Cartesian3.ZERO - */ - alignedAxis : createPropertyDescriptor('alignedAxis'), + var Cl1 = -325 * 1e-7; + var Cl2 = -322 * 1e-7; + var Cl3 = -79 * 1e-7; + var Cl4 = 232 * 1e-7; + var Cl5 = -52 * 1e-7; + var Cl6 = 97 * 1e-7; + var Cl7 = 55 * 1e-7; + var Cl8 = -41 * 1e-7; - /** - * Gets or sets the Property specifying the {@link HorizontalOrigin}. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default HorizontalOrigin.CENTER - */ - horizontalOrigin : createPropertyDescriptor('horizontalOrigin'), + var Sl1 = -105 * 1e-7; + var Sl2 = -137 * 1e-7; + var Sl3 = 258 * 1e-7; + var Sl4 = 35 * 1e-7; + var Sl5 = -116 * 1e-7; + var Sl6 = -88 * 1e-7; + var Sl7 = -112 * 1e-7; + var Sl8 = -80 * 1e-7; - /** - * Gets or sets the Property specifying the {@link VerticalOrigin}. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default VerticalOrigin.CENTER - */ - verticalOrigin : createPropertyDescriptor('verticalOrigin'), + var scratchDate = new JulianDate(0, 0.0, TimeStandard.TAI); + /** + * Gets a point describing the motion of the Earth-Moon barycenter according to the equations + * described in section 6. + */ - /** - * Gets or sets the Property specifying the {@link Color} that is multiplied with the <code>image</code>. - * This has two common use cases. First, the same white texture may be used by many different billboards, - * each with a different color, to create colored billboards. Second, the color's alpha component can be - * used to make the billboard translucent as shown below. An alpha of <code>0.0</code> makes the billboard - * transparent, and <code>1.0</code> makes the billboard opaque. - * <p> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><code>default</code><br/><img src='Images/Billboard.setColor.Alpha255.png' width='250' height='188' /></td> - * <td align='center'><code>alpha : 0.5</code><br/><img src='Images/Billboard.setColor.Alpha127.png' width='250' height='188' /></td> - * </tr></table> - * </div> - * </p> - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color'), + function computeSimonEarthMoonBarycenter(date, result) { - /** - * Gets or sets the {@link Cartesian3} Property specifying the billboard's offset in eye coordinates. - * Eye coordinates is a left-handed coordinate system, where <code>x</code> points towards the viewer's - * right, <code>y</code> points up, and <code>z</code> points into the screen. - * <p> - * An eye offset is commonly used to arrange multiple billboards or objects at the same position, e.g., to - * arrange a billboard above its corresponding 3D model. - * </p> - * Below, the billboard is positioned at the center of the Earth but an eye offset makes it always - * appear on top of the Earth regardless of the viewer's or Earth's orientation. - * <p> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> - * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> - * </tr></table> - * <code>b.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code> - * </div> - * </p> - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default Cartesian3.ZERO - */ - eyeOffset : createPropertyDescriptor('eyeOffset'), + // t is thousands of years from J2000 TDB + taiToTdb(date, scratchDate); + var x = (scratchDate.dayNumber - epoch.dayNumber) + ((scratchDate.secondsOfDay - epoch.secondsOfDay)/TimeConstants.SECONDS_PER_DAY); + var t = x / (TimeConstants.DAYS_PER_JULIAN_CENTURY * 10.0); - /** - * Gets or sets the Property specifying the {@link HeightReference}. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default HeightReference.NONE - */ - heightReference : createPropertyDescriptor('heightReference'), + var u = 0.35953620 * t; + var semimajorAxis = semiMajorAxis0 + + Ca1 * Math.cos(p1u * u) + Sa1 * Math.sin(p1u * u) + + Ca2 * Math.cos(p2u * u) + Sa2 * Math.sin(p2u * u) + + Ca3 * Math.cos(p3u * u) + Sa3 * Math.sin(p3u * u) + + Ca4 * Math.cos(p4u * u) + Sa4 * Math.sin(p4u * u) + + Ca5 * Math.cos(p5u * u) + Sa5 * Math.sin(p5u * u) + + Ca6 * Math.cos(p6u * u) + Sa6 * Math.sin(p6u * u) + + Ca7 * Math.cos(p7u * u) + Sa7 * Math.sin(p7u * u) + + Ca8 * Math.cos(p8u * u) + Sa8 * Math.sin(p8u * u); + var meanLongitude = meanLongitude0 + meanLongitude1 * t + + Cl1 * Math.cos(q1u * u) + Sl1 * Math.sin(q1u * u) + + Cl2 * Math.cos(q2u * u) + Sl2 * Math.sin(q2u * u) + + Cl3 * Math.cos(q3u * u) + Sl3 * Math.sin(q3u * u) + + Cl4 * Math.cos(q4u * u) + Sl4 * Math.sin(q4u * u) + + Cl5 * Math.cos(q5u * u) + Sl5 * Math.sin(q5u * u) + + Cl6 * Math.cos(q6u * u) + Sl6 * Math.sin(q6u * u) + + Cl7 * Math.cos(q7u * u) + Sl7 * Math.sin(q7u * u) + + Cl8 * Math.cos(q8u * u) + Sl8 * Math.sin(q8u * u); - /** - * Gets or sets the {@link Cartesian2} Property specifying the billboard's pixel offset in screen space - * from the origin of this billboard. This is commonly used to align multiple billboards and labels at - * the same position, e.g., an image and text. The screen space origin is the top, left corner of the - * canvas; <code>x</code> increases from left to right, and <code>y</code> increases from top to bottom. - * <p> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><code>default</code><br/><img src='Images/Billboard.setPixelOffset.default.png' width='250' height='188' /></td> - * <td align='center'><code>b.pixeloffset = new Cartesian2(50, 25);</code><br/><img src='Images/Billboard.setPixelOffset.x50y-25.png' width='250' height='188' /></td> - * </tr></table> - * The billboard's origin is indicated by the yellow point. - * </div> - * </p> - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default Cartesian2.ZERO - */ - pixelOffset : createPropertyDescriptor('pixelOffset'), + // All constants in this part are from section 5.8 + var eccentricity = 0.0167086342 - 0.0004203654 * t; + var longitudeOfPerigee = 102.93734808 * RadiansPerDegree + 11612.35290 * RadiansPerArcSecond * t; + var inclination = 469.97289 * RadiansPerArcSecond * t; + var longitudeOfNode = 174.87317577 * RadiansPerDegree - 8679.27034 * RadiansPerArcSecond * t; - /** - * Gets or sets the boolean Property specifying the visibility of the billboard. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + return elementsToCartesian(semimajorAxis, eccentricity, inclination, longitudeOfPerigee, + longitudeOfNode, meanLongitude, result); + } - /** - * Gets or sets the numeric Property specifying the billboard's width in pixels. - * When undefined, the native width is used. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - width : createPropertyDescriptor('width'), + /** + * Gets a point describing the position of the moon according to the equations described in section 4. + */ + function computeSimonMoon(date, result) { + taiToTdb(date, scratchDate); + var x = (scratchDate.dayNumber - epoch.dayNumber) + ((scratchDate.secondsOfDay - epoch.secondsOfDay)/TimeConstants.SECONDS_PER_DAY); + var t = x / (TimeConstants.DAYS_PER_JULIAN_CENTURY); + var t2 = t * t; + var t3 = t2 * t; + var t4 = t3 * t; - /** - * Gets or sets the numeric Property specifying the height of the billboard in pixels. - * When undefined, the native height is used. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - height : createPropertyDescriptor('height'), + // Terms from section 3.4 (b.1) + var semimajorAxis = 383397.7725 + 0.0040 * t; + var eccentricity = 0.055545526 - 0.000000016 * t; + var inclinationConstant = 5.15668983 * RadiansPerDegree; + var inclinationSecPart = -0.00008 * t + 0.02966 * t2 - + 0.000042 * t3 - 0.00000013 * t4; + var longitudeOfPerigeeConstant = 83.35324312 * RadiansPerDegree; + var longitudeOfPerigeeSecPart = 14643420.2669 * t - 38.2702 * t2 - + 0.045047 * t3 + 0.00021301 * t4; + var longitudeOfNodeConstant = 125.04455501 * RadiansPerDegree; + var longitudeOfNodeSecPart = -6967919.3631 * t + 6.3602 * t2 + + 0.007625 * t3 - 0.00003586 * t4; + var meanLongitudeConstant = 218.31664563 * RadiansPerDegree; + var meanLongitudeSecPart = 1732559343.48470 * t - 6.3910 * t2 + + 0.006588 * t3 - 0.00003169 * t4; - /** - * Gets or sets {@link NearFarScalar} Property specifying the scale of the billboard based on the distance from the camera. - * A billboard's scale will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the billboard's scale remains clamped to the nearest bound. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - scaleByDistance : createPropertyDescriptor('scaleByDistance'), + // Delaunay arguments from section 3.5 b + var D = 297.85019547 * RadiansPerDegree + RadiansPerArcSecond * + (1602961601.2090 * t - 6.3706 * t2 + 0.006593 * t3 - 0.00003169 * t4); + var F = 93.27209062 * RadiansPerDegree + RadiansPerArcSecond * + (1739527262.8478 * t - 12.7512 * t2 - 0.001037 * t3 + 0.00000417 * t4); + var l = 134.96340251 * RadiansPerDegree + RadiansPerArcSecond * + (1717915923.2178 * t + 31.8792 * t2 + 0.051635 * t3 - 0.00024470 * t4); + var lprime = 357.52910918 * RadiansPerDegree + RadiansPerArcSecond * + (129596581.0481 * t - 0.5532 * t2 + 0.000136 * t3 - 0.00001149 * t4); + var psi = 310.17137918 * RadiansPerDegree - RadiansPerArcSecond * + (6967051.4360 * t + 6.2068 * t2 + 0.007618 * t3 - 0.00003219 * t4); - /** - * Gets or sets {@link NearFarScalar} Property specifying the translucency of the billboard based on the distance from the camera. - * A billboard's translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the billboard's translucency remains clamped to the nearest bound. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - translucencyByDistance : createPropertyDescriptor('translucencyByDistance'), + // Add terms from Table 4 + var twoD = 2.0 * D; + var fourD = 4.0 * D; + var sixD = 6.0 * D; + var twol = 2.0 * l; + var threel = 3.0 * l; + var fourl = 4.0 * l; + var twoF = 2.0 * F; + semimajorAxis += 3400.4 * Math.cos(twoD) - 635.6 * Math.cos(twoD - l) - + 235.6 * Math.cos(l) + 218.1 * Math.cos(twoD - lprime) + + 181.0 * Math.cos(twoD + l); + eccentricity += 0.014216 * Math.cos(twoD - l) + 0.008551 * Math.cos(twoD - twol) - + 0.001383 * Math.cos(l) + 0.001356 * Math.cos(twoD + l) - + 0.001147 * Math.cos(fourD - threel) - 0.000914 * Math.cos(fourD - twol) + + 0.000869 * Math.cos(twoD - lprime - l) - 0.000627 * Math.cos(twoD) - + 0.000394 * Math.cos(fourD - fourl) + 0.000282 * Math.cos(twoD - lprime - twol) - + 0.000279 * Math.cos(D - l) - 0.000236 * Math.cos(twol) + + 0.000231 * Math.cos(fourD) + 0.000229 * Math.cos(sixD - fourl) - + 0.000201 * Math.cos(twol - twoF); + inclinationSecPart += 486.26 * Math.cos(twoD - twoF) - 40.13 * Math.cos(twoD) + + 37.51 * Math.cos(twoF) + 25.73 * Math.cos(twol - twoF) + + 19.97 * Math.cos(twoD - lprime - twoF); + longitudeOfPerigeeSecPart += -55609 * Math.sin(twoD - l) - 34711 * Math.sin(twoD - twol) - + 9792 * Math.sin(l) + 9385 * Math.sin(fourD - threel) + + 7505 * Math.sin(fourD - twol) + 5318 * Math.sin(twoD + l) + + 3484 * Math.sin(fourD - fourl) - 3417 * Math.sin(twoD - lprime - l) - + 2530 * Math.sin(sixD - fourl) - 2376 * Math.sin(twoD) - + 2075 * Math.sin(twoD - threel) - 1883 * Math.sin(twol) - + 1736 * Math.sin(sixD - 5.0 * l) + 1626 * Math.sin(lprime) - + 1370 * Math.sin(sixD - threel); + longitudeOfNodeSecPart += -5392 * Math.sin(twoD - twoF) - 540 * Math.sin(lprime) - + 441 * Math.sin(twoD) + 423 * Math.sin(twoF) - + 288 * Math.sin(twol - twoF); + meanLongitudeSecPart += -3332.9 * Math.sin(twoD) + 1197.4 * Math.sin(twoD - l) - + 662.5 * Math.sin(lprime) + 396.3 * Math.sin(l) - + 218.0 * Math.sin(twoD - lprime); - /** - * Gets or sets {@link NearFarScalar} Property specifying the pixel offset of the billboard based on the distance from the camera. - * A billboard's pixel offset will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the billboard's pixel offset remains clamped to the nearest bound. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - pixelOffsetScaleByDistance : createPropertyDescriptor('pixelOffsetScaleByDistance'), + // Add terms from Table 5 + var twoPsi = 2.0 * psi; + var threePsi = 3.0 * psi; + inclinationSecPart += 46.997 * Math.cos(psi) * t - 0.614 * Math.cos(twoD - twoF + psi) * t + + 0.614 * Math.cos(twoD - twoF - psi) * t - 0.0297 * Math.cos(twoPsi) * t2 - + 0.0335 * Math.cos(psi) * t2 + 0.0012 * Math.cos(twoD - twoF + twoPsi) * t2 - + 0.00016 * Math.cos(psi) * t3 + 0.00004 * Math.cos(threePsi) * t3 + + 0.00004 * Math.cos(twoPsi) * t3; + var perigeeAndMean = 2.116 * Math.sin(psi) * t - 0.111 * Math.sin(twoD - twoF - psi) * t - + 0.0015 * Math.sin(psi) * t2; + longitudeOfPerigeeSecPart += perigeeAndMean; + meanLongitudeSecPart += perigeeAndMean; + longitudeOfNodeSecPart += -520.77 * Math.sin(psi) * t + 13.66 * Math.sin(twoD - twoF + psi) * t + + 1.12 * Math.sin(twoD - psi) * t - 1.06 * Math.sin(twoF - psi) * t + + 0.660 * Math.sin(twoPsi) * t2 + 0.371 * Math.sin(psi) * t2 - + 0.035 * Math.sin(twoD - twoF + twoPsi) * t2 - 0.015 * Math.sin(twoD - twoF + psi) * t2 + + 0.0014 * Math.sin(psi) * t3 - 0.0011 * Math.sin(threePsi) * t3 - + 0.0009 * Math.sin(twoPsi) * t3; - /** - * Gets or sets the boolean Property specifying if this billboard's size will be measured in meters. - * @memberof BillboardGraphics.prototype - * @type {Property} - * @default false - */ - sizeInMeters : createPropertyDescriptor('sizeInMeters'), + // Add constants and convert units + semimajorAxis *= MetersPerKilometer; + var inclination = inclinationConstant + inclinationSecPart * RadiansPerArcSecond; + var longitudeOfPerigee = longitudeOfPerigeeConstant + longitudeOfPerigeeSecPart * RadiansPerArcSecond; + var meanLongitude = meanLongitudeConstant + meanLongitudeSecPart * RadiansPerArcSecond; + var longitudeOfNode = longitudeOfNodeConstant + longitudeOfNodeSecPart * RadiansPerArcSecond; - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this billboard will be displayed. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + return elementsToCartesian(semimajorAxis, eccentricity, inclination, longitudeOfPerigee, + longitudeOfNode, meanLongitude, result); + } - /** - * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. - * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. - * @memberof BillboardGraphics.prototype - * @type {Property} - */ - disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') - }); + /** + * Gets a point describing the motion of the Earth. This point uses the Moon point and + * the 1992 mu value (ratio between Moon and Earth masses) in Table 2 of the paper in order + * to determine the position of the Earth relative to the Earth-Moon barycenter. + */ + var moonEarthMassRatio = 0.012300034; // From 1992 mu value in Table 2 + var factor = moonEarthMassRatio / (moonEarthMassRatio + 1.0) * -1; + function computeSimonEarth(date, result) { + result = computeSimonMoon(date, result); + return Cartesian3.multiplyByScalar(result, factor, result); + } + + // Values for the <code>axesTransformation</code> needed for the rotation were found using the STK Components + // GreographicTransformer on the position of the sun center of mass point and the earth J2000 frame. + var axesTransformation = new Matrix3(1.0000000000000002, 5.619723173785822e-16, 4.690511510146299e-19, + -5.154129427414611e-16, 0.9174820620691819, -0.39777715593191376, + -2.23970096136568e-16, 0.39777715593191376, 0.9174820620691819); + var translation = new Cartesian3(); /** - * Duplicates this instance. + * Computes the position of the Sun in the Earth-centered inertial frame * - * @param {BillboardGraphics} [result] The object onto which to store the result. - * @returns {BillboardGraphics} The modified result parameter or a new instance if one was not provided. + * @param {JulianDate} [julianDate] The time at which to compute the Sun's position, if not provided the current system time is used. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} Calculated sun position */ - BillboardGraphics.prototype.clone = function(result) { + Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame= function(julianDate, result){ + if (!defined(julianDate)) { + julianDate = JulianDate.now(); + } + if (!defined(result)) { - return new BillboardGraphics(this); + result = new Cartesian3(); } - result.color = this._color; - result.eyeOffset = this._eyeOffset; - result.heightReference = this._heightReference; - result.horizontalOrigin = this._horizontalOrigin; - result.image = this._image; - result.imageSubRegion = this._imageSubRegion; - result.pixelOffset = this._pixelOffset; - result.scale = this._scale; - result.rotation = this._rotation; - result.alignedAxis = this._alignedAxis; - result.show = this._show; - result.verticalOrigin = this._verticalOrigin; - result.width = this._width; - result.height = this._height; - result.scaleByDistance = this._scaleByDistance; - result.translucencyByDistance = this._translucencyByDistance; - result.pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; - result.sizeInMeters = this._sizeInMeters; - result.distanceDisplayCondition = this._distanceDisplayCondition; - result.disableDepthTestDistance = this._disableDepthTestDistance; + + //first forward transformation + translation = computeSimonEarthMoonBarycenter(julianDate, translation); + result = Cartesian3.negate(translation, result); + + //second forward transformation + computeSimonEarth(julianDate, translation); + + Cartesian3.subtract(result, translation, result); + Matrix3.multiplyByVector(axesTransformation, result, result); + return result; }; /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. + * Computes the position of the Moon in the Earth-centered inertial frame * - * @param {BillboardGraphics} source The object to be merged into this object. + * @param {JulianDate} [julianDate] The time at which to compute the Sun's position, if not provided the current system time is used. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} Calculated moon position */ - BillboardGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame = function(julianDate, result){ + if (!defined(julianDate)) { + julianDate = JulianDate.now(); } - - this.color = defaultValue(this._color, source.color); - this.eyeOffset = defaultValue(this._eyeOffset, source.eyeOffset); - this.heightReference = defaultValue(this._heightReference, source.heightReference); - this.horizontalOrigin = defaultValue(this._horizontalOrigin, source.horizontalOrigin); - this.image = defaultValue(this._image, source.image); - this.imageSubRegion = defaultValue(this._imageSubRegion, source.imageSubRegion); - this.pixelOffset = defaultValue(this._pixelOffset, source.pixelOffset); - this.scale = defaultValue(this._scale, source.scale); - this.rotation = defaultValue(this._rotation, source.rotation); - this.alignedAxis = defaultValue(this._alignedAxis, source.alignedAxis); - this.show = defaultValue(this._show, source.show); - this.verticalOrigin = defaultValue(this._verticalOrigin, source.verticalOrigin); - this.width = defaultValue(this._width, source.width); - this.height = defaultValue(this._height, source.height); - this.scaleByDistance = defaultValue(this._scaleByDistance, source.scaleByDistance); - this.translucencyByDistance = defaultValue(this._translucencyByDistance, source.translucencyByDistance); - this.pixelOffsetScaleByDistance = defaultValue(this._pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); - this.sizeInMeters = defaultValue(this._sizeInMeters, source.sizeInMeters); - this.distanceDisplayCondition = defaultValue(this._distanceDisplayCondition, source.distanceDisplayCondition); - this.disableDepthTestDistance = defaultValue(this._disableDepthTestDistance, source.disableDepthTestDistance); + + result = computeSimonMoon(julianDate, result); + Matrix3.multiplyByVector(axesTransformation, result, result); + + return result; }; - return BillboardGraphics; + return Simon1994PlanetaryPositions; }); -define('Scene/HeightReference',[ - '../Core/freezeObject' +define('Core/SimplePolylineGeometry',[ + './BoundingSphere', + './Cartesian3', + './Color', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PolylinePipeline', + './PrimitiveType' ], function( - freezeObject) { + BoundingSphere, + Cartesian3, + Color, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PolylinePipeline, + PrimitiveType) { 'use strict'; - /** - * Represents the position relative to the terrain. - * - * @exports HeightReference - */ - var HeightReference = { - /** - * The position is absolute. - * @type {Number} - * @constant - */ - NONE : 0, + function interpolateColors(p0, p1, color0, color1, minDistance, array, offset) { + var numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance); + var i; - /** - * The position is clamped to the terrain. - * @type {Number} - * @constant - */ - CLAMP_TO_GROUND : 1, + var r0 = color0.red; + var g0 = color0.green; + var b0 = color0.blue; + var a0 = color0.alpha; - /** - * The position height is the height above the terrain. - * @type {Number} - * @constant - */ - RELATIVE_TO_GROUND : 2 - }; + var r1 = color1.red; + var g1 = color1.green; + var b1 = color1.blue; + var a1 = color1.alpha; - return freezeObject(HeightReference); -}); + if (Color.equals(color0, color1)) { + for (i = 0; i < numPoints; i++) { + array[offset++] = Color.floatToByte(r0); + array[offset++] = Color.floatToByte(g0); + array[offset++] = Color.floatToByte(b0); + array[offset++] = Color.floatToByte(a0); + } + return offset; + } -define('Scene/HorizontalOrigin',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + var redPerVertex = (r1 - r0) / numPoints; + var greenPerVertex = (g1 - g0) / numPoints; + var bluePerVertex = (b1 - b0) / numPoints; + var alphaPerVertex = (a1 - a0) / numPoints; + + var index = offset; + for (i = 0; i < numPoints; i++) { + array[index++] = Color.floatToByte(r0 + i * redPerVertex); + array[index++] = Color.floatToByte(g0 + i * greenPerVertex); + array[index++] = Color.floatToByte(b0 + i * bluePerVertex); + array[index++] = Color.floatToByte(a0 + i * alphaPerVertex); + } + + return index; + } /** - * The horizontal location of an origin relative to an object, e.g., a {@link Billboard} - * or {@link Label}. For example, setting the horizontal origin to <code>LEFT</code> - * or <code>RIGHT</code> will display a billboard to the left or right (in screen space) - * of the anchor position. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> - * </div> + * A description of a polyline modeled as a line strip; the first two positions define a line segment, + * and each additional position defines a line segment from the previous position. * - * @exports HorizontalOrigin + * @alias SimplePolylineGeometry + * @constructor * - * @see Billboard#horizontalOrigin - * @see Label#horizontalOrigin + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of {@link Cartesian3} defining the positions in the polyline as a line strip. + * @param {Color[]} [options.colors] An Array of {@link Color} defining the per vertex or per segment colors. + * @param {Boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. + * @param {Boolean} [options.followSurface=true] A boolean that determines whether positions will be adjusted to the surface of the ellipsoid via a great arc. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.followSurface=true. Determines the number of positions in the buffer. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * + * @exception {DeveloperError} At least two positions are required. + * @exception {DeveloperError} colors has an invalid length. + * + * @see SimplePolylineGeometry#createGeometry + * + * @example + * // A polyline with two connected line segments + * var polyline = new Cesium.SimplePolylineGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * 0.0, 0.0, + * 5.0, 0.0, + * 5.0, 5.0 + * ]) + * }); + * var geometry = Cesium.SimplePolylineGeometry.createGeometry(polyline); */ - var HorizontalOrigin = { - /** - * The origin is at the horizontal center of the object. - * - * @type {Number} - * @constant - */ - CENTER : 0, + function SimplePolylineGeometry(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.positions; + var colors = options.colors; + var colorsPerVertex = defaultValue(options.colorsPerVertex, false); - /** - * The origin is on the left side of the object. - * - * @type {Number} - * @constant - */ - LEFT : 1, + if ((!defined(positions)) || (positions.length < 2)) { + throw new DeveloperError('At least two positions are required.'); + } + if (defined(colors) && ((colorsPerVertex && colors.length < positions.length) || (!colorsPerVertex && colors.length < positions.length - 1))) { + throw new DeveloperError('colors has an invalid length.'); + } + + this._positions = positions; + this._colors = colors; + this._colorsPerVertex = colorsPerVertex; + this._followSurface = defaultValue(options.followSurface, true); + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._workerName = 'createSimplePolylineGeometry'; + + var numComponents = 1 + positions.length * Cartesian3.packedLength; + numComponents += defined(colors) ? 1 + colors.length * Color.packedLength : 1; /** - * The origin is on the right side of the object. - * + * The number of elements used to pack the object into an array. * @type {Number} - * @constant */ - RIGHT : -1 - }; - - return freezeObject(HorizontalOrigin); -}); - -define('Scene/VerticalOrigin',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + this.packedLength = numComponents + Ellipsoid.packedLength + 3; + } /** - * The vertical location of an origin relative to an object, e.g., a {@link Billboard} - * or {@link Label}. For example, setting the vertical origin to <code>TOP</code> - * or <code>BOTTOM</code> will display a billboard above or below (in screen space) - * the anchor position. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> - * </div> + * Stores the provided instance into the provided array. * - * @exports VerticalOrigin + * @param {SimplePolylineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @see Billboard#verticalOrigin - * @see Label#verticalOrigin + * @returns {Number[]} The array that was packed into */ - var VerticalOrigin = { - /** - * The origin is at the vertical center between <code>BASELINE</code> and <code>TOP</code>. - * - * @type {Number} - * @constant - */ - CENTER : 0, + SimplePolylineGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - /** - * The origin is at the bottom of the object. - * - * @type {Number} - * @constant - */ - BOTTOM : 1, + var i; - /** - * If the object contains text, the origin is at the baseline of the text, else the origin is at the bottom of the object. - * - * @type {Number} - * @constant - */ - BASELINE : 2, + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; - /** - * The origin is at the top of the object. - * - * @type {Number} - * @constant - */ - TOP : -1 + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); + } + + var colors = value._colors; + length = defined(colors) ? colors.length : 0.0; + array[startingIndex++] = length; + + for (i = 0; i < length; ++i, startingIndex += Color.packedLength) { + Color.pack(colors[i], array, startingIndex); + } + + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; + + array[startingIndex++] = value._colorsPerVertex ? 1.0 : 0.0; + array[startingIndex++] = value._followSurface ? 1.0 : 0.0; + array[startingIndex] = value._granularity; + + return array; }; - return freezeObject(VerticalOrigin); -}); + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {SimplePolylineGeometry} [result] The object into which to store the result. + * @returns {SimplePolylineGeometry} The modified result parameter or a new SimplePolylineGeometry instance if one was not provided. + */ + SimplePolylineGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); -define('DataSources/BoundingSphereState',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + var i; + + var length = array[startingIndex++]; + var positions = new Array(length); + + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); + } + + length = array[startingIndex++]; + var colors = length > 0 ? new Array(length) : undefined; + + for (i = 0; i < length; ++i, startingIndex += Color.packedLength) { + colors[i] = Color.unpack(array, startingIndex); + } + + var ellipsoid = Ellipsoid.unpack(array, startingIndex); + startingIndex += Ellipsoid.packedLength; + + var colorsPerVertex = array[startingIndex++] === 1.0; + var followSurface = array[startingIndex++] === 1.0; + var granularity = array[startingIndex]; + + if (!defined(result)) { + return new SimplePolylineGeometry({ + positions : positions, + colors : colors, + ellipsoid : ellipsoid, + colorsPerVertex : colorsPerVertex, + followSurface : followSurface, + granularity : granularity + }); + } + + result._positions = positions; + result._colors = colors; + result._ellipsoid = ellipsoid; + result._colorsPerVertex = colorsPerVertex; + result._followSurface = followSurface; + result._granularity = granularity; + + return result; + }; + + var scratchArray1 = new Array(2); + var scratchArray2 = new Array(2); + var generateArcOptionsScratch = { + positions : scratchArray1, + height: scratchArray2, + ellipsoid: undefined, + minDistance : undefined + }; /** - * The state of a BoundingSphere computation being performed by a {@link Visualizer}. - * @exports BoundingSphereState - * @private + * Computes the geometric representation of a simple polyline, including its vertices, indices, and a bounding sphere. + * + * @param {SimplePolylineGeometry} simplePolylineGeometry A description of the polyline. + * @returns {Geometry} The computed vertices and indices. */ - var BoundingSphereState = { - /** - * The BoundingSphere has been computed. - * @type BoundingSphereState - * @constant - */ - DONE : 0, - /** - * The BoundingSphere is still being computed. - * @type BoundingSphereState - * @constant - */ - PENDING : 1, - /** - * The BoundingSphere does not exist. - * @type BoundingSphereState - * @constant - */ - FAILED : 2 + SimplePolylineGeometry.createGeometry = function(simplePolylineGeometry) { + var positions = simplePolylineGeometry._positions; + var colors = simplePolylineGeometry._colors; + var colorsPerVertex = simplePolylineGeometry._colorsPerVertex; + var followSurface = simplePolylineGeometry._followSurface; + var granularity = simplePolylineGeometry._granularity; + var ellipsoid = simplePolylineGeometry._ellipsoid; + + var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); + var perSegmentColors = defined(colors) && !colorsPerVertex; + + var i; + var length = positions.length; + + var positionValues; + var numberOfPositions; + var colorValues; + var color; + var offset = 0; + + if (followSurface) { + var heights = PolylinePipeline.extractHeights(positions, ellipsoid); + var generateArcOptions = generateArcOptionsScratch; + generateArcOptions.minDistance = minDistance; + generateArcOptions.ellipsoid = ellipsoid; + + if (perSegmentColors) { + var positionCount = 0; + for (i = 0; i < length - 1; i++) { + positionCount += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance) + 1; + } + + positionValues = new Float64Array(positionCount * 3); + colorValues = new Uint8Array(positionCount * 4); + + generateArcOptions.positions = scratchArray1; + generateArcOptions.height= scratchArray2; + + var ci = 0; + for (i = 0; i < length - 1; ++i) { + scratchArray1[0] = positions[i]; + scratchArray1[1] = positions[i + 1]; + + scratchArray2[0] = heights[i]; + scratchArray2[1] = heights[i + 1]; + + var pos = PolylinePipeline.generateArc(generateArcOptions); + + if (defined(colors)) { + var segLen = pos.length / 3; + color = colors[i]; + for(var k = 0; k < segLen; ++k) { + colorValues[ci++] = Color.floatToByte(color.red); + colorValues[ci++] = Color.floatToByte(color.green); + colorValues[ci++] = Color.floatToByte(color.blue); + colorValues[ci++] = Color.floatToByte(color.alpha); + } + } + + positionValues.set(pos, offset); + offset += pos.length; + } + } else { + generateArcOptions.positions = positions; + generateArcOptions.height= heights; + positionValues = new Float64Array(PolylinePipeline.generateArc(generateArcOptions)); + + if (defined(colors)) { + colorValues = new Uint8Array(positionValues.length / 3 * 4); + + for (i = 0; i < length - 1; ++i) { + var p0 = positions[i]; + var p1 = positions[i + 1]; + var c0 = colors[i]; + var c1 = colors[i + 1]; + offset = interpolateColors(p0, p1, c0, c1, minDistance, colorValues, offset); + } + + var lastColor = colors[length - 1]; + colorValues[offset++] = Color.floatToByte(lastColor.red); + colorValues[offset++] = Color.floatToByte(lastColor.green); + colorValues[offset++] = Color.floatToByte(lastColor.blue); + colorValues[offset++] = Color.floatToByte(lastColor.alpha); + } + } + } else { + numberOfPositions = perSegmentColors ? length * 2 - 2 : length; + positionValues = new Float64Array(numberOfPositions * 3); + colorValues = defined(colors) ? new Uint8Array(numberOfPositions * 4) : undefined; + + var positionIndex = 0; + var colorIndex = 0; + + for (i = 0; i < length; ++i) { + var p = positions[i]; + + if (perSegmentColors && i > 0) { + Cartesian3.pack(p, positionValues, positionIndex); + positionIndex += 3; + + color = colors[i - 1]; + colorValues[colorIndex++] = Color.floatToByte(color.red); + colorValues[colorIndex++] = Color.floatToByte(color.green); + colorValues[colorIndex++] = Color.floatToByte(color.blue); + colorValues[colorIndex++] = Color.floatToByte(color.alpha); + } + + if (perSegmentColors && i === length - 1) { + break; + } + + Cartesian3.pack(p, positionValues, positionIndex); + positionIndex += 3; + + if (defined(colors)) { + color = colors[i]; + colorValues[colorIndex++] = Color.floatToByte(color.red); + colorValues[colorIndex++] = Color.floatToByte(color.green); + colorValues[colorIndex++] = Color.floatToByte(color.blue); + colorValues[colorIndex++] = Color.floatToByte(color.alpha); + } + } + } + + var attributes = new GeometryAttributes(); + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positionValues + }); + + if (defined(colors)) { + attributes.color = new GeometryAttribute({ + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + componentsPerAttribute : 4, + values : colorValues, + normalize : true + }); + } + + numberOfPositions = positionValues.length / 3; + var numberOfIndices = (numberOfPositions - 1) * 2; + var indices = IndexDatatype.createTypedArray(numberOfPositions, numberOfIndices); + + var index = 0; + for (i = 0; i < numberOfPositions - 1; ++i) { + indices[index++] = i; + indices[index++] = i + 1; + } + + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : BoundingSphere.fromPoints(positions) + }); }; - return freezeObject(BoundingSphereState); + return SimplePolylineGeometry; }); -define('DataSources/Property',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError' +define('Core/SphereGeometry',[ + './Cartesian3', + './Check', + './defaultValue', + './defined', + './EllipsoidGeometry', + './VertexFormat' ], function( + Cartesian3, + Check, defaultValue, defined, - defineProperties, - DeveloperError) { + EllipsoidGeometry, + VertexFormat) { 'use strict'; /** - * The interface for all properties, which represent a value that can optionally vary over time. - * This type defines an interface and cannot be instantiated directly. + * A description of a sphere centered at the origin. * - * @alias Property + * @alias SphereGeometry * @constructor * - * @see CompositeProperty - * @see ConstantProperty - * @see SampledProperty - * @see TimeIntervalCollectionProperty - * @see MaterialProperty - * @see PositionProperty - * @see ReferenceProperty + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.radius=1.0] The radius of the sphere. + * @param {Number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. + * @param {Number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * + * @exception {DeveloperError} options.slicePartitions cannot be less than three. + * @exception {DeveloperError} options.stackPartitions cannot be less than three. + * + * @see SphereGeometry#createGeometry + * + * @example + * var sphere = new Cesium.SphereGeometry({ + * radius : 100.0, + * vertexFormat : Cesium.VertexFormat.POSITION_ONLY + * }); + * var geometry = Cesium.SphereGeometry.createGeometry(sphere); */ - function Property() { - DeveloperError.throwInstantiationError(); - } + function SphereGeometry(options) { + var radius = defaultValue(options.radius, 1.0); + var radii = new Cartesian3(radius, radius, radius); + var ellipsoidOptions = { + radii: radii, + stackPartitions: options.stackPartitions, + slicePartitions: options.slicePartitions, + vertexFormat: options.vertexFormat + }; - defineProperties(Property.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof Property.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof Property.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : DeveloperError.throwInstantiationError - } - }); + this._ellipsoidGeometry = new EllipsoidGeometry(ellipsoidOptions); + this._workerName = 'createSphereGeometry'; + } /** - * Gets the value of the property at the provided time. - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * The number of elements used to pack the object into an array. + * @type {Number} */ - Property.prototype.getValue = DeveloperError.throwInstantiationError; + SphereGeometry.packedLength = EllipsoidGeometry.packedLength; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * @function + * Stores the provided instance into the provided array. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - Property.prototype.equals = DeveloperError.throwInstantiationError; - - /** - * @private + * @param {SphereGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - Property.equals = function(left, right) { - return left === right || (defined(left) && left.equals(right)); + SphereGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + + return EllipsoidGeometry.pack(value._ellipsoidGeometry, array, startingIndex); }; - /** - * @private - */ - Property.arrayEquals = function(left, right) { - if (left === right) { - return true; - } - if ((!defined(left) || !defined(right)) || (left.length !== right.length)) { - return false; - } - var length = left.length; - for (var i = 0; i < length; i++) { - if (!Property.equals(left[i], right[i])) { - return false; - } - } - return true; + var scratchEllipsoidGeometry = new EllipsoidGeometry(); + var scratchOptions = { + radius : undefined, + radii : new Cartesian3(), + vertexFormat : new VertexFormat(), + stackPartitions : undefined, + slicePartitions : undefined }; /** - * @private + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {SphereGeometry} [result] The object into which to store the result. + * @returns {SphereGeometry} The modified result parameter or a new SphereGeometry instance if one was not provided. */ - Property.isConstant = function(property) { - return !defined(property) || property.isConstant; - }; + SphereGeometry.unpack = function(array, startingIndex, result) { + var ellipsoidGeometry = EllipsoidGeometry.unpack(array, startingIndex, scratchEllipsoidGeometry); + scratchOptions.vertexFormat = VertexFormat.clone(ellipsoidGeometry._vertexFormat, scratchOptions.vertexFormat); + scratchOptions.stackPartitions = ellipsoidGeometry._stackPartitions; + scratchOptions.slicePartitions = ellipsoidGeometry._slicePartitions; - /** - * @private - */ - Property.getValueOrUndefined = function(property, time, result) { - return defined(property) ? property.getValue(time, result) : undefined; - }; + if (!defined(result)) { + scratchOptions.radius = ellipsoidGeometry._radii.x; + return new SphereGeometry(scratchOptions); + } - /** - * @private - */ - Property.getValueOrDefault = function(property, time, valueDefault, result) { - return defined(property) ? defaultValue(property.getValue(time, result), valueDefault) : valueDefault; + Cartesian3.clone(ellipsoidGeometry._radii, scratchOptions.radii); + result._ellipsoidGeometry = new EllipsoidGeometry(scratchOptions); + return result; }; /** - * @private + * Computes the geometric representation of a sphere, including its vertices, indices, and a bounding sphere. + * + * @param {SphereGeometry} sphereGeometry A description of the sphere. + * @returns {Geometry} The computed vertices and indices. */ - Property.getValueOrClonedDefault = function(property, time, valueDefault, result) { - var value; - if (defined(property)) { - value = property.getValue(time, result); - } - if (!defined(value)) { - value = valueDefault.clone(value); - } - return value; + SphereGeometry.createGeometry = function(sphereGeometry) { + return EllipsoidGeometry.createGeometry(sphereGeometry._ellipsoidGeometry); }; - return Property; + return SphereGeometry; }); -define('DataSources/BillboardVisualizer',[ - '../Core/AssociativeArray', - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Color', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/NearFarScalar', - '../Scene/HeightReference', - '../Scene/HorizontalOrigin', - '../Scene/VerticalOrigin', - './BoundingSphereState', - './Property' +define('Core/SphereOutlineGeometry',[ + './Cartesian3', + './Check', + './defaultValue', + './defined', + './EllipsoidOutlineGeometry' ], function( - AssociativeArray, - BoundingRectangle, - Cartesian2, Cartesian3, - Color, + Check, + defaultValue, defined, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - NearFarScalar, - HeightReference, - HorizontalOrigin, - VerticalOrigin, - BoundingSphereState, - Property) { + EllipsoidOutlineGeometry) { 'use strict'; - var defaultColor = Color.WHITE; - var defaultEyeOffset = Cartesian3.ZERO; - var defaultHeightReference = HeightReference.NONE; - var defaultPixelOffset = Cartesian2.ZERO; - var defaultScale = 1.0; - var defaultRotation = 0.0; - var defaultAlignedAxis = Cartesian3.ZERO; - var defaultHorizontalOrigin = HorizontalOrigin.CENTER; - var defaultVerticalOrigin = VerticalOrigin.CENTER; - var defaultSizeInMeters = false; - var defaultDisableDepthTestDistance = 0.0; - - var position = new Cartesian3(); - var color = new Color(); - var eyeOffset = new Cartesian3(); - var pixelOffset = new Cartesian2(); - var scaleByDistance = new NearFarScalar(); - var translucencyByDistance = new NearFarScalar(); - var pixelOffsetScaleByDistance = new NearFarScalar(); - var boundingRectangle = new BoundingRectangle(); - var distanceDisplayCondition = new DistanceDisplayCondition(); + /** + * A description of the outline of a sphere. + * + * @alias SphereOutlineGeometry + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.radius=1.0] The radius of the sphere. + * @param {Number} [options.stackPartitions=10] The count of stacks for the sphere (1 greater than the number of parallel lines). + * @param {Number} [options.slicePartitions=8] The count of slices for the sphere (Equal to the number of radial lines). + * @param {Number} [options.subdivisions=200] The number of points per line, determining the granularity of the curvature . + * + * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one. + * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero. + * @exception {DeveloperError} options.subdivisions must be greater than or equal to zero. + * + * @example + * var sphere = new Cesium.SphereOutlineGeometry({ + * radius : 100.0, + * stackPartitions : 6, + * slicePartitions: 5 + * }); + * var geometry = Cesium.SphereOutlineGeometry.createGeometry(sphere); + */ + function SphereOutlineGeometry(options) { + var radius = defaultValue(options.radius, 1.0); + var radii = new Cartesian3(radius, radius, radius); + var ellipsoidOptions = { + radii: radii, + stackPartitions: options.stackPartitions, + slicePartitions: options.slicePartitions, + subdivisions: options.subdivisions + }; - function EntityData(entity) { - this.entity = entity; - this.billboard = undefined; - this.textureValue = undefined; + this._ellipsoidGeometry = new EllipsoidOutlineGeometry(ellipsoidOptions); + this._workerName = 'createSphereOutlineGeometry'; } /** - * A {@link Visualizer} which maps {@link Entity#billboard} to a {@link Billboard}. - * @alias BillboardVisualizer - * @constructor + * The number of elements used to pack the object into an array. + * @type {Number} + */ + SphereOutlineGeometry.packedLength = EllipsoidOutlineGeometry.packedLength; + + /** + * Stores the provided instance into the provided array. * - * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities. - * @param {EntityCollection} entityCollection The entityCollection to visualize. + * @param {SphereOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into */ - function BillboardVisualizer(entityCluster, entityCollection) { - if (!defined(entityCluster)) { - throw new DeveloperError('entityCluster is required.'); - } - if (!defined(entityCollection)) { - throw new DeveloperError('entityCollection is required.'); - } + SphereOutlineGeometry.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); - entityCollection.collectionChanged.addEventListener(BillboardVisualizer.prototype._onCollectionChanged, this); + return EllipsoidOutlineGeometry.pack(value._ellipsoidGeometry, array, startingIndex); + }; - this._cluster = entityCluster; - this._entityCollection = entityCollection; - this._items = new AssociativeArray(); - this._onCollectionChanged(entityCollection, entityCollection.values, [], []); - } + var scratchEllipsoidGeometry = new EllipsoidOutlineGeometry(); + var scratchOptions = { + radius : undefined, + radii : new Cartesian3(), + stackPartitions : undefined, + slicePartitions : undefined, + subdivisions : undefined + }; /** - * Updates the primitives created by this visualizer to match their - * Entity counterpart at the given time. + * Retrieves an instance from a packed array. * - * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {SphereOutlineGeometry} [result] The object into which to store the result. + * @returns {SphereOutlineGeometry} The modified result parameter or a new SphereOutlineGeometry instance if one was not provided. */ - BillboardVisualizer.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + SphereOutlineGeometry.unpack = function(array, startingIndex, result) { + var ellipsoidGeometry = EllipsoidOutlineGeometry.unpack(array, startingIndex, scratchEllipsoidGeometry); + scratchOptions.stackPartitions = ellipsoidGeometry._stackPartitions; + scratchOptions.slicePartitions = ellipsoidGeometry._slicePartitions; + scratchOptions.subdivisions = ellipsoidGeometry._subdivisions; + + if (!defined(result)) { + scratchOptions.radius = ellipsoidGeometry._radii.x; + return new SphereOutlineGeometry(scratchOptions); } - - var items = this._items.values; - var cluster = this._cluster; - for (var i = 0, len = items.length; i < len; i++) { - var item = items[i]; - var entity = item.entity; - var billboardGraphics = entity._billboard; - var textureValue; - var billboard = item.billboard; - var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(billboardGraphics._show, time, true); + Cartesian3.clone(ellipsoidGeometry._radii, scratchOptions.radii); + result._ellipsoidGeometry = new EllipsoidOutlineGeometry(scratchOptions); + return result; + }; - if (show) { - position = Property.getValueOrUndefined(entity._position, time, position); - textureValue = Property.getValueOrUndefined(billboardGraphics._image, time); - show = defined(position) && defined(textureValue); - } + /** + * Computes the geometric representation of an outline of a sphere, including its vertices, indices, and a bounding sphere. + * + * @param {SphereOutlineGeometry} sphereGeometry A description of the sphere outline. + * @returns {Geometry} The computed vertices and indices. + */ + SphereOutlineGeometry.createGeometry = function(sphereGeometry) { + return EllipsoidOutlineGeometry.createGeometry(sphereGeometry._ellipsoidGeometry); + }; - if (!show) { - //don't bother creating or updating anything else - returnPrimitive(item, entity, cluster); - continue; - } + return SphereOutlineGeometry; +}); - if (!Property.isConstant(entity._position)) { - cluster._clusterDirty = true; - } +define('Core/Spherical',[ + './Check', + './defaultValue', + './defined' + ], function( + Check, + defaultValue, + defined) { + 'use strict'; - if (!defined(billboard)) { - billboard = cluster.getBillboard(entity); - billboard.id = entity; - billboard.image = undefined; - item.billboard = billboard; - } + /** + * A set of curvilinear 3-dimensional coordinates. + * + * @alias Spherical + * @constructor + * + * @param {Number} [clock=0.0] The angular coordinate lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. + * @param {Number} [cone=0.0] The angular coordinate measured from the positive z-axis and toward the negative z-axis. + * @param {Number} [magnitude=1.0] The linear coordinate measured from the origin. + */ + function Spherical(clock, cone, magnitude) { + this.clock = defaultValue(clock, 0.0); + this.cone = defaultValue(cone, 0.0); + this.magnitude = defaultValue(magnitude, 1.0); + } - billboard.show = show; - if (!defined(billboard.image) || item.textureValue !== textureValue) { - billboard.image = textureValue; - item.textureValue = textureValue; - } - billboard.position = position; - billboard.color = Property.getValueOrDefault(billboardGraphics._color, time, defaultColor, color); - billboard.eyeOffset = Property.getValueOrDefault(billboardGraphics._eyeOffset, time, defaultEyeOffset, eyeOffset); - billboard.heightReference = Property.getValueOrDefault(billboardGraphics._heightReference, time, defaultHeightReference); - billboard.pixelOffset = Property.getValueOrDefault(billboardGraphics._pixelOffset, time, defaultPixelOffset, pixelOffset); - billboard.scale = Property.getValueOrDefault(billboardGraphics._scale, time, defaultScale); - billboard.rotation = Property.getValueOrDefault(billboardGraphics._rotation, time, defaultRotation); - billboard.alignedAxis = Property.getValueOrDefault(billboardGraphics._alignedAxis, time, defaultAlignedAxis); - billboard.horizontalOrigin = Property.getValueOrDefault(billboardGraphics._horizontalOrigin, time, defaultHorizontalOrigin); - billboard.verticalOrigin = Property.getValueOrDefault(billboardGraphics._verticalOrigin, time, defaultVerticalOrigin); - billboard.width = Property.getValueOrUndefined(billboardGraphics._width, time); - billboard.height = Property.getValueOrUndefined(billboardGraphics._height, time); - billboard.scaleByDistance = Property.getValueOrUndefined(billboardGraphics._scaleByDistance, time, scaleByDistance); - billboard.translucencyByDistance = Property.getValueOrUndefined(billboardGraphics._translucencyByDistance, time, translucencyByDistance); - billboard.pixelOffsetScaleByDistance = Property.getValueOrUndefined(billboardGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance); - billboard.sizeInMeters = Property.getValueOrDefault(billboardGraphics._sizeInMeters, time, defaultSizeInMeters); - billboard.distanceDisplayCondition = Property.getValueOrUndefined(billboardGraphics._distanceDisplayCondition, time, distanceDisplayCondition); - billboard.disableDepthTestDistance = Property.getValueOrDefault(billboardGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); + /** + * Converts the provided Cartesian3 into Spherical coordinates. + * + * @param {Cartesian3} cartesian3 The Cartesian3 to be converted to Spherical. + * @param {Spherical} [result] The object in which the result will be stored, if undefined a new instance will be created. + * @returns {Spherical} The modified result parameter, or a new instance if one was not provided. + */ + Spherical.fromCartesian3 = function(cartesian3, result) { + Check.typeOf.object('cartesian3', cartesian3); + + var x = cartesian3.x; + var y = cartesian3.y; + var z = cartesian3.z; + var radialSquared = x * x + y * y; - var subRegion = Property.getValueOrUndefined(billboardGraphics._imageSubRegion, time, boundingRectangle); - if (defined(subRegion)) { - billboard.setImageSubRegion(billboard._imageId, subRegion); - } + if (!defined(result)) { + result = new Spherical(); } - return true; + + result.clock = Math.atan2(y, x); + result.cone = Math.atan2(Math.sqrt(radialSquared), z); + result.magnitude = Math.sqrt(radialSquared + z * z); + return result; }; /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. + * Creates a duplicate of a Spherical. * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private + * @param {Spherical} spherical The spherical to clone. + * @param {Spherical} [result] The object to store the result into, if undefined a new instance will be created. + * @returns {Spherical} The modified result parameter or a new instance if result was undefined. (Returns undefined if spherical is undefined) */ - BillboardVisualizer.prototype.getBoundingSphere = function(entity, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); + Spherical.clone = function(spherical, result) { + if (!defined(spherical)) { + return undefined; } + if (!defined(result)) { - throw new DeveloperError('result is required.'); - } - - var item = this._items.get(entity.id); - if (!defined(item) || !defined(item.billboard)) { - return BoundingSphereState.FAILED; + return new Spherical(spherical.clock, spherical.cone, spherical.magnitude); } - var billboard = item.billboard; - if (billboard.heightReference === HeightReference.NONE) { - result.center = Cartesian3.clone(billboard.position, result.center); - } else { - if (!defined(billboard._clampedPosition)) { - return BoundingSphereState.PENDING; - } - result.center = Cartesian3.clone(billboard._clampedPosition, result.center); - } - result.radius = 0; - return BoundingSphereState.DONE; + result.clock = spherical.clock; + result.cone = spherical.cone; + result.magnitude = spherical.magnitude; + return result; }; /** - * Returns true if this object was destroyed; otherwise, false. + * Computes the normalized version of the provided spherical. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @param {Spherical} spherical The spherical to be normalized. + * @param {Spherical} [result] The object to store the result into, if undefined a new instance will be created. + * @returns {Spherical} The modified result parameter or a new instance if result was undefined. */ - BillboardVisualizer.prototype.isDestroyed = function() { - return false; + Spherical.normalize = function(spherical, result) { + Check.typeOf.object('spherical', spherical); + + if (!defined(result)) { + return new Spherical(spherical.clock, spherical.cone, 1.0); + } + + result.clock = spherical.clock; + result.cone = spherical.cone; + result.magnitude = 1.0; + return result; }; /** - * Removes and destroys all primitives created by this instance. + * Returns true if the first spherical is equal to the second spherical, false otherwise. + * + * @param {Spherical} left The first Spherical to be compared. + * @param {Spherical} right The second Spherical to be compared. + * @returns {Boolean} true if the first spherical is equal to the second spherical, false otherwise. */ - BillboardVisualizer.prototype.destroy = function() { - this._entityCollection.collectionChanged.removeEventListener(BillboardVisualizer.prototype._onCollectionChanged, this); - var entities = this._entityCollection.values; - for (var i = 0; i < entities.length; i++) { - this._cluster.removeBillboard(entities[i]); - } - return destroyObject(this); + Spherical.equals = function(left, right) { + return (left === right) || + ((defined(left)) && + (defined(right)) && + (left.clock === right.clock) && + (left.cone === right.cone) && + (left.magnitude === right.magnitude)); }; - BillboardVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { - var i; - var entity; - var items = this._items; - var cluster = this._cluster; + /** + * Returns true if the first spherical is within the provided epsilon of the second spherical, false otherwise. + * + * @param {Spherical} left The first Spherical to be compared. + * @param {Spherical} right The second Spherical to be compared. + * @param {Number} [epsilon=0.0] The epsilon to compare against. + * @returns {Boolean} true if the first spherical is within the provided epsilon of the second spherical, false otherwise. + */ + Spherical.equalsEpsilon = function(left, right, epsilon) { + epsilon = defaultValue(epsilon, 0.0); + return (left === right) || + ((defined(left)) && + (defined(right)) && + (Math.abs(left.clock - right.clock) <= epsilon) && + (Math.abs(left.cone - right.cone) <= epsilon) && + (Math.abs(left.magnitude - right.magnitude) <= epsilon)); + }; - for (i = added.length - 1; i > -1; i--) { - entity = added[i]; - if (defined(entity._billboard) && defined(entity._position)) { - items.set(entity.id, new EntityData(entity)); - } - } + /** + * Returns true if this spherical is equal to the provided spherical, false otherwise. + * + * @param {Spherical} other The Spherical to be compared. + * @returns {Boolean} true if this spherical is equal to the provided spherical, false otherwise. + */ + Spherical.prototype.equals = function(other) { + return Spherical.equals(this, other); + }; - for (i = changed.length - 1; i > -1; i--) { - entity = changed[i]; - if (defined(entity._billboard) && defined(entity._position)) { - if (!items.contains(entity.id)) { - items.set(entity.id, new EntityData(entity)); - } - } else { - returnPrimitive(items.get(entity.id), entity, cluster); - items.remove(entity.id); - } - } + /** + * Creates a duplicate of this Spherical. + * + * @param {Spherical} [result] The object to store the result into, if undefined a new instance will be created. + * @returns {Spherical} The modified result parameter or a new instance if result was undefined. + */ + Spherical.prototype.clone = function(result) { + return Spherical.clone(this, result); + }; - for (i = removed.length - 1; i > -1; i--) { - entity = removed[i]; - returnPrimitive(items.get(entity.id), entity, cluster); - items.remove(entity.id); - } + /** + * Returns true if this spherical is within the provided epsilon of the provided spherical, false otherwise. + * + * @param {Spherical} other The Spherical to be compared. + * @param {Number} epsilon The epsilon to compare against. + * @returns {Boolean} true if this spherical is within the provided epsilon of the provided spherical, false otherwise. + */ + Spherical.prototype.equalsEpsilon = function(other, epsilon) { + return Spherical.equalsEpsilon(this, other, epsilon); }; - function returnPrimitive(item, entity, cluster) { - if (defined(item)) { - item.billboard = undefined; - cluster.removeBillboard(entity); - } - } + /** + * Returns a string representing this instance in the format (clock, cone, magnitude). + * + * @returns {String} A string representing this instance. + */ + Spherical.prototype.toString = function() { + return '(' + this.clock + ', ' + this.cone + ', ' + this.magnitude + ')'; + }; - return BillboardVisualizer; + return Spherical; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/AllMaterialAppearanceFS',[],function() { - 'use strict'; - return "varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -varying vec3 v_tangentEC;\n\ -varying vec3 v_bitangentEC;\n\ -varying vec2 v_st;\n\ -void main()\n\ -{\n\ -vec3 positionToEyeEC = -v_positionEC;\n\ -mat3 tangentToEyeMatrix = czm_tangentToEyeSpaceMatrix(v_normalEC, v_tangentEC, v_bitangentEC);\n\ -vec3 normalEC = normalize(v_normalEC);\n\ -#ifdef FACE_FORWARD\n\ -normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ -#endif\n\ -czm_materialInput materialInput;\n\ -materialInput.normalEC = normalEC;\n\ -materialInput.tangentToEyeMatrix = tangentToEyeMatrix;\n\ -materialInput.positionToEyeEC = positionToEyeEC;\n\ -materialInput.st = v_st;\n\ -czm_material material = czm_getMaterial(materialInput);\n\ -#ifdef FLAT\n\ -gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ -#else\n\ -gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ -#endif\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/AllMaterialAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 normal;\n\ -attribute vec3 tangent;\n\ -attribute vec3 bitangent;\n\ -attribute vec2 st;\n\ -attribute float batchId;\n\ -varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -varying vec3 v_tangentEC;\n\ -varying vec3 v_bitangentEC;\n\ -varying vec2 v_st;\n\ -void main()\n\ -{\n\ -vec4 p = czm_computePosition();\n\ -v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ -v_normalEC = czm_normal * normal;\n\ -v_tangentEC = czm_normal * tangent;\n\ -v_bitangentEC = czm_normal * bitangent;\n\ -v_st = st;\n\ -gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/BasicMaterialAppearanceFS',[],function() { - 'use strict'; - return "varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -void main()\n\ -{\n\ -vec3 positionToEyeEC = -v_positionEC;\n\ -vec3 normalEC = normalize(v_normalEC);\n\ -#ifdef FACE_FORWARD\n\ -normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ -#endif\n\ -czm_materialInput materialInput;\n\ -materialInput.normalEC = normalEC;\n\ -materialInput.positionToEyeEC = positionToEyeEC;\n\ -czm_material material = czm_getMaterial(materialInput);\n\ -#ifdef FLAT\n\ -gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ -#else\n\ -gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ -#endif\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/BasicMaterialAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 normal;\n\ -attribute float batchId;\n\ -varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -void main()\n\ -{\n\ -vec4 p = czm_computePosition();\n\ -v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ -v_normalEC = czm_normal * normal;\n\ -gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/TexturedMaterialAppearanceFS',[],function() { - 'use strict'; - return "varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -varying vec2 v_st;\n\ -void main()\n\ -{\n\ -vec3 positionToEyeEC = -v_positionEC;\n\ -vec3 normalEC = normalize(v_normalEC);;\n\ -#ifdef FACE_FORWARD\n\ -normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ -#endif\n\ -czm_materialInput materialInput;\n\ -materialInput.normalEC = normalEC;\n\ -materialInput.positionToEyeEC = positionToEyeEC;\n\ -materialInput.st = v_st;\n\ -czm_material material = czm_getMaterial(materialInput);\n\ -#ifdef FLAT\n\ -gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ -#else\n\ -gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ -#endif\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/TexturedMaterialAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 normal;\n\ -attribute vec2 st;\n\ -attribute float batchId;\n\ -varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -varying vec2 v_st;\n\ -void main()\n\ -{\n\ -vec4 p = czm_computePosition();\n\ -v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ -v_normalEC = czm_normal * normal;\n\ -v_st = st;\n\ -gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ -}\n\ -"; -}); -define('Scene/BlendEquation',[ - '../Core/freezeObject', - '../Core/WebGLConstants' +define('Core/subdivideArray',[ + './defined', + './DeveloperError' ], function( - freezeObject, - WebGLConstants) { + defined, + DeveloperError) { 'use strict'; /** - * Determines how two pixels' values are combined. + * Subdivides an array into a number of smaller, equal sized arrays. * - * @exports BlendEquation + * @exports subdivideArray + * + * @param {Array} array The array to divide. + * @param {Number} numberOfArrays The number of arrays to divide the provided array into. + * + * @exception {DeveloperError} numberOfArrays must be greater than 0. */ - var BlendEquation = { - /** - * Pixel values are added componentwise. This is used in additive blending for translucency. - * - * @type {Number} - * @constant - */ - ADD : WebGLConstants.FUNC_ADD, - - /** - * Pixel values are subtracted componentwise (source - destination). This is used in alpha blending for translucency. - * - * @type {Number} - * @constant - */ - SUBTRACT : WebGLConstants.FUNC_SUBTRACT, - - /** - * Pixel values are subtracted componentwise (destination - source). - * - * @type {Number} - * @constant - */ - REVERSE_SUBTRACT : WebGLConstants.FUNC_REVERSE_SUBTRACT, - - /** - * Pixel values are given to the minimum function (min(source, destination)). - * - * This equation operates on each pixel color component. - * - * @type {Number} - * @constant - */ - MIN : WebGLConstants.MIN, + function subdivideArray(array, numberOfArrays) { + if (!defined(array)) { + throw new DeveloperError('array is required.'); + } - /** - * Pixel values are given to the maximum function (max(source, destination)). - * - * This equation operates on each pixel color component. - * - * @type {Number} - * @constant - */ - MAX : WebGLConstants.MAX - }; + if (!defined(numberOfArrays) || numberOfArrays < 1) { + throw new DeveloperError('numberOfArrays must be greater than 0.'); + } + + var result = []; + var len = array.length; + var i = 0; + while (i < len) { + var size = Math.ceil((len - i) / numberOfArrays--); + result.push(array.slice(i, i + size)); + i += size; + } + return result; + } - return freezeObject(BlendEquation); + return subdivideArray; }); -define('Scene/BlendFunction',[ - '../Core/freezeObject', - '../Core/WebGLConstants' +define('Core/TerrainData',[ + './defineProperties', + './DeveloperError' ], function( - freezeObject, - WebGLConstants) { + defineProperties, + DeveloperError) { 'use strict'; /** - * Determines how blending factors are computed. + * Terrain data for a single tile. This type describes an + * interface and is not intended to be instantiated directly. * - * @exports BlendFunction + * @alias TerrainData + * @constructor + * + * @see HeightmapTerrainData + * @see QuantizedMeshTerrainData */ - var BlendFunction = { - /** - * The blend factor is zero. - * - * @type {Number} - * @constant - */ - ZERO : WebGLConstants.ZERO, - - /** - * The blend factor is one. - * - * @type {Number} - * @constant - */ - ONE : WebGLConstants.ONE, - - /** - * The blend factor is the source color. - * - * @type {Number} - * @constant - */ - SOURCE_COLOR : WebGLConstants.SRC_COLOR, - - /** - * The blend factor is one minus the source color. - * - * @type {Number} - * @constant - */ - ONE_MINUS_SOURCE_COLOR : WebGLConstants.ONE_MINUS_SRC_COLOR, - - /** - * The blend factor is the destination color. - * - * @type {Number} - * @constant - */ - DESTINATION_COLOR : WebGLConstants.DST_COLOR, - - /** - * The blend factor is one minus the destination color. - * - * @type {Number} - * @constant - */ - ONE_MINUS_DESTINATION_COLOR : WebGLConstants.ONE_MINUS_DST_COLOR, - - /** - * The blend factor is the source alpha. - * - * @type {Number} - * @constant - */ - SOURCE_ALPHA : WebGLConstants.SRC_ALPHA, - - /** - * The blend factor is one minus the source alpha. - * - * @type {Number} - * @constant - */ - ONE_MINUS_SOURCE_ALPHA : WebGLConstants.ONE_MINUS_SRC_ALPHA, + function TerrainData() { + DeveloperError.throwInstantiationError(); + } + defineProperties(TerrainData.prototype, { /** - * The blend factor is the destination alpha. - * - * @type {Number} - * @constant + * An array of credits for this tile. + * @memberof TerrainData.prototype + * @type {Credit[]} */ - DESTINATION_ALPHA : WebGLConstants.DST_ALPHA, - + credits : { + get : DeveloperError.throwInstantiationError + }, /** - * The blend factor is one minus the destination alpha. - * - * @type {Number} - * @constant + * The water mask included in this terrain data, if any. A water mask is a rectangular + * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. + * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. + * @memberof TerrainData.prototype + * @type {Uint8Array|Image|Canvas} */ - ONE_MINUS_DESTINATION_ALPHA : WebGLConstants.ONE_MINUS_DST_ALPHA, + waterMask : { + get : DeveloperError.throwInstantiationError + } + }); - /** - * The blend factor is the constant color. - * - * @type {Number} - * @constant - */ - CONSTANT_COLOR : WebGLConstants.CONSTANT_COLOR, + /** + * Computes the terrain height at a specified longitude and latitude. + * @function + * + * @param {Rectangle} rectangle The rectangle covered by this terrain data. + * @param {Number} longitude The longitude in radians. + * @param {Number} latitude The latitude in radians. + * @returns {Number} The terrain height at the specified position. If the position + * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly + * incorrect for positions far outside the rectangle. + */ + TerrainData.prototype.interpolateHeight = DeveloperError.throwInstantiationError; - /** - * The blend factor is one minus the constant color. - * - * @type {Number} - * @constant - */ - ONE_MINUS_CONSTANT_COLOR : WebGLConstants.ONE_MINUS_CONSTANT_ALPHA, + /** + * Determines if a given child tile is available, based on the + * {@link TerrainData#childTileMask}. The given child tile coordinates are assumed + * to be one of the four children of this tile. If non-child tile coordinates are + * given, the availability of the southeast child tile is returned. + * @function + * + * @param {Number} thisX The tile X coordinate of this (the parent) tile. + * @param {Number} thisY The tile Y coordinate of this (the parent) tile. + * @param {Number} childX The tile X coordinate of the child tile to check for availability. + * @param {Number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {Boolean} True if the child tile is available; otherwise, false. + */ + TerrainData.prototype.isChildAvailable = DeveloperError.throwInstantiationError; - /** - * The blend factor is the constant alpha. - * - * @type {Number} - * @constant - */ - CONSTANT_ALPHA : WebGLConstants.CONSTANT_ALPHA, + /** + * Creates a {@link TerrainMesh} from this terrain data. + * @function + * + * @private + * + * @param {TilingScheme} tilingScheme The tiling scheme to which this tile belongs. + * @param {Number} x The X coordinate of the tile for which to create the terrain data. + * @param {Number} y The Y coordinate of the tile for which to create the terrain data. + * @param {Number} level The level of the tile for which to create the terrain data. + * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * asynchronous mesh creations are already in progress and the operation should + * be retried later. + */ + TerrainData.prototype.createMesh = DeveloperError.throwInstantiationError; - /** - * The blend factor is one minus the constant alpha. - * - * @type {Number} - * @constant - */ - ONE_MINUS_CONSTANT_ALPHA : WebGLConstants.ONE_MINUS_CONSTANT_ALPHA, + /** + * Upsamples this terrain data for use by a descendant tile. + * @function + * + * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. + * @param {Number} thisX The X coordinate of this tile in the tiling scheme. + * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {Number} thisLevel The level of this tile in the tiling scheme. + * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise.<TerrainData>|undefined} A promise for upsampled terrain data for the descendant tile, + * or undefined if too many asynchronous upsample operations are in progress and the request has been + * deferred. + */ + TerrainData.prototype.upsample = DeveloperError.throwInstantiationError; - /** - * The blend factor is the saturated source alpha. - * - * @type {Number} - * @constant - */ - SOURCE_ALPHA_SATURATE : WebGLConstants.SRC_ALPHA_SATURATE - }; + /** + * Gets a value indicating whether or not this terrain data was created by upsampling lower resolution + * terrain data. If this value is false, the data was obtained from some other source, such + * as by downloading it from a remote server. This method should return true for instances + * returned from a call to {@link TerrainData#upsample}. + * @function + * + * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + */ + TerrainData.prototype.wasCreatedByUpsampling = DeveloperError.throwInstantiationError; - return freezeObject(BlendFunction); + return TerrainData; }); -define('Scene/BlendingState',[ - '../Core/freezeObject', - './BlendEquation', - './BlendFunction' +define('Core/TilingScheme',[ + './defineProperties', + './DeveloperError' ], function( - freezeObject, - BlendEquation, - BlendFunction) { + defineProperties, + DeveloperError) { 'use strict'; /** - * The blending state combines {@link BlendEquation} and {@link BlendFunction} and the - * <code>enabled</code> flag to define the full blending state for combining source and - * destination fragments when rendering. - * <p> - * This is a helper when using custom render states with {@link Appearance#renderState}. - * </p> + * A tiling scheme for geometry or imagery on the surface of an ellipsoid. At level-of-detail zero, + * the coarsest, least-detailed level, the number of tiles is configurable. + * At level of detail one, each of the level zero tiles has four children, two in each direction. + * At level of detail two, each of the level one tiles has four children, two in each direction. + * This continues for as many levels as are present in the geometry or imagery source. * - * @exports BlendingState + * @alias TilingScheme + * @constructor + * + * @see WebMercatorTilingScheme + * @see GeographicTilingScheme */ - var BlendingState = { - /** - * Blending is disabled. - * - * @type {Object} - * @constant - */ - DISABLED : freezeObject({ - enabled : false - }), + function TilingScheme(options) { + throw new DeveloperError('This type should not be instantiated directly. Instead, use WebMercatorTilingScheme or GeographicTilingScheme.'); + } + defineProperties(TilingScheme.prototype, { /** - * Blending is enabled using alpha blending, <code>source(source.alpha) + destination(1 - source.alpha)</code>. - * - * @type {Object} - * @constant + * Gets the ellipsoid that is tiled by the tiling scheme. + * @memberof TilingScheme.prototype + * @type {Ellipsoid} */ - ALPHA_BLEND : freezeObject({ - enabled : true, - equationRgb : BlendEquation.ADD, - equationAlpha : BlendEquation.ADD, - functionSourceRgb : BlendFunction.SOURCE_ALPHA, - functionSourceAlpha : BlendFunction.SOURCE_ALPHA, - functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA, - functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA - }), + ellipsoid: { + get : DeveloperError.throwInstantiationError + }, /** - * Blending is enabled using alpha blending with premultiplied alpha, <code>source + destination(1 - source.alpha)</code>. - * - * @type {Object} - * @constant + * Gets the rectangle, in radians, covered by this tiling scheme. + * @memberof TilingScheme.prototype + * @type {Rectangle} */ - PRE_MULTIPLIED_ALPHA_BLEND : freezeObject({ - enabled : true, - equationRgb : BlendEquation.ADD, - equationAlpha : BlendEquation.ADD, - functionSourceRgb : BlendFunction.ONE, - functionSourceAlpha : BlendFunction.ONE, - functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA, - functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA - }), + rectangle : { + get : DeveloperError.throwInstantiationError + }, + /** - * Blending is enabled using additive blending, <code>source(source.alpha) + destination</code>. - * - * @type {Object} - * @constant + * Gets the map projection used by the tiling scheme. + * @memberof TilingScheme.prototype + * @type {MapProjection} */ - ADDITIVE_BLEND : freezeObject({ - enabled : true, - equationRgb : BlendEquation.ADD, - equationAlpha : BlendEquation.ADD, - functionSourceRgb : BlendFunction.SOURCE_ALPHA, - functionSourceAlpha : BlendFunction.SOURCE_ALPHA, - functionDestinationRgb : BlendFunction.ONE, - functionDestinationAlpha : BlendFunction.ONE - }) - }; + projection : { + get : DeveloperError.throwInstantiationError + } + }); - return freezeObject(BlendingState); -}); + /** + * Gets the total number of tiles in the X direction at a specified level-of-detail. + * @function + * + * @param {Number} level The level-of-detail. + * @returns {Number} The number of tiles in the X direction at the given level. + */ + TilingScheme.prototype.getNumberOfXTilesAtLevel = DeveloperError.throwInstantiationError; -define('Scene/CullFace',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + /** + * Gets the total number of tiles in the Y direction at a specified level-of-detail. + * @function + * + * @param {Number} level The level-of-detail. + * @returns {Number} The number of tiles in the Y direction at the given level. + */ + TilingScheme.prototype.getNumberOfYTilesAtLevel = DeveloperError.throwInstantiationError; /** - * Determines which triangles, if any, are culled. + * Transforms a rectangle specified in geodetic radians to the native coordinate system + * of this tiling scheme. + * @function * - * @exports CullFace + * @param {Rectangle} rectangle The rectangle to transform. + * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result' + * is undefined. */ - var CullFace = { - /** - * Front-facing triangles are culled. - * - * @type {Number} - * @constant - */ - FRONT : WebGLConstants.FRONT, + TilingScheme.prototype.rectangleToNativeRectangle = DeveloperError.throwInstantiationError; - /** - * Back-facing triangles are culled. - * - * @type {Number} - * @constant - */ - BACK : WebGLConstants.BACK, + /** + * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates + * of the tiling scheme. + * @function + * + * @param {Number} x The integer x coordinate of the tile. + * @param {Number} y The integer y coordinate of the tile. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the rectangle + * if 'result' is undefined. + */ + TilingScheme.prototype.tileXYToNativeRectangle = DeveloperError.throwInstantiationError; - /** - * Both front-facing and back-facing triangles are culled. - * - * @type {Number} - * @constant - */ - FRONT_AND_BACK : WebGLConstants.FRONT_AND_BACK - }; + /** + * Converts tile x, y coordinates and level to a cartographic rectangle in radians. + * @function + * + * @param {Number} x The integer x coordinate of the tile. + * @param {Number} y The integer y coordinate of the tile. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the rectangle + * if 'result' is undefined. + */ + TilingScheme.prototype.tileXYToRectangle = DeveloperError.throwInstantiationError; - return freezeObject(CullFace); + /** + * Calculates the tile x, y coordinates of the tile containing + * a given cartographic position. + * @function + * + * @param {Cartographic} position The position. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates + * if 'result' is undefined. + */ + TilingScheme.prototype.positionToTileXY = DeveloperError.throwInstantiationError; + + return TilingScheme; }); -define('Scene/Appearance',[ - '../Core/clone', - '../Core/combine', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - './BlendingState', - './CullFace' +define('Core/TimeIntervalCollection',[ + './binarySearch', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Event', + './GregorianDate', + './isLeapYear', + './Iso8601', + './JulianDate', + './TimeInterval' ], function( - clone, - combine, + binarySearch, defaultValue, defined, defineProperties, - BlendingState, - CullFace) { + DeveloperError, + Event, + GregorianDate, + isLeapYear, + Iso8601, + JulianDate, + TimeInterval) { 'use strict'; + function compareIntervalStartTimes(left, right) { + return JulianDate.compare(left.start, right.start); + } + /** - * An appearance defines the full GLSL vertex and fragment shaders and the - * render state used to draw a {@link Primitive}. All appearances implement - * this base <code>Appearance</code> interface. - * - * @alias Appearance + * A non-overlapping collection of {@link TimeInterval} instances sorted by start time. + * @alias TimeIntervalCollection * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link Appearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link Appearance#renderState} has backface culling enabled. - * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {RenderState} [options.renderState] Optional render state to override the default render state. - * - * @see MaterialAppearance - * @see EllipsoidSurfaceAppearance - * @see PerInstanceColorAppearance - * @see DebugAppearance - * @see PolylineColorAppearance - * @see PolylineMaterialAppearance - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @param {TimeInterval[]} [intervals] An array of intervals to add to the collection. */ - function Appearance(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function TimeIntervalCollection(intervals) { + this._intervals = []; + this._changedEvent = new Event(); + + if (defined(intervals)) { + var length = intervals.length; + for (var i = 0; i < length; i++) { + this.addInterval(intervals[i]); + } + } + } + defineProperties(TimeIntervalCollection.prototype, { /** - * The material used to determine the fragment color. Unlike other {@link Appearance} - * properties, this is not read-only, so an appearance's material can change on the fly. - * - * @type Material - * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + * Gets an event that is raised whenever the collection of intervals change. + * @memberof TimeIntervalCollection.prototype + * @type {Event} + * @readonly */ - this.material = options.material; + changedEvent : { + get : function() { + return this._changedEvent; + } + }, /** - * When <code>true</code>, the geometry is expected to appear translucent. - * - * @type {Boolean} - * - * @default true + * Gets the start time of the collection. + * @memberof TimeIntervalCollection.prototype + * @type {JulianDate} + * @readonly */ - this.translucent = defaultValue(options.translucent, true); + start : { + get : function() { + var intervals = this._intervals; + return intervals.length === 0 ? undefined : intervals[0].start; + } + }, - this._vertexShaderSource = options.vertexShaderSource; - this._fragmentShaderSource = options.fragmentShaderSource; - this._renderState = options.renderState; - this._closed = defaultValue(options.closed, false); - } + /** + * Gets whether or not the start time is included in the collection. + * @memberof TimeIntervalCollection.prototype + * @type {Boolean} + * @readonly + */ + isStartIncluded : { + get : function() { + var intervals = this._intervals; + return intervals.length === 0 ? false : intervals[0].isStartIncluded; + } + }, - defineProperties(Appearance.prototype, { /** - * The GLSL source code for the vertex shader. - * - * @memberof Appearance.prototype - * - * @type {String} + * Gets the stop time of the collection. + * @memberof TimeIntervalCollection.prototype + * @type {JulianDate} * @readonly */ - vertexShaderSource : { + stop : { get : function() { - return this._vertexShaderSource; + var intervals = this._intervals; + var length = intervals.length; + return length === 0 ? undefined : intervals[length - 1].stop; } }, /** - * The GLSL source code for the fragment shader. The full fragment shader - * source is built procedurally taking into account the {@link Appearance#material}. - * Use {@link Appearance#getFragmentShaderSource} to get the full source. - * - * @memberof Appearance.prototype - * - * @type {String} + * Gets whether or not the stop time is included in the collection. + * @memberof TimeIntervalCollection.prototype + * @type {Boolean} * @readonly */ - fragmentShaderSource : { + isStopIncluded : { get : function() { - return this._fragmentShaderSource; + var intervals = this._intervals; + var length = intervals.length; + return length === 0 ? false : intervals[length - 1].isStopIncluded; } }, /** - * The WebGL fixed-function state to use when rendering the geometry. - * - * @memberof Appearance.prototype - * - * @type {Object} + * Gets the number of intervals in the collection. + * @memberof TimeIntervalCollection.prototype + * @type {Number} * @readonly */ - renderState : { + length : { get : function() { - return this._renderState; + return this._intervals.length; } }, /** - * When <code>true</code>, the geometry is expected to be closed. - * - * @memberof Appearance.prototype - * + * Gets whether or not the collection is empty. + * @memberof TimeIntervalCollection.prototype * @type {Boolean} * @readonly - * - * @default false */ - closed : { + isEmpty : { get : function() { - return this._closed; + return this._intervals.length === 0; } } }); /** - * Procedurally creates the full GLSL fragment shader source for this appearance - * taking into account {@link Appearance#fragmentShaderSource} and {@link Appearance#material}. + * Compares this instance against the provided instance componentwise and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @returns {String} The full GLSL fragment shader source. + * @param {TimeIntervalCollection} [right] The right hand side collection. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ - Appearance.prototype.getFragmentShaderSource = function() { - var parts = []; - if (this.flat) { - parts.push('#define FLAT'); + TimeIntervalCollection.prototype.equals = function(right, dataComparer) { + if (this === right) { + return true; } - if (this.faceForward) { - parts.push('#define FACE_FORWARD'); + if (!(right instanceof TimeIntervalCollection)) { + return false; } - if (defined(this.material)) { - parts.push(this.material.shaderSource); + var intervals = this._intervals; + var rightIntervals = right._intervals; + var length = intervals.length; + if (length !== rightIntervals.length) { + return false; } - parts.push(this.fragmentShaderSource); - - return parts.join('\n'); + for (var i = 0; i < length; i++) { + if (!TimeInterval.equals(intervals[i], rightIntervals[i], dataComparer)) { + return false; + } + } + return true; }; /** - * Determines if the geometry is translucent based on {@link Appearance#translucent} and {@link Material#isTranslucent}. + * Gets the interval at the specified index. * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @param {Number} index The index of the interval to retrieve. + * @returns {TimeInterval} The interval at the specified index, or <code>undefined</code> if no interval exists as that index. */ - Appearance.prototype.isTranslucent = function() { - return (defined(this.material) && this.material.isTranslucent()) || (!defined(this.material) && this.translucent); + TimeIntervalCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); + } + + return this._intervals[index]; }; /** - * Creates a render state. This is not the final render state instance; instead, - * it can contain a subset of render state properties identical to the render state - * created in the context. - * - * @returns {Object} The render state. + * Removes all intervals from the collection. */ - Appearance.prototype.getRenderState = function() { - var translucent = this.isTranslucent(); - var rs = clone(this.renderState, false); - if (translucent) { - rs.depthMask = false; - rs.blending = BlendingState.ALPHA_BLEND; - } else { - rs.depthMask = true; + TimeIntervalCollection.prototype.removeAll = function() { + if (this._intervals.length > 0) { + this._intervals.length = 0; + this._changedEvent.raiseEvent(this); } - return rs; }; /** - * @private + * Finds and returns the interval that contains the specified date. + * + * @param {JulianDate} date The date to search for. + * @returns {TimeInterval|undefined} The interval containing the specified date, <code>undefined</code> if no such interval exists. */ - Appearance.getDefaultRenderState = function(translucent, closed, existing) { - var rs = { - depthTest : { - enabled : true - } - }; + TimeIntervalCollection.prototype.findIntervalContainingDate = function(date) { + var index = this.indexOf(date); + return index >= 0 ? this._intervals[index] : undefined; + }; - if (translucent) { - rs.depthMask = false; - rs.blending = BlendingState.ALPHA_BLEND; - } - - if (closed) { - rs.cull = { - enabled : true, - face : CullFace.BACK - }; - } - - if (defined(existing)) { - rs = combine(existing, rs, true); - } - - return rs; - }; - - return Appearance; -}); - -define('Renderer/ContextLimits',[ - '../Core/defineProperties' - ], function( - defineProperties) { - 'use strict'; + /** + * Finds and returns the data for the interval that contains the specified date. + * + * @param {JulianDate} date The date to search for. + * @returns {Object} The data for the interval containing the specified date, or <code>undefined</code> if no such interval exists. + */ + TimeIntervalCollection.prototype.findDataForIntervalContainingDate = function(date) { + var index = this.indexOf(date); + return index >= 0 ? this._intervals[index].data : undefined; + }; /** - * @private + * Checks if the specified date is inside this collection. + * + * @param {JulianDate} julianDate The date to check. + * @returns {Boolean} <code>true</code> if the collection contains the specified date, <code>false</code> otherwise. */ - var ContextLimits = { - _maximumCombinedTextureImageUnits : 0, - _maximumCubeMapSize : 0, - _maximumFragmentUniformVectors : 0, - _maximumTextureImageUnits : 0, - _maximumRenderbufferSize : 0, - _maximumTextureSize : 0, - _maximumVaryingVectors : 0, - _maximumVertexAttributes : 0, - _maximumVertexTextureImageUnits : 0, - _maximumVertexUniformVectors : 0, - _minimumAliasedLineWidth : 0, - _maximumAliasedLineWidth : 0, - _minimumAliasedPointSize : 0, - _maximumAliasedPointSize : 0, - _maximumViewportWidth : 0, - _maximumViewportHeight : 0, - _maximumTextureFilterAnisotropy : 0, - _maximumDrawBuffers : 0, - _maximumColorAttachments : 0, - _highpFloatSupported: false, - _highpIntSupported: false + TimeIntervalCollection.prototype.contains = function(julianDate) { + return this.indexOf(julianDate) >= 0; }; - defineProperties(ContextLimits, { + var indexOfScratch = new TimeInterval(); - /** - * The maximum number of texture units that can be used from the vertex and fragment - * shader with this WebGL implementation. The minimum is eight. If both shaders access the - * same texture unit, this counts as two texture units. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_COMBINED_TEXTURE_IMAGE_UNITS</code>. - */ - maximumCombinedTextureImageUnits : { - get: function () { - return ContextLimits._maximumCombinedTextureImageUnits; + /** + * Finds and returns the index of the interval in the collection that contains the specified date. + * + * @param {JulianDate} date The date to search for. + * @returns {Number} The index of the interval that contains the specified date, if no such interval exists, + * it returns a negative number which is the bitwise complement of the index of the next interval that + * starts after the date, or if no interval starts after the specified date, the bitwise complement of + * the length of the collection. + */ + TimeIntervalCollection.prototype.indexOf = function(date) { + if (!defined(date)) { + throw new DeveloperError('date is required'); + } + + var intervals = this._intervals; + indexOfScratch.start = date; + indexOfScratch.stop = date; + var index = binarySearch(intervals, indexOfScratch, compareIntervalStartTimes); + if (index >= 0) { + if (intervals[index].isStartIncluded) { + return index; } - }, - /** - * The approximate maximum cube mape width and height supported by this WebGL implementation. - * The minimum is 16, but most desktop and laptop implementations will support much larger sizes like 8,192. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_CUBE_MAP_TEXTURE_SIZE</code>. - */ - maximumCubeMapSize : { - get: function () { - return ContextLimits._maximumCubeMapSize; + if (index > 0 && intervals[index - 1].stop.equals(date) && intervals[index - 1].isStopIncluded) { + return index - 1; } - }, + return ~index; + } - /** - * The maximum number of <code>vec4</code>, <code>ivec4</code>, and <code>bvec4</code> - * uniforms that can be used by a fragment shader with this WebGL implementation. The minimum is 16. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_FRAGMENT_UNIFORM_VECTORS</code>. - */ - maximumFragmentUniformVectors : { - get: function () { - return ContextLimits._maximumFragmentUniformVectors; - } - }, + index = ~index; + if (index > 0 && (index - 1) < intervals.length && TimeInterval.contains(intervals[index - 1], date)) { + return index - 1; + } + return ~index; + }; - /** - * The maximum number of texture units that can be used from the fragment shader with this WebGL implementation. The minimum is eight. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_TEXTURE_IMAGE_UNITS</code>. - */ - maximumTextureImageUnits : { - get: function () { - return ContextLimits._maximumTextureImageUnits; - } - }, + /** + * Returns the first interval in the collection that matches the specified parameters. + * All parameters are optional and <code>undefined</code> parameters are treated as a don't care condition. + * + * @param {Object} [options] Object with the following properties: + * @param {JulianDate} [options.start] The start time of the interval. + * @param {JulianDate} [options.stop] The stop time of the interval. + * @param {Boolean} [options.isStartIncluded] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. + * @returns {TimeInterval} The first interval in the collection that matches the specified parameters. + */ + TimeIntervalCollection.prototype.findInterval = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var start = options.start; + var stop = options.stop; + var isStartIncluded = options.isStartIncluded; + var isStopIncluded = options.isStopIncluded; - /** - * The maximum renderbuffer width and height supported by this WebGL implementation. - * The minimum is 16, but most desktop and laptop implementations will support much larger sizes like 8,192. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_RENDERBUFFER_SIZE</code>. - */ - maximumRenderbufferSize : { - get: function () { - return ContextLimits._maximumRenderbufferSize; + var intervals = this._intervals; + for (var i = 0, len = intervals.length; i < len; i++) { + var interval = intervals[i]; + if ((!defined(start) || interval.start.equals(start)) && + (!defined(stop) || interval.stop.equals(stop)) && + (!defined(isStartIncluded) || interval.isStartIncluded === isStartIncluded) && + (!defined(isStopIncluded) || interval.isStopIncluded === isStopIncluded)) { + return intervals[i]; } - }, + } + return undefined; + }; - /** - * The approximate maximum texture width and height supported by this WebGL implementation. - * The minimum is 64, but most desktop and laptop implementations will support much larger sizes like 8,192. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_TEXTURE_SIZE</code>. - */ - maximumTextureSize : { - get: function () { - return ContextLimits._maximumTextureSize; - } - }, + /** + * Adds an interval to the collection, merging intervals that contain the same data and + * splitting intervals of different data as needed in order to maintain a non-overlapping collection. + * The data in the new interval takes precedence over any existing intervals in the collection. + * + * @param {TimeInterval} interval The interval to add. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + */ + TimeIntervalCollection.prototype.addInterval = function(interval, dataComparer) { + if (!defined(interval)) { + throw new DeveloperError('interval is required'); + } + + if (interval.isEmpty) { + return; + } - /** - * The maximum number of <code>vec4</code> varying variables supported by this WebGL implementation. - * The minimum is eight. Matrices and arrays count as multiple <code>vec4</code>s. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VARYING_VECTORS</code>. - */ - maximumVaryingVectors : { - get: function () { - return ContextLimits._maximumVaryingVectors; - } - }, + var comparison; + var index; + var intervals = this._intervals; - /** - * The maximum number of <code>vec4</code> vertex attributes supported by this WebGL implementation. The minimum is eight. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_ATTRIBS</code>. - */ - maximumVertexAttributes : { - get: function () { - return ContextLimits._maximumVertexAttributes; - } - }, + // Handle the common case quickly: we're adding a new interval which is after all existing intervals. + if (intervals.length === 0 || JulianDate.greaterThan(interval.start, intervals[intervals.length - 1].stop)) { + intervals.push(interval); + this._changedEvent.raiseEvent(this); + return; + } - /** - * The maximum number of texture units that can be used from the vertex shader with this WebGL implementation. - * The minimum is zero, which means the GL does not support vertex texture fetch. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_TEXTURE_IMAGE_UNITS</code>. - */ - maximumVertexTextureImageUnits : { - get: function () { - return ContextLimits._maximumVertexTextureImageUnits; - } - }, + // Keep the list sorted by the start date + index = binarySearch(intervals, interval, compareIntervalStartTimes); + if (index < 0) { + index = ~index; + } else if (index > 0 && interval.isStartIncluded && intervals[index - 1].isStartIncluded && intervals[index - 1].start.equals(interval.start)) { + // interval's start date exactly equals the start date of at least one interval in the collection. + // It could actually equal the start date of two intervals if one of them does not actually + // include the date. In that case, the binary search could have found either. We need to + // look at the surrounding intervals and their IsStartIncluded properties in order to make sure + // we're working with the correct interval. + --index; + } else if (index < intervals.length && !interval.isStartIncluded && intervals[index].isStartIncluded && intervals[index].start.equals(interval.start)) { + ++index; + } - /** - * The maximum number of <code>vec4</code>, <code>ivec4</code>, and <code>bvec4</code> - * uniforms that can be used by a vertex shader with this WebGL implementation. The minimum is 16. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_UNIFORM_VECTORS</code>. - */ - maximumVertexUniformVectors : { - get: function () { - return ContextLimits._maximumVertexUniformVectors; + if (index > 0) { + // Not the first thing in the list, so see if the interval before this one + // overlaps this one. + comparison = JulianDate.compare(intervals[index - 1].stop, interval.start); + if (comparison > 0 || (comparison === 0 && (intervals[index - 1].isStopIncluded || interval.isStartIncluded))) { + // There is an overlap + if (defined(dataComparer) ? dataComparer(intervals[index - 1].data, interval.data) : (intervals[index - 1].data === interval.data)) { + // Overlapping intervals have the same data, so combine them + if (JulianDate.greaterThan(interval.stop, intervals[index - 1].stop)) { + interval = new TimeInterval({ + start : intervals[index - 1].start, + stop : interval.stop, + isStartIncluded : intervals[index - 1].isStartIncluded, + isStopIncluded : interval.isStopIncluded, + data : interval.data + }); + } else { + interval = new TimeInterval({ + start : intervals[index - 1].start, + stop : intervals[index - 1].stop, + isStartIncluded : intervals[index - 1].isStartIncluded, + isStopIncluded : intervals[index - 1].isStopIncluded || (interval.stop.equals(intervals[index - 1].stop) && interval.isStopIncluded), + data : interval.data + }); + } + intervals.splice(index - 1, 1); + --index; + } else { + // Overlapping intervals have different data. The new interval + // being added 'wins' so truncate the previous interval. + // If the existing interval extends past the end of the new one, + // split the existing interval into two intervals. + comparison = JulianDate.compare(intervals[index - 1].stop, interval.stop); + if (comparison > 0 || (comparison === 0 && intervals[index - 1].isStopIncluded && !interval.isStopIncluded)) { + intervals.splice(index - 1, 1, new TimeInterval({ + start : intervals[index - 1].start, + stop : interval.start, + isStartIncluded : intervals[index - 1].isStartIncluded, + isStopIncluded : !interval.isStartIncluded, + data : intervals[index - 1].data + }), new TimeInterval({ + start : interval.stop, + stop : intervals[index - 1].stop, + isStartIncluded : !interval.isStopIncluded, + isStopIncluded : intervals[index - 1].isStopIncluded, + data : intervals[index - 1].data + })); + } else { + intervals[index - 1] = new TimeInterval({ + start : intervals[index - 1].start, + stop : interval.start, + isStartIncluded : intervals[index - 1].isStartIncluded, + isStopIncluded : !interval.isStartIncluded, + data : intervals[index - 1].data + }); + } + } } - }, + } - /** - * The minimum aliased line width, in pixels, supported by this WebGL implementation. It will be at most one. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. - */ - minimumAliasedLineWidth : { - get: function () { - return ContextLimits._minimumAliasedLineWidth; + while (index < intervals.length) { + // Not the last thing in the list, so see if the intervals after this one overlap this one. + comparison = JulianDate.compare(interval.stop, intervals[index].start); + if (comparison > 0 || (comparison === 0 && (interval.isStopIncluded || intervals[index].isStartIncluded))) { + // There is an overlap + if (defined(dataComparer) ? dataComparer(intervals[index].data, interval.data) : intervals[index].data === interval.data) { + // Overlapping intervals have the same data, so combine them + interval = new TimeInterval({ + start : interval.start, + stop : JulianDate.greaterThan(intervals[index].stop, interval.stop) ? intervals[index].stop : interval.stop, + isStartIncluded : interval.isStartIncluded, + isStopIncluded : JulianDate.greaterThan(intervals[index].stop, interval.stop) ? intervals[index].isStopIncluded : interval.isStopIncluded, + data : interval.data + }); + intervals.splice(index, 1); + } else { + // Overlapping intervals have different data. The new interval + // being added 'wins' so truncate the next interval. + intervals[index] = new TimeInterval({ + start : interval.stop, + stop : intervals[index].stop, + isStartIncluded : !interval.isStopIncluded, + isStopIncluded : intervals[index].isStopIncluded, + data : intervals[index].data + }); + if (intervals[index].isEmpty) { + intervals.splice(index, 1); + } else { + // Found a partial span, so it is not possible for the next + // interval to be spanned at all. Stop looking. + break; + } + } + } else { + // Found the last one we're spanning, so stop looking. + break; } - }, + } - /** - * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. - */ - maximumAliasedLineWidth : { - get: function () { - return ContextLimits._maximumAliasedLineWidth; - } - }, + // Add the new interval + intervals.splice(index, 0, interval); + this._changedEvent.raiseEvent(this); + }; - /** - * The minimum aliased point size, in pixels, supported by this WebGL implementation. It will be at most one. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_POINT_SIZE_RANGE</code>. - */ - minimumAliasedPointSize : { - get: function () { - return ContextLimits._minimumAliasedPointSize; - } - }, + /** + * Removes the specified interval from this interval collection, creating a hole over the specified interval. + * The data property of the input interval is ignored. + * + * @param {TimeInterval} interval The interval to remove. + * @returns <code>true</code> if the interval was removed, <code>false</code> if no part of the interval was in the collection. + */ + TimeIntervalCollection.prototype.removeInterval = function(interval) { + if (!defined(interval)) { + throw new DeveloperError('interval is required'); + } + + if (interval.isEmpty) { + return false; + } - /** - * The maximum aliased point size, in pixels, supported by this WebGL implementation. It will be at least one. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_POINT_SIZE_RANGE</code>. - */ - maximumAliasedPointSize : { - get: function () { - return ContextLimits._maximumAliasedPointSize; - } - }, + var result = false; + var intervals = this._intervals; - /** - * The maximum supported width of the viewport. It will be at least as large as the visible width of the associated canvas. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VIEWPORT_DIMS</code>. - */ - maximumViewportWidth : { - get: function () { - return ContextLimits._maximumViewportWidth; - } - }, + var index = binarySearch(intervals, interval, compareIntervalStartTimes); + if (index < 0) { + index = ~index; + } - /** - * The maximum supported height of the viewport. It will be at least as large as the visible height of the associated canvas. - * @memberof ContextLimits - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VIEWPORT_DIMS</code>. - */ - maximumViewportHeight : { - get: function () { - return ContextLimits._maximumViewportHeight; - } - }, + var intervalStart = interval.start; + var intervalStop = interval.stop; + var intervalIsStartIncluded = interval.isStartIncluded; + var intervalIsStopIncluded = interval.isStopIncluded; - /** - * The maximum degree of anisotropy for texture filtering - * @memberof ContextLimits - * @type {Number} - */ - maximumTextureFilterAnisotropy : { - get: function () { - return ContextLimits._maximumTextureFilterAnisotropy; - } - }, + // Check for truncation of the end of the previous interval. + if (index > 0) { + var indexMinus1 = intervals[index - 1]; + var indexMinus1Stop = indexMinus1.stop; + if (JulianDate.greaterThan(indexMinus1Stop, intervalStart) || + (TimeInterval.equals(indexMinus1Stop, intervalStart) && + indexMinus1.isStopIncluded && intervalIsStartIncluded)) { + result = true; - /** - * The maximum number of simultaneous outputs that may be written in a fragment shader. - * @memberof ContextLimits - * @type {Number} - */ - maximumDrawBuffers : { - get: function () { - return ContextLimits._maximumDrawBuffers; + if (JulianDate.greaterThan(indexMinus1Stop, intervalStop) || + (indexMinus1.isStopIncluded && !intervalIsStopIncluded && TimeInterval.equals(indexMinus1Stop, intervalStop))) { + // Break the existing interval into two pieces + intervals.splice(index, 0, new TimeInterval({ + start : intervalStop, + stop : indexMinus1Stop, + isStartIncluded : !intervalIsStopIncluded, + isStopIncluded : indexMinus1.isStopIncluded, + data : indexMinus1.data + })); + } + intervals[index - 1] = new TimeInterval({ + start : indexMinus1.start, + stop : intervalStart, + isStartIncluded : indexMinus1.isStartIncluded, + isStopIncluded : !intervalIsStartIncluded, + data : indexMinus1.data + }); } - }, + } - /** - * The maximum number of color attachments supported. - * @memberof ContextLimits - * @type {Number} - */ - maximumColorAttachments : { - get: function () { - return ContextLimits._maximumColorAttachments; - } - }, + // Check if the Start of the current interval should remain because interval.start is the same but + // it is not included. + var indexInterval = intervals[index]; + if (index < intervals.length && + !intervalIsStartIncluded && + indexInterval.isStartIncluded && + intervalStart.equals(indexInterval.start)) { + result = true; - /** - * High precision float supported (<code>highp</code>) in fragment shaders. - * @memberof ContextLimits - * @type {Boolean} - */ - highpFloatSupported : { - get: function () { - return ContextLimits._highpFloatSupported; - } - }, + intervals.splice(index, 0, new TimeInterval({ + start : indexInterval.start, + stop : indexInterval.start, + isStartIncluded : true, + isStopIncluded : true, + data : indexInterval.data + })); + ++index; + indexInterval = intervals[index]; + } - /** - * High precision int supported (<code>highp</code>) in fragment shaders. - * @memberof ContextLimits - * @type {Boolean} - */ - highpIntSupported : { - get: function () { - return ContextLimits._highpIntSupported; + // Remove any intervals that are completely overlapped by the input interval. + while (index < intervals.length && JulianDate.greaterThan(intervalStop, indexInterval.stop)) { + result = true; + intervals.splice(index, 1); + indexInterval = intervals[index]; + } + + // Check for the case where the input interval ends on the same date + // as an existing interval. + if (index < intervals.length && intervalStop.equals(indexInterval.stop)) { + result = true; + + if (!intervalIsStopIncluded && indexInterval.isStopIncluded) { + // Last point of interval should remain because the stop date is included in + // the existing interval but is not included in the input interval. + if ((index + 1) < intervals.length && intervals[index + 1].start.equals(intervalStop) && indexInterval.data === intervals[index + 1].data) { + // Combine single point with the next interval + intervals.splice(index, 1); + indexInterval = new TimeInterval({ + start : indexInterval.start, + stop : indexInterval.stop, + isStartIncluded : true, + isStopIncluded : indexInterval.isStopIncluded, + data : indexInterval.data + }); + } else { + indexInterval = new TimeInterval({ + start : intervalStop, + stop : intervalStop, + isStartIncluded : true, + isStopIncluded : true, + data : indexInterval.data + }); + } + intervals[index] = indexInterval; + } else { + // Interval is completely overlapped + intervals.splice(index, 1); } } - }); + // Truncate any partially-overlapped intervals. + if (index < intervals.length && + (JulianDate.greaterThan(intervalStop, indexInterval.start) || + (intervalStop.equals(indexInterval.start) && + intervalIsStopIncluded && + indexInterval.isStartIncluded))) { + result = true; + intervals[index] = new TimeInterval({ + start : intervalStop, + stop : indexInterval.stop, + isStartIncluded : !intervalIsStopIncluded, + isStopIncluded : indexInterval.isStopIncluded, + data : indexInterval.data + }); + } - return ContextLimits; -}); + if (result) { + this._changedEvent.raiseEvent(this); + } -define('Renderer/CubeMapFace',[ - '../Core/Check', - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/DeveloperError', - './PixelDatatype' - ], function( - Check, - defaultValue, - defineProperties, - DeveloperError, - PixelDatatype) { - 'use strict'; + return result; + }; /** - * @private + * Creates a new instance that is the intersection of this collection and the provided collection. + * + * @param {TimeIntervalCollection} other The collection to intersect with. + * @param {TimeInterval~DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. + * @param {TimeInterval~MergeCallback} [mergeCallback] A function which merges the data of the two intervals. If omitted, the data from the left interval will be used. + * @returns {TimeIntervalCollection} A new TimeIntervalCollection which is the intersection of this collection and the provided collection. */ - function CubeMapFace(gl, texture, textureTarget, targetFace, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY) { - this._gl = gl; - this._texture = texture; - this._textureTarget = textureTarget; - this._targetFace = targetFace; - this._pixelFormat = pixelFormat; - this._pixelDatatype = pixelDatatype; - this._size = size; - this._preMultiplyAlpha = preMultiplyAlpha; - this._flipY = flipY; - } + TimeIntervalCollection.prototype.intersect = function(other, dataComparer, mergeCallback) { + if (!defined(other)) { + throw new DeveloperError('other is required.'); + } + + var left = 0; + var right = 0; + var result = new TimeIntervalCollection(); + var intervals = this._intervals; + var otherIntervals = other._intervals; - defineProperties(CubeMapFace.prototype, { - pixelFormat : { - get : function() { - return this._pixelFormat; - } - }, - pixelDatatype : { - get : function() { - return this._pixelDatatype; - } - }, - _target : { - get : function() { - return this._targetFace; + while (left < intervals.length && right < otherIntervals.length) { + var leftInterval = intervals[left]; + var rightInterval = otherIntervals[right]; + if (JulianDate.lessThan(leftInterval.stop, rightInterval.start)) { + ++left; + } else if (JulianDate.lessThan(rightInterval.stop, leftInterval.start)) { + ++right; + } else { + // The following will return an intersection whose data is 'merged' if the callback is defined + if (defined(mergeCallback) || + ((defined(dataComparer) && dataComparer(leftInterval.data, rightInterval.data)) || + (!defined(dataComparer) && rightInterval.data === leftInterval.data))) { + + var intersection = TimeInterval.intersect(leftInterval, rightInterval, new TimeInterval(), mergeCallback); + if (!intersection.isEmpty) { + // Since we start with an empty collection for 'result', and there are no overlapping intervals in 'this' (as a rule), + // the 'intersection' will never overlap with a previous interval in 'result'. So, no need to do any additional 'merging'. + result.addInterval(intersection, dataComparer); + } + } + + if (JulianDate.lessThan(leftInterval.stop, rightInterval.stop) || + (leftInterval.stop.equals(rightInterval.stop) && + !leftInterval.isStopIncluded && + rightInterval.isStopIncluded)) { + ++left; + } else { + ++right; + } } } - }); + return result; + }; /** - * Copies texels from the source to the cubemap's face. - * - * @param {Object} source The source ImageData, HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, or an object with a width, height, and typed array as shown in the example. - * @param {Number} [xOffset=0] An offset in the x direction in the cubemap where copying begins. - * @param {Number} [yOffset=0] An offset in the y direction in the cubemap where copying begins. - * - * @exception {DeveloperError} xOffset must be greater than or equal to zero. - * @exception {DeveloperError} yOffset must be greater than or equal to zero. - * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. - * @exception {DeveloperError} yOffset + source.height must be less than or equal to height. - * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. + * Creates a new instance from a JulianDate array. * - * @example - * // Create a cubemap with 1x1 faces, and make the +x face red. - * var cubeMap = new CubeMap({ - * context : context - * width : 1, - * height : 1 - * }); - * cubeMap.positiveX.copyFrom({ - * width : 1, - * height : 1, - * arrayBufferView : new Uint8Array([255, 0, 0, 255]) - * }); + * @param {Object} options Object with the following properties: + * @param {JulianDate[]} options.julianDates An array of ISO 8601 dates. + * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. + * @param {TimeIntervalCollection} [result] An existing instance to use for the result. + * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. */ - CubeMapFace.prototype.copyFrom = function(source, xOffset, yOffset) { - xOffset = defaultValue(xOffset, 0); - yOffset = defaultValue(yOffset, 0); - - Check.defined('source', source); - Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); - Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); - if (xOffset + source.width > this._size) { - throw new DeveloperError('xOffset + source.width must be less than or equal to width.'); + TimeIntervalCollection.fromJulianDateArray = function(options, result) { + if (!defined(options)) { + throw new DeveloperError('options is required.'); } - if (yOffset + source.height > this._size) { - throw new DeveloperError('yOffset + source.height must be less than or equal to height.'); + if (!defined(options.julianDates)) { + throw new DeveloperError('options.iso8601Array is required.'); } - var gl = this._gl; - var target = this._textureTarget; + if (!defined(result)) { + result = new TimeIntervalCollection(); + } - // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); + var julianDates = options.julianDates; + var length = julianDates.length; + var dataCallback = options.dataCallback; - if (source.arrayBufferView) { - gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); - } else { - gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); + var isStartIncluded = defaultValue(options.isStartIncluded, true); + var isStopIncluded = defaultValue(options.isStopIncluded, true); + var leadingInterval = defaultValue(options.leadingInterval, false); + var trailingInterval = defaultValue(options.trailingInterval, false); + var interval; + + // Add a default interval, which will only end up being used up to first interval + var startIndex = 0; + if (leadingInterval) { + ++startIndex; + interval = new TimeInterval({ + start : Iso8601.MINIMUM_VALUE, + stop : julianDates[0], + isStartIncluded : true, + isStopIncluded : !isStartIncluded + }); + interval.data = defined(dataCallback) ? dataCallback(interval, result.length) : result.length; + result.addInterval(interval); } - gl.bindTexture(target, null); - }; + for (var i = 0; i < length - 1; ++i) { + var startDate = julianDates[i]; + var endDate = julianDates[i + 1]; - /** - * Copies texels from the framebuffer to the cubemap's face. - * - * @param {Number} [xOffset=0] An offset in the x direction in the cubemap where copying begins. - * @param {Number} [yOffset=0] An offset in the y direction in the cubemap where copying begins. - * @param {Number} [framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. - * @param {Number} [framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. - * @param {Number} [width=CubeMap's width] The width of the subimage to copy. - * @param {Number} [height=CubeMap's height] The height of the subimage to copy. - * - * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT. - * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. - * @exception {DeveloperError} xOffset must be greater than or equal to zero. - * @exception {DeveloperError} yOffset must be greater than or equal to zero. - * @exception {DeveloperError} framebufferXOffset must be greater than or equal to zero. - * @exception {DeveloperError} framebufferYOffset must be greater than or equal to zero. - * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. - * @exception {DeveloperError} yOffset + source.height must be less than or equal to height. - * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. - * - * @example - * // Copy the framebuffer contents to the +x cube map face. - * cubeMap.positiveX.copyFromFramebuffer(); - */ - CubeMapFace.prototype.copyFromFramebuffer = function(xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height) { - xOffset = defaultValue(xOffset, 0); - yOffset = defaultValue(yOffset, 0); - framebufferXOffset = defaultValue(framebufferXOffset, 0); - framebufferYOffset = defaultValue(framebufferYOffset, 0); - width = defaultValue(width, this._size); - height = defaultValue(height, this._size); + interval = new TimeInterval({ + start : startDate, + stop : endDate, + isStartIncluded : (result.length === startIndex) ? isStartIncluded : true, + isStopIncluded : (i === (length - 2)) ? isStopIncluded : false + }); + interval.data = defined(dataCallback) ? dataCallback(interval, result.length) : result.length; + result.addInterval(interval); - Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); - Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); - Check.typeOf.number.greaterThanOrEquals('framebufferXOffset', framebufferXOffset, 0); - Check.typeOf.number.greaterThanOrEquals('framebufferYOffset', framebufferYOffset, 0); - if (xOffset + width > this._size) { - throw new DeveloperError('xOffset + source.width must be less than or equal to width.'); - } - if (yOffset + height > this._size) { - throw new DeveloperError('yOffset + source.height must be less than or equal to height.'); + startDate = endDate; } - if (this._pixelDatatype === PixelDatatype.FLOAT) { - throw new DeveloperError('Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT.'); + + if (trailingInterval) { + interval = new TimeInterval({ + start : julianDates[length - 1], + stop : Iso8601.MAXIMUM_VALUE, + isStartIncluded : !isStopIncluded, + isStopIncluded : true + }); + interval.data = defined(dataCallback) ? dataCallback(interval, result.length) : result.length; + result.addInterval(interval); } - - var gl = this._gl; - var target = this._textureTarget; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); - gl.copyTexSubImage2D(this._targetFace, 0, xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height); - gl.bindTexture(target, null); + return result; }; - return CubeMapFace; -}); - -define('Renderer/MipmapHint',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + var scratchGregorianDate = new GregorianDate(); + var monthLengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; /** + * Adds duration represented as a GregorianDate to a JulianDate + * + * @param {JulianDate} julianDate The date. + * @param {GregorianDate} duration An duration represented as a GregorianDate. + * @param {JulianDate} result An existing instance to use for the result. + * @returns {JulianDate} The modified result parameter. + * * @private */ - var MipmapHint = { - DONT_CARE : WebGLConstants.DONT_CARE, - FASTEST : WebGLConstants.FASTEST, - NICEST : WebGLConstants.NICEST, + function addToDate(julianDate, duration, result) { + if (!defined(result)) { + result = new JulianDate(); + } + JulianDate.toGregorianDate(julianDate, scratchGregorianDate); - validate : function(mipmapHint) { - return ((mipmapHint === MipmapHint.DONT_CARE) || - (mipmapHint === MipmapHint.FASTEST) || - (mipmapHint === MipmapHint.NICEST)); + var millisecond = scratchGregorianDate.millisecond + duration.millisecond; + var second = scratchGregorianDate.second + duration.second; + var minute = scratchGregorianDate.minute + duration.minute; + var hour = scratchGregorianDate.hour + duration.hour; + var day = scratchGregorianDate.day + duration.day; + var month = scratchGregorianDate.month + duration.month; + var year = scratchGregorianDate.year + duration.year; + + if (millisecond >= 1000) { + second += Math.floor(millisecond / 1000); + millisecond = millisecond % 1000; } - }; - return freezeObject(MipmapHint); -}); + if (second >= 60) { + minute += Math.floor(second / 60); + second = second % 60; + } -define('Renderer/TextureMagnificationFilter',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + if (minute >= 60) { + hour += Math.floor(minute / 60); + minute = minute % 60; + } - /** - * Enumerates all possible filters used when magnifying WebGL textures. - * - * @exports TextureMagnificationFilter - * - * @see TextureMinificationFilter - */ - var TextureMagnificationFilter = { - /** - * Samples the texture by returning the closest pixel. - * - * @type {Number} - * @constant - */ - NEAREST : WebGLConstants.NEAREST, - /** - * Samples the texture through bi-linear interpolation of the four nearest pixels. This produces smoother results than <code>NEAREST</code> filtering. - * - * @type {Number} - * @constant - */ - LINEAR : WebGLConstants.LINEAR, + if (hour >= 24) { + day += Math.floor(hour / 24); + hour = hour % 24; + } - /** - * Validates the given <code>textureMinificationFilter</code> with respect to the possible enum values. - * - * @private - * - * @param textureMagnificationFilter - * @returns {Boolean} <code>true</code> if <code>textureMagnificationFilter</code> is valid. - */ - validate : function(textureMagnificationFilter) { - return ((textureMagnificationFilter === TextureMagnificationFilter.NEAREST) || - (textureMagnificationFilter === TextureMagnificationFilter.LINEAR)); + // If days is greater than the month's length we need to remove those number of days, + // readjust month and year and repeat until days is less than the month's length. + monthLengths[2] = isLeapYear(year) ? 29 : 28; + while ((day > monthLengths[month]) || (month >= 13)) { + if (day > monthLengths[month]) { + day -= monthLengths[month]; + ++month; + } + + if (month >= 13) { + --month; + year += Math.floor(month / 12); + month = month % 12; + ++month; + } + + monthLengths[2] = isLeapYear(year) ? 29 : 28; } - }; - return freezeObject(TextureMagnificationFilter); -}); + scratchGregorianDate.millisecond = millisecond; + scratchGregorianDate.second = second; + scratchGregorianDate.minute = minute; + scratchGregorianDate.hour = hour; + scratchGregorianDate.day = day; + scratchGregorianDate.month = month; + scratchGregorianDate.year = year; -define('Renderer/TextureMinificationFilter',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + return JulianDate.fromGregorianDate(scratchGregorianDate, result); + } + + var scratchJulianDate = new JulianDate(); + var durationRegex = /P(?:([\d.,]+)Y)?(?:([\d.,]+)M)?(?:([\d.,]+)W)?(?:([\d.,]+)D)?(?:T(?:([\d.,]+)H)?(?:([\d.,]+)M)?(?:([\d.,]+)S)?)?/; /** - * Enumerates all possible filters used when minifying WebGL textures. + * Parses ISO8601 duration string * - * @exports TextureMinificationFilter + * @param {String} iso8601 An ISO 8601 duration. + * @param {GregorianDate} result An existing instance to use for the result. + * @returns {Boolean} True is parsing succeeded, false otherwise * - * @see TextureMagnificationFilter + * @private */ - var TextureMinificationFilter = { - /** - * Samples the texture by returning the closest pixel. - * - * @type {Number} - * @constant - */ - NEAREST : WebGLConstants.NEAREST, - /** - * Samples the texture through bi-linear interpolation of the four nearest pixels. This produces smoother results than <code>NEAREST</code> filtering. - * - * @type {Number} - * @constant - */ - LINEAR : WebGLConstants.LINEAR, - /** - * Selects the nearest mip level and applies nearest sampling within that level. - * <p> - * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. - * </p> - * - * @type {Number} - * @constant - */ - NEAREST_MIPMAP_NEAREST : WebGLConstants.NEAREST_MIPMAP_NEAREST, - /** - * Selects the nearest mip level and applies linear sampling within that level. - * <p> - * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. - * </p> - * - * @type {Number} - * @constant - */ - LINEAR_MIPMAP_NEAREST : WebGLConstants.LINEAR_MIPMAP_NEAREST, - /** - * Read texture values with nearest sampling from two adjacent mip levels and linearly interpolate the results. - * <p> - * This option provides a good balance of visual quality and speed when sampling from a mipmapped texture. - * </p> - * <p> - * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. - * </p> - * - * @type {Number} - * @constant - */ - NEAREST_MIPMAP_LINEAR : WebGLConstants.NEAREST_MIPMAP_LINEAR, - /** - * Read texture values with linear sampling from two adjacent mip levels and linearly interpolate the results. - * <p> - * This option provides a good balance of visual quality and speed when sampling from a mipmapped texture. - * </p> - * <p> - * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. - * </p> - * @type {Number} - * @constant - */ - LINEAR_MIPMAP_LINEAR : WebGLConstants.LINEAR_MIPMAP_LINEAR, + function parseDuration(iso8601, result) { + if (!defined(iso8601) || iso8601.length === 0) { + return false; + } - /** - * Validates the given <code>textureMinificationFilter</code> with respect to the possible enum values. - * - * @private - * - * @param textureMinificationFilter - * @returns {Boolean} <code>true</code> if <code>textureMinificationFilter</code> is valid. - */ - validate : function(textureMinificationFilter) { - return ((textureMinificationFilter === TextureMinificationFilter.NEAREST) || - (textureMinificationFilter === TextureMinificationFilter.LINEAR) || - (textureMinificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || - (textureMinificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || - (textureMinificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || - (textureMinificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR)); + // Reset object + result.year = 0; + result.month = 0; + result.day = 0; + result.hour = 0; + result.minute = 0; + result.second = 0; + result.millisecond = 0; + + if (iso8601[0] === 'P') { + var matches = iso8601.match(durationRegex); + if (!defined(matches)) { + return false; + } + if (defined(matches[1])) { // Years + result.year = Number(matches[1].replace(',', '.')); + } + if (defined(matches[2])) { // Months + result.month = Number(matches[2].replace(',', '.')); + } + if (defined(matches[3])) { // Weeks + result.day = Number(matches[3].replace(',', '.')) * 7; + } + if (defined(matches[4])) { // Days + result.day += Number(matches[4].replace(',', '.')); + } + if (defined(matches[5])) { // Hours + result.hour = Number(matches[5].replace(',', '.')); + } + if (defined(matches[6])) { // Weeks + result.minute = Number(matches[6].replace(',', '.')); + } + if (defined(matches[7])) { // Seconds + var seconds = Number(matches[7].replace(',', '.')); + result.second = Math.floor(seconds); + result.millisecond = (seconds % 1) * 1000; + } + } else { + // They can technically specify the duration as a normal date with some caveats. Try our best to load it. + if (iso8601[iso8601.length - 1] !== 'Z') { // It's not a date, its a duration, so it always has to be UTC + iso8601 += 'Z'; + } + JulianDate.toGregorianDate(JulianDate.fromIso8601(iso8601, scratchJulianDate), result); + } + + // A duration of 0 will cause an infinite loop, so just make sure something is non-zero + return (result.year || result.month || result.day || result.hour || + result.minute || result.second || result.millisecond); + } + + var scratchDuration = new GregorianDate(); + /** + * Creates a new instance from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} time interval (start/end/duration). + * + * @param {Object} options Object with the following properties: + * @param {String} options.iso8601 An ISO 8601 interval. + * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. + * @param {TimeIntervalCollection} [result] An existing instance to use for the result. + * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. + */ + TimeIntervalCollection.fromIso8601 = function(options, result) { + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + if (!defined(options.iso8601)) { + throw new DeveloperError('options.iso8601 is required.'); + } + + var dates = options.iso8601.split('/'); + var start = JulianDate.fromIso8601(dates[0]); + var stop = JulianDate.fromIso8601(dates[1]); + var julianDates = []; + + if (!parseDuration(dates[2], scratchDuration)) { + julianDates.push(start, stop); + } else { + var date = JulianDate.clone(start); + julianDates.push(date); + while (JulianDate.compare(date, stop) < 0) { + date = addToDate(date, scratchDuration); + var afterStop = (JulianDate.compare(stop, date) <= 0); + if (afterStop) { + JulianDate.clone(stop, date); + } + + julianDates.push(date); + } } + + return TimeIntervalCollection.fromJulianDateArray({ + julianDates : julianDates, + isStartIncluded : options.isStartIncluded, + isStopIncluded : options.isStopIncluded, + leadingInterval : options.leadingInterval, + trailingInterval : options.trailingInterval, + dataCallback : options.dataCallback + }, result); }; - return freezeObject(TextureMinificationFilter); + /** + * Creates a new instance from a {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} date array. + * + * @param {Object} options Object with the following properties: + * @param {String[]} options.iso8601Dates An array of ISO 8601 dates. + * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. + * @param {TimeIntervalCollection} [result] An existing instance to use for the result. + * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. + */ + TimeIntervalCollection.fromIso8601DateArray = function(options, result) { + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + if (!defined(options.iso8601Dates)) { + throw new DeveloperError('options.iso8601Dates is required.'); + } + + return TimeIntervalCollection.fromJulianDateArray({ + julianDates : options.iso8601Dates.map(function(date) { + return JulianDate.fromIso8601(date); + }), + isStartIncluded : options.isStartIncluded, + isStopIncluded : options.isStopIncluded, + leadingInterval : options.leadingInterval, + trailingInterval : options.trailingInterval, + dataCallback : options.dataCallback + }, result); + }; + + /** + * Creates a new instance from a {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} duration array. + * + * @param {Object} options Object with the following properties: + * @param {JulianDate} options.epoch An date that the durations are relative to. + * @param {String} options.iso8601Durations An array of ISO 8601 durations. + * @param {Boolean} [options.relativeToPrevious=false] <code>true</code> if durations are relative to previous date, <code>false</code> if always relative to the epoch. + * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. + * @param {TimeIntervalCollection} [result] An existing instance to use for the result. + * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. + */ + TimeIntervalCollection.fromIso8601DurationArray = function(options, result) { + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + if (!defined(options.epoch)) { + throw new DeveloperError('options.epoch is required.'); + } + if (!defined(options.iso8601Durations)) { + throw new DeveloperError('options.iso8601Durations is required.'); + } + + var epoch = options.epoch; + var iso8601Durations = options.iso8601Durations; + var relativeToPrevious = defaultValue(options.relativeToPrevious, false); + var julianDates = []; + var date, previousDate; + + var length = iso8601Durations.length; + for (var i = 0; i < length; ++i) { + // Allow a duration of 0 on the first iteration, because then it is just the epoch + if (parseDuration(iso8601Durations[i], scratchDuration) || i === 0) { + if (relativeToPrevious && defined(previousDate)) { + date = addToDate(previousDate, scratchDuration); + } else { + date = addToDate(epoch, scratchDuration); + } + julianDates.push(date); + previousDate = date; + } + } + + return TimeIntervalCollection.fromJulianDateArray({ + julianDates : julianDates, + isStartIncluded : options.isStartIncluded, + isStopIncluded : options.isStopIncluded, + leadingInterval : options.leadingInterval, + trailingInterval : options.trailingInterval, + dataCallback : options.dataCallback + }, result); + }; + + return TimeIntervalCollection; }); -define('Renderer/TextureWrap',[ - '../Core/freezeObject', - '../Core/WebGLConstants' +define('Core/TranslationRotationScale',[ + './Cartesian3', + './defaultValue', + './defined', + './Quaternion' ], function( - freezeObject, - WebGLConstants) { + Cartesian3, + defaultValue, + defined, + Quaternion) { 'use strict'; + var defaultScale = new Cartesian3(1.0, 1.0, 1.0); + var defaultTranslation = Cartesian3.ZERO; + var defaultRotation = Quaternion.IDENTITY; + /** - * @private + * An affine transformation defined by a translation, rotation, and scale. + * @alias TranslationRotationScale + * @constructor + * + * @param {Cartesian3} [translation=Cartesian3.ZERO] A {@link Cartesian3} specifying the (x, y, z) translation to apply to the node. + * @param {Quaternion} [rotation=Quaternion.IDENTITY] A {@link Quaternion} specifying the (x, y, z, w) rotation to apply to the node. + * @param {Cartesian3} [scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} specifying the (x, y, z) scaling to apply to the node. */ - var TextureWrap = { - CLAMP_TO_EDGE : WebGLConstants.CLAMP_TO_EDGE, - REPEAT : WebGLConstants.REPEAT, - MIRRORED_REPEAT : WebGLConstants.MIRRORED_REPEAT, + var TranslationRotationScale = function(translation, rotation, scale) { + /** + * Gets or sets the (x, y, z) translation to apply to the node. + * @type {Cartesian3} + * @default Cartesian3.ZERO + */ + this.translation = Cartesian3.clone(defaultValue(translation, defaultTranslation)); - validate : function(textureWrap) { - return ((textureWrap === TextureWrap.CLAMP_TO_EDGE) || - (textureWrap === TextureWrap.REPEAT) || - (textureWrap === TextureWrap.MIRRORED_REPEAT)); - } + /** + * Gets or sets the (x, y, z, w) rotation to apply to the node. + * @type {Quaternion} + * @default Quaternion.IDENTITY + */ + this.rotation = Quaternion.clone(defaultValue(rotation, defaultRotation)); + + /** + * Gets or sets the (x, y, z) scaling to apply to the node. + * @type {Cartesian3} + * @default new Cartesian3(1.0, 1.0, 1.0) + */ + this.scale = Cartesian3.clone(defaultValue(scale, defaultScale)); }; - return freezeObject(TextureWrap); + /** + * Compares this instance against the provided instance and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {TranslationRotationScale} [right] The right hand side TranslationRotationScale. + * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + */ + TranslationRotationScale.prototype.equals = function(right) { + return (this === right) || + (defined(right) && + Cartesian3.equals(this.translation, right.translation) && + Quaternion.equals(this.rotation, right.rotation) && + Cartesian3.equals(this.scale, right.scale)); + }; + + return TranslationRotationScale; }); -define('Renderer/Sampler',[ - '../Core/Check', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - './TextureMagnificationFilter', - './TextureMinificationFilter', - './TextureWrap' +define('Core/VideoSynchronizer',[ + './defaultValue', + './defined', + './defineProperties', + './destroyObject', + './Iso8601', + './JulianDate' ], function( - Check, defaultValue, defined, defineProperties, - DeveloperError, - TextureMagnificationFilter, - TextureMinificationFilter, - TextureWrap) { + destroyObject, + Iso8601, + JulianDate) { 'use strict'; /** - * @private + * Synchronizes a video element with a simulation clock. + * + * @alias VideoSynchronizer + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Clock} [options.clock] The clock instance used to drive the video. + * @param {HTMLVideoElement} [options.element] The video element to be synchronized. + * @param {JulianDate} [options.epoch=Iso8601.MINIMUM_VALUE] The simulation time that marks the start of the video. + * @param {Number} [options.tolerance=1.0] The maximum amount of time, in seconds, that the clock and video can diverge. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Video.html|Video Material Demo} */ - function Sampler(options) { + function VideoSynchronizer(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var wrapS = defaultValue(options.wrapS, TextureWrap.CLAMP_TO_EDGE); - var wrapT = defaultValue(options.wrapT, TextureWrap.CLAMP_TO_EDGE); - var minificationFilter = defaultValue(options.minificationFilter, TextureMinificationFilter.LINEAR); - var magnificationFilter = defaultValue(options.magnificationFilter, TextureMagnificationFilter.LINEAR); - var maximumAnisotropy = (defined(options.maximumAnisotropy)) ? options.maximumAnisotropy : 1.0; - - if (!TextureWrap.validate(wrapS)) { - throw new DeveloperError('Invalid sampler.wrapS.'); - } + this._clock = undefined; + this._element = undefined; + this._clockSubscription = undefined; + this._seekFunction = undefined; - if (!TextureWrap.validate(wrapT)) { - throw new DeveloperError('Invalid sampler.wrapT.'); - } + this.clock = options.clock; + this.element = options.element; - if (!TextureMinificationFilter.validate(minificationFilter)) { - throw new DeveloperError('Invalid sampler.minificationFilter.'); - } + /** + * Gets or sets the simulation time that marks the start of the video. + * @type {JulianDate} + * @default Iso8601.MINIMUM_VALUE + */ + this.epoch = defaultValue(options.epoch, Iso8601.MINIMUM_VALUE); - if (!TextureMagnificationFilter.validate(magnificationFilter)) { - throw new DeveloperError('Invalid sampler.magnificationFilter.'); - } + /** + * Gets or sets the amount of time in seconds the video's currentTime + * and the clock's currentTime can diverge before a video seek is performed. + * Lower values make the synchronization more accurate but video + * performance might suffer. Higher values provide better performance + * but at the cost of accuracy. + * @type {Number} + * @default 1.0 + */ + this.tolerance = defaultValue(options.tolerance, 1.0); - Check.typeOf.number.greaterThanOrEquals('maximumAnisotropy', maximumAnisotropy, 1.0); - - this._wrapS = wrapS; - this._wrapT = wrapT; - this._minificationFilter = minificationFilter; - this._magnificationFilter = magnificationFilter; - this._maximumAnisotropy = maximumAnisotropy; + this._seeking = false; + this._seekFunction = undefined; + this._firstTickAfterSeek = false; } - defineProperties(Sampler.prototype, { - wrapS : { - get : function() { - return this._wrapS; - } - }, - wrapT : { + defineProperties(VideoSynchronizer.prototype, { + /** + * Gets or sets the clock used to drive the video element. + * + * @memberof VideoSynchronizer.prototype + * @type {Clock} + */ + clock : { get : function() { - return this._wrapT; + return this._clock; + }, + set : function(value) { + var oldValue = this._clock; + + if (oldValue === value) { + return; + } + + if (defined(oldValue)) { + this._clockSubscription(); + this._clockSubscription = undefined; + } + + if (defined(value)) { + this._clockSubscription = value.onTick.addEventListener(VideoSynchronizer.prototype._onTick, this); + } + + this._clock = value; } }, - minificationFilter : { + /** + * Gets or sets the video element to synchronize. + * + * @memberof VideoSynchronizer.prototype + * @type {HTMLVideoElement} + */ + element : { get : function() { - return this._minificationFilter; + return this._element; + }, + set : function(value) { + var oldValue = this._element; + + if (oldValue === value) { + return; + } + + if (defined(oldValue)) { + oldValue.removeEventListener('seeked', this._seekFunction, false); + } + + if (defined(value)) { + this._seeking = false; + this._seekFunction = createSeekFunction(this); + value.addEventListener('seeked', this._seekFunction, false); + } + + this._element = value; + this._seeking = false; + this._firstTickAfterSeek = false; } - }, - magnificationFilter : { - get : function() { - return this._magnificationFilter; + } + }); + + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + VideoSynchronizer.prototype.destroy = function() { + this.element = undefined; + this.clock = undefined; + return destroyObject(this); + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + VideoSynchronizer.prototype.isDestroyed = function() { + return false; + }; + + VideoSynchronizer.prototype._onTick = function(clock) { + var element = this._element; + if (!defined(element) || element.readyState < 2) { + return; + } + + var paused = element.paused; + var shouldAnimate = clock.shouldAnimate; + if (shouldAnimate === paused) { + if (shouldAnimate) { + element.play(); + } else { + element.pause(); } - }, - maximumAnisotropy : { - get : function() { - return this._maximumAnisotropy; + } + + //We need to avoid constant seeking or the video will + //never contain a complete frame for us to render. + //So don't do anything if we're seeing or on the first + //tick after a seek (the latter of which allows the frame + //to actually be rendered. + if (this._seeking || this._firstTickAfterSeek) { + this._firstTickAfterSeek = false; + return; + } + + element.playbackRate = clock.multiplier; + + var clockTime = clock.currentTime; + var epoch = defaultValue(this.epoch, Iso8601.MINIMUM_VALUE); + var videoTime = JulianDate.secondsDifference(clockTime, epoch); + + var duration = element.duration; + var desiredTime; + var currentTime = element.currentTime; + if (element.loop) { + videoTime = videoTime % duration; + if (videoTime < 0.0) { + videoTime = duration - videoTime; } + desiredTime = videoTime; + } else if (videoTime > duration) { + desiredTime = duration; + } else if (videoTime < 0.0) { + desiredTime = 0.0; + } else { + desiredTime = videoTime; } - }); - return Sampler; + //If the playing video's time and the scene's clock time + //ever drift too far apart, we want to set the video to match + var tolerance = shouldAnimate ? defaultValue(this.tolerance, 1.0) : 0.001; + if (Math.abs(desiredTime - currentTime) > tolerance) { + this._seeking = true; + element.currentTime = desiredTime; + } + }; + + function createSeekFunction(that) { + return function() { + that._seeking = false; + that._firstTickAfterSeek = true; + }; + } + + return VideoSynchronizer; }); -define('Renderer/CubeMap',[ - '../Core/Check', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Math', - '../Core/PixelFormat', - './ContextLimits', - './CubeMapFace', - './MipmapHint', - './PixelDatatype', - './Sampler', - './TextureMagnificationFilter', - './TextureMinificationFilter' +define('Core/VRTheWorldTerrainProvider',[ + '../ThirdParty/when', + './Credit', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './Ellipsoid', + './Event', + './GeographicTilingScheme', + './getImagePixels', + './HeightmapTerrainData', + './Math', + './Rectangle', + './Resource', + './TerrainProvider', + './TileProviderError' ], function( - Check, + when, + Credit, defaultValue, defined, defineProperties, - destroyObject, + deprecationWarning, DeveloperError, + Ellipsoid, + Event, + GeographicTilingScheme, + getImagePixels, + HeightmapTerrainData, CesiumMath, - PixelFormat, - ContextLimits, - CubeMapFace, - MipmapHint, - PixelDatatype, - Sampler, - TextureMagnificationFilter, - TextureMinificationFilter) { + Rectangle, + Resource, + TerrainProvider, + TileProviderError) { 'use strict'; - function CubeMap(options) { + function DataRectangle(rectangle, maxLevel) { + this.rectangle = rectangle; + this.maxLevel = maxLevel; + } + /** + * A {@link TerrainProvider} that produces terrain geometry by tessellating height maps + * retrieved from a {@link http://vr-theworld.com/|VT MÄK VR-TheWorld server}. + * + * @alias VRTheWorldTerrainProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The URL of the VR-TheWorld TileMap. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid. If this parameter is not + * specified, the WGS84 ellipsoid is used. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * + * + * @example + * var terrainProvider = new Cesium.VRTheWorldTerrainProvider({ + * url : 'https://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/' + * }); + * viewer.terrainProvider = terrainProvider; + * + * @see TerrainProvider + */ + function VRTheWorldTerrainProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - Check.defined('options.context', options.context); + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); + } - var context = options.context; - var source = options.source; - var width; - var height; - - if (defined(source)) { - var faces = [source.positiveX, source.negativeX, source.positiveY, source.negativeY, source.positiveZ, source.negativeZ]; - - if (!faces[0] || !faces[1] || !faces[2] || !faces[3] || !faces[4] || !faces[5]) { - throw new DeveloperError('options.source requires positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ faces.'); - } - - width = faces[0].width; - height = faces[0].height; - - for ( var i = 1; i < 6; ++i) { - if ((Number(faces[i].width) !== width) || (Number(faces[i].height) !== height)) { - throw new DeveloperError('Each face in options.source must have the same width and height.'); - } - } - } else { - width = options.width; - height = options.height; + if (defined(options.proxy)) { + deprecationWarning('VRTheWorldTerrainProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - var size = width; - var pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGBA); - var pixelDatatype = defaultValue(options.pixelDatatype, PixelDatatype.UNSIGNED_BYTE); + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); - if (!defined(width) || !defined(height)) { - throw new DeveloperError('options requires a source field to create an initialized cube map or width and height fields to create a blank cube map.'); - } + this._resource = resource; - if (width !== height) { - throw new DeveloperError('Width must equal height.'); - } + this._errorEvent = new Event(); + this._ready = false; + this._readyPromise = when.defer(); - if (size <= 0) { - throw new DeveloperError('Width and height must be greater than zero.'); - } + this._terrainDataStructure = { + heightScale : 1.0 / 1000.0, + heightOffset : -1000.0, + elementsPerHeight : 3, + stride : 4, + elementMultiplier : 256.0, + isBigEndian : true, + lowestEncodedHeight : 0, + highestEncodedHeight : 256 * 256 * 256 - 1 + }; - if (size > ContextLimits.maximumCubeMapSize) { - throw new DeveloperError('Width and height must be less than or equal to the maximum cube map size (' + ContextLimits.maximumCubeMapSize + '). Check maximumCubeMapSize.'); + var credit = options.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); } + this._credit = credit; - if (!PixelFormat.validate(pixelFormat)) { - throw new DeveloperError('Invalid options.pixelFormat.'); - } + this._tilingScheme = undefined; + this._rectangles = []; - if (PixelFormat.isDepthFormat(pixelFormat)) { - throw new DeveloperError('options.pixelFormat cannot be DEPTH_COMPONENT or DEPTH_STENCIL.'); - } + var that = this; + var metadataError; + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - if (!PixelDatatype.validate(pixelDatatype)) { - throw new DeveloperError('Invalid options.pixelDatatype.'); - } + function metadataSuccess(xml) { + var srs = xml.getElementsByTagName('SRS')[0].textContent; + if (srs === 'EPSG:4326') { + that._tilingScheme = new GeographicTilingScheme({ ellipsoid : ellipsoid }); + } else { + metadataFailure('SRS ' + srs + ' is not supported.'); + return; + } - if ((pixelDatatype === PixelDatatype.FLOAT) && !context.floatingPointTexture) { - throw new DeveloperError('When options.pixelDatatype is FLOAT, this WebGL implementation must support the OES_texture_float extension.'); - } - - var sizeInBytes = PixelFormat.textureSizeInBytes(pixelFormat, pixelDatatype, size, size) * 6; + var tileFormat = xml.getElementsByTagName('TileFormat')[0]; + that._heightmapWidth = parseInt(tileFormat.getAttribute('width'), 10); + that._heightmapHeight = parseInt(tileFormat.getAttribute('height'), 10); + that._levelZeroMaximumGeometricError = TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(ellipsoid, Math.min(that._heightmapWidth, that._heightmapHeight), that._tilingScheme.getNumberOfXTilesAtLevel(0)); - // Use premultiplied alpha for opaque textures should perform better on Chrome: - // http://media.tojicode.com/webglCamp4/#20 - var preMultiplyAlpha = options.preMultiplyAlpha || ((pixelFormat === PixelFormat.RGB) || (pixelFormat === PixelFormat.LUMINANCE)); - var flipY = defaultValue(options.flipY, true); + var dataRectangles = xml.getElementsByTagName('DataExtent'); - var gl = context._gl; - var textureTarget = gl.TEXTURE_CUBE_MAP; - var texture = gl.createTexture(); + for (var i = 0; i < dataRectangles.length; ++i) { + var dataRectangle = dataRectangles[i]; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(textureTarget, texture); + var west = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('minx'))); + var south = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('miny'))); + var east = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('maxx'))); + var north = CesiumMath.toRadians(parseFloat(dataRectangle.getAttribute('maxy'))); + var maxLevel = parseInt(dataRectangle.getAttribute('maxlevel'), 10); - function createFace(target, sourceFace) { - if (sourceFace.arrayBufferView) { - gl.texImage2D(target, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, sourceFace.arrayBufferView); - } else { - gl.texImage2D(target, 0, pixelFormat, pixelFormat, pixelDatatype, sourceFace); + that._rectangles.push(new DataRectangle(new Rectangle(west, south, east, north), maxLevel)); } - } - - if (defined(source)) { - // TODO: _gl.pixelStorei(_gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_X, source.positiveX); - createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, source.negativeX); - createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, source.positiveY); - createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, source.negativeY); - createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, source.positiveZ); - createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, source.negativeZ); - } else { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + that._ready = true; + that._readyPromise.resolve(true); } - gl.bindTexture(textureTarget, null); - this._gl = gl; - this._textureFilterAnisotropic = context._textureFilterAnisotropic; - this._textureTarget = textureTarget; - this._texture = texture; - this._pixelFormat = pixelFormat; - this._pixelDatatype = pixelDatatype; - this._size = size; - this._hasMipmap = false; - this._sizeInBytes = sizeInBytes; - this._preMultiplyAlpha = preMultiplyAlpha; - this._flipY = flipY; - this._sampler = undefined; + function metadataFailure(e) { + var message = defaultValue(e, 'An error occurred while accessing ' + that._resource.url + '.'); + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + } - this._positiveX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._negativeX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._positiveY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._negativeY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._positiveZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - this._negativeZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + function requestMetadata() { + when(that._resource.fetchXML(), metadataSuccess, metadataFailure); + } - this.sampler = defined(options.sampler) ? options.sampler : new Sampler(); + requestMetadata(); } - defineProperties(CubeMap.prototype, { - positiveX : { - get : function() { - return this._positiveX; - } - }, - negativeX : { - get : function() { - return this._negativeX; - } - }, - positiveY : { - get : function() { - return this._positiveY; - } - }, - negativeY : { - get : function() { - return this._negativeY; - } - }, - positiveZ : { - get : function() { - return this._positiveZ; - } - }, - negativeZ : { + defineProperties(VRTheWorldTerrainProvider.prototype, { + /** + * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Event} + */ + errorEvent : { get : function() { - return this._negativeZ; + return this._errorEvent; } }, - sampler : { - get : function() { - return this._sampler; - }, - set : function(sampler) { - var minificationFilter = sampler.minificationFilter; - var magnificationFilter = sampler.magnificationFilter; - - var mipmap = - (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || - (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || - (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || - (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR); - - // float textures only support nearest filtering, so override the sampler's settings - if (this._pixelDatatype === PixelDatatype.FLOAT) { - minificationFilter = mipmap ? TextureMinificationFilter.NEAREST_MIPMAP_NEAREST : TextureMinificationFilter.NEAREST; - magnificationFilter = TextureMagnificationFilter.NEAREST; - } - var gl = this._gl; - var target = this._textureTarget; - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); - gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, minificationFilter); - gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, magnificationFilter); - gl.texParameteri(target, gl.TEXTURE_WRAP_S, sampler.wrapS); - gl.texParameteri(target, gl.TEXTURE_WRAP_T, sampler.wrapT); - if (defined(this._textureFilterAnisotropic)) { - gl.texParameteri(target, this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, sampler.maximumAnisotropy); - } - gl.bindTexture(target, null); - - this._sampler = sampler; - } - }, - pixelFormat: { - get : function() { - return this._pixelFormat; - } - }, - pixelDatatype : { - get : function() { - return this._pixelDatatype; - } - }, - width : { + /** + * Gets the credit to display when this terrain provider is active. Typically this is used to credit + * the source of the terrain. This function should not be called before {@link VRTheWorldTerrainProvider#ready} returns true. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Credit} + */ + credit : { get : function() { - return this._size; + return this._credit; } }, - height : { + + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link VRTheWorldTerrainProvider#ready} returns true. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {GeographicTilingScheme} + */ + tilingScheme : { get : function() { - return this._size; + if (!this.ready) { + throw new DeveloperError('requestTileGeometry must not be called before ready returns true.'); + } + + return this._tilingScheme; } }, - sizeInBytes : { + + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Boolean} + */ + ready : { get : function() { - if (this._hasMipmap) { - return Math.floor(this._sizeInBytes * 4 / 3); - } - return this._sizeInBytes; + return this._ready; } }, - preMultiplyAlpha : { + + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { get : function() { - return this._preMultiplyAlpha; + return this._readyPromise.promise; } }, - flipY : { + + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link VRTheWorldTerrainProvider#ready} returns true. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Boolean} + */ + hasWaterMask : { get : function() { - return this._flipY; + return false; } }, - _target : { + /** + * Gets a value indicating whether or not the requested tiles include vertex normals. + * This function should not be called before {@link VRTheWorldTerrainProvider#ready} returns true. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { get : function() { - return this._textureTarget; + return false; } } }); /** - * Generates a complete mipmap chain for each cubemap face. - * - * @param {MipmapHint} [hint=MipmapHint.DONT_CARE] A performance vs. quality hint. - * - * @exception {DeveloperError} hint is invalid. - * @exception {DeveloperError} This CubeMap's width must be a power of two to call generateMipmap(). - * @exception {DeveloperError} This CubeMap's height must be a power of two to call generateMipmap(). - * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. + * Requests the geometry for a given tile. This function should not be called before + * {@link VRTheWorldTerrainProvider#ready} returns true. The result includes terrain + * data and indicates that all child tiles are available. * - * @example - * // Generate mipmaps, and then set the sampler so mipmaps are used for - * // minification when the cube map is sampled. - * cubeMap.generateMipmap(); - * cubeMap.sampler = new Sampler({ - * minificationFilter : Cesium.TextureMinificationFilter.NEAREST_MIPMAP_LINEAR - * }); + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * returns undefined instead of a promise, it is an indication that too many requests are already + * pending and the request will be retried later. */ - CubeMap.prototype.generateMipmap = function(hint) { - hint = defaultValue(hint, MipmapHint.DONT_CARE); - - if ((this._size > 1) && !CesiumMath.isPowerOfTwo(this._size)) { - throw new DeveloperError('width and height must be a power of two to call generateMipmap().'); - } - if (!MipmapHint.validate(hint)) { - throw new DeveloperError('hint is invalid.'); + VRTheWorldTerrainProvider.prototype.requestTileGeometry = function(x, y, level, request) { + if (!this.ready) { + throw new DeveloperError('requestTileGeometry must not be called before ready returns true.'); } - this._hasMipmap = true; + var yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level); + var resource = this._resource.getDerivedResource({ + url: level + '/' + x + '/' + (yTiles - y - 1) + '.tif', + queryParameters: { + cesium: true + }, + request: request + }); + var promise = resource.fetchImage(); + if (!defined(promise)) { + return undefined; + } - var gl = this._gl; - var target = this._textureTarget; - gl.hint(gl.GENERATE_MIPMAP_HINT, hint); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); - gl.generateMipmap(target); - gl.bindTexture(target, null); + var that = this; + return when(promise, function(image) { + return new HeightmapTerrainData({ + buffer : getImagePixels(image), + width : that._heightmapWidth, + height : that._heightmapHeight, + childTileMask : getChildMask(that, x, y, level), + structure : that._terrainDataStructure + }); + }); }; - CubeMap.prototype.isDestroyed = function() { - return false; + /** + * Gets the maximum geometric error allowed in a tile at a given level. + * + * @param {Number} level The tile level for which to get the maximum geometric error. + * @returns {Number} The maximum geometric error. + */ + VRTheWorldTerrainProvider.prototype.getLevelMaximumGeometricError = function(level) { + if (!this.ready) { + throw new DeveloperError('requestTileGeometry must not be called before ready returns true.'); + } + return this._levelZeroMaximumGeometricError / (1 << level); }; - CubeMap.prototype.destroy = function() { - this._gl.deleteTexture(this._texture); - this._positiveX = destroyObject(this._positiveX); - this._negativeX = destroyObject(this._negativeX); - this._positiveY = destroyObject(this._positiveY); - this._negativeY = destroyObject(this._negativeY); - this._positiveZ = destroyObject(this._positiveZ); - this._negativeZ = destroyObject(this._negativeZ); - return destroyObject(this); + var rectangleScratch = new Rectangle(); + + function getChildMask(provider, x, y, level) { + var tilingScheme = provider._tilingScheme; + var rectangles = provider._rectangles; + var parentRectangle = tilingScheme.tileXYToRectangle(x, y, level); + + var childMask = 0; + + for (var i = 0; i < rectangles.length && childMask !== 15; ++i) { + var rectangle = rectangles[i]; + if (rectangle.maxLevel <= level) { + continue; + } + + var testRectangle = rectangle.rectangle; + + var intersection = Rectangle.intersection(testRectangle, parentRectangle, rectangleScratch); + if (defined(intersection)) { + // Parent tile is inside this rectangle, so at least one child is, too. + if (isTileInRectangle(tilingScheme, testRectangle, x * 2, y * 2, level + 1)) { + childMask |= 4; // northwest + } + if (isTileInRectangle(tilingScheme, testRectangle, x * 2 + 1, y * 2, level + 1)) { + childMask |= 8; // northeast + } + if (isTileInRectangle(tilingScheme, testRectangle, x * 2, y * 2 + 1, level + 1)) { + childMask |= 1; // southwest + } + if (isTileInRectangle(tilingScheme, testRectangle, x * 2 + 1, y * 2 + 1, level + 1)) { + childMask |= 2; // southeast + } + } + } + + return childMask; + } + + function isTileInRectangle(tilingScheme, rectangle, x, y, level) { + var tileRectangle = tilingScheme.tileXYToRectangle(x, y, level); + return defined(Rectangle.intersection(tileRectangle, rectangle, rectangleScratch)); + } + + /** + * Determines whether data for a tile is available to be loaded. + * + * @param {Number} x The X coordinate of the tile for which to request geometry. + * @param {Number} y The Y coordinate of the tile for which to request geometry. + * @param {Number} level The level of the tile for which to request geometry. + * @returns {Boolean} Undefined if not supported, otherwise true or false. + */ + VRTheWorldTerrainProvider.prototype.getTileDataAvailable = function(x, y, level) { + return undefined; }; - return CubeMap; + return VRTheWorldTerrainProvider; }); -define('Renderer/Texture',[ - '../Core/Cartesian2', - '../Core/Check', - '../Core/createGuid', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Math', - '../Core/PixelFormat', - '../Core/WebGLConstants', - './ContextLimits', - './MipmapHint', - './PixelDatatype', - './Sampler', - './TextureMagnificationFilter', - './TextureMinificationFilter' +define('Core/WallGeometryLibrary',[ + './Cartographic', + './defined', + './EllipsoidTangentPlane', + './Math', + './PolygonPipeline', + './PolylinePipeline', + './WindingOrder' ], function( - Cartesian2, - Check, - createGuid, - defaultValue, + Cartographic, defined, - defineProperties, - destroyObject, - DeveloperError, + EllipsoidTangentPlane, CesiumMath, - PixelFormat, - WebGLConstants, - ContextLimits, - MipmapHint, - PixelDatatype, - Sampler, - TextureMagnificationFilter, - TextureMinificationFilter) { + PolygonPipeline, + PolylinePipeline, + WindingOrder) { 'use strict'; - function Texture(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + /** + * private + */ + var WallGeometryLibrary = {}; - Check.defined('options.context', options.context); - - var context = options.context; - var width = options.width; - var height = options.height; - var source = options.source; + function latLonEquals(c0, c1) { + return ((CesiumMath.equalsEpsilon(c0.latitude, c1.latitude, CesiumMath.EPSILON14)) && (CesiumMath.equalsEpsilon(c0.longitude, c1.longitude, CesiumMath.EPSILON14))); + } - if (defined(source)) { - if (!defined(width)) { - width = defaultValue(source.videoWidth, source.width); - } - if (!defined(height)) { - height = defaultValue(source.videoHeight, source.height); - } + var scratchCartographic1 = new Cartographic(); + var scratchCartographic2 = new Cartographic(); + function removeDuplicates(ellipsoid, positions, topHeights, bottomHeights) { + var length = positions.length; + if (length < 2) { + return; } - var pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGBA); - var pixelDatatype = defaultValue(options.pixelDatatype, PixelDatatype.UNSIGNED_BYTE); - var internalFormat = pixelFormat; + var hasBottomHeights = defined(bottomHeights); + var hasTopHeights = defined(topHeights); + var hasAllZeroHeights = true; - var isCompressed = PixelFormat.isCompressedFormat(internalFormat); + var cleanedPositions = new Array(length); + var cleanedTopHeights = new Array(length); + var cleanedBottomHeights = new Array(length); - if (context.webgl2) { - if (pixelFormat === PixelFormat.DEPTH_STENCIL) { - internalFormat = WebGLConstants.DEPTH24_STENCIL8; - } else if (pixelFormat === PixelFormat.DEPTH_COMPONENT) { - if (pixelDatatype === PixelDatatype.UNSIGNED_SHORT) { - internalFormat = WebGLConstants.DEPTH_COMPONENT16; - } else if (pixelDatatype === PixelDatatype.UNSIGNED_INT) { - internalFormat = WebGLConstants.DEPTH_COMPONENT24; - } - } + var v0 = positions[0]; + cleanedPositions[0] = v0; - if (pixelDatatype === PixelDatatype.FLOAT) { - switch (pixelFormat) { - case PixelFormat.RGBA: - internalFormat = WebGLConstants.RGBA32F; - break; - case PixelFormat.RGB: - internalFormat = WebGLConstants.RGB32F; - break; - case PixelFormat.RG: - internalFormat = WebGLConstants.RG32F; - break; - case PixelFormat.R: - internalFormat = WebGLConstants.R32F; - break; - } - } + var c0 = ellipsoid.cartesianToCartographic(v0, scratchCartographic1); + if (hasTopHeights) { + c0.height = topHeights[0]; } - if (!defined(width) || !defined(height)) { - throw new DeveloperError('options requires a source field to create an initialized texture or width and height fields to create a blank texture.'); - } + hasAllZeroHeights = hasAllZeroHeights && c0.height <= 0; - Check.typeOf.number.greaterThan('width', width, 0); + cleanedTopHeights[0] = c0.height; - if (width > ContextLimits.maximumTextureSize) { - throw new DeveloperError('Width must be less than or equal to the maximum texture size (' + ContextLimits.maximumTextureSize + '). Check maximumTextureSize.'); + if (hasBottomHeights) { + cleanedBottomHeights[0] = bottomHeights[0]; + } else { + cleanedBottomHeights[0] = 0.0; } - Check.typeOf.number.greaterThan('height', height, 0); + var index = 1; + for (var i = 1; i < length; ++i) { + var v1 = positions[i]; + var c1 = ellipsoid.cartesianToCartographic(v1, scratchCartographic2); + if (hasTopHeights) { + c1.height = topHeights[i]; + } + hasAllZeroHeights = hasAllZeroHeights && c1.height <= 0; - if (height > ContextLimits.maximumTextureSize) { - throw new DeveloperError('Height must be less than or equal to the maximum texture size (' + ContextLimits.maximumTextureSize + '). Check maximumTextureSize.'); - } + if (!latLonEquals(c0, c1)) { + cleanedPositions[index] = v1; // Shallow copy! + cleanedTopHeights[index] = c1.height; - if (!PixelFormat.validate(pixelFormat)) { - throw new DeveloperError('Invalid options.pixelFormat.'); - } + if (hasBottomHeights) { + cleanedBottomHeights[index] = bottomHeights[i]; + } else { + cleanedBottomHeights[index] = 0.0; + } - if (!isCompressed && !PixelDatatype.validate(pixelDatatype)) { - throw new DeveloperError('Invalid options.pixelDatatype.'); + Cartographic.clone(c1, c0); + ++index; + } else if (c0.height < c1.height) { + cleanedTopHeights[index - 1] = c1.height; + } } - if ((pixelFormat === PixelFormat.DEPTH_COMPONENT) && - ((pixelDatatype !== PixelDatatype.UNSIGNED_SHORT) && (pixelDatatype !== PixelDatatype.UNSIGNED_INT))) { - throw new DeveloperError('When options.pixelFormat is DEPTH_COMPONENT, options.pixelDatatype must be UNSIGNED_SHORT or UNSIGNED_INT.'); + if (hasAllZeroHeights || index < 2) { + return; } - if ((pixelFormat === PixelFormat.DEPTH_STENCIL) && (pixelDatatype !== PixelDatatype.UNSIGNED_INT_24_8)) { - throw new DeveloperError('When options.pixelFormat is DEPTH_STENCIL, options.pixelDatatype must be UNSIGNED_INT_24_8.'); - } + cleanedPositions.length = index; + cleanedTopHeights.length = index; + cleanedBottomHeights.length = index; - if ((pixelDatatype === PixelDatatype.FLOAT) && !context.floatingPointTexture) { - throw new DeveloperError('When options.pixelDatatype is FLOAT, this WebGL implementation must support the OES_texture_float extension. Check context.floatingPointTexture.'); + return { + positions: cleanedPositions, + topHeights: cleanedTopHeights, + bottomHeights: cleanedBottomHeights + }; + } + + var positionsArrayScratch = new Array(2); + var heightsArrayScratch = new Array(2); + var generateArcOptionsScratch = { + positions : undefined, + height : undefined, + granularity : undefined, + ellipsoid : undefined + }; + + /** + * @private + */ + WallGeometryLibrary.computePositions = function(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, duplicateCorners) { + var o = removeDuplicates(ellipsoid, wallPositions, maximumHeights, minimumHeights); + + if (!defined(o)) { + return; } - if (PixelFormat.isDepthFormat(pixelFormat)) { - if (defined(source)) { - throw new DeveloperError('When options.pixelFormat is DEPTH_COMPONENT or DEPTH_STENCIL, source cannot be provided.'); - } + wallPositions = o.positions; + maximumHeights = o.topHeights; + minimumHeights = o.bottomHeights; - if (!context.depthTexture) { - throw new DeveloperError('When options.pixelFormat is DEPTH_COMPONENT or DEPTH_STENCIL, this WebGL implementation must support WEBGL_depth_texture. Check context.depthTexture.'); + if (wallPositions.length >= 3) { + // Order positions counter-clockwise + var tangentPlane = EllipsoidTangentPlane.fromPoints(wallPositions, ellipsoid); + var positions2D = tangentPlane.projectPointsOntoPlane(wallPositions); + + if (PolygonPipeline.computeWindingOrder2D(positions2D) === WindingOrder.CLOCKWISE) { + wallPositions.reverse(); + maximumHeights.reverse(); + minimumHeights.reverse(); } } - if (isCompressed) { - if (!defined(source) || !defined(source.arrayBufferView)) { - throw new DeveloperError('When options.pixelFormat is compressed, options.source.arrayBufferView must be defined.'); - } + var length = wallPositions.length; + var numCorners = length - 2; + var topPositions; + var bottomPositions; - if (PixelFormat.isDXTFormat(internalFormat) && !context.s3tc) { - throw new DeveloperError('When options.pixelFormat is S3TC compressed, this WebGL implementation must support the WEBGL_texture_compression_s3tc extension. Check context.s3tc.'); - } else if (PixelFormat.isPVRTCFormat(internalFormat) && !context.pvrtc) { - throw new DeveloperError('When options.pixelFormat is PVRTC compressed, this WebGL implementation must support the WEBGL_texture_compression_pvrtc extension. Check context.pvrtc.'); - } else if (PixelFormat.isETC1Format(internalFormat) && !context.etc1) { - throw new DeveloperError('When options.pixelFormat is ETC1 compressed, this WebGL implementation must support the WEBGL_texture_compression_etc1 extension. Check context.etc1.'); - } + var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); - if (PixelFormat.compressedTextureSizeInBytes(internalFormat, width, height) !== source.arrayBufferView.byteLength) { - throw new DeveloperError('The byte length of the array buffer is invalid for the compressed texture with the given width and height.'); + var generateArcOptions = generateArcOptionsScratch; + generateArcOptions.minDistance = minDistance; + generateArcOptions.ellipsoid = ellipsoid; + + if (duplicateCorners) { + var count = 0; + var i; + + for (i = 0; i < length - 1; i++) { + count += PolylinePipeline.numberOfPoints(wallPositions[i], wallPositions[i+1], minDistance) + 1; } - } - - // Use premultiplied alpha for opaque textures should perform better on Chrome: - // http://media.tojicode.com/webglCamp4/#20 - var preMultiplyAlpha = options.preMultiplyAlpha || pixelFormat === PixelFormat.RGB || pixelFormat === PixelFormat.LUMINANCE; - var flipY = defaultValue(options.flipY, true); - var gl = context._gl; - var textureTarget = gl.TEXTURE_2D; - var texture = gl.createTexture(); + topPositions = new Float64Array(count * 3); + bottomPositions = new Float64Array(count * 3); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(textureTarget, texture); + var generateArcPositions = positionsArrayScratch; + var generateArcHeights = heightsArrayScratch; + generateArcOptions.positions = generateArcPositions; + generateArcOptions.height = generateArcHeights; - if (defined(source)) { - // TODO: _gl.pixelStorei(_gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); + var offset = 0; + for (i = 0; i < length - 1; i++) { + generateArcPositions[0] = wallPositions[i]; + generateArcPositions[1] = wallPositions[i + 1]; - if (defined(source.arrayBufferView)) { - // Source: typed array - if (isCompressed) { - gl.compressedTexImage2D(textureTarget, 0, internalFormat, width, height, 0, source.arrayBufferView); - } else { - gl.texImage2D(textureTarget, 0, internalFormat, width, height, 0, pixelFormat, pixelDatatype, source.arrayBufferView); - } - } else if (defined(source.framebuffer)) { - // Source: framebuffer - if (source.framebuffer !== context.defaultFramebuffer) { - source.framebuffer._bind(); - } + generateArcHeights[0] = maximumHeights[i]; + generateArcHeights[1] = maximumHeights[i + 1]; - gl.copyTexImage2D(textureTarget, 0, internalFormat, source.xOffset, source.yOffset, width, height, 0); + var pos = PolylinePipeline.generateArc(generateArcOptions); + topPositions.set(pos, offset); - if (source.framebuffer !== context.defaultFramebuffer) { - source.framebuffer._unBind(); - } - } else { - // Source: ImageData, HTMLImageElement, HTMLCanvasElement, or HTMLVideoElement - gl.texImage2D(textureTarget, 0, internalFormat, pixelFormat, pixelDatatype, source); + generateArcHeights[0] = minimumHeights[i]; + generateArcHeights[1] = minimumHeights[i + 1]; + + bottomPositions.set(PolylinePipeline.generateArc(generateArcOptions), offset); + + offset += pos.length; } } else { - gl.texImage2D(textureTarget, 0, internalFormat, width, height, 0, pixelFormat, pixelDatatype, null); - } - gl.bindTexture(textureTarget, null); + generateArcOptions.positions = wallPositions; + generateArcOptions.height = maximumHeights; + topPositions = new Float64Array(PolylinePipeline.generateArc(generateArcOptions)); - var sizeInBytes; - if (isCompressed) { - sizeInBytes = PixelFormat.compressedTextureSizeInBytes(pixelFormat, width, height); - } else { - sizeInBytes = PixelFormat.textureSizeInBytes(pixelFormat, pixelDatatype, width, height); + generateArcOptions.height = minimumHeights; + bottomPositions = new Float64Array(PolylinePipeline.generateArc(generateArcOptions)); } - this._id = createGuid(); - this._context = context; - this._textureFilterAnisotropic = context._textureFilterAnisotropic; - this._textureTarget = textureTarget; - this._texture = texture; - this._pixelFormat = pixelFormat; - this._pixelDatatype = pixelDatatype; - this._width = width; - this._height = height; - this._dimensions = new Cartesian2(width, height); - this._hasMipmap = false; - this._sizeInBytes = sizeInBytes; - this._preMultiplyAlpha = preMultiplyAlpha; - this._flipY = flipY; - this._sampler = undefined; + return { + bottomPositions: bottomPositions, + topPositions: topPositions, + numCorners: numCorners + }; + }; - this.sampler = defined(options.sampler) ? options.sampler : new Sampler(); - } + return WallGeometryLibrary; +}); + +define('Core/WallGeometry',[ + './BoundingSphere', + './Cartesian3', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PrimitiveType', + './VertexFormat', + './WallGeometryLibrary' + ], function( + BoundingSphere, + Cartesian3, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PrimitiveType, + VertexFormat, + WallGeometryLibrary) { + 'use strict'; + + var scratchCartesian3Position1 = new Cartesian3(); + var scratchCartesian3Position2 = new Cartesian3(); + var scratchCartesian3Position3 = new Cartesian3(); + var scratchCartesian3Position4 = new Cartesian3(); + var scratchCartesian3Position5 = new Cartesian3(); + var scratchBitangent = new Cartesian3(); + var scratchTangent = new Cartesian3(); + var scratchNormal = new Cartesian3(); /** - * Creates a texture, and copies a subimage of the framebuffer to it. When called without arguments, - * the texture is the same width and height as the framebuffer and contains its contents. + * A description of a wall, which is similar to a KML line string. A wall is defined by a series of points, + * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. + * + * @alias WallGeometry + * @constructor * * @param {Object} options Object with the following properties: - * @param {Context} options.context The context in which the Texture gets created. - * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGB] The texture's internal pixel format. - * @param {Number} [options.framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. - * @param {Number} [options.framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. - * @param {Number} [options.width=canvas.clientWidth] The width of the texture in texels. - * @param {Number} [options.height=canvas.clientHeight] The height of the texture in texels. - * @param {Framebuffer} [options.framebuffer=defaultFramebuffer] The framebuffer from which to create the texture. If this - * parameter is not specified, the default framebuffer is used. - * @returns {Texture} A texture with contents from the framebuffer. + * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the + * wall at <code>positions</code>. If undefined, the height of each position in used. + * @param {Number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the + * wall at <code>positions</code>. If undefined, the height at each position is 0.0. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * - * @exception {DeveloperError} Invalid pixelFormat. - * @exception {DeveloperError} pixelFormat cannot be DEPTH_COMPONENT, DEPTH_STENCIL or a compressed format. - * @exception {DeveloperError} framebufferXOffset must be greater than or equal to zero. - * @exception {DeveloperError} framebufferYOffset must be greater than or equal to zero. - * @exception {DeveloperError} framebufferXOffset + width must be less than or equal to canvas.clientWidth. - * @exception {DeveloperError} framebufferYOffset + height must be less than or equal to canvas.clientHeight. + * @exception {DeveloperError} positions length must be greater than or equal to 2. + * @exception {DeveloperError} positions and maximumHeights must have the same length. + * @exception {DeveloperError} positions and minimumHeights must have the same length. * + * @see WallGeometry#createGeometry + * @see WallGeometry#fromConstantHeight + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo} * * @example - * // Create a texture with the contents of the framebuffer. - * var t = Texture.fromFramebuffer({ - * context : context + * // create a wall that spans from ground level to 10000 meters + * var wall = new Cesium.WallGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArrayHeights([ + * 19.0, 47.0, 10000.0, + * 19.0, 48.0, 10000.0, + * 20.0, 48.0, 10000.0, + * 20.0, 47.0, 10000.0, + * 19.0, 47.0, 10000.0 + * ]) * }); - * - * @see Sampler - * - * @private + * var geometry = Cesium.WallGeometry.createGeometry(wall); */ - Texture.fromFramebuffer = function(options) { + function WallGeometry(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - Check.defined('options.context', options.context); - - var context = options.context; - var gl = context._gl; - - var pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGB); - var framebufferXOffset = defaultValue(options.framebufferXOffset, 0); - var framebufferYOffset = defaultValue(options.framebufferYOffset, 0); - var width = defaultValue(options.width, gl.drawingBufferWidth); - var height = defaultValue(options.height, gl.drawingBufferHeight); - var framebuffer = options.framebuffer; + var wallPositions = options.positions; + var maximumHeights = options.maximumHeights; + var minimumHeights = options.minimumHeights; - if (!PixelFormat.validate(pixelFormat)) { - throw new DeveloperError('Invalid pixelFormat.'); - } - if (PixelFormat.isDepthFormat(pixelFormat) || PixelFormat.isCompressedFormat(pixelFormat)) { - throw new DeveloperError('pixelFormat cannot be DEPTH_COMPONENT, DEPTH_STENCIL or a compressed format.'); + if (!defined(wallPositions)) { + throw new DeveloperError('options.positions is required.'); } - Check.defined('options.context', options.context); - Check.typeOf.number.greaterThanOrEquals('framebufferXOffset', framebufferXOffset, 0); - Check.typeOf.number.greaterThanOrEquals('framebufferYOffset', framebufferYOffset, 0); - if (framebufferXOffset + width > gl.drawingBufferWidth) { - throw new DeveloperError('framebufferXOffset + width must be less than or equal to drawingBufferWidth'); + if (defined(maximumHeights) && maximumHeights.length !== wallPositions.length) { + throw new DeveloperError('options.positions and options.maximumHeights must have the same length.'); } - if (framebufferYOffset + height > gl.drawingBufferHeight) { - throw new DeveloperError('framebufferYOffset + height must be less than or equal to drawingBufferHeight.'); + if (defined(minimumHeights) && minimumHeights.length !== wallPositions.length) { + throw new DeveloperError('options.positions and options.minimumHeights must have the same length.'); } - var texture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : pixelFormat, - source : { - framebuffer : defined(framebuffer) ? framebuffer : context.defaultFramebuffer, - xOffset : framebufferXOffset, - yOffset : framebufferYOffset, - width : width, - height : height - } - }); + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - return texture; - }; + this._positions = wallPositions; + this._minimumHeights = minimumHeights; + this._maximumHeights = maximumHeights; + this._vertexFormat = VertexFormat.clone(vertexFormat); + this._granularity = granularity; + this._ellipsoid = Ellipsoid.clone(ellipsoid); + this._workerName = 'createWallGeometry'; + + var numComponents = 1 + wallPositions.length * Cartesian3.packedLength + 2; + if (defined(minimumHeights)) { + numComponents += minimumHeights.length; + } + if (defined(maximumHeights)) { + numComponents += maximumHeights.length; + } - defineProperties(Texture.prototype, { - /** - * A unique id for the texture - * @memberof Texture.prototype - * @type {String} - * @readonly - * @private - */ - id : { - get : function() { - return this._id; - } - }, /** - * The sampler to use when sampling this texture. - * Create a sampler by calling {@link Sampler}. If this - * parameter is not specified, a default sampler is used. The default sampler clamps texture - * coordinates in both directions, uses linear filtering for both magnification and minifcation, - * and uses a maximum anisotropy of 1.0. - * @memberof Texture.prototype - * @type {Object} + * The number of elements used to pack the object into an array. + * @type {Number} */ - sampler : { - get : function() { - return this._sampler; - }, - set : function(sampler) { - var minificationFilter = sampler.minificationFilter; - var magnificationFilter = sampler.magnificationFilter; + this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 1; + } - var mipmap = - (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || - (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || - (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || - (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR); + /** + * Stores the provided instance into the provided array. + * + * @param {WallGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + WallGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - // float textures only support nearest filtering, so override the sampler's settings - if (this._pixelDatatype === PixelDatatype.FLOAT) { - minificationFilter = mipmap ? TextureMinificationFilter.NEAREST_MIPMAP_NEAREST : TextureMinificationFilter.NEAREST; - magnificationFilter = TextureMagnificationFilter.NEAREST; - } + var i; - var gl = this._context._gl; - var target = this._textureTarget; + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); - gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, minificationFilter); - gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, magnificationFilter); - gl.texParameteri(target, gl.TEXTURE_WRAP_S, sampler.wrapS); - gl.texParameteri(target, gl.TEXTURE_WRAP_T, sampler.wrapT); - if (defined(this._textureFilterAnisotropic)) { - gl.texParameteri(target, this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, sampler.maximumAnisotropy); - } - gl.bindTexture(target, null); + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); + } - this._sampler = sampler; - } - }, - pixelFormat : { - get : function() { - return this._pixelFormat; - } - }, - pixelDatatype : { - get : function() { - return this._pixelDatatype; - } - }, - dimensions : { - get : function() { - return this._dimensions; - } - }, - preMultiplyAlpha : { - get : function() { - return this._preMultiplyAlpha; - } - }, - flipY : { - get : function() { - return this._flipY; - } - }, - width : { - get : function() { - return this._width; - } - }, - height : { - get : function() { - return this._height; - } - }, - sizeInBytes : { - get : function() { - if (this._hasMipmap) { - return Math.floor(this._sizeInBytes * 4 / 3); - } - return this._sizeInBytes; + var minimumHeights = value._minimumHeights; + length = defined(minimumHeights) ? minimumHeights.length : 0; + array[startingIndex++] = length; + + if (defined(minimumHeights)) { + for (i = 0; i < length; ++i) { + array[startingIndex++] = minimumHeights[i]; } - }, - _target : { - get : function() { - return this._textureTarget; + } + + var maximumHeights = value._maximumHeights; + length = defined(maximumHeights) ? maximumHeights.length : 0; + array[startingIndex++] = length; + + if (defined(maximumHeights)) { + for (i = 0; i < length; ++i) { + array[startingIndex++] = maximumHeights[i]; } } - }); + + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; + + VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + + array[startingIndex] = value._granularity; + + return array; + }; + + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchVertexFormat = new VertexFormat(); + var scratchOptions = { + positions : undefined, + minimumHeights : undefined, + maximumHeights : undefined, + ellipsoid : scratchEllipsoid, + vertexFormat : scratchVertexFormat, + granularity : undefined + }; /** - * Copy new image data into this texture, from a source {@link ImageData}, {@link Image}, {@link Canvas}, or {@link Video}. - * or an object with width, height, and arrayBufferView properties. - * - * @param {Object} source The source {@link ImageData}, {@link Image}, {@link Canvas}, or {@link Video}, - * or an object with width, height, and arrayBufferView properties. - * @param {Number} [xOffset=0] The offset in the x direction within the texture to copy into. - * @param {Number} [yOffset=0] The offset in the y direction within the texture to copy into. - * - * @exception {DeveloperError} Cannot call copyFrom when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. - * @exception {DeveloperError} Cannot call copyFrom with a compressed texture pixel format. - * @exception {DeveloperError} xOffset must be greater than or equal to zero. - * @exception {DeveloperError} yOffset must be greater than or equal to zero. - * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. - * @exception {DeveloperError} yOffset + source.height must be less than or equal to height. - * @exception {DeveloperError} This texture was destroyed, i.e., destroy() was called. + * Retrieves an instance from a packed array. * - * @example - * texture.copyFrom({ - * width : 1, - * height : 1, - * arrayBufferView : new Uint8Array([255, 0, 0, 255]) - * }); + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {WallGeometry} [result] The object into which to store the result. + * @returns {WallGeometry} The modified result parameter or a new WallGeometry instance if one was not provided. */ - Texture.prototype.copyFrom = function(source, xOffset, yOffset) { - xOffset = defaultValue(xOffset, 0); - yOffset = defaultValue(yOffset, 0); + WallGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - Check.defined('source', source); - if (PixelFormat.isDepthFormat(this._pixelFormat)) { - throw new DeveloperError('Cannot call copyFrom when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL.'); + var i; + + var length = array[startingIndex++]; + var positions = new Array(length); + + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); } - if (PixelFormat.isCompressedFormat(this._pixelFormat)) { - throw new DeveloperError('Cannot call copyFrom with a compressed texture pixel format.'); + + length = array[startingIndex++]; + var minimumHeights; + + if (length > 0) { + minimumHeights = new Array(length); + for (i = 0; i < length; ++i) { + minimumHeights[i] = array[startingIndex++]; + } } - Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); - Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); - Check.typeOf.number.lessThanOrEquals('xOffset + source.width', xOffset + source.width, this._width); - Check.typeOf.number.lessThanOrEquals('yOffset + source.height', yOffset + source.height, this._height); - - var gl = this._context._gl; - var target = this._textureTarget; - // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); + length = array[startingIndex++]; + var maximumHeights; - if (source.arrayBufferView) { - gl.texSubImage2D(target, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); - } else { - gl.texSubImage2D(target, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); + if (length > 0) { + maximumHeights = new Array(length); + for (i = 0; i < length; ++i) { + maximumHeights[i] = array[startingIndex++]; + } } - gl.bindTexture(target, null); + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; + + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; + + var granularity = array[startingIndex]; + + if (!defined(result)) { + scratchOptions.positions = positions; + scratchOptions.minimumHeights = minimumHeights; + scratchOptions.maximumHeights = maximumHeights; + scratchOptions.granularity = granularity; + return new WallGeometry(scratchOptions); + } + + result._positions = positions; + result._minimumHeights = minimumHeights; + result._maximumHeights = maximumHeights; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._granularity = granularity; + + return result; }; /** - * @param {Number} [xOffset=0] The offset in the x direction within the texture to copy into. - * @param {Number} [yOffset=0] The offset in the y direction within the texture to copy into. - * @param {Number} [framebufferXOffset=0] optional - * @param {Number} [framebufferYOffset=0] optional - * @param {Number} [width=width] optional - * @param {Number} [height=height] optional + * A description of a wall, which is similar to a KML line string. A wall is defined by a series of points, + * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. * - * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. - * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT. - * @exception {DeveloperError} Cannot call copyFrom with a compressed texture pixel format. - * @exception {DeveloperError} This texture was destroyed, i.e., destroy() was called. - * @exception {DeveloperError} xOffset must be greater than or equal to zero. - * @exception {DeveloperError} yOffset must be greater than or equal to zero. - * @exception {DeveloperError} framebufferXOffset must be greater than or equal to zero. - * @exception {DeveloperError} framebufferYOffset must be greater than or equal to zero. - * @exception {DeveloperError} xOffset + width must be less than or equal to width. - * @exception {DeveloperError} yOffset + height must be less than or equal to height. + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. + * @param {Number} [options.maximumHeight] A constant that defines the maximum height of the + * wall at <code>positions</code>. If undefined, the height of each position in used. + * @param {Number} [options.minimumHeight] A constant that defines the minimum height of the + * wall at <code>positions</code>. If undefined, the height at each position is 0.0. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + * @returns {WallGeometry} + * + * + * @example + * // create a wall that spans from 10000 meters to 20000 meters + * var wall = Cesium.WallGeometry.fromConstantHeights({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * 19.0, 47.0, + * 19.0, 48.0, + * 20.0, 48.0, + * 20.0, 47.0, + * 19.0, 47.0, + * ]), + * minimumHeight : 20000.0, + * maximumHeight : 10000.0 + * }); + * var geometry = Cesium.WallGeometry.createGeometry(wall); + * + * @see WallGeometry#createGeometry */ - Texture.prototype.copyFromFramebuffer = function(xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height) { - xOffset = defaultValue(xOffset, 0); - yOffset = defaultValue(yOffset, 0); - framebufferXOffset = defaultValue(framebufferXOffset, 0); - framebufferYOffset = defaultValue(framebufferYOffset, 0); - width = defaultValue(width, this._width); - height = defaultValue(height, this._height); + WallGeometry.fromConstantHeights = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.positions; - if (PixelFormat.isDepthFormat(this._pixelFormat)) { - throw new DeveloperError('Cannot call copyFromFramebuffer when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL.'); - } - if (this._pixelDatatype === PixelDatatype.FLOAT) { - throw new DeveloperError('Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT.'); - } - if (PixelFormat.isCompressedFormat(this._pixelFormat)) { - throw new DeveloperError('Cannot call copyFrom with a compressed texture pixel format.'); + if (!defined(positions)) { + throw new DeveloperError('options.positions is required.'); } - - Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); - Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); - Check.typeOf.number.greaterThanOrEquals('framebufferXOffset', framebufferXOffset, 0); - Check.typeOf.number.greaterThanOrEquals('framebufferYOffset', framebufferYOffset, 0); - Check.typeOf.number.lessThanOrEquals('xOffset + width', xOffset + width, this._width); - Check.typeOf.number.lessThanOrEquals('yOffset + height', yOffset + height, this._height); - var gl = this._context._gl; - var target = this._textureTarget; + var minHeights; + var maxHeights; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); - gl.copyTexSubImage2D(target, 0, xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height); - gl.bindTexture(target, null); + var min = options.minimumHeight; + var max = options.maximumHeight; + + var doMin = defined(min); + var doMax = defined(max); + if (doMin || doMax) { + var length = positions.length; + minHeights = (doMin) ? new Array(length) : undefined; + maxHeights = (doMax) ? new Array(length) : undefined; + + for (var i = 0; i < length; ++i) { + if (doMin) { + minHeights[i] = min; + } + + if (doMax) { + maxHeights[i] = max; + } + } + } + + var newOptions = { + positions : positions, + maximumHeights : maxHeights, + minimumHeights : minHeights, + ellipsoid : options.ellipsoid, + vertexFormat : options.vertexFormat + }; + return new WallGeometry(newOptions); }; /** - * @param {MipmapHint} [hint=MipmapHint.DONT_CARE] optional. + * Computes the geometric representation of a wall, including its vertices, indices, and a bounding sphere. * - * @exception {DeveloperError} Cannot call generateMipmap when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. - * @exception {DeveloperError} Cannot call generateMipmap when the texture pixel format is a compressed format. - * @exception {DeveloperError} hint is invalid. - * @exception {DeveloperError} This texture's width must be a power of two to call generateMipmap(). - * @exception {DeveloperError} This texture's height must be a power of two to call generateMipmap(). - * @exception {DeveloperError} This texture was destroyed, i.e., destroy() was called. + * @param {WallGeometry} wallGeometry A description of the wall. + * @returns {Geometry|undefined} The computed vertices and indices. */ - Texture.prototype.generateMipmap = function(hint) { - hint = defaultValue(hint, MipmapHint.DONT_CARE); + WallGeometry.createGeometry = function(wallGeometry) { + var wallPositions = wallGeometry._positions; + var minimumHeights = wallGeometry._minimumHeights; + var maximumHeights = wallGeometry._maximumHeights; + var vertexFormat = wallGeometry._vertexFormat; + var granularity = wallGeometry._granularity; + var ellipsoid = wallGeometry._ellipsoid; - if (PixelFormat.isDepthFormat(this._pixelFormat)) { - throw new DeveloperError('Cannot call generateMipmap when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL.'); - } - if (PixelFormat.isCompressedFormat(this._pixelFormat)) { - throw new DeveloperError('Cannot call generateMipmap with a compressed pixel format.'); - } - if (this._width > 1 && !CesiumMath.isPowerOfTwo(this._width)) { - throw new DeveloperError('width must be a power of two to call generateMipmap().'); - } - if (this._height > 1 && !CesiumMath.isPowerOfTwo(this._height)) { - throw new DeveloperError('height must be a power of two to call generateMipmap().'); - } - if (!MipmapHint.validate(hint)) { - throw new DeveloperError('hint is invalid.'); + var pos = WallGeometryLibrary.computePositions(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, true); + if (!defined(pos)) { + return; } - - this._hasMipmap = true; - - var gl = this._context._gl; - var target = this._textureTarget; - gl.hint(gl.GENERATE_MIPMAP_HINT, hint); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(target, this._texture); - gl.generateMipmap(target); - gl.bindTexture(target, null); - }; + var bottomPositions = pos.bottomPositions; + var topPositions = pos.topPositions; + var numCorners = pos.numCorners; - Texture.prototype.isDestroyed = function() { - return false; - }; + var length = topPositions.length; + var size = length * 2; - Texture.prototype.destroy = function() { - this._context._gl.deleteTexture(this._texture); - return destroyObject(this); - }; + var positions = vertexFormat.position ? new Float64Array(size) : undefined; + var normals = vertexFormat.normal ? new Float32Array(size) : undefined; + var tangents = vertexFormat.tangent ? new Float32Array(size) : undefined; + var bitangents = vertexFormat.bitangent ? new Float32Array(size) : undefined; + var textureCoordinates = vertexFormat.st ? new Float32Array(size / 3 * 2) : undefined; - return Texture; -}); + var positionIndex = 0; + var normalIndex = 0; + var bitangentIndex = 0; + var tangentIndex = 0; + var stIndex = 0; -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/BumpMapMaterial',[],function() { - 'use strict'; - return "uniform sampler2D image;\n\ -uniform float strength;\n\ -uniform vec2 repeat;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -vec2 centerPixel = fract(repeat * st);\n\ -float centerBump = texture2D(image, centerPixel).channel;\n\ -float imageWidth = float(imageDimensions.x);\n\ -vec2 rightPixel = fract(repeat * (st + vec2(1.0 / imageWidth, 0.0)));\n\ -float rightBump = texture2D(image, rightPixel).channel;\n\ -float imageHeight = float(imageDimensions.y);\n\ -vec2 leftPixel = fract(repeat * (st + vec2(0.0, 1.0 / imageHeight)));\n\ -float topBump = texture2D(image, leftPixel).channel;\n\ -vec3 normalTangentSpace = normalize(vec3(centerBump - rightBump, centerBump - topBump, clamp(1.0 - strength, 0.1, 1.0)));\n\ -vec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\n\ -material.normal = normalEC;\n\ -material.diffuse = vec3(0.01);\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/CheckerboardMaterial',[],function() { - 'use strict'; - return "uniform vec4 lightColor;\n\ -uniform vec4 darkColor;\n\ -uniform vec2 repeat;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -float b = mod(floor(repeat.s * st.s) + floor(repeat.t * st.t), 2.0);\n\ -float scaledWidth = fract(repeat.s * st.s);\n\ -scaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\n\ -float scaledHeight = fract(repeat.t * st.t);\n\ -scaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\n\ -float value = min(scaledWidth, scaledHeight);\n\ -vec4 currentColor = mix(lightColor, darkColor, b);\n\ -vec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03);\n\ -material.diffuse = color.rgb;\n\ -material.alpha = color.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/DotMaterial',[],function() { - 'use strict'; - return "uniform vec4 lightColor;\n\ -uniform vec4 darkColor;\n\ -uniform vec2 repeat;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -float b = smoothstep(0.3, 0.32, length(fract(repeat * materialInput.st) - 0.5));\n\ -vec4 color = mix(lightColor, darkColor, b);\n\ -material.diffuse = color.rgb;\n\ -material.alpha = color.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/ElevationContourMaterial',[],function() { - 'use strict'; - return "#ifdef GL_OES_standard_derivatives\n\ -#extension GL_OES_standard_derivatives : enable\n\ -#endif\n\ -uniform vec4 color;\n\ -uniform float spacing;\n\ -uniform float width;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -float distanceToContour = mod(materialInput.height, spacing);\n\ -#ifdef GL_OES_standard_derivatives\n\ -float dxc = abs(dFdx(materialInput.height));\n\ -float dyc = abs(dFdy(materialInput.height));\n\ -float dF = max(dxc, dyc) * width;\n\ -material.alpha = (distanceToContour < dF) ? 1.0 : 0.0;\n\ -#else\n\ -material.alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0;\n\ -#endif\n\ -material.diffuse = color.rgb;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/ElevationRampMaterial',[],function() { - 'use strict'; - return "uniform sampler2D image;\n\ -uniform float minimumHeight;\n\ -uniform float maximumHeight;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -float scaledHeight = clamp((materialInput.height - minimumHeight) / (maximumHeight - minimumHeight), 0.0, 1.0);\n\ -vec4 rampColor = texture2D(image, vec2(scaledHeight, 0.5));\n\ -material.diffuse = rampColor.rgb;\n\ -material.alpha = rampColor.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/FadeMaterial',[],function() { - 'use strict'; - return "uniform vec4 fadeInColor;\n\ -uniform vec4 fadeOutColor;\n\ -uniform float maximumDistance;\n\ -uniform bool repeat;\n\ -uniform vec2 fadeDirection;\n\ -uniform vec2 time;\n\ -float getTime(float t, float coord)\n\ -{\n\ -float scalar = 1.0 / maximumDistance;\n\ -float q = distance(t, coord) * scalar;\n\ -if (repeat)\n\ -{\n\ -float r = distance(t, coord + 1.0) * scalar;\n\ -float s = distance(t, coord - 1.0) * scalar;\n\ -q = min(min(r, s), q);\n\ -}\n\ -return clamp(q, 0.0, 1.0);\n\ -}\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -float s = getTime(time.x, st.s) * fadeDirection.s;\n\ -float t = getTime(time.y, st.t) * fadeDirection.t;\n\ -float u = length(vec2(s, t));\n\ -vec4 color = mix(fadeInColor, fadeOutColor, u);\n\ -material.emission = color.rgb;\n\ -material.alpha = color.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/GridMaterial',[],function() { - 'use strict'; - return "#ifdef GL_OES_standard_derivatives\n\ -#extension GL_OES_standard_derivatives : enable\n\ -#endif\n\ -uniform vec4 color;\n\ -uniform float cellAlpha;\n\ -uniform vec2 lineCount;\n\ -uniform vec2 lineThickness;\n\ -uniform vec2 lineOffset;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -float scaledWidth = fract(lineCount.s * st.s - lineOffset.s);\n\ -scaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\n\ -float scaledHeight = fract(lineCount.t * st.t - lineOffset.t);\n\ -scaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\n\ -float value;\n\ -#ifdef GL_OES_standard_derivatives\n\ -const float fuzz = 1.2;\n\ -vec2 thickness = (lineThickness * czm_resolutionScale) - 1.0;\n\ -vec2 dx = abs(dFdx(st));\n\ -vec2 dy = abs(dFdy(st));\n\ -vec2 dF = vec2(max(dx.s, dy.s), max(dx.t, dy.t)) * lineCount;\n\ -value = min(\n\ -smoothstep(dF.s * thickness.s, dF.s * (fuzz + thickness.s), scaledWidth),\n\ -smoothstep(dF.t * thickness.t, dF.t * (fuzz + thickness.t), scaledHeight));\n\ -#else\n\ -const float fuzz = 0.05;\n\ -vec2 range = 0.5 - (lineThickness * 0.05);\n\ -value = min(\n\ -1.0 - smoothstep(range.s, range.s + fuzz, scaledWidth),\n\ -1.0 - smoothstep(range.t, range.t + fuzz, scaledHeight));\n\ -#endif\n\ -float dRim = 1.0 - abs(dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC)));\n\ -float sRim = smoothstep(0.8, 1.0, dRim);\n\ -value *= (1.0 - sRim);\n\ -vec3 halfColor = color.rgb * 0.5;\n\ -material.diffuse = halfColor;\n\ -material.emission = halfColor;\n\ -material.alpha = color.a * (1.0 - ((1.0 - cellAlpha) * value));\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/NormalMapMaterial',[],function() { - 'use strict'; - return "uniform sampler2D image;\n\ -uniform float strength;\n\ -uniform vec2 repeat;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec4 textureValue = texture2D(image, fract(repeat * materialInput.st));\n\ -vec3 normalTangentSpace = textureValue.channels;\n\ -normalTangentSpace.xy = normalTangentSpace.xy * 2.0 - 1.0;\n\ -normalTangentSpace.z = clamp(1.0 - strength, 0.1, 1.0);\n\ -normalTangentSpace = normalize(normalTangentSpace);\n\ -vec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\n\ -material.normal = normalEC;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/PolylineArrowMaterial',[],function() { - 'use strict'; - return "#ifdef GL_OES_standard_derivatives\n\ -#extension GL_OES_standard_derivatives : enable\n\ -#endif\n\ -uniform vec4 color;\n\ -varying float v_width;\n\ -float getPointOnLine(vec2 p0, vec2 p1, float x)\n\ -{\n\ -float slope = (p0.y - p1.y) / (p0.x - p1.x);\n\ -return slope * (x - p0.x) + p0.y;\n\ -}\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -#ifdef GL_OES_standard_derivatives\n\ -float base = 1.0 - abs(fwidth(st.s)) * 10.0;\n\ -#else\n\ -float base = 0.99;\n\ -#endif\n\ -vec2 center = vec2(1.0, 0.5);\n\ -float ptOnUpperLine = getPointOnLine(vec2(base, 1.0), center, st.s);\n\ -float ptOnLowerLine = getPointOnLine(vec2(base, 0.0), center, st.s);\n\ -float halfWidth = 0.15;\n\ -float s = step(0.5 - halfWidth, st.t);\n\ -s *= 1.0 - step(0.5 + halfWidth, st.t);\n\ -s *= 1.0 - step(base, st.s);\n\ -float t = step(base, materialInput.st.s);\n\ -t *= 1.0 - step(ptOnUpperLine, st.t);\n\ -t *= step(ptOnLowerLine, st.t);\n\ -float dist;\n\ -if (st.s < base)\n\ -{\n\ -float d1 = abs(st.t - (0.5 - halfWidth));\n\ -float d2 = abs(st.t - (0.5 + halfWidth));\n\ -dist = min(d1, d2);\n\ -}\n\ -else\n\ -{\n\ -float d1 = czm_infinity;\n\ -if (st.t < 0.5 - halfWidth && st.t > 0.5 + halfWidth)\n\ -{\n\ -d1 = abs(st.s - base);\n\ -}\n\ -float d2 = abs(st.t - ptOnUpperLine);\n\ -float d3 = abs(st.t - ptOnLowerLine);\n\ -dist = min(min(d1, d2), d3);\n\ -}\n\ -vec4 outsideColor = vec4(0.0);\n\ -vec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0));\n\ -vec4 outColor = czm_antialias(outsideColor, color, currentColor, dist);\n\ -material.diffuse = outColor.rgb;\n\ -material.alpha = outColor.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/PolylineDashMaterial',[],function() { - 'use strict'; - return "uniform vec4 color;\n\ -uniform vec4 gapColor;\n\ -uniform float dashLength;\n\ -uniform float dashPattern;\n\ -varying float v_polylineAngle;\n\ -const float maskLength = 16.0;\n\ -mat2 rotate(float rad) {\n\ -float c = cos(rad);\n\ -float s = sin(rad);\n\ -return mat2(\n\ -c, s,\n\ --s, c\n\ -);\n\ -}\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 pos = rotate(v_polylineAngle) * gl_FragCoord.xy;\n\ -float dashPosition = fract(pos.x / dashLength);\n\ -float maskIndex = floor(dashPosition * maskLength);\n\ -float maskTest = floor(dashPattern / pow(2.0, maskIndex));\n\ -vec4 fragColor = (mod(maskTest, 2.0) < 1.0) ? gapColor : color;\n\ -if (fragColor.a < 0.005) {\n\ -discard;\n\ -}\n\ -material.emission = fragColor.rgb;\n\ -material.alpha = fragColor.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/PolylineGlowMaterial',[],function() { - 'use strict'; - return "uniform vec4 color;\n\ -uniform float glowPower;\n\ -varying float v_width;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -float glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5);\n\ -material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb);\n\ -material.alpha = clamp(0.0, 1.0, glow) * color.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/PolylineOutlineMaterial',[],function() { - 'use strict'; - return "uniform vec4 color;\n\ -uniform vec4 outlineColor;\n\ -uniform float outlineWidth;\n\ -varying float v_width;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec2 st = materialInput.st;\n\ -float halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width;\n\ -float b = step(0.5 - halfInteriorWidth, st.t);\n\ -b *= 1.0 - step(0.5 + halfInteriorWidth, st.t);\n\ -float d1 = abs(st.t - (0.5 - halfInteriorWidth));\n\ -float d2 = abs(st.t - (0.5 + halfInteriorWidth));\n\ -float dist = min(d1, d2);\n\ -vec4 currentColor = mix(outlineColor, color, b);\n\ -vec4 outColor = czm_antialias(outlineColor, color, currentColor, dist);\n\ -material.diffuse = outColor.rgb;\n\ -material.alpha = outColor.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/RimLightingMaterial',[],function() { - 'use strict'; - return "uniform vec4 color;\n\ -uniform vec4 rimColor;\n\ -uniform float width;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -float d = 1.0 - dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC));\n\ -float s = smoothstep(1.0 - width, 1.0, d);\n\ -material.diffuse = color.rgb;\n\ -material.emission = rimColor.rgb * s;\n\ -material.alpha = mix(color.a, rimColor.a, s);\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/SlopeRampMaterial',[],function() { - 'use strict'; - return "uniform sampler2D image;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -vec4 rampColor = texture2D(image, vec2(materialInput.slope, 0.5));\n\ -material.diffuse = rampColor.rgb;\n\ -material.alpha = rampColor.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/StripeMaterial',[],function() { - 'use strict'; - return "uniform vec4 evenColor;\n\ -uniform vec4 oddColor;\n\ -uniform float offset;\n\ -uniform float repeat;\n\ -uniform bool horizontal;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -float coord = mix(materialInput.st.s, materialInput.st.t, float(horizontal));\n\ -float value = fract((coord - offset) * (repeat * 0.5));\n\ -float dist = min(value, min(abs(value - 0.5), 1.0 - value));\n\ -vec4 currentColor = mix(evenColor, oddColor, step(0.5, value));\n\ -vec4 color = czm_antialias(evenColor, oddColor, currentColor, dist);\n\ -material.diffuse = color.rgb;\n\ -material.alpha = color.a;\n\ -return material;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Materials/Water',[],function() { - 'use strict'; - return "uniform sampler2D specularMap;\n\ -uniform sampler2D normalMap;\n\ -uniform vec4 baseWaterColor;\n\ -uniform vec4 blendColor;\n\ -uniform float frequency;\n\ -uniform float animationSpeed;\n\ -uniform float amplitude;\n\ -uniform float specularIntensity;\n\ -uniform float fadeFactor;\n\ -czm_material czm_getMaterial(czm_materialInput materialInput)\n\ -{\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -float time = czm_frameNumber * animationSpeed;\n\ -float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);\n\ -float specularMapValue = texture2D(specularMap, materialInput.st).r;\n\ -vec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);\n\ -vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));\n\ -normalTangentSpace.xy /= fade;\n\ -normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);\n\ -normalTangentSpace = normalize(normalTangentSpace);\n\ -float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);\n\ -material.alpha = specularMapValue;\n\ -material.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);\n\ -material.diffuse += (0.1 * tsPerturbationRatio);\n\ -material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);\n\ -material.specular = specularIntensity;\n\ -material.shininess = 10.0;\n\ -return material;\n\ -}\n\ -"; -}); -define('Scene/Material',[ - '../Core/Cartesian2', - '../Core/clone', - '../Core/Color', - '../Core/combine', - '../Core/createGuid', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/isArray', - '../Core/loadCRN', - '../Core/loadImage', - '../Core/loadKTX', - '../Core/Matrix2', - '../Core/Matrix3', - '../Core/Matrix4', - '../Renderer/CubeMap', - '../Renderer/Texture', - '../Shaders/Materials/BumpMapMaterial', - '../Shaders/Materials/CheckerboardMaterial', - '../Shaders/Materials/DotMaterial', - '../Shaders/Materials/ElevationContourMaterial', - '../Shaders/Materials/ElevationRampMaterial', - '../Shaders/Materials/FadeMaterial', - '../Shaders/Materials/GridMaterial', - '../Shaders/Materials/NormalMapMaterial', - '../Shaders/Materials/PolylineArrowMaterial', - '../Shaders/Materials/PolylineDashMaterial', - '../Shaders/Materials/PolylineGlowMaterial', - '../Shaders/Materials/PolylineOutlineMaterial', - '../Shaders/Materials/RimLightingMaterial', - '../Shaders/Materials/SlopeRampMaterial', - '../Shaders/Materials/StripeMaterial', - '../Shaders/Materials/Water', - '../ThirdParty/when' - ], function( - Cartesian2, - clone, - Color, - combine, - createGuid, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - isArray, - loadCRN, - loadImage, - loadKTX, - Matrix2, - Matrix3, - Matrix4, - CubeMap, - Texture, - BumpMapMaterial, - CheckerboardMaterial, - DotMaterial, - ElevationContourMaterial, - ElevationRampMaterial, - FadeMaterial, - GridMaterial, - NormalMapMaterial, - PolylineArrowMaterial, - PolylineDashMaterial, - PolylineGlowMaterial, - PolylineOutlineMaterial, - RimLightingMaterial, - SlopeRampMaterial, - StripeMaterial, - WaterMaterial, - when) { - 'use strict'; - - /** - * A Material defines surface appearance through a combination of diffuse, specular, - * normal, emission, and alpha components. These values are specified using a - * JSON schema called Fabric which gets parsed and assembled into glsl shader code - * behind-the-scenes. Check out the {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|wiki page} - * for more details on Fabric. - * <br /><br /> - * <style type="text/css"> - * #materialDescriptions code { - * font-weight: normal; - * font-family: Consolas, 'Lucida Console', Monaco, monospace; - * color: #A35A00; - * } - * #materialDescriptions ul, #materialDescriptions ul ul { - * list-style-type: none; - * } - * #materialDescriptions ul ul { - * margin-bottom: 10px; - * } - * #materialDescriptions ul ul li { - * font-weight: normal; - * color: #000000; - * text-indent: -2em; - * margin-left: 2em; - * } - * #materialDescriptions ul li { - * font-weight: bold; - * color: #0053CF; - * } - * </style> - * - * Base material types and their uniforms: - * <div id='materialDescriptions'> - * <ul> - * <li>Color</li> - * <ul> - * <li><code>color</code>: rgba color object.</li> - * </ul> - * <li>Image</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * </ul> - * <li>DiffuseMap</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>channels</code>: Three character string containing any combination of r, g, b, and a for selecting the desired image channels.</li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * </ul> - * <li>AlphaMap</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>channel</code>: One character string containing r, g, b, or a for selecting the desired image channel. </li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * </ul> - * <li>SpecularMap</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>channel</code>: One character string containing r, g, b, or a for selecting the desired image channel. </li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * </ul> - * <li>EmissionMap</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>channels</code>: Three character string containing any combination of r, g, b, and a for selecting the desired image channels. </li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * </ul> - * <li>BumpMap</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>channel</code>: One character string containing r, g, b, or a for selecting the desired image channel. </li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * <li><code>strength</code>: Bump strength value between 0.0 and 1.0 where 0.0 is small bumps and 1.0 is large bumps.</li> - * </ul> - * <li>NormalMap</li> - * <ul> - * <li><code>image</code>: path to image.</li> - * <li><code>channels</code>: Three character string containing any combination of r, g, b, and a for selecting the desired image channels. </li> - * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> - * <li><code>strength</code>: Bump strength value between 0.0 and 1.0 where 0.0 is small bumps and 1.0 is large bumps.</li> - * </ul> - * <li>Grid</li> - * <ul> - * <li><code>color</code>: rgba color object for the whole material.</li> - * <li><code>cellAlpha</code>: Alpha value for the cells between grid lines. This will be combined with color.alpha.</li> - * <li><code>lineCount</code>: Object with x and y values specifying the number of columns and rows respectively.</li> - * <li><code>lineThickness</code>: Object with x and y values specifying the thickness of grid lines (in pixels where available).</li> - * <li><code>lineOffset</code>: Object with x and y values specifying the offset of grid lines (range is 0 to 1).</li> - * </ul> - * <li>Stripe</li> - * <ul> - * <li><code>horizontal</code>: Boolean that determines if the stripes are horizontal or vertical.</li> - * <li><code>evenColor</code>: rgba color object for the stripe's first color.</li> - * <li><code>oddColor</code>: rgba color object for the stripe's second color.</li> - * <li><code>offset</code>: Number that controls at which point into the pattern to begin drawing; with 0.0 being the beginning of the even color, 1.0 the beginning of the odd color, 2.0 being the even color again, and any multiple or fractional values being in between.</li> - * <li><code>repeat</code>: Number that controls the total number of stripes, half light and half dark.</li> - * </ul> - * <li>Checkerboard</li> - * <ul> - * <li><code>lightColor</code>: rgba color object for the checkerboard's light alternating color.</li> - * <li><code>darkColor</code>: rgba color object for the checkerboard's dark alternating color.</li> - * <li><code>repeat</code>: Object with x and y values specifying the number of columns and rows respectively.</li> - * </ul> - * <li>Dot</li> - * <ul> - * <li><code>lightColor</code>: rgba color object for the dot color.</li> - * <li><code>darkColor</code>: rgba color object for the background color.</li> - * <li><code>repeat</code>: Object with x and y values specifying the number of columns and rows of dots respectively.</li> - * </ul> - * <li>Water</li> - * <ul> - * <li><code>baseWaterColor</code>: rgba color object base color of the water.</li> - * <li><code>blendColor</code>: rgba color object used when blending from water to non-water areas.</li> - * <li><code>specularMap</code>: Single channel texture used to indicate areas of water.</li> - * <li><code>normalMap</code>: Normal map for water normal perturbation.</li> - * <li><code>frequency</code>: Number that controls the number of waves.</li> - * <li><code>normalMap</code>: Normal map for water normal perturbation.</li> - * <li><code>animationSpeed</code>: Number that controls the animations speed of the water.</li> - * <li><code>amplitude</code>: Number that controls the amplitude of water waves.</li> - * <li><code>specularIntensity</code>: Number that controls the intensity of specular reflections.</li> - * </ul> - * <li>RimLighting</li> - * <ul> - * <li><code>color</code>: diffuse color and alpha.</li> - * <li><code>rimColor</code>: diffuse color and alpha of the rim.</li> - * <li><code>width</code>: Number that determines the rim's width.</li> - * </ul> - * <li>Fade</li> - * <ul> - * <li><code>fadeInColor</code>: diffuse color and alpha at <code>time</code></li> - * <li><code>fadeOutColor</code>: diffuse color and alpha at <code>maximumDistance</code> from <code>time</code></li> - * <li><code>maximumDistance</code>: Number between 0.0 and 1.0 where the <code>fadeInColor</code> becomes the <code>fadeOutColor</code>. A value of 0.0 gives the entire material a color of <code>fadeOutColor</code> and a value of 1.0 gives the the entire material a color of <code>fadeInColor</code></li> - * <li><code>repeat</code>: true if the fade should wrap around the texture coodinates.</li> - * <li><code>fadeDirection</code>: Object with x and y values specifying if the fade should be in the x and y directions.</li> - * <li><code>time</code>: Object with x and y values between 0.0 and 1.0 of the <code>fadeInColor</code> position</li> - * </ul> - * <li>PolylineArrow</li> - * <ul> - * <li><code>color</code>: diffuse color and alpha.</li> - * </ul> - * <li>PolylineDash</li> - * <ul> - * <li><code>color</code>: color for the line.</li> - * <li><code>gapColor</code>: color for the gaps in the line.</li> - * <li><code>dashLength</code>: Dash length in pixels.</li> - * <li><code>dashPattern</code>: The 16 bit stipple pattern for the line..</li> - * </ul> - * <li>PolylineGlow</li> - * <ul> - * <li><code>color</code>: color and maximum alpha for the glow on the line.</li> - * <li><code>glowPower</code>: strength of the glow, as a percentage of the total line width (less than 1.0).</li> - * </ul> - * <li>PolylineOutline</li> - * <ul> - * <li><code>color</code>: diffuse color and alpha for the interior of the line.</li> - * <li><code>outlineColor</code>: diffuse color and alpha for the outline.</li> - * <li><code>outlineWidth</code>: width of the outline in pixels.</li> - * </ul> - * <li>ElevationContour</li> - * <ul> - * <li><code>color</code>: color and alpha for the contour line.</li> - * <li><code>spacing</code>: spacing for contour lines in meters.</li> - * <li><code>width</code>: Number specifying the width of the grid lines in pixels.</li> - * </ul> - * <li>ElevationRamp</li> - * <ul> - * <li><code>image</code>: color ramp image to use for coloring the terrain.</li> - * <li><code>minimumHeight</code>: minimum height for the ramp.</li> - * <li><code>maximumHeight</code>: maximum height for the ramp.</li> - * </ul> - * <li>SlopeRamp</li> - * <ul> - * <li><code>image</code>: color ramp image to use for coloring the terrain.</li> - * </ul> - * </ul> - * </ul> - * </div> - * - * @alias Material - * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. - * @param {Boolean|Function} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry - * with this material is expected to appear translucent. - * @param {Object} options.fabric The fabric JSON used to generate the material. - * - * @constructor - * - * @exception {DeveloperError} fabric: uniform has invalid type. - * @exception {DeveloperError} fabric: uniforms and materials cannot share the same property. - * @exception {DeveloperError} fabric: cannot have source and components in the same section. - * @exception {DeveloperError} fabric: property name is not valid. It should be 'type', 'materials', 'uniforms', 'components', or 'source'. - * @exception {DeveloperError} fabric: property name is not valid. It should be 'diffuse', 'specular', 'shininess', 'normal', 'emission', or 'alpha'. - * @exception {DeveloperError} strict: shader source does not use string. - * @exception {DeveloperError} strict: shader source does not use uniform. - * @exception {DeveloperError} strict: shader source does not use material. - * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric wiki page} for a more detailed options of Fabric. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Materials.html|Cesium Sandcastle Materials Demo} - * - * @example - * // Create a color material with fromType: - * polygon.material = Cesium.Material.fromType('Color'); - * polygon.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); - * - * // Create the default material: - * polygon.material = new Cesium.Material(); - * - * // Create a color material with full Fabric notation: - * polygon.material = new Cesium.Material({ - * fabric : { - * type : 'Color', - * uniforms : { - * color : new Cesium.Color(1.0, 1.0, 0.0, 1.0) - * } - * } - * }); - */ - function Material(options) { - /** - * The material type. Can be an existing type or a new type. If no type is specified in fabric, type is a GUID. - * @type {String} - * @default undefined - */ - this.type = undefined; - - /** - * The glsl shader source for this material. - * @type {String} - * @default undefined - */ - this.shaderSource = undefined; - - /** - * Maps sub-material names to Material objects. - * @type {Object} - * @default undefined - */ - this.materials = undefined; + // add lower and upper points one after the other, lower + // points being even and upper points being odd + var normal = scratchNormal; + var tangent = scratchTangent; + var bitangent = scratchBitangent; + var recomputeNormal = true; + length /= 3; + var i; + var s = 0; + var ds = 1/(length - wallPositions.length + 1); + for (i = 0; i < length; ++i) { + var i3 = i * 3; + var topPosition = Cartesian3.fromArray(topPositions, i3, scratchCartesian3Position1); + var bottomPosition = Cartesian3.fromArray(bottomPositions, i3, scratchCartesian3Position2); + if (vertexFormat.position) { + // insert the lower point + positions[positionIndex++] = bottomPosition.x; + positions[positionIndex++] = bottomPosition.y; + positions[positionIndex++] = bottomPosition.z; - /** - * Maps uniform names to their values. - * @type {Object} - * @default undefined - */ - this.uniforms = undefined; - this._uniforms = undefined; + // insert the upper point + positions[positionIndex++] = topPosition.x; + positions[positionIndex++] = topPosition.y; + positions[positionIndex++] = topPosition.z; + } - /** - * When <code>true</code> or a function that returns <code>true</code>, - * the geometry is expected to appear translucent. - * @type {Boolean|Function} - * @default undefined - */ - this.translucent = undefined; + if (vertexFormat.st) { + textureCoordinates[stIndex++] = s; + textureCoordinates[stIndex++] = 0.0; - this._strict = undefined; - this._template = undefined; - this._count = undefined; + textureCoordinates[stIndex++] = s; + textureCoordinates[stIndex++] = 1.0; + } - this._texturePaths = {}; - this._loadedImages = []; - this._loadedCubeMaps = []; + if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) { + var nextPosition; + var nextTop = Cartesian3.clone(Cartesian3.ZERO, scratchCartesian3Position5); + var groundPosition = ellipsoid.scaleToGeodeticSurface(Cartesian3.fromArray(topPositions, i3, scratchCartesian3Position2), scratchCartesian3Position2); + if (i + 1 < length) { + nextPosition = ellipsoid.scaleToGeodeticSurface(Cartesian3.fromArray(topPositions, i3 + 3, scratchCartesian3Position3), scratchCartesian3Position3); + nextTop = Cartesian3.fromArray(topPositions, i3 + 3, scratchCartesian3Position5); + } - this._textures = {}; + if (recomputeNormal) { + var scalednextPosition = Cartesian3.subtract(nextTop, topPosition, scratchCartesian3Position4); + var scaledGroundPosition = Cartesian3.subtract(groundPosition, topPosition, scratchCartesian3Position1); + normal = Cartesian3.normalize(Cartesian3.cross(scaledGroundPosition, scalednextPosition, normal), normal); + recomputeNormal = false; + } - this._updateFunctions = []; + if (Cartesian3.equalsEpsilon(nextPosition, groundPosition, CesiumMath.EPSILON10)) { + recomputeNormal = true; + } else { + s += ds; + if (vertexFormat.tangent) { + tangent = Cartesian3.normalize(Cartesian3.subtract(nextPosition, groundPosition, tangent), tangent); + } + if (vertexFormat.bitangent) { + bitangent = Cartesian3.normalize(Cartesian3.cross(normal, tangent, bitangent), bitangent); + } + } - this._defaultTexture = undefined; + if (vertexFormat.normal) { + normals[normalIndex++] = normal.x; + normals[normalIndex++] = normal.y; + normals[normalIndex++] = normal.z; - initializeMaterial(options, this); - defineProperties(this, { - type : { - value : this.type, - writable : false - } - }); + normals[normalIndex++] = normal.x; + normals[normalIndex++] = normal.y; + normals[normalIndex++] = normal.z; + } - if (!defined(Material._uniformList[this.type])) { - Material._uniformList[this.type] = Object.keys(this._uniforms); - } - } + if (vertexFormat.tangent) { + tangents[tangentIndex++] = tangent.x; + tangents[tangentIndex++] = tangent.y; + tangents[tangentIndex++] = tangent.z; - // Cached list of combined uniform names indexed by type. - // Used to get the list of uniforms in the same order. - Material._uniformList = {}; + tangents[tangentIndex++] = tangent.x; + tangents[tangentIndex++] = tangent.y; + tangents[tangentIndex++] = tangent.z; + } - /** - * Creates a new material using an existing material type. - * <br /><br /> - * Shorthand for: new Material({fabric : {type : type}}); - * - * @param {String} type The base material type. - * @param {Object} [uniforms] Overrides for the default uniforms. - * @returns {Material} New material object. - * - * @exception {DeveloperError} material with that type does not exist. - * - * @example - * var material = Cesium.Material.fromType('Color', { - * color : new Cesium.Color(1.0, 0.0, 0.0, 1.0) - * }); - */ - Material.fromType = function(type, uniforms) { - if (!defined(Material._materialCache.getMaterial(type))) { - throw new DeveloperError('material with type \'' + type + '\' does not exist.'); - } - - var material = new Material({ - fabric : { - type : type - } - }); + if (vertexFormat.bitangent) { + bitangents[bitangentIndex++] = bitangent.x; + bitangents[bitangentIndex++] = bitangent.y; + bitangents[bitangentIndex++] = bitangent.z; - if (defined(uniforms)) { - for (var name in uniforms) { - if (uniforms.hasOwnProperty(name)) { - material.uniforms[name] = uniforms[name]; + bitangents[bitangentIndex++] = bitangent.x; + bitangents[bitangentIndex++] = bitangent.y; + bitangents[bitangentIndex++] = bitangent.z; } } } - return material; - }; + var attributes = new GeometryAttributes(); - /** - * Gets whether or not this material is translucent. - * @returns <code>true</code> if this material is translucent, <code>false</code> otherwise. - */ - Material.prototype.isTranslucent = function() { - if (defined(this.translucent)) { - if (typeof this.translucent === 'function') { - return this.translucent(); - } + if (vertexFormat.position) { + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }); + } - return this.translucent; + if (vertexFormat.normal) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); } - var translucent = true; - var funcs = this._translucentFunctions; - var length = funcs.length; - for (var i = 0; i < length; ++i) { - var func = funcs[i]; - if (typeof func === 'function') { - translucent = translucent && func(); - } else { - translucent = translucent && func; - } + if (vertexFormat.tangent) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } - if (!translucent) { - break; - } + if (vertexFormat.bitangent) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); } - return translucent; - }; - /** - * @private - */ - Material.prototype.update = function(context) { - var i; - var uniformId; + if (vertexFormat.st) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : textureCoordinates + }); + } - var loadedImages = this._loadedImages; - var length = loadedImages.length; + // prepare the side walls, two triangles for each wall + // + // A (i+1) B (i+3) E + // +--------+-------+ + // | / | /| triangles: A C B + // | / | / | B C D + // | / | / | + // | / | / | + // | / | / | + // | / | / | + // +--------+-------+ + // C (i) D (i+2) F + // - for (i = 0; i < length; ++i) { - var loadedImage = loadedImages[i]; - uniformId = loadedImage.id; - var image = loadedImage.image; + var numVertices = size / 3; + size -= 6 * (numCorners + 1); + var indices = IndexDatatype.createTypedArray(numVertices, size); - var texture; - if (defined(image.internalFormat)) { - texture = new Texture({ - context : context, - pixelFormat : image.internalFormat, - width : image.width, - height : image.height, - source : { - arrayBufferView : image.bufferView - } - }); - } else { - texture = new Texture({ - context : context, - source : image - }); + var edgeIndex = 0; + for (i = 0; i < numVertices - 2; i += 2) { + var LL = i; + var LR = i + 2; + var pl = Cartesian3.fromArray(positions, LL * 3, scratchCartesian3Position1); + var pr = Cartesian3.fromArray(positions, LR * 3, scratchCartesian3Position2); + if (Cartesian3.equalsEpsilon(pl, pr, CesiumMath.EPSILON10)) { + continue; } + var UL = i + 1; + var UR = i + 3; - this._textures[uniformId] = texture; - - var uniformDimensionsName = uniformId + 'Dimensions'; - if (this.uniforms.hasOwnProperty(uniformDimensionsName)) { - var uniformDimensions = this.uniforms[uniformDimensionsName]; - uniformDimensions.x = texture._width; - uniformDimensions.y = texture._height; - } + indices[edgeIndex++] = UL; + indices[edgeIndex++] = LL; + indices[edgeIndex++] = UR; + indices[edgeIndex++] = UR; + indices[edgeIndex++] = LL; + indices[edgeIndex++] = LR; } - loadedImages.length = 0; - - var loadedCubeMaps = this._loadedCubeMaps; - length = loadedCubeMaps.length; - - for (i = 0; i < length; ++i) { - var loadedCubeMap = loadedCubeMaps[i]; - uniformId = loadedCubeMap.id; - var images = loadedCubeMap.images; - - var cubeMap = new CubeMap({ - context : context, - source : { - positiveX : images[0], - negativeX : images[1], - positiveY : images[2], - negativeY : images[3], - positiveZ : images[4], - negativeZ : images[5] - } - }); - - this._textures[uniformId] = cubeMap; - } - - loadedCubeMaps.length = 0; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : new BoundingSphere.fromVertices(positions) + }); + }; - var updateFunctions = this._updateFunctions; - length = updateFunctions.length; - for (i = 0; i < length; ++i) { - updateFunctions[i](this, context); - } + return WallGeometry; +}); - var subMaterials = this.materials; - for (var name in subMaterials) { - if (subMaterials.hasOwnProperty(name)) { - subMaterials[name].update(context); - } - } - }; +define('Core/WallOutlineGeometry',[ + './BoundingSphere', + './Cartesian3', + './ComponentDatatype', + './defaultValue', + './defined', + './DeveloperError', + './Ellipsoid', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './IndexDatatype', + './Math', + './PrimitiveType', + './WallGeometryLibrary' + ], function( + BoundingSphere, + Cartesian3, + ComponentDatatype, + defaultValue, + defined, + DeveloperError, + Ellipsoid, + Geometry, + GeometryAttribute, + GeometryAttributes, + IndexDatatype, + CesiumMath, + PrimitiveType, + WallGeometryLibrary) { + 'use strict'; - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see Material#destroy - */ - Material.prototype.isDestroyed = function() { - return false; - }; + var scratchCartesian3Position1 = new Cartesian3(); + var scratchCartesian3Position2 = new Cartesian3(); /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. + * A description of a wall outline. A wall is defined by a series of points, + * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. * - * @returns {undefined} + * @alias WallOutlineGeometry + * @constructor * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the + * wall at <code>positions</code>. If undefined, the height of each position in used. + * @param {Number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the + * wall at <code>positions</code>. If undefined, the height at each position is 0.0. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * + * @exception {DeveloperError} positions length must be greater than or equal to 2. + * @exception {DeveloperError} positions and maximumHeights must have the same length. + * @exception {DeveloperError} positions and minimumHeights must have the same length. * - * @example - * material = material && material.destroy(); + * @see WallGeometry#createGeometry + * @see WallGeometry#fromConstantHeight * - * @see Material#isDestroyed + * @example + * // create a wall outline that spans from ground level to 10000 meters + * var wall = new Cesium.WallOutlineGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArrayHeights([ + * 19.0, 47.0, 10000.0, + * 19.0, 48.0, 10000.0, + * 20.0, 48.0, 10000.0, + * 20.0, 47.0, 10000.0, + * 19.0, 47.0, 10000.0 + * ]) + * }); + * var geometry = Cesium.WallOutlineGeometry.createGeometry(wall); */ - Material.prototype.destroy = function() { - var textures = this._textures; - for ( var texture in textures) { - if (textures.hasOwnProperty(texture)) { - var instance = textures[texture]; - if (instance !== this._defaultTexture) { - instance.destroy(); - } - } - } - - var materials = this.materials; - for ( var material in materials) { - if (materials.hasOwnProperty(material)) { - materials[material].destroy(); - } - } - return destroyObject(this); - }; - - function initializeMaterial(options, result) { + function WallOutlineGeometry(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - result._strict = defaultValue(options.strict, false); - result._count = defaultValue(options.count, 0); - result._template = clone(defaultValue(options.fabric, defaultValue.EMPTY_OBJECT)); - result._template.uniforms = clone(defaultValue(result._template.uniforms, defaultValue.EMPTY_OBJECT)); - result._template.materials = clone(defaultValue(result._template.materials, defaultValue.EMPTY_OBJECT)); - result.type = defined(result._template.type) ? result._template.type : createGuid(); + var wallPositions = options.positions; + var maximumHeights = options.maximumHeights; + var minimumHeights = options.minimumHeights; - result.shaderSource = ''; - result.materials = {}; - result.uniforms = {}; - result._uniforms = {}; - result._translucentFunctions = []; + if (!defined(wallPositions)) { + throw new DeveloperError('options.positions is required.'); + } + if (defined(maximumHeights) && maximumHeights.length !== wallPositions.length) { + throw new DeveloperError('options.positions and options.maximumHeights must have the same length.'); + } + if (defined(minimumHeights) && minimumHeights.length !== wallPositions.length) { + throw new DeveloperError('options.positions and options.minimumHeights must have the same length.'); + } + + var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - var translucent; + this._positions = wallPositions; + this._minimumHeights = minimumHeights; + this._maximumHeights = maximumHeights; + this._granularity = granularity; + this._ellipsoid = Ellipsoid.clone(ellipsoid); + this._workerName = 'createWallOutlineGeometry'; - // If the cache contains this material type, build the material template off of the stored template. - var cachedMaterial = Material._materialCache.getMaterial(result.type); - if (defined(cachedMaterial)) { - var template = clone(cachedMaterial.fabric, true); - result._template = combine(result._template, template, true); - translucent = cachedMaterial.translucent; + var numComponents = 1 + wallPositions.length * Cartesian3.packedLength + 2; + if (defined(minimumHeights)) { + numComponents += minimumHeights.length; + } + if (defined(maximumHeights)) { + numComponents += maximumHeights.length; } - // Make sure the template has no obvious errors. More error checking happens later. - checkForTemplateErrors(result); + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = numComponents + Ellipsoid.packedLength + 1; + } - // If the material has a new type, add it to the cache. - if (!defined(cachedMaterial)) { - Material._materialCache.addMaterial(result.type, result); + /** + * Stores the provided instance into the provided array. + * + * @param {WallOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + WallOutlineGeometry.pack = function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); } + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); - createMethodDefinition(result); - createUniforms(result); - createSubMaterials(result); - - var defaultTranslucent = result._translucentFunctions.length === 0 ? true : undefined; - translucent = defaultValue(translucent, defaultTranslucent); - translucent = defaultValue(options.translucent, translucent); + var i; - if (defined(translucent)) { - if (typeof translucent === 'function') { - var wrappedTranslucent = function() { - return translucent(result); - }; - result._translucentFunctions.push(wrappedTranslucent); - } else { - result._translucentFunctions.push(translucent); - } + var positions = value._positions; + var length = positions.length; + array[startingIndex++] = length; + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + Cartesian3.pack(positions[i], array, startingIndex); } - } - function checkForValidProperties(object, properties, result, throwNotFound) { - if (defined(object)) { - for ( var property in object) { - if (object.hasOwnProperty(property)) { - var hasProperty = properties.indexOf(property) !== -1; - if ((throwNotFound && !hasProperty) || (!throwNotFound && hasProperty)) { - result(property, properties); - } - } + var minimumHeights = value._minimumHeights; + length = defined(minimumHeights) ? minimumHeights.length : 0; + array[startingIndex++] = length; + + if (defined(minimumHeights)) { + for (i = 0; i < length; ++i) { + array[startingIndex++] = minimumHeights[i]; } } - } - function invalidNameError(property, properties) { - var errorString = 'fabric: property name \'' + property + '\' is not valid. It should be '; - for ( var i = 0; i < properties.length; i++) { - var propertyName = '\'' + properties[i] + '\''; - errorString += (i === properties.length - 1) ? ('or ' + propertyName + '.') : (propertyName + ', '); - } - throw new DeveloperError(errorString); - } + var maximumHeights = value._maximumHeights; + length = defined(maximumHeights) ? maximumHeights.length : 0; + array[startingIndex++] = length; - function duplicateNameError(property, properties) { - var errorString = 'fabric: uniforms and materials cannot share the same property \'' + property + '\''; - throw new DeveloperError(errorString); + if (defined(maximumHeights)) { + for (i = 0; i < length; ++i) { + array[startingIndex++] = maximumHeights[i]; } + } - var templateProperties = ['type', 'materials', 'uniforms', 'components', 'source']; - var componentProperties = ['diffuse', 'specular', 'shininess', 'normal', 'emission', 'alpha']; + Ellipsoid.pack(value._ellipsoid, array, startingIndex); + startingIndex += Ellipsoid.packedLength; - function checkForTemplateErrors(material) { - var template = material._template; - var uniforms = template.uniforms; - var materials = template.materials; - var components = template.components; + array[startingIndex] = value._granularity; - // Make sure source and components do not exist in the same template. - if (defined(components) && defined(template.source)) { - throw new DeveloperError('fabric: cannot have source and components in the same template.'); + return array; + }; + + var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); + var scratchOptions = { + positions : undefined, + minimumHeights : undefined, + maximumHeights : undefined, + ellipsoid : scratchEllipsoid, + granularity : undefined + }; + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {WallOutlineGeometry} [result] The object into which to store the result. + * @returns {WallOutlineGeometry} The modified result parameter or a new WallOutlineGeometry instance if one was not provided. + */ + WallOutlineGeometry.unpack = function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); } - // Make sure all template and components properties are valid. - checkForValidProperties(template, templateProperties, invalidNameError, true); - checkForValidProperties(components, componentProperties, invalidNameError, true); + startingIndex = defaultValue(startingIndex, 0); - // Make sure uniforms and materials do not share any of the same names. - var materialNames = []; - for ( var property in materials) { - if (materials.hasOwnProperty(property)) { - materialNames.push(property); - } + var i; + + var length = array[startingIndex++]; + var positions = new Array(length); + + for (i = 0; i < length; ++i, startingIndex += Cartesian3.packedLength) { + positions[i] = Cartesian3.unpack(array, startingIndex); } - checkForValidProperties(uniforms, materialNames, duplicateNameError, false); - } - // Create the czm_getMaterial method body using source or components. - function createMethodDefinition(material) { - var components = material._template.components; - var source = material._template.source; - if (defined(source)) { - material.shaderSource += source + '\n'; - } else { - material.shaderSource += 'czm_material czm_getMaterial(czm_materialInput materialInput)\n{\n'; - material.shaderSource += 'czm_material material = czm_getDefaultMaterial(materialInput);\n'; - if (defined(components)) { - for ( var component in components) { - if (components.hasOwnProperty(component)) { - material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; - } - } + length = array[startingIndex++]; + var minimumHeights; + + if (length > 0) { + minimumHeights = new Array(length); + for (i = 0; i < length; ++i) { + minimumHeights[i] = array[startingIndex++]; } - material.shaderSource += 'return material;\n}\n'; } - } - var matrixMap = { - 'mat2' : Matrix2, - 'mat3' : Matrix3, - 'mat4' : Matrix4 - }; + length = array[startingIndex++]; + var maximumHeights; - var ktxRegex = /\.ktx$/i; - var crnRegex = /\.crn$/i; + if (length > 0) { + maximumHeights = new Array(length); + for (i = 0; i < length; ++i) { + maximumHeights[i] = array[startingIndex++]; + } + } - function createTexture2DUpdateFunction(uniformId) { - var oldUniformValue; - return function(material, context) { - var uniforms = material.uniforms; - var uniformValue = uniforms[uniformId]; - var uniformChanged = oldUniformValue !== uniformValue; - oldUniformValue = uniformValue; - var texture = material._textures[uniformId]; + var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid); + startingIndex += Ellipsoid.packedLength; - var uniformDimensionsName; - var uniformDimensions; + var granularity = array[startingIndex]; - if (uniformValue instanceof HTMLVideoElement) { - // HTMLVideoElement.readyState >=2 means we have enough data for the current frame. - // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState - if (uniformValue.readyState >= 2) { - if (uniformChanged && defined(texture)) { - if (texture !== context.defaultTexture) { - texture.destroy(); - } - texture = undefined; - } + if (!defined(result)) { + scratchOptions.positions = positions; + scratchOptions.minimumHeights = minimumHeights; + scratchOptions.maximumHeights = maximumHeights; + scratchOptions.granularity = granularity; + return new WallOutlineGeometry(scratchOptions); + } - if (!defined(texture) || texture === context.defaultTexture) { - texture = new Texture({ - context : context, - source : uniformValue - }); - material._textures[uniformId] = texture; - return; - } + result._positions = positions; + result._minimumHeights = minimumHeights; + result._maximumHeights = maximumHeights; + result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid); + result._granularity = granularity; - texture.copyFrom(uniformValue); - } else if (!defined(texture)) { - material._textures[uniformId] = context.defaultTexture; - } - return; - } + return result; + }; - if (uniformValue instanceof Texture && uniformValue !== texture) { - material._texturePaths[uniformId] = undefined; - var tmp = material._textures[uniformId]; - if (tmp !== material._defaultTexture) { - tmp.destroy(); - } - material._textures[uniformId] = uniformValue; + /** + * A description of a walloutline. A wall is defined by a series of points, + * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. + * @param {Number} [options.maximumHeight] A constant that defines the maximum height of the + * wall at <code>positions</code>. If undefined, the height of each position in used. + * @param {Number} [options.minimumHeight] A constant that defines the minimum height of the + * wall at <code>positions</code>. If undefined, the height at each position is 0.0. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation + * @returns {WallOutlineGeometry} + * + * + * @example + * // create a wall that spans from 10000 meters to 20000 meters + * var wall = Cesium.WallOutlineGeometry.fromConstantHeights({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * 19.0, 47.0, + * 19.0, 48.0, + * 20.0, 48.0, + * 20.0, 47.0, + * 19.0, 47.0, + * ]), + * minimumHeight : 20000.0, + * maximumHeight : 10000.0 + * }); + * var geometry = Cesium.WallOutlineGeometry.createGeometry(wall); + * + * @see WallOutlineGeometry#createGeometry + */ + WallOutlineGeometry.fromConstantHeights = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.positions; - uniformDimensionsName = uniformId + 'Dimensions'; - if (uniforms.hasOwnProperty(uniformDimensionsName)) { - uniformDimensions = uniforms[uniformDimensionsName]; - uniformDimensions.x = uniformValue._width; - uniformDimensions.y = uniformValue._height; - } + if (!defined(positions)) { + throw new DeveloperError('options.positions is required.'); + } + + var minHeights; + var maxHeights; - return; - } + var min = options.minimumHeight; + var max = options.maximumHeight; - if (!defined(texture)) { - material._texturePaths[uniformId] = undefined; - if (!defined(material._defaultTexture)) { - material._defaultTexture = context.defaultTexture; + var doMin = defined(min); + var doMax = defined(max); + if (doMin || doMax) { + var length = positions.length; + minHeights = (doMin) ? new Array(length) : undefined; + maxHeights = (doMax) ? new Array(length) : undefined; + + for (var i = 0; i < length; ++i) { + if (doMin) { + minHeights[i] = min; } - texture = material._textures[uniformId] = material._defaultTexture; - uniformDimensionsName = uniformId + 'Dimensions'; - if (uniforms.hasOwnProperty(uniformDimensionsName)) { - uniformDimensions = uniforms[uniformDimensionsName]; - uniformDimensions.x = texture._width; - uniformDimensions.y = texture._height; + if (doMax) { + maxHeights[i] = max; } } + } - if (uniformValue === Material.DefaultImageId) { - return; - } + var newOptions = { + positions : positions, + maximumHeights : maxHeights, + minimumHeights : minHeights, + ellipsoid : options.ellipsoid + }; + return new WallOutlineGeometry(newOptions); + }; - if (uniformValue !== material._texturePaths[uniformId]) { - if (typeof uniformValue === 'string') { - var promise; - if (ktxRegex.test(uniformValue)) { - promise = loadKTX(uniformValue); - } else if (crnRegex.test(uniformValue)) { - promise = loadCRN(uniformValue); - } else { - promise = loadImage(uniformValue); - } - when(promise, function(image) { - material._loadedImages.push({ - id : uniformId, - image : image - }); - }); - } else if (uniformValue instanceof HTMLCanvasElement) { - material._loadedImages.push({ - id : uniformId, - image : uniformValue - }); - } + /** + * Computes the geometric representation of a wall outline, including its vertices, indices, and a bounding sphere. + * + * @param {WallOutlineGeometry} wallGeometry A description of the wall outline. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + WallOutlineGeometry.createGeometry = function(wallGeometry) { + var wallPositions = wallGeometry._positions; + var minimumHeights = wallGeometry._minimumHeights; + var maximumHeights = wallGeometry._maximumHeights; + var granularity = wallGeometry._granularity; + var ellipsoid = wallGeometry._ellipsoid; - material._texturePaths[uniformId] = uniformValue; - } - }; - } + var pos = WallGeometryLibrary.computePositions(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, false); + if (!defined(pos)) { + return; + } - function createCubeMapUpdateFunction(uniformId) { - return function(material, context) { - var uniformValue = material.uniforms[uniformId]; + var bottomPositions = pos.bottomPositions; + var topPositions = pos.topPositions; - if (uniformValue instanceof CubeMap) { - var tmp = material._textures[uniformId]; - if (tmp !== material._defaultTexture) { - tmp.destroy(); - } - material._texturePaths[uniformId] = undefined; - material._textures[uniformId] = uniformValue; - return; - } + var length = topPositions.length; + var size = length * 2; - if (!defined(material._textures[uniformId])) { - material._texturePaths[uniformId] = undefined; - material._textures[uniformId] = context.defaultCubeMap; - } + var positions = new Float64Array(size); + var positionIndex = 0; - if (uniformValue === Material.DefaultCubeMapId) { - return; - } + // add lower and upper points one after the other, lower + // points being even and upper points being odd + length /= 3; + var i; + for (i = 0; i < length; ++i) { + var i3 = i * 3; + var topPosition = Cartesian3.fromArray(topPositions, i3, scratchCartesian3Position1); + var bottomPosition = Cartesian3.fromArray(bottomPositions, i3, scratchCartesian3Position2); - var path = - uniformValue.positiveX + uniformValue.negativeX + - uniformValue.positiveY + uniformValue.negativeY + - uniformValue.positiveZ + uniformValue.negativeZ; + // insert the lower point + positions[positionIndex++] = bottomPosition.x; + positions[positionIndex++] = bottomPosition.y; + positions[positionIndex++] = bottomPosition.z; - if (path !== material._texturePaths[uniformId]) { - var promises = [ - loadImage(uniformValue.positiveX), - loadImage(uniformValue.negativeX), - loadImage(uniformValue.positiveY), - loadImage(uniformValue.negativeY), - loadImage(uniformValue.positiveZ), - loadImage(uniformValue.negativeZ) - ]; + // insert the upper point + positions[positionIndex++] = topPosition.x; + positions[positionIndex++] = topPosition.y; + positions[positionIndex++] = topPosition.z; + } - when.all(promises).then(function(images) { - material._loadedCubeMaps.push({ - id : uniformId, - images : images - }); - }); + var attributes = new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }) + }); - material._texturePaths[uniformId] = path; - } - }; - } + var numVertices = size / 3; + size = 2 * numVertices - 4 + numVertices; + var indices = IndexDatatype.createTypedArray(numVertices, size); - function createUniforms(material) { - var uniforms = material._template.uniforms; - for ( var uniformId in uniforms) { - if (uniforms.hasOwnProperty(uniformId)) { - createUniform(material, uniformId); + var edgeIndex = 0; + for (i = 0; i < numVertices - 2; i += 2) { + var LL = i; + var LR = i + 2; + var pl = Cartesian3.fromArray(positions, LL * 3, scratchCartesian3Position1); + var pr = Cartesian3.fromArray(positions, LR * 3, scratchCartesian3Position2); + if (Cartesian3.equalsEpsilon(pl, pr, CesiumMath.EPSILON10)) { + continue; } - } - } - - // Writes uniform declarations to the shader file and connects uniform values with - // corresponding material properties through the returnUniforms function. - function createUniform(material, uniformId) { - var strict = material._strict; - var materialUniforms = material._template.uniforms; - var uniformValue = materialUniforms[uniformId]; - var uniformType = getUniformType(uniformValue); + var UL = i + 1; + var UR = i + 3; - if (!defined(uniformType)) { - throw new DeveloperError('fabric: uniform \'' + uniformId + '\' has invalid type.'); + indices[edgeIndex++] = UL; + indices[edgeIndex++] = LL; + indices[edgeIndex++] = UL; + indices[edgeIndex++] = UR; + indices[edgeIndex++] = LL; + indices[edgeIndex++] = LR; } - - var replacedTokenCount; - if (uniformType === 'channels') { - replacedTokenCount = replaceToken(material, uniformId, uniformValue, false); - if (replacedTokenCount === 0 && strict) { - throw new DeveloperError('strict: shader source does not use channels \'' + uniformId + '\'.'); - } - } else { - // Since webgl doesn't allow texture dimension queries in glsl, create a uniform to do it. - // Check if the shader source actually uses texture dimensions before creating the uniform. - if (uniformType === 'sampler2D') { - var imageDimensionsUniformName = uniformId + 'Dimensions'; - if (getNumberOfTokens(material, imageDimensionsUniformName) > 0) { - materialUniforms[imageDimensionsUniformName] = { - type : 'ivec3', - x : 1, - y : 1 - }; - createUniform(material, imageDimensionsUniformName); - } - } - // Add uniform declaration to source code. - var uniformDeclarationRegex = new RegExp('uniform\\s+' + uniformType + '\\s+' + uniformId + '\\s*;'); - if (!uniformDeclarationRegex.test(material.shaderSource)) { - var uniformDeclaration = 'uniform ' + uniformType + ' ' + uniformId + ';'; - material.shaderSource = uniformDeclaration + material.shaderSource; - } + indices[edgeIndex++] = numVertices - 2; + indices[edgeIndex++] = numVertices - 1; - var newUniformId = uniformId + '_' + material._count++; - replacedTokenCount = replaceToken(material, uniformId, newUniformId); - if (replacedTokenCount === 1 && strict) { - throw new DeveloperError('strict: shader source does not use uniform \'' + uniformId + '\'.'); - } - - // Set uniform value - material.uniforms[uniformId] = uniformValue; + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : new BoundingSphere.fromVertices(positions) + }); + }; - if (uniformType === 'sampler2D') { - material._uniforms[newUniformId] = function() { - return material._textures[uniformId]; - }; - material._updateFunctions.push(createTexture2DUpdateFunction(uniformId)); - } else if (uniformType === 'samplerCube') { - material._uniforms[newUniformId] = function() { - return material._textures[uniformId]; - }; - material._updateFunctions.push(createCubeMapUpdateFunction(uniformId)); - } else if (uniformType.indexOf('mat') !== -1) { - var scratchMatrix = new matrixMap[uniformType](); - material._uniforms[newUniformId] = function() { - return matrixMap[uniformType].fromColumnMajorArray(material.uniforms[uniformId], scratchMatrix); - }; - } else { - material._uniforms[newUniformId] = function() { - return material.uniforms[uniformId]; - }; - } - } - } + return WallOutlineGeometry; +}); - // Determines the uniform type based on the uniform in the template. - function getUniformType(uniformValue) { - var uniformType = uniformValue.type; - if (!defined(uniformType)) { - var type = typeof uniformValue; - if (type === 'number') { - uniformType = 'float'; - } else if (type === 'boolean') { - uniformType = 'bool'; - } else if (type === 'string' || uniformValue instanceof HTMLCanvasElement) { - if (/^([rgba]){1,4}$/i.test(uniformValue)) { - uniformType = 'channels'; - } else if (uniformValue === Material.DefaultCubeMapId) { - uniformType = 'samplerCube'; - } else { - uniformType = 'sampler2D'; - } - } else if (type === 'object') { - if (isArray(uniformValue)) { - if (uniformValue.length === 4 || uniformValue.length === 9 || uniformValue.length === 16) { - uniformType = 'mat' + Math.sqrt(uniformValue.length); - } - } else { - var numAttributes = 0; - for ( var attribute in uniformValue) { - if (uniformValue.hasOwnProperty(attribute)) { - numAttributes += 1; - } - } - if (numAttributes >= 2 && numAttributes <= 4) { - uniformType = 'vec' + numAttributes; - } else if (numAttributes === 6) { - uniformType = 'samplerCube'; - } - } - } - } - return uniformType; - } +define('Core/WebMercatorTilingScheme',[ + './Cartesian2', + './defaultValue', + './defined', + './defineProperties', + './Ellipsoid', + './Rectangle', + './WebMercatorProjection' + ], function( + Cartesian2, + defaultValue, + defined, + defineProperties, + Ellipsoid, + Rectangle, + WebMercatorProjection) { + 'use strict'; - // Create all sub-materials by combining source and uniforms together. - function createSubMaterials(material) { - var strict = material._strict; - var subMaterialTemplates = material._template.materials; - for ( var subMaterialId in subMaterialTemplates) { - if (subMaterialTemplates.hasOwnProperty(subMaterialId)) { - // Construct the sub-material. - var subMaterial = new Material({ - strict : strict, - fabric : subMaterialTemplates[subMaterialId], - count : material._count - }); + /** + * A tiling scheme for geometry referenced to a {@link WebMercatorProjection}, EPSG:3857. This is + * the tiling scheme used by Google Maps, Microsoft Bing Maps, and most of ESRI ArcGIS Online. + * + * @alias WebMercatorTilingScheme + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to + * the WGS84 ellipsoid. + * @param {Number} [options.numberOfLevelZeroTilesX=1] The number of tiles in the X direction at level zero of + * the tile tree. + * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of + * the tile tree. + * @param {Cartesian2} [options.rectangleSouthwestInMeters] The southwest corner of the rectangle covered by the + * tiling scheme, in meters. If this parameter or rectangleNortheastInMeters is not specified, the entire + * globe is covered in the longitude direction and an equal distance is covered in the latitude + * direction, resulting in a square projection. + * @param {Cartesian2} [options.rectangleNortheastInMeters] The northeast corner of the rectangle covered by the + * tiling scheme, in meters. If this parameter or rectangleSouthwestInMeters is not specified, the entire + * globe is covered in the longitude direction and an equal distance is covered in the latitude + * direction, resulting in a square projection. + */ + function WebMercatorTilingScheme(options) { + options = defaultValue(options, {}); - material._count = subMaterial._count; - material._uniforms = combine(material._uniforms, subMaterial._uniforms, true); - material.materials[subMaterialId] = subMaterial; - material._translucentFunctions = material._translucentFunctions.concat(subMaterial._translucentFunctions); + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._numberOfLevelZeroTilesX = defaultValue(options.numberOfLevelZeroTilesX, 1); + this._numberOfLevelZeroTilesY = defaultValue(options.numberOfLevelZeroTilesY, 1); - // Make the material's czm_getMaterial unique by appending the sub-material type. - var originalMethodName = 'czm_getMaterial'; - var newMethodName = originalMethodName + '_' + material._count++; - replaceToken(subMaterial, originalMethodName, newMethodName); - material.shaderSource = subMaterial.shaderSource + material.shaderSource; + this._projection = new WebMercatorProjection(this._ellipsoid); - // Replace each material id with an czm_getMaterial method call. - var materialMethodCall = newMethodName + '(materialInput)'; - var tokensReplacedCount = replaceToken(material, subMaterialId, materialMethodCall); - if (tokensReplacedCount === 0 && strict) { - throw new DeveloperError('strict: shader source does not use material \'' + subMaterialId + '\'.'); - } - } + if (defined(options.rectangleSouthwestInMeters) && + defined(options.rectangleNortheastInMeters)) { + this._rectangleSouthwestInMeters = options.rectangleSouthwestInMeters; + this._rectangleNortheastInMeters = options.rectangleNortheastInMeters; + } else { + var semimajorAxisTimesPi = this._ellipsoid.maximumRadius * Math.PI; + this._rectangleSouthwestInMeters = new Cartesian2(-semimajorAxisTimesPi, -semimajorAxisTimesPi); + this._rectangleNortheastInMeters = new Cartesian2(semimajorAxisTimesPi, semimajorAxisTimesPi); } - } - // Used for searching or replacing a token in a material's shader source with something else. - // If excludePeriod is true, do not accept tokens that are preceded by periods. - // http://stackoverflow.com/questions/641407/javascript-negative-lookbehind-equivalent - function replaceToken(material, token, newToken, excludePeriod) { - excludePeriod = defaultValue(excludePeriod, true); - var count = 0; - var suffixChars = '([\\w])?'; - var prefixChars = '([\\w' + (excludePeriod ? '.' : '') + '])?'; - var regExp = new RegExp(prefixChars + token + suffixChars, 'g'); - material.shaderSource = material.shaderSource.replace(regExp, function($0, $1, $2) { - if ($1 || $2) { - return $0; - } - count += 1; - return newToken; - }); - return count; + var southwest = this._projection.unproject(this._rectangleSouthwestInMeters); + var northeast = this._projection.unproject(this._rectangleNortheastInMeters); + this._rectangle = new Rectangle(southwest.longitude, southwest.latitude, + northeast.longitude, northeast.latitude); } - function getNumberOfTokens(material, token, excludePeriod) { - return replaceToken(material, token, token, excludePeriod); - } + defineProperties(WebMercatorTilingScheme.prototype, { + /** + * Gets the ellipsoid that is tiled by this tiling scheme. + * @memberof WebMercatorTilingScheme.prototype + * @type {Ellipsoid} + */ + ellipsoid : { + get : function() { + return this._ellipsoid; + } + }, - Material._materialCache = { - _materials : {}, - addMaterial : function(type, materialTemplate) { - this._materials[type] = materialTemplate; + /** + * Gets the rectangle, in radians, covered by this tiling scheme. + * @memberof WebMercatorTilingScheme.prototype + * @type {Rectangle} + */ + rectangle : { + get : function() { + return this._rectangle; + } }, - getMaterial : function(type) { - return this._materials[type]; + + /** + * Gets the map projection used by this tiling scheme. + * @memberof WebMercatorTilingScheme.prototype + * @type {MapProjection} + */ + projection : { + get : function() { + return this._projection; + } } - }; + }); /** - * Gets or sets the default texture uniform value. - * @type {String} + * Gets the total number of tiles in the X direction at a specified level-of-detail. + * + * @param {Number} level The level-of-detail. + * @returns {Number} The number of tiles in the X direction at the given level. */ - Material.DefaultImageId = 'czm_defaultImage'; + WebMercatorTilingScheme.prototype.getNumberOfXTilesAtLevel = function(level) { + return this._numberOfLevelZeroTilesX << level; + }; /** - * Gets or sets the default cube map texture uniform value. - * @type {String} + * Gets the total number of tiles in the Y direction at a specified level-of-detail. + * + * @param {Number} level The level-of-detail. + * @returns {Number} The number of tiles in the Y direction at the given level. */ - Material.DefaultCubeMapId = 'czm_defaultCubeMap'; + WebMercatorTilingScheme.prototype.getNumberOfYTilesAtLevel = function(level) { + return this._numberOfLevelZeroTilesY << level; + }; /** - * Gets the name of the color material. - * @type {String} - * @readonly + * Transforms a rectangle specified in geodetic radians to the native coordinate system + * of this tiling scheme. + * + * @param {Rectangle} rectangle The rectangle to transform. + * @param {Rectangle} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the native rectangle if 'result' + * is undefined. */ - Material.ColorType = 'Color'; - Material._materialCache.addMaterial(Material.ColorType, { - fabric : { - type : Material.ColorType, - uniforms : { - color : new Color(1.0, 0.0, 0.0, 0.5) - }, - components : { - diffuse : 'color.rgb', - alpha : 'color.a' - } - }, - translucent : function(material) { - return material.uniforms.color.alpha < 1.0; + WebMercatorTilingScheme.prototype.rectangleToNativeRectangle = function(rectangle, result) { + var projection = this._projection; + var southwest = projection.project(Rectangle.southwest(rectangle)); + var northeast = projection.project(Rectangle.northeast(rectangle)); + + if (!defined(result)) { + return new Rectangle(southwest.x, southwest.y, northeast.x, northeast.y); } - }); + + result.west = southwest.x; + result.south = southwest.y; + result.east = northeast.x; + result.north = northeast.y; + return result; + }; /** - * Gets the name of the image material. - * @type {String} - * @readonly + * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates + * of the tiling scheme. + * + * @param {Number} x The integer x coordinate of the tile. + * @param {Number} y The integer y coordinate of the tile. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the rectangle + * if 'result' is undefined. */ - Material.ImageType = 'Image'; - Material._materialCache.addMaterial(Material.ImageType, { - fabric : { - type : Material.ImageType, - uniforms : { - image : Material.DefaultImageId, - repeat : new Cartesian2(1.0, 1.0), - color: new Color(1.0, 1.0, 1.0, 1.0) - }, - components : { - diffuse : 'texture2D(image, fract(repeat * materialInput.st)).rgb * color.rgb', - alpha : 'texture2D(image, fract(repeat * materialInput.st)).a * color.a' - } - }, - translucent : function(material) { - return material.uniforms.color.alpha < 1.0; + WebMercatorTilingScheme.prototype.tileXYToNativeRectangle = function(x, y, level, result) { + var xTiles = this.getNumberOfXTilesAtLevel(level); + var yTiles = this.getNumberOfYTilesAtLevel(level); + + var xTileWidth = (this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x) / xTiles; + var west = this._rectangleSouthwestInMeters.x + x * xTileWidth; + var east = this._rectangleSouthwestInMeters.x + (x + 1) * xTileWidth; + + var yTileHeight = (this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y) / yTiles; + var north = this._rectangleNortheastInMeters.y - y * yTileHeight; + var south = this._rectangleNortheastInMeters.y - (y + 1) * yTileHeight; + + if (!defined(result)) { + return new Rectangle(west, south, east, north); } - }); + + result.west = west; + result.south = south; + result.east = east; + result.north = north; + return result; + }; /** - * Gets the name of the diffuce map material. - * @type {String} - * @readonly - */ - Material.DiffuseMapType = 'DiffuseMap'; - Material._materialCache.addMaterial(Material.DiffuseMapType, { - fabric : { - type : Material.DiffuseMapType, - uniforms : { - image : Material.DefaultImageId, - channels : 'rgb', - repeat : new Cartesian2(1.0, 1.0) - }, - components : { - diffuse : 'texture2D(image, fract(repeat * materialInput.st)).channels' - } - }, - translucent : false - }); + * Converts tile x, y coordinates and level to a cartographic rectangle in radians. + * + * @param {Number} x The integer x coordinate of the tile. + * @param {Number} y The integer y coordinate of the tile. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Rectangle} The specified 'result', or a new object containing the rectangle + * if 'result' is undefined. + */ + WebMercatorTilingScheme.prototype.tileXYToRectangle = function(x, y, level, result) { + var nativeRectangle = this.tileXYToNativeRectangle(x, y, level, result); + + var projection = this._projection; + var southwest = projection.unproject(new Cartesian2(nativeRectangle.west, nativeRectangle.south)); + var northeast = projection.unproject(new Cartesian2(nativeRectangle.east, nativeRectangle.north)); + + nativeRectangle.west = southwest.longitude; + nativeRectangle.south = southwest.latitude; + nativeRectangle.east = northeast.longitude; + nativeRectangle.north = northeast.latitude; + return nativeRectangle; + }; /** - * Gets the name of the alpha map material. - * @type {String} - * @readonly + * Calculates the tile x, y coordinates of the tile containing + * a given cartographic position. + * + * @param {Cartographic} position The position. + * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance + * should be created. + * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates + * if 'result' is undefined. */ - Material.AlphaMapType = 'AlphaMap'; - Material._materialCache.addMaterial(Material.AlphaMapType, { - fabric : { - type : Material.AlphaMapType, - uniforms : { - image : Material.DefaultImageId, - channel : 'a', - repeat : new Cartesian2(1.0, 1.0) - }, - components : { - alpha : 'texture2D(image, fract(repeat * materialInput.st)).channel' - } - }, - translucent : true - }); + WebMercatorTilingScheme.prototype.positionToTileXY = function(position, level, result) { + var rectangle = this._rectangle; + if (!Rectangle.contains(rectangle, position)) { + // outside the bounds of the tiling scheme + return undefined; + } + + var xTiles = this.getNumberOfXTilesAtLevel(level); + var yTiles = this.getNumberOfYTilesAtLevel(level); + + var overallWidth = this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x; + var xTileWidth = overallWidth / xTiles; + var overallHeight = this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y; + var yTileHeight = overallHeight / yTiles; + + var projection = this._projection; + + var webMercatorPosition = projection.project(position); + var distanceFromWest = webMercatorPosition.x - this._rectangleSouthwestInMeters.x; + var distanceFromNorth = this._rectangleNortheastInMeters.y - webMercatorPosition.y; + + var xTileCoordinate = distanceFromWest / xTileWidth | 0; + if (xTileCoordinate >= xTiles) { + xTileCoordinate = xTiles - 1; + } + var yTileCoordinate = distanceFromNorth / yTileHeight | 0; + if (yTileCoordinate >= yTiles) { + yTileCoordinate = yTiles - 1; + } + + if (!defined(result)) { + return new Cartesian2(xTileCoordinate, yTileCoordinate); + } + + result.x = xTileCoordinate; + result.y = yTileCoordinate; + return result; + }; + + return WebMercatorTilingScheme; +}); + +define('Core/WeightSpline',[ + './Check', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Spline' +], function( + Check, + defaultValue, + defined, + defineProperties, + DeveloperError, + Spline) { + 'use strict'; /** - * Gets the name of the specular map material. - * @type {String} - * @readonly + * A spline that linearly interpolates over an array of weight values used by morph targets. + * + * @alias WeightSpline + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * The values are in no way connected to the clock time. They are the parameterization for the curve. + * @param {Number[]} options.weights The array of floating-point control weights given. The weights are ordered such + * that all weights for the targets are given in chronological order and order in which they appear in + * the glTF from which the morph targets come. This means for 2 targets, weights = [w(0,0), w(0,1), w(1,0), w(1,1) ...] + * where i and j in w(i,j) are the time indices and target indices, respectively. + * + * @exception {DeveloperError} weights.length must be greater than or equal to 2. + * @exception {DeveloperError} times.length must be a factor of weights.length. + * + * + * @example + * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ]; + * var weights = [0.0, 1.0, 0.25, 0.75, 0.5, 0.5, 0.75, 0.25, 1.0, 0.0]; //Two targets + * var spline = new Cesium.WeightSpline({ + * times : times, + * weights : weights + * }); + * + * var p0 = spline.evaluate(times[0]); + * + * @see LinearSpline + * @see HermiteSpline + * @see CatmullRomSpline + * @see QuaternionSpline */ - Material.SpecularMapType = 'SpecularMap'; - Material._materialCache.addMaterial(Material.SpecularMapType, { - fabric : { - type : Material.SpecularMapType, - uniforms : { - image : Material.DefaultImageId, - channel : 'r', - repeat : new Cartesian2(1.0, 1.0) - }, - components : { - specular : 'texture2D(image, fract(repeat * materialInput.st)).channel' + function WeightSpline(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var weights = options.weights; + var times = options.times; + + Check.defined('weights', weights); + Check.defined('times', times); + Check.typeOf.number.greaterThanOrEquals('weights.length', weights.length, 3); + if (weights.length % times.length !== 0) { + throw new DeveloperError('times.length must be a factor of weights.length.'); + } + + this._times = times; + this._weights = weights; + this._count = weights.length / times.length; + + this._lastTimeIndex = 0; + } + + defineProperties(WeightSpline.prototype, { + /** + * An array of times for the control weights. + * + * @memberof WeightSpline.prototype + * + * @type {Number[]} + * @readonly + */ + times : { + get : function() { + return this._times; } }, - translucent : false - }); - /** - * Gets the name of the emmision map material. - * @type {String} - * @readonly - */ - Material.EmissionMapType = 'EmissionMap'; - Material._materialCache.addMaterial(Material.EmissionMapType, { - fabric : { - type : Material.EmissionMapType, - uniforms : { - image : Material.DefaultImageId, - channels : 'rgb', - repeat : new Cartesian2(1.0, 1.0) - }, - components : { - emission : 'texture2D(image, fract(repeat * materialInput.st)).channels' + /** + * An array of floating-point array control weights. + * + * @memberof WeightSpline.prototype + * + * @type {Number[]} + * @readonly + */ + weights : { + get : function() { + return this._weights; } - }, - translucent : false + } }); /** - * Gets the name of the bump map material. - * @type {String} - * @readonly + * Finds an index <code>i</code> in <code>times</code> such that the parameter + * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. + * @function + * + * @param {Number} time The time. + * @returns {Number} The index for the element at the start of the interval. + * + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - Material.BumpMapType = 'BumpMap'; - Material._materialCache.addMaterial(Material.BumpMapType, { - fabric : { - type : Material.BumpMapType, - uniforms : { - image : Material.DefaultImageId, - channel : 'r', - strength : 0.8, - repeat : new Cartesian2(1.0, 1.0) - }, - source : BumpMapMaterial - }, - translucent : false - }); + WeightSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; /** - * Gets the name of the normal map material. - * @type {String} - * @readonly + * Wraps the given time to the period covered by the spline. + * @function + * + * @param {Number} time The time. + * @return {Number} The time, wrapped around to the updated animation. */ - Material.NormalMapType = 'NormalMap'; - Material._materialCache.addMaterial(Material.NormalMapType, { - fabric : { - type : Material.NormalMapType, - uniforms : { - image : Material.DefaultImageId, - channels : 'rgb', - strength : 0.8, - repeat : new Cartesian2(1.0, 1.0) - }, - source : NormalMapMaterial - }, - translucent : false - }); + WeightSpline.prototype.wrapTime = Spline.prototype.wrapTime; /** - * Gets the name of the grid material. - * @type {String} - * @readonly + * Clamps the given time to the period covered by the spline. + * @function + * + * @param {Number} time The time. + * @return {Number} The time, clamped to the animation period. */ - Material.GridType = 'Grid'; - Material._materialCache.addMaterial(Material.GridType, { - fabric : { - type : Material.GridType, - uniforms : { - color : new Color(0.0, 1.0, 0.0, 1.0), - cellAlpha : 0.1, - lineCount : new Cartesian2(8.0, 8.0), - lineThickness : new Cartesian2(1.0, 1.0), - lineOffset : new Cartesian2(0.0, 0.0) - }, - source : GridMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.color.alpha < 1.0) || (uniforms.cellAlpha < 1.0); - } - }); + WeightSpline.prototype.clampTime = Spline.prototype.clampTime; /** - * Gets the name of the stripe material. - * @type {String} - * @readonly + * Evaluates the curve at a given time. + * + * @param {Number} time The time at which to evaluate the curve. + * @param {Number[]} [result] The object onto which to store the result. + * @returns {Number[]} The modified result parameter or a new instance of the point on the curve at the given time. + * + * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> + * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element + * in the array <code>times</code>. */ - Material.StripeType = 'Stripe'; - Material._materialCache.addMaterial(Material.StripeType, { - fabric : { - type : Material.StripeType, - uniforms : { - horizontal : true, - evenColor : new Color(1.0, 1.0, 1.0, 0.5), - oddColor : new Color(0.0, 0.0, 1.0, 0.5), - offset : 0.0, - repeat : 5.0 - }, - source : StripeMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.evenColor.alpha < 1.0) || (uniforms.oddColor.alpha < 1.0); + WeightSpline.prototype.evaluate = function(time, result) { + var weights = this.weights; + var times = this.times; + + var i = this._lastTimeIndex = this.findTimeInterval(time, this._lastTimeIndex); + var u = (time - times[i]) / (times[i + 1] - times[i]); + + if (!defined(result)) { + result = new Array(this._count); } - }); - /** - * Gets the name of the checkerboard material. - * @type {String} - * @readonly - */ - Material.CheckerboardType = 'Checkerboard'; - Material._materialCache.addMaterial(Material.CheckerboardType, { - fabric : { - type : Material.CheckerboardType, - uniforms : { - lightColor : new Color(1.0, 1.0, 1.0, 0.5), - darkColor : new Color(0.0, 0.0, 0.0, 0.5), - repeat : new Cartesian2(5.0, 5.0) - }, - source : CheckerboardMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.lightColor.alpha < 1.0) || (uniforms.darkColor.alpha < 1.0); + for (var j = 0; j < this._count; j++) { + var index = (i * this._count) + j; + result[j] = weights[index] * (1.0 - u) + weights[index + this._count] * u; } - }); + + return result; + }; + + return WeightSpline; +}); + +define('Core/wrapFunction',[ + './DeveloperError' + ], function( + DeveloperError) { + 'use strict'; /** - * Gets the name of the dot material. - * @type {String} - * @readonly + * Wraps a function on the provided objects with another function called in the + * object's context so that the new function is always called immediately + * before the old one. + * + * @private */ - Material.DotType = 'Dot'; - Material._materialCache.addMaterial(Material.DotType, { - fabric : { - type : Material.DotType, - uniforms : { - lightColor : new Color(1.0, 1.0, 0.0, 0.75), - darkColor : new Color(0.0, 1.0, 1.0, 0.75), - repeat : new Cartesian2(5.0, 5.0) - }, - source : DotMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.lightColor.alpha < 1.0) || (uniforms.darkColor.alpha < 1.0); + function wrapFunction(obj, oldFunction, newFunction) { + if (typeof oldFunction !== 'function') { + throw new DeveloperError('oldFunction is required to be a function.'); } - }); - /** - * Gets the name of the water material. - * @type {String} - * @readonly - */ - Material.WaterType = 'Water'; - Material._materialCache.addMaterial(Material.WaterType, { - fabric : { - type : Material.WaterType, - uniforms : { - baseWaterColor : new Color(0.2, 0.3, 0.6, 1.0), - blendColor : new Color(0.0, 1.0, 0.699, 1.0), - specularMap : Material.DefaultImageId, - normalMap : Material.DefaultImageId, - frequency : 10.0, - animationSpeed : 0.01, - amplitude : 1.0, - specularIntensity : 0.5, - fadeFactor : 1.0 - }, - source : WaterMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.baseWaterColor.alpha < 1.0) || (uniforms.blendColor.alpha < 1.0); + if (typeof newFunction !== 'function') { + throw new DeveloperError('oldFunction is required to be a function.'); } - }); + + return function() { + newFunction.apply(obj, arguments); + oldFunction.apply(obj, arguments); + }; + } + + return wrapFunction; +}); + +define('DataSources/ConstantProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/Event' + ], function( + defined, + defineProperties, + Event) { + 'use strict'; /** - * Gets the name of the rim lighting material. - * @type {String} - * @readonly + * A {@link Property} whose value does not change with respect to simulation time. + * + * @alias ConstantProperty + * @constructor + * + * @param {Object} [value] The property value. + * + * @see ConstantPositionProperty */ - Material.RimLightingType = 'RimLighting'; - Material._materialCache.addMaterial(Material.RimLightingType, { - fabric : { - type : Material.RimLightingType, - uniforms : { - color : new Color(1.0, 0.0, 0.0, 0.7), - rimColor : new Color(1.0, 1.0, 1.0, 0.4), - width : 0.3 - }, - source : RimLightingMaterial + function ConstantProperty(value) { + this._value = undefined; + this._hasClone = false; + this._hasEquals = false; + this._definitionChanged = new Event(); + this.setValue(value); + } + + defineProperties(ConstantProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * This property always returns <code>true</code>. + * @memberof ConstantProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + value : true }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.color.alpha < 1.0) || (uniforms.rimColor.alpha < 1.0); + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof ConstantProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } } }); /** - * Gets the name of the fade material. - * @type {String} - * @readonly + * Gets the value of the property. + * + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. */ - Material.FadeType = 'Fade'; - Material._materialCache.addMaterial(Material.FadeType, { - fabric : { - type : Material.FadeType, - uniforms : { - fadeInColor : new Color(1.0, 0.0, 0.0, 1.0), - fadeOutColor : new Color(0.0, 0.0, 0.0, 0.0), - maximumDistance : 0.5, - repeat : true, - fadeDirection : { - x : true, - y : true - }, - time : new Cartesian2(0.5, 0.5) - }, - source : FadeMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.fadeInColor.alpha < 1.0) || (uniforms.fadeOutColor.alpha < 1.0); - } - }); + ConstantProperty.prototype.getValue = function(time, result) { + return this._hasClone ? this._value.clone(result) : this._value; + }; /** - * Gets the name of the polyline arrow material. - * @type {String} - * @readonly + * Sets the value of the property. + * + * @param {Object} value The property value. */ - Material.PolylineArrowType = 'PolylineArrow'; - Material._materialCache.addMaterial(Material.PolylineArrowType, { - fabric : { - type : Material.PolylineArrowType, - uniforms : { - color : new Color(1.0, 1.0, 1.0, 1.0) - }, - source : PolylineArrowMaterial - }, - translucent : true - }); + ConstantProperty.prototype.setValue = function(value) { + var oldValue = this._value; + if (oldValue !== value) { + var isDefined = defined(value); + var hasClone = isDefined && typeof value.clone === 'function'; + var hasEquals = isDefined && typeof value.equals === 'function'; - /** - * Gets the name of the polyline glow material. - * @type {String} - * @readonly - */ - Material.PolylineDashType = 'PolylineDash'; - Material._materialCache.addMaterial(Material.PolylineDashType, { - fabric : { - type : Material.PolylineDashType, - uniforms : { - color : new Color(1.0, 0.0, 1.0, 1.0), - gapColor : new Color(0.0, 0.0, 0.0, 0.0), - dashLength : 16.0, - dashPattern : 255.0 - }, - source : PolylineDashMaterial - }, - translucent : true - }); + var changed = !hasEquals || !value.equals(oldValue); + if (changed) { + this._hasClone = hasClone; + this._hasEquals = hasEquals; + this._value = !hasClone ? value : value.clone(this._value); + this._definitionChanged.raiseEvent(this); + } + } + }; /** - * Gets the name of the polyline glow material. - * @type {String} - * @readonly + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - Material.PolylineGlowType = 'PolylineGlow'; - Material._materialCache.addMaterial(Material.PolylineGlowType, { - fabric : { - type : Material.PolylineGlowType, - uniforms : { - color : new Color(0.0, 0.5, 1.0, 1.0), - glowPower : 0.25 - }, - source : PolylineGlowMaterial - }, - translucent : true - }); + ConstantProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof ConstantProperty && // + ((!this._hasEquals && (this._value === other._value)) || // + (this._hasEquals && this._value.equals(other._value)))); + }; /** - * Gets the name of the polyline outline material. - * @type {String} - * @readonly + * Gets this property's value. + * + * @returns {*} This property's value. */ - Material.PolylineOutlineType = 'PolylineOutline'; - Material._materialCache.addMaterial(Material.PolylineOutlineType, { - fabric : { - type : Material.PolylineOutlineType, - uniforms : { - color : new Color(1.0, 1.0, 1.0, 1.0), - outlineColor : new Color(1.0, 0.0, 0.0, 1.0), - outlineWidth : 1.0 - }, - source : PolylineOutlineMaterial - }, - translucent : function(material) { - var uniforms = material.uniforms; - return (uniforms.color.alpha < 1.0) || (uniforms.outlineColor.alpha < 1.0); - } - }); + ConstantProperty.prototype.valueOf = function() { + return this._value; + }; /** - * Gets the name of the elevation contour material. - * @type {String} - * @readonly + * Creates a string representing this property's value. + * + * @returns {String} A string representing the property's value. */ - Material.ElevationContourType = 'ElevationContour'; - Material._materialCache.addMaterial(Material.ElevationContourType, { - fabric : { - type : Material.ElevationContourType, - uniforms : { - spacing: 100.0, - color: new Color(1.0, 0.0, 0.0, 1.0), - width: 1.0 - }, - source : ElevationContourMaterial - }, - translucent : false - }); + ConstantProperty.prototype.toString = function() { + return String(this._value); + }; - /** - * Gets the name of the elevation contour material. - * @type {String} - * @readonly - */ - Material.ElevationRampType = 'ElevationRamp'; - Material._materialCache.addMaterial(Material.ElevationRampType, { - fabric : { - type : Material.ElevationRampType, - uniforms : { - image: Material.DefaultImageId, - minimumHeight: 0.0, - maximumHeight: 10000.0 + return ConstantProperty; +}); + +define('DataSources/createPropertyDescriptor',[ + '../Core/defaultValue', + '../Core/defined', + './ConstantProperty' + ], function( + defaultValue, + defined, + ConstantProperty) { + 'use strict'; + + function createProperty(name, privateName, subscriptionName, configurable, createPropertyCallback) { + return { + configurable : configurable, + get : function() { + return this[privateName]; }, - source : ElevationRampMaterial - }, - translucent : false - }); + set : function(value) { + var oldValue = this[privateName]; + var subscription = this[subscriptionName]; + if (defined(subscription)) { + subscription(); + this[subscriptionName] = undefined; + } + + var hasValue = value !== undefined; + if (hasValue && (!defined(value) || !defined(value.getValue)) && defined(createPropertyCallback)) { + value = createPropertyCallback(value); + } + + if (oldValue !== value) { + this[privateName] = value; + this._definitionChanged.raiseEvent(this, name, value, oldValue); + } + + if (defined(value) && defined(value.definitionChanged)) { + this[subscriptionName] = value.definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this, name, value, value); + }, this); + } + } + }; + } + + function createConstantProperty(value) { + return new ConstantProperty(value); + } /** - * Gets the name of the slope ramp material. - * @type {String} - * @readonly + * Used to consistently define all DataSources graphics objects. + * This is broken into two functions because the Chrome profiler does a better + * job of optimizing lookups if it notices that the string is constant throughout the function. + * @private */ - Material.SlopeRampMaterialType = 'SlopeRamp'; - Material._materialCache.addMaterial(Material.SlopeRampMaterialType, { - fabric : { - type : Material.SlopeRampMaterialType, - uniforms : { - image: Material.DefaultImageId - }, - source : SlopeRampMaterial - }, - translucent : false - }); + function createPropertyDescriptor(name, configurable, createPropertyCallback) { + //Safari 8.0.3 has a JavaScript bug that causes it to confuse two variables and treat them as the same. + //The two extra toString calls work around the issue. + return createProperty(name, '_' + name.toString(), '_' + name.toString() + 'Subscription', defaultValue(configurable, false), defaultValue(createPropertyCallback, createConstantProperty)); + } - return Material; + return createPropertyDescriptor; }); -define('Scene/MaterialAppearance',[ +define('DataSources/BillboardGraphics',[ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/freezeObject', - '../Core/VertexFormat', - '../Shaders/Appearances/AllMaterialAppearanceFS', - '../Shaders/Appearances/AllMaterialAppearanceVS', - '../Shaders/Appearances/BasicMaterialAppearanceFS', - '../Shaders/Appearances/BasicMaterialAppearanceVS', - '../Shaders/Appearances/TexturedMaterialAppearanceFS', - '../Shaders/Appearances/TexturedMaterialAppearanceVS', - './Appearance', - './Material' + '../Core/DeveloperError', + '../Core/Event', + './createPropertyDescriptor' ], function( defaultValue, defined, defineProperties, - freezeObject, - VertexFormat, - AllMaterialAppearanceFS, - AllMaterialAppearanceVS, - BasicMaterialAppearanceFS, - BasicMaterialAppearanceVS, - TexturedMaterialAppearanceFS, - TexturedMaterialAppearanceVS, - Appearance, - Material) { + DeveloperError, + Event, + createPropertyDescriptor) { 'use strict'; /** - * An appearance for arbitrary geometry (as opposed to {@link EllipsoidSurfaceAppearance}, for example) - * that supports shading with materials. + * Describes a two dimensional icon located at the position of the containing {@link Entity}. + * <p> + * <div align='center'> + * <img src='Images/Billboard.png' width='400' height='300' /><br /> + * Example billboards + * </div> + * </p> * - * @alias MaterialAppearance + * @alias BillboardGraphics * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. - * @param {Boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link MaterialAppearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link MaterialAppearance#renderState} has backface culling enabled. - * @param {MaterialAppearance.MaterialSupport} [options.materialSupport=MaterialAppearance.MaterialSupport.TEXTURED] The type of materials that will be supported. - * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {RenderState} [options.renderState] Optional render state to override the default render state. - * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Materials.html|Cesium Sandcastle Material Appearance Demo} - * - * @example - * var primitive = new Cesium.Primitive({ - * geometryInstances : new Cesium.GeometryInstance({ - * geometry : new Cesium.WallGeometry({ - materialSupport : Cesium.MaterialAppearance.MaterialSupport.BASIC.vertexFormat, - * // ... - * }) - * }), - * appearance : new Cesium.MaterialAppearance({ - * material : Cesium.Material.fromType('Color'), - * faceForward : true - * }) + * @param {Property} [options.image] A Property specifying the Image, URI, or Canvas to use for the billboard. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the billboard. + * @param {Property} [options.scale=1.0] A numeric Property specifying the scale to apply to the image size. + * @param {Property} [options.horizontalOrigin=HorizontalOrigin.CENTER] A Property specifying the {@link HorizontalOrigin}. + * @param {Property} [options.verticalOrigin=VerticalOrigin.CENTER] A Property specifying the {@link VerticalOrigin}. + * @param {Property} [options.eyeOffset=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the eye offset. + * @param {Property} [options.pixelOffset=Cartesian2.ZERO] A {@link Cartesian2} Property specifying the pixel offset. + * @param {Property} [options.rotation=0] A numeric Property specifying the rotation about the alignedAxis. + * @param {Property} [options.alignedAxis=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the unit vector axis of rotation. + * @param {Property} [options.width] A numeric Property specifying the width of the billboard in pixels, overriding the native size. + * @param {Property} [options.height] A numeric Property specifying the height of the billboard in pixels, overriding the native size. + * @param {Property} [options.color=Color.WHITE] A Property specifying the tint {@link Color} of the image. + * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to scale the point based on distance from the camera. + * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera. + * @param {Property} [options.pixelOffsetScaleByDistance] A {@link NearFarScalar} Property used to set pixelOffset based on distance from the camera. + * @param {Property} [options.imageSubRegion] A Property specifying a {@link BoundingRectangle} that defines a sub-region of the image to use for the billboard, rather than the entire image, measured in pixels from the bottom-left. + * @param {Property} [options.sizeInMeters] A boolean Property specifying whether this billboard's size should be measured in meters. + * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this billboard will be displayed. + * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to. * - * }); + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Billboards.html|Cesium Sandcastle Billboard Demo} */ - function MaterialAppearance(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var translucent = defaultValue(options.translucent, true); - var closed = defaultValue(options.closed, false); - var materialSupport = defaultValue(options.materialSupport, MaterialAppearance.MaterialSupport.TEXTURED); - - /** - * The material used to determine the fragment color. Unlike other {@link MaterialAppearance} - * properties, this is not read-only, so an appearance's material can change on the fly. - * - * @type Material - * - * @default {@link Material.ColorType} - * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} - */ - this.material = (defined(options.material)) ? options.material : Material.fromType(Material.ColorType); - - /** - * When <code>true</code>, the geometry is expected to appear translucent. - * - * @type {Boolean} - * - * @default true - */ - this.translucent = translucent; - - this._vertexShaderSource = defaultValue(options.vertexShaderSource, materialSupport.vertexShaderSource); - this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, materialSupport.fragmentShaderSource); - this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); - this._closed = closed; - - // Non-derived members + function BillboardGraphics(options) { + this._image = undefined; + this._imageSubscription = undefined; + this._imageSubRegion = undefined; + this._imageSubRegionSubscription = undefined; + this._width = undefined; + this._widthSubscription = undefined; + this._height = undefined; + this._heightSubscription = undefined; + this._scale = undefined; + this._scaleSubscription = undefined; + this._rotation = undefined; + this._rotationSubscription = undefined; + this._alignedAxis = undefined; + this._alignedAxisSubscription = undefined; + this._horizontalOrigin = undefined; + this._horizontalOriginSubscription = undefined; + this._verticalOrigin = undefined; + this._verticalOriginSubscription = undefined; + this._color = undefined; + this._colorSubscription = undefined; + this._eyeOffset = undefined; + this._eyeOffsetSubscription = undefined; + this._heightReference = undefined; + this._heightReferenceSubscription = undefined; + this._pixelOffset = undefined; + this._pixelOffsetSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._scaleByDistance = undefined; + this._scaleByDistanceSubscription = undefined; + this._translucencyByDistance = undefined; + this._translucencyByDistanceSubscription = undefined; + this._pixelOffsetScaleByDistance = undefined; + this._pixelOffsetScaleByDistanceSubscription = undefined; + this._sizeInMeters = undefined; + this._sizeInMetersSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._disableDepthTestDistance = undefined; + this._disableDepthTestDistanceSubscription = undefined; + this._definitionChanged = new Event(); - this._materialSupport = materialSupport; - this._vertexFormat = materialSupport.vertexFormat; - this._flat = defaultValue(options.flat, false); - this._faceForward = defaultValue(options.faceForward, !closed); + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); } - defineProperties(MaterialAppearance.prototype, { + defineProperties(BillboardGraphics.prototype, { /** - * The GLSL source code for the vertex shader. - * - * @memberof MaterialAppearance.prototype + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof BillboardGraphics.prototype * - * @type {String} + * @type {Event} * @readonly */ - vertexShaderSource : { + definitionChanged : { get : function() { - return this._vertexShaderSource; + return this._definitionChanged; } }, /** - * The GLSL source code for the fragment shader. The full fragment shader - * source is built procedurally taking into account {@link MaterialAppearance#material}, - * {@link MaterialAppearance#flat}, and {@link MaterialAppearance#faceForward}. - * Use {@link MaterialAppearance#getFragmentShaderSource} to get the full source. - * - * @memberof MaterialAppearance.prototype - * - * @type {String} - * @readonly + * Gets or sets the Property specifying the Image, URI, or Canvas to use for the billboard. + * @memberof BillboardGraphics.prototype + * @type {Property} */ - fragmentShaderSource : { - get : function() { - return this._fragmentShaderSource; - } - }, + image : createPropertyDescriptor('image'), /** - * The WebGL fixed-function state to use when rendering the geometry. - * <p> - * The render state can be explicitly defined when constructing a {@link MaterialAppearance} - * instance, or it is set implicitly via {@link MaterialAppearance#translucent} - * and {@link MaterialAppearance#closed}. - * </p> - * - * @memberof MaterialAppearance.prototype - * - * @type {Object} - * @readonly + * Gets or sets the Property specifying a {@link BoundingRectangle} that defines a + * sub-region of the <code>image</code> to use for the billboard, rather than the entire image, + * measured in pixels from the bottom-left. + * @memberof BillboardGraphics.prototype + * @type {Property} */ - renderState : { - get : function() { - return this._renderState; - } - }, + imageSubRegion : createPropertyDescriptor('imageSubRegion'), /** - * When <code>true</code>, the geometry is expected to be closed so - * {@link MaterialAppearance#renderState} has backface culling enabled. - * If the viewer enters the geometry, it will not be visible. - * - * @memberof MaterialAppearance.prototype - * - * @type {Boolean} - * @readonly - * - * @default false + * Gets or sets the numeric Property specifying the uniform scale to apply to the image. + * A scale greater than <code>1.0</code> enlarges the billboard while a scale less than <code>1.0</code> shrinks it. + * <p> + * <div align='center'> + * <img src='Images/Billboard.setScale.png' width='400' height='300' /><br/> + * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, and <code>2.0</code>. + * </div> + * </p> + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default 1.0 */ - closed : { - get : function() { - return this._closed; - } - }, + scale : createPropertyDescriptor('scale'), /** - * The type of materials supported by this instance. This impacts the required - * {@link VertexFormat} and the complexity of the vertex and fragment shaders. - * - * @memberof MaterialAppearance.prototype - * - * @type {MaterialAppearance.MaterialSupport} - * @readonly - * - * @default {@link MaterialAppearance.MaterialSupport.TEXTURED} + * Gets or sets the numeric Property specifying the rotation of the image + * counter clockwise from the <code>alignedAxis</code>. + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default 0 */ - materialSupport : { - get : function() { - return this._materialSupport; - } - }, + rotation : createPropertyDescriptor('rotation'), /** - * The {@link VertexFormat} that this appearance instance is compatible with. - * A geometry can have more vertex attributes and still be compatible - at a - * potential performance cost - but it can't have less. - * - * @memberof MaterialAppearance.prototype - * - * @type VertexFormat - * @readonly - * - * @default {@link MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat} + * Gets or sets the {@link Cartesian3} Property specifying the unit vector axis of rotation + * in the fixed frame. When set to Cartesian3.ZERO the rotation is from the top of the screen. + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default Cartesian3.ZERO */ - vertexFormat : { - get : function() { - return this._vertexFormat; - } - }, + alignedAxis : createPropertyDescriptor('alignedAxis'), /** - * When <code>true</code>, flat shading is used in the fragment shader, - * which means lighting is not taking into account. - * - * @memberof MaterialAppearance.prototype - * - * @type {Boolean} - * @readonly - * - * @default false + * Gets or sets the Property specifying the {@link HorizontalOrigin}. + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default HorizontalOrigin.CENTER */ - flat : { - get : function() { - return this._flat; - } - }, + horizontalOrigin : createPropertyDescriptor('horizontalOrigin'), /** - * When <code>true</code>, the fragment shader flips the surface normal - * as needed to ensure that the normal faces the viewer to avoid - * dark spots. This is useful when both sides of a geometry should be - * shaded like {@link WallGeometry}. - * - * @memberof MaterialAppearance.prototype - * - * @type {Boolean} - * @readonly - * + * Gets or sets the Property specifying the {@link VerticalOrigin}. + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default VerticalOrigin.CENTER + */ + verticalOrigin : createPropertyDescriptor('verticalOrigin'), + + /** + * Gets or sets the Property specifying the {@link Color} that is multiplied with the <code>image</code>. + * This has two common use cases. First, the same white texture may be used by many different billboards, + * each with a different color, to create colored billboards. Second, the color's alpha component can be + * used to make the billboard translucent as shown below. An alpha of <code>0.0</code> makes the billboard + * transparent, and <code>1.0</code> makes the billboard opaque. + * <p> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><code>default</code><br/><img src='Images/Billboard.setColor.Alpha255.png' width='250' height='188' /></td> + * <td align='center'><code>alpha : 0.5</code><br/><img src='Images/Billboard.setColor.Alpha127.png' width='250' height='188' /></td> + * </tr></table> + * </div> + * </p> + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default Color.WHITE + */ + color : createPropertyDescriptor('color'), + + /** + * Gets or sets the {@link Cartesian3} Property specifying the billboard's offset in eye coordinates. + * Eye coordinates is a left-handed coordinate system, where <code>x</code> points towards the viewer's + * right, <code>y</code> points up, and <code>z</code> points into the screen. + * <p> + * An eye offset is commonly used to arrange multiple billboards or objects at the same position, e.g., to + * arrange a billboard above its corresponding 3D model. + * </p> + * Below, the billboard is positioned at the center of the Earth but an eye offset makes it always + * appear on top of the Earth regardless of the viewer's or Earth's orientation. + * <p> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> + * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> + * </tr></table> + * <code>b.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code> + * </div> + * </p> + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default Cartesian3.ZERO + */ + eyeOffset : createPropertyDescriptor('eyeOffset'), + + /** + * Gets or sets the Property specifying the {@link HeightReference}. + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default HeightReference.NONE + */ + heightReference : createPropertyDescriptor('heightReference'), + + /** + * Gets or sets the {@link Cartesian2} Property specifying the billboard's pixel offset in screen space + * from the origin of this billboard. This is commonly used to align multiple billboards and labels at + * the same position, e.g., an image and text. The screen space origin is the top, left corner of the + * canvas; <code>x</code> increases from left to right, and <code>y</code> increases from top to bottom. + * <p> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><code>default</code><br/><img src='Images/Billboard.setPixelOffset.default.png' width='250' height='188' /></td> + * <td align='center'><code>b.pixeloffset = new Cartesian2(50, 25);</code><br/><img src='Images/Billboard.setPixelOffset.x50y-25.png' width='250' height='188' /></td> + * </tr></table> + * The billboard's origin is indicated by the yellow point. + * </div> + * </p> + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default Cartesian2.ZERO + */ + pixelOffset : createPropertyDescriptor('pixelOffset'), + + /** + * Gets or sets the boolean Property specifying the visibility of the billboard. + * @memberof BillboardGraphics.prototype + * @type {Property} * @default true */ - faceForward : { - get : function() { - return this._faceForward; - } - } + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the numeric Property specifying the billboard's width in pixels. + * When undefined, the native width is used. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + width : createPropertyDescriptor('width'), + + /** + * Gets or sets the numeric Property specifying the height of the billboard in pixels. + * When undefined, the native height is used. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + height : createPropertyDescriptor('height'), + + /** + * Gets or sets {@link NearFarScalar} Property specifying the scale of the billboard based on the distance from the camera. + * A billboard's scale will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the billboard's scale remains clamped to the nearest bound. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + scaleByDistance : createPropertyDescriptor('scaleByDistance'), + + /** + * Gets or sets {@link NearFarScalar} Property specifying the translucency of the billboard based on the distance from the camera. + * A billboard's translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the billboard's translucency remains clamped to the nearest bound. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + translucencyByDistance : createPropertyDescriptor('translucencyByDistance'), + + /** + * Gets or sets {@link NearFarScalar} Property specifying the pixel offset of the billboard based on the distance from the camera. + * A billboard's pixel offset will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the billboard's pixel offset remains clamped to the nearest bound. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + pixelOffsetScaleByDistance : createPropertyDescriptor('pixelOffsetScaleByDistance'), + + /** + * Gets or sets the boolean Property specifying if this billboard's size will be measured in meters. + * @memberof BillboardGraphics.prototype + * @type {Property} + * @default false + */ + sizeInMeters : createPropertyDescriptor('sizeInMeters'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this billboard will be displayed. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') }); /** - * Procedurally creates the full GLSL fragment shader source. For {@link MaterialAppearance}, - * this is derived from {@link MaterialAppearance#fragmentShaderSource}, {@link MaterialAppearance#material}, - * {@link MaterialAppearance#flat}, and {@link MaterialAppearance#faceForward}. - * - * @function + * Duplicates this instance. * - * @returns {String} The full GLSL fragment shader source. + * @param {BillboardGraphics} [result] The object onto which to store the result. + * @returns {BillboardGraphics} The modified result parameter or a new instance if one was not provided. */ - MaterialAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; + BillboardGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new BillboardGraphics(this); + } + result.color = this._color; + result.eyeOffset = this._eyeOffset; + result.heightReference = this._heightReference; + result.horizontalOrigin = this._horizontalOrigin; + result.image = this._image; + result.imageSubRegion = this._imageSubRegion; + result.pixelOffset = this._pixelOffset; + result.scale = this._scale; + result.rotation = this._rotation; + result.alignedAxis = this._alignedAxis; + result.show = this._show; + result.verticalOrigin = this._verticalOrigin; + result.width = this._width; + result.height = this._height; + result.scaleByDistance = this._scaleByDistance; + result.translucencyByDistance = this._translucencyByDistance; + result.pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; + result.sizeInMeters = this._sizeInMeters; + result.distanceDisplayCondition = this._distanceDisplayCondition; + result.disableDepthTestDistance = this._disableDepthTestDistance; + return result; + }; /** - * Determines if the geometry is translucent based on {@link MaterialAppearance#translucent} and {@link Material#isTranslucent}. - * - * @function + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @param {BillboardGraphics} source The object to be merged into this object. */ - MaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; + BillboardGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.color = defaultValue(this._color, source.color); + this.eyeOffset = defaultValue(this._eyeOffset, source.eyeOffset); + this.heightReference = defaultValue(this._heightReference, source.heightReference); + this.horizontalOrigin = defaultValue(this._horizontalOrigin, source.horizontalOrigin); + this.image = defaultValue(this._image, source.image); + this.imageSubRegion = defaultValue(this._imageSubRegion, source.imageSubRegion); + this.pixelOffset = defaultValue(this._pixelOffset, source.pixelOffset); + this.scale = defaultValue(this._scale, source.scale); + this.rotation = defaultValue(this._rotation, source.rotation); + this.alignedAxis = defaultValue(this._alignedAxis, source.alignedAxis); + this.show = defaultValue(this._show, source.show); + this.verticalOrigin = defaultValue(this._verticalOrigin, source.verticalOrigin); + this.width = defaultValue(this._width, source.width); + this.height = defaultValue(this._height, source.height); + this.scaleByDistance = defaultValue(this._scaleByDistance, source.scaleByDistance); + this.translucencyByDistance = defaultValue(this._translucencyByDistance, source.translucencyByDistance); + this.pixelOffsetScaleByDistance = defaultValue(this._pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); + this.sizeInMeters = defaultValue(this._sizeInMeters, source.sizeInMeters); + this.distanceDisplayCondition = defaultValue(this._distanceDisplayCondition, source.distanceDisplayCondition); + this.disableDepthTestDistance = defaultValue(this._disableDepthTestDistance, source.disableDepthTestDistance); + }; - /** - * Creates a render state. This is not the final render state instance; instead, - * it can contain a subset of render state properties identical to the render state - * created in the context. - * - * @function - * - * @returns {Object} The render state. - */ - MaterialAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; + return BillboardGraphics; +}); + +define('Scene/HeightReference',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; /** - * Determines the type of {@link Material} that is supported by a - * {@link MaterialAppearance} instance. This is a trade-off between - * flexibility (a wide array of materials) and memory/performance - * (required vertex format and GLSL shader complexity. + * Represents the position relative to the terrain. + * + * @exports HeightReference */ - MaterialAppearance.MaterialSupport = { + var HeightReference = { /** - * Only basic materials, which require just <code>position</code> and - * <code>normal</code> vertex attributes, are supported. - * + * The position is absolute. + * @type {Number} * @constant */ - BASIC : freezeObject({ - vertexFormat : VertexFormat.POSITION_AND_NORMAL, - vertexShaderSource : BasicMaterialAppearanceVS, - fragmentShaderSource : BasicMaterialAppearanceFS - }), + NONE : 0, + /** - * Materials with textures, which require <code>position</code>, - * <code>normal</code>, and <code>st</code> vertex attributes, - * are supported. The vast majority of materials fall into this category. - * + * The position is clamped to the terrain. + * @type {Number} * @constant */ - TEXTURED : freezeObject({ - vertexFormat : VertexFormat.POSITION_NORMAL_AND_ST, - vertexShaderSource : TexturedMaterialAppearanceVS, - fragmentShaderSource : TexturedMaterialAppearanceFS - }), + CLAMP_TO_GROUND : 1, + /** - * All materials, including those that work in tangent space, are supported. - * This requires <code>position</code>, <code>normal</code>, <code>st</code>, - * <code>tangent</code>, and <code>bitangent</code> vertex attributes. - * + * The position height is the height above the terrain. + * @type {Number} * @constant */ - ALL : freezeObject({ - vertexFormat : VertexFormat.ALL, - vertexShaderSource : AllMaterialAppearanceVS, - fragmentShaderSource : AllMaterialAppearanceFS - }) + RELATIVE_TO_GROUND : 2 }; - return MaterialAppearance; + return freezeObject(HeightReference); }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/PerInstanceColorAppearanceFS',[],function() { - 'use strict'; - return "varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -varying vec4 v_color;\n\ -void main()\n\ -{\n\ -vec3 positionToEyeEC = -v_positionEC;\n\ -vec3 normalEC = normalize(v_normalEC);\n\ -#ifdef FACE_FORWARD\n\ -normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ -#endif\n\ -czm_materialInput materialInput;\n\ -materialInput.normalEC = normalEC;\n\ -materialInput.positionToEyeEC = positionToEyeEC;\n\ -czm_material material = czm_getDefaultMaterial(materialInput);\n\ -material.diffuse = v_color.rgb;\n\ -material.alpha = v_color.a;\n\ -gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/PerInstanceColorAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 normal;\n\ -attribute vec4 color;\n\ -attribute float batchId;\n\ -varying vec3 v_positionEC;\n\ -varying vec3 v_normalEC;\n\ -varying vec4 v_color;\n\ -void main()\n\ -{\n\ -vec4 p = czm_computePosition();\n\ -v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ -v_normalEC = czm_normal * normal;\n\ -v_color = color;\n\ -gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/PerInstanceFlatColorAppearanceFS',[],function() { - 'use strict'; - return "varying vec4 v_color;\n\ -void main()\n\ -{\n\ -gl_FragColor = v_color;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/PerInstanceFlatColorAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec4 color;\n\ -attribute float batchId;\n\ -varying vec4 v_color;\n\ -void main()\n\ -{\n\ -vec4 p = czm_computePosition();\n\ -v_color = color;\n\ -gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ -}\n\ -"; -}); -define('Scene/PerInstanceColorAppearance',[ - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/VertexFormat', - '../Shaders/Appearances/PerInstanceColorAppearanceFS', - '../Shaders/Appearances/PerInstanceColorAppearanceVS', - '../Shaders/Appearances/PerInstanceFlatColorAppearanceFS', - '../Shaders/Appearances/PerInstanceFlatColorAppearanceVS', - './Appearance' +define('Scene/HorizontalOrigin',[ + '../Core/freezeObject' ], function( - defaultValue, - defineProperties, - VertexFormat, - PerInstanceColorAppearanceFS, - PerInstanceColorAppearanceVS, - PerInstanceFlatColorAppearanceFS, - PerInstanceFlatColorAppearanceVS, - Appearance) { + freezeObject) { 'use strict'; /** - * An appearance for {@link GeometryInstance} instances with color attributes. - * This allows several geometry instances, each with a different color, to - * be drawn with the same {@link Primitive} as shown in the second example below. - * - * @alias PerInstanceColorAppearance - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. - * @param {Boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link PerInstanceColorAppearance#renderState} has backface culling enabled. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {RenderState} [options.renderState] Optional render state to override the default render state. - * - * @example - * // A solid white line segment - * var primitive = new Cesium.Primitive({ - * geometryInstances : new Cesium.GeometryInstance({ - * geometry : new Cesium.SimplePolylineGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * 0.0, 0.0, - * 5.0, 0.0 - * ]) - * }), - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0)) - * } - * }), - * appearance : new Cesium.PerInstanceColorAppearance({ - * flat : true, - * translucent : false - * }) - * }); - * - * // Two rectangles in a primitive, each with a different color - * var instance = new Cesium.GeometryInstance({ - * geometry : new Cesium.RectangleGeometry({ - * rectangle : Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0) - * }), - * attributes : { - * color : new Cesium.Color(1.0, 0.0, 0.0, 0.5) - * } - * }); + * The horizontal location of an origin relative to an object, e.g., a {@link Billboard} + * or {@link Label}. For example, setting the horizontal origin to <code>LEFT</code> + * or <code>RIGHT</code> will display a billboard to the left or right (in screen space) + * of the anchor position. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> + * </div> * - * var anotherInstance = new Cesium.GeometryInstance({ - * geometry : new Cesium.RectangleGeometry({ - * rectangle : Cesium.Rectangle.fromDegrees(0.0, 40.0, 10.0, 50.0) - * }), - * attributes : { - * color : new Cesium.Color(0.0, 0.0, 1.0, 0.5) - * } - * }); + * @exports HorizontalOrigin * - * var rectanglePrimitive = new Cesium.Primitive({ - * geometryInstances : [instance, anotherInstance], - * appearance : new Cesium.PerInstanceColorAppearance() - * }); + * @see Billboard#horizontalOrigin + * @see Label#horizontalOrigin */ - function PerInstanceColorAppearance(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var translucent = defaultValue(options.translucent, true); - var closed = defaultValue(options.closed, false); - var flat = defaultValue(options.flat, false); - var vs = flat ? PerInstanceFlatColorAppearanceVS : PerInstanceColorAppearanceVS; - var fs = flat ? PerInstanceFlatColorAppearanceFS : PerInstanceColorAppearanceFS; - var vertexFormat = flat ? PerInstanceColorAppearance.FLAT_VERTEX_FORMAT : PerInstanceColorAppearance.VERTEX_FORMAT; - + var HorizontalOrigin = { /** - * This property is part of the {@link Appearance} interface, but is not - * used by {@link PerInstanceColorAppearance} since a fully custom fragment shader is used. - * - * @type Material + * The origin is at the horizontal center of the object. * - * @default undefined + * @type {Number} + * @constant */ - this.material = undefined; + CENTER : 0, /** - * When <code>true</code>, the geometry is expected to appear translucent so - * {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. - * - * @type {Boolean} + * The origin is on the left side of the object. * - * @default true + * @type {Number} + * @constant */ - this.translucent = translucent; + LEFT : 1, - this._vertexShaderSource = defaultValue(options.vertexShaderSource, vs); - this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, fs); - this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); - this._closed = closed; + /** + * The origin is on the right side of the object. + * + * @type {Number} + * @constant + */ + RIGHT : -1 + }; - // Non-derived members + return freezeObject(HorizontalOrigin); +}); - this._vertexFormat = vertexFormat; - this._flat = flat; - this._faceForward = defaultValue(options.faceForward, !closed); - } +define('Scene/VerticalOrigin',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - defineProperties(PerInstanceColorAppearance.prototype, { + /** + * The vertical location of an origin relative to an object, e.g., a {@link Billboard} + * or {@link Label}. For example, setting the vertical origin to <code>TOP</code> + * or <code>BOTTOM</code> will display a billboard above or below (in screen space) + * the anchor position. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> + * </div> + * + * @exports VerticalOrigin + * + * @see Billboard#verticalOrigin + * @see Label#verticalOrigin + */ + var VerticalOrigin = { /** - * The GLSL source code for the vertex shader. - * - * @memberof PerInstanceColorAppearance.prototype + * The origin is at the vertical center between <code>BASELINE</code> and <code>TOP</code>. * - * @type {String} - * @readonly + * @type {Number} + * @constant */ - vertexShaderSource : { - get : function() { - return this._vertexShaderSource; - } - }, + CENTER : 0, /** - * The GLSL source code for the fragment shader. - * - * @memberof PerInstanceColorAppearance.prototype + * The origin is at the bottom of the object. * - * @type {String} - * @readonly + * @type {Number} + * @constant */ - fragmentShaderSource : { - get : function() { - return this._fragmentShaderSource; - } - }, + BOTTOM : 1, /** - * The WebGL fixed-function state to use when rendering the geometry. - * <p> - * The render state can be explicitly defined when constructing a {@link PerInstanceColorAppearance} - * instance, or it is set implicitly via {@link PerInstanceColorAppearance#translucent} - * and {@link PerInstanceColorAppearance#closed}. - * </p> - * - * @memberof PerInstanceColorAppearance.prototype + * If the object contains text, the origin is at the baseline of the text, else the origin is at the bottom of the object. * - * @type {Object} - * @readonly + * @type {Number} + * @constant */ - renderState : { - get : function() { - return this._renderState; - } - }, + BASELINE : 2, /** - * When <code>true</code>, the geometry is expected to be closed so - * {@link PerInstanceColorAppearance#renderState} has backface culling enabled. - * If the viewer enters the geometry, it will not be visible. - * - * @memberof PerInstanceColorAppearance.prototype - * - * @type {Boolean} - * @readonly + * The origin is at the top of the object. * - * @default false + * @type {Number} + * @constant */ - closed : { - get : function() { - return this._closed; - } - }, + TOP : -1 + }; + + return freezeObject(VerticalOrigin); +}); + +define('DataSources/BoundingSphereState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** + * The state of a BoundingSphere computation being performed by a {@link Visualizer}. + * @exports BoundingSphereState + * @private + */ + var BoundingSphereState = { /** - * The {@link VertexFormat} that this appearance instance is compatible with. - * A geometry can have more vertex attributes and still be compatible - at a - * potential performance cost - but it can't have less. - * - * @memberof PerInstanceColorAppearance.prototype - * - * @type VertexFormat - * @readonly + * The BoundingSphere has been computed. + * @type BoundingSphereState + * @constant */ - vertexFormat : { - get : function() { - return this._vertexFormat; - } - }, + DONE : 0, + /** + * The BoundingSphere is still being computed. + * @type BoundingSphereState + * @constant + */ + PENDING : 1, + /** + * The BoundingSphere does not exist. + * @type BoundingSphereState + * @constant + */ + FAILED : 2 + }; + + return freezeObject(BoundingSphereState); +}); + +define('DataSources/Property',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError) { + 'use strict'; + + /** + * The interface for all properties, which represent a value that can optionally vary over time. + * This type defines an interface and cannot be instantiated directly. + * + * @alias Property + * @constructor + * + * @see CompositeProperty + * @see ConstantProperty + * @see SampledProperty + * @see TimeIntervalCollectionProperty + * @see MaterialProperty + * @see PositionProperty + * @see ReferenceProperty + */ + function Property() { + DeveloperError.throwInstantiationError(); + } + defineProperties(Property.prototype, { /** - * When <code>true</code>, flat shading is used in the fragment shader, - * which means lighting is not taking into account. - * - * @memberof PerInstanceColorAppearance.prototype + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof Property.prototype * * @type {Boolean} * @readonly - * - * @default false */ - flat : { - get : function() { - return this._flat; - } + isConstant : { + get : DeveloperError.throwInstantiationError }, - /** - * When <code>true</code>, the fragment shader flips the surface normal - * as needed to ensure that the normal faces the viewer to avoid - * dark spots. This is useful when both sides of a geometry should be - * shaded like {@link WallGeometry}. - * - * @memberof PerInstanceColorAppearance.prototype + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof Property.prototype * - * @type {Boolean} + * @type {Event} * @readonly - * - * @default true */ - faceForward : { - get : function() { - return this._faceForward; - } + definitionChanged : { + get : DeveloperError.throwInstantiationError } }); /** - * The {@link VertexFormat} that all {@link PerInstanceColorAppearance} instances - * are compatible with. This requires only <code>position</code> and <code>st</code> - * attributes. - * - * @type VertexFormat + * Gets the value of the property at the provided time. + * @function * - * @constant + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. */ - PerInstanceColorAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_NORMAL; + Property.prototype.getValue = DeveloperError.throwInstantiationError; /** - * The {@link VertexFormat} that all {@link PerInstanceColorAppearance} instances - * are compatible with when {@link PerInstanceColorAppearance#flat} is <code>false</code>. - * This requires only a <code>position</code> attribute. - * - * @type VertexFormat + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * @function * - * @constant + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - PerInstanceColorAppearance.FLAT_VERTEX_FORMAT = VertexFormat.POSITION_ONLY; + Property.prototype.equals = DeveloperError.throwInstantiationError; /** - * Procedurally creates the full GLSL fragment shader source. For {@link PerInstanceColorAppearance}, - * this is derived from {@link PerInstanceColorAppearance#fragmentShaderSource}, {@link PerInstanceColorAppearance#flat}, - * and {@link PerInstanceColorAppearance#faceForward}. - * - * @function - * - * @returns {String} The full GLSL fragment shader source. + * @private */ - PerInstanceColorAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; + Property.equals = function(left, right) { + return left === right || (defined(left) && left.equals(right)); + }; /** - * Determines if the geometry is translucent based on {@link PerInstanceColorAppearance#translucent}. - * - * @function - * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @private */ - PerInstanceColorAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; + Property.arrayEquals = function(left, right) { + if (left === right) { + return true; + } + if ((!defined(left) || !defined(right)) || (left.length !== right.length)) { + return false; + } + var length = left.length; + for (var i = 0; i < length; i++) { + if (!Property.equals(left[i], right[i])) { + return false; + } + } + return true; + }; /** - * Creates a render state. This is not the final render state instance; instead, - * it can contain a subset of render state properties identical to the render state - * created in the context. - * - * @function - * - * @returns {Object} The render state. + * @private */ - PerInstanceColorAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; - - return PerInstanceColorAppearance; -}); + Property.isConstant = function(property) { + return !defined(property) || property.isConstant; + }; -define('Renderer/BufferUsage',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + /** + * @private + */ + Property.getValueOrUndefined = function(property, time, result) { + return defined(property) ? property.getValue(time, result) : undefined; + }; /** * @private */ - var BufferUsage = { - STREAM_DRAW : WebGLConstants.STREAM_DRAW, - STATIC_DRAW : WebGLConstants.STATIC_DRAW, - DYNAMIC_DRAW : WebGLConstants.DYNAMIC_DRAW, + Property.getValueOrDefault = function(property, time, valueDefault, result) { + return defined(property) ? defaultValue(property.getValue(time, result), valueDefault) : valueDefault; + }; - validate : function(bufferUsage) { - return ((bufferUsage === BufferUsage.STREAM_DRAW) || - (bufferUsage === BufferUsage.STATIC_DRAW) || - (bufferUsage === BufferUsage.DYNAMIC_DRAW)); + /** + * @private + */ + Property.getValueOrClonedDefault = function(property, time, valueDefault, result) { + var value; + if (defined(property)) { + value = property.getValue(time, result); + } + if (!defined(value)) { + value = valueDefault.clone(value); } + return value; }; - return freezeObject(BufferUsage); + return Property; }); -define('Renderer/DrawCommand',[ - '../Core/defaultValue', +define('DataSources/BillboardVisualizer',[ + '../Core/AssociativeArray', + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Color', '../Core/defined', - '../Core/defineProperties', - '../Core/PrimitiveType' + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/NearFarScalar', + '../Scene/HeightReference', + '../Scene/HorizontalOrigin', + '../Scene/VerticalOrigin', + './BoundingSphereState', + './Property' ], function( - defaultValue, + AssociativeArray, + BoundingRectangle, + Cartesian2, + Cartesian3, + Color, defined, - defineProperties, - PrimitiveType) { + destroyObject, + DeveloperError, + DistanceDisplayCondition, + NearFarScalar, + HeightReference, + HorizontalOrigin, + VerticalOrigin, + BoundingSphereState, + Property) { 'use strict'; + var defaultColor = Color.WHITE; + var defaultEyeOffset = Cartesian3.ZERO; + var defaultHeightReference = HeightReference.NONE; + var defaultPixelOffset = Cartesian2.ZERO; + var defaultScale = 1.0; + var defaultRotation = 0.0; + var defaultAlignedAxis = Cartesian3.ZERO; + var defaultHorizontalOrigin = HorizontalOrigin.CENTER; + var defaultVerticalOrigin = VerticalOrigin.CENTER; + var defaultSizeInMeters = false; + var defaultDisableDepthTestDistance = 0.0; + + var position = new Cartesian3(); + var color = new Color(); + var eyeOffset = new Cartesian3(); + var pixelOffset = new Cartesian2(); + var scaleByDistance = new NearFarScalar(); + var translucencyByDistance = new NearFarScalar(); + var pixelOffsetScaleByDistance = new NearFarScalar(); + var boundingRectangle = new BoundingRectangle(); + var distanceDisplayCondition = new DistanceDisplayCondition(); + + function EntityData(entity) { + this.entity = entity; + this.billboard = undefined; + this.textureValue = undefined; + } + /** - * Represents a command to the renderer for drawing. + * A {@link Visualizer} which maps {@link Entity#billboard} to a {@link Billboard}. + * @alias BillboardVisualizer + * @constructor * - * @private + * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities. + * @param {EntityCollection} entityCollection The entityCollection to visualize. */ - function DrawCommand(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function BillboardVisualizer(entityCluster, entityCollection) { + if (!defined(entityCluster)) { + throw new DeveloperError('entityCluster is required.'); + } + if (!defined(entityCollection)) { + throw new DeveloperError('entityCollection is required.'); + } + + entityCollection.collectionChanged.addEventListener(BillboardVisualizer.prototype._onCollectionChanged, this); - this._boundingVolume = options.boundingVolume; - this._orientedBoundingBox = options.orientedBoundingBox; - this._cull = defaultValue(options.cull, true); - this._modelMatrix = options.modelMatrix; - this._primitiveType = defaultValue(options.primitiveType, PrimitiveType.TRIANGLES); - this._vertexArray = options.vertexArray; - this._count = options.count; - this._offset = defaultValue(options.offset, 0); - this._instanceCount = defaultValue(options.instanceCount, 0); - this._shaderProgram = options.shaderProgram; - this._uniformMap = options.uniformMap; - this._renderState = options.renderState; - this._framebuffer = options.framebuffer; - this._pass = options.pass; - this._executeInClosestFrustum = defaultValue(options.executeInClosestFrustum, false); - this._owner = options.owner; - this._debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - this._debugOverlappingFrustums = 0; - this._castShadows = defaultValue(options.castShadows, false); - this._receiveShadows = defaultValue(options.receiveShadows, false); + this._cluster = entityCluster; + this._entityCollection = entityCollection; + this._items = new AssociativeArray(); + this._onCollectionChanged(entityCollection, entityCollection.values, [], []); + } - this.dirty = true; - this.lastDirtyTime = 0; + /** + * Updates the primitives created by this visualizer to match their + * Entity counterpart at the given time. + * + * @param {JulianDate} time The time to update to. + * @returns {Boolean} This function always returns true. + */ + BillboardVisualizer.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var items = this._items.values; + var cluster = this._cluster; - /** - * @private - */ - this.derivedCommands = {}; - } + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + var entity = item.entity; + var billboardGraphics = entity._billboard; + var textureValue; + var billboard = item.billboard; + var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(billboardGraphics._show, time, true); - defineProperties(DrawCommand.prototype, { - /** - * The bounding volume of the geometry in world space. This is used for culling and frustum selection. - * <p> - * For best rendering performance, use the tightest possible bounding volume. Although - * <code>undefined</code> is allowed, always try to provide a bounding volume to - * allow the tightest possible near and far planes to be computed for the scene, and - * minimize the number of frustums needed. - * </p> - * - * @memberof DrawCommand.prototype - * @type {Object} - * @default undefined - * - * @see DrawCommand#debugShowBoundingVolume - */ - boundingVolume : { - get : function() { - return this._boundingVolume; - }, - set : function(value) { - if (this._boundingVolume !== value) { - this._boundingVolume = value; - this.dirty = true; + if (show) { + position = Property.getValueOrUndefined(entity._position, time, position); + textureValue = Property.getValueOrUndefined(billboardGraphics._image, time); + show = defined(position) && defined(textureValue); + } + + if (!show) { + //don't bother creating or updating anything else + returnPrimitive(item, entity, cluster); + continue; + } + + if (!Property.isConstant(entity._position)) { + cluster._clusterDirty = true; + } + + if (!defined(billboard)) { + billboard = cluster.getBillboard(entity); + billboard.id = entity; + billboard.image = undefined; + item.billboard = billboard; + } + + billboard.show = show; + if (!defined(billboard.image) || item.textureValue !== textureValue) { + billboard.image = textureValue; + item.textureValue = textureValue; + } + billboard.position = position; + billboard.color = Property.getValueOrDefault(billboardGraphics._color, time, defaultColor, color); + billboard.eyeOffset = Property.getValueOrDefault(billboardGraphics._eyeOffset, time, defaultEyeOffset, eyeOffset); + billboard.heightReference = Property.getValueOrDefault(billboardGraphics._heightReference, time, defaultHeightReference); + billboard.pixelOffset = Property.getValueOrDefault(billboardGraphics._pixelOffset, time, defaultPixelOffset, pixelOffset); + billboard.scale = Property.getValueOrDefault(billboardGraphics._scale, time, defaultScale); + billboard.rotation = Property.getValueOrDefault(billboardGraphics._rotation, time, defaultRotation); + billboard.alignedAxis = Property.getValueOrDefault(billboardGraphics._alignedAxis, time, defaultAlignedAxis); + billboard.horizontalOrigin = Property.getValueOrDefault(billboardGraphics._horizontalOrigin, time, defaultHorizontalOrigin); + billboard.verticalOrigin = Property.getValueOrDefault(billboardGraphics._verticalOrigin, time, defaultVerticalOrigin); + billboard.width = Property.getValueOrUndefined(billboardGraphics._width, time); + billboard.height = Property.getValueOrUndefined(billboardGraphics._height, time); + billboard.scaleByDistance = Property.getValueOrUndefined(billboardGraphics._scaleByDistance, time, scaleByDistance); + billboard.translucencyByDistance = Property.getValueOrUndefined(billboardGraphics._translucencyByDistance, time, translucencyByDistance); + billboard.pixelOffsetScaleByDistance = Property.getValueOrUndefined(billboardGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance); + billboard.sizeInMeters = Property.getValueOrDefault(billboardGraphics._sizeInMeters, time, defaultSizeInMeters); + billboard.distanceDisplayCondition = Property.getValueOrUndefined(billboardGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + billboard.disableDepthTestDistance = Property.getValueOrDefault(billboardGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); + + var subRegion = Property.getValueOrUndefined(billboardGraphics._imageSubRegion, time, boundingRectangle); + if (defined(subRegion)) { + billboard.setImageSubRegion(billboard._imageId, subRegion); + } + } + return true; + }; + + /** + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. + * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private + */ + BillboardVisualizer.prototype.getBoundingSphere = function(entity, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var item = this._items.get(entity.id); + if (!defined(item) || !defined(item.billboard)) { + return BoundingSphereState.FAILED; + } + + var billboard = item.billboard; + if (billboard.heightReference === HeightReference.NONE) { + result.center = Cartesian3.clone(billboard.position, result.center); + } else { + if (!defined(billboard._clampedPosition)) { + return BoundingSphereState.PENDING; + } + result.center = Cartesian3.clone(billboard._clampedPosition, result.center); + } + result.radius = 0; + return BoundingSphereState.DONE; + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + BillboardVisualizer.prototype.isDestroyed = function() { + return false; + }; + + /** + * Removes and destroys all primitives created by this instance. + */ + BillboardVisualizer.prototype.destroy = function() { + this._entityCollection.collectionChanged.removeEventListener(BillboardVisualizer.prototype._onCollectionChanged, this); + var entities = this._entityCollection.values; + for (var i = 0; i < entities.length; i++) { + this._cluster.removeBillboard(entities[i]); + } + return destroyObject(this); + }; + + BillboardVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { + var i; + var entity; + var items = this._items; + var cluster = this._cluster; + + for (i = added.length - 1; i > -1; i--) { + entity = added[i]; + if (defined(entity._billboard) && defined(entity._position)) { + items.set(entity.id, new EntityData(entity)); + } + } + + for (i = changed.length - 1; i > -1; i--) { + entity = changed[i]; + if (defined(entity._billboard) && defined(entity._position)) { + if (!items.contains(entity.id)) { + items.set(entity.id, new EntityData(entity)); } + } else { + returnPrimitive(items.get(entity.id), entity, cluster); + items.remove(entity.id); } - }, + } + + for (i = removed.length - 1; i > -1; i--) { + entity = removed[i]; + returnPrimitive(items.get(entity.id), entity, cluster); + items.remove(entity.id); + } + }; + + function returnPrimitive(item, entity, cluster) { + if (defined(item)) { + item.billboard = undefined; + cluster.removeBillboard(entity); + } + } + + return BillboardVisualizer; +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/AllMaterialAppearanceFS',[],function() { + 'use strict'; + return "varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +varying vec3 v_tangentEC;\n\ +varying vec3 v_bitangentEC;\n\ +varying vec2 v_st;\n\ +void main()\n\ +{\n\ +vec3 positionToEyeEC = -v_positionEC;\n\ +mat3 tangentToEyeMatrix = czm_tangentToEyeSpaceMatrix(v_normalEC, v_tangentEC, v_bitangentEC);\n\ +vec3 normalEC = normalize(v_normalEC);\n\ +#ifdef FACE_FORWARD\n\ +normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ +#endif\n\ +czm_materialInput materialInput;\n\ +materialInput.normalEC = normalEC;\n\ +materialInput.tangentToEyeMatrix = tangentToEyeMatrix;\n\ +materialInput.positionToEyeEC = positionToEyeEC;\n\ +materialInput.st = v_st;\n\ +czm_material material = czm_getMaterial(materialInput);\n\ +#ifdef FLAT\n\ +gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ +#else\n\ +gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/AllMaterialAppearanceVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 normal;\n\ +attribute vec3 tangent;\n\ +attribute vec3 bitangent;\n\ +attribute vec2 st;\n\ +attribute float batchId;\n\ +varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +varying vec3 v_tangentEC;\n\ +varying vec3 v_bitangentEC;\n\ +varying vec2 v_st;\n\ +void main()\n\ +{\n\ +vec4 p = czm_computePosition();\n\ +v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ +v_normalEC = czm_normal * normal;\n\ +v_tangentEC = czm_normal * tangent;\n\ +v_bitangentEC = czm_normal * bitangent;\n\ +v_st = st;\n\ +gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/BasicMaterialAppearanceFS',[],function() { + 'use strict'; + return "varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +void main()\n\ +{\n\ +vec3 positionToEyeEC = -v_positionEC;\n\ +vec3 normalEC = normalize(v_normalEC);\n\ +#ifdef FACE_FORWARD\n\ +normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ +#endif\n\ +czm_materialInput materialInput;\n\ +materialInput.normalEC = normalEC;\n\ +materialInput.positionToEyeEC = positionToEyeEC;\n\ +czm_material material = czm_getMaterial(materialInput);\n\ +#ifdef FLAT\n\ +gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ +#else\n\ +gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/BasicMaterialAppearanceVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 normal;\n\ +attribute float batchId;\n\ +varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +void main()\n\ +{\n\ +vec4 p = czm_computePosition();\n\ +v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ +v_normalEC = czm_normal * normal;\n\ +gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/TexturedMaterialAppearanceFS',[],function() { + 'use strict'; + return "varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +varying vec2 v_st;\n\ +void main()\n\ +{\n\ +vec3 positionToEyeEC = -v_positionEC;\n\ +vec3 normalEC = normalize(v_normalEC);;\n\ +#ifdef FACE_FORWARD\n\ +normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ +#endif\n\ +czm_materialInput materialInput;\n\ +materialInput.normalEC = normalEC;\n\ +materialInput.positionToEyeEC = positionToEyeEC;\n\ +materialInput.st = v_st;\n\ +czm_material material = czm_getMaterial(materialInput);\n\ +#ifdef FLAT\n\ +gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ +#else\n\ +gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/TexturedMaterialAppearanceVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 normal;\n\ +attribute vec2 st;\n\ +attribute float batchId;\n\ +varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +varying vec2 v_st;\n\ +void main()\n\ +{\n\ +vec4 p = czm_computePosition();\n\ +v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ +v_normalEC = czm_normal * normal;\n\ +v_st = st;\n\ +gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ +}\n\ +"; +}); +define('Scene/BlendEquation',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + /** + * Determines how two pixels' values are combined. + * + * @exports BlendEquation + */ + var BlendEquation = { /** - * The oriented bounding box of the geometry in world space. If this is defined, it is used instead of - * {@link DrawCommand#boundingVolume} for plane intersection testing. - * - * @memberof DrawCommand.prototype - * @type {OrientedBoundingBox} - * @default undefined + * Pixel values are added componentwise. This is used in additive blending for translucency. * - * @see DrawCommand#debugShowBoundingVolume + * @type {Number} + * @constant */ - orientedBoundingBox : { - get : function() { - return this._orientedBoundingBox; - }, - set : function(value) { - if (this._orientedBoundingBox !== value) { - this._orientedBoundingBox = value; - this.dirty = true; - } - } - }, + ADD : WebGLConstants.FUNC_ADD, /** - * When <code>true</code>, the renderer frustum and horizon culls the command based on its {@link DrawCommand#boundingVolume}. - * If the command was already culled, set this to <code>false</code> for a performance improvement. + * Pixel values are subtracted componentwise (source - destination). This is used in alpha blending for translucency. * - * @memberof DrawCommand.prototype - * @type {Boolean} - * @default true + * @type {Number} + * @constant */ - cull : { - get : function() { - return this._cull; - }, - set : function(value) { - if (this._cull !== value) { - this._cull = value; - this.dirty = true; - } - } - }, + SUBTRACT : WebGLConstants.FUNC_SUBTRACT, /** - * The transformation from the geometry in model space to world space. - * <p> - * When <code>undefined</code>, the geometry is assumed to be defined in world space. - * </p> + * Pixel values are subtracted componentwise (destination - source). * - * @memberof DrawCommand.prototype - * @type {Matrix4} - * @default undefined + * @type {Number} + * @constant */ - modelMatrix : { - get : function() { - return this._modelMatrix; - }, - set : function(value) { - if (this._modelMatrix !== value) { - this._modelMatrix = value; - this.dirty = true; - } - } - }, + REVERSE_SUBTRACT : WebGLConstants.FUNC_REVERSE_SUBTRACT, /** - * The type of geometry in the vertex array. + * Pixel values are given to the minimum function (min(source, destination)). * - * @memberof DrawCommand.prototype - * @type {PrimitiveType} - * @default PrimitiveType.TRIANGLES + * This equation operates on each pixel color component. + * + * @type {Number} + * @constant */ - primitiveType : { - get : function() { - return this._primitiveType; - }, - set : function(value) { - if (this._primitiveType !== value) { - this._primitiveType = value; - this.dirty = true; - } - } - }, + MIN : WebGLConstants.MIN, /** - * The vertex array. + * Pixel values are given to the maximum function (max(source, destination)). * - * @memberof DrawCommand.prototype - * @type {VertexArray} - * @default undefined + * This equation operates on each pixel color component. + * + * @type {Number} + * @constant */ - vertexArray : { - get : function() { - return this._vertexArray; - }, - set : function(value) { - if (this._vertexArray !== value) { - this._vertexArray = value; - this.dirty = true; - } - } - }, + MAX : WebGLConstants.MAX + }; + + return freezeObject(BlendEquation); +}); + +define('Scene/BlendFunction',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + /** + * Determines how blending factors are computed. + * + * @exports BlendFunction + */ + var BlendFunction = { /** - * The number of vertices to draw in the vertex array. + * The blend factor is zero. * - * @memberof DrawCommand.prototype * @type {Number} - * @default undefined + * @constant */ - count : { - get : function() { - return this._count; - }, - set : function(value) { - if (this._count !== value) { - this._count = value; - this.dirty = true; - } - } - }, + ZERO : WebGLConstants.ZERO, /** - * The offset to start drawing in the vertex array. + * The blend factor is one. * - * @memberof DrawCommand.prototype * @type {Number} - * @default 0 + * @constant */ - offset : { - get : function() { - return this._offset; - }, - set : function(value) { - if (this._offset !== value) { - this._offset = value; - this.dirty = true; - } - } - }, + ONE : WebGLConstants.ONE, /** - * The number of instances to draw. + * The blend factor is the source color. * - * @memberof DrawCommand.prototype * @type {Number} - * @default 0 + * @constant */ - instanceCount : { - get : function() { - return this._instanceCount; - }, - set : function(value) { - if (this._instanceCount !== value) { - this._instanceCount = value; - this.dirty = true; - } - } - }, + SOURCE_COLOR : WebGLConstants.SRC_COLOR, /** - * The shader program to apply. + * The blend factor is one minus the source color. * - * @memberof DrawCommand.prototype - * @type {ShaderProgram} - * @default undefined + * @type {Number} + * @constant */ - shaderProgram : { - get : function() { - return this._shaderProgram; - }, - set : function(value) { - if (this._shaderProgram !== value) { - this._shaderProgram = value; - this.dirty = true; - } - } - }, + ONE_MINUS_SOURCE_COLOR : WebGLConstants.ONE_MINUS_SRC_COLOR, /** - * Whether this command should cast shadows when shadowing is enabled. + * The blend factor is the destination color. * - * @memberof DrawCommand.prototype - * @type {Boolean} - * @default false + * @type {Number} + * @constant */ - castShadows : { - get : function() { - return this._castShadows; - }, - set : function(value) { - if (this._castShadows !== value) { - this._castShadows = value; - this.dirty = true; - } - } - }, + DESTINATION_COLOR : WebGLConstants.DST_COLOR, /** - * Whether this command should receive shadows when shadowing is enabled. + * The blend factor is one minus the destination color. * - * @memberof DrawCommand.prototype - * @type {Boolean} - * @default false + * @type {Number} + * @constant */ - receiveShadows : { - get : function() { - return this._receiveShadows; - }, - set : function(value) { - if (this._receiveShadows !== value) { - this._receiveShadows = value; - this.dirty = true; - } - } - }, + ONE_MINUS_DESTINATION_COLOR : WebGLConstants.ONE_MINUS_DST_COLOR, /** - * An object with functions whose names match the uniforms in the shader program - * and return values to set those uniforms. + * The blend factor is the source alpha. * - * @memberof DrawCommand.prototype - * @type {Object} - * @default undefined + * @type {Number} + * @constant */ - uniformMap : { - get : function() { - return this._uniformMap; - }, - set : function(value) { - if (this._uniformMap !== value) { - this._uniformMap = value; - this.dirty = true; - } - } - }, + SOURCE_ALPHA : WebGLConstants.SRC_ALPHA, /** - * The render state. + * The blend factor is one minus the source alpha. * - * @memberof DrawCommand.prototype - * @type {RenderState} - * @default undefined + * @type {Number} + * @constant */ - renderState : { - get : function() { - return this._renderState; - }, - set : function(value) { - if (this._renderState !== value) { - this._renderState = value; - this.dirty = true; - } - } - }, + ONE_MINUS_SOURCE_ALPHA : WebGLConstants.ONE_MINUS_SRC_ALPHA, /** - * The framebuffer to draw to. + * The blend factor is the destination alpha. * - * @memberof DrawCommand.prototype - * @type {Framebuffer} - * @default undefined + * @type {Number} + * @constant */ - framebuffer : { - get : function() { - return this._framebuffer; - }, - set : function(value) { - if (this._framebuffer !== value) { - this._framebuffer = value; - this.dirty = true; - } - } - }, + DESTINATION_ALPHA : WebGLConstants.DST_ALPHA, /** - * The pass when to render. + * The blend factor is one minus the destination alpha. * - * @memberof DrawCommand.prototype - * @type {Pass} - * @default undefined + * @type {Number} + * @constant */ - pass : { - get : function() { - return this._pass; - }, - set : function(value) { - if (this._pass !== value) { - this._pass = value; - this.dirty = true; - } - } - }, + ONE_MINUS_DESTINATION_ALPHA : WebGLConstants.ONE_MINUS_DST_ALPHA, /** - * Specifies if this command is only to be executed in the frustum closest - * to the eye containing the bounding volume. Defaults to <code>false</code>. + * The blend factor is the constant color. * - * @memberof DrawCommand.prototype - * @type {Boolean} - * @default false + * @type {Number} + * @constant */ - executeInClosestFrustum : { - get : function() { - return this._executeInClosestFrustum; - }, - set : function(value) { - if (this._executeInClosestFrustum !== value) { - this._executeInClosestFrustum = value; - this.dirty = true; - } - } - }, + CONSTANT_COLOR : WebGLConstants.CONSTANT_COLOR, /** - * The object who created this command. This is useful for debugging command - * execution; it allows us to see who created a command when we only have a - * reference to the command, and can be used to selectively execute commands - * with {@link Scene#debugCommandFilter}. - * - * @memberof DrawCommand.prototype - * @type {Object} - * @default undefined + * The blend factor is one minus the constant color. * - * @see Scene#debugCommandFilter + * @type {Number} + * @constant */ - owner : { - get : function() { - return this._owner; - }, - set : function(value) { - if (this._owner !== value) { - this._owner = value; - this.dirty = true; - } - } - }, + ONE_MINUS_CONSTANT_COLOR : WebGLConstants.ONE_MINUS_CONSTANT_ALPHA, /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the {@link DrawCommand#boundingVolume} for this command, assuming it is a sphere, when the command executes. - * </p> - * - * @memberof DrawCommand.prototype - * @type {Boolean} - * @default false + * The blend factor is the constant alpha. * - * @see DrawCommand#boundingVolume + * @type {Number} + * @constant */ - debugShowBoundingVolume : { - get : function() { - return this._debugShowBoundingVolume; - }, - set : function(value) { - if (this._debugShowBoundingVolume !== value) { - this._debugShowBoundingVolume = value; - this.dirty = true; - } - } - }, + CONSTANT_ALPHA : WebGLConstants.CONSTANT_ALPHA, /** - * Used to implement Scene.debugShowFrustums. - * @private + * The blend factor is one minus the constant alpha. + * + * @type {Number} + * @constant */ - debugOverlappingFrustums : { - get : function() { - return this._debugOverlappingFrustums; - }, - set : function(value) { - if (this._debugOverlappingFrustums !== value) { - this._debugOverlappingFrustums = value; - this.dirty = true; - } - } - } - }); - - /** - * @private - */ - DrawCommand.shallowClone = function(command, result) { - if (!defined(command)) { - return undefined; - } - if (!defined(result)) { - result = new DrawCommand(); - } + ONE_MINUS_CONSTANT_ALPHA : WebGLConstants.ONE_MINUS_CONSTANT_ALPHA, - result._boundingVolume = command._boundingVolume; - result._orientedBoundingBox = command._orientedBoundingBox; - result._cull = command._cull; - result._modelMatrix = command._modelMatrix; - result._primitiveType = command._primitiveType; - result._vertexArray = command._vertexArray; - result._count = command._count; - result._offset = command._offset; - result._instanceCount = command._instanceCount; - result._shaderProgram = command._shaderProgram; - result._uniformMap = command._uniformMap; - result._renderState = command._renderState; - result._framebuffer = command._framebuffer; - result._pass = command._pass; - result._executeInClosestFrustum = command._executeInClosestFrustum; - result._owner = command._owner; - result._debugShowBoundingVolume = command._debugShowBoundingVolume; - result._debugOverlappingFrustums = command._debugOverlappingFrustums; - result._castShadows = command._castShadows; - result._receiveShadows = command._receiveShadows; + /** + * The blend factor is the saturated source alpha. + * + * @type {Number} + * @constant + */ + SOURCE_ALPHA_SATURATE : WebGLConstants.SRC_ALPHA_SATURATE + }; - result.dirty = true; - result.lastDirtyTime = 0; + return freezeObject(BlendFunction); +}); - return result; - }; +define('Scene/BlendingState',[ + '../Core/freezeObject', + './BlendEquation', + './BlendFunction' + ], function( + freezeObject, + BlendEquation, + BlendFunction) { + 'use strict'; /** - * Executes the draw command. + * The blending state combines {@link BlendEquation} and {@link BlendFunction} and the + * <code>enabled</code> flag to define the full blending state for combining source and + * destination fragments when rendering. + * <p> + * This is a helper when using custom render states with {@link Appearance#renderState}. + * </p> * - * @param {Context} context The renderer context in which to draw. - * @param {PassState} [passState] The state for the current render pass. + * @exports BlendingState */ - DrawCommand.prototype.execute = function(context, passState) { - context.draw(this, passState); + var BlendingState = { + /** + * Blending is disabled. + * + * @type {Object} + * @constant + */ + DISABLED : freezeObject({ + enabled : false + }), + + /** + * Blending is enabled using alpha blending, <code>source(source.alpha) + destination(1 - source.alpha)</code>. + * + * @type {Object} + * @constant + */ + ALPHA_BLEND : freezeObject({ + enabled : true, + equationRgb : BlendEquation.ADD, + equationAlpha : BlendEquation.ADD, + functionSourceRgb : BlendFunction.SOURCE_ALPHA, + functionSourceAlpha : BlendFunction.SOURCE_ALPHA, + functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA, + functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA + }), + + /** + * Blending is enabled using alpha blending with premultiplied alpha, <code>source + destination(1 - source.alpha)</code>. + * + * @type {Object} + * @constant + */ + PRE_MULTIPLIED_ALPHA_BLEND : freezeObject({ + enabled : true, + equationRgb : BlendEquation.ADD, + equationAlpha : BlendEquation.ADD, + functionSourceRgb : BlendFunction.ONE, + functionSourceAlpha : BlendFunction.ONE, + functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA, + functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA + }), + + /** + * Blending is enabled using additive blending, <code>source(source.alpha) + destination</code>. + * + * @type {Object} + * @constant + */ + ADDITIVE_BLEND : freezeObject({ + enabled : true, + equationRgb : BlendEquation.ADD, + equationAlpha : BlendEquation.ADD, + functionSourceRgb : BlendFunction.SOURCE_ALPHA, + functionSourceAlpha : BlendFunction.SOURCE_ALPHA, + functionDestinationRgb : BlendFunction.ONE, + functionDestinationAlpha : BlendFunction.ONE + }) }; - return DrawCommand; + return freezeObject(BlendingState); }); -define('Renderer/Pass',[ - '../Core/freezeObject' +define('Scene/CullFace',[ + '../Core/freezeObject', + '../Core/WebGLConstants' ], function( - freezeObject) { + freezeObject, + WebGLConstants) { 'use strict'; /** - * The render pass for a command. + * Determines which triangles, if any, are culled. * - * @private + * @exports CullFace */ - var Pass = { - // If you add/modify/remove Pass constants, also change the automatic GLSL constants - // that start with 'czm_pass' - // - // Commands are executed in order by pass up to the translucent pass. - // Translucent geometry needs special handling (sorting/OIT). The compute pass - // is executed first and the overlay pass is executed last. Both are not sorted - // by frustum. - ENVIRONMENT : 0, - COMPUTE : 1, - GLOBE : 2, - TERRAIN_CLASSIFICATION : 3, - CESIUM_3D_TILE : 4, - CESIUM_3D_TILE_CLASSIFICATION : 5, - CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW : 6, - OPAQUE : 7, - TRANSLUCENT : 8, - OVERLAY : 9, - NUMBER_OF_PASSES : 10 - }; - - return freezeObject(Pass); -}); - -/*global define*/ -define('Renderer/freezeRenderState',[ - '../Core/freezeObject' - ], function(freezeObject) { - 'use strict'; - + var CullFace = { /** - * Returns frozen renderState as well as all of the object literal properties. This function is deep object freeze - * function ignoring properties named "_applyFunctions". - * - * @private + * Front-facing triangles are culled. * - * @param {Object} renderState - * @returns {Object} Returns frozen renderState. + * @type {Number} + * @constant + */ + FRONT : WebGLConstants.FRONT, + + /** + * Back-facing triangles are culled. * + * @type {Number} + * @constant */ - function freezeRenderState(renderState) { - if (typeof renderState !== 'object' || renderState === null) { - return renderState; - } + BACK : WebGLConstants.BACK, - var propName; - var propNames = Object.keys(renderState); + /** + * Both front-facing and back-facing triangles are culled. + * + * @type {Number} + * @constant + */ + FRONT_AND_BACK : WebGLConstants.FRONT_AND_BACK + }; - for (var i = 0; i < propNames.length; i++) { - propName = propNames[i]; - if (renderState.hasOwnProperty(propName) && propName !== '_applyFunctions') { - renderState[propName] = freezeRenderState(renderState[propName]); - } - } - return freezeObject(renderState); - } - return freezeRenderState; + return freezeObject(CullFace); }); -define('Renderer/RenderState',[ - '../Core/BoundingRectangle', - '../Core/Color', +define('Scene/Appearance',[ + '../Core/clone', + '../Core/combine', '../Core/defaultValue', '../Core/defined', - '../Core/DeveloperError', - '../Core/WebGLConstants', - '../Core/WindingOrder', - './ContextLimits', - './freezeRenderState' + '../Core/defineProperties', + './BlendingState', + './CullFace' ], function( - BoundingRectangle, - Color, + clone, + combine, defaultValue, defined, - DeveloperError, - WebGLConstants, - WindingOrder, - ContextLimits, - freezeRenderState) { + defineProperties, + BlendingState, + CullFace) { 'use strict'; - function validateBlendEquation(blendEquation) { - return ((blendEquation === WebGLConstants.FUNC_ADD) || - (blendEquation === WebGLConstants.FUNC_SUBTRACT) || - (blendEquation === WebGLConstants.FUNC_REVERSE_SUBTRACT) || - (blendEquation === WebGLConstants.MIN) || - (blendEquation === WebGLConstants.MAX)); - } + /** + * An appearance defines the full GLSL vertex and fragment shaders and the + * render state used to draw a {@link Primitive}. All appearances implement + * this base <code>Appearance</code> interface. + * + * @alias Appearance + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link Appearance#renderState} has alpha blending enabled. + * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link Appearance#renderState} has backface culling enabled. + * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. + * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {RenderState} [options.renderState] Optional render state to override the default render state. + * + * @see MaterialAppearance + * @see EllipsoidSurfaceAppearance + * @see PerInstanceColorAppearance + * @see DebugAppearance + * @see PolylineColorAppearance + * @see PolylineMaterialAppearance + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + */ + function Appearance(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - function validateBlendFunction(blendFunction) { - return ((blendFunction === WebGLConstants.ZERO) || - (blendFunction === WebGLConstants.ONE) || - (blendFunction === WebGLConstants.SRC_COLOR) || - (blendFunction === WebGLConstants.ONE_MINUS_SRC_COLOR) || - (blendFunction === WebGLConstants.DST_COLOR) || - (blendFunction === WebGLConstants.ONE_MINUS_DST_COLOR) || - (blendFunction === WebGLConstants.SRC_ALPHA) || - (blendFunction === WebGLConstants.ONE_MINUS_SRC_ALPHA) || - (blendFunction === WebGLConstants.DST_ALPHA) || - (blendFunction === WebGLConstants.ONE_MINUS_DST_ALPHA) || - (blendFunction === WebGLConstants.CONSTANT_COLOR) || - (blendFunction === WebGLConstants.ONE_MINUS_CONSTANT_COLOR) || - (blendFunction === WebGLConstants.CONSTANT_ALPHA) || - (blendFunction === WebGLConstants.ONE_MINUS_CONSTANT_ALPHA) || - (blendFunction === WebGLConstants.SRC_ALPHA_SATURATE)); - } + /** + * The material used to determine the fragment color. Unlike other {@link Appearance} + * properties, this is not read-only, so an appearance's material can change on the fly. + * + * @type Material + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + */ + this.material = options.material; - function validateCullFace(cullFace) { - return ((cullFace === WebGLConstants.FRONT) || - (cullFace === WebGLConstants.BACK) || - (cullFace === WebGLConstants.FRONT_AND_BACK)); + /** + * When <code>true</code>, the geometry is expected to appear translucent. + * + * @type {Boolean} + * + * @default true + */ + this.translucent = defaultValue(options.translucent, true); + + this._vertexShaderSource = options.vertexShaderSource; + this._fragmentShaderSource = options.fragmentShaderSource; + this._renderState = options.renderState; + this._closed = defaultValue(options.closed, false); } - function validateDepthFunction(depthFunction) { - return ((depthFunction === WebGLConstants.NEVER) || - (depthFunction === WebGLConstants.LESS) || - (depthFunction === WebGLConstants.EQUAL) || - (depthFunction === WebGLConstants.LEQUAL) || - (depthFunction === WebGLConstants.GREATER) || - (depthFunction === WebGLConstants.NOTEQUAL) || - (depthFunction === WebGLConstants.GEQUAL) || - (depthFunction === WebGLConstants.ALWAYS)); - } - - function validateStencilFunction(stencilFunction) { - return ((stencilFunction === WebGLConstants.NEVER) || - (stencilFunction === WebGLConstants.LESS) || - (stencilFunction === WebGLConstants.EQUAL) || - (stencilFunction === WebGLConstants.LEQUAL) || - (stencilFunction === WebGLConstants.GREATER) || - (stencilFunction === WebGLConstants.NOTEQUAL) || - (stencilFunction === WebGLConstants.GEQUAL) || - (stencilFunction === WebGLConstants.ALWAYS)); - } - - function validateStencilOperation(stencilOperation) { - return ((stencilOperation === WebGLConstants.ZERO) || - (stencilOperation === WebGLConstants.KEEP) || - (stencilOperation === WebGLConstants.REPLACE) || - (stencilOperation === WebGLConstants.INCR) || - (stencilOperation === WebGLConstants.DECR) || - (stencilOperation === WebGLConstants.INVERT) || - (stencilOperation === WebGLConstants.INCR_WRAP) || - (stencilOperation === WebGLConstants.DECR_WRAP)); - } - - /** - * @private - */ - function RenderState(renderState) { - var rs = defaultValue(renderState, {}); - var cull = defaultValue(rs.cull, {}); - var polygonOffset = defaultValue(rs.polygonOffset, {}); - var scissorTest = defaultValue(rs.scissorTest, {}); - var scissorTestRectangle = defaultValue(scissorTest.rectangle, {}); - var depthRange = defaultValue(rs.depthRange, {}); - var depthTest = defaultValue(rs.depthTest, {}); - var colorMask = defaultValue(rs.colorMask, {}); - var blending = defaultValue(rs.blending, {}); - var blendingColor = defaultValue(blending.color, {}); - var stencilTest = defaultValue(rs.stencilTest, {}); - var stencilTestFrontOperation = defaultValue(stencilTest.frontOperation, {}); - var stencilTestBackOperation = defaultValue(stencilTest.backOperation, {}); - var sampleCoverage = defaultValue(rs.sampleCoverage, {}); - var viewport = rs.viewport; - - this.frontFace = defaultValue(rs.frontFace, WindingOrder.COUNTER_CLOCKWISE); - this.cull = { - enabled : defaultValue(cull.enabled, false), - face : defaultValue(cull.face, WebGLConstants.BACK) - }; - this.lineWidth = defaultValue(rs.lineWidth, 1.0); - this.polygonOffset = { - enabled : defaultValue(polygonOffset.enabled, false), - factor : defaultValue(polygonOffset.factor, 0), - units : defaultValue(polygonOffset.units, 0) - }; - this.scissorTest = { - enabled : defaultValue(scissorTest.enabled, false), - rectangle : BoundingRectangle.clone(scissorTestRectangle) - }; - this.depthRange = { - near : defaultValue(depthRange.near, 0), - far : defaultValue(depthRange.far, 1) - }; - this.depthTest = { - enabled : defaultValue(depthTest.enabled, false), - func : defaultValue(depthTest.func, WebGLConstants.LESS) // func, because function is a JavaScript keyword - }; - this.colorMask = { - red : defaultValue(colorMask.red, true), - green : defaultValue(colorMask.green, true), - blue : defaultValue(colorMask.blue, true), - alpha : defaultValue(colorMask.alpha, true) - }; - this.depthMask = defaultValue(rs.depthMask, true); - this.stencilMask = defaultValue(rs.stencilMask, ~0); - this.blending = { - enabled : defaultValue(blending.enabled, false), - color : new Color( - defaultValue(blendingColor.red, 0.0), - defaultValue(blendingColor.green, 0.0), - defaultValue(blendingColor.blue, 0.0), - defaultValue(blendingColor.alpha, 0.0) - ), - equationRgb : defaultValue(blending.equationRgb, WebGLConstants.FUNC_ADD), - equationAlpha : defaultValue(blending.equationAlpha, WebGLConstants.FUNC_ADD), - functionSourceRgb : defaultValue(blending.functionSourceRgb, WebGLConstants.ONE), - functionSourceAlpha : defaultValue(blending.functionSourceAlpha, WebGLConstants.ONE), - functionDestinationRgb : defaultValue(blending.functionDestinationRgb, WebGLConstants.ZERO), - functionDestinationAlpha : defaultValue(blending.functionDestinationAlpha, WebGLConstants.ZERO) - }; - this.stencilTest = { - enabled : defaultValue(stencilTest.enabled, false), - frontFunction : defaultValue(stencilTest.frontFunction, WebGLConstants.ALWAYS), - backFunction : defaultValue(stencilTest.backFunction, WebGLConstants.ALWAYS), - reference : defaultValue(stencilTest.reference, 0), - mask : defaultValue(stencilTest.mask, ~0), - frontOperation : { - fail : defaultValue(stencilTestFrontOperation.fail, WebGLConstants.KEEP), - zFail : defaultValue(stencilTestFrontOperation.zFail, WebGLConstants.KEEP), - zPass : defaultValue(stencilTestFrontOperation.zPass, WebGLConstants.KEEP) - }, - backOperation : { - fail : defaultValue(stencilTestBackOperation.fail, WebGLConstants.KEEP), - zFail : defaultValue(stencilTestBackOperation.zFail, WebGLConstants.KEEP), - zPass : defaultValue(stencilTestBackOperation.zPass, WebGLConstants.KEEP) + defineProperties(Appearance.prototype, { + /** + * The GLSL source code for the vertex shader. + * + * @memberof Appearance.prototype + * + * @type {String} + * @readonly + */ + vertexShaderSource : { + get : function() { + return this._vertexShaderSource; } - }; - this.sampleCoverage = { - enabled : defaultValue(sampleCoverage.enabled, false), - value : defaultValue(sampleCoverage.value, 1.0), - invert : defaultValue(sampleCoverage.invert, false) - }; - this.viewport = (defined(viewport)) ? new BoundingRectangle(viewport.x, viewport.y, viewport.width, viewport.height) : undefined; - - if ((this.lineWidth < ContextLimits.minimumAliasedLineWidth) || - (this.lineWidth > ContextLimits.maximumAliasedLineWidth)) { - throw new DeveloperError('renderState.lineWidth is out of range. Check minimumAliasedLineWidth and maximumAliasedLineWidth.'); - } - if (!WindingOrder.validate(this.frontFace)) { - throw new DeveloperError('Invalid renderState.frontFace.'); - } - if (!validateCullFace(this.cull.face)) { - throw new DeveloperError('Invalid renderState.cull.face.'); - } - if ((this.scissorTest.rectangle.width < 0) || - (this.scissorTest.rectangle.height < 0)) { - throw new DeveloperError('renderState.scissorTest.rectangle.width and renderState.scissorTest.rectangle.height must be greater than or equal to zero.'); - } - if (this.depthRange.near > this.depthRange.far) { - // WebGL specific - not an error in GL ES - throw new DeveloperError('renderState.depthRange.near can not be greater than renderState.depthRange.far.'); - } - if (this.depthRange.near < 0) { - // Would be clamped by GL - throw new DeveloperError('renderState.depthRange.near must be greater than or equal to zero.'); - } - if (this.depthRange.far > 1) { - // Would be clamped by GL - throw new DeveloperError('renderState.depthRange.far must be less than or equal to one.'); - } - if (!validateDepthFunction(this.depthTest.func)) { - throw new DeveloperError('Invalid renderState.depthTest.func.'); - } - if ((this.blending.color.red < 0.0) || (this.blending.color.red > 1.0) || - (this.blending.color.green < 0.0) || (this.blending.color.green > 1.0) || - (this.blending.color.blue < 0.0) || (this.blending.color.blue > 1.0) || - (this.blending.color.alpha < 0.0) || (this.blending.color.alpha > 1.0)) { - // Would be clamped by GL - throw new DeveloperError('renderState.blending.color components must be greater than or equal to zero and less than or equal to one.'); - } - if (!validateBlendEquation(this.blending.equationRgb)) { - throw new DeveloperError('Invalid renderState.blending.equationRgb.'); - } - if (!validateBlendEquation(this.blending.equationAlpha)) { - throw new DeveloperError('Invalid renderState.blending.equationAlpha.'); - } - if (!validateBlendFunction(this.blending.functionSourceRgb)) { - throw new DeveloperError('Invalid renderState.blending.functionSourceRgb.'); - } - if (!validateBlendFunction(this.blending.functionSourceAlpha)) { - throw new DeveloperError('Invalid renderState.blending.functionSourceAlpha.'); - } - if (!validateBlendFunction(this.blending.functionDestinationRgb)) { - throw new DeveloperError('Invalid renderState.blending.functionDestinationRgb.'); - } - if (!validateBlendFunction(this.blending.functionDestinationAlpha)) { - throw new DeveloperError('Invalid renderState.blending.functionDestinationAlpha.'); - } - if (!validateStencilFunction(this.stencilTest.frontFunction)) { - throw new DeveloperError('Invalid renderState.stencilTest.frontFunction.'); - } - if (!validateStencilFunction(this.stencilTest.backFunction)) { - throw new DeveloperError('Invalid renderState.stencilTest.backFunction.'); - } - if (!validateStencilOperation(this.stencilTest.frontOperation.fail)) { - throw new DeveloperError('Invalid renderState.stencilTest.frontOperation.fail.'); - } - if (!validateStencilOperation(this.stencilTest.frontOperation.zFail)) { - throw new DeveloperError('Invalid renderState.stencilTest.frontOperation.zFail.'); - } - if (!validateStencilOperation(this.stencilTest.frontOperation.zPass)) { - throw new DeveloperError('Invalid renderState.stencilTest.frontOperation.zPass.'); - } - if (!validateStencilOperation(this.stencilTest.backOperation.fail)) { - throw new DeveloperError('Invalid renderState.stencilTest.backOperation.fail.'); - } - if (!validateStencilOperation(this.stencilTest.backOperation.zFail)) { - throw new DeveloperError('Invalid renderState.stencilTest.backOperation.zFail.'); - } - if (!validateStencilOperation(this.stencilTest.backOperation.zPass)) { - throw new DeveloperError('Invalid renderState.stencilTest.backOperation.zPass.'); - } + }, - if (defined(this.viewport)) { - if (this.viewport.width < 0) { - throw new DeveloperError('renderState.viewport.width must be greater than or equal to zero.'); - } - if (this.viewport.height < 0) { - throw new DeveloperError('renderState.viewport.height must be greater than or equal to zero.'); + /** + * The GLSL source code for the fragment shader. The full fragment shader + * source is built procedurally taking into account the {@link Appearance#material}. + * Use {@link Appearance#getFragmentShaderSource} to get the full source. + * + * @memberof Appearance.prototype + * + * @type {String} + * @readonly + */ + fragmentShaderSource : { + get : function() { + return this._fragmentShaderSource; } + }, - if (this.viewport.width > ContextLimits.maximumViewportWidth) { - throw new DeveloperError('renderState.viewport.width must be less than or equal to the maximum viewport width (' + ContextLimits.maximumViewportWidth.toString() + '). Check maximumViewportWidth.'); + /** + * The WebGL fixed-function state to use when rendering the geometry. + * + * @memberof Appearance.prototype + * + * @type {Object} + * @readonly + */ + renderState : { + get : function() { + return this._renderState; } - if (this.viewport.height > ContextLimits.maximumViewportHeight) { - throw new DeveloperError('renderState.viewport.height must be less than or equal to the maximum viewport height (' + ContextLimits.maximumViewportHeight.toString() + '). Check maximumViewportHeight.'); + }, + + /** + * When <code>true</code>, the geometry is expected to be closed. + * + * @memberof Appearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + closed : { + get : function() { + return this._closed; } } - - this.id = 0; - this._applyFunctions = []; - } - - var nextRenderStateId = 0; - var renderStateCache = {}; + }); /** - * Validates and then finds or creates an immutable render state, which defines the pipeline - * state for a {@link DrawCommand} or {@link ClearCommand}. All inputs states are optional. Omitted states - * use the defaults shown in the example below. - * - * @param {Object} [renderState] The states defining the render state as shown in the example below. - * - * @exception {RuntimeError} renderState.lineWidth is out of range. - * @exception {DeveloperError} Invalid renderState.frontFace. - * @exception {DeveloperError} Invalid renderState.cull.face. - * @exception {DeveloperError} scissorTest.rectangle.width and scissorTest.rectangle.height must be greater than or equal to zero. - * @exception {DeveloperError} renderState.depthRange.near can't be greater than renderState.depthRange.far. - * @exception {DeveloperError} renderState.depthRange.near must be greater than or equal to zero. - * @exception {DeveloperError} renderState.depthRange.far must be less than or equal to zero. - * @exception {DeveloperError} Invalid renderState.depthTest.func. - * @exception {DeveloperError} renderState.blending.color components must be greater than or equal to zero and less than or equal to one - * @exception {DeveloperError} Invalid renderState.blending.equationRgb. - * @exception {DeveloperError} Invalid renderState.blending.equationAlpha. - * @exception {DeveloperError} Invalid renderState.blending.functionSourceRgb. - * @exception {DeveloperError} Invalid renderState.blending.functionSourceAlpha. - * @exception {DeveloperError} Invalid renderState.blending.functionDestinationRgb. - * @exception {DeveloperError} Invalid renderState.blending.functionDestinationAlpha. - * @exception {DeveloperError} Invalid renderState.stencilTest.frontFunction. - * @exception {DeveloperError} Invalid renderState.stencilTest.backFunction. - * @exception {DeveloperError} Invalid renderState.stencilTest.frontOperation.fail. - * @exception {DeveloperError} Invalid renderState.stencilTest.frontOperation.zFail. - * @exception {DeveloperError} Invalid renderState.stencilTest.frontOperation.zPass. - * @exception {DeveloperError} Invalid renderState.stencilTest.backOperation.fail. - * @exception {DeveloperError} Invalid renderState.stencilTest.backOperation.zFail. - * @exception {DeveloperError} Invalid renderState.stencilTest.backOperation.zPass. - * @exception {DeveloperError} renderState.viewport.width must be greater than or equal to zero. - * @exception {DeveloperError} renderState.viewport.width must be less than or equal to the maximum viewport width. - * @exception {DeveloperError} renderState.viewport.height must be greater than or equal to zero. - * @exception {DeveloperError} renderState.viewport.height must be less than or equal to the maximum viewport height. - * - * - * @example - * var defaults = { - * frontFace : WindingOrder.COUNTER_CLOCKWISE, - * cull : { - * enabled : false, - * face : CullFace.BACK - * }, - * lineWidth : 1, - * polygonOffset : { - * enabled : false, - * factor : 0, - * units : 0 - * }, - * scissorTest : { - * enabled : false, - * rectangle : { - * x : 0, - * y : 0, - * width : 0, - * height : 0 - * } - * }, - * depthRange : { - * near : 0, - * far : 1 - * }, - * depthTest : { - * enabled : false, - * func : DepthFunction.LESS - * }, - * colorMask : { - * red : true, - * green : true, - * blue : true, - * alpha : true - * }, - * depthMask : true, - * stencilMask : ~0, - * blending : { - * enabled : false, - * color : { - * red : 0.0, - * green : 0.0, - * blue : 0.0, - * alpha : 0.0 - * }, - * equationRgb : BlendEquation.ADD, - * equationAlpha : BlendEquation.ADD, - * functionSourceRgb : BlendFunction.ONE, - * functionSourceAlpha : BlendFunction.ONE, - * functionDestinationRgb : BlendFunction.ZERO, - * functionDestinationAlpha : BlendFunction.ZERO - * }, - * stencilTest : { - * enabled : false, - * frontFunction : StencilFunction.ALWAYS, - * backFunction : StencilFunction.ALWAYS, - * reference : 0, - * mask : ~0, - * frontOperation : { - * fail : StencilOperation.KEEP, - * zFail : StencilOperation.KEEP, - * zPass : StencilOperation.KEEP - * }, - * backOperation : { - * fail : StencilOperation.KEEP, - * zFail : StencilOperation.KEEP, - * zPass : StencilOperation.KEEP - * } - * }, - * sampleCoverage : { - * enabled : false, - * value : 1.0, - * invert : false - * } - * }; - * - * var rs = RenderState.fromCache(defaults); - * - * @see DrawCommand - * @see ClearCommand + * Procedurally creates the full GLSL fragment shader source for this appearance + * taking into account {@link Appearance#fragmentShaderSource} and {@link Appearance#material}. * - * @private + * @returns {String} The full GLSL fragment shader source. */ - RenderState.fromCache = function(renderState) { - var partialKey = JSON.stringify(renderState); - var cachedState = renderStateCache[partialKey]; - if (defined(cachedState)) { - ++cachedState.referenceCount; - return cachedState.state; + Appearance.prototype.getFragmentShaderSource = function() { + var parts = []; + if (this.flat) { + parts.push('#define FLAT'); } - - // Cache miss. Fully define render state and try again. - var states = new RenderState(renderState); - var fullKey = JSON.stringify(states); - cachedState = renderStateCache[fullKey]; - if (!defined(cachedState)) { - states.id = nextRenderStateId++; - states = freezeRenderState(states); - cachedState = { - referenceCount : 0, - state : states - }; - - // Cache full render state. Multiple partially defined render states may map to this. - renderStateCache[fullKey] = cachedState; + if (this.faceForward) { + parts.push('#define FACE_FORWARD'); } + if (defined(this.material)) { + parts.push(this.material.shaderSource); + } + parts.push(this.fragmentShaderSource); - ++cachedState.referenceCount; - - // Cache partial render state so we can skip validation on a cache hit for a partially defined render state - renderStateCache[partialKey] = { - referenceCount : 1, - state : cachedState.state - }; - - return cachedState.state; + return parts.join('\n'); }; /** - * @private + * Determines if the geometry is translucent based on {@link Appearance#translucent} and {@link Material#isTranslucent}. + * + * @returns {Boolean} <code>true</code> if the appearance is translucent. */ - RenderState.removeFromCache = function(renderState) { - var states = new RenderState(renderState); - var fullKey = JSON.stringify(states); - var fullCachedState = renderStateCache[fullKey]; - - // decrement partial key reference count - var partialKey = JSON.stringify(renderState); - var cachedState = renderStateCache[partialKey]; - if (defined(cachedState)) { - --cachedState.referenceCount; - - if (cachedState.referenceCount === 0) { - // remove partial key - delete renderStateCache[partialKey]; - - // decrement full key reference count - if (defined(fullCachedState)) { - --fullCachedState.referenceCount; - } - } - } - - // remove full key if reference count is zero - if (defined(fullCachedState) && (fullCachedState.referenceCount === 0)) { - delete renderStateCache[fullKey]; - } + Appearance.prototype.isTranslucent = function() { + return (defined(this.material) && this.material.isTranslucent()) || (!defined(this.material) && this.translucent); }; /** - * This function is for testing purposes only. - * @private + * Creates a render state. This is not the final render state instance; instead, + * it can contain a subset of render state properties identical to the render state + * created in the context. + * + * @returns {Object} The render state. */ - RenderState.getCache = function() { - return renderStateCache; + Appearance.prototype.getRenderState = function() { + var translucent = this.isTranslucent(); + var rs = clone(this.renderState, false); + if (translucent) { + rs.depthMask = false; + rs.blending = BlendingState.ALPHA_BLEND; + } else { + rs.depthMask = true; + } + return rs; }; /** - * This function is for testing purposes only. * @private */ - RenderState.clearCache = function() { - renderStateCache = {}; - }; + Appearance.getDefaultRenderState = function(translucent, closed, existing) { + var rs = { + depthTest : { + enabled : true + } + }; - function enableOrDisable(gl, glEnum, enable) { - if (enable) { - gl.enable(glEnum); - } else { - gl.disable(glEnum); + if (translucent) { + rs.depthMask = false; + rs.blending = BlendingState.ALPHA_BLEND; } - } - - function applyFrontFace(gl, renderState) { - gl.frontFace(renderState.frontFace); - } - - function applyCull(gl, renderState) { - var cull = renderState.cull; - var enabled = cull.enabled; - enableOrDisable(gl, gl.CULL_FACE, enabled); + if (closed) { + rs.cull = { + enabled : true, + face : CullFace.BACK + }; + } - if (enabled) { - gl.cullFace(cull.face); + if (defined(existing)) { + rs = combine(existing, rs, true); } - } - function applyLineWidth(gl, renderState) { - gl.lineWidth(renderState.lineWidth); - } + return rs; + }; - function applyPolygonOffset(gl, renderState) { - var polygonOffset = renderState.polygonOffset; - var enabled = polygonOffset.enabled; + return Appearance; +}); - enableOrDisable(gl, gl.POLYGON_OFFSET_FILL, enabled); +define('Renderer/ContextLimits',[ + '../Core/defineProperties' + ], function( + defineProperties) { + 'use strict'; - if (enabled) { - gl.polygonOffset(polygonOffset.factor, polygonOffset.units); - } - } + /** + * @private + */ + var ContextLimits = { + _maximumCombinedTextureImageUnits : 0, + _maximumCubeMapSize : 0, + _maximumFragmentUniformVectors : 0, + _maximumTextureImageUnits : 0, + _maximumRenderbufferSize : 0, + _maximumTextureSize : 0, + _maximumVaryingVectors : 0, + _maximumVertexAttributes : 0, + _maximumVertexTextureImageUnits : 0, + _maximumVertexUniformVectors : 0, + _minimumAliasedLineWidth : 0, + _maximumAliasedLineWidth : 0, + _minimumAliasedPointSize : 0, + _maximumAliasedPointSize : 0, + _maximumViewportWidth : 0, + _maximumViewportHeight : 0, + _maximumTextureFilterAnisotropy : 0, + _maximumDrawBuffers : 0, + _maximumColorAttachments : 0, + _highpFloatSupported: false, + _highpIntSupported: false + }; - function applyScissorTest(gl, renderState, passState) { - var scissorTest = renderState.scissorTest; - var enabled = (defined(passState.scissorTest)) ? passState.scissorTest.enabled : scissorTest.enabled; + defineProperties(ContextLimits, { - enableOrDisable(gl, gl.SCISSOR_TEST, enabled); + /** + * The maximum number of texture units that can be used from the vertex and fragment + * shader with this WebGL implementation. The minimum is eight. If both shaders access the + * same texture unit, this counts as two texture units. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_COMBINED_TEXTURE_IMAGE_UNITS</code>. + */ + maximumCombinedTextureImageUnits : { + get: function () { + return ContextLimits._maximumCombinedTextureImageUnits; + } + }, - if (enabled) { - var rectangle = (defined(passState.scissorTest)) ? passState.scissorTest.rectangle : scissorTest.rectangle; - gl.scissor(rectangle.x, rectangle.y, rectangle.width, rectangle.height); - } - } + /** + * The approximate maximum cube mape width and height supported by this WebGL implementation. + * The minimum is 16, but most desktop and laptop implementations will support much larger sizes like 8,192. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_CUBE_MAP_TEXTURE_SIZE</code>. + */ + maximumCubeMapSize : { + get: function () { + return ContextLimits._maximumCubeMapSize; + } + }, - function applyDepthRange(gl, renderState) { - var depthRange = renderState.depthRange; - gl.depthRange(depthRange.near, depthRange.far); - } + /** + * The maximum number of <code>vec4</code>, <code>ivec4</code>, and <code>bvec4</code> + * uniforms that can be used by a fragment shader with this WebGL implementation. The minimum is 16. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_FRAGMENT_UNIFORM_VECTORS</code>. + */ + maximumFragmentUniformVectors : { + get: function () { + return ContextLimits._maximumFragmentUniformVectors; + } + }, - function applyDepthTest(gl, renderState) { - var depthTest = renderState.depthTest; - var enabled = depthTest.enabled; + /** + * The maximum number of texture units that can be used from the fragment shader with this WebGL implementation. The minimum is eight. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_TEXTURE_IMAGE_UNITS</code>. + */ + maximumTextureImageUnits : { + get: function () { + return ContextLimits._maximumTextureImageUnits; + } + }, - enableOrDisable(gl, gl.DEPTH_TEST, enabled); + /** + * The maximum renderbuffer width and height supported by this WebGL implementation. + * The minimum is 16, but most desktop and laptop implementations will support much larger sizes like 8,192. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_RENDERBUFFER_SIZE</code>. + */ + maximumRenderbufferSize : { + get: function () { + return ContextLimits._maximumRenderbufferSize; + } + }, - if (enabled) { - gl.depthFunc(depthTest.func); - } - } + /** + * The approximate maximum texture width and height supported by this WebGL implementation. + * The minimum is 64, but most desktop and laptop implementations will support much larger sizes like 8,192. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_TEXTURE_SIZE</code>. + */ + maximumTextureSize : { + get: function () { + return ContextLimits._maximumTextureSize; + } + }, - function applyColorMask(gl, renderState) { - var colorMask = renderState.colorMask; - gl.colorMask(colorMask.red, colorMask.green, colorMask.blue, colorMask.alpha); - } + /** + * The maximum number of <code>vec4</code> varying variables supported by this WebGL implementation. + * The minimum is eight. Matrices and arrays count as multiple <code>vec4</code>s. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VARYING_VECTORS</code>. + */ + maximumVaryingVectors : { + get: function () { + return ContextLimits._maximumVaryingVectors; + } + }, - function applyDepthMask(gl, renderState) { - gl.depthMask(renderState.depthMask); - } + /** + * The maximum number of <code>vec4</code> vertex attributes supported by this WebGL implementation. The minimum is eight. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_ATTRIBS</code>. + */ + maximumVertexAttributes : { + get: function () { + return ContextLimits._maximumVertexAttributes; + } + }, - function applyStencilMask(gl, renderState) { - gl.stencilMask(renderState.stencilMask); - } + /** + * The maximum number of texture units that can be used from the vertex shader with this WebGL implementation. + * The minimum is zero, which means the GL does not support vertex texture fetch. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_TEXTURE_IMAGE_UNITS</code>. + */ + maximumVertexTextureImageUnits : { + get: function () { + return ContextLimits._maximumVertexTextureImageUnits; + } + }, - function applyBlendingColor(gl, color) { - gl.blendColor(color.red, color.green, color.blue, color.alpha); - } + /** + * The maximum number of <code>vec4</code>, <code>ivec4</code>, and <code>bvec4</code> + * uniforms that can be used by a vertex shader with this WebGL implementation. The minimum is 16. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_UNIFORM_VECTORS</code>. + */ + maximumVertexUniformVectors : { + get: function () { + return ContextLimits._maximumVertexUniformVectors; + } + }, - function applyBlending(gl, renderState, passState) { - var blending = renderState.blending; - var enabled = (defined(passState.blendingEnabled)) ? passState.blendingEnabled : blending.enabled; + /** + * The minimum aliased line width, in pixels, supported by this WebGL implementation. It will be at most one. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. + */ + minimumAliasedLineWidth : { + get: function () { + return ContextLimits._minimumAliasedLineWidth; + } + }, - enableOrDisable(gl, gl.BLEND, enabled); + /** + * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. + */ + maximumAliasedLineWidth : { + get: function () { + return ContextLimits._maximumAliasedLineWidth; + } + }, - if (enabled) { - applyBlendingColor(gl, blending.color); - gl.blendEquationSeparate(blending.equationRgb, blending.equationAlpha); - gl.blendFuncSeparate(blending.functionSourceRgb, blending.functionDestinationRgb, blending.functionSourceAlpha, blending.functionDestinationAlpha); - } - } + /** + * The minimum aliased point size, in pixels, supported by this WebGL implementation. It will be at most one. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_POINT_SIZE_RANGE</code>. + */ + minimumAliasedPointSize : { + get: function () { + return ContextLimits._minimumAliasedPointSize; + } + }, - function applyStencilTest(gl, renderState) { - var stencilTest = renderState.stencilTest; - var enabled = stencilTest.enabled; + /** + * The maximum aliased point size, in pixels, supported by this WebGL implementation. It will be at least one. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_POINT_SIZE_RANGE</code>. + */ + maximumAliasedPointSize : { + get: function () { + return ContextLimits._maximumAliasedPointSize; + } + }, - enableOrDisable(gl, gl.STENCIL_TEST, enabled); + /** + * The maximum supported width of the viewport. It will be at least as large as the visible width of the associated canvas. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VIEWPORT_DIMS</code>. + */ + maximumViewportWidth : { + get: function () { + return ContextLimits._maximumViewportWidth; + } + }, - if (enabled) { - var frontFunction = stencilTest.frontFunction; - var backFunction = stencilTest.backFunction; - var reference = stencilTest.reference; - var mask = stencilTest.mask; + /** + * The maximum supported height of the viewport. It will be at least as large as the visible height of the associated canvas. + * @memberof ContextLimits + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VIEWPORT_DIMS</code>. + */ + maximumViewportHeight : { + get: function () { + return ContextLimits._maximumViewportHeight; + } + }, - // Section 6.8 of the WebGL spec requires the reference and masks to be the same for - // front- and back-face tests. This call prevents invalid operation errors when calling - // stencilFuncSeparate on Firefox. Perhaps they should delay validation to avoid requiring this. - gl.stencilFunc(frontFunction, reference, mask); - gl.stencilFuncSeparate(gl.BACK, backFunction, reference, mask); - gl.stencilFuncSeparate(gl.FRONT, frontFunction, reference, mask); + /** + * The maximum degree of anisotropy for texture filtering + * @memberof ContextLimits + * @type {Number} + */ + maximumTextureFilterAnisotropy : { + get: function () { + return ContextLimits._maximumTextureFilterAnisotropy; + } + }, - var frontOperation = stencilTest.frontOperation; - var frontOperationFail = frontOperation.fail; - var frontOperationZFail = frontOperation.zFail; - var frontOperationZPass = frontOperation.zPass; + /** + * The maximum number of simultaneous outputs that may be written in a fragment shader. + * @memberof ContextLimits + * @type {Number} + */ + maximumDrawBuffers : { + get: function () { + return ContextLimits._maximumDrawBuffers; + } + }, - gl.stencilOpSeparate(gl.FRONT, frontOperationFail, frontOperationZFail, frontOperationZPass); + /** + * The maximum number of color attachments supported. + * @memberof ContextLimits + * @type {Number} + */ + maximumColorAttachments : { + get: function () { + return ContextLimits._maximumColorAttachments; + } + }, - var backOperation = stencilTest.backOperation; - var backOperationFail = backOperation.fail; - var backOperationZFail = backOperation.zFail; - var backOperationZPass = backOperation.zPass; + /** + * High precision float supported (<code>highp</code>) in fragment shaders. + * @memberof ContextLimits + * @type {Boolean} + */ + highpFloatSupported : { + get: function () { + return ContextLimits._highpFloatSupported; + } + }, - gl.stencilOpSeparate(gl.BACK, backOperationFail, backOperationZFail, backOperationZPass); + /** + * High precision int supported (<code>highp</code>) in fragment shaders. + * @memberof ContextLimits + * @type {Boolean} + */ + highpIntSupported : { + get: function () { + return ContextLimits._highpIntSupported; + } } - } - function applySampleCoverage(gl, renderState) { - var sampleCoverage = renderState.sampleCoverage; - var enabled = sampleCoverage.enabled; - - enableOrDisable(gl, gl.SAMPLE_COVERAGE, enabled); - - if (enabled) { - gl.sampleCoverage(sampleCoverage.value, sampleCoverage.invert); - } - } + }); - var scratchViewport = new BoundingRectangle(); + return ContextLimits; +}); - function applyViewport(gl, renderState, passState) { - var viewport = defaultValue(renderState.viewport, passState.viewport); - if (!defined(viewport)) { - viewport = scratchViewport; - viewport.width = passState.context.drawingBufferWidth; - viewport.height = passState.context.drawingBufferHeight; - } +define('Renderer/CubeMapFace',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/DeveloperError', + './PixelDatatype' + ], function( + Check, + defaultValue, + defineProperties, + DeveloperError, + PixelDatatype) { + 'use strict'; - passState.context.uniformState.viewport = viewport; - gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + /** + * @private + */ + function CubeMapFace(gl, texture, textureTarget, targetFace, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY) { + this._gl = gl; + this._texture = texture; + this._textureTarget = textureTarget; + this._targetFace = targetFace; + this._pixelFormat = pixelFormat; + this._pixelDatatype = pixelDatatype; + this._size = size; + this._preMultiplyAlpha = preMultiplyAlpha; + this._flipY = flipY; } - RenderState.apply = function(gl, renderState, passState) { - applyFrontFace(gl, renderState); - applyCull(gl, renderState); - applyLineWidth(gl, renderState); - applyPolygonOffset(gl, renderState); - applyDepthRange(gl, renderState); - applyDepthTest(gl, renderState); - applyColorMask(gl, renderState); - applyDepthMask(gl, renderState); - applyStencilMask(gl, renderState); - applyStencilTest(gl, renderState); - applySampleCoverage(gl, renderState); - applyScissorTest(gl, renderState, passState); - applyBlending(gl, renderState, passState); - applyViewport(gl, renderState, passState); - }; - - function createFuncs(previousState, nextState) { - var funcs = []; - - if (previousState.frontFace !== nextState.frontFace) { - funcs.push(applyFrontFace); + defineProperties(CubeMapFace.prototype, { + pixelFormat : { + get : function() { + return this._pixelFormat; + } + }, + pixelDatatype : { + get : function() { + return this._pixelDatatype; + } + }, + _target : { + get : function() { + return this._targetFace; + } } + }); - if ((previousState.cull.enabled !== nextState.cull.enabled) || (previousState.cull.face !== nextState.cull.face)) { - funcs.push(applyCull); - } + /** + * Copies texels from the source to the cubemap's face. + * + * @param {Object} source The source ImageData, HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, or an object with a width, height, and typed array as shown in the example. + * @param {Number} [xOffset=0] An offset in the x direction in the cubemap where copying begins. + * @param {Number} [yOffset=0] An offset in the y direction in the cubemap where copying begins. + * + * @exception {DeveloperError} xOffset must be greater than or equal to zero. + * @exception {DeveloperError} yOffset must be greater than or equal to zero. + * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. + * @exception {DeveloperError} yOffset + source.height must be less than or equal to height. + * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. + * + * @example + * // Create a cubemap with 1x1 faces, and make the +x face red. + * var cubeMap = new CubeMap({ + * context : context + * width : 1, + * height : 1 + * }); + * cubeMap.positiveX.copyFrom({ + * width : 1, + * height : 1, + * arrayBufferView : new Uint8Array([255, 0, 0, 255]) + * }); + */ + CubeMapFace.prototype.copyFrom = function(source, xOffset, yOffset) { + xOffset = defaultValue(xOffset, 0); + yOffset = defaultValue(yOffset, 0); - if (previousState.lineWidth !== nextState.lineWidth) { - funcs.push(applyLineWidth); + Check.defined('source', source); + Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); + Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); + if (xOffset + source.width > this._size) { + throw new DeveloperError('xOffset + source.width must be less than or equal to width.'); } - - if ((previousState.polygonOffset.enabled !== nextState.polygonOffset.enabled) || - (previousState.polygonOffset.factor !== nextState.polygonOffset.factor) || - (previousState.polygonOffset.units !== nextState.polygonOffset.units)) { - funcs.push(applyPolygonOffset); + if (yOffset + source.height > this._size) { + throw new DeveloperError('yOffset + source.height must be less than or equal to height.'); } + + var gl = this._gl; + var target = this._textureTarget; - if ((previousState.depthRange.near !== nextState.depthRange.near) || (previousState.depthRange.far !== nextState.depthRange.far)) { - funcs.push(applyDepthRange); - } + // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); - if ((previousState.depthTest.enabled !== nextState.depthTest.enabled) || (previousState.depthTest.func !== nextState.depthTest.func)) { - funcs.push(applyDepthTest); + if (source.arrayBufferView) { + gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); + } else { + gl.texSubImage2D(this._targetFace, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); } - if ((previousState.colorMask.red !== nextState.colorMask.red) || - (previousState.colorMask.green !== nextState.colorMask.green) || - (previousState.colorMask.blue !== nextState.colorMask.blue) || - (previousState.colorMask.alpha !== nextState.colorMask.alpha)) { - funcs.push(applyColorMask); - } - - if (previousState.depthMask !== nextState.depthMask) { - funcs.push(applyDepthMask); - } + gl.bindTexture(target, null); + }; - if (previousState.stencilMask !== nextState.stencilMask) { - funcs.push(applyStencilMask); - } + /** + * Copies texels from the framebuffer to the cubemap's face. + * + * @param {Number} [xOffset=0] An offset in the x direction in the cubemap where copying begins. + * @param {Number} [yOffset=0] An offset in the y direction in the cubemap where copying begins. + * @param {Number} [framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. + * @param {Number} [framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. + * @param {Number} [width=CubeMap's width] The width of the subimage to copy. + * @param {Number} [height=CubeMap's height] The height of the subimage to copy. + * + * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT. + * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. + * @exception {DeveloperError} xOffset must be greater than or equal to zero. + * @exception {DeveloperError} yOffset must be greater than or equal to zero. + * @exception {DeveloperError} framebufferXOffset must be greater than or equal to zero. + * @exception {DeveloperError} framebufferYOffset must be greater than or equal to zero. + * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. + * @exception {DeveloperError} yOffset + source.height must be less than or equal to height. + * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. + * + * @example + * // Copy the framebuffer contents to the +x cube map face. + * cubeMap.positiveX.copyFromFramebuffer(); + */ + CubeMapFace.prototype.copyFromFramebuffer = function(xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height) { + xOffset = defaultValue(xOffset, 0); + yOffset = defaultValue(yOffset, 0); + framebufferXOffset = defaultValue(framebufferXOffset, 0); + framebufferYOffset = defaultValue(framebufferYOffset, 0); + width = defaultValue(width, this._size); + height = defaultValue(height, this._size); - if ((previousState.stencilTest.enabled !== nextState.stencilTest.enabled) || - (previousState.stencilTest.frontFunction !== nextState.stencilTest.frontFunction) || - (previousState.stencilTest.backFunction !== nextState.stencilTest.backFunction) || - (previousState.stencilTest.reference !== nextState.stencilTest.reference) || - (previousState.stencilTest.mask !== nextState.stencilTest.mask) || - (previousState.stencilTest.frontOperation.fail !== nextState.stencilTest.frontOperation.fail) || - (previousState.stencilTest.frontOperation.zFail !== nextState.stencilTest.frontOperation.zFail) || - (previousState.stencilTest.backOperation.fail !== nextState.stencilTest.backOperation.fail) || - (previousState.stencilTest.backOperation.zFail !== nextState.stencilTest.backOperation.zFail) || - (previousState.stencilTest.backOperation.zPass !== nextState.stencilTest.backOperation.zPass)) { - funcs.push(applyStencilTest); + Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); + Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); + Check.typeOf.number.greaterThanOrEquals('framebufferXOffset', framebufferXOffset, 0); + Check.typeOf.number.greaterThanOrEquals('framebufferYOffset', framebufferYOffset, 0); + if (xOffset + width > this._size) { + throw new DeveloperError('xOffset + source.width must be less than or equal to width.'); } - - if ((previousState.sampleCoverage.enabled !== nextState.sampleCoverage.enabled) || - (previousState.sampleCoverage.value !== nextState.sampleCoverage.value) || - (previousState.sampleCoverage.invert !== nextState.sampleCoverage.invert)) { - funcs.push(applySampleCoverage); + if (yOffset + height > this._size) { + throw new DeveloperError('yOffset + source.height must be less than or equal to height.'); } - - return funcs; - } - - RenderState.partialApply = function(gl, previousRenderState, renderState, previousPassState, passState, clear) { - if (previousRenderState !== renderState) { - // When a new render state is applied, instead of making WebGL calls for all the states or first - // comparing the states one-by-one with the previous state (basically a linear search), we take - // advantage of RenderState's immutability, and store a dynamically populated sparse data structure - // containing functions that make the minimum number of WebGL calls when transitioning from one state - // to the other. In practice, this works well since state-to-state transitions generally only require a - // few WebGL calls, especially if commands are stored by state. - var funcs = renderState._applyFunctions[previousRenderState.id]; - if (!defined(funcs)) { - funcs = createFuncs(previousRenderState, renderState); - renderState._applyFunctions[previousRenderState.id] = funcs; - } - - var len = funcs.length; - for (var i = 0; i < len; ++i) { - funcs[i](gl, renderState); - } + if (this._pixelDatatype === PixelDatatype.FLOAT) { + throw new DeveloperError('Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT.'); } + + var gl = this._gl; + var target = this._textureTarget; - var previousScissorTest = (defined(previousPassState.scissorTest)) ? previousPassState.scissorTest : previousRenderState.scissorTest; - var scissorTest = (defined(passState.scissorTest)) ? passState.scissorTest : renderState.scissorTest; + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); + gl.copyTexSubImage2D(this._targetFace, 0, xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height); + gl.bindTexture(target, null); + }; - // Our scissor rectangle can get out of sync with the GL scissor rectangle on clears. - // Seems to be a problem only on ANGLE. See https://github.com/AnalyticalGraphicsInc/cesium/issues/2994 - if ((previousScissorTest !== scissorTest) || clear) { - applyScissorTest(gl, renderState, passState); - } + return CubeMapFace; +}); - var previousBlendingEnabled = (defined(previousPassState.blendingEnabled)) ? previousPassState.blendingEnabled : previousRenderState.blending.enabled; - var blendingEnabled = (defined(passState.blendingEnabled)) ? passState.blendingEnabled : renderState.blending.enabled; - if ((previousBlendingEnabled !== blendingEnabled) || - (blendingEnabled && (previousRenderState.blending !== renderState.blending))) { - applyBlending(gl, renderState, passState); - } +define('Renderer/MipmapHint',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; - if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { - applyViewport(gl, renderState, passState); - } - }; + /** + * @private + */ + var MipmapHint = { + DONT_CARE : WebGLConstants.DONT_CARE, + FASTEST : WebGLConstants.FASTEST, + NICEST : WebGLConstants.NICEST, - RenderState.getState = function(renderState) { - if (!defined(renderState)) { - throw new DeveloperError('renderState is required.'); + validate : function(mipmapHint) { + return ((mipmapHint === MipmapHint.DONT_CARE) || + (mipmapHint === MipmapHint.FASTEST) || + (mipmapHint === MipmapHint.NICEST)); } - - return { - frontFace : renderState.frontFace, - cull : { - enabled : renderState.cull.enabled, - face : renderState.cull.face - }, - lineWidth : renderState.lineWidth, - polygonOffset : { - enabled : renderState.polygonOffset.enabled, - factor : renderState.polygonOffset.factor, - units : renderState.polygonOffset.units - }, - scissorTest : { - enabled : renderState.scissorTest.enabled, - rectangle : BoundingRectangle.clone(renderState.scissorTest.rectangle) - }, - depthRange : { - near : renderState.depthRange.near, - far : renderState.depthRange.far - }, - depthTest : { - enabled : renderState.depthTest.enabled, - func : renderState.depthTest.func - }, - colorMask : { - red : renderState.colorMask.red, - green : renderState.colorMask.green, - blue : renderState.colorMask.blue, - alpha : renderState.colorMask.alpha - }, - depthMask : renderState.depthMask, - stencilMask : renderState.stencilMask, - blending : { - enabled : renderState.blending.enabled, - color : Color.clone(renderState.blending.color), - equationRgb : renderState.blending.equationRgb, - equationAlpha : renderState.blending.equationAlpha, - functionSourceRgb : renderState.blending.functionSourceRgb, - functionSourceAlpha : renderState.blending.functionSourceAlpha, - functionDestinationRgb : renderState.blending.functionDestinationRgb, - functionDestinationAlpha : renderState.blending.functionDestinationAlpha - }, - stencilTest : { - enabled : renderState.stencilTest.enabled, - frontFunction : renderState.stencilTest.frontFunction, - backFunction : renderState.stencilTest.backFunction, - reference : renderState.stencilTest.reference, - mask : renderState.stencilTest.mask, - frontOperation : { - fail : renderState.stencilTest.frontOperation.fail, - zFail : renderState.stencilTest.frontOperation.zFail, - zPass : renderState.stencilTest.frontOperation.zPass - }, - backOperation : { - fail : renderState.stencilTest.backOperation.fail, - zFail : renderState.stencilTest.backOperation.zFail, - zPass : renderState.stencilTest.backOperation.zPass - } - }, - sampleCoverage : { - enabled : renderState.sampleCoverage.enabled, - value : renderState.sampleCoverage.value, - invert : renderState.sampleCoverage.invert - }, - viewport : defined(renderState.viewport) ? BoundingRectangle.clone(renderState.viewport) : undefined - }; }; - return RenderState; + return freezeObject(MipmapHint); }); -define('Renderer/AutomaticUniforms',[ - '../Core/Cartesian3', - '../Core/Matrix4', +define('Renderer/TextureMagnificationFilter',[ + '../Core/freezeObject', '../Core/WebGLConstants' ], function( - Cartesian3, - Matrix4, + freezeObject, WebGLConstants) { 'use strict'; - /*global WebGLRenderingContext*/ - - var viewerPositionWCScratch = new Cartesian3(); - - function AutomaticUniform(options) { - this._size = options.size; - this._datatype = options.datatype; - this.getValue = options.getValue; - } - - // this check must use typeof, not defined, because defined doesn't work with undeclared variables. - if (typeof WebGLRenderingContext === 'undefined') { - return {}; - } - - var datatypeToGlsl = {}; - datatypeToGlsl[WebGLConstants.FLOAT] = 'float'; - datatypeToGlsl[WebGLConstants.FLOAT_VEC2] = 'vec2'; - datatypeToGlsl[WebGLConstants.FLOAT_VEC3] = 'vec3'; - datatypeToGlsl[WebGLConstants.FLOAT_VEC4] = 'vec4'; - datatypeToGlsl[WebGLConstants.INT] = 'int'; - datatypeToGlsl[WebGLConstants.INT_VEC2] = 'ivec2'; - datatypeToGlsl[WebGLConstants.INT_VEC3] = 'ivec3'; - datatypeToGlsl[WebGLConstants.INT_VEC4] = 'ivec4'; - datatypeToGlsl[WebGLConstants.BOOL] = 'bool'; - datatypeToGlsl[WebGLConstants.BOOL_VEC2] = 'bvec2'; - datatypeToGlsl[WebGLConstants.BOOL_VEC3] = 'bvec3'; - datatypeToGlsl[WebGLConstants.BOOL_VEC4] = 'bvec4'; - datatypeToGlsl[WebGLConstants.FLOAT_MAT2] = 'mat2'; - datatypeToGlsl[WebGLConstants.FLOAT_MAT3] = 'mat3'; - datatypeToGlsl[WebGLConstants.FLOAT_MAT4] = 'mat4'; - datatypeToGlsl[WebGLConstants.SAMPLER_2D] = 'sampler2D'; - datatypeToGlsl[WebGLConstants.SAMPLER_CUBE] = 'samplerCube'; - - AutomaticUniform.prototype.getDeclaration = function(name) { - var declaration = 'uniform ' + datatypeToGlsl[this._datatype] + ' ' + name; - - var size = this._size; - if (size === 1) { - declaration += ';'; - } else { - declaration += '[' + size.toString() + '];'; - } - - return declaration; - }; /** - * @private + * Enumerates all possible filters used when magnifying WebGL textures. + * + * @exports TextureMagnificationFilter + * + * @see TextureMinificationFilter */ - var AutomaticUniforms = { - /** - * An automatic GLSL uniform containing the viewport's <code>x</code>, <code>y</code>, <code>width</code>, - * and <code>height</code> properties in an <code>vec4</code>'s <code>x</code>, <code>y</code>, <code>z</code>, - * and <code>w</code> components, respectively. - * - * @alias czm_viewport - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec4 czm_viewport; - * - * // Scale the window coordinate components to [0, 1] by dividing - * // by the viewport's width and height. - * vec2 v = gl_FragCoord.xy / czm_viewport.zw; - * - * @see Context#getViewport - */ - czm_viewport : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC4, - getValue : function(uniformState) { - return uniformState.viewportCartesian4; - } - }), - + var TextureMagnificationFilter = { /** - * An automatic GLSL uniform representing a 4x4 orthographic projection matrix that - * transforms window coordinates to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * <br /><br /> - * This transform is useful when a vertex shader inputs or manipulates window coordinates - * as done by {@link BillboardCollection}. - * <br /><br /> - * Do not confuse {@link czm_viewportTransformation} with <code>czm_viewportOrthographic</code>. - * The former transforms from normalized device coordinates to window coordinates; the later transforms - * from window coordinates to clip coordinates, and is often used to assign to <code>gl_Position</code>. - * - * @alias czm_viewportOrthographic - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_viewportOrthographic; - * - * // Example - * gl_Position = czm_viewportOrthographic * vec4(windowPosition, 0.0, 1.0); + * Samples the texture by returning the closest pixel. * - * @see UniformState#viewportOrthographic - * @see czm_viewport - * @see czm_viewportTransformation - * @see BillboardCollection + * @type {Number} + * @constant */ - czm_viewportOrthographic : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.viewportOrthographic; - } - }), - + NEAREST : WebGLConstants.NEAREST, /** - * An automatic GLSL uniform representing a 4x4 transformation matrix that - * transforms normalized device coordinates to window coordinates. The context's - * full viewport is used, and the depth range is assumed to be <code>near = 0</code> - * and <code>far = 1</code>. - * <br /><br /> - * This transform is useful when there is a need to manipulate window coordinates - * in a vertex shader as done by {@link BillboardCollection}. In many cases, - * this matrix will not be used directly; instead, {@link czm_modelToWindowCoordinates} - * will be used to transform directly from model to window coordinates. - * <br /><br /> - * Do not confuse <code>czm_viewportTransformation</code> with {@link czm_viewportOrthographic}. - * The former transforms from normalized device coordinates to window coordinates; the later transforms - * from window coordinates to clip coordinates, and is often used to assign to <code>gl_Position</code>. - * - * @alias czm_viewportTransformation - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_viewportTransformation; - * - * // Use czm_viewportTransformation as part of the - * // transform from model to window coordinates. - * vec4 q = czm_modelViewProjection * positionMC; // model to clip coordinates - * q.xyz /= q.w; // clip to normalized device coordinates (ndc) - * q.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz; // ndc to window coordinates + * Samples the texture through bi-linear interpolation of the four nearest pixels. This produces smoother results than <code>NEAREST</code> filtering. * - * @see UniformState#viewportTransformation - * @see czm_viewport - * @see czm_viewportOrthographic - * @see czm_modelToWindowCoordinates - * @see BillboardCollection + * @type {Number} + * @constant */ - czm_viewportTransformation : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.viewportTransformation; - } - }), + LINEAR : WebGLConstants.LINEAR, /** - * An automatic GLSL uniform representing the depth after - * only the globe has been rendered and packed into an RGBA texture. + * Validates the given <code>textureMinificationFilter</code> with respect to the possible enum values. * * @private * - * @alias czm_globeDepthTexture - * @glslUniform - * - * @example - * // GLSL declaration - * uniform sampler2D czm_globeDepthTexture; - * - * // Get the depth at the current fragment - * vec2 coords = gl_FragCoord.xy / czm_viewport.zw; - * float depth = czm_unpackDepth(texture2D(czm_globeDepthTexture, coords)); + * @param textureMagnificationFilter + * @returns {Boolean} <code>true</code> if <code>textureMagnificationFilter</code> is valid. */ - czm_globeDepthTexture : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.SAMPLER_2D, - getValue : function(uniformState) { - return uniformState.globeDepthTexture; - } - }), + validate : function(textureMagnificationFilter) { + return ((textureMagnificationFilter === TextureMagnificationFilter.NEAREST) || + (textureMagnificationFilter === TextureMagnificationFilter.LINEAR)); + } + }; - /** - * An automatic GLSL uniform representing a 4x4 model transformation matrix that - * transforms model coordinates to world coordinates. - * - * @alias czm_model - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_model; - * - * // Example - * vec4 worldPosition = czm_model * modelPosition; - * - * @see UniformState#model - * @see czm_inverseModel - * @see czm_modelView - * @see czm_modelViewProjection - */ - czm_model : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.model; - } - }), + return freezeObject(TextureMagnificationFilter); +}); - /** - * An automatic GLSL uniform representing a 4x4 model transformation matrix that - * transforms world coordinates to model coordinates. - * - * @alias czm_inverseModel - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseModel; - * - * // Example - * vec4 modelPosition = czm_inverseModel * worldPosition; - * - * @see UniformState#inverseModel - * @see czm_model - * @see czm_inverseModelView - */ - czm_inverseModel : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseModel; - } - }), +define('Renderer/TextureMinificationFilter',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + /** + * Enumerates all possible filters used when minifying WebGL textures. + * + * @exports TextureMinificationFilter + * + * @see TextureMagnificationFilter + */ + var TextureMinificationFilter = { /** - * An automatic GLSL uniform representing a 4x4 view transformation matrix that - * transforms world coordinates to eye coordinates. - * - * @alias czm_view - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_view; - * - * // Example - * vec4 eyePosition = czm_view * worldPosition; + * Samples the texture by returning the closest pixel. * - * @see UniformState#view - * @see czm_viewRotation - * @see czm_modelView - * @see czm_viewProjection - * @see czm_modelViewProjection - * @see czm_inverseView + * @type {Number} + * @constant */ - czm_view : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.view; - } - }), - + NEAREST : WebGLConstants.NEAREST, /** - * An automatic GLSL uniform representing a 4x4 view transformation matrix that - * transforms 3D world coordinates to eye coordinates. In 3D mode, this is identical to - * {@link czm_view}, but in 2D and Columbus View it represents the view matrix - * as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * - * @alias czm_view3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_view3D; - * - * // Example - * vec4 eyePosition3D = czm_view3D * worldPosition3D; + * Samples the texture through bi-linear interpolation of the four nearest pixels. This produces smoother results than <code>NEAREST</code> filtering. * - * @see UniformState#view3D - * @see czm_view + * @type {Number} + * @constant */ - czm_view3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.view3D; - } - }), - + LINEAR : WebGLConstants.LINEAR, /** - * An automatic GLSL uniform representing a 3x3 view rotation matrix that - * transforms vectors in world coordinates to eye coordinates. - * - * @alias czm_viewRotation - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_viewRotation; - * - * // Example - * vec3 eyeVector = czm_viewRotation * worldVector; + * Selects the nearest mip level and applies nearest sampling within that level. + * <p> + * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. + * </p> * - * @see UniformState#viewRotation - * @see czm_view - * @see czm_inverseView - * @see czm_inverseViewRotation + * @type {Number} + * @constant */ - czm_viewRotation : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.viewRotation; - } - }), - + NEAREST_MIPMAP_NEAREST : WebGLConstants.NEAREST_MIPMAP_NEAREST, /** - * An automatic GLSL uniform representing a 3x3 view rotation matrix that - * transforms vectors in 3D world coordinates to eye coordinates. In 3D mode, this is identical to - * {@link czm_viewRotation}, but in 2D and Columbus View it represents the view matrix - * as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * - * @alias czm_viewRotation3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_viewRotation3D; - * - * // Example - * vec3 eyeVector = czm_viewRotation3D * worldVector; + * Selects the nearest mip level and applies linear sampling within that level. + * <p> + * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. + * </p> * - * @see UniformState#viewRotation3D - * @see czm_viewRotation + * @type {Number} + * @constant */ - czm_viewRotation3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.viewRotation3D; - } - }), - + LINEAR_MIPMAP_NEAREST : WebGLConstants.LINEAR_MIPMAP_NEAREST, /** - * An automatic GLSL uniform representing a 4x4 transformation matrix that - * transforms from eye coordinates to world coordinates. - * - * @alias czm_inverseView - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseView; - * - * // Example - * vec4 worldPosition = czm_inverseView * eyePosition; + * Read texture values with nearest sampling from two adjacent mip levels and linearly interpolate the results. + * <p> + * This option provides a good balance of visual quality and speed when sampling from a mipmapped texture. + * </p> + * <p> + * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. + * </p> * - * @see UniformState#inverseView - * @see czm_view - * @see czm_inverseNormal + * @type {Number} + * @constant */ - czm_inverseView : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseView; - } - }), - + NEAREST_MIPMAP_LINEAR : WebGLConstants.NEAREST_MIPMAP_LINEAR, /** - * An automatic GLSL uniform representing a 4x4 transformation matrix that - * transforms from 3D eye coordinates to world coordinates. In 3D mode, this is identical to - * {@link czm_inverseView}, but in 2D and Columbus View it represents the inverse view matrix - * as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * - * @alias czm_inverseView3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseView3D; - * - * // Example - * vec4 worldPosition = czm_inverseView3D * eyePosition; - * - * @see UniformState#inverseView3D - * @see czm_inverseView + * Read texture values with linear sampling from two adjacent mip levels and linearly interpolate the results. + * <p> + * This option provides a good balance of visual quality and speed when sampling from a mipmapped texture. + * </p> + * <p> + * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. + * </p> + * @type {Number} + * @constant */ - czm_inverseView3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseView3D; - } - }), + LINEAR_MIPMAP_LINEAR : WebGLConstants.LINEAR_MIPMAP_LINEAR, /** - * An automatic GLSL uniform representing a 3x3 rotation matrix that - * transforms vectors from eye coordinates to world coordinates. - * - * @alias czm_inverseViewRotation - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_inverseViewRotation; + * Validates the given <code>textureMinificationFilter</code> with respect to the possible enum values. * - * // Example - * vec4 worldVector = czm_inverseViewRotation * eyeVector; + * @private * - * @see UniformState#inverseView - * @see czm_view - * @see czm_viewRotation - * @see czm_inverseViewRotation + * @param textureMinificationFilter + * @returns {Boolean} <code>true</code> if <code>textureMinificationFilter</code> is valid. */ - czm_inverseViewRotation : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.inverseViewRotation; - } - }), + validate : function(textureMinificationFilter) { + return ((textureMinificationFilter === TextureMinificationFilter.NEAREST) || + (textureMinificationFilter === TextureMinificationFilter.LINEAR) || + (textureMinificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || + (textureMinificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || + (textureMinificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || + (textureMinificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR)); + } + }; - /** - * An automatic GLSL uniform representing a 3x3 rotation matrix that - * transforms vectors from 3D eye coordinates to world coordinates. In 3D mode, this is identical to - * {@link czm_inverseViewRotation}, but in 2D and Columbus View it represents the inverse view matrix - * as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * - * @alias czm_inverseViewRotation3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_inverseViewRotation3D; - * - * // Example - * vec4 worldVector = czm_inverseViewRotation3D * eyeVector; - * - * @see UniformState#inverseView3D - * @see czm_inverseViewRotation - */ - czm_inverseViewRotation3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.inverseViewRotation3D; - } - }), + return freezeObject(TextureMinificationFilter); +}); - /** - * An automatic GLSL uniform representing a 4x4 projection transformation matrix that - * transforms eye coordinates to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * - * @alias czm_projection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_projection; - * - * // Example - * gl_Position = czm_projection * eyePosition; - * - * @see UniformState#projection - * @see czm_viewProjection - * @see czm_modelViewProjection - * @see czm_infiniteProjection - */ - czm_projection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.projection; - } - }), +define('Renderer/TextureWrap',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; - /** - * An automatic GLSL uniform representing a 4x4 inverse projection transformation matrix that - * transforms from clip coordinates to eye coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * - * @alias czm_inverseProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseProjection; - * - * // Example - * vec4 eyePosition = czm_inverseProjection * clipPosition; - * - * @see UniformState#inverseProjection - * @see czm_projection - */ - czm_inverseProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseProjection; - } - }), + /** + * @private + */ + var TextureWrap = { + CLAMP_TO_EDGE : WebGLConstants.CLAMP_TO_EDGE, + REPEAT : WebGLConstants.REPEAT, + MIRRORED_REPEAT : WebGLConstants.MIRRORED_REPEAT, - /** - * An automatic GLSL uniform representing a 4x4 projection transformation matrix with the far plane at infinity, - * that transforms eye coordinates to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. An infinite far plane is used - * in algorithms like shadow volumes and GPU ray casting with proxy geometry to ensure that triangles - * are not clipped by the far plane. - * - * @alias czm_infiniteProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_infiniteProjection; - * - * // Example - * gl_Position = czm_infiniteProjection * eyePosition; - * - * @see UniformState#infiniteProjection - * @see czm_projection - * @see czm_modelViewInfiniteProjection - */ - czm_infiniteProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.infiniteProjection; - } - }), + validate : function(textureWrap) { + return ((textureWrap === TextureWrap.CLAMP_TO_EDGE) || + (textureWrap === TextureWrap.REPEAT) || + (textureWrap === TextureWrap.MIRRORED_REPEAT)); + } + }; - /** - * An automatic GLSL uniform representing a 4x4 model-view transformation matrix that - * transforms model coordinates to eye coordinates. - * <br /><br /> - * Positions should be transformed to eye coordinates using <code>czm_modelView</code> and - * normals should be transformed using {@link czm_normal}. - * - * @alias czm_modelView - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_modelView; - * - * // Example - * vec4 eyePosition = czm_modelView * modelPosition; - * - * // The above is equivalent to, but more efficient than: - * vec4 eyePosition = czm_view * czm_model * modelPosition; - * - * @see UniformState#modelView - * @see czm_model - * @see czm_view - * @see czm_modelViewProjection - * @see czm_normal - */ - czm_modelView : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.modelView; - } - }), + return freezeObject(TextureWrap); +}); - /** - * An automatic GLSL uniform representing a 4x4 model-view transformation matrix that - * transforms 3D model coordinates to eye coordinates. In 3D mode, this is identical to - * {@link czm_modelView}, but in 2D and Columbus View it represents the model-view matrix - * as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * <br /><br /> - * Positions should be transformed to eye coordinates using <code>czm_modelView3D</code> and - * normals should be transformed using {@link czm_normal3D}. - * - * @alias czm_modelView3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_modelView3D; - * - * // Example - * vec4 eyePosition = czm_modelView3D * modelPosition; - * - * // The above is equivalent to, but more efficient than: - * vec4 eyePosition = czm_view3D * czm_model * modelPosition; - * - * @see UniformState#modelView3D - * @see czm_modelView - */ - czm_modelView3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.modelView3D; - } - }), +define('Renderer/Sampler',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + './TextureMagnificationFilter', + './TextureMinificationFilter', + './TextureWrap' + ], function( + Check, + defaultValue, + defined, + defineProperties, + DeveloperError, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap) { + 'use strict'; - /** - * An automatic GLSL uniform representing a 4x4 model-view transformation matrix that - * transforms model coordinates, relative to the eye, to eye coordinates. This is used - * in conjunction with {@link czm_translateRelativeToEye}. - * - * @alias czm_modelViewRelativeToEye - * @glslUniform - * - * @example - * // GLSL declaration - * uniform mat4 czm_modelViewRelativeToEye; - * - * // Example - * attribute vec3 positionHigh; - * attribute vec3 positionLow; - * - * void main() - * { - * vec4 p = czm_translateRelativeToEye(positionHigh, positionLow); - * gl_Position = czm_projection * (czm_modelViewRelativeToEye * p); - * } - * - * @see czm_modelViewProjectionRelativeToEye - * @see czm_translateRelativeToEye - * @see EncodedCartesian3 - */ - czm_modelViewRelativeToEye : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.modelViewRelativeToEye; - } - }), + /** + * @private + */ + function Sampler(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * An automatic GLSL uniform representing a 4x4 transformation matrix that - * transforms from eye coordinates to model coordinates. - * - * @alias czm_inverseModelView - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseModelView; - * - * // Example - * vec4 modelPosition = czm_inverseModelView * eyePosition; - * - * @see UniformState#inverseModelView - * @see czm_modelView - */ - czm_inverseModelView : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseModelView; - } - }), + var wrapS = defaultValue(options.wrapS, TextureWrap.CLAMP_TO_EDGE); + var wrapT = defaultValue(options.wrapT, TextureWrap.CLAMP_TO_EDGE); + var minificationFilter = defaultValue(options.minificationFilter, TextureMinificationFilter.LINEAR); + var magnificationFilter = defaultValue(options.magnificationFilter, TextureMagnificationFilter.LINEAR); + var maximumAnisotropy = (defined(options.maximumAnisotropy)) ? options.maximumAnisotropy : 1.0; - /** - * An automatic GLSL uniform representing a 4x4 transformation matrix that - * transforms from eye coordinates to 3D model coordinates. In 3D mode, this is identical to - * {@link czm_inverseModelView}, but in 2D and Columbus View it represents the inverse model-view matrix - * as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * - * @alias czm_inverseModelView3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseModelView3D; - * - * // Example - * vec4 modelPosition = czm_inverseModelView3D * eyePosition; - * - * @see UniformState#inverseModelView - * @see czm_inverseModelView - * @see czm_modelView3D - */ - czm_inverseModelView3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseModelView3D; - } - }), + if (!TextureWrap.validate(wrapS)) { + throw new DeveloperError('Invalid sampler.wrapS.'); + } - /** - * An automatic GLSL uniform representing a 4x4 view-projection transformation matrix that - * transforms world coordinates to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * - * @alias czm_viewProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_viewProjection; - * - * // Example - * vec4 gl_Position = czm_viewProjection * czm_model * modelPosition; - * - * // The above is equivalent to, but more efficient than: - * gl_Position = czm_projection * czm_view * czm_model * modelPosition; - * - * @see UniformState#viewProjection - * @see czm_view - * @see czm_projection - * @see czm_modelViewProjection - * @see czm_inverseViewProjection - */ - czm_viewProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.viewProjection; - } - }), + if (!TextureWrap.validate(wrapT)) { + throw new DeveloperError('Invalid sampler.wrapT.'); + } - /** - * An automatic GLSL uniform representing a 4x4 view-projection transformation matrix that - * transforms clip coordinates to world coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * - * @alias czm_inverseViewProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseViewProjection; - * - * // Example - * vec4 worldPosition = czm_inverseViewProjection * clipPosition; - * - * @see UniformState#inverseViewProjection - * @see czm_viewProjection - */ - czm_inverseViewProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseViewProjection; - } - }), + if (!TextureMinificationFilter.validate(minificationFilter)) { + throw new DeveloperError('Invalid sampler.minificationFilter.'); + } - /** - * An automatic GLSL uniform representing a 4x4 model-view-projection transformation matrix that - * transforms model coordinates to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * - * @alias czm_modelViewProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_modelViewProjection; - * - * // Example - * vec4 gl_Position = czm_modelViewProjection * modelPosition; - * - * // The above is equivalent to, but more efficient than: - * gl_Position = czm_projection * czm_view * czm_model * modelPosition; - * - * @see UniformState#modelViewProjection - * @see czm_model - * @see czm_view - * @see czm_projection - * @see czm_modelView - * @see czm_viewProjection - * @see czm_modelViewInfiniteProjection - * @see czm_inverseModelViewProjection - */ - czm_modelViewProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.modelViewProjection; - } - }), + if (!TextureMagnificationFilter.validate(magnificationFilter)) { + throw new DeveloperError('Invalid sampler.magnificationFilter.'); + } - /** - * An automatic GLSL uniform representing a 4x4 inverse model-view-projection transformation matrix that - * transforms clip coordinates to model coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. - * - * @alias czm_inverseModelViewProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_inverseModelViewProjection; - * - * // Example - * vec4 modelPosition = czm_inverseModelViewProjection * clipPosition; - * - * @see UniformState#modelViewProjection - * @see czm_modelViewProjection - */ - czm_inverseModelViewProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.inverseModelViewProjection; - } - }), + Check.typeOf.number.greaterThanOrEquals('maximumAnisotropy', maximumAnisotropy, 1.0); + + this._wrapS = wrapS; + this._wrapT = wrapT; + this._minificationFilter = minificationFilter; + this._magnificationFilter = magnificationFilter; + this._maximumAnisotropy = maximumAnisotropy; + } - /** - * An automatic GLSL uniform representing a 4x4 model-view-projection transformation matrix that - * transforms model coordinates, relative to the eye, to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. This is used in - * conjunction with {@link czm_translateRelativeToEye}. - * - * @alias czm_modelViewProjectionRelativeToEye - * @glslUniform - * - * @example - * // GLSL declaration - * uniform mat4 czm_modelViewProjectionRelativeToEye; - * - * // Example - * attribute vec3 positionHigh; - * attribute vec3 positionLow; - * - * void main() - * { - * vec4 p = czm_translateRelativeToEye(positionHigh, positionLow); - * gl_Position = czm_modelViewProjectionRelativeToEye * p; - * } - * - * @see czm_modelViewRelativeToEye - * @see czm_translateRelativeToEye - * @see EncodedCartesian3 - */ - czm_modelViewProjectionRelativeToEye : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.modelViewProjectionRelativeToEye; + defineProperties(Sampler.prototype, { + wrapS : { + get : function() { + return this._wrapS; } - }), - - /** - * An automatic GLSL uniform representing a 4x4 model-view-projection transformation matrix that - * transforms model coordinates to clip coordinates. Clip coordinates is the - * coordinate system for a vertex shader's <code>gl_Position</code> output. The projection matrix places - * the far plane at infinity. This is useful in algorithms like shadow volumes and GPU ray casting with - * proxy geometry to ensure that triangles are not clipped by the far plane. - * - * @alias czm_modelViewInfiniteProjection - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat4 czm_modelViewInfiniteProjection; - * - * // Example - * vec4 gl_Position = czm_modelViewInfiniteProjection * modelPosition; - * - * // The above is equivalent to, but more efficient than: - * gl_Position = czm_infiniteProjection * czm_view * czm_model * modelPosition; - * - * @see UniformState#modelViewInfiniteProjection - * @see czm_model - * @see czm_view - * @see czm_infiniteProjection - * @see czm_modelViewProjection - */ - czm_modelViewInfiniteProjection : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT4, - getValue : function(uniformState) { - return uniformState.modelViewInfiniteProjection; + }, + wrapT : { + get : function() { + return this._wrapT; } - }), - - /** - * An automatic GLSL uniform representing a 3x3 normal transformation matrix that - * transforms normal vectors in model coordinates to eye coordinates. - * <br /><br /> - * Positions should be transformed to eye coordinates using {@link czm_modelView} and - * normals should be transformed using <code>czm_normal</code>. - * - * @alias czm_normal - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_normal; - * - * // Example - * vec3 eyeNormal = czm_normal * normal; - * - * @see UniformState#normal - * @see czm_inverseNormal - * @see czm_modelView - */ - czm_normal : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.normal; + }, + minificationFilter : { + get : function() { + return this._minificationFilter; } - }), - - /** - * An automatic GLSL uniform representing a 3x3 normal transformation matrix that - * transforms normal vectors in 3D model coordinates to eye coordinates. - * In 3D mode, this is identical to - * {@link czm_normal}, but in 2D and Columbus View it represents the normal transformation - * matrix as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * <br /><br /> - * Positions should be transformed to eye coordinates using {@link czm_modelView3D} and - * normals should be transformed using <code>czm_normal3D</code>. - * - * @alias czm_normal3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_normal3D; - * - * // Example - * vec3 eyeNormal = czm_normal3D * normal; - * - * @see UniformState#normal3D - * @see czm_normal - */ - czm_normal3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.normal3D; + }, + magnificationFilter : { + get : function() { + return this._magnificationFilter; } - }), - - /** - * An automatic GLSL uniform representing a 3x3 normal transformation matrix that - * transforms normal vectors in eye coordinates to model coordinates. This is - * the opposite of the transform provided by {@link czm_normal}. - * - * @alias czm_inverseNormal - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_inverseNormal; - * - * // Example - * vec3 normalMC = czm_inverseNormal * normalEC; - * - * @see UniformState#inverseNormal - * @see czm_normal - * @see czm_modelView - * @see czm_inverseView - */ - czm_inverseNormal : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.inverseNormal; + }, + maximumAnisotropy : { + get : function() { + return this._maximumAnisotropy; } - }), + } + }); - /** - * An automatic GLSL uniform representing a 3x3 normal transformation matrix that - * transforms normal vectors in eye coordinates to 3D model coordinates. This is - * the opposite of the transform provided by {@link czm_normal}. - * In 3D mode, this is identical to - * {@link czm_inverseNormal}, but in 2D and Columbus View it represents the inverse normal transformation - * matrix as if the camera were at an equivalent location in 3D mode. This is useful for lighting - * 2D and Columbus View in the same way that 3D is lit. - * - * @alias czm_inverseNormal3D - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_inverseNormal3D; - * - * // Example - * vec3 normalMC = czm_inverseNormal3D * normalEC; - * - * @see UniformState#inverseNormal3D - * @see czm_inverseNormal - */ - czm_inverseNormal3D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.inverseNormal3D; - } - }), + return Sampler; +}); - /** - * An automatic GLSL uniform containing height (<code>x</code>) and height squared (<code>y</code>) - * of the eye (camera) in the 2D scene in meters. - * - * @alias czm_eyeHeight2D - * @glslUniform - * - * @see UniformState#eyeHeight2D - */ - czm_eyeHeight2D : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC2, - getValue : function(uniformState) { - return uniformState.eyeHeight2D; - } - }), +define('Renderer/CubeMap',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Math', + '../Core/PixelFormat', + './ContextLimits', + './CubeMapFace', + './MipmapHint', + './PixelDatatype', + './Sampler', + './TextureMagnificationFilter', + './TextureMinificationFilter' + ], function( + Check, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + CesiumMath, + PixelFormat, + ContextLimits, + CubeMapFace, + MipmapHint, + PixelDatatype, + Sampler, + TextureMagnificationFilter, + TextureMinificationFilter) { + 'use strict'; - /** - * An automatic GLSL uniform containing the near distance (<code>x</code>) and the far distance (<code>y</code>) - * of the frustum defined by the camera. This is the largest possible frustum, not an individual - * frustum used for multi-frustum rendering. - * - * @alias czm_entireFrustum - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec2 czm_entireFrustum; - * - * // Example - * float frustumLength = czm_entireFrustum.y - czm_entireFrustum.x; - * - * @see UniformState#entireFrustum - * @see czm_currentFrustum - */ - czm_entireFrustum : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC2, - getValue : function(uniformState) { - return uniformState.entireFrustum; - } - }), + function CubeMap(options) { - /** - * An automatic GLSL uniform containing the near distance (<code>x</code>) and the far distance (<code>y</code>) - * of the frustum defined by the camera. This is the individual - * frustum used for multi-frustum rendering. - * - * @alias czm_currentFrustum - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec2 czm_currentFrustum; - * - * // Example - * float frustumLength = czm_currentFrustum.y - czm_currentFrustum.x; - * - * @see UniformState#currentFrustum - * @see czm_entireFrustum - */ - czm_currentFrustum : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC2, - getValue : function(uniformState) { - return uniformState.currentFrustum; - } - }), + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The distances to the frustum planes. The top, bottom, left and right distances are - * the x, y, z, and w components, respectively. - * - * @alias czm_frustumPlanes - * @glslUniform - */ - czm_frustumPlanes : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC4, - getValue : function(uniformState) { - return uniformState.frustumPlanes; - } - }), + Check.defined('options.context', options.context); + + var context = options.context; + var source = options.source; + var width; + var height; - /** - * An automatic GLSL uniform representing the sun position in world coordinates. - * - * @alias czm_sunPositionWC - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_sunPositionWC; - * - * @see UniformState#sunPositionWC - * @see czm_sunPositionColumbusView - * @see czm_sunDirectionWC - */ - czm_sunPositionWC : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.sunPositionWC; - } - }), + if (defined(source)) { + var faces = [source.positiveX, source.negativeX, source.positiveY, source.negativeY, source.positiveZ, source.negativeZ]; - /** - * An automatic GLSL uniform representing the sun position in Columbus view world coordinates. - * - * @alias czm_sunPositionColumbusView - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_sunPositionColumbusView; - * - * @see UniformState#sunPositionColumbusView - * @see czm_sunPositionWC - */ - czm_sunPositionColumbusView : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.sunPositionColumbusView; + if (!faces[0] || !faces[1] || !faces[2] || !faces[3] || !faces[4] || !faces[5]) { + throw new DeveloperError('options.source requires positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ faces.'); } - }), + + width = faces[0].width; + height = faces[0].height; - /** - * An automatic GLSL uniform representing the normalized direction to the sun in eye coordinates. - * This is commonly used for directional lighting computations. - * - * @alias czm_sunDirectionEC - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_sunDirectionEC; - * - * // Example - * float diffuse = max(dot(czm_sunDirectionEC, normalEC), 0.0); - * - * @see UniformState#sunDirectionEC - * @see czm_moonDirectionEC - * @see czm_sunDirectionWC - */ - czm_sunDirectionEC : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.sunDirectionEC; + for ( var i = 1; i < 6; ++i) { + if ((Number(faces[i].width) !== width) || (Number(faces[i].height) !== height)) { + throw new DeveloperError('Each face in options.source must have the same width and height.'); + } } - }), + } else { + width = options.width; + height = options.height; + } - /** - * An automatic GLSL uniform representing the normalized direction to the sun in world coordinates. - * This is commonly used for directional lighting computations. - * - * @alias czm_sunDirectionWC - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_sunDirectionWC; - * - * @see UniformState#sunDirectionWC - * @see czm_sunPositionWC - * @see czm_sunDirectionEC - */ - czm_sunDirectionWC : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.sunDirectionWC; - } - }), + var size = width; + var pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGBA); + var pixelDatatype = defaultValue(options.pixelDatatype, PixelDatatype.UNSIGNED_BYTE); - /** - * An automatic GLSL uniform representing the normalized direction to the moon in eye coordinates. - * This is commonly used for directional lighting computations. - * - * @alias czm_moonDirectionEC - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_moonDirectionEC; - * - * // Example - * float diffuse = max(dot(czm_moonDirectionEC, normalEC), 0.0); - * - * @see UniformState#moonDirectionEC - * @see czm_sunDirectionEC - */ - czm_moonDirectionEC : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.moonDirectionEC; - } - }), + if (!defined(width) || !defined(height)) { + throw new DeveloperError('options requires a source field to create an initialized cube map or width and height fields to create a blank cube map.'); + } - /** - * An automatic GLSL uniform representing the high bits of the camera position in model - * coordinates. This is used for GPU RTE to eliminate jittering artifacts when rendering - * as described in {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. - * - * @alias czm_encodedCameraPositionMCHigh - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_encodedCameraPositionMCHigh; - * - * @see czm_encodedCameraPositionMCLow - * @see czm_modelViewRelativeToEye - * @see czm_modelViewProjectionRelativeToEye - */ - czm_encodedCameraPositionMCHigh : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.encodedCameraPositionMCHigh; - } - }), + if (width !== height) { + throw new DeveloperError('Width must equal height.'); + } - /** - * An automatic GLSL uniform representing the low bits of the camera position in model - * coordinates. This is used for GPU RTE to eliminate jittering artifacts when rendering - * as described in {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. - * - * @alias czm_encodedCameraPositionMCLow - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform vec3 czm_encodedCameraPositionMCLow; - * - * @see czm_encodedCameraPositionMCHigh - * @see czm_modelViewRelativeToEye - * @see czm_modelViewProjectionRelativeToEye - */ - czm_encodedCameraPositionMCLow : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return uniformState.encodedCameraPositionMCLow; - } - }), + if (size <= 0) { + throw new DeveloperError('Width and height must be greater than zero.'); + } - /** - * An automatic GLSL uniform representing the position of the viewer (camera) in world coordinates. - * - * @alias czm_viewerPositionWC - * @glslUniform - * - * @example - * // GLSL declaration - * uniform vec3 czm_viewerPositionWC; - */ - czm_viewerPositionWC : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC3, - getValue : function(uniformState) { - return Matrix4.getTranslation(uniformState.inverseView, viewerPositionWCScratch); - } - }), + if (size > ContextLimits.maximumCubeMapSize) { + throw new DeveloperError('Width and height must be less than or equal to the maximum cube map size (' + ContextLimits.maximumCubeMapSize + '). Check maximumCubeMapSize.'); + } - /** - * An automatic GLSL uniform representing the frame number. This uniform is automatically incremented - * every frame. - * - * @alias czm_frameNumber - * @glslUniform - * - * @example - * // GLSL declaration - * uniform float czm_frameNumber; - */ - czm_frameNumber : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.frameState.frameNumber; - } - }), + if (!PixelFormat.validate(pixelFormat)) { + throw new DeveloperError('Invalid options.pixelFormat.'); + } - /** - * An automatic GLSL uniform representing the current morph transition time between - * 2D/Columbus View and 3D, with 0.0 being 2D or Columbus View and 1.0 being 3D. - * - * @alias czm_morphTime - * @glslUniform - * - * @example - * // GLSL declaration - * uniform float czm_morphTime; - * - * // Example - * vec4 p = czm_columbusViewMorph(position2D, position3D, czm_morphTime); - */ - czm_morphTime : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.frameState.morphTime; - } - }), + if (PixelFormat.isDepthFormat(pixelFormat)) { + throw new DeveloperError('options.pixelFormat cannot be DEPTH_COMPONENT or DEPTH_STENCIL.'); + } - /** - * An automatic GLSL uniform representing the current {@link SceneMode}, expressed - * as a float. - * - * @alias czm_sceneMode - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform float czm_sceneMode; - * - * // Example - * if (czm_sceneMode == czm_sceneMode2D) - * { - * eyeHeightSq = czm_eyeHeight2D.y; - * } - * - * @see czm_sceneMode2D - * @see czm_sceneModeColumbusView - * @see czm_sceneMode3D - * @see czm_sceneModeMorphing - */ - czm_sceneMode : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.frameState.mode; - } - }), + if (!PixelDatatype.validate(pixelDatatype)) { + throw new DeveloperError('Invalid options.pixelDatatype.'); + } - /** - * An automatic GLSL uniform representing the current rendering pass. - * - * @alias czm_pass - * @glslUniform - * - * @example - * // GLSL declaration - * uniform float czm_pass; - * - * // Example - * if ((czm_pass == czm_passTranslucent) && isOpaque()) - * { - * gl_Position *= 0.0; // Cull opaque geometry in the translucent pass - * } - */ - czm_pass : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.pass; - } - }), + if ((pixelDatatype === PixelDatatype.FLOAT) && !context.floatingPointTexture) { + throw new DeveloperError('When options.pixelDatatype is FLOAT, this WebGL implementation must support the OES_texture_float extension.'); + } + + var sizeInBytes = PixelFormat.textureSizeInBytes(pixelFormat, pixelDatatype, size, size) * 6; - /** - * An automatic GLSL uniform representing the current scene background color. - * - * @alias czm_backgroundColor - * @glslUniform - * - * @example - * // GLSL declaration - * uniform vec4 czm_backgroundColor; - * - * // Example: If the given color's RGB matches the background color, invert it. - * vec4 adjustColorForContrast(vec4 color) - * { - * if (czm_backgroundColor.rgb == color.rgb) - * { - * color.rgb = vec3(1.0) - color.rgb; - * } - * - * return color; - * } - */ - czm_backgroundColor : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC4, - getValue : function(uniformState) { - return uniformState.backgroundColor; - } - }), + // Use premultiplied alpha for opaque textures should perform better on Chrome: + // http://media.tojicode.com/webglCamp4/#20 + var preMultiplyAlpha = options.preMultiplyAlpha || ((pixelFormat === PixelFormat.RGB) || (pixelFormat === PixelFormat.LUMINANCE)); + var flipY = defaultValue(options.flipY, true); - /** - * An automatic GLSL uniform containing the BRDF look up texture used for image-based lighting computations. - * - * @alias czm_brdfLut - * @glslUniform - * - * @example - * // GLSL declaration - * uniform sampler2D czm_brdfLut; - * - * // Example: For a given roughness and NdotV value, find the material's BRDF information in the red and green channels - * float roughness = 0.5; - * float NdotV = dot(normal, view); - * vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg; - */ - czm_brdfLut : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.SAMPLER_2D, - getValue : function(uniformState) { - return uniformState.brdfLut; - } - }), + var gl = context._gl; + var textureTarget = gl.TEXTURE_CUBE_MAP; + var texture = gl.createTexture(); - /** - * An automatic GLSL uniform containing the environment map used within the scene. - * - * @alias czm_environmentMap - * @glslUniform - * - * @example - * // GLSL declaration - * uniform samplerCube czm_environmentMap; - * - * // Example: Create a perfect reflection of the environment map on a model - * float reflected = reflect(view, normal); - * vec4 reflectedColor = textureCube(czm_environmentMap, reflected); - */ - czm_environmentMap : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.SAMPLER_CUBE, - getValue : function(uniformState) { - return uniformState.environmentMap; - } - }), + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(textureTarget, texture); - /** - * An automatic GLSL uniform representing a 3x3 rotation matrix that transforms - * from True Equator Mean Equinox (TEME) axes to the pseudo-fixed axes at the current scene time. - * - * @alias czm_temeToPseudoFixed - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform mat3 czm_temeToPseudoFixed; - * - * // Example - * vec3 pseudoFixed = czm_temeToPseudoFixed * teme; - * - * @see UniformState#temeToPseudoFixedMatrix - * @see Transforms.computeTemeToPseudoFixedMatrix - */ - czm_temeToPseudoFixed : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_MAT3, - getValue : function(uniformState) { - return uniformState.temeToPseudoFixedMatrix; + function createFace(target, sourceFace) { + if (sourceFace.arrayBufferView) { + gl.texImage2D(target, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, sourceFace.arrayBufferView); + } else { + gl.texImage2D(target, 0, pixelFormat, pixelFormat, pixelDatatype, sourceFace); } - }), + } - /** - * An automatic GLSL uniform representing the ratio of canvas coordinate space to canvas pixel space. - * - * @alias czm_resolutionScale - * @glslUniform - * - * @example - * uniform float czm_resolutionScale; - */ - czm_resolutionScale : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.resolutionScale; - } - }), + if (defined(source)) { + // TODO: _gl.pixelStorei(_gl._UNPACK_ALIGNMENT, 4); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - /** - * An automatic GLSL uniform scalar used to mix a color with the fog color based on the distance to the camera. - * - * @alias czm_fogDensity - * @glslUniform - * - * @see czm_fog - */ - czm_fogDensity : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.fogDensity; - } - }), + createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_X, source.positiveX); + createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, source.negativeX); + createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, source.positiveY); + createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, source.negativeY); + createFace(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, source.positiveZ); + createFace(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, source.negativeZ); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, pixelFormat, size, size, 0, pixelFormat, pixelDatatype, null); + } + gl.bindTexture(textureTarget, null); - /** - * An automatic GLSL uniform representing the splitter position to use when rendering imagery layers with a splitter. - * This will be in pixel coordinates relative to the canvas. - * - * @alias czm_imagerySplitPosition - * @glslUniform - * - * - * @example - * // GLSL declaration - * uniform float czm_imagerySplitPosition; - */ - czm_imagerySplitPosition : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.imagerySplitPosition; - } - }), + this._gl = gl; + this._textureFilterAnisotropic = context._textureFilterAnisotropic; + this._textureTarget = textureTarget; + this._texture = texture; + this._pixelFormat = pixelFormat; + this._pixelDatatype = pixelDatatype; + this._size = size; + this._hasMipmap = false; + this._sizeInBytes = sizeInBytes; + this._preMultiplyAlpha = preMultiplyAlpha; + this._flipY = flipY; + this._sampler = undefined; - /** - * An automatic GLSL uniform scalar representing the geometric tolerance per meter - * - * @alias czm_geometricToleranceOverMeter - * @glslUniform - */ - czm_geometricToleranceOverMeter : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.geometricToleranceOverMeter; - } - }), + this._positiveX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + this._negativeX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + this._positiveY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + this._negativeY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + this._positiveZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); + this._negativeZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY); - /** - * An automatic GLSL uniform representing the distance from the camera at which to disable the depth test of billboards, labels and points - * to, for example, prevent clipping against terrain. When set to zero, the depth test should always be applied. When less than zero, - * the depth test should never be applied. - * - * @alias czm_minimumDisableDepthTestDistance - * @glslUniform - */ - czm_minimumDisableDepthTestDistance : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT, - getValue : function(uniformState) { - return uniformState.minimumDisableDepthTestDistance; - } - }), + this.sampler = defined(options.sampler) ? options.sampler : new Sampler(); + } - /** - * An automatic GLSL uniform that will be the highlight color of unclassified 3D Tiles. - * - * @alias czm_invertClassificationColor - * @glslUniform - */ - czm_invertClassificationColor : new AutomaticUniform({ - size : 1, - datatype : WebGLConstants.FLOAT_VEC4, - getValue : function(uniformState) { - return uniformState.invertClassificationColor; + defineProperties(CubeMap.prototype, { + positiveX : { + get : function() { + return this._positiveX; } - }) - }; - - return AutomaticUniforms; -}); - -define('Renderer/createUniform',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Color', - '../Core/defined', - '../Core/DeveloperError', - '../Core/Matrix2', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/RuntimeError' - ], function( - Cartesian2, - Cartesian3, - Cartesian4, - Color, - defined, - DeveloperError, - Matrix2, - Matrix3, - Matrix4, - RuntimeError) { - 'use strict'; - - /** - * @private - */ - function createUniform(gl, activeUniform, uniformName, location) { - switch (activeUniform.type) { - case gl.FLOAT: - return new UniformFloat(gl, activeUniform, uniformName, location); - case gl.FLOAT_VEC2: - return new UniformFloatVec2(gl, activeUniform, uniformName, location); - case gl.FLOAT_VEC3: - return new UniformFloatVec3(gl, activeUniform, uniformName, location); - case gl.FLOAT_VEC4: - return new UniformFloatVec4(gl, activeUniform, uniformName, location); - case gl.SAMPLER_2D: - case gl.SAMPLER_CUBE: - return new UniformSampler(gl, activeUniform, uniformName, location); - case gl.INT: - case gl.BOOL: - return new UniformInt(gl, activeUniform, uniformName, location); - case gl.INT_VEC2: - case gl.BOOL_VEC2: - return new UniformIntVec2(gl, activeUniform, uniformName, location); - case gl.INT_VEC3: - case gl.BOOL_VEC3: - return new UniformIntVec3(gl, activeUniform, uniformName, location); - case gl.INT_VEC4: - case gl.BOOL_VEC4: - return new UniformIntVec4(gl, activeUniform, uniformName, location); - case gl.FLOAT_MAT2: - return new UniformMat2(gl, activeUniform, uniformName, location); - case gl.FLOAT_MAT3: - return new UniformMat3(gl, activeUniform, uniformName, location); - case gl.FLOAT_MAT4: - return new UniformMat4(gl, activeUniform, uniformName, location); - default: - throw new RuntimeError('Unrecognized uniform type: ' + activeUniform.type + ' for uniform "' + uniformName + '".'); - } - } - - function UniformFloat(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = 0.0; - - this._gl = gl; - this._location = location; - } - - UniformFloat.prototype.set = function() { - if (this.value !== this._value) { - this._value = this.value; - this._gl.uniform1f(this._location, this.value); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformFloatVec2(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = new Cartesian2(); - - this._gl = gl; - this._location = location; - } - - UniformFloatVec2.prototype.set = function() { - var v = this.value; - if (!Cartesian2.equals(v, this._value)) { - Cartesian2.clone(v, this._value); - this._gl.uniform2f(this._location, v.x, v.y); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformFloatVec3(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = undefined; - - this._gl = gl; - this._location = location; - } - - UniformFloatVec3.prototype.set = function() { - var v = this.value; - - if (defined(v.red)) { - if (!Color.equals(v, this._value)) { - this._value = Color.clone(v, this._value); - this._gl.uniform3f(this._location, v.red, v.green, v.blue); + }, + negativeX : { + get : function() { + return this._negativeX; } - } else if (defined(v.x)) { - if (!Cartesian3.equals(v, this._value)) { - this._value = Cartesian3.clone(v, this._value); - this._gl.uniform3f(this._location, v.x, v.y, v.z); + }, + positiveY : { + get : function() { + return this._positiveY; } - } else { - throw new DeveloperError('Invalid vec3 value for uniform "' + this._activethis.name + '".'); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformFloatVec4(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = undefined; - - this._gl = gl; - this._location = location; - } - - UniformFloatVec4.prototype.set = function() { - var v = this.value; - - if (defined(v.red)) { - if (!Color.equals(v, this._value)) { - this._value = Color.clone(v, this._value); - this._gl.uniform4f(this._location, v.red, v.green, v.blue, v.alpha); + }, + negativeY : { + get : function() { + return this._negativeY; } - } else if (defined(v.x)) { - if (!Cartesian4.equals(v, this._value)) { - this._value = Cartesian4.clone(v, this._value); - this._gl.uniform4f(this._location, v.x, v.y, v.z, v.w); + }, + positiveZ : { + get : function() { + return this._positiveZ; } - } else { - throw new DeveloperError('Invalid vec4 value for uniform "' + this._activethis.name + '".'); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformSampler(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - - this._gl = gl; - this._location = location; - - this.textureUnitIndex = undefined; - } - - UniformSampler.prototype.set = function() { - var gl = this._gl; - gl.activeTexture(gl.TEXTURE0 + this.textureUnitIndex); - - var v = this.value; - gl.bindTexture(v._target, v._texture); - }; - - UniformSampler.prototype._setSampler = function(textureUnitIndex) { - this.textureUnitIndex = textureUnitIndex; - this._gl.uniform1i(this._location, textureUnitIndex); - return textureUnitIndex + 1; - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformInt(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = 0.0; - - this._gl = gl; - this._location = location; - } + }, + negativeZ : { + get : function() { + return this._negativeZ; + } + }, + sampler : { + get : function() { + return this._sampler; + }, + set : function(sampler) { + var minificationFilter = sampler.minificationFilter; + var magnificationFilter = sampler.magnificationFilter; - UniformInt.prototype.set = function() { - if (this.value !== this._value) { - this._value = this.value; - this._gl.uniform1i(this._location, this.value); - } - }; + var mipmap = + (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || + (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || + (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || + (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR); - /////////////////////////////////////////////////////////////////////////// + // float textures only support nearest filtering, so override the sampler's settings + if (this._pixelDatatype === PixelDatatype.FLOAT) { + minificationFilter = mipmap ? TextureMinificationFilter.NEAREST_MIPMAP_NEAREST : TextureMinificationFilter.NEAREST; + magnificationFilter = TextureMagnificationFilter.NEAREST; + } - function UniformIntVec2(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; + var gl = this._gl; + var target = this._textureTarget; - this.value = undefined; - this._value = new Cartesian2(); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); + gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, minificationFilter); + gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, magnificationFilter); + gl.texParameteri(target, gl.TEXTURE_WRAP_S, sampler.wrapS); + gl.texParameteri(target, gl.TEXTURE_WRAP_T, sampler.wrapT); + if (defined(this._textureFilterAnisotropic)) { + gl.texParameteri(target, this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, sampler.maximumAnisotropy); + } + gl.bindTexture(target, null); - this._gl = gl; - this._location = location; - } + this._sampler = sampler; + } + }, + pixelFormat: { + get : function() { + return this._pixelFormat; + } + }, + pixelDatatype : { + get : function() { + return this._pixelDatatype; + } + }, + width : { + get : function() { + return this._size; + } + }, + height : { + get : function() { + return this._size; + } + }, + sizeInBytes : { + get : function() { + if (this._hasMipmap) { + return Math.floor(this._sizeInBytes * 4 / 3); + } + return this._sizeInBytes; + } + }, + preMultiplyAlpha : { + get : function() { + return this._preMultiplyAlpha; + } + }, + flipY : { + get : function() { + return this._flipY; + } + }, - UniformIntVec2.prototype.set = function() { - var v = this.value; - if (!Cartesian2.equals(v, this._value)) { - Cartesian2.clone(v, this._value); - this._gl.uniform2i(this._location, v.x, v.y); + _target : { + get : function() { + return this._textureTarget; + } } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformIntVec3(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = new Cartesian3(); + }); - this._gl = gl; - this._location = location; - } + /** + * Generates a complete mipmap chain for each cubemap face. + * + * @param {MipmapHint} [hint=MipmapHint.DONT_CARE] A performance vs. quality hint. + * + * @exception {DeveloperError} hint is invalid. + * @exception {DeveloperError} This CubeMap's width must be a power of two to call generateMipmap(). + * @exception {DeveloperError} This CubeMap's height must be a power of two to call generateMipmap(). + * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called. + * + * @example + * // Generate mipmaps, and then set the sampler so mipmaps are used for + * // minification when the cube map is sampled. + * cubeMap.generateMipmap(); + * cubeMap.sampler = new Sampler({ + * minificationFilter : Cesium.TextureMinificationFilter.NEAREST_MIPMAP_LINEAR + * }); + */ + CubeMap.prototype.generateMipmap = function(hint) { + hint = defaultValue(hint, MipmapHint.DONT_CARE); - UniformIntVec3.prototype.set = function() { - var v = this.value; - if (!Cartesian3.equals(v, this._value)) { - Cartesian3.clone(v, this._value); - this._gl.uniform3i(this._location, v.x, v.y, v.z); + if ((this._size > 1) && !CesiumMath.isPowerOfTwo(this._size)) { + throw new DeveloperError('width and height must be a power of two to call generateMipmap().'); } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformIntVec4(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = new Cartesian4(); - - this._gl = gl; - this._location = location; - } - - UniformIntVec4.prototype.set = function() { - var v = this.value; - if (!Cartesian4.equals(v, this._value)) { - Cartesian4.clone(v, this._value); - this._gl.uniform4i(this._location, v.x, v.y, v.z, v.w); + if (!MipmapHint.validate(hint)) { + throw new DeveloperError('hint is invalid.'); } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformMat2(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = new Float32Array(4); - - this._gl = gl; - this._location = location; - } + + this._hasMipmap = true; - UniformMat2.prototype.set = function() { - if (!Matrix2.equalsArray(this.value, this._value, 0)) { - Matrix2.toArray(this.value, this._value); - this._gl.uniformMatrix2fv(this._location, false, this._value); - } + var gl = this._gl; + var target = this._textureTarget; + gl.hint(gl.GENERATE_MIPMAP_HINT, hint); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); + gl.generateMipmap(target); + gl.bindTexture(target, null); }; - /////////////////////////////////////////////////////////////////////////// - - function UniformMat3(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = new Float32Array(9); - - this._gl = gl; - this._location = location; - } - - UniformMat3.prototype.set = function() { - if (!Matrix3.equalsArray(this.value, this._value, 0)) { - Matrix3.toArray(this.value, this._value); - this._gl.uniformMatrix3fv(this._location, false, this._value); - } + CubeMap.prototype.isDestroyed = function() { + return false; }; - /////////////////////////////////////////////////////////////////////////// - - function UniformMat4(gl, activeUniform, uniformName, location) { - /** - * @readonly - */ - this.name = uniformName; - - this.value = undefined; - this._value = new Float32Array(16); - - this._gl = gl; - this._location = location; - } - - UniformMat4.prototype.set = function() { - if (!Matrix4.equalsArray(this.value, this._value, 0)) { - Matrix4.toArray(this.value, this._value); - this._gl.uniformMatrix4fv(this._location, false, this._value); - } + CubeMap.prototype.destroy = function() { + this._gl.deleteTexture(this._texture); + this._positiveX = destroyObject(this._positiveX); + this._negativeX = destroyObject(this._negativeX); + this._positiveY = destroyObject(this._positiveY); + this._negativeY = destroyObject(this._negativeY); + this._positiveZ = destroyObject(this._positiveZ); + this._negativeZ = destroyObject(this._negativeZ); + return destroyObject(this); }; - return createUniform; + return CubeMap; }); -define('Renderer/createUniformArray',[ +define('Renderer/Texture',[ '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Color', + '../Core/Check', + '../Core/createGuid', + '../Core/defaultValue', '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Matrix2', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/RuntimeError' + '../Core/Math', + '../Core/PixelFormat', + '../Core/WebGLConstants', + './ContextLimits', + './MipmapHint', + './PixelDatatype', + './Sampler', + './TextureMagnificationFilter', + './TextureMinificationFilter' ], function( Cartesian2, - Cartesian3, - Cartesian4, - Color, + Check, + createGuid, + defaultValue, defined, + defineProperties, + destroyObject, DeveloperError, - Matrix2, - Matrix3, - Matrix4, - RuntimeError) { + CesiumMath, + PixelFormat, + WebGLConstants, + ContextLimits, + MipmapHint, + PixelDatatype, + Sampler, + TextureMagnificationFilter, + TextureMinificationFilter) { 'use strict'; - /** - * @private - */ - function createUniformArray(gl, activeUniform, uniformName, locations) { - switch (activeUniform.type) { - case gl.FLOAT: - return new UniformArrayFloat(gl, activeUniform, uniformName, locations); - case gl.FLOAT_VEC2: - return new UniformArrayFloatVec2(gl, activeUniform, uniformName, locations); - case gl.FLOAT_VEC3: - return new UniformArrayFloatVec3(gl, activeUniform, uniformName, locations); - case gl.FLOAT_VEC4: - return new UniformArrayFloatVec4(gl, activeUniform, uniformName, locations); - case gl.SAMPLER_2D: - case gl.SAMPLER_CUBE: - return new UniformArraySampler(gl, activeUniform, uniformName, locations); - case gl.INT: - case gl.BOOL: - return new UniformArrayInt(gl, activeUniform, uniformName, locations); - case gl.INT_VEC2: - case gl.BOOL_VEC2: - return new UniformArrayIntVec2(gl, activeUniform, uniformName, locations); - case gl.INT_VEC3: - case gl.BOOL_VEC3: - return new UniformArrayIntVec3(gl, activeUniform, uniformName, locations); - case gl.INT_VEC4: - case gl.BOOL_VEC4: - return new UniformArrayIntVec4(gl, activeUniform, uniformName, locations); - case gl.FLOAT_MAT2: - return new UniformArrayMat2(gl, activeUniform, uniformName, locations); - case gl.FLOAT_MAT3: - return new UniformArrayMat3(gl, activeUniform, uniformName, locations); - case gl.FLOAT_MAT4: - return new UniformArrayMat4(gl, activeUniform, uniformName, locations); - default: - throw new RuntimeError('Unrecognized uniform type: ' + activeUniform.type + ' for uniform "' + uniformName + '".'); - } - } - - function UniformArrayFloat(gl, activeUniform, uniformName, locations) { - var length = locations.length; + function Texture(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * @readonly - */ - this.name = uniformName; + Check.defined('options.context', options.context); + + var context = options.context; + var width = options.width; + var height = options.height; + var source = options.source; - this.value = new Array(length); - this._value = new Float32Array(length); + if (defined(source)) { + if (!defined(width)) { + width = defaultValue(source.videoWidth, source.width); + } + if (!defined(height)) { + height = defaultValue(source.videoHeight, source.height); + } + } - this._gl = gl; - this._location = locations[0]; - } + var pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGBA); + var pixelDatatype = defaultValue(options.pixelDatatype, PixelDatatype.UNSIGNED_BYTE); + var internalFormat = pixelFormat; - UniformArrayFloat.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; + var isCompressed = PixelFormat.isCompressedFormat(internalFormat); - for (var i = 0; i < length; ++i) { - var v = value[i]; + if (context.webgl2) { + if (pixelFormat === PixelFormat.DEPTH_STENCIL) { + internalFormat = WebGLConstants.DEPTH24_STENCIL8; + } else if (pixelFormat === PixelFormat.DEPTH_COMPONENT) { + if (pixelDatatype === PixelDatatype.UNSIGNED_SHORT) { + internalFormat = WebGLConstants.DEPTH_COMPONENT16; + } else if (pixelDatatype === PixelDatatype.UNSIGNED_INT) { + internalFormat = WebGLConstants.DEPTH_COMPONENT24; + } + } - if (v !== arraybuffer[i]) { - arraybuffer[i] = v; - changed = true; + if (pixelDatatype === PixelDatatype.FLOAT) { + switch (pixelFormat) { + case PixelFormat.RGBA: + internalFormat = WebGLConstants.RGBA32F; + break; + case PixelFormat.RGB: + internalFormat = WebGLConstants.RGB32F; + break; + case PixelFormat.RG: + internalFormat = WebGLConstants.RG32F; + break; + case PixelFormat.R: + internalFormat = WebGLConstants.R32F; + break; + } } } - if (changed) { - this._gl.uniform1fv(this._location, arraybuffer); + if (!defined(width) || !defined(height)) { + throw new DeveloperError('options requires a source field to create an initialized texture or width and height fields to create a blank texture.'); } - }; - /////////////////////////////////////////////////////////////////////////// + Check.typeOf.number.greaterThan('width', width, 0); - function UniformArrayFloatVec2(gl, activeUniform, uniformName, locations) { - var length = locations.length; + if (width > ContextLimits.maximumTextureSize) { + throw new DeveloperError('Width must be less than or equal to the maximum texture size (' + ContextLimits.maximumTextureSize + '). Check maximumTextureSize.'); + } - /** - * @readonly - */ - this.name = uniformName; + Check.typeOf.number.greaterThan('height', height, 0); - this.value = new Array(length); - this._value = new Float32Array(length * 2); + if (height > ContextLimits.maximumTextureSize) { + throw new DeveloperError('Height must be less than or equal to the maximum texture size (' + ContextLimits.maximumTextureSize + '). Check maximumTextureSize.'); + } - this._gl = gl; - this._location = locations[0]; - } + if (!PixelFormat.validate(pixelFormat)) { + throw new DeveloperError('Invalid options.pixelFormat.'); + } - UniformArrayFloatVec2.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; + if (!isCompressed && !PixelDatatype.validate(pixelDatatype)) { + throw new DeveloperError('Invalid options.pixelDatatype.'); + } - for (var i = 0; i < length; ++i) { - var v = value[i]; + if ((pixelFormat === PixelFormat.DEPTH_COMPONENT) && + ((pixelDatatype !== PixelDatatype.UNSIGNED_SHORT) && (pixelDatatype !== PixelDatatype.UNSIGNED_INT))) { + throw new DeveloperError('When options.pixelFormat is DEPTH_COMPONENT, options.pixelDatatype must be UNSIGNED_SHORT or UNSIGNED_INT.'); + } - if (!Cartesian2.equalsArray(v, arraybuffer, j)) { - Cartesian2.pack(v, arraybuffer, j); - changed = true; - } - j += 2; + if ((pixelFormat === PixelFormat.DEPTH_STENCIL) && (pixelDatatype !== PixelDatatype.UNSIGNED_INT_24_8)) { + throw new DeveloperError('When options.pixelFormat is DEPTH_STENCIL, options.pixelDatatype must be UNSIGNED_INT_24_8.'); } - if (changed) { - this._gl.uniform2fv(this._location, arraybuffer); + if ((pixelDatatype === PixelDatatype.FLOAT) && !context.floatingPointTexture) { + throw new DeveloperError('When options.pixelDatatype is FLOAT, this WebGL implementation must support the OES_texture_float extension. Check context.floatingPointTexture.'); } - }; - /////////////////////////////////////////////////////////////////////////// + if (PixelFormat.isDepthFormat(pixelFormat)) { + if (defined(source)) { + throw new DeveloperError('When options.pixelFormat is DEPTH_COMPONENT or DEPTH_STENCIL, source cannot be provided.'); + } - function UniformArrayFloatVec3(gl, activeUniform, uniformName, locations) { - var length = locations.length; + if (!context.depthTexture) { + throw new DeveloperError('When options.pixelFormat is DEPTH_COMPONENT or DEPTH_STENCIL, this WebGL implementation must support WEBGL_depth_texture. Check context.depthTexture.'); + } + } - /** - * @readonly - */ - this.name = uniformName; + if (isCompressed) { + if (!defined(source) || !defined(source.arrayBufferView)) { + throw new DeveloperError('When options.pixelFormat is compressed, options.source.arrayBufferView must be defined.'); + } - this.value = new Array(length); - this._value = new Float32Array(length * 3); + if (PixelFormat.isDXTFormat(internalFormat) && !context.s3tc) { + throw new DeveloperError('When options.pixelFormat is S3TC compressed, this WebGL implementation must support the WEBGL_texture_compression_s3tc extension. Check context.s3tc.'); + } else if (PixelFormat.isPVRTCFormat(internalFormat) && !context.pvrtc) { + throw new DeveloperError('When options.pixelFormat is PVRTC compressed, this WebGL implementation must support the WEBGL_texture_compression_pvrtc extension. Check context.pvrtc.'); + } else if (PixelFormat.isETC1Format(internalFormat) && !context.etc1) { + throw new DeveloperError('When options.pixelFormat is ETC1 compressed, this WebGL implementation must support the WEBGL_texture_compression_etc1 extension. Check context.etc1.'); + } - this._gl = gl; - this._location = locations[0]; - } + if (PixelFormat.compressedTextureSizeInBytes(internalFormat, width, height) !== source.arrayBufferView.byteLength) { + throw new DeveloperError('The byte length of the array buffer is invalid for the compressed texture with the given width and height.'); + } + } + + // Use premultiplied alpha for opaque textures should perform better on Chrome: + // http://media.tojicode.com/webglCamp4/#20 + var preMultiplyAlpha = options.preMultiplyAlpha || pixelFormat === PixelFormat.RGB || pixelFormat === PixelFormat.LUMINANCE; + var flipY = defaultValue(options.flipY, true); - UniformArrayFloatVec3.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; + var gl = context._gl; + var textureTarget = gl.TEXTURE_2D; + var texture = gl.createTexture(); - for (var i = 0; i < length; ++i) { - var v = value[i]; + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(textureTarget, texture); - if (defined(v.red)) { - if ((v.red !== arraybuffer[j]) || - (v.green !== arraybuffer[j + 1]) || - (v.blue !== arraybuffer[j + 2])) { + if (defined(source)) { + // TODO: _gl.pixelStorei(_gl._UNPACK_ALIGNMENT, 4); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - arraybuffer[j] = v.red; - arraybuffer[j + 1] = v.green; - arraybuffer[j + 2] = v.blue; - changed = true; + if (defined(source.arrayBufferView)) { + // Source: typed array + if (isCompressed) { + gl.compressedTexImage2D(textureTarget, 0, internalFormat, width, height, 0, source.arrayBufferView); + } else { + gl.texImage2D(textureTarget, 0, internalFormat, width, height, 0, pixelFormat, pixelDatatype, source.arrayBufferView); } - } else if (defined(v.x)) { - if (!Cartesian3.equalsArray(v, arraybuffer, j)) { - Cartesian3.pack(v, arraybuffer, j); - changed = true; + } else if (defined(source.framebuffer)) { + // Source: framebuffer + if (source.framebuffer !== context.defaultFramebuffer) { + source.framebuffer._bind(); } - } else { - throw new DeveloperError('Invalid vec3 value.'); - } - - j += 3; - } - - if (changed) { - this._gl.uniform3fv(this._location, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayFloatVec4(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Float32Array(length * 4); - - this._gl = gl; - this._location = locations[0]; - } - - UniformArrayFloatVec4.prototype.set = function() { - // PERFORMANCE_IDEA: if it is a common case that only a few elements - // in a uniform array change, we could use heuristics to determine - // when it is better to call uniform4f for each element that changed - // vs. call uniform4fv once to set the entire array. This applies - // to all uniform array types, not just vec4. We might not care - // once we have uniform buffers since that will be the fast path. - - // PERFORMANCE_IDEA: Micro-optimization (I bet it works though): - // As soon as changed is true, break into a separate loop that - // does the copy without the equals check. - - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; - for (var i = 0; i < length; ++i) { - var v = value[i]; + gl.copyTexImage2D(textureTarget, 0, internalFormat, source.xOffset, source.yOffset, width, height, 0); - if (defined(v.red)) { - if (!Color.equalsArray(v, arraybuffer, j)) { - Color.pack(v, arraybuffer, j); - changed = true; - } - } else if (defined(v.x)) { - if (!Cartesian4.equalsArray(v, arraybuffer, j)) { - Cartesian4.pack(v, arraybuffer, j); - changed = true; + if (source.framebuffer !== context.defaultFramebuffer) { + source.framebuffer._unBind(); } } else { - throw new DeveloperError('Invalid vec4 value.'); - } - - j += 4; + // Source: ImageData, HTMLImageElement, HTMLCanvasElement, or HTMLVideoElement + gl.texImage2D(textureTarget, 0, internalFormat, pixelFormat, pixelDatatype, source); + } + } else { + gl.texImage2D(textureTarget, 0, internalFormat, width, height, 0, pixelFormat, pixelDatatype, null); } + gl.bindTexture(textureTarget, null); - if (changed) { - this._gl.uniform4fv(this._location, arraybuffer); + var sizeInBytes; + if (isCompressed) { + sizeInBytes = PixelFormat.compressedTextureSizeInBytes(pixelFormat, width, height); + } else { + sizeInBytes = PixelFormat.textureSizeInBytes(pixelFormat, pixelDatatype, width, height); } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArraySampler(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Float32Array(length); - this._gl = gl; - this._locations = locations; + this._id = createGuid(); + this._context = context; + this._textureFilterAnisotropic = context._textureFilterAnisotropic; + this._textureTarget = textureTarget; + this._texture = texture; + this._pixelFormat = pixelFormat; + this._pixelDatatype = pixelDatatype; + this._width = width; + this._height = height; + this._dimensions = new Cartesian2(width, height); + this._hasMipmap = false; + this._sizeInBytes = sizeInBytes; + this._preMultiplyAlpha = preMultiplyAlpha; + this._flipY = flipY; + this._sampler = undefined; - this.textureUnitIndex = undefined; + this.sampler = defined(options.sampler) ? options.sampler : new Sampler(); } - UniformArraySampler.prototype.set = function() { - var gl = this._gl; - var textureUnitIndex = gl.TEXTURE0 + this.textureUnitIndex; + /** + * Creates a texture, and copies a subimage of the framebuffer to it. When called without arguments, + * the texture is the same width and height as the framebuffer and contains its contents. + * + * @param {Object} options Object with the following properties: + * @param {Context} options.context The context in which the Texture gets created. + * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGB] The texture's internal pixel format. + * @param {Number} [options.framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. + * @param {Number} [options.framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. + * @param {Number} [options.width=canvas.clientWidth] The width of the texture in texels. + * @param {Number} [options.height=canvas.clientHeight] The height of the texture in texels. + * @param {Framebuffer} [options.framebuffer=defaultFramebuffer] The framebuffer from which to create the texture. If this + * parameter is not specified, the default framebuffer is used. + * @returns {Texture} A texture with contents from the framebuffer. + * + * @exception {DeveloperError} Invalid pixelFormat. + * @exception {DeveloperError} pixelFormat cannot be DEPTH_COMPONENT, DEPTH_STENCIL or a compressed format. + * @exception {DeveloperError} framebufferXOffset must be greater than or equal to zero. + * @exception {DeveloperError} framebufferYOffset must be greater than or equal to zero. + * @exception {DeveloperError} framebufferXOffset + width must be less than or equal to canvas.clientWidth. + * @exception {DeveloperError} framebufferYOffset + height must be less than or equal to canvas.clientHeight. + * + * + * @example + * // Create a texture with the contents of the framebuffer. + * var t = Texture.fromFramebuffer({ + * context : context + * }); + * + * @see Sampler + * + * @private + */ + Texture.fromFramebuffer = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var value = this.value; - var length = value.length; - for (var i = 0; i < length; ++i) { - var v = value[i]; - gl.activeTexture(textureUnitIndex + i); - gl.bindTexture(v._target, v._texture); - } - }; + Check.defined('options.context', options.context); + + var context = options.context; + var gl = context._gl; - UniformArraySampler.prototype._setSampler = function(textureUnitIndex) { - this.textureUnitIndex = textureUnitIndex; + var pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGB); + var framebufferXOffset = defaultValue(options.framebufferXOffset, 0); + var framebufferYOffset = defaultValue(options.framebufferYOffset, 0); + var width = defaultValue(options.width, gl.drawingBufferWidth); + var height = defaultValue(options.height, gl.drawingBufferHeight); + var framebuffer = options.framebuffer; - var locations = this._locations; - var length = locations.length; - for (var i = 0; i < length; ++i) { - var index = textureUnitIndex + i; - this._gl.uniform1i(locations[i], index); + if (!PixelFormat.validate(pixelFormat)) { + throw new DeveloperError('Invalid pixelFormat.'); + } + if (PixelFormat.isDepthFormat(pixelFormat) || PixelFormat.isCompressedFormat(pixelFormat)) { + throw new DeveloperError('pixelFormat cannot be DEPTH_COMPONENT, DEPTH_STENCIL or a compressed format.'); + } + Check.defined('options.context', options.context); + Check.typeOf.number.greaterThanOrEquals('framebufferXOffset', framebufferXOffset, 0); + Check.typeOf.number.greaterThanOrEquals('framebufferYOffset', framebufferYOffset, 0); + if (framebufferXOffset + width > gl.drawingBufferWidth) { + throw new DeveloperError('framebufferXOffset + width must be less than or equal to drawingBufferWidth'); + } + if (framebufferYOffset + height > gl.drawingBufferHeight) { + throw new DeveloperError('framebufferYOffset + height must be less than or equal to drawingBufferHeight.'); } + + var texture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : pixelFormat, + source : { + framebuffer : defined(framebuffer) ? framebuffer : context.defaultFramebuffer, + xOffset : framebufferXOffset, + yOffset : framebufferYOffset, + width : width, + height : height + } + }); - return textureUnitIndex + length; + return texture; }; - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayInt(gl, activeUniform, uniformName, locations) { - var length = locations.length; - + defineProperties(Texture.prototype, { /** + * A unique id for the texture + * @memberof Texture.prototype + * @type {String} * @readonly + * @private */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Int32Array(length); + id : { + get : function() { + return this._id; + } + }, + /** + * The sampler to use when sampling this texture. + * Create a sampler by calling {@link Sampler}. If this + * parameter is not specified, a default sampler is used. The default sampler clamps texture + * coordinates in both directions, uses linear filtering for both magnification and minifcation, + * and uses a maximum anisotropy of 1.0. + * @memberof Texture.prototype + * @type {Object} + */ + sampler : { + get : function() { + return this._sampler; + }, + set : function(sampler) { + var minificationFilter = sampler.minificationFilter; + var magnificationFilter = sampler.magnificationFilter; - this._gl = gl; - this._location = locations[0]; - } + var mipmap = + (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || + (minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || + (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || + (minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR); - UniformArrayInt.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - - for (var i = 0; i < length; ++i) { - var v = value[i]; - - if (v !== arraybuffer[i]) { - arraybuffer[i] = v; - changed = true; - } - } - - if (changed) { - this._gl.uniform1iv(this._location, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayIntVec2(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Int32Array(length * 2); - - this._gl = gl; - this._location = locations[0]; - } - - UniformArrayIntVec2.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; - - for (var i = 0; i < length; ++i) { - var v = value[i]; - - if (!Cartesian2.equalsArray(v, arraybuffer, j)) { - Cartesian2.pack(v, arraybuffer, j); - changed = true; - } - j += 2; - } - - if (changed) { - this._gl.uniform2iv(this._location, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayIntVec3(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Int32Array(length * 3); - - this._gl = gl; - this._location = locations[0]; - } + // float textures only support nearest filtering, so override the sampler's settings + if (this._pixelDatatype === PixelDatatype.FLOAT) { + minificationFilter = mipmap ? TextureMinificationFilter.NEAREST_MIPMAP_NEAREST : TextureMinificationFilter.NEAREST; + magnificationFilter = TextureMagnificationFilter.NEAREST; + } - UniformArrayIntVec3.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; + var gl = this._context._gl; + var target = this._textureTarget; - for (var i = 0; i < length; ++i) { - var v = value[i]; + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); + gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, minificationFilter); + gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, magnificationFilter); + gl.texParameteri(target, gl.TEXTURE_WRAP_S, sampler.wrapS); + gl.texParameteri(target, gl.TEXTURE_WRAP_T, sampler.wrapT); + if (defined(this._textureFilterAnisotropic)) { + gl.texParameteri(target, this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, sampler.maximumAnisotropy); + } + gl.bindTexture(target, null); - if (!Cartesian3.equalsArray(v, arraybuffer, j)) { - Cartesian3.pack(v, arraybuffer, j); - changed = true; + this._sampler = sampler; } - j += 3; - } - - if (changed) { - this._gl.uniform3iv(this._location, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayIntVec4(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Int32Array(length * 4); - - this._gl = gl; - this._location = locations[0]; - } - - UniformArrayIntVec4.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; - - for (var i = 0; i < length; ++i) { - var v = value[i]; - - if (!Cartesian4.equalsArray(v, arraybuffer, j)) { - Cartesian4.pack(v, arraybuffer, j); - changed = true; + }, + pixelFormat : { + get : function() { + return this._pixelFormat; } - j += 4; - } - - if (changed) { - this._gl.uniform4iv(this._location, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayMat2(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Float32Array(length * 4); - - this._gl = gl; - this._location = locations[0]; - } - - UniformArrayMat2.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; - - for (var i = 0; i < length; ++i) { - var v = value[i]; - - if (!Matrix2.equalsArray(v, arraybuffer, j)) { - Matrix2.pack(v, arraybuffer, j); - changed = true; + }, + pixelDatatype : { + get : function() { + return this._pixelDatatype; } - j += 4; - } - - if (changed) { - this._gl.uniformMatrix2fv(this._location, false, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayMat3(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Float32Array(length * 9); - - this._gl = gl; - this._location = locations[0]; - } - - UniformArrayMat3.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; - - for (var i = 0; i < length; ++i) { - var v = value[i]; - - if (!Matrix3.equalsArray(v, arraybuffer, j)) { - Matrix3.pack(v, arraybuffer, j); - changed = true; + }, + dimensions : { + get : function() { + return this._dimensions; } - j += 9; - } - - if (changed) { - this._gl.uniformMatrix3fv(this._location, false, arraybuffer); - } - }; - - /////////////////////////////////////////////////////////////////////////// - - function UniformArrayMat4(gl, activeUniform, uniformName, locations) { - var length = locations.length; - - /** - * @readonly - */ - this.name = uniformName; - - this.value = new Array(length); - this._value = new Float32Array(length * 16); - - this._gl = gl; - this._location = locations[0]; - } - - UniformArrayMat4.prototype.set = function() { - var value = this.value; - var length = value.length; - var arraybuffer = this._value; - var changed = false; - var j = 0; - - for (var i = 0; i < length; ++i) { - var v = value[i]; - - if (!Matrix4.equalsArray(v, arraybuffer, j)) { - Matrix4.pack(v, arraybuffer, j); - changed = true; + }, + preMultiplyAlpha : { + get : function() { + return this._preMultiplyAlpha; } - j += 16; - } - - if (changed) { - this._gl.uniformMatrix4fv(this._location, false, arraybuffer); - } - }; - - return createUniformArray; -}); - -define('Renderer/ShaderProgram',[ - '../Core/Check', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/RuntimeError', - './AutomaticUniforms', - './ContextLimits', - './createUniform', - './createUniformArray' - ], function( - Check, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - RuntimeError, - AutomaticUniforms, - ContextLimits, - createUniform, - createUniformArray) { - 'use strict'; - - var nextShaderProgramId = 0; - - /** - * @private - */ - function ShaderProgram(options) { - var modifiedFS = handleUniformPrecisionMismatches(options.vertexShaderText, options.fragmentShaderText); - - this._gl = options.gl; - this._logShaderCompilation = options.logShaderCompilation; - this._debugShaders = options.debugShaders; - this._attributeLocations = options.attributeLocations; - - this._program = undefined; - this._numberOfVertexAttributes = undefined; - this._vertexAttributes = undefined; - this._uniformsByName = undefined; - this._uniforms = undefined; - this._automaticUniforms = undefined; - this._manualUniforms = undefined; - this._duplicateUniformNames = modifiedFS.duplicateUniformNames; - this._cachedShader = undefined; // Used by ShaderCache - - /** - * @private - */ - this.maximumTextureUnitIndex = undefined; - - this._vertexShaderSource = options.vertexShaderSource; - this._vertexShaderText = options.vertexShaderText; - this._fragmentShaderSource = options.fragmentShaderSource; - this._fragmentShaderText = modifiedFS.fragmentShaderText; - - /** - * @private - */ - this.id = nextShaderProgramId++; - } - - ShaderProgram.fromCache = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - Check.defined('options.context', options.context); - - return options.context.shaderCache.getShaderProgram(options); - }; - - ShaderProgram.replaceCache = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - Check.defined('options.context', options.context); - - return options.context.shaderCache.replaceShaderProgram(options); - }; - - defineProperties(ShaderProgram.prototype, { - /** - * GLSL source for the shader program's vertex shader. - * @memberof ShaderProgram.prototype - * - * @type {ShaderSource} - * @readonly - */ - vertexShaderSource : { + }, + flipY : { get : function() { - return this._vertexShaderSource; + return this._flipY; } }, - /** - * GLSL source for the shader program's fragment shader. - * @memberof ShaderProgram.prototype - * - * @type {ShaderSource} - * @readonly - */ - fragmentShaderSource : { + width : { get : function() { - return this._fragmentShaderSource; + return this._width; } }, - vertexAttributes : { + height : { get : function() { - initialize(this); - return this._vertexAttributes; + return this._height; } }, - numberOfVertexAttributes : { + sizeInBytes : { get : function() { - initialize(this); - return this._numberOfVertexAttributes; + if (this._hasMipmap) { + return Math.floor(this._sizeInBytes * 4 / 3); + } + return this._sizeInBytes; } }, - allUniforms : { + _target : { get : function() { - initialize(this); - return this._uniformsByName; + return this._textureTarget; } } }); - function extractUniforms(shaderText) { - var uniformNames = []; - var uniformLines = shaderText.match(/uniform.*?(?![^{]*})(?=[=\[;])/g); - if (defined(uniformLines)) { - var len = uniformLines.length; - for (var i = 0; i < len; i++) { - var line = uniformLines[i].trim(); - var name = line.slice(line.lastIndexOf(' ') + 1); - uniformNames.push(name); - } - } - return uniformNames; - } - - function handleUniformPrecisionMismatches(vertexShaderText, fragmentShaderText) { - // If a uniform exists in both the vertex and fragment shader but with different precision qualifiers, - // give the fragment shader uniform a different name. This fixes shader compilation errors on devices - // that only support mediump in the fragment shader. - var duplicateUniformNames = {}; - - if (!ContextLimits.highpFloatSupported || !ContextLimits.highpIntSupported) { - var i, j; - var uniformName; - var duplicateName; - var vertexShaderUniforms = extractUniforms(vertexShaderText); - var fragmentShaderUniforms = extractUniforms(fragmentShaderText); - var vertexUniformsCount = vertexShaderUniforms.length; - var fragmentUniformsCount = fragmentShaderUniforms.length; + /** + * Copy new image data into this texture, from a source {@link ImageData}, {@link Image}, {@link Canvas}, or {@link Video}. + * or an object with width, height, and arrayBufferView properties. + * + * @param {Object} source The source {@link ImageData}, {@link Image}, {@link Canvas}, or {@link Video}, + * or an object with width, height, and arrayBufferView properties. + * @param {Number} [xOffset=0] The offset in the x direction within the texture to copy into. + * @param {Number} [yOffset=0] The offset in the y direction within the texture to copy into. + * + * @exception {DeveloperError} Cannot call copyFrom when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. + * @exception {DeveloperError} Cannot call copyFrom with a compressed texture pixel format. + * @exception {DeveloperError} xOffset must be greater than or equal to zero. + * @exception {DeveloperError} yOffset must be greater than or equal to zero. + * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. + * @exception {DeveloperError} yOffset + source.height must be less than or equal to height. + * @exception {DeveloperError} This texture was destroyed, i.e., destroy() was called. + * + * @example + * texture.copyFrom({ + * width : 1, + * height : 1, + * arrayBufferView : new Uint8Array([255, 0, 0, 255]) + * }); + */ + Texture.prototype.copyFrom = function(source, xOffset, yOffset) { + xOffset = defaultValue(xOffset, 0); + yOffset = defaultValue(yOffset, 0); - for (i = 0; i < vertexUniformsCount; i++) { - for (j = 0; j < fragmentUniformsCount; j++) { - if (vertexShaderUniforms[i] === fragmentShaderUniforms[j]) { - uniformName = vertexShaderUniforms[i]; - duplicateName = 'czm_mediump_' + uniformName; - // Update fragmentShaderText with renamed uniforms - var re = new RegExp(uniformName + '\\b', 'g'); - fragmentShaderText = fragmentShaderText.replace(re, duplicateName); - duplicateUniformNames[duplicateName] = uniformName; - } - } - } + Check.defined('source', source); + if (PixelFormat.isDepthFormat(this._pixelFormat)) { + throw new DeveloperError('Cannot call copyFrom when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL.'); } - - return { - fragmentShaderText : fragmentShaderText, - duplicateUniformNames : duplicateUniformNames - }; - } - - var consolePrefix = '[Cesium WebGL] '; - - function createAndLinkProgram(gl, shader) { - var vsSource = shader._vertexShaderText; - var fsSource = shader._fragmentShaderText; - - var vertexShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertexShader, vsSource); - gl.compileShader(vertexShader); - - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fsSource); - gl.compileShader(fragmentShader); - - var program = gl.createProgram(); - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - - gl.deleteShader(vertexShader); - gl.deleteShader(fragmentShader); - - var attributeLocations = shader._attributeLocations; - if (defined(attributeLocations)) { - for ( var attribute in attributeLocations) { - if (attributeLocations.hasOwnProperty(attribute)) { - gl.bindAttribLocation(program, attributeLocations[attribute], attribute); - } - } + if (PixelFormat.isCompressedFormat(this._pixelFormat)) { + throw new DeveloperError('Cannot call copyFrom with a compressed texture pixel format.'); } + Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); + Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); + Check.typeOf.number.lessThanOrEquals('xOffset + source.width', xOffset + source.width, this._width); + Check.typeOf.number.lessThanOrEquals('yOffset + source.height', yOffset + source.height, this._height); + + var gl = this._context._gl; + var target = this._textureTarget; - gl.linkProgram(program); - - var log; - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - var debugShaders = shader._debugShaders; - - // For performance, only check compile errors if there is a linker error. - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - log = gl.getShaderInfoLog(fragmentShader); - console.error(consolePrefix + 'Fragment shader compile log: ' + log); - if (defined(debugShaders)) { - var fragmentSourceTranslation = debugShaders.getTranslatedShaderSource(fragmentShader); - if (fragmentSourceTranslation !== '') { - console.error(consolePrefix + 'Translated fragment shader source:\n' + fragmentSourceTranslation); - } else { - console.error(consolePrefix + 'Fragment shader translation failed.'); - } - } - - gl.deleteProgram(program); - throw new RuntimeError('Fragment shader failed to compile. Compile log: ' + log); - } - - if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { - log = gl.getShaderInfoLog(vertexShader); - console.error(consolePrefix + 'Vertex shader compile log: ' + log); - if (defined(debugShaders)) { - var vertexSourceTranslation = debugShaders.getTranslatedShaderSource(vertexShader); - if (vertexSourceTranslation !== '') { - console.error(consolePrefix + 'Translated vertex shader source:\n' + vertexSourceTranslation); - } else { - console.error(consolePrefix + 'Vertex shader translation failed.'); - } - } - - gl.deleteProgram(program); - throw new RuntimeError('Vertex shader failed to compile. Compile log: ' + log); - } - - log = gl.getProgramInfoLog(program); - console.error(consolePrefix + 'Shader program link log: ' + log); - if (defined(debugShaders)) { - console.error(consolePrefix + 'Translated vertex shader source:\n' + debugShaders.getTranslatedShaderSource(vertexShader)); - console.error(consolePrefix + 'Translated fragment shader source:\n' + debugShaders.getTranslatedShaderSource(fragmentShader)); - } + // TODO: gl.pixelStorei(gl._UNPACK_ALIGNMENT, 4); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this._preMultiplyAlpha); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this._flipY); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); - gl.deleteProgram(program); - throw new RuntimeError('Program failed to link. Link log: ' + log); + if (source.arrayBufferView) { + gl.texSubImage2D(target, 0, xOffset, yOffset, source.width, source.height, this._pixelFormat, this._pixelDatatype, source.arrayBufferView); + } else { + gl.texSubImage2D(target, 0, xOffset, yOffset, this._pixelFormat, this._pixelDatatype, source); } - var logShaderCompilation = shader._logShaderCompilation; - - if (logShaderCompilation) { - log = gl.getShaderInfoLog(vertexShader); - if (defined(log) && (log.length > 0)) { - console.log(consolePrefix + 'Vertex shader compile log: ' + log); - } - } + gl.bindTexture(target, null); + }; - if (logShaderCompilation) { - log = gl.getShaderInfoLog(fragmentShader); - if (defined(log) && (log.length > 0)) { - console.log(consolePrefix + 'Fragment shader compile log: ' + log); - } - } + /** + * @param {Number} [xOffset=0] The offset in the x direction within the texture to copy into. + * @param {Number} [yOffset=0] The offset in the y direction within the texture to copy into. + * @param {Number} [framebufferXOffset=0] optional + * @param {Number} [framebufferYOffset=0] optional + * @param {Number} [width=width] optional + * @param {Number} [height=height] optional + * + * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. + * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT. + * @exception {DeveloperError} Cannot call copyFrom with a compressed texture pixel format. + * @exception {DeveloperError} This texture was destroyed, i.e., destroy() was called. + * @exception {DeveloperError} xOffset must be greater than or equal to zero. + * @exception {DeveloperError} yOffset must be greater than or equal to zero. + * @exception {DeveloperError} framebufferXOffset must be greater than or equal to zero. + * @exception {DeveloperError} framebufferYOffset must be greater than or equal to zero. + * @exception {DeveloperError} xOffset + width must be less than or equal to width. + * @exception {DeveloperError} yOffset + height must be less than or equal to height. + */ + Texture.prototype.copyFromFramebuffer = function(xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height) { + xOffset = defaultValue(xOffset, 0); + yOffset = defaultValue(yOffset, 0); + framebufferXOffset = defaultValue(framebufferXOffset, 0); + framebufferYOffset = defaultValue(framebufferYOffset, 0); + width = defaultValue(width, this._width); + height = defaultValue(height, this._height); - if (logShaderCompilation) { - log = gl.getProgramInfoLog(program); - if (defined(log) && (log.length > 0)) { - console.log(consolePrefix + 'Shader program link log: ' + log); - } + if (PixelFormat.isDepthFormat(this._pixelFormat)) { + throw new DeveloperError('Cannot call copyFromFramebuffer when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL.'); } - - return program; - } - - function findVertexAttributes(gl, program, numberOfAttributes) { - var attributes = {}; - for (var i = 0; i < numberOfAttributes; ++i) { - var attr = gl.getActiveAttrib(program, i); - var location = gl.getAttribLocation(program, attr.name); - - attributes[attr.name] = { - name : attr.name, - type : attr.type, - index : location - }; + if (this._pixelDatatype === PixelDatatype.FLOAT) { + throw new DeveloperError('Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT.'); } - - return attributes; - } - - function findUniforms(gl, program) { - var uniformsByName = {}; - var uniforms = []; - var samplerUniforms = []; - - var numberOfUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - - for (var i = 0; i < numberOfUniforms; ++i) { - var activeUniform = gl.getActiveUniform(program, i); - var suffix = '[0]'; - var uniformName = activeUniform.name.indexOf(suffix, activeUniform.name.length - suffix.length) !== -1 ? activeUniform.name.slice(0, activeUniform.name.length - 3) : activeUniform.name; - - // Ignore GLSL built-in uniforms returned in Firefox. - if (uniformName.indexOf('gl_') !== 0) { - if (activeUniform.name.indexOf('[') < 0) { - // Single uniform - var location = gl.getUniformLocation(program, uniformName); - - // IE 11.0.9 needs this check since getUniformLocation can return null - // if the uniform is not active (e.g., it is optimized out). Looks like - // getActiveUniform() above returns uniforms that are not actually active. - if (location !== null) { - var uniform = createUniform(gl, activeUniform, uniformName, location); - - uniformsByName[uniformName] = uniform; - uniforms.push(uniform); - - if (uniform._setSampler) { - samplerUniforms.push(uniform); - } - } - } else { - // Uniform array - - var uniformArray; - var locations; - var value; - var loc; - - // On some platforms - Nexus 4 in Firefox for one - an array of sampler2D ends up being represented - // as separate uniforms, one for each array element. Check for and handle that case. - var indexOfBracket = uniformName.indexOf('['); - if (indexOfBracket >= 0) { - // We're assuming the array elements show up in numerical order - it seems to be true. - uniformArray = uniformsByName[uniformName.slice(0, indexOfBracket)]; - - // Nexus 4 with Android 4.3 needs this check, because it reports a uniform - // with the strange name webgl_3467e0265d05c3c1[1] in our globe surface shader. - if (!defined(uniformArray)) { - continue; - } - - locations = uniformArray._locations; - - // On the Nexus 4 in Chrome, we get one uniform per sampler, just like in Firefox, - // but the size is not 1 like it is in Firefox. So if we push locations here, - // we'll end up adding too many locations. - if (locations.length <= 1) { - value = uniformArray.value; - loc = gl.getUniformLocation(program, uniformName); - - // Workaround for IE 11.0.9. See above. - if (loc !== null) { - locations.push(loc); - value.push(gl.getUniform(program, loc)); - } - } - } else { - locations = []; - for (var j = 0; j < activeUniform.size; ++j) { - loc = gl.getUniformLocation(program, uniformName + '[' + j + ']'); - - // Workaround for IE 11.0.9. See above. - if (loc !== null) { - locations.push(loc); - } - } - uniformArray = createUniformArray(gl, activeUniform, uniformName, locations); - - uniformsByName[uniformName] = uniformArray; - uniforms.push(uniformArray); - - if (uniformArray._setSampler) { - samplerUniforms.push(uniformArray); - } - } - } - } + if (PixelFormat.isCompressedFormat(this._pixelFormat)) { + throw new DeveloperError('Cannot call copyFrom with a compressed texture pixel format.'); } - return { - uniformsByName : uniformsByName, - uniforms : uniforms, - samplerUniforms : samplerUniforms - }; - } - - function partitionUniforms(shader, uniforms) { - var automaticUniforms = []; - var manualUniforms = []; - - for (var uniform in uniforms) { - if (uniforms.hasOwnProperty(uniform)) { - var uniformObject = uniforms[uniform]; - var uniformName = uniform; - // if it's a duplicate uniform, use its original name so it is updated correctly - var duplicateUniform = shader._duplicateUniformNames[uniformName]; - if (defined(duplicateUniform)) { - uniformObject.name = duplicateUniform; - uniformName = duplicateUniform; - } - var automaticUniform = AutomaticUniforms[uniformName]; - if (defined(automaticUniform)) { - automaticUniforms.push({ - uniform : uniformObject, - automaticUniform : automaticUniform - }); - } else { - manualUniforms.push(uniformObject); - } - } - } + Check.typeOf.number.greaterThanOrEquals('xOffset', xOffset, 0); + Check.typeOf.number.greaterThanOrEquals('yOffset', yOffset, 0); + Check.typeOf.number.greaterThanOrEquals('framebufferXOffset', framebufferXOffset, 0); + Check.typeOf.number.greaterThanOrEquals('framebufferYOffset', framebufferYOffset, 0); + Check.typeOf.number.lessThanOrEquals('xOffset + width', xOffset + width, this._width); + Check.typeOf.number.lessThanOrEquals('yOffset + height', yOffset + height, this._height); + + var gl = this._context._gl; + var target = this._textureTarget; - return { - automaticUniforms : automaticUniforms, - manualUniforms : manualUniforms - }; - } + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); + gl.copyTexSubImage2D(target, 0, xOffset, yOffset, framebufferXOffset, framebufferYOffset, width, height); + gl.bindTexture(target, null); + }; - function setSamplerUniforms(gl, program, samplerUniforms) { - gl.useProgram(program); + /** + * @param {MipmapHint} [hint=MipmapHint.DONT_CARE] optional. + * + * @exception {DeveloperError} Cannot call generateMipmap when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. + * @exception {DeveloperError} Cannot call generateMipmap when the texture pixel format is a compressed format. + * @exception {DeveloperError} hint is invalid. + * @exception {DeveloperError} This texture's width must be a power of two to call generateMipmap(). + * @exception {DeveloperError} This texture's height must be a power of two to call generateMipmap(). + * @exception {DeveloperError} This texture was destroyed, i.e., destroy() was called. + */ + Texture.prototype.generateMipmap = function(hint) { + hint = defaultValue(hint, MipmapHint.DONT_CARE); - var textureUnitIndex = 0; - var length = samplerUniforms.length; - for (var i = 0; i < length; ++i) { - textureUnitIndex = samplerUniforms[i]._setSampler(textureUnitIndex); + if (PixelFormat.isDepthFormat(this._pixelFormat)) { + throw new DeveloperError('Cannot call generateMipmap when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL.'); } - - gl.useProgram(null); - - return textureUnitIndex; - } - - function initialize(shader) { - if (defined(shader._program)) { - return; + if (PixelFormat.isCompressedFormat(this._pixelFormat)) { + throw new DeveloperError('Cannot call generateMipmap with a compressed pixel format.'); } - - var gl = shader._gl; - var program = createAndLinkProgram(gl, shader, shader._debugShaders); - var numberOfVertexAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); - var uniforms = findUniforms(gl, program); - var partitionedUniforms = partitionUniforms(shader, uniforms.uniformsByName); - - shader._program = program; - shader._numberOfVertexAttributes = numberOfVertexAttributes; - shader._vertexAttributes = findVertexAttributes(gl, program, numberOfVertexAttributes); - shader._uniformsByName = uniforms.uniformsByName; - shader._uniforms = uniforms.uniforms; - shader._automaticUniforms = partitionedUniforms.automaticUniforms; - shader._manualUniforms = partitionedUniforms.manualUniforms; - - shader.maximumTextureUnitIndex = setSamplerUniforms(gl, program, uniforms.samplerUniforms); - } - - ShaderProgram.prototype._bind = function() { - initialize(this); - this._gl.useProgram(this._program); - }; - - ShaderProgram.prototype._setUniforms = function(uniformMap, uniformState, validate) { - var len; - var i; - - if (defined(uniformMap)) { - var manualUniforms = this._manualUniforms; - len = manualUniforms.length; - for (i = 0; i < len; ++i) { - var mu = manualUniforms[i]; - mu.value = uniformMap[mu.name](); - } + if (this._width > 1 && !CesiumMath.isPowerOfTwo(this._width)) { + throw new DeveloperError('width must be a power of two to call generateMipmap().'); } - - var automaticUniforms = this._automaticUniforms; - len = automaticUniforms.length; - for (i = 0; i < len; ++i) { - var au = automaticUniforms[i]; - au.uniform.value = au.automaticUniform.getValue(uniformState); + if (this._height > 1 && !CesiumMath.isPowerOfTwo(this._height)) { + throw new DeveloperError('height must be a power of two to call generateMipmap().'); } - - /////////////////////////////////////////////////////////////////// - - // It appears that assigning the uniform values above and then setting them here - // (which makes the GL calls) is faster than removing this loop and making - // the GL calls above. I suspect this is because each GL call pollutes the - // L2 cache making our JavaScript and the browser/driver ping-pong cache lines. - var uniforms = this._uniforms; - len = uniforms.length; - for (i = 0; i < len; ++i) { - uniforms[i].set(); + if (!MipmapHint.validate(hint)) { + throw new DeveloperError('hint is invalid.'); } + + this._hasMipmap = true; - if (validate) { - var gl = this._gl; - var program = this._program; + var gl = this._context._gl; + var target = this._textureTarget; - gl.validateProgram(program); - if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) { - throw new DeveloperError('Program validation failed. Program info log: ' + gl.getProgramInfoLog(program)); - } - } + gl.hint(gl.GENERATE_MIPMAP_HINT, hint); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(target, this._texture); + gl.generateMipmap(target); + gl.bindTexture(target, null); }; - ShaderProgram.prototype.isDestroyed = function() { + Texture.prototype.isDestroyed = function() { return false; }; - ShaderProgram.prototype.destroy = function() { - this._cachedShader.cache.releaseShaderProgram(this); - return undefined; - }; - - ShaderProgram.prototype.finalDestroy = function() { - this._gl.deleteProgram(this._program); + Texture.prototype.destroy = function() { + this._context._gl.deleteTexture(this._texture); return destroyObject(this); }; - return ShaderProgram; + return Texture; }); -define('Renderer/modernizeShader',[ - '../Core/defined', - '../Core/DeveloperError' - ], function( - defined, - DeveloperError) { +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Materials/BumpMapMaterial',[],function() { 'use strict'; - - /** - * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 3.00 - * - * This function is nowhere near comprehensive or complete. It just - * handles some common cases. - * - * Note that this function requires the presence of the - * "#define OUTPUT_DECLARATION" line that is appended - * by ShaderSource. - * - * @private - */ - function modernizeShader(source, isFragmentShader) { - var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; - var splitSource = source.split('\n'); - - if (/#version 300 es/g.test(source)) { - return source; - } - - var outputDeclarationLine = -1; - var i, line; - for (i = 0; i < splitSource.length; ++i) { - line = splitSource[i]; - if (outputDeclarationRegex.test(line)) { - outputDeclarationLine = i; - break; - } - } - - if (outputDeclarationLine === -1) { - throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION!'); - } - - var outputVariables = []; - - for (i = 0; i < 10; i++) { - var fragDataString = 'gl_FragData\\[' + i + '\\]'; - var newOutput = 'czm_out' + i; - var regex = new RegExp(fragDataString, 'g'); - if (regex.test(source)) { - setAdd(newOutput, outputVariables); - replaceInSourceString(fragDataString, newOutput, splitSource); - splitSource.splice(outputDeclarationLine, 0, 'layout(location = ' + i + ') out vec4 ' + newOutput + ';'); - outputDeclarationLine += 1; - } - } - - var czmFragColor = 'czm_fragColor'; - if (findInSource('gl_FragColor', splitSource)) { - setAdd(czmFragColor, outputVariables); - replaceInSourceString('gl_FragColor', czmFragColor, splitSource); - splitSource.splice(outputDeclarationLine, 0, 'layout(location = 0) out vec4 czm_fragColor;'); - outputDeclarationLine += 1; - } - - var variableMap = getVariablePreprocessorBranch(outputVariables, splitSource); - var lineAdds = {}; - for (i = 0; i < splitSource.length; i++) { - line = splitSource[i]; - for (var variable in variableMap) { - if (variableMap.hasOwnProperty(variable)) { - var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + variable + ')[^]+', 'g'); - if (matchVar.test(line)) { - lineAdds[line] = variable; - } - } - } - } - - for (var layoutDeclaration in lineAdds) { - if (lineAdds.hasOwnProperty(layoutDeclaration)) { - var variableName = lineAdds[layoutDeclaration]; - var lineNumber = splitSource.indexOf(layoutDeclaration); - var entry = variableMap[variableName]; - var depth = entry.length; - var d; - for (d = 0; d < depth; d++) { - splitSource.splice(lineNumber, 0, entry[d]); - } - lineNumber += depth + 1; - for (d = depth - 1; d >= 0; d--) { - splitSource.splice(lineNumber, 0, '#endif //' + entry[d]); - } - } - } - - var versionThree = '#version 300 es'; - var foundVersion = false; - for (i = 0; i < splitSource.length; i++) { - if (/#version/.test(splitSource[i])) { - splitSource[i] = versionThree; - foundVersion = true; - } - } - - if (!foundVersion) { - splitSource.splice(0, 0, versionThree); - } - - removeExtension('EXT_draw_buffers', splitSource); - removeExtension('EXT_frag_depth', splitSource); - - replaceInSourceString('texture2D', 'texture', splitSource); - replaceInSourceString('texture3D', 'texture', splitSource); - replaceInSourceString('textureCube', 'texture', splitSource); - replaceInSourceString('gl_FragDepthEXT', 'gl_FragDepth', splitSource); - - if (isFragmentShader) { - replaceInSourceString('varying', 'in', splitSource); - } else { - replaceInSourceString('attribute', 'in', splitSource); - replaceInSourceString('varying', 'out', splitSource); - } - - return compileSource(splitSource); - } - - // Note that this fails if your string looks like - // searchString[singleCharacter]searchString - function replaceInSourceString(str, replacement, splitSource) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - var regex = new RegExp(regexStr, 'g'); - - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - var line = splitSource[i]; - splitSource[i] = line.replace(regex, '$1' + replacement + '$3'); - } - } - - function replaceInSourceRegex(regex, replacement, splitSource) { - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - var line = splitSource[i]; - splitSource[i] = line.replace(regex, replacement); - } - } - - function findInSource(str, splitSource) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - var regex = new RegExp(regexStr, 'g'); - - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - var line = splitSource[i]; - if (regex.test(line)) { - return true; - } - } - return false; - } - - function compileSource(splitSource) { - var wholeSource = ''; - - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - wholeSource += splitSource[i] + '\n'; - } - return wholeSource; - } - - function setAdd(variable, set) { - if (set.indexOf(variable) === -1) { - set.push(variable); - } - } - - function getVariablePreprocessorBranch(layoutVariables, splitSource) { - var variableMap = {}; - - var numLayoutVariables = layoutVariables.length; - - var stack = []; - for (var i = 0; i < splitSource.length; ++i) { - var line = splitSource[i]; - var hasIF = /(#ifdef|#if)/g.test(line); - var hasELSE = /#else/g.test(line); - var hasENDIF = /#endif/g.test(line); - - if (hasIF) { - stack.push(line); - } else if (hasELSE) { - var top = stack[stack.length - 1]; - var op = top.replace('ifdef', 'ifndef'); - if (/if/g.test(op)) { - op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); - } - stack.pop(); - stack.push(op); - } else if (hasENDIF) { - stack.pop(); - } else if (!/layout/g.test(line)) { - for (var varIndex = 0; varIndex < numLayoutVariables; ++varIndex) { - var varName = layoutVariables[varIndex]; - if (line.indexOf(varName) !== -1) { - if (!defined(variableMap[varName])) { - variableMap[varName] = stack.slice(); - } else { - variableMap[varName] = variableMap[varName].filter(function(x) { - return stack.indexOf(x) >= 0; - }); - } - } - } - } - } - - return variableMap; - } - - function removeExtension(name, splitSource) { - var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; - replaceInSourceRegex(new RegExp(regex, 'g'), '', splitSource); - } - - return modernizeShader; -}); - -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/degreesPerRadian',[],function() { - 'use strict'; - return "const float czm_degreesPerRadian = 57.29577951308232;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/depthRange',[],function() { - 'use strict'; - return "const czm_depthRangeStruct czm_depthRange = czm_depthRangeStruct(0.0, 1.0);\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon1',[],function() { - 'use strict'; - return "const float czm_epsilon1 = 0.1;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon2',[],function() { - 'use strict'; - return "const float czm_epsilon2 = 0.01;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon3',[],function() { - 'use strict'; - return "const float czm_epsilon3 = 0.001;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon4',[],function() { - 'use strict'; - return "const float czm_epsilon4 = 0.0001;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon5',[],function() { - 'use strict'; - return "const float czm_epsilon5 = 0.00001;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon6',[],function() { - 'use strict'; - return "const float czm_epsilon6 = 0.000001;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/epsilon7',[],function() { - 'use strict'; - return "const float czm_epsilon7 = 0.0000001;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/infinity',[],function() { - 'use strict'; - return "const float czm_infinity = 5906376272000.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/maxClippingPlanes',[],function() { - 'use strict'; - return "const int czm_maxClippingPlanes = 6;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/oneOverPi',[],function() { - 'use strict'; - return "const float czm_oneOverPi = 0.3183098861837907;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/oneOverTwoPi',[],function() { - 'use strict'; - return "const float czm_oneOverTwoPi = 0.15915494309189535;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passCesium3DTile',[],function() { - 'use strict'; - return "const float czm_passCesium3DTile = 4.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passCesium3DTileClassification',[],function() { - 'use strict'; - return "const float czm_passCesium3DTileClassification = 5.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow',[],function() { - 'use strict'; - return "const float czm_passCesium3DTileClassificationIgnoreShow = 6.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passCompute',[],function() { - 'use strict'; - return "const float czm_passCompute = 1.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passEnvironment',[],function() { - 'use strict'; - return "const float czm_passEnvironment = 0.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passGlobe',[],function() { - 'use strict'; - return "const float czm_passGlobe = 2.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passOpaque',[],function() { - 'use strict'; - return "const float czm_passOpaque = 7.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passOverlay',[],function() { - 'use strict'; - return "const float czm_passOverlay = 9.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passTerrainClassification',[],function() { - 'use strict'; - return "const float czm_passTerrainClassification = 3.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/passTranslucent',[],function() { - 'use strict'; - return "const float czm_passTranslucent = 8.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/pi',[],function() { - 'use strict'; - return "const float czm_pi = 3.141592653589793;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/piOverFour',[],function() { - 'use strict'; - return "const float czm_piOverFour = 0.7853981633974483;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/piOverSix',[],function() { - 'use strict'; - return "const float czm_piOverSix = 0.5235987755982988;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/piOverThree',[],function() { - 'use strict'; - return "const float czm_piOverThree = 1.0471975511965976;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/piOverTwo',[],function() { - 'use strict'; - return "const float czm_piOverTwo = 1.5707963267948966;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/radiansPerDegree',[],function() { - 'use strict'; - return "const float czm_radiansPerDegree = 0.017453292519943295;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/sceneMode2D',[],function() { - 'use strict'; - return "const float czm_sceneMode2D = 2.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/sceneMode3D',[],function() { - 'use strict'; - return "const float czm_sceneMode3D = 3.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/sceneModeColumbusView',[],function() { - 'use strict'; - return "const float czm_sceneModeColumbusView = 1.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/sceneModeMorphing',[],function() { - 'use strict'; - return "const float czm_sceneModeMorphing = 0.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/solarRadius',[],function() { - 'use strict'; - return "const float czm_solarRadius = 695500000.0;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/threePiOver2',[],function() { - 'use strict'; - return "const float czm_threePiOver2 = 4.71238898038469;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/twoPi',[],function() { - 'use strict'; - return "const float czm_twoPi = 6.283185307179586;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Constants/webMercatorMaxLatitude',[],function() { - 'use strict'; - return "const float czm_webMercatorMaxLatitude = 1.4844222297453324;\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/depthRangeStruct',[],function() { - 'use strict'; - return "struct czm_depthRangeStruct\n\ -{\n\ -float near;\n\ -float far;\n\ -};\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/ellipsoid',[],function() { - 'use strict'; - return "struct czm_ellipsoid\n\ -{\n\ -vec3 center;\n\ -vec3 radii;\n\ -vec3 inverseRadii;\n\ -vec3 inverseRadiiSquared;\n\ -};\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/material',[],function() { - 'use strict'; - return "struct czm_material\n\ -{\n\ -vec3 diffuse;\n\ -float specular;\n\ -float shininess;\n\ -vec3 normal;\n\ -vec3 emission;\n\ -float alpha;\n\ -};\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/materialInput',[],function() { - 'use strict'; - return "struct czm_materialInput\n\ + return "uniform sampler2D image;\n\ +uniform float strength;\n\ +uniform vec2 repeat;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -float s;\n\ -vec2 st;\n\ -vec3 str;\n\ -vec3 normalEC;\n\ -mat3 tangentToEyeMatrix;\n\ -vec3 positionToEyeEC;\n\ -float height;\n\ -float slope;\n\ -};\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +vec2 centerPixel = fract(repeat * st);\n\ +float centerBump = texture2D(image, centerPixel).channel;\n\ +float imageWidth = float(imageDimensions.x);\n\ +vec2 rightPixel = fract(repeat * (st + vec2(1.0 / imageWidth, 0.0)));\n\ +float rightBump = texture2D(image, rightPixel).channel;\n\ +float imageHeight = float(imageDimensions.y);\n\ +vec2 leftPixel = fract(repeat * (st + vec2(0.0, 1.0 / imageHeight)));\n\ +float topBump = texture2D(image, leftPixel).channel;\n\ +vec3 normalTangentSpace = normalize(vec3(centerBump - rightBump, centerBump - topBump, clamp(1.0 - strength, 0.1, 1.0)));\n\ +vec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\n\ +material.normal = normalEC;\n\ +material.diffuse = vec3(0.01);\n\ +return material;\n\ +}\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/ray',[],function() { +define('Shaders/Materials/CheckerboardMaterial',[],function() { 'use strict'; - return "struct czm_ray\n\ + return "uniform vec4 lightColor;\n\ +uniform vec4 darkColor;\n\ +uniform vec2 repeat;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -vec3 origin;\n\ -vec3 direction;\n\ -};\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +float b = mod(floor(repeat.s * st.s) + floor(repeat.t * st.t), 2.0);\n\ +float scaledWidth = fract(repeat.s * st.s);\n\ +scaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\n\ +float scaledHeight = fract(repeat.t * st.t);\n\ +scaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\n\ +float value = min(scaledWidth, scaledHeight);\n\ +vec4 currentColor = mix(lightColor, darkColor, b);\n\ +vec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03);\n\ +material.diffuse = color.rgb;\n\ +material.alpha = color.a;\n\ +return material;\n\ +}\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/raySegment',[],function() { +define('Shaders/Materials/DotMaterial',[],function() { 'use strict'; - return "struct czm_raySegment\n\ + return "uniform vec4 lightColor;\n\ +uniform vec4 darkColor;\n\ +uniform vec2 repeat;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -float start;\n\ -float stop;\n\ -};\n\ -const czm_raySegment czm_emptyRaySegment = czm_raySegment(-czm_infinity, -czm_infinity);\n\ -const czm_raySegment czm_fullRaySegment = czm_raySegment(0.0, czm_infinity);\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +float b = smoothstep(0.3, 0.32, length(fract(repeat * materialInput.st) - 0.5));\n\ +vec4 color = mix(lightColor, darkColor, b);\n\ +material.diffuse = color.rgb;\n\ +material.alpha = color.a;\n\ +return material;\n\ +}\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Structs/shadowParameters',[],function() { +define('Shaders/Materials/ElevationContourMaterial',[],function() { 'use strict'; - return "struct czm_shadowParameters\n\ + return "#ifdef GL_OES_standard_derivatives\n\ +#extension GL_OES_standard_derivatives : enable\n\ +#endif\n\ +uniform vec4 color;\n\ +uniform float spacing;\n\ +uniform float width;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -#ifdef USE_CUBE_MAP_SHADOW\n\ -vec3 texCoords;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +float distanceToContour = mod(materialInput.height, spacing);\n\ +#ifdef GL_OES_standard_derivatives\n\ +float dxc = abs(dFdx(materialInput.height));\n\ +float dyc = abs(dFdy(materialInput.height));\n\ +float dF = max(dxc, dyc) * width;\n\ +material.alpha = (distanceToContour < dF) ? 1.0 : 0.0;\n\ #else\n\ -vec2 texCoords;\n\ +material.alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0;\n\ #endif\n\ -float depthBias;\n\ -float depth;\n\ -float nDotL;\n\ -vec2 texelStepSize;\n\ -float normalShadingSmooth;\n\ -float darkness;\n\ -};\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/alphaWeight',[],function() { - 'use strict'; - return "float czm_alphaWeight(float a)\n\ -{\n\ -float x = 2.0 * (gl_FragCoord.x - czm_viewport.x) / czm_viewport.z - 1.0;\n\ -float y = 2.0 * (gl_FragCoord.y - czm_viewport.y) / czm_viewport.w - 1.0;\n\ -float z = (gl_FragCoord.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\n\ -vec4 q = vec4(x, y, z, 0.0);\n\ -q /= gl_FragCoord.w;\n\ -if (czm_inverseProjection != mat4(0.0)) {\n\ -q = czm_inverseProjection * q;\n\ -} else {\n\ -float top = czm_frustumPlanes.x;\n\ -float bottom = czm_frustumPlanes.y;\n\ -float left = czm_frustumPlanes.z;\n\ -float right = czm_frustumPlanes.w;\n\ -float near = czm_currentFrustum.x;\n\ -float far = czm_currentFrustum.y;\n\ -q.x = (q.x * (right - left) + left + right) * 0.5;\n\ -q.y = (q.y * (top - bottom) + bottom + top) * 0.5;\n\ -q.z = (q.z * (near - far) - near - far) * 0.5;\n\ -q.w = 1.0;\n\ -}\n\ -return pow(a + 0.01, 4.0) + max(1e-2, min(3.0 * 1e3, 100.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0))));\n\ +material.diffuse = color.rgb;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/antialias',[],function() { +define('Shaders/Materials/ElevationRampMaterial',[],function() { 'use strict'; - return "vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist, float fuzzFactor)\n\ -{\n\ -float val1 = clamp(dist / fuzzFactor, 0.0, 1.0);\n\ -float val2 = clamp((dist - 0.5) / fuzzFactor, 0.0, 1.0);\n\ -val1 = val1 * (1.0 - val2);\n\ -val1 = val1 * val1 * (3.0 - (2.0 * val1));\n\ -val1 = pow(val1, 0.5);\n\ -vec4 midColor = (color1 + color2) * 0.5;\n\ -return mix(midColor, currentColor, val1);\n\ -}\n\ -vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist)\n\ + return "uniform sampler2D image;\n\ +uniform float minimumHeight;\n\ +uniform float maximumHeight;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -return czm_antialias(color1, color2, currentColor, dist, 0.1);\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +float scaledHeight = clamp((materialInput.height - minimumHeight) / (maximumHeight - minimumHeight), 0.0, 1.0);\n\ +vec4 rampColor = texture2D(image, vec2(scaledHeight, 0.5));\n\ +material.diffuse = rampColor.rgb;\n\ +material.alpha = rampColor.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/cascadeColor',[],function() { +define('Shaders/Materials/FadeMaterial',[],function() { 'use strict'; - return "vec4 czm_cascadeColor(vec4 weights)\n\ + return "uniform vec4 fadeInColor;\n\ +uniform vec4 fadeOutColor;\n\ +uniform float maximumDistance;\n\ +uniform bool repeat;\n\ +uniform vec2 fadeDirection;\n\ +uniform vec2 time;\n\ +float getTime(float t, float coord)\n\ {\n\ -return vec4(1.0, 0.0, 0.0, 1.0) * weights.x +\n\ -vec4(0.0, 1.0, 0.0, 1.0) * weights.y +\n\ -vec4(0.0, 0.0, 1.0, 1.0) * weights.z +\n\ -vec4(1.0, 0.0, 1.0, 1.0) * weights.w;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/cascadeDistance',[],function() { - 'use strict'; - return "uniform vec4 shadowMap_cascadeDistances;\n\ -float czm_cascadeDistance(vec4 weights)\n\ +float scalar = 1.0 / maximumDistance;\n\ +float q = distance(t, coord) * scalar;\n\ +if (repeat)\n\ {\n\ -return dot(shadowMap_cascadeDistances, weights);\n\ +float r = distance(t, coord + 1.0) * scalar;\n\ +float s = distance(t, coord - 1.0) * scalar;\n\ +q = min(min(r, s), q);\n\ }\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/cascadeMatrix',[],function() { - 'use strict'; - return "uniform mat4 shadowMap_cascadeMatrices[4];\n\ -mat4 czm_cascadeMatrix(vec4 weights)\n\ +return clamp(q, 0.0, 1.0);\n\ +}\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -return shadowMap_cascadeMatrices[0] * weights.x +\n\ -shadowMap_cascadeMatrices[1] * weights.y +\n\ -shadowMap_cascadeMatrices[2] * weights.z +\n\ -shadowMap_cascadeMatrices[3] * weights.w;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +float s = getTime(time.x, st.s) * fadeDirection.s;\n\ +float t = getTime(time.y, st.t) * fadeDirection.t;\n\ +float u = length(vec2(s, t));\n\ +vec4 color = mix(fadeInColor, fadeOutColor, u);\n\ +material.emission = color.rgb;\n\ +material.alpha = color.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/cascadeWeights',[],function() { +define('Shaders/Materials/GridMaterial',[],function() { 'use strict'; - return "uniform vec4 shadowMap_cascadeSplits[2];\n\ -vec4 czm_cascadeWeights(float depthEye)\n\ + return "#ifdef GL_OES_standard_derivatives\n\ +#extension GL_OES_standard_derivatives : enable\n\ +#endif\n\ +uniform vec4 color;\n\ +uniform float cellAlpha;\n\ +uniform vec2 lineCount;\n\ +uniform vec2 lineThickness;\n\ +uniform vec2 lineOffset;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -vec4 near = step(shadowMap_cascadeSplits[0], vec4(depthEye));\n\ -vec4 far = step(depthEye, shadowMap_cascadeSplits[1]);\n\ -return near * far;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +float scaledWidth = fract(lineCount.s * st.s - lineOffset.s);\n\ +scaledWidth = abs(scaledWidth - floor(scaledWidth + 0.5));\n\ +float scaledHeight = fract(lineCount.t * st.t - lineOffset.t);\n\ +scaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5));\n\ +float value;\n\ +#ifdef GL_OES_standard_derivatives\n\ +const float fuzz = 1.2;\n\ +vec2 thickness = (lineThickness * czm_resolutionScale) - 1.0;\n\ +vec2 dx = abs(dFdx(st));\n\ +vec2 dy = abs(dFdy(st));\n\ +vec2 dF = vec2(max(dx.s, dy.s), max(dx.t, dy.t)) * lineCount;\n\ +value = min(\n\ +smoothstep(dF.s * thickness.s, dF.s * (fuzz + thickness.s), scaledWidth),\n\ +smoothstep(dF.t * thickness.t, dF.t * (fuzz + thickness.t), scaledHeight));\n\ +#else\n\ +const float fuzz = 0.05;\n\ +vec2 range = 0.5 - (lineThickness * 0.05);\n\ +value = min(\n\ +1.0 - smoothstep(range.s, range.s + fuzz, scaledWidth),\n\ +1.0 - smoothstep(range.t, range.t + fuzz, scaledHeight));\n\ +#endif\n\ +float dRim = 1.0 - abs(dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC)));\n\ +float sRim = smoothstep(0.8, 1.0, dRim);\n\ +value *= (1.0 - sRim);\n\ +vec3 halfColor = color.rgb * 0.5;\n\ +material.diffuse = halfColor;\n\ +material.emission = halfColor;\n\ +material.alpha = color.a * (1.0 - ((1.0 - cellAlpha) * value));\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/columbusViewMorph',[],function() { +define('Shaders/Materials/NormalMapMaterial',[],function() { 'use strict'; - return "vec4 czm_columbusViewMorph(vec4 position2D, vec4 position3D, float time)\n\ + return "uniform sampler2D image;\n\ +uniform float strength;\n\ +uniform vec2 repeat;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -vec3 p = mix(position2D.xyz, position3D.xyz, time);\n\ -return vec4(p, 1.0);\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec4 textureValue = texture2D(image, fract(repeat * materialInput.st));\n\ +vec3 normalTangentSpace = textureValue.channels;\n\ +normalTangentSpace.xy = normalTangentSpace.xy * 2.0 - 1.0;\n\ +normalTangentSpace.z = clamp(1.0 - strength, 0.1, 1.0);\n\ +normalTangentSpace = normalize(normalTangentSpace);\n\ +vec3 normalEC = materialInput.tangentToEyeMatrix * normalTangentSpace;\n\ +material.normal = normalEC;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/computePosition',[],function() { - 'use strict'; - return "vec4 czm_computePosition();\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/cosineAndSine',[],function() { +define('Shaders/Materials/PolylineArrowMaterial',[],function() { 'use strict'; - return "vec2 cordic(float angle)\n\ + return "#ifdef GL_OES_standard_derivatives\n\ +#extension GL_OES_standard_derivatives : enable\n\ +#endif\n\ +uniform vec4 color;\n\ +varying float v_width;\n\ +float getPointOnLine(vec2 p0, vec2 p1, float x)\n\ {\n\ -vec2 vector = vec2(6.0725293500888267e-1, 0.0);\n\ -float sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -mat2 rotation = mat2(1.0, sense, -sense, 1.0);\n\ -vector = rotation * vector;\n\ -angle -= sense * 7.8539816339744828e-1;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -float factor = sense * 5.0e-1;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 4.6364760900080609e-1;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 2.5e-1;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 2.4497866312686414e-1;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.25e-1;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 1.2435499454676144e-1;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 6.25e-2;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 6.2418809995957350e-2;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 3.125e-2;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 3.1239833430268277e-2;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.5625e-2;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 1.5623728620476831e-2;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 7.8125e-3;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 7.8123410601011111e-3;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 3.90625e-3;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 3.9062301319669718e-3;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.953125e-3;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 1.9531225164788188e-3;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 9.765625e-4;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 9.7656218955931946e-4;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 4.8828125e-4;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 4.8828121119489829e-4;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 2.44140625e-4;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 2.4414062014936177e-4;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.220703125e-4;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 1.2207031189367021e-4;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 6.103515625e-5;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 6.1035156174208773e-5;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 3.0517578125e-5;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 3.0517578115526096e-5;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.52587890625e-5;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 1.5258789061315762e-5;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 7.62939453125e-6;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 7.6293945311019700e-6;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 3.814697265625e-6;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 3.8146972656064961e-6;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.9073486328125e-6;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 1.9073486328101870e-6;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 9.5367431640625e-7;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 9.5367431640596084e-7;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 4.76837158203125e-7;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 4.7683715820308884e-7;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 2.384185791015625e-7;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -angle -= sense * 2.3841857910155797e-7;\n\ -sense = (angle < 0.0) ? -1.0 : 1.0;\n\ -factor = sense * 1.1920928955078125e-7;\n\ -rotation[0][1] = factor;\n\ -rotation[1][0] = -factor;\n\ -vector = rotation * vector;\n\ -return vector;\n\ +float slope = (p0.y - p1.y) / (p0.x - p1.x);\n\ +return slope * (x - p0.x) + p0.y;\n\ }\n\ -vec2 czm_cosineAndSine(float angle)\n\ -{\n\ -if (angle < -czm_piOverTwo || angle > czm_piOverTwo)\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -if (angle < 0.0)\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +#ifdef GL_OES_standard_derivatives\n\ +float base = 1.0 - abs(fwidth(st.s)) * 10.0;\n\ +#else\n\ +float base = 0.99;\n\ +#endif\n\ +vec2 center = vec2(1.0, 0.5);\n\ +float ptOnUpperLine = getPointOnLine(vec2(base, 1.0), center, st.s);\n\ +float ptOnLowerLine = getPointOnLine(vec2(base, 0.0), center, st.s);\n\ +float halfWidth = 0.15;\n\ +float s = step(0.5 - halfWidth, st.t);\n\ +s *= 1.0 - step(0.5 + halfWidth, st.t);\n\ +s *= 1.0 - step(base, st.s);\n\ +float t = step(base, materialInput.st.s);\n\ +t *= 1.0 - step(ptOnUpperLine, st.t);\n\ +t *= step(ptOnLowerLine, st.t);\n\ +float dist;\n\ +if (st.s < base)\n\ {\n\ -return -cordic(angle + czm_pi);\n\ +float d1 = abs(st.t - (0.5 - halfWidth));\n\ +float d2 = abs(st.t - (0.5 + halfWidth));\n\ +dist = min(d1, d2);\n\ }\n\ else\n\ {\n\ -return -cordic(angle - czm_pi);\n\ -}\n\ -}\n\ -else\n\ +float d1 = czm_infinity;\n\ +if (st.t < 0.5 - halfWidth && st.t > 0.5 + halfWidth)\n\ {\n\ -return cordic(angle);\n\ +d1 = abs(st.s - base);\n\ }\n\ +float d2 = abs(st.t - ptOnUpperLine);\n\ +float d3 = abs(st.t - ptOnLowerLine);\n\ +dist = min(min(d1, d2), d3);\n\ }\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/decompressTextureCoordinates',[],function() { - 'use strict'; - return "vec2 czm_decompressTextureCoordinates(float encoded)\n\ -{\n\ -float temp = encoded / 4096.0;\n\ -float xZeroTo4095 = floor(temp);\n\ -float stx = xZeroTo4095 / 4095.0;\n\ -float sty = (encoded - xZeroTo4095 * 4096.0) / 4095.0;\n\ -return vec2(stx, sty);\n\ +vec4 outsideColor = vec4(0.0);\n\ +vec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0));\n\ +vec4 outColor = czm_antialias(outsideColor, color, currentColor, dist);\n\ +material.diffuse = outColor.rgb;\n\ +material.alpha = outColor.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/discardIfClippedWithIntersect',[],function() { +define('Shaders/Materials/PolylineDashMaterial',[],function() { 'use strict'; - return "float czm_discardIfClippedWithIntersect(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n\ -{\n\ -if (clippingPlanesLength > 0)\n\ -{\n\ -bool clipped = true;\n\ -vec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\n\ -vec3 clipNormal = vec3(0.0);\n\ -vec3 clipPosition = vec3(0.0);\n\ -float clipAmount = 0.0;\n\ -float pixelWidth = czm_metersPerPixel(position);\n\ -for (int i = 0; i < czm_maxClippingPlanes; ++i)\n\ -{\n\ -if (i == clippingPlanesLength)\n\ -{\n\ -break;\n\ -}\n\ -clipNormal = clippingPlanes[i].xyz;\n\ -clipPosition = -clippingPlanes[i].w * clipNormal;\n\ -float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n\ -clipAmount = max(amount, clipAmount);\n\ -clipped = clipped && (amount <= 0.0);\n\ + return "uniform vec4 color;\n\ +uniform vec4 gapColor;\n\ +uniform float dashLength;\n\ +uniform float dashPattern;\n\ +varying float v_polylineAngle;\n\ +const float maskLength = 16.0;\n\ +mat2 rotate(float rad) {\n\ +float c = cos(rad);\n\ +float s = sin(rad);\n\ +return mat2(\n\ +c, s,\n\ +-s, c\n\ +);\n\ }\n\ -if (clipped)\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 pos = rotate(v_polylineAngle) * gl_FragCoord.xy;\n\ +float dashPosition = fract(pos.x / dashLength);\n\ +float maskIndex = floor(dashPosition * maskLength);\n\ +float maskTest = floor(dashPattern / pow(2.0, maskIndex));\n\ +vec4 fragColor = (mod(maskTest, 2.0) < 1.0) ? gapColor : color;\n\ +if (fragColor.a < 0.005) {\n\ discard;\n\ }\n\ -return clipAmount;\n\ -}\n\ -return 0.0;\n\ +material.emission = fragColor.rgb;\n\ +material.alpha = fragColor.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/discardIfClippedWithUnion',[],function() { +define('Shaders/Materials/PolylineGlowMaterial',[],function() { 'use strict'; - return "float czm_discardIfClippedWithUnion(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n\ -{\n\ -if (clippingPlanesLength > 0)\n\ -{\n\ -vec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\n\ -vec3 clipNormal = vec3(0.0);\n\ -vec3 clipPosition = vec3(0.0);\n\ -float clipAmount = 0.0;\n\ -float pixelWidth = czm_metersPerPixel(position);\n\ -for (int i = 0; i < czm_maxClippingPlanes; ++i)\n\ -{\n\ -if (i == clippingPlanesLength)\n\ -{\n\ -break;\n\ -}\n\ -clipNormal = clippingPlanes[i].xyz;\n\ -clipPosition = -clippingPlanes[i].w * clipNormal;\n\ -float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n\ -clipAmount = max(amount, clipAmount);\n\ -if (amount <= 0.0)\n\ + return "uniform vec4 color;\n\ +uniform float glowPower;\n\ +varying float v_width;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -discard;\n\ -}\n\ -}\n\ -return clipAmount;\n\ -}\n\ -return 0.0;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +float glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5);\n\ +material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb);\n\ +material.alpha = clamp(0.0, 1.0, glow) * color.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates',[],function() { +define('Shaders/Materials/PolylineOutlineMaterial',[],function() { 'use strict'; - return "mat3 czm_eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)\n\ + return "uniform vec4 color;\n\ +uniform vec4 outlineColor;\n\ +uniform float outlineWidth;\n\ +varying float v_width;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -vec3 tangentMC = normalize(vec3(-positionMC.y, positionMC.x, 0.0));\n\ -vec3 tangentEC = normalize(czm_normal3D * tangentMC);\n\ -vec3 bitangentEC = normalize(cross(normalEC, tangentEC));\n\ -return mat3(\n\ -tangentEC.x, tangentEC.y, tangentEC.z,\n\ -bitangentEC.x, bitangentEC.y, bitangentEC.z,\n\ -normalEC.x, normalEC.y, normalEC.z);\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec2 st = materialInput.st;\n\ +float halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width;\n\ +float b = step(0.5 - halfInteriorWidth, st.t);\n\ +b *= 1.0 - step(0.5 + halfInteriorWidth, st.t);\n\ +float d1 = abs(st.t - (0.5 - halfInteriorWidth));\n\ +float d2 = abs(st.t - (0.5 + halfInteriorWidth));\n\ +float dist = min(d1, d2);\n\ +vec4 currentColor = mix(outlineColor, color, b);\n\ +vec4 outColor = czm_antialias(outlineColor, color, currentColor, dist);\n\ +material.diffuse = outColor.rgb;\n\ +material.alpha = outColor.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/ellipsoidContainsPoint',[],function() { +define('Shaders/Materials/RimLightingMaterial',[],function() { 'use strict'; - return "bool czm_ellipsoidContainsPoint(czm_ellipsoid ellipsoid, vec3 point)\n\ + return "uniform vec4 color;\n\ +uniform vec4 rimColor;\n\ +uniform float width;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -vec3 scaled = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(point, 1.0)).xyz;\n\ -return (dot(scaled, scaled) <= 1.0);\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +float d = 1.0 - dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC));\n\ +float s = smoothstep(1.0 - width, 1.0, d);\n\ +material.diffuse = color.rgb;\n\ +material.emission = rimColor.rgb * s;\n\ +material.alpha = mix(color.a, rimColor.a, s);\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/ellipsoidNew',[],function() { +define('Shaders/Materials/SlopeRampMaterial',[],function() { 'use strict'; - return "czm_ellipsoid czm_ellipsoidNew(vec3 center, vec3 radii)\n\ + return "uniform sampler2D image;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -vec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\n\ -vec3 inverseRadiiSquared = inverseRadii * inverseRadii;\n\ -czm_ellipsoid temp = czm_ellipsoid(center, radii, inverseRadii, inverseRadiiSquared);\n\ -return temp;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +vec4 rampColor = texture2D(image, vec2(materialInput.slope, 0.5));\n\ +material.diffuse = rampColor.rgb;\n\ +material.alpha = rampColor.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates',[],function() { +define('Shaders/Materials/StripeMaterial',[],function() { 'use strict'; - return "vec2 czm_ellipsoidWgs84TextureCoordinates(vec3 normal)\n\ + return "uniform vec4 evenColor;\n\ +uniform vec4 oddColor;\n\ +uniform float offset;\n\ +uniform float repeat;\n\ +uniform bool horizontal;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -return vec2(atan(normal.y, normal.x) * czm_oneOverTwoPi + 0.5, asin(normal.z) * czm_oneOverPi + 0.5);\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +float coord = mix(materialInput.st.s, materialInput.st.t, float(horizontal));\n\ +float value = fract((coord - offset) * (repeat * 0.5));\n\ +float dist = min(value, min(abs(value - 0.5), 1.0 - value));\n\ +vec4 currentColor = mix(evenColor, oddColor, step(0.5, value));\n\ +vec4 color = czm_antialias(evenColor, oddColor, currentColor, dist);\n\ +material.diffuse = color.rgb;\n\ +material.alpha = color.a;\n\ +return material;\n\ }\n\ "; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/equalsEpsilon',[],function() { +define('Shaders/Materials/Water',[],function() { 'use strict'; - return "bool czm_equalsEpsilon(vec4 left, vec4 right, float epsilon) {\n\ -return all(lessThanEqual(abs(left - right), vec4(epsilon)));\n\ -}\n\ -bool czm_equalsEpsilon(vec3 left, vec3 right, float epsilon) {\n\ -return all(lessThanEqual(abs(left - right), vec3(epsilon)));\n\ -}\n\ -bool czm_equalsEpsilon(vec2 left, vec2 right, float epsilon) {\n\ -return all(lessThanEqual(abs(left - right), vec2(epsilon)));\n\ -}\n\ -bool czm_equalsEpsilon(float left, float right, float epsilon) {\n\ -return (abs(left - right) <= epsilon);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/eyeOffset',[],function() { - 'use strict'; - return "vec4 czm_eyeOffset(vec4 positionEC, vec3 eyeOffset)\n\ -{\n\ -vec4 p = positionEC;\n\ -vec4 zEyeOffset = normalize(p) * eyeOffset.z;\n\ -p.xy += eyeOffset.xy + zEyeOffset.xy;\n\ -p.z += zEyeOffset.z;\n\ -return p;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/eyeToWindowCoordinates',[],function() { - 'use strict'; - return "vec4 czm_eyeToWindowCoordinates(vec4 positionEC)\n\ -{\n\ -vec4 q = czm_projection * positionEC;\n\ -q.xyz /= q.w;\n\ -q.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\n\ -return q;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/fog',[],function() { - 'use strict'; - return "vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor)\n\ -{\n\ -float scalar = distanceToCamera * czm_fogDensity;\n\ -float fog = 1.0 - exp(-(scalar * scalar));\n\ -return mix(color, fogColor, fog);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/geodeticSurfaceNormal',[],function() { - 'use strict'; - return "vec3 czm_geodeticSurfaceNormal(vec3 positionOnEllipsoid, vec3 ellipsoidCenter, vec3 oneOverEllipsoidRadiiSquared)\n\ -{\n\ -return normalize((positionOnEllipsoid - ellipsoidCenter) * oneOverEllipsoidRadiiSquared);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/getDefaultMaterial',[],function() { - 'use strict'; - return "czm_material czm_getDefaultMaterial(czm_materialInput materialInput)\n\ + return "uniform sampler2D specularMap;\n\ +uniform sampler2D normalMap;\n\ +uniform vec4 baseWaterColor;\n\ +uniform vec4 blendColor;\n\ +uniform float frequency;\n\ +uniform float animationSpeed;\n\ +uniform float amplitude;\n\ +uniform float specularIntensity;\n\ +uniform float fadeFactor;\n\ +czm_material czm_getMaterial(czm_materialInput materialInput)\n\ {\n\ -czm_material material;\n\ -material.diffuse = vec3(0.0);\n\ -material.specular = 0.0;\n\ -material.shininess = 1.0;\n\ -material.normal = materialInput.normalEC;\n\ -material.emission = vec3(0.0);\n\ -material.alpha = 1.0;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +float time = czm_frameNumber * animationSpeed;\n\ +float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);\n\ +float specularMapValue = texture2D(specularMap, materialInput.st).r;\n\ +vec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);\n\ +vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));\n\ +normalTangentSpace.xy /= fade;\n\ +normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);\n\ +normalTangentSpace = normalize(normalTangentSpace);\n\ +float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);\n\ +material.alpha = specularMapValue;\n\ +material.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);\n\ +material.diffuse += (0.1 * tsPerturbationRatio);\n\ +material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);\n\ +material.specular = specularIntensity;\n\ +material.shininess = 10.0;\n\ return material;\n\ }\n\ "; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/getLambertDiffuse',[],function() { - 'use strict'; - return "float czm_getLambertDiffuse(vec3 lightDirectionEC, vec3 normalEC)\n\ -{\n\ -return max(dot(lightDirectionEC, normalEC), 0.0);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/getSpecular',[],function() { - 'use strict'; - return "float czm_getSpecular(vec3 lightDirectionEC, vec3 toEyeEC, vec3 normalEC, float shininess)\n\ -{\n\ -vec3 toReflectedLight = reflect(-lightDirectionEC, normalEC);\n\ -float specular = max(dot(toReflectedLight, toEyeEC), 0.0);\n\ -return pow(specular, max(shininess, czm_epsilon2));\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/getWaterNoise',[],function() { - 'use strict'; - return "vec4 czm_getWaterNoise(sampler2D normalMap, vec2 uv, float time, float angleInRadians)\n\ -{\n\ -float cosAngle = cos(angleInRadians);\n\ -float sinAngle = sin(angleInRadians);\n\ -vec2 s0 = vec2(1.0/17.0, 0.0);\n\ -vec2 s1 = vec2(-1.0/29.0, 0.0);\n\ -vec2 s2 = vec2(1.0/101.0, 1.0/59.0);\n\ -vec2 s3 = vec2(-1.0/109.0, -1.0/57.0);\n\ -s0 = vec2((cosAngle * s0.x) - (sinAngle * s0.y), (sinAngle * s0.x) + (cosAngle * s0.y));\n\ -s1 = vec2((cosAngle * s1.x) - (sinAngle * s1.y), (sinAngle * s1.x) + (cosAngle * s1.y));\n\ -s2 = vec2((cosAngle * s2.x) - (sinAngle * s2.y), (sinAngle * s2.x) + (cosAngle * s2.y));\n\ -s3 = vec2((cosAngle * s3.x) - (sinAngle * s3.y), (sinAngle * s3.x) + (cosAngle * s3.y));\n\ -vec2 uv0 = (uv/103.0) + (time * s0);\n\ -vec2 uv1 = uv/107.0 + (time * s1) + vec2(0.23);\n\ -vec2 uv2 = uv/vec2(897.0, 983.0) + (time * s2) + vec2(0.51);\n\ -vec2 uv3 = uv/vec2(991.0, 877.0) + (time * s3) + vec2(0.71);\n\ -uv0 = fract(uv0);\n\ -uv1 = fract(uv1);\n\ -uv2 = fract(uv2);\n\ -uv3 = fract(uv3);\n\ -vec4 noise = (texture2D(normalMap, uv0)) +\n\ -(texture2D(normalMap, uv1)) +\n\ -(texture2D(normalMap, uv2)) +\n\ -(texture2D(normalMap, uv3));\n\ -return ((noise / 4.0) - 0.5) * 2.0;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/getWgs84EllipsoidEC',[],function() { - 'use strict'; - return "czm_ellipsoid czm_getWgs84EllipsoidEC()\n\ -{\n\ -vec3 radii = vec3(6378137.0, 6378137.0, 6356752.314245);\n\ -vec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\n\ -vec3 inverseRadiiSquared = inverseRadii * inverseRadii;\n\ -czm_ellipsoid temp = czm_ellipsoid(czm_view[3].xyz, radii, inverseRadii, inverseRadiiSquared);\n\ -return temp;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/HSBToRGB',[],function() { - 'use strict'; - return "const vec4 K_HSB2RGB = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n\ -vec3 czm_HSBToRGB(vec3 hsb)\n\ -{\n\ -vec3 p = abs(fract(hsb.xxx + K_HSB2RGB.xyz) * 6.0 - K_HSB2RGB.www);\n\ -return hsb.z * mix(K_HSB2RGB.xxx, clamp(p - K_HSB2RGB.xxx, 0.0, 1.0), hsb.y);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/HSLToRGB',[],function() { - 'use strict'; - return "vec3 hueToRGB(float hue)\n\ -{\n\ -float r = abs(hue * 6.0 - 3.0) - 1.0;\n\ -float g = 2.0 - abs(hue * 6.0 - 2.0);\n\ -float b = 2.0 - abs(hue * 6.0 - 4.0);\n\ -return clamp(vec3(r, g, b), 0.0, 1.0);\n\ -}\n\ -vec3 czm_HSLToRGB(vec3 hsl)\n\ -{\n\ -vec3 rgb = hueToRGB(hsl.x);\n\ -float c = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;\n\ -return (rgb - 0.5) * c + hsl.z;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/hue',[],function() { - 'use strict'; - return "vec3 czm_hue(vec3 rgb, float adjustment)\n\ -{\n\ -const mat3 toYIQ = mat3(0.299, 0.587, 0.114,\n\ -0.595716, -0.274453, -0.321263,\n\ -0.211456, -0.522591, 0.311135);\n\ -const mat3 toRGB = mat3(1.0, 0.9563, 0.6210,\n\ -1.0, -0.2721, -0.6474,\n\ -1.0, -1.107, 1.7046);\n\ -vec3 yiq = toYIQ * rgb;\n\ -float hue = atan(yiq.z, yiq.y) + adjustment;\n\ -float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);\n\ -vec3 color = vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));\n\ -return toRGB * color;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/isEmpty',[],function() { - 'use strict'; - return "bool czm_isEmpty(czm_raySegment interval)\n\ -{\n\ -return (interval.stop < 0.0);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/isFull',[],function() { - 'use strict'; - return "bool czm_isFull(czm_raySegment interval)\n\ -{\n\ -return (interval.start == 0.0 && interval.stop == czm_infinity);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/latitudeToWebMercatorFraction',[],function() { - 'use strict'; - return "float czm_latitudeToWebMercatorFraction(float latitude, float southMercatorY, float oneOverMercatorHeight)\n\ -{\n\ -float sinLatitude = sin(latitude);\n\ -float mercatorY = 0.5 * log((1.0 + sinLatitude) / (1.0 - sinLatitude));\n\ -return (mercatorY - southMercatorY) * oneOverMercatorHeight;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/luminance',[],function() { - 'use strict'; - return "float czm_luminance(vec3 rgb)\n\ -{\n\ -const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n\ -return dot(rgb, W);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/metersPerPixel',[],function() { - 'use strict'; - return "float czm_metersPerPixel(vec4 positionEC)\n\ -{\n\ -float width = czm_viewport.z;\n\ -float height = czm_viewport.w;\n\ -float pixelWidth;\n\ -float pixelHeight;\n\ -float top = czm_frustumPlanes.x;\n\ -float bottom = czm_frustumPlanes.y;\n\ -float left = czm_frustumPlanes.z;\n\ -float right = czm_frustumPlanes.w;\n\ -if (czm_sceneMode == czm_sceneMode2D)\n\ -{\n\ -float frustumWidth = right - left;\n\ -float frustumHeight = top - bottom;\n\ -pixelWidth = frustumWidth / width;\n\ -pixelHeight = frustumHeight / height;\n\ -}\n\ -else\n\ -{\n\ -float distanceToPixel = -positionEC.z;\n\ -float inverseNear = 1.0 / czm_currentFrustum.x;\n\ -float tanTheta = top * inverseNear;\n\ -pixelHeight = 2.0 * distanceToPixel * tanTheta / height;\n\ -tanTheta = right * inverseNear;\n\ -pixelWidth = 2.0 * distanceToPixel * tanTheta / width;\n\ -}\n\ -return max(pixelWidth, pixelHeight);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/modelToWindowCoordinates',[],function() { - 'use strict'; - return "vec4 czm_modelToWindowCoordinates(vec4 position)\n\ -{\n\ -vec4 q = czm_modelViewProjection * position;\n\ -q.xyz /= q.w;\n\ -q.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\n\ -return q;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/multiplyWithColorBalance',[],function() { - 'use strict'; - return "vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right)\n\ -{\n\ -const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n\ -vec3 target = left * right;\n\ -float leftLuminance = dot(left, W);\n\ -float rightLuminance = dot(right, W);\n\ -float targetLuminance = dot(target, W);\n\ -return ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/nearFarScalar',[],function() { +define('Scene/Material',[ + '../Core/Cartesian2', + '../Core/clone', + '../Core/Color', + '../Core/combine', + '../Core/createGuid', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/isArray', + '../Core/loadCRN', + '../Core/loadKTX', + '../Core/Matrix2', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/Resource', + '../Renderer/CubeMap', + '../Renderer/Texture', + '../Shaders/Materials/BumpMapMaterial', + '../Shaders/Materials/CheckerboardMaterial', + '../Shaders/Materials/DotMaterial', + '../Shaders/Materials/ElevationContourMaterial', + '../Shaders/Materials/ElevationRampMaterial', + '../Shaders/Materials/FadeMaterial', + '../Shaders/Materials/GridMaterial', + '../Shaders/Materials/NormalMapMaterial', + '../Shaders/Materials/PolylineArrowMaterial', + '../Shaders/Materials/PolylineDashMaterial', + '../Shaders/Materials/PolylineGlowMaterial', + '../Shaders/Materials/PolylineOutlineMaterial', + '../Shaders/Materials/RimLightingMaterial', + '../Shaders/Materials/SlopeRampMaterial', + '../Shaders/Materials/StripeMaterial', + '../Shaders/Materials/Water', + '../ThirdParty/when' + ], function( + Cartesian2, + clone, + Color, + combine, + createGuid, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + isArray, + loadCRN, + loadKTX, + Matrix2, + Matrix3, + Matrix4, + Resource, + CubeMap, + Texture, + BumpMapMaterial, + CheckerboardMaterial, + DotMaterial, + ElevationContourMaterial, + ElevationRampMaterial, + FadeMaterial, + GridMaterial, + NormalMapMaterial, + PolylineArrowMaterial, + PolylineDashMaterial, + PolylineGlowMaterial, + PolylineOutlineMaterial, + RimLightingMaterial, + SlopeRampMaterial, + StripeMaterial, + WaterMaterial, + when) { 'use strict'; - return "float czm_nearFarScalar(vec4 nearFarScalar, float cameraDistSq)\n\ -{\n\ -float valueAtMin = nearFarScalar.y;\n\ -float valueAtMax = nearFarScalar.w;\n\ -float nearDistanceSq = nearFarScalar.x * nearFarScalar.x;\n\ -float farDistanceSq = nearFarScalar.z * nearFarScalar.z;\n\ -float t = (cameraDistSq - nearDistanceSq) / (farDistanceSq - nearDistanceSq);\n\ -t = pow(clamp(t, 0.0, 1.0), 0.2);\n\ -return mix(valueAtMin, valueAtMax, t);\n\ -}\n\ -"; + + /** + * A Material defines surface appearance through a combination of diffuse, specular, + * normal, emission, and alpha components. These values are specified using a + * JSON schema called Fabric which gets parsed and assembled into glsl shader code + * behind-the-scenes. Check out the {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|wiki page} + * for more details on Fabric. + * <br /><br /> + * <style type="text/css"> + * #materialDescriptions code { + * font-weight: normal; + * font-family: Consolas, 'Lucida Console', Monaco, monospace; + * color: #A35A00; + * } + * #materialDescriptions ul, #materialDescriptions ul ul { + * list-style-type: none; + * } + * #materialDescriptions ul ul { + * margin-bottom: 10px; + * } + * #materialDescriptions ul ul li { + * font-weight: normal; + * color: #000000; + * text-indent: -2em; + * margin-left: 2em; + * } + * #materialDescriptions ul li { + * font-weight: bold; + * color: #0053CF; + * } + * </style> + * + * Base material types and their uniforms: + * <div id='materialDescriptions'> + * <ul> + * <li>Color</li> + * <ul> + * <li><code>color</code>: rgba color object.</li> + * </ul> + * <li>Image</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * </ul> + * <li>DiffuseMap</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>channels</code>: Three character string containing any combination of r, g, b, and a for selecting the desired image channels.</li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * </ul> + * <li>AlphaMap</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>channel</code>: One character string containing r, g, b, or a for selecting the desired image channel. </li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * </ul> + * <li>SpecularMap</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>channel</code>: One character string containing r, g, b, or a for selecting the desired image channel. </li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * </ul> + * <li>EmissionMap</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>channels</code>: Three character string containing any combination of r, g, b, and a for selecting the desired image channels. </li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * </ul> + * <li>BumpMap</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>channel</code>: One character string containing r, g, b, or a for selecting the desired image channel. </li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * <li><code>strength</code>: Bump strength value between 0.0 and 1.0 where 0.0 is small bumps and 1.0 is large bumps.</li> + * </ul> + * <li>NormalMap</li> + * <ul> + * <li><code>image</code>: path to image.</li> + * <li><code>channels</code>: Three character string containing any combination of r, g, b, and a for selecting the desired image channels. </li> + * <li><code>repeat</code>: Object with x and y values specifying the number of times to repeat the image.</li> + * <li><code>strength</code>: Bump strength value between 0.0 and 1.0 where 0.0 is small bumps and 1.0 is large bumps.</li> + * </ul> + * <li>Grid</li> + * <ul> + * <li><code>color</code>: rgba color object for the whole material.</li> + * <li><code>cellAlpha</code>: Alpha value for the cells between grid lines. This will be combined with color.alpha.</li> + * <li><code>lineCount</code>: Object with x and y values specifying the number of columns and rows respectively.</li> + * <li><code>lineThickness</code>: Object with x and y values specifying the thickness of grid lines (in pixels where available).</li> + * <li><code>lineOffset</code>: Object with x and y values specifying the offset of grid lines (range is 0 to 1).</li> + * </ul> + * <li>Stripe</li> + * <ul> + * <li><code>horizontal</code>: Boolean that determines if the stripes are horizontal or vertical.</li> + * <li><code>evenColor</code>: rgba color object for the stripe's first color.</li> + * <li><code>oddColor</code>: rgba color object for the stripe's second color.</li> + * <li><code>offset</code>: Number that controls at which point into the pattern to begin drawing; with 0.0 being the beginning of the even color, 1.0 the beginning of the odd color, 2.0 being the even color again, and any multiple or fractional values being in between.</li> + * <li><code>repeat</code>: Number that controls the total number of stripes, half light and half dark.</li> + * </ul> + * <li>Checkerboard</li> + * <ul> + * <li><code>lightColor</code>: rgba color object for the checkerboard's light alternating color.</li> + * <li><code>darkColor</code>: rgba color object for the checkerboard's dark alternating color.</li> + * <li><code>repeat</code>: Object with x and y values specifying the number of columns and rows respectively.</li> + * </ul> + * <li>Dot</li> + * <ul> + * <li><code>lightColor</code>: rgba color object for the dot color.</li> + * <li><code>darkColor</code>: rgba color object for the background color.</li> + * <li><code>repeat</code>: Object with x and y values specifying the number of columns and rows of dots respectively.</li> + * </ul> + * <li>Water</li> + * <ul> + * <li><code>baseWaterColor</code>: rgba color object base color of the water.</li> + * <li><code>blendColor</code>: rgba color object used when blending from water to non-water areas.</li> + * <li><code>specularMap</code>: Single channel texture used to indicate areas of water.</li> + * <li><code>normalMap</code>: Normal map for water normal perturbation.</li> + * <li><code>frequency</code>: Number that controls the number of waves.</li> + * <li><code>normalMap</code>: Normal map for water normal perturbation.</li> + * <li><code>animationSpeed</code>: Number that controls the animations speed of the water.</li> + * <li><code>amplitude</code>: Number that controls the amplitude of water waves.</li> + * <li><code>specularIntensity</code>: Number that controls the intensity of specular reflections.</li> + * </ul> + * <li>RimLighting</li> + * <ul> + * <li><code>color</code>: diffuse color and alpha.</li> + * <li><code>rimColor</code>: diffuse color and alpha of the rim.</li> + * <li><code>width</code>: Number that determines the rim's width.</li> + * </ul> + * <li>Fade</li> + * <ul> + * <li><code>fadeInColor</code>: diffuse color and alpha at <code>time</code></li> + * <li><code>fadeOutColor</code>: diffuse color and alpha at <code>maximumDistance</code> from <code>time</code></li> + * <li><code>maximumDistance</code>: Number between 0.0 and 1.0 where the <code>fadeInColor</code> becomes the <code>fadeOutColor</code>. A value of 0.0 gives the entire material a color of <code>fadeOutColor</code> and a value of 1.0 gives the the entire material a color of <code>fadeInColor</code></li> + * <li><code>repeat</code>: true if the fade should wrap around the texture coodinates.</li> + * <li><code>fadeDirection</code>: Object with x and y values specifying if the fade should be in the x and y directions.</li> + * <li><code>time</code>: Object with x and y values between 0.0 and 1.0 of the <code>fadeInColor</code> position</li> + * </ul> + * <li>PolylineArrow</li> + * <ul> + * <li><code>color</code>: diffuse color and alpha.</li> + * </ul> + * <li>PolylineDash</li> + * <ul> + * <li><code>color</code>: color for the line.</li> + * <li><code>gapColor</code>: color for the gaps in the line.</li> + * <li><code>dashLength</code>: Dash length in pixels.</li> + * <li><code>dashPattern</code>: The 16 bit stipple pattern for the line..</li> + * </ul> + * <li>PolylineGlow</li> + * <ul> + * <li><code>color</code>: color and maximum alpha for the glow on the line.</li> + * <li><code>glowPower</code>: strength of the glow, as a percentage of the total line width (less than 1.0).</li> + * </ul> + * <li>PolylineOutline</li> + * <ul> + * <li><code>color</code>: diffuse color and alpha for the interior of the line.</li> + * <li><code>outlineColor</code>: diffuse color and alpha for the outline.</li> + * <li><code>outlineWidth</code>: width of the outline in pixels.</li> + * </ul> + * <li>ElevationContour</li> + * <ul> + * <li><code>color</code>: color and alpha for the contour line.</li> + * <li><code>spacing</code>: spacing for contour lines in meters.</li> + * <li><code>width</code>: Number specifying the width of the grid lines in pixels.</li> + * </ul> + * <li>ElevationRamp</li> + * <ul> + * <li><code>image</code>: color ramp image to use for coloring the terrain.</li> + * <li><code>minimumHeight</code>: minimum height for the ramp.</li> + * <li><code>maximumHeight</code>: maximum height for the ramp.</li> + * </ul> + * <li>SlopeRamp</li> + * <ul> + * <li><code>image</code>: color ramp image to use for coloring the terrain.</li> + * </ul> + * </ul> + * </ul> + * </div> + * + * @alias Material + * + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. + * @param {Boolean|Function} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry + * with this material is expected to appear translucent. + * @param {Object} options.fabric The fabric JSON used to generate the material. + * + * @constructor + * + * @exception {DeveloperError} fabric: uniform has invalid type. + * @exception {DeveloperError} fabric: uniforms and materials cannot share the same property. + * @exception {DeveloperError} fabric: cannot have source and components in the same section. + * @exception {DeveloperError} fabric: property name is not valid. It should be 'type', 'materials', 'uniforms', 'components', or 'source'. + * @exception {DeveloperError} fabric: property name is not valid. It should be 'diffuse', 'specular', 'shininess', 'normal', 'emission', or 'alpha'. + * @exception {DeveloperError} strict: shader source does not use string. + * @exception {DeveloperError} strict: shader source does not use uniform. + * @exception {DeveloperError} strict: shader source does not use material. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric wiki page} for a more detailed options of Fabric. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Materials.html|Cesium Sandcastle Materials Demo} + * + * @example + * // Create a color material with fromType: + * polygon.material = Cesium.Material.fromType('Color'); + * polygon.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); + * + * // Create the default material: + * polygon.material = new Cesium.Material(); + * + * // Create a color material with full Fabric notation: + * polygon.material = new Cesium.Material({ + * fabric : { + * type : 'Color', + * uniforms : { + * color : new Cesium.Color(1.0, 1.0, 0.0, 1.0) + * } + * } + * }); + */ + function Material(options) { + /** + * The material type. Can be an existing type or a new type. If no type is specified in fabric, type is a GUID. + * @type {String} + * @default undefined + */ + this.type = undefined; + + /** + * The glsl shader source for this material. + * @type {String} + * @default undefined + */ + this.shaderSource = undefined; + + /** + * Maps sub-material names to Material objects. + * @type {Object} + * @default undefined + */ + this.materials = undefined; + + /** + * Maps uniform names to their values. + * @type {Object} + * @default undefined + */ + this.uniforms = undefined; + this._uniforms = undefined; + + /** + * When <code>true</code> or a function that returns <code>true</code>, + * the geometry is expected to appear translucent. + * @type {Boolean|Function} + * @default undefined + */ + this.translucent = undefined; + + this._strict = undefined; + this._template = undefined; + this._count = undefined; + + this._texturePaths = {}; + this._loadedImages = []; + this._loadedCubeMaps = []; + + this._textures = {}; + + this._updateFunctions = []; + + this._defaultTexture = undefined; + + initializeMaterial(options, this); + defineProperties(this, { + type : { + value : this.type, + writable : false + } + }); + + if (!defined(Material._uniformList[this.type])) { + Material._uniformList[this.type] = Object.keys(this._uniforms); + } + } + + // Cached list of combined uniform names indexed by type. + // Used to get the list of uniforms in the same order. + Material._uniformList = {}; + + /** + * Creates a new material using an existing material type. + * <br /><br /> + * Shorthand for: new Material({fabric : {type : type}}); + * + * @param {String} type The base material type. + * @param {Object} [uniforms] Overrides for the default uniforms. + * @returns {Material} New material object. + * + * @exception {DeveloperError} material with that type does not exist. + * + * @example + * var material = Cesium.Material.fromType('Color', { + * color : new Cesium.Color(1.0, 0.0, 0.0, 1.0) + * }); + */ + Material.fromType = function(type, uniforms) { + if (!defined(Material._materialCache.getMaterial(type))) { + throw new DeveloperError('material with type \'' + type + '\' does not exist.'); + } + + var material = new Material({ + fabric : { + type : type + } + }); + + if (defined(uniforms)) { + for (var name in uniforms) { + if (uniforms.hasOwnProperty(name)) { + material.uniforms[name] = uniforms[name]; + } + } + } + + return material; + }; + + /** + * Gets whether or not this material is translucent. + * @returns <code>true</code> if this material is translucent, <code>false</code> otherwise. + */ + Material.prototype.isTranslucent = function() { + if (defined(this.translucent)) { + if (typeof this.translucent === 'function') { + return this.translucent(); + } + + return this.translucent; + } + + var translucent = true; + var funcs = this._translucentFunctions; + var length = funcs.length; + for (var i = 0; i < length; ++i) { + var func = funcs[i]; + if (typeof func === 'function') { + translucent = translucent && func(); + } else { + translucent = translucent && func; + } + + if (!translucent) { + break; + } + } + return translucent; + }; + + /** + * @private + */ + Material.prototype.update = function(context) { + var i; + var uniformId; + + var loadedImages = this._loadedImages; + var length = loadedImages.length; + + for (i = 0; i < length; ++i) { + var loadedImage = loadedImages[i]; + uniformId = loadedImage.id; + var image = loadedImage.image; + + var texture; + if (defined(image.internalFormat)) { + texture = new Texture({ + context : context, + pixelFormat : image.internalFormat, + width : image.width, + height : image.height, + source : { + arrayBufferView : image.bufferView + } + }); + } else { + texture = new Texture({ + context : context, + source : image + }); + } + + this._textures[uniformId] = texture; + + var uniformDimensionsName = uniformId + 'Dimensions'; + if (this.uniforms.hasOwnProperty(uniformDimensionsName)) { + var uniformDimensions = this.uniforms[uniformDimensionsName]; + uniformDimensions.x = texture._width; + uniformDimensions.y = texture._height; + } + } + + loadedImages.length = 0; + + var loadedCubeMaps = this._loadedCubeMaps; + length = loadedCubeMaps.length; + + for (i = 0; i < length; ++i) { + var loadedCubeMap = loadedCubeMaps[i]; + uniformId = loadedCubeMap.id; + var images = loadedCubeMap.images; + + var cubeMap = new CubeMap({ + context : context, + source : { + positiveX : images[0], + negativeX : images[1], + positiveY : images[2], + negativeY : images[3], + positiveZ : images[4], + negativeZ : images[5] + } + }); + + this._textures[uniformId] = cubeMap; + } + + loadedCubeMaps.length = 0; + + var updateFunctions = this._updateFunctions; + length = updateFunctions.length; + for (i = 0; i < length; ++i) { + updateFunctions[i](this, context); + } + + var subMaterials = this.materials; + for (var name in subMaterials) { + if (subMaterials.hasOwnProperty(name)) { + subMaterials[name].update(context); + } + } + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see Material#destroy + */ + Material.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * material = material && material.destroy(); + * + * @see Material#isDestroyed + */ + Material.prototype.destroy = function() { + var textures = this._textures; + for ( var texture in textures) { + if (textures.hasOwnProperty(texture)) { + var instance = textures[texture]; + if (instance !== this._defaultTexture) { + instance.destroy(); + } + } + } + + var materials = this.materials; + for ( var material in materials) { + if (materials.hasOwnProperty(material)) { + materials[material].destroy(); + } + } + return destroyObject(this); + }; + + function initializeMaterial(options, result) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + result._strict = defaultValue(options.strict, false); + result._count = defaultValue(options.count, 0); + result._template = clone(defaultValue(options.fabric, defaultValue.EMPTY_OBJECT)); + result._template.uniforms = clone(defaultValue(result._template.uniforms, defaultValue.EMPTY_OBJECT)); + result._template.materials = clone(defaultValue(result._template.materials, defaultValue.EMPTY_OBJECT)); + + result.type = defined(result._template.type) ? result._template.type : createGuid(); + + result.shaderSource = ''; + result.materials = {}; + result.uniforms = {}; + result._uniforms = {}; + result._translucentFunctions = []; + + var translucent; + + // If the cache contains this material type, build the material template off of the stored template. + var cachedMaterial = Material._materialCache.getMaterial(result.type); + if (defined(cachedMaterial)) { + var template = clone(cachedMaterial.fabric, true); + result._template = combine(result._template, template, true); + translucent = cachedMaterial.translucent; + } + + // Make sure the template has no obvious errors. More error checking happens later. + checkForTemplateErrors(result); + + // If the material has a new type, add it to the cache. + if (!defined(cachedMaterial)) { + Material._materialCache.addMaterial(result.type, result); + } + + createMethodDefinition(result); + createUniforms(result); + createSubMaterials(result); + + var defaultTranslucent = result._translucentFunctions.length === 0 ? true : undefined; + translucent = defaultValue(translucent, defaultTranslucent); + translucent = defaultValue(options.translucent, translucent); + + if (defined(translucent)) { + if (typeof translucent === 'function') { + var wrappedTranslucent = function() { + return translucent(result); + }; + result._translucentFunctions.push(wrappedTranslucent); + } else { + result._translucentFunctions.push(translucent); + } + + } + } + + function checkForValidProperties(object, properties, result, throwNotFound) { + if (defined(object)) { + for ( var property in object) { + if (object.hasOwnProperty(property)) { + var hasProperty = properties.indexOf(property) !== -1; + if ((throwNotFound && !hasProperty) || (!throwNotFound && hasProperty)) { + result(property, properties); + } + } + } + } + } + + function invalidNameError(property, properties) { + var errorString = 'fabric: property name \'' + property + '\' is not valid. It should be '; + for ( var i = 0; i < properties.length; i++) { + var propertyName = '\'' + properties[i] + '\''; + errorString += (i === properties.length - 1) ? ('or ' + propertyName + '.') : (propertyName + ', '); + } + throw new DeveloperError(errorString); + } + + function duplicateNameError(property, properties) { + var errorString = 'fabric: uniforms and materials cannot share the same property \'' + property + '\''; + throw new DeveloperError(errorString); + } + + var templateProperties = ['type', 'materials', 'uniforms', 'components', 'source']; + var componentProperties = ['diffuse', 'specular', 'shininess', 'normal', 'emission', 'alpha']; + + function checkForTemplateErrors(material) { + var template = material._template; + var uniforms = template.uniforms; + var materials = template.materials; + var components = template.components; + + // Make sure source and components do not exist in the same template. + if (defined(components) && defined(template.source)) { + throw new DeveloperError('fabric: cannot have source and components in the same template.'); + } + + // Make sure all template and components properties are valid. + checkForValidProperties(template, templateProperties, invalidNameError, true); + checkForValidProperties(components, componentProperties, invalidNameError, true); + + // Make sure uniforms and materials do not share any of the same names. + var materialNames = []; + for ( var property in materials) { + if (materials.hasOwnProperty(property)) { + materialNames.push(property); + } + } + checkForValidProperties(uniforms, materialNames, duplicateNameError, false); + } + + // Create the czm_getMaterial method body using source or components. + function createMethodDefinition(material) { + var components = material._template.components; + var source = material._template.source; + if (defined(source)) { + material.shaderSource += source + '\n'; + } else { + material.shaderSource += 'czm_material czm_getMaterial(czm_materialInput materialInput)\n{\n'; + material.shaderSource += 'czm_material material = czm_getDefaultMaterial(materialInput);\n'; + if (defined(components)) { + for ( var component in components) { + if (components.hasOwnProperty(component)) { + material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; + } + } + } + material.shaderSource += 'return material;\n}\n'; + } + } + + var matrixMap = { + 'mat2' : Matrix2, + 'mat3' : Matrix3, + 'mat4' : Matrix4 + }; + + var ktxRegex = /\.ktx$/i; + var crnRegex = /\.crn$/i; + + function createTexture2DUpdateFunction(uniformId) { + var oldUniformValue; + return function(material, context) { + var uniforms = material.uniforms; + var uniformValue = uniforms[uniformId]; + var uniformChanged = oldUniformValue !== uniformValue; + oldUniformValue = uniformValue; + var texture = material._textures[uniformId]; + + var uniformDimensionsName; + var uniformDimensions; + + if (uniformValue instanceof HTMLVideoElement) { + // HTMLVideoElement.readyState >=2 means we have enough data for the current frame. + // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState + if (uniformValue.readyState >= 2) { + if (uniformChanged && defined(texture)) { + if (texture !== context.defaultTexture) { + texture.destroy(); + } + texture = undefined; + } + + if (!defined(texture) || texture === context.defaultTexture) { + texture = new Texture({ + context : context, + source : uniformValue + }); + material._textures[uniformId] = texture; + return; + } + + texture.copyFrom(uniformValue); + } else if (!defined(texture)) { + material._textures[uniformId] = context.defaultTexture; + } + return; + } + + if (uniformValue instanceof Texture && uniformValue !== texture) { + material._texturePaths[uniformId] = undefined; + var tmp = material._textures[uniformId]; + if (tmp !== material._defaultTexture) { + tmp.destroy(); + } + material._textures[uniformId] = uniformValue; + + uniformDimensionsName = uniformId + 'Dimensions'; + if (uniforms.hasOwnProperty(uniformDimensionsName)) { + uniformDimensions = uniforms[uniformDimensionsName]; + uniformDimensions.x = uniformValue._width; + uniformDimensions.y = uniformValue._height; + } + + return; + } + + if (!defined(texture)) { + material._texturePaths[uniformId] = undefined; + if (!defined(material._defaultTexture)) { + material._defaultTexture = context.defaultTexture; + } + texture = material._textures[uniformId] = material._defaultTexture; + + uniformDimensionsName = uniformId + 'Dimensions'; + if (uniforms.hasOwnProperty(uniformDimensionsName)) { + uniformDimensions = uniforms[uniformDimensionsName]; + uniformDimensions.x = texture._width; + uniformDimensions.y = texture._height; + } + } + + if (uniformValue === Material.DefaultImageId) { + return; + } + + if (uniformValue !== material._texturePaths[uniformId]) { + if (typeof uniformValue === 'string') { + var resource = new Resource({ + url: uniformValue + }); + var promise; + if (ktxRegex.test(uniformValue)) { + promise = loadKTX(resource); + } else if (crnRegex.test(uniformValue)) { + promise = loadCRN(resource); + } else { + promise = resource.fetchImage(); + } + when(promise, function(image) { + material._loadedImages.push({ + id : uniformId, + image : image + }); + }); + } else if (uniformValue instanceof HTMLCanvasElement) { + material._loadedImages.push({ + id : uniformId, + image : uniformValue + }); + } + + material._texturePaths[uniformId] = uniformValue; + } + }; + } + + function createCubeMapUpdateFunction(uniformId) { + return function(material, context) { + var uniformValue = material.uniforms[uniformId]; + + if (uniformValue instanceof CubeMap) { + var tmp = material._textures[uniformId]; + if (tmp !== material._defaultTexture) { + tmp.destroy(); + } + material._texturePaths[uniformId] = undefined; + material._textures[uniformId] = uniformValue; + return; + } + + if (!defined(material._textures[uniformId])) { + material._texturePaths[uniformId] = undefined; + material._textures[uniformId] = context.defaultCubeMap; + } + + if (uniformValue === Material.DefaultCubeMapId) { + return; + } + + var path = + uniformValue.positiveX + uniformValue.negativeX + + uniformValue.positiveY + uniformValue.negativeY + + uniformValue.positiveZ + uniformValue.negativeZ; + + if (path !== material._texturePaths[uniformId]) { + var promises = [ + Resource.createIfNeeded(uniformValue.positiveX).fetchImage(), + Resource.createIfNeeded(uniformValue.negativeX).fetchImage(), + Resource.createIfNeeded(uniformValue.positiveY).fetchImage(), + Resource.createIfNeeded(uniformValue.negativeY).fetchImage(), + Resource.createIfNeeded(uniformValue.positiveZ).fetchImage(), + Resource.createIfNeeded(uniformValue.negativeZ).fetchImage() + ]; + + when.all(promises).then(function(images) { + material._loadedCubeMaps.push({ + id : uniformId, + images : images + }); + }); + + material._texturePaths[uniformId] = path; + } + }; + } + + function createUniforms(material) { + var uniforms = material._template.uniforms; + for ( var uniformId in uniforms) { + if (uniforms.hasOwnProperty(uniformId)) { + createUniform(material, uniformId); + } + } + } + + // Writes uniform declarations to the shader file and connects uniform values with + // corresponding material properties through the returnUniforms function. + function createUniform(material, uniformId) { + var strict = material._strict; + var materialUniforms = material._template.uniforms; + var uniformValue = materialUniforms[uniformId]; + var uniformType = getUniformType(uniformValue); + + if (!defined(uniformType)) { + throw new DeveloperError('fabric: uniform \'' + uniformId + '\' has invalid type.'); + } + + var replacedTokenCount; + if (uniformType === 'channels') { + replacedTokenCount = replaceToken(material, uniformId, uniformValue, false); + if (replacedTokenCount === 0 && strict) { + throw new DeveloperError('strict: shader source does not use channels \'' + uniformId + '\'.'); + } + } else { + // Since webgl doesn't allow texture dimension queries in glsl, create a uniform to do it. + // Check if the shader source actually uses texture dimensions before creating the uniform. + if (uniformType === 'sampler2D') { + var imageDimensionsUniformName = uniformId + 'Dimensions'; + if (getNumberOfTokens(material, imageDimensionsUniformName) > 0) { + materialUniforms[imageDimensionsUniformName] = { + type : 'ivec3', + x : 1, + y : 1 + }; + createUniform(material, imageDimensionsUniformName); + } + } + + // Add uniform declaration to source code. + var uniformDeclarationRegex = new RegExp('uniform\\s+' + uniformType + '\\s+' + uniformId + '\\s*;'); + if (!uniformDeclarationRegex.test(material.shaderSource)) { + var uniformDeclaration = 'uniform ' + uniformType + ' ' + uniformId + ';'; + material.shaderSource = uniformDeclaration + material.shaderSource; + } + + var newUniformId = uniformId + '_' + material._count++; + replacedTokenCount = replaceToken(material, uniformId, newUniformId); + if (replacedTokenCount === 1 && strict) { + throw new DeveloperError('strict: shader source does not use uniform \'' + uniformId + '\'.'); + } + + // Set uniform value + material.uniforms[uniformId] = uniformValue; + + if (uniformType === 'sampler2D') { + material._uniforms[newUniformId] = function() { + return material._textures[uniformId]; + }; + material._updateFunctions.push(createTexture2DUpdateFunction(uniformId)); + } else if (uniformType === 'samplerCube') { + material._uniforms[newUniformId] = function() { + return material._textures[uniformId]; + }; + material._updateFunctions.push(createCubeMapUpdateFunction(uniformId)); + } else if (uniformType.indexOf('mat') !== -1) { + var scratchMatrix = new matrixMap[uniformType](); + material._uniforms[newUniformId] = function() { + return matrixMap[uniformType].fromColumnMajorArray(material.uniforms[uniformId], scratchMatrix); + }; + } else { + material._uniforms[newUniformId] = function() { + return material.uniforms[uniformId]; + }; + } + } + } + + // Determines the uniform type based on the uniform in the template. + function getUniformType(uniformValue) { + var uniformType = uniformValue.type; + if (!defined(uniformType)) { + var type = typeof uniformValue; + if (type === 'number') { + uniformType = 'float'; + } else if (type === 'boolean') { + uniformType = 'bool'; + } else if (type === 'string' || uniformValue instanceof HTMLCanvasElement) { + if (/^([rgba]){1,4}$/i.test(uniformValue)) { + uniformType = 'channels'; + } else if (uniformValue === Material.DefaultCubeMapId) { + uniformType = 'samplerCube'; + } else { + uniformType = 'sampler2D'; + } + } else if (type === 'object') { + if (isArray(uniformValue)) { + if (uniformValue.length === 4 || uniformValue.length === 9 || uniformValue.length === 16) { + uniformType = 'mat' + Math.sqrt(uniformValue.length); + } + } else { + var numAttributes = 0; + for ( var attribute in uniformValue) { + if (uniformValue.hasOwnProperty(attribute)) { + numAttributes += 1; + } + } + if (numAttributes >= 2 && numAttributes <= 4) { + uniformType = 'vec' + numAttributes; + } else if (numAttributes === 6) { + uniformType = 'samplerCube'; + } + } + } + } + return uniformType; + } + + // Create all sub-materials by combining source and uniforms together. + function createSubMaterials(material) { + var strict = material._strict; + var subMaterialTemplates = material._template.materials; + for ( var subMaterialId in subMaterialTemplates) { + if (subMaterialTemplates.hasOwnProperty(subMaterialId)) { + // Construct the sub-material. + var subMaterial = new Material({ + strict : strict, + fabric : subMaterialTemplates[subMaterialId], + count : material._count + }); + + material._count = subMaterial._count; + material._uniforms = combine(material._uniforms, subMaterial._uniforms, true); + material.materials[subMaterialId] = subMaterial; + material._translucentFunctions = material._translucentFunctions.concat(subMaterial._translucentFunctions); + + // Make the material's czm_getMaterial unique by appending the sub-material type. + var originalMethodName = 'czm_getMaterial'; + var newMethodName = originalMethodName + '_' + material._count++; + replaceToken(subMaterial, originalMethodName, newMethodName); + material.shaderSource = subMaterial.shaderSource + material.shaderSource; + + // Replace each material id with an czm_getMaterial method call. + var materialMethodCall = newMethodName + '(materialInput)'; + var tokensReplacedCount = replaceToken(material, subMaterialId, materialMethodCall); + if (tokensReplacedCount === 0 && strict) { + throw new DeveloperError('strict: shader source does not use material \'' + subMaterialId + '\'.'); + } + } + } + } + + // Used for searching or replacing a token in a material's shader source with something else. + // If excludePeriod is true, do not accept tokens that are preceded by periods. + // http://stackoverflow.com/questions/641407/javascript-negative-lookbehind-equivalent + function replaceToken(material, token, newToken, excludePeriod) { + excludePeriod = defaultValue(excludePeriod, true); + var count = 0; + var suffixChars = '([\\w])?'; + var prefixChars = '([\\w' + (excludePeriod ? '.' : '') + '])?'; + var regExp = new RegExp(prefixChars + token + suffixChars, 'g'); + material.shaderSource = material.shaderSource.replace(regExp, function($0, $1, $2) { + if ($1 || $2) { + return $0; + } + count += 1; + return newToken; + }); + return count; + } + + function getNumberOfTokens(material, token, excludePeriod) { + return replaceToken(material, token, token, excludePeriod); + } + + Material._materialCache = { + _materials : {}, + addMaterial : function(type, materialTemplate) { + this._materials[type] = materialTemplate; + }, + getMaterial : function(type) { + return this._materials[type]; + } + }; + + /** + * Gets or sets the default texture uniform value. + * @type {String} + */ + Material.DefaultImageId = 'czm_defaultImage'; + + /** + * Gets or sets the default cube map texture uniform value. + * @type {String} + */ + Material.DefaultCubeMapId = 'czm_defaultCubeMap'; + + /** + * Gets the name of the color material. + * @type {String} + * @readonly + */ + Material.ColorType = 'Color'; + Material._materialCache.addMaterial(Material.ColorType, { + fabric : { + type : Material.ColorType, + uniforms : { + color : new Color(1.0, 0.0, 0.0, 0.5) + }, + components : { + diffuse : 'color.rgb', + alpha : 'color.a' + } + }, + translucent : function(material) { + return material.uniforms.color.alpha < 1.0; + } + }); + + /** + * Gets the name of the image material. + * @type {String} + * @readonly + */ + Material.ImageType = 'Image'; + Material._materialCache.addMaterial(Material.ImageType, { + fabric : { + type : Material.ImageType, + uniforms : { + image : Material.DefaultImageId, + repeat : new Cartesian2(1.0, 1.0), + color: new Color(1.0, 1.0, 1.0, 1.0) + }, + components : { + diffuse : 'texture2D(image, fract(repeat * materialInput.st)).rgb * color.rgb', + alpha : 'texture2D(image, fract(repeat * materialInput.st)).a * color.a' + } + }, + translucent : function(material) { + return material.uniforms.color.alpha < 1.0; + } + }); + + /** + * Gets the name of the diffuce map material. + * @type {String} + * @readonly + */ + Material.DiffuseMapType = 'DiffuseMap'; + Material._materialCache.addMaterial(Material.DiffuseMapType, { + fabric : { + type : Material.DiffuseMapType, + uniforms : { + image : Material.DefaultImageId, + channels : 'rgb', + repeat : new Cartesian2(1.0, 1.0) + }, + components : { + diffuse : 'texture2D(image, fract(repeat * materialInput.st)).channels' + } + }, + translucent : false + }); + + /** + * Gets the name of the alpha map material. + * @type {String} + * @readonly + */ + Material.AlphaMapType = 'AlphaMap'; + Material._materialCache.addMaterial(Material.AlphaMapType, { + fabric : { + type : Material.AlphaMapType, + uniforms : { + image : Material.DefaultImageId, + channel : 'a', + repeat : new Cartesian2(1.0, 1.0) + }, + components : { + alpha : 'texture2D(image, fract(repeat * materialInput.st)).channel' + } + }, + translucent : true + }); + + /** + * Gets the name of the specular map material. + * @type {String} + * @readonly + */ + Material.SpecularMapType = 'SpecularMap'; + Material._materialCache.addMaterial(Material.SpecularMapType, { + fabric : { + type : Material.SpecularMapType, + uniforms : { + image : Material.DefaultImageId, + channel : 'r', + repeat : new Cartesian2(1.0, 1.0) + }, + components : { + specular : 'texture2D(image, fract(repeat * materialInput.st)).channel' + } + }, + translucent : false + }); + + /** + * Gets the name of the emmision map material. + * @type {String} + * @readonly + */ + Material.EmissionMapType = 'EmissionMap'; + Material._materialCache.addMaterial(Material.EmissionMapType, { + fabric : { + type : Material.EmissionMapType, + uniforms : { + image : Material.DefaultImageId, + channels : 'rgb', + repeat : new Cartesian2(1.0, 1.0) + }, + components : { + emission : 'texture2D(image, fract(repeat * materialInput.st)).channels' + } + }, + translucent : false + }); + + /** + * Gets the name of the bump map material. + * @type {String} + * @readonly + */ + Material.BumpMapType = 'BumpMap'; + Material._materialCache.addMaterial(Material.BumpMapType, { + fabric : { + type : Material.BumpMapType, + uniforms : { + image : Material.DefaultImageId, + channel : 'r', + strength : 0.8, + repeat : new Cartesian2(1.0, 1.0) + }, + source : BumpMapMaterial + }, + translucent : false + }); + + /** + * Gets the name of the normal map material. + * @type {String} + * @readonly + */ + Material.NormalMapType = 'NormalMap'; + Material._materialCache.addMaterial(Material.NormalMapType, { + fabric : { + type : Material.NormalMapType, + uniforms : { + image : Material.DefaultImageId, + channels : 'rgb', + strength : 0.8, + repeat : new Cartesian2(1.0, 1.0) + }, + source : NormalMapMaterial + }, + translucent : false + }); + + /** + * Gets the name of the grid material. + * @type {String} + * @readonly + */ + Material.GridType = 'Grid'; + Material._materialCache.addMaterial(Material.GridType, { + fabric : { + type : Material.GridType, + uniforms : { + color : new Color(0.0, 1.0, 0.0, 1.0), + cellAlpha : 0.1, + lineCount : new Cartesian2(8.0, 8.0), + lineThickness : new Cartesian2(1.0, 1.0), + lineOffset : new Cartesian2(0.0, 0.0) + }, + source : GridMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.color.alpha < 1.0) || (uniforms.cellAlpha < 1.0); + } + }); + + /** + * Gets the name of the stripe material. + * @type {String} + * @readonly + */ + Material.StripeType = 'Stripe'; + Material._materialCache.addMaterial(Material.StripeType, { + fabric : { + type : Material.StripeType, + uniforms : { + horizontal : true, + evenColor : new Color(1.0, 1.0, 1.0, 0.5), + oddColor : new Color(0.0, 0.0, 1.0, 0.5), + offset : 0.0, + repeat : 5.0 + }, + source : StripeMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.evenColor.alpha < 1.0) || (uniforms.oddColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the checkerboard material. + * @type {String} + * @readonly + */ + Material.CheckerboardType = 'Checkerboard'; + Material._materialCache.addMaterial(Material.CheckerboardType, { + fabric : { + type : Material.CheckerboardType, + uniforms : { + lightColor : new Color(1.0, 1.0, 1.0, 0.5), + darkColor : new Color(0.0, 0.0, 0.0, 0.5), + repeat : new Cartesian2(5.0, 5.0) + }, + source : CheckerboardMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.lightColor.alpha < 1.0) || (uniforms.darkColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the dot material. + * @type {String} + * @readonly + */ + Material.DotType = 'Dot'; + Material._materialCache.addMaterial(Material.DotType, { + fabric : { + type : Material.DotType, + uniforms : { + lightColor : new Color(1.0, 1.0, 0.0, 0.75), + darkColor : new Color(0.0, 1.0, 1.0, 0.75), + repeat : new Cartesian2(5.0, 5.0) + }, + source : DotMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.lightColor.alpha < 1.0) || (uniforms.darkColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the water material. + * @type {String} + * @readonly + */ + Material.WaterType = 'Water'; + Material._materialCache.addMaterial(Material.WaterType, { + fabric : { + type : Material.WaterType, + uniforms : { + baseWaterColor : new Color(0.2, 0.3, 0.6, 1.0), + blendColor : new Color(0.0, 1.0, 0.699, 1.0), + specularMap : Material.DefaultImageId, + normalMap : Material.DefaultImageId, + frequency : 10.0, + animationSpeed : 0.01, + amplitude : 1.0, + specularIntensity : 0.5, + fadeFactor : 1.0 + }, + source : WaterMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.baseWaterColor.alpha < 1.0) || (uniforms.blendColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the rim lighting material. + * @type {String} + * @readonly + */ + Material.RimLightingType = 'RimLighting'; + Material._materialCache.addMaterial(Material.RimLightingType, { + fabric : { + type : Material.RimLightingType, + uniforms : { + color : new Color(1.0, 0.0, 0.0, 0.7), + rimColor : new Color(1.0, 1.0, 1.0, 0.4), + width : 0.3 + }, + source : RimLightingMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.color.alpha < 1.0) || (uniforms.rimColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the fade material. + * @type {String} + * @readonly + */ + Material.FadeType = 'Fade'; + Material._materialCache.addMaterial(Material.FadeType, { + fabric : { + type : Material.FadeType, + uniforms : { + fadeInColor : new Color(1.0, 0.0, 0.0, 1.0), + fadeOutColor : new Color(0.0, 0.0, 0.0, 0.0), + maximumDistance : 0.5, + repeat : true, + fadeDirection : { + x : true, + y : true + }, + time : new Cartesian2(0.5, 0.5) + }, + source : FadeMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.fadeInColor.alpha < 1.0) || (uniforms.fadeOutColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the polyline arrow material. + * @type {String} + * @readonly + */ + Material.PolylineArrowType = 'PolylineArrow'; + Material._materialCache.addMaterial(Material.PolylineArrowType, { + fabric : { + type : Material.PolylineArrowType, + uniforms : { + color : new Color(1.0, 1.0, 1.0, 1.0) + }, + source : PolylineArrowMaterial + }, + translucent : true + }); + + /** + * Gets the name of the polyline glow material. + * @type {String} + * @readonly + */ + Material.PolylineDashType = 'PolylineDash'; + Material._materialCache.addMaterial(Material.PolylineDashType, { + fabric : { + type : Material.PolylineDashType, + uniforms : { + color : new Color(1.0, 0.0, 1.0, 1.0), + gapColor : new Color(0.0, 0.0, 0.0, 0.0), + dashLength : 16.0, + dashPattern : 255.0 + }, + source : PolylineDashMaterial + }, + translucent : true + }); + + /** + * Gets the name of the polyline glow material. + * @type {String} + * @readonly + */ + Material.PolylineGlowType = 'PolylineGlow'; + Material._materialCache.addMaterial(Material.PolylineGlowType, { + fabric : { + type : Material.PolylineGlowType, + uniforms : { + color : new Color(0.0, 0.5, 1.0, 1.0), + glowPower : 0.25 + }, + source : PolylineGlowMaterial + }, + translucent : true + }); + + /** + * Gets the name of the polyline outline material. + * @type {String} + * @readonly + */ + Material.PolylineOutlineType = 'PolylineOutline'; + Material._materialCache.addMaterial(Material.PolylineOutlineType, { + fabric : { + type : Material.PolylineOutlineType, + uniforms : { + color : new Color(1.0, 1.0, 1.0, 1.0), + outlineColor : new Color(1.0, 0.0, 0.0, 1.0), + outlineWidth : 1.0 + }, + source : PolylineOutlineMaterial + }, + translucent : function(material) { + var uniforms = material.uniforms; + return (uniforms.color.alpha < 1.0) || (uniforms.outlineColor.alpha < 1.0); + } + }); + + /** + * Gets the name of the elevation contour material. + * @type {String} + * @readonly + */ + Material.ElevationContourType = 'ElevationContour'; + Material._materialCache.addMaterial(Material.ElevationContourType, { + fabric : { + type : Material.ElevationContourType, + uniforms : { + spacing: 100.0, + color: new Color(1.0, 0.0, 0.0, 1.0), + width: 1.0 + }, + source : ElevationContourMaterial + }, + translucent : false + }); + + /** + * Gets the name of the elevation contour material. + * @type {String} + * @readonly + */ + Material.ElevationRampType = 'ElevationRamp'; + Material._materialCache.addMaterial(Material.ElevationRampType, { + fabric : { + type : Material.ElevationRampType, + uniforms : { + image: Material.DefaultImageId, + minimumHeight: 0.0, + maximumHeight: 10000.0 + }, + source : ElevationRampMaterial + }, + translucent : false + }); + + /** + * Gets the name of the slope ramp material. + * @type {String} + * @readonly + */ + Material.SlopeRampMaterialType = 'SlopeRamp'; + Material._materialCache.addMaterial(Material.SlopeRampMaterialType, { + fabric : { + type : Material.SlopeRampMaterialType, + uniforms : { + image: Material.DefaultImageId + }, + source : SlopeRampMaterial + }, + translucent : false + }); + + return Material; +}); + +define('Scene/MaterialAppearance',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/freezeObject', + '../Core/VertexFormat', + '../Shaders/Appearances/AllMaterialAppearanceFS', + '../Shaders/Appearances/AllMaterialAppearanceVS', + '../Shaders/Appearances/BasicMaterialAppearanceFS', + '../Shaders/Appearances/BasicMaterialAppearanceVS', + '../Shaders/Appearances/TexturedMaterialAppearanceFS', + '../Shaders/Appearances/TexturedMaterialAppearanceVS', + './Appearance', + './Material' + ], function( + defaultValue, + defined, + defineProperties, + freezeObject, + VertexFormat, + AllMaterialAppearanceFS, + AllMaterialAppearanceVS, + BasicMaterialAppearanceFS, + BasicMaterialAppearanceVS, + TexturedMaterialAppearanceFS, + TexturedMaterialAppearanceVS, + Appearance, + Material) { + 'use strict'; + + /** + * An appearance for arbitrary geometry (as opposed to {@link EllipsoidSurfaceAppearance}, for example) + * that supports shading with materials. + * + * @alias MaterialAppearance + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. + * @param {Boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. + * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link MaterialAppearance#renderState} has alpha blending enabled. + * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link MaterialAppearance#renderState} has backface culling enabled. + * @param {MaterialAppearance.MaterialSupport} [options.materialSupport=MaterialAppearance.MaterialSupport.TEXTURED] The type of materials that will be supported. + * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. + * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {RenderState} [options.renderState] Optional render state to override the default render state. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Materials.html|Cesium Sandcastle Material Appearance Demo} + * + * @example + * var primitive = new Cesium.Primitive({ + * geometryInstances : new Cesium.GeometryInstance({ + * geometry : new Cesium.WallGeometry({ + materialSupport : Cesium.MaterialAppearance.MaterialSupport.BASIC.vertexFormat, + * // ... + * }) + * }), + * appearance : new Cesium.MaterialAppearance({ + * material : Cesium.Material.fromType('Color'), + * faceForward : true + * }) + * + * }); + */ + function MaterialAppearance(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var translucent = defaultValue(options.translucent, true); + var closed = defaultValue(options.closed, false); + var materialSupport = defaultValue(options.materialSupport, MaterialAppearance.MaterialSupport.TEXTURED); + + /** + * The material used to determine the fragment color. Unlike other {@link MaterialAppearance} + * properties, this is not read-only, so an appearance's material can change on the fly. + * + * @type Material + * + * @default {@link Material.ColorType} + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + */ + this.material = (defined(options.material)) ? options.material : Material.fromType(Material.ColorType); + + /** + * When <code>true</code>, the geometry is expected to appear translucent. + * + * @type {Boolean} + * + * @default true + */ + this.translucent = translucent; + + this._vertexShaderSource = defaultValue(options.vertexShaderSource, materialSupport.vertexShaderSource); + this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, materialSupport.fragmentShaderSource); + this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); + this._closed = closed; + + // Non-derived members + + this._materialSupport = materialSupport; + this._vertexFormat = materialSupport.vertexFormat; + this._flat = defaultValue(options.flat, false); + this._faceForward = defaultValue(options.faceForward, !closed); + } + + defineProperties(MaterialAppearance.prototype, { + /** + * The GLSL source code for the vertex shader. + * + * @memberof MaterialAppearance.prototype + * + * @type {String} + * @readonly + */ + vertexShaderSource : { + get : function() { + return this._vertexShaderSource; + } + }, + + /** + * The GLSL source code for the fragment shader. The full fragment shader + * source is built procedurally taking into account {@link MaterialAppearance#material}, + * {@link MaterialAppearance#flat}, and {@link MaterialAppearance#faceForward}. + * Use {@link MaterialAppearance#getFragmentShaderSource} to get the full source. + * + * @memberof MaterialAppearance.prototype + * + * @type {String} + * @readonly + */ + fragmentShaderSource : { + get : function() { + return this._fragmentShaderSource; + } + }, + + /** + * The WebGL fixed-function state to use when rendering the geometry. + * <p> + * The render state can be explicitly defined when constructing a {@link MaterialAppearance} + * instance, or it is set implicitly via {@link MaterialAppearance#translucent} + * and {@link MaterialAppearance#closed}. + * </p> + * + * @memberof MaterialAppearance.prototype + * + * @type {Object} + * @readonly + */ + renderState : { + get : function() { + return this._renderState; + } + }, + + /** + * When <code>true</code>, the geometry is expected to be closed so + * {@link MaterialAppearance#renderState} has backface culling enabled. + * If the viewer enters the geometry, it will not be visible. + * + * @memberof MaterialAppearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + closed : { + get : function() { + return this._closed; + } + }, + + /** + * The type of materials supported by this instance. This impacts the required + * {@link VertexFormat} and the complexity of the vertex and fragment shaders. + * + * @memberof MaterialAppearance.prototype + * + * @type {MaterialAppearance.MaterialSupport} + * @readonly + * + * @default {@link MaterialAppearance.MaterialSupport.TEXTURED} + */ + materialSupport : { + get : function() { + return this._materialSupport; + } + }, + + /** + * The {@link VertexFormat} that this appearance instance is compatible with. + * A geometry can have more vertex attributes and still be compatible - at a + * potential performance cost - but it can't have less. + * + * @memberof MaterialAppearance.prototype + * + * @type VertexFormat + * @readonly + * + * @default {@link MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat} + */ + vertexFormat : { + get : function() { + return this._vertexFormat; + } + }, + + /** + * When <code>true</code>, flat shading is used in the fragment shader, + * which means lighting is not taking into account. + * + * @memberof MaterialAppearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + flat : { + get : function() { + return this._flat; + } + }, + + /** + * When <code>true</code>, the fragment shader flips the surface normal + * as needed to ensure that the normal faces the viewer to avoid + * dark spots. This is useful when both sides of a geometry should be + * shaded like {@link WallGeometry}. + * + * @memberof MaterialAppearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + faceForward : { + get : function() { + return this._faceForward; + } + } + }); + + /** + * Procedurally creates the full GLSL fragment shader source. For {@link MaterialAppearance}, + * this is derived from {@link MaterialAppearance#fragmentShaderSource}, {@link MaterialAppearance#material}, + * {@link MaterialAppearance#flat}, and {@link MaterialAppearance#faceForward}. + * + * @function + * + * @returns {String} The full GLSL fragment shader source. + */ + MaterialAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; + + /** + * Determines if the geometry is translucent based on {@link MaterialAppearance#translucent} and {@link Material#isTranslucent}. + * + * @function + * + * @returns {Boolean} <code>true</code> if the appearance is translucent. + */ + MaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; + + /** + * Creates a render state. This is not the final render state instance; instead, + * it can contain a subset of render state properties identical to the render state + * created in the context. + * + * @function + * + * @returns {Object} The render state. + */ + MaterialAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; + + /** + * Determines the type of {@link Material} that is supported by a + * {@link MaterialAppearance} instance. This is a trade-off between + * flexibility (a wide array of materials) and memory/performance + * (required vertex format and GLSL shader complexity. + */ + MaterialAppearance.MaterialSupport = { + /** + * Only basic materials, which require just <code>position</code> and + * <code>normal</code> vertex attributes, are supported. + * + * @constant + */ + BASIC : freezeObject({ + vertexFormat : VertexFormat.POSITION_AND_NORMAL, + vertexShaderSource : BasicMaterialAppearanceVS, + fragmentShaderSource : BasicMaterialAppearanceFS + }), + /** + * Materials with textures, which require <code>position</code>, + * <code>normal</code>, and <code>st</code> vertex attributes, + * are supported. The vast majority of materials fall into this category. + * + * @constant + */ + TEXTURED : freezeObject({ + vertexFormat : VertexFormat.POSITION_NORMAL_AND_ST, + vertexShaderSource : TexturedMaterialAppearanceVS, + fragmentShaderSource : TexturedMaterialAppearanceFS + }), + /** + * All materials, including those that work in tangent space, are supported. + * This requires <code>position</code>, <code>normal</code>, <code>st</code>, + * <code>tangent</code>, and <code>bitangent</code> vertex attributes. + * + * @constant + */ + ALL : freezeObject({ + vertexFormat : VertexFormat.ALL, + vertexShaderSource : AllMaterialAppearanceVS, + fragmentShaderSource : AllMaterialAppearanceFS + }) + }; + + return MaterialAppearance; +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/PerInstanceColorAppearanceFS',[],function() { + 'use strict'; + return "varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +varying vec4 v_color;\n\ +void main()\n\ +{\n\ +vec3 positionToEyeEC = -v_positionEC;\n\ +vec3 normalEC = normalize(v_normalEC);\n\ +#ifdef FACE_FORWARD\n\ +normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\ +#endif\n\ +czm_materialInput materialInput;\n\ +materialInput.normalEC = normalEC;\n\ +materialInput.positionToEyeEC = positionToEyeEC;\n\ +czm_material material = czm_getDefaultMaterial(materialInput);\n\ +material.diffuse = v_color.rgb;\n\ +material.alpha = v_color.a;\n\ +gl_FragColor = czm_phong(normalize(positionToEyeEC), material);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/PerInstanceColorAppearanceVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 normal;\n\ +attribute vec4 color;\n\ +attribute float batchId;\n\ +varying vec3 v_positionEC;\n\ +varying vec3 v_normalEC;\n\ +varying vec4 v_color;\n\ +void main()\n\ +{\n\ +vec4 p = czm_computePosition();\n\ +v_positionEC = (czm_modelViewRelativeToEye * p).xyz;\n\ +v_normalEC = czm_normal * normal;\n\ +v_color = color;\n\ +gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/PerInstanceFlatColorAppearanceFS',[],function() { + 'use strict'; + return "varying vec4 v_color;\n\ +void main()\n\ +{\n\ +gl_FragColor = v_color;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/PerInstanceFlatColorAppearanceVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec4 color;\n\ +attribute float batchId;\n\ +varying vec4 v_color;\n\ +void main()\n\ +{\n\ +vec4 p = czm_computePosition();\n\ +v_color = color;\n\ +gl_Position = czm_modelViewProjectionRelativeToEye * p;\n\ +}\n\ +"; +}); +define('Scene/PerInstanceColorAppearance',[ + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/VertexFormat', + '../Shaders/Appearances/PerInstanceColorAppearanceFS', + '../Shaders/Appearances/PerInstanceColorAppearanceVS', + '../Shaders/Appearances/PerInstanceFlatColorAppearanceFS', + '../Shaders/Appearances/PerInstanceFlatColorAppearanceVS', + './Appearance' + ], function( + defaultValue, + defineProperties, + VertexFormat, + PerInstanceColorAppearanceFS, + PerInstanceColorAppearanceVS, + PerInstanceFlatColorAppearanceFS, + PerInstanceFlatColorAppearanceVS, + Appearance) { + 'use strict'; + + /** + * An appearance for {@link GeometryInstance} instances with color attributes. + * This allows several geometry instances, each with a different color, to + * be drawn with the same {@link Primitive} as shown in the second example below. + * + * @alias PerInstanceColorAppearance + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. + * @param {Boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. + * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. + * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link PerInstanceColorAppearance#renderState} has backface culling enabled. + * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {RenderState} [options.renderState] Optional render state to override the default render state. + * + * @example + * // A solid white line segment + * var primitive = new Cesium.Primitive({ + * geometryInstances : new Cesium.GeometryInstance({ + * geometry : new Cesium.SimplePolylineGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * 0.0, 0.0, + * 5.0, 0.0 + * ]) + * }), + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0)) + * } + * }), + * appearance : new Cesium.PerInstanceColorAppearance({ + * flat : true, + * translucent : false + * }) + * }); + * + * // Two rectangles in a primitive, each with a different color + * var instance = new Cesium.GeometryInstance({ + * geometry : new Cesium.RectangleGeometry({ + * rectangle : Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0) + * }), + * attributes : { + * color : new Cesium.Color(1.0, 0.0, 0.0, 0.5) + * } + * }); + * + * var anotherInstance = new Cesium.GeometryInstance({ + * geometry : new Cesium.RectangleGeometry({ + * rectangle : Cesium.Rectangle.fromDegrees(0.0, 40.0, 10.0, 50.0) + * }), + * attributes : { + * color : new Cesium.Color(0.0, 0.0, 1.0, 0.5) + * } + * }); + * + * var rectanglePrimitive = new Cesium.Primitive({ + * geometryInstances : [instance, anotherInstance], + * appearance : new Cesium.PerInstanceColorAppearance() + * }); + */ + function PerInstanceColorAppearance(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var translucent = defaultValue(options.translucent, true); + var closed = defaultValue(options.closed, false); + var flat = defaultValue(options.flat, false); + var vs = flat ? PerInstanceFlatColorAppearanceVS : PerInstanceColorAppearanceVS; + var fs = flat ? PerInstanceFlatColorAppearanceFS : PerInstanceColorAppearanceFS; + var vertexFormat = flat ? PerInstanceColorAppearance.FLAT_VERTEX_FORMAT : PerInstanceColorAppearance.VERTEX_FORMAT; + + /** + * This property is part of the {@link Appearance} interface, but is not + * used by {@link PerInstanceColorAppearance} since a fully custom fragment shader is used. + * + * @type Material + * + * @default undefined + */ + this.material = undefined; + + /** + * When <code>true</code>, the geometry is expected to appear translucent so + * {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. + * + * @type {Boolean} + * + * @default true + */ + this.translucent = translucent; + + this._vertexShaderSource = defaultValue(options.vertexShaderSource, vs); + this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, fs); + this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); + this._closed = closed; + + // Non-derived members + + this._vertexFormat = vertexFormat; + this._flat = flat; + this._faceForward = defaultValue(options.faceForward, !closed); + } + + defineProperties(PerInstanceColorAppearance.prototype, { + /** + * The GLSL source code for the vertex shader. + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type {String} + * @readonly + */ + vertexShaderSource : { + get : function() { + return this._vertexShaderSource; + } + }, + + /** + * The GLSL source code for the fragment shader. + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type {String} + * @readonly + */ + fragmentShaderSource : { + get : function() { + return this._fragmentShaderSource; + } + }, + + /** + * The WebGL fixed-function state to use when rendering the geometry. + * <p> + * The render state can be explicitly defined when constructing a {@link PerInstanceColorAppearance} + * instance, or it is set implicitly via {@link PerInstanceColorAppearance#translucent} + * and {@link PerInstanceColorAppearance#closed}. + * </p> + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type {Object} + * @readonly + */ + renderState : { + get : function() { + return this._renderState; + } + }, + + /** + * When <code>true</code>, the geometry is expected to be closed so + * {@link PerInstanceColorAppearance#renderState} has backface culling enabled. + * If the viewer enters the geometry, it will not be visible. + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + closed : { + get : function() { + return this._closed; + } + }, + + /** + * The {@link VertexFormat} that this appearance instance is compatible with. + * A geometry can have more vertex attributes and still be compatible - at a + * potential performance cost - but it can't have less. + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type VertexFormat + * @readonly + */ + vertexFormat : { + get : function() { + return this._vertexFormat; + } + }, + + /** + * When <code>true</code>, flat shading is used in the fragment shader, + * which means lighting is not taking into account. + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + flat : { + get : function() { + return this._flat; + } + }, + + /** + * When <code>true</code>, the fragment shader flips the surface normal + * as needed to ensure that the normal faces the viewer to avoid + * dark spots. This is useful when both sides of a geometry should be + * shaded like {@link WallGeometry}. + * + * @memberof PerInstanceColorAppearance.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + faceForward : { + get : function() { + return this._faceForward; + } + } + }); + + /** + * The {@link VertexFormat} that all {@link PerInstanceColorAppearance} instances + * are compatible with. This requires only <code>position</code> and <code>st</code> + * attributes. + * + * @type VertexFormat + * + * @constant + */ + PerInstanceColorAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_NORMAL; + + /** + * The {@link VertexFormat} that all {@link PerInstanceColorAppearance} instances + * are compatible with when {@link PerInstanceColorAppearance#flat} is <code>false</code>. + * This requires only a <code>position</code> attribute. + * + * @type VertexFormat + * + * @constant + */ + PerInstanceColorAppearance.FLAT_VERTEX_FORMAT = VertexFormat.POSITION_ONLY; + + /** + * Procedurally creates the full GLSL fragment shader source. For {@link PerInstanceColorAppearance}, + * this is derived from {@link PerInstanceColorAppearance#fragmentShaderSource}, {@link PerInstanceColorAppearance#flat}, + * and {@link PerInstanceColorAppearance#faceForward}. + * + * @function + * + * @returns {String} The full GLSL fragment shader source. + */ + PerInstanceColorAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; + + /** + * Determines if the geometry is translucent based on {@link PerInstanceColorAppearance#translucent}. + * + * @function + * + * @returns {Boolean} <code>true</code> if the appearance is translucent. + */ + PerInstanceColorAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; + + /** + * Creates a render state. This is not the final render state instance; instead, + * it can contain a subset of render state properties identical to the render state + * created in the context. + * + * @function + * + * @returns {Object} The render state. + */ + PerInstanceColorAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; + + return PerInstanceColorAppearance; +}); + +define('Renderer/BufferUsage',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + + /** + * @private + */ + var BufferUsage = { + STREAM_DRAW : WebGLConstants.STREAM_DRAW, + STATIC_DRAW : WebGLConstants.STATIC_DRAW, + DYNAMIC_DRAW : WebGLConstants.DYNAMIC_DRAW, + + validate : function(bufferUsage) { + return ((bufferUsage === BufferUsage.STREAM_DRAW) || + (bufferUsage === BufferUsage.STATIC_DRAW) || + (bufferUsage === BufferUsage.DYNAMIC_DRAW)); + } + }; + + return freezeObject(BufferUsage); +}); + +define('Renderer/DrawCommand',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/PrimitiveType' + ], function( + defaultValue, + defined, + defineProperties, + PrimitiveType) { + 'use strict'; + + /** + * Represents a command to the renderer for drawing. + * + * @private + */ + function DrawCommand(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._boundingVolume = options.boundingVolume; + this._orientedBoundingBox = options.orientedBoundingBox; + this._cull = defaultValue(options.cull, true); + this._modelMatrix = options.modelMatrix; + this._primitiveType = defaultValue(options.primitiveType, PrimitiveType.TRIANGLES); + this._vertexArray = options.vertexArray; + this._count = options.count; + this._offset = defaultValue(options.offset, 0); + this._instanceCount = defaultValue(options.instanceCount, 0); + this._shaderProgram = options.shaderProgram; + this._uniformMap = options.uniformMap; + this._renderState = options.renderState; + this._framebuffer = options.framebuffer; + this._pass = options.pass; + this._executeInClosestFrustum = defaultValue(options.executeInClosestFrustum, false); + this._owner = options.owner; + this._debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + this._debugOverlappingFrustums = 0; + this._castShadows = defaultValue(options.castShadows, false); + this._receiveShadows = defaultValue(options.receiveShadows, false); + + this.dirty = true; + this.lastDirtyTime = 0; + + /** + * @private + */ + this.derivedCommands = {}; + } + + defineProperties(DrawCommand.prototype, { + /** + * The bounding volume of the geometry in world space. This is used for culling and frustum selection. + * <p> + * For best rendering performance, use the tightest possible bounding volume. Although + * <code>undefined</code> is allowed, always try to provide a bounding volume to + * allow the tightest possible near and far planes to be computed for the scene, and + * minimize the number of frustums needed. + * </p> + * + * @memberof DrawCommand.prototype + * @type {Object} + * @default undefined + * + * @see DrawCommand#debugShowBoundingVolume + */ + boundingVolume : { + get : function() { + return this._boundingVolume; + }, + set : function(value) { + if (this._boundingVolume !== value) { + this._boundingVolume = value; + this.dirty = true; + } + } + }, + + /** + * The oriented bounding box of the geometry in world space. If this is defined, it is used instead of + * {@link DrawCommand#boundingVolume} for plane intersection testing. + * + * @memberof DrawCommand.prototype + * @type {OrientedBoundingBox} + * @default undefined + * + * @see DrawCommand#debugShowBoundingVolume + */ + orientedBoundingBox : { + get : function() { + return this._orientedBoundingBox; + }, + set : function(value) { + if (this._orientedBoundingBox !== value) { + this._orientedBoundingBox = value; + this.dirty = true; + } + } + }, + + /** + * When <code>true</code>, the renderer frustum and horizon culls the command based on its {@link DrawCommand#boundingVolume}. + * If the command was already culled, set this to <code>false</code> for a performance improvement. + * + * @memberof DrawCommand.prototype + * @type {Boolean} + * @default true + */ + cull : { + get : function() { + return this._cull; + }, + set : function(value) { + if (this._cull !== value) { + this._cull = value; + this.dirty = true; + } + } + }, + + /** + * The transformation from the geometry in model space to world space. + * <p> + * When <code>undefined</code>, the geometry is assumed to be defined in world space. + * </p> + * + * @memberof DrawCommand.prototype + * @type {Matrix4} + * @default undefined + */ + modelMatrix : { + get : function() { + return this._modelMatrix; + }, + set : function(value) { + if (this._modelMatrix !== value) { + this._modelMatrix = value; + this.dirty = true; + } + } + }, + + /** + * The type of geometry in the vertex array. + * + * @memberof DrawCommand.prototype + * @type {PrimitiveType} + * @default PrimitiveType.TRIANGLES + */ + primitiveType : { + get : function() { + return this._primitiveType; + }, + set : function(value) { + if (this._primitiveType !== value) { + this._primitiveType = value; + this.dirty = true; + } + } + }, + + /** + * The vertex array. + * + * @memberof DrawCommand.prototype + * @type {VertexArray} + * @default undefined + */ + vertexArray : { + get : function() { + return this._vertexArray; + }, + set : function(value) { + if (this._vertexArray !== value) { + this._vertexArray = value; + this.dirty = true; + } + } + }, + + /** + * The number of vertices to draw in the vertex array. + * + * @memberof DrawCommand.prototype + * @type {Number} + * @default undefined + */ + count : { + get : function() { + return this._count; + }, + set : function(value) { + if (this._count !== value) { + this._count = value; + this.dirty = true; + } + } + }, + + /** + * The offset to start drawing in the vertex array. + * + * @memberof DrawCommand.prototype + * @type {Number} + * @default 0 + */ + offset : { + get : function() { + return this._offset; + }, + set : function(value) { + if (this._offset !== value) { + this._offset = value; + this.dirty = true; + } + } + }, + + /** + * The number of instances to draw. + * + * @memberof DrawCommand.prototype + * @type {Number} + * @default 0 + */ + instanceCount : { + get : function() { + return this._instanceCount; + }, + set : function(value) { + if (this._instanceCount !== value) { + this._instanceCount = value; + this.dirty = true; + } + } + }, + + /** + * The shader program to apply. + * + * @memberof DrawCommand.prototype + * @type {ShaderProgram} + * @default undefined + */ + shaderProgram : { + get : function() { + return this._shaderProgram; + }, + set : function(value) { + if (this._shaderProgram !== value) { + this._shaderProgram = value; + this.dirty = true; + } + } + }, + + /** + * Whether this command should cast shadows when shadowing is enabled. + * + * @memberof DrawCommand.prototype + * @type {Boolean} + * @default false + */ + castShadows : { + get : function() { + return this._castShadows; + }, + set : function(value) { + if (this._castShadows !== value) { + this._castShadows = value; + this.dirty = true; + } + } + }, + + /** + * Whether this command should receive shadows when shadowing is enabled. + * + * @memberof DrawCommand.prototype + * @type {Boolean} + * @default false + */ + receiveShadows : { + get : function() { + return this._receiveShadows; + }, + set : function(value) { + if (this._receiveShadows !== value) { + this._receiveShadows = value; + this.dirty = true; + } + } + }, + + /** + * An object with functions whose names match the uniforms in the shader program + * and return values to set those uniforms. + * + * @memberof DrawCommand.prototype + * @type {Object} + * @default undefined + */ + uniformMap : { + get : function() { + return this._uniformMap; + }, + set : function(value) { + if (this._uniformMap !== value) { + this._uniformMap = value; + this.dirty = true; + } + } + }, + + /** + * The render state. + * + * @memberof DrawCommand.prototype + * @type {RenderState} + * @default undefined + */ + renderState : { + get : function() { + return this._renderState; + }, + set : function(value) { + if (this._renderState !== value) { + this._renderState = value; + this.dirty = true; + } + } + }, + + /** + * The framebuffer to draw to. + * + * @memberof DrawCommand.prototype + * @type {Framebuffer} + * @default undefined + */ + framebuffer : { + get : function() { + return this._framebuffer; + }, + set : function(value) { + if (this._framebuffer !== value) { + this._framebuffer = value; + this.dirty = true; + } + } + }, + + /** + * The pass when to render. + * + * @memberof DrawCommand.prototype + * @type {Pass} + * @default undefined + */ + pass : { + get : function() { + return this._pass; + }, + set : function(value) { + if (this._pass !== value) { + this._pass = value; + this.dirty = true; + } + } + }, + + /** + * Specifies if this command is only to be executed in the frustum closest + * to the eye containing the bounding volume. Defaults to <code>false</code>. + * + * @memberof DrawCommand.prototype + * @type {Boolean} + * @default false + */ + executeInClosestFrustum : { + get : function() { + return this._executeInClosestFrustum; + }, + set : function(value) { + if (this._executeInClosestFrustum !== value) { + this._executeInClosestFrustum = value; + this.dirty = true; + } + } + }, + + /** + * The object who created this command. This is useful for debugging command + * execution; it allows us to see who created a command when we only have a + * reference to the command, and can be used to selectively execute commands + * with {@link Scene#debugCommandFilter}. + * + * @memberof DrawCommand.prototype + * @type {Object} + * @default undefined + * + * @see Scene#debugCommandFilter + */ + owner : { + get : function() { + return this._owner; + }, + set : function(value) { + if (this._owner !== value) { + this._owner = value; + this.dirty = true; + } + } + }, + + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the {@link DrawCommand#boundingVolume} for this command, assuming it is a sphere, when the command executes. + * </p> + * + * @memberof DrawCommand.prototype + * @type {Boolean} + * @default false + * + * @see DrawCommand#boundingVolume + */ + debugShowBoundingVolume : { + get : function() { + return this._debugShowBoundingVolume; + }, + set : function(value) { + if (this._debugShowBoundingVolume !== value) { + this._debugShowBoundingVolume = value; + this.dirty = true; + } + } + }, + + /** + * Used to implement Scene.debugShowFrustums. + * @private + */ + debugOverlappingFrustums : { + get : function() { + return this._debugOverlappingFrustums; + }, + set : function(value) { + if (this._debugOverlappingFrustums !== value) { + this._debugOverlappingFrustums = value; + this.dirty = true; + } + } + } + }); + + /** + * @private + */ + DrawCommand.shallowClone = function(command, result) { + if (!defined(command)) { + return undefined; + } + if (!defined(result)) { + result = new DrawCommand(); + } + + result._boundingVolume = command._boundingVolume; + result._orientedBoundingBox = command._orientedBoundingBox; + result._cull = command._cull; + result._modelMatrix = command._modelMatrix; + result._primitiveType = command._primitiveType; + result._vertexArray = command._vertexArray; + result._count = command._count; + result._offset = command._offset; + result._instanceCount = command._instanceCount; + result._shaderProgram = command._shaderProgram; + result._uniformMap = command._uniformMap; + result._renderState = command._renderState; + result._framebuffer = command._framebuffer; + result._pass = command._pass; + result._executeInClosestFrustum = command._executeInClosestFrustum; + result._owner = command._owner; + result._debugShowBoundingVolume = command._debugShowBoundingVolume; + result._debugOverlappingFrustums = command._debugOverlappingFrustums; + result._castShadows = command._castShadows; + result._receiveShadows = command._receiveShadows; + + result.dirty = true; + result.lastDirtyTime = 0; + + return result; + }; + + /** + * Executes the draw command. + * + * @param {Context} context The renderer context in which to draw. + * @param {PassState} [passState] The state for the current render pass. + */ + DrawCommand.prototype.execute = function(context, passState) { + context.draw(this, passState); + }; + + return DrawCommand; +}); + +define('Renderer/Pass',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * The render pass for a command. + * + * @private + */ + var Pass = { + // If you add/modify/remove Pass constants, also change the automatic GLSL constants + // that start with 'czm_pass' + // + // Commands are executed in order by pass up to the translucent pass. + // Translucent geometry needs special handling (sorting/OIT). The compute pass + // is executed first and the overlay pass is executed last. Both are not sorted + // by frustum. + ENVIRONMENT : 0, + COMPUTE : 1, + GLOBE : 2, + TERRAIN_CLASSIFICATION : 3, + CESIUM_3D_TILE : 4, + CESIUM_3D_TILE_CLASSIFICATION : 5, + CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW : 6, + CLASSIFICATION : 7, + OPAQUE : 8, + TRANSLUCENT : 9, + OVERLAY : 10, + NUMBER_OF_PASSES : 11 + }; + + return freezeObject(Pass); +}); + +/*global define*/ +define('Renderer/freezeRenderState',[ + '../Core/freezeObject' + ], function(freezeObject) { + 'use strict'; + + /** + * Returns frozen renderState as well as all of the object literal properties. This function is deep object freeze + * function ignoring properties named "_applyFunctions". + * + * @private + * + * @param {Object} renderState + * @returns {Object} Returns frozen renderState. + * + */ + function freezeRenderState(renderState) { + if (typeof renderState !== 'object' || renderState === null) { + return renderState; + } + + var propName; + var propNames = Object.keys(renderState); + + for (var i = 0; i < propNames.length; i++) { + propName = propNames[i]; + if (renderState.hasOwnProperty(propName) && propName !== '_applyFunctions') { + renderState[propName] = freezeRenderState(renderState[propName]); + } + } + return freezeObject(renderState); + } + return freezeRenderState; +}); + +define('Renderer/RenderState',[ + '../Core/BoundingRectangle', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/DeveloperError', + '../Core/WebGLConstants', + '../Core/WindingOrder', + './ContextLimits', + './freezeRenderState' + ], function( + BoundingRectangle, + Color, + defaultValue, + defined, + DeveloperError, + WebGLConstants, + WindingOrder, + ContextLimits, + freezeRenderState) { + 'use strict'; + + function validateBlendEquation(blendEquation) { + return ((blendEquation === WebGLConstants.FUNC_ADD) || + (blendEquation === WebGLConstants.FUNC_SUBTRACT) || + (blendEquation === WebGLConstants.FUNC_REVERSE_SUBTRACT) || + (blendEquation === WebGLConstants.MIN) || + (blendEquation === WebGLConstants.MAX)); + } + + function validateBlendFunction(blendFunction) { + return ((blendFunction === WebGLConstants.ZERO) || + (blendFunction === WebGLConstants.ONE) || + (blendFunction === WebGLConstants.SRC_COLOR) || + (blendFunction === WebGLConstants.ONE_MINUS_SRC_COLOR) || + (blendFunction === WebGLConstants.DST_COLOR) || + (blendFunction === WebGLConstants.ONE_MINUS_DST_COLOR) || + (blendFunction === WebGLConstants.SRC_ALPHA) || + (blendFunction === WebGLConstants.ONE_MINUS_SRC_ALPHA) || + (blendFunction === WebGLConstants.DST_ALPHA) || + (blendFunction === WebGLConstants.ONE_MINUS_DST_ALPHA) || + (blendFunction === WebGLConstants.CONSTANT_COLOR) || + (blendFunction === WebGLConstants.ONE_MINUS_CONSTANT_COLOR) || + (blendFunction === WebGLConstants.CONSTANT_ALPHA) || + (blendFunction === WebGLConstants.ONE_MINUS_CONSTANT_ALPHA) || + (blendFunction === WebGLConstants.SRC_ALPHA_SATURATE)); + } + + function validateCullFace(cullFace) { + return ((cullFace === WebGLConstants.FRONT) || + (cullFace === WebGLConstants.BACK) || + (cullFace === WebGLConstants.FRONT_AND_BACK)); + } + + function validateDepthFunction(depthFunction) { + return ((depthFunction === WebGLConstants.NEVER) || + (depthFunction === WebGLConstants.LESS) || + (depthFunction === WebGLConstants.EQUAL) || + (depthFunction === WebGLConstants.LEQUAL) || + (depthFunction === WebGLConstants.GREATER) || + (depthFunction === WebGLConstants.NOTEQUAL) || + (depthFunction === WebGLConstants.GEQUAL) || + (depthFunction === WebGLConstants.ALWAYS)); + } + + function validateStencilFunction(stencilFunction) { + return ((stencilFunction === WebGLConstants.NEVER) || + (stencilFunction === WebGLConstants.LESS) || + (stencilFunction === WebGLConstants.EQUAL) || + (stencilFunction === WebGLConstants.LEQUAL) || + (stencilFunction === WebGLConstants.GREATER) || + (stencilFunction === WebGLConstants.NOTEQUAL) || + (stencilFunction === WebGLConstants.GEQUAL) || + (stencilFunction === WebGLConstants.ALWAYS)); + } + + function validateStencilOperation(stencilOperation) { + return ((stencilOperation === WebGLConstants.ZERO) || + (stencilOperation === WebGLConstants.KEEP) || + (stencilOperation === WebGLConstants.REPLACE) || + (stencilOperation === WebGLConstants.INCR) || + (stencilOperation === WebGLConstants.DECR) || + (stencilOperation === WebGLConstants.INVERT) || + (stencilOperation === WebGLConstants.INCR_WRAP) || + (stencilOperation === WebGLConstants.DECR_WRAP)); + } + + /** + * @private + */ + function RenderState(renderState) { + var rs = defaultValue(renderState, {}); + var cull = defaultValue(rs.cull, {}); + var polygonOffset = defaultValue(rs.polygonOffset, {}); + var scissorTest = defaultValue(rs.scissorTest, {}); + var scissorTestRectangle = defaultValue(scissorTest.rectangle, {}); + var depthRange = defaultValue(rs.depthRange, {}); + var depthTest = defaultValue(rs.depthTest, {}); + var colorMask = defaultValue(rs.colorMask, {}); + var blending = defaultValue(rs.blending, {}); + var blendingColor = defaultValue(blending.color, {}); + var stencilTest = defaultValue(rs.stencilTest, {}); + var stencilTestFrontOperation = defaultValue(stencilTest.frontOperation, {}); + var stencilTestBackOperation = defaultValue(stencilTest.backOperation, {}); + var sampleCoverage = defaultValue(rs.sampleCoverage, {}); + var viewport = rs.viewport; + + this.frontFace = defaultValue(rs.frontFace, WindingOrder.COUNTER_CLOCKWISE); + this.cull = { + enabled : defaultValue(cull.enabled, false), + face : defaultValue(cull.face, WebGLConstants.BACK) + }; + this.lineWidth = defaultValue(rs.lineWidth, 1.0); + this.polygonOffset = { + enabled : defaultValue(polygonOffset.enabled, false), + factor : defaultValue(polygonOffset.factor, 0), + units : defaultValue(polygonOffset.units, 0) + }; + this.scissorTest = { + enabled : defaultValue(scissorTest.enabled, false), + rectangle : BoundingRectangle.clone(scissorTestRectangle) + }; + this.depthRange = { + near : defaultValue(depthRange.near, 0), + far : defaultValue(depthRange.far, 1) + }; + this.depthTest = { + enabled : defaultValue(depthTest.enabled, false), + func : defaultValue(depthTest.func, WebGLConstants.LESS) // func, because function is a JavaScript keyword + }; + this.colorMask = { + red : defaultValue(colorMask.red, true), + green : defaultValue(colorMask.green, true), + blue : defaultValue(colorMask.blue, true), + alpha : defaultValue(colorMask.alpha, true) + }; + this.depthMask = defaultValue(rs.depthMask, true); + this.stencilMask = defaultValue(rs.stencilMask, ~0); + this.blending = { + enabled : defaultValue(blending.enabled, false), + color : new Color( + defaultValue(blendingColor.red, 0.0), + defaultValue(blendingColor.green, 0.0), + defaultValue(blendingColor.blue, 0.0), + defaultValue(blendingColor.alpha, 0.0) + ), + equationRgb : defaultValue(blending.equationRgb, WebGLConstants.FUNC_ADD), + equationAlpha : defaultValue(blending.equationAlpha, WebGLConstants.FUNC_ADD), + functionSourceRgb : defaultValue(blending.functionSourceRgb, WebGLConstants.ONE), + functionSourceAlpha : defaultValue(blending.functionSourceAlpha, WebGLConstants.ONE), + functionDestinationRgb : defaultValue(blending.functionDestinationRgb, WebGLConstants.ZERO), + functionDestinationAlpha : defaultValue(blending.functionDestinationAlpha, WebGLConstants.ZERO) + }; + this.stencilTest = { + enabled : defaultValue(stencilTest.enabled, false), + frontFunction : defaultValue(stencilTest.frontFunction, WebGLConstants.ALWAYS), + backFunction : defaultValue(stencilTest.backFunction, WebGLConstants.ALWAYS), + reference : defaultValue(stencilTest.reference, 0), + mask : defaultValue(stencilTest.mask, ~0), + frontOperation : { + fail : defaultValue(stencilTestFrontOperation.fail, WebGLConstants.KEEP), + zFail : defaultValue(stencilTestFrontOperation.zFail, WebGLConstants.KEEP), + zPass : defaultValue(stencilTestFrontOperation.zPass, WebGLConstants.KEEP) + }, + backOperation : { + fail : defaultValue(stencilTestBackOperation.fail, WebGLConstants.KEEP), + zFail : defaultValue(stencilTestBackOperation.zFail, WebGLConstants.KEEP), + zPass : defaultValue(stencilTestBackOperation.zPass, WebGLConstants.KEEP) + } + }; + this.sampleCoverage = { + enabled : defaultValue(sampleCoverage.enabled, false), + value : defaultValue(sampleCoverage.value, 1.0), + invert : defaultValue(sampleCoverage.invert, false) + }; + this.viewport = (defined(viewport)) ? new BoundingRectangle(viewport.x, viewport.y, viewport.width, viewport.height) : undefined; + + if ((this.lineWidth < ContextLimits.minimumAliasedLineWidth) || + (this.lineWidth > ContextLimits.maximumAliasedLineWidth)) { + throw new DeveloperError('renderState.lineWidth is out of range. Check minimumAliasedLineWidth and maximumAliasedLineWidth.'); + } + if (!WindingOrder.validate(this.frontFace)) { + throw new DeveloperError('Invalid renderState.frontFace.'); + } + if (!validateCullFace(this.cull.face)) { + throw new DeveloperError('Invalid renderState.cull.face.'); + } + if ((this.scissorTest.rectangle.width < 0) || + (this.scissorTest.rectangle.height < 0)) { + throw new DeveloperError('renderState.scissorTest.rectangle.width and renderState.scissorTest.rectangle.height must be greater than or equal to zero.'); + } + if (this.depthRange.near > this.depthRange.far) { + // WebGL specific - not an error in GL ES + throw new DeveloperError('renderState.depthRange.near can not be greater than renderState.depthRange.far.'); + } + if (this.depthRange.near < 0) { + // Would be clamped by GL + throw new DeveloperError('renderState.depthRange.near must be greater than or equal to zero.'); + } + if (this.depthRange.far > 1) { + // Would be clamped by GL + throw new DeveloperError('renderState.depthRange.far must be less than or equal to one.'); + } + if (!validateDepthFunction(this.depthTest.func)) { + throw new DeveloperError('Invalid renderState.depthTest.func.'); + } + if ((this.blending.color.red < 0.0) || (this.blending.color.red > 1.0) || + (this.blending.color.green < 0.0) || (this.blending.color.green > 1.0) || + (this.blending.color.blue < 0.0) || (this.blending.color.blue > 1.0) || + (this.blending.color.alpha < 0.0) || (this.blending.color.alpha > 1.0)) { + // Would be clamped by GL + throw new DeveloperError('renderState.blending.color components must be greater than or equal to zero and less than or equal to one.'); + } + if (!validateBlendEquation(this.blending.equationRgb)) { + throw new DeveloperError('Invalid renderState.blending.equationRgb.'); + } + if (!validateBlendEquation(this.blending.equationAlpha)) { + throw new DeveloperError('Invalid renderState.blending.equationAlpha.'); + } + if (!validateBlendFunction(this.blending.functionSourceRgb)) { + throw new DeveloperError('Invalid renderState.blending.functionSourceRgb.'); + } + if (!validateBlendFunction(this.blending.functionSourceAlpha)) { + throw new DeveloperError('Invalid renderState.blending.functionSourceAlpha.'); + } + if (!validateBlendFunction(this.blending.functionDestinationRgb)) { + throw new DeveloperError('Invalid renderState.blending.functionDestinationRgb.'); + } + if (!validateBlendFunction(this.blending.functionDestinationAlpha)) { + throw new DeveloperError('Invalid renderState.blending.functionDestinationAlpha.'); + } + if (!validateStencilFunction(this.stencilTest.frontFunction)) { + throw new DeveloperError('Invalid renderState.stencilTest.frontFunction.'); + } + if (!validateStencilFunction(this.stencilTest.backFunction)) { + throw new DeveloperError('Invalid renderState.stencilTest.backFunction.'); + } + if (!validateStencilOperation(this.stencilTest.frontOperation.fail)) { + throw new DeveloperError('Invalid renderState.stencilTest.frontOperation.fail.'); + } + if (!validateStencilOperation(this.stencilTest.frontOperation.zFail)) { + throw new DeveloperError('Invalid renderState.stencilTest.frontOperation.zFail.'); + } + if (!validateStencilOperation(this.stencilTest.frontOperation.zPass)) { + throw new DeveloperError('Invalid renderState.stencilTest.frontOperation.zPass.'); + } + if (!validateStencilOperation(this.stencilTest.backOperation.fail)) { + throw new DeveloperError('Invalid renderState.stencilTest.backOperation.fail.'); + } + if (!validateStencilOperation(this.stencilTest.backOperation.zFail)) { + throw new DeveloperError('Invalid renderState.stencilTest.backOperation.zFail.'); + } + if (!validateStencilOperation(this.stencilTest.backOperation.zPass)) { + throw new DeveloperError('Invalid renderState.stencilTest.backOperation.zPass.'); + } + + if (defined(this.viewport)) { + if (this.viewport.width < 0) { + throw new DeveloperError('renderState.viewport.width must be greater than or equal to zero.'); + } + if (this.viewport.height < 0) { + throw new DeveloperError('renderState.viewport.height must be greater than or equal to zero.'); + } + + if (this.viewport.width > ContextLimits.maximumViewportWidth) { + throw new DeveloperError('renderState.viewport.width must be less than or equal to the maximum viewport width (' + ContextLimits.maximumViewportWidth.toString() + '). Check maximumViewportWidth.'); + } + if (this.viewport.height > ContextLimits.maximumViewportHeight) { + throw new DeveloperError('renderState.viewport.height must be less than or equal to the maximum viewport height (' + ContextLimits.maximumViewportHeight.toString() + '). Check maximumViewportHeight.'); + } + } + + this.id = 0; + this._applyFunctions = []; + } + + var nextRenderStateId = 0; + var renderStateCache = {}; + + /** + * Validates and then finds or creates an immutable render state, which defines the pipeline + * state for a {@link DrawCommand} or {@link ClearCommand}. All inputs states are optional. Omitted states + * use the defaults shown in the example below. + * + * @param {Object} [renderState] The states defining the render state as shown in the example below. + * + * @exception {RuntimeError} renderState.lineWidth is out of range. + * @exception {DeveloperError} Invalid renderState.frontFace. + * @exception {DeveloperError} Invalid renderState.cull.face. + * @exception {DeveloperError} scissorTest.rectangle.width and scissorTest.rectangle.height must be greater than or equal to zero. + * @exception {DeveloperError} renderState.depthRange.near can't be greater than renderState.depthRange.far. + * @exception {DeveloperError} renderState.depthRange.near must be greater than or equal to zero. + * @exception {DeveloperError} renderState.depthRange.far must be less than or equal to zero. + * @exception {DeveloperError} Invalid renderState.depthTest.func. + * @exception {DeveloperError} renderState.blending.color components must be greater than or equal to zero and less than or equal to one + * @exception {DeveloperError} Invalid renderState.blending.equationRgb. + * @exception {DeveloperError} Invalid renderState.blending.equationAlpha. + * @exception {DeveloperError} Invalid renderState.blending.functionSourceRgb. + * @exception {DeveloperError} Invalid renderState.blending.functionSourceAlpha. + * @exception {DeveloperError} Invalid renderState.blending.functionDestinationRgb. + * @exception {DeveloperError} Invalid renderState.blending.functionDestinationAlpha. + * @exception {DeveloperError} Invalid renderState.stencilTest.frontFunction. + * @exception {DeveloperError} Invalid renderState.stencilTest.backFunction. + * @exception {DeveloperError} Invalid renderState.stencilTest.frontOperation.fail. + * @exception {DeveloperError} Invalid renderState.stencilTest.frontOperation.zFail. + * @exception {DeveloperError} Invalid renderState.stencilTest.frontOperation.zPass. + * @exception {DeveloperError} Invalid renderState.stencilTest.backOperation.fail. + * @exception {DeveloperError} Invalid renderState.stencilTest.backOperation.zFail. + * @exception {DeveloperError} Invalid renderState.stencilTest.backOperation.zPass. + * @exception {DeveloperError} renderState.viewport.width must be greater than or equal to zero. + * @exception {DeveloperError} renderState.viewport.width must be less than or equal to the maximum viewport width. + * @exception {DeveloperError} renderState.viewport.height must be greater than or equal to zero. + * @exception {DeveloperError} renderState.viewport.height must be less than or equal to the maximum viewport height. + * + * + * @example + * var defaults = { + * frontFace : WindingOrder.COUNTER_CLOCKWISE, + * cull : { + * enabled : false, + * face : CullFace.BACK + * }, + * lineWidth : 1, + * polygonOffset : { + * enabled : false, + * factor : 0, + * units : 0 + * }, + * scissorTest : { + * enabled : false, + * rectangle : { + * x : 0, + * y : 0, + * width : 0, + * height : 0 + * } + * }, + * depthRange : { + * near : 0, + * far : 1 + * }, + * depthTest : { + * enabled : false, + * func : DepthFunction.LESS + * }, + * colorMask : { + * red : true, + * green : true, + * blue : true, + * alpha : true + * }, + * depthMask : true, + * stencilMask : ~0, + * blending : { + * enabled : false, + * color : { + * red : 0.0, + * green : 0.0, + * blue : 0.0, + * alpha : 0.0 + * }, + * equationRgb : BlendEquation.ADD, + * equationAlpha : BlendEquation.ADD, + * functionSourceRgb : BlendFunction.ONE, + * functionSourceAlpha : BlendFunction.ONE, + * functionDestinationRgb : BlendFunction.ZERO, + * functionDestinationAlpha : BlendFunction.ZERO + * }, + * stencilTest : { + * enabled : false, + * frontFunction : StencilFunction.ALWAYS, + * backFunction : StencilFunction.ALWAYS, + * reference : 0, + * mask : ~0, + * frontOperation : { + * fail : StencilOperation.KEEP, + * zFail : StencilOperation.KEEP, + * zPass : StencilOperation.KEEP + * }, + * backOperation : { + * fail : StencilOperation.KEEP, + * zFail : StencilOperation.KEEP, + * zPass : StencilOperation.KEEP + * } + * }, + * sampleCoverage : { + * enabled : false, + * value : 1.0, + * invert : false + * } + * }; + * + * var rs = RenderState.fromCache(defaults); + * + * @see DrawCommand + * @see ClearCommand + * + * @private + */ + RenderState.fromCache = function(renderState) { + var partialKey = JSON.stringify(renderState); + var cachedState = renderStateCache[partialKey]; + if (defined(cachedState)) { + ++cachedState.referenceCount; + return cachedState.state; + } + + // Cache miss. Fully define render state and try again. + var states = new RenderState(renderState); + var fullKey = JSON.stringify(states); + cachedState = renderStateCache[fullKey]; + if (!defined(cachedState)) { + states.id = nextRenderStateId++; + states = freezeRenderState(states); + cachedState = { + referenceCount : 0, + state : states + }; + + // Cache full render state. Multiple partially defined render states may map to this. + renderStateCache[fullKey] = cachedState; + } + + ++cachedState.referenceCount; + + // Cache partial render state so we can skip validation on a cache hit for a partially defined render state + renderStateCache[partialKey] = { + referenceCount : 1, + state : cachedState.state + }; + + return cachedState.state; + }; + + /** + * @private + */ + RenderState.removeFromCache = function(renderState) { + var states = new RenderState(renderState); + var fullKey = JSON.stringify(states); + var fullCachedState = renderStateCache[fullKey]; + + // decrement partial key reference count + var partialKey = JSON.stringify(renderState); + var cachedState = renderStateCache[partialKey]; + if (defined(cachedState)) { + --cachedState.referenceCount; + + if (cachedState.referenceCount === 0) { + // remove partial key + delete renderStateCache[partialKey]; + + // decrement full key reference count + if (defined(fullCachedState)) { + --fullCachedState.referenceCount; + } + } + } + + // remove full key if reference count is zero + if (defined(fullCachedState) && (fullCachedState.referenceCount === 0)) { + delete renderStateCache[fullKey]; + } + }; + + /** + * This function is for testing purposes only. + * @private + */ + RenderState.getCache = function() { + return renderStateCache; + }; + + /** + * This function is for testing purposes only. + * @private + */ + RenderState.clearCache = function() { + renderStateCache = {}; + }; + + function enableOrDisable(gl, glEnum, enable) { + if (enable) { + gl.enable(glEnum); + } else { + gl.disable(glEnum); + } + } + + function applyFrontFace(gl, renderState) { + gl.frontFace(renderState.frontFace); + } + + function applyCull(gl, renderState) { + var cull = renderState.cull; + var enabled = cull.enabled; + + enableOrDisable(gl, gl.CULL_FACE, enabled); + + if (enabled) { + gl.cullFace(cull.face); + } + } + + function applyLineWidth(gl, renderState) { + gl.lineWidth(renderState.lineWidth); + } + + function applyPolygonOffset(gl, renderState) { + var polygonOffset = renderState.polygonOffset; + var enabled = polygonOffset.enabled; + + enableOrDisable(gl, gl.POLYGON_OFFSET_FILL, enabled); + + if (enabled) { + gl.polygonOffset(polygonOffset.factor, polygonOffset.units); + } + } + + function applyScissorTest(gl, renderState, passState) { + var scissorTest = renderState.scissorTest; + var enabled = (defined(passState.scissorTest)) ? passState.scissorTest.enabled : scissorTest.enabled; + + enableOrDisable(gl, gl.SCISSOR_TEST, enabled); + + if (enabled) { + var rectangle = (defined(passState.scissorTest)) ? passState.scissorTest.rectangle : scissorTest.rectangle; + gl.scissor(rectangle.x, rectangle.y, rectangle.width, rectangle.height); + } + } + + function applyDepthRange(gl, renderState) { + var depthRange = renderState.depthRange; + gl.depthRange(depthRange.near, depthRange.far); + } + + function applyDepthTest(gl, renderState) { + var depthTest = renderState.depthTest; + var enabled = depthTest.enabled; + + enableOrDisable(gl, gl.DEPTH_TEST, enabled); + + if (enabled) { + gl.depthFunc(depthTest.func); + } + } + + function applyColorMask(gl, renderState) { + var colorMask = renderState.colorMask; + gl.colorMask(colorMask.red, colorMask.green, colorMask.blue, colorMask.alpha); + } + + function applyDepthMask(gl, renderState) { + gl.depthMask(renderState.depthMask); + } + + function applyStencilMask(gl, renderState) { + gl.stencilMask(renderState.stencilMask); + } + + function applyBlendingColor(gl, color) { + gl.blendColor(color.red, color.green, color.blue, color.alpha); + } + + function applyBlending(gl, renderState, passState) { + var blending = renderState.blending; + var enabled = (defined(passState.blendingEnabled)) ? passState.blendingEnabled : blending.enabled; + + enableOrDisable(gl, gl.BLEND, enabled); + + if (enabled) { + applyBlendingColor(gl, blending.color); + gl.blendEquationSeparate(blending.equationRgb, blending.equationAlpha); + gl.blendFuncSeparate(blending.functionSourceRgb, blending.functionDestinationRgb, blending.functionSourceAlpha, blending.functionDestinationAlpha); + } + } + + function applyStencilTest(gl, renderState) { + var stencilTest = renderState.stencilTest; + var enabled = stencilTest.enabled; + + enableOrDisable(gl, gl.STENCIL_TEST, enabled); + + if (enabled) { + var frontFunction = stencilTest.frontFunction; + var backFunction = stencilTest.backFunction; + var reference = stencilTest.reference; + var mask = stencilTest.mask; + + // Section 6.8 of the WebGL spec requires the reference and masks to be the same for + // front- and back-face tests. This call prevents invalid operation errors when calling + // stencilFuncSeparate on Firefox. Perhaps they should delay validation to avoid requiring this. + gl.stencilFunc(frontFunction, reference, mask); + gl.stencilFuncSeparate(gl.BACK, backFunction, reference, mask); + gl.stencilFuncSeparate(gl.FRONT, frontFunction, reference, mask); + + var frontOperation = stencilTest.frontOperation; + var frontOperationFail = frontOperation.fail; + var frontOperationZFail = frontOperation.zFail; + var frontOperationZPass = frontOperation.zPass; + + gl.stencilOpSeparate(gl.FRONT, frontOperationFail, frontOperationZFail, frontOperationZPass); + + var backOperation = stencilTest.backOperation; + var backOperationFail = backOperation.fail; + var backOperationZFail = backOperation.zFail; + var backOperationZPass = backOperation.zPass; + + gl.stencilOpSeparate(gl.BACK, backOperationFail, backOperationZFail, backOperationZPass); + } + } + + function applySampleCoverage(gl, renderState) { + var sampleCoverage = renderState.sampleCoverage; + var enabled = sampleCoverage.enabled; + + enableOrDisable(gl, gl.SAMPLE_COVERAGE, enabled); + + if (enabled) { + gl.sampleCoverage(sampleCoverage.value, sampleCoverage.invert); + } + } + + var scratchViewport = new BoundingRectangle(); + + function applyViewport(gl, renderState, passState) { + var viewport = defaultValue(renderState.viewport, passState.viewport); + if (!defined(viewport)) { + viewport = scratchViewport; + viewport.width = passState.context.drawingBufferWidth; + viewport.height = passState.context.drawingBufferHeight; + } + + passState.context.uniformState.viewport = viewport; + gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + } + + RenderState.apply = function(gl, renderState, passState) { + applyFrontFace(gl, renderState); + applyCull(gl, renderState); + applyLineWidth(gl, renderState); + applyPolygonOffset(gl, renderState); + applyDepthRange(gl, renderState); + applyDepthTest(gl, renderState); + applyColorMask(gl, renderState); + applyDepthMask(gl, renderState); + applyStencilMask(gl, renderState); + applyStencilTest(gl, renderState); + applySampleCoverage(gl, renderState); + applyScissorTest(gl, renderState, passState); + applyBlending(gl, renderState, passState); + applyViewport(gl, renderState, passState); + }; + + function createFuncs(previousState, nextState) { + var funcs = []; + + if (previousState.frontFace !== nextState.frontFace) { + funcs.push(applyFrontFace); + } + + if ((previousState.cull.enabled !== nextState.cull.enabled) || (previousState.cull.face !== nextState.cull.face)) { + funcs.push(applyCull); + } + + if (previousState.lineWidth !== nextState.lineWidth) { + funcs.push(applyLineWidth); + } + + if ((previousState.polygonOffset.enabled !== nextState.polygonOffset.enabled) || + (previousState.polygonOffset.factor !== nextState.polygonOffset.factor) || + (previousState.polygonOffset.units !== nextState.polygonOffset.units)) { + funcs.push(applyPolygonOffset); + } + + if ((previousState.depthRange.near !== nextState.depthRange.near) || (previousState.depthRange.far !== nextState.depthRange.far)) { + funcs.push(applyDepthRange); + } + + if ((previousState.depthTest.enabled !== nextState.depthTest.enabled) || (previousState.depthTest.func !== nextState.depthTest.func)) { + funcs.push(applyDepthTest); + } + + if ((previousState.colorMask.red !== nextState.colorMask.red) || + (previousState.colorMask.green !== nextState.colorMask.green) || + (previousState.colorMask.blue !== nextState.colorMask.blue) || + (previousState.colorMask.alpha !== nextState.colorMask.alpha)) { + funcs.push(applyColorMask); + } + + if (previousState.depthMask !== nextState.depthMask) { + funcs.push(applyDepthMask); + } + + if (previousState.stencilMask !== nextState.stencilMask) { + funcs.push(applyStencilMask); + } + + if ((previousState.stencilTest.enabled !== nextState.stencilTest.enabled) || + (previousState.stencilTest.frontFunction !== nextState.stencilTest.frontFunction) || + (previousState.stencilTest.backFunction !== nextState.stencilTest.backFunction) || + (previousState.stencilTest.reference !== nextState.stencilTest.reference) || + (previousState.stencilTest.mask !== nextState.stencilTest.mask) || + (previousState.stencilTest.frontOperation.fail !== nextState.stencilTest.frontOperation.fail) || + (previousState.stencilTest.frontOperation.zFail !== nextState.stencilTest.frontOperation.zFail) || + (previousState.stencilTest.backOperation.fail !== nextState.stencilTest.backOperation.fail) || + (previousState.stencilTest.backOperation.zFail !== nextState.stencilTest.backOperation.zFail) || + (previousState.stencilTest.backOperation.zPass !== nextState.stencilTest.backOperation.zPass)) { + funcs.push(applyStencilTest); + } + + if ((previousState.sampleCoverage.enabled !== nextState.sampleCoverage.enabled) || + (previousState.sampleCoverage.value !== nextState.sampleCoverage.value) || + (previousState.sampleCoverage.invert !== nextState.sampleCoverage.invert)) { + funcs.push(applySampleCoverage); + } + + return funcs; + } + + RenderState.partialApply = function(gl, previousRenderState, renderState, previousPassState, passState, clear) { + if (previousRenderState !== renderState) { + // When a new render state is applied, instead of making WebGL calls for all the states or first + // comparing the states one-by-one with the previous state (basically a linear search), we take + // advantage of RenderState's immutability, and store a dynamically populated sparse data structure + // containing functions that make the minimum number of WebGL calls when transitioning from one state + // to the other. In practice, this works well since state-to-state transitions generally only require a + // few WebGL calls, especially if commands are stored by state. + var funcs = renderState._applyFunctions[previousRenderState.id]; + if (!defined(funcs)) { + funcs = createFuncs(previousRenderState, renderState); + renderState._applyFunctions[previousRenderState.id] = funcs; + } + + var len = funcs.length; + for (var i = 0; i < len; ++i) { + funcs[i](gl, renderState); + } + } + + var previousScissorTest = (defined(previousPassState.scissorTest)) ? previousPassState.scissorTest : previousRenderState.scissorTest; + var scissorTest = (defined(passState.scissorTest)) ? passState.scissorTest : renderState.scissorTest; + + // Our scissor rectangle can get out of sync with the GL scissor rectangle on clears. + // Seems to be a problem only on ANGLE. See https://github.com/AnalyticalGraphicsInc/cesium/issues/2994 + if ((previousScissorTest !== scissorTest) || clear) { + applyScissorTest(gl, renderState, passState); + } + + var previousBlendingEnabled = (defined(previousPassState.blendingEnabled)) ? previousPassState.blendingEnabled : previousRenderState.blending.enabled; + var blendingEnabled = (defined(passState.blendingEnabled)) ? passState.blendingEnabled : renderState.blending.enabled; + if ((previousBlendingEnabled !== blendingEnabled) || + (blendingEnabled && (previousRenderState.blending !== renderState.blending))) { + applyBlending(gl, renderState, passState); + } + + if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { + applyViewport(gl, renderState, passState); + } + }; + + RenderState.getState = function(renderState) { + if (!defined(renderState)) { + throw new DeveloperError('renderState is required.'); + } + + return { + frontFace : renderState.frontFace, + cull : { + enabled : renderState.cull.enabled, + face : renderState.cull.face + }, + lineWidth : renderState.lineWidth, + polygonOffset : { + enabled : renderState.polygonOffset.enabled, + factor : renderState.polygonOffset.factor, + units : renderState.polygonOffset.units + }, + scissorTest : { + enabled : renderState.scissorTest.enabled, + rectangle : BoundingRectangle.clone(renderState.scissorTest.rectangle) + }, + depthRange : { + near : renderState.depthRange.near, + far : renderState.depthRange.far + }, + depthTest : { + enabled : renderState.depthTest.enabled, + func : renderState.depthTest.func + }, + colorMask : { + red : renderState.colorMask.red, + green : renderState.colorMask.green, + blue : renderState.colorMask.blue, + alpha : renderState.colorMask.alpha + }, + depthMask : renderState.depthMask, + stencilMask : renderState.stencilMask, + blending : { + enabled : renderState.blending.enabled, + color : Color.clone(renderState.blending.color), + equationRgb : renderState.blending.equationRgb, + equationAlpha : renderState.blending.equationAlpha, + functionSourceRgb : renderState.blending.functionSourceRgb, + functionSourceAlpha : renderState.blending.functionSourceAlpha, + functionDestinationRgb : renderState.blending.functionDestinationRgb, + functionDestinationAlpha : renderState.blending.functionDestinationAlpha + }, + stencilTest : { + enabled : renderState.stencilTest.enabled, + frontFunction : renderState.stencilTest.frontFunction, + backFunction : renderState.stencilTest.backFunction, + reference : renderState.stencilTest.reference, + mask : renderState.stencilTest.mask, + frontOperation : { + fail : renderState.stencilTest.frontOperation.fail, + zFail : renderState.stencilTest.frontOperation.zFail, + zPass : renderState.stencilTest.frontOperation.zPass + }, + backOperation : { + fail : renderState.stencilTest.backOperation.fail, + zFail : renderState.stencilTest.backOperation.zFail, + zPass : renderState.stencilTest.backOperation.zPass + } + }, + sampleCoverage : { + enabled : renderState.sampleCoverage.enabled, + value : renderState.sampleCoverage.value, + invert : renderState.sampleCoverage.invert + }, + viewport : defined(renderState.viewport) ? BoundingRectangle.clone(renderState.viewport) : undefined + }; + }; + + return RenderState; +}); + +define('Renderer/AutomaticUniforms',[ + '../Core/Cartesian3', + '../Core/Matrix4', + '../Core/WebGLConstants' + ], function( + Cartesian3, + Matrix4, + WebGLConstants) { + 'use strict'; + /*global WebGLRenderingContext*/ + + var viewerPositionWCScratch = new Cartesian3(); + + function AutomaticUniform(options) { + this._size = options.size; + this._datatype = options.datatype; + this.getValue = options.getValue; + } + + // this check must use typeof, not defined, because defined doesn't work with undeclared variables. + if (typeof WebGLRenderingContext === 'undefined') { + return {}; + } + + var datatypeToGlsl = {}; + datatypeToGlsl[WebGLConstants.FLOAT] = 'float'; + datatypeToGlsl[WebGLConstants.FLOAT_VEC2] = 'vec2'; + datatypeToGlsl[WebGLConstants.FLOAT_VEC3] = 'vec3'; + datatypeToGlsl[WebGLConstants.FLOAT_VEC4] = 'vec4'; + datatypeToGlsl[WebGLConstants.INT] = 'int'; + datatypeToGlsl[WebGLConstants.INT_VEC2] = 'ivec2'; + datatypeToGlsl[WebGLConstants.INT_VEC3] = 'ivec3'; + datatypeToGlsl[WebGLConstants.INT_VEC4] = 'ivec4'; + datatypeToGlsl[WebGLConstants.BOOL] = 'bool'; + datatypeToGlsl[WebGLConstants.BOOL_VEC2] = 'bvec2'; + datatypeToGlsl[WebGLConstants.BOOL_VEC3] = 'bvec3'; + datatypeToGlsl[WebGLConstants.BOOL_VEC4] = 'bvec4'; + datatypeToGlsl[WebGLConstants.FLOAT_MAT2] = 'mat2'; + datatypeToGlsl[WebGLConstants.FLOAT_MAT3] = 'mat3'; + datatypeToGlsl[WebGLConstants.FLOAT_MAT4] = 'mat4'; + datatypeToGlsl[WebGLConstants.SAMPLER_2D] = 'sampler2D'; + datatypeToGlsl[WebGLConstants.SAMPLER_CUBE] = 'samplerCube'; + + AutomaticUniform.prototype.getDeclaration = function(name) { + var declaration = 'uniform ' + datatypeToGlsl[this._datatype] + ' ' + name; + + var size = this._size; + if (size === 1) { + declaration += ';'; + } else { + declaration += '[' + size.toString() + '];'; + } + + return declaration; + }; + + /** + * @private + */ + var AutomaticUniforms = { + /** + * An automatic GLSL uniform containing the viewport's <code>x</code>, <code>y</code>, <code>width</code>, + * and <code>height</code> properties in an <code>vec4</code>'s <code>x</code>, <code>y</code>, <code>z</code>, + * and <code>w</code> components, respectively. + * + * @alias czm_viewport + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec4 czm_viewport; + * + * // Scale the window coordinate components to [0, 1] by dividing + * // by the viewport's width and height. + * vec2 v = gl_FragCoord.xy / czm_viewport.zw; + * + * @see Context#getViewport + */ + czm_viewport : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC4, + getValue : function(uniformState) { + return uniformState.viewportCartesian4; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 orthographic projection matrix that + * transforms window coordinates to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * <br /><br /> + * This transform is useful when a vertex shader inputs or manipulates window coordinates + * as done by {@link BillboardCollection}. + * <br /><br /> + * Do not confuse {@link czm_viewportTransformation} with <code>czm_viewportOrthographic</code>. + * The former transforms from normalized device coordinates to window coordinates; the later transforms + * from window coordinates to clip coordinates, and is often used to assign to <code>gl_Position</code>. + * + * @alias czm_viewportOrthographic + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_viewportOrthographic; + * + * // Example + * gl_Position = czm_viewportOrthographic * vec4(windowPosition, 0.0, 1.0); + * + * @see UniformState#viewportOrthographic + * @see czm_viewport + * @see czm_viewportTransformation + * @see BillboardCollection + */ + czm_viewportOrthographic : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.viewportOrthographic; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 transformation matrix that + * transforms normalized device coordinates to window coordinates. The context's + * full viewport is used, and the depth range is assumed to be <code>near = 0</code> + * and <code>far = 1</code>. + * <br /><br /> + * This transform is useful when there is a need to manipulate window coordinates + * in a vertex shader as done by {@link BillboardCollection}. In many cases, + * this matrix will not be used directly; instead, {@link czm_modelToWindowCoordinates} + * will be used to transform directly from model to window coordinates. + * <br /><br /> + * Do not confuse <code>czm_viewportTransformation</code> with {@link czm_viewportOrthographic}. + * The former transforms from normalized device coordinates to window coordinates; the later transforms + * from window coordinates to clip coordinates, and is often used to assign to <code>gl_Position</code>. + * + * @alias czm_viewportTransformation + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_viewportTransformation; + * + * // Use czm_viewportTransformation as part of the + * // transform from model to window coordinates. + * vec4 q = czm_modelViewProjection * positionMC; // model to clip coordinates + * q.xyz /= q.w; // clip to normalized device coordinates (ndc) + * q.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz; // ndc to window coordinates + * + * @see UniformState#viewportTransformation + * @see czm_viewport + * @see czm_viewportOrthographic + * @see czm_modelToWindowCoordinates + * @see BillboardCollection + */ + czm_viewportTransformation : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.viewportTransformation; + } + }), + + /** + * An automatic GLSL uniform representing the depth after + * only the globe has been rendered and packed into an RGBA texture. + * + * @private + * + * @alias czm_globeDepthTexture + * @glslUniform + * + * @example + * // GLSL declaration + * uniform sampler2D czm_globeDepthTexture; + * + * // Get the depth at the current fragment + * vec2 coords = gl_FragCoord.xy / czm_viewport.zw; + * float depth = czm_unpackDepth(texture2D(czm_globeDepthTexture, coords)); + */ + czm_globeDepthTexture : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.SAMPLER_2D, + getValue : function(uniformState) { + return uniformState.globeDepthTexture; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model transformation matrix that + * transforms model coordinates to world coordinates. + * + * @alias czm_model + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_model; + * + * // Example + * vec4 worldPosition = czm_model * modelPosition; + * + * @see UniformState#model + * @see czm_inverseModel + * @see czm_modelView + * @see czm_modelViewProjection + */ + czm_model : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.model; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model transformation matrix that + * transforms world coordinates to model coordinates. + * + * @alias czm_inverseModel + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseModel; + * + * // Example + * vec4 modelPosition = czm_inverseModel * worldPosition; + * + * @see UniformState#inverseModel + * @see czm_model + * @see czm_inverseModelView + */ + czm_inverseModel : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseModel; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 view transformation matrix that + * transforms world coordinates to eye coordinates. + * + * @alias czm_view + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_view; + * + * // Example + * vec4 eyePosition = czm_view * worldPosition; + * + * @see UniformState#view + * @see czm_viewRotation + * @see czm_modelView + * @see czm_viewProjection + * @see czm_modelViewProjection + * @see czm_inverseView + */ + czm_view : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.view; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 view transformation matrix that + * transforms 3D world coordinates to eye coordinates. In 3D mode, this is identical to + * {@link czm_view}, but in 2D and Columbus View it represents the view matrix + * as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * + * @alias czm_view3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_view3D; + * + * // Example + * vec4 eyePosition3D = czm_view3D * worldPosition3D; + * + * @see UniformState#view3D + * @see czm_view + */ + czm_view3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.view3D; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 view rotation matrix that + * transforms vectors in world coordinates to eye coordinates. + * + * @alias czm_viewRotation + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_viewRotation; + * + * // Example + * vec3 eyeVector = czm_viewRotation * worldVector; + * + * @see UniformState#viewRotation + * @see czm_view + * @see czm_inverseView + * @see czm_inverseViewRotation + */ + czm_viewRotation : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.viewRotation; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 view rotation matrix that + * transforms vectors in 3D world coordinates to eye coordinates. In 3D mode, this is identical to + * {@link czm_viewRotation}, but in 2D and Columbus View it represents the view matrix + * as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * + * @alias czm_viewRotation3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_viewRotation3D; + * + * // Example + * vec3 eyeVector = czm_viewRotation3D * worldVector; + * + * @see UniformState#viewRotation3D + * @see czm_viewRotation + */ + czm_viewRotation3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.viewRotation3D; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 transformation matrix that + * transforms from eye coordinates to world coordinates. + * + * @alias czm_inverseView + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseView; + * + * // Example + * vec4 worldPosition = czm_inverseView * eyePosition; + * + * @see UniformState#inverseView + * @see czm_view + * @see czm_inverseNormal + */ + czm_inverseView : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseView; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 transformation matrix that + * transforms from 3D eye coordinates to world coordinates. In 3D mode, this is identical to + * {@link czm_inverseView}, but in 2D and Columbus View it represents the inverse view matrix + * as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * + * @alias czm_inverseView3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseView3D; + * + * // Example + * vec4 worldPosition = czm_inverseView3D * eyePosition; + * + * @see UniformState#inverseView3D + * @see czm_inverseView + */ + czm_inverseView3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseView3D; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 rotation matrix that + * transforms vectors from eye coordinates to world coordinates. + * + * @alias czm_inverseViewRotation + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_inverseViewRotation; + * + * // Example + * vec4 worldVector = czm_inverseViewRotation * eyeVector; + * + * @see UniformState#inverseView + * @see czm_view + * @see czm_viewRotation + * @see czm_inverseViewRotation + */ + czm_inverseViewRotation : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.inverseViewRotation; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 rotation matrix that + * transforms vectors from 3D eye coordinates to world coordinates. In 3D mode, this is identical to + * {@link czm_inverseViewRotation}, but in 2D and Columbus View it represents the inverse view matrix + * as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * + * @alias czm_inverseViewRotation3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_inverseViewRotation3D; + * + * // Example + * vec4 worldVector = czm_inverseViewRotation3D * eyeVector; + * + * @see UniformState#inverseView3D + * @see czm_inverseViewRotation + */ + czm_inverseViewRotation3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.inverseViewRotation3D; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 projection transformation matrix that + * transforms eye coordinates to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * + * @alias czm_projection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_projection; + * + * // Example + * gl_Position = czm_projection * eyePosition; + * + * @see UniformState#projection + * @see czm_viewProjection + * @see czm_modelViewProjection + * @see czm_infiniteProjection + */ + czm_projection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.projection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 inverse projection transformation matrix that + * transforms from clip coordinates to eye coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * + * @alias czm_inverseProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseProjection; + * + * // Example + * vec4 eyePosition = czm_inverseProjection * clipPosition; + * + * @see UniformState#inverseProjection + * @see czm_projection + */ + czm_inverseProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 projection transformation matrix with the far plane at infinity, + * that transforms eye coordinates to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. An infinite far plane is used + * in algorithms like shadow volumes and GPU ray casting with proxy geometry to ensure that triangles + * are not clipped by the far plane. + * + * @alias czm_infiniteProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_infiniteProjection; + * + * // Example + * gl_Position = czm_infiniteProjection * eyePosition; + * + * @see UniformState#infiniteProjection + * @see czm_projection + * @see czm_modelViewInfiniteProjection + */ + czm_infiniteProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.infiniteProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model-view transformation matrix that + * transforms model coordinates to eye coordinates. + * <br /><br /> + * Positions should be transformed to eye coordinates using <code>czm_modelView</code> and + * normals should be transformed using {@link czm_normal}. + * + * @alias czm_modelView + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_modelView; + * + * // Example + * vec4 eyePosition = czm_modelView * modelPosition; + * + * // The above is equivalent to, but more efficient than: + * vec4 eyePosition = czm_view * czm_model * modelPosition; + * + * @see UniformState#modelView + * @see czm_model + * @see czm_view + * @see czm_modelViewProjection + * @see czm_normal + */ + czm_modelView : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.modelView; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model-view transformation matrix that + * transforms 3D model coordinates to eye coordinates. In 3D mode, this is identical to + * {@link czm_modelView}, but in 2D and Columbus View it represents the model-view matrix + * as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * <br /><br /> + * Positions should be transformed to eye coordinates using <code>czm_modelView3D</code> and + * normals should be transformed using {@link czm_normal3D}. + * + * @alias czm_modelView3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_modelView3D; + * + * // Example + * vec4 eyePosition = czm_modelView3D * modelPosition; + * + * // The above is equivalent to, but more efficient than: + * vec4 eyePosition = czm_view3D * czm_model * modelPosition; + * + * @see UniformState#modelView3D + * @see czm_modelView + */ + czm_modelView3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.modelView3D; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model-view transformation matrix that + * transforms model coordinates, relative to the eye, to eye coordinates. This is used + * in conjunction with {@link czm_translateRelativeToEye}. + * + * @alias czm_modelViewRelativeToEye + * @glslUniform + * + * @example + * // GLSL declaration + * uniform mat4 czm_modelViewRelativeToEye; + * + * // Example + * attribute vec3 positionHigh; + * attribute vec3 positionLow; + * + * void main() + * { + * vec4 p = czm_translateRelativeToEye(positionHigh, positionLow); + * gl_Position = czm_projection * (czm_modelViewRelativeToEye * p); + * } + * + * @see czm_modelViewProjectionRelativeToEye + * @see czm_translateRelativeToEye + * @see EncodedCartesian3 + */ + czm_modelViewRelativeToEye : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.modelViewRelativeToEye; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 transformation matrix that + * transforms from eye coordinates to model coordinates. + * + * @alias czm_inverseModelView + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseModelView; + * + * // Example + * vec4 modelPosition = czm_inverseModelView * eyePosition; + * + * @see UniformState#inverseModelView + * @see czm_modelView + */ + czm_inverseModelView : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseModelView; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 transformation matrix that + * transforms from eye coordinates to 3D model coordinates. In 3D mode, this is identical to + * {@link czm_inverseModelView}, but in 2D and Columbus View it represents the inverse model-view matrix + * as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * + * @alias czm_inverseModelView3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseModelView3D; + * + * // Example + * vec4 modelPosition = czm_inverseModelView3D * eyePosition; + * + * @see UniformState#inverseModelView + * @see czm_inverseModelView + * @see czm_modelView3D + */ + czm_inverseModelView3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseModelView3D; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 view-projection transformation matrix that + * transforms world coordinates to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * + * @alias czm_viewProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_viewProjection; + * + * // Example + * vec4 gl_Position = czm_viewProjection * czm_model * modelPosition; + * + * // The above is equivalent to, but more efficient than: + * gl_Position = czm_projection * czm_view * czm_model * modelPosition; + * + * @see UniformState#viewProjection + * @see czm_view + * @see czm_projection + * @see czm_modelViewProjection + * @see czm_inverseViewProjection + */ + czm_viewProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.viewProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 view-projection transformation matrix that + * transforms clip coordinates to world coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * + * @alias czm_inverseViewProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseViewProjection; + * + * // Example + * vec4 worldPosition = czm_inverseViewProjection * clipPosition; + * + * @see UniformState#inverseViewProjection + * @see czm_viewProjection + */ + czm_inverseViewProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseViewProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model-view-projection transformation matrix that + * transforms model coordinates to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * + * @alias czm_modelViewProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_modelViewProjection; + * + * // Example + * vec4 gl_Position = czm_modelViewProjection * modelPosition; + * + * // The above is equivalent to, but more efficient than: + * gl_Position = czm_projection * czm_view * czm_model * modelPosition; + * + * @see UniformState#modelViewProjection + * @see czm_model + * @see czm_view + * @see czm_projection + * @see czm_modelView + * @see czm_viewProjection + * @see czm_modelViewInfiniteProjection + * @see czm_inverseModelViewProjection + */ + czm_modelViewProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.modelViewProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 inverse model-view-projection transformation matrix that + * transforms clip coordinates to model coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. + * + * @alias czm_inverseModelViewProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_inverseModelViewProjection; + * + * // Example + * vec4 modelPosition = czm_inverseModelViewProjection * clipPosition; + * + * @see UniformState#modelViewProjection + * @see czm_modelViewProjection + */ + czm_inverseModelViewProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.inverseModelViewProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model-view-projection transformation matrix that + * transforms model coordinates, relative to the eye, to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. This is used in + * conjunction with {@link czm_translateRelativeToEye}. + * + * @alias czm_modelViewProjectionRelativeToEye + * @glslUniform + * + * @example + * // GLSL declaration + * uniform mat4 czm_modelViewProjectionRelativeToEye; + * + * // Example + * attribute vec3 positionHigh; + * attribute vec3 positionLow; + * + * void main() + * { + * vec4 p = czm_translateRelativeToEye(positionHigh, positionLow); + * gl_Position = czm_modelViewProjectionRelativeToEye * p; + * } + * + * @see czm_modelViewRelativeToEye + * @see czm_translateRelativeToEye + * @see EncodedCartesian3 + */ + czm_modelViewProjectionRelativeToEye : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.modelViewProjectionRelativeToEye; + } + }), + + /** + * An automatic GLSL uniform representing a 4x4 model-view-projection transformation matrix that + * transforms model coordinates to clip coordinates. Clip coordinates is the + * coordinate system for a vertex shader's <code>gl_Position</code> output. The projection matrix places + * the far plane at infinity. This is useful in algorithms like shadow volumes and GPU ray casting with + * proxy geometry to ensure that triangles are not clipped by the far plane. + * + * @alias czm_modelViewInfiniteProjection + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat4 czm_modelViewInfiniteProjection; + * + * // Example + * vec4 gl_Position = czm_modelViewInfiniteProjection * modelPosition; + * + * // The above is equivalent to, but more efficient than: + * gl_Position = czm_infiniteProjection * czm_view * czm_model * modelPosition; + * + * @see UniformState#modelViewInfiniteProjection + * @see czm_model + * @see czm_view + * @see czm_infiniteProjection + * @see czm_modelViewProjection + */ + czm_modelViewInfiniteProjection : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT4, + getValue : function(uniformState) { + return uniformState.modelViewInfiniteProjection; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 normal transformation matrix that + * transforms normal vectors in model coordinates to eye coordinates. + * <br /><br /> + * Positions should be transformed to eye coordinates using {@link czm_modelView} and + * normals should be transformed using <code>czm_normal</code>. + * + * @alias czm_normal + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_normal; + * + * // Example + * vec3 eyeNormal = czm_normal * normal; + * + * @see UniformState#normal + * @see czm_inverseNormal + * @see czm_modelView + */ + czm_normal : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.normal; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 normal transformation matrix that + * transforms normal vectors in 3D model coordinates to eye coordinates. + * In 3D mode, this is identical to + * {@link czm_normal}, but in 2D and Columbus View it represents the normal transformation + * matrix as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * <br /><br /> + * Positions should be transformed to eye coordinates using {@link czm_modelView3D} and + * normals should be transformed using <code>czm_normal3D</code>. + * + * @alias czm_normal3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_normal3D; + * + * // Example + * vec3 eyeNormal = czm_normal3D * normal; + * + * @see UniformState#normal3D + * @see czm_normal + */ + czm_normal3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.normal3D; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 normal transformation matrix that + * transforms normal vectors in eye coordinates to model coordinates. This is + * the opposite of the transform provided by {@link czm_normal}. + * + * @alias czm_inverseNormal + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_inverseNormal; + * + * // Example + * vec3 normalMC = czm_inverseNormal * normalEC; + * + * @see UniformState#inverseNormal + * @see czm_normal + * @see czm_modelView + * @see czm_inverseView + */ + czm_inverseNormal : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.inverseNormal; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 normal transformation matrix that + * transforms normal vectors in eye coordinates to 3D model coordinates. This is + * the opposite of the transform provided by {@link czm_normal}. + * In 3D mode, this is identical to + * {@link czm_inverseNormal}, but in 2D and Columbus View it represents the inverse normal transformation + * matrix as if the camera were at an equivalent location in 3D mode. This is useful for lighting + * 2D and Columbus View in the same way that 3D is lit. + * + * @alias czm_inverseNormal3D + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_inverseNormal3D; + * + * // Example + * vec3 normalMC = czm_inverseNormal3D * normalEC; + * + * @see UniformState#inverseNormal3D + * @see czm_inverseNormal + */ + czm_inverseNormal3D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.inverseNormal3D; + } + }), + + /** + * An automatic GLSL uniform containing height (<code>x</code>) and height squared (<code>y</code>) + * of the eye (camera) in the 2D scene in meters. + * + * @alias czm_eyeHeight2D + * @glslUniform + * + * @see UniformState#eyeHeight2D + */ + czm_eyeHeight2D : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC2, + getValue : function(uniformState) { + return uniformState.eyeHeight2D; + } + }), + + /** + * An automatic GLSL uniform containing the near distance (<code>x</code>) and the far distance (<code>y</code>) + * of the frustum defined by the camera. This is the largest possible frustum, not an individual + * frustum used for multi-frustum rendering. + * + * @alias czm_entireFrustum + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec2 czm_entireFrustum; + * + * // Example + * float frustumLength = czm_entireFrustum.y - czm_entireFrustum.x; + * + * @see UniformState#entireFrustum + * @see czm_currentFrustum + */ + czm_entireFrustum : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC2, + getValue : function(uniformState) { + return uniformState.entireFrustum; + } + }), + + /** + * An automatic GLSL uniform containing the near distance (<code>x</code>) and the far distance (<code>y</code>) + * of the frustum defined by the camera. This is the individual + * frustum used for multi-frustum rendering. + * + * @alias czm_currentFrustum + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec2 czm_currentFrustum; + * + * // Example + * float frustumLength = czm_currentFrustum.y - czm_currentFrustum.x; + * + * @see UniformState#currentFrustum + * @see czm_entireFrustum + */ + czm_currentFrustum : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC2, + getValue : function(uniformState) { + return uniformState.currentFrustum; + } + }), + + /** + * The distances to the frustum planes. The top, bottom, left and right distances are + * the x, y, z, and w components, respectively. + * + * @alias czm_frustumPlanes + * @glslUniform + */ + czm_frustumPlanes : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC4, + getValue : function(uniformState) { + return uniformState.frustumPlanes; + } + }), + + /** + * An automatic GLSL uniform representing the sun position in world coordinates. + * + * @alias czm_sunPositionWC + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_sunPositionWC; + * + * @see UniformState#sunPositionWC + * @see czm_sunPositionColumbusView + * @see czm_sunDirectionWC + */ + czm_sunPositionWC : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.sunPositionWC; + } + }), + + /** + * An automatic GLSL uniform representing the sun position in Columbus view world coordinates. + * + * @alias czm_sunPositionColumbusView + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_sunPositionColumbusView; + * + * @see UniformState#sunPositionColumbusView + * @see czm_sunPositionWC + */ + czm_sunPositionColumbusView : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.sunPositionColumbusView; + } + }), + + /** + * An automatic GLSL uniform representing the normalized direction to the sun in eye coordinates. + * This is commonly used for directional lighting computations. + * + * @alias czm_sunDirectionEC + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_sunDirectionEC; + * + * // Example + * float diffuse = max(dot(czm_sunDirectionEC, normalEC), 0.0); + * + * @see UniformState#sunDirectionEC + * @see czm_moonDirectionEC + * @see czm_sunDirectionWC + */ + czm_sunDirectionEC : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.sunDirectionEC; + } + }), + + /** + * An automatic GLSL uniform representing the normalized direction to the sun in world coordinates. + * This is commonly used for directional lighting computations. + * + * @alias czm_sunDirectionWC + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_sunDirectionWC; + * + * @see UniformState#sunDirectionWC + * @see czm_sunPositionWC + * @see czm_sunDirectionEC + */ + czm_sunDirectionWC : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.sunDirectionWC; + } + }), + + /** + * An automatic GLSL uniform representing the normalized direction to the moon in eye coordinates. + * This is commonly used for directional lighting computations. + * + * @alias czm_moonDirectionEC + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_moonDirectionEC; + * + * // Example + * float diffuse = max(dot(czm_moonDirectionEC, normalEC), 0.0); + * + * @see UniformState#moonDirectionEC + * @see czm_sunDirectionEC + */ + czm_moonDirectionEC : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.moonDirectionEC; + } + }), + + /** + * An automatic GLSL uniform representing the high bits of the camera position in model + * coordinates. This is used for GPU RTE to eliminate jittering artifacts when rendering + * as described in {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. + * + * @alias czm_encodedCameraPositionMCHigh + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_encodedCameraPositionMCHigh; + * + * @see czm_encodedCameraPositionMCLow + * @see czm_modelViewRelativeToEye + * @see czm_modelViewProjectionRelativeToEye + */ + czm_encodedCameraPositionMCHigh : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.encodedCameraPositionMCHigh; + } + }), + + /** + * An automatic GLSL uniform representing the low bits of the camera position in model + * coordinates. This is used for GPU RTE to eliminate jittering artifacts when rendering + * as described in {@link http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/|Precisions, Precisions}. + * + * @alias czm_encodedCameraPositionMCLow + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform vec3 czm_encodedCameraPositionMCLow; + * + * @see czm_encodedCameraPositionMCHigh + * @see czm_modelViewRelativeToEye + * @see czm_modelViewProjectionRelativeToEye + */ + czm_encodedCameraPositionMCLow : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return uniformState.encodedCameraPositionMCLow; + } + }), + + /** + * An automatic GLSL uniform representing the position of the viewer (camera) in world coordinates. + * + * @alias czm_viewerPositionWC + * @glslUniform + * + * @example + * // GLSL declaration + * uniform vec3 czm_viewerPositionWC; + */ + czm_viewerPositionWC : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC3, + getValue : function(uniformState) { + return Matrix4.getTranslation(uniformState.inverseView, viewerPositionWCScratch); + } + }), + + /** + * An automatic GLSL uniform representing the frame number. This uniform is automatically incremented + * every frame. + * + * @alias czm_frameNumber + * @glslUniform + * + * @example + * // GLSL declaration + * uniform float czm_frameNumber; + */ + czm_frameNumber : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.frameState.frameNumber; + } + }), + + /** + * An automatic GLSL uniform representing the current morph transition time between + * 2D/Columbus View and 3D, with 0.0 being 2D or Columbus View and 1.0 being 3D. + * + * @alias czm_morphTime + * @glslUniform + * + * @example + * // GLSL declaration + * uniform float czm_morphTime; + * + * // Example + * vec4 p = czm_columbusViewMorph(position2D, position3D, czm_morphTime); + */ + czm_morphTime : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.frameState.morphTime; + } + }), + + /** + * An automatic GLSL uniform representing the current {@link SceneMode}, expressed + * as a float. + * + * @alias czm_sceneMode + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform float czm_sceneMode; + * + * // Example + * if (czm_sceneMode == czm_sceneMode2D) + * { + * eyeHeightSq = czm_eyeHeight2D.y; + * } + * + * @see czm_sceneMode2D + * @see czm_sceneModeColumbusView + * @see czm_sceneMode3D + * @see czm_sceneModeMorphing + */ + czm_sceneMode : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.frameState.mode; + } + }), + + /** + * An automatic GLSL uniform representing the current rendering pass. + * + * @alias czm_pass + * @glslUniform + * + * @example + * // GLSL declaration + * uniform float czm_pass; + * + * // Example + * if ((czm_pass == czm_passTranslucent) && isOpaque()) + * { + * gl_Position *= 0.0; // Cull opaque geometry in the translucent pass + * } + */ + czm_pass : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.pass; + } + }), + + /** + * An automatic GLSL uniform representing the current scene background color. + * + * @alias czm_backgroundColor + * @glslUniform + * + * @example + * // GLSL declaration + * uniform vec4 czm_backgroundColor; + * + * // Example: If the given color's RGB matches the background color, invert it. + * vec4 adjustColorForContrast(vec4 color) + * { + * if (czm_backgroundColor.rgb == color.rgb) + * { + * color.rgb = vec3(1.0) - color.rgb; + * } + * + * return color; + * } + */ + czm_backgroundColor : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC4, + getValue : function(uniformState) { + return uniformState.backgroundColor; + } + }), + + /** + * An automatic GLSL uniform containing the BRDF look up texture used for image-based lighting computations. + * + * @alias czm_brdfLut + * @glslUniform + * + * @example + * // GLSL declaration + * uniform sampler2D czm_brdfLut; + * + * // Example: For a given roughness and NdotV value, find the material's BRDF information in the red and green channels + * float roughness = 0.5; + * float NdotV = dot(normal, view); + * vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg; + */ + czm_brdfLut : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.SAMPLER_2D, + getValue : function(uniformState) { + return uniformState.brdfLut; + } + }), + + /** + * An automatic GLSL uniform containing the environment map used within the scene. + * + * @alias czm_environmentMap + * @glslUniform + * + * @example + * // GLSL declaration + * uniform samplerCube czm_environmentMap; + * + * // Example: Create a perfect reflection of the environment map on a model + * float reflected = reflect(view, normal); + * vec4 reflectedColor = textureCube(czm_environmentMap, reflected); + */ + czm_environmentMap : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.SAMPLER_CUBE, + getValue : function(uniformState) { + return uniformState.environmentMap; + } + }), + + /** + * An automatic GLSL uniform representing a 3x3 rotation matrix that transforms + * from True Equator Mean Equinox (TEME) axes to the pseudo-fixed axes at the current scene time. + * + * @alias czm_temeToPseudoFixed + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform mat3 czm_temeToPseudoFixed; + * + * // Example + * vec3 pseudoFixed = czm_temeToPseudoFixed * teme; + * + * @see UniformState#temeToPseudoFixedMatrix + * @see Transforms.computeTemeToPseudoFixedMatrix + */ + czm_temeToPseudoFixed : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_MAT3, + getValue : function(uniformState) { + return uniformState.temeToPseudoFixedMatrix; + } + }), + + /** + * An automatic GLSL uniform representing the ratio of canvas coordinate space to canvas pixel space. + * + * @alias czm_resolutionScale + * @glslUniform + * + * @example + * uniform float czm_resolutionScale; + */ + czm_resolutionScale : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.resolutionScale; + } + }), + + /** + * An automatic GLSL uniform scalar used to mix a color with the fog color based on the distance to the camera. + * + * @alias czm_fogDensity + * @glslUniform + * + * @see czm_fog + */ + czm_fogDensity : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.fogDensity; + } + }), + + /** + * An automatic GLSL uniform representing the splitter position to use when rendering imagery layers with a splitter. + * This will be in pixel coordinates relative to the canvas. + * + * @alias czm_imagerySplitPosition + * @glslUniform + * + * + * @example + * // GLSL declaration + * uniform float czm_imagerySplitPosition; + */ + czm_imagerySplitPosition : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.imagerySplitPosition; + } + }), + + /** + * An automatic GLSL uniform scalar representing the geometric tolerance per meter + * + * @alias czm_geometricToleranceOverMeter + * @glslUniform + */ + czm_geometricToleranceOverMeter : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.geometricToleranceOverMeter; + } + }), + + /** + * An automatic GLSL uniform representing the distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always be applied. When less than zero, + * the depth test should never be applied. + * + * @alias czm_minimumDisableDepthTestDistance + * @glslUniform + */ + czm_minimumDisableDepthTestDistance : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.minimumDisableDepthTestDistance; + } + }), + + /** + * An automatic GLSL uniform that will be the highlight color of unclassified 3D Tiles. + * + * @alias czm_invertClassificationColor + * @glslUniform + */ + czm_invertClassificationColor : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT_VEC4, + getValue : function(uniformState) { + return uniformState.invertClassificationColor; + } + }) + }; + + return AutomaticUniforms; +}); + +define('Renderer/createUniform',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Color', + '../Core/defined', + '../Core/DeveloperError', + '../Core/Matrix2', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/RuntimeError' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + Color, + defined, + DeveloperError, + Matrix2, + Matrix3, + Matrix4, + RuntimeError) { + 'use strict'; + + /** + * @private + */ + function createUniform(gl, activeUniform, uniformName, location) { + switch (activeUniform.type) { + case gl.FLOAT: + return new UniformFloat(gl, activeUniform, uniformName, location); + case gl.FLOAT_VEC2: + return new UniformFloatVec2(gl, activeUniform, uniformName, location); + case gl.FLOAT_VEC3: + return new UniformFloatVec3(gl, activeUniform, uniformName, location); + case gl.FLOAT_VEC4: + return new UniformFloatVec4(gl, activeUniform, uniformName, location); + case gl.SAMPLER_2D: + case gl.SAMPLER_CUBE: + return new UniformSampler(gl, activeUniform, uniformName, location); + case gl.INT: + case gl.BOOL: + return new UniformInt(gl, activeUniform, uniformName, location); + case gl.INT_VEC2: + case gl.BOOL_VEC2: + return new UniformIntVec2(gl, activeUniform, uniformName, location); + case gl.INT_VEC3: + case gl.BOOL_VEC3: + return new UniformIntVec3(gl, activeUniform, uniformName, location); + case gl.INT_VEC4: + case gl.BOOL_VEC4: + return new UniformIntVec4(gl, activeUniform, uniformName, location); + case gl.FLOAT_MAT2: + return new UniformMat2(gl, activeUniform, uniformName, location); + case gl.FLOAT_MAT3: + return new UniformMat3(gl, activeUniform, uniformName, location); + case gl.FLOAT_MAT4: + return new UniformMat4(gl, activeUniform, uniformName, location); + default: + throw new RuntimeError('Unrecognized uniform type: ' + activeUniform.type + ' for uniform "' + uniformName + '".'); + } + } + + function UniformFloat(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = 0.0; + + this._gl = gl; + this._location = location; + } + + UniformFloat.prototype.set = function() { + if (this.value !== this._value) { + this._value = this.value; + this._gl.uniform1f(this._location, this.value); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformFloatVec2(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Cartesian2(); + + this._gl = gl; + this._location = location; + } + + UniformFloatVec2.prototype.set = function() { + var v = this.value; + if (!Cartesian2.equals(v, this._value)) { + Cartesian2.clone(v, this._value); + this._gl.uniform2f(this._location, v.x, v.y); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformFloatVec3(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = undefined; + + this._gl = gl; + this._location = location; + } + + UniformFloatVec3.prototype.set = function() { + var v = this.value; + + if (defined(v.red)) { + if (!Color.equals(v, this._value)) { + this._value = Color.clone(v, this._value); + this._gl.uniform3f(this._location, v.red, v.green, v.blue); + } + } else if (defined(v.x)) { + if (!Cartesian3.equals(v, this._value)) { + this._value = Cartesian3.clone(v, this._value); + this._gl.uniform3f(this._location, v.x, v.y, v.z); + } + } else { + throw new DeveloperError('Invalid vec3 value for uniform "' + this._activethis.name + '".'); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformFloatVec4(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = undefined; + + this._gl = gl; + this._location = location; + } + + UniformFloatVec4.prototype.set = function() { + var v = this.value; + + if (defined(v.red)) { + if (!Color.equals(v, this._value)) { + this._value = Color.clone(v, this._value); + this._gl.uniform4f(this._location, v.red, v.green, v.blue, v.alpha); + } + } else if (defined(v.x)) { + if (!Cartesian4.equals(v, this._value)) { + this._value = Cartesian4.clone(v, this._value); + this._gl.uniform4f(this._location, v.x, v.y, v.z, v.w); + } + } else { + throw new DeveloperError('Invalid vec4 value for uniform "' + this._activethis.name + '".'); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformSampler(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + + this._gl = gl; + this._location = location; + + this.textureUnitIndex = undefined; + } + + UniformSampler.prototype.set = function() { + var gl = this._gl; + gl.activeTexture(gl.TEXTURE0 + this.textureUnitIndex); + + var v = this.value; + gl.bindTexture(v._target, v._texture); + }; + + UniformSampler.prototype._setSampler = function(textureUnitIndex) { + this.textureUnitIndex = textureUnitIndex; + this._gl.uniform1i(this._location, textureUnitIndex); + return textureUnitIndex + 1; + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformInt(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = 0.0; + + this._gl = gl; + this._location = location; + } + + UniformInt.prototype.set = function() { + if (this.value !== this._value) { + this._value = this.value; + this._gl.uniform1i(this._location, this.value); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformIntVec2(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Cartesian2(); + + this._gl = gl; + this._location = location; + } + + UniformIntVec2.prototype.set = function() { + var v = this.value; + if (!Cartesian2.equals(v, this._value)) { + Cartesian2.clone(v, this._value); + this._gl.uniform2i(this._location, v.x, v.y); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformIntVec3(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Cartesian3(); + + this._gl = gl; + this._location = location; + } + + UniformIntVec3.prototype.set = function() { + var v = this.value; + if (!Cartesian3.equals(v, this._value)) { + Cartesian3.clone(v, this._value); + this._gl.uniform3i(this._location, v.x, v.y, v.z); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformIntVec4(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Cartesian4(); + + this._gl = gl; + this._location = location; + } + + UniformIntVec4.prototype.set = function() { + var v = this.value; + if (!Cartesian4.equals(v, this._value)) { + Cartesian4.clone(v, this._value); + this._gl.uniform4i(this._location, v.x, v.y, v.z, v.w); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformMat2(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Float32Array(4); + + this._gl = gl; + this._location = location; + } + + UniformMat2.prototype.set = function() { + if (!Matrix2.equalsArray(this.value, this._value, 0)) { + Matrix2.toArray(this.value, this._value); + this._gl.uniformMatrix2fv(this._location, false, this._value); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformMat3(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Float32Array(9); + + this._gl = gl; + this._location = location; + } + + UniformMat3.prototype.set = function() { + if (!Matrix3.equalsArray(this.value, this._value, 0)) { + Matrix3.toArray(this.value, this._value); + this._gl.uniformMatrix3fv(this._location, false, this._value); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformMat4(gl, activeUniform, uniformName, location) { + /** + * @readonly + */ + this.name = uniformName; + + this.value = undefined; + this._value = new Float32Array(16); + + this._gl = gl; + this._location = location; + } + + UniformMat4.prototype.set = function() { + if (!Matrix4.equalsArray(this.value, this._value, 0)) { + Matrix4.toArray(this.value, this._value); + this._gl.uniformMatrix4fv(this._location, false, this._value); + } + }; + + return createUniform; +}); + +define('Renderer/createUniformArray',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Color', + '../Core/defined', + '../Core/DeveloperError', + '../Core/Matrix2', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/RuntimeError' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + Color, + defined, + DeveloperError, + Matrix2, + Matrix3, + Matrix4, + RuntimeError) { + 'use strict'; + + /** + * @private + */ + function createUniformArray(gl, activeUniform, uniformName, locations) { + switch (activeUniform.type) { + case gl.FLOAT: + return new UniformArrayFloat(gl, activeUniform, uniformName, locations); + case gl.FLOAT_VEC2: + return new UniformArrayFloatVec2(gl, activeUniform, uniformName, locations); + case gl.FLOAT_VEC3: + return new UniformArrayFloatVec3(gl, activeUniform, uniformName, locations); + case gl.FLOAT_VEC4: + return new UniformArrayFloatVec4(gl, activeUniform, uniformName, locations); + case gl.SAMPLER_2D: + case gl.SAMPLER_CUBE: + return new UniformArraySampler(gl, activeUniform, uniformName, locations); + case gl.INT: + case gl.BOOL: + return new UniformArrayInt(gl, activeUniform, uniformName, locations); + case gl.INT_VEC2: + case gl.BOOL_VEC2: + return new UniformArrayIntVec2(gl, activeUniform, uniformName, locations); + case gl.INT_VEC3: + case gl.BOOL_VEC3: + return new UniformArrayIntVec3(gl, activeUniform, uniformName, locations); + case gl.INT_VEC4: + case gl.BOOL_VEC4: + return new UniformArrayIntVec4(gl, activeUniform, uniformName, locations); + case gl.FLOAT_MAT2: + return new UniformArrayMat2(gl, activeUniform, uniformName, locations); + case gl.FLOAT_MAT3: + return new UniformArrayMat3(gl, activeUniform, uniformName, locations); + case gl.FLOAT_MAT4: + return new UniformArrayMat4(gl, activeUniform, uniformName, locations); + default: + throw new RuntimeError('Unrecognized uniform type: ' + activeUniform.type + ' for uniform "' + uniformName + '".'); + } + } + + function UniformArrayFloat(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayFloat.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (v !== arraybuffer[i]) { + arraybuffer[i] = v; + changed = true; + } + } + + if (changed) { + this._gl.uniform1fv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayFloatVec2(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length * 2); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayFloatVec2.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Cartesian2.equalsArray(v, arraybuffer, j)) { + Cartesian2.pack(v, arraybuffer, j); + changed = true; + } + j += 2; + } + + if (changed) { + this._gl.uniform2fv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayFloatVec3(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length * 3); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayFloatVec3.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (defined(v.red)) { + if ((v.red !== arraybuffer[j]) || + (v.green !== arraybuffer[j + 1]) || + (v.blue !== arraybuffer[j + 2])) { + + arraybuffer[j] = v.red; + arraybuffer[j + 1] = v.green; + arraybuffer[j + 2] = v.blue; + changed = true; + } + } else if (defined(v.x)) { + if (!Cartesian3.equalsArray(v, arraybuffer, j)) { + Cartesian3.pack(v, arraybuffer, j); + changed = true; + } + } else { + throw new DeveloperError('Invalid vec3 value.'); + } + + j += 3; + } + + if (changed) { + this._gl.uniform3fv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayFloatVec4(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length * 4); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayFloatVec4.prototype.set = function() { + // PERFORMANCE_IDEA: if it is a common case that only a few elements + // in a uniform array change, we could use heuristics to determine + // when it is better to call uniform4f for each element that changed + // vs. call uniform4fv once to set the entire array. This applies + // to all uniform array types, not just vec4. We might not care + // once we have uniform buffers since that will be the fast path. + + // PERFORMANCE_IDEA: Micro-optimization (I bet it works though): + // As soon as changed is true, break into a separate loop that + // does the copy without the equals check. + + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (defined(v.red)) { + if (!Color.equalsArray(v, arraybuffer, j)) { + Color.pack(v, arraybuffer, j); + changed = true; + } + } else if (defined(v.x)) { + if (!Cartesian4.equalsArray(v, arraybuffer, j)) { + Cartesian4.pack(v, arraybuffer, j); + changed = true; + } + } else { + throw new DeveloperError('Invalid vec4 value.'); + } + + j += 4; + } + + if (changed) { + this._gl.uniform4fv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArraySampler(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length); + + this._gl = gl; + this._locations = locations; + + this.textureUnitIndex = undefined; + } + + UniformArraySampler.prototype.set = function() { + var gl = this._gl; + var textureUnitIndex = gl.TEXTURE0 + this.textureUnitIndex; + + var value = this.value; + var length = value.length; + for (var i = 0; i < length; ++i) { + var v = value[i]; + gl.activeTexture(textureUnitIndex + i); + gl.bindTexture(v._target, v._texture); + } + }; + + UniformArraySampler.prototype._setSampler = function(textureUnitIndex) { + this.textureUnitIndex = textureUnitIndex; + + var locations = this._locations; + var length = locations.length; + for (var i = 0; i < length; ++i) { + var index = textureUnitIndex + i; + this._gl.uniform1i(locations[i], index); + } + + return textureUnitIndex + length; + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayInt(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Int32Array(length); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayInt.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (v !== arraybuffer[i]) { + arraybuffer[i] = v; + changed = true; + } + } + + if (changed) { + this._gl.uniform1iv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayIntVec2(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Int32Array(length * 2); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayIntVec2.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Cartesian2.equalsArray(v, arraybuffer, j)) { + Cartesian2.pack(v, arraybuffer, j); + changed = true; + } + j += 2; + } + + if (changed) { + this._gl.uniform2iv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayIntVec3(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Int32Array(length * 3); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayIntVec3.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Cartesian3.equalsArray(v, arraybuffer, j)) { + Cartesian3.pack(v, arraybuffer, j); + changed = true; + } + j += 3; + } + + if (changed) { + this._gl.uniform3iv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayIntVec4(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Int32Array(length * 4); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayIntVec4.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Cartesian4.equalsArray(v, arraybuffer, j)) { + Cartesian4.pack(v, arraybuffer, j); + changed = true; + } + j += 4; + } + + if (changed) { + this._gl.uniform4iv(this._location, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayMat2(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length * 4); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayMat2.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Matrix2.equalsArray(v, arraybuffer, j)) { + Matrix2.pack(v, arraybuffer, j); + changed = true; + } + j += 4; + } + + if (changed) { + this._gl.uniformMatrix2fv(this._location, false, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayMat3(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length * 9); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayMat3.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Matrix3.equalsArray(v, arraybuffer, j)) { + Matrix3.pack(v, arraybuffer, j); + changed = true; + } + j += 9; + } + + if (changed) { + this._gl.uniformMatrix3fv(this._location, false, arraybuffer); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + function UniformArrayMat4(gl, activeUniform, uniformName, locations) { + var length = locations.length; + + /** + * @readonly + */ + this.name = uniformName; + + this.value = new Array(length); + this._value = new Float32Array(length * 16); + + this._gl = gl; + this._location = locations[0]; + } + + UniformArrayMat4.prototype.set = function() { + var value = this.value; + var length = value.length; + var arraybuffer = this._value; + var changed = false; + var j = 0; + + for (var i = 0; i < length; ++i) { + var v = value[i]; + + if (!Matrix4.equalsArray(v, arraybuffer, j)) { + Matrix4.pack(v, arraybuffer, j); + changed = true; + } + j += 16; + } + + if (changed) { + this._gl.uniformMatrix4fv(this._location, false, arraybuffer); + } + }; + + return createUniformArray; +}); + +define('Renderer/ShaderProgram',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/RuntimeError', + './AutomaticUniforms', + './ContextLimits', + './createUniform', + './createUniformArray' + ], function( + Check, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + RuntimeError, + AutomaticUniforms, + ContextLimits, + createUniform, + createUniformArray) { + 'use strict'; + + var nextShaderProgramId = 0; + + /** + * @private + */ + function ShaderProgram(options) { + var modifiedFS = handleUniformPrecisionMismatches(options.vertexShaderText, options.fragmentShaderText); + + this._gl = options.gl; + this._logShaderCompilation = options.logShaderCompilation; + this._debugShaders = options.debugShaders; + this._attributeLocations = options.attributeLocations; + + this._program = undefined; + this._numberOfVertexAttributes = undefined; + this._vertexAttributes = undefined; + this._uniformsByName = undefined; + this._uniforms = undefined; + this._automaticUniforms = undefined; + this._manualUniforms = undefined; + this._duplicateUniformNames = modifiedFS.duplicateUniformNames; + this._cachedShader = undefined; // Used by ShaderCache + + /** + * @private + */ + this.maximumTextureUnitIndex = undefined; + + this._vertexShaderSource = options.vertexShaderSource; + this._vertexShaderText = options.vertexShaderText; + this._fragmentShaderSource = options.fragmentShaderSource; + this._fragmentShaderText = modifiedFS.fragmentShaderText; + + /** + * @private + */ + this.id = nextShaderProgramId++; + } + + ShaderProgram.fromCache = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + Check.defined('options.context', options.context); + + return options.context.shaderCache.getShaderProgram(options); + }; + + ShaderProgram.replaceCache = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + Check.defined('options.context', options.context); + + return options.context.shaderCache.replaceShaderProgram(options); + }; + + defineProperties(ShaderProgram.prototype, { + /** + * GLSL source for the shader program's vertex shader. + * @memberof ShaderProgram.prototype + * + * @type {ShaderSource} + * @readonly + */ + vertexShaderSource : { + get : function() { + return this._vertexShaderSource; + } + }, + /** + * GLSL source for the shader program's fragment shader. + * @memberof ShaderProgram.prototype + * + * @type {ShaderSource} + * @readonly + */ + fragmentShaderSource : { + get : function() { + return this._fragmentShaderSource; + } + }, + vertexAttributes : { + get : function() { + initialize(this); + return this._vertexAttributes; + } + }, + numberOfVertexAttributes : { + get : function() { + initialize(this); + return this._numberOfVertexAttributes; + } + }, + allUniforms : { + get : function() { + initialize(this); + return this._uniformsByName; + } + } + }); + + function extractUniforms(shaderText) { + var uniformNames = []; + var uniformLines = shaderText.match(/uniform.*?(?![^{]*})(?=[=\[;])/g); + if (defined(uniformLines)) { + var len = uniformLines.length; + for (var i = 0; i < len; i++) { + var line = uniformLines[i].trim(); + var name = line.slice(line.lastIndexOf(' ') + 1); + uniformNames.push(name); + } + } + return uniformNames; + } + + function handleUniformPrecisionMismatches(vertexShaderText, fragmentShaderText) { + // If a uniform exists in both the vertex and fragment shader but with different precision qualifiers, + // give the fragment shader uniform a different name. This fixes shader compilation errors on devices + // that only support mediump in the fragment shader. + var duplicateUniformNames = {}; + + if (!ContextLimits.highpFloatSupported || !ContextLimits.highpIntSupported) { + var i, j; + var uniformName; + var duplicateName; + var vertexShaderUniforms = extractUniforms(vertexShaderText); + var fragmentShaderUniforms = extractUniforms(fragmentShaderText); + var vertexUniformsCount = vertexShaderUniforms.length; + var fragmentUniformsCount = fragmentShaderUniforms.length; + + for (i = 0; i < vertexUniformsCount; i++) { + for (j = 0; j < fragmentUniformsCount; j++) { + if (vertexShaderUniforms[i] === fragmentShaderUniforms[j]) { + uniformName = vertexShaderUniforms[i]; + duplicateName = 'czm_mediump_' + uniformName; + // Update fragmentShaderText with renamed uniforms + var re = new RegExp(uniformName + '\\b', 'g'); + fragmentShaderText = fragmentShaderText.replace(re, duplicateName); + duplicateUniformNames[duplicateName] = uniformName; + } + } + } + } + + return { + fragmentShaderText : fragmentShaderText, + duplicateUniformNames : duplicateUniformNames + }; + } + + var consolePrefix = '[Cesium WebGL] '; + + function createAndLinkProgram(gl, shader) { + var vsSource = shader._vertexShaderText; + var fsSource = shader._fragmentShaderText; + + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vsSource); + gl.compileShader(vertexShader); + + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fsSource); + gl.compileShader(fragmentShader); + + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + + var attributeLocations = shader._attributeLocations; + if (defined(attributeLocations)) { + for ( var attribute in attributeLocations) { + if (attributeLocations.hasOwnProperty(attribute)) { + gl.bindAttribLocation(program, attributeLocations[attribute], attribute); + } + } + } + + gl.linkProgram(program); + + var log; + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + var debugShaders = shader._debugShaders; + + // For performance, only check compile errors if there is a linker error. + if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { + log = gl.getShaderInfoLog(fragmentShader); + console.error(consolePrefix + 'Fragment shader compile log: ' + log); + if (defined(debugShaders)) { + var fragmentSourceTranslation = debugShaders.getTranslatedShaderSource(fragmentShader); + if (fragmentSourceTranslation !== '') { + console.error(consolePrefix + 'Translated fragment shader source:\n' + fragmentSourceTranslation); + } else { + console.error(consolePrefix + 'Fragment shader translation failed.'); + } + } + + gl.deleteProgram(program); + throw new RuntimeError('Fragment shader failed to compile. Compile log: ' + log); + } + + if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { + log = gl.getShaderInfoLog(vertexShader); + console.error(consolePrefix + 'Vertex shader compile log: ' + log); + if (defined(debugShaders)) { + var vertexSourceTranslation = debugShaders.getTranslatedShaderSource(vertexShader); + if (vertexSourceTranslation !== '') { + console.error(consolePrefix + 'Translated vertex shader source:\n' + vertexSourceTranslation); + } else { + console.error(consolePrefix + 'Vertex shader translation failed.'); + } + } + + gl.deleteProgram(program); + throw new RuntimeError('Vertex shader failed to compile. Compile log: ' + log); + } + + log = gl.getProgramInfoLog(program); + console.error(consolePrefix + 'Shader program link log: ' + log); + if (defined(debugShaders)) { + console.error(consolePrefix + 'Translated vertex shader source:\n' + debugShaders.getTranslatedShaderSource(vertexShader)); + console.error(consolePrefix + 'Translated fragment shader source:\n' + debugShaders.getTranslatedShaderSource(fragmentShader)); + } + + gl.deleteProgram(program); + throw new RuntimeError('Program failed to link. Link log: ' + log); + } + + var logShaderCompilation = shader._logShaderCompilation; + + if (logShaderCompilation) { + log = gl.getShaderInfoLog(vertexShader); + if (defined(log) && (log.length > 0)) { + console.log(consolePrefix + 'Vertex shader compile log: ' + log); + } + } + + if (logShaderCompilation) { + log = gl.getShaderInfoLog(fragmentShader); + if (defined(log) && (log.length > 0)) { + console.log(consolePrefix + 'Fragment shader compile log: ' + log); + } + } + + if (logShaderCompilation) { + log = gl.getProgramInfoLog(program); + if (defined(log) && (log.length > 0)) { + console.log(consolePrefix + 'Shader program link log: ' + log); + } + } + + return program; + } + + function findVertexAttributes(gl, program, numberOfAttributes) { + var attributes = {}; + for (var i = 0; i < numberOfAttributes; ++i) { + var attr = gl.getActiveAttrib(program, i); + var location = gl.getAttribLocation(program, attr.name); + + attributes[attr.name] = { + name : attr.name, + type : attr.type, + index : location + }; + } + + return attributes; + } + + function findUniforms(gl, program) { + var uniformsByName = {}; + var uniforms = []; + var samplerUniforms = []; + + var numberOfUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + + for (var i = 0; i < numberOfUniforms; ++i) { + var activeUniform = gl.getActiveUniform(program, i); + var suffix = '[0]'; + var uniformName = activeUniform.name.indexOf(suffix, activeUniform.name.length - suffix.length) !== -1 ? activeUniform.name.slice(0, activeUniform.name.length - 3) : activeUniform.name; + + // Ignore GLSL built-in uniforms returned in Firefox. + if (uniformName.indexOf('gl_') !== 0) { + if (activeUniform.name.indexOf('[') < 0) { + // Single uniform + var location = gl.getUniformLocation(program, uniformName); + + // IE 11.0.9 needs this check since getUniformLocation can return null + // if the uniform is not active (e.g., it is optimized out). Looks like + // getActiveUniform() above returns uniforms that are not actually active. + if (location !== null) { + var uniform = createUniform(gl, activeUniform, uniformName, location); + + uniformsByName[uniformName] = uniform; + uniforms.push(uniform); + + if (uniform._setSampler) { + samplerUniforms.push(uniform); + } + } + } else { + // Uniform array + + var uniformArray; + var locations; + var value; + var loc; + + // On some platforms - Nexus 4 in Firefox for one - an array of sampler2D ends up being represented + // as separate uniforms, one for each array element. Check for and handle that case. + var indexOfBracket = uniformName.indexOf('['); + if (indexOfBracket >= 0) { + // We're assuming the array elements show up in numerical order - it seems to be true. + uniformArray = uniformsByName[uniformName.slice(0, indexOfBracket)]; + + // Nexus 4 with Android 4.3 needs this check, because it reports a uniform + // with the strange name webgl_3467e0265d05c3c1[1] in our globe surface shader. + if (!defined(uniformArray)) { + continue; + } + + locations = uniformArray._locations; + + // On the Nexus 4 in Chrome, we get one uniform per sampler, just like in Firefox, + // but the size is not 1 like it is in Firefox. So if we push locations here, + // we'll end up adding too many locations. + if (locations.length <= 1) { + value = uniformArray.value; + loc = gl.getUniformLocation(program, uniformName); + + // Workaround for IE 11.0.9. See above. + if (loc !== null) { + locations.push(loc); + value.push(gl.getUniform(program, loc)); + } + } + } else { + locations = []; + for (var j = 0; j < activeUniform.size; ++j) { + loc = gl.getUniformLocation(program, uniformName + '[' + j + ']'); + + // Workaround for IE 11.0.9. See above. + if (loc !== null) { + locations.push(loc); + } + } + uniformArray = createUniformArray(gl, activeUniform, uniformName, locations); + + uniformsByName[uniformName] = uniformArray; + uniforms.push(uniformArray); + + if (uniformArray._setSampler) { + samplerUniforms.push(uniformArray); + } + } + } + } + } + + return { + uniformsByName : uniformsByName, + uniforms : uniforms, + samplerUniforms : samplerUniforms + }; + } + + function partitionUniforms(shader, uniforms) { + var automaticUniforms = []; + var manualUniforms = []; + + for (var uniform in uniforms) { + if (uniforms.hasOwnProperty(uniform)) { + var uniformObject = uniforms[uniform]; + var uniformName = uniform; + // if it's a duplicate uniform, use its original name so it is updated correctly + var duplicateUniform = shader._duplicateUniformNames[uniformName]; + if (defined(duplicateUniform)) { + uniformObject.name = duplicateUniform; + uniformName = duplicateUniform; + } + var automaticUniform = AutomaticUniforms[uniformName]; + if (defined(automaticUniform)) { + automaticUniforms.push({ + uniform : uniformObject, + automaticUniform : automaticUniform + }); + } else { + manualUniforms.push(uniformObject); + } + } + } + + return { + automaticUniforms : automaticUniforms, + manualUniforms : manualUniforms + }; + } + + function setSamplerUniforms(gl, program, samplerUniforms) { + gl.useProgram(program); + + var textureUnitIndex = 0; + var length = samplerUniforms.length; + for (var i = 0; i < length; ++i) { + textureUnitIndex = samplerUniforms[i]._setSampler(textureUnitIndex); + } + + gl.useProgram(null); + + return textureUnitIndex; + } + + function initialize(shader) { + if (defined(shader._program)) { + return; + } + + var gl = shader._gl; + var program = createAndLinkProgram(gl, shader, shader._debugShaders); + var numberOfVertexAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); + var uniforms = findUniforms(gl, program); + var partitionedUniforms = partitionUniforms(shader, uniforms.uniformsByName); + + shader._program = program; + shader._numberOfVertexAttributes = numberOfVertexAttributes; + shader._vertexAttributes = findVertexAttributes(gl, program, numberOfVertexAttributes); + shader._uniformsByName = uniforms.uniformsByName; + shader._uniforms = uniforms.uniforms; + shader._automaticUniforms = partitionedUniforms.automaticUniforms; + shader._manualUniforms = partitionedUniforms.manualUniforms; + + shader.maximumTextureUnitIndex = setSamplerUniforms(gl, program, uniforms.samplerUniforms); + } + + ShaderProgram.prototype._bind = function() { + initialize(this); + this._gl.useProgram(this._program); + }; + + ShaderProgram.prototype._setUniforms = function(uniformMap, uniformState, validate) { + var len; + var i; + + if (defined(uniformMap)) { + var manualUniforms = this._manualUniforms; + len = manualUniforms.length; + for (i = 0; i < len; ++i) { + var mu = manualUniforms[i]; + mu.value = uniformMap[mu.name](); + } + } + + var automaticUniforms = this._automaticUniforms; + len = automaticUniforms.length; + for (i = 0; i < len; ++i) { + var au = automaticUniforms[i]; + au.uniform.value = au.automaticUniform.getValue(uniformState); + } + + /////////////////////////////////////////////////////////////////// + + // It appears that assigning the uniform values above and then setting them here + // (which makes the GL calls) is faster than removing this loop and making + // the GL calls above. I suspect this is because each GL call pollutes the + // L2 cache making our JavaScript and the browser/driver ping-pong cache lines. + var uniforms = this._uniforms; + len = uniforms.length; + for (i = 0; i < len; ++i) { + uniforms[i].set(); + } + + if (validate) { + var gl = this._gl; + var program = this._program; + + gl.validateProgram(program); + if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) { + throw new DeveloperError('Program validation failed. Program info log: ' + gl.getProgramInfoLog(program)); + } + } + }; + + ShaderProgram.prototype.isDestroyed = function() { + return false; + }; + + ShaderProgram.prototype.destroy = function() { + this._cachedShader.cache.releaseShaderProgram(this); + return undefined; + }; + + ShaderProgram.prototype.finalDestroy = function() { + this._gl.deleteProgram(this._program); + return destroyObject(this); + }; + + return ShaderProgram; +}); + +define('Renderer/modernizeShader',[ + '../Core/defined', + '../Core/DeveloperError' + ], function( + defined, + DeveloperError) { + 'use strict'; + + /** + * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 3.00 + * + * This function is nowhere near comprehensive or complete. It just + * handles some common cases. + * + * Note that this function requires the presence of the + * "#define OUTPUT_DECLARATION" line that is appended + * by ShaderSource. + * + * @private + */ + function modernizeShader(source, isFragmentShader) { + var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; + var splitSource = source.split('\n'); + + if (/#version 300 es/g.test(source)) { + return source; + } + + var outputDeclarationLine = -1; + var i, line; + for (i = 0; i < splitSource.length; ++i) { + line = splitSource[i]; + if (outputDeclarationRegex.test(line)) { + outputDeclarationLine = i; + break; + } + } + + if (outputDeclarationLine === -1) { + throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION!'); + } + + var outputVariables = []; + + for (i = 0; i < 10; i++) { + var fragDataString = 'gl_FragData\\[' + i + '\\]'; + var newOutput = 'czm_out' + i; + var regex = new RegExp(fragDataString, 'g'); + if (regex.test(source)) { + setAdd(newOutput, outputVariables); + replaceInSourceString(fragDataString, newOutput, splitSource); + splitSource.splice(outputDeclarationLine, 0, 'layout(location = ' + i + ') out vec4 ' + newOutput + ';'); + outputDeclarationLine += 1; + } + } + + var czmFragColor = 'czm_fragColor'; + if (findInSource('gl_FragColor', splitSource)) { + setAdd(czmFragColor, outputVariables); + replaceInSourceString('gl_FragColor', czmFragColor, splitSource); + splitSource.splice(outputDeclarationLine, 0, 'layout(location = 0) out vec4 czm_fragColor;'); + outputDeclarationLine += 1; + } + + var variableMap = getVariablePreprocessorBranch(outputVariables, splitSource); + var lineAdds = {}; + for (i = 0; i < splitSource.length; i++) { + line = splitSource[i]; + for (var variable in variableMap) { + if (variableMap.hasOwnProperty(variable)) { + var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + variable + ')[^]+', 'g'); + if (matchVar.test(line)) { + lineAdds[line] = variable; + } + } + } + } + + for (var layoutDeclaration in lineAdds) { + if (lineAdds.hasOwnProperty(layoutDeclaration)) { + var variableName = lineAdds[layoutDeclaration]; + var lineNumber = splitSource.indexOf(layoutDeclaration); + var entry = variableMap[variableName]; + var depth = entry.length; + var d; + for (d = 0; d < depth; d++) { + splitSource.splice(lineNumber, 0, entry[d]); + } + lineNumber += depth + 1; + for (d = depth - 1; d >= 0; d--) { + splitSource.splice(lineNumber, 0, '#endif //' + entry[d]); + } + } + } + + var versionThree = '#version 300 es'; + var foundVersion = false; + for (i = 0; i < splitSource.length; i++) { + if (/#version/.test(splitSource[i])) { + splitSource[i] = versionThree; + foundVersion = true; + } + } + + if (!foundVersion) { + splitSource.splice(0, 0, versionThree); + } + + removeExtension('EXT_draw_buffers', splitSource); + removeExtension('EXT_frag_depth', splitSource); + + replaceInSourceString('texture2D', 'texture', splitSource); + replaceInSourceString('texture3D', 'texture', splitSource); + replaceInSourceString('textureCube', 'texture', splitSource); + replaceInSourceString('gl_FragDepthEXT', 'gl_FragDepth', splitSource); + + if (isFragmentShader) { + replaceInSourceString('varying', 'in', splitSource); + } else { + replaceInSourceString('attribute', 'in', splitSource); + replaceInSourceString('varying', 'out', splitSource); + } + + return compileSource(splitSource); + } + + // Note that this fails if your string looks like + // searchString[singleCharacter]searchString + function replaceInSourceString(str, replacement, splitSource) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + splitSource[i] = line.replace(regex, '$1' + replacement + '$3'); + } + } + + function replaceInSourceRegex(regex, replacement, splitSource) { + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + splitSource[i] = line.replace(regex, replacement); + } + } + + function findInSource(str, splitSource) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + if (regex.test(line)) { + return true; + } + } + return false; + } + + function compileSource(splitSource) { + var wholeSource = ''; + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + wholeSource += splitSource[i] + '\n'; + } + return wholeSource; + } + + function setAdd(variable, set) { + if (set.indexOf(variable) === -1) { + set.push(variable); + } + } + + function getVariablePreprocessorBranch(layoutVariables, splitSource) { + var variableMap = {}; + + var numLayoutVariables = layoutVariables.length; + + var stack = []; + for (var i = 0; i < splitSource.length; ++i) { + var line = splitSource[i]; + var hasIF = /(#ifdef|#if)/g.test(line); + var hasELSE = /#else/g.test(line); + var hasENDIF = /#endif/g.test(line); + + if (hasIF) { + stack.push(line); + } else if (hasELSE) { + var top = stack[stack.length - 1]; + var op = top.replace('ifdef', 'ifndef'); + if (/if/g.test(op)) { + op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); + } + stack.pop(); + stack.push(op); + } else if (hasENDIF) { + stack.pop(); + } else if (!/layout/g.test(line)) { + for (var varIndex = 0; varIndex < numLayoutVariables; ++varIndex) { + var varName = layoutVariables[varIndex]; + if (line.indexOf(varName) !== -1) { + if (!defined(variableMap[varName])) { + variableMap[varName] = stack.slice(); + } else { + variableMap[varName] = variableMap[varName].filter(function(x) { + return stack.indexOf(x) >= 0; + }); + } + } + } + } + } + + return variableMap; + } + + function removeExtension(name, splitSource) { + var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; + replaceInSourceRegex(new RegExp(regex, 'g'), '', splitSource); + } + + return modernizeShader; +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/degreesPerRadian',[],function() { + 'use strict'; + return "const float czm_degreesPerRadian = 57.29577951308232;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/depthRange',[],function() { + 'use strict'; + return "const czm_depthRangeStruct czm_depthRange = czm_depthRangeStruct(0.0, 1.0);\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon1',[],function() { + 'use strict'; + return "const float czm_epsilon1 = 0.1;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon2',[],function() { + 'use strict'; + return "const float czm_epsilon2 = 0.01;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon3',[],function() { + 'use strict'; + return "const float czm_epsilon3 = 0.001;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon4',[],function() { + 'use strict'; + return "const float czm_epsilon4 = 0.0001;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon5',[],function() { + 'use strict'; + return "const float czm_epsilon5 = 0.00001;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon6',[],function() { + 'use strict'; + return "const float czm_epsilon6 = 0.000001;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/epsilon7',[],function() { + 'use strict'; + return "const float czm_epsilon7 = 0.0000001;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/infinity',[],function() { + 'use strict'; + return "const float czm_infinity = 5906376272000.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/maxClippingPlanes',[],function() { + 'use strict'; + return "const int czm_maxClippingPlanes = 6;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/oneOverPi',[],function() { + 'use strict'; + return "const float czm_oneOverPi = 0.3183098861837907;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/oneOverTwoPi',[],function() { + 'use strict'; + return "const float czm_oneOverTwoPi = 0.15915494309189535;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passCesium3DTile',[],function() { + 'use strict'; + return "const float czm_passCesium3DTile = 4.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passCesium3DTileClassification',[],function() { + 'use strict'; + return "const float czm_passCesium3DTileClassification = 5.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow',[],function() { + 'use strict'; + return "const float czm_passCesium3DTileClassificationIgnoreShow = 6.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passClassification',[],function() { + 'use strict'; + return "const float czm_passClassification = 7.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passCompute',[],function() { + 'use strict'; + return "const float czm_passCompute = 1.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passEnvironment',[],function() { + 'use strict'; + return "const float czm_passEnvironment = 0.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passGlobe',[],function() { + 'use strict'; + return "const float czm_passGlobe = 2.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passOpaque',[],function() { + 'use strict'; + return "const float czm_passOpaque = 8.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passOverlay',[],function() { + 'use strict'; + return "const float czm_passOverlay = 10.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passTerrainClassification',[],function() { + 'use strict'; + return "const float czm_passTerrainClassification = 3.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/passTranslucent',[],function() { + 'use strict'; + return "const float czm_passTranslucent = 9.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/pi',[],function() { + 'use strict'; + return "const float czm_pi = 3.141592653589793;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/piOverFour',[],function() { + 'use strict'; + return "const float czm_piOverFour = 0.7853981633974483;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/piOverSix',[],function() { + 'use strict'; + return "const float czm_piOverSix = 0.5235987755982988;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/piOverThree',[],function() { + 'use strict'; + return "const float czm_piOverThree = 1.0471975511965976;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/piOverTwo',[],function() { + 'use strict'; + return "const float czm_piOverTwo = 1.5707963267948966;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/radiansPerDegree',[],function() { + 'use strict'; + return "const float czm_radiansPerDegree = 0.017453292519943295;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/sceneMode2D',[],function() { + 'use strict'; + return "const float czm_sceneMode2D = 2.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/sceneMode3D',[],function() { + 'use strict'; + return "const float czm_sceneMode3D = 3.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/sceneModeColumbusView',[],function() { + 'use strict'; + return "const float czm_sceneModeColumbusView = 1.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/sceneModeMorphing',[],function() { + 'use strict'; + return "const float czm_sceneModeMorphing = 0.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/solarRadius',[],function() { + 'use strict'; + return "const float czm_solarRadius = 695500000.0;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/threePiOver2',[],function() { + 'use strict'; + return "const float czm_threePiOver2 = 4.71238898038469;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/twoPi',[],function() { + 'use strict'; + return "const float czm_twoPi = 6.283185307179586;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Constants/webMercatorMaxLatitude',[],function() { + 'use strict'; + return "const float czm_webMercatorMaxLatitude = 1.4844222297453324;\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/depthRangeStruct',[],function() { + 'use strict'; + return "struct czm_depthRangeStruct\n\ +{\n\ +float near;\n\ +float far;\n\ +};\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/ellipsoid',[],function() { + 'use strict'; + return "struct czm_ellipsoid\n\ +{\n\ +vec3 center;\n\ +vec3 radii;\n\ +vec3 inverseRadii;\n\ +vec3 inverseRadiiSquared;\n\ +};\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/material',[],function() { + 'use strict'; + return "struct czm_material\n\ +{\n\ +vec3 diffuse;\n\ +float specular;\n\ +float shininess;\n\ +vec3 normal;\n\ +vec3 emission;\n\ +float alpha;\n\ +};\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/materialInput',[],function() { + 'use strict'; + return "struct czm_materialInput\n\ +{\n\ +float s;\n\ +vec2 st;\n\ +vec3 str;\n\ +vec3 normalEC;\n\ +mat3 tangentToEyeMatrix;\n\ +vec3 positionToEyeEC;\n\ +float height;\n\ +float slope;\n\ +};\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/ray',[],function() { + 'use strict'; + return "struct czm_ray\n\ +{\n\ +vec3 origin;\n\ +vec3 direction;\n\ +};\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/raySegment',[],function() { + 'use strict'; + return "struct czm_raySegment\n\ +{\n\ +float start;\n\ +float stop;\n\ +};\n\ +const czm_raySegment czm_emptyRaySegment = czm_raySegment(-czm_infinity, -czm_infinity);\n\ +const czm_raySegment czm_fullRaySegment = czm_raySegment(0.0, czm_infinity);\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Structs/shadowParameters',[],function() { + 'use strict'; + return "struct czm_shadowParameters\n\ +{\n\ +#ifdef USE_CUBE_MAP_SHADOW\n\ +vec3 texCoords;\n\ +#else\n\ +vec2 texCoords;\n\ +#endif\n\ +float depthBias;\n\ +float depth;\n\ +float nDotL;\n\ +vec2 texelStepSize;\n\ +float normalShadingSmooth;\n\ +float darkness;\n\ +};\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/alphaWeight',[],function() { + 'use strict'; + return "float czm_alphaWeight(float a)\n\ +{\n\ +float x = 2.0 * (gl_FragCoord.x - czm_viewport.x) / czm_viewport.z - 1.0;\n\ +float y = 2.0 * (gl_FragCoord.y - czm_viewport.y) / czm_viewport.w - 1.0;\n\ +float z = (gl_FragCoord.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\n\ +vec4 q = vec4(x, y, z, 0.0);\n\ +q /= gl_FragCoord.w;\n\ +if (czm_inverseProjection != mat4(0.0)) {\n\ +q = czm_inverseProjection * q;\n\ +} else {\n\ +float top = czm_frustumPlanes.x;\n\ +float bottom = czm_frustumPlanes.y;\n\ +float left = czm_frustumPlanes.z;\n\ +float right = czm_frustumPlanes.w;\n\ +float near = czm_currentFrustum.x;\n\ +float far = czm_currentFrustum.y;\n\ +q.x = (q.x * (right - left) + left + right) * 0.5;\n\ +q.y = (q.y * (top - bottom) + bottom + top) * 0.5;\n\ +q.z = (q.z * (near - far) - near - far) * 0.5;\n\ +q.w = 1.0;\n\ +}\n\ +return pow(a + 0.01, 4.0) + max(1e-2, min(3.0 * 1e3, 100.0 / (1e-5 + pow(abs(z) / 10.0, 3.0) + pow(abs(z) / 200.0, 6.0))));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/antialias',[],function() { + 'use strict'; + return "vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist, float fuzzFactor)\n\ +{\n\ +float val1 = clamp(dist / fuzzFactor, 0.0, 1.0);\n\ +float val2 = clamp((dist - 0.5) / fuzzFactor, 0.0, 1.0);\n\ +val1 = val1 * (1.0 - val2);\n\ +val1 = val1 * val1 * (3.0 - (2.0 * val1));\n\ +val1 = pow(val1, 0.5);\n\ +vec4 midColor = (color1 + color2) * 0.5;\n\ +return mix(midColor, currentColor, val1);\n\ +}\n\ +vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist)\n\ +{\n\ +return czm_antialias(color1, color2, currentColor, dist, 0.1);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/cascadeColor',[],function() { + 'use strict'; + return "vec4 czm_cascadeColor(vec4 weights)\n\ +{\n\ +return vec4(1.0, 0.0, 0.0, 1.0) * weights.x +\n\ +vec4(0.0, 1.0, 0.0, 1.0) * weights.y +\n\ +vec4(0.0, 0.0, 1.0, 1.0) * weights.z +\n\ +vec4(1.0, 0.0, 1.0, 1.0) * weights.w;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/cascadeDistance',[],function() { + 'use strict'; + return "uniform vec4 shadowMap_cascadeDistances;\n\ +float czm_cascadeDistance(vec4 weights)\n\ +{\n\ +return dot(shadowMap_cascadeDistances, weights);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/cascadeMatrix',[],function() { + 'use strict'; + return "uniform mat4 shadowMap_cascadeMatrices[4];\n\ +mat4 czm_cascadeMatrix(vec4 weights)\n\ +{\n\ +return shadowMap_cascadeMatrices[0] * weights.x +\n\ +shadowMap_cascadeMatrices[1] * weights.y +\n\ +shadowMap_cascadeMatrices[2] * weights.z +\n\ +shadowMap_cascadeMatrices[3] * weights.w;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/cascadeWeights',[],function() { + 'use strict'; + return "uniform vec4 shadowMap_cascadeSplits[2];\n\ +vec4 czm_cascadeWeights(float depthEye)\n\ +{\n\ +vec4 near = step(shadowMap_cascadeSplits[0], vec4(depthEye));\n\ +vec4 far = step(depthEye, shadowMap_cascadeSplits[1]);\n\ +return near * far;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/columbusViewMorph',[],function() { + 'use strict'; + return "vec4 czm_columbusViewMorph(vec4 position2D, vec4 position3D, float time)\n\ +{\n\ +vec3 p = mix(position2D.xyz, position3D.xyz, time);\n\ +return vec4(p, 1.0);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/computePosition',[],function() { + 'use strict'; + return "vec4 czm_computePosition();\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/cosineAndSine',[],function() { + 'use strict'; + return "vec2 cordic(float angle)\n\ +{\n\ +vec2 vector = vec2(6.0725293500888267e-1, 0.0);\n\ +float sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +mat2 rotation = mat2(1.0, sense, -sense, 1.0);\n\ +vector = rotation * vector;\n\ +angle -= sense * 7.8539816339744828e-1;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +float factor = sense * 5.0e-1;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 4.6364760900080609e-1;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 2.5e-1;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 2.4497866312686414e-1;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.25e-1;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 1.2435499454676144e-1;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 6.25e-2;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 6.2418809995957350e-2;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 3.125e-2;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 3.1239833430268277e-2;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.5625e-2;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 1.5623728620476831e-2;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 7.8125e-3;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 7.8123410601011111e-3;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 3.90625e-3;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 3.9062301319669718e-3;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.953125e-3;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 1.9531225164788188e-3;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 9.765625e-4;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 9.7656218955931946e-4;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 4.8828125e-4;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 4.8828121119489829e-4;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 2.44140625e-4;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 2.4414062014936177e-4;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.220703125e-4;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 1.2207031189367021e-4;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 6.103515625e-5;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 6.1035156174208773e-5;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 3.0517578125e-5;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 3.0517578115526096e-5;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.52587890625e-5;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 1.5258789061315762e-5;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 7.62939453125e-6;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 7.6293945311019700e-6;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 3.814697265625e-6;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 3.8146972656064961e-6;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.9073486328125e-6;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 1.9073486328101870e-6;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 9.5367431640625e-7;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 9.5367431640596084e-7;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 4.76837158203125e-7;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 4.7683715820308884e-7;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 2.384185791015625e-7;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +angle -= sense * 2.3841857910155797e-7;\n\ +sense = (angle < 0.0) ? -1.0 : 1.0;\n\ +factor = sense * 1.1920928955078125e-7;\n\ +rotation[0][1] = factor;\n\ +rotation[1][0] = -factor;\n\ +vector = rotation * vector;\n\ +return vector;\n\ +}\n\ +vec2 czm_cosineAndSine(float angle)\n\ +{\n\ +if (angle < -czm_piOverTwo || angle > czm_piOverTwo)\n\ +{\n\ +if (angle < 0.0)\n\ +{\n\ +return -cordic(angle + czm_pi);\n\ +}\n\ +else\n\ +{\n\ +return -cordic(angle - czm_pi);\n\ +}\n\ +}\n\ +else\n\ +{\n\ +return cordic(angle);\n\ +}\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/decompressTextureCoordinates',[],function() { + 'use strict'; + return "vec2 czm_decompressTextureCoordinates(float encoded)\n\ +{\n\ +float temp = encoded / 4096.0;\n\ +float xZeroTo4095 = floor(temp);\n\ +float stx = xZeroTo4095 / 4095.0;\n\ +float sty = (encoded - xZeroTo4095 * 4096.0) / 4095.0;\n\ +return vec2(stx, sty);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/depthClampFarPlane',[],function() { + 'use strict'; + return "varying float v_WindowZ;\n\ +vec4 czm_depthClampFarPlane(vec4 coords)\n\ +{\n\ +v_WindowZ = (0.5 * (coords.z / coords.w) + 0.5) * coords.w;\n\ +coords.z = min(coords.z, coords.w);\n\ +return coords;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/discardIfClippedWithIntersect',[],function() { + 'use strict'; + return "float czm_discardIfClippedWithIntersect(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n\ +{\n\ +if (clippingPlanesLength > 0)\n\ +{\n\ +bool clipped = true;\n\ +vec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\n\ +vec3 clipNormal = vec3(0.0);\n\ +vec3 clipPosition = vec3(0.0);\n\ +float clipAmount = 0.0;\n\ +float pixelWidth = czm_metersPerPixel(position);\n\ +for (int i = 0; i < czm_maxClippingPlanes; ++i)\n\ +{\n\ +if (i == clippingPlanesLength)\n\ +{\n\ +break;\n\ +}\n\ +clipNormal = clippingPlanes[i].xyz;\n\ +clipPosition = -clippingPlanes[i].w * clipNormal;\n\ +float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n\ +clipAmount = max(amount, clipAmount);\n\ +clipped = clipped && (amount <= 0.0);\n\ +}\n\ +if (clipped)\n\ +{\n\ +discard;\n\ +}\n\ +return clipAmount;\n\ +}\n\ +return 0.0;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/discardIfClippedWithUnion',[],function() { + 'use strict'; + return "float czm_discardIfClippedWithUnion(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength)\n\ +{\n\ +if (clippingPlanesLength > 0)\n\ +{\n\ +vec4 position = czm_windowToEyeCoordinates(gl_FragCoord);\n\ +vec3 clipNormal = vec3(0.0);\n\ +vec3 clipPosition = vec3(0.0);\n\ +float clipAmount = 0.0;\n\ +float pixelWidth = czm_metersPerPixel(position);\n\ +for (int i = 0; i < czm_maxClippingPlanes; ++i)\n\ +{\n\ +if (i == clippingPlanesLength)\n\ +{\n\ +break;\n\ +}\n\ +clipNormal = clippingPlanes[i].xyz;\n\ +clipPosition = -clippingPlanes[i].w * clipNormal;\n\ +float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n\ +clipAmount = max(amount, clipAmount);\n\ +if (amount <= 0.0)\n\ +{\n\ +discard;\n\ +}\n\ +}\n\ +return clipAmount;\n\ +}\n\ +return 0.0;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates',[],function() { + 'use strict'; + return "mat3 czm_eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)\n\ +{\n\ +vec3 tangentMC = normalize(vec3(-positionMC.y, positionMC.x, 0.0));\n\ +vec3 tangentEC = normalize(czm_normal3D * tangentMC);\n\ +vec3 bitangentEC = normalize(cross(normalEC, tangentEC));\n\ +return mat3(\n\ +tangentEC.x, tangentEC.y, tangentEC.z,\n\ +bitangentEC.x, bitangentEC.y, bitangentEC.z,\n\ +normalEC.x, normalEC.y, normalEC.z);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/ellipsoidContainsPoint',[],function() { + 'use strict'; + return "bool czm_ellipsoidContainsPoint(czm_ellipsoid ellipsoid, vec3 point)\n\ +{\n\ +vec3 scaled = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(point, 1.0)).xyz;\n\ +return (dot(scaled, scaled) <= 1.0);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/ellipsoidNew',[],function() { + 'use strict'; + return "czm_ellipsoid czm_ellipsoidNew(vec3 center, vec3 radii)\n\ +{\n\ +vec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\n\ +vec3 inverseRadiiSquared = inverseRadii * inverseRadii;\n\ +czm_ellipsoid temp = czm_ellipsoid(center, radii, inverseRadii, inverseRadiiSquared);\n\ +return temp;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates',[],function() { + 'use strict'; + return "vec2 czm_ellipsoidWgs84TextureCoordinates(vec3 normal)\n\ +{\n\ +return vec2(atan(normal.y, normal.x) * czm_oneOverTwoPi + 0.5, asin(normal.z) * czm_oneOverPi + 0.5);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/equalsEpsilon',[],function() { + 'use strict'; + return "bool czm_equalsEpsilon(vec4 left, vec4 right, float epsilon) {\n\ +return all(lessThanEqual(abs(left - right), vec4(epsilon)));\n\ +}\n\ +bool czm_equalsEpsilon(vec3 left, vec3 right, float epsilon) {\n\ +return all(lessThanEqual(abs(left - right), vec3(epsilon)));\n\ +}\n\ +bool czm_equalsEpsilon(vec2 left, vec2 right, float epsilon) {\n\ +return all(lessThanEqual(abs(left - right), vec2(epsilon)));\n\ +}\n\ +bool czm_equalsEpsilon(float left, float right, float epsilon) {\n\ +return (abs(left - right) <= epsilon);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/eyeOffset',[],function() { + 'use strict'; + return "vec4 czm_eyeOffset(vec4 positionEC, vec3 eyeOffset)\n\ +{\n\ +vec4 p = positionEC;\n\ +vec4 zEyeOffset = normalize(p) * eyeOffset.z;\n\ +p.xy += eyeOffset.xy + zEyeOffset.xy;\n\ +p.z += zEyeOffset.z;\n\ +return p;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/eyeToWindowCoordinates',[],function() { + 'use strict'; + return "vec4 czm_eyeToWindowCoordinates(vec4 positionEC)\n\ +{\n\ +vec4 q = czm_projection * positionEC;\n\ +q.xyz /= q.w;\n\ +q.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\n\ +return q;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/fog',[],function() { + 'use strict'; + return "vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor)\n\ +{\n\ +float scalar = distanceToCamera * czm_fogDensity;\n\ +float fog = 1.0 - exp(-(scalar * scalar));\n\ +return mix(color, fogColor, fog);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/geodeticSurfaceNormal',[],function() { + 'use strict'; + return "vec3 czm_geodeticSurfaceNormal(vec3 positionOnEllipsoid, vec3 ellipsoidCenter, vec3 oneOverEllipsoidRadiiSquared)\n\ +{\n\ +return normalize((positionOnEllipsoid - ellipsoidCenter) * oneOverEllipsoidRadiiSquared);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/getDefaultMaterial',[],function() { + 'use strict'; + return "czm_material czm_getDefaultMaterial(czm_materialInput materialInput)\n\ +{\n\ +czm_material material;\n\ +material.diffuse = vec3(0.0);\n\ +material.specular = 0.0;\n\ +material.shininess = 1.0;\n\ +material.normal = materialInput.normalEC;\n\ +material.emission = vec3(0.0);\n\ +material.alpha = 1.0;\n\ +return material;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/getLambertDiffuse',[],function() { + 'use strict'; + return "float czm_getLambertDiffuse(vec3 lightDirectionEC, vec3 normalEC)\n\ +{\n\ +return max(dot(lightDirectionEC, normalEC), 0.0);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/getSpecular',[],function() { + 'use strict'; + return "float czm_getSpecular(vec3 lightDirectionEC, vec3 toEyeEC, vec3 normalEC, float shininess)\n\ +{\n\ +vec3 toReflectedLight = reflect(-lightDirectionEC, normalEC);\n\ +float specular = max(dot(toReflectedLight, toEyeEC), 0.0);\n\ +return pow(specular, max(shininess, czm_epsilon2));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/getWaterNoise',[],function() { + 'use strict'; + return "vec4 czm_getWaterNoise(sampler2D normalMap, vec2 uv, float time, float angleInRadians)\n\ +{\n\ +float cosAngle = cos(angleInRadians);\n\ +float sinAngle = sin(angleInRadians);\n\ +vec2 s0 = vec2(1.0/17.0, 0.0);\n\ +vec2 s1 = vec2(-1.0/29.0, 0.0);\n\ +vec2 s2 = vec2(1.0/101.0, 1.0/59.0);\n\ +vec2 s3 = vec2(-1.0/109.0, -1.0/57.0);\n\ +s0 = vec2((cosAngle * s0.x) - (sinAngle * s0.y), (sinAngle * s0.x) + (cosAngle * s0.y));\n\ +s1 = vec2((cosAngle * s1.x) - (sinAngle * s1.y), (sinAngle * s1.x) + (cosAngle * s1.y));\n\ +s2 = vec2((cosAngle * s2.x) - (sinAngle * s2.y), (sinAngle * s2.x) + (cosAngle * s2.y));\n\ +s3 = vec2((cosAngle * s3.x) - (sinAngle * s3.y), (sinAngle * s3.x) + (cosAngle * s3.y));\n\ +vec2 uv0 = (uv/103.0) + (time * s0);\n\ +vec2 uv1 = uv/107.0 + (time * s1) + vec2(0.23);\n\ +vec2 uv2 = uv/vec2(897.0, 983.0) + (time * s2) + vec2(0.51);\n\ +vec2 uv3 = uv/vec2(991.0, 877.0) + (time * s3) + vec2(0.71);\n\ +uv0 = fract(uv0);\n\ +uv1 = fract(uv1);\n\ +uv2 = fract(uv2);\n\ +uv3 = fract(uv3);\n\ +vec4 noise = (texture2D(normalMap, uv0)) +\n\ +(texture2D(normalMap, uv1)) +\n\ +(texture2D(normalMap, uv2)) +\n\ +(texture2D(normalMap, uv3));\n\ +return ((noise / 4.0) - 0.5) * 2.0;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/getWgs84EllipsoidEC',[],function() { + 'use strict'; + return "czm_ellipsoid czm_getWgs84EllipsoidEC()\n\ +{\n\ +vec3 radii = vec3(6378137.0, 6378137.0, 6356752.314245);\n\ +vec3 inverseRadii = vec3(1.0 / radii.x, 1.0 / radii.y, 1.0 / radii.z);\n\ +vec3 inverseRadiiSquared = inverseRadii * inverseRadii;\n\ +czm_ellipsoid temp = czm_ellipsoid(czm_view[3].xyz, radii, inverseRadii, inverseRadiiSquared);\n\ +return temp;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/HSBToRGB',[],function() { + 'use strict'; + return "const vec4 K_HSB2RGB = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n\ +vec3 czm_HSBToRGB(vec3 hsb)\n\ +{\n\ +vec3 p = abs(fract(hsb.xxx + K_HSB2RGB.xyz) * 6.0 - K_HSB2RGB.www);\n\ +return hsb.z * mix(K_HSB2RGB.xxx, clamp(p - K_HSB2RGB.xxx, 0.0, 1.0), hsb.y);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/HSLToRGB',[],function() { + 'use strict'; + return "vec3 hueToRGB(float hue)\n\ +{\n\ +float r = abs(hue * 6.0 - 3.0) - 1.0;\n\ +float g = 2.0 - abs(hue * 6.0 - 2.0);\n\ +float b = 2.0 - abs(hue * 6.0 - 4.0);\n\ +return clamp(vec3(r, g, b), 0.0, 1.0);\n\ +}\n\ +vec3 czm_HSLToRGB(vec3 hsl)\n\ +{\n\ +vec3 rgb = hueToRGB(hsl.x);\n\ +float c = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;\n\ +return (rgb - 0.5) * c + hsl.z;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/hue',[],function() { + 'use strict'; + return "vec3 czm_hue(vec3 rgb, float adjustment)\n\ +{\n\ +const mat3 toYIQ = mat3(0.299, 0.587, 0.114,\n\ +0.595716, -0.274453, -0.321263,\n\ +0.211456, -0.522591, 0.311135);\n\ +const mat3 toRGB = mat3(1.0, 0.9563, 0.6210,\n\ +1.0, -0.2721, -0.6474,\n\ +1.0, -1.107, 1.7046);\n\ +vec3 yiq = toYIQ * rgb;\n\ +float hue = atan(yiq.z, yiq.y) + adjustment;\n\ +float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);\n\ +vec3 color = vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));\n\ +return toRGB * color;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/isEmpty',[],function() { + 'use strict'; + return "bool czm_isEmpty(czm_raySegment interval)\n\ +{\n\ +return (interval.stop < 0.0);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/isFull',[],function() { + 'use strict'; + return "bool czm_isFull(czm_raySegment interval)\n\ +{\n\ +return (interval.start == 0.0 && interval.stop == czm_infinity);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/latitudeToWebMercatorFraction',[],function() { + 'use strict'; + return "float czm_latitudeToWebMercatorFraction(float latitude, float southMercatorY, float oneOverMercatorHeight)\n\ +{\n\ +float sinLatitude = sin(latitude);\n\ +float mercatorY = 0.5 * log((1.0 + sinLatitude) / (1.0 - sinLatitude));\n\ +return (mercatorY - southMercatorY) * oneOverMercatorHeight;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/luminance',[],function() { + 'use strict'; + return "float czm_luminance(vec3 rgb)\n\ +{\n\ +const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n\ +return dot(rgb, W);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/metersPerPixel',[],function() { + 'use strict'; + return "float czm_metersPerPixel(vec4 positionEC)\n\ +{\n\ +float width = czm_viewport.z;\n\ +float height = czm_viewport.w;\n\ +float pixelWidth;\n\ +float pixelHeight;\n\ +float top = czm_frustumPlanes.x;\n\ +float bottom = czm_frustumPlanes.y;\n\ +float left = czm_frustumPlanes.z;\n\ +float right = czm_frustumPlanes.w;\n\ +if (czm_sceneMode == czm_sceneMode2D)\n\ +{\n\ +float frustumWidth = right - left;\n\ +float frustumHeight = top - bottom;\n\ +pixelWidth = frustumWidth / width;\n\ +pixelHeight = frustumHeight / height;\n\ +}\n\ +else\n\ +{\n\ +float distanceToPixel = -positionEC.z;\n\ +float inverseNear = 1.0 / czm_currentFrustum.x;\n\ +float tanTheta = top * inverseNear;\n\ +pixelHeight = 2.0 * distanceToPixel * tanTheta / height;\n\ +tanTheta = right * inverseNear;\n\ +pixelWidth = 2.0 * distanceToPixel * tanTheta / width;\n\ +}\n\ +return max(pixelWidth, pixelHeight);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/modelToWindowCoordinates',[],function() { + 'use strict'; + return "vec4 czm_modelToWindowCoordinates(vec4 position)\n\ +{\n\ +vec4 q = czm_modelViewProjection * position;\n\ +q.xyz /= q.w;\n\ +q.xyz = (czm_viewportTransformation * vec4(q.xyz, 1.0)).xyz;\n\ +return q;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/multiplyWithColorBalance',[],function() { + 'use strict'; + return "vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right)\n\ +{\n\ +const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n\ +vec3 target = left * right;\n\ +float leftLuminance = dot(left, W);\n\ +float rightLuminance = dot(right, W);\n\ +float targetLuminance = dot(target, W);\n\ +return ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/nearFarScalar',[],function() { + 'use strict'; + return "float czm_nearFarScalar(vec4 nearFarScalar, float cameraDistSq)\n\ +{\n\ +float valueAtMin = nearFarScalar.y;\n\ +float valueAtMax = nearFarScalar.w;\n\ +float nearDistanceSq = nearFarScalar.x * nearFarScalar.x;\n\ +float farDistanceSq = nearFarScalar.z * nearFarScalar.z;\n\ +float t = (cameraDistSq - nearDistanceSq) / (farDistanceSq - nearDistanceSq);\n\ +t = pow(clamp(t, 0.0, 1.0), 0.2);\n\ +return mix(valueAtMin, valueAtMax, t);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/octDecode',[],function() { + 'use strict'; + return "vec3 czm_octDecode(vec2 encoded, float range)\n\ +{\n\ +if (encoded.x == 0.0 && encoded.y == 0.0) {\n\ +return vec3(0.0, 0.0, 0.0);\n\ +}\n\ +encoded = encoded / range * 2.0 - 1.0;\n\ +vec3 v = vec3(encoded.x, encoded.y, 1.0 - abs(encoded.x) - abs(encoded.y));\n\ +if (v.z < 0.0)\n\ +{\n\ +v.xy = (1.0 - abs(v.yx)) * czm_signNotZero(v.xy);\n\ +}\n\ +return normalize(v);\n\ +}\n\ +vec3 czm_octDecode(vec2 encoded)\n\ +{\n\ +return czm_octDecode(encoded, 255.0);\n\ +}\n\ +vec3 czm_octDecode(float encoded)\n\ +{\n\ +float temp = encoded / 256.0;\n\ +float x = floor(temp);\n\ +float y = (temp - x) * 256.0;\n\ +return czm_octDecode(vec2(x, y));\n\ +}\n\ +void czm_octDecode(vec2 encoded, out vec3 vector1, out vec3 vector2, out vec3 vector3)\n\ +{\n\ +float temp = encoded.x / 65536.0;\n\ +float x = floor(temp);\n\ +float encodedFloat1 = (temp - x) * 65536.0;\n\ +temp = encoded.y / 65536.0;\n\ +float y = floor(temp);\n\ +float encodedFloat2 = (temp - y) * 65536.0;\n\ +vector1 = czm_octDecode(encodedFloat1);\n\ +vector2 = czm_octDecode(encodedFloat2);\n\ +vector3 = czm_octDecode(vec2(x, y));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/packDepth',[],function() { + 'use strict'; + return "vec4 czm_packDepth(float depth)\n\ +{\n\ +vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\n\ +enc = fract(enc);\n\ +enc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n\ +return enc;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/phong',[],function() { + 'use strict'; + return "float czm_private_getLambertDiffuseOfMaterial(vec3 lightDirectionEC, czm_material material)\n\ +{\n\ +return czm_getLambertDiffuse(lightDirectionEC, material.normal);\n\ +}\n\ +float czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm_material material)\n\ +{\n\ +return czm_getSpecular(lightDirectionEC, toEyeEC, material.normal, material.shininess);\n\ +}\n\ +vec4 czm_phong(vec3 toEye, czm_material material)\n\ +{\n\ +float diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material);\n\ +if (czm_sceneMode == czm_sceneMode3D) {\n\ +diffuse += czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 1.0, 0.0), material);\n\ +}\n\ +float specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material) + czm_private_getSpecularOfMaterial(czm_moonDirectionEC, toEye, material);\n\ +vec3 materialDiffuse = material.diffuse * 0.5;\n\ +vec3 ambient = materialDiffuse;\n\ +vec3 color = ambient + material.emission;\n\ +color += materialDiffuse * diffuse;\n\ +color += material.specular * specular;\n\ +return vec4(color, material.alpha);\n\ +}\n\ +vec4 czm_private_phong(vec3 toEye, czm_material material)\n\ +{\n\ +float diffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material);\n\ +float specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material);\n\ +vec3 ambient = vec3(0.0);\n\ +vec3 color = ambient + material.emission;\n\ +color += material.diffuse * diffuse;\n\ +color += material.specular * specular;\n\ +return vec4(color, material.alpha);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/pointAlongRay',[],function() { + 'use strict'; + return "vec3 czm_pointAlongRay(czm_ray ray, float time)\n\ +{\n\ +return ray.origin + (time * ray.direction);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval',[],function() { + 'use strict'; + return "czm_raySegment czm_rayEllipsoidIntersectionInterval(czm_ray ray, czm_ellipsoid ellipsoid)\n\ +{\n\ +vec3 q = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.origin, 1.0)).xyz;\n\ +vec3 w = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.direction, 0.0)).xyz;\n\ +q = q - ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ellipsoid.center, 1.0)).xyz;\n\ +float q2 = dot(q, q);\n\ +float qw = dot(q, w);\n\ +if (q2 > 1.0)\n\ +{\n\ +if (qw >= 0.0)\n\ +{\n\ +return czm_emptyRaySegment;\n\ +}\n\ +else\n\ +{\n\ +float qw2 = qw * qw;\n\ +float difference = q2 - 1.0;\n\ +float w2 = dot(w, w);\n\ +float product = w2 * difference;\n\ +if (qw2 < product)\n\ +{\n\ +return czm_emptyRaySegment;\n\ +}\n\ +else if (qw2 > product)\n\ +{\n\ +float discriminant = qw * qw - product;\n\ +float temp = -qw + sqrt(discriminant);\n\ +float root0 = temp / w2;\n\ +float root1 = difference / temp;\n\ +if (root0 < root1)\n\ +{\n\ +czm_raySegment i = czm_raySegment(root0, root1);\n\ +return i;\n\ +}\n\ +else\n\ +{\n\ +czm_raySegment i = czm_raySegment(root1, root0);\n\ +return i;\n\ +}\n\ +}\n\ +else\n\ +{\n\ +float root = sqrt(difference / w2);\n\ +czm_raySegment i = czm_raySegment(root, root);\n\ +return i;\n\ +}\n\ +}\n\ +}\n\ +else if (q2 < 1.0)\n\ +{\n\ +float difference = q2 - 1.0;\n\ +float w2 = dot(w, w);\n\ +float product = w2 * difference;\n\ +float discriminant = qw * qw - product;\n\ +float temp = -qw + sqrt(discriminant);\n\ +czm_raySegment i = czm_raySegment(0.0, temp / w2);\n\ +return i;\n\ +}\n\ +else\n\ +{\n\ +if (qw < 0.0)\n\ +{\n\ +float w2 = dot(w, w);\n\ +czm_raySegment i = czm_raySegment(0.0, -qw / w2);\n\ +return i;\n\ +}\n\ +else\n\ +{\n\ +return czm_emptyRaySegment;\n\ +}\n\ +}\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/RGBToHSB',[],function() { + 'use strict'; + return "const vec4 K_RGB2HSB = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n\ +vec3 czm_RGBToHSB(vec3 rgb)\n\ +{\n\ +vec4 p = mix(vec4(rgb.bg, K_RGB2HSB.wz), vec4(rgb.gb, K_RGB2HSB.xy), step(rgb.b, rgb.g));\n\ +vec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r));\n\ +float d = q.x - min(q.w, q.y);\n\ +return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + czm_epsilon7)), d / (q.x + czm_epsilon7), q.x);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/RGBToHSL',[],function() { + 'use strict'; + return "vec3 RGBtoHCV(vec3 rgb)\n\ +{\n\ +vec4 p = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0 / 3.0) : vec4(rgb.gb, 0.0, -1.0 / 3.0);\n\ +vec4 q = (rgb.r < p.x) ? vec4(p.xyw, rgb.r) : vec4(rgb.r, p.yzx);\n\ +float c = q.x - min(q.w, q.y);\n\ +float h = abs((q.w - q.y) / (6.0 * c + czm_epsilon7) + q.z);\n\ +return vec3(h, c, q.x);\n\ +}\n\ +vec3 czm_RGBToHSL(vec3 rgb)\n\ +{\n\ +vec3 hcv = RGBtoHCV(rgb);\n\ +float l = hcv.z - hcv.y * 0.5;\n\ +float s = hcv.y / (1.0 - abs(l * 2.0 - 1.0) + czm_epsilon7);\n\ +return vec3(hcv.x, s, l);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/RGBToXYZ',[],function() { + 'use strict'; + return "vec3 czm_RGBToXYZ(vec3 rgb)\n\ +{\n\ +const mat3 RGB2XYZ = mat3(0.4124, 0.2126, 0.0193,\n\ +0.3576, 0.7152, 0.1192,\n\ +0.1805, 0.0722, 0.9505);\n\ +vec3 xyz = RGB2XYZ * rgb;\n\ +vec3 Yxy;\n\ +Yxy.r = xyz.g;\n\ +float temp = dot(vec3(1.0), xyz);\n\ +Yxy.gb = xyz.rg / temp;\n\ +return Yxy;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/saturation',[],function() { + 'use strict'; + return "vec3 czm_saturation(vec3 rgb, float adjustment)\n\ +{\n\ +const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n\ +vec3 intensity = vec3(dot(rgb, W));\n\ +return mix(intensity, rgb, adjustment);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/shadowDepthCompare',[],function() { + 'use strict'; + return "float czm_sampleShadowMap(samplerCube shadowMap, vec3 d)\n\ +{\n\ +return czm_unpackDepth(textureCube(shadowMap, d));\n\ +}\n\ +float czm_sampleShadowMap(sampler2D shadowMap, vec2 uv)\n\ +{\n\ +#ifdef USE_SHADOW_DEPTH_TEXTURE\n\ +return texture2D(shadowMap, uv).r;\n\ +#else\n\ +return czm_unpackDepth(texture2D(shadowMap, uv));\n\ +#endif\n\ +}\n\ +float czm_shadowDepthCompare(samplerCube shadowMap, vec3 uv, float depth)\n\ +{\n\ +return step(depth, czm_sampleShadowMap(shadowMap, uv));\n\ +}\n\ +float czm_shadowDepthCompare(sampler2D shadowMap, vec2 uv, float depth)\n\ +{\n\ +return step(depth, czm_sampleShadowMap(shadowMap, uv));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/shadowVisibility',[],function() { + 'use strict'; + return "float czm_private_shadowVisibility(float visibility, float nDotL, float normalShadingSmooth, float darkness)\n\ +{\n\ +#ifdef USE_NORMAL_SHADING\n\ +#ifdef USE_NORMAL_SHADING_SMOOTH\n\ +float strength = clamp(nDotL / normalShadingSmooth, 0.0, 1.0);\n\ +#else\n\ +float strength = step(0.0, nDotL);\n\ +#endif\n\ +visibility *= strength;\n\ +#endif\n\ +visibility = max(visibility, darkness);\n\ +return visibility;\n\ +}\n\ +#ifdef USE_CUBE_MAP_SHADOW\n\ +float czm_shadowVisibility(samplerCube shadowMap, czm_shadowParameters shadowParameters)\n\ +{\n\ +float depthBias = shadowParameters.depthBias;\n\ +float depth = shadowParameters.depth;\n\ +float nDotL = shadowParameters.nDotL;\n\ +float normalShadingSmooth = shadowParameters.normalShadingSmooth;\n\ +float darkness = shadowParameters.darkness;\n\ +vec3 uvw = shadowParameters.texCoords;\n\ +depth -= depthBias;\n\ +float visibility = czm_shadowDepthCompare(shadowMap, uvw, depth);\n\ +return czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n\ +}\n\ +#else\n\ +float czm_shadowVisibility(sampler2D shadowMap, czm_shadowParameters shadowParameters)\n\ +{\n\ +float depthBias = shadowParameters.depthBias;\n\ +float depth = shadowParameters.depth;\n\ +float nDotL = shadowParameters.nDotL;\n\ +float normalShadingSmooth = shadowParameters.normalShadingSmooth;\n\ +float darkness = shadowParameters.darkness;\n\ +vec2 uv = shadowParameters.texCoords;\n\ +depth -= depthBias;\n\ +#ifdef USE_SOFT_SHADOWS\n\ +vec2 texelStepSize = shadowParameters.texelStepSize;\n\ +float radius = 1.0;\n\ +float dx0 = -texelStepSize.x * radius;\n\ +float dy0 = -texelStepSize.y * radius;\n\ +float dx1 = texelStepSize.x * radius;\n\ +float dy1 = texelStepSize.y * radius;\n\ +float visibility = (\n\ +czm_shadowDepthCompare(shadowMap, uv, depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy0), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy0), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy0), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, 0.0), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, 0.0), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy1), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy1), depth) +\n\ +czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy1), depth)\n\ +) * (1.0 / 9.0);\n\ +#else\n\ +float visibility = czm_shadowDepthCompare(shadowMap, uv, depth);\n\ +#endif\n\ +return czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n\ +}\n\ +#endif\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/signNotZero',[],function() { + 'use strict'; + return "float czm_signNotZero(float value)\n\ +{\n\ +return value >= 0.0 ? 1.0 : -1.0;\n\ +}\n\ +vec2 czm_signNotZero(vec2 value)\n\ +{\n\ +return vec2(czm_signNotZero(value.x), czm_signNotZero(value.y));\n\ +}\n\ +vec3 czm_signNotZero(vec3 value)\n\ +{\n\ +return vec3(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z));\n\ +}\n\ +vec4 czm_signNotZero(vec4 value)\n\ +{\n\ +return vec4(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z), czm_signNotZero(value.w));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/tangentToEyeSpaceMatrix',[],function() { + 'use strict'; + return "mat3 czm_tangentToEyeSpaceMatrix(vec3 normalEC, vec3 tangentEC, vec3 bitangentEC)\n\ +{\n\ +vec3 normal = normalize(normalEC);\n\ +vec3 tangent = normalize(tangentEC);\n\ +vec3 bitangent = normalize(bitangentEC);\n\ +return mat3(tangent.x , tangent.y , tangent.z,\n\ +bitangent.x, bitangent.y, bitangent.z,\n\ +normal.x , normal.y , normal.z);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/translateRelativeToEye',[],function() { + 'use strict'; + return "vec4 czm_translateRelativeToEye(vec3 high, vec3 low)\n\ +{\n\ +vec3 highDifference = high - czm_encodedCameraPositionMCHigh;\n\ +vec3 lowDifference = low - czm_encodedCameraPositionMCLow;\n\ +return vec4(highDifference + lowDifference, 1.0);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/translucentPhong',[],function() { + 'use strict'; + return "vec4 czm_translucentPhong(vec3 toEye, czm_material material)\n\ +{\n\ +float diffuse = czm_getLambertDiffuse(vec3(0.0, 0.0, 1.0), material.normal);\n\ +if (czm_sceneMode == czm_sceneMode3D) {\n\ +diffuse += czm_getLambertDiffuse(vec3(0.0, 1.0, 0.0), material.normal);\n\ +}\n\ +diffuse = clamp(diffuse, 0.0, 1.0);\n\ +float specular = czm_getSpecular(czm_sunDirectionEC, toEye, material.normal, material.shininess);\n\ +specular += czm_getSpecular(czm_moonDirectionEC, toEye, material.normal, material.shininess);\n\ +vec3 materialDiffuse = material.diffuse * 0.5;\n\ +vec3 ambient = materialDiffuse;\n\ +vec3 color = ambient + material.emission;\n\ +color += materialDiffuse * diffuse;\n\ +color += material.specular * specular;\n\ +return vec4(color, material.alpha);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/transpose',[],function() { + 'use strict'; + return "mat2 czm_transpose(mat2 matrix)\n\ +{\n\ +return mat2(\n\ +matrix[0][0], matrix[1][0],\n\ +matrix[0][1], matrix[1][1]);\n\ +}\n\ +mat3 czm_transpose(mat3 matrix)\n\ +{\n\ +return mat3(\n\ +matrix[0][0], matrix[1][0], matrix[2][0],\n\ +matrix[0][1], matrix[1][1], matrix[2][1],\n\ +matrix[0][2], matrix[1][2], matrix[2][2]);\n\ +}\n\ +mat4 czm_transpose(mat4 matrix)\n\ +{\n\ +return mat4(\n\ +matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],\n\ +matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],\n\ +matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],\n\ +matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/unpackDepth',[],function() { + 'use strict'; + return "float czm_unpackDepth(vec4 packedDepth)\n\ +{\n\ +return dot(packedDepth, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/windowToEyeCoordinates',[],function() { + 'use strict'; + return "vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate)\n\ +{\n\ +float x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0;\n\ +float y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0;\n\ +float z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\n\ +vec4 q = vec4(x, y, z, 1.0);\n\ +q /= fragmentCoordinate.w;\n\ +if (czm_inverseProjection != mat4(0.0)) {\n\ +q = czm_inverseProjection * q;\n\ +} else {\n\ +float top = czm_frustumPlanes.x;\n\ +float bottom = czm_frustumPlanes.y;\n\ +float left = czm_frustumPlanes.z;\n\ +float right = czm_frustumPlanes.w;\n\ +float near = czm_currentFrustum.x;\n\ +float far = czm_currentFrustum.y;\n\ +q.x = (q.x * (right - left) + left + right) * 0.5;\n\ +q.y = (q.y * (top - bottom) + bottom + top) * 0.5;\n\ +q.z = (q.z * (near - far) - near - far) * 0.5;\n\ +q.w = 1.0;\n\ +}\n\ +return q;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/writeDepthClampedToFarPlane',[],function() { + 'use strict'; + return "varying float v_WindowZ;\n\ +void czm_writeDepthClampedToFarPlane()\n\ +{\n\ +#ifdef GL_EXT_frag_depth\n\ +gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/Functions/XYZToRGB',[],function() { + 'use strict'; + return "vec3 czm_XYZToRGB(vec3 Yxy)\n\ +{\n\ +const mat3 XYZ2RGB = mat3( 3.2405, -0.9693, 0.0556,\n\ +-1.5371, 1.8760, -0.2040,\n\ +-0.4985, 0.0416, 1.0572);\n\ +vec3 xyz;\n\ +xyz.r = Yxy.r * Yxy.g / Yxy.b;\n\ +xyz.g = Yxy.r;\n\ +xyz.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b;\n\ +return XYZ2RGB * xyz;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Builtin/CzmBuiltins',[ + './Constants/degreesPerRadian', + './Constants/depthRange', + './Constants/epsilon1', + './Constants/epsilon2', + './Constants/epsilon3', + './Constants/epsilon4', + './Constants/epsilon5', + './Constants/epsilon6', + './Constants/epsilon7', + './Constants/infinity', + './Constants/maxClippingPlanes', + './Constants/oneOverPi', + './Constants/oneOverTwoPi', + './Constants/passCesium3DTile', + './Constants/passCesium3DTileClassification', + './Constants/passCesium3DTileClassificationIgnoreShow', + './Constants/passClassification', + './Constants/passCompute', + './Constants/passEnvironment', + './Constants/passGlobe', + './Constants/passOpaque', + './Constants/passOverlay', + './Constants/passTerrainClassification', + './Constants/passTranslucent', + './Constants/pi', + './Constants/piOverFour', + './Constants/piOverSix', + './Constants/piOverThree', + './Constants/piOverTwo', + './Constants/radiansPerDegree', + './Constants/sceneMode2D', + './Constants/sceneMode3D', + './Constants/sceneModeColumbusView', + './Constants/sceneModeMorphing', + './Constants/solarRadius', + './Constants/threePiOver2', + './Constants/twoPi', + './Constants/webMercatorMaxLatitude', + './Structs/depthRangeStruct', + './Structs/ellipsoid', + './Structs/material', + './Structs/materialInput', + './Structs/ray', + './Structs/raySegment', + './Structs/shadowParameters', + './Functions/alphaWeight', + './Functions/antialias', + './Functions/cascadeColor', + './Functions/cascadeDistance', + './Functions/cascadeMatrix', + './Functions/cascadeWeights', + './Functions/columbusViewMorph', + './Functions/computePosition', + './Functions/cosineAndSine', + './Functions/decompressTextureCoordinates', + './Functions/depthClampFarPlane', + './Functions/discardIfClippedWithIntersect', + './Functions/discardIfClippedWithUnion', + './Functions/eastNorthUpToEyeCoordinates', + './Functions/ellipsoidContainsPoint', + './Functions/ellipsoidNew', + './Functions/ellipsoidWgs84TextureCoordinates', + './Functions/equalsEpsilon', + './Functions/eyeOffset', + './Functions/eyeToWindowCoordinates', + './Functions/fog', + './Functions/geodeticSurfaceNormal', + './Functions/getDefaultMaterial', + './Functions/getLambertDiffuse', + './Functions/getSpecular', + './Functions/getWaterNoise', + './Functions/getWgs84EllipsoidEC', + './Functions/HSBToRGB', + './Functions/HSLToRGB', + './Functions/hue', + './Functions/isEmpty', + './Functions/isFull', + './Functions/latitudeToWebMercatorFraction', + './Functions/luminance', + './Functions/metersPerPixel', + './Functions/modelToWindowCoordinates', + './Functions/multiplyWithColorBalance', + './Functions/nearFarScalar', + './Functions/octDecode', + './Functions/packDepth', + './Functions/phong', + './Functions/pointAlongRay', + './Functions/rayEllipsoidIntersectionInterval', + './Functions/RGBToHSB', + './Functions/RGBToHSL', + './Functions/RGBToXYZ', + './Functions/saturation', + './Functions/shadowDepthCompare', + './Functions/shadowVisibility', + './Functions/signNotZero', + './Functions/tangentToEyeSpaceMatrix', + './Functions/translateRelativeToEye', + './Functions/translucentPhong', + './Functions/transpose', + './Functions/unpackDepth', + './Functions/windowToEyeCoordinates', + './Functions/writeDepthClampedToFarPlane', + './Functions/XYZToRGB' + ], function( + czm_degreesPerRadian, + czm_depthRange, + czm_epsilon1, + czm_epsilon2, + czm_epsilon3, + czm_epsilon4, + czm_epsilon5, + czm_epsilon6, + czm_epsilon7, + czm_infinity, + czm_maxClippingPlanes, + czm_oneOverPi, + czm_oneOverTwoPi, + czm_passCesium3DTile, + czm_passCesium3DTileClassification, + czm_passCesium3DTileClassificationIgnoreShow, + czm_passClassification, + czm_passCompute, + czm_passEnvironment, + czm_passGlobe, + czm_passOpaque, + czm_passOverlay, + czm_passTerrainClassification, + czm_passTranslucent, + czm_pi, + czm_piOverFour, + czm_piOverSix, + czm_piOverThree, + czm_piOverTwo, + czm_radiansPerDegree, + czm_sceneMode2D, + czm_sceneMode3D, + czm_sceneModeColumbusView, + czm_sceneModeMorphing, + czm_solarRadius, + czm_threePiOver2, + czm_twoPi, + czm_webMercatorMaxLatitude, + czm_depthRangeStruct, + czm_ellipsoid, + czm_material, + czm_materialInput, + czm_ray, + czm_raySegment, + czm_shadowParameters, + czm_alphaWeight, + czm_antialias, + czm_cascadeColor, + czm_cascadeDistance, + czm_cascadeMatrix, + czm_cascadeWeights, + czm_columbusViewMorph, + czm_computePosition, + czm_cosineAndSine, + czm_decompressTextureCoordinates, + czm_depthClampFarPlane, + czm_discardIfClippedWithIntersect, + czm_discardIfClippedWithUnion, + czm_eastNorthUpToEyeCoordinates, + czm_ellipsoidContainsPoint, + czm_ellipsoidNew, + czm_ellipsoidWgs84TextureCoordinates, + czm_equalsEpsilon, + czm_eyeOffset, + czm_eyeToWindowCoordinates, + czm_fog, + czm_geodeticSurfaceNormal, + czm_getDefaultMaterial, + czm_getLambertDiffuse, + czm_getSpecular, + czm_getWaterNoise, + czm_getWgs84EllipsoidEC, + czm_HSBToRGB, + czm_HSLToRGB, + czm_hue, + czm_isEmpty, + czm_isFull, + czm_latitudeToWebMercatorFraction, + czm_luminance, + czm_metersPerPixel, + czm_modelToWindowCoordinates, + czm_multiplyWithColorBalance, + czm_nearFarScalar, + czm_octDecode, + czm_packDepth, + czm_phong, + czm_pointAlongRay, + czm_rayEllipsoidIntersectionInterval, + czm_RGBToHSB, + czm_RGBToHSL, + czm_RGBToXYZ, + czm_saturation, + czm_shadowDepthCompare, + czm_shadowVisibility, + czm_signNotZero, + czm_tangentToEyeSpaceMatrix, + czm_translateRelativeToEye, + czm_translucentPhong, + czm_transpose, + czm_unpackDepth, + czm_windowToEyeCoordinates, + czm_writeDepthClampedToFarPlane, + czm_XYZToRGB) { + 'use strict'; + return { + czm_degreesPerRadian : czm_degreesPerRadian, + czm_depthRange : czm_depthRange, + czm_epsilon1 : czm_epsilon1, + czm_epsilon2 : czm_epsilon2, + czm_epsilon3 : czm_epsilon3, + czm_epsilon4 : czm_epsilon4, + czm_epsilon5 : czm_epsilon5, + czm_epsilon6 : czm_epsilon6, + czm_epsilon7 : czm_epsilon7, + czm_infinity : czm_infinity, + czm_maxClippingPlanes : czm_maxClippingPlanes, + czm_oneOverPi : czm_oneOverPi, + czm_oneOverTwoPi : czm_oneOverTwoPi, + czm_passCesium3DTile : czm_passCesium3DTile, + czm_passCesium3DTileClassification : czm_passCesium3DTileClassification, + czm_passCesium3DTileClassificationIgnoreShow : czm_passCesium3DTileClassificationIgnoreShow, + czm_passClassification : czm_passClassification, + czm_passCompute : czm_passCompute, + czm_passEnvironment : czm_passEnvironment, + czm_passGlobe : czm_passGlobe, + czm_passOpaque : czm_passOpaque, + czm_passOverlay : czm_passOverlay, + czm_passTerrainClassification : czm_passTerrainClassification, + czm_passTranslucent : czm_passTranslucent, + czm_pi : czm_pi, + czm_piOverFour : czm_piOverFour, + czm_piOverSix : czm_piOverSix, + czm_piOverThree : czm_piOverThree, + czm_piOverTwo : czm_piOverTwo, + czm_radiansPerDegree : czm_radiansPerDegree, + czm_sceneMode2D : czm_sceneMode2D, + czm_sceneMode3D : czm_sceneMode3D, + czm_sceneModeColumbusView : czm_sceneModeColumbusView, + czm_sceneModeMorphing : czm_sceneModeMorphing, + czm_solarRadius : czm_solarRadius, + czm_threePiOver2 : czm_threePiOver2, + czm_twoPi : czm_twoPi, + czm_webMercatorMaxLatitude : czm_webMercatorMaxLatitude, + czm_depthRangeStruct : czm_depthRangeStruct, + czm_ellipsoid : czm_ellipsoid, + czm_material : czm_material, + czm_materialInput : czm_materialInput, + czm_ray : czm_ray, + czm_raySegment : czm_raySegment, + czm_shadowParameters : czm_shadowParameters, + czm_alphaWeight : czm_alphaWeight, + czm_antialias : czm_antialias, + czm_cascadeColor : czm_cascadeColor, + czm_cascadeDistance : czm_cascadeDistance, + czm_cascadeMatrix : czm_cascadeMatrix, + czm_cascadeWeights : czm_cascadeWeights, + czm_columbusViewMorph : czm_columbusViewMorph, + czm_computePosition : czm_computePosition, + czm_cosineAndSine : czm_cosineAndSine, + czm_decompressTextureCoordinates : czm_decompressTextureCoordinates, + czm_depthClampFarPlane : czm_depthClampFarPlane, + czm_discardIfClippedWithIntersect : czm_discardIfClippedWithIntersect, + czm_discardIfClippedWithUnion : czm_discardIfClippedWithUnion, + czm_eastNorthUpToEyeCoordinates : czm_eastNorthUpToEyeCoordinates, + czm_ellipsoidContainsPoint : czm_ellipsoidContainsPoint, + czm_ellipsoidNew : czm_ellipsoidNew, + czm_ellipsoidWgs84TextureCoordinates : czm_ellipsoidWgs84TextureCoordinates, + czm_equalsEpsilon : czm_equalsEpsilon, + czm_eyeOffset : czm_eyeOffset, + czm_eyeToWindowCoordinates : czm_eyeToWindowCoordinates, + czm_fog : czm_fog, + czm_geodeticSurfaceNormal : czm_geodeticSurfaceNormal, + czm_getDefaultMaterial : czm_getDefaultMaterial, + czm_getLambertDiffuse : czm_getLambertDiffuse, + czm_getSpecular : czm_getSpecular, + czm_getWaterNoise : czm_getWaterNoise, + czm_getWgs84EllipsoidEC : czm_getWgs84EllipsoidEC, + czm_HSBToRGB : czm_HSBToRGB, + czm_HSLToRGB : czm_HSLToRGB, + czm_hue : czm_hue, + czm_isEmpty : czm_isEmpty, + czm_isFull : czm_isFull, + czm_latitudeToWebMercatorFraction : czm_latitudeToWebMercatorFraction, + czm_luminance : czm_luminance, + czm_metersPerPixel : czm_metersPerPixel, + czm_modelToWindowCoordinates : czm_modelToWindowCoordinates, + czm_multiplyWithColorBalance : czm_multiplyWithColorBalance, + czm_nearFarScalar : czm_nearFarScalar, + czm_octDecode : czm_octDecode, + czm_packDepth : czm_packDepth, + czm_phong : czm_phong, + czm_pointAlongRay : czm_pointAlongRay, + czm_rayEllipsoidIntersectionInterval : czm_rayEllipsoidIntersectionInterval, + czm_RGBToHSB : czm_RGBToHSB, + czm_RGBToHSL : czm_RGBToHSL, + czm_RGBToXYZ : czm_RGBToXYZ, + czm_saturation : czm_saturation, + czm_shadowDepthCompare : czm_shadowDepthCompare, + czm_shadowVisibility : czm_shadowVisibility, + czm_signNotZero : czm_signNotZero, + czm_tangentToEyeSpaceMatrix : czm_tangentToEyeSpaceMatrix, + czm_translateRelativeToEye : czm_translateRelativeToEye, + czm_translucentPhong : czm_translucentPhong, + czm_transpose : czm_transpose, + czm_unpackDepth : czm_unpackDepth, + czm_windowToEyeCoordinates : czm_windowToEyeCoordinates, + czm_writeDepthClampedToFarPlane : czm_writeDepthClampedToFarPlane, + czm_XYZToRGB : czm_XYZToRGB}; +}); +define('Renderer/ShaderSource',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/DeveloperError', + '../Renderer/modernizeShader', + '../Shaders/Builtin/CzmBuiltins', + './AutomaticUniforms' + ], function( + defaultValue, + defined, + DeveloperError, + modernizeShader, + CzmBuiltins, + AutomaticUniforms) { + 'use strict'; + + function removeComments(source) { + // remove inline comments + source = source.replace(/\/\/.*/g, ''); + // remove multiline comment block + return source.replace(/\/\*\*[\s\S]*?\*\//gm, function(match) { + // preserve the number of lines in the comment block so the line numbers will be correct when debugging shaders + var numberOfLines = match.match(/\n/gm).length; + var replacement = ''; + for (var lineNumber = 0; lineNumber < numberOfLines; ++lineNumber) { + replacement += '\n'; + } + return replacement; + }); + } + + function getDependencyNode(name, glslSource, nodes) { + var dependencyNode; + + // check if already loaded + for (var i = 0; i < nodes.length; ++i) { + if (nodes[i].name === name) { + dependencyNode = nodes[i]; + } + } + + if (!defined(dependencyNode)) { + // strip doc comments so we don't accidentally try to determine a dependency for something found + // in a comment + glslSource = removeComments(glslSource); + + // create new node + dependencyNode = { + name : name, + glslSource : glslSource, + dependsOn : [], + requiredBy : [], + evaluated : false + }; + nodes.push(dependencyNode); + } + + return dependencyNode; + } + + function generateDependencies(currentNode, dependencyNodes) { + if (currentNode.evaluated) { + return; + } + + currentNode.evaluated = true; + + // identify all dependencies that are referenced from this glsl source code + var czmMatches = currentNode.glslSource.match(/\bczm_[a-zA-Z0-9_]*/g); + if (defined(czmMatches) && czmMatches !== null) { + // remove duplicates + czmMatches = czmMatches.filter(function(elem, pos) { + return czmMatches.indexOf(elem) === pos; + }); + + czmMatches.forEach(function(element) { + if (element !== currentNode.name && ShaderSource._czmBuiltinsAndUniforms.hasOwnProperty(element)) { + var referencedNode = getDependencyNode(element, ShaderSource._czmBuiltinsAndUniforms[element], dependencyNodes); + currentNode.dependsOn.push(referencedNode); + referencedNode.requiredBy.push(currentNode); + + // recursive call to find any dependencies of the new node + generateDependencies(referencedNode, dependencyNodes); + } + }); + } + } + + function sortDependencies(dependencyNodes) { + var nodesWithoutIncomingEdges = []; + var allNodes = []; + + while (dependencyNodes.length > 0) { + var node = dependencyNodes.pop(); + allNodes.push(node); + + if (node.requiredBy.length === 0) { + nodesWithoutIncomingEdges.push(node); + } + } + + while (nodesWithoutIncomingEdges.length > 0) { + var currentNode = nodesWithoutIncomingEdges.shift(); + + dependencyNodes.push(currentNode); + + for (var i = 0; i < currentNode.dependsOn.length; ++i) { + // remove the edge from the graph + var referencedNode = currentNode.dependsOn[i]; + var index = referencedNode.requiredBy.indexOf(currentNode); + referencedNode.requiredBy.splice(index, 1); + + // if referenced node has no more incoming edges, add to list + if (referencedNode.requiredBy.length === 0) { + nodesWithoutIncomingEdges.push(referencedNode); + } + } + } + + // if there are any nodes left with incoming edges, then there was a circular dependency somewhere in the graph + var badNodes = []; + for (var j = 0; j < allNodes.length; ++j) { + if (allNodes[j].requiredBy.length !== 0) { + badNodes.push(allNodes[j]); + } + } + + if (badNodes.length !== 0) { + var message = 'A circular dependency was found in the following built-in functions/structs/constants: \n'; + for (var k = 0; k < badNodes.length; ++k) { + message = message + badNodes[k].name + '\n'; + } + throw new DeveloperError(message); + } + } + + function getBuiltinsAndAutomaticUniforms(shaderSource) { + // generate a dependency graph for builtin functions + var dependencyNodes = []; + var root = getDependencyNode('main', shaderSource, dependencyNodes); + generateDependencies(root, dependencyNodes); + sortDependencies(dependencyNodes); + + // Concatenate the source code for the function dependencies. + // Iterate in reverse so that dependent items are declared before they are used. + var builtinsSource = ''; + for (var i = dependencyNodes.length - 1; i >= 0; --i) { + builtinsSource = builtinsSource + dependencyNodes[i].glslSource + '\n'; + } + + return builtinsSource.replace(root.glslSource, ''); + } + + function combineShader(shaderSource, isFragmentShader, context) { + var i; + var length; + + // Combine shader sources, generally for pseudo-polymorphism, e.g., czm_getMaterial. + var combinedSources = ''; + var sources = shaderSource.sources; + if (defined(sources)) { + for (i = 0, length = sources.length; i < length; ++i) { + // #line needs to be on its own line. + combinedSources += '\n#line 0\n' + sources[i]; + } + } + + combinedSources = removeComments(combinedSources); + + // Extract existing shader version from sources + var version; + combinedSources = combinedSources.replace(/#version\s+(.*?)\n/gm, function(match, group1) { + if (defined(version) && version !== group1) { + throw new DeveloperError('inconsistent versions found: ' + version + ' and ' + group1); + } + + // Extract #version to put at the top + version = group1; + + // Replace original #version directive with a new line so the line numbers + // are not off by one. There can be only one #version directive + // and it must appear at the top of the source, only preceded by + // whitespace and comments. + return '\n'; + }); + + // Extract shader extensions from sources + var extensions = []; + combinedSources = combinedSources.replace(/#extension.*\n/gm, function(match) { + // Extract extension to put at the top + extensions.push(match); + + // Replace original #extension directive with a new line so the line numbers + // are not off by one. + return '\n'; + }); + + // Remove precision qualifier + combinedSources = combinedSources.replace(/precision\s(lowp|mediump|highp)\s(float|int);/, ''); + + // Replace main() for picked if desired. + var pickColorQualifier = shaderSource.pickColorQualifier; + if (defined(pickColorQualifier)) { + combinedSources = ShaderSource.createPickFragmentShaderSource(combinedSources, pickColorQualifier); + } + + // combine into single string + var result = ''; + + // #version must be first + // defaults to #version 100 if not specified + if (defined(version)) { + result = '#version ' + version + '\n'; + } + + var extensionsLength = extensions.length; + for (i = 0; i < extensionsLength; i++) { + result += extensions[i]; + } + + if (isFragmentShader) { + result += '\ +#ifdef GL_FRAGMENT_PRECISION_HIGH\n\ + precision highp float;\n\ +#else\n\ + precision mediump float;\n\ +#endif\n\n'; + } + + // Prepend #defines for uber-shaders + var defines = shaderSource.defines; + if (defined(defines)) { + for (i = 0, length = defines.length; i < length; ++i) { + var define = defines[i]; + if (define.length !== 0) { + result += '#define ' + define + '\n'; + } + } + } + + // GLSLModernizer inserts its own layout qualifiers + // at this position in the source + if (context.webgl2) { + result += '#define OUTPUT_DECLARATION\n\n'; + } + + // append built-ins + if (shaderSource.includeBuiltIns) { + result += getBuiltinsAndAutomaticUniforms(combinedSources); + } + + // reset line number + result += '\n#line 0\n'; + + // append actual source + result += combinedSources; + + // modernize the source + if (context.webgl2) { + result = modernizeShader(result, isFragmentShader, true); + } + + return result; + } + + /** + * An object containing various inputs that will be combined to form a final GLSL shader string. + * + * @param {Object} [options] Object with the following properties: + * @param {String[]} [options.sources] An array of strings to combine containing GLSL code for the shader. + * @param {String[]} [options.defines] An array of strings containing GLSL identifiers to <code>#define</code>. + * @param {String} [options.pickColorQualifier] The GLSL qualifier, <code>uniform</code> or <code>varying</code>, for the input <code>czm_pickColor</code>. When defined, a pick fragment shader is generated. + * @param {Boolean} [options.includeBuiltIns=true] If true, referenced built-in functions will be included with the combined shader. Set to false if this shader will become a source in another shader, to avoid duplicating functions. + * + * @exception {DeveloperError} options.pickColorQualifier must be 'uniform' or 'varying'. + * + * @example + * // 1. Prepend #defines to a shader + * var source = new Cesium.ShaderSource({ + * defines : ['WHITE'], + * sources : ['void main() { \n#ifdef WHITE\n gl_FragColor = vec4(1.0); \n#else\n gl_FragColor = vec4(0.0); \n#endif\n }'] + * }); + * + * // 2. Modify a fragment shader for picking + * var source = new Cesium.ShaderSource({ + * sources : ['void main() { gl_FragColor = vec4(1.0); }'], + * pickColorQualifier : 'uniform' + * }); + * + * @private + */ + function ShaderSource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var pickColorQualifier = options.pickColorQualifier; + + if (defined(pickColorQualifier) && pickColorQualifier !== 'uniform' && pickColorQualifier !== 'varying') { + throw new DeveloperError('options.pickColorQualifier must be \'uniform\' or \'varying\'.'); + } + + this.defines = defined(options.defines) ? options.defines.slice(0) : []; + this.sources = defined(options.sources) ? options.sources.slice(0) : []; + this.pickColorQualifier = pickColorQualifier; + this.includeBuiltIns = defaultValue(options.includeBuiltIns, true); + } + + ShaderSource.prototype.clone = function() { + return new ShaderSource({ + sources : this.sources, + defines : this.defines, + pickColorQuantifier : this.pickColorQualifier, + includeBuiltIns : this.includeBuiltIns + }); + }; + + ShaderSource.replaceMain = function(source, renamedMain) { + renamedMain = 'void ' + renamedMain + '()'; + return source.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, renamedMain); + }; + + /** + * Create a single string containing the full, combined vertex shader with all dependencies and defines. + * + * @param {Context} context The current rendering context + * + * @returns {String} The combined shader string. + */ + ShaderSource.prototype.createCombinedVertexShader = function(context) { + return combineShader(this, false, context); + }; + + /** + * Create a single string containing the full, combined fragment shader with all dependencies and defines. + * + * @param {Context} context The current rendering context + * + * @returns {String} The combined shader string. + */ + ShaderSource.prototype.createCombinedFragmentShader = function(context) { + return combineShader(this, true, context); + }; + + /** + * For ShaderProgram testing + * @private + */ + ShaderSource._czmBuiltinsAndUniforms = {}; + + // combine automatic uniforms and Cesium built-ins + for ( var builtinName in CzmBuiltins) { + if (CzmBuiltins.hasOwnProperty(builtinName)) { + ShaderSource._czmBuiltinsAndUniforms[builtinName] = CzmBuiltins[builtinName]; + } + } + for ( var uniformName in AutomaticUniforms) { + if (AutomaticUniforms.hasOwnProperty(uniformName)) { + var uniform = AutomaticUniforms[uniformName]; + if (typeof uniform.getDeclaration === 'function') { + ShaderSource._czmBuiltinsAndUniforms[uniformName] = uniform.getDeclaration(uniformName); + } + } + } + + ShaderSource.createPickVertexShaderSource = function(vertexShaderSource) { + var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_old_main'); + var pickMain = 'attribute vec4 pickColor; \n' + + 'varying vec4 czm_pickColor; \n' + + 'void main() \n' + + '{ \n' + + ' czm_old_main(); \n' + + ' czm_pickColor = pickColor; \n' + + '}'; + + return renamedVS + '\n' + pickMain; + }; + + ShaderSource.createPickFragmentShaderSource = function(fragmentShaderSource, pickColorQualifier) { + var renamedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_old_main'); + var pickMain = pickColorQualifier + ' vec4 czm_pickColor; \n' + + 'void main() \n' + + '{ \n' + + ' czm_old_main(); \n' + + ' if (gl_FragColor.a == 0.0) { \n' + + ' discard; \n' + + ' } \n' + + ' gl_FragColor = czm_pickColor; \n' + + '}'; + + return renamedFS + '\n' + pickMain; + }; + + ShaderSource.findVarying = function(shaderSource, names) { + var sources = shaderSource.sources; + + var namesLength = names.length; + for (var i = 0; i < namesLength; ++i) { + var name = names[i]; + + var sourcesLength = sources.length; + for (var j = 0; j < sourcesLength; ++j) { + if (sources[j].indexOf(name) !== -1) { + return name; + } + } + } + + return undefined; + }; + + var normalVaryingNames = ['v_normalEC', 'v_normal']; + + ShaderSource.findNormalVarying = function(shaderSource) { + return ShaderSource.findVarying(shaderSource, normalVaryingNames); + }; + + var positionVaryingNames = ['v_positionEC']; + + ShaderSource.findPositionVarying = function(shaderSource) { + return ShaderSource.findVarying(shaderSource, positionVaryingNames); + }; + + return ShaderSource; +}); + +define('Renderer/Buffer',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/IndexDatatype', + '../Core/WebGLConstants', + './BufferUsage' + ], function( + Check, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + IndexDatatype, + WebGLConstants, + BufferUsage) { + 'use strict'; + + /** + * @private + */ + function Buffer(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + Check.defined('options.context', options.context); + + if (!defined(options.typedArray) && !defined(options.sizeInBytes)) { + throw new DeveloperError('Either options.sizeInBytes or options.typedArray is required.'); + } + + if (defined(options.typedArray) && defined(options.sizeInBytes)) { + throw new DeveloperError('Cannot pass in both options.sizeInBytes and options.typedArray.'); + } + + if (defined(options.typedArray)) { + Check.typeOf.object('options.typedArray', options.typedArray); + Check.typeOf.number('options.typedArray.byteLength', options.typedArray.byteLength); + } + + if (!BufferUsage.validate(options.usage)) { + throw new DeveloperError('usage is invalid.'); + } + + var gl = options.context._gl; + var bufferTarget = options.bufferTarget; + var typedArray = options.typedArray; + var sizeInBytes = options.sizeInBytes; + var usage = options.usage; + var hasArray = defined(typedArray); + + if (hasArray) { + sizeInBytes = typedArray.byteLength; + } + + Check.typeOf.number.greaterThan('sizeInBytes', sizeInBytes, 0); + + var buffer = gl.createBuffer(); + gl.bindBuffer(bufferTarget, buffer); + gl.bufferData(bufferTarget, hasArray ? typedArray : sizeInBytes, usage); + gl.bindBuffer(bufferTarget, null); + + this._gl = gl; + this._webgl2 = options.context._webgl2; + this._bufferTarget = bufferTarget; + this._sizeInBytes = sizeInBytes; + this._usage = usage; + this._buffer = buffer; + this.vertexArrayDestroyable = true; + } + + /** + * Creates a vertex buffer, which contains untyped vertex data in GPU-controlled memory. + * <br /><br /> + * A vertex array defines the actual makeup of a vertex, e.g., positions, normals, texture coordinates, + * etc., by interpreting the raw data in one or more vertex buffers. + * + * @param {Object} options An object containing the following properties: + * @param {Context} options.context The context in which to create the buffer + * @param {ArrayBufferView} [options.typedArray] A typed array containing the data to copy to the buffer. + * @param {Number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. + * @param {BufferUsage} options.usage Specifies the expected usage pattern of the buffer. On some GL implementations, this can significantly affect performance. See {@link BufferUsage}. + * @returns {VertexBuffer} The vertex buffer, ready to be attached to a vertex array. + * + * @exception {DeveloperError} Must specify either <options.typedArray> or <options.sizeInBytes>, but not both. + * @exception {DeveloperError} The buffer size must be greater than zero. + * @exception {DeveloperError} Invalid <code>usage</code>. + * + * + * @example + * // Example 1. Create a dynamic vertex buffer 16 bytes in size. + * var buffer = Buffer.createVertexBuffer({ + * context : context, + * sizeInBytes : 16, + * usage : BufferUsage.DYNAMIC_DRAW + * }); + * + * @example + * // Example 2. Create a dynamic vertex buffer from three floating-point values. + * // The data copied to the vertex buffer is considered raw bytes until it is + * // interpreted as vertices using a vertex array. + * var positionBuffer = buffer.createVertexBuffer({ + * context : context, + * typedArray : new Float32Array([0, 0, 0]), + * usage : BufferUsage.STATIC_DRAW + * }); + * + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenBuffer.xml|glGenBuffer} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindBuffer.xml|glBindBuffer} with <code>ARRAY_BUFFER</code> + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBufferData.xml|glBufferData} with <code>ARRAY_BUFFER</code> + */ + Buffer.createVertexBuffer = function(options) { + Check.defined('options.context', options.context); + + return new Buffer({ + context: options.context, + bufferTarget: WebGLConstants.ARRAY_BUFFER, + typedArray: options.typedArray, + sizeInBytes: options.sizeInBytes, + usage: options.usage + }); + }; + + /** + * Creates an index buffer, which contains typed indices in GPU-controlled memory. + * <br /><br /> + * An index buffer can be attached to a vertex array to select vertices for rendering. + * <code>Context.draw</code> can render using the entire index buffer or a subset + * of the index buffer defined by an offset and count. + * + * @param {Object} options An object containing the following properties: + * @param {Context} options.context The context in which to create the buffer + * @param {ArrayBufferView} [options.typedArray] A typed array containing the data to copy to the buffer. + * @param {Number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. + * @param {BufferUsage} options.usage Specifies the expected usage pattern of the buffer. On some GL implementations, this can significantly affect performance. See {@link BufferUsage}. + * @param {IndexDatatype} options.indexDatatype The datatype of indices in the buffer. + * @returns {IndexBuffer} The index buffer, ready to be attached to a vertex array. + * + * @exception {DeveloperError} Must specify either <options.typedArray> or <options.sizeInBytes>, but not both. + * @exception {DeveloperError} IndexDatatype.UNSIGNED_INT requires OES_element_index_uint, which is not supported on this system. Check context.elementIndexUint. + * @exception {DeveloperError} The size in bytes must be greater than zero. + * @exception {DeveloperError} Invalid <code>usage</code>. + * @exception {DeveloperError} Invalid <code>indexDatatype</code>. + * + * + * @example + * // Example 1. Create a stream index buffer of unsigned shorts that is + * // 16 bytes in size. + * var buffer = Buffer.createIndexBuffer({ + * context : context, + * sizeInBytes : 16, + * usage : BufferUsage.STREAM_DRAW, + * indexDatatype : IndexDatatype.UNSIGNED_SHORT + * }); + * + * @example + * // Example 2. Create a static index buffer containing three unsigned shorts. + * var buffer = Buffer.createIndexBuffer({ + * context : context, + * typedArray : new Uint16Array([0, 1, 2]), + * usage : BufferUsage.STATIC_DRAW, + * indexDatatype : IndexDatatype.UNSIGNED_SHORT + * }); + * + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenBuffer.xml|glGenBuffer} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindBuffer.xml|glBindBuffer} with <code>ELEMENT_ARRAY_BUFFER</code> + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBufferData.xml|glBufferData} with <code>ELEMENT_ARRAY_BUFFER</code> + */ + Buffer.createIndexBuffer = function(options) { + Check.defined('options.context', options.context); + + if (!IndexDatatype.validate(options.indexDatatype)) { + throw new DeveloperError('Invalid indexDatatype.'); + } + + if (options.indexDatatype === IndexDatatype.UNSIGNED_INT && !options.context.elementIndexUint) { + throw new DeveloperError('IndexDatatype.UNSIGNED_INT requires OES_element_index_uint, which is not supported on this system. Check context.elementIndexUint.'); + } + + var context = options.context; + var indexDatatype = options.indexDatatype; + + var bytesPerIndex = IndexDatatype.getSizeInBytes(indexDatatype); + var buffer = new Buffer({ + context : context, + bufferTarget : WebGLConstants.ELEMENT_ARRAY_BUFFER, + typedArray : options.typedArray, + sizeInBytes : options.sizeInBytes, + usage : options.usage + }); + + var numberOfIndices = buffer.sizeInBytes / bytesPerIndex; + + defineProperties(buffer, { + indexDatatype: { + get : function() { + return indexDatatype; + } + }, + bytesPerIndex : { + get : function() { + return bytesPerIndex; + } + }, + numberOfIndices : { + get : function() { + return numberOfIndices; + } + } + }); + + return buffer; + }; + + defineProperties(Buffer.prototype, { + sizeInBytes : { + get : function() { + return this._sizeInBytes; + } + }, + + usage: { + get : function() { + return this._usage; + } + } + }); + + Buffer.prototype._getBuffer = function() { + return this._buffer; + }; + + Buffer.prototype.copyFromArrayView = function(arrayView, offsetInBytes) { + offsetInBytes = defaultValue(offsetInBytes, 0); + + Check.defined('arrayView', arrayView); + Check.typeOf.number.lessThanOrEquals('offsetInBytes + arrayView.byteLength', offsetInBytes + arrayView.byteLength, this._sizeInBytes); + + var gl = this._gl; + var target = this._bufferTarget; + gl.bindBuffer(target, this._buffer); + gl.bufferSubData(target, offsetInBytes, arrayView); + gl.bindBuffer(target, null); + }; + + Buffer.prototype.copyFromBuffer = function(readBuffer, readOffset, writeOffset, sizeInBytes) { + if (!this._webgl2) { + throw new DeveloperError('A WebGL 2 context is required.'); + } + if (!defined(readBuffer)) { + throw new DeveloperError('readBuffer must be defined.'); + } + if (!defined(sizeInBytes) || sizeInBytes <= 0) { + throw new DeveloperError('sizeInBytes must be defined and be greater than zero.'); + } + if (!defined(readOffset) || readOffset < 0 || readOffset + sizeInBytes > readBuffer._sizeInBytes) { + throw new DeveloperError('readOffset must be greater than or equal to zero and readOffset + sizeInBytes must be less than of equal to readBuffer.sizeInBytes.'); + } + if (!defined(writeOffset) || writeOffset < 0 || writeOffset + sizeInBytes > this._sizeInBytes) { + throw new DeveloperError('writeOffset must be greater than or equal to zero and writeOffset + sizeInBytes must be less than of equal to this.sizeInBytes.'); + } + if (this._buffer === readBuffer._buffer && ((writeOffset >= readOffset && writeOffset < readOffset + sizeInBytes) || (readOffset > writeOffset && readOffset < writeOffset + sizeInBytes))) { + throw new DeveloperError('When readBuffer is equal to this, the ranges [readOffset + sizeInBytes) and [writeOffset, writeOffset + sizeInBytes) must not overlap.'); + } + if ((this._bufferTarget === WebGLConstants.ELEMENT_ARRAY_BUFFER && readBuffer._bufferTarget !== WebGLConstants.ELEMENT_ARRAY_BUFFER) || + (this._bufferTarget !== WebGLConstants.ELEMENT_ARRAY_BUFFER && readBuffer._bufferTarget === WebGLConstants.ELEMENT_ARRAY_BUFFER)) { + throw new DeveloperError('Can not copy an index buffer into another buffer type.'); + } + + var readTarget = WebGLConstants.COPY_READ_BUFFER; + var writeTarget = WebGLConstants.COPY_WRITE_BUFFER; + + var gl = this._gl; + gl.bindBuffer(writeTarget, this._buffer); + gl.bindBuffer(readTarget, readBuffer._buffer); + gl.copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, sizeInBytes); + gl.bindBuffer(writeTarget, null); + gl.bindBuffer(readTarget, null); + }; + + Buffer.prototype.getBufferData = function(arrayView, sourceOffset, destinationOffset, length) { + sourceOffset = defaultValue(sourceOffset, 0); + destinationOffset = defaultValue(destinationOffset, 0); + + if (!this._webgl2) { + throw new DeveloperError('A WebGL 2 context is required.'); + } + if (!defined(arrayView)) { + throw new DeveloperError('arrayView is required.'); + } + + var copyLength; + var elementSize; + var arrayLength = arrayView.byteLength; + if (!defined(length)) { + if (defined(arrayLength)) { + copyLength = arrayLength - destinationOffset; + elementSize = 1; + } else { + arrayLength = arrayView.length; + copyLength = arrayLength - destinationOffset; + elementSize = arrayView.BYTES_PER_ELEMENT; + } + } else { + copyLength = length; + if (defined(arrayLength)) { + elementSize = 1; + } else { + arrayLength = arrayView.length; + elementSize = arrayView.BYTES_PER_ELEMENT; + } + } + + if (destinationOffset < 0 || destinationOffset > arrayLength) { + throw new DeveloperError('destinationOffset must be greater than zero and less than the arrayView length.'); + } + if (destinationOffset + copyLength > arrayLength) { + throw new DeveloperError('destinationOffset + length must be less than or equal to the arrayViewLength.'); + } + if (sourceOffset < 0 || sourceOffset > this._sizeInBytes) { + throw new DeveloperError('sourceOffset must be greater than zero and less than the buffers size.'); + } + if (sourceOffset + copyLength * elementSize > this._sizeInBytes) { + throw new DeveloperError('sourceOffset + length must be less than the buffers size.'); + } + + var gl = this._gl; + var target = WebGLConstants.COPY_READ_BUFFER; + gl.bindBuffer(target, this._buffer); + gl.getBufferSubData(target, sourceOffset, arrayView, destinationOffset, length); + gl.bindBuffer(target, null); + }; + + Buffer.prototype.isDestroyed = function() { + return false; + }; + + Buffer.prototype.destroy = function() { + this._gl.deleteBuffer(this._buffer); + return destroyObject(this); + }; + + return Buffer; +}); + +define('Renderer/VertexArray',[ + '../Core/Check', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Geometry', + '../Core/IndexDatatype', + '../Core/Math', + '../Core/RuntimeError', + './Buffer', + './BufferUsage', + './ContextLimits' + ], function( + Check, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + Geometry, + IndexDatatype, + CesiumMath, + RuntimeError, + Buffer, + BufferUsage, + ContextLimits) { + 'use strict'; + + function addAttribute(attributes, attribute, index, context) { + var hasVertexBuffer = defined(attribute.vertexBuffer); + var hasValue = defined(attribute.value); + var componentsPerAttribute = attribute.value ? attribute.value.length : attribute.componentsPerAttribute; + + if (!hasVertexBuffer && !hasValue) { + throw new DeveloperError('attribute must have a vertexBuffer or a value.'); + } + if (hasVertexBuffer && hasValue) { + throw new DeveloperError('attribute cannot have both a vertexBuffer and a value. It must have either a vertexBuffer property defining per-vertex data or a value property defining data for all vertices.'); + } + if ((componentsPerAttribute !== 1) && + (componentsPerAttribute !== 2) && + (componentsPerAttribute !== 3) && + (componentsPerAttribute !== 4)) { + if (hasValue) { + throw new DeveloperError('attribute.value.length must be in the range [1, 4].'); + } + + throw new DeveloperError('attribute.componentsPerAttribute must be in the range [1, 4].'); + } + if (defined(attribute.componentDatatype) && !ComponentDatatype.validate(attribute.componentDatatype)) { + throw new DeveloperError('attribute must have a valid componentDatatype or not specify it.'); + } + if (defined(attribute.strideInBytes) && (attribute.strideInBytes > 255)) { + // WebGL limit. Not in GL ES. + throw new DeveloperError('attribute must have a strideInBytes less than or equal to 255 or not specify it.'); + } + if (defined(attribute.instanceDivisor) && (attribute.instanceDivisor > 0) && !context.instancedArrays) { + throw new DeveloperError('instanced arrays is not supported'); + } + if (defined(attribute.instanceDivisor) && (attribute.instanceDivisor < 0)) { + throw new DeveloperError('attribute must have an instanceDivisor greater than or equal to zero'); + } + if (defined(attribute.instanceDivisor) && hasValue) { + throw new DeveloperError('attribute cannot have have an instanceDivisor if it is not backed by a buffer'); + } + if (defined(attribute.instanceDivisor) && (attribute.instanceDivisor > 0) && (attribute.index === 0)) { + throw new DeveloperError('attribute zero cannot have an instanceDivisor greater than 0'); + } + + // Shallow copy the attribute; we do not want to copy the vertex buffer. + var attr = { + index : defaultValue(attribute.index, index), + enabled : defaultValue(attribute.enabled, true), + vertexBuffer : attribute.vertexBuffer, + value : hasValue ? attribute.value.slice(0) : undefined, + componentsPerAttribute : componentsPerAttribute, + componentDatatype : defaultValue(attribute.componentDatatype, ComponentDatatype.FLOAT), + normalize : defaultValue(attribute.normalize, false), + offsetInBytes : defaultValue(attribute.offsetInBytes, 0), + strideInBytes : defaultValue(attribute.strideInBytes, 0), + instanceDivisor : defaultValue(attribute.instanceDivisor, 0) + }; + + if (hasVertexBuffer) { + // Common case: vertex buffer for per-vertex data + attr.vertexAttrib = function(gl) { + var index = this.index; + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer._getBuffer()); + gl.vertexAttribPointer(index, this.componentsPerAttribute, this.componentDatatype, this.normalize, this.strideInBytes, this.offsetInBytes); + gl.enableVertexAttribArray(index); + if (this.instanceDivisor > 0) { + context.glVertexAttribDivisor(index, this.instanceDivisor); + context._vertexAttribDivisors[index] = this.instanceDivisor; + context._previousDrawInstanced = true; + } + }; + + attr.disableVertexAttribArray = function(gl) { + gl.disableVertexAttribArray(this.index); + if (this.instanceDivisor > 0) { + context.glVertexAttribDivisor(index, 0); + } + }; + } else { + // Less common case: value array for the same data for each vertex + switch (attr.componentsPerAttribute) { + case 1: + attr.vertexAttrib = function(gl) { + gl.vertexAttrib1fv(this.index, this.value); + }; + break; + case 2: + attr.vertexAttrib = function(gl) { + gl.vertexAttrib2fv(this.index, this.value); + }; + break; + case 3: + attr.vertexAttrib = function(gl) { + gl.vertexAttrib3fv(this.index, this.value); + }; + break; + case 4: + attr.vertexAttrib = function(gl) { + gl.vertexAttrib4fv(this.index, this.value); + }; + break; + } + + attr.disableVertexAttribArray = function(gl) { + }; + } + + attributes.push(attr); + } + + function bind(gl, attributes, indexBuffer) { + for ( var i = 0; i < attributes.length; ++i) { + var attribute = attributes[i]; + if (attribute.enabled) { + attribute.vertexAttrib(gl); + } + } + + if (defined(indexBuffer)) { + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer._getBuffer()); + } + } + + /** + * Creates a vertex array, which defines the attributes making up a vertex, and contains an optional index buffer + * to select vertices for rendering. Attributes are defined using object literals as shown in Example 1 below. + * + * @param {Object} options Object with the following properties: + * @param {Context} options.context The context in which the VertexArray gets created. + * @param {Object[]} options.attributes An array of attributes. + * @param {IndexBuffer} [options.indexBuffer] An optional index buffer. + * + * @returns {VertexArray} The vertex array, ready for use with drawing. + * + * @exception {DeveloperError} Attribute must have a <code>vertexBuffer</code>. + * @exception {DeveloperError} Attribute must have a <code>componentsPerAttribute</code>. + * @exception {DeveloperError} Attribute must have a valid <code>componentDatatype</code> or not specify it. + * @exception {DeveloperError} Attribute must have a <code>strideInBytes</code> less than or equal to 255 or not specify it. + * @exception {DeveloperError} Index n is used by more than one attribute. + * + * + * @example + * // Example 1. Create a vertex array with vertices made up of three floating point + * // values, e.g., a position, from a single vertex buffer. No index buffer is used. + * var positionBuffer = Buffer.createVertexBuffer({ + * context : context, + * sizeInBytes : 12, + * usage : BufferUsage.STATIC_DRAW + * }); + * var attributes = [ + * { + * index : 0, + * enabled : true, + * vertexBuffer : positionBuffer, + * componentsPerAttribute : 3, + * componentDatatype : ComponentDatatype.FLOAT, + * normalize : false, + * offsetInBytes : 0, + * strideInBytes : 0 // tightly packed + * instanceDivisor : 0 // not instanced + * } + * ]; + * var va = new VertexArray({ + * context : context, + * attributes : attributes + * }); + * + * @example + * // Example 2. Create a vertex array with vertices from two different vertex buffers. + * // Each vertex has a three-component position and three-component normal. + * var positionBuffer = Buffer.createVertexBuffer({ + * context : context, + * sizeInBytes : 12, + * usage : BufferUsage.STATIC_DRAW + * }); + * var normalBuffer = Buffer.createVertexBuffer({ + * context : context, + * sizeInBytes : 12, + * usage : BufferUsage.STATIC_DRAW + * }); + * var attributes = [ + * { + * index : 0, + * vertexBuffer : positionBuffer, + * componentsPerAttribute : 3, + * componentDatatype : ComponentDatatype.FLOAT + * }, + * { + * index : 1, + * vertexBuffer : normalBuffer, + * componentsPerAttribute : 3, + * componentDatatype : ComponentDatatype.FLOAT + * } + * ]; + * var va = new VertexArray({ + * context : context, + * attributes : attributes + * }); + * + * @example + * // Example 3. Creates the same vertex layout as Example 2 using a single + * // vertex buffer, instead of two. + * var buffer = Buffer.createVertexBuffer({ + * context : context, + * sizeInBytes : 24, + * usage : BufferUsage.STATIC_DRAW + * }); + * var attributes = [ + * { + * vertexBuffer : buffer, + * componentsPerAttribute : 3, + * componentDatatype : ComponentDatatype.FLOAT, + * offsetInBytes : 0, + * strideInBytes : 24 + * }, + * { + * vertexBuffer : buffer, + * componentsPerAttribute : 3, + * componentDatatype : ComponentDatatype.FLOAT, + * normalize : true, + * offsetInBytes : 12, + * strideInBytes : 24 + * } + * ]; + * var va = new VertexArray({ + * context : context, + * attributes : attributes + * }); + * + * @see Buffer#createVertexBuffer + * @see Buffer#createIndexBuffer + * @see Context#draw + * + * @private + */ + function VertexArray(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + Check.defined('options.context', options.context); + Check.defined('options.attributes', options.attributes); + + var context = options.context; + var gl = context._gl; + var attributes = options.attributes; + var indexBuffer = options.indexBuffer; + + var i; + var vaAttributes = []; + var numberOfVertices = 1; // if every attribute is backed by a single value + var hasInstancedAttributes = false; + var hasConstantAttributes = false; + + var length = attributes.length; + for (i = 0; i < length; ++i) { + addAttribute(vaAttributes, attributes[i], i, context); + } + + length = vaAttributes.length; + for (i = 0; i < length; ++i) { + var attribute = vaAttributes[i]; + + if (defined(attribute.vertexBuffer) && (attribute.instanceDivisor === 0)) { + // This assumes that each vertex buffer in the vertex array has the same number of vertices. + var bytes = attribute.strideInBytes || (attribute.componentsPerAttribute * ComponentDatatype.getSizeInBytes(attribute.componentDatatype)); + numberOfVertices = attribute.vertexBuffer.sizeInBytes / bytes; + break; + } + } + + for (i = 0; i < length; ++i) { + if (vaAttributes[i].instanceDivisor > 0) { + hasInstancedAttributes = true; + } + if (defined(vaAttributes[i].value)) { + hasConstantAttributes = true; + } + } + + // Verify all attribute names are unique + var uniqueIndices = {}; + for (i = 0; i < length; ++i) { + var index = vaAttributes[i].index; + if (uniqueIndices[index]) { + throw new DeveloperError('Index ' + index + ' is used by more than one attribute.'); + } + uniqueIndices[index] = true; + } + + var vao; + + // Setup VAO if supported + if (context.vertexArrayObject) { + vao = context.glCreateVertexArray(); + context.glBindVertexArray(vao); + bind(gl, vaAttributes, indexBuffer); + context.glBindVertexArray(null); + } + + this._numberOfVertices = numberOfVertices; + this._hasInstancedAttributes = hasInstancedAttributes; + this._hasConstantAttributes = hasConstantAttributes; + this._context = context; + this._gl = gl; + this._vao = vao; + this._attributes = vaAttributes; + this._indexBuffer = indexBuffer; + } + + function computeNumberOfVertices(attribute) { + return attribute.values.length / attribute.componentsPerAttribute; + } + + function computeAttributeSizeInBytes(attribute) { + return ComponentDatatype.getSizeInBytes(attribute.componentDatatype) * attribute.componentsPerAttribute; + } + + function interleaveAttributes(attributes) { + var j; + var name; + var attribute; + + // Extract attribute names. + var names = []; + for (name in attributes) { + // Attribute needs to have per-vertex values; not a constant value for all vertices. + if (attributes.hasOwnProperty(name) && + defined(attributes[name]) && + defined(attributes[name].values)) { + names.push(name); + + if (attributes[name].componentDatatype === ComponentDatatype.DOUBLE) { + attributes[name].componentDatatype = ComponentDatatype.FLOAT; + attributes[name].values = ComponentDatatype.createTypedArray(ComponentDatatype.FLOAT, attributes[name].values); + } + } + } + + // Validation. Compute number of vertices. + var numberOfVertices; + var namesLength = names.length; + + if (namesLength > 0) { + numberOfVertices = computeNumberOfVertices(attributes[names[0]]); + + for (j = 1; j < namesLength; ++j) { + var currentNumberOfVertices = computeNumberOfVertices(attributes[names[j]]); + + if (currentNumberOfVertices !== numberOfVertices) { + throw new RuntimeError( + 'Each attribute list must have the same number of vertices. ' + + 'Attribute ' + names[j] + ' has a different number of vertices ' + + '(' + currentNumberOfVertices.toString() + ')' + + ' than attribute ' + names[0] + + ' (' + numberOfVertices.toString() + ').'); + } + } + } + + // Sort attributes by the size of their components. From left to right, a vertex stores floats, shorts, and then bytes. + names.sort(function(left, right) { + return ComponentDatatype.getSizeInBytes(attributes[right].componentDatatype) - ComponentDatatype.getSizeInBytes(attributes[left].componentDatatype); + }); + + // Compute sizes and strides. + var vertexSizeInBytes = 0; + var offsetsInBytes = {}; + + for (j = 0; j < namesLength; ++j) { + name = names[j]; + attribute = attributes[name]; + + offsetsInBytes[name] = vertexSizeInBytes; + vertexSizeInBytes += computeAttributeSizeInBytes(attribute); + } + + if (vertexSizeInBytes > 0) { + // Pad each vertex to be a multiple of the largest component datatype so each + // attribute can be addressed using typed arrays. + var maxComponentSizeInBytes = ComponentDatatype.getSizeInBytes(attributes[names[0]].componentDatatype); // Sorted large to small + var remainder = vertexSizeInBytes % maxComponentSizeInBytes; + if (remainder !== 0) { + vertexSizeInBytes += (maxComponentSizeInBytes - remainder); + } + + // Total vertex buffer size in bytes, including per-vertex padding. + var vertexBufferSizeInBytes = numberOfVertices * vertexSizeInBytes; + + // Create array for interleaved vertices. Each attribute has a different view (pointer) into the array. + var buffer = new ArrayBuffer(vertexBufferSizeInBytes); + var views = {}; + + for (j = 0; j < namesLength; ++j) { + name = names[j]; + var sizeInBytes = ComponentDatatype.getSizeInBytes(attributes[name].componentDatatype); + + views[name] = { + pointer : ComponentDatatype.createTypedArray(attributes[name].componentDatatype, buffer), + index : offsetsInBytes[name] / sizeInBytes, // Offset in ComponentType + strideInComponentType : vertexSizeInBytes / sizeInBytes + }; + } + + // Copy attributes into one interleaved array. + // PERFORMANCE_IDEA: Can we optimize these loops? + for (j = 0; j < numberOfVertices; ++j) { + for ( var n = 0; n < namesLength; ++n) { + name = names[n]; + attribute = attributes[name]; + var values = attribute.values; + var view = views[name]; + var pointer = view.pointer; + + var numberOfComponents = attribute.componentsPerAttribute; + for ( var k = 0; k < numberOfComponents; ++k) { + pointer[view.index + k] = values[(j * numberOfComponents) + k]; + } + + view.index += view.strideInComponentType; + } + } + + return { + buffer : buffer, + offsetsInBytes : offsetsInBytes, + vertexSizeInBytes : vertexSizeInBytes + }; + } + + // No attributes to interleave. + return undefined; + } + + /** + * Creates a vertex array from a geometry. A geometry contains vertex attributes and optional index data + * in system memory, whereas a vertex array contains vertex buffers and an optional index buffer in WebGL + * memory for use with rendering. + * <br /><br /> + * The <code>geometry</code> argument should use the standard layout like the geometry returned by {@link BoxGeometry}. + * <br /><br /> + * <code>options</code> can have four properties: + * <ul> + * <li><code>geometry</code>: The source geometry containing data used to create the vertex array.</li> + * <li><code>attributeLocations</code>: An object that maps geometry attribute names to vertex shader attribute locations.</li> + * <li><code>bufferUsage</code>: The expected usage pattern of the vertex array's buffers. On some WebGL implementations, this can significantly affect performance. See {@link BufferUsage}. Default: <code>BufferUsage.DYNAMIC_DRAW</code>.</li> + * <li><code>interleave</code>: Determines if all attributes are interleaved in a single vertex buffer or if each attribute is stored in a separate vertex buffer. Default: <code>false</code>.</li> + * </ul> + * <br /> + * If <code>options</code> is not specified or the <code>geometry</code> contains no data, the returned vertex array is empty. + * + * @param {Object} options An object defining the geometry, attribute indices, buffer usage, and vertex layout used to create the vertex array. + * + * @exception {RuntimeError} Each attribute list must have the same number of vertices. + * @exception {DeveloperError} The geometry must have zero or one index lists. + * @exception {DeveloperError} Index n is used by more than one attribute. + * + * + * @example + * // Example 1. Creates a vertex array for rendering a box. The default dynamic draw + * // usage is used for the created vertex and index buffer. The attributes are not + * // interleaved by default. + * var geometry = new BoxGeometry(); + * var va = VertexArray.fromGeometry({ + * context : context, + * geometry : geometry, + * attributeLocations : GeometryPipeline.createAttributeLocations(geometry), + * }); + * + * @example + * // Example 2. Creates a vertex array with interleaved attributes in a + * // single vertex buffer. The vertex and index buffer have static draw usage. + * var va = VertexArray.fromGeometry({ + * context : context, + * geometry : geometry, + * attributeLocations : GeometryPipeline.createAttributeLocations(geometry), + * bufferUsage : BufferUsage.STATIC_DRAW, + * interleave : true + * }); + * + * @example + * // Example 3. When the caller destroys the vertex array, it also destroys the + * // attached vertex buffer(s) and index buffer. + * va = va.destroy(); + * + * @see Buffer#createVertexBuffer + * @see Buffer#createIndexBuffer + * @see GeometryPipeline.createAttributeLocations + * @see ShaderProgram + */ + VertexArray.fromGeometry = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + Check.defined('options.context', options.context); + + var context = options.context; + var geometry = defaultValue(options.geometry, defaultValue.EMPTY_OBJECT); + + var bufferUsage = defaultValue(options.bufferUsage, BufferUsage.DYNAMIC_DRAW); + + var attributeLocations = defaultValue(options.attributeLocations, defaultValue.EMPTY_OBJECT); + var interleave = defaultValue(options.interleave, false); + var createdVAAttributes = options.vertexArrayAttributes; + + var name; + var attribute; + var vertexBuffer; + var vaAttributes = (defined(createdVAAttributes)) ? createdVAAttributes : []; + var attributes = geometry.attributes; + + if (interleave) { + // Use a single vertex buffer with interleaved vertices. + var interleavedAttributes = interleaveAttributes(attributes); + if (defined(interleavedAttributes)) { + vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : interleavedAttributes.buffer, + usage : bufferUsage + }); + var offsetsInBytes = interleavedAttributes.offsetsInBytes; + var strideInBytes = interleavedAttributes.vertexSizeInBytes; + + for (name in attributes) { + if (attributes.hasOwnProperty(name) && defined(attributes[name])) { + attribute = attributes[name]; + + if (defined(attribute.values)) { + // Common case: per-vertex attributes + vaAttributes.push({ + index : attributeLocations[name], + vertexBuffer : vertexBuffer, + componentDatatype : attribute.componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize, + offsetInBytes : offsetsInBytes[name], + strideInBytes : strideInBytes + }); + } else { + // Constant attribute for all vertices + vaAttributes.push({ + index : attributeLocations[name], + value : attribute.value, + componentDatatype : attribute.componentDatatype, + normalize : attribute.normalize + }); + } + } + } + } + } else { + // One vertex buffer per attribute. + for (name in attributes) { + if (attributes.hasOwnProperty(name) && defined(attributes[name])) { + attribute = attributes[name]; + + var componentDatatype = attribute.componentDatatype; + if (componentDatatype === ComponentDatatype.DOUBLE) { + componentDatatype = ComponentDatatype.FLOAT; + } + + vertexBuffer = undefined; + if (defined(attribute.values)) { + vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : ComponentDatatype.createTypedArray(componentDatatype, attribute.values), + usage : bufferUsage + }); + } + + vaAttributes.push({ + index : attributeLocations[name], + vertexBuffer : vertexBuffer, + value : attribute.value, + componentDatatype : componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize + }); + } + } + } + + var indexBuffer; + var indices = geometry.indices; + if (defined(indices)) { + if ((Geometry.computeNumberOfVertices(geometry) >= CesiumMath.SIXTY_FOUR_KILOBYTES) && context.elementIndexUint) { + indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : new Uint32Array(indices), + usage : bufferUsage, + indexDatatype : IndexDatatype.UNSIGNED_INT + }); + } else{ + indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : new Uint16Array(indices), + usage : bufferUsage, + indexDatatype : IndexDatatype.UNSIGNED_SHORT + }); + } + } + + return new VertexArray({ + context : context, + attributes : vaAttributes, + indexBuffer : indexBuffer + }); + }; + + defineProperties(VertexArray.prototype, { + numberOfAttributes : { + get : function() { + return this._attributes.length; + } + }, + numberOfVertices : { + get : function() { + return this._numberOfVertices; + } + }, + indexBuffer : { + get : function() { + return this._indexBuffer; + } + } + }); + + /** + * index is the location in the array of attributes, not the index property of an attribute. + */ + VertexArray.prototype.getAttribute = function(index) { + Check.defined('index', index); + + return this._attributes[index]; + }; + + // Workaround for ANGLE, where the attribute divisor seems to be part of the global state instead + // of the VAO state. This function is called when the vao is bound, and should be removed + // once the ANGLE issue is resolved. Setting the divisor should normally happen in vertexAttrib and + // disableVertexAttribArray. + function setVertexAttribDivisor(vertexArray) { + var context = vertexArray._context; + var hasInstancedAttributes = vertexArray._hasInstancedAttributes; + if (!hasInstancedAttributes && !context._previousDrawInstanced) { + return; + } + context._previousDrawInstanced = hasInstancedAttributes; + + var divisors = context._vertexAttribDivisors; + var attributes = vertexArray._attributes; + var maxAttributes = ContextLimits.maximumVertexAttributes; + var i; + + if (hasInstancedAttributes) { + var length = attributes.length; + for (i = 0; i < length; ++i) { + var attribute = attributes[i]; + if (attribute.enabled) { + var divisor = attribute.instanceDivisor; + var index = attribute.index; + if (divisor !== divisors[index]) { + context.glVertexAttribDivisor(index, divisor); + divisors[index] = divisor; + } + } + } + } else { + for (i = 0; i < maxAttributes; ++i) { + if (divisors[i] > 0) { + context.glVertexAttribDivisor(i, 0); + divisors[i] = 0; + } + } + } + } + + // Vertex attributes backed by a constant value go through vertexAttrib[1234]f[v] + // which is part of context state rather than VAO state. + function setConstantAttributes(vertexArray, gl) { + var attributes = vertexArray._attributes; + var length = attributes.length; + for (var i = 0; i < length; ++i) { + var attribute = attributes[i]; + if (attribute.enabled && defined(attribute.value)) { + attribute.vertexAttrib(gl); + } + } + } + + VertexArray.prototype._bind = function() { + if (defined(this._vao)) { + this._context.glBindVertexArray(this._vao); + if (this._context.instancedArrays) { + setVertexAttribDivisor(this); + } + if (this._hasConstantAttributes) { + setConstantAttributes(this, this._gl); + } + } else { + bind(this._gl, this._attributes, this._indexBuffer); + } + }; + + VertexArray.prototype._unBind = function() { + if (defined(this._vao)) { + this._context.glBindVertexArray(null); + } else { + var attributes = this._attributes; + var gl = this._gl; + + for ( var i = 0; i < attributes.length; ++i) { + var attribute = attributes[i]; + if (attribute.enabled) { + attribute.disableVertexAttribArray(gl); + } + } + if (this._indexBuffer) { + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + } + }; + + VertexArray.prototype.isDestroyed = function() { + return false; + }; + + VertexArray.prototype.destroy = function() { + var attributes = this._attributes; + for ( var i = 0; i < attributes.length; ++i) { + var vertexBuffer = attributes[i].vertexBuffer; + if (defined(vertexBuffer) && !vertexBuffer.isDestroyed() && vertexBuffer.vertexArrayDestroyable) { + vertexBuffer.destroy(); + } + } + + var indexBuffer = this._indexBuffer; + if (defined(indexBuffer) && !indexBuffer.isDestroyed() && indexBuffer.vertexArrayDestroyable) { + indexBuffer.destroy(); + } + + if (defined(this._vao)) { + this._context.glDeleteVertexArray(this._vao); + } + + return destroyObject(this); + }; + + return VertexArray; +}); + +define('Scene/BatchTable',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/FeatureDetection', + '../Core/Math', + '../Core/PixelFormat', + '../Renderer/ContextLimits', + '../Renderer/PixelDatatype', + '../Renderer/Sampler', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + combine, + ComponentDatatype, + defined, + defineProperties, + destroyObject, + DeveloperError, + FeatureDetection, + CesiumMath, + PixelFormat, + ContextLimits, + PixelDatatype, + Sampler, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter) { + 'use strict'; + + /** + * Creates a texture to look up per instance attributes for batched primitives. For example, store each primitive's pick color in the texture. + * + * @alias BatchTable + * @constructor + * @private + * + * @param {Context} context The context in which the batch table is created. + * @param {Object[]} attributes An array of objects describing a per instance attribute. Each object contains a datatype, components per attributes, whether it is normalized and a function name + * to retrieve the value in the vertex shader. + * @param {Number} numberOfInstances The number of instances in a batch table. + * + * @example + * // create the batch table + * var attributes = [{ + * functionName : 'getShow', + * componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + * componentsPerAttribute : 1 + * }, { + * functionName : 'getPickColor', + * componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + * componentsPerAttribute : 4, + * normalize : true + * }]; + * var batchTable = new BatchTable(context, attributes, 5); + * + * // when creating the draw commands, update the uniform map and the vertex shader + * vertexShaderSource = batchTable.getVertexShaderCallback()(vertexShaderSource); + * var shaderProgram = ShaderProgram.fromCache({ + * // ... + * vertexShaderSource : vertexShaderSource, + * }); + * + * drawCommand.shaderProgram = shaderProgram; + * drawCommand.uniformMap = batchTable.getUniformMapCallback()(uniformMap); + * + * // use the attribute function names in the shader to retrieve the instance values + * // ... + * attribute float batchId; + * + * void main() { + * // ... + * float show = getShow(batchId); + * vec3 pickColor = getPickColor(batchId); + * // ... + * } + */ + function BatchTable(context, attributes, numberOfInstances) { + if (!defined(context)) { + throw new DeveloperError('context is required'); + } + if (!defined(attributes)) { + throw new DeveloperError('attributes is required'); + } + if (!defined(numberOfInstances)) { + throw new DeveloperError('numberOfInstances is required'); + } + + this._attributes = attributes; + this._numberOfInstances = numberOfInstances; + + if (attributes.length === 0) { + return; + } + + // PERFORMANCE_IDEA: We may be able to arrange the attributes so they can be packing into fewer texels. + // Right now, an attribute with one component uses an entire texel when 4 single component attributes can + // be packed into a texel. + // + // Packing floats into unsigned byte textures makes the problem worse. A single component float attribute + // will be packed into a single texel leaving 3 texels unused. 4 texels are reserved for each float attribute + // regardless of how many components it has. + var pixelDatatype = getDatatype(attributes); + var textureFloatSupported = context.floatingPointTexture; + var packFloats = pixelDatatype === PixelDatatype.FLOAT && !textureFloatSupported; + var offsets = createOffsets(attributes, packFloats); + + var stride = getStride(offsets, attributes, packFloats); + var maxNumberOfInstancesPerRow = Math.floor(ContextLimits.maximumTextureSize / stride); + + var instancesPerWidth = Math.min(numberOfInstances, maxNumberOfInstancesPerRow); + var width = stride * instancesPerWidth; + var height = Math.ceil(numberOfInstances / instancesPerWidth); + + var stepX = 1.0 / width; + var centerX = stepX * 0.5; + var stepY = 1.0 / height; + var centerY = stepY * 0.5; + + this._textureDimensions = new Cartesian2(width, height); + this._textureStep = new Cartesian4(stepX, centerX, stepY, centerY); + this._pixelDatatype = !packFloats ? pixelDatatype : PixelDatatype.UNSIGNED_BYTE; + this._packFloats = packFloats; + this._offsets = offsets; + this._stride = stride; + this._texture = undefined; + + var batchLength = 4 * width * height; + this._batchValues = pixelDatatype === PixelDatatype.FLOAT && !packFloats ? new Float32Array(batchLength) : new Uint8Array(batchLength); + this._batchValuesDirty = false; + } + + defineProperties(BatchTable.prototype, { + /** + * The attribute descriptions. + * @memberOf BatchTable.prototype + * @type {Object[]} + * @readonly + */ + attributes : { + get : function() { + return this._attributes; + } + }, + /** + * The number of instances. + * @memberOf BatchTable.prototype + * @type {Number} + * @readonly + */ + numberOfInstances : { + get : function () { + return this._numberOfInstances; + } + } + }); + + function getDatatype(attributes) { + var foundFloatDatatype = false; + var length = attributes.length; + for (var i = 0; i < length; ++i) { + if (attributes[i].componentDatatype !== ComponentDatatype.UNSIGNED_BYTE) { + foundFloatDatatype = true; + break; + } + } + return foundFloatDatatype ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE; + } + + function getAttributeType(attributes, attributeIndex) { + var componentsPerAttribute = attributes[attributeIndex].componentsPerAttribute; + if (componentsPerAttribute === 2) { + return Cartesian2; + } else if (componentsPerAttribute === 3) { + return Cartesian3; + } else if (componentsPerAttribute === 4) { + return Cartesian4; + } + return Number; + } + + function createOffsets(attributes, packFloats) { + var offsets = new Array(attributes.length); + + var currentOffset = 0; + var attributesLength = attributes.length; + for (var i = 0; i < attributesLength; ++i) { + var attribute = attributes[i]; + var componentDatatype = attribute.componentDatatype; + + offsets[i] = currentOffset; + + if (componentDatatype !== ComponentDatatype.UNSIGNED_BYTE && packFloats) { + currentOffset += 4; + } else { + ++currentOffset; + } + } + + return offsets; + } + + function getStride(offsets, attributes, packFloats) { + var length = offsets.length; + var lastOffset = offsets[length - 1]; + var lastAttribute = attributes[length - 1]; + var componentDatatype = lastAttribute.componentDatatype; + + if (componentDatatype !== ComponentDatatype.UNSIGNED_BYTE && packFloats) { + return lastOffset + 4; + } + return lastOffset + 1; + } + + var scratchPackedFloatCartesian4 = new Cartesian4(); + + var SHIFT_LEFT_8 = 256.0; + var SHIFT_LEFT_16 = 65536.0; + var SHIFT_LEFT_24 = 16777216.0; + + var SHIFT_RIGHT_8 = 1.0 / SHIFT_LEFT_8; + var SHIFT_RIGHT_16 = 1.0 / SHIFT_LEFT_16; + var SHIFT_RIGHT_24 = 1.0 / SHIFT_LEFT_24; + + var BIAS = 38.0; + + function unpackFloat(value) { + var temp = value.w / 2.0; + var exponent = Math.floor(temp); + var sign = (temp - exponent) * 2.0; + exponent = exponent - BIAS; + + sign = sign * 2.0 - 1.0; + sign = -sign; + + if (exponent >= BIAS) { + return sign < 0.0 ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY; + } + + var unpacked = sign * value.x * SHIFT_RIGHT_8; + unpacked += sign * value.y * SHIFT_RIGHT_16; + unpacked += sign * value.z * SHIFT_RIGHT_24; + + return unpacked * Math.pow(10.0, exponent); + } + + function getPackedFloat(array, index, result) { + var packed = Cartesian4.unpack(array, index, scratchPackedFloatCartesian4); + var x = unpackFloat(packed); + + packed = Cartesian4.unpack(array, index + 4, scratchPackedFloatCartesian4); + var y = unpackFloat(packed); + + packed = Cartesian4.unpack(array, index + 8, scratchPackedFloatCartesian4); + var z = unpackFloat(packed); + + packed = Cartesian4.unpack(array, index + 12, scratchPackedFloatCartesian4); + var w = unpackFloat(packed); + + return Cartesian4.fromElements(x, y, z, w, result); + } + + if (!FeatureDetection.supportsTypedArrays()) { + return; + } + var scratchFloatArray = new Float32Array(1); + + function packFloat(value, result) { + scratchFloatArray[0] = value; + value = scratchFloatArray[0]; + + if (value === 0.0) { + return Cartesian4.clone(Cartesian4.ZERO, result); + } + + var sign = value < 0.0 ? 1.0 : 0.0; + var exponent; + + if (!isFinite(value)) { + value = 0.1; + exponent = BIAS; + } else { + value = Math.abs(value); + exponent = Math.floor(CesiumMath.logBase(value, 10)) + 1.0; + value = value / Math.pow(10.0, exponent); + } + + var temp = value * SHIFT_LEFT_8; + result.x = Math.floor(temp); + temp = (temp - result.x) * SHIFT_LEFT_8; + result.y = Math.floor(temp); + temp = (temp - result.y) * SHIFT_LEFT_8; + result.z = Math.floor(temp); + result.w = (exponent + BIAS) * 2.0 + sign; + + return result; + } + + function setPackedAttribute(value, array, index) { + var packed = packFloat(value.x, scratchPackedFloatCartesian4); + Cartesian4.pack(packed, array, index); + + packed = packFloat(value.y, packed); + Cartesian4.pack(packed, array, index + 4); + + packed = packFloat(value.z, packed); + Cartesian4.pack(packed, array, index + 8); + + packed = packFloat(value.w, packed); + Cartesian4.pack(packed, array, index + 12); + } + + var scratchGetAttributeCartesian4 = new Cartesian4(); + + /** + * Gets the value of an attribute in the table. + * + * @param {Number} instanceIndex The index of the instance. + * @param {Number} attributeIndex The index of the attribute. + * @param {undefined|Cartesian2|Cartesian3|Cartesian4} [result] The object onto which to store the result. The type is dependent on the attribute's number of components. + * @returns {Number|Cartesian2|Cartesian3|Cartesian4} The attribute value stored for the instance. + * + * @exception {DeveloperError} instanceIndex is out of range. + * @exception {DeveloperError} attributeIndex is out of range. + */ + BatchTable.prototype.getBatchedAttribute = function(instanceIndex, attributeIndex, result) { + if (instanceIndex < 0 || instanceIndex >= this._numberOfInstances) { + throw new DeveloperError('instanceIndex is out of range.'); + } + if (attributeIndex < 0 || attributeIndex >= this._attributes.length) { + throw new DeveloperError('attributeIndex is out of range'); + } + + var attributes = this._attributes; + var offset = this._offsets[attributeIndex]; + var stride = this._stride; + + var index = 4 * stride * instanceIndex + 4 * offset; + var value; + + if (this._packFloats && attributes[attributeIndex].componentDatatype !== PixelDatatype.UNSIGNED_BYTE) { + value = getPackedFloat(this._batchValues, index, scratchGetAttributeCartesian4); + } else { + value = Cartesian4.unpack(this._batchValues, index, scratchGetAttributeCartesian4); + } + + var attributeType = getAttributeType(attributes, attributeIndex); + if (defined(attributeType.fromCartesian4)) { + return attributeType.fromCartesian4(value, result); + } else if (defined(attributeType.clone)) { + return attributeType.clone(value, result); + } + + return value.x; + }; + + var setAttributeScratchValues = [undefined, undefined, new Cartesian2(), new Cartesian3(), new Cartesian4()]; + var setAttributeScratchCartesian4 = new Cartesian4(); + + /** + * Sets the value of an attribute in the table. + * + * @param {Number} instanceIndex The index of the instance. + * @param {Number} attributeIndex The index of the attribute. + * @param {Number|Cartesian2|Cartesian3|Cartesian4} value The value to be stored in the table. The type of value will depend on the number of components of the attribute. + * + * @exception {DeveloperError} instanceIndex is out of range. + * @exception {DeveloperError} attributeIndex is out of range. + */ + BatchTable.prototype.setBatchedAttribute = function(instanceIndex, attributeIndex, value) { + if (instanceIndex < 0 || instanceIndex >= this._numberOfInstances) { + throw new DeveloperError('instanceIndex is out of range.'); + } + if (attributeIndex < 0 || attributeIndex >= this._attributes.length) { + throw new DeveloperError('attributeIndex is out of range'); + } + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var attributes = this._attributes; + var result = setAttributeScratchValues[attributes[attributeIndex].componentsPerAttribute]; + var currentAttribute = this.getBatchedAttribute(instanceIndex, attributeIndex, result); + var attributeType = getAttributeType(this._attributes, attributeIndex); + var entriesEqual = defined(attributeType.equals) ? attributeType.equals(currentAttribute, value) : currentAttribute === value; + if (entriesEqual) { + return; + } + + var attributeValue = setAttributeScratchCartesian4; + attributeValue.x = defined(value.x) ? value.x : value; + attributeValue.y = defined(value.y) ? value.y : 0.0; + attributeValue.z = defined(value.z) ? value.z : 0.0; + attributeValue.w = defined(value.w) ? value.w : 0.0; + + var offset = this._offsets[attributeIndex]; + var stride = this._stride; + var index = 4 * stride * instanceIndex + 4 * offset; + + if (this._packFloats && attributes[attributeIndex].componentDatatype !== PixelDatatype.UNSIGNED_BYTE) { + setPackedAttribute(attributeValue, this._batchValues, index); + } else { + Cartesian4.pack(attributeValue, this._batchValues, index); + } + + this._batchValuesDirty = true; + }; + + function createTexture(batchTable, context) { + var dimensions = batchTable._textureDimensions; + batchTable._texture = new Texture({ + context : context, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : batchTable._pixelDatatype, + width : dimensions.x, + height : dimensions.y, + sampler : new Sampler({ + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }) + }); + } + + function updateTexture(batchTable) { + var dimensions = batchTable._textureDimensions; + batchTable._texture.copyFrom({ + width : dimensions.x, + height : dimensions.y, + arrayBufferView : batchTable._batchValues + }); + } + + /** + * Creates/updates the batch table texture. + * @param {FrameState} frameState The frame state. + * + * @exception {RuntimeError} The floating point texture extension is required but not supported. + */ + BatchTable.prototype.update = function(frameState) { + if ((defined(this._texture) && !this._batchValuesDirty) || this._attributes.length === 0) { + return; + } + + this._batchValuesDirty = false; + + if (!defined(this._texture)) { + createTexture(this, frameState.context); + } + updateTexture(this); + }; + + /** + * Gets a function that will update a uniform map to contain values for looking up values in the batch table. + * + * @returns {BatchTable~updateUniformMapCallback} A callback for updating uniform maps. + */ + BatchTable.prototype.getUniformMapCallback = function() { + var that = this; + return function(uniformMap) { + if (that._attributes.length === 0) { + return uniformMap; + } + + var batchUniformMap = { + batchTexture : function() { + return that._texture; + }, + batchTextureDimensions : function() { + return that._textureDimensions; + }, + batchTextureStep : function() { + return that._textureStep; + } + }; + return combine(uniformMap, batchUniformMap); + }; + }; + + function getGlslComputeSt(batchTable) { + var stride = batchTable._stride; + + // GLSL batchId is zero-based: [0, numberOfInstances - 1] + if (batchTable._textureDimensions.y === 1) { + return 'uniform vec4 batchTextureStep; \n' + + 'vec2 computeSt(float batchId) \n' + + '{ \n' + + ' float stepX = batchTextureStep.x; \n' + + ' float centerX = batchTextureStep.y; \n' + + ' float numberOfAttributes = float('+ stride + '); \n' + + ' return vec2(centerX + (batchId * numberOfAttributes * stepX), 0.5); \n' + + '} \n'; + } + + return 'uniform vec4 batchTextureStep; \n' + + 'uniform vec2 batchTextureDimensions; \n' + + 'vec2 computeSt(float batchId) \n' + + '{ \n' + + ' float stepX = batchTextureStep.x; \n' + + ' float centerX = batchTextureStep.y; \n' + + ' float stepY = batchTextureStep.z; \n' + + ' float centerY = batchTextureStep.w; \n' + + ' float numberOfAttributes = float('+ stride + '); \n' + + ' float xId = mod(batchId * numberOfAttributes, batchTextureDimensions.x); \n' + + ' float yId = floor(batchId * numberOfAttributes / batchTextureDimensions.x); \n' + + ' return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n' + + '} \n'; + } + + function getGlslUnpackFloat(batchTable) { + if (!batchTable._packFloats) { + return ''; + } + + return 'float unpackFloat(vec4 value) \n' + + '{ \n' + + ' value *= 255.0; \n' + + ' float temp = value.w / 2.0; \n' + + ' float exponent = floor(temp); \n' + + ' float sign = (temp - exponent) * 2.0; \n' + + ' exponent = exponent - float(' + BIAS + '); \n' + + ' sign = sign * 2.0 - 1.0; \n' + + ' sign = -sign; \n' + + ' float unpacked = sign * value.x * float(' + SHIFT_RIGHT_8 + '); \n' + + ' unpacked += sign * value.y * float(' + SHIFT_RIGHT_16 + '); \n' + + ' unpacked += sign * value.z * float(' + SHIFT_RIGHT_24 + '); \n' + + ' return unpacked * pow(10.0, exponent); \n' + + '} \n'; + } + + function getComponentType(componentsPerAttribute) { + if (componentsPerAttribute === 1) { + return 'float'; + } + return 'vec' + componentsPerAttribute; + } + + function getComponentSwizzle(componentsPerAttribute) { + if (componentsPerAttribute === 1) { + return '.x'; + } else if (componentsPerAttribute === 2) { + return '.xy'; + } else if (componentsPerAttribute === 3) { + return '.xyz'; + } + return ''; + } + + function getGlslAttributeFunction(batchTable, attributeIndex) { + var attributes = batchTable._attributes; + var attribute = attributes[attributeIndex]; + var componentsPerAttribute = attribute.componentsPerAttribute; + var functionName = attribute.functionName; + var functionReturnType = getComponentType(componentsPerAttribute); + var functionReturnValue = getComponentSwizzle(componentsPerAttribute); + + var offset = batchTable._offsets[attributeIndex]; + + var glslFunction = + functionReturnType + ' ' + functionName + '(float batchId) \n' + + '{ \n' + + ' vec2 st = computeSt(batchId); \n' + + ' st.x += batchTextureStep.x * float(' + offset + '); \n'; + + if (batchTable._packFloats && attribute.componentDatatype !== PixelDatatype.UNSIGNED_BYTE) { + glslFunction += 'vec4 textureValue; \n' + + 'textureValue.x = unpackFloat(texture2D(batchTexture, st)); \n' + + 'textureValue.y = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x, 0.0))); \n' + + 'textureValue.z = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 2.0, 0.0))); \n' + + 'textureValue.w = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 3.0, 0.0))); \n'; + + } else { + glslFunction += ' vec4 textureValue = texture2D(batchTexture, st); \n'; + } + + glslFunction += ' ' + functionReturnType + ' value = textureValue' + functionReturnValue + '; \n'; + + if (batchTable._pixelDatatype === PixelDatatype.UNSIGNED_BYTE && attribute.componentDatatype === ComponentDatatype.UNSIGNED_BYTE && !attribute.normalize) { + glslFunction += 'value *= 255.0; \n'; + } else if (batchTable._pixelDatatype === PixelDatatype.FLOAT && attribute.componentDatatype === ComponentDatatype.UNSIGNED_BYTE && attribute.normalize) { + glslFunction += 'value /= 255.0; \n'; + } + + glslFunction += + ' return value; \n' + + '} \n'; + return glslFunction; + } + + /** + * Gets a function that will update a vertex shader to contain functions for looking up values in the batch table. + * + * @returns {BatchTable~updateVertexShaderSourceCallback} A callback for updating a vertex shader source. + */ + BatchTable.prototype.getVertexShaderCallback = function() { + var attributes = this._attributes; + if (attributes.length === 0) { + return function(source) { + return source; + }; + } + + var batchTableShader = 'uniform sampler2D batchTexture; \n'; + batchTableShader += getGlslComputeSt(this) + '\n'; + batchTableShader += getGlslUnpackFloat(this) + '\n'; + + var length = attributes.length; + for (var i = 0; i < length; ++i) { + batchTableShader += getGlslAttributeFunction(this, i); + } + + return function(source) { + var mainIndex = source.indexOf('void main'); + var beforeMain = source.substring(0, mainIndex); + var afterMain = source.substring(mainIndex); + return beforeMain + '\n' + batchTableShader + '\n' + afterMain; + }; + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see BatchTable#destroy + */ + BatchTable.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see BatchTable#isDestroyed + */ + BatchTable.prototype.destroy = function() { + this._texture = this._texture && this._texture.destroy(); + return destroyObject(this); + }; + + /** + * A callback for updating uniform maps. + * @callback BatchTable~updateUniformMapCallback + * + * @param {Object} uniformMap The uniform map. + * @returns {Object} The new uniform map with properties for retrieving values from the batch table. + */ + + /** + * A callback for updating a vertex shader source. + * @callback BatchTable~updateVertexShaderSourceCallback + * + * @param {String} vertexShaderSource The vertex shader source. + * @returns {String} The new vertex shader source with the functions for retrieving batch table values injected. + */ + + return BatchTable; +}); + +define('Scene/DepthFunction',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + + /** + * Determines the function used to compare two depths for the depth test. + * + * @exports DepthFunction + */ + var DepthFunction = { + /** + * The depth test never passes. + * + * @type {Number} + * @constant + */ + NEVER : WebGLConstants.NEVER, + + /** + * The depth test passes if the incoming depth is less than the stored depth. + * + * @type {Number} + * @constant + */ + LESS : WebGLConstants.LESS, + + /** + * The depth test passes if the incoming depth is equal to the stored depth. + * + * @type {Number} + * @constant + */ + EQUAL : WebGLConstants.EQUAL, + + /** + * The depth test passes if the incoming depth is less than or equal to the stored depth. + * + * @type {Number} + * @constant + */ + LESS_OR_EQUAL : WebGLConstants.LEQUAL, + + /** + * The depth test passes if the incoming depth is greater than the stored depth. + * + * @type {Number} + * @constant + */ + GREATER : WebGLConstants.GREATER, + + /** + * The depth test passes if the incoming depth is not equal to the stored depth. + * + * @type {Number} + * @constant + */ + NOT_EQUAL : WebGLConstants.NOTEQUAL, + + /** + * The depth test passes if the incoming depth is greater than or equal to the stored depth. + * + * @type {Number} + * @constant + */ + GREATER_OR_EQUAL : WebGLConstants.GEQUAL, + + /** + * The depth test always passes. + * + * @type {Number} + * @constant + */ + ALWAYS : WebGLConstants.ALWAYS + }; + + return freezeObject(DepthFunction); +}); + +define('Scene/PrimitivePipeline',[ + '../Core/BoundingSphere', + '../Core/ComponentDatatype', + '../Core/defined', + '../Core/DeveloperError', + '../Core/Ellipsoid', + '../Core/FeatureDetection', + '../Core/GeographicProjection', + '../Core/Geometry', + '../Core/GeometryAttribute', + '../Core/GeometryAttributes', + '../Core/GeometryPipeline', + '../Core/IndexDatatype', + '../Core/Matrix4', + '../Core/WebMercatorProjection' + ], function( + BoundingSphere, + ComponentDatatype, + defined, + DeveloperError, + Ellipsoid, + FeatureDetection, + GeographicProjection, + Geometry, + GeometryAttribute, + GeometryAttributes, + GeometryPipeline, + IndexDatatype, + Matrix4, + WebMercatorProjection) { + 'use strict'; + + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; + } + + function transformToWorldCoordinates(instances, primitiveModelMatrix, scene3DOnly) { + var toWorld = !scene3DOnly; + var length = instances.length; + var i; + + if (!toWorld && (length > 1)) { + var modelMatrix = instances[0].modelMatrix; + + for (i = 1; i < length; ++i) { + if (!Matrix4.equals(modelMatrix, instances[i].modelMatrix)) { + toWorld = true; + break; + } + } + } + + if (toWorld) { + for (i = 0; i < length; ++i) { + if (defined(instances[i].geometry)) { + GeometryPipeline.transformToWorldCoordinates(instances[i]); + } + } + } else { + // Leave geometry in local coordinate system; auto update model-matrix. + Matrix4.multiplyTransformation(primitiveModelMatrix, instances[0].modelMatrix, primitiveModelMatrix); + } + } + + function addGeometryBatchId(geometry, batchId) { + var attributes = geometry.attributes; + var positionAttr = attributes.position; + var numberOfComponents = positionAttr.values.length / positionAttr.componentsPerAttribute; + + attributes.batchId = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 1, + values : new Float32Array(numberOfComponents) + }); + + var values = attributes.batchId.values; + for (var j = 0; j < numberOfComponents; ++j) { + values[j] = batchId; + } + } + + function addBatchIds(instances) { + var length = instances.length; + + for (var i = 0; i < length; ++i) { + var instance = instances[i]; + if (defined(instance.geometry)) { + addGeometryBatchId(instance.geometry, i); + } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { + addGeometryBatchId(instance.westHemisphereGeometry, i); + addGeometryBatchId(instance.eastHemisphereGeometry, i); + } + } + } + + function geometryPipeline(parameters) { + var instances = parameters.instances; + var projection = parameters.projection; + var uintIndexSupport = parameters.elementIndexUintSupported; + var scene3DOnly = parameters.scene3DOnly; + var vertexCacheOptimize = parameters.vertexCacheOptimize; + var compressVertices = parameters.compressVertices; + var modelMatrix = parameters.modelMatrix; + + var i; + var geometry; + var primitiveType; + var length = instances.length; + + for (i = 0 ; i < length; ++i) { + if (defined(instances[i].geometry)) { + primitiveType = instances[i].geometry.primitiveType; + break; + } + } + + for (i = 1; i < length; ++i) { + if (defined(instances[i].geometry) && instances[i].geometry.primitiveType !== primitiveType) { + throw new DeveloperError('All instance geometries must have the same primitiveType.'); + } + } + + // Unify to world coordinates before combining. + transformToWorldCoordinates(instances, modelMatrix, scene3DOnly); + + // Clip to IDL + if (!scene3DOnly) { + for (i = 0; i < length; ++i) { + if (defined(instances[i].geometry)) { + GeometryPipeline.splitLongitude(instances[i]); + } + } + } + + addBatchIds(instances); + + // Optimize for vertex shader caches + if (vertexCacheOptimize) { + for (i = 0; i < length; ++i) { + var instance = instances[i]; + if (defined(instance.geometry)) { + GeometryPipeline.reorderForPostVertexCache(instance.geometry); + GeometryPipeline.reorderForPreVertexCache(instance.geometry); + } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { + GeometryPipeline.reorderForPostVertexCache(instance.westHemisphereGeometry); + GeometryPipeline.reorderForPreVertexCache(instance.westHemisphereGeometry); + + GeometryPipeline.reorderForPostVertexCache(instance.eastHemisphereGeometry); + GeometryPipeline.reorderForPreVertexCache(instance.eastHemisphereGeometry); + } + } + } + + // Combine into single geometry for better rendering performance. + var geometries = GeometryPipeline.combineInstances(instances); + + length = geometries.length; + for (i = 0; i < length; ++i) { + geometry = geometries[i]; + + // Split positions for GPU RTE + var attributes = geometry.attributes; + var name; + if (!scene3DOnly) { + for (name in attributes) { + if (attributes.hasOwnProperty(name) && attributes[name].componentDatatype === ComponentDatatype.DOUBLE) { + var name3D = name + '3D'; + var name2D = name + '2D'; + + // Compute 2D positions + GeometryPipeline.projectTo2D(geometry, name, name3D, name2D, projection); + if (defined(geometry.boundingSphere) && name === 'position') { + geometry.boundingSphereCV = BoundingSphere.fromVertices(geometry.attributes.position2D.values); + } + + GeometryPipeline.encodeAttribute(geometry, name3D, name3D + 'High', name3D + 'Low'); + GeometryPipeline.encodeAttribute(geometry, name2D, name2D + 'High', name2D + 'Low'); + } + } + } else { + for (name in attributes) { + if (attributes.hasOwnProperty(name) && attributes[name].componentDatatype === ComponentDatatype.DOUBLE) { + GeometryPipeline.encodeAttribute(geometry, name, name + '3DHigh', name + '3DLow'); + } + } + } + + // oct encode and pack normals, compress texture coordinates + if (compressVertices) { + GeometryPipeline.compressVertices(geometry); + } + } + + if (!uintIndexSupport) { + // Break into multiple geometries to fit within unsigned short indices if needed + var splitGeometries = []; + length = geometries.length; + for (i = 0; i < length; ++i) { + geometry = geometries[i]; + splitGeometries = splitGeometries.concat(GeometryPipeline.fitToUnsignedShortIndices(geometry)); + } + + geometries = splitGeometries; + } + + return geometries; + } + + function createPickOffsets(instances, geometryName, geometries, pickOffsets) { + var offset; + var indexCount; + var geometryIndex; + + var offsetIndex = pickOffsets.length - 1; + if (offsetIndex >= 0) { + var pickOffset = pickOffsets[offsetIndex]; + offset = pickOffset.offset + pickOffset.count; + geometryIndex = pickOffset.index; + indexCount = geometries[geometryIndex].indices.length; + } else { + offset = 0; + geometryIndex = 0; + indexCount = geometries[geometryIndex].indices.length; + } + + var length = instances.length; + for (var i = 0; i < length; ++i) { + var instance = instances[i]; + var geometry = instance[geometryName]; + if (!defined(geometry)) { + continue; + } + + var count = geometry.indices.length; + + if (offset + count > indexCount) { + offset = 0; + indexCount = geometries[++geometryIndex].indices.length; + } + + pickOffsets.push({ + index : geometryIndex, + offset : offset, + count : count + }); + offset += count; + } + } + + function createInstancePickOffsets(instances, geometries) { + var pickOffsets = []; + createPickOffsets(instances, 'geometry', geometries, pickOffsets); + createPickOffsets(instances, 'westHemisphereGeometry', geometries, pickOffsets); + createPickOffsets(instances, 'eastHemisphereGeometry', geometries, pickOffsets); + return pickOffsets; + } + + /** + * @private + */ + var PrimitivePipeline = {}; + + /** + * @private + */ + PrimitivePipeline.combineGeometry = function(parameters) { + var geometries; + var attributeLocations; + var instances = parameters.instances; + var length = instances.length; + var pickOffsets; + + if (length > 0) { + geometries = geometryPipeline(parameters); + if (geometries.length > 0) { + attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); + if (parameters.createPickOffsets) { + pickOffsets = createInstancePickOffsets(instances, geometries); + } + } + } + + var boundingSpheres = new Array(length); + var boundingSpheresCV = new Array(length); + for (var i = 0; i < length; ++i) { + var instance = instances[i]; + var geometry = instance.geometry; + if (defined(geometry)) { + boundingSpheres[i] = geometry.boundingSphere; + boundingSpheresCV[i] = geometry.boundingSphereCV; + } + + var eastHemisphereGeometry = instance.eastHemisphereGeometry; + var westHemisphereGeometry = instance.westHemisphereGeometry; + if (defined(eastHemisphereGeometry) && defined(westHemisphereGeometry)) { + if (defined(eastHemisphereGeometry.boundingSphere) && defined(westHemisphereGeometry.boundingSphere)) { + boundingSpheres[i] = BoundingSphere.union(eastHemisphereGeometry.boundingSphere, westHemisphereGeometry.boundingSphere); + } + if (defined(eastHemisphereGeometry.boundingSphereCV) && defined(westHemisphereGeometry.boundingSphereCV)) { + boundingSpheresCV[i] = BoundingSphere.union(eastHemisphereGeometry.boundingSphereCV, westHemisphereGeometry.boundingSphereCV); + } + } + } + + return { + geometries : geometries, + modelMatrix : parameters.modelMatrix, + attributeLocations : attributeLocations, + pickOffsets : pickOffsets, + boundingSpheres : boundingSpheres, + boundingSpheresCV : boundingSpheresCV + }; + }; + + function transferGeometry(geometry, transferableObjects) { + var attributes = geometry.attributes; + for ( var name in attributes) { + if (attributes.hasOwnProperty(name)) { + var attribute = attributes[name]; + + if (defined(attribute) && defined(attribute.values)) { + transferableObjects.push(attribute.values.buffer); + } + } + } + + if (defined(geometry.indices)) { + transferableObjects.push(geometry.indices.buffer); + } + } + + function transferGeometries(geometries, transferableObjects) { + var length = geometries.length; + for (var i = 0; i < length; ++i) { + transferGeometry(geometries[i], transferableObjects); + } + } + + // This function was created by simplifying packCreateGeometryResults into a count-only operation. + function countCreateGeometryResults(items) { + var count = 1; + var length = items.length; + for (var i = 0; i < length; i++) { + var geometry = items[i]; + ++count; + + if (!defined(geometry)) { + continue; + } + + var attributes = geometry.attributes; + + count += 6 + 2 * BoundingSphere.packedLength + (defined(geometry.indices) ? geometry.indices.length : 0); + + for ( var property in attributes) { + if (attributes.hasOwnProperty(property) && defined(attributes[property])) { + var attribute = attributes[property]; + count += 5 + attribute.values.length; + } + } + } + + return count; + } + + /** + * @private + */ + PrimitivePipeline.packCreateGeometryResults = function(items, transferableObjects) { + var packedData = new Float64Array(countCreateGeometryResults(items)); + var stringTable = []; + var stringHash = {}; + + var length = items.length; + var count = 0; + packedData[count++] = length; + for (var i = 0; i < length; i++) { + var geometry = items[i]; + + var validGeometry = defined(geometry); + packedData[count++] = validGeometry ? 1.0 : 0.0; + + if (!validGeometry) { + continue; + } + + packedData[count++] = geometry.primitiveType; + packedData[count++] = geometry.geometryType; + + var validBoundingSphere = defined(geometry.boundingSphere) ? 1.0 : 0.0; + packedData[count++] = validBoundingSphere; + if (validBoundingSphere) { + BoundingSphere.pack(geometry.boundingSphere, packedData, count); + } + + count += BoundingSphere.packedLength; + + var validBoundingSphereCV = defined(geometry.boundingSphereCV) ? 1.0 : 0.0; + packedData[count++] = validBoundingSphereCV; + if (validBoundingSphereCV) { + BoundingSphere.pack(geometry.boundingSphereCV, packedData, count); + } + + count += BoundingSphere.packedLength; + + var attributes = geometry.attributes; + var attributesToWrite = []; + for ( var property in attributes) { + if (attributes.hasOwnProperty(property) && defined(attributes[property])) { + attributesToWrite.push(property); + if (!defined(stringHash[property])) { + stringHash[property] = stringTable.length; + stringTable.push(property); + } + } + } + + packedData[count++] = attributesToWrite.length; + for (var q = 0; q < attributesToWrite.length; q++) { + var name = attributesToWrite[q]; + var attribute = attributes[name]; + packedData[count++] = stringHash[name]; + packedData[count++] = attribute.componentDatatype; + packedData[count++] = attribute.componentsPerAttribute; + packedData[count++] = attribute.normalize ? 1 : 0; + packedData[count++] = attribute.values.length; + packedData.set(attribute.values, count); + count += attribute.values.length; + } + + var indicesLength = defined(geometry.indices) ? geometry.indices.length : 0; + packedData[count++] = indicesLength; + + if (indicesLength > 0) { + packedData.set(geometry.indices, count); + count += indicesLength; + } + } + + transferableObjects.push(packedData.buffer); + + return { + stringTable : stringTable, + packedData : packedData + }; + }; + + /** + * @private + */ + PrimitivePipeline.unpackCreateGeometryResults = function(createGeometryResult) { + var stringTable = createGeometryResult.stringTable; + var packedGeometry = createGeometryResult.packedData; + + var i; + var result = new Array(packedGeometry[0]); + var resultIndex = 0; + + var packedGeometryIndex = 1; + while (packedGeometryIndex < packedGeometry.length) { + var valid = packedGeometry[packedGeometryIndex++] === 1.0; + if (!valid) { + result[resultIndex++] = undefined; + continue; + } + + var primitiveType = packedGeometry[packedGeometryIndex++]; + var geometryType = packedGeometry[packedGeometryIndex++]; + + var boundingSphere; + var boundingSphereCV; + + var validBoundingSphere = packedGeometry[packedGeometryIndex++] === 1.0; + if (validBoundingSphere) { + boundingSphere = BoundingSphere.unpack(packedGeometry, packedGeometryIndex); + } + + packedGeometryIndex += BoundingSphere.packedLength; + + var validBoundingSphereCV = packedGeometry[packedGeometryIndex++] === 1.0; + if (validBoundingSphereCV) { + boundingSphereCV = BoundingSphere.unpack(packedGeometry, packedGeometryIndex); + } + + packedGeometryIndex += BoundingSphere.packedLength; + + var length; + var values; + var componentsPerAttribute; + var attributes = new GeometryAttributes(); + var numAttributes = packedGeometry[packedGeometryIndex++]; + for (i = 0; i < numAttributes; i++) { + var name = stringTable[packedGeometry[packedGeometryIndex++]]; + var componentDatatype = packedGeometry[packedGeometryIndex++]; + componentsPerAttribute = packedGeometry[packedGeometryIndex++]; + var normalize = packedGeometry[packedGeometryIndex++] !== 0; + + length = packedGeometry[packedGeometryIndex++]; + values = ComponentDatatype.createTypedArray(componentDatatype, length); + for (var valuesIndex = 0; valuesIndex < length; valuesIndex++) { + values[valuesIndex] = packedGeometry[packedGeometryIndex++]; + } + + attributes[name] = new GeometryAttribute({ + componentDatatype : componentDatatype, + componentsPerAttribute : componentsPerAttribute, + normalize : normalize, + values : values + }); + } + + var indices; + length = packedGeometry[packedGeometryIndex++]; + + if (length > 0) { + var numberOfVertices = values.length / componentsPerAttribute; + indices = IndexDatatype.createTypedArray(numberOfVertices, length); + for (i = 0; i < length; i++) { + indices[i] = packedGeometry[packedGeometryIndex++]; + } + } + + result[resultIndex++] = new Geometry({ + primitiveType : primitiveType, + geometryType : geometryType, + boundingSphere : boundingSphere, + boundingSphereCV : boundingSphereCV, + indices : indices, + attributes : attributes + }); + } + + return result; + }; + + function packInstancesForCombine(instances, transferableObjects) { + var length = instances.length; + var packedData = new Float64Array(1 + (length * 16)); + var count = 0; + packedData[count++] = length; + for (var i = 0; i < length; i++) { + var instance = instances[i]; + + Matrix4.pack(instance.modelMatrix, packedData, count); + count += Matrix4.packedLength; + } + transferableObjects.push(packedData.buffer); + + return packedData; + } + + function unpackInstancesForCombine(data) { + var packedInstances = data; + var result = new Array(packedInstances[0]); + var count = 0; + + var i = 1; + while (i < packedInstances.length) { + var modelMatrix = Matrix4.unpack(packedInstances, i); + i += Matrix4.packedLength; + + result[count++] = { + modelMatrix : modelMatrix + }; + } + + return result; + } + + /** + * @private + */ + PrimitivePipeline.packCombineGeometryParameters = function(parameters, transferableObjects) { + var createGeometryResults = parameters.createGeometryResults; + var length = createGeometryResults.length; + + for (var i = 0; i < length; i++) { + transferableObjects.push(createGeometryResults[i].packedData.buffer); + } + + return { + createGeometryResults : parameters.createGeometryResults, + packedInstances : packInstancesForCombine(parameters.instances, transferableObjects), + ellipsoid : parameters.ellipsoid, + isGeographic : parameters.projection instanceof GeographicProjection, + elementIndexUintSupported : parameters.elementIndexUintSupported, + scene3DOnly : parameters.scene3DOnly, + vertexCacheOptimize : parameters.vertexCacheOptimize, + compressVertices : parameters.compressVertices, + modelMatrix : parameters.modelMatrix, + createPickOffsets : parameters.createPickOffsets + }; + }; + + /** + * @private + */ + PrimitivePipeline.unpackCombineGeometryParameters = function(packedParameters) { + var instances = unpackInstancesForCombine(packedParameters.packedInstances); + var createGeometryResults = packedParameters.createGeometryResults; + var length = createGeometryResults.length; + var instanceIndex = 0; + + for (var resultIndex = 0; resultIndex < length; resultIndex++) { + var geometries = PrimitivePipeline.unpackCreateGeometryResults(createGeometryResults[resultIndex]); + var geometriesLength = geometries.length; + for (var geometryIndex = 0; geometryIndex < geometriesLength; geometryIndex++) { + var geometry = geometries[geometryIndex]; + var instance = instances[instanceIndex]; + instance.geometry = geometry; + ++instanceIndex; + } + } + + var ellipsoid = Ellipsoid.clone(packedParameters.ellipsoid); + var projection = packedParameters.isGeographic ? new GeographicProjection(ellipsoid) : new WebMercatorProjection(ellipsoid); + + return { + instances : instances, + ellipsoid : ellipsoid, + projection : projection, + elementIndexUintSupported : packedParameters.elementIndexUintSupported, + scene3DOnly : packedParameters.scene3DOnly, + vertexCacheOptimize : packedParameters.vertexCacheOptimize, + compressVertices : packedParameters.compressVertices, + modelMatrix : Matrix4.clone(packedParameters.modelMatrix), + createPickOffsets : packedParameters.createPickOffsets + }; + }; + + function packBoundingSpheres(boundingSpheres) { + var length = boundingSpheres.length; + var bufferLength = 1 + (BoundingSphere.packedLength + 1) * length; + var buffer = new Float32Array(bufferLength); + + var bufferIndex = 0; + buffer[bufferIndex++] = length; + + for (var i = 0; i < length; ++i) { + var bs = boundingSpheres[i]; + if (!defined(bs)) { + buffer[bufferIndex++] = 0.0; + } else { + buffer[bufferIndex++] = 1.0; + BoundingSphere.pack(boundingSpheres[i], buffer, bufferIndex); + } + bufferIndex += BoundingSphere.packedLength; + } + + return buffer; + } + + function unpackBoundingSpheres(buffer) { + var result = new Array(buffer[0]); + var count = 0; + + var i = 1; + while (i < buffer.length) { + if (buffer[i++] === 1.0) { + result[count] = BoundingSphere.unpack(buffer, i); + } + ++count; + i += BoundingSphere.packedLength; + } + + return result; + } + + /** + * @private + */ + PrimitivePipeline.packCombineGeometryResults = function(results, transferableObjects) { + if (defined(results.geometries)) { + transferGeometries(results.geometries, transferableObjects); + } + + var packedBoundingSpheres = packBoundingSpheres(results.boundingSpheres); + var packedBoundingSpheresCV = packBoundingSpheres(results.boundingSpheresCV); + transferableObjects.push(packedBoundingSpheres.buffer, packedBoundingSpheresCV.buffer); + + return { + geometries : results.geometries, + attributeLocations : results.attributeLocations, + modelMatrix : results.modelMatrix, + pickOffsets : results.pickOffsets, + boundingSpheres : packedBoundingSpheres, + boundingSpheresCV : packedBoundingSpheresCV + }; + }; + + /** + * @private + */ + PrimitivePipeline.unpackCombineGeometryResults = function(packedResult) { + return { + geometries : packedResult.geometries, + attributeLocations : packedResult.attributeLocations, + modelMatrix : packedResult.modelMatrix, + pickOffsets : packedResult.pickOffsets, + boundingSpheres : unpackBoundingSpheres(packedResult.boundingSpheres), + boundingSpheresCV : unpackBoundingSpheres(packedResult.boundingSpheresCV) + }; + }; + + return PrimitivePipeline; +}); + +define('Scene/PrimitiveState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * @private + */ + var PrimitiveState = { + READY : 0, + CREATING : 1, + CREATED : 2, + COMBINING : 3, + COMBINED : 4, + COMPLETE : 5, + FAILED : 6 + }; + + return freezeObject(PrimitiveState); +}); + +define('Scene/SceneMode',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * Indicates if the scene is viewed in 3D, 2D, or 2.5D Columbus view. + * + * @exports SceneMode + * + * @see Scene#mode + */ + var SceneMode = { + /** + * Morphing between mode, e.g., 3D to 2D. + * + * @type {Number} + * @constant + */ + MORPHING : 0, + + /** + * Columbus View mode. A 2.5D perspective view where the map is laid out + * flat and objects with non-zero height are drawn above it. + * + * @type {Number} + * @constant + */ + COLUMBUS_VIEW : 1, + + /** + * 2D mode. The map is viewed top-down with an orthographic projection. + * + * @type {Number} + * @constant + */ + SCENE2D : 2, + + /** + * 3D mode. A traditional 3D perspective view of the globe. + * + * @type {Number} + * @constant + */ + SCENE3D : 3 + }; + + /** + * Returns the morph time for the given scene mode. + * + * @param {SceneMode} value The scene mode + * @returns {Number} The morph time + */ + SceneMode.getMorphTime = function(value) { + if (value === SceneMode.SCENE3D) { + return 1.0; + } else if (value === SceneMode.MORPHING) { + return undefined; + } + return 0.0; + }; + + return freezeObject(SceneMode); +}); + +define('Scene/ShadowMode',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * Specifies whether the object casts or receives shadows from each light source when + * shadows are enabled. + * + * @exports ShadowMode + */ + var ShadowMode = { + /** + * The object does not cast or receive shadows. + * + * @type {Number} + * @constant + */ + DISABLED : 0, + + /** + * The object casts and receives shadows. + * + * @type {Number} + * @constant + */ + ENABLED : 1, + + /** + * The object casts shadows only. + * + * @type {Number} + * @constant + */ + CAST_ONLY : 2, + + /** + * The object receives shadows only. + * + * @type {Number} + * @constant + */ + RECEIVE_ONLY : 3, + + /** + * @private + */ + NUMBER_OF_SHADOW_MODES : 4 + }; + + /** + * @private + */ + ShadowMode.castShadows = function(shadowMode) { + return (shadowMode === ShadowMode.ENABLED) || (shadowMode === ShadowMode.CAST_ONLY); + }; + + /** + * @private + */ + ShadowMode.receiveShadows = function(shadowMode) { + return (shadowMode === ShadowMode.ENABLED) || (shadowMode === ShadowMode.RECEIVE_ONLY); + }; + + /** + * @private + */ + ShadowMode.fromCastReceive = function(castShadows, receiveShadows) { + if (castShadows && receiveShadows) { + return ShadowMode.ENABLED; + } else if (castShadows) { + return ShadowMode.CAST_ONLY; + } else if (receiveShadows) { + return ShadowMode.RECEIVE_ONLY; + } + return ShadowMode.DISABLED; + }; + + return freezeObject(ShadowMode); +}); + +define('Scene/Primitive',[ + '../Core/BoundingSphere', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/clone', + '../Core/Color', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/EncodedCartesian3', + '../Core/FeatureDetection', + '../Core/Geometry', + '../Core/GeometryAttribute', + '../Core/GeometryAttributes', + '../Core/isArray', + '../Core/Matrix4', + '../Core/RuntimeError', + '../Core/subdivideArray', + '../Core/TaskProcessor', + '../Renderer/BufferUsage', + '../Renderer/ContextLimits', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArray', + '../ThirdParty/when', + './BatchTable', + './CullFace', + './DepthFunction', + './PrimitivePipeline', + './PrimitiveState', + './SceneMode', + './ShadowMode' + ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + clone, + Color, + combine, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + EncodedCartesian3, + FeatureDetection, + Geometry, + GeometryAttribute, + GeometryAttributes, + isArray, + Matrix4, + RuntimeError, + subdivideArray, + TaskProcessor, + BufferUsage, + ContextLimits, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + VertexArray, + when, + BatchTable, + CullFace, + DepthFunction, + PrimitivePipeline, + PrimitiveState, + SceneMode, + ShadowMode) { + 'use strict'; + + /** + * A primitive represents geometry in the {@link Scene}. The geometry can be from a single {@link GeometryInstance} + * as shown in example 1 below, or from an array of instances, even if the geometry is from different + * geometry types, e.g., an {@link RectangleGeometry} and an {@link EllipsoidGeometry} as shown in Code Example 2. + * <p> + * A primitive combines geometry instances with an {@link Appearance} that describes the full shading, including + * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, + * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix + * and match most of them and add a new geometry or appearance independently of each other. + * </p> + * <p> + * Combining multiple instances into one primitive is called batching, and significantly improves performance for static data. + * Instances can be individually picked; {@link Scene#pick} returns their {@link GeometryInstance#id}. Using + * per-instance appearances like {@link PerInstanceColorAppearance}, each instance can also have a unique color. + * </p> + * <p> + * {@link Geometry} can either be created and batched on a web worker or the main thread. The first two examples + * show geometry that will be created on a web worker by using the descriptions of the geometry. The third example + * shows how to create the geometry on the main thread by explicitly calling the <code>createGeometry</code> method. + * </p> + * + * @alias Primitive + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {GeometryInstance[]|GeometryInstance} [options.geometryInstances] The geometry instances - or a single geometry instance - to render. + * @param {Appearance} [options.appearance] The appearance used to render the primitive. + * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the primitive (all geometry instances) from model to world coordinates. + * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. + * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {Boolean} [options.cull=true] When <code>true</code>, the renderer frustum culls and horizon culls the primitive's commands based on their bounding volume. Set this to <code>false</code> for a small performance gain if you are manually culling the primitive. + * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {ShadowMode} [options.shadows=ShadowMode.DISABLED] Determines whether this primitive casts or receives shadows from each light source. + * + * @example + * // 1. Draw a translucent ellipse on the surface with a checkerboard pattern + * var instance = new Cesium.GeometryInstance({ + * geometry : new Cesium.EllipseGeometry({ + * center : Cesium.Cartesian3.fromDegrees(-100.0, 20.0), + * semiMinorAxis : 500000.0, + * semiMajorAxis : 1000000.0, + * rotation : Cesium.Math.PI_OVER_FOUR, + * vertexFormat : Cesium.VertexFormat.POSITION_AND_ST + * }), + * id : 'object returned when this instance is picked and to get/set per-instance attributes' + * }); + * scene.primitives.add(new Cesium.Primitive({ + * geometryInstances : instance, + * appearance : new Cesium.EllipsoidSurfaceAppearance({ + * material : Cesium.Material.fromType('Checkerboard') + * }) + * })); + * + * @example + * // 2. Draw different instances each with a unique color + * var rectangleInstance = new Cesium.GeometryInstance({ + * geometry : new Cesium.RectangleGeometry({ + * rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0), + * vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT + * }), + * id : 'rectangle', + * attributes : { + * color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5) + * } + * }); + * var ellipsoidInstance = new Cesium.GeometryInstance({ + * geometry : new Cesium.EllipsoidGeometry({ + * radii : new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0), + * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL + * }), + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 500000.0), new Cesium.Matrix4()), + * id : 'ellipsoid', + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) + * } + * }); + * scene.primitives.add(new Cesium.Primitive({ + * geometryInstances : [rectangleInstance, ellipsoidInstance], + * appearance : new Cesium.PerInstanceColorAppearance() + * })); + * + * @example + * // 3. Create the geometry on the main thread. + * scene.primitives.add(new Cesium.Primitive({ + * geometryInstances : new Cesium.GeometryInstance({ + * geometry : Cesium.EllipsoidGeometry.createGeometry(new Cesium.EllipsoidGeometry({ + * radii : new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0), + * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL + * })), + * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( + * Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 500000.0), new Cesium.Matrix4()), + * id : 'ellipsoid', + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) + * } + * }), + * appearance : new Cesium.PerInstanceColorAppearance() + * })); + * + * @see GeometryInstance + * @see Appearance + * @see ClassificationPrimitive + * @see GroundPrimitive + */ + function Primitive(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + /** + * The geometry instances rendered with this primitive. This may + * be <code>undefined</code> if <code>options.releaseGeometryInstances</code> + * is <code>true</code> when the primitive is constructed. + * <p> + * Changing this property after the primitive is rendered has no effect. + * </p> + * + * @readonly + * @type GeometryInstance[]|GeometryInstance + * + * @default undefined + */ + this.geometryInstances = options.geometryInstances; + + /** + * The {@link Appearance} used to shade this primitive. Each geometry + * instance is shaded with the same appearance. Some appearances, like + * {@link PerInstanceColorAppearance} allow giving each instance unique + * properties. + * + * @type Appearance + * + * @default undefined + */ + this.appearance = options.appearance; + this._appearance = undefined; + this._material = undefined; + + /** + * The {@link Appearance} used to shade this primitive when it fails the depth test. Each geometry + * instance is shaded with the same appearance. Some appearances, like + * {@link PerInstanceColorAppearance} allow giving each instance unique + * properties. + * + * <p> + * When using an appearance that requires a color attribute, like PerInstanceColorAppearance, + * add a depthFailColor per-instance attribute instead. + * </p> + * + * <p> + * Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, + * there may be artifacts. + * </p> + * @type Appearance + * + * @default undefined + */ + this.depthFailAppearance = options.depthFailAppearance; + this._depthFailAppearance = undefined; + this._depthFailMaterial = undefined; + + /** + * The 4x4 transformation matrix that transforms the primitive (all geometry instances) from model to world coordinates. + * When this is the identity matrix, the primitive is drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. + * + * <p> + * This property is only supported in 3D mode. + * </p> + * + * @type Matrix4 + * + * @default Matrix4.IDENTITY + * + * @example + * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); + * p.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); + */ + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._modelMatrix = new Matrix4(); + + /** + * Determines if the primitive will be shown. This affects all geometry + * instances in the primitive. + * + * @type Boolean + * + * @default true + */ + this.show = defaultValue(options.show, true); + + this._vertexCacheOptimize = defaultValue(options.vertexCacheOptimize, false); + this._interleave = defaultValue(options.interleave, false); + this._releaseGeometryInstances = defaultValue(options.releaseGeometryInstances, true); + this._allowPicking = defaultValue(options.allowPicking, true); + this._asynchronous = defaultValue(options.asynchronous, true); + this._compressVertices = defaultValue(options.compressVertices, true); + + /** + * When <code>true</code>, the renderer frustum culls and horizon culls the primitive's commands + * based on their bounding volume. Set this to <code>false</code> for a small performance gain + * if you are manually culling the primitive. + * + * @type {Boolean} + * + * @default true + */ + this.cull = defaultValue(options.cull, true); + + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the primitive. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + + /** + * @private + */ + this.rtcCenter = options.rtcCenter; + + if (defined(this.rtcCenter) && (!defined(this.geometryInstances) || (isArray(this.geometryInstances) && this.geometryInstances !== 1))) { + throw new DeveloperError('Relative-to-center rendering only supports one geometry instance.'); + } + + /** + * Determines whether this primitive casts or receives shadows from each light source. + * + * @type {ShadowMode} + * + * @default ShadowMode.DISABLED + */ + this.shadows = defaultValue(options.shadows, ShadowMode.DISABLED); + + this._translucent = undefined; + + this._state = PrimitiveState.READY; + this._geometries = []; + this._error = undefined; + this._numberOfInstances = 0; + + this._boundingSpheres = []; + this._boundingSphereWC = []; + this._boundingSphereCV = []; + this._boundingSphere2D = []; + this._boundingSphereMorph = []; + this._perInstanceAttributeCache = []; + this._instanceIds = []; + this._lastPerInstanceAttributeIndex = 0; + + this._va = []; + this._attributeLocations = undefined; + this._primitiveType = undefined; + + this._frontFaceRS = undefined; + this._backFaceRS = undefined; + this._sp = undefined; + + this._depthFailAppearance = undefined; + this._spDepthFail = undefined; + this._frontFaceDepthFailRS = undefined; + this._backFaceDepthFailRS = undefined; + + this._pickRS = undefined; + this._pickSP = undefined; + this._pickIds = []; + + this._colorCommands = []; + this._pickCommands = []; + + this._readOnlyInstanceAttributes = options._readOnlyInstanceAttributes; + + this._createBoundingVolumeFunction = options._createBoundingVolumeFunction; + this._createRenderStatesFunction = options._createRenderStatesFunction; + this._createShaderProgramFunction = options._createShaderProgramFunction; + this._createCommandsFunction = options._createCommandsFunction; + this._updateAndQueueCommandsFunction = options._updateAndQueueCommandsFunction; + + this._createPickOffsets = options._createPickOffsets; + this._pickOffsets = undefined; + + this._createGeometryResults = undefined; + this._ready = false; + this._readyPromise = when.defer(); + + this._batchTable = undefined; + this._batchTableAttributeIndices = undefined; + this._instanceBoundingSpheres = undefined; + this._instanceBoundingSpheresCV = undefined; + this._batchTableBoundingSpheresUpdated = false; + this._batchTableBoundingSphereAttributeIndices = undefined; + } + + defineProperties(Primitive.prototype, { + /** + * When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + vertexCacheOptimize : { + get : function() { + return this._vertexCacheOptimize; + } + }, + + /** + * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + interleave : { + get : function() { + return this._interleave; + } + }, + + /** + * When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + releaseGeometryInstances : { + get : function() { + return this._releaseGeometryInstances; + } + }, + + /** + * When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. * + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + allowPicking : { + get : function() { + return this._allowPicking; + } + }, + + /** + * Determines if the geometry instances will be created and batched on a web worker. + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + asynchronous : { + get : function() { + return this._asynchronous; + } + }, + + /** + * When <code>true</code>, geometry vertices are compressed, which will save memory. + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + compressVertices : { + get : function() { + return this._compressVertices; + } + }, + + /** + * Determines if the primitive is complete and ready to render. If this property is + * true, the primitive will be rendered the next time that {@link Primitive#update} + * is called. + * + * @memberof Primitive.prototype + * + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; + } + }, + + /** + * Gets a promise that resolves when the primitive is ready to render. + * @memberof Primitive.prototype + * @type {Promise.<Primitive>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + } + }); + + function getCommonPerInstanceAttributeNames(instances) { + var length = instances.length; + + var attributesInAllInstances = []; + var attributes0 = instances[0].attributes; + var name; + + for (name in attributes0) { + if (attributes0.hasOwnProperty(name)) { + var attribute = attributes0[name]; + var inAllInstances = true; + + // Does this same attribute exist in all instances? + for (var i = 1; i < length; ++i) { + var otherAttribute = instances[i].attributes[name]; + + if (!defined(otherAttribute) || + (attribute.componentDatatype !== otherAttribute.componentDatatype) || + (attribute.componentsPerAttribute !== otherAttribute.componentsPerAttribute) || + (attribute.normalize !== otherAttribute.normalize)) { + + inAllInstances = false; + break; + } + } + + if (inAllInstances) { + attributesInAllInstances.push(name); + } + } + } + + return attributesInAllInstances; + } + + var scratchGetAttributeCartesian2 = new Cartesian2(); + var scratchGetAttributeCartesian3 = new Cartesian3(); + var scratchGetAttributeCartesian4 = new Cartesian4(); + + function getAttributeValue(value) { + var componentsPerAttribute = value.length; + if (componentsPerAttribute === 1) { + return value[0]; + } else if (componentsPerAttribute === 2) { + return Cartesian2.unpack(value, 0, scratchGetAttributeCartesian2); + } else if (componentsPerAttribute === 3) { + return Cartesian3.unpack(value, 0, scratchGetAttributeCartesian3); + } else if (componentsPerAttribute === 4) { + return Cartesian4.unpack(value, 0, scratchGetAttributeCartesian4); + } + } + + function createBatchTable(primitive, context) { + var geometryInstances = primitive.geometryInstances; + var instances = (isArray(geometryInstances)) ? geometryInstances : [geometryInstances]; + var numberOfInstances = instances.length; + if (numberOfInstances === 0) { + return; + } + + var names = getCommonPerInstanceAttributeNames(instances); + var length = names.length; + + var allowPicking = primitive.allowPicking; + var attributes = []; + var attributeIndices = {}; + var boundingSphereAttributeIndices = {}; + + var firstInstance = instances[0]; + var instanceAttributes = firstInstance.attributes; + + var i; + var name; + var attribute; + + for (i = 0; i < length; ++i) { + name = names[i]; + attribute = instanceAttributes[name]; + + attributeIndices[name] = i; + attributes.push({ + functionName : 'czm_batchTable_' + name, + componentDatatype : attribute.componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize + }); + } + + if (names.indexOf('distanceDisplayCondition') !== -1) { + attributes.push({ + functionName : 'czm_batchTable_boundingSphereCenter3DHigh', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + },{ + functionName : 'czm_batchTable_boundingSphereCenter3DLow', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + },{ + functionName : 'czm_batchTable_boundingSphereCenter2DHigh', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + },{ + functionName : 'czm_batchTable_boundingSphereCenter2DLow', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + },{ + functionName : 'czm_batchTable_boundingSphereRadius', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 1 + }); + boundingSphereAttributeIndices.center3DHigh = attributes.length - 5; + boundingSphereAttributeIndices.center3DLow = attributes.length - 4; + boundingSphereAttributeIndices.center2DHigh = attributes.length - 3; + boundingSphereAttributeIndices.center2DLow = attributes.length - 2; + boundingSphereAttributeIndices.radius = attributes.length - 1; + } + + if (allowPicking) { + attributes.push({ + functionName : 'czm_batchTable_pickColor', + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + componentsPerAttribute : 4, + normalize : true + }); + } + + var attributesLength = attributes.length; + var batchTable = new BatchTable(context, attributes, numberOfInstances); + + for (i = 0; i < numberOfInstances; ++i) { + var instance = instances[i]; + instanceAttributes = instance.attributes; + + for (var j = 0; j < length; ++j) { + name = names[j]; + attribute = instanceAttributes[name]; + var value = getAttributeValue(attribute.value); + var attributeIndex = attributeIndices[name]; + batchTable.setBatchedAttribute(i, attributeIndex, value); + } + + if (allowPicking) { + var pickObject = { + primitive : defaultValue(instance.pickPrimitive, primitive) + }; + + if (defined(instance.id)) { + pickObject.id = instance.id; + } + + var pickId = context.createPickId(pickObject); + primitive._pickIds.push(pickId); + + var pickColor = pickId.color; + var color = scratchGetAttributeCartesian4; + color.x = Color.floatToByte(pickColor.red); + color.y = Color.floatToByte(pickColor.green); + color.z = Color.floatToByte(pickColor.blue); + color.w = Color.floatToByte(pickColor.alpha); + + batchTable.setBatchedAttribute(i, attributesLength - 1, color); + } + } + + primitive._batchTable = batchTable; + primitive._batchTableAttributeIndices = attributeIndices; + primitive._batchTableBoundingSphereAttributeIndices = boundingSphereAttributeIndices; + } + + function cloneAttribute(attribute) { + var clonedValues; + if (isArray(attribute.values)) { + clonedValues = attribute.values.slice(0); + } else { + clonedValues = new attribute.values.constructor(attribute.values); + } + return new GeometryAttribute({ + componentDatatype : attribute.componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize, + values : clonedValues + }); + } + + function cloneGeometry(geometry) { + var attributes = geometry.attributes; + var newAttributes = new GeometryAttributes(); + for (var property in attributes) { + if (attributes.hasOwnProperty(property) && defined(attributes[property])) { + newAttributes[property] = cloneAttribute(attributes[property]); + } + } + + var indices; + if (defined(geometry.indices)) { + var sourceValues = geometry.indices; + if (isArray(sourceValues)) { + indices = sourceValues.slice(0); + } else { + indices = new sourceValues.constructor(sourceValues); + } + } + + return new Geometry({ + attributes : newAttributes, + indices : indices, + primitiveType : geometry.primitiveType, + boundingSphere : BoundingSphere.clone(geometry.boundingSphere) + }); + } + + function cloneInstance(instance, geometry) { + return { + geometry : geometry, + modelMatrix : Matrix4.clone(instance.modelMatrix), + pickPrimitive : instance.pickPrimitive, + id : instance.id + }; + } + + var positionRegex = /attribute\s+vec(?:3|4)\s+(.*)3DHigh;/g; + + Primitive._modifyShaderPosition = function(primitive, vertexShaderSource, scene3DOnly) { + var match; + + var forwardDecl = ''; + var attributes = ''; + var computeFunctions = ''; + + while ((match = positionRegex.exec(vertexShaderSource)) !== null) { + var name = match[1]; + + var functionName = 'vec4 czm_compute' + name[0].toUpperCase() + name.substr(1) + '()'; + + // Don't forward-declare czm_computePosition because computePosition.glsl already does. + if (functionName !== 'vec4 czm_computePosition()') { + forwardDecl += functionName + ';\n'; + } + + if (!defined(primitive.rtcCenter)) { + // Use GPU RTE + if (!scene3DOnly) { + attributes += + 'attribute vec3 ' + name + '2DHigh;\n' + + 'attribute vec3 ' + name + '2DLow;\n'; + + computeFunctions += + functionName + '\n' + + '{\n' + + ' vec4 p;\n' + + ' if (czm_morphTime == 1.0)\n' + + ' {\n' + + ' p = czm_translateRelativeToEye(' + name + '3DHigh, ' + name + '3DLow);\n' + + ' }\n' + + ' else if (czm_morphTime == 0.0)\n' + + ' {\n' + + ' p = czm_translateRelativeToEye(' + name + '2DHigh.zxy, ' + name + '2DLow.zxy);\n' + + ' }\n' + + ' else\n' + + ' {\n' + + ' p = czm_columbusViewMorph(\n' + + ' czm_translateRelativeToEye(' + name + '2DHigh.zxy, ' + name + '2DLow.zxy),\n' + + ' czm_translateRelativeToEye(' + name + '3DHigh, ' + name + '3DLow),\n' + + ' czm_morphTime);\n' + + ' }\n' + + ' return p;\n' + + '}\n\n'; + } else { + computeFunctions += + functionName + '\n' + + '{\n' + + ' return czm_translateRelativeToEye(' + name + '3DHigh, ' + name + '3DLow);\n' + + '}\n\n'; + } + } else { + // Use RTC + vertexShaderSource = vertexShaderSource.replace(/attribute\s+vec(?:3|4)\s+position3DHigh;/g, ''); + vertexShaderSource = vertexShaderSource.replace(/attribute\s+vec(?:3|4)\s+position3DLow;/g, ''); + + forwardDecl += 'uniform mat4 u_modifiedModelView;\n'; + attributes += 'attribute vec4 position;\n'; + + computeFunctions += + functionName + '\n' + + '{\n' + + ' return u_modifiedModelView * position;\n' + + '}\n\n'; + + + vertexShaderSource = vertexShaderSource.replace(/czm_modelViewRelativeToEye\s+\*\s+/g, ''); + vertexShaderSource = vertexShaderSource.replace(/czm_modelViewProjectionRelativeToEye/g, 'czm_projection'); + } + } + + return [forwardDecl, attributes, vertexShaderSource, computeFunctions].join('\n'); + }; + + Primitive._appendShowToShader = function(primitive, vertexShaderSource) { + if (!defined(primitive._batchTableAttributeIndices.show)) { + return vertexShaderSource; + } + + var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_show_main'); + var showMain = + 'void main() \n' + + '{ \n' + + ' czm_non_show_main(); \n' + + ' gl_Position *= czm_batchTable_show(batchId); \n' + + '}'; + + return renamedVS + '\n' + showMain; + }; + + Primitive._updateColorAttribute = function(primitive, vertexShaderSource, isDepthFail) { + // some appearances have a color attribute for per vertex color. + // only remove if color is a per instance attribute. + if (!defined(primitive._batchTableAttributeIndices.color) && !defined(primitive._batchTableAttributeIndices.depthFailColor)) { + return vertexShaderSource; + } + + if (vertexShaderSource.search(/attribute\s+vec4\s+color;/g) === -1) { + return vertexShaderSource; + } + + if (isDepthFail && !defined(primitive._batchTableAttributeIndices.depthFailColor)) { + throw new DeveloperError('A depthFailColor per-instance attribute is required when using a depth fail appearance that uses a color attribute.'); + } + + var modifiedVS = vertexShaderSource; + modifiedVS = modifiedVS.replace(/attribute\s+vec4\s+color;/g, ''); + if (!isDepthFail) { + modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_color(batchId)$2'); + } else { + modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_depthFailColor(batchId)$2'); + } + return modifiedVS; + }; + + Primitive._updatePickColorAttribute = function(source) { + var vsPick = source.replace(/attribute\s+vec4\s+pickColor;/g, ''); + vsPick = vsPick.replace(/(\b)pickColor(\b)/g, '$1czm_batchTable_pickColor(batchId)$2'); + return vsPick; + }; + + Primitive._appendDistanceDisplayConditionToShader = function(primitive, vertexShaderSource, scene3DOnly) { + if (!defined(primitive._batchTableAttributeIndices.distanceDisplayCondition)) { + return vertexShaderSource; + } + + var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_distanceDisplayCondition_main'); + var distanceDisplayConditionMain = + 'void main() \n' + + '{ \n' + + ' czm_non_distanceDisplayCondition_main(); \n' + + ' vec2 distanceDisplayCondition = czm_batchTable_distanceDisplayCondition(batchId);\n' + + ' vec3 boundingSphereCenter3DHigh = czm_batchTable_boundingSphereCenter3DHigh(batchId);\n' + + ' vec3 boundingSphereCenter3DLow = czm_batchTable_boundingSphereCenter3DLow(batchId);\n' + + ' vec3 boundingSphereCenter2DHigh = czm_batchTable_boundingSphereCenter2DHigh(batchId);\n' + + ' vec3 boundingSphereCenter2DLow = czm_batchTable_boundingSphereCenter2DLow(batchId);\n' + + ' float boundingSphereRadius = czm_batchTable_boundingSphereRadius(batchId);\n'; + + if (!scene3DOnly) { + distanceDisplayConditionMain += + ' vec4 centerRTE;\n' + + ' if (czm_morphTime == 1.0)\n' + + ' {\n' + + ' centerRTE = czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow);\n' + + ' }\n' + + ' else if (czm_morphTime == 0.0)\n' + + ' {\n' + + ' centerRTE = czm_translateRelativeToEye(boundingSphereCenter2DHigh.zxy, boundingSphereCenter2DLow.zxy);\n' + + ' }\n' + + ' else\n' + + ' {\n' + + ' centerRTE = czm_columbusViewMorph(\n' + + ' czm_translateRelativeToEye(boundingSphereCenter2DHigh.zxy, boundingSphereCenter2DLow.zxy),\n' + + ' czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow),\n' + + ' czm_morphTime);\n' + + ' }\n'; + } else { + distanceDisplayConditionMain += + ' vec4 centerRTE = czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow);\n'; + } + + distanceDisplayConditionMain += + ' float radiusSq = boundingSphereRadius * boundingSphereRadius; \n' + + ' float distanceSq; \n' + + ' if (czm_sceneMode == czm_sceneMode2D) \n' + + ' { \n' + + ' distanceSq = czm_eyeHeight2D.y - radiusSq; \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' distanceSq = dot(centerRTE.xyz, centerRTE.xyz) - radiusSq; \n' + + ' } \n' + + ' distanceSq = max(distanceSq, 0.0); \n' + + ' float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x; \n' + + ' float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y; \n' + + ' float show = (distanceSq >= nearSq && distanceSq <= farSq) ? 1.0 : 0.0; \n' + + ' gl_Position *= show; \n' + + '}'; + return renamedVS + '\n' + distanceDisplayConditionMain; + }; + + function modifyForEncodedNormals(primitive, vertexShaderSource) { + if (!primitive.compressVertices) { + return vertexShaderSource; + } + + var containsNormal = vertexShaderSource.search(/attribute\s+vec3\s+normal;/g) !== -1; + var containsSt = vertexShaderSource.search(/attribute\s+vec2\s+st;/g) !== -1; + if (!containsNormal && !containsSt) { + return vertexShaderSource; + } + + var containsTangent = vertexShaderSource.search(/attribute\s+vec3\s+tangent;/g) !== -1; + var containsBitangent = vertexShaderSource.search(/attribute\s+vec3\s+bitangent;/g) !== -1; + + var numComponents = containsSt && containsNormal ? 2.0 : 1.0; + numComponents += containsTangent || containsBitangent ? 1 : 0; + + var type = (numComponents > 1) ? 'vec' + numComponents : 'float'; + + var attributeName = 'compressedAttributes'; + var attributeDecl = 'attribute ' + type + ' ' + attributeName + ';'; + + var globalDecl = ''; + var decode = ''; + + if (containsSt) { + globalDecl += 'vec2 st;\n'; + var stComponent = numComponents > 1 ? attributeName + '.x' : attributeName; + decode += ' st = czm_decompressTextureCoordinates(' + stComponent + ');\n'; + } + + if (containsNormal && containsTangent && containsBitangent) { + globalDecl += + 'vec3 normal;\n' + + 'vec3 tangent;\n' + + 'vec3 bitangent;\n'; + decode += ' czm_octDecode(' + attributeName + '.' + (containsSt ? 'yz' : 'xy') + ', normal, tangent, bitangent);\n'; + } else { + if (containsNormal) { + globalDecl += 'vec3 normal;\n'; + decode += ' normal = czm_octDecode(' + attributeName + (numComponents > 1 ? '.' + (containsSt ? 'y' : 'x') : '') + ');\n'; + } + + if (containsTangent) { + globalDecl += 'vec3 tangent;\n'; + decode += ' tangent = czm_octDecode(' + attributeName + '.' + (containsSt && containsNormal ? 'z' : 'y') + ');\n'; + } + + if (containsBitangent) { + globalDecl += 'vec3 bitangent;\n'; + decode += ' bitangent = czm_octDecode(' + attributeName + '.' + (containsSt && containsNormal ? 'z' : 'y') + ');\n'; + } + } + + var modifiedVS = vertexShaderSource; + modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+normal;/g, ''); + modifiedVS = modifiedVS.replace(/attribute\s+vec2\s+st;/g, ''); + modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+tangent;/g, ''); + modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+bitangent;/g, ''); + modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); + var compressedMain = + 'void main() \n' + + '{ \n' + + decode + + ' czm_non_compressed_main(); \n' + + '}'; + + return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); + } + + function depthClampVS(vertexShaderSource) { + var modifiedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_depth_clamp_main'); + // The varying should be surround by #ifdef GL_EXT_frag_depth as an optimization. + // It is not to workaround an issue with Edge: + // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12120362/ + modifiedVS += + 'varying float v_WindowZ;\n' + + 'void main() {\n' + + ' czm_non_depth_clamp_main();\n' + + ' vec4 position = gl_Position;\n' + + ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + + ' position.z = min(position.z, position.w);\n' + + ' gl_Position = position;' + + '}\n'; + return modifiedVS; + } + + function depthClampFS(fragmentShaderSource) { + var modifiedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_non_depth_clamp_main'); + modifiedFS += + 'varying float v_WindowZ;\n' + + 'void main() {\n' + + ' czm_non_depth_clamp_main();\n' + + '#ifdef GL_EXT_frag_depth\n' + + ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + + '#endif\n' + + '}\n'; + modifiedFS = + '#ifdef GL_EXT_frag_depth\n' + + '#extension GL_EXT_frag_depth : enable\n' + + '#endif\n' + + modifiedFS; + return modifiedFS; + } + + function validateShaderMatching(shaderProgram, attributeLocations) { + // For a VAO and shader program to be compatible, the VAO must have + // all active attribute in the shader program. The VAO may have + // extra attributes with the only concern being a potential + // performance hit due to extra memory bandwidth and cache pollution. + // The shader source could have extra attributes that are not used, + // but there is no guarantee they will be optimized out. + // + // Here, we validate that the VAO has all attributes required + // to match the shader program. + var shaderAttributes = shaderProgram.vertexAttributes; + + for (var name in shaderAttributes) { + if (shaderAttributes.hasOwnProperty(name)) { + if (!defined(attributeLocations[name])) { + throw new DeveloperError('Appearance/Geometry mismatch. The appearance requires vertex shader attribute input \'' + name + + '\', which was not computed as part of the Geometry. Use the appearance\'s vertexFormat property when constructing the geometry.'); + } + } + } + } + + function getUniformFunction(uniforms, name) { + return function() { + return uniforms[name]; + }; + } + + var numberOfCreationWorkers = Math.max(FeatureDetection.hardwareConcurrency - 1, 1); + var createGeometryTaskProcessors; + var combineGeometryTaskProcessor = new TaskProcessor('combineGeometry', Number.POSITIVE_INFINITY); + + function loadAsynchronous(primitive, frameState) { + var instances; + var geometry; + var i; + var j; + + var instanceIds = primitive._instanceIds; + + if (primitive._state === PrimitiveState.READY) { + instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; + var length = primitive._numberOfInstances = instances.length; + + var promises = []; + var subTasks = []; + for (i = 0; i < length; ++i) { + geometry = instances[i].geometry; + instanceIds.push(instances[i].id); + + if (!defined(geometry._workerName)) { + throw new DeveloperError('_workerName must be defined for asynchronous geometry.'); + } + + subTasks.push({ + moduleName : geometry._workerName, + geometry : geometry + }); + } + + if (!defined(createGeometryTaskProcessors)) { + createGeometryTaskProcessors = new Array(numberOfCreationWorkers); + for (i = 0; i < numberOfCreationWorkers; i++) { + createGeometryTaskProcessors[i] = new TaskProcessor('createGeometry', Number.POSITIVE_INFINITY); + } + } + + var subTask; + subTasks = subdivideArray(subTasks, numberOfCreationWorkers); + + for (i = 0; i < subTasks.length; i++) { + var packedLength = 0; + var workerSubTasks = subTasks[i]; + var workerSubTasksLength = workerSubTasks.length; + for (j = 0; j < workerSubTasksLength; ++j) { + subTask = workerSubTasks[j]; + geometry = subTask.geometry; + if (defined(geometry.constructor.pack)) { + subTask.offset = packedLength; + packedLength += defaultValue(geometry.constructor.packedLength, geometry.packedLength); + } + } + + var subTaskTransferableObjects; + + if (packedLength > 0) { + var array = new Float64Array(packedLength); + subTaskTransferableObjects = [array.buffer]; + + for (j = 0; j < workerSubTasksLength; ++j) { + subTask = workerSubTasks[j]; + geometry = subTask.geometry; + if (defined(geometry.constructor.pack)) { + geometry.constructor.pack(geometry, array, subTask.offset); + subTask.geometry = array; + } + } + } + + promises.push(createGeometryTaskProcessors[i].scheduleTask({ + subTasks : subTasks[i] + }, subTaskTransferableObjects)); + } + + primitive._state = PrimitiveState.CREATING; + + when.all(promises, function(results) { + primitive._createGeometryResults = results; + primitive._state = PrimitiveState.CREATED; + }).otherwise(function(error) { + setReady(primitive, frameState, PrimitiveState.FAILED, error); + }); + } else if (primitive._state === PrimitiveState.CREATED) { + var transferableObjects = []; + instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; + + var scene3DOnly = frameState.scene3DOnly; + var projection = frameState.mapProjection; + + var promise = combineGeometryTaskProcessor.scheduleTask(PrimitivePipeline.packCombineGeometryParameters({ + createGeometryResults : primitive._createGeometryResults, + instances : instances, + ellipsoid : projection.ellipsoid, + projection : projection, + elementIndexUintSupported : frameState.context.elementIndexUint, + scene3DOnly : scene3DOnly, + vertexCacheOptimize : primitive.vertexCacheOptimize, + compressVertices : primitive.compressVertices, + modelMatrix : primitive.modelMatrix, + createPickOffsets : primitive._createPickOffsets + }, transferableObjects), transferableObjects); + + primitive._createGeometryResults = undefined; + primitive._state = PrimitiveState.COMBINING; + + when(promise, function(packedResult) { + var result = PrimitivePipeline.unpackCombineGeometryResults(packedResult); + primitive._geometries = result.geometries; + primitive._attributeLocations = result.attributeLocations; + primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); + primitive._pickOffsets = result.pickOffsets; + primitive._instanceBoundingSpheres = result.boundingSpheres; + primitive._instanceBoundingSpheresCV = result.boundingSpheresCV; + + if (defined(primitive._geometries) && primitive._geometries.length > 0) { + primitive._state = PrimitiveState.COMBINED; + } else { + setReady(primitive, frameState, PrimitiveState.FAILED, undefined); + } + }).otherwise(function(error) { + setReady(primitive, frameState, PrimitiveState.FAILED, error); + }); + } + } + + function loadSynchronous(primitive, frameState) { + var instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; + var length = primitive._numberOfInstances = instances.length; + var clonedInstances = new Array(length); + var instanceIds = primitive._instanceIds; + + var instance; + var i; + + var geometryIndex = 0; + for (i = 0; i < length; i++) { + instance = instances[i]; + var geometry = instance.geometry; + + var createdGeometry; + if (defined(geometry.attributes) && defined(geometry.primitiveType)) { + createdGeometry = cloneGeometry(geometry); + } else { + createdGeometry = geometry.constructor.createGeometry(geometry); + } + + clonedInstances[geometryIndex++] = cloneInstance(instance, createdGeometry); + instanceIds.push(instance.id); + } + + clonedInstances.length = geometryIndex; + + var scene3DOnly = frameState.scene3DOnly; + var projection = frameState.mapProjection; + + var result = PrimitivePipeline.combineGeometry({ + instances : clonedInstances, + ellipsoid : projection.ellipsoid, + projection : projection, + elementIndexUintSupported : frameState.context.elementIndexUint, + scene3DOnly : scene3DOnly, + vertexCacheOptimize : primitive.vertexCacheOptimize, + compressVertices : primitive.compressVertices, + modelMatrix : primitive.modelMatrix, + createPickOffsets : primitive._createPickOffsets + }); + + primitive._geometries = result.geometries; + primitive._attributeLocations = result.attributeLocations; + primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); + primitive._pickOffsets = result.pickOffsets; + primitive._instanceBoundingSpheres = result.boundingSpheres; + primitive._instanceBoundingSpheresCV = result.boundingSpheresCV; + + if (defined(primitive._geometries) && primitive._geometries.length > 0) { + primitive._state = PrimitiveState.COMBINED; + } else { + setReady(primitive, frameState, PrimitiveState.FAILED, undefined); + } + } + + var scratchBoundingSphereCenterEncoded = new EncodedCartesian3(); + var scratchBoundingSphereCartographic = new Cartographic(); + var scratchBoundingSphereCenter2D = new Cartesian3(); + var scratchBoundingSphere = new BoundingSphere(); + + function updateBatchTableBoundingSpheres(primitive, frameState) { + var hasDistanceDisplayCondition = defined(primitive._batchTableAttributeIndices.distanceDisplayCondition); + if (!hasDistanceDisplayCondition || primitive._batchTableBoundingSpheresUpdated) { + return; + } + + var indices = primitive._batchTableBoundingSphereAttributeIndices; + var center3DHighIndex = indices.center3DHigh; + var center3DLowIndex = indices.center3DLow; + var center2DHighIndex = indices.center2DHigh; + var center2DLowIndex = indices.center2DLow; + var radiusIndex = indices.radius; + + var projection = frameState.mapProjection; + var ellipsoid = projection.ellipsoid; + + var batchTable = primitive._batchTable; + var boundingSpheres = primitive._instanceBoundingSpheres; + var length = boundingSpheres.length; + + for (var i = 0; i < length; ++i) { + var boundingSphere = boundingSpheres[i]; + if (!defined(boundingSphere)) { + continue; + } + + var modelMatrix = primitive.modelMatrix; + if (defined(modelMatrix)) { + boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix, scratchBoundingSphere); + } + + var center = boundingSphere.center; + var radius = boundingSphere.radius; + + var encodedCenter = EncodedCartesian3.fromCartesian(center, scratchBoundingSphereCenterEncoded); + batchTable.setBatchedAttribute(i, center3DHighIndex, encodedCenter.high); + batchTable.setBatchedAttribute(i, center3DLowIndex, encodedCenter.low); + + var cartographic = ellipsoid.cartesianToCartographic(center, scratchBoundingSphereCartographic); + var center2D = projection.project(cartographic, scratchBoundingSphereCenter2D); + encodedCenter = EncodedCartesian3.fromCartesian(center2D, scratchBoundingSphereCenterEncoded); + batchTable.setBatchedAttribute(i, center2DHighIndex, encodedCenter.high); + batchTable.setBatchedAttribute(i, center2DLowIndex, encodedCenter.low); + batchTable.setBatchedAttribute(i, radiusIndex, radius); + } + + primitive._batchTableBoundingSpheresUpdated = true; + } + + function createVertexArray(primitive, frameState) { + var attributeLocations = primitive._attributeLocations; + var geometries = primitive._geometries; + var scene3DOnly = frameState.scene3DOnly; + var context = frameState.context; + + var va = []; + var length = geometries.length; + for (var i = 0; i < length; ++i) { + var geometry = geometries[i]; + + va.push(VertexArray.fromGeometry({ + context : context, + geometry : geometry, + attributeLocations : attributeLocations, + bufferUsage : BufferUsage.STATIC_DRAW, + interleave : primitive._interleave + })); + + if (defined(primitive._createBoundingVolumeFunction)) { + primitive._createBoundingVolumeFunction(frameState, geometry); + } else { + primitive._boundingSpheres.push(BoundingSphere.clone(geometry.boundingSphere)); + primitive._boundingSphereWC.push(new BoundingSphere()); + + if (!scene3DOnly) { + var center = geometry.boundingSphereCV.center; + var x = center.x; + var y = center.y; + var z = center.z; + center.x = z; + center.y = x; + center.z = y; + + primitive._boundingSphereCV.push(BoundingSphere.clone(geometry.boundingSphereCV)); + primitive._boundingSphere2D.push(new BoundingSphere()); + primitive._boundingSphereMorph.push(new BoundingSphere()); + } + } + } + + primitive._va = va; + primitive._primitiveType = geometries[0].primitiveType; + + if (primitive.releaseGeometryInstances) { + primitive.geometryInstances = undefined; + } + + primitive._geometries = undefined; + setReady(primitive, frameState, PrimitiveState.COMPLETE, undefined); + } + + function createRenderStates(primitive, context, appearance, twoPasses) { + var renderState = appearance.getRenderState(); + var rs; + + if (twoPasses) { + rs = clone(renderState, false); + rs.cull = { + enabled : true, + face : CullFace.BACK + }; + primitive._frontFaceRS = RenderState.fromCache(rs); + + rs.cull.face = CullFace.FRONT; + primitive._backFaceRS = RenderState.fromCache(rs); + } else { + primitive._frontFaceRS = RenderState.fromCache(renderState); + primitive._backFaceRS = primitive._frontFaceRS; + } + + rs = clone(renderState, false); + if (defined(primitive._depthFailAppearance)) { + rs.depthTest.enabled = false; + } + + if (primitive.allowPicking) { + if (twoPasses) { + rs.cull = { + enabled : false + }; + primitive._pickRS = RenderState.fromCache(rs); + } else { + primitive._pickRS = RenderState.fromCache(rs); + } + } else { + rs.colorMask = { + red : false, + green : false, + blue : false, + alpha : false + }; + + if (twoPasses) { + rs.cull = { + enabled : false + }; + primitive._pickRS = RenderState.fromCache(rs); + } else { + primitive._pickRS = RenderState.fromCache(rs); + } + } + + if (defined(primitive._depthFailAppearance)) { + renderState = primitive._depthFailAppearance.getRenderState(); + rs = clone(renderState, false); + rs.depthTest.func = DepthFunction.GREATER; + if (twoPasses) { + rs.cull = { + enabled : true, + face : CullFace.BACK + }; + primitive._frontFaceDepthFailRS = RenderState.fromCache(rs); + + rs.cull.face = CullFace.FRONT; + primitive._backFaceDepthFailRS = RenderState.fromCache(rs); + } else { + primitive._frontFaceDepthFailRS = RenderState.fromCache(rs); + primitive._backFaceDepthFailRS = primitive._frontFaceRS; + } + } + } + + function createShaderProgram(primitive, frameState, appearance) { + var context = frameState.context; + + var attributeLocations = primitive._attributeLocations; + + var vs = primitive._batchTable.getVertexShaderCallback()(appearance.vertexShaderSource); + vs = Primitive._appendShowToShader(primitive, vs); + vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); + vs = Primitive._updateColorAttribute(primitive, vs, false); + vs = modifyForEncodedNormals(primitive, vs); + vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); + var fs = appearance.getFragmentShaderSource(); + + // Create pick program + if (primitive.allowPicking) { + var vsPick = ShaderSource.createPickVertexShaderSource(vs); + vsPick = Primitive._updatePickColorAttribute(vsPick); + + primitive._pickSP = ShaderProgram.replaceCache({ + context : context, + shaderProgram : primitive._pickSP, + vertexShaderSource : vsPick, + fragmentShaderSource : ShaderSource.createPickFragmentShaderSource(fs, 'varying'), + attributeLocations : attributeLocations + }); + } else { + primitive._pickSP = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } + validateShaderMatching(primitive._pickSP, attributeLocations); + + primitive._sp = ShaderProgram.replaceCache({ + context : context, + shaderProgram : primitive._sp, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + validateShaderMatching(primitive._sp, attributeLocations); + + if (defined(primitive._depthFailAppearance)) { + vs = primitive._batchTable.getVertexShaderCallback()(primitive._depthFailAppearance.vertexShaderSource); + vs = Primitive._appendShowToShader(primitive, vs); + vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); + vs = Primitive._updateColorAttribute(primitive, vs, true); + vs = modifyForEncodedNormals(primitive, vs); + vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); + vs = depthClampVS(vs); + + fs = depthClampFS(primitive._depthFailAppearance.getFragmentShaderSource()); + + primitive._spDepthFail = ShaderProgram.replaceCache({ + context : context, + shaderProgram : primitive._spDepthFail, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + validateShaderMatching(primitive._spDepthFail, attributeLocations); + } + } + + var modifiedModelViewScratch = new Matrix4(); + var rtcScratch = new Cartesian3(); + + function getUniforms(primitive, appearance, material, frameState) { + // Create uniform map by combining uniforms from the appearance and material if either have uniforms. + var materialUniformMap = defined(material) ? material._uniforms : undefined; + var appearanceUniformMap = {}; + var appearanceUniforms = appearance.uniforms; + if (defined(appearanceUniforms)) { + // Convert to uniform map of functions for the renderer + for (var name in appearanceUniforms) { + if (appearanceUniforms.hasOwnProperty(name)) { + if (defined(materialUniformMap) && defined(materialUniformMap[name])) { + // Later, we could rename uniforms behind-the-scenes if needed. + throw new DeveloperError('Appearance and material have a uniform with the same name: ' + name); + } + + appearanceUniformMap[name] = getUniformFunction(appearanceUniforms, name); + } + } + } + var uniforms = combine(appearanceUniformMap, materialUniformMap); + uniforms = primitive._batchTable.getUniformMapCallback()(uniforms); + + if (defined(primitive.rtcCenter)) { + uniforms.u_modifiedModelView = function() { + var viewMatrix = frameState.context.uniformState.view; + Matrix4.multiply(viewMatrix, primitive._modelMatrix, modifiedModelViewScratch); + Matrix4.multiplyByPoint(modifiedModelViewScratch, primitive.rtcCenter, rtcScratch); + Matrix4.setTranslation(modifiedModelViewScratch, rtcScratch, modifiedModelViewScratch); + return modifiedModelViewScratch; + }; + } + + return uniforms; + } + + function createCommands(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands, frameState) { + var uniforms = getUniforms(primitive, appearance, material, frameState); + + var depthFailUniforms; + if (defined(primitive._depthFailAppearance)) { + depthFailUniforms = getUniforms(primitive, primitive._depthFailAppearance, primitive._depthFailAppearance.material, frameState); + } + + var pass = translucent ? Pass.TRANSLUCENT : Pass.OPAQUE; + + var multiplier = twoPasses ? 2 : 1; + multiplier *= defined(primitive._depthFailAppearance) ? 2 : 1; + + colorCommands.length = primitive._va.length * multiplier; + pickCommands.length = primitive._va.length; + + var length = colorCommands.length; + var m = 0; + var vaIndex = 0; + for (var i = 0; i < length; ++i) { + var colorCommand; + + if (twoPasses) { + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._backFaceRS; + colorCommand.shaderProgram = primitive._sp; + colorCommand.uniformMap = uniforms; + colorCommand.pass = pass; + + ++i; + } + + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._frontFaceRS; + colorCommand.shaderProgram = primitive._sp; + colorCommand.uniformMap = uniforms; + colorCommand.pass = pass; + + if (defined(primitive._depthFailAppearance)) { + if (twoPasses) { + ++i; + + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._backFaceDepthFailRS; + colorCommand.shaderProgram = primitive._spDepthFail; + colorCommand.uniformMap = depthFailUniforms; + colorCommand.pass = pass; + } + + ++i; + + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._frontFaceDepthFailRS; + colorCommand.shaderProgram = primitive._spDepthFail; + colorCommand.uniformMap = depthFailUniforms; + colorCommand.pass = pass; + } + + var pickCommand = pickCommands[m]; + if (!defined(pickCommand)) { + pickCommand = pickCommands[m] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + pickCommand.vertexArray = primitive._va[vaIndex]; + pickCommand.renderState = primitive._pickRS; + pickCommand.shaderProgram = primitive._pickSP; + pickCommand.uniformMap = uniforms; + pickCommand.pass = pass; + ++m; + + ++vaIndex; + } + } + + Primitive._updateBoundingVolumes = function(primitive, frameState, modelMatrix) { + var i; + var length; + var boundingSphere; + + // Update bounding volumes for primitives that are sized in pixels. + // The pixel size in meters varies based on the distance from the camera. + var pixelSize = primitive.appearance.pixelSize; + if (defined(pixelSize)) { + length = primitive._boundingSpheres.length; + for (i = 0; i < length; ++i) { + boundingSphere = primitive._boundingSpheres[i]; + var boundingSphereWC = primitive._boundingSphereWC[i]; + var pixelSizeInMeters = frameState.camera.getPixelSize(boundingSphere, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); + var sizeInMeters = pixelSizeInMeters * pixelSize; + boundingSphereWC.radius = boundingSphere.radius + sizeInMeters; + } + } + + if (!Matrix4.equals(modelMatrix, primitive._modelMatrix)) { + Matrix4.clone(modelMatrix, primitive._modelMatrix); + length = primitive._boundingSpheres.length; + for (i = 0; i < length; ++i) { + boundingSphere = primitive._boundingSpheres[i]; + if (defined(boundingSphere)) { + primitive._boundingSphereWC[i] = BoundingSphere.transform(boundingSphere, modelMatrix, primitive._boundingSphereWC[i]); + if (!frameState.scene3DOnly) { + primitive._boundingSphere2D[i] = BoundingSphere.clone(primitive._boundingSphereCV[i], primitive._boundingSphere2D[i]); + primitive._boundingSphere2D[i].center.x = 0.0; + primitive._boundingSphereMorph[i] = BoundingSphere.union(primitive._boundingSphereWC[i], primitive._boundingSphereCV[i]); + } + } + } + } + }; + + function updateAndQueueCommands(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + if (frameState.mode !== SceneMode.SCENE3D && !Matrix4.equals(modelMatrix, Matrix4.IDENTITY)) { + throw new DeveloperError('Primitive.modelMatrix is only supported in 3D mode.'); + } + + Primitive._updateBoundingVolumes(primitive, frameState, modelMatrix); + + var boundingSpheres; + if (frameState.mode === SceneMode.SCENE3D) { + boundingSpheres = primitive._boundingSphereWC; + } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { + boundingSpheres = primitive._boundingSphereCV; + } else if (frameState.mode === SceneMode.SCENE2D && defined(primitive._boundingSphere2D)) { + boundingSpheres = primitive._boundingSphere2D; + } else if (defined(primitive._boundingSphereMorph)) { + boundingSpheres = primitive._boundingSphereMorph; + } + + var commandList = frameState.commandList; + var passes = frameState.passes; + if (passes.render) { + var castShadows = ShadowMode.castShadows(primitive.shadows); + var receiveShadows = ShadowMode.receiveShadows(primitive.shadows); + var colorLength = colorCommands.length; + + var factor = twoPasses ? 2 : 1; + factor *= defined(primitive._depthFailAppearance) ? 2 : 1; + + for (var j = 0; j < colorLength; ++j) { + var sphereIndex = Math.floor(j / factor); + var colorCommand = colorCommands[j]; + colorCommand.modelMatrix = modelMatrix; + colorCommand.boundingVolume = boundingSpheres[sphereIndex]; + colorCommand.cull = cull; + colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + colorCommand.castShadows = castShadows; + colorCommand.receiveShadows = receiveShadows; + + commandList.push(colorCommand); + } + } + + if (passes.pick) { + var pickLength = pickCommands.length; + for (var k = 0; k < pickLength; ++k) { + var pickCommand = pickCommands[k]; + pickCommand.modelMatrix = modelMatrix; + pickCommand.boundingVolume = boundingSpheres[k]; + pickCommand.cull = cull; + + commandList.push(pickCommand); + } + } + } + + /** + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> + * + * @exception {DeveloperError} All instance geometries must have the same primitiveType. + * @exception {DeveloperError} Appearance and material have a uniform with the same name. + * @exception {DeveloperError} Primitive.modelMatrix is only supported in 3D mode. + * @exception {RuntimeError} Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero. + */ + Primitive.prototype.update = function(frameState) { + if (((!defined(this.geometryInstances)) && (this._va.length === 0)) || + (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length === 0) || + (!defined(this.appearance)) || + (frameState.mode !== SceneMode.SCENE3D && frameState.scene3DOnly) || + (!frameState.passes.render && !frameState.passes.pick)) { + return; + } + + if (defined(this._error)) { + throw this._error; + } + + if (defined(this.rtcCenter) && !frameState.scene3DOnly) { + throw new DeveloperError('RTC rendering is only available for 3D only scenes.'); + } + + if (this._state === PrimitiveState.FAILED) { + return; + } + + var context = frameState.context; + if (!defined(this._batchTable)) { + createBatchTable(this, context); + } + if (this._batchTable.attributes.length > 0) { + if (ContextLimits.maximumVertexTextureImageUnits === 0) { + throw new RuntimeError('Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero.'); + } + this._batchTable.update(frameState); + } + + if (this._state !== PrimitiveState.COMPLETE && this._state !== PrimitiveState.COMBINED) { + if (this.asynchronous) { + loadAsynchronous(this, frameState); + } else { + loadSynchronous(this, frameState); + } + } + + if (this._state === PrimitiveState.COMBINED) { + updateBatchTableBoundingSpheres(this, frameState); + createVertexArray(this, frameState); + } + + if (!this.show || this._state !== PrimitiveState.COMPLETE) { + return; + } + + // Create or recreate render state and shader program if appearance/material changed + var appearance = this.appearance; + var material = appearance.material; + var createRS = false; + var createSP = false; + + if (this._appearance !== appearance) { + this._appearance = appearance; + this._material = material; + createRS = true; + createSP = true; + } else if (this._material !== material ) { + this._material = material; + createSP = true; + } + + var depthFailAppearance = this.depthFailAppearance; + var depthFailMaterial = defined(depthFailAppearance) ? depthFailAppearance.material : undefined; + + if (this._depthFailAppearance !== depthFailAppearance) { + this._depthFailAppearance = depthFailAppearance; + this._depthFailMaterial = depthFailMaterial; + createRS = true; + createSP = true; + } else if (this._depthFailMaterial !== depthFailMaterial) { + this._depthFailMaterial = depthFailMaterial; + createSP = true; + } + + var translucent = this._appearance.isTranslucent(); + if (this._translucent !== translucent) { + this._translucent = translucent; + createRS = true; + } + + if (defined(this._material)) { + this._material.update(context); + } + + var twoPasses = appearance.closed && translucent; + + if (createRS) { + var rsFunc = defaultValue(this._createRenderStatesFunction, createRenderStates); + rsFunc(this, context, appearance, twoPasses); + } + + if (createSP) { + var spFunc = defaultValue(this._createShaderProgramFunction, createShaderProgram); + spFunc(this, frameState, appearance); + } + + if (createRS || createSP) { + var commandFunc = defaultValue(this._createCommandsFunction, createCommands); + commandFunc(this, appearance, material, translucent, twoPasses, this._colorCommands, this._pickCommands, frameState); + } + + var updateAndQueueCommandsFunc = defaultValue(this._updateAndQueueCommandsFunction, updateAndQueueCommands); + updateAndQueueCommandsFunc(this, frameState, this._colorCommands, this._pickCommands, this.modelMatrix, this.cull, this.debugShowBoundingVolume, twoPasses); + }; + + function createGetFunction(batchTable, instanceIndex, attributeIndex) { + return function() { + var attributeValue = batchTable.getBatchedAttribute(instanceIndex, attributeIndex); + var attribute = batchTable.attributes[attributeIndex]; + var componentsPerAttribute = attribute.componentsPerAttribute; + var value = ComponentDatatype.createTypedArray(attribute.componentDatatype, componentsPerAttribute); + if (defined(attributeValue.constructor.pack)) { + attributeValue.constructor.pack(attributeValue, value, 0); + } else { + value[0] = attributeValue; + } + return value; + }; + } + + function createSetFunction(batchTable, instanceIndex, attributeIndex) { + return function(value) { + if (!defined(value) || !defined(value.length) || value.length < 1 || value.length > 4) { + throw new DeveloperError('value must be and array with length between 1 and 4.'); + } + var attributeValue = getAttributeValue(value); + batchTable.setBatchedAttribute(instanceIndex, attributeIndex, attributeValue); + }; + } + + function createBoundingSphereProperties(primitive, properties, index) { + properties.boundingSphere = { + get : function() { + var boundingSphere = primitive._instanceBoundingSpheres[index]; + var modelMatrix = primitive.modelMatrix; + if (defined(modelMatrix) && defined(boundingSphere)) { + boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix); + } + return boundingSphere; + } + }; + properties.boundingSphereCV = { + get : function() { + return primitive._instanceBoundingSpheresCV[index]; + } + }; + } + + /** + * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. + * + * @param {Object} id The id of the {@link GeometryInstance}. + * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * + * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. + * + * @example + * var attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); + * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true); + * attributes.distanceDisplayCondition = Cesium.DistanceDisplayConditionGeometryInstanceAttribute.toValue(100.0, 10000.0); + */ + Primitive.prototype.getGeometryInstanceAttributes = function(id) { + if (!defined(id)) { + throw new DeveloperError('id is required'); + } + if (!defined(this._batchTable)) { + throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); + } + + var index = -1; + var lastIndex = this._lastPerInstanceAttributeIndex; + var ids = this._instanceIds; + var length = ids.length; + for (var i = 0; i < length; ++i) { + var curIndex = (lastIndex + i) % length; + if (id === ids[curIndex]) { + index = curIndex; + break; + } + } + + if (index === -1) { + return undefined; + } + + var attributes = this._perInstanceAttributeCache[index]; + if (defined(attributes)) { + return attributes; + } + + var batchTable = this._batchTable; + var perInstanceAttributeIndices = this._batchTableAttributeIndices; + attributes = {}; + var properties = {}; + + for (var name in perInstanceAttributeIndices) { + if (perInstanceAttributeIndices.hasOwnProperty(name)) { + var attributeIndex = perInstanceAttributeIndices[name]; + properties[name] = { + get : createGetFunction(batchTable, index, attributeIndex) + }; + + var createSetter = true; + var readOnlyAttributes = this._readOnlyInstanceAttributes; + if (createSetter && defined(readOnlyAttributes)) { + length = readOnlyAttributes.length; + for (var k = 0; k < length; ++k) { + if (name === readOnlyAttributes[k]) { + createSetter = false; + break; + } + } + } + + if (createSetter) { + properties[name].set = createSetFunction(batchTable, index, attributeIndex); + } + } + } + + createBoundingSphereProperties(this, properties, index); + defineProperties(attributes, properties); + + this._lastPerInstanceAttributeIndex = index; + this._perInstanceAttributeCache[index] = attributes; + return attributes; + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * <p> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see Primitive#destroy + */ + Primitive.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * e = e && e.destroy(); + * + * @see Primitive#isDestroyed + */ + Primitive.prototype.destroy = function() { + var length; + var i; + + this._sp = this._sp && this._sp.destroy(); + this._pickSP = this._pickSP && this._pickSP.destroy(); + + var va = this._va; + length = va.length; + for (i = 0; i < length; ++i) { + va[i].destroy(); + } + this._va = undefined; + + var pickIds = this._pickIds; + length = pickIds.length; + for (i = 0; i < length; ++i) { + pickIds[i].destroy(); + } + this._pickIds = undefined; + + this._batchTable = this._batchTable && this._batchTable.destroy(); + + //These objects may be fairly large and reference other large objects (like Entities) + //We explicitly set them to undefined here so that the memory can be freed + //even if a reference to the destroyed Primitive has been kept around. + this._instanceIds = undefined; + this._perInstanceAttributeCache = undefined; + this._attributeLocations = undefined; + + return destroyObject(this); + }; + + function setReady(primitive, frameState, state, error) { + primitive._error = error; + primitive._state = state; + frameState.afterRender.push(function() { + primitive._ready = primitive._state === PrimitiveState.COMPLETE || primitive._state === PrimitiveState.FAILED; + if (!defined(error)) { + primitive._readyPromise.resolve(primitive); + } else { + primitive._readyPromise.reject(error); + } + }); + } + + return Primitive; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/octDecode',[],function() { + +define('DataSources/ColorMaterialProperty',[ + '../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Color, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { 'use strict'; - return "vec3 czm_octDecode(vec2 encoded, float range)\n\ -{\n\ -if (encoded.x == 0.0 && encoded.y == 0.0) {\n\ -return vec3(0.0, 0.0, 0.0);\n\ -}\n\ -encoded = encoded / range * 2.0 - 1.0;\n\ -vec3 v = vec3(encoded.x, encoded.y, 1.0 - abs(encoded.x) - abs(encoded.y));\n\ -if (v.z < 0.0)\n\ -{\n\ -v.xy = (1.0 - abs(v.yx)) * czm_signNotZero(v.xy);\n\ -}\n\ -return normalize(v);\n\ -}\n\ -vec3 czm_octDecode(vec2 encoded)\n\ -{\n\ -return czm_octDecode(encoded, 255.0);\n\ -}\n\ -vec3 czm_octDecode(float encoded)\n\ -{\n\ -float temp = encoded / 256.0;\n\ -float x = floor(temp);\n\ -float y = (temp - x) * 256.0;\n\ -return czm_octDecode(vec2(x, y));\n\ -}\n\ -void czm_octDecode(vec2 encoded, out vec3 vector1, out vec3 vector2, out vec3 vector3)\n\ -{\n\ -float temp = encoded.x / 65536.0;\n\ -float x = floor(temp);\n\ -float encodedFloat1 = (temp - x) * 65536.0;\n\ -temp = encoded.y / 65536.0;\n\ -float y = floor(temp);\n\ -float encodedFloat2 = (temp - y) * 65536.0;\n\ -vector1 = czm_octDecode(encodedFloat1);\n\ -vector2 = czm_octDecode(encodedFloat2);\n\ -vector3 = czm_octDecode(vec2(x, y));\n\ -}\n\ -"; + + /** + * A {@link MaterialProperty} that maps to solid color {@link Material} uniforms. + * + * @param {Property} [color=Color.WHITE] The {@link Color} Property to be used. + * + * @alias ColorMaterialProperty + * @constructor + */ + function ColorMaterialProperty(color) { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this.color = color; + } + + defineProperties(ColorMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ColorMaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._color); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ColorMaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets or sets the {@link Color} {@link Property}. + * @memberof ColorMaterialProperty.prototype + * @type {Property} + * @default Color.WHITE + */ + color : createPropertyDescriptor('color') + }); + + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + ColorMaterialProperty.prototype.getType = function(time) { + return 'Color'; + }; + + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ColorMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.color = Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color); + return result; + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + ColorMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof ColorMaterialProperty && // + Property.equals(this._color, other._color)); + }; + + return ColorMaterialProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/packDepth',[],function() { + +define('DataSources/dynamicGeometryGetBoundingSphere',[ + '../Core/BoundingSphere', + '../Core/defined', + '../Core/DeveloperError', + './BoundingSphereState' + ], function( + BoundingSphere, + defined, + DeveloperError, + BoundingSphereState) { 'use strict'; - return "vec4 czm_packDepth(float depth)\n\ -{\n\ -vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\n\ -enc = fract(enc);\n\ -enc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n\ -return enc;\n\ -}\n\ -"; + + /** + * @private + */ + function dynamicGeometryGetBoundingSphere(entity, primitive, outlinePrimitive, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var attributes; + + //Outline and Fill geometries have the same bounding sphere, so just use whichever one is defined and ready + if (defined(primitive) && primitive.show && primitive.ready) { + attributes = primitive.getGeometryInstanceAttributes(entity); + if (defined(attributes) && defined(attributes.boundingSphere)) { + BoundingSphere.clone(attributes.boundingSphere, result); + return BoundingSphereState.DONE; + } + } + + if (defined(outlinePrimitive) && outlinePrimitive.show && outlinePrimitive.ready) { + attributes = outlinePrimitive.getGeometryInstanceAttributes(entity); + if (defined(attributes) && defined(attributes.boundingSphere)) { + BoundingSphere.clone(attributes.boundingSphere, result); + return BoundingSphereState.DONE; + } + } + + if ((defined(primitive) && !primitive.ready) || (defined(outlinePrimitive) && !outlinePrimitive.ready)) { + return BoundingSphereState.PENDING; + } + + return BoundingSphereState.FAILED; + } + + return dynamicGeometryGetBoundingSphere; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/phong',[],function() { + +define('DataSources/MaterialProperty',[ + '../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Scene/Material' + ], function( + Color, + defined, + defineProperties, + DeveloperError, + Material) { 'use strict'; - return "float czm_private_getLambertDiffuseOfMaterial(vec3 lightDirectionEC, czm_material material)\n\ -{\n\ -return czm_getLambertDiffuse(lightDirectionEC, material.normal);\n\ -}\n\ -float czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm_material material)\n\ -{\n\ -return czm_getSpecular(lightDirectionEC, toEyeEC, material.normal, material.shininess);\n\ -}\n\ -vec4 czm_phong(vec3 toEye, czm_material material)\n\ -{\n\ -float diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material);\n\ -if (czm_sceneMode == czm_sceneMode3D) {\n\ -diffuse += czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 1.0, 0.0), material);\n\ -}\n\ -float specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material) + czm_private_getSpecularOfMaterial(czm_moonDirectionEC, toEye, material);\n\ -vec3 materialDiffuse = material.diffuse * 0.5;\n\ -vec3 ambient = materialDiffuse;\n\ -vec3 color = ambient + material.emission;\n\ -color += materialDiffuse * diffuse;\n\ -color += material.specular * specular;\n\ -return vec4(color, material.alpha);\n\ -}\n\ -vec4 czm_private_phong(vec3 toEye, czm_material material)\n\ -{\n\ -float diffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material);\n\ -float specular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material);\n\ -vec3 ambient = vec3(0.0);\n\ -vec3 color = ambient + material.emission;\n\ -color += material.diffuse * diffuse;\n\ -color += material.specular * specular;\n\ -return vec4(color, material.alpha);\n\ -}\n\ -"; + + /** + * The interface for all {@link Property} objects that represent {@link Material} uniforms. + * This type defines an interface and cannot be instantiated directly. + * + * @alias MaterialProperty + * @constructor + * + * @see ColorMaterialProperty + * @see CompositeMaterialProperty + * @see GridMaterialProperty + * @see ImageMaterialProperty + * @see PolylineGlowMaterialProperty + * @see PolylineOutlineMaterialProperty + * @see StripeMaterialProperty + */ + function MaterialProperty() { + DeveloperError.throwInstantiationError(); + } + + defineProperties(MaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof MaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof MaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * @function + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; + + /** + * Gets the value of the property at the provided time. + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * @function + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + MaterialProperty.prototype.equals = DeveloperError.throwInstantiationError; + + /** + * @private + */ + MaterialProperty.getValue = function(time, materialProperty, material) { + var type; + + if (defined(materialProperty)) { + type = materialProperty.getType(time); + if (defined(type)) { + if (!defined(material) || (material.type !== type)) { + material = Material.fromType(type); + } + materialProperty.getValue(time, material.uniforms); + return material; + } + } + + if (!defined(material) || (material.type !== Material.ColorType)) { + material = Material.fromType(Material.ColorType); + } + Color.clone(Color.WHITE, material.uniforms.color); + + return material; + }; + + return MaterialProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/pointAlongRay',[],function() { + +define('DataSources/BoxGeometryUpdater',[ + '../Core/BoxGeometry', + '../Core/BoxOutlineGeometry', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' + ], function( + BoxGeometry, + BoxOutlineGeometry, + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + ShowGeometryInstanceAttribute, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { 'use strict'; - return "vec3 czm_pointAlongRay(czm_ray ray, float time)\n\ -{\n\ -return ray.origin + (time * ray.direction);\n\ -}\n\ -"; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.dimensions = undefined; + } + + /** + * A {@link GeometryUpdater} for boxes. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias BoxGeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. + */ + function BoxGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(BoxGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'box', entity.box, undefined); + } + + defineProperties(BoxGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof BoxGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof BoxGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); + + defineProperties(BoxGeometryUpdater.prototype, { + /** + * Gets the entity associated with this geometry. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Entity} + * @readonly + */ + entity : { + get : function() { + return this._entity; + } + }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + fillEnabled : { + get : function() { + return this._fillEnabled; + } + }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantFill : { + get : function() { + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); + } + }, + /** + * Gets the material property used to fill the geometry. + * @memberof BoxGeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly + */ + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, + /** + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Number} + * @readonly + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + } + }, + /** + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayConditionProperty; + } + }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isDynamic : { + get : function() { + return this._dynamic; + } + }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isClosed : { + value : true + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof BoxGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { + get : function() { + return this._geometryChanged; + } + } + }); + + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + BoxGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; + + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + BoxGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; + + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + BoxGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + } + + return new GeometryInstance({ + id : entity, + geometry : BoxGeometry.fromDimensions(this._options), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), + attributes : attributes + }); + }; + + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + BoxGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + + return new GeometryInstance({ + id : entity, + geometry : BoxOutlineGeometry.fromDimensions(this._options), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + BoxGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + BoxGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; + + BoxGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'box')) { + return; + } + + var box = this._entity.box; + + if (!defined(box)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var fillProperty = box.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = box.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } + + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var dimensions = box.dimensions; + var position = entity.position; + + var show = box.show; + if (!defined(dimensions) || !defined(position) || (defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(box.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(box.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(box.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(box.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(box.distanceDisplayCondition, defaultDistanceDisplayCondition); + + var outlineWidth = box.outlineWidth; + + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; + + if (!position.isConstant || // + !Property.isConstant(entity.orientation) || // + !dimensions.isConstant || // + !Property.isConstant(outlineWidth)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.dimensions = dimensions.getValue(Iso8601.MINIMUM_VALUE, options.dimensions); + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } + }; + + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + BoxGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } + + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, this); + }; + + /** + * @private + */ + function DynamicGeometryUpdater(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._primitive = undefined; + this._outlinePrimitive = undefined; + + var geometryUpdater = this._geometryUpdater; + var entity = geometryUpdater._entity; + var box = entity.box; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(box.show, time, true)) { + return; + } + + var options = this._options; + var modelMatrix = entity.computeModelMatrix(time); + var dimensions = Property.getValueOrUndefined(box.dimensions, time, options.dimensions); + if (!defined(modelMatrix) || !defined(dimensions)) { + return; + } + + options.dimensions = dimensions; + + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + + var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + + if (Property.getValueOrDefault(box.fill, time, true)) { + var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + this._material = material; + + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : BoxGeometry.fromDimensions(options), + modelMatrix : modelMatrix, + attributes : { + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); + } + + if (Property.getValueOrDefault(box.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = Property.getValueOrClonedDefault(box.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(box.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; + + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : BoxOutlineGeometry.fromDimensions(options), + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } + }; + + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; + + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; + + return BoxGeometryUpdater; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval',[],function() { + +define('DataSources/ImageMaterialProperty',[ + '../Core/Cartesian2', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Cartesian2, + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { 'use strict'; - return "czm_raySegment czm_rayEllipsoidIntersectionInterval(czm_ray ray, czm_ellipsoid ellipsoid)\n\ -{\n\ -vec3 q = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.origin, 1.0)).xyz;\n\ -vec3 w = ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ray.direction, 0.0)).xyz;\n\ -q = q - ellipsoid.inverseRadii * (czm_inverseModelView * vec4(ellipsoid.center, 1.0)).xyz;\n\ -float q2 = dot(q, q);\n\ -float qw = dot(q, w);\n\ -if (q2 > 1.0)\n\ -{\n\ -if (qw >= 0.0)\n\ -{\n\ -return czm_emptyRaySegment;\n\ -}\n\ -else\n\ -{\n\ -float qw2 = qw * qw;\n\ -float difference = q2 - 1.0;\n\ -float w2 = dot(w, w);\n\ -float product = w2 * difference;\n\ -if (qw2 < product)\n\ -{\n\ -return czm_emptyRaySegment;\n\ -}\n\ -else if (qw2 > product)\n\ -{\n\ -float discriminant = qw * qw - product;\n\ -float temp = -qw + sqrt(discriminant);\n\ -float root0 = temp / w2;\n\ -float root1 = difference / temp;\n\ -if (root0 < root1)\n\ -{\n\ -czm_raySegment i = czm_raySegment(root0, root1);\n\ -return i;\n\ -}\n\ -else\n\ -{\n\ -czm_raySegment i = czm_raySegment(root1, root0);\n\ -return i;\n\ -}\n\ -}\n\ -else\n\ -{\n\ -float root = sqrt(difference / w2);\n\ -czm_raySegment i = czm_raySegment(root, root);\n\ -return i;\n\ -}\n\ -}\n\ -}\n\ -else if (q2 < 1.0)\n\ -{\n\ -float difference = q2 - 1.0;\n\ -float w2 = dot(w, w);\n\ -float product = w2 * difference;\n\ -float discriminant = qw * qw - product;\n\ -float temp = -qw + sqrt(discriminant);\n\ -czm_raySegment i = czm_raySegment(0.0, temp / w2);\n\ -return i;\n\ -}\n\ -else\n\ -{\n\ -if (qw < 0.0)\n\ -{\n\ -float w2 = dot(w, w);\n\ -czm_raySegment i = czm_raySegment(0.0, -qw / w2);\n\ -return i;\n\ -}\n\ -else\n\ -{\n\ -return czm_emptyRaySegment;\n\ -}\n\ -}\n\ -}\n\ -"; + + var defaultRepeat = new Cartesian2(1, 1); + var defaultTransparent = false; + var defaultColor = Color.WHITE; + + /** + * A {@link MaterialProperty} that maps to image {@link Material} uniforms. + * @alias ImageMaterialProperty + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.image] A Property specifying the Image, URL, Canvas, or Video. + * @param {Property} [options.repeat=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the number of times the image repeats in each direction. + * @param {Property} [options.color=Color.WHITE] The color applied to the image + * @param {Property} [options.transparent=false] Set to true when the image has transparency (for example, when a png has transparent sections) + */ + function ImageMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._definitionChanged = new Event(); + this._image = undefined; + this._imageSubscription = undefined; + this._repeat = undefined; + this._repeatSubscription = undefined; + this._color = undefined; + this._colorSubscription = undefined; + this._transparent = undefined; + this._transparentSubscription = undefined; + this.image = options.image; + this.repeat = options.repeat; + this.color = options.color; + this.transparent = options.transparent; + } + + defineProperties(ImageMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ImageMaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._image) && Property.isConstant(this._repeat); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ImageMaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets or sets the Property specifying Image, URL, Canvas, or Video to use. + * @memberof ImageMaterialProperty.prototype + * @type {Property} + */ + image : createPropertyDescriptor('image'), + /** + * Gets or sets the {@link Cartesian2} Property specifying the number of times the image repeats in each direction. + * @memberof ImageMaterialProperty.prototype + * @type {Property} + * @default new Cartesian2(1, 1) + */ + repeat : createPropertyDescriptor('repeat'), + /** + * Gets or sets the Color Property specifying the desired color applied to the image. + * @memberof ImageMaterialProperty.prototype + * @type {Property} + * @default 1.0 + */ + color : createPropertyDescriptor('color'), + /** + * Gets or sets the Boolean Property specifying whether the image has transparency + * @memberof ImageMaterialProperty.prototype + * @type {Property} + * @default 1.0 + */ + transparent : createPropertyDescriptor('transparent') + }); + + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + ImageMaterialProperty.prototype.getType = function(time) { + return 'Image'; + }; + + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ImageMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + + result.image = Property.getValueOrUndefined(this._image, time); + result.repeat = Property.getValueOrClonedDefault(this._repeat, time, defaultRepeat, result.repeat); + result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); + if (Property.getValueOrDefault(this._transparent, time, defaultTransparent)) { + result.color.alpha = Math.min(0.99, result.color.alpha); + } + + return result; + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + ImageMaterialProperty.prototype.equals = function(other) { + return this === other || + (other instanceof ImageMaterialProperty && + Property.equals(this._image, other._image) && + Property.equals(this._color, other._color) && + Property.equals(this._transparent, other._transparent) && + Property.equals(this._repeat, other._repeat)); + }; + + return ImageMaterialProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/RGBToHSB',[],function() { + +define('DataSources/createMaterialPropertyDescriptor',[ + '../Core/Color', + '../Core/DeveloperError', + '../Core/Resource', + './ColorMaterialProperty', + './createPropertyDescriptor', + './ImageMaterialProperty' + ], function( + Color, + DeveloperError, + Resource, + ColorMaterialProperty, + createPropertyDescriptor, + ImageMaterialProperty) { 'use strict'; - return "const vec4 K_RGB2HSB = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n\ -vec3 czm_RGBToHSB(vec3 rgb)\n\ -{\n\ -vec4 p = mix(vec4(rgb.bg, K_RGB2HSB.wz), vec4(rgb.gb, K_RGB2HSB.xy), step(rgb.b, rgb.g));\n\ -vec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r));\n\ -float d = q.x - min(q.w, q.y);\n\ -return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + czm_epsilon7)), d / (q.x + czm_epsilon7), q.x);\n\ -}\n\ -"; + + function createMaterialProperty(value) { + if (value instanceof Color) { + return new ColorMaterialProperty(value); + } + + if (typeof value === 'string' || value instanceof Resource || value instanceof HTMLCanvasElement || value instanceof HTMLVideoElement) { + var result = new ImageMaterialProperty(); + result.image = value; + return result; + } + + throw new DeveloperError('Unable to infer material type: ' + value); + } + + /** + * @private + */ + function createMaterialPropertyDescriptor(name, configurable) { + return createPropertyDescriptor(name, configurable, createMaterialProperty); + } + + return createMaterialPropertyDescriptor; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/RGBToHSL',[],function() { + +define('DataSources/BoxGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - return "vec3 RGBtoHCV(vec3 rgb)\n\ -{\n\ -vec4 p = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0 / 3.0) : vec4(rgb.gb, 0.0, -1.0 / 3.0);\n\ -vec4 q = (rgb.r < p.x) ? vec4(p.xyw, rgb.r) : vec4(rgb.r, p.yzx);\n\ -float c = q.x - min(q.w, q.y);\n\ -float h = abs((q.w - q.y) / (6.0 * c + czm_epsilon7) + q.z);\n\ -return vec3(h, c, q.x);\n\ -}\n\ -vec3 czm_RGBToHSL(vec3 rgb)\n\ -{\n\ -vec3 hcv = RGBtoHCV(rgb);\n\ -float l = hcv.z - hcv.y * 0.5;\n\ -float s = hcv.y / (1.0 - abs(l * 2.0 - 1.0) + czm_epsilon7);\n\ -return vec3(hcv.x, s, l);\n\ -}\n\ -"; + + /** + * Describes a box. The center position and orientation are determined by the containing {@link Entity}. + * + * @alias BoxGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.dimensions] A {@link Cartesian3} Property specifying the length, width, and height of the box. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the box. + * @param {Property} [options.fill=true] A boolean Property specifying whether the box is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the box. + * @param {Property} [options.outline=false] A boolean Property specifying whether the box is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the box casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this box will be displayed. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo} + */ + function BoxGraphics(options) { + this._dimensions = undefined; + this._dimensionsSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(BoxGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof BoxGraphics.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the boolean Property specifying the visibility of the box. + * @memberof BoxGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets {@link Cartesian3} Property property specifying the length, width, and height of the box. + * @memberof BoxGraphics.prototype + * @type {Property} + */ + dimensions : createPropertyDescriptor('dimensions'), + + /** + * Gets or sets the material used to fill the box. + * @memberof BoxGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), + + /** + * Gets or sets the boolean Property specifying whether the box is filled with the provided material. + * @memberof BoxGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), + + /** + * Gets or sets the Property specifying whether the box is outlined. + * @memberof BoxGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), + + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof BoxGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof BoxGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Get or sets the enum Property specifying whether the box + * casts or receives shadows from each light source. + * @memberof BoxGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this box will be displayed. + * @memberof BoxGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); + + /** + * Duplicates this instance. + * + * @param {BoxGraphics} [result] The object onto which to store the result. + * @returns {BoxGraphics} The modified result parameter or a new instance if one was not provided. + */ + BoxGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new BoxGraphics(this); + } + result.dimensions = this.dimensions; + result.show = this.show; + result.material = this.material; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {BoxGraphics} source The object to be merged into this object. + */ + BoxGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.dimensions = defaultValue(this.dimensions, source.dimensions); + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; + + return BoxGraphics; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/RGBToXYZ',[],function() { + +define('DataSources/CallbackProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event' + ], function( + defined, + defineProperties, + DeveloperError, + Event) { 'use strict'; - return "vec3 czm_RGBToXYZ(vec3 rgb)\n\ -{\n\ -const mat3 RGB2XYZ = mat3(0.4124, 0.2126, 0.0193,\n\ -0.3576, 0.7152, 0.1192,\n\ -0.1805, 0.0722, 0.9505);\n\ -vec3 xyz = RGB2XYZ * rgb;\n\ -vec3 Yxy;\n\ -Yxy.r = xyz.g;\n\ -float temp = dot(vec3(1.0), xyz);\n\ -Yxy.gb = xyz.rg / temp;\n\ -return Yxy;\n\ -}\n\ -"; + + /** + * A {@link Property} whose value is lazily evaluated by a callback function. + * + * @alias CallbackProperty + * @constructor + * + * @param {CallbackProperty~Callback} callback The function to be called when the property is evaluated. + * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. + */ + function CallbackProperty(callback, isConstant) { + this._callback = undefined; + this._isConstant = undefined; + this._definitionChanged = new Event(); + this.setCallback(callback, isConstant); + } + + defineProperties(CallbackProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof CallbackProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return this._isConstant; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setCallback is called. + * @memberof CallbackProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + } + }); + + /** + * Gets the value of the property. + * + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied or is unsupported. + */ + CallbackProperty.prototype.getValue = function(time, result) { + return this._callback(time, result); + }; + + /** + * Sets the callback to be used. + * + * @param {CallbackProperty~Callback} callback The function to be called when the property is evaluated. + * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. + */ + CallbackProperty.prototype.setCallback = function(callback, isConstant) { + if (!defined(callback)) { + throw new DeveloperError('callback is required.'); + } + if (!defined(isConstant)) { + throw new DeveloperError('isConstant is required.'); + } + + var changed = this._callback !== callback || this._isConstant !== isConstant; + + this._callback = callback; + this._isConstant = isConstant; + + if (changed) { + this._definitionChanged.raiseEvent(this); + } + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + CallbackProperty.prototype.equals = function(other) { + return this === other || (other instanceof CallbackProperty && this._callback === other._callback && this._isConstant === other._isConstant); + }; + + /** + * A function that returns the value of the property. + * @callback CallbackProperty~Callback + * + * @param {JulianDate} [time] The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied or is unsupported. + */ + + return CallbackProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/saturation',[],function() { + +define('DataSources/CheckerboardMaterialProperty',[ + '../Core/Cartesian2', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Cartesian2, + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { 'use strict'; - return "vec3 czm_saturation(vec3 rgb, float adjustment)\n\ -{\n\ -const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n\ -vec3 intensity = vec3(dot(rgb, W));\n\ -return mix(intensity, rgb, adjustment);\n\ -}\n\ -"; + + var defaultEvenColor = Color.WHITE; + var defaultOddColor = Color.BLACK; + var defaultRepeat = new Cartesian2(2.0, 2.0); + + /** + * A {@link MaterialProperty} that maps to checkerboard {@link Material} uniforms. + * @alias CheckerboardMaterialProperty + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}. + * @param {Property} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}. + * @param {Property} [options.repeat=new Cartesian2(2.0, 2.0)] A {@link Cartesian2} Property specifying how many times the tiles repeat in each direction. + */ + function CheckerboardMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._definitionChanged = new Event(); + + this._evenColor = undefined; + this._evenColorSubscription = undefined; + + this._oddColor = undefined; + this._oddColorSubscription = undefined; + + this._repeat = undefined; + this._repeatSubscription = undefined; + + this.evenColor = options.evenColor; + this.oddColor = options.oddColor; + this.repeat = options.repeat; + } + + defineProperties(CheckerboardMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CheckerboardMaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._evenColor) && // + Property.isConstant(this._oddColor) && // + Property.isConstant(this._repeat); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof CheckerboardMaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets or sets the Property specifying the first {@link Color}. + * @memberof CheckerboardMaterialProperty.prototype + * @type {Property} + * @default Color.WHITE + */ + evenColor : createPropertyDescriptor('evenColor'), + /** + * Gets or sets the Property specifying the second {@link Color}. + * @memberof CheckerboardMaterialProperty.prototype + * @type {Property} + * @default Color.BLACK + */ + oddColor : createPropertyDescriptor('oddColor'), + /** + * Gets or sets the {@link Cartesian2} Property specifying how many times the tiles repeat in each direction. + * @memberof CheckerboardMaterialProperty.prototype + * @type {Property} + * @default new Cartesian2(2.0, 2.0) + */ + repeat : createPropertyDescriptor('repeat') + }); + + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + CheckerboardMaterialProperty.prototype.getType = function(time) { + return 'Checkerboard'; + }; + + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + CheckerboardMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.lightColor = Property.getValueOrClonedDefault(this._evenColor, time, defaultEvenColor, result.lightColor); + result.darkColor = Property.getValueOrClonedDefault(this._oddColor, time, defaultOddColor, result.darkColor); + result.repeat = Property.getValueOrDefault(this._repeat, time, defaultRepeat); + return result; + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + CheckerboardMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CheckerboardMaterialProperty && // + Property.equals(this._evenColor, other._evenColor) && // + Property.equals(this._oddColor, other._oddColor) && // + Property.equals(this._repeat, other._repeat)); + }; + + return CheckerboardMaterialProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/shadowDepthCompare',[],function() { + +define('DataSources/PositionProperty',[ + '../Core/Cartesian3', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Matrix3', + '../Core/ReferenceFrame', + '../Core/Transforms' + ], function( + Cartesian3, + defined, + defineProperties, + DeveloperError, + Matrix3, + ReferenceFrame, + Transforms) { 'use strict'; - return "float czm_sampleShadowMap(samplerCube shadowMap, vec3 d)\n\ -{\n\ -return czm_unpackDepth(textureCube(shadowMap, d));\n\ -}\n\ -float czm_sampleShadowMap(sampler2D shadowMap, vec2 uv)\n\ -{\n\ -#ifdef USE_SHADOW_DEPTH_TEXTURE\n\ -return texture2D(shadowMap, uv).r;\n\ -#else\n\ -return czm_unpackDepth(texture2D(shadowMap, uv));\n\ -#endif\n\ -}\n\ -float czm_shadowDepthCompare(samplerCube shadowMap, vec3 uv, float depth)\n\ -{\n\ -return step(depth, czm_sampleShadowMap(shadowMap, uv));\n\ -}\n\ -float czm_shadowDepthCompare(sampler2D shadowMap, vec2 uv, float depth)\n\ -{\n\ -return step(depth, czm_sampleShadowMap(shadowMap, uv));\n\ -}\n\ -"; + + /** + * The interface for all {@link Property} objects that define a world + * location as a {@link Cartesian3} with an associated {@link ReferenceFrame}. + * This type defines an interface and cannot be instantiated directly. + * + * @alias PositionProperty + * @constructor + * + * @see CompositePositionProperty + * @see ConstantPositionProperty + * @see SampledPositionProperty + * @see TimeIntervalCollectionPositionProperty + */ + function PositionProperty() { + DeveloperError.throwInstantiationError(); + } + + defineProperties(PositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PositionProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PositionProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the reference frame that the position is defined in. + * @memberof PositionProperty.prototype + * @type {ReferenceFrame} + */ + referenceFrame : { + get : DeveloperError.throwInstantiationError + } + }); + + /** + * Gets the value of the property at the provided time in the fixed frame. + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PositionProperty.prototype.getValue = DeveloperError.throwInstantiationError; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * @function + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PositionProperty.prototype.getValueInReferenceFrame = DeveloperError.throwInstantiationError; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * @function + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PositionProperty.prototype.equals = DeveloperError.throwInstantiationError; + + var scratchMatrix3 = new Matrix3(); + + /** + * @private + */ + PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) { + if (!defined(value)) { + return value; + } + if (!defined(result)){ + result = new Cartesian3(); + } + + if (inputFrame === outputFrame) { + return Cartesian3.clone(value, result); + } + + var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3); + if (!defined(icrfToFixed)) { + icrfToFixed = Transforms.computeTemeToPseudoFixedMatrix(time, scratchMatrix3); + } + if (inputFrame === ReferenceFrame.INERTIAL) { + return Matrix3.multiplyByVector(icrfToFixed, value, result); + } + if (inputFrame === ReferenceFrame.FIXED) { + return Matrix3.multiplyByVector(Matrix3.transpose(icrfToFixed, scratchMatrix3), value, result); + } + }; + + return PositionProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/shadowVisibility',[],function() { + +define('DataSources/ConstantPositionProperty',[ + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame', + './PositionProperty' + ], function( + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame, + PositionProperty) { 'use strict'; - return "float czm_private_shadowVisibility(float visibility, float nDotL, float normalShadingSmooth, float darkness)\n\ -{\n\ -#ifdef USE_NORMAL_SHADING\n\ -#ifdef USE_NORMAL_SHADING_SMOOTH\n\ -float strength = clamp(nDotL / normalShadingSmooth, 0.0, 1.0);\n\ -#else\n\ -float strength = step(0.0, nDotL);\n\ -#endif\n\ -visibility *= strength;\n\ -#endif\n\ -visibility = max(visibility, darkness);\n\ -return visibility;\n\ -}\n\ -#ifdef USE_CUBE_MAP_SHADOW\n\ -float czm_shadowVisibility(samplerCube shadowMap, czm_shadowParameters shadowParameters)\n\ -{\n\ -float depthBias = shadowParameters.depthBias;\n\ -float depth = shadowParameters.depth;\n\ -float nDotL = shadowParameters.nDotL;\n\ -float normalShadingSmooth = shadowParameters.normalShadingSmooth;\n\ -float darkness = shadowParameters.darkness;\n\ -vec3 uvw = shadowParameters.texCoords;\n\ -depth -= depthBias;\n\ -float visibility = czm_shadowDepthCompare(shadowMap, uvw, depth);\n\ -return czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n\ -}\n\ -#else\n\ -float czm_shadowVisibility(sampler2D shadowMap, czm_shadowParameters shadowParameters)\n\ -{\n\ -float depthBias = shadowParameters.depthBias;\n\ -float depth = shadowParameters.depth;\n\ -float nDotL = shadowParameters.nDotL;\n\ -float normalShadingSmooth = shadowParameters.normalShadingSmooth;\n\ -float darkness = shadowParameters.darkness;\n\ -vec2 uv = shadowParameters.texCoords;\n\ -depth -= depthBias;\n\ -#ifdef USE_SOFT_SHADOWS\n\ -vec2 texelStepSize = shadowParameters.texelStepSize;\n\ -float radius = 1.0;\n\ -float dx0 = -texelStepSize.x * radius;\n\ -float dy0 = -texelStepSize.y * radius;\n\ -float dx1 = texelStepSize.x * radius;\n\ -float dy1 = texelStepSize.y * radius;\n\ -float visibility = (\n\ -czm_shadowDepthCompare(shadowMap, uv, depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy0), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy0), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy0), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, 0.0), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, 0.0), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(dx0, dy1), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(0.0, dy1), depth) +\n\ -czm_shadowDepthCompare(shadowMap, uv + vec2(dx1, dy1), depth)\n\ -) * (1.0 / 9.0);\n\ -#else\n\ -float visibility = czm_shadowDepthCompare(shadowMap, uv, depth);\n\ -#endif\n\ -return czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);\n\ -}\n\ -#endif\n\ -"; + + /** + * A {@link PositionProperty} whose value does not change in respect to the + * {@link ReferenceFrame} in which is it defined. + * + * @alias ConstantPositionProperty + * @constructor + * + * @param {Cartesian3} [value] The property value. + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + */ + function ConstantPositionProperty(value, referenceFrame) { + this._definitionChanged = new Event(); + this._value = Cartesian3.clone(value); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + } + + defineProperties(ConstantPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof ConstantPositionProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return !defined(this._value) || this._referenceFrame === ReferenceFrame.FIXED; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof ConstantPositionProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof ConstantPositionProperty.prototype + * @type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + } + } + }); + + /** + * Gets the value of the property at the provided time in the fixed frame. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ConstantPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Sets the value of the property. + * + * @param {Cartesian3} value The property value. + * @param {ReferenceFrame} [referenceFrame=this.referenceFrame] The reference frame in which the position is defined. + */ + ConstantPositionProperty.prototype.setValue = function(value, referenceFrame) { + var definitionChanged = false; + if (!Cartesian3.equals(this._value, value)) { + definitionChanged = true; + this._value = Cartesian3.clone(value); + } + if (defined(referenceFrame) && this._referenceFrame !== referenceFrame) { + definitionChanged = true; + this._referenceFrame = referenceFrame; + } + if (definitionChanged) { + this._definitionChanged.raiseEvent(this); + } + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ConstantPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + + return PositionProperty.convertToReferenceFrame(time, this._value, this._referenceFrame, referenceFrame, result); + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + ConstantPositionProperty.prototype.equals = function(other) { + return this === other || + (other instanceof ConstantPositionProperty && + Cartesian3.equals(this._value, other._value) && + this._referenceFrame === other._referenceFrame); + }; + + return ConstantPositionProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/signNotZero',[],function() { + +define('DataSources/CorridorGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - return "float czm_signNotZero(float value)\n\ -{\n\ -return value >= 0.0 ? 1.0 : -1.0;\n\ -}\n\ -vec2 czm_signNotZero(vec2 value)\n\ -{\n\ -return vec2(czm_signNotZero(value.x), czm_signNotZero(value.y));\n\ -}\n\ -vec3 czm_signNotZero(vec3 value)\n\ -{\n\ -return vec3(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z));\n\ -}\n\ -vec4 czm_signNotZero(vec4 value)\n\ -{\n\ -return vec4(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z), czm_signNotZero(value.w));\n\ -}\n\ -"; + + /** + * Describes a corridor, which is a shape defined by a centerline and width that + * conforms to the curvature of the globe. It can be placed on the surface or at altitude + * and can optionally be extruded into a volume. + * + * @alias CorridorGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions that define the centerline of the corridor. + * @param {Property} [options.width] A numeric Property specifying the distance between the edges of the corridor. + * @param {Property} [options.cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners. + * @param {Property} [options.height=0] A numeric Property specifying the altitude of the corridor relative to the ellipsoid surface. + * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the corridor's extruded face relative to the ellipsoid surface. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the corridor. + * @param {Property} [options.fill=true] A boolean Property specifying whether the corridor is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the corridor. + * @param {Property} [options.outline=false] A boolean Property specifying whether the corridor is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the distance between each latitude and longitude. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the corridor casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this corridor will be displayed. + * + * @see Entity + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo} + */ + function CorridorGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._positions = undefined; + this._positionsSubscription = undefined; + this._height = undefined; + this._heightSubscription = undefined; + this._extrudedHeight = undefined; + this._extrudedHeightSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._width = undefined; + this._widthSubscription = undefined; + this._cornerType = undefined; + this._cornerTypeSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(CorridorGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof CorridorGraphics.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the boolean Property specifying the visibility of the corridor. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the Property specifying the material used to fill the corridor. + * @memberof CorridorGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), + + /** + * Gets or sets a Property specifying the array of {@link Cartesian3} positions that define the centerline of the corridor. + * @memberof CorridorGraphics.prototype + * @type {Property} + */ + positions : createPropertyDescriptor('positions'), + + /** + * Gets or sets the numeric Property specifying the altitude of the corridor. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default 0.0 + */ + height : createPropertyDescriptor('height'), + + /** + * Gets or sets the numeric Property specifying the altitude of the corridor extrusion. + * Setting this property creates a corridor shaped volume starting at height and ending + * at this altitude. + * @memberof CorridorGraphics.prototype + * @type {Property} + */ + extrudedHeight : createPropertyDescriptor('extrudedHeight'), + + /** + * Gets or sets the numeric Property specifying the sampling distance between each latitude and longitude point. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default {CesiumMath.RADIANS_PER_DEGREE} + */ + granularity : createPropertyDescriptor('granularity'), + + /** + * Gets or sets the numeric Property specifying the width of the corridor. + * @memberof CorridorGraphics.prototype + * @type {Property} + */ + width : createPropertyDescriptor('width'), + + /** + * Gets or sets the boolean Property specifying whether the corridor is filled with the provided material. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), + + /** + * Gets or sets the Property specifying whether the corridor is outlined. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), + + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Gets or sets the {@link CornerType} Property specifying how corners are styled. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default CornerType.ROUNDED + */ + cornerType : createPropertyDescriptor('cornerType'), + + /** + * Get or sets the enum Property specifying whether the corridor + * casts or receives shadows from each light source. + * @memberof CorridorGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this corridor will be displayed. + * @memberof CorridorGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); + + /** + * Duplicates this instance. + * + * @param {CorridorGraphics} [result] The object onto which to store the result. + * @returns {CorridorGraphics} The modified result parameter or a new instance if one was not provided. + */ + CorridorGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new CorridorGraphics(this); + } + result.show = this.show; + result.material = this.material; + result.positions = this.positions; + result.height = this.height; + result.extrudedHeight = this.extrudedHeight; + result.granularity = this.granularity; + result.width = this.width; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.cornerType = this.cornerType; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {CorridorGraphics} source The object to be merged into this object. + */ + CorridorGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.positions = defaultValue(this.positions, source.positions); + this.height = defaultValue(this.height, source.height); + this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); + this.granularity = defaultValue(this.granularity, source.granularity); + this.width = defaultValue(this.width, source.width); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.cornerType = defaultValue(this.cornerType, source.cornerType); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; + + return CorridorGraphics; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/tangentToEyeSpaceMatrix',[],function() { + +define('DataSources/createRawPropertyDescriptor',[ + './createPropertyDescriptor' + ], function( + createPropertyDescriptor) { 'use strict'; - return "mat3 czm_tangentToEyeSpaceMatrix(vec3 normalEC, vec3 tangentEC, vec3 bitangentEC)\n\ -{\n\ -vec3 normal = normalize(normalEC);\n\ -vec3 tangent = normalize(tangentEC);\n\ -vec3 bitangent = normalize(bitangentEC);\n\ -return mat3(tangent.x , tangent.y , tangent.z,\n\ -bitangent.x, bitangent.y, bitangent.z,\n\ -normal.x , normal.y , normal.z);\n\ -}\n\ -"; + + function createRawProperty(value) { + return value; + } + + /** + * @private + */ + function createRawPropertyDescriptor(name, configurable) { + return createPropertyDescriptor(name, configurable, createRawProperty); + } + + return createRawPropertyDescriptor; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/translateRelativeToEye',[],function() { + +define('DataSources/CylinderGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - return "vec4 czm_translateRelativeToEye(vec3 high, vec3 low)\n\ -{\n\ -vec3 highDifference = high - czm_encodedCameraPositionMCHigh;\n\ -vec3 lowDifference = low - czm_encodedCameraPositionMCLow;\n\ -return vec4(highDifference + lowDifference, 1.0);\n\ -}\n\ -"; + + /** + * Describes a cylinder, truncated cone, or cone defined by a length, top radius, and bottom radius. + * The center position and orientation are determined by the containing {@link Entity}. + * + * @alias CylinderGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.length] A numeric Property specifying the length of the cylinder. + * @param {Property} [options.topRadius] A numeric Property specifying the radius of the top of the cylinder. + * @param {Property} [options.bottomRadius] A numeric Property specifying the radius of the bottom of the cylinder. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the cylinder. + * @param {Property} [options.fill=true] A boolean Property specifying whether the cylinder is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the cylinder. + * @param {Property} [options.outline=false] A boolean Property specifying whether the cylinder is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.numberOfVerticalLines=16] A numeric Property specifying the number of vertical lines to draw along the perimeter for the outline. + * @param {Property} [options.slices=128] The number of edges around the perimeter of the cylinder. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the cylinder casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this cylinder will be displayed. + */ + function CylinderGraphics(options) { + this._length = undefined; + this._lengthSubscription = undefined; + this._topRadius = undefined; + this._topRadiusSubscription = undefined; + this._bottomRadius = undefined; + this._bottomRadiusSubscription = undefined; + this._numberOfVerticalLines = undefined; + this._numberOfVerticalLinesSubscription = undefined; + this._slices = undefined; + this._slicesSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(CylinderGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof CylinderGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the numeric Property specifying the length of the cylinder. + * @memberof CylinderGraphics.prototype + * @type {Property} + */ + length : createPropertyDescriptor('length'), + + /** + * Gets or sets the numeric Property specifying the radius of the top of the cylinder. + * @memberof CylinderGraphics.prototype + * @type {Property} + */ + topRadius : createPropertyDescriptor('topRadius'), + + /** + * Gets or sets the numeric Property specifying the radius of the bottom of the cylinder. + * @memberof CylinderGraphics.prototype + * @type {Property} + */ + bottomRadius : createPropertyDescriptor('bottomRadius'), + + /** + * Gets or sets the Property specifying the number of vertical lines to draw along the perimeter for the outline. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default 16 + */ + numberOfVerticalLines : createPropertyDescriptor('numberOfVerticalLines'), + + /** + * Gets or sets the Property specifying the number of edges around the perimeter of the cylinder. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default 128 + */ + slices : createPropertyDescriptor('slices'), + + /** + * Gets or sets the boolean Property specifying the visibility of the cylinder. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the Property specifying the material used to fill the cylinder. + * @memberof CylinderGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), + + /** + * Gets or sets the boolean Property specifying whether the cylinder is filled with the provided material. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), + + /** + * Gets or sets the boolean Property specifying whether the cylinder is outlined. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), + + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Get or sets the enum Property specifying whether the cylinder + * casts or receives shadows from each light source. + * @memberof CylinderGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this cylinder will be displayed. + * @memberof CylinderGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); + + /** + * Duplicates this instance. + * + * @param {CylinderGraphics} [result] The object onto which to store the result. + * @returns {CylinderGraphics} The modified result parameter or a new instance if one was not provided. + */ + CylinderGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new CylinderGraphics(this); + } + result.bottomRadius = this.bottomRadius; + result.length = this.length; + result.topRadius = this.topRadius; + result.show = this.show; + result.material = this.material; + result.numberOfVerticalLines = this.numberOfVerticalLines; + result.slices = this.slices; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {CylinderGraphics} source The object to be merged into this object. + */ + CylinderGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.bottomRadius = defaultValue(this.bottomRadius, source.bottomRadius); + this.length = defaultValue(this.length, source.length); + this.topRadius = defaultValue(this.topRadius, source.topRadius); + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.numberOfVerticalLines = defaultValue(this.numberOfVerticalLines, source.numberOfVerticalLines); + this.slices = defaultValue(this.slices, source.slices); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; + + return CylinderGraphics; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/translucentPhong',[],function() { + +define('DataSources/EllipseGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - return "vec4 czm_translucentPhong(vec3 toEye, czm_material material)\n\ -{\n\ -float diffuse = czm_getLambertDiffuse(vec3(0.0, 0.0, 1.0), material.normal);\n\ -if (czm_sceneMode == czm_sceneMode3D) {\n\ -diffuse += czm_getLambertDiffuse(vec3(0.0, 1.0, 0.0), material.normal);\n\ -}\n\ -diffuse = clamp(diffuse, 0.0, 1.0);\n\ -float specular = czm_getSpecular(czm_sunDirectionEC, toEye, material.normal, material.shininess);\n\ -specular += czm_getSpecular(czm_moonDirectionEC, toEye, material.normal, material.shininess);\n\ -vec3 materialDiffuse = material.diffuse * 0.5;\n\ -vec3 ambient = materialDiffuse;\n\ -vec3 color = ambient + material.emission;\n\ -color += materialDiffuse * diffuse;\n\ -color += material.specular * specular;\n\ -return vec4(color, material.alpha);\n\ -}\n\ -"; + + /** + * Describes an ellipse defined by a center point and semi-major and semi-minor axes. + * The ellipse conforms to the curvature of the globe and can be placed on the surface or + * at altitude and can optionally be extruded into a volume. + * The center point is determined by the containing {@link Entity}. + * + * @alias EllipseGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.semiMajorAxis] The numeric Property specifying the semi-major axis. + * @param {Property} [options.semiMinorAxis] The numeric Property specifying the semi-minor axis. + * @param {Property} [options.height=0] A numeric Property specifying the altitude of the ellipse relative to the ellipsoid surface. + * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the ellipse's extruded face relative to the ellipsoid surface. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the ellipse. + * @param {Property} [options.fill=true] A boolean Property specifying whether the ellipse is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the ellipse. + * @param {Property} [options.outline=false] A boolean Property specifying whether the ellipse is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.numberOfVerticalLines=16] A numeric Property specifying the number of vertical lines to draw along the perimeter for the outline. + * @param {Property} [options.rotation=0.0] A numeric property specifying the rotation of the ellipse counter-clockwise from north. + * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the ellipse texture counter-clockwise from north. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the ellipse. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipse casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this ellipse will be displayed. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Circles and Ellipses.html|Cesium Sandcastle Circles and Ellipses Demo} + */ + function EllipseGraphics(options) { + this._semiMajorAxis = undefined; + this._semiMajorAxisSubscription = undefined; + this._semiMinorAxis = undefined; + this._semiMinorAxisSubscription = undefined; + this._rotation = undefined; + this._rotationSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._height = undefined; + this._heightSubscription = undefined; + this._extrudedHeight = undefined; + this._extrudedHeightSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._stRotation = undefined; + this._stRotationSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._numberOfVerticalLines = undefined; + this._numberOfVerticalLinesSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(EllipseGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof EllipseGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the numeric Property specifying the semi-major axis. + * @memberof EllipseGraphics.prototype + * @type {Property} + */ + semiMajorAxis : createPropertyDescriptor('semiMajorAxis'), + + /** + * Gets or sets the numeric Property specifying the semi-minor axis. + * @memberof EllipseGraphics.prototype + * @type {Property} + */ + semiMinorAxis : createPropertyDescriptor('semiMinorAxis'), + + /** + * Gets or sets the numeric property specifying the rotation of the ellipse clockwise from north. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default 0 + */ + rotation : createPropertyDescriptor('rotation'), + + /** + * Gets or sets the boolean Property specifying the visibility of the ellipse. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the Property specifying the material used to fill the ellipse. + * @memberof EllipseGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), + + /** + * Gets or sets the numeric Property specifying the altitude of the ellipse. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default 0.0 + */ + height : createPropertyDescriptor('height'), + + /** + * Gets or sets the numeric Property specifying the altitude of the ellipse extrusion. + * Setting this property creates volume starting at height and ending at this altitude. + * @memberof EllipseGraphics.prototype + * @type {Property} + */ + extrudedHeight : createPropertyDescriptor('extrudedHeight'), + + /** + * Gets or sets the numeric Property specifying the angular distance between points on the ellipse. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default {CesiumMath.RADIANS_PER_DEGREE} + */ + granularity : createPropertyDescriptor('granularity'), + + /** + * Gets or sets the numeric property specifying the rotation of the ellipse texture counter-clockwise from north. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default 0 + */ + stRotation : createPropertyDescriptor('stRotation'), + + /** + * Gets or sets the boolean Property specifying whether the ellipse is filled with the provided material. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), + + /** + * Gets or sets the Property specifying whether the ellipse is outlined. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), + + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Gets or sets the numeric Property specifying the number of vertical lines to draw along the perimeter for the outline. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default 16 + */ + numberOfVerticalLines : createPropertyDescriptor('numberOfVerticalLines'), + + /** + * Get or sets the enum Property specifying whether the ellipse + * casts or receives shadows from each light source. + * @memberof EllipseGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this ellipse will be displayed. + * @memberof EllipseGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); + + /** + * Duplicates this instance. + * + * @param {EllipseGraphics} [result] The object onto which to store the result. + * @returns {EllipseGraphics} The modified result parameter or a new instance if one was not provided. + */ + EllipseGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new EllipseGraphics(this); + } + result.rotation = this.rotation; + result.semiMajorAxis = this.semiMajorAxis; + result.semiMinorAxis = this.semiMinorAxis; + result.show = this.show; + result.material = this.material; + result.height = this.height; + result.extrudedHeight = this.extrudedHeight; + result.granularity = this.granularity; + result.stRotation = this.stRotation; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.numberOfVerticalLines = this.numberOfVerticalLines; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {EllipseGraphics} source The object to be merged into this object. + */ + EllipseGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.rotation = defaultValue(this.rotation, source.rotation); + this.semiMajorAxis = defaultValue(this.semiMajorAxis, source.semiMajorAxis); + this.semiMinorAxis = defaultValue(this.semiMinorAxis, source.semiMinorAxis); + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.height = defaultValue(this.height, source.height); + this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); + this.granularity = defaultValue(this.granularity, source.granularity); + this.stRotation = defaultValue(this.stRotation, source.stRotation); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.numberOfVerticalLines = defaultValue(this.numberOfVerticalLines, source.numberOfVerticalLines); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; + + return EllipseGraphics; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/transpose',[],function() { + +define('DataSources/EllipsoidGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - return "mat2 czm_transpose(mat2 matrix)\n\ -{\n\ -return mat2(\n\ -matrix[0][0], matrix[1][0],\n\ -matrix[0][1], matrix[1][1]);\n\ -}\n\ -mat3 czm_transpose(mat3 matrix)\n\ -{\n\ -return mat3(\n\ -matrix[0][0], matrix[1][0], matrix[2][0],\n\ -matrix[0][1], matrix[1][1], matrix[2][1],\n\ -matrix[0][2], matrix[1][2], matrix[2][2]);\n\ -}\n\ -mat4 czm_transpose(mat4 matrix)\n\ -{\n\ -return mat4(\n\ -matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],\n\ -matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],\n\ -matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],\n\ -matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);\n\ -}\n\ -"; + + /** + * Describe an ellipsoid or sphere. The center position and orientation are determined by the containing {@link Entity}. + * + * @alias EllipsoidGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.radii] A {@link Cartesian3} Property specifying the radii of the ellipsoid. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the ellipsoid. + * @param {Property} [options.fill=true] A boolean Property specifying whether the ellipsoid is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the ellipsoid. + * @param {Property} [options.outline=false] A boolean Property specifying whether the ellipsoid is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.subdivisions=128] A Property specifying the number of samples per outline ring, determining the granularity of the curvature. + * @param {Property} [options.stackPartitions=64] A Property specifying the number of stacks. + * @param {Property} [options.slicePartitions=64] A Property specifying the number of radial slices. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipsoid casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this ellipsoid will be displayed. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Spheres%20and%20Ellipsoids.html|Cesium Sandcastle Spheres and Ellipsoids Demo} + */ + function EllipsoidGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._radii = undefined; + this._radiiSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._stackPartitions = undefined; + this._stackPartitionsSubscription = undefined; + this._slicePartitions = undefined; + this._slicePartitionsSubscription = undefined; + this._subdivisions = undefined; + this._subdivisionsSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(EllipsoidGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof EllipsoidGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the boolean Property specifying the visibility of the ellipsoid. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the {@link Cartesian3} {@link Property} specifying the radii of the ellipsoid. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + */ + radii : createPropertyDescriptor('radii'), + + /** + * Gets or sets the Property specifying the material used to fill the ellipsoid. + * @memberof EllipsoidGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), + + /** + * Gets or sets the boolean Property specifying whether the ellipsoid is filled with the provided material. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), + + /** + * Gets or sets the Property specifying whether the ellipsoid is outlined. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), + + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Gets or sets the Property specifying the number of stacks. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default 64 + */ + stackPartitions : createPropertyDescriptor('stackPartitions'), + + /** + * Gets or sets the Property specifying the number of radial slices. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default 64 + */ + slicePartitions : createPropertyDescriptor('slicePartitions'), + + /** + * Gets or sets the Property specifying the number of samples per outline ring, determining the granularity of the curvature. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default 128 + */ + subdivisions : createPropertyDescriptor('subdivisions'), + + /** + * Get or sets the enum Property specifying whether the ellipsoid + * casts or receives shadows from each light source. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this ellipsoid will be displayed. + * @memberof EllipsoidGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); + + /** + * Duplicates this instance. + * + * @param {EllipsoidGraphics} [result] The object onto which to store the result. + * @returns {EllipsoidGraphics} The modified result parameter or a new instance if one was not provided. + */ + EllipsoidGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new EllipsoidGraphics(this); + } + result.show = this.show; + result.radii = this.radii; + result.material = this.material; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.stackPartitions = this.stackPartitions; + result.slicePartitions = this.slicePartitions; + result.subdivisions = this.subdivisions; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {EllipsoidGraphics} source The object to be merged into this object. + */ + EllipsoidGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.show = defaultValue(this.show, source.show); + this.radii = defaultValue(this.radii, source.radii); + this.material = defaultValue(this.material, source.material); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.stackPartitions = defaultValue(this.stackPartitions, source.stackPartitions); + this.slicePartitions = defaultValue(this.slicePartitions, source.slicePartitions); + this.subdivisions = defaultValue(this.subdivisions, source.subdivisions); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; + + return EllipsoidGraphics; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/unpackDepth',[],function() { + +define('DataSources/LabelGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createPropertyDescriptor) { 'use strict'; - return "float czm_unpackDepth(vec4 packedDepth)\n\ -{\n\ -return dot(packedDepth, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n\ -}\n\ -"; + + /** + * Describes a two dimensional label located at the position of the containing {@link Entity}. + * <p> + * <div align='center'> + * <img src='Images/Label.png' width='400' height='300' /><br /> + * Example labels + * </div> + * </p> + * + * @alias LabelGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.text] A Property specifying the text. Explicit newlines '\n' are supported. + * @param {Property} [options.font='10px sans-serif'] A Property specifying the CSS font. + * @param {Property} [options.style=LabelStyle.FILL] A Property specifying the {@link LabelStyle}. + * @param {Property} [options.fillColor=Color.WHITE] A Property specifying the fill {@link Color}. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the outline {@link Color}. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the outline width. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the label. + * @param {Property} [options.showBackground=false] A boolean Property specifying the visibility of the background behind the label. + * @param {Property} [options.backgroundColor=new Color(0.165, 0.165, 0.165, 0.8)] A Property specifying the background {@link Color}. + * @param {Property} [options.backgroundPadding=new Cartesian2(7, 5)] A {@link Cartesian2} Property specifying the horizontal and vertical background padding in pixels. + * @param {Property} [options.scale=1.0] A numeric Property specifying the scale to apply to the text. + * @param {Property} [options.horizontalOrigin=HorizontalOrigin.CENTER] A Property specifying the {@link HorizontalOrigin}. + * @param {Property} [options.verticalOrigin=VerticalOrigin.CENTER] A Property specifying the {@link VerticalOrigin}. + * @param {Property} [options.eyeOffset=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the eye offset. + * @param {Property} [options.pixelOffset=Cartesian2.ZERO] A {@link Cartesian2} Property specifying the pixel offset. + * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera. + * @param {Property} [options.pixelOffsetScaleByDistance] A {@link NearFarScalar} Property used to set pixelOffset based on distance from the camera. + * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to set scale based on distance from the camera. + * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this label will be displayed. + * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Labels.html|Cesium Sandcastle Labels Demo} + */ + function LabelGraphics(options) { + this._text = undefined; + this._textSubscription = undefined; + this._font = undefined; + this._fontSubscription = undefined; + this._style = undefined; + this._styleSubscription = undefined; + this._fillColor = undefined; + this._fillColorSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._horizontalOrigin = undefined; + this._horizontalOriginSubscription = undefined; + this._verticalOrigin = undefined; + this._verticalOriginSubscription = undefined; + this._eyeOffset = undefined; + this._eyeOffsetSubscription = undefined; + this._heightReference = undefined; + this._heightReferenceSubscription = undefined; + this._pixelOffset = undefined; + this._pixelOffsetSubscription = undefined; + this._scale = undefined; + this._scaleSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._showBackground = undefined; + this._showBackgroundSubscription = undefined; + this._backgroundColor = undefined; + this._backgroundColorSubscription = undefined; + this._backgroundPadding = undefined; + this._backgroundPaddingSubscription = undefined; + this._translucencyByDistance = undefined; + this._translucencyByDistanceSubscription = undefined; + this._pixelOffsetScaleByDistance = undefined; + this._pixelOffsetScaleByDistanceSubscription = undefined; + this._scaleByDistance = undefined; + this._scaleByDistanceSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._disableDepthTestDistance = undefined; + this._disableDepthTestDistanceSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(LabelGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof LabelGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the string Property specifying the text of the label. + * Explicit newlines '\n' are supported. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + text : createPropertyDescriptor('text'), + + /** + * Gets or sets the string Property specifying the font in CSS syntax. + * @memberof LabelGraphics.prototype + * @type {Property} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font|CSS font on MDN} + */ + font : createPropertyDescriptor('font'), + + /** + * Gets or sets the Property specifying the {@link LabelStyle}. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + style : createPropertyDescriptor('style'), + + /** + * Gets or sets the Property specifying the fill {@link Color}. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + fillColor : createPropertyDescriptor('fillColor'), + + /** + * Gets or sets the Property specifying the outline {@link Color}. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the outline width. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Gets or sets the Property specifying the {@link HorizontalOrigin}. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + horizontalOrigin : createPropertyDescriptor('horizontalOrigin'), + + /** + * Gets or sets the Property specifying the {@link VerticalOrigin}. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + verticalOrigin : createPropertyDescriptor('verticalOrigin'), + + /** + * Gets or sets the {@link Cartesian3} Property specifying the label's offset in eye coordinates. + * Eye coordinates is a left-handed coordinate system, where <code>x</code> points towards the viewer's + * right, <code>y</code> points up, and <code>z</code> points into the screen. + * <p> + * An eye offset is commonly used to arrange multiple labels or objects at the same position, e.g., to + * arrange a label above its corresponding 3D model. + * </p> + * Below, the label is positioned at the center of the Earth but an eye offset makes it always + * appear on top of the Earth regardless of the viewer's or Earth's orientation. + * <p> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> + * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> + * </tr></table> + * <code>l.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code><br /><br /> + * </div> + * </p> + * @memberof LabelGraphics.prototype + * @type {Property} + * @default Cartesian3.ZERO + */ + eyeOffset : createPropertyDescriptor('eyeOffset'), + + /** + * Gets or sets the Property specifying the {@link HeightReference}. + * @memberof LabelGraphics.prototype + * @type {Property} + * @default HeightReference.NONE + */ + heightReference : createPropertyDescriptor('heightReference'), + + /** + * Gets or sets the {@link Cartesian2} Property specifying the label's pixel offset in screen space + * from the origin of this label. This is commonly used to align multiple labels and labels at + * the same position, e.g., an image and text. The screen space origin is the top, left corner of the + * canvas; <code>x</code> increases from left to right, and <code>y</code> increases from top to bottom. + * <p> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><code>default</code><br/><img src='Images/Label.setPixelOffset.default.png' width='250' height='188' /></td> + * <td align='center'><code>l.pixeloffset = new Cartesian2(25, 75);</code><br/><img src='Images/Label.setPixelOffset.x50y-25.png' width='250' height='188' /></td> + * </tr></table> + * The label's origin is indicated by the yellow point. + * </div> + * </p> + * @memberof LabelGraphics.prototype + * @type {Property} + * @default Cartesian2.ZERO + */ + pixelOffset : createPropertyDescriptor('pixelOffset'), + + /** + * Gets or sets the numeric Property specifying the uniform scale to apply to the image. + * A scale greater than <code>1.0</code> enlarges the label while a scale less than <code>1.0</code> shrinks it. + * <p> + * <div align='center'> + * <img src='Images/Label.setScale.png' width='400' height='300' /><br/> + * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, + * and <code>2.0</code>. + * </div> + * </p> + * @memberof LabelGraphics.prototype + * @type {Property} + * @default 1.0 + */ + scale : createPropertyDescriptor('scale'), + + /** + * Gets or sets the boolean Property specifying the visibility of the label. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the boolean Property specifying the visibility of the background behind the label. + * @memberof LabelGraphics.prototype + * @type {Property} + * @default false + */ + showBackground : createPropertyDescriptor('showBackground'), + + /** + * Gets or sets the Property specifying the background {@link Color}. + * @memberof LabelGraphics.prototype + * @type {Property} + * @default new Color(0.165, 0.165, 0.165, 0.8) + */ + backgroundColor : createPropertyDescriptor('backgroundColor'), + + /** + * Gets or sets the {@link Cartesian2} Property specifying the label's horizontal and vertical + * background padding in pixels. + * @memberof LabelGraphics.prototype + * @type {Property} + * @default new Cartesian2(7, 5) + */ + backgroundPadding : createPropertyDescriptor('backgroundPadding'), + + /** + * Gets or sets {@link NearFarScalar} Property specifying the translucency of the label based on the distance from the camera. + * A label's translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the label's translucency remains clamped to the nearest bound. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + translucencyByDistance : createPropertyDescriptor('translucencyByDistance'), + + /** + * Gets or sets {@link NearFarScalar} Property specifying the pixel offset of the label based on the distance from the camera. + * A label's pixel offset will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the label's pixel offset remains clamped to the nearest bound. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + pixelOffsetScaleByDistance : createPropertyDescriptor('pixelOffsetScaleByDistance'), + + /** + * Gets or sets near and far scaling properties of a Label based on the label's distance from the camera. + * A label's scale will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the label's scale remains clamped to the nearest bound. If undefined, + * scaleByDistance will be disabled. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + scaleByDistance : createPropertyDescriptor('scaleByDistance'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this label will be displayed. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') + }); + + /** + * Duplicates this instance. + * + * @param {LabelGraphics} [result] The object onto which to store the result. + * @returns {LabelGraphics} The modified result parameter or a new instance if one was not provided. + */ + LabelGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new LabelGraphics(this); + } + result.text = this.text; + result.font = this.font; + result.show = this.show; + result.style = this.style; + result.fillColor = this.fillColor; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.showBackground = this.showBackground; + result.backgroundColor = this.backgroundColor; + result.backgroundPadding = this.backgroundPadding; + result.scale = this.scale; + result.horizontalOrigin = this.horizontalOrigin; + result.verticalOrigin = this.verticalOrigin; + result.eyeOffset = this.eyeOffset; + result.heightReference = this.heightReference; + result.pixelOffset = this.pixelOffset; + result.translucencyByDistance = this.translucencyByDistance; + result.pixelOffsetScaleByDistance = this.pixelOffsetScaleByDistance; + result.scaleByDistance = this.scaleByDistance; + result.distanceDisplayCondition = this.distanceDisplayCondition; + result.disableDepthTestDistance = this.disableDepthTestDistance; + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {LabelGraphics} source The object to be merged into this object. + */ + LabelGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.text = defaultValue(this.text, source.text); + this.font = defaultValue(this.font, source.font); + this.show = defaultValue(this.show, source.show); + this.style = defaultValue(this.style, source.style); + this.fillColor = defaultValue(this.fillColor, source.fillColor); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.showBackground = defaultValue(this.showBackground, source.showBackground); + this.backgroundColor = defaultValue(this.backgroundColor, source.backgroundColor); + this.backgroundPadding = defaultValue(this.backgroundPadding, source.backgroundPadding); + this.scale = defaultValue(this.scale, source.scale); + this.horizontalOrigin = defaultValue(this.horizontalOrigin, source.horizontalOrigin); + this.verticalOrigin = defaultValue(this.verticalOrigin, source.verticalOrigin); + this.eyeOffset = defaultValue(this.eyeOffset, source.eyeOffset); + this.heightReference = defaultValue(this.heightReference, source.heightReference); + this.pixelOffset = defaultValue(this.pixelOffset, source.pixelOffset); + this.translucencyByDistance = defaultValue(this.translucencyByDistance, source.translucencyByDistance); + this.pixelOffsetScaleByDistance = defaultValue(this.pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); + this.scaleByDistance = defaultValue(this.scaleByDistance, source.scaleByDistance); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this.disableDepthTestDistance = defaultValue(this.disableDepthTestDistance, source.disableDepthTestDistance); + }; + + return LabelGraphics; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/windowToEyeCoordinates',[],function() { + +define('DataSources/NodeTransformationProperty',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + '../Core/TranslationRotationScale', + './createPropertyDescriptor', + './Property' + ], function( + defaultValue, + defined, + defineProperties, + Event, + TranslationRotationScale, + createPropertyDescriptor, + Property) { 'use strict'; - return "vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate)\n\ -{\n\ -float x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0;\n\ -float y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0;\n\ -float z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];\n\ -vec4 q = vec4(x, y, z, 1.0);\n\ -q /= fragmentCoordinate.w;\n\ -if (czm_inverseProjection != mat4(0.0)) {\n\ -q = czm_inverseProjection * q;\n\ -} else {\n\ -float top = czm_frustumPlanes.x;\n\ -float bottom = czm_frustumPlanes.y;\n\ -float left = czm_frustumPlanes.z;\n\ -float right = czm_frustumPlanes.w;\n\ -float near = czm_currentFrustum.x;\n\ -float far = czm_currentFrustum.y;\n\ -q.x = (q.x * (right - left) + left + right) * 0.5;\n\ -q.y = (q.y * (top - bottom) + bottom + top) * 0.5;\n\ -q.z = (q.z * (near - far) - near - far) * 0.5;\n\ -q.w = 1.0;\n\ -}\n\ -return q;\n\ -}\n\ -"; + + var defaultNodeTransformation = new TranslationRotationScale(); + + /** + * A {@link Property} that produces {@link TranslationRotationScale} data. + * @alias NodeTransformationProperty + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.translation=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node. + * @param {Property} [options.rotation=Quaternion.IDENTITY] A {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node. + * @param {Property} [options.scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node. + */ + var NodeTransformationProperty = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._definitionChanged = new Event(); + this._translation = undefined; + this._translationSubscription = undefined; + this._rotation = undefined; + this._rotationSubscription = undefined; + this._scale = undefined; + this._scaleSubscription = undefined; + + this.translation = options.translation; + this.rotation = options.rotation; + this.scale = options.scale; + }; + + defineProperties(NodeTransformationProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof NodeTransformationProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._translation) && + Property.isConstant(this._rotation) && + Property.isConstant(this._scale); + } + }, + + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof NodeTransformationProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node. + * @memberof NodeTransformationProperty.prototype + * @type {Property} + * @default Cartesian3.ZERO + */ + translation : createPropertyDescriptor('translation'), + + /** + * Gets or sets the {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node. + * @memberof NodeTransformationProperty.prototype + * @type {Property} + * @default Quaternion.IDENTITY + */ + rotation : createPropertyDescriptor('rotation'), + + /** + * Gets or sets the {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node. + * @memberof NodeTransformationProperty.prototype + * @type {Property} + * @default new Cartesian3(1.0, 1.0, 1.0) + */ + scale : createPropertyDescriptor('scale') + }); + + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {TranslationRotationScale} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {TranslationRotationScale} The modified result parameter or a new instance if the result parameter was not supplied. + */ + NodeTransformationProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = new TranslationRotationScale(); + } + + result.translation = Property.getValueOrClonedDefault(this._translation, time, defaultNodeTransformation.translation, result.translation); + result.rotation = Property.getValueOrClonedDefault(this._rotation, time, defaultNodeTransformation.rotation, result.rotation); + result.scale = Property.getValueOrClonedDefault(this._scale, time, defaultNodeTransformation.scale, result.scale); + return result; + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + NodeTransformationProperty.prototype.equals = function(other) { + return this === other || + (other instanceof NodeTransformationProperty && + Property.equals(this._translation, other._translation) && + Property.equals(this._rotation, other._rotation) && + Property.equals(this._scale, other._scale)); + }; + + return NodeTransformationProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/Functions/XYZToRGB',[],function() { + +define('DataSources/PropertyBag',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './ConstantProperty', + './createPropertyDescriptor', + './Property' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ConstantProperty, + createPropertyDescriptor, + Property) { 'use strict'; - return "vec3 czm_XYZToRGB(vec3 Yxy)\n\ -{\n\ -const mat3 XYZ2RGB = mat3( 3.2405, -0.9693, 0.0556,\n\ --1.5371, 1.8760, -0.2040,\n\ --0.4985, 0.0416, 1.0572);\n\ -vec3 xyz;\n\ -xyz.r = Yxy.r * Yxy.g / Yxy.b;\n\ -xyz.g = Yxy.r;\n\ -xyz.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b;\n\ -return XYZ2RGB * xyz;\n\ -}\n\ -"; + + /** + * A {@link Property} whose value is a key-value mapping of property names to the computed value of other properties. + * + * @alias PropertyBag + * @constructor + * + * @param {Object} [value] An object, containing key-value mapping of property names to properties. + * @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. + */ + var PropertyBag = function(value, createPropertyCallback) { + this._propertyNames = []; + this._definitionChanged = new Event(); + + if (defined(value)) { + this.merge(value, createPropertyCallback); + } + }; + + defineProperties(PropertyBag.prototype, { + /** + * Gets the names of all properties registered on this instance. + * @memberof PropertyBag.prototype + * @type {Array} + */ + propertyNames : { + get : function() { + return this._propertyNames; + } + }, + /** + * Gets a value indicating if this property is constant. This property + * is considered constant if all property items in this object are constant. + * @memberof PropertyBag.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + var propertyNames = this._propertyNames; + for (var i = 0, len = propertyNames.length; i < len; i++) { + if (!Property.isConstant(this[propertyNames[i]])) { + return false; + } + } + return true; + } + }, + /** + * Gets the event that is raised whenever the set of properties contained in this + * object changes, or one of the properties itself changes. + * + * @memberof PropertyBag.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + } + }); + + /** + * Determines if this object has defined a property with the given name. + * + * @param {String} propertyName The name of the property to check for. + * + * @returns {Boolean} True if this object has defined a property with the given name, false otherwise. + */ + PropertyBag.prototype.hasProperty = function(propertyName) { + return this._propertyNames.indexOf(propertyName) !== -1; + }; + + function createConstantProperty(value) { + return new ConstantProperty(value); + } + + /** + * Adds a property to this object. + * + * @param {String} propertyName The name of the property to add. + * @param {*} [value] The value of the new property, if provided. + * @param {Function} [createPropertyCallback] A function that will be called when the value of this new property is set to a value that is not a Property. + * + * @exception {DeveloperError} "propertyName" is already a registered property. + */ + PropertyBag.prototype.addProperty = function(propertyName, value, createPropertyCallback) { + var propertyNames = this._propertyNames; + + if (!defined(propertyName)) { + throw new DeveloperError('propertyName is required.'); + } + if (propertyNames.indexOf(propertyName) !== -1) { + throw new DeveloperError(propertyName + ' is already a registered property.'); + } + + propertyNames.push(propertyName); + Object.defineProperty(this, propertyName, createPropertyDescriptor(propertyName, true, defaultValue(createPropertyCallback, createConstantProperty))); + + if (defined(value)) { + this[propertyName] = value; + } + + this._definitionChanged.raiseEvent(this); + }; + + /** + * Removed a property previously added with addProperty. + * + * @param {String} propertyName The name of the property to remove. + * + * @exception {DeveloperError} "propertyName" is not a registered property. + */ + PropertyBag.prototype.removeProperty = function(propertyName) { + var propertyNames = this._propertyNames; + var index = propertyNames.indexOf(propertyName); + + if (!defined(propertyName)) { + throw new DeveloperError('propertyName is required.'); + } + if (index === -1) { + throw new DeveloperError(propertyName + ' is not a registered property.'); + } + + this._propertyNames.splice(index, 1); + delete this[propertyName]; + + this._definitionChanged.raiseEvent(this); + }; + + /** + * Gets the value of this property. Each contained property will be evaluated at the given time, and the overall + * result will be an object, mapping property names to those values. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * Note that any properties in result which are not part of this PropertyBag will be left as-is. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PropertyBag.prototype.getValue = function(time, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!defined(result)) { + result = {}; + } + + var propertyNames = this._propertyNames; + for (var i = 0, len = propertyNames.length; i < len; i++) { + var propertyName = propertyNames[i]; + result[propertyName] = Property.getValueOrUndefined(this[propertyName], time, result[propertyName]); + } + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {Object} source The object to be merged into this object. + * @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. + */ + PropertyBag.prototype.merge = function(source, createPropertyCallback) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + var propertyNames = this._propertyNames; + var sourcePropertyNames = defined(source._propertyNames) ? source._propertyNames : Object.keys(source); + for (var i = 0, len = sourcePropertyNames.length; i < len; i++) { + var name = sourcePropertyNames[i]; + + var targetProperty = this[name]; + var sourceProperty = source[name]; + + //Custom properties that are registered on the source must also be added to this. + if (targetProperty === undefined && propertyNames.indexOf(name) === -1) { + this.addProperty(name, undefined, createPropertyCallback); + } + + if (sourceProperty !== undefined) { + if (targetProperty !== undefined) { + if (defined(targetProperty) && defined(targetProperty.merge)) { + targetProperty.merge(sourceProperty); + } + } else if (defined(sourceProperty) && defined(sourceProperty.merge) && defined(sourceProperty.clone)) { + this[name] = sourceProperty.clone(); + } else { + this[name] = sourceProperty; + } + } + } + }; + + function propertiesEqual(a, b) { + var aPropertyNames = a._propertyNames; + var bPropertyNames = b._propertyNames; + + var len = aPropertyNames.length; + if (len !== bPropertyNames.length) { + return false; + } + + for (var aIndex = 0; aIndex < len; ++aIndex) { + var name = aPropertyNames[aIndex]; + var bIndex = bPropertyNames.indexOf(name); + if (bIndex === -1) { + return false; + } + if (!Property.equals(a[name], b[name])) { + return false; + } + } + return true; + } + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PropertyBag.prototype.equals = function(other) { + return this === other || // + (other instanceof PropertyBag && // + propertiesEqual(this, other)); + }; + + return PropertyBag; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Builtin/CzmBuiltins',[ - './Constants/degreesPerRadian', - './Constants/depthRange', - './Constants/epsilon1', - './Constants/epsilon2', - './Constants/epsilon3', - './Constants/epsilon4', - './Constants/epsilon5', - './Constants/epsilon6', - './Constants/epsilon7', - './Constants/infinity', - './Constants/maxClippingPlanes', - './Constants/oneOverPi', - './Constants/oneOverTwoPi', - './Constants/passCesium3DTile', - './Constants/passCesium3DTileClassification', - './Constants/passCesium3DTileClassificationIgnoreShow', - './Constants/passCompute', - './Constants/passEnvironment', - './Constants/passGlobe', - './Constants/passOpaque', - './Constants/passOverlay', - './Constants/passTerrainClassification', - './Constants/passTranslucent', - './Constants/pi', - './Constants/piOverFour', - './Constants/piOverSix', - './Constants/piOverThree', - './Constants/piOverTwo', - './Constants/radiansPerDegree', - './Constants/sceneMode2D', - './Constants/sceneMode3D', - './Constants/sceneModeColumbusView', - './Constants/sceneModeMorphing', - './Constants/solarRadius', - './Constants/threePiOver2', - './Constants/twoPi', - './Constants/webMercatorMaxLatitude', - './Structs/depthRangeStruct', - './Structs/ellipsoid', - './Structs/material', - './Structs/materialInput', - './Structs/ray', - './Structs/raySegment', - './Structs/shadowParameters', - './Functions/alphaWeight', - './Functions/antialias', - './Functions/cascadeColor', - './Functions/cascadeDistance', - './Functions/cascadeMatrix', - './Functions/cascadeWeights', - './Functions/columbusViewMorph', - './Functions/computePosition', - './Functions/cosineAndSine', - './Functions/decompressTextureCoordinates', - './Functions/discardIfClippedWithIntersect', - './Functions/discardIfClippedWithUnion', - './Functions/eastNorthUpToEyeCoordinates', - './Functions/ellipsoidContainsPoint', - './Functions/ellipsoidNew', - './Functions/ellipsoidWgs84TextureCoordinates', - './Functions/equalsEpsilon', - './Functions/eyeOffset', - './Functions/eyeToWindowCoordinates', - './Functions/fog', - './Functions/geodeticSurfaceNormal', - './Functions/getDefaultMaterial', - './Functions/getLambertDiffuse', - './Functions/getSpecular', - './Functions/getWaterNoise', - './Functions/getWgs84EllipsoidEC', - './Functions/HSBToRGB', - './Functions/HSLToRGB', - './Functions/hue', - './Functions/isEmpty', - './Functions/isFull', - './Functions/latitudeToWebMercatorFraction', - './Functions/luminance', - './Functions/metersPerPixel', - './Functions/modelToWindowCoordinates', - './Functions/multiplyWithColorBalance', - './Functions/nearFarScalar', - './Functions/octDecode', - './Functions/packDepth', - './Functions/phong', - './Functions/pointAlongRay', - './Functions/rayEllipsoidIntersectionInterval', - './Functions/RGBToHSB', - './Functions/RGBToHSL', - './Functions/RGBToXYZ', - './Functions/saturation', - './Functions/shadowDepthCompare', - './Functions/shadowVisibility', - './Functions/signNotZero', - './Functions/tangentToEyeSpaceMatrix', - './Functions/translateRelativeToEye', - './Functions/translucentPhong', - './Functions/transpose', - './Functions/unpackDepth', - './Functions/windowToEyeCoordinates', - './Functions/XYZToRGB' + +define('DataSources/ModelGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createPropertyDescriptor', + './NodeTransformationProperty', + './PropertyBag' ], function( - czm_degreesPerRadian, - czm_depthRange, - czm_epsilon1, - czm_epsilon2, - czm_epsilon3, - czm_epsilon4, - czm_epsilon5, - czm_epsilon6, - czm_epsilon7, - czm_infinity, - czm_maxClippingPlanes, - czm_oneOverPi, - czm_oneOverTwoPi, - czm_passCesium3DTile, - czm_passCesium3DTileClassification, - czm_passCesium3DTileClassificationIgnoreShow, - czm_passCompute, - czm_passEnvironment, - czm_passGlobe, - czm_passOpaque, - czm_passOverlay, - czm_passTerrainClassification, - czm_passTranslucent, - czm_pi, - czm_piOverFour, - czm_piOverSix, - czm_piOverThree, - czm_piOverTwo, - czm_radiansPerDegree, - czm_sceneMode2D, - czm_sceneMode3D, - czm_sceneModeColumbusView, - czm_sceneModeMorphing, - czm_solarRadius, - czm_threePiOver2, - czm_twoPi, - czm_webMercatorMaxLatitude, - czm_depthRangeStruct, - czm_ellipsoid, - czm_material, - czm_materialInput, - czm_ray, - czm_raySegment, - czm_shadowParameters, - czm_alphaWeight, - czm_antialias, - czm_cascadeColor, - czm_cascadeDistance, - czm_cascadeMatrix, - czm_cascadeWeights, - czm_columbusViewMorph, - czm_computePosition, - czm_cosineAndSine, - czm_decompressTextureCoordinates, - czm_discardIfClippedWithIntersect, - czm_discardIfClippedWithUnion, - czm_eastNorthUpToEyeCoordinates, - czm_ellipsoidContainsPoint, - czm_ellipsoidNew, - czm_ellipsoidWgs84TextureCoordinates, - czm_equalsEpsilon, - czm_eyeOffset, - czm_eyeToWindowCoordinates, - czm_fog, - czm_geodeticSurfaceNormal, - czm_getDefaultMaterial, - czm_getLambertDiffuse, - czm_getSpecular, - czm_getWaterNoise, - czm_getWgs84EllipsoidEC, - czm_HSBToRGB, - czm_HSLToRGB, - czm_hue, - czm_isEmpty, - czm_isFull, - czm_latitudeToWebMercatorFraction, - czm_luminance, - czm_metersPerPixel, - czm_modelToWindowCoordinates, - czm_multiplyWithColorBalance, - czm_nearFarScalar, - czm_octDecode, - czm_packDepth, - czm_phong, - czm_pointAlongRay, - czm_rayEllipsoidIntersectionInterval, - czm_RGBToHSB, - czm_RGBToHSL, - czm_RGBToXYZ, - czm_saturation, - czm_shadowDepthCompare, - czm_shadowVisibility, - czm_signNotZero, - czm_tangentToEyeSpaceMatrix, - czm_translateRelativeToEye, - czm_translucentPhong, - czm_transpose, - czm_unpackDepth, - czm_windowToEyeCoordinates, - czm_XYZToRGB) { - 'use strict'; - return { - czm_degreesPerRadian : czm_degreesPerRadian, - czm_depthRange : czm_depthRange, - czm_epsilon1 : czm_epsilon1, - czm_epsilon2 : czm_epsilon2, - czm_epsilon3 : czm_epsilon3, - czm_epsilon4 : czm_epsilon4, - czm_epsilon5 : czm_epsilon5, - czm_epsilon6 : czm_epsilon6, - czm_epsilon7 : czm_epsilon7, - czm_infinity : czm_infinity, - czm_maxClippingPlanes : czm_maxClippingPlanes, - czm_oneOverPi : czm_oneOverPi, - czm_oneOverTwoPi : czm_oneOverTwoPi, - czm_passCesium3DTile : czm_passCesium3DTile, - czm_passCesium3DTileClassification : czm_passCesium3DTileClassification, - czm_passCesium3DTileClassificationIgnoreShow : czm_passCesium3DTileClassificationIgnoreShow, - czm_passCompute : czm_passCompute, - czm_passEnvironment : czm_passEnvironment, - czm_passGlobe : czm_passGlobe, - czm_passOpaque : czm_passOpaque, - czm_passOverlay : czm_passOverlay, - czm_passTerrainClassification : czm_passTerrainClassification, - czm_passTranslucent : czm_passTranslucent, - czm_pi : czm_pi, - czm_piOverFour : czm_piOverFour, - czm_piOverSix : czm_piOverSix, - czm_piOverThree : czm_piOverThree, - czm_piOverTwo : czm_piOverTwo, - czm_radiansPerDegree : czm_radiansPerDegree, - czm_sceneMode2D : czm_sceneMode2D, - czm_sceneMode3D : czm_sceneMode3D, - czm_sceneModeColumbusView : czm_sceneModeColumbusView, - czm_sceneModeMorphing : czm_sceneModeMorphing, - czm_solarRadius : czm_solarRadius, - czm_threePiOver2 : czm_threePiOver2, - czm_twoPi : czm_twoPi, - czm_webMercatorMaxLatitude : czm_webMercatorMaxLatitude, - czm_depthRangeStruct : czm_depthRangeStruct, - czm_ellipsoid : czm_ellipsoid, - czm_material : czm_material, - czm_materialInput : czm_materialInput, - czm_ray : czm_ray, - czm_raySegment : czm_raySegment, - czm_shadowParameters : czm_shadowParameters, - czm_alphaWeight : czm_alphaWeight, - czm_antialias : czm_antialias, - czm_cascadeColor : czm_cascadeColor, - czm_cascadeDistance : czm_cascadeDistance, - czm_cascadeMatrix : czm_cascadeMatrix, - czm_cascadeWeights : czm_cascadeWeights, - czm_columbusViewMorph : czm_columbusViewMorph, - czm_computePosition : czm_computePosition, - czm_cosineAndSine : czm_cosineAndSine, - czm_decompressTextureCoordinates : czm_decompressTextureCoordinates, - czm_discardIfClippedWithIntersect : czm_discardIfClippedWithIntersect, - czm_discardIfClippedWithUnion : czm_discardIfClippedWithUnion, - czm_eastNorthUpToEyeCoordinates : czm_eastNorthUpToEyeCoordinates, - czm_ellipsoidContainsPoint : czm_ellipsoidContainsPoint, - czm_ellipsoidNew : czm_ellipsoidNew, - czm_ellipsoidWgs84TextureCoordinates : czm_ellipsoidWgs84TextureCoordinates, - czm_equalsEpsilon : czm_equalsEpsilon, - czm_eyeOffset : czm_eyeOffset, - czm_eyeToWindowCoordinates : czm_eyeToWindowCoordinates, - czm_fog : czm_fog, - czm_geodeticSurfaceNormal : czm_geodeticSurfaceNormal, - czm_getDefaultMaterial : czm_getDefaultMaterial, - czm_getLambertDiffuse : czm_getLambertDiffuse, - czm_getSpecular : czm_getSpecular, - czm_getWaterNoise : czm_getWaterNoise, - czm_getWgs84EllipsoidEC : czm_getWgs84EllipsoidEC, - czm_HSBToRGB : czm_HSBToRGB, - czm_HSLToRGB : czm_HSLToRGB, - czm_hue : czm_hue, - czm_isEmpty : czm_isEmpty, - czm_isFull : czm_isFull, - czm_latitudeToWebMercatorFraction : czm_latitudeToWebMercatorFraction, - czm_luminance : czm_luminance, - czm_metersPerPixel : czm_metersPerPixel, - czm_modelToWindowCoordinates : czm_modelToWindowCoordinates, - czm_multiplyWithColorBalance : czm_multiplyWithColorBalance, - czm_nearFarScalar : czm_nearFarScalar, - czm_octDecode : czm_octDecode, - czm_packDepth : czm_packDepth, - czm_phong : czm_phong, - czm_pointAlongRay : czm_pointAlongRay, - czm_rayEllipsoidIntersectionInterval : czm_rayEllipsoidIntersectionInterval, - czm_RGBToHSB : czm_RGBToHSB, - czm_RGBToHSL : czm_RGBToHSL, - czm_RGBToXYZ : czm_RGBToXYZ, - czm_saturation : czm_saturation, - czm_shadowDepthCompare : czm_shadowDepthCompare, - czm_shadowVisibility : czm_shadowVisibility, - czm_signNotZero : czm_signNotZero, - czm_tangentToEyeSpaceMatrix : czm_tangentToEyeSpaceMatrix, - czm_translateRelativeToEye : czm_translateRelativeToEye, - czm_translucentPhong : czm_translucentPhong, - czm_transpose : czm_transpose, - czm_unpackDepth : czm_unpackDepth, - czm_windowToEyeCoordinates : czm_windowToEyeCoordinates, - czm_XYZToRGB : czm_XYZToRGB}; + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createPropertyDescriptor, + NodeTransformationProperty, + PropertyBag) { + 'use strict'; + + function createNodeTransformationProperty(value) { + return new NodeTransformationProperty(value); + } + + function createNodeTransformationPropertyBag(value) { + return new PropertyBag(value, createNodeTransformationProperty); + } + + /** + * A 3D model based on {@link https://github.com/KhronosGroup/glTF|glTF}, the runtime asset format for WebGL, OpenGL ES, and OpenGL. + * The position and orientation of the model is determined by the containing {@link Entity}. + * <p> + * Cesium includes support for glTF geometry, materials, animations, and skinning. + * Cameras and lights are not currently supported. + * </p> + * + * @alias ModelGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.uri] A string or Resource Property specifying the URI of the glTF asset. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the model. + * @param {Property} [options.scale=1.0] A numeric Property specifying a uniform linear scale. + * @param {Property} [options.minimumPixelSize=0.0] A numeric Property specifying the approximate minimum pixel size of the model regardless of zoom. + * @param {Property} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. + * @param {Property} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {Property} [options.runAnimations=true] A boolean Property specifying if glTF animations specified in the model should be started. + * @param {Property} [options.clampAnimations=true] A boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes. + * @param {Property} [options.nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. + * @param {Property} [options.shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from each light source. + * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed. + * @param {Property} [options.silhouetteColor=Color.RED] A Property specifying the {@link Color} of the silhouette. + * @param {Property} [options.silhouetteSize=0.0] A numeric Property specifying the size of the silhouette in pixels. + * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} that blends with the model's rendered color. + * @param {Property} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model. + * @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @param {Property} [options.clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. Clipping planes are not currently supported in Internet Explorer. + * + * @see {@link https://cesiumjs.org/tutorials/3D-Models-Tutorial/|3D Models Tutorial} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle 3D Models Demo} + */ + function ModelGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._scale = undefined; + this._scaleSubscription = undefined; + this._minimumPixelSize = undefined; + this._minimumPixelSizeSubscription = undefined; + this._maximumScale = undefined; + this._maximumScaleSubscription = undefined; + this._incrementallyLoadTextures = undefined; + this._incrementallyLoadTexturesSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._uri = undefined; + this._uriSubscription = undefined; + this._runAnimations = undefined; + this._clampAnimations = undefined; + this._runAnimationsSubscription = undefined; + this._nodeTransformations = undefined; + this._nodeTransformationsSubscription = undefined; + this._heightReference = undefined; + this._heightReferenceSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._silhouetteColor = undefined; + this._silhouetteColorSubscription = undefined; + this._silhouetteSize = undefined; + this._silhouetteSizeSubscription = undefined; + this._color = undefined; + this._colorSubscription = undefined; + this._colorBlendMode = undefined; + this._colorBlendModeSubscription = undefined; + this._colorBlendAmount = undefined; + this._colorBlendAmountSubscription = undefined; + this._clippingPlanes = undefined; + this._clippingPlanesSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } + + defineProperties(ModelGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof ModelGraphics.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + + /** + * Gets or sets the boolean Property specifying the visibility of the model. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), + + /** + * Gets or sets the numeric Property specifying a uniform linear scale + * for this model. Values greater than 1.0 increase the size of the model while + * values less than 1.0 decrease it. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default 1.0 + */ + scale : createPropertyDescriptor('scale'), + + /** + * Gets or sets the numeric Property specifying the approximate minimum + * pixel size of the model regardless of zoom. This can be used to ensure that + * a model is visible even when the viewer zooms out. When <code>0.0</code>, + * no minimum size is enforced. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default 0.0 + */ + minimumPixelSize : createPropertyDescriptor('minimumPixelSize'), + + /** + * Gets or sets the numeric Property specifying the maximum scale + * size of a model. This property is used as an upper limit for + * {@link ModelGraphics#minimumPixelSize}. + * @memberof ModelGraphics.prototype + * @type {Property} + */ + maximumScale : createPropertyDescriptor('maximumScale'), + + /** + * Get or sets the boolean Property specifying whether textures + * may continue to stream in after the model is loaded. + * @memberof ModelGraphics.prototype + * @type {Property} + */ + incrementallyLoadTextures : createPropertyDescriptor('incrementallyLoadTextures'), + + /** + * Get or sets the enum Property specifying whether the model + * casts or receives shadows from each light source. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default ShadowMode.ENABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the string Property specifying the URI of the glTF asset. + * @memberof ModelGraphics.prototype + * @type {Property} + */ + uri : createPropertyDescriptor('uri'), + + /** + * Gets or sets the boolean Property specifying if glTF animations should be run. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default true + */ + runAnimations : createPropertyDescriptor('runAnimations'), + + /** + * Gets or sets the boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default true + */ + clampAnimations : createPropertyDescriptor('clampAnimations'), + + /** + * Gets or sets the set of node transformations to apply to this model. This is represented as an {@link PropertyBag}, where keys are + * names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. + * @memberof ModelGraphics.prototype + * @type {PropertyBag} + */ + nodeTransformations : createPropertyDescriptor('nodeTransformations', undefined, createNodeTransformationPropertyBag), + + /** + * Gets or sets the Property specifying the {@link HeightReference}. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default HeightReference.NONE + */ + heightReference : createPropertyDescriptor('heightReference'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this model will be displayed. + * @memberof ModelGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + + /** + * Gets or sets the Property specifying the {@link Color} of the silhouette. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default Color.RED + */ + silhouetteColor: createPropertyDescriptor('silhouetteColor'), + + /** + * Gets or sets the numeric Property specifying the size of the silhouette in pixels. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default 0.0 + */ + silhouetteSize : createPropertyDescriptor('silhouetteSize'), + + /** + * Gets or sets the Property specifying the {@link Color} that blends with the model's rendered color. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default Color.WHITE + */ + color : createPropertyDescriptor('color'), + + /** + * Gets or sets the enum Property specifying how the color blends with the model. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default ColorBlendMode.HIGHLIGHT + */ + colorBlendMode : createPropertyDescriptor('colorBlendMode'), + + /** + * A numeric Property specifying the color strength when the <code>colorBlendMode</code> is MIX. + * A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with + * any value in-between resulting in a mix of the two. + * @memberof ModelGraphics.prototype + * @type {Property} + * @default 0.5 + */ + colorBlendAmount : createPropertyDescriptor('colorBlendAmount'), + + /** + * A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. + * @memberof ModelGraphics.prototype + * @type {Property} + */ + clippingPlanes : createPropertyDescriptor('clippingPlanes') + }); + + /** + * Duplicates this instance. + * + * @param {ModelGraphics} [result] The object onto which to store the result. + * @returns {ModelGraphics} The modified result parameter or a new instance if one was not provided. + */ + ModelGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new ModelGraphics(this); + } + result.show = this.show; + result.scale = this.scale; + result.minimumPixelSize = this.minimumPixelSize; + result.maximumScale = this.maximumScale; + result.incrementallyLoadTextures = this.incrementallyLoadTextures; + result.shadows = this.shadows; + result.uri = this.uri; + result.runAnimations = this.runAnimations; + result.clampAnimations = this.clampAnimations; + result.nodeTransformations = this.nodeTransformations; + result.heightReference = this._heightReference; + result.distanceDisplayCondition = this.distanceDisplayCondition; + result.silhouetteColor = this.silhouetteColor; + result.silhouetteSize = this.silhouetteSize; + result.color = this.color; + result.colorBlendMode = this.colorBlendMode; + result.colorBlendAmount = this.colorBlendAmount; + result.clippingPlanes = this.clippingPlanes; + + return result; + }; + + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {ModelGraphics} source The object to be merged into this object. + */ + ModelGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.show = defaultValue(this.show, source.show); + this.scale = defaultValue(this.scale, source.scale); + this.minimumPixelSize = defaultValue(this.minimumPixelSize, source.minimumPixelSize); + this.maximumScale = defaultValue(this.maximumScale, source.maximumScale); + this.incrementallyLoadTextures = defaultValue(this.incrementallyLoadTextures, source.incrementallyLoadTextures); + this.shadows = defaultValue(this.shadows, source.shadows); + this.uri = defaultValue(this.uri, source.uri); + this.runAnimations = defaultValue(this.runAnimations, source.runAnimations); + this.clampAnimations = defaultValue(this.clampAnimations, source.clampAnimations); + this.heightReference = defaultValue(this.heightReference, source.heightReference); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this.silhouetteColor = defaultValue(this.silhouetteColor, source.silhouetteColor); + this.silhouetteSize = defaultValue(this.silhouetteSize, source.silhouetteSize); + this.color = defaultValue(this.color, source.color); + this.colorBlendMode = defaultValue(this.colorBlendMode, source.colorBlendMode); + this.colorBlendAmount = defaultValue(this.colorBlendAmount, source.colorBlendAmount); + this.clippingPlanes = defaultValue(this.clippingPlanes, source.clippingPlanes); + + var sourceNodeTransformations = source.nodeTransformations; + if (defined(sourceNodeTransformations)) { + var targetNodeTransformations = this.nodeTransformations; + if (defined(targetNodeTransformations)) { + targetNodeTransformations.merge(sourceNodeTransformations); + } else { + this.nodeTransformations = new PropertyBag(sourceNodeTransformations, createNodeTransformationProperty); + } + } + }; + + return ModelGraphics; }); -define('Renderer/ShaderSource',[ + +define('DataSources/PathGraphics',[ '../Core/defaultValue', '../Core/defined', + '../Core/defineProperties', '../Core/DeveloperError', - '../Renderer/modernizeShader', - '../Shaders/Builtin/CzmBuiltins', - './AutomaticUniforms' + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' ], function( defaultValue, defined, + defineProperties, DeveloperError, - modernizeShader, - CzmBuiltins, - AutomaticUniforms) { + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - function removeComments(source) { - // remove inline comments - source = source.replace(/\/\/.*/g, ''); - // remove multiline comment block - return source.replace(/\/\*\*[\s\S]*?\*\//gm, function(match) { - // preserve the number of lines in the comment block so the line numbers will be correct when debugging shaders - var numberOfLines = match.match(/\n/gm).length; - var replacement = ''; - for (var lineNumber = 0; lineNumber < numberOfLines; ++lineNumber) { - replacement += '\n'; - } - return replacement; - }); + /** + * Describes a polyline defined as the path made by an {@link Entity} as it moves over time. + * + * @alias PathGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.leadTime] A Property specifying the number of seconds behind the object to show. + * @param {Property} [options.trailTime] A Property specifying the number of seconds in front of the object to show. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the path. + * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the path. + * @param {Property} [options.resolution=60] A numeric Property specifying the maximum number of seconds to step when sampling the position. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this path will be displayed. + */ + function PathGraphics(options) { + this._material = undefined; + this._materialSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._width = undefined; + this._widthSubscription = undefined; + this._resolution = undefined; + this._resolutionSubscription = undefined; + this._leadTime = undefined; + this._leadTimeSubscription = undefined; + this._trailTime = undefined; + this._trailTimeSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); + + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); } - function getDependencyNode(name, glslSource, nodes) { - var dependencyNode; - - // check if already loaded - for (var i = 0; i < nodes.length; ++i) { - if (nodes[i].name === name) { - dependencyNode = nodes[i]; + defineProperties(PathGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof PathGraphics.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - } + }, - if (!defined(dependencyNode)) { - // strip doc comments so we don't accidentally try to determine a dependency for something found - // in a comment - glslSource = removeComments(glslSource); + /** + * Gets or sets the boolean Property specifying the visibility of the path. + * @memberof PathGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - // create new node - dependencyNode = { - name : name, - glslSource : glslSource, - dependsOn : [], - requiredBy : [], - evaluated : false - }; - nodes.push(dependencyNode); - } + /** + * Gets or sets the Property specifying the material used to draw the path. + * @memberof PathGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - return dependencyNode; - } + /** + * Gets or sets the numeric Property specifying the width in pixels. + * @memberof PathGraphics.prototype + * @type {Property} + * @default 1.0 + */ + width : createPropertyDescriptor('width'), - function generateDependencies(currentNode, dependencyNodes) { - if (currentNode.evaluated) { - return; - } + /** + * Gets or sets the Property specifying the maximum number of seconds to step when sampling the position. + * @memberof PathGraphics.prototype + * @type {Property} + * @default 60 + */ + resolution : createPropertyDescriptor('resolution'), - currentNode.evaluated = true; + /** + * Gets or sets the Property specifying the number of seconds in front of the object to show. + * @memberof PathGraphics.prototype + * @type {Property} + */ + leadTime : createPropertyDescriptor('leadTime'), - // identify all dependencies that are referenced from this glsl source code - var czmMatches = currentNode.glslSource.match(/\bczm_[a-zA-Z0-9_]*/g); - if (defined(czmMatches) && czmMatches !== null) { - // remove duplicates - czmMatches = czmMatches.filter(function(elem, pos) { - return czmMatches.indexOf(elem) === pos; - }); + /** + * Gets or sets the Property specifying the number of seconds behind the object to show. + * @memberof PathGraphics.prototype + * @type {Property} + */ + trailTime : createPropertyDescriptor('trailTime'), - czmMatches.forEach(function(element) { - if (element !== currentNode.name && ShaderSource._czmBuiltinsAndUniforms.hasOwnProperty(element)) { - var referencedNode = getDependencyNode(element, ShaderSource._czmBuiltinsAndUniforms[element], dependencyNodes); - currentNode.dependsOn.push(referencedNode); - referencedNode.requiredBy.push(currentNode); + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this path will be displayed. + * @memberof PathGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); - // recursive call to find any dependencies of the new node - generateDependencies(referencedNode, dependencyNodes); - } - }); + /** + * Duplicates this instance. + * + * @param {PathGraphics} [result] The object onto which to store the result. + * @returns {PathGraphics} The modified result parameter or a new instance if one was not provided. + */ + PathGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new PathGraphics(this); } - } - - function sortDependencies(dependencyNodes) { - var nodesWithoutIncomingEdges = []; - var allNodes = []; - - while (dependencyNodes.length > 0) { - var node = dependencyNodes.pop(); - allNodes.push(node); + result.material = this.material; + result.width = this.width; + result.resolution = this.resolution; + result.show = this.show; + result.leadTime = this.leadTime; + result.trailTime = this.trailTime; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; - if (node.requiredBy.length === 0) { - nodesWithoutIncomingEdges.push(node); - } + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {PathGraphics} source The object to be merged into this object. + */ + PathGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); } + + this.material = defaultValue(this.material, source.material); + this.width = defaultValue(this.width, source.width); + this.resolution = defaultValue(this.resolution, source.resolution); + this.show = defaultValue(this.show, source.show); + this.leadTime = defaultValue(this.leadTime, source.leadTime); + this.trailTime = defaultValue(this.trailTime, source.trailTime); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; - while (nodesWithoutIncomingEdges.length > 0) { - var currentNode = nodesWithoutIncomingEdges.shift(); - - dependencyNodes.push(currentNode); + return PathGraphics; +}); - for (var i = 0; i < currentNode.dependsOn.length; ++i) { - // remove the edge from the graph - var referencedNode = currentNode.dependsOn[i]; - var index = referencedNode.requiredBy.indexOf(currentNode); - referencedNode.requiredBy.splice(index, 1); +define('DataSources/PlaneGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' +], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { + 'use strict'; - // if referenced node has no more incoming edges, add to list - if (referencedNode.requiredBy.length === 0) { - nodesWithoutIncomingEdges.push(referencedNode); - } - } - } + /** + * Describes a plane. The center position and orientation are determined by the containing {@link Entity}. + * + * @alias PlaneGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.plane] A {@link Plane} Property specifying the normal and distance for the plane. + * @param {Property} [options.dimensions] A {@link Cartesian2} Property specifying the width and height of the plane. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the plane. + * @param {Property} [options.fill=true] A boolean Property specifying whether the plane is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the plane. + * @param {Property} [options.outline=false] A boolean Property specifying whether the plane is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the plane casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this plane will be displayed. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Plane.html|Cesium Sandcastle Plane Demo} + */ + function PlaneGraphics(options) { + this._plane = undefined; + this._planeSubscription = undefined; + this._dimensions = undefined; + this._dimensionsSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); - // if there are any nodes left with incoming edges, then there was a circular dependency somewhere in the graph - var badNodes = []; - for (var j = 0; j < allNodes.length; ++j) { - if (allNodes[j].requiredBy.length !== 0) { - badNodes.push(allNodes[j]); - } - } + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } - if (badNodes.length !== 0) { - var message = 'A circular dependency was found in the following built-in functions/structs/constants: \n'; - for (var k = 0; k < badNodes.length; ++k) { - message = message + badNodes[k].name + '\n'; - } - throw new DeveloperError(message); - } + defineProperties(PlaneGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof PlaneGraphics.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } + }, - function getBuiltinsAndAutomaticUniforms(shaderSource) { - // generate a dependency graph for builtin functions - var dependencyNodes = []; - var root = getDependencyNode('main', shaderSource, dependencyNodes); - generateDependencies(root, dependencyNodes); - sortDependencies(dependencyNodes); + /** + * Gets or sets the boolean Property specifying the visibility of the plane. + * @memberof PlaneGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - // Concatenate the source code for the function dependencies. - // Iterate in reverse so that dependent items are declared before they are used. - var builtinsSource = ''; - for (var i = dependencyNodes.length - 1; i >= 0; --i) { - builtinsSource = builtinsSource + dependencyNodes[i].glslSource + '\n'; - } + /** + * Gets or sets the {@link Plane} Property specifying the normal and distance of the plane. + * + * @memberof PlaneGraphics.prototype + * @type {Property} + */ + plane : createPropertyDescriptor('plane'), - return builtinsSource.replace(root.glslSource, ''); - } + /** + * Gets or sets the {@link Cartesian2} Property specifying the width and height of the plane. + * + * @memberof PlaneGraphics.prototype + * @type {Property} + */ + dimensions : createPropertyDescriptor('dimensions'), - function combineShader(shaderSource, isFragmentShader, context) { - var i; - var length; + /** + * Gets or sets the material used to fill the plane. + * @memberof PlaneGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - // Combine shader sources, generally for pseudo-polymorphism, e.g., czm_getMaterial. - var combinedSources = ''; - var sources = shaderSource.sources; - if (defined(sources)) { - for (i = 0, length = sources.length; i < length; ++i) { - // #line needs to be on its own line. - combinedSources += '\n#line 0\n' + sources[i]; - } - } + /** + * Gets or sets the boolean Property specifying whether the plane is filled with the provided material. + * @memberof PlaneGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), - combinedSources = removeComments(combinedSources); + /** + * Gets or sets the Property specifying whether the plane is outlined. + * @memberof PlaneGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), - // Extract existing shader version from sources - var version; - combinedSources = combinedSources.replace(/#version\s+(.*?)\n/gm, function(match, group1) { - if (defined(version) && version !== group1) { - throw new DeveloperError('inconsistent versions found: ' + version + ' and ' + group1); - } - - // Extract #version to put at the top - version = group1; + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof PlaneGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), - // Replace original #version directive with a new line so the line numbers - // are not off by one. There can be only one #version directive - // and it must appear at the top of the source, only preceded by - // whitespace and comments. - return '\n'; - }); + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof PlaneGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), - // Extract shader extensions from sources - var extensions = []; - combinedSources = combinedSources.replace(/#extension.*\n/gm, function(match) { - // Extract extension to put at the top - extensions.push(match); + /** + * Get or sets the enum Property specifying whether the plane + * casts or receives shadows from each light source. + * @memberof PlaneGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), - // Replace original #extension directive with a new line so the line numbers - // are not off by one. - return '\n'; - }); + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this plane will be displayed. + * @memberof PlaneGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); - // Remove precision qualifier - combinedSources = combinedSources.replace(/precision\s(lowp|mediump|highp)\s(float|int);/, ''); + /** + * Duplicates this instance. + * + * @param {PlaneGraphics} [result] The object onto which to store the result. + * @returns {PlaneGraphics} The modified result parameter or a new instance if one was not provided. + */ + PlaneGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new PlaneGraphics(this); + } + result.plane = this.plane; + result.dimensions = this.dimensions; + result.show = this.show; + result.material = this.material; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; - // Replace main() for picked if desired. - var pickColorQualifier = shaderSource.pickColorQualifier; - if (defined(pickColorQualifier)) { - combinedSources = ShaderSource.createPickFragmentShaderSource(combinedSources, pickColorQualifier); + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {PlaneGraphics} source The object to be merged into this object. + */ + PlaneGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); } + + this.plane = defaultValue(this.plane, source.plane); + this.dimensions = defaultValue(this.dimensions, source.dimensions); + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; - // combine into single string - var result = ''; + return PlaneGraphics; +}); - // #version must be first - // defaults to #version 100 if not specified - if (defined(version)) { - result = '#version ' + version + '\n'; - } +define('DataSources/PointGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createPropertyDescriptor) { + 'use strict'; - var extensionsLength = extensions.length; - for (i = 0; i < extensionsLength; i++) { - result += extensions[i]; - } + /** + * Describes a graphical point located at the position of the containing {@link Entity}. + * + * @alias PointGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the point. + * @param {Property} [options.pixelSize=1] A numeric Property specifying the size in pixels. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=0] A numeric Property specifying the the outline width in pixels. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the point. + * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to scale the point based on distance. + * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera. + * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this point will be displayed. + * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to. + */ + function PointGraphics(options) { + this._color = undefined; + this._colorSubscription = undefined; + this._pixelSize = undefined; + this._pixelSizeSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; + this._scaleByDistance = undefined; + this._scaleByDistanceSubscription = undefined; + this._translucencyByDistance = undefined; + this._translucencyByDistanceSubscription = undefined; + this._heightReference = undefined; + this._heightReferenceSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._disableDepthTestDistance = undefined; + this._disableDepthTestDistanceSubscription = undefined; + this._definitionChanged = new Event(); - if (isFragmentShader) { - result += '\ -#ifdef GL_FRAGMENT_PRECISION_HIGH\n\ - precision highp float;\n\ -#else\n\ - precision mediump float;\n\ -#endif\n\n'; - } + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } - // Prepend #defines for uber-shaders - var defines = shaderSource.defines; - if (defined(defines)) { - for (i = 0, length = defines.length; i < length; ++i) { - var define = defines[i]; - if (define.length !== 0) { - result += '#define ' + define + '\n'; - } + defineProperties(PointGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof PointGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - } + }, - // GLSLModernizer inserts its own layout qualifiers - // at this position in the source - if (context.webgl2) { - result += '#define OUTPUT_DECLARATION\n\n'; - } + /** + * Gets or sets the Property specifying the {@link Color} of the point. + * @memberof PointGraphics.prototype + * @type {Property} + * @default Color.WHITE + */ + color : createPropertyDescriptor('color'), - // append built-ins - if (shaderSource.includeBuiltIns) { - result += getBuiltinsAndAutomaticUniforms(combinedSources); - } + /** + * Gets or sets the numeric Property specifying the size in pixels. + * @memberof PointGraphics.prototype + * @type {Property} + * @default 1 + */ + pixelSize : createPropertyDescriptor('pixelSize'), - // reset line number - result += '\n#line 0\n'; + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof PointGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), - // append actual source - result += combinedSources; + /** + * Gets or sets the numeric Property specifying the the outline width in pixels. + * @memberof PointGraphics.prototype + * @type {Property} + * @default 0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), - // modernize the source - if (context.webgl2) { - result = modernizeShader(result, isFragmentShader, true); - } + /** + * Gets or sets the boolean Property specifying the visibility of the point. + * @memberof PointGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - return result; - } + /** + * Gets or sets the {@link NearFarScalar} Property used to scale the point based on distance. + * If undefined, a constant size is used. + * @memberof PointGraphics.prototype + * @type {Property} + */ + scaleByDistance : createPropertyDescriptor('scaleByDistance'), - /** - * An object containing various inputs that will be combined to form a final GLSL shader string. - * - * @param {Object} [options] Object with the following properties: - * @param {String[]} [options.sources] An array of strings to combine containing GLSL code for the shader. - * @param {String[]} [options.defines] An array of strings containing GLSL identifiers to <code>#define</code>. - * @param {String} [options.pickColorQualifier] The GLSL qualifier, <code>uniform</code> or <code>varying</code>, for the input <code>czm_pickColor</code>. When defined, a pick fragment shader is generated. - * @param {Boolean} [options.includeBuiltIns=true] If true, referenced built-in functions will be included with the combined shader. Set to false if this shader will become a source in another shader, to avoid duplicating functions. - * - * @exception {DeveloperError} options.pickColorQualifier must be 'uniform' or 'varying'. - * - * @example - * // 1. Prepend #defines to a shader - * var source = new Cesium.ShaderSource({ - * defines : ['WHITE'], - * sources : ['void main() { \n#ifdef WHITE\n gl_FragColor = vec4(1.0); \n#else\n gl_FragColor = vec4(0.0); \n#endif\n }'] - * }); - * - * // 2. Modify a fragment shader for picking - * var source = new Cesium.ShaderSource({ - * sources : ['void main() { gl_FragColor = vec4(1.0); }'], - * pickColorQualifier : 'uniform' - * }); - * - * @private - */ - function ShaderSource(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var pickColorQualifier = options.pickColorQualifier; + /** + * Gets or sets {@link NearFarScalar} Property specifying the translucency of the point based on the distance from the camera. + * A point's translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the points's translucency remains clamped to the nearest bound. + * @memberof PointGraphics.prototype + * @type {Property} + */ + translucencyByDistance : createPropertyDescriptor('translucencyByDistance'), - if (defined(pickColorQualifier) && pickColorQualifier !== 'uniform' && pickColorQualifier !== 'varying') { - throw new DeveloperError('options.pickColorQualifier must be \'uniform\' or \'varying\'.'); - } - - this.defines = defined(options.defines) ? options.defines.slice(0) : []; - this.sources = defined(options.sources) ? options.sources.slice(0) : []; - this.pickColorQualifier = pickColorQualifier; - this.includeBuiltIns = defaultValue(options.includeBuiltIns, true); - } + /** + * Gets or sets the Property specifying the {@link HeightReference}. + * @memberof PointGraphics.prototype + * @type {Property} + * @default HeightReference.NONE + */ + heightReference : createPropertyDescriptor('heightReference'), - ShaderSource.prototype.clone = function() { - return new ShaderSource({ - sources : this.sources, - defines : this.defines, - pickColorQuantifier : this.pickColorQualifier, - includeBuiltIns : this.includeBuiltIns - }); - }; + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this point will be displayed. + * @memberof PointGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), - ShaderSource.replaceMain = function(source, renamedMain) { - renamedMain = 'void ' + renamedMain + '()'; - return source.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, renamedMain); - }; + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof PointGraphics.prototype + * @type {Property} + */ + disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') + }); /** - * Create a single string containing the full, combined vertex shader with all dependencies and defines. - * - * @param {Context} context The current rendering context + * Duplicates this instance. * - * @returns {String} The combined shader string. + * @param {PointGraphics} [result] The object onto which to store the result. + * @returns {PointGraphics} The modified result parameter or a new instance if one was not provided. */ - ShaderSource.prototype.createCombinedVertexShader = function(context) { - return combineShader(this, false, context); + PointGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new PointGraphics(this); + } + result.color = this.color; + result.pixelSize = this.pixelSize; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.show = this.show; + result.scaleByDistance = this.scaleByDistance; + result.translucencyByDistance = this._translucencyByDistance; + result.heightReference = this.heightReference; + result.distanceDisplayCondition = this.distanceDisplayCondition; + result.disableDepthTestDistance = this.disableDepthTestDistance; + return result; }; /** - * Create a single string containing the full, combined fragment shader with all dependencies and defines. - * - * @param {Context} context The current rendering context + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. * - * @returns {String} The combined shader string. + * @param {PointGraphics} source The object to be merged into this object. */ - ShaderSource.prototype.createCombinedFragmentShader = function(context) { - return combineShader(this, true, context); + PointGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.color = defaultValue(this.color, source.color); + this.pixelSize = defaultValue(this.pixelSize, source.pixelSize); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.show = defaultValue(this.show, source.show); + this.scaleByDistance = defaultValue(this.scaleByDistance, source.scaleByDistance); + this.translucencyByDistance = defaultValue(this._translucencyByDistance, source.translucencyByDistance); + this.heightReference = defaultValue(this.heightReference, source.heightReference); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this.disableDepthTestDistance = defaultValue(this.disableDepthTestDistance, source.disableDepthTestDistance); }; + return PointGraphics; +}); + +define('DataSources/PolygonGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { + 'use strict'; + /** - * For ShaderProgram testing - * @private + * Describes a polygon defined by an hierarchy of linear rings which make up the outer shape and any nested holes. + * The polygon conforms to the curvature of the globe and can be placed on the surface or + * at altitude and can optionally be extruded into a volume. + * + * @alias PolygonGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.hierarchy] A Property specifying the {@link PolygonHierarchy}. + * @param {Property} [options.height=0] A numeric Property specifying the altitude of the polygon relative to the ellipsoid surface. + * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the polygon's extruded face relative to the ellipsoid surface. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polygon. + * @param {Property} [options.fill=true] A boolean Property specifying whether the polygon is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the polygon. + * @param {Property} [options.outline=false] A boolean Property specifying whether the polygon is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the polygon texture counter-clockwise from north. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. + * @param {Property} [options.perPositionHeight=false] A boolean specifying whether or not the the height of each position is used. + * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. + * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polygon will be displayed. + * + * @see Entity + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo} */ - ShaderSource._czmBuiltinsAndUniforms = {}; + function PolygonGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._hierarchy = undefined; + this._hierarchySubscription = undefined; + this._height = undefined; + this._heightSubscription = undefined; + this._extrudedHeight = undefined; + this._extrudedHeightSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._stRotation = undefined; + this._stRotationSubscription = undefined; + this._perPositionHeight = undefined; + this._perPositionHeightSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._definitionChanged = new Event(); + this._closeTop = undefined; + this._closeTopSubscription = undefined; + this._closeBottom = undefined; + this._closeBottomSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; - // combine automatic uniforms and Cesium built-ins - for ( var builtinName in CzmBuiltins) { - if (CzmBuiltins.hasOwnProperty(builtinName)) { - ShaderSource._czmBuiltinsAndUniforms[builtinName] = CzmBuiltins[builtinName]; - } + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); } - for ( var uniformName in AutomaticUniforms) { - if (AutomaticUniforms.hasOwnProperty(uniformName)) { - var uniform = AutomaticUniforms[uniformName]; - if (typeof uniform.getDeclaration === 'function') { - ShaderSource._czmBuiltinsAndUniforms[uniformName] = uniform.getDeclaration(uniformName); + + defineProperties(PolygonGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof PolygonGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - } - } + }, - ShaderSource.createPickVertexShaderSource = function(vertexShaderSource) { - var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_old_main'); - var pickMain = 'attribute vec4 pickColor; \n' + - 'varying vec4 czm_pickColor; \n' + - 'void main() \n' + - '{ \n' + - ' czm_old_main(); \n' + - ' czm_pickColor = pickColor; \n' + - '}'; + /** + * Gets or sets the boolean Property specifying the visibility of the polygon. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - return renamedVS + '\n' + pickMain; - }; + /** + * Gets or sets the Property specifying the material used to fill the polygon. + * @memberof PolygonGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - ShaderSource.createPickFragmentShaderSource = function(fragmentShaderSource, pickColorQualifier) { - var renamedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_old_main'); - var pickMain = pickColorQualifier + ' vec4 czm_pickColor; \n' + - 'void main() \n' + - '{ \n' + - ' czm_old_main(); \n' + - ' if (gl_FragColor.a == 0.0) { \n' + - ' discard; \n' + - ' } \n' + - ' gl_FragColor = czm_pickColor; \n' + - '}'; + /** + * Gets or sets the Property specifying the {@link PolygonHierarchy}. + * @memberof PolygonGraphics.prototype + * @type {Property} + */ + hierarchy : createPropertyDescriptor('hierarchy'), - return renamedFS + '\n' + pickMain; - }; + /** + * Gets or sets the numeric Property specifying the constant altitude of the polygon. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default 0.0 + */ + height : createPropertyDescriptor('height'), - ShaderSource.findVarying = function(shaderSource, names) { - var sources = shaderSource.sources; + /** + * Gets or sets the numeric Property specifying the altitude of the polygon extrusion. + * If {@link PolygonGraphics#perPositionHeight} is false, the volume starts at {@link PolygonGraphics#height} and ends at this altitude. + * If {@link PolygonGraphics#perPositionHeight} is true, the volume starts at the height of each {@link PolygonGraphics#hierarchy} position and ends at this altitude. + * @memberof PolygonGraphics.prototype + * @type {Property} + */ + extrudedHeight : createPropertyDescriptor('extrudedHeight'), - var namesLength = names.length; - for (var i = 0; i < namesLength; ++i) { - var name = names[i]; + /** + * Gets or sets the numeric Property specifying the angular distance between points on the polygon. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default {CesiumMath.RADIANS_PER_DEGREE} + */ + granularity : createPropertyDescriptor('granularity'), - var sourcesLength = sources.length; - for (var j = 0; j < sourcesLength; ++j) { - if (sources[j].indexOf(name) !== -1) { - return name; - } - } - } + /** + * Gets or sets the numeric property specifying the rotation of the polygon texture counter-clockwise from north. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default 0 + */ + stRotation : createPropertyDescriptor('stRotation'), - return undefined; - }; + /** + * Gets or sets the boolean Property specifying whether the polygon is filled with the provided material. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), - var normalVaryingNames = ['v_normalEC', 'v_normal']; + /** + * Gets or sets the Property specifying whether the polygon is outlined. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), - ShaderSource.findNormalVarying = function(shaderSource) { - return ShaderSource.findVarying(shaderSource, normalVaryingNames); + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), + + /** + * Gets or sets the boolean specifying whether or not the the height of each position is used. + * If true, the shape will have non-uniform altitude defined by the height of each {@link PolygonGraphics#hierarchy} position. + * If false, the shape will have a constant altitude as specified by {@link PolygonGraphics#height}. + * @memberof PolygonGraphics.prototype + * @type {Property} + */ + perPositionHeight : createPropertyDescriptor('perPositionHeight'), + + /** + * Gets or sets a boolean specifying whether or not the top of an extruded polygon is included. + * @memberof PolygonGraphics.prototype + * @type {Property} + */ + closeTop : createPropertyDescriptor('closeTop'), + + /** + * Gets or sets a boolean specifying whether or not the bottom of an extruded polygon is included. + * @memberof PolygonGraphics.prototype + * @type {Property} + */ + closeBottom : createPropertyDescriptor('closeBottom'), + + /** + * Get or sets the enum Property specifying whether the polygon + * casts or receives shadows from each light source. + * @memberof PolygonGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), + + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this polygon will be displayed. + * @memberof PolygonGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); + + /** + * Duplicates this instance. + * + * @param {PolygonGraphics} [result] The object onto which to store the result. + * @returns {PolygonGraphics} The modified result parameter or a new instance if one was not provided. + */ + PolygonGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new PolygonGraphics(this); + } + result.show = this.show; + result.material = this.material; + result.hierarchy = this.hierarchy; + result.height = this.height; + result.extrudedHeight = this.extrudedHeight; + result.granularity = this.granularity; + result.stRotation = this.stRotation; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.perPositionHeight = this.perPositionHeight; + result.closeTop = this.closeTop; + result.closeBottom = this.closeBottom; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; }; - var positionVaryingNames = ['v_positionEC']; - - ShaderSource.findPositionVarying = function(shaderSource) { - return ShaderSource.findVarying(shaderSource, positionVaryingNames); + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {PolygonGraphics} source The object to be merged into this object. + */ + PolygonGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.hierarchy = defaultValue(this.hierarchy, source.hierarchy); + this.height = defaultValue(this.height, source.height); + this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); + this.granularity = defaultValue(this.granularity, source.granularity); + this.stRotation = defaultValue(this.stRotation, source.stRotation); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.perPositionHeight = defaultValue(this.perPositionHeight, source.perPositionHeight); + this.closeTop = defaultValue(this.closeTop, source.closeTop); + this.closeBottom = defaultValue(this.closeBottom, source.closeBottom); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); }; - return ShaderSource; + return PolygonGraphics; }); -define('Renderer/Buffer',[ - '../Core/Check', +define('DataSources/PolylineGraphics',[ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/IndexDatatype', - '../Core/WebGLConstants', - './BufferUsage' + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' ], function( - Check, defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - IndexDatatype, - WebGLConstants, - BufferUsage) { + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; /** - * @private - */ - function Buffer(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - Check.defined('options.context', options.context); - - if (!defined(options.typedArray) && !defined(options.sizeInBytes)) { - throw new DeveloperError('Either options.sizeInBytes or options.typedArray is required.'); - } - - if (defined(options.typedArray) && defined(options.sizeInBytes)) { - throw new DeveloperError('Cannot pass in both options.sizeInBytes and options.typedArray.'); - } - - if (defined(options.typedArray)) { - Check.typeOf.object('options.typedArray', options.typedArray); - Check.typeOf.number('options.typedArray.byteLength', options.typedArray.byteLength); - } - - if (!BufferUsage.validate(options.usage)) { - throw new DeveloperError('usage is invalid.'); - } - - var gl = options.context._gl; - var bufferTarget = options.bufferTarget; - var typedArray = options.typedArray; - var sizeInBytes = options.sizeInBytes; - var usage = options.usage; - var hasArray = defined(typedArray); - - if (hasArray) { - sizeInBytes = typedArray.byteLength; - } - - Check.typeOf.number.greaterThan('sizeInBytes', sizeInBytes, 0); - - var buffer = gl.createBuffer(); - gl.bindBuffer(bufferTarget, buffer); - gl.bufferData(bufferTarget, hasArray ? typedArray : sizeInBytes, usage); - gl.bindBuffer(bufferTarget, null); - - this._gl = gl; - this._webgl2 = options.context._webgl2; - this._bufferTarget = bufferTarget; - this._sizeInBytes = sizeInBytes; - this._usage = usage; - this._buffer = buffer; - this.vertexArrayDestroyable = true; - } - - /** - * Creates a vertex buffer, which contains untyped vertex data in GPU-controlled memory. - * <br /><br /> - * A vertex array defines the actual makeup of a vertex, e.g., positions, normals, texture coordinates, - * etc., by interpreting the raw data in one or more vertex buffers. - * - * @param {Object} options An object containing the following properties: - * @param {Context} options.context The context in which to create the buffer - * @param {ArrayBufferView} [options.typedArray] A typed array containing the data to copy to the buffer. - * @param {Number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. - * @param {BufferUsage} options.usage Specifies the expected usage pattern of the buffer. On some GL implementations, this can significantly affect performance. See {@link BufferUsage}. - * @returns {VertexBuffer} The vertex buffer, ready to be attached to a vertex array. - * - * @exception {DeveloperError} Must specify either <options.typedArray> or <options.sizeInBytes>, but not both. - * @exception {DeveloperError} The buffer size must be greater than zero. - * @exception {DeveloperError} Invalid <code>usage</code>. - * - * - * @example - * // Example 1. Create a dynamic vertex buffer 16 bytes in size. - * var buffer = Buffer.createVertexBuffer({ - * context : context, - * sizeInBytes : 16, - * usage : BufferUsage.DYNAMIC_DRAW - * }); - * - * @example - * // Example 2. Create a dynamic vertex buffer from three floating-point values. - * // The data copied to the vertex buffer is considered raw bytes until it is - * // interpreted as vertices using a vertex array. - * var positionBuffer = buffer.createVertexBuffer({ - * context : context, - * typedArray : new Float32Array([0, 0, 0]), - * usage : BufferUsage.STATIC_DRAW - * }); - * - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenBuffer.xml|glGenBuffer} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindBuffer.xml|glBindBuffer} with <code>ARRAY_BUFFER</code> - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBufferData.xml|glBufferData} with <code>ARRAY_BUFFER</code> - */ - Buffer.createVertexBuffer = function(options) { - Check.defined('options.context', options.context); - - return new Buffer({ - context: options.context, - bufferTarget: WebGLConstants.ARRAY_BUFFER, - typedArray: options.typedArray, - sizeInBytes: options.sizeInBytes, - usage: options.usage - }); - }; - - /** - * Creates an index buffer, which contains typed indices in GPU-controlled memory. - * <br /><br /> - * An index buffer can be attached to a vertex array to select vertices for rendering. - * <code>Context.draw</code> can render using the entire index buffer or a subset - * of the index buffer defined by an offset and count. - * - * @param {Object} options An object containing the following properties: - * @param {Context} options.context The context in which to create the buffer - * @param {ArrayBufferView} [options.typedArray] A typed array containing the data to copy to the buffer. - * @param {Number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. - * @param {BufferUsage} options.usage Specifies the expected usage pattern of the buffer. On some GL implementations, this can significantly affect performance. See {@link BufferUsage}. - * @param {IndexDatatype} options.indexDatatype The datatype of indices in the buffer. - * @returns {IndexBuffer} The index buffer, ready to be attached to a vertex array. - * - * @exception {DeveloperError} Must specify either <options.typedArray> or <options.sizeInBytes>, but not both. - * @exception {DeveloperError} IndexDatatype.UNSIGNED_INT requires OES_element_index_uint, which is not supported on this system. Check context.elementIndexUint. - * @exception {DeveloperError} The size in bytes must be greater than zero. - * @exception {DeveloperError} Invalid <code>usage</code>. - * @exception {DeveloperError} Invalid <code>indexDatatype</code>. - * + * Describes a polyline defined as a line strip. The first two positions define a line segment, + * and each additional position defines a line segment from the previous position. The segments + * can be linear connected points or great arcs. * - * @example - * // Example 1. Create a stream index buffer of unsigned shorts that is - * // 16 bytes in size. - * var buffer = Buffer.createIndexBuffer({ - * context : context, - * sizeInBytes : 16, - * usage : BufferUsage.STREAM_DRAW, - * indexDatatype : IndexDatatype.UNSIGNED_SHORT - * }); + * @alias PolylineGraphics + * @constructor * - * @example - * // Example 2. Create a static index buffer containing three unsigned shorts. - * var buffer = Buffer.createIndexBuffer({ - * context : context, - * typedArray : new Uint16Array([0, 1, 2]), - * usage : BufferUsage.STATIC_DRAW, - * indexDatatype : IndexDatatype.UNSIGNED_SHORT - * }); + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions that define the line strip. + * @param {Property} [options.followSurface=true] A boolean Property specifying whether the line segments should be great arcs or linearly connected. + * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polyline. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the polyline. + * @param {MaterialProperty} [options.depthFailMaterial] A property specifiying the material used to draw the polyline when it is below the terrain. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if followSurface is true. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polyline casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polyline will be displayed. * - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenBuffer.xml|glGenBuffer} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindBuffer.xml|glBindBuffer} with <code>ELEMENT_ARRAY_BUFFER</code> - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBufferData.xml|glBufferData} with <code>ELEMENT_ARRAY_BUFFER</code> + * @see Entity + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo} */ - Buffer.createIndexBuffer = function(options) { - Check.defined('options.context', options.context); - - if (!IndexDatatype.validate(options.indexDatatype)) { - throw new DeveloperError('Invalid indexDatatype.'); - } - - if (options.indexDatatype === IndexDatatype.UNSIGNED_INT && !options.context.elementIndexUint) { - throw new DeveloperError('IndexDatatype.UNSIGNED_INT requires OES_element_index_uint, which is not supported on this system. Check context.elementIndexUint.'); - } - - var context = options.context; - var indexDatatype = options.indexDatatype; - - var bytesPerIndex = IndexDatatype.getSizeInBytes(indexDatatype); - var buffer = new Buffer({ - context : context, - bufferTarget : WebGLConstants.ELEMENT_ARRAY_BUFFER, - typedArray : options.typedArray, - sizeInBytes : options.sizeInBytes, - usage : options.usage - }); - - var numberOfIndices = buffer.sizeInBytes / bytesPerIndex; - - defineProperties(buffer, { - indexDatatype: { - get : function() { - return indexDatatype; - } - }, - bytesPerIndex : { - get : function() { - return bytesPerIndex; - } - }, - numberOfIndices : { - get : function() { - return numberOfIndices; - } - } - }); + function PolylineGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._depthFailMaterial = undefined; + this._depthFailMaterialSubscription = undefined; + this._positions = undefined; + this._positionsSubscription = undefined; + this._followSurface = undefined; + this._followSurfaceSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._widthSubscription = undefined; + this._width = undefined; + this._widthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); - return buffer; - }; + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } - defineProperties(Buffer.prototype, { - sizeInBytes : { + defineProperties(PolylineGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof PolylineGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { get : function() { - return this._sizeInBytes; + return this._definitionChanged; } }, - usage: { - get : function() { - return this._usage; - } - } - }); + /** + * Gets or sets the boolean Property specifying the visibility of the polyline. + * @memberof PolylineGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - Buffer.prototype._getBuffer = function() { - return this._buffer; - }; + /** + * Gets or sets the Property specifying the material used to draw the polyline. + * @memberof PolylineGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - Buffer.prototype.copyFromArrayView = function(arrayView, offsetInBytes) { - offsetInBytes = defaultValue(offsetInBytes, 0); + /** + * Gets or sets the Property specifying the material used to draw the polyline when it fails the depth test. + * <p> + * Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, + * there may be artifacts. + * </p> + * @memberof PolylineGraphics.prototype + * @type {MaterialProperty} + * @default undefined + */ + depthFailMaterial : createMaterialPropertyDescriptor('depthFailMaterial'), - Check.defined('arrayView', arrayView); - Check.typeOf.number.lessThanOrEquals('offsetInBytes + arrayView.byteLength', offsetInBytes + arrayView.byteLength, this._sizeInBytes); - - var gl = this._gl; - var target = this._bufferTarget; - gl.bindBuffer(target, this._buffer); - gl.bufferSubData(target, offsetInBytes, arrayView); - gl.bindBuffer(target, null); - }; + /** + * Gets or sets the Property specifying the array of {@link Cartesian3} + * positions that define the line strip. + * @memberof PolylineGraphics.prototype + * @type {Property} + */ + positions : createPropertyDescriptor('positions'), - Buffer.prototype.copyFromBuffer = function(readBuffer, readOffset, writeOffset, sizeInBytes) { - if (!this._webgl2) { - throw new DeveloperError('A WebGL 2 context is required.'); - } - if (!defined(readBuffer)) { - throw new DeveloperError('readBuffer must be defined.'); - } - if (!defined(sizeInBytes) || sizeInBytes <= 0) { - throw new DeveloperError('sizeInBytes must be defined and be greater than zero.'); - } - if (!defined(readOffset) || readOffset < 0 || readOffset + sizeInBytes > readBuffer._sizeInBytes) { - throw new DeveloperError('readOffset must be greater than or equal to zero and readOffset + sizeInBytes must be less than of equal to readBuffer.sizeInBytes.'); - } - if (!defined(writeOffset) || writeOffset < 0 || writeOffset + sizeInBytes > this._sizeInBytes) { - throw new DeveloperError('writeOffset must be greater than or equal to zero and writeOffset + sizeInBytes must be less than of equal to this.sizeInBytes.'); - } - if (this._buffer === readBuffer._buffer && ((writeOffset >= readOffset && writeOffset < readOffset + sizeInBytes) || (readOffset > writeOffset && readOffset < writeOffset + sizeInBytes))) { - throw new DeveloperError('When readBuffer is equal to this, the ranges [readOffset + sizeInBytes) and [writeOffset, writeOffset + sizeInBytes) must not overlap.'); - } - if ((this._bufferTarget === WebGLConstants.ELEMENT_ARRAY_BUFFER && readBuffer._bufferTarget !== WebGLConstants.ELEMENT_ARRAY_BUFFER) || - (this._bufferTarget !== WebGLConstants.ELEMENT_ARRAY_BUFFER && readBuffer._bufferTarget === WebGLConstants.ELEMENT_ARRAY_BUFFER)) { - throw new DeveloperError('Can not copy an index buffer into another buffer type.'); - } - - var readTarget = WebGLConstants.COPY_READ_BUFFER; - var writeTarget = WebGLConstants.COPY_WRITE_BUFFER; + /** + * Gets or sets the numeric Property specifying the width in pixels. + * @memberof PolylineGraphics.prototype + * @type {Property} + * @default 1.0 + */ + width : createPropertyDescriptor('width'), - var gl = this._gl; - gl.bindBuffer(writeTarget, this._buffer); - gl.bindBuffer(readTarget, readBuffer._buffer); - gl.copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, sizeInBytes); - gl.bindBuffer(writeTarget, null); - gl.bindBuffer(readTarget, null); - }; + /** + * Gets or sets the boolean Property specifying whether the line segments + * should be great arcs or linearly connected. + * @memberof PolylineGraphics.prototype + * @type {Property} + * @default true + */ + followSurface : createPropertyDescriptor('followSurface'), - Buffer.prototype.getBufferData = function(arrayView, sourceOffset, destinationOffset, length) { - sourceOffset = defaultValue(sourceOffset, 0); - destinationOffset = defaultValue(destinationOffset, 0); + /** + * Gets or sets the numeric Property specifying the angular distance between each latitude and longitude if followSurface is true. + * @memberof PolylineGraphics.prototype + * @type {Property} + * @default Cesium.Math.RADIANS_PER_DEGREE + */ + granularity : createPropertyDescriptor('granularity'), - if (!this._webgl2) { - throw new DeveloperError('A WebGL 2 context is required.'); - } - if (!defined(arrayView)) { - throw new DeveloperError('arrayView is required.'); - } + /** + * Get or sets the enum Property specifying whether the polyline + * casts or receives shadows from each light source. + * @memberof PolylineGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), - var copyLength; - var elementSize; - var arrayLength = arrayView.byteLength; - if (!defined(length)) { - if (defined(arrayLength)) { - copyLength = arrayLength - destinationOffset; - elementSize = 1; - } else { - arrayLength = arrayView.length; - copyLength = arrayLength - destinationOffset; - elementSize = arrayView.BYTES_PER_ELEMENT; - } - } else { - copyLength = length; - if (defined(arrayLength)) { - elementSize = 1; - } else { - arrayLength = arrayView.length; - elementSize = arrayView.BYTES_PER_ELEMENT; - } - } + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this polyline will be displayed. + * @memberof PolylineGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); - if (destinationOffset < 0 || destinationOffset > arrayLength) { - throw new DeveloperError('destinationOffset must be greater than zero and less than the arrayView length.'); - } - if (destinationOffset + copyLength > arrayLength) { - throw new DeveloperError('destinationOffset + length must be less than or equal to the arrayViewLength.'); - } - if (sourceOffset < 0 || sourceOffset > this._sizeInBytes) { - throw new DeveloperError('sourceOffset must be greater than zero and less than the buffers size.'); - } - if (sourceOffset + copyLength * elementSize > this._sizeInBytes) { - throw new DeveloperError('sourceOffset + length must be less than the buffers size.'); + /** + * Duplicates this instance. + * + * @param {PolylineGraphics} [result] The object onto which to store the result. + * @returns {PolylineGraphics} The modified result parameter or a new instance if one was not provided. + */ + PolylineGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new PolylineGraphics(this); } - - var gl = this._gl; - var target = WebGLConstants.COPY_READ_BUFFER; - gl.bindBuffer(target, this._buffer); - gl.getBufferSubData(target, sourceOffset, arrayView, destinationOffset, length); - gl.bindBuffer(target, null); - }; - - Buffer.prototype.isDestroyed = function() { - return false; + result.show = this.show; + result.material = this.material; + result.depthFailMaterial = this.depthFailMaterial; + result.positions = this.positions; + result.width = this.width; + result.followSurface = this.followSurface; + result.granularity = this.granularity; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; }; - Buffer.prototype.destroy = function() { - this._gl.deleteBuffer(this._buffer); - return destroyObject(this); + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {PolylineGraphics} source The object to be merged into this object. + */ + PolylineGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.depthFailMaterial = defaultValue(this.depthFailMaterial, source.depthFailMaterial); + this.positions = defaultValue(this.positions, source.positions); + this.width = defaultValue(this.width, source.width); + this.followSurface = defaultValue(this.followSurface, source.followSurface); + this.granularity = defaultValue(this.granularity, source.granularity); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); }; - return Buffer; + return PolylineGraphics; }); -define('Renderer/VertexArray',[ - '../Core/Check', - '../Core/ComponentDatatype', +define('DataSources/PolylineVolumeGraphics',[ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Geometry', - '../Core/IndexDatatype', - '../Core/Math', - '../Core/RuntimeError', - './Buffer', - './BufferUsage', - './ContextLimits' + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' ], function( - Check, - ComponentDatatype, defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - Geometry, - IndexDatatype, - CesiumMath, - RuntimeError, - Buffer, - BufferUsage, - ContextLimits) { + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { 'use strict'; - function addAttribute(attributes, attribute, index, context) { - var hasVertexBuffer = defined(attribute.vertexBuffer); - var hasValue = defined(attribute.value); - var componentsPerAttribute = attribute.value ? attribute.value.length : attribute.componentsPerAttribute; + /** + * Describes a polyline volume defined as a line strip and corresponding two dimensional shape which is extruded along it. + * The resulting volume conforms to the curvature of the globe. + * + * @alias PolylineVolumeGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions which define the line strip. + * @param {Property} [options.shape] A Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded. + * @param {Property} [options.cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the volume. + * @param {Property} [options.fill=true] A boolean Property specifying whether the volume is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the volume. + * @param {Property} [options.outline=false] A boolean Property specifying whether the volume is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the volume casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this volume will be displayed. + * + * @see Entity + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo} + */ + function PolylineVolumeGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._positions = undefined; + this._positionsSubscription = undefined; + this._shape = undefined; + this._shapeSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._cornerType = undefined; + this._cornerTypeSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubsription = undefined; + this._definitionChanged = new Event(); - if (!hasVertexBuffer && !hasValue) { - throw new DeveloperError('attribute must have a vertexBuffer or a value.'); - } - if (hasVertexBuffer && hasValue) { - throw new DeveloperError('attribute cannot have both a vertexBuffer and a value. It must have either a vertexBuffer property defining per-vertex data or a value property defining data for all vertices.'); - } - if ((componentsPerAttribute !== 1) && - (componentsPerAttribute !== 2) && - (componentsPerAttribute !== 3) && - (componentsPerAttribute !== 4)) { - if (hasValue) { - throw new DeveloperError('attribute.value.length must be in the range [1, 4].'); - } + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } - throw new DeveloperError('attribute.componentsPerAttribute must be in the range [1, 4].'); - } - if (defined(attribute.componentDatatype) && !ComponentDatatype.validate(attribute.componentDatatype)) { - throw new DeveloperError('attribute must have a valid componentDatatype or not specify it.'); - } - if (defined(attribute.strideInBytes) && (attribute.strideInBytes > 255)) { - // WebGL limit. Not in GL ES. - throw new DeveloperError('attribute must have a strideInBytes less than or equal to 255 or not specify it.'); - } - if (defined(attribute.instanceDivisor) && (attribute.instanceDivisor > 0) && !context.instancedArrays) { - throw new DeveloperError('instanced arrays is not supported'); - } - if (defined(attribute.instanceDivisor) && (attribute.instanceDivisor < 0)) { - throw new DeveloperError('attribute must have an instanceDivisor greater than or equal to zero'); - } - if (defined(attribute.instanceDivisor) && hasValue) { - throw new DeveloperError('attribute cannot have have an instanceDivisor if it is not backed by a buffer'); - } - if (defined(attribute.instanceDivisor) && (attribute.instanceDivisor > 0) && (attribute.index === 0)) { - throw new DeveloperError('attribute zero cannot have an instanceDivisor greater than 0'); - } - - // Shallow copy the attribute; we do not want to copy the vertex buffer. - var attr = { - index : defaultValue(attribute.index, index), - enabled : defaultValue(attribute.enabled, true), - vertexBuffer : attribute.vertexBuffer, - value : hasValue ? attribute.value.slice(0) : undefined, - componentsPerAttribute : componentsPerAttribute, - componentDatatype : defaultValue(attribute.componentDatatype, ComponentDatatype.FLOAT), - normalize : defaultValue(attribute.normalize, false), - offsetInBytes : defaultValue(attribute.offsetInBytes, 0), - strideInBytes : defaultValue(attribute.strideInBytes, 0), - instanceDivisor : defaultValue(attribute.instanceDivisor, 0) - }; + defineProperties(PolylineVolumeGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof PolylineVolumeGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, - if (hasVertexBuffer) { - // Common case: vertex buffer for per-vertex data - attr.vertexAttrib = function(gl) { - var index = this.index; - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer._getBuffer()); - gl.vertexAttribPointer(index, this.componentsPerAttribute, this.componentDatatype, this.normalize, this.strideInBytes, this.offsetInBytes); - gl.enableVertexAttribArray(index); - if (this.instanceDivisor > 0) { - context.glVertexAttribDivisor(index, this.instanceDivisor); - context._vertexAttribDivisors[index] = this.instanceDivisor; - context._previousDrawInstanced = true; - } - }; + /** + * Gets or sets the boolean Property specifying the visibility of the volume. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - attr.disableVertexAttribArray = function(gl) { - gl.disableVertexAttribArray(this.index); - if (this.instanceDivisor > 0) { - context.glVertexAttribDivisor(index, 0); - } - }; - } else { - // Less common case: value array for the same data for each vertex - switch (attr.componentsPerAttribute) { - case 1: - attr.vertexAttrib = function(gl) { - gl.vertexAttrib1fv(this.index, this.value); - }; - break; - case 2: - attr.vertexAttrib = function(gl) { - gl.vertexAttrib2fv(this.index, this.value); - }; - break; - case 3: - attr.vertexAttrib = function(gl) { - gl.vertexAttrib3fv(this.index, this.value); - }; - break; - case 4: - attr.vertexAttrib = function(gl) { - gl.vertexAttrib4fv(this.index, this.value); - }; - break; - } + /** + * Gets or sets the Property specifying the material used to fill the volume. + * @memberof PolylineVolumeGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - attr.disableVertexAttribArray = function(gl) { - }; - } + /** + * Gets or sets the Property specifying the array of {@link Cartesian3} positions which define the line strip. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + */ + positions : createPropertyDescriptor('positions'), - attributes.push(attr); - } + /** + * Gets or sets the Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + */ + shape : createPropertyDescriptor('shape'), - function bind(gl, attributes, indexBuffer) { - for ( var i = 0; i < attributes.length; ++i) { - var attribute = attributes[i]; - if (attribute.enabled) { - attribute.vertexAttrib(gl); - } - } + /** + * Gets or sets the numeric Property specifying the angular distance between points on the volume. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default {CesiumMath.RADIANS_PER_DEGREE} + */ + granularity : createPropertyDescriptor('granularity'), - if (defined(indexBuffer)) { - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer._getBuffer()); - } - } + /** + * Gets or sets the boolean Property specifying whether the volume is filled with the provided material. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), - /** - * Creates a vertex array, which defines the attributes making up a vertex, and contains an optional index buffer - * to select vertices for rendering. Attributes are defined using object literals as shown in Example 1 below. - * - * @param {Object} options Object with the following properties: - * @param {Context} options.context The context in which the VertexArray gets created. - * @param {Object[]} options.attributes An array of attributes. - * @param {IndexBuffer} [options.indexBuffer] An optional index buffer. - * - * @returns {VertexArray} The vertex array, ready for use with drawing. - * - * @exception {DeveloperError} Attribute must have a <code>vertexBuffer</code>. - * @exception {DeveloperError} Attribute must have a <code>componentsPerAttribute</code>. - * @exception {DeveloperError} Attribute must have a valid <code>componentDatatype</code> or not specify it. - * @exception {DeveloperError} Attribute must have a <code>strideInBytes</code> less than or equal to 255 or not specify it. - * @exception {DeveloperError} Index n is used by more than one attribute. - * - * - * @example - * // Example 1. Create a vertex array with vertices made up of three floating point - * // values, e.g., a position, from a single vertex buffer. No index buffer is used. - * var positionBuffer = Buffer.createVertexBuffer({ - * context : context, - * sizeInBytes : 12, - * usage : BufferUsage.STATIC_DRAW - * }); - * var attributes = [ - * { - * index : 0, - * enabled : true, - * vertexBuffer : positionBuffer, - * componentsPerAttribute : 3, - * componentDatatype : ComponentDatatype.FLOAT, - * normalize : false, - * offsetInBytes : 0, - * strideInBytes : 0 // tightly packed - * instanceDivisor : 0 // not instanced - * } - * ]; - * var va = new VertexArray({ - * context : context, - * attributes : attributes - * }); - * - * @example - * // Example 2. Create a vertex array with vertices from two different vertex buffers. - * // Each vertex has a three-component position and three-component normal. - * var positionBuffer = Buffer.createVertexBuffer({ - * context : context, - * sizeInBytes : 12, - * usage : BufferUsage.STATIC_DRAW - * }); - * var normalBuffer = Buffer.createVertexBuffer({ - * context : context, - * sizeInBytes : 12, - * usage : BufferUsage.STATIC_DRAW - * }); - * var attributes = [ - * { - * index : 0, - * vertexBuffer : positionBuffer, - * componentsPerAttribute : 3, - * componentDatatype : ComponentDatatype.FLOAT - * }, - * { - * index : 1, - * vertexBuffer : normalBuffer, - * componentsPerAttribute : 3, - * componentDatatype : ComponentDatatype.FLOAT - * } - * ]; - * var va = new VertexArray({ - * context : context, - * attributes : attributes - * }); - * - * @example - * // Example 3. Creates the same vertex layout as Example 2 using a single - * // vertex buffer, instead of two. - * var buffer = Buffer.createVertexBuffer({ - * context : context, - * sizeInBytes : 24, - * usage : BufferUsage.STATIC_DRAW - * }); - * var attributes = [ - * { - * vertexBuffer : buffer, - * componentsPerAttribute : 3, - * componentDatatype : ComponentDatatype.FLOAT, - * offsetInBytes : 0, - * strideInBytes : 24 - * }, - * { - * vertexBuffer : buffer, - * componentsPerAttribute : 3, - * componentDatatype : ComponentDatatype.FLOAT, - * normalize : true, - * offsetInBytes : 12, - * strideInBytes : 24 - * } - * ]; - * var va = new VertexArray({ - * context : context, - * attributes : attributes - * }); - * - * @see Buffer#createVertexBuffer - * @see Buffer#createIndexBuffer - * @see Context#draw - * - * @private - */ - function VertexArray(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + /** + * Gets or sets the Property specifying whether the volume is outlined. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), - Check.defined('options.context', options.context); - Check.defined('options.attributes', options.attributes); - - var context = options.context; - var gl = context._gl; - var attributes = options.attributes; - var indexBuffer = options.indexBuffer; + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), - var i; - var vaAttributes = []; - var numberOfVertices = 1; // if every attribute is backed by a single value - var hasInstancedAttributes = false; - var hasConstantAttributes = false; + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), - var length = attributes.length; - for (i = 0; i < length; ++i) { - addAttribute(vaAttributes, attributes[i], i, context); - } + /** + * Gets or sets the {@link CornerType} Property specifying the style of the corners. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default CornerType.ROUNDED + */ + cornerType : createPropertyDescriptor('cornerType'), - length = vaAttributes.length; - for (i = 0; i < length; ++i) { - var attribute = vaAttributes[i]; + /** + * Get or sets the enum Property specifying whether the volume + * casts or receives shadows from each light source. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), - if (defined(attribute.vertexBuffer) && (attribute.instanceDivisor === 0)) { - // This assumes that each vertex buffer in the vertex array has the same number of vertices. - var bytes = attribute.strideInBytes || (attribute.componentsPerAttribute * ComponentDatatype.getSizeInBytes(attribute.componentDatatype)); - numberOfVertices = attribute.vertexBuffer.sizeInBytes / bytes; - break; - } - } + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this volume will be displayed. + * @memberof PolylineVolumeGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); - for (i = 0; i < length; ++i) { - if (vaAttributes[i].instanceDivisor > 0) { - hasInstancedAttributes = true; - } - if (defined(vaAttributes[i].value)) { - hasConstantAttributes = true; - } + /** + * Duplicates this instance. + * + * @param {PolylineVolumeGraphics} [result] The object onto which to store the result. + * @returns {PolylineVolumeGraphics} The modified result parameter or a new instance if one was not provided. + */ + PolylineVolumeGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new PolylineVolumeGraphics(this); } + result.show = this.show; + result.material = this.material; + result.positions = this.positions; + result.shape = this.shape; + result.granularity = this.granularity; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.cornerType = this.cornerType; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; - // Verify all attribute names are unique - var uniqueIndices = {}; - for (i = 0; i < length; ++i) { - var index = vaAttributes[i].index; - if (uniqueIndices[index]) { - throw new DeveloperError('Index ' + index + ' is used by more than one attribute.'); - } - uniqueIndices[index] = true; + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {PolylineVolumeGraphics} source The object to be merged into this object. + */ + PolylineVolumeGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); } - var vao; - - // Setup VAO if supported - if (context.vertexArrayObject) { - vao = context.glCreateVertexArray(); - context.glBindVertexArray(vao); - bind(gl, vaAttributes, indexBuffer); - context.glBindVertexArray(null); - } - - this._numberOfVertices = numberOfVertices; - this._hasInstancedAttributes = hasInstancedAttributes; - this._hasConstantAttributes = hasConstantAttributes; - this._context = context; - this._gl = gl; - this._vao = vao; - this._attributes = vaAttributes; - this._indexBuffer = indexBuffer; - } + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.positions = defaultValue(this.positions, source.positions); + this.shape = defaultValue(this.shape, source.shape); + this.granularity = defaultValue(this.granularity, source.granularity); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.cornerType = defaultValue(this.cornerType, source.cornerType); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; - function computeNumberOfVertices(attribute) { - return attribute.values.length / attribute.componentsPerAttribute; - } + return PolylineVolumeGraphics; +}); - function computeAttributeSizeInBytes(attribute) { - return ComponentDatatype.getSizeInBytes(attribute.componentDatatype) * attribute.componentsPerAttribute; - } +define('DataSources/RectangleGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { + 'use strict'; - function interleaveAttributes(attributes) { - var j; - var name; - var attribute; + /** + * Describes graphics for a {@link Rectangle}. + * The rectangle conforms to the curvature of the globe and can be placed on the surface or + * at altitude and can optionally be extruded into a volume. + * + * @alias RectangleGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.coordinates] The Property specifying the {@link Rectangle}. + * @param {Property} [options.height=0] A numeric Property specifying the altitude of the rectangle relative to the ellipsoid surface. + * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the rectangle's extruded face relative to the ellipsoid surface. + * @param {Property} [options.closeTop=true] A boolean Property specifying whether the rectangle has a top cover when extruded + * @param {Property} [options.closeBottom=true] A boolean Property specifying whether the rectangle has a bottom cover when extruded. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the rectangle. + * @param {Property} [options.fill=true] A boolean Property specifying whether the rectangle is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the rectangle. + * @param {Property} [options.outline=false] A boolean Property specifying whether the rectangle is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.rotation=0.0] A numeric property specifying the rotation of the rectangle clockwise from north. + * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the rectangle texture counter-clockwise from north. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the rectangle. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the rectangle casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this rectangle will be displayed. + * + * @see Entity + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo} + */ + function RectangleGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._coordinates = undefined; + this._coordinatesSubscription = undefined; + this._height = undefined; + this._heightSubscription = undefined; + this._extrudedHeight = undefined; + this._extrudedHeightSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._stRotation = undefined; + this._stRotationSubscription = undefined; + this._rotation = undefined; + this._rotationSubscription = undefined; + this._closeTop = undefined; + this._closeTopSubscription = undefined; + this._closeBottom = undefined; + this._closeBottomSubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distancedisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); - // Extract attribute names. - var names = []; - for (name in attributes) { - // Attribute needs to have per-vertex values; not a constant value for all vertices. - if (attributes.hasOwnProperty(name) && - defined(attributes[name]) && - defined(attributes[name].values)) { - names.push(name); + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } - if (attributes[name].componentDatatype === ComponentDatatype.DOUBLE) { - attributes[name].componentDatatype = ComponentDatatype.FLOAT; - attributes[name].values = ComponentDatatype.createTypedArray(ComponentDatatype.FLOAT, attributes[name].values); - } + defineProperties(RectangleGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof RectangleGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - } + }, - // Validation. Compute number of vertices. - var numberOfVertices; - var namesLength = names.length; + /** + * Gets or sets the boolean Property specifying the visibility of the rectangle. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - if (namesLength > 0) { - numberOfVertices = computeNumberOfVertices(attributes[names[0]]); + /** + * Gets or sets the Property specifying the {@link Rectangle}. + * @memberof RectangleGraphics.prototype + * @type {Property} + */ + coordinates : createPropertyDescriptor('coordinates'), - for (j = 1; j < namesLength; ++j) { - var currentNumberOfVertices = computeNumberOfVertices(attributes[names[j]]); + /** + * Gets or sets the Property specifying the material used to fill the rectangle. + * @memberof RectangleGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - if (currentNumberOfVertices !== numberOfVertices) { - throw new RuntimeError( - 'Each attribute list must have the same number of vertices. ' + - 'Attribute ' + names[j] + ' has a different number of vertices ' + - '(' + currentNumberOfVertices.toString() + ')' + - ' than attribute ' + names[0] + - ' (' + numberOfVertices.toString() + ').'); - } - } - } + /** + * Gets or sets the numeric Property specifying the altitude of the rectangle. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default 0.0 + */ + height : createPropertyDescriptor('height'), - // Sort attributes by the size of their components. From left to right, a vertex stores floats, shorts, and then bytes. - names.sort(function(left, right) { - return ComponentDatatype.getSizeInBytes(attributes[right].componentDatatype) - ComponentDatatype.getSizeInBytes(attributes[left].componentDatatype); - }); + /** + * Gets or sets the numeric Property specifying the altitude of the rectangle extrusion. + * Setting this property creates volume starting at height and ending at this altitude. + * @memberof RectangleGraphics.prototype + * @type {Property} + */ + extrudedHeight : createPropertyDescriptor('extrudedHeight'), - // Compute sizes and strides. - var vertexSizeInBytes = 0; - var offsetsInBytes = {}; + /** + * Gets or sets the numeric Property specifying the angular distance between points on the rectangle. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default {CesiumMath.RADIANS_PER_DEGREE} + */ + granularity : createPropertyDescriptor('granularity'), - for (j = 0; j < namesLength; ++j) { - name = names[j]; - attribute = attributes[name]; + /** + * Gets or sets the numeric property specifying the rotation of the rectangle texture counter-clockwise from north. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default 0 + */ + stRotation : createPropertyDescriptor('stRotation'), - offsetsInBytes[name] = vertexSizeInBytes; - vertexSizeInBytes += computeAttributeSizeInBytes(attribute); - } + /** + * Gets or sets the numeric property specifying the rotation of the rectangle clockwise from north. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default 0 + */ + rotation : createPropertyDescriptor('rotation'), - if (vertexSizeInBytes > 0) { - // Pad each vertex to be a multiple of the largest component datatype so each - // attribute can be addressed using typed arrays. - var maxComponentSizeInBytes = ComponentDatatype.getSizeInBytes(attributes[names[0]].componentDatatype); // Sorted large to small - var remainder = vertexSizeInBytes % maxComponentSizeInBytes; - if (remainder !== 0) { - vertexSizeInBytes += (maxComponentSizeInBytes - remainder); - } + /** + * Gets or sets the boolean Property specifying whether the rectangle is filled with the provided material. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), - // Total vertex buffer size in bytes, including per-vertex padding. - var vertexBufferSizeInBytes = numberOfVertices * vertexSizeInBytes; + /** + * Gets or sets the Property specifying whether the rectangle is outlined. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), - // Create array for interleaved vertices. Each attribute has a different view (pointer) into the array. - var buffer = new ArrayBuffer(vertexBufferSizeInBytes); - var views = {}; + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), - for (j = 0; j < namesLength; ++j) { - name = names[j]; - var sizeInBytes = ComponentDatatype.getSizeInBytes(attributes[name].componentDatatype); + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), - views[name] = { - pointer : ComponentDatatype.createTypedArray(attributes[name].componentDatatype, buffer), - index : offsetsInBytes[name] / sizeInBytes, // Offset in ComponentType - strideInComponentType : vertexSizeInBytes / sizeInBytes - }; - } + /** + * Gets or sets the boolean Property specifying whether the rectangle has a top cover when extruded. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default true + */ + closeTop : createPropertyDescriptor('closeTop'), - // Copy attributes into one interleaved array. - // PERFORMANCE_IDEA: Can we optimize these loops? - for (j = 0; j < numberOfVertices; ++j) { - for ( var n = 0; n < namesLength; ++n) { - name = names[n]; - attribute = attributes[name]; - var values = attribute.values; - var view = views[name]; - var pointer = view.pointer; + /** + * Gets or sets the boolean Property specifying whether the rectangle has a bottom cover when extruded. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default true + */ + closeBottom : createPropertyDescriptor('closeBottom'), - var numberOfComponents = attribute.componentsPerAttribute; - for ( var k = 0; k < numberOfComponents; ++k) { - pointer[view.index + k] = values[(j * numberOfComponents) + k]; - } + /** + * Get or sets the enum Property specifying whether the rectangle + * casts or receives shadows from each light source. + * @memberof RectangleGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), - view.index += view.strideInComponentType; - } - } + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this rectangle will be displayed. + * @memberof RectangleGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); - return { - buffer : buffer, - offsetsInBytes : offsetsInBytes, - vertexSizeInBytes : vertexSizeInBytes - }; + /** + * Duplicates this instance. + * + * @param {RectangleGraphics} [result] The object onto which to store the result. + * @returns {RectangleGraphics} The modified result parameter or a new instance if one was not provided. + */ + RectangleGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new RectangleGraphics(this); } - - // No attributes to interleave. - return undefined; - } + result.show = this.show; + result.coordinates = this.coordinates; + result.material = this.material; + result.height = this.height; + result.extrudedHeight = this.extrudedHeight; + result.granularity = this.granularity; + result.stRotation = this.stRotation; + result.rotation = this.rotation; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.closeTop = this.closeTop; + result.closeBottom = this.closeBottom; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; + }; /** - * Creates a vertex array from a geometry. A geometry contains vertex attributes and optional index data - * in system memory, whereas a vertex array contains vertex buffers and an optional index buffer in WebGL - * memory for use with rendering. - * <br /><br /> - * The <code>geometry</code> argument should use the standard layout like the geometry returned by {@link BoxGeometry}. - * <br /><br /> - * <code>options</code> can have four properties: - * <ul> - * <li><code>geometry</code>: The source geometry containing data used to create the vertex array.</li> - * <li><code>attributeLocations</code>: An object that maps geometry attribute names to vertex shader attribute locations.</li> - * <li><code>bufferUsage</code>: The expected usage pattern of the vertex array's buffers. On some WebGL implementations, this can significantly affect performance. See {@link BufferUsage}. Default: <code>BufferUsage.DYNAMIC_DRAW</code>.</li> - * <li><code>interleave</code>: Determines if all attributes are interleaved in a single vertex buffer or if each attribute is stored in a separate vertex buffer. Default: <code>false</code>.</li> - * </ul> - * <br /> - * If <code>options</code> is not specified or the <code>geometry</code> contains no data, the returned vertex array is empty. - * - * @param {Object} options An object defining the geometry, attribute indices, buffer usage, and vertex layout used to create the vertex array. - * - * @exception {RuntimeError} Each attribute list must have the same number of vertices. - * @exception {DeveloperError} The geometry must have zero or one index lists. - * @exception {DeveloperError} Index n is used by more than one attribute. - * - * - * @example - * // Example 1. Creates a vertex array for rendering a box. The default dynamic draw - * // usage is used for the created vertex and index buffer. The attributes are not - * // interleaved by default. - * var geometry = new BoxGeometry(); - * var va = VertexArray.fromGeometry({ - * context : context, - * geometry : geometry, - * attributeLocations : GeometryPipeline.createAttributeLocations(geometry), - * }); - * - * @example - * // Example 2. Creates a vertex array with interleaved attributes in a - * // single vertex buffer. The vertex and index buffer have static draw usage. - * var va = VertexArray.fromGeometry({ - * context : context, - * geometry : geometry, - * attributeLocations : GeometryPipeline.createAttributeLocations(geometry), - * bufferUsage : BufferUsage.STATIC_DRAW, - * interleave : true - * }); - * - * @example - * // Example 3. When the caller destroys the vertex array, it also destroys the - * // attached vertex buffer(s) and index buffer. - * va = va.destroy(); + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. * - * @see Buffer#createVertexBuffer - * @see Buffer#createIndexBuffer - * @see GeometryPipeline.createAttributeLocations - * @see ShaderProgram + * @param {RectangleGraphics} source The object to be merged into this object. */ - VertexArray.fromGeometry = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - Check.defined('options.context', options.context); + RectangleGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } - var context = options.context; - var geometry = defaultValue(options.geometry, defaultValue.EMPTY_OBJECT); - - var bufferUsage = defaultValue(options.bufferUsage, BufferUsage.DYNAMIC_DRAW); + this.show = defaultValue(this.show, source.show); + this.coordinates = defaultValue(this.coordinates, source.coordinates); + this.material = defaultValue(this.material, source.material); + this.height = defaultValue(this.height, source.height); + this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); + this.granularity = defaultValue(this.granularity, source.granularity); + this.stRotation = defaultValue(this.stRotation, source.stRotation); + this.rotation = defaultValue(this.rotation, source.rotation); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.closeTop = defaultValue(this.closeTop, source.closeTop); + this.closeBottom = defaultValue(this.closeBottom, source.closeBottom); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + }; - var attributeLocations = defaultValue(options.attributeLocations, defaultValue.EMPTY_OBJECT); - var interleave = defaultValue(options.interleave, false); - var createdVAAttributes = options.vertexArrayAttributes; + return RectangleGraphics; +}); - var name; - var attribute; - var vertexBuffer; - var vaAttributes = (defined(createdVAAttributes)) ? createdVAAttributes : []; - var attributes = geometry.attributes; +define('DataSources/WallGraphics',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './createMaterialPropertyDescriptor', + './createPropertyDescriptor' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + createMaterialPropertyDescriptor, + createPropertyDescriptor) { + 'use strict'; - if (interleave) { - // Use a single vertex buffer with interleaved vertices. - var interleavedAttributes = interleaveAttributes(attributes); - if (defined(interleavedAttributes)) { - vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : interleavedAttributes.buffer, - usage : bufferUsage - }); - var offsetsInBytes = interleavedAttributes.offsetsInBytes; - var strideInBytes = interleavedAttributes.vertexSizeInBytes; + /** + * Describes a two dimensional wall defined as a line strip and optional maximum and minimum heights. + * The wall conforms to the curvature of the globe and can be placed along the surface or at altitude. + * + * @alias WallGraphics + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions which define the top of the wall. + * @param {Property} [options.maximumHeights] A Property specifying an array of heights to be used for the top of the wall instead of the height of each position. + * @param {Property} [options.minimumHeights] A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface. + * @param {Property} [options.show=true] A boolean Property specifying the visibility of the wall. + * @param {Property} [options.fill=true] A boolean Property specifying whether the wall is filled with the provided material. + * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the wall. + * @param {Property} [options.outline=false] A boolean Property specifying whether the wall is outlined. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. + * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. + * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the wall casts or receives shadows from each light source. + * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this wall will be displayed. + * + * @see Entity + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo} + */ + function WallGraphics(options) { + this._show = undefined; + this._showSubscription = undefined; + this._material = undefined; + this._materialSubscription = undefined; + this._positions = undefined; + this._positionsSubscription = undefined; + this._minimumHeights = undefined; + this._minimumHeightsSubscription = undefined; + this._maximumHeights = undefined; + this._maximumHeightsSubscription = undefined; + this._granularity = undefined; + this._granularitySubscription = undefined; + this._fill = undefined; + this._fillSubscription = undefined; + this._outline = undefined; + this._outlineSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + this._shadows = undefined; + this._shadowsSubscription = undefined; + this._distanceDisplayCondition = undefined; + this._distanceDisplayConditionSubscription = undefined; + this._definitionChanged = new Event(); - for (name in attributes) { - if (attributes.hasOwnProperty(name) && defined(attributes[name])) { - attribute = attributes[name]; + this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + } - if (defined(attribute.values)) { - // Common case: per-vertex attributes - vaAttributes.push({ - index : attributeLocations[name], - vertexBuffer : vertexBuffer, - componentDatatype : attribute.componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize, - offsetInBytes : offsetsInBytes[name], - strideInBytes : strideInBytes - }); - } else { - // Constant attribute for all vertices - vaAttributes.push({ - index : attributeLocations[name], - value : attribute.value, - componentDatatype : attribute.componentDatatype, - normalize : attribute.normalize - }); - } - } - } + defineProperties(WallGraphics.prototype, { + /** + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof WallGraphics.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - } else { - // One vertex buffer per attribute. - for (name in attributes) { - if (attributes.hasOwnProperty(name) && defined(attributes[name])) { - attribute = attributes[name]; - - var componentDatatype = attribute.componentDatatype; - if (componentDatatype === ComponentDatatype.DOUBLE) { - componentDatatype = ComponentDatatype.FLOAT; - } + }, - vertexBuffer = undefined; - if (defined(attribute.values)) { - vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : ComponentDatatype.createTypedArray(componentDatatype, attribute.values), - usage : bufferUsage - }); - } + /** + * Gets or sets the boolean Property specifying the visibility of the wall. + * @memberof WallGraphics.prototype + * @type {Property} + * @default true + */ + show : createPropertyDescriptor('show'), - vaAttributes.push({ - index : attributeLocations[name], - vertexBuffer : vertexBuffer, - value : attribute.value, - componentDatatype : componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize - }); - } - } - } + /** + * Gets or sets the Property specifying the material used to fill the wall. + * @memberof WallGraphics.prototype + * @type {MaterialProperty} + * @default Color.WHITE + */ + material : createMaterialPropertyDescriptor('material'), - var indexBuffer; - var indices = geometry.indices; - if (defined(indices)) { - if ((Geometry.computeNumberOfVertices(geometry) >= CesiumMath.SIXTY_FOUR_KILOBYTES) && context.elementIndexUint) { - indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : new Uint32Array(indices), - usage : bufferUsage, - indexDatatype : IndexDatatype.UNSIGNED_INT - }); - } else{ - indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : new Uint16Array(indices), - usage : bufferUsage, - indexDatatype : IndexDatatype.UNSIGNED_SHORT - }); - } - } + /** + * Gets or sets the Property specifying the array of {@link Cartesian3} positions which define the top of the wall. + * @memberof WallGraphics.prototype + * @type {Property} + */ + positions : createPropertyDescriptor('positions'), - return new VertexArray({ - context : context, - attributes : vaAttributes, - indexBuffer : indexBuffer - }); - }; + /** + * Gets or sets the Property specifying an array of heights to be used for the bottom of the wall instead of the surface of the globe. + * If defined, the array must be the same length as {@link Wall#positions}. + * @memberof WallGraphics.prototype + * @type {Property} + */ + minimumHeights : createPropertyDescriptor('minimumHeights'), - defineProperties(VertexArray.prototype, { - numberOfAttributes : { - get : function() { - return this._attributes.length; - } - }, - numberOfVertices : { - get : function() { - return this._numberOfVertices; - } - }, - indexBuffer : { - get : function() { - return this._indexBuffer; - } - } - }); + /** + * Gets or sets the Property specifying an array of heights to be used for the top of the wall instead of the height of each position. + * If defined, the array must be the same length as {@link Wall#positions}. + * @memberof WallGraphics.prototype + * @type {Property} + */ + maximumHeights : createPropertyDescriptor('maximumHeights'), - /** - * index is the location in the array of attributes, not the index property of an attribute. - */ - VertexArray.prototype.getAttribute = function(index) { - Check.defined('index', index); - - return this._attributes[index]; - }; + /** + * Gets or sets the numeric Property specifying the angular distance between points on the wall. + * @memberof WallGraphics.prototype + * @type {Property} + * @default {CesiumMath.RADIANS_PER_DEGREE} + */ + granularity : createPropertyDescriptor('granularity'), - // Workaround for ANGLE, where the attribute divisor seems to be part of the global state instead - // of the VAO state. This function is called when the vao is bound, and should be removed - // once the ANGLE issue is resolved. Setting the divisor should normally happen in vertexAttrib and - // disableVertexAttribArray. - function setVertexAttribDivisor(vertexArray) { - var context = vertexArray._context; - var hasInstancedAttributes = vertexArray._hasInstancedAttributes; - if (!hasInstancedAttributes && !context._previousDrawInstanced) { - return; - } - context._previousDrawInstanced = hasInstancedAttributes; + /** + * Gets or sets the boolean Property specifying whether the wall is filled with the provided material. + * @memberof WallGraphics.prototype + * @type {Property} + * @default true + */ + fill : createPropertyDescriptor('fill'), - var divisors = context._vertexAttribDivisors; - var attributes = vertexArray._attributes; - var maxAttributes = ContextLimits.maximumVertexAttributes; - var i; + /** + * Gets or sets the Property specifying whether the wall is outlined. + * @memberof WallGraphics.prototype + * @type {Property} + * @default false + */ + outline : createPropertyDescriptor('outline'), - if (hasInstancedAttributes) { - var length = attributes.length; - for (i = 0; i < length; ++i) { - var attribute = attributes[i]; - if (attribute.enabled) { - var divisor = attribute.instanceDivisor; - var index = attribute.index; - if (divisor !== divisors[index]) { - context.glVertexAttribDivisor(index, divisor); - divisors[index] = divisor; - } - } - } - } else { - for (i = 0; i < maxAttributes; ++i) { - if (divisors[i] > 0) { - context.glVertexAttribDivisor(i, 0); - divisors[i] = 0; - } - } - } - } + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof WallGraphics.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), - // Vertex attributes backed by a constant value go through vertexAttrib[1234]f[v] - // which is part of context state rather than VAO state. - function setConstantAttributes(vertexArray, gl) { - var attributes = vertexArray._attributes; - var length = attributes.length; - for (var i = 0; i < length; ++i) { - var attribute = attributes[i]; - if (attribute.enabled && defined(attribute.value)) { - attribute.vertexAttrib(gl); - } - } - } + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof WallGraphics.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth'), - VertexArray.prototype._bind = function() { - if (defined(this._vao)) { - this._context.glBindVertexArray(this._vao); - if (this._context.instancedArrays) { - setVertexAttribDivisor(this); - } - if (this._hasConstantAttributes) { - setConstantAttributes(this, this._gl); - } - } else { - bind(this._gl, this._attributes, this._indexBuffer); - } - }; + /** + * Get or sets the enum Property specifying whether the wall + * casts or receives shadows from each light source. + * @memberof WallGraphics.prototype + * @type {Property} + * @default ShadowMode.DISABLED + */ + shadows : createPropertyDescriptor('shadows'), - VertexArray.prototype._unBind = function() { - if (defined(this._vao)) { - this._context.glBindVertexArray(null); - } else { - var attributes = this._attributes; - var gl = this._gl; + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this wall will be displayed. + * @memberof WallGraphics.prototype + * @type {Property} + */ + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + }); - for ( var i = 0; i < attributes.length; ++i) { - var attribute = attributes[i]; - if (attribute.enabled) { - attribute.disableVertexAttribArray(gl); - } - } - if (this._indexBuffer) { - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); - } + /** + * Duplicates this instance. + * + * @param {WallGraphics} [result] The object onto which to store the result. + * @returns {WallGraphics} The modified result parameter or a new instance if one was not provided. + */ + WallGraphics.prototype.clone = function(result) { + if (!defined(result)) { + return new WallGraphics(this); } + result.show = this.show; + result.material = this.material; + result.positions = this.positions; + result.minimumHeights = this.minimumHeights; + result.maximumHeights = this.maximumHeights; + result.granularity = this.granularity; + result.fill = this.fill; + result.outline = this.outline; + result.outlineColor = this.outlineColor; + result.outlineWidth = this.outlineWidth; + result.shadows = this.shadows; + result.distanceDisplayCondition = this.distanceDisplayCondition; + return result; }; - VertexArray.prototype.isDestroyed = function() { - return false; - }; - - VertexArray.prototype.destroy = function() { - var attributes = this._attributes; - for ( var i = 0; i < attributes.length; ++i) { - var vertexBuffer = attributes[i].vertexBuffer; - if (defined(vertexBuffer) && !vertexBuffer.isDestroyed() && vertexBuffer.vertexArrayDestroyable) { - vertexBuffer.destroy(); - } - } - - var indexBuffer = this._indexBuffer; - if (defined(indexBuffer) && !indexBuffer.isDestroyed() && indexBuffer.vertexArrayDestroyable) { - indexBuffer.destroy(); - } - - if (defined(this._vao)) { - this._context.glDeleteVertexArray(this._vao); + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {WallGraphics} source The object to be merged into this object. + */ + WallGraphics.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); } - - return destroyObject(this); + + this.show = defaultValue(this.show, source.show); + this.material = defaultValue(this.material, source.material); + this.positions = defaultValue(this.positions, source.positions); + this.minimumHeights = defaultValue(this.minimumHeights, source.minimumHeights); + this.maximumHeights = defaultValue(this.maximumHeights, source.maximumHeights); + this.granularity = defaultValue(this.granularity, source.granularity); + this.fill = defaultValue(this.fill, source.fill); + this.outline = defaultValue(this.outline, source.outline); + this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); + this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); + this.shadows = defaultValue(this.shadows, source.shadows); + this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); }; - return VertexArray; + return WallGraphics; }); -define('Scene/BatchTable',[ - '../Core/Cartesian2', +define('DataSources/Entity',[ '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/combine', - '../Core/ComponentDatatype', + '../Core/Check', + '../Core/createGuid', + '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/FeatureDetection', - '../Core/Math', - '../Core/PixelFormat', - '../Renderer/ContextLimits', - '../Renderer/PixelDatatype', - '../Renderer/Sampler', - '../Renderer/Texture', - '../Renderer/TextureMagnificationFilter', - '../Renderer/TextureMinificationFilter' + '../Core/Event', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/Quaternion', + '../Core/Transforms', + './BillboardGraphics', + './BoxGraphics', + './ConstantPositionProperty', + './CorridorGraphics', + './createPropertyDescriptor', + './createRawPropertyDescriptor', + './CylinderGraphics', + './EllipseGraphics', + './EllipsoidGraphics', + './LabelGraphics', + './ModelGraphics', + './PathGraphics', + './PlaneGraphics', + './PointGraphics', + './PolygonGraphics', + './PolylineGraphics', + './PolylineVolumeGraphics', + './Property', + './PropertyBag', + './RectangleGraphics', + './WallGraphics' ], function( - Cartesian2, Cartesian3, - Cartesian4, - combine, - ComponentDatatype, + Check, + createGuid, + defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - FeatureDetection, - CesiumMath, - PixelFormat, - ContextLimits, - PixelDatatype, - Sampler, - Texture, - TextureMagnificationFilter, - TextureMinificationFilter) { + Event, + Matrix3, + Matrix4, + Quaternion, + Transforms, + BillboardGraphics, + BoxGraphics, + ConstantPositionProperty, + CorridorGraphics, + createPropertyDescriptor, + createRawPropertyDescriptor, + CylinderGraphics, + EllipseGraphics, + EllipsoidGraphics, + LabelGraphics, + ModelGraphics, + PathGraphics, + PlaneGraphics, + PointGraphics, + PolygonGraphics, + PolylineGraphics, + PolylineVolumeGraphics, + Property, + PropertyBag, + RectangleGraphics, + WallGraphics) { 'use strict'; + function createConstantPositionProperty(value) { + return new ConstantPositionProperty(value); + } + + function createPositionPropertyDescriptor(name) { + return createPropertyDescriptor(name, undefined, createConstantPositionProperty); + } + + function createPropertyTypeDescriptor(name, Type) { + return createPropertyDescriptor(name, undefined, function(value) { + if (value instanceof Type) { + return value; + } + return new Type(value); + }); + } + /** - * Creates a texture to look up per instance attributes for batched primitives. For example, store each primitive's pick color in the texture. - * - * @alias BatchTable + * Entity instances aggregate multiple forms of visualization into a single high-level object. + * They can be created manually and added to {@link Viewer#entities} or be produced by + * data sources, such as {@link CzmlDataSource} and {@link GeoJsonDataSource}. + * @alias Entity * @constructor - * @private - * - * @param {Context} context The context in which the batch table is created. - * @param {Object[]} attributes An array of objects describing a per instance attribute. Each object contains a datatype, components per attributes, whether it is normalized and a function name - * to retrieve the value in the vertex shader. - * @param {Number} numberOfInstances The number of instances in a batch table. - * - * @example - * // create the batch table - * var attributes = [{ - * functionName : 'getShow', - * componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - * componentsPerAttribute : 1 - * }, { - * functionName : 'getPickColor', - * componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - * componentsPerAttribute : 4, - * normalize : true - * }]; - * var batchTable = new BatchTable(context, attributes, 5); - * - * // when creating the draw commands, update the uniform map and the vertex shader - * vertexShaderSource = batchTable.getVertexShaderCallback()(vertexShaderSource); - * var shaderProgram = ShaderProgram.fromCache({ - * // ... - * vertexShaderSource : vertexShaderSource, - * }); * - * drawCommand.shaderProgram = shaderProgram; - * drawCommand.uniformMap = batchTable.getUniformMapCallback()(uniformMap); - * - * // use the attribute function names in the shader to retrieve the instance values - * // ... - * attribute float batchId; + * @param {Object} [options] Object with the following properties: + * @param {String} [options.id] A unique identifier for this object. If none is provided, a GUID is generated. + * @param {String} [options.name] A human readable name to display to users. It does not have to be unique. + * @param {TimeIntervalCollection} [options.availability] The availability, if any, associated with this object. + * @param {Boolean} [options.show] A boolean value indicating if the entity and its children are displayed. + * @param {Property} [options.description] A string Property specifying an HTML description for this entity. + * @param {PositionProperty} [options.position] A Property specifying the entity position. + * @param {Property} [options.orientation] A Property specifying the entity orientation. + * @param {Property} [options.viewFrom] A suggested initial offset for viewing this object. + * @param {Entity} [options.parent] A parent entity to associate with this entity. + * @param {BillboardGraphics} [options.billboard] A billboard to associate with this entity. + * @param {BoxGraphics} [options.box] A box to associate with this entity. + * @param {CorridorGraphics} [options.corridor] A corridor to associate with this entity. + * @param {CylinderGraphics} [options.cylinder] A cylinder to associate with this entity. + * @param {EllipseGraphics} [options.ellipse] A ellipse to associate with this entity. + * @param {EllipsoidGraphics} [options.ellipsoid] A ellipsoid to associate with this entity. + * @param {LabelGraphics} [options.label] A options.label to associate with this entity. + * @param {ModelGraphics} [options.model] A model to associate with this entity. + * @param {PathGraphics} [options.path] A path to associate with this entity. + * @param {PlaneGraphics} [options.plane] A plane to associate with this entity. + * @param {PointGraphics} [options.point] A point to associate with this entity. + * @param {PolygonGraphics} [options.polygon] A polygon to associate with this entity. + * @param {PolylineGraphics} [options.polyline] A polyline to associate with this entity. + * @param {PropertyBag} [options.properties] Arbitrary properties to associate with this entity. + * @param {PolylineVolumeGraphics} [options.polylineVolume] A polylineVolume to associate with this entity. + * @param {RectangleGraphics} [options.rectangle] A rectangle to associate with this entity. + * @param {WallGraphics} [options.wall] A wall to associate with this entity. * - * void main() { - * // ... - * float show = getShow(batchId); - * vec3 pickColor = getPickColor(batchId); - * // ... - * } + * @see {@link https://cesiumjs.org/tutorials/Visualizing-Spatial-Data/|Visualizing Spatial Data} */ - function BatchTable(context, attributes, numberOfInstances) { - if (!defined(context)) { - throw new DeveloperError('context is required'); - } - if (!defined(attributes)) { - throw new DeveloperError('attributes is required'); - } - if (!defined(numberOfInstances)) { - throw new DeveloperError('numberOfInstances is required'); - } - - this._attributes = attributes; - this._numberOfInstances = numberOfInstances; + function Entity(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (attributes.length === 0) { - return; + var id = options.id; + if (!defined(id)) { + id = createGuid(); } - // PERFORMANCE_IDEA: We may be able to arrange the attributes so they can be packing into fewer texels. - // Right now, an attribute with one component uses an entire texel when 4 single component attributes can - // be packed into a texel. - // - // Packing floats into unsigned byte textures makes the problem worse. A single component float attribute - // will be packed into a single texel leaving 3 texels unused. 4 texels are reserved for each float attribute - // regardless of how many components it has. - var pixelDatatype = getDatatype(attributes); - var textureFloatSupported = context.floatingPointTexture; - var packFloats = pixelDatatype === PixelDatatype.FLOAT && !textureFloatSupported; - var offsets = createOffsets(attributes, packFloats); - - var stride = getStride(offsets, attributes, packFloats); - var maxNumberOfInstancesPerRow = Math.floor(ContextLimits.maximumTextureSize / stride); + this._availability = undefined; + this._id = id; + this._definitionChanged = new Event(); + this._name = options.name; + this._show = defaultValue(options.show, true); + this._parent = undefined; + this._propertyNames = ['billboard', 'box', 'corridor', 'cylinder', 'description', 'ellipse', // + 'ellipsoid', 'label', 'model', 'orientation', 'path', 'plane', 'point', 'polygon', // + 'polyline', 'polylineVolume', 'position', 'properties', 'rectangle', 'viewFrom', 'wall']; - var instancesPerWidth = Math.min(numberOfInstances, maxNumberOfInstancesPerRow); - var width = stride * instancesPerWidth; - var height = Math.ceil(numberOfInstances / instancesPerWidth); + this._billboard = undefined; + this._billboardSubscription = undefined; + this._box = undefined; + this._boxSubscription = undefined; + this._corridor = undefined; + this._corridorSubscription = undefined; + this._cylinder = undefined; + this._cylinderSubscription = undefined; + this._description = undefined; + this._descriptionSubscription = undefined; + this._ellipse = undefined; + this._ellipseSubscription = undefined; + this._ellipsoid = undefined; + this._ellipsoidSubscription = undefined; + this._label = undefined; + this._labelSubscription = undefined; + this._model = undefined; + this._modelSubscription = undefined; + this._orientation = undefined; + this._orientationSubscription = undefined; + this._path = undefined; + this._pathSubscription = undefined; + this._plane = undefined; + this._planeSubscription = undefined; + this._point = undefined; + this._pointSubscription = undefined; + this._polygon = undefined; + this._polygonSubscription = undefined; + this._polyline = undefined; + this._polylineSubscription = undefined; + this._polylineVolume = undefined; + this._polylineVolumeSubscription = undefined; + this._position = undefined; + this._positionSubscription = undefined; + this._properties = undefined; + this._propertiesSubscription = undefined; + this._rectangle = undefined; + this._rectangleSubscription = undefined; + this._viewFrom = undefined; + this._viewFromSubscription = undefined; + this._wall = undefined; + this._wallSubscription = undefined; + this._children = []; - var stepX = 1.0 / width; - var centerX = stepX * 0.5; - var stepY = 1.0 / height; - var centerY = stepY * 0.5; + /** + * Gets or sets the entity collection that this entity belongs to. + * @type {EntityCollection} + */ + this.entityCollection = undefined; - this._textureDimensions = new Cartesian2(width, height); - this._textureStep = new Cartesian4(stepX, centerX, stepY, centerY); - this._pixelDatatype = !packFloats ? pixelDatatype : PixelDatatype.UNSIGNED_BYTE; - this._packFloats = packFloats; - this._offsets = offsets; - this._stride = stride; - this._texture = undefined; + this.parent = options.parent; + this.merge(options); + } - var batchLength = 4 * width * height; - this._batchValues = pixelDatatype === PixelDatatype.FLOAT && !packFloats ? new Float32Array(batchLength) : new Uint8Array(batchLength); - this._batchValuesDirty = false; + function updateShow(entity, children, isShowing) { + var length = children.length; + for (var i = 0; i < length; i++) { + var child = children[i]; + var childShow = child._show; + var oldValue = !isShowing && childShow; + var newValue = isShowing && childShow; + if (oldValue !== newValue) { + updateShow(child, child._children, isShowing); + } + } + entity._definitionChanged.raiseEvent(entity, 'isShowing', isShowing, !isShowing); } - defineProperties(BatchTable.prototype, { + defineProperties(Entity.prototype, { /** - * The attribute descriptions. - * @memberOf BatchTable.prototype - * @type {Object[]} - * @readonly + * The availability, if any, associated with this object. + * If availability is undefined, it is assumed that this object's + * other properties will return valid data for any provided time. + * If availability exists, the objects other properties will only + * provide valid data if queried within the given interval. + * @memberof Entity.prototype + * @type {TimeIntervalCollection} */ - attributes : { + availability : createRawPropertyDescriptor('availability'), + /** + * Gets the unique ID associated with this object. + * @memberof Entity.prototype + * @type {String} + */ + id : { get : function() { - return this._attributes; + return this._id; } }, /** - * The number of instances. - * @memberOf BatchTable.prototype - * @type {Number} + * Gets the event that is raised whenever a property or sub-property is changed or modified. + * @memberof Entity.prototype + * + * @type {Event} * @readonly */ - numberOfInstances : { - get : function () { - return this._numberOfInstances; - } - } - }); - - function getDatatype(attributes) { - var foundFloatDatatype = false; - var length = attributes.length; - for (var i = 0; i < length; ++i) { - if (attributes[i].componentDatatype !== ComponentDatatype.UNSIGNED_BYTE) { - foundFloatDatatype = true; - break; + definitionChanged : { + get : function() { + return this._definitionChanged; } - } - return foundFloatDatatype ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE; - } - - function getAttributeType(attributes, attributeIndex) { - var componentsPerAttribute = attributes[attributeIndex].componentsPerAttribute; - if (componentsPerAttribute === 2) { - return Cartesian2; - } else if (componentsPerAttribute === 3) { - return Cartesian3; - } else if (componentsPerAttribute === 4) { - return Cartesian4; - } - return Number; - } - - function createOffsets(attributes, packFloats) { - var offsets = new Array(attributes.length); + }, + /** + * Gets or sets the name of the object. The name is intended for end-user + * consumption and does not need to be unique. + * @memberof Entity.prototype + * @type {String} + */ + name : createRawPropertyDescriptor('name'), + /** + * Gets or sets whether this entity should be displayed. When set to true, + * the entity is only displayed if the parent entity's show property is also true. + * @memberof Entity.prototype + * @type {Boolean} + */ + show : { + get : function() { + return this._show; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (value === this._show) { + return; + } - var currentOffset = 0; - var attributesLength = attributes.length; - for (var i = 0; i < attributesLength; ++i) { - var attribute = attributes[i]; - var componentDatatype = attribute.componentDatatype; + var wasShowing = this.isShowing; + this._show = value; + var isShowing = this.isShowing; - offsets[i] = currentOffset; + if (wasShowing !== isShowing) { + updateShow(this, this._children, isShowing); + } - if (componentDatatype !== ComponentDatatype.UNSIGNED_BYTE && packFloats) { - currentOffset += 4; - } else { - ++currentOffset; + this._definitionChanged.raiseEvent(this, 'show', value, !value); } - } - - return offsets; - } - - function getStride(offsets, attributes, packFloats) { - var length = offsets.length; - var lastOffset = offsets[length - 1]; - var lastAttribute = attributes[length - 1]; - var componentDatatype = lastAttribute.componentDatatype; - - if (componentDatatype !== ComponentDatatype.UNSIGNED_BYTE && packFloats) { - return lastOffset + 4; - } - return lastOffset + 1; - } + }, + /** + * Gets whether this entity is being displayed, taking into account + * the visibility of any ancestor entities. + * @memberof Entity.prototype + * @type {Boolean} + */ + isShowing : { + get : function() { + return this._show && (!defined(this.entityCollection) || this.entityCollection.show) && (!defined(this._parent) || this._parent.isShowing); + } + }, + /** + * Gets or sets the parent object. + * @memberof Entity.prototype + * @type {Entity} + */ + parent : { + get : function() { + return this._parent; + }, + set : function(value) { + var oldValue = this._parent; - var scratchPackedFloatCartesian4 = new Cartesian4(); + if (oldValue === value) { + return; + } - var SHIFT_LEFT_8 = 256.0; - var SHIFT_LEFT_16 = 65536.0; - var SHIFT_LEFT_24 = 16777216.0; + var wasShowing = this.isShowing; + if (defined(oldValue)) { + var index = oldValue._children.indexOf(this); + oldValue._children.splice(index, 1); + } - var SHIFT_RIGHT_8 = 1.0 / SHIFT_LEFT_8; - var SHIFT_RIGHT_16 = 1.0 / SHIFT_LEFT_16; - var SHIFT_RIGHT_24 = 1.0 / SHIFT_LEFT_24; + this._parent = value; + if (defined(value)) { + value._children.push(this); + } - var BIAS = 38.0; + var isShowing = this.isShowing; - function unpackFloat(value) { - var temp = value.w / 2.0; - var exponent = Math.floor(temp); - var sign = (temp - exponent) * 2.0; - exponent = exponent - BIAS; + if (wasShowing !== isShowing) { + updateShow(this, this._children, isShowing); + } - sign = sign * 2.0 - 1.0; - sign = -sign; + this._definitionChanged.raiseEvent(this, 'parent', value, oldValue); + } + }, + /** + * Gets the names of all properties registered on this instance. + * @memberof Entity.prototype + * @type {Array} + */ + propertyNames : { + get : function() { + return this._propertyNames; + } + }, + /** + * Gets or sets the billboard. + * @memberof Entity.prototype + * @type {BillboardGraphics} + */ + billboard : createPropertyTypeDescriptor('billboard', BillboardGraphics), + /** + * Gets or sets the box. + * @memberof Entity.prototype + * @type {BoxGraphics} + */ + box : createPropertyTypeDescriptor('box', BoxGraphics), + /** + * Gets or sets the corridor. + * @memberof Entity.prototype + * @type {CorridorGraphics} + */ + corridor : createPropertyTypeDescriptor('corridor', CorridorGraphics), + /** + * Gets or sets the cylinder. + * @memberof Entity.prototype + * @type {CylinderGraphics} + */ + cylinder : createPropertyTypeDescriptor('cylinder', CylinderGraphics), + /** + * Gets or sets the description. + * @memberof Entity.prototype + * @type {Property} + */ + description : createPropertyDescriptor('description'), + /** + * Gets or sets the ellipse. + * @memberof Entity.prototype + * @type {EllipseGraphics} + */ + ellipse : createPropertyTypeDescriptor('ellipse', EllipseGraphics), + /** + * Gets or sets the ellipsoid. + * @memberof Entity.prototype + * @type {EllipsoidGraphics} + */ + ellipsoid : createPropertyTypeDescriptor('ellipsoid', EllipsoidGraphics), + /** + * Gets or sets the label. + * @memberof Entity.prototype + * @type {LabelGraphics} + */ + label : createPropertyTypeDescriptor('label', LabelGraphics), + /** + * Gets or sets the model. + * @memberof Entity.prototype + * @type {ModelGraphics} + */ + model : createPropertyTypeDescriptor('model', ModelGraphics), + /** + * Gets or sets the orientation. + * @memberof Entity.prototype + * @type {Property} + */ + orientation : createPropertyDescriptor('orientation'), + /** + * Gets or sets the path. + * @memberof Entity.prototype + * @type {PathGraphics} + */ + path : createPropertyTypeDescriptor('path', PathGraphics), + /** + * Gets or sets the plane. + * @memberof Entity.prototype + * @type {PlaneGraphics} + */ + plane : createPropertyTypeDescriptor('plane', PlaneGraphics), + /** + * Gets or sets the point graphic. + * @memberof Entity.prototype + * @type {PointGraphics} + */ + point : createPropertyTypeDescriptor('point', PointGraphics), + /** + * Gets or sets the polygon. + * @memberof Entity.prototype + * @type {PolygonGraphics} + */ + polygon : createPropertyTypeDescriptor('polygon', PolygonGraphics), + /** + * Gets or sets the polyline. + * @memberof Entity.prototype + * @type {PolylineGraphics} + */ + polyline : createPropertyTypeDescriptor('polyline', PolylineGraphics), + /** + * Gets or sets the polyline volume. + * @memberof Entity.prototype + * @type {PolylineVolumeGraphics} + */ + polylineVolume : createPropertyTypeDescriptor('polylineVolume', PolylineVolumeGraphics), + /** + * Gets or sets the bag of arbitrary properties associated with this entity. + * @memberof Entity.prototype + * @type {PropertyBag} + */ + properties : createPropertyTypeDescriptor('properties', PropertyBag), + /** + * Gets or sets the position. + * @memberof Entity.prototype + * @type {PositionProperty} + */ + position : createPositionPropertyDescriptor('position'), + /** + * Gets or sets the rectangle. + * @memberof Entity.prototype + * @type {RectangleGraphics} + */ + rectangle : createPropertyTypeDescriptor('rectangle', RectangleGraphics), + /** + * Gets or sets the suggested initial offset for viewing this object + * with the camera. The offset is defined in the east-north-up reference frame. + * @memberof Entity.prototype + * @type {Property} + */ + viewFrom : createPropertyDescriptor('viewFrom'), + /** + * Gets or sets the wall. + * @memberof Entity.prototype + * @type {WallGraphics} + */ + wall : createPropertyTypeDescriptor('wall', WallGraphics) + }); - if (exponent >= BIAS) { - return sign < 0.0 ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY; + /** + * Given a time, returns true if this object should have data during that time. + * + * @param {JulianDate} time The time to check availability for. + * @returns {Boolean} true if the object should have data during the provided time, false otherwise. + */ + Entity.prototype.isAvailable = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } + + var availability = this._availability; + return !defined(availability) || availability.contains(time); + }; - var unpacked = sign * value.x * SHIFT_RIGHT_8; - unpacked += sign * value.y * SHIFT_RIGHT_16; - unpacked += sign * value.z * SHIFT_RIGHT_24; - - return unpacked * Math.pow(10.0, exponent); - } - - function getPackedFloat(array, index, result) { - var packed = Cartesian4.unpack(array, index, scratchPackedFloatCartesian4); - var x = unpackFloat(packed); - - packed = Cartesian4.unpack(array, index + 4, scratchPackedFloatCartesian4); - var y = unpackFloat(packed); - - packed = Cartesian4.unpack(array, index + 8, scratchPackedFloatCartesian4); - var z = unpackFloat(packed); - - packed = Cartesian4.unpack(array, index + 12, scratchPackedFloatCartesian4); - var w = unpackFloat(packed); - - return Cartesian4.fromElements(x, y, z, w, result); - } - - if (!FeatureDetection.supportsTypedArrays()) { - return; - } - var scratchFloatArray = new Float32Array(1); - - function packFloat(value, result) { - scratchFloatArray[0] = value; - value = scratchFloatArray[0]; + /** + * Adds a property to this object. Once a property is added, it can be + * observed with {@link Entity#definitionChanged} and composited + * with {@link CompositeEntityCollection} + * + * @param {String} propertyName The name of the property to add. + * + * @exception {DeveloperError} "propertyName" is a reserved property name. + * @exception {DeveloperError} "propertyName" is already a registered property. + */ + Entity.prototype.addProperty = function(propertyName) { + var propertyNames = this._propertyNames; - if (value === 0.0) { - return Cartesian4.clone(Cartesian4.ZERO, result); + if (!defined(propertyName)) { + throw new DeveloperError('propertyName is required.'); } - - var sign = value < 0.0 ? 1.0 : 0.0; - var exponent; - - if (!isFinite(value)) { - value = 0.1; - exponent = BIAS; - } else { - value = Math.abs(value); - exponent = Math.floor(CesiumMath.logBase(value, 10)) + 1.0; - value = value / Math.pow(10.0, exponent); + if (propertyNames.indexOf(propertyName) !== -1) { + throw new DeveloperError(propertyName + ' is already a registered property.'); } - - var temp = value * SHIFT_LEFT_8; - result.x = Math.floor(temp); - temp = (temp - result.x) * SHIFT_LEFT_8; - result.y = Math.floor(temp); - temp = (temp - result.y) * SHIFT_LEFT_8; - result.z = Math.floor(temp); - result.w = (exponent + BIAS) * 2.0 + sign; - - return result; - } - - function setPackedAttribute(value, array, index) { - var packed = packFloat(value.x, scratchPackedFloatCartesian4); - Cartesian4.pack(packed, array, index); - - packed = packFloat(value.y, packed); - Cartesian4.pack(packed, array, index + 4); - - packed = packFloat(value.z, packed); - Cartesian4.pack(packed, array, index + 8); - - packed = packFloat(value.w, packed); - Cartesian4.pack(packed, array, index + 12); - } - - var scratchGetAttributeCartesian4 = new Cartesian4(); + if (propertyName in this) { + throw new DeveloperError(propertyName + ' is a reserved property name.'); + } + + propertyNames.push(propertyName); + Object.defineProperty(this, propertyName, createRawPropertyDescriptor(propertyName, true)); + }; /** - * Gets the value of an attribute in the table. + * Removed a property previously added with addProperty. * - * @param {Number} instanceIndex The index of the instance. - * @param {Number} attributeIndex The index of the attribute. - * @param {undefined|Cartesian2|Cartesian3|Cartesian4} [result] The object onto which to store the result. The type is dependent on the attribute's number of components. - * @returns {Number|Cartesian2|Cartesian3|Cartesian4} The attribute value stored for the instance. + * @param {String} propertyName The name of the property to remove. * - * @exception {DeveloperError} instanceIndex is out of range. - * @exception {DeveloperError} attributeIndex is out of range. + * @exception {DeveloperError} "propertyName" is a reserved property name. + * @exception {DeveloperError} "propertyName" is not a registered property. */ - BatchTable.prototype.getBatchedAttribute = function(instanceIndex, attributeIndex, result) { - if (instanceIndex < 0 || instanceIndex >= this._numberOfInstances) { - throw new DeveloperError('instanceIndex is out of range.'); + Entity.prototype.removeProperty = function(propertyName) { + var propertyNames = this._propertyNames; + var index = propertyNames.indexOf(propertyName); + + if (!defined(propertyName)) { + throw new DeveloperError('propertyName is required.'); } - if (attributeIndex < 0 || attributeIndex >= this._attributes.length) { - throw new DeveloperError('attributeIndex is out of range'); + if (index === -1) { + throw new DeveloperError(propertyName + ' is not a registered property.'); } - var attributes = this._attributes; - var offset = this._offsets[attributeIndex]; - var stride = this._stride; - - var index = 4 * stride * instanceIndex + 4 * offset; - var value; + this._propertyNames.splice(index, 1); + delete this[propertyName]; + }; - if (this._packFloats && attributes[attributeIndex].componentDatatype !== PixelDatatype.UNSIGNED_BYTE) { - value = getPackedFloat(this._batchValues, index, scratchGetAttributeCartesian4); - } else { - value = Cartesian4.unpack(this._batchValues, index, scratchGetAttributeCartesian4); + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {Entity} source The object to be merged into this object. + */ + Entity.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); } + + //Name, show, and availability are not Property objects and are currently handled differently. + //source.show is intentionally ignored because this.show always has a value. + this.name = defaultValue(this.name, source.name); + this.availability = defaultValue(source.availability, this.availability); - var attributeType = getAttributeType(attributes, attributeIndex); - if (defined(attributeType.fromCartesian4)) { - return attributeType.fromCartesian4(value, result); - } else if (defined(attributeType.clone)) { - return attributeType.clone(value, result); - } + var propertyNames = this._propertyNames; + var sourcePropertyNames = defined(source._propertyNames) ? source._propertyNames : Object.keys(source); + var propertyNamesLength = sourcePropertyNames.length; + for (var i = 0; i < propertyNamesLength; i++) { + var name = sourcePropertyNames[i]; - return value.x; + //Ignore parent when merging, this only happens at construction time. + if (name === 'parent') { + continue; + } + + var targetProperty = this[name]; + var sourceProperty = source[name]; + + //Custom properties that are registered on the source entity must also + //get registered on this entity. + if (!defined(targetProperty) && propertyNames.indexOf(name) === -1) { + this.addProperty(name); + } + + if (defined(sourceProperty)) { + if (defined(targetProperty)) { + if (defined(targetProperty.merge)) { + targetProperty.merge(sourceProperty); + } + } else if (defined(sourceProperty.merge) && defined(sourceProperty.clone)) { + this[name] = sourceProperty.clone(); + } else { + this[name] = sourceProperty; + } + } + } }; - var setAttributeScratchValues = [undefined, undefined, new Cartesian2(), new Cartesian3(), new Cartesian4()]; - var setAttributeScratchCartesian4 = new Cartesian4(); + var matrix3Scratch = new Matrix3(); + var positionScratch = new Cartesian3(); + var orientationScratch = new Quaternion(); /** - * Sets the value of an attribute in the table. + * Computes the model matrix for the entity's transform at specified time. Returns undefined if orientation or position + * are undefined. * - * @param {Number} instanceIndex The index of the instance. - * @param {Number} attributeIndex The index of the attribute. - * @param {Number|Cartesian2|Cartesian3|Cartesian4} value The value to be stored in the table. The type of value will depend on the number of components of the attribute. + * @param {JulianDate} time The time to retrieve model matrix for. + * @param {Matrix4} [result] The object onto which to store the result. * - * @exception {DeveloperError} instanceIndex is out of range. - * @exception {DeveloperError} attributeIndex is out of range. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. Result is undefined if position or orientation are undefined. */ - BatchTable.prototype.setBatchedAttribute = function(instanceIndex, attributeIndex, value) { - if (instanceIndex < 0 || instanceIndex >= this._numberOfInstances) { - throw new DeveloperError('instanceIndex is out of range.'); - } - if (attributeIndex < 0 || attributeIndex >= this._attributes.length) { - throw new DeveloperError('attributeIndex is out of range'); - } - if (!defined(value)) { - throw new DeveloperError('value is required.'); + Entity.prototype.computeModelMatrix = function(time, result) { + Check.typeOf.object('time', time); + var position = Property.getValueOrUndefined(this._position, time, positionScratch); + if (!defined(position)) { + return undefined; } - - var attributes = this._attributes; - var result = setAttributeScratchValues[attributes[attributeIndex].componentsPerAttribute]; - var currentAttribute = this.getBatchedAttribute(instanceIndex, attributeIndex, result); - var attributeType = getAttributeType(this._attributes, attributeIndex); - var entriesEqual = defined(attributeType.equals) ? attributeType.equals(currentAttribute, value) : currentAttribute === value; - if (entriesEqual) { - return; + var orientation = Property.getValueOrUndefined(this._orientation, time, orientationScratch); + if (!defined(orientation)) { + result = Transforms.eastNorthUpToFixedFrame(position, undefined, result); + } else { + result = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation, matrix3Scratch), position, result); } + return result; + }; - var attributeValue = setAttributeScratchCartesian4; - attributeValue.x = defined(value.x) ? value.x : value; - attributeValue.y = defined(value.y) ? value.y : 0.0; - attributeValue.z = defined(value.z) ? value.z : 0.0; - attributeValue.w = defined(value.w) ? value.w : 0.0; - - var offset = this._offsets[attributeIndex]; - var stride = this._stride; - var index = 4 * stride * instanceIndex + 4 * offset; + return Entity; +}); - if (this._packFloats && attributes[attributeIndex].componentDatatype !== PixelDatatype.UNSIGNED_BYTE) { - setPackedAttribute(attributeValue, this._batchValues, index); - } else { - Cartesian4.pack(attributeValue, this._batchValues, index); - } +define('DataSources/EntityCollection',[ + '../Core/AssociativeArray', + '../Core/createGuid', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/Iso8601', + '../Core/JulianDate', + '../Core/RuntimeError', + '../Core/TimeInterval', + './Entity' + ], function( + AssociativeArray, + createGuid, + defined, + defineProperties, + DeveloperError, + Event, + Iso8601, + JulianDate, + RuntimeError, + TimeInterval, + Entity) { + 'use strict'; - this._batchValuesDirty = true; + var entityOptionsScratch = { + id : undefined }; - function createTexture(batchTable, context) { - var dimensions = batchTable._textureDimensions; - batchTable._texture = new Texture({ - context : context, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : batchTable._pixelDatatype, - width : dimensions.x, - height : dimensions.y, - sampler : new Sampler({ - minificationFilter : TextureMinificationFilter.NEAREST, - magnificationFilter : TextureMagnificationFilter.NEAREST - }) - }); - } + function fireChangedEvent(collection) { + if (collection._firing) { + collection._refire = true; + return; + } - function updateTexture(batchTable) { - var dimensions = batchTable._textureDimensions; - batchTable._texture.copyFrom({ - width : dimensions.x, - height : dimensions.y, - arrayBufferView : batchTable._batchValues - }); + if (collection._suspendCount === 0) { + var added = collection._addedEntities; + var removed = collection._removedEntities; + var changed = collection._changedEntities; + if (changed.length !== 0 || added.length !== 0 || removed.length !== 0) { + collection._firing = true; + do { + collection._refire = false; + var addedArray = added.values.slice(0); + var removedArray = removed.values.slice(0); + var changedArray = changed.values.slice(0); + + added.removeAll(); + removed.removeAll(); + changed.removeAll(); + collection._collectionChanged.raiseEvent(collection, addedArray, removedArray, changedArray); + } while (collection._refire); + collection._firing = false; + } + } } /** - * Creates/updates the batch table texture. - * @param {FrameState} frameState The frame state. + * An observable collection of {@link Entity} instances where each entity has a unique id. + * @alias EntityCollection + * @constructor * - * @exception {RuntimeError} The floating point texture extension is required but not supported. + * @param {DataSource|CompositeEntityCollection} [owner] The data source (or composite entity collection) which created this collection. */ - BatchTable.prototype.update = function(frameState) { - if ((defined(this._texture) && !this._batchValuesDirty) || this._attributes.length === 0) { - return; - } + function EntityCollection(owner) { + this._owner = owner; + this._entities = new AssociativeArray(); + this._addedEntities = new AssociativeArray(); + this._removedEntities = new AssociativeArray(); + this._changedEntities = new AssociativeArray(); + this._suspendCount = 0; + this._collectionChanged = new Event(); + this._id = createGuid(); + this._show = true; + this._firing = false; + this._refire = false; + } - this._batchValuesDirty = false; + /** + * Prevents {@link EntityCollection#collectionChanged} events from being raised + * until a corresponding call is made to {@link EntityCollection#resumeEvents}, at which + * point a single event will be raised that covers all suspended operations. + * This allows for many items to be added and removed efficiently. + * This function can be safely called multiple times as long as there + * are corresponding calls to {@link EntityCollection#resumeEvents}. + */ + EntityCollection.prototype.suspendEvents = function() { + this._suspendCount++; + }; - if (!defined(this._texture)) { - createTexture(this, frameState.context); + /** + * Resumes raising {@link EntityCollection#collectionChanged} events immediately + * when an item is added or removed. Any modifications made while while events were suspended + * will be triggered as a single event when this function is called. + * This function is reference counted and can safely be called multiple times as long as there + * are corresponding calls to {@link EntityCollection#resumeEvents}. + * + * @exception {DeveloperError} resumeEvents can not be called before suspendEvents. + */ + EntityCollection.prototype.resumeEvents = function() { + if (this._suspendCount === 0) { + throw new DeveloperError('resumeEvents can not be called before suspendEvents.'); } - updateTexture(this); + + this._suspendCount--; + fireChangedEvent(this); }; /** - * Gets a function that will update a uniform map to contain values for looking up values in the batch table. + * The signature of the event generated by {@link EntityCollection#collectionChanged}. + * @function * - * @returns {BatchTable~updateUniformMapCallback} A callback for updating uniform maps. + * @param {EntityCollection} collection The collection that triggered the event. + * @param {Entity[]} added The array of {@link Entity} instances that have been added to the collection. + * @param {Entity[]} removed The array of {@link Entity} instances that have been removed from the collection. + * @param {Entity[]} changed The array of {@link Entity} instances that have been modified. */ - BatchTable.prototype.getUniformMapCallback = function() { - var that = this; - return function(uniformMap) { - if (that._attributes.length === 0) { - return uniformMap; - } + EntityCollection.collectionChangedEventCallback = undefined; - var batchUniformMap = { - batchTexture : function() { - return that._texture; - }, - batchTextureDimensions : function() { - return that._textureDimensions; - }, - batchTextureStep : function() { - return that._textureStep; + defineProperties(EntityCollection.prototype, { + /** + * Gets the event that is fired when entities are added or removed from the collection. + * The generated event is a {@link EntityCollection.collectionChangedEventCallback}. + * @memberof EntityCollection.prototype + * @readonly + * @type {Event} + */ + collectionChanged : { + get : function() { + return this._collectionChanged; + } + }, + /** + * Gets a globally unique identifier for this collection. + * @memberof EntityCollection.prototype + * @readonly + * @type {String} + */ + id : { + get : function() { + return this._id; + } + }, + /** + * Gets the array of Entity instances in the collection. + * This array should not be modified directly. + * @memberof EntityCollection.prototype + * @readonly + * @type {Entity[]} + */ + values : { + get : function() { + return this._entities.values; + } + }, + /** + * Gets whether or not this entity collection should be + * displayed. When true, each entity is only displayed if + * its own show property is also true. + * @memberof EntityCollection.prototype + * @type {Boolean} + */ + show : { + get : function() { + return this._show; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (value === this._show) { + return; } - }; - return combine(uniformMap, batchUniformMap); - }; - }; - - function getGlslComputeSt(batchTable) { - var stride = batchTable._stride; - - // GLSL batchId is zero-based: [0, numberOfInstances - 1] - if (batchTable._textureDimensions.y === 1) { - return 'uniform vec4 batchTextureStep; \n' + - 'vec2 computeSt(float batchId) \n' + - '{ \n' + - ' float stepX = batchTextureStep.x; \n' + - ' float centerX = batchTextureStep.y; \n' + - ' float numberOfAttributes = float('+ stride + '); \n' + - ' return vec2(centerX + (batchId * numberOfAttributes * stepX), 0.5); \n' + - '} \n'; - } - - return 'uniform vec4 batchTextureStep; \n' + - 'uniform vec2 batchTextureDimensions; \n' + - 'vec2 computeSt(float batchId) \n' + - '{ \n' + - ' float stepX = batchTextureStep.x; \n' + - ' float centerX = batchTextureStep.y; \n' + - ' float stepY = batchTextureStep.z; \n' + - ' float centerY = batchTextureStep.w; \n' + - ' float numberOfAttributes = float('+ stride + '); \n' + - ' float xId = mod(batchId * numberOfAttributes, batchTextureDimensions.x); \n' + - ' float yId = floor(batchId * numberOfAttributes / batchTextureDimensions.x); \n' + - ' return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n' + - '} \n'; - } - - function getGlslUnpackFloat(batchTable) { - if (!batchTable._packFloats) { - return ''; - } - - return 'float unpackFloat(vec4 value) \n' + - '{ \n' + - ' value *= 255.0; \n' + - ' float temp = value.w / 2.0; \n' + - ' float exponent = floor(temp); \n' + - ' float sign = (temp - exponent) * 2.0; \n' + - ' exponent = exponent - float(' + BIAS + '); \n' + - ' sign = sign * 2.0 - 1.0; \n' + - ' sign = -sign; \n' + - ' float unpacked = sign * value.x * float(' + SHIFT_RIGHT_8 + '); \n' + - ' unpacked += sign * value.y * float(' + SHIFT_RIGHT_16 + '); \n' + - ' unpacked += sign * value.z * float(' + SHIFT_RIGHT_24 + '); \n' + - ' return unpacked * pow(10.0, exponent); \n' + - '} \n'; - } - - function getComponentType(componentsPerAttribute) { - if (componentsPerAttribute === 1) { - return 'float'; - } - return 'vec' + componentsPerAttribute; - } - function getComponentSwizzle(componentsPerAttribute) { - if (componentsPerAttribute === 1) { - return '.x'; - } else if (componentsPerAttribute === 2) { - return '.xy'; - } else if (componentsPerAttribute === 3) { - return '.xyz'; - } - return ''; - } + //Since entity.isShowing includes the EntityCollection.show state + //in its calculation, we need to loop over the entities array + //twice, once to get the old showing value and a second time + //to raise the changed event. + this.suspendEvents(); - function getGlslAttributeFunction(batchTable, attributeIndex) { - var attributes = batchTable._attributes; - var attribute = attributes[attributeIndex]; - var componentsPerAttribute = attribute.componentsPerAttribute; - var functionName = attribute.functionName; - var functionReturnType = getComponentType(componentsPerAttribute); - var functionReturnValue = getComponentSwizzle(componentsPerAttribute); + var i; + var oldShows = []; + var entities = this._entities.values; + var entitiesLength = entities.length; - var offset = batchTable._offsets[attributeIndex]; + for (i = 0; i < entitiesLength; i++) { + oldShows.push(entities[i].isShowing); + } - var glslFunction = - functionReturnType + ' ' + functionName + '(float batchId) \n' + - '{ \n' + - ' vec2 st = computeSt(batchId); \n' + - ' st.x += batchTextureStep.x * float(' + offset + '); \n'; + this._show = value; - if (batchTable._packFloats && attribute.componentDatatype !== PixelDatatype.UNSIGNED_BYTE) { - glslFunction += 'vec4 textureValue; \n' + - 'textureValue.x = unpackFloat(texture2D(batchTexture, st)); \n' + - 'textureValue.y = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x, 0.0))); \n' + - 'textureValue.z = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 2.0, 0.0))); \n' + - 'textureValue.w = unpackFloat(texture2D(batchTexture, st + vec2(batchTextureStep.x * 3.0, 0.0))); \n'; + for (i = 0; i < entitiesLength; i++) { + var oldShow = oldShows[i]; + var entity = entities[i]; + if (oldShow !== entity.isShowing) { + entity.definitionChanged.raiseEvent(entity, 'isShowing', entity.isShowing, oldShow); + } + } - } else { - glslFunction += ' vec4 textureValue = texture2D(batchTexture, st); \n'; + this.resumeEvents(); + } + }, + /** + * Gets the owner of this entity collection, ie. the data source or composite entity collection which created it. + * @memberof EntityCollection.prototype + * @readonly + * @type {DataSource|CompositeEntityCollection} + */ + owner : { + get : function() { + return this._owner; + } } + }); - glslFunction += ' ' + functionReturnType + ' value = textureValue' + functionReturnValue + '; \n'; - - if (batchTable._pixelDatatype === PixelDatatype.UNSIGNED_BYTE && attribute.componentDatatype === ComponentDatatype.UNSIGNED_BYTE && !attribute.normalize) { - glslFunction += 'value *= 255.0; \n'; - } else if (batchTable._pixelDatatype === PixelDatatype.FLOAT && attribute.componentDatatype === ComponentDatatype.UNSIGNED_BYTE && attribute.normalize) { - glslFunction += 'value /= 255.0; \n'; + /** + * Computes the maximum availability of the entities in the collection. + * If the collection contains a mix of infinitely available data and non-infinite data, + * it will return the interval pertaining to the non-infinite data only. If all + * data is infinite, an infinite interval will be returned. + * + * @returns {TimeInterval} The availability of entities in the collection. + */ + EntityCollection.prototype.computeAvailability = function() { + var startTime = Iso8601.MAXIMUM_VALUE; + var stopTime = Iso8601.MINIMUM_VALUE; + var entities = this._entities.values; + for (var i = 0, len = entities.length; i < len; i++) { + var entity = entities[i]; + var availability = entity.availability; + if (defined(availability)) { + var start = availability.start; + var stop = availability.stop; + if (JulianDate.lessThan(start, startTime) && !start.equals(Iso8601.MINIMUM_VALUE)) { + startTime = start; + } + if (JulianDate.greaterThan(stop, stopTime) && !stop.equals(Iso8601.MAXIMUM_VALUE)) { + stopTime = stop; + } + } } - glslFunction += - ' return value; \n' + - '} \n'; - return glslFunction; - } + if (Iso8601.MAXIMUM_VALUE.equals(startTime)) { + startTime = Iso8601.MINIMUM_VALUE; + } + if (Iso8601.MINIMUM_VALUE.equals(stopTime)) { + stopTime = Iso8601.MAXIMUM_VALUE; + } + return new TimeInterval({ + start : startTime, + stop : stopTime + }); + }; /** - * Gets a function that will update a vertex shader to contain functions for looking up values in the batch table. + * Add an entity to the collection. * - * @returns {BatchTable~updateVertexShaderSourceCallback} A callback for updating a vertex shader source. + * @param {Entity} entity The entity to be added. + * @returns {Entity} The entity that was added. + * @exception {DeveloperError} An entity with <entity.id> already exists in this collection. */ - BatchTable.prototype.getVertexShaderCallback = function() { - var attributes = this._attributes; - if (attributes.length === 0) { - return function(source) { - return source; - }; + EntityCollection.prototype.add = function(entity) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); + } + + if (!(entity instanceof Entity)) { + entity = new Entity(entity); } - var batchTableShader = 'uniform sampler2D batchTexture; \n'; - batchTableShader += getGlslComputeSt(this) + '\n'; - batchTableShader += getGlslUnpackFloat(this) + '\n'; + var id = entity.id; + var entities = this._entities; + if (entities.contains(id)) { + throw new RuntimeError('An entity with id ' + id + ' already exists in this collection.'); + } - var length = attributes.length; - for (var i = 0; i < length; ++i) { - batchTableShader += getGlslAttributeFunction(this, i); + entity.entityCollection = this; + entities.set(id, entity); + + if (!this._removedEntities.remove(id)) { + this._addedEntities.set(id, entity); } + entity.definitionChanged.addEventListener(EntityCollection.prototype._onEntityDefinitionChanged, this); - return function(source) { - var mainIndex = source.indexOf('void main'); - var beforeMain = source.substring(0, mainIndex); - var afterMain = source.substring(mainIndex); - return beforeMain + '\n' + batchTableShader + '\n' + afterMain; - }; + fireChangedEvent(this); + return entity; }; /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * Removes an entity from the collection. * - * @see BatchTable#destroy + * @param {Entity} entity The entity to be removed. + * @returns {Boolean} true if the item was removed, false if it did not exist in the collection. */ - BatchTable.prototype.isDestroyed = function() { - return false; + EntityCollection.prototype.remove = function(entity) { + if (!defined(entity)) { + return false; + } + return this.removeById(entity.id); }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * Returns true if the provided entity is in this collection, false otherwise. * - * @see BatchTable#isDestroyed + * @param {Entity} entity The entity. + * @returns {Boolean} true if the provided entity is in this collection, false otherwise. */ - BatchTable.prototype.destroy = function() { - this._texture = this._texture && this._texture.destroy(); - return destroyObject(this); + EntityCollection.prototype.contains = function(entity) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + return this._entities.get(entity.id) === entity; }; /** - * A callback for updating uniform maps. - * @callback BatchTable~updateUniformMapCallback + * Removes an entity with the provided id from the collection. * - * @param {Object} uniformMap The uniform map. - * @returns {Object} The new uniform map with properties for retrieving values from the batch table. + * @param {String} id The id of the entity to remove. + * @returns {Boolean} true if the item was removed, false if no item with the provided id existed in the collection. */ + EntityCollection.prototype.removeById = function(id) { + if (!defined(id)) { + return false; + } - /** - * A callback for updating a vertex shader source. - * @callback BatchTable~updateVertexShaderSourceCallback - * - * @param {String} vertexShaderSource The vertex shader source. - * @returns {String} The new vertex shader source with the functions for retrieving batch table values injected. - */ + var entities = this._entities; + var entity = entities.get(id); + if (!this._entities.remove(id)) { + return false; + } - return BatchTable; -}); + if (!this._addedEntities.remove(id)) { + this._removedEntities.set(id, entity); + this._changedEntities.remove(id); + } + this._entities.remove(id); + entity.definitionChanged.removeEventListener(EntityCollection.prototype._onEntityDefinitionChanged, this); + fireChangedEvent(this); -define('Scene/DepthFunction',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + return true; + }; /** - * Determines the function used to compare two depths for the depth test. - * - * @exports DepthFunction + * Removes all Entities from the collection. */ - var DepthFunction = { - /** - * The depth test never passes. - * - * @type {Number} - * @constant - */ - NEVER : WebGLConstants.NEVER, - - /** - * The depth test passes if the incoming depth is less than the stored depth. - * - * @type {Number} - * @constant - */ - LESS : WebGLConstants.LESS, + EntityCollection.prototype.removeAll = function() { + //The event should only contain items added before events were suspended + //and the contents of the collection. + var entities = this._entities; + var entitiesLength = entities.length; + var array = entities.values; - /** - * The depth test passes if the incoming depth is equal to the stored depth. - * - * @type {Number} - * @constant - */ - EQUAL : WebGLConstants.EQUAL, + var addedEntities = this._addedEntities; + var removed = this._removedEntities; - /** - * The depth test passes if the incoming depth is less than or equal to the stored depth. - * - * @type {Number} - * @constant - */ - LESS_OR_EQUAL : WebGLConstants.LEQUAL, + for (var i = 0; i < entitiesLength; i++) { + var existingItem = array[i]; + var existingItemId = existingItem.id; + var addedItem = addedEntities.get(existingItemId); + if (!defined(addedItem)) { + existingItem.definitionChanged.removeEventListener(EntityCollection.prototype._onEntityDefinitionChanged, this); + removed.set(existingItemId, existingItem); + } + } - /** - * The depth test passes if the incoming depth is greater than the stored depth. - * - * @type {Number} - * @constant - */ - GREATER : WebGLConstants.GREATER, + entities.removeAll(); + addedEntities.removeAll(); + this._changedEntities.removeAll(); + fireChangedEvent(this); + }; - /** - * The depth test passes if the incoming depth is not equal to the stored depth. - * - * @type {Number} - * @constant - */ - NOT_EQUAL : WebGLConstants.NOTEQUAL, + /** + * Gets an entity with the specified id. + * + * @param {String} id The id of the entity to retrieve. + * @returns {Entity} The entity with the provided id or undefined if the id did not exist in the collection. + */ + EntityCollection.prototype.getById = function(id) { + if (!defined(id)) { + throw new DeveloperError('id is required.'); + } + + return this._entities.get(id); + }; - /** - * The depth test passes if the incoming depth is greater than or equal to the stored depth. - * - * @type {Number} - * @constant - */ - GREATER_OR_EQUAL : WebGLConstants.GEQUAL, + /** + * Gets an entity with the specified id or creates it and adds it to the collection if it does not exist. + * + * @param {String} id The id of the entity to retrieve or create. + * @returns {Entity} The new or existing object. + */ + EntityCollection.prototype.getOrCreateEntity = function(id) { + if (!defined(id)) { + throw new DeveloperError('id is required.'); + } + + var entity = this._entities.get(id); + if (!defined(entity)) { + entityOptionsScratch.id = id; + entity = new Entity(entityOptionsScratch); + this.add(entity); + } + return entity; + }; - /** - * The depth test always passes. - * - * @type {Number} - * @constant - */ - ALWAYS : WebGLConstants.ALWAYS + EntityCollection.prototype._onEntityDefinitionChanged = function(entity) { + var id = entity.id; + if (!this._addedEntities.contains(id)) { + this._changedEntities.set(id, entity); + } + fireChangedEvent(this); }; - return freezeObject(DepthFunction); + return EntityCollection; }); -define('Scene/PrimitivePipeline',[ - '../Core/BoundingSphere', - '../Core/ComponentDatatype', +define('DataSources/CompositeEntityCollection',[ + '../Core/createGuid', '../Core/defined', + '../Core/defineProperties', '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/FeatureDetection', - '../Core/GeographicProjection', - '../Core/Geometry', - '../Core/GeometryAttribute', - '../Core/GeometryAttributes', - '../Core/GeometryPipeline', - '../Core/IndexDatatype', - '../Core/Matrix4', - '../Core/WebMercatorProjection' + '../Core/Math', + './Entity', + './EntityCollection' ], function( - BoundingSphere, - ComponentDatatype, + createGuid, defined, + defineProperties, DeveloperError, - Ellipsoid, - FeatureDetection, - GeographicProjection, - Geometry, - GeometryAttribute, - GeometryAttributes, - GeometryPipeline, - IndexDatatype, - Matrix4, - WebMercatorProjection) { + CesiumMath, + Entity, + EntityCollection) { 'use strict'; - // Bail out if the browser doesn't support typed arrays, to prevent the setup function - // from failing, since we won't be able to create a WebGL context anyway. - if (!FeatureDetection.supportsTypedArrays()) { - return {}; - } - - function transformToWorldCoordinates(instances, primitiveModelMatrix, scene3DOnly) { - var toWorld = !scene3DOnly; - var length = instances.length; - var i; - - if (!toWorld && (length > 1)) { - var modelMatrix = instances[0].modelMatrix; - - for (i = 1; i < length; ++i) { - if (!Matrix4.equals(modelMatrix, instances[i].modelMatrix)) { - toWorld = true; - break; - } - } - } + var entityOptionsScratch = { + id : undefined + }; + var entityIdScratch = new Array(2); - if (toWorld) { - for (i = 0; i < length; ++i) { - if (defined(instances[i].geometry)) { - GeometryPipeline.transformToWorldCoordinates(instances[i]); - } - } - } else { - // Leave geometry in local coordinate system; auto update model-matrix. - Matrix4.multiplyTransformation(primitiveModelMatrix, instances[0].modelMatrix, primitiveModelMatrix); + function clean(entity) { + var propertyNames = entity.propertyNames; + var propertyNamesLength = propertyNames.length; + for (var i = 0; i < propertyNamesLength; i++) { + entity[propertyNames[i]] = undefined; } } - function addGeometryBatchId(geometry, batchId) { - var attributes = geometry.attributes; - var positionAttr = attributes.position; - var numberOfComponents = positionAttr.values.length / positionAttr.componentsPerAttribute; - - attributes.batchId = new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 1, - values : new Float32Array(numberOfComponents) - }); - - var values = attributes.batchId.values; - for (var j = 0; j < numberOfComponents; ++j) { - values[j] = batchId; - } + function subscribeToEntity(that, eventHash, collectionId, entity) { + entityIdScratch[0] = collectionId; + entityIdScratch[1] = entity.id; + eventHash[JSON.stringify(entityIdScratch)] = entity.definitionChanged.addEventListener(CompositeEntityCollection.prototype._onDefinitionChanged, that); } - function addBatchIds(instances) { - var length = instances.length; - - for (var i = 0; i < length; ++i) { - var instance = instances[i]; - if (defined(instance.geometry)) { - addGeometryBatchId(instance.geometry, i); - } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { - addGeometryBatchId(instance.westHemisphereGeometry, i); - addGeometryBatchId(instance.eastHemisphereGeometry, i); - } - } + function unsubscribeFromEntity(that, eventHash, collectionId, entity) { + entityIdScratch[0] = collectionId; + entityIdScratch[1] = entity.id; + var id = JSON.stringify(entityIdScratch); + eventHash[id](); + eventHash[id] = undefined; } - function geometryPipeline(parameters) { - var instances = parameters.instances; - var projection = parameters.projection; - var uintIndexSupport = parameters.elementIndexUintSupported; - var scene3DOnly = parameters.scene3DOnly; - var vertexCacheOptimize = parameters.vertexCacheOptimize; - var compressVertices = parameters.compressVertices; - var modelMatrix = parameters.modelMatrix; + function recomposite(that) { + that._shouldRecomposite = true; + if (that._suspendCount !== 0) { + return; + } - var i; - var geometry; - var primitiveType; - var length = instances.length; + var collections = that._collections; + var collectionsLength = collections.length; - for (i = 0 ; i < length; ++i) { - if (defined(instances[i].geometry)) { - primitiveType = instances[i].geometry.primitiveType; - break; - } - } + var collectionsCopy = that._collectionsCopy; + var collectionsCopyLength = collectionsCopy.length; - for (i = 1; i < length; ++i) { - if (defined(instances[i].geometry) && instances[i].geometry.primitiveType !== primitiveType) { - throw new DeveloperError('All instance geometries must have the same primitiveType.'); - } - } - - // Unify to world coordinates before combining. - transformToWorldCoordinates(instances, modelMatrix, scene3DOnly); + var i; + var entity; + var entities; + var iEntities; + var collection; + var composite = that._composite; + var newEntities = new EntityCollection(that); + var eventHash = that._eventHash; + var collectionId; - // Clip to IDL - if (!scene3DOnly) { - for (i = 0; i < length; ++i) { - if (defined(instances[i].geometry)) { - GeometryPipeline.splitLongitude(instances[i]); - } + for (i = 0; i < collectionsCopyLength; i++) { + collection = collectionsCopy[i]; + collection.collectionChanged.removeEventListener(CompositeEntityCollection.prototype._onCollectionChanged, that); + entities = collection.values; + collectionId = collection.id; + for (iEntities = entities.length - 1; iEntities > -1; iEntities--) { + entity = entities[iEntities]; + unsubscribeFromEntity(that, eventHash, collectionId, entity); } } - addBatchIds(instances); + for (i = collectionsLength - 1; i >= 0; i--) { + collection = collections[i]; + collection.collectionChanged.addEventListener(CompositeEntityCollection.prototype._onCollectionChanged, that); - // Optimize for vertex shader caches - if (vertexCacheOptimize) { - for (i = 0; i < length; ++i) { - var instance = instances[i]; - if (defined(instance.geometry)) { - GeometryPipeline.reorderForPostVertexCache(instance.geometry); - GeometryPipeline.reorderForPreVertexCache(instance.geometry); - } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { - GeometryPipeline.reorderForPostVertexCache(instance.westHemisphereGeometry); - GeometryPipeline.reorderForPreVertexCache(instance.westHemisphereGeometry); + //Merge all of the existing entities. + entities = collection.values; + collectionId = collection.id; + for (iEntities = entities.length - 1; iEntities > -1; iEntities--) { + entity = entities[iEntities]; + subscribeToEntity(that, eventHash, collectionId, entity); - GeometryPipeline.reorderForPostVertexCache(instance.eastHemisphereGeometry); - GeometryPipeline.reorderForPreVertexCache(instance.eastHemisphereGeometry); + var compositeEntity = newEntities.getById(entity.id); + if (!defined(compositeEntity)) { + compositeEntity = composite.getById(entity.id); + if (!defined(compositeEntity)) { + entityOptionsScratch.id = entity.id; + compositeEntity = new Entity(entityOptionsScratch); + } else { + clean(compositeEntity); + } + newEntities.add(compositeEntity); } + compositeEntity.merge(entity); } } + that._collectionsCopy = collections.slice(0); - // Combine into single geometry for better rendering performance. - var geometries = GeometryPipeline.combineInstances(instances); - - length = geometries.length; - for (i = 0; i < length; ++i) { - geometry = geometries[i]; - - // Split positions for GPU RTE - var attributes = geometry.attributes; - var name; - if (!scene3DOnly) { - for (name in attributes) { - if (attributes.hasOwnProperty(name) && attributes[name].componentDatatype === ComponentDatatype.DOUBLE) { - var name3D = name + '3D'; - var name2D = name + '2D'; + composite.suspendEvents(); + composite.removeAll(); + var newEntitiesArray = newEntities.values; + for (i = 0; i < newEntitiesArray.length; i++) { + composite.add(newEntitiesArray[i]); + } + composite.resumeEvents(); + } - // Compute 2D positions - GeometryPipeline.projectTo2D(geometry, name, name3D, name2D, projection); - if (defined(geometry.boundingSphere) && name === 'position') { - geometry.boundingSphereCV = BoundingSphere.fromVertices(geometry.attributes.position2D.values); - } + /** + * Non-destructively composites multiple {@link EntityCollection} instances into a single collection. + * If a Entity with the same ID exists in multiple collections, it is non-destructively + * merged into a single new entity instance. If an entity has the same property in multiple + * collections, the property of the Entity in the last collection of the list it + * belongs to is used. CompositeEntityCollection can be used almost anywhere that a + * EntityCollection is used. + * + * @alias CompositeEntityCollection + * @constructor + * + * @param {EntityCollection[]} [collections] The initial list of EntityCollection instances to merge. + * @param {DataSource|CompositeEntityCollection} [owner] The data source (or composite entity collection) which created this collection. + */ + function CompositeEntityCollection(collections, owner) { + this._owner = owner; + this._composite = new EntityCollection(this); + this._suspendCount = 0; + this._collections = defined(collections) ? collections.slice() : []; + this._collectionsCopy = []; + this._id = createGuid(); + this._eventHash = {}; + recomposite(this); + this._shouldRecomposite = false; + } - GeometryPipeline.encodeAttribute(geometry, name3D, name3D + 'High', name3D + 'Low'); - GeometryPipeline.encodeAttribute(geometry, name2D, name2D + 'High', name2D + 'Low'); - } - } - } else { - for (name in attributes) { - if (attributes.hasOwnProperty(name) && attributes[name].componentDatatype === ComponentDatatype.DOUBLE) { - GeometryPipeline.encodeAttribute(geometry, name, name + '3DHigh', name + '3DLow'); - } - } + defineProperties(CompositeEntityCollection.prototype, { + /** + * Gets the event that is fired when entities are added or removed from the collection. + * The generated event is a {@link EntityCollection.collectionChangedEventCallback}. + * @memberof CompositeEntityCollection.prototype + * @readonly + * @type {Event} + */ + collectionChanged : { + get : function() { + return this._composite._collectionChanged; } - - // oct encode and pack normals, compress texture coordinates - if (compressVertices) { - GeometryPipeline.compressVertices(geometry); + }, + /** + * Gets a globally unique identifier for this collection. + * @memberof CompositeEntityCollection.prototype + * @readonly + * @type {String} + */ + id : { + get : function() { + return this._id; + } + }, + /** + * Gets the array of Entity instances in the collection. + * This array should not be modified directly. + * @memberof CompositeEntityCollection.prototype + * @readonly + * @type {Entity[]} + */ + values : { + get : function() { + return this._composite.values; + } + }, + /** + * Gets the owner of this composite entity collection, ie. the data source or composite entity collection which created it. + * @memberof CompositeEntityCollection.prototype + * @readonly + * @type {DataSource|CompositeEntityCollection} + */ + owner : { + get : function() { + return this._owner; } } + }); - if (!uintIndexSupport) { - // Break into multiple geometries to fit within unsigned short indices if needed - var splitGeometries = []; - length = geometries.length; - for (i = 0; i < length; ++i) { - geometry = geometries[i]; - splitGeometries = splitGeometries.concat(GeometryPipeline.fitToUnsignedShortIndices(geometry)); + /** + * Adds a collection to the composite. + * + * @param {EntityCollection} collection the collection to add. + * @param {Number} [index] the index to add the collection at. If omitted, the collection will + * added on top of all existing collections. + * + * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of collections. + */ + CompositeEntityCollection.prototype.addCollection = function(collection, index) { + var hasIndex = defined(index); + if (!defined(collection)) { + throw new DeveloperError('collection is required.'); + } + if (hasIndex) { + if (index < 0) { + throw new DeveloperError('index must be greater than or equal to zero.'); + } else if (index > this._collections.length) { + throw new DeveloperError('index must be less than or equal to the number of collections.'); } - - geometries = splitGeometries; } - - return geometries; - } - - function createPickOffsets(instances, geometryName, geometries, pickOffsets) { - var offset; - var indexCount; - var geometryIndex; - - var offsetIndex = pickOffsets.length - 1; - if (offsetIndex >= 0) { - var pickOffset = pickOffsets[offsetIndex]; - offset = pickOffset.offset + pickOffset.count; - geometryIndex = pickOffset.index; - indexCount = geometries[geometryIndex].indices.length; + + if (!hasIndex) { + index = this._collections.length; + this._collections.push(collection); } else { - offset = 0; - geometryIndex = 0; - indexCount = geometries[geometryIndex].indices.length; + this._collections.splice(index, 0, collection); } - var length = instances.length; - for (var i = 0; i < length; ++i) { - var instance = instances[i]; - var geometry = instance[geometryName]; - if (!defined(geometry)) { - continue; - } - - var count = geometry.indices.length; - - if (offset + count > indexCount) { - offset = 0; - indexCount = geometries[++geometryIndex].indices.length; - } + recomposite(this); + }; - pickOffsets.push({ - index : geometryIndex, - offset : offset, - count : count - }); - offset += count; + /** + * Removes a collection from this composite, if present. + * + * @param {EntityCollection} collection The collection to remove. + * @returns {Boolean} true if the collection was in the composite and was removed, + * false if the collection was not in the composite. + */ + CompositeEntityCollection.prototype.removeCollection = function(collection) { + var index = this._collections.indexOf(collection); + if (index !== -1) { + this._collections.splice(index, 1); + recomposite(this); + return true; } - } - - function createInstancePickOffsets(instances, geometries) { - var pickOffsets = []; - createPickOffsets(instances, 'geometry', geometries, pickOffsets); - createPickOffsets(instances, 'westHemisphereGeometry', geometries, pickOffsets); - createPickOffsets(instances, 'eastHemisphereGeometry', geometries, pickOffsets); - return pickOffsets; - } + return false; + }; /** - * @private + * Removes all collections from this composite. */ - var PrimitivePipeline = {}; + CompositeEntityCollection.prototype.removeAllCollections = function() { + this._collections.length = 0; + recomposite(this); + }; /** - * @private + * Checks to see if the composite contains a given collection. + * + * @param {EntityCollection} collection the collection to check for. + * @returns {Boolean} true if the composite contains the collection, false otherwise. */ - PrimitivePipeline.combineGeometry = function(parameters) { - var geometries; - var attributeLocations; - var instances = parameters.instances; - var length = instances.length; - var pickOffsets; + CompositeEntityCollection.prototype.containsCollection = function(collection) { + return this._collections.indexOf(collection) !== -1; + }; - if (length > 0) { - geometries = geometryPipeline(parameters); - if (geometries.length > 0) { - attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); - if (parameters.createPickOffsets) { - pickOffsets = createInstancePickOffsets(instances, geometries); - } - } - } + /** + * Returns true if the provided entity is in this collection, false otherwise. + * + * @param {Entity} entity The entity. + * @returns {Boolean} true if the provided entity is in this collection, false otherwise. + */ + CompositeEntityCollection.prototype.contains = function(entity) { + return this._composite.contains(entity); + }; - var boundingSpheres = new Array(length); - var boundingSpheresCV = new Array(length); - for (var i = 0; i < length; ++i) { - var instance = instances[i]; - var geometry = instance.geometry; - if (defined(geometry)) { - boundingSpheres[i] = geometry.boundingSphere; - boundingSpheresCV[i] = geometry.boundingSphereCV; - } + /** + * Determines the index of a given collection in the composite. + * + * @param {EntityCollection} collection The collection to find the index of. + * @returns {Number} The index of the collection in the composite, or -1 if the collection does not exist in the composite. + */ + CompositeEntityCollection.prototype.indexOfCollection = function(collection) { + return this._collections.indexOf(collection); + }; - var eastHemisphereGeometry = instance.eastHemisphereGeometry; - var westHemisphereGeometry = instance.westHemisphereGeometry; - if (defined(eastHemisphereGeometry) && defined(westHemisphereGeometry)) { - if (defined(eastHemisphereGeometry.boundingSphere) && defined(westHemisphereGeometry.boundingSphere)) { - boundingSpheres[i] = BoundingSphere.union(eastHemisphereGeometry.boundingSphere, westHemisphereGeometry.boundingSphere); - } - if (defined(eastHemisphereGeometry.boundingSphereCV) && defined(westHemisphereGeometry.boundingSphereCV)) { - boundingSpheresCV[i] = BoundingSphere.union(eastHemisphereGeometry.boundingSphereCV, westHemisphereGeometry.boundingSphereCV); - } - } + /** + * Gets a collection by index from the composite. + * + * @param {Number} index the index to retrieve. + */ + CompositeEntityCollection.prototype.getCollection = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.', 'index'); } - - return { - geometries : geometries, - modelMatrix : parameters.modelMatrix, - attributeLocations : attributeLocations, - pickOffsets : pickOffsets, - boundingSpheres : boundingSpheres, - boundingSpheresCV : boundingSpheresCV - }; + + return this._collections[index]; }; - function transferGeometry(geometry, transferableObjects) { - var attributes = geometry.attributes; - for ( var name in attributes) { - if (attributes.hasOwnProperty(name)) { - var attribute = attributes[name]; - - if (defined(attribute) && defined(attribute.values)) { - transferableObjects.push(attribute.values.buffer); - } - } - } + /** + * Gets the number of collections in this composite. + */ + CompositeEntityCollection.prototype.getCollectionsLength = function() { + return this._collections.length; + }; - if (defined(geometry.indices)) { - transferableObjects.push(geometry.indices.buffer); + function getCollectionIndex(collections, collection) { + if (!defined(collection)) { + throw new DeveloperError('collection is required.'); } - } + + var index = collections.indexOf(collection); - function transferGeometries(geometries, transferableObjects) { - var length = geometries.length; - for (var i = 0; i < length; ++i) { - transferGeometry(geometries[i], transferableObjects); + if (index === -1) { + throw new DeveloperError('collection is not in this composite.'); } + + return index; } - // This function was created by simplifying packCreateGeometryResults into a count-only operation. - function countCreateGeometryResults(items) { - var count = 1; - var length = items.length; - for (var i = 0; i < length; i++) { - var geometry = items[i]; - ++count; - - if (!defined(geometry)) { - continue; - } - - var attributes = geometry.attributes; - - count += 6 + 2 * BoundingSphere.packedLength + (defined(geometry.indices) ? geometry.indices.length : 0); + function swapCollections(composite, i, j) { + var arr = composite._collections; + i = CesiumMath.clamp(i, 0, arr.length - 1); + j = CesiumMath.clamp(j, 0, arr.length - 1); - for ( var property in attributes) { - if (attributes.hasOwnProperty(property) && defined(attributes[property])) { - var attribute = attributes[property]; - count += 5 + attribute.values.length; - } - } + if (i === j) { + return; } - return count; + var temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + + recomposite(composite); } /** - * @private + * Raises a collection up one position in the composite. + * + * @param {EntityCollection} collection the collection to move. + * + * @exception {DeveloperError} collection is not in this composite. */ - PrimitivePipeline.packCreateGeometryResults = function(items, transferableObjects) { - var packedData = new Float64Array(countCreateGeometryResults(items)); - var stringTable = []; - var stringHash = {}; - - var length = items.length; - var count = 0; - packedData[count++] = length; - for (var i = 0; i < length; i++) { - var geometry = items[i]; - - var validGeometry = defined(geometry); - packedData[count++] = validGeometry ? 1.0 : 0.0; - - if (!validGeometry) { - continue; - } - - packedData[count++] = geometry.primitiveType; - packedData[count++] = geometry.geometryType; - - var validBoundingSphere = defined(geometry.boundingSphere) ? 1.0 : 0.0; - packedData[count++] = validBoundingSphere; - if (validBoundingSphere) { - BoundingSphere.pack(geometry.boundingSphere, packedData, count); - } + CompositeEntityCollection.prototype.raiseCollection = function(collection) { + var index = getCollectionIndex(this._collections, collection); + swapCollections(this, index, index + 1); + }; - count += BoundingSphere.packedLength; + /** + * Lowers a collection down one position in the composite. + * + * @param {EntityCollection} collection the collection to move. + * + * @exception {DeveloperError} collection is not in this composite. + */ + CompositeEntityCollection.prototype.lowerCollection = function(collection) { + var index = getCollectionIndex(this._collections, collection); + swapCollections(this, index, index - 1); + }; - var validBoundingSphereCV = defined(geometry.boundingSphereCV) ? 1.0 : 0.0; - packedData[count++] = validBoundingSphereCV; - if (validBoundingSphereCV) { - BoundingSphere.pack(geometry.boundingSphereCV, packedData, count); - } + /** + * Raises a collection to the top of the composite. + * + * @param {EntityCollection} collection the collection to move. + * + * @exception {DeveloperError} collection is not in this composite. + */ + CompositeEntityCollection.prototype.raiseCollectionToTop = function(collection) { + var index = getCollectionIndex(this._collections, collection); + if (index === this._collections.length - 1) { + return; + } + this._collections.splice(index, 1); + this._collections.push(collection); - count += BoundingSphere.packedLength; + recomposite(this); + }; - var attributes = geometry.attributes; - var attributesToWrite = []; - for ( var property in attributes) { - if (attributes.hasOwnProperty(property) && defined(attributes[property])) { - attributesToWrite.push(property); - if (!defined(stringHash[property])) { - stringHash[property] = stringTable.length; - stringTable.push(property); - } - } - } + /** + * Lowers a collection to the bottom of the composite. + * + * @param {EntityCollection} collection the collection to move. + * + * @exception {DeveloperError} collection is not in this composite. + */ + CompositeEntityCollection.prototype.lowerCollectionToBottom = function(collection) { + var index = getCollectionIndex(this._collections, collection); + if (index === 0) { + return; + } + this._collections.splice(index, 1); + this._collections.splice(0, 0, collection); - packedData[count++] = attributesToWrite.length; - for (var q = 0; q < attributesToWrite.length; q++) { - var name = attributesToWrite[q]; - var attribute = attributes[name]; - packedData[count++] = stringHash[name]; - packedData[count++] = attribute.componentDatatype; - packedData[count++] = attribute.componentsPerAttribute; - packedData[count++] = attribute.normalize ? 1 : 0; - packedData[count++] = attribute.values.length; - packedData.set(attribute.values, count); - count += attribute.values.length; - } + recomposite(this); + }; - var indicesLength = defined(geometry.indices) ? geometry.indices.length : 0; - packedData[count++] = indicesLength; + /** + * Prevents {@link EntityCollection#collectionChanged} events from being raised + * until a corresponding call is made to {@link EntityCollection#resumeEvents}, at which + * point a single event will be raised that covers all suspended operations. + * This allows for many items to be added and removed efficiently. + * While events are suspended, recompositing of the collections will + * also be suspended, as this can be a costly operation. + * This function can be safely called multiple times as long as there + * are corresponding calls to {@link EntityCollection#resumeEvents}. + */ + CompositeEntityCollection.prototype.suspendEvents = function() { + this._suspendCount++; + this._composite.suspendEvents(); + }; - if (indicesLength > 0) { - packedData.set(geometry.indices, count); - count += indicesLength; - } + /** + * Resumes raising {@link EntityCollection#collectionChanged} events immediately + * when an item is added or removed. Any modifications made while while events were suspended + * will be triggered as a single event when this function is called. This function also ensures + * the collection is recomposited if events are also resumed. + * This function is reference counted and can safely be called multiple times as long as there + * are corresponding calls to {@link EntityCollection#resumeEvents}. + * + * @exception {DeveloperError} resumeEvents can not be called before suspendEvents. + */ + CompositeEntityCollection.prototype.resumeEvents = function() { + if (this._suspendCount === 0) { + throw new DeveloperError('resumeEvents can not be called before suspendEvents.'); + } + + this._suspendCount--; + // recomposite before triggering events (but only if required for performance) that might depend on a composited collection + if (this._shouldRecomposite && this._suspendCount === 0) { + recomposite(this); + this._shouldRecomposite = false; } - transferableObjects.push(packedData.buffer); + this._composite.resumeEvents(); + }; - return { - stringTable : stringTable, - packedData : packedData - }; + /** + * Computes the maximum availability of the entities in the collection. + * If the collection contains a mix of infinitely available data and non-infinite data, + * It will return the interval pertaining to the non-infinite data only. If all + * data is infinite, an infinite interval will be returned. + * + * @returns {TimeInterval} The availability of entities in the collection. + */ + CompositeEntityCollection.prototype.computeAvailability = function() { + return this._composite.computeAvailability(); }; /** - * @private + * Gets an entity with the specified id. + * + * @param {String} id The id of the entity to retrieve. + * @returns {Entity} The entity with the provided id or undefined if the id did not exist in the collection. */ - PrimitivePipeline.unpackCreateGeometryResults = function(createGeometryResult) { - var stringTable = createGeometryResult.stringTable; - var packedGeometry = createGeometryResult.packedData; + CompositeEntityCollection.prototype.getById = function(id) { + return this._composite.getById(id); + }; + + CompositeEntityCollection.prototype._onCollectionChanged = function(collection, added, removed) { + var collections = this._collectionsCopy; + var collectionsLength = collections.length; + var composite = this._composite; + composite.suspendEvents(); var i; - var result = new Array(packedGeometry[0]); - var resultIndex = 0; + var q; + var entity; + var compositeEntity; + var removedLength = removed.length; + var eventHash = this._eventHash; + var collectionId = collection.id; + for (i = 0; i < removedLength; i++) { + var removedEntity = removed[i]; + unsubscribeFromEntity(this, eventHash, collectionId, removedEntity); - var packedGeometryIndex = 1; - while (packedGeometryIndex < packedGeometry.length) { - var valid = packedGeometry[packedGeometryIndex++] === 1.0; - if (!valid) { - result[resultIndex++] = undefined; - continue; + var removedId = removedEntity.id; + //Check if the removed entity exists in any of the remaining collections + //If so, we clean and remerge it. + for (q = collectionsLength - 1; q >= 0; q--) { + entity = collections[q].getById(removedId); + if (defined(entity)) { + if (!defined(compositeEntity)) { + compositeEntity = composite.getById(removedId); + clean(compositeEntity); + } + compositeEntity.merge(entity); + } } - - var primitiveType = packedGeometry[packedGeometryIndex++]; - var geometryType = packedGeometry[packedGeometryIndex++]; - - var boundingSphere; - var boundingSphereCV; - - var validBoundingSphere = packedGeometry[packedGeometryIndex++] === 1.0; - if (validBoundingSphere) { - boundingSphere = BoundingSphere.unpack(packedGeometry, packedGeometryIndex); + //We never retrieved the compositeEntity, which means it no longer + //exists in any of the collections, remove it from the composite. + if (!defined(compositeEntity)) { + composite.removeById(removedId); } + compositeEntity = undefined; + } - packedGeometryIndex += BoundingSphere.packedLength; + var addedLength = added.length; + for (i = 0; i < addedLength; i++) { + var addedEntity = added[i]; + subscribeToEntity(this, eventHash, collectionId, addedEntity); - var validBoundingSphereCV = packedGeometry[packedGeometryIndex++] === 1.0; - if (validBoundingSphereCV) { - boundingSphereCV = BoundingSphere.unpack(packedGeometry, packedGeometryIndex); + var addedId = addedEntity.id; + //We know the added entity exists in at least one collection, + //but we need to check all collections and re-merge in order + //to maintain the priority of properties. + for (q = collectionsLength - 1; q >= 0; q--) { + entity = collections[q].getById(addedId); + if (defined(entity)) { + if (!defined(compositeEntity)) { + compositeEntity = composite.getById(addedId); + if (!defined(compositeEntity)) { + entityOptionsScratch.id = addedId; + compositeEntity = new Entity(entityOptionsScratch); + composite.add(compositeEntity); + } else { + clean(compositeEntity); + } + } + compositeEntity.merge(entity); + } } + compositeEntity = undefined; + } - packedGeometryIndex += BoundingSphere.packedLength; - - var length; - var values; - var componentsPerAttribute; - var attributes = new GeometryAttributes(); - var numAttributes = packedGeometry[packedGeometryIndex++]; - for (i = 0; i < numAttributes; i++) { - var name = stringTable[packedGeometry[packedGeometryIndex++]]; - var componentDatatype = packedGeometry[packedGeometryIndex++]; - componentsPerAttribute = packedGeometry[packedGeometryIndex++]; - var normalize = packedGeometry[packedGeometryIndex++] !== 0; - - length = packedGeometry[packedGeometryIndex++]; - values = ComponentDatatype.createTypedArray(componentDatatype, length); - for (var valuesIndex = 0; valuesIndex < length; valuesIndex++) { - values[valuesIndex] = packedGeometry[packedGeometryIndex++]; - } + composite.resumeEvents(); + }; - attributes[name] = new GeometryAttribute({ - componentDatatype : componentDatatype, - componentsPerAttribute : componentsPerAttribute, - normalize : normalize, - values : values - }); - } + CompositeEntityCollection.prototype._onDefinitionChanged = function(entity, propertyName, newValue, oldValue) { + var collections = this._collections; + var composite = this._composite; - var indices; - length = packedGeometry[packedGeometryIndex++]; + var collectionsLength = collections.length; + var id = entity.id; + var compositeEntity = composite.getById(id); + var compositeProperty = compositeEntity[propertyName]; + var newProperty = !defined(compositeProperty); - if (length > 0) { - var numberOfVertices = values.length / componentsPerAttribute; - indices = IndexDatatype.createTypedArray(numberOfVertices, length); - for (i = 0; i < length; i++) { - indices[i] = packedGeometry[packedGeometryIndex++]; + var firstTime = true; + for (var q = collectionsLength - 1; q >= 0; q--) { + var innerEntity = collections[q].getById(entity.id); + if (defined(innerEntity)) { + var property = innerEntity[propertyName]; + if (defined(property)) { + if (firstTime) { + firstTime = false; + //We only want to clone if the property is also mergeable. + //This ensures that leaf properties are referenced and not copied, + //which is the entire point of compositing. + if (defined(property.merge) && defined(property.clone)) { + compositeProperty = property.clone(compositeProperty); + } else { + compositeProperty = property; + break; + } + } + compositeProperty.merge(property); } } - - result[resultIndex++] = new Geometry({ - primitiveType : primitiveType, - geometryType : geometryType, - boundingSphere : boundingSphere, - boundingSphereCV : boundingSphereCV, - indices : indices, - attributes : attributes - }); } - return result; - }; - - function packInstancesForCombine(instances, transferableObjects) { - var length = instances.length; - var packedData = new Float64Array(1 + (length * 16)); - var count = 0; - packedData[count++] = length; - for (var i = 0; i < length; i++) { - var instance = instances[i]; - - Matrix4.pack(instance.modelMatrix, packedData, count); - count += Matrix4.packedLength; + if (newProperty && compositeEntity.propertyNames.indexOf(propertyName) === -1) { + compositeEntity.addProperty(propertyName); } - transferableObjects.push(packedData.buffer); - return packedData; - } + compositeEntity[propertyName] = compositeProperty; + }; - function unpackInstancesForCombine(data) { - var packedInstances = data; - var result = new Array(packedInstances[0]); - var count = 0; + return CompositeEntityCollection; +}); - var i = 1; - while (i < packedInstances.length) { - var modelMatrix = Matrix4.unpack(packedInstances, i); - i += Matrix4.packedLength; +define('DataSources/CompositeProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/EventHelper', + '../Core/TimeIntervalCollection', + './Property' + ], function( + defined, + defineProperties, + DeveloperError, + Event, + EventHelper, + TimeIntervalCollection, + Property) { + 'use strict'; - result[count++] = { - modelMatrix : modelMatrix - }; + function subscribeAll(property, eventHelper, definitionChanged, intervals) { + function callback() { + definitionChanged.raiseEvent(property); } - - return result; - } - - /** - * @private - */ - PrimitivePipeline.packCombineGeometryParameters = function(parameters, transferableObjects) { - var createGeometryResults = parameters.createGeometryResults; - var length = createGeometryResults.length; - + var items = []; + eventHelper.removeAll(); + var length = intervals.length; for (var i = 0; i < length; i++) { - transferableObjects.push(createGeometryResults[i].packedData.buffer); + var interval = intervals.get(i); + if (defined(interval.data) && items.indexOf(interval.data) === -1) { + eventHelper.add(interval.data.definitionChanged, callback); + } } - - return { - createGeometryResults : parameters.createGeometryResults, - packedInstances : packInstancesForCombine(parameters.instances, transferableObjects), - ellipsoid : parameters.ellipsoid, - isGeographic : parameters.projection instanceof GeographicProjection, - elementIndexUintSupported : parameters.elementIndexUintSupported, - scene3DOnly : parameters.scene3DOnly, - vertexCacheOptimize : parameters.vertexCacheOptimize, - compressVertices : parameters.compressVertices, - modelMatrix : parameters.modelMatrix, - createPickOffsets : parameters.createPickOffsets - }; - }; + } /** - * @private + * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the + * data property of each {@link TimeInterval} is another Property instance which is + * evaluated at the provided time. + * + * @alias CompositeProperty + * @constructor + * + * + * @example + * var constantProperty = ...; + * var sampledProperty = ...; + * + * //Create a composite property from two previously defined properties + * //where the property is valid on August 1st, 2012 and uses a constant + * //property for the first half of the day and a sampled property for the + * //remaining half. + * var composite = new Cesium.CompositeProperty(); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2012-08-01T00:00:00.00Z/2012-08-01T12:00:00.00Z', + * data : constantProperty + * })); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2012-08-01T12:00:00.00Z/2012-08-02T00:00:00.00Z', + * isStartIncluded : false, + * isStopIncluded : false, + * data : sampledProperty + * })); + * + * @see CompositeMaterialProperty + * @see CompositePositionProperty */ - PrimitivePipeline.unpackCombineGeometryParameters = function(packedParameters) { - var instances = unpackInstancesForCombine(packedParameters.packedInstances); - var createGeometryResults = packedParameters.createGeometryResults; - var length = createGeometryResults.length; - var instanceIndex = 0; + function CompositeProperty() { + this._eventHelper = new EventHelper(); + this._definitionChanged = new Event(); + this._intervals = new TimeIntervalCollection(); + this._intervals.changedEvent.addEventListener(CompositeProperty.prototype._intervalsChanged, this); + } - for (var resultIndex = 0; resultIndex < length; resultIndex++) { - var geometries = PrimitivePipeline.unpackCreateGeometryResults(createGeometryResults[resultIndex]); - var geometriesLength = geometries.length; - for (var geometryIndex = 0; geometryIndex < geometriesLength; geometryIndex++) { - var geometry = geometries[geometryIndex]; - var instance = instances[instanceIndex]; - instance.geometry = geometry; - ++instanceIndex; + defineProperties(CompositeProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CompositeProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return this._intervals.isEmpty; } - } - - var ellipsoid = Ellipsoid.clone(packedParameters.ellipsoid); - var projection = packedParameters.isGeographic ? new GeographicProjection(ellipsoid) : new WebMercatorProjection(ellipsoid); - - return { - instances : instances, - ellipsoid : ellipsoid, - projection : projection, - elementIndexUintSupported : packedParameters.elementIndexUintSupported, - scene3DOnly : packedParameters.scene3DOnly, - vertexCacheOptimize : packedParameters.vertexCacheOptimize, - compressVertices : packedParameters.compressVertices, - modelMatrix : Matrix4.clone(packedParameters.modelMatrix), - createPickOffsets : packedParameters.createPickOffsets - }; - }; - - function packBoundingSpheres(boundingSpheres) { - var length = boundingSpheres.length; - var bufferLength = 1 + (BoundingSphere.packedLength + 1) * length; - var buffer = new Float32Array(bufferLength); - - var bufferIndex = 0; - buffer[bufferIndex++] = length; - - for (var i = 0; i < length; ++i) { - var bs = boundingSpheres[i]; - if (!defined(bs)) { - buffer[bufferIndex++] = 0.0; - } else { - buffer[bufferIndex++] = 1.0; - BoundingSphere.pack(boundingSpheres[i], buffer, bufferIndex); + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositeProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - bufferIndex += BoundingSphere.packedLength; - } - - return buffer; - } - - function unpackBoundingSpheres(buffer) { - var result = new Array(buffer[0]); - var count = 0; - - var i = 1; - while (i < buffer.length) { - if (buffer[i++] === 1.0) { - result[count] = BoundingSphere.unpack(buffer, i); + }, + /** + * Gets the interval collection. + * @memberof CompositeProperty.prototype + * + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._intervals; } - ++count; - i += BoundingSphere.packedLength; } - - return result; - } + }); /** - * @private + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. */ - PrimitivePipeline.packCombineGeometryResults = function(results, transferableObjects) { - if (defined(results.geometries)) { - transferGeometries(results.geometries, transferableObjects); + CompositeProperty.prototype.getValue = function(time, result) { + if (!defined(time)) { + throw new DeveloperError('time is required'); } - - var packedBoundingSpheres = packBoundingSpheres(results.boundingSpheres); - var packedBoundingSpheresCV = packBoundingSpheres(results.boundingSpheresCV); - transferableObjects.push(packedBoundingSpheres.buffer, packedBoundingSpheresCV.buffer); - - return { - geometries : results.geometries, - attributeLocations : results.attributeLocations, - modelMatrix : results.modelMatrix, - pickOffsets : results.pickOffsets, - boundingSpheres : packedBoundingSpheres, - boundingSpheresCV : packedBoundingSpheresCV - }; + + var innerProperty = this._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getValue(time, result); + } + return undefined; }; /** - * @private + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - PrimitivePipeline.unpackCombineGeometryResults = function(packedResult) { - return { - geometries : packedResult.geometries, - attributeLocations : packedResult.attributeLocations, - modelMatrix : packedResult.modelMatrix, - pickOffsets : packedResult.pickOffsets, - boundingSpheres : unpackBoundingSpheres(packedResult.boundingSpheres), - boundingSpheresCV : unpackBoundingSpheres(packedResult.boundingSpheresCV) - }; + CompositeProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CompositeProperty && // + this._intervals.equals(other._intervals, Property.equals)); }; - return PrimitivePipeline; -}); - -define('Scene/PrimitiveState',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; - /** * @private */ - var PrimitiveState = { - READY : 0, - CREATING : 1, - CREATED : 2, - COMBINING : 3, - COMBINED : 4, - COMPLETE : 5, - FAILED : 6 + CompositeProperty.prototype._intervalsChanged = function() { + subscribeAll(this, this._eventHelper, this._definitionChanged, this._intervals); + this._definitionChanged.raiseEvent(this); }; - return freezeObject(PrimitiveState); + return CompositeProperty; }); -define('Scene/SceneMode',[ - '../Core/freezeObject' +define('DataSources/CompositeMaterialProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + './CompositeProperty', + './Property' ], function( - freezeObject) { + defined, + defineProperties, + DeveloperError, + Event, + CompositeProperty, + Property) { 'use strict'; /** - * Indicates if the scene is viewed in 3D, 2D, or 2.5D Columbus view. - * - * @exports SceneMode + * A {@link CompositeProperty} which is also a {@link MaterialProperty}. * - * @see Scene#mode + * @alias CompositeMaterialProperty + * @constructor */ - var SceneMode = { - /** - * Morphing between mode, e.g., 3D to 2D. - * - * @type {Number} - * @constant - */ - MORPHING : 0, + function CompositeMaterialProperty() { + this._definitionChanged = new Event(); + this._composite = new CompositeProperty(); + this._composite.definitionChanged.addEventListener(CompositeMaterialProperty.prototype._raiseDefinitionChanged, this); + } + defineProperties(CompositeMaterialProperty.prototype, { /** - * Columbus View mode. A 2.5D perspective view where the map is laid out - * flat and objects with non-zero height are drawn above it. + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CompositeMaterialProperty.prototype * - * @type {Number} - * @constant + * @type {Boolean} + * @readonly */ - COLUMBUS_VIEW : 1, - + isConstant : { + get : function() { + return this._composite.isConstant; + } + }, /** - * 2D mode. The map is viewed top-down with an orthographic projection. + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositeMaterialProperty.prototype * - * @type {Number} - * @constant + * @type {Event} + * @readonly */ - SCENE2D : 2, - + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** - * 3D mode. A traditional 3D perspective view of the globe. + * Gets the interval collection. + * @memberof CompositeMaterialProperty.prototype * - * @type {Number} - * @constant + * @type {TimeIntervalCollection} */ - SCENE3D : 3 + intervals : { + get : function() { + return this._composite._intervals; + } + } + }); + + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + CompositeMaterialProperty.prototype.getType = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required'); + } + + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getType(time); + } + return undefined; }; /** - * Returns the morph time for the given scene mode. + * Gets the value of the property at the provided time. * - * @param {SceneMode} value The scene mode - * @returns {Number} The morph time + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. */ - SceneMode.getMorphTime = function(value) { - if (value === SceneMode.SCENE3D) { - return 1.0; - } else if (value === SceneMode.MORPHING) { - return undefined; + CompositeMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(time)) { + throw new DeveloperError('time is required'); } - return 0.0; + + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getValue(time, result); + } + return undefined; }; - return freezeObject(SceneMode); + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + CompositeMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CompositeMaterialProperty && // + this._composite.equals(other._composite, Property.equals)); + }; + + /** + * @private + */ + CompositeMaterialProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; + + return CompositeMaterialProperty; }); -define('Scene/ShadowMode',[ - '../Core/freezeObject' +define('DataSources/CompositePositionProperty',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame', + './CompositeProperty', + './Property' ], function( - freezeObject) { + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame, + CompositeProperty, + Property) { 'use strict'; /** - * Specifies whether the object casts or receives shadows from each light source when - * shadows are enabled. + * A {@link CompositeProperty} which is also a {@link PositionProperty}. * - * @exports ShadowMode + * @alias CompositePositionProperty + * @constructor + * + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. */ - var ShadowMode = { + function CompositePositionProperty(referenceFrame) { + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + this._definitionChanged = new Event(); + this._composite = new CompositeProperty(); + this._composite.definitionChanged.addEventListener(CompositePositionProperty.prototype._raiseDefinitionChanged, this); + } + + defineProperties(CompositePositionProperty.prototype, { /** - * The object does not cast or receive shadows. + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof CompositePositionProperty.prototype * - * @type {Number} - * @constant + * @type {Boolean} + * @readonly */ - DISABLED : 0, - + isConstant : { + get : function() { + return this._composite.isConstant; + } + }, /** - * The object casts and receives shadows. + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof CompositePositionProperty.prototype * - * @type {Number} - * @constant + * @type {Event} + * @readonly */ - ENABLED : 1, - + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** - * The object casts shadows only. + * Gets the interval collection. + * @memberof CompositePositionProperty.prototype * - * @type {Number} - * @constant + * @type {TimeIntervalCollection} */ - CAST_ONLY : 2, - + intervals : { + get : function() { + return this._composite.intervals; + } + }, /** - * The object receives shadows only. + * Gets or sets the reference frame which this position presents itself as. + * Each PositionProperty making up this object has it's own reference frame, + * so this property merely exposes a "preferred" reference frame for clients + * to use. + * @memberof CompositePositionProperty.prototype * - * @type {Number} - * @constant + * @type {ReferenceFrame} */ - RECEIVE_ONLY : 3, + referenceFrame : { + get : function() { + return this._referenceFrame; + }, + set : function(value) { + this._referenceFrame = value; + } + } + }); - /** - * @private - */ - NUMBER_OF_SHADOW_MODES : 4 + /** + * Gets the value of the property at the provided time in the fixed frame. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + CompositePositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); }; /** - * @private + * Gets the value of the property at the provided time and in the provided reference frame. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. */ - ShadowMode.castShadows = function(shadowMode) { - return (shadowMode === ShadowMode.ENABLED) || (shadowMode === ShadowMode.CAST_ONLY); + CompositePositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + + var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); + if (defined(innerProperty)) { + return innerProperty.getValueInReferenceFrame(time, referenceFrame, result); + } + return undefined; }; /** - * @private + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - ShadowMode.receiveShadows = function(shadowMode) { - return (shadowMode === ShadowMode.ENABLED) || (shadowMode === ShadowMode.RECEIVE_ONLY); + CompositePositionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof CompositePositionProperty && // + this._referenceFrame === other._referenceFrame && // + this._composite.equals(other._composite, Property.equals)); }; /** * @private */ - ShadowMode.fromCastReceive = function(castShadows, receiveShadows) { - if (castShadows && receiveShadows) { - return ShadowMode.ENABLED; - } else if (castShadows) { - return ShadowMode.CAST_ONLY; - } else if (receiveShadows) { - return ShadowMode.RECEIVE_ONLY; - } - return ShadowMode.DISABLED; + CompositePositionProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); }; - return freezeObject(ShadowMode); + return CompositePositionProperty; }); -define('Scene/Primitive',[ - '../Core/BoundingSphere', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', - '../Core/clone', - '../Core/Color', - '../Core/combine', - '../Core/ComponentDatatype', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/EncodedCartesian3', - '../Core/FeatureDetection', - '../Core/Geometry', - '../Core/GeometryAttribute', - '../Core/GeometryAttributes', - '../Core/isArray', - '../Core/Matrix4', - '../Core/RuntimeError', - '../Core/subdivideArray', - '../Core/TaskProcessor', - '../Renderer/BufferUsage', - '../Renderer/ContextLimits', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/VertexArray', - '../ThirdParty/when', - './BatchTable', - './CullFace', - './DepthFunction', - './PrimitivePipeline', - './PrimitiveState', - './SceneMode', - './ShadowMode' +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/ShadowVolumeFS',[],function() { + 'use strict'; + return "#ifdef GL_EXT_frag_depth\n\ +#extension GL_EXT_frag_depth : enable\n\ +#endif\n\ +#ifdef VECTOR_TILE\n\ +uniform vec4 u_highlightColor;\n\ +#else\n\ +varying vec4 v_color;\n\ +#endif\n\ +void main(void)\n\ +{\n\ +#ifdef VECTOR_TILE\n\ +gl_FragColor = u_highlightColor;\n\ +#else\n\ +gl_FragColor = v_color;\n\ +#endif\n\ +czm_writeDepthClampedToFarPlane();\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/ShadowVolumeVS',[],function() { + 'use strict'; + return "#ifdef VECTOR_TILE\n\ +attribute vec3 position;\n\ +attribute float a_batchId;\n\ +uniform mat4 u_modifiedModelViewProjection;\n\ +#else\n\ +attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec4 color;\n\ +attribute float batchId;\n\ +#endif\n\ +#ifdef EXTRUDED_GEOMETRY\n\ +attribute vec3 extrudeDirection;\n\ +uniform float u_globeMinimumAltitude;\n\ +#endif\n\ +#ifndef VECTOR_TILE\n\ +varying vec4 v_color;\n\ +#endif\n\ +void main()\n\ +{\n\ +#ifdef VECTOR_TILE\n\ +gl_Position = czm_depthClampFarPlane(u_modifiedModelViewProjection * vec4(position, 1.0));\n\ +#else\n\ +v_color = color;\n\ +vec4 position = czm_computePosition();\n\ +#ifdef EXTRUDED_GEOMETRY\n\ +float delta = min(u_globeMinimumAltitude, czm_geometricToleranceOverMeter * length(position.xyz));\n\ +delta *= czm_sceneMode == czm_sceneMode3D ? 1.0 : 0.0;\n\ +position = position + vec4(extrudeDirection * delta, 0.0);\n\ +#endif\n\ +gl_Position = czm_depthClampFarPlane(czm_modelViewProjectionRelativeToEye * position);\n\ +#endif\n\ +}\n\ +"; +}); +define('Scene/ClassificationType',[ + '../Core/freezeObject' ], function( - BoundingSphere, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - clone, - Color, - combine, - ComponentDatatype, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - EncodedCartesian3, - FeatureDetection, - Geometry, - GeometryAttribute, - GeometryAttributes, - isArray, - Matrix4, - RuntimeError, - subdivideArray, - TaskProcessor, - BufferUsage, - ContextLimits, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - VertexArray, - when, - BatchTable, - CullFace, - DepthFunction, - PrimitivePipeline, - PrimitiveState, - SceneMode, - ShadowMode) { + freezeObject) { 'use strict'; /** - * A primitive represents geometry in the {@link Scene}. The geometry can be from a single {@link GeometryInstance} - * as shown in example 1 below, or from an array of instances, even if the geometry is from different - * geometry types, e.g., an {@link RectangleGeometry} and an {@link EllipsoidGeometry} as shown in Code Example 2. - * <p> - * A primitive combines geometry instances with an {@link Appearance} that describes the full shading, including - * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, - * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix - * and match most of them and add a new geometry or appearance independently of each other. - * </p> - * <p> - * Combining multiple instances into one primitive is called batching, and significantly improves performance for static data. - * Instances can be individually picked; {@link Scene#pick} returns their {@link GeometryInstance#id}. Using - * per-instance appearances like {@link PerInstanceColorAppearance}, each instance can also have a unique color. - * </p> - * <p> - * {@link Geometry} can either be created and batched on a web worker or the main thread. The first two examples - * show geometry that will be created on a web worker by using the descriptions of the geometry. The third example - * shows how to create the geometry on the main thread by explicitly calling the <code>createGeometry</code> method. - * </p> - * - * @alias Primitive - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {GeometryInstance[]|GeometryInstance} [options.geometryInstances] The geometry instances - or a single geometry instance - to render. - * @param {Appearance} [options.appearance] The appearance used to render the primitive. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the primitive (all geometry instances) from model to world coordinates. - * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.cull=true] When <code>true</code>, the renderer frustum culls and horizon culls the primitive's commands based on their bounding volume. Set this to <code>false</code> for a small performance gain if you are manually culling the primitive. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {ShadowMode} [options.shadows=ShadowMode.DISABLED] Determines whether this primitive casts or receives shadows from each light source. - * - * @example - * // 1. Draw a translucent ellipse on the surface with a checkerboard pattern - * var instance = new Cesium.GeometryInstance({ - * geometry : new Cesium.EllipseGeometry({ - * center : Cesium.Cartesian3.fromDegrees(-100.0, 20.0), - * semiMinorAxis : 500000.0, - * semiMajorAxis : 1000000.0, - * rotation : Cesium.Math.PI_OVER_FOUR, - * vertexFormat : Cesium.VertexFormat.POSITION_AND_ST - * }), - * id : 'object returned when this instance is picked and to get/set per-instance attributes' - * }); - * scene.primitives.add(new Cesium.Primitive({ - * geometryInstances : instance, - * appearance : new Cesium.EllipsoidSurfaceAppearance({ - * material : Cesium.Material.fromType('Checkerboard') - * }) - * })); - * - * @example - * // 2. Draw different instances each with a unique color - * var rectangleInstance = new Cesium.GeometryInstance({ - * geometry : new Cesium.RectangleGeometry({ - * rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0), - * vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT - * }), - * id : 'rectangle', - * attributes : { - * color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5) - * } - * }); - * var ellipsoidInstance = new Cesium.GeometryInstance({ - * geometry : new Cesium.EllipsoidGeometry({ - * radii : new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0), - * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL - * }), - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 500000.0), new Cesium.Matrix4()), - * id : 'ellipsoid', - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) - * } - * }); - * scene.primitives.add(new Cesium.Primitive({ - * geometryInstances : [rectangleInstance, ellipsoidInstance], - * appearance : new Cesium.PerInstanceColorAppearance() - * })); - * - * @example - * // 3. Create the geometry on the main thread. - * scene.primitives.add(new Cesium.Primitive({ - * geometryInstances : new Cesium.GeometryInstance({ - * geometry : Cesium.EllipsoidGeometry.createGeometry(new Cesium.EllipsoidGeometry({ - * radii : new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0), - * vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL - * })), - * modelMatrix : Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame( - * Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 500000.0), new Cesium.Matrix4()), - * id : 'ellipsoid', - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA) - * } - * }), - * appearance : new Cesium.PerInstanceColorAppearance() - * })); + * Whether a classification affects terrain, 3D Tiles or both. * - * @see GeometryInstance - * @see Appearance - * @see ClassificationPrimitive - * @see GroundPrimitive + * @exports ClassificationOption */ - function Primitive(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - + var ClassificationType = { /** - * The geometry instances rendered with this primitive. This may - * be <code>undefined</code> if <code>options.releaseGeometryInstances</code> - * is <code>true</code> when the primitive is constructed. - * <p> - * Changing this property after the primitive is rendered has no effect. - * </p> - * - * @readonly - * @type GeometryInstance[]|GeometryInstance + * Only terrain will be classified. * - * @default undefined + * @type {Number} + * @constant */ - this.geometryInstances = options.geometryInstances; - + TERRAIN : 0, /** - * The {@link Appearance} used to shade this primitive. Each geometry - * instance is shaded with the same appearance. Some appearances, like - * {@link PerInstanceColorAppearance} allow giving each instance unique - * properties. + * Only 3D Tiles will be classified. * - * @type Appearance + * @type {Number} + * @constant + */ + CESIUM_3D_TILE : 1, + /** + * Both terrain and 3D Tiles will be classified. * - * @default undefined + * @type {Number} + * @constant */ - this.appearance = options.appearance; - this._appearance = undefined; - this._material = undefined; + BOTH : 2 + }; + + return freezeObject(ClassificationType); +}); + +define('Scene/StencilFunction',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; + /** + * Determines the function used to compare stencil values for the stencil test. + * + * @exports StencilFunction + */ + var StencilFunction = { /** - * The {@link Appearance} used to shade this primitive when it fails the depth test. Each geometry - * instance is shaded with the same appearance. Some appearances, like - * {@link PerInstanceColorAppearance} allow giving each instance unique - * properties. - * - * <p> - * When using an appearance that requires a color attribute, like PerInstanceColorAppearance, - * add a depthFailColor per-instance attribute instead. - * </p> - * - * <p> - * Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, - * there may be artifacts. - * </p> - * @type Appearance + * The stencil test never passes. * - * @default undefined + * @type {Number} + * @constant */ - this.depthFailAppearance = options.depthFailAppearance; - this._depthFailAppearance = undefined; - this._depthFailMaterial = undefined; + NEVER : WebGLConstants.NEVER, /** - * The 4x4 transformation matrix that transforms the primitive (all geometry instances) from model to world coordinates. - * When this is the identity matrix, the primitive is drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. - * - * <p> - * This property is only supported in 3D mode. - * </p> - * - * @type Matrix4 - * - * @default Matrix4.IDENTITY + * The stencil test passes when the masked reference value is less than the masked stencil value. * - * @example - * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); - * p.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); + * @type {Number} + * @constant */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - this._modelMatrix = new Matrix4(); + LESS : WebGLConstants.LESS, /** - * Determines if the primitive will be shown. This affects all geometry - * instances in the primitive. - * - * @type Boolean + * The stencil test passes when the masked reference value is equal to the masked stencil value. * - * @default true + * @type {Number} + * @constant */ - this.show = defaultValue(options.show, true); - - this._vertexCacheOptimize = defaultValue(options.vertexCacheOptimize, false); - this._interleave = defaultValue(options.interleave, false); - this._releaseGeometryInstances = defaultValue(options.releaseGeometryInstances, true); - this._allowPicking = defaultValue(options.allowPicking, true); - this._asynchronous = defaultValue(options.asynchronous, true); - this._compressVertices = defaultValue(options.compressVertices, true); + EQUAL : WebGLConstants.EQUAL, /** - * When <code>true</code>, the renderer frustum culls and horizon culls the primitive's commands - * based on their bounding volume. Set this to <code>false</code> for a small performance gain - * if you are manually culling the primitive. - * - * @type {Boolean} + * The stencil test passes when the masked reference value is less than or equal to the masked stencil value. * - * @default true + * @type {Number} + * @constant */ - this.cull = defaultValue(options.cull, true); + LESS_OR_EQUAL : WebGLConstants.LEQUAL, /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the primitive. - * </p> - * - * @type {Boolean} + * The stencil test passes when the masked reference value is greater than the masked stencil value. * - * @default false + * @type {Number} + * @constant */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + GREATER : WebGLConstants.GREATER, /** - * @private + * The stencil test passes when the masked reference value is not equal to the masked stencil value. + * + * @type {Number} + * @constant */ - this.rtcCenter = options.rtcCenter; + NOT_EQUAL : WebGLConstants.NOTEQUAL, - if (defined(this.rtcCenter) && (!defined(this.geometryInstances) || (isArray(this.geometryInstances) && this.geometryInstances !== 1))) { - throw new DeveloperError('Relative-to-center rendering only supports one geometry instance.'); - } - /** - * Determines whether this primitive casts or receives shadows from each light source. - * - * @type {ShadowMode} + * The stencil test passes when the masked reference value is greater than or equal to the masked stencil value. * - * @default ShadowMode.DISABLED + * @type {Number} + * @constant */ - this.shadows = defaultValue(options.shadows, ShadowMode.DISABLED); - - this._translucent = undefined; - - this._state = PrimitiveState.READY; - this._geometries = []; - this._error = undefined; - this._numberOfInstances = 0; - - this._boundingSpheres = []; - this._boundingSphereWC = []; - this._boundingSphereCV = []; - this._boundingSphere2D = []; - this._boundingSphereMorph = []; - this._perInstanceAttributeCache = []; - this._instanceIds = []; - this._lastPerInstanceAttributeIndex = 0; - - this._va = []; - this._attributeLocations = undefined; - this._primitiveType = undefined; - - this._frontFaceRS = undefined; - this._backFaceRS = undefined; - this._sp = undefined; - - this._depthFailAppearance = undefined; - this._spDepthFail = undefined; - this._frontFaceDepthFailRS = undefined; - this._backFaceDepthFailRS = undefined; - - this._pickRS = undefined; - this._pickSP = undefined; - this._pickIds = []; - - this._colorCommands = []; - this._pickCommands = []; - - this._readOnlyInstanceAttributes = options._readOnlyInstanceAttributes; - - this._createBoundingVolumeFunction = options._createBoundingVolumeFunction; - this._createRenderStatesFunction = options._createRenderStatesFunction; - this._createShaderProgramFunction = options._createShaderProgramFunction; - this._createCommandsFunction = options._createCommandsFunction; - this._updateAndQueueCommandsFunction = options._updateAndQueueCommandsFunction; + GREATER_OR_EQUAL : WebGLConstants.GEQUAL, - this._createPickOffsets = options._createPickOffsets; - this._pickOffsets = undefined; + /** + * The stencil test always passes. + * + * @type {Number} + * @constant + */ + ALWAYS : WebGLConstants.ALWAYS + }; - this._createGeometryResults = undefined; - this._ready = false; - this._readyPromise = when.defer(); + return freezeObject(StencilFunction); +}); - this._batchTable = undefined; - this._batchTableAttributeIndices = undefined; - this._instanceBoundingSpheres = undefined; - this._instanceBoundingSpheresCV = undefined; - this._batchTableBoundingSpheresUpdated = false; - this._batchTableBoundingSphereAttributeIndices = undefined; - } +define('Scene/StencilOperation',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; - defineProperties(Primitive.prototype, { + /** + * Determines the action taken based on the result of the stencil test. + * + * @exports StencilOperation + */ + var StencilOperation = { /** - * When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * - * @memberof Primitive.prototype - * - * @type {Boolean} - * @readonly + * Sets the stencil buffer value to zero. * - * @default true + * @type {Number} + * @constant */ - vertexCacheOptimize : { - get : function() { - return this._vertexCacheOptimize; - } - }, + ZERO : WebGLConstants.ZERO, /** - * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. - * - * @memberof Primitive.prototype - * - * @type {Boolean} - * @readonly + * Does not change the stencil buffer. * - * @default false + * @type {Number} + * @constant */ - interleave : { - get : function() { - return this._interleave; - } - }, + KEEP : WebGLConstants.KEEP, /** - * When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * - * @memberof Primitive.prototype - * - * @type {Boolean} - * @readonly + * Replaces the stencil buffer value with the reference value. * - * @default true + * @type {Number} + * @constant */ - releaseGeometryInstances : { - get : function() { - return this._releaseGeometryInstances; - } - }, + REPLACE : WebGLConstants.REPLACE, /** - * When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. * - * - * @memberof Primitive.prototype - * - * @type {Boolean} - * @readonly + * Increments the stencil buffer value, clamping to unsigned byte. * - * @default true + * @type {Number} + * @constant */ - allowPicking : { - get : function() { - return this._allowPicking; - } - }, + INCREMENT : WebGLConstants.INCR, /** - * Determines if the geometry instances will be created and batched on a web worker. - * - * @memberof Primitive.prototype - * - * @type {Boolean} - * @readonly + * Decrements the stencil buffer value, clamping to zero. * - * @default true + * @type {Number} + * @constant */ - asynchronous : { - get : function() { - return this._asynchronous; - } - }, + DECREMENT : WebGLConstants.DECR, /** - * When <code>true</code>, geometry vertices are compressed, which will save memory. - * - * @memberof Primitive.prototype - * - * @type {Boolean} - * @readonly + * Bitwise inverts the existing stencil buffer value. * - * @default true + * @type {Number} + * @constant */ - compressVertices : { - get : function() { - return this._compressVertices; - } - }, + INVERT : WebGLConstants.INVERT, /** - * Determines if the primitive is complete and ready to render. If this property is - * true, the primitive will be rendered the next time that {@link Primitive#update} - * is called. - * - * @memberof Primitive.prototype + * Increments the stencil buffer value, wrapping to zero when exceeding the unsigned byte range. * - * @type {Boolean} - * @readonly + * @type {Number} + * @constant */ - ready : { - get : function() { - return this._ready; - } - }, + INCREMENT_WRAP : WebGLConstants.INCR_WRAP, /** - * Gets a promise that resolves when the primitive is ready to render. - * @memberof Primitive.prototype - * @type {Promise.<Primitive>} - * @readonly + * Decrements the stencil buffer value, wrapping to the maximum unsigned byte instead of going below zero. + * + * @type {Number} + * @constant */ - readyPromise : { - get : function() { - return this._readyPromise.promise; - } - } - }); - - function getCommonPerInstanceAttributeNames(instances) { - var length = instances.length; - - var attributesInAllInstances = []; - var attributes0 = instances[0].attributes; - var name; - - for (name in attributes0) { - if (attributes0.hasOwnProperty(name)) { - var attribute = attributes0[name]; - var inAllInstances = true; - - // Does this same attribute exist in all instances? - for (var i = 1; i < length; ++i) { - var otherAttribute = instances[i].attributes[name]; - - if (!defined(otherAttribute) || - (attribute.componentDatatype !== otherAttribute.componentDatatype) || - (attribute.componentsPerAttribute !== otherAttribute.componentsPerAttribute) || - (attribute.normalize !== otherAttribute.normalize)) { - - inAllInstances = false; - break; - } - } - - if (inAllInstances) { - attributesInAllInstances.push(name); - } - } - } - - return attributesInAllInstances; - } - - var scratchGetAttributeCartesian2 = new Cartesian2(); - var scratchGetAttributeCartesian3 = new Cartesian3(); - var scratchGetAttributeCartesian4 = new Cartesian4(); - - function getAttributeValue(value) { - var componentsPerAttribute = value.length; - if (componentsPerAttribute === 1) { - return value[0]; - } else if (componentsPerAttribute === 2) { - return Cartesian2.unpack(value, 0, scratchGetAttributeCartesian2); - } else if (componentsPerAttribute === 3) { - return Cartesian3.unpack(value, 0, scratchGetAttributeCartesian3); - } else if (componentsPerAttribute === 4) { - return Cartesian4.unpack(value, 0, scratchGetAttributeCartesian4); - } - } - - function createBatchTable(primitive, context) { - var geometryInstances = primitive.geometryInstances; - var instances = (isArray(geometryInstances)) ? geometryInstances : [geometryInstances]; - var numberOfInstances = instances.length; - if (numberOfInstances === 0) { - return; - } - - var names = getCommonPerInstanceAttributeNames(instances); - var length = names.length; - - var allowPicking = primitive.allowPicking; - var attributes = []; - var attributeIndices = {}; - var boundingSphereAttributeIndices = {}; - - var firstInstance = instances[0]; - var instanceAttributes = firstInstance.attributes; - - var i; - var name; - var attribute; - - for (i = 0; i < length; ++i) { - name = names[i]; - attribute = instanceAttributes[name]; - - attributeIndices[name] = i; - attributes.push({ - functionName : 'czm_batchTable_' + name, - componentDatatype : attribute.componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize - }); - } - - if (names.indexOf('distanceDisplayCondition') !== -1) { - attributes.push({ - functionName : 'czm_batchTable_boundingSphereCenter3DHigh', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3 - },{ - functionName : 'czm_batchTable_boundingSphereCenter3DLow', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3 - },{ - functionName : 'czm_batchTable_boundingSphereCenter2DHigh', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3 - },{ - functionName : 'czm_batchTable_boundingSphereCenter2DLow', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3 - },{ - functionName : 'czm_batchTable_boundingSphereRadius', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 1 - }); - boundingSphereAttributeIndices.center3DHigh = attributes.length - 5; - boundingSphereAttributeIndices.center3DLow = attributes.length - 4; - boundingSphereAttributeIndices.center2DHigh = attributes.length - 3; - boundingSphereAttributeIndices.center2DLow = attributes.length - 2; - boundingSphereAttributeIndices.radius = attributes.length - 1; - } - - if (allowPicking) { - attributes.push({ - functionName : 'czm_batchTable_pickColor', - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - componentsPerAttribute : 4, - normalize : true - }); - } - - var attributesLength = attributes.length; - var batchTable = new BatchTable(context, attributes, numberOfInstances); - - for (i = 0; i < numberOfInstances; ++i) { - var instance = instances[i]; - instanceAttributes = instance.attributes; - - for (var j = 0; j < length; ++j) { - name = names[j]; - attribute = instanceAttributes[name]; - var value = getAttributeValue(attribute.value); - var attributeIndex = attributeIndices[name]; - batchTable.setBatchedAttribute(i, attributeIndex, value); - } - - if (allowPicking) { - var pickObject = { - primitive : defaultValue(instance.pickPrimitive, primitive) - }; - - if (defined(instance.id)) { - pickObject.id = instance.id; - } - - var pickId = context.createPickId(pickObject); - primitive._pickIds.push(pickId); - - var pickColor = pickId.color; - var color = scratchGetAttributeCartesian4; - color.x = Color.floatToByte(pickColor.red); - color.y = Color.floatToByte(pickColor.green); - color.z = Color.floatToByte(pickColor.blue); - color.w = Color.floatToByte(pickColor.alpha); - - batchTable.setBatchedAttribute(i, attributesLength - 1, color); - } - } - - primitive._batchTable = batchTable; - primitive._batchTableAttributeIndices = attributeIndices; - primitive._batchTableBoundingSphereAttributeIndices = boundingSphereAttributeIndices; - } - - function cloneAttribute(attribute) { - var clonedValues; - if (isArray(attribute.values)) { - clonedValues = attribute.values.slice(0); - } else { - clonedValues = new attribute.values.constructor(attribute.values); - } - return new GeometryAttribute({ - componentDatatype : attribute.componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize, - values : clonedValues - }); - } - - function cloneGeometry(geometry) { - var attributes = geometry.attributes; - var newAttributes = new GeometryAttributes(); - for (var property in attributes) { - if (attributes.hasOwnProperty(property) && defined(attributes[property])) { - newAttributes[property] = cloneAttribute(attributes[property]); - } - } - - var indices; - if (defined(geometry.indices)) { - var sourceValues = geometry.indices; - if (isArray(sourceValues)) { - indices = sourceValues.slice(0); - } else { - indices = new sourceValues.constructor(sourceValues); - } - } - - return new Geometry({ - attributes : newAttributes, - indices : indices, - primitiveType : geometry.primitiveType, - boundingSphere : BoundingSphere.clone(geometry.boundingSphere) - }); - } - - function cloneInstance(instance, geometry) { - return { - geometry : geometry, - modelMatrix : Matrix4.clone(instance.modelMatrix), - pickPrimitive : instance.pickPrimitive, - id : instance.id - }; - } - - var positionRegex = /attribute\s+vec(?:3|4)\s+(.*)3DHigh;/g; - - Primitive._modifyShaderPosition = function(primitive, vertexShaderSource, scene3DOnly) { - var match; - - var forwardDecl = ''; - var attributes = ''; - var computeFunctions = ''; - - while ((match = positionRegex.exec(vertexShaderSource)) !== null) { - var name = match[1]; - - var functionName = 'vec4 czm_compute' + name[0].toUpperCase() + name.substr(1) + '()'; - - // Don't forward-declare czm_computePosition because computePosition.glsl already does. - if (functionName !== 'vec4 czm_computePosition()') { - forwardDecl += functionName + ';\n'; - } - - if (!defined(primitive.rtcCenter)) { - // Use GPU RTE - if (!scene3DOnly) { - attributes += - 'attribute vec3 ' + name + '2DHigh;\n' + - 'attribute vec3 ' + name + '2DLow;\n'; - - computeFunctions += - functionName + '\n' + - '{\n' + - ' vec4 p;\n' + - ' if (czm_morphTime == 1.0)\n' + - ' {\n' + - ' p = czm_translateRelativeToEye(' + name + '3DHigh, ' + name + '3DLow);\n' + - ' }\n' + - ' else if (czm_morphTime == 0.0)\n' + - ' {\n' + - ' p = czm_translateRelativeToEye(' + name + '2DHigh.zxy, ' + name + '2DLow.zxy);\n' + - ' }\n' + - ' else\n' + - ' {\n' + - ' p = czm_columbusViewMorph(\n' + - ' czm_translateRelativeToEye(' + name + '2DHigh.zxy, ' + name + '2DLow.zxy),\n' + - ' czm_translateRelativeToEye(' + name + '3DHigh, ' + name + '3DLow),\n' + - ' czm_morphTime);\n' + - ' }\n' + - ' return p;\n' + - '}\n\n'; - } else { - computeFunctions += - functionName + '\n' + - '{\n' + - ' return czm_translateRelativeToEye(' + name + '3DHigh, ' + name + '3DLow);\n' + - '}\n\n'; - } - } else { - // Use RTC - vertexShaderSource = vertexShaderSource.replace(/attribute\s+vec(?:3|4)\s+position3DHigh;/g, ''); - vertexShaderSource = vertexShaderSource.replace(/attribute\s+vec(?:3|4)\s+position3DLow;/g, ''); - - forwardDecl += 'uniform mat4 u_modifiedModelView;\n'; - attributes += 'attribute vec4 position;\n'; - - computeFunctions += - functionName + '\n' + - '{\n' + - ' return u_modifiedModelView * position;\n' + - '}\n\n'; - - - vertexShaderSource = vertexShaderSource.replace(/czm_modelViewRelativeToEye\s+\*\s+/g, ''); - vertexShaderSource = vertexShaderSource.replace(/czm_modelViewProjectionRelativeToEye/g, 'czm_projection'); - } - } - - return [forwardDecl, attributes, vertexShaderSource, computeFunctions].join('\n'); - }; - - Primitive._appendShowToShader = function(primitive, vertexShaderSource) { - if (!defined(primitive._batchTableAttributeIndices.show)) { - return vertexShaderSource; - } - - var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_show_main'); - var showMain = - 'void main() \n' + - '{ \n' + - ' czm_non_show_main(); \n' + - ' gl_Position *= czm_batchTable_show(batchId); \n' + - '}'; - - return renamedVS + '\n' + showMain; - }; - - Primitive._updateColorAttribute = function(primitive, vertexShaderSource, isDepthFail) { - // some appearances have a color attribute for per vertex color. - // only remove if color is a per instance attribute. - if (!defined(primitive._batchTableAttributeIndices.color) && !defined(primitive._batchTableAttributeIndices.depthFailColor)) { - return vertexShaderSource; - } - - if (vertexShaderSource.search(/attribute\s+vec4\s+color;/g) === -1) { - return vertexShaderSource; - } - - if (isDepthFail && !defined(primitive._batchTableAttributeIndices.depthFailColor)) { - throw new DeveloperError('A depthFailColor per-instance attribute is required when using a depth fail appearance that uses a color attribute.'); - } - - var modifiedVS = vertexShaderSource; - modifiedVS = modifiedVS.replace(/attribute\s+vec4\s+color;/g, ''); - if (!isDepthFail) { - modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_color(batchId)$2'); - } else { - modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_depthFailColor(batchId)$2'); - } - return modifiedVS; - }; - - Primitive._updatePickColorAttribute = function(source) { - var vsPick = source.replace(/attribute\s+vec4\s+pickColor;/g, ''); - vsPick = vsPick.replace(/(\b)pickColor(\b)/g, '$1czm_batchTable_pickColor(batchId)$2'); - return vsPick; - }; - - Primitive._appendDistanceDisplayConditionToShader = function(primitive, vertexShaderSource, scene3DOnly) { - if (!defined(primitive._batchTableAttributeIndices.distanceDisplayCondition)) { - return vertexShaderSource; - } - - var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_distanceDisplayCondition_main'); - var distanceDisplayConditionMain = - 'void main() \n' + - '{ \n' + - ' czm_non_distanceDisplayCondition_main(); \n' + - ' vec2 distanceDisplayCondition = czm_batchTable_distanceDisplayCondition(batchId);\n' + - ' vec3 boundingSphereCenter3DHigh = czm_batchTable_boundingSphereCenter3DHigh(batchId);\n' + - ' vec3 boundingSphereCenter3DLow = czm_batchTable_boundingSphereCenter3DLow(batchId);\n' + - ' vec3 boundingSphereCenter2DHigh = czm_batchTable_boundingSphereCenter2DHigh(batchId);\n' + - ' vec3 boundingSphereCenter2DLow = czm_batchTable_boundingSphereCenter2DLow(batchId);\n' + - ' float boundingSphereRadius = czm_batchTable_boundingSphereRadius(batchId);\n'; - - if (!scene3DOnly) { - distanceDisplayConditionMain += - ' vec4 centerRTE;\n' + - ' if (czm_morphTime == 1.0)\n' + - ' {\n' + - ' centerRTE = czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow);\n' + - ' }\n' + - ' else if (czm_morphTime == 0.0)\n' + - ' {\n' + - ' centerRTE = czm_translateRelativeToEye(boundingSphereCenter2DHigh.zxy, boundingSphereCenter2DLow.zxy);\n' + - ' }\n' + - ' else\n' + - ' {\n' + - ' centerRTE = czm_columbusViewMorph(\n' + - ' czm_translateRelativeToEye(boundingSphereCenter2DHigh.zxy, boundingSphereCenter2DLow.zxy),\n' + - ' czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow),\n' + - ' czm_morphTime);\n' + - ' }\n'; - } else { - distanceDisplayConditionMain += - ' vec4 centerRTE = czm_translateRelativeToEye(boundingSphereCenter3DHigh, boundingSphereCenter3DLow);\n'; - } - - distanceDisplayConditionMain += - ' float radiusSq = boundingSphereRadius * boundingSphereRadius; \n' + - ' float distanceSq; \n' + - ' if (czm_sceneMode == czm_sceneMode2D) \n' + - ' { \n' + - ' distanceSq = czm_eyeHeight2D.y - radiusSq; \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' distanceSq = dot(centerRTE.xyz, centerRTE.xyz) - radiusSq; \n' + - ' } \n' + - ' distanceSq = max(distanceSq, 0.0); \n' + - ' float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x; \n' + - ' float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y; \n' + - ' float show = (distanceSq >= nearSq && distanceSq <= farSq) ? 1.0 : 0.0; \n' + - ' gl_Position *= show; \n' + - '}'; - return renamedVS + '\n' + distanceDisplayConditionMain; + DECREMENT_WRAP : WebGLConstants.DECR_WRAP }; - function modifyForEncodedNormals(primitive, vertexShaderSource) { - if (!primitive.compressVertices) { - return vertexShaderSource; - } - - var containsNormal = vertexShaderSource.search(/attribute\s+vec3\s+normal;/g) !== -1; - var containsSt = vertexShaderSource.search(/attribute\s+vec2\s+st;/g) !== -1; - if (!containsNormal && !containsSt) { - return vertexShaderSource; - } - - var containsTangent = vertexShaderSource.search(/attribute\s+vec3\s+tangent;/g) !== -1; - var containsBitangent = vertexShaderSource.search(/attribute\s+vec3\s+bitangent;/g) !== -1; - - var numComponents = containsSt && containsNormal ? 2.0 : 1.0; - numComponents += containsTangent || containsBitangent ? 1 : 0; - - var type = (numComponents > 1) ? 'vec' + numComponents : 'float'; - - var attributeName = 'compressedAttributes'; - var attributeDecl = 'attribute ' + type + ' ' + attributeName + ';'; - - var globalDecl = ''; - var decode = ''; - - if (containsSt) { - globalDecl += 'vec2 st;\n'; - var stComponent = numComponents > 1 ? attributeName + '.x' : attributeName; - decode += ' st = czm_decompressTextureCoordinates(' + stComponent + ');\n'; - } - - if (containsNormal && containsTangent && containsBitangent) { - globalDecl += - 'vec3 normal;\n' + - 'vec3 tangent;\n' + - 'vec3 bitangent;\n'; - decode += ' czm_octDecode(' + attributeName + '.' + (containsSt ? 'yz' : 'xy') + ', normal, tangent, bitangent);\n'; - } else { - if (containsNormal) { - globalDecl += 'vec3 normal;\n'; - decode += ' normal = czm_octDecode(' + attributeName + (numComponents > 1 ? '.' + (containsSt ? 'y' : 'x') : '') + ');\n'; - } - - if (containsTangent) { - globalDecl += 'vec3 tangent;\n'; - decode += ' tangent = czm_octDecode(' + attributeName + '.' + (containsSt && containsNormal ? 'z' : 'y') + ');\n'; - } - - if (containsBitangent) { - globalDecl += 'vec3 bitangent;\n'; - decode += ' bitangent = czm_octDecode(' + attributeName + '.' + (containsSt && containsNormal ? 'z' : 'y') + ');\n'; - } - } - - var modifiedVS = vertexShaderSource; - modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+normal;/g, ''); - modifiedVS = modifiedVS.replace(/attribute\s+vec2\s+st;/g, ''); - modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+tangent;/g, ''); - modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+bitangent;/g, ''); - modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); - var compressedMain = - 'void main() \n' + - '{ \n' + - decode + - ' czm_non_compressed_main(); \n' + - '}'; - - return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); - } - - function depthClampVS(vertexShaderSource) { - var modifiedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_depth_clamp_main'); - // The varying should be surround by #ifdef GL_EXT_frag_depth as an optimization. - // It is not to workaround an issue with Edge: - // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12120362/ - modifiedVS += - 'varying float v_WindowZ;\n' + - 'void main() {\n' + - ' czm_non_depth_clamp_main();\n' + - ' vec4 position = gl_Position;\n' + - ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + - ' position.z = min(position.z, position.w);\n' + - ' gl_Position = position;' + - '}\n'; - return modifiedVS; - } - - function depthClampFS(fragmentShaderSource) { - var modifiedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_non_depth_clamp_main'); - modifiedFS += - 'varying float v_WindowZ;\n' + - 'void main() {\n' + - ' czm_non_depth_clamp_main();\n' + - '#ifdef GL_EXT_frag_depth\n' + - ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + - '#endif\n' + - '}\n'; - modifiedFS = - '#ifdef GL_EXT_frag_depth\n' + - '#extension GL_EXT_frag_depth : enable\n' + - '#endif\n' + - modifiedFS; - return modifiedFS; - } - - function validateShaderMatching(shaderProgram, attributeLocations) { - // For a VAO and shader program to be compatible, the VAO must have - // all active attribute in the shader program. The VAO may have - // extra attributes with the only concern being a potential - // performance hit due to extra memory bandwidth and cache pollution. - // The shader source could have extra attributes that are not used, - // but there is no guarantee they will be optimized out. - // - // Here, we validate that the VAO has all attributes required - // to match the shader program. - var shaderAttributes = shaderProgram.vertexAttributes; - - for (var name in shaderAttributes) { - if (shaderAttributes.hasOwnProperty(name)) { - if (!defined(attributeLocations[name])) { - throw new DeveloperError('Appearance/Geometry mismatch. The appearance requires vertex shader attribute input \'' + name + - '\', which was not computed as part of the Geometry. Use the appearance\'s vertexFormat property when constructing the geometry.'); - } - } - } - } - - function getUniformFunction(uniforms, name) { - return function() { - return uniforms[name]; - }; - } - - var numberOfCreationWorkers = Math.max(FeatureDetection.hardwareConcurrency - 1, 1); - var createGeometryTaskProcessors; - var combineGeometryTaskProcessor = new TaskProcessor('combineGeometry', Number.POSITIVE_INFINITY); - - function loadAsynchronous(primitive, frameState) { - var instances; - var geometry; - var i; - var j; - - var instanceIds = primitive._instanceIds; - - if (primitive._state === PrimitiveState.READY) { - instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; - var length = primitive._numberOfInstances = instances.length; - - var promises = []; - var subTasks = []; - for (i = 0; i < length; ++i) { - geometry = instances[i].geometry; - instanceIds.push(instances[i].id); - - if (!defined(geometry._workerName)) { - throw new DeveloperError('_workerName must be defined for asynchronous geometry.'); - } - - subTasks.push({ - moduleName : geometry._workerName, - geometry : geometry - }); - } - - if (!defined(createGeometryTaskProcessors)) { - createGeometryTaskProcessors = new Array(numberOfCreationWorkers); - for (i = 0; i < numberOfCreationWorkers; i++) { - createGeometryTaskProcessors[i] = new TaskProcessor('createGeometry', Number.POSITIVE_INFINITY); - } - } - - var subTask; - subTasks = subdivideArray(subTasks, numberOfCreationWorkers); - - for (i = 0; i < subTasks.length; i++) { - var packedLength = 0; - var workerSubTasks = subTasks[i]; - var workerSubTasksLength = workerSubTasks.length; - for (j = 0; j < workerSubTasksLength; ++j) { - subTask = workerSubTasks[j]; - geometry = subTask.geometry; - if (defined(geometry.constructor.pack)) { - subTask.offset = packedLength; - packedLength += defaultValue(geometry.constructor.packedLength, geometry.packedLength); - } - } - - var subTaskTransferableObjects; - - if (packedLength > 0) { - var array = new Float64Array(packedLength); - subTaskTransferableObjects = [array.buffer]; - - for (j = 0; j < workerSubTasksLength; ++j) { - subTask = workerSubTasks[j]; - geometry = subTask.geometry; - if (defined(geometry.constructor.pack)) { - geometry.constructor.pack(geometry, array, subTask.offset); - subTask.geometry = array; - } - } - } - - promises.push(createGeometryTaskProcessors[i].scheduleTask({ - subTasks : subTasks[i] - }, subTaskTransferableObjects)); - } + return freezeObject(StencilOperation); +}); - primitive._state = PrimitiveState.CREATING; +define('Scene/ClassificationPrimitive',[ + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/GeometryInstance', + '../Core/isArray', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Shaders/ShadowVolumeFS', + '../Shaders/ShadowVolumeVS', + '../ThirdParty/when', + './BlendingState', + './ClassificationType', + './DepthFunction', + './PerInstanceColorAppearance', + './Primitive', + './SceneMode', + './StencilFunction', + './StencilOperation' + ], function( + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + GeometryInstance, + isArray, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + ShadowVolumeFS, + ShadowVolumeVS, + when, + BlendingState, + ClassificationType, + DepthFunction, + PerInstanceColorAppearance, + Primitive, + SceneMode, + StencilFunction, + StencilOperation) { + 'use strict'; - when.all(promises, function(results) { - primitive._createGeometryResults = results; - primitive._state = PrimitiveState.CREATED; - }).otherwise(function(error) { - setReady(primitive, frameState, PrimitiveState.FAILED, error); - }); - } else if (primitive._state === PrimitiveState.CREATED) { - var transferableObjects = []; - instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; + var ClassificationPrimitiveReadOnlyInstanceAttributes = ['color']; - var scene3DOnly = frameState.scene3DOnly; - var projection = frameState.mapProjection; + /** + * A classification primitive represents a volume enclosing geometry in the {@link Scene} to be highlighted. The geometry must be from a single {@link GeometryInstance}. + * Batching multiple geometries is not yet supported. + * <p> + * A primitive combines the geometry instance with an {@link Appearance} that describes the full shading, including + * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, + * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix + * and match most of them and add a new geometry or appearance independently of each other. Only the {@link PerInstanceColorAppearance} + * is supported at this time. + * </p> + * <p> + * For correct rendering, this feature requires the EXT_frag_depth WebGL extension. For hardware that do not support this extension, there + * will be rendering artifacts for some viewing angles. + * </p> + * <p> + * Valid geometries are {@link BoxGeometry}, {@link CylinderGeometry}, {@link EllipsoidGeometry}, {@link PolylineVolumeGeometry}, and {@link SphereGeometry}. + * </p> + * <p> + * Geometries that follow the surface of the ellipsoid, such as {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}, + * are also valid if they are extruded volumes; otherwise, they will not be rendered. + * </p> + * + * @alias ClassificationPrimitive + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. This can either be a single instance or an array of length one. + * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. + * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on + * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be <code>false</code>. + * + * @see Primitive + * @see GroundPrimitive + * @see GeometryInstance + * @see Appearance + */ + function ClassificationPrimitive(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var promise = combineGeometryTaskProcessor.scheduleTask(PrimitivePipeline.packCombineGeometryParameters({ - createGeometryResults : primitive._createGeometryResults, - instances : instances, - ellipsoid : projection.ellipsoid, - projection : projection, - elementIndexUintSupported : frameState.context.elementIndexUint, - scene3DOnly : scene3DOnly, - vertexCacheOptimize : primitive.vertexCacheOptimize, - compressVertices : primitive.compressVertices, - modelMatrix : primitive.modelMatrix, - createPickOffsets : primitive._createPickOffsets - }, transferableObjects), transferableObjects); + /** + * The geometry instance rendered with this primitive. This may + * be <code>undefined</code> if <code>options.releaseGeometryInstances</code> + * is <code>true</code> when the primitive is constructed. + * <p> + * Changing this property after the primitive is rendered has no effect. + * </p> + * <p> + * Because of the rendering technique used, all geometry instances must be the same color. + * If there is an instance with a differing color, a <code>DeveloperError</code> will be thrown + * on the first attempt to render. + * </p> + * + * @readonly + * @type {Array|GeometryInstance} + * + * @default undefined + */ + this.geometryInstances = options.geometryInstances; + /** + * Determines if the primitive will be shown. This affects all geometry + * instances in the primitive. + * + * @type {Boolean} + * + * @default true + */ + this.show = defaultValue(options.show, true); + /** + * Determines whether terrain, 3D Tiles or both will be classified. + * + * @type {ClassificationType} + * + * @default ClassificationType.BOTH + */ + this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the primitive. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the shadow volume for each geometry in the primitive. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); + this._debugShowShadowVolume = false; - primitive._createGeometryResults = undefined; - primitive._state = PrimitiveState.COMBINING; + // These are used by GroundPrimitive to augment the shader and uniform map. + this._extruded = defaultValue(options._extruded, false); + this._uniformMap = options._uniformMap; - when(promise, function(packedResult) { - var result = PrimitivePipeline.unpackCombineGeometryResults(packedResult); - primitive._geometries = result.geometries; - primitive._attributeLocations = result.attributeLocations; - primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); - primitive._pickOffsets = result.pickOffsets; - primitive._instanceBoundingSpheres = result.boundingSpheres; - primitive._instanceBoundingSpheresCV = result.boundingSpheresCV; + this._sp = undefined; + this._spStencil = undefined; + this._spPick = undefined; - if (defined(primitive._geometries) && primitive._geometries.length > 0) { - primitive._state = PrimitiveState.COMBINED; - } else { - setReady(primitive, frameState, PrimitiveState.FAILED, undefined); - } - }).otherwise(function(error) { - setReady(primitive, frameState, PrimitiveState.FAILED, error); - }); - } - } + this._rsStencilPreloadPass = undefined; + this._rsStencilDepthPass = undefined; + this._rsColorPass = undefined; + this._rsPickPass = undefined; - function loadSynchronous(primitive, frameState) { - var instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; - var length = primitive._numberOfInstances = instances.length; - var clonedInstances = new Array(length); - var instanceIds = primitive._instanceIds; + this._commandsIgnoreShow = []; - var instance; - var i; + this._ready = false; + this._readyPromise = when.defer(); - var geometryIndex = 0; - for (i = 0; i < length; i++) { - instance = instances[i]; - var geometry = instance.geometry; + this._primitive = undefined; + this._pickPrimitive = options._pickPrimitive; - var createdGeometry; - if (defined(geometry.attributes) && defined(geometry.primitiveType)) { - createdGeometry = cloneGeometry(geometry); - } else { - createdGeometry = geometry.constructor.createGeometry(geometry); - } + var appearance = new PerInstanceColorAppearance({ + flat : true + }); - clonedInstances[geometryIndex++] = cloneInstance(instance, createdGeometry); - instanceIds.push(instance.id); + var readOnlyAttributes; + if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { + readOnlyAttributes = ClassificationPrimitiveReadOnlyInstanceAttributes; } - clonedInstances.length = geometryIndex; - - var scene3DOnly = frameState.scene3DOnly; - var projection = frameState.mapProjection; - - var result = PrimitivePipeline.combineGeometry({ - instances : clonedInstances, - ellipsoid : projection.ellipsoid, - projection : projection, - elementIndexUintSupported : frameState.context.elementIndexUint, - scene3DOnly : scene3DOnly, - vertexCacheOptimize : primitive.vertexCacheOptimize, - compressVertices : primitive.compressVertices, - modelMatrix : primitive.modelMatrix, - createPickOffsets : primitive._createPickOffsets - }); - - primitive._geometries = result.geometries; - primitive._attributeLocations = result.attributeLocations; - primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); - primitive._pickOffsets = result.pickOffsets; - primitive._instanceBoundingSpheres = result.boundingSpheres; - primitive._instanceBoundingSpheresCV = result.boundingSpheresCV; + this._createBoundingVolumeFunction = options._createBoundingVolumeFunction; + this._updateAndQueueCommandsFunction = options._updateAndQueueCommandsFunction; - if (defined(primitive._geometries) && primitive._geometries.length > 0) { - primitive._state = PrimitiveState.COMBINED; - } else { - setReady(primitive, frameState, PrimitiveState.FAILED, undefined); - } + this._primitiveOptions = { + geometryInstances : undefined, + appearance : appearance, + vertexCacheOptimize : defaultValue(options.vertexCacheOptimize, false), + interleave : defaultValue(options.interleave, false), + releaseGeometryInstances : defaultValue(options.releaseGeometryInstances, true), + allowPicking : defaultValue(options.allowPicking, true), + asynchronous : defaultValue(options.asynchronous, true), + compressVertices : defaultValue(options.compressVertices, true), + _readOnlyInstanceAttributes : readOnlyAttributes, + _createBoundingVolumeFunction : undefined, + _createRenderStatesFunction : undefined, + _createShaderProgramFunction : undefined, + _createCommandsFunction : undefined, + _updateAndQueueCommandsFunction : undefined, + _createPickOffsets : true + }; } - var scratchBoundingSphereCenterEncoded = new EncodedCartesian3(); - var scratchBoundingSphereCartographic = new Cartographic(); - var scratchBoundingSphereCenter2D = new Cartesian3(); - var scratchBoundingSphere = new BoundingSphere(); + defineProperties(ClassificationPrimitive.prototype, { + /** + * When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + vertexCacheOptimize : { + get : function() { + return this._primitiveOptions.vertexCacheOptimize; + } + }, - function updateBatchTableBoundingSpheres(primitive, frameState) { - var hasDistanceDisplayCondition = defined(primitive._batchTableAttributeIndices.distanceDisplayCondition); - if (!hasDistanceDisplayCondition || primitive._batchTableBoundingSpheresUpdated) { - return; - } + /** + * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + interleave : { + get : function() { + return this._primitiveOptions.interleave; + } + }, - var indices = primitive._batchTableBoundingSphereAttributeIndices; - var center3DHighIndex = indices.center3DHigh; - var center3DLowIndex = indices.center3DLow; - var center2DHighIndex = indices.center2DHigh; - var center2DLowIndex = indices.center2DLow; - var radiusIndex = indices.radius; + /** + * When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + releaseGeometryInstances : { + get : function() { + return this._primitiveOptions.releaseGeometryInstances; + } + }, - var projection = frameState.mapProjection; - var ellipsoid = projection.ellipsoid; + /** + * When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + allowPicking : { + get : function() { + return this._primitiveOptions.allowPicking; + } + }, - var batchTable = primitive._batchTable; - var boundingSpheres = primitive._instanceBoundingSpheres; - var length = boundingSpheres.length; + /** + * Determines if the geometry instances will be created and batched on a web worker. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + asynchronous : { + get : function() { + return this._primitiveOptions.asynchronous; + } + }, - for (var i = 0; i < length; ++i) { - var boundingSphere = boundingSpheres[i]; - if (!defined(boundingSphere)) { - continue; + /** + * When <code>true</code>, geometry vertices are compressed, which will save memory. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + compressVertices : { + get : function() { + return this._primitiveOptions.compressVertices; } + }, - var modelMatrix = primitive.modelMatrix; - if (defined(modelMatrix)) { - boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix, scratchBoundingSphere); + /** + * Determines if the primitive is complete and ready to render. If this property is + * true, the primitive will be rendered the next time that {@link ClassificationPrimitive#update} + * is called. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; } + }, - var center = boundingSphere.center; - var radius = boundingSphere.radius; + /** + * Gets a promise that resolves when the primitive is ready to render. + * @memberof ClassificationPrimitive.prototype + * @type {Promise.<ClassificationPrimitive>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + } + }); - var encodedCenter = EncodedCartesian3.fromCartesian(center, scratchBoundingSphereCenterEncoded); - batchTable.setBatchedAttribute(i, center3DHighIndex, encodedCenter.high); - batchTable.setBatchedAttribute(i, center3DLowIndex, encodedCenter.low); + /** + * Determines if ClassificationPrimitive rendering is supported. + * + * @param {Scene} scene The scene. + * @returns {Boolean} <code>true</code> if ClassificationPrimitives are supported; otherwise, returns <code>false</code> + */ + ClassificationPrimitive.isSupported = function(scene) { + return scene.context.stencilBuffer; + }; - var cartographic = ellipsoid.cartesianToCartographic(center, scratchBoundingSphereCartographic); - var center2D = projection.project(cartographic, scratchBoundingSphereCenter2D); - encodedCenter = EncodedCartesian3.fromCartesian(center2D, scratchBoundingSphereCenterEncoded); - batchTable.setBatchedAttribute(i, center2DHighIndex, encodedCenter.high); - batchTable.setBatchedAttribute(i, center2DLowIndex, encodedCenter.low); - batchTable.setBatchedAttribute(i, radiusIndex, radius); - } + // The stencil mask only uses the least significant 4 bits. + // This is so 3D Tiles with the skip LOD optimization, which uses the most significant 4 bits, + // can be classified. + var stencilMask = 0x0F; + var stencilReference = 0; - primitive._batchTableBoundingSpheresUpdated = true; + function getStencilPreloadRenderState(enableStencil) { + return { + colorMask : { + red : false, + green : false, + blue : false, + alpha : false + }, + stencilTest : { + enabled : enableStencil, + frontFunction : StencilFunction.ALWAYS, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.DECREMENT_WRAP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.ALWAYS, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.INCREMENT_WRAP, + zPass : StencilOperation.INCREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : false + }, + depthMask : false + }; } - function createVertexArray(primitive, frameState) { - var attributeLocations = primitive._attributeLocations; - var geometries = primitive._geometries; - var scene3DOnly = frameState.scene3DOnly; - var context = frameState.context; - - var va = []; - var length = geometries.length; - for (var i = 0; i < length; ++i) { - var geometry = geometries[i]; + function getStencilDepthRenderState(enableStencil) { + return { + colorMask : { + red : false, + green : false, + blue : false, + alpha : false + }, + stencilTest : { + enabled : enableStencil, + frontFunction : StencilFunction.ALWAYS, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.INCREMENT_WRAP + }, + backFunction : StencilFunction.ALWAYS, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : true, + func : DepthFunction.LESS_OR_EQUAL + }, + depthMask : false + }; + } - va.push(VertexArray.fromGeometry({ - context : context, - geometry : geometry, - attributeLocations : attributeLocations, - bufferUsage : BufferUsage.STATIC_DRAW, - interleave : primitive._interleave - })); - if (defined(primitive._createBoundingVolumeFunction)) { - primitive._createBoundingVolumeFunction(frameState, geometry); - } else { - primitive._boundingSpheres.push(BoundingSphere.clone(geometry.boundingSphere)); - primitive._boundingSphereWC.push(new BoundingSphere()); + function getColorRenderState(enableStencil) { + return { + stencilTest : { + enabled : enableStencil, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.NOT_EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : false + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND + }; + } - if (!scene3DOnly) { - var center = geometry.boundingSphereCV.center; - var x = center.x; - var y = center.y; - var z = center.z; - center.x = z; - center.y = x; - center.z = y; + var pickRenderState = { + stencilTest : { + enabled : true, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.NOT_EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : false + }, + depthMask : false + }; - primitive._boundingSphereCV.push(BoundingSphere.clone(geometry.boundingSphereCV)); - primitive._boundingSphere2D.push(new BoundingSphere()); - primitive._boundingSphereMorph.push(new BoundingSphere()); - } - } + function createRenderStates(classificationPrimitive, context, appearance, twoPasses) { + if (defined(classificationPrimitive._rsStencilPreloadPass)) { + return; } + var stencilEnabled = !classificationPrimitive.debugShowShadowVolume; - primitive._va = va; - primitive._primitiveType = geometries[0].primitiveType; + classificationPrimitive._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(stencilEnabled)); + classificationPrimitive._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(stencilEnabled)); + classificationPrimitive._rsColorPass = RenderState.fromCache(getColorRenderState(stencilEnabled)); + classificationPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); + } - if (primitive.releaseGeometryInstances) { - primitive.geometryInstances = undefined; + function modifyForEncodedNormals(primitive, vertexShaderSource) { + if (!primitive.compressVertices) { + return vertexShaderSource; } - primitive._geometries = undefined; - setReady(primitive, frameState, PrimitiveState.COMPLETE, undefined); - } + if (vertexShaderSource.search(/attribute\s+vec3\s+extrudeDirection;/g) !== -1) { + var attributeName = 'compressedAttributes'; - function createRenderStates(primitive, context, appearance, twoPasses) { - var renderState = appearance.getRenderState(); - var rs; + //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes + var attributeDecl = 'attribute vec2 ' + attributeName + ';'; - if (twoPasses) { - rs = clone(renderState, false); - rs.cull = { - enabled : true, - face : CullFace.BACK - }; - primitive._frontFaceRS = RenderState.fromCache(rs); + var globalDecl = 'vec3 extrudeDirection;\n'; + var decode = ' extrudeDirection = czm_octDecode(' + attributeName + ', 65535.0);\n'; - rs.cull.face = CullFace.FRONT; - primitive._backFaceRS = RenderState.fromCache(rs); - } else { - primitive._frontFaceRS = RenderState.fromCache(renderState); - primitive._backFaceRS = primitive._frontFaceRS; - } + var modifiedVS = vertexShaderSource; + modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+extrudeDirection;/g, ''); + modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); + var compressedMain = + 'void main() \n' + + '{ \n' + + decode + + ' czm_non_compressed_main(); \n' + + '}'; - rs = clone(renderState, false); - if (defined(primitive._depthFailAppearance)) { - rs.depthTest.enabled = false; + return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); } + } - if (primitive.allowPicking) { - if (twoPasses) { - rs.cull = { - enabled : false - }; - primitive._pickRS = RenderState.fromCache(rs); - } else { - primitive._pickRS = RenderState.fromCache(rs); - } - } else { - rs.colorMask = { - red : false, - green : false, - blue : false, - alpha : false - }; - - if (twoPasses) { - rs.cull = { - enabled : false - }; - primitive._pickRS = RenderState.fromCache(rs); - } else { - primitive._pickRS = RenderState.fromCache(rs); - } + function createShaderProgram(classificationPrimitive, frameState, appearance) { + if (defined(classificationPrimitive._sp)) { + return; } - if (defined(primitive._depthFailAppearance)) { - renderState = primitive._depthFailAppearance.getRenderState(); - rs = clone(renderState, false); - rs.depthTest.func = DepthFunction.GREATER; - if (twoPasses) { - rs.cull = { - enabled : true, - face : CullFace.BACK - }; - primitive._frontFaceDepthFailRS = RenderState.fromCache(rs); + var context = frameState.context; + var primitive = classificationPrimitive._primitive; + var vs = ShadowVolumeVS; + vs = classificationPrimitive._primitive._batchTable.getVertexShaderCallback()(vs); + vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs); + vs = Primitive._modifyShaderPosition(classificationPrimitive, vs, frameState.scene3DOnly); + vs = Primitive._updateColorAttribute(primitive, vs); - rs.cull.face = CullFace.FRONT; - primitive._backFaceDepthFailRS = RenderState.fromCache(rs); - } else { - primitive._frontFaceDepthFailRS = RenderState.fromCache(rs); - primitive._backFaceDepthFailRS = primitive._frontFaceRS; - } + if (classificationPrimitive._extruded) { + vs = modifyForEncodedNormals(primitive, vs); } - } - function createShaderProgram(primitive, frameState, appearance) { - var context = frameState.context; + var extrudedDefine = classificationPrimitive._extruded ? 'EXTRUDED_GEOMETRY' : ''; - var attributeLocations = primitive._attributeLocations; + var vsSource = new ShaderSource({ + defines : [extrudedDefine], + sources : [vs] + }); + var fsSource = new ShaderSource({ + sources : [ShadowVolumeFS] + }); + var attributeLocations = classificationPrimitive._primitive._attributeLocations; - var vs = primitive._batchTable.getVertexShaderCallback()(appearance.vertexShaderSource); - vs = Primitive._appendShowToShader(primitive, vs); - vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); - vs = Primitive._updateColorAttribute(primitive, vs, false); - vs = modifyForEncodedNormals(primitive, vs); - vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); - var fs = appearance.getFragmentShaderSource(); + classificationPrimitive._spStencil = ShaderProgram.replaceCache({ + context : context, + shaderProgram : classificationPrimitive._spStencil, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, + attributeLocations : attributeLocations + }); - // Create pick program - if (primitive.allowPicking) { + if (classificationPrimitive._primitive.allowPicking) { var vsPick = ShaderSource.createPickVertexShaderSource(vs); + vsPick = Primitive._appendShowToShader(primitive, vsPick); vsPick = Primitive._updatePickColorAttribute(vsPick); - primitive._pickSP = ShaderProgram.replaceCache({ + var pickVS = new ShaderSource({ + defines : [extrudedDefine], + sources : [vsPick] + }); + + var pickFS = new ShaderSource({ + sources : [ShadowVolumeFS], + pickColorQualifier : 'varying' + }); + + classificationPrimitive._spPick = ShaderProgram.replaceCache({ context : context, - shaderProgram : primitive._pickSP, - vertexShaderSource : vsPick, - fragmentShaderSource : ShaderSource.createPickFragmentShaderSource(fs, 'varying'), + shaderProgram : classificationPrimitive._spPick, + vertexShaderSource : pickVS, + fragmentShaderSource : pickFS, attributeLocations : attributeLocations }); } else { - primitive._pickSP = ShaderProgram.fromCache({ + classificationPrimitive._spPick = ShaderProgram.fromCache({ context : context, - vertexShaderSource : vs, - fragmentShaderSource : fs, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); } - validateShaderMatching(primitive._pickSP, attributeLocations); - primitive._sp = ShaderProgram.replaceCache({ + vs = Primitive._appendShowToShader(primitive, vs); + vsSource = new ShaderSource({ + defines : [extrudedDefine], + sources : [vs] + }); + + classificationPrimitive._sp = ShaderProgram.replaceCache({ context : context, - shaderProgram : primitive._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, + shaderProgram : classificationPrimitive._sp, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); - validateShaderMatching(primitive._sp, attributeLocations); + } - if (defined(primitive._depthFailAppearance)) { - vs = primitive._batchTable.getVertexShaderCallback()(primitive._depthFailAppearance.vertexShaderSource); - vs = Primitive._appendShowToShader(primitive, vs); - vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); - vs = Primitive._updateColorAttribute(primitive, vs, true); - vs = modifyForEncodedNormals(primitive, vs); - vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); - vs = depthClampVS(vs); + function createColorCommands(classificationPrimitive, colorCommands) { + var primitive = classificationPrimitive._primitive; + var length = primitive._va.length * 3; + colorCommands.length = length; - fs = depthClampFS(primitive._depthFailAppearance.getFragmentShaderSource()); + var i; + var command; + var vaIndex = 0; + var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); - primitive._spDepthFail = ShaderProgram.replaceCache({ - context : context, - shaderProgram : primitive._spDepthFail, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - validateShaderMatching(primitive._spDepthFail, attributeLocations); - } - } + for (i = 0; i < length; i += 3) { + var vertexArray = primitive._va[vaIndex++]; - var modifiedModelViewScratch = new Matrix4(); - var rtcScratch = new Cartesian3(); + // stencil preload command + command = colorCommands[i]; + if (!defined(command)) { + command = colorCommands[i] = new DrawCommand({ + owner : classificationPrimitive, + primitiveType : primitive._primitiveType + }); + } - function getUniforms(primitive, appearance, material, frameState) { - // Create uniform map by combining uniforms from the appearance and material if either have uniforms. - var materialUniformMap = defined(material) ? material._uniforms : undefined; - var appearanceUniformMap = {}; - var appearanceUniforms = appearance.uniforms; - if (defined(appearanceUniforms)) { - // Convert to uniform map of functions for the renderer - for (var name in appearanceUniforms) { - if (appearanceUniforms.hasOwnProperty(name)) { - if (defined(materialUniformMap) && defined(materialUniformMap[name])) { - // Later, we could rename uniforms behind-the-scenes if needed. - throw new DeveloperError('Appearance and material have a uniform with the same name: ' + name); - } - - appearanceUniformMap[name] = getUniformFunction(appearanceUniforms, name); - } + command.vertexArray = vertexArray; + command.renderState = classificationPrimitive._rsStencilPreloadPass; + command.shaderProgram = classificationPrimitive._sp; + command.uniformMap = uniformMap; + + // stencil depth command + command = colorCommands[i + 1]; + if (!defined(command)) { + command = colorCommands[i + 1] = new DrawCommand({ + owner : classificationPrimitive, + primitiveType : primitive._primitiveType + }); } - } - var uniforms = combine(appearanceUniformMap, materialUniformMap); - uniforms = primitive._batchTable.getUniformMapCallback()(uniforms); - if (defined(primitive.rtcCenter)) { - uniforms.u_modifiedModelView = function() { - var viewMatrix = frameState.context.uniformState.view; - Matrix4.multiply(viewMatrix, primitive._modelMatrix, modifiedModelViewScratch); - Matrix4.multiplyByPoint(modifiedModelViewScratch, primitive.rtcCenter, rtcScratch); - Matrix4.setTranslation(modifiedModelViewScratch, rtcScratch, modifiedModelViewScratch); - return modifiedModelViewScratch; - }; + command.vertexArray = vertexArray; + command.renderState = classificationPrimitive._rsStencilDepthPass; + command.shaderProgram = classificationPrimitive._sp; + command.uniformMap = uniformMap; + + // color command + command = colorCommands[i + 2]; + if (!defined(command)) { + command = colorCommands[i + 2] = new DrawCommand({ + owner : classificationPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.renderState = classificationPrimitive._rsColorPass; + command.shaderProgram = classificationPrimitive._sp; + command.uniformMap = uniformMap; } - return uniforms; - } + var commandsIgnoreShow = classificationPrimitive._commandsIgnoreShow; + var spStencil = classificationPrimitive._spStencil; - function createCommands(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands, frameState) { - var uniforms = getUniforms(primitive, appearance, material, frameState); + var commandIndex = 0; + length = commandsIgnoreShow.length = length / 3 * 2; - var depthFailUniforms; - if (defined(primitive._depthFailAppearance)) { - depthFailUniforms = getUniforms(primitive, primitive._depthFailAppearance, primitive._depthFailAppearance.material, frameState); - } + for (var j = 0; j < length; j += 2) { + var commandIgnoreShow = commandsIgnoreShow[j] = DrawCommand.shallowClone(colorCommands[commandIndex], commandsIgnoreShow[j]); + commandIgnoreShow.shaderProgram = spStencil; + commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW; - var pass = translucent ? Pass.TRANSLUCENT : Pass.OPAQUE; + commandIgnoreShow = commandsIgnoreShow[j + 1] = DrawCommand.shallowClone(colorCommands[commandIndex + 1], commandsIgnoreShow[j + 1]); + commandIgnoreShow.shaderProgram = spStencil; + commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW; - var multiplier = twoPasses ? 2 : 1; - multiplier *= defined(primitive._depthFailAppearance) ? 2 : 1; + commandIndex += 3; + } + } - colorCommands.length = primitive._va.length * multiplier; - pickCommands.length = primitive._va.length; + function createPickCommands(classificationPrimitive, pickCommands) { + var primitive = classificationPrimitive._primitive; + var pickOffsets = primitive._pickOffsets; + var length = pickOffsets.length * 3; + pickCommands.length = length; - var length = colorCommands.length; - var m = 0; - var vaIndex = 0; - for (var i = 0; i < length; ++i) { - var colorCommand; + var j; + var command; + var pickIndex = 0; + var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); - if (twoPasses) { - colorCommand = colorCommands[i]; - if (!defined(colorCommand)) { - colorCommand = colorCommands[i] = new DrawCommand({ - owner : primitive, - primitiveType : primitive._primitiveType - }); - } - colorCommand.vertexArray = primitive._va[vaIndex]; - colorCommand.renderState = primitive._backFaceRS; - colorCommand.shaderProgram = primitive._sp; - colorCommand.uniformMap = uniforms; - colorCommand.pass = pass; + for (j = 0; j < length; j += 3) { + var pickOffset = pickOffsets[pickIndex++]; - ++i; - } + var offset = pickOffset.offset; + var count = pickOffset.count; + var vertexArray = primitive._va[pickOffset.index]; - colorCommand = colorCommands[i]; - if (!defined(colorCommand)) { - colorCommand = colorCommands[i] = new DrawCommand({ - owner : primitive, + // stencil preload command + command = pickCommands[j]; + if (!defined(command)) { + command = pickCommands[j] = new DrawCommand({ + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } - colorCommand.vertexArray = primitive._va[vaIndex]; - colorCommand.renderState = primitive._frontFaceRS; - colorCommand.shaderProgram = primitive._sp; - colorCommand.uniformMap = uniforms; - colorCommand.pass = pass; - - if (defined(primitive._depthFailAppearance)) { - if (twoPasses) { - ++i; - - colorCommand = colorCommands[i]; - if (!defined(colorCommand)) { - colorCommand = colorCommands[i] = new DrawCommand({ - owner : primitive, - primitiveType : primitive._primitiveType - }); - } - colorCommand.vertexArray = primitive._va[vaIndex]; - colorCommand.renderState = primitive._backFaceDepthFailRS; - colorCommand.shaderProgram = primitive._spDepthFail; - colorCommand.uniformMap = depthFailUniforms; - colorCommand.pass = pass; - } - ++i; + command.vertexArray = vertexArray; + command.offset = offset; + command.count = count; + command.renderState = classificationPrimitive._rsStencilPreloadPass; + command.shaderProgram = classificationPrimitive._spStencil; + command.uniformMap = uniformMap; - colorCommand = colorCommands[i]; - if (!defined(colorCommand)) { - colorCommand = colorCommands[i] = new DrawCommand({ - owner : primitive, - primitiveType : primitive._primitiveType - }); - } - colorCommand.vertexArray = primitive._va[vaIndex]; - colorCommand.renderState = primitive._frontFaceDepthFailRS; - colorCommand.shaderProgram = primitive._spDepthFail; - colorCommand.uniformMap = depthFailUniforms; - colorCommand.pass = pass; + // stencil depth command + command = pickCommands[j + 1]; + if (!defined(command)) { + command = pickCommands[j + 1] = new DrawCommand({ + owner : classificationPrimitive, + primitiveType : primitive._primitiveType + }); } - var pickCommand = pickCommands[m]; - if (!defined(pickCommand)) { - pickCommand = pickCommands[m] = new DrawCommand({ - owner : primitive, + command.vertexArray = vertexArray; + command.offset = offset; + command.count = count; + command.renderState = classificationPrimitive._rsStencilDepthPass; + command.shaderProgram = classificationPrimitive._spStencil; + command.uniformMap = uniformMap; + + // color command + command = pickCommands[j + 2]; + if (!defined(command)) { + command = pickCommands[j + 2] = new DrawCommand({ + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } - pickCommand.vertexArray = primitive._va[vaIndex]; - pickCommand.renderState = primitive._pickRS; - pickCommand.shaderProgram = primitive._pickSP; - pickCommand.uniformMap = uniforms; - pickCommand.pass = pass; - ++m; - ++vaIndex; + command.vertexArray = vertexArray; + command.offset = offset; + command.count = count; + command.renderState = classificationPrimitive._rsPickPass; + command.shaderProgram = classificationPrimitive._spPick; + command.uniformMap = uniformMap; } } - Primitive._updateBoundingVolumes = function(primitive, frameState, modelMatrix) { - var i; - var length; - var boundingSphere; - - // Update bounding volumes for primitives that are sized in pixels. - // The pixel size in meters varies based on the distance from the camera. - var pixelSize = primitive.appearance.pixelSize; - if (defined(pixelSize)) { - length = primitive._boundingSpheres.length; - for (i = 0; i < length; ++i) { - boundingSphere = primitive._boundingSpheres[i]; - var boundingSphereWC = primitive._boundingSphereWC[i]; - var pixelSizeInMeters = frameState.camera.getPixelSize(boundingSphere, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); - var sizeInMeters = pixelSizeInMeters * pixelSize; - boundingSphereWC.radius = boundingSphere.radius + sizeInMeters; - } - } + function createCommands(classificationPrimitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { + createColorCommands(classificationPrimitive, colorCommands); + createPickCommands(classificationPrimitive, pickCommands); + } - if (!Matrix4.equals(modelMatrix, primitive._modelMatrix)) { - Matrix4.clone(modelMatrix, primitive._modelMatrix); - length = primitive._boundingSpheres.length; - for (i = 0; i < length; ++i) { - boundingSphere = primitive._boundingSpheres[i]; - if (defined(boundingSphere)) { - primitive._boundingSphereWC[i] = BoundingSphere.transform(boundingSphere, modelMatrix, primitive._boundingSphereWC[i]); - if (!frameState.scene3DOnly) { - primitive._boundingSphere2D[i] = BoundingSphere.clone(primitive._boundingSphereCV[i], primitive._boundingSphere2D[i]); - primitive._boundingSphere2D[i].center.x = 0.0; - primitive._boundingSphereMorph[i] = BoundingSphere.union(primitive._boundingSphereWC[i], primitive._boundingSphereCV[i]); - } - } - } - } - }; + function boundingVolumeIndex(commandIndex, length) { + return Math.floor((commandIndex % length) / 3); + } - function updateAndQueueCommands(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - if (frameState.mode !== SceneMode.SCENE3D && !Matrix4.equals(modelMatrix, Matrix4.IDENTITY)) { - throw new DeveloperError('Primitive.modelMatrix is only supported in 3D mode.'); - } - + function updateAndQueueCommands(classificationPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + var primitive = classificationPrimitive._primitive; Primitive._updateBoundingVolumes(primitive, frameState, modelMatrix); - var boundingSpheres; + var boundingVolumes; if (frameState.mode === SceneMode.SCENE3D) { - boundingSpheres = primitive._boundingSphereWC; + boundingVolumes = primitive._boundingSphereWC; } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { - boundingSpheres = primitive._boundingSphereCV; + boundingVolumes = primitive._boundingSphereCV; } else if (frameState.mode === SceneMode.SCENE2D && defined(primitive._boundingSphere2D)) { - boundingSpheres = primitive._boundingSphere2D; + boundingVolumes = primitive._boundingSphere2D; } else if (defined(primitive._boundingSphereMorph)) { - boundingSpheres = primitive._boundingSphereMorph; + boundingVolumes = primitive._boundingSphereMorph; } var commandList = frameState.commandList; var passes = frameState.passes; - if (passes.render) { - var castShadows = ShadowMode.castShadows(primitive.shadows); - var receiveShadows = ShadowMode.receiveShadows(primitive.shadows); - var colorLength = colorCommands.length; - var factor = twoPasses ? 2 : 1; - factor *= defined(primitive._depthFailAppearance) ? 2 : 1; + var i; + var pass; + switch (classificationPrimitive.classificationType) { + case ClassificationType.TERRAIN: + pass = Pass.TERRAIN_CLASSIFICATION; + break; + case ClassificationType.CESIUM_3D_TILE: + pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; + break; + default: + pass = Pass.CLASSIFICATION; + } - for (var j = 0; j < colorLength; ++j) { - var sphereIndex = Math.floor(j / factor); - var colorCommand = colorCommands[j]; + if (passes.render) { + var colorCommand; + var colorLength = colorCommands.length; + for (i = 0; i < colorLength; ++i) { + colorCommand = colorCommands[i]; colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingSpheres[sphereIndex]; + colorCommand.boundingVolume = boundingVolumes[boundingVolumeIndex(i, colorLength)]; colorCommand.cull = cull; colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; - colorCommand.castShadows = castShadows; - colorCommand.receiveShadows = receiveShadows; + colorCommand.pass = pass; commandList.push(colorCommand); } + + if (frameState.invertClassification) { + var ignoreShowCommands = classificationPrimitive._commandsIgnoreShow; + var ignoreShowCommandsLength = ignoreShowCommands.length; + + for (i = 0; i < ignoreShowCommandsLength; ++i) { + var bvIndex = Math.floor(i / 2); + colorCommand = ignoreShowCommands[i]; + colorCommand.modelMatrix = modelMatrix; + colorCommand.boundingVolume = boundingVolumes[bvIndex]; + colorCommand.cull = cull; + colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + + commandList.push(colorCommand); + } + } } if (passes.pick) { var pickLength = pickCommands.length; - for (var k = 0; k < pickLength; ++k) { - var pickCommand = pickCommands[k]; + var pickOffsets = primitive._pickOffsets; + for (i = 0; i < pickLength; ++i) { + var pickOffset = pickOffsets[boundingVolumeIndex(i, pickLength)]; + var pickCommand = pickCommands[i]; pickCommand.modelMatrix = modelMatrix; - pickCommand.boundingVolume = boundingSpheres[k]; + pickCommand.boundingVolume = boundingVolumes[pickOffset.index]; pickCommand.cull = cull; + pickCommand.pass = pass; commandList.push(pickCommand); } @@ -99662,161 +110503,108 @@ define('Scene/Primitive',[ * * @exception {DeveloperError} All instance geometries must have the same primitiveType. * @exception {DeveloperError} Appearance and material have a uniform with the same name. - * @exception {DeveloperError} Primitive.modelMatrix is only supported in 3D mode. - * @exception {RuntimeError} Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero. + * @exception {DeveloperError} Not all of the geometry instances have the same color attribute. */ - Primitive.prototype.update = function(frameState) { - if (((!defined(this.geometryInstances)) && (this._va.length === 0)) || - (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length === 0) || - (!defined(this.appearance)) || - (frameState.mode !== SceneMode.SCENE3D && frameState.scene3DOnly) || - (!frameState.passes.render && !frameState.passes.pick)) { + ClassificationPrimitive.prototype.update = function(frameState) { + if (!this.show || (!defined(this._primitive) && !defined(this.geometryInstances))) { return; } - if (defined(this._error)) { - throw this._error; - } + var that = this; + var primitiveOptions = this._primitiveOptions; - if (defined(this.rtcCenter) && !frameState.scene3DOnly) { - throw new DeveloperError('RTC rendering is only available for 3D only scenes.'); - } - - if (this._state === PrimitiveState.FAILED) { - return; - } + if (!defined(this._primitive)) { + var instances = isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; + var length = instances.length; - var context = frameState.context; - if (!defined(this._batchTable)) { - createBatchTable(this, context); - } - if (this._batchTable.attributes.length > 0) { - if (ContextLimits.maximumVertexTextureImageUnits === 0) { - throw new RuntimeError('Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero.'); + var i; + var instance; + var color; + for (i = 0; i < length; ++i) { + instance = instances[i]; + var attributes = instance.attributes; + if (!defined(attributes) || !defined(attributes.color)) { + throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); + } else if (defined(color) && !ColorGeometryInstanceAttribute.equals(color, attributes.color)) { + throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); + } else if (!defined(color)) { + color = attributes.color; + } } - this._batchTable.update(frameState); - } - - if (this._state !== PrimitiveState.COMPLETE && this._state !== PrimitiveState.COMBINED) { - if (this.asynchronous) { - loadAsynchronous(this, frameState); - } else { - loadSynchronous(this, frameState); + + var geometryInstances = new Array(length); + for (i = 0; i < length; ++i) { + instance = instances[i]; + geometryInstances[i] = new GeometryInstance({ + geometry : instance.geometry, + attributes : instance.attributes, + modelMatrix : instance.modelMatrix, + id : instance.id, + pickPrimitive : defaultValue(this._pickPrimitive, that) + }); } - } - - if (this._state === PrimitiveState.COMBINED) { - updateBatchTableBoundingSpheres(this, frameState); - createVertexArray(this, frameState); - } - - if (!this.show || this._state !== PrimitiveState.COMPLETE) { - return; - } - - // Create or recreate render state and shader program if appearance/material changed - var appearance = this.appearance; - var material = appearance.material; - var createRS = false; - var createSP = false; - - if (this._appearance !== appearance) { - this._appearance = appearance; - this._material = material; - createRS = true; - createSP = true; - } else if (this._material !== material ) { - this._material = material; - createSP = true; - } - var depthFailAppearance = this.depthFailAppearance; - var depthFailMaterial = defined(depthFailAppearance) ? depthFailAppearance.material : undefined; + primitiveOptions.geometryInstances = geometryInstances; - if (this._depthFailAppearance !== depthFailAppearance) { - this._depthFailAppearance = depthFailAppearance; - this._depthFailMaterial = depthFailMaterial; - createRS = true; - createSP = true; - } else if (this._depthFailMaterial !== depthFailMaterial) { - this._depthFailMaterial = depthFailMaterial; - createSP = true; - } + if (defined(this._createBoundingVolumeFunction)) { + primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { + that._createBoundingVolumeFunction(frameState, geometry); + }; + } - var translucent = this._appearance.isTranslucent(); - if (this._translucent !== translucent) { - this._translucent = translucent; - createRS = true; - } + primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { + createRenderStates(that, context); + }; + primitiveOptions._createShaderProgramFunction = function(primitive, frameState, appearance) { + createShaderProgram(that, frameState); + }; + primitiveOptions._createCommandsFunction = function(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { + createCommands(that, undefined, undefined, true, false, colorCommands, pickCommands); + }; - if (defined(this._material)) { - this._material.update(context); - } + if (defined(this._updateAndQueueCommandsFunction)) { + primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + that._updateAndQueueCommandsFunction(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); + }; + } else { + primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); + }; + } - var twoPasses = appearance.closed && translucent; + this._primitive = new Primitive(primitiveOptions); + this._primitive.readyPromise.then(function(primitive) { + that._ready = true; - if (createRS) { - var rsFunc = defaultValue(this._createRenderStatesFunction, createRenderStates); - rsFunc(this, context, appearance, twoPasses); - } + if (that.releaseGeometryInstances) { + that.geometryInstances = undefined; + } - if (createSP) { - var spFunc = defaultValue(this._createShaderProgramFunction, createShaderProgram); - spFunc(this, frameState, appearance); + var error = primitive._error; + if (!defined(error)) { + that._readyPromise.resolve(that); + } else { + that._readyPromise.reject(error); + } + }); } - if (createRS || createSP) { - var commandFunc = defaultValue(this._createCommandsFunction, createCommands); - commandFunc(this, appearance, material, translucent, twoPasses, this._colorCommands, this._pickCommands, frameState); + if (this.debugShowShadowVolume && !this._debugShowShadowVolume && this._ready) { + this._debugShowShadowVolume = true; + this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(false)); + this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(false)); + this._rsColorPass = RenderState.fromCache(getColorRenderState(false)); + } else if (!this.debugShowShadowVolume && this._debugShowShadowVolume) { + this._debugShowShadowVolume = false; + this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(true)); + this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(true)); + this._rsColorPass = RenderState.fromCache(getColorRenderState(true)); } - var updateAndQueueCommandsFunc = defaultValue(this._updateAndQueueCommandsFunction, updateAndQueueCommands); - updateAndQueueCommandsFunc(this, frameState, this._colorCommands, this._pickCommands, this.modelMatrix, this.cull, this.debugShowBoundingVolume, twoPasses); + this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; + this._primitive.update(frameState); }; - function createGetFunction(batchTable, instanceIndex, attributeIndex) { - return function() { - var attributeValue = batchTable.getBatchedAttribute(instanceIndex, attributeIndex); - var attribute = batchTable.attributes[attributeIndex]; - var componentsPerAttribute = attribute.componentsPerAttribute; - var value = ComponentDatatype.createTypedArray(attribute.componentDatatype, componentsPerAttribute); - if (defined(attributeValue.constructor.pack)) { - attributeValue.constructor.pack(attributeValue, value, 0); - } else { - value[0] = attributeValue; - } - return value; - }; - } - - function createSetFunction(batchTable, instanceIndex, attributeIndex) { - return function(value) { - if (!defined(value) || !defined(value.length) || value.length < 1 || value.length > 4) { - throw new DeveloperError('value must be and array with length between 1 and 4.'); - } - var attributeValue = getAttributeValue(value); - batchTable.setBatchedAttribute(instanceIndex, attributeIndex, attributeValue); - }; - } - - function createBoundingSphereProperties(primitive, properties, index) { - properties.boundingSphere = { - get : function() { - var boundingSphere = primitive._instanceBoundingSpheres[index]; - var modelMatrix = primitive.modelMatrix; - if (defined(modelMatrix) && defined(boundingSphere)) { - boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix); - } - return boundingSphere; - } - }; - properties.boundingSphereCV = { - get : function() { - return primitive._instanceBoundingSpheresCV[index]; - } - }; - } - /** * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. * @@ -99829,73 +110617,12 @@ define('Scene/Primitive',[ * var attributes = primitive.getGeometryInstanceAttributes('an id'); * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true); - * attributes.distanceDisplayCondition = Cesium.DistanceDisplayConditionGeometryInstanceAttribute.toValue(100.0, 10000.0); */ - Primitive.prototype.getGeometryInstanceAttributes = function(id) { - if (!defined(id)) { - throw new DeveloperError('id is required'); - } - if (!defined(this._batchTable)) { + ClassificationPrimitive.prototype.getGeometryInstanceAttributes = function(id) { + if (!defined(this._primitive)) { throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); } - - var index = -1; - var lastIndex = this._lastPerInstanceAttributeIndex; - var ids = this._instanceIds; - var length = ids.length; - for (var i = 0; i < length; ++i) { - var curIndex = (lastIndex + i) % length; - if (id === ids[curIndex]) { - index = curIndex; - break; - } - } - - if (index === -1) { - return undefined; - } - - var attributes = this._perInstanceAttributeCache[index]; - if (defined(attributes)) { - return attributes; - } - - var batchTable = this._batchTable; - var perInstanceAttributeIndices = this._batchTableAttributeIndices; - attributes = {}; - var properties = {}; - - for (var name in perInstanceAttributeIndices) { - if (perInstanceAttributeIndices.hasOwnProperty(name)) { - var attributeIndex = perInstanceAttributeIndices[name]; - properties[name] = { - get : createGetFunction(batchTable, index, attributeIndex) - }; - - var createSetter = true; - var readOnlyAttributes = this._readOnlyInstanceAttributes; - if (createSetter && defined(readOnlyAttributes)) { - length = readOnlyAttributes.length; - for (var k = 0; k < length; ++k) { - if (name === readOnlyAttributes[k]) { - createSetter = false; - break; - } - } - } - - if (createSetter) { - properties[name].set = createSetFunction(batchTable, index, attributeIndex); - } - } - } - - createBoundingSphereProperties(this, properties, index); - defineProperties(attributes, properties); - - this._lastPerInstanceAttributeIndex = index; - this._perInstanceAttributeCache[index] = attributes; - return attributes; + return this._primitive.getGeometryInstanceAttributes(id); }; /** @@ -99907,9 +110634,9 @@ define('Scene/Primitive',[ * * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * - * @see Primitive#destroy + * @see ClassificationPrimitive#destroy */ - Primitive.prototype.isDestroyed = function() { + ClassificationPrimitive.prototype.isDestroyed = function() { return false; }; @@ -99926,9400 +110653,10060 @@ define('Scene/Primitive',[ * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * - * * @example * e = e && e.destroy(); * - * @see Primitive#isDestroyed + * @see ClassificationPrimitive#isDestroyed */ - Primitive.prototype.destroy = function() { - var length; - var i; - + ClassificationPrimitive.prototype.destroy = function() { + this._primitive = this._primitive && this._primitive.destroy(); this._sp = this._sp && this._sp.destroy(); - this._pickSP = this._pickSP && this._pickSP.destroy(); - - var va = this._va; - length = va.length; - for (i = 0; i < length; ++i) { - va[i].destroy(); - } - this._va = undefined; - - var pickIds = this._pickIds; - length = pickIds.length; - for (i = 0; i < length; ++i) { - pickIds[i].destroy(); - } - this._pickIds = undefined; - - this._batchTable = this._batchTable && this._batchTable.destroy(); - - //These objects may be fairly large and reference other large objects (like Entities) - //We explicitly set them to undefined here so that the memory can be freed - //even if a reference to the destroyed Primitive has been kept around. - this._instanceIds = undefined; - this._perInstanceAttributeCache = undefined; - this._attributeLocations = undefined; - + this._spPick = this._spPick && this._spPick.destroy(); return destroyObject(this); }; - function setReady(primitive, frameState, state, error) { - primitive._error = error; - primitive._state = state; - frameState.afterRender.push(function() { - primitive._ready = primitive._state === PrimitiveState.COMPLETE || primitive._state === PrimitiveState.FAILED; - if (!defined(error)) { - primitive._readyPromise.resolve(primitive); - } else { - primitive._readyPromise.reject(error); - } - }); - } - - return Primitive; -}); - -define('DataSources/ColorMaterialProperty',[ - '../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' - ], function( - Color, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { - 'use strict'; - - /** - * A {@link MaterialProperty} that maps to solid color {@link Material} uniforms. - * - * @param {Property} [color=Color.WHITE] The {@link Color} Property to be used. - * - * @alias ColorMaterialProperty - * @constructor - */ - function ColorMaterialProperty(color) { - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this.color = color; - } - - defineProperties(ColorMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof ColorMaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._color); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof ColorMaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets or sets the {@link Color} {@link Property}. - * @memberof ColorMaterialProperty.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color') - }); - - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - ColorMaterialProperty.prototype.getType = function(time) { - return 'Color'; - }; - - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ColorMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.color = Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color); - return result; - }; - - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - ColorMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof ColorMaterialProperty && // - Property.equals(this._color, other._color)); - }; - - return ColorMaterialProperty; + return ClassificationPrimitive; }); -define('DataSources/dynamicGeometryGetBoundingSphere',[ +define('Scene/GroundPrimitive',[ '../Core/BoundingSphere', - '../Core/defined', - '../Core/DeveloperError', - './BoundingSphereState' - ], function( - BoundingSphere, - defined, - DeveloperError, - BoundingSphereState) { - 'use strict'; - - /** - * @private - */ - function dynamicGeometryGetBoundingSphere(entity, primitive, outlinePrimitive, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); - } - if (!defined(result)) { - throw new DeveloperError('result is required.'); - } - - var attributes; - - //Outline and Fill geometries have the same bounding sphere, so just use whichever one is defined and ready - if (defined(primitive) && primitive.show && primitive.ready) { - attributes = primitive.getGeometryInstanceAttributes(entity); - if (defined(attributes) && defined(attributes.boundingSphere)) { - BoundingSphere.clone(attributes.boundingSphere, result); - return BoundingSphereState.DONE; - } - } - - if (defined(outlinePrimitive) && outlinePrimitive.show && outlinePrimitive.ready) { - attributes = outlinePrimitive.getGeometryInstanceAttributes(entity); - if (defined(attributes) && defined(attributes.boundingSphere)) { - BoundingSphere.clone(attributes.boundingSphere, result); - return BoundingSphereState.DONE; - } - } - - if ((defined(primitive) && !primitive.ready) || (defined(outlinePrimitive) && !outlinePrimitive.ready)) { - return BoundingSphereState.PENDING; - } - - return BoundingSphereState.FAILED; - } - - return dynamicGeometryGetBoundingSphere; -}); - -define('DataSources/MaterialProperty',[ - '../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Scene/Material' - ], function( - Color, - defined, - defineProperties, - DeveloperError, - Material) { - 'use strict'; - - /** - * The interface for all {@link Property} objects that represent {@link Material} uniforms. - * This type defines an interface and cannot be instantiated directly. - * - * @alias MaterialProperty - * @constructor - * - * @see ColorMaterialProperty - * @see CompositeMaterialProperty - * @see GridMaterialProperty - * @see ImageMaterialProperty - * @see PolylineGlowMaterialProperty - * @see PolylineOutlineMaterialProperty - * @see StripeMaterialProperty - */ - function MaterialProperty() { - DeveloperError.throwInstantiationError(); - } - - defineProperties(MaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof MaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof MaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Gets the {@link Material} type at the provided time. - * @function - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; - - /** - * Gets the value of the property at the provided time. - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; - - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * @function - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - MaterialProperty.prototype.equals = DeveloperError.throwInstantiationError; - - /** - * @private - */ - MaterialProperty.getValue = function(time, materialProperty, material) { - var type; - - if (defined(materialProperty)) { - type = materialProperty.getType(time); - if (defined(type)) { - if (!defined(material) || (material.type !== type)) { - material = Material.fromType(type); - } - materialProperty.getValue(time, material.uniforms); - return material; - } - } - - if (!defined(material) || (material.type !== Material.ColorType)) { - material = Material.fromType(Material.ColorType); - } - Color.clone(Color.WHITE, material.uniforms.color); - - return material; - }; - - return MaterialProperty; -}); - -define('DataSources/BoxGeometryUpdater',[ - '../Core/BoxGeometry', - '../Core/BoxOutlineGeometry', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', + '../Core/buildModuleUrl', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartographic', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', + '../Core/GeographicTilingScheme', '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' + '../Core/isArray', + '../Core/Math', + '../Core/OrientedBoundingBox', + '../Core/Rectangle', + '../Core/Resource', + '../Renderer/Pass', + '../ThirdParty/when', + './ClassificationPrimitive', + './ClassificationType', + './SceneMode' ], function( - BoxGeometry, - BoxOutlineGeometry, - Color, - ColorGeometryInstanceAttribute, + BoundingSphere, + buildModuleUrl, + Cartesian2, + Cartesian3, + Cartographic, defaultValue, defined, defineProperties, destroyObject, DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, + GeographicTilingScheme, GeometryInstance, - Iso8601, - ShowGeometryInstanceAttribute, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { + isArray, + CesiumMath, + OrientedBoundingBox, + Rectangle, + Resource, + Pass, + when, + ClassificationPrimitive, + ClassificationType, + SceneMode) { 'use strict'; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + var GroundPrimitiveUniformMap = { + u_globeMinimumAltitude: function() { + return 55000.0; + } + }; - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.dimensions = undefined; - } + var terrainHeightsResource = new Resource({ + url: buildModuleUrl('Assets/approximateTerrainHeights.json') + }); /** - * A {@link GeometryUpdater} for boxes. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias BoxGeometryUpdater + * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. + * Batching multiple geometries is not yet supported. + * <p> + * A primitive combines the geometry instance with an {@link Appearance} that describes the full shading, including + * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, + * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix + * and match most of them and add a new geometry or appearance independently of each other. Only the {@link PerInstanceColorAppearance} + * is supported at this time. + * </p> + * <p> + * For correct rendering, this feature requires the EXT_frag_depth WebGL extension. For hardware that do not support this extension, there + * will be rendering artifacts for some viewing angles. + * </p> + * <p> + * Valid geometries are {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}. + * </p> + * + * @alias GroundPrimitive * @constructor * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. + * @param {Object} [options] Object with the following properties: + * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. + * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. + * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on + * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be <code>false</code>. + * + * @example + * // Example 1: Create primitive with a single instance + * var rectangleInstance = new Cesium.GeometryInstance({ + * geometry : new Cesium.RectangleGeometry({ + * rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0) + * }), + * id : 'rectangle', + * attributes : { + * color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5) + * } + * }); + * scene.primitives.add(new Cesium.GroundPrimitive({ + * geometryInstances : rectangleInstance + * })); + * + * // Example 2: Batch instances + * var color = new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5); // Both instances must have the same color. + * var rectangleInstance = new Cesium.GeometryInstance({ + * geometry : new Cesium.RectangleGeometry({ + * rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0) + * }), + * id : 'rectangle', + * attributes : { + * color : color + * } + * }); + * var ellipseInstance = new Cesium.GeometryInstance({ + * geometry : new Cesium.EllipseGeometry({ + * center : Cesium.Cartesian3.fromDegrees(-105.0, 40.0), + * semiMinorAxis : 300000.0, + * semiMajorAxis : 400000.0 + * }), + * id : 'ellipse', + * attributes : { + * color : color + * } + * }); + * scene.primitives.add(new Cesium.GroundPrimitive({ + * geometryInstances : [rectangleInstance, ellipseInstance] + * })); + * + * @see Primitive + * @see ClassificationPrimitive + * @see GeometryInstance + * @see Appearance */ - function BoxGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); - } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(BoxGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'box', entity.box, undefined); - } - - defineProperties(BoxGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof BoxGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof BoxGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance - } - }); + function GroundPrimitive(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - defineProperties(BoxGeometryUpdater.prototype, { /** - * Gets the entity associated with this geometry. - * @memberof BoxGeometryUpdater.prototype + * The geometry instance rendered with this primitive. This may + * be <code>undefined</code> if <code>options.releaseGeometryInstances</code> + * is <code>true</code> when the primitive is constructed. + * <p> + * Changing this property after the primitive is rendered has no effect. + * </p> + * <p> + * Because of the rendering technique used, all geometry instances must be the same color. + * If there is an instance with a differing color, a <code>DeveloperError</code> will be thrown + * on the first attempt to render. + * </p> * - * @type {Entity} * @readonly + * @type {Array|GeometryInstance} + * + * @default undefined */ - entity : { - get : function() { - return this._entity; - } - }, + this.geometryInstances = options.geometryInstances; /** - * Gets a value indicating if the geometry has a fill component. - * @memberof BoxGeometryUpdater.prototype + * Determines if the primitive will be shown. This affects all geometry + * instances in the primitive. * * @type {Boolean} - * @readonly + * + * @default true */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, + this.show = defaultValue(options.show, true); /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof BoxGeometryUpdater.prototype + * Determines whether terrain, 3D Tiles or both will be classified. * - * @type {Boolean} - * @readonly + * @type {ClassificationType} + * + * @default ClassificationType.BOTH */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, + this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); /** - * Gets the material property used to fill the geometry. - * @memberof BoxGeometryUpdater.prototype + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the primitive. + * </p> * - * @type {MaterialProperty} - * @readonly + * @type {Boolean} + * + * @default false */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof BoxGeometryUpdater.prototype + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the shadow volume for each geometry in the primitive. + * </p> * * @type {Boolean} - * @readonly + * + * @default false */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, + this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); + + this._boundingVolumes = []; + this._boundingVolumes2D = []; + + this._ready = false; + this._readyPromise = when.defer(); + + this._primitive = undefined; + + this._maxHeight = undefined; + this._minHeight = undefined; + + this._maxTerrainHeight = GroundPrimitive._defaultMaxTerrainHeight; + this._minTerrainHeight = GroundPrimitive._defaultMinTerrainHeight; + + this._boundingSpheresKeys = []; + this._boundingSpheres = []; + + var that = this; + this._primitiveOptions = { + geometryInstances : undefined, + vertexCacheOptimize : defaultValue(options.vertexCacheOptimize, false), + interleave : defaultValue(options.interleave, false), + releaseGeometryInstances : defaultValue(options.releaseGeometryInstances, true), + allowPicking : defaultValue(options.allowPicking, true), + asynchronous : defaultValue(options.asynchronous, true), + compressVertices : defaultValue(options.compressVertices, true), + _createBoundingVolumeFunction : undefined, + _updateAndQueueCommandsFunction : undefined, + _pickPrimitive : that, + _extruded : true, + _uniformMap : GroundPrimitiveUniformMap + }; + } + + defineProperties(GroundPrimitive.prototype, { /** - * Gets a value indicating if the geometry has an outline component. - * @memberof BoxGeometryUpdater.prototype + * When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * + * @memberof GroundPrimitive.prototype * * @type {Boolean} * @readonly + * + * @default true */ - hasConstantOutline : { + vertexCacheOptimize : { get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); + return this._primitiveOptions.vertexCacheOptimize; } }, + /** - * Gets the {@link Color} property for the geometry outline. - * @memberof BoxGeometryUpdater.prototype + * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. * - * @type {Property} + * @memberof GroundPrimitive.prototype + * + * @type {Boolean} * @readonly + * + * @default false */ - outlineColorProperty : { + interleave : { get : function() { - return this._outlineColorProperty; + return this._primitiveOptions.interleave; } }, + /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof BoxGeometryUpdater.prototype + * When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. * - * @type {Number} + * @memberof GroundPrimitive.prototype + * + * @type {Boolean} * @readonly + * + * @default true */ - outlineWidth : { + releaseGeometryInstances : { get : function() { - return this._outlineWidth; + return this._primitiveOptions.releaseGeometryInstances; } }, + /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof BoxGeometryUpdater.prototype + * When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. * - * @type {Property} + * @memberof GroundPrimitive.prototype + * + * @type {Boolean} * @readonly + * + * @default true */ - shadowsProperty : { + allowPicking : { get : function() { - return this._shadowsProperty; + return this._primitiveOptions.allowPicking; } }, + /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof BoxGeometryUpdater.prototype + * Determines if the geometry instances will be created and batched on a web worker. * - * @type {Property} + * @memberof GroundPrimitive.prototype + * + * @type {Boolean} * @readonly + * + * @default true */ - distanceDisplayConditionProperty : { + asynchronous : { get : function() { - return this._distanceDisplayConditionProperty; + return this._primitiveOptions.asynchronous; } }, + /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof BoxGeometryUpdater.prototype + * When <code>true</code>, geometry vertices are compressed, which will save memory. + * + * @memberof GroundPrimitive.prototype * * @type {Boolean} * @readonly + * + * @default true */ - isDynamic : { + compressVertices : { get : function() { - return this._dynamic; + return this._primitiveOptions.compressVertices; } }, + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof BoxGeometryUpdater.prototype + * Determines if the primitive is complete and ready to render. If this property is + * true, the primitive will be rendered the next time that {@link GroundPrimitive#update} + * is called. + * + * @memberof GroundPrimitive.prototype * * @type {Boolean} * @readonly */ - isClosed : { - value : true + ready : { + get : function() { + return this._ready; + } }, + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof BoxGeometryUpdater.prototype - * - * @type {Boolean} + * Gets a promise that resolves when the primitive is ready to render. + * @memberof GroundPrimitive.prototype + * @type {Promise.<GroundPrimitive>} * @readonly */ - geometryChanged : { + readyPromise : { get : function() { - return this._geometryChanged; + return this._readyPromise.promise; } } }); /** - * Checks if the geometry is outlined at the provided time. + * Determines if GroundPrimitive rendering is supported. * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + * @param {Scene} scene The scene. + * @returns {Boolean} <code>true</code> if GroundPrimitives are supported; otherwise, returns <code>false</code> */ - BoxGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + GroundPrimitive.isSupported = ClassificationPrimitive.isSupported; - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - BoxGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; + GroundPrimitive._defaultMaxTerrainHeight = 9000.0; + GroundPrimitive._defaultMinTerrainHeight = -100000.0; - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - BoxGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + GroundPrimitive._terrainHeights = undefined; + GroundPrimitive._terrainHeightsMaxLevel = 6; - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); + function getComputeMaximumHeightFunction(primitive) { + return function(granularity, ellipsoid) { + var r = ellipsoid.maximumRadius; + var delta = (r / Math.cos(granularity * 0.5)) - r; + return primitive._maxHeight + delta; + }; + } - var attributes; + function getComputeMinimumHeightFunction(primitive) { + return function(granularity, ellipsoid) { + return primitive._minHeight; + }; + } - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; - } + var scratchBVCartesianHigh = new Cartesian3(); + var scratchBVCartesianLow = new Cartesian3(); + var scratchBVCartesian = new Cartesian3(); + var scratchBVCartographic = new Cartographic(); + var scratchBVRectangle = new Rectangle(); + var tilingScheme = new GeographicTilingScheme(); + var scratchCorners = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; + var scratchTileXY = new Cartesian2(); - return new GeometryInstance({ - id : entity, - geometry : BoxGeometry.fromDimensions(this._options), - modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), - attributes : attributes - }); - }; + function getRectangle(frameState, geometry) { + var ellipsoid = frameState.mapProjection.ellipsoid; - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - BoxGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + if (!defined(geometry.attributes) || !defined(geometry.attributes.position3DHigh)) { + if (defined(geometry.rectangle)) { + return geometry.rectangle; + } - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + return undefined; } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - return new GeometryInstance({ - id : entity, - geometry : BoxOutlineGeometry.fromDimensions(this._options), - modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) - } - }); - }; + var highPositions = geometry.attributes.position3DHigh.values; + var lowPositions = geometry.attributes.position3DLow.values; + var length = highPositions.length; - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - BoxGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + var minLat = Number.POSITIVE_INFINITY; + var minLon = Number.POSITIVE_INFINITY; + var maxLat = Number.NEGATIVE_INFINITY; + var maxLon = Number.NEGATIVE_INFINITY; - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - BoxGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + for (var i = 0; i < length; i +=3) { + var highPosition = Cartesian3.unpack(highPositions, i, scratchBVCartesianHigh); + var lowPosition = Cartesian3.unpack(lowPositions, i, scratchBVCartesianLow); - BoxGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'box')) { - return; - } + var position = Cartesian3.add(highPosition, lowPosition, scratchBVCartesian); + var cartographic = ellipsoid.cartesianToCartographic(position, scratchBVCartographic); - var box = this._entity.box; + var latitude = cartographic.latitude; + var longitude = cartographic.longitude; - if (!defined(box)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + minLat = Math.min(minLat, latitude); + minLon = Math.min(minLon, longitude); + maxLat = Math.max(maxLat, latitude); + maxLon = Math.max(maxLon, longitude); } - var fillProperty = box.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + var rectangle = scratchBVRectangle; + rectangle.north = maxLat; + rectangle.south = minLat; + rectangle.east = maxLon; + rectangle.west = minLon; - var outlineProperty = box.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); - } + return rectangle; + } - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + var scratchDiagonalCartesianNE = new Cartesian3(); + var scratchDiagonalCartesianSW = new Cartesian3(); + var scratchDiagonalCartographic = new Cartographic(); + var scratchCenterCartesian = new Cartesian3(); + var scratchSurfaceCartesian = new Cartesian3(); - var dimensions = box.dimensions; - var position = entity.position; + function getTileXYLevel(rectangle) { + Cartographic.fromRadians(rectangle.east, rectangle.north, 0.0, scratchCorners[0]); + Cartographic.fromRadians(rectangle.west, rectangle.north, 0.0, scratchCorners[1]); + Cartographic.fromRadians(rectangle.east, rectangle.south, 0.0, scratchCorners[2]); + Cartographic.fromRadians(rectangle.west, rectangle.south, 0.0, scratchCorners[3]); - var show = box.show; - if (!defined(dimensions) || !defined(position) || (defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + // Determine which tile the bounding rectangle is in + var lastLevelX = 0, lastLevelY = 0; + var currentX = 0, currentY = 0; + var maxLevel = GroundPrimitive._terrainHeightsMaxLevel; + var i; + for(i = 0; i <= maxLevel; ++i) { + var failed = false; + for(var j = 0; j < 4; ++j) { + var corner = scratchCorners[j]; + tilingScheme.positionToTileXY(corner, i, scratchTileXY); + if (j === 0) { + currentX = scratchTileXY.x; + currentY = scratchTileXY.y; + } else if(currentX !== scratchTileXY.x || currentY !== scratchTileXY.y) { + failed = true; + break; + } } - return; + + if (failed) { + break; + } + + lastLevelX = currentX; + lastLevelY = currentY; } - var material = defaultValue(box.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(box.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(box.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(box.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(box.distanceDisplayCondition, defaultDistanceDisplayCondition); + if (i === 0) { + return undefined; + } - var outlineWidth = box.outlineWidth; + return { + x : lastLevelX, + y : lastLevelY, + level : (i > maxLevel) ? maxLevel : (i - 1) + }; + } - this._fillEnabled = fillEnabled; - this._outlineEnabled = outlineEnabled; + function setMinMaxTerrainHeights(primitive, rectangle, ellipsoid) { + var xyLevel = getTileXYLevel(rectangle); - if (!position.isConstant || // - !Property.isConstant(entity.orientation) || // - !dimensions.isConstant || // - !Property.isConstant(outlineWidth)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + // Get the terrain min/max for that tile + var minTerrainHeight = GroundPrimitive._defaultMinTerrainHeight; + var maxTerrainHeight = GroundPrimitive._defaultMaxTerrainHeight; + if (defined(xyLevel)) { + var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; + var heights = GroundPrimitive._terrainHeights[key]; + if (defined(heights)) { + minTerrainHeight = heights[0]; + maxTerrainHeight = heights[1]; } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.dimensions = dimensions.getValue(Iso8601.MINIMUM_VALUE, options.dimensions); - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); - } - }; - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - BoxGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); - } + // Compute min by taking the center of the NE->SW diagonal and finding distance to the surface + ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle, scratchDiagonalCartographic), + scratchDiagonalCartesianNE); + ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle, scratchDiagonalCartographic), + scratchDiagonalCartesianSW); - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); + Cartesian3.subtract(scratchDiagonalCartesianSW, scratchDiagonalCartesianNE, scratchCenterCartesian); + Cartesian3.add(scratchDiagonalCartesianNE, + Cartesian3.multiplyByScalar(scratchCenterCartesian, 0.5, scratchCenterCartesian), scratchCenterCartesian); + var surfacePosition = ellipsoid.scaleToGeodeticSurface(scratchCenterCartesian, scratchSurfaceCartesian); + if (defined(surfacePosition)) { + var distance = Cartesian3.distance(scratchCenterCartesian, surfacePosition); + minTerrainHeight = Math.min(minTerrainHeight, -distance); + } else { + minTerrainHeight = GroundPrimitive._defaultMinTerrainHeight; + } } - - return new DynamicGeometryUpdater(primitives, this); - }; - /** - * @private - */ - function DynamicGeometryUpdater(primitives, geometryUpdater) { - this._primitives = primitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); + primitive._minTerrainHeight = Math.max(GroundPrimitive._defaultMinTerrainHeight, minTerrainHeight); + primitive._maxTerrainHeight = maxTerrainHeight; } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._primitive = undefined; - this._outlinePrimitive = undefined; - var geometryUpdater = this._geometryUpdater; - var entity = geometryUpdater._entity; - var box = entity.box; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(box.show, time, true)) { - return; - } + var scratchBoundingSphere = new BoundingSphere(); + function getInstanceBoundingSphere(rectangle, ellipsoid) { + var xyLevel = getTileXYLevel(rectangle); - var options = this._options; - var modelMatrix = entity.computeModelMatrix(time); - var dimensions = Property.getValueOrUndefined(box.dimensions, time, options.dimensions); - if (!defined(modelMatrix) || !defined(dimensions)) { - return; + // Get the terrain max for that tile + var maxTerrainHeight = GroundPrimitive._defaultMaxTerrainHeight; + if (defined(xyLevel)) { + var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; + var heights = GroundPrimitive._terrainHeights[key]; + if (defined(heights)) { + maxTerrainHeight = heights[1]; + } } - options.dimensions = dimensions; + var result = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, 0.0); + BoundingSphere.fromRectangle3D(rectangle, ellipsoid, maxTerrainHeight, scratchBoundingSphere); - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + return BoundingSphere.union(result, scratchBoundingSphere, result); + } - var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + function createBoundingVolume(groundPrimitive, frameState, geometry) { + var ellipsoid = frameState.mapProjection.ellipsoid; + var rectangle = getRectangle(frameState, geometry); - if (Property.getValueOrDefault(box.fill, time, true)) { - var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - this._material = material; + // Use an oriented bounding box by default, but switch to a bounding sphere if bounding box creation would fail. + if (rectangle.width < CesiumMath.PI) { + var obb = OrientedBoundingBox.fromRectangle(rectangle, groundPrimitive._maxHeight, groundPrimitive._minHeight, ellipsoid); + groundPrimitive._boundingVolumes.push(obb); + } else { + var highPositions = geometry.attributes.position3DHigh.values; + var lowPositions = geometry.attributes.position3DLow.values; + groundPrimitive._boundingVolumes.push(BoundingSphere.fromEncodedCartesianVertices(highPositions, lowPositions)); + } - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : true - }); - options.vertexFormat = appearance.vertexFormat; + if (!frameState.scene3DOnly) { + var projection = frameState.mapProjection; + var boundingVolume = BoundingSphere.fromRectangleWithHeights2D(rectangle, projection, groundPrimitive._maxHeight, groundPrimitive._minHeight); + Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : BoxGeometry.fromDimensions(options), - modelMatrix : modelMatrix, - attributes : { - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + groundPrimitive._boundingVolumes2D.push(boundingVolume); } + } - if (Property.getValueOrDefault(box.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + function boundingVolumeIndex(commandIndex, length) { + return Math.floor((commandIndex % length) / 3); + } - var outlineColor = Property.getValueOrClonedDefault(box.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(box.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + var boundingVolumes; + if (frameState.mode === SceneMode.SCENE3D) { + boundingVolumes = groundPrimitive._boundingVolumes; + } else { + boundingVolumes = groundPrimitive._boundingVolumes2D; + } - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : BoxOutlineGeometry.fromDimensions(options), - modelMatrix : modelMatrix, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) - } - }), - asynchronous : false, - shadows : shadows - })); + var pass; + switch (groundPrimitive.classificationType) { + case ClassificationType.TERRAIN: + pass = Pass.TERRAIN_CLASSIFICATION; + break; + case ClassificationType.CESIUM_3D_TILE: + pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; + break; + default: + pass = Pass.CLASSIFICATION; } - }; - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; + var commandList = frameState.commandList; + var passes = frameState.passes; + if (passes.render) { + var colorLength = colorCommands.length; + var i; + var colorCommand; - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + for (i = 0; i < colorLength; ++i) { + colorCommand = colorCommands[i]; + colorCommand.owner = groundPrimitive; + colorCommand.modelMatrix = modelMatrix; + colorCommand.boundingVolume = boundingVolumes[boundingVolumeIndex(i, colorLength)]; + colorCommand.cull = cull; + colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + colorCommand.pass = pass; - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; + commandList.push(colorCommand); + } - return BoxGeometryUpdater; -}); + if (frameState.invertClassification) { + var ignoreShowCommands = groundPrimitive._primitive._commandsIgnoreShow; + var ignoreShowCommandsLength = ignoreShowCommands.length; -define('DataSources/ImageMaterialProperty',[ - '../Core/Cartesian2', - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' - ], function( - Cartesian2, - Color, - defaultValue, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { - 'use strict'; + for (i = 0; i < ignoreShowCommandsLength; ++i) { + var bvIndex = Math.floor(i / 2); + colorCommand = ignoreShowCommands[i]; + colorCommand.modelMatrix = modelMatrix; + colorCommand.boundingVolume = boundingVolumes[bvIndex]; + colorCommand.cull = cull; + colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; - var defaultRepeat = new Cartesian2(1, 1); - var defaultTransparent = false; - var defaultColor = Color.WHITE; + commandList.push(colorCommand); + } + } + } - /** - * A {@link MaterialProperty} that maps to image {@link Material} uniforms. - * @alias ImageMaterialProperty - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.image] A Property specifying the Image, URL, Canvas, or Video. - * @param {Property} [options.repeat=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the number of times the image repeats in each direction. - * @param {Property} [options.color=Color.WHITE] The color applied to the image - * @param {Property} [options.transparent=false] Set to true when the image has transparency (for example, when a png has transparent sections) - */ - function ImageMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (passes.pick) { + var pickLength = pickCommands.length; + var primitive = groundPrimitive._primitive._primitive; + var pickOffsets = primitive._pickOffsets; + for (var j = 0; j < pickLength; ++j) { + var pickOffset = pickOffsets[boundingVolumeIndex(j, pickLength)]; + var bv = boundingVolumes[pickOffset.index]; - this._definitionChanged = new Event(); - this._image = undefined; - this._imageSubscription = undefined; - this._repeat = undefined; - this._repeatSubscription = undefined; - this._color = undefined; - this._colorSubscription = undefined; - this._transparent = undefined; - this._transparentSubscription = undefined; - this.image = options.image; - this.repeat = options.repeat; - this.color = options.color; - this.transparent = options.transparent; - } + var pickCommand = pickCommands[j]; + pickCommand.owner = groundPrimitive; + pickCommand.modelMatrix = modelMatrix; + pickCommand.boundingVolume = bv; + pickCommand.cull = cull; + pickCommand.pass = pass; - defineProperties(ImageMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof ImageMaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._image) && Property.isConstant(this._repeat); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof ImageMaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + commandList.push(pickCommand); } - }, - /** - * Gets or sets the Property specifying Image, URL, Canvas, or Video to use. - * @memberof ImageMaterialProperty.prototype - * @type {Property} - */ - image : createPropertyDescriptor('image'), - /** - * Gets or sets the {@link Cartesian2} Property specifying the number of times the image repeats in each direction. - * @memberof ImageMaterialProperty.prototype - * @type {Property} - * @default new Cartesian2(1, 1) - */ - repeat : createPropertyDescriptor('repeat'), - /** - * Gets or sets the Color Property specifying the desired color applied to the image. - * @memberof ImageMaterialProperty.prototype - * @type {Property} - * @default 1.0 - */ - color : createPropertyDescriptor('color'), - /** - * Gets or sets the Boolean Property specifying whether the image has transparency - * @memberof ImageMaterialProperty.prototype - * @type {Property} - * @default 1.0 - */ - transparent : createPropertyDescriptor('transparent') - }); + } + } - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - ImageMaterialProperty.prototype.getType = function(time) { - return 'Image'; - }; + GroundPrimitive._initialized = false; + GroundPrimitive._initPromise = undefined; /** - * Gets the value of the property at the provided time. + * Initializes the minimum and maximum terrain heights. This only needs to be called if you are creating the + * GroundPrimitive synchronously. + * + * @returns {Promise} A promise that will resolve once the terrain heights have been loaded. * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. */ - ImageMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; + GroundPrimitive.initializeTerrainHeights = function() { + var initPromise = GroundPrimitive._initPromise; + if (defined(initPromise)) { + return initPromise; } - result.image = Property.getValueOrUndefined(this._image, time); - result.repeat = Property.getValueOrClonedDefault(this._repeat, time, defaultRepeat, result.repeat); - result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); - if (Property.getValueOrDefault(this._transparent, time, defaultTransparent)) { - result.color.alpha = Math.min(0.99, result.color.alpha); - } + GroundPrimitive._initPromise = terrainHeightsResource.fetchJson().then(function(json) { + GroundPrimitive._initialized = true; + GroundPrimitive._terrainHeights = json; + }); - return result; + return GroundPrimitive._initPromise; }; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @exception {DeveloperError} All instance geometries must have the same primitiveType. + * @exception {DeveloperError} Appearance and material have a uniform with the same name. + * @exception {DeveloperError} Not all of the geometry instances have the same color attribute. */ - ImageMaterialProperty.prototype.equals = function(other) { - return this === other || - (other instanceof ImageMaterialProperty && - Property.equals(this._image, other._image) && - Property.equals(this._color, other._color) && - Property.equals(this._transparent, other._transparent) && - Property.equals(this._repeat, other._repeat)); - }; - - return ImageMaterialProperty; -}); - -define('DataSources/createMaterialPropertyDescriptor',[ - '../Core/Color', - '../Core/DeveloperError', - './ColorMaterialProperty', - './createPropertyDescriptor', - './ImageMaterialProperty' - ], function( - Color, - DeveloperError, - ColorMaterialProperty, - createPropertyDescriptor, - ImageMaterialProperty) { - 'use strict'; - - function createMaterialProperty(value) { - if (value instanceof Color) { - return new ColorMaterialProperty(value); + GroundPrimitive.prototype.update = function(frameState) { + if (!this.show || (!defined(this._primitive) && !defined(this.geometryInstances))) { + return; } - if (typeof value === 'string' || value instanceof HTMLCanvasElement || value instanceof HTMLVideoElement) { - var result = new ImageMaterialProperty(); - result.image = value; - return result; + if (!GroundPrimitive._initialized) { + if (!this.asynchronous) { + throw new DeveloperError('For synchronous GroundPrimitives, you must call GroundPrimitive.initializeTerrainHeights() and wait for the returned promise to resolve.'); + } + + GroundPrimitive.initializeTerrainHeights(); + return; } - throw new DeveloperError('Unable to infer material type: ' + value); - } + var that = this; + var primitiveOptions = this._primitiveOptions; - /** - * @private - */ - function createMaterialPropertyDescriptor(name, configurable) { - return createPropertyDescriptor(name, configurable, createMaterialProperty); - } + if (!defined(this._primitive)) { + var ellipsoid = frameState.mapProjection.ellipsoid; - return createMaterialPropertyDescriptor; -}); + var instance; + var geometry; + var instanceType; -define('DataSources/BoxGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + var instances = isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; + var length = instances.length; + var groundInstances = new Array(length); - /** - * Describes a box. The center position and orientation are determined by the containing {@link Entity}. - * - * @alias BoxGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.dimensions] A {@link Cartesian3} Property specifying the length, width, and height of the box. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the box. - * @param {Property} [options.fill=true] A boolean Property specifying whether the box is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the box. - * @param {Property} [options.outline=false] A boolean Property specifying whether the box is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the box casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this box will be displayed. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo} - */ - function BoxGraphics(options) { - this._dimensions = undefined; - this._dimensionsSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + var i; + var rectangle; + for (i = 0; i < length; ++i) { + instance = instances[i]; + geometry = instance.geometry; + var instanceRectangle = getRectangle(frameState, geometry); + if (!defined(rectangle)) { + rectangle = instanceRectangle; + } else if (defined(instanceRectangle)) { + Rectangle.union(rectangle, instanceRectangle, rectangle); + } - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + var id = instance.id; + if (defined(id) && defined(instanceRectangle)) { + var boundingSphere = getInstanceBoundingSphere(instanceRectangle, ellipsoid); + this._boundingSpheresKeys.push(id); + this._boundingSpheres.push(boundingSphere); + } - defineProperties(BoxGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof BoxGraphics.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + instanceType = geometry.constructor; + if (!defined(instanceType) || !defined(instanceType.createShadowVolume)) { + throw new DeveloperError('Not all of the geometry instances have GroundPrimitive support.'); + } } - }, - - /** - * Gets or sets the boolean Property specifying the visibility of the box. - * @memberof BoxGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), - - /** - * Gets or sets {@link Cartesian3} Property property specifying the length, width, and height of the box. - * @memberof BoxGraphics.prototype - * @type {Property} - */ - dimensions : createPropertyDescriptor('dimensions'), - - /** - * Gets or sets the material used to fill the box. - * @memberof BoxGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), - - /** - * Gets or sets the boolean Property specifying whether the box is filled with the provided material. - * @memberof BoxGraphics.prototype - * @type {Property} - * @default true - */ - fill : createPropertyDescriptor('fill'), - - /** - * Gets or sets the Property specifying whether the box is outlined. - * @memberof BoxGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), - - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof BoxGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), - - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof BoxGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), - - /** - * Get or sets the enum Property specifying whether the box - * casts or receives shadows from each light source. - * @memberof BoxGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), - - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this box will be displayed. - * @memberof BoxGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); - - /** - * Duplicates this instance. - * - * @param {BoxGraphics} [result] The object onto which to store the result. - * @returns {BoxGraphics} The modified result parameter or a new instance if one was not provided. - */ - BoxGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new BoxGraphics(this); - } - result.dimensions = this.dimensions; - result.show = this.show; - result.material = this.material; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {BoxGraphics} source The object to be merged into this object. - */ - BoxGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); - } - - this.dimensions = defaultValue(this.dimensions, source.dimensions); - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - }; + // Now compute the min/max heights for the primitive + setMinMaxTerrainHeights(this, rectangle, frameState.mapProjection.ellipsoid); + var exaggeration = frameState.terrainExaggeration; + this._minHeight = this._minTerrainHeight * exaggeration; + this._maxHeight = this._maxTerrainHeight * exaggeration; - return BoxGraphics; -}); + for (i = 0; i < length; ++i) { + instance = instances[i]; + geometry = instance.geometry; + instanceType = geometry.constructor; + groundInstances[i] = new GeometryInstance({ + geometry : instanceType.createShadowVolume(geometry, getComputeMinimumHeightFunction(this), + getComputeMaximumHeightFunction(this)), + attributes : instance.attributes, + id : instance.id + }); + } -define('DataSources/CallbackProperty',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event' - ], function( - defined, - defineProperties, - DeveloperError, - Event) { - 'use strict'; + primitiveOptions.geometryInstances = groundInstances; - /** - * A {@link Property} whose value is lazily evaluated by a callback function. - * - * @alias CallbackProperty - * @constructor - * - * @param {CallbackProperty~Callback} callback The function to be called when the property is evaluated. - * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. - */ - function CallbackProperty(callback, isConstant) { - this._callback = undefined; - this._isConstant = undefined; - this._definitionChanged = new Event(); - this.setCallback(callback, isConstant); - } + primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { + createBoundingVolume(that, frameState, geometry); + }; + primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); + }; - defineProperties(CallbackProperty.prototype, { - /** - * Gets a value indicating if this property is constant. - * @memberof CallbackProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return this._isConstant; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setCallback is called. - * @memberof CallbackProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } + this._primitive = new ClassificationPrimitive(primitiveOptions); + this._primitive.readyPromise.then(function(primitive) { + that._ready = true; + + if (that.releaseGeometryInstances) { + that.geometryInstances = undefined; + } + + var error = primitive._error; + if (!defined(error)) { + that._readyPromise.resolve(that); + } else { + that._readyPromise.reject(error); + } + }); } - }); - /** - * Gets the value of the property. - * - * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied or is unsupported. - */ - CallbackProperty.prototype.getValue = function(time, result) { - return this._callback(time, result); + this._primitive.debugShowShadowVolume = this.debugShowShadowVolume; + this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; + this._primitive.update(frameState); }; /** - * Sets the callback to be used. - * - * @param {CallbackProperty~Callback} callback The function to be called when the property is evaluated. - * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. + * @private */ - CallbackProperty.prototype.setCallback = function(callback, isConstant) { - if (!defined(callback)) { - throw new DeveloperError('callback is required.'); - } - if (!defined(isConstant)) { - throw new DeveloperError('isConstant is required.'); + GroundPrimitive.prototype.getBoundingSphere = function(id) { + var index = this._boundingSpheresKeys.indexOf(id); + if (index !== -1) { + return this._boundingSpheres[index]; } - - var changed = this._callback !== callback || this._isConstant !== isConstant; - this._callback = callback; - this._isConstant = isConstant; + return undefined; + }; - if (changed) { - this._definitionChanged.raiseEvent(this); + /** + * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. + * + * @param {Object} id The id of the {@link GeometryInstance}. + * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * + * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. + * + * @example + * var attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); + * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true); + */ + GroundPrimitive.prototype.getGeometryInstanceAttributes = function(id) { + if (!defined(this._primitive)) { + throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); } + return this._primitive.getGeometryInstanceAttributes(id); }; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Returns true if this object was destroyed; otherwise, false. + * <p> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see GroundPrimitive#destroy */ - CallbackProperty.prototype.equals = function(other) { - return this === other || (other instanceof CallbackProperty && this._callback === other._callback && this._isConstant === other._isConstant); + GroundPrimitive.prototype.isDestroyed = function() { + return false; }; /** - * A function that returns the value of the property. - * @callback CallbackProperty~Callback + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> * - * @param {JulianDate} [time] The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied or is unsupported. + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * e = e && e.destroy(); + * + * @see GroundPrimitive#isDestroyed */ + GroundPrimitive.prototype.destroy = function() { + this._primitive = this._primitive && this._primitive.destroy(); + return destroyObject(this); + }; - return CallbackProperty; + return GroundPrimitive; }); -define('DataSources/CheckerboardMaterialProperty',[ - '../Core/Cartesian2', +define('DataSources/CorridorGeometryUpdater',[ '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/CorridorGeometry', + '../Core/CorridorOutlineGeometry', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', '../Core/Event', - './createPropertyDescriptor', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/oneTimeWarning', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/GroundPrimitive', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', './Property' ], function( - Cartesian2, Color, + ColorGeometryInstanceAttribute, + CorridorGeometry, + CorridorOutlineGeometry, defaultValue, defined, defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, Event, - createPropertyDescriptor, + GeometryInstance, + Iso8601, + oneTimeWarning, + ShowGeometryInstanceAttribute, + GroundPrimitive, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, Property) { 'use strict'; - var defaultEvenColor = Color.WHITE; - var defaultOddColor = Color.BLACK; - var defaultRepeat = new Cartesian2(2.0, 2.0); + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.positions = undefined; + this.width = undefined; + this.cornerType = undefined; + this.height = undefined; + this.extrudedHeight = undefined; + this.granularity = undefined; + } /** - * A {@link MaterialProperty} that maps to checkerboard {@link Material} uniforms. - * @alias CheckerboardMaterialProperty + * A {@link GeometryUpdater} for corridors. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias CorridorGeometryUpdater * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}. - * @param {Property} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}. - * @param {Property} [options.repeat=new Cartesian2(2.0, 2.0)] A {@link Cartesian2} Property specifying how many times the tiles repeat in each direction. + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - function CheckerboardMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._definitionChanged = new Event(); - - this._evenColor = undefined; - this._evenColorSubscription = undefined; - - this._oddColor = undefined; - this._oddColorSubscription = undefined; - - this._repeat = undefined; - this._repeatSubscription = undefined; + function CorridorGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(CorridorGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._isClosed = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._onTerrain = false; + this._options = new GeometryOptions(entity); - this.evenColor = options.evenColor; - this.oddColor = options.oddColor; - this.repeat = options.repeat; + this._onEntityPropertyChanged(entity, 'corridor', entity.corridor, undefined); } - defineProperties(CheckerboardMaterialProperty.prototype, { + defineProperties(CorridorGeometryUpdater, { /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CheckerboardMaterialProperty.prototype + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof CorridorGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof CorridorGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); + + defineProperties(CorridorGeometryUpdater.prototype, { + /** + * Gets the entity associated with this geometry. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Entity} + * @readonly + */ + entity : { + get : function() { + return this._entity; + } + }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof CorridorGeometryUpdater.prototype * * @type {Boolean} * @readonly */ - isConstant : { + fillEnabled : { get : function() { - return Property.isConstant(this._evenColor) && // - Property.isConstant(this._oddColor) && // - Property.isConstant(this._repeat); + return this._fillEnabled; } }, /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof CheckerboardMaterialProperty.prototype + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof CorridorGeometryUpdater.prototype * - * @type {Event} + * @type {Boolean} * @readonly */ - definitionChanged : { + hasConstantFill : { get : function() { - return this._definitionChanged; + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, /** - * Gets or sets the Property specifying the first {@link Color}. - * @memberof CheckerboardMaterialProperty.prototype + * Gets the material property used to fill the geometry. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly + */ + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof CorridorGeometryUpdater.prototype + * * @type {Property} - * @default Color.WHITE + * @readonly */ - evenColor : createPropertyDescriptor('evenColor'), + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, /** - * Gets or sets the Property specifying the second {@link Color}. - * @memberof CheckerboardMaterialProperty.prototype + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Number} + * @readonly + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + } + }, + /** + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof CorridorGeometryUpdater.prototype + * * @type {Property} - * @default Color.BLACK + * @readonly */ - oddColor : createPropertyDescriptor('oddColor'), + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, /** - * Gets or sets the {@link Cartesian2} Property specifying how many times the tiles repeat in each direction. - * @memberof CheckerboardMaterialProperty.prototype + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof CorridorGeometryUpdater.prototype + * * @type {Property} - * @default new Cartesian2(2.0, 2.0) + * @readonly */ - repeat : createPropertyDescriptor('repeat') + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayCondition; + } + }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isDynamic : { + get : function() { + return this._dynamic; + } + }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isClosed : { + get : function() { + return this._isClosed; + } + }, + /** + * Gets a value indicating if the geometry should be drawn on terrain. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + onTerrain : { + get : function() { + return this._onTerrain; + } + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof CorridorGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { + get : function() { + return this._geometryChanged; + } + } }); /** - * Gets the {@link Material} type at the provided time. + * Checks if the geometry is outlined at the provided time. * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. */ - CheckerboardMaterialProperty.prototype.getType = function(time) { - return 'Checkerboard'; + CorridorGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; /** - * Gets the value of the property at the provided time. + * Checks if the geometry is filled at the provided time. * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. */ - CheckerboardMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.lightColor = Property.getValueOrClonedDefault(this._evenColor, time, defaultEvenColor, result.lightColor); - result.darkColor = Property.getValueOrClonedDefault(this._oddColor, time, defaultOddColor, result.darkColor); - result.repeat = Property.getValueOrDefault(this._repeat, time, defaultRepeat); - return result; + CorridorGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Creates the geometry instance which represents the fill of the geometry. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. */ - CheckerboardMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CheckerboardMaterialProperty && // - Property.equals(this._evenColor, other._evenColor) && // - Property.equals(this._oddColor, other._oddColor) && // - Property.equals(this._repeat, other._repeat)); - }; + CorridorGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - return CheckerboardMaterialProperty; -}); + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); -define('DataSources/PositionProperty',[ - '../Core/Cartesian3', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Matrix3', - '../Core/ReferenceFrame', - '../Core/Transforms' - ], function( - Cartesian3, - defined, - defineProperties, - DeveloperError, - Matrix3, - ReferenceFrame, - Transforms) { - 'use strict'; + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayCondition.getValue(time)); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayCondition, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayCondition + }; + } + + return new GeometryInstance({ + id : entity, + geometry : new CorridorGeometry(this._options), + attributes : attributes + }); + }; /** - * The interface for all {@link Property} objects that define a world - * location as a {@link Cartesian3} with an associated {@link ReferenceFrame}. - * This type defines an interface and cannot be instantiated directly. + * Creates the geometry instance which represents the outline of the geometry. * - * @alias PositionProperty - * @constructor + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. * - * @see CompositePositionProperty - * @see ConstantPositionProperty - * @see SampledPositionProperty - * @see TimeIntervalCollectionPositionProperty + * @exception {DeveloperError} This instance does not represent an outlined geometry. */ - function PositionProperty() { - DeveloperError.throwInstantiationError(); - } + CorridorGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - defineProperties(PositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PositionProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PositionProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the reference frame that the position is defined in. - * @memberof PositionProperty.prototype - * @type {ReferenceFrame} - */ - referenceFrame : { - get : DeveloperError.throwInstantiationError + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); } - }); + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - /** - * Gets the value of the property at the provided time in the fixed frame. - * @function - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - PositionProperty.prototype.getValue = DeveloperError.throwInstantiationError; + return new GeometryInstance({ + id : entity, + geometry : new CorridorOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayCondition.getValue(time)) + } + }); + }; /** - * Gets the value of the property at the provided time and in the provided reference frame. - * @function + * Returns true if this object was destroyed; otherwise, false. * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - PositionProperty.prototype.getValueInReferenceFrame = DeveloperError.throwInstantiationError; + CorridorGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * @function + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ - PositionProperty.prototype.equals = DeveloperError.throwInstantiationError; - - var scratchMatrix3 = new Matrix3(); + CorridorGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; - /** - * @private - */ - PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) { - if (!defined(value)) { - return value; + CorridorGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'corridor')) { + return; } - if (!defined(result)){ - result = new Cartesian3(); + + var corridor = this._entity.corridor; + + if (!defined(corridor)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; } - if (inputFrame === outputFrame) { - return Cartesian3.clone(value, result); + var fillProperty = corridor.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = corridor.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3); - if (!defined(icrfToFixed)) { - icrfToFixed = Transforms.computeTemeToPseudoFixedMatrix(time, scratchMatrix3); + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; } - if (inputFrame === ReferenceFrame.INERTIAL) { - return Matrix3.multiplyByVector(icrfToFixed, value, result); + + var positions = corridor.positions; + + var show = corridor.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(positions))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; } - if (inputFrame === ReferenceFrame.FIXED) { - return Matrix3.multiplyByVector(Matrix3.transpose(icrfToFixed, scratchMatrix3), value, result); + + var material = defaultValue(corridor.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(corridor.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(corridor.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(corridor.shadows, defaultShadows); + this._distanceDisplayCondition = defaultValue(corridor.distanceDisplayCondition, defaultDistanceDisplayCondition); + + var height = corridor.height; + var extrudedHeight = corridor.extrudedHeight; + var granularity = corridor.granularity; + var width = corridor.width; + var outlineWidth = corridor.outlineWidth; + var cornerType = corridor.cornerType; + var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && + isColorMaterial && GroundPrimitive.isSupported(this._scene); + + if (outlineEnabled && onTerrain) { + oneTimeWarning(oneTimeWarning.geometryOutlines); + outlineEnabled = false; } - }; - return PositionProperty; -}); + this._fillEnabled = fillEnabled; + this._onTerrain = onTerrain; + this._isClosed = defined(extrudedHeight) || onTerrain; + this._outlineEnabled = outlineEnabled; -define('DataSources/ConstantPositionProperty',[ - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame', - './PositionProperty' - ], function( - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame, - PositionProperty) { - 'use strict'; + if (!positions.isConstant || // + !Property.isConstant(height) || // + !Property.isConstant(extrudedHeight) || // + !Property.isConstant(granularity) || // + !Property.isConstant(width) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(cornerType) || // + (onTerrain && !Property.isConstant(material))) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.positions = positions.getValue(Iso8601.MINIMUM_VALUE, options.positions); + options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.cornerType = defined(cornerType) ? cornerType.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } + }; /** - * A {@link PositionProperty} whose value does not change in respect to the - * {@link ReferenceFrame} in which is it defined. + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. * - * @alias ConstantPositionProperty - * @constructor + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @param {PrimitiveCollection} groundPrimitives The ground primitives collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. * - * @param {Cartesian3} [value] The property value. - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + * @exception {DeveloperError} This instance does not represent dynamic geometry. */ - function ConstantPositionProperty(value, referenceFrame) { - this._definitionChanged = new Event(); - this._value = Cartesian3.clone(value); - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + CorridorGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } + + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, groundPrimitives, this); + }; + + /** + * @private + */ + function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { + this._primitives = primitives; + this._groundPrimitives = groundPrimitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var geometryUpdater = this._geometryUpdater; + var onTerrain = geometryUpdater._onTerrain; - defineProperties(ConstantPositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof ConstantPositionProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return !defined(this._value) || this._referenceFrame === ReferenceFrame.FIXED; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof ConstantPositionProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof ConstantPositionProperty.prototype - * @type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._outlinePrimitive = undefined; + } + this._primitive = undefined; + + var entity = geometryUpdater._entity; + var corridor = entity.corridor; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(corridor.show, time, true)) { + return; + } + + var options = this._options; + var positions = Property.getValueOrUndefined(corridor.positions, time, options.positions); + var width = Property.getValueOrUndefined(corridor.width, time); + if (!defined(positions) || !defined(width)) { + return; + } + + options.positions = positions; + options.width = width; + options.height = Property.getValueOrUndefined(corridor.height, time); + options.extrudedHeight = Property.getValueOrUndefined(corridor.extrudedHeight, time); + options.granularity = Property.getValueOrUndefined(corridor.granularity, time); + options.cornerType = Property.getValueOrUndefined(corridor.cornerType, time); + + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + var distanceDisplayCondition = this._geometryUpdater.distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + + if (!defined(corridor.fill) || corridor.fill.getValue(time)) { + var fillMaterialProperty = geometryUpdater.fillMaterialProperty; + var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); + this._material = material; + + if (onTerrain) { + var currentColor = Color.WHITE; + if (defined(fillMaterialProperty.color)) { + currentColor = fillMaterialProperty.color.getValue(time); + } + + this._primitive = groundPrimitives.add(new GroundPrimitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new CorridorGeometry(options), + attributes: { + color: ColorGeometryInstanceAttribute.fromColor(currentColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + asynchronous : false, + shadows : shadows + })); + } else { + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : defined(options.extrudedHeight) + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new CorridorGeometry(options), + attributes : { + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); } } - }); - - /** - * Gets the value of the property at the provided time in the fixed frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ConstantPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + + if (!onTerrain && defined(corridor.outline) && corridor.outline.getValue(time)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = Property.getValueOrClonedDefault(corridor.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(corridor.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; + + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new CorridorOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } }; - /** - * Sets the value of the property. - * - * @param {Cartesian3} value The property value. - * @param {ReferenceFrame} [referenceFrame=this.referenceFrame] The reference frame in which the position is defined. - */ - ConstantPositionProperty.prototype.setValue = function(value, referenceFrame) { - var definitionChanged = false; - if (!Cartesian3.equals(this._value, value)) { - definitionChanged = true; - this._value = Cartesian3.clone(value); - } - if (defined(referenceFrame) && this._referenceFrame !== referenceFrame) { - definitionChanged = true; - this._referenceFrame = referenceFrame; - } - if (definitionChanged) { - this._definitionChanged.raiseEvent(this); - } + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); }; - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ConstantPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); - } - - return PositionProperty.convertToReferenceFrame(time, this._value, this._referenceFrame, referenceFrame, result); + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; }; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - ConstantPositionProperty.prototype.equals = function(other) { - return this === other || - (other instanceof ConstantPositionProperty && - Cartesian3.equals(this._value, other._value) && - this._referenceFrame === other._referenceFrame); + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (this._geometryUpdater._onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + } + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); }; - return ConstantPositionProperty; + return CorridorGeometryUpdater; }); -define('DataSources/CorridorGraphics',[ - '../Core/defaultValue', - '../Core/defined', +define('DataSources/DataSource',[ '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' + '../Core/DeveloperError' ], function( - defaultValue, - defined, defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { + DeveloperError) { 'use strict'; /** - * Describes a corridor, which is a shape defined by a centerline and width that - * conforms to the curvature of the globe. It can be placed on the surface or at altitude - * and can optionally be extruded into a volume. - * - * @alias CorridorGraphics + * Defines the interface for data sources, which turn arbitrary data into a + * {@link EntityCollection} for generic consumption. This object is an interface + * for documentation purposes and is not intended to be instantiated directly. + * @alias DataSource * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions that define the centerline of the corridor. - * @param {Property} [options.width] A numeric Property specifying the distance between the edges of the corridor. - * @param {Property} [options.cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners. - * @param {Property} [options.height=0] A numeric Property specifying the altitude of the corridor relative to the ellipsoid surface. - * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the corridor's extruded face relative to the ellipsoid surface. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the corridor. - * @param {Property} [options.fill=true] A boolean Property specifying whether the corridor is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the corridor. - * @param {Property} [options.outline=false] A boolean Property specifying whether the corridor is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the distance between each latitude and longitude. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the corridor casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this corridor will be displayed. - * * @see Entity - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo} + * @see DataSourceDisplay */ - function CorridorGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._positions = undefined; - this._positionsSubscription = undefined; - this._height = undefined; - this._heightSubscription = undefined; - this._extrudedHeight = undefined; - this._extrudedHeightSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._width = undefined; - this._widthSubscription = undefined; - this._cornerType = undefined; - this._cornerTypeSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); - - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + function DataSource() { + DeveloperError.throwInstantiationError(); } - defineProperties(CorridorGraphics.prototype, { + defineProperties(DataSource.prototype, { /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof CorridorGraphics.prototype - * @type {Event} - * @readonly + * Gets a human-readable name for this instance. + * @memberof DataSource.prototype + * @type {String} */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } + name : { + get : DeveloperError.throwInstantiationError }, - - /** - * Gets or sets the boolean Property specifying the visibility of the corridor. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), - - /** - * Gets or sets the Property specifying the material used to fill the corridor. - * @memberof CorridorGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), - /** - * Gets or sets a Property specifying the array of {@link Cartesian3} positions that define the centerline of the corridor. - * @memberof CorridorGraphics.prototype - * @type {Property} - */ - positions : createPropertyDescriptor('positions'), - - /** - * Gets or sets the numeric Property specifying the altitude of the corridor. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default 0.0 - */ - height : createPropertyDescriptor('height'), - - /** - * Gets or sets the numeric Property specifying the altitude of the corridor extrusion. - * Setting this property creates a corridor shaped volume starting at height and ending - * at this altitude. - * @memberof CorridorGraphics.prototype - * @type {Property} - */ - extrudedHeight : createPropertyDescriptor('extrudedHeight'), - - /** - * Gets or sets the numeric Property specifying the sampling distance between each latitude and longitude point. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default {CesiumMath.RADIANS_PER_DEGREE} - */ - granularity : createPropertyDescriptor('granularity'), - - /** - * Gets or sets the numeric Property specifying the width of the corridor. - * @memberof CorridorGraphics.prototype - * @type {Property} + * Gets the preferred clock settings for this data source. + * @memberof DataSource.prototype + * @type {DataSourceClock} */ - width : createPropertyDescriptor('width'), - + clock : { + get : DeveloperError.throwInstantiationError + }, /** - * Gets or sets the boolean Property specifying whether the corridor is filled with the provided material. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default true + * Gets the collection of {@link Entity} instances. + * @memberof DataSource.prototype + * @type {EntityCollection} */ - fill : createPropertyDescriptor('fill'), - + entities : { + get : DeveloperError.throwInstantiationError + }, /** - * Gets or sets the Property specifying whether the corridor is outlined. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default false + * Gets a value indicating if the data source is currently loading data. + * @memberof DataSource.prototype + * @type {Boolean} */ - outline : createPropertyDescriptor('outline'), - + isLoading : { + get : DeveloperError.throwInstantiationError + }, /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default Color.BLACK + * Gets an event that will be raised when the underlying data changes. + * @memberof DataSource.prototype + * @type {Event} */ - outlineColor : createPropertyDescriptor('outlineColor'), - + changedEvent : { + get : DeveloperError.throwInstantiationError + }, /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default 1.0 + * Gets an event that will be raised if an error is encountered during processing. + * @memberof DataSource.prototype + * @type {Event} */ - outlineWidth : createPropertyDescriptor('outlineWidth'), - + errorEvent : { + get : DeveloperError.throwInstantiationError + }, /** - * Gets or sets the {@link CornerType} Property specifying how corners are styled. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default CornerType.ROUNDED + * Gets an event that will be raised when the value of isLoading changes. + * @memberof DataSource.prototype + * @type {Event} */ - cornerType : createPropertyDescriptor('cornerType'), - + loadingEvent : { + get : DeveloperError.throwInstantiationError + }, /** - * Get or sets the enum Property specifying whether the corridor - * casts or receives shadows from each light source. - * @memberof CorridorGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED + * Gets whether or not this data source should be displayed. + * @memberof DataSource.prototype + * @type {Boolean} */ - shadows : createPropertyDescriptor('shadows'), + show : { + get : DeveloperError.throwInstantiationError + }, /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this corridor will be displayed. - * @memberof CorridorGraphics.prototype - * @type {Property} + * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. + * + * @memberof DataSource.prototype + * @type {EntityCluster} */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + clustering : { + get : DeveloperError.throwInstantiationError + } }); /** - * Duplicates this instance. + * Updates the data source to the provided time. This function is optional and + * is not required to be implemented. It is provided for data sources which + * retrieve data based on the current animation time or scene state. + * If implemented, update will be called by {@link DataSourceDisplay} once a frame. + * @function * - * @param {CorridorGraphics} [result] The object onto which to store the result. - * @returns {CorridorGraphics} The modified result parameter or a new instance if one was not provided. + * @param {JulianDate} time The simulation time. + * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ - CorridorGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new CorridorGraphics(this); - } - result.show = this.show; - result.material = this.material; - result.positions = this.positions; - result.height = this.height; - result.extrudedHeight = this.extrudedHeight; - result.granularity = this.granularity; - result.width = this.width; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.cornerType = this.cornerType; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; + DataSource.prototype.update = DeveloperError.throwInstantiationError; /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {CorridorGraphics} source The object to be merged into this object. + * @private */ - CorridorGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + DataSource.setLoading = function(dataSource, isLoading) { + if (dataSource._isLoading !== isLoading) { + if (isLoading) { + dataSource._entityCollection.suspendEvents(); + } else { + dataSource._entityCollection.resumeEvents(); + } + dataSource._isLoading = isLoading; + dataSource._loading.raiseEvent(dataSource, isLoading); } - - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.positions = defaultValue(this.positions, source.positions); - this.height = defaultValue(this.height, source.height); - this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); - this.granularity = defaultValue(this.granularity, source.granularity); - this.width = defaultValue(this.width, source.width); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.cornerType = defaultValue(this.cornerType, source.cornerType); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); }; - return CorridorGraphics; + return DataSource; }); -define('DataSources/createRawPropertyDescriptor',[ - './createPropertyDescriptor' +define('Scene/SceneTransforms',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/defined', + '../Core/DeveloperError', + '../Core/Math', + '../Core/Matrix4', + '../Core/OrthographicFrustum', + '../Core/OrthographicOffCenterFrustum', + '../Core/Transforms', + './SceneMode' ], function( - createPropertyDescriptor) { + BoundingRectangle, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + defined, + DeveloperError, + CesiumMath, + Matrix4, + OrthographicFrustum, + OrthographicOffCenterFrustum, + Transforms, + SceneMode) { 'use strict'; - function createRawProperty(value) { - return value; - } - /** - * @private + * Functions that do scene-dependent transforms between rendering-related coordinate systems. + * + * @exports SceneTransforms */ - function createRawPropertyDescriptor(name, configurable) { - return createPropertyDescriptor(name, configurable, createRawProperty); - } + var SceneTransforms = {}; - return createRawPropertyDescriptor; -}); + var actualPositionScratch = new Cartesian4(0, 0, 0, 1); + var positionCC = new Cartesian4(); + var scratchViewport = new BoundingRectangle(); -define('DataSources/CylinderGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + var scratchWindowCoord0 = new Cartesian2(); + var scratchWindowCoord1 = new Cartesian2(); /** - * Describes a cylinder, truncated cone, or cone defined by a length, top radius, and bottom radius. - * The center position and orientation are determined by the containing {@link Entity}. + * Transforms a position in WGS84 coordinates to window coordinates. This is commonly used to place an + * HTML element at the same screen position as an object in the scene. * - * @alias CylinderGraphics - * @constructor + * @param {Scene} scene The scene. + * @param {Cartesian3} position The position in WGS84 (world) coordinates. + * @param {Cartesian2} [result] An optional object to return the input position transformed to window coordinates. + * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid. * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.length] A numeric Property specifying the length of the cylinder. - * @param {Property} [options.topRadius] A numeric Property specifying the radius of the top of the cylinder. - * @param {Property} [options.bottomRadius] A numeric Property specifying the radius of the bottom of the cylinder. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the cylinder. - * @param {Property} [options.fill=true] A boolean Property specifying whether the cylinder is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the cylinder. - * @param {Property} [options.outline=false] A boolean Property specifying whether the cylinder is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.numberOfVerticalLines=16] A numeric Property specifying the number of vertical lines to draw along the perimeter for the outline. - * @param {Property} [options.slices=128] The number of edges around the perimeter of the cylinder. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the cylinder casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this cylinder will be displayed. + * @example + * // Output the window position of longitude/latitude (0, 0) every time the mouse moves. + * var scene = widget.scene; + * var ellipsoid = scene.globe.ellipsoid; + * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + * handler.setInputAction(function(movement) { + * console.log(Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position)); + * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); */ - function CylinderGraphics(options) { - this._length = undefined; - this._lengthSubscription = undefined; - this._topRadius = undefined; - this._topRadiusSubscription = undefined; - this._bottomRadius = undefined; - this._bottomRadiusSubscription = undefined; - this._numberOfVerticalLines = undefined; - this._numberOfVerticalLinesSubscription = undefined; - this._slices = undefined; - this._slicesSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + SceneTransforms.wgs84ToWindowCoordinates = function(scene, position, result) { + return SceneTransforms.wgs84WithEyeOffsetToWindowCoordinates(scene, position, Cartesian3.ZERO, result); + }; - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + var scratchCartesian4 = new Cartesian4(); + var scratchEyeOffset = new Cartesian3(); + + function worldToClip(position, eyeOffset, camera, result) { + var viewMatrix = camera.viewMatrix; + + var positionEC = Matrix4.multiplyByVector(viewMatrix, Cartesian4.fromElements(position.x, position.y, position.z, 1, scratchCartesian4), scratchCartesian4); + + var zEyeOffset = Cartesian3.multiplyComponents(eyeOffset, Cartesian3.normalize(positionEC, scratchEyeOffset), scratchEyeOffset); + positionEC.x += eyeOffset.x + zEyeOffset.x; + positionEC.y += eyeOffset.y + zEyeOffset.y; + positionEC.z += zEyeOffset.z; + + return Matrix4.multiplyByVector(camera.frustum.projectionMatrix, positionEC, result); } - defineProperties(CylinderGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof CylinderGraphics.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + var scratchMaxCartographic = new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO); + var scratchProjectedCartesian = new Cartesian3(); + var scratchCameraPosition = new Cartesian3(); - /** - * Gets or sets the numeric Property specifying the length of the cylinder. - * @memberof CylinderGraphics.prototype - * @type {Property} - */ - length : createPropertyDescriptor('length'), + /** + * @private + */ + SceneTransforms.wgs84WithEyeOffsetToWindowCoordinates = function(scene, position, eyeOffset, result) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } + + // Transform for 3D, 2D, or Columbus view + var frameState = scene.frameState; + var actualPosition = SceneTransforms.computeActualWgs84Position(frameState, position, actualPositionScratch); - /** - * Gets or sets the numeric Property specifying the radius of the top of the cylinder. - * @memberof CylinderGraphics.prototype - * @type {Property} - */ - topRadius : createPropertyDescriptor('topRadius'), + if (!defined(actualPosition)) { + return undefined; + } - /** - * Gets or sets the numeric Property specifying the radius of the bottom of the cylinder. - * @memberof CylinderGraphics.prototype - * @type {Property} - */ - bottomRadius : createPropertyDescriptor('bottomRadius'), + // Assuming viewport takes up the entire canvas... + var canvas = scene.canvas; + var viewport = scratchViewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = canvas.clientWidth; + viewport.height = canvas.clientHeight; - /** - * Gets or sets the Property specifying the number of vertical lines to draw along the perimeter for the outline. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default 16 - */ - numberOfVerticalLines : createPropertyDescriptor('numberOfVerticalLines'), + var camera = scene.camera; + var cameraCentered = false; - /** - * Gets or sets the Property specifying the number of edges around the perimeter of the cylinder. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default 128 - */ - slices : createPropertyDescriptor('slices'), + if (frameState.mode === SceneMode.SCENE2D) { + var projection = scene.mapProjection; + var maxCartographic = scratchMaxCartographic; + var maxCoord = projection.project(maxCartographic, scratchProjectedCartesian); - /** - * Gets or sets the boolean Property specifying the visibility of the cylinder. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + var cameraPosition = Cartesian3.clone(camera.position, scratchCameraPosition); + var frustum = camera.frustum.clone(); - /** - * Gets or sets the Property specifying the material used to fill the cylinder. - * @memberof CylinderGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), + var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, new Matrix4()); + var projectionMatrix = camera.frustum.projectionMatrix; - /** - * Gets or sets the boolean Property specifying whether the cylinder is filled with the provided material. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default true - */ - fill : createPropertyDescriptor('fill'), + var x = camera.positionWC.y; + var eyePoint = Cartesian3.fromElements(CesiumMath.sign(x) * maxCoord.x - x, 0.0, -camera.positionWC.x); + var windowCoordinates = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, eyePoint); - /** - * Gets or sets the boolean Property specifying whether the cylinder is outlined. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), + if (x === 0.0 || windowCoordinates.x <= 0.0 || windowCoordinates.x >= canvas.clientWidth) { + cameraCentered = true; + } else { + if (windowCoordinates.x > canvas.clientWidth * 0.5) { + viewport.width = windowCoordinates.x; - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), + camera.frustum.right = maxCoord.x - x; - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); + SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord0); - /** - * Get or sets the enum Property specifying whether the cylinder - * casts or receives shadows from each light source. - * @memberof CylinderGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + viewport.x += windowCoordinates.x; - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this cylinder will be displayed. - * @memberof CylinderGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + camera.position.x = -camera.position.x; - /** - * Duplicates this instance. - * - * @param {CylinderGraphics} [result] The object onto which to store the result. - * @returns {CylinderGraphics} The modified result parameter or a new instance if one was not provided. - */ - CylinderGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new CylinderGraphics(this); - } - result.bottomRadius = this.bottomRadius; - result.length = this.length; - result.topRadius = this.topRadius; - result.show = this.show; - result.material = this.material; - result.numberOfVerticalLines = this.numberOfVerticalLines; - result.slices = this.slices; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; + var right = camera.frustum.right; + camera.frustum.right = -camera.frustum.left; + camera.frustum.left = -right; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {CylinderGraphics} source The object to be merged into this object. - */ - CylinderGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); - } - - this.bottomRadius = defaultValue(this.bottomRadius, source.bottomRadius); - this.length = defaultValue(this.length, source.length); - this.topRadius = defaultValue(this.topRadius, source.topRadius); - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.numberOfVerticalLines = defaultValue(this.numberOfVerticalLines, source.numberOfVerticalLines); - this.slices = defaultValue(this.slices, source.slices); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - }; + positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); + SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord1); + } else { + viewport.x += windowCoordinates.x; + viewport.width -= windowCoordinates.x; - return CylinderGraphics; -}); + camera.frustum.left = -maxCoord.x - x; -define('DataSources/EllipseGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); + SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord0); - /** - * Describes an ellipse defined by a center point and semi-major and semi-minor axes. - * The ellipse conforms to the curvature of the globe and can be placed on the surface or - * at altitude and can optionally be extruded into a volume. - * The center point is determined by the containing {@link Entity}. - * - * @alias EllipseGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.semiMajorAxis] The numeric Property specifying the semi-major axis. - * @param {Property} [options.semiMinorAxis] The numeric Property specifying the semi-minor axis. - * @param {Property} [options.height=0] A numeric Property specifying the altitude of the ellipse relative to the ellipsoid surface. - * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the ellipse's extruded face relative to the ellipsoid surface. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the ellipse. - * @param {Property} [options.fill=true] A boolean Property specifying whether the ellipse is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the ellipse. - * @param {Property} [options.outline=false] A boolean Property specifying whether the ellipse is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.numberOfVerticalLines=16] A numeric Property specifying the number of vertical lines to draw along the perimeter for the outline. - * @param {Property} [options.rotation=0.0] A numeric property specifying the rotation of the ellipse counter-clockwise from north. - * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the ellipse texture counter-clockwise from north. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the ellipse. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipse casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this ellipse will be displayed. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Circles and Ellipses.html|Cesium Sandcastle Circles and Ellipses Demo} - */ - function EllipseGraphics(options) { - this._semiMajorAxis = undefined; - this._semiMajorAxisSubscription = undefined; - this._semiMinorAxis = undefined; - this._semiMinorAxisSubscription = undefined; - this._rotation = undefined; - this._rotationSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._height = undefined; - this._heightSubscription = undefined; - this._extrudedHeight = undefined; - this._extrudedHeightSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._stRotation = undefined; - this._stRotationSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._numberOfVerticalLines = undefined; - this._numberOfVerticalLinesSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + viewport.x = viewport.x - viewport.width; - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + camera.position.x = -camera.position.x; - defineProperties(EllipseGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof EllipseGraphics.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + var left = camera.frustum.left; + camera.frustum.left = -camera.frustum.right; + camera.frustum.right = -left; + + positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); + SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord1); + } + + Cartesian3.clone(cameraPosition, camera.position); + camera.frustum = frustum.clone(); + + result = Cartesian2.clone(scratchWindowCoord0, result); + if (result.x < 0.0 || result.x > canvas.clientWidth) { + result.x = scratchWindowCoord1.x; + } } - }, + } - /** - * Gets or sets the numeric Property specifying the semi-major axis. - * @memberof EllipseGraphics.prototype - * @type {Property} - */ - semiMajorAxis : createPropertyDescriptor('semiMajorAxis'), + if (frameState.mode !== SceneMode.SCENE2D || cameraCentered) { + // View-projection matrix to transform from world coordinates to clip coordinates + positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); + if (positionCC.z < 0 && !(camera.frustum instanceof OrthographicFrustum) && !(camera.frustum instanceof OrthographicOffCenterFrustum)) { + return undefined; + } - /** - * Gets or sets the numeric Property specifying the semi-minor axis. - * @memberof EllipseGraphics.prototype - * @type {Property} - */ - semiMinorAxis : createPropertyDescriptor('semiMinorAxis'), + result = SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, result); + } - /** - * Gets or sets the numeric property specifying the rotation of the ellipse clockwise from north. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default 0 - */ - rotation : createPropertyDescriptor('rotation'), + result.y = canvas.clientHeight - result.y; + return result; + }; - /** - * Gets or sets the boolean Property specifying the visibility of the ellipse. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + /** + * Transforms a position in WGS84 coordinates to drawing buffer coordinates. This may produce different + * results from SceneTransforms.wgs84ToWindowCoordinates when the browser zoom is not 100%, or on high-DPI displays. + * + * @param {Scene} scene The scene. + * @param {Cartesian3} position The position in WGS84 (world) coordinates. + * @param {Cartesian2} [result] An optional object to return the input position transformed to window coordinates. + * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid. + * + * @example + * // Output the window position of longitude/latitude (0, 0) every time the mouse moves. + * var scene = widget.scene; + * var ellipsoid = scene.globe.ellipsoid; + * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + * handler.setInputAction(function(movement) { + * console.log(Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position)); + * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + */ + SceneTransforms.wgs84ToDrawingBufferCoordinates = function(scene, position, result) { + result = SceneTransforms.wgs84ToWindowCoordinates(scene, position, result); + if (!defined(result)) { + return undefined; + } - /** - * Gets or sets the Property specifying the material used to fill the ellipse. - * @memberof EllipseGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), + return SceneTransforms.transformWindowToDrawingBuffer(scene, result, result); + }; - /** - * Gets or sets the numeric Property specifying the altitude of the ellipse. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default 0.0 - */ - height : createPropertyDescriptor('height'), + var projectedPosition = new Cartesian3(); + var positionInCartographic = new Cartographic(); - /** - * Gets or sets the numeric Property specifying the altitude of the ellipse extrusion. - * Setting this property creates volume starting at height and ending at this altitude. - * @memberof EllipseGraphics.prototype - * @type {Property} - */ - extrudedHeight : createPropertyDescriptor('extrudedHeight'), + /** + * @private + */ + SceneTransforms.computeActualWgs84Position = function(frameState, position, result) { + var mode = frameState.mode; - /** - * Gets or sets the numeric Property specifying the angular distance between points on the ellipse. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default {CesiumMath.RADIANS_PER_DEGREE} - */ - granularity : createPropertyDescriptor('granularity'), + if (mode === SceneMode.SCENE3D) { + return Cartesian3.clone(position, result); + } - /** - * Gets or sets the numeric property specifying the rotation of the ellipse texture counter-clockwise from north. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default 0 - */ - stRotation : createPropertyDescriptor('stRotation'), + var projection = frameState.mapProjection; + var cartographic = projection.ellipsoid.cartesianToCartographic(position, positionInCartographic); + if (!defined(cartographic)) { + return undefined; + } - /** - * Gets or sets the boolean Property specifying whether the ellipse is filled with the provided material. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default true - */ - fill : createPropertyDescriptor('fill'), + projection.project(cartographic, projectedPosition); - /** - * Gets or sets the Property specifying whether the ellipse is outlined. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), + if (mode === SceneMode.COLUMBUS_VIEW) { + return Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, result); + } - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), + if (mode === SceneMode.SCENE2D) { + return Cartesian3.fromElements(0.0, projectedPosition.x, projectedPosition.y, result); + } - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + // mode === SceneMode.MORPHING + var morphTime = frameState.morphTime; + return Cartesian3.fromElements( + CesiumMath.lerp(projectedPosition.z, position.x, morphTime), + CesiumMath.lerp(projectedPosition.x, position.y, morphTime), + CesiumMath.lerp(projectedPosition.y, position.z, morphTime), + result); + }; - /** - * Gets or sets the numeric Property specifying the number of vertical lines to draw along the perimeter for the outline. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default 16 - */ - numberOfVerticalLines : createPropertyDescriptor('numberOfVerticalLines'), + var positionNDC = new Cartesian3(); + var positionWC = new Cartesian3(); + var viewportTransform = new Matrix4(); + + /** + * @private + */ + SceneTransforms.clipToGLWindowCoordinates = function(viewport, position, result) { + // Perspective divide to transform from clip coordinates to normalized device coordinates + Cartesian3.divideByScalar(position, position.w, positionNDC); - /** - * Get or sets the enum Property specifying whether the ellipse - * casts or receives shadows from each light source. - * @memberof EllipseGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + // Viewport transform to transform from clip coordinates to window coordinates + Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, viewportTransform); + Matrix4.multiplyByPoint(viewportTransform, positionNDC, positionWC); - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this ellipse will be displayed. - * @memberof EllipseGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + return Cartesian2.fromCartesian3(positionWC, result); + }; /** - * Duplicates this instance. - * - * @param {EllipseGraphics} [result] The object onto which to store the result. - * @returns {EllipseGraphics} The modified result parameter or a new instance if one was not provided. + * @private */ - EllipseGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new EllipseGraphics(this); - } - result.rotation = this.rotation; - result.semiMajorAxis = this.semiMajorAxis; - result.semiMinorAxis = this.semiMinorAxis; - result.show = this.show; - result.material = this.material; - result.height = this.height; - result.extrudedHeight = this.extrudedHeight; - result.granularity = this.granularity; - result.stRotation = this.stRotation; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.numberOfVerticalLines = this.numberOfVerticalLines; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; + SceneTransforms.transformWindowToDrawingBuffer = function(scene, windowPosition, result) { + var canvas = scene.canvas; + var xScale = scene.drawingBufferWidth / canvas.clientWidth; + var yScale = scene.drawingBufferHeight / canvas.clientHeight; + return Cartesian2.fromElements(windowPosition.x * xScale, windowPosition.y * yScale, result); }; + var scratchNDC = new Cartesian4(); + var scratchWorldCoords = new Cartesian4(); + /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {EllipseGraphics} source The object to be merged into this object. + * @private */ - EllipseGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + SceneTransforms.drawingBufferToWgs84Coordinates = function(scene, drawingBufferPosition, depth, result) { + var context = scene.context; + var uniformState = context.uniformState; + + var viewport = scene._passState.viewport; + var ndc = Cartesian4.clone(Cartesian4.UNIT_W, scratchNDC); + ndc.x = (drawingBufferPosition.x - viewport.x) / viewport.width * 2.0 - 1.0; + ndc.y = (drawingBufferPosition.y - viewport.y) / viewport.height * 2.0 - 1.0; + ndc.z = (depth * 2.0) - 1.0; + ndc.w = 1.0; + + var worldCoords; + var frustum = scene.camera.frustum; + if (!defined(frustum.fovy)) { + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } + var currentFrustum = uniformState.currentFrustum; + worldCoords = scratchWorldCoords; + worldCoords.x = (ndc.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; + worldCoords.y = (ndc.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; + worldCoords.z = (ndc.z * (currentFrustum.x - currentFrustum.y) - currentFrustum.x - currentFrustum.y) * 0.5; + worldCoords.w = 1.0; + + worldCoords = Matrix4.multiplyByVector(uniformState.inverseView, worldCoords, worldCoords); + } else { + worldCoords = Matrix4.multiplyByVector(uniformState.inverseViewProjection, ndc, scratchWorldCoords); + + // Reverse perspective divide + var w = 1.0 / worldCoords.w; + Cartesian3.multiplyByScalar(worldCoords, w, worldCoords); } - - this.rotation = defaultValue(this.rotation, source.rotation); - this.semiMajorAxis = defaultValue(this.semiMajorAxis, source.semiMajorAxis); - this.semiMinorAxis = defaultValue(this.semiMinorAxis, source.semiMinorAxis); - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.height = defaultValue(this.height, source.height); - this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); - this.granularity = defaultValue(this.granularity, source.granularity); - this.stRotation = defaultValue(this.stRotation, source.stRotation); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.numberOfVerticalLines = defaultValue(this.numberOfVerticalLines, source.numberOfVerticalLines); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + + return Cartesian3.fromCartesian4(worldCoords, result); }; - return EllipseGraphics; + return SceneTransforms; }); -define('DataSources/EllipsoidGraphics',[ +define('Scene/Billboard',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/Color', + '../Core/createGuid', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' + '../Core/DistanceDisplayCondition', + '../Core/Matrix4', + '../Core/NearFarScalar', + '../Core/Resource', + './HeightReference', + './HorizontalOrigin', + './SceneMode', + './SceneTransforms', + './VerticalOrigin' ], function( + BoundingRectangle, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + Color, + createGuid, defaultValue, defined, defineProperties, DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { + DistanceDisplayCondition, + Matrix4, + NearFarScalar, + Resource, + HeightReference, + HorizontalOrigin, + SceneMode, + SceneTransforms, + VerticalOrigin) { 'use strict'; /** - * Describe an ellipsoid or sphere. The center position and orientation are determined by the containing {@link Entity}. + * A viewport-aligned image positioned in the 3D scene, that is created + * and rendered using a {@link BillboardCollection}. A billboard is created and its initial + * properties are set by calling {@link BillboardCollection#add}. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.png' width='400' height='300' /><br /> + * Example billboards + * </div> * - * @alias EllipsoidGraphics - * @constructor + * @alias Billboard * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.radii] A {@link Cartesian3} Property specifying the radii of the ellipsoid. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the ellipsoid. - * @param {Property} [options.fill=true] A boolean Property specifying whether the ellipsoid is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the ellipsoid. - * @param {Property} [options.outline=false] A boolean Property specifying whether the ellipsoid is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.subdivisions=128] A Property specifying the number of samples per outline ring, determining the granularity of the curvature. - * @param {Property} [options.stackPartitions=64] A Property specifying the number of stacks. - * @param {Property} [options.slicePartitions=64] A Property specifying the number of radial slices. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipsoid casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this ellipsoid will be displayed. + * @performance Reading a property, e.g., {@link Billboard#show}, is constant time. + * Assigning to a property is constant time but results in + * CPU to GPU traffic when {@link BillboardCollection#update} is called. The per-billboard traffic is + * the same regardless of how many properties were updated. If most billboards in a collection need to be + * updated, it may be more efficient to clear the collection with {@link BillboardCollection#removeAll} + * and add new billboards instead of modifying each one. + * + * @exception {DeveloperError} scaleByDistance.far must be greater than scaleByDistance.near + * @exception {DeveloperError} translucencyByDistance.far must be greater than translucencyByDistance.near + * @exception {DeveloperError} pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near + * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near + * + * @see BillboardCollection + * @see BillboardCollection#add + * @see Label + * + * @internalConstructor * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Spheres%20and%20Ellipsoids.html|Cesium Sandcastle Spheres and Ellipsoids Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Billboards.html|Cesium Sandcastle Billboard Demo} */ - function EllipsoidGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._radii = undefined; - this._radiiSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._stackPartitions = undefined; - this._stackPartitionsSubscription = undefined; - this._slicePartitions = undefined; - this._slicePartitionsSubscription = undefined; - this._subdivisions = undefined; - this._subdivisionsSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + function Billboard(options, billboardCollection) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } + + var translucencyByDistance = options.translucencyByDistance; + var pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; + var scaleByDistance = options.scaleByDistance; + var distanceDisplayCondition = options.distanceDisplayCondition; + if (defined(translucencyByDistance)) { + if (translucencyByDistance.far <= translucencyByDistance.near) { + throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + } + translucencyByDistance = NearFarScalar.clone(translucencyByDistance); + } + if (defined(pixelOffsetScaleByDistance)) { + if (pixelOffsetScaleByDistance.far <= pixelOffsetScaleByDistance.near) { + throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); + } + pixelOffsetScaleByDistance = NearFarScalar.clone(pixelOffsetScaleByDistance); + } + if (defined(scaleByDistance)) { + if (scaleByDistance.far <= scaleByDistance.near) { + throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + } + scaleByDistance = NearFarScalar.clone(scaleByDistance); + } + if (defined(distanceDisplayCondition)) { + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); + } + distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); + } + + this._show = defaultValue(options.show, true); + this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); + this._actualPosition = Cartesian3.clone(this._position); // For columbus view and 2D + this._pixelOffset = Cartesian2.clone(defaultValue(options.pixelOffset, Cartesian2.ZERO)); + this._translate = new Cartesian2(0.0, 0.0); // used by labels for glyph vertex translation + this._eyeOffset = Cartesian3.clone(defaultValue(options.eyeOffset, Cartesian3.ZERO)); + this._heightReference = defaultValue(options.heightReference, HeightReference.NONE); + this._verticalOrigin = defaultValue(options.verticalOrigin, VerticalOrigin.CENTER); + this._horizontalOrigin = defaultValue(options.horizontalOrigin, HorizontalOrigin.CENTER); + this._scale = defaultValue(options.scale, 1.0); + this._color = Color.clone(defaultValue(options.color, Color.WHITE)); + this._rotation = defaultValue(options.rotation, 0.0); + this._alignedAxis = Cartesian3.clone(defaultValue(options.alignedAxis, Cartesian3.ZERO)); + this._width = options.width; + this._height = options.height; + this._scaleByDistance = scaleByDistance; + this._translucencyByDistance = translucencyByDistance; + this._pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; + this._sizeInMeters = defaultValue(options.sizeInMeters, false); + this._distanceDisplayCondition = distanceDisplayCondition; + this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); + this._id = options.id; + this._collection = defaultValue(options.collection, billboardCollection); + + this._pickId = undefined; + this._pickPrimitive = defaultValue(options._pickPrimitive, this); + this._billboardCollection = billboardCollection; + this._dirty = false; + this._index = -1; //Used only by BillboardCollection + this._batchIndex = undefined; // Used only by Vector3DTilePoints and BillboardCollection + + this._imageIndex = -1; + this._imageIndexPromise = undefined; + this._imageId = undefined; + this._image = undefined; + this._imageSubRegion = undefined; + this._imageWidth = undefined; + this._imageHeight = undefined; + + var image = options.image; + var imageId = options.imageId; + if (defined(image)) { + if (!defined(imageId)) { + if (typeof image === 'string') { + imageId = image; + } else if (defined(image.src)) { + imageId = image.src; + } else { + imageId = createGuid(); + } + } + + this._imageId = imageId; + this._image = image; + } + + if (defined(options.imageSubRegion)) { + this._imageId = imageId; + this._imageSubRegion = options.imageSubRegion; + } + + if (defined(this._billboardCollection._textureAtlas)) { + this._loadImage(); + } + + this._actualClampedPosition = undefined; + this._removeCallbackFunc = undefined; + this._mode = SceneMode.SCENE3D; + + this._clusterShow = true; + + this._updateClamping(); } - defineProperties(EllipsoidGraphics.prototype, { + var SHOW_INDEX = Billboard.SHOW_INDEX = 0; + var POSITION_INDEX = Billboard.POSITION_INDEX = 1; + var PIXEL_OFFSET_INDEX = Billboard.PIXEL_OFFSET_INDEX = 2; + var EYE_OFFSET_INDEX = Billboard.EYE_OFFSET_INDEX = 3; + var HORIZONTAL_ORIGIN_INDEX = Billboard.HORIZONTAL_ORIGIN_INDEX = 4; + var VERTICAL_ORIGIN_INDEX = Billboard.VERTICAL_ORIGIN_INDEX = 5; + var SCALE_INDEX = Billboard.SCALE_INDEX = 6; + var IMAGE_INDEX_INDEX = Billboard.IMAGE_INDEX_INDEX = 7; + var COLOR_INDEX = Billboard.COLOR_INDEX = 8; + var ROTATION_INDEX = Billboard.ROTATION_INDEX = 9; + var ALIGNED_AXIS_INDEX = Billboard.ALIGNED_AXIS_INDEX = 10; + var SCALE_BY_DISTANCE_INDEX = Billboard.SCALE_BY_DISTANCE_INDEX = 11; + var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX = 12; + var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = 13; + var DISTANCE_DISPLAY_CONDITION = Billboard.DISTANCE_DISPLAY_CONDITION = 14; + var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE = 15; + Billboard.NUMBER_OF_PROPERTIES = 16; + + function makeDirty(billboard, propertyChanged) { + var billboardCollection = billboard._billboardCollection; + if (defined(billboardCollection)) { + billboardCollection._updateBillboard(billboard, propertyChanged); + billboard._dirty = true; + } + } + + defineProperties(Billboard.prototype, { /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof EllipsoidGraphics.prototype - * - * @type {Event} - * @readonly + * Determines if this billboard will be shown. Use this to hide or show a billboard, instead + * of removing it and re-adding it to the collection. + * @memberof Billboard.prototype + * @type {Boolean} + * @default true */ - definitionChanged : { + show : { get : function() { - return this._definitionChanged; + return this._show; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._show !== value) { + this._show = value; + makeDirty(this, SHOW_INDEX); + } } }, /** - * Gets or sets the boolean Property specifying the visibility of the ellipsoid. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + * Gets or sets the Cartesian position of this billboard. + * @memberof Billboard.prototype + * @type {Cartesian3} + */ + position : { + get : function() { + return this._position; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var position = this._position; + if (!Cartesian3.equals(position, value)) { + Cartesian3.clone(value, position); + Cartesian3.clone(value, this._actualPosition); + this._updateClamping(); + makeDirty(this, POSITION_INDEX); + } + } + }, /** - * Gets or sets the {@link Cartesian3} {@link Property} specifying the radii of the ellipsoid. - * @memberof EllipsoidGraphics.prototype - * @type {Property} + * Gets or sets the height reference of this billboard. + * @memberof Billboard.prototype + * @type {HeightReference} + * @default HeightReference.NONE */ - radii : createPropertyDescriptor('radii'), + heightReference : { + get : function() { + return this._heightReference; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var heightReference = this._heightReference; + if (value !== heightReference) { + this._heightReference = value; + this._updateClamping(); + makeDirty(this, POSITION_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the material used to fill the ellipsoid. - * @memberof EllipsoidGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE + * Gets or sets the pixel offset in screen space from the origin of this billboard. This is commonly used + * to align multiple billboards and labels at the same position, e.g., an image and text. The + * screen space origin is the top, left corner of the canvas; <code>x</code> increases from + * left to right, and <code>y</code> increases from top to bottom. + * <br /><br /> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><code>default</code><br/><img src='Images/Billboard.setPixelOffset.default.png' width='250' height='188' /></td> + * <td align='center'><code>b.pixeloffset = new Cartesian2(50, 25);</code><br/><img src='Images/Billboard.setPixelOffset.x50y-25.png' width='250' height='188' /></td> + * </tr></table> + * The billboard's origin is indicated by the yellow point. + * </div> + * @memberof Billboard.prototype + * @type {Cartesian2} */ - material : createMaterialPropertyDescriptor('material'), + pixelOffset : { + get : function() { + return this._pixelOffset; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var pixelOffset = this._pixelOffset; + if (!Cartesian2.equals(pixelOffset, value)) { + Cartesian2.clone(value, pixelOffset); + makeDirty(this, PIXEL_OFFSET_INDEX); + } + } + }, /** - * Gets or sets the boolean Property specifying whether the ellipsoid is filled with the provided material. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default true + * Gets or sets near and far scaling properties of a Billboard based on the billboard's distance from the camera. + * A billboard's scale will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the billboard's scale remains clamped to the nearest bound. If undefined, + * scaleByDistance will be disabled. + * @memberof Billboard.prototype + * @type {NearFarScalar} + * + * @example + * // Example 1. + * // Set a billboard's scaleByDistance to scale by 1.5 when the + * // camera is 1500 meters from the billboard and disappear as + * // the camera distance approaches 8.0e6 meters. + * b.scaleByDistance = new Cesium.NearFarScalar(1.5e2, 1.5, 8.0e6, 0.0); + * + * @example + * // Example 2. + * // disable scaling by distance + * b.scaleByDistance = undefined; */ - fill : createPropertyDescriptor('fill'), + scaleByDistance : { + get : function() { + return this._scaleByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var scaleByDistance = this._scaleByDistance; + if (!NearFarScalar.equals(scaleByDistance, value)) { + this._scaleByDistance = NearFarScalar.clone(value, scaleByDistance); + makeDirty(this, SCALE_BY_DISTANCE_INDEX); + } + } + }, /** - * Gets or sets the Property specifying whether the ellipsoid is outlined. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default false + * Gets or sets near and far translucency properties of a Billboard based on the billboard's distance from the camera. + * A billboard's translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the billboard's translucency remains clamped to the nearest bound. If undefined, + * translucencyByDistance will be disabled. + * @memberof Billboard.prototype + * @type {NearFarScalar} + * + * @example + * // Example 1. + * // Set a billboard's translucency to 1.0 when the + * // camera is 1500 meters from the billboard and disappear as + * // the camera distance approaches 8.0e6 meters. + * b.translucencyByDistance = new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.0); + * + * @example + * // Example 2. + * // disable translucency by distance + * b.translucencyByDistance = undefined; */ - outline : createPropertyDescriptor('outline'), + translucencyByDistance : { + get : function() { + return this._translucencyByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var translucencyByDistance = this._translucencyByDistance; + if (!NearFarScalar.equals(translucencyByDistance, value)) { + this._translucencyByDistance = NearFarScalar.clone(value, translucencyByDistance); + makeDirty(this, TRANSLUCENCY_BY_DISTANCE_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default Color.BLACK + * Gets or sets near and far pixel offset scaling properties of a Billboard based on the billboard's distance from the camera. + * A billboard's pixel offset will be scaled between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the billboard's pixel offset scale remains clamped to the nearest bound. If undefined, + * pixelOffsetScaleByDistance will be disabled. + * @memberof Billboard.prototype + * @type {NearFarScalar} + * + * @example + * // Example 1. + * // Set a billboard's pixel offset scale to 0.0 when the + * // camera is 1500 meters from the billboard and scale pixel offset to 10.0 pixels + * // in the y direction the camera distance approaches 8.0e6 meters. + * b.pixelOffset = new Cesium.Cartesian2(0.0, 1.0); + * b.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(1.5e2, 0.0, 8.0e6, 10.0); + * + * @example + * // Example 2. + * // disable pixel offset by distance + * b.pixelOffsetScaleByDistance = undefined; */ - outlineColor : createPropertyDescriptor('outlineColor'), + pixelOffsetScaleByDistance : { + get : function() { + return this._pixelOffsetScaleByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; + if (!NearFarScalar.equals(pixelOffsetScaleByDistance, value)) { + this._pixelOffsetScaleByDistance = NearFarScalar.clone(value, pixelOffsetScaleByDistance); + makeDirty(this, PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX); + } + } + }, /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default 1.0 + * Gets or sets the 3D Cartesian offset applied to this billboard in eye coordinates. Eye coordinates is a left-handed + * coordinate system, where <code>x</code> points towards the viewer's right, <code>y</code> points up, and + * <code>z</code> points into the screen. Eye coordinates use the same scale as world and model coordinates, + * which is typically meters. + * <br /><br /> + * An eye offset is commonly used to arrange multiple billboards or objects at the same position, e.g., to + * arrange a billboard above its corresponding 3D model. + * <br /><br /> + * Below, the billboard is positioned at the center of the Earth but an eye offset makes it always + * appear on top of the Earth regardless of the viewer's or Earth's orientation. + * <br /><br /> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> + * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> + * </tr></table> + * <code>b.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code><br /><br /> + * </div> + * @memberof Billboard.prototype + * @type {Cartesian3} */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + eyeOffset : { + get : function() { + return this._eyeOffset; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var eyeOffset = this._eyeOffset; + if (!Cartesian3.equals(eyeOffset, value)) { + Cartesian3.clone(value, eyeOffset); + makeDirty(this, EYE_OFFSET_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the number of stacks. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default 64 + * Gets or sets the horizontal origin of this billboard, which determines if the billboard is + * to the left, center, or right of its anchor position. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> + * </div> + * @memberof Billboard.prototype + * @type {HorizontalOrigin} + * @example + * // Use a bottom, left origin + * b.horizontalOrigin = Cesium.HorizontalOrigin.LEFT; + * b.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; */ - stackPartitions : createPropertyDescriptor('stackPartitions'), + horizontalOrigin : { + get : function() { + return this._horizontalOrigin; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._horizontalOrigin !== value) { + this._horizontalOrigin = value; + makeDirty(this, HORIZONTAL_ORIGIN_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the number of radial slices. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default 64 + * Gets or sets the vertical origin of this billboard, which determines if the billboard is + * to the above, below, or at the center of its anchor position. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> + * </div> + * @memberof Billboard.prototype + * @type {VerticalOrigin} + * @example + * // Use a bottom, left origin + * b.horizontalOrigin = Cesium.HorizontalOrigin.LEFT; + * b.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; */ - slicePartitions : createPropertyDescriptor('slicePartitions'), + verticalOrigin : { + get : function() { + return this._verticalOrigin; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._verticalOrigin !== value) { + this._verticalOrigin = value; + makeDirty(this, VERTICAL_ORIGIN_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the number of samples per outline ring, determining the granularity of the curvature. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default 128 + * Gets or sets the uniform scale that is multiplied with the billboard's image size in pixels. + * A scale of <code>1.0</code> does not change the size of the billboard; a scale greater than + * <code>1.0</code> enlarges the billboard; a positive scale less than <code>1.0</code> shrinks + * the billboard. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setScale.png' width='400' height='300' /><br/> + * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, + * and <code>2.0</code>. + * </div> + * @memberof Billboard.prototype + * @type {Number} */ - subdivisions : createPropertyDescriptor('subdivisions'), + scale : { + get : function() { + return this._scale; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._scale !== value) { + this._scale = value; + makeDirty(this, SCALE_INDEX); + } + } + }, /** - * Get or sets the enum Property specifying whether the ellipsoid - * casts or receives shadows from each light source. - * @memberof EllipsoidGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED + * Gets or sets the color that is multiplied with the billboard's texture. This has two common use cases. First, + * the same white texture may be used by many different billboards, each with a different color, to create + * colored billboards. Second, the color's alpha component can be used to make the billboard translucent as shown below. + * An alpha of <code>0.0</code> makes the billboard transparent, and <code>1.0</code> makes the billboard opaque. + * <br /><br /> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><code>default</code><br/><img src='Images/Billboard.setColor.Alpha255.png' width='250' height='188' /></td> + * <td align='center'><code>alpha : 0.5</code><br/><img src='Images/Billboard.setColor.Alpha127.png' width='250' height='188' /></td> + * </tr></table> + * </div> + * <br /> + * The red, green, blue, and alpha values are indicated by <code>value</code>'s <code>red</code>, <code>green</code>, + * <code>blue</code>, and <code>alpha</code> properties as shown in Example 1. These components range from <code>0.0</code> + * (no intensity) to <code>1.0</code> (full intensity). + * @memberof Billboard.prototype + * @type {Color} + * + * @example + * // Example 1. Assign yellow. + * b.color = Cesium.Color.YELLOW; + * + * @example + * // Example 2. Make a billboard 50% translucent. + * b.color = new Cesium.Color(1.0, 1.0, 1.0, 0.5); */ - shadows : createPropertyDescriptor('shadows'), + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var color = this._color; + if (!Color.equals(color, value)) { + Color.clone(value, color); + makeDirty(this, COLOR_INDEX); + } + } + }, /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this ellipsoid will be displayed. - * @memberof EllipsoidGraphics.prototype - * @type {Property} + * Gets or sets the rotation angle in radians. + * @memberof Billboard.prototype + * @type {Number} */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); - - /** - * Duplicates this instance. - * - * @param {EllipsoidGraphics} [result] The object onto which to store the result. - * @returns {EllipsoidGraphics} The modified result parameter or a new instance if one was not provided. - */ - EllipsoidGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new EllipsoidGraphics(this); - } - result.show = this.show; - result.radii = this.radii; - result.material = this.material; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.stackPartitions = this.stackPartitions; - result.slicePartitions = this.slicePartitions; - result.subdivisions = this.subdivisions; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - - return result; - }; - - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {EllipsoidGraphics} source The object to be merged into this object. - */ - EllipsoidGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); - } - - this.show = defaultValue(this.show, source.show); - this.radii = defaultValue(this.radii, source.radii); - this.material = defaultValue(this.material, source.material); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.stackPartitions = defaultValue(this.stackPartitions, source.stackPartitions); - this.slicePartitions = defaultValue(this.slicePartitions, source.slicePartitions); - this.subdivisions = defaultValue(this.subdivisions, source.subdivisions); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - }; - - return EllipsoidGraphics; -}); - -define('DataSources/LabelGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createPropertyDescriptor) { - 'use strict'; - - /** - * Describes a two dimensional label located at the position of the containing {@link Entity}. - * <p> - * <div align='center'> - * <img src='Images/Label.png' width='400' height='300' /><br /> - * Example labels - * </div> - * </p> - * - * @alias LabelGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.text] A Property specifying the text. Explicit newlines '\n' are supported. - * @param {Property} [options.font='10px sans-serif'] A Property specifying the CSS font. - * @param {Property} [options.style=LabelStyle.FILL] A Property specifying the {@link LabelStyle}. - * @param {Property} [options.fillColor=Color.WHITE] A Property specifying the fill {@link Color}. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the outline {@link Color}. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the outline width. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the label. - * @param {Property} [options.showBackground=false] A boolean Property specifying the visibility of the background behind the label. - * @param {Property} [options.backgroundColor=new Color(0.165, 0.165, 0.165, 0.8)] A Property specifying the background {@link Color}. - * @param {Property} [options.backgroundPadding=new Cartesian2(7, 5)] A {@link Cartesian2} Property specifying the horizontal and vertical background padding in pixels. - * @param {Property} [options.scale=1.0] A numeric Property specifying the scale to apply to the text. - * @param {Property} [options.horizontalOrigin=HorizontalOrigin.CENTER] A Property specifying the {@link HorizontalOrigin}. - * @param {Property} [options.verticalOrigin=VerticalOrigin.CENTER] A Property specifying the {@link VerticalOrigin}. - * @param {Property} [options.eyeOffset=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the eye offset. - * @param {Property} [options.pixelOffset=Cartesian2.ZERO] A {@link Cartesian2} Property specifying the pixel offset. - * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera. - * @param {Property} [options.pixelOffsetScaleByDistance] A {@link NearFarScalar} Property used to set pixelOffset based on distance from the camera. - * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to set scale based on distance from the camera. - * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this label will be displayed. - * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Labels.html|Cesium Sandcastle Labels Demo} - */ - function LabelGraphics(options) { - this._text = undefined; - this._textSubscription = undefined; - this._font = undefined; - this._fontSubscription = undefined; - this._style = undefined; - this._styleSubscription = undefined; - this._fillColor = undefined; - this._fillColorSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._horizontalOrigin = undefined; - this._horizontalOriginSubscription = undefined; - this._verticalOrigin = undefined; - this._verticalOriginSubscription = undefined; - this._eyeOffset = undefined; - this._eyeOffsetSubscription = undefined; - this._heightReference = undefined; - this._heightReferenceSubscription = undefined; - this._pixelOffset = undefined; - this._pixelOffsetSubscription = undefined; - this._scale = undefined; - this._scaleSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._showBackground = undefined; - this._showBackgroundSubscription = undefined; - this._backgroundColor = undefined; - this._backgroundColorSubscription = undefined; - this._backgroundPadding = undefined; - this._backgroundPaddingSubscription = undefined; - this._translucencyByDistance = undefined; - this._translucencyByDistanceSubscription = undefined; - this._pixelOffsetScaleByDistance = undefined; - this._pixelOffsetScaleByDistanceSubscription = undefined; - this._scaleByDistance = undefined; - this._scaleByDistanceSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._disableDepthTestDistance = undefined; - this._disableDepthTestDistanceSubscription = undefined; - this._definitionChanged = new Event(); - - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + rotation : { + get : function() { + return this._rotation; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._rotation !== value) { + this._rotation = value; + makeDirty(this, ROTATION_INDEX); + } + } + }, - defineProperties(LabelGraphics.prototype, { /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof LabelGraphics.prototype + * Gets or sets the aligned axis in world space. The aligned axis is the unit vector that the billboard up vector points towards. + * The default is the zero vector, which means the billboard is aligned to the screen up vector. + * @memberof Billboard.prototype + * @type {Cartesian3} + * @example + * // Example 1. + * // Have the billboard up vector point north + * billboard.alignedAxis = Cesium.Cartesian3.UNIT_Z; * - * @type {Event} - * @readonly + * @example + * // Example 2. + * // Have the billboard point east. + * billboard.alignedAxis = Cesium.Cartesian3.UNIT_Z; + * billboard.rotation = -Cesium.Math.PI_OVER_TWO; + * + * @example + * // Example 3. + * // Reset the aligned axis + * billboard.alignedAxis = Cesium.Cartesian3.ZERO; */ - definitionChanged : { + alignedAxis : { get : function() { - return this._definitionChanged; + return this._alignedAxis; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var alignedAxis = this._alignedAxis; + if (!Cartesian3.equals(alignedAxis, value)) { + Cartesian3.clone(value, alignedAxis); + makeDirty(this, ALIGNED_AXIS_INDEX); + } } }, /** - * Gets or sets the string Property specifying the text of the label. - * Explicit newlines '\n' are supported. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - text : createPropertyDescriptor('text'), - - /** - * Gets or sets the string Property specifying the font in CSS syntax. - * @memberof LabelGraphics.prototype - * @type {Property} - * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font|CSS font on MDN} + * Gets or sets a width for the billboard. If undefined, the image width will be used. + * @memberof Billboard.prototype + * @type {Number} */ - font : createPropertyDescriptor('font'), + width : { + get : function() { + return defaultValue(this._width, this._imageWidth); + }, + set : function(value) { + if (this._width !== value) { + this._width = value; + makeDirty(this, IMAGE_INDEX_INDEX); + } + } + }, - /** - * Gets or sets the Property specifying the {@link LabelStyle}. - * @memberof LabelGraphics.prototype - * @type {Property} + /** + * Gets or sets a height for the billboard. If undefined, the image height will be used. + * @memberof Billboard.prototype + * @type {Number} */ - style : createPropertyDescriptor('style'), + height : { + get : function() { + return defaultValue(this._height, this._imageHeight); + }, + set : function(value) { + if (this._height !== value) { + this._height = value; + makeDirty(this, IMAGE_INDEX_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the fill {@link Color}. - * @memberof LabelGraphics.prototype - * @type {Property} + * Gets or sets if the billboard size is in meters or pixels. <code>true</code> to size the billboard in meters; + * otherwise, the size is in pixels. + * @memberof Billboard.prototype + * @type {Boolean} + * @default false */ - fillColor : createPropertyDescriptor('fillColor'), + sizeInMeters : { + get : function() { + return this._sizeInMeters; + }, + set : function(value) { + if (this._sizeInMeters !== value) { + this._sizeInMeters = value; + makeDirty(this, COLOR_INDEX); + } + } + }, /** - * Gets or sets the Property specifying the outline {@link Color}. - * @memberof LabelGraphics.prototype - * @type {Property} + * Gets or sets the condition specifying at what distance from the camera that this billboard will be displayed. + * @memberof Billboard.prototype + * @type {DistanceDisplayCondition} + * @default undefined */ - outlineColor : createPropertyDescriptor('outlineColor'), + distanceDisplayCondition : { + get : function() { + return this._distanceDisplayCondition; + }, + set : function(value) { + if (!DistanceDisplayCondition.equals(value, this._distanceDisplayCondition)) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); + makeDirty(this, DISTANCE_DISPLAY_CONDITION); + } + } + }, /** - * Gets or sets the numeric Property specifying the outline width. - * @memberof LabelGraphics.prototype - * @type {Property} + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof Billboard.prototype + * @type {Number} + * @default 0.0 */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + disableDepthTestDistance : { + get : function() { + return this._disableDepthTestDistance; + }, + set : function(value) { + if (this._disableDepthTestDistance !== value) { + if (!defined(value) || value < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } + this._disableDepthTestDistance = value; + makeDirty(this, DISABLE_DEPTH_DISTANCE); + } + } + }, /** - * Gets or sets the Property specifying the {@link HorizontalOrigin}. - * @memberof LabelGraphics.prototype - * @type {Property} + * Gets or sets the user-defined object returned when the billboard is picked. + * @memberof Billboard.prototype + * @type {Object} */ - horizontalOrigin : createPropertyDescriptor('horizontalOrigin'), + id : { + get : function() { + return this._id; + }, + set : function(value) { + this._id = value; + if (defined(this._pickId)) { + this._pickId.object.id = value; + } + } + }, /** - * Gets or sets the Property specifying the {@link VerticalOrigin}. - * @memberof LabelGraphics.prototype - * @type {Property} + * The primitive to return when picking this billboard. + * @memberof Billboard.prototype + * @private */ - verticalOrigin : createPropertyDescriptor('verticalOrigin'), + pickPrimitive : { + get : function() { + return this._pickPrimitive; + }, + set : function(value) { + this._pickPrimitive = value; + if (defined(this._pickId)) { + this._pickId.object.primitive = value; + } + } + }, /** - * Gets or sets the {@link Cartesian3} Property specifying the label's offset in eye coordinates. - * Eye coordinates is a left-handed coordinate system, where <code>x</code> points towards the viewer's - * right, <code>y</code> points up, and <code>z</code> points into the screen. * <p> - * An eye offset is commonly used to arrange multiple labels or objects at the same position, e.g., to - * arrange a label above its corresponding 3D model. + * Gets or sets the image to be used for this billboard. If a texture has already been created for the + * given image, the existing texture is used. * </p> - * Below, the label is positioned at the center of the Earth but an eye offset makes it always - * appear on top of the Earth regardless of the viewer's or Earth's orientation. * <p> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> - * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> - * </tr></table> - * <code>l.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code><br /><br /> - * </div> + * This property can be set to a loaded Image, a URL which will be loaded as an Image automatically, + * a canvas, or another billboard's image property (from the same billboard collection). * </p> - * @memberof LabelGraphics.prototype - * @type {Property} - * @default Cartesian3.ZERO + * + * @memberof Billboard.prototype + * @type {String} + * @example + * // load an image from a URL + * b.image = 'some/image/url.png'; + * + * // assuming b1 and b2 are billboards in the same billboard collection, + * // use the same image for both billboards. + * b2.image = b1.image; */ - eyeOffset : createPropertyDescriptor('eyeOffset'), + image : { + get : function() { + return this._imageId; + }, + set : function(value) { + if (!defined(value)) { + this._imageIndex = -1; + this._imageSubRegion = undefined; + this._imageId = undefined; + this._image = undefined; + this._imageIndexPromise = undefined; + makeDirty(this, IMAGE_INDEX_INDEX); + } else if (typeof value === 'string') { + this.setImage(value, value); + } else if (value instanceof Resource) { + this.setImage(value.url, value); + } else if (defined(value.src)) { + this.setImage(value.src, value); + } else { + this.setImage(createGuid(), value); + } + } + }, /** - * Gets or sets the Property specifying the {@link HeightReference}. - * @memberof LabelGraphics.prototype - * @type {Property} - * @default HeightReference.NONE + * When <code>true</code>, this billboard is ready to render, i.e., the image + * has been downloaded and the WebGL resources are created. + * + * @memberof Billboard.prototype + * + * @type {Boolean} + * @readonly + * + * @default false */ - heightReference : createPropertyDescriptor('heightReference'), + ready : { + get : function() { + return this._imageIndex !== -1; + } + }, /** - * Gets or sets the {@link Cartesian2} Property specifying the label's pixel offset in screen space - * from the origin of this label. This is commonly used to align multiple labels and labels at - * the same position, e.g., an image and text. The screen space origin is the top, left corner of the - * canvas; <code>x</code> increases from left to right, and <code>y</code> increases from top to bottom. - * <p> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><code>default</code><br/><img src='Images/Label.setPixelOffset.default.png' width='250' height='188' /></td> - * <td align='center'><code>l.pixeloffset = new Cartesian2(25, 75);</code><br/><img src='Images/Label.setPixelOffset.x50y-25.png' width='250' height='188' /></td> - * </tr></table> - * The label's origin is indicated by the yellow point. - * </div> - * </p> - * @memberof LabelGraphics.prototype - * @type {Property} - * @default Cartesian2.ZERO + * Keeps track of the position of the billboard based on the height reference. + * @memberof Billboard.prototype + * @type {Cartesian3} + * @private */ - pixelOffset : createPropertyDescriptor('pixelOffset'), + _clampedPosition : { + get : function() { + return this._actualClampedPosition; + }, + set : function(value) { + this._actualClampedPosition = Cartesian3.clone(value, this._actualClampedPosition); + makeDirty(this, POSITION_INDEX); + } + }, /** - * Gets or sets the numeric Property specifying the uniform scale to apply to the image. - * A scale greater than <code>1.0</code> enlarges the label while a scale less than <code>1.0</code> shrinks it. - * <p> - * <div align='center'> - * <img src='Images/Label.setScale.png' width='400' height='300' /><br/> - * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, - * and <code>2.0</code>. - * </div> - * </p> - * @memberof LabelGraphics.prototype - * @type {Property} - * @default 1.0 + * Determines whether or not this billboard will be shown or hidden because it was clustered. + * @memberof Billboard.prototype + * @type {Boolean} + * @private */ - scale : createPropertyDescriptor('scale'), + clusterShow : { + get : function() { + return this._clusterShow; + }, + set : function(value) { + if (this._clusterShow !== value) { + this._clusterShow = value; + makeDirty(this, SHOW_INDEX); + } + } + } + }); - /** - * Gets or sets the boolean Property specifying the visibility of the label. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - show : createPropertyDescriptor('show'), + Billboard.prototype.getPickId = function(context) { + if (!defined(this._pickId)) { + this._pickId = context.createPickId({ + primitive : this._pickPrimitive, + collection : this._collection, + id : this._id + }); + } - /** - * Gets or sets the boolean Property specifying the visibility of the background behind the label. - * @memberof LabelGraphics.prototype - * @type {Property} - * @default false - */ - showBackground : createPropertyDescriptor('showBackground'), + return this._pickId; + }; - /** - * Gets or sets the Property specifying the background {@link Color}. - * @memberof LabelGraphics.prototype - * @type {Property} - * @default new Color(0.165, 0.165, 0.165, 0.8) - */ - backgroundColor : createPropertyDescriptor('backgroundColor'), + Billboard.prototype._updateClamping = function() { + Billboard._updateClamping(this._billboardCollection, this); + }; - /** - * Gets or sets the {@link Cartesian2} Property specifying the label's horizontal and vertical - * background padding in pixels. - * @memberof LabelGraphics.prototype - * @type {Property} - * @default new Cartesian2(7, 5) - */ - backgroundPadding : createPropertyDescriptor('backgroundPadding'), + var scratchCartographic = new Cartographic(); + var scratchPosition = new Cartesian3(); - /** - * Gets or sets {@link NearFarScalar} Property specifying the translucency of the label based on the distance from the camera. - * A label's translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the label's translucency remains clamped to the nearest bound. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - translucencyByDistance : createPropertyDescriptor('translucencyByDistance'), + Billboard._updateClamping = function(collection, owner) { + var scene = collection._scene; + if (!defined(scene) || !defined(scene.globe)) { + if (owner._heightReference !== HeightReference.NONE) { + throw new DeveloperError('Height reference is not supported without a scene and globe.'); + } + return; + } - /** - * Gets or sets {@link NearFarScalar} Property specifying the pixel offset of the label based on the distance from the camera. - * A label's pixel offset will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the label's pixel offset remains clamped to the nearest bound. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - pixelOffsetScaleByDistance : createPropertyDescriptor('pixelOffsetScaleByDistance'), + var globe = scene.globe; + var ellipsoid = globe.ellipsoid; + var surface = globe._surface; - /** - * Gets or sets near and far scaling properties of a Label based on the label's distance from the camera. - * A label's scale will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the label's scale remains clamped to the nearest bound. If undefined, - * scaleByDistance will be disabled. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - scaleByDistance : createPropertyDescriptor('scaleByDistance'), + var mode = scene.frameState.mode; - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this label will be displayed. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + var modeChanged = mode !== owner._mode; + owner._mode = mode; - /** - * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. - * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. - * @memberof LabelGraphics.prototype - * @type {Property} - */ - disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') - }); + if ((owner._heightReference === HeightReference.NONE || modeChanged) && defined(owner._removeCallbackFunc)) { + owner._removeCallbackFunc(); + owner._removeCallbackFunc = undefined; + owner._clampedPosition = undefined; + } + + if (owner._heightReference === HeightReference.NONE || !defined(owner._position)) { + return; + } + + var position = ellipsoid.cartesianToCartographic(owner._position); + if (!defined(position)) { + owner._actualClampedPosition = undefined; + return; + } + + if (defined(owner._removeCallbackFunc)) { + owner._removeCallbackFunc(); + } + + function updateFunction(clampedPosition) { + if (owner._heightReference === HeightReference.RELATIVE_TO_GROUND) { + if (owner._mode === SceneMode.SCENE3D) { + var clampedCart = ellipsoid.cartesianToCartographic(clampedPosition, scratchCartographic); + clampedCart.height += position.height; + ellipsoid.cartographicToCartesian(clampedCart, clampedPosition); + } else { + clampedPosition.x += position.height; + } + } + owner._clampedPosition = Cartesian3.clone(clampedPosition, owner._clampedPosition); + } + owner._removeCallbackFunc = surface.updateHeight(position, updateFunction); + + Cartographic.clone(position, scratchCartographic); + var height = globe.getHeight(position); + if (defined(height)) { + scratchCartographic.height = height; + } + + ellipsoid.cartographicToCartesian(scratchCartographic, scratchPosition); + + updateFunction(scratchPosition); + }; + + Billboard.prototype._loadImage = function() { + var atlas = this._billboardCollection._textureAtlas; + + var imageId = this._imageId; + var image = this._image; + var imageSubRegion = this._imageSubRegion; + var imageIndexPromise; + + if (defined(image)) { + imageIndexPromise = atlas.addImage(imageId, image); + } + if (defined(imageSubRegion)) { + imageIndexPromise = atlas.addSubRegion(imageId, imageSubRegion); + } + + this._imageIndexPromise = imageIndexPromise; + + if (!defined(imageIndexPromise)) { + return; + } + + var that = this; + imageIndexPromise.then(function(index) { + if (that._imageId !== imageId || that._image !== image || !BoundingRectangle.equals(that._imageSubRegion, imageSubRegion)) { + // another load occurred before this one finished, ignore the index + return; + } + + // fill in imageWidth and imageHeight + var textureCoordinates = atlas.textureCoordinates[index]; + that._imageWidth = atlas.texture.width * textureCoordinates.width; + that._imageHeight = atlas.texture.height * textureCoordinates.height; + + that._imageIndex = index; + that._ready = true; + that._image = undefined; + that._imageIndexPromise = undefined; + makeDirty(that, IMAGE_INDEX_INDEX); + }).otherwise(function(error) { + console.error('Error loading image for billboard: ' + error); + that._imageIndexPromise = undefined; + }); + }; /** - * Duplicates this instance. + * <p> + * Sets the image to be used for this billboard. If a texture has already been created for the + * given id, the existing texture is used. + * </p> + * <p> + * This function is useful for dynamically creating textures that are shared across many billboards. + * Only the first billboard will actually call the function and create the texture, while subsequent + * billboards created with the same id will simply re-use the existing texture. + * </p> + * <p> + * To load an image from a URL, setting the {@link Billboard#image} property is more convenient. + * </p> * - * @param {LabelGraphics} [result] The object onto which to store the result. - * @returns {LabelGraphics} The modified result parameter or a new instance if one was not provided. + * @param {String} id The id of the image. This can be any string that uniquely identifies the image. + * @param {Image|Canvas|String|Resource|Billboard~CreateImageCallback} image The image to load. This parameter + * can either be a loaded Image or Canvas, a URL which will be loaded as an Image automatically, + * or a function which will be called to create the image if it hasn't been loaded already. + * @example + * // create a billboard image dynamically + * function drawImage(id) { + * // create and draw an image using a canvas + * var canvas = document.createElement('canvas'); + * var context2D = canvas.getContext('2d'); + * // ... draw image + * return canvas; + * } + * // drawImage will be called to create the texture + * b.setImage('myImage', drawImage); + * + * // subsequent billboards created in the same collection using the same id will use the existing + * // texture, without the need to create the canvas or draw the image + * b2.setImage('myImage', drawImage); */ - LabelGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new LabelGraphics(this); + Billboard.prototype.setImage = function(id, image) { + if (!defined(id)) { + throw new DeveloperError('id is required.'); + } + if (!defined(image)) { + throw new DeveloperError('image is required.'); + } + + if (this._imageId === id) { + return; + } + + this._imageIndex = -1; + this._imageSubRegion = undefined; + this._imageId = id; + this._image = image; + + if (defined(this._billboardCollection._textureAtlas)) { + this._loadImage(); } - result.text = this.text; - result.font = this.font; - result.show = this.show; - result.style = this.style; - result.fillColor = this.fillColor; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.showBackground = this.showBackground; - result.backgroundColor = this.backgroundColor; - result.backgroundPadding = this.backgroundPadding; - result.scale = this.scale; - result.horizontalOrigin = this.horizontalOrigin; - result.verticalOrigin = this.verticalOrigin; - result.eyeOffset = this.eyeOffset; - result.heightReference = this.heightReference; - result.pixelOffset = this.pixelOffset; - result.translucencyByDistance = this.translucencyByDistance; - result.pixelOffsetScaleByDistance = this.pixelOffsetScaleByDistance; - result.scaleByDistance = this.scaleByDistance; - result.distanceDisplayCondition = this.distanceDisplayCondition; - result.disableDepthTestDistance = this.disableDepthTestDistance; - return result; }; /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. + * Uses a sub-region of the image with the given id as the image for this billboard, + * measured in pixels from the bottom-left. * - * @param {LabelGraphics} source The object to be merged into this object. + * @param {String} id The id of the image to use. + * @param {BoundingRectangle} subRegion The sub-region of the image. + * + * @exception {RuntimeError} image with id must be in the atlas */ - LabelGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + Billboard.prototype.setImageSubRegion = function(id, subRegion) { + if (!defined(id)) { + throw new DeveloperError('id is required.'); + } + if (!defined(subRegion)) { + throw new DeveloperError('subRegion is required.'); } - this.text = defaultValue(this.text, source.text); - this.font = defaultValue(this.font, source.font); - this.show = defaultValue(this.show, source.show); - this.style = defaultValue(this.style, source.style); - this.fillColor = defaultValue(this.fillColor, source.fillColor); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.showBackground = defaultValue(this.showBackground, source.showBackground); - this.backgroundColor = defaultValue(this.backgroundColor, source.backgroundColor); - this.backgroundPadding = defaultValue(this.backgroundPadding, source.backgroundPadding); - this.scale = defaultValue(this.scale, source.scale); - this.horizontalOrigin = defaultValue(this.horizontalOrigin, source.horizontalOrigin); - this.verticalOrigin = defaultValue(this.verticalOrigin, source.verticalOrigin); - this.eyeOffset = defaultValue(this.eyeOffset, source.eyeOffset); - this.heightReference = defaultValue(this.heightReference, source.heightReference); - this.pixelOffset = defaultValue(this.pixelOffset, source.pixelOffset); - this.translucencyByDistance = defaultValue(this.translucencyByDistance, source.translucencyByDistance); - this.pixelOffsetScaleByDistance = defaultValue(this.pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); - this.scaleByDistance = defaultValue(this.scaleByDistance, source.scaleByDistance); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - this.disableDepthTestDistance = defaultValue(this.disableDepthTestDistance, source.disableDepthTestDistance); + if (this._imageId === id && BoundingRectangle.equals(this._imageSubRegion, subRegion)) { + return; + } + + this._imageIndex = -1; + this._imageId = id; + this._imageSubRegion = BoundingRectangle.clone(subRegion); + + if (defined(this._billboardCollection._textureAtlas)) { + this._loadImage(); + } }; - return LabelGraphics; -}); + Billboard.prototype._setTranslate = function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var translate = this._translate; + if (!Cartesian2.equals(translate, value)) { + Cartesian2.clone(value, translate); + makeDirty(this, PIXEL_OFFSET_INDEX); + } + }; -define('DataSources/NodeTransformationProperty',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - '../Core/TranslationRotationScale', - './createPropertyDescriptor', - './Property' - ], function( - defaultValue, - defined, - defineProperties, - Event, - TranslationRotationScale, - createPropertyDescriptor, - Property) { - 'use strict'; + Billboard.prototype._getActualPosition = function() { + return defined(this._clampedPosition) ? this._clampedPosition : this._actualPosition; + }; - var defaultNodeTransformation = new TranslationRotationScale(); + Billboard.prototype._setActualPosition = function(value) { + if (!(defined(this._clampedPosition))) { + Cartesian3.clone(value, this._actualPosition); + } + makeDirty(this, POSITION_INDEX); + }; - /** - * A {@link Property} that produces {@link TranslationRotationScale} data. - * @alias NodeTransformationProperty - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.translation=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node. - * @param {Property} [options.rotation=Quaternion.IDENTITY] A {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node. - * @param {Property} [options.scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node. - */ - var NodeTransformationProperty = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var tempCartesian3 = new Cartesian4(); + Billboard._computeActualPosition = function(billboard, position, frameState, modelMatrix) { + if (defined(billboard._clampedPosition)) { + if (frameState.mode !== billboard._mode) { + billboard._updateClamping(); + } + return billboard._clampedPosition; + } else if (frameState.mode === SceneMode.SCENE3D) { + return position; + } - this._definitionChanged = new Event(); - this._translation = undefined; - this._translationSubscription = undefined; - this._rotation = undefined; - this._rotationSubscription = undefined; - this._scale = undefined; - this._scaleSubscription = undefined; + Matrix4.multiplyByPoint(modelMatrix, position, tempCartesian3); + return SceneTransforms.computeActualWgs84Position(frameState, tempCartesian3); + }; - this.translation = options.translation; - this.rotation = options.rotation; - this.scale = options.scale; + var scratchCartesian3 = new Cartesian3(); + + // This function is basically a stripped-down JavaScript version of BillboardCollectionVS.glsl + Billboard._computeScreenSpacePosition = function(modelMatrix, position, eyeOffset, pixelOffset, scene, result) { + // Model to world coordinates + var positionWorld = Matrix4.multiplyByPoint(modelMatrix, position, scratchCartesian3); + + // World to window coordinates + var positionWC = SceneTransforms.wgs84WithEyeOffsetToWindowCoordinates(scene, positionWorld, eyeOffset, result); + if (!defined(positionWC)) { + return undefined; + } + + // Apply pixel offset + Cartesian2.add(positionWC, pixelOffset, positionWC); + + return positionWC; }; - defineProperties(NodeTransformationProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof NodeTransformationProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._translation) && - Property.isConstant(this._rotation) && - Property.isConstant(this._scale); - } - }, + var scratchPixelOffset = new Cartesian2(0.0, 0.0); - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof NodeTransformationProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + /** + * Computes the screen-space position of the billboard's origin, taking into account eye and pixel offsets. + * The screen space origin is the top, left corner of the canvas; <code>x</code> increases from + * left to right, and <code>y</code> increases from top to bottom. + * + * @param {Scene} scene The scene. + * @param {Cartesian2} [result] The object onto which to store the result. + * @returns {Cartesian2} The screen-space position of the billboard. + * + * @exception {DeveloperError} Billboard must be in a collection. + * + * @example + * console.log(b.computeScreenSpacePosition(scene).toString()); + * + * @see Billboard#eyeOffset + * @see Billboard#pixelOffset + */ + Billboard.prototype.computeScreenSpacePosition = function(scene, result) { + var billboardCollection = this._billboardCollection; + if (!defined(result)) { + result = new Cartesian2(); + } - /** - * Gets or sets the {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node. - * @memberof NodeTransformationProperty.prototype - * @type {Property} - * @default Cartesian3.ZERO - */ - translation : createPropertyDescriptor('translation'), + if (!defined(billboardCollection)) { + throw new DeveloperError('Billboard must be in a collection. Was it removed?'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + + // pixel offset for screen space computation is the pixelOffset + screen space translate + Cartesian2.clone(this._pixelOffset, scratchPixelOffset); + Cartesian2.add(scratchPixelOffset, this._translate, scratchPixelOffset); - /** - * Gets or sets the {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node. - * @memberof NodeTransformationProperty.prototype - * @type {Property} - * @default Quaternion.IDENTITY - */ - rotation : createPropertyDescriptor('rotation'), + var modelMatrix = billboardCollection.modelMatrix; + var position = this._position; + if (defined(this._clampedPosition)) { + position = this._clampedPosition; + if (scene.mode !== SceneMode.SCENE3D) { + // position needs to be in world coordinates + var projection = scene.mapProjection; + var ellipsoid = projection.ellipsoid; + var cart = projection.unproject(position, scratchCartographic); + position = ellipsoid.cartographicToCartesian(cart, scratchCartesian3); + modelMatrix = Matrix4.IDENTITY; + } + } - /** - * Gets or sets the {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node. - * @memberof NodeTransformationProperty.prototype - * @type {Property} - * @default new Cartesian3(1.0, 1.0, 1.0) - */ - scale : createPropertyDescriptor('scale') - }); + var windowCoordinates = Billboard._computeScreenSpacePosition(modelMatrix, position, + this._eyeOffset, scratchPixelOffset, scene, result); + return windowCoordinates; + }; /** - * Gets the value of the property at the provided time. + * Gets a billboard's screen space bounding box centered around screenSpacePosition. + * @param {Billboard} billboard The billboard to get the screen space bounding box for. + * @param {Cartesian2} screenSpacePosition The screen space center of the label. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The screen space bounding box. * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {TranslationRotationScale} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {TranslationRotationScale} The modified result parameter or a new instance if the result parameter was not supplied. + * @private */ - NodeTransformationProperty.prototype.getValue = function(time, result) { + Billboard.getScreenSpaceBoundingBox = function(billboard, screenSpacePosition, result) { + var width = billboard.width; + var height = billboard.height; + + var scale = billboard.scale; + width *= scale; + height *= scale; + + var x = screenSpacePosition.x; + if (billboard.horizontalOrigin === HorizontalOrigin.RIGHT) { + x -= width; + } else if (billboard.horizontalOrigin === HorizontalOrigin.CENTER) { + x -= width * 0.5; + } + + var y = screenSpacePosition.y; + if (billboard.verticalOrigin === VerticalOrigin.BOTTOM || billboard.verticalOrigin === VerticalOrigin.BASELINE) { + y -= height; + } else if (billboard.verticalOrigin === VerticalOrigin.CENTER) { + y -= height * 0.5; + } + if (!defined(result)) { - result = new TranslationRotationScale(); + result = new BoundingRectangle(); } - result.translation = Property.getValueOrClonedDefault(this._translation, time, defaultNodeTransformation.translation, result.translation); - result.rotation = Property.getValueOrClonedDefault(this._rotation, time, defaultNodeTransformation.rotation, result.rotation); - result.scale = Property.getValueOrClonedDefault(this._scale, time, defaultNodeTransformation.scale, result.scale); + result.x = x; + result.y = y; + result.width = width; + result.height = height; + return result; }; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Determines if this billboard equals another billboard. Billboards are equal if all their properties + * are equal. Billboards in different collections can be equal. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @param {Billboard} other The billboard to compare for equality. + * @returns {Boolean} <code>true</code> if the billboards are equal; otherwise, <code>false</code>. */ - NodeTransformationProperty.prototype.equals = function(other) { + Billboard.prototype.equals = function(other) { return this === other || - (other instanceof NodeTransformationProperty && - Property.equals(this._translation, other._translation) && - Property.equals(this._rotation, other._rotation) && - Property.equals(this._scale, other._scale)); + defined(other) && + this._id === other._id && + Cartesian3.equals(this._position, other._position) && + this._imageId === other._imageId && + this._show === other._show && + this._scale === other._scale && + this._verticalOrigin === other._verticalOrigin && + this._horizontalOrigin === other._horizontalOrigin && + this._heightReference === other._heightReference && + BoundingRectangle.equals(this._imageSubRegion, other._imageSubRegion) && + Color.equals(this._color, other._color) && + Cartesian2.equals(this._pixelOffset, other._pixelOffset) && + Cartesian2.equals(this._translate, other._translate) && + Cartesian3.equals(this._eyeOffset, other._eyeOffset) && + NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && + NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && + NearFarScalar.equals(this._pixelOffsetScaleByDistance, other._pixelOffsetScaleByDistance) && + DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && + this._disableDepthTestDistance === other._disableDepthTestDistance; }; - return NodeTransformationProperty; + Billboard.prototype._destroy = function() { + if (defined(this._customData)) { + this._billboardCollection._scene.globe._surface.removeTileCustomData(this._customData); + this._customData = undefined; + } + + if (defined(this._removeCallbackFunc)) { + this._removeCallbackFunc(); + this._removeCallbackFunc = undefined; + } + + this.image = undefined; + this._pickId = this._pickId && this._pickId.destroy(); + this._billboardCollection = undefined; + }; + + /** + * A function that creates an image. + * @callback Billboard~CreateImageCallback + * @param {String} id The identifier of the image to load. + * @returns {Image|Canvas|Promise<Image|Canvas>} The image, or a promise that will resolve to an image. + */ + + return Billboard; }); -define('DataSources/PropertyBag',[ +define('Renderer/VertexArrayFacade',[ + '../Core/Check', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Event', - './ConstantProperty', - './createPropertyDescriptor', - './Property' + '../Core/Math', + './Buffer', + './BufferUsage', + './VertexArray' ], function( + Check, + ComponentDatatype, defaultValue, defined, - defineProperties, + destroyObject, DeveloperError, - Event, - ConstantProperty, - createPropertyDescriptor, - Property) { + CesiumMath, + Buffer, + BufferUsage, + VertexArray) { 'use strict'; /** - * A {@link Property} whose value is a key-value mapping of property names to the computed value of other properties. - * - * @alias PropertyBag - * @constructor - * - * @param {Object} [value] An object, containing key-value mapping of property names to properties. - * @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. + * @private */ - var PropertyBag = function(value, createPropertyCallback) { - this._propertyNames = []; - this._definitionChanged = new Event(); - - if (defined(value)) { - this.merge(value, createPropertyCallback); + function VertexArrayFacade(context, attributes, sizeInVertices, instanced) { + Check.defined('context', context); + if (!attributes || (attributes.length === 0)) { + throw new DeveloperError('At least one attribute is required.'); } - }; + + var attrs = VertexArrayFacade._verifyAttributes(attributes); + sizeInVertices = defaultValue(sizeInVertices, 0); + var precreatedAttributes = []; + var attributesByUsage = {}; + var attributesForUsage; + var usage; - defineProperties(PropertyBag.prototype, { - /** - * Gets the names of all properties registered on this instance. - * @memberof PropertyBag.prototype - * @type {Array} - */ - propertyNames : { - get : function() { - return this._propertyNames; - } - }, - /** - * Gets a value indicating if this property is constant. This property - * is considered constant if all property items in this object are constant. - * @memberof PropertyBag.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - var propertyNames = this._propertyNames; - for (var i = 0, len = propertyNames.length; i < len; i++) { - if (!Property.isConstant(this[propertyNames[i]])) { - return false; - } - } - return true; + // Bucket the attributes by usage. + var length = attrs.length; + for (var i = 0; i < length; ++i) { + var attribute = attrs[i]; + + // If the attribute already has a vertex buffer, we do not need + // to manage a vertex buffer or typed array for it. + if (attribute.vertexBuffer) { + precreatedAttributes.push(attribute); + continue; } - }, - /** - * Gets the event that is raised whenever the set of properties contained in this - * object changes, or one of the properties itself changes. - * - * @memberof PropertyBag.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + + usage = attribute.usage; + attributesForUsage = attributesByUsage[usage]; + if (!defined(attributesForUsage)) { + attributesForUsage = attributesByUsage[usage] = []; } + + attributesForUsage.push(attribute); } - }); - /** - * Determines if this object has defined a property with the given name. - * - * @param {String} propertyName The name of the property to check for. - * - * @returns {Boolean} True if this object has defined a property with the given name, false otherwise. - */ - PropertyBag.prototype.hasProperty = function(propertyName) { - return this._propertyNames.indexOf(propertyName) !== -1; - }; + // A function to sort attributes by the size of their components. From left to right, a vertex + // stores floats, shorts, and then bytes. + function compare(left, right) { + return ComponentDatatype.getSizeInBytes(right.componentDatatype) - ComponentDatatype.getSizeInBytes(left.componentDatatype); + } - function createConstantProperty(value) { - return new ConstantProperty(value); - } + this._allBuffers = []; - /** - * Adds a property to this object. - * - * @param {String} propertyName The name of the property to add. - * @param {*} [value] The value of the new property, if provided. - * @param {Function} [createPropertyCallback] A function that will be called when the value of this new property is set to a value that is not a Property. - * - * @exception {DeveloperError} "propertyName" is already a registered property. - */ - PropertyBag.prototype.addProperty = function(propertyName, value, createPropertyCallback) { - var propertyNames = this._propertyNames; + for (usage in attributesByUsage) { + if (attributesByUsage.hasOwnProperty(usage)) { + attributesForUsage = attributesByUsage[usage]; - if (!defined(propertyName)) { - throw new DeveloperError('propertyName is required.'); - } - if (propertyNames.indexOf(propertyName) !== -1) { - throw new DeveloperError(propertyName + ' is already a registered property.'); - } - - propertyNames.push(propertyName); - Object.defineProperty(this, propertyName, createPropertyDescriptor(propertyName, true, defaultValue(createPropertyCallback, createConstantProperty))); + attributesForUsage.sort(compare); + var vertexSizeInBytes = VertexArrayFacade._vertexSizeInBytes(attributesForUsage); + + var bufferUsage = attributesForUsage[0].usage; + + var buffer = { + vertexSizeInBytes : vertexSizeInBytes, + vertexBuffer : undefined, + usage : bufferUsage, + needsCommit : false, + arrayBuffer : undefined, + arrayViews : VertexArrayFacade._createArrayViews(attributesForUsage, vertexSizeInBytes) + }; - if (defined(value)) { - this[propertyName] = value; + this._allBuffers.push(buffer); + } } - this._definitionChanged.raiseEvent(this); - }; + this._size = 0; + this._instanced = defaultValue(instanced, false); - /** - * Removed a property previously added with addProperty. - * - * @param {String} propertyName The name of the property to remove. - * - * @exception {DeveloperError} "propertyName" is not a registered property. - */ - PropertyBag.prototype.removeProperty = function(propertyName) { - var propertyNames = this._propertyNames; - var index = propertyNames.indexOf(propertyName); + this._precreated = precreatedAttributes; + this._context = context; - if (!defined(propertyName)) { - throw new DeveloperError('propertyName is required.'); - } - if (index === -1) { - throw new DeveloperError(propertyName + ' is not a registered property.'); - } - - this._propertyNames.splice(index, 1); - delete this[propertyName]; + this.writers = undefined; + this.va = undefined; - this._definitionChanged.raiseEvent(this); - }; + this.resize(sizeInVertices); + } + VertexArrayFacade._verifyAttributes = function(attributes) { + var attrs = []; - /** - * Gets the value of this property. Each contained property will be evaluated at the given time, and the overall - * result will be an object, mapping property names to those values. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * Note that any properties in result which are not part of this PropertyBag will be left as-is. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - PropertyBag.prototype.getValue = function(time, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - if (!defined(result)) { - result = {}; - } + for ( var i = 0; i < attributes.length; ++i) { + var attribute = attributes[i]; - var propertyNames = this._propertyNames; - for (var i = 0, len = propertyNames.length; i < len; i++) { - var propertyName = propertyNames[i]; - result[propertyName] = Property.getValueOrUndefined(this[propertyName], time, result[propertyName]); - } - return result; - }; + var attr = { + index : defaultValue(attribute.index, i), + enabled : defaultValue(attribute.enabled, true), + componentsPerAttribute : attribute.componentsPerAttribute, + componentDatatype : defaultValue(attribute.componentDatatype, ComponentDatatype.FLOAT), + normalize : defaultValue(attribute.normalize, false), - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {Object} source The object to be merged into this object. - * @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. - */ - PropertyBag.prototype.merge = function(source, createPropertyCallback) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); - } - - var propertyNames = this._propertyNames; - var sourcePropertyNames = defined(source._propertyNames) ? source._propertyNames : Object.keys(source); - for (var i = 0, len = sourcePropertyNames.length; i < len; i++) { - var name = sourcePropertyNames[i]; + // There will be either a vertexBuffer or an [optional] usage. + vertexBuffer : attribute.vertexBuffer, + usage : defaultValue(attribute.usage, BufferUsage.STATIC_DRAW) + }; + attrs.push(attr); - var targetProperty = this[name]; - var sourceProperty = source[name]; + if ((attr.componentsPerAttribute !== 1) && (attr.componentsPerAttribute !== 2) && (attr.componentsPerAttribute !== 3) && (attr.componentsPerAttribute !== 4)) { + throw new DeveloperError('attribute.componentsPerAttribute must be in the range [1, 4].'); + } - //Custom properties that are registered on the source must also be added to this. - if (targetProperty === undefined && propertyNames.indexOf(name) === -1) { - this.addProperty(name, undefined, createPropertyCallback); + var datatype = attr.componentDatatype; + if (!ComponentDatatype.validate(datatype)) { + throw new DeveloperError('Attribute must have a valid componentDatatype or not specify it.'); } - if (sourceProperty !== undefined) { - if (targetProperty !== undefined) { - if (defined(targetProperty) && defined(targetProperty.merge)) { - targetProperty.merge(sourceProperty); + if (!BufferUsage.validate(attr.usage)) { + throw new DeveloperError('Attribute must have a valid usage or not specify it.'); + } } - } else if (defined(sourceProperty) && defined(sourceProperty.merge) && defined(sourceProperty.clone)) { - this[name] = sourceProperty.clone(); - } else { - this[name] = sourceProperty; - } + + // Verify all attribute names are unique. + var uniqueIndices = new Array(attrs.length); + for ( var j = 0; j < attrs.length; ++j) { + var currentAttr = attrs[j]; + var index = currentAttr.index; + if (uniqueIndices[index]) { + throw new DeveloperError('Index ' + index + ' is used by more than one attribute.'); } + uniqueIndices[index] = true; } + + return attrs; }; - function propertiesEqual(a, b) { - var aPropertyNames = a._propertyNames; - var bPropertyNames = b._propertyNames; + VertexArrayFacade._vertexSizeInBytes = function(attributes) { + var sizeInBytes = 0; - var len = aPropertyNames.length; - if (len !== bPropertyNames.length) { - return false; + var length = attributes.length; + for ( var i = 0; i < length; ++i) { + var attribute = attributes[i]; + sizeInBytes += (attribute.componentsPerAttribute * ComponentDatatype.getSizeInBytes(attribute.componentDatatype)); } - for (var aIndex = 0; aIndex < len; ++aIndex) { - var name = aPropertyNames[aIndex]; - var bIndex = bPropertyNames.indexOf(name); - if (bIndex === -1) { - return false; - } - if (!Property.equals(a[name], b[name])) { - return false; - } - } - return true; - } + var maxComponentSizeInBytes = (length > 0) ? ComponentDatatype.getSizeInBytes(attributes[0].componentDatatype) : 0; // Sorted by size + var remainder = (maxComponentSizeInBytes > 0) ? (sizeInBytes % maxComponentSizeInBytes) : 0; + var padding = (remainder === 0) ? 0 : (maxComponentSizeInBytes - remainder); + sizeInBytes += padding; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - PropertyBag.prototype.equals = function(other) { - return this === other || // - (other instanceof PropertyBag && // - propertiesEqual(this, other)); + return sizeInBytes; }; - return PropertyBag; -}); + VertexArrayFacade._createArrayViews = function(attributes, vertexSizeInBytes) { + var views = []; + var offsetInBytes = 0; -define('DataSources/ModelGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createPropertyDescriptor', - './NodeTransformationProperty', - './PropertyBag' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createPropertyDescriptor, - NodeTransformationProperty, - PropertyBag) { - 'use strict'; + var length = attributes.length; + for ( var i = 0; i < length; ++i) { + var attribute = attributes[i]; + var componentDatatype = attribute.componentDatatype; - function createNodeTransformationProperty(value) { - return new NodeTransformationProperty(value); - } + views.push({ + index : attribute.index, + enabled : attribute.enabled, + componentsPerAttribute : attribute.componentsPerAttribute, + componentDatatype : componentDatatype, + normalize : attribute.normalize, - function createNodeTransformationPropertyBag(value) { - return new PropertyBag(value, createNodeTransformationProperty); - } + offsetInBytes : offsetInBytes, + vertexSizeInComponentType : vertexSizeInBytes / ComponentDatatype.getSizeInBytes(componentDatatype), + + view : undefined + }); + + offsetInBytes += (attribute.componentsPerAttribute * ComponentDatatype.getSizeInBytes(componentDatatype)); + } + + return views; + }; /** - * A 3D model based on {@link https://github.com/KhronosGroup/glTF|glTF}, the runtime asset format for WebGL, OpenGL ES, and OpenGL. - * The position and orientation of the model is determined by the containing {@link Entity}. - * <p> - * Cesium includes support for glTF geometry, materials, animations, and skinning. - * Cameras and lights are not currently supported. - * </p> - * - * @alias ModelGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.uri] A string Property specifying the URI of the glTF asset. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the model. - * @param {Property} [options.scale=1.0] A numeric Property specifying a uniform linear scale. - * @param {Property} [options.minimumPixelSize=0.0] A numeric Property specifying the approximate minimum pixel size of the model regardless of zoom. - * @param {Property} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. - * @param {Property} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. - * @param {Property} [options.runAnimations=true] A boolean Property specifying if glTF animations specified in the model should be started. - * @param {Property} [options.clampAnimations=true] A boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes. - * @param {Property} [options.nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. - * @param {Property} [options.shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from each light source. - * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed. - * @param {Property} [options.silhouetteColor=Color.RED] A Property specifying the {@link Color} of the silhouette. - * @param {Property} [options.silhouetteSize=0.0] A numeric Property specifying the size of the silhouette in pixels. - * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} that blends with the model's rendered color. - * @param {Property} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model. - * @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. - * @param {Property} [options.clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. - * - * @see {@link http://cesiumjs.org/2014/03/03/Cesium-3D-Models-Tutorial/|3D Models Tutorial} - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle 3D Models Demo} + * Invalidates writers. Can't render again until commit is called. */ - function ModelGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._scale = undefined; - this._scaleSubscription = undefined; - this._minimumPixelSize = undefined; - this._minimumPixelSizeSubscription = undefined; - this._maximumScale = undefined; - this._maximumScaleSubscription = undefined; - this._incrementallyLoadTextures = undefined; - this._incrementallyLoadTexturesSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._uri = undefined; - this._uriSubscription = undefined; - this._runAnimations = undefined; - this._clampAnimations = undefined; - this._runAnimationsSubscription = undefined; - this._nodeTransformations = undefined; - this._nodeTransformationsSubscription = undefined; - this._heightReference = undefined; - this._heightReferenceSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._silhouetteColor = undefined; - this._silhouetteColorSubscription = undefined; - this._silhouetteSize = undefined; - this._silhouetteSizeSubscription = undefined; - this._color = undefined; - this._colorSubscription = undefined; - this._colorBlendMode = undefined; - this._colorBlendModeSubscription = undefined; - this._colorBlendAmount = undefined; - this._colorBlendAmountSubscription = undefined; - this._clippingPlanes = undefined; - this._clippingPlanesSubscription = undefined; - this._definitionChanged = new Event(); + VertexArrayFacade.prototype.resize = function(sizeInVertices) { + this._size = sizeInVertices; - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + var allBuffers = this._allBuffers; + this.writers = []; - defineProperties(ModelGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof ModelGraphics.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + for (var i = 0, len = allBuffers.length; i < len; ++i) { + var buffer = allBuffers[i]; + + VertexArrayFacade._resize(buffer, this._size); + + // Reserving invalidates the writers, so if client's cache them, they need to invalidate their cache. + VertexArrayFacade._appendWriters(this.writers, buffer); + } + + // VAs are recreated next time commit is called. + destroyVA(this); + }; + + VertexArrayFacade._resize = function(buffer, size) { + if (buffer.vertexSizeInBytes > 0) { + // Create larger array buffer + var arrayBuffer = new ArrayBuffer(size * buffer.vertexSizeInBytes); + + // Copy contents from previous array buffer + if (defined(buffer.arrayBuffer)) { + var destView = new Uint8Array(arrayBuffer); + var sourceView = new Uint8Array(buffer.arrayBuffer); + var sourceLength = sourceView.length; + for ( var j = 0; j < sourceLength; ++j) { + destView[j] = sourceView[j]; + } } - }, - /** - * Gets or sets the boolean Property specifying the visibility of the model. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + // Create typed views into the new array buffer + var views = buffer.arrayViews; + var length = views.length; + for ( var i = 0; i < length; ++i) { + var view = views[i]; + view.view = ComponentDatatype.createArrayBufferView(view.componentDatatype, arrayBuffer, view.offsetInBytes); + } - /** - * Gets or sets the numeric Property specifying a uniform linear scale - * for this model. Values greater than 1.0 increase the size of the model while - * values less than 1.0 decrease it. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default 1.0 - */ - scale : createPropertyDescriptor('scale'), + buffer.arrayBuffer = arrayBuffer; + } + }; - /** - * Gets or sets the numeric Property specifying the approximate minimum - * pixel size of the model regardless of zoom. This can be used to ensure that - * a model is visible even when the viewer zooms out. When <code>0.0</code>, - * no minimum size is enforced. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default 0.0 - */ - minimumPixelSize : createPropertyDescriptor('minimumPixelSize'), + var createWriters = [ + // 1 component per attribute + function(buffer, view, vertexSizeInComponentType) { + return function(index, attribute) { + view[index * vertexSizeInComponentType] = attribute; + buffer.needsCommit = true; + }; + }, - /** - * Gets or sets the numeric Property specifying the maximum scale - * size of a model. This property is used as an upper limit for - * {@link ModelGraphics#minimumPixelSize}. - * @memberof ModelGraphics.prototype - * @type {Property} - */ - maximumScale : createPropertyDescriptor('maximumScale'), + // 2 component per attribute + function(buffer, view, vertexSizeInComponentType) { + return function(index, component0, component1) { + var i = index * vertexSizeInComponentType; + view[i] = component0; + view[i + 1] = component1; + buffer.needsCommit = true; + }; + }, - /** - * Get or sets the boolean Property specifying whether textures - * may continue to stream in after the model is loaded. - * @memberof ModelGraphics.prototype - * @type {Property} - */ - incrementallyLoadTextures : createPropertyDescriptor('incrementallyLoadTextures'), + // 3 component per attribute + function(buffer, view, vertexSizeInComponentType) { + return function(index, component0, component1, component2) { + var i = index * vertexSizeInComponentType; + view[i] = component0; + view[i + 1] = component1; + view[i + 2] = component2; + buffer.needsCommit = true; + }; + }, - /** - * Get or sets the enum Property specifying whether the model - * casts or receives shadows from each light source. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default ShadowMode.ENABLED - */ - shadows : createPropertyDescriptor('shadows'), + // 4 component per attribute + function(buffer, view, vertexSizeInComponentType) { + return function(index, component0, component1, component2, component3) { + var i = index * vertexSizeInComponentType; + view[i] = component0; + view[i + 1] = component1; + view[i + 2] = component2; + view[i + 3] = component3; + buffer.needsCommit = true; + }; + }]; - /** - * Gets or sets the string Property specifying the URI of the glTF asset. - * @memberof ModelGraphics.prototype - * @type {Property} - */ - uri : createPropertyDescriptor('uri'), + VertexArrayFacade._appendWriters = function(writers, buffer) { + var arrayViews = buffer.arrayViews; + var length = arrayViews.length; + for ( var i = 0; i < length; ++i) { + var arrayView = arrayViews[i]; + writers[arrayView.index] = createWriters[arrayView.componentsPerAttribute - 1](buffer, arrayView.view, arrayView.vertexSizeInComponentType); + } + }; - /** - * Gets or sets the boolean Property specifying if glTF animations should be run. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default true - */ - runAnimations : createPropertyDescriptor('runAnimations'), + VertexArrayFacade.prototype.commit = function(indexBuffer) { + var recreateVA = false; - /** - * Gets or sets the boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default true - */ - clampAnimations : createPropertyDescriptor('clampAnimations'), + var allBuffers = this._allBuffers; + var buffer; + var i; + var length; - /** - * Gets or sets the set of node transformations to apply to this model. This is represented as an {@link PropertyBag}, where keys are - * names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. - * @memberof ModelGraphics.prototype - * @type {PropertyBag} - */ - nodeTransformations : createPropertyDescriptor('nodeTransformations', undefined, createNodeTransformationPropertyBag), + for (i = 0, length = allBuffers.length; i < length; ++i) { + buffer = allBuffers[i]; + recreateVA = commit(this, buffer) || recreateVA; + } - /** - * Gets or sets the Property specifying the {@link HeightReference}. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default HeightReference.NONE - */ - heightReference : createPropertyDescriptor('heightReference'), + /////////////////////////////////////////////////////////////////////// - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this model will be displayed. - * @memberof ModelGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + if (recreateVA || !defined(this.va)) { + destroyVA(this); + var va = this.va = []; - /** - * Gets or sets the Property specifying the {@link Color} of the silhouette. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default Color.RED - */ - silhouetteColor: createPropertyDescriptor('silhouetteColor'), + var numberOfVertexArrays = defined(indexBuffer) ? Math.ceil(this._size / (CesiumMath.SIXTY_FOUR_KILOBYTES - 1)) : 1; + for ( var k = 0; k < numberOfVertexArrays; ++k) { + var attributes = []; + for (i = 0, length = allBuffers.length; i < length; ++i) { + buffer = allBuffers[i]; + var offset = k * (buffer.vertexSizeInBytes * (CesiumMath.SIXTY_FOUR_KILOBYTES - 1)); + VertexArrayFacade._appendAttributes(attributes, buffer, offset, this._instanced); + } - /** - * Gets or sets the numeric Property specifying the size of the silhouette in pixels. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default 0.0 - */ - silhouetteSize : createPropertyDescriptor('silhouetteSize'), + attributes = attributes.concat(this._precreated); - /** - * Gets or sets the Property specifying the {@link Color} that blends with the model's rendered color. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color'), + va.push({ + va : new VertexArray({ + context : this._context, + attributes : attributes, + indexBuffer : indexBuffer + }), + indicesCount : 1.5 * ((k !== (numberOfVertexArrays - 1)) ? (CesiumMath.SIXTY_FOUR_KILOBYTES - 1) : (this._size % (CesiumMath.SIXTY_FOUR_KILOBYTES - 1))) + // TODO: not hardcode 1.5, this assumes 6 indices per 4 vertices (as for Billboard quads). + }); + } + } + }; - /** - * Gets or sets the enum Property specifying how the color blends with the model. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default ColorBlendMode.HIGHLIGHT - */ - colorBlendMode : createPropertyDescriptor('colorBlendMode'), + function commit(vertexArrayFacade, buffer) { + if (buffer.needsCommit && (buffer.vertexSizeInBytes > 0)) { + buffer.needsCommit = false; - /** - * A numeric Property specifying the color strength when the <code>colorBlendMode</code> is MIX. - * A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with - * any value in-between resulting in a mix of the two. - * @memberof ModelGraphics.prototype - * @type {Property} - * @default 0.5 - */ - colorBlendAmount : createPropertyDescriptor('colorBlendAmount'), + var vertexBuffer = buffer.vertexBuffer; + var vertexBufferSizeInBytes = vertexArrayFacade._size * buffer.vertexSizeInBytes; + var vertexBufferDefined = defined(vertexBuffer); + if (!vertexBufferDefined || (vertexBuffer.sizeInBytes < vertexBufferSizeInBytes)) { + if (vertexBufferDefined) { + vertexBuffer.destroy(); + } + buffer.vertexBuffer = Buffer.createVertexBuffer({ + context : vertexArrayFacade._context, + typedArray : buffer.arrayBuffer, + usage : buffer.usage + }); + buffer.vertexBuffer.vertexArrayDestroyable = false; - /** - * A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. - * @memberof ModelGraphics.prototype - * @type {Property} - */ - clippingPlanes : createPropertyDescriptor('clippingPlanes') - }); + return true; // Created new vertex buffer + } - /** - * Duplicates this instance. - * - * @param {ModelGraphics} [result] The object onto which to store the result. - * @returns {ModelGraphics} The modified result parameter or a new instance if one was not provided. - */ - ModelGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new ModelGraphics(this); + buffer.vertexBuffer.copyFromArrayView(buffer.arrayBuffer); } - result.show = this.show; - result.scale = this.scale; - result.minimumPixelSize = this.minimumPixelSize; - result.maximumScale = this.maximumScale; - result.incrementallyLoadTextures = this.incrementallyLoadTextures; - result.shadows = this.shadows; - result.uri = this.uri; - result.runAnimations = this.runAnimations; - result.clampAnimations = this.clampAnimations; - result.nodeTransformations = this.nodeTransformations; - result.heightReference = this._heightReference; - result.distanceDisplayCondition = this.distanceDisplayCondition; - result.silhouetteColor = this.silhouetteColor; - result.silhouetteSize = this.silhouetteSize; - result.color = this.color; - result.colorBlendMode = this.colorBlendMode; - result.colorBlendAmount = this.colorBlendAmount; - result.clippingPlanes = this.clippingPlanes; - return result; + return false; // Did not create new vertex buffer + } + + VertexArrayFacade._appendAttributes = function(attributes, buffer, vertexBufferOffset, instanced) { + var arrayViews = buffer.arrayViews; + var length = arrayViews.length; + for ( var i = 0; i < length; ++i) { + var view = arrayViews[i]; + + attributes.push({ + index : view.index, + enabled : view.enabled, + componentsPerAttribute : view.componentsPerAttribute, + componentDatatype : view.componentDatatype, + normalize : view.normalize, + vertexBuffer : buffer.vertexBuffer, + offsetInBytes : vertexBufferOffset + view.offsetInBytes, + strideInBytes : buffer.vertexSizeInBytes, + instanceDivisor : instanced ? 1 : 0 + }); + } }; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {ModelGraphics} source The object to be merged into this object. - */ - ModelGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + VertexArrayFacade.prototype.subCommit = function(offsetInVertices, lengthInVertices) { + if (offsetInVertices < 0 || offsetInVertices >= this._size) { + throw new DeveloperError('offsetInVertices must be greater than or equal to zero and less than the vertex array size.'); + } + if (offsetInVertices + lengthInVertices > this._size) { + throw new DeveloperError('offsetInVertices + lengthInVertices cannot exceed the vertex array size.'); } - this.show = defaultValue(this.show, source.show); - this.scale = defaultValue(this.scale, source.scale); - this.minimumPixelSize = defaultValue(this.minimumPixelSize, source.minimumPixelSize); - this.maximumScale = defaultValue(this.maximumScale, source.maximumScale); - this.incrementallyLoadTextures = defaultValue(this.incrementallyLoadTextures, source.incrementallyLoadTextures); - this.shadows = defaultValue(this.shadows, source.shadows); - this.uri = defaultValue(this.uri, source.uri); - this.runAnimations = defaultValue(this.runAnimations, source.runAnimations); - this.clampAnimations = defaultValue(this.clampAnimations, source.clampAnimations); - this.heightReference = defaultValue(this.heightReference, source.heightReference); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - this.silhouetteColor = defaultValue(this.silhouetteColor, source.silhouetteColor); - this.silhouetteSize = defaultValue(this.silhouetteSize, source.silhouetteSize); - this.color = defaultValue(this.color, source.color); - this.colorBlendMode = defaultValue(this.colorBlendMode, source.colorBlendMode); - this.colorBlendAmount = defaultValue(this.colorBlendAmount, source.colorBlendAmount); - this.clippingPlanes = defaultValue(this.clippingPlanes, source.clippingPlanes); - - var sourceNodeTransformations = source.nodeTransformations; - if (defined(sourceNodeTransformations)) { - var targetNodeTransformations = this.nodeTransformations; - if (defined(targetNodeTransformations)) { - targetNodeTransformations.merge(sourceNodeTransformations); - } else { - this.nodeTransformations = new PropertyBag(sourceNodeTransformations, createNodeTransformationProperty); - } + var allBuffers = this._allBuffers; + for (var i = 0, len = allBuffers.length; i < len; ++i) { + subCommit(allBuffers[i], offsetInVertices, lengthInVertices); } }; - return ModelGraphics; -}); + function subCommit(buffer, offsetInVertices, lengthInVertices) { + if (buffer.needsCommit && (buffer.vertexSizeInBytes > 0)) { + var byteOffset = buffer.vertexSizeInBytes * offsetInVertices; + var byteLength = buffer.vertexSizeInBytes * lengthInVertices; -define('DataSources/PathGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + // PERFORMANCE_IDEA: If we want to get really crazy, we could consider updating + // individual attributes instead of the entire (sub-)vertex. + // + // PERFORMANCE_IDEA: Does creating the typed view add too much GC overhead? + buffer.vertexBuffer.copyFromArrayView(new Uint8Array(buffer.arrayBuffer, byteOffset, byteLength), byteOffset); + } + } - /** - * Describes a polyline defined as the path made by an {@link Entity} as it moves over time. - * - * @alias PathGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.leadTime] A Property specifying the number of seconds behind the object to show. - * @param {Property} [options.trailTime] A Property specifying the number of seconds in front of the object to show. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the path. - * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the path. - * @param {Property} [options.resolution=60] A numeric Property specifying the maximum number of seconds to step when sampling the position. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this path will be displayed. - */ - function PathGraphics(options) { - this._material = undefined; - this._materialSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._width = undefined; - this._widthSubscription = undefined; - this._resolution = undefined; - this._resolutionSubscription = undefined; - this._leadTime = undefined; - this._leadTimeSubscription = undefined; - this._trailTime = undefined; - this._trailTimeSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + VertexArrayFacade.prototype.endSubCommits = function() { + var allBuffers = this._allBuffers; - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + for (var i = 0, len = allBuffers.length; i < len; ++i) { + allBuffers[i].needsCommit = false; + } + }; + + function destroyVA(vertexArrayFacade) { + var va = vertexArrayFacade.va; + if (!defined(va)) { + return; + } + + var length = va.length; + for (var i = 0; i < length; ++i) { + va[i].va.destroy(); + } + + vertexArrayFacade.va = undefined; } - defineProperties(PathGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof PathGraphics.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + VertexArrayFacade.prototype.isDestroyed = function() { + return false; + }; - /** - * Gets or sets the boolean Property specifying the visibility of the path. - * @memberof PathGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + VertexArrayFacade.prototype.destroy = function() { + var allBuffers = this._allBuffers; + for (var i = 0, len = allBuffers.length; i < len; ++i) { + var buffer = allBuffers[i]; + buffer.vertexBuffer = buffer.vertexBuffer && buffer.vertexBuffer.destroy(); + } - /** - * Gets or sets the Property specifying the material used to draw the path. - * @memberof PathGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), + destroyVA(this); - /** - * Gets or sets the numeric Property specifying the width in pixels. - * @memberof PathGraphics.prototype - * @type {Property} - * @default 1.0 - */ - width : createPropertyDescriptor('width'), + return destroyObject(this); + }; - /** - * Gets or sets the Property specifying the maximum number of seconds to step when sampling the position. - * @memberof PathGraphics.prototype - * @type {Property} - * @default 60 - */ - resolution : createPropertyDescriptor('resolution'), + return VertexArrayFacade; +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/BillboardCollectionFS',[],function() { + 'use strict'; + return "uniform sampler2D u_atlas;\n\ +#ifdef VECTOR_TILE\n\ +uniform vec4 u_highlightColor;\n\ +#endif\n\ +varying vec2 v_textureCoordinates;\n\ +#ifdef RENDER_FOR_PICK\n\ +varying vec4 v_pickColor;\n\ +#else\n\ +varying vec4 v_color;\n\ +#endif\n\ +void main()\n\ +{\n\ +#ifdef RENDER_FOR_PICK\n\ +vec4 vertexColor = vec4(1.0, 1.0, 1.0, 1.0);\n\ +#else\n\ +vec4 vertexColor = v_color;\n\ +#endif\n\ +vec4 color = texture2D(u_atlas, v_textureCoordinates) * vertexColor;\n\ +#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\n\ +if (color.a < 0.005)\n\ +{\n\ +discard;\n\ +}\n\ +#else\n\ +#ifdef OPAQUE\n\ +if (color.a < 0.995)\n\ +{\n\ +discard;\n\ +}\n\ +#else\n\ +if (color.a >= 0.995)\n\ +{\n\ +discard;\n\ +}\n\ +#endif\n\ +#endif\n\ +#ifdef VECTOR_TILE\n\ +color *= u_highlightColor;\n\ +#endif\n\ +#ifdef RENDER_FOR_PICK\n\ +gl_FragColor = v_pickColor;\n\ +#else\n\ +gl_FragColor = color;\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/BillboardCollectionVS',[],function() { + 'use strict'; + return "#ifdef INSTANCED\n\ +attribute vec2 direction;\n\ +#endif\n\ +attribute vec4 positionHighAndScale;\n\ +attribute vec4 positionLowAndRotation;\n\ +attribute vec4 compressedAttribute0;\n\ +attribute vec4 compressedAttribute1;\n\ +attribute vec4 compressedAttribute2;\n\ +attribute vec4 eyeOffset;\n\ +attribute vec4 scaleByDistance;\n\ +attribute vec4 pixelOffsetScaleByDistance;\n\ +attribute vec3 distanceDisplayConditionAndDisableDepth;\n\ +#ifdef VECTOR_TILE\n\ +attribute float a_batchId;\n\ +#endif\n\ +varying vec2 v_textureCoordinates;\n\ +#ifdef RENDER_FOR_PICK\n\ +varying vec4 v_pickColor;\n\ +#else\n\ +varying vec4 v_color;\n\ +#endif\n\ +const float UPPER_BOUND = 32768.0;\n\ +const float SHIFT_LEFT16 = 65536.0;\n\ +const float SHIFT_LEFT8 = 256.0;\n\ +const float SHIFT_LEFT7 = 128.0;\n\ +const float SHIFT_LEFT5 = 32.0;\n\ +const float SHIFT_LEFT3 = 8.0;\n\ +const float SHIFT_LEFT2 = 4.0;\n\ +const float SHIFT_LEFT1 = 2.0;\n\ +const float SHIFT_RIGHT8 = 1.0 / 256.0;\n\ +const float SHIFT_RIGHT7 = 1.0 / 128.0;\n\ +const float SHIFT_RIGHT5 = 1.0 / 32.0;\n\ +const float SHIFT_RIGHT3 = 1.0 / 8.0;\n\ +const float SHIFT_RIGHT2 = 1.0 / 4.0;\n\ +const float SHIFT_RIGHT1 = 1.0 / 2.0;\n\ +vec4 computePositionWindowCoordinates(vec4 positionEC, vec2 imageSize, float scale, vec2 direction, vec2 origin, vec2 translate, vec2 pixelOffset, vec3 alignedAxis, bool validAlignedAxis, float rotation, bool sizeInMeters)\n\ +{\n\ +vec2 halfSize = imageSize * scale * czm_resolutionScale * 0.5;\n\ +halfSize *= ((direction * 2.0) - 1.0);\n\ +vec2 originTranslate = origin * abs(halfSize);\n\ +#if defined(ROTATION) || defined(ALIGNED_AXIS)\n\ +if (validAlignedAxis || rotation != 0.0)\n\ +{\n\ +float angle = rotation;\n\ +if (validAlignedAxis)\n\ +{\n\ +vec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0);\n\ +angle += sign(-projectedAlignedAxis.x) * acos( sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) /\n\ +(projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y) );\n\ +}\n\ +float cosTheta = cos(angle);\n\ +float sinTheta = sin(angle);\n\ +mat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta);\n\ +halfSize = rotationMatrix * halfSize;\n\ +}\n\ +#endif\n\ +if (sizeInMeters)\n\ +{\n\ +positionEC.xy += halfSize;\n\ +}\n\ +vec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\n\ +if (sizeInMeters)\n\ +{\n\ +originTranslate /= czm_metersPerPixel(positionEC);\n\ +}\n\ +positionWC.xy += originTranslate;\n\ +if (!sizeInMeters)\n\ +{\n\ +positionWC.xy += halfSize;\n\ +}\n\ +positionWC.xy += translate;\n\ +positionWC.xy += (pixelOffset * czm_resolutionScale);\n\ +return positionWC;\n\ +}\n\ +void main()\n\ +{\n\ +vec3 positionHigh = positionHighAndScale.xyz;\n\ +vec3 positionLow = positionLowAndRotation.xyz;\n\ +float scale = positionHighAndScale.w;\n\ +#if defined(ROTATION) || defined(ALIGNED_AXIS)\n\ +float rotation = positionLowAndRotation.w;\n\ +#else\n\ +float rotation = 0.0;\n\ +#endif\n\ +float compressed = compressedAttribute0.x;\n\ +vec2 pixelOffset;\n\ +pixelOffset.x = floor(compressed * SHIFT_RIGHT7);\n\ +compressed -= pixelOffset.x * SHIFT_LEFT7;\n\ +pixelOffset.x -= UPPER_BOUND;\n\ +vec2 origin;\n\ +origin.x = floor(compressed * SHIFT_RIGHT5);\n\ +compressed -= origin.x * SHIFT_LEFT5;\n\ +origin.y = floor(compressed * SHIFT_RIGHT3);\n\ +compressed -= origin.y * SHIFT_LEFT3;\n\ +origin -= vec2(1.0);\n\ +float show = floor(compressed * SHIFT_RIGHT2);\n\ +compressed -= show * SHIFT_LEFT2;\n\ +#ifdef INSTANCED\n\ +vec2 textureCoordinatesBottomLeft = czm_decompressTextureCoordinates(compressedAttribute0.w);\n\ +vec2 textureCoordinatesRange = czm_decompressTextureCoordinates(eyeOffset.w);\n\ +vec2 textureCoordinates = textureCoordinatesBottomLeft + direction * textureCoordinatesRange;\n\ +#else\n\ +vec2 direction;\n\ +direction.x = floor(compressed * SHIFT_RIGHT1);\n\ +direction.y = compressed - direction.x * SHIFT_LEFT1;\n\ +vec2 textureCoordinates = czm_decompressTextureCoordinates(compressedAttribute0.w);\n\ +#endif\n\ +float temp = compressedAttribute0.y * SHIFT_RIGHT8;\n\ +pixelOffset.y = -(floor(temp) - UPPER_BOUND);\n\ +vec2 translate;\n\ +translate.y = (temp - floor(temp)) * SHIFT_LEFT16;\n\ +temp = compressedAttribute0.z * SHIFT_RIGHT8;\n\ +translate.x = floor(temp) - UPPER_BOUND;\n\ +translate.y += (temp - floor(temp)) * SHIFT_LEFT8;\n\ +translate.y -= UPPER_BOUND;\n\ +temp = compressedAttribute1.x * SHIFT_RIGHT8;\n\ +vec2 imageSize = vec2(floor(temp), compressedAttribute2.w);\n\ +#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ +vec4 translucencyByDistance;\n\ +translucencyByDistance.x = compressedAttribute1.z;\n\ +translucencyByDistance.z = compressedAttribute1.w;\n\ +translucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ +temp = compressedAttribute1.y * SHIFT_RIGHT8;\n\ +translucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ +#endif\n\ +#ifdef ALIGNED_AXIS\n\ +vec3 alignedAxis = czm_octDecode(floor(compressedAttribute1.y * SHIFT_RIGHT8));\n\ +temp = compressedAttribute2.z * SHIFT_RIGHT5;\n\ +bool validAlignedAxis = (temp - floor(temp)) * SHIFT_LEFT1 > 0.0;\n\ +#else\n\ +vec3 alignedAxis = vec3(0.0);\n\ +bool validAlignedAxis = false;\n\ +#endif\n\ +#ifdef RENDER_FOR_PICK\n\ +temp = compressedAttribute2.y;\n\ +#else\n\ +temp = compressedAttribute2.x;\n\ +#endif\n\ +vec4 color;\n\ +temp = temp * SHIFT_RIGHT8;\n\ +color.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +temp = floor(temp) * SHIFT_RIGHT8;\n\ +color.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +color.r = floor(temp);\n\ +temp = compressedAttribute2.z * SHIFT_RIGHT8;\n\ +bool sizeInMeters = floor((temp - floor(temp)) * SHIFT_LEFT7) > 0.0;\n\ +temp = floor(temp) * SHIFT_RIGHT8;\n\ +#ifdef RENDER_FOR_PICK\n\ +color.a = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +vec4 pickColor = color / 255.0;\n\ +#else\n\ +color.a = floor(temp);\n\ +color /= 255.0;\n\ +#endif\n\ +vec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\n\ +vec4 positionEC = czm_modelViewRelativeToEye * p;\n\ +positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz);\n\ +positionEC.xyz *= show;\n\ +#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(EYE_DISTANCE_PIXEL_OFFSET) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\n\ +float lengthSq;\n\ +if (czm_sceneMode == czm_sceneMode2D)\n\ +{\n\ +lengthSq = czm_eyeHeight2D.y;\n\ +}\n\ +else\n\ +{\n\ +lengthSq = dot(positionEC.xyz, positionEC.xyz);\n\ +}\n\ +#endif\n\ +#ifdef EYE_DISTANCE_SCALING\n\ +float distanceScale = czm_nearFarScalar(scaleByDistance, lengthSq);\n\ +scale *= distanceScale;\n\ +translate *= distanceScale;\n\ +if (scale == 0.0)\n\ +{\n\ +positionEC.xyz = vec3(0.0);\n\ +}\n\ +#endif\n\ +float translucency = 1.0;\n\ +#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ +translucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\n\ +if (translucency == 0.0)\n\ +{\n\ +positionEC.xyz = vec3(0.0);\n\ +}\n\ +#endif\n\ +#ifdef EYE_DISTANCE_PIXEL_OFFSET\n\ +float pixelOffsetScale = czm_nearFarScalar(pixelOffsetScaleByDistance, lengthSq);\n\ +pixelOffset *= pixelOffsetScale;\n\ +#endif\n\ +#ifdef DISTANCE_DISPLAY_CONDITION\n\ +float nearSq = distanceDisplayConditionAndDisableDepth.x;\n\ +float farSq = distanceDisplayConditionAndDisableDepth.y;\n\ +if (lengthSq < nearSq || lengthSq > farSq)\n\ +{\n\ +positionEC.xyz = vec3(0.0);\n\ +}\n\ +#endif\n\ +vec4 positionWC = computePositionWindowCoordinates(positionEC, imageSize, scale, direction, origin, translate, pixelOffset, alignedAxis, validAlignedAxis, rotation, sizeInMeters);\n\ +gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\n\ +v_textureCoordinates = textureCoordinates;\n\ +#ifdef DISABLE_DEPTH_DISTANCE\n\ +float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\n\ +if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n\ +{\n\ +disableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n\ +}\n\ +if (disableDepthTestDistance != 0.0)\n\ +{\n\ +float zclip = gl_Position.z / gl_Position.w;\n\ +bool clipped = (zclip < -1.0 || zclip > 1.0);\n\ +if (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n\ +{\n\ +gl_Position.z = -gl_Position.w;\n\ +}\n\ +}\n\ +#endif\n\ +#ifdef RENDER_FOR_PICK\n\ +v_pickColor = pickColor;\n\ +#else\n\ +v_color = color;\n\ +v_color.a *= translucency;\n\ +#endif\n\ +}\n\ +"; +}); +define('Scene/BlendOption',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** + * Determines how opaque and translucent parts of billboards, points, and labels are blended with the scene. + * + * @exports BlendOption + */ + var BlendOption = { /** - * Gets or sets the Property specifying the number of seconds in front of the object to show. - * @memberof PathGraphics.prototype - * @type {Property} + * The billboards, points, or labels in the collection are completely opaque. + * @type {Number} + * @constant */ - leadTime : createPropertyDescriptor('leadTime'), + OPAQUE : 0, /** - * Gets or sets the Property specifying the number of seconds behind the object to show. - * @memberof PathGraphics.prototype - * @type {Property} + * The billboards, points, or labels in the collection are completely translucent. + * @type {Number} + * @constant */ - trailTime : createPropertyDescriptor('trailTime'), + TRANSLUCENT : 1, /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this path will be displayed. - * @memberof PathGraphics.prototype - * @type {Property} + * The billboards, points, or labels in the collection are both opaque and translucent. + * @type {Number} + * @constant */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); - - /** - * Duplicates this instance. - * - * @param {PathGraphics} [result] The object onto which to store the result. - * @returns {PathGraphics} The modified result parameter or a new instance if one was not provided. - */ - PathGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new PathGraphics(this); - } - result.material = this.material; - result.width = this.width; - result.resolution = this.resolution; - result.show = this.show; - result.leadTime = this.leadTime; - result.trailTime = this.trailTime; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; - - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {PathGraphics} source The object to be merged into this object. - */ - PathGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); - } - - this.material = defaultValue(this.material, source.material); - this.width = defaultValue(this.width, source.width); - this.resolution = defaultValue(this.resolution, source.resolution); - this.show = defaultValue(this.show, source.show); - this.leadTime = defaultValue(this.leadTime, source.leadTime); - this.trailTime = defaultValue(this.trailTime, source.trailTime); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + OPAQUE_AND_TRANSLUCENT : 2 }; - return PathGraphics; + return freezeObject(BlendOption); }); -define('DataSources/PlaneGraphics',[ +define('Renderer/Framebuffer',[ + '../Core/Check', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' -], function( + '../Core/PixelFormat', + './ContextLimits' + ], function( + Check, defaultValue, defined, defineProperties, + destroyObject, DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { + PixelFormat, + ContextLimits) { 'use strict'; + function attachTexture(framebuffer, attachment, texture) { + var gl = framebuffer._gl; + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, texture._target, texture._texture, 0); + } + + function attachRenderbuffer(framebuffer, attachment, renderbuffer) { + var gl = framebuffer._gl; + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbuffer._getRenderbuffer()); + } + /** - * Describes a plane. The center position and orientation are determined by the containing {@link Entity}. + * Creates a framebuffer with optional initial color, depth, and stencil attachments. + * Framebuffers are used for render-to-texture effects; they allow us to render to + * textures in one pass, and read from it in a later pass. * - * @alias PlaneGraphics - * @constructor + * @param {Object} options The initial framebuffer attachments as shown in the example below. <code>context</code> is required. The possible properties are <code>colorTextures</code>, <code>colorRenderbuffers</code>, <code>depthTexture</code>, <code>depthRenderbuffer</code>, <code>stencilRenderbuffer</code>, <code>depthStencilTexture</code>, and <code>depthStencilRenderbuffer</code>. * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.plane] A {@link Plane} Property specifying the normal and distance for the plane. - * @param {Property} [options.dimensions] A {@link Cartesian2} Property specifying the width and height of the plane. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the plane. - * @param {Property} [options.fill=true] A boolean Property specifying whether the plane is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the plane. - * @param {Property} [options.outline=false] A boolean Property specifying whether the plane is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the plane casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this plane will be displayed. + * @exception {DeveloperError} Cannot have both color texture and color renderbuffer attachments. + * @exception {DeveloperError} Cannot have both a depth texture and depth renderbuffer attachment. + * @exception {DeveloperError} Cannot have both a depth-stencil texture and depth-stencil renderbuffer attachment. + * @exception {DeveloperError} Cannot have both a depth and depth-stencil renderbuffer. + * @exception {DeveloperError} Cannot have both a stencil and depth-stencil renderbuffer. + * @exception {DeveloperError} Cannot have both a depth and stencil renderbuffer. + * @exception {DeveloperError} The color-texture pixel-format must be a color format. + * @exception {DeveloperError} The depth-texture pixel-format must be DEPTH_COMPONENT. + * @exception {DeveloperError} The depth-stencil-texture pixel-format must be DEPTH_STENCIL. + * @exception {DeveloperError} The number of color attachments exceeds the number supported. + * + * @example + * // Create a framebuffer with color and depth texture attachments. + * var width = context.canvas.clientWidth; + * var height = context.canvas.clientHeight; + * var framebuffer = new Framebuffer({ + * context : context, + * colorTextures : [new Texture({ + * context : context, + * width : width, + * height : height, + * pixelFormat : PixelFormat.RGBA + * })], + * depthTexture : new Texture({ + * context : context, + * width : width, + * height : height, + * pixelFormat : PixelFormat.DEPTH_COMPONENT, + * pixelDatatype : PixelDatatype.UNSIGNED_SHORT + * }) + * }); * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Plane.html|Cesium Sandcastle Plane Demo} + * @private */ - function PlaneGraphics(options) { - this._plane = undefined; - this._planeSubscription = undefined; - this._dimensions = undefined; - this._dimensionsSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + function Framebuffer(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + Check.defined('options.context', options.context); + + var gl = options.context._gl; + var maximumColorAttachments = ContextLimits.maximumColorAttachments; - defineProperties(PlaneGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof PlaneGraphics.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + this._gl = gl; + this._framebuffer = gl.createFramebuffer(); - /** - * Gets or sets the boolean Property specifying the visibility of the plane. - * @memberof PlaneGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + this._colorTextures = []; + this._colorRenderbuffers = []; + this._activeColorAttachments = []; - /** - * Gets or sets the {@link Plane} Property specifying the normal and distance of the plane. - * - * @memberof PlaneGraphics.prototype - * @type {Property} - */ - plane : createPropertyDescriptor('plane'), + this._depthTexture = undefined; + this._depthRenderbuffer = undefined; + this._stencilRenderbuffer = undefined; + this._depthStencilTexture = undefined; + this._depthStencilRenderbuffer = undefined; /** - * Gets or sets the {@link Cartesian2} Property specifying the width and height of the plane. + * When true, the framebuffer owns its attachments so they will be destroyed when + * {@link Framebuffer#destroy} is called or when a new attachment is assigned + * to an attachment point. * - * @memberof PlaneGraphics.prototype - * @type {Property} - */ - dimensions : createPropertyDescriptor('dimensions'), - - /** - * Gets or sets the material used to fill the plane. - * @memberof PlaneGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), - - /** - * Gets or sets the boolean Property specifying whether the plane is filled with the provided material. - * @memberof PlaneGraphics.prototype - * @type {Property} + * @type {Boolean} * @default true + * + * @see Framebuffer#destroy */ - fill : createPropertyDescriptor('fill'), - - /** - * Gets or sets the Property specifying whether the plane is outlined. - * @memberof PlaneGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), - - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof PlaneGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), - - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof PlaneGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), - - /** - * Get or sets the enum Property specifying whether the plane - * casts or receives shadows from each light source. - * @memberof PlaneGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + this.destroyAttachments = defaultValue(options.destroyAttachments, true); - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this plane will be displayed. - * @memberof PlaneGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + // Throw if a texture and renderbuffer are attached to the same point. This won't + // cause a WebGL error (because only one will be attached), but is likely a developer error. - /** - * Duplicates this instance. - * - * @param {PlaneGraphics} [result] The object onto which to store the result. - * @returns {PlaneGraphics} The modified result parameter or a new instance if one was not provided. - */ - PlaneGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new PlaneGraphics(this); + if (defined(options.colorTextures) && defined(options.colorRenderbuffers)) { + throw new DeveloperError('Cannot have both color texture and color renderbuffer attachments.'); } - result.plane = this.plane; - result.dimensions = this.dimensions; - result.show = this.show; - result.material = this.material; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; - - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {PlaneGraphics} source The object to be merged into this object. - */ - PlaneGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + if (defined(options.depthTexture) && defined(options.depthRenderbuffer)) { + throw new DeveloperError('Cannot have both a depth texture and depth renderbuffer attachment.'); + } + if (defined(options.depthStencilTexture) && defined(options.depthStencilRenderbuffer)) { + throw new DeveloperError('Cannot have both a depth-stencil texture and depth-stencil renderbuffer attachment.'); } - this.plane = defaultValue(this.plane, source.plane); - this.dimensions = defaultValue(this.dimensions, source.dimensions); - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - }; + // Avoid errors defined in Section 6.5 of the WebGL spec + var depthAttachment = (defined(options.depthTexture) || defined(options.depthRenderbuffer)); + var depthStencilAttachment = (defined(options.depthStencilTexture) || defined(options.depthStencilRenderbuffer)); - return PlaneGraphics; -}); + if (depthAttachment && depthStencilAttachment) { + throw new DeveloperError('Cannot have both a depth and depth-stencil attachment.'); + } + if (defined(options.stencilRenderbuffer) && depthStencilAttachment) { + throw new DeveloperError('Cannot have both a stencil and depth-stencil attachment.'); + } + if (depthAttachment && defined(options.stencilRenderbuffer)) { + throw new DeveloperError('Cannot have both a depth and stencil attachment.'); + } + + /////////////////////////////////////////////////////////////////// -define('DataSources/PointGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createPropertyDescriptor) { - 'use strict'; + this._bind(); - /** - * Describes a graphical point located at the position of the containing {@link Entity}. - * - * @alias PointGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the point. - * @param {Property} [options.pixelSize=1] A numeric Property specifying the size in pixels. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=0] A numeric Property specifying the the outline width in pixels. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the point. - * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to scale the point based on distance. - * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera. - * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this point will be displayed. - * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to. - */ - function PointGraphics(options) { - this._color = undefined; - this._colorSubscription = undefined; - this._pixelSize = undefined; - this._pixelSizeSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._show = undefined; - this._showSubscription = undefined; - this._scaleByDistance = undefined; - this._scaleByDistanceSubscription = undefined; - this._translucencyByDistance = undefined; - this._translucencyByDistanceSubscription = undefined; - this._heightReference = undefined; - this._heightReferenceSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._disableDepthTestDistance = undefined; - this._disableDepthTestDistanceSubscription = undefined; - this._definitionChanged = new Event(); + var texture; + var renderbuffer; + var i; + var length; + var attachmentEnum; - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + if (defined(options.colorTextures)) { + var textures = options.colorTextures; + length = this._colorTextures.length = this._activeColorAttachments.length = textures.length; - defineProperties(PointGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof PointGraphics.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + if (length > maximumColorAttachments) { + throw new DeveloperError('The number of color attachments exceeds the number supported.'); } - }, - - /** - * Gets or sets the Property specifying the {@link Color} of the point. - * @memberof PointGraphics.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color'), - - /** - * Gets or sets the numeric Property specifying the size in pixels. - * @memberof PointGraphics.prototype - * @type {Property} - * @default 1 - */ - pixelSize : createPropertyDescriptor('pixelSize'), - - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof PointGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), - - /** - * Gets or sets the numeric Property specifying the the outline width in pixels. - * @memberof PointGraphics.prototype - * @type {Property} - * @default 0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), - - /** - * Gets or sets the boolean Property specifying the visibility of the point. - * @memberof PointGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + + for (i = 0; i < length; ++i) { + texture = textures[i]; - /** - * Gets or sets the {@link NearFarScalar} Property used to scale the point based on distance. - * If undefined, a constant size is used. - * @memberof PointGraphics.prototype - * @type {Property} - */ - scaleByDistance : createPropertyDescriptor('scaleByDistance'), + if (!PixelFormat.isColorFormat(texture.pixelFormat)) { + throw new DeveloperError('The color-texture pixel-format must be a color format.'); + } + + attachmentEnum = this._gl.COLOR_ATTACHMENT0 + i; + attachTexture(this, attachmentEnum, texture); + this._activeColorAttachments[i] = attachmentEnum; + this._colorTextures[i] = texture; + } + } - /** - * Gets or sets {@link NearFarScalar} Property specifying the translucency of the point based on the distance from the camera. - * A point's translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the points's translucency remains clamped to the nearest bound. - * @memberof PointGraphics.prototype - * @type {Property} - */ - translucencyByDistance : createPropertyDescriptor('translucencyByDistance'), + if (defined(options.colorRenderbuffers)) { + var renderbuffers = options.colorRenderbuffers; + length = this._colorRenderbuffers.length = this._activeColorAttachments.length = renderbuffers.length; - /** - * Gets or sets the Property specifying the {@link HeightReference}. - * @memberof PointGraphics.prototype - * @type {Property} - * @default HeightReference.NONE - */ - heightReference : createPropertyDescriptor('heightReference'), + if (length > maximumColorAttachments) { + throw new DeveloperError('The number of color attachments exceeds the number supported.'); + } + + for (i = 0; i < length; ++i) { + renderbuffer = renderbuffers[i]; + attachmentEnum = this._gl.COLOR_ATTACHMENT0 + i; + attachRenderbuffer(this, attachmentEnum, renderbuffer); + this._activeColorAttachments[i] = attachmentEnum; + this._colorRenderbuffers[i] = renderbuffer; + } + } - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this point will be displayed. - * @memberof PointGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + if (defined(options.depthTexture)) { + texture = options.depthTexture; - /** - * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. - * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. - * @memberof PointGraphics.prototype - * @type {Property} - */ - disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') - }); + if (texture.pixelFormat !== PixelFormat.DEPTH_COMPONENT) { + throw new DeveloperError('The depth-texture pixel-format must be DEPTH_COMPONENT.'); + } + + attachTexture(this, this._gl.DEPTH_ATTACHMENT, texture); + this._depthTexture = texture; + } - /** - * Duplicates this instance. - * - * @param {PointGraphics} [result] The object onto which to store the result. - * @returns {PointGraphics} The modified result parameter or a new instance if one was not provided. - */ - PointGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new PointGraphics(this); + if (defined(options.depthRenderbuffer)) { + renderbuffer = options.depthRenderbuffer; + attachRenderbuffer(this, this._gl.DEPTH_ATTACHMENT, renderbuffer); + this._depthRenderbuffer = renderbuffer; } - result.color = this.color; - result.pixelSize = this.pixelSize; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.show = this.show; - result.scaleByDistance = this.scaleByDistance; - result.translucencyByDistance = this._translucencyByDistance; - result.heightReference = this.heightReference; - result.distanceDisplayCondition = this.distanceDisplayCondition; - result.disableDepthTestDistance = this.disableDepthTestDistance; - return result; - }; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {PointGraphics} source The object to be merged into this object. - */ - PointGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + if (defined(options.stencilRenderbuffer)) { + renderbuffer = options.stencilRenderbuffer; + attachRenderbuffer(this, this._gl.STENCIL_ATTACHMENT, renderbuffer); + this._stencilRenderbuffer = renderbuffer; } - - this.color = defaultValue(this.color, source.color); - this.pixelSize = defaultValue(this.pixelSize, source.pixelSize); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.show = defaultValue(this.show, source.show); - this.scaleByDistance = defaultValue(this.scaleByDistance, source.scaleByDistance); - this.translucencyByDistance = defaultValue(this._translucencyByDistance, source.translucencyByDistance); - this.heightReference = defaultValue(this.heightReference, source.heightReference); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - this.disableDepthTestDistance = defaultValue(this.disableDepthTestDistance, source.disableDepthTestDistance); - }; - return PointGraphics; -}); + if (defined(options.depthStencilTexture)) { + texture = options.depthStencilTexture; -define('DataSources/PolygonGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + if (texture.pixelFormat !== PixelFormat.DEPTH_STENCIL) { + throw new DeveloperError('The depth-stencil pixel-format must be DEPTH_STENCIL.'); + } + + attachTexture(this, this._gl.DEPTH_STENCIL_ATTACHMENT, texture); + this._depthStencilTexture = texture; + } - /** - * Describes a polygon defined by an hierarchy of linear rings which make up the outer shape and any nested holes. - * The polygon conforms to the curvature of the globe and can be placed on the surface or - * at altitude and can optionally be extruded into a volume. - * - * @alias PolygonGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.hierarchy] A Property specifying the {@link PolygonHierarchy}. - * @param {Property} [options.height=0] A numeric Property specifying the altitude of the polygon relative to the ellipsoid surface. - * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the polygon's extruded face relative to the ellipsoid surface. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polygon. - * @param {Property} [options.fill=true] A boolean Property specifying whether the polygon is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the polygon. - * @param {Property} [options.outline=false] A boolean Property specifying whether the polygon is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the polygon texture counter-clockwise from north. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. - * @param {Property} [options.perPositionHeight=false] A boolean specifying whether or not the the height of each position is used. - * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. - * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polygon will be displayed. - * - * @see Entity - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo} - */ - function PolygonGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._hierarchy = undefined; - this._hierarchySubscription = undefined; - this._height = undefined; - this._heightSubscription = undefined; - this._extrudedHeight = undefined; - this._extrudedHeightSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._stRotation = undefined; - this._stRotationSubscription = undefined; - this._perPositionHeight = undefined; - this._perPositionHeightSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._definitionChanged = new Event(); - this._closeTop = undefined; - this._closeTopSubscription = undefined; - this._closeBottom = undefined; - this._closeBottomSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; + if (defined(options.depthStencilRenderbuffer)) { + renderbuffer = options.depthStencilRenderbuffer; + attachRenderbuffer(this, this._gl.DEPTH_STENCIL_ATTACHMENT, renderbuffer); + this._depthStencilRenderbuffer = renderbuffer; + } - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + this._unBind(); } - defineProperties(PolygonGraphics.prototype, { + defineProperties(Framebuffer.prototype, { /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof PolygonGraphics.prototype - * - * @type {Event} - * @readonly + * The status of the framebuffer. If the status is not WebGLConstants.FRAMEBUFFER_COMPLETE, + * a {@link DeveloperError} will be thrown when attempting to render to the framebuffer. + * @memberof Framebuffer.prototype + * @type {Number} */ - definitionChanged : { + status : { get : function() { - return this._definitionChanged; + this._bind(); + var status = this._gl.checkFramebufferStatus(this._gl.FRAMEBUFFER); + this._unBind(); + return status; + } + }, + numberOfColorAttachments : { + get : function() { + return this._activeColorAttachments.length; + } + }, + depthTexture: { + get : function() { + return this._depthTexture; + } + }, + depthRenderbuffer: { + get : function() { + return this._depthRenderbuffer; + } + }, + stencilRenderbuffer : { + get : function() { + return this._stencilRenderbuffer; + } + }, + depthStencilTexture : { + get : function() { + return this._depthStencilTexture; + } + }, + depthStencilRenderbuffer : { + get : function() { + return this._depthStencilRenderbuffer; } }, /** - * Gets or sets the boolean Property specifying the visibility of the polygon. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), - - /** - * Gets or sets the Property specifying the material used to fill the polygon. - * @memberof PolygonGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), - - /** - * Gets or sets the Property specifying the {@link PolygonHierarchy}. - * @memberof PolygonGraphics.prototype - * @type {Property} - */ - hierarchy : createPropertyDescriptor('hierarchy'), - - /** - * Gets or sets the numeric Property specifying the constant altitude of the polygon. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default 0.0 - */ - height : createPropertyDescriptor('height'), - - /** - * Gets or sets the numeric Property specifying the altitude of the polygon extrusion. - * If {@link PolygonGraphics#perPositionHeight} is false, the volume starts at {@link PolygonGraphics#height} and ends at this altitude. - * If {@link PolygonGraphics#perPositionHeight} is true, the volume starts at the height of each {@link PolygonGraphics#hierarchy} position and ends at this altitude. - * @memberof PolygonGraphics.prototype - * @type {Property} - */ - extrudedHeight : createPropertyDescriptor('extrudedHeight'), - - /** - * Gets or sets the numeric Property specifying the angular distance between points on the polygon. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default {CesiumMath.RADIANS_PER_DEGREE} - */ - granularity : createPropertyDescriptor('granularity'), - - /** - * Gets or sets the numeric property specifying the rotation of the polygon texture counter-clockwise from north. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default 0 - */ - stRotation : createPropertyDescriptor('stRotation'), - - /** - * Gets or sets the boolean Property specifying whether the polygon is filled with the provided material. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default true + * True if the framebuffer has a depth attachment. Depth attachments include + * depth and depth-stencil textures, and depth and depth-stencil renderbuffers. When + * rendering to a framebuffer, a depth attachment is required for the depth test to have effect. + * @memberof Framebuffer.prototype + * @type {Boolean} */ - fill : createPropertyDescriptor('fill'), + hasDepthAttachment : { + get : function() { + return !!(this.depthTexture || this.depthRenderbuffer || this.depthStencilTexture || this.depthStencilRenderbuffer); + } + } + }); - /** - * Gets or sets the Property specifying whether the polygon is outlined. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), + Framebuffer.prototype._bind = function() { + var gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer); + }; - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), + Framebuffer.prototype._unBind = function() { + var gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }; - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + Framebuffer.prototype._getActiveColorAttachments = function() { + return this._activeColorAttachments; + }; - /** - * Gets or sets the boolean specifying whether or not the the height of each position is used. - * If true, the shape will have non-uniform altitude defined by the height of each {@link PolygonGraphics#hierarchy} position. - * If false, the shape will have a constant altitude as specified by {@link PolygonGraphics#height}. - * @memberof PolygonGraphics.prototype - * @type {Property} - */ - perPositionHeight : createPropertyDescriptor('perPositionHeight'), + Framebuffer.prototype.getColorTexture = function(index) { + if (!defined(index) || index < 0 || index >= this._colorTextures.length) { + throw new DeveloperError('index is required, must be greater than or equal to zero and must be less than the number of color attachments.'); + } + + return this._colorTextures[index]; + }; - /** - * Gets or sets a boolean specifying whether or not the top of an extruded polygon is included. - * @memberof PolygonGraphics.prototype - * @type {Property} - */ - closeTop : createPropertyDescriptor('closeTop'), + Framebuffer.prototype.getColorRenderbuffer = function(index) { + if (!defined(index) || index < 0 || index >= this._colorRenderbuffers.length) { + throw new DeveloperError('index is required, must be greater than or equal to zero and must be less than the number of color attachments.'); + } + + return this._colorRenderbuffers[index]; + }; - /** - * Gets or sets a boolean specifying whether or not the bottom of an extruded polygon is included. - * @memberof PolygonGraphics.prototype - * @type {Property} - */ - closeBottom : createPropertyDescriptor('closeBottom'), + Framebuffer.prototype.isDestroyed = function() { + return false; + }; - /** - * Get or sets the enum Property specifying whether the polygon - * casts or receives shadows from each light source. - * @memberof PolygonGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + Framebuffer.prototype.destroy = function() { + if (this.destroyAttachments) { + // If the color texture is a cube map face, it is owned by the cube map, and will not be destroyed. + var i = 0; + var textures = this._colorTextures; + var length = textures.length; + for (; i < length; ++i) { + var texture = textures[i]; + if (defined(texture)) { + texture.destroy(); + } + } - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this polygon will be displayed. - * @memberof PolygonGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + var renderbuffers = this._colorRenderbuffers; + length = renderbuffers.length; + for (i = 0; i < length; ++i) { + var renderbuffer = renderbuffers[i]; + if (defined(renderbuffer)) { + renderbuffer.destroy(); + } + } - /** - * Duplicates this instance. - * - * @param {PolygonGraphics} [result] The object onto which to store the result. - * @returns {PolygonGraphics} The modified result parameter or a new instance if one was not provided. - */ - PolygonGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new PolygonGraphics(this); + this._depthTexture = this._depthTexture && this._depthTexture.destroy(); + this._depthRenderbuffer = this._depthRenderbuffer && this._depthRenderbuffer.destroy(); + this._stencilRenderbuffer = this._stencilRenderbuffer && this._stencilRenderbuffer.destroy(); + this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); + this._depthStencilRenderbuffer = this._depthStencilRenderbuffer && this._depthStencilRenderbuffer.destroy(); } - result.show = this.show; - result.material = this.material; - result.hierarchy = this.hierarchy; - result.height = this.height; - result.extrudedHeight = this.extrudedHeight; - result.granularity = this.granularity; - result.stRotation = this.stRotation; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.perPositionHeight = this.perPositionHeight; - result.closeTop = this.closeTop; - result.closeBottom = this.closeBottom; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {PolygonGraphics} source The object to be merged into this object. - */ - PolygonGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); - } - - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.hierarchy = defaultValue(this.hierarchy, source.hierarchy); - this.height = defaultValue(this.height, source.height); - this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); - this.granularity = defaultValue(this.granularity, source.granularity); - this.stRotation = defaultValue(this.stRotation, source.stRotation); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.perPositionHeight = defaultValue(this.perPositionHeight, source.perPositionHeight); - this.closeTop = defaultValue(this.closeTop, source.closeTop); - this.closeBottom = defaultValue(this.closeBottom, source.closeBottom); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this._gl.deleteFramebuffer(this._framebuffer); + return destroyObject(this); }; - return PolygonGraphics; + return Framebuffer; }); -define('DataSources/PolylineGraphics',[ +define('Scene/TextureAtlas',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/createGuid', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' + '../Core/PixelFormat', + '../Core/Resource', + '../Core/RuntimeError', + '../Renderer/Framebuffer', + '../Renderer/Texture', + '../ThirdParty/when' ], function( + BoundingRectangle, + Cartesian2, + createGuid, defaultValue, defined, defineProperties, + destroyObject, DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { + PixelFormat, + Resource, + RuntimeError, + Framebuffer, + Texture, + when) { 'use strict'; + // The atlas is made up of regions of space called nodes that contain images or child nodes. + function TextureAtlasNode(bottomLeft, topRight, childNode1, childNode2, imageIndex) { + this.bottomLeft = defaultValue(bottomLeft, Cartesian2.ZERO); + this.topRight = defaultValue(topRight, Cartesian2.ZERO); + this.childNode1 = childNode1; + this.childNode2 = childNode2; + this.imageIndex = imageIndex; + } + + var defaultInitialSize = new Cartesian2(16.0, 16.0); + /** - * Describes a polyline defined as a line strip. The first two positions define a line segment, - * and each additional position defines a line segment from the previous position. The segments - * can be linear connected points or great arcs. + * A TextureAtlas stores multiple images in one square texture and keeps + * track of the texture coordinates for each image. TextureAtlas is dynamic, + * meaning new images can be added at any point in time. + * Texture coordinates are subject to change if the texture atlas resizes, so it is + * important to check {@link TextureAtlas#getGUID} before using old values. * - * @alias PolylineGraphics + * @alias TextureAtlas * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions that define the line strip. - * @param {Property} [options.followSurface=true] A boolean Property specifying whether the line segments should be great arcs or linearly connected. - * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polyline. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the polyline. - * @param {MaterialProperty} [options.depthFailMaterial] A property specifiying the material used to draw the polyline when it is below the terrain. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if followSurface is true. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polyline casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polyline will be displayed. + * @param {Object} options Object with the following properties: + * @param {Scene} options.context The context in which the texture gets created. + * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGBA] The pixel format of the texture. + * @param {Number} [options.borderWidthInPixels=1] The amount of spacing between adjacent images in pixels. + * @param {Cartesian2} [options.initialSize=new Cartesian2(16.0, 16.0)] The initial side lengths of the texture. * - * @see Entity - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo} + * @exception {DeveloperError} borderWidthInPixels must be greater than or equal to zero. + * @exception {DeveloperError} initialSize must be greater than zero. + * + * @private */ - function PolylineGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._depthFailMaterial = undefined; - this._depthFailMaterialSubscription = undefined; - this._positions = undefined; - this._positionsSubscription = undefined; - this._followSurface = undefined; - this._followSurfaceSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._widthSubscription = undefined; - this._width = undefined; - this._widthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + function TextureAtlas(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var borderWidthInPixels = defaultValue(options.borderWidthInPixels, 1.0); + var initialSize = defaultValue(options.initialSize, defaultInitialSize); - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + if (!defined(options.context)) { + throw new DeveloperError('context is required.'); + } + if (borderWidthInPixels < 0) { + throw new DeveloperError('borderWidthInPixels must be greater than or equal to zero.'); + } + if (initialSize.x < 1 || initialSize.y < 1) { + throw new DeveloperError('initialSize must be greater than zero.'); + } + + this._context = options.context; + this._pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGBA); + this._borderWidthInPixels = borderWidthInPixels; + this._textureCoordinates = []; + this._guid = createGuid(); + this._idHash = {}; + this._initialSize = initialSize; + + this._root = undefined; } - defineProperties(PolylineGraphics.prototype, { + defineProperties(TextureAtlas.prototype, { /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof PolylineGraphics.prototype - * - * @type {Event} - * @readonly + * The amount of spacing between adjacent images in pixels. + * @memberof TextureAtlas.prototype + * @type {Number} */ - definitionChanged : { + borderWidthInPixels : { get : function() { - return this._definitionChanged; + return this._borderWidthInPixels; } }, /** - * Gets or sets the boolean Property specifying the visibility of the polyline. - * @memberof PolylineGraphics.prototype - * @type {Property} - * @default true + * An array of {@link BoundingRectangle} texture coordinate regions for all the images in the texture atlas. + * The x and y values of the rectangle correspond to the bottom-left corner of the texture coordinate. + * The coordinates are in the order that the corresponding images were added to the atlas. + * @memberof TextureAtlas.prototype + * @type {BoundingRectangle[]} */ - show : createPropertyDescriptor('show'), + textureCoordinates : { + get : function() { + return this._textureCoordinates; + } + }, /** - * Gets or sets the Property specifying the material used to draw the polyline. - * @memberof PolylineGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE + * The texture that all of the images are being written to. + * @memberof TextureAtlas.prototype + * @type {Texture} */ - material : createMaterialPropertyDescriptor('material'), + texture : { + get : function() { + if(!defined(this._texture)) { + this._texture = new Texture({ + context : this._context, + width : this._initialSize.x, + height : this._initialSize.y, + pixelFormat : this._pixelFormat + }); + } + return this._texture; + } + }, /** - * Gets or sets the Property specifying the material used to draw the polyline when it fails the depth test. - * <p> - * Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, - * there may be artifacts. - * </p> - * @memberof PolylineGraphics.prototype - * @type {MaterialProperty} - * @default undefined + * The number of images in the texture atlas. This value increases + * every time addImage or addImages is called. + * Texture coordinates are subject to change if the texture atlas resizes, so it is + * important to check {@link TextureAtlas#getGUID} before using old values. + * @memberof TextureAtlas.prototype + * @type {Number} */ - depthFailMaterial : createMaterialPropertyDescriptor('depthFailMaterial'), + numberOfImages : { + get : function() { + return this._textureCoordinates.length; + } + }, /** - * Gets or sets the Property specifying the array of {@link Cartesian3} - * positions that define the line strip. - * @memberof PolylineGraphics.prototype - * @type {Property} + * The atlas' globally unique identifier (GUID). + * The GUID changes whenever the texture atlas is modified. + * Classes that use a texture atlas should check if the GUID + * has changed before processing the atlas data. + * @memberof TextureAtlas.prototype + * @type {String} */ - positions : createPropertyDescriptor('positions'), + guid : { + get : function() { + return this._guid; + } + } + }); - /** - * Gets or sets the numeric Property specifying the width in pixels. - * @memberof PolylineGraphics.prototype - * @type {Property} - * @default 1.0 - */ - width : createPropertyDescriptor('width'), + // Builds a larger texture and copies the old texture into the new one. + function resizeAtlas(textureAtlas, image) { + var context = textureAtlas._context; + var numImages = textureAtlas.numberOfImages; + var scalingFactor = 2.0; + var borderWidthInPixels = textureAtlas._borderWidthInPixels; + if (numImages > 0) { + var oldAtlasWidth = textureAtlas._texture.width; + var oldAtlasHeight = textureAtlas._texture.height; + var atlasWidth = scalingFactor * (oldAtlasWidth + image.width + borderWidthInPixels); + var atlasHeight = scalingFactor * (oldAtlasHeight + image.height + borderWidthInPixels); + var widthRatio = oldAtlasWidth / atlasWidth; + var heightRatio = oldAtlasHeight / atlasHeight; - /** - * Gets or sets the boolean Property specifying whether the line segments - * should be great arcs or linearly connected. - * @memberof PolylineGraphics.prototype - * @type {Property} - * @default true - */ - followSurface : createPropertyDescriptor('followSurface'), + // Create new node structure, putting the old root node in the bottom left. + var nodeBottomRight = new TextureAtlasNode(new Cartesian2(oldAtlasWidth + borderWidthInPixels, borderWidthInPixels), new Cartesian2(atlasWidth, oldAtlasHeight)); + var nodeBottomHalf = new TextureAtlasNode(new Cartesian2(), new Cartesian2(atlasWidth, oldAtlasHeight), textureAtlas._root, nodeBottomRight); + var nodeTopHalf = new TextureAtlasNode(new Cartesian2(borderWidthInPixels, oldAtlasHeight + borderWidthInPixels), new Cartesian2(atlasWidth, atlasHeight)); + var nodeMain = new TextureAtlasNode(new Cartesian2(), new Cartesian2(atlasWidth, atlasHeight), nodeBottomHalf, nodeTopHalf); - /** - * Gets or sets the numeric Property specifying the angular distance between each latitude and longitude if followSurface is true. - * @memberof PolylineGraphics.prototype - * @type {Property} - * @default Cesium.Math.RADIANS_PER_DEGREE - */ - granularity : createPropertyDescriptor('granularity'), + // Resize texture coordinates. + for (var i = 0; i < textureAtlas._textureCoordinates.length; i++) { + var texCoord = textureAtlas._textureCoordinates[i]; + if (defined(texCoord)) { + texCoord.x *= widthRatio; + texCoord.y *= heightRatio; + texCoord.width *= widthRatio; + texCoord.height *= heightRatio; + } + } - /** - * Get or sets the enum Property specifying whether the polyline - * casts or receives shadows from each light source. - * @memberof PolylineGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + // Copy larger texture. + var newTexture = new Texture({ + context : textureAtlas._context, + width : atlasWidth, + height : atlasHeight, + pixelFormat : textureAtlas._pixelFormat + }); - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this polyline will be displayed. - * @memberof PolylineGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + var framebuffer = new Framebuffer({ + context : context, + colorTextures : [textureAtlas._texture], + destroyAttachments : false + }); + + framebuffer._bind(); + newTexture.copyFromFramebuffer(0, 0, 0, 0, atlasWidth, atlasHeight); + framebuffer._unBind(); + framebuffer.destroy(); + textureAtlas._texture = textureAtlas._texture && textureAtlas._texture.destroy(); + textureAtlas._texture = newTexture; + textureAtlas._root = nodeMain; + } else { + // First image exceeds initialSize + var initialWidth = scalingFactor * (image.width + 2 * borderWidthInPixels); + var initialHeight = scalingFactor * (image.height + 2 * borderWidthInPixels); + if(initialWidth < textureAtlas._initialSize.x) { + initialWidth = textureAtlas._initialSize.x; + } + if(initialHeight < textureAtlas._initialSize.y) { + initialHeight = textureAtlas._initialSize.y; + } + textureAtlas._texture = textureAtlas._texture && textureAtlas._texture.destroy(); + textureAtlas._texture = new Texture({ + context : textureAtlas._context, + width : initialWidth, + height : initialHeight, + pixelFormat : textureAtlas._pixelFormat + }); + textureAtlas._root = new TextureAtlasNode(new Cartesian2(borderWidthInPixels, borderWidthInPixels), + new Cartesian2(initialWidth, initialHeight)); + } + } + + // A recursive function that finds the best place to insert + // a new image based on existing image 'nodes'. + // Inspired by: http://blackpawn.com/texts/lightmaps/default.html + function findNode(textureAtlas, node, image) { + if (!defined(node)) { + return undefined; + } + + // If a leaf node + if (!defined(node.childNode1) && + !defined(node.childNode2)) { + + // Node already contains an image, don't add to it. + if (defined(node.imageIndex)) { + return undefined; + } + + var nodeWidth = node.topRight.x - node.bottomLeft.x; + var nodeHeight = node.topRight.y - node.bottomLeft.y; + var widthDifference = nodeWidth - image.width; + var heightDifference = nodeHeight - image.height; + + // Node is smaller than the image. + if (widthDifference < 0 || heightDifference < 0) { + return undefined; + } + + // If the node is the same size as the image, return the node + if (widthDifference === 0 && heightDifference === 0) { + return node; + } + + // Vertical split (childNode1 = left half, childNode2 = right half). + if (widthDifference > heightDifference) { + node.childNode1 = new TextureAtlasNode(new Cartesian2(node.bottomLeft.x, node.bottomLeft.y), new Cartesian2(node.bottomLeft.x + image.width, node.topRight.y)); + // Only make a second child if the border gives enough space. + var childNode2BottomLeftX = node.bottomLeft.x + image.width + textureAtlas._borderWidthInPixels; + if (childNode2BottomLeftX < node.topRight.x) { + node.childNode2 = new TextureAtlasNode(new Cartesian2(childNode2BottomLeftX, node.bottomLeft.y), new Cartesian2(node.topRight.x, node.topRight.y)); + } + } + // Horizontal split (childNode1 = bottom half, childNode2 = top half). + else { + node.childNode1 = new TextureAtlasNode(new Cartesian2(node.bottomLeft.x, node.bottomLeft.y), new Cartesian2(node.topRight.x, node.bottomLeft.y + image.height)); + // Only make a second child if the border gives enough space. + var childNode2BottomLeftY = node.bottomLeft.y + image.height + textureAtlas._borderWidthInPixels; + if (childNode2BottomLeftY < node.topRight.y) { + node.childNode2 = new TextureAtlasNode(new Cartesian2(node.bottomLeft.x, childNode2BottomLeftY), new Cartesian2(node.topRight.x, node.topRight.y)); + } + } + return findNode(textureAtlas, node.childNode1, image); + } + + // If not a leaf node + return findNode(textureAtlas, node.childNode1, image) || + findNode(textureAtlas, node.childNode2, image); + } + + // Adds image of given index to the texture atlas. Called from addImage and addImages. + function addImage(textureAtlas, image, index) { + var node = findNode(textureAtlas, textureAtlas._root, image); + if (defined(node)) { + // Found a node that can hold the image. + node.imageIndex = index; + + // Add texture coordinate and write to texture + var atlasWidth = textureAtlas._texture.width; + var atlasHeight = textureAtlas._texture.height; + var nodeWidth = node.topRight.x - node.bottomLeft.x; + var nodeHeight = node.topRight.y - node.bottomLeft.y; + var x = node.bottomLeft.x / atlasWidth; + var y = node.bottomLeft.y / atlasHeight; + var w = nodeWidth / atlasWidth; + var h = nodeHeight / atlasHeight; + textureAtlas._textureCoordinates[index] = new BoundingRectangle(x, y, w, h); + textureAtlas._texture.copyFrom(image, node.bottomLeft.x, node.bottomLeft.y); + } else { + // No node found, must resize the texture atlas. + resizeAtlas(textureAtlas, image); + addImage(textureAtlas, image, index); + } + + textureAtlas._guid = createGuid(); + } /** - * Duplicates this instance. + * Adds an image to the atlas. If the image is already in the atlas, the atlas is unchanged and + * the existing index is used. * - * @param {PolylineGraphics} [result] The object onto which to store the result. - * @returns {PolylineGraphics} The modified result parameter or a new instance if one was not provided. + * @param {String} id An identifier to detect whether the image already exists in the atlas. + * @param {Image|Canvas|String|Resource|Promise|TextureAtlas~CreateImageCallback} image An image or canvas to add to the texture atlas, + * or a URL to an Image, or a Promise for an image, or a function that creates an image. + * @returns {Promise.<Number>} A Promise for the image index. */ - PolylineGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new PolylineGraphics(this); + TextureAtlas.prototype.addImage = function(id, image) { + if (!defined(id)) { + throw new DeveloperError('id is required.'); } - result.show = this.show; - result.material = this.material; - result.depthFailMaterial = this.depthFailMaterial; - result.positions = this.positions; - result.width = this.width; - result.followSurface = this.followSurface; - result.granularity = this.granularity; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; + if (!defined(image)) { + throw new DeveloperError('image is required.'); + } + + var indexPromise = this._idHash[id]; + if (defined(indexPromise)) { + // we're already aware of this source + return indexPromise; + } + + // not in atlas, create the promise for the index + + if (typeof image === 'function') { + // if image is a function, call it + image = image(id); + if (!defined(image)) { + throw new DeveloperError('image is required.'); + } + } else if ((typeof image === 'string') || (image instanceof Resource)) { + // Get a resource + var resource = Resource.createIfNeeded(image); + image = resource.fetchImage(); + } + + var that = this; + + indexPromise = when(image, function(image) { + if (that.isDestroyed()) { + return -1; + } + + var index = that.numberOfImages; + + addImage(that, image, index); + + return index; + }); + + // store the promise + this._idHash[id] = indexPromise; + + return indexPromise; }; /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. + * Add a sub-region of an existing atlas image as additional image indices. * - * @param {PolylineGraphics} source The object to be merged into this object. + * @param {String} id The identifier of the existing image. + * @param {BoundingRectangle} subRegion An {@link BoundingRectangle} sub-region measured in pixels from the bottom-left. + * + * @returns {Promise.<Number>} A Promise for the image index. */ - PolylineGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + TextureAtlas.prototype.addSubRegion = function(id, subRegion) { + if (!defined(id)) { + throw new DeveloperError('id is required.'); + } + if (!defined(subRegion)) { + throw new DeveloperError('subRegion is required.'); } - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.depthFailMaterial = defaultValue(this.depthFailMaterial, source.depthFailMaterial); - this.positions = defaultValue(this.positions, source.positions); - this.width = defaultValue(this.width, source.width); - this.followSurface = defaultValue(this.followSurface, source.followSurface); - this.granularity = defaultValue(this.granularity, source.granularity); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + var indexPromise = this._idHash[id]; + if (!defined(indexPromise)) { + throw new RuntimeError('image with id "' + id + '" not found in the atlas.'); + } + + var that = this; + return when(indexPromise, function(index) { + if (index === -1) { + // the atlas is destroyed + return -1; + } + var atlasWidth = that._texture.width; + var atlasHeight = that._texture.height; + var numImages = that.numberOfImages; + + var baseRegion = that._textureCoordinates[index]; + var x = baseRegion.x + (subRegion.x / atlasWidth); + var y = baseRegion.y + (subRegion.y / atlasHeight); + var w = subRegion.width / atlasWidth; + var h = subRegion.height / atlasHeight; + that._textureCoordinates.push(new BoundingRectangle(x, y, w, h)); + that._guid = createGuid(); + + return numImages; + }); }; - return PolylineGraphics; + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see TextureAtlas#destroy + */ + TextureAtlas.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * atlas = atlas && atlas.destroy(); + * + * @see TextureAtlas#isDestroyed + */ + TextureAtlas.prototype.destroy = function() { + this._texture = this._texture && this._texture.destroy(); + return destroyObject(this); + }; + + /** + * A function that creates an image. + * @callback TextureAtlas~CreateImageCallback + * @param {String} id The identifier of the image to load. + * @returns {Image|Promise} The image, or a promise that will resolve to an image. + */ + + return TextureAtlas; }); -define('DataSources/PolylineVolumeGraphics',[ +define('Scene/BillboardCollection',[ + '../Core/AttributeCompression', + '../Core/BoundingSphere', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Color', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' + '../Core/EncodedCartesian3', + '../Core/IndexDatatype', + '../Core/Math', + '../Core/Matrix4', + '../Core/WebGLConstants', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArrayFacade', + '../Shaders/BillboardCollectionFS', + '../Shaders/BillboardCollectionVS', + './Billboard', + './BlendingState', + './BlendOption', + './HeightReference', + './HorizontalOrigin', + './SceneMode', + './TextureAtlas', + './VerticalOrigin' ], function( + AttributeCompression, + BoundingSphere, + Cartesian2, + Cartesian3, + Color, + ComponentDatatype, defaultValue, defined, defineProperties, + destroyObject, DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { + EncodedCartesian3, + IndexDatatype, + CesiumMath, + Matrix4, + WebGLConstants, + Buffer, + BufferUsage, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + VertexArrayFacade, + BillboardCollectionFS, + BillboardCollectionVS, + Billboard, + BlendingState, + BlendOption, + HeightReference, + HorizontalOrigin, + SceneMode, + TextureAtlas, + VerticalOrigin) { 'use strict'; + var SHOW_INDEX = Billboard.SHOW_INDEX; + var POSITION_INDEX = Billboard.POSITION_INDEX; + var PIXEL_OFFSET_INDEX = Billboard.PIXEL_OFFSET_INDEX; + var EYE_OFFSET_INDEX = Billboard.EYE_OFFSET_INDEX; + var HORIZONTAL_ORIGIN_INDEX = Billboard.HORIZONTAL_ORIGIN_INDEX; + var VERTICAL_ORIGIN_INDEX = Billboard.VERTICAL_ORIGIN_INDEX; + var SCALE_INDEX = Billboard.SCALE_INDEX; + var IMAGE_INDEX_INDEX = Billboard.IMAGE_INDEX_INDEX; + var COLOR_INDEX = Billboard.COLOR_INDEX; + var ROTATION_INDEX = Billboard.ROTATION_INDEX; + var ALIGNED_AXIS_INDEX = Billboard.ALIGNED_AXIS_INDEX; + var SCALE_BY_DISTANCE_INDEX = Billboard.SCALE_BY_DISTANCE_INDEX; + var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX; + var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX; + var DISTANCE_DISPLAY_CONDITION_INDEX = Billboard.DISTANCE_DISPLAY_CONDITION_INDEX; + var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE; + var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES; + + var attributeLocations; + + var attributeLocationsBatched = { + positionHighAndScale : 0, + positionLowAndRotation : 1, + compressedAttribute0 : 2, // pixel offset, translate, horizontal origin, vertical origin, show, direction, texture coordinates + compressedAttribute1 : 3, // aligned axis, translucency by distance, image width + compressedAttribute2 : 4, // image height, color, pick color, size in meters, valid aligned axis, 13 bits free + eyeOffset : 5, // 4 bytes free + scaleByDistance : 6, + pixelOffsetScaleByDistance : 7, + distanceDisplayConditionAndDisableDepth : 8, + a_batchId : 9 + }; + + var attributeLocationsInstanced = { + direction : 0, + positionHighAndScale : 1, + positionLowAndRotation : 2, // texture offset in w + compressedAttribute0 : 3, + compressedAttribute1 : 4, + compressedAttribute2 : 5, + eyeOffset : 6, // texture range in w + scaleByDistance : 7, + pixelOffsetScaleByDistance : 8, + distanceDisplayConditionAndDisableDepth : 9, + a_batchId : 10 + }; + /** - * Describes a polyline volume defined as a line strip and corresponding two dimensional shape which is extruded along it. - * The resulting volume conforms to the curvature of the globe. + * A renderable collection of billboards. Billboards are viewport-aligned + * images positioned in the 3D scene. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.png' width='400' height='300' /><br /> + * Example billboards + * </div> + * <br /><br /> + * Billboards are added and removed from the collection using {@link BillboardCollection#add} + * and {@link BillboardCollection#remove}. Billboards in a collection automatically share textures + * for images with the same identifier. * - * @alias PolylineVolumeGraphics + * @alias BillboardCollection * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions which define the line strip. - * @param {Property} [options.shape] A Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded. - * @param {Property} [options.cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the volume. - * @param {Property} [options.fill=true] A boolean Property specifying whether the volume is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the volume. - * @param {Property} [options.outline=false] A boolean Property specifying whether the volume is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the volume casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this volume will be displayed. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each billboard from model to world coordinates. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {Scene} [options.scene] Must be passed in for billboards that use the height reference property or will be depth tested against the globe. + * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The billboard blending option. The default + * is used for rendering both opaque and translucent billboards. However, if either all of the billboards are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. * - * @see Entity - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo} + * @performance For best performance, prefer a few collections, each with many billboards, to + * many collections with only a few billboards each. Organize collections so that billboards + * with the same update frequency are in the same collection, i.e., billboards that do not + * change should be in one collection; billboards that change every frame should be in another + * collection; and so on. + * + * @see BillboardCollection#add + * @see BillboardCollection#remove + * @see Billboard + * @see LabelCollection + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Billboards.html|Cesium Sandcastle Billboard Demo} + * + * @example + * // Create a billboard collection with two billboards + * var billboards = scene.primitives.add(new Cesium.BillboardCollection()); + * billboards.add({ + * position : new Cesium.Cartesian3(1.0, 2.0, 3.0), + * image : 'url/to/image' + * }); + * billboards.add({ + * position : new Cesium.Cartesian3(4.0, 5.0, 6.0), + * image : 'url/to/another/image' + * }); */ - function PolylineVolumeGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._positions = undefined; - this._positionsSubscription = undefined; - this._shape = undefined; - this._shapeSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._cornerType = undefined; - this._cornerTypeSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubsription = undefined; - this._definitionChanged = new Event(); + function BillboardCollection(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); - } + this._scene = options.scene; + this._batchTable = options.batchTable; + + this._textureAtlas = undefined; + this._textureAtlasGUID = undefined; + this._destroyTextureAtlas = true; + this._sp = undefined; + this._spTranslucent = undefined; + this._spPick = undefined; + this._rsOpaque = undefined; + this._rsTranslucent = undefined; + this._vaf = undefined; + + this._billboards = []; + this._billboardsToUpdate = []; + this._billboardsToUpdateIndex = 0; + this._billboardsRemoved = false; + this._createVertexArray = false; + + this._shaderRotation = false; + this._compiledShaderRotation = false; + this._compiledShaderRotationPick = false; + + this._shaderAlignedAxis = false; + this._compiledShaderAlignedAxis = false; + this._compiledShaderAlignedAxisPick = false; + + this._shaderScaleByDistance = false; + this._compiledShaderScaleByDistance = false; + this._compiledShaderScaleByDistancePick = false; + + this._shaderTranslucencyByDistance = false; + this._compiledShaderTranslucencyByDistance = false; + this._compiledShaderTranslucencyByDistancePick = false; + + this._shaderPixelOffsetScaleByDistance = false; + this._compiledShaderPixelOffsetScaleByDistance = false; + this._compiledShaderPixelOffsetScaleByDistancePick = false; + + this._shaderDistanceDisplayCondition = false; + this._compiledShaderDistanceDisplayCondition = false; + this._compiledShaderDistanceDisplayConditionPick = false; + + this._shaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistancePick = false; + + this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); + + this._maxSize = 0.0; + this._maxEyeOffset = 0.0; + this._maxScale = 1.0; + this._maxPixelOffset = 0.0; + this._allHorizontalCenter = true; + this._allVerticalCenter = true; + this._allSizedInMeters = true; + + this._baseVolume = new BoundingSphere(); + this._baseVolumeWC = new BoundingSphere(); + this._baseVolume2D = new BoundingSphere(); + this._boundingVolume = new BoundingSphere(); + this._boundingVolumeDirty = false; + + this._colorCommands = []; + this._pickCommands = []; - defineProperties(PolylineVolumeGraphics.prototype, { /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof PolylineVolumeGraphics.prototype + * The 4x4 transformation matrix that transforms each billboard in this collection from model to world coordinates. + * When this is the identity matrix, the billboards are drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. * - * @type {Event} - * @readonly + * @type {Matrix4} + * @default {@link Matrix4.IDENTITY} + * + * + * @example + * var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); + * billboards.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + * billboards.add({ + * image : 'url/to/image', + * position : new Cesium.Cartesian3(0.0, 0.0, 0.0) // center + * }); + * billboards.add({ + * image : 'url/to/image', + * position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0) // east + * }); + * billboards.add({ + * image : 'url/to/image', + * position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0) // north + * }); + * billboards.add({ + * image : 'url/to/image', + * position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0) // up + * }); + * + * @see Transforms.eastNorthUpToFixedFrame */ - definitionChanged : { + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the primitive. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + + /** + * The billboard blending option. The default is used for rendering both opaque and translucent billboards. + * However, if either all of the billboards are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve + * performance by up to 2x. + * @type {BlendOption} + * @default BlendOption.OPAQUE_AND_TRANSLUCENT + */ + this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); + this._blendOption = undefined; + + this._mode = SceneMode.SCENE3D; + + // The buffer usage for each attribute is determined based on the usage of the attribute over time. + this._buffersUsage = [ + BufferUsage.STATIC_DRAW, // SHOW_INDEX + BufferUsage.STATIC_DRAW, // POSITION_INDEX + BufferUsage.STATIC_DRAW, // PIXEL_OFFSET_INDEX + BufferUsage.STATIC_DRAW, // EYE_OFFSET_INDEX + BufferUsage.STATIC_DRAW, // HORIZONTAL_ORIGIN_INDEX + BufferUsage.STATIC_DRAW, // VERTICAL_ORIGIN_INDEX + BufferUsage.STATIC_DRAW, // SCALE_INDEX + BufferUsage.STATIC_DRAW, // IMAGE_INDEX_INDEX + BufferUsage.STATIC_DRAW, // COLOR_INDEX + BufferUsage.STATIC_DRAW, // ROTATION_INDEX + BufferUsage.STATIC_DRAW, // ALIGNED_AXIS_INDEX + BufferUsage.STATIC_DRAW, // SCALE_BY_DISTANCE_INDEX + BufferUsage.STATIC_DRAW, // TRANSLUCENCY_BY_DISTANCE_INDEX + BufferUsage.STATIC_DRAW, // PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX + BufferUsage.STATIC_DRAW // DISTANCE_DISPLAY_CONDITION_INDEX + ]; + + this._highlightColor = Color.clone(Color.WHITE); // Only used by Vector3DTilePoints + + var that = this; + this._uniforms = { + u_atlas : function() { + return that._textureAtlas.texture; + }, + u_highlightColor : function() { + return that._highlightColor; + } + }; + + var scene = this._scene; + if (defined(scene) && defined(scene.terrainProviderChanged)) { + this._removeCallbackFunc = scene.terrainProviderChanged.addEventListener(function() { + var billboards = this._billboards; + var length = billboards.length; + for (var i=0;i<length;++i) { + billboards[i]._updateClamping(); + } + }, this); + } + } + + defineProperties(BillboardCollection.prototype, { + /** + * Returns the number of billboards in this collection. This is commonly used with + * {@link BillboardCollection#get} to iterate over all the billboards + * in the collection. + * @memberof BillboardCollection.prototype + * @type {Number} + */ + length : { get : function() { - return this._definitionChanged; + removeBillboards(this); + return this._billboards.length; } }, /** - * Gets or sets the boolean Property specifying the visibility of the volume. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default true + * Gets or sets the textureAtlas. + * @memberof BillboardCollection.prototype + * @type {TextureAtlas} + * @private */ - show : createPropertyDescriptor('show'), + textureAtlas : { + get : function() { + return this._textureAtlas; + }, + set : function(value) { + if (this._textureAtlas !== value) { + this._textureAtlas = this._destroyTextureAtlas && this._textureAtlas && this._textureAtlas.destroy(); + this._textureAtlas = value; + this._createVertexArray = true; // New per-billboard texture coordinates + } + } + }, + + /** + * Gets or sets a value which determines if the texture atlas is + * destroyed when the collection is destroyed. + * + * If the texture atlas is used by more than one collection, set this to <code>false</code>, + * and explicitly destroy the atlas to avoid attempting to destroy it multiple times. + * + * @memberof BillboardCollection.prototype + * @type {Boolean} + * @private + * + * @example + * // Set destroyTextureAtlas + * // Destroy a billboard collection but not its texture atlas. + * + * var atlas = new TextureAtlas({ + * scene : scene, + * images : images + * }); + * billboards.textureAtlas = atlas; + * billboards.destroyTextureAtlas = false; + * billboards = billboards.destroy(); + * console.log(atlas.isDestroyed()); // False + */ + destroyTextureAtlas : { + get : function() { + return this._destroyTextureAtlas; + }, + set : function(value) { + this._destroyTextureAtlas = value; + } + } + }); + + function destroyBillboards(billboards) { + var length = billboards.length; + for (var i = 0; i < length; ++i) { + if (billboards[i]) { + billboards[i]._destroy(); + } + } + } + + /** + * Creates and adds a billboard with the specified initial properties to the collection. + * The added billboard is returned so it can be modified or removed from the collection later. + * + * @param {Object}[billboard] A template describing the billboard's properties as shown in Example 1. + * @returns {Billboard} The billboard that was added to the collection. + * + * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer + * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For + * best performance, add as many billboards as possible before calling <code>update</code>. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Example 1: Add a billboard, specifying all the default values. + * var b = billboards.add({ + * show : true, + * position : Cesium.Cartesian3.ZERO, + * pixelOffset : Cesium.Cartesian2.ZERO, + * eyeOffset : Cesium.Cartesian3.ZERO, + * heightReference : Cesium.HeightReference.NONE, + * horizontalOrigin : Cesium.HorizontalOrigin.CENTER, + * verticalOrigin : Cesium.VerticalOrigin.CENTER, + * scale : 1.0, + * image : 'url/to/image', + * imageSubRegion : undefined, + * color : Cesium.Color.WHITE, + * id : undefined, + * rotation : 0.0, + * alignedAxis : Cesium.Cartesian3.ZERO, + * width : undefined, + * height : undefined, + * scaleByDistance : undefined, + * translucencyByDistance : undefined, + * pixelOffsetScaleByDistance : undefined, + * sizeInMeters : false, + * distanceDisplayCondition : undefined + * }); + * + * @example + * // Example 2: Specify only the billboard's cartographic position. + * var b = billboards.add({ + * position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height) + * }); + * + * @see BillboardCollection#remove + * @see BillboardCollection#removeAll + */ + BillboardCollection.prototype.add = function(billboard) { + var b = new Billboard(billboard, this); + b._index = this._billboards.length; - /** - * Gets or sets the Property specifying the material used to fill the volume. - * @memberof PolylineVolumeGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), + this._billboards.push(b); + this._createVertexArray = true; - /** - * Gets or sets the Property specifying the array of {@link Cartesian3} positions which define the line strip. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - */ - positions : createPropertyDescriptor('positions'), + return b; + }; - /** - * Gets or sets the Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - */ - shape : createPropertyDescriptor('shape'), + /** + * Removes a billboard from the collection. + * + * @param {Billboard} billboard The billboard to remove. + * @returns {Boolean} <code>true</code> if the billboard was removed; <code>false</code> if the billboard was not found in the collection. + * + * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer + * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For + * best performance, remove as many billboards as possible before calling <code>update</code>. + * If you intend to temporarily hide a billboard, it is usually more efficient to call + * {@link Billboard#show} instead of removing and re-adding the billboard. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * var b = billboards.add(...); + * billboards.remove(b); // Returns true + * + * @see BillboardCollection#add + * @see BillboardCollection#removeAll + * @see Billboard#show + */ + BillboardCollection.prototype.remove = function(billboard) { + if (this.contains(billboard)) { + this._billboards[billboard._index] = null; // Removed later + this._billboardsRemoved = true; + this._createVertexArray = true; + billboard._destroy(); + return true; + } - /** - * Gets or sets the numeric Property specifying the angular distance between points on the volume. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default {CesiumMath.RADIANS_PER_DEGREE} - */ - granularity : createPropertyDescriptor('granularity'), + return false; + }; - /** - * Gets or sets the boolean Property specifying whether the volume is filled with the provided material. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default true - */ - fill : createPropertyDescriptor('fill'), + /** + * Removes all billboards from the collection. + * + * @performance <code>O(n)</code>. It is more efficient to remove all the billboards + * from a collection and then add new ones than to create a new collection entirely. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * billboards.add(...); + * billboards.add(...); + * billboards.removeAll(); + * + * @see BillboardCollection#add + * @see BillboardCollection#remove + */ + BillboardCollection.prototype.removeAll = function() { + destroyBillboards(this._billboards); + this._billboards = []; + this._billboardsToUpdate = []; + this._billboardsToUpdateIndex = 0; + this._billboardsRemoved = false; - /** - * Gets or sets the Property specifying whether the volume is outlined. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), + this._createVertexArray = true; + }; - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), + function removeBillboards(billboardCollection) { + if (billboardCollection._billboardsRemoved) { + billboardCollection._billboardsRemoved = false; - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + var newBillboards = []; + var billboards = billboardCollection._billboards; + var length = billboards.length; + for (var i = 0, j = 0; i < length; ++i) { + var billboard = billboards[i]; + if (billboard) { + billboard._index = j++; + newBillboards.push(billboard); + } + } - /** - * Gets or sets the {@link CornerType} Property specifying the style of the corners. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default CornerType.ROUNDED - */ - cornerType : createPropertyDescriptor('cornerType'), + billboardCollection._billboards = newBillboards; + } + } - /** - * Get or sets the enum Property specifying whether the volume - * casts or receives shadows from each light source. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + BillboardCollection.prototype._updateBillboard = function(billboard, propertyChanged) { + if (!billboard._dirty) { + this._billboardsToUpdate[this._billboardsToUpdateIndex++] = billboard; + } - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this volume will be displayed. - * @memberof PolylineVolumeGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + ++this._propertiesChanged[propertyChanged]; + }; /** - * Duplicates this instance. + * Check whether this collection contains a given billboard. * - * @param {PolylineVolumeGraphics} [result] The object onto which to store the result. - * @returns {PolylineVolumeGraphics} The modified result parameter or a new instance if one was not provided. + * @param {Billboard} [billboard] The billboard to check for. + * @returns {Boolean} true if this collection contains the billboard, false otherwise. + * + * @see BillboardCollection#get */ - PolylineVolumeGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new PolylineVolumeGraphics(this); - } - result.show = this.show; - result.material = this.material; - result.positions = this.positions; - result.shape = this.shape; - result.granularity = this.granularity; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.cornerType = this.cornerType; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; + BillboardCollection.prototype.contains = function(billboard) { + return defined(billboard) && billboard._billboardCollection === this; }; /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. + * Returns the billboard in the collection at the specified index. Indices are zero-based + * and increase as billboards are added. Removing a billboard shifts all billboards after + * it to the left, changing their indices. This function is commonly used with + * {@link BillboardCollection#length} to iterate over all the billboards + * in the collection. * - * @param {PolylineVolumeGraphics} source The object to be merged into this object. + * @param {Number} index The zero-based index of the billboard. + * @returns {Billboard} The billboard at the specified index. + * + * @performance Expected constant time. If billboards were removed from the collection and + * {@link BillboardCollection#update} was not called, an implicit <code>O(n)</code> + * operation is performed. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Toggle the show property of every billboard in the collection + * var len = billboards.length; + * for (var i = 0; i < len; ++i) { + * var b = billboards.get(i); + * b.show = !b.show; + * } + * + * @see BillboardCollection#length */ - PolylineVolumeGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + BillboardCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); } - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.positions = defaultValue(this.positions, source.positions); - this.shape = defaultValue(this.shape, source.shape); - this.granularity = defaultValue(this.granularity, source.granularity); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.cornerType = defaultValue(this.cornerType, source.cornerType); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + removeBillboards(this); + return this._billboards[index]; }; - return PolylineVolumeGraphics; -}); + var getIndexBuffer; -define('DataSources/RectangleGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + function getIndexBufferBatched(context) { + var sixteenK = 16 * 1024; - /** - * Describes graphics for a {@link Rectangle}. - * The rectangle conforms to the curvature of the globe and can be placed on the surface or - * at altitude and can optionally be extruded into a volume. - * - * @alias RectangleGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.coordinates] The Property specifying the {@link Rectangle}. - * @param {Property} [options.height=0] A numeric Property specifying the altitude of the rectangle relative to the ellipsoid surface. - * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the rectangle's extruded face relative to the ellipsoid surface. - * @param {Property} [options.closeTop=true] A boolean Property specifying whether the rectangle has a top cover when extruded - * @param {Property} [options.closeBottom=true] A boolean Property specifying whether the rectangle has a bottom cover when extruded. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the rectangle. - * @param {Property} [options.fill=true] A boolean Property specifying whether the rectangle is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the rectangle. - * @param {Property} [options.outline=false] A boolean Property specifying whether the rectangle is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.rotation=0.0] A numeric property specifying the rotation of the rectangle clockwise from north. - * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the rectangle texture counter-clockwise from north. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the rectangle. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the rectangle casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this rectangle will be displayed. - * - * @see Entity - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo} - */ - function RectangleGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._coordinates = undefined; - this._coordinatesSubscription = undefined; - this._height = undefined; - this._heightSubscription = undefined; - this._extrudedHeight = undefined; - this._extrudedHeightSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._stRotation = undefined; - this._stRotationSubscription = undefined; - this._rotation = undefined; - this._rotationSubscription = undefined; - this._closeTop = undefined; - this._closeTopSubscription = undefined; - this._closeBottom = undefined; - this._closeBottomSubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distancedisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + var indexBuffer = context.cache.billboardCollection_indexBufferBatched; + if (defined(indexBuffer)) { + return indexBuffer; + } - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + // Subtract 6 because the last index is reserverd for primitive restart. + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.18 + var length = sixteenK * 6 - 6; + var indices = new Uint16Array(length); + for (var i = 0, j = 0; i < length; i += 6, j += 4) { + indices[i] = j; + indices[i + 1] = j + 1; + indices[i + 2] = j + 2; + + indices[i + 3] = j + 0; + indices[i + 4] = j + 2; + indices[i + 5] = j + 3; + } + + // PERFORMANCE_IDEA: Should we reference count billboard collections, and eventually delete this? + // Is this too much memory to allocate up front? Should we dynamically grow it? + indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : indices, + usage : BufferUsage.STATIC_DRAW, + indexDatatype : IndexDatatype.UNSIGNED_SHORT + }); + indexBuffer.vertexArrayDestroyable = false; + context.cache.billboardCollection_indexBufferBatched = indexBuffer; + return indexBuffer; } - defineProperties(RectangleGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof RectangleGraphics.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + function getIndexBufferInstanced(context) { + var indexBuffer = context.cache.billboardCollection_indexBufferInstanced; + if (defined(indexBuffer)) { + return indexBuffer; + } - /** - * Gets or sets the boolean Property specifying the visibility of the rectangle. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : new Uint16Array([0, 1, 2, 0, 2, 3]), + usage : BufferUsage.STATIC_DRAW, + indexDatatype : IndexDatatype.UNSIGNED_SHORT + }); - /** - * Gets or sets the Property specifying the {@link Rectangle}. - * @memberof RectangleGraphics.prototype - * @type {Property} - */ - coordinates : createPropertyDescriptor('coordinates'), + indexBuffer.vertexArrayDestroyable = false; + context.cache.billboardCollection_indexBufferInstanced = indexBuffer; + return indexBuffer; + } - /** - * Gets or sets the Property specifying the material used to fill the rectangle. - * @memberof RectangleGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), + function getVertexBufferInstanced(context) { + var vertexBuffer = context.cache.billboardCollection_vertexBufferInstanced; + if (defined(vertexBuffer)) { + return vertexBuffer; + } - /** - * Gets or sets the numeric Property specifying the altitude of the rectangle. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default 0.0 - */ - height : createPropertyDescriptor('height'), + vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : new Float32Array([0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]), + usage : BufferUsage.STATIC_DRAW + }); - /** - * Gets or sets the numeric Property specifying the altitude of the rectangle extrusion. - * Setting this property creates volume starting at height and ending at this altitude. - * @memberof RectangleGraphics.prototype - * @type {Property} - */ - extrudedHeight : createPropertyDescriptor('extrudedHeight'), + vertexBuffer.vertexArrayDestroyable = false; + context.cache.billboardCollection_vertexBufferInstanced = vertexBuffer; + return vertexBuffer; + } - /** - * Gets or sets the numeric Property specifying the angular distance between points on the rectangle. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default {CesiumMath.RADIANS_PER_DEGREE} - */ - granularity : createPropertyDescriptor('granularity'), + BillboardCollection.prototype.computeNewBuffersUsage = function() { + var buffersUsage = this._buffersUsage; + var usageChanged = false; - /** - * Gets or sets the numeric property specifying the rotation of the rectangle texture counter-clockwise from north. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default 0 - */ - stRotation : createPropertyDescriptor('stRotation'), + var properties = this._propertiesChanged; + for ( var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { + var newUsage = (properties[k] === 0) ? BufferUsage.STATIC_DRAW : BufferUsage.STREAM_DRAW; + usageChanged = usageChanged || (buffersUsage[k] !== newUsage); + buffersUsage[k] = newUsage; + } - /** - * Gets or sets the numeric property specifying the rotation of the rectangle clockwise from north. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default 0 - */ - rotation : createPropertyDescriptor('rotation'), + return usageChanged; + }; - /** - * Gets or sets the boolean Property specifying whether the rectangle is filled with the provided material. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default true - */ - fill : createPropertyDescriptor('fill'), + function createVAF(context, numberOfBillboards, buffersUsage, instanced, batchTable) { + var attributes = [{ + index : attributeLocations.positionHighAndScale, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[POSITION_INDEX] + }, { + index : attributeLocations.positionLowAndRotation, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[POSITION_INDEX] + }, { + index : attributeLocations.compressedAttribute0, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[PIXEL_OFFSET_INDEX] + }, { + index : attributeLocations.compressedAttribute1, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[TRANSLUCENCY_BY_DISTANCE_INDEX] + }, { + index : attributeLocations.compressedAttribute2, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[COLOR_INDEX] + }, { + index : attributeLocations.eyeOffset, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[EYE_OFFSET_INDEX] + }, { + index : attributeLocations.scaleByDistance, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[SCALE_BY_DISTANCE_INDEX] + }, { + index : attributeLocations.pixelOffsetScaleByDistance, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX] + }, { + index : attributeLocations.distanceDisplayConditionAndDisableDepth, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] + }]; - /** - * Gets or sets the Property specifying whether the rectangle is outlined. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), + // Instancing requires one non-instanced attribute. + if (instanced) { + attributes.push({ + index : attributeLocations.direction, + componentsPerAttribute : 2, + componentDatatype : ComponentDatatype.FLOAT, + vertexBuffer : getVertexBufferInstanced(context) + }); + } - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), + if (defined(batchTable)) { + attributes.push({ + index : attributeLocations.a_batchId, + componentsPerAttribute : 1, + componentDatatyps : ComponentDatatype.FLOAT, + bufferUsage : BufferUsage.STATIC_DRAW + }); + } - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + // When instancing is enabled, only one vertex is needed for each billboard. + var sizeInVertices = instanced ? numberOfBillboards : 4 * numberOfBillboards; + return new VertexArrayFacade(context, attributes, sizeInVertices, instanced); + } - /** - * Gets or sets the boolean Property specifying whether the rectangle has a top cover when extruded. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default true - */ - closeTop : createPropertyDescriptor('closeTop'), + /////////////////////////////////////////////////////////////////////////// - /** - * Gets or sets the boolean Property specifying whether the rectangle has a bottom cover when extruded. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default true - */ - closeBottom : createPropertyDescriptor('closeBottom'), + // Four vertices per billboard. Each has the same position, etc., but a different screen-space direction vector. - /** - * Get or sets the enum Property specifying whether the rectangle - * casts or receives shadows from each light source. - * @memberof RectangleGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + // PERFORMANCE_IDEA: Save memory if a property is the same for all billboards, use a latched attribute state, + // instead of storing it in a vertex buffer. - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this rectangle will be displayed. - * @memberof RectangleGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + var writePositionScratch = new EncodedCartesian3(); - /** - * Duplicates this instance. - * - * @param {RectangleGraphics} [result] The object onto which to store the result. - * @returns {RectangleGraphics} The modified result parameter or a new instance if one was not provided. - */ - RectangleGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new RectangleGraphics(this); + function writePositionScaleAndRotation(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var positionHighWriter = vafWriters[attributeLocations.positionHighAndScale]; + var positionLowWriter = vafWriters[attributeLocations.positionLowAndRotation]; + var position = billboard._getActualPosition(); + + if (billboardCollection._mode === SceneMode.SCENE3D) { + BoundingSphere.expand(billboardCollection._baseVolume, position, billboardCollection._baseVolume); + billboardCollection._boundingVolumeDirty = true; } - result.show = this.show; - result.coordinates = this.coordinates; - result.material = this.material; - result.height = this.height; - result.extrudedHeight = this.extrudedHeight; - result.granularity = this.granularity; - result.stRotation = this.stRotation; - result.rotation = this.rotation; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.closeTop = this.closeTop; - result.closeBottom = this.closeBottom; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {RectangleGraphics} source The object to be merged into this object. - */ - RectangleGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + EncodedCartesian3.fromCartesian(position, writePositionScratch); + var scale = billboard.scale; + var rotation = billboard.rotation; + + if (rotation !== 0.0) { + billboardCollection._shaderRotation = true; } - - this.show = defaultValue(this.show, source.show); - this.coordinates = defaultValue(this.coordinates, source.coordinates); - this.material = defaultValue(this.material, source.material); - this.height = defaultValue(this.height, source.height); - this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight); - this.granularity = defaultValue(this.granularity, source.granularity); - this.stRotation = defaultValue(this.stRotation, source.stRotation); - this.rotation = defaultValue(this.rotation, source.rotation); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.closeTop = defaultValue(this.closeTop, source.closeTop); - this.closeBottom = defaultValue(this.closeBottom, source.closeBottom); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - }; - return RectangleGraphics; -}); + billboardCollection._maxScale = Math.max(billboardCollection._maxScale, scale); -define('DataSources/WallGraphics',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './createMaterialPropertyDescriptor', - './createPropertyDescriptor' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - createMaterialPropertyDescriptor, - createPropertyDescriptor) { - 'use strict'; + var high = writePositionScratch.high; + var low = writePositionScratch.low; - /** - * Describes a two dimensional wall defined as a line strip and optional maximum and minimum heights. - * The wall conforms to the curvature of the globe and can be placed along the surface or at altitude. - * - * @alias WallGraphics - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions which define the top of the wall. - * @param {Property} [options.maximumHeights] A Property specifying an array of heights to be used for the top of the wall instead of the height of each position. - * @param {Property} [options.minimumHeights] A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface. - * @param {Property} [options.show=true] A boolean Property specifying the visibility of the wall. - * @param {Property} [options.fill=true] A boolean Property specifying whether the wall is filled with the provided material. - * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the wall. - * @param {Property} [options.outline=false] A boolean Property specifying whether the wall is outlined. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline. - * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. - * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the wall casts or receives shadows from each light source. - * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this wall will be displayed. - * - * @see Entity - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo} - */ - function WallGraphics(options) { - this._show = undefined; - this._showSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; - this._positions = undefined; - this._positionsSubscription = undefined; - this._minimumHeights = undefined; - this._minimumHeightsSubscription = undefined; - this._maximumHeights = undefined; - this._maximumHeightsSubscription = undefined; - this._granularity = undefined; - this._granularitySubscription = undefined; - this._fill = undefined; - this._fillSubscription = undefined; - this._outline = undefined; - this._outlineSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; - this._shadows = undefined; - this._shadowsSubscription = undefined; - this._distanceDisplayCondition = undefined; - this._distanceDisplayConditionSubscription = undefined; - this._definitionChanged = new Event(); + if (billboardCollection._instanced) { + i = billboard._index; + positionHighWriter(i, high.x, high.y, high.z, scale); + positionLowWriter(i, low.x, low.y, low.z, rotation); + } else { + i = billboard._index * 4; + positionHighWriter(i + 0, high.x, high.y, high.z, scale); + positionHighWriter(i + 1, high.x, high.y, high.z, scale); + positionHighWriter(i + 2, high.x, high.y, high.z, scale); + positionHighWriter(i + 3, high.x, high.y, high.z, scale); - this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); + positionLowWriter(i + 0, low.x, low.y, low.z, rotation); + positionLowWriter(i + 1, low.x, low.y, low.z, rotation); + positionLowWriter(i + 2, low.x, low.y, low.z, rotation); + positionLowWriter(i + 3, low.x, low.y, low.z, rotation); + } } - defineProperties(WallGraphics.prototype, { - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof WallGraphics.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - - /** - * Gets or sets the boolean Property specifying the visibility of the wall. - * @memberof WallGraphics.prototype - * @type {Property} - * @default true - */ - show : createPropertyDescriptor('show'), + var scratchCartesian2 = new Cartesian2(); - /** - * Gets or sets the Property specifying the material used to fill the wall. - * @memberof WallGraphics.prototype - * @type {MaterialProperty} - * @default Color.WHITE - */ - material : createMaterialPropertyDescriptor('material'), + var UPPER_BOUND = 32768.0; // 2^15 - /** - * Gets or sets the Property specifying the array of {@link Cartesian3} positions which define the top of the wall. - * @memberof WallGraphics.prototype - * @type {Property} - */ - positions : createPropertyDescriptor('positions'), + var LEFT_SHIFT16 = 65536.0; // 2^16 + var LEFT_SHIFT8 = 256.0; // 2^8 + var LEFT_SHIFT7 = 128.0; + var LEFT_SHIFT5 = 32.0; + var LEFT_SHIFT3 = 8.0; + var LEFT_SHIFT2 = 4.0; - /** - * Gets or sets the Property specifying an array of heights to be used for the bottom of the wall instead of the surface of the globe. - * If defined, the array must be the same length as {@link Wall#positions}. - * @memberof WallGraphics.prototype - * @type {Property} - */ - minimumHeights : createPropertyDescriptor('minimumHeights'), + var RIGHT_SHIFT8 = 1.0 / 256.0; - /** - * Gets or sets the Property specifying an array of heights to be used for the top of the wall instead of the height of each position. - * If defined, the array must be the same length as {@link Wall#positions}. - * @memberof WallGraphics.prototype - * @type {Property} - */ - maximumHeights : createPropertyDescriptor('maximumHeights'), + var LOWER_LEFT = 0.0; + var LOWER_RIGHT = 2.0; + var UPPER_RIGHT = 3.0; + var UPPER_LEFT = 1.0; - /** - * Gets or sets the numeric Property specifying the angular distance between points on the wall. - * @memberof WallGraphics.prototype - * @type {Property} - * @default {CesiumMath.RADIANS_PER_DEGREE} - */ - granularity : createPropertyDescriptor('granularity'), + function writeCompressedAttrib0(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.compressedAttribute0]; + var pixelOffset = billboard.pixelOffset; + var pixelOffsetX = pixelOffset.x; + var pixelOffsetY = pixelOffset.y; - /** - * Gets or sets the boolean Property specifying whether the wall is filled with the provided material. - * @memberof WallGraphics.prototype - * @type {Property} - * @default true - */ - fill : createPropertyDescriptor('fill'), + var translate = billboard._translate; + var translateX = translate.x; + var translateY = translate.y; - /** - * Gets or sets the Property specifying whether the wall is outlined. - * @memberof WallGraphics.prototype - * @type {Property} - * @default false - */ - outline : createPropertyDescriptor('outline'), + billboardCollection._maxPixelOffset = Math.max(billboardCollection._maxPixelOffset, Math.abs(pixelOffsetX + translateX), Math.abs(-pixelOffsetY + translateY)); - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof WallGraphics.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), + var horizontalOrigin = billboard.horizontalOrigin; + var verticalOrigin = billboard._verticalOrigin; + var show = billboard.show && billboard.clusterShow; - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof WallGraphics.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth'), + // If the color alpha is zero, do not show this billboard. This lets us avoid providing + // color during the pick pass and also eliminates a discard in the fragment shader. + if (billboard.color.alpha === 0.0) { + show = false; + } - /** - * Get or sets the enum Property specifying whether the wall - * casts or receives shadows from each light source. - * @memberof WallGraphics.prototype - * @type {Property} - * @default ShadowMode.DISABLED - */ - shadows : createPropertyDescriptor('shadows'), + // Raw billboards don't distinguish between BASELINE and BOTTOM, only LabelCollection does that. + if (verticalOrigin === VerticalOrigin.BASELINE) { + verticalOrigin = VerticalOrigin.BOTTOM; + } - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this wall will be displayed. - * @memberof WallGraphics.prototype - * @type {Property} - */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') - }); + billboardCollection._allHorizontalCenter = billboardCollection._allHorizontalCenter && horizontalOrigin === HorizontalOrigin.CENTER; + billboardCollection._allVerticalCenter = billboardCollection._allVerticalCenter && verticalOrigin === VerticalOrigin.CENTER; - /** - * Duplicates this instance. - * - * @param {WallGraphics} [result] The object onto which to store the result. - * @returns {WallGraphics} The modified result parameter or a new instance if one was not provided. - */ - WallGraphics.prototype.clone = function(result) { - if (!defined(result)) { - return new WallGraphics(this); - } - result.show = this.show; - result.material = this.material; - result.positions = this.positions; - result.minimumHeights = this.minimumHeights; - result.maximumHeights = this.maximumHeights; - result.granularity = this.granularity; - result.fill = this.fill; - result.outline = this.outline; - result.outlineColor = this.outlineColor; - result.outlineWidth = this.outlineWidth; - result.shadows = this.shadows; - result.distanceDisplayCondition = this.distanceDisplayCondition; - return result; - }; + var bottomLeftX = 0; + var bottomLeftY = 0; + var width = 0; + var height = 0; + var index = billboard._imageIndex; + if (index !== -1) { + var imageRectangle = textureAtlasCoordinates[index]; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {WallGraphics} source The object to be merged into this object. - */ - WallGraphics.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + if (!defined(imageRectangle)) { + throw new DeveloperError('Invalid billboard image index: ' + index); + } + + bottomLeftX = imageRectangle.x; + bottomLeftY = imageRectangle.y; + width = imageRectangle.width; + height = imageRectangle.height; } - - this.show = defaultValue(this.show, source.show); - this.material = defaultValue(this.material, source.material); - this.positions = defaultValue(this.positions, source.positions); - this.minimumHeights = defaultValue(this.minimumHeights, source.minimumHeights); - this.maximumHeights = defaultValue(this.maximumHeights, source.maximumHeights); - this.granularity = defaultValue(this.granularity, source.granularity); - this.fill = defaultValue(this.fill, source.fill); - this.outline = defaultValue(this.outline, source.outline); - this.outlineColor = defaultValue(this.outlineColor, source.outlineColor); - this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth); - this.shadows = defaultValue(this.shadows, source.shadows); - this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); - }; + var topRightX = bottomLeftX + width; + var topRightY = bottomLeftY + height; - return WallGraphics; -}); + var compressed0 = Math.floor(CesiumMath.clamp(pixelOffsetX, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * LEFT_SHIFT7; + compressed0 += (horizontalOrigin + 1.0) * LEFT_SHIFT5; + compressed0 += (verticalOrigin + 1.0) * LEFT_SHIFT3; + compressed0 += (show ? 1.0 : 0.0) * LEFT_SHIFT2; -define('DataSources/Entity',[ - '../Core/Cartesian3', - '../Core/Check', - '../Core/createGuid', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/Quaternion', - '../Core/Transforms', - './BillboardGraphics', - './BoxGraphics', - './ConstantPositionProperty', - './CorridorGraphics', - './createPropertyDescriptor', - './createRawPropertyDescriptor', - './CylinderGraphics', - './EllipseGraphics', - './EllipsoidGraphics', - './LabelGraphics', - './ModelGraphics', - './PathGraphics', - './PlaneGraphics', - './PointGraphics', - './PolygonGraphics', - './PolylineGraphics', - './PolylineVolumeGraphics', - './Property', - './PropertyBag', - './RectangleGraphics', - './WallGraphics' - ], function( - Cartesian3, - Check, - createGuid, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - Matrix3, - Matrix4, - Quaternion, - Transforms, - BillboardGraphics, - BoxGraphics, - ConstantPositionProperty, - CorridorGraphics, - createPropertyDescriptor, - createRawPropertyDescriptor, - CylinderGraphics, - EllipseGraphics, - EllipsoidGraphics, - LabelGraphics, - ModelGraphics, - PathGraphics, - PlaneGraphics, - PointGraphics, - PolygonGraphics, - PolylineGraphics, - PolylineVolumeGraphics, - Property, - PropertyBag, - RectangleGraphics, - WallGraphics) { - 'use strict'; + var compressed1 = Math.floor(CesiumMath.clamp(pixelOffsetY, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * LEFT_SHIFT8; + var compressed2 = Math.floor(CesiumMath.clamp(translateX, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * LEFT_SHIFT8; - function createConstantPositionProperty(value) { - return new ConstantPositionProperty(value); - } + var tempTanslateY = (CesiumMath.clamp(translateY, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * RIGHT_SHIFT8; + var upperTranslateY = Math.floor(tempTanslateY); + var lowerTranslateY = Math.floor((tempTanslateY - upperTranslateY) * LEFT_SHIFT8); - function createPositionPropertyDescriptor(name) { - return createPropertyDescriptor(name, undefined, createConstantPositionProperty); + compressed1 += upperTranslateY; + compressed2 += lowerTranslateY; + + scratchCartesian2.x = bottomLeftX; + scratchCartesian2.y = bottomLeftY; + var compressedTexCoordsLL = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + scratchCartesian2.x = topRightX; + var compressedTexCoordsLR = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + scratchCartesian2.y = topRightY; + var compressedTexCoordsUR = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + scratchCartesian2.x = bottomLeftX; + var compressedTexCoordsUL = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, compressed0, compressed1, compressed2, compressedTexCoordsLL); + } else { + i = billboard._index * 4; + writer(i + 0, compressed0 + LOWER_LEFT, compressed1, compressed2, compressedTexCoordsLL); + writer(i + 1, compressed0 + LOWER_RIGHT, compressed1, compressed2, compressedTexCoordsLR); + writer(i + 2, compressed0 + UPPER_RIGHT, compressed1, compressed2, compressedTexCoordsUR); + writer(i + 3, compressed0 + UPPER_LEFT, compressed1, compressed2, compressedTexCoordsUL); + } } - function createPropertyTypeDescriptor(name, Type) { - return createPropertyDescriptor(name, undefined, function(value) { - if (value instanceof Type) { - return value; + function writeCompressedAttrib1(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.compressedAttribute1]; + var alignedAxis = billboard.alignedAxis; + if (!Cartesian3.equals(alignedAxis, Cartesian3.ZERO)) { + billboardCollection._shaderAlignedAxis = true; + } + + var near = 0.0; + var nearValue = 1.0; + var far = 1.0; + var farValue = 1.0; + + var translucency = billboard.translucencyByDistance; + if (defined(translucency)) { + near = translucency.near; + nearValue = translucency.nearValue; + far = translucency.far; + farValue = translucency.farValue; + + if (nearValue !== 1.0 || farValue !== 1.0) { + // translucency by distance calculation in shader need not be enabled + // until a billboard with near and far !== 1.0 is found + billboardCollection._shaderTranslucencyByDistance = true; } - return new Type(value); - }); - } + } - /** - * Entity instances aggregate multiple forms of visualization into a single high-level object. - * They can be created manually and added to {@link Viewer#entities} or be produced by - * data sources, such as {@link CzmlDataSource} and {@link GeoJsonDataSource}. - * @alias Entity - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.id] A unique identifier for this object. If none is provided, a GUID is generated. - * @param {String} [options.name] A human readable name to display to users. It does not have to be unique. - * @param {TimeIntervalCollection} [options.availability] The availability, if any, associated with this object. - * @param {Boolean} [options.show] A boolean value indicating if the entity and its children are displayed. - * @param {Property} [options.description] A string Property specifying an HTML description for this entity. - * @param {PositionProperty} [options.position] A Property specifying the entity position. - * @param {Property} [options.orientation] A Property specifying the entity orientation. - * @param {Property} [options.viewFrom] A suggested initial offset for viewing this object. - * @param {Entity} [options.parent] A parent entity to associate with this entity. - * @param {BillboardGraphics} [options.billboard] A billboard to associate with this entity. - * @param {BoxGraphics} [options.box] A box to associate with this entity. - * @param {CorridorGraphics} [options.corridor] A corridor to associate with this entity. - * @param {CylinderGraphics} [options.cylinder] A cylinder to associate with this entity. - * @param {EllipseGraphics} [options.ellipse] A ellipse to associate with this entity. - * @param {EllipsoidGraphics} [options.ellipsoid] A ellipsoid to associate with this entity. - * @param {LabelGraphics} [options.label] A options.label to associate with this entity. - * @param {ModelGraphics} [options.model] A model to associate with this entity. - * @param {PathGraphics} [options.path] A path to associate with this entity. - * @param {PlaneGraphics} [options.plane] A plane to associate with this entity. - * @param {PointGraphics} [options.point] A point to associate with this entity. - * @param {PolygonGraphics} [options.polygon] A polygon to associate with this entity. - * @param {PolylineGraphics} [options.polyline] A polyline to associate with this entity. - * @param {PropertyBag} [options.properties] Arbitrary properties to associate with this entity. - * @param {PolylineVolumeGraphics} [options.polylineVolume] A polylineVolume to associate with this entity. - * @param {RectangleGraphics} [options.rectangle] A rectangle to associate with this entity. - * @param {WallGraphics} [options.wall] A wall to associate with this entity. - * - * @see {@link http://cesiumjs.org/2015/02/02/Visualizing-Spatial-Data/|Visualizing Spatial Data} - */ - function Entity(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var width = 0; + var index = billboard._imageIndex; + if (index !== -1) { + var imageRectangle = textureAtlasCoordinates[index]; - var id = options.id; - if (!defined(id)) { - id = createGuid(); + if (!defined(imageRectangle)) { + throw new DeveloperError('Invalid billboard image index: ' + index); + } + + width = imageRectangle.width; } - this._availability = undefined; - this._id = id; - this._definitionChanged = new Event(); - this._name = options.name; - this._show = defaultValue(options.show, true); - this._parent = undefined; - this._propertyNames = ['billboard', 'box', 'corridor', 'cylinder', 'description', 'ellipse', // - 'ellipsoid', 'label', 'model', 'orientation', 'path', 'plane', 'point', 'polygon', // - 'polyline', 'polylineVolume', 'position', 'properties', 'rectangle', 'viewFrom', 'wall']; + var textureWidth = billboardCollection._textureAtlas.texture.width; + var imageWidth = Math.round(defaultValue(billboard.width, textureWidth * width)); + billboardCollection._maxSize = Math.max(billboardCollection._maxSize, imageWidth); - this._billboard = undefined; - this._billboardSubscription = undefined; - this._box = undefined; - this._boxSubscription = undefined; - this._corridor = undefined; - this._corridorSubscription = undefined; - this._cylinder = undefined; - this._cylinderSubscription = undefined; - this._description = undefined; - this._descriptionSubscription = undefined; - this._ellipse = undefined; - this._ellipseSubscription = undefined; - this._ellipsoid = undefined; - this._ellipsoidSubscription = undefined; - this._label = undefined; - this._labelSubscription = undefined; - this._model = undefined; - this._modelSubscription = undefined; - this._orientation = undefined; - this._orientationSubscription = undefined; - this._path = undefined; - this._pathSubscription = undefined; - this._plane = undefined; - this._planeSubscription = undefined; - this._point = undefined; - this._pointSubscription = undefined; - this._polygon = undefined; - this._polygonSubscription = undefined; - this._polyline = undefined; - this._polylineSubscription = undefined; - this._polylineVolume = undefined; - this._polylineVolumeSubscription = undefined; - this._position = undefined; - this._positionSubscription = undefined; - this._properties = undefined; - this._propertiesSubscription = undefined; - this._rectangle = undefined; - this._rectangleSubscription = undefined; - this._viewFrom = undefined; - this._viewFromSubscription = undefined; - this._wall = undefined; - this._wallSubscription = undefined; - this._children = []; + var compressed0 = CesiumMath.clamp(imageWidth, 0.0, LEFT_SHIFT16); + var compressed1 = 0.0; - /** - * Gets or sets the entity collection that this entity belongs to. - * @type {EntityCollection} - */ - this.entityCollection = undefined; + if (Math.abs(Cartesian3.magnitudeSquared(alignedAxis) - 1.0) < CesiumMath.EPSILON6) { + compressed1 = AttributeCompression.octEncodeFloat(alignedAxis); + } - this.parent = options.parent; - this.merge(options); - } + nearValue = CesiumMath.clamp(nearValue, 0.0, 1.0); + nearValue = nearValue === 1.0 ? 255.0 : (nearValue * 255.0) | 0; + compressed0 = compressed0 * LEFT_SHIFT8 + nearValue; - function updateShow(entity, children, isShowing) { - var length = children.length; - for (var i = 0; i < length; i++) { - var child = children[i]; - var childShow = child._show; - var oldValue = !isShowing && childShow; - var newValue = isShowing && childShow; - if (oldValue !== newValue) { - updateShow(child, child._children, isShowing); - } + farValue = CesiumMath.clamp(farValue, 0.0, 1.0); + farValue = farValue === 1.0 ? 255.0 : (farValue * 255.0) | 0; + compressed1 = compressed1 * LEFT_SHIFT8 + farValue; + + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, compressed0, compressed1, near, far); + } else { + i = billboard._index * 4; + writer(i + 0, compressed0, compressed1, near, far); + writer(i + 1, compressed0, compressed1, near, far); + writer(i + 2, compressed0, compressed1, near, far); + writer(i + 3, compressed0, compressed1, near, far); } - entity._definitionChanged.raiseEvent(entity, 'isShowing', isShowing, !isShowing); } - defineProperties(Entity.prototype, { - /** - * The availability, if any, associated with this object. - * If availability is undefined, it is assumed that this object's - * other properties will return valid data for any provided time. - * If availability exists, the objects other properties will only - * provide valid data if queried within the given interval. - * @memberof Entity.prototype - * @type {TimeIntervalCollection} - */ - availability : createRawPropertyDescriptor('availability'), - /** - * Gets the unique ID associated with this object. - * @memberof Entity.prototype - * @type {String} - */ - id : { - get : function() { - return this._id; - } - }, - /** - * Gets the event that is raised whenever a property or sub-property is changed or modified. - * @memberof Entity.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets or sets the name of the object. The name is intended for end-user - * consumption and does not need to be unique. - * @memberof Entity.prototype - * @type {String} - */ - name : createRawPropertyDescriptor('name'), - /** - * Gets or sets whether this entity should be displayed. When set to true, - * the entity is only displayed if the parent entity's show property is also true. - * @memberof Entity.prototype - * @type {Boolean} - */ - show : { - get : function() { - return this._show; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (value === this._show) { - return; - } + function writeCompressedAttrib2(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.compressedAttribute2]; + var color = billboard.color; + var pickColor = !defined(billboardCollection._batchTable) ? billboard.getPickId(context).color : Color.WHITE; + var sizeInMeters = billboard.sizeInMeters ? 1.0 : 0.0; + var validAlignedAxis = Math.abs(Cartesian3.magnitudeSquared(billboard.alignedAxis) - 1.0) < CesiumMath.EPSILON6 ? 1.0 : 0.0; - var wasShowing = this.isShowing; - this._show = value; - var isShowing = this.isShowing; + billboardCollection._allSizedInMeters = billboardCollection._allSizedInMeters && sizeInMeters === 1.0; - if (wasShowing !== isShowing) { - updateShow(this, this._children, isShowing); - } + var height = 0; + var index = billboard._imageIndex; + if (index !== -1) { + var imageRectangle = textureAtlasCoordinates[index]; - this._definitionChanged.raiseEvent(this, 'show', value, !value); - } - }, - /** - * Gets whether this entity is being displayed, taking into account - * the visibility of any ancestor entities. - * @memberof Entity.prototype - * @type {Boolean} - */ - isShowing : { - get : function() { - return this._show && (!defined(this.entityCollection) || this.entityCollection.show) && (!defined(this._parent) || this._parent.isShowing); + if (!defined(imageRectangle)) { + throw new DeveloperError('Invalid billboard image index: ' + index); } - }, - /** - * Gets or sets the parent object. - * @memberof Entity.prototype - * @type {Entity} - */ - parent : { - get : function() { - return this._parent; - }, - set : function(value) { - var oldValue = this._parent; + + height = imageRectangle.height; + } - if (oldValue === value) { - return; - } + var dimensions = billboardCollection._textureAtlas.texture.dimensions; + var imageHeight = Math.round(defaultValue(billboard.height, dimensions.y * height)); + billboardCollection._maxSize = Math.max(billboardCollection._maxSize, imageHeight); - var wasShowing = this.isShowing; - if (defined(oldValue)) { - var index = oldValue._children.indexOf(this); - oldValue._children.splice(index, 1); - } + var red = Color.floatToByte(color.red); + var green = Color.floatToByte(color.green); + var blue = Color.floatToByte(color.blue); + var compressed0 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; - this._parent = value; - if (defined(value)) { - value._children.push(this); - } + red = Color.floatToByte(pickColor.red); + green = Color.floatToByte(pickColor.green); + blue = Color.floatToByte(pickColor.blue); + var compressed1 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; - var isShowing = this.isShowing; + var compressed2 = Color.floatToByte(color.alpha) * LEFT_SHIFT16 + Color.floatToByte(pickColor.alpha) * LEFT_SHIFT8; + compressed2 += sizeInMeters * 2.0 + validAlignedAxis; - if (wasShowing !== isShowing) { - updateShow(this, this._children, isShowing); - } + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, compressed0, compressed1, compressed2, imageHeight); + } else { + i = billboard._index * 4; + writer(i + 0, compressed0, compressed1, compressed2, imageHeight); + writer(i + 1, compressed0, compressed1, compressed2, imageHeight); + writer(i + 2, compressed0, compressed1, compressed2, imageHeight); + writer(i + 3, compressed0, compressed1, compressed2, imageHeight); + } + } - this._definitionChanged.raiseEvent(this, 'parent', value, oldValue); - } - }, - /** - * Gets the names of all properties registered on this instance. - * @memberof Entity.prototype - * @type {Array} - */ - propertyNames : { - get : function() { - return this._propertyNames; - } - }, - /** - * Gets or sets the billboard. - * @memberof Entity.prototype - * @type {BillboardGraphics} - */ - billboard : createPropertyTypeDescriptor('billboard', BillboardGraphics), - /** - * Gets or sets the box. - * @memberof Entity.prototype - * @type {BoxGraphics} - */ - box : createPropertyTypeDescriptor('box', BoxGraphics), - /** - * Gets or sets the corridor. - * @memberof Entity.prototype - * @type {CorridorGraphics} - */ - corridor : createPropertyTypeDescriptor('corridor', CorridorGraphics), - /** - * Gets or sets the cylinder. - * @memberof Entity.prototype - * @type {CylinderGraphics} - */ - cylinder : createPropertyTypeDescriptor('cylinder', CylinderGraphics), - /** - * Gets or sets the description. - * @memberof Entity.prototype - * @type {Property} - */ - description : createPropertyDescriptor('description'), - /** - * Gets or sets the ellipse. - * @memberof Entity.prototype - * @type {EllipseGraphics} - */ - ellipse : createPropertyTypeDescriptor('ellipse', EllipseGraphics), - /** - * Gets or sets the ellipsoid. - * @memberof Entity.prototype - * @type {EllipsoidGraphics} - */ - ellipsoid : createPropertyTypeDescriptor('ellipsoid', EllipsoidGraphics), - /** - * Gets or sets the label. - * @memberof Entity.prototype - * @type {LabelGraphics} - */ - label : createPropertyTypeDescriptor('label', LabelGraphics), - /** - * Gets or sets the model. - * @memberof Entity.prototype - * @type {ModelGraphics} - */ - model : createPropertyTypeDescriptor('model', ModelGraphics), - /** - * Gets or sets the orientation. - * @memberof Entity.prototype - * @type {Property} - */ - orientation : createPropertyDescriptor('orientation'), - /** - * Gets or sets the path. - * @memberof Entity.prototype - * @type {PathGraphics} - */ - path : createPropertyTypeDescriptor('path', PathGraphics), - /** - * Gets or sets the plane. - * @memberof Entity.prototype - * @type {PlaneGraphics} - */ - plane : createPropertyTypeDescriptor('plane', PlaneGraphics), - /** - * Gets or sets the point graphic. - * @memberof Entity.prototype - * @type {PointGraphics} - */ - point : createPropertyTypeDescriptor('point', PointGraphics), - /** - * Gets or sets the polygon. - * @memberof Entity.prototype - * @type {PolygonGraphics} - */ - polygon : createPropertyTypeDescriptor('polygon', PolygonGraphics), - /** - * Gets or sets the polyline. - * @memberof Entity.prototype - * @type {PolylineGraphics} - */ - polyline : createPropertyTypeDescriptor('polyline', PolylineGraphics), - /** - * Gets or sets the polyline volume. - * @memberof Entity.prototype - * @type {PolylineVolumeGraphics} - */ - polylineVolume : createPropertyTypeDescriptor('polylineVolume', PolylineVolumeGraphics), - /** - * Gets or sets the bag of arbitrary properties associated with this entity. - * @memberof Entity.prototype - * @type {PropertyBag} - */ - properties : createPropertyTypeDescriptor('properties', PropertyBag), - /** - * Gets or sets the position. - * @memberof Entity.prototype - * @type {PositionProperty} - */ - position : createPositionPropertyDescriptor('position'), - /** - * Gets or sets the rectangle. - * @memberof Entity.prototype - * @type {RectangleGraphics} - */ - rectangle : createPropertyTypeDescriptor('rectangle', RectangleGraphics), - /** - * Gets or sets the suggested initial offset for viewing this object - * with the camera. The offset is defined in the east-north-up reference frame. - * @memberof Entity.prototype - * @type {Property} - */ - viewFrom : createPropertyDescriptor('viewFrom'), - /** - * Gets or sets the wall. - * @memberof Entity.prototype - * @type {WallGraphics} - */ - wall : createPropertyTypeDescriptor('wall', WallGraphics) - }); + function writeEyeOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.eyeOffset]; + var eyeOffset = billboard.eyeOffset; - /** - * Given a time, returns true if this object should have data during that time. - * - * @param {JulianDate} time The time to check availability for. - * @returns {Boolean} true if the object should have data during the provided time, false otherwise. - */ - Entity.prototype.isAvailable = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + // For billboards that are clamped to ground, move it slightly closer to the camera + var eyeOffsetZ = eyeOffset.z; + if (billboard._heightReference !== HeightReference.NONE) { + eyeOffsetZ *= 1.005; } - - var availability = this._availability; - return !defined(availability) || availability.contains(time); - }; + billboardCollection._maxEyeOffset = Math.max(billboardCollection._maxEyeOffset, Math.abs(eyeOffset.x), Math.abs(eyeOffset.y), Math.abs(eyeOffsetZ)); - /** - * Adds a property to this object. Once a property is added, it can be - * observed with {@link Entity#definitionChanged} and composited - * with {@link CompositeEntityCollection} - * - * @param {String} propertyName The name of the property to add. - * - * @exception {DeveloperError} "propertyName" is a reserved property name. - * @exception {DeveloperError} "propertyName" is already a registered property. - */ - Entity.prototype.addProperty = function(propertyName) { - var propertyNames = this._propertyNames; + if (billboardCollection._instanced) { + var width = 0; + var height = 0; + var index = billboard._imageIndex; + if (index !== -1) { + var imageRectangle = textureAtlasCoordinates[index]; - if (!defined(propertyName)) { - throw new DeveloperError('propertyName is required.'); + if (!defined(imageRectangle)) { + throw new DeveloperError('Invalid billboard image index: ' + index); + } + + width = imageRectangle.width; + height = imageRectangle.height; + } + + scratchCartesian2.x = width; + scratchCartesian2.y = height; + var compressedTexCoordsRange = AttributeCompression.compressTextureCoordinates(scratchCartesian2); + + i = billboard._index; + writer(i, eyeOffset.x, eyeOffset.y, eyeOffsetZ, compressedTexCoordsRange); + } else { + i = billboard._index * 4; + writer(i + 0, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); + writer(i + 1, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); + writer(i + 2, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); + writer(i + 3, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); } - if (propertyNames.indexOf(propertyName) !== -1) { - throw new DeveloperError(propertyName + ' is already a registered property.'); + } + + function writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.scaleByDistance]; + var near = 0.0; + var nearValue = 1.0; + var far = 1.0; + var farValue = 1.0; + + var scale = billboard.scaleByDistance; + if (defined(scale)) { + near = scale.near; + nearValue = scale.nearValue; + far = scale.far; + farValue = scale.farValue; + + if (nearValue !== 1.0 || farValue !== 1.0) { + // scale by distance calculation in shader need not be enabled + // until a billboard with near and far !== 1.0 is found + billboardCollection._shaderScaleByDistance = true; + } } - if (propertyName in this) { - throw new DeveloperError(propertyName + ' is a reserved property name.'); + + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, near, nearValue, far, farValue); + } else { + i = billboard._index * 4; + writer(i + 0, near, nearValue, far, farValue); + writer(i + 1, near, nearValue, far, farValue); + writer(i + 2, near, nearValue, far, farValue); + writer(i + 3, near, nearValue, far, farValue); } - - propertyNames.push(propertyName); - Object.defineProperty(this, propertyName, createRawPropertyDescriptor(propertyName, true)); - }; + } - /** - * Removed a property previously added with addProperty. - * - * @param {String} propertyName The name of the property to remove. - * - * @exception {DeveloperError} "propertyName" is a reserved property name. - * @exception {DeveloperError} "propertyName" is not a registered property. - */ - Entity.prototype.removeProperty = function(propertyName) { - var propertyNames = this._propertyNames; - var index = propertyNames.indexOf(propertyName); + function writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.pixelOffsetScaleByDistance]; + var near = 0.0; + var nearValue = 1.0; + var far = 1.0; + var farValue = 1.0; - if (!defined(propertyName)) { - throw new DeveloperError('propertyName is required.'); - } - if (index === -1) { - throw new DeveloperError(propertyName + ' is not a registered property.'); + var pixelOffsetScale = billboard.pixelOffsetScaleByDistance; + if (defined(pixelOffsetScale)) { + near = pixelOffsetScale.near; + nearValue = pixelOffsetScale.nearValue; + far = pixelOffsetScale.far; + farValue = pixelOffsetScale.farValue; + + if (nearValue !== 1.0 || farValue !== 1.0) { + // pixelOffsetScale by distance calculation in shader need not be enabled + // until a billboard with near and far !== 1.0 is found + billboardCollection._shaderPixelOffsetScaleByDistance = true; + } } - - this._propertyNames.splice(index, 1); - delete this[propertyName]; - }; - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {Entity} source The object to be merged into this object. - */ - Entity.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, near, nearValue, far, farValue); + } else { + i = billboard._index * 4; + writer(i + 0, near, nearValue, far, farValue); + writer(i + 1, near, nearValue, far, farValue); + writer(i + 2, near, nearValue, far, farValue); + writer(i + 3, near, nearValue, far, farValue); } - - //Name, show, and availability are not Property objects and are currently handled differently. - //source.show is intentionally ignored because this.show always has a value. - this.name = defaultValue(this.name, source.name); - this.availability = defaultValue(source.availability, this.availability); + } - var propertyNames = this._propertyNames; - var sourcePropertyNames = defined(source._propertyNames) ? source._propertyNames : Object.keys(source); - var propertyNamesLength = sourcePropertyNames.length; - for (var i = 0; i < propertyNamesLength; i++) { - var name = sourcePropertyNames[i]; + function writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + var i; + var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth]; + var near = 0.0; + var far = Number.MAX_VALUE; - //Ignore parent when merging, this only happens at construction time. - if (name === 'parent') { - continue; - } + var distanceDisplayCondition = billboard.distanceDisplayCondition; + if (defined(distanceDisplayCondition)) { + near = distanceDisplayCondition.near; + far = distanceDisplayCondition.far; - var targetProperty = this[name]; - var sourceProperty = source[name]; + near *= near; + far *= far; - //Custom properties that are registered on the source entity must also - //get registered on this entity. - if (!defined(targetProperty) && propertyNames.indexOf(name) === -1) { - this.addProperty(name); - } + billboardCollection._shaderDistanceDisplayCondition = true; + } - if (defined(sourceProperty)) { - if (defined(targetProperty)) { - if (defined(targetProperty.merge)) { - targetProperty.merge(sourceProperty); - } - } else if (defined(sourceProperty.merge) && defined(sourceProperty.clone)) { - this[name] = sourceProperty.clone(); - } else { - this[name] = sourceProperty; - } + var disableDepthTestDistance = billboard.disableDepthTestDistance; + disableDepthTestDistance *= disableDepthTestDistance; + if (disableDepthTestDistance > 0.0) { + billboardCollection._shaderDisableDepthDistance = true; + if (disableDepthTestDistance === Number.POSITIVE_INFINITY) { + disableDepthTestDistance = -1.0; } } - }; - var matrix3Scratch = new Matrix3(); - var positionScratch = new Cartesian3(); - var orientationScratch = new Quaternion(); + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, near, far, disableDepthTestDistance); + } else { + i = billboard._index * 4; + writer(i + 0, near, far, disableDepthTestDistance); + writer(i + 1, near, far, disableDepthTestDistance); + writer(i + 2, near, far, disableDepthTestDistance); + writer(i + 3, near, far, disableDepthTestDistance); + } + } - /** - * Computes the model matrix for the entity's transform at specified time. Returns undefined if orientation or position - * are undefined. - * - * @param {JulianDate} time The time to retrieve model matrix for. - * @param {Matrix4} [result] The object onto which to store the result. - * - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. Result is undefined if position or orientation are undefined. - */ - Entity.prototype.computeModelMatrix = function(time, result) { - Check.typeOf.object('time', time); - var position = Property.getValueOrUndefined(this._position, time, positionScratch); - if (!defined(position)) { - return undefined; + function writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + if (!defined(billboardCollection._batchTable)) { + return; } - var orientation = Property.getValueOrUndefined(this._orientation, time, orientationScratch); - if (!defined(orientation)) { - result = Transforms.eastNorthUpToFixedFrame(position, undefined, result); + + var writer = vafWriters[attributeLocations.a_batchId]; + var id = billboard._batchIndex; + + var i; + if (billboardCollection._instanced) { + i = billboard._index; + writer(i, id); } else { - result = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation, matrix3Scratch), position, result); + i = billboard._index * 4; + writer(i + 0, id); + writer(i + 1, id); + writer(i + 2, id); + writer(i + 3, id); } - return result; - }; + } - return Entity; -}); + function writeBillboard(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + writePositionScaleAndRotation(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeCompressedAttrib0(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeCompressedAttrib1(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeCompressedAttrib2(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeEyeOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + } -define('DataSources/EntityCollection',[ - '../Core/AssociativeArray', - '../Core/createGuid', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/Iso8601', - '../Core/JulianDate', - '../Core/RuntimeError', - '../Core/TimeInterval', - './Entity' - ], function( - AssociativeArray, - createGuid, - defined, - defineProperties, - DeveloperError, - Event, - Iso8601, - JulianDate, - RuntimeError, - TimeInterval, - Entity) { - 'use strict'; + function recomputeActualPositions(billboardCollection, billboards, length, frameState, modelMatrix, recomputeBoundingVolume) { + var boundingVolume; + if (frameState.mode === SceneMode.SCENE3D) { + boundingVolume = billboardCollection._baseVolume; + billboardCollection._boundingVolumeDirty = true; + } else { + boundingVolume = billboardCollection._baseVolume2D; + } - var entityOptionsScratch = { - id : undefined - }; + var positions = []; + for ( var i = 0; i < length; ++i) { + var billboard = billboards[i]; + var position = billboard.position; + var actualPosition = Billboard._computeActualPosition(billboard, position, frameState, modelMatrix); + if (defined(actualPosition)) { + billboard._setActualPosition(actualPosition); - function fireChangedEvent(collection) { - if (collection._firing) { - collection._refire = true; - return; + if (recomputeBoundingVolume) { + positions.push(actualPosition); + } else { + BoundingSphere.expand(boundingVolume, actualPosition, boundingVolume); + } + } } - if (collection._suspendCount === 0) { - var added = collection._addedEntities; - var removed = collection._removedEntities; - var changed = collection._changedEntities; - if (changed.length !== 0 || added.length !== 0 || removed.length !== 0) { - collection._firing = true; - do { - collection._refire = false; - var addedArray = added.values.slice(0); - var removedArray = removed.values.slice(0); - var changedArray = changed.values.slice(0); + if (recomputeBoundingVolume) { + BoundingSphere.fromPoints(positions, boundingVolume); + } + } - added.removeAll(); - removed.removeAll(); - changed.removeAll(); - collection._collectionChanged.raiseEvent(collection, addedArray, removedArray, changedArray); - } while (collection._refire); - collection._firing = false; + function updateMode(billboardCollection, frameState) { + var mode = frameState.mode; + + var billboards = billboardCollection._billboards; + var billboardsToUpdate = billboardCollection._billboardsToUpdate; + var modelMatrix = billboardCollection._modelMatrix; + + if (billboardCollection._createVertexArray || + billboardCollection._mode !== mode || + mode !== SceneMode.SCENE3D && + !Matrix4.equals(modelMatrix, billboardCollection.modelMatrix)) { + + billboardCollection._mode = mode; + Matrix4.clone(billboardCollection.modelMatrix, modelMatrix); + billboardCollection._createVertexArray = true; + + if (mode === SceneMode.SCENE3D || mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { + recomputeActualPositions(billboardCollection, billboards, billboards.length, frameState, modelMatrix, true); } + } else if (mode === SceneMode.MORPHING) { + recomputeActualPositions(billboardCollection, billboards, billboards.length, frameState, modelMatrix, true); + } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { + recomputeActualPositions(billboardCollection, billboardsToUpdate, billboardCollection._billboardsToUpdateIndex, frameState, modelMatrix, false); } } - /** - * An observable collection of {@link Entity} instances where each entity has a unique id. - * @alias EntityCollection - * @constructor - * - * @param {DataSource|CompositeEntityCollection} [owner] The data source (or composite entity collection) which created this collection. - */ - function EntityCollection(owner) { - this._owner = owner; - this._entities = new AssociativeArray(); - this._addedEntities = new AssociativeArray(); - this._removedEntities = new AssociativeArray(); - this._changedEntities = new AssociativeArray(); - this._suspendCount = 0; - this._collectionChanged = new Event(); - this._id = createGuid(); - this._show = true; - this._firing = false; - this._refire = false; + function updateBoundingVolume(collection, frameState, boundingVolume) { + var pixelScale = 1.0; + if (!collection._allSizedInMeters || collection._maxPixelOffset !== 0.0) { + pixelScale = frameState.camera.getPixelSize(boundingVolume, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); + } + + var size = pixelScale * collection._maxScale * collection._maxSize * 2.0; + if (collection._allHorizontalCenter && collection._allVerticalCenter ) { + size *= 0.5; + } + + var offset = pixelScale * collection._maxPixelOffset + collection._maxEyeOffset; + boundingVolume.radius += size + offset; } - /** - * Prevents {@link EntityCollection#collectionChanged} events from being raised - * until a corresponding call is made to {@link EntityCollection#resumeEvents}, at which - * point a single event will be raised that covers all suspended operations. - * This allows for many items to be added and removed efficiently. - * This function can be safely called multiple times as long as there - * are corresponding calls to {@link EntityCollection#resumeEvents}. - */ - EntityCollection.prototype.suspendEvents = function() { - this._suspendCount++; - }; + var scratchWriterArray = []; /** - * Resumes raising {@link EntityCollection#collectionChanged} events immediately - * when an item is added or removed. Any modifications made while while events were suspended - * will be triggered as a single event when this function is called. - * This function is reference counted and can safely be called multiple times as long as there - * are corresponding calls to {@link EntityCollection#resumeEvents}. + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> * - * @exception {DeveloperError} resumeEvents can not be called before suspendEvents. + * @exception {RuntimeError} image with id must be in the atlas. */ - EntityCollection.prototype.resumeEvents = function() { - if (this._suspendCount === 0) { - throw new DeveloperError('resumeEvents can not be called before suspendEvents.'); - } - - this._suspendCount--; - fireChangedEvent(this); - }; + BillboardCollection.prototype.update = function(frameState) { + removeBillboards(this); + var billboards = this._billboards; + var billboardsLength = billboards.length; - /** - * The signature of the event generated by {@link EntityCollection#collectionChanged}. - * @function - * - * @param {EntityCollection} collection The collection that triggered the event. - * @param {Entity[]} added The array of {@link Entity} instances that have been added to the collection. - * @param {Entity[]} removed The array of {@link Entity} instances that have been removed from the collection. - * @param {Entity[]} changed The array of {@link Entity} instances that have been modified. - */ - EntityCollection.collectionChangedEventCallback = undefined; + var context = frameState.context; + this._instanced = context.instancedArrays; + attributeLocations = this._instanced ? attributeLocationsInstanced : attributeLocationsBatched; + getIndexBuffer = this._instanced ? getIndexBufferInstanced : getIndexBufferBatched; - defineProperties(EntityCollection.prototype, { - /** - * Gets the event that is fired when entities are added or removed from the collection. - * The generated event is a {@link EntityCollection.collectionChangedEventCallback}. - * @memberof EntityCollection.prototype - * @readonly - * @type {Event} - */ - collectionChanged : { - get : function() { - return this._collectionChanged; - } - }, - /** - * Gets a globally unique identifier for this collection. - * @memberof EntityCollection.prototype - * @readonly - * @type {String} - */ - id : { - get : function() { - return this._id; - } - }, - /** - * Gets the array of Entity instances in the collection. - * This array should not be modified directly. - * @memberof EntityCollection.prototype - * @readonly - * @type {Entity[]} - */ - values : { - get : function() { - return this._entities.values; + var textureAtlas = this._textureAtlas; + if (!defined(textureAtlas)) { + textureAtlas = this._textureAtlas = new TextureAtlas({ + context : context + }); + + for (var ii = 0; ii < billboardsLength; ++ii) { + billboards[ii]._loadImage(); } - }, - /** - * Gets whether or not this entity collection should be - * displayed. When true, each entity is only displayed if - * its own show property is also true. - * @memberof EntityCollection.prototype - * @type {Boolean} - */ - show : { - get : function() { - return this._show; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (value === this._show) { - return; - } + } + + var textureAtlasCoordinates = textureAtlas.textureCoordinates; + if (textureAtlasCoordinates.length === 0) { + // Can't write billboard vertices until we have texture coordinates + // provided by a texture atlas + return; + } + + updateMode(this, frameState); + + billboards = this._billboards; + billboardsLength = billboards.length; + var billboardsToUpdate = this._billboardsToUpdate; + var billboardsToUpdateLength = this._billboardsToUpdateIndex; + + var properties = this._propertiesChanged; + + var textureAtlasGUID = textureAtlas.guid; + var createVertexArray = this._createVertexArray || this._textureAtlasGUID !== textureAtlasGUID; + this._textureAtlasGUID = textureAtlasGUID; + + var vafWriters; + var pass = frameState.passes; + var picking = pass.pick; - //Since entity.isShowing includes the EntityCollection.show state - //in its calculation, we need to loop over the entities array - //twice, once to get the old showing value and a second time - //to raise the changed event. - this.suspendEvents(); + // PERFORMANCE_IDEA: Round robin multiple buffers. + if (createVertexArray || (!picking && this.computeNewBuffersUsage())) { + this._createVertexArray = false; - var i; - var oldShows = []; - var entities = this._entities.values; - var entitiesLength = entities.length; + for (var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { + properties[k] = 0; + } - for (i = 0; i < entitiesLength; i++) { - oldShows.push(entities[i].isShowing); - } + this._vaf = this._vaf && this._vaf.destroy(); - this._show = value; + if (billboardsLength > 0) { + // PERFORMANCE_IDEA: Instead of creating a new one, resize like std::vector. + this._vaf = createVAF(context, billboardsLength, this._buffersUsage, this._instanced, this._batchTable); + vafWriters = this._vaf.writers; - for (i = 0; i < entitiesLength; i++) { - var oldShow = oldShows[i]; - var entity = entities[i]; - if (oldShow !== entity.isShowing) { - entity.definitionChanged.raiseEvent(entity, 'isShowing', entity.isShowing, oldShow); - } + // Rewrite entire buffer if billboards were added or removed. + for (var i = 0; i < billboardsLength; ++i) { + var billboard = this._billboards[i]; + billboard._dirty = false; // In case it needed an update. + writeBillboard(this, context, textureAtlasCoordinates, vafWriters, billboard); } - this.resumeEvents(); + // Different billboard collections share the same index buffer. + this._vaf.commit(getIndexBuffer(context)); } - }, - /** - * Gets the owner of this entity collection, ie. the data source or composite entity collection which created it. - * @memberof EntityCollection.prototype - * @readonly - * @type {DataSource|CompositeEntityCollection} - */ - owner : { - get : function() { - return this._owner; + + this._billboardsToUpdateIndex = 0; + } else if (billboardsToUpdateLength > 0) { + // Billboards were modified, but none were added or removed. + var writers = scratchWriterArray; + writers.length = 0; + + if (properties[POSITION_INDEX] || properties[ROTATION_INDEX] || properties[SCALE_INDEX]) { + writers.push(writePositionScaleAndRotation); } - } - }); - /** - * Computes the maximum availability of the entities in the collection. - * If the collection contains a mix of infinitely available data and non-infinite data, - * it will return the interval pertaining to the non-infinite data only. If all - * data is infinite, an infinite interval will be returned. - * - * @returns {TimeInterval} The availability of entities in the collection. - */ - EntityCollection.prototype.computeAvailability = function() { - var startTime = Iso8601.MAXIMUM_VALUE; - var stopTime = Iso8601.MINIMUM_VALUE; - var entities = this._entities.values; - for (var i = 0, len = entities.length; i < len; i++) { - var entity = entities[i]; - var availability = entity.availability; - if (defined(availability)) { - var start = availability.start; - var stop = availability.stop; - if (JulianDate.lessThan(start, startTime) && !start.equals(Iso8601.MINIMUM_VALUE)) { - startTime = start; - } - if (JulianDate.greaterThan(stop, stopTime) && !stop.equals(Iso8601.MAXIMUM_VALUE)) { - stopTime = stop; + if (properties[IMAGE_INDEX_INDEX] || properties[PIXEL_OFFSET_INDEX] || properties[HORIZONTAL_ORIGIN_INDEX] || properties[VERTICAL_ORIGIN_INDEX] || properties[SHOW_INDEX]) { + writers.push(writeCompressedAttrib0); + if (this._instanced) { + writers.push(writeEyeOffset); } } - } - - if (Iso8601.MAXIMUM_VALUE.equals(startTime)) { - startTime = Iso8601.MINIMUM_VALUE; - } - if (Iso8601.MINIMUM_VALUE.equals(stopTime)) { - stopTime = Iso8601.MAXIMUM_VALUE; - } - return new TimeInterval({ - start : startTime, - stop : stopTime - }); - }; - - /** - * Add an entity to the collection. - * - * @param {Entity} entity The entity to be added. - * @returns {Entity} The entity that was added. - * @exception {DeveloperError} An entity with <entity.id> already exists in this collection. - */ - EntityCollection.prototype.add = function(entity) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); - } - - if (!(entity instanceof Entity)) { - entity = new Entity(entity); - } - var id = entity.id; - var entities = this._entities; - if (entities.contains(id)) { - throw new RuntimeError('An entity with id ' + id + ' already exists in this collection.'); - } + if (properties[IMAGE_INDEX_INDEX] || properties[ALIGNED_AXIS_INDEX] || properties[TRANSLUCENCY_BY_DISTANCE_INDEX]) { + writers.push(writeCompressedAttrib1); + writers.push(writeCompressedAttrib2); + } - entity.entityCollection = this; - entities.set(id, entity); + if (properties[IMAGE_INDEX_INDEX] || properties[COLOR_INDEX]) { + writers.push(writeCompressedAttrib2); + } - if (!this._removedEntities.remove(id)) { - this._addedEntities.set(id, entity); - } - entity.definitionChanged.addEventListener(EntityCollection.prototype._onEntityDefinitionChanged, this); + if (properties[EYE_OFFSET_INDEX]) { + writers.push(writeEyeOffset); + } - fireChangedEvent(this); - return entity; - }; + if (properties[SCALE_BY_DISTANCE_INDEX]) { + writers.push(writeScaleByDistance); + } - /** - * Removes an entity from the collection. - * - * @param {Entity} entity The entity to be removed. - * @returns {Boolean} true if the item was removed, false if it did not exist in the collection. - */ - EntityCollection.prototype.remove = function(entity) { - if (!defined(entity)) { - return false; - } - return this.removeById(entity.id); - }; + if (properties[PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX]) { + writers.push(writePixelOffsetScaleByDistance); + } - /** - * Returns true if the provided entity is in this collection, false otherwise. - * - * @param {Entity} entity The entity. - * @returns {Boolean} true if the provided entity is in this collection, false otherwise. - */ - EntityCollection.prototype.contains = function(entity) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - return this._entities.get(entity.id) === entity; - }; + if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE]) { + writers.push(writeDistanceDisplayConditionAndDepthDisable); + } - /** - * Removes an entity with the provided id from the collection. - * - * @param {String} id The id of the entity to remove. - * @returns {Boolean} true if the item was removed, false if no item with the provided id existed in the collection. - */ - EntityCollection.prototype.removeById = function(id) { - if (!defined(id)) { - return false; - } + var numWriters = writers.length; + vafWriters = this._vaf.writers; - var entities = this._entities; - var entity = entities.get(id); - if (!this._entities.remove(id)) { - return false; - } + if ((billboardsToUpdateLength / billboardsLength) > 0.1) { + // If more than 10% of billboard change, rewrite the entire buffer. - if (!this._addedEntities.remove(id)) { - this._removedEntities.set(id, entity); - this._changedEntities.remove(id); - } - this._entities.remove(id); - entity.definitionChanged.removeEventListener(EntityCollection.prototype._onEntityDefinitionChanged, this); - fireChangedEvent(this); + // PERFORMANCE_IDEA: I totally made up 10% :). - return true; - }; + for (var m = 0; m < billboardsToUpdateLength; ++m) { + var b = billboardsToUpdate[m]; + b._dirty = false; - /** - * Removes all Entities from the collection. - */ - EntityCollection.prototype.removeAll = function() { - //The event should only contain items added before events were suspended - //and the contents of the collection. - var entities = this._entities; - var entitiesLength = entities.length; - var array = entities.values; + for ( var n = 0; n < numWriters; ++n) { + writers[n](this, context, textureAtlasCoordinates, vafWriters, b); + } + } + this._vaf.commit(getIndexBuffer(context)); + } else { + for (var h = 0; h < billboardsToUpdateLength; ++h) { + var bb = billboardsToUpdate[h]; + bb._dirty = false; - var addedEntities = this._addedEntities; - var removed = this._removedEntities; + for ( var o = 0; o < numWriters; ++o) { + writers[o](this, context, textureAtlasCoordinates, vafWriters, bb); + } - for (var i = 0; i < entitiesLength; i++) { - var existingItem = array[i]; - var existingItemId = existingItem.id; - var addedItem = addedEntities.get(existingItemId); - if (!defined(addedItem)) { - existingItem.definitionChanged.removeEventListener(EntityCollection.prototype._onEntityDefinitionChanged, this); - removed.set(existingItemId, existingItem); + if (this._instanced) { + this._vaf.subCommit(bb._index, 1); + } else { + this._vaf.subCommit(bb._index * 4, 4); + } + } + this._vaf.endSubCommits(); } - } - entities.removeAll(); - addedEntities.removeAll(); - this._changedEntities.removeAll(); - fireChangedEvent(this); - }; + this._billboardsToUpdateIndex = 0; + } - /** - * Gets an entity with the specified id. - * - * @param {String} id The id of the entity to retrieve. - * @returns {Entity} The entity with the provided id or undefined if the id did not exist in the collection. - */ - EntityCollection.prototype.getById = function(id) { - if (!defined(id)) { - throw new DeveloperError('id is required.'); + // If the number of total billboards ever shrinks considerably + // Truncate billboardsToUpdate so that we free memory that we're + // not going to be using. + if (billboardsToUpdateLength > billboardsLength * 1.5) { + billboardsToUpdate.length = billboardsLength; } - - return this._entities.get(id); - }; - /** - * Gets an entity with the specified id or creates it and adds it to the collection if it does not exist. - * - * @param {String} id The id of the entity to retrieve or create. - * @returns {Entity} The new or existing object. - */ - EntityCollection.prototype.getOrCreateEntity = function(id) { - if (!defined(id)) { - throw new DeveloperError('id is required.'); + if (!defined(this._vaf) || !defined(this._vaf.va)) { + return; } - - var entity = this._entities.get(id); - if (!defined(entity)) { - entityOptionsScratch.id = id; - entity = new Entity(entityOptionsScratch); - this.add(entity); + + if (this._boundingVolumeDirty) { + this._boundingVolumeDirty = false; + BoundingSphere.transform(this._baseVolume, this.modelMatrix, this._baseVolumeWC); } - return entity; - }; - EntityCollection.prototype._onEntityDefinitionChanged = function(entity) { - var id = entity.id; - if (!this._addedEntities.contains(id)) { - this._changedEntities.set(id, entity); + var boundingVolume; + var modelMatrix = Matrix4.IDENTITY; + if (frameState.mode === SceneMode.SCENE3D) { + modelMatrix = this.modelMatrix; + boundingVolume = BoundingSphere.clone(this._baseVolumeWC, this._boundingVolume); + } else { + boundingVolume = BoundingSphere.clone(this._baseVolume2D, this._boundingVolume); } - fireChangedEvent(this); - }; + updateBoundingVolume(this, frameState, boundingVolume); - return EntityCollection; -}); + var blendOptionChanged = this._blendOption !== this.blendOption; + this._blendOption = this.blendOption; -define('DataSources/CompositeEntityCollection',[ - '../Core/createGuid', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Math', - './Entity', - './EntityCollection' - ], function( - createGuid, - defined, - defineProperties, - DeveloperError, - CesiumMath, - Entity, - EntityCollection) { - 'use strict'; + if (blendOptionChanged) { + if (this._blendOption === BlendOption.OPAQUE || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { + this._rsOpaque = RenderState.fromCache({ + depthTest : { + enabled : true, + func : WebGLConstants.LESS + }, + depthMask : true + }); + } else { + this._rsOpaque = undefined; + } - var entityOptionsScratch = { - id : undefined - }; - var entityIdScratch = new Array(2); + // If OPAQUE_AND_TRANSLUCENT is in use, only the opaque pass gets the benefit of the depth buffer, + // not the translucent pass. Otherwise, if the TRANSLUCENT pass is on its own, it turns on + // a depthMask in lieu of full depth sorting (because it has opaque-ish fragments that look bad in OIT). + // When the TRANSLUCENT depth mask is in use, label backgrounds require the depth func to be LEQUAL. + var useTranslucentDepthMask = this._blendOption === BlendOption.TRANSLUCENT; - function clean(entity) { - var propertyNames = entity.propertyNames; - var propertyNamesLength = propertyNames.length; - for (var i = 0; i < propertyNamesLength; i++) { - entity[propertyNames[i]] = undefined; + if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { + this._rsTranslucent = RenderState.fromCache({ + depthTest : { + enabled : true, + func : (useTranslucentDepthMask ? WebGLConstants.LEQUAL : WebGLConstants.LESS) + }, + depthMask : useTranslucentDepthMask, + blending : BlendingState.ALPHA_BLEND + }); + } else { + this._rsTranslucent = undefined; + } } - } - function subscribeToEntity(that, eventHash, collectionId, entity) { - entityIdScratch[0] = collectionId; - entityIdScratch[1] = entity.id; - eventHash[JSON.stringify(entityIdScratch)] = entity.definitionChanged.addEventListener(CompositeEntityCollection.prototype._onDefinitionChanged, that); - } + this._shaderDisableDepthDistance = this._shaderDisableDepthDistance || frameState.minimumDisableDepthTestDistance !== 0.0; - function unsubscribeFromEntity(that, eventHash, collectionId, entity) { - entityIdScratch[0] = collectionId; - entityIdScratch[1] = entity.id; - var id = JSON.stringify(entityIdScratch); - eventHash[id](); - eventHash[id] = undefined; - } + var vsSource; + var fsSource; + var vs; + var fs; + var vertDefines; - function recomposite(that) { - that._shouldRecomposite = true; - if (that._suspendCount !== 0) { - return; - } + if (blendOptionChanged || + (this._shaderRotation !== this._compiledShaderRotation) || + (this._shaderAlignedAxis !== this._compiledShaderAlignedAxis) || + (this._shaderScaleByDistance !== this._compiledShaderScaleByDistance) || + (this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistance) || + (this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistance) || + (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayCondition) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) { - var collections = that._collections; - var collectionsLength = collections.length; + vsSource = BillboardCollectionVS; + fsSource = BillboardCollectionFS; - var collectionsCopy = that._collectionsCopy; - var collectionsCopyLength = collectionsCopy.length; + vertDefines = []; + if (defined(this._batchTable)) { + vertDefines.push('VECTOR_TILE'); + vsSource = this._batchTable.getVertexShaderCallback(false, 'a_batchId', undefined)(vsSource); + fsSource = this._batchTable.getFragmentShaderCallback(false, undefined)(fsSource); + } - var i; - var entity; - var entities; - var iEntities; - var collection; - var composite = that._composite; - var newEntities = new EntityCollection(that); - var eventHash = that._eventHash; - var collectionId; + vs = new ShaderSource({ + defines : vertDefines, + sources : [vsSource] + }); + if (this._instanced) { + vs.defines.push('INSTANCED'); + } + if (this._shaderRotation) { + vs.defines.push('ROTATION'); + } + if (this._shaderAlignedAxis) { + vs.defines.push('ALIGNED_AXIS'); + } + if (this._shaderScaleByDistance) { + vs.defines.push('EYE_DISTANCE_SCALING'); + } + if (this._shaderTranslucencyByDistance) { + vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); + } + if (this._shaderPixelOffsetScaleByDistance) { + vs.defines.push('EYE_DISTANCE_PIXEL_OFFSET'); + } + if (this._shaderDistanceDisplayCondition) { + vs.defines.push('DISTANCE_DISPLAY_CONDITION'); + } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); + } - for (i = 0; i < collectionsCopyLength; i++) { - collection = collectionsCopy[i]; - collection.collectionChanged.removeEventListener(CompositeEntityCollection.prototype._onCollectionChanged, that); - entities = collection.values; - collectionId = collection.id; - for (iEntities = entities.length - 1; iEntities > -1; iEntities--) { - entity = entities[iEntities]; - unsubscribeFromEntity(that, eventHash, collectionId, entity); + var vectorFragDefine = defined(this._batchTable) ? 'VECTOR_TILE' : ''; + + if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { + fs = new ShaderSource({ + defines : ['OPAQUE', vectorFragDefine], + sources : [fsSource] + }); + this._sp = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._sp, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + + fs = new ShaderSource({ + defines : ['TRANSLUCENT', vectorFragDefine], + sources : [fsSource] + }); + this._spTranslucent = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._spTranslucent, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } + + if (this._blendOption === BlendOption.OPAQUE) { + fs = new ShaderSource({ + defines : [vectorFragDefine], + sources : [fsSource] + }); + this._sp = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._sp, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } + + if (this._blendOption === BlendOption.TRANSLUCENT) { + fs = new ShaderSource({ + defines : [vectorFragDefine], + sources : [fsSource] + }); + this._spTranslucent = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._spTranslucent, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); } + + this._compiledShaderRotation = this._shaderRotation; + this._compiledShaderAlignedAxis = this._shaderAlignedAxis; + this._compiledShaderScaleByDistance = this._shaderScaleByDistance; + this._compiledShaderTranslucencyByDistance = this._shaderTranslucencyByDistance; + this._compiledShaderPixelOffsetScaleByDistance = this._shaderPixelOffsetScaleByDistance; + this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance; } - for (i = collectionsLength - 1; i >= 0; i--) { - collection = collections[i]; - collection.collectionChanged.addEventListener(CompositeEntityCollection.prototype._onCollectionChanged, that); + if (!defined(this._spPick) || + (this._shaderRotation !== this._compiledShaderRotationPick) || + (this._shaderAlignedAxis !== this._compiledShaderAlignedAxisPick) || + (this._shaderScaleByDistance !== this._compiledShaderScaleByDistancePick) || + (this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistancePick) || + (this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistancePick) || + (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayConditionPick) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistancePick)) { - //Merge all of the existing entities. - entities = collection.values; - collectionId = collection.id; - for (iEntities = entities.length - 1; iEntities > -1; iEntities--) { - entity = entities[iEntities]; - subscribeToEntity(that, eventHash, collectionId, entity); + vsSource = BillboardCollectionVS; + fsSource = BillboardCollectionFS; - var compositeEntity = newEntities.getById(entity.id); - if (!defined(compositeEntity)) { - compositeEntity = composite.getById(entity.id); - if (!defined(compositeEntity)) { - entityOptionsScratch.id = entity.id; - compositeEntity = new Entity(entityOptionsScratch); - } else { - clean(compositeEntity); - } - newEntities.add(compositeEntity); - } - compositeEntity.merge(entity); + vertDefines = []; + if (defined(this._batchTable)) { + vertDefines.push('VECTOR_TILE'); + vsSource = this._batchTable.getPickVertexShaderCallback('a_batchId')(vsSource); + fsSource = this._batchTable.getPickFragmentShaderCallback()(fsSource); } - } - that._collectionsCopy = collections.slice(0); - composite.suspendEvents(); - composite.removeAll(); - var newEntitiesArray = newEntities.values; - for (i = 0; i < newEntitiesArray.length; i++) { - composite.add(newEntitiesArray[i]); - } - composite.resumeEvents(); - } + vertDefines.push(defined(this._batchTable) ? '' : 'RENDER_FOR_PICK'); - /** - * Non-destructively composites multiple {@link EntityCollection} instances into a single collection. - * If a Entity with the same ID exists in multiple collections, it is non-destructively - * merged into a single new entity instance. If an entity has the same property in multiple - * collections, the property of the Entity in the last collection of the list it - * belongs to is used. CompositeEntityCollection can be used almost anywhere that a - * EntityCollection is used. - * - * @alias CompositeEntityCollection - * @constructor - * - * @param {EntityCollection[]} [collections] The initial list of EntityCollection instances to merge. - * @param {DataSource|CompositeEntityCollection} [owner] The data source (or composite entity collection) which created this collection. - */ - function CompositeEntityCollection(collections, owner) { - this._owner = owner; - this._composite = new EntityCollection(this); - this._suspendCount = 0; - this._collections = defined(collections) ? collections.slice() : []; - this._collectionsCopy = []; - this._id = createGuid(); - this._eventHash = {}; - recomposite(this); - this._shouldRecomposite = false; - } + vs = new ShaderSource({ + defines : vertDefines, + sources : [vsSource] + }); - defineProperties(CompositeEntityCollection.prototype, { - /** - * Gets the event that is fired when entities are added or removed from the collection. - * The generated event is a {@link EntityCollection.collectionChangedEventCallback}. - * @memberof CompositeEntityCollection.prototype - * @readonly - * @type {Event} - */ - collectionChanged : { - get : function() { - return this._composite._collectionChanged; + if(this._instanced) { + vs.defines.push('INSTANCED'); } - }, - /** - * Gets a globally unique identifier for this collection. - * @memberof CompositeEntityCollection.prototype - * @readonly - * @type {String} - */ - id : { - get : function() { - return this._id; + if (this._shaderRotation) { + vs.defines.push('ROTATION'); } - }, - /** - * Gets the array of Entity instances in the collection. - * This array should not be modified directly. - * @memberof CompositeEntityCollection.prototype - * @readonly - * @type {Entity[]} - */ - values : { - get : function() { - return this._composite.values; + if (this._shaderAlignedAxis) { + vs.defines.push('ALIGNED_AXIS'); } - }, - /** - * Gets the owner of this composite entity collection, ie. the data source or composite entity collection which created it. - * @memberof CompositeEntityCollection.prototype - * @readonly - * @type {DataSource|CompositeEntityCollection} - */ - owner : { - get : function() { - return this._owner; + if (this._shaderScaleByDistance) { + vs.defines.push('EYE_DISTANCE_SCALING'); } - } - }); - - /** - * Adds a collection to the composite. - * - * @param {EntityCollection} collection the collection to add. - * @param {Number} [index] the index to add the collection at. If omitted, the collection will - * added on top of all existing collections. - * - * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of collections. - */ - CompositeEntityCollection.prototype.addCollection = function(collection, index) { - var hasIndex = defined(index); - if (!defined(collection)) { - throw new DeveloperError('collection is required.'); - } - if (hasIndex) { - if (index < 0) { - throw new DeveloperError('index must be greater than or equal to zero.'); - } else if (index > this._collections.length) { - throw new DeveloperError('index must be less than or equal to the number of collections.'); + if (this._shaderTranslucencyByDistance) { + vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); + } + if (this._shaderPixelOffsetScaleByDistance) { + vs.defines.push('EYE_DISTANCE_PIXEL_OFFSET'); + } + if (this._shaderDistanceDisplayCondition) { + vs.defines.push('DISTANCE_DISPLAY_CONDITION'); + } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); } - } - - if (!hasIndex) { - index = this._collections.length; - this._collections.push(collection); - } else { - this._collections.splice(index, 0, collection); - } - recomposite(this); - }; + fs = new ShaderSource({ + defines : vertDefines, + sources : [fsSource] + }); - /** - * Removes a collection from this composite, if present. - * - * @param {EntityCollection} collection The collection to remove. - * @returns {Boolean} true if the collection was in the composite and was removed, - * false if the collection was not in the composite. - */ - CompositeEntityCollection.prototype.removeCollection = function(collection) { - var index = this._collections.indexOf(collection); - if (index !== -1) { - this._collections.splice(index, 1); - recomposite(this); - return true; + this._spPick = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._spPick, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + this._compiledShaderRotationPick = this._shaderRotation; + this._compiledShaderAlignedAxisPick = this._shaderAlignedAxis; + this._compiledShaderScaleByDistancePick = this._shaderScaleByDistance; + this._compiledShaderTranslucencyByDistancePick = this._shaderTranslucencyByDistance; + this._compiledShaderPixelOffsetScaleByDistancePick = this._shaderPixelOffsetScaleByDistance; + this._compiledShaderDistanceDisplayConditionPick = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistancePick = this._shaderDisableDepthDistance; } - return false; - }; - - /** - * Removes all collections from this composite. - */ - CompositeEntityCollection.prototype.removeAllCollections = function() { - this._collections.length = 0; - recomposite(this); - }; - /** - * Checks to see if the composite contains a given collection. - * - * @param {EntityCollection} collection the collection to check for. - * @returns {Boolean} true if the composite contains the collection, false otherwise. - */ - CompositeEntityCollection.prototype.containsCollection = function(collection) { - return this._collections.indexOf(collection) !== -1; - }; + var va; + var vaLength; + var command; + var uniforms; + var j; - /** - * Returns true if the provided entity is in this collection, false otherwise. - * - * @param {Entity} entity The entity. - * @returns {Boolean} true if the provided entity is in this collection, false otherwise. - */ - CompositeEntityCollection.prototype.contains = function(entity) { - return this._composite.contains(entity); - }; + var commandList = frameState.commandList; - /** - * Determines the index of a given collection in the composite. - * - * @param {EntityCollection} collection The collection to find the index of. - * @returns {Number} The index of the collection in the composite, or -1 if the collection does not exist in the composite. - */ - CompositeEntityCollection.prototype.indexOfCollection = function(collection) { - return this._collections.indexOf(collection); - }; + if (pass.render) { + var colorList = this._colorCommands; - /** - * Gets a collection by index from the composite. - * - * @param {Number} index the index to retrieve. - */ - CompositeEntityCollection.prototype.getCollection = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.', 'index'); - } - - return this._collections[index]; - }; + var opaque = this._blendOption === BlendOption.OPAQUE; + var opaqueAndTranslucent = this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT; - /** - * Gets the number of collections in this composite. - */ - CompositeEntityCollection.prototype.getCollectionsLength = function() { - return this._collections.length; - }; + va = this._vaf.va; + vaLength = va.length; - function getCollectionIndex(collections, collection) { - if (!defined(collection)) { - throw new DeveloperError('collection is required.'); - } - - var index = collections.indexOf(collection); + uniforms = this._uniforms; + if (defined(this._batchTable)) { + uniforms = this._batchTable.getUniformMapCallback()(uniforms); + } - if (index === -1) { - throw new DeveloperError('collection is not in this composite.'); - } - - return index; - } + colorList.length = vaLength; + var totalLength = opaqueAndTranslucent ? vaLength * 2 : vaLength; + for (j = 0; j < totalLength; ++j) { + command = colorList[j]; + if (!defined(command)) { + command = colorList[j] = new DrawCommand(); + } - function swapCollections(composite, i, j) { - var arr = composite._collections; - i = CesiumMath.clamp(i, 0, arr.length - 1); - j = CesiumMath.clamp(j, 0, arr.length - 1); + var opaqueCommand = opaque || (opaqueAndTranslucent && j % 2 === 0); - if (i === j) { - return; - } + command.pass = opaqueCommand || !opaqueAndTranslucent ? Pass.OPAQUE : Pass.TRANSLUCENT; + command.owner = this; - var temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; + var index = opaqueAndTranslucent ? Math.floor(j / 2.0) : j; + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.count = va[index].indicesCount; + command.shaderProgram = opaqueCommand ? this._sp : this._spTranslucent; + command.uniformMap = uniforms; + command.vertexArray = va[index].va; + command.renderState = opaqueCommand ? this._rsOpaque : this._rsTranslucent; + command.debugShowBoundingVolume = this.debugShowBoundingVolume; - recomposite(composite); - } + if (this._instanced) { + command.count = 6; + command.instanceCount = billboardsLength; + } - /** - * Raises a collection up one position in the composite. - * - * @param {EntityCollection} collection the collection to move. - * - * @exception {DeveloperError} collection is not in this composite. - */ - CompositeEntityCollection.prototype.raiseCollection = function(collection) { - var index = getCollectionIndex(this._collections, collection); - swapCollections(this, index, index + 1); - }; + commandList.push(command); + } + } - /** - * Lowers a collection down one position in the composite. - * - * @param {EntityCollection} collection the collection to move. - * - * @exception {DeveloperError} collection is not in this composite. - */ - CompositeEntityCollection.prototype.lowerCollection = function(collection) { - var index = getCollectionIndex(this._collections, collection); - swapCollections(this, index, index - 1); - }; + if (picking) { + var pickList = this._pickCommands; - /** - * Raises a collection to the top of the composite. - * - * @param {EntityCollection} collection the collection to move. - * - * @exception {DeveloperError} collection is not in this composite. - */ - CompositeEntityCollection.prototype.raiseCollectionToTop = function(collection) { - var index = getCollectionIndex(this._collections, collection); - if (index === this._collections.length - 1) { - return; - } - this._collections.splice(index, 1); - this._collections.push(collection); + va = this._vaf.va; + vaLength = va.length; - recomposite(this); - }; + uniforms = this._uniforms; + if (defined(this._batchTable)) { + uniforms = this._batchTable.getPickUniformMapCallback()(uniforms); + } - /** - * Lowers a collection to the bottom of the composite. - * - * @param {EntityCollection} collection the collection to move. - * - * @exception {DeveloperError} collection is not in this composite. - */ - CompositeEntityCollection.prototype.lowerCollectionToBottom = function(collection) { - var index = getCollectionIndex(this._collections, collection); - if (index === 0) { - return; - } - this._collections.splice(index, 1); - this._collections.splice(0, 0, collection); + pickList.length = vaLength; + for (j = 0; j < vaLength; ++j) { + command = pickList[j]; + if (!defined(command)) { + command = pickList[j] = new DrawCommand({ + pass : Pass.OPAQUE, + owner : this + }); + } - recomposite(this); - }; + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.count = va[j].indicesCount; + command.shaderProgram = this._spPick; + command.uniformMap = uniforms; + command.vertexArray = va[j].va; + command.renderState = this._rsOpaque; - /** - * Prevents {@link EntityCollection#collectionChanged} events from being raised - * until a corresponding call is made to {@link EntityCollection#resumeEvents}, at which - * point a single event will be raised that covers all suspended operations. - * This allows for many items to be added and removed efficiently. - * While events are suspended, recompositing of the collections will - * also be suspended, as this can be a costly operation. - * This function can be safely called multiple times as long as there - * are corresponding calls to {@link EntityCollection#resumeEvents}. - */ - CompositeEntityCollection.prototype.suspendEvents = function() { - this._suspendCount++; - this._composite.suspendEvents(); - }; + if (this._instanced) { + command.count = 6; + command.instanceCount = billboardsLength; + } - /** - * Resumes raising {@link EntityCollection#collectionChanged} events immediately - * when an item is added or removed. Any modifications made while while events were suspended - * will be triggered as a single event when this function is called. This function also ensures - * the collection is recomposited if events are also resumed. - * This function is reference counted and can safely be called multiple times as long as there - * are corresponding calls to {@link EntityCollection#resumeEvents}. - * - * @exception {DeveloperError} resumeEvents can not be called before suspendEvents. - */ - CompositeEntityCollection.prototype.resumeEvents = function() { - if (this._suspendCount === 0) { - throw new DeveloperError('resumeEvents can not be called before suspendEvents.'); - } - - this._suspendCount--; - // recomposite before triggering events (but only if required for performance) that might depend on a composited collection - if (this._shouldRecomposite && this._suspendCount === 0) { - recomposite(this); - this._shouldRecomposite = false; + commandList.push(command); + } } - - this._composite.resumeEvents(); }; /** - * Computes the maximum availability of the entities in the collection. - * If the collection contains a mix of infinitely available data and non-infinite data, - * It will return the interval pertaining to the non-infinite data only. If all - * data is infinite, an infinite interval will be returned. + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {TimeInterval} The availability of entities in the collection. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see BillboardCollection#destroy */ - CompositeEntityCollection.prototype.computeAvailability = function() { - return this._composite.computeAvailability(); + BillboardCollection.prototype.isDestroyed = function() { + return false; }; /** - * Gets an entity with the specified id. + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. * - * @param {String} id The id of the entity to retrieve. - * @returns {Entity} The entity with the provided id or undefined if the id did not exist in the collection. + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * billboards = billboards && billboards.destroy(); + * + * @see BillboardCollection#isDestroyed */ - CompositeEntityCollection.prototype.getById = function(id) { - return this._composite.getById(id); - }; - - CompositeEntityCollection.prototype._onCollectionChanged = function(collection, added, removed) { - var collections = this._collectionsCopy; - var collectionsLength = collections.length; - var composite = this._composite; - composite.suspendEvents(); - - var i; - var q; - var entity; - var compositeEntity; - var removedLength = removed.length; - var eventHash = this._eventHash; - var collectionId = collection.id; - for (i = 0; i < removedLength; i++) { - var removedEntity = removed[i]; - unsubscribeFromEntity(this, eventHash, collectionId, removedEntity); - - var removedId = removedEntity.id; - //Check if the removed entity exists in any of the remaining collections - //If so, we clean and remerge it. - for (q = collectionsLength - 1; q >= 0; q--) { - entity = collections[q].getById(removedId); - if (defined(entity)) { - if (!defined(compositeEntity)) { - compositeEntity = composite.getById(removedId); - clean(compositeEntity); - } - compositeEntity.merge(entity); - } - } - //We never retrieved the compositeEntity, which means it no longer - //exists in any of the collections, remove it from the composite. - if (!defined(compositeEntity)) { - composite.removeById(removedId); - } - compositeEntity = undefined; + BillboardCollection.prototype.destroy = function() { + if (defined(this._removeCallbackFunc)) { + this._removeCallbackFunc(); + this._removeCallbackFunc = undefined; } - var addedLength = added.length; - for (i = 0; i < addedLength; i++) { - var addedEntity = added[i]; - subscribeToEntity(this, eventHash, collectionId, addedEntity); - - var addedId = addedEntity.id; - //We know the added entity exists in at least one collection, - //but we need to check all collections and re-merge in order - //to maintain the priority of properties. - for (q = collectionsLength - 1; q >= 0; q--) { - entity = collections[q].getById(addedId); - if (defined(entity)) { - if (!defined(compositeEntity)) { - compositeEntity = composite.getById(addedId); - if (!defined(compositeEntity)) { - entityOptionsScratch.id = addedId; - compositeEntity = new Entity(entityOptionsScratch); - composite.add(compositeEntity); - } else { - clean(compositeEntity); - } - } - compositeEntity.merge(entity); - } - } - compositeEntity = undefined; - } + this._textureAtlas = this._destroyTextureAtlas && this._textureAtlas && this._textureAtlas.destroy(); + this._sp = this._sp && this._sp.destroy(); + this._spTranslucent = this._spTranslucent && this._spTranslucent.destroy(); + this._spPick = this._spPick && this._spPick.destroy(); + this._vaf = this._vaf && this._vaf.destroy(); + destroyBillboards(this._billboards); - composite.resumeEvents(); + return destroyObject(this); }; - CompositeEntityCollection.prototype._onDefinitionChanged = function(entity, propertyName, newValue, oldValue) { - var collections = this._collections; - var composite = this._composite; + return BillboardCollection; +}); - var collectionsLength = collections.length; - var id = entity.id; - var compositeEntity = composite.getById(id); - var compositeProperty = compositeEntity[propertyName]; - var newProperty = !defined(compositeProperty); +define('Scene/LabelStyle',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - var firstTime = true; - for (var q = collectionsLength - 1; q >= 0; q--) { - var innerEntity = collections[q].getById(entity.id); - if (defined(innerEntity)) { - var property = innerEntity[propertyName]; - if (defined(property)) { - if (firstTime) { - firstTime = false; - //We only want to clone if the property is also mergeable. - //This ensures that leaf properties are referenced and not copied, - //which is the entire point of compositing. - if (defined(property.merge) && defined(property.clone)) { - compositeProperty = property.clone(compositeProperty); - } else { - compositeProperty = property; - break; - } - } - compositeProperty.merge(property); - } - } - } + /** + * Describes how to draw a label. + * + * @exports LabelStyle + * + * @see Label#style + */ + var LabelStyle = { + /** + * Fill the text of the label, but do not outline. + * + * @type {Number} + * @constant + */ + FILL : 0, - if (newProperty && compositeEntity.propertyNames.indexOf(propertyName) === -1) { - compositeEntity.addProperty(propertyName); - } + /** + * Outline the text of the label, but do not fill. + * + * @type {Number} + * @constant + */ + OUTLINE : 1, - compositeEntity[propertyName] = compositeProperty; + /** + * Fill and outline the text of the label. + * + * @type {Number} + * @constant + */ + FILL_AND_OUTLINE : 2 }; - return CompositeEntityCollection; + return freezeObject(LabelStyle); }); -define('DataSources/CompositeProperty',[ +define('Scene/Label',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Color', + '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/Event', - '../Core/EventHelper', - '../Core/TimeIntervalCollection', - './Property' + '../Core/DistanceDisplayCondition', + '../Core/freezeObject', + '../Core/NearFarScalar', + './Billboard', + './HeightReference', + './HorizontalOrigin', + './LabelStyle', + './VerticalOrigin' ], function( + BoundingRectangle, + Cartesian2, + Cartesian3, + Color, + defaultValue, defined, defineProperties, DeveloperError, - Event, - EventHelper, - TimeIntervalCollection, - Property) { + DistanceDisplayCondition, + freezeObject, + NearFarScalar, + Billboard, + HeightReference, + HorizontalOrigin, + LabelStyle, + VerticalOrigin) { 'use strict'; - function subscribeAll(property, eventHelper, definitionChanged, intervals) { - function callback() { - definitionChanged.raiseEvent(property); + var textTypes = freezeObject({ + LTR : 0, + RTL : 1, + WEAK : 2, + BRACKETS : 3 + }); + + function rebindAllGlyphs(label) { + if (!label._rebindAllGlyphs && !label._repositionAllGlyphs) { + // only push label if it's not already been marked dirty + label._labelCollection._labelsToUpdate.push(label); } - var items = []; - eventHelper.removeAll(); - var length = intervals.length; - for (var i = 0; i < length; i++) { - var interval = intervals.get(i); - if (defined(interval.data) && items.indexOf(interval.data) === -1) { - eventHelper.add(interval.data.definitionChanged, callback); - } + label._rebindAllGlyphs = true; + } + + function repositionAllGlyphs(label) { + if (!label._rebindAllGlyphs && !label._repositionAllGlyphs) { + // only push label if it's not already been marked dirty + label._labelCollection._labelsToUpdate.push(label); } + label._repositionAllGlyphs = true; } /** - * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the - * data property of each {@link TimeInterval} is another Property instance which is - * evaluated at the provided time. - * - * @alias CompositeProperty - * @constructor + * A Label draws viewport-aligned text positioned in the 3D scene. This constructor + * should not be used directly, instead create labels by calling {@link LabelCollection#add}. * + * @alias Label + * @internalConstructor * - * @example - * var constantProperty = ...; - * var sampledProperty = ...; + * @exception {DeveloperError} translucencyByDistance.far must be greater than translucencyByDistance.near + * @exception {DeveloperError} pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near + * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near * - * //Create a composite property from two previously defined properties - * //where the property is valid on August 1st, 2012 and uses a constant - * //property for the first half of the day and a sampled property for the - * //remaining half. - * var composite = new Cesium.CompositeProperty(); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2012-08-01T00:00:00.00Z/2012-08-01T12:00:00.00Z', - * data : constantProperty - * })); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2012-08-01T12:00:00.00Z/2012-08-02T00:00:00.00Z', - * isStartIncluded : false, - * isStopIncluded : false, - * data : sampledProperty - * })); + * @see LabelCollection + * @see LabelCollection#add * - * @see CompositeMaterialProperty - * @see CompositePositionProperty + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Labels.html|Cesium Sandcastle Labels Demo} */ - function CompositeProperty() { - this._eventHelper = new EventHelper(); - this._definitionChanged = new Event(); - this._intervals = new TimeIntervalCollection(); - this._intervals.changedEvent.addEventListener(CompositeProperty.prototype._intervalsChanged, this); + function Label(options, labelCollection) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + } + + var translucencyByDistance = options.translucencyByDistance; + var pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; + var scaleByDistance = options.scaleByDistance; + var distanceDisplayCondition = options.distanceDisplayCondition; + if (defined(translucencyByDistance)) { + if (translucencyByDistance.far <= translucencyByDistance.near) { + throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + } + translucencyByDistance = NearFarScalar.clone(translucencyByDistance); + } + if (defined(pixelOffsetScaleByDistance)) { + if (pixelOffsetScaleByDistance.far <= pixelOffsetScaleByDistance.near) { + throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); + } + pixelOffsetScaleByDistance = NearFarScalar.clone(pixelOffsetScaleByDistance); + } + if (defined(scaleByDistance)) { + if (scaleByDistance.far <= scaleByDistance.near) { + throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + } + scaleByDistance = NearFarScalar.clone(scaleByDistance); + } + if (defined(distanceDisplayCondition)) { + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); + } + distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); + } + + this._renderedText = undefined; + this._text = undefined; + this._show = defaultValue(options.show, true); + this._font = defaultValue(options.font, '30px sans-serif'); + this._fillColor = Color.clone(defaultValue(options.fillColor, Color.WHITE)); + this._outlineColor = Color.clone(defaultValue(options.outlineColor, Color.BLACK)); + this._outlineWidth = defaultValue(options.outlineWidth, 1.0); + this._showBackground = defaultValue(options.showBackground, false); + this._backgroundColor = defaultValue(options.backgroundColor, new Color(0.165, 0.165, 0.165, 0.8)); + this._backgroundPadding = defaultValue(options.backgroundPadding, new Cartesian2(7, 5)); + this._style = defaultValue(options.style, LabelStyle.FILL); + this._verticalOrigin = defaultValue(options.verticalOrigin, VerticalOrigin.BASELINE); + this._horizontalOrigin = defaultValue(options.horizontalOrigin, HorizontalOrigin.LEFT); + this._pixelOffset = Cartesian2.clone(defaultValue(options.pixelOffset, Cartesian2.ZERO)); + this._eyeOffset = Cartesian3.clone(defaultValue(options.eyeOffset, Cartesian3.ZERO)); + this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); + this._scale = defaultValue(options.scale, 1.0); + this._id = options.id; + this._translucencyByDistance = translucencyByDistance; + this._pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; + this._scaleByDistance = scaleByDistance; + this._heightReference = defaultValue(options.heightReference, HeightReference.NONE); + this._distanceDisplayCondition = distanceDisplayCondition; + this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); + + this._labelCollection = labelCollection; + this._glyphs = []; + this._backgroundBillboard = undefined; + this._batchIndex = undefined; // Used only by Vector3DTilePoints and BillboardCollection + + this._rebindAllGlyphs = true; + this._repositionAllGlyphs = true; + + this._actualClampedPosition = undefined; + this._removeCallbackFunc = undefined; + this._mode = undefined; + + this._clusterShow = true; + + this.text = defaultValue(options.text, ''); + + this._updateClamping(); } - defineProperties(CompositeProperty.prototype, { + defineProperties(Label.prototype, { /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CompositeProperty.prototype - * + * Determines if this label will be shown. Use this to hide or show a label, instead + * of removing it and re-adding it to the collection. + * @memberof Label.prototype * @type {Boolean} - * @readonly + * @default true */ - isConstant : { + show : { get : function() { - return this._intervals.isEmpty; + return this._show; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._show !== value) { + this._show = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var billboard = glyphs[i].billboard; + if (defined(billboard)) { + billboard.show = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.show = value; + } + } } }, + /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof CompositeProperty.prototype - * - * @type {Event} - * @readonly + * Gets or sets the Cartesian position of this label. + * @memberof Label.prototype + * @type {Cartesian3} */ - definitionChanged : { + position : { get : function() { - return this._definitionChanged; + return this._position; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var position = this._position; + if (!Cartesian3.equals(position, value)) { + Cartesian3.clone(value, position); + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var billboard = glyphs[i].billboard; + if (defined(billboard)) { + billboard.position = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.position = value; + } + + this._updateClamping(); + } } }, + /** - * Gets the interval collection. - * @memberof CompositeProperty.prototype - * - * @type {TimeIntervalCollection} + * Gets or sets the height reference of this billboard. + * @memberof Label.prototype + * @type {HeightReference} + * @default HeightReference.NONE */ - intervals : { + heightReference : { get : function() { - return this._intervals; + return this._heightReference; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (value !== this._heightReference) { + this._heightReference = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var billboard = glyphs[i].billboard; + if (defined(billboard)) { + billboard.heightReference = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.heightReference = value; + } + + repositionAllGlyphs(this); + + this._updateClamping(); + } } - } - }); + }, - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - CompositeProperty.prototype.getValue = function(time, result) { - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - - var innerProperty = this._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getValue(time, result); - } - return undefined; - }; + /** + * Gets or sets the text of this label. + * @memberof Label.prototype + * @type {String} + */ + text : { + get : function() { + return this._text; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._text !== value) { + this._text = value; + this._renderedText = Label.enableRightToLeftDetection ? reverseRtl(value) : value; + rebindAllGlyphs(this); + } + } + }, - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - CompositeProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CompositeProperty && // - this._intervals.equals(other._intervals, Property.equals)); - }; + /** + * Gets or sets the font used to draw this label. Fonts are specified using the same syntax as the CSS 'font' property. + * @memberof Label.prototype + * @type {String} + * @default '30px sans-serif' + * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles|HTML canvas 2D context text styles} + */ + font : { + get : function() { + return this._font; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._font !== value) { + this._font = value; + rebindAllGlyphs(this); + } + } + }, - /** - * @private - */ - CompositeProperty.prototype._intervalsChanged = function() { - subscribeAll(this, this._eventHelper, this._definitionChanged, this._intervals); - this._definitionChanged.raiseEvent(this); - }; + /** + * Gets or sets the fill color of this label. + * @memberof Label.prototype + * @type {Color} + * @default Color.WHITE + * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} + */ + fillColor : { + get : function() { + return this._fillColor; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var fillColor = this._fillColor; + if (!Color.equals(fillColor, value)) { + Color.clone(value, fillColor); + rebindAllGlyphs(this); + } + } + }, - return CompositeProperty; -}); + /** + * Gets or sets the outline color of this label. + * @memberof Label.prototype + * @type {Color} + * @default Color.BLACK + * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} + */ + outlineColor : { + get : function() { + return this._outlineColor; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var outlineColor = this._outlineColor; + if (!Color.equals(outlineColor, value)) { + Color.clone(value, outlineColor); + rebindAllGlyphs(this); + } + } + }, -define('DataSources/CompositeMaterialProperty',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './CompositeProperty', - './Property' - ], function( - defined, - defineProperties, - DeveloperError, - Event, - CompositeProperty, - Property) { - 'use strict'; + /** + * Gets or sets the outline width of this label. + * @memberof Label.prototype + * @type {Number} + * @default 1.0 + * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._outlineWidth !== value) { + this._outlineWidth = value; + rebindAllGlyphs(this); + } + } + }, - /** - * A {@link CompositeProperty} which is also a {@link MaterialProperty}. - * - * @alias CompositeMaterialProperty - * @constructor - */ - function CompositeMaterialProperty() { - this._definitionChanged = new Event(); - this._composite = new CompositeProperty(); - this._composite.definitionChanged.addEventListener(CompositeMaterialProperty.prototype._raiseDefinitionChanged, this); - } + /** + * Determines if a background behind this label will be shown. + * @memberof Label.prototype + * @default false + * @type {Boolean} + */ + showBackground : { + get : function() { + return this._showBackground; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._showBackground !== value) { + this._showBackground = value; + rebindAllGlyphs(this); + } + } + }, - defineProperties(CompositeMaterialProperty.prototype, { /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CompositeMaterialProperty.prototype + * Gets or sets the background color of this label. + * @memberof Label.prototype + * @type {Color} + * @default new Color(0.165, 0.165, 0.165, 0.8) + */ + backgroundColor : { + get : function() { + return this._backgroundColor; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var backgroundColor = this._backgroundColor; + if (!Color.equals(backgroundColor, value)) { + Color.clone(value, backgroundColor); + + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.color = backgroundColor; + } + } + } + }, + + /** + * Gets or sets the background padding, in pixels, of this label. The <code>x</code> value + * controls horizontal padding, and the <code>y</code> value controls vertical padding. + * @memberof Label.prototype + * @type {Cartesian2} + * @default new Cartesian2(7, 5) + */ + backgroundPadding : { + get : function() { + return this._backgroundPadding; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var backgroundPadding = this._backgroundPadding; + if (!Cartesian2.equals(backgroundPadding, value)) { + Cartesian2.clone(value, backgroundPadding); + repositionAllGlyphs(this); + } + } + }, + + /** + * Gets or sets the style of this label. + * @memberof Label.prototype + * @type {LabelStyle} + * @default LabelStyle.FILL + */ + style : { + get : function() { + return this._style; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._style !== value) { + this._style = value; + rebindAllGlyphs(this); + } + } + }, + + /** + * Gets or sets the pixel offset in screen space from the origin of this label. This is commonly used + * to align multiple labels and billboards at the same position, e.g., an image and text. The + * screen space origin is the top, left corner of the canvas; <code>x</code> increases from + * left to right, and <code>y</code> increases from top to bottom. + * <br /><br /> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><code>default</code><br/><img src='Images/Label.setPixelOffset.default.png' width='250' height='188' /></td> + * <td align='center'><code>l.pixeloffset = new Cartesian2(25, 75);</code><br/><img src='Images/Label.setPixelOffset.x50y-25.png' width='250' height='188' /></td> + * </tr></table> + * The label's origin is indicated by the yellow point. + * </div> + * @memberof Label.prototype + * @type {Cartesian2} + * @default Cartesian2.ZERO + */ + pixelOffset : { + get : function() { + return this._pixelOffset; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var pixelOffset = this._pixelOffset; + if (!Cartesian2.equals(pixelOffset, value)) { + Cartesian2.clone(value, pixelOffset); + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.pixelOffset = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.pixelOffset = value; + } + } + } + }, + + /** + * Gets or sets near and far translucency properties of a Label based on the Label's distance from the camera. + * A label's translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the label's translucency remains clamped to the nearest bound. If undefined, + * translucencyByDistance will be disabled. + * @memberof Label.prototype + * @type {NearFarScalar} * - * @type {Boolean} - * @readonly + * @example + * // Example 1. + * // Set a label's translucencyByDistance to 1.0 when the + * // camera is 1500 meters from the label and disappear as + * // the camera distance approaches 8.0e6 meters. + * text.translucencyByDistance = new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.0); + * + * @example + * // Example 2. + * // disable translucency by distance + * text.translucencyByDistance = undefined; */ - isConstant : { + translucencyByDistance : { get : function() { - return this._composite.isConstant; + return this._translucencyByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var translucencyByDistance = this._translucencyByDistance; + if (!NearFarScalar.equals(translucencyByDistance, value)) { + this._translucencyByDistance = NearFarScalar.clone(value, translucencyByDistance); + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.translucencyByDistance = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.translucencyByDistance = value; + } + } } }, + /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof CompositeMaterialProperty.prototype + * Gets or sets near and far pixel offset scaling properties of a Label based on the Label's distance from the camera. + * A label's pixel offset will be scaled between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the label's pixel offset scaling remains clamped to the nearest bound. If undefined, + * pixelOffsetScaleByDistance will be disabled. + * @memberof Label.prototype + * @type {NearFarScalar} * - * @type {Event} - * @readonly + * @example + * // Example 1. + * // Set a label's pixel offset scale to 0.0 when the + * // camera is 1500 meters from the label and scale pixel offset to 10.0 pixels + * // in the y direction the camera distance approaches 8.0e6 meters. + * text.pixelOffset = new Cesium.Cartesian2(0.0, 1.0); + * text.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(1.5e2, 0.0, 8.0e6, 10.0); + * + * @example + * // Example 2. + * // disable pixel offset by distance + * text.pixelOffsetScaleByDistance = undefined; */ - definitionChanged : { + pixelOffsetScaleByDistance : { get : function() { - return this._definitionChanged; + return this._pixelOffsetScaleByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; + if (!NearFarScalar.equals(pixelOffsetScaleByDistance, value)) { + this._pixelOffsetScaleByDistance = NearFarScalar.clone(value, pixelOffsetScaleByDistance); + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.pixelOffsetScaleByDistance = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.pixelOffsetScaleByDistance = value; + } + } } }, + /** - * Gets the interval collection. - * @memberof CompositeMaterialProperty.prototype + * Gets or sets near and far scaling properties of a Label based on the label's distance from the camera. + * A label's scale will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the label's scale remains clamped to the nearest bound. If undefined, + * scaleByDistance will be disabled. + * @memberof Label.prototype + * @type {NearFarScalar} * - * @type {TimeIntervalCollection} + * @example + * // Example 1. + * // Set a label's scaleByDistance to scale by 1.5 when the + * // camera is 1500 meters from the label and disappear as + * // the camera distance approaches 8.0e6 meters. + * label.scaleByDistance = new Cesium.NearFarScalar(1.5e2, 1.5, 8.0e6, 0.0); + * + * @example + * // Example 2. + * // disable scaling by distance + * label.scaleByDistance = undefined; */ - intervals : { + scaleByDistance : { get : function() { - return this._composite._intervals; + return this._scaleByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var scaleByDistance = this._scaleByDistance; + if (!NearFarScalar.equals(scaleByDistance, value)) { + this._scaleByDistance = NearFarScalar.clone(value, scaleByDistance); + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.scaleByDistance = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.scaleByDistance = value; + } + } } - } - }); + }, - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - CompositeMaterialProperty.prototype.getType = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - - var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getType(time); - } - return undefined; - }; + /** + * Gets and sets the 3D Cartesian offset applied to this label in eye coordinates. Eye coordinates is a left-handed + * coordinate system, where <code>x</code> points towards the viewer's right, <code>y</code> points up, and + * <code>z</code> points into the screen. Eye coordinates use the same scale as world and model coordinates, + * which is typically meters. + * <br /><br /> + * An eye offset is commonly used to arrange multiple label or objects at the same position, e.g., to + * arrange a label above its corresponding 3D model. + * <br /><br /> + * Below, the label is positioned at the center of the Earth but an eye offset makes it always + * appear on top of the Earth regardless of the viewer's or Earth's orientation. + * <br /><br /> + * <div align='center'> + * <table border='0' cellpadding='5'><tr> + * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> + * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> + * </tr></table> + * <code>l.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code><br /><br /> + * </div> + * @memberof Label.prototype + * @type {Cartesian3} + * @default Cartesian3.ZERO + */ + eyeOffset : { + get : function() { + return this._eyeOffset; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var eyeOffset = this._eyeOffset; + if (!Cartesian3.equals(eyeOffset, value)) { + Cartesian3.clone(value, eyeOffset); - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - CompositeMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - - var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getValue(time, result); - } - return undefined; - }; + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.eyeOffset = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.eyeOffset = value; + } + } + } + }, - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - CompositeMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CompositeMaterialProperty && // - this._composite.equals(other._composite, Property.equals)); - }; + /** + * Gets or sets the horizontal origin of this label, which determines if the label is drawn + * to the left, center, or right of its anchor position. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> + * </div> + * @memberof Label.prototype + * @type {HorizontalOrigin} + * @default HorizontalOrigin.LEFT + * @example + * // Use a top, right origin + * l.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT; + * l.verticalOrigin = Cesium.VerticalOrigin.TOP; + */ + horizontalOrigin : { + get : function() { + return this._horizontalOrigin; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._horizontalOrigin !== value) { + this._horizontalOrigin = value; + repositionAllGlyphs(this); + } + } + }, + + /** + * Gets or sets the vertical origin of this label, which determines if the label is + * to the above, below, or at the center of its anchor position. + * <br /><br /> + * <div align='center'> + * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> + * </div> + * @memberof Label.prototype + * @type {VerticalOrigin} + * @default VerticalOrigin.BASELINE + * @example + * // Use a top, right origin + * l.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT; + * l.verticalOrigin = Cesium.VerticalOrigin.TOP; + */ + verticalOrigin : { + get : function() { + return this._verticalOrigin; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._verticalOrigin !== value) { + this._verticalOrigin = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.verticalOrigin = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.verticalOrigin = value; + } + + repositionAllGlyphs(this); + } + } + }, + + /** + * Gets or sets the uniform scale that is multiplied with the label's size in pixels. + * A scale of <code>1.0</code> does not change the size of the label; a scale greater than + * <code>1.0</code> enlarges the label; a positive scale less than <code>1.0</code> shrinks + * the label. + * <br /><br /> + * Applying a large scale value may pixelate the label. To make text larger without pixelation, + * use a larger font size when calling {@link Label#font} instead. + * <br /><br /> + * <div align='center'> + * <img src='Images/Label.setScale.png' width='400' height='300' /><br/> + * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, + * and <code>2.0</code>. + * </div> + * @memberof Label.prototype + * @type {Number} + * @default 1.0 + */ + scale : { + get : function() { + return this._scale; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._scale !== value) { + this._scale = value; - /** - * @private - */ - CompositeMaterialProperty.prototype._raiseDefinitionChanged = function() { - this._definitionChanged.raiseEvent(this); - }; + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.scale = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.scale = value; + } - return CompositeMaterialProperty; -}); + repositionAllGlyphs(this); + } + } + }, -define('DataSources/CompositePositionProperty',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame', - './CompositeProperty', - './Property' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame, - CompositeProperty, - Property) { - 'use strict'; + /** + * Gets or sets the condition specifying at what distance from the camera that this label will be displayed. + * @memberof Label.prototype + * @type {DistanceDisplayCondition} + * @default undefined + */ + distanceDisplayCondition : { + get : function() { + return this._distanceDisplayCondition; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far must be greater than near'); + } + if (!DistanceDisplayCondition.equals(value, this._distanceDisplayCondition)) { + this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); - /** - * A {@link CompositeProperty} which is also a {@link PositionProperty}. - * - * @alias CompositePositionProperty - * @constructor - * - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - */ - function CompositePositionProperty(referenceFrame) { - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - this._definitionChanged = new Event(); - this._composite = new CompositeProperty(); - this._composite.definitionChanged.addEventListener(CompositePositionProperty.prototype._raiseDefinitionChanged, this); - } + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.distanceDisplayCondition = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.distanceDisplayCondition = value; + } + } + } + }, - defineProperties(CompositePositionProperty.prototype, { /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof CompositePositionProperty.prototype - * - * @type {Boolean} - * @readonly + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof Label.prototype + * @type {Number} + * @default 0.0 */ - isConstant : { + disableDepthTestDistance : { get : function() { - return this._composite.isConstant; + return this._disableDepthTestDistance; + }, + set : function(value) { + if (this._disableDepthTestDistance !== value) { + if (!defined(value) || value < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + } + this._disableDepthTestDistance = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.disableDepthTestDistance = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.disableDepthTestDistance = value; + } + } } }, + /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof CompositePositionProperty.prototype - * - * @type {Event} - * @readonly + * Gets or sets the user-defined object returned when the label is picked. + * @memberof Label.prototype + * @type {Object} */ - definitionChanged : { + id : { get : function() { - return this._definitionChanged; + return this._id; + }, + set : function(value) { + if (this._id !== value) { + this._id = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.id = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.id = value; + } + } } }, + /** - * Gets the interval collection. - * @memberof CompositePositionProperty.prototype - * - * @type {TimeIntervalCollection} + * Keeps track of the position of the label based on the height reference. + * @memberof Label.prototype + * @type {Cartesian3} + * @private */ - intervals : { + _clampedPosition : { get : function() { - return this._composite.intervals; + return this._actualClampedPosition; + }, + set : function(value) { + this._actualClampedPosition = Cartesian3.clone(value, this._actualClampedPosition); + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + // Set all the private values here, because we already clamped to ground + // so we don't want to do it again for every glyph + glyph.billboard._clampedPosition = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard._clampedPosition = value; + } } }, + /** - * Gets or sets the reference frame which this position presents itself as. - * Each PositionProperty making up this object has it's own reference frame, - * so this property merely exposes a "preferred" reference frame for clients - * to use. - * @memberof CompositePositionProperty.prototype - * - * @type {ReferenceFrame} + * Determines whether or not this label will be shown or hidden because it was clustered. + * @memberof Label.prototype + * @type {Boolean} + * @default true + * @private */ - referenceFrame : { + clusterShow : { get : function() { - return this._referenceFrame; + return this._clusterShow; }, set : function(value) { - this._referenceFrame = value; + if (this._clusterShow !== value) { + this._clusterShow = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.clusterShow = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.clusterShow = value; + } + } } } }); - /** - * Gets the value of the property at the provided time in the fixed frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - CompositePositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + Label.prototype._updateClamping = function() { + Billboard._updateClamping(this._labelCollection, this); }; /** - * Gets the value of the property at the provided time and in the provided reference frame. + * Computes the screen-space position of the label's origin, taking into account eye and pixel offsets. + * The screen space origin is the top, left corner of the canvas; <code>x</code> increases from + * left to right, and <code>y</code> increases from top to bottom. * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {Scene} scene The scene the label is in. + * @param {Cartesian2} [result] The object onto which to store the result. + * @returns {Cartesian2} The screen-space position of the label. + * + * + * @example + * console.log(l.computeScreenSpacePosition(scene).toString()); + * + * @see Label#eyeOffset + * @see Label#pixelOffset */ - CompositePositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); + Label.prototype.computeScreenSpacePosition = function(scene, result) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); } - var innerProperty = this._composite._intervals.findDataForIntervalContainingDate(time); - if (defined(innerProperty)) { - return innerProperty.getValueInReferenceFrame(time, referenceFrame, result); + if (!defined(result)) { + result = new Cartesian2(); } - return undefined; + + var labelCollection = this._labelCollection; + var modelMatrix = labelCollection.modelMatrix; + var actualPosition = defined(this._actualClampedPosition) ? this._actualClampedPosition : this._position; + + var windowCoordinates = Billboard._computeScreenSpacePosition(modelMatrix, actualPosition, + this._eyeOffset, this._pixelOffset, scene, result); + return windowCoordinates; }; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Gets a label's screen space bounding box centered around screenSpacePosition. + * @param {Label} label The label to get the screen space bounding box for. + * @param {Cartesian2} screenSpacePosition The screen space center of the label. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The screen space bounding box. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @private */ - CompositePositionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof CompositePositionProperty && // - this._referenceFrame === other._referenceFrame && // - this._composite.equals(other._composite, Property.equals)); + Label.getScreenSpaceBoundingBox = function(label, screenSpacePosition, result) { + var x = 0; + var y = 0; + var width = 0; + var height = 0; + var scale = label.scale; + var resolutionScale = label._labelCollection._resolutionScale; + + var backgroundBillboard = label._backgroundBillboard; + if (defined(backgroundBillboard)) { + x = screenSpacePosition.x + (backgroundBillboard._translate.x / resolutionScale); + y = screenSpacePosition.y - (backgroundBillboard._translate.y / resolutionScale); + width = backgroundBillboard.width * scale; + height = backgroundBillboard.height * scale; + + if (label.verticalOrigin === VerticalOrigin.BOTTOM || label.verticalOrigin === VerticalOrigin.BASELINE) { + y -= height; + } else if (label.verticalOrigin === VerticalOrigin.CENTER) { + y -= height * 0.5; + } + } else { + x = Number.POSITIVE_INFINITY; + y = Number.POSITIVE_INFINITY; + var maxX = 0; + var maxY = 0; + var glyphs = label._glyphs; + var length = glyphs.length; + for (var i = 0; i < length; ++i) { + var glyph = glyphs[i]; + var billboard = glyph.billboard; + if (!defined(billboard)) { + continue; + } + + var glyphX = screenSpacePosition.x + (billboard._translate.x / resolutionScale); + var glyphY = screenSpacePosition.y - (billboard._translate.y / resolutionScale); + var glyphWidth = billboard.width * scale; + var glyphHeight = billboard.height * scale; + + if (label.verticalOrigin === VerticalOrigin.BOTTOM || label.verticalOrigin === VerticalOrigin.BASELINE) { + glyphY -= glyphHeight; + } else if (label.verticalOrigin === VerticalOrigin.CENTER) { + glyphY -= glyphHeight * 0.5; + } + + x = Math.min(x, glyphX); + y = Math.min(y, glyphY); + maxX = Math.max(maxX, glyphX + glyphWidth); + maxY = Math.max(maxY, glyphY + glyphHeight); + } + + width = maxX - x; + height = maxY - y; + } + + if (!defined(result)) { + result = new BoundingRectangle(); + } + + result.x = x; + result.y = y; + result.width = width; + result.height = height; + + return result; }; /** - * @private + * Determines if this label equals another label. Labels are equal if all their properties + * are equal. Labels in different collections can be equal. + * + * @param {Label} other The label to compare for equality. + * @returns {Boolean} <code>true</code> if the labels are equal; otherwise, <code>false</code>. */ - CompositePositionProperty.prototype._raiseDefinitionChanged = function() { - this._definitionChanged.raiseEvent(this); + Label.prototype.equals = function(other) { + return this === other || + defined(other) && + this._show === other._show && + this._scale === other._scale && + this._outlineWidth === other._outlineWidth && + this._showBackground === other._showBackground && + this._style === other._style && + this._verticalOrigin === other._verticalOrigin && + this._horizontalOrigin === other._horizontalOrigin && + this._heightReference === other._heightReference && + this._renderedText === other._renderedText && + this._font === other._font && + Cartesian3.equals(this._position, other._position) && + Color.equals(this._fillColor, other._fillColor) && + Color.equals(this._outlineColor, other._outlineColor) && + Color.equals(this._backgroundColor, other._backgroundColor) && + Cartesian2.equals(this._backgroundPadding, other._backgroundPadding) && + Cartesian2.equals(this._pixelOffset, other._pixelOffset) && + Cartesian3.equals(this._eyeOffset, other._eyeOffset) && + NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && + NearFarScalar.equals(this._pixelOffsetScaleByDistance, other._pixelOffsetScaleByDistance) && + NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && + DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && + this._disableDepthTestDistance === other._disableDepthTestDistance && + this._id === other._id; }; - return CompositePositionProperty; -}); - -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/ShadowVolumeFS',[],function() { - 'use strict'; - return "#ifdef GL_EXT_frag_depth\n\ -#extension GL_EXT_frag_depth : enable\n\ -#endif\n\ -varying float v_WindowZ;\n\ -varying vec4 v_color;\n\ -void writeDepthClampedToFarPlane()\n\ -{\n\ -#ifdef GL_EXT_frag_depth\n\ -gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n\ -#endif\n\ -}\n\ -void main(void)\n\ -{\n\ -gl_FragColor = v_color;\n\ -writeDepthClampedToFarPlane();\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/ShadowVolumeVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec4 color;\n\ -attribute float batchId;\n\ -#ifdef EXTRUDED_GEOMETRY\n\ -attribute vec3 extrudeDirection;\n\ -uniform float u_globeMinimumAltitude;\n\ -#endif\n\ -varying float v_WindowZ;\n\ -varying vec4 v_color;\n\ -vec4 depthClampFarPlane(vec4 vertexInClipCoordinates)\n\ -{\n\ -v_WindowZ = (0.5 * (vertexInClipCoordinates.z / vertexInClipCoordinates.w) + 0.5) * vertexInClipCoordinates.w;\n\ -vertexInClipCoordinates.z = min(vertexInClipCoordinates.z, vertexInClipCoordinates.w);\n\ -return vertexInClipCoordinates;\n\ -}\n\ -void main()\n\ -{\n\ -v_color = color;\n\ -vec4 position = czm_computePosition();\n\ -#ifdef EXTRUDED_GEOMETRY\n\ -float delta = min(u_globeMinimumAltitude, czm_geometricToleranceOverMeter * length(position.xyz));\n\ -delta *= czm_sceneMode == czm_sceneMode3D ? 1.0 : 0.0;\n\ -position = position + vec4(extrudeDirection * delta, 0.0);\n\ -#endif\n\ -gl_Position = depthClampFarPlane(czm_modelViewProjectionRelativeToEye * position);\n\ -}\n\ -"; -}); -define('Scene/ClassificationType',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; - /** - * Whether a classification affects terrain, 3D Tiles or both. + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @exports ClassificationOption + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - var ClassificationType = { - /** - * Only terrain will be classified. - * - * @type {Number} - * @constant - */ - TERRAIN : 0, - /** - * Only 3D Tiles will be classified. - * - * @type {Number} - * @constant - */ - CESIUM_3D_TILE : 1, - /** - * Both terrain and 3D Tiles will be classified. - * - * @type {Number} - * @constant - */ - BOTH : 2 + Label.prototype.isDestroyed = function() { + return false; }; - return freezeObject(ClassificationType); -}); - -define('Scene/StencilFunction',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; - /** - * Determines the function used to compare stencil values for the stencil test. + * Determines whether or not run the algorithm, that match the text of the label to right-to-left languages + * @memberof Label + * @type {Boolean} + * @default false * - * @exports StencilFunction + * @example + * // Example 1. + * // Set a label's rightToLeft before init + * Cesium.Label.enableRightToLeftDetection = true; + * var myLabelEntity = viewer.entities.add({ + * label: { + * id: 'my label', + * text: 'זה טקסט בעברית \n ועכשיו יורדים שורה', + * } + * }); + * + * @example + * // Example 2. + * var myLabelEntity = viewer.entities.add({ + * label: { + * id: 'my label', + * text: 'English text' + * } + * }); + * // Set a label's rightToLeft after init + * Cesium.Label.enableRightToLeftDetection = true; + * myLabelEntity.text = 'טקסט חדש'; */ - var StencilFunction = { - /** - * The stencil test never passes. - * - * @type {Number} - * @constant - */ - NEVER : WebGLConstants.NEVER, - - /** - * The stencil test passes when the masked reference value is less than the masked stencil value. - * - * @type {Number} - * @constant - */ - LESS : WebGLConstants.LESS, - - /** - * The stencil test passes when the masked reference value is equal to the masked stencil value. - * - * @type {Number} - * @constant - */ - EQUAL : WebGLConstants.EQUAL, + Label.enableRightToLeftDetection = false; - /** - * The stencil test passes when the masked reference value is less than or equal to the masked stencil value. - * - * @type {Number} - * @constant - */ - LESS_OR_EQUAL : WebGLConstants.LEQUAL, + function convertTextToTypes(text, rtlChars) { + var ltrChars = /[a-zA-Z0-9]/; + var bracketsChars = /[()[\]{}<>]/; + var parsedText = []; + var word = ''; + var lastType = textTypes.LTR; + var currentType = ''; + var textLength = text.length; + for (var textIndex = 0; textIndex < textLength; ++textIndex) { + var character = text.charAt(textIndex); + if (rtlChars.test(character)) { + currentType = textTypes.RTL; + } + else if (ltrChars.test(character)) { + currentType = textTypes.LTR; + } + else if (bracketsChars.test(character)) { + currentType = textTypes.BRACKETS; + } + else { + currentType = textTypes.WEAK; + } - /** - * The stencil test passes when the masked reference value is greater than the masked stencil value. - * - * @type {Number} - * @constant - */ - GREATER : WebGLConstants.GREATER, + if (textIndex === 0) { + lastType = currentType; + } - /** - * The stencil test passes when the masked reference value is not equal to the masked stencil value. - * - * @type {Number} - * @constant - */ - NOT_EQUAL : WebGLConstants.NOTEQUAL, + if (lastType === currentType && currentType !== textTypes.BRACKETS) { + word += character; + } + else { + if (word !== '') { + parsedText.push({Type : lastType, Word : word}); + } + lastType = currentType; + word = character; + } + } + parsedText.push({Type : currentType, Word : word}); + return parsedText; + } - /** - * The stencil test passes when the masked reference value is greater than or equal to the masked stencil value. - * - * @type {Number} - * @constant - */ - GREATER_OR_EQUAL : WebGLConstants.GEQUAL, + function reverseWord(word) { + return word.split('').reverse().join(''); + } - /** - * The stencil test always passes. - * - * @type {Number} - * @constant - */ - ALWAYS : WebGLConstants.ALWAYS - }; + function spliceWord(result, pointer, word) { + return result.slice(0, pointer) + word + result.slice(pointer); + } - return freezeObject(StencilFunction); -}); + function reverseBrackets(bracket) { + switch(bracket) { + case '(': + return ')'; + case ')': + return '('; + case '[': + return ']'; + case ']': + return '['; + case '{': + return '}'; + case '}': + return '{'; + case '<': + return '>'; + case '>': + return '<'; + } + } -define('Scene/StencilOperation',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; + //To add another language, simply add its Unicode block range(s) to the below regex. + var hebrew = '\u05D0-\u05EA'; + var arabic = '\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF'; + var rtlChars = new RegExp('[' + hebrew + arabic + ']'); /** - * Determines the action taken based on the result of the stencil test. * - * @exports StencilOperation + * @param {String} value the text to parse and reorder + * @returns {String} the text as rightToLeft direction + * @private */ - var StencilOperation = { - /** - * Sets the stencil buffer value to zero. - * - * @type {Number} - * @constant - */ - ZERO : WebGLConstants.ZERO, - - /** - * Does not change the stencil buffer. - * - * @type {Number} - * @constant - */ - KEEP : WebGLConstants.KEEP, - - /** - * Replaces the stencil buffer value with the reference value. - * - * @type {Number} - * @constant - */ - REPLACE : WebGLConstants.REPLACE, - - /** - * Increments the stencil buffer value, clamping to unsigned byte. - * - * @type {Number} - * @constant - */ - INCREMENT : WebGLConstants.INCR, - - /** - * Decrements the stencil buffer value, clamping to zero. - * - * @type {Number} - * @constant - */ - DECREMENT : WebGLConstants.DECR, - - /** - * Bitwise inverts the existing stencil buffer value. - * - * @type {Number} - * @constant - */ - INVERT : WebGLConstants.INVERT, + function reverseRtl(value) { + var texts = value.split('\n'); + var result = ''; + for (var i = 0; i < texts.length; i++) { + var text = texts[i]; + var rtlDir = rtlChars.test(text.charAt(0)); + var parsedText = convertTextToTypes(text, rtlChars); - /** - * Increments the stencil buffer value, wrapping to zero when exceeding the unsigned byte range. - * - * @type {Number} - * @constant - */ - INCREMENT_WRAP : WebGLConstants.INCR_WRAP, + var splicePointer = 0; + var line = ''; + for (var wordIndex = 0; wordIndex < parsedText.length; ++wordIndex) { + var subText = parsedText[wordIndex]; + var reverse = subText.Type === textTypes.BRACKETS ? reverseBrackets(subText.Word) : subText.Word; + if (rtlDir) { + if (subText.Type === textTypes.RTL) { + line = reverseWord(subText.Word) + line; + splicePointer = 0; + } + else if (subText.Type === textTypes.LTR) { + line = spliceWord(line, splicePointer, subText.Word); + splicePointer += subText.Word.length; + } + else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { + if (subText.Type === textTypes.WEAK && parsedText[wordIndex - 1].Type === textTypes.BRACKETS) { + line = reverseWord(subText.Word) + line; + } + else if (parsedText[wordIndex - 1].Type === textTypes.RTL) { + line = reverse + line; + splicePointer = 0; + } + else if (parsedText.length > wordIndex + 1) { + if (parsedText[wordIndex + 1].Type === textTypes.RTL) { + line = reverse + line; + splicePointer = 0; + } + else { + line = spliceWord(line, splicePointer, subText.Word); + splicePointer += subText.Word.length; + } + } + else { + line = spliceWord(line, 0, reverse); + } + } + } + else if (subText.Type === textTypes.RTL) { + line = spliceWord(line, splicePointer, reverseWord(subText.Word)); + } + else if (subText.Type === textTypes.LTR) { + line += subText.Word; + splicePointer = line.length; + } + else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { + if (wordIndex > 0) { + if (parsedText[wordIndex - 1].Type === textTypes.RTL) { + if (parsedText.length > wordIndex + 1) { + if (parsedText[wordIndex + 1].Type === textTypes.RTL) { + line = spliceWord(line, splicePointer, reverse); + } + else { + line += subText.Word; + splicePointer = line.length; + } + } + else { + line += subText.Word; + } + } + else { + line += subText.Word; + splicePointer = line.length; + } + } + else { + line += subText.Word; + splicePointer = line.length; + } + } + } - /** - * Decrements the stencil buffer value, wrapping to the maximum unsigned byte instead of going below zero. - * - * @type {Number} - * @constant - */ - DECREMENT_WRAP : WebGLConstants.DECR_WRAP - }; + result += line; + if (i < texts.length - 1) { + result += '\n'; + } + } + return result; + } - return freezeObject(StencilOperation); + return Label; }); -define('Scene/ClassificationPrimitive',[ - '../Core/ColorGeometryInstanceAttribute', +define('Scene/LabelCollection',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Color', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/GeometryInstance', - '../Core/isArray', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Shaders/ShadowVolumeFS', - '../Shaders/ShadowVolumeVS', - '../ThirdParty/when', - './BlendingState', - './ClassificationType', - './DepthFunction', - './PerInstanceColorAppearance', - './Primitive', - './SceneMode', - './StencilFunction', - './StencilOperation' + '../Core/Matrix4', + '../Core/writeTextToCanvas', + './BillboardCollection', + './BlendOption', + './HorizontalOrigin', + './Label', + './LabelStyle', + './TextureAtlas', + './VerticalOrigin' ], function( - ColorGeometryInstanceAttribute, + BoundingRectangle, + Cartesian2, + Color, defaultValue, defined, defineProperties, destroyObject, DeveloperError, - GeometryInstance, - isArray, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - ShadowVolumeFS, - ShadowVolumeVS, - when, - BlendingState, - ClassificationType, - DepthFunction, - PerInstanceColorAppearance, - Primitive, - SceneMode, - StencilFunction, - StencilOperation) { + Matrix4, + writeTextToCanvas, + BillboardCollection, + BlendOption, + HorizontalOrigin, + Label, + LabelStyle, + TextureAtlas, + VerticalOrigin) { 'use strict'; - var ClassificationPrimitiveReadOnlyInstanceAttributes = ['color']; - - /** - * A classification primitive represents a volume enclosing geometry in the {@link Scene} to be highlighted. The geometry must be from a single {@link GeometryInstance}. - * Batching multiple geometries is not yet supported. - * <p> - * A primitive combines the geometry instance with an {@link Appearance} that describes the full shading, including - * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, - * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix - * and match most of them and add a new geometry or appearance independently of each other. Only the {@link PerInstanceColorAppearance} - * is supported at this time. - * </p> - * <p> - * For correct rendering, this feature requires the EXT_frag_depth WebGL extension. For hardware that do not support this extension, there - * will be rendering artifacts for some viewing angles. - * </p> - * <p> - * Valid geometries are {@link BoxGeometry}, {@link CylinderGeometry}, {@link EllipsoidGeometry}, {@link PolylineVolumeGeometry}, and {@link SphereGeometry}. - * </p> - * <p> - * Geometries that follow the surface of the ellipsoid, such as {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}, - * are also valid if they are extruded volumes; otherwise, they will not be rendered. - * </p> - * - * @alias ClassificationPrimitive - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. This can either be a single instance or an array of length one. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. - * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on - * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be <code>false</code>. - * - * @see Primitive - * @see GroundPrimitive - * @see GeometryInstance - * @see Appearance - */ - function ClassificationPrimitive(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * The geometry instance rendered with this primitive. This may - * be <code>undefined</code> if <code>options.releaseGeometryInstances</code> - * is <code>true</code> when the primitive is constructed. - * <p> - * Changing this property after the primitive is rendered has no effect. - * </p> - * <p> - * Because of the rendering technique used, all geometry instances must be the same color. - * If there is an instance with a differing color, a <code>DeveloperError</code> will be thrown - * on the first attempt to render. - * </p> - * - * @readonly - * @type {Array|GeometryInstance} - * - * @default undefined - */ - this.geometryInstances = options.geometryInstances; - /** - * Determines if the primitive will be shown. This affects all geometry - * instances in the primitive. - * - * @type {Boolean} - * - * @default true - */ - this.show = defaultValue(options.show, true); - /** - * Determines whether terrain, 3D Tiles or both will be classified. - * - * @type {ClassificationType} - * - * @default ClassificationType.BOTH - */ - this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); - /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the primitive. - * </p> - * - * @type {Boolean} - * - * @default false - */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the shadow volume for each geometry in the primitive. - * </p> - * - * @type {Boolean} - * - * @default false - */ - this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); - this._debugShowShadowVolume = false; - - // These are used by GroundPrimitive to augment the shader and uniform map. - this._extruded = defaultValue(options._extruded, false); - this._uniformMap = options._uniformMap; + // A glyph represents a single character in a particular label. It may or may + // not have a billboard, depending on whether the texture info has an index into + // the the label collection's texture atlas. Invisible characters have no texture, and + // no billboard. However, it always has a valid dimensions object. + function Glyph() { + this.textureInfo = undefined; + this.dimensions = undefined; + this.billboard = undefined; + } - this._sp = undefined; - this._spStencil = undefined; - this._spPick = undefined; + // GlyphTextureInfo represents a single character, drawn in a particular style, + // shared and reference counted across all labels. It may or may not have an + // index into the label collection's texture atlas, depending on whether the character + // has both width and height, but it always has a valid dimensions object. + function GlyphTextureInfo(labelCollection, index, dimensions) { + this.labelCollection = labelCollection; + this.index = index; + this.dimensions = dimensions; + } - this._rsStencilPreloadPass = undefined; - this._rsStencilDepthPass = undefined; - this._rsColorPass = undefined; - this._rsPickPass = undefined; + // Traditionally, leading is %20 of the font size. + var defaultLineSpacingPercent = 1.2; - this._commandsIgnoreShow = []; + var whitePixelCanvasId = 'ID_WHITE_PIXEL'; + var whitePixelSize = new Cartesian2(4, 4); + var whitePixelBoundingRegion = new BoundingRectangle(1, 1, 1, 1); - this._ready = false; - this._readyPromise = when.defer(); + function addWhitePixelCanvas(textureAtlas, labelCollection) { + var canvas = document.createElement('canvas'); + canvas.width = whitePixelSize.x; + canvas.height = whitePixelSize.y; - this._primitive = undefined; - this._pickPrimitive = options._pickPrimitive; + var context2D = canvas.getContext('2d'); + context2D.fillStyle = '#fff'; + context2D.fillRect(0, 0, canvas.width, canvas.height); - var appearance = new PerInstanceColorAppearance({ - flat : true + textureAtlas.addImage(whitePixelCanvasId, canvas).then(function(index) { + labelCollection._whitePixelIndex = index; }); + } - var readOnlyAttributes; - if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { - readOnlyAttributes = ClassificationPrimitiveReadOnlyInstanceAttributes; + // reusable object for calling writeTextToCanvas + var writeTextToCanvasParameters = {}; + function createGlyphCanvas(character, font, fillColor, outlineColor, outlineWidth, style, verticalOrigin) { + writeTextToCanvasParameters.font = font; + writeTextToCanvasParameters.fillColor = fillColor; + writeTextToCanvasParameters.strokeColor = outlineColor; + writeTextToCanvasParameters.strokeWidth = outlineWidth; + + if (verticalOrigin === VerticalOrigin.CENTER) { + writeTextToCanvasParameters.textBaseline = 'middle'; + } else if (verticalOrigin === VerticalOrigin.TOP) { + writeTextToCanvasParameters.textBaseline = 'top'; + } else { + // VerticalOrigin.BOTTOM and VerticalOrigin.BASELINE + writeTextToCanvasParameters.textBaseline = 'bottom'; } - this._createBoundingVolumeFunction = options._createBoundingVolumeFunction; - this._updateAndQueueCommandsFunction = options._updateAndQueueCommandsFunction; + writeTextToCanvasParameters.fill = style === LabelStyle.FILL || style === LabelStyle.FILL_AND_OUTLINE; + writeTextToCanvasParameters.stroke = style === LabelStyle.OUTLINE || style === LabelStyle.FILL_AND_OUTLINE; - this._primitiveOptions = { - geometryInstances : undefined, - appearance : appearance, - vertexCacheOptimize : defaultValue(options.vertexCacheOptimize, false), - interleave : defaultValue(options.interleave, false), - releaseGeometryInstances : defaultValue(options.releaseGeometryInstances, true), - allowPicking : defaultValue(options.allowPicking, true), - asynchronous : defaultValue(options.asynchronous, true), - compressVertices : defaultValue(options.compressVertices, true), - _readOnlyInstanceAttributes : readOnlyAttributes, - _createBoundingVolumeFunction : undefined, - _createRenderStatesFunction : undefined, - _createShaderProgramFunction : undefined, - _createCommandsFunction : undefined, - _updateAndQueueCommandsFunction : undefined, - _createPickOffsets : true - }; + return writeTextToCanvas(character, writeTextToCanvasParameters); } - defineProperties(ClassificationPrimitive.prototype, { - /** - * When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - vertexCacheOptimize : { - get : function() { - return this._primitiveOptions.vertexCacheOptimize; - } - }, + function unbindGlyph(labelCollection, glyph) { + glyph.textureInfo = undefined; + glyph.dimensions = undefined; - /** - * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default false - */ - interleave : { - get : function() { - return this._primitiveOptions.interleave; + var billboard = glyph.billboard; + if (defined(billboard)) { + billboard.show = false; + billboard.image = undefined; + if (defined(billboard._removeCallbackFunc)) { + billboard._removeCallbackFunc(); + billboard._removeCallbackFunc = undefined; } - }, + labelCollection._spareBillboards.push(billboard); + glyph.billboard = undefined; + } + } - /** - * When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - releaseGeometryInstances : { - get : function() { - return this._primitiveOptions.releaseGeometryInstances; - } - }, + function addGlyphToTextureAtlas(textureAtlas, id, canvas, glyphTextureInfo) { + textureAtlas.addImage(id, canvas).then(function(index) { + glyphTextureInfo.index = index; + }); + } - /** - * When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - allowPicking : { - get : function() { - return this._primitiveOptions.allowPicking; - } - }, + function rebindAllGlyphs(labelCollection, label) { + var text = label._renderedText; + var textLength = text.length; + var glyphs = label._glyphs; + var glyphsLength = glyphs.length; - /** - * Determines if the geometry instances will be created and batched on a web worker. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - asynchronous : { - get : function() { - return this._primitiveOptions.asynchronous; - } - }, + var glyph; + var glyphIndex; + var textIndex; - /** - * When <code>true</code>, geometry vertices are compressed, which will save memory. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - compressVertices : { - get : function() { - return this._primitiveOptions.compressVertices; + // if we have more glyphs than needed, unbind the extras. + if (textLength < glyphsLength) { + for (glyphIndex = textLength; glyphIndex < glyphsLength; ++glyphIndex) { + unbindGlyph(labelCollection, glyphs[glyphIndex]); } - }, + } - /** - * Determines if the primitive is complete and ready to render. If this property is - * true, the primitive will be rendered the next time that {@link ClassificationPrimitive#update} - * is called. - * - * @memberof ClassificationPrimitive.prototype - * - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, + // presize glyphs to match the new text length + glyphs.length = textLength; - /** - * Gets a promise that resolves when the primitive is ready to render. - * @memberof ClassificationPrimitive.prototype - * @type {Promise.<ClassificationPrimitive>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; + var showBackground = label._showBackground && (text.split('\n').join('').length > 0); + var backgroundBillboard = label._backgroundBillboard; + var backgroundBillboardCollection = labelCollection._backgroundBillboardCollection; + if (!showBackground) { + if (defined(backgroundBillboard)) { + backgroundBillboardCollection.remove(backgroundBillboard); + label._backgroundBillboard = backgroundBillboard = undefined; + } + } else { + if (!defined(backgroundBillboard)) { + backgroundBillboard = backgroundBillboardCollection.add({ + collection : labelCollection, + image : whitePixelCanvasId, + imageSubRegion : whitePixelBoundingRegion + }); + label._backgroundBillboard = backgroundBillboard; } + + backgroundBillboard.color = label._backgroundColor; + backgroundBillboard.show = label._show; + backgroundBillboard.position = label._position; + backgroundBillboard.eyeOffset = label._eyeOffset; + backgroundBillboard.pixelOffset = label._pixelOffset; + backgroundBillboard.horizontalOrigin = HorizontalOrigin.LEFT; + backgroundBillboard.verticalOrigin = label._verticalOrigin; + backgroundBillboard.heightReference = label._heightReference; + backgroundBillboard.scale = label._scale; + backgroundBillboard.pickPrimitive = label; + backgroundBillboard.id = label._id; + backgroundBillboard.translucencyByDistance = label._translucencyByDistance; + backgroundBillboard.pixelOffsetScaleByDistance = label._pixelOffsetScaleByDistance; + backgroundBillboard.scaleByDistance = label._scaleByDistance; + backgroundBillboard.distanceDisplayCondition = label._distanceDisplayCondition; + backgroundBillboard.disableDepthTestDistance = label._disableDepthTestDistance; } - }); - /** - * Determines if ClassificationPrimitive rendering is supported. - * - * @param {Scene} scene The scene. - * @returns {Boolean} <code>true</code> if ClassificationPrimitives are supported; otherwise, returns <code>false</code> - */ - ClassificationPrimitive.isSupported = function(scene) { - return scene.context.stencilBuffer; - }; + var glyphTextureCache = labelCollection._glyphTextureCache; - // The stencil mask only uses the least significant 4 bits. - // This is so 3D Tiles with the skip LOD optimization, which uses the most significant 4 bits, - // can be classified. - var stencilMask = 0x0F; - var stencilReference = 0; + // walk the text looking for new characters (creating new glyphs for each) + // or changed characters (rebinding existing glyphs) + for (textIndex = 0; textIndex < textLength; ++textIndex) { + var character = text.charAt(textIndex); + var font = label._font; + var fillColor = label._fillColor; + var outlineColor = label._outlineColor; + var outlineWidth = label._outlineWidth; + var style = label._style; + var verticalOrigin = label._verticalOrigin; - function getStencilPreloadRenderState(enableStencil) { - return { - colorMask : { - red : false, - green : false, - blue : false, - alpha : false - }, - stencilTest : { - enabled : enableStencil, - frontFunction : StencilFunction.ALWAYS, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.DECREMENT_WRAP, - zPass : StencilOperation.DECREMENT_WRAP - }, - backFunction : StencilFunction.ALWAYS, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.INCREMENT_WRAP, - zPass : StencilOperation.INCREMENT_WRAP - }, - reference : stencilReference, - mask : stencilMask - }, - depthTest : { - enabled : false - }, - depthMask : false - }; - } + // retrieve glyph dimensions and texture index (if the canvas has area) + // from the glyph texture cache, or create and add if not present. + var id = JSON.stringify([ + character, + font, + fillColor.toRgba(), + outlineColor.toRgba(), + outlineWidth, + +style, + +verticalOrigin + ]); - function getStencilDepthRenderState(enableStencil) { - return { - colorMask : { - red : false, - green : false, - blue : false, - alpha : false - }, - stencilTest : { - enabled : enableStencil, - frontFunction : StencilFunction.ALWAYS, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.INCREMENT_WRAP - }, - backFunction : StencilFunction.ALWAYS, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - reference : stencilReference, - mask : stencilMask - }, - depthTest : { - enabled : true, - func : DepthFunction.LESS_OR_EQUAL - }, - depthMask : false - }; - } + var glyphTextureInfo = glyphTextureCache[id]; + if (!defined(glyphTextureInfo)) { + var canvas = createGlyphCanvas(character, font, fillColor, outlineColor, outlineWidth, style, verticalOrigin); + glyphTextureInfo = new GlyphTextureInfo(labelCollection, -1, canvas.dimensions); + glyphTextureCache[id] = glyphTextureInfo; - function getColorRenderState(enableStencil) { - return { - stencilTest : { - enabled : enableStencil, - frontFunction : StencilFunction.NOT_EQUAL, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - backFunction : StencilFunction.NOT_EQUAL, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - reference : stencilReference, - mask : stencilMask - }, - depthTest : { - enabled : false - }, - depthMask : false, - blending : BlendingState.ALPHA_BLEND - }; - } + if (canvas.width > 0 && canvas.height > 0) { + addGlyphToTextureAtlas(labelCollection._textureAtlas, id, canvas, glyphTextureInfo); + } + } - var pickRenderState = { - stencilTest : { - enabled : true, - frontFunction : StencilFunction.NOT_EQUAL, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - backFunction : StencilFunction.NOT_EQUAL, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - reference : stencilReference, - mask : stencilMask - }, - depthTest : { - enabled : false - }, - depthMask : false - }; + glyph = glyphs[textIndex]; - function createRenderStates(classificationPrimitive, context, appearance, twoPasses) { - if (defined(classificationPrimitive._rsStencilPreloadPass)) { - return; + if (defined(glyph)) { + // clean up leftover information from the previous glyph + if (glyphTextureInfo.index === -1) { + // no texture, and therefore no billboard, for this glyph. + // so, completely unbind glyph. + unbindGlyph(labelCollection, glyph); + } else if (defined(glyph.textureInfo)) { + // we have a texture and billboard. If we had one before, release + // our reference to that texture info, but reuse the billboard. + glyph.textureInfo = undefined; + } + } else { + // create a glyph object + glyph = new Glyph(); + glyphs[textIndex] = glyph; + } + + glyph.textureInfo = glyphTextureInfo; + glyph.dimensions = glyphTextureInfo.dimensions; + + // if we have a texture, configure the existing billboard, or obtain one + if (glyphTextureInfo.index !== -1) { + var billboard = glyph.billboard; + var spareBillboards = labelCollection._spareBillboards; + if (!defined(billboard)) { + if (spareBillboards.length > 0) { + billboard = spareBillboards.pop(); + } else { + billboard = labelCollection._billboardCollection.add({ + collection : labelCollection + }); + } + glyph.billboard = billboard; + } + + billboard.show = label._show; + billboard.position = label._position; + billboard.eyeOffset = label._eyeOffset; + billboard.pixelOffset = label._pixelOffset; + billboard.horizontalOrigin = HorizontalOrigin.LEFT; + billboard.verticalOrigin = label._verticalOrigin; + billboard.heightReference = label._heightReference; + billboard.scale = label._scale; + billboard.pickPrimitive = label; + billboard.id = label._id; + billboard.image = id; + billboard.translucencyByDistance = label._translucencyByDistance; + billboard.pixelOffsetScaleByDistance = label._pixelOffsetScaleByDistance; + billboard.scaleByDistance = label._scaleByDistance; + billboard.distanceDisplayCondition = label._distanceDisplayCondition; + billboard.disableDepthTestDistance = label._disableDepthTestDistance; + billboard._batchIndex = label._batchIndex; + } } - var stencilEnabled = !classificationPrimitive.debugShowShadowVolume; - classificationPrimitive._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(stencilEnabled)); - classificationPrimitive._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(stencilEnabled)); - classificationPrimitive._rsColorPass = RenderState.fromCache(getColorRenderState(stencilEnabled)); - classificationPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); + // changing glyphs will cause the position of the + // glyphs to change, since different characters have different widths + label._repositionAllGlyphs = true; } - function modifyForEncodedNormals(primitive, vertexShaderSource) { - if (!primitive.compressVertices) { - return vertexShaderSource; + function calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding) { + if (horizontalOrigin === HorizontalOrigin.CENTER) { + return -lineWidth / 2; + } else if (horizontalOrigin === HorizontalOrigin.RIGHT) { + return -(lineWidth + backgroundPadding.x); } + return backgroundPadding.x; + } - if (vertexShaderSource.search(/attribute\s+vec3\s+extrudeDirection;/g) !== -1) { - var attributeName = 'compressedAttributes'; + // reusable Cartesian2 instances + var glyphPixelOffset = new Cartesian2(); + var scratchBackgroundPadding = new Cartesian2(); - //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes - var attributeDecl = 'attribute vec2 ' + attributeName + ';'; + function repositionAllGlyphs(label, resolutionScale) { + var glyphs = label._glyphs; + var text = label._renderedText; + var glyph; + var dimensions; + var lastLineWidth = 0; + var maxLineWidth = 0; + var lineWidths = []; + var maxGlyphDescent = Number.NEGATIVE_INFINITY; + var maxGlyphY = 0; + var numberOfLines = 1; + var glyphIndex = 0; + var glyphLength = glyphs.length; - var globalDecl = 'vec3 extrudeDirection;\n'; - var decode = ' extrudeDirection = czm_octDecode(' + attributeName + ', 65535.0);\n'; + var backgroundBillboard = label._backgroundBillboard; + var backgroundPadding = scratchBackgroundPadding; + Cartesian2.clone( + (defined(backgroundBillboard) ? label._backgroundPadding : Cartesian2.ZERO), + backgroundPadding); - var modifiedVS = vertexShaderSource; - modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+extrudeDirection;/g, ''); - modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); - var compressedMain = - 'void main() \n' + - '{ \n' + - decode + - ' czm_non_compressed_main(); \n' + - '}'; + for (glyphIndex = 0; glyphIndex < glyphLength; ++glyphIndex) { + if (text.charAt(glyphIndex) === '\n') { + lineWidths.push(lastLineWidth); + ++numberOfLines; + lastLineWidth = 0; + } else { + glyph = glyphs[glyphIndex]; + dimensions = glyph.dimensions; + maxGlyphY = Math.max(maxGlyphY, dimensions.height - dimensions.descent); + maxGlyphDescent = Math.max(maxGlyphDescent, dimensions.descent); - return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); + //Computing the line width must also account for the kerning that occurs between letters. + lastLineWidth += dimensions.width - dimensions.bounds.minx; + if (glyphIndex < glyphLength - 1) { + lastLineWidth += glyphs[glyphIndex + 1].dimensions.bounds.minx; + } + maxLineWidth = Math.max(maxLineWidth, lastLineWidth); + } } - } + lineWidths.push(lastLineWidth); + var maxLineHeight = maxGlyphY + maxGlyphDescent; - function createShaderProgram(classificationPrimitive, frameState, appearance) { - if (defined(classificationPrimitive._sp)) { - return; - } + var scale = label._scale; + var horizontalOrigin = label._horizontalOrigin; + var verticalOrigin = label._verticalOrigin; + var lineIndex = 0; + var lineWidth = lineWidths[lineIndex]; + var widthOffset = calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding); + var lineSpacing = defaultLineSpacingPercent * maxLineHeight; + var otherLinesHeight = lineSpacing * (numberOfLines - 1); - var context = frameState.context; - var primitive = classificationPrimitive._primitive; - var vs = ShadowVolumeVS; - vs = classificationPrimitive._primitive._batchTable.getVertexShaderCallback()(vs); - vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs); - vs = Primitive._modifyShaderPosition(classificationPrimitive, vs, frameState.scene3DOnly); - vs = Primitive._updateColorAttribute(primitive, vs); + glyphPixelOffset.x = widthOffset * scale * resolutionScale; + glyphPixelOffset.y = 0; - if (classificationPrimitive._extruded) { - vs = modifyForEncodedNormals(primitive, vs); - } + var lineOffsetY = 0; + for (glyphIndex = 0; glyphIndex < glyphLength; ++glyphIndex) { + if (text.charAt(glyphIndex) === '\n') { + ++lineIndex; + lineOffsetY += lineSpacing; + lineWidth = lineWidths[lineIndex]; + widthOffset = calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding); + glyphPixelOffset.x = widthOffset * scale * resolutionScale; + } else { + glyph = glyphs[glyphIndex]; + dimensions = glyph.dimensions; - var extrudedDefine = classificationPrimitive._extruded ? 'EXTRUDED_GEOMETRY' : ''; + if (verticalOrigin === VerticalOrigin.TOP) { + glyphPixelOffset.y = dimensions.height - maxGlyphY - backgroundPadding.y; + } else if (verticalOrigin === VerticalOrigin.CENTER) { + glyphPixelOffset.y = (otherLinesHeight + dimensions.height - maxGlyphY) / 2; + } else if (verticalOrigin === VerticalOrigin.BASELINE) { + glyphPixelOffset.y = otherLinesHeight; + } else { + // VerticalOrigin.BOTTOM + glyphPixelOffset.y = otherLinesHeight + maxGlyphDescent + backgroundPadding.y; + } + glyphPixelOffset.y = (glyphPixelOffset.y - dimensions.descent - lineOffsetY) * scale * resolutionScale; - var vsSource = new ShaderSource({ - defines : [extrudedDefine], - sources : [vs] - }); - var fsSource = new ShaderSource({ - sources : [ShadowVolumeFS] - }); - var attributeLocations = classificationPrimitive._primitive._attributeLocations; + if (defined(glyph.billboard)) { + glyph.billboard._setTranslate(glyphPixelOffset); + } - classificationPrimitive._spStencil = ShaderProgram.replaceCache({ - context : context, - shaderProgram : classificationPrimitive._spStencil, - vertexShaderSource : vsSource, - fragmentShaderSource : fsSource, - attributeLocations : attributeLocations - }); + //Compute the next x offset taking into acocunt the kerning performed + //on both the current letter as well as the next letter to be drawn + //as well as any applied scale. + if (glyphIndex < glyphLength - 1) { + var nextGlyph = glyphs[glyphIndex + 1]; + glyphPixelOffset.x += ((dimensions.width - dimensions.bounds.minx) + nextGlyph.dimensions.bounds.minx) * scale * resolutionScale; + } + } + } - if (classificationPrimitive._primitive.allowPicking) { - var vsPick = ShaderSource.createPickVertexShaderSource(vs); - vsPick = Primitive._appendShowToShader(primitive, vsPick); - vsPick = Primitive._updatePickColorAttribute(vsPick); + if (defined(backgroundBillboard) && (text.split('\n').join('').length > 0)) { + if (horizontalOrigin === HorizontalOrigin.CENTER) { + widthOffset = -maxLineWidth / 2 - backgroundPadding.x; + } else if (horizontalOrigin === HorizontalOrigin.RIGHT) { + widthOffset = -(maxLineWidth + backgroundPadding.x * 2); + } else { + widthOffset = 0; + } + glyphPixelOffset.x = widthOffset * scale * resolutionScale; - var pickVS = new ShaderSource({ - defines : [extrudedDefine], - sources : [vsPick] - }); + if (verticalOrigin === VerticalOrigin.TOP) { + glyphPixelOffset.y = maxLineHeight - maxGlyphY - maxGlyphDescent; + } else if (verticalOrigin === VerticalOrigin.CENTER) { + glyphPixelOffset.y = (maxLineHeight - maxGlyphY) / 2 - maxGlyphDescent; + } else if (verticalOrigin === VerticalOrigin.BASELINE) { + glyphPixelOffset.y = -backgroundPadding.y - maxGlyphDescent; + } else { + // VerticalOrigin.BOTTOM + glyphPixelOffset.y = 0; + } + glyphPixelOffset.y = glyphPixelOffset.y * scale * resolutionScale; - var pickFS = new ShaderSource({ - sources : [ShadowVolumeFS], - pickColorQualifier : 'varying' - }); + backgroundBillboard.width = maxLineWidth + (backgroundPadding.x * 2); + backgroundBillboard.height = maxLineHeight + otherLinesHeight + (backgroundPadding.y * 2); + backgroundBillboard._setTranslate(glyphPixelOffset); + } + } - classificationPrimitive._spPick = ShaderProgram.replaceCache({ - context : context, - shaderProgram : classificationPrimitive._spPick, - vertexShaderSource : pickVS, - fragmentShaderSource : pickFS, - attributeLocations : attributeLocations - }); - } else { - classificationPrimitive._spPick = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : vsSource, - fragmentShaderSource : fsSource, - attributeLocations : attributeLocations - }); + function destroyLabel(labelCollection, label) { + var glyphs = label._glyphs; + for (var i = 0, len = glyphs.length; i < len; ++i) { + unbindGlyph(labelCollection, glyphs[i]); } + if (defined(label._backgroundBillboard)) { + labelCollection._backgroundBillboardCollection.remove(label._backgroundBillboard); + label._backgroundBillboard = undefined; + } + label._labelCollection = undefined; - vs = Primitive._appendShowToShader(primitive, vs); - vsSource = new ShaderSource({ - defines : [extrudedDefine], - sources : [vs] + if (defined(label._removeCallbackFunc)) { + label._removeCallbackFunc(); + } + + destroyObject(label); + } + + /** + * A renderable collection of labels. Labels are viewport-aligned text positioned in the 3D scene. + * Each label can have a different font, color, scale, etc. + * <br /><br /> + * <div align='center'> + * <img src='Images/Label.png' width='400' height='300' /><br /> + * Example labels + * </div> + * <br /><br /> + * Labels are added and removed from the collection using {@link LabelCollection#add} + * and {@link LabelCollection#remove}. + * + * @alias LabelCollection + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each label from model to world coordinates. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {Scene} [options.scene] Must be passed in for labels that use the height reference property or will be depth tested against the globe. + * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The label blending option. The default + * is used for rendering both opaque and translucent labels. However, if either all of the labels are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. + * + * @performance For best performance, prefer a few collections, each with many labels, to + * many collections with only a few labels each. Avoid having collections where some + * labels change every frame and others do not; instead, create one or more collections + * for static labels, and one or more collections for dynamic labels. + * + * @see LabelCollection#add + * @see LabelCollection#remove + * @see Label + * @see BillboardCollection + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Labels.html|Cesium Sandcastle Labels Demo} + * + * @example + * // Create a label collection with two labels + * var labels = scene.primitives.add(new Cesium.LabelCollection()); + * labels.add({ + * position : new Cesium.Cartesian3(1.0, 2.0, 3.0), + * text : 'A label' + * }); + * labels.add({ + * position : new Cesium.Cartesian3(4.0, 5.0, 6.0), + * text : 'Another label' + * }); + */ + function LabelCollection(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._scene = options.scene; + this._batchTable = options.batchTable; + + this._textureAtlas = undefined; + this._backgroundTextureAtlas = undefined; + this._whitePixelIndex = undefined; + + this._backgroundBillboardCollection = new BillboardCollection({ + scene : this._scene }); + this._backgroundBillboardCollection.destroyTextureAtlas = false; - classificationPrimitive._sp = ShaderProgram.replaceCache({ - context : context, - shaderProgram : classificationPrimitive._sp, - vertexShaderSource : vsSource, - fragmentShaderSource : fsSource, - attributeLocations : attributeLocations + this._billboardCollection = new BillboardCollection({ + scene : this._scene, + batchTable : this._batchTable }); - } + this._billboardCollection.destroyTextureAtlas = false; - function createColorCommands(classificationPrimitive, colorCommands) { - var primitive = classificationPrimitive._primitive; - var length = primitive._va.length * 3; - colorCommands.length = length * 2; + this._spareBillboards = []; + this._glyphTextureCache = {}; + this._labels = []; + this._labelsToUpdate = []; + this._totalGlyphCount = 0; + this._resolutionScale = undefined; - var i; - var command; - var vaIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); + this._highlightColor = Color.clone(Color.WHITE); // Only used by Vector3DTilePoints - for (i = 0; i < length; i += 3) { - var vertexArray = primitive._va[vaIndex++]; + /** + * The 4x4 transformation matrix that transforms each label in this collection from model to world coordinates. + * When this is the identity matrix, the labels are drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. + * + * @type Matrix4 + * @default {@link Matrix4.IDENTITY} + * + * @example + * var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); + * labels.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + * labels.add({ + * position : new Cesium.Cartesian3(0.0, 0.0, 0.0), + * text : 'Center' + * }); + * labels.add({ + * position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0), + * text : 'East' + * }); + * labels.add({ + * position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0), + * text : 'North' + * }); + * labels.add({ + * position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0), + * text : 'Up' + * }); + */ + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - // stencil preload command - command = colorCommands[i]; - if (!defined(command)) { - command = colorCommands[i] = new DrawCommand({ - owner : classificationPrimitive, - primitiveType : primitive._primitiveType - }); - } + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the primitive. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - command.vertexArray = vertexArray; - command.renderState = classificationPrimitive._rsStencilPreloadPass; - command.shaderProgram = classificationPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.TERRAIN_CLASSIFICATION; + /** + * The label blending option. The default is used for rendering both opaque and translucent labels. + * However, if either all of the labels are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve + * performance by up to 2x. + * @type {BlendOption} + * @default BlendOption.OPAQUE_AND_TRANSLUCENT + */ + this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); + } - // stencil depth command - command = colorCommands[i + 1]; - if (!defined(command)) { - command = colorCommands[i + 1] = new DrawCommand({ - owner : classificationPrimitive, - primitiveType : primitive._primitiveType - }); + defineProperties(LabelCollection.prototype, { + /** + * Returns the number of labels in this collection. This is commonly used with + * {@link LabelCollection#get} to iterate over all the labels + * in the collection. + * @memberof LabelCollection.prototype + * @type {Number} + */ + length : { + get : function() { + return this._labels.length; } + } + }); - command.vertexArray = vertexArray; - command.renderState = classificationPrimitive._rsStencilDepthPass; - command.shaderProgram = classificationPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.TERRAIN_CLASSIFICATION; + /** + * Creates and adds a label with the specified initial properties to the collection. + * The added label is returned so it can be modified or removed from the collection later. + * + * @param {Object}[options] A template describing the label's properties as shown in Example 1. + * @returns {Label} The label that was added to the collection. + * + * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer + * is rewritten; this operations is <code>O(n)</code> and also incurs + * CPU to GPU overhead. For best performance, add as many billboards as possible before + * calling <code>update</code>. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Example 1: Add a label, specifying all the default values. + * var l = labels.add({ + * show : true, + * position : Cesium.Cartesian3.ZERO, + * text : '', + * font : '30px sans-serif', + * fillColor : Cesium.Color.WHITE, + * outlineColor : Cesium.Color.BLACK, + * outlineWidth : 1.0, + * showBackground : false, + * backgroundColor : new Cesium.Color(0.165, 0.165, 0.165, 0.8), + * backgroundPadding : new Cesium.Cartesian2(7, 5), + * style : Cesium.LabelStyle.FILL, + * pixelOffset : Cesium.Cartesian2.ZERO, + * eyeOffset : Cesium.Cartesian3.ZERO, + * horizontalOrigin : Cesium.HorizontalOrigin.LEFT, + * verticalOrigin : Cesium.VerticalOrigin.BASELINE, + * scale : 1.0, + * translucencyByDistance : undefined, + * pixelOffsetScaleByDistance : undefined, + * heightReference : HeightReference.NONE, + * distanceDisplayCondition : undefined + * }); + * + * @example + * // Example 2: Specify only the label's cartographic position, + * // text, and font. + * var l = labels.add({ + * position : Cesium.Cartesian3.fromRadians(longitude, latitude, height), + * text : 'Hello World', + * font : '24px Helvetica', + * }); + * + * @see LabelCollection#remove + * @see LabelCollection#removeAll + */ + LabelCollection.prototype.add = function(options) { + var label = new Label(options, this); - // color command - command = colorCommands[i + 2]; - if (!defined(command)) { - command = colorCommands[i + 2] = new DrawCommand({ - owner : classificationPrimitive, - primitiveType : primitive._primitiveType - }); - } + this._labels.push(label); + this._labelsToUpdate.push(label); - command.vertexArray = vertexArray; - command.renderState = classificationPrimitive._rsColorPass; - command.shaderProgram = classificationPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.TERRAIN_CLASSIFICATION; + return label; + }; + + /** + * Removes a label from the collection. Once removed, a label is no longer usable. + * + * @param {Label} label The label to remove. + * @returns {Boolean} <code>true</code> if the label was removed; <code>false</code> if the label was not found in the collection. + * + * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer + * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For + * best performance, remove as many labels as possible before calling <code>update</code>. + * If you intend to temporarily hide a label, it is usually more efficient to call + * {@link Label#show} instead of removing and re-adding the label. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * var l = labels.add(...); + * labels.remove(l); // Returns true + * + * @see LabelCollection#add + * @see LabelCollection#removeAll + * @see Label#show + */ + LabelCollection.prototype.remove = function(label) { + if (defined(label) && label._labelCollection === this) { + var index = this._labels.indexOf(label); + if (index !== -1) { + this._labels.splice(index, 1); + destroyLabel(this, label); + return true; + } } + return false; + }; - for (i = 0; i < length; ++i) { - command = colorCommands[length + i] = DrawCommand.shallowClone(colorCommands[i], colorCommands[length + i]); - command.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; + /** + * Removes all labels from the collection. + * + * @performance <code>O(n)</code>. It is more efficient to remove all the labels + * from a collection and then add new ones than to create a new collection entirely. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * labels.add(...); + * labels.add(...); + * labels.removeAll(); + * + * @see LabelCollection#add + * @see LabelCollection#remove + */ + LabelCollection.prototype.removeAll = function() { + var labels = this._labels; + + for (var i = 0, len = labels.length; i < len; ++i) { + destroyLabel(this, labels[i]); } - var commandsIgnoreShow = classificationPrimitive._commandsIgnoreShow; - var spStencil = classificationPrimitive._spStencil; + labels.length = 0; + }; - var commandIndex = 0; - length = commandsIgnoreShow.length = length / 3 * 2; + /** + * Check whether this collection contains a given label. + * + * @param {Label} label The label to check for. + * @returns {Boolean} true if this collection contains the label, false otherwise. + * + * @see LabelCollection#get + */ + LabelCollection.prototype.contains = function(label) { + return defined(label) && label._labelCollection === this; + }; + + /** + * Returns the label in the collection at the specified index. Indices are zero-based + * and increase as labels are added. Removing a label shifts all labels after + * it to the left, changing their indices. This function is commonly used with + * {@link LabelCollection#length} to iterate over all the labels + * in the collection. + * + * @param {Number} index The zero-based index of the billboard. + * + * @returns {Label} The label at the specified index. + * + * @performance Expected constant time. If labels were removed from the collection and + * {@link Scene#render} was not called, an implicit <code>O(n)</code> + * operation is performed. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Toggle the show property of every label in the collection + * var len = labels.length; + * for (var i = 0; i < len; ++i) { + * var l = billboards.get(i); + * l.show = !l.show; + * } + * + * @see LabelCollection#length + */ + LabelCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); + } + + return this._labels[index]; + }; + + /** + * @private + */ + LabelCollection.prototype.update = function(frameState) { + var billboardCollection = this._billboardCollection; + var backgroundBillboardCollection = this._backgroundBillboardCollection; - for (var j = 0; j < length; j += 2) { - var commandIgnoreShow = commandsIgnoreShow[j] = DrawCommand.shallowClone(colorCommands[commandIndex], commandsIgnoreShow[j]); - commandIgnoreShow.shaderProgram = spStencil; - commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW; + billboardCollection.modelMatrix = this.modelMatrix; + billboardCollection.debugShowBoundingVolume = this.debugShowBoundingVolume; + backgroundBillboardCollection.modelMatrix = this.modelMatrix; + backgroundBillboardCollection.debugShowBoundingVolume = this.debugShowBoundingVolume; - commandIgnoreShow = commandsIgnoreShow[j + 1] = DrawCommand.shallowClone(colorCommands[commandIndex + 1], commandsIgnoreShow[j + 1]); - commandIgnoreShow.shaderProgram = spStencil; - commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW; + var context = frameState.context; - commandIndex += 3; + if (!defined(this._textureAtlas)) { + this._textureAtlas = new TextureAtlas({ + context : context + }); + billboardCollection.textureAtlas = this._textureAtlas; } - } - function createPickCommands(classificationPrimitive, pickCommands) { - var primitive = classificationPrimitive._primitive; - var pickOffsets = primitive._pickOffsets; - var length = pickOffsets.length * 3; - pickCommands.length = length * 2; - - var j; - var command; - var pickIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); + if (!defined(this._backgroundTextureAtlas)) { + this._backgroundTextureAtlas = new TextureAtlas({ + context : context, + initialSize : whitePixelSize + }); + backgroundBillboardCollection.textureAtlas = this._backgroundTextureAtlas; + addWhitePixelCanvas(this._backgroundTextureAtlas, this); + } - for (j = 0; j < length; j += 3) { - var pickOffset = pickOffsets[pickIndex++]; + var uniformState = context.uniformState; + var resolutionScale = uniformState.resolutionScale; + var resolutionChanged = this._resolutionScale !== resolutionScale; + this._resolutionScale = resolutionScale; - var offset = pickOffset.offset; - var count = pickOffset.count; - var vertexArray = primitive._va[pickOffset.index]; + var labelsToUpdate; + if (resolutionChanged) { + labelsToUpdate = this._labels; + } else { + labelsToUpdate = this._labelsToUpdate; + } - // stencil preload command - command = pickCommands[j]; - if (!defined(command)) { - command = pickCommands[j] = new DrawCommand({ - owner : classificationPrimitive, - primitiveType : primitive._primitiveType - }); + var len = labelsToUpdate.length; + for (var i = 0; i < len; ++i) { + var label = labelsToUpdate[i]; + if (label.isDestroyed()) { + continue; } - command.vertexArray = vertexArray; - command.offset = offset; - command.count = count; - command.renderState = classificationPrimitive._rsStencilPreloadPass; - command.shaderProgram = classificationPrimitive._spStencil; - command.uniformMap = uniformMap; - command.pass = Pass.TERRAIN_CLASSIFICATION; + var preUpdateGlyphCount = label._glyphs.length; - // stencil depth command - command = pickCommands[j + 1]; - if (!defined(command)) { - command = pickCommands[j + 1] = new DrawCommand({ - owner : classificationPrimitive, - primitiveType : primitive._primitiveType - }); + if (label._rebindAllGlyphs) { + rebindAllGlyphs(this, label); + label._rebindAllGlyphs = false; } - command.vertexArray = vertexArray; - command.offset = offset; - command.count = count; - command.renderState = classificationPrimitive._rsStencilDepthPass; - command.shaderProgram = classificationPrimitive._spStencil; - command.uniformMap = uniformMap; - command.pass = Pass.TERRAIN_CLASSIFICATION; - - // color command - command = pickCommands[j + 2]; - if (!defined(command)) { - command = pickCommands[j + 2] = new DrawCommand({ - owner : classificationPrimitive, - primitiveType : primitive._primitiveType - }); + if (resolutionChanged || label._repositionAllGlyphs) { + repositionAllGlyphs(label, resolutionScale); + label._repositionAllGlyphs = false; } - command.vertexArray = vertexArray; - command.offset = offset; - command.count = count; - command.renderState = classificationPrimitive._rsPickPass; - command.shaderProgram = classificationPrimitive._spPick; - command.uniformMap = uniformMap; - command.pass = Pass.TERRAIN_CLASSIFICATION; + var glyphCountDifference = label._glyphs.length - preUpdateGlyphCount; + this._totalGlyphCount += glyphCountDifference; } - for (j = 0; j < length; ++j) { - command = pickCommands[length + j] = DrawCommand.shallowClone(pickCommands[j], pickCommands[length + j]); - command.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; - } - } + var blendOption = backgroundBillboardCollection.length > 0 ? BlendOption.TRANSLUCENT : this.blendOption; + billboardCollection.blendOption = blendOption; + backgroundBillboardCollection.blendOption = blendOption; - function createCommands(classificationPrimitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { - createColorCommands(classificationPrimitive, colorCommands); - createPickCommands(classificationPrimitive, pickCommands); - } + billboardCollection._highlightColor = this._highlightColor; + backgroundBillboardCollection._highlightColor = this._highlightColor; - function boundingVolumeIndex(commandIndex, length) { - return Math.floor((commandIndex % (length / 2)) / 3); - } + this._labelsToUpdate.length = 0; + backgroundBillboardCollection.update(frameState); + billboardCollection.update(frameState); + }; - var scratchCommandIndices = { - start : 0, - end : 0 + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see LabelCollection#destroy + */ + LabelCollection.prototype.isDestroyed = function() { + return false; }; - function getCommandIndices(classificationType, length) { - var startIndex; - var endIndex; - if (classificationType === ClassificationType.TERRAIN) { - startIndex = 0; - endIndex = length / 2; - } else if (classificationType === ClassificationType.CESIUM_3D_TILE) { - startIndex = length / 2; - endIndex = length; - } else { - startIndex = 0; - endIndex = length; - } + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * labels = labels && labels.destroy(); + * + * @see LabelCollection#isDestroyed + */ + LabelCollection.prototype.destroy = function() { + this.removeAll(); + this._billboardCollection = this._billboardCollection.destroy(); + this._textureAtlas = this._textureAtlas && this._textureAtlas.destroy(); + this._backgroundBillboardCollection = this._backgroundBillboardCollection.destroy(); + this._backgroundTextureAtlas = this._backgroundTextureAtlas && this._backgroundTextureAtlas.destroy(); - scratchCommandIndices.start = startIndex; - scratchCommandIndices.end = endIndex; - return scratchCommandIndices; - } + return destroyObject(this); + }; - function updateAndQueueCommands(classificationPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - var primitive = classificationPrimitive._primitive; - Primitive._updateBoundingVolumes(primitive, frameState, modelMatrix); + return LabelCollection; +}); - var boundingVolumes; - if (frameState.mode === SceneMode.SCENE3D) { - boundingVolumes = primitive._boundingSphereWC; - } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { - boundingVolumes = primitive._boundingSphereCV; - } else if (frameState.mode === SceneMode.SCENE2D && defined(primitive._boundingSphere2D)) { - boundingVolumes = primitive._boundingSphere2D; - } else if (defined(primitive._boundingSphereMorph)) { - boundingVolumes = primitive._boundingSphereMorph; - } +define('Scene/PointPrimitive',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/Matrix4', + '../Core/NearFarScalar', + './SceneMode', + './SceneTransforms' + ], function( + BoundingRectangle, + Cartesian2, + Cartesian3, + Cartesian4, + Color, + defaultValue, + defined, + defineProperties, + DeveloperError, + DistanceDisplayCondition, + Matrix4, + NearFarScalar, + SceneMode, + SceneTransforms) { + 'use strict'; - var commandList = frameState.commandList; - var passes = frameState.passes; + /** + * A graphical point positioned in the 3D scene, that is created + * and rendered using a {@link PointPrimitiveCollection}. A point is created and its initial + * properties are set by calling {@link PointPrimitiveCollection#add}. + * + * @alias PointPrimitive + * + * @performance Reading a property, e.g., {@link PointPrimitive#show}, is constant time. + * Assigning to a property is constant time but results in + * CPU to GPU traffic when {@link PointPrimitiveCollection#update} is called. The per-pointPrimitive traffic is + * the same regardless of how many properties were updated. If most pointPrimitives in a collection need to be + * updated, it may be more efficient to clear the collection with {@link PointPrimitiveCollection#removeAll} + * and add new pointPrimitives instead of modifying each one. + * + * @exception {DeveloperError} scaleByDistance.far must be greater than scaleByDistance.near + * @exception {DeveloperError} translucencyByDistance.far must be greater than translucencyByDistance.near + * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near + * + * @see PointPrimitiveCollection + * @see PointPrimitiveCollection#add + * + * @internalConstructor + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Points.html|Cesium Sandcastle Points Demo} + */ + function PointPrimitive(options, pointPrimitiveCollection) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var i; - var indices; - var startIndex; - var endIndex; - var classificationType = classificationPrimitive.classificationType; + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } + + var translucencyByDistance = options.translucencyByDistance; + var scaleByDistance = options.scaleByDistance; + var distanceDisplayCondition = options.distanceDisplayCondition; + if (defined(translucencyByDistance)) { + if (translucencyByDistance.far <= translucencyByDistance.near) { + throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + } + translucencyByDistance = NearFarScalar.clone(translucencyByDistance); + } + if (defined(scaleByDistance)) { + if (scaleByDistance.far <= scaleByDistance.near) { + throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + } + scaleByDistance = NearFarScalar.clone(scaleByDistance); + } + if (defined(distanceDisplayCondition)) { + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); + } + distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); + } - if (passes.render) { - var colorCommand; - var colorLength = colorCommands.length; - indices = getCommandIndices(classificationType, colorLength); - startIndex = indices.start; - endIndex = indices.end; + this._show = defaultValue(options.show, true); + this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); + this._actualPosition = Cartesian3.clone(this._position); // For columbus view and 2D + this._color = Color.clone(defaultValue(options.color, Color.WHITE)); + this._outlineColor = Color.clone(defaultValue(options.outlineColor, Color.TRANSPARENT)); + this._outlineWidth = defaultValue(options.outlineWidth, 0.0); + this._pixelSize = defaultValue(options.pixelSize, 10.0); + this._scaleByDistance = scaleByDistance; + this._translucencyByDistance = translucencyByDistance; + this._distanceDisplayCondition = distanceDisplayCondition; + this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); + this._id = options.id; + this._collection = defaultValue(options.collection, pointPrimitiveCollection); - for (i = startIndex; i < endIndex; ++i) { - colorCommand = colorCommands[i]; - colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingVolumes[boundingVolumeIndex(i, colorLength)]; - colorCommand.cull = cull; - colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + this._clusterShow = true; - commandList.push(colorCommand); - } + this._pickId = undefined; + this._pointPrimitiveCollection = pointPrimitiveCollection; + this._dirty = false; + this._index = -1; //Used only by PointPrimitiveCollection + } - if (frameState.invertClassification) { - var ignoreShowCommands = classificationPrimitive._commandsIgnoreShow; - startIndex = 0; - endIndex = ignoreShowCommands.length; + var SHOW_INDEX = PointPrimitive.SHOW_INDEX = 0; + var POSITION_INDEX = PointPrimitive.POSITION_INDEX = 1; + var COLOR_INDEX = PointPrimitive.COLOR_INDEX = 2; + var OUTLINE_COLOR_INDEX = PointPrimitive.OUTLINE_COLOR_INDEX = 3; + var OUTLINE_WIDTH_INDEX = PointPrimitive.OUTLINE_WIDTH_INDEX = 4; + var PIXEL_SIZE_INDEX = PointPrimitive.PIXEL_SIZE_INDEX = 5; + var SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX = 6; + var TRANSLUCENCY_BY_DISTANCE_INDEX = PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX = 7; + var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX = 8; + var DISABLE_DEPTH_DISTANCE_INDEX = PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX = 9; + PointPrimitive.NUMBER_OF_PROPERTIES = 10; - for (i = startIndex; i < endIndex; ++i) { - var bvIndex = Math.floor(i / 2); - colorCommand = ignoreShowCommands[i]; - colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingVolumes[bvIndex]; - colorCommand.cull = cull; - colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + function makeDirty(pointPrimitive, propertyChanged) { + var pointPrimitiveCollection = pointPrimitive._pointPrimitiveCollection; + if (defined(pointPrimitiveCollection)) { + pointPrimitiveCollection._updatePointPrimitive(pointPrimitive, propertyChanged); + pointPrimitive._dirty = true; + } + } - commandList.push(colorCommand); + defineProperties(PointPrimitive.prototype, { + /** + * Determines if this point will be shown. Use this to hide or show a point, instead + * of removing it and re-adding it to the collection. + * @memberof PointPrimitive.prototype + * @type {Boolean} + */ + show : { + get : function() { + return this._show; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._show !== value) { + this._show = value; + makeDirty(this, SHOW_INDEX); } } - } - - if (passes.pick) { - var pickLength = pickCommands.length; - indices = getCommandIndices(classificationType, pickLength); - startIndex = indices.start; - endIndex = indices.end; + }, - var pickOffsets = primitive._pickOffsets; - for (i = startIndex; i < endIndex; ++i) { - var pickOffset = pickOffsets[boundingVolumeIndex(i, pickLength)]; - var pickCommand = pickCommands[i]; - pickCommand.modelMatrix = modelMatrix; - pickCommand.boundingVolume = boundingVolumes[pickOffset.index]; - pickCommand.cull = cull; + /** + * Gets or sets the Cartesian position of this point. + * @memberof PointPrimitive.prototype + * @type {Cartesian3} + */ + position : { + get : function() { + return this._position; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var position = this._position; + if (!Cartesian3.equals(position, value)) { + Cartesian3.clone(value, position); + Cartesian3.clone(value, this._actualPosition); - commandList.push(pickCommand); + makeDirty(this, POSITION_INDEX); + } } - } - } - - /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> - * - * @exception {DeveloperError} All instance geometries must have the same primitiveType. - * @exception {DeveloperError} Appearance and material have a uniform with the same name. - * @exception {DeveloperError} Not all of the geometry instances have the same color attribute. - */ - ClassificationPrimitive.prototype.update = function(frameState) { - if (!this.show || (!defined(this._primitive) && !defined(this.geometryInstances))) { - return; - } - - var that = this; - var primitiveOptions = this._primitiveOptions; + }, - if (!defined(this._primitive)) { - var instances = isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; - var length = instances.length; + /** + * Gets or sets near and far scaling properties of a point based on the point's distance from the camera. + * A point's scale will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the point's scale remains clamped to the nearest bound. This scale + * multiplies the pixelSize and outlineWidth to affect the total size of the point. If undefined, + * scaleByDistance will be disabled. + * @memberof PointPrimitive.prototype + * @type {NearFarScalar} + * + * @example + * // Example 1. + * // Set a pointPrimitive's scaleByDistance to scale to 15 when the + * // camera is 1500 meters from the pointPrimitive and disappear as + * // the camera distance approaches 8.0e6 meters. + * p.scaleByDistance = new Cesium.NearFarScalar(1.5e2, 15, 8.0e6, 0.0); + * + * @example + * // Example 2. + * // disable scaling by distance + * p.scaleByDistance = undefined; + */ + scaleByDistance : { + get : function() { + return this._scaleByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var scaleByDistance = this._scaleByDistance; + if (!NearFarScalar.equals(scaleByDistance, value)) { + this._scaleByDistance = NearFarScalar.clone(value, scaleByDistance); + makeDirty(this, SCALE_BY_DISTANCE_INDEX); + } + } + }, - var i; - var instance; - var color; - for (i = 0; i < length; ++i) { - instance = instances[i]; - var attributes = instance.attributes; - if (!defined(attributes) || !defined(attributes.color)) { - throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); - } else if (defined(color) && !ColorGeometryInstanceAttribute.equals(color, attributes.color)) { - throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); - } else if (!defined(color)) { - color = attributes.color; + /** + * Gets or sets near and far translucency properties of a point based on the point's distance from the camera. + * A point's translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the point's translucency remains clamped to the nearest bound. If undefined, + * translucencyByDistance will be disabled. + * @memberof PointPrimitive.prototype + * @type {NearFarScalar} + * + * @example + * // Example 1. + * // Set a point's translucency to 1.0 when the + * // camera is 1500 meters from the point and disappear as + * // the camera distance approaches 8.0e6 meters. + * p.translucencyByDistance = new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.0); + * + * @example + * // Example 2. + * // disable translucency by distance + * p.translucencyByDistance = undefined; + */ + translucencyByDistance : { + get : function() { + return this._translucencyByDistance; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); + } + + var translucencyByDistance = this._translucencyByDistance; + if (!NearFarScalar.equals(translucencyByDistance, value)) { + this._translucencyByDistance = NearFarScalar.clone(value, translucencyByDistance); + makeDirty(this, TRANSLUCENCY_BY_DISTANCE_INDEX); } } - - var geometryInstances = new Array(length); - for (i = 0; i < length; ++i) { - instance = instances[i]; - geometryInstances[i] = new GeometryInstance({ - geometry : instance.geometry, - attributes : instance.attributes, - modelMatrix : instance.modelMatrix, - id : instance.id, - pickPrimitive : defaultValue(this._pickPrimitive, that) - }); + }, + + /** + * Gets or sets the inner size of the point in pixels. + * @memberof PointPrimitive.prototype + * @type {Number} + */ + pixelSize : { + get : function() { + return this._pixelSize; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._pixelSize !== value) { + this._pixelSize = value; + makeDirty(this, PIXEL_SIZE_INDEX); + } } + }, - primitiveOptions.geometryInstances = geometryInstances; + /** + * Gets or sets the inner color of the point. + * The red, green, blue, and alpha values are indicated by <code>value</code>'s <code>red</code>, <code>green</code>, + * <code>blue</code>, and <code>alpha</code> properties as shown in Example 1. These components range from <code>0.0</code> + * (no intensity) to <code>1.0</code> (full intensity). + * @memberof PointPrimitive.prototype + * @type {Color} + * + * @example + * // Example 1. Assign yellow. + * p.color = Cesium.Color.YELLOW; + * + * @example + * // Example 2. Make a pointPrimitive 50% translucent. + * p.color = new Cesium.Color(1.0, 1.0, 1.0, 0.5); + */ + color : { + get : function() { + return this._color; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var color = this._color; + if (!Color.equals(color, value)) { + Color.clone(value, color); + makeDirty(this, COLOR_INDEX); + } + } + }, - if (defined(this._createBoundingVolumeFunction)) { - primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { - that._createBoundingVolumeFunction(frameState, geometry); - }; + /** + * Gets or sets the outline color of the point. + * @memberof PointPrimitive.prototype + * @type {Color} + */ + outlineColor : { + get : function() { + return this._outlineColor; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var outlineColor = this._outlineColor; + if (!Color.equals(outlineColor, value)) { + Color.clone(value, outlineColor); + makeDirty(this, OUTLINE_COLOR_INDEX); + } } + }, - primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { - createRenderStates(that, context); - }; - primitiveOptions._createShaderProgramFunction = function(primitive, frameState, appearance) { - createShaderProgram(that, frameState); - }; - primitiveOptions._createCommandsFunction = function(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { - createCommands(that, undefined, undefined, true, false, colorCommands, pickCommands); - }; + /** + * Gets or sets the outline width in pixels. This width adds to pixelSize, + * increasing the total size of the point. + * @memberof PointPrimitive.prototype + * @type {Number} + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._outlineWidth !== value) { + this._outlineWidth = value; + makeDirty(this, OUTLINE_WIDTH_INDEX); + } + } + }, - if (defined(this._updateAndQueueCommandsFunction)) { - primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - that._updateAndQueueCommandsFunction(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); - }; - } else { - primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); - }; + /** + * Gets or sets the condition specifying at what distance from the camera that this point will be displayed. + * @memberof PointPrimitive.prototype + * @type {DistanceDisplayCondition} + * @default undefined + */ + distanceDisplayCondition : { + get : function() { + return this._distanceDisplayCondition; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far must be greater than near'); + } + if (!DistanceDisplayCondition.equals(this._distanceDisplayCondition, value)) { + this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); + makeDirty(this, DISTANCE_DISPLAY_CONDITION_INDEX); + } } + }, - this._primitive = new Primitive(primitiveOptions); - this._primitive.readyPromise.then(function(primitive) { - that._ready = true; + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof PointPrimitive.prototype + * @type {Number} + * @default 0.0 + */ + disableDepthTestDistance : { + get : function() { + return this._disableDepthTestDistance; + }, + set : function(value) { + if (this._disableDepthTestDistance !== value) { + if (!defined(value) || value < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } + this._disableDepthTestDistance = value; + makeDirty(this, DISABLE_DEPTH_DISTANCE_INDEX); + } + } + }, - if (that.releaseGeometryInstances) { - that.geometryInstances = undefined; + /** + * Gets or sets the user-defined object returned when the point is picked. + * @memberof PointPrimitive.prototype + * @type {Object} + */ + id : { + get : function() { + return this._id; + }, + set : function(value) { + this._id = value; + if (defined(this._pickId)) { + this._pickId.object.id = value; } + } + }, - var error = primitive._error; - if (!defined(error)) { - that._readyPromise.resolve(that); - } else { - that._readyPromise.reject(error); + /** + * Determines whether or not this point will be shown or hidden because it was clustered. + * @memberof PointPrimitive.prototype + * @type {Boolean} + * @private + */ + clusterShow : { + get : function() { + return this._clusterShow; + }, + set : function(value) { + if (this._clusterShow !== value) { + this._clusterShow = value; + makeDirty(this, SHOW_INDEX); } + } + } + }); + + PointPrimitive.prototype.getPickId = function(context) { + if (!defined(this._pickId)) { + this._pickId = context.createPickId({ + primitive : this, + collection : this._collection, + id : this._id }); } - if (this.debugShowShadowVolume && !this._debugShowShadowVolume && this._ready) { - this._debugShowShadowVolume = true; - this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(false)); - this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(false)); - this._rsColorPass = RenderState.fromCache(getColorRenderState(false)); - } else if (!this.debugShowShadowVolume && this._debugShowShadowVolume) { - this._debugShowShadowVolume = false; - this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(true)); - this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(true)); - this._rsColorPass = RenderState.fromCache(getColorRenderState(true)); + return this._pickId; + }; + + PointPrimitive.prototype._getActualPosition = function() { + return this._actualPosition; + }; + + PointPrimitive.prototype._setActualPosition = function(value) { + Cartesian3.clone(value, this._actualPosition); + makeDirty(this, POSITION_INDEX); + }; + + var tempCartesian3 = new Cartesian4(); + PointPrimitive._computeActualPosition = function(position, frameState, modelMatrix) { + if (frameState.mode === SceneMode.SCENE3D) { + return position; } - this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; - this._primitive.update(frameState); + Matrix4.multiplyByPoint(modelMatrix, position, tempCartesian3); + return SceneTransforms.computeActualWgs84Position(frameState, tempCartesian3); + }; + + var scratchCartesian4 = new Cartesian4(); + + // This function is basically a stripped-down JavaScript version of PointPrimitiveCollectionVS.glsl + PointPrimitive._computeScreenSpacePosition = function(modelMatrix, position, scene, result) { + // Model to world coordinates + var positionWorld = Matrix4.multiplyByVector(modelMatrix, Cartesian4.fromElements(position.x, position.y, position.z, 1, scratchCartesian4), scratchCartesian4); + var positionWC = SceneTransforms.wgs84ToWindowCoordinates(scene, positionWorld, result); + return positionWC; }; /** - * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. + * Computes the screen-space position of the point's origin. + * The screen space origin is the top, left corner of the canvas; <code>x</code> increases from + * left to right, and <code>y</code> increases from top to bottom. * - * @param {Object} id The id of the {@link GeometryInstance}. - * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * @param {Scene} scene The scene. + * @param {Cartesian2} [result] The object onto which to store the result. + * @returns {Cartesian2} The screen-space position of the point. * - * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. + * @exception {DeveloperError} PointPrimitive must be in a collection. * * @example - * var attributes = primitive.getGeometryInstanceAttributes('an id'); - * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); - * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true); + * console.log(p.computeScreenSpacePosition(scene).toString()); */ - ClassificationPrimitive.prototype.getGeometryInstanceAttributes = function(id) { - if (!defined(this._primitive)) { - throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); + PointPrimitive.prototype.computeScreenSpacePosition = function(scene, result) { + var pointPrimitiveCollection = this._pointPrimitiveCollection; + if (!defined(result)) { + result = new Cartesian2(); } - return this._primitive.getGeometryInstanceAttributes(id); + + if (!defined(pointPrimitiveCollection)) { + throw new DeveloperError('PointPrimitive must be in a collection.'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + + var modelMatrix = pointPrimitiveCollection.modelMatrix; + var windowCoordinates = PointPrimitive._computeScreenSpacePosition(modelMatrix, this._actualPosition, scene, result); + if (!defined(windowCoordinates)) { + return undefined; + } + + windowCoordinates.y = scene.canvas.clientHeight - windowCoordinates.y; + return windowCoordinates; }; /** - * Returns true if this object was destroyed; otherwise, false. - * <p> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * </p> - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * Gets a point's screen space bounding box centered around screenSpacePosition. + * @param {PointPrimitive} point The point to get the screen space bounding box for. + * @param {Cartesian2} screenSpacePosition The screen space center of the label. + * @param {BoundingRectangle} [result] The object onto which to store the result. + * @returns {BoundingRectangle} The screen space bounding box. * - * @see ClassificationPrimitive#destroy + * @private */ - ClassificationPrimitive.prototype.isDestroyed = function() { - return false; + PointPrimitive.getScreenSpaceBoundingBox = function(point, screenSpacePosition, result) { + var size = point.pixelSize; + var halfSize = size * 0.5; + + var x = screenSpacePosition.x - halfSize; + var y = screenSpacePosition.y - halfSize; + var width = size; + var height = size; + + if (!defined(result)) { + result = new BoundingRectangle(); + } + + result.x = x; + result.y = y; + result.width = width; + result.height = height; + + return result; }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <p> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * </p> - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @example - * e = e && e.destroy(); + * Determines if this point equals another point. Points are equal if all their properties + * are equal. Points in different collections can be equal. * - * @see ClassificationPrimitive#isDestroyed + * @param {PointPrimitive} other The point to compare for equality. + * @returns {Boolean} <code>true</code> if the points are equal; otherwise, <code>false</code>. */ - ClassificationPrimitive.prototype.destroy = function() { - this._primitive = this._primitive && this._primitive.destroy(); - this._sp = this._sp && this._sp.destroy(); - this._spPick = this._spPick && this._spPick.destroy(); - return destroyObject(this); + PointPrimitive.prototype.equals = function(other) { + return this === other || + defined(other) && + this._id === other._id && + Cartesian3.equals(this._position, other._position) && + Color.equals(this._color, other._color) && + this._pixelSize === other._pixelSize && + this._outlineWidth === other._outlineWidth && + this._show === other._show && + Color.equals(this._outlineColor, other._outlineColor) && + NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && + NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && + DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && + this._disableDepthTestDistance === other._disableDepthTestDistance; }; - return ClassificationPrimitive; + PointPrimitive.prototype._destroy = function() { + this._pickId = this._pickId && this._pickId.destroy(); + this._pointPrimitiveCollection = undefined; + }; + + return PointPrimitive; +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PointPrimitiveCollectionFS',[],function() { + 'use strict'; + return "varying vec4 v_color;\n\ +varying vec4 v_outlineColor;\n\ +varying float v_innerPercent;\n\ +varying float v_pixelDistance;\n\ +#ifdef RENDER_FOR_PICK\n\ +varying vec4 v_pickColor;\n\ +#endif\n\ +void main()\n\ +{\n\ +float distanceToCenter = length(gl_PointCoord - vec2(0.5));\n\ +float maxDistance = max(0.0, 0.5 - v_pixelDistance);\n\ +float wholeAlpha = 1.0 - smoothstep(maxDistance, 0.5, distanceToCenter);\n\ +float innerAlpha = 1.0 - smoothstep(maxDistance * v_innerPercent, 0.5 * v_innerPercent, distanceToCenter);\n\ +vec4 color = mix(v_outlineColor, v_color, innerAlpha);\n\ +color.a *= wholeAlpha;\n\ +#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\n\ +if (color.a < 0.005)\n\ +{\n\ +discard;\n\ +}\n\ +#else\n\ +#ifdef OPAQUE\n\ +if (color.a < 0.995)\n\ +{\n\ +discard;\n\ +}\n\ +#else\n\ +if (color.a >= 0.995)\n\ +{\n\ +discard;\n\ +}\n\ +#endif\n\ +#endif\n\ +#ifdef RENDER_FOR_PICK\n\ +gl_FragColor = v_pickColor;\n\ +#else\n\ +gl_FragColor = color;\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PointPrimitiveCollectionVS',[],function() { + 'use strict'; + return "uniform float u_maxTotalPointSize;\n\ +attribute vec4 positionHighAndSize;\n\ +attribute vec4 positionLowAndOutline;\n\ +attribute vec4 compressedAttribute0;\n\ +attribute vec4 compressedAttribute1;\n\ +attribute vec4 scaleByDistance;\n\ +attribute vec3 distanceDisplayConditionAndDisableDepth;\n\ +varying vec4 v_color;\n\ +varying vec4 v_outlineColor;\n\ +varying float v_innerPercent;\n\ +varying float v_pixelDistance;\n\ +#ifdef RENDER_FOR_PICK\n\ +varying vec4 v_pickColor;\n\ +#endif\n\ +const float SHIFT_LEFT8 = 256.0;\n\ +const float SHIFT_RIGHT8 = 1.0 / 256.0;\n\ +void main()\n\ +{\n\ +vec3 positionHigh = positionHighAndSize.xyz;\n\ +vec3 positionLow = positionLowAndOutline.xyz;\n\ +float outlineWidthBothSides = 2.0 * positionLowAndOutline.w;\n\ +float totalSize = positionHighAndSize.w + outlineWidthBothSides;\n\ +float outlinePercent = outlineWidthBothSides / totalSize;\n\ +totalSize *= czm_resolutionScale;\n\ +totalSize += 3.0;\n\ +float temp = compressedAttribute1.x * SHIFT_RIGHT8;\n\ +float show = floor(temp);\n\ +#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ +vec4 translucencyByDistance;\n\ +translucencyByDistance.x = compressedAttribute1.z;\n\ +translucencyByDistance.z = compressedAttribute1.w;\n\ +translucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ +temp = compressedAttribute1.y * SHIFT_RIGHT8;\n\ +translucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ +#endif\n\ +vec4 color;\n\ +vec4 outlineColor;\n\ +#ifdef RENDER_FOR_PICK\n\ +color = vec4(0.0);\n\ +outlineColor = vec4(0.0);\n\ +vec4 pickColor;\n\ +temp = compressedAttribute0.z * SHIFT_RIGHT8;\n\ +pickColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +temp = floor(temp) * SHIFT_RIGHT8;\n\ +pickColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +pickColor.r = floor(temp);\n\ +#else\n\ +temp = compressedAttribute0.x * SHIFT_RIGHT8;\n\ +color.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +temp = floor(temp) * SHIFT_RIGHT8;\n\ +color.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +color.r = floor(temp);\n\ +temp = compressedAttribute0.y * SHIFT_RIGHT8;\n\ +outlineColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +temp = floor(temp) * SHIFT_RIGHT8;\n\ +outlineColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +outlineColor.r = floor(temp);\n\ +#endif\n\ +temp = compressedAttribute0.w * SHIFT_RIGHT8;\n\ +#ifdef RENDER_FOR_PICK\n\ +pickColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +pickColor = pickColor / 255.0;\n\ +#endif\n\ +temp = floor(temp) * SHIFT_RIGHT8;\n\ +outlineColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\n\ +outlineColor /= 255.0;\n\ +color.a = floor(temp);\n\ +color /= 255.0;\n\ +vec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\n\ +vec4 positionEC = czm_modelViewRelativeToEye * p;\n\ +positionEC.xyz *= show;\n\ +#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\n\ +float lengthSq;\n\ +if (czm_sceneMode == czm_sceneMode2D)\n\ +{\n\ +lengthSq = czm_eyeHeight2D.y;\n\ +}\n\ +else\n\ +{\n\ +lengthSq = dot(positionEC.xyz, positionEC.xyz);\n\ +}\n\ +#endif\n\ +#ifdef EYE_DISTANCE_SCALING\n\ +totalSize *= czm_nearFarScalar(scaleByDistance, lengthSq);\n\ +#endif\n\ +totalSize = min(totalSize, u_maxTotalPointSize);\n\ +if (totalSize < 1.0)\n\ +{\n\ +positionEC.xyz = vec3(0.0);\n\ +totalSize = 1.0;\n\ +}\n\ +float translucency = 1.0;\n\ +#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ +translucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\n\ +if (translucency < 0.004)\n\ +{\n\ +positionEC.xyz = vec3(0.0);\n\ +}\n\ +#endif\n\ +#ifdef DISTANCE_DISPLAY_CONDITION\n\ +float nearSq = distanceDisplayConditionAndDisableDepth.x;\n\ +float farSq = distanceDisplayConditionAndDisableDepth.y;\n\ +if (lengthSq < nearSq || lengthSq > farSq) {\n\ +positionEC.xyz = vec3(0.0);\n\ +}\n\ +#endif\n\ +vec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\n\ +gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\n\ +#ifdef DISABLE_DEPTH_DISTANCE\n\ +float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\n\ +if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n\ +{\n\ +disableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n\ +}\n\ +if (disableDepthTestDistance != 0.0)\n\ +{\n\ +float zclip = gl_Position.z / gl_Position.w;\n\ +bool clipped = (zclip < -1.0 || zclip > 1.0);\n\ +if (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n\ +{\n\ +gl_Position.z = -gl_Position.w;\n\ +}\n\ +}\n\ +#endif\n\ +v_color = color;\n\ +v_color.a *= translucency;\n\ +v_outlineColor = outlineColor;\n\ +v_outlineColor.a *= translucency;\n\ +v_innerPercent = 1.0 - outlinePercent;\n\ +v_pixelDistance = 2.0 / totalSize;\n\ +gl_PointSize = totalSize;\n\ +#ifdef RENDER_FOR_PICK\n\ +v_pickColor = pickColor;\n\ +#endif\n\ +}\n\ +"; }); - -define('Scene/GroundPrimitive',[ +define('Scene/PointPrimitiveCollection',[ '../Core/BoundingSphere', - '../Core/buildModuleUrl', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartographic', + '../Core/Color', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/GeographicTilingScheme', - '../Core/GeometryInstance', - '../Core/isArray', - '../Core/loadJson', + '../Core/EncodedCartesian3', '../Core/Math', - '../Core/OrientedBoundingBox', - '../Core/Rectangle', - '../ThirdParty/when', - './ClassificationPrimitive', - './ClassificationType', + '../Core/Matrix4', + '../Core/PrimitiveType', + '../Core/WebGLConstants', + '../Renderer/BufferUsage', + '../Renderer/ContextLimits', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArrayFacade', + '../Shaders/PointPrimitiveCollectionFS', + '../Shaders/PointPrimitiveCollectionVS', + './BlendingState', + './BlendOption', + './PointPrimitive', './SceneMode' ], function( BoundingSphere, - buildModuleUrl, - Cartesian2, - Cartesian3, - Cartographic, + Color, + ComponentDatatype, defaultValue, defined, defineProperties, destroyObject, DeveloperError, - GeographicTilingScheme, - GeometryInstance, - isArray, - loadJson, + EncodedCartesian3, CesiumMath, - OrientedBoundingBox, - Rectangle, - when, - ClassificationPrimitive, - ClassificationType, + Matrix4, + PrimitiveType, + WebGLConstants, + BufferUsage, + ContextLimits, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + VertexArrayFacade, + PointPrimitiveCollectionFS, + PointPrimitiveCollectionVS, + BlendingState, + BlendOption, + PointPrimitive, SceneMode) { 'use strict'; - var GroundPrimitiveUniformMap = { - u_globeMinimumAltitude: function() { - return 55000.0; - } + var SHOW_INDEX = PointPrimitive.SHOW_INDEX; + var POSITION_INDEX = PointPrimitive.POSITION_INDEX; + var COLOR_INDEX = PointPrimitive.COLOR_INDEX; + var OUTLINE_COLOR_INDEX = PointPrimitive.OUTLINE_COLOR_INDEX; + var OUTLINE_WIDTH_INDEX = PointPrimitive.OUTLINE_WIDTH_INDEX; + var PIXEL_SIZE_INDEX = PointPrimitive.PIXEL_SIZE_INDEX; + var SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX; + var TRANSLUCENCY_BY_DISTANCE_INDEX = PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX; + var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX; + var DISABLE_DEPTH_DISTANCE_INDEX = PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX; + var NUMBER_OF_PROPERTIES = PointPrimitive.NUMBER_OF_PROPERTIES; + + var attributeLocations = { + positionHighAndSize : 0, + positionLowAndOutline : 1, + compressedAttribute0 : 2, // color, outlineColor, pick color + compressedAttribute1 : 3, // show, translucency by distance, some free space + scaleByDistance : 4, + distanceDisplayConditionAndDisableDepth : 5 }; /** - * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. - * Batching multiple geometries is not yet supported. - * <p> - * A primitive combines the geometry instance with an {@link Appearance} that describes the full shading, including - * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, - * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix - * and match most of them and add a new geometry or appearance independently of each other. Only the {@link PerInstanceColorAppearance} - * is supported at this time. - * </p> - * <p> - * For correct rendering, this feature requires the EXT_frag_depth WebGL extension. For hardware that do not support this extension, there - * will be rendering artifacts for some viewing angles. - * </p> - * <p> - * Valid geometries are {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}. - * </p> + * A renderable collection of points. + * <br /><br /> + * Points are added and removed from the collection using {@link PointPrimitiveCollection#add} + * and {@link PointPrimitiveCollection#remove}. * - * @alias GroundPrimitive + * @alias PointPrimitiveCollection * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. - * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each point from model to world coordinates. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on - * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be <code>false</code>. + * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The point blending option. The default + * is used for rendering both opaque and translucent points. However, if either all of the points are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. * - * @example - * // Example 1: Create primitive with a single instance - * var rectangleInstance = new Cesium.GeometryInstance({ - * geometry : new Cesium.RectangleGeometry({ - * rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0) - * }), - * id : 'rectangle', - * attributes : { - * color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5) - * } - * }); - * scene.primitives.add(new Cesium.GroundPrimitive({ - * geometryInstances : rectangleInstance - * })); + * @performance For best performance, prefer a few collections, each with many points, to + * many collections with only a few points each. Organize collections so that points + * with the same update frequency are in the same collection, i.e., points that do not + * change should be in one collection; points that change every frame should be in another + * collection; and so on. * - * // Example 2: Batch instances - * var color = new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5); // Both instances must have the same color. - * var rectangleInstance = new Cesium.GeometryInstance({ - * geometry : new Cesium.RectangleGeometry({ - * rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0) - * }), - * id : 'rectangle', - * attributes : { - * color : color - * } + * + * @example + * // Create a pointPrimitive collection with two points + * var points = scene.primitives.add(new Cesium.PointPrimitiveCollection()); + * points.add({ + * position : new Cesium.Cartesian3(1.0, 2.0, 3.0), + * color : Cesium.Color.YELLOW * }); - * var ellipseInstance = new Cesium.GeometryInstance({ - * geometry : new Cesium.EllipseGeometry({ - * center : Cesium.Cartesian3.fromDegrees(-105.0, 40.0), - * semiMinorAxis : 300000.0, - * semiMajorAxis : 400000.0 - * }), - * id : 'ellipse', - * attributes : { - * color : color - * } + * points.add({ + * position : new Cesium.Cartesian3(4.0, 5.0, 6.0), + * color : Cesium.Color.CYAN * }); - * scene.primitives.add(new Cesium.GroundPrimitive({ - * geometryInstances : [rectangleInstance, ellipseInstance] - * })); * - * @see Primitive - * @see ClassificationPrimitive - * @see GeometryInstance - * @see Appearance + * @see PointPrimitiveCollection#add + * @see PointPrimitiveCollection#remove + * @see PointPrimitive */ - function GroundPrimitive(options) { + function PointPrimitiveCollection(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); + this._sp = undefined; + this._spTranslucent = undefined; + this._spPick = undefined; + this._rsOpaque = undefined; + this._rsTranslucent = undefined; + this._vaf = undefined; + + this._pointPrimitives = []; + this._pointPrimitivesToUpdate = []; + this._pointPrimitivesToUpdateIndex = 0; + this._pointPrimitivesRemoved = false; + this._createVertexArray = false; + + this._shaderScaleByDistance = false; + this._compiledShaderScaleByDistance = false; + this._compiledShaderScaleByDistancePick = false; + + this._shaderTranslucencyByDistance = false; + this._compiledShaderTranslucencyByDistance = false; + this._compiledShaderTranslucencyByDistancePick = false; + + this._shaderDistanceDisplayCondition = false; + this._compiledShaderDistanceDisplayCondition = false; + this._compiledShaderDistanceDisplayConditionPick = false; + + this._shaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistancePick = false; + + this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); + + this._maxPixelSize = 1.0; + + this._baseVolume = new BoundingSphere(); + this._baseVolumeWC = new BoundingSphere(); + this._baseVolume2D = new BoundingSphere(); + this._boundingVolume = new BoundingSphere(); + this._boundingVolumeDirty = false; + + this._colorCommands = []; + this._pickCommands = []; + /** - * The geometry instance rendered with this primitive. This may - * be <code>undefined</code> if <code>options.releaseGeometryInstances</code> - * is <code>true</code> when the primitive is constructed. - * <p> - * Changing this property after the primitive is rendered has no effect. - * </p> - * <p> - * Because of the rendering technique used, all geometry instances must be the same color. - * If there is an instance with a differing color, a <code>DeveloperError</code> will be thrown - * on the first attempt to render. - * </p> - * - * @readonly - * @type {Array|GeometryInstance} - * - * @default undefined - */ - this.geometryInstances = options.geometryInstances; - /** - * Determines if the primitive will be shown. This affects all geometry - * instances in the primitive. + * The 4x4 transformation matrix that transforms each point in this collection from model to world coordinates. + * When this is the identity matrix, the pointPrimitives are drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. * - * @type {Boolean} + * @type {Matrix4} + * @default {@link Matrix4.IDENTITY} * - * @default true - */ - this.show = defaultValue(options.show, true); - /** - * Determines whether terrain, 3D Tiles or both will be classified. * - * @type {ClassificationType} + * @example + * var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); + * pointPrimitives.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + * pointPrimitives.add({ + * color : Cesium.Color.ORANGE, + * position : new Cesium.Cartesian3(0.0, 0.0, 0.0) // center + * }); + * pointPrimitives.add({ + * color : Cesium.Color.YELLOW, + * position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0) // east + * }); + * pointPrimitives.add({ + * color : Cesium.Color.GREEN, + * position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0) // north + * }); + * pointPrimitives.add({ + * color : Cesium.Color.CYAN, + * position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0) // up + * }); * - * @default ClassificationType.BOTH + * @see Transforms.eastNorthUpToFixedFrame */ - this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + /** * This property is for debugging only; it is not for production use nor is it optimized. * <p> @@ -109333,8793 +120720,8928 @@ define('Scene/GroundPrimitive',[ this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the shadow volume for each geometry in the primitive. - * </p> - * - * @type {Boolean} - * - * @default false + * The point blending option. The default is used for rendering both opaque and translucent points. + * However, if either all of the points are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve + * performance by up to 2x. + * @type {BlendOption} + * @default BlendOption.OPAQUE_AND_TRANSLUCENT */ - this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); - - this._boundingVolumes = []; - this._boundingVolumes2D = []; - - this._ready = false; - this._readyPromise = when.defer(); - - this._primitive = undefined; - - this._maxHeight = undefined; - this._minHeight = undefined; + this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); + this._blendOption = undefined; - this._maxTerrainHeight = GroundPrimitive._defaultMaxTerrainHeight; - this._minTerrainHeight = GroundPrimitive._defaultMinTerrainHeight; + this._mode = SceneMode.SCENE3D; + this._maxTotalPointSize = 1; - this._boundingSpheresKeys = []; - this._boundingSpheres = []; + // The buffer usage for each attribute is determined based on the usage of the attribute over time. + this._buffersUsage = [ + BufferUsage.STATIC_DRAW, // SHOW_INDEX + BufferUsage.STATIC_DRAW, // POSITION_INDEX + BufferUsage.STATIC_DRAW, // COLOR_INDEX + BufferUsage.STATIC_DRAW, // OUTLINE_COLOR_INDEX + BufferUsage.STATIC_DRAW, // OUTLINE_WIDTH_INDEX + BufferUsage.STATIC_DRAW, // PIXEL_SIZE_INDEX + BufferUsage.STATIC_DRAW, // SCALE_BY_DISTANCE_INDEX + BufferUsage.STATIC_DRAW, // TRANSLUCENCY_BY_DISTANCE_INDEX + BufferUsage.STATIC_DRAW // DISTANCE_DISPLAY_CONDITION_INDEX + ]; var that = this; - this._primitiveOptions = { - geometryInstances : undefined, - vertexCacheOptimize : defaultValue(options.vertexCacheOptimize, false), - interleave : defaultValue(options.interleave, false), - releaseGeometryInstances : defaultValue(options.releaseGeometryInstances, true), - allowPicking : defaultValue(options.allowPicking, true), - asynchronous : defaultValue(options.asynchronous, true), - compressVertices : defaultValue(options.compressVertices, true), - _createBoundingVolumeFunction : undefined, - _updateAndQueueCommandsFunction : undefined, - _pickPrimitive : that, - _extruded : true, - _uniformMap : GroundPrimitiveUniformMap + this._uniforms = { + u_maxTotalPointSize : function() { + return that._maxTotalPointSize; + } }; } - defineProperties(GroundPrimitive.prototype, { + defineProperties(PointPrimitiveCollection.prototype, { /** - * When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true + * Returns the number of points in this collection. This is commonly used with + * {@link PointPrimitiveCollection#get} to iterate over all the points + * in the collection. + * @memberof PointPrimitiveCollection.prototype + * @type {Number} */ - vertexCacheOptimize : { + length : { get : function() { - return this._primitiveOptions.vertexCacheOptimize; + removePointPrimitives(this); + return this._pointPrimitives.length; } - }, + } + }); - /** - * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default false - */ - interleave : { - get : function() { - return this._primitiveOptions.interleave; + function destroyPointPrimitives(pointPrimitives) { + var length = pointPrimitives.length; + for (var i = 0; i < length; ++i) { + if (pointPrimitives[i]) { + pointPrimitives[i]._destroy(); } - }, + } + } - /** - * When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - releaseGeometryInstances : { - get : function() { - return this._primitiveOptions.releaseGeometryInstances; - } - }, + /** + * Creates and adds a point with the specified initial properties to the collection. + * The added point is returned so it can be modified or removed from the collection later. + * + * @param {Object}[pointPrimitive] A template describing the point's properties as shown in Example 1. + * @returns {PointPrimitive} The point that was added to the collection. + * + * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer + * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For + * best performance, add as many pointPrimitives as possible before calling <code>update</code>. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Example 1: Add a point, specifying all the default values. + * var p = pointPrimitives.add({ + * show : true, + * position : Cesium.Cartesian3.ZERO, + * pixelSize : 10.0, + * color : Cesium.Color.WHITE, + * outlineColor : Cesium.Color.TRANSPARENT, + * outlineWidth : 0.0, + * id : undefined + * }); + * + * @example + * // Example 2: Specify only the point's cartographic position. + * var p = pointPrimitives.add({ + * position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height) + * }); + * + * @see PointPrimitiveCollection#remove + * @see PointPrimitiveCollection#removeAll + */ + PointPrimitiveCollection.prototype.add = function(pointPrimitive) { + var p = new PointPrimitive(pointPrimitive, this); + p._index = this._pointPrimitives.length; - /** - * When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - allowPicking : { - get : function() { - return this._primitiveOptions.allowPicking; - } - }, + this._pointPrimitives.push(p); + this._createVertexArray = true; - /** - * Determines if the geometry instances will be created and batched on a web worker. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - asynchronous : { - get : function() { - return this._primitiveOptions.asynchronous; - } - }, + return p; + }; - /** - * When <code>true</code>, geometry vertices are compressed, which will save memory. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - * - * @default true - */ - compressVertices : { - get : function() { - return this._primitiveOptions.compressVertices; - } - }, + /** + * Removes a point from the collection. + * + * @param {PointPrimitive} pointPrimitive The point to remove. + * @returns {Boolean} <code>true</code> if the point was removed; <code>false</code> if the point was not found in the collection. + * + * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer + * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For + * best performance, remove as many points as possible before calling <code>update</code>. + * If you intend to temporarily hide a point, it is usually more efficient to call + * {@link PointPrimitive#show} instead of removing and re-adding the point. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * var p = pointPrimitives.add(...); + * pointPrimitives.remove(p); // Returns true + * + * @see PointPrimitiveCollection#add + * @see PointPrimitiveCollection#removeAll + * @see PointPrimitive#show + */ + PointPrimitiveCollection.prototype.remove = function(pointPrimitive) { + if (this.contains(pointPrimitive)) { + this._pointPrimitives[pointPrimitive._index] = null; // Removed later + this._pointPrimitivesRemoved = true; + this._createVertexArray = true; + pointPrimitive._destroy(); + return true; + } - /** - * Determines if the primitive is complete and ready to render. If this property is - * true, the primitive will be rendered the next time that {@link GroundPrimitive#update} - * is called. - * - * @memberof GroundPrimitive.prototype - * - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, + return false; + }; - /** - * Gets a promise that resolves when the primitive is ready to render. - * @memberof GroundPrimitive.prototype - * @type {Promise.<GroundPrimitive>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; + /** + * Removes all points from the collection. + * + * @performance <code>O(n)</code>. It is more efficient to remove all the points + * from a collection and then add new ones than to create a new collection entirely. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * pointPrimitives.add(...); + * pointPrimitives.add(...); + * pointPrimitives.removeAll(); + * + * @see PointPrimitiveCollection#add + * @see PointPrimitiveCollection#remove + */ + PointPrimitiveCollection.prototype.removeAll = function() { + destroyPointPrimitives(this._pointPrimitives); + this._pointPrimitives = []; + this._pointPrimitivesToUpdate = []; + this._pointPrimitivesToUpdateIndex = 0; + this._pointPrimitivesRemoved = false; + + this._createVertexArray = true; + }; + + function removePointPrimitives(pointPrimitiveCollection) { + if (pointPrimitiveCollection._pointPrimitivesRemoved) { + pointPrimitiveCollection._pointPrimitivesRemoved = false; + + var newPointPrimitives = []; + var pointPrimitives = pointPrimitiveCollection._pointPrimitives; + var length = pointPrimitives.length; + for (var i = 0, j = 0; i < length; ++i) { + var pointPrimitive = pointPrimitives[i]; + if (pointPrimitive) { + pointPrimitive._index = j++; + newPointPrimitives.push(pointPrimitive); + } } + + pointPrimitiveCollection._pointPrimitives = newPointPrimitives; } - }); + } + + PointPrimitiveCollection.prototype._updatePointPrimitive = function(pointPrimitive, propertyChanged) { + if (!pointPrimitive._dirty) { + this._pointPrimitivesToUpdate[this._pointPrimitivesToUpdateIndex++] = pointPrimitive; + } + + ++this._propertiesChanged[propertyChanged]; + }; /** - * Determines if GroundPrimitive rendering is supported. + * Check whether this collection contains a given point. * - * @param {Scene} scene The scene. - * @returns {Boolean} <code>true</code> if GroundPrimitives are supported; otherwise, returns <code>false</code> + * @param {PointPrimitive} [pointPrimitive] The point to check for. + * @returns {Boolean} true if this collection contains the point, false otherwise. + * + * @see PointPrimitiveCollection#get */ - GroundPrimitive.isSupported = ClassificationPrimitive.isSupported; + PointPrimitiveCollection.prototype.contains = function(pointPrimitive) { + return defined(pointPrimitive) && pointPrimitive._pointPrimitiveCollection === this; + }; - GroundPrimitive._defaultMaxTerrainHeight = 9000.0; - GroundPrimitive._defaultMinTerrainHeight = -100000.0; + /** + * Returns the point in the collection at the specified index. Indices are zero-based + * and increase as points are added. Removing a point shifts all points after + * it to the left, changing their indices. This function is commonly used with + * {@link PointPrimitiveCollection#length} to iterate over all the points + * in the collection. + * + * @param {Number} index The zero-based index of the point. + * @returns {PointPrimitive} The point at the specified index. + * + * @performance Expected constant time. If points were removed from the collection and + * {@link PointPrimitiveCollection#update} was not called, an implicit <code>O(n)</code> + * operation is performed. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Toggle the show property of every point in the collection + * var len = pointPrimitives.length; + * for (var i = 0; i < len; ++i) { + * var p = pointPrimitives.get(i); + * p.show = !p.show; + * } + * + * @see PointPrimitiveCollection#length + */ + PointPrimitiveCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); + } + + removePointPrimitives(this); + return this._pointPrimitives[index]; + }; - GroundPrimitive._terrainHeights = undefined; - GroundPrimitive._terrainHeightsMaxLevel = 6; + PointPrimitiveCollection.prototype.computeNewBuffersUsage = function() { + var buffersUsage = this._buffersUsage; + var usageChanged = false; - function getComputeMaximumHeightFunction(primitive) { - return function(granularity, ellipsoid) { - var r = ellipsoid.maximumRadius; - var delta = (r / Math.cos(granularity * 0.5)) - r; - return primitive._maxHeight + delta; - }; + var properties = this._propertiesChanged; + for ( var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { + var newUsage = (properties[k] === 0) ? BufferUsage.STATIC_DRAW : BufferUsage.STREAM_DRAW; + usageChanged = usageChanged || (buffersUsage[k] !== newUsage); + buffersUsage[k] = newUsage; + } + + return usageChanged; + }; + + function createVAF(context, numberOfPointPrimitives, buffersUsage) { + return new VertexArrayFacade(context, [{ + index : attributeLocations.positionHighAndSize, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[POSITION_INDEX] + }, { + index : attributeLocations.positionLowAndShow, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[POSITION_INDEX] + }, { + index : attributeLocations.compressedAttribute0, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[COLOR_INDEX] + }, { + index : attributeLocations.compressedAttribute1, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[TRANSLUCENCY_BY_DISTANCE_INDEX] + }, { + index : attributeLocations.scaleByDistance, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[SCALE_BY_DISTANCE_INDEX] + }, { + index : attributeLocations.distanceDisplayConditionAndDisableDepth, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] + }], numberOfPointPrimitives); // 1 vertex per pointPrimitive } - function getComputeMinimumHeightFunction(primitive) { - return function(granularity, ellipsoid) { - return primitive._minHeight; - }; + /////////////////////////////////////////////////////////////////////////// + + // PERFORMANCE_IDEA: Save memory if a property is the same for all pointPrimitives, use a latched attribute state, + // instead of storing it in a vertex buffer. + + var writePositionScratch = new EncodedCartesian3(); + + function writePositionSizeAndOutline(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + var i = pointPrimitive._index; + var position = pointPrimitive._getActualPosition(); + + if (pointPrimitiveCollection._mode === SceneMode.SCENE3D) { + BoundingSphere.expand(pointPrimitiveCollection._baseVolume, position, pointPrimitiveCollection._baseVolume); + pointPrimitiveCollection._boundingVolumeDirty = true; + } + + EncodedCartesian3.fromCartesian(position, writePositionScratch); + var pixelSize = pointPrimitive.pixelSize; + var outlineWidth = pointPrimitive.outlineWidth; + + pointPrimitiveCollection._maxPixelSize = Math.max(pointPrimitiveCollection._maxPixelSize, pixelSize + outlineWidth); + + var positionHighWriter = vafWriters[attributeLocations.positionHighAndSize]; + var high = writePositionScratch.high; + positionHighWriter(i, high.x, high.y, high.z, pixelSize); + + var positionLowWriter = vafWriters[attributeLocations.positionLowAndOutline]; + var low = writePositionScratch.low; + positionLowWriter(i, low.x, low.y, low.z, outlineWidth); } - var scratchBVCartesianHigh = new Cartesian3(); - var scratchBVCartesianLow = new Cartesian3(); - var scratchBVCartesian = new Cartesian3(); - var scratchBVCartographic = new Cartographic(); - var scratchBVRectangle = new Rectangle(); - var tilingScheme = new GeographicTilingScheme(); - var scratchCorners = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; - var scratchTileXY = new Cartesian2(); + var LEFT_SHIFT16 = 65536.0; // 2^16 + var LEFT_SHIFT8 = 256.0; // 2^8 - function getRectangle(frameState, geometry) { - var ellipsoid = frameState.mapProjection.ellipsoid; + function writeCompressedAttrib0(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + var i = pointPrimitive._index; - if (!defined(geometry.attributes) || !defined(geometry.attributes.position3DHigh)) { - if (defined(geometry.rectangle)) { - return geometry.rectangle; + var color = pointPrimitive.color; + var pickColor = pointPrimitive.getPickId(context).color; + var outlineColor = pointPrimitive.outlineColor; + + var red = Color.floatToByte(color.red); + var green = Color.floatToByte(color.green); + var blue = Color.floatToByte(color.blue); + var compressed0 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + + red = Color.floatToByte(outlineColor.red); + green = Color.floatToByte(outlineColor.green); + blue = Color.floatToByte(outlineColor.blue); + var compressed1 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + + red = Color.floatToByte(pickColor.red); + green = Color.floatToByte(pickColor.green); + blue = Color.floatToByte(pickColor.blue); + var compressed2 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + + var compressed3 = + Color.floatToByte(color.alpha) * LEFT_SHIFT16 + + Color.floatToByte(outlineColor.alpha) * LEFT_SHIFT8 + + Color.floatToByte(pickColor.alpha); + + var writer = vafWriters[attributeLocations.compressedAttribute0]; + writer(i, compressed0, compressed1, compressed2, compressed3); + } + + function writeCompressedAttrib1(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + var i = pointPrimitive._index; + + var near = 0.0; + var nearValue = 1.0; + var far = 1.0; + var farValue = 1.0; + + var translucency = pointPrimitive.translucencyByDistance; + if (defined(translucency)) { + near = translucency.near; + nearValue = translucency.nearValue; + far = translucency.far; + farValue = translucency.farValue; + + if (nearValue !== 1.0 || farValue !== 1.0) { + // translucency by distance calculation in shader need not be enabled + // until a pointPrimitive with near and far !== 1.0 is found + pointPrimitiveCollection._shaderTranslucencyByDistance = true; } + } - return undefined; + var show = pointPrimitive.show && pointPrimitive.clusterShow; + + // If the color alphas are zero, do not show this pointPrimitive. This lets us avoid providing + // color during the pick pass and also eliminates a discard in the fragment shader. + if (pointPrimitive.color.alpha === 0.0 && pointPrimitive.outlineColor.alpha === 0.0) { + show = false; } - var highPositions = geometry.attributes.position3DHigh.values; - var lowPositions = geometry.attributes.position3DLow.values; - var length = highPositions.length; + nearValue = CesiumMath.clamp(nearValue, 0.0, 1.0); + nearValue = nearValue === 1.0 ? 255.0 : (nearValue * 255.0) | 0; + var compressed0 = (show ? 1.0 : 0.0) * LEFT_SHIFT8 + nearValue; - var minLat = Number.POSITIVE_INFINITY; - var minLon = Number.POSITIVE_INFINITY; - var maxLat = Number.NEGATIVE_INFINITY; - var maxLon = Number.NEGATIVE_INFINITY; + farValue = CesiumMath.clamp(farValue, 0.0, 1.0); + farValue = farValue === 1.0 ? 255.0 : (farValue * 255.0) | 0; + var compressed1 = farValue; - for (var i = 0; i < length; i +=3) { - var highPosition = Cartesian3.unpack(highPositions, i, scratchBVCartesianHigh); - var lowPosition = Cartesian3.unpack(lowPositions, i, scratchBVCartesianLow); + var writer = vafWriters[attributeLocations.compressedAttribute1]; + writer(i, compressed0, compressed1, near, far); + } - var position = Cartesian3.add(highPosition, lowPosition, scratchBVCartesian); - var cartographic = ellipsoid.cartesianToCartographic(position, scratchBVCartographic); + function writeScaleByDistance(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + var i = pointPrimitive._index; + var writer = vafWriters[attributeLocations.scaleByDistance]; + var near = 0.0; + var nearValue = 1.0; + var far = 1.0; + var farValue = 1.0; - var latitude = cartographic.latitude; - var longitude = cartographic.longitude; + var scale = pointPrimitive.scaleByDistance; + if (defined(scale)) { + near = scale.near; + nearValue = scale.nearValue; + far = scale.far; + farValue = scale.farValue; - minLat = Math.min(minLat, latitude); - minLon = Math.min(minLon, longitude); - maxLat = Math.max(maxLat, latitude); - maxLon = Math.max(maxLon, longitude); + if (nearValue !== 1.0 || farValue !== 1.0) { + // scale by distance calculation in shader need not be enabled + // until a pointPrimitive with near and far !== 1.0 is found + pointPrimitiveCollection._shaderScaleByDistance = true; + } } - var rectangle = scratchBVRectangle; - rectangle.north = maxLat; - rectangle.south = minLat; - rectangle.east = maxLon; - rectangle.west = minLon; + writer(i, near, nearValue, far, farValue); + } - return rectangle; + function writeDistanceDisplayConditionAndDepthDisable(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + var i = pointPrimitive._index; + var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth]; + var near = 0.0; + var far = Number.MAX_VALUE; + + var distanceDisplayCondition = pointPrimitive.distanceDisplayCondition; + if (defined(distanceDisplayCondition)) { + near = distanceDisplayCondition.near; + far = distanceDisplayCondition.far; + + near *= near; + far *= far; + + pointPrimitiveCollection._shaderDistanceDisplayCondition = true; + } + + var disableDepthTestDistance = pointPrimitive.disableDepthTestDistance; + disableDepthTestDistance *= disableDepthTestDistance; + if (disableDepthTestDistance > 0.0) { + pointPrimitiveCollection._shaderDisableDepthDistance = true; + if (disableDepthTestDistance === Number.POSITIVE_INFINITY) { + disableDepthTestDistance = -1.0; + } + } + + writer(i, near, far, disableDepthTestDistance); + } + + function writePointPrimitive(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + writePositionSizeAndOutline(pointPrimitiveCollection, context, vafWriters, pointPrimitive); + writeCompressedAttrib0(pointPrimitiveCollection, context, vafWriters, pointPrimitive); + writeCompressedAttrib1(pointPrimitiveCollection, context, vafWriters, pointPrimitive); + writeScaleByDistance(pointPrimitiveCollection, context, vafWriters, pointPrimitive); + writeDistanceDisplayConditionAndDepthDisable(pointPrimitiveCollection, context, vafWriters, pointPrimitive); + } + + function recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, length, frameState, modelMatrix, recomputeBoundingVolume) { + var boundingVolume; + if (frameState.mode === SceneMode.SCENE3D) { + boundingVolume = pointPrimitiveCollection._baseVolume; + pointPrimitiveCollection._boundingVolumeDirty = true; + } else { + boundingVolume = pointPrimitiveCollection._baseVolume2D; + } + + var positions = []; + for ( var i = 0; i < length; ++i) { + var pointPrimitive = pointPrimitives[i]; + var position = pointPrimitive.position; + var actualPosition = PointPrimitive._computeActualPosition(position, frameState, modelMatrix); + if (defined(actualPosition)) { + pointPrimitive._setActualPosition(actualPosition); + + if (recomputeBoundingVolume) { + positions.push(actualPosition); + } else { + BoundingSphere.expand(boundingVolume, actualPosition, boundingVolume); + } + } + } + + if (recomputeBoundingVolume) { + BoundingSphere.fromPoints(positions, boundingVolume); + } + } + + function updateMode(pointPrimitiveCollection, frameState) { + var mode = frameState.mode; + + var pointPrimitives = pointPrimitiveCollection._pointPrimitives; + var pointPrimitivesToUpdate = pointPrimitiveCollection._pointPrimitivesToUpdate; + var modelMatrix = pointPrimitiveCollection._modelMatrix; + + if (pointPrimitiveCollection._createVertexArray || + pointPrimitiveCollection._mode !== mode || + mode !== SceneMode.SCENE3D && + !Matrix4.equals(modelMatrix, pointPrimitiveCollection.modelMatrix)) { + + pointPrimitiveCollection._mode = mode; + Matrix4.clone(pointPrimitiveCollection.modelMatrix, modelMatrix); + pointPrimitiveCollection._createVertexArray = true; + + if (mode === SceneMode.SCENE3D || mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { + recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, pointPrimitives.length, frameState, modelMatrix, true); + } + } else if (mode === SceneMode.MORPHING) { + recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, pointPrimitives.length, frameState, modelMatrix, true); + } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { + recomputeActualPositions(pointPrimitiveCollection, pointPrimitivesToUpdate, pointPrimitiveCollection._pointPrimitivesToUpdateIndex, frameState, modelMatrix, false); + } } - var scratchDiagonalCartesianNE = new Cartesian3(); - var scratchDiagonalCartesianSW = new Cartesian3(); - var scratchDiagonalCartographic = new Cartographic(); - var scratchCenterCartesian = new Cartesian3(); - var scratchSurfaceCartesian = new Cartesian3(); + function updateBoundingVolume(collection, frameState, boundingVolume) { + var pixelSize = frameState.camera.getPixelSize(boundingVolume, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); + var size = pixelSize * collection._maxPixelSize; + boundingVolume.radius += size; + } + + var scratchWriterArray = []; + + /** + * @private + */ + PointPrimitiveCollection.prototype.update = function(frameState) { + removePointPrimitives(this); + + this._maxTotalPointSize = ContextLimits.maximumAliasedPointSize; + + updateMode(this, frameState); + + var pointPrimitives = this._pointPrimitives; + var pointPrimitivesLength = pointPrimitives.length; + var pointPrimitivesToUpdate = this._pointPrimitivesToUpdate; + var pointPrimitivesToUpdateLength = this._pointPrimitivesToUpdateIndex; + + var properties = this._propertiesChanged; + + var createVertexArray = this._createVertexArray; + + var vafWriters; + var context = frameState.context; + var pass = frameState.passes; + var picking = pass.pick; + + // PERFORMANCE_IDEA: Round robin multiple buffers. + if (createVertexArray || (!picking && this.computeNewBuffersUsage())) { + this._createVertexArray = false; + + for (var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { + properties[k] = 0; + } + + this._vaf = this._vaf && this._vaf.destroy(); - function getTileXYLevel(rectangle) { - Cartographic.fromRadians(rectangle.east, rectangle.north, 0.0, scratchCorners[0]); - Cartographic.fromRadians(rectangle.west, rectangle.north, 0.0, scratchCorners[1]); - Cartographic.fromRadians(rectangle.east, rectangle.south, 0.0, scratchCorners[2]); - Cartographic.fromRadians(rectangle.west, rectangle.south, 0.0, scratchCorners[3]); + if (pointPrimitivesLength > 0) { + // PERFORMANCE_IDEA: Instead of creating a new one, resize like std::vector. + this._vaf = createVAF(context, pointPrimitivesLength, this._buffersUsage); + vafWriters = this._vaf.writers; - // Determine which tile the bounding rectangle is in - var lastLevelX = 0, lastLevelY = 0; - var currentX = 0, currentY = 0; - var maxLevel = GroundPrimitive._terrainHeightsMaxLevel; - var i; - for(i = 0; i <= maxLevel; ++i) { - var failed = false; - for(var j = 0; j < 4; ++j) { - var corner = scratchCorners[j]; - tilingScheme.positionToTileXY(corner, i, scratchTileXY); - if (j === 0) { - currentX = scratchTileXY.x; - currentY = scratchTileXY.y; - } else if(currentX !== scratchTileXY.x || currentY !== scratchTileXY.y) { - failed = true; - break; + // Rewrite entire buffer if pointPrimitives were added or removed. + for (var i = 0; i < pointPrimitivesLength; ++i) { + var pointPrimitive = this._pointPrimitives[i]; + pointPrimitive._dirty = false; // In case it needed an update. + writePointPrimitive(this, context, vafWriters, pointPrimitive); } - } - if (failed) { - break; + this._vaf.commit(); } - lastLevelX = currentX; - lastLevelY = currentY; - } - - if (i === 0) { - return undefined; - } - - return { - x : lastLevelX, - y : lastLevelY, - level : (i > maxLevel) ? maxLevel : (i - 1) - }; - } + this._pointPrimitivesToUpdateIndex = 0; + } else if (pointPrimitivesToUpdateLength > 0) { + // PointPrimitives were modified, but none were added or removed. + var writers = scratchWriterArray; + writers.length = 0; - function setMinMaxTerrainHeights(primitive, rectangle, ellipsoid) { - var xyLevel = getTileXYLevel(rectangle); + if (properties[POSITION_INDEX] || properties[OUTLINE_WIDTH_INDEX] || properties[PIXEL_SIZE_INDEX]) { + writers.push(writePositionSizeAndOutline); + } - // Get the terrain min/max for that tile - var minTerrainHeight = GroundPrimitive._defaultMinTerrainHeight; - var maxTerrainHeight = GroundPrimitive._defaultMaxTerrainHeight; - if (defined(xyLevel)) { - var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; - var heights = GroundPrimitive._terrainHeights[key]; - if (defined(heights)) { - minTerrainHeight = heights[0]; - maxTerrainHeight = heights[1]; + if (properties[COLOR_INDEX] || properties[OUTLINE_COLOR_INDEX]) { + writers.push(writeCompressedAttrib0); } - // Compute min by taking the center of the NE->SW diagonal and finding distance to the surface - ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle, scratchDiagonalCartographic), - scratchDiagonalCartesianNE); - ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle, scratchDiagonalCartographic), - scratchDiagonalCartesianSW); + if (properties[SHOW_INDEX] || properties[TRANSLUCENCY_BY_DISTANCE_INDEX]) { + writers.push(writeCompressedAttrib1); + } - Cartesian3.subtract(scratchDiagonalCartesianSW, scratchDiagonalCartesianNE, scratchCenterCartesian); - Cartesian3.add(scratchDiagonalCartesianNE, - Cartesian3.multiplyByScalar(scratchCenterCartesian, 0.5, scratchCenterCartesian), scratchCenterCartesian); - var surfacePosition = ellipsoid.scaleToGeodeticSurface(scratchCenterCartesian, scratchSurfaceCartesian); - if (defined(surfacePosition)) { - var distance = Cartesian3.distance(scratchCenterCartesian, surfacePosition); - minTerrainHeight = Math.min(minTerrainHeight, -distance); - } else { - minTerrainHeight = GroundPrimitive._defaultMinTerrainHeight; + if (properties[SCALE_BY_DISTANCE_INDEX]) { + writers.push(writeScaleByDistance); } - } - primitive._minTerrainHeight = Math.max(GroundPrimitive._defaultMinTerrainHeight, minTerrainHeight); - primitive._maxTerrainHeight = maxTerrainHeight; - } + if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE_INDEX]) { + writers.push(writeDistanceDisplayConditionAndDepthDisable); + } - var scratchBoundingSphere = new BoundingSphere(); - function getInstanceBoundingSphere(rectangle, ellipsoid) { - var xyLevel = getTileXYLevel(rectangle); + var numWriters = writers.length; - // Get the terrain max for that tile - var maxTerrainHeight = GroundPrimitive._defaultMaxTerrainHeight; - if (defined(xyLevel)) { - var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; - var heights = GroundPrimitive._terrainHeights[key]; - if (defined(heights)) { - maxTerrainHeight = heights[1]; - } - } + vafWriters = this._vaf.writers; - var result = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, 0.0); - BoundingSphere.fromRectangle3D(rectangle, ellipsoid, maxTerrainHeight, scratchBoundingSphere); + if ((pointPrimitivesToUpdateLength / pointPrimitivesLength) > 0.1) { + // If more than 10% of pointPrimitive change, rewrite the entire buffer. - return BoundingSphere.union(result, scratchBoundingSphere, result); - } + // PERFORMANCE_IDEA: I totally made up 10% :). - function createBoundingVolume(groundPrimitive, frameState, geometry) { - var ellipsoid = frameState.mapProjection.ellipsoid; - var rectangle = getRectangle(frameState, geometry); + for (var m = 0; m < pointPrimitivesToUpdateLength; ++m) { + var b = pointPrimitivesToUpdate[m]; + b._dirty = false; - // Use an oriented bounding box by default, but switch to a bounding sphere if bounding box creation would fail. - if (rectangle.width < CesiumMath.PI) { - var obb = OrientedBoundingBox.fromRectangle(rectangle, groundPrimitive._maxHeight, groundPrimitive._minHeight, ellipsoid); - groundPrimitive._boundingVolumes.push(obb); - } else { - var highPositions = geometry.attributes.position3DHigh.values; - var lowPositions = geometry.attributes.position3DLow.values; - groundPrimitive._boundingVolumes.push(BoundingSphere.fromEncodedCartesianVertices(highPositions, lowPositions)); - } + for ( var n = 0; n < numWriters; ++n) { + writers[n](this, context, vafWriters, b); + } + } + this._vaf.commit(); + } else { + for (var h = 0; h < pointPrimitivesToUpdateLength; ++h) { + var bb = pointPrimitivesToUpdate[h]; + bb._dirty = false; - if (!frameState.scene3DOnly) { - var projection = frameState.mapProjection; - var boundingVolume = BoundingSphere.fromRectangleWithHeights2D(rectangle, projection, groundPrimitive._maxHeight, groundPrimitive._minHeight); - Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); + for ( var o = 0; o < numWriters; ++o) { + writers[o](this, context, vafWriters, bb); + } + this._vaf.subCommit(bb._index, 1); + } + this._vaf.endSubCommits(); + } - groundPrimitive._boundingVolumes2D.push(boundingVolume); + this._pointPrimitivesToUpdateIndex = 0; } - } - function boundingVolumeIndex(commandIndex, length) { - return Math.floor((commandIndex % (length / 2)) / 3); - } - - var scratchCommandIndices = { - start : 0, - end : 0 - }; + // If the number of total pointPrimitives ever shrinks considerably + // Truncate pointPrimitivesToUpdate so that we free memory that we're + // not going to be using. + if (pointPrimitivesToUpdateLength > pointPrimitivesLength * 1.5) { + pointPrimitivesToUpdate.length = pointPrimitivesLength; + } - function getCommandIndices(classificationType, length) { - var startIndex; - var endIndex; - if (classificationType === ClassificationType.TERRAIN) { - startIndex = 0; - endIndex = length / 2; - } else if (classificationType === ClassificationType.CESIUM_3D_TILE) { - startIndex = length / 2; - endIndex = length; - } else { - startIndex = 0; - endIndex = length; + if (!defined(this._vaf) || !defined(this._vaf.va)) { + return; } - scratchCommandIndices.start = startIndex; - scratchCommandIndices.end = endIndex; - return scratchCommandIndices; - } + if (this._boundingVolumeDirty) { + this._boundingVolumeDirty = false; + BoundingSphere.transform(this._baseVolume, this.modelMatrix, this._baseVolumeWC); + } - function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - var boundingVolumes; + var boundingVolume; + var modelMatrix = Matrix4.IDENTITY; if (frameState.mode === SceneMode.SCENE3D) { - boundingVolumes = groundPrimitive._boundingVolumes; + modelMatrix = this.modelMatrix; + boundingVolume = BoundingSphere.clone(this._baseVolumeWC, this._boundingVolume); } else { - boundingVolumes = groundPrimitive._boundingVolumes2D; + boundingVolume = BoundingSphere.clone(this._baseVolume2D, this._boundingVolume); } + updateBoundingVolume(this, frameState, boundingVolume); - var indices; - var startIndex; - var endIndex; - var classificationType = groundPrimitive.classificationType; - - var commandList = frameState.commandList; - var passes = frameState.passes; - if (passes.render) { - var colorLength = colorCommands.length; - indices = getCommandIndices(classificationType, colorLength); - startIndex = indices.start; - endIndex = indices.end; - - var i; - var colorCommand; + var blendOptionChanged = this._blendOption !== this.blendOption; + this._blendOption = this.blendOption; - for (i = startIndex; i < endIndex; ++i) { - colorCommand = colorCommands[i]; - colorCommand.owner = groundPrimitive; - colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingVolumes[boundingVolumeIndex(i, colorLength)]; - colorCommand.cull = cull; - colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + if (blendOptionChanged) { + if (this._blendOption === BlendOption.OPAQUE || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { + this._rsOpaque = RenderState.fromCache({ + depthTest : { + enabled : true, + func : WebGLConstants.LEQUAL + }, + depthMask : true + }); + } else { + this._rsOpaque = undefined; + } - commandList.push(colorCommand); + if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { + this._rsTranslucent = RenderState.fromCache({ + depthTest : { + enabled : true, + func : WebGLConstants.LEQUAL + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND + }); + } else { + this._rsTranslucent = undefined; } + } - if (frameState.invertClassification) { - var ignoreShowCommands = groundPrimitive._primitive._commandsIgnoreShow; - startIndex = 0; - endIndex = ignoreShowCommands.length; + this._shaderDisableDepthDistance = this._shaderDisableDepthDistance || frameState.minimumDisableDepthTestDistance !== 0.0; + var vs; + var fs; - for (i = startIndex; i < endIndex; ++i) { - var bvIndex = Math.floor(i / 2); - colorCommand = ignoreShowCommands[i]; - colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingVolumes[bvIndex]; - colorCommand.cull = cull; - colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + if (blendOptionChanged || + (this._shaderScaleByDistance && !this._compiledShaderScaleByDistance) || + (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistance) || + (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayCondition) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) { - commandList.push(colorCommand); - } + vs = new ShaderSource({ + sources : [PointPrimitiveCollectionVS] + }); + if (this._shaderScaleByDistance) { + vs.defines.push('EYE_DISTANCE_SCALING'); + } + if (this._shaderTranslucencyByDistance) { + vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); + } + if (this._shaderDistanceDisplayCondition) { + vs.defines.push('DISTANCE_DISPLAY_CONDITION'); + } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); } - } - if (passes.pick) { - var pickLength = pickCommands.length; - indices = getCommandIndices(classificationType, pickLength); - startIndex = indices.start; - endIndex = indices.end; + if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { + fs = new ShaderSource({ + defines : ['OPAQUE'], + sources : [PointPrimitiveCollectionFS] + }); + this._sp = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._sp, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); - var primitive = groundPrimitive._primitive._primitive; - var pickOffsets = primitive._pickOffsets; - for (var j = startIndex; j < endIndex; ++j) { - var pickOffset = pickOffsets[boundingVolumeIndex(j, pickLength)]; - var bv = boundingVolumes[pickOffset.index]; + fs = new ShaderSource({ + defines : ['TRANSLUCENT'], + sources : [PointPrimitiveCollectionFS] + }); + this._spTranslucent = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._spTranslucent, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } - var pickCommand = pickCommands[j]; - pickCommand.owner = groundPrimitive; - pickCommand.modelMatrix = modelMatrix; - pickCommand.boundingVolume = bv; - pickCommand.cull = cull; + if (this._blendOption === BlendOption.OPAQUE) { + fs = new ShaderSource({ + sources : [PointPrimitiveCollectionFS] + }); + this._sp = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._sp, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } - commandList.push(pickCommand); + if (this._blendOption === BlendOption.TRANSLUCENT) { + fs = new ShaderSource({ + sources : [PointPrimitiveCollectionFS] + }); + this._spTranslucent = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._spTranslucent, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); } + + this._compiledShaderScaleByDistance = this._shaderScaleByDistance; + this._compiledShaderTranslucencyByDistance = this._shaderTranslucencyByDistance; + this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance; } - } - GroundPrimitive._initialized = false; - GroundPrimitive._initPromise = undefined; + if (!defined(this._spPick) || + (this._shaderScaleByDistance && !this._compiledShaderScaleByDistancePick) || + (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistancePick) || + (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayConditionPick) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistancePick)) { - /** - * Initializes the minimum and maximum terrain heights. This only needs to be called if you are creating the - * GroundPrimitive synchronously. - * - * @returns {Promise} A promise that will resolve once the terrain heights have been loaded. - * - */ - GroundPrimitive.initializeTerrainHeights = function() { - var initPromise = GroundPrimitive._initPromise; - if (defined(initPromise)) { - return initPromise; - } + vs = new ShaderSource({ + defines : ['RENDER_FOR_PICK'], + sources : [PointPrimitiveCollectionVS] + }); - GroundPrimitive._initPromise = loadJson(buildModuleUrl('Assets/approximateTerrainHeights.json')).then(function(json) { - GroundPrimitive._initialized = true; - GroundPrimitive._terrainHeights = json; - }); + if (this._shaderScaleByDistance) { + vs.defines.push('EYE_DISTANCE_SCALING'); + } + if (this._shaderTranslucencyByDistance) { + vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); + } + if (this._shaderDistanceDisplayCondition) { + vs.defines.push('DISTANCE_DISPLAY_CONDITION'); + } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); + } - return GroundPrimitive._initPromise; - }; + fs = new ShaderSource({ + defines : ['RENDER_FOR_PICK'], + sources : [PointPrimitiveCollectionFS] + }); - /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> - * - * @exception {DeveloperError} All instance geometries must have the same primitiveType. - * @exception {DeveloperError} Appearance and material have a uniform with the same name. - * @exception {DeveloperError} Not all of the geometry instances have the same color attribute. - */ - GroundPrimitive.prototype.update = function(frameState) { - if (!this.show || (!defined(this._primitive) && !defined(this.geometryInstances))) { - return; - } + this._spPick = ShaderProgram.replaceCache({ + context : context, + shaderProgram : this._spPick, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); - if (!GroundPrimitive._initialized) { - if (!this.asynchronous) { - throw new DeveloperError('For synchronous GroundPrimitives, you must call GroundPrimitive.initializeTerrainHeights() and wait for the returned promise to resolve.'); - } - - GroundPrimitive.initializeTerrainHeights(); - return; + this._compiledShaderScaleByDistancePick = this._shaderScaleByDistance; + this._compiledShaderTranslucencyByDistancePick = this._shaderTranslucencyByDistance; + this._compiledShaderDistanceDisplayConditionPick = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistancePick = this._shaderDisableDepthDistance; } - var that = this; - var primitiveOptions = this._primitiveOptions; + var va; + var vaLength; + var command; + var j; - if (!defined(this._primitive)) { - var ellipsoid = frameState.mapProjection.ellipsoid; + var commandList = frameState.commandList; - var instance; - var geometry; - var instanceType; + if (pass.render) { + var colorList = this._colorCommands; - var instances = isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; - var length = instances.length; - var groundInstances = new Array(length); + var opaque = this._blendOption === BlendOption.OPAQUE; + var opaqueAndTranslucent = this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT; - var i; - var rectangle; - for (i = 0; i < length; ++i) { - instance = instances[i]; - geometry = instance.geometry; - var instanceRectangle = getRectangle(frameState, geometry); - if (!defined(rectangle)) { - rectangle = instanceRectangle; - } else if (defined(instanceRectangle)) { - Rectangle.union(rectangle, instanceRectangle, rectangle); - } + va = this._vaf.va; + vaLength = va.length; - var id = instance.id; - if (defined(id) && defined(instanceRectangle)) { - var boundingSphere = getInstanceBoundingSphere(instanceRectangle, ellipsoid); - this._boundingSpheresKeys.push(id); - this._boundingSpheres.push(boundingSphere); + colorList.length = vaLength; + var totalLength = opaqueAndTranslucent ? vaLength * 2 : vaLength; + for (j = 0; j < totalLength; ++j) { + var opaqueCommand = opaque || (opaqueAndTranslucent && j % 2 === 0); + + command = colorList[j]; + if (!defined(command)) { + command = colorList[j] = new DrawCommand(); } - instanceType = geometry.constructor; - if (!defined(instanceType) || !defined(instanceType.createShadowVolume)) { - throw new DeveloperError('Not all of the geometry instances have GroundPrimitive support.'); - } - } + command.primitiveType = PrimitiveType.POINTS; + command.pass = opaqueCommand || !opaqueAndTranslucent ? Pass.OPAQUE : Pass.TRANSLUCENT; + command.owner = this; - // Now compute the min/max heights for the primitive - setMinMaxTerrainHeights(this, rectangle, frameState.mapProjection.ellipsoid); - var exaggeration = frameState.terrainExaggeration; - this._minHeight = this._minTerrainHeight * exaggeration; - this._maxHeight = this._maxTerrainHeight * exaggeration; + var index = opaqueAndTranslucent ? Math.floor(j / 2.0) : j; + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.shaderProgram = opaqueCommand ? this._sp : this._spTranslucent; + command.uniformMap = this._uniforms; + command.vertexArray = va[index].va; + command.renderState = opaqueCommand ? this._rsOpaque : this._rsTranslucent; + command.debugShowBoundingVolume = this.debugShowBoundingVolume; - for (i = 0; i < length; ++i) { - instance = instances[i]; - geometry = instance.geometry; - instanceType = geometry.constructor; - groundInstances[i] = new GeometryInstance({ - geometry : instanceType.createShadowVolume(geometry, getComputeMinimumHeightFunction(this), - getComputeMaximumHeightFunction(this)), - attributes : instance.attributes, - id : instance.id - }); + commandList.push(command); } + } - primitiveOptions.geometryInstances = groundInstances; - - primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { - createBoundingVolume(that, frameState, geometry); - }; - primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); - }; - - this._primitive = new ClassificationPrimitive(primitiveOptions); - this._primitive.readyPromise.then(function(primitive) { - that._ready = true; + if (picking) { + var pickList = this._pickCommands; - if (that.releaseGeometryInstances) { - that.geometryInstances = undefined; - } + va = this._vaf.va; + vaLength = va.length; - var error = primitive._error; - if (!defined(error)) { - that._readyPromise.resolve(that); - } else { - that._readyPromise.reject(error); + pickList.length = vaLength; + for (j = 0; j < vaLength; ++j) { + command = pickList[j]; + if (!defined(command)) { + command = pickList[j] = new DrawCommand({ + primitiveType : PrimitiveType.POINTS, + pass : Pass.OPAQUE, + owner : this + }); } - }); - } - - this._primitive.debugShowShadowVolume = this.debugShowShadowVolume; - this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; - this._primitive.update(frameState); - }; - - /** - * @private - */ - GroundPrimitive.prototype.getBoundingSphere = function(id) { - var index = this._boundingSpheresKeys.indexOf(id); - if (index !== -1) { - return this._boundingSpheres[index]; - } - return undefined; - }; + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.shaderProgram = this._spPick; + command.uniformMap = this._uniforms; + command.vertexArray = va[j].va; + command.renderState = this._rsOpaque; - /** - * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. - * - * @param {Object} id The id of the {@link GeometryInstance}. - * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. - * - * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. - * - * @example - * var attributes = primitive.getGeometryInstanceAttributes('an id'); - * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); - * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true); - */ - GroundPrimitive.prototype.getGeometryInstanceAttributes = function(id) { - if (!defined(this._primitive)) { - throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); + commandList.push(command); + } } - return this._primitive.getGeometryInstanceAttributes(id); }; /** * Returns true if this object was destroyed; otherwise, false. - * <p> + * <br /><br /> * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * </p> * * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * - * @see GroundPrimitive#destroy + * @see PointPrimitiveCollection#destroy */ - GroundPrimitive.prototype.isDestroyed = function() { + PointPrimitiveCollection.prototype.isDestroyed = function() { return false; }; /** * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <p> + * <br /><br /> * Once an object is destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, * assign the return value (<code>undefined</code>) to the object as done in the example. - * </p> * * @returns {undefined} * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * + * * @example - * e = e && e.destroy(); + * pointPrimitives = pointPrimitives && pointPrimitives.destroy(); * - * @see GroundPrimitive#isDestroyed + * @see PointPrimitiveCollection#isDestroyed */ - GroundPrimitive.prototype.destroy = function() { - this._primitive = this._primitive && this._primitive.destroy(); + PointPrimitiveCollection.prototype.destroy = function() { + this._sp = this._sp && this._sp.destroy(); + this._spTranslucent = this._spTranslucent && this._spTranslucent.destroy(); + this._spPick = this._spPick && this._spPick.destroy(); + this._vaf = this._vaf && this._vaf.destroy(); + destroyPointPrimitives(this._pointPrimitives); + return destroyObject(this); }; - return GroundPrimitive; + return PointPrimitiveCollection; }); -define('DataSources/CorridorGeometryUpdater',[ - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/CorridorGeometry', - '../Core/CorridorOutlineGeometry', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/oneTimeWarning', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/GroundPrimitive', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' - ], function( - Color, - ColorGeometryInstanceAttribute, - CorridorGeometry, - CorridorOutlineGeometry, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - oneTimeWarning, - ShowGeometryInstanceAttribute, - GroundPrimitive, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { - 'use strict'; +define('ThirdParty/kdbush',[], function() { +'use strict'; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); +function kdbush(points, getX, getY, nodeSize, ArrayType) { + return new KDBush(points, getX, getY, nodeSize, ArrayType); +} - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.positions = undefined; - this.width = undefined; - this.cornerType = undefined; - this.height = undefined; - this.extrudedHeight = undefined; - this.granularity = undefined; +function KDBush(points, getX, getY, nodeSize, ArrayType) { + getX = getX || defaultGetX; + getY = getY || defaultGetY; + ArrayType = ArrayType || Array; + + this.nodeSize = nodeSize || 64; + this.points = points; + + this.ids = new ArrayType(points.length); + this.coords = new ArrayType(points.length * 2); + + for (var i = 0; i < points.length; i++) { + this.ids[i] = i; + this.coords[2 * i] = getX(points[i]); + this.coords[2 * i + 1] = getY(points[i]); } - /** - * A {@link GeometryUpdater} for corridors. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias CorridorGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function CorridorGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + sort(this.ids, this.coords, this.nodeSize, 0, this.ids.length - 1, 0); +} + +KDBush.prototype = { + range: function (minX, minY, maxX, maxY) { + return range(this.ids, this.coords, minX, minY, maxX, maxY, this.nodeSize); + }, + + within: function (x, y, r) { + return within(this.ids, this.coords, x, y, r, this.nodeSize); + } +}; + +function defaultGetX(p) { return p[0]; } +function defaultGetY(p) { return p[1]; } + +function range(ids, coords, minX, minY, maxX, maxY, nodeSize) { + var stack = [0, ids.length - 1, 0]; + var result = []; + var x, y; + + while (stack.length) { + var axis = stack.pop(); + var right = stack.pop(); + var left = stack.pop(); + + if (right - left <= nodeSize) { + for (var i = left; i <= right; i++) { + x = coords[2 * i]; + y = coords[2 * i + 1]; + if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]); + } + continue; } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(CorridorGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._isClosed = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._onTerrain = false; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'corridor', entity.corridor, undefined); + var m = Math.floor((left + right) / 2); + + x = coords[2 * m]; + y = coords[2 * m + 1]; + + if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]); + + var nextAxis = (axis + 1) % 2; + + if (axis === 0 ? minX <= x : minY <= y) { + stack.push(left); + stack.push(m - 1); + stack.push(nextAxis); + } + if (axis === 0 ? maxX >= x : maxY >= y) { + stack.push(m + 1); + stack.push(right); + stack.push(nextAxis); + } } - defineProperties(CorridorGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof CorridorGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof CorridorGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance + return result; +} + +function sort(ids, coords, nodeSize, left, right, depth) { + if (right - left <= nodeSize) return; + + var m = Math.floor((left + right) / 2); + + select(ids, coords, m, left, right, depth % 2); + + sort(ids, coords, nodeSize, left, m - 1, depth + 1); + sort(ids, coords, nodeSize, m + 1, right, depth + 1); +} + +function select(ids, coords, k, left, right, inc) { + + while (right > left) { + if (right - left > 600) { + var n = right - left + 1; + var m = k - left + 1; + var z = Math.log(n); + var s = 0.5 * Math.exp(2 * z / 3); + var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); + var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); + var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); + select(ids, coords, k, newLeft, newRight, inc); } - }); - defineProperties(CorridorGeometryUpdater.prototype, { - /** - * Gets the entity associated with this geometry. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Entity} - * @readonly - */ - entity : { - get : function() { - return this._entity; - } - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, - /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, - /** - * Gets the material property used to fill the geometry. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly - */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); - } - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - outlineColorProperty : { - get : function() { - return this._outlineColorProperty; - } - }, - /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Number} - * @readonly - */ - outlineWidth : { - get : function() { - return this._outlineWidth; - } - }, - /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; - } - }, - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayCondition; - } - }, - /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isDynamic : { - get : function() { - return this._dynamic; - } - }, - /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isClosed : { - get : function() { - return this._isClosed; - } - }, - /** - * Gets a value indicating if the geometry should be drawn on terrain. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - onTerrain : { - get : function() { - return this._onTerrain; - } - }, - /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof CorridorGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - geometryChanged : { - get : function() { - return this._geometryChanged; + var t = coords[2 * k + inc]; + var i = left; + var j = right; + + swapItem(ids, coords, left, k); + if (coords[2 * right + inc] > t) swapItem(ids, coords, left, right); + + while (i < j) { + swapItem(ids, coords, i, j); + i++; + j--; + while (coords[2 * i + inc] < t) i++; + while (coords[2 * j + inc] > t) j--; + } + + if (coords[2 * left + inc] === t) swapItem(ids, coords, left, j); + else { + j++; + swapItem(ids, coords, j, right); + } + + if (j <= k) left = j + 1; + if (k <= j) right = j - 1; + } +} + +function swapItem(ids, coords, i, j) { + swap(ids, i, j); + swap(coords, 2 * i, 2 * j); + swap(coords, 2 * i + 1, 2 * j + 1); +} + +function swap(arr, i, j) { + var tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; +} + +function within(ids, coords, qx, qy, r, nodeSize) { + var stack = [0, ids.length - 1, 0]; + var result = []; + var r2 = r * r; + + while (stack.length) { + var axis = stack.pop(); + var right = stack.pop(); + var left = stack.pop(); + + if (right - left <= nodeSize) { + for (var i = left; i <= right; i++) { + if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) result.push(ids[i]); } + continue; } - }); - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - CorridorGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + var m = Math.floor((left + right) / 2); - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - CorridorGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; + var x = coords[2 * m]; + var y = coords[2 * m + 1]; - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - CorridorGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + if (sqDist(x, y, qx, qy) <= r2) result.push(ids[m]); - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); + var nextAxis = (axis + 1) % 2; + + if (axis === 0 ? qx - r <= x : qy - r <= y) { + stack.push(left); + stack.push(m - 1); + stack.push(nextAxis); } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); + if (axis === 0 ? qx + r >= x : qy + r >= y) { + stack.push(m + 1); + stack.push(right); + stack.push(nextAxis); + } + } - var attributes; + return result; +} - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayCondition.getValue(time)); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayCondition, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayCondition - }; - } +function sqDist(ax, ay, bx, by) { + var dx = ax - bx; + var dy = ay - by; + return dx * dx + dy * dy; +} - return new GeometryInstance({ - id : entity, - geometry : new CorridorGeometry(this._options), - attributes : attributes - }); - }; +return kdbush; +}); + +define('DataSources/EntityCluster',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/EllipsoidalOccluder', + '../Core/Event', + '../Core/Matrix4', + '../Scene/Billboard', + '../Scene/BillboardCollection', + '../Scene/Label', + '../Scene/LabelCollection', + '../Scene/PointPrimitive', + '../Scene/PointPrimitiveCollection', + '../Scene/SceneMode', + '../ThirdParty/kdbush' + ], function( + BoundingRectangle, + Cartesian2, + Cartesian3, + defaultValue, + defined, + defineProperties, + EllipsoidalOccluder, + Event, + Matrix4, + Billboard, + BillboardCollection, + Label, + LabelCollection, + PointPrimitive, + PointPrimitiveCollection, + SceneMode, + kdbush) { + 'use strict'; /** - * Creates the geometry instance which represents the outline of the geometry. + * Defines how screen space objects (billboards, points, labels) are clustered. * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.enabled=false] Whether or not to enable clustering. + * @param {Number} [options.pixelRange=80] The pixel range to extend the screen space bounding box. + * @param {Number} [options.minimumClusterSize=2] The minimum number of screen space objects that can be clustered. + * @param {Boolean} [options.clusterBillboards=true] Whether or not to cluster the billboards of an entity. + * @param {Boolean} [options.clusterLabels=true] Whether or not to cluster the labels of an entity. + * @param {Boolean} [options.clusterPoints=true] Whether or not to cluster the points of an entity. * - * @exception {DeveloperError} This instance does not represent an outlined geometry. + * @alias EntityCluster + * @constructor + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Clustering.html|Cesium Sandcastle Clustering Demo} */ - CorridorGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + function EntityCluster(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._enabled = defaultValue(options.enabled, false); + this._pixelRange = defaultValue(options.pixelRange, 80); + this._minimumClusterSize = defaultValue(options.minimumClusterSize, 2); + this._clusterBillboards = defaultValue(options.clusterBillboards, true); + this._clusterLabels = defaultValue(options.clusterLabels, true); + this._clusterPoints = defaultValue(options.clusterPoints, true); + + this._labelCollection = undefined; + this._billboardCollection = undefined; + this._pointCollection = undefined; + + this._clusterBillboardCollection = undefined; + this._clusterLabelCollection = undefined; + this._clusterPointCollection = undefined; + + this._collectionIndicesByEntity = {}; + + this._unusedLabelIndices = []; + this._unusedBillboardIndices = []; + this._unusedPointIndices = []; + + this._previousClusters = []; + this._previousHeight = undefined; + + this._enabledDirty = false; + this._clusterDirty = false; + + this._cluster = undefined; + this._removeEventListener = undefined; + + this._clusterEvent = new Event(); + } + + function getX(point) { + return point.coord.x; + } + + function getY(point) { + return point.coord.y; + } + + function expandBoundingBox(bbox, pixelRange) { + bbox.x -= pixelRange; + bbox.y -= pixelRange; + bbox.width += pixelRange * 2.0; + bbox.height += pixelRange * 2.0; + } + + var labelBoundingBoxScratch = new BoundingRectangle(); + + function getBoundingBox(item, coord, pixelRange, entityCluster, result) { + if (defined(item._labelCollection) && entityCluster._clusterLabels) { + result = Label.getScreenSpaceBoundingBox(item, coord, result); + } else if (defined(item._billboardCollection) && entityCluster._clusterBillboards) { + result = Billboard.getScreenSpaceBoundingBox(item, coord, result); + } else if (defined(item._pointPrimitiveCollection) && entityCluster._clusterPoints) { + result = PointPrimitive.getScreenSpaceBoundingBox(item, coord, result); } - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + expandBoundingBox(result, pixelRange); + + if (entityCluster._clusterLabels && !defined(item._labelCollection) && defined(item.id) && hasLabelIndex(entityCluster, item.id) && defined(item.id._label)) { + var labelIndex = entityCluster._collectionIndicesByEntity[item.id]; + var label = entityCluster._labelCollection.get(labelIndex); + var labelBBox = Label.getScreenSpaceBoundingBox(label, coord, labelBoundingBoxScratch); + expandBoundingBox(labelBBox, pixelRange); + result = BoundingRectangle.union(result, labelBBox, result); } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - return new GeometryInstance({ - id : entity, - geometry : new CorridorOutlineGeometry(this._options), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayCondition.getValue(time)) - } - }); - }; + return result; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - CorridorGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + function addNonClusteredItem(item, entityCluster) { + item.clusterShow = true; - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - CorridorGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + if (!defined(item._labelCollection) && defined(item.id) && hasLabelIndex(entityCluster, item.id) && defined(item.id._label)) { + var labelIndex = entityCluster._collectionIndicesByEntity[item.id]; + var label = entityCluster._labelCollection.get(labelIndex); + label.clusterShow = true; + } + } - CorridorGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'corridor')) { + function addCluster(position, numPoints, ids, entityCluster) { + var cluster = { + billboard : entityCluster._clusterBillboardCollection.add(), + label : entityCluster._clusterLabelCollection.add(), + point : entityCluster._clusterPointCollection.add() + }; + + cluster.billboard.show = false; + cluster.point.show = false; + cluster.label.show = true; + cluster.label.text = numPoints.toLocaleString(); + cluster.label.id = ids; + cluster.billboard.position = cluster.label.position = cluster.point.position = position; + + entityCluster._clusterEvent.raiseEvent(ids, cluster); + } + + function hasLabelIndex(entityCluster, entityId) { + return defined(entityCluster) && defined(entityCluster._collectionIndicesByEntity[entityId]) && defined(entityCluster._collectionIndicesByEntity[entityId].labelIndex); + } + + function getScreenSpacePositions(collection, points, scene, occluder, entityCluster) { + if (!defined(collection)) { return; } - var corridor = this._entity.corridor; + var length = collection.length; + for (var i = 0; i < length; ++i) { + var item = collection.get(i); + item.clusterShow = false; - if (!defined(corridor)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + if (!item.show || (entityCluster._scene.mode === SceneMode.SCENE3D && !occluder.isPointVisible(item.position))) { + continue; } - return; - } - var fillProperty = corridor.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + var canClusterLabels = entityCluster._clusterLabels && defined(item._labelCollection); + var canClusterBillboards = entityCluster._clusterBillboards && defined(item.id._billboard); + var canClusterPoints = entityCluster._clusterPoints && defined(item.id._point); + if (canClusterLabels && (canClusterPoints || canClusterBillboards)) { + continue; + } - var outlineProperty = corridor.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + var coord = item.computeScreenSpacePosition(scene); + if (!defined(coord)) { + continue; + } + + points.push({ + index : i, + collection : collection, + clustered : false, + coord : coord + }); } + } - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + var pointBoundinRectangleScratch = new BoundingRectangle(); + var totalBoundingRectangleScratch = new BoundingRectangle(); + var neighborBoundingRectangleScratch = new BoundingRectangle(); + + function createDeclutterCallback(entityCluster) { + return function(amount) { + if ((defined(amount) && amount < 0.05) || !entityCluster.enabled) { + return; } - return; - } - var positions = corridor.positions; + var scene = entityCluster._scene; - var show = corridor.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(positions))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + var labelCollection = entityCluster._labelCollection; + var billboardCollection = entityCluster._billboardCollection; + var pointCollection = entityCluster._pointCollection; + + if ((!defined(labelCollection) && !defined(billboardCollection) && !defined(pointCollection)) || + (!entityCluster._clusterBillboards && !entityCluster._clusterLabels && !entityCluster._clusterPoints)) { + return; } - return; - } - var material = defaultValue(corridor.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(corridor.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(corridor.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(corridor.shadows, defaultShadows); - this._distanceDisplayCondition = defaultValue(corridor.distanceDisplayCondition, defaultDistanceDisplayCondition); + var clusteredLabelCollection = entityCluster._clusterLabelCollection; + var clusteredBillboardCollection = entityCluster._clusterBillboardCollection; + var clusteredPointCollection = entityCluster._clusterPointCollection; - var height = corridor.height; - var extrudedHeight = corridor.extrudedHeight; - var granularity = corridor.granularity; - var width = corridor.width; - var outlineWidth = corridor.outlineWidth; - var cornerType = corridor.cornerType; - var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && - isColorMaterial && GroundPrimitive.isSupported(this._scene); + if (defined(clusteredLabelCollection)) { + clusteredLabelCollection.removeAll(); + } else { + clusteredLabelCollection = entityCluster._clusterLabelCollection = new LabelCollection({ + scene : scene + }); + } - if (outlineEnabled && onTerrain) { - oneTimeWarning(oneTimeWarning.geometryOutlines); - outlineEnabled = false; - } + if (defined(clusteredBillboardCollection)) { + clusteredBillboardCollection.removeAll(); + } else { + clusteredBillboardCollection = entityCluster._clusterBillboardCollection = new BillboardCollection({ + scene : scene + }); + } - this._fillEnabled = fillEnabled; - this._onTerrain = onTerrain; - this._isClosed = defined(extrudedHeight) || onTerrain; - this._outlineEnabled = outlineEnabled; + if (defined(clusteredPointCollection)) { + clusteredPointCollection.removeAll(); + } else { + clusteredPointCollection = entityCluster._clusterPointCollection = new PointPrimitiveCollection(); + } - if (!positions.isConstant || // - !Property.isConstant(height) || // - !Property.isConstant(extrudedHeight) || // - !Property.isConstant(granularity) || // - !Property.isConstant(width) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(cornerType) || // - (onTerrain && !Property.isConstant(material))) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + var pixelRange = entityCluster._pixelRange; + var minimumClusterSize = entityCluster._minimumClusterSize; + + var clusters = entityCluster._previousClusters; + var newClusters = []; + + var previousHeight = entityCluster._previousHeight; + var currentHeight = scene.camera.positionCartographic.height; + + var ellipsoid = scene.mapProjection.ellipsoid; + var cameraPosition = scene.camera.positionWC; + var occluder = new EllipsoidalOccluder(ellipsoid, cameraPosition); + + var points = []; + if (entityCluster._clusterLabels) { + getScreenSpacePositions(labelCollection, points, scene, occluder, entityCluster); + } + if (entityCluster._clusterBillboards) { + getScreenSpacePositions(billboardCollection, points, scene, occluder, entityCluster); + } + if (entityCluster._clusterPoints) { + getScreenSpacePositions(pointCollection, points, scene, occluder, entityCluster); } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.positions = positions.getValue(Iso8601.MINIMUM_VALUE, options.positions); - options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.cornerType = defined(cornerType) ? cornerType.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); - } - }; - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @param {PrimitiveCollection} groundPrimitives The ground primitives collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - CorridorGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); - } + var i; + var j; + var length; + var bbox; + var neighbors; + var neighborLength; + var neighborIndex; + var neighborPoint; + var ids; + var numPoints; - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); - } - - return new DynamicGeometryUpdater(primitives, groundPrimitives, this); - }; + var collection; + var collectionIndex; - /** - * @private - */ - function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { - this._primitives = primitives; - this._groundPrimitives = groundPrimitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); - } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var geometryUpdater = this._geometryUpdater; - var onTerrain = geometryUpdater._onTerrain; + var index = kdbush(points, getX, getY, 64, Int32Array); - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._outlinePrimitive = undefined; - } - this._primitive = undefined; + if (currentHeight < previousHeight) { + length = clusters.length; + for (i = 0; i < length; ++i) { + var cluster = clusters[i]; - var entity = geometryUpdater._entity; - var corridor = entity.corridor; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(corridor.show, time, true)) { - return; - } + if (!occluder.isPointVisible(cluster.position)) { + continue; + } - var options = this._options; - var positions = Property.getValueOrUndefined(corridor.positions, time, options.positions); - var width = Property.getValueOrUndefined(corridor.width, time); - if (!defined(positions) || !defined(width)) { - return; - } + var coord = Billboard._computeScreenSpacePosition(Matrix4.IDENTITY, cluster.position, Cartesian3.ZERO, Cartesian2.ZERO, scene); + if (!defined(coord)) { + continue; + } - options.positions = positions; - options.width = width; - options.height = Property.getValueOrUndefined(corridor.height, time); - options.extrudedHeight = Property.getValueOrUndefined(corridor.extrudedHeight, time); - options.granularity = Property.getValueOrUndefined(corridor.granularity, time); - options.cornerType = Property.getValueOrUndefined(corridor.cornerType, time); + var factor = 1.0 - currentHeight / previousHeight; + var width = cluster.width = cluster.width * factor; + var height = cluster.height = cluster.height * factor; - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); - var distanceDisplayCondition = this._geometryUpdater.distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + width = Math.max(width, cluster.minimumWidth); + height = Math.max(height, cluster.minimumHeight); - if (!defined(corridor.fill) || corridor.fill.getValue(time)) { - var fillMaterialProperty = geometryUpdater.fillMaterialProperty; - var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); - this._material = material; + var minX = coord.x - width * 0.5; + var minY = coord.y - height * 0.5; + var maxX = coord.x + width; + var maxY = coord.y + height; - if (onTerrain) { - var currentColor = Color.WHITE; - if (defined(fillMaterialProperty.color)) { - currentColor = fillMaterialProperty.color.getValue(time); - } + neighbors = index.range(minX, minY, maxX, maxY); + neighborLength = neighbors.length; + numPoints = 0; + ids = []; - this._primitive = groundPrimitives.add(new GroundPrimitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new CorridorGeometry(options), - attributes: { - color: ColorGeometryInstanceAttribute.fromColor(currentColor), - distanceDisplayCondition : distanceDisplayConditionAttribute + for (j = 0; j < neighborLength; ++j) { + neighborIndex = neighbors[j]; + neighborPoint = points[neighborIndex]; + if (!neighborPoint.clustered) { + ++numPoints; + + collection = neighborPoint.collection; + collectionIndex = neighborPoint.index; + ids.push(collection.get(collectionIndex).id); } - }), - asynchronous : false, - shadows : shadows - })); - } else { - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : defined(options.extrudedHeight) - }); - options.vertexFormat = appearance.vertexFormat; + } - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new CorridorGeometry(options), - attributes : { - distanceDisplayCondition : distanceDisplayConditionAttribute + if (numPoints >= minimumClusterSize) { + addCluster(cluster.position, numPoints, ids, entityCluster); + newClusters.push(cluster); + + for (j = 0; j < neighborLength; ++j) { + points[neighbors[j]].clustered = true; } - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + } + } } - } - if (!onTerrain && defined(corridor.outline) && corridor.outline.getValue(time)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + length = points.length; + for (i = 0; i < length; ++i) { + var point = points[i]; + if (point.clustered) { + continue; + } - var outlineColor = Property.getValueOrClonedDefault(corridor.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(corridor.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + point.clustered = true; - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new CorridorOutlineGeometry(options), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + collection = point.collection; + collectionIndex = point.index; + + var item = collection.get(collectionIndex); + bbox = getBoundingBox(item, point.coord, pixelRange, entityCluster, pointBoundinRectangleScratch); + var totalBBox = BoundingRectangle.clone(bbox, totalBoundingRectangleScratch); + + neighbors = index.range(bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height); + neighborLength = neighbors.length; + + var clusterPosition = Cartesian3.clone(item.position); + numPoints = 1; + ids = [item.id]; + + for (j = 0; j < neighborLength; ++j) { + neighborIndex = neighbors[j]; + neighborPoint = points[neighborIndex]; + if (!neighborPoint.clustered) { + var neighborItem = neighborPoint.collection.get(neighborPoint.index); + var neighborBBox = getBoundingBox(neighborItem, neighborPoint.coord, pixelRange, entityCluster, neighborBoundingRectangleScratch); + + Cartesian3.add(neighborItem.position, clusterPosition, clusterPosition); + + BoundingRectangle.union(totalBBox, neighborBBox, totalBBox); + ++numPoints; + + ids.push(neighborItem.id); } - }), - asynchronous : false, - shadows : shadows - })); - } - }; + } - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; + if (numPoints >= minimumClusterSize) { + var position = Cartesian3.multiplyByScalar(clusterPosition, 1.0 / numPoints, clusterPosition); + addCluster(position, numPoints, ids, entityCluster); + newClusters.push({ + position : position, + width : totalBBox.width, + height : totalBBox.height, + minimumWidth : bbox.width, + minimumHeight : bbox.height + }); - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + for (j = 0; j < neighborLength; ++j) { + points[neighbors[j]].clustered = true; + } + } else { + addNonClusteredItem(item, entityCluster); + } + } - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (this._geometryUpdater._onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - } - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; + if (clusteredLabelCollection.length === 0) { + clusteredLabelCollection.destroy(); + entityCluster._clusterLabelCollection = undefined; + } - return CorridorGeometryUpdater; -}); + if (clusteredBillboardCollection.length === 0) { + clusteredBillboardCollection.destroy(); + entityCluster._clusterBillboardCollection = undefined; + } -define('DataSources/DataSource',[ - '../Core/defineProperties', - '../Core/DeveloperError' - ], function( - defineProperties, - DeveloperError) { - 'use strict'; + if (clusteredPointCollection.length === 0) { + clusteredPointCollection.destroy(); + entityCluster._clusterPointCollection = undefined; + } - /** - * Defines the interface for data sources, which turn arbitrary data into a - * {@link EntityCollection} for generic consumption. This object is an interface - * for documentation purposes and is not intended to be instantiated directly. - * @alias DataSource - * @constructor - * - * @see Entity - * @see DataSourceDisplay - */ - function DataSource() { - DeveloperError.throwInstantiationError(); + entityCluster._previousClusters = newClusters; + entityCluster._previousHeight = currentHeight; + }; } - defineProperties(DataSource.prototype, { - /** - * Gets a human-readable name for this instance. - * @memberof DataSource.prototype - * @type {String} - */ - name : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the preferred clock settings for this data source. - * @memberof DataSource.prototype - * @type {DataSourceClock} - */ - clock : { - get : DeveloperError.throwInstantiationError - }, + EntityCluster.prototype._initialize = function(scene) { + this._scene = scene; + + var cluster = createDeclutterCallback(this); + this._cluster = cluster; + this._removeEventListener = scene.camera.changed.addEventListener(cluster); + }; + + defineProperties(EntityCluster.prototype, { /** - * Gets the collection of {@link Entity} instances. - * @memberof DataSource.prototype - * @type {EntityCollection} + * Gets or sets whether clustering is enabled. + * @memberof EntityCluster.prototype + * @type {Boolean} */ - entities : { - get : DeveloperError.throwInstantiationError + enabled : { + get : function() { + return this._enabled; + }, + set : function(value) { + this._enabledDirty = value !== this._enabled; + this._enabled = value; + } }, /** - * Gets a value indicating if the data source is currently loading data. - * @memberof DataSource.prototype - * @type {Boolean} + * Gets or sets the pixel range to extend the screen space bounding box. + * @memberof EntityCluster.prototype + * @type {Number} */ - isLoading : { - get : DeveloperError.throwInstantiationError + pixelRange : { + get : function() { + return this._pixelRange; + }, + set : function(value) { + this._clusterDirty = this._clusterDirty || value !== this._pixelRange; + this._pixelRange = value; + } }, /** - * Gets an event that will be raised when the underlying data changes. - * @memberof DataSource.prototype - * @type {Event} + * Gets or sets the minimum number of screen space objects that can be clustered. + * @memberof EntityCluster.prototype + * @type {Number} */ - changedEvent : { - get : DeveloperError.throwInstantiationError + minimumClusterSize : { + get : function() { + return this._minimumClusterSize; + }, + set : function(value) { + this._clusterDirty = this._clusterDirty || value !== this._minimumClusterSize; + this._minimumClusterSize = value; + } }, /** - * Gets an event that will be raised if an error is encountered during processing. - * @memberof DataSource.prototype + * Gets the event that will be raised when a new cluster will be displayed. The signature of the event listener is {@link EntityCluster~newClusterCallback}. + * @memberof EntityCluster.prototype * @type {Event} */ - errorEvent : { - get : DeveloperError.throwInstantiationError + clusterEvent : { + get : function() { + return this._clusterEvent; + } }, /** - * Gets an event that will be raised when the value of isLoading changes. - * @memberof DataSource.prototype - * @type {Event} + * Gets or sets whether clustering billboard entities is enabled. + * @memberof EntityCluster.prototype + * @type {Boolean} */ - loadingEvent : { - get : DeveloperError.throwInstantiationError + clusterBillboards : { + get : function() { + return this._clusterBillboards; + }, + set : function(value) { + this._clusterDirty = this._clusterDirty || value !== this._clusterBillboards; + this._clusterBillboards = value; + } }, /** - * Gets whether or not this data source should be displayed. - * @memberof DataSource.prototype + * Gets or sets whether clustering labels entities is enabled. + * @memberof EntityCluster.prototype * @type {Boolean} */ - show : { - get : DeveloperError.throwInstantiationError + clusterLabels : { + get : function() { + return this._clusterLabels; + }, + set : function(value) { + this._clusterDirty = this._clusterDirty || value !== this._clusterLabels; + this._clusterLabels = value; + } }, - /** - * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. - * - * @memberof DataSource.prototype - * @type {EntityCluster} + * Gets or sets whether clustering point entities is enabled. + * @memberof EntityCluster.prototype + * @type {Boolean} */ - clustering : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Updates the data source to the provided time. This function is optional and - * is not required to be implemented. It is provided for data sources which - * retrieve data based on the current animation time or scene state. - * If implemented, update will be called by {@link DataSourceDisplay} once a frame. - * @function - * - * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. - */ - DataSource.prototype.update = DeveloperError.throwInstantiationError; - - /** - * @private - */ - DataSource.setLoading = function(dataSource, isLoading) { - if (dataSource._isLoading !== isLoading) { - if (isLoading) { - dataSource._entityCollection.suspendEvents(); - } else { - dataSource._entityCollection.resumeEvents(); - } - dataSource._isLoading = isLoading; - dataSource._loading.raiseEvent(dataSource, isLoading); - } - }; - - return DataSource; -}); - -define('Scene/SceneTransforms',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', - '../Core/defined', - '../Core/DeveloperError', - '../Core/Math', - '../Core/Matrix4', - '../Core/OrthographicFrustum', - '../Core/OrthographicOffCenterFrustum', - '../Core/Transforms', - './SceneMode' - ], function( - BoundingRectangle, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - defined, - DeveloperError, - CesiumMath, - Matrix4, - OrthographicFrustum, - OrthographicOffCenterFrustum, - Transforms, - SceneMode) { - 'use strict'; - - /** - * Functions that do scene-dependent transforms between rendering-related coordinate systems. - * - * @exports SceneTransforms - */ - var SceneTransforms = {}; - - var actualPositionScratch = new Cartesian4(0, 0, 0, 1); - var positionCC = new Cartesian4(); - var scratchViewport = new BoundingRectangle(); - - var scratchWindowCoord0 = new Cartesian2(); - var scratchWindowCoord1 = new Cartesian2(); - - /** - * Transforms a position in WGS84 coordinates to window coordinates. This is commonly used to place an - * HTML element at the same screen position as an object in the scene. - * - * @param {Scene} scene The scene. - * @param {Cartesian3} position The position in WGS84 (world) coordinates. - * @param {Cartesian2} [result] An optional object to return the input position transformed to window coordinates. - * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid. - * - * @example - * // Output the window position of longitude/latitude (0, 0) every time the mouse moves. - * var scene = widget.scene; - * var ellipsoid = scene.globe.ellipsoid; - * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - * handler.setInputAction(function(movement) { - * console.log(Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position)); - * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - */ - SceneTransforms.wgs84ToWindowCoordinates = function(scene, position, result) { - return SceneTransforms.wgs84WithEyeOffsetToWindowCoordinates(scene, position, Cartesian3.ZERO, result); - }; - - var scratchCartesian4 = new Cartesian4(); - var scratchEyeOffset = new Cartesian3(); - - function worldToClip(position, eyeOffset, camera, result) { - var viewMatrix = camera.viewMatrix; - - var positionEC = Matrix4.multiplyByVector(viewMatrix, Cartesian4.fromElements(position.x, position.y, position.z, 1, scratchCartesian4), scratchCartesian4); - - var zEyeOffset = Cartesian3.multiplyComponents(eyeOffset, Cartesian3.normalize(positionEC, scratchEyeOffset), scratchEyeOffset); - positionEC.x += eyeOffset.x + zEyeOffset.x; - positionEC.y += eyeOffset.y + zEyeOffset.y; - positionEC.z += zEyeOffset.z; - - return Matrix4.multiplyByVector(camera.frustum.projectionMatrix, positionEC, result); - } - - var scratchMaxCartographic = new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO); - var scratchProjectedCartesian = new Cartesian3(); - var scratchCameraPosition = new Cartesian3(); - - /** - * @private - */ - SceneTransforms.wgs84WithEyeOffsetToWindowCoordinates = function(scene, position, eyeOffset, result) { - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - if (!defined(position)) { - throw new DeveloperError('position is required.'); - } - - // Transform for 3D, 2D, or Columbus view - var frameState = scene.frameState; - var actualPosition = SceneTransforms.computeActualWgs84Position(frameState, position, actualPositionScratch); - - if (!defined(actualPosition)) { - return undefined; + clusterPoints : { + get : function() { + return this._clusterPoints; + }, + set : function(value) { + this._clusterDirty = this._clusterDirty || value !== this._clusterPoints; + this._clusterPoints = value; + } } + }); - // Assuming viewport takes up the entire canvas... - var canvas = scene.canvas; - var viewport = scratchViewport; - viewport.x = 0; - viewport.y = 0; - viewport.width = canvas.clientWidth; - viewport.height = canvas.clientHeight; + function createGetEntity(collectionProperty, CollectionConstructor, unusedIndicesProperty, entityIndexProperty) { + return function(entity) { + var collection = this[collectionProperty]; - var camera = scene.camera; - var cameraCentered = false; + if (!defined(this._collectionIndicesByEntity)) { + this._collectionIndicesByEntity = {}; + } - if (frameState.mode === SceneMode.SCENE2D) { - var projection = scene.mapProjection; - var maxCartographic = scratchMaxCartographic; - var maxCoord = projection.project(maxCartographic, scratchProjectedCartesian); + var entityIndices = this._collectionIndicesByEntity[entity.id]; - var cameraPosition = Cartesian3.clone(camera.position, scratchCameraPosition); - var frustum = camera.frustum.clone(); + if (!defined(entityIndices)) { + entityIndices = this._collectionIndicesByEntity[entity.id] = { + billboardIndex: undefined, + labelIndex: undefined, + pointIndex: undefined + }; + } - var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, new Matrix4()); - var projectionMatrix = camera.frustum.projectionMatrix; + if (defined(collection) && defined(entityIndices[entityIndexProperty])) { + return collection.get(entityIndices[entityIndexProperty]); + } - var x = camera.positionWC.y; - var eyePoint = Cartesian3.fromElements(CesiumMath.sign(x) * maxCoord.x - x, 0.0, -camera.positionWC.x); - var windowCoordinates = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, eyePoint); + if (!defined(collection)) { + collection = this[collectionProperty] = new CollectionConstructor({ + scene : this._scene + }); + } - if (x === 0.0 || windowCoordinates.x <= 0.0 || windowCoordinates.x >= canvas.clientWidth) { - cameraCentered = true; + var index; + var entityItem; + + var unusedIndices = this[unusedIndicesProperty]; + if (unusedIndices.length > 0) { + index = unusedIndices.pop(); + entityItem = collection.get(index); } else { - if (windowCoordinates.x > canvas.clientWidth * 0.5) { - viewport.width = windowCoordinates.x; + entityItem = collection.add(); + index = collection.length - 1; + } - camera.frustum.right = maxCoord.x - x; + entityIndices[entityIndexProperty] = index; - positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); - SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord0); + this._clusterDirty = true; - viewport.x += windowCoordinates.x; + return entityItem; + }; + } - camera.position.x = -camera.position.x; + function removeEntityIndicesIfUnused(entityCluster, entityId) { + var indices = entityCluster._collectionIndicesByEntity[entityId]; - var right = camera.frustum.right; - camera.frustum.right = -camera.frustum.left; - camera.frustum.left = -right; + if (!defined(indices.billboardIndex) && !defined(indices.labelIndex) && !defined(indices.pointIndex)) { + delete entityCluster._collectionIndicesByEntity[entityId]; + } + } - positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); - SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord1); - } else { - viewport.x += windowCoordinates.x; - viewport.width -= windowCoordinates.x; + /** + * Returns a new {@link Label}. + * @param {Entity} entity The entity that will use the returned {@link Label} for visualization. + * @returns {Label} The label that will be used to visualize an entity. + * + * @private + */ + EntityCluster.prototype.getLabel = createGetEntity('_labelCollection', LabelCollection, '_unusedLabelIndices', 'labelIndex'); - camera.frustum.left = -maxCoord.x - x; - positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); - SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord0); + /** + * Removes the {@link Label} associated with an entity so it can be reused by another entity. + * @param {Entity} entity The entity that will uses the returned {@link Label} for visualization. + * + * @private + */ + EntityCluster.prototype.removeLabel = function(entity) { + var entityIndices = this._collectionIndicesByEntity && this._collectionIndicesByEntity[entity.id]; + if (!defined(this._labelCollection) || !defined(entityIndices) || !defined(entityIndices.labelIndex)) { + return; + } - viewport.x = viewport.x - viewport.width; + var index = entityIndices.labelIndex; + entityIndices.labelIndex = undefined; + removeEntityIndicesIfUnused(this, entity.id); - camera.position.x = -camera.position.x; + var label = this._labelCollection.get(index); + label.show = false; + label.text = ''; + label.id = undefined; - var left = camera.frustum.left; - camera.frustum.left = -camera.frustum.right; - camera.frustum.right = -left; + this._unusedLabelIndices.push(index); - positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); - SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, scratchWindowCoord1); - } + this._clusterDirty = true; + }; - Cartesian3.clone(cameraPosition, camera.position); - camera.frustum = frustum.clone(); + /** + * Returns a new {@link Billboard}. + * @param {Entity} entity The entity that will use the returned {@link Billboard} for visualization. + * @returns {Billboard} The label that will be used to visualize an entity. + * + * @private + */ + EntityCluster.prototype.getBillboard = createGetEntity('_billboardCollection', BillboardCollection, '_unusedBillboardIndices', 'billboardIndex'); - result = Cartesian2.clone(scratchWindowCoord0, result); - if (result.x < 0.0 || result.x > canvas.clientWidth) { - result.x = scratchWindowCoord1.x; - } - } + + /** + * Removes the {@link Billboard} associated with an entity so it can be reused by another entity. + * @param {Entity} entity The entity that will uses the returned {@link Billboard} for visualization. + * + * @private + */ + EntityCluster.prototype.removeBillboard = function(entity) { + var entityIndices = this._collectionIndicesByEntity && this._collectionIndicesByEntity[entity.id]; + if (!defined(this._billboardCollection) || !defined(entityIndices) || !defined(entityIndices.billboardIndex)) { + return; } - if (frameState.mode !== SceneMode.SCENE2D || cameraCentered) { - // View-projection matrix to transform from world coordinates to clip coordinates - positionCC = worldToClip(actualPosition, eyeOffset, camera, positionCC); - if (positionCC.z < 0 && !(camera.frustum instanceof OrthographicFrustum) && !(camera.frustum instanceof OrthographicOffCenterFrustum)) { - return undefined; - } + var index = entityIndices.billboardIndex; + entityIndices.billboardIndex = undefined; + removeEntityIndicesIfUnused(this, entity.id); - result = SceneTransforms.clipToGLWindowCoordinates(viewport, positionCC, result); - } + var billboard = this._billboardCollection.get(index); + billboard.id = undefined; + billboard.show = false; + billboard.image = undefined; - result.y = canvas.clientHeight - result.y; - return result; + this._unusedBillboardIndices.push(index); + + this._clusterDirty = true; }; /** - * Transforms a position in WGS84 coordinates to drawing buffer coordinates. This may produce different - * results from SceneTransforms.wgs84ToWindowCoordinates when the browser zoom is not 100%, or on high-DPI displays. + * Returns a new {@link Point}. + * @param {Entity} entity The entity that will use the returned {@link Point} for visualization. + * @returns {Point} The label that will be used to visualize an entity. * - * @param {Scene} scene The scene. - * @param {Cartesian3} position The position in WGS84 (world) coordinates. - * @param {Cartesian2} [result] An optional object to return the input position transformed to window coordinates. - * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid. + * @private + */ + EntityCluster.prototype.getPoint = createGetEntity('_pointCollection', PointPrimitiveCollection, '_unusedPointIndices', 'pointIndex'); + + /** + * Removes the {@link Point} associated with an entity so it can be reused by another entity. + * @param {Entity} entity The entity that will uses the returned {@link Point} for visualization. * - * @example - * // Output the window position of longitude/latitude (0, 0) every time the mouse moves. - * var scene = widget.scene; - * var ellipsoid = scene.globe.ellipsoid; - * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - * handler.setInputAction(function(movement) { - * console.log(Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position)); - * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + * @private */ - SceneTransforms.wgs84ToDrawingBufferCoordinates = function(scene, position, result) { - result = SceneTransforms.wgs84ToWindowCoordinates(scene, position, result); - if (!defined(result)) { - return undefined; + EntityCluster.prototype.removePoint = function(entity) { + var entityIndices = this._collectionIndicesByEntity && this._collectionIndicesByEntity[entity.id]; + if (!defined(this._pointCollection) || !defined(entityIndices) || !defined(entityIndices.pointIndex)) { + return; } - return SceneTransforms.transformWindowToDrawingBuffer(scene, result, result); - }; + var index = entityIndices.pointIndex; + entityIndices.pointIndex = undefined; + removeEntityIndicesIfUnused(this, entity.id); - var projectedPosition = new Cartesian3(); - var positionInCartographic = new Cartographic(); + var point = this._pointCollection.get(index); + point.show = false; + point.id = undefined; - /** - * @private - */ - SceneTransforms.computeActualWgs84Position = function(frameState, position, result) { - var mode = frameState.mode; + this._unusedPointIndices.push(index); - if (mode === SceneMode.SCENE3D) { - return Cartesian3.clone(position, result); - } + this._clusterDirty = true; + }; - var projection = frameState.mapProjection; - var cartographic = projection.ellipsoid.cartesianToCartographic(position, positionInCartographic); - if (!defined(cartographic)) { - return undefined; + function disableCollectionClustering(collection) { + if (!defined(collection)) { + return; } - projection.project(cartographic, projectedPosition); + var length = collection.length; + for (var i = 0; i < length; ++i) { + collection.get(i).clusterShow = true; + } + } - if (mode === SceneMode.COLUMBUS_VIEW) { - return Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, result); + function updateEnable(entityCluster) { + if (entityCluster.enabled) { + return; } - if (mode === SceneMode.SCENE2D) { - return Cartesian3.fromElements(0.0, projectedPosition.x, projectedPosition.y, result); + if (defined(entityCluster._clusterLabelCollection)) { + entityCluster._clusterLabelCollection.destroy(); + } + if (defined(entityCluster._clusterBillboardCollection)) { + entityCluster._clusterBillboardCollection.destroy(); + } + if (defined(entityCluster._clusterPointCollection)) { + entityCluster._clusterPointCollection.destroy(); } - // mode === SceneMode.MORPHING - var morphTime = frameState.morphTime; - return Cartesian3.fromElements( - CesiumMath.lerp(projectedPosition.z, position.x, morphTime), - CesiumMath.lerp(projectedPosition.x, position.y, morphTime), - CesiumMath.lerp(projectedPosition.y, position.z, morphTime), - result); - }; + entityCluster._clusterLabelCollection = undefined; + entityCluster._clusterBillboardCollection = undefined; + entityCluster._clusterPointCollection = undefined; - var positionNDC = new Cartesian3(); - var positionWC = new Cartesian3(); - var viewportTransform = new Matrix4(); + disableCollectionClustering(entityCluster._labelCollection); + disableCollectionClustering(entityCluster._billboardCollection); + disableCollectionClustering(entityCluster._pointCollection); + } /** + * Gets the draw commands for the clustered billboards/points/labels if enabled, otherwise, + * queues the draw commands for billboards/points/labels created for entities. * @private */ - SceneTransforms.clipToGLWindowCoordinates = function(viewport, position, result) { - // Perspective divide to transform from clip coordinates to normalized device coordinates - Cartesian3.divideByScalar(position, position.w, positionNDC); + EntityCluster.prototype.update = function(frameState) { + // If clustering is enabled before the label collection is updated, + // the glyphs haven't been created so the screen space bounding boxes + // are incorrect. + var commandList; + if (defined(this._labelCollection) && this._labelCollection.length > 0 && this._labelCollection.get(0)._glyphs.length === 0) { + commandList = frameState.commandList; + frameState.commandList = []; + this._labelCollection.update(frameState); + frameState.commandList = commandList; + } - // Viewport transform to transform from clip coordinates to window coordinates - Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, viewportTransform); - Matrix4.multiplyByPoint(viewportTransform, positionNDC, positionWC); + // If clustering is enabled before the billboard collection is updated, + // the images haven't been added to the image atlas so the screen space bounding boxes + // are incorrect. + if (defined(this._billboardCollection) && this._billboardCollection.length > 0 && !defined(this._billboardCollection.get(0).width)) { + commandList = frameState.commandList; + frameState.commandList = []; + this._billboardCollection.update(frameState); + frameState.commandList = commandList; + } - return Cartesian2.fromCartesian3(positionWC, result); + if (this._enabledDirty) { + this._enabledDirty = false; + updateEnable(this); + this._clusterDirty = true; + } + + if (this._clusterDirty) { + this._clusterDirty = false; + this._cluster(); + } + + if (defined(this._clusterLabelCollection)) { + this._clusterLabelCollection.update(frameState); + } + if (defined(this._clusterBillboardCollection)) { + this._clusterBillboardCollection.update(frameState); + } + if (defined(this._clusterPointCollection)) { + this._clusterPointCollection.update(frameState); + } + + if (defined(this._labelCollection)) { + this._labelCollection.update(frameState); + } + if (defined(this._billboardCollection)) { + this._billboardCollection.update(frameState); + } + if (defined(this._pointCollection)) { + this._pointCollection.update(frameState); + } }; /** - * @private + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Unlike other objects that use WebGL resources, this object can be reused. For example, if a data source is removed + * from a data source collection and added to another. + * </p> + * + * @returns {undefined} */ - SceneTransforms.transformWindowToDrawingBuffer = function(scene, windowPosition, result) { - var canvas = scene.canvas; - var xScale = scene.drawingBufferWidth / canvas.clientWidth; - var yScale = scene.drawingBufferHeight / canvas.clientHeight; - return Cartesian2.fromElements(windowPosition.x * xScale, windowPosition.y * yScale, result); - }; + EntityCluster.prototype.destroy = function() { + this._labelCollection = this._labelCollection && this._labelCollection.destroy(); + this._billboardCollection = this._billboardCollection && this._billboardCollection.destroy(); + this._pointCollection = this._pointCollection && this._pointCollection.destroy(); - var scratchNDC = new Cartesian4(); - var scratchWorldCoords = new Cartesian4(); + this._clusterLabelCollection = this._clusterLabelCollection && this._clusterLabelCollection.destroy(); + this._clusterBillboardCollection = this._clusterBillboardCollection && this._clusterBillboardCollection.destroy(); + this._clusterPointCollection = this._clusterPointCollection && this._clusterPointCollection.destroy(); - /** - * @private - */ - SceneTransforms.drawingBufferToWgs84Coordinates = function(scene, drawingBufferPosition, depth, result) { - var context = scene.context; - var uniformState = context.uniformState; + if (defined(this._removeEventListener)) { + this._removeEventListener(); + this._removeEventListener = undefined; + } - var viewport = scene._passState.viewport; - var ndc = Cartesian4.clone(Cartesian4.UNIT_W, scratchNDC); - ndc.x = (drawingBufferPosition.x - viewport.x) / viewport.width * 2.0 - 1.0; - ndc.y = (drawingBufferPosition.y - viewport.y) / viewport.height * 2.0 - 1.0; - ndc.z = (depth * 2.0) - 1.0; - ndc.w = 1.0; + this._labelCollection = undefined; + this._billboardCollection = undefined; + this._pointCollection = undefined; - var worldCoords; - var frustum = scene.camera.frustum; - if (!defined(frustum.fovy)) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; - } - var currentFrustum = uniformState.currentFrustum; - worldCoords = scratchWorldCoords; - worldCoords.x = (ndc.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; - worldCoords.y = (ndc.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; - worldCoords.z = (ndc.z * (currentFrustum.x - currentFrustum.y) - currentFrustum.x - currentFrustum.y) * 0.5; - worldCoords.w = 1.0; + this._clusterBillboardCollection = undefined; + this._clusterLabelCollection = undefined; + this._clusterPointCollection = undefined; - worldCoords = Matrix4.multiplyByVector(uniformState.inverseView, worldCoords, worldCoords); - } else { - worldCoords = Matrix4.multiplyByVector(uniformState.inverseViewProjection, ndc, scratchWorldCoords); + this._collectionIndicesByEntity = undefined; - // Reverse perspective divide - var w = 1.0 / worldCoords.w; - Cartesian3.multiplyByScalar(worldCoords, w, worldCoords); - } + this._unusedLabelIndices = []; + this._unusedBillboardIndices = []; + this._unusedPointIndices = []; - return Cartesian3.fromCartesian4(worldCoords, result); + this._previousClusters = []; + this._previousHeight = undefined; + + this._enabledDirty = false; + this._pixelRangeDirty = false; + this._minimumClusterSizeDirty = false; + + return undefined; }; - return SceneTransforms; + /** + * A event listener function used to style clusters. + * @callback EntityCluster~newClusterCallback + * + * @param {Entity[]} clusteredEntities An array of the entities contained in the cluster. + * @param {Object} cluster An object containing billboard, label, and point properties. The values are the same as + * billboard, label and point entities, but must be the values of the ConstantProperty. + * + * @example + * // The default cluster values. + * dataSource.clustering.clusterEvent.addEventListener(function(entities, cluster) { + * cluster.label.show = true; + * cluster.label.text = entities.length.toLocaleString(); + * }); + */ + + return EntityCluster; }); -define('Scene/Billboard',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', - '../Core/Color', - '../Core/createGuid', - '../Core/defaultValue', +define('DataSources/CustomDataSource',[ '../Core/defined', '../Core/defineProperties', '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/Matrix4', - '../Core/NearFarScalar', - './HeightReference', - './HorizontalOrigin', - './SceneMode', - './SceneTransforms', - './VerticalOrigin' + '../Core/Event', + './DataSource', + './EntityCluster', + './EntityCollection' ], function( - BoundingRectangle, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - Color, - createGuid, - defaultValue, defined, defineProperties, DeveloperError, - DistanceDisplayCondition, - Matrix4, - NearFarScalar, - HeightReference, - HorizontalOrigin, - SceneMode, - SceneTransforms, - VerticalOrigin) { + Event, + DataSource, + EntityCluster, + EntityCollection) { 'use strict'; /** - * A viewport-aligned image positioned in the 3D scene, that is created - * and rendered using a {@link BillboardCollection}. A billboard is created and its initial - * properties are set by calling {@link BillboardCollection#add}. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.png' width='400' height='300' /><br /> - * Example billboards - * </div> - * - * @alias Billboard + * A {@link DataSource} implementation which can be used to manually manage a group of entities. * - * @performance Reading a property, e.g., {@link Billboard#show}, is constant time. - * Assigning to a property is constant time but results in - * CPU to GPU traffic when {@link BillboardCollection#update} is called. The per-billboard traffic is - * the same regardless of how many properties were updated. If most billboards in a collection need to be - * updated, it may be more efficient to clear the collection with {@link BillboardCollection#removeAll} - * and add new billboards instead of modifying each one. + * @alias CustomDataSource + * @constructor * - * @exception {DeveloperError} scaleByDistance.far must be greater than scaleByDistance.near - * @exception {DeveloperError} translucencyByDistance.far must be greater than translucencyByDistance.near - * @exception {DeveloperError} pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near - * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near + * @param {String} [name] A human-readable name for this instance. * - * @see BillboardCollection - * @see BillboardCollection#add - * @see Label + * @example + * var dataSource = new Cesium.CustomDataSource('myData'); * - * @internalConstructor + * var entity = dataSource.entities.add({ + * position : Cesium.Cartesian3.fromDegrees(1, 2, 0), + * billboard : { + * image : 'image.png' + * } + * }); * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Billboards.html|Cesium Sandcastle Billboard Demo} + * viewer.dataSources.add(dataSource); */ - function Billboard(options, billboardCollection) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); - } - - var translucencyByDistance = options.translucencyByDistance; - var pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; - var scaleByDistance = options.scaleByDistance; - var distanceDisplayCondition = options.distanceDisplayCondition; - if (defined(translucencyByDistance)) { - if (translucencyByDistance.far <= translucencyByDistance.near) { - throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); - } - translucencyByDistance = NearFarScalar.clone(translucencyByDistance); - } - if (defined(pixelOffsetScaleByDistance)) { - if (pixelOffsetScaleByDistance.far <= pixelOffsetScaleByDistance.near) { - throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); - } - pixelOffsetScaleByDistance = NearFarScalar.clone(pixelOffsetScaleByDistance); - } - if (defined(scaleByDistance)) { - if (scaleByDistance.far <= scaleByDistance.near) { - throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); - } - scaleByDistance = NearFarScalar.clone(scaleByDistance); - } - if (defined(distanceDisplayCondition)) { - if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); - } - distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); - } - - this._show = defaultValue(options.show, true); - this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); - this._actualPosition = Cartesian3.clone(this._position); // For columbus view and 2D - this._pixelOffset = Cartesian2.clone(defaultValue(options.pixelOffset, Cartesian2.ZERO)); - this._translate = new Cartesian2(0.0, 0.0); // used by labels for glyph vertex translation - this._eyeOffset = Cartesian3.clone(defaultValue(options.eyeOffset, Cartesian3.ZERO)); - this._heightReference = defaultValue(options.heightReference, HeightReference.NONE); - this._verticalOrigin = defaultValue(options.verticalOrigin, VerticalOrigin.CENTER); - this._horizontalOrigin = defaultValue(options.horizontalOrigin, HorizontalOrigin.CENTER); - this._scale = defaultValue(options.scale, 1.0); - this._color = Color.clone(defaultValue(options.color, Color.WHITE)); - this._rotation = defaultValue(options.rotation, 0.0); - this._alignedAxis = Cartesian3.clone(defaultValue(options.alignedAxis, Cartesian3.ZERO)); - this._width = options.width; - this._height = options.height; - this._scaleByDistance = scaleByDistance; - this._translucencyByDistance = translucencyByDistance; - this._pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; - this._sizeInMeters = defaultValue(options.sizeInMeters, false); - this._distanceDisplayCondition = distanceDisplayCondition; - this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); - this._id = options.id; - this._collection = defaultValue(options.collection, billboardCollection); - - this._pickId = undefined; - this._pickPrimitive = defaultValue(options._pickPrimitive, this); - this._billboardCollection = billboardCollection; - this._dirty = false; - this._index = -1; //Used only by BillboardCollection - - this._imageIndex = -1; - this._imageIndexPromise = undefined; - this._imageId = undefined; - this._image = undefined; - this._imageSubRegion = undefined; - this._imageWidth = undefined; - this._imageHeight = undefined; - - var image = options.image; - var imageId = options.imageId; - if (defined(image)) { - if (!defined(imageId)) { - if (typeof image === 'string') { - imageId = image; - } else if (defined(image.src)) { - imageId = image.src; - } else { - imageId = createGuid(); - } - } - - this._imageId = imageId; - this._image = image; - } - - if (defined(options.imageSubRegion)) { - this._imageId = imageId; - this._imageSubRegion = options.imageSubRegion; - } - - if (defined(this._billboardCollection._textureAtlas)) { - this._loadImage(); - } - - this._actualClampedPosition = undefined; - this._removeCallbackFunc = undefined; - this._mode = SceneMode.SCENE3D; - - this._clusterShow = true; - - this._updateClamping(); - } - - var SHOW_INDEX = Billboard.SHOW_INDEX = 0; - var POSITION_INDEX = Billboard.POSITION_INDEX = 1; - var PIXEL_OFFSET_INDEX = Billboard.PIXEL_OFFSET_INDEX = 2; - var EYE_OFFSET_INDEX = Billboard.EYE_OFFSET_INDEX = 3; - var HORIZONTAL_ORIGIN_INDEX = Billboard.HORIZONTAL_ORIGIN_INDEX = 4; - var VERTICAL_ORIGIN_INDEX = Billboard.VERTICAL_ORIGIN_INDEX = 5; - var SCALE_INDEX = Billboard.SCALE_INDEX = 6; - var IMAGE_INDEX_INDEX = Billboard.IMAGE_INDEX_INDEX = 7; - var COLOR_INDEX = Billboard.COLOR_INDEX = 8; - var ROTATION_INDEX = Billboard.ROTATION_INDEX = 9; - var ALIGNED_AXIS_INDEX = Billboard.ALIGNED_AXIS_INDEX = 10; - var SCALE_BY_DISTANCE_INDEX = Billboard.SCALE_BY_DISTANCE_INDEX = 11; - var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX = 12; - var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = 13; - var DISTANCE_DISPLAY_CONDITION = Billboard.DISTANCE_DISPLAY_CONDITION = 14; - var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE = 15; - Billboard.NUMBER_OF_PROPERTIES = 16; - - function makeDirty(billboard, propertyChanged) { - var billboardCollection = billboard._billboardCollection; - if (defined(billboardCollection)) { - billboardCollection._updateBillboard(billboard, propertyChanged); - billboard._dirty = true; - } + function CustomDataSource(name) { + this._name = name; + this._clock = undefined; + this._changed = new Event(); + this._error = new Event(); + this._isLoading = false; + this._loading = new Event(); + this._entityCollection = new EntityCollection(this); + this._entityCluster = new EntityCluster(); } - defineProperties(Billboard.prototype, { - /** - * Determines if this billboard will be shown. Use this to hide or show a billboard, instead - * of removing it and re-adding it to the collection. - * @memberof Billboard.prototype - * @type {Boolean} - * @default true - */ - show : { - get : function() { - return this._show; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._show !== value) { - this._show = value; - makeDirty(this, SHOW_INDEX); - } - } - }, - - /** - * Gets or sets the Cartesian position of this billboard. - * @memberof Billboard.prototype - * @type {Cartesian3} - */ - position : { - get : function() { - return this._position; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var position = this._position; - if (!Cartesian3.equals(position, value)) { - Cartesian3.clone(value, position); - Cartesian3.clone(value, this._actualPosition); - this._updateClamping(); - makeDirty(this, POSITION_INDEX); - } - } - }, - - /** - * Gets or sets the height reference of this billboard. - * @memberof Billboard.prototype - * @type {HeightReference} - * @default HeightReference.NONE - */ - heightReference : { - get : function() { - return this._heightReference; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var heightReference = this._heightReference; - if (value !== heightReference) { - this._heightReference = value; - this._updateClamping(); - makeDirty(this, POSITION_INDEX); - } - } - }, - - /** - * Gets or sets the pixel offset in screen space from the origin of this billboard. This is commonly used - * to align multiple billboards and labels at the same position, e.g., an image and text. The - * screen space origin is the top, left corner of the canvas; <code>x</code> increases from - * left to right, and <code>y</code> increases from top to bottom. - * <br /><br /> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><code>default</code><br/><img src='Images/Billboard.setPixelOffset.default.png' width='250' height='188' /></td> - * <td align='center'><code>b.pixeloffset = new Cartesian2(50, 25);</code><br/><img src='Images/Billboard.setPixelOffset.x50y-25.png' width='250' height='188' /></td> - * </tr></table> - * The billboard's origin is indicated by the yellow point. - * </div> - * @memberof Billboard.prototype - * @type {Cartesian2} - */ - pixelOffset : { - get : function() { - return this._pixelOffset; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var pixelOffset = this._pixelOffset; - if (!Cartesian2.equals(pixelOffset, value)) { - Cartesian2.clone(value, pixelOffset); - makeDirty(this, PIXEL_OFFSET_INDEX); - } - } - }, - - /** - * Gets or sets near and far scaling properties of a Billboard based on the billboard's distance from the camera. - * A billboard's scale will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the billboard's scale remains clamped to the nearest bound. If undefined, - * scaleByDistance will be disabled. - * @memberof Billboard.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a billboard's scaleByDistance to scale by 1.5 when the - * // camera is 1500 meters from the billboard and disappear as - * // the camera distance approaches 8.0e6 meters. - * b.scaleByDistance = new Cesium.NearFarScalar(1.5e2, 1.5, 8.0e6, 0.0); - * - * @example - * // Example 2. - * // disable scaling by distance - * b.scaleByDistance = undefined; - */ - scaleByDistance : { - get : function() { - return this._scaleByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var scaleByDistance = this._scaleByDistance; - if (!NearFarScalar.equals(scaleByDistance, value)) { - this._scaleByDistance = NearFarScalar.clone(value, scaleByDistance); - makeDirty(this, SCALE_BY_DISTANCE_INDEX); - } - } - }, - - /** - * Gets or sets near and far translucency properties of a Billboard based on the billboard's distance from the camera. - * A billboard's translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the billboard's translucency remains clamped to the nearest bound. If undefined, - * translucencyByDistance will be disabled. - * @memberof Billboard.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a billboard's translucency to 1.0 when the - * // camera is 1500 meters from the billboard and disappear as - * // the camera distance approaches 8.0e6 meters. - * b.translucencyByDistance = new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.0); - * - * @example - * // Example 2. - * // disable translucency by distance - * b.translucencyByDistance = undefined; - */ - translucencyByDistance : { - get : function() { - return this._translucencyByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var translucencyByDistance = this._translucencyByDistance; - if (!NearFarScalar.equals(translucencyByDistance, value)) { - this._translucencyByDistance = NearFarScalar.clone(value, translucencyByDistance); - makeDirty(this, TRANSLUCENCY_BY_DISTANCE_INDEX); - } - } - }, - + defineProperties(CustomDataSource.prototype, { /** - * Gets or sets near and far pixel offset scaling properties of a Billboard based on the billboard's distance from the camera. - * A billboard's pixel offset will be scaled between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the billboard's pixel offset scale remains clamped to the nearest bound. If undefined, - * pixelOffsetScaleByDistance will be disabled. - * @memberof Billboard.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a billboard's pixel offset scale to 0.0 when the - * // camera is 1500 meters from the billboard and scale pixel offset to 10.0 pixels - * // in the y direction the camera distance approaches 8.0e6 meters. - * b.pixelOffset = new Cesium.Cartesian2(0.0, 1.0); - * b.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(1.5e2, 0.0, 8.0e6, 10.0); - * - * @example - * // Example 2. - * // disable pixel offset by distance - * b.pixelOffsetScaleByDistance = undefined; + * Gets or sets a human-readable name for this instance. + * @memberof CustomDataSource.prototype + * @type {String} */ - pixelOffsetScaleByDistance : { + name : { get : function() { - return this._pixelOffsetScaleByDistance; + return this._name; }, set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; - if (!NearFarScalar.equals(pixelOffsetScaleByDistance, value)) { - this._pixelOffsetScaleByDistance = NearFarScalar.clone(value, pixelOffsetScaleByDistance); - makeDirty(this, PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX); + if (this._name !== value) { + this._name = value; + this._changed.raiseEvent(this); } } }, - /** - * Gets or sets the 3D Cartesian offset applied to this billboard in eye coordinates. Eye coordinates is a left-handed - * coordinate system, where <code>x</code> points towards the viewer's right, <code>y</code> points up, and - * <code>z</code> points into the screen. Eye coordinates use the same scale as world and model coordinates, - * which is typically meters. - * <br /><br /> - * An eye offset is commonly used to arrange multiple billboards or objects at the same position, e.g., to - * arrange a billboard above its corresponding 3D model. - * <br /><br /> - * Below, the billboard is positioned at the center of the Earth but an eye offset makes it always - * appear on top of the Earth regardless of the viewer's or Earth's orientation. - * <br /><br /> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> - * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> - * </tr></table> - * <code>b.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code><br /><br /> - * </div> - * @memberof Billboard.prototype - * @type {Cartesian3} + * Gets or sets the clock for this instance. + * @memberof CustomDataSource.prototype + * @type {DataSourceClock} */ - eyeOffset : { + clock : { get : function() { - return this._eyeOffset; + return this._clock; }, set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var eyeOffset = this._eyeOffset; - if (!Cartesian3.equals(eyeOffset, value)) { - Cartesian3.clone(value, eyeOffset); - makeDirty(this, EYE_OFFSET_INDEX); + if (this._clock !== value) { + this._clock = value; + this._changed.raiseEvent(this); } } }, - /** - * Gets or sets the horizontal origin of this billboard, which determines if the billboard is - * to the left, center, or right of its anchor position. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> - * </div> - * @memberof Billboard.prototype - * @type {HorizontalOrigin} - * @example - * // Use a bottom, left origin - * b.horizontalOrigin = Cesium.HorizontalOrigin.LEFT; - * b.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; + * Gets the collection of {@link Entity} instances. + * @memberof CustomDataSource.prototype + * @type {EntityCollection} */ - horizontalOrigin : { + entities : { get : function() { - return this._horizontalOrigin; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._horizontalOrigin !== value) { - this._horizontalOrigin = value; - makeDirty(this, HORIZONTAL_ORIGIN_INDEX); - } + return this._entityCollection; } }, - /** - * Gets or sets the vertical origin of this billboard, which determines if the billboard is - * to the above, below, or at the center of its anchor position. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> - * </div> - * @memberof Billboard.prototype - * @type {VerticalOrigin} - * @example - * // Use a bottom, left origin - * b.horizontalOrigin = Cesium.HorizontalOrigin.LEFT; - * b.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; + * Gets or sets whether the data source is currently loading data. + * @memberof CustomDataSource.prototype + * @type {Boolean} */ - verticalOrigin : { + isLoading : { get : function() { - return this._verticalOrigin; + return this._isLoading; }, set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._verticalOrigin !== value) { - this._verticalOrigin = value; - makeDirty(this, VERTICAL_ORIGIN_INDEX); - } + DataSource.setLoading(this, value); } }, - /** - * Gets or sets the uniform scale that is multiplied with the billboard's image size in pixels. - * A scale of <code>1.0</code> does not change the size of the billboard; a scale greater than - * <code>1.0</code> enlarges the billboard; a positive scale less than <code>1.0</code> shrinks - * the billboard. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setScale.png' width='400' height='300' /><br/> - * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, - * and <code>2.0</code>. - * </div> - * @memberof Billboard.prototype - * @type {Number} + * Gets an event that will be raised when the underlying data changes. + * @memberof CustomDataSource.prototype + * @type {Event} */ - scale : { + changedEvent : { get : function() { - return this._scale; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._scale !== value) { - this._scale = value; - makeDirty(this, SCALE_INDEX); - } - } - }, - - /** - * Gets or sets the color that is multiplied with the billboard's texture. This has two common use cases. First, - * the same white texture may be used by many different billboards, each with a different color, to create - * colored billboards. Second, the color's alpha component can be used to make the billboard translucent as shown below. - * An alpha of <code>0.0</code> makes the billboard transparent, and <code>1.0</code> makes the billboard opaque. - * <br /><br /> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><code>default</code><br/><img src='Images/Billboard.setColor.Alpha255.png' width='250' height='188' /></td> - * <td align='center'><code>alpha : 0.5</code><br/><img src='Images/Billboard.setColor.Alpha127.png' width='250' height='188' /></td> - * </tr></table> - * </div> - * <br /> - * The red, green, blue, and alpha values are indicated by <code>value</code>'s <code>red</code>, <code>green</code>, - * <code>blue</code>, and <code>alpha</code> properties as shown in Example 1. These components range from <code>0.0</code> - * (no intensity) to <code>1.0</code> (full intensity). - * @memberof Billboard.prototype - * @type {Color} - * - * @example - * // Example 1. Assign yellow. - * b.color = Cesium.Color.YELLOW; - * - * @example - * // Example 2. Make a billboard 50% translucent. - * b.color = new Cesium.Color(1.0, 1.0, 1.0, 0.5); + return this._changed; + } + }, + /** + * Gets an event that will be raised if an error is encountered during processing. + * @memberof CustomDataSource.prototype + * @type {Event} */ - color : { + errorEvent : { get : function() { - return this._color; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var color = this._color; - if (!Color.equals(color, value)) { - Color.clone(value, color); - makeDirty(this, COLOR_INDEX); - } + return this._error; } }, - /** - * Gets or sets the rotation angle in radians. - * @memberof Billboard.prototype - * @type {Number} + * Gets an event that will be raised when the data source either starts or stops loading. + * @memberof CustomDataSource.prototype + * @type {Event} */ - rotation : { + loadingEvent : { get : function() { - return this._rotation; + return this._loading; + } + }, + /** + * Gets whether or not this data source should be displayed. + * @memberof CustomDataSource.prototype + * @type {Boolean} + */ + show : { + get : function() { + return this._entityCollection.show; }, set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._rotation !== value) { - this._rotation = value; - makeDirty(this, ROTATION_INDEX); - } + this._entityCollection.show = value; } }, /** - * Gets or sets the aligned axis in world space. The aligned axis is the unit vector that the billboard up vector points towards. - * The default is the zero vector, which means the billboard is aligned to the screen up vector. - * @memberof Billboard.prototype - * @type {Cartesian3} - * @example - * // Example 1. - * // Have the billboard up vector point north - * billboard.alignedAxis = Cesium.Cartesian3.UNIT_Z; - * - * @example - * // Example 2. - * // Have the billboard point east. - * billboard.alignedAxis = Cesium.Cartesian3.UNIT_Z; - * billboard.rotation = -Cesium.Math.PI_OVER_TWO; + * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. * - * @example - * // Example 3. - * // Reset the aligned axis - * billboard.alignedAxis = Cesium.Cartesian3.ZERO; + * @memberof CustomDataSource.prototype + * @type {EntityCluster} */ - alignedAxis : { + clustering : { get : function() { - return this._alignedAxis; + return this._entityCluster; }, set : function(value) { if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var alignedAxis = this._alignedAxis; - if (!Cartesian3.equals(alignedAxis, value)) { - Cartesian3.clone(value, alignedAxis); - makeDirty(this, ALIGNED_AXIS_INDEX); + throw new DeveloperError('value must be defined.'); } + this._entityCluster = value; } + } + }); + + return CustomDataSource; +}); + +define('DataSources/CylinderGeometryUpdater',[ + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/CylinderGeometry', + '../Core/CylinderOutlineGeometry', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' + ], function( + Color, + ColorGeometryInstanceAttribute, + CylinderGeometry, + CylinderOutlineGeometry, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + ShowGeometryInstanceAttribute, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { + 'use strict'; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.length = undefined; + this.topRadius = undefined; + this.bottomRadius = undefined; + this.slices = undefined; + this.numberOfVerticalLines = undefined; + } + + /** + * A {@link GeometryUpdater} for cylinders. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias CylinderGeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. + */ + function CylinderGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(CylinderGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'cylinder', entity.cylinder, undefined); + } + + defineProperties(CylinderGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof CylinderGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof CylinderGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); + defineProperties(CylinderGeometryUpdater.prototype, { /** - * Gets or sets a width for the billboard. If undefined, the image width will be used. - * @memberof Billboard.prototype - * @type {Number} + * Gets the entity associated with this geometry. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Entity} + * @readonly */ - width : { + entity : { get : function() { - return defaultValue(this._width, this._imageWidth); - }, - set : function(value) { - if (this._width !== value) { - this._width = value; - makeDirty(this, IMAGE_INDEX_INDEX); - } + return this._entity; } }, - /** - * Gets or sets a height for the billboard. If undefined, the image height will be used. - * @memberof Billboard.prototype - * @type {Number} + * Gets a value indicating if the geometry has a fill component. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - height : { + fillEnabled : { get : function() { - return defaultValue(this._height, this._imageHeight); - }, - set : function(value) { - if (this._height !== value) { - this._height = value; - makeDirty(this, IMAGE_INDEX_INDEX); - } + return this._fillEnabled; } }, - /** - * Gets or sets if the billboard size is in meters or pixels. <code>true</code> to size the billboard in meters; - * otherwise, the size is in pixels. - * @memberof Billboard.prototype + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof CylinderGeometryUpdater.prototype + * * @type {Boolean} - * @default false + * @readonly */ - sizeInMeters : { + hasConstantFill : { get : function() { - return this._sizeInMeters; - }, - set : function(value) { - if (this._sizeInMeters !== value) { - this._sizeInMeters = value; - makeDirty(this, COLOR_INDEX); - } + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, - /** - * Gets or sets the condition specifying at what distance from the camera that this billboard will be displayed. - * @memberof Billboard.prototype - * @type {DistanceDisplayCondition} - * @default undefined + * Gets the material property used to fill the geometry. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly */ - distanceDisplayCondition : { + fillMaterialProperty : { get : function() { - return this._distanceDisplayCondition; - }, - set : function(value) { - if (!DistanceDisplayCondition.equals(value, this._distanceDisplayCondition)) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); - makeDirty(this, DISTANCE_DISPLAY_CONDITION); - } + return this._materialProperty; } }, - /** - * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. - * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. - * @memberof Billboard.prototype - * @type {Number} - * @default 0.0 + * Gets a value indicating if the geometry has an outline component. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - disableDepthTestDistance : { + outlineEnabled : { get : function() { - return this._disableDepthTestDistance; - }, - set : function(value) { - if (this._disableDepthTestDistance !== value) { - if (!defined(value) || value < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); - } - this._disableDepthTestDistance = value; - makeDirty(this, DISABLE_DEPTH_DISTANCE); - } + return this._outlineEnabled; } }, - /** - * Gets or sets the user-defined object returned when the billboard is picked. - * @memberof Billboard.prototype - * @type {Object} + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - id : { + hasConstantOutline : { get : function() { - return this._id; - }, - set : function(value) { - this._id = value; - if (defined(this._pickId)) { - this._pickId.object.id = value; - } + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); } }, - /** - * The primitive to return when picking this billboard. - * @memberof Billboard.prototype - * @private + * Gets the {@link Color} property for the geometry outline. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Property} + * @readonly */ - pickPrimitive : { + outlineColorProperty : { get : function() { - return this._pickPrimitive; - }, - set : function(value) { - this._pickPrimitive = value; - if (defined(this._pickId)) { - this._pickId.object.primitive = value; - } + return this._outlineColorProperty; } }, - /** - * <p> - * Gets or sets the image to be used for this billboard. If a texture has already been created for the - * given image, the existing texture is used. - * </p> - * <p> - * This property can be set to a loaded Image, a URL which will be loaded as an Image automatically, - * a canvas, or another billboard's image property (from the same billboard collection). - * </p> - * - * @memberof Billboard.prototype - * @type {String} - * @example - * // load an image from a URL - * b.image = 'some/image/url.png'; + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof CylinderGeometryUpdater.prototype * - * // assuming b1 and b2 are billboards in the same billboard collection, - * // use the same image for both billboards. - * b2.image = b1.image; + * @type {Number} + * @readonly */ - image : { + outlineWidth : { get : function() { - return this._imageId; - }, - set : function(value) { - if (!defined(value)) { - this._imageIndex = -1; - this._imageSubRegion = undefined; - this._imageId = undefined; - this._image = undefined; - this._imageIndexPromise = undefined; - makeDirty(this, IMAGE_INDEX_INDEX); - } else if (typeof value === 'string') { - this.setImage(value, value); - } else if (defined(value.src)) { - this.setImage(value.src, value); - } else { - this.setImage(createGuid(), value); - } + return this._outlineWidth; } }, - /** - * When <code>true</code>, this billboard is ready to render, i.e., the image - * has been downloaded and the WebGL resources are created. - * - * @memberof Billboard.prototype + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof CylinderGeometryUpdater.prototype * - * @type {Boolean} + * @type {Property} * @readonly + */ + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof CylinderGeometryUpdater.prototype * - * @default false + * @type {Property} + * @readonly */ - ready : { + distanceDisplayConditionProperty : { get : function() { - return this._imageIndex !== -1; + return this._distanceDisplayConditionProperty; } }, - /** - * Keeps track of the position of the billboard based on the height reference. - * @memberof Billboard.prototype - * @type {Cartesian3} - * @private + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - _clampedPosition : { + isDynamic : { get : function() { - return this._actualClampedPosition; - }, - set : function(value) { - this._actualClampedPosition = Cartesian3.clone(value, this._actualClampedPosition); - makeDirty(this, POSITION_INDEX); + return this._dynamic; } }, - /** - * Determines whether or not this billboard will be shown or hidden because it was clustered. - * @memberof Billboard.prototype + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof CylinderGeometryUpdater.prototype + * * @type {Boolean} - * @private + * @readonly */ - clusterShow : { + isClosed : { + value : true + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof CylinderGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { get : function() { - return this._clusterShow; - }, - set : function(value) { - if (this._clusterShow !== value) { - this._clusterShow = value; - makeDirty(this, SHOW_INDEX); - } + return this._geometryChanged; } } }); - Billboard.prototype.getPickId = function(context) { - if (!defined(this._pickId)) { - this._pickId = context.createPickId({ - primitive : this._pickPrimitive, - collection : this._collection, - id : this._id - }); - } - - return this._pickId; + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + CylinderGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; - Billboard.prototype._updateClamping = function() { - Billboard._updateClamping(this._billboardCollection, this); + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + CylinderGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; - var scratchCartographic = new Cartographic(); - var scratchPosition = new Cartesian3(); - - Billboard._updateClamping = function(collection, owner) { - var scene = collection._scene; - if (!defined(scene)) { - if (owner._heightReference !== HeightReference.NONE) { - throw new DeveloperError('Height reference is not supported without a scene.'); - } - return; - } - - var globe = scene.globe; - var ellipsoid = globe.ellipsoid; - var surface = globe._surface; - - var mode = scene.frameState.mode; - - var modeChanged = mode !== owner._mode; - owner._mode = mode; - - if ((owner._heightReference === HeightReference.NONE || modeChanged) && defined(owner._removeCallbackFunc)) { - owner._removeCallbackFunc(); - owner._removeCallbackFunc = undefined; - owner._clampedPosition = undefined; - } - - if (owner._heightReference === HeightReference.NONE || !defined(owner._position)) { - return; + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + CylinderGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - var position = ellipsoid.cartesianToCartographic(owner._position); - if (!defined(position)) { - owner._actualClampedPosition = undefined; - return; + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - if (defined(owner._removeCallbackFunc)) { - owner._removeCallbackFunc(); - } + var attributes; - function updateFunction(clampedPosition) { - if (owner._heightReference === HeightReference.RELATIVE_TO_GROUND) { - if (owner._mode === SceneMode.SCENE3D) { - var clampedCart = ellipsoid.cartesianToCartographic(clampedPosition, scratchCartographic); - clampedCart.height += position.height; - ellipsoid.cartographicToCartesian(clampedCart, clampedPosition); - } else { - clampedPosition.x += position.height; - } + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); } - owner._clampedPosition = Cartesian3.clone(clampedPosition, owner._clampedPosition); - } - owner._removeCallbackFunc = surface.updateHeight(position, updateFunction); - - Cartographic.clone(position, scratchCartographic); - var height = globe.getHeight(position); - if (defined(height)) { - scratchCartographic.height = height; + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; } - ellipsoid.cartographicToCartesian(scratchCartographic, scratchPosition); - - updateFunction(scratchPosition); + return new GeometryInstance({ + id : entity, + geometry : new CylinderGeometry(this._options), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), + attributes : attributes + }); }; - Billboard.prototype._loadImage = function() { - var atlas = this._billboardCollection._textureAtlas; - - var imageId = this._imageId; - var image = this._image; - var imageSubRegion = this._imageSubRegion; - var imageIndexPromise; - - if (defined(image)) { - imageIndexPromise = atlas.addImage(imageId, image); - } - if (defined(imageSubRegion)) { - imageIndexPromise = atlas.addSubRegion(imageId, imageSubRegion); + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + CylinderGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - this._imageIndexPromise = imageIndexPromise; - - if (!defined(imageIndexPromise)) { - return; + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var that = this; - imageIndexPromise.then(function(index) { - if (that._imageId !== imageId || that._image !== image || !BoundingRectangle.equals(that._imageSubRegion, imageSubRegion)) { - // another load occurred before this one finished, ignore the index - return; + return new GeometryInstance({ + id : entity, + geometry : new CylinderOutlineGeometry(this._options), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) } - - // fill in imageWidth and imageHeight - var textureCoordinates = atlas.textureCoordinates[index]; - that._imageWidth = atlas.texture.width * textureCoordinates.width; - that._imageHeight = atlas.texture.height * textureCoordinates.height; - - that._imageIndex = index; - that._ready = true; - that._image = undefined; - that._imageIndexPromise = undefined; - makeDirty(that, IMAGE_INDEX_INDEX); - }).otherwise(function(error) { - console.error('Error loading image for billboard: ' + error); - that._imageIndexPromise = undefined; }); }; /** - * <p> - * Sets the image to be used for this billboard. If a texture has already been created for the - * given id, the existing texture is used. - * </p> - * <p> - * This function is useful for dynamically creating textures that are shared across many billboards. - * Only the first billboard will actually call the function and create the texture, while subsequent - * billboards created with the same id will simply re-use the existing texture. - * </p> - * <p> - * To load an image from a URL, setting the {@link Billboard#image} property is more convenient. - * </p> - * - * @param {String} id The id of the image. This can be any string that uniquely identifies the image. - * @param {Image|Canvas|String|Billboard~CreateImageCallback} image The image to load. This parameter - * can either be a loaded Image or Canvas, a URL which will be loaded as an Image automatically, - * or a function which will be called to create the image if it hasn't been loaded already. - * @example - * // create a billboard image dynamically - * function drawImage(id) { - * // create and draw an image using a canvas - * var canvas = document.createElement('canvas'); - * var context2D = canvas.getContext('2d'); - * // ... draw image - * return canvas; - * } - * // drawImage will be called to create the texture - * b.setImage('myImage', drawImage); + * Returns true if this object was destroyed; otherwise, false. * - * // subsequent billboards created in the same collection using the same id will use the existing - * // texture, without the need to create the canvas or draw the image - * b2.setImage('myImage', drawImage); + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - Billboard.prototype.setImage = function(id, image) { - if (!defined(id)) { - throw new DeveloperError('id is required.'); - } - if (!defined(image)) { - throw new DeveloperError('image is required.'); - } - - if (this._imageId === id) { - return; - } - - this._imageIndex = -1; - this._imageSubRegion = undefined; - this._imageId = id; - this._image = image; - - if (defined(this._billboardCollection._textureAtlas)) { - this._loadImage(); - } + CylinderGeometryUpdater.prototype.isDestroyed = function() { + return false; }; /** - * Uses a sub-region of the image with the given id as the image for this billboard, - * measured in pixels from the bottom-left. - * - * @param {String} id The id of the image to use. - * @param {BoundingRectangle} subRegion The sub-region of the image. + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. * - * @exception {RuntimeError} image with id must be in the atlas + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ - Billboard.prototype.setImageSubRegion = function(id, subRegion) { - if (!defined(id)) { - throw new DeveloperError('id is required.'); - } - if (!defined(subRegion)) { - throw new DeveloperError('subRegion is required.'); - } - - if (this._imageId === id && BoundingRectangle.equals(this._imageSubRegion, subRegion)) { + CylinderGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; + + CylinderGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'cylinder')) { return; } - this._imageIndex = -1; - this._imageId = id; - this._imageSubRegion = BoundingRectangle.clone(subRegion); - - if (defined(this._billboardCollection._textureAtlas)) { - this._loadImage(); - } - }; + var cylinder = entity.cylinder; - Billboard.prototype._setTranslate = function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var translate = this._translate; - if (!Cartesian2.equals(translate, value)) { - Cartesian2.clone(value, translate); - makeDirty(this, PIXEL_OFFSET_INDEX); + if (!defined(cylinder)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; } - }; - Billboard.prototype._getActualPosition = function() { - return defined(this._clampedPosition) ? this._clampedPosition : this._actualPosition; - }; + var fillProperty = cylinder.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; - Billboard.prototype._setActualPosition = function(value) { - if (!(defined(this._clampedPosition))) { - Cartesian3.clone(value, this._actualPosition); + var outlineProperty = cylinder.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - makeDirty(this, POSITION_INDEX); - }; - var tempCartesian3 = new Cartesian4(); - Billboard._computeActualPosition = function(billboard, position, frameState, modelMatrix) { - if (defined(billboard._clampedPosition)) { - if (frameState.mode !== billboard._mode) { - billboard._updateClamping(); + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); } - return billboard._clampedPosition; - } else if (frameState.mode === SceneMode.SCENE3D) { - return position; + return; } - Matrix4.multiplyByPoint(modelMatrix, position, tempCartesian3); - return SceneTransforms.computeActualWgs84Position(frameState, tempCartesian3); - }; + var position = entity.position; + var length = cylinder.length; + var topRadius = cylinder.topRadius; + var bottomRadius = cylinder.bottomRadius; - var scratchCartesian3 = new Cartesian3(); + var show = cylinder.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(position) || !defined(length) || !defined(topRadius) || !defined(bottomRadius))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - // This function is basically a stripped-down JavaScript version of BillboardCollectionVS.glsl - Billboard._computeScreenSpacePosition = function(modelMatrix, position, eyeOffset, pixelOffset, scene, result) { - // Model to world coordinates - var positionWorld = Matrix4.multiplyByPoint(modelMatrix, position, scratchCartesian3); + var material = defaultValue(cylinder.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(cylinder.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(cylinder.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(cylinder.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(cylinder.distanceDisplayCondition, defaultDistanceDisplayCondition); - // World to window coordinates - var positionWC = SceneTransforms.wgs84WithEyeOffsetToWindowCoordinates(scene, positionWorld, eyeOffset, result); - if (!defined(positionWC)) { - return undefined; - } + var slices = cylinder.slices; + var outlineWidth = cylinder.outlineWidth; + var numberOfVerticalLines = cylinder.numberOfVerticalLines; - // Apply pixel offset - Cartesian2.add(positionWC, pixelOffset, positionWC); + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; - return positionWC; + if (!position.isConstant || // + !Property.isConstant(entity.orientation) || // + !length.isConstant || // + !topRadius.isConstant || // + !bottomRadius.isConstant || // + !Property.isConstant(slices) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(numberOfVerticalLines)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.length = length.getValue(Iso8601.MINIMUM_VALUE); + options.topRadius = topRadius.getValue(Iso8601.MINIMUM_VALUE); + options.bottomRadius = bottomRadius.getValue(Iso8601.MINIMUM_VALUE); + options.slices = defined(slices) ? slices.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } }; - var scratchPixelOffset = new Cartesian2(0.0, 0.0); - /** - * Computes the screen-space position of the billboard's origin, taking into account eye and pixel offsets. - * The screen space origin is the top, left corner of the canvas; <code>x</code> increases from - * left to right, and <code>y</code> increases from top to bottom. - * - * @param {Scene} scene The scene. - * @param {Cartesian2} [result] The object onto which to store the result. - * @returns {Cartesian2} The screen-space position of the billboard. - * - * @exception {DeveloperError} Billboard must be in a collection. + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. * - * @example - * console.log(b.computeScreenSpacePosition(scene).toString()); + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. * - * @see Billboard#eyeOffset - * @see Billboard#pixelOffset + * @exception {DeveloperError} This instance does not represent dynamic geometry. */ - Billboard.prototype.computeScreenSpacePosition = function(scene, result) { - var billboardCollection = this._billboardCollection; - if (!defined(result)) { - result = new Cartesian2(); + CylinderGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } - if (!defined(billboardCollection)) { - throw new DeveloperError('Billboard must be in a collection. Was it removed?'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); } - // pixel offset for screen space computation is the pixelOffset + screen space translate - Cartesian2.clone(this._pixelOffset, scratchPixelOffset); - Cartesian2.add(scratchPixelOffset, this._translate, scratchPixelOffset); - - var modelMatrix = billboardCollection.modelMatrix; - var position = this._position; - if (defined(this._clampedPosition)) { - position = this._clampedPosition; - if (scene.mode !== SceneMode.SCENE3D) { - // position needs to be in world coordinates - var projection = scene.mapProjection; - var ellipsoid = projection.ellipsoid; - var cart = projection.unproject(position, scratchCartographic); - position = ellipsoid.cartographicToCartesian(cart, scratchCartesian3); - modelMatrix = Matrix4.IDENTITY; - } - } - - var windowCoordinates = Billboard._computeScreenSpacePosition(modelMatrix, position, - this._eyeOffset, scratchPixelOffset, scene, result); - return windowCoordinates; + return new DynamicGeometryUpdater(primitives, this); }; /** - * Gets a billboard's screen space bounding box centered around screenSpacePosition. - * @param {Billboard} billboard The billboard to get the screen space bounding box for. - * @param {Cartesian2} screenSpacePosition The screen space center of the label. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The screen space bounding box. - * * @private */ - Billboard.getScreenSpaceBoundingBox = function(billboard, screenSpacePosition, result) { - var width = billboard.width; - var height = billboard.height; + function DynamicGeometryUpdater(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._primitive = undefined; + this._outlinePrimitive = undefined; - var scale = billboard.scale; - width *= scale; - height *= scale; + var geometryUpdater = this._geometryUpdater; + var entity = geometryUpdater._entity; + var cylinder = entity.cylinder; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(cylinder.show, time, true)) { + return; + } - var x = screenSpacePosition.x; - if (billboard.horizontalOrigin === HorizontalOrigin.RIGHT) { - x -= width; - } else if (billboard.horizontalOrigin === HorizontalOrigin.CENTER) { - x -= width * 0.5; + var options = this._options; + var modelMatrix = entity.computeModelMatrix(time); + var length = Property.getValueOrUndefined(cylinder.length, time); + var topRadius = Property.getValueOrUndefined(cylinder.topRadius, time); + var bottomRadius = Property.getValueOrUndefined(cylinder.bottomRadius, time); + if (!defined(modelMatrix) || !defined(length) || !defined(topRadius) || !defined(bottomRadius)) { + return; } - var y = screenSpacePosition.y; - if (billboard.verticalOrigin === VerticalOrigin.BOTTOM || billboard.verticalOrigin === VerticalOrigin.BASELINE) { - y -= height; - } else if (billboard.verticalOrigin === VerticalOrigin.CENTER) { - y -= height * 0.5; + options.length = length; + options.topRadius = topRadius; + options.bottomRadius = bottomRadius; + options.slices = Property.getValueOrUndefined(cylinder.slices, time); + options.numberOfVerticalLines = Property.getValueOrUndefined(cylinder.numberOfVerticalLines, time); + + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + + var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + + if (Property.getValueOrDefault(cylinder.fill, time, true)) { + var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + this._material = material; + + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new CylinderGeometry(options), + modelMatrix : modelMatrix, + attributes : { + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); } - if (!defined(result)) { - result = new BoundingRectangle(); + if (Property.getValueOrDefault(cylinder.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = Property.getValueOrClonedDefault(cylinder.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(cylinder.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; + + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new CylinderOutlineGeometry(options), + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); } + }; - result.x = x; - result.y = y; - result.width = width; - result.height = height; + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; - return result; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; }; - /** - * Determines if this billboard equals another billboard. Billboards are equal if all their properties - * are equal. Billboards in different collections can be equal. - * - * @param {Billboard} other The billboard to compare for equality. - * @returns {Boolean} <code>true</code> if the billboards are equal; otherwise, <code>false</code>. - */ - Billboard.prototype.equals = function(other) { - return this === other || - defined(other) && - this._id === other._id && - Cartesian3.equals(this._position, other._position) && - this._imageId === other._imageId && - this._show === other._show && - this._scale === other._scale && - this._verticalOrigin === other._verticalOrigin && - this._horizontalOrigin === other._horizontalOrigin && - this._heightReference === other._heightReference && - BoundingRectangle.equals(this._imageSubRegion, other._imageSubRegion) && - Color.equals(this._color, other._color) && - Cartesian2.equals(this._pixelOffset, other._pixelOffset) && - Cartesian2.equals(this._translate, other._translate) && - Cartesian3.equals(this._eyeOffset, other._eyeOffset) && - NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && - NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && - NearFarScalar.equals(this._pixelOffsetScaleByDistance, other._pixelOffsetScaleByDistance) && - DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && - this._disableDepthTestDistance === other._disableDepthTestDistance; + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); }; - Billboard.prototype._destroy = function() { - if (defined(this._customData)) { - this._billboardCollection._scene.globe._surface.removeTileCustomData(this._customData); - this._customData = undefined; - } + return CylinderGeometryUpdater; +}); - if (defined(this._removeCallbackFunc)) { - this._removeCallbackFunc(); - this._removeCallbackFunc = undefined; - } +define('Scene/ColorBlendMode',[ + '../Core/freezeObject', + '../Core/Math' + ], function( + freezeObject, + CesiumMath) { + 'use strict'; - this.image = undefined; - this._pickId = this._pickId && this._pickId.destroy(); - this._billboardCollection = undefined; + /** + * Defines different modes for blending between a target color and a primitive's source color. + * + * HIGHLIGHT multiplies the source color by the target color + * REPLACE replaces the source color with the target color + * MIX blends the source color and target color together + * + * @exports ColorBlendMode + * + * @see Model.colorBlendMode + */ + var ColorBlendMode = { + HIGHLIGHT : 0, + REPLACE : 1, + MIX : 2 }; /** - * A function that creates an image. - * @callback Billboard~CreateImageCallback - * @param {String} id The identifier of the image to load. - * @returns {Image|Canvas|Promise<Image|Canvas>} The image, or a promise that will resolve to an image. + * @private */ + ColorBlendMode.getColorBlend = function(colorBlendMode, colorBlendAmount) { + if (colorBlendMode === ColorBlendMode.HIGHLIGHT) { + return 0.0; + } else if (colorBlendMode === ColorBlendMode.REPLACE) { + return 1.0; + } else if (colorBlendMode === ColorBlendMode.MIX) { + // The value 0.0 is reserved for highlight, so clamp to just above 0.0. + return CesiumMath.clamp(colorBlendAmount, CesiumMath.EPSILON4, 1.0); + } + }; - return Billboard; + return freezeObject(ColorBlendMode); }); -define('Renderer/VertexArrayFacade',[ - '../Core/Check', - '../Core/ComponentDatatype', +define('DataSources/DataSourceClock',[ + '../Core/Clock', '../Core/defaultValue', '../Core/defined', - '../Core/destroyObject', + '../Core/defineProperties', '../Core/DeveloperError', - '../Core/Math', - './Buffer', - './BufferUsage', - './VertexArray' + '../Core/Event', + '../Core/JulianDate', + './createRawPropertyDescriptor' ], function( - Check, - ComponentDatatype, + Clock, defaultValue, defined, - destroyObject, + defineProperties, DeveloperError, - CesiumMath, - Buffer, - BufferUsage, - VertexArray) { + Event, + JulianDate, + createRawPropertyDescriptor) { 'use strict'; /** - * @private + * Represents desired clock settings for a particular {@link DataSource}. These settings may be applied + * to the {@link Clock} when the DataSource is loaded. + * + * @alias DataSourceClock + * @constructor */ - function VertexArrayFacade(context, attributes, sizeInVertices, instanced) { - Check.defined('context', context); - if (!attributes || (attributes.length === 0)) { - throw new DeveloperError('At least one attribute is required.'); - } - - var attrs = VertexArrayFacade._verifyAttributes(attributes); - sizeInVertices = defaultValue(sizeInVertices, 0); - var precreatedAttributes = []; - var attributesByUsage = {}; - var attributesForUsage; - var usage; - - // Bucket the attributes by usage. - var length = attrs.length; - for (var i = 0; i < length; ++i) { - var attribute = attrs[i]; - - // If the attribute already has a vertex buffer, we do not need - // to manage a vertex buffer or typed array for it. - if (attribute.vertexBuffer) { - precreatedAttributes.push(attribute); - continue; - } + function DataSourceClock() { + this._startTime = undefined; + this._stopTime = undefined; + this._currentTime = undefined; + this._clockRange = undefined; + this._clockStep = undefined; + this._multiplier = undefined; + this._definitionChanged = new Event(); + } - usage = attribute.usage; - attributesForUsage = attributesByUsage[usage]; - if (!defined(attributesForUsage)) { - attributesForUsage = attributesByUsage[usage] = []; + defineProperties(DataSourceClock.prototype, { + /** + * Gets the event that is raised whenever a new property is assigned. + * @memberof DataSourceClock.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } + }, - attributesForUsage.push(attribute); - } - - // A function to sort attributes by the size of their components. From left to right, a vertex - // stores floats, shorts, and then bytes. - function compare(left, right) { - return ComponentDatatype.getSizeInBytes(right.componentDatatype) - ComponentDatatype.getSizeInBytes(left.componentDatatype); - } + /** + * Gets or sets the desired start time of the clock. + * See {@link Clock#startTime}. + * @memberof DataSourceClock.prototype + * @type {JulianDate} + */ + startTime : createRawPropertyDescriptor('startTime'), - this._allBuffers = []; + /** + * Gets or sets the desired stop time of the clock. + * See {@link Clock#stopTime}. + * @memberof DataSourceClock.prototype + * @type {JulianDate} + */ + stopTime : createRawPropertyDescriptor('stopTime'), - for (usage in attributesByUsage) { - if (attributesByUsage.hasOwnProperty(usage)) { - attributesForUsage = attributesByUsage[usage]; + /** + * Gets or sets the desired current time when this data source is loaded. + * See {@link Clock#currentTime}. + * @memberof DataSourceClock.prototype + * @type {JulianDate} + */ + currentTime : createRawPropertyDescriptor('currentTime'), - attributesForUsage.sort(compare); - var vertexSizeInBytes = VertexArrayFacade._vertexSizeInBytes(attributesForUsage); + /** + * Gets or sets the desired clock range setting. + * See {@link Clock#clockRange}. + * @memberof DataSourceClock.prototype + * @type {ClockRange} + */ + clockRange : createRawPropertyDescriptor('clockRange'), - var bufferUsage = attributesForUsage[0].usage; + /** + * Gets or sets the desired clock step setting. + * See {@link Clock#clockStep}. + * @memberof DataSourceClock.prototype + * @type {ClockStep} + */ + clockStep : createRawPropertyDescriptor('clockStep'), - var buffer = { - vertexSizeInBytes : vertexSizeInBytes, - vertexBuffer : undefined, - usage : bufferUsage, - needsCommit : false, - arrayBuffer : undefined, - arrayViews : VertexArrayFacade._createArrayViews(attributesForUsage, vertexSizeInBytes) - }; + /** + * Gets or sets the desired clock multiplier. + * See {@link Clock#multiplier}. + * @memberof DataSourceClock.prototype + * @type {Number} + */ + multiplier : createRawPropertyDescriptor('multiplier') + }); - this._allBuffers.push(buffer); - } + /** + * Duplicates a DataSourceClock instance. + * + * @param {DataSourceClock} [result] The object onto which to store the result. + * @returns {DataSourceClock} The modified result parameter or a new instance if one was not provided. + */ + DataSourceClock.prototype.clone = function(result) { + if (!defined(result)) { + result = new DataSourceClock(); } + result.startTime = this.startTime; + result.stopTime = this.stopTime; + result.currentTime = this.currentTime; + result.clockRange = this.clockRange; + result.clockStep = this.clockStep; + result.multiplier = this.multiplier; + return result; + }; - this._size = 0; - this._instanced = defaultValue(instanced, false); + /** + * Returns true if this DataSourceClock is equivalent to the other + * + * @param {DataSourceClock} other The other DataSourceClock to compare to. + * @returns {Boolean} <code>true</code> if the DataSourceClocks are equal; otherwise, <code>false</code>. + */ + DataSourceClock.prototype.equals = function(other) { + return this === other || + defined(other) && + JulianDate.equals(this.startTime, other.startTime) && + JulianDate.equals(this.stopTime, other.stopTime) && + JulianDate.equals(this.currentTime, other.currentTime) && + this.clockRange === other.clockRange && + this.clockStep === other.clockStep && + this.multiplier === other.multiplier; + }; - this._precreated = precreatedAttributes; - this._context = context; + /** + * Assigns each unassigned property on this object to the value + * of the same property on the provided source object. + * + * @param {DataSourceClock} source The object to be merged into this object. + */ + DataSourceClock.prototype.merge = function(source) { + if (!defined(source)) { + throw new DeveloperError('source is required.'); + } + + this.startTime = defaultValue(this.startTime, source.startTime); + this.stopTime = defaultValue(this.stopTime, source.stopTime); + this.currentTime = defaultValue(this.currentTime, source.currentTime); + this.clockRange = defaultValue(this.clockRange, source.clockRange); + this.clockStep = defaultValue(this.clockStep, source.clockStep); + this.multiplier = defaultValue(this.multiplier, source.multiplier); + }; - this.writers = undefined; - this.va = undefined; + /** + * Gets the value of this clock instance as a {@link Clock} object. + * + * @returns {Clock} The modified result parameter or a new instance if one was not provided. + */ + DataSourceClock.prototype.getValue = function(result) { + if (!defined(result)) { + result = new Clock(); + } + result.startTime = defaultValue(this.startTime, result.startTime); + result.stopTime = defaultValue(this.stopTime, result.stopTime); + result.currentTime = defaultValue(this.currentTime, result.currentTime); + result.clockRange = defaultValue(this.clockRange, result.clockRange); + result.multiplier = defaultValue(this.multiplier, result.multiplier); + result.clockStep = defaultValue(this.clockStep, result.clockStep); + return result; + }; - this.resize(sizeInVertices); - } - VertexArrayFacade._verifyAttributes = function(attributes) { - var attrs = []; + return DataSourceClock; +}); - for ( var i = 0; i < attributes.length; ++i) { - var attribute = attributes[i]; +define('DataSources/GridMaterialProperty',[ + '../Core/Cartesian2', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Cartesian2, + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { + 'use strict'; - var attr = { - index : defaultValue(attribute.index, i), - enabled : defaultValue(attribute.enabled, true), - componentsPerAttribute : attribute.componentsPerAttribute, - componentDatatype : defaultValue(attribute.componentDatatype, ComponentDatatype.FLOAT), - normalize : defaultValue(attribute.normalize, false), + var defaultColor = Color.WHITE; + var defaultCellAlpha = 0.1; + var defaultLineCount = new Cartesian2(8, 8); + var defaultLineOffset = new Cartesian2(0, 0); + var defaultLineThickness = new Cartesian2(1, 1); - // There will be either a vertexBuffer or an [optional] usage. - vertexBuffer : attribute.vertexBuffer, - usage : defaultValue(attribute.usage, BufferUsage.STATIC_DRAW) - }; - attrs.push(attr); + /** + * A {@link MaterialProperty} that maps to grid {@link Material} uniforms. + * @alias GridMaterialProperty + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.color=Color.WHITE] A Property specifying the grid {@link Color}. + * @param {Property} [options.cellAlpha=0.1] A numeric Property specifying cell alpha values. + * @param {Property} [options.lineCount=new Cartesian2(8, 8)] A {@link Cartesian2} Property specifying the number of grid lines along each axis. + * @param {Property} [options.lineThickness=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the thickness of grid lines along each axis. + * @param {Property} [options.lineOffset=new Cartesian2(0.0, 0.0)] A {@link Cartesian2} Property specifying starting offset of grid lines along each axis. + * + * @constructor + */ + function GridMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if ((attr.componentsPerAttribute !== 1) && (attr.componentsPerAttribute !== 2) && (attr.componentsPerAttribute !== 3) && (attr.componentsPerAttribute !== 4)) { - throw new DeveloperError('attribute.componentsPerAttribute must be in the range [1, 4].'); - } + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._cellAlpha = undefined; + this._cellAlphaSubscription = undefined; + this._lineCount = undefined; + this._lineCountSubscription = undefined; + this._lineThickness = undefined; + this._lineThicknessSubscription = undefined; + this._lineOffset = undefined; + this._lineOffsetSubscription = undefined; - var datatype = attr.componentDatatype; - if (!ComponentDatatype.validate(datatype)) { - throw new DeveloperError('Attribute must have a valid componentDatatype or not specify it.'); - } + this.color = options.color; + this.cellAlpha = options.cellAlpha; + this.lineCount = options.lineCount; + this.lineThickness = options.lineThickness; + this.lineOffset = options.lineOffset; + } - if (!BufferUsage.validate(attr.usage)) { - throw new DeveloperError('Attribute must have a valid usage or not specify it.'); + defineProperties(GridMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof GridMaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._color) && + Property.isConstant(this._cellAlpha) && + Property.isConstant(this._lineCount) && + Property.isConstant(this._lineThickness) && + Property.isConstant(this._lineOffset); } - } - - // Verify all attribute names are unique. - var uniqueIndices = new Array(attrs.length); - for ( var j = 0; j < attrs.length; ++j) { - var currentAttr = attrs[j]; - var index = currentAttr.index; - if (uniqueIndices[index]) { - throw new DeveloperError('Index ' + index + ' is used by more than one attribute.'); + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof GridMaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - uniqueIndices[index] = true; - } - - return attrs; - }; - - VertexArrayFacade._vertexSizeInBytes = function(attributes) { - var sizeInBytes = 0; - - var length = attributes.length; - for ( var i = 0; i < length; ++i) { - var attribute = attributes[i]; - sizeInBytes += (attribute.componentsPerAttribute * ComponentDatatype.getSizeInBytes(attribute.componentDatatype)); - } - - var maxComponentSizeInBytes = (length > 0) ? ComponentDatatype.getSizeInBytes(attributes[0].componentDatatype) : 0; // Sorted by size - var remainder = (maxComponentSizeInBytes > 0) ? (sizeInBytes % maxComponentSizeInBytes) : 0; - var padding = (remainder === 0) ? 0 : (maxComponentSizeInBytes - remainder); - sizeInBytes += padding; + }, + /** + * Gets or sets the Property specifying the grid {@link Color}. + * @memberof GridMaterialProperty.prototype + * @type {Property} + * @default Color.WHITE + */ + color : createPropertyDescriptor('color'), + /** + * Gets or sets the numeric Property specifying cell alpha values. + * @memberof GridMaterialProperty.prototype + * @type {Property} + * @default 0.1 + */ + cellAlpha : createPropertyDescriptor('cellAlpha'), + /** + * Gets or sets the {@link Cartesian2} Property specifying the number of grid lines along each axis. + * @memberof GridMaterialProperty.prototype + * @type {Property} + * @default new Cartesian2(8.0, 8.0) + */ + lineCount : createPropertyDescriptor('lineCount'), + /** + * Gets or sets the {@link Cartesian2} Property specifying the thickness of grid lines along each axis. + * @memberof GridMaterialProperty.prototype + * @type {Property} + * @default new Cartesian2(1.0, 1.0) + */ + lineThickness : createPropertyDescriptor('lineThickness'), + /** + * Gets or sets the {@link Cartesian2} Property specifying the starting offset of grid lines along each axis. + * @memberof GridMaterialProperty.prototype + * @type {Property} + * @default new Cartesian2(0.0, 0.0) + */ + lineOffset : createPropertyDescriptor('lineOffset') + }); - return sizeInBytes; + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + GridMaterialProperty.prototype.getType = function(time) { + return 'Grid'; }; - VertexArrayFacade._createArrayViews = function(attributes, vertexSizeInBytes) { - var views = []; - var offsetInBytes = 0; - - var length = attributes.length; - for ( var i = 0; i < length; ++i) { - var attribute = attributes[i]; - var componentDatatype = attribute.componentDatatype; - - views.push({ - index : attribute.index, - enabled : attribute.enabled, - componentsPerAttribute : attribute.componentsPerAttribute, - componentDatatype : componentDatatype, - normalize : attribute.normalize, - - offsetInBytes : offsetInBytes, - vertexSizeInComponentType : vertexSizeInBytes / ComponentDatatype.getSizeInBytes(componentDatatype), - - view : undefined - }); - - offsetInBytes += (attribute.componentsPerAttribute * ComponentDatatype.getSizeInBytes(componentDatatype)); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + GridMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; } - - return views; + result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); + result.cellAlpha = Property.getValueOrDefault(this._cellAlpha, time, defaultCellAlpha); + result.lineCount = Property.getValueOrClonedDefault(this._lineCount, time, defaultLineCount, result.lineCount); + result.lineThickness = Property.getValueOrClonedDefault(this._lineThickness, time, defaultLineThickness, result.lineThickness); + result.lineOffset = Property.getValueOrClonedDefault(this._lineOffset, time, defaultLineOffset, result.lineOffset); + return result; }; /** - * Invalidates writers. Can't render again until commit is called. + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - VertexArrayFacade.prototype.resize = function(sizeInVertices) { - this._size = sizeInVertices; - - var allBuffers = this._allBuffers; - this.writers = []; - - for (var i = 0, len = allBuffers.length; i < len; ++i) { - var buffer = allBuffers[i]; - - VertexArrayFacade._resize(buffer, this._size); + GridMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof GridMaterialProperty && // + Property.equals(this._color, other._color) && // + Property.equals(this._cellAlpha, other._cellAlpha) && // + Property.equals(this._lineCount, other._lineCount) && // + Property.equals(this._lineThickness, other._lineThickness) && // + Property.equals(this._lineOffset, other._lineOffset)); + }; - // Reserving invalidates the writers, so if client's cache them, they need to invalidate their cache. - VertexArrayFacade._appendWriters(this.writers, buffer); - } + return GridMaterialProperty; +}); - // VAs are recreated next time commit is called. - destroyVA(this); - }; +define('DataSources/PolylineArrowMaterialProperty',[ + '../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Color, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { + 'use strict'; - VertexArrayFacade._resize = function(buffer, size) { - if (buffer.vertexSizeInBytes > 0) { - // Create larger array buffer - var arrayBuffer = new ArrayBuffer(size * buffer.vertexSizeInBytes); + /** + * A {@link MaterialProperty} that maps to PolylineArrow {@link Material} uniforms. + * + * @param {Property} [color=Color.WHITE] The {@link Color} Property to be used. + * + * @alias PolylineArrowMaterialProperty + * @constructor + */ + function PolylineArrowMaterialProperty(color) { + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this.color = color; + } - // Copy contents from previous array buffer - if (defined(buffer.arrayBuffer)) { - var destView = new Uint8Array(arrayBuffer); - var sourceView = new Uint8Array(buffer.arrayBuffer); - var sourceLength = sourceView.length; - for ( var j = 0; j < sourceLength; ++j) { - destView[j] = sourceView[j]; - } + defineProperties(PolylineArrowMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PolylineArrowMaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._color); } - - // Create typed views into the new array buffer - var views = buffer.arrayViews; - var length = views.length; - for ( var i = 0; i < length; ++i) { - var view = views[i]; - view.view = ComponentDatatype.createArrayBufferView(view.componentDatatype, arrayBuffer, view.offsetInBytes); + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PolylineArrowMaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } + }, + /** + * Gets or sets the {@link Color} {@link Property}. + * @memberof PolylineArrowMaterialProperty.prototype + * @type {Property} + * @default Color.WHITE + */ + color : createPropertyDescriptor('color') + }); - buffer.arrayBuffer = arrayBuffer; - } + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + PolylineArrowMaterialProperty.prototype.getType = function(time) { + return 'PolylineArrow'; }; - var createWriters = [ - // 1 component per attribute - function(buffer, view, vertexSizeInComponentType) { - return function(index, attribute) { - view[index * vertexSizeInComponentType] = attribute; - buffer.needsCommit = true; - }; - }, - - // 2 component per attribute - function(buffer, view, vertexSizeInComponentType) { - return function(index, component0, component1) { - var i = index * vertexSizeInComponentType; - view[i] = component0; - view[i + 1] = component1; - buffer.needsCommit = true; - }; - }, - - // 3 component per attribute - function(buffer, view, vertexSizeInComponentType) { - return function(index, component0, component1, component2) { - var i = index * vertexSizeInComponentType; - view[i] = component0; - view[i + 1] = component1; - view[i + 2] = component2; - buffer.needsCommit = true; - }; - }, - - // 4 component per attribute - function(buffer, view, vertexSizeInComponentType) { - return function(index, component0, component1, component2, component3) { - var i = index * vertexSizeInComponentType; - view[i] = component0; - view[i + 1] = component1; - view[i + 2] = component2; - view[i + 3] = component3; - buffer.needsCommit = true; - }; - }]; - - VertexArrayFacade._appendWriters = function(writers, buffer) { - var arrayViews = buffer.arrayViews; - var length = arrayViews.length; - for ( var i = 0; i < length; ++i) { - var arrayView = arrayViews[i]; - writers[arrayView.index] = createWriters[arrayView.componentsPerAttribute - 1](buffer, arrayView.view, arrayView.vertexSizeInComponentType); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PolylineArrowMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; } + result.color = Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color); + return result; }; - VertexArrayFacade.prototype.commit = function(indexBuffer) { - var recreateVA = false; + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PolylineArrowMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof PolylineArrowMaterialProperty && // + Property.equals(this._color, other._color)); + }; - var allBuffers = this._allBuffers; - var buffer; - var i; - var length; + return PolylineArrowMaterialProperty; +}); - for (i = 0, length = allBuffers.length; i < length; ++i) { - buffer = allBuffers[i]; - recreateVA = commit(this, buffer) || recreateVA; - } +define('DataSources/PolylineDashMaterialProperty',[ + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { + 'use strict'; - /////////////////////////////////////////////////////////////////////// + var defaultColor = Color.WHITE; + var defaultGapColor = Color.TRANSPARENT; + var defaultDashLength = 16.0; + var defaultDashPattern = 255.0; - if (recreateVA || !defined(this.va)) { - destroyVA(this); - var va = this.va = []; + /** + * A {@link MaterialProperty} that maps to polyline dash {@link Material} uniforms. + * @alias PolylineDashMaterialProperty + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. + * @param {Property} [options.gapColor=Color.TRANSPARENT] A Property specifying the {@link Color} of the gaps in the line. + * @param {Property} [options.dashLength=16.0] A numeric Property specifying the length of the dash pattern in pixel.s + * @param {Property} [options.dashPattern=255.0] A numeric Property specifying a 16 bit pattern for the dash + */ + function PolylineDashMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var numberOfVertexArrays = defined(indexBuffer) ? Math.ceil(this._size / (CesiumMath.SIXTY_FOUR_KILOBYTES - 1)) : 1; - for ( var k = 0; k < numberOfVertexArrays; ++k) { - var attributes = []; - for (i = 0, length = allBuffers.length; i < length; ++i) { - buffer = allBuffers[i]; - var offset = k * (buffer.vertexSizeInBytes * (CesiumMath.SIXTY_FOUR_KILOBYTES - 1)); - VertexArrayFacade._appendAttributes(attributes, buffer, offset, this._instanced); - } + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._gapColor = undefined; + this._gapColorSubscription = undefined; + this._dashLength = undefined; + this._dashLengthSubscription = undefined; + this._dashPattern = undefined; + this._dashPatternSubscription = undefined; - attributes = attributes.concat(this._precreated); + this.color = options.color; + this.gapColor = options.gapColor; + this.dashLength = options.dashLength; + this.dashPattern = options.dashPattern; + } - va.push({ - va : new VertexArray({ - context : this._context, - attributes : attributes, - indexBuffer : indexBuffer - }), - indicesCount : 1.5 * ((k !== (numberOfVertexArrays - 1)) ? (CesiumMath.SIXTY_FOUR_KILOBYTES - 1) : (this._size % (CesiumMath.SIXTY_FOUR_KILOBYTES - 1))) - // TODO: not hardcode 1.5, this assumes 6 indices per 4 vertices (as for Billboard quads). - }); + defineProperties(PolylineDashMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PolylineDashMaterialProperty.prototype + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return (Property.isConstant(this._color) && + Property.isConstant(this._gapColor) && + Property.isConstant(this._dashLength) && + Property.isConstant(this._dashPattern)); } - } - }; - - function commit(vertexArrayFacade, buffer) { - if (buffer.needsCommit && (buffer.vertexSizeInBytes > 0)) { - buffer.needsCommit = false; - - var vertexBuffer = buffer.vertexBuffer; - var vertexBufferSizeInBytes = vertexArrayFacade._size * buffer.vertexSizeInBytes; - var vertexBufferDefined = defined(vertexBuffer); - if (!vertexBufferDefined || (vertexBuffer.sizeInBytes < vertexBufferSizeInBytes)) { - if (vertexBufferDefined) { - vertexBuffer.destroy(); - } - buffer.vertexBuffer = Buffer.createVertexBuffer({ - context : vertexArrayFacade._context, - typedArray : buffer.arrayBuffer, - usage : buffer.usage - }); - buffer.vertexBuffer.vertexArrayDestroyable = false; - - return true; // Created new vertex buffer + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PolylineDashMaterialProperty.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } + }, + /** + * Gets or sets the Property specifying the {@link Color} of the line. + * @memberof PolylineDashMaterialProperty.prototype + * @type {Property} + */ + color : createPropertyDescriptor('color'), + /** + * Gets or sets the Property specifying the {@link Color} of the gaps in the line. + * @memberof PolylineDashMaterialProperty.prototype + * @type {Property} + */ + gapColor : createPropertyDescriptor('gapColor'), + /** + * Gets or sets the numeric Property specifying the length of a dash cycle + * @memberof PolylineDashMaterialProperty.prototype + * @type {Property} + */ + dashLength : createPropertyDescriptor('dashLength'), + /** + * Gets or sets the numeric Property specifying a dash pattern + * @memberof PolylineDashMaterialProperty.prototype + * @type {Property} + */ + dashPattern : createPropertyDescriptor('dashPattern') + }); - buffer.vertexBuffer.copyFromArrayView(buffer.arrayBuffer); - } - - return false; // Did not create new vertex buffer - } - - VertexArrayFacade._appendAttributes = function(attributes, buffer, vertexBufferOffset, instanced) { - var arrayViews = buffer.arrayViews; - var length = arrayViews.length; - for ( var i = 0; i < length; ++i) { - var view = arrayViews[i]; - - attributes.push({ - index : view.index, - enabled : view.enabled, - componentsPerAttribute : view.componentsPerAttribute, - componentDatatype : view.componentDatatype, - normalize : view.normalize, - vertexBuffer : buffer.vertexBuffer, - offsetInBytes : vertexBufferOffset + view.offsetInBytes, - strideInBytes : buffer.vertexSizeInBytes, - instanceDivisor : instanced ? 1 : 0 - }); - } + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + PolylineDashMaterialProperty.prototype.getType = function(time) { + return 'PolylineDash'; }; - VertexArrayFacade.prototype.subCommit = function(offsetInVertices, lengthInVertices) { - if (offsetInVertices < 0 || offsetInVertices >= this._size) { - throw new DeveloperError('offsetInVertices must be greater than or equal to zero and less than the vertex array size.'); - } - if (offsetInVertices + lengthInVertices > this._size) { - throw new DeveloperError('offsetInVertices + lengthInVertices cannot exceed the vertex array size.'); - } - - var allBuffers = this._allBuffers; - for (var i = 0, len = allBuffers.length; i < len; ++i) { - subCommit(allBuffers[i], offsetInVertices, lengthInVertices); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PolylineDashMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; } + result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); + result.gapColor = Property.getValueOrClonedDefault(this._gapColor, time, defaultGapColor, result.gapColor); + result.dashLength = Property.getValueOrDefault(this._dashLength, time, defaultDashLength, result.dashLength); + result.dashPattern = Property.getValueOrDefault(this._dashPattern, time, defaultDashPattern, result.dashPattern); + return result; }; - function subCommit(buffer, offsetInVertices, lengthInVertices) { - if (buffer.needsCommit && (buffer.vertexSizeInBytes > 0)) { - var byteOffset = buffer.vertexSizeInBytes * offsetInVertices; - var byteLength = buffer.vertexSizeInBytes * lengthInVertices; + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PolylineDashMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof PolylineDashMaterialProperty && + Property.equals(this._color, other._color) && + Property.equals(this._gapColor, other._gapColor) && + Property.equals(this._dashLength, other._dashLength) && + Property.equals(this._dashPattern, other._dashPattern) + ); + }; - // PERFORMANCE_IDEA: If we want to get really crazy, we could consider updating - // individual attributes instead of the entire (sub-)vertex. - // - // PERFORMANCE_IDEA: Does creating the typed view add too much GC overhead? - buffer.vertexBuffer.copyFromArrayView(new Uint8Array(buffer.arrayBuffer, byteOffset, byteLength), byteOffset); - } - } + return PolylineDashMaterialProperty; +}); - VertexArrayFacade.prototype.endSubCommits = function() { - var allBuffers = this._allBuffers; +define('DataSources/PolylineGlowMaterialProperty',[ + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' + ], function( + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { + 'use strict'; - for (var i = 0, len = allBuffers.length; i < len; ++i) { - allBuffers[i].needsCommit = false; - } - }; + var defaultColor = Color.WHITE; + var defaultGlowPower = 0.25; - function destroyVA(vertexArrayFacade) { - var va = vertexArrayFacade.va; - if (!defined(va)) { - return; - } + /** + * A {@link MaterialProperty} that maps to polyline glow {@link Material} uniforms. + * @alias PolylineGlowMaterialProperty + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. + * @param {Property} [options.glowPower=0.25] A numeric Property specifying the strength of the glow, as a percentage of the total line width. + */ + function PolylineGlowMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var length = va.length; - for (var i = 0; i < length; ++i) { - va[i].va.destroy(); - } + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._glowPower = undefined; + this._glowPowerSubscription = undefined; - vertexArrayFacade.va = undefined; + this.color = options.color; + this.glowPower = options.glowPower; } - VertexArrayFacade.prototype.isDestroyed = function() { - return false; + defineProperties(PolylineGlowMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PolylineGlowMaterialProperty.prototype + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._color) && Property.isConstant(this._glow); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PolylineGlowMaterialProperty.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets or sets the Property specifying the {@link Color} of the line. + * @memberof PolylineGlowMaterialProperty.prototype + * @type {Property} + */ + color : createPropertyDescriptor('color'), + /** + * Gets or sets the numeric Property specifying the strength of the glow, as a percentage of the total line width (less than 1.0). + * @memberof PolylineGlowMaterialProperty.prototype + * @type {Property} + */ + glowPower : createPropertyDescriptor('glowPower') + }); + + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + PolylineGlowMaterialProperty.prototype.getType = function(time) { + return 'PolylineGlow'; }; - VertexArrayFacade.prototype.destroy = function() { - var allBuffers = this._allBuffers; - for (var i = 0, len = allBuffers.length; i < len; ++i) { - var buffer = allBuffers[i]; - buffer.vertexBuffer = buffer.vertexBuffer && buffer.vertexBuffer.destroy(); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PolylineGlowMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; } + result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); + result.glowPower = Property.getValueOrDefault(this._glowPower, time, defaultGlowPower, result.glowPower); + return result; + }; - destroyVA(this); - - return destroyObject(this); + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PolylineGlowMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof PolylineGlowMaterialProperty && // + Property.equals(this._color, other._color) && + Property.equals(this._glowPower, other._glowPower)); }; - return VertexArrayFacade; + return PolylineGlowMaterialProperty; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/BillboardCollectionFS',[],function() { - 'use strict'; - return "uniform sampler2D u_atlas;\n\ -varying vec2 v_textureCoordinates;\n\ -#ifdef RENDER_FOR_PICK\n\ -varying vec4 v_pickColor;\n\ -#else\n\ -varying vec4 v_color;\n\ -#endif\n\ -void main()\n\ -{\n\ -#ifdef RENDER_FOR_PICK\n\ -vec4 vertexColor = vec4(1.0, 1.0, 1.0, 1.0);\n\ -#else\n\ -vec4 vertexColor = v_color;\n\ -#endif\n\ -vec4 color = texture2D(u_atlas, v_textureCoordinates) * vertexColor;\n\ -#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\n\ -if (color.a < 0.005)\n\ -{\n\ -discard;\n\ -}\n\ -#else\n\ -#ifdef OPAQUE\n\ -if (color.a < 0.995)\n\ -{\n\ -discard;\n\ -}\n\ -#else\n\ -if (color.a >= 0.995)\n\ -{\n\ -discard;\n\ -}\n\ -#endif\n\ -#endif\n\ -#ifdef RENDER_FOR_PICK\n\ -gl_FragColor = v_pickColor;\n\ -#else\n\ -gl_FragColor = color;\n\ -#endif\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/BillboardCollectionVS',[],function() { - 'use strict'; - return "#ifdef INSTANCED\n\ -attribute vec2 direction;\n\ -#endif\n\ -attribute vec4 positionHighAndScale;\n\ -attribute vec4 positionLowAndRotation;\n\ -attribute vec4 compressedAttribute0;\n\ -attribute vec4 compressedAttribute1;\n\ -attribute vec4 compressedAttribute2;\n\ -attribute vec4 eyeOffset;\n\ -attribute vec4 scaleByDistance;\n\ -attribute vec4 pixelOffsetScaleByDistance;\n\ -attribute vec3 distanceDisplayConditionAndDisableDepth;\n\ -varying vec2 v_textureCoordinates;\n\ -#ifdef RENDER_FOR_PICK\n\ -varying vec4 v_pickColor;\n\ -#else\n\ -varying vec4 v_color;\n\ -#endif\n\ -const float UPPER_BOUND = 32768.0;\n\ -const float SHIFT_LEFT16 = 65536.0;\n\ -const float SHIFT_LEFT8 = 256.0;\n\ -const float SHIFT_LEFT7 = 128.0;\n\ -const float SHIFT_LEFT5 = 32.0;\n\ -const float SHIFT_LEFT3 = 8.0;\n\ -const float SHIFT_LEFT2 = 4.0;\n\ -const float SHIFT_LEFT1 = 2.0;\n\ -const float SHIFT_RIGHT8 = 1.0 / 256.0;\n\ -const float SHIFT_RIGHT7 = 1.0 / 128.0;\n\ -const float SHIFT_RIGHT5 = 1.0 / 32.0;\n\ -const float SHIFT_RIGHT3 = 1.0 / 8.0;\n\ -const float SHIFT_RIGHT2 = 1.0 / 4.0;\n\ -const float SHIFT_RIGHT1 = 1.0 / 2.0;\n\ -vec4 computePositionWindowCoordinates(vec4 positionEC, vec2 imageSize, float scale, vec2 direction, vec2 origin, vec2 translate, vec2 pixelOffset, vec3 alignedAxis, bool validAlignedAxis, float rotation, bool sizeInMeters)\n\ -{\n\ -vec2 halfSize = imageSize * scale * czm_resolutionScale * 0.5;\n\ -halfSize *= ((direction * 2.0) - 1.0);\n\ -vec2 originTranslate = origin * abs(halfSize);\n\ -#if defined(ROTATION) || defined(ALIGNED_AXIS)\n\ -if (validAlignedAxis || rotation != 0.0)\n\ -{\n\ -float angle = rotation;\n\ -if (validAlignedAxis)\n\ -{\n\ -vec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0);\n\ -angle += sign(-projectedAlignedAxis.x) * acos( sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) /\n\ -(projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y) );\n\ -}\n\ -float cosTheta = cos(angle);\n\ -float sinTheta = sin(angle);\n\ -mat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta);\n\ -halfSize = rotationMatrix * halfSize;\n\ -}\n\ -#endif\n\ -if (sizeInMeters)\n\ -{\n\ -positionEC.xy += halfSize;\n\ -}\n\ -vec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\n\ -if (sizeInMeters)\n\ -{\n\ -originTranslate /= czm_metersPerPixel(positionEC);\n\ -}\n\ -positionWC.xy += originTranslate;\n\ -if (!sizeInMeters)\n\ -{\n\ -positionWC.xy += halfSize;\n\ -}\n\ -positionWC.xy += translate;\n\ -positionWC.xy += (pixelOffset * czm_resolutionScale);\n\ -return positionWC;\n\ -}\n\ -void main()\n\ -{\n\ -vec3 positionHigh = positionHighAndScale.xyz;\n\ -vec3 positionLow = positionLowAndRotation.xyz;\n\ -float scale = positionHighAndScale.w;\n\ -#if defined(ROTATION) || defined(ALIGNED_AXIS)\n\ -float rotation = positionLowAndRotation.w;\n\ -#else\n\ -float rotation = 0.0;\n\ -#endif\n\ -float compressed = compressedAttribute0.x;\n\ -vec2 pixelOffset;\n\ -pixelOffset.x = floor(compressed * SHIFT_RIGHT7);\n\ -compressed -= pixelOffset.x * SHIFT_LEFT7;\n\ -pixelOffset.x -= UPPER_BOUND;\n\ -vec2 origin;\n\ -origin.x = floor(compressed * SHIFT_RIGHT5);\n\ -compressed -= origin.x * SHIFT_LEFT5;\n\ -origin.y = floor(compressed * SHIFT_RIGHT3);\n\ -compressed -= origin.y * SHIFT_LEFT3;\n\ -origin -= vec2(1.0);\n\ -float show = floor(compressed * SHIFT_RIGHT2);\n\ -compressed -= show * SHIFT_LEFT2;\n\ -#ifdef INSTANCED\n\ -vec2 textureCoordinatesBottomLeft = czm_decompressTextureCoordinates(compressedAttribute0.w);\n\ -vec2 textureCoordinatesRange = czm_decompressTextureCoordinates(eyeOffset.w);\n\ -vec2 textureCoordinates = textureCoordinatesBottomLeft + direction * textureCoordinatesRange;\n\ -#else\n\ -vec2 direction;\n\ -direction.x = floor(compressed * SHIFT_RIGHT1);\n\ -direction.y = compressed - direction.x * SHIFT_LEFT1;\n\ -vec2 textureCoordinates = czm_decompressTextureCoordinates(compressedAttribute0.w);\n\ -#endif\n\ -float temp = compressedAttribute0.y * SHIFT_RIGHT8;\n\ -pixelOffset.y = -(floor(temp) - UPPER_BOUND);\n\ -vec2 translate;\n\ -translate.y = (temp - floor(temp)) * SHIFT_LEFT16;\n\ -temp = compressedAttribute0.z * SHIFT_RIGHT8;\n\ -translate.x = floor(temp) - UPPER_BOUND;\n\ -translate.y += (temp - floor(temp)) * SHIFT_LEFT8;\n\ -translate.y -= UPPER_BOUND;\n\ -temp = compressedAttribute1.x * SHIFT_RIGHT8;\n\ -vec2 imageSize = vec2(floor(temp), compressedAttribute2.w);\n\ -#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ -vec4 translucencyByDistance;\n\ -translucencyByDistance.x = compressedAttribute1.z;\n\ -translucencyByDistance.z = compressedAttribute1.w;\n\ -translucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ -temp = compressedAttribute1.y * SHIFT_RIGHT8;\n\ -translucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ -#endif\n\ -#ifdef ALIGNED_AXIS\n\ -vec3 alignedAxis = czm_octDecode(floor(compressedAttribute1.y * SHIFT_RIGHT8));\n\ -temp = compressedAttribute2.z * SHIFT_RIGHT5;\n\ -bool validAlignedAxis = (temp - floor(temp)) * SHIFT_LEFT1 > 0.0;\n\ -#else\n\ -vec3 alignedAxis = vec3(0.0);\n\ -bool validAlignedAxis = false;\n\ -#endif\n\ -#ifdef RENDER_FOR_PICK\n\ -temp = compressedAttribute2.y;\n\ -#else\n\ -temp = compressedAttribute2.x;\n\ -#endif\n\ -vec4 color;\n\ -temp = temp * SHIFT_RIGHT8;\n\ -color.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -temp = floor(temp) * SHIFT_RIGHT8;\n\ -color.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -color.r = floor(temp);\n\ -temp = compressedAttribute2.z * SHIFT_RIGHT8;\n\ -bool sizeInMeters = floor((temp - floor(temp)) * SHIFT_LEFT7) > 0.0;\n\ -temp = floor(temp) * SHIFT_RIGHT8;\n\ -#ifdef RENDER_FOR_PICK\n\ -color.a = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -vec4 pickColor = color / 255.0;\n\ -#else\n\ -color.a = floor(temp);\n\ -color /= 255.0;\n\ -#endif\n\ -vec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\n\ -vec4 positionEC = czm_modelViewRelativeToEye * p;\n\ -positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz);\n\ -positionEC.xyz *= show;\n\ -#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(EYE_DISTANCE_PIXEL_OFFSET) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\n\ -float lengthSq;\n\ -if (czm_sceneMode == czm_sceneMode2D)\n\ -{\n\ -lengthSq = czm_eyeHeight2D.y;\n\ -}\n\ -else\n\ -{\n\ -lengthSq = dot(positionEC.xyz, positionEC.xyz);\n\ -}\n\ -#endif\n\ -#ifdef EYE_DISTANCE_SCALING\n\ -float distanceScale = czm_nearFarScalar(scaleByDistance, lengthSq);\n\ -scale *= distanceScale;\n\ -translate *= distanceScale;\n\ -if (scale == 0.0)\n\ -{\n\ -positionEC.xyz = vec3(0.0);\n\ -}\n\ -#endif\n\ -float translucency = 1.0;\n\ -#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ -translucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\n\ -if (translucency == 0.0)\n\ -{\n\ -positionEC.xyz = vec3(0.0);\n\ -}\n\ -#endif\n\ -#ifdef EYE_DISTANCE_PIXEL_OFFSET\n\ -float pixelOffsetScale = czm_nearFarScalar(pixelOffsetScaleByDistance, lengthSq);\n\ -pixelOffset *= pixelOffsetScale;\n\ -#endif\n\ -#ifdef DISTANCE_DISPLAY_CONDITION\n\ -float nearSq = distanceDisplayConditionAndDisableDepth.x;\n\ -float farSq = distanceDisplayConditionAndDisableDepth.y;\n\ -if (lengthSq < nearSq || lengthSq > farSq)\n\ -{\n\ -positionEC.xyz = vec3(0.0);\n\ -}\n\ -#endif\n\ -vec4 positionWC = computePositionWindowCoordinates(positionEC, imageSize, scale, direction, origin, translate, pixelOffset, alignedAxis, validAlignedAxis, rotation, sizeInMeters);\n\ -gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\n\ -v_textureCoordinates = textureCoordinates;\n\ -#ifdef DISABLE_DEPTH_DISTANCE\n\ -float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\n\ -if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n\ -{\n\ -disableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n\ -}\n\ -if (disableDepthTestDistance != 0.0)\n\ -{\n\ -float zclip = gl_Position.z / gl_Position.w;\n\ -bool clipped = (zclip < -1.0 || zclip > 1.0);\n\ -if (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n\ -{\n\ -gl_Position.z = -gl_Position.w;\n\ -}\n\ -}\n\ -#endif\n\ -#ifdef RENDER_FOR_PICK\n\ -v_pickColor = pickColor;\n\ -#else\n\ -v_color = color;\n\ -v_color.a *= translucency;\n\ -#endif\n\ -}\n\ -"; -}); -define('Scene/BlendOption',[ - '../Core/freezeObject' +define('DataSources/PolylineOutlineMaterialProperty',[ + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property' ], function( - freezeObject) { + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property) { 'use strict'; + var defaultColor = Color.WHITE; + var defaultOutlineColor = Color.BLACK; + var defaultOutlineWidth = 1.0; + /** - * Determines how opaque and translucent parts of billboards, points, and labels are blended with the scene. + * A {@link MaterialProperty} that maps to polyline outline {@link Material} uniforms. + * @alias PolylineOutlineMaterialProperty + * @constructor * - * @exports BlendOption + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. + * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. + * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline, in pixels. */ - var BlendOption = { + function PolylineOutlineMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._definitionChanged = new Event(); + this._color = undefined; + this._colorSubscription = undefined; + this._outlineColor = undefined; + this._outlineColorSubscription = undefined; + this._outlineWidth = undefined; + this._outlineWidthSubscription = undefined; + + this.color = options.color; + this.outlineColor = options.outlineColor; + this.outlineWidth = options.outlineWidth; + } + + defineProperties(PolylineOutlineMaterialProperty.prototype, { /** - * The billboards, points, or labels in the collection are completely opaque. - * @type {Number} - * @constant + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof PolylineOutlineMaterialProperty.prototype + * + * @type {Boolean} + * @readonly */ - OPAQUE : 0, - + isConstant : { + get : function() { + return Property.isConstant(this._color) && Property.isConstant(this._outlineColor) && Property.isConstant(this._outlineWidth); + } + }, /** - * The billboards, points, or labels in the collection are completely translucent. - * @type {Number} - * @constant + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof PolylineOutlineMaterialProperty.prototype + * + * @type {Event} + * @readonly */ - TRANSLUCENT : 1, - + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** - * The billboards, points, or labels in the collection are both opaque and translucent. - * @type {Number} - * @constant + * Gets or sets the Property specifying the {@link Color} of the line. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Property} + * @default Color.WHITE */ - OPAQUE_AND_TRANSLUCENT : 2 + color : createPropertyDescriptor('color'), + /** + * Gets or sets the Property specifying the {@link Color} of the outline. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Property} + * @default Color.BLACK + */ + outlineColor : createPropertyDescriptor('outlineColor'), + /** + * Gets or sets the numeric Property specifying the width of the outline. + * @memberof PolylineOutlineMaterialProperty.prototype + * @type {Property} + * @default 1.0 + */ + outlineWidth : createPropertyDescriptor('outlineWidth') + }); + + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + PolylineOutlineMaterialProperty.prototype.getType = function(time) { + return 'PolylineOutline'; }; - return freezeObject(BlendOption); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PolylineOutlineMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); + result.outlineColor = Property.getValueOrClonedDefault(this._outlineColor, time, defaultOutlineColor, result.outlineColor); + result.outlineWidth = Property.getValueOrDefault(this._outlineWidth, time, defaultOutlineWidth); + return result; + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PolylineOutlineMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof PolylineOutlineMaterialProperty && // + Property.equals(this._color, other._color) && // + Property.equals(this._outlineColor, other._outlineColor) && // + Property.equals(this._outlineWidth, other._outlineWidth)); + }; + + return PolylineOutlineMaterialProperty; }); -define('Renderer/Framebuffer',[ - '../Core/Check', +define('DataSources/PositionPropertyArray',[ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/PixelFormat', - './ContextLimits' + '../Core/Event', + '../Core/EventHelper', + '../Core/ReferenceFrame', + './Property' ], function( - Check, defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - PixelFormat, - ContextLimits) { + Event, + EventHelper, + ReferenceFrame, + Property) { 'use strict'; - function attachTexture(framebuffer, attachment, texture) { - var gl = framebuffer._gl; - gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, texture._target, texture._texture, 0); + /** + * A {@link PositionProperty} whose value is an array whose items are the computed value + * of other PositionProperty instances. + * + * @alias PositionPropertyArray + * @constructor + * + * @param {Property[]} [value] An array of Property instances. + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + */ + function PositionPropertyArray(value, referenceFrame) { + this._value = undefined; + this._definitionChanged = new Event(); + this._eventHelper = new EventHelper(); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + this.setValue(value); } - function attachRenderbuffer(framebuffer, attachment, renderbuffer) { - var gl = framebuffer._gl; - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbuffer._getRenderbuffer()); - } + defineProperties(PositionPropertyArray.prototype, { + /** + * Gets a value indicating if this property is constant. This property + * is considered constant if all property items in the array are constant. + * @memberof PositionPropertyArray.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + var value = this._value; + if (!defined(value)) { + return true; + } + + var length = value.length; + for (var i = 0; i < length; i++) { + if (!Property.isConstant(value[i])) { + return false; + } + } + return true; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value or one of the properties in the array also changes. + * @memberof PositionPropertyArray.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof PositionPropertyArray.prototype + * @type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; + } + } + }); /** - * Creates a framebuffer with optional initial color, depth, and stencil attachments. - * Framebuffers are used for render-to-texture effects; they allow us to render to - * textures in one pass, and read from it in a later pass. + * Gets the value of the property. * - * @param {Object} options The initial framebuffer attachments as shown in the example below. <code>context</code> is required. The possible properties are <code>colorTextures</code>, <code>colorRenderbuffers</code>, <code>depthTexture</code>, <code>depthRenderbuffer</code>, <code>stencilRenderbuffer</code>, <code>depthStencilTexture</code>, and <code>depthStencilRenderbuffer</code>. + * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. + * @param {Cartesian3[]} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3[]} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PositionPropertyArray.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; + + /** + * Gets the value of the property at the provided time and in the provided reference frame. * - * @exception {DeveloperError} Cannot have both color texture and color renderbuffer attachments. - * @exception {DeveloperError} Cannot have both a depth texture and depth renderbuffer attachment. - * @exception {DeveloperError} Cannot have both a depth-stencil texture and depth-stencil renderbuffer attachment. - * @exception {DeveloperError} Cannot have both a depth and depth-stencil renderbuffer. - * @exception {DeveloperError} Cannot have both a stencil and depth-stencil renderbuffer. - * @exception {DeveloperError} Cannot have both a depth and stencil renderbuffer. - * @exception {DeveloperError} The color-texture pixel-format must be a color format. - * @exception {DeveloperError} The depth-texture pixel-format must be DEPTH_COMPONENT. - * @exception {DeveloperError} The depth-stencil-texture pixel-format must be DEPTH_STENCIL. - * @exception {DeveloperError} The number of color attachments exceeds the number supported. + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + PositionPropertyArray.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + + var value = this._value; + if (!defined(value)) { + return undefined; + } + + var length = value.length; + if (!defined(result)) { + result = new Array(length); + } + var i = 0; + var x = 0; + while (i < length) { + var property = value[i]; + var itemValue = property.getValueInReferenceFrame(time, referenceFrame, result[i]); + if (defined(itemValue)) { + result[x] = itemValue; + x++; + } + i++; + } + result.length = x; + return result; + }; + + /** + * Sets the value of the property. * - * @example - * // Create a framebuffer with color and depth texture attachments. - * var width = context.canvas.clientWidth; - * var height = context.canvas.clientHeight; - * var framebuffer = new Framebuffer({ - * context : context, - * colorTextures : [new Texture({ - * context : context, - * width : width, - * height : height, - * pixelFormat : PixelFormat.RGBA - * })], - * depthTexture : new Texture({ - * context : context, - * width : width, - * height : height, - * pixelFormat : PixelFormat.DEPTH_COMPONENT, - * pixelDatatype : PixelDatatype.UNSIGNED_SHORT - * }) - * }); + * @param {Property[]} value An array of Property instances. + */ + PositionPropertyArray.prototype.setValue = function(value) { + var eventHelper = this._eventHelper; + eventHelper.removeAll(); + + if (defined(value)) { + this._value = value.slice(); + var length = value.length; + for (var i = 0; i < length; i++) { + var property = value[i]; + if (defined(property)) { + eventHelper.add(property.definitionChanged, PositionPropertyArray.prototype._raiseDefinitionChanged, this); + } + } + } else { + this._value = undefined; + } + this._definitionChanged.raiseEvent(this); + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @private + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - function Framebuffer(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + PositionPropertyArray.prototype.equals = function(other) { + return this === other || // + (other instanceof PositionPropertyArray && // + this._referenceFrame === other._referenceFrame && // + Property.arrayEquals(this._value, other._value)); + }; - Check.defined('options.context', options.context); - - var gl = options.context._gl; - var maximumColorAttachments = ContextLimits.maximumColorAttachments; + PositionPropertyArray.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; - this._gl = gl; - this._framebuffer = gl.createFramebuffer(); + return PositionPropertyArray; +}); - this._colorTextures = []; - this._colorRenderbuffers = []; - this._activeColorAttachments = []; +define('DataSources/PropertyArray',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/EventHelper', + './Property' + ], function( + defined, + defineProperties, + DeveloperError, + Event, + EventHelper, + Property) { + 'use strict'; - this._depthTexture = undefined; - this._depthRenderbuffer = undefined; - this._stencilRenderbuffer = undefined; - this._depthStencilTexture = undefined; - this._depthStencilRenderbuffer = undefined; + /** + * A {@link Property} whose value is an array whose items are the computed value + * of other property instances. + * + * @alias PropertyArray + * @constructor + * + * @param {Property[]} [value] An array of Property instances. + */ + function PropertyArray(value) { + this._value = undefined; + this._definitionChanged = new Event(); + this._eventHelper = new EventHelper(); + this.setValue(value); + } + defineProperties(PropertyArray.prototype, { /** - * When true, the framebuffer owns its attachments so they will be destroyed when - * {@link Framebuffer#destroy} is called or when a new attachment is assigned - * to an attachment point. + * Gets a value indicating if this property is constant. This property + * is considered constant if all property items in the array are constant. + * @memberof PropertyArray.prototype * * @type {Boolean} - * @default true + * @readonly + */ + isConstant : { + get : function() { + var value = this._value; + if (!defined(value)) { + return true; + } + var length = value.length; + for (var i = 0; i < length; i++) { + if (!Property.isConstant(value[i])) { + return false; + } + } + return true; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value or one of the properties in the array also changes. + * @memberof PropertyArray.prototype * - * @see Framebuffer#destroy + * @type {Event} + * @readonly */ - this.destroyAttachments = defaultValue(options.destroyAttachments, true); - - // Throw if a texture and renderbuffer are attached to the same point. This won't - // cause a WebGL error (because only one will be attached), but is likely a developer error. - - if (defined(options.colorTextures) && defined(options.colorRenderbuffers)) { - throw new DeveloperError('Cannot have both color texture and color renderbuffer attachments.'); - } - if (defined(options.depthTexture) && defined(options.depthRenderbuffer)) { - throw new DeveloperError('Cannot have both a depth texture and depth renderbuffer attachment.'); + definitionChanged : { + get : function() { + return this._definitionChanged; + } } - if (defined(options.depthStencilTexture) && defined(options.depthStencilRenderbuffer)) { - throw new DeveloperError('Cannot have both a depth-stencil texture and depth-stencil renderbuffer attachment.'); + }); + + /** + * Gets the value of the property. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object[]} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object[]} The modified result parameter, which is an array of values produced by evaluating each of the contained properties at the given time or a new instance if the result parameter was not supplied. + */ + PropertyArray.prototype.getValue = function(time, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - // Avoid errors defined in Section 6.5 of the WebGL spec - var depthAttachment = (defined(options.depthTexture) || defined(options.depthRenderbuffer)); - var depthStencilAttachment = (defined(options.depthStencilTexture) || defined(options.depthStencilRenderbuffer)); + var value = this._value; + if (!defined(value)) { + return undefined; + } - if (depthAttachment && depthStencilAttachment) { - throw new DeveloperError('Cannot have both a depth and depth-stencil attachment.'); + var length = value.length; + if (!defined(result)) { + result = new Array(length); } - if (defined(options.stencilRenderbuffer) && depthStencilAttachment) { - throw new DeveloperError('Cannot have both a stencil and depth-stencil attachment.'); + var i = 0; + var x = 0; + while (i < length) { + var property = this._value[i]; + var itemValue = property.getValue(time, result[i]); + if (defined(itemValue)) { + result[x] = itemValue; + x++; + } + i++; } - if (depthAttachment && defined(options.stencilRenderbuffer)) { - throw new DeveloperError('Cannot have both a depth and stencil attachment.'); + result.length = x; + return result; + }; + + /** + * Sets the value of the property. + * + * @param {Property[]} value An array of Property instances. + */ + PropertyArray.prototype.setValue = function(value) { + var eventHelper = this._eventHelper; + eventHelper.removeAll(); + + if (defined(value)) { + this._value = value.slice(); + var length = value.length; + for (var i = 0; i < length; i++) { + var property = value[i]; + if (defined(property)) { + eventHelper.add(property.definitionChanged, PropertyArray.prototype._raiseDefinitionChanged, this); + } + } + } else { + this._value = undefined; } - - /////////////////////////////////////////////////////////////////// + this._definitionChanged.raiseEvent(this); + }; - this._bind(); + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + PropertyArray.prototype.equals = function(other) { + return this === other || // + (other instanceof PropertyArray && // + Property.arrayEquals(this._value, other._value)); + }; - var texture; - var renderbuffer; - var i; - var length; - var attachmentEnum; + PropertyArray.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; - if (defined(options.colorTextures)) { - var textures = options.colorTextures; - length = this._colorTextures.length = this._activeColorAttachments.length = textures.length; + return PropertyArray; +}); - if (length > maximumColorAttachments) { - throw new DeveloperError('The number of color attachments exceeds the number supported.'); +define('DataSources/ReferenceProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/RuntimeError', + './Property' + ], function( + defined, + defineProperties, + DeveloperError, + Event, + RuntimeError, + Property) { + 'use strict'; + + function resolveEntity(that) { + var entityIsResolved = true; + if (that._resolveEntity) { + var targetEntity = that._targetCollection.getById(that._targetId); + + if (defined(targetEntity)) { + targetEntity.definitionChanged.addEventListener(ReferenceProperty.prototype._onTargetEntityDefinitionChanged, that); + that._targetEntity = targetEntity; + that._resolveEntity = false; + } else { + //The property has become detached. It has a valid value but is not currently resolved to an entity in the collection + targetEntity = that._targetEntity; + entityIsResolved = false; } - - for (i = 0; i < length; ++i) { - texture = textures[i]; - if (!PixelFormat.isColorFormat(texture.pixelFormat)) { - throw new DeveloperError('The color-texture pixel-format must be a color format.'); - } - - attachmentEnum = this._gl.COLOR_ATTACHMENT0 + i; - attachTexture(this, attachmentEnum, texture); - this._activeColorAttachments[i] = attachmentEnum; - this._colorTextures[i] = texture; + if (!defined(targetEntity)) { + throw new RuntimeError('target entity "' + that._targetId + '" could not be resolved.'); } } + return entityIsResolved; + } - if (defined(options.colorRenderbuffers)) { - var renderbuffers = options.colorRenderbuffers; - length = this._colorRenderbuffers.length = this._activeColorAttachments.length = renderbuffers.length; + function resolve(that) { + var targetProperty = that._targetProperty; - if (length > maximumColorAttachments) { - throw new DeveloperError('The number of color attachments exceeds the number supported.'); - } - - for (i = 0; i < length; ++i) { - renderbuffer = renderbuffers[i]; - attachmentEnum = this._gl.COLOR_ATTACHMENT0 + i; - attachRenderbuffer(this, attachmentEnum, renderbuffer); - this._activeColorAttachments[i] = attachmentEnum; - this._colorRenderbuffers[i] = renderbuffer; - } - } + if (that._resolveProperty) { + var entityIsResolved = resolveEntity(that); - if (defined(options.depthTexture)) { - texture = options.depthTexture; + var names = that._targetPropertyNames; + targetProperty = that._targetEntity; + var length = names.length; + for (var i = 0; i < length && defined(targetProperty); i++) { + targetProperty = targetProperty[names[i]]; + } - if (texture.pixelFormat !== PixelFormat.DEPTH_COMPONENT) { - throw new DeveloperError('The depth-texture pixel-format must be DEPTH_COMPONENT.'); + if (defined(targetProperty)) { + that._targetProperty = targetProperty; + that._resolveProperty = !entityIsResolved; + } else if (!defined(that._targetProperty)) { + throw new RuntimeError('targetProperty "' + that._targetId + '.' + names.join('.') + '" could not be resolved.'); } - - attachTexture(this, this._gl.DEPTH_ATTACHMENT, texture); - this._depthTexture = texture; } - if (defined(options.depthRenderbuffer)) { - renderbuffer = options.depthRenderbuffer; - attachRenderbuffer(this, this._gl.DEPTH_ATTACHMENT, renderbuffer); - this._depthRenderbuffer = renderbuffer; - } + return targetProperty; + } - if (defined(options.stencilRenderbuffer)) { - renderbuffer = options.stencilRenderbuffer; - attachRenderbuffer(this, this._gl.STENCIL_ATTACHMENT, renderbuffer); - this._stencilRenderbuffer = renderbuffer; + /** + * A {@link Property} which transparently links to another property on a provided object. + * + * @alias ReferenceProperty + * @constructor + * + * @param {EntityCollection} targetCollection The entity collection which will be used to resolve the reference. + * @param {String} targetId The id of the entity which is being referenced. + * @param {String[]} targetPropertyNames The names of the property on the target entity which we will use. + * + * @example + * var collection = new Cesium.EntityCollection(); + * + * //Create a new entity and assign a billboard scale. + * var object1 = new Cesium.Entity({id:'object1'}); + * object1.billboard = new Cesium.BillboardGraphics(); + * object1.billboard.scale = new Cesium.ConstantProperty(2.0); + * collection.add(object1); + * + * //Create a second entity and reference the scale from the first one. + * var object2 = new Cesium.Entity({id:'object2'}); + * object2.model = new Cesium.ModelGraphics(); + * object2.model.scale = new Cesium.ReferenceProperty(collection, 'object1', ['billboard', 'scale']); + * collection.add(object2); + * + * //Create a third object, but use the fromString helper function. + * var object3 = new Cesium.Entity({id:'object3'}); + * object3.billboard = new Cesium.BillboardGraphics(); + * object3.billboard.scale = Cesium.ReferenceProperty.fromString(collection, 'object1#billboard.scale'); + * collection.add(object3); + * + * //You can refer to an entity with a # or . in id and property names by escaping them. + * var object4 = new Cesium.Entity({id:'#object.4'}); + * object4.billboard = new Cesium.BillboardGraphics(); + * object4.billboard.scale = new Cesium.ConstantProperty(2.0); + * collection.add(object4); + * + * var object5 = new Cesium.Entity({id:'object5'}); + * object5.billboard = new Cesium.BillboardGraphics(); + * object5.billboard.scale = Cesium.ReferenceProperty.fromString(collection, '\\#object\\.4#billboard.scale'); + * collection.add(object5); + */ + function ReferenceProperty(targetCollection, targetId, targetPropertyNames) { + if (!defined(targetCollection)) { + throw new DeveloperError('targetCollection is required.'); } - - if (defined(options.depthStencilTexture)) { - texture = options.depthStencilTexture; - - if (texture.pixelFormat !== PixelFormat.DEPTH_STENCIL) { - throw new DeveloperError('The depth-stencil pixel-format must be DEPTH_STENCIL.'); - } - - attachTexture(this, this._gl.DEPTH_STENCIL_ATTACHMENT, texture); - this._depthStencilTexture = texture; + if (!defined(targetId) || targetId === '') { + throw new DeveloperError('targetId is required.'); } - - if (defined(options.depthStencilRenderbuffer)) { - renderbuffer = options.depthStencilRenderbuffer; - attachRenderbuffer(this, this._gl.DEPTH_STENCIL_ATTACHMENT, renderbuffer); - this._depthStencilRenderbuffer = renderbuffer; + if (!defined(targetPropertyNames) || targetPropertyNames.length === 0) { + throw new DeveloperError('targetPropertyNames is required.'); + } + for (var i = 0; i < targetPropertyNames.length; i++) { + var item = targetPropertyNames[i]; + if (!defined(item) || item === '') { + throw new DeveloperError('reference contains invalid properties.'); + } } + + this._targetCollection = targetCollection; + this._targetId = targetId; + this._targetPropertyNames = targetPropertyNames; + this._targetProperty = undefined; + this._targetEntity = undefined; + this._definitionChanged = new Event(); + this._resolveEntity = true; + this._resolveProperty = true; - this._unBind(); + targetCollection.collectionChanged.addEventListener(ReferenceProperty.prototype._onCollectionChanged, this); } - defineProperties(Framebuffer.prototype, { + defineProperties(ReferenceProperty.prototype, { /** - * The status of the framebuffer. If the status is not WebGLConstants.FRAMEBUFFER_COMPLETE, - * a {@link DeveloperError} will be thrown when attempting to render to the framebuffer. - * @memberof Framebuffer.prototype - * @type {Number} + * Gets a value indicating if this property is constant. + * @memberof ReferenceProperty.prototype + * @type {Boolean} + * @readonly */ - status : { - get : function() { - this._bind(); - var status = this._gl.checkFramebufferStatus(this._gl.FRAMEBUFFER); - this._unBind(); - return status; - } - }, - numberOfColorAttachments : { + isConstant : { get : function() { - return this._activeColorAttachments.length; + return Property.isConstant(resolve(this)); } }, - depthTexture: { + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever the referenced property's definition is changed. + * @memberof ReferenceProperty.prototype + * @type {Event} + * @readonly + */ + definitionChanged : { get : function() { - return this._depthTexture; + return this._definitionChanged; } }, - depthRenderbuffer: { + /** + * Gets the reference frame that the position is defined in. + * This property is only valid if the referenced property is a {@link PositionProperty}. + * @memberof ReferenceProperty.prototype + * @type {ReferenceFrame} + * @readonly + */ + referenceFrame : { get : function() { - return this._depthRenderbuffer; + return resolve(this).referenceFrame; } }, - stencilRenderbuffer : { + /** + * Gets the id of the entity being referenced. + * @memberof ReferenceProperty.prototype + * @type {String} + * @readonly + */ + targetId : { get : function() { - return this._stencilRenderbuffer; + return this._targetId; } }, - depthStencilTexture : { + /** + * Gets the collection containing the entity being referenced. + * @memberof ReferenceProperty.prototype + * @type {EntityCollection} + * @readonly + */ + targetCollection : { get : function() { - return this._depthStencilTexture; + return this._targetCollection; } }, - depthStencilRenderbuffer : { + /** + * Gets the array of property names used to retrieve the referenced property. + * @memberof ReferenceProperty.prototype + * @type {String[]} + * @readonly + */ + targetPropertyNames : { get : function() { - return this._depthStencilRenderbuffer; + return this._targetPropertyNames; } }, - /** - * True if the framebuffer has a depth attachment. Depth attachments include - * depth and depth-stencil textures, and depth and depth-stencil renderbuffers. When - * rendering to a framebuffer, a depth attachment is required for the depth test to have effect. - * @memberof Framebuffer.prototype - * @type {Boolean} + * Gets the resolved instance of the underlying referenced property. + * @memberof ReferenceProperty.prototype + * @type {Property} + * @readonly */ - hasDepthAttachment : { + resolvedProperty : { get : function() { - return !!(this.depthTexture || this.depthRenderbuffer || this.depthStencilTexture || this.depthStencilRenderbuffer); + return resolve(this); } } }); - Framebuffer.prototype._bind = function() { - var gl = this._gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer); + /** + * Creates a new instance given the entity collection that will + * be used to resolve it and a string indicating the target entity id and property. + * The format of the string is "objectId#foo.bar", where # separates the id from + * property path and . separates sub-properties. If the reference identifier or + * or any sub-properties contains a # . or \ they must be escaped. + * + * @param {EntityCollection} targetCollection + * @param {String} referenceString + * @returns {ReferenceProperty} A new instance of ReferenceProperty. + * + * @exception {DeveloperError} invalid referenceString. + */ + ReferenceProperty.fromString = function(targetCollection, referenceString) { + if (!defined(targetCollection)) { + throw new DeveloperError('targetCollection is required.'); + } + if (!defined(referenceString)) { + throw new DeveloperError('referenceString is required.'); + } + + var identifier; + var values = []; + + var inIdentifier = true; + var isEscaped = false; + var token = ''; + for (var i = 0; i < referenceString.length; ++i) { + var c = referenceString.charAt(i); + + if (isEscaped) { + token += c; + isEscaped = false; + } else if (c === '\\') { + isEscaped = true; + } else if (inIdentifier && c === '#') { + identifier = token; + inIdentifier = false; + token = ''; + } else if (!inIdentifier && c === '.') { + values.push(token); + token = ''; + } else { + token += c; + } + } + values.push(token); + + return new ReferenceProperty(targetCollection, identifier, values); }; - Framebuffer.prototype._unBind = function() { - var gl = this._gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ReferenceProperty.prototype.getValue = function(time, result) { + return resolve(this).getValue(time, result); }; - Framebuffer.prototype._getActiveColorAttachments = function() { - return this._activeColorAttachments; + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * This method is only valid if the property being referenced is a {@link PositionProperty}. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + ReferenceProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + return resolve(this).getValueInReferenceFrame(time, referenceFrame, result); }; - Framebuffer.prototype.getColorTexture = function(index) { - if (!defined(index) || index < 0 || index >= this._colorTextures.length) { - throw new DeveloperError('index is required, must be greater than or equal to zero and must be less than the number of color attachments.'); - } - - return this._colorTextures[index]; + /** + * Gets the {@link Material} type at the provided time. + * This method is only valid if the property being referenced is a {@link MaterialProperty}. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + ReferenceProperty.prototype.getType = function(time) { + return resolve(this).getType(time); }; - Framebuffer.prototype.getColorRenderbuffer = function(index) { - if (!defined(index) || index < 0 || index >= this._colorRenderbuffers.length) { - throw new DeveloperError('index is required, must be greater than or equal to zero and must be less than the number of color attachments.'); + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + ReferenceProperty.prototype.equals = function(other) { + if (this === other) { + return true; } - - return this._colorRenderbuffers[index]; + + var names = this._targetPropertyNames; + var otherNames = other._targetPropertyNames; + + if (this._targetCollection !== other._targetCollection || // + this._targetId !== other._targetId || // + names.length !== otherNames.length) { + return false; + } + + var length = this._targetPropertyNames.length; + for (var i = 0; i < length; i++) { + if (names[i] !== otherNames[i]) { + return false; + } + } + + return true; }; - Framebuffer.prototype.isDestroyed = function() { - return false; + ReferenceProperty.prototype._onTargetEntityDefinitionChanged = function(targetEntity, name, value, oldValue) { + if (this._targetPropertyNames[0] === name) { + this._resolveProperty = true; + this._definitionChanged.raiseEvent(this); + } }; - Framebuffer.prototype.destroy = function() { - if (this.destroyAttachments) { - // If the color texture is a cube map face, it is owned by the cube map, and will not be destroyed. - var i = 0; - var textures = this._colorTextures; - var length = textures.length; - for (; i < length; ++i) { - var texture = textures[i]; - if (defined(texture)) { - texture.destroy(); + ReferenceProperty.prototype._onCollectionChanged = function(collection, added, removed) { + var targetEntity = this._targetEntity; + if (defined(targetEntity)) { + if (removed.indexOf(targetEntity) !== -1) { + targetEntity.definitionChanged.removeEventListener(ReferenceProperty.prototype._onTargetEntityDefinitionChanged, this); + this._resolveEntity = true; + this._resolveProperty = true; + } else if (this._resolveEntity) { + //If targetEntity is defined but resolveEntity is true, then the entity is detached + //and any change to the collection needs to incur an attempt to resolve in order to re-attach. + //without this if block, a reference that becomes re-attached will not signal definitionChanged + resolve(this); + if (!this._resolveEntity) { + this._definitionChanged.raiseEvent(this); } } + } + }; - var renderbuffers = this._colorRenderbuffers; - length = renderbuffers.length; - for (i = 0; i < length; ++i) { - var renderbuffer = renderbuffers[i]; - if (defined(renderbuffer)) { - renderbuffer.destroy(); + return ReferenceProperty; +}); + +define('DataSources/Rotation',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/DeveloperError', + '../Core/Math' + ], function( + defaultValue, + defined, + DeveloperError, + CesiumMath) { + 'use strict'; + + /** + * Represents a {@link Packable} number that always interpolates values + * towards the shortest angle of rotation. This object is never used directly + * but is instead passed to the constructor of {@link SampledProperty} + * in order to represent a two-dimensional angle of rotation. + * + * @exports Rotation + * + * + * @example + * var time1 = Cesium.JulianDate.fromIso8601('2010-05-07T00:00:00'); + * var time2 = Cesium.JulianDate.fromIso8601('2010-05-07T00:01:00'); + * var time3 = Cesium.JulianDate.fromIso8601('2010-05-07T00:02:00'); + * + * var property = new Cesium.SampledProperty(Cesium.Rotation); + * property.addSample(time1, 0); + * property.addSample(time3, Cesium.Math.toRadians(350)); + * + * //Getting the value at time2 will equal 355 degrees instead + * //of 175 degrees (which is what you get if you construct + * //a SampledProperty(Number) instead. Note, the actual + * //return value is in radians, not degrees. + * property.getValue(time2); + * + * @see PackableForInterpolation + */ + var Rotation = { + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + packedLength : 1, + + /** + * Stores the provided instance into the provided array. + * + * @param {Rotation} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + pack : function(value, array, startingIndex) { + if (!defined(value)) { + throw new DeveloperError('value is required'); + } + + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); + array[startingIndex] = value; + + return array; + }, + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {Rotation} [result] The object into which to store the result. + * @returns {Rotation} The modified result parameter or a new Rotation instance if one was not provided. + */ + unpack : function(array, startingIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + + startingIndex = defaultValue(startingIndex, 0); + return array[startingIndex]; + }, + + /** + * Converts a packed array into a form suitable for interpolation. + * + * @param {Number[]} packedArray The packed array. + * @param {Number} [startingIndex=0] The index of the first element to be converted. + * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. + * @param {Number[]} result The object into which to store the result. + */ + convertPackedArrayForInterpolation : function(packedArray, startingIndex, lastIndex, result) { + if (!defined(packedArray)) { + throw new DeveloperError('packedArray is required'); + } + + startingIndex = defaultValue(startingIndex, 0); + lastIndex = defaultValue(lastIndex, packedArray.length); + + var previousValue; + for (var i = 0, len = lastIndex - startingIndex + 1; i < len; i++) { + var value = packedArray[startingIndex + i]; + if (i === 0 || Math.abs(previousValue - value) < Math.PI) { + result[i] = value; + } else { + result[i] = value - CesiumMath.TWO_PI; } + previousValue = value; } + }, - this._depthTexture = this._depthTexture && this._depthTexture.destroy(); - this._depthRenderbuffer = this._depthRenderbuffer && this._depthRenderbuffer.destroy(); - this._stencilRenderbuffer = this._stencilRenderbuffer && this._stencilRenderbuffer.destroy(); - this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); - this._depthStencilRenderbuffer = this._depthStencilRenderbuffer && this._depthStencilRenderbuffer.destroy(); + /** + * Retrieves an instance from a packed array converted with {@link Rotation.convertPackedArrayForInterpolation}. + * + * @param {Number[]} array The array previously packed for interpolation. + * @param {Number[]} sourceArray The original packed array. + * @param {Number} [firstIndex=0] The firstIndex used to convert the array. + * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. + * @param {Rotation} [result] The object into which to store the result. + * @returns {Rotation} The modified result parameter or a new Rotation instance if one was not provided. + */ + unpackInterpolationResult : function(array, sourceArray, firstIndex, lastIndex, result) { + if (!defined(array)) { + throw new DeveloperError('array is required'); + } + if (!defined(sourceArray)) { + throw new DeveloperError('sourceArray is required'); + } + + result = array[0]; + if (result < 0) { + return result + CesiumMath.TWO_PI; + } + return result; } - - this._gl.deleteFramebuffer(this._framebuffer); - return destroyObject(this); }; - return Framebuffer; + return Rotation; }); -define('Scene/TextureAtlas',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/createGuid', +define('DataSources/SampledProperty',[ + '../Core/binarySearch', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/loadImage', - '../Core/PixelFormat', - '../Core/RuntimeError', - '../Renderer/Framebuffer', - '../Renderer/Texture', - '../ThirdParty/when' + '../Core/Event', + '../Core/ExtrapolationType', + '../Core/JulianDate', + '../Core/LinearApproximation' ], function( - BoundingRectangle, - Cartesian2, - createGuid, + binarySearch, defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - loadImage, - PixelFormat, - RuntimeError, - Framebuffer, - Texture, - when) { + Event, + ExtrapolationType, + JulianDate, + LinearApproximation) { 'use strict'; - // The atlas is made up of regions of space called nodes that contain images or child nodes. - function TextureAtlasNode(bottomLeft, topRight, childNode1, childNode2, imageIndex) { - this.bottomLeft = defaultValue(bottomLeft, Cartesian2.ZERO); - this.topRight = defaultValue(topRight, Cartesian2.ZERO); - this.childNode1 = childNode1; - this.childNode2 = childNode2; - this.imageIndex = imageIndex; + var PackableNumber = { + packedLength : 1, + pack : function(value, array, startingIndex) { + startingIndex = defaultValue(startingIndex, 0); + array[startingIndex] = value; + }, + unpack : function(array, startingIndex, result) { + startingIndex = defaultValue(startingIndex, 0); + return array[startingIndex]; + } + }; + + //We can't use splice for inserting new elements because function apply can't handle + //a huge number of arguments. See https://code.google.com/p/chromium/issues/detail?id=56588 + function arrayInsert(array, startIndex, items) { + var i; + var arrayLength = array.length; + var itemsLength = items.length; + var newLength = arrayLength + itemsLength; + + array.length = newLength; + if (arrayLength !== startIndex) { + var q = arrayLength - 1; + for (i = newLength - 1; i >= startIndex; i--) { + array[i] = array[q--]; + } + } + + for (i = 0; i < itemsLength; i++) { + array[startIndex++] = items[i]; + } } - var defaultInitialSize = new Cartesian2(16.0, 16.0); + function convertDate(date, epoch) { + if (date instanceof JulianDate) { + return date; + } + if (typeof date === 'string') { + return JulianDate.fromIso8601(date); + } + return JulianDate.addSeconds(epoch, date, new JulianDate()); + } + + var timesSpliceArgs = []; + var valuesSpliceArgs = []; + + function mergeNewSamples(epoch, times, values, newData, packedLength) { + var newDataIndex = 0; + var i; + var prevItem; + var timesInsertionPoint; + var valuesInsertionPoint; + var currentTime; + var nextTime; + + while (newDataIndex < newData.length) { + currentTime = convertDate(newData[newDataIndex], epoch); + timesInsertionPoint = binarySearch(times, currentTime, JulianDate.compare); + var timesSpliceArgsCount = 0; + var valuesSpliceArgsCount = 0; + + if (timesInsertionPoint < 0) { + //Doesn't exist, insert as many additional values as we can. + timesInsertionPoint = ~timesInsertionPoint; + + valuesInsertionPoint = timesInsertionPoint * packedLength; + prevItem = undefined; + nextTime = times[timesInsertionPoint]; + while (newDataIndex < newData.length) { + currentTime = convertDate(newData[newDataIndex], epoch); + if ((defined(prevItem) && JulianDate.compare(prevItem, currentTime) >= 0) || (defined(nextTime) && JulianDate.compare(currentTime, nextTime) >= 0)) { + break; + } + timesSpliceArgs[timesSpliceArgsCount++] = currentTime; + newDataIndex = newDataIndex + 1; + for (i = 0; i < packedLength; i++) { + valuesSpliceArgs[valuesSpliceArgsCount++] = newData[newDataIndex]; + newDataIndex = newDataIndex + 1; + } + prevItem = currentTime; + } + + if (timesSpliceArgsCount > 0) { + valuesSpliceArgs.length = valuesSpliceArgsCount; + arrayInsert(values, valuesInsertionPoint, valuesSpliceArgs); + + timesSpliceArgs.length = timesSpliceArgsCount; + arrayInsert(times, timesInsertionPoint, timesSpliceArgs); + } + } else { + //Found an exact match + for (i = 0; i < packedLength; i++) { + newDataIndex++; + values[(timesInsertionPoint * packedLength) + i] = newData[newDataIndex]; + } + newDataIndex++; + } + } + } /** - * A TextureAtlas stores multiple images in one square texture and keeps - * track of the texture coordinates for each image. TextureAtlas is dynamic, - * meaning new images can be added at any point in time. - * Texture coordinates are subject to change if the texture atlas resizes, so it is - * important to check {@link TextureAtlas#getGUID} before using old values. - * - * @alias TextureAtlas + * A {@link Property} whose value is interpolated for a given time from the + * provided set of samples and specified interpolation algorithm and degree. + * @alias SampledProperty * @constructor * - * @param {Object} options Object with the following properties: - * @param {Scene} options.context The context in which the texture gets created. - * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGBA] The pixel format of the texture. - * @param {Number} [options.borderWidthInPixels=1] The amount of spacing between adjacent images in pixels. - * @param {Cartesian2} [options.initialSize=new Cartesian2(16.0, 16.0)] The initial side lengths of the texture. + * @param {Number|Packable} type The type of property. + * @param {Packable[]} [derivativeTypes] When supplied, indicates that samples will contain derivative information of the specified types. * - * @exception {DeveloperError} borderWidthInPixels must be greater than or equal to zero. - * @exception {DeveloperError} initialSize must be greater than zero. * - * @private + * @example + * //Create a linearly interpolated Cartesian2 + * var property = new Cesium.SampledProperty(Cesium.Cartesian2); + * + * //Populate it with data + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:00.00Z'), new Cesium.Cartesian2(0, 0)); + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-02T00:00:00.00Z'), new Cesium.Cartesian2(4, 7)); + * + * //Retrieve an interpolated value + * var result = property.getValue(Cesium.JulianDate.fromIso8601('2012-08-01T12:00:00.00Z')); + * + * @example + * //Create a simple numeric SampledProperty that uses third degree Hermite Polynomial Approximation + * var property = new Cesium.SampledProperty(Number); + * property.setInterpolationOptions({ + * interpolationDegree : 3, + * interpolationAlgorithm : Cesium.HermitePolynomialApproximation + * }); + * + * //Populate it with data + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:00.00Z'), 1.0); + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:01:00.00Z'), 6.0); + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:02:00.00Z'), 12.0); + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:03:30.00Z'), 5.0); + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:06:30.00Z'), 2.0); + * + * //Samples can be added in any order. + * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:30.00Z'), 6.2); + * + * //Retrieve an interpolated value + * var result = property.getValue(Cesium.JulianDate.fromIso8601('2012-08-01T00:02:34.00Z')); + * + * @see SampledPositionProperty */ - function TextureAtlas(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var borderWidthInPixels = defaultValue(options.borderWidthInPixels, 1.0); - var initialSize = defaultValue(options.initialSize, defaultInitialSize); - - if (!defined(options.context)) { - throw new DeveloperError('context is required.'); + function SampledProperty(type, derivativeTypes) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); } - if (borderWidthInPixels < 0) { - throw new DeveloperError('borderWidthInPixels must be greater than or equal to zero.'); + + var innerType = type; + if (innerType === Number) { + innerType = PackableNumber; } - if (initialSize.x < 1 || initialSize.y < 1) { - throw new DeveloperError('initialSize must be greater than zero.'); + var packedLength = innerType.packedLength; + var packedInterpolationLength = defaultValue(innerType.packedInterpolationLength, packedLength); + + var inputOrder = 0; + var innerDerivativeTypes; + if (defined(derivativeTypes)) { + var length = derivativeTypes.length; + innerDerivativeTypes = new Array(length); + for (var i = 0; i < length; i++) { + var derivativeType = derivativeTypes[i]; + if (derivativeType === Number) { + derivativeType = PackableNumber; + } + var derivativePackedLength = derivativeType.packedLength; + packedLength += derivativePackedLength; + packedInterpolationLength += defaultValue(derivativeType.packedInterpolationLength, derivativePackedLength); + innerDerivativeTypes[i] = derivativeType; + } + inputOrder = length; } - - this._context = options.context; - this._pixelFormat = defaultValue(options.pixelFormat, PixelFormat.RGBA); - this._borderWidthInPixels = borderWidthInPixels; - this._textureCoordinates = []; - this._guid = createGuid(); - this._idHash = {}; - this._initialSize = initialSize; - this._root = undefined; + this._type = type; + this._innerType = innerType; + this._interpolationDegree = 1; + this._interpolationAlgorithm = LinearApproximation; + this._numberOfPoints = 0; + this._times = []; + this._values = []; + this._xTable = []; + this._yTable = []; + this._packedLength = packedLength; + this._packedInterpolationLength = packedInterpolationLength; + this._updateTableLength = true; + this._interpolationResult = new Array(packedInterpolationLength); + this._definitionChanged = new Event(); + this._derivativeTypes = derivativeTypes; + this._innerDerivativeTypes = innerDerivativeTypes; + this._inputOrder = inputOrder; + this._forwardExtrapolationType = ExtrapolationType.NONE; + this._forwardExtrapolationDuration = 0; + this._backwardExtrapolationType = ExtrapolationType.NONE; + this._backwardExtrapolationDuration = 0; } - defineProperties(TextureAtlas.prototype, { + defineProperties(SampledProperty.prototype, { /** - * The amount of spacing between adjacent images in pixels. - * @memberof TextureAtlas.prototype + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof SampledProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return this._values.length === 0; + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof SampledProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the type of property. + * @memberof SampledProperty.prototype + * @type {Object} + */ + type : { + get : function() { + return this._type; + } + }, + /** + * Gets the derivative types used by this property. + * @memberof SampledProperty.prototype + * @type {Packable[]} + */ + derivativeTypes : { + get : function() { + return this._derivativeTypes; + } + }, + /** + * Gets the degree of interpolation to perform when retrieving a value. + * @memberof SampledProperty.prototype * @type {Number} + * @default 1 */ - borderWidthInPixels : { + interpolationDegree : { get : function() { - return this._borderWidthInPixels; + return this._interpolationDegree; } }, - /** - * An array of {@link BoundingRectangle} texture coordinate regions for all the images in the texture atlas. - * The x and y values of the rectangle correspond to the bottom-left corner of the texture coordinate. - * The coordinates are in the order that the corresponding images were added to the atlas. - * @memberof TextureAtlas.prototype - * @type {BoundingRectangle[]} + * Gets the interpolation algorithm to use when retrieving a value. + * @memberof SampledProperty.prototype + * @type {InterpolationAlgorithm} + * @default LinearApproximation */ - textureCoordinates : { + interpolationAlgorithm : { get : function() { - return this._textureCoordinates; + return this._interpolationAlgorithm; } }, - /** - * The texture that all of the images are being written to. - * @memberof TextureAtlas.prototype - * @type {Texture} + * Gets or sets the type of extrapolation to perform when a value + * is requested at a time after any available samples. + * @memberof SampledProperty.prototype + * @type {ExtrapolationType} + * @default ExtrapolationType.NONE */ - texture : { + forwardExtrapolationType : { get : function() { - if(!defined(this._texture)) { - this._texture = new Texture({ - context : this._context, - width : this._initialSize.x, - height : this._initialSize.y, - pixelFormat : this._pixelFormat - }); + return this._forwardExtrapolationType; + }, + set : function(value) { + if (this._forwardExtrapolationType !== value) { + this._forwardExtrapolationType = value; + this._definitionChanged.raiseEvent(this); } - return this._texture; } }, - /** - * The number of images in the texture atlas. This value increases - * every time addImage or addImages is called. - * Texture coordinates are subject to change if the texture atlas resizes, so it is - * important to check {@link TextureAtlas#getGUID} before using old values. - * @memberof TextureAtlas.prototype + * Gets or sets the amount of time to extrapolate forward before + * the property becomes undefined. A value of 0 will extrapolate forever. + * @memberof SampledProperty.prototype * @type {Number} + * @default 0 */ - numberOfImages : { + forwardExtrapolationDuration : { get : function() { - return this._textureCoordinates.length; + return this._forwardExtrapolationDuration; + }, + set : function(value) { + if (this._forwardExtrapolationDuration !== value) { + this._forwardExtrapolationDuration = value; + this._definitionChanged.raiseEvent(this); + } } }, - /** - * The atlas' globally unique identifier (GUID). - * The GUID changes whenever the texture atlas is modified. - * Classes that use a texture atlas should check if the GUID - * has changed before processing the atlas data. - * @memberof TextureAtlas.prototype - * @type {String} + * Gets or sets the type of extrapolation to perform when a value + * is requested at a time before any available samples. + * @memberof SampledProperty.prototype + * @type {ExtrapolationType} + * @default ExtrapolationType.NONE */ - guid : { + backwardExtrapolationType : { get : function() { - return this._guid; + return this._backwardExtrapolationType; + }, + set : function(value) { + if (this._backwardExtrapolationType !== value) { + this._backwardExtrapolationType = value; + this._definitionChanged.raiseEvent(this); + } + } + }, + /** + * Gets or sets the amount of time to extrapolate backward + * before the property becomes undefined. A value of 0 will extrapolate forever. + * @memberof SampledProperty.prototype + * @type {Number} + * @default 0 + */ + backwardExtrapolationDuration : { + get : function() { + return this._backwardExtrapolationDuration; + }, + set : function(value) { + if (this._backwardExtrapolationDuration !== value) { + this._backwardExtrapolationDuration = value; + this._definitionChanged.raiseEvent(this); + } } } }); - // Builds a larger texture and copies the old texture into the new one. - function resizeAtlas(textureAtlas, image) { - var context = textureAtlas._context; - var numImages = textureAtlas.numberOfImages; - var scalingFactor = 2.0; - var borderWidthInPixels = textureAtlas._borderWidthInPixels; - if (numImages > 0) { - var oldAtlasWidth = textureAtlas._texture.width; - var oldAtlasHeight = textureAtlas._texture.height; - var atlasWidth = scalingFactor * (oldAtlasWidth + image.width + borderWidthInPixels); - var atlasHeight = scalingFactor * (oldAtlasHeight + image.height + borderWidthInPixels); - var widthRatio = oldAtlasWidth / atlasWidth; - var heightRatio = oldAtlasHeight / atlasHeight; - - // Create new node structure, putting the old root node in the bottom left. - var nodeBottomRight = new TextureAtlasNode(new Cartesian2(oldAtlasWidth + borderWidthInPixels, borderWidthInPixels), new Cartesian2(atlasWidth, oldAtlasHeight)); - var nodeBottomHalf = new TextureAtlasNode(new Cartesian2(), new Cartesian2(atlasWidth, oldAtlasHeight), textureAtlas._root, nodeBottomRight); - var nodeTopHalf = new TextureAtlasNode(new Cartesian2(borderWidthInPixels, oldAtlasHeight + borderWidthInPixels), new Cartesian2(atlasWidth, atlasHeight)); - var nodeMain = new TextureAtlasNode(new Cartesian2(), new Cartesian2(atlasWidth, atlasHeight), nodeBottomHalf, nodeTopHalf); - - // Resize texture coordinates. - for (var i = 0; i < textureAtlas._textureCoordinates.length; i++) { - var texCoord = textureAtlas._textureCoordinates[i]; - if (defined(texCoord)) { - texCoord.x *= widthRatio; - texCoord.y *= heightRatio; - texCoord.width *= widthRatio; - texCoord.height *= heightRatio; - } - } + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + SampledProperty.prototype.getValue = function(time, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var times = this._times; + var timesLength = times.length; + if (timesLength === 0) { + return undefined; + } - // Copy larger texture. - var newTexture = new Texture({ - context : textureAtlas._context, - width : atlasWidth, - height : atlasHeight, - pixelFormat : textureAtlas._pixelFormat - }); + var timeout; + var innerType = this._innerType; + var values = this._values; + var index = binarySearch(times, time, JulianDate.compare); - var framebuffer = new Framebuffer({ - context : context, - colorTextures : [textureAtlas._texture], - destroyAttachments : false - }); + if (index < 0) { + index = ~index; - framebuffer._bind(); - newTexture.copyFromFramebuffer(0, 0, 0, 0, atlasWidth, atlasHeight); - framebuffer._unBind(); - framebuffer.destroy(); - textureAtlas._texture = textureAtlas._texture && textureAtlas._texture.destroy(); - textureAtlas._texture = newTexture; - textureAtlas._root = nodeMain; - } else { - // First image exceeds initialSize - var initialWidth = scalingFactor * (image.width + 2 * borderWidthInPixels); - var initialHeight = scalingFactor * (image.height + 2 * borderWidthInPixels); - if(initialWidth < textureAtlas._initialSize.x) { - initialWidth = textureAtlas._initialSize.x; - } - if(initialHeight < textureAtlas._initialSize.y) { - initialHeight = textureAtlas._initialSize.y; + if (index === 0) { + var startTime = times[index]; + timeout = this._backwardExtrapolationDuration; + if (this._backwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(startTime, time) > timeout)) { + return undefined; + } + if (this._backwardExtrapolationType === ExtrapolationType.HOLD) { + return innerType.unpack(values, 0, result); + } } - textureAtlas._texture = textureAtlas._texture && textureAtlas._texture.destroy(); - textureAtlas._texture = new Texture({ - context : textureAtlas._context, - width : initialWidth, - height : initialHeight, - pixelFormat : textureAtlas._pixelFormat - }); - textureAtlas._root = new TextureAtlasNode(new Cartesian2(borderWidthInPixels, borderWidthInPixels), - new Cartesian2(initialWidth, initialHeight)); - } - } - // A recursive function that finds the best place to insert - // a new image based on existing image 'nodes'. - // Inspired by: http://blackpawn.com/texts/lightmaps/default.html - function findNode(textureAtlas, node, image) { - if (!defined(node)) { - return undefined; - } + if (index >= timesLength) { + index = timesLength - 1; + var endTime = times[index]; + timeout = this._forwardExtrapolationDuration; + if (this._forwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(time, endTime) > timeout)) { + return undefined; + } + if (this._forwardExtrapolationType === ExtrapolationType.HOLD) { + index = timesLength - 1; + return innerType.unpack(values, index * innerType.packedLength, result); + } + } - // If a leaf node - if (!defined(node.childNode1) && - !defined(node.childNode2)) { + var xTable = this._xTable; + var yTable = this._yTable; + var interpolationAlgorithm = this._interpolationAlgorithm; + var packedInterpolationLength = this._packedInterpolationLength; + var inputOrder = this._inputOrder; - // Node already contains an image, don't add to it. - if (defined(node.imageIndex)) { + if (this._updateTableLength) { + this._updateTableLength = false; + var numberOfPoints = Math.min(interpolationAlgorithm.getRequiredDataPoints(this._interpolationDegree, inputOrder), timesLength); + if (numberOfPoints !== this._numberOfPoints) { + this._numberOfPoints = numberOfPoints; + xTable.length = numberOfPoints; + yTable.length = numberOfPoints * packedInterpolationLength; + } + } + + var degree = this._numberOfPoints - 1; + if (degree < 1) { return undefined; } - var nodeWidth = node.topRight.x - node.bottomLeft.x; - var nodeHeight = node.topRight.y - node.bottomLeft.y; - var widthDifference = nodeWidth - image.width; - var heightDifference = nodeHeight - image.height; + var firstIndex = 0; + var lastIndex = timesLength - 1; + var pointsInCollection = lastIndex - firstIndex + 1; - // Node is smaller than the image. - if (widthDifference < 0 || heightDifference < 0) { - return undefined; + if (pointsInCollection >= degree + 1) { + var computedFirstIndex = index - ((degree / 2) | 0) - 1; + if (computedFirstIndex < firstIndex) { + computedFirstIndex = firstIndex; + } + var computedLastIndex = computedFirstIndex + degree; + if (computedLastIndex > lastIndex) { + computedLastIndex = lastIndex; + computedFirstIndex = computedLastIndex - degree; + if (computedFirstIndex < firstIndex) { + computedFirstIndex = firstIndex; + } + } + + firstIndex = computedFirstIndex; + lastIndex = computedLastIndex; } + var length = lastIndex - firstIndex + 1; - // If the node is the same size as the image, return the node - if (widthDifference === 0 && heightDifference === 0) { - return node; + // Build the tables + for (var i = 0; i < length; ++i) { + xTable[i] = JulianDate.secondsDifference(times[firstIndex + i], times[lastIndex]); } - // Vertical split (childNode1 = left half, childNode2 = right half). - if (widthDifference > heightDifference) { - node.childNode1 = new TextureAtlasNode(new Cartesian2(node.bottomLeft.x, node.bottomLeft.y), new Cartesian2(node.bottomLeft.x + image.width, node.topRight.y)); - // Only make a second child if the border gives enough space. - var childNode2BottomLeftX = node.bottomLeft.x + image.width + textureAtlas._borderWidthInPixels; - if (childNode2BottomLeftX < node.topRight.x) { - node.childNode2 = new TextureAtlasNode(new Cartesian2(childNode2BottomLeftX, node.bottomLeft.y), new Cartesian2(node.topRight.x, node.topRight.y)); + if (!defined(innerType.convertPackedArrayForInterpolation)) { + var destinationIndex = 0; + var packedLength = this._packedLength; + var sourceIndex = firstIndex * packedLength; + var stop = (lastIndex + 1) * packedLength; + + while (sourceIndex < stop) { + yTable[destinationIndex] = values[sourceIndex]; + sourceIndex++; + destinationIndex++; } + } else { + innerType.convertPackedArrayForInterpolation(values, firstIndex, lastIndex, yTable); } - // Horizontal split (childNode1 = bottom half, childNode2 = top half). - else { - node.childNode1 = new TextureAtlasNode(new Cartesian2(node.bottomLeft.x, node.bottomLeft.y), new Cartesian2(node.topRight.x, node.bottomLeft.y + image.height)); - // Only make a second child if the border gives enough space. - var childNode2BottomLeftY = node.bottomLeft.y + image.height + textureAtlas._borderWidthInPixels; - if (childNode2BottomLeftY < node.topRight.y) { - node.childNode2 = new TextureAtlasNode(new Cartesian2(node.bottomLeft.x, childNode2BottomLeftY), new Cartesian2(node.topRight.x, node.topRight.y)); - } + + // Interpolate! + var x = JulianDate.secondsDifference(time, times[lastIndex]); + var interpolationResult; + if (inputOrder === 0 || !defined(interpolationAlgorithm.interpolate)) { + interpolationResult = interpolationAlgorithm.interpolateOrderZero(x, xTable, yTable, packedInterpolationLength, this._interpolationResult); + } else { + var yStride = Math.floor(packedInterpolationLength / (inputOrder + 1)); + interpolationResult = interpolationAlgorithm.interpolate(x, xTable, yTable, yStride, inputOrder, inputOrder, this._interpolationResult); } - return findNode(textureAtlas, node.childNode1, image); + + if (!defined(innerType.unpackInterpolationResult)) { + return innerType.unpack(interpolationResult, 0, result); + } + return innerType.unpackInterpolationResult(interpolationResult, values, firstIndex, lastIndex, result); } + return innerType.unpack(values, index * this._packedLength, result); + }; - // If not a leaf node - return findNode(textureAtlas, node.childNode1, image) || - findNode(textureAtlas, node.childNode2, image); - } + /** + * Sets the algorithm and degree to use when interpolating a value. + * + * @param {Object} [options] Object with the following properties: + * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. + * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + */ + SampledProperty.prototype.setInterpolationOptions = function(options) { + if (!defined(options)) { + return; + } - // Adds image of given index to the texture atlas. Called from addImage and addImages. - function addImage(textureAtlas, image, index) { - var node = findNode(textureAtlas, textureAtlas._root, image); - if (defined(node)) { - // Found a node that can hold the image. - node.imageIndex = index; + var valuesChanged = false; - // Add texture coordinate and write to texture - var atlasWidth = textureAtlas._texture.width; - var atlasHeight = textureAtlas._texture.height; - var nodeWidth = node.topRight.x - node.bottomLeft.x; - var nodeHeight = node.topRight.y - node.bottomLeft.y; - var x = node.bottomLeft.x / atlasWidth; - var y = node.bottomLeft.y / atlasHeight; - var w = nodeWidth / atlasWidth; - var h = nodeHeight / atlasHeight; - textureAtlas._textureCoordinates[index] = new BoundingRectangle(x, y, w, h); - textureAtlas._texture.copyFrom(image, node.bottomLeft.x, node.bottomLeft.y); - } else { - // No node found, must resize the texture atlas. - resizeAtlas(textureAtlas, image); - addImage(textureAtlas, image, index); + var interpolationAlgorithm = options.interpolationAlgorithm; + var interpolationDegree = options.interpolationDegree; + + if (defined(interpolationAlgorithm) && this._interpolationAlgorithm !== interpolationAlgorithm) { + this._interpolationAlgorithm = interpolationAlgorithm; + valuesChanged = true; } - textureAtlas._guid = createGuid(); - } + if (defined(interpolationDegree) && this._interpolationDegree !== interpolationDegree) { + this._interpolationDegree = interpolationDegree; + valuesChanged = true; + } + + if (valuesChanged) { + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); + } + }; /** - * Adds an image to the atlas. If the image is already in the atlas, the atlas is unchanged and - * the existing index is used. + * Adds a new sample * - * @param {String} id An identifier to detect whether the image already exists in the atlas. - * @param {Image|Canvas|String|Promise|TextureAtlas~CreateImageCallback} image An image or canvas to add to the texture atlas, - * or a URL to an Image, or a Promise for an image, or a function that creates an image. - * @returns {Promise.<Number>} A Promise for the image index. + * @param {JulianDate} time The sample time. + * @param {Packable} value The value at the provided time. + * @param {Packable[]} [derivatives] The array of derivatives at the provided time. */ - TextureAtlas.prototype.addImage = function(id, image) { - if (!defined(id)) { - throw new DeveloperError('id is required.'); + SampledProperty.prototype.addSample = function(time, value, derivatives) { + var innerDerivativeTypes = this._innerDerivativeTypes; + var hasDerivatives = defined(innerDerivativeTypes); + + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - if (!defined(image)) { - throw new DeveloperError('image is required.'); + if (!defined(value)) { + throw new DeveloperError('value is required.'); } - - var indexPromise = this._idHash[id]; - if (defined(indexPromise)) { - // we're already aware of this source - return indexPromise; + if (hasDerivatives && !defined(derivatives)) { + throw new DeveloperError('derivatives is required.'); } + + var innerType = this._innerType; + var data = []; + data.push(time); + innerType.pack(value, data, data.length); - // not in atlas, create the promise for the index - - if (typeof image === 'function') { - // if image is a function, call it - image = image(id); - if (!defined(image)) { - throw new DeveloperError('image is required.'); + if (hasDerivatives) { + var derivativesLength = innerDerivativeTypes.length; + for (var x = 0; x < derivativesLength; x++) { + innerDerivativeTypes[x].pack(derivatives[x], data, data.length); } - } else if (typeof image === 'string') { - // if image is a string, load it as an image - image = loadImage(image); } - - var that = this; - - indexPromise = when(image, function(image) { - if (that.isDestroyed()) { - return -1; - } - - var index = that.numberOfImages; - - addImage(that, image, index); - - return index; - }); - - // store the promise - this._idHash[id] = indexPromise; - - return indexPromise; + mergeNewSamples(undefined, this._times, this._values, data, this._packedLength); + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); }; /** - * Add a sub-region of an existing atlas image as additional image indices. + * Adds an array of samples * - * @param {String} id The identifier of the existing image. - * @param {BoundingRectangle} subRegion An {@link BoundingRectangle} sub-region measured in pixels from the bottom-left. + * @param {JulianDate[]} times An array of JulianDate instances where each index is a sample time. + * @param {Packable[]} values The array of values, where each value corresponds to the provided times index. + * @param {Array[]} [derivativeValues] An array where each item is the array of derivatives at the equivalent time index. * - * @returns {Promise.<Number>} A Promise for the image index. + * @exception {DeveloperError} times and values must be the same length. + * @exception {DeveloperError} times and derivativeValues must be the same length. */ - TextureAtlas.prototype.addSubRegion = function(id, subRegion) { - if (!defined(id)) { - throw new DeveloperError('id is required.'); + SampledProperty.prototype.addSamples = function(times, values, derivativeValues) { + var innerDerivativeTypes = this._innerDerivativeTypes; + var hasDerivatives = defined(innerDerivativeTypes); + + if (!defined(times)) { + throw new DeveloperError('times is required.'); } - if (!defined(subRegion)) { - throw new DeveloperError('subRegion is required.'); + if (!defined(values)) { + throw new DeveloperError('values is required.'); } - - var indexPromise = this._idHash[id]; - if (!defined(indexPromise)) { - throw new RuntimeError('image with id "' + id + '" not found in the atlas.'); + if (times.length !== values.length) { + throw new DeveloperError('times and values must be the same length.'); } + if (hasDerivatives && (!defined(derivativeValues) || derivativeValues.length !== times.length)) { + throw new DeveloperError('times and derivativeValues must be the same length.'); + } + + var innerType = this._innerType; + var length = times.length; + var data = []; + for (var i = 0; i < length; i++) { + data.push(times[i]); + innerType.pack(values[i], data, data.length); - var that = this; - return when(indexPromise, function(index) { - if (index === -1) { - // the atlas is destroyed - return -1; + if (hasDerivatives) { + var derivatives = derivativeValues[i]; + var derivativesLength = innerDerivativeTypes.length; + for (var x = 0; x < derivativesLength; x++) { + innerDerivativeTypes[x].pack(derivatives[x], data, data.length); + } } - var atlasWidth = that._texture.width; - var atlasHeight = that._texture.height; - var numImages = that.numberOfImages; - - var baseRegion = that._textureCoordinates[index]; - var x = baseRegion.x + (subRegion.x / atlasWidth); - var y = baseRegion.y + (subRegion.y / atlasHeight); - var w = subRegion.width / atlasWidth; - var h = subRegion.height / atlasHeight; - that._textureCoordinates.push(new BoundingRectangle(x, y, w, h)); - that._guid = createGuid(); - - return numImages; - }); + } + mergeNewSamples(undefined, this._times, this._values, data, this._packedLength); + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); }; /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * Adds samples as a single packed array where each new sample is represented as a date, + * followed by the packed representation of the corresponding value and derivatives. * - * @see TextureAtlas#destroy + * @param {Number[]} packedSamples The array of packed samples. + * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. */ - TextureAtlas.prototype.isDestroyed = function() { - return false; + SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) { + if (!defined(packedSamples)) { + throw new DeveloperError('packedSamples is required.'); + } + + mergeNewSamples(epoch, this._times, this._values, packedSamples, this._packedLength); + this._updateTableLength = true; + this._definitionChanged.raiseEvent(this); }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * atlas = atlas && atlas.destroy(); + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @see TextureAtlas#isDestroyed + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - TextureAtlas.prototype.destroy = function() { - this._texture = this._texture && this._texture.destroy(); - return destroyObject(this); + SampledProperty.prototype.equals = function(other) { + if (this === other) { + return true; + } + if (!defined(other)) { + return false; + } + + if (this._type !== other._type || // + this._interpolationDegree !== other._interpolationDegree || // + this._interpolationAlgorithm !== other._interpolationAlgorithm) { + return false; + } + + var derivativeTypes = this._derivativeTypes; + var hasDerivatives = defined(derivativeTypes); + var otherDerivativeTypes = other._derivativeTypes; + var otherHasDerivatives = defined(otherDerivativeTypes); + if (hasDerivatives !== otherHasDerivatives) { + return false; + } + + var i; + var length; + if (hasDerivatives) { + length = derivativeTypes.length; + if (length !== otherDerivativeTypes.length) { + return false; + } + + for (i = 0; i < length; i++) { + if (derivativeTypes[i] !== otherDerivativeTypes[i]) { + return false; + } + } + } + + var times = this._times; + var otherTimes = other._times; + length = times.length; + + if (length !== otherTimes.length) { + return false; + } + + for (i = 0; i < length; i++) { + if (!JulianDate.equals(times[i], otherTimes[i])) { + return false; + } + } + + var values = this._values; + var otherValues = other._values; + for (i = 0; i < length; i++) { + if (values[i] !== otherValues[i]) { + return false; + } + } + + return true; }; - /** - * A function that creates an image. - * @callback TextureAtlas~CreateImageCallback - * @param {String} id The identifier of the image to load. - * @returns {Image|Promise} The image, or a promise that will resolve to an image. - */ + //Exposed for testing. + SampledProperty._mergeNewSamples = mergeNewSamples; - return TextureAtlas; + return SampledProperty; }); -define('Scene/BillboardCollection',[ - '../Core/AttributeCompression', - '../Core/BoundingSphere', - '../Core/Cartesian2', +define('DataSources/SampledPositionProperty',[ '../Core/Cartesian3', - '../Core/Color', - '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/EncodedCartesian3', - '../Core/IndexDatatype', - '../Core/Math', - '../Core/Matrix4', - '../Core/WebGLConstants', - '../Renderer/Buffer', - '../Renderer/BufferUsage', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/VertexArrayFacade', - '../Shaders/BillboardCollectionFS', - '../Shaders/BillboardCollectionVS', - './Billboard', - './BlendingState', - './BlendOption', - './HeightReference', - './HorizontalOrigin', - './SceneMode', - './TextureAtlas', - './VerticalOrigin' + '../Core/Event', + '../Core/ReferenceFrame', + './PositionProperty', + './Property', + './SampledProperty' ], function( - AttributeCompression, - BoundingSphere, - Cartesian2, Cartesian3, - Color, - ComponentDatatype, defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - EncodedCartesian3, - IndexDatatype, - CesiumMath, - Matrix4, - WebGLConstants, - Buffer, - BufferUsage, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - VertexArrayFacade, - BillboardCollectionFS, - BillboardCollectionVS, - Billboard, - BlendingState, - BlendOption, - HeightReference, - HorizontalOrigin, - SceneMode, - TextureAtlas, - VerticalOrigin) { + Event, + ReferenceFrame, + PositionProperty, + Property, + SampledProperty) { 'use strict'; - var SHOW_INDEX = Billboard.SHOW_INDEX; - var POSITION_INDEX = Billboard.POSITION_INDEX; - var PIXEL_OFFSET_INDEX = Billboard.PIXEL_OFFSET_INDEX; - var EYE_OFFSET_INDEX = Billboard.EYE_OFFSET_INDEX; - var HORIZONTAL_ORIGIN_INDEX = Billboard.HORIZONTAL_ORIGIN_INDEX; - var VERTICAL_ORIGIN_INDEX = Billboard.VERTICAL_ORIGIN_INDEX; - var SCALE_INDEX = Billboard.SCALE_INDEX; - var IMAGE_INDEX_INDEX = Billboard.IMAGE_INDEX_INDEX; - var COLOR_INDEX = Billboard.COLOR_INDEX; - var ROTATION_INDEX = Billboard.ROTATION_INDEX; - var ALIGNED_AXIS_INDEX = Billboard.ALIGNED_AXIS_INDEX; - var SCALE_BY_DISTANCE_INDEX = Billboard.SCALE_BY_DISTANCE_INDEX; - var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX; - var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX; - var DISTANCE_DISPLAY_CONDITION_INDEX = Billboard.DISTANCE_DISPLAY_CONDITION_INDEX; - var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE; - var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES; - - var attributeLocations; - - var attributeLocationsBatched = { - positionHighAndScale : 0, - positionLowAndRotation : 1, - compressedAttribute0 : 2, // pixel offset, translate, horizontal origin, vertical origin, show, direction, texture coordinates - compressedAttribute1 : 3, // aligned axis, translucency by distance, image width - compressedAttribute2 : 4, // image height, color, pick color, size in meters, valid aligned axis, 13 bits free - eyeOffset : 5, // 4 bytes free - scaleByDistance : 6, - pixelOffsetScaleByDistance : 7, - distanceDisplayConditionAndDisableDepth : 8 - }; - - var attributeLocationsInstanced = { - direction : 0, - positionHighAndScale : 1, - positionLowAndRotation : 2, // texture offset in w - compressedAttribute0 : 3, - compressedAttribute1 : 4, - compressedAttribute2 : 5, - eyeOffset : 6, // texture range in w - scaleByDistance : 7, - pixelOffsetScaleByDistance : 8, - distanceDisplayConditionAndDisableDepth : 9 - }; - /** - * A renderable collection of billboards. Billboards are viewport-aligned - * images positioned in the 3D scene. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.png' width='400' height='300' /><br /> - * Example billboards - * </div> - * <br /><br /> - * Billboards are added and removed from the collection using {@link BillboardCollection#add} - * and {@link BillboardCollection#remove}. Billboards in a collection automatically share textures - * for images with the same identifier. + * A {@link SampledProperty} which is also a {@link PositionProperty}. * - * @alias BillboardCollection + * @alias SampledPositionProperty * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each billboard from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Scene} [options.scene] Must be passed in for billboards that use the height reference property or will be depth tested against the globe. - * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The billboard blending option. The default - * is used for rendering both opaque and translucent billboards. However, if either all of the billboards are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. - * - * @performance For best performance, prefer a few collections, each with many billboards, to - * many collections with only a few billboards each. Organize collections so that billboards - * with the same update frequency are in the same collection, i.e., billboards that do not - * change should be in one collection; billboards that change every frame should be in another - * collection; and so on. - * - * @see BillboardCollection#add - * @see BillboardCollection#remove - * @see Billboard - * @see LabelCollection - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Billboards.html|Cesium Sandcastle Billboard Demo} - * - * @example - * // Create a billboard collection with two billboards - * var billboards = scene.primitives.add(new Cesium.BillboardCollection()); - * billboards.add({ - * position : new Cesium.Cartesian3(1.0, 2.0, 3.0), - * image : 'url/to/image' - * }); - * billboards.add({ - * position : new Cesium.Cartesian3(4.0, 5.0, 6.0), - * image : 'url/to/another/image' - * }); + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + * @param {Number} [numberOfDerivatives=0] The number of derivatives that accompany each position; i.e. velocity, acceleration, etc... */ - function BillboardCollection(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._scene = options.scene; - - this._textureAtlas = undefined; - this._textureAtlasGUID = undefined; - this._destroyTextureAtlas = true; - this._sp = undefined; - this._spTranslucent = undefined; - this._spPick = undefined; - this._rsOpaque = undefined; - this._rsTranslucent = undefined; - this._vaf = undefined; - - this._billboards = []; - this._billboardsToUpdate = []; - this._billboardsToUpdateIndex = 0; - this._billboardsRemoved = false; - this._createVertexArray = false; - - this._shaderRotation = false; - this._compiledShaderRotation = false; - this._compiledShaderRotationPick = false; - - this._shaderAlignedAxis = false; - this._compiledShaderAlignedAxis = false; - this._compiledShaderAlignedAxisPick = false; - - this._shaderScaleByDistance = false; - this._compiledShaderScaleByDistance = false; - this._compiledShaderScaleByDistancePick = false; - - this._shaderTranslucencyByDistance = false; - this._compiledShaderTranslucencyByDistance = false; - this._compiledShaderTranslucencyByDistancePick = false; - - this._shaderPixelOffsetScaleByDistance = false; - this._compiledShaderPixelOffsetScaleByDistance = false; - this._compiledShaderPixelOffsetScaleByDistancePick = false; - - this._shaderDistanceDisplayCondition = false; - this._compiledShaderDistanceDisplayCondition = false; - this._compiledShaderDistanceDisplayConditionPick = false; - - this._shaderDisableDepthDistance = false; - this._compiledShaderDisableDepthDistance = false; - this._compiledShaderDisableDepthDistancePick = false; - - this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); + function SampledPositionProperty(referenceFrame, numberOfDerivatives) { + numberOfDerivatives = defaultValue(numberOfDerivatives, 0); - this._maxSize = 0.0; - this._maxEyeOffset = 0.0; - this._maxScale = 1.0; - this._maxPixelOffset = 0.0; - this._allHorizontalCenter = true; - this._allVerticalCenter = true; - this._allSizedInMeters = true; + var derivativeTypes; + if (numberOfDerivatives > 0) { + derivativeTypes = new Array(numberOfDerivatives); + for (var i = 0; i < numberOfDerivatives; i++) { + derivativeTypes[i] = Cartesian3; + } + } - this._baseVolume = new BoundingSphere(); - this._baseVolumeWC = new BoundingSphere(); - this._baseVolume2D = new BoundingSphere(); - this._boundingVolume = new BoundingSphere(); - this._boundingVolumeDirty = false; + this._numberOfDerivatives = numberOfDerivatives; + this._property = new SampledProperty(Cartesian3, derivativeTypes); + this._definitionChanged = new Event(); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - this._colorCommands = []; - this._pickCommands = []; + this._property._definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); + } + defineProperties(SampledPositionProperty.prototype, { /** - * The 4x4 transformation matrix that transforms each billboard in this collection from model to world coordinates. - * When this is the identity matrix, the billboards are drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. - * - * @type {Matrix4} - * @default {@link Matrix4.IDENTITY} - * - * - * @example - * var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); - * billboards.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - * billboards.add({ - * image : 'url/to/image', - * position : new Cesium.Cartesian3(0.0, 0.0, 0.0) // center - * }); - * billboards.add({ - * image : 'url/to/image', - * position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0) // east - * }); - * billboards.add({ - * image : 'url/to/image', - * position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0) // north - * }); - * billboards.add({ - * image : 'url/to/image', - * position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0) // up - * }); + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof SampledPositionProperty.prototype * - * @see Transforms.eastNorthUpToFixedFrame + * @type {Boolean} + * @readonly */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); - + isConstant : { + get : function() { + return this._property.isConstant; + } + }, /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the primitive. - * </p> - * - * @type {Boolean} + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof SampledPositionProperty.prototype * - * @default false + * @type {Event} + * @readonly */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, /** - * The billboard blending option. The default is used for rendering both opaque and translucent billboards. - * However, if either all of the billboards are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve - * performance by up to 2x. - * @type {BlendOption} - * @default BlendOption.OPAQUE_AND_TRANSLUCENT + * Gets the reference frame in which the position is defined. + * @memberof SampledPositionProperty.prototype + * @type {ReferenceFrame} + * @default ReferenceFrame.FIXED; */ - this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); - this._blendOption = undefined; - - this._mode = SceneMode.SCENE3D; - - // The buffer usage for each attribute is determined based on the usage of the attribute over time. - this._buffersUsage = [ - BufferUsage.STATIC_DRAW, // SHOW_INDEX - BufferUsage.STATIC_DRAW, // POSITION_INDEX - BufferUsage.STATIC_DRAW, // PIXEL_OFFSET_INDEX - BufferUsage.STATIC_DRAW, // EYE_OFFSET_INDEX - BufferUsage.STATIC_DRAW, // HORIZONTAL_ORIGIN_INDEX - BufferUsage.STATIC_DRAW, // VERTICAL_ORIGIN_INDEX - BufferUsage.STATIC_DRAW, // SCALE_INDEX - BufferUsage.STATIC_DRAW, // IMAGE_INDEX_INDEX - BufferUsage.STATIC_DRAW, // COLOR_INDEX - BufferUsage.STATIC_DRAW, // ROTATION_INDEX - BufferUsage.STATIC_DRAW, // ALIGNED_AXIS_INDEX - BufferUsage.STATIC_DRAW, // SCALE_BY_DISTANCE_INDEX - BufferUsage.STATIC_DRAW, // TRANSLUCENCY_BY_DISTANCE_INDEX - BufferUsage.STATIC_DRAW, // PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX - BufferUsage.STATIC_DRAW // DISTANCE_DISPLAY_CONDITION_INDEX - ]; - - var that = this; - this._uniforms = { - u_atlas : function() { - return that._textureAtlas.texture; + referenceFrame : { + get : function() { + return this._referenceFrame; } - }; - - var scene = this._scene; - if (defined(scene) && defined(scene.terrainProviderChanged)) { - this._removeCallbackFunc = scene.terrainProviderChanged.addEventListener(function() { - var billboards = this._billboards; - var length = billboards.length; - for (var i=0;i<length;++i) { - billboards[i]._updateClamping(); - } - }, this); - } - } - - defineProperties(BillboardCollection.prototype, { + }, /** - * Returns the number of billboards in this collection. This is commonly used with - * {@link BillboardCollection#get} to iterate over all the billboards - * in the collection. - * @memberof BillboardCollection.prototype + * Gets the degree of interpolation to perform when retrieving a value. + * @memberof SampledPositionProperty.prototype + * * @type {Number} + * @default 1 */ - length : { + interpolationDegree : { get : function() { - removeBillboards(this); - return this._billboards.length; + return this._property.interpolationDegree; } }, - /** - * Gets or sets the textureAtlas. - * @memberof BillboardCollection.prototype - * @type {TextureAtlas} - * @private + * Gets the interpolation algorithm to use when retrieving a value. + * @memberof SampledPositionProperty.prototype + * + * @type {InterpolationAlgorithm} + * @default LinearApproximation */ - textureAtlas : { + interpolationAlgorithm : { get : function() { - return this._textureAtlas; - }, - set : function(value) { - if (this._textureAtlas !== value) { - this._textureAtlas = this._destroyTextureAtlas && this._textureAtlas && this._textureAtlas.destroy(); - this._textureAtlas = value; - this._createVertexArray = true; // New per-billboard texture coordinates - } + return this._property.interpolationAlgorithm; } }, - /** - * Gets or sets a value which determines if the texture atlas is - * destroyed when the collection is destroyed. - * - * If the texture atlas is used by more than one collection, set this to <code>false</code>, - * and explicitly destroy the atlas to avoid attempting to destroy it multiple times. + * The number of derivatives contained by this property; i.e. 0 for just position, 1 for velocity, etc. + * @memberof SampledPositionProperty.prototype * - * @memberof BillboardCollection.prototype * @type {Boolean} - * @private - * - * @example - * // Set destroyTextureAtlas - * // Destroy a billboard collection but not its texture atlas. - * - * var atlas = new TextureAtlas({ - * scene : scene, - * images : images - * }); - * billboards.textureAtlas = atlas; - * billboards.destroyTextureAtlas = false; - * billboards = billboards.destroy(); - * console.log(atlas.isDestroyed()); // False + * @default false */ - destroyTextureAtlas : { + numberOfDerivatives : { get : function() { - return this._destroyTextureAtlas; + return this._numberOfDerivatives; + } + }, + /** + * Gets or sets the type of extrapolation to perform when a value + * is requested at a time after any available samples. + * @memberof SampledPositionProperty.prototype + * @type {ExtrapolationType} + * @default ExtrapolationType.NONE + */ + forwardExtrapolationType : { + get : function() { + return this._property.forwardExtrapolationType; }, set : function(value) { - this._destroyTextureAtlas = value; + this._property.forwardExtrapolationType = value; } - } - }); - - function destroyBillboards(billboards) { - var length = billboards.length; - for (var i = 0; i < length; ++i) { - if (billboards[i]) { - billboards[i]._destroy(); + }, + /** + * Gets or sets the amount of time to extrapolate forward before + * the property becomes undefined. A value of 0 will extrapolate forever. + * @memberof SampledPositionProperty.prototype + * @type {Number} + * @default 0 + */ + forwardExtrapolationDuration : { + get : function() { + return this._property.forwardExtrapolationDuration; + }, + set : function(value) { + this._property.forwardExtrapolationDuration = value; } - } - } - - /** - * Creates and adds a billboard with the specified initial properties to the collection. - * The added billboard is returned so it can be modified or removed from the collection later. - * - * @param {Object}[billboard] A template describing the billboard's properties as shown in Example 1. - * @returns {Billboard} The billboard that was added to the collection. - * - * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer - * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For - * best performance, add as many billboards as possible before calling <code>update</code>. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Example 1: Add a billboard, specifying all the default values. - * var b = billboards.add({ - * show : true, - * position : Cesium.Cartesian3.ZERO, - * pixelOffset : Cesium.Cartesian2.ZERO, - * eyeOffset : Cesium.Cartesian3.ZERO, - * heightReference : Cesium.HeightReference.NONE, - * horizontalOrigin : Cesium.HorizontalOrigin.CENTER, - * verticalOrigin : Cesium.VerticalOrigin.CENTER, - * scale : 1.0, - * image : 'url/to/image', - * imageSubRegion : undefined, - * color : Cesium.Color.WHITE, - * id : undefined, - * rotation : 0.0, - * alignedAxis : Cesium.Cartesian3.ZERO, - * width : undefined, - * height : undefined, - * scaleByDistance : undefined, - * translucencyByDistance : undefined, - * pixelOffsetScaleByDistance : undefined, - * sizeInMeters : false, - * distanceDisplayCondition : undefined - * }); - * - * @example - * // Example 2: Specify only the billboard's cartographic position. - * var b = billboards.add({ - * position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height) - * }); - * - * @see BillboardCollection#remove - * @see BillboardCollection#removeAll - */ - BillboardCollection.prototype.add = function(billboard) { - var b = new Billboard(billboard, this); - b._index = this._billboards.length; - - this._billboards.push(b); - this._createVertexArray = true; - - return b; - }; - - /** - * Removes a billboard from the collection. - * - * @param {Billboard} billboard The billboard to remove. - * @returns {Boolean} <code>true</code> if the billboard was removed; <code>false</code> if the billboard was not found in the collection. - * - * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer - * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For - * best performance, remove as many billboards as possible before calling <code>update</code>. - * If you intend to temporarily hide a billboard, it is usually more efficient to call - * {@link Billboard#show} instead of removing and re-adding the billboard. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * var b = billboards.add(...); - * billboards.remove(b); // Returns true - * - * @see BillboardCollection#add - * @see BillboardCollection#removeAll - * @see Billboard#show - */ - BillboardCollection.prototype.remove = function(billboard) { - if (this.contains(billboard)) { - this._billboards[billboard._index] = null; // Removed later - this._billboardsRemoved = true; - this._createVertexArray = true; - billboard._destroy(); - return true; - } - - return false; - }; - - /** - * Removes all billboards from the collection. - * - * @performance <code>O(n)</code>. It is more efficient to remove all the billboards - * from a collection and then add new ones than to create a new collection entirely. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * billboards.add(...); - * billboards.add(...); - * billboards.removeAll(); - * - * @see BillboardCollection#add - * @see BillboardCollection#remove - */ - BillboardCollection.prototype.removeAll = function() { - destroyBillboards(this._billboards); - this._billboards = []; - this._billboardsToUpdate = []; - this._billboardsToUpdateIndex = 0; - this._billboardsRemoved = false; - - this._createVertexArray = true; - }; - - function removeBillboards(billboardCollection) { - if (billboardCollection._billboardsRemoved) { - billboardCollection._billboardsRemoved = false; - - var newBillboards = []; - var billboards = billboardCollection._billboards; - var length = billboards.length; - for (var i = 0, j = 0; i < length; ++i) { - var billboard = billboards[i]; - if (billboard) { - billboard._index = j++; - newBillboards.push(billboard); - } + }, + /** + * Gets or sets the type of extrapolation to perform when a value + * is requested at a time before any available samples. + * @memberof SampledPositionProperty.prototype + * @type {ExtrapolationType} + * @default ExtrapolationType.NONE + */ + backwardExtrapolationType : { + get : function() { + return this._property.backwardExtrapolationType; + }, + set : function(value) { + this._property.backwardExtrapolationType = value; + } + }, + /** + * Gets or sets the amount of time to extrapolate backward + * before the property becomes undefined. A value of 0 will extrapolate forever. + * @memberof SampledPositionProperty.prototype + * @type {Number} + * @default 0 + */ + backwardExtrapolationDuration : { + get : function() { + return this._property.backwardExtrapolationDuration; + }, + set : function(value) { + this._property.backwardExtrapolationDuration = value; } - - billboardCollection._billboards = newBillboards; - } - } - - BillboardCollection.prototype._updateBillboard = function(billboard, propertyChanged) { - if (!billboard._dirty) { - this._billboardsToUpdate[this._billboardsToUpdateIndex++] = billboard; } - - ++this._propertiesChanged[propertyChanged]; - }; + }); /** - * Check whether this collection contains a given billboard. - * - * @param {Billboard} [billboard] The billboard to check for. - * @returns {Boolean} true if this collection contains the billboard, false otherwise. + * Gets the position at the provided time. * - * @see BillboardCollection#get + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. */ - BillboardCollection.prototype.contains = function(billboard) { - return defined(billboard) && billboard._billboardCollection === this; + SampledPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); }; /** - * Returns the billboard in the collection at the specified index. Indices are zero-based - * and increase as billboards are added. Removing a billboard shifts all billboards after - * it to the left, changing their indices. This function is commonly used with - * {@link BillboardCollection#length} to iterate over all the billboards - * in the collection. - * - * @param {Number} index The zero-based index of the billboard. - * @returns {Billboard} The billboard at the specified index. - * - * @performance Expected constant time. If billboards were removed from the collection and - * {@link BillboardCollection#update} was not called, an implicit <code>O(n)</code> - * operation is performed. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Toggle the show property of every billboard in the collection - * var len = billboards.length; - * for (var i = 0; i < len; ++i) { - * var b = billboards.get(i); - * b.show = !b.show; - * } + * Gets the position at the provided time and in the provided reference frame. * - * @see BillboardCollection#length + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. */ - BillboardCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - removeBillboards(this); - return this._billboards[index]; - }; - - var getIndexBuffer; - - function getIndexBufferBatched(context) { - var sixteenK = 16 * 1024; - - var indexBuffer = context.cache.billboardCollection_indexBufferBatched; - if (defined(indexBuffer)) { - return indexBuffer; + SampledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - - // Subtract 6 because the last index is reserverd for primitive restart. - // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.18 - var length = sixteenK * 6 - 6; - var indices = new Uint16Array(length); - for (var i = 0, j = 0; i < length; i += 6, j += 4) { - indices[i] = j; - indices[i + 1] = j + 1; - indices[i + 2] = j + 2; - - indices[i + 3] = j + 0; - indices[i + 4] = j + 2; - indices[i + 5] = j + 3; + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); } - - // PERFORMANCE_IDEA: Should we reference count billboard collections, and eventually delete this? - // Is this too much memory to allocate up front? Should we dynamically grow it? - indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : indices, - usage : BufferUsage.STATIC_DRAW, - indexDatatype : IndexDatatype.UNSIGNED_SHORT - }); - indexBuffer.vertexArrayDestroyable = false; - context.cache.billboardCollection_indexBufferBatched = indexBuffer; - return indexBuffer; - } - - function getIndexBufferInstanced(context) { - var indexBuffer = context.cache.billboardCollection_indexBufferInstanced; - if (defined(indexBuffer)) { - return indexBuffer; + + result = this._property.getValue(time, result); + if (defined(result)) { + return PositionProperty.convertToReferenceFrame(time, result, this._referenceFrame, referenceFrame, result); } + return undefined; + }; - indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : new Uint16Array([0, 1, 2, 0, 2, 3]), - usage : BufferUsage.STATIC_DRAW, - indexDatatype : IndexDatatype.UNSIGNED_SHORT - }); - - indexBuffer.vertexArrayDestroyable = false; - context.cache.billboardCollection_indexBufferInstanced = indexBuffer; - return indexBuffer; - } + /** + * Sets the algorithm and degree to use when interpolating a position. + * + * @param {Object} [options] Object with the following properties: + * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. + * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + */ + SampledPositionProperty.prototype.setInterpolationOptions = function(options) { + this._property.setInterpolationOptions(options); + }; - function getVertexBufferInstanced(context) { - var vertexBuffer = context.cache.billboardCollection_vertexBufferInstanced; - if (defined(vertexBuffer)) { - return vertexBuffer; + /** + * Adds a new sample. + * + * @param {JulianDate} time The sample time. + * @param {Cartesian3} position The position at the provided time. + * @param {Cartesian3[]} [derivatives] The array of derivative values at the provided time. + */ + SampledPositionProperty.prototype.addSample = function(time, position, derivatives) { + var numberOfDerivatives = this._numberOfDerivatives; + if (numberOfDerivatives > 0 && (!defined(derivatives) || derivatives.length !== numberOfDerivatives)) { + throw new DeveloperError('derivatives length must be equal to the number of derivatives.'); } + this._property.addSample(time, position, derivatives); + }; - vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : new Float32Array([0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]), - usage : BufferUsage.STATIC_DRAW - }); - - vertexBuffer.vertexArrayDestroyable = false; - context.cache.billboardCollection_vertexBufferInstanced = vertexBuffer; - return vertexBuffer; - } - - BillboardCollection.prototype.computeNewBuffersUsage = function() { - var buffersUsage = this._buffersUsage; - var usageChanged = false; + /** + * Adds multiple samples via parallel arrays. + * + * @param {JulianDate[]} times An array of JulianDate instances where each index is a sample time. + * @param {Cartesian3[]} positions An array of Cartesian3 position instances, where each value corresponds to the provided time index. + * @param {Array[]} [derivatives] An array where each value is another array containing derivatives for the corresponding time index. + * + * @exception {DeveloperError} All arrays must be the same length. + */ + SampledPositionProperty.prototype.addSamples = function(times, positions, derivatives) { + this._property.addSamples(times, positions, derivatives); + }; - var properties = this._propertiesChanged; - for ( var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { - var newUsage = (properties[k] === 0) ? BufferUsage.STATIC_DRAW : BufferUsage.STREAM_DRAW; - usageChanged = usageChanged || (buffersUsage[k] !== newUsage); - buffersUsage[k] = newUsage; - } + /** + * Adds samples as a single packed array where each new sample is represented as a date, + * followed by the packed representation of the corresponding value and derivatives. + * + * @param {Number[]} packedSamples The array of packed samples. + * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. + */ + SampledPositionProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) { + this._property.addSamplesPackedArray(packedSamples, epoch); + }; - return usageChanged; + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + SampledPositionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof SampledPositionProperty && + Property.equals(this._property, other._property) && // + this._referenceFrame === other._referenceFrame); }; - function createVAF(context, numberOfBillboards, buffersUsage, instanced) { - var attributes = [{ - index : attributeLocations.positionHighAndScale, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[POSITION_INDEX] - }, { - index : attributeLocations.positionLowAndRotation, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[POSITION_INDEX] - }, { - index : attributeLocations.compressedAttribute0, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[PIXEL_OFFSET_INDEX] - }, { - index : attributeLocations.compressedAttribute1, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[TRANSLUCENCY_BY_DISTANCE_INDEX] - }, { - index : attributeLocations.compressedAttribute2, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[COLOR_INDEX] - }, { - index : attributeLocations.eyeOffset, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[EYE_OFFSET_INDEX] - }, { - index : attributeLocations.scaleByDistance, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[SCALE_BY_DISTANCE_INDEX] - }, { - index : attributeLocations.pixelOffsetScaleByDistance, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX] - }, { - index : attributeLocations.distanceDisplayConditionAndDisableDepth, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] - }]; + return SampledPositionProperty; +}); - // Instancing requires one non-instanced attribute. - if (instanced) { - attributes.push({ - index : attributeLocations.direction, - componentsPerAttribute : 2, - componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : getVertexBufferInstanced(context) - }); - } +define('DataSources/StripeOrientation',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - // When instancing is enabled, only one vertex is needed for each billboard. - var sizeInVertices = instanced ? numberOfBillboards : 4 * numberOfBillboards; - return new VertexArrayFacade(context, attributes, sizeInVertices, instanced); - } + /** + * Defined the orientation of stripes in {@link StripeMaterialProperty}. + * + * @exports StripeOrientation + */ + var StripeOrientation = { + /** + * Horizontal orientation. + * @type {Number} + */ + HORIZONTAL : 0, - /////////////////////////////////////////////////////////////////////////// + /** + * Vertical orientation. + * @type {Number} + */ + VERTICAL : 1 + }; - // Four vertices per billboard. Each has the same position, etc., but a different screen-space direction vector. + return freezeObject(StripeOrientation); +}); - // PERFORMANCE_IDEA: Save memory if a property is the same for all billboards, use a latched attribute state, - // instead of storing it in a vertex buffer. +define('DataSources/StripeMaterialProperty',[ + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Event', + './createPropertyDescriptor', + './Property', + './StripeOrientation' + ], function( + Color, + defaultValue, + defined, + defineProperties, + Event, + createPropertyDescriptor, + Property, + StripeOrientation) { + 'use strict'; - var writePositionScratch = new EncodedCartesian3(); + var defaultOrientation = StripeOrientation.HORIZONTAL; + var defaultEvenColor = Color.WHITE; + var defaultOddColor = Color.BLACK; + var defaultOffset = 0; + var defaultRepeat = 1; - function writePositionScaleAndRotation(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var positionHighWriter = vafWriters[attributeLocations.positionHighAndScale]; - var positionLowWriter = vafWriters[attributeLocations.positionLowAndRotation]; - var position = billboard._getActualPosition(); + /** + * A {@link MaterialProperty} that maps to stripe {@link Material} uniforms. + * @alias StripeMaterialProperty + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Property} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}. + * @param {Property} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}. + * @param {Property} [options.repeat=1] A numeric Property specifying how many times the stripes repeat. + * @param {Property} [options.offset=0] A numeric Property specifying how far into the pattern to start the material. + * @param {Property} [options.orientation=StripeOrientation.HORIZONTAL] A Property specifying the {@link StripeOrientation}. + */ + function StripeMaterialProperty(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (billboardCollection._mode === SceneMode.SCENE3D) { - BoundingSphere.expand(billboardCollection._baseVolume, position, billboardCollection._baseVolume); - billboardCollection._boundingVolumeDirty = true; - } + this._definitionChanged = new Event(); - EncodedCartesian3.fromCartesian(position, writePositionScratch); - var scale = billboard.scale; - var rotation = billboard.rotation; + this._orientation = undefined; + this._orientationSubscription = undefined; - if (rotation !== 0.0) { - billboardCollection._shaderRotation = true; - } + this._evenColor = undefined; + this._evenColorSubscription = undefined; - billboardCollection._maxScale = Math.max(billboardCollection._maxScale, scale); + this._oddColor = undefined; + this._oddColorSubscription = undefined; - var high = writePositionScratch.high; - var low = writePositionScratch.low; + this._offset = undefined; + this._offsetSubscription = undefined; - if (billboardCollection._instanced) { - i = billboard._index; - positionHighWriter(i, high.x, high.y, high.z, scale); - positionLowWriter(i, low.x, low.y, low.z, rotation); - } else { - i = billboard._index * 4; - positionHighWriter(i + 0, high.x, high.y, high.z, scale); - positionHighWriter(i + 1, high.x, high.y, high.z, scale); - positionHighWriter(i + 2, high.x, high.y, high.z, scale); - positionHighWriter(i + 3, high.x, high.y, high.z, scale); + this._repeat = undefined; + this._repeatSubscription = undefined; - positionLowWriter(i + 0, low.x, low.y, low.z, rotation); - positionLowWriter(i + 1, low.x, low.y, low.z, rotation); - positionLowWriter(i + 2, low.x, low.y, low.z, rotation); - positionLowWriter(i + 3, low.x, low.y, low.z, rotation); - } + this.orientation = options.orientation; + this.evenColor = options.evenColor; + this.oddColor = options.oddColor; + this.offset = options.offset; + this.repeat = options.repeat; } - var scratchCartesian2 = new Cartesian2(); - - var UPPER_BOUND = 32768.0; // 2^15 - - var LEFT_SHIFT16 = 65536.0; // 2^16 - var LEFT_SHIFT8 = 256.0; // 2^8 - var LEFT_SHIFT7 = 128.0; - var LEFT_SHIFT5 = 32.0; - var LEFT_SHIFT3 = 8.0; - var LEFT_SHIFT2 = 4.0; - - var RIGHT_SHIFT8 = 1.0 / 256.0; - - var LOWER_LEFT = 0.0; - var LOWER_RIGHT = 2.0; - var UPPER_RIGHT = 3.0; - var UPPER_LEFT = 1.0; - - function writeCompressedAttrib0(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.compressedAttribute0]; - var pixelOffset = billboard.pixelOffset; - var pixelOffsetX = pixelOffset.x; - var pixelOffsetY = pixelOffset.y; - - var translate = billboard._translate; - var translateX = translate.x; - var translateY = translate.y; - - billboardCollection._maxPixelOffset = Math.max(billboardCollection._maxPixelOffset, Math.abs(pixelOffsetX + translateX), Math.abs(-pixelOffsetY + translateY)); - - var horizontalOrigin = billboard.horizontalOrigin; - var verticalOrigin = billboard._verticalOrigin; - var show = billboard.show && billboard.clusterShow; - - // If the color alpha is zero, do not show this billboard. This lets us avoid providing - // color during the pick pass and also eliminates a discard in the fragment shader. - if (billboard.color.alpha === 0.0) { - show = false; - } - - // Raw billboards don't distinguish between BASELINE and BOTTOM, only LabelCollection does that. - if (verticalOrigin === VerticalOrigin.BASELINE) { - verticalOrigin = VerticalOrigin.BOTTOM; - } - - billboardCollection._allHorizontalCenter = billboardCollection._allHorizontalCenter && horizontalOrigin === HorizontalOrigin.CENTER; - billboardCollection._allVerticalCenter = billboardCollection._allVerticalCenter && verticalOrigin === VerticalOrigin.CENTER; - - var bottomLeftX = 0; - var bottomLeftY = 0; - var width = 0; - var height = 0; - var index = billboard._imageIndex; - if (index !== -1) { - var imageRectangle = textureAtlasCoordinates[index]; - - if (!defined(imageRectangle)) { - throw new DeveloperError('Invalid billboard image index: ' + index); + defineProperties(StripeMaterialProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof StripeMaterialProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._orientation) && // + Property.isConstant(this._evenColor) && // + Property.isConstant(this._oddColor) && // + Property.isConstant(this._offset) && // + Property.isConstant(this._repeat); } - - bottomLeftX = imageRectangle.x; - bottomLeftY = imageRectangle.y; - width = imageRectangle.width; - height = imageRectangle.height; - } - var topRightX = bottomLeftX + width; - var topRightY = bottomLeftY + height; + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof StripeMaterialProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets or sets the Property specifying the {@link StripeOrientation}/ + * @memberof StripeMaterialProperty.prototype + * @type {Property} + * @default StripeOrientation.HORIZONTAL + */ + orientation : createPropertyDescriptor('orientation'), + /** + * Gets or sets the Property specifying the first {@link Color}. + * @memberof StripeMaterialProperty.prototype + * @type {Property} + * @default Color.WHITE + */ + evenColor : createPropertyDescriptor('evenColor'), + /** + * Gets or sets the Property specifying the second {@link Color}. + * @memberof StripeMaterialProperty.prototype + * @type {Property} + * @default Color.BLACK + */ + oddColor : createPropertyDescriptor('oddColor'), + /** + * Gets or sets the numeric Property specifying the point into the pattern + * to begin drawing; with 0.0 being the beginning of the even color, 1.0 the beginning + * of the odd color, 2.0 being the even color again, and any multiple or fractional values + * being in between. + * @memberof StripeMaterialProperty.prototype + * @type {Property} + * @default 0.0 + */ + offset : createPropertyDescriptor('offset'), + /** + * Gets or sets the numeric Property specifying how many times the stripes repeat. + * @memberof StripeMaterialProperty.prototype + * @type {Property} + * @default 1.0 + */ + repeat : createPropertyDescriptor('repeat') + }); - var compressed0 = Math.floor(CesiumMath.clamp(pixelOffsetX, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * LEFT_SHIFT7; - compressed0 += (horizontalOrigin + 1.0) * LEFT_SHIFT5; - compressed0 += (verticalOrigin + 1.0) * LEFT_SHIFT3; - compressed0 += (show ? 1.0 : 0.0) * LEFT_SHIFT2; + /** + * Gets the {@link Material} type at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the type. + * @returns {String} The type of material. + */ + StripeMaterialProperty.prototype.getType = function(time) { + return 'Stripe'; + }; - var compressed1 = Math.floor(CesiumMath.clamp(pixelOffsetY, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * LEFT_SHIFT8; - var compressed2 = Math.floor(CesiumMath.clamp(translateX, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * LEFT_SHIFT8; + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + StripeMaterialProperty.prototype.getValue = function(time, result) { + if (!defined(result)) { + result = {}; + } + result.horizontal = Property.getValueOrDefault(this._orientation, time, defaultOrientation) === StripeOrientation.HORIZONTAL; + result.evenColor = Property.getValueOrClonedDefault(this._evenColor, time, defaultEvenColor, result.evenColor); + result.oddColor = Property.getValueOrClonedDefault(this._oddColor, time, defaultOddColor, result.oddColor); + result.offset = Property.getValueOrDefault(this._offset, time, defaultOffset); + result.repeat = Property.getValueOrDefault(this._repeat, time, defaultRepeat); + return result; + }; - var tempTanslateY = (CesiumMath.clamp(translateY, -UPPER_BOUND, UPPER_BOUND) + UPPER_BOUND) * RIGHT_SHIFT8; - var upperTranslateY = Math.floor(tempTanslateY); - var lowerTranslateY = Math.floor((tempTanslateY - upperTranslateY) * LEFT_SHIFT8); + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + StripeMaterialProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof StripeMaterialProperty && // + Property.equals(this._orientation, other._orientation) && // + Property.equals(this._evenColor, other._evenColor) && // + Property.equals(this._oddColor, other._oddColor) && // + Property.equals(this._offset, other._offset) && // + Property.equals(this._repeat, other._repeat)); + }; - compressed1 += upperTranslateY; - compressed2 += lowerTranslateY; + return StripeMaterialProperty; +}); - scratchCartesian2.x = bottomLeftX; - scratchCartesian2.y = bottomLeftY; - var compressedTexCoordsLL = AttributeCompression.compressTextureCoordinates(scratchCartesian2); - scratchCartesian2.x = topRightX; - var compressedTexCoordsLR = AttributeCompression.compressTextureCoordinates(scratchCartesian2); - scratchCartesian2.y = topRightY; - var compressedTexCoordsUR = AttributeCompression.compressTextureCoordinates(scratchCartesian2); - scratchCartesian2.x = bottomLeftX; - var compressedTexCoordsUL = AttributeCompression.compressTextureCoordinates(scratchCartesian2); +define('DataSources/TimeIntervalCollectionPositionProperty',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/ReferenceFrame', + '../Core/TimeIntervalCollection', + './PositionProperty', + './Property' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + ReferenceFrame, + TimeIntervalCollection, + PositionProperty, + Property) { + 'use strict'; - if (billboardCollection._instanced) { - i = billboard._index; - writer(i, compressed0, compressed1, compressed2, compressedTexCoordsLL); - } else { - i = billboard._index * 4; - writer(i + 0, compressed0 + LOWER_LEFT, compressed1, compressed2, compressedTexCoordsLL); - writer(i + 1, compressed0 + LOWER_RIGHT, compressed1, compressed2, compressedTexCoordsLR); - writer(i + 2, compressed0 + UPPER_RIGHT, compressed1, compressed2, compressedTexCoordsUR); - writer(i + 3, compressed0 + UPPER_LEFT, compressed1, compressed2, compressedTexCoordsUL); - } + /** + * A {@link TimeIntervalCollectionProperty} which is also a {@link PositionProperty}. + * + * @alias TimeIntervalCollectionPositionProperty + * @constructor + * + * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. + */ + function TimeIntervalCollectionPositionProperty(referenceFrame) { + this._definitionChanged = new Event(); + this._intervals = new TimeIntervalCollection(); + this._intervals.changedEvent.addEventListener(TimeIntervalCollectionPositionProperty.prototype._intervalsChanged, this); + this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); } - function writeCompressedAttrib1(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.compressedAttribute1]; - var alignedAxis = billboard.alignedAxis; - if (!Cartesian3.equals(alignedAxis, Cartesian3.ZERO)) { - billboardCollection._shaderAlignedAxis = true; - } - - var near = 0.0; - var nearValue = 1.0; - var far = 1.0; - var farValue = 1.0; - - var translucency = billboard.translucencyByDistance; - if (defined(translucency)) { - near = translucency.near; - nearValue = translucency.nearValue; - far = translucency.far; - farValue = translucency.farValue; - - if (nearValue !== 1.0 || farValue !== 1.0) { - // translucency by distance calculation in shader need not be enabled - // until a billboard with near and far !== 1.0 is found - billboardCollection._shaderTranslucencyByDistance = true; + defineProperties(TimeIntervalCollectionPositionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return this._intervals.isEmpty; } - } - - var width = 0; - var index = billboard._imageIndex; - if (index !== -1) { - var imageRectangle = textureAtlasCoordinates[index]; - - if (!defined(imageRectangle)) { - throw new DeveloperError('Invalid billboard image index: ' + index); + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is considered to have changed if a call to getValue would return + * a different result for the same time. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._intervals; + } + }, + /** + * Gets the reference frame in which the position is defined. + * @memberof TimeIntervalCollectionPositionProperty.prototype + * @type {ReferenceFrame} + * @default ReferenceFrame.FIXED; + */ + referenceFrame : { + get : function() { + return this._referenceFrame; } - - width = imageRectangle.width; } + }); - var textureWidth = billboardCollection._textureAtlas.texture.width; - var imageWidth = Math.round(defaultValue(billboard.width, textureWidth * width)); - billboardCollection._maxSize = Math.max(billboardCollection._maxSize, imageWidth); - - var compressed0 = CesiumMath.clamp(imageWidth, 0.0, LEFT_SHIFT16); - var compressed1 = 0.0; + /** + * Gets the value of the property at the provided time in the fixed frame. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + TimeIntervalCollectionPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; - if (Math.abs(Cartesian3.magnitudeSquared(alignedAxis) - 1.0) < CesiumMath.EPSILON6) { - compressed1 = AttributeCompression.octEncodeFloat(alignedAxis); + /** + * Gets the value of the property at the provided time and in the provided reference frame. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + TimeIntervalCollectionPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - - nearValue = CesiumMath.clamp(nearValue, 0.0, 1.0); - nearValue = nearValue === 1.0 ? 255.0 : (nearValue * 255.0) | 0; - compressed0 = compressed0 * LEFT_SHIFT8 + nearValue; - - farValue = CesiumMath.clamp(farValue, 0.0, 1.0); - farValue = farValue === 1.0 ? 255.0 : (farValue * 255.0) | 0; - compressed1 = compressed1 * LEFT_SHIFT8 + farValue; - - if (billboardCollection._instanced) { - i = billboard._index; - writer(i, compressed0, compressed1, near, far); - } else { - i = billboard._index * 4; - writer(i + 0, compressed0, compressed1, near, far); - writer(i + 1, compressed0, compressed1, near, far); - writer(i + 2, compressed0, compressed1, near, far); - writer(i + 3, compressed0, compressed1, near, far); + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); } - } - - function writeCompressedAttrib2(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.compressedAttribute2]; - var color = billboard.color; - var pickColor = billboard.getPickId(context).color; - var sizeInMeters = billboard.sizeInMeters ? 1.0 : 0.0; - var validAlignedAxis = Math.abs(Cartesian3.magnitudeSquared(billboard.alignedAxis) - 1.0) < CesiumMath.EPSILON6 ? 1.0 : 0.0; - - billboardCollection._allSizedInMeters = billboardCollection._allSizedInMeters && sizeInMeters === 1.0; - - var height = 0; - var index = billboard._imageIndex; - if (index !== -1) { - var imageRectangle = textureAtlasCoordinates[index]; - - if (!defined(imageRectangle)) { - throw new DeveloperError('Invalid billboard image index: ' + index); - } - - height = imageRectangle.height; + + var position = this._intervals.findDataForIntervalContainingDate(time); + if (defined(position)) { + return PositionProperty.convertToReferenceFrame(time, position, this._referenceFrame, referenceFrame, result); } + return undefined; + }; - var dimensions = billboardCollection._textureAtlas.texture.dimensions; - var imageHeight = Math.round(defaultValue(billboard.height, dimensions.y * height)); - billboardCollection._maxSize = Math.max(billboardCollection._maxSize, imageHeight); + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + TimeIntervalCollectionPositionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof TimeIntervalCollectionPositionProperty && // + this._intervals.equals(other._intervals, Property.equals) && // + this._referenceFrame === other._referenceFrame); + }; - var red = Color.floatToByte(color.red); - var green = Color.floatToByte(color.green); - var blue = Color.floatToByte(color.blue); - var compressed0 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + /** + * @private + */ + TimeIntervalCollectionPositionProperty.prototype._intervalsChanged = function() { + this._definitionChanged.raiseEvent(this); + }; - red = Color.floatToByte(pickColor.red); - green = Color.floatToByte(pickColor.green); - blue = Color.floatToByte(pickColor.blue); - var compressed1 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + return TimeIntervalCollectionPositionProperty; +}); - var compressed2 = Color.floatToByte(color.alpha) * LEFT_SHIFT16 + Color.floatToByte(pickColor.alpha) * LEFT_SHIFT8; - compressed2 += sizeInMeters * 2.0 + validAlignedAxis; +define('DataSources/TimeIntervalCollectionProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/TimeIntervalCollection', + './Property' + ], function( + defined, + defineProperties, + DeveloperError, + Event, + TimeIntervalCollection, + Property) { + 'use strict'; - if (billboardCollection._instanced) { - i = billboard._index; - writer(i, compressed0, compressed1, compressed2, imageHeight); - } else { - i = billboard._index * 4; - writer(i + 0, compressed0, compressed1, compressed2, imageHeight); - writer(i + 1, compressed0, compressed1, compressed2, imageHeight); - writer(i + 2, compressed0, compressed1, compressed2, imageHeight); - writer(i + 3, compressed0, compressed1, compressed2, imageHeight); - } + /** + * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the + * data property of each {@link TimeInterval} represents the value at time. + * + * @alias TimeIntervalCollectionProperty + * @constructor + * + * @example + * //Create a Cartesian2 interval property which contains data on August 1st, 2012 + * //and uses a different value every 6 hours. + * var composite = new Cesium.TimeIntervalCollectionProperty(); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', + * isStartIncluded : true, + * isStopIncluded : false, + * data : new Cesium.Cartesian2(2.0, 3.4) + * })); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', + * isStartIncluded : true, + * isStopIncluded : false, + * data : new Cesium.Cartesian2(12.0, 2.7) + * })); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2012-08-01T12:00:00.00Z/2012-08-01T18:00:00.00Z', + * isStartIncluded : true, + * isStopIncluded : false, + * data : new Cesium.Cartesian2(5.0, 12.4) + * })); + * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ + * iso8601 : '2012-08-01T18:00:00.00Z/2012-08-02T00:00:00.00Z', + * isStartIncluded : true, + * isStopIncluded : true, + * data : new Cesium.Cartesian2(85.0, 4.1) + * })); + */ + function TimeIntervalCollectionProperty() { + this._definitionChanged = new Event(); + this._intervals = new TimeIntervalCollection(); + this._intervals.changedEvent.addEventListener(TimeIntervalCollectionProperty.prototype._intervalsChanged, this); } - function writeEyeOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.eyeOffset]; - var eyeOffset = billboard.eyeOffset; - - // For billboards that are clamped to ground, move it slightly closer to the camera - var eyeOffsetZ = eyeOffset.z; - if (billboard._heightReference !== HeightReference.NONE) { - eyeOffsetZ *= 1.005; - } - billboardCollection._maxEyeOffset = Math.max(billboardCollection._maxEyeOffset, Math.abs(eyeOffset.x), Math.abs(eyeOffset.y), Math.abs(eyeOffsetZ)); - - if (billboardCollection._instanced) { - var width = 0; - var height = 0; - var index = billboard._imageIndex; - if (index !== -1) { - var imageRectangle = textureAtlasCoordinates[index]; - - if (!defined(imageRectangle)) { - throw new DeveloperError('Invalid billboard image index: ' + index); - } - - width = imageRectangle.width; - height = imageRectangle.height; + defineProperties(TimeIntervalCollectionProperty.prototype, { + /** + * Gets a value indicating if this property is constant. A property is considered + * constant if getValue always returns the same result for the current definition. + * @memberof TimeIntervalCollectionProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return this._intervals.isEmpty; } - - scratchCartesian2.x = width; - scratchCartesian2.y = height; - var compressedTexCoordsRange = AttributeCompression.compressTextureCoordinates(scratchCartesian2); - - i = billboard._index; - writer(i, eyeOffset.x, eyeOffset.y, eyeOffsetZ, compressedTexCoordsRange); - } else { - i = billboard._index * 4; - writer(i + 0, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); - writer(i + 1, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); - writer(i + 2, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); - writer(i + 3, eyeOffset.x, eyeOffset.y, eyeOffsetZ, 0.0); - } - } - - function writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.scaleByDistance]; - var near = 0.0; - var nearValue = 1.0; - var far = 1.0; - var farValue = 1.0; - - var scale = billboard.scaleByDistance; - if (defined(scale)) { - near = scale.near; - nearValue = scale.nearValue; - far = scale.far; - farValue = scale.farValue; - - if (nearValue !== 1.0 || farValue !== 1.0) { - // scale by distance calculation in shader need not be enabled - // until a billboard with near and far !== 1.0 is found - billboardCollection._shaderScaleByDistance = true; + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * The definition is changed whenever setValue is called with data different + * than the current value. + * @memberof TimeIntervalCollectionProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets the interval collection. + * @memberof TimeIntervalCollectionProperty.prototype + * + * @type {TimeIntervalCollection} + */ + intervals : { + get : function() { + return this._intervals; } } + }); - if (billboardCollection._instanced) { - i = billboard._index; - writer(i, near, nearValue, far, farValue); - } else { - i = billboard._index * 4; - writer(i + 0, near, nearValue, far, farValue); - writer(i + 1, near, nearValue, far, farValue); - writer(i + 2, near, nearValue, far, farValue); - writer(i + 3, near, nearValue, far, farValue); + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} time The time for which to retrieve the value. + * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + */ + TimeIntervalCollectionProperty.prototype.getValue = function(time, result) { + if (!defined(time)) { + throw new DeveloperError('time is required'); } - } + + var value = this._intervals.findDataForIntervalContainingDate(time); + if (defined(value) && (typeof value.clone === 'function')) { + return value.clone(result); + } + return value; + }; + + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + TimeIntervalCollectionProperty.prototype.equals = function(other) { + return this === other || // + (other instanceof TimeIntervalCollectionProperty && // + this._intervals.equals(other._intervals, Property.equals)); + }; + + /** + * @private + */ + TimeIntervalCollectionProperty.prototype._intervalsChanged = function() { + this._definitionChanged.raiseEvent(this); + }; - function writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.pixelOffsetScaleByDistance]; - var near = 0.0; - var nearValue = 1.0; - var far = 1.0; - var farValue = 1.0; + return TimeIntervalCollectionProperty; +}); - var pixelOffsetScale = billboard.pixelOffsetScaleByDistance; - if (defined(pixelOffsetScale)) { - near = pixelOffsetScale.near; - nearValue = pixelOffsetScale.nearValue; - far = pixelOffsetScale.far; - farValue = pixelOffsetScale.farValue; +define('DataSources/VelocityVectorProperty',[ + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/JulianDate', + './Property' + ], function( + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + JulianDate, + Property) { + 'use strict'; - if (nearValue !== 1.0 || farValue !== 1.0) { - // pixelOffsetScale by distance calculation in shader need not be enabled - // until a billboard with near and far !== 1.0 is found - billboardCollection._shaderPixelOffsetScaleByDistance = true; - } - } + /** + * A {@link Property} which evaluates to a {@link Cartesian3} vector + * based on the velocity of the provided {@link PositionProperty}. + * + * @alias VelocityVectorProperty + * @constructor + * + * @param {Property} [position] The position property used to compute the velocity. + * @param {Boolean} [normalize=true] Whether to normalize the computed velocity vector. + * + * @example + * //Create an entity with a billboard rotated to match its velocity. + * var position = new Cesium.SampledProperty(); + * position.addSamples(...); + * var entity = viewer.entities.add({ + * position : position, + * billboard : { + * image : 'image.png', + * alignedAxis : new Cesium.VelocityVectorProperty(position, true) // alignedAxis must be a unit vector + * } + * })); + */ + function VelocityVectorProperty(position, normalize) { + this._position = undefined; + this._subscription = undefined; + this._definitionChanged = new Event(); + this._normalize = defaultValue(normalize, true); - if (billboardCollection._instanced) { - i = billboard._index; - writer(i, near, nearValue, far, farValue); - } else { - i = billboard._index * 4; - writer(i + 0, near, nearValue, far, farValue); - writer(i + 1, near, nearValue, far, farValue); - writer(i + 2, near, nearValue, far, farValue); - writer(i + 3, near, nearValue, far, farValue); - } + this.position = position; } - function writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - var i; - var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth]; - var near = 0.0; - var far = Number.MAX_VALUE; + defineProperties(VelocityVectorProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof VelocityVectorProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._position); + } + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * @memberof VelocityVectorProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + /** + * Gets or sets the position property used to compute the velocity vector. + * @memberof VelocityVectorProperty.prototype + * + * @type {Property} + */ + position : { + get : function() { + return this._position; + }, + set : function(value) { + var oldValue = this._position; + if (oldValue !== value) { + if (defined(oldValue)) { + this._subscription(); + } - var distanceDisplayCondition = billboard.distanceDisplayCondition; - if (defined(distanceDisplayCondition)) { - near = distanceDisplayCondition.near; - far = distanceDisplayCondition.far; + this._position = value; - near *= near; - far *= far; + if (defined(value)) { + this._subscription = value._definitionChanged.addEventListener(function() { + this._definitionChanged.raiseEvent(this); + }, this); + } - billboardCollection._shaderDistanceDisplayCondition = true; - } + this._definitionChanged.raiseEvent(this); + } + } + }, + /** + * Gets or sets whether the vector produced by this property + * will be normalized or not. + * @memberof VelocityVectorProperty.prototype + * + * @type {Boolean} + */ + normalize : { + get : function() { + return this._normalize; + }, + set : function(value) { + if (this._normalize === value) { + return; + } - var disableDepthTestDistance = billboard.disableDepthTestDistance; - disableDepthTestDistance *= disableDepthTestDistance; - if (disableDepthTestDistance > 0.0) { - billboardCollection._shaderDisableDepthDistance = true; - if (disableDepthTestDistance === Number.POSITIVE_INFINITY) { - disableDepthTestDistance = -1.0; + this._normalize = value; + this._definitionChanged.raiseEvent(this); } } + }); - if (billboardCollection._instanced) { - i = billboard._index; - writer(i, near, far, disableDepthTestDistance); - } else { - i = billboard._index * 4; - writer(i + 0, near, far, disableDepthTestDistance); - writer(i + 1, near, far, disableDepthTestDistance); - writer(i + 2, near, far, disableDepthTestDistance); - writer(i + 3, near, far, disableDepthTestDistance); - } - } + var position1Scratch = new Cartesian3(); + var position2Scratch = new Cartesian3(); + var timeScratch = new JulianDate(); + var step = 1.0 / 60.0; - function writeBillboard(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { - writePositionScaleAndRotation(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeCompressedAttrib0(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeCompressedAttrib1(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeCompressedAttrib2(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeEyeOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - } + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} [time] The time for which to retrieve the value. + * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. + */ + VelocityVectorProperty.prototype.getValue = function(time, result) { + return this._getValue(time, result); + }; - function recomputeActualPositions(billboardCollection, billboards, length, frameState, modelMatrix, recomputeBoundingVolume) { - var boundingVolume; - if (frameState.mode === SceneMode.SCENE3D) { - boundingVolume = billboardCollection._baseVolume; - billboardCollection._boundingVolumeDirty = true; - } else { - boundingVolume = billboardCollection._baseVolume2D; + /** + * @private + */ + VelocityVectorProperty.prototype._getValue = function(time, velocityResult, positionResult) { + if (!defined(time)) { + throw new DeveloperError('time is required'); } - - var positions = []; - for ( var i = 0; i < length; ++i) { - var billboard = billboards[i]; - var position = billboard.position; - var actualPosition = Billboard._computeActualPosition(billboard, position, frameState, modelMatrix); - if (defined(actualPosition)) { - billboard._setActualPosition(actualPosition); - - if (recomputeBoundingVolume) { - positions.push(actualPosition); - } else { - BoundingSphere.expand(boundingVolume, actualPosition, boundingVolume); - } - } + + if (!defined(velocityResult)) { + velocityResult = new Cartesian3(); } - if (recomputeBoundingVolume) { - BoundingSphere.fromPoints(positions, boundingVolume); + var property = this._position; + if (Property.isConstant(property)) { + return this._normalize ? undefined : Cartesian3.clone(Cartesian3.ZERO, velocityResult); } - } - function updateMode(billboardCollection, frameState) { - var mode = frameState.mode; - - var billboards = billboardCollection._billboards; - var billboardsToUpdate = billboardCollection._billboardsToUpdate; - var modelMatrix = billboardCollection._modelMatrix; + var position1 = property.getValue(time, position1Scratch); + var position2 = property.getValue(JulianDate.addSeconds(time, step, timeScratch), position2Scratch); - if (billboardCollection._createVertexArray || - billboardCollection._mode !== mode || - mode !== SceneMode.SCENE3D && - !Matrix4.equals(modelMatrix, billboardCollection.modelMatrix)) { + //If we don't have a position for now, return undefined. + if (!defined(position1)) { + return undefined; + } - billboardCollection._mode = mode; - Matrix4.clone(billboardCollection.modelMatrix, modelMatrix); - billboardCollection._createVertexArray = true; + //If we don't have a position for now + step, see if we have a position for now - step. + if (!defined(position2)) { + position2 = position1; + position1 = property.getValue(JulianDate.addSeconds(time, -step, timeScratch), position2Scratch); - if (mode === SceneMode.SCENE3D || mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - recomputeActualPositions(billboardCollection, billboards, billboards.length, frameState, modelMatrix, true); + if (!defined(position1)) { + return undefined; } - } else if (mode === SceneMode.MORPHING) { - recomputeActualPositions(billboardCollection, billboards, billboards.length, frameState, modelMatrix, true); - } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - recomputeActualPositions(billboardCollection, billboardsToUpdate, billboardCollection._billboardsToUpdateIndex, frameState, modelMatrix, false); } - } - function updateBoundingVolume(collection, frameState, boundingVolume) { - var pixelScale = 1.0; - if (!collection._allSizedInMeters || collection._maxPixelOffset !== 0.0) { - pixelScale = frameState.camera.getPixelSize(boundingVolume, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); + if (Cartesian3.equals(position1, position2)) { + return this._normalize ? undefined : Cartesian3.clone(Cartesian3.ZERO, velocityResult); } - var size = pixelScale * collection._maxScale * collection._maxSize * 2.0; - if (collection._allHorizontalCenter && collection._allVerticalCenter ) { - size *= 0.5; + if (defined(positionResult)) { + position1.clone(positionResult); } - var offset = pixelScale * collection._maxPixelOffset + collection._maxEyeOffset; - boundingVolume.radius += size + offset; - } + var velocity = Cartesian3.subtract(position2, position1, velocityResult); + if (this._normalize) { + return Cartesian3.normalize(velocity, velocityResult); + } - var scratchWriterArray = []; + return Cartesian3.divideByScalar(velocity, step, velocityResult); + }; /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. * - * @exception {RuntimeError} image with id must be in the atlas. + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ - BillboardCollection.prototype.update = function(frameState) { - removeBillboards(this); - var billboards = this._billboards; - var billboardsLength = billboards.length; - - var context = frameState.context; - this._instanced = context.instancedArrays; - attributeLocations = this._instanced ? attributeLocationsInstanced : attributeLocationsBatched; - getIndexBuffer = this._instanced ? getIndexBufferInstanced : getIndexBufferBatched; - - var textureAtlas = this._textureAtlas; - if (!defined(textureAtlas)) { - textureAtlas = this._textureAtlas = new TextureAtlas({ - context : context - }); - - for (var ii = 0; ii < billboardsLength; ++ii) { - billboards[ii]._loadImage(); - } - } - - var textureAtlasCoordinates = textureAtlas.textureCoordinates; - if (textureAtlasCoordinates.length === 0) { - // Can't write billboard vertices until we have texture coordinates - // provided by a texture atlas - return; - } - - updateMode(this, frameState); + VelocityVectorProperty.prototype.equals = function(other) { + return this === other ||// + (other instanceof VelocityVectorProperty && + Property.equals(this._position, other._position)); + }; - billboards = this._billboards; - billboardsLength = billboards.length; - var billboardsToUpdate = this._billboardsToUpdate; - var billboardsToUpdateLength = this._billboardsToUpdateIndex; + return VelocityVectorProperty; +}); - var properties = this._propertiesChanged; +define('DataSources/VelocityOrientationProperty',[ + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Ellipsoid', + '../Core/Event', + '../Core/Matrix3', + '../Core/Quaternion', + '../Core/Transforms', + './Property', + './VelocityVectorProperty' + ], function( + Cartesian3, + defaultValue, + defined, + defineProperties, + Ellipsoid, + Event, + Matrix3, + Quaternion, + Transforms, + Property, + VelocityVectorProperty) { + 'use strict'; - var textureAtlasGUID = textureAtlas.guid; - var createVertexArray = this._createVertexArray || this._textureAtlasGUID !== textureAtlasGUID; - this._textureAtlasGUID = textureAtlasGUID; + /** + * A {@link Property} which evaluates to a {@link Quaternion} rotation + * based on the velocity of the provided {@link PositionProperty}. + * + * @alias VelocityOrientationProperty + * @constructor + * + * @param {Property} [position] The position property used to compute the orientation. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine which way is up. + * + * @example + * //Create an entity with position and orientation. + * var position = new Cesium.SampledProperty(); + * position.addSamples(...); + * var entity = viewer.entities.add({ + * position : position, + * orientation : new Cesium.VelocityOrientationProperty(position) + * })); + */ + function VelocityOrientationProperty(position, ellipsoid) { + this._velocityVectorProperty = new VelocityVectorProperty(position, true); + this._subscription = undefined; + this._ellipsoid = undefined; + this._definitionChanged = new Event(); - var vafWriters; - var pass = frameState.passes; - var picking = pass.pick; + this.ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - // PERFORMANCE_IDEA: Round robin multiple buffers. - if (createVertexArray || (!picking && this.computeNewBuffersUsage())) { - this._createVertexArray = false; + var that = this; + this._velocityVectorProperty.definitionChanged.addEventListener(function() { + that._definitionChanged.raiseEvent(that); + }); + } - for (var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { - properties[k] = 0; + defineProperties(VelocityOrientationProperty.prototype, { + /** + * Gets a value indicating if this property is constant. + * @memberof VelocityOrientationProperty.prototype + * + * @type {Boolean} + * @readonly + */ + isConstant : { + get : function() { + return Property.isConstant(this._velocityVectorProperty); } - - this._vaf = this._vaf && this._vaf.destroy(); - - if (billboardsLength > 0) { - // PERFORMANCE_IDEA: Instead of creating a new one, resize like std::vector. - this._vaf = createVAF(context, billboardsLength, this._buffersUsage, this._instanced); - vafWriters = this._vaf.writers; - - // Rewrite entire buffer if billboards were added or removed. - for (var i = 0; i < billboardsLength; ++i) { - var billboard = this._billboards[i]; - billboard._dirty = false; // In case it needed an update. - writeBillboard(this, context, textureAtlasCoordinates, vafWriters, billboard); - } - - // Different billboard collections share the same index buffer. - this._vaf.commit(getIndexBuffer(context)); + }, + /** + * Gets the event that is raised whenever the definition of this property changes. + * @memberof VelocityOrientationProperty.prototype + * + * @type {Event} + * @readonly + */ + definitionChanged : { + get : function() { + return this._definitionChanged; } - - this._billboardsToUpdateIndex = 0; - } else if (billboardsToUpdateLength > 0) { - // Billboards were modified, but none were added or removed. - var writers = scratchWriterArray; - writers.length = 0; - - if (properties[POSITION_INDEX] || properties[ROTATION_INDEX] || properties[SCALE_INDEX]) { - writers.push(writePositionScaleAndRotation); + }, + /** + * Gets or sets the position property used to compute orientation. + * @memberof VelocityOrientationProperty.prototype + * + * @type {Property} + */ + position : { + get : function() { + return this._velocityVectorProperty.position; + }, + set : function(value) { + this._velocityVectorProperty.position = value; } - - if (properties[IMAGE_INDEX_INDEX] || properties[PIXEL_OFFSET_INDEX] || properties[HORIZONTAL_ORIGIN_INDEX] || properties[VERTICAL_ORIGIN_INDEX] || properties[SHOW_INDEX]) { - writers.push(writeCompressedAttrib0); - if (this._instanced) { - writers.push(writeEyeOffset); + }, + /** + * Gets or sets the ellipsoid used to determine which way is up. + * @memberof VelocityOrientationProperty.prototype + * + * @type {Property} + */ + ellipsoid : { + get : function() { + return this._ellipsoid; + }, + set : function(value) { + var oldValue = this._ellipsoid; + if (oldValue !== value) { + this._ellipsoid = value; + this._definitionChanged.raiseEvent(this); } } + } + }); - if (properties[IMAGE_INDEX_INDEX] || properties[ALIGNED_AXIS_INDEX] || properties[TRANSLUCENCY_BY_DISTANCE_INDEX]) { - writers.push(writeCompressedAttrib1); - writers.push(writeCompressedAttrib2); - } + var positionScratch = new Cartesian3(); + var velocityScratch = new Cartesian3(); + var rotationScratch = new Matrix3(); - if (properties[IMAGE_INDEX_INDEX] || properties[COLOR_INDEX]) { - writers.push(writeCompressedAttrib2); - } + /** + * Gets the value of the property at the provided time. + * + * @param {JulianDate} [time] The time for which to retrieve the value. + * @param {Quaternion} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {Quaternion} The modified result parameter or a new instance if the result parameter was not supplied. + */ + VelocityOrientationProperty.prototype.getValue = function(time, result) { + var velocity = this._velocityVectorProperty._getValue(time, velocityScratch, positionScratch); - if (properties[EYE_OFFSET_INDEX]) { - writers.push(writeEyeOffset); - } + if (!defined(velocity)) { + return undefined; + } - if (properties[SCALE_BY_DISTANCE_INDEX]) { - writers.push(writeScaleByDistance); - } + Transforms.rotationMatrixFromPositionVelocity(positionScratch, velocity, this._ellipsoid, rotationScratch); + return Quaternion.fromRotationMatrix(rotationScratch, result); + }; - if (properties[PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX]) { - writers.push(writePixelOffsetScaleByDistance); - } + /** + * Compares this property to the provided property and returns + * <code>true</code> if they are equal, <code>false</code> otherwise. + * + * @param {Property} [other] The other property. + * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + */ + VelocityOrientationProperty.prototype.equals = function(other) { + return this === other ||// + (other instanceof VelocityOrientationProperty && + Property.equals(this._velocityVectorProperty, other._velocityVectorProperty) && + (this._ellipsoid === other._ellipsoid || + this._ellipsoid.equals(other._ellipsoid))); + }; - if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE]) { - writers.push(writeDistanceDisplayConditionAndDepthDisable); - } + return VelocityOrientationProperty; +}); - var numWriters = writers.length; - vafWriters = this._vaf.writers; +define('DataSources/CzmlDataSource',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/ClockRange', + '../Core/ClockStep', + '../Core/Color', + '../Core/CornerType', + '../Core/createGuid', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/Ellipsoid', + '../Core/Event', + '../Core/ExtrapolationType', + '../Core/getFilenameFromUri', + '../Core/HermitePolynomialApproximation', + '../Core/isArray', + '../Core/Iso8601', + '../Core/JulianDate', + '../Core/LagrangePolynomialApproximation', + '../Core/LinearApproximation', + '../Core/Math', + '../Core/NearFarScalar', + '../Core/Quaternion', + '../Core/Rectangle', + '../Core/ReferenceFrame', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/Spherical', + '../Core/TimeInterval', + '../Core/TimeIntervalCollection', + '../Scene/ColorBlendMode', + '../Scene/HeightReference', + '../Scene/HorizontalOrigin', + '../Scene/LabelStyle', + '../Scene/ShadowMode', + '../Scene/VerticalOrigin', + '../ThirdParty/Uri', + '../ThirdParty/when', + './BillboardGraphics', + './BoxGraphics', + './ColorMaterialProperty', + './CompositeMaterialProperty', + './CompositePositionProperty', + './CompositeProperty', + './ConstantPositionProperty', + './ConstantProperty', + './CorridorGraphics', + './CylinderGraphics', + './DataSource', + './DataSourceClock', + './EllipseGraphics', + './EllipsoidGraphics', + './EntityCluster', + './EntityCollection', + './GridMaterialProperty', + './ImageMaterialProperty', + './LabelGraphics', + './ModelGraphics', + './NodeTransformationProperty', + './PathGraphics', + './PointGraphics', + './PolygonGraphics', + './PolylineArrowMaterialProperty', + './PolylineDashMaterialProperty', + './PolylineGlowMaterialProperty', + './PolylineGraphics', + './PolylineOutlineMaterialProperty', + './PositionPropertyArray', + './PropertyArray', + './PropertyBag', + './RectangleGraphics', + './ReferenceProperty', + './Rotation', + './SampledPositionProperty', + './SampledProperty', + './StripeMaterialProperty', + './StripeOrientation', + './TimeIntervalCollectionPositionProperty', + './TimeIntervalCollectionProperty', + './VelocityOrientationProperty', + './VelocityVectorProperty', + './WallGraphics' + ], function( + BoundingRectangle, + Cartesian2, + Cartesian3, + Cartographic, + ClockRange, + ClockStep, + Color, + CornerType, + createGuid, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + DistanceDisplayCondition, + Ellipsoid, + Event, + ExtrapolationType, + getFilenameFromUri, + HermitePolynomialApproximation, + isArray, + Iso8601, + JulianDate, + LagrangePolynomialApproximation, + LinearApproximation, + CesiumMath, + NearFarScalar, + Quaternion, + Rectangle, + ReferenceFrame, + Resource, + RuntimeError, + Spherical, + TimeInterval, + TimeIntervalCollection, + ColorBlendMode, + HeightReference, + HorizontalOrigin, + LabelStyle, + ShadowMode, + VerticalOrigin, + Uri, + when, + BillboardGraphics, + BoxGraphics, + ColorMaterialProperty, + CompositeMaterialProperty, + CompositePositionProperty, + CompositeProperty, + ConstantPositionProperty, + ConstantProperty, + CorridorGraphics, + CylinderGraphics, + DataSource, + DataSourceClock, + EllipseGraphics, + EllipsoidGraphics, + EntityCluster, + EntityCollection, + GridMaterialProperty, + ImageMaterialProperty, + LabelGraphics, + ModelGraphics, + NodeTransformationProperty, + PathGraphics, + PointGraphics, + PolygonGraphics, + PolylineArrowMaterialProperty, + PolylineDashMaterialProperty, + PolylineGlowMaterialProperty, + PolylineGraphics, + PolylineOutlineMaterialProperty, + PositionPropertyArray, + PropertyArray, + PropertyBag, + RectangleGraphics, + ReferenceProperty, + Rotation, + SampledPositionProperty, + SampledProperty, + StripeMaterialProperty, + StripeOrientation, + TimeIntervalCollectionPositionProperty, + TimeIntervalCollectionProperty, + VelocityOrientationProperty, + VelocityVectorProperty, + WallGraphics) { + 'use strict'; - if ((billboardsToUpdateLength / billboardsLength) > 0.1) { - // If more than 10% of billboard change, rewrite the entire buffer. + // A marker type to distinguish CZML properties where we need to end up with a unit vector. + // The data is still loaded into Cartesian3 objects but they are normalized. + function UnitCartesian3() {} + UnitCartesian3.packedLength = Cartesian3.packedLength; + UnitCartesian3.unpack = Cartesian3.unpack; + UnitCartesian3.pack = Cartesian3.pack; - // PERFORMANCE_IDEA: I totally made up 10% :). + // As a side note, for the purposes of CZML, Quaternion always indicates a unit quaternion. - for (var m = 0; m < billboardsToUpdateLength; ++m) { - var b = billboardsToUpdate[m]; - b._dirty = false; + var currentId; - for ( var n = 0; n < numWriters; ++n) { - writers[n](this, context, textureAtlasCoordinates, vafWriters, b); - } - } - this._vaf.commit(getIndexBuffer(context)); - } else { - for (var h = 0; h < billboardsToUpdateLength; ++h) { - var bb = billboardsToUpdate[h]; - bb._dirty = false; + function createReferenceProperty(entityCollection, referenceString) { + if (referenceString[0] === '#') { + referenceString = currentId + referenceString; + } + return ReferenceProperty.fromString(entityCollection, referenceString); + } - for ( var o = 0; o < numWriters; ++o) { - writers[o](this, context, textureAtlasCoordinates, vafWriters, bb); - } + function createSpecializedProperty(type, entityCollection, packetData) { + if (defined(packetData.reference)) { + return createReferenceProperty(entityCollection, packetData.reference); + } - if (this._instanced) { - this._vaf.subCommit(bb._index, 1); - } else { - this._vaf.subCommit(bb._index * 4, 4); - } - } - this._vaf.endSubCommits(); + if (defined(packetData.velocityReference)) { + var referenceProperty = createReferenceProperty(entityCollection, packetData.velocityReference); + switch (type) { + case Cartesian3: + case UnitCartesian3: + return new VelocityVectorProperty(referenceProperty, type === UnitCartesian3); + case Quaternion: + return new VelocityOrientationProperty(referenceProperty); } - - this._billboardsToUpdateIndex = 0; } - // If the number of total billboards ever shrinks considerably - // Truncate billboardsToUpdate so that we free memory that we're - // not going to be using. - if (billboardsToUpdateLength > billboardsLength * 1.5) { - billboardsToUpdate.length = billboardsLength; - } + throw new RuntimeError(JSON.stringify(packetData) + ' is not valid CZML.'); + } - if (!defined(this._vaf) || !defined(this._vaf.va)) { - return; - } + var scratchCartesian = new Cartesian3(); + var scratchSpherical = new Spherical(); + var scratchCartographic = new Cartographic(); + var scratchTimeInterval = new TimeInterval(); + var scratchQuaternion = new Quaternion(); - if (this._boundingVolumeDirty) { - this._boundingVolumeDirty = false; - BoundingSphere.transform(this._baseVolume, this.modelMatrix, this._baseVolumeWC); + function unwrapColorInterval(czmlInterval) { + var rgbaf = czmlInterval.rgbaf; + if (defined(rgbaf)) { + return rgbaf; } - var boundingVolume; - var modelMatrix = Matrix4.IDENTITY; - if (frameState.mode === SceneMode.SCENE3D) { - modelMatrix = this.modelMatrix; - boundingVolume = BoundingSphere.clone(this._baseVolumeWC, this._boundingVolume); - } else { - boundingVolume = BoundingSphere.clone(this._baseVolume2D, this._boundingVolume); + var rgba = czmlInterval.rgba; + if (!defined(rgba)) { + return undefined; } - updateBoundingVolume(this, frameState, boundingVolume); - - var blendOptionChanged = this._blendOption !== this.blendOption; - this._blendOption = this.blendOption; - - if (blendOptionChanged) { - if (this._blendOption === BlendOption.OPAQUE || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { - this._rsOpaque = RenderState.fromCache({ - depthTest : { - enabled : true, - func : WebGLConstants.LESS - }, - depthMask : true - }); - } else { - this._rsOpaque = undefined; - } - - // If OPAQUE_AND_TRANSLUCENT is in use, only the opaque pass gets the benefit of the depth buffer, - // not the translucent pass. Otherwise, if the TRANSLUCENT pass is on its own, it turns on - // a depthMask in lieu of full depth sorting (because it has opaque-ish fragments that look bad in OIT). - // When the TRANSLUCENT depth mask is in use, label backgrounds require the depth func to be LEQUAL. - var useTranslucentDepthMask = this._blendOption === BlendOption.TRANSLUCENT; - if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { - this._rsTranslucent = RenderState.fromCache({ - depthTest : { - enabled : true, - func : (useTranslucentDepthMask ? WebGLConstants.LEQUAL : WebGLConstants.LESS) - }, - depthMask : useTranslucentDepthMask, - blending : BlendingState.ALPHA_BLEND - }); - } else { - this._rsTranslucent = undefined; - } + var length = rgba.length; + if (length === Color.packedLength) { + return [Color.byteToFloat(rgba[0]), Color.byteToFloat(rgba[1]), Color.byteToFloat(rgba[2]), Color.byteToFloat(rgba[3])]; } - this._shaderDisableDepthDistance = this._shaderDisableDepthDistance || frameState.minimumDisableDepthTestDistance !== 0.0; - var vs; - var fs; - - if (blendOptionChanged || - (this._shaderRotation !== this._compiledShaderRotation) || - (this._shaderAlignedAxis !== this._compiledShaderAlignedAxis) || - (this._shaderScaleByDistance !== this._compiledShaderScaleByDistance) || - (this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistance) || - (this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistance) || - (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayCondition) || - (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) { + rgbaf = new Array(length); + for (var i = 0; i < length; i += 5) { + rgbaf[i] = rgba[i]; + rgbaf[i + 1] = Color.byteToFloat(rgba[i + 1]); + rgbaf[i + 2] = Color.byteToFloat(rgba[i + 2]); + rgbaf[i + 3] = Color.byteToFloat(rgba[i + 3]); + rgbaf[i + 4] = Color.byteToFloat(rgba[i + 4]); + } + return rgbaf; + } - vs = new ShaderSource({ - sources : [BillboardCollectionVS] + function unwrapUriInterval(czmlInterval, sourceUri) { + var uri = defaultValue(czmlInterval.uri, czmlInterval); + if (defined(sourceUri)) { + return sourceUri.getDerivedResource({ + url: uri }); - if (this._instanced) { - vs.defines.push('INSTANCED'); - } - if (this._shaderRotation) { - vs.defines.push('ROTATION'); - } - if (this._shaderAlignedAxis) { - vs.defines.push('ALIGNED_AXIS'); - } - if (this._shaderScaleByDistance) { - vs.defines.push('EYE_DISTANCE_SCALING'); - } - if (this._shaderTranslucencyByDistance) { - vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); - } - if (this._shaderPixelOffsetScaleByDistance) { - vs.defines.push('EYE_DISTANCE_PIXEL_OFFSET'); - } - if (this._shaderDistanceDisplayCondition) { - vs.defines.push('DISTANCE_DISPLAY_CONDITION'); - } - if (this._shaderDisableDepthDistance) { - vs.defines.push('DISABLE_DEPTH_DISTANCE'); - } - - if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { - fs = new ShaderSource({ - defines : ['OPAQUE'], - sources : [BillboardCollectionFS] - }); - this._sp = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - - fs = new ShaderSource({ - defines : ['TRANSLUCENT'], - sources : [BillboardCollectionFS] - }); - this._spTranslucent = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._spTranslucent, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } - - if (this._blendOption === BlendOption.OPAQUE) { - fs = new ShaderSource({ - sources : [BillboardCollectionFS] - }); - this._sp = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } - - if (this._blendOption === BlendOption.TRANSLUCENT) { - fs = new ShaderSource({ - sources : [BillboardCollectionFS] - }); - this._spTranslucent = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._spTranslucent, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } - - this._compiledShaderRotation = this._shaderRotation; - this._compiledShaderAlignedAxis = this._shaderAlignedAxis; - this._compiledShaderScaleByDistance = this._shaderScaleByDistance; - this._compiledShaderTranslucencyByDistance = this._shaderTranslucencyByDistance; - this._compiledShaderPixelOffsetScaleByDistance = this._shaderPixelOffsetScaleByDistance; - this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition; - this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance; } - if (!defined(this._spPick) || - (this._shaderRotation !== this._compiledShaderRotationPick) || - (this._shaderAlignedAxis !== this._compiledShaderAlignedAxisPick) || - (this._shaderScaleByDistance !== this._compiledShaderScaleByDistancePick) || - (this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistancePick) || - (this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistancePick) || - (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayConditionPick) || - (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistancePick)) { + return Resource.createIfNeeded(uri); + } - vs = new ShaderSource({ - defines : ['RENDER_FOR_PICK'], - sources : [BillboardCollectionVS] - }); + function unwrapRectangleInterval(czmlInterval) { + var wsen = czmlInterval.wsen; + if (defined(wsen)) { + return wsen; + } - if(this._instanced) { - vs.defines.push('INSTANCED'); - } - if (this._shaderRotation) { - vs.defines.push('ROTATION'); - } - if (this._shaderAlignedAxis) { - vs.defines.push('ALIGNED_AXIS'); - } - if (this._shaderScaleByDistance) { - vs.defines.push('EYE_DISTANCE_SCALING'); - } - if (this._shaderTranslucencyByDistance) { - vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); - } - if (this._shaderPixelOffsetScaleByDistance) { - vs.defines.push('EYE_DISTANCE_PIXEL_OFFSET'); - } - if (this._shaderDistanceDisplayCondition) { - vs.defines.push('DISTANCE_DISPLAY_CONDITION'); - } - if (this._shaderDisableDepthDistance) { - vs.defines.push('DISABLE_DEPTH_DISTANCE'); - } + var wsenDegrees = czmlInterval.wsenDegrees; + if (!defined(wsenDegrees)) { + return undefined; + } - fs = new ShaderSource({ - defines : ['RENDER_FOR_PICK'], - sources : [BillboardCollectionFS] - }); + var length = wsenDegrees.length; + if (length === Rectangle.packedLength) { + return [CesiumMath.toRadians(wsenDegrees[0]), CesiumMath.toRadians(wsenDegrees[1]), CesiumMath.toRadians(wsenDegrees[2]), CesiumMath.toRadians(wsenDegrees[3])]; + } - this._spPick = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._spPick, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - this._compiledShaderRotationPick = this._shaderRotation; - this._compiledShaderAlignedAxisPick = this._shaderAlignedAxis; - this._compiledShaderScaleByDistancePick = this._shaderScaleByDistance; - this._compiledShaderTranslucencyByDistancePick = this._shaderTranslucencyByDistance; - this._compiledShaderPixelOffsetScaleByDistancePick = this._shaderPixelOffsetScaleByDistance; - this._compiledShaderDistanceDisplayConditionPick = this._shaderDistanceDisplayCondition; - this._compiledShaderDisableDepthDistancePick = this._shaderDisableDepthDistance; + wsen = new Array(length); + for (var i = 0; i < length; i += 5) { + wsen[i] = wsenDegrees[i]; + wsen[i + 1] = CesiumMath.toRadians(wsenDegrees[i + 1]); + wsen[i + 2] = CesiumMath.toRadians(wsenDegrees[i + 2]); + wsen[i + 3] = CesiumMath.toRadians(wsenDegrees[i + 3]); + wsen[i + 4] = CesiumMath.toRadians(wsenDegrees[i + 4]); } + return wsen; + } - var va; - var vaLength; - var command; - var j; + function convertUnitSphericalToCartesian(unitSpherical) { + var length = unitSpherical.length; + scratchSpherical.magnitude = 1.0; + if (length === 2) { + scratchSpherical.clock = unitSpherical[0]; + scratchSpherical.cone = unitSpherical[1]; + Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); + return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; + } - var commandList = frameState.commandList; + var result = new Array(length / 3 * 4); + for (var i = 0, j = 0; i < length; i += 3, j += 4) { + result[j] = unitSpherical[i]; - if (pass.render) { - var colorList = this._colorCommands; + scratchSpherical.clock = unitSpherical[i + 1]; + scratchSpherical.cone = unitSpherical[i + 2]; + Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); - var opaque = this._blendOption === BlendOption.OPAQUE; - var opaqueAndTranslucent = this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT; + result[j + 1] = scratchCartesian.x; + result[j + 2] = scratchCartesian.y; + result[j + 3] = scratchCartesian.z; + } + return result; + } - va = this._vaf.va; - vaLength = va.length; + function convertSphericalToCartesian(spherical) { + var length = spherical.length; + if (length === 3) { + scratchSpherical.clock = spherical[0]; + scratchSpherical.cone = spherical[1]; + scratchSpherical.magnitude = spherical[2]; + Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); + return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; + } - colorList.length = vaLength; - var totalLength = opaqueAndTranslucent ? vaLength * 2 : vaLength; - for (j = 0; j < totalLength; ++j) { - command = colorList[j]; - if (!defined(command)) { - command = colorList[j] = new DrawCommand(); - } + var result = new Array(length); + for (var i = 0; i < length; i += 4) { + result[i] = spherical[i]; - var opaqueCommand = opaque || (opaqueAndTranslucent && j % 2 === 0); + scratchSpherical.clock = spherical[i + 1]; + scratchSpherical.cone = spherical[i + 2]; + scratchSpherical.magnitude = spherical[i + 3]; + Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); - command.pass = opaqueCommand || !opaqueAndTranslucent ? Pass.OPAQUE : Pass.TRANSLUCENT; - command.owner = this; + result[i + 1] = scratchCartesian.x; + result[i + 2] = scratchCartesian.y; + result[i + 3] = scratchCartesian.z; + } + return result; + } - var index = opaqueAndTranslucent ? Math.floor(j / 2.0) : j; - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.count = va[index].indicesCount; - command.shaderProgram = opaqueCommand ? this._sp : this._spTranslucent; - command.uniformMap = this._uniforms; - command.vertexArray = va[index].va; - command.renderState = opaqueCommand ? this._rsOpaque : this._rsTranslucent; - command.debugShowBoundingVolume = this.debugShowBoundingVolume; + function convertCartographicRadiansToCartesian(cartographicRadians) { + var length = cartographicRadians.length; + if (length === 3) { + scratchCartographic.longitude = cartographicRadians[0]; + scratchCartographic.latitude = cartographicRadians[1]; + scratchCartographic.height = cartographicRadians[2]; + Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); + return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; + } - if (this._instanced) { - command.count = 6; - command.instanceCount = billboardsLength; - } + var result = new Array(length); + for (var i = 0; i < length; i += 4) { + result[i] = cartographicRadians[i]; - commandList.push(command); - } + scratchCartographic.longitude = cartographicRadians[i + 1]; + scratchCartographic.latitude = cartographicRadians[i + 2]; + scratchCartographic.height = cartographicRadians[i + 3]; + Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); + + result[i + 1] = scratchCartesian.x; + result[i + 2] = scratchCartesian.y; + result[i + 3] = scratchCartesian.z; } + return result; + } - if (picking) { - var pickList = this._pickCommands; + function convertCartographicDegreesToCartesian(cartographicDegrees) { + var length = cartographicDegrees.length; + if (length === 3) { + scratchCartographic.longitude = CesiumMath.toRadians(cartographicDegrees[0]); + scratchCartographic.latitude = CesiumMath.toRadians(cartographicDegrees[1]); + scratchCartographic.height = cartographicDegrees[2]; + Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); + return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; + } - va = this._vaf.va; - vaLength = va.length; + var result = new Array(length); + for (var i = 0; i < length; i += 4) { + result[i] = cartographicDegrees[i]; - pickList.length = vaLength; - for (j = 0; j < vaLength; ++j) { - command = pickList[j]; - if (!defined(command)) { - command = pickList[j] = new DrawCommand({ - pass : Pass.OPAQUE, - owner : this - }); - } + scratchCartographic.longitude = CesiumMath.toRadians(cartographicDegrees[i + 1]); + scratchCartographic.latitude = CesiumMath.toRadians(cartographicDegrees[i + 2]); + scratchCartographic.height = cartographicDegrees[i + 3]; + Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.count = va[j].indicesCount; - command.shaderProgram = this._spPick; - command.uniformMap = this._uniforms; - command.vertexArray = va[j].va; - command.renderState = this._rsOpaque; + result[i + 1] = scratchCartesian.x; + result[i + 2] = scratchCartesian.y; + result[i + 3] = scratchCartesian.z; + } + return result; + } - if (this._instanced) { - command.count = 6; - command.instanceCount = billboardsLength; - } + function unwrapCartesianInterval(czmlInterval) { + var cartesian = czmlInterval.cartesian; + if (defined(cartesian)) { + return cartesian; + } - commandList.push(command); - } + var cartesianVelocity = czmlInterval.cartesianVelocity; + if (defined(cartesianVelocity)) { + return cartesianVelocity; } - }; - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see BillboardCollection#destroy - */ - BillboardCollection.prototype.isDestroyed = function() { - return false; - }; + var unitCartesian = czmlInterval.unitCartesian; + if (defined(unitCartesian)) { + return unitCartesian; + } - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * billboards = billboards && billboards.destroy(); - * - * @see BillboardCollection#isDestroyed - */ - BillboardCollection.prototype.destroy = function() { - if (defined(this._removeCallbackFunc)) { - this._removeCallbackFunc(); - this._removeCallbackFunc = undefined; + var unitSpherical = czmlInterval.unitSpherical; + if (defined(unitSpherical)) { + return convertUnitSphericalToCartesian(unitSpherical); } - this._textureAtlas = this._destroyTextureAtlas && this._textureAtlas && this._textureAtlas.destroy(); - this._sp = this._sp && this._sp.destroy(); - this._spTranslucent = this._spTranslucent && this._spTranslucent.destroy(); - this._spPick = this._spPick && this._spPick.destroy(); - this._vaf = this._vaf && this._vaf.destroy(); - destroyBillboards(this._billboards); + var spherical = czmlInterval.spherical; + if (defined(spherical)) { + return convertSphericalToCartesian(spherical); + } - return destroyObject(this); - }; + var cartographicRadians = czmlInterval.cartographicRadians; + if (defined(cartographicRadians)) { + return convertCartographicRadiansToCartesian(cartographicRadians); + } - return BillboardCollection; -}); + var cartographicDegrees = czmlInterval.cartographicDegrees; + if (defined(cartographicDegrees)) { + return convertCartographicDegreesToCartesian(cartographicDegrees); + } -define('Scene/LabelStyle',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + throw new RuntimeError(JSON.stringify(czmlInterval) + ' is not a valid CZML interval.'); + } - /** - * Describes how to draw a label. - * - * @exports LabelStyle - * - * @see Label#style - */ - var LabelStyle = { - /** - * Fill the text of the label, but do not outline. - * - * @type {Number} - * @constant - */ - FILL : 0, + function normalizePackedCartesianArray(array, startingIndex) { + Cartesian3.unpack(array, startingIndex, scratchCartesian); + Cartesian3.normalize(scratchCartesian, scratchCartesian); + Cartesian3.pack(scratchCartesian, array, startingIndex); + } - /** - * Outline the text of the label, but do not fill. - * - * @type {Number} - * @constant - */ - OUTLINE : 1, + function unwrapUnitCartesianInterval(czmlInterval) { + var cartesian = unwrapCartesianInterval(czmlInterval); + if (cartesian.length === 3) { + normalizePackedCartesianArray(cartesian, 0); + return cartesian; + } - /** - * Fill and outline the text of the label. - * - * @type {Number} - * @constant - */ - FILL_AND_OUTLINE : 2 - }; + for (var i = 1; i < cartesian.length; i += 4) { + normalizePackedCartesianArray(cartesian, i); + } - return freezeObject(LabelStyle); -}); + return cartesian; + } -define('Scene/Label',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/freezeObject', - '../Core/NearFarScalar', - './Billboard', - './HeightReference', - './HorizontalOrigin', - './LabelStyle', - './VerticalOrigin' - ], function( - BoundingRectangle, - Cartesian2, - Cartesian3, - Color, - defaultValue, - defined, - defineProperties, - DeveloperError, - DistanceDisplayCondition, - freezeObject, - NearFarScalar, - Billboard, - HeightReference, - HorizontalOrigin, - LabelStyle, - VerticalOrigin) { - 'use strict'; + function normalizePackedQuaternionArray(array, startingIndex) { + Quaternion.unpack(array, startingIndex, scratchQuaternion); + Quaternion.normalize(scratchQuaternion, scratchQuaternion); + Quaternion.pack(scratchQuaternion, array, startingIndex); + } - var textTypes = freezeObject({ - LTR : 0, - RTL : 1, - WEAK : 2, - BRACKETS : 3 - }); + function unwrapQuaternionInterval(czmlInterval) { + var unitQuaternion = czmlInterval.unitQuaternion; + if (defined(unitQuaternion)) { + if (unitQuaternion.length === 4) { + normalizePackedQuaternionArray(unitQuaternion, 0); + return unitQuaternion; + } - function rebindAllGlyphs(label) { - if (!label._rebindAllGlyphs && !label._repositionAllGlyphs) { - // only push label if it's not already been marked dirty - label._labelCollection._labelsToUpdate.push(label); + for (var i = 1; i < unitQuaternion.length; i += 5) { + normalizePackedQuaternionArray(unitQuaternion, i); + } } - label._rebindAllGlyphs = true; + return unitQuaternion; } - function repositionAllGlyphs(label) { - if (!label._rebindAllGlyphs && !label._repositionAllGlyphs) { - // only push label if it's not already been marked dirty - label._labelCollection._labelsToUpdate.push(label); + function getPropertyType(czmlInterval) { + // The associations in this function need to be kept in sync with the + // associations in unwrapInterval. + + // Intentionally omitted due to conficts in CZML property names: + // * Image (conflicts with Uri) + // * Rotation (conflicts with Number) + // + // cartesianVelocity is also omitted due to incomplete support for + // derivative information in CZML properties. + // (Currently cartesianVelocity is hacked directly into the position processing code) + if (typeof czmlInterval === 'boolean') { + return Boolean; + } else if (typeof czmlInterval === 'number') { + return Number; + } else if (typeof czmlInterval === 'string') { + return String; + } else if (czmlInterval.hasOwnProperty('array')) { + return Array; + } else if (czmlInterval.hasOwnProperty('boolean')) { + return Boolean; + } else if (czmlInterval.hasOwnProperty('boundingRectangle')) { + return BoundingRectangle; + } else if (czmlInterval.hasOwnProperty('cartesian2')) { + return Cartesian2; + } else if (czmlInterval.hasOwnProperty('cartesian') || + czmlInterval.hasOwnProperty('spherical') || + czmlInterval.hasOwnProperty('cartographicRadians') || + czmlInterval.hasOwnProperty('cartographicDegrees')) { + return Cartesian3; + } else if (czmlInterval.hasOwnProperty('unitCartesian') || + czmlInterval.hasOwnProperty('unitSpherical')) { + return UnitCartesian3; + } else if (czmlInterval.hasOwnProperty('rgba') || + czmlInterval.hasOwnProperty('rgbaf')) { + return Color; + } else if (czmlInterval.hasOwnProperty('colorBlendMode')) { + return ColorBlendMode; + } else if (czmlInterval.hasOwnProperty('cornerType')) { + return CornerType; + } else if (czmlInterval.hasOwnProperty('heightReference')) { + return HeightReference; + } else if (czmlInterval.hasOwnProperty('horizontalOrigin')) { + return HorizontalOrigin; + } else if (czmlInterval.hasOwnProperty('date')) { + return JulianDate; + } else if (czmlInterval.hasOwnProperty('labelStyle')) { + return LabelStyle; + } else if (czmlInterval.hasOwnProperty('number')) { + return Number; + } else if (czmlInterval.hasOwnProperty('nearFarScalar')) { + return NearFarScalar; + } else if (czmlInterval.hasOwnProperty('distanceDisplayCondition')) { + return DistanceDisplayCondition; + } else if (czmlInterval.hasOwnProperty('object') || + czmlInterval.hasOwnProperty('value')) { + return Object; + } else if (czmlInterval.hasOwnProperty('unitQuaternion')) { + return Quaternion; + } else if (czmlInterval.hasOwnProperty('shadowMode')) { + return ShadowMode; + } else if (czmlInterval.hasOwnProperty('string')) { + return String; + } else if (czmlInterval.hasOwnProperty('stripeOrientation')) { + return StripeOrientation; + } else if (czmlInterval.hasOwnProperty('wsen') || + czmlInterval.hasOwnProperty('wsenDegrees')) { + return Rectangle; + } else if (czmlInterval.hasOwnProperty('uri')) { + return Uri; + } else if (czmlInterval.hasOwnProperty('verticalOrigin')) { + return VerticalOrigin; } - label._repositionAllGlyphs = true; + // fallback case + return Object; } - /** - * A Label draws viewport-aligned text positioned in the 3D scene. This constructor - * should not be used directly, instead create labels by calling {@link LabelCollection#add}. - * - * @alias Label - * @internalConstructor - * - * @exception {DeveloperError} translucencyByDistance.far must be greater than translucencyByDistance.near - * @exception {DeveloperError} pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near - * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near - * - * @see LabelCollection - * @see LabelCollection#add - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Labels.html|Cesium Sandcastle Labels Demo} - */ - function Label(options, labelCollection) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function unwrapInterval(type, czmlInterval, sourceUri) { + // The associations in this function need to be kept in sync with the + // associations in getPropertyType + switch (type) { + case Array: + return czmlInterval.array; + case Boolean: + return defaultValue(czmlInterval['boolean'], czmlInterval); + case BoundingRectangle: + return czmlInterval.boundingRectangle; + case Cartesian2: + return czmlInterval.cartesian2; + case Cartesian3: + return unwrapCartesianInterval(czmlInterval); + case UnitCartesian3: + return unwrapUnitCartesianInterval(czmlInterval); + case Color: + return unwrapColorInterval(czmlInterval); + case ColorBlendMode: + return ColorBlendMode[defaultValue(czmlInterval.colorBlendMode, czmlInterval)]; + case CornerType: + return CornerType[defaultValue(czmlInterval.cornerType, czmlInterval)]; + case HeightReference: + return HeightReference[defaultValue(czmlInterval.heightReference, czmlInterval)]; + case HorizontalOrigin: + return HorizontalOrigin[defaultValue(czmlInterval.horizontalOrigin, czmlInterval)]; + case Image: + return unwrapUriInterval(czmlInterval, sourceUri); + case JulianDate: + return JulianDate.fromIso8601(defaultValue(czmlInterval.date, czmlInterval)); + case LabelStyle: + return LabelStyle[defaultValue(czmlInterval.labelStyle, czmlInterval)]; + case Number: + return defaultValue(czmlInterval.number, czmlInterval); + case NearFarScalar: + return czmlInterval.nearFarScalar; + case DistanceDisplayCondition: + return czmlInterval.distanceDisplayCondition; + case Object: + return defaultValue(defaultValue(czmlInterval.object, czmlInterval.value), czmlInterval); + case Quaternion: + return unwrapQuaternionInterval(czmlInterval); + case Rotation: + return defaultValue(czmlInterval.number, czmlInterval); + case ShadowMode: + return ShadowMode[defaultValue(defaultValue(czmlInterval.shadowMode, czmlInterval.shadows), czmlInterval)]; + case String: + return defaultValue(czmlInterval.string, czmlInterval); + case StripeOrientation: + return StripeOrientation[defaultValue(czmlInterval.stripeOrientation, czmlInterval)]; + case Rectangle: + return unwrapRectangleInterval(czmlInterval); + case Uri: + return unwrapUriInterval(czmlInterval, sourceUri); + case VerticalOrigin: + return VerticalOrigin[defaultValue(czmlInterval.verticalOrigin, czmlInterval)]; + default: + throw new RuntimeError(type); + } + } - if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + var interpolators = { + HERMITE : HermitePolynomialApproximation, + LAGRANGE : LagrangePolynomialApproximation, + LINEAR : LinearApproximation + }; + + function updateInterpolationSettings(packetData, property) { + var interpolationAlgorithm = packetData.interpolationAlgorithm; + if (defined(interpolationAlgorithm) || defined(packetData.interpolationDegree)) { + property.setInterpolationOptions({ + interpolationAlgorithm : interpolators[interpolationAlgorithm], + interpolationDegree : packetData.interpolationDegree + }); } - - var translucencyByDistance = options.translucencyByDistance; - var pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; - var scaleByDistance = options.scaleByDistance; - var distanceDisplayCondition = options.distanceDisplayCondition; - if (defined(translucencyByDistance)) { - if (translucencyByDistance.far <= translucencyByDistance.near) { - throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); - } - translucencyByDistance = NearFarScalar.clone(translucencyByDistance); + + var forwardExtrapolationType = packetData.forwardExtrapolationType; + if (defined(forwardExtrapolationType)) { + property.forwardExtrapolationType = ExtrapolationType[forwardExtrapolationType]; } - if (defined(pixelOffsetScaleByDistance)) { - if (pixelOffsetScaleByDistance.far <= pixelOffsetScaleByDistance.near) { - throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); - } - pixelOffsetScaleByDistance = NearFarScalar.clone(pixelOffsetScaleByDistance); + + var forwardExtrapolationDuration = packetData.forwardExtrapolationDuration; + if (defined(forwardExtrapolationDuration)) { + property.forwardExtrapolationDuration = forwardExtrapolationDuration; } - if (defined(scaleByDistance)) { - if (scaleByDistance.far <= scaleByDistance.near) { - throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); - } - scaleByDistance = NearFarScalar.clone(scaleByDistance); + + var backwardExtrapolationType = packetData.backwardExtrapolationType; + if (defined(backwardExtrapolationType)) { + property.backwardExtrapolationType = ExtrapolationType[backwardExtrapolationType]; } - if (defined(distanceDisplayCondition)) { - if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); - } - distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); + + var backwardExtrapolationDuration = packetData.backwardExtrapolationDuration; + if (defined(backwardExtrapolationDuration)) { + property.backwardExtrapolationDuration = backwardExtrapolationDuration; } + } - this._renderedText = undefined; - this._text = undefined; - this._show = defaultValue(options.show, true); - this._font = defaultValue(options.font, '30px sans-serif'); - this._fillColor = Color.clone(defaultValue(options.fillColor, Color.WHITE)); - this._outlineColor = Color.clone(defaultValue(options.outlineColor, Color.BLACK)); - this._outlineWidth = defaultValue(options.outlineWidth, 1.0); - this._showBackground = defaultValue(options.showBackground, false); - this._backgroundColor = defaultValue(options.backgroundColor, new Color(0.165, 0.165, 0.165, 0.8)); - this._backgroundPadding = defaultValue(options.backgroundPadding, new Cartesian2(7, 5)); - this._style = defaultValue(options.style, LabelStyle.FILL); - this._verticalOrigin = defaultValue(options.verticalOrigin, VerticalOrigin.BASELINE); - this._horizontalOrigin = defaultValue(options.horizontalOrigin, HorizontalOrigin.LEFT); - this._pixelOffset = Cartesian2.clone(defaultValue(options.pixelOffset, Cartesian2.ZERO)); - this._eyeOffset = Cartesian3.clone(defaultValue(options.eyeOffset, Cartesian3.ZERO)); - this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); - this._scale = defaultValue(options.scale, 1.0); - this._id = options.id; - this._translucencyByDistance = translucencyByDistance; - this._pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; - this._scaleByDistance = scaleByDistance; - this._heightReference = defaultValue(options.heightReference, HeightReference.NONE); - this._distanceDisplayCondition = distanceDisplayCondition; - this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); + var iso8601Scratch = { + iso8601 : undefined + }; - this._labelCollection = labelCollection; - this._glyphs = []; - this._backgroundBillboard = undefined; + function processProperty(type, object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection) { + var combinedInterval; + var packetInterval = packetData.interval; + if (defined(packetInterval)) { + iso8601Scratch.iso8601 = packetInterval; + combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); + if (defined(constrainedInterval)) { + combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); + } + } else if (defined(constrainedInterval)) { + combinedInterval = constrainedInterval; + } - this._rebindAllGlyphs = true; - this._repositionAllGlyphs = true; + var packedLength; + var isSampled; + var unwrappedInterval; + var unwrappedIntervalLength; - this._actualClampedPosition = undefined; - this._removeCallbackFunc = undefined; - this._mode = undefined; + // CZML properties can be defined in many ways. Most ways represent a structure for + // encoding a single value (number, string, cartesian, etc.) Regardless of the value type, + // if it encodes a single value it will get loaded into a ConstantProperty eventually. + // Alternatively, there are ways of defining a property that require specialized + // client-side representation. Currently, these are ReferenceProperty, + // and client-side velocity computation properties such as VelocityVectorProperty. + var isValue = !defined(packetData.reference) && !defined(packetData.velocityReference); + var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL); - this._clusterShow = true; + if (isValue) { + unwrappedInterval = unwrapInterval(type, packetData, sourceUri); + packedLength = defaultValue(type.packedLength, 1); + unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1); + isSampled = !defined(packetData.array) && (typeof unwrappedInterval !== 'string') && (unwrappedIntervalLength > packedLength) && (type !== Object); + } - this.text = defaultValue(options.text, ''); + //Rotation is a special case because it represents a native type (Number) + //and therefore does not need to be unpacked when loaded as a constant value. + var needsUnpacking = typeof type.unpack === 'function' && type !== Rotation; - this._updateClamping(); - } + //Any time a constant value is assigned, it completely blows away anything else. + if (!isSampled && !hasInterval) { + if (isValue) { + object[propertyName] = new ConstantProperty(needsUnpacking ? type.unpack(unwrappedInterval, 0) : unwrappedInterval); + } else { + object[propertyName] = createSpecializedProperty(type, entityCollection, packetData); + } + return; + } - defineProperties(Label.prototype, { - /** - * Determines if this label will be shown. Use this to hide or show a label, instead - * of removing it and re-adding it to the collection. - * @memberof Label.prototype - * @type {Boolean} - * @default true - */ - show : { - get : function() { - return this._show; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._show !== value) { - this._show = value; + var property = object[propertyName]; - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var billboard = glyphs[i].billboard; - if (defined(billboard)) { - billboard.show = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.show = value; - } - } + var epoch; + var packetEpoch = packetData.epoch; + if (defined(packetEpoch)) { + epoch = JulianDate.fromIso8601(packetEpoch); + } + + //Without an interval, any sampled value is infinite, meaning it completely + //replaces any non-sampled property that may exist. + if (isSampled && !hasInterval) { + if (!(property instanceof SampledProperty)) { + property = new SampledProperty(type); + object[propertyName] = property; } - }, + property.addSamplesPackedArray(unwrappedInterval, epoch); + updateInterpolationSettings(packetData, property); + return; + } - /** - * Gets or sets the Cartesian position of this label. - * @memberof Label.prototype - * @type {Cartesian3} - */ - position : { - get : function() { - return this._position; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var position = this._position; - if (!Cartesian3.equals(position, value)) { - Cartesian3.clone(value, position); + var interval; - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var billboard = glyphs[i].billboard; - if (defined(billboard)) { - billboard.position = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.position = value; - } + //A constant value with an interval is normally part of a TimeIntervalCollection, + //However, if the current property is not a time-interval collection, we need + //to turn it into a Composite, preserving the old data with the new interval. + if (!isSampled && hasInterval) { + //Create a new interval for the constant value. + combinedInterval = combinedInterval.clone(); + if (isValue) { + combinedInterval.data = needsUnpacking ? type.unpack(unwrappedInterval, 0) : unwrappedInterval; + } else { + combinedInterval.data = createSpecializedProperty(type, entityCollection, packetData); + } - this._updateClamping(); + //If no property exists, simply use a new interval collection + if (!defined(property)) { + if (isValue) { + property = new TimeIntervalCollectionProperty(); + } else { + property = new CompositeProperty(); } + object[propertyName] = property; } - }, - /** - * Gets or sets the height reference of this billboard. - * @memberof Label.prototype - * @type {HeightReference} - * @default HeightReference.NONE - */ - heightReference : { - get : function() { - return this._heightReference; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); + if (isValue && property instanceof TimeIntervalCollectionProperty) { + //If we create a collection, or it already existed, use it. + property.intervals.addInterval(combinedInterval); + } else if (property instanceof CompositeProperty) { + //If the collection was already a CompositeProperty, use it. + if (isValue) { + combinedInterval.data = new ConstantProperty(combinedInterval.data); } - - if (value !== this._heightReference) { - this._heightReference = value; + property.intervals.addInterval(combinedInterval); + } else { + //Otherwise, create a CompositeProperty but preserve the existing data. - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var billboard = glyphs[i].billboard; - if (defined(billboard)) { - billboard.heightReference = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.heightReference = value; - } + //Put the old property in an infinite interval. + interval = Iso8601.MAXIMUM_INTERVAL.clone(); + interval.data = property; - repositionAllGlyphs(this); + //Create the composite. + property = new CompositeProperty(); + object[propertyName] = property; - this._updateClamping(); - } - } - }, + //add the old property interval + property.intervals.addInterval(interval); - /** - * Gets or sets the text of this label. - * @memberof Label.prototype - * @type {String} - */ - text : { - get : function() { - return this._text; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._text !== value) { - this._text = value; - this._renderedText = Label.enableRightToLeftDetection ? reverseRtl(value) : value; - rebindAllGlyphs(this); + //Change the new data to a ConstantProperty and add it. + if (isValue) { + combinedInterval.data = new ConstantProperty(combinedInterval.data); } + property.intervals.addInterval(combinedInterval); } - }, - /** - * Gets or sets the font used to draw this label. Fonts are specified using the same syntax as the CSS 'font' property. - * @memberof Label.prototype - * @type {String} - * @default '30px sans-serif' - * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles|HTML canvas 2D context text styles} - */ - font : { - get : function() { - return this._font; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._font !== value) { - this._font = value; - rebindAllGlyphs(this); - } - } - }, + return; + } - /** - * Gets or sets the fill color of this label. - * @memberof Label.prototype - * @type {Color} - * @default Color.WHITE - * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} - */ - fillColor : { - get : function() { - return this._fillColor; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var fillColor = this._fillColor; - if (!Color.equals(fillColor, value)) { - Color.clone(value, fillColor); - rebindAllGlyphs(this); - } + //isSampled && hasInterval + if (!defined(property)) { + property = new CompositeProperty(); + object[propertyName] = property; + } + + //create a CompositeProperty but preserve the existing data. + if (!(property instanceof CompositeProperty)) { + //Put the old property in an infinite interval. + interval = Iso8601.MAXIMUM_INTERVAL.clone(); + interval.data = property; + + //Create the composite. + property = new CompositeProperty(); + object[propertyName] = property; + + //add the old property interval + property.intervals.addInterval(interval); + } + + //Check if the interval already exists in the composite + var intervals = property.intervals; + interval = intervals.findInterval(combinedInterval); + if (!defined(interval) || !(interval.data instanceof SampledProperty)) { + //If not, create a SampledProperty for it. + interval = combinedInterval.clone(); + interval.data = new SampledProperty(type); + intervals.addInterval(interval); + } + interval.data.addSamplesPackedArray(unwrappedInterval, epoch); + updateInterpolationSettings(packetData, interval.data); + } + + function processPacketData(type, object, propertyName, packetData, interval, sourceUri, entityCollection) { + if (!defined(packetData)) { + return; + } + + if (isArray(packetData)) { + for (var i = 0, len = packetData.length; i < len; i++) { + processProperty(type, object, propertyName, packetData[i], interval, sourceUri, entityCollection); } - }, + } else { + processProperty(type, object, propertyName, packetData, interval, sourceUri, entityCollection); + } + } - /** - * Gets or sets the outline color of this label. - * @memberof Label.prototype - * @type {Color} - * @default Color.BLACK - * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} - */ - outlineColor : { - get : function() { - return this._outlineColor; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var outlineColor = this._outlineColor; - if (!Color.equals(outlineColor, value)) { - Color.clone(value, outlineColor); - rebindAllGlyphs(this); - } + function processPositionProperty(object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection) { + var combinedInterval; + var packetInterval = packetData.interval; + if (defined(packetInterval)) { + iso8601Scratch.iso8601 = packetInterval; + combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); + if (defined(constrainedInterval)) { + combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); } - }, + } else if (defined(constrainedInterval)) { + combinedInterval = constrainedInterval; + } - /** - * Gets or sets the outline width of this label. - * @memberof Label.prototype - * @type {Number} - * @default 1.0 - * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} - */ - outlineWidth : { - get : function() { - return this._outlineWidth; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._outlineWidth !== value) { - this._outlineWidth = value; - rebindAllGlyphs(this); - } + var referenceFrame; + var unwrappedInterval; + var isSampled = false; + var unwrappedIntervalLength; + var numberOfDerivatives = defined(packetData.cartesianVelocity) ? 1 : 0; + var packedLength = Cartesian3.packedLength * (numberOfDerivatives + 1); + var isValue = !defined(packetData.reference); + var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL); + + if (isValue) { + if (defined(packetData.referenceFrame)) { + referenceFrame = ReferenceFrame[packetData.referenceFrame]; } - }, + referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); + unwrappedInterval = unwrapCartesianInterval(packetData); + unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1); + isSampled = unwrappedIntervalLength > packedLength; + } - /** - * Determines if a background behind this label will be shown. - * @memberof Label.prototype - * @default false - * @type {Boolean} - */ - showBackground : { - get : function() { - return this._showBackground; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._showBackground !== value) { - this._showBackground = value; - rebindAllGlyphs(this); - } + //Any time a constant value is assigned, it completely blows away anything else. + if (!isSampled && !hasInterval) { + if (isValue) { + object[propertyName] = new ConstantPositionProperty(Cartesian3.unpack(unwrappedInterval), referenceFrame); + } else { + object[propertyName] = createReferenceProperty(entityCollection, packetData.reference); } - }, + return; + } - /** - * Gets or sets the background color of this label. - * @memberof Label.prototype - * @type {Color} - * @default new Color(0.165, 0.165, 0.165, 0.8) - */ - backgroundColor : { - get : function() { - return this._backgroundColor; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var backgroundColor = this._backgroundColor; - if (!Color.equals(backgroundColor, value)) { - Color.clone(value, backgroundColor); + var property = object[propertyName]; - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.color = backgroundColor; - } - } + var epoch; + var packetEpoch = packetData.epoch; + if (defined(packetEpoch)) { + epoch = JulianDate.fromIso8601(packetEpoch); + } + + //Without an interval, any sampled value is infinite, meaning it completely + //replaces any non-sampled property that may exist. + if (isSampled && !hasInterval) { + if (!(property instanceof SampledPositionProperty) || (defined(referenceFrame) && property.referenceFrame !== referenceFrame)) { + property = new SampledPositionProperty(referenceFrame, numberOfDerivatives); + object[propertyName] = property; } - }, + property.addSamplesPackedArray(unwrappedInterval, epoch); + updateInterpolationSettings(packetData, property); + return; + } - /** - * Gets or sets the background padding, in pixels, of this label. The <code>x</code> value - * controls horizontal padding, and the <code>y</code> value controls vertical padding. - * @memberof Label.prototype - * @type {Cartesian2} - * @default new Cartesian2(7, 5) - */ - backgroundPadding : { - get : function() { - return this._backgroundPadding; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var backgroundPadding = this._backgroundPadding; - if (!Cartesian2.equals(backgroundPadding, value)) { - Cartesian2.clone(value, backgroundPadding); - repositionAllGlyphs(this); - } + var interval; + + //A constant value with an interval is normally part of a TimeIntervalCollection, + //However, if the current property is not a time-interval collection, we need + //to turn it into a Composite, preserving the old data with the new interval. + if (!isSampled && hasInterval) { + //Create a new interval for the constant value. + combinedInterval = combinedInterval.clone(); + if (isValue) { + combinedInterval.data = Cartesian3.unpack(unwrappedInterval); + } else { + combinedInterval.data = createReferenceProperty(entityCollection, packetData.reference); } - }, - /** - * Gets or sets the style of this label. - * @memberof Label.prototype - * @type {LabelStyle} - * @default LabelStyle.FILL - */ - style : { - get : function() { - return this._style; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._style !== value) { - this._style = value; - rebindAllGlyphs(this); + //If no property exists, simply use a new interval collection + if (!defined(property)) { + if (isValue) { + property = new TimeIntervalCollectionPositionProperty(referenceFrame); + } else { + property = new CompositePositionProperty(referenceFrame); } + object[propertyName] = property; } - }, - /** - * Gets or sets the pixel offset in screen space from the origin of this label. This is commonly used - * to align multiple labels and billboards at the same position, e.g., an image and text. The - * screen space origin is the top, left corner of the canvas; <code>x</code> increases from - * left to right, and <code>y</code> increases from top to bottom. - * <br /><br /> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><code>default</code><br/><img src='Images/Label.setPixelOffset.default.png' width='250' height='188' /></td> - * <td align='center'><code>l.pixeloffset = new Cartesian2(25, 75);</code><br/><img src='Images/Label.setPixelOffset.x50y-25.png' width='250' height='188' /></td> - * </tr></table> - * The label's origin is indicated by the yellow point. - * </div> - * @memberof Label.prototype - * @type {Cartesian2} - * @default Cartesian2.ZERO - */ - pixelOffset : { - get : function() { - return this._pixelOffset; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); + if (isValue && property instanceof TimeIntervalCollectionPositionProperty && (defined(referenceFrame) && property.referenceFrame === referenceFrame)) { + //If we create a collection, or it already existed, use it. + property.intervals.addInterval(combinedInterval); + } else if (property instanceof CompositePositionProperty) { + //If the collection was already a CompositePositionProperty, use it. + if (isValue) { + combinedInterval.data = new ConstantPositionProperty(combinedInterval.data, referenceFrame); } - - var pixelOffset = this._pixelOffset; - if (!Cartesian2.equals(pixelOffset, value)) { - Cartesian2.clone(value, pixelOffset); + property.intervals.addInterval(combinedInterval); + } else { + //Otherwise, create a CompositePositionProperty but preserve the existing data. - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.pixelOffset = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.pixelOffset = value; - } - } - } - }, + //Put the old property in an infinite interval. + interval = Iso8601.MAXIMUM_INTERVAL.clone(); + interval.data = property; - /** - * Gets or sets near and far translucency properties of a Label based on the Label's distance from the camera. - * A label's translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the label's translucency remains clamped to the nearest bound. If undefined, - * translucencyByDistance will be disabled. - * @memberof Label.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a label's translucencyByDistance to 1.0 when the - * // camera is 1500 meters from the label and disappear as - * // the camera distance approaches 8.0e6 meters. - * text.translucencyByDistance = new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.0); - * - * @example - * // Example 2. - * // disable translucency by distance - * text.translucencyByDistance = undefined; - */ - translucencyByDistance : { - get : function() { - return this._translucencyByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var translucencyByDistance = this._translucencyByDistance; - if (!NearFarScalar.equals(translucencyByDistance, value)) { - this._translucencyByDistance = NearFarScalar.clone(value, translucencyByDistance); + //Create the composite. + property = new CompositePositionProperty(property.referenceFrame); + object[propertyName] = property; - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.translucencyByDistance = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.translucencyByDistance = value; - } + //add the old property interval + property.intervals.addInterval(interval); + + //Change the new data to a ConstantPositionProperty and add it. + if (isValue) { + combinedInterval.data = new ConstantPositionProperty(combinedInterval.data, referenceFrame); } + property.intervals.addInterval(combinedInterval); } - }, - /** - * Gets or sets near and far pixel offset scaling properties of a Label based on the Label's distance from the camera. - * A label's pixel offset will be scaled between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the label's pixel offset scaling remains clamped to the nearest bound. If undefined, - * pixelOffsetScaleByDistance will be disabled. - * @memberof Label.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a label's pixel offset scale to 0.0 when the - * // camera is 1500 meters from the label and scale pixel offset to 10.0 pixels - * // in the y direction the camera distance approaches 8.0e6 meters. - * text.pixelOffset = new Cesium.Cartesian2(0.0, 1.0); - * text.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(1.5e2, 0.0, 8.0e6, 10.0); - * - * @example - * // Example 2. - * // disable pixel offset by distance - * text.pixelOffsetScaleByDistance = undefined; - */ - pixelOffsetScaleByDistance : { - get : function() { - return this._pixelOffsetScaleByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; - if (!NearFarScalar.equals(pixelOffsetScaleByDistance, value)) { - this._pixelOffsetScaleByDistance = NearFarScalar.clone(value, pixelOffsetScaleByDistance); + return; + } - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.pixelOffsetScaleByDistance = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.pixelOffsetScaleByDistance = value; - } - } - } - }, + //isSampled && hasInterval + if (!defined(property)) { + property = new CompositePositionProperty(referenceFrame); + object[propertyName] = property; + } else if (!(property instanceof CompositePositionProperty)) { + //create a CompositeProperty but preserve the existing data. + //Put the old property in an infinite interval. + interval = Iso8601.MAXIMUM_INTERVAL.clone(); + interval.data = property; - /** - * Gets or sets near and far scaling properties of a Label based on the label's distance from the camera. - * A label's scale will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the label's scale remains clamped to the nearest bound. If undefined, - * scaleByDistance will be disabled. - * @memberof Label.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a label's scaleByDistance to scale by 1.5 when the - * // camera is 1500 meters from the label and disappear as - * // the camera distance approaches 8.0e6 meters. - * label.scaleByDistance = new Cesium.NearFarScalar(1.5e2, 1.5, 8.0e6, 0.0); - * - * @example - * // Example 2. - * // disable scaling by distance - * label.scaleByDistance = undefined; - */ - scaleByDistance : { - get : function() { - return this._scaleByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var scaleByDistance = this._scaleByDistance; - if (!NearFarScalar.equals(scaleByDistance, value)) { - this._scaleByDistance = NearFarScalar.clone(value, scaleByDistance); + //Create the composite. + property = new CompositePositionProperty(property.referenceFrame); + object[propertyName] = property; - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.scaleByDistance = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.scaleByDistance = value; - } - } - } - }, + //add the old property interval + property.intervals.addInterval(interval); + } - /** - * Gets and sets the 3D Cartesian offset applied to this label in eye coordinates. Eye coordinates is a left-handed - * coordinate system, where <code>x</code> points towards the viewer's right, <code>y</code> points up, and - * <code>z</code> points into the screen. Eye coordinates use the same scale as world and model coordinates, - * which is typically meters. - * <br /><br /> - * An eye offset is commonly used to arrange multiple label or objects at the same position, e.g., to - * arrange a label above its corresponding 3D model. - * <br /><br /> - * Below, the label is positioned at the center of the Earth but an eye offset makes it always - * appear on top of the Earth regardless of the viewer's or Earth's orientation. - * <br /><br /> - * <div align='center'> - * <table border='0' cellpadding='5'><tr> - * <td align='center'><img src='Images/Billboard.setEyeOffset.one.png' width='250' height='188' /></td> - * <td align='center'><img src='Images/Billboard.setEyeOffset.two.png' width='250' height='188' /></td> - * </tr></table> - * <code>l.eyeOffset = new Cartesian3(0.0, 8000000.0, 0.0);</code><br /><br /> - * </div> - * @memberof Label.prototype - * @type {Cartesian3} - * @default Cartesian3.ZERO - */ - eyeOffset : { - get : function() { - return this._eyeOffset; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var eyeOffset = this._eyeOffset; - if (!Cartesian3.equals(eyeOffset, value)) { - Cartesian3.clone(value, eyeOffset); + //Check if the interval already exists in the composite + var intervals = property.intervals; + interval = intervals.findInterval(combinedInterval); + if (!defined(interval) || !(interval.data instanceof SampledPositionProperty) || (defined(referenceFrame) && interval.data.referenceFrame !== referenceFrame)) { + //If not, create a SampledPositionProperty for it. + interval = combinedInterval.clone(); + interval.data = new SampledPositionProperty(referenceFrame, numberOfDerivatives); + intervals.addInterval(interval); + } + interval.data.addSamplesPackedArray(unwrappedInterval, epoch); + updateInterpolationSettings(packetData, interval.data); + } - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.eyeOffset = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.eyeOffset = value; - } - } + function processPositionPacketData(object, propertyName, packetData, interval, sourceUri, entityCollection) { + if (!defined(packetData)) { + return; + } + + if (isArray(packetData)) { + for (var i = 0, len = packetData.length; i < len; i++) { + processPositionProperty(object, propertyName, packetData[i], interval, sourceUri, entityCollection); } - }, + } else { + processPositionProperty(object, propertyName, packetData, interval, sourceUri, entityCollection); + } + } - /** - * Gets or sets the horizontal origin of this label, which determines if the label is drawn - * to the left, center, or right of its anchor position. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> - * </div> - * @memberof Label.prototype - * @type {HorizontalOrigin} - * @default HorizontalOrigin.LEFT - * @example - * // Use a top, right origin - * l.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT; - * l.verticalOrigin = Cesium.VerticalOrigin.TOP; - */ - horizontalOrigin : { - get : function() { - return this._horizontalOrigin; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._horizontalOrigin !== value) { - this._horizontalOrigin = value; - repositionAllGlyphs(this); - } + function processMaterialProperty(object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection) { + var combinedInterval; + var packetInterval = packetData.interval; + if (defined(packetInterval)) { + iso8601Scratch.iso8601 = packetInterval; + combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); + if (defined(constrainedInterval)) { + combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); } - }, + } else if (defined(constrainedInterval)) { + combinedInterval = constrainedInterval; + } - /** - * Gets or sets the vertical origin of this label, which determines if the label is - * to the above, below, or at the center of its anchor position. - * <br /><br /> - * <div align='center'> - * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> - * </div> - * @memberof Label.prototype - * @type {VerticalOrigin} - * @default VerticalOrigin.BASELINE - * @example - * // Use a top, right origin - * l.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT; - * l.verticalOrigin = Cesium.VerticalOrigin.TOP; - */ - verticalOrigin : { - get : function() { - return this._verticalOrigin; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._verticalOrigin !== value) { - this._verticalOrigin = value; + var property = object[propertyName]; + var existingMaterial; + var existingInterval; - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.verticalOrigin = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.verticalOrigin = value; - } + if (defined(combinedInterval)) { + if (!(property instanceof CompositeMaterialProperty)) { + property = new CompositeMaterialProperty(); + object[propertyName] = property; + } + //See if we already have data at that interval. + var thisIntervals = property.intervals; + existingInterval = thisIntervals.findInterval({ + start : combinedInterval.start, + stop : combinedInterval.stop + }); + if (defined(existingInterval)) { + //We have an interval, but we need to make sure the + //new data is the same type of material as the old data. + existingMaterial = existingInterval.data; + } else { + //If not, create it. + existingInterval = combinedInterval.clone(); + thisIntervals.addInterval(existingInterval); + } + } else { + existingMaterial = property; + } - repositionAllGlyphs(this); - } + var materialData; + if (defined(packetData.solidColor)) { + if (!(existingMaterial instanceof ColorMaterialProperty)) { + existingMaterial = new ColorMaterialProperty(); } - }, + materialData = packetData.solidColor; + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, undefined, entityCollection); + } else if (defined(packetData.grid)) { + if (!(existingMaterial instanceof GridMaterialProperty)) { + existingMaterial = new GridMaterialProperty(); + } + materialData = packetData.grid; + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection); + processPacketData(Number, existingMaterial, 'cellAlpha', materialData.cellAlpha, undefined, sourceUri, entityCollection); + processPacketData(Cartesian2, existingMaterial, 'lineCount', materialData.lineCount, undefined, sourceUri, entityCollection); + processPacketData(Cartesian2, existingMaterial, 'lineThickness', materialData.lineThickness, undefined, sourceUri, entityCollection); + processPacketData(Cartesian2, existingMaterial, 'lineOffset', materialData.lineOffset, undefined, sourceUri, entityCollection); + } else if (defined(packetData.image)) { + if (!(existingMaterial instanceof ImageMaterialProperty)) { + existingMaterial = new ImageMaterialProperty(); + } + materialData = packetData.image; + processPacketData(Image, existingMaterial, 'image', materialData.image, undefined, sourceUri, entityCollection); + processPacketData(Cartesian2, existingMaterial, 'repeat', materialData.repeat, undefined, sourceUri, entityCollection); + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection); + processPacketData(Boolean, existingMaterial, 'transparent', materialData.transparent, undefined, sourceUri, entityCollection); + } else if (defined(packetData.stripe)) { + if (!(existingMaterial instanceof StripeMaterialProperty)) { + existingMaterial = new StripeMaterialProperty(); + } + materialData = packetData.stripe; + processPacketData(StripeOrientation, existingMaterial, 'orientation', materialData.orientation, undefined, sourceUri, entityCollection); + processPacketData(Color, existingMaterial, 'evenColor', materialData.evenColor, undefined, sourceUri, entityCollection); + processPacketData(Color, existingMaterial, 'oddColor', materialData.oddColor, undefined, sourceUri, entityCollection); + processPacketData(Number, existingMaterial, 'offset', materialData.offset, undefined, sourceUri, entityCollection); + processPacketData(Number, existingMaterial, 'repeat', materialData.repeat, undefined, sourceUri, entityCollection); + } else if (defined(packetData.polylineOutline)) { + if (!(existingMaterial instanceof PolylineOutlineMaterialProperty)) { + existingMaterial = new PolylineOutlineMaterialProperty(); + } + materialData = packetData.polylineOutline; + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection); + processPacketData(Color, existingMaterial, 'outlineColor', materialData.outlineColor, undefined, sourceUri, entityCollection); + processPacketData(Number, existingMaterial, 'outlineWidth', materialData.outlineWidth, undefined, sourceUri, entityCollection); + } else if (defined(packetData.polylineGlow)) { + if (!(existingMaterial instanceof PolylineGlowMaterialProperty)) { + existingMaterial = new PolylineGlowMaterialProperty(); + } + materialData = packetData.polylineGlow; + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection); + processPacketData(Number, existingMaterial, 'glowPower', materialData.glowPower, undefined, sourceUri, entityCollection); + } else if (defined(packetData.polylineArrow)) { + if (!(existingMaterial instanceof PolylineArrowMaterialProperty)) { + existingMaterial = new PolylineArrowMaterialProperty(); + } + materialData = packetData.polylineArrow; + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, undefined, entityCollection); + } else if (defined(packetData.polylineDash)) { + if (!(existingMaterial instanceof PolylineDashMaterialProperty)) { + existingMaterial = new PolylineDashMaterialProperty(); + } + materialData = packetData.polylineDash; + processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, undefined, entityCollection); + processPacketData(Color, existingMaterial, 'gapColor', materialData.gapColor, undefined, undefined, entityCollection); + processPacketData(Number, existingMaterial, 'dashLength', materialData.dashLength, undefined, sourceUri, entityCollection); + processPacketData(Number, existingMaterial, 'dashPattern', materialData.dashPattern, undefined, sourceUri, entityCollection); + } - /** - * Gets or sets the uniform scale that is multiplied with the label's size in pixels. - * A scale of <code>1.0</code> does not change the size of the label; a scale greater than - * <code>1.0</code> enlarges the label; a positive scale less than <code>1.0</code> shrinks - * the label. - * <br /><br /> - * Applying a large scale value may pixelate the label. To make text larger without pixelation, - * use a larger font size when calling {@link Label#font} instead. - * <br /><br /> - * <div align='center'> - * <img src='Images/Label.setScale.png' width='400' height='300' /><br/> - * From left to right in the above image, the scales are <code>0.5</code>, <code>1.0</code>, - * and <code>2.0</code>. - * </div> - * @memberof Label.prototype - * @type {Number} - * @default 1.0 - */ - scale : { - get : function() { - return this._scale; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._scale !== value) { - this._scale = value; + if (defined(existingInterval)) { + existingInterval.data = existingMaterial; + } else { + object[propertyName] = existingMaterial; + } + } - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.scale = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.scale = value; - } + function processMaterialPacketData(object, propertyName, packetData, interval, sourceUri, entityCollection) { + if (!defined(packetData)) { + return; + } - repositionAllGlyphs(this); - } + if (isArray(packetData)) { + for (var i = 0, len = packetData.length; i < len; i++) { + processMaterialProperty(object, propertyName, packetData[i], interval, sourceUri, entityCollection); } - }, + } else { + processMaterialProperty(object, propertyName, packetData, interval, sourceUri, entityCollection); + } + } - /** - * Gets or sets the condition specifying at what distance from the camera that this label will be displayed. - * @memberof Label.prototype - * @type {DistanceDisplayCondition} - * @default undefined - */ - distanceDisplayCondition : { - get : function() { - return this._distanceDisplayCondition; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far must be greater than near'); - } - if (!DistanceDisplayCondition.equals(value, this._distanceDisplayCondition)) { - this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); + function processName(entity, packet, entityCollection, sourceUri) { + entity.name = defaultValue(packet.name, entity.name); + } - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.distanceDisplayCondition = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.distanceDisplayCondition = value; - } - } + function processDescription(entity, packet, entityCollection, sourceUri) { + var descriptionData = packet.description; + if (defined(descriptionData)) { + processPacketData(String, entity, 'description', descriptionData, undefined, sourceUri, entityCollection); + } + } + + function processPosition(entity, packet, entityCollection, sourceUri) { + var positionData = packet.position; + if (defined(positionData)) { + processPositionPacketData(entity, 'position', positionData, undefined, sourceUri, entityCollection); + } + } + + function processViewFrom(entity, packet, entityCollection, sourceUri) { + var viewFromData = packet.viewFrom; + if (defined(viewFromData)) { + processPacketData(Cartesian3, entity, 'viewFrom', viewFromData, undefined, sourceUri, entityCollection); + } + } + + function processOrientation(entity, packet, entityCollection, sourceUri) { + var orientationData = packet.orientation; + if (defined(orientationData)) { + processPacketData(Quaternion, entity, 'orientation', orientationData, undefined, sourceUri, entityCollection); + } + } + + function processProperties(entity, packet, entityCollection, sourceUri) { + var propertiesData = packet.properties; + if (defined(propertiesData)) { + if (!defined(entity.properties)) { + entity.properties = new PropertyBag(); } - }, + //We cannot simply call processPacketData(entity, 'properties', propertyData, undefined, sourceUri, entityCollection) + //because each property of "properties" may vary separately. + //The properties will be accessible as entity.properties.myprop.getValue(time). - /** - * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. - * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. - * @memberof Label.prototype - * @type {Number} - * @default 0.0 - */ - disableDepthTestDistance : { - get : function() { - return this._disableDepthTestDistance; - }, - set : function(value) { - if (this._disableDepthTestDistance !== value) { - if (!defined(value) || value < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + for (var key in propertiesData) { + if (propertiesData.hasOwnProperty(key)) { + if (!entity.properties.hasProperty(key)) { + entity.properties.addProperty(key); } - this._disableDepthTestDistance = value; - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.disableDepthTestDistance = value; + var propertyData = propertiesData[key]; + if (isArray(propertyData)) { + for (var i = 0, len = propertyData.length; i < len; i++) { + processProperty(getPropertyType(propertyData[i]), entity.properties, key, propertyData[i], undefined, sourceUri, entityCollection); } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.disableDepthTestDistance = value; + } else { + processProperty(getPropertyType(propertyData), entity.properties, key, propertyData, undefined, sourceUri, entityCollection); } } } - }, + } + } - /** - * Gets or sets the user-defined object returned when the label is picked. - * @memberof Label.prototype - * @type {Object} - */ - id : { - get : function() { - return this._id; - }, - set : function(value) { - if (this._id !== value) { - this._id = value; + function processArrayPacketData(object, propertyName, packetData, entityCollection) { + var references = packetData.references; + if (defined(references)) { + var properties = references.map(function(reference) { + return createReferenceProperty(entityCollection, reference); + }); - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.id = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.id = value; - } + var iso8601Interval = packetData.interval; + if (defined(iso8601Interval)) { + iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); + if (!(object[propertyName] instanceof CompositePositionProperty)) { + iso8601Interval.data = new PropertyArray(properties); + var property = new CompositeProperty(); + property.intervals.addInterval(iso8601Interval); + object[propertyName] = property; } + } else { + object[propertyName] = new PropertyArray(properties); } - }, + } else { + processPacketData(Array, object, propertyName, packetData, undefined, undefined, entityCollection); + } + } - /** - * Keeps track of the position of the label based on the height reference. - * @memberof Label.prototype - * @type {Cartesian3} - * @private - */ - _clampedPosition : { - get : function() { - return this._actualClampedPosition; - }, - set : function(value) { - this._actualClampedPosition = Cartesian3.clone(value, this._actualClampedPosition); + function processArray(object, propertyName, packetData, entityCollection) { + if (!defined(packetData)) { + return; + } - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - // Set all the private values here, because we already clamped to ground - // so we don't want to do it again for every glyph - glyph.billboard._clampedPosition = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard._clampedPosition = value; + if (isArray(packetData)) { + for (var i = 0, length = packetData.length; i < length; ++i) { + processArrayPacketData(object, propertyName, packetData[i], entityCollection); + } + } else { + processArrayPacketData(object, propertyName, packetData, entityCollection); + } + } + + function processPositionsPacketData(object, propertyName, positionsData, entityCollection) { + if (defined(positionsData.references)) { + var properties = positionsData.references.map(function(reference) { + return createReferenceProperty(entityCollection, reference); + }); + + var iso8601Interval = positionsData.interval; + if (defined(iso8601Interval)) { + iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); + if (!(object[propertyName] instanceof CompositePositionProperty)) { + iso8601Interval.data = new PositionPropertyArray(properties); + var property = new CompositePositionProperty(); + property.intervals.addInterval(iso8601Interval); + object[propertyName] = property; } + } else { + object[propertyName] = new PositionPropertyArray(properties); + } + } else { + if (defined(positionsData.cartesian)) { + positionsData.array = Cartesian3.unpackArray(positionsData.cartesian); + } else if (defined(positionsData.cartographicRadians)) { + positionsData.array = Cartesian3.fromRadiansArrayHeights(positionsData.cartographicRadians); + } else if (defined(positionsData.cartographicDegrees)) { + positionsData.array = Cartesian3.fromDegreesArrayHeights(positionsData.cartographicDegrees); } - }, - /** - * Determines whether or not this label will be shown or hidden because it was clustered. - * @memberof Label.prototype - * @type {Boolean} - * @default true - * @private - */ - clusterShow : { - get : function() { - return this._clusterShow; - }, - set : function(value) { - if (this._clusterShow !== value) { - this._clusterShow = value; + if (defined(positionsData.array)) { + processPacketData(Array, object, propertyName, positionsData, undefined, undefined, entityCollection); + } + } + } - var glyphs = this._glyphs; - for (var i = 0, len = glyphs.length; i < len; i++) { - var glyph = glyphs[i]; - if (defined(glyph.billboard)) { - glyph.billboard.clusterShow = value; - } - } - var backgroundBillboard = this._backgroundBillboard; - if (defined(backgroundBillboard)) { - backgroundBillboard.clusterShow = value; - } + function processPositions(object, propertyName, positionsData, entityCollection) { + if (!defined(positionsData)) { + return; + } + + if (isArray(positionsData)) { + for (var i = 0, length = positionsData.length; i < length; i++) { + processPositionsPacketData(object, propertyName, positionsData[i], entityCollection); + } + } else { + processPositionsPacketData(object, propertyName, positionsData, entityCollection); + } + } + + function processAvailability(entity, packet, entityCollection, sourceUri) { + var interval; + var packetData = packet.availability; + if (!defined(packetData)) { + return; + } + + var intervals; + if (isArray(packetData)) { + var length = packetData.length; + for (var i = 0; i < length; i++) { + if (!defined(intervals)) { + intervals = new TimeIntervalCollection(); } + iso8601Scratch.iso8601 = packetData[i]; + interval = TimeInterval.fromIso8601(iso8601Scratch); + intervals.addInterval(interval); } + } else { + iso8601Scratch.iso8601 = packetData; + interval = TimeInterval.fromIso8601(iso8601Scratch); + intervals = new TimeIntervalCollection(); + intervals.addInterval(interval); } - }); + entity.availability = intervals; + } - Label.prototype._updateClamping = function() { - Billboard._updateClamping(this._labelCollection, this); - }; + function processAlignedAxis(billboard, packetData, interval, sourceUri, entityCollection) { + if (!defined(packetData)) { + return; + } - /** - * Computes the screen-space position of the label's origin, taking into account eye and pixel offsets. - * The screen space origin is the top, left corner of the canvas; <code>x</code> increases from - * left to right, and <code>y</code> increases from top to bottom. - * - * @param {Scene} scene The scene the label is in. - * @param {Cartesian2} [result] The object onto which to store the result. - * @returns {Cartesian2} The screen-space position of the label. - * - * - * @example - * console.log(l.computeScreenSpacePosition(scene).toString()); - * - * @see Label#eyeOffset - * @see Label#pixelOffset - */ - Label.prototype.computeScreenSpacePosition = function(scene, result) { - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); + processPacketData(UnitCartesian3, billboard, 'alignedAxis', packetData, interval, sourceUri, entityCollection); + } + + function processBillboard(entity, packet, entityCollection, sourceUri) { + var billboardData = packet.billboard; + if (!defined(billboardData)) { + return; } - - if (!defined(result)) { - result = new Cartesian2(); + + var interval; + var intervalString = billboardData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); } - var labelCollection = this._labelCollection; - var modelMatrix = labelCollection.modelMatrix; - var actualPosition = defined(this._actualClampedPosition) ? this._actualClampedPosition : this._position; + var billboard = entity.billboard; + if (!defined(billboard)) { + entity.billboard = billboard = new BillboardGraphics(); + } - var windowCoordinates = Billboard._computeScreenSpacePosition(modelMatrix, actualPosition, - this._eyeOffset, this._pixelOffset, scene, result); - return windowCoordinates; - }; + processPacketData(Boolean, billboard, 'show', billboardData.show, interval, sourceUri, entityCollection); + processPacketData(Image, billboard, 'image', billboardData.image, interval, sourceUri, entityCollection); + processPacketData(Number, billboard, 'scale', billboardData.scale, interval, sourceUri, entityCollection); + processPacketData(Cartesian2, billboard, 'pixelOffset', billboardData.pixelOffset, interval, sourceUri, entityCollection); + processPacketData(Cartesian3, billboard, 'eyeOffset', billboardData.eyeOffset, interval, sourceUri, entityCollection); + processPacketData(HorizontalOrigin, billboard, 'horizontalOrigin', billboardData.horizontalOrigin, interval, sourceUri, entityCollection); + processPacketData(VerticalOrigin, billboard, 'verticalOrigin', billboardData.verticalOrigin, interval, sourceUri, entityCollection); + processPacketData(HeightReference, billboard, 'heightReference', billboardData.heightReference, interval, sourceUri, entityCollection); + processPacketData(Color, billboard, 'color', billboardData.color, interval, sourceUri, entityCollection); + processPacketData(Rotation, billboard, 'rotation', billboardData.rotation, interval, sourceUri, entityCollection); + processAlignedAxis(billboard, billboardData.alignedAxis, interval, sourceUri, entityCollection); + processPacketData(Boolean, billboard, 'sizeInMeters', billboardData.sizeInMeters, interval, sourceUri, entityCollection); + processPacketData(Number, billboard, 'width', billboardData.width, interval, sourceUri, entityCollection); + processPacketData(Number, billboard, 'height', billboardData.height, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, billboard, 'scaleByDistance', billboardData.scaleByDistance, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, billboard, 'translucencyByDistance', billboardData.translucencyByDistance, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, billboard, 'pixelOffsetScaleByDistance', billboardData.pixelOffsetScaleByDistance, interval, sourceUri, entityCollection); + processPacketData(BoundingRectangle, billboard, 'imageSubRegion', billboardData.imageSubRegion, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, billboard, 'distanceDisplayCondition', billboardData.distanceDisplayCondition, interval, sourceUri, entityCollection); + processPacketData(Number, billboard, 'disableDepthTestDistance', billboardData.disableDepthTestDistance, interval, sourceUri, entityCollection); + } + + function processBox(entity, packet, entityCollection, sourceUri) { + var boxData = packet.box; + if (!defined(boxData)) { + return; + } - /** - * Gets a label's screen space bounding box centered around screenSpacePosition. - * @param {Label} label The label to get the screen space bounding box for. - * @param {Cartesian2} screenSpacePosition The screen space center of the label. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The screen space bounding box. - * - * @private - */ - Label.getScreenSpaceBoundingBox = function(label, screenSpacePosition, result) { - var x = 0; - var y = 0; - var width = 0; - var height = 0; - var scale = label.scale; - var resolutionScale = label._labelCollection._resolutionScale; + var interval; + var intervalString = boxData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - var backgroundBillboard = label._backgroundBillboard; - if (defined(backgroundBillboard)) { - x = screenSpacePosition.x + (backgroundBillboard._translate.x / resolutionScale); - y = screenSpacePosition.y - (backgroundBillboard._translate.y / resolutionScale); - width = backgroundBillboard.width * scale; - height = backgroundBillboard.height * scale; + var box = entity.box; + if (!defined(box)) { + entity.box = box = new BoxGraphics(); + } - if (label.verticalOrigin === VerticalOrigin.BOTTOM || label.verticalOrigin === VerticalOrigin.BASELINE) { - y -= height; - } else if (label.verticalOrigin === VerticalOrigin.CENTER) { - y -= height * 0.5; - } - } else { - x = Number.POSITIVE_INFINITY; - y = Number.POSITIVE_INFINITY; - var maxX = 0; - var maxY = 0; - var glyphs = label._glyphs; - var length = glyphs.length; - for (var i = 0; i < length; ++i) { - var glyph = glyphs[i]; - var billboard = glyph.billboard; - if (!defined(billboard)) { - continue; + processPacketData(Boolean, box, 'show', boxData.show, interval, sourceUri, entityCollection); + processPacketData(Cartesian3, box, 'dimensions', boxData.dimensions, interval, sourceUri, entityCollection); + processPacketData(Boolean, box, 'fill', boxData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(box, 'material', boxData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, box, 'outline', boxData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, box, 'outlineColor', boxData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, box, 'outlineWidth', boxData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, box, 'shadows', boxData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, box, 'distanceDisplayCondition', boxData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } + + function processCorridor(entity, packet, entityCollection, sourceUri) { + var corridorData = packet.corridor; + if (!defined(corridorData)) { + return; + } + + var interval; + var intervalString = corridorData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } + + var corridor = entity.corridor; + if (!defined(corridor)) { + entity.corridor = corridor = new CorridorGraphics(); + } + + processPacketData(Boolean, corridor, 'show', corridorData.show, interval, sourceUri, entityCollection); + processPositions(corridor, 'positions', corridorData.positions, entityCollection); + processPacketData(Number, corridor, 'width', corridorData.width, interval, sourceUri, entityCollection); + processPacketData(Number, corridor, 'height', corridorData.height, interval, sourceUri, entityCollection); + processPacketData(Number, corridor, 'extrudedHeight', corridorData.extrudedHeight, interval, sourceUri, entityCollection); + processPacketData(CornerType, corridor, 'cornerType', corridorData.cornerType, interval, sourceUri, entityCollection); + processPacketData(Number, corridor, 'granularity', corridorData.granularity, interval, sourceUri, entityCollection); + processPacketData(Boolean, corridor, 'fill', corridorData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(corridor, 'material', corridorData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, corridor, 'outline', corridorData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, corridor, 'outlineColor', corridorData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, corridor, 'outlineWidth', corridorData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, corridor, 'shadows', corridorData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, corridor, 'distanceDisplayCondition', corridorData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } + + function processCylinder(entity, packet, entityCollection, sourceUri) { + var cylinderData = packet.cylinder; + if (!defined(cylinderData)) { + return; + } + + var interval; + var intervalString = cylinderData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } + + var cylinder = entity.cylinder; + if (!defined(cylinder)) { + entity.cylinder = cylinder = new CylinderGraphics(); + } + + processPacketData(Boolean, cylinder, 'show', cylinderData.show, interval, sourceUri, entityCollection); + processPacketData(Number, cylinder, 'length', cylinderData.length, interval, sourceUri, entityCollection); + processPacketData(Number, cylinder, 'topRadius', cylinderData.topRadius, interval, sourceUri, entityCollection); + processPacketData(Number, cylinder, 'bottomRadius', cylinderData.bottomRadius, interval, sourceUri, entityCollection); + processPacketData(Boolean, cylinder, 'fill', cylinderData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(cylinder, 'material', cylinderData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, cylinder, 'outline', cylinderData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, cylinder, 'outlineColor', cylinderData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, cylinder, 'outlineWidth', cylinderData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(Number, cylinder, 'numberOfVerticalLines', cylinderData.numberOfVerticalLines, interval, sourceUri, entityCollection); + processPacketData(Number, cylinder, 'slices', cylinderData.slices, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, cylinder, 'shadows', cylinderData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, cylinder, 'distanceDisplayCondition', cylinderData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } + + function processDocument(packet, dataSource) { + var version = packet.version; + if (defined(version)) { + if (typeof version === 'string') { + var tokens = version.split('.'); + if (tokens.length === 2) { + if (tokens[0] !== '1') { + throw new RuntimeError('Cesium only supports CZML version 1.'); + } + dataSource._version = version; } + } + } - var glyphX = screenSpacePosition.x + (billboard._translate.x / resolutionScale); - var glyphY = screenSpacePosition.y - (billboard._translate.y / resolutionScale); - var glyphWidth = billboard.width * scale; - var glyphHeight = billboard.height * scale; + if (!defined(dataSource._version)) { + throw new RuntimeError('CZML version information invalid. It is expected to be a property on the document object in the <Major>.<Minor> version format.'); + } + + var documentPacket = dataSource._documentPacket; + + if (defined(packet.name)) { + documentPacket.name = packet.name; + } + + var clockPacket = packet.clock; + if (defined(clockPacket)) { + var clock = documentPacket.clock; + if (!defined(clock)) { + documentPacket.clock = { + interval : clockPacket.interval, + currentTime : clockPacket.currentTime, + range : clockPacket.range, + step : clockPacket.step, + multiplier : clockPacket.multiplier + }; + } else { + clock.interval = defaultValue(clockPacket.interval, clock.interval); + clock.currentTime = defaultValue(clockPacket.currentTime, clock.currentTime); + clock.range = defaultValue(clockPacket.range, clock.range); + clock.step = defaultValue(clockPacket.step, clock.step); + clock.multiplier = defaultValue(clockPacket.multiplier, clock.multiplier); + } + } + } + + function processEllipse(entity, packet, entityCollection, sourceUri) { + var ellipseData = packet.ellipse; + if (!defined(ellipseData)) { + return; + } - if (label.verticalOrigin === VerticalOrigin.BOTTOM || label.verticalOrigin === VerticalOrigin.BASELINE) { - glyphY -= glyphHeight; - } else if (label.verticalOrigin === VerticalOrigin.CENTER) { - glyphY -= glyphHeight * 0.5; - } + var interval; + var intervalString = ellipseData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - x = Math.min(x, glyphX); - y = Math.min(y, glyphY); - maxX = Math.max(maxX, glyphX + glyphWidth); - maxY = Math.max(maxY, glyphY + glyphHeight); - } + var ellipse = entity.ellipse; + if (!defined(ellipse)) { + entity.ellipse = ellipse = new EllipseGraphics(); + } - width = maxX - x; - height = maxY - y; + processPacketData(Boolean, ellipse, 'show', ellipseData.show, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'semiMajorAxis', ellipseData.semiMajorAxis, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'semiMinorAxis', ellipseData.semiMinorAxis, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'height', ellipseData.height, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'extrudedHeight', ellipseData.extrudedHeight, interval, sourceUri, entityCollection); + processPacketData(Rotation, ellipse, 'rotation', ellipseData.rotation, interval, sourceUri, entityCollection); + processPacketData(Rotation, ellipse, 'stRotation', ellipseData.stRotation, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'granularity', ellipseData.granularity, interval, sourceUri, entityCollection); + processPacketData(Boolean, ellipse, 'fill', ellipseData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(ellipse, 'material', ellipseData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, ellipse, 'outline', ellipseData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, ellipse, 'outlineColor', ellipseData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'outlineWidth', ellipseData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(Number, ellipse, 'numberOfVerticalLines', ellipseData.numberOfVerticalLines, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, ellipse, 'shadows', ellipseData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, ellipse, 'distanceDisplayCondition', ellipseData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } + + function processEllipsoid(entity, packet, entityCollection, sourceUri) { + var ellipsoidData = packet.ellipsoid; + if (!defined(ellipsoidData)) { + return; } - if (!defined(result)) { - result = new BoundingRectangle(); + var interval; + var intervalString = ellipsoidData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); } - result.x = x; - result.y = y; - result.width = width; - result.height = height; + var ellipsoid = entity.ellipsoid; + if (!defined(ellipsoid)) { + entity.ellipsoid = ellipsoid = new EllipsoidGraphics(); + } - return result; - }; + processPacketData(Boolean, ellipsoid, 'show', ellipsoidData.show, interval, sourceUri, entityCollection); + processPacketData(Cartesian3, ellipsoid, 'radii', ellipsoidData.radii, interval, sourceUri, entityCollection); + processPacketData(Boolean, ellipsoid, 'fill', ellipsoidData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(ellipsoid, 'material', ellipsoidData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, ellipsoid, 'outline', ellipsoidData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, ellipsoid, 'outlineColor', ellipsoidData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, ellipsoid, 'outlineWidth', ellipsoidData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(Number, ellipsoid, 'stackPartitions', ellipsoidData.stackPartitions, interval, sourceUri, entityCollection); + processPacketData(Number, ellipsoid, 'slicePartitions', ellipsoidData.slicePartitions, interval, sourceUri, entityCollection); + processPacketData(Number, ellipsoid, 'subdivisions', ellipsoidData.subdivisions, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, ellipsoid, 'shadows', ellipsoidData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, ellipsoid, 'distanceDisplayCondition', ellipsoidData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } - /** - * Determines if this label equals another label. Labels are equal if all their properties - * are equal. Labels in different collections can be equal. - * - * @param {Label} other The label to compare for equality. - * @returns {Boolean} <code>true</code> if the labels are equal; otherwise, <code>false</code>. - */ - Label.prototype.equals = function(other) { - return this === other || - defined(other) && - this._show === other._show && - this._scale === other._scale && - this._outlineWidth === other._outlineWidth && - this._showBackground === other._showBackground && - this._style === other._style && - this._verticalOrigin === other._verticalOrigin && - this._horizontalOrigin === other._horizontalOrigin && - this._heightReference === other._heightReference && - this._renderedText === other._renderedText && - this._font === other._font && - Cartesian3.equals(this._position, other._position) && - Color.equals(this._fillColor, other._fillColor) && - Color.equals(this._outlineColor, other._outlineColor) && - Color.equals(this._backgroundColor, other._backgroundColor) && - Cartesian2.equals(this._backgroundPadding, other._backgroundPadding) && - Cartesian2.equals(this._pixelOffset, other._pixelOffset) && - Cartesian3.equals(this._eyeOffset, other._eyeOffset) && - NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && - NearFarScalar.equals(this._pixelOffsetScaleByDistance, other._pixelOffsetScaleByDistance) && - NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && - DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && - this._disableDepthTestDistance === other._disableDepthTestDistance && - this._id === other._id; - }; + function processLabel(entity, packet, entityCollection, sourceUri) { + var labelData = packet.label; + if (!defined(labelData)) { + return; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - Label.prototype.isDestroyed = function() { - return false; - }; + var interval; + var intervalString = labelData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - /** - * Determines whether or not run the algorithm, that match the text of the label to right-to-left languages - * @memberof Label - * @type {Boolean} - * @default false - * - * @example - * // Example 1. - * // Set a label's rightToLeft before init - * Cesium.Label.enableRightToLeftDetection = true; - * var myLabelEntity = viewer.entities.add({ - * label: { - * id: 'my label', - * text: 'זה טקסט בעברית \n ועכשיו יורדים שורה', - * } - * }); - * - * @example - * // Example 2. - * var myLabelEntity = viewer.entities.add({ - * label: { - * id: 'my label', - * text: 'English text' - * } - * }); - * // Set a label's rightToLeft after init - * Cesium.Label.enableRightToLeftDetection = true; - * myLabelEntity.text = 'טקסט חדש'; - */ - Label.enableRightToLeftDetection = false; + var label = entity.label; + if (!defined(label)) { + entity.label = label = new LabelGraphics(); + } - function convertTextToTypes(text, rtlChars) { - var ltrChars = /[a-zA-Z0-9]/; - var bracketsChars = /[()[\]{}<>]/; - var parsedText = []; - var word = ''; - var lastType = textTypes.LTR; - var currentType = ''; - var textLength = text.length; - for (var textIndex = 0; textIndex < textLength; ++textIndex) { - var character = text.charAt(textIndex); - if (rtlChars.test(character)) { - currentType = textTypes.RTL; - } - else if (ltrChars.test(character)) { - currentType = textTypes.LTR; - } - else if (bracketsChars.test(character)) { - currentType = textTypes.BRACKETS; - } - else { - currentType = textTypes.WEAK; - } + processPacketData(Boolean, label, 'show', labelData.show, interval, sourceUri, entityCollection); + processPacketData(String, label, 'text', labelData.text, interval, sourceUri, entityCollection); + processPacketData(String, label, 'font', labelData.font, interval, sourceUri, entityCollection); + processPacketData(LabelStyle, label, 'style', labelData.style, interval, sourceUri, entityCollection); + processPacketData(Number, label, 'scale', labelData.scale, interval, sourceUri, entityCollection); + processPacketData(Boolean, label, 'showBackground', labelData.showBackground, interval, sourceUri, entityCollection); + processPacketData(Color, label, 'backgroundColor', labelData.backgroundColor, interval, sourceUri, entityCollection); + processPacketData(Cartesian2, label, 'backgroundPadding', labelData.backgroundPadding, interval, sourceUri, entityCollection); + processPacketData(Cartesian2, label, 'pixelOffset', labelData.pixelOffset, interval, sourceUri, entityCollection); + processPacketData(Cartesian3, label, 'eyeOffset', labelData.eyeOffset, interval, sourceUri, entityCollection); + processPacketData(HorizontalOrigin, label, 'horizontalOrigin', labelData.horizontalOrigin, interval, sourceUri, entityCollection); + processPacketData(VerticalOrigin, label, 'verticalOrigin', labelData.verticalOrigin, interval, sourceUri, entityCollection); + processPacketData(HeightReference, label, 'heightReference', labelData.heightReference, interval, sourceUri, entityCollection); + processPacketData(Color, label, 'fillColor', labelData.fillColor, interval, sourceUri, entityCollection); + processPacketData(Color, label, 'outlineColor', labelData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, label, 'outlineWidth', labelData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, label, 'translucencyByDistance', labelData.translucencyByDistance, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, label, 'pixelOffsetScaleByDistance', labelData.pixelOffsetScaleByDistance, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, label, 'scaleByDistance', labelData.scaleByDistance, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, label, 'distanceDisplayCondition', labelData.distanceDisplayCondition, interval, sourceUri, entityCollection); + processPacketData(Number, label, 'disableDepthTestDistance', labelData.disableDepthTestDistance, interval, sourceUri, entityCollection); + } + + function processModel(entity, packet, entityCollection, sourceUri) { + var modelData = packet.model; + if (!defined(modelData)) { + return; + } - if (textIndex === 0) { - lastType = currentType; - } + var interval; + var intervalString = modelData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - if (lastType === currentType && currentType !== textTypes.BRACKETS) { - word += character; - } - else { - if (word !== '') { - parsedText.push({Type : lastType, Word : word}); + var model = entity.model; + if (!defined(model)) { + entity.model = model = new ModelGraphics(); + } + + processPacketData(Boolean, model, 'show', modelData.show, interval, sourceUri, entityCollection); + processPacketData(Uri, model, 'uri', modelData.gltf, interval, sourceUri, entityCollection); + processPacketData(Number, model, 'scale', modelData.scale, interval, sourceUri, entityCollection); + processPacketData(Number, model, 'minimumPixelSize', modelData.minimumPixelSize, interval, sourceUri, entityCollection); + processPacketData(Number, model, 'maximumScale', modelData.maximumScale, interval, sourceUri, entityCollection); + processPacketData(Boolean, model, 'incrementallyLoadTextures', modelData.incrementallyLoadTextures, interval, sourceUri, entityCollection); + processPacketData(Boolean, model, 'runAnimations', modelData.runAnimations, interval, sourceUri, entityCollection); + processPacketData(Boolean, model, 'clampAnimations', modelData.clampAnimations, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, model, 'shadows', modelData.shadows, interval, sourceUri, entityCollection); + processPacketData(HeightReference, model, 'heightReference', modelData.heightReference, interval, sourceUri, entityCollection); + processPacketData(Color, model, 'silhouetteColor', modelData.silhouetteColor, interval, sourceUri, entityCollection); + processPacketData(Number, model, 'silhouetteSize', modelData.silhouetteSize, interval, sourceUri, entityCollection); + processPacketData(Color, model, 'color', modelData.color, interval, sourceUri, entityCollection); + processPacketData(ColorBlendMode, model, 'colorBlendMode', modelData.colorBlendMode, interval, sourceUri, entityCollection); + processPacketData(Number, model, 'colorBlendAmount', modelData.colorBlendAmount, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, model, 'distanceDisplayCondition', modelData.distanceDisplayCondition, interval, sourceUri, entityCollection); + + var nodeTransformationsData = modelData.nodeTransformations; + if (defined(nodeTransformationsData)) { + if (isArray(nodeTransformationsData)) { + for (var i = 0, len = nodeTransformationsData.length; i < len; i++) { + processNodeTransformations(model, nodeTransformationsData[i], interval, sourceUri, entityCollection); } - lastType = currentType; - word = character; + } else { + processNodeTransformations(model, nodeTransformationsData, interval, sourceUri, entityCollection); } } - parsedText.push({Type : currentType, Word : word}); - return parsedText; } - function reverseWord(word) { - return word.split('').reverse().join(''); - } + function processNodeTransformations(model, nodeTransformationsData, constrainedInterval, sourceUri, entityCollection) { + var combinedInterval; + var packetInterval = nodeTransformationsData.interval; + if (defined(packetInterval)) { + iso8601Scratch.iso8601 = packetInterval; + combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); + if (defined(constrainedInterval)) { + combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); + } + } else if (defined(constrainedInterval)) { + combinedInterval = constrainedInterval; + } - function spliceWord(result, pointer, word) { - return result.slice(0, pointer) + word + result.slice(pointer); - } + var nodeTransformations = model.nodeTransformations; + var nodeNames = Object.keys(nodeTransformationsData); + for (var i = 0, len = nodeNames.length; i < len; ++i) { + var nodeName = nodeNames[i]; - function reverseBrackets(bracket) { - switch(bracket) { - case '(': - return ')'; - case ')': - return '('; - case '[': - return ']'; - case ']': - return '['; - case '{': - return '}'; - case '}': - return '{'; - case '<': - return '>'; - case '>': - return '<'; - } - } + if (nodeName === 'interval') { + continue; + } - //To add another language, simply add its Unicode block range(s) to the below regex. - var hebrew = '\u05D0-\u05EA'; - var arabic = '\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF'; - var rtlChars = new RegExp('[' + hebrew + arabic + ']'); + var nodeTransformationData = nodeTransformationsData[nodeName]; - /** - * - * @param {String} value the text to parse and reorder - * @returns {String} the text as rightToLeft direction - * @private - */ - function reverseRtl(value) { - var texts = value.split('\n'); - var result = ''; - for (var i = 0; i < texts.length; i++) { - var text = texts[i]; - var rtlDir = rtlChars.test(text.charAt(0)); - var parsedText = convertTextToTypes(text, rtlChars); + if (!defined(nodeTransformationData)) { + continue; + } - var splicePointer = 0; - var line = ''; - for (var wordIndex = 0; wordIndex < parsedText.length; ++wordIndex) { - var subText = parsedText[wordIndex]; - var reverse = subText.Type === textTypes.BRACKETS ? reverseBrackets(subText.Word) : subText.Word; - if (rtlDir) { - if (subText.Type === textTypes.RTL) { - line = reverseWord(subText.Word) + line; - splicePointer = 0; - } - else if (subText.Type === textTypes.LTR) { - line = spliceWord(line, splicePointer, subText.Word); - splicePointer += subText.Word.length; - } - else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { - if (subText.Type === textTypes.WEAK && parsedText[wordIndex - 1].Type === textTypes.BRACKETS) { - line = reverseWord(subText.Word) + line; - } - else if (parsedText[wordIndex - 1].Type === textTypes.RTL) { - line = reverse + line; - splicePointer = 0; - } - else if (parsedText.length > wordIndex + 1) { - if (parsedText[wordIndex + 1].Type === textTypes.RTL) { - line = reverse + line; - splicePointer = 0; - } - else { - line = spliceWord(line, splicePointer, subText.Word); - splicePointer += subText.Word.length; - } - } - else { - line = spliceWord(line, 0, reverse); - } - } - } - else if (subText.Type === textTypes.RTL) { - line = spliceWord(line, splicePointer, reverseWord(subText.Word)); - } - else if (subText.Type === textTypes.LTR) { - line += subText.Word; - splicePointer = line.length; - } - else if (subText.Type === textTypes.WEAK || subText.Type === textTypes.BRACKETS) { - if (wordIndex > 0) { - if (parsedText[wordIndex - 1].Type === textTypes.RTL) { - if (parsedText.length > wordIndex + 1) { - if (parsedText[wordIndex + 1].Type === textTypes.RTL) { - line = spliceWord(line, splicePointer, reverse); - } - else { - line += subText.Word; - splicePointer = line.length; - } - } - else { - line += subText.Word; - } - } - else { - line += subText.Word; - splicePointer = line.length; - } - } - else { - line += subText.Word; - splicePointer = line.length; - } - } + if (!defined(nodeTransformations)) { + model.nodeTransformations = nodeTransformations = new PropertyBag(); } - result += line; - if (i < texts.length - 1) { - result += '\n'; + if (!nodeTransformations.hasProperty(nodeName)) { + nodeTransformations.addProperty(nodeName); + } + + var nodeTransformation = nodeTransformations[nodeName]; + if (!defined(nodeTransformation)) { + nodeTransformations[nodeName] = nodeTransformation = new NodeTransformationProperty(); } + + processPacketData(Cartesian3, nodeTransformation, 'translation', nodeTransformationData.translation, combinedInterval, sourceUri, entityCollection); + processPacketData(Quaternion, nodeTransformation, 'rotation', nodeTransformationData.rotation, combinedInterval, sourceUri, entityCollection); + processPacketData(Cartesian3, nodeTransformation, 'scale', nodeTransformationData.scale, combinedInterval, sourceUri, entityCollection); } - return result; } - return Label; -}); + function processPath(entity, packet, entityCollection, sourceUri) { + var pathData = packet.path; + if (!defined(pathData)) { + return; + } -define('Scene/LabelCollection',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Matrix4', - '../Core/writeTextToCanvas', - './BillboardCollection', - './BlendOption', - './HorizontalOrigin', - './Label', - './LabelStyle', - './TextureAtlas', - './VerticalOrigin' - ], function( - BoundingRectangle, - Cartesian2, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - Matrix4, - writeTextToCanvas, - BillboardCollection, - BlendOption, - HorizontalOrigin, - Label, - LabelStyle, - TextureAtlas, - VerticalOrigin) { - 'use strict'; + var interval; + var intervalString = pathData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - // A glyph represents a single character in a particular label. It may or may - // not have a billboard, depending on whether the texture info has an index into - // the the label collection's texture atlas. Invisible characters have no texture, and - // no billboard. However, it always has a valid dimensions object. - function Glyph() { - this.textureInfo = undefined; - this.dimensions = undefined; - this.billboard = undefined; - } + var path = entity.path; + if (!defined(path)) { + entity.path = path = new PathGraphics(); + } - // GlyphTextureInfo represents a single character, drawn in a particular style, - // shared and reference counted across all labels. It may or may not have an - // index into the label collection's texture atlas, depending on whether the character - // has both width and height, but it always has a valid dimensions object. - function GlyphTextureInfo(labelCollection, index, dimensions) { - this.labelCollection = labelCollection; - this.index = index; - this.dimensions = dimensions; + processPacketData(Boolean, path, 'show', pathData.show, interval, sourceUri, entityCollection); + processPacketData(Number, path, 'width', pathData.width, interval, sourceUri, entityCollection); + processPacketData(Number, path, 'resolution', pathData.resolution, interval, sourceUri, entityCollection); + processPacketData(Number, path, 'leadTime', pathData.leadTime, interval, sourceUri, entityCollection); + processPacketData(Number, path, 'trailTime', pathData.trailTime, interval, sourceUri, entityCollection); + processMaterialPacketData(path, 'material', pathData.material, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, path, 'distanceDisplayCondition', pathData.distanceDisplayCondition, interval, sourceUri, entityCollection); } - // Traditionally, leading is %20 of the font size. - var defaultLineSpacingPercent = 1.2; - - var whitePixelCanvasId = 'ID_WHITE_PIXEL'; - var whitePixelSize = new Cartesian2(4, 4); - var whitePixelBoundingRegion = new BoundingRectangle(1, 1, 1, 1); + function processPoint(entity, packet, entityCollection, sourceUri) { + var pointData = packet.point; + if (!defined(pointData)) { + return; + } - function addWhitePixelCanvas(textureAtlas, labelCollection) { - var canvas = document.createElement('canvas'); - canvas.width = whitePixelSize.x; - canvas.height = whitePixelSize.y; + var interval; + var intervalString = pointData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - var context2D = canvas.getContext('2d'); - context2D.fillStyle = '#fff'; - context2D.fillRect(0, 0, canvas.width, canvas.height); + var point = entity.point; + if (!defined(point)) { + entity.point = point = new PointGraphics(); + } - textureAtlas.addImage(whitePixelCanvasId, canvas).then(function(index) { - labelCollection._whitePixelIndex = index; - }); + processPacketData(Boolean, point, 'show', pointData.show, interval, sourceUri, entityCollection); + processPacketData(Number, point, 'pixelSize', pointData.pixelSize, interval, sourceUri, entityCollection); + processPacketData(HeightReference, point, 'heightReference', pointData.heightReference, interval, sourceUri, entityCollection); + processPacketData(Color, point, 'color', pointData.color, interval, sourceUri, entityCollection); + processPacketData(Color, point, 'outlineColor', pointData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, point, 'outlineWidth', pointData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, point, 'scaleByDistance', pointData.scaleByDistance, interval, sourceUri, entityCollection); + processPacketData(NearFarScalar, point, 'translucencyByDistance', pointData.translucencyByDistance, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, point, 'distanceDisplayCondition', pointData.distanceDisplayCondition, interval, sourceUri, entityCollection); + processPacketData(Number, point, 'disableDepthTestDistance', pointData.disableDepthTestDistance, interval, sourceUri, entityCollection); } - // reusable object for calling writeTextToCanvas - var writeTextToCanvasParameters = {}; - function createGlyphCanvas(character, font, fillColor, outlineColor, outlineWidth, style, verticalOrigin) { - writeTextToCanvasParameters.font = font; - writeTextToCanvasParameters.fillColor = fillColor; - writeTextToCanvasParameters.strokeColor = outlineColor; - writeTextToCanvasParameters.strokeWidth = outlineWidth; + function processPolygon(entity, packet, entityCollection, sourceUri) { + var polygonData = packet.polygon; + if (!defined(polygonData)) { + return; + } - if (verticalOrigin === VerticalOrigin.CENTER) { - writeTextToCanvasParameters.textBaseline = 'middle'; - } else if (verticalOrigin === VerticalOrigin.TOP) { - writeTextToCanvasParameters.textBaseline = 'top'; - } else { - // VerticalOrigin.BOTTOM and VerticalOrigin.BASELINE - writeTextToCanvasParameters.textBaseline = 'bottom'; + var interval; + var intervalString = polygonData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); } - writeTextToCanvasParameters.fill = style === LabelStyle.FILL || style === LabelStyle.FILL_AND_OUTLINE; - writeTextToCanvasParameters.stroke = style === LabelStyle.OUTLINE || style === LabelStyle.FILL_AND_OUTLINE; + var polygon = entity.polygon; + if (!defined(polygon)) { + entity.polygon = polygon = new PolygonGraphics(); + } - return writeTextToCanvas(character, writeTextToCanvasParameters); - } + processPacketData(Boolean, polygon, 'show', polygonData.show, interval, sourceUri, entityCollection); + processPositions(polygon, 'hierarchy', polygonData.positions, entityCollection); + processPacketData(Number, polygon, 'height', polygonData.height, interval, sourceUri, entityCollection); + processPacketData(Number, polygon, 'extrudedHeight', polygonData.extrudedHeight, interval, sourceUri, entityCollection); + processPacketData(Rotation, polygon, 'stRotation', polygonData.stRotation, interval, sourceUri, entityCollection); + processPacketData(Number, polygon, 'granularity', polygonData.granularity, interval, sourceUri, entityCollection); + processPacketData(Boolean, polygon, 'fill', polygonData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(polygon, 'material', polygonData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, polygon, 'outline', polygonData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, polygon, 'outlineColor', polygonData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, polygon, 'outlineWidth', polygonData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(Boolean, polygon, 'perPositionHeight', polygonData.perPositionHeight, interval, sourceUri, entityCollection); + processPacketData(Boolean, polygon, 'closeTop', polygonData.closeTop, interval, sourceUri, entityCollection); + processPacketData(Boolean, polygon, 'closeBottom', polygonData.closeBottom, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, polygon, 'shadows', polygonData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, polygon, 'distanceDisplayCondition', polygonData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } + + function processPolyline(entity, packet, entityCollection, sourceUri) { + var polylineData = packet.polyline; + if (!defined(polylineData)) { + return; + } - function unbindGlyph(labelCollection, glyph) { - glyph.textureInfo = undefined; - glyph.dimensions = undefined; + var interval; + var intervalString = polylineData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - var billboard = glyph.billboard; - if (defined(billboard)) { - billboard.show = false; - billboard.image = undefined; - if (defined(billboard._removeCallbackFunc)) { - billboard._removeCallbackFunc(); - billboard._removeCallbackFunc = undefined; - } - labelCollection._spareBillboards.push(billboard); - glyph.billboard = undefined; + var polyline = entity.polyline; + if (!defined(polyline)) { + entity.polyline = polyline = new PolylineGraphics(); } - } - function addGlyphToTextureAtlas(textureAtlas, id, canvas, glyphTextureInfo) { - textureAtlas.addImage(id, canvas).then(function(index) { - glyphTextureInfo.index = index; - }); + processPacketData(Boolean, polyline, 'show', polylineData.show, interval, sourceUri, entityCollection); + processPositions(polyline, 'positions', polylineData.positions, entityCollection); + processPacketData(Number, polyline, 'width', polylineData.width, interval, sourceUri, entityCollection); + processPacketData(Number, polyline, 'granularity', polylineData.granularity, interval, sourceUri, entityCollection); + processMaterialPacketData(polyline, 'material', polylineData.material, interval, sourceUri, entityCollection); + processMaterialPacketData(polyline, 'depthFailMaterial', polylineData.depthFailMaterial, interval, sourceUri, entityCollection); + processPacketData(Boolean, polyline, 'followSurface', polylineData.followSurface, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, polyline, 'shadows', polylineData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, polyline, 'distanceDisplayCondition', polylineData.distanceDisplayCondition, interval, sourceUri, entityCollection); } - function rebindAllGlyphs(labelCollection, label) { - var text = label._renderedText; - var textLength = text.length; - var glyphs = label._glyphs; - var glyphsLength = glyphs.length; + function processRectangle(entity, packet, entityCollection, sourceUri) { + var rectangleData = packet.rectangle; + if (!defined(rectangleData)) { + return; + } - var glyph; - var glyphIndex; - var textIndex; + var interval; + var intervalString = rectangleData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - // if we have more glyphs than needed, unbind the extras. - if (textLength < glyphsLength) { - for (glyphIndex = textLength; glyphIndex < glyphsLength; ++glyphIndex) { - unbindGlyph(labelCollection, glyphs[glyphIndex]); - } + var rectangle = entity.rectangle; + if (!defined(rectangle)) { + entity.rectangle = rectangle = new RectangleGraphics(); } - // presize glyphs to match the new text length - glyphs.length = textLength; + processPacketData(Boolean, rectangle, 'show', rectangleData.show, interval, sourceUri, entityCollection); + processPacketData(Rectangle, rectangle, 'coordinates', rectangleData.coordinates, interval, sourceUri, entityCollection); + processPacketData(Number, rectangle, 'height', rectangleData.height, interval, sourceUri, entityCollection); + processPacketData(Number, rectangle, 'extrudedHeight', rectangleData.extrudedHeight, interval, sourceUri, entityCollection); + processPacketData(Rotation, rectangle, 'rotation', rectangleData.rotation, interval, sourceUri, entityCollection); + processPacketData(Rotation, rectangle, 'stRotation', rectangleData.stRotation, interval, sourceUri, entityCollection); + processPacketData(Number, rectangle, 'granularity', rectangleData.granularity, interval, sourceUri, entityCollection); + processPacketData(Boolean, rectangle, 'fill', rectangleData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(rectangle, 'material', rectangleData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, rectangle, 'outline', rectangleData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, rectangle, 'outlineColor', rectangleData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, rectangle, 'outlineWidth', rectangleData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(Boolean, rectangle, 'closeTop', rectangleData.closeTop, interval, sourceUri, entityCollection); + processPacketData(Boolean, rectangle, 'closeBottom', rectangleData.closeBottom, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, rectangle, 'shadows', rectangleData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, rectangle, 'distanceDisplayCondition', rectangleData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } + + function processWall(entity, packet, entityCollection, sourceUri) { + var wallData = packet.wall; + if (!defined(wallData)) { + return; + } - var showBackground = label._showBackground && (text.split('\n').join('').length > 0); - var backgroundBillboard = label._backgroundBillboard; - var backgroundBillboardCollection = labelCollection._backgroundBillboardCollection; - if (!showBackground) { - if (defined(backgroundBillboard)) { - backgroundBillboardCollection.remove(backgroundBillboard); - label._backgroundBillboard = backgroundBillboard = undefined; - } - } else { - if (!defined(backgroundBillboard)) { - backgroundBillboard = backgroundBillboardCollection.add({ - collection : labelCollection, - image : whitePixelCanvasId, - imageSubRegion : whitePixelBoundingRegion - }); - label._backgroundBillboard = backgroundBillboard; - } + var interval; + var intervalString = wallData.interval; + if (defined(intervalString)) { + iso8601Scratch.iso8601 = intervalString; + interval = TimeInterval.fromIso8601(iso8601Scratch); + } - backgroundBillboard.color = label._backgroundColor; - backgroundBillboard.show = label._show; - backgroundBillboard.position = label._position; - backgroundBillboard.eyeOffset = label._eyeOffset; - backgroundBillboard.pixelOffset = label._pixelOffset; - backgroundBillboard.horizontalOrigin = HorizontalOrigin.LEFT; - backgroundBillboard.verticalOrigin = label._verticalOrigin; - backgroundBillboard.heightReference = label._heightReference; - backgroundBillboard.scale = label._scale; - backgroundBillboard.pickPrimitive = label; - backgroundBillboard.id = label._id; - backgroundBillboard.translucencyByDistance = label._translucencyByDistance; - backgroundBillboard.pixelOffsetScaleByDistance = label._pixelOffsetScaleByDistance; - backgroundBillboard.scaleByDistance = label._scaleByDistance; - backgroundBillboard.distanceDisplayCondition = label._distanceDisplayCondition; - backgroundBillboard.disableDepthTestDistance = label._disableDepthTestDistance; + var wall = entity.wall; + if (!defined(wall)) { + entity.wall = wall = new WallGraphics(); } - var glyphTextureCache = labelCollection._glyphTextureCache; + processPacketData(Boolean, wall, 'show', wallData.show, interval, sourceUri, entityCollection); + processPositions(wall, 'positions', wallData.positions, entityCollection); + processArray(wall, 'minimumHeights', wallData.minimumHeights, entityCollection); + processArray(wall, 'maximumHeights', wallData.maximumHeights, entityCollection); + processPacketData(Number, wall, 'granularity', wallData.granularity, interval, sourceUri, entityCollection); + processPacketData(Boolean, wall, 'fill', wallData.fill, interval, sourceUri, entityCollection); + processMaterialPacketData(wall, 'material', wallData.material, interval, sourceUri, entityCollection); + processPacketData(Boolean, wall, 'outline', wallData.outline, interval, sourceUri, entityCollection); + processPacketData(Color, wall, 'outlineColor', wallData.outlineColor, interval, sourceUri, entityCollection); + processPacketData(Number, wall, 'outlineWidth', wallData.outlineWidth, interval, sourceUri, entityCollection); + processPacketData(ShadowMode, wall, 'shadows', wallData.shadows, interval, sourceUri, entityCollection); + processPacketData(DistanceDisplayCondition, wall, 'distanceDisplayCondition', wallData.distanceDisplayCondition, interval, sourceUri, entityCollection); + } - // walk the text looking for new characters (creating new glyphs for each) - // or changed characters (rebinding existing glyphs) - for (textIndex = 0; textIndex < textLength; ++textIndex) { - var character = text.charAt(textIndex); - var font = label._font; - var fillColor = label._fillColor; - var outlineColor = label._outlineColor; - var outlineWidth = label._outlineWidth; - var style = label._style; - var verticalOrigin = label._verticalOrigin; + function processCzmlPacket(packet, entityCollection, updaterFunctions, sourceUri, dataSource) { + var objectId = packet.id; + if (!defined(objectId)) { + objectId = createGuid(); + } - // retrieve glyph dimensions and texture index (if the canvas has area) - // from the glyph texture cache, or create and add if not present. - var id = JSON.stringify([ - character, - font, - fillColor.toRgba(), - outlineColor.toRgba(), - outlineWidth, - +style, - +verticalOrigin - ]); + currentId = objectId; - var glyphTextureInfo = glyphTextureCache[id]; - if (!defined(glyphTextureInfo)) { - var canvas = createGlyphCanvas(character, font, fillColor, outlineColor, outlineWidth, style, verticalOrigin); + if (!defined(dataSource._version) && objectId !== 'document') { + throw new RuntimeError('The first CZML packet is required to be the document object.'); + } - glyphTextureInfo = new GlyphTextureInfo(labelCollection, -1, canvas.dimensions); - glyphTextureCache[id] = glyphTextureInfo; + if (packet['delete'] === true) { + entityCollection.removeById(objectId); + } else if (objectId === 'document') { + processDocument(packet, dataSource); + } else { + var entity = entityCollection.getOrCreateEntity(objectId); - if (canvas.width > 0 && canvas.height > 0) { - addGlyphToTextureAtlas(labelCollection._textureAtlas, id, canvas, glyphTextureInfo); - } + var parentId = packet.parent; + if (defined(parentId)) { + entity.parent = entityCollection.getOrCreateEntity(parentId); } - glyph = glyphs[textIndex]; - - if (defined(glyph)) { - // clean up leftover information from the previous glyph - if (glyphTextureInfo.index === -1) { - // no texture, and therefore no billboard, for this glyph. - // so, completely unbind glyph. - unbindGlyph(labelCollection, glyph); - } else if (defined(glyph.textureInfo)) { - // we have a texture and billboard. If we had one before, release - // our reference to that texture info, but reuse the billboard. - glyph.textureInfo = undefined; - } - } else { - // create a glyph object - glyph = new Glyph(); - glyphs[textIndex] = glyph; + for (var i = updaterFunctions.length - 1; i > -1; i--) { + updaterFunctions[i](entity, packet, entityCollection, sourceUri); } + } - glyph.textureInfo = glyphTextureInfo; - glyph.dimensions = glyphTextureInfo.dimensions; + currentId = undefined; + } - // if we have a texture, configure the existing billboard, or obtain one - if (glyphTextureInfo.index !== -1) { - var billboard = glyph.billboard; - var spareBillboards = labelCollection._spareBillboards; - if (!defined(billboard)) { - if (spareBillboards.length > 0) { - billboard = spareBillboards.pop(); - } else { - billboard = labelCollection._billboardCollection.add({ - collection : labelCollection - }); - } - glyph.billboard = billboard; - } + function updateClock(dataSource) { + var clock; + var clockPacket = dataSource._documentPacket.clock; + if (!defined(clockPacket)) { + if (!defined(dataSource._clock)) { + var availability = dataSource._entityCollection.computeAvailability(); + if (!availability.start.equals(Iso8601.MINIMUM_VALUE)) { + var startTime = availability.start; + var stopTime = availability.stop; + var totalSeconds = JulianDate.secondsDifference(stopTime, startTime); + var multiplier = Math.round(totalSeconds / 120.0); - billboard.show = label._show; - billboard.position = label._position; - billboard.eyeOffset = label._eyeOffset; - billboard.pixelOffset = label._pixelOffset; - billboard.horizontalOrigin = HorizontalOrigin.LEFT; - billboard.verticalOrigin = label._verticalOrigin; - billboard.heightReference = label._heightReference; - billboard.scale = label._scale; - billboard.pickPrimitive = label; - billboard.id = label._id; - billboard.image = id; - billboard.translucencyByDistance = label._translucencyByDistance; - billboard.pixelOffsetScaleByDistance = label._pixelOffsetScaleByDistance; - billboard.scaleByDistance = label._scaleByDistance; - billboard.distanceDisplayCondition = label._distanceDisplayCondition; - billboard.disableDepthTestDistance = label._disableDepthTestDistance; + clock = new DataSourceClock(); + clock.startTime = JulianDate.clone(startTime); + clock.stopTime = JulianDate.clone(stopTime); + clock.clockRange = ClockRange.LOOP_STOP; + clock.multiplier = multiplier; + clock.currentTime = JulianDate.clone(startTime); + clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; + dataSource._clock = clock; + return true; + } } + return false; } - // changing glyphs will cause the position of the - // glyphs to change, since different characters have different widths - label._repositionAllGlyphs = true; - } + if (defined(dataSource._clock)) { + clock = dataSource._clock.clone(); + } else { + clock = new DataSourceClock(); + clock.startTime = Iso8601.MINIMUM_VALUE.clone(); + clock.stopTime = Iso8601.MAXIMUM_VALUE.clone(); + clock.currentTime = Iso8601.MINIMUM_VALUE.clone(); + clock.clockRange = ClockRange.LOOP_STOP; + clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; + clock.multiplier = 1.0; + } + if (defined(clockPacket.interval)) { + iso8601Scratch.iso8601 = clockPacket.interval; + var interval = TimeInterval.fromIso8601(iso8601Scratch); + clock.startTime = interval.start; + clock.stopTime = interval.stop; + } + if (defined(clockPacket.currentTime)) { + clock.currentTime = JulianDate.fromIso8601(clockPacket.currentTime); + } + if (defined(clockPacket.range)) { + clock.clockRange = defaultValue(ClockRange[clockPacket.range], ClockRange.LOOP_STOP); + } + if (defined(clockPacket.step)) { + clock.clockStep = defaultValue(ClockStep[clockPacket.step], ClockStep.SYSTEM_CLOCK_MULTIPLIER); + } + if (defined(clockPacket.multiplier)) { + clock.multiplier = clockPacket.multiplier; + } - function calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding) { - if (horizontalOrigin === HorizontalOrigin.CENTER) { - return -lineWidth / 2; - } else if (horizontalOrigin === HorizontalOrigin.RIGHT) { - return -(lineWidth + backgroundPadding.x); + if (!clock.equals(dataSource._clock)) { + dataSource._clock = clock.clone(dataSource._clock); + return true; } - return backgroundPadding.x; + + return false; } - // reusable Cartesian2 instances - var glyphPixelOffset = new Cartesian2(); - var scratchBackgroundPadding = new Cartesian2(); + function load(dataSource, czml, options, clear) { + if (!defined(czml)) { + throw new DeveloperError('czml is required.'); + } + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - function repositionAllGlyphs(label, resolutionScale) { - var glyphs = label._glyphs; - var text = label._renderedText; - var glyph; - var dimensions; - var lastLineWidth = 0; - var maxLineWidth = 0; - var lineWidths = []; - var maxGlyphDescent = Number.NEGATIVE_INFINITY; - var maxGlyphY = 0; - var numberOfLines = 1; - var glyphIndex = 0; - var glyphLength = glyphs.length; + if (defined(options.query)) { + deprecationWarning('CzmlDataSource.query', 'The options.query parameter has been deprecated. Specify czml or options.sourceUri as a Resource instance and add query parameters there.'); + } - var backgroundBillboard = label._backgroundBillboard; - var backgroundPadding = scratchBackgroundPadding; - Cartesian2.clone( - (defined(backgroundBillboard) ? label._backgroundPadding : Cartesian2.ZERO), - backgroundPadding); + var promise = czml; + var sourceUri = options.sourceUri; + var query = options.query; - for (glyphIndex = 0; glyphIndex < glyphLength; ++glyphIndex) { - if (text.charAt(glyphIndex) === '\n') { - lineWidths.push(lastLineWidth); - ++numberOfLines; - lastLineWidth = 0; - } else { - glyph = glyphs[glyphIndex]; - dimensions = glyph.dimensions; - maxGlyphY = Math.max(maxGlyphY, dimensions.height - dimensions.descent); - maxGlyphDescent = Math.max(maxGlyphDescent, dimensions.descent); + // If the czml is a URL + if (typeof czml === 'string' || (czml instanceof Resource)) { + czml = Resource.createIfNeeded(czml, { + queryParameters: query + }); - //Computing the line width must also account for the kerning that occurs between letters. - lastLineWidth += dimensions.width - dimensions.bounds.minx; - if (glyphIndex < glyphLength - 1) { - lastLineWidth += glyphs[glyphIndex + 1].dimensions.bounds.minx; - } - maxLineWidth = Math.max(maxLineWidth, lastLineWidth); - } - } - lineWidths.push(lastLineWidth); - var maxLineHeight = maxGlyphY + maxGlyphDescent; + promise = czml.fetchJson(); - var scale = label._scale; - var horizontalOrigin = label._horizontalOrigin; - var verticalOrigin = label._verticalOrigin; - var lineIndex = 0; - var lineWidth = lineWidths[lineIndex]; - var widthOffset = calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding); - var lineSpacing = defaultLineSpacingPercent * maxLineHeight; - var otherLinesHeight = lineSpacing * (numberOfLines - 1); + sourceUri = defaultValue(sourceUri, czml.clone()); + } - glyphPixelOffset.x = widthOffset * scale * resolutionScale; - glyphPixelOffset.y = 0; + sourceUri = Resource.createIfNeeded(sourceUri, { + queryParameters: query + }); - var lineOffsetY = 0; - for (glyphIndex = 0; glyphIndex < glyphLength; ++glyphIndex) { - if (text.charAt(glyphIndex) === '\n') { - ++lineIndex; - lineOffsetY += lineSpacing; - lineWidth = lineWidths[lineIndex]; - widthOffset = calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding); - glyphPixelOffset.x = widthOffset * scale * resolutionScale; - } else { - glyph = glyphs[glyphIndex]; - dimensions = glyph.dimensions; + DataSource.setLoading(dataSource, true); - if (verticalOrigin === VerticalOrigin.TOP) { - glyphPixelOffset.y = dimensions.height - maxGlyphY - backgroundPadding.y; - } else if (verticalOrigin === VerticalOrigin.CENTER) { - glyphPixelOffset.y = (otherLinesHeight + dimensions.height - maxGlyphY) / 2; - } else if (verticalOrigin === VerticalOrigin.BASELINE) { - glyphPixelOffset.y = otherLinesHeight; - } else { - // VerticalOrigin.BOTTOM - glyphPixelOffset.y = otherLinesHeight + maxGlyphDescent + backgroundPadding.y; - } - glyphPixelOffset.y = (glyphPixelOffset.y - dimensions.descent - lineOffsetY) * scale * resolutionScale; + return when(promise, function(czml) { + return loadCzml(dataSource, czml, sourceUri, clear); + }).otherwise(function(error) { + DataSource.setLoading(dataSource, false); + dataSource._error.raiseEvent(dataSource, error); + console.log(error); + return when.reject(error); + }); + } - if (defined(glyph.billboard)) { - glyph.billboard._setTranslate(glyphPixelOffset); - } + function loadCzml(dataSource, czml, sourceUri, clear) { + DataSource.setLoading(dataSource, true); + var entityCollection = dataSource._entityCollection; - //Compute the next x offset taking into acocunt the kerning performed - //on both the current letter as well as the next letter to be drawn - //as well as any applied scale. - if (glyphIndex < glyphLength - 1) { - var nextGlyph = glyphs[glyphIndex + 1]; - glyphPixelOffset.x += ((dimensions.width - dimensions.bounds.minx) + nextGlyph.dimensions.bounds.minx) * scale * resolutionScale; - } - } + if (clear) { + dataSource._version = undefined; + dataSource._documentPacket = new DocumentPacket(); + entityCollection.removeAll(); } - if (defined(backgroundBillboard) && (text.split('\n').join('').length > 0)) { - if (horizontalOrigin === HorizontalOrigin.CENTER) { - widthOffset = -maxLineWidth / 2 - backgroundPadding.x; - } else if (horizontalOrigin === HorizontalOrigin.RIGHT) { - widthOffset = -(maxLineWidth + backgroundPadding.x * 2); - } else { - widthOffset = 0; - } - glyphPixelOffset.x = widthOffset * scale * resolutionScale; + CzmlDataSource._processCzml(czml, entityCollection, sourceUri, undefined, dataSource); - if (verticalOrigin === VerticalOrigin.TOP) { - glyphPixelOffset.y = maxLineHeight - maxGlyphY - maxGlyphDescent; - } else if (verticalOrigin === VerticalOrigin.CENTER) { - glyphPixelOffset.y = (maxLineHeight - maxGlyphY) / 2 - maxGlyphDescent; - } else if (verticalOrigin === VerticalOrigin.BASELINE) { - glyphPixelOffset.y = -backgroundPadding.y - maxGlyphDescent; - } else { - // VerticalOrigin.BOTTOM - glyphPixelOffset.y = 0; - } - glyphPixelOffset.y = glyphPixelOffset.y * scale * resolutionScale; + var raiseChangedEvent = updateClock(dataSource); - backgroundBillboard.width = maxLineWidth + (backgroundPadding.x * 2); - backgroundBillboard.height = maxLineHeight + otherLinesHeight + (backgroundPadding.y * 2); - backgroundBillboard._setTranslate(glyphPixelOffset); + var documentPacket = dataSource._documentPacket; + if (defined(documentPacket.name) && dataSource._name !== documentPacket.name) { + dataSource._name = documentPacket.name; + raiseChangedEvent = true; + } else if (!defined(dataSource._name) && defined(sourceUri)) { + dataSource._name = getFilenameFromUri(sourceUri.getUrlComponent()); + raiseChangedEvent = true; } - } - function destroyLabel(labelCollection, label) { - var glyphs = label._glyphs; - for (var i = 0, len = glyphs.length; i < len; ++i) { - unbindGlyph(labelCollection, glyphs[i]); - } - if (defined(label._backgroundBillboard)) { - labelCollection._backgroundBillboardCollection.remove(label._backgroundBillboard); - label._backgroundBillboard = undefined; + DataSource.setLoading(dataSource, false); + if (raiseChangedEvent) { + dataSource._changed.raiseEvent(dataSource); } - label._labelCollection = undefined; - if (defined(label._removeCallbackFunc)) { - label._removeCallbackFunc(); + return dataSource; + } + + function DocumentPacket() { + this.name = undefined; + this.clock = undefined; + } + + /** + * A {@link DataSource} which processes {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/CZML-Guide|CZML}. + * @alias CzmlDataSource + * @constructor + * + * @param {String} [name] An optional name for the data source. This value will be overwritten if a loaded document contains a name. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=CZML.html|Cesium Sandcastle CZML Demo} + */ + function CzmlDataSource(name) { + this._name = name; + this._changed = new Event(); + this._error = new Event(); + this._isLoading = false; + this._loading = new Event(); + this._clock = undefined; + this._documentPacket = new DocumentPacket(); + this._version = undefined; + this._entityCollection = new EntityCollection(this); + this._entityCluster = new EntityCluster(); + } + + /** + * Creates a Promise to a new instance loaded with the provided CZML data. + * + * @param {Resource|String|Object} czml A url or CZML object to be processed. + * @param {Object} [options] An object with the following properties: + * @param {Resource|String} [options.sourceUri] Overrides the url to use for resolving relative links. + * @returns {Promise.<CzmlDataSource>} A promise that resolves to the new instance once the data is processed. + */ + CzmlDataSource.load = function(czml, options) { + return new CzmlDataSource().load(czml, options); + }; + + defineProperties(CzmlDataSource.prototype, { + /** + * Gets a human-readable name for this instance. + * @memberof CzmlDataSource.prototype + * @type {String} + */ + name : { + get : function() { + return this._name; + } + }, + /** + * Gets the clock settings defined by the loaded CZML. If no clock is explicitly + * defined in the CZML, the combined availability of all objects is returned. If + * only static data exists, this value is undefined. + * @memberof CzmlDataSource.prototype + * @type {DataSourceClock} + */ + clock : { + get : function() { + return this._clock; + } + }, + /** + * Gets the collection of {@link Entity} instances. + * @memberof CzmlDataSource.prototype + * @type {EntityCollection} + */ + entities : { + get : function() { + return this._entityCollection; + } + }, + /** + * Gets a value indicating if the data source is currently loading data. + * @memberof CzmlDataSource.prototype + * @type {Boolean} + */ + isLoading : { + get : function() { + return this._isLoading; + } + }, + /** + * Gets an event that will be raised when the underlying data changes. + * @memberof CzmlDataSource.prototype + * @type {Event} + */ + changedEvent : { + get : function() { + return this._changed; + } + }, + /** + * Gets an event that will be raised if an error is encountered during processing. + * @memberof CzmlDataSource.prototype + * @type {Event} + */ + errorEvent : { + get : function() { + return this._error; + } + }, + /** + * Gets an event that will be raised when the data source either starts or stops loading. + * @memberof CzmlDataSource.prototype + * @type {Event} + */ + loadingEvent : { + get : function() { + return this._loading; + } + }, + /** + * Gets whether or not this data source should be displayed. + * @memberof CzmlDataSource.prototype + * @type {Boolean} + */ + show : { + get : function() { + return this._entityCollection.show; + }, + set : function(value) { + this._entityCollection.show = value; + } + }, + + /** + * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. + * + * @memberof CzmlDataSource.prototype + * @type {EntityCluster} + */ + clustering : { + get : function() { + return this._entityCluster; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value must be defined.'); + } + this._entityCluster = value; + } } + }); - destroyObject(label); - } + /** + * Gets the array of CZML processing functions. + * @memberof CzmlDataSource + * @type Array + */ + CzmlDataSource.updaters = [ + processBillboard, // + processBox, // + processCorridor, // + processCylinder, // + processEllipse, // + processEllipsoid, // + processLabel, // + processModel, // + processName, // + processDescription, // + processPath, // + processPoint, // + processPolygon, // + processPolyline, // + processProperties, // + processRectangle, // + processPosition, // + processViewFrom, // + processWall, // + processOrientation, // + processAvailability]; /** - * A renderable collection of labels. Labels are viewport-aligned text positioned in the 3D scene. - * Each label can have a different font, color, scale, etc. - * <br /><br /> - * <div align='center'> - * <img src='Images/Label.png' width='400' height='300' /><br /> - * Example labels - * </div> - * <br /><br /> - * Labels are added and removed from the collection using {@link LabelCollection#add} - * and {@link LabelCollection#remove}. - * - * @alias LabelCollection - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each label from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Scene} [options.scene] Must be passed in for labels that use the height reference property or will be depth tested against the globe. - * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The label blending option. The default - * is used for rendering both opaque and translucent labels. However, if either all of the labels are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. + * Processes the provided url or CZML object without clearing any existing data. * - * @performance For best performance, prefer a few collections, each with many labels, to - * many collections with only a few labels each. Avoid having collections where some - * labels change every frame and others do not; instead, create one or more collections - * for static labels, and one or more collections for dynamic labels. + * @param {Resource|String|Object} czml A url or CZML object to be processed. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. + * @returns {Promise.<CzmlDataSource>} A promise that resolves to this instances once the data is processed. + */ + CzmlDataSource.prototype.process = function(czml, options) { + return load(this, czml, options, false); + }; + + /** + * Loads the provided url or CZML object, replacing any existing data. * - * @see LabelCollection#add - * @see LabelCollection#remove - * @see Label - * @see BillboardCollection + * @param {Resource|String|Object} czml A url or CZML object to be processed. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. + * @returns {Promise.<CzmlDataSource>} A promise that resolves to this instances once the data is processed. + */ + CzmlDataSource.prototype.load = function(czml, options) { + return load(this, czml, options, true); + }; + + /** + * A helper function used by custom CZML updater functions + * which creates or updates a {@link Property} from a CZML packet. + * @function * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Labels.html|Cesium Sandcastle Labels Demo} + * @param {Function} type The constructor function for the property being processed. + * @param {Object} object The object on which the property will be added or updated. + * @param {String} propertyName The name of the property on the object. + * @param {Object} packetData The CZML packet being processed. + * @param {TimeInterval} interval A constraining interval for which the data is valid. + * @param {String} sourceUri The originating uri of the data being processed. + * @param {EntityCollection} entityCollection The collection being processsed. + */ + CzmlDataSource.processPacketData = processPacketData; + + /** + * A helper function used by custom CZML updater functions + * which creates or updates a {@link PositionProperty} from a CZML packet. + * @function * - * @example - * // Create a label collection with two labels - * var labels = scene.primitives.add(new Cesium.LabelCollection()); - * labels.add({ - * position : new Cesium.Cartesian3(1.0, 2.0, 3.0), - * text : 'A label' - * }); - * labels.add({ - * position : new Cesium.Cartesian3(4.0, 5.0, 6.0), - * text : 'Another label' - * }); + * @param {Object} object The object on which the property will be added or updated. + * @param {String} propertyName The name of the property on the object. + * @param {Object} packetData The CZML packet being processed. + * @param {TimeInterval} interval A constraining interval for which the data is valid. + * @param {String} sourceUri The originating uri of the data being processed. + * @param {EntityCollection} entityCollection The collection being processsed. */ - function LabelCollection(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + CzmlDataSource.processPositionPacketData = processPositionPacketData; - this._scene = options.scene; + /** + * A helper function used by custom CZML updater functions + * which creates or updates a {@link MaterialProperty} from a CZML packet. + * @function + * + * @param {Object} object The object on which the property will be added or updated. + * @param {String} propertyName The name of the property on the object. + * @param {Object} packetData The CZML packet being processed. + * @param {TimeInterval} interval A constraining interval for which the data is valid. + * @param {String} sourceUri The originating uri of the data being processed. + * @param {EntityCollection} entityCollection The collection being processsed. + */ + CzmlDataSource.processMaterialPacketData = processMaterialPacketData; - this._textureAtlas = undefined; - this._backgroundTextureAtlas = undefined; - this._whitePixelIndex = undefined; + CzmlDataSource._processCzml = function(czml, entityCollection, sourceUri, updaterFunctions, dataSource) { + updaterFunctions = defined(updaterFunctions) ? updaterFunctions : CzmlDataSource.updaters; - this._backgroundBillboardCollection = new BillboardCollection({ - scene : this._scene - }); - this._backgroundBillboardCollection.destroyTextureAtlas = false; + if (isArray(czml)) { + for (var i = 0, len = czml.length; i < len; i++) { + processCzmlPacket(czml[i], entityCollection, updaterFunctions, sourceUri, dataSource); + } + } else { + processCzmlPacket(czml, entityCollection, updaterFunctions, sourceUri, dataSource); + } + }; - this._billboardCollection = new BillboardCollection({ - scene : this._scene - }); - this._billboardCollection.destroyTextureAtlas = false; + return CzmlDataSource; +}); - this._spareBillboards = []; - this._glyphTextureCache = {}; - this._labels = []; - this._labelsToUpdate = []; - this._totalGlyphCount = 0; - this._resolutionScale = undefined; +define('DataSources/DataSourceCollection',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Event', + '../ThirdParty/when' + ], function( + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + Event, + when) { + 'use strict'; - /** - * The 4x4 transformation matrix that transforms each label in this collection from model to world coordinates. - * When this is the identity matrix, the labels are drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. - * - * @type Matrix4 - * @default {@link Matrix4.IDENTITY} - * - * @example - * var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); - * labels.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - * labels.add({ - * position : new Cesium.Cartesian3(0.0, 0.0, 0.0), - * text : 'Center' - * }); - * labels.add({ - * position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0), - * text : 'East' - * }); - * labels.add({ - * position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0), - * text : 'North' - * }); - * labels.add({ - * position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0), - * text : 'Up' - * }); - */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + /** + * A collection of {@link DataSource} instances. + * @alias DataSourceCollection + * @constructor + */ + function DataSourceCollection() { + this._dataSources = []; + this._dataSourceAdded = new Event(); + this._dataSourceRemoved = new Event(); + } + defineProperties(DataSourceCollection.prototype, { /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the primitive. - * </p> - * - * @type {Boolean} - * - * @default false + * Gets the number of data sources in this collection. + * @memberof DataSourceCollection.prototype + * @type {Number} + * @readonly */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + length : { + get : function() { + return this._dataSources.length; + } + }, /** - * The label blending option. The default is used for rendering both opaque and translucent labels. - * However, if either all of the labels are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve - * performance by up to 2x. - * @type {BlendOption} - * @default BlendOption.OPAQUE_AND_TRANSLUCENT + * An event that is raised when a data source is added to the collection. + * Event handlers are passed the data source that was added. + * @memberof DataSourceCollection.prototype + * @type {Event} + * @readonly */ - this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); - } + dataSourceAdded : { + get : function() { + return this._dataSourceAdded; + } + }, - defineProperties(LabelCollection.prototype, { /** - * Returns the number of labels in this collection. This is commonly used with - * {@link LabelCollection#get} to iterate over all the labels - * in the collection. - * @memberof LabelCollection.prototype - * @type {Number} + * An event that is raised when a data source is removed from the collection. + * Event handlers are passed the data source that was removed. + * @memberof DataSourceCollection.prototype + * @type {Event} + * @readonly */ - length : { + dataSourceRemoved : { get : function() { - return this._labels.length; + return this._dataSourceRemoved; } } }); /** - * Creates and adds a label with the specified initial properties to the collection. - * The added label is returned so it can be modified or removed from the collection later. - * - * @param {Object}[options] A template describing the label's properties as shown in Example 1. - * @returns {Label} The label that was added to the collection. - * - * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer - * is rewritten; this operations is <code>O(n)</code> and also incurs - * CPU to GPU overhead. For best performance, add as many billboards as possible before - * calling <code>update</code>. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Example 1: Add a label, specifying all the default values. - * var l = labels.add({ - * show : true, - * position : Cesium.Cartesian3.ZERO, - * text : '', - * font : '30px sans-serif', - * fillColor : Cesium.Color.WHITE, - * outlineColor : Cesium.Color.BLACK, - * outlineWidth : 1.0, - * showBackground : false, - * backgroundColor : new Cesium.Color(0.165, 0.165, 0.165, 0.8), - * backgroundPadding : new Cesium.Cartesian2(7, 5), - * style : Cesium.LabelStyle.FILL, - * pixelOffset : Cesium.Cartesian2.ZERO, - * eyeOffset : Cesium.Cartesian3.ZERO, - * horizontalOrigin : Cesium.HorizontalOrigin.LEFT, - * verticalOrigin : Cesium.VerticalOrigin.BASELINE, - * scale : 1.0, - * translucencyByDistance : undefined, - * pixelOffsetScaleByDistance : undefined, - * heightReference : HeightReference.NONE, - * distanceDisplayCondition : undefined - * }); - * - * @example - * // Example 2: Specify only the label's cartographic position, - * // text, and font. - * var l = labels.add({ - * position : Cesium.Cartesian3.fromRadians(longitude, latitude, height), - * text : 'Hello World', - * font : '24px Helvetica', - * }); + * Adds a data source to the collection. * - * @see LabelCollection#remove - * @see LabelCollection#removeAll + * @param {DataSource|Promise.<DataSource>} dataSource A data source or a promise to a data source to add to the collection. + * When passing a promise, the data source will not actually be added + * to the collection until the promise resolves successfully. + * @returns {Promise.<DataSource>} A Promise that resolves once the data source has been added to the collection. */ - LabelCollection.prototype.add = function(options) { - var label = new Label(options, this); - - this._labels.push(label); - this._labelsToUpdate.push(label); - - return label; + DataSourceCollection.prototype.add = function(dataSource) { + if (!defined(dataSource)) { + throw new DeveloperError('dataSource is required.'); + } + + var that = this; + var dataSources = this._dataSources; + return when(dataSource, function(value) { + //Only add the data source if removeAll has not been called + //Since it was added. + if (dataSources === that._dataSources) { + that._dataSources.push(value); + that._dataSourceAdded.raiseEvent(that, value); + } + return value; + }); }; /** - * Removes a label from the collection. Once removed, a label is no longer usable. - * - * @param {Label} label The label to remove. - * @returns {Boolean} <code>true</code> if the label was removed; <code>false</code> if the label was not found in the collection. - * - * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer - * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For - * best performance, remove as many labels as possible before calling <code>update</code>. - * If you intend to temporarily hide a label, it is usually more efficient to call - * {@link Label#show} instead of removing and re-adding the label. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * var l = labels.add(...); - * labels.remove(l); // Returns true + * Removes a data source from this collection, if present. * - * @see LabelCollection#add - * @see LabelCollection#removeAll - * @see Label#show + * @param {DataSource} dataSource The data source to remove. + * @param {Boolean} [destroy=false] Whether to destroy the data source in addition to removing it. + * @returns {Boolean} true if the data source was in the collection and was removed, + * false if the data source was not in the collection. */ - LabelCollection.prototype.remove = function(label) { - if (defined(label) && label._labelCollection === this) { - var index = this._labels.indexOf(label); - if (index !== -1) { - this._labels.splice(index, 1); - destroyLabel(this, label); - return true; + DataSourceCollection.prototype.remove = function(dataSource, destroy) { + destroy = defaultValue(destroy, false); + + var index = this._dataSources.indexOf(dataSource); + if (index !== -1) { + this._dataSources.splice(index, 1); + this._dataSourceRemoved.raiseEvent(this, dataSource); + + if (destroy && typeof dataSource.destroy === 'function') { + dataSource.destroy(); } + + return true; } + return false; }; /** - * Removes all labels from the collection. - * - * @performance <code>O(n)</code>. It is more efficient to remove all the labels - * from a collection and then add new ones than to create a new collection entirely. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * labels.add(...); - * labels.add(...); - * labels.removeAll(); + * Removes all data sources from this collection. * - * @see LabelCollection#add - * @see LabelCollection#remove + * @param {Boolean} [destroy=false] whether to destroy the data sources in addition to removing them. */ - LabelCollection.prototype.removeAll = function() { - var labels = this._labels; + DataSourceCollection.prototype.removeAll = function(destroy) { + destroy = defaultValue(destroy, false); - for (var i = 0, len = labels.length; i < len; ++i) { - destroyLabel(this, labels[i]); - } + var dataSources = this._dataSources; + for (var i = 0, len = dataSources.length; i < len; ++i) { + var dataSource = dataSources[i]; + this._dataSourceRemoved.raiseEvent(this, dataSource); - labels.length = 0; + if (destroy && typeof dataSource.destroy === 'function') { + dataSource.destroy(); + } + } + this._dataSources = []; }; /** - * Check whether this collection contains a given label. - * - * @param {Label} label The label to check for. - * @returns {Boolean} true if this collection contains the label, false otherwise. + * Checks to see if the collection contains a given data source. * - * @see LabelCollection#get + * @param {DataSource} dataSource The data source to check for. + * @returns {Boolean} true if the collection contains the data source, false otherwise. */ - LabelCollection.prototype.contains = function(label) { - return defined(label) && label._labelCollection === this; + DataSourceCollection.prototype.contains = function(dataSource) { + return this.indexOf(dataSource) !== -1; }; /** - * Returns the label in the collection at the specified index. Indices are zero-based - * and increase as labels are added. Removing a label shifts all labels after - * it to the left, changing their indices. This function is commonly used with - * {@link LabelCollection#length} to iterate over all the labels - * in the collection. - * - * @param {Number} index The zero-based index of the billboard. - * - * @returns {Label} The label at the specified index. - * - * @performance Expected constant time. If labels were removed from the collection and - * {@link Scene#render} was not called, an implicit <code>O(n)</code> - * operation is performed. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Toggle the show property of every label in the collection - * var len = labels.length; - * for (var i = 0; i < len; ++i) { - * var l = billboards.get(i); - * l.show = !l.show; - * } + * Determines the index of a given data source in the collection. * - * @see LabelCollection#length + * @param {DataSource} dataSource The data source to find the index of. + * @returns {Number} The index of the data source in the collection, or -1 if the data source does not exist in the collection. */ - LabelCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - return this._labels[index]; + DataSourceCollection.prototype.indexOf = function(dataSource) { + return this._dataSources.indexOf(dataSource); }; /** - * @private + * Gets a data source by index from the collection. + * + * @param {Number} index the index to retrieve. + * @returns {DataSource} The data source at the specified index. */ - LabelCollection.prototype.update = function(frameState) { - var billboardCollection = this._billboardCollection; - var backgroundBillboardCollection = this._backgroundBillboardCollection; - - billboardCollection.modelMatrix = this.modelMatrix; - billboardCollection.debugShowBoundingVolume = this.debugShowBoundingVolume; - backgroundBillboardCollection.modelMatrix = this.modelMatrix; - backgroundBillboardCollection.debugShowBoundingVolume = this.debugShowBoundingVolume; - - var context = frameState.context; - - if (!defined(this._textureAtlas)) { - this._textureAtlas = new TextureAtlas({ - context : context - }); - billboardCollection.textureAtlas = this._textureAtlas; - } - - if (!defined(this._backgroundTextureAtlas)) { - this._backgroundTextureAtlas = new TextureAtlas({ - context : context, - initialSize : whitePixelSize - }); - backgroundBillboardCollection.textureAtlas = this._backgroundTextureAtlas; - addWhitePixelCanvas(this._backgroundTextureAtlas, this); - } - - var uniformState = context.uniformState; - var resolutionScale = uniformState.resolutionScale; - var resolutionChanged = this._resolutionScale !== resolutionScale; - this._resolutionScale = resolutionScale; - - var labelsToUpdate; - if (resolutionChanged) { - labelsToUpdate = this._labels; - } else { - labelsToUpdate = this._labelsToUpdate; - } - - var len = labelsToUpdate.length; - for (var i = 0; i < len; ++i) { - var label = labelsToUpdate[i]; - if (label.isDestroyed()) { - continue; - } - - var preUpdateGlyphCount = label._glyphs.length; - - if (label._rebindAllGlyphs) { - rebindAllGlyphs(this, label); - label._rebindAllGlyphs = false; - } - - if (resolutionChanged || label._repositionAllGlyphs) { - repositionAllGlyphs(label, resolutionScale); - label._repositionAllGlyphs = false; - } - - var glyphCountDifference = label._glyphs.length - preUpdateGlyphCount; - this._totalGlyphCount += glyphCountDifference; + DataSourceCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); } - - var blendOption = backgroundBillboardCollection.length > 0 ? BlendOption.TRANSLUCENT : this.blendOption; - billboardCollection.blendOption = blendOption; - backgroundBillboardCollection.blendOption = blendOption; - - this._labelsToUpdate.length = 0; - backgroundBillboardCollection.update(frameState); - billboardCollection.update(frameState); + + return this._dataSources[index]; }; /** * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {Boolean} true if this object was destroyed; otherwise, false. * - * @see LabelCollection#destroy + * @see DataSourceCollection#destroy */ - LabelCollection.prototype.isDestroyed = function() { + DataSourceCollection.prototype.isDestroyed = function() { return false; }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than + * Destroys the resources held by all data sources in this collection. Explicitly destroying this + * object allows for deterministic release of WebGL resources, instead of relying on the garbage + * collector. Once this object is destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, * assign the return value (<code>undefined</code>) to the object as done in the example. * @@ -118129,13636 +129651,14579 @@ define('Scene/LabelCollection',[ * * * @example - * labels = labels && labels.destroy(); + * dataSourceCollection = dataSourceCollection && dataSourceCollection.destroy(); * - * @see LabelCollection#isDestroyed + * @see DataSourceCollection#isDestroyed */ - LabelCollection.prototype.destroy = function() { - this.removeAll(); - this._billboardCollection = this._billboardCollection.destroy(); - this._textureAtlas = this._textureAtlas && this._textureAtlas.destroy(); - this._backgroundBillboardCollection = this._backgroundBillboardCollection.destroy(); - this._backgroundTextureAtlas = this._backgroundTextureAtlas && this._backgroundTextureAtlas.destroy(); - + DataSourceCollection.prototype.destroy = function() { + this.removeAll(true); return destroyObject(this); }; - return LabelCollection; + return DataSourceCollection; }); -define('Scene/PointPrimitive',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', +define('DataSources/EllipseGeometryUpdater',[ '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', '../Core/DistanceDisplayCondition', - '../Core/Matrix4', - '../Core/NearFarScalar', - './SceneMode', - './SceneTransforms' + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/EllipseGeometry', + '../Core/EllipseOutlineGeometry', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/oneTimeWarning', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/GroundPrimitive', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' ], function( - BoundingRectangle, - Cartesian2, - Cartesian3, - Cartesian4, Color, + ColorGeometryInstanceAttribute, defaultValue, defined, defineProperties, + destroyObject, DeveloperError, DistanceDisplayCondition, - Matrix4, - NearFarScalar, - SceneMode, - SceneTransforms) { + DistanceDisplayConditionGeometryInstanceAttribute, + EllipseGeometry, + EllipseOutlineGeometry, + Event, + GeometryInstance, + Iso8601, + oneTimeWarning, + ShowGeometryInstanceAttribute, + GroundPrimitive, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { 'use strict'; + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.center = undefined; + this.semiMajorAxis = undefined; + this.semiMinorAxis = undefined; + this.rotation = undefined; + this.height = undefined; + this.extrudedHeight = undefined; + this.granularity = undefined; + this.stRotation = undefined; + this.numberOfVerticalLines = undefined; + } + /** - * A graphical point positioned in the 3D scene, that is created - * and rendered using a {@link PointPrimitiveCollection}. A point is created and its initial - * properties are set by calling {@link PointPrimitiveCollection#add}. - * - * @alias PointPrimitive - * - * @performance Reading a property, e.g., {@link PointPrimitive#show}, is constant time. - * Assigning to a property is constant time but results in - * CPU to GPU traffic when {@link PointPrimitiveCollection#update} is called. The per-pointPrimitive traffic is - * the same regardless of how many properties were updated. If most pointPrimitives in a collection need to be - * updated, it may be more efficient to clear the collection with {@link PointPrimitiveCollection#removeAll} - * and add new pointPrimitives instead of modifying each one. - * - * @exception {DeveloperError} scaleByDistance.far must be greater than scaleByDistance.near - * @exception {DeveloperError} translucencyByDistance.far must be greater than translucencyByDistance.near - * @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near - * - * @see PointPrimitiveCollection - * @see PointPrimitiveCollection#add - * - * @internalConstructor + * A {@link GeometryUpdater} for ellipses. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias EllipseGeometryUpdater + * @constructor * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Points.html|Cesium Sandcastle Points Demo} + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - function PointPrimitive(options, pointPrimitiveCollection) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); - } - - var translucencyByDistance = options.translucencyByDistance; - var scaleByDistance = options.scaleByDistance; - var distanceDisplayCondition = options.distanceDisplayCondition; - if (defined(translucencyByDistance)) { - if (translucencyByDistance.far <= translucencyByDistance.near) { - throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); - } - translucencyByDistance = NearFarScalar.clone(translucencyByDistance); - } - if (defined(scaleByDistance)) { - if (scaleByDistance.far <= scaleByDistance.near) { - throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); - } - scaleByDistance = NearFarScalar.clone(scaleByDistance); + function EllipseGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); } - if (defined(distanceDisplayCondition)) { - if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); - } - distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); + if (!defined(scene)) { + throw new DeveloperError('scene is required'); } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._isClosed = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._onTerrain = false; + this._options = new GeometryOptions(entity); - this._show = defaultValue(options.show, true); - this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); - this._actualPosition = Cartesian3.clone(this._position); // For columbus view and 2D - this._color = Color.clone(defaultValue(options.color, Color.WHITE)); - this._outlineColor = Color.clone(defaultValue(options.outlineColor, Color.TRANSPARENT)); - this._outlineWidth = defaultValue(options.outlineWidth, 0.0); - this._pixelSize = defaultValue(options.pixelSize, 10.0); - this._scaleByDistance = scaleByDistance; - this._translucencyByDistance = translucencyByDistance; - this._distanceDisplayCondition = distanceDisplayCondition; - this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); - this._id = options.id; - this._collection = defaultValue(options.collection, pointPrimitiveCollection); - - this._clusterShow = true; - - this._pickId = undefined; - this._pointPrimitiveCollection = pointPrimitiveCollection; - this._dirty = false; - this._index = -1; //Used only by PointPrimitiveCollection + this._onEntityPropertyChanged(entity, 'ellipse', entity.ellipse, undefined); } - var SHOW_INDEX = PointPrimitive.SHOW_INDEX = 0; - var POSITION_INDEX = PointPrimitive.POSITION_INDEX = 1; - var COLOR_INDEX = PointPrimitive.COLOR_INDEX = 2; - var OUTLINE_COLOR_INDEX = PointPrimitive.OUTLINE_COLOR_INDEX = 3; - var OUTLINE_WIDTH_INDEX = PointPrimitive.OUTLINE_WIDTH_INDEX = 4; - var PIXEL_SIZE_INDEX = PointPrimitive.PIXEL_SIZE_INDEX = 5; - var SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX = 6; - var TRANSLUCENCY_BY_DISTANCE_INDEX = PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX = 7; - var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX = 8; - var DISABLE_DEPTH_DISTANCE_INDEX = PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX = 9; - PointPrimitive.NUMBER_OF_PROPERTIES = 10; - - function makeDirty(pointPrimitive, propertyChanged) { - var pointPrimitiveCollection = pointPrimitive._pointPrimitiveCollection; - if (defined(pointPrimitiveCollection)) { - pointPrimitiveCollection._updatePointPrimitive(pointPrimitive, propertyChanged); - pointPrimitive._dirty = true; + defineProperties(EllipseGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof EllipseGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof EllipseGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance } - } + }); - defineProperties(PointPrimitive.prototype, { + defineProperties(EllipseGeometryUpdater.prototype, { /** - * Determines if this point will be shown. Use this to hide or show a point, instead - * of removing it and re-adding it to the collection. - * @memberof PointPrimitive.prototype - * @type {Boolean} + * Gets the entity associated with this geometry. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Entity} + * @readonly */ - show : { + entity : { get : function() { - return this._show; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._show !== value) { - this._show = value; - makeDirty(this, SHOW_INDEX); - } + return this._entity; } }, - /** - * Gets or sets the Cartesian position of this point. - * @memberof PointPrimitive.prototype - * @type {Cartesian3} - */ - position : { + * Gets a value indicating if the geometry has a fill component. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + fillEnabled : { get : function() { - return this._position; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var position = this._position; - if (!Cartesian3.equals(position, value)) { - Cartesian3.clone(value, position); - Cartesian3.clone(value, this._actualPosition); - - makeDirty(this, POSITION_INDEX); - } + return this._fillEnabled; } }, - /** - * Gets or sets near and far scaling properties of a point based on the point's distance from the camera. - * A point's scale will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the point's scale remains clamped to the nearest bound. This scale - * multiplies the pixelSize and outlineWidth to affect the total size of the point. If undefined, - * scaleByDistance will be disabled. - * @memberof PointPrimitive.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a pointPrimitive's scaleByDistance to scale to 15 when the - * // camera is 1500 meters from the pointPrimitive and disappear as - * // the camera distance approaches 8.0e6 meters. - * p.scaleByDistance = new Cesium.NearFarScalar(1.5e2, 15, 8.0e6, 0.0); + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof EllipseGeometryUpdater.prototype * - * @example - * // Example 2. - * // disable scaling by distance - * p.scaleByDistance = undefined; + * @type {Boolean} + * @readonly */ - scaleByDistance : { + hasConstantFill : { get : function() { - return this._scaleByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var scaleByDistance = this._scaleByDistance; - if (!NearFarScalar.equals(scaleByDistance, value)) { - this._scaleByDistance = NearFarScalar.clone(value, scaleByDistance); - makeDirty(this, SCALE_BY_DISTANCE_INDEX); - } + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, - /** - * Gets or sets near and far translucency properties of a point based on the point's distance from the camera. - * A point's translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the point's translucency remains clamped to the nearest bound. If undefined, - * translucencyByDistance will be disabled. - * @memberof PointPrimitive.prototype - * @type {NearFarScalar} - * - * @example - * // Example 1. - * // Set a point's translucency to 1.0 when the - * // camera is 1500 meters from the point and disappear as - * // the camera distance approaches 8.0e6 meters. - * p.translucencyByDistance = new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.0); + * Gets the material property used to fill the geometry. + * @memberof EllipseGeometryUpdater.prototype * - * @example - * // Example 2. - * // disable translucency by distance - * p.translucencyByDistance = undefined; + * @type {MaterialProperty} + * @readonly */ - translucencyByDistance : { + fillMaterialProperty : { get : function() { - return this._translucencyByDistance; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - - var translucencyByDistance = this._translucencyByDistance; - if (!NearFarScalar.equals(translucencyByDistance, value)) { - this._translucencyByDistance = NearFarScalar.clone(value, translucencyByDistance); - makeDirty(this, TRANSLUCENCY_BY_DISTANCE_INDEX); - } + return this._materialProperty; } }, - /** - * Gets or sets the inner size of the point in pixels. - * @memberof PointPrimitive.prototype - * @type {Number} + * Gets a value indicating if the geometry has an outline component. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - pixelSize : { + outlineEnabled : { get : function() { - return this._pixelSize; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._pixelSize !== value) { - this._pixelSize = value; - makeDirty(this, PIXEL_SIZE_INDEX); - } + return this._outlineEnabled; } }, - /** - * Gets or sets the inner color of the point. - * The red, green, blue, and alpha values are indicated by <code>value</code>'s <code>red</code>, <code>green</code>, - * <code>blue</code>, and <code>alpha</code> properties as shown in Example 1. These components range from <code>0.0</code> - * (no intensity) to <code>1.0</code> (full intensity). - * @memberof PointPrimitive.prototype - * @type {Color} + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof EllipseGeometryUpdater.prototype * - * @example - * // Example 1. Assign yellow. - * p.color = Cesium.Color.YELLOW; + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof EllipseGeometryUpdater.prototype * - * @example - * // Example 2. Make a pointPrimitive 50% translucent. - * p.color = new Cesium.Color(1.0, 1.0, 1.0, 0.5); + * @type {Property} + * @readonly */ - color : { + outlineColorProperty : { get : function() { - return this._color; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var color = this._color; - if (!Color.equals(color, value)) { - Color.clone(value, color); - makeDirty(this, COLOR_INDEX); - } + return this._outlineColorProperty; + } + }, + /** + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Number} + * @readonly + */ + outlineWidth : { + get : function() { + return this._outlineWidth; } }, - /** - * Gets or sets the outline color of the point. - * @memberof PointPrimitive.prototype - * @type {Color} + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Property} + * @readonly */ - outlineColor : { + shadowsProperty : { get : function() { - return this._outlineColor; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var outlineColor = this._outlineColor; - if (!Color.equals(outlineColor, value)) { - Color.clone(value, outlineColor); - makeDirty(this, OUTLINE_COLOR_INDEX); - } + return this._shadowsProperty; } }, - /** - * Gets or sets the outline width in pixels. This width adds to pixelSize, - * increasing the total size of the point. - * @memberof PointPrimitive.prototype - * @type {Number} + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Property} + * @readonly */ - outlineWidth : { + distanceDisplayConditionProperty : { get : function() { - return this._outlineWidth; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._outlineWidth !== value) { - this._outlineWidth = value; - makeDirty(this, OUTLINE_WIDTH_INDEX); - } + return this._distanceDisplayConditionProperty; } }, - /** - * Gets or sets the condition specifying at what distance from the camera that this point will be displayed. - * @memberof PointPrimitive.prototype - * @type {DistanceDisplayCondition} - * @default undefined + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - distanceDisplayCondition : { + isDynamic : { get : function() { - return this._distanceDisplayCondition; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far must be greater than near'); - } - if (!DistanceDisplayCondition.equals(this._distanceDisplayCondition, value)) { - this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); - makeDirty(this, DISTANCE_DISPLAY_CONDITION_INDEX); - } + return this._dynamic; } }, - /** - * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. - * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. - * @memberof PointPrimitive.prototype - * @type {Number} - * @default 0.0 + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - disableDepthTestDistance : { + isClosed : { get : function() { - return this._disableDepthTestDistance; - }, - set : function(value) { - if (this._disableDepthTestDistance !== value) { - if (!defined(value) || value < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); - } - this._disableDepthTestDistance = value; - makeDirty(this, DISABLE_DEPTH_DISTANCE_INDEX); - } + return this._isClosed; } }, - /** - * Gets or sets the user-defined object returned when the point is picked. - * @memberof PointPrimitive.prototype - * @type {Object} + * Gets a value indicating if the geometry should be drawn on terrain. + * @memberof EllipseGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - id : { + onTerrain : { get : function() { - return this._id; - }, - set : function(value) { - this._id = value; - if (defined(this._pickId)) { - this._pickId.object.id = value; - } + return this._onTerrain; } }, - /** - * Determines whether or not this point will be shown or hidden because it was clustered. - * @memberof PointPrimitive.prototype + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof EllipseGeometryUpdater.prototype + * * @type {Boolean} - * @private + * @readonly */ - clusterShow : { + geometryChanged : { get : function() { - return this._clusterShow; - }, - set : function(value) { - if (this._clusterShow !== value) { - this._clusterShow = value; - makeDirty(this, SHOW_INDEX); - } + return this._geometryChanged; } } }); - PointPrimitive.prototype.getPickId = function(context) { - if (!defined(this._pickId)) { - this._pickId = context.createPickId({ - primitive : this, - collection : this._collection, - id : this._id - }); - } - - return this._pickId; + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + EllipseGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; - PointPrimitive.prototype._getActualPosition = function() { - return this._actualPosition; + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + EllipseGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; - PointPrimitive.prototype._setActualPosition = function(value) { - Cartesian3.clone(value, this._actualPosition); - makeDirty(this, POSITION_INDEX); - }; + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + EllipseGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - var tempCartesian3 = new Cartesian4(); - PointPrimitive._computeActualPosition = function(position, frameState, modelMatrix) { - if (frameState.mode === SceneMode.SCENE3D) { - return position; + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - Matrix4.multiplyByPoint(modelMatrix, position, tempCartesian3); - return SceneTransforms.computeActualWgs84Position(frameState, tempCartesian3); - }; + var attributes; - var scratchCartesian4 = new Cartesian4(); + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + } - // This function is basically a stripped-down JavaScript version of PointPrimitiveCollectionVS.glsl - PointPrimitive._computeScreenSpacePosition = function(modelMatrix, position, scene, result) { - // Model to world coordinates - var positionWorld = Matrix4.multiplyByVector(modelMatrix, Cartesian4.fromElements(position.x, position.y, position.z, 1, scratchCartesian4), scratchCartesian4); - var positionWC = SceneTransforms.wgs84ToWindowCoordinates(scene, positionWorld, result); - return positionWC; + return new GeometryInstance({ + id : entity, + geometry : new EllipseGeometry(this._options), + attributes : attributes + }); }; /** - * Computes the screen-space position of the point's origin. - * The screen space origin is the top, left corner of the canvas; <code>x</code> increases from - * left to right, and <code>y</code> increases from top to bottom. - * - * @param {Scene} scene The scene. - * @param {Cartesian2} [result] The object onto which to store the result. - * @returns {Cartesian2} The screen-space position of the point. + * Creates the geometry instance which represents the outline of the geometry. * - * @exception {DeveloperError} PointPrimitive must be in a collection. + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. * - * @example - * console.log(p.computeScreenSpacePosition(scene).toString()); + * @exception {DeveloperError} This instance does not represent an outlined geometry. */ - PointPrimitive.prototype.computeScreenSpacePosition = function(scene, result) { - var pointPrimitiveCollection = this._pointPrimitiveCollection; - if (!defined(result)) { - result = new Cartesian2(); + EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - if (!defined(pointPrimitiveCollection)) { - throw new DeveloperError('PointPrimitive must be in a collection.'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); } - var modelMatrix = pointPrimitiveCollection.modelMatrix; - var windowCoordinates = PointPrimitive._computeScreenSpacePosition(modelMatrix, this._actualPosition, scene, result); - if (!defined(windowCoordinates)) { - return undefined; - } + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - windowCoordinates.y = scene.canvas.clientHeight - windowCoordinates.y; - return windowCoordinates; + return new GeometryInstance({ + id : entity, + geometry : new EllipseOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); }; /** - * Gets a point's screen space bounding box centered around screenSpacePosition. - * @param {PointPrimitive} point The point to get the screen space bounding box for. - * @param {Cartesian2} screenSpacePosition The screen space center of the label. - * @param {BoundingRectangle} [result] The object onto which to store the result. - * @returns {BoundingRectangle} The screen space bounding box. + * Returns true if this object was destroyed; otherwise, false. * - * @private + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - PointPrimitive.getScreenSpaceBoundingBox = function(point, screenSpacePosition, result) { - var size = point.pixelSize; - var halfSize = size * 0.5; + EllipseGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - var x = screenSpacePosition.x - halfSize; - var y = screenSpacePosition.y - halfSize; - var width = size; - var height = size; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + EllipseGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; - if (!defined(result)) { - result = new BoundingRectangle(); + EllipseGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'ellipse')) { + return; } - result.x = x; - result.y = y; - result.width = width; - result.height = height; + var ellipse = this._entity.ellipse; - return result; + if (!defined(ellipse)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var fillProperty = ellipse.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = ellipse.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } + + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var position = this._entity.position; + var semiMajorAxis = ellipse.semiMajorAxis; + var semiMinorAxis = ellipse.semiMinorAxis; + + var show = ellipse.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(ellipse.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(ellipse.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(ellipse.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(ellipse.distanceDisplayCondition, defaultDistanceDisplayCondition); + + var rotation = ellipse.rotation; + var height = ellipse.height; + var extrudedHeight = ellipse.extrudedHeight; + var granularity = ellipse.granularity; + var stRotation = ellipse.stRotation; + var outlineWidth = ellipse.outlineWidth; + var numberOfVerticalLines = ellipse.numberOfVerticalLines; + var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && + isColorMaterial && GroundPrimitive.isSupported(this._scene); + + if (outlineEnabled && onTerrain) { + oneTimeWarning(oneTimeWarning.geometryOutlines); + outlineEnabled = false; + } + + this._fillEnabled = fillEnabled; + this._onTerrain = onTerrain; + this._isClosed = defined(extrudedHeight) || onTerrain; + this._outlineEnabled = outlineEnabled; + + if (!position.isConstant || // + !semiMajorAxis.isConstant || // + !semiMinorAxis.isConstant || // + !Property.isConstant(rotation) || // + !Property.isConstant(height) || // + !Property.isConstant(extrudedHeight) || // + !Property.isConstant(granularity) || // + !Property.isConstant(stRotation) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(numberOfVerticalLines) || // + (onTerrain && !Property.isConstant(material))) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.center = position.getValue(Iso8601.MINIMUM_VALUE, options.center); + options.semiMajorAxis = semiMajorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMajorAxis); + options.semiMinorAxis = semiMinorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMinorAxis); + options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } }; /** - * Determines if this point equals another point. Points are equal if all their properties - * are equal. Points in different collections can be equal. + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. * - * @param {PointPrimitive} other The point to compare for equality. - * @returns {Boolean} <code>true</code> if the points are equal; otherwise, <code>false</code>. + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @param {PrimitiveCollection} groundPrimitives The ground primitives collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. */ - PointPrimitive.prototype.equals = function(other) { - return this === other || - defined(other) && - this._id === other._id && - Cartesian3.equals(this._position, other._position) && - Color.equals(this._color, other._color) && - this._pixelSize === other._pixelSize && - this._outlineWidth === other._outlineWidth && - this._show === other._show && - Color.equals(this._outlineColor, other._outlineColor) && - NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && - NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && - DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && - this._disableDepthTestDistance === other._disableDepthTestDistance; + EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } + + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, groundPrimitives, this); }; - PointPrimitive.prototype._destroy = function() { - this._pickId = this._pickId && this._pickId.destroy(); - this._pointPrimitiveCollection = undefined; + /** + * @private + */ + function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { + this._primitives = primitives; + this._groundPrimitives = groundPrimitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var geometryUpdater = this._geometryUpdater; + var onTerrain = geometryUpdater._onTerrain; + + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._outlinePrimitive = undefined; + } + this._primitive = undefined; + + + var entity = geometryUpdater._entity; + var ellipse = entity.ellipse; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(ellipse.show, time, true)) { + return; + } + + var options = this._options; + var center = Property.getValueOrUndefined(entity.position, time, options.center); + var semiMajorAxis = Property.getValueOrUndefined(ellipse.semiMajorAxis, time); + var semiMinorAxis = Property.getValueOrUndefined(ellipse.semiMinorAxis, time); + if (!defined(center) || !defined(semiMajorAxis) || !defined(semiMinorAxis)) { + return; + } + + options.center = center; + options.semiMajorAxis = semiMajorAxis; + options.semiMinorAxis = semiMinorAxis; + options.rotation = Property.getValueOrUndefined(ellipse.rotation, time); + options.height = Property.getValueOrUndefined(ellipse.height, time); + options.extrudedHeight = Property.getValueOrUndefined(ellipse.extrudedHeight, time); + options.granularity = Property.getValueOrUndefined(ellipse.granularity, time); + options.stRotation = Property.getValueOrUndefined(ellipse.stRotation, time); + options.numberOfVerticalLines = Property.getValueOrUndefined(ellipse.numberOfVerticalLines, time); + + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + + var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + + if (Property.getValueOrDefault(ellipse.fill, time, true)) { + var fillMaterialProperty = geometryUpdater.fillMaterialProperty; + var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); + this._material = material; + + if (onTerrain) { + var currentColor = Color.WHITE; + if (defined(fillMaterialProperty.color)) { + currentColor = fillMaterialProperty.color.getValue(time); + } + + this._primitive = groundPrimitives.add(new GroundPrimitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new EllipseGeometry(options), + attributes: { + color: ColorGeometryInstanceAttribute.fromColor(currentColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + asynchronous : false, + shadows : shadows + })); + } else { + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : defined(options.extrudedHeight) + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new EllipseGeometry(options) + }), + attributes : { + distanceDisplayCondition : distanceDisplayConditionAttribute + }, + appearance : appearance, + asynchronous : false, + shadows : shadows + })); + } + } + + if (!onTerrain && Property.getValueOrDefault(ellipse.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = Property.getValueOrClonedDefault(ellipse.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(ellipse.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; + + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new EllipseOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } }; - return PointPrimitive; -}); + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PointPrimitiveCollectionFS',[],function() { - 'use strict'; - return "varying vec4 v_color;\n\ -varying vec4 v_outlineColor;\n\ -varying float v_innerPercent;\n\ -varying float v_pixelDistance;\n\ -#ifdef RENDER_FOR_PICK\n\ -varying vec4 v_pickColor;\n\ -#endif\n\ -void main()\n\ -{\n\ -float distanceToCenter = length(gl_PointCoord - vec2(0.5));\n\ -float maxDistance = max(0.0, 0.5 - v_pixelDistance);\n\ -float wholeAlpha = 1.0 - smoothstep(maxDistance, 0.5, distanceToCenter);\n\ -float innerAlpha = 1.0 - smoothstep(maxDistance * v_innerPercent, 0.5 * v_innerPercent, distanceToCenter);\n\ -vec4 color = mix(v_outlineColor, v_color, innerAlpha);\n\ -color.a *= wholeAlpha;\n\ -#if defined(RENDER_FOR_PICK) || (!defined(OPAQUE) && !defined(TRANSLUCENT))\n\ -if (color.a < 0.005)\n\ -{\n\ -discard;\n\ -}\n\ -#else\n\ -#ifdef OPAQUE\n\ -if (color.a < 0.995)\n\ -{\n\ -discard;\n\ -}\n\ -#else\n\ -if (color.a >= 0.995)\n\ -{\n\ -discard;\n\ -}\n\ -#endif\n\ -#endif\n\ -#ifdef RENDER_FOR_PICK\n\ -gl_FragColor = v_pickColor;\n\ -#else\n\ -gl_FragColor = color;\n\ -#endif\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PointPrimitiveCollectionVS',[],function() { - 'use strict'; - return "uniform float u_maxTotalPointSize;\n\ -attribute vec4 positionHighAndSize;\n\ -attribute vec4 positionLowAndOutline;\n\ -attribute vec4 compressedAttribute0;\n\ -attribute vec4 compressedAttribute1;\n\ -attribute vec4 scaleByDistance;\n\ -attribute vec3 distanceDisplayConditionAndDisableDepth;\n\ -varying vec4 v_color;\n\ -varying vec4 v_outlineColor;\n\ -varying float v_innerPercent;\n\ -varying float v_pixelDistance;\n\ -#ifdef RENDER_FOR_PICK\n\ -varying vec4 v_pickColor;\n\ -#endif\n\ -const float SHIFT_LEFT8 = 256.0;\n\ -const float SHIFT_RIGHT8 = 1.0 / 256.0;\n\ -void main()\n\ -{\n\ -vec3 positionHigh = positionHighAndSize.xyz;\n\ -vec3 positionLow = positionLowAndOutline.xyz;\n\ -float outlineWidthBothSides = 2.0 * positionLowAndOutline.w;\n\ -float totalSize = positionHighAndSize.w + outlineWidthBothSides;\n\ -float outlinePercent = outlineWidthBothSides / totalSize;\n\ -totalSize *= czm_resolutionScale;\n\ -totalSize += 3.0;\n\ -float temp = compressedAttribute1.x * SHIFT_RIGHT8;\n\ -float show = floor(temp);\n\ -#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ -vec4 translucencyByDistance;\n\ -translucencyByDistance.x = compressedAttribute1.z;\n\ -translucencyByDistance.z = compressedAttribute1.w;\n\ -translucencyByDistance.y = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ -temp = compressedAttribute1.y * SHIFT_RIGHT8;\n\ -translucencyByDistance.w = ((temp - floor(temp)) * SHIFT_LEFT8) / 255.0;\n\ -#endif\n\ -vec4 color;\n\ -vec4 outlineColor;\n\ -#ifdef RENDER_FOR_PICK\n\ -color = vec4(0.0);\n\ -outlineColor = vec4(0.0);\n\ -vec4 pickColor;\n\ -temp = compressedAttribute0.z * SHIFT_RIGHT8;\n\ -pickColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -temp = floor(temp) * SHIFT_RIGHT8;\n\ -pickColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -pickColor.r = floor(temp);\n\ -#else\n\ -temp = compressedAttribute0.x * SHIFT_RIGHT8;\n\ -color.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -temp = floor(temp) * SHIFT_RIGHT8;\n\ -color.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -color.r = floor(temp);\n\ -temp = compressedAttribute0.y * SHIFT_RIGHT8;\n\ -outlineColor.b = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -temp = floor(temp) * SHIFT_RIGHT8;\n\ -outlineColor.g = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -outlineColor.r = floor(temp);\n\ -#endif\n\ -temp = compressedAttribute0.w * SHIFT_RIGHT8;\n\ -#ifdef RENDER_FOR_PICK\n\ -pickColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -pickColor = pickColor / 255.0;\n\ -#endif\n\ -temp = floor(temp) * SHIFT_RIGHT8;\n\ -outlineColor.a = (temp - floor(temp)) * SHIFT_LEFT8;\n\ -outlineColor /= 255.0;\n\ -color.a = floor(temp);\n\ -color /= 255.0;\n\ -vec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\n\ -vec4 positionEC = czm_modelViewRelativeToEye * p;\n\ -positionEC.xyz *= show;\n\ -#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE)\n\ -float lengthSq;\n\ -if (czm_sceneMode == czm_sceneMode2D)\n\ -{\n\ -lengthSq = czm_eyeHeight2D.y;\n\ -}\n\ -else\n\ -{\n\ -lengthSq = dot(positionEC.xyz, positionEC.xyz);\n\ -}\n\ -#endif\n\ -#ifdef EYE_DISTANCE_SCALING\n\ -totalSize *= czm_nearFarScalar(scaleByDistance, lengthSq);\n\ -#endif\n\ -totalSize = min(totalSize, u_maxTotalPointSize);\n\ -if (totalSize < 1.0)\n\ -{\n\ -positionEC.xyz = vec3(0.0);\n\ -totalSize = 1.0;\n\ -}\n\ -float translucency = 1.0;\n\ -#ifdef EYE_DISTANCE_TRANSLUCENCY\n\ -translucency = czm_nearFarScalar(translucencyByDistance, lengthSq);\n\ -if (translucency < 0.004)\n\ -{\n\ -positionEC.xyz = vec3(0.0);\n\ -}\n\ -#endif\n\ -#ifdef DISTANCE_DISPLAY_CONDITION\n\ -float nearSq = distanceDisplayConditionAndDisableDepth.x;\n\ -float farSq = distanceDisplayConditionAndDisableDepth.y;\n\ -if (lengthSq < nearSq || lengthSq > farSq) {\n\ -positionEC.xyz = vec3(0.0);\n\ -}\n\ -#endif\n\ -vec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\n\ -gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);\n\ -#ifdef DISABLE_DEPTH_DISTANCE\n\ -float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z;\n\ -if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0)\n\ -{\n\ -disableDepthTestDistance = czm_minimumDisableDepthTestDistance;\n\ -}\n\ -if (disableDepthTestDistance != 0.0)\n\ -{\n\ -float zclip = gl_Position.z / gl_Position.w;\n\ -bool clipped = (zclip < -1.0 || zclip > 1.0);\n\ -if (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance)))\n\ -{\n\ -gl_Position.z = -gl_Position.w;\n\ -}\n\ -}\n\ -#endif\n\ -v_color = color;\n\ -v_color.a *= translucency;\n\ -v_outlineColor = outlineColor;\n\ -v_outlineColor.a *= translucency;\n\ -v_innerPercent = 1.0 - outlinePercent;\n\ -v_pixelDistance = 2.0 / totalSize;\n\ -gl_PointSize = totalSize;\n\ -#ifdef RENDER_FOR_PICK\n\ -v_pickColor = pickColor;\n\ -#endif\n\ -}\n\ -"; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (this._geometryUpdater._onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + } + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; + + return EllipseGeometryUpdater; }); -define('Scene/PointPrimitiveCollection',[ - '../Core/BoundingSphere', + +define('DataSources/EllipsoidGeometryUpdater',[ + '../Core/Cartesian3', '../Core/Color', - '../Core/ComponentDatatype', + '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/EncodedCartesian3', - '../Core/Math', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/EllipsoidGeometry', + '../Core/EllipsoidOutlineGeometry', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', '../Core/Matrix4', - '../Core/PrimitiveType', - '../Core/WebGLConstants', - '../Renderer/BufferUsage', - '../Renderer/ContextLimits', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/VertexArrayFacade', - '../Shaders/PointPrimitiveCollectionFS', - '../Shaders/PointPrimitiveCollectionVS', - './BlendingState', - './BlendOption', - './PointPrimitive', - './SceneMode' + '../Core/ShowGeometryInstanceAttribute', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/SceneMode', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' ], function( - BoundingSphere, + Cartesian3, Color, - ComponentDatatype, + ColorGeometryInstanceAttribute, defaultValue, defined, defineProperties, destroyObject, DeveloperError, - EncodedCartesian3, - CesiumMath, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + EllipsoidGeometry, + EllipsoidOutlineGeometry, + Event, + GeometryInstance, + Iso8601, Matrix4, - PrimitiveType, - WebGLConstants, - BufferUsage, - ContextLimits, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - VertexArrayFacade, - PointPrimitiveCollectionFS, - PointPrimitiveCollectionVS, - BlendingState, - BlendOption, - PointPrimitive, - SceneMode) { + ShowGeometryInstanceAttribute, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + SceneMode, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { 'use strict'; - var SHOW_INDEX = PointPrimitive.SHOW_INDEX; - var POSITION_INDEX = PointPrimitive.POSITION_INDEX; - var COLOR_INDEX = PointPrimitive.COLOR_INDEX; - var OUTLINE_COLOR_INDEX = PointPrimitive.OUTLINE_COLOR_INDEX; - var OUTLINE_WIDTH_INDEX = PointPrimitive.OUTLINE_WIDTH_INDEX; - var PIXEL_SIZE_INDEX = PointPrimitive.PIXEL_SIZE_INDEX; - var SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX; - var TRANSLUCENCY_BY_DISTANCE_INDEX = PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX; - var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX; - var DISABLE_DEPTH_DISTANCE_INDEX = PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX; - var NUMBER_OF_PROPERTIES = PointPrimitive.NUMBER_OF_PROPERTIES; + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var attributeLocations = { - positionHighAndSize : 0, - positionLowAndOutline : 1, - compressedAttribute0 : 2, // color, outlineColor, pick color - compressedAttribute1 : 3, // show, translucency by distance, some free space - scaleByDistance : 4, - distanceDisplayConditionAndDisableDepth : 5 - }; + var radiiScratch = new Cartesian3(); + var scratchColor = new Color(); + var unitSphere = new Cartesian3(1, 1, 1); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.radii = undefined; + this.stackPartitions = undefined; + this.slicePartitions = undefined; + this.subdivisions = undefined; + } /** - * A renderable collection of points. - * <br /><br /> - * Points are added and removed from the collection using {@link PointPrimitiveCollection#add} - * and {@link PointPrimitiveCollection#remove}. - * - * @alias PointPrimitiveCollection + * A {@link GeometryUpdater} for ellipsoids. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias EllipsoidGeometryUpdater * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each point from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The point blending option. The default - * is used for rendering both opaque and translucent points. However, if either all of the points are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. - * - * @performance For best performance, prefer a few collections, each with many points, to - * many collections with only a few points each. Organize collections so that points - * with the same update frequency are in the same collection, i.e., points that do not - * change should be in one collection; points that change every frame should be in another - * collection; and so on. - * - * - * @example - * // Create a pointPrimitive collection with two points - * var points = scene.primitives.add(new Cesium.PointPrimitiveCollection()); - * points.add({ - * position : new Cesium.Cartesian3(1.0, 2.0, 3.0), - * color : Cesium.Color.YELLOW - * }); - * points.add({ - * position : new Cesium.Cartesian3(4.0, 5.0, 6.0), - * color : Cesium.Color.CYAN - * }); - * - * @see PointPrimitiveCollection#add - * @see PointPrimitiveCollection#remove - * @see PointPrimitive + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - function PointPrimitiveCollection(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._sp = undefined; - this._spTranslucent = undefined; - this._spPick = undefined; - this._rsOpaque = undefined; - this._rsTranslucent = undefined; - this._vaf = undefined; - - this._pointPrimitives = []; - this._pointPrimitivesToUpdate = []; - this._pointPrimitivesToUpdateIndex = 0; - this._pointPrimitivesRemoved = false; - this._createVertexArray = false; - - this._shaderScaleByDistance = false; - this._compiledShaderScaleByDistance = false; - this._compiledShaderScaleByDistancePick = false; - - this._shaderTranslucencyByDistance = false; - this._compiledShaderTranslucencyByDistance = false; - this._compiledShaderTranslucencyByDistancePick = false; - - this._shaderDistanceDisplayCondition = false; - this._compiledShaderDistanceDisplayCondition = false; - this._compiledShaderDistanceDisplayConditionPick = false; - - this._shaderDisableDepthDistance = false; - this._compiledShaderDisableDepthDistance = false; - this._compiledShaderDisableDepthDistancePick = false; - - this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); - - this._maxPixelSize = 1.0; - - this._baseVolume = new BoundingSphere(); - this._baseVolumeWC = new BoundingSphere(); - this._baseVolume2D = new BoundingSphere(); - this._boundingVolume = new BoundingSphere(); - this._boundingVolumeDirty = false; + function EllipsoidGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._scene = scene; + this._entity = entity; + this._entitySubscription = entity.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'ellipsoid', entity.ellipsoid, undefined); + } - this._colorCommands = []; - this._pickCommands = []; + defineProperties(EllipsoidGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof EllipsoidGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof EllipsoidGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); + defineProperties(EllipsoidGeometryUpdater.prototype, { /** - * The 4x4 transformation matrix that transforms each point in this collection from model to world coordinates. - * When this is the identity matrix, the pointPrimitives are drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. + * Gets the entity associated with this geometry. + * @memberof EllipsoidGeometryUpdater.prototype * - * @type {Matrix4} - * @default {@link Matrix4.IDENTITY} + * @type {Entity} + * @readonly + */ + entity : { + get : function() { + return this._entity; + } + }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof EllipsoidGeometryUpdater.prototype * + * @type {Boolean} + * @readonly + */ + fillEnabled : { + get : function() { + return this._fillEnabled; + } + }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof EllipsoidGeometryUpdater.prototype * - * @example - * var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); - * pointPrimitives.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - * pointPrimitives.add({ - * color : Cesium.Color.ORANGE, - * position : new Cesium.Cartesian3(0.0, 0.0, 0.0) // center - * }); - * pointPrimitives.add({ - * color : Cesium.Color.YELLOW, - * position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0) // east - * }); - * pointPrimitives.add({ - * color : Cesium.Color.GREEN, - * position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0) // north - * }); - * pointPrimitives.add({ - * color : Cesium.Color.CYAN, - * position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0) // up - * }); + * @type {Boolean} + * @readonly + */ + hasConstantFill : { + get : function() { + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); + } + }, + /** + * Gets the material property used to fill the geometry. + * @memberof EllipsoidGeometryUpdater.prototype * - * @see Transforms.eastNorthUpToFixedFrame + * @type {MaterialProperty} + * @readonly */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); - + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the primitive. - * </p> + * Gets a value indicating if the geometry has an outline component. + * @memberof EllipsoidGeometryUpdater.prototype * * @type {Boolean} + * @readonly + */ + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, + /** + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof EllipsoidGeometryUpdater.prototype * - * @default false + * @type {Boolean} + * @readonly */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, /** - * The point blending option. The default is used for rendering both opaque and translucent points. - * However, if either all of the points are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve - * performance by up to 2x. - * @type {BlendOption} - * @default BlendOption.OPAQUE_AND_TRANSLUCENT + * Gets the {@link Color} property for the geometry outline. + * @memberof EllipsoidGeometryUpdater.prototype + * + * @type {Property} + * @readonly */ - this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); - this._blendOption = undefined; - - this._mode = SceneMode.SCENE3D; - this._maxTotalPointSize = 1; - - // The buffer usage for each attribute is determined based on the usage of the attribute over time. - this._buffersUsage = [ - BufferUsage.STATIC_DRAW, // SHOW_INDEX - BufferUsage.STATIC_DRAW, // POSITION_INDEX - BufferUsage.STATIC_DRAW, // COLOR_INDEX - BufferUsage.STATIC_DRAW, // OUTLINE_COLOR_INDEX - BufferUsage.STATIC_DRAW, // OUTLINE_WIDTH_INDEX - BufferUsage.STATIC_DRAW, // PIXEL_SIZE_INDEX - BufferUsage.STATIC_DRAW, // SCALE_BY_DISTANCE_INDEX - BufferUsage.STATIC_DRAW, // TRANSLUCENCY_BY_DISTANCE_INDEX - BufferUsage.STATIC_DRAW // DISTANCE_DISPLAY_CONDITION_INDEX - ]; - - var that = this; - this._uniforms = { - u_maxTotalPointSize : function() { - return that._maxTotalPointSize; + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; } - }; - } - - defineProperties(PointPrimitiveCollection.prototype, { + }, /** - * Returns the number of points in this collection. This is commonly used with - * {@link PointPrimitiveCollection#get} to iterate over all the points - * in the collection. - * @memberof PointPrimitiveCollection.prototype + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof EllipsoidGeometryUpdater.prototype + * * @type {Number} + * @readonly */ - length : { + outlineWidth : { get : function() { - removePointPrimitives(this); - return this._pointPrimitives.length; + return this._outlineWidth; } - } - }); - - function destroyPointPrimitives(pointPrimitives) { - var length = pointPrimitives.length; - for (var i = 0; i < length; ++i) { - if (pointPrimitives[i]) { - pointPrimitives[i]._destroy(); + }, + /** + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof EllipsoidGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof EllipsoidGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayConditionProperty; + } + }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof EllipsoidGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isDynamic : { + get : function() { + return this._dynamic; + } + }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof EllipsoidGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isClosed : { + value : true + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof EllipsoidGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { + get : function() { + return this._geometryChanged; } } - } + }); /** - * Creates and adds a point with the specified initial properties to the collection. - * The added point is returned so it can be modified or removed from the collection later. - * - * @param {Object}[pointPrimitive] A template describing the point's properties as shown in Example 1. - * @returns {PointPrimitive} The point that was added to the collection. - * - * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer - * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For - * best performance, add as many pointPrimitives as possible before calling <code>update</code>. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Example 1: Add a point, specifying all the default values. - * var p = pointPrimitives.add({ - * show : true, - * position : Cesium.Cartesian3.ZERO, - * pixelSize : 10.0, - * color : Cesium.Color.WHITE, - * outlineColor : Cesium.Color.TRANSPARENT, - * outlineWidth : 0.0, - * id : undefined - * }); - * - * @example - * // Example 2: Specify only the point's cartographic position. - * var p = pointPrimitives.add({ - * position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height) - * }); + * Checks if the geometry is outlined at the provided time. * - * @see PointPrimitiveCollection#remove - * @see PointPrimitiveCollection#removeAll + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. */ - PointPrimitiveCollection.prototype.add = function(pointPrimitive) { - var p = new PointPrimitive(pointPrimitive, this); - p._index = this._pointPrimitives.length; - - this._pointPrimitives.push(p); - this._createVertexArray = true; - - return p; + EllipsoidGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); }; /** - * Removes a point from the collection. - * - * @param {PointPrimitive} pointPrimitive The point to remove. - * @returns {Boolean} <code>true</code> if the point was removed; <code>false</code> if the point was not found in the collection. - * - * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer - * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For - * best performance, remove as many points as possible before calling <code>update</code>. - * If you intend to temporarily hide a point, it is usually more efficient to call - * {@link PointPrimitive#show} instead of removing and re-adding the point. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * var p = pointPrimitives.add(...); - * pointPrimitives.remove(p); // Returns true + * Checks if the geometry is filled at the provided time. * - * @see PointPrimitiveCollection#add - * @see PointPrimitiveCollection#removeAll - * @see PointPrimitive#show + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. */ - PointPrimitiveCollection.prototype.remove = function(pointPrimitive) { - if (this.contains(pointPrimitive)) { - this._pointPrimitives[pointPrimitive._index] = null; // Removed later - this._pointPrimitivesRemoved = true; - this._createVertexArray = true; - pointPrimitive._destroy(); - return true; - } - - return false; + EllipsoidGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); }; /** - * Removes all points from the collection. - * - * @performance <code>O(n)</code>. It is more efficient to remove all the points - * from a collection and then add new ones than to create a new collection entirely. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * + * Creates the geometry instance which represents the fill of the geometry. * - * @example - * pointPrimitives.add(...); - * pointPrimitives.add(...); - * pointPrimitives.removeAll(); + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. * - * @see PointPrimitiveCollection#add - * @see PointPrimitiveCollection#remove + * @exception {DeveloperError} This instance does not represent a filled geometry. */ - PointPrimitiveCollection.prototype.removeAll = function() { - destroyPointPrimitives(this._pointPrimitives); - this._pointPrimitives = []; - this._pointPrimitivesToUpdate = []; - this._pointPrimitivesToUpdateIndex = 0; - this._pointPrimitivesRemoved = false; + EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - this._createVertexArray = true; - }; + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - function removePointPrimitives(pointPrimitiveCollection) { - if (pointPrimitiveCollection._pointPrimitivesRemoved) { - pointPrimitiveCollection._pointPrimitivesRemoved = false; + var attributes; - var newPointPrimitives = []; - var pointPrimitives = pointPrimitiveCollection._pointPrimitives; - var length = pointPrimitives.length; - for (var i = 0, j = 0; i < length; ++i) { - var pointPrimitive = pointPrimitives[i]; - if (pointPrimitive) { - pointPrimitive._index = j++; - newPointPrimitives.push(pointPrimitive); - } + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + } - pointPrimitiveCollection._pointPrimitives = newPointPrimitives; + return new GeometryInstance({ + id : entity, + geometry : new EllipsoidGeometry(this._options), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), + attributes : attributes + }); + }; + + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - } - PointPrimitiveCollection.prototype._updatePointPrimitive = function(pointPrimitive, propertyChanged) { - if (!pointPrimitive._dirty) { - this._pointPrimitivesToUpdate[this._pointPrimitivesToUpdateIndex++] = pointPrimitive; + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - ++this._propertiesChanged[propertyChanged]; + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + + return new GeometryInstance({ + id : entity, + geometry : new EllipsoidOutlineGeometry(this._options), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); }; /** - * Check whether this collection contains a given point. - * - * @param {PointPrimitive} [pointPrimitive] The point to check for. - * @returns {Boolean} true if this collection contains the point, false otherwise. + * Returns true if this object was destroyed; otherwise, false. * - * @see PointPrimitiveCollection#get + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - PointPrimitiveCollection.prototype.contains = function(pointPrimitive) { - return defined(pointPrimitive) && pointPrimitive._pointPrimitiveCollection === this; + EllipsoidGeometryUpdater.prototype.isDestroyed = function() { + return false; }; /** - * Returns the point in the collection at the specified index. Indices are zero-based - * and increase as points are added. Removing a point shifts all points after - * it to the left, changing their indices. This function is commonly used with - * {@link PointPrimitiveCollection#length} to iterate over all the points - * in the collection. - * - * @param {Number} index The zero-based index of the point. - * @returns {PointPrimitive} The point at the specified index. - * - * @performance Expected constant time. If points were removed from the collection and - * {@link PointPrimitiveCollection#update} was not called, an implicit <code>O(n)</code> - * operation is performed. + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Toggle the show property of every point in the collection - * var len = pointPrimitives.length; - * for (var i = 0; i < len; ++i) { - * var p = pointPrimitives.get(i); - * p.show = !p.show; - * } - * - * @see PointPrimitiveCollection#length */ - PointPrimitiveCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - removePointPrimitives(this); - return this._pointPrimitives[index]; + EllipsoidGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); }; - PointPrimitiveCollection.prototype.computeNewBuffersUsage = function() { - var buffersUsage = this._buffersUsage; - var usageChanged = false; - - var properties = this._propertiesChanged; - for ( var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { - var newUsage = (properties[k] === 0) ? BufferUsage.STATIC_DRAW : BufferUsage.STREAM_DRAW; - usageChanged = usageChanged || (buffersUsage[k] !== newUsage); - buffersUsage[k] = newUsage; + EllipsoidGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'ellipsoid')) { + return; } - return usageChanged; - }; + var ellipsoid = entity.ellipsoid; - function createVAF(context, numberOfPointPrimitives, buffersUsage) { - return new VertexArrayFacade(context, [{ - index : attributeLocations.positionHighAndSize, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[POSITION_INDEX] - }, { - index : attributeLocations.positionLowAndShow, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[POSITION_INDEX] - }, { - index : attributeLocations.compressedAttribute0, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[COLOR_INDEX] - }, { - index : attributeLocations.compressedAttribute1, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[TRANSLUCENCY_BY_DISTANCE_INDEX] - }, { - index : attributeLocations.scaleByDistance, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[SCALE_BY_DISTANCE_INDEX] - }, { - index : attributeLocations.distanceDisplayConditionAndDisableDepth, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] - }], numberOfPointPrimitives); // 1 vertex per pointPrimitive - } + if (!defined(ellipsoid)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - /////////////////////////////////////////////////////////////////////////// + var fillProperty = ellipsoid.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; - // PERFORMANCE_IDEA: Save memory if a property is the same for all pointPrimitives, use a latched attribute state, - // instead of storing it in a vertex buffer. + var outlineProperty = ellipsoid.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } - var writePositionScratch = new EncodedCartesian3(); + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - function writePositionSizeAndOutline(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { - var i = pointPrimitive._index; - var position = pointPrimitive._getActualPosition(); + var position = entity.position; + var radii = ellipsoid.radii; - if (pointPrimitiveCollection._mode === SceneMode.SCENE3D) { - BoundingSphere.expand(pointPrimitiveCollection._baseVolume, position, pointPrimitiveCollection._baseVolume); - pointPrimitiveCollection._boundingVolumeDirty = true; + var show = ellipsoid.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(position) || !defined(radii))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; } - EncodedCartesian3.fromCartesian(position, writePositionScratch); - var pixelSize = pointPrimitive.pixelSize; - var outlineWidth = pointPrimitive.outlineWidth; + var material = defaultValue(ellipsoid.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(ellipsoid.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(ellipsoid.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(ellipsoid.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(ellipsoid.distanceDisplayCondition, defaultDistanceDisplayCondition); - pointPrimitiveCollection._maxPixelSize = Math.max(pointPrimitiveCollection._maxPixelSize, pixelSize + outlineWidth); + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; - var positionHighWriter = vafWriters[attributeLocations.positionHighAndSize]; - var high = writePositionScratch.high; - positionHighWriter(i, high.x, high.y, high.z, pixelSize); + var stackPartitions = ellipsoid.stackPartitions; + var slicePartitions = ellipsoid.slicePartitions; + var outlineWidth = ellipsoid.outlineWidth; + var subdivisions = ellipsoid.subdivisions; - var positionLowWriter = vafWriters[attributeLocations.positionLowAndOutline]; - var low = writePositionScratch.low; - positionLowWriter(i, low.x, low.y, low.z, outlineWidth); + if (!position.isConstant || // + !Property.isConstant(entity.orientation) || // + !radii.isConstant || // + !Property.isConstant(stackPartitions) || // + !Property.isConstant(slicePartitions) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(subdivisions)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.radii = radii.getValue(Iso8601.MINIMUM_VALUE, options.radii); + options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.subdivisions = defined(subdivisions) ? subdivisions.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } + }; + + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } + + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, this); + }; + + /** + * @private + */ + function DynamicGeometryUpdater(primitives, geometryUpdater) { + this._entity = geometryUpdater._entity; + this._scene = geometryUpdater._scene; + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + this._modelMatrix = new Matrix4(); + this._material = undefined; + this._attributes = undefined; + this._outlineAttributes = undefined; + this._lastSceneMode = undefined; + this._lastShow = undefined; + this._lastOutlineShow = undefined; + this._lastOutlineWidth = undefined; + this._lastOutlineColor = undefined; } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var entity = this._entity; + var ellipsoid = entity.ellipsoid; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(ellipsoid.show, time, true)) { + if (defined(this._primitive)) { + this._primitive.show = false; + } - var LEFT_SHIFT16 = 65536.0; // 2^16 - var LEFT_SHIFT8 = 256.0; // 2^8 + if (defined(this._outlinePrimitive)) { + this._outlinePrimitive.show = false; + } + return; + } - function writeCompressedAttrib0(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { - var i = pointPrimitive._index; + var radii = Property.getValueOrUndefined(ellipsoid.radii, time, radiiScratch); + var modelMatrix = entity.computeModelMatrix(time, this._modelMatrix); + if (!defined(modelMatrix) || !defined(radii)) { + if (defined(this._primitive)) { + this._primitive.show = false; + } - var color = pointPrimitive.color; - var pickColor = pointPrimitive.getPickId(context).color; - var outlineColor = pointPrimitive.outlineColor; + if (defined(this._outlinePrimitive)) { + this._outlinePrimitive.show = false; + } + return; + } - var red = Color.floatToByte(color.red); - var green = Color.floatToByte(color.green); - var blue = Color.floatToByte(color.blue); - var compressed0 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + //Compute attributes and material. + var appearance; + var showFill = Property.getValueOrDefault(ellipsoid.fill, time, true); + var showOutline = Property.getValueOrDefault(ellipsoid.outline, time, false); + var outlineColor = Property.getValueOrClonedDefault(ellipsoid.outlineColor, time, Color.BLACK, scratchColor); + var material = MaterialProperty.getValue(time, defaultValue(ellipsoid.material, defaultMaterial), this._material); + this._material = material; - red = Color.floatToByte(outlineColor.red); - green = Color.floatToByte(outlineColor.green); - blue = Color.floatToByte(outlineColor.blue); - var compressed1 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + // Check properties that could trigger a primitive rebuild. + var stackPartitions = Property.getValueOrUndefined(ellipsoid.stackPartitions, time); + var slicePartitions = Property.getValueOrUndefined(ellipsoid.slicePartitions, time); + var subdivisions = Property.getValueOrUndefined(ellipsoid.subdivisions, time); + var outlineWidth = Property.getValueOrDefault(ellipsoid.outlineWidth, time, 1.0); - red = Color.floatToByte(pickColor.red); - green = Color.floatToByte(pickColor.green); - blue = Color.floatToByte(pickColor.blue); - var compressed2 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue; + //In 3D we use a fast path by modifying Primitive.modelMatrix instead of regenerating the primitive every frame. + var sceneMode = this._scene.mode; + var in3D = sceneMode === SceneMode.SCENE3D; - var compressed3 = - Color.floatToByte(color.alpha) * LEFT_SHIFT16 + - Color.floatToByte(outlineColor.alpha) * LEFT_SHIFT8 + - Color.floatToByte(pickColor.alpha); + var options = this._options; - var writer = vafWriters[attributeLocations.compressedAttribute0]; - writer(i, compressed0, compressed1, compressed2, compressed3); - } + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); - function writeCompressedAttrib1(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { - var i = pointPrimitive._index; + var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - var near = 0.0; - var nearValue = 1.0; - var far = 1.0; - var farValue = 1.0; + //We only rebuild the primitive if something other than the radii has changed + //For the radii, we use unit sphere and then deform it with a scale matrix. + var rebuildPrimitives = !in3D || this._lastSceneMode !== sceneMode || !defined(this._primitive) || // + options.stackPartitions !== stackPartitions || options.slicePartitions !== slicePartitions || // + options.subdivisions !== subdivisions || this._lastOutlineWidth !== outlineWidth; - var translucency = pointPrimitive.translucencyByDistance; - if (defined(translucency)) { - near = translucency.near; - nearValue = translucency.nearValue; - far = translucency.far; - farValue = translucency.farValue; + if (rebuildPrimitives) { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._lastSceneMode = sceneMode; + this._lastOutlineWidth = outlineWidth; - if (nearValue !== 1.0 || farValue !== 1.0) { - // translucency by distance calculation in shader need not be enabled - // until a pointPrimitive with near and far !== 1.0 is found - pointPrimitiveCollection._shaderTranslucencyByDistance = true; - } - } + options.stackPartitions = stackPartitions; + options.slicePartitions = slicePartitions; + options.subdivisions = subdivisions; + options.radii = in3D ? unitSphere : radii; - var show = pointPrimitive.show && pointPrimitive.clusterShow; + appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; - // If the color alphas are zero, do not show this pointPrimitive. This lets us avoid providing - // color during the pick pass and also eliminates a discard in the fragment shader. - if (pointPrimitive.color.alpha === 0.0 && pointPrimitive.outlineColor.alpha === 0.0) { - show = false; - } + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new EllipsoidGeometry(options), + modelMatrix : !in3D ? modelMatrix : undefined, + attributes : { + show : new ShowGeometryInstanceAttribute(showFill), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); - nearValue = CesiumMath.clamp(nearValue, 0.0, 1.0); - nearValue = nearValue === 1.0 ? 255.0 : (nearValue * 255.0) | 0; - var compressed0 = (show ? 1.0 : 0.0) * LEFT_SHIFT8 + nearValue; + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - farValue = CesiumMath.clamp(farValue, 0.0, 1.0); - farValue = farValue === 1.0 ? 255.0 : (farValue * 255.0) | 0; - var compressed1 = farValue; + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new EllipsoidOutlineGeometry(options), + modelMatrix : !in3D ? modelMatrix : undefined, + attributes : { + show : new ShowGeometryInstanceAttribute(showOutline), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : outlineColor.alpha !== 1.0, + renderState : { + lineWidth : this._geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); - var writer = vafWriters[attributeLocations.compressedAttribute1]; - writer(i, compressed0, compressed1, near, far); - } + this._lastShow = showFill; + this._lastOutlineShow = showOutline; + this._lastOutlineColor = Color.clone(outlineColor, this._lastOutlineColor); + this._lastDistanceDisplayCondition = distanceDisplayCondition; + } else if (this._primitive.ready) { + //Update attributes only. + var primitive = this._primitive; + var outlinePrimitive = this._outlinePrimitive; - function writeScaleByDistance(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { - var i = pointPrimitive._index; - var writer = vafWriters[attributeLocations.scaleByDistance]; - var near = 0.0; - var nearValue = 1.0; - var far = 1.0; - var farValue = 1.0; + primitive.show = true; + outlinePrimitive.show = true; - var scale = pointPrimitive.scaleByDistance; - if (defined(scale)) { - near = scale.near; - nearValue = scale.nearValue; - far = scale.far; - farValue = scale.farValue; + appearance = primitive.appearance; + appearance.material = material; - if (nearValue !== 1.0 || farValue !== 1.0) { - // scale by distance calculation in shader need not be enabled - // until a pointPrimitive with near and far !== 1.0 is found - pointPrimitiveCollection._shaderScaleByDistance = true; + var attributes = this._attributes; + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(entity); + this._attributes = attributes; + } + if (showFill !== this._lastShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(showFill, attributes.show); + this._lastShow = showFill; } - } - writer(i, near, nearValue, far, farValue); - } + var outlineAttributes = this._outlineAttributes; - function writeDistanceDisplayConditionAndDepthDisable(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { - var i = pointPrimitive._index; - var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth]; - var near = 0.0; - var far = Number.MAX_VALUE; + if (!defined(outlineAttributes)) { + outlineAttributes = outlinePrimitive.getGeometryInstanceAttributes(entity); + this._outlineAttributes = outlineAttributes; + } - var distanceDisplayCondition = pointPrimitive.distanceDisplayCondition; - if (defined(distanceDisplayCondition)) { - near = distanceDisplayCondition.near; - far = distanceDisplayCondition.far; + if (showOutline !== this._lastOutlineShow) { + outlineAttributes.show = ShowGeometryInstanceAttribute.toValue(showOutline, outlineAttributes.show); + this._lastOutlineShow = showOutline; + } - near *= near; - far *= far; + if (!Color.equals(outlineColor, this._lastOutlineColor)) { + outlineAttributes.color = ColorGeometryInstanceAttribute.toValue(outlineColor, outlineAttributes.color); + Color.clone(outlineColor, this._lastOutlineColor); + } - pointPrimitiveCollection._shaderDistanceDisplayCondition = true; + if (!DistanceDisplayCondition.equals(distanceDisplayCondition, this._lastDistanceDisplayCondition)) { + attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); + outlineAttributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, outlineAttributes.distanceDisplayCondition); + DistanceDisplayCondition.clone(distanceDisplayCondition, this._lastDistanceDisplayCondition); + } } - var disableDepthTestDistance = pointPrimitive.disableDepthTestDistance; - disableDepthTestDistance *= disableDepthTestDistance; - if (disableDepthTestDistance > 0.0) { - pointPrimitiveCollection._shaderDisableDepthDistance = true; - if (disableDepthTestDistance === Number.POSITIVE_INFINITY) { - disableDepthTestDistance = -1.0; - } + if (in3D) { + //Since we are scaling a unit sphere, we can't let any of the values go to zero. + //Instead we clamp them to a small value. To the naked eye, this produces the same results + //that you get passing EllipsoidGeometry a radii with a zero component. + radii.x = Math.max(radii.x, 0.001); + radii.y = Math.max(radii.y, 0.001); + radii.z = Math.max(radii.z, 0.001); + + modelMatrix = Matrix4.multiplyByScale(modelMatrix, radii, modelMatrix); + this._primitive.modelMatrix = modelMatrix; + this._outlinePrimitive.modelMatrix = modelMatrix; } + }; - writer(i, near, far, disableDepthTestDistance); - } + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; - function writePointPrimitive(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { - writePositionSizeAndOutline(pointPrimitiveCollection, context, vafWriters, pointPrimitive); - writeCompressedAttrib0(pointPrimitiveCollection, context, vafWriters, pointPrimitive); - writeCompressedAttrib1(pointPrimitiveCollection, context, vafWriters, pointPrimitive); - writeScaleByDistance(pointPrimitiveCollection, context, vafWriters, pointPrimitive); - writeDistanceDisplayConditionAndDepthDisable(pointPrimitiveCollection, context, vafWriters, pointPrimitive); - } + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - function recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, length, frameState, modelMatrix, recomputeBoundingVolume) { - var boundingVolume; - if (frameState.mode === SceneMode.SCENE3D) { - boundingVolume = pointPrimitiveCollection._baseVolume; - pointPrimitiveCollection._boundingVolumeDirty = true; - } else { - boundingVolume = pointPrimitiveCollection._baseVolume2D; - } + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; - var positions = []; - for ( var i = 0; i < length; ++i) { - var pointPrimitive = pointPrimitives[i]; - var position = pointPrimitive.position; - var actualPosition = PointPrimitive._computeActualPosition(position, frameState, modelMatrix); - if (defined(actualPosition)) { - pointPrimitive._setActualPosition(actualPosition); + return EllipsoidGeometryUpdater; +}); - if (recomputeBoundingVolume) { - positions.push(actualPosition); - } else { - BoundingSphere.expand(boundingVolume, actualPosition, boundingVolume); - } - } - } +define('DataSources/StaticGeometryColorBatch',[ + '../Core/AssociativeArray', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defined', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/Primitive', + './BoundingSphereState', + './ColorMaterialProperty', + './MaterialProperty', + './Property' + ], function( + AssociativeArray, + Color, + ColorGeometryInstanceAttribute, + defined, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + Primitive, + BoundingSphereState, + ColorMaterialProperty, + MaterialProperty, + Property) { + 'use strict'; - if (recomputeBoundingVolume) { - BoundingSphere.fromPoints(positions, boundingVolume); + var colorScratch = new Color(); + var distanceDisplayConditionScratch = new DistanceDisplayCondition(); + + function Batch(primitives, translucent, appearanceType, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) { + this.translucent = translucent; + this.appearanceType = appearanceType; + this.depthFailAppearanceType = depthFailAppearanceType; + this.depthFailMaterialProperty = depthFailMaterialProperty; + this.depthFailMaterial = undefined; + this.closed = closed; + this.shadows = shadows; + this.primitives = primitives; + this.createPrimitive = false; + this.waitingOnCreate = false; + this.primitive = undefined; + this.oldPrimitive = undefined; + this.geometry = new AssociativeArray(); + this.updaters = new AssociativeArray(); + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); + this.subscriptions = new AssociativeArray(); + this.showsUpdated = new AssociativeArray(); + this.itemsToRemove = []; + this.invalidated = false; + + var removeMaterialSubscription; + if (defined(depthFailMaterialProperty)) { + removeMaterialSubscription = depthFailMaterialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); } + this.removeMaterialSubscription = removeMaterialSubscription; } - function updateMode(pointPrimitiveCollection, frameState) { - var mode = frameState.mode; - - var pointPrimitives = pointPrimitiveCollection._pointPrimitives; - var pointPrimitivesToUpdate = pointPrimitiveCollection._pointPrimitivesToUpdate; - var modelMatrix = pointPrimitiveCollection._modelMatrix; + Batch.prototype.onMaterialChanged = function() { + this.invalidated = true; + }; - if (pointPrimitiveCollection._createVertexArray || - pointPrimitiveCollection._mode !== mode || - mode !== SceneMode.SCENE3D && - !Matrix4.equals(modelMatrix, pointPrimitiveCollection.modelMatrix)) { + Batch.prototype.isMaterial = function(updater) { + var material = this.depthFailMaterialProperty; + var updaterMaterial = updater.depthFailMaterialProperty; + if (updaterMaterial === material) { + return true; + } + if (defined(material)) { + return material.equals(updaterMaterial); + } + return false; + }; - pointPrimitiveCollection._mode = mode; - Matrix4.clone(pointPrimitiveCollection.modelMatrix, modelMatrix); - pointPrimitiveCollection._createVertexArray = true; + Batch.prototype.add = function(updater, instance) { + var id = updater.entity.id; + this.createPrimitive = true; + this.geometry.set(id, instance); + this.updaters.set(id, updater); + if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { + this.updatersWithAttributes.set(id, updater); + } else { + var that = this; + this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { + if (propertyName === 'isShowing') { + that.showsUpdated.set(entity.id, updater); + } + })); + } + }; - if (mode === SceneMode.SCENE3D || mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, pointPrimitives.length, frameState, modelMatrix, true); + Batch.prototype.remove = function(updater) { + var id = updater.entity.id; + this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; + if (this.updaters.remove(id)) { + this.updatersWithAttributes.remove(id); + var unsubscribe = this.subscriptions.get(id); + if (defined(unsubscribe)) { + unsubscribe(); + this.subscriptions.remove(id); } - } else if (mode === SceneMode.MORPHING) { - recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, pointPrimitives.length, frameState, modelMatrix, true); - } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - recomputeActualPositions(pointPrimitiveCollection, pointPrimitivesToUpdate, pointPrimitiveCollection._pointPrimitivesToUpdateIndex, frameState, modelMatrix, false); } - } - - function updateBoundingVolume(collection, frameState, boundingVolume) { - var pixelSize = frameState.camera.getPixelSize(boundingVolume, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); - var size = pixelSize * collection._maxPixelSize; - boundingVolume.radius += size; - } - - var scratchWriterArray = []; - - /** - * @private - */ - PointPrimitiveCollection.prototype.update = function(frameState) { - removePointPrimitives(this); + }; - this._maxTotalPointSize = ContextLimits.maximumAliasedPointSize; + Batch.prototype.update = function(time) { + var isUpdated = true; + var removedCount = 0; + var primitive = this.primitive; + var primitives = this.primitives; + var attributes; + var i; - updateMode(this, frameState); + if (this.createPrimitive) { + var geometries = this.geometry.values; + var geometriesLength = geometries.length; + if (geometriesLength > 0) { + if (defined(primitive)) { + if (!defined(this.oldPrimitive)) { + this.oldPrimitive = primitive; + } else { + primitives.remove(primitive); + } + } - var pointPrimitives = this._pointPrimitives; - var pointPrimitivesLength = pointPrimitives.length; - var pointPrimitivesToUpdate = this._pointPrimitivesToUpdate; - var pointPrimitivesToUpdateLength = this._pointPrimitivesToUpdateIndex; + for (i = 0; i < geometriesLength; i++) { + var geometryItem = geometries[i]; + var originalAttributes = geometryItem.attributes; + attributes = this.attributes.get(geometryItem.id.id); - var properties = this._propertiesChanged; + if (defined(attributes)) { + if (defined(originalAttributes.show)) { + originalAttributes.show.value = attributes.show; + } + if (defined(originalAttributes.color)) { + originalAttributes.color.value = attributes.color; + } + if (defined(originalAttributes.depthFailColor)) { + originalAttributes.depthFailColor.value = attributes.depthFailColor; + } + } + } - var createVertexArray = this._createVertexArray; + var depthFailAppearance; + if (defined(this.depthFailAppearanceType)) { + if (defined(this.depthFailMaterialProperty)) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + } + depthFailAppearance = new this.depthFailAppearanceType({ + material : this.depthFailMaterial, + translucent : this.translucent, + closed : this.closed + }); + } - var vafWriters; - var context = frameState.context; - var pass = frameState.passes; - var picking = pass.pick; + primitive = new Primitive({ + asynchronous : true, + geometryInstances : geometries, + appearance : new this.appearanceType({ + translucent : this.translucent, + closed : this.closed + }), + depthFailAppearance : depthFailAppearance, + shadows : this.shadows + }); + primitives.add(primitive); + isUpdated = false; + } else { + if (defined(primitive)) { + primitives.remove(primitive); + primitive = undefined; + } + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; + } + } - // PERFORMANCE_IDEA: Round robin multiple buffers. - if (createVertexArray || (!picking && this.computeNewBuffersUsage())) { - this._createVertexArray = false; + this.attributes.removeAll(); + this.primitive = primitive; + this.createPrimitive = false; + this.waitingOnCreate = true; + } else if (defined(primitive) && primitive.ready) { + if (defined(this.oldPrimitive)) { + primitives.remove(this.oldPrimitive); + this.oldPrimitive = undefined; + } - for (var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { - properties[k] = 0; + if (defined(this.depthFailAppearanceType) && !(this.depthFailMaterialProperty instanceof ColorMaterialProperty)) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + this.primitive.depthFailAppearance.material = this.depthFailMaterial; } - this._vaf = this._vaf && this._vaf.destroy(); + var updatersWithAttributes = this.updatersWithAttributes.values; + var length = updatersWithAttributes.length; + var waitingOnCreate = this.waitingOnCreate; + for (i = 0; i < length; i++) { + var updater = updatersWithAttributes[i]; + var instance = this.geometry.get(updater.entity.id); - if (pointPrimitivesLength > 0) { - // PERFORMANCE_IDEA: Instead of creating a new one, resize like std::vector. - this._vaf = createVAF(context, pointPrimitivesLength, this._buffersUsage); - vafWriters = this._vaf.writers; + attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } - // Rewrite entire buffer if pointPrimitives were added or removed. - for (var i = 0; i < pointPrimitivesLength; ++i) { - var pointPrimitive = this._pointPrimitives[i]; - pointPrimitive._dirty = false; // In case it needed an update. - writePointPrimitive(this, context, vafWriters, pointPrimitive); + if (!updater.fillMaterialProperty.isConstant || waitingOnCreate) { + var colorProperty = updater.fillMaterialProperty.color; + colorProperty.getValue(time, colorScratch); + if (!Color.equals(attributes._lastColor, colorScratch)) { + attributes._lastColor = Color.clone(colorScratch, attributes._lastColor); + attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; + } + } } - this._vaf.commit(); - } + if (defined(this.depthFailAppearanceType) && this.depthFailAppearanceType instanceof ColorMaterialProperty && (!updater.depthFailMaterialProperty.isConstant || waitingOnCreate)) { + var depthFailColorProperty = updater.depthFailMaterialProperty.color; + depthFailColorProperty.getValue(time, colorScratch); + if (!Color.equals(attributes._lastDepthFailColor, colorScratch)) { + attributes._lastDepthFailColor = Color.clone(colorScratch, attributes._lastDepthFailColor); + attributes.depthFailColor = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.depthFailColor); + } + } - this._pointPrimitivesToUpdateIndex = 0; - } else if (pointPrimitivesToUpdateLength > 0) { - // PointPrimitives were modified, but none were added or removed. - var writers = scratchWriterArray; - writers.length = 0; + var show = updater.entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } - if (properties[POSITION_INDEX] || properties[OUTLINE_WIDTH_INDEX] || properties[PIXEL_SIZE_INDEX]) { - writers.push(writePositionSizeAndOutline); + var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; + if (!Property.isConstant(distanceDisplayConditionProperty)) { + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); + if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { + attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); + attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); + } + } } - if (properties[COLOR_INDEX] || properties[OUTLINE_COLOR_INDEX]) { - writers.push(writeCompressedAttrib0); - } + this.updateShows(primitive); + this.waitingOnCreate = false; + } else if (defined(primitive) && !primitive.ready) { + isUpdated = false; + } + this.itemsToRemove.length = removedCount; + return isUpdated; + }; - if (properties[SHOW_INDEX] || properties[TRANSLUCENCY_BY_DISTANCE_INDEX]) { - writers.push(writeCompressedAttrib1); - } + Batch.prototype.updateShows = function(primitive) { + var showsUpdated = this.showsUpdated.values; + var length = showsUpdated.length; + for (var i = 0; i < length; i++) { + var updater = showsUpdated[i]; + var instance = this.geometry.get(updater.entity.id); - if (properties[SCALE_BY_DISTANCE_INDEX]) { - writers.push(writeScaleByDistance); + var attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); } - if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE_INDEX]) { - writers.push(writeDistanceDisplayConditionAndDepthDisable); + var show = updater.entity.isShowing; + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); } + } + this.showsUpdated.removeAll(); + }; - var numWriters = writers.length; - - vafWriters = this._vaf.writers; - - if ((pointPrimitivesToUpdateLength / pointPrimitivesLength) > 0.1) { - // If more than 10% of pointPrimitive change, rewrite the entire buffer. - - // PERFORMANCE_IDEA: I totally made up 10% :). - - for (var m = 0; m < pointPrimitivesToUpdateLength; ++m) { - var b = pointPrimitivesToUpdate[m]; - b._dirty = false; + Batch.prototype.contains = function(entity) { + return this.updaters.contains(entity.id); + }; - for ( var n = 0; n < numWriters; ++n) { - writers[n](this, context, vafWriters, b); - } - } - this._vaf.commit(); - } else { - for (var h = 0; h < pointPrimitivesToUpdateLength; ++h) { - var bb = pointPrimitivesToUpdate[h]; - bb._dirty = false; + Batch.prototype.getBoundingSphere = function(entity, result) { + var primitive = this.primitive; + if (!primitive.ready) { + return BoundingSphereState.PENDING; + } + var attributes = primitive.getGeometryInstanceAttributes(entity); + if (!defined(attributes) || !defined(attributes.boundingSphere) ||// + (defined(attributes.show) && attributes.show[0] === 0)) { + return BoundingSphereState.FAILED; + } + attributes.boundingSphere.clone(result); + return BoundingSphereState.DONE; + }; - for ( var o = 0; o < numWriters; ++o) { - writers[o](this, context, vafWriters, bb); - } - this._vaf.subCommit(bb._index, 1); - } - this._vaf.endSubCommits(); - } + Batch.prototype.removeAllPrimitives = function() { + var primitives = this.primitives; - this._pointPrimitivesToUpdateIndex = 0; + var primitive = this.primitive; + if (defined(primitive)) { + primitives.remove(primitive); + this.primitive = undefined; + this.geometry.removeAll(); + this.updaters.removeAll(); } - // If the number of total pointPrimitives ever shrinks considerably - // Truncate pointPrimitivesToUpdate so that we free memory that we're - // not going to be using. - if (pointPrimitivesToUpdateLength > pointPrimitivesLength * 1.5) { - pointPrimitivesToUpdate.length = pointPrimitivesLength; + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; } + }; - if (!defined(this._vaf) || !defined(this._vaf.va)) { - return; + Batch.prototype.destroy = function() { + var primitive = this.primitive; + var primitives = this.primitives; + if (defined(primitive)) { + primitives.remove(primitive); } - - if (this._boundingVolumeDirty) { - this._boundingVolumeDirty = false; - BoundingSphere.transform(this._baseVolume, this.modelMatrix, this._baseVolumeWC); + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); } - - var boundingVolume; - var modelMatrix = Matrix4.IDENTITY; - if (frameState.mode === SceneMode.SCENE3D) { - modelMatrix = this.modelMatrix; - boundingVolume = BoundingSphere.clone(this._baseVolumeWC, this._boundingVolume); - } else { - boundingVolume = BoundingSphere.clone(this._baseVolume2D, this._boundingVolume); + if(defined(this.removeMaterialSubscription)) { + this.removeMaterialSubscription(); } - updateBoundingVolume(this, frameState, boundingVolume); + }; - var blendOptionChanged = this._blendOption !== this.blendOption; - this._blendOption = this.blendOption; + /** + * @private + */ + function StaticGeometryColorBatch(primitives, appearanceType, depthFailAppearanceType, closed, shadows) { + this._solidItems = []; + this._translucentItems = []; + this._primitives = primitives; + this._appearanceType = appearanceType; + this._depthFailAppearanceType = depthFailAppearanceType; + this._closed = closed; + this._shadows = shadows; + } - if (blendOptionChanged) { - if (this._blendOption === BlendOption.OPAQUE || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { - this._rsOpaque = RenderState.fromCache({ - depthTest : { - enabled : true, - func : WebGLConstants.LEQUAL - }, - depthMask : true - }); - } else { - this._rsOpaque = undefined; - } + StaticGeometryColorBatch.prototype.add = function(time, updater) { + var items; + var translucent; + var instance = updater.createFillGeometryInstance(time); + if (instance.attributes.color.value[3] === 255) { + items = this._solidItems; + translucent = false; + } else { + items = this._translucentItems; + translucent = true; + } - if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { - this._rsTranslucent = RenderState.fromCache({ - depthTest : { - enabled : true, - func : WebGLConstants.LEQUAL - }, - depthMask : false, - blending : BlendingState.ALPHA_BLEND - }); - } else { - this._rsTranslucent = undefined; + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if (item.isMaterial(updater)) { + item.add(updater, instance); + return; } } + var batch = new Batch(this._primitives, translucent, this._appearanceType, this._depthFailAppearanceType, updater.depthFailMaterialProperty, this._closed, this._shadows); + batch.add(updater, instance); + items.push(batch); + }; - this._shaderDisableDepthDistance = this._shaderDisableDepthDistance || frameState.minimumDisableDepthTestDistance !== 0.0; - var vs; - var fs; - - if (blendOptionChanged || - (this._shaderScaleByDistance && !this._compiledShaderScaleByDistance) || - (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistance) || - (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayCondition) || - (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) { - - vs = new ShaderSource({ - sources : [PointPrimitiveCollectionVS] - }); - if (this._shaderScaleByDistance) { - vs.defines.push('EYE_DISTANCE_SCALING'); - } - if (this._shaderTranslucencyByDistance) { - vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); - } - if (this._shaderDistanceDisplayCondition) { - vs.defines.push('DISTANCE_DISPLAY_CONDITION'); - } - if (this._shaderDisableDepthDistance) { - vs.defines.push('DISABLE_DEPTH_DISTANCE'); + function removeItem(items, updater) { + var length = items.length; + for (var i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.remove(updater)) { + if (item.updaters.length === 0) { + items.splice(i, 1); + item.destroy(); + return true; + } } + } + return false; + } - if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { - fs = new ShaderSource({ - defines : ['OPAQUE'], - sources : [PointPrimitiveCollectionFS] - }); - this._sp = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - - fs = new ShaderSource({ - defines : ['TRANSLUCENT'], - sources : [PointPrimitiveCollectionFS] - }); - this._spTranslucent = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._spTranslucent, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } + StaticGeometryColorBatch.prototype.remove = function(updater) { + if (!removeItem(this._solidItems, updater)) { + removeItem(this._translucentItems, updater); + } + }; - if (this._blendOption === BlendOption.OPAQUE) { - fs = new ShaderSource({ - sources : [PointPrimitiveCollectionFS] - }); - this._sp = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); + function moveItems(batch, items, time) { + var itemsMoved = false; + var length = items.length; + for (var i = 0; i < length; ++i) { + var item = items[i]; + var itemsToRemove = item.itemsToRemove; + var itemsToMoveLength = itemsToRemove.length; + if (itemsToMoveLength > 0) { + for (i = 0; i < itemsToMoveLength; i++) { + var updater = itemsToRemove[i]; + item.remove(updater); + batch.add(time, updater); + itemsMoved = true; + } } + } + return itemsMoved; + } - if (this._blendOption === BlendOption.TRANSLUCENT) { - fs = new ShaderSource({ - sources : [PointPrimitiveCollectionFS] - }); - this._spTranslucent = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._spTranslucent, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); + function updateItems(batch, items, time, isUpdated) { + var length = items.length; + var i; + for (i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.invalidated) { + items.splice(i, 1); + var updaters = item.updaters.values; + var updatersLength = updaters.length; + for (var h = 0; h < updatersLength; h++) { + batch.add(time, updaters[h]); + } + item.destroy(); } - - this._compiledShaderScaleByDistance = this._shaderScaleByDistance; - this._compiledShaderTranslucencyByDistance = this._shaderTranslucencyByDistance; - this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition; - this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance; } - if (!defined(this._spPick) || - (this._shaderScaleByDistance && !this._compiledShaderScaleByDistancePick) || - (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistancePick) || - (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayConditionPick) || - (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistancePick)) { + length = items.length; + for (i = 0; i < length; ++i) { + isUpdated = items[i].update(time) && isUpdated; + } + return isUpdated; + } - vs = new ShaderSource({ - defines : ['RENDER_FOR_PICK'], - sources : [PointPrimitiveCollectionVS] - }); + StaticGeometryColorBatch.prototype.update = function(time) { + //Perform initial update + var isUpdated = updateItems(this, this._solidItems, time, true); + isUpdated = updateItems(this, this._translucentItems, time, isUpdated) && isUpdated; - if (this._shaderScaleByDistance) { - vs.defines.push('EYE_DISTANCE_SCALING'); - } - if (this._shaderTranslucencyByDistance) { - vs.defines.push('EYE_DISTANCE_TRANSLUCENCY'); - } - if (this._shaderDistanceDisplayCondition) { - vs.defines.push('DISTANCE_DISPLAY_CONDITION'); - } - if (this._shaderDisableDepthDistance) { - vs.defines.push('DISABLE_DEPTH_DISTANCE'); - } + //If any items swapped between solid/translucent, we need to + //move them between batches + var solidsMoved = moveItems(this, this._solidItems, time); + var translucentsMoved = moveItems(this, this._translucentItems, time); - fs = new ShaderSource({ - defines : ['RENDER_FOR_PICK'], - sources : [PointPrimitiveCollectionFS] - }); + //If we moved anything around, we need to re-build the primitive + if (solidsMoved || translucentsMoved) { + isUpdated = updateItems(this, this._solidItems, time, isUpdated) && isUpdated; + isUpdated = updateItems(this, this._translucentItems, time, isUpdated)&& isUpdated; + } - this._spPick = ShaderProgram.replaceCache({ - context : context, - shaderProgram : this._spPick, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); + return isUpdated; + }; - this._compiledShaderScaleByDistancePick = this._shaderScaleByDistance; - this._compiledShaderTranslucencyByDistancePick = this._shaderTranslucencyByDistance; - this._compiledShaderDistanceDisplayConditionPick = this._shaderDistanceDisplayCondition; - this._compiledShaderDisableDepthDistancePick = this._shaderDisableDepthDistance; + function getBoundingSphere(items, entity, result) { + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if(item.contains(entity)){ + return item.getBoundingSphere(entity, result); + } } + return BoundingSphereState.FAILED; + } - var va; - var vaLength; - var command; - var j; + StaticGeometryColorBatch.prototype.getBoundingSphere = function(entity, result) { + var boundingSphere = getBoundingSphere(this._solidItems, entity, result); + if (boundingSphere === BoundingSphereState.FAILED) { + return getBoundingSphere(this._translucentItems, entity, result); + } + return boundingSphere; + }; - var commandList = frameState.commandList; + function removeAllPrimitives(items) { + var length = items.length; + for (var i = 0; i < length; i++) { + items[i].destroy(); + } + items.length = 0; + } - if (pass.render) { - var colorList = this._colorCommands; + StaticGeometryColorBatch.prototype.removeAllPrimitives = function() { + removeAllPrimitives(this._solidItems); + removeAllPrimitives(this._translucentItems); + }; - var opaque = this._blendOption === BlendOption.OPAQUE; - var opaqueAndTranslucent = this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT; + return StaticGeometryColorBatch; +}); - va = this._vaf.va; - vaLength = va.length; +define('DataSources/StaticGeometryPerMaterialBatch',[ + '../Core/AssociativeArray', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defined', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/Primitive', + './BoundingSphereState', + './ColorMaterialProperty', + './MaterialProperty', + './Property' + ], function( + AssociativeArray, + Color, + ColorGeometryInstanceAttribute, + defined, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + Primitive, + BoundingSphereState, + ColorMaterialProperty, + MaterialProperty, + Property) { + 'use strict'; - colorList.length = vaLength; - var totalLength = opaqueAndTranslucent ? vaLength * 2 : vaLength; - for (j = 0; j < totalLength; ++j) { - var opaqueCommand = opaque || (opaqueAndTranslucent && j % 2 === 0); + var distanceDisplayConditionScratch = new DistanceDisplayCondition(); - command = colorList[j]; - if (!defined(command)) { - command = colorList[j] = new DrawCommand(); - } + function Batch(primitives, appearanceType, materialProperty, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) { + this.primitives = primitives; + this.appearanceType = appearanceType; + this.materialProperty = materialProperty; + this.depthFailAppearanceType = depthFailAppearanceType; + this.depthFailMaterialProperty = depthFailMaterialProperty; + this.closed = closed; + this.shadows = shadows; + this.updaters = new AssociativeArray(); + this.createPrimitive = true; + this.primitive = undefined; + this.oldPrimitive = undefined; + this.geometry = new AssociativeArray(); + this.material = undefined; + this.depthFailMaterial = undefined; + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); + this.invalidated = false; + this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); + this.subscriptions = new AssociativeArray(); + this.showsUpdated = new AssociativeArray(); + } - command.primitiveType = PrimitiveType.POINTS; - command.pass = opaqueCommand || !opaqueAndTranslucent ? Pass.OPAQUE : Pass.TRANSLUCENT; - command.owner = this; + Batch.prototype.onMaterialChanged = function() { + this.invalidated = true; + }; - var index = opaqueAndTranslucent ? Math.floor(j / 2.0) : j; - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.shaderProgram = opaqueCommand ? this._sp : this._spTranslucent; - command.uniformMap = this._uniforms; - command.vertexArray = va[index].va; - command.renderState = opaqueCommand ? this._rsOpaque : this._rsTranslucent; - command.debugShowBoundingVolume = this.debugShowBoundingVolume; + Batch.prototype.isMaterial = function(updater) { + var material = this.materialProperty; + var updaterMaterial = updater.fillMaterialProperty; + var depthFailMaterial = this.depthFailMaterialProperty; + var updaterDepthFailMaterial = updater.depthFailMaterialProperty; - commandList.push(command); - } + if (updaterMaterial === material && updaterDepthFailMaterial === depthFailMaterial) { + return true; } + var equals = defined(material) && material.equals(updaterMaterial); + equals = ((!defined(depthFailMaterial) && !defined(updaterDepthFailMaterial)) || (defined(depthFailMaterial) && depthFailMaterial.equals(updaterDepthFailMaterial))) && equals; + return equals; + }; - if (picking) { - var pickList = this._pickCommands; - - va = this._vaf.va; - vaLength = va.length; - - pickList.length = vaLength; - for (j = 0; j < vaLength; ++j) { - command = pickList[j]; - if (!defined(command)) { - command = pickList[j] = new DrawCommand({ - primitiveType : PrimitiveType.POINTS, - pass : Pass.OPAQUE, - owner : this - }); + Batch.prototype.add = function(time, updater) { + var id = updater.entity.id; + this.updaters.set(id, updater); + this.geometry.set(id, updater.createFillGeometryInstance(time)); + if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { + this.updatersWithAttributes.set(id, updater); + } else { + var that = this; + this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { + if (propertyName === 'isShowing') { + that.showsUpdated.set(entity.id, updater); } + })); + } + this.createPrimitive = true; + }; - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.shaderProgram = this._spPick; - command.uniformMap = this._uniforms; - command.vertexArray = va[j].va; - command.renderState = this._rsOpaque; - - commandList.push(command); + Batch.prototype.remove = function(updater) { + var id = updater.entity.id; + this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; + if (this.updaters.remove(id)) { + this.updatersWithAttributes.remove(id); + var unsubscribe = this.subscriptions.get(id); + if (defined(unsubscribe)) { + unsubscribe(); + this.subscriptions.remove(id); } } + return this.createPrimitive; }; - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see PointPrimitiveCollection#destroy - */ - PointPrimitiveCollection.prototype.isDestroyed = function() { - return false; - }; + var colorScratch = new Color(); - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * pointPrimitives = pointPrimitives && pointPrimitives.destroy(); - * - * @see PointPrimitiveCollection#isDestroyed - */ - PointPrimitiveCollection.prototype.destroy = function() { - this._sp = this._sp && this._sp.destroy(); - this._spTranslucent = this._spTranslucent && this._spTranslucent.destroy(); - this._spPick = this._spPick && this._spPick.destroy(); - this._vaf = this._vaf && this._vaf.destroy(); - destroyPointPrimitives(this._pointPrimitives); + Batch.prototype.update = function(time) { + var isUpdated = true; + var primitive = this.primitive; + var primitives = this.primitives; + var geometries = this.geometry.values; + var attributes; + var i; - return destroyObject(this); - }; + if (this.createPrimitive) { + var geometriesLength = geometries.length; + if (geometriesLength > 0) { + if (defined(primitive)) { + if (!defined(this.oldPrimitive)) { + this.oldPrimitive = primitive; + } else { + primitives.remove(primitive); + } + } - return PointPrimitiveCollection; -}); + for (i = 0; i < geometriesLength; i++) { + var geometry = geometries[i]; + var originalAttributes = geometry.attributes; + attributes = this.attributes.get(geometry.id.id); -define('ThirdParty/kdbush',[], function() { -'use strict'; + if (defined(attributes)) { + if (defined(originalAttributes.show)) { + originalAttributes.show.value = attributes.show; + } + if (defined(originalAttributes.color)) { + originalAttributes.color.value = attributes.color; + } + if (defined(originalAttributes.depthFailColor)) { + originalAttributes.depthFailColor.value = attributes.depthFailColor; + } + } + } -function kdbush(points, getX, getY, nodeSize, ArrayType) { - return new KDBush(points, getX, getY, nodeSize, ArrayType); -} + this.material = MaterialProperty.getValue(time, this.materialProperty, this.material); -function KDBush(points, getX, getY, nodeSize, ArrayType) { - getX = getX || defaultGetX; - getY = getY || defaultGetY; - ArrayType = ArrayType || Array; + var depthFailAppearance; + if (defined(this.depthFailMaterialProperty)) { + var translucent; + if (this.depthFailMaterialProperty instanceof MaterialProperty) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + translucent = this.depthFailMaterial.isTranslucent(); + } else { + translucent = this.material.isTranslucent(); + } + depthFailAppearance = new this.depthFailAppearanceType({ + material : this.depthFailMaterial, + translucent : translucent, + closed : this.closed + }); + } - this.nodeSize = nodeSize || 64; - this.points = points; + primitive = new Primitive({ + asynchronous : true, + geometryInstances : geometries, + appearance : new this.appearanceType({ + material : this.material, + translucent : this.material.isTranslucent(), + closed : this.closed + }), + depthFailAppearance : depthFailAppearance, + shadows : this.shadows + }); - this.ids = new ArrayType(points.length); - this.coords = new ArrayType(points.length * 2); + primitives.add(primitive); + isUpdated = false; + } else { + if (defined(primitive)) { + primitives.remove(primitive); + primitive = undefined; + } + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; + } + } - for (var i = 0; i < points.length; i++) { - this.ids[i] = i; - this.coords[2 * i] = getX(points[i]); - this.coords[2 * i + 1] = getY(points[i]); - } + this.attributes.removeAll(); + this.primitive = primitive; + this.createPrimitive = false; + } else if (defined(primitive) && primitive.ready) { + if (defined(this.oldPrimitive)) { + primitives.remove(this.oldPrimitive); + this.oldPrimitive = undefined; + } - sort(this.ids, this.coords, this.nodeSize, 0, this.ids.length - 1, 0); -} + this.material = MaterialProperty.getValue(time, this.materialProperty, this.material); + this.primitive.appearance.material = this.material; -KDBush.prototype = { - range: function (minX, minY, maxX, maxY) { - return range(this.ids, this.coords, minX, minY, maxX, maxY, this.nodeSize); - }, + if (defined(this.depthFailAppearanceType) && !(this.depthFailMaterialProperty instanceof ColorMaterialProperty)) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + this.primitive.depthFailAppearance.material = this.depthFailMaterial; + } - within: function (x, y, r) { - return within(this.ids, this.coords, x, y, r, this.nodeSize); - } -}; + var updatersWithAttributes = this.updatersWithAttributes.values; + var length = updatersWithAttributes.length; + for (i = 0; i < length; i++) { + var updater = updatersWithAttributes[i]; + var entity = updater.entity; + var instance = this.geometry.get(entity.id); -function defaultGetX(p) { return p[0]; } -function defaultGetY(p) { return p[1]; } + attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } -function range(ids, coords, minX, minY, maxX, maxY, nodeSize) { - var stack = [0, ids.length - 1, 0]; - var result = []; - var x, y; + if (defined(this.depthFailAppearanceType) && this.depthFailAppearanceType instanceof ColorMaterialProperty && !updater.depthFailMaterialProperty.isConstant) { + var depthFailColorProperty = updater.depthFailMaterialProperty.color; + depthFailColorProperty.getValue(time, colorScratch); + if (!Color.equals(attributes._lastDepthFailColor, colorScratch)) { + attributes._lastDepthFailColor = Color.clone(colorScratch, attributes._lastDepthFailColor); + attributes.depthFailColor = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.depthFailColor); + } + } - while (stack.length) { - var axis = stack.pop(); - var right = stack.pop(); - var left = stack.pop(); + var show = entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } - if (right - left <= nodeSize) { - for (var i = left; i <= right; i++) { - x = coords[2 * i]; - y = coords[2 * i + 1]; - if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]); + var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; + if (!Property.isConstant(distanceDisplayConditionProperty)) { + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); + if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { + attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); + attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); + } + } } - continue; - } - - var m = Math.floor((left + right) / 2); - - x = coords[2 * m]; - y = coords[2 * m + 1]; - - if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]); - - var nextAxis = (axis + 1) % 2; - if (axis === 0 ? minX <= x : minY <= y) { - stack.push(left); - stack.push(m - 1); - stack.push(nextAxis); - } - if (axis === 0 ? maxX >= x : maxY >= y) { - stack.push(m + 1); - stack.push(right); - stack.push(nextAxis); + this.updateShows(primitive); + } else if (defined(primitive) && !primitive.ready) { + isUpdated = false; } - } - - return result; -} - -function sort(ids, coords, nodeSize, left, right, depth) { - if (right - left <= nodeSize) return; - - var m = Math.floor((left + right) / 2); - - select(ids, coords, m, left, right, depth % 2); + return isUpdated; + }; - sort(ids, coords, nodeSize, left, m - 1, depth + 1); - sort(ids, coords, nodeSize, m + 1, right, depth + 1); -} + Batch.prototype.updateShows = function(primitive) { + var showsUpdated = this.showsUpdated.values; + var length = showsUpdated.length; + for (var i = 0; i < length; i++) { + var updater = showsUpdated[i]; + var entity = updater.entity; + var instance = this.geometry.get(entity.id); -function select(ids, coords, k, left, right, inc) { + var attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } - while (right > left) { - if (right - left > 600) { - var n = right - left + 1; - var m = k - left + 1; - var z = Math.log(n); - var s = 0.5 * Math.exp(2 * z / 3); - var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); - var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); - var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); - select(ids, coords, k, newLeft, newRight, inc); + var show = entity.isShowing; + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } } + this.showsUpdated.removeAll(); + }; - var t = coords[2 * k + inc]; - var i = left; - var j = right; - - swapItem(ids, coords, left, k); - if (coords[2 * right + inc] > t) swapItem(ids, coords, left, right); + Batch.prototype.contains = function(entity) { + return this.updaters.contains(entity.id); + }; - while (i < j) { - swapItem(ids, coords, i, j); - i++; - j--; - while (coords[2 * i + inc] < t) i++; - while (coords[2 * j + inc] > t) j--; + Batch.prototype.getBoundingSphere = function(entity, result) { + var primitive = this.primitive; + if (!primitive.ready) { + return BoundingSphereState.PENDING; } + var attributes = primitive.getGeometryInstanceAttributes(entity); + if (!defined(attributes) || !defined(attributes.boundingSphere) || + (defined(attributes.show) && attributes.show[0] === 0)) { + return BoundingSphereState.FAILED; + } + attributes.boundingSphere.clone(result); + return BoundingSphereState.DONE; + }; - if (coords[2 * left + inc] === t) swapItem(ids, coords, left, j); - else { - j++; - swapItem(ids, coords, j, right); + Batch.prototype.destroy = function() { + var primitive = this.primitive; + var primitives = this.primitives; + if (defined(primitive)) { + primitives.remove(primitive); + } + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); } + this.removeMaterialSubscription(); + }; - if (j <= k) left = j + 1; - if (k <= j) right = j - 1; + /** + * @private + */ + function StaticGeometryPerMaterialBatch(primitives, appearanceType, depthFailAppearanceType, closed, shadows) { + this._items = []; + this._primitives = primitives; + this._appearanceType = appearanceType; + this._depthFailAppearanceType = depthFailAppearanceType; + this._closed = closed; + this._shadows = shadows; } -} - -function swapItem(ids, coords, i, j) { - swap(ids, i, j); - swap(coords, 2 * i, 2 * j); - swap(coords, 2 * i + 1, 2 * j + 1); -} - -function swap(arr, i, j) { - var tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; -} - -function within(ids, coords, qx, qy, r, nodeSize) { - var stack = [0, ids.length - 1, 0]; - var result = []; - var r2 = r * r; - - while (stack.length) { - var axis = stack.pop(); - var right = stack.pop(); - var left = stack.pop(); - if (right - left <= nodeSize) { - for (var i = left; i <= right; i++) { - if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) result.push(ids[i]); + StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) { + var items = this._items; + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if (item.isMaterial(updater)) { + item.add(time, updater); + return; } - continue; } + var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._depthFailAppearanceType, updater.depthFailMaterialProperty, this._closed, this._shadows); + batch.add(time, updater); + items.push(batch); + }; - var m = Math.floor((left + right) / 2); - - var x = coords[2 * m]; - var y = coords[2 * m + 1]; - - if (sqDist(x, y, qx, qy) <= r2) result.push(ids[m]); + StaticGeometryPerMaterialBatch.prototype.remove = function(updater) { + var items = this._items; + var length = items.length; + for (var i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.remove(updater)) { + if (item.updaters.length === 0) { + items.splice(i, 1); + item.destroy(); + } + break; + } + } + }; - var nextAxis = (axis + 1) % 2; + StaticGeometryPerMaterialBatch.prototype.update = function(time) { + var i; + var items = this._items; + var length = items.length; - if (axis === 0 ? qx - r <= x : qy - r <= y) { - stack.push(left); - stack.push(m - 1); - stack.push(nextAxis); + for (i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.invalidated) { + items.splice(i, 1); + var updaters = item.updaters.values; + var updatersLength = updaters.length; + for (var h = 0; h < updatersLength; h++) { + this.add(time, updaters[h]); + } + item.destroy(); + } } - if (axis === 0 ? qx + r >= x : qy + r >= y) { - stack.push(m + 1); - stack.push(right); - stack.push(nextAxis); + + var isUpdated = true; + for (i = 0; i < length; i++) { + isUpdated = items[i].update(time) && isUpdated; } - } + return isUpdated; + }; - return result; -} + StaticGeometryPerMaterialBatch.prototype.getBoundingSphere = function(entity, result) { + var items = this._items; + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if(item.contains(entity)){ + return item.getBoundingSphere(entity, result); + } + } + return BoundingSphereState.FAILED; + }; -function sqDist(ax, ay, bx, by) { - var dx = ax - bx; - var dy = ay - by; - return dx * dx + dy * dy; -} + StaticGeometryPerMaterialBatch.prototype.removeAllPrimitives = function() { + var items = this._items; + var length = items.length; + for (var i = 0; i < length; i++) { + items[i].destroy(); + } + this._items.length = 0; + }; -return kdbush; + return StaticGeometryPerMaterialBatch; }); -define('DataSources/EntityCluster',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/defaultValue', +define('DataSources/StaticGroundGeometryColorBatch',[ + '../Core/AssociativeArray', + '../Core/Color', '../Core/defined', - '../Core/defineProperties', - '../Core/EllipsoidalOccluder', - '../Core/Event', - '../Core/Matrix4', - '../Scene/Billboard', - '../Scene/BillboardCollection', - '../Scene/Label', - '../Scene/LabelCollection', - '../Scene/PointPrimitive', - '../Scene/PointPrimitiveCollection', - '../Scene/SceneMode', - '../ThirdParty/kdbush' + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/GroundPrimitive', + './BoundingSphereState', + './Property' ], function( - BoundingRectangle, - Cartesian2, - Cartesian3, - defaultValue, + AssociativeArray, + Color, defined, - defineProperties, - EllipsoidalOccluder, - Event, - Matrix4, - Billboard, - BillboardCollection, - Label, - LabelCollection, - PointPrimitive, - PointPrimitiveCollection, - SceneMode, - kdbush) { + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + GroundPrimitive, + BoundingSphereState, + Property) { 'use strict'; - /** - * Defines how screen space objects (billboards, points, labels) are clustered. - * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.enabled=false] Whether or not to enable clustering. - * @param {Number} [options.pixelRange=80] The pixel range to extend the screen space bounding box. - * @param {Number} [options.minimumClusterSize=2] The minimum number of screen space objects that can be clustered. - * @param {Boolean} [options.clusterBillboards=true] Whether or not to cluster the billboards of an entity. - * @param {Boolean} [options.clusterLabels=true] Whether or not to cluster the labels of an entity. - * @param {Boolean} [options.clusterPoints=true] Whether or not to cluster the points of an entity. - * - * @alias EntityCluster - * @constructor - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Clustering.html|Cesium Sandcastle Clustering Demo} - */ - function EntityCluster(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var colorScratch = new Color(); + var distanceDisplayConditionScratch = new DistanceDisplayCondition(); - this._enabled = defaultValue(options.enabled, false); - this._pixelRange = defaultValue(options.pixelRange, 80); - this._minimumClusterSize = defaultValue(options.minimumClusterSize, 2); - this._clusterBillboards = defaultValue(options.clusterBillboards, true); - this._clusterLabels = defaultValue(options.clusterLabels, true); - this._clusterPoints = defaultValue(options.clusterPoints, true); + function Batch(primitives, color, key) { + this.primitives = primitives; + this.color = color; + this.key = key; + this.createPrimitive = false; + this.waitingOnCreate = false; + this.primitive = undefined; + this.oldPrimitive = undefined; + this.geometry = new AssociativeArray(); + this.updaters = new AssociativeArray(); + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); + this.subscriptions = new AssociativeArray(); + this.showsUpdated = new AssociativeArray(); + this.itemsToRemove = []; + this.isDirty = false; + } - this._labelCollection = undefined; - this._billboardCollection = undefined; - this._pointCollection = undefined; + Batch.prototype.add = function(updater, instance) { + var id = updater.entity.id; + this.createPrimitive = true; + this.geometry.set(id, instance); + this.updaters.set(id, updater); + if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { + this.updatersWithAttributes.set(id, updater); + } else { + var that = this; + this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { + if (propertyName === 'isShowing') { + that.showsUpdated.set(entity.id, updater); + } + })); + } + }; - this._clusterBillboardCollection = undefined; - this._clusterLabelCollection = undefined; - this._clusterPointCollection = undefined; + Batch.prototype.remove = function(updater) { + var id = updater.entity.id; + this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; + if (this.updaters.remove(id)) { + this.updatersWithAttributes.remove(id); + var unsubscribe = this.subscriptions.get(id); + if (defined(unsubscribe)) { + unsubscribe(); + this.subscriptions.remove(id); + } + } + }; - this._collectionIndicesByEntity = {}; + var scratchArray = new Array(4); - this._unusedLabelIndices = []; - this._unusedBillboardIndices = []; - this._unusedPointIndices = []; + Batch.prototype.update = function(time) { + var isUpdated = true; + var removedCount = 0; + var primitive = this.primitive; + var primitives = this.primitives; + var attributes; + var i; - this._previousClusters = []; - this._previousHeight = undefined; + if (this.createPrimitive) { + var geometries = this.geometry.values; + var geometriesLength = geometries.length; + if (geometriesLength > 0) { + if (defined(primitive)) { + if (!defined(this.oldPrimitive)) { + this.oldPrimitive = primitive; + } else { + primitives.remove(primitive); + } + } - this._enabledDirty = false; - this._clusterDirty = false; + for (i = 0; i < geometriesLength; i++) { + var geometryItem = geometries[i]; + var originalAttributes = geometryItem.attributes; + attributes = this.attributes.get(geometryItem.id.id); - this._cluster = undefined; - this._removeEventListener = undefined; + if (defined(attributes)) { + if (defined(originalAttributes.show)) { + originalAttributes.show.value = attributes.show; + } + if (defined(originalAttributes.color)) { + originalAttributes.color.value = attributes.color; + } + } + } - this._clusterEvent = new Event(); - } + primitive = new GroundPrimitive({ + asynchronous : true, + geometryInstances : geometries + }); + primitives.add(primitive); + isUpdated = false; + } else { + if (defined(primitive)) { + primitives.remove(primitive); + primitive = undefined; + } + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; + } + } - function getX(point) { - return point.coord.x; - } + this.attributes.removeAll(); + this.primitive = primitive; + this.createPrimitive = false; + this.waitingOnCreate = true; + } else if (defined(primitive) && primitive.ready) { + if (defined(this.oldPrimitive)) { + primitives.remove(this.oldPrimitive); + this.oldPrimitive = undefined; + } + var updatersWithAttributes = this.updatersWithAttributes.values; + var length = updatersWithAttributes.length; + var waitingOnCreate = this.waitingOnCreate; + for (i = 0; i < length; i++) { + var updater = updatersWithAttributes[i]; + var instance = this.geometry.get(updater.entity.id); - function getY(point) { - return point.coord.y; - } + attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } - function expandBoundingBox(bbox, pixelRange) { - bbox.x -= pixelRange; - bbox.y -= pixelRange; - bbox.width += pixelRange * 2.0; - bbox.height += pixelRange * 2.0; - } + if (!updater.fillMaterialProperty.isConstant || waitingOnCreate) { + var colorProperty = updater.fillMaterialProperty.color; + colorProperty.getValue(time, colorScratch); - var labelBoundingBoxScratch = new BoundingRectangle(); + if (!Color.equals(attributes._lastColor, colorScratch)) { + attributes._lastColor = Color.clone(colorScratch, attributes._lastColor); + var color = this.color; + var newColor = colorScratch.toBytes(scratchArray); + if (color[0] !== newColor[0] || color[1] !== newColor[1] || + color[2] !== newColor[2] || color[3] !== newColor[3]) { + this.itemsToRemove[removedCount++] = updater; + } + } + } - function getBoundingBox(item, coord, pixelRange, entityCluster, result) { - if (defined(item._labelCollection) && entityCluster._clusterLabels) { - result = Label.getScreenSpaceBoundingBox(item, coord, result); - } else if (defined(item._billboardCollection) && entityCluster._clusterBillboards) { - result = Billboard.getScreenSpaceBoundingBox(item, coord, result); - } else if (defined(item._pointPrimitiveCollection) && entityCluster._clusterPoints) { - result = PointPrimitive.getScreenSpaceBoundingBox(item, coord, result); - } + var show = updater.entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } - expandBoundingBox(result, pixelRange); + var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; + if (!Property.isConstant(distanceDisplayConditionProperty)) { + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); + if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { + attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); + attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); + } + } + } - if (entityCluster._clusterLabels && !defined(item._labelCollection) && defined(item.id) && hasLabelIndex(entityCluster, item.id) && defined(item.id._label)) { - var labelIndex = entityCluster._collectionIndicesByEntity[item.id]; - var label = entityCluster._labelCollection.get(labelIndex); - var labelBBox = Label.getScreenSpaceBoundingBox(label, coord, labelBoundingBoxScratch); - expandBoundingBox(labelBBox, pixelRange); - result = BoundingRectangle.union(result, labelBBox, result); + this.updateShows(primitive); + this.waitingOnCreate = false; + } else if (defined(primitive) && !primitive.ready) { + isUpdated = false; } + this.itemsToRemove.length = removedCount; + return isUpdated; + }; - return result; - } + Batch.prototype.updateShows = function(primitive) { + var showsUpdated = this.showsUpdated.values; + var length = showsUpdated.length; + for (var i = 0; i < length; i++) { + var updater = showsUpdated[i]; + var instance = this.geometry.get(updater.entity.id); - function addNonClusteredItem(item, entityCluster) { - item.clusterShow = true; + var attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } - if (!defined(item._labelCollection) && defined(item.id) && hasLabelIndex(entityCluster, item.id) && defined(item.id._label)) { - var labelIndex = entityCluster._collectionIndicesByEntity[item.id]; - var label = entityCluster._labelCollection.get(labelIndex); - label.clusterShow = true; + var show = updater.entity.isShowing; + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } } - } - - function addCluster(position, numPoints, ids, entityCluster) { - var cluster = { - billboard : entityCluster._clusterBillboardCollection.add(), - label : entityCluster._clusterLabelCollection.add(), - point : entityCluster._clusterPointCollection.add() - }; - - cluster.billboard.show = false; - cluster.point.show = false; - cluster.label.show = true; - cluster.label.text = numPoints.toLocaleString(); - cluster.label.id = ids; - cluster.billboard.position = cluster.label.position = cluster.point.position = position; - - entityCluster._clusterEvent.raiseEvent(ids, cluster); - } + this.showsUpdated.removeAll(); + }; - function hasLabelIndex(entityCluster, entityId) { - return defined(entityCluster) && defined(entityCluster._collectionIndicesByEntity[entityId]) && defined(entityCluster._collectionIndicesByEntity[entityId].labelIndex); - } + Batch.prototype.contains = function(entity) { + return this.updaters.contains(entity.id); + }; - function getScreenSpacePositions(collection, points, scene, occluder, entityCluster) { - if (!defined(collection)) { - return; + Batch.prototype.getBoundingSphere = function(entity, result) { + var primitive = this.primitive; + if (!primitive.ready) { + return BoundingSphereState.PENDING; } - var length = collection.length; - for (var i = 0; i < length; ++i) { - var item = collection.get(i); - item.clusterShow = false; + var bs = primitive.getBoundingSphere(entity); + if (!defined(bs)) { + return BoundingSphereState.FAILED; + } - if (!item.show || (entityCluster._scene.mode === SceneMode.SCENE3D && !occluder.isPointVisible(item.position))) { - continue; - } + bs.clone(result); + return BoundingSphereState.DONE; + }; - var canClusterLabels = entityCluster._clusterLabels && defined(item._labelCollection); - var canClusterBillboards = entityCluster._clusterBillboards && defined(item.id._billboard); - var canClusterPoints = entityCluster._clusterPoints && defined(item.id._point); - if (canClusterLabels && (canClusterPoints || canClusterBillboards)) { - continue; - } + Batch.prototype.removeAllPrimitives = function() { + var primitives = this.primitives; - var coord = item.computeScreenSpacePosition(scene); - if (!defined(coord)) { - continue; - } + var primitive = this.primitive; + if (defined(primitive)) { + primitives.remove(primitive); + this.primitive = undefined; + this.geometry.removeAll(); + this.updaters.removeAll(); + } - points.push({ - index : i, - collection : collection, - clustered : false, - coord : coord - }); + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; } + }; + + /** + * @private + */ + function StaticGroundGeometryColorBatch(primitives) { + this._batches = new AssociativeArray(); + this._primitives = primitives; } - var pointBoundinRectangleScratch = new BoundingRectangle(); - var totalBoundingRectangleScratch = new BoundingRectangle(); - var neighborBoundingRectangleScratch = new BoundingRectangle(); + StaticGroundGeometryColorBatch.prototype.add = function(time, updater) { + var instance = updater.createFillGeometryInstance(time); + var batches = this._batches; + // instance.attributes.color.value is a Uint8Array, so just read it as a Uint32 and make that the key + var batchKey = new Uint32Array(instance.attributes.color.value.buffer)[0]; + var batch; + if (batches.contains(batchKey)) { + batch = batches.get(batchKey); + } else { + batch = new Batch(this._primitives, instance.attributes.color.value, batchKey); + batches.set(batchKey, batch); + } + batch.add(updater, instance); + return batch; + }; - function createDeclutterCallback(entityCluster) { - return function(amount) { - if ((defined(amount) && amount < 0.05) || !entityCluster.enabled) { + StaticGroundGeometryColorBatch.prototype.remove = function(updater) { + var batchesArray = this._batches.values; + var count = batchesArray.length; + for (var i = 0; i < count; ++i) { + if (batchesArray[i].remove(updater)) { return; } + } + }; - var scene = entityCluster._scene; + StaticGroundGeometryColorBatch.prototype.update = function(time) { + var i; + var updater; - var labelCollection = entityCluster._labelCollection; - var billboardCollection = entityCluster._billboardCollection; - var pointCollection = entityCluster._pointCollection; + //Perform initial update + var isUpdated = true; + var batches = this._batches; + var batchesArray = batches.values; + var batchCount = batchesArray.length; + for (i = 0; i < batchCount; ++i) { + isUpdated = batchesArray[i].update(time) && isUpdated; + } - if ((!defined(labelCollection) && !defined(billboardCollection) && !defined(pointCollection)) || - (!entityCluster._clusterBillboards && !entityCluster._clusterLabels && !entityCluster._clusterPoints)) { - return; + //If any items swapped between batches we need to move them + for (i = 0; i < batchCount; ++i) { + var oldBatch = batchesArray[i]; + var itemsToRemove = oldBatch.itemsToRemove; + var itemsToMoveLength = itemsToRemove.length; + for (var j = 0; j < itemsToMoveLength; j++) { + updater = itemsToRemove[j]; + oldBatch.remove(updater); + var newBatch = this.add(time, updater); + oldBatch.isDirty = true; + newBatch.isDirty = true; } + } - var clusteredLabelCollection = entityCluster._clusterLabelCollection; - var clusteredBillboardCollection = entityCluster._clusterBillboardCollection; - var clusteredPointCollection = entityCluster._clusterPointCollection; - - if (defined(clusteredLabelCollection)) { - clusteredLabelCollection.removeAll(); - } else { - clusteredLabelCollection = entityCluster._clusterLabelCollection = new LabelCollection({ - scene : scene - }); + //If we moved anything around, we need to re-build the primitive and remove empty batches + var batchesArrayCopy = batchesArray.slice(); + var batchesCopyCount = batchesArrayCopy.length; + for (i = 0; i < batchesCopyCount; ++i) { + var batch = batchesArrayCopy[i]; + if (batch.isDirty) { + isUpdated = batchesArrayCopy[i].update(time) && isUpdated; + batch.isDirty = false; } - - if (defined(clusteredBillboardCollection)) { - clusteredBillboardCollection.removeAll(); - } else { - clusteredBillboardCollection = entityCluster._clusterBillboardCollection = new BillboardCollection({ - scene : scene - }); + if (batch.geometry.length === 0) { + batches.remove(batch.key); } + } - if (defined(clusteredPointCollection)) { - clusteredPointCollection.removeAll(); - } else { - clusteredPointCollection = entityCluster._clusterPointCollection = new PointPrimitiveCollection(); - } + return isUpdated; + }; - var pixelRange = entityCluster._pixelRange; - var minimumClusterSize = entityCluster._minimumClusterSize; + StaticGroundGeometryColorBatch.prototype.getBoundingSphere = function(entity, result) { + var batchesArray = this._batches.values; + var batchCount = batchesArray.length; + for (var i = 0; i < batchCount; ++i) { + var batch = batchesArray[i]; + if (batch.contains(entity)) { + return batch.getBoundingSphere(entity, result); + } + } - var clusters = entityCluster._previousClusters; - var newClusters = []; + return BoundingSphereState.FAILED; + }; - var previousHeight = entityCluster._previousHeight; - var currentHeight = scene.camera.positionCartographic.height; + StaticGroundGeometryColorBatch.prototype.removeAllPrimitives = function() { + var batchesArray = this._batches.values; + var batchCount = batchesArray.length; + for (var i = 0; i < batchCount; ++i) { + batchesArray[i].removeAllPrimitives(); + } + }; - var ellipsoid = scene.mapProjection.ellipsoid; - var cameraPosition = scene.camera.positionWC; - var occluder = new EllipsoidalOccluder(ellipsoid, cameraPosition); + return StaticGroundGeometryColorBatch; +}); - var points = []; - if (entityCluster._clusterLabels) { - getScreenSpacePositions(labelCollection, points, scene, occluder, entityCluster); - } - if (entityCluster._clusterBillboards) { - getScreenSpacePositions(billboardCollection, points, scene, occluder, entityCluster); - } - if (entityCluster._clusterPoints) { - getScreenSpacePositions(pointCollection, points, scene, occluder, entityCluster); - } +define('DataSources/StaticOutlineGeometryBatch',[ + '../Core/AssociativeArray', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defined', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + './BoundingSphereState', + './Property' + ], function( + AssociativeArray, + Color, + ColorGeometryInstanceAttribute, + defined, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + ShowGeometryInstanceAttribute, + PerInstanceColorAppearance, + Primitive, + BoundingSphereState, + Property) { + 'use strict'; - var i; - var j; - var length; - var bbox; - var neighbors; - var neighborLength; - var neighborIndex; - var neighborPoint; - var ids; - var numPoints; + function Batch(primitives, translucent, width, shadows) { + this.translucent = translucent; + this.width = width; + this.shadows = shadows; + this.primitives = primitives; + this.createPrimitive = false; + this.waitingOnCreate = false; + this.primitive = undefined; + this.oldPrimitive = undefined; + this.geometry = new AssociativeArray(); + this.updaters = new AssociativeArray(); + this.updatersWithAttributes = new AssociativeArray(); + this.attributes = new AssociativeArray(); + this.itemsToRemove = []; + this.subscriptions = new AssociativeArray(); + this.showsUpdated = new AssociativeArray(); + } + Batch.prototype.add = function(updater, instance) { + var id = updater.entity.id; + this.createPrimitive = true; + this.geometry.set(id, instance); + this.updaters.set(id, updater); + if (!updater.hasConstantOutline || !updater.outlineColorProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { + this.updatersWithAttributes.set(id, updater); + } else { + var that = this; + this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { + if (propertyName === 'isShowing') { + that.showsUpdated.set(entity.id, updater); + } + })); + } + }; - var collection; - var collectionIndex; + Batch.prototype.remove = function(updater) { + var id = updater.entity.id; + this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; + if (this.updaters.remove(id)) { + this.updatersWithAttributes.remove(id); + var unsubscribe = this.subscriptions.get(id); + if (defined(unsubscribe)) { + unsubscribe(); + this.subscriptions.remove(id); + } + } + }; - var index = kdbush(points, getX, getY, 64, Int32Array); + var colorScratch = new Color(); + var distanceDisplayConditionScratch = new DistanceDisplayCondition(); - if (currentHeight < previousHeight) { - length = clusters.length; - for (i = 0; i < length; ++i) { - var cluster = clusters[i]; + Batch.prototype.update = function(time) { + var isUpdated = true; + var removedCount = 0; + var primitive = this.primitive; + var primitives = this.primitives; + var attributes; + var i; - if (!occluder.isPointVisible(cluster.position)) { - continue; + if (this.createPrimitive) { + var geometries = this.geometry.values; + var geometriesLength = geometries.length; + if (geometriesLength > 0) { + if (defined(primitive)) { + if (!defined(this.oldPrimitive)) { + this.oldPrimitive = primitive; + } else { + primitives.remove(primitive); } + } - var coord = Billboard._computeScreenSpacePosition(Matrix4.IDENTITY, cluster.position, Cartesian3.ZERO, Cartesian2.ZERO, scene); - if (!defined(coord)) { - continue; + for (i = 0; i < geometriesLength; i++) { + var geometryItem = geometries[i]; + var originalAttributes = geometryItem.attributes; + attributes = this.attributes.get(geometryItem.id.id); + + if (defined(attributes)) { + if (defined(originalAttributes.show)) { + originalAttributes.show.value = attributes.show; + } + if (defined(originalAttributes.color)) { + originalAttributes.color.value = attributes.color; + } } + } - var factor = 1.0 - currentHeight / previousHeight; - var width = cluster.width = cluster.width * factor; - var height = cluster.height = cluster.height * factor; + primitive = new Primitive({ + asynchronous : true, + geometryInstances : geometries, + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : this.translucent, + renderState : { + lineWidth : this.width + } + }), + shadows : this.shadows + }); - width = Math.max(width, cluster.minimumWidth); - height = Math.max(height, cluster.minimumHeight); + primitives.add(primitive); + isUpdated = false; + } else { + if (defined(primitive)) { + primitives.remove(primitive); + primitive = undefined; + } + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; + } + } - var minX = coord.x - width * 0.5; - var minY = coord.y - height * 0.5; - var maxX = coord.x + width; - var maxY = coord.y + height; + this.attributes.removeAll(); + this.primitive = primitive; + this.createPrimitive = false; + this.waitingOnCreate = true; + } else if (defined(primitive) && primitive.ready) { + if (defined(this.oldPrimitive)) { + primitives.remove(this.oldPrimitive); + this.oldPrimitive = undefined; + } - neighbors = index.range(minX, minY, maxX, maxY); - neighborLength = neighbors.length; - numPoints = 0; - ids = []; + var updatersWithAttributes = this.updatersWithAttributes.values; + var length = updatersWithAttributes.length; + var waitingOnCreate = this.waitingOnCreate; + for (i = 0; i < length; i++) { + var updater = updatersWithAttributes[i]; + var instance = this.geometry.get(updater.entity.id); - for (j = 0; j < neighborLength; ++j) { - neighborIndex = neighbors[j]; - neighborPoint = points[neighborIndex]; - if (!neighborPoint.clustered) { - ++numPoints; + attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } - collection = neighborPoint.collection; - collectionIndex = neighborPoint.index; - ids.push(collection.get(collectionIndex).id); + if (!updater.outlineColorProperty.isConstant || waitingOnCreate) { + var outlineColorProperty = updater.outlineColorProperty; + outlineColorProperty.getValue(time, colorScratch); + if (!Color.equals(attributes._lastColor, colorScratch)) { + attributes._lastColor = Color.clone(colorScratch, attributes._lastColor); + attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); + if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { + this.itemsToRemove[removedCount++] = updater; } } + } - if (numPoints >= minimumClusterSize) { - addCluster(cluster.position, numPoints, ids, entityCluster); - newClusters.push(cluster); + var show = updater.entity.isShowing && (updater.hasConstantOutline || updater.isOutlineVisible(time)); + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } - for (j = 0; j < neighborLength; ++j) { - points[neighbors[j]].clustered = true; - } + var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; + if (!Property.isConstant(distanceDisplayConditionProperty)) { + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); + if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { + attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); + attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); } } } - length = points.length; - for (i = 0; i < length; ++i) { - var point = points[i]; - if (point.clustered) { - continue; - } + this.updateShows(primitive); + this.waitingOnCreate = false; + } else if (defined(primitive) && !primitive.ready) { + isUpdated = false; + } - point.clustered = true; + this.itemsToRemove.length = removedCount; + return isUpdated; + }; - collection = point.collection; - collectionIndex = point.index; + Batch.prototype.updateShows = function(primitive) { + var showsUpdated = this.showsUpdated.values; + var length = showsUpdated.length; + for (var i = 0; i < length; i++) { + var updater = showsUpdated[i]; + var instance = this.geometry.get(updater.entity.id); - var item = collection.get(collectionIndex); - bbox = getBoundingBox(item, point.coord, pixelRange, entityCluster, pointBoundinRectangleScratch); - var totalBBox = BoundingRectangle.clone(bbox, totalBoundingRectangleScratch); + var attributes = this.attributes.get(instance.id.id); + if (!defined(attributes)) { + attributes = primitive.getGeometryInstanceAttributes(instance.id); + this.attributes.set(instance.id.id, attributes); + } + + var show = updater.entity.isShowing; + var currentShow = attributes.show[0] === 1; + if (show !== currentShow) { + attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + } + } + this.showsUpdated.removeAll(); + }; + + Batch.prototype.contains = function(entity) { + return this.updaters.contains(entity.id); + }; + + Batch.prototype.getBoundingSphere = function(entity, result) { + var primitive = this.primitive; + if (!primitive.ready) { + return BoundingSphereState.PENDING; + } + var attributes = primitive.getGeometryInstanceAttributes(entity); + if (!defined(attributes) || !defined(attributes.boundingSphere) ||// + (defined(attributes.show) && attributes.show[0] === 0)) { + return BoundingSphereState.FAILED; + } + attributes.boundingSphere.clone(result); + return BoundingSphereState.DONE; + }; + + Batch.prototype.removeAllPrimitives = function() { + var primitives = this.primitives; + + var primitive = this.primitive; + if (defined(primitive)) { + primitives.remove(primitive); + this.primitive = undefined; + this.geometry.removeAll(); + this.updaters.removeAll(); + } + + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + this.oldPrimitive = undefined; + } + }; + + /** + * @private + */ + function StaticOutlineGeometryBatch(primitives, scene, shadows) { + this._primitives = primitives; + this._scene = scene; + this._shadows = shadows; + this._solidBatches = new AssociativeArray(); + this._translucentBatches = new AssociativeArray(); + } + StaticOutlineGeometryBatch.prototype.add = function(time, updater) { + var instance = updater.createOutlineGeometryInstance(time); + var width = this._scene.clampLineWidth(updater.outlineWidth); + var batches; + var batch; + if (instance.attributes.color.value[3] === 255) { + batches = this._solidBatches; + batch = batches.get(width); + if (!defined(batch)) { + batch = new Batch(this._primitives, false, width, this._shadows); + batches.set(width, batch); + } + batch.add(updater, instance); + } else { + batches = this._translucentBatches; + batch = batches.get(width); + if (!defined(batch)) { + batch = new Batch(this._primitives, true, width, this._shadows); + batches.set(width, batch); + } + batch.add(updater, instance); + } + }; - neighbors = index.range(bbox.x, bbox.y, bbox.x + bbox.width, bbox.y + bbox.height); - neighborLength = neighbors.length; + StaticOutlineGeometryBatch.prototype.remove = function(updater) { + var i; - var clusterPosition = Cartesian3.clone(item.position); - numPoints = 1; - ids = [item.id]; + var solidBatches = this._solidBatches.values; + var solidBatchesLength = solidBatches.length; + for (i = 0; i < solidBatchesLength; i++) { + if (solidBatches[i].remove(updater)) { + return; + } + } - for (j = 0; j < neighborLength; ++j) { - neighborIndex = neighbors[j]; - neighborPoint = points[neighborIndex]; - if (!neighborPoint.clustered) { - var neighborItem = neighborPoint.collection.get(neighborPoint.index); - var neighborBBox = getBoundingBox(neighborItem, neighborPoint.coord, pixelRange, entityCluster, neighborBoundingRectangleScratch); + var translucentBatches = this._translucentBatches.values; + var translucentBatchesLength = translucentBatches.length; + for (i = 0; i < translucentBatchesLength; i++) { + if (translucentBatches[i].remove(updater)) { + return; + } + } + }; - Cartesian3.add(neighborItem.position, clusterPosition, clusterPosition); + StaticOutlineGeometryBatch.prototype.update = function(time) { + var i; + var x; + var updater; + var batch; + var solidBatches = this._solidBatches.values; + var solidBatchesLength = solidBatches.length; + var translucentBatches = this._translucentBatches.values; + var translucentBatchesLength = translucentBatches.length; + var itemsToRemove; + var isUpdated = true; + var needUpdate = false; - BoundingRectangle.union(totalBBox, neighborBBox, totalBBox); - ++numPoints; + do { + needUpdate = false; + for (x = 0; x < solidBatchesLength; x++) { + batch = solidBatches[x]; + //Perform initial update + isUpdated = batch.update(time); - ids.push(neighborItem.id); + //If any items swapped between solid/translucent, we need to + //move them between batches + itemsToRemove = batch.itemsToRemove; + var solidsToMoveLength = itemsToRemove.length; + if (solidsToMoveLength > 0) { + needUpdate = true; + for (i = 0; i < solidsToMoveLength; i++) { + updater = itemsToRemove[i]; + batch.remove(updater); + this.add(time, updater); } } + } + for (x = 0; x < translucentBatchesLength; x++) { + batch = translucentBatches[x]; + //Perform initial update + isUpdated = batch.update(time); - if (numPoints >= minimumClusterSize) { - var position = Cartesian3.multiplyByScalar(clusterPosition, 1.0 / numPoints, clusterPosition); - addCluster(position, numPoints, ids, entityCluster); - newClusters.push({ - position : position, - width : totalBBox.width, - height : totalBBox.height, - minimumWidth : bbox.width, - minimumHeight : bbox.height - }); - - for (j = 0; j < neighborLength; ++j) { - points[neighbors[j]].clustered = true; + //If any items swapped between solid/translucent, we need to + //move them between batches + itemsToRemove = batch.itemsToRemove; + var translucentToMoveLength = itemsToRemove.length; + if (translucentToMoveLength > 0) { + needUpdate = true; + for (i = 0; i < translucentToMoveLength; i++) { + updater = itemsToRemove[i]; + batch.remove(updater); + this.add(time, updater); } - } else { - addNonClusteredItem(item, entityCluster); } } + } while (needUpdate); - if (clusteredLabelCollection.length === 0) { - clusteredLabelCollection.destroy(); - entityCluster._clusterLabelCollection = undefined; - } + return isUpdated; + }; - if (clusteredBillboardCollection.length === 0) { - clusteredBillboardCollection.destroy(); - entityCluster._clusterBillboardCollection = undefined; + StaticOutlineGeometryBatch.prototype.getBoundingSphere = function(entity, result) { + var i; + + var solidBatches = this._solidBatches.values; + var solidBatchesLength = solidBatches.length; + for (i = 0; i < solidBatchesLength; i++) { + var solidBatch = solidBatches[i]; + if(solidBatch.contains(entity)){ + return solidBatch.getBoundingSphere(entity, result); } + } - if (clusteredPointCollection.length === 0) { - clusteredPointCollection.destroy(); - entityCluster._clusterPointCollection = undefined; + var translucentBatches = this._translucentBatches.values; + var translucentBatchesLength = translucentBatches.length; + for (i = 0; i < translucentBatchesLength; i++) { + var translucentBatch = translucentBatches[i]; + if(translucentBatch.contains(entity)){ + return translucentBatch.getBoundingSphere(entity, result); } + } - entityCluster._previousClusters = newClusters; - entityCluster._previousHeight = currentHeight; - }; - } + return BoundingSphereState.FAILED; + }; - EntityCluster.prototype._initialize = function(scene) { - this._scene = scene; + StaticOutlineGeometryBatch.prototype.removeAllPrimitives = function() { + var i; - var cluster = createDeclutterCallback(this); - this._cluster = cluster; - this._removeEventListener = scene.camera.changed.addEventListener(cluster); - }; + var solidBatches = this._solidBatches.values; + var solidBatchesLength = solidBatches.length; + for (i = 0; i < solidBatchesLength; i++) { + solidBatches[i].removeAllPrimitives(); + } - defineProperties(EntityCluster.prototype, { - /** - * Gets or sets whether clustering is enabled. - * @memberof EntityCluster.prototype - * @type {Boolean} - */ - enabled : { - get : function() { - return this._enabled; - }, - set : function(value) { - this._enabledDirty = value !== this._enabled; - this._enabled = value; - } - }, - /** - * Gets or sets the pixel range to extend the screen space bounding box. - * @memberof EntityCluster.prototype - * @type {Number} - */ - pixelRange : { - get : function() { - return this._pixelRange; - }, - set : function(value) { - this._clusterDirty = this._clusterDirty || value !== this._pixelRange; - this._pixelRange = value; - } - }, - /** - * Gets or sets the minimum number of screen space objects that can be clustered. - * @memberof EntityCluster.prototype - * @type {Number} - */ - minimumClusterSize : { - get : function() { - return this._minimumClusterSize; - }, - set : function(value) { - this._clusterDirty = this._clusterDirty || value !== this._minimumClusterSize; - this._minimumClusterSize = value; - } - }, - /** - * Gets the event that will be raised when a new cluster will be displayed. The signature of the event listener is {@link EntityCluster~newClusterCallback}. - * @memberof EntityCluster.prototype - * @type {Event} - */ - clusterEvent : { - get : function() { - return this._clusterEvent; - } - }, - /** - * Gets or sets whether clustering billboard entities is enabled. - * @memberof EntityCluster.prototype - * @type {Boolean} - */ - clusterBillboards : { - get : function() { - return this._clusterBillboards; - }, - set : function(value) { - this._clusterDirty = this._clusterDirty || value !== this._clusterBillboards; - this._clusterBillboards = value; - } - }, - /** - * Gets or sets whether clustering labels entities is enabled. - * @memberof EntityCluster.prototype - * @type {Boolean} - */ - clusterLabels : { - get : function() { - return this._clusterLabels; - }, - set : function(value) { - this._clusterDirty = this._clusterDirty || value !== this._clusterLabels; - this._clusterLabels = value; - } - }, - /** - * Gets or sets whether clustering point entities is enabled. - * @memberof EntityCluster.prototype - * @type {Boolean} - */ - clusterPoints : { - get : function() { - return this._clusterPoints; - }, - set : function(value) { - this._clusterDirty = this._clusterDirty || value !== this._clusterPoints; - this._clusterPoints = value; - } + var translucentBatches = this._translucentBatches.values; + var translucentBatchesLength = translucentBatches.length; + for (i = 0; i < translucentBatchesLength; i++) { + translucentBatches[i].removeAllPrimitives(); } - }); + }; - function createGetEntity(collectionProperty, CollectionConstructor, unusedIndicesProperty, entityIndexProperty) { - return function(entity) { - var collection = this[collectionProperty]; + return StaticOutlineGeometryBatch; +}); - if (!defined(this._collectionIndicesByEntity)) { - this._collectionIndicesByEntity = {}; - } +define('DataSources/GeometryVisualizer',[ + '../Core/AssociativeArray', + '../Core/BoundingSphere', + '../Core/defined', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Scene/ShadowMode', + './BoundingSphereState', + './ColorMaterialProperty', + './StaticGeometryColorBatch', + './StaticGeometryPerMaterialBatch', + './StaticGroundGeometryColorBatch', + './StaticOutlineGeometryBatch' + ], function( + AssociativeArray, + BoundingSphere, + defined, + destroyObject, + DeveloperError, + ShadowMode, + BoundingSphereState, + ColorMaterialProperty, + StaticGeometryColorBatch, + StaticGeometryPerMaterialBatch, + StaticGroundGeometryColorBatch, + StaticOutlineGeometryBatch) { + 'use strict'; - var entityIndices = this._collectionIndicesByEntity[entity.id]; + var emptyArray = []; - if (!defined(entityIndices)) { - entityIndices = this._collectionIndicesByEntity[entity.id] = { - billboardIndex: undefined, - labelIndex: undefined, - pointIndex: undefined - }; - } + function DynamicGeometryBatch(primitives, groundPrimitives) { + this._primitives = primitives; + this._groundPrimitives = groundPrimitives; + this._dynamicUpdaters = new AssociativeArray(); + } + DynamicGeometryBatch.prototype.add = function(time, updater) { + this._dynamicUpdaters.set(updater.entity.id, updater.createDynamicUpdater(this._primitives, this._groundPrimitives)); + }; - if (defined(collection) && defined(entityIndices[entityIndexProperty])) { - return collection.get(entityIndices[entityIndexProperty]); - } + DynamicGeometryBatch.prototype.remove = function(updater) { + var id = updater.entity.id; + var dynamicUpdater = this._dynamicUpdaters.get(id); + if (defined(dynamicUpdater)) { + this._dynamicUpdaters.remove(id); + dynamicUpdater.destroy(); + } + }; - if (!defined(collection)) { - collection = this[collectionProperty] = new CollectionConstructor({ - scene : this._scene - }); - } + DynamicGeometryBatch.prototype.update = function(time) { + var geometries = this._dynamicUpdaters.values; + for (var i = 0, len = geometries.length; i < len; i++) { + geometries[i].update(time); + } + return true; + }; - var index; - var entityItem; + DynamicGeometryBatch.prototype.removeAllPrimitives = function() { + var geometries = this._dynamicUpdaters.values; + for (var i = 0, len = geometries.length; i < len; i++) { + geometries[i].destroy(); + } + this._dynamicUpdaters.removeAll(); + }; - var unusedIndices = this[unusedIndicesProperty]; - if (unusedIndices.length > 0) { - index = unusedIndices.pop(); - entityItem = collection.get(index); - } else { - entityItem = collection.add(); - index = collection.length - 1; - } + DynamicGeometryBatch.prototype.getBoundingSphere = function(entity, result) { + var updater = this._dynamicUpdaters.get(entity.id); + if (defined(updater) && defined(updater.getBoundingSphere)) { + return updater.getBoundingSphere(entity, result); + } + return BoundingSphereState.FAILED; + }; - entityIndices[entityIndexProperty] = index; + function removeUpdater(that, updater) { + //We don't keep track of which batch an updater is in, so just remove it from all of them. + var batches = that._batches; + var length = batches.length; + for (var i = 0; i < length; i++) { + batches[i].remove(updater); + } + } - this._clusterDirty = true; + function insertUpdaterIntoBatch(that, time, updater) { + if (updater.isDynamic) { + that._dynamicBatch.add(time, updater); + return; + } - return entityItem; - }; - } + var shadows; + if (updater.outlineEnabled || updater.fillEnabled) { + shadows = updater.shadowsProperty.getValue(time); + } - function removeEntityIndicesIfUnused(entityCluster, entityId) { - var indices = entityCluster._collectionIndicesByEntity[entityId]; + if (updater.outlineEnabled) { + that._outlineBatches[shadows].add(time, updater); + } - if (!defined(indices.billboardIndex) && !defined(indices.labelIndex) && !defined(indices.pointIndex)) { - delete entityCluster._collectionIndicesByEntity[entityId]; + var multiplier = 0; + if (defined(updater.depthFailMaterialProperty)) { + multiplier = updater.depthFailMaterialProperty instanceof ColorMaterialProperty ? 1 : 2; } - } - /** - * Returns a new {@link Label}. - * @param {Entity} entity The entity that will use the returned {@link Label} for visualization. - * @returns {Label} The label that will be used to visualize an entity. - * - * @private - */ - EntityCluster.prototype.getLabel = createGetEntity('_labelCollection', LabelCollection, '_unusedLabelIndices', 'labelIndex'); + var index; + if (defined(shadows)) { + index = shadows + multiplier * ShadowMode.NUMBER_OF_SHADOW_MODES; + } + if (updater.fillEnabled) { + if (updater.onTerrain) { + that._groundColorBatch.add(time, updater); + } else if (updater.isClosed) { + if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { + that._closedColorBatches[index].add(time, updater); + } else { + that._closedMaterialBatches[index].add(time, updater); + } + } else if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { + that._openColorBatches[index].add(time, updater); + } else { + that._openMaterialBatches[index].add(time, updater); + } + } + } /** - * Removes the {@link Label} associated with an entity so it can be reused by another entity. - * @param {Entity} entity The entity that will uses the returned {@link Label} for visualization. + * A general purpose visualizer for geometry represented by {@link Primitive} instances. + * @alias GeometryVisualizer + * @constructor * - * @private + * @param {GeometryUpdater} type The updater to be used for creating the geometry. + * @param {Scene} scene The scene the primitives will be rendered in. + * @param {EntityCollection} entityCollection The entityCollection to visualize. */ - EntityCluster.prototype.removeLabel = function(entity) { - var entityIndices = this._collectionIndicesByEntity && this._collectionIndicesByEntity[entity.id]; - if (!defined(this._labelCollection) || !defined(entityIndices) || !defined(entityIndices.labelIndex)) { - return; + function GeometryVisualizer(type, scene, entityCollection) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); } + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + if (!defined(entityCollection)) { + throw new DeveloperError('entityCollection is required.'); + } + + this._type = type; - var index = entityIndices.labelIndex; - entityIndices.labelIndex = undefined; - removeEntityIndicesIfUnused(this, entity.id); - - var label = this._labelCollection.get(index); - label.show = false; - label.text = ''; - label.id = undefined; + var primitives = scene.primitives; + var groundPrimitives = scene.groundPrimitives; + this._scene = scene; + this._primitives = primitives; + this._groundPrimitives = groundPrimitives; + this._entityCollection = undefined; + this._addedObjects = new AssociativeArray(); + this._removedObjects = new AssociativeArray(); + this._changedObjects = new AssociativeArray(); - this._unusedLabelIndices.push(index); + var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES; + this._outlineBatches = new Array(numberOfShadowModes); + this._closedColorBatches = new Array(numberOfShadowModes * 3); + this._closedMaterialBatches = new Array(numberOfShadowModes * 3); + this._openColorBatches = new Array(numberOfShadowModes * 3); + this._openMaterialBatches = new Array(numberOfShadowModes * 3); - this._clusterDirty = true; - }; + for (var i = 0; i < numberOfShadowModes; ++i) { + this._outlineBatches[i] = new StaticOutlineGeometryBatch(primitives, scene, i); - /** - * Returns a new {@link Billboard}. - * @param {Entity} entity The entity that will use the returned {@link Billboard} for visualization. - * @returns {Billboard} The label that will be used to visualize an entity. - * - * @private - */ - EntityCluster.prototype.getBillboard = createGetEntity('_billboardCollection', BillboardCollection, '_unusedBillboardIndices', 'billboardIndex'); + this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, undefined, true, i); + this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, undefined, true, i); + this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, undefined, false, i); + this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, undefined, false, i); + this._closedColorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.perInstanceColorAppearanceType, true, i); + this._closedMaterialBatches[i + numberOfShadowModes] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.perInstanceColorAppearanceType, true, i); + this._openColorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.perInstanceColorAppearanceType, false, i); + this._openMaterialBatches[i + numberOfShadowModes] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.perInstanceColorAppearanceType, false, i); - /** - * Removes the {@link Billboard} associated with an entity so it can be reused by another entity. - * @param {Entity} entity The entity that will uses the returned {@link Billboard} for visualization. - * - * @private - */ - EntityCluster.prototype.removeBillboard = function(entity) { - var entityIndices = this._collectionIndicesByEntity && this._collectionIndicesByEntity[entity.id]; - if (!defined(this._billboardCollection) || !defined(entityIndices) || !defined(entityIndices.billboardIndex)) { - return; + this._closedColorBatches[i + numberOfShadowModes * 2] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.materialAppearanceType, true, i); + this._closedMaterialBatches[i + numberOfShadowModes * 2] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.materialAppearanceType, true, i); + this._openColorBatches[i + numberOfShadowModes * 2] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.materialAppearanceType, false, i); + this._openMaterialBatches[i + numberOfShadowModes * 2] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.materialAppearanceType, false, i); } - var index = entityIndices.billboardIndex; - entityIndices.billboardIndex = undefined; - removeEntityIndicesIfUnused(this, entity.id); - - var billboard = this._billboardCollection.get(index); - billboard.id = undefined; - billboard.show = false; - billboard.image = undefined; + this._groundColorBatch = new StaticGroundGeometryColorBatch(groundPrimitives); + this._dynamicBatch = new DynamicGeometryBatch(primitives, groundPrimitives); - this._unusedBillboardIndices.push(index); + this._batches = this._outlineBatches.concat(this._closedColorBatches, this._closedMaterialBatches, this._openColorBatches, this._openMaterialBatches, this._groundColorBatch, this._dynamicBatch); - this._clusterDirty = true; - }; + this._subscriptions = new AssociativeArray(); + this._updaters = new AssociativeArray(); - /** - * Returns a new {@link Point}. - * @param {Entity} entity The entity that will use the returned {@link Point} for visualization. - * @returns {Point} The label that will be used to visualize an entity. - * - * @private - */ - EntityCluster.prototype.getPoint = createGetEntity('_pointCollection', PointPrimitiveCollection, '_unusedPointIndices', 'pointIndex'); + this._entityCollection = entityCollection; + entityCollection.collectionChanged.addEventListener(GeometryVisualizer.prototype._onCollectionChanged, this); + this._onCollectionChanged(entityCollection, entityCollection.values, emptyArray); + } /** - * Removes the {@link Point} associated with an entity so it can be reused by another entity. - * @param {Entity} entity The entity that will uses the returned {@link Point} for visualization. + * Updates all of the primitives created by this visualizer to match their + * Entity counterpart at the given time. * - * @private + * @param {JulianDate} time The time to update to. + * @returns {Boolean} True if the visualizer successfully updated to the provided time, + * false if the visualizer is waiting for asynchronous primitives to be created. */ - EntityCluster.prototype.removePoint = function(entity) { - var entityIndices = this._collectionIndicesByEntity && this._collectionIndicesByEntity[entity.id]; - if (!defined(this._pointCollection) || !defined(entityIndices) || !defined(entityIndices.pointIndex)) { - return; + GeometryVisualizer.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } + + var addedObjects = this._addedObjects; + var added = addedObjects.values; + var removedObjects = this._removedObjects; + var removed = removedObjects.values; + var changedObjects = this._changedObjects; + var changed = changedObjects.values; - var index = entityIndices.pointIndex; - entityIndices.pointIndex = undefined; - removeEntityIndicesIfUnused(this, entity.id); - - var point = this._pointCollection.get(index); - point.show = false; - point.id = undefined; - - this._unusedPointIndices.push(index); + var i; + var entity; + var id; + var updater; - this._clusterDirty = true; - }; + for (i = changed.length - 1; i > -1; i--) { + entity = changed[i]; + id = entity.id; + updater = this._updaters.get(id); - function disableCollectionClustering(collection) { - if (!defined(collection)) { - return; + //If in a single update, an entity gets removed and a new instance + //re-added with the same id, the updater no longer tracks the + //correct entity, we need to both remove the old one and + //add the new one, which is done by pushing the entity + //onto the removed/added lists. + if (updater.entity === entity) { + removeUpdater(this, updater); + insertUpdaterIntoBatch(this, time, updater); + } else { + removed.push(entity); + added.push(entity); + } } - var length = collection.length; - for (var i = 0; i < length; ++i) { - collection.get(i).clusterShow = true; + for (i = removed.length - 1; i > -1; i--) { + entity = removed[i]; + id = entity.id; + updater = this._updaters.get(id); + removeUpdater(this, updater); + updater.destroy(); + this._updaters.remove(id); + this._subscriptions.get(id)(); + this._subscriptions.remove(id); } - } - function updateEnable(entityCluster) { - if (entityCluster.enabled) { - return; + for (i = added.length - 1; i > -1; i--) { + entity = added[i]; + id = entity.id; + updater = new this._type(entity, this._scene); + this._updaters.set(id, updater); + insertUpdaterIntoBatch(this, time, updater); + this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometryChanged, this)); } - if (defined(entityCluster._clusterLabelCollection)) { - entityCluster._clusterLabelCollection.destroy(); - } - if (defined(entityCluster._clusterBillboardCollection)) { - entityCluster._clusterBillboardCollection.destroy(); - } - if (defined(entityCluster._clusterPointCollection)) { - entityCluster._clusterPointCollection.destroy(); + addedObjects.removeAll(); + removedObjects.removeAll(); + changedObjects.removeAll(); + + var isUpdated = true; + var batches = this._batches; + var length = batches.length; + for (i = 0; i < length; i++) { + isUpdated = batches[i].update(time) && isUpdated; } - entityCluster._clusterLabelCollection = undefined; - entityCluster._clusterBillboardCollection = undefined; - entityCluster._clusterPointCollection = undefined; + return isUpdated; + }; - disableCollectionClustering(entityCluster._labelCollection); - disableCollectionClustering(entityCluster._billboardCollection); - disableCollectionClustering(entityCluster._pointCollection); - } + var getBoundingSphereArrayScratch = []; + var getBoundingSphereBoundingSphereScratch = new BoundingSphere(); /** - * Gets the draw commands for the clustered billboards/points/labels if enabled, otherwise, - * queues the draw commands for billboards/points/labels created for entities. + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. + * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. * @private */ - EntityCluster.prototype.update = function(frameState) { - // If clustering is enabled before the label collection is updated, - // the glyphs haven't been created so the screen space bounding boxes - // are incorrect. - var commandList; - if (defined(this._labelCollection) && this._labelCollection.length > 0 && this._labelCollection.get(0)._glyphs.length === 0) { - commandList = frameState.commandList; - frameState.commandList = []; - this._labelCollection.update(frameState); - frameState.commandList = commandList; + GeometryVisualizer.prototype.getBoundingSphere = function(entity, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); } - - // If clustering is enabled before the billboard collection is updated, - // the images haven't been added to the image atlas so the screen space bounding boxes - // are incorrect. - if (defined(this._billboardCollection) && this._billboardCollection.length > 0 && !defined(this._billboardCollection.get(0).width)) { - commandList = frameState.commandList; - frameState.commandList = []; - this._billboardCollection.update(frameState); - frameState.commandList = commandList; + if (!defined(result)) { + throw new DeveloperError('result is required.'); } + + var boundingSpheres = getBoundingSphereArrayScratch; + var tmp = getBoundingSphereBoundingSphereScratch; - if (this._enabledDirty) { - this._enabledDirty = false; - updateEnable(this); - this._clusterDirty = true; - } + var count = 0; + var state = BoundingSphereState.DONE; + var batches = this._batches; + var batchesLength = batches.length; - if (this._clusterDirty) { - this._clusterDirty = false; - this._cluster(); + for (var i = 0; i < batchesLength; i++) { + state = batches[i].getBoundingSphere(entity, tmp); + if (state === BoundingSphereState.PENDING) { + return BoundingSphereState.PENDING; + } else if (state === BoundingSphereState.DONE) { + boundingSpheres[count] = BoundingSphere.clone(tmp, boundingSpheres[count]); + count++; + } } - if (defined(this._clusterLabelCollection)) { - this._clusterLabelCollection.update(frameState); - } - if (defined(this._clusterBillboardCollection)) { - this._clusterBillboardCollection.update(frameState); - } - if (defined(this._clusterPointCollection)) { - this._clusterPointCollection.update(frameState); + if (count === 0) { + return BoundingSphereState.FAILED; } - if (defined(this._labelCollection)) { - this._labelCollection.update(frameState); - } - if (defined(this._billboardCollection)) { - this._billboardCollection.update(frameState); - } - if (defined(this._pointCollection)) { - this._pointCollection.update(frameState); - } + boundingSpheres.length = count; + BoundingSphere.fromBoundingSpheres(boundingSpheres, result); + return BoundingSphereState.DONE; }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <p> - * Unlike other objects that use WebGL resources, this object can be reused. For example, if a data source is removed - * from a data source collection and added to another. - * </p> + * Returns true if this object was destroyed; otherwise, false. * - * @returns {undefined} + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - EntityCluster.prototype.destroy = function() { - this._labelCollection = this._labelCollection && this._labelCollection.destroy(); - this._billboardCollection = this._billboardCollection && this._billboardCollection.destroy(); - this._pointCollection = this._pointCollection && this._pointCollection.destroy(); + GeometryVisualizer.prototype.isDestroyed = function() { + return false; + }; - this._clusterLabelCollection = this._clusterLabelCollection && this._clusterLabelCollection.destroy(); - this._clusterBillboardCollection = this._clusterBillboardCollection && this._clusterBillboardCollection.destroy(); - this._clusterPointCollection = this._clusterPointCollection && this._clusterPointCollection.destroy(); + /** + * Removes and destroys all primitives created by this instance. + */ + GeometryVisualizer.prototype.destroy = function() { + this._entityCollection.collectionChanged.removeEventListener(GeometryVisualizer.prototype._onCollectionChanged, this); + this._addedObjects.removeAll(); + this._removedObjects.removeAll(); - if (defined(this._removeEventListener)) { - this._removeEventListener(); - this._removeEventListener = undefined; + var i; + var batches = this._batches; + var length = batches.length; + for (i = 0; i < length; i++) { + batches[i].removeAllPrimitives(); } - this._labelCollection = undefined; - this._billboardCollection = undefined; - this._pointCollection = undefined; - - this._clusterBillboardCollection = undefined; - this._clusterLabelCollection = undefined; - this._clusterPointCollection = undefined; - - this._collectionIndicesByEntity = undefined; - - this._unusedLabelIndices = []; - this._unusedBillboardIndices = []; - this._unusedPointIndices = []; - - this._previousClusters = []; - this._previousHeight = undefined; - - this._enabledDirty = false; - this._pixelRangeDirty = false; - this._minimumClusterSizeDirty = false; - - return undefined; + var subscriptions = this._subscriptions.values; + length = subscriptions.length; + for (i = 0; i < length; i++) { + subscriptions[i](); + } + this._subscriptions.removeAll(); + return destroyObject(this); }; /** - * A event listener function used to style clusters. - * @callback EntityCluster~newClusterCallback - * - * @param {Entity[]} clusteredEntities An array of the entities contained in the cluster. - * @param {Object} cluster An object containing billboard, label, and point properties. The values are the same as - * billboard, label and point entities, but must be the values of the ConstantProperty. - * - * @example - * // The default cluster values. - * dataSource.clustering.clusterEvent.addEventListener(function(entities, cluster) { - * cluster.label.show = true; - * cluster.label.text = entities.length.toLocaleString(); - * }); + * @private */ + GeometryVisualizer._onGeometryChanged = function(updater) { + var removedObjects = this._removedObjects; + var changedObjects = this._changedObjects; - return EntityCluster; -}); + var entity = updater.entity; + var id = entity.id; -define('DataSources/CustomDataSource',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - './DataSource', - './EntityCluster', - './EntityCollection' - ], function( - defined, - defineProperties, - DeveloperError, - Event, - DataSource, - EntityCluster, - EntityCollection) { - 'use strict'; + if (!defined(removedObjects.get(id)) && !defined(changedObjects.get(id))) { + changedObjects.set(id, entity); + } + }; /** - * A {@link DataSource} implementation which can be used to manually manage a group of entities. - * - * @alias CustomDataSource - * @constructor - * - * @param {String} [name] A human-readable name for this instance. - * - * @example - * var dataSource = new Cesium.CustomDataSource('myData'); - * - * var entity = dataSource.entities.add({ - * position : Cesium.Cartesian3.fromDegrees(1, 2, 0), - * billboard : { - * image : 'image.png' - * } - * }); - * - * viewer.dataSources.add(dataSource); + * @private */ - function CustomDataSource(name) { - this._name = name; - this._clock = undefined; - this._changed = new Event(); - this._error = new Event(); - this._isLoading = false; - this._loading = new Event(); - this._entityCollection = new EntityCollection(this); - this._entityCluster = new EntityCluster(); - } + GeometryVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed) { + var addedObjects = this._addedObjects; + var removedObjects = this._removedObjects; + var changedObjects = this._changedObjects; - defineProperties(CustomDataSource.prototype, { - /** - * Gets or sets a human-readable name for this instance. - * @memberof CustomDataSource.prototype - * @type {String} - */ - name : { - get : function() { - return this._name; - }, - set : function(value) { - if (this._name !== value) { - this._name = value; - this._changed.raiseEvent(this); - } - } - }, - /** - * Gets or sets the clock for this instance. - * @memberof CustomDataSource.prototype - * @type {DataSourceClock} - */ - clock : { - get : function() { - return this._clock; - }, - set : function(value) { - if (this._clock !== value) { - this._clock = value; - this._changed.raiseEvent(this); - } - } - }, - /** - * Gets the collection of {@link Entity} instances. - * @memberof CustomDataSource.prototype - * @type {EntityCollection} - */ - entities : { - get : function() { - return this._entityCollection; - } - }, - /** - * Gets or sets whether the data source is currently loading data. - * @memberof CustomDataSource.prototype - * @type {Boolean} - */ - isLoading : { - get : function() { - return this._isLoading; - }, - set : function(value) { - DataSource.setLoading(this, value); - } - }, - /** - * Gets an event that will be raised when the underlying data changes. - * @memberof CustomDataSource.prototype - * @type {Event} - */ - changedEvent : { - get : function() { - return this._changed; - } - }, - /** - * Gets an event that will be raised if an error is encountered during processing. - * @memberof CustomDataSource.prototype - * @type {Event} - */ - errorEvent : { - get : function() { - return this._error; - } - }, - /** - * Gets an event that will be raised when the data source either starts or stops loading. - * @memberof CustomDataSource.prototype - * @type {Event} - */ - loadingEvent : { - get : function() { - return this._loading; - } - }, - /** - * Gets whether or not this data source should be displayed. - * @memberof CustomDataSource.prototype - * @type {Boolean} - */ - show : { - get : function() { - return this._entityCollection.show; - }, - set : function(value) { - this._entityCollection.show = value; + var i; + var id; + var entity; + for (i = removed.length - 1; i > -1; i--) { + entity = removed[i]; + id = entity.id; + if (!addedObjects.remove(id)) { + removedObjects.set(id, entity); + changedObjects.remove(id); } - }, + } - /** - * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. - * - * @memberof CustomDataSource.prototype - * @type {EntityCluster} - */ - clustering : { - get : function() { - return this._entityCluster; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value must be defined.'); - } - this._entityCluster = value; + for (i = added.length - 1; i > -1; i--) { + entity = added[i]; + id = entity.id; + if (removedObjects.remove(id)) { + changedObjects.set(id, entity); + } else { + addedObjects.set(id, entity); } } - }); + }; - return CustomDataSource; + return GeometryVisualizer; }); -define('DataSources/CylinderGeometryUpdater',[ +define('DataSources/LabelVisualizer',[ + '../Core/AssociativeArray', + '../Core/Cartesian2', + '../Core/Cartesian3', '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/CylinderGeometry', - '../Core/CylinderOutlineGeometry', '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', + '../Core/NearFarScalar', + '../Scene/HeightReference', + '../Scene/HorizontalOrigin', + '../Scene/LabelStyle', + '../Scene/VerticalOrigin', + './BoundingSphereState', './Property' ], function( - Color, - ColorGeometryInstanceAttribute, - CylinderGeometry, - CylinderOutlineGeometry, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - ShowGeometryInstanceAttribute, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, + AssociativeArray, + Cartesian2, + Cartesian3, + Color, + defaultValue, + defined, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + NearFarScalar, + HeightReference, + HorizontalOrigin, + LabelStyle, + VerticalOrigin, + BoundingSphereState, Property) { 'use strict'; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var defaultScale = 1.0; + var defaultFont = '30px sans-serif'; + var defaultStyle = LabelStyle.FILL; + var defaultFillColor = Color.WHITE; + var defaultOutlineColor = Color.BLACK; + var defaultOutlineWidth = 1.0; + var defaultShowBackground = false; + var defaultBackgroundColor = new Color(0.165, 0.165, 0.165, 0.8); + var defaultBackgroundPadding = new Cartesian2(7, 5); + var defaultPixelOffset = Cartesian2.ZERO; + var defaultEyeOffset = Cartesian3.ZERO; + var defaultHeightReference = HeightReference.NONE; + var defaultHorizontalOrigin = HorizontalOrigin.CENTER; + var defaultVerticalOrigin = VerticalOrigin.CENTER; + var defaultDisableDepthTestDistance = 0.0; - var scratchColor = new Color(); + var position = new Cartesian3(); + var fillColor = new Color(); + var outlineColor = new Color(); + var backgroundColor = new Color(); + var backgroundPadding = new Cartesian2(); + var eyeOffset = new Cartesian3(); + var pixelOffset = new Cartesian2(); + var translucencyByDistance = new NearFarScalar(); + var pixelOffsetScaleByDistance = new NearFarScalar(); + var scaleByDistance = new NearFarScalar(); + var distanceDisplayCondition = new DistanceDisplayCondition(); - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.length = undefined; - this.topRadius = undefined; - this.bottomRadius = undefined; - this.slices = undefined; - this.numberOfVerticalLines = undefined; + function EntityData(entity) { + this.entity = entity; + this.label = undefined; + this.index = undefined; } /** - * A {@link GeometryUpdater} for cylinders. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias CylinderGeometryUpdater + * A {@link Visualizer} which maps the {@link LabelGraphics} instance + * in {@link Entity#label} to a {@link Label}. + * @alias LabelVisualizer * @constructor * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. + * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities. + * @param {EntityCollection} entityCollection The entityCollection to visualize. */ - function CylinderGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); + function LabelVisualizer(entityCluster, entityCollection) { + if (!defined(entityCluster)) { + throw new DeveloperError('entityCluster is required.'); } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + if (!defined(entityCollection)) { + throw new DeveloperError('entityCollection is required.'); } - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(CylinderGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'cylinder', entity.cylinder, undefined); + entityCollection.collectionChanged.addEventListener(LabelVisualizer.prototype._onCollectionChanged, this); + + this._cluster = entityCluster; + this._entityCollection = entityCollection; + this._items = new AssociativeArray(); + + this._onCollectionChanged(entityCollection, entityCollection.values, [], []); } - defineProperties(CylinderGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof CylinderGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof CylinderGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance + /** + * Updates the primitives created by this visualizer to match their + * Entity counterpart at the given time. + * + * @param {JulianDate} time The time to update to. + * @returns {Boolean} This function always returns true. + */ + LabelVisualizer.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - }); + + var items = this._items.values; + var cluster = this._cluster; - defineProperties(CylinderGeometryUpdater.prototype, { - /** - * Gets the entity associated with this geometry. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Entity} - * @readonly - */ - entity : { - get : function() { - return this._entity; - } - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, - /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, - /** - * Gets the material property used to fill the geometry. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly - */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, - /** - * Gets a value indicating if outline visibility varies with simulation time. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); - } - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - outlineColorProperty : { - get : function() { - return this._outlineColorProperty; - } - }, - /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Number} - * @readonly - */ - outlineWidth : { - get : function() { - return this._outlineWidth; - } - }, - /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + var entity = item.entity; + var labelGraphics = entity._label; + var text; + var label = item.label; + var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(labelGraphics._show, time, true); + + if (show) { + position = Property.getValueOrUndefined(entity._position, time, position); + text = Property.getValueOrUndefined(labelGraphics._text, time); + show = defined(position) && defined(text); } - }, - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayConditionProperty; + + if (!show) { + //don't bother creating or updating anything else + returnPrimitive(item, entity, cluster); + continue; } - }, - /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isDynamic : { - get : function() { - return this._dynamic; + + if (!Property.isConstant(entity._position)) { + cluster._clusterDirty = true; } - }, - /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isClosed : { - value : true - }, - /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof CylinderGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - geometryChanged : { - get : function() { - return this._geometryChanged; + + if (!defined(label)) { + label = cluster.getLabel(entity); + label.id = entity; + item.label = label; } + + label.show = true; + label.position = position; + label.text = text; + label.scale = Property.getValueOrDefault(labelGraphics._scale, time, defaultScale); + label.font = Property.getValueOrDefault(labelGraphics._font, time, defaultFont); + label.style = Property.getValueOrDefault(labelGraphics._style, time, defaultStyle); + label.fillColor = Property.getValueOrDefault(labelGraphics._fillColor, time, defaultFillColor, fillColor); + label.outlineColor = Property.getValueOrDefault(labelGraphics._outlineColor, time, defaultOutlineColor, outlineColor); + label.outlineWidth = Property.getValueOrDefault(labelGraphics._outlineWidth, time, defaultOutlineWidth); + label.showBackground = Property.getValueOrDefault(labelGraphics._showBackground, time, defaultShowBackground); + label.backgroundColor = Property.getValueOrDefault(labelGraphics._backgroundColor, time, defaultBackgroundColor, backgroundColor); + label.backgroundPadding = Property.getValueOrDefault(labelGraphics._backgroundPadding, time, defaultBackgroundPadding, backgroundPadding); + label.pixelOffset = Property.getValueOrDefault(labelGraphics._pixelOffset, time, defaultPixelOffset, pixelOffset); + label.eyeOffset = Property.getValueOrDefault(labelGraphics._eyeOffset, time, defaultEyeOffset, eyeOffset); + label.heightReference = Property.getValueOrDefault(labelGraphics._heightReference, time, defaultHeightReference); + label.horizontalOrigin = Property.getValueOrDefault(labelGraphics._horizontalOrigin, time, defaultHorizontalOrigin); + label.verticalOrigin = Property.getValueOrDefault(labelGraphics._verticalOrigin, time, defaultVerticalOrigin); + label.translucencyByDistance = Property.getValueOrUndefined(labelGraphics._translucencyByDistance, time, translucencyByDistance); + label.pixelOffsetScaleByDistance = Property.getValueOrUndefined(labelGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance); + label.scaleByDistance = Property.getValueOrUndefined(labelGraphics._scaleByDistance, time, scaleByDistance); + label.distanceDisplayCondition = Property.getValueOrUndefined(labelGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + label.disableDepthTestDistance = Property.getValueOrDefault(labelGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); } - }); + return true; + }; /** - * Checks if the geometry is outlined at the provided time. + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private */ - CylinderGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + LabelVisualizer.prototype.getBoundingSphere = function(entity, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var item = this._items.get(entity.id); + if (!defined(item) || !defined(item.label)) { + return BoundingSphereState.FAILED; + } + + var label = item.label; + result.center = Cartesian3.clone(defaultValue(label._clampedPosition, label.position), result.center); + result.radius = 0; + return BoundingSphereState.DONE; }; /** - * Checks if the geometry is filled at the provided time. + * Returns true if this object was destroyed; otherwise, false. * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - CylinderGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + LabelVisualizer.prototype.isDestroyed = function() { + return false; }; /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. + * Removes and destroys all primitives created by this instance. */ - CylinderGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + LabelVisualizer.prototype.destroy = function() { + this._entityCollection.collectionChanged.removeEventListener(LabelVisualizer.prototype._onCollectionChanged, this); + var entities = this._entityCollection.values; + for (var i = 0; i < entities.length; i++) { + this._cluster.removeLabel(entities[i]); } + return destroyObject(this); + }; - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); + LabelVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { + var i; + var entity; + var items = this._items; + var cluster = this._cluster; - var attributes; + for (i = added.length - 1; i > -1; i--) { + entity = added[i]; + if (defined(entity._label) && defined(entity._position)) { + items.set(entity.id, new EntityData(entity)); + } + } - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); + for (i = changed.length - 1; i > -1; i--) { + entity = changed[i]; + if (defined(entity._label) && defined(entity._position)) { + if (!items.contains(entity.id)) { + items.set(entity.id, new EntityData(entity)); + } + } else { + returnPrimitive(items.get(entity.id), entity, cluster); + items.remove(entity.id); } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; } - return new GeometryInstance({ - id : entity, - geometry : new CylinderGeometry(this._options), - modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), - attributes : attributes - }); + for (i = removed.length - 1; i > -1; i--) { + entity = removed[i]; + returnPrimitive(items.get(entity.id), entity, cluster); + items.remove(entity.id); + } }; + function returnPrimitive(item, entity, cluster) { + if (defined(item)) { + item.label = undefined; + cluster.removeLabel(entity); + } + } + + return LabelVisualizer; +}); + +define('ThirdParty/GltfPipeline/addToArray',[], function() { + 'use strict'; + + function addToArray(array, element) { + array.push(element); + return array.length - 1; + } + return addToArray; +}); + +define('ThirdParty/GltfPipeline/ForEach',[ + '../../Core/defined' + ], function( + defined) { + 'use strict'; + /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. + * Contains traversal functions for processing elements of the glTF hierarchy. */ - CylinderGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + var ForEach = {}; - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + ForEach.object = function(arrayOfObjects, handler) { + if (defined(arrayOfObjects)) { + for (var i = 0; i < arrayOfObjects.length; i++) { + var object = arrayOfObjects[i]; + var returnValue = handler(object, i); + if (typeof returnValue === 'number') { + i += returnValue; + } + else if (returnValue) { + break; + } + } } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + }; - return new GeometryInstance({ - id : entity, - geometry : new CylinderOutlineGeometry(this._options), - modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) - } - }); + ForEach.topLevel = function(gltf, name, handler) { + var arrayOfObjects = gltf[name]; + ForEach.object(arrayOfObjects, handler); }; - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - CylinderGeometryUpdater.prototype.isDestroyed = function() { - return false; + ForEach.accessor = function(gltf, handler) { + ForEach.topLevel(gltf, 'accessors', handler); }; - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - CylinderGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); + ForEach.accessorWithSemantic = function(gltf, semantic, handler) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) { + if (attributeSemantic.indexOf(semantic) === 0) { + handler(accessorId, attributeSemantic, primitive); + } + }); + }); + }); }; - CylinderGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'cylinder')) { - return; + ForEach.animation = function(gltf, handler) { + ForEach.topLevel(gltf, 'animations', handler); + }; + + ForEach.animationSampler = function(animation, handler) { + var samplers = animation.samplers; + if (defined(samplers)) { + ForEach.object(samplers, handler); } + }; - var cylinder = entity.cylinder; + ForEach.buffer = function(gltf, handler) { + ForEach.topLevel(gltf, 'buffers', handler); + }; - if (!defined(cylinder)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + ForEach.bufferView = function(gltf, handler) { + ForEach.topLevel(gltf, 'bufferViews', handler); + }; - var fillProperty = cylinder.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + ForEach.camera = function(gltf, handler) { + ForEach.topLevel(gltf, 'cameras', handler); + }; - var outlineProperty = cylinder.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); - } + ForEach.image = function(gltf, handler) { + ForEach.topLevel(gltf, 'images', handler); + }; - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + ForEach.material = function(gltf, handler) { + ForEach.topLevel(gltf, 'materials', handler); + }; + + ForEach.materialValue = function(material, handler) { + var values = material.values; + if (defined(values)) { + for (var name in values) { + if (values.hasOwnProperty(name)) { + handler(values[name], name); + } } - return; } + }; - var position = entity.position; - var length = cylinder.length; - var topRadius = cylinder.topRadius; - var bottomRadius = cylinder.bottomRadius; + ForEach.mesh = function(gltf, handler) { + ForEach.topLevel(gltf, 'meshes', handler); + }; - var show = cylinder.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(position) || !defined(length) || !defined(topRadius) || !defined(bottomRadius))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + ForEach.meshPrimitive = function(mesh, handler) { + var primitives = mesh.primitives; + if (defined(primitives)) { + var primitivesLength = primitives.length; + for (var i = 0; i < primitivesLength; i++) { + var primitive = primitives[i]; + handler(primitive, i); } - return; } + }; - var material = defaultValue(cylinder.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(cylinder.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(cylinder.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(cylinder.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(cylinder.distanceDisplayCondition, defaultDistanceDisplayCondition); + ForEach.meshPrimitiveAttribute = function(primitive, handler) { + var attributes = primitive.attributes; + if (defined(attributes)) { + for (var semantic in attributes) { + if (attributes.hasOwnProperty(semantic)) { + handler(attributes[semantic], semantic); + } + } + } + }; - var slices = cylinder.slices; - var outlineWidth = cylinder.outlineWidth; - var numberOfVerticalLines = cylinder.numberOfVerticalLines; + ForEach.meshPrimitiveTargetAttribute = function(primitive, handler) { + var targets = primitive.targets; + if (defined(targets)) { + for (var targetId in targets) { + if (targets.hasOwnProperty(targetId)) { + var target = targets[targetId]; + for (var attributeId in target) { + if (target.hasOwnProperty(attributeId) && attributeId !== 'extras') { + handler(target[attributeId], attributeId); + } + } + } + } + } + }; - this._fillEnabled = fillEnabled; - this._outlineEnabled = outlineEnabled; + ForEach.node = function(gltf, handler) { + ForEach.topLevel(gltf, 'nodes', handler); + }; - if (!position.isConstant || // - !Property.isConstant(entity.orientation) || // - !length.isConstant || // - !topRadius.isConstant || // - !bottomRadius.isConstant || // - !Property.isConstant(slices) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(numberOfVerticalLines)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + ForEach.nodeInTree = function(gltf, nodeIds, handler) { + var nodes = gltf.nodes; + if (defined(nodes)) { + for (var i = 0; i < nodeIds.length; i++) { + var nodeId = nodeIds[i]; + var node = nodes[nodeId]; + if (defined(node)) { + handler(node, nodeId); + var children = node.children; + if (defined(children)) { + ForEach.nodeInTree(gltf, children, handler); + } + } } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.length = length.getValue(Iso8601.MINIMUM_VALUE); - options.topRadius = topRadius.getValue(Iso8601.MINIMUM_VALUE); - options.bottomRadius = bottomRadius.getValue(Iso8601.MINIMUM_VALUE); - options.slices = defined(slices) ? slices.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); } }; - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - CylinderGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); + ForEach.nodeInScene = function(gltf, scene, handler) { + var sceneNodeIds = scene.nodes; + if (defined(sceneNodeIds)) { + ForEach.nodeInTree(gltf, sceneNodeIds, handler); } + }; - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); - } - - return new DynamicGeometryUpdater(primitives, this); + ForEach.program = function(gltf, handler) { + ForEach.topLevel(gltf, 'programs', handler); }; - /** - * @private - */ - function DynamicGeometryUpdater(primitives, geometryUpdater) { - this._primitives = primitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); - } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._primitive = undefined; - this._outlinePrimitive = undefined; + ForEach.sampler = function(gltf, handler) { + ForEach.topLevel(gltf, 'samplers', handler); + }; - var geometryUpdater = this._geometryUpdater; - var entity = geometryUpdater._entity; - var cylinder = entity.cylinder; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(cylinder.show, time, true)) { - return; + ForEach.scene = function(gltf, handler) { + ForEach.topLevel(gltf, 'scenes', handler); + }; + + ForEach.shader = function(gltf, handler) { + ForEach.topLevel(gltf, 'shaders', handler); + }; + + ForEach.skin = function(gltf, handler) { + ForEach.topLevel(gltf, 'skins', handler); + }; + + ForEach.techniqueAttribute = function(technique, handler) { + var attributes = technique.attributes; + if (defined(attributes)) { + for (var semantic in attributes) { + if (attributes.hasOwnProperty(semantic)) { + if (handler(attributes[semantic], semantic)) { + break; + } + } + } } + }; - var options = this._options; - var modelMatrix = entity.computeModelMatrix(time); - var length = Property.getValueOrUndefined(cylinder.length, time); - var topRadius = Property.getValueOrUndefined(cylinder.topRadius, time); - var bottomRadius = Property.getValueOrUndefined(cylinder.bottomRadius, time); - if (!defined(modelMatrix) || !defined(length) || !defined(topRadius) || !defined(bottomRadius)) { - return; + ForEach.techniqueParameter = function(technique, handler) { + var parameters = technique.parameters; + if (defined(parameters)) { + for (var parameterName in parameters) { + if (parameters.hasOwnProperty(parameterName)) { + if (handler(parameters[parameterName], parameterName)) { + break; + } + } + } } + }; - options.length = length; - options.topRadius = topRadius; - options.bottomRadius = bottomRadius; - options.slices = Property.getValueOrUndefined(cylinder.slices, time); - options.numberOfVerticalLines = Property.getValueOrUndefined(cylinder.numberOfVerticalLines, time); + ForEach.technique = function(gltf, handler) { + ForEach.topLevel(gltf, 'techniques', handler); + }; - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + ForEach.texture = function(gltf, handler) { + ForEach.topLevel(gltf, 'textures', handler); + }; - var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + return ForEach; +}); - if (Property.getValueOrDefault(cylinder.fill, time, true)) { - var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - this._material = material; +define('ThirdParty/GltfPipeline/addDefaults',[ + './addToArray', + './ForEach', + '../../Core/clone', + '../../Core/defaultValue', + '../../Core/defined', + '../../Core/WebGLConstants' + ], function( + addToArray, + ForEach, + clone, + defaultValue, + defined, + WebGLConstants) { + 'use strict'; - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : true - }); - options.vertexFormat = appearance.vertexFormat; + var gltfTemplate = { + accessors: [], + animations : [ + { + channels : [], + samplers : [ + { + interpolation : 'LINEAR' + } + ] + } + ], + asset : {}, + buffers : [ + { + byteLength: 0, + type: 'arraybuffer' + } + ], + bufferViews: [ + { + byteLength: 0 + } + ], + cameras: [], + images: [], + materials: [ + { + values: function(material) { + var extensions = defaultValue(material.extensions, {}); + var materialsCommon = extensions.KHR_materials_common; + if (!defined(materialsCommon)) { + return {}; + } + }, + extensions: function(material) { + var extensions = defaultValue(material.extensions, {}); + var materialsCommon = extensions.KHR_materials_common; + if (defined(materialsCommon)) { + var technique = materialsCommon.technique; + var defaults = { + ambient: [0.0, 0.0, 0.0, 1.0], + emission: [0.0, 0.0, 0.0, 1.0], + transparency: 1.0 + }; + if (technique !== 'CONSTANT') { + defaults.diffuse = [0.0, 0.0, 0.0, 1.0]; + if (technique !== 'LAMBERT') { + defaults.specular = [0.0, 0.0, 0.0, 1.0]; + defaults.shininess = 0.0; + } + } + return { + KHR_materials_common: { + doubleSided: false, + transparent: false, + values: defaults + } + }; + } + } + } + ], + meshes : [ + { + primitives : [ + { + attributes : {}, + mode : WebGLConstants.TRIANGLES + } + ] + } + ], + nodes : [ + { + children : [], + matrix : function(node) { + if (!defined(node.translation) && !defined(node.rotation) && !defined(node.scale)) { + return [ + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + ]; + } + }, + rotation : function(node) { + if (defined(node.translation) || defined(node.scale)) { + return [0.0, 0.0, 0.0, 1.0]; + } + }, + scale : function(node) { + if (defined(node.translation) || defined(node.rotation)) { + return [1.0, 1.0, 1.0]; + } + }, + translation : function(node) { + if (defined(node.rotation) || defined(node.scale)) { + return [0.0, 0.0, 0.0]; + } + } + } + ], + programs : [ + { + attributes : [] + } + ], + samplers : [ + { + magFilter: WebGLConstants.LINEAR, + minFilter : WebGLConstants.NEAREST_MIPMAP_LINEAR, + wrapS : WebGLConstants.REPEAT, + wrapT : WebGLConstants.REPEAT + } + ], + scenes : [ + { + nodes : [] + } + ], + shaders : [], + skins : [ + { + bindShapeMatrix : [ + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + ] + } + ], + techniques : [ + { + parameters: {}, + attributes: {}, + uniforms: {}, + states: { + enable: [] + } + } + ], + textures : [ + { + format: WebGLConstants.RGBA, + internalFormat: WebGLConstants.RGBA, + target: WebGLConstants.TEXTURE_2D, + type: WebGLConstants.UNSIGNED_BYTE + } + ], + extensionsUsed : [], + extensionsRequired : [] + }; - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new CylinderGeometry(options), - modelMatrix : modelMatrix, - attributes : { - distanceDisplayCondition : distanceDisplayConditionAttribute + function addDefaultsFromTemplate(object, template) { + for (var id in template) { + if (template.hasOwnProperty(id)) { + var templateValue = template[id]; + if (typeof templateValue === 'function') { + templateValue = templateValue(object); + } + if (defined(templateValue)) { + if (typeof templateValue === 'object') { + if (Array.isArray(templateValue)) { + var arrayValue = defaultValue(object[id], []); + if (templateValue.length > 0) { + var arrayTemplate = templateValue[0]; + if (typeof arrayTemplate === 'object') { + var arrayValueLength = arrayValue.length; + for (var i = 0; i < arrayValueLength; i++) { + addDefaultsFromTemplate(arrayValue[i], arrayTemplate); + } + } else { + arrayValue = defaultValue(object[id], templateValue); + } + } + object[id] = arrayValue; + } else { + var applyTemplate = templateValue['*']; + object[id] = defaultValue(object[id], {}); + var objectValue = object[id]; + if (defined(applyTemplate)) { + for (var subId in objectValue) { + if (objectValue.hasOwnProperty(subId) && subId !== 'extras') { + var subObject = objectValue[subId]; + addDefaultsFromTemplate(subObject, applyTemplate); + } + } + } else { + addDefaultsFromTemplate(objectValue, templateValue); + } + } + } else { + object[id] = defaultValue(object[id], templateValue); } - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + } + } } + } - if (Property.getValueOrDefault(cylinder.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - - var outlineColor = Property.getValueOrClonedDefault(cylinder.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(cylinder.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; - - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new CylinderOutlineGeometry(options), - modelMatrix : modelMatrix, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) - } - }), - asynchronous : false, - shadows : shadows - })); + var defaultMaterial = { + values : { + emission : [ + 0.5, 0.5, 0.5, 1.0 + ] + }, + extras : { + _pipeline: {} } }; - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + var defaultTechnique = { + attributes : { + a_position : 'position' + }, + parameters : { + modelViewMatrix : { + semantic : 'MODELVIEW', + type : WebGLConstants.FLOAT_MAT4 + }, + projectionMatrix : { + semantic : 'PROJECTION', + type : WebGLConstants.FLOAT_MAT4 + }, + emission : { + type : WebGLConstants.FLOAT_VEC4, + value : [ + 0.5, 0.5, 0.5, 1.0 + ] + }, + position : { + semantic: 'POSITION', + type: WebGLConstants.FLOAT_VEC3 + } + }, + states : { + enable : [ + WebGLConstants.CULL_FACE, + WebGLConstants.DEPTH_TEST + ] + }, + uniforms : { + u_modelViewMatrix : 'modelViewMatrix', + u_projectionMatrix : 'projectionMatrix', + u_emission : 'emission' + } }; - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; + var defaultProgram = { + attributes : [ + 'a_position' + ] }; - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); + var defaultVertexShader = { + type : WebGLConstants.VERTEX_SHADER, + extras : { + _pipeline : { + extension : '.vert', + source : '' + + 'precision highp float;\n' + + '\n' + + 'uniform mat4 u_modelViewMatrix;\n' + + 'uniform mat4 u_projectionMatrix;\n' + + '\n' + + 'attribute vec3 a_position;\n' + + '\n' + + 'void main (void)\n' + + '{\n' + + ' gl_Position = u_projectionMatrix * u_modelViewMatrix * vec4(a_position, 1.0);\n' + + '}\n' + } + } }; - return CylinderGeometryUpdater; -}); + var defaultFragmentShader = { + type : WebGLConstants.FRAGMENT_SHADER, + extras : { + _pipeline : { + extension: '.frag', + source : '' + + 'precision highp float;\n' + + '\n' + + 'uniform vec4 u_emission;\n' + + '\n' + + 'void main(void)\n' + + '{\n' + + ' gl_FragColor = u_emission;\n' + + '}\n' + } + } + }; -define('Scene/ColorBlendMode',[ - '../Core/freezeObject', - '../Core/Math' - ], function( - freezeObject, - CesiumMath) { - 'use strict'; + function addDefaultMaterial(gltf) { + var materials = gltf.materials; + var meshes = gltf.meshes; - /** - * Defines different modes for blending between a target color and a primitive's source color. - * - * HIGHLIGHT multiplies the source color by the target color - * REPLACE replaces the source color with the target color - * MIX blends the source color and target color together - * - * @exports ColorBlendMode - * - * @see Model.colorBlendMode - */ - var ColorBlendMode = { - HIGHLIGHT : 0, - REPLACE : 1, - MIX : 2 - }; + var defaultMaterialId; - /** - * @private - */ - ColorBlendMode.getColorBlend = function(colorBlendMode, colorBlendAmount) { - if (colorBlendMode === ColorBlendMode.HIGHLIGHT) { - return 0.0; - } else if (colorBlendMode === ColorBlendMode.REPLACE) { - return 1.0; - } else if (colorBlendMode === ColorBlendMode.MIX) { - // The value 0.0 is reserved for highlight, so clamp to just above 0.0. - return CesiumMath.clamp(colorBlendAmount, CesiumMath.EPSILON4, 1.0); + var meshesLength = meshes.length; + for (var meshId = 0; meshId < meshesLength; meshId++) { + var mesh = meshes[meshId]; + var primitives = mesh.primitives; + var primitivesLength = primitives.length; + for (var j = 0; j < primitivesLength; j++) { + var primitive = primitives[j]; + if (!defined(primitive.material)) { + if (!defined(defaultMaterialId)) { + defaultMaterialId = addToArray(materials, clone(defaultMaterial, true)); + } + primitive.material = defaultMaterialId; + } + } } - }; + } - return freezeObject(ColorBlendMode); -}); + function addDefaultTechnique(gltf) { + var materials = gltf.materials; + var techniques = gltf.techniques; + var programs = gltf.programs; + var shaders = gltf.shaders; -define('DataSources/DataSourceClock',[ - '../Core/Clock', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/JulianDate', - './createRawPropertyDescriptor' - ], function( - Clock, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - JulianDate, - createRawPropertyDescriptor) { - 'use strict'; + var defaultTechniqueId; - /** - * Represents desired clock settings for a particular {@link DataSource}. These settings may be applied - * to the {@link Clock} when the DataSource is loaded. - * - * @alias DataSourceClock - * @constructor - */ - function DataSourceClock() { - this._startTime = undefined; - this._stopTime = undefined; - this._currentTime = undefined; - this._clockRange = undefined; - this._clockStep = undefined; - this._multiplier = undefined; - this._definitionChanged = new Event(); - } + var materialsLength = materials.length; + for (var materialId = 0; materialId < materialsLength; materialId++) { + var material = materials[materialId]; + var techniqueId = material.technique; + var extensions = defaultValue(material.extensions, {}); + var materialsCommon = extensions.KHR_materials_common; + if (!defined(techniqueId)) { + if (!defined(defaultTechniqueId) && !defined(materialsCommon)) { + var technique = clone(defaultTechnique, true); + defaultTechniqueId = addToArray(techniques, technique); - defineProperties(DataSourceClock.prototype, { - /** - * Gets the event that is raised whenever a new property is assigned. - * @memberof DataSourceClock.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + var program = clone(defaultProgram, true); + technique.program = addToArray(programs, program); - /** - * Gets or sets the desired start time of the clock. - * See {@link Clock#startTime}. - * @memberof DataSourceClock.prototype - * @type {JulianDate} - */ - startTime : createRawPropertyDescriptor('startTime'), + var vertexShader = clone(defaultVertexShader, true); + program.vertexShader = addToArray(shaders, vertexShader); - /** - * Gets or sets the desired stop time of the clock. - * See {@link Clock#stopTime}. - * @memberof DataSourceClock.prototype - * @type {JulianDate} - */ - stopTime : createRawPropertyDescriptor('stopTime'), + var fragmentShader = clone(defaultFragmentShader, true); + program.fragmentShader = addToArray(shaders, fragmentShader); + } + material.technique = defaultTechniqueId; + } + } + } - /** - * Gets or sets the desired current time when this data source is loaded. - * See {@link Clock#currentTime}. - * @memberof DataSourceClock.prototype - * @type {JulianDate} - */ - currentTime : createRawPropertyDescriptor('currentTime'), + function addDefaultByteOffsets(gltf) { + var accessors = gltf.accessors; - /** - * Gets or sets the desired clock range setting. - * See {@link Clock#clockRange}. - * @memberof DataSourceClock.prototype - * @type {ClockRange} - */ - clockRange : createRawPropertyDescriptor('clockRange'), + var accessorLength = accessors.length; + for (var i = 0; i < accessorLength; i++) { + var accessor = accessors[i]; + if (!defined(accessor.byteOffset)) { + accessor.byteOffset = 0; + } + } - /** - * Gets or sets the desired clock step setting. - * See {@link Clock#clockStep}. - * @memberof DataSourceClock.prototype - * @type {ClockStep} - */ - clockStep : createRawPropertyDescriptor('clockStep'), + var bufferViews = gltf.bufferViews; - /** - * Gets or sets the desired clock multiplier. - * See {@link Clock#multiplier}. - * @memberof DataSourceClock.prototype - * @type {Number} - */ - multiplier : createRawPropertyDescriptor('multiplier') - }); + var bufferViewsLength = bufferViews.length; + for (var j = 0; j < bufferViewsLength; j++) { + var bufferView = bufferViews[j]; + if (!defined(bufferView.byteOffset)) { + bufferView.byteOffset = 0; + } + } + } - /** - * Duplicates a DataSourceClock instance. - * - * @param {DataSourceClock} [result] The object onto which to store the result. - * @returns {DataSourceClock} The modified result parameter or a new instance if one was not provided. - */ - DataSourceClock.prototype.clone = function(result) { - if (!defined(result)) { - result = new DataSourceClock(); + function selectDefaultScene(gltf) { + if (defined(gltf.scenes) && !defined(gltf.scene)) { + gltf.scene = 0; } - result.startTime = this.startTime; - result.stopTime = this.stopTime; - result.currentTime = this.currentTime; - result.clockRange = this.clockRange; - result.clockStep = this.clockStep; - result.multiplier = this.multiplier; - return result; - }; + } - /** - * Returns true if this DataSourceClock is equivalent to the other - * - * @param {DataSourceClock} other The other DataSourceClock to compare to. - * @returns {Boolean} <code>true</code> if the DataSourceClocks are equal; otherwise, <code>false</code>. - */ - DataSourceClock.prototype.equals = function(other) { - return this === other || - defined(other) && - JulianDate.equals(this.startTime, other.startTime) && - JulianDate.equals(this.stopTime, other.stopTime) && - JulianDate.equals(this.currentTime, other.currentTime) && - this.clockRange === other.clockRange && - this.clockStep === other.clockStep && - this.multiplier === other.multiplier; - }; + function optimizeForCesium(gltf) { + // Give the diffuse uniform a semantic to support color replacement in 3D Tiles + var techniques = gltf.techniques; + var techniquesLength = techniques.length; + for (var techniqueId = 0; techniqueId < techniquesLength; techniqueId++) { + var technique = techniques[techniqueId]; + var parameters = technique.parameters; + if (defined(parameters.diffuse)) { + parameters.diffuse.semantic = '_3DTILESDIFFUSE'; + } + } + } - /** - * Assigns each unassigned property on this object to the value - * of the same property on the provided source object. - * - * @param {DataSourceClock} source The object to be merged into this object. - */ - DataSourceClock.prototype.merge = function(source) { - if (!defined(source)) { - throw new DeveloperError('source is required.'); + function inferBufferViewTargets(gltf) { + // If bufferView elements are missing targets, we can infer their type from their use + var needsTarget = {}; + var shouldTraverse = 0; + ForEach.bufferView(gltf, function(bufferView, bufferViewId) { + if (!defined(bufferView.target)) { + needsTarget[bufferViewId] = true; + shouldTraverse++; + } + }); + if (shouldTraverse > 0) { + var accessors = gltf.accessors; + var bufferViews = gltf.bufferViews; + ForEach.mesh(gltf, function (mesh) { + ForEach.meshPrimitive(mesh, function (primitive) { + var indices = primitive.indices; + if (defined(indices)) { + var accessor = accessors[indices]; + var bufferViewId = accessor.bufferView; + if (needsTarget[bufferViewId]) { + var bufferView = bufferViews[bufferViewId]; + if (defined(bufferView)) { + bufferView.target = WebGLConstants.ELEMENT_ARRAY_BUFFER; + needsTarget[bufferViewId] = false; + shouldTraverse--; + } + } + } + ForEach.meshPrimitiveAttribute(primitive, function (accessorId) { + var accessor = accessors[accessorId]; + var bufferViewId = accessor.bufferView; + if (needsTarget[bufferViewId]) { + var bufferView = bufferViews[bufferViewId]; + if (defined(bufferView)) { + bufferView.target = WebGLConstants.ARRAY_BUFFER; + needsTarget[bufferViewId] = false; + shouldTraverse--; + } + } + }); + ForEach.meshPrimitiveTargetAttribute(primitive, function (targetAttribute) { + var bufferViewId = accessors[targetAttribute].bufferView; + if (needsTarget[bufferViewId]) { + var bufferView = bufferViews[bufferViewId]; + if (defined(bufferView)) { + bufferView.target = WebGLConstants.ARRAY_BUFFER; + needsTarget[bufferViewId] = false; + shouldTraverse--; + } + } + }); + }); + if (shouldTraverse === 0) { + return true; + } + }); } - - this.startTime = defaultValue(this.startTime, source.startTime); - this.stopTime = defaultValue(this.stopTime, source.stopTime); - this.currentTime = defaultValue(this.currentTime, source.currentTime); - this.clockRange = defaultValue(this.clockRange, source.clockRange); - this.clockStep = defaultValue(this.clockStep, source.clockStep); - this.multiplier = defaultValue(this.multiplier, source.multiplier); - }; + } /** - * Gets the value of this clock instance as a {@link Clock} object. + * Adds default glTF values if they don't exist. * - * @returns {Clock} The modified result parameter or a new instance if one was not provided. + * The glTF asset must be initialized for the pipeline. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.optimizeForCesium] Optimize the defaults for Cesium. Uses the Cesium sun as the default light source. + * @returns {Object} The modified glTF. + * + * @see addPipelineExtras + * @see loadGltfUris */ - DataSourceClock.prototype.getValue = function(result) { - if (!defined(result)) { - result = new Clock(); + function addDefaults(gltf, options) { + options = defaultValue(options, {}); + addDefaultsFromTemplate(gltf, gltfTemplate); + addDefaultMaterial(gltf); + addDefaultTechnique(gltf); + addDefaultByteOffsets(gltf); + selectDefaultScene(gltf); + inferBufferViewTargets(gltf); + if (options.optimizeForCesium) { + optimizeForCesium(gltf); } - result.startTime = defaultValue(this.startTime, result.startTime); - result.stopTime = defaultValue(this.stopTime, result.stopTime); - result.currentTime = defaultValue(this.currentTime, result.currentTime); - result.clockRange = defaultValue(this.clockRange, result.clockRange); - result.multiplier = defaultValue(this.multiplier, result.multiplier); - result.clockStep = defaultValue(this.clockStep, result.clockStep); - return result; - }; + return gltf; + } - return DataSourceClock; + return addDefaults; }); -define('DataSources/GridMaterialProperty',[ - '../Core/Cartesian2', - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' +define('ThirdParty/GltfPipeline/addPipelineExtras',[ + '../../Core/defaultValue', + '../../Core/defined' ], function( - Cartesian2, - Color, defaultValue, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { + defined) { 'use strict'; - var defaultColor = Color.WHITE; - var defaultCellAlpha = 0.1; - var defaultLineCount = new Cartesian2(8, 8); - var defaultLineOffset = new Cartesian2(0, 0); - var defaultLineThickness = new Cartesian2(1, 1); + // Objects with these ids should not have extras added + var exceptions = { + attributes: true, + uniforms: true, + extensions: true, + values: true, + samplers: true + }; /** - * A {@link MaterialProperty} that maps to grid {@link Material} uniforms. - * @alias GridMaterialProperty - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.color=Color.WHITE] A Property specifying the grid {@link Color}. - * @param {Property} [options.cellAlpha=0.1] A numeric Property specifying cell alpha values. - * @param {Property} [options.lineCount=new Cartesian2(8, 8)] A {@link Cartesian2} Property specifying the number of grid lines along each axis. - * @param {Property} [options.lineThickness=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the thickness of grid lines along each axis. - * @param {Property} [options.lineOffset=new Cartesian2(0.0, 0.0)] A {@link Cartesian2} Property specifying starting offset of grid lines along each axis. + * Adds extras._pipeline to each object that can have extras in the glTF asset. * - * @constructor + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The glTF asset with the added pipeline extras. */ - function GridMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this._cellAlpha = undefined; - this._cellAlphaSubscription = undefined; - this._lineCount = undefined; - this._lineCountSubscription = undefined; - this._lineThickness = undefined; - this._lineThicknessSubscription = undefined; - this._lineOffset = undefined; - this._lineOffsetSubscription = undefined; - - this.color = options.color; - this.cellAlpha = options.cellAlpha; - this.lineCount = options.lineCount; - this.lineThickness = options.lineThickness; - this.lineOffset = options.lineOffset; - } - - defineProperties(GridMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof GridMaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._color) && - Property.isConstant(this._cellAlpha) && - Property.isConstant(this._lineCount) && - Property.isConstant(this._lineThickness) && - Property.isConstant(this._lineOffset); + function addPipelineExtras(gltf) { + var objectStack = []; + for (var rootArrayId in gltf) { + if (gltf.hasOwnProperty(rootArrayId)) { + var rootArray = gltf[rootArrayId]; + var rootArrayLength = rootArray.length; + for (var i = 0; i < rootArrayLength; i++) { + var rootObject = rootArray[i]; + if (defined(rootObject) && typeof rootObject === 'object') { + rootObject.extras = defaultValue(rootObject.extras, {}); + rootObject.extras._pipeline = defaultValue(rootObject.extras._pipeline, {}); + objectStack.push(rootObject); + } + } } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof GridMaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + } + while (objectStack.length > 0) { + var object = objectStack.pop(); + for (var propertyId in object) { + if (object.hasOwnProperty(propertyId)) { + var property = object[propertyId]; + if (defined(property) && typeof property === 'object' && propertyId !== 'extras') { + objectStack.push(property); + if (!exceptions[propertyId] && !Array.isArray(property)) { + property.extras = defaultValue(property.extras, {}); + property.extras._pipeline = defaultValue(property.extras._pipeline, {}); + } + } + } } - }, - /** - * Gets or sets the Property specifying the grid {@link Color}. - * @memberof GridMaterialProperty.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color'), - /** - * Gets or sets the numeric Property specifying cell alpha values. - * @memberof GridMaterialProperty.prototype - * @type {Property} - * @default 0.1 - */ - cellAlpha : createPropertyDescriptor('cellAlpha'), - /** - * Gets or sets the {@link Cartesian2} Property specifying the number of grid lines along each axis. - * @memberof GridMaterialProperty.prototype - * @type {Property} - * @default new Cartesian2(8.0, 8.0) - */ - lineCount : createPropertyDescriptor('lineCount'), - /** - * Gets or sets the {@link Cartesian2} Property specifying the thickness of grid lines along each axis. - * @memberof GridMaterialProperty.prototype - * @type {Property} - * @default new Cartesian2(1.0, 1.0) - */ - lineThickness : createPropertyDescriptor('lineThickness'), - /** - * Gets or sets the {@link Cartesian2} Property specifying the starting offset of grid lines along each axis. - * @memberof GridMaterialProperty.prototype - * @type {Property} - * @default new Cartesian2(0.0, 0.0) - */ - lineOffset : createPropertyDescriptor('lineOffset') - }); - - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - GridMaterialProperty.prototype.getType = function(time) { - return 'Grid'; - }; - - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - GridMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; } - result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); - result.cellAlpha = Property.getValueOrDefault(this._cellAlpha, time, defaultCellAlpha); - result.lineCount = Property.getValueOrClonedDefault(this._lineCount, time, defaultLineCount, result.lineCount); - result.lineThickness = Property.getValueOrClonedDefault(this._lineThickness, time, defaultLineThickness, result.lineThickness); - result.lineOffset = Property.getValueOrClonedDefault(this._lineOffset, time, defaultLineOffset, result.lineOffset); - return result; - }; - - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - GridMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof GridMaterialProperty && // - Property.equals(this._color, other._color) && // - Property.equals(this._cellAlpha, other._cellAlpha) && // - Property.equals(this._lineCount, other._lineCount) && // - Property.equals(this._lineThickness, other._lineThickness) && // - Property.equals(this._lineOffset, other._lineOffset)); - }; - - return GridMaterialProperty; + gltf.extras = defaultValue(gltf.extras, {}); + gltf.extras._pipeline = defaultValue(gltf.extras._pipeline, {}); + gltf.asset = defaultValue(gltf.asset, {}); + gltf.asset.extras = defaultValue(gltf.asset.extras, {}); + if (defined(gltf.asset.extras) && typeof(gltf.asset.extras) !== 'object') { + gltf.asset.extras = { + extras : gltf.asset.extras + }; + } + gltf.asset.extras._pipeline = defaultValue(gltf.asset.extras._pipeline, {}); + return gltf; + } + return addPipelineExtras; }); -define('DataSources/PolylineArrowMaterialProperty',[ - '../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' +define('ThirdParty/GltfPipeline/byteLengthForComponentType',[ + '../../Core/WebGLConstants' ], function( - Color, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { + WebGLConstants) { 'use strict'; /** - * A {@link MaterialProperty} that maps to PolylineArrow {@link Material} uniforms. - * - * @param {Property} [color=Color.WHITE] The {@link Color} Property to be used. + * Utility function for retrieving the byte length of a component type. + * As per the spec: + * 5120 (BYTE) : 1 + * 5121 (UNSIGNED_BYTE) : 1 + * 5122 (SHORT) : 2 + * 5123 (UNSIGNED_SHORT) : 2 + * 5126 (FLOAT) : 4 + * 5125 (UNSIGNED_INT) : 4 * - * @alias PolylineArrowMaterialProperty - * @constructor + * @param {Number} [componentType] + * @returns {Number} The byte length of the component type. */ - function PolylineArrowMaterialProperty(color) { - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this.color = color; + function byteLengthForComponentType(componentType) { + switch (componentType) { + case WebGLConstants.BYTE: + case WebGLConstants.UNSIGNED_BYTE: + return 1; + case WebGLConstants.SHORT: + case WebGLConstants.UNSIGNED_SHORT: + return 2; + case WebGLConstants.FLOAT: + case WebGLConstants.UNSIGNED_INT: + return 4; + } } + return byteLengthForComponentType; +}); - defineProperties(PolylineArrowMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PolylineArrowMaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._color); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PolylineArrowMaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets or sets the {@link Color} {@link Property}. - * @memberof PolylineArrowMaterialProperty.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color') - }); - - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - PolylineArrowMaterialProperty.prototype.getType = function(time) { - return 'PolylineArrow'; - }; +define('ThirdParty/GltfPipeline/numberOfComponentsForType',[], function() { + 'use strict'; /** - * Gets the value of the property at the provided time. + * Utility function for retrieving the number of components in a given type. + * As per the spec: + * 'SCALAR' : 1 + * 'VEC2' : 2 + * 'VEC3' : 3 + * 'VEC4' : 4 + * 'MAT2' : 4 + * 'MAT3' : 9 + * 'MAT4' : 16 * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {String} type glTF type + * @returns {Number} The number of components in that type. */ - PolylineArrowMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; + function numberOfComponentsForType(type) { + switch (type) { + case 'SCALAR': + return 1; + case 'VEC2': + return 2; + case 'VEC3': + return 3; + case 'VEC4': + case 'MAT2': + return 4; + case 'MAT3': + return 9; + case 'MAT4': + return 16; } - result.color = Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color); - return result; - }; - - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - PolylineArrowMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof PolylineArrowMaterialProperty && // - Property.equals(this._color, other._color)); - }; - - return PolylineArrowMaterialProperty; + } + return numberOfComponentsForType; }); -define('DataSources/PolylineDashMaterialProperty',[ - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' +define('ThirdParty/GltfPipeline/getAccessorByteStride',[ + './byteLengthForComponentType', + './numberOfComponentsForType', + '../../Core/defined' ], function( - Color, - defaultValue, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { + byteLengthForComponentType, + numberOfComponentsForType, + defined) { 'use strict'; - var defaultColor = Color.WHITE; - var defaultGapColor = Color.TRANSPARENT; - var defaultDashLength = 16.0; - var defaultDashPattern = 255.0; - - /** - * A {@link MaterialProperty} that maps to polyline dash {@link Material} uniforms. - * @alias PolylineDashMaterialProperty - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. - * @param {Property} [options.gapColor=Color.TRANSPARENT] A Property specifying the {@link Color} of the gaps in the line. - * @param {Property} [options.dashLength=16.0] A numeric Property specifying the length of the dash pattern in pixel.s - * @param {Property} [options.dashPattern=255.0] A numeric Property specifying a 16 bit pattern for the dash - */ - function PolylineDashMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this._gapColor = undefined; - this._gapColorSubscription = undefined; - this._dashLength = undefined; - this._dashLengthSubscription = undefined; - this._dashPattern = undefined; - this._dashPatternSubscription = undefined; - - this.color = options.color; - this.gapColor = options.gapColor; - this.dashLength = options.dashLength; - this.dashPattern = options.dashPattern; - } - - defineProperties(PolylineDashMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PolylineDashMaterialProperty.prototype - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return (Property.isConstant(this._color) && - Property.isConstant(this._gapColor) && - Property.isConstant(this._dashLength) && - Property.isConstant(this._dashPattern)); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PolylineDashMaterialProperty.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets or sets the Property specifying the {@link Color} of the line. - * @memberof PolylineDashMaterialProperty.prototype - * @type {Property} - */ - color : createPropertyDescriptor('color'), - /** - * Gets or sets the Property specifying the {@link Color} of the gaps in the line. - * @memberof PolylineDashMaterialProperty.prototype - * @type {Property} - */ - gapColor : createPropertyDescriptor('gapColor'), - /** - * Gets or sets the numeric Property specifying the length of a dash cycle - * @memberof PolylineDashMaterialProperty.prototype - * @type {Property} - */ - dashLength : createPropertyDescriptor('dashLength'), - /** - * Gets or sets the numeric Property specifying a dash pattern - * @memberof PolylineDashMaterialProperty.prototype - * @type {Property} - */ - dashPattern : createPropertyDescriptor('dashPattern') - }); - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - PolylineDashMaterialProperty.prototype.getType = function(time) { - return 'PolylineDash'; - }; - - /** - * Gets the value of the property at the provided time. + * Returns the byte stride of the provided accessor. + * If the byteStride is 0, it is calculated based on type and componentType * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} accessor The accessor. + * @returns {Number} The byte stride of the accessor. */ - PolylineDashMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); - result.gapColor = Property.getValueOrClonedDefault(this._gapColor, time, defaultGapColor, result.gapColor); - result.dashLength = Property.getValueOrDefault(this._dashLength, time, defaultDashLength, result.dashLength); - result.dashPattern = Property.getValueOrDefault(this._dashPattern, time, defaultDashPattern, result.dashPattern); - return result; - }; + function getAccessorByteStride(gltf, accessor) { + var bufferView = gltf.bufferViews[accessor.bufferView]; + if (defined(bufferView.byteStride) && bufferView.byteStride > 0) { + return bufferView.byteStride; + } + return byteLengthForComponentType(accessor.componentType) * numberOfComponentsForType(accessor.type); + } + return getAccessorByteStride; +}); + +define('ThirdParty/GltfPipeline/removeExtensionsRequired',[ + '../../Core/defined' + ], function( + defined) { + 'use strict'; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Removes an extension from gltf.extensionsRequired if it is present. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to remove. */ - PolylineDashMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof PolylineDashMaterialProperty && - Property.equals(this._color, other._color) && - Property.equals(this._gapColor, other._gapColor) && - Property.equals(this._dashLength, other._dashLength) && - Property.equals(this._dashPattern, other._dashPattern) - ); - }; + function removeExtensionsRequired(gltf, extension) { + var extensionsRequired = gltf.extensionsRequired; + if (defined(extensionsRequired)) { + var index = extensionsRequired.indexOf(extension); + if (index >= 0) { + extensionsRequired.splice(index, 1); + } + if (extensionsRequired.length === 0) { + delete gltf.extensionsRequired; + } + } + } - return PolylineDashMaterialProperty; + return removeExtensionsRequired; }); -define('DataSources/PolylineGlowMaterialProperty',[ - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' +define('ThirdParty/GltfPipeline/removeExtensionsUsed',[ + './removeExtensionsRequired', + '../../Core/defined' ], function( - Color, - defaultValue, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { + removeExtensionsRequired, + defined) { 'use strict'; - var defaultColor = Color.WHITE; - var defaultGlowPower = 0.25; - /** - * A {@link MaterialProperty} that maps to polyline glow {@link Material} uniforms. - * @alias PolylineGlowMaterialProperty - * @constructor + * Removes an extension from gltf.extensionsUsed and gltf.extensionsRequired if it is present. * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. - * @param {Property} [options.glowPower=0.25] A numeric Property specifying the strength of the glow, as a percentage of the total line width. + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to remove. */ - function PolylineGlowMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this._glowPower = undefined; - this._glowPowerSubscription = undefined; - - this.color = options.color; - this.glowPower = options.glowPower; - } - - defineProperties(PolylineGlowMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PolylineGlowMaterialProperty.prototype - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._color) && Property.isConstant(this._glow); + function removeExtensionsUsed(gltf, extension) { + var extensionsUsed = gltf.extensionsUsed; + if (defined(extensionsUsed)) { + var index = extensionsUsed.indexOf(extension); + if (index >= 0) { + extensionsUsed.splice(index, 1); } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PolylineGlowMaterialProperty.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + removeExtensionsRequired(gltf, extension); + if (extensionsUsed.length === 0) { + delete gltf.extensionsUsed; } - }, - /** - * Gets or sets the Property specifying the {@link Color} of the line. - * @memberof PolylineGlowMaterialProperty.prototype - * @type {Property} - */ - color : createPropertyDescriptor('color'), - /** - * Gets or sets the numeric Property specifying the strength of the glow, as a percentage of the total line width (less than 1.0). - * @memberof PolylineGlowMaterialProperty.prototype - * @type {Property} - */ - glowPower : createPropertyDescriptor('glowPower') - }); + } + } + return removeExtensionsUsed; +}); - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - PolylineGlowMaterialProperty.prototype.getType = function(time) { - return 'PolylineGlow'; - }; +define('ThirdParty/GltfPipeline/addExtensionsUsed',[ + '../../Core/defined' + ], function( + defined) { + 'use strict'; /** - * Gets the value of the property at the provided time. + * Adds an extension to gltf.extensionsUsed if it does not already exist. + * Initializes extensionsUsed if it is not defined. * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to add. */ - PolylineGlowMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; + function addExtensionsUsed(gltf, extension) { + var extensionsUsed = gltf.extensionsUsed; + if (!defined(extensionsUsed)) { + extensionsUsed = []; + gltf.extensionsUsed = extensionsUsed; } - result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); - result.glowPower = Property.getValueOrDefault(this._glowPower, time, defaultGlowPower, result.glowPower); - return result; - }; + if (extensionsUsed.indexOf(extension) < 0) { + extensionsUsed.push(extension); + } + } + return addExtensionsUsed; +}); + +define('ThirdParty/GltfPipeline/addExtensionsRequired',[ + './addExtensionsUsed', + '../../Core/defined' + ], function( + addExtensionsUsed, + defined) { + 'use strict'; /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. + * Adds an extension to gltf.extensionsRequired if it does not already exist. + * Initializes extensionsRequired if it is not defined. * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to add. */ - PolylineGlowMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof PolylineGlowMaterialProperty && // - Property.equals(this._color, other._color) && - Property.equals(this._glowPower, other._glowPower)); - }; - - return PolylineGlowMaterialProperty; + function addExtensionsRequired(gltf, extension) { + var extensionsRequired = gltf.extensionsRequired; + if (!defined(extensionsRequired)) { + extensionsRequired = []; + gltf.extensionsRequired = extensionsRequired; + } + if (extensionsRequired.indexOf(extension) < 0) { + extensionsRequired.push(extension); + } + addExtensionsUsed(gltf, extension); + } + return addExtensionsRequired; }); -define('DataSources/PolylineOutlineMaterialProperty',[ - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property' +define('ThirdParty/GltfPipeline/updateVersion',[ + './addExtensionsRequired', + './addToArray', + './ForEach', + './getAccessorByteStride', + './numberOfComponentsForType', + '../../Core/Cartesian3', + '../../Core/Math', + '../../Core/clone', + '../../Core/ComponentDatatype', + '../../Core/defaultValue', + '../../Core/defined', + '../../Core/Quaternion', + '../../Core/WebGLConstants' ], function( - Color, + addExtensionsRequired, + addToArray, + ForEach, + getAccessorByteStride, + numberOfComponentsForType, + Cartesian3, + CesiumMath, + clone, + ComponentDatatype, defaultValue, defined, - defineProperties, - Event, - createPropertyDescriptor, - Property) { + Quaternion, + WebGLConstants) { 'use strict'; - var defaultColor = Color.WHITE; - var defaultOutlineColor = Color.BLACK; - var defaultOutlineWidth = 1.0; + var updateFunctions = { + '0.8' : glTF08to10, + '1.0' : glTF10to20, + '2.0' : undefined + }; /** - * A {@link MaterialProperty} that maps to polyline outline {@link Material} uniforms. - * @alias PolylineOutlineMaterialProperty - * @constructor + * Update the glTF version to the latest version (2.0), or targetVersion if specified. + * Applies changes made to the glTF spec between revisions so that the core library + * only has to handle the latest version. * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. - * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline, in pixels. + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} [options] Options for updating the glTF. + * @param {String} [options.targetVersion] The glTF will be upgraded until it hits the specified version. + * @returns {Object} The updated glTF asset. */ - function PolylineOutlineMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function updateVersion(gltf, options) { + options = defaultValue(options, {}); + var targetVersion = options.targetVersion; + var version = gltf.version; - this._definitionChanged = new Event(); - this._color = undefined; - this._colorSubscription = undefined; - this._outlineColor = undefined; - this._outlineColorSubscription = undefined; - this._outlineWidth = undefined; - this._outlineWidthSubscription = undefined; + gltf.asset = defaultValue(gltf.asset, { + version: '1.0' + }); - this.color = options.color; - this.outlineColor = options.outlineColor; - this.outlineWidth = options.outlineWidth; + version = defaultValue(version, gltf.asset.version); + // invalid version + if (!updateFunctions.hasOwnProperty(version)) { + // try truncating trailing version numbers, could be a number as well if it is 0.8 + if (defined(version)) { + version = ('' + version).substring(0, 3); + } + // default to 1.0 if it cannot be determined + if (!updateFunctions.hasOwnProperty(version)) { + version = '1.0'; + } + } + + var updateFunction = updateFunctions[version]; + + while (defined(updateFunction)) { + if (version === targetVersion) { + break; + } + updateFunction(gltf); + version = gltf.asset.version; + updateFunction = updateFunctions[version]; + } + return gltf; } - defineProperties(PolylineOutlineMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof PolylineOutlineMaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._color) && Property.isConstant(this._outlineColor) && Property.isConstant(this._outlineWidth); + function updateInstanceTechniques(gltf) { + var materials = gltf.materials; + for (var materialId in materials) { + if (materials.hasOwnProperty(materialId)) { + var material = materials[materialId]; + var instanceTechnique = material.instanceTechnique; + if (defined(instanceTechnique)) { + material.technique = instanceTechnique.technique; + material.values = instanceTechnique.values; + delete material.instanceTechnique; + } } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof PolylineOutlineMaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + } + } + + function setPrimitiveModes(gltf) { + var meshes = gltf.meshes; + for (var meshId in meshes) { + if (meshes.hasOwnProperty(meshId)) { + var mesh = meshes[meshId]; + var primitives = mesh.primitives; + if (defined(primitives)) { + var primitivesLength = primitives.length; + for (var i = 0; i < primitivesLength; i++) { + var primitive = primitives[i]; + var defaultMode = defaultValue(primitive.primitive, WebGLConstants.TRIANGLES); + primitive.mode = defaultValue(primitive.mode, defaultMode); + delete primitive.primitive; + } + } } - }, - /** - * Gets or sets the Property specifying the {@link Color} of the line. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Property} - * @default Color.WHITE - */ - color : createPropertyDescriptor('color'), - /** - * Gets or sets the Property specifying the {@link Color} of the outline. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Property} - * @default Color.BLACK - */ - outlineColor : createPropertyDescriptor('outlineColor'), - /** - * Gets or sets the numeric Property specifying the width of the outline. - * @memberof PolylineOutlineMaterialProperty.prototype - * @type {Property} - * @default 1.0 - */ - outlineWidth : createPropertyDescriptor('outlineWidth') - }); + } + } - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - PolylineOutlineMaterialProperty.prototype.getType = function(time) { - return 'PolylineOutline'; - }; + function updateNodes(gltf) { + var nodes = gltf.nodes; + var axis = new Cartesian3(); + var quat = new Quaternion(); + for (var nodeId in nodes) { + if (nodes.hasOwnProperty(nodeId)) { + var node = nodes[nodeId]; + if (defined(node.rotation)) { + var rotation = node.rotation; + Cartesian3.fromArray(rotation, 0, axis); + Quaternion.fromAxisAngle(axis, rotation[3], quat); + node.rotation = [quat.x, quat.y, quat.z, quat.w]; + } + var instanceSkin = node.instanceSkin; + if (defined(instanceSkin)) { + node.skeletons = instanceSkin.skeletons; + node.skin = instanceSkin.skin; + node.meshes = instanceSkin.meshes; + delete node.instanceSkin; + } + } + } + } - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - PolylineOutlineMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; + function updateAnimations(gltf) { + var animations = gltf.animations; + var accessors = gltf.accessors; + var bufferViews = gltf.bufferViews; + var buffers = gltf.buffers; + var updatedAccessors = {}; + var axis = new Cartesian3(); + var quat = new Quaternion(); + for (var animationId in animations) { + if (animations.hasOwnProperty(animationId)) { + var animation = animations[animationId]; + var channels = animation.channels; + var parameters = animation.parameters; + var samplers = animation.samplers; + if (defined(channels)) { + var channelsLength = channels.length; + for (var i = 0; i < channelsLength; ++i) { + var channel = channels[i]; + if (channel.target.path === 'rotation') { + var accessorId = parameters[samplers[channel.sampler].output]; + if (defined(updatedAccessors[accessorId])) { + continue; + } + updatedAccessors[accessorId] = true; + var accessor = accessors[accessorId]; + var bufferView = bufferViews[accessor.bufferView]; + var buffer = buffers[bufferView.buffer]; + var source = buffer.extras._pipeline.source; + var byteOffset = source.byteOffset + bufferView.byteOffset + accessor.byteOffset; + var componentType = accessor.componentType; + var count = accessor.count; + var componentsLength = numberOfComponentsForType(accessor.type); + var length = accessor.count * componentsLength; + var typedArray = ComponentDatatype.createArrayBufferView(componentType, source.buffer, byteOffset, length); + + for (var j = 0; j < count; j++) { + var offset = j * componentsLength; + Cartesian3.unpack(typedArray, offset, axis); + var angle = typedArray[offset + 3]; + Quaternion.fromAxisAngle(axis, angle, quat); + Quaternion.pack(quat, typedArray, offset); + } + } + } + } + } } - result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color); - result.outlineColor = Property.getValueOrClonedDefault(this._outlineColor, time, defaultOutlineColor, result.outlineColor); - result.outlineWidth = Property.getValueOrDefault(this._outlineWidth, time, defaultOutlineWidth); - return result; - }; + } - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - PolylineOutlineMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof PolylineOutlineMaterialProperty && // - Property.equals(this._color, other._color) && // - Property.equals(this._outlineColor, other._outlineColor) && // - Property.equals(this._outlineWidth, other._outlineWidth)); + function removeTechniquePasses(gltf) { + var techniques = gltf.techniques; + for (var techniqueId in techniques) { + if (techniques.hasOwnProperty(techniqueId)) { + var technique = techniques[techniqueId]; + var passes = technique.passes; + if (defined(passes)) { + var passName = defaultValue(technique.pass, 'defaultPass'); + if (passes.hasOwnProperty(passName)) { + var pass = passes[passName]; + var instanceProgram = pass.instanceProgram; + technique.attributes = defaultValue(technique.attributes, instanceProgram.attributes); + technique.program = defaultValue(technique.program, instanceProgram.program); + technique.uniforms = defaultValue(technique.uniforms, instanceProgram.uniforms); + technique.states = defaultValue(technique.states, pass.states); + } + delete technique.passes; + delete technique.pass; + } + } + } + } + + function glTF08to10(gltf) { + if (!defined(gltf.asset)) { + gltf.asset = {}; + } + var asset = gltf.asset; + asset.version = '1.0'; + // profile should be an object, not a string + if (!defined(asset.profile) || (typeof asset.profile === 'string')) { + asset.profile = {}; + } + // version property should be in asset, not on the root element + if (defined(gltf.version)) { + delete gltf.version; + } + // material.instanceTechnique properties should be directly on the material + updateInstanceTechniques(gltf); + // primitive.primitive should be primitive.mode + setPrimitiveModes(gltf); + // node rotation should be quaternion, not axis-angle + // node.instanceSkin is deprecated + updateNodes(gltf); + // animations that target rotations should be quaternion, not axis-angle + updateAnimations(gltf); + // technique.pass and techniques.passes are deprecated + removeTechniquePasses(gltf); + // gltf.lights -> khrMaterialsCommon.lights + if (defined(gltf.lights)) { + var extensions = defaultValue(gltf.extensions, {}); + gltf.extensions = extensions; + var materialsCommon = defaultValue(extensions.KHR_materials_common, {}); + extensions.KHR_materials_common = materialsCommon; + materialsCommon.lights = gltf.lights; + delete gltf.lights; + } + // gltf.allExtensions -> extensionsUsed + if (defined(gltf.allExtensions)) { + gltf.extensionsUsed = gltf.allExtensions; + gltf.allExtensions = undefined; + } + } + + function removeAnimationSamplersIndirection(gltf) { + var animations = gltf.animations; + for (var animationId in animations) { + if (animations.hasOwnProperty(animationId)) { + var animation = animations[animationId]; + var parameters = animation.parameters; + if (defined(parameters)) { + var samplers = animation.samplers; + for (var samplerId in samplers) { + if (samplers.hasOwnProperty(samplerId)) { + var sampler = samplers[samplerId]; + sampler.input = parameters[sampler.input]; + sampler.output = parameters[sampler.output]; + } + } + delete animation.parameters; + } + } + } + } + + function objectToArray(object, mapping) { + var array = []; + for (var id in object) { + if (object.hasOwnProperty(id)) { + var value = object[id]; + mapping[id] = array.length; + array.push(value); + if (!defined(value.name) && typeof(value) === 'object') { + value.name = id; + } + } + } + return array; + } + + function objectsToArrays(gltf) { + var i; + var globalMapping = { + accessors: {}, + animations: {}, + bufferViews: {}, + buffers: {}, + cameras: {}, + materials: {}, + meshes: {}, + nodes: {}, + programs: {}, + shaders: {}, + skins: {}, + techniques: {} + }; + + // Map joint names to id names + var jointName; + var jointNameToId = {}; + var nodes = gltf.nodes; + for (var id in nodes) { + if (nodes.hasOwnProperty(id)) { + jointName = nodes[id].jointName; + if (defined(jointName)) { + jointNameToId[jointName] = id; + } + } + } + + // Convert top level objects to arrays + for (var topLevelId in gltf) { + if (gltf.hasOwnProperty(topLevelId) && topLevelId !== 'extras' && topLevelId !== 'asset' && topLevelId !== 'extensions') { + var objectMapping = {}; + var object = gltf[topLevelId]; + if (typeof(object) === 'object' && !Array.isArray(object)) { + gltf[topLevelId] = objectToArray(object, objectMapping); + globalMapping[topLevelId] = objectMapping; + if (topLevelId === 'animations') { + objectMapping = {}; + object.samplers = objectToArray(object.samplers, objectMapping); + globalMapping[topLevelId].samplers = objectMapping; + } + } + } + } + + // Remap joint names to array indexes + for (jointName in jointNameToId) { + if (jointNameToId.hasOwnProperty(jointName)) { + jointNameToId[jointName] = globalMapping.nodes[jointNameToId[jointName]]; + } + } + + // Fix references + if (defined(gltf.scene)) { + gltf.scene = globalMapping.scenes[gltf.scene]; + } + ForEach.bufferView(gltf, function(bufferView) { + if (defined(bufferView.buffer)) { + bufferView.buffer = globalMapping.buffers[bufferView.buffer]; + } + }); + ForEach.accessor(gltf, function(accessor) { + if (defined(accessor.bufferView)) { + accessor.bufferView = globalMapping.bufferViews[accessor.bufferView]; + } + }); + ForEach.shader(gltf, function(shader) { + var extensions = shader.extensions; + if (defined(extensions)) { + var binaryGltf = extensions.KHR_binary_glTF; + if (defined(binaryGltf)) { + shader.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; + delete extensions.KHR_binary_glTF; + } + if (Object.keys(extensions).length === 0) { + delete shader.extensions; + } + } + }); + ForEach.program(gltf, function(program) { + if (defined(program.vertexShader)) { + program.vertexShader = globalMapping.shaders[program.vertexShader]; + } + if (defined(program.fragmentShader)) { + program.fragmentShader = globalMapping.shaders[program.fragmentShader]; + } + }); + ForEach.technique(gltf, function(technique) { + if (defined(technique.program)) { + technique.program = globalMapping.programs[technique.program]; + } + ForEach.techniqueParameter(technique, function(parameter) { + if (defined(parameter.node)) { + parameter.node = globalMapping.nodes[parameter.node]; + } + var value = parameter.value; + if (defined(value)) { + if (Array.isArray(value)) { + if (value.length === 1) { + var textureId = value[0]; + if (typeof textureId === 'string') { + value[0] = globalMapping.textures[textureId]; + } + } + } + else if (typeof value === 'string') { + parameter.value = [globalMapping.textures[value]]; + } + } + }); + }); + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + if (defined(primitive.indices)) { + primitive.indices = globalMapping.accessors[primitive.indices]; + } + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + primitive.attributes[semantic] = globalMapping.accessors[accessorId]; + }); + if (defined(primitive.material)) { + primitive.material = globalMapping.materials[primitive.material]; + } + }); + }); + ForEach.node(gltf, function(node) { + var children = node.children; + if (defined(children)) { + var childrenLength = children.length; + for (i = 0; i < childrenLength; i++) { + children[i] = globalMapping.nodes[children[i]]; + } + } + if (defined(node.meshes)) { + // Split out meshes on nodes + var meshes = node.meshes; + var meshesLength = meshes.length; + if (meshesLength > 0) { + node.mesh = globalMapping.meshes[meshes[0]]; + for (i = 1; i < meshesLength; i++) { + var meshNode = { + mesh: globalMapping.meshes[meshes[i]], + extras: { + _pipeline: {} + } + }; + var meshNodeId = addToArray(gltf.nodes, meshNode); + if (!defined(children)) { + children = []; + node.children = children; + } + children.push(meshNodeId); + } + } + delete node.meshes; + } + if (defined(node.camera)) { + node.camera = globalMapping.cameras[node.camera]; + } + if (defined(node.skeletons)) { + // Assign skeletons to skins + var skeletons = node.skeletons; + var skeletonsLength = skeletons.length; + if ((skeletonsLength > 0) && defined(node.skin)) { + var skin = gltf.skins[globalMapping.skins[node.skin]]; + skin.skeleton = globalMapping.nodes[skeletons[0]]; + } + delete node.skeletons; + } + if (defined(node.skin)) { + node.skin = globalMapping.skins[node.skin]; + } + if (defined(node.jointName)) { + delete(node.jointName); + } + }); + ForEach.skin(gltf, function(skin) { + if (defined(skin.inverseBindMatrices)) { + skin.inverseBindMatrices = globalMapping.accessors[skin.inverseBindMatrices]; + } + var joints = []; + var jointNames = skin.jointNames; + if (defined(jointNames)) { + for (i = 0; i < jointNames.length; i++) { + joints[i] = jointNameToId[jointNames[i]]; + } + skin.joints = joints; + delete skin.jointNames; + } + }); + ForEach.scene(gltf, function(scene) { + var sceneNodes = scene.nodes; + if (defined(sceneNodes)) { + var sceneNodesLength = sceneNodes.length; + for (i = 0; i < sceneNodesLength; i++) { + sceneNodes[i] = globalMapping.nodes[sceneNodes[i]]; + } + } + }); + ForEach.animation(gltf, function(animation) { + var samplerMapping = {}; + animation.samplers = objectToArray(animation.samplers, samplerMapping); + ForEach.animationSampler(animation, function(sampler) { + sampler.input = globalMapping.accessors[sampler.input]; + sampler.output = globalMapping.accessors[sampler.output]; + }); + var channels = animation.channels; + if (defined(channels)) { + var channelsLength = channels.length; + for (i = 0; i < channelsLength; i++) { + var channel = channels[i]; + channel.sampler = samplerMapping[channel.sampler]; + var target = channel.target; + if (defined(target)) { + target.node = globalMapping.nodes[target.id]; + delete target.id; + } + } + } + }); + ForEach.material(gltf, function(material) { + if (defined(material.technique)) { + material.technique = globalMapping.techniques[material.technique]; + } + ForEach.materialValue(material, function(value, name) { + if (Array.isArray(value)) { + if (value.length === 1) { + var textureId = value[0]; + if (typeof textureId === 'string') { + value[0] = globalMapping.textures[textureId]; + } + } + } + else if (typeof value === 'string') { + material.values[name] = { + index : globalMapping.textures[value] + }; + } + }); + var extensions = material.extensions; + if (defined(extensions)) { + var materialsCommon = extensions.KHR_materials_common; + if (defined(materialsCommon)) { + ForEach.materialValue(materialsCommon, function(value, name) { + if (Array.isArray(value)) { + if (value.length === 1) { + var textureId = value[0]; + if (typeof textureId === 'string') { + value[0] = globalMapping.textures[textureId]; + } + } + } + else if (typeof value === 'string') { + materialsCommon.values[name] = { + index: globalMapping.textures[value] + }; + } + }); + } + } + }); + ForEach.image(gltf, function(image) { + var extensions = image.extensions; + if (defined(extensions)) { + var binaryGltf = extensions.KHR_binary_glTF; + if (defined(binaryGltf)) { + image.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; + image.mimeType = binaryGltf.mimeType; + delete extensions.KHR_binary_glTF; + } + if (Object.keys(extensions).length === 0) { + delete image.extensions; + } + } + if (defined(image.extras)) { + var compressedImages = image.extras.compressedImage3DTiles; + for (var type in compressedImages) { + if (compressedImages.hasOwnProperty(type)) { + var compressedImage = compressedImages[type]; + var compressedExtensions = compressedImage.extensions; + if (defined(compressedExtensions)) { + var compressedBinaryGltf = compressedExtensions.KHR_binary_glTF; + if (defined(compressedBinaryGltf)) { + compressedImage.bufferView = globalMapping.bufferViews[compressedBinaryGltf.bufferView]; + compressedImage.mimeType = compressedBinaryGltf.mimeType; + delete compressedExtensions.KHR_binary_glTF; + } + if (Object.keys(compressedExtensions).length === 0) { + delete compressedImage.extensions; + } + } + } + } + } + }); + ForEach.texture(gltf, function(texture) { + if (defined(texture.sampler)) { + texture.sampler = globalMapping.samplers[texture.sampler]; + } + if (defined(texture.source)) { + texture.source = globalMapping.images[texture.source]; + } + }); + } + + function stripProfile(gltf) { + var asset = gltf.asset; + delete asset.profile; + } + + var knownExtensions = { + CESIUM_RTC : true, + KHR_materials_common : true, + WEB3D_quantized_attributes : true }; + function requireKnownExtensions(gltf) { + var extensionsUsed = gltf.extensionsUsed; + gltf.extensionsRequired = defaultValue(gltf.extensionsRequired, []); + if (defined(extensionsUsed)) { + var extensionsUsedLength = extensionsUsed.length; + for (var i = 0; i < extensionsUsedLength; i++) { + var extension = extensionsUsed[i]; + if (defined(knownExtensions[extension])) { + gltf.extensionsRequired.push(extension); + } + } + } + } - return PolylineOutlineMaterialProperty; -}); + function removeBufferType(gltf) { + ForEach.buffer(gltf, function(buffer) { + delete buffer.type; + }); + } -define('DataSources/PositionPropertyArray',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/EventHelper', - '../Core/ReferenceFrame', - './Property' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - EventHelper, - ReferenceFrame, - Property) { - 'use strict'; + function requireAttributeSetIndex(gltf) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + if (semantic === 'TEXCOORD') { + primitive.attributes.TEXCOORD_0 = accessorId; + } else if (semantic === 'COLOR') { + primitive.attributes.COLOR_0 = accessorId; + } + }); + delete primitive.attributes.TEXCOORD; + delete primitive.attributes.COLOR; + }); + }); + ForEach.technique(gltf, function(technique) { + ForEach.techniqueParameter(technique, function(parameter) { + var semantic = parameter.semantic; + if (defined(semantic)) { + if (semantic === 'TEXCOORD') { + parameter.semantic = 'TEXCOORD_0'; + } else if (semantic === 'COLOR') { + parameter.semantic = 'COLOR_0'; + } + } + }); + }); + } - /** - * A {@link PositionProperty} whose value is an array whose items are the computed value - * of other PositionProperty instances. - * - * @alias PositionPropertyArray - * @constructor - * - * @param {Property[]} [value] An array of Property instances. - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - */ - function PositionPropertyArray(value, referenceFrame) { - this._value = undefined; - this._definitionChanged = new Event(); - this._eventHelper = new EventHelper(); - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - this.setValue(value); + var knownSemantics = { + POSITION: true, + NORMAL: true, + TEXCOORD: true, + COLOR: true, + JOINT: true, + WEIGHT: true + }; + function underscoreApplicationSpecificSemantics(gltf) { + var mappedSemantics = {}; + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + /* jshint unused:vars */ + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + if (semantic.charAt(0) !== '_') { + var setIndex = semantic.search(/_[0-9]+/g); + var strippedSemantic = semantic; + if (setIndex >= 0) { + strippedSemantic = semantic.substring(0, setIndex); + } + if (!defined(knownSemantics[strippedSemantic])) { + var newSemantic = '_' + semantic; + mappedSemantics[semantic] = newSemantic; + } + } + }); + for (var semantic in mappedSemantics) { + if (mappedSemantics.hasOwnProperty(semantic)) { + var mappedSemantic = mappedSemantics[semantic]; + var accessorId = primitive.attributes[semantic]; + if (defined(accessorId)) { + delete primitive.attributes[semantic]; + primitive.attributes[mappedSemantic] = accessorId; + } + } + } + }); + }); + ForEach.technique(gltf, function(technique) { + ForEach.techniqueParameter(technique, function(parameter) { + var mappedSemantic = mappedSemantics[parameter.semantic]; + if (defined(mappedSemantic)) { + parameter.semantic = mappedSemantic; + } + }); + }); } - defineProperties(PositionPropertyArray.prototype, { - /** - * Gets a value indicating if this property is constant. This property - * is considered constant if all property items in the array are constant. - * @memberof PositionPropertyArray.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - var value = this._value; - if (!defined(value)) { - return true; + function removeScissorFromTechniques(gltf) { + ForEach.technique(gltf, function(technique) { + var techniqueStates = technique.states; + if (defined(techniqueStates)) { + var techniqueFunctions = techniqueStates.functions; + if (defined(techniqueFunctions)) { + delete techniqueFunctions.scissor; + } + var enableStates = techniqueStates.enable; + if (defined(enableStates)) { + var scissorIndex = enableStates.indexOf(WebGLConstants.SCISSOR_TEST); + if (scissorIndex >= 0) { + enableStates.splice(scissorIndex, 1); + } } + } + }); + } - var length = value.length; - for (var i = 0; i < length; i++) { - if (!Property.isConstant(value[i])) { - return false; + function clampTechniqueFunctionStates(gltf) { + ForEach.technique(gltf, function(technique) { + var techniqueStates = technique.states; + if (defined(techniqueStates)) { + var functions = techniqueStates.functions; + if (defined(functions)) { + var blendColor = functions.blendColor; + if (defined(blendColor)) { + for (var i = 0; i < 4; i++) { + blendColor[i] = CesiumMath.clamp(blendColor[i], 0.0, 1.0); + } + } + var depthRange = functions.depthRange; + if (defined(depthRange)) { + depthRange[1] = CesiumMath.clamp(depthRange[1], 0.0, 1.0); + depthRange[0] = CesiumMath.clamp(depthRange[0], 0.0, depthRange[1]); } } - return true; } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value or one of the properties in the array also changes. - * @memberof PositionPropertyArray.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + }); + } + + function clampCameraParameters(gltf) { + ForEach.camera(gltf, function(camera) { + var perspective = camera.perspective; + if (defined(perspective)) { + var aspectRatio = perspective.aspectRatio; + if (defined(aspectRatio) && aspectRatio === 0.0) { + delete perspective.aspectRatio; + } + var yfov = perspective.yfov; + if (defined(yfov) && yfov === 0.0) { + perspective.yfov = 1.0; + } } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof PositionPropertyArray.prototype - * @type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; + }); + } + + function requireByteLength(gltf) { + ForEach.buffer(gltf, function(buffer) { + if (!defined(buffer.byteLength)) { + buffer.byteLength = buffer.extras._pipeline.source.length; } - } - }); + }); + ForEach.bufferView(gltf, function(bufferView) { + if (!defined(bufferView.byteLength)) { + var bufferViewBufferId = bufferView.buffer; + var bufferViewBuffer = gltf.buffers[bufferViewBufferId]; + bufferView.byteLength = bufferViewBuffer.byteLength; + } + }); + } - /** - * Gets the value of the property. - * - * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. - * @param {Cartesian3[]} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3[]} The modified result parameter or a new instance if the result parameter was not supplied. - */ - PositionPropertyArray.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; + function moveByteStrideToBufferView(gltf) { + var bufferViews = gltf.bufferViews; + var bufferViewsToDelete = {}; + ForEach.accessor(gltf, function(accessor) { + var oldBufferViewId = accessor.bufferView; + if (defined(oldBufferViewId)) { + if (!defined(bufferViewsToDelete[oldBufferViewId])) { + bufferViewsToDelete[oldBufferViewId] = true; + } + var bufferView = clone(bufferViews[oldBufferViewId]); + var accessorByteStride = (defined(accessor.byteStride) && accessor.byteStride !== 0) ? accessor.byteStride : getAccessorByteStride(gltf, accessor); + if (defined(accessorByteStride)) { + bufferView.byteStride = accessorByteStride; + if (bufferView.byteStride !== 0) { + bufferView.byteLength = accessor.count * accessorByteStride; + } + bufferView.byteOffset += accessor.byteOffset; + accessor.byteOffset = 0; + delete accessor.byteStride; + } + accessor.bufferView = addToArray(bufferViews, bufferView); + } + }); - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - PositionPropertyArray.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); - } - - var value = this._value; - if (!defined(value)) { - return undefined; - } + var bufferViewShiftMap = {}; + var bufferViewRemovalCount = 0; + /* jshint unused:vars */ + ForEach.bufferView(gltf, function(bufferView, bufferViewId) { + if (defined(bufferViewsToDelete[bufferViewId])) { + bufferViewRemovalCount++; + } else { + bufferViewShiftMap[bufferViewId] = bufferViewId - bufferViewRemovalCount; + } + }); - var length = value.length; - if (!defined(result)) { - result = new Array(length); - } - var i = 0; - var x = 0; - while (i < length) { - var property = value[i]; - var itemValue = property.getValueInReferenceFrame(time, referenceFrame, result[i]); - if (defined(itemValue)) { - result[x] = itemValue; - x++; + var removedCount = 0; + for (var bufferViewId in bufferViewsToDelete) { + if (defined(bufferViewId)) { + var index = parseInt(bufferViewId) - removedCount; + bufferViews.splice(index, 1); + removedCount++; } - i++; } - result.length = x; - return result; - }; - /** - * Sets the value of the property. - * - * @param {Property[]} value An array of Property instances. - */ - PositionPropertyArray.prototype.setValue = function(value) { - var eventHelper = this._eventHelper; - eventHelper.removeAll(); + ForEach.accessor(gltf, function(accessor) { + var accessorBufferView = accessor.bufferView; + if (defined(accessorBufferView)) { + accessor.bufferView = bufferViewShiftMap[accessorBufferView]; + } + }); - if (defined(value)) { - this._value = value.slice(); - var length = value.length; - for (var i = 0; i < length; i++) { - var property = value[i]; - if (defined(property)) { - eventHelper.add(property.definitionChanged, PositionPropertyArray.prototype._raiseDefinitionChanged, this); + ForEach.shader(gltf, function(shader) { + var shaderBufferView = shader.bufferView; + if (defined(shaderBufferView)) { + shader.bufferView = bufferViewShiftMap[shaderBufferView]; + } + }); + + ForEach.image(gltf, function(image) { + var imageBufferView = image.bufferView; + if (defined(imageBufferView)) { + image.bufferView = bufferViewShiftMap[imageBufferView]; + } + if (defined(image.extras)) { + var compressedImages = image.extras.compressedImage3DTiles; + for (var type in compressedImages) { + if (compressedImages.hasOwnProperty(type)) { + var compressedImage = compressedImages[type]; + var compressedImageBufferView = compressedImage.bufferView; + if (defined(compressedImageBufferView)) { + compressedImage.bufferView = bufferViewShiftMap[compressedImageBufferView]; + } + } } } - } else { - this._value = undefined; - } - this._definitionChanged.raiseEvent(this); - }; + }); + } - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - PositionPropertyArray.prototype.equals = function(other) { - return this === other || // - (other instanceof PositionPropertyArray && // - this._referenceFrame === other._referenceFrame && // - Property.arrayEquals(this._value, other._value)); - }; + function stripTechniqueAttributeValues(gltf) { + ForEach.technique(gltf, function(technique) { + ForEach.techniqueAttribute(technique, function(attribute) { + var parameter = technique.parameters[attribute]; + if (defined(parameter.value)) { + delete parameter.value; + } + }); + }); + } - PositionPropertyArray.prototype._raiseDefinitionChanged = function() { - this._definitionChanged.raiseEvent(this); - }; + function stripTechniqueParameterCount(gltf) { + ForEach.technique(gltf, function(technique) { + ForEach.techniqueParameter(technique, function(parameter) { + if (defined(parameter.count)) { + var semantic = parameter.semantic; + if (!defined(semantic) || (semantic !== 'JOINTMATRIX' && semantic.indexOf('_') !== 0)) { + delete parameter.count; + } + } + }); + }); + } - return PositionPropertyArray; + function addKHRTechniqueExtension(gltf) { + var techniques = gltf.techniques; + if (defined(techniques) && techniques.length > 0) { + addExtensionsRequired(gltf, 'KHR_technique_webgl'); + } + } + + function glTF10to20(gltf) { + if (!defined(gltf.asset)) { + gltf.asset = {}; + } + var asset = gltf.asset; + asset.version = '2.0'; + // material.instanceTechnique properties should be directly on the material. instanceTechnique is a gltf 0.8 property but is seen in some 1.0 models. + updateInstanceTechniques(gltf); + // animation.samplers now refers directly to accessors and animation.parameters should be removed + removeAnimationSamplersIndirection(gltf); + // top-level objects are now arrays referenced by index instead of id + objectsToArrays(gltf); + // asset.profile no longer exists + stripProfile(gltf); + // move known extensions from extensionsUsed to extensionsRequired + requireKnownExtensions(gltf); + // bufferView.byteLength and buffer.byteLength are required + requireByteLength(gltf); + // byteStride moved from accessor to bufferView + moveByteStrideToBufferView(gltf); + // buffer.type is unnecessary and should be removed + removeBufferType(gltf); + // TEXCOORD and COLOR attributes must be written with a set index (TEXCOORD_#) + requireAttributeSetIndex(gltf); + // Add underscores to application-specific parameters + underscoreApplicationSpecificSemantics(gltf); + // remove scissor from techniques + removeScissorFromTechniques(gltf); + // clamp technique function states to min/max + clampTechniqueFunctionStates(gltf); + // clamp camera parameters + clampCameraParameters(gltf); + // a technique parameter specified as an attribute cannot have a value + stripTechniqueAttributeValues(gltf); + // only techniques with a JOINTMATRIX or application specific semantic may have a defined count property + stripTechniqueParameterCount(gltf); + // add KHR_technique_webgl extension + addKHRTechniqueExtension(gltf); + } + return updateVersion; }); -define('DataSources/PropertyArray',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/EventHelper', - './Property' +define('ThirdParty/GltfPipeline/parseBinaryGltf',[ + './addPipelineExtras', + './removeExtensionsUsed', + './updateVersion', + '../../Core/ComponentDatatype', + '../../Core/defined', + '../../Core/DeveloperError', + '../../Core/getMagic', + '../../Core/getStringFromTypedArray', + '../../Core/WebGLConstants' ], function( + addPipelineExtras, + removeExtensionsUsed, + updateVersion, + ComponentDatatype, defined, - defineProperties, DeveloperError, - Event, - EventHelper, - Property) { + getMagic, + getStringFromTypedArray, + WebGLConstants) { 'use strict'; /** - * A {@link Property} whose value is an array whose items are the computed value - * of other property instances. - * - * @alias PropertyArray - * @constructor + * Parses a binary glTF buffer into glTF JSON. * - * @param {Property[]} [value] An array of Property instances. + * @param {Uint8Array} data The binary glTF data to parse. + * @returns {Object} The parsed binary glTF. */ - function PropertyArray(value) { - this._value = undefined; - this._definitionChanged = new Event(); - this._eventHelper = new EventHelper(); - this.setValue(value); - } + function parseBinaryGltf(data) { + var headerView = ComponentDatatype.createArrayBufferView(WebGLConstants.INT, data.buffer, data.byteOffset, 5); - defineProperties(PropertyArray.prototype, { - /** - * Gets a value indicating if this property is constant. This property - * is considered constant if all property items in the array are constant. - * @memberof PropertyArray.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - var value = this._value; - if (!defined(value)) { - return true; - } - var length = value.length; - for (var i = 0; i < length; i++) { - if (!Property.isConstant(value[i])) { - return false; - } - } - return true; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value or one of the properties in the array also changes. - * @memberof PropertyArray.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } + // Check that the magic string is present + var magic = getMagic(data); + if (magic !== 'glTF') { + throw new DeveloperError('File is not valid binary glTF'); } - }); - /** - * Gets the value of the property. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object[]} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object[]} The modified result parameter, which is an array of values produced by evaluating each of the contained properties at the given time or a new instance if the result parameter was not supplied. - */ - PropertyArray.prototype.getValue = function(time, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var value = this._value; - if (!defined(value)) { - return undefined; + // Check that the version is 1 or 2 + var version = headerView[1]; + if (version !== 1 && version !== 2) { + throw new DeveloperError('Binary glTF version is not 1 or 2'); } - var length = value.length; - if (!defined(result)) { - result = new Array(length); + var gltf; + var buffers; + var length; + // Load binary glTF version 1 + if (version === 1) { + length = headerView[2]; + var contentLength = headerView[3]; + var contentFormat = headerView[4]; + + // Check that the content format is 0, indicating that it is JSON + if (contentFormat !== 0) { + throw new DeveloperError('Binary glTF scene format is not JSON'); + } + + var jsonStart = 20; + var binaryStart = jsonStart + contentLength; + + var contentString = getStringFromTypedArray(data, jsonStart, contentLength); + gltf = JSON.parse(contentString); + + var binaryData = data.subarray(binaryStart, length); + + buffers = gltf.buffers; + if (defined(buffers) && Object.keys(buffers).length > 0) { + var binaryGltfBuffer = buffers.binary_glTF; + // In some older models, the binary glTF buffer is named KHR_binary_glTF + if (!defined(binaryGltfBuffer)) { + binaryGltfBuffer = buffers.KHR_binary_glTF; + } + if (defined(binaryGltfBuffer)) { + binaryGltfBuffer.extras = { + _pipeline: { + source: binaryData + } + }; + } + } + // Update to glTF 2.0 + updateVersion(gltf); + // Remove the KHR_binary_glTF extension + removeExtensionsUsed(gltf, 'KHR_binary_glTF'); + addPipelineExtras(gltf); } - var i = 0; - var x = 0; - while (i < length) { - var property = this._value[i]; - var itemValue = property.getValue(time, result[i]); - if (defined(itemValue)) { - result[x] = itemValue; - x++; + + // Load binary glTF version 2 + if (version === 2) { + length = headerView[2]; + var byteOffset = 12; + var binaryBuffer; + while (byteOffset < length) { + var chunkHeaderView = ComponentDatatype.createArrayBufferView(WebGLConstants.INT, data.buffer, data.byteOffset + byteOffset, 2); + var chunkLength = chunkHeaderView[0]; + var chunkType = chunkHeaderView[1]; + byteOffset += 8; + var chunkBuffer = data.subarray(byteOffset, byteOffset + chunkLength); + byteOffset += chunkLength; + // Load JSON chunk + if (chunkType === 0x4E4F534A) { + var jsonString = getStringFromTypedArray(chunkBuffer); + gltf = JSON.parse(jsonString); + addPipelineExtras(gltf); + } + // Load Binary chunk + else if (chunkType === 0x004E4942) { + binaryBuffer = chunkBuffer; + } + } + if (defined(gltf) && defined(binaryBuffer)) { + buffers = gltf.buffers; + if (defined(buffers) && buffers.length > 0) { + var buffer = buffers[0]; + buffer.extras._pipeline.source = binaryBuffer; + } } - i++; } - result.length = x; - return result; - }; + return gltf; + } + return parseBinaryGltf; +}); + +define('ThirdParty/GltfPipeline/techniqueParameterForSemantic',[ + '../../Core/defined' + ], function( + defined) { + 'use strict'; /** - * Sets the value of the property. + * Retrieves the technique parameter that has a matching semantic. * - * @param {Property[]} value An array of Property instances. + * @param {Object} technique A javascript object containing a glTF technique. + * @param {String} semantic The search string for semantics. + * @returns {String} The technique parameter with matching semantic. + * + * @private */ - PropertyArray.prototype.setValue = function(value) { - var eventHelper = this._eventHelper; - eventHelper.removeAll(); - - if (defined(value)) { - this._value = value.slice(); - var length = value.length; - for (var i = 0; i < length; i++) { - var property = value[i]; - if (defined(property)) { - eventHelper.add(property.definitionChanged, PropertyArray.prototype._raiseDefinitionChanged, this); + function techniqueParameterForSemantic(technique, semantic) { + var parameters = technique.parameters; + for (var parameterName in parameters) { + if (parameters.hasOwnProperty(parameterName)) { + var parameter = parameters[parameterName]; + var parameterSemantic = parameter.semantic; + if (defined(parameterSemantic) && parameterSemantic === semantic) { + return parameterName; } } - } else { - this._value = undefined; } - this._definitionChanged.raiseEvent(this); - }; + } + return techniqueParameterForSemantic; +}); - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - PropertyArray.prototype.equals = function(other) { - return this === other || // - (other instanceof PropertyArray && // - Property.arrayEquals(this._value, other._value)); - }; +define('ThirdParty/GltfPipeline/webGLConstantToGlslType',[ + '../../Core/WebGLConstants' + ], function( + WebGLConstants) { + 'use strict'; - PropertyArray.prototype._raiseDefinitionChanged = function() { - this._definitionChanged.raiseEvent(this); - }; + function webGLConstantToGlslType(webGLValue) { + switch (webGLValue) { + case WebGLConstants.FLOAT: + return 'float'; + case WebGLConstants.FLOAT_VEC2: + return 'vec2'; + case WebGLConstants.FLOAT_VEC3: + return 'vec3'; + case WebGLConstants.FLOAT_VEC4: + return 'vec4'; + case WebGLConstants.FLOAT_MAT2: + return 'mat2'; + case WebGLConstants.FLOAT_MAT3: + return 'mat3'; + case WebGLConstants.FLOAT_MAT4: + return 'mat4'; + case WebGLConstants.SAMPLER_2D: + return 'sampler2D'; + case WebGLConstants.BOOL: + return 'bool'; + } + } + return webGLConstantToGlslType; +}); - return PropertyArray; +define('ThirdParty/GltfPipeline/glslTypeToWebGLConstant',[ + '../../Core/WebGLConstants' + ], function( + WebGLConstants) { + 'use strict'; + + function glslTypeToWebGLConstant(glslType) { + switch (glslType) { + case 'float': + return WebGLConstants.FLOAT; + case 'vec2': + return WebGLConstants.FLOAT_VEC2; + case 'vec3': + return WebGLConstants.FLOAT_VEC3; + case 'vec4': + return WebGLConstants.FLOAT_VEC4; + case 'mat2': + return WebGLConstants.FLOAT_MAT2; + case 'mat3': + return WebGLConstants.FLOAT_MAT3; + case 'mat4': + return WebGLConstants.FLOAT_MAT4; + case 'sampler2D': + return WebGLConstants.SAMPLER_2D; + } + } + return glslTypeToWebGLConstant; }); -define('DataSources/ReferenceProperty',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/RuntimeError', - './Property' +define('ThirdParty/GltfPipeline/processModelMaterialsCommon',[ + './addToArray', + './ForEach', + './numberOfComponentsForType', + './techniqueParameterForSemantic', + './webGLConstantToGlslType', + './glslTypeToWebGLConstant', + '../../Core/clone', + '../../Core/defined', + '../../Core/defaultValue', + '../../Core/WebGLConstants' ], function( + addToArray, + ForEach, + numberOfComponentsForType, + techniqueParameterForSemantic, + webGLConstantToGlslType, + glslTypeToWebGLConstant, + clone, defined, - defineProperties, - DeveloperError, - Event, - RuntimeError, - Property) { + defaultValue, + WebGLConstants) { 'use strict'; - function resolveEntity(that) { - var entityIsResolved = true; - if (that._resolveEntity) { - var targetEntity = that._targetCollection.getById(that._targetId); + /** + * @private + */ + function processModelMaterialsCommon(gltf, options) { + options = defaultValue(options, {}); - if (defined(targetEntity)) { - targetEntity.definitionChanged.addEventListener(ReferenceProperty.prototype._onTargetEntityDefinitionChanged, that); - that._targetEntity = targetEntity; - that._resolveEntity = false; - } else { - //The property has become detached. It has a valid value but is not currently resolved to an entity in the collection - targetEntity = that._targetEntity; - entityIsResolved = false; - } + if (!defined(gltf)) { + return undefined; + } - if (!defined(targetEntity)) { - throw new RuntimeError('target entity "' + that._targetId + '" could not be resolved.'); + var hasExtension = false; + var extensionsRequired = gltf.extensionsRequired; + var extensionsUsed = gltf.extensionsUsed; + if (defined(extensionsUsed)) { + var index = extensionsUsed.indexOf('KHR_materials_common'); + if (index >= 0) { + extensionsUsed.splice(index, 1); + hasExtension = true; + } + if (defined(extensionsRequired)) { + index = extensionsRequired.indexOf('KHR_materials_common'); + if (index >= 0) { + extensionsRequired.splice(index, 1); + } } } - return entityIsResolved; - } - function resolve(that) { - var targetProperty = that._targetProperty; + if (hasExtension) { + if (!defined(gltf.programs)) { + gltf.programs = []; + } + if (!defined(gltf.shaders)) { + gltf.shaders = []; + } + if (!defined(gltf.techniques)) { + gltf.techniques = []; + } + lightDefaults(gltf); - if (that._resolveProperty) { - var entityIsResolved = resolveEntity(that); + var lightParameters = generateLightParameters(gltf); - var names = that._targetPropertyNames; - targetProperty = that._targetEntity; - var length = names.length; - for (var i = 0; i < length && defined(targetProperty); i++) { - targetProperty = targetProperty[names[i]]; - } + // Pre-processing to address incompatibilities between primitives using the same materials. Handles skinning and vertex color incompatibilities. + splitIncompatibleMaterials(gltf); - if (defined(targetProperty)) { - that._targetProperty = targetProperty; - that._resolveProperty = !entityIsResolved; - } else if (!defined(that._targetProperty)) { - throw new RuntimeError('targetProperty "' + that._targetId + '.' + names.join('.') + '" could not be resolved.'); - } - } + var techniques = {}; + ForEach.material(gltf, function(material) { + if (defined(material.extensions) && defined(material.extensions.KHR_materials_common)) { + var khrMaterialsCommon = material.extensions.KHR_materials_common; + var techniqueKey = getTechniqueKey(khrMaterialsCommon); + var technique = techniques[techniqueKey]; + if (!defined(technique)) { + technique = generateTechnique(gltf, khrMaterialsCommon, lightParameters, options); + techniques[techniqueKey] = technique; + } - return targetProperty; - } + // Take advantage of the fact that we generate techniques that use the + // same parameter names as the extension values. + material.values = {}; + var values = khrMaterialsCommon.values; + for (var valueName in values) { + if (values.hasOwnProperty(valueName)) { + var value = values[valueName]; + material.values[valueName] = value; + } + } - /** - * A {@link Property} which transparently links to another property on a provided object. - * - * @alias ReferenceProperty - * @constructor - * - * @param {EntityCollection} targetCollection The entity collection which will be used to resolve the reference. - * @param {String} targetId The id of the entity which is being referenced. - * @param {String[]} targetPropertyNames The names of the property on the target entity which we will use. - * - * @example - * var collection = new Cesium.EntityCollection(); - * - * //Create a new entity and assign a billboard scale. - * var object1 = new Cesium.Entity({id:'object1'}); - * object1.billboard = new Cesium.BillboardGraphics(); - * object1.billboard.scale = new Cesium.ConstantProperty(2.0); - * collection.add(object1); - * - * //Create a second entity and reference the scale from the first one. - * var object2 = new Cesium.Entity({id:'object2'}); - * object2.model = new Cesium.ModelGraphics(); - * object2.model.scale = new Cesium.ReferenceProperty(collection, 'object1', ['billboard', 'scale']); - * collection.add(object2); - * - * //Create a third object, but use the fromString helper function. - * var object3 = new Cesium.Entity({id:'object3'}); - * object3.billboard = new Cesium.BillboardGraphics(); - * object3.billboard.scale = Cesium.ReferenceProperty.fromString(collection, 'object1#billboard.scale'); - * collection.add(object3); - * - * //You can refer to an entity with a # or . in id and property names by escaping them. - * var object4 = new Cesium.Entity({id:'#object.4'}); - * object4.billboard = new Cesium.BillboardGraphics(); - * object4.billboard.scale = new Cesium.ConstantProperty(2.0); - * collection.add(object4); - * - * var object5 = new Cesium.Entity({id:'object5'}); - * object5.billboard = new Cesium.BillboardGraphics(); - * object5.billboard.scale = Cesium.ReferenceProperty.fromString(collection, '\\#object\\.4#billboard.scale'); - * collection.add(object5); - */ - function ReferenceProperty(targetCollection, targetId, targetPropertyNames) { - if (!defined(targetCollection)) { - throw new DeveloperError('targetCollection is required.'); - } - if (!defined(targetId) || targetId === '') { - throw new DeveloperError('targetId is required.'); - } - if (!defined(targetPropertyNames) || targetPropertyNames.length === 0) { - throw new DeveloperError('targetPropertyNames is required.'); - } - for (var i = 0; i < targetPropertyNames.length; i++) { - var item = targetPropertyNames[i]; - if (!defined(item) || item === '') { - throw new DeveloperError('reference contains invalid properties.'); + material.technique = technique; + + delete material.extensions.KHR_materials_common; + if (Object.keys(material.extensions).length === 0) { + delete material.extensions; + } + } + }); + + if (defined(gltf.extensions)) { + delete gltf.extensions.KHR_materials_common; + if (Object.keys(gltf.extensions).length === 0) { + delete gltf.extensions; + } } + + // If any primitives have semantics that aren't declared in the generated + // shaders, we want to preserve them. + ensureSemanticExistence(gltf); } - - this._targetCollection = targetCollection; - this._targetId = targetId; - this._targetPropertyNames = targetPropertyNames; - this._targetProperty = undefined; - this._targetEntity = undefined; - this._definitionChanged = new Event(); - this._resolveEntity = true; - this._resolveProperty = true; - targetCollection.collectionChanged.addEventListener(ReferenceProperty.prototype._onCollectionChanged, this); + return gltf; } - defineProperties(ReferenceProperty.prototype, { - /** - * Gets a value indicating if this property is constant. - * @memberof ReferenceProperty.prototype - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(resolve(this)); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever the referenced property's definition is changed. - * @memberof ReferenceProperty.prototype - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the reference frame that the position is defined in. - * This property is only valid if the referenced property is a {@link PositionProperty}. - * @memberof ReferenceProperty.prototype - * @type {ReferenceFrame} - * @readonly - */ - referenceFrame : { - get : function() { - return resolve(this).referenceFrame; - } - }, - /** - * Gets the id of the entity being referenced. - * @memberof ReferenceProperty.prototype - * @type {String} - * @readonly - */ - targetId : { - get : function() { - return this._targetId; - } - }, - /** - * Gets the collection containing the entity being referenced. - * @memberof ReferenceProperty.prototype - * @type {EntityCollection} - * @readonly - */ - targetCollection : { - get : function() { - return this._targetCollection; - } - }, - /** - * Gets the array of property names used to retrieve the referenced property. - * @memberof ReferenceProperty.prototype - * @type {String[]} - * @readonly - */ - targetPropertyNames : { - get : function() { - return this._targetPropertyNames; + function generateLightParameters(gltf) { + var result = {}; + + var lights; + if (defined(gltf.extensions) && defined(gltf.extensions.KHR_materials_common)) { + lights = gltf.extensions.KHR_materials_common.lights; + } + + if (defined(lights)) { + // Figure out which node references the light + var nodes = gltf.nodes; + for (var nodeName in nodes) { + if (nodes.hasOwnProperty(nodeName)) { + var node = nodes[nodeName]; + if (defined(node.extensions) && defined(node.extensions.KHR_materials_common)) { + var nodeLightId = node.extensions.KHR_materials_common.light; + if (defined(nodeLightId) && defined(lights[nodeLightId])) { + lights[nodeLightId].node = nodeName; + } + delete node.extensions.KHR_materials_common; + } + } } - }, - /** - * Gets the resolved instance of the underlying referenced property. - * @memberof ReferenceProperty.prototype - * @type {Property} - * @readonly - */ - resolvedProperty : { - get : function() { - return resolve(this); + + // Add light parameters to result + var lightCount = 0; + for (var lightName in lights) { + if (lights.hasOwnProperty(lightName)) { + var light = lights[lightName]; + var lightType = light.type; + if ((lightType !== 'ambient') && !defined(light.node)) { + delete lights[lightName]; + continue; + } + var lightBaseName = 'light' + lightCount.toString(); + light.baseName = lightBaseName; + switch (lightType) { + case 'ambient': + var ambient = light.ambient; + result[lightBaseName + 'Color'] = { + type: WebGLConstants.FLOAT_VEC3, + value: ambient.color + }; + break; + case 'directional': + var directional = light.directional; + result[lightBaseName + 'Color'] = { + type: WebGLConstants.FLOAT_VEC3, + value: directional.color + }; + if (defined(light.node)) { + result[lightBaseName + 'Transform'] = { + node: light.node, + semantic: 'MODELVIEW', + type: WebGLConstants.FLOAT_MAT4 + }; + } + break; + case 'point': + var point = light.point; + result[lightBaseName + 'Color'] = { + type: WebGLConstants.FLOAT_VEC3, + value: point.color + }; + if (defined(light.node)) { + result[lightBaseName + 'Transform'] = { + node: light.node, + semantic: 'MODELVIEW', + type: WebGLConstants.FLOAT_MAT4 + }; + } + result[lightBaseName + 'Attenuation'] = { + type: WebGLConstants.FLOAT_VEC3, + value: [point.constantAttenuation, point.linearAttenuation, point.quadraticAttenuation] + }; + break; + case 'spot': + var spot = light.spot; + result[lightBaseName + 'Color'] = { + type: WebGLConstants.FLOAT_VEC3, + value: spot.color + }; + if (defined(light.node)) { + result[lightBaseName + 'Transform'] = { + node: light.node, + semantic: 'MODELVIEW', + type: WebGLConstants.FLOAT_MAT4 + }; + result[lightBaseName + 'InverseTransform'] = { + node: light.node, + semantic: 'MODELVIEWINVERSE', + type: WebGLConstants.FLOAT_MAT4, + useInFragment: true + }; + } + result[lightBaseName + 'Attenuation'] = { + type: WebGLConstants.FLOAT_VEC3, + value: [spot.constantAttenuation, spot.linearAttenuation, spot.quadraticAttenuation] + }; + + result[lightBaseName + 'FallOff'] = { + type: WebGLConstants.FLOAT_VEC2, + value: [spot.fallOffAngle, spot.fallOffExponent] + }; + break; + } + ++lightCount; + } } } - }); - /** - * Creates a new instance given the entity collection that will - * be used to resolve it and a string indicating the target entity id and property. - * The format of the string is "objectId#foo.bar", where # separates the id from - * property path and . separates sub-properties. If the reference identifier or - * or any sub-properties contains a # . or \ they must be escaped. - * - * @param {EntityCollection} targetCollection - * @param {String} referenceString - * @returns {ReferenceProperty} A new instance of ReferenceProperty. - * - * @exception {DeveloperError} invalid referenceString. - */ - ReferenceProperty.fromString = function(targetCollection, referenceString) { - if (!defined(targetCollection)) { - throw new DeveloperError('targetCollection is required.'); - } - if (!defined(referenceString)) { - throw new DeveloperError('referenceString is required.'); - } - - var identifier; - var values = []; + return result; + } - var inIdentifier = true; - var isEscaped = false; - var token = ''; - for (var i = 0; i < referenceString.length; ++i) { - var c = referenceString.charAt(i); + function generateTechnique(gltf, khrMaterialsCommon, lightParameters, options) { + var optimizeForCesium = defaultValue(options.optimizeForCesium, false); + var hasCesiumRTCExtension = defined(gltf.extensions) && defined(gltf.extensions.CESIUM_RTC); + var addBatchIdToGeneratedShaders = defaultValue(options.addBatchIdToGeneratedShaders, false); - if (isEscaped) { - token += c; - isEscaped = false; - } else if (c === '\\') { - isEscaped = true; - } else if (inIdentifier && c === '#') { - identifier = token; - inIdentifier = false; - token = ''; - } else if (!inIdentifier && c === '.') { - values.push(token); - token = ''; - } else { - token += c; - } + var techniques = gltf.techniques; + var shaders = gltf.shaders; + var programs = gltf.programs; + var lightingModel = khrMaterialsCommon.technique.toUpperCase(); + var lights; + if (defined(gltf.extensions) && defined(gltf.extensions.KHR_materials_common)) { + lights = gltf.extensions.KHR_materials_common.lights; } - values.push(token); + var parameterValues = khrMaterialsCommon.values; + if (defined(khrMaterialsCommon.transparent)) { + parameterValues.transparent = khrMaterialsCommon.transparent; + } + if (defined(khrMaterialsCommon.doubleSided)) { + parameterValues.doubleSided = khrMaterialsCommon.doubleSided; + } + var jointCount = defaultValue(khrMaterialsCommon.jointCount, 0); - return new ReferenceProperty(targetCollection, identifier, values); - }; + var hasSkinning = jointCount > 0; + var primitiveInfo = khrMaterialsCommon.extras._pipeline.primitive; + var skinningInfo = primitiveInfo.skinning; + var hasVertexColors = primitiveInfo.hasVertexColors; - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ReferenceProperty.prototype.getValue = function(time, result) { - return resolve(this).getValue(time, result); - }; + var vertexShader = 'precision highp float;\n'; + var fragmentShader = 'precision highp float;\n'; - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * This method is only valid if the property being referenced is a {@link PositionProperty}. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - ReferenceProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - return resolve(this).getValueInReferenceFrame(time, referenceFrame, result); - }; + var hasNormals = (lightingModel !== 'CONSTANT'); - /** - * Gets the {@link Material} type at the provided time. - * This method is only valid if the property being referenced is a {@link MaterialProperty}. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - ReferenceProperty.prototype.getType = function(time) { - return resolve(this).getType(time); - }; + // Add techniques + var techniqueParameters = { + // Add matrices + modelViewMatrix: { + semantic: hasCesiumRTCExtension ? 'CESIUM_RTC_MODELVIEW' : 'MODELVIEW', + type: WebGLConstants.FLOAT_MAT4 + }, + projectionMatrix: { + semantic: 'PROJECTION', + type: WebGLConstants.FLOAT_MAT4 + } + }; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - ReferenceProperty.prototype.equals = function(other) { - if (this === other) { - return true; + if (hasNormals) { + techniqueParameters.normalMatrix = { + semantic: 'MODELVIEWINVERSETRANSPOSE', + type: WebGLConstants.FLOAT_MAT3 + }; } - var names = this._targetPropertyNames; - var otherNames = other._targetPropertyNames; - - if (this._targetCollection !== other._targetCollection || // - this._targetId !== other._targetId || // - names.length !== otherNames.length) { - return false; + if (hasSkinning) { + techniqueParameters.jointMatrix = { + count: jointCount, + semantic: 'JOINTMATRIX', + type: WebGLConstants.FLOAT_MAT4 + }; } - var length = this._targetPropertyNames.length; - for (var i = 0; i < length; i++) { - if (names[i] !== otherNames[i]) { - return false; + // Add material parameters + var lowerCase; + var hasTexCoords = false; + for (var name in parameterValues) { + //generate shader parameters for KHR_materials_common attributes + //(including a check, because some boolean flags should not be used as shader parameters) + if (parameterValues.hasOwnProperty(name) && (name !== 'transparent') && (name !== 'doubleSided')) { + var valType = getKHRMaterialsCommonValueType(name, parameterValues[name]); + lowerCase = name.toLowerCase(); + if (!hasTexCoords && (valType === WebGLConstants.SAMPLER_2D)) { + hasTexCoords = true; + } + techniqueParameters[lowerCase] = { + type: valType + }; } } - return true; - }; - - ReferenceProperty.prototype._onTargetEntityDefinitionChanged = function(targetEntity, name, value, oldValue) { - if (this._targetPropertyNames[0] === name) { - this._resolveProperty = true; - this._definitionChanged.raiseEvent(this); + // Give the diffuse uniform a semantic to support color replacement in 3D Tiles + if (defined(techniqueParameters.diffuse) && optimizeForCesium) { + techniqueParameters.diffuse.semantic = '_3DTILESDIFFUSE'; } - }; - ReferenceProperty.prototype._onCollectionChanged = function(collection, added, removed) { - var targetEntity = this._targetEntity; - if (defined(targetEntity)) { - if (removed.indexOf(targetEntity) !== -1) { - targetEntity.definitionChanged.removeEventListener(ReferenceProperty.prototype._onTargetEntityDefinitionChanged, this); - this._resolveEntity = true; - this._resolveProperty = true; - } else if (this._resolveEntity) { - //If targetEntity is defined but resolveEntity is true, then the entity is detached - //and any change to the collection needs to incur an attempt to resolve in order to re-attach. - //without this if block, a reference that becomes re-attached will not signal definitionChanged - resolve(this); - if (!this._resolveEntity) { - this._definitionChanged.raiseEvent(this); + // Copy light parameters into technique parameters + if (defined(lightParameters)) { + for (var lightParamName in lightParameters) { + if (lightParameters.hasOwnProperty(lightParamName)) { + techniqueParameters[lightParamName] = lightParameters[lightParamName]; } } } - }; - - return ReferenceProperty; -}); - -define('DataSources/Rotation',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/DeveloperError', - '../Core/Math' - ], function( - defaultValue, - defined, - DeveloperError, - CesiumMath) { - 'use strict'; - - /** - * Represents a {@link Packable} number that always interpolates values - * towards the shortest angle of rotation. This object is never used directly - * but is instead passed to the constructor of {@link SampledProperty} - * in order to represent a two-dimensional angle of rotation. - * - * @exports Rotation - * - * - * @example - * var time1 = Cesium.JulianDate.fromIso8601('2010-05-07T00:00:00'); - * var time2 = Cesium.JulianDate.fromIso8601('2010-05-07T00:01:00'); - * var time3 = Cesium.JulianDate.fromIso8601('2010-05-07T00:02:00'); - * - * var property = new Cesium.SampledProperty(Cesium.Rotation); - * property.addSample(time1, 0); - * property.addSample(time3, Cesium.Math.toRadians(350)); - * - * //Getting the value at time2 will equal 355 degrees instead - * //of 175 degrees (which is what you get if you construct - * //a SampledProperty(Number) instead. Note, the actual - * //return value is in radians, not degrees. - * property.getValue(time2); - * - * @see PackableForInterpolation - */ - var Rotation = { - /** - * The number of elements used to pack the object into an array. - * @type {Number} - */ - packedLength : 1, - /** - * Stores the provided instance into the provided array. - * - * @param {Rotation} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. - * - * @returns {Number[]} The array that was packed into - */ - pack : function(value, array, startingIndex) { - if (!defined(value)) { - throw new DeveloperError('value is required'); + // Generate uniforms object before attributes are added + var techniqueUniforms = {}; + for (var paramName in techniqueParameters) { + if (techniqueParameters.hasOwnProperty(paramName) && paramName !== 'extras') { + var param = techniqueParameters[paramName]; + techniqueUniforms['u_' + paramName] = paramName; + var arraySize = defined(param.count) ? '[' + param.count + ']' : ''; + if (((param.type !== WebGLConstants.FLOAT_MAT3) && (param.type !== WebGLConstants.FLOAT_MAT4)) || + param.useInFragment) { + fragmentShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; + delete param.useInFragment; + } else { + vertexShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; + } } + } - if (!defined(array)) { - throw new DeveloperError('array is required'); + // Add attributes with semantics + var vertexShaderMain = ''; + if (hasSkinning) { + var i, j; + var numberOfComponents = numberOfComponentsForType(skinningInfo.type); + var matrix = false; + if (skinningInfo.type.indexOf('MAT') === 0) { + matrix = true; + numberOfComponents = Math.sqrt(numberOfComponents); } - - startingIndex = defaultValue(startingIndex, 0); - array[startingIndex] = value; - - return array; - }, - - /** - * Retrieves an instance from a packed array. - * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Rotation} [result] The object into which to store the result. - * @returns {Rotation} The modified result parameter or a new Rotation instance if one was not provided. - */ - unpack : function(array, startingIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); + if (!matrix) { + for (i = 0; i < numberOfComponents; i++) { + if (i === 0) { + vertexShaderMain += ' mat4 skinMat = '; + } else { + vertexShaderMain += ' skinMat += '; + } + vertexShaderMain += 'a_weight[' + i + '] * u_jointMatrix[int(a_joint[' + i + '])];\n'; + } + } else { + for (i = 0; i < numberOfComponents; i++) { + for (j = 0; j < numberOfComponents; j++) { + if (i === 0 && j === 0) { + vertexShaderMain += ' mat4 skinMat = '; + } else { + vertexShaderMain += ' skinMat += '; + } + vertexShaderMain += 'a_weight[' + i + '][' + j + '] * u_jointMatrix[int(a_joint[' + i + '][' + j + '])];\n'; + } + } } - - startingIndex = defaultValue(startingIndex, 0); - return array[startingIndex]; - }, + } - /** - * Converts a packed array into a form suitable for interpolation. - * - * @param {Number[]} packedArray The packed array. - * @param {Number} [startingIndex=0] The index of the first element to be converted. - * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. - * @param {Number[]} result The object into which to store the result. - */ - convertPackedArrayForInterpolation : function(packedArray, startingIndex, lastIndex, result) { - if (!defined(packedArray)) { - throw new DeveloperError('packedArray is required'); - } - - startingIndex = defaultValue(startingIndex, 0); - lastIndex = defaultValue(lastIndex, packedArray.length); + // Add position always + var techniqueAttributes = { + a_position: 'position' + }; + techniqueParameters.position = { + semantic: 'POSITION', + type: WebGLConstants.FLOAT_VEC3 + }; + vertexShader += 'attribute vec3 a_position;\n'; + vertexShader += 'varying vec3 v_positionEC;\n'; + if (hasSkinning) { + vertexShaderMain += ' vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);\n'; + } else { + vertexShaderMain += ' vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);\n'; + } + vertexShaderMain += ' v_positionEC = pos.xyz;\n'; + vertexShaderMain += ' gl_Position = u_projectionMatrix * pos;\n'; + fragmentShader += 'varying vec3 v_positionEC;\n'; - var previousValue; - for (var i = 0, len = lastIndex - startingIndex + 1; i < len; i++) { - var value = packedArray[startingIndex + i]; - if (i === 0 || Math.abs(previousValue - value) < Math.PI) { - result[i] = value; - } else { - result[i] = value - CesiumMath.TWO_PI; - } - previousValue = value; + // Add normal if we don't have constant lighting + if (hasNormals) { + techniqueAttributes.a_normal = 'normal'; + techniqueParameters.normal = { + semantic: 'NORMAL', + type: WebGLConstants.FLOAT_VEC3 + }; + vertexShader += 'attribute vec3 a_normal;\n'; + vertexShader += 'varying vec3 v_normal;\n'; + if (hasSkinning) { + vertexShaderMain += ' v_normal = u_normalMatrix * mat3(skinMat) * a_normal;\n'; + } else { + vertexShaderMain += ' v_normal = u_normalMatrix * a_normal;\n'; } - }, - /** - * Retrieves an instance from a packed array converted with {@link Rotation.convertPackedArrayForInterpolation}. - * - * @param {Number[]} array The array previously packed for interpolation. - * @param {Number[]} sourceArray The original packed array. - * @param {Number} [firstIndex=0] The firstIndex used to convert the array. - * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. - * @param {Rotation} [result] The object into which to store the result. - * @returns {Rotation} The modified result parameter or a new Rotation instance if one was not provided. - */ - unpackInterpolationResult : function(array, sourceArray, firstIndex, lastIndex, result) { - if (!defined(array)) { - throw new DeveloperError('array is required'); - } - if (!defined(sourceArray)) { - throw new DeveloperError('sourceArray is required'); - } - - result = array[0]; - if (result < 0) { - return result + CesiumMath.TWO_PI; - } - return result; + fragmentShader += 'varying vec3 v_normal;\n'; } - }; - return Rotation; -}); + // Add texture coordinates if the material uses them + var v_texcoord; + if (hasTexCoords) { + techniqueAttributes.a_texcoord_0 = 'texcoord_0'; + techniqueParameters.texcoord_0 = { + semantic: 'TEXCOORD_0', + type: WebGLConstants.FLOAT_VEC2 + }; -define('DataSources/SampledProperty',[ - '../Core/binarySearch', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ExtrapolationType', - '../Core/JulianDate', - '../Core/LinearApproximation' - ], function( - binarySearch, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ExtrapolationType, - JulianDate, - LinearApproximation) { - 'use strict'; + v_texcoord = 'v_texcoord_0'; + vertexShader += 'attribute vec2 a_texcoord_0;\n'; + vertexShader += 'varying vec2 ' + v_texcoord + ';\n'; + vertexShaderMain += ' ' + v_texcoord + ' = a_texcoord_0;\n'; - var PackableNumber = { - packedLength : 1, - pack : function(value, array, startingIndex) { - startingIndex = defaultValue(startingIndex, 0); - array[startingIndex] = value; - }, - unpack : function(array, startingIndex, result) { - startingIndex = defaultValue(startingIndex, 0); - return array[startingIndex]; + fragmentShader += 'varying vec2 ' + v_texcoord + ';\n'; } - }; - //We can't use splice for inserting new elements because function apply can't handle - //a huge number of arguments. See https://code.google.com/p/chromium/issues/detail?id=56588 - function arrayInsert(array, startIndex, items) { - var i; - var arrayLength = array.length; - var itemsLength = items.length; - var newLength = arrayLength + itemsLength; + if (hasSkinning) { + techniqueAttributes.a_joint = 'joint'; + var attributeType = getShaderVariable(skinningInfo.type); + var webGLConstant = glslTypeToWebGLConstant(attributeType); - array.length = newLength; - if (arrayLength !== startIndex) { - var q = arrayLength - 1; - for (i = newLength - 1; i >= startIndex; i--) { - array[i] = array[q--]; - } - } + techniqueParameters.joint = { + semantic: 'JOINT', + type: webGLConstant + }; + techniqueAttributes.a_weight = 'weight'; + techniqueParameters.weight = { + semantic: 'WEIGHT', + type: webGLConstant + }; - for (i = 0; i < itemsLength; i++) { - array[startIndex++] = items[i]; + vertexShader += 'attribute ' + attributeType + ' a_joint;\n'; + vertexShader += 'attribute ' + attributeType + ' a_weight;\n'; } - } - function convertDate(date, epoch) { - if (date instanceof JulianDate) { - return date; + if (hasVertexColors) { + techniqueAttributes.a_vertexColor = 'vertexColor'; + techniqueParameters.vertexColor = { + semantic: 'COLOR_0', + type: WebGLConstants.FLOAT_VEC4 + }; + vertexShader += 'attribute vec4 a_vertexColor;\n'; + vertexShader += 'varying vec4 v_vertexColor;\n'; + vertexShaderMain += ' v_vertexColor = a_vertexColor;\n'; + fragmentShader += 'varying vec4 v_vertexColor;\n'; } - if (typeof date === 'string') { - return JulianDate.fromIso8601(date); + + if (addBatchIdToGeneratedShaders) { + techniqueAttributes.a_batchId = 'batchId'; + techniqueParameters.batchId = { + semantic: '_BATCHID', + type: WebGLConstants.FLOAT + }; + vertexShader += 'attribute float a_batchId;\n'; } - return JulianDate.addSeconds(epoch, date, new JulianDate()); - } - var timesSpliceArgs = []; - var valuesSpliceArgs = []; + var hasSpecular = hasNormals && ((lightingModel === 'BLINN') || (lightingModel === 'PHONG')) && + defined(techniqueParameters.specular) && defined(techniqueParameters.shininess) && + (techniqueParameters.shininess > 0.0); - function mergeNewSamples(epoch, times, values, newData, packedLength) { - var newDataIndex = 0; - var i; - var prevItem; - var timesInsertionPoint; - var valuesInsertionPoint; - var currentTime; - var nextTime; + // Generate lighting code blocks + var hasNonAmbientLights = false; + var hasAmbientLights = false; + var fragmentLightingBlock = ''; + for (var lightName in lights) { + if (lights.hasOwnProperty(lightName)) { + var light = lights[lightName]; + var lightType = light.type.toLowerCase(); + var lightBaseName = light.baseName; + fragmentLightingBlock += ' {\n'; + var lightColorName = 'u_' + lightBaseName + 'Color'; + var varyingDirectionName; + var varyingPositionName; + if (lightType === 'ambient') { + hasAmbientLights = true; + fragmentLightingBlock += ' ambientLight += ' + lightColorName + ';\n'; + } else if (hasNormals) { + hasNonAmbientLights = true; + varyingDirectionName = 'v_' + lightBaseName + 'Direction'; + varyingPositionName = 'v_' + lightBaseName + 'Position'; - while (newDataIndex < newData.length) { - currentTime = convertDate(newData[newDataIndex], epoch); - timesInsertionPoint = binarySearch(times, currentTime, JulianDate.compare); - var timesSpliceArgsCount = 0; - var valuesSpliceArgsCount = 0; + if (lightType !== 'point') { + vertexShader += 'varying vec3 ' + varyingDirectionName + ';\n'; + fragmentShader += 'varying vec3 ' + varyingDirectionName + ';\n'; - if (timesInsertionPoint < 0) { - //Doesn't exist, insert as many additional values as we can. - timesInsertionPoint = ~timesInsertionPoint; + vertexShaderMain += ' ' + varyingDirectionName + ' = mat3(u_' + lightBaseName + 'Transform) * vec3(0.,0.,1.);\n'; + if (lightType === 'directional') { + fragmentLightingBlock += ' vec3 l = normalize(' + varyingDirectionName + ');\n'; + } + } - valuesInsertionPoint = timesInsertionPoint * packedLength; - prevItem = undefined; - nextTime = times[timesInsertionPoint]; - while (newDataIndex < newData.length) { - currentTime = convertDate(newData[newDataIndex], epoch); - if ((defined(prevItem) && JulianDate.compare(prevItem, currentTime) >= 0) || (defined(nextTime) && JulianDate.compare(currentTime, nextTime) >= 0)) { - break; + if (lightType !== 'directional') { + vertexShader += 'varying vec3 ' + varyingPositionName + ';\n'; + fragmentShader += 'varying vec3 ' + varyingPositionName + ';\n'; + + vertexShaderMain += ' ' + varyingPositionName + ' = u_' + lightBaseName + 'Transform[3].xyz;\n'; + fragmentLightingBlock += ' vec3 VP = ' + varyingPositionName + ' - v_positionEC;\n'; + fragmentLightingBlock += ' vec3 l = normalize(VP);\n'; + fragmentLightingBlock += ' float range = length(VP);\n'; + fragmentLightingBlock += ' float attenuation = 1.0 / (u_' + lightBaseName + 'Attenuation.x + '; + fragmentLightingBlock += '(u_' + lightBaseName + 'Attenuation.y * range) + '; + fragmentLightingBlock += '(u_' + lightBaseName + 'Attenuation.z * range * range));\n'; + } else { + fragmentLightingBlock += ' float attenuation = 1.0;\n'; } - timesSpliceArgs[timesSpliceArgsCount++] = currentTime; - newDataIndex = newDataIndex + 1; - for (i = 0; i < packedLength; i++) { - valuesSpliceArgs[valuesSpliceArgsCount++] = newData[newDataIndex]; - newDataIndex = newDataIndex + 1; + + if (lightType === 'spot') { + fragmentLightingBlock += ' float spotDot = dot(l, normalize(' + varyingDirectionName + '));\n'; + fragmentLightingBlock += ' if (spotDot < cos(u_' + lightBaseName + 'FallOff.x * 0.5))\n'; + fragmentLightingBlock += ' {\n'; + fragmentLightingBlock += ' attenuation = 0.0;\n'; + fragmentLightingBlock += ' }\n'; + fragmentLightingBlock += ' else\n'; + fragmentLightingBlock += ' {\n'; + fragmentLightingBlock += ' attenuation *= max(0.0, pow(spotDot, u_' + lightBaseName + 'FallOff.y));\n'; + fragmentLightingBlock += ' }\n'; } - prevItem = currentTime; - } - if (timesSpliceArgsCount > 0) { - valuesSpliceArgs.length = valuesSpliceArgsCount; - arrayInsert(values, valuesInsertionPoint, valuesSpliceArgs); + fragmentLightingBlock += ' diffuseLight += ' + lightColorName + '* max(dot(normal,l), 0.) * attenuation;\n'; - timesSpliceArgs.length = timesSpliceArgsCount; - arrayInsert(times, timesInsertionPoint, timesSpliceArgs); - } - } else { - //Found an exact match - for (i = 0; i < packedLength; i++) { - newDataIndex++; - values[(timesInsertionPoint * packedLength) + i] = newData[newDataIndex]; + if (hasSpecular) { + if (lightingModel === 'BLINN') { + fragmentLightingBlock += ' vec3 h = normalize(l + viewDir);\n'; + fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n'; + } else { // PHONG + fragmentLightingBlock += ' vec3 reflectDir = reflect(-l, normal);\n'; + fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n'; + } + fragmentLightingBlock += ' specularLight += ' + lightColorName + ' * specularIntensity;\n'; + } } - newDataIndex++; + fragmentLightingBlock += ' }\n'; } } - } - /** - * A {@link Property} whose value is interpolated for a given time from the - * provided set of samples and specified interpolation algorithm and degree. - * @alias SampledProperty - * @constructor - * - * @param {Number|Packable} type The type of property. - * @param {Packable[]} [derivativeTypes] When supplied, indicates that samples will contain derivative information of the specified types. - * - * - * @example - * //Create a linearly interpolated Cartesian2 - * var property = new Cesium.SampledProperty(Cesium.Cartesian2); - * - * //Populate it with data - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:00.00Z'), new Cesium.Cartesian2(0, 0)); - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-02T00:00:00.00Z'), new Cesium.Cartesian2(4, 7)); - * - * //Retrieve an interpolated value - * var result = property.getValue(Cesium.JulianDate.fromIso8601('2012-08-01T12:00:00.00Z')); - * - * @example - * //Create a simple numeric SampledProperty that uses third degree Hermite Polynomial Approximation - * var property = new Cesium.SampledProperty(Number); - * property.setInterpolationOptions({ - * interpolationDegree : 3, - * interpolationAlgorithm : Cesium.HermitePolynomialApproximation - * }); - * - * //Populate it with data - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:00.00Z'), 1.0); - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:01:00.00Z'), 6.0); - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:02:00.00Z'), 12.0); - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:03:30.00Z'), 5.0); - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:06:30.00Z'), 2.0); - * - * //Samples can be added in any order. - * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:30.00Z'), 6.2); - * - * //Retrieve an interpolated value - * var result = property.getValue(Cesium.JulianDate.fromIso8601('2012-08-01T00:02:34.00Z')); - * - * @see SampledPositionProperty - */ - function SampledProperty(type, derivativeTypes) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - var innerType = type; - if (innerType === Number) { - innerType = PackableNumber; + if (!hasAmbientLights) { + // Add an ambient light if we don't have one + fragmentLightingBlock += ' ambientLight += vec3(0.2, 0.2, 0.2);\n'; } - var packedLength = innerType.packedLength; - var packedInterpolationLength = defaultValue(innerType.packedInterpolationLength, packedLength); - var inputOrder = 0; - var innerDerivativeTypes; - if (defined(derivativeTypes)) { - var length = derivativeTypes.length; - innerDerivativeTypes = new Array(length); - for (var i = 0; i < length; i++) { - var derivativeType = derivativeTypes[i]; - if (derivativeType === Number) { - derivativeType = PackableNumber; + if (!hasNonAmbientLights && (lightingModel !== 'CONSTANT')) { + if (optimizeForCesium) { + fragmentLightingBlock += ' vec3 l = normalize(czm_sunDirectionEC);\n'; + } else { + fragmentLightingBlock += ' vec3 l = vec3(0.0, 0.0, 1.0);\n'; + } + var minimumLighting = optimizeForCesium ? '0.2' : '0.0'; // Use strings instead of values as 0.0 -> 0 when stringified + fragmentLightingBlock += ' diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal,l), ' + minimumLighting + ');\n'; + + if (hasSpecular) { + if (lightingModel === 'BLINN') { + fragmentLightingBlock += ' vec3 h = normalize(l + viewDir);\n'; + fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n'; + } else { // PHONG + fragmentLightingBlock += ' vec3 reflectDir = reflect(-l, normal);\n'; + fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n'; } - var derivativePackedLength = derivativeType.packedLength; - packedLength += derivativePackedLength; - packedInterpolationLength += defaultValue(derivativeType.packedInterpolationLength, derivativePackedLength); - innerDerivativeTypes[i] = derivativeType; + + fragmentLightingBlock += ' specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity;\n'; } - inputOrder = length; } - this._type = type; - this._innerType = innerType; - this._interpolationDegree = 1; - this._interpolationAlgorithm = LinearApproximation; - this._numberOfPoints = 0; - this._times = []; - this._values = []; - this._xTable = []; - this._yTable = []; - this._packedLength = packedLength; - this._packedInterpolationLength = packedInterpolationLength; - this._updateTableLength = true; - this._interpolationResult = new Array(packedInterpolationLength); - this._definitionChanged = new Event(); - this._derivativeTypes = derivativeTypes; - this._innerDerivativeTypes = innerDerivativeTypes; - this._inputOrder = inputOrder; - this._forwardExtrapolationType = ExtrapolationType.NONE; - this._forwardExtrapolationDuration = 0; - this._backwardExtrapolationType = ExtrapolationType.NONE; - this._backwardExtrapolationDuration = 0; - } + vertexShader += 'void main(void) {\n'; + vertexShader += vertexShaderMain; + vertexShader += '}\n'; - defineProperties(SampledProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof SampledProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return this._values.length === 0; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof SampledProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the type of property. - * @memberof SampledProperty.prototype - * @type {Object} - */ - type : { - get : function() { - return this._type; - } - }, - /** - * Gets the derivative types used by this property. - * @memberof SampledProperty.prototype - * @type {Packable[]} - */ - derivativeTypes : { - get : function() { - return this._derivativeTypes; - } - }, - /** - * Gets the degree of interpolation to perform when retrieving a value. - * @memberof SampledProperty.prototype - * @type {Number} - * @default 1 - */ - interpolationDegree : { - get : function() { - return this._interpolationDegree; - } - }, - /** - * Gets the interpolation algorithm to use when retrieving a value. - * @memberof SampledProperty.prototype - * @type {InterpolationAlgorithm} - * @default LinearApproximation - */ - interpolationAlgorithm : { - get : function() { - return this._interpolationAlgorithm; + fragmentShader += 'void main(void) {\n'; + var colorCreationBlock = ' vec3 color = vec3(0.0, 0.0, 0.0);\n'; + if (hasNormals) { + fragmentShader += ' vec3 normal = normalize(v_normal);\n'; + if (khrMaterialsCommon.doubleSided) { + fragmentShader += ' if (gl_FrontFacing == false)\n'; + fragmentShader += ' {\n'; + fragmentShader += ' normal = -normal;\n'; + fragmentShader += ' }\n'; } - }, - /** - * Gets or sets the type of extrapolation to perform when a value - * is requested at a time after any available samples. - * @memberof SampledProperty.prototype - * @type {ExtrapolationType} - * @default ExtrapolationType.NONE - */ - forwardExtrapolationType : { - get : function() { - return this._forwardExtrapolationType; - }, - set : function(value) { - if (this._forwardExtrapolationType !== value) { - this._forwardExtrapolationType = value; - this._definitionChanged.raiseEvent(this); + } + + var finalColorComputation; + if (lightingModel !== 'CONSTANT') { + if (defined(techniqueParameters.diffuse)) { + if (techniqueParameters.diffuse.type === WebGLConstants.SAMPLER_2D) { + fragmentShader += ' vec4 diffuse = texture2D(u_diffuse, ' + v_texcoord + ');\n'; + } else { + fragmentShader += ' vec4 diffuse = u_diffuse;\n'; } + fragmentShader += ' vec3 diffuseLight = vec3(0.0, 0.0, 0.0);\n'; + colorCreationBlock += ' color += diffuse.rgb * diffuseLight;\n'; } - }, - /** - * Gets or sets the amount of time to extrapolate forward before - * the property becomes undefined. A value of 0 will extrapolate forever. - * @memberof SampledProperty.prototype - * @type {Number} - * @default 0 - */ - forwardExtrapolationDuration : { - get : function() { - return this._forwardExtrapolationDuration; - }, - set : function(value) { - if (this._forwardExtrapolationDuration !== value) { - this._forwardExtrapolationDuration = value; - this._definitionChanged.raiseEvent(this); + + if (hasSpecular) { + if (techniqueParameters.specular.type === WebGLConstants.SAMPLER_2D) { + fragmentShader += ' vec3 specular = texture2D(u_specular, ' + v_texcoord + ').rgb;\n'; + } else { + fragmentShader += ' vec3 specular = u_specular.rgb;\n'; } + fragmentShader += ' vec3 specularLight = vec3(0.0, 0.0, 0.0);\n'; + colorCreationBlock += ' color += specular * specularLight;\n'; } - }, - /** - * Gets or sets the type of extrapolation to perform when a value - * is requested at a time before any available samples. - * @memberof SampledProperty.prototype - * @type {ExtrapolationType} - * @default ExtrapolationType.NONE - */ - backwardExtrapolationType : { - get : function() { - return this._backwardExtrapolationType; - }, - set : function(value) { - if (this._backwardExtrapolationType !== value) { - this._backwardExtrapolationType = value; - this._definitionChanged.raiseEvent(this); - } + + if (defined(techniqueParameters.transparency)) { + finalColorComputation = ' gl_FragColor = vec4(color * diffuse.a * u_transparency, diffuse.a * u_transparency);\n'; + } else { + finalColorComputation = ' gl_FragColor = vec4(color * diffuse.a, diffuse.a);\n'; } - }, - /** - * Gets or sets the amount of time to extrapolate backward - * before the property becomes undefined. A value of 0 will extrapolate forever. - * @memberof SampledProperty.prototype - * @type {Number} - * @default 0 - */ - backwardExtrapolationDuration : { - get : function() { - return this._backwardExtrapolationDuration; - }, - set : function(value) { - if (this._backwardExtrapolationDuration !== value) { - this._backwardExtrapolationDuration = value; - this._definitionChanged.raiseEvent(this); - } + } else { + if (defined(techniqueParameters.transparency)) { + finalColorComputation = ' gl_FragColor = vec4(color * u_transparency, u_transparency);\n'; + } else { + finalColorComputation = ' gl_FragColor = vec4(color, 1.0);\n'; } } - }); - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - SampledProperty.prototype.getValue = function(time, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var times = this._times; - var timesLength = times.length; - if (timesLength === 0) { - return undefined; + if (hasVertexColors) { + colorCreationBlock += ' color *= v_vertexColor.rgb;\n'; } - var timeout; - var innerType = this._innerType; - var values = this._values; - var index = binarySearch(times, time, JulianDate.compare); - - if (index < 0) { - index = ~index; - - if (index === 0) { - var startTime = times[index]; - timeout = this._backwardExtrapolationDuration; - if (this._backwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(startTime, time) > timeout)) { - return undefined; - } - if (this._backwardExtrapolationType === ExtrapolationType.HOLD) { - return innerType.unpack(values, 0, result); - } - } - - if (index >= timesLength) { - index = timesLength - 1; - var endTime = times[index]; - timeout = this._forwardExtrapolationDuration; - if (this._forwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(time, endTime) > timeout)) { - return undefined; - } - if (this._forwardExtrapolationType === ExtrapolationType.HOLD) { - index = timesLength - 1; - return innerType.unpack(values, index * innerType.packedLength, result); - } + if (defined(techniqueParameters.emission)) { + if (techniqueParameters.emission.type === WebGLConstants.SAMPLER_2D) { + fragmentShader += ' vec3 emission = texture2D(u_emission, ' + v_texcoord + ').rgb;\n'; + } else { + fragmentShader += ' vec3 emission = u_emission.rgb;\n'; } + colorCreationBlock += ' color += emission;\n'; + } - var xTable = this._xTable; - var yTable = this._yTable; - var interpolationAlgorithm = this._interpolationAlgorithm; - var packedInterpolationLength = this._packedInterpolationLength; - var inputOrder = this._inputOrder; - - if (this._updateTableLength) { - this._updateTableLength = false; - var numberOfPoints = Math.min(interpolationAlgorithm.getRequiredDataPoints(this._interpolationDegree, inputOrder), timesLength); - if (numberOfPoints !== this._numberOfPoints) { - this._numberOfPoints = numberOfPoints; - xTable.length = numberOfPoints; - yTable.length = numberOfPoints * packedInterpolationLength; + if (defined(techniqueParameters.ambient) || (lightingModel !== 'CONSTANT')) { + if (defined(techniqueParameters.ambient)) { + if (techniqueParameters.ambient.type === WebGLConstants.SAMPLER_2D) { + fragmentShader += ' vec3 ambient = texture2D(u_ambient, ' + v_texcoord + ').rgb;\n'; + } else { + fragmentShader += ' vec3 ambient = u_ambient.rgb;\n'; } + } else { + fragmentShader += ' vec3 ambient = diffuse.rgb;\n'; } + colorCreationBlock += ' color += ambient * ambientLight;\n'; + } + fragmentShader += ' vec3 viewDir = -normalize(v_positionEC);\n'; + fragmentShader += ' vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n'; - var degree = this._numberOfPoints - 1; - if (degree < 1) { - return undefined; - } - - var firstIndex = 0; - var lastIndex = timesLength - 1; - var pointsInCollection = lastIndex - firstIndex + 1; - - if (pointsInCollection >= degree + 1) { - var computedFirstIndex = index - ((degree / 2) | 0) - 1; - if (computedFirstIndex < firstIndex) { - computedFirstIndex = firstIndex; - } - var computedLastIndex = computedFirstIndex + degree; - if (computedLastIndex > lastIndex) { - computedLastIndex = lastIndex; - computedFirstIndex = computedLastIndex - degree; - if (computedFirstIndex < firstIndex) { - computedFirstIndex = firstIndex; - } - } - - firstIndex = computedFirstIndex; - lastIndex = computedLastIndex; - } - var length = lastIndex - firstIndex + 1; + // Add in light computations + fragmentShader += fragmentLightingBlock; - // Build the tables - for (var i = 0; i < length; ++i) { - xTable[i] = JulianDate.secondsDifference(times[firstIndex + i], times[lastIndex]); - } + fragmentShader += colorCreationBlock; + fragmentShader += finalColorComputation; + fragmentShader += '}\n'; - if (!defined(innerType.convertPackedArrayForInterpolation)) { - var destinationIndex = 0; - var packedLength = this._packedLength; - var sourceIndex = firstIndex * packedLength; - var stop = (lastIndex + 1) * packedLength; + var techniqueStates; + if (parameterValues.transparent) { + techniqueStates = { + enable: [ + WebGLConstants.DEPTH_TEST, + WebGLConstants.BLEND + ], + functions: { + depthMask : [false], + blendEquationSeparate: [ + WebGLConstants.FUNC_ADD, + WebGLConstants.FUNC_ADD + ], + blendFuncSeparate: [ + WebGLConstants.ONE, + WebGLConstants.ONE_MINUS_SRC_ALPHA, + WebGLConstants.ONE, + WebGLConstants.ONE_MINUS_SRC_ALPHA + ] + } + }; + } else if (khrMaterialsCommon.doubleSided) { + techniqueStates = { + enable: [ + WebGLConstants.DEPTH_TEST + ] + }; + } else { // Not transparent or double sided + techniqueStates = { + enable: [ + WebGLConstants.CULL_FACE, + WebGLConstants.DEPTH_TEST + ] + }; + } - while (sourceIndex < stop) { - yTable[destinationIndex] = values[sourceIndex]; - sourceIndex++; - destinationIndex++; + // Add shaders + var vertexShaderId = addToArray(shaders, { + type: WebGLConstants.VERTEX_SHADER, + extras: { + _pipeline: { + source: vertexShader, + extension: '.glsl' } - } else { - innerType.convertPackedArrayForInterpolation(values, firstIndex, lastIndex, yTable); } + }); - // Interpolate! - var x = JulianDate.secondsDifference(time, times[lastIndex]); - var interpolationResult; - if (inputOrder === 0 || !defined(interpolationAlgorithm.interpolate)) { - interpolationResult = interpolationAlgorithm.interpolateOrderZero(x, xTable, yTable, packedInterpolationLength, this._interpolationResult); - } else { - var yStride = Math.floor(packedInterpolationLength / (inputOrder + 1)); - interpolationResult = interpolationAlgorithm.interpolate(x, xTable, yTable, yStride, inputOrder, inputOrder, this._interpolationResult); + var fragmentShaderId = addToArray(shaders, { + type: WebGLConstants.FRAGMENT_SHADER, + extras: { + _pipeline: { + source: fragmentShader, + extension: '.glsl' + } } + }); - if (!defined(innerType.unpackInterpolationResult)) { - return innerType.unpack(interpolationResult, 0, result); - } - return innerType.unpackInterpolationResult(interpolationResult, values, firstIndex, lastIndex, result); - } - return innerType.unpack(values, index * this._packedLength, result); - }; + // Add program + var programAttributes = Object.keys(techniqueAttributes); + var programId = addToArray(programs, { + attributes: programAttributes, + fragmentShader: fragmentShaderId, + vertexShader: vertexShaderId + }); - /** - * Sets the algorithm and degree to use when interpolating a value. - * - * @param {Object} [options] Object with the following properties: - * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. - * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. - */ - SampledProperty.prototype.setInterpolationOptions = function(options) { - if (!defined(options)) { - return; - } + var techniqueId = addToArray(techniques, { + attributes: techniqueAttributes, + parameters: techniqueParameters, + program: programId, + states: techniqueStates, + uniforms: techniqueUniforms + }); - var valuesChanged = false; + return techniqueId; + } - var interpolationAlgorithm = options.interpolationAlgorithm; - var interpolationDegree = options.interpolationDegree; + function getKHRMaterialsCommonValueType(paramName, paramValue) { + var value; - if (defined(interpolationAlgorithm) && this._interpolationAlgorithm !== interpolationAlgorithm) { - this._interpolationAlgorithm = interpolationAlgorithm; - valuesChanged = true; + // Backwards compatibility for COLLADA2GLTF v1.0-draft when it encoding + // materials using KHR_materials_common with explicit type/value members + if (defined(paramValue.value)) { + value = paramValue.value; + } else if (defined(paramValue.index)) { + value = [paramValue.index]; + } else { + value = paramValue; } - if (defined(interpolationDegree) && this._interpolationDegree !== interpolationDegree) { - this._interpolationDegree = interpolationDegree; - valuesChanged = true; - } + switch (paramName) { + case 'ambient': + return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; + case 'diffuse': + return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; + case 'emission': + return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; + case 'specular': + return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; + case 'shininess': + return WebGLConstants.FLOAT; + case 'transparency': + return WebGLConstants.FLOAT; - if (valuesChanged) { - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); + // these two are usually not used directly within shaders, + // they are just added here for completeness + case 'transparent': + return WebGLConstants.BOOL; + case 'doubleSided': + return WebGLConstants.BOOL; } - }; + } - /** - * Adds a new sample - * - * @param {JulianDate} time The sample time. - * @param {Packable} value The value at the provided time. - * @param {Packable[]} [derivatives] The array of derivatives at the provided time. - */ - SampledProperty.prototype.addSample = function(time, value, derivatives) { - var innerDerivativeTypes = this._innerDerivativeTypes; - var hasDerivatives = defined(innerDerivativeTypes); + function getTechniqueKey(khrMaterialsCommon) { + var techniqueKey = ''; + techniqueKey += 'technique:' + khrMaterialsCommon.technique + ';'; - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - if (hasDerivatives && !defined(derivatives)) { - throw new DeveloperError('derivatives is required.'); + var values = khrMaterialsCommon.values; + var keys = Object.keys(values).sort(); + var keysCount = keys.length; + for (var i = 0; i < keysCount; ++i) { + var name = keys[i]; + if (values.hasOwnProperty(name)) { + techniqueKey += name + ':' + getKHRMaterialsCommonValueType(name, values[name]); + techniqueKey += ';'; + } } - - var innerType = this._innerType; - var data = []; - data.push(time); - innerType.pack(value, data, data.length); - if (hasDerivatives) { - var derivativesLength = innerDerivativeTypes.length; - for (var x = 0; x < derivativesLength; x++) { - innerDerivativeTypes[x].pack(derivatives[x], data, data.length); - } + var doubleSided = defaultValue(khrMaterialsCommon.doubleSided, defaultValue(khrMaterialsCommon.values.doubleSided, false)); + techniqueKey += doubleSided.toString() + ';'; + var transparent = defaultValue(khrMaterialsCommon.transparent, defaultValue(khrMaterialsCommon.values.transparent, false)); + techniqueKey += transparent.toString() + ';'; + var jointCount = defaultValue(khrMaterialsCommon.jointCount, 0); + techniqueKey += jointCount.toString() + ';'; + var primitiveInfo = khrMaterialsCommon.extras._pipeline.primitive; + var skinningInfo = primitiveInfo.skinning; + if (jointCount > 0) { + techniqueKey += skinningInfo.type + ';'; } - mergeNewSamples(undefined, this._times, this._values, data, this._packedLength); - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - }; + techniqueKey += primitiveInfo.hasVertexColors; - /** - * Adds an array of samples - * - * @param {JulianDate[]} times An array of JulianDate instances where each index is a sample time. - * @param {Packable[]} values The array of values, where each value corresponds to the provided times index. - * @param {Array[]} [derivativeValues] An array where each item is the array of derivatives at the equivalent time index. - * - * @exception {DeveloperError} times and values must be the same length. - * @exception {DeveloperError} times and derivativeValues must be the same length. - */ - SampledProperty.prototype.addSamples = function(times, values, derivativeValues) { - var innerDerivativeTypes = this._innerDerivativeTypes; - var hasDerivatives = defined(innerDerivativeTypes); + return techniqueKey; + } - if (!defined(times)) { - throw new DeveloperError('times is required.'); - } - if (!defined(values)) { - throw new DeveloperError('values is required.'); - } - if (times.length !== values.length) { - throw new DeveloperError('times and values must be the same length.'); - } - if (hasDerivatives && (!defined(derivativeValues) || derivativeValues.length !== times.length)) { - throw new DeveloperError('times and derivativeValues must be the same length.'); + function lightDefaults(gltf) { + if (!defined(gltf.extensions)) { + gltf.extensions = {}; } - - var innerType = this._innerType; - var length = times.length; - var data = []; - for (var i = 0; i < length; i++) { - data.push(times[i]); - innerType.pack(values[i], data, data.length); + var extensions = gltf.extensions; - if (hasDerivatives) { - var derivatives = derivativeValues[i]; - var derivativesLength = innerDerivativeTypes.length; - for (var x = 0; x < derivativesLength; x++) { - innerDerivativeTypes[x].pack(derivatives[x], data, data.length); - } - } + if (!defined(extensions.KHR_materials_common)) { + extensions.KHR_materials_common = {}; } - mergeNewSamples(undefined, this._times, this._values, data, this._packedLength); - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - }; + var khrMaterialsCommon = extensions.KHR_materials_common; - /** - * Adds samples as a single packed array where each new sample is represented as a date, - * followed by the packed representation of the corresponding value and derivatives. - * - * @param {Number[]} packedSamples The array of packed samples. - * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. - */ - SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) { - if (!defined(packedSamples)) { - throw new DeveloperError('packedSamples is required.'); + if (!defined(khrMaterialsCommon.lights)) { + khrMaterialsCommon.lights = {}; } - - mergeNewSamples(epoch, this._times, this._values, packedSamples, this._packedLength); - this._updateTableLength = true; - this._definitionChanged.raiseEvent(this); - }; + var lights = khrMaterialsCommon.lights; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - SampledProperty.prototype.equals = function(other) { - if (this === other) { - return true; - } - if (!defined(other)) { - return false; - } + var lightsLength = lights.length; + for (var lightId = 0; lightId < lightsLength; lightId++) { + var light = lights[lightId]; + if (light.type === 'ambient') { + if (!defined(light.ambient)) { + light.ambient = {}; + } + var ambientLight = light.ambient; - if (this._type !== other._type || // - this._interpolationDegree !== other._interpolationDegree || // - this._interpolationAlgorithm !== other._interpolationAlgorithm) { - return false; - } + if (!defined(ambientLight.color)) { + ambientLight.color = [1.0, 1.0, 1.0]; + } + } else if (light.type === 'directional') { + if (!defined(light.directional)) { + light.directional = {}; + } + var directionalLight = light.directional; - var derivativeTypes = this._derivativeTypes; - var hasDerivatives = defined(derivativeTypes); - var otherDerivativeTypes = other._derivativeTypes; - var otherHasDerivatives = defined(otherDerivativeTypes); - if (hasDerivatives !== otherHasDerivatives) { - return false; - } + if (!defined(directionalLight.color)) { + directionalLight.color = [1.0, 1.0, 1.0]; + } + } else if (light.type === 'point') { + if (!defined(light.point)) { + light.point = {}; + } + var pointLight = light.point; - var i; - var length; - if (hasDerivatives) { - length = derivativeTypes.length; - if (length !== otherDerivativeTypes.length) { - return false; - } + if (!defined(pointLight.color)) { + pointLight.color = [1.0, 1.0, 1.0]; + } - for (i = 0; i < length; i++) { - if (derivativeTypes[i] !== otherDerivativeTypes[i]) { - return false; + pointLight.constantAttenuation = defaultValue(pointLight.constantAttenuation, 1.0); + pointLight.linearAttenuation = defaultValue(pointLight.linearAttenuation, 0.0); + pointLight.quadraticAttenuation = defaultValue(pointLight.quadraticAttenuation, 0.0); + } else if (light.type === 'spot') { + if (!defined(light.spot)) { + light.spot = {}; } - } - } + var spotLight = light.spot; - var times = this._times; - var otherTimes = other._times; - length = times.length; + if (!defined(spotLight.color)) { + spotLight.color = [1.0, 1.0, 1.0]; + } - if (length !== otherTimes.length) { - return false; + spotLight.constantAttenuation = defaultValue(spotLight.constantAttenuation, 1.0); + spotLight.fallOffAngle = defaultValue(spotLight.fallOffAngle, 3.14159265); + spotLight.fallOffExponent = defaultValue(spotLight.fallOffExponent, 0.0); + spotLight.linearAttenuation = defaultValue(spotLight.linearAttenuation, 0.0); + spotLight.quadraticAttenuation = defaultValue(spotLight.quadraticAttenuation, 0.0); + } } + } - for (i = 0; i < length; i++) { - if (!JulianDate.equals(times[i], otherTimes[i])) { - return false; - } + function getShaderVariable(type) { + if (type === 'SCALAR') { + return 'float'; } + return type.toLowerCase(); + } - var values = this._values; - var otherValues = other._values; - for (i = 0; i < length; i++) { - if (values[i] !== otherValues[i]) { - return false; + function ensureSemanticExistenceForPrimitive(gltf, primitive) { + var accessors = gltf.accessors; + var materials = gltf.materials; + var techniques = gltf.techniques; + var programs = gltf.programs; + var shaders = gltf.shaders; + + var attributes = primitive.attributes; + var material = materials[primitive.material]; + var technique = techniques[material.technique]; + var program = programs[technique.program]; + var vertexShader = shaders[program.vertexShader]; + + for (var semantic in attributes) { + if (attributes.hasOwnProperty(semantic)) { + if (!defined(techniqueParameterForSemantic(technique, semantic))) { + var accessorId = attributes[semantic]; + var accessor = accessors[accessorId]; + var lowerCase = semantic.toLowerCase(); + if (lowerCase.charAt(0) === '_') { + lowerCase = lowerCase.slice(1); + } + var attributeName = 'a_' + lowerCase; + technique.parameters[lowerCase] = { + semantic: semantic, + type: accessor.componentType + }; + technique.attributes[attributeName] = lowerCase; + program.attributes.push(attributeName); + var pipelineExtras = vertexShader.extras._pipeline; + var shaderText = pipelineExtras.source; + shaderText = 'attribute ' + getShaderVariable(accessor.type) + ' ' + attributeName + ';\n' + shaderText; + pipelineExtras.source = shaderText; + } } } + } - return true; - }; + function ensureSemanticExistence(gltf) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + ensureSemanticExistenceForPrimitive(gltf, primitive); + }); + }); + } - //Exposed for testing. - SampledProperty._mergeNewSamples = mergeNewSamples; + function splitIncompatibleMaterials(gltf) { + var accessors = gltf.accessors; + var materials = gltf.materials; + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + var materialId = primitive.material; + var material = materials[materialId]; - return SampledProperty; + if (defined(material.extensions) && defined(material.extensions.KHR_materials_common)) { + var khrMaterialsCommon = material.extensions.KHR_materials_common; + var jointAccessorId = primitive.attributes.JOINT; + var componentType; + var type; + if (defined(jointAccessorId)) { + var jointAccessor = accessors[jointAccessorId]; + componentType = jointAccessor.componentType; + type = jointAccessor.type; + } + var isSkinned = defined(jointAccessorId); + var hasVertexColors = defined(primitive.attributes.COLOR_0); + + var primitiveInfo = khrMaterialsCommon.extras._pipeline.primitive; + if (!defined(primitiveInfo)) { + khrMaterialsCommon.extras._pipeline.primitive = { + skinning : { + skinned: isSkinned, + componentType: componentType, + type: type + }, + hasVertexColors : hasVertexColors + }; + } else if ((primitiveInfo.skinning.skinned !== isSkinned) || (primitiveInfo.skinning.type !== type) || (primitiveInfo.hasVertexColors !== hasVertexColors)) { + // This primitive uses the same material as another one that either: + // * Isn't skinned + // * Uses a different type to store joints and weights + // * Doesn't have vertex colors + var clonedMaterial = clone(material, true); + clonedMaterial.extensions.KHR_materials_common.extras._pipeline.primitive = { + skinning : { + skinned: isSkinned, + componentType: componentType, + type: type + }, + hasVertexColors : hasVertexColors + }; + // Split this off as a separate material + materialId = addToArray(materials, clonedMaterial); + primitive.material = materialId; + } + } + }); + }); + } + + return processModelMaterialsCommon; }); -define('DataSources/SampledPositionProperty',[ - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame', - './PositionProperty', - './Property', - './SampledProperty' +define('ThirdParty/GltfPipeline/processPbrMetallicRoughness',[ + './addToArray', + './ForEach', + './numberOfComponentsForType', + './techniqueParameterForSemantic', + './webGLConstantToGlslType', + './glslTypeToWebGLConstant', + '../../Core/clone', + '../../Core/defined', + '../../Core/defaultValue', + '../../Core/WebGLConstants' ], function( - Cartesian3, - defaultValue, + addToArray, + ForEach, + numberOfComponentsForType, + techniqueParameterForSemantic, + webGLConstantToGlslType, + glslTypeToWebGLConstant, + clone, defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame, - PositionProperty, - Property, - SampledProperty) { + defaultValue, + WebGLConstants) { 'use strict'; /** - * A {@link SampledProperty} which is also a {@link PositionProperty}. - * - * @alias SampledPositionProperty - * @constructor - * - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - * @param {Number} [numberOfDerivatives=0] The number of derivatives that accompany each position; i.e. velocity, acceleration, etc... + * @private */ - function SampledPositionProperty(referenceFrame, numberOfDerivatives) { - numberOfDerivatives = defaultValue(numberOfDerivatives, 0); + function processPbrMetallicRoughness(gltf, options) { + options = defaultValue(options, {}); - var derivativeTypes; - if (numberOfDerivatives > 0) { - derivativeTypes = new Array(numberOfDerivatives); - for (var i = 0; i < numberOfDerivatives; i++) { - derivativeTypes[i] = Cartesian3; + var hasPbrMetallicRoughness = false; + ForEach.material(gltf, function(material) { + if (defined(material.pbrMetallicRoughness)) { + hasPbrMetallicRoughness = true; } - } - - this._numberOfDerivatives = numberOfDerivatives; - this._property = new SampledProperty(Cartesian3, derivativeTypes); - this._definitionChanged = new Event(); - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - - this._property._definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); - } + }); - defineProperties(SampledPositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof SampledPositionProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return this._property.isConstant; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof SampledPositionProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof SampledPositionProperty.prototype - * @type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; - } - }, - /** - * Gets the degree of interpolation to perform when retrieving a value. - * @memberof SampledPositionProperty.prototype - * - * @type {Number} - * @default 1 - */ - interpolationDegree : { - get : function() { - return this._property.interpolationDegree; - } - }, - /** - * Gets the interpolation algorithm to use when retrieving a value. - * @memberof SampledPositionProperty.prototype - * - * @type {InterpolationAlgorithm} - * @default LinearApproximation - */ - interpolationAlgorithm : { - get : function() { - return this._property.interpolationAlgorithm; - } - }, - /** - * The number of derivatives contained by this property; i.e. 0 for just position, 1 for velocity, etc. - * @memberof SampledPositionProperty.prototype - * - * @type {Boolean} - * @default false - */ - numberOfDerivatives : { - get : function() { - return this._numberOfDerivatives; - } - }, - /** - * Gets or sets the type of extrapolation to perform when a value - * is requested at a time after any available samples. - * @memberof SampledPositionProperty.prototype - * @type {ExtrapolationType} - * @default ExtrapolationType.NONE - */ - forwardExtrapolationType : { - get : function() { - return this._property.forwardExtrapolationType; - }, - set : function(value) { - this._property.forwardExtrapolationType = value; + if (hasPbrMetallicRoughness) { + if (!defined(gltf.programs)) { + gltf.programs = []; } - }, - /** - * Gets or sets the amount of time to extrapolate forward before - * the property becomes undefined. A value of 0 will extrapolate forever. - * @memberof SampledPositionProperty.prototype - * @type {Number} - * @default 0 - */ - forwardExtrapolationDuration : { - get : function() { - return this._property.forwardExtrapolationDuration; - }, - set : function(value) { - this._property.forwardExtrapolationDuration = value; + if (!defined(gltf.shaders)) { + gltf.shaders = []; } - }, - /** - * Gets or sets the type of extrapolation to perform when a value - * is requested at a time before any available samples. - * @memberof SampledPositionProperty.prototype - * @type {ExtrapolationType} - * @default ExtrapolationType.NONE - */ - backwardExtrapolationType : { - get : function() { - return this._property.backwardExtrapolationType; - }, - set : function(value) { - this._property.backwardExtrapolationType = value; + if (!defined(gltf.techniques)) { + gltf.techniques = []; } - }, - /** - * Gets or sets the amount of time to extrapolate backward - * before the property becomes undefined. A value of 0 will extrapolate forever. - * @memberof SampledPositionProperty.prototype - * @type {Number} - * @default 0 - */ - backwardExtrapolationDuration : { - get : function() { - return this._property.backwardExtrapolationDuration; - }, - set : function(value) { - this._property.backwardExtrapolationDuration = value; + + // Pre-processing to address incompatibilities between primitives using the same materials. Handles skinning and vertex color incompatibilities. + splitIncompatibleMaterials(gltf); + + ForEach.material(gltf, function(material) { + var pbrMetallicRoughness = material.pbrMetallicRoughness; + if (defined(pbrMetallicRoughness)) { + var technique = generateTechnique(gltf, material, options); + + material.values = pbrMetallicRoughness; + material.technique = technique; + delete material.pbrMetallicRoughness; + } + }); + + // If any primitives have semantics that aren't declared in the generated + // shaders, we want to preserve them. + ensureSemanticExistence(gltf); + } + + return gltf; + } + + function generateTechnique(gltf, material, options) { + var optimizeForCesium = defaultValue(options.optimizeForCesium, false); + var hasCesiumRTCExtension = defined(gltf.extensions) && defined(gltf.extensions.CESIUM_RTC); + var addBatchIdToGeneratedShaders = defaultValue(options.addBatchIdToGeneratedShaders, false); + + var techniques = gltf.techniques; + var shaders = gltf.shaders; + var programs = gltf.programs; + + var parameterValues = material.pbrMetallicRoughness; + for (var additional in material) { + if (material.hasOwnProperty(additional) && ((additional.indexOf('Texture') >= 0) || additional.indexOf('Factor') >= 0) || additional === 'doubleSided') { + parameterValues[additional] = material[additional]; } } - }); - /** - * Gets the position at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - SampledPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; + var vertexShader = 'precision highp float;\n'; + var fragmentShader = 'precision highp float;\n'; - /** - * Gets the position at the provided time and in the provided reference frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - SampledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + var skin; + if (defined(gltf.skins)) { + skin = gltf.skins[0]; } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); + var joints = (defined(skin)) ? skin.joints : []; + var jointCount = joints.length; + var primitiveInfo = material.extras._pipeline.primitive; + var skinningInfo = primitiveInfo.skinning; + var hasSkinning = skinningInfo.skinned; + var hasVertexColors = primitiveInfo.hasVertexColors; + + var hasNormals = true; + var hasTangents = false; + var hasMorphTargets = false; + var morphTargets; + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + var targets = primitive.targets; + if (!hasMorphTargets && defined(targets)) { + hasMorphTargets = true; + morphTargets = targets; + } + var attributes = primitive.attributes; + for (var attribute in attributes) { + if (attribute.indexOf('TANGENT') >= 0) { + hasTangents = true; + } + } + }); + }); + + // Add techniques + var techniqueParameters = { + // Add matrices + modelViewMatrix : { + semantic : hasCesiumRTCExtension ? 'CESIUM_RTC_MODELVIEW' : 'MODELVIEW', + type : WebGLConstants.FLOAT_MAT4 + }, + projectionMatrix : { + semantic : 'PROJECTION', + type : WebGLConstants.FLOAT_MAT4 + } + }; + + if (hasNormals) { + techniqueParameters.normalMatrix = { + semantic : 'MODELVIEWINVERSETRANSPOSE', + type : WebGLConstants.FLOAT_MAT3 + }; } - - result = this._property.getValue(time, result); - if (defined(result)) { - return PositionProperty.convertToReferenceFrame(time, result, this._referenceFrame, referenceFrame, result); + + if (hasSkinning) { + techniqueParameters.jointMatrix = { + count : jointCount, + semantic : 'JOINTMATRIX', + type : WebGLConstants.FLOAT_MAT4 + }; } - return undefined; - }; - /** - * Sets the algorithm and degree to use when interpolating a position. - * - * @param {Object} [options] Object with the following properties: - * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. - * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. - */ - SampledPositionProperty.prototype.setInterpolationOptions = function(options) { - this._property.setInterpolationOptions(options); - }; + if (hasMorphTargets) { + techniqueParameters.morphWeights = { + count : morphTargets.length, + semantic : 'MORPHWEIGHTS', + type : WebGLConstants.FLOAT + }; + } - /** - * Adds a new sample. - * - * @param {JulianDate} time The sample time. - * @param {Cartesian3} position The position at the provided time. - * @param {Cartesian3[]} [derivatives] The array of derivative values at the provided time. - */ - SampledPositionProperty.prototype.addSample = function(time, position, derivatives) { - var numberOfDerivatives = this._numberOfDerivatives; - if (numberOfDerivatives > 0 && (!defined(derivatives) || derivatives.length !== numberOfDerivatives)) { - throw new DeveloperError('derivatives length must be equal to the number of derivatives.'); + // Add material parameters + var hasTexCoords = false; + for (var name in parameterValues) { + //generate shader parameters + if (parameterValues.hasOwnProperty(name)) { + var valType = getPBRValueType(name); + if (!hasTexCoords && (valType === WebGLConstants.SAMPLER_2D)) { + hasTexCoords = true; + } + techniqueParameters[name] = { + type : valType + }; + } } - this._property.addSample(time, position, derivatives); - }; - /** - * Adds multiple samples via parallel arrays. - * - * @param {JulianDate[]} times An array of JulianDate instances where each index is a sample time. - * @param {Cartesian3[]} positions An array of Cartesian3 position instances, where each value corresponds to the provided time index. - * @param {Array[]} [derivatives] An array where each value is another array containing derivatives for the corresponding time index. - * - * @exception {DeveloperError} All arrays must be the same length. - */ - SampledPositionProperty.prototype.addSamples = function(times, positions, derivatives) { - this._property.addSamples(times, positions, derivatives); - }; + // Generate uniforms object before attributes are added + var techniqueUniforms = {}; + for (var paramName in techniqueParameters) { + if (techniqueParameters.hasOwnProperty(paramName) && paramName !== 'extras') { + var param = techniqueParameters[paramName]; + techniqueUniforms['u_' + paramName] = paramName; + var arraySize = defined(param.count) ? '[' + param.count + ']' : ''; + if (((param.type !== WebGLConstants.FLOAT_MAT3) && (param.type !== WebGLConstants.FLOAT_MAT4) && (paramName !== 'morphWeights')) || + param.useInFragment) { + fragmentShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; + delete param.useInFragment; + } else { + vertexShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; + } + } + } - /** - * Adds samples as a single packed array where each new sample is represented as a date, - * followed by the packed representation of the corresponding value and derivatives. - * - * @param {Number[]} packedSamples The array of packed samples. - * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. - */ - SampledPositionProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) { - this._property.addSamplesPackedArray(packedSamples, epoch); - }; + // Add attributes with semantics + var vertexShaderMain = ''; + if (hasSkinning) { + var i, j; + var numberOfComponents = numberOfComponentsForType(skinningInfo.type); + var matrix = false; + if (skinningInfo.type.indexOf('MAT') === 0) { + matrix = true; + numberOfComponents = Math.sqrt(numberOfComponents); + } + if (!matrix) { + for (i = 0; i < numberOfComponents; i++) { + if (i === 0) { + vertexShaderMain += ' mat4 skinMatrix = '; + } else { + vertexShaderMain += ' skinMatrix += '; + } + vertexShaderMain += 'a_weight[' + i + '] * u_jointMatrix[int(a_joint[' + i + '])];\n'; + } + } else { + for (i = 0; i < numberOfComponents; i++) { + for (j = 0; j < numberOfComponents; j++) { + if (i === 0 && j === 0) { + vertexShaderMain += ' mat4 skinMatrix = '; + } else { + vertexShaderMain += ' skinMatrix += '; + } + vertexShaderMain += 'a_weight[' + i + '][' + j + '] * u_jointMatrix[int(a_joint[' + i + '][' + j + '])];\n'; + } + } + } + } - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - SampledPositionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof SampledPositionProperty && - Property.equals(this._property, other._property) && // - this._referenceFrame === other._referenceFrame); - }; + // Add position always + var techniqueAttributes = { + a_position : 'position' + }; + techniqueParameters.position = { + semantic : 'POSITION', + type : WebGLConstants.FLOAT_VEC3 + }; + vertexShader += 'attribute vec3 a_position;\n'; + vertexShader += 'varying vec3 v_positionEC;\n'; + if (optimizeForCesium) { + vertexShader += 'varying vec3 v_positionWC;\n'; + } - return SampledPositionProperty; -}); + // Morph Target Weighting + vertexShaderMain += ' vec3 weightedPosition = a_position;\n'; + if (hasNormals) { + vertexShaderMain += ' vec3 weightedNormal = a_normal;\n'; + } + if (hasTangents) { + vertexShaderMain += ' vec3 weightedTangent = a_tangent;\n'; + } + if (hasMorphTargets) { + for (var k = 0; k < morphTargets.length; k++) { + var targetAttributes = morphTargets[k]; + for (var targetAttribute in targetAttributes) { + if (targetAttributes.hasOwnProperty(targetAttribute) && targetAttribute !== 'extras') { + var attributeLower = targetAttribute.toLowerCase() + '_' + k; + techniqueAttributes['a_' + attributeLower] = attributeLower; + techniqueParameters[attributeLower] = { + semantic : targetAttribute + '_' + k, + type : WebGLConstants.FLOAT_VEC3 + }; + vertexShader += 'attribute vec3 a_' + attributeLower + ';\n'; + if (targetAttribute === 'POSITION') { + vertexShaderMain += ' weightedPosition += u_morphWeights[' + k + '] * a_' + attributeLower + ';\n'; + } else if (targetAttribute === 'NORMAL') { + vertexShaderMain += ' weightedNormal += u_morphWeights[' + k + '] * a_' + attributeLower + ';\n'; + } else if (targetAttribute === 'TANGENT') { + vertexShaderMain += ' weightedTangent += u_morphWeights[' + k + '] * a_' + attributeLower + ';\n'; + } + } + } + } + } -define('DataSources/StripeOrientation',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + // Final position computation + if (hasSkinning) { + vertexShaderMain += ' vec4 position = skinMatrix * vec4(weightedPosition, 1.0);\n'; + } else { + vertexShaderMain += ' vec4 position = vec4(weightedPosition, 1.0);\n'; + } + if (optimizeForCesium) { + vertexShaderMain += ' v_positionWC = (czm_model * position).xyz;\n'; + } + vertexShaderMain += ' position = u_modelViewMatrix * position;\n'; + vertexShaderMain += ' v_positionEC = position.xyz;\n'; + vertexShaderMain += ' gl_Position = u_projectionMatrix * position;\n'; + fragmentShader += 'varying vec3 v_positionEC;\n'; + if (optimizeForCesium) { + fragmentShader += 'varying vec3 v_positionWC;\n'; + } - /** - * Defined the orientation of stripes in {@link StripeMaterialProperty}. - * - * @exports StripeOrientation - */ - var StripeOrientation = { - /** - * Horizontal orientation. - * @type {Number} - */ - HORIZONTAL : 0, + // Final normal computation + if (hasNormals) { + techniqueAttributes.a_normal = 'normal'; + techniqueParameters.normal = { + semantic : 'NORMAL', + type : WebGLConstants.FLOAT_VEC3 + }; + vertexShader += 'attribute vec3 a_normal;\n'; + vertexShader += 'varying vec3 v_normal;\n'; + if (hasSkinning) { + vertexShaderMain += ' v_normal = u_normalMatrix * mat3(skinMatrix) * weightedNormal;\n'; + } else { + vertexShaderMain += ' v_normal = u_normalMatrix * weightedNormal;\n'; + } - /** - * Vertical orientation. - * @type {Number} - */ - VERTICAL : 1 - }; + fragmentShader += 'varying vec3 v_normal;\n'; + } + + // Read tangents if available + if (hasTangents) { + techniqueAttributes.a_tangent = 'tangent'; + techniqueParameters.tangent = { + semantic : 'TANGENT', + type : WebGLConstants.FLOAT_VEC3 + }; + vertexShader += 'attribute vec3 a_tangent;\n'; + vertexShader += 'varying vec3 v_tangent;\n'; + vertexShaderMain += ' v_tangent = (u_modelViewMatrix * vec4(weightedTangent, 1.0)).xyz;\n'; - return freezeObject(StripeOrientation); -}); + fragmentShader += 'varying vec3 v_tangent;\n'; + } -define('DataSources/StripeMaterialProperty',[ - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - './createPropertyDescriptor', - './Property', - './StripeOrientation' - ], function( - Color, - defaultValue, - defined, - defineProperties, - Event, - createPropertyDescriptor, - Property, - StripeOrientation) { - 'use strict'; + // Add texture coordinates if the material uses them + var v_texcoord; + if (hasTexCoords) { + techniqueAttributes.a_texcoord_0 = 'texcoord_0'; + techniqueParameters.texcoord_0 = { + semantic : 'TEXCOORD_0', + type : WebGLConstants.FLOAT_VEC2 + }; - var defaultOrientation = StripeOrientation.HORIZONTAL; - var defaultEvenColor = Color.WHITE; - var defaultOddColor = Color.BLACK; - var defaultOffset = 0; - var defaultRepeat = 1; + v_texcoord = 'v_texcoord_0'; + vertexShader += 'attribute vec2 a_texcoord_0;\n'; + vertexShader += 'varying vec2 ' + v_texcoord + ';\n'; + vertexShaderMain += ' ' + v_texcoord + ' = a_texcoord_0;\n'; - /** - * A {@link MaterialProperty} that maps to stripe {@link Material} uniforms. - * @alias StripeMaterialProperty - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Property} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}. - * @param {Property} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}. - * @param {Property} [options.repeat=1] A numeric Property specifying how many times the stripes repeat. - * @param {Property} [options.offset=0] A numeric Property specifying how far into the pattern to start the material. - * @param {Property} [options.orientation=StripeOrientation.HORIZONTAL] A Property specifying the {@link StripeOrientation}. - */ - function StripeMaterialProperty(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + fragmentShader += 'varying vec2 ' + v_texcoord + ';\n'; + } - this._definitionChanged = new Event(); + // Add skinning information if available + if (hasSkinning) { + techniqueAttributes.a_joint = 'joint'; + var attributeType = getShaderVariable(skinningInfo.type); + var webGLConstant = glslTypeToWebGLConstant(attributeType); - this._orientation = undefined; - this._orientationSubscription = undefined; + techniqueParameters.joint = { + semantic : 'JOINTS_0', + type : webGLConstant + }; + techniqueAttributes.a_weight = 'weight'; + techniqueParameters.weight = { + semantic : 'WEIGHTS_0', + type : webGLConstant + }; - this._evenColor = undefined; - this._evenColorSubscription = undefined; + vertexShader += 'attribute ' + attributeType + ' a_joint;\n'; + vertexShader += 'attribute ' + attributeType + ' a_weight;\n'; + } - this._oddColor = undefined; - this._oddColorSubscription = undefined; + if (hasVertexColors) { + techniqueAttributes.a_vertexColor = 'vertexColor'; + techniqueParameters.vertexColor = { + semantic: 'COLOR_0', + type: WebGLConstants.FLOAT_VEC4 + }; + vertexShader += 'attribute vec4 a_vertexColor;\n'; + vertexShader += 'varying vec4 v_vertexColor;\n'; + vertexShaderMain += ' v_vertexColor = a_vertexColor;\n'; + fragmentShader += 'varying vec4 v_vertexColor;\n'; + } - this._offset = undefined; - this._offsetSubscription = undefined; + if (addBatchIdToGeneratedShaders) { + techniqueAttributes.a_batchId = 'batchId'; + techniqueParameters.batchId = { + semantic: '_BATCHID', + type: WebGLConstants.FLOAT + }; + vertexShader += 'attribute float a_batchId;\n'; + } - this._repeat = undefined; - this._repeatSubscription = undefined; + vertexShader += 'void main(void) \n{\n'; + vertexShader += vertexShaderMain; + vertexShader += '}\n'; - this.orientation = options.orientation; - this.evenColor = options.evenColor; - this.oddColor = options.oddColor; - this.offset = options.offset; - this.repeat = options.repeat; - } + // Fragment shader lighting + fragmentShader += 'const float M_PI = 3.141592653589793;\n'; - defineProperties(StripeMaterialProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof StripeMaterialProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._orientation) && // - Property.isConstant(this._evenColor) && // - Property.isConstant(this._oddColor) && // - Property.isConstant(this._offset) && // - Property.isConstant(this._repeat); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof StripeMaterialProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets or sets the Property specifying the {@link StripeOrientation}/ - * @memberof StripeMaterialProperty.prototype - * @type {Property} - * @default StripeOrientation.HORIZONTAL - */ - orientation : createPropertyDescriptor('orientation'), - /** - * Gets or sets the Property specifying the first {@link Color}. - * @memberof StripeMaterialProperty.prototype - * @type {Property} - * @default Color.WHITE - */ - evenColor : createPropertyDescriptor('evenColor'), - /** - * Gets or sets the Property specifying the second {@link Color}. - * @memberof StripeMaterialProperty.prototype - * @type {Property} - * @default Color.BLACK - */ - oddColor : createPropertyDescriptor('oddColor'), - /** - * Gets or sets the numeric Property specifying the point into the pattern - * to begin drawing; with 0.0 being the beginning of the even color, 1.0 the beginning - * of the odd color, 2.0 being the even color again, and any multiple or fractional values - * being in between. - * @memberof StripeMaterialProperty.prototype - * @type {Property} - * @default 0.0 - */ - offset : createPropertyDescriptor('offset'), - /** - * Gets or sets the numeric Property specifying how many times the stripes repeat. - * @memberof StripeMaterialProperty.prototype - * @type {Property} - * @default 1.0 - */ - repeat : createPropertyDescriptor('repeat') - }); + fragmentShader += 'vec3 lambertianDiffuse(vec3 baseColor) \n' + + '{\n' + + ' return baseColor / M_PI;\n' + + '}\n\n'; - /** - * Gets the {@link Material} type at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. - */ - StripeMaterialProperty.prototype.getType = function(time) { - return 'Stripe'; - }; + fragmentShader += 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' + + '{\n' + + ' return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);\n' + + '}\n\n'; - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - StripeMaterialProperty.prototype.getValue = function(time, result) { - if (!defined(result)) { - result = {}; - } - result.horizontal = Property.getValueOrDefault(this._orientation, time, defaultOrientation) === StripeOrientation.HORIZONTAL; - result.evenColor = Property.getValueOrClonedDefault(this._evenColor, time, defaultEvenColor, result.evenColor); - result.oddColor = Property.getValueOrClonedDefault(this._oddColor, time, defaultOddColor, result.oddColor); - result.offset = Property.getValueOrDefault(this._offset, time, defaultOffset); - result.repeat = Property.getValueOrDefault(this._repeat, time, defaultRepeat); - return result; - }; + fragmentShader += 'vec3 fresnelSchlick(float metalness, float VdotH) \n' + + '{\n' + + ' return metalness + (vec3(1.0) - metalness) * pow(1.0 - VdotH, 5.0);\n' + + '}\n\n'; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - StripeMaterialProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof StripeMaterialProperty && // - Property.equals(this._orientation, other._orientation) && // - Property.equals(this._evenColor, other._evenColor) && // - Property.equals(this._oddColor, other._oddColor) && // - Property.equals(this._offset, other._offset) && // - Property.equals(this._repeat, other._repeat)); - }; + fragmentShader += 'float smithVisibilityG1(float NdotV, float roughness) \n' + + '{\n' + + ' float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n' + + ' return NdotV / (NdotV * (1.0 - k) + k);\n' + + '}\n\n'; - return StripeMaterialProperty; -}); + fragmentShader += 'float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n' + + '{\n' + + ' return smithVisibilityG1(NdotL, roughness) * smithVisibilityG1(NdotV, roughness);\n' + + '}\n\n'; -define('DataSources/TimeIntervalCollectionPositionProperty',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/ReferenceFrame', - '../Core/TimeIntervalCollection', - './PositionProperty', - './Property' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - ReferenceFrame, - TimeIntervalCollection, - PositionProperty, - Property) { - 'use strict'; + fragmentShader += 'float GGX(float roughness, float NdotH) \n' + + '{\n' + + ' float roughnessSquared = roughness * roughness;\n' + + ' float f = (NdotH * roughnessSquared - NdotH) * NdotH + 1.0;\n' + + ' return roughnessSquared / (M_PI * f * f);\n' + + '}\n\n'; - /** - * A {@link TimeIntervalCollectionProperty} which is also a {@link PositionProperty}. - * - * @alias TimeIntervalCollectionPositionProperty - * @constructor - * - * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - */ - function TimeIntervalCollectionPositionProperty(referenceFrame) { - this._definitionChanged = new Event(); - this._intervals = new TimeIntervalCollection(); - this._intervals.changedEvent.addEventListener(TimeIntervalCollectionPositionProperty.prototype._intervalsChanged, this); - this._referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - } + fragmentShader += 'void main(void) \n{\n'; - defineProperties(TimeIntervalCollectionPositionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return this._intervals.isEmpty; + // Add normal mapping to fragment shader + if (hasNormals) { + fragmentShader += ' vec3 ng = normalize(v_normal);\n'; + if (defined(parameterValues.normalTexture)) { + if (hasTangents) { + // Read tangents from varying + fragmentShader += ' vec3 t = normalize(v_tangent);\n'; + fragmentShader += ' vec3 b = normalize(cross(ng, t));\n'; + fragmentShader += ' mat3 tbn = mat3(t, b, ng);\n'; + fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + v_texcoord + ').rgb;\n'; + fragmentShader += ' n = normalize(tbn * (2.0 * n - 1.0));\n'; + } else { + // Add standard derivatives extension + fragmentShader = '#ifdef GL_OES_standard_derivatives\n' + + '#extension GL_OES_standard_derivatives : enable\n' + + '#endif\n' + + fragmentShader; + // Compute tangents + fragmentShader += '#ifdef GL_OES_standard_derivatives\n'; + fragmentShader += ' vec3 pos_dx = dFdx(v_positionEC);\n'; + fragmentShader += ' vec3 pos_dy = dFdy(v_positionEC);\n'; + fragmentShader += ' vec3 tex_dx = dFdx(vec3(' + v_texcoord + ',0.0));\n'; + fragmentShader += ' vec3 tex_dy = dFdy(vec3(' + v_texcoord + ',0.0));\n'; + fragmentShader += ' vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n'; + fragmentShader += ' t = normalize(t - ng * dot(ng, t));\n'; + fragmentShader += ' vec3 b = normalize(cross(ng, t));\n'; + fragmentShader += ' mat3 tbn = mat3(t, b, ng);\n'; + fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + v_texcoord + ').rgb;\n'; + fragmentShader += ' n = normalize(tbn * (2.0 * n - 1.0));\n'; + fragmentShader += '#else\n'; + fragmentShader += ' vec3 n = ng;\n'; + fragmentShader += '#endif\n'; + } + } else { + fragmentShader += ' vec3 n = ng;\n'; } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is considered to have changed if a call to getValue would return - * a different result for the same time. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + if (parameterValues.doubleSided) { + fragmentShader += ' if (!gl_FrontFacing)\n'; + fragmentShader += ' {\n'; + fragmentShader += ' n = -n;\n'; + fragmentShader += ' }\n'; } - }, - /** - * Gets the interval collection. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._intervals; + } + + // Add base color to fragment shader + if (defined(parameterValues.baseColorTexture)) { + fragmentShader += ' vec4 baseColorWithAlpha = texture2D(u_baseColorTexture, ' + v_texcoord + ');\n'; + if (defined(parameterValues.baseColorFactor)) { + fragmentShader += ' baseColorWithAlpha *= u_baseColorFactor;\n'; } - }, - /** - * Gets the reference frame in which the position is defined. - * @memberof TimeIntervalCollectionPositionProperty.prototype - * @type {ReferenceFrame} - * @default ReferenceFrame.FIXED; - */ - referenceFrame : { - get : function() { - return this._referenceFrame; + } else { + if (defined(parameterValues.baseColorFactor)) { + fragmentShader += ' vec4 baseColorWithAlpha = u_baseColorFactor;\n'; + } else { + fragmentShader += ' vec4 baseColorWithAlpha = vec4(1.0);\n'; } } - }); - /** - * Gets the value of the property at the provided time in the fixed frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - TimeIntervalCollectionPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); - }; + if (hasVertexColors) { + fragmentShader += ' baseColorWithAlpha *= v_vertexColor;\n'; + } - /** - * Gets the value of the property at the provided time and in the provided reference frame. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {ReferenceFrame} referenceFrame The desired referenceFrame of the result. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - TimeIntervalCollectionPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + fragmentShader += ' vec3 baseColor = baseColorWithAlpha.rgb;\n'; + // Add metallic-roughness to fragment shader + if (defined(parameterValues.metallicRoughnessTexture)) { + fragmentShader += ' vec3 metallicRoughness = texture2D(u_metallicRoughnessTexture, ' + v_texcoord + ').rgb;\n'; + fragmentShader += ' float metalness = clamp(metallicRoughness.b, 0.0, 1.0);\n'; + fragmentShader += ' float roughness = clamp(metallicRoughness.g, 0.04, 1.0);\n'; + if (defined(parameterValues.metallicFactor)) { + fragmentShader += ' metalness *= u_metallicFactor;\n'; + } + if (defined(parameterValues.roughnessFactor)) { + fragmentShader += ' roughness *= u_roughnessFactor;\n'; + } + } else { + if (defined(parameterValues.metallicFactor)) { + fragmentShader += ' float metalness = clamp(u_metallicFactor, 0.0, 1.0);\n'; + } else { + fragmentShader += ' float metalness = 1.0;\n'; + } + if (defined(parameterValues.roughnessFactor)) { + fragmentShader += ' float roughness = clamp(u_roughnessFactor, 0.04, 1.0);\n'; + } else { + fragmentShader += ' float roughness = 1.0;\n'; + } } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); + fragmentShader += ' vec3 v = -normalize(v_positionEC);\n'; + + // Generate fragment shader's lighting block + fragmentShader += ' vec3 lightColor = vec3(1.0, 1.0, 1.0);\n'; + if (optimizeForCesium) { + fragmentShader += ' vec3 l = normalize(czm_sunDirectionEC);\n'; + } else { + fragmentShader += ' vec3 l = vec3(0.0, 0.0, 1.0);\n'; } - - var position = this._intervals.findDataForIntervalContainingDate(time); - if (defined(position)) { - return PositionProperty.convertToReferenceFrame(time, position, this._referenceFrame, referenceFrame, result); + fragmentShader += ' vec3 h = normalize(v + l);\n'; + if (optimizeForCesium) { + fragmentShader += ' vec3 r = normalize(czm_inverseViewRotation * normalize(reflect(v, n)));\n'; + // Figure out if the reflection vector hits the ellipsoid + fragmentShader += ' czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\n'; + fragmentShader += ' float vertexRadius = length(v_positionWC);\n'; + fragmentShader += ' float horizonDotNadir = 1.0 - ellipsoid.radii.x / vertexRadius;\n'; + fragmentShader += ' float reflectionDotNadir = dot(r, normalize(v_positionWC));\n'; + // Flipping the X vector is a cheap way to get the inverse of czm_temeToPseudoFixed, since that's a rotation about Z. + fragmentShader += ' r.x = -r.x;\n'; + fragmentShader += ' r = -normalize(czm_temeToPseudoFixed * r);\n'; + fragmentShader += ' r.x = -r.x;\n'; + } else { + fragmentShader += ' vec3 r = normalize(reflect(v, n));\n'; } - return undefined; - }; + fragmentShader += ' float NdotL = clamp(dot(n, l), 0.001, 1.0);\n'; + fragmentShader += ' float NdotV = abs(dot(n, v)) + 0.001;\n'; + fragmentShader += ' float NdotH = clamp(dot(n, h), 0.0, 1.0);\n'; + fragmentShader += ' float LdotH = clamp(dot(l, h), 0.0, 1.0);\n'; + fragmentShader += ' float VdotH = clamp(dot(v, h), 0.0, 1.0);\n'; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - TimeIntervalCollectionPositionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof TimeIntervalCollectionPositionProperty && // - this._intervals.equals(other._intervals, Property.equals) && // - this._referenceFrame === other._referenceFrame); - }; + fragmentShader += ' vec3 f0 = vec3(0.04);\n'; + fragmentShader += ' float alpha = roughness * roughness;\n'; + fragmentShader += ' vec3 diffuseColor = baseColor * (1.0 - metalness);\n'; + fragmentShader += ' vec3 specularColor = mix(f0, baseColor, metalness);\n'; + fragmentShader += ' float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n'; + fragmentShader += ' vec3 r90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));\n'; + fragmentShader += ' vec3 r0 = specularColor.rgb;\n'; - /** - * @private - */ - TimeIntervalCollectionPositionProperty.prototype._intervalsChanged = function() { - this._definitionChanged.raiseEvent(this); - }; + fragmentShader += ' vec3 F = fresnelSchlick2(r0, r90, VdotH);\n'; + fragmentShader += ' float G = smithVisibilityGGX(alpha, NdotL, NdotV);\n'; + fragmentShader += ' float D = GGX(alpha, NdotH);\n'; - return TimeIntervalCollectionPositionProperty; -}); + fragmentShader += ' vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(baseColor);\n'; + fragmentShader += ' vec3 specularContribution = F * G * D / (4.0 * NdotL * NdotV);\n'; + fragmentShader += ' vec3 color = NdotL * lightColor * (diffuseContribution + specularContribution);\n'; -define('DataSources/TimeIntervalCollectionProperty',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/TimeIntervalCollection', - './Property' - ], function( - defined, - defineProperties, - DeveloperError, - Event, - TimeIntervalCollection, - Property) { - 'use strict'; + if (optimizeForCesium) { + fragmentShader += ' float inverseRoughness = 1.0 - roughness;\n'; + fragmentShader += ' inverseRoughness *= inverseRoughness;\n'; + fragmentShader += ' vec3 sceneSkyBox = textureCube(czm_environmentMap, r).rgb * inverseRoughness;\n'; - /** - * A {@link Property} which is defined by a {@link TimeIntervalCollection}, where the - * data property of each {@link TimeInterval} represents the value at time. - * - * @alias TimeIntervalCollectionProperty - * @constructor - * - * @example - * //Create a Cartesian2 interval property which contains data on August 1st, 2012 - * //and uses a different value every 6 hours. - * var composite = new Cesium.TimeIntervalCollectionProperty(); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2012-08-01T00:00:00.00Z/2012-08-01T06:00:00.00Z', - * isStartIncluded : true, - * isStopIncluded : false, - * data : new Cesium.Cartesian2(2.0, 3.4) - * })); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2012-08-01T06:00:00.00Z/2012-08-01T12:00:00.00Z', - * isStartIncluded : true, - * isStopIncluded : false, - * data : new Cesium.Cartesian2(12.0, 2.7) - * })); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2012-08-01T12:00:00.00Z/2012-08-01T18:00:00.00Z', - * isStartIncluded : true, - * isStopIncluded : false, - * data : new Cesium.Cartesian2(5.0, 12.4) - * })); - * composite.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ - * iso8601 : '2012-08-01T18:00:00.00Z/2012-08-02T00:00:00.00Z', - * isStartIncluded : true, - * isStopIncluded : true, - * data : new Cesium.Cartesian2(85.0, 4.1) - * })); - */ - function TimeIntervalCollectionProperty() { - this._definitionChanged = new Event(); - this._intervals = new TimeIntervalCollection(); - this._intervals.changedEvent.addEventListener(TimeIntervalCollectionProperty.prototype._intervalsChanged, this); - } + fragmentShader += ' float atmosphereHeight = 0.05;\n'; + fragmentShader += ' float blendRegionSize = 0.1 * ((1.0 - inverseRoughness) * 8.0 + 1.1 - horizonDotNadir);\n'; + fragmentShader += ' float farAboveHorizon = clamp(horizonDotNadir - blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n'; + fragmentShader += ' float aroundHorizon = clamp(horizonDotNadir + blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n'; + fragmentShader += ' float farBelowHorizon = clamp(horizonDotNadir + blendRegionSize * 1.5, 1.0e-10 - blendRegionSize, 0.99999);\n'; + fragmentShader += ' float smoothstepHeight = smoothstep(0.0, atmosphereHeight, horizonDotNadir);\n'; + fragmentShader += ' float lightScale = smoothstepHeight * 1.5 + 1.0;\n'; - defineProperties(TimeIntervalCollectionProperty.prototype, { - /** - * Gets a value indicating if this property is constant. A property is considered - * constant if getValue always returns the same result for the current definition. - * @memberof TimeIntervalCollectionProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return this._intervals.isEmpty; - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * The definition is changed whenever setValue is called with data different - * than the current value. - * @memberof TimeIntervalCollectionProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; + fragmentShader += ' vec3 diffuseIrradiance = mix(vec3(0.5), vec3(0.05), smoothstepHeight);\n'; + fragmentShader += ' vec3 belowHorizonColor = mix(vec3(0.1, 0.2, 0.4), vec3(0.2, 0.5, 0.7), smoothstepHeight);\n'; + fragmentShader += ' vec3 nadirColor = belowHorizonColor * 0.5;\n'; + fragmentShader += ' vec3 aboveHorizonColor = vec3(0.8, 0.9, 0.95);\n'; + fragmentShader += ' vec3 blueSkyColor = mix(vec3(0.09, 0.13, 0.24), aboveHorizonColor, reflectionDotNadir * inverseRoughness * 0.5 + 0.5);\n'; + fragmentShader += ' vec3 zenithColor = mix(blueSkyColor, sceneSkyBox, smoothstepHeight);\n'; + + fragmentShader += ' vec3 specularIrradiance = mix(zenithColor, aboveHorizonColor, smoothstep(farAboveHorizon, aroundHorizon, reflectionDotNadir) * inverseRoughness);\n'; + fragmentShader += ' specularIrradiance = mix(specularIrradiance, belowHorizonColor, smoothstep(aroundHorizon, farBelowHorizon, reflectionDotNadir) * inverseRoughness);\n'; + fragmentShader += ' specularIrradiance = mix(specularIrradiance, nadirColor, smoothstep(farBelowHorizon, 1.0, reflectionDotNadir) * inverseRoughness);\n'; + + fragmentShader += ' vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n'; + fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * (specularColor * brdfLut.x + brdfLut.y));\n'; + fragmentShader += ' color = color * lightScale + IBLColor;\n'; + } + + if (defined(parameterValues.occlusionTexture)) { + fragmentShader += ' color *= texture2D(u_occlusionTexture, ' + v_texcoord + ').r;\n'; + } + if (defined(parameterValues.emissiveTexture)) { + fragmentShader += ' vec3 emissive = texture2D(u_emissiveTexture, ' + v_texcoord + ').rgb;\n'; + if (defined(parameterValues.emissiveFactor)) { + fragmentShader += ' emissive *= u_emissiveFactor;\n'; } - }, - /** - * Gets the interval collection. - * @memberof TimeIntervalCollectionProperty.prototype - * - * @type {TimeIntervalCollection} - */ - intervals : { - get : function() { - return this._intervals; + fragmentShader += ' color += emissive;\n'; + } + else { + if (defined(parameterValues.emissiveFactor)) { + fragmentShader += ' color += u_emissiveFactor;\n'; } } - }); - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. - */ - TimeIntervalCollectionProperty.prototype.getValue = function(time, result) { - if (!defined(time)) { - throw new DeveloperError('time is required'); + // Final color + var alphaMode = material.alphaMode; + if (defined(alphaMode)) { + if (alphaMode === 'MASK') { + var alphaCutoff = material.alphaCutoff; + if (defined(alphaCutoff)) { + fragmentShader += ' gl_FragColor = vec4(color, int(baseColorWithAlpha.a >= ' + alphaCutoff + '));\n'; + } else { + fragmentShader += ' gl_FragColor = vec4(color, 1.0);\n'; + } + } else if (alphaMode === 'BLEND') { + fragmentShader += ' gl_FragColor = vec4(color, baseColorWithAlpha.a);\n'; + } else { + fragmentShader += ' gl_FragColor = vec4(color, 1.0);\n'; + } + } else { + fragmentShader += ' gl_FragColor = vec4(color, 1.0);\n'; } - - var value = this._intervals.findDataForIntervalContainingDate(time); - if (defined(value) && (typeof value.clone === 'function')) { - return value.clone(result); + fragmentShader += '}\n'; + + var techniqueStates; + if (defined(alphaMode) && alphaMode !== 'OPAQUE') { + techniqueStates = { + enable: [ + WebGLConstants.DEPTH_TEST, + WebGLConstants.BLEND + ], + functions: { + depthMask : [false], + blendEquationSeparate: [ + WebGLConstants.FUNC_ADD, + WebGLConstants.FUNC_ADD + ], + blendFuncSeparate: [ + WebGLConstants.ONE, + WebGLConstants.ONE_MINUS_SRC_ALPHA, + WebGLConstants.ONE, + WebGLConstants.ONE_MINUS_SRC_ALPHA + ] + } + }; + } else if (parameterValues.doubleSided) { + techniqueStates = { + enable : [ + WebGLConstants.DEPTH_TEST + ] + }; + } else { + techniqueStates = { + enable : [ + WebGLConstants.CULL_FACE, + WebGLConstants.DEPTH_TEST + ] + }; } - return value; - }; - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - TimeIntervalCollectionProperty.prototype.equals = function(other) { - return this === other || // - (other instanceof TimeIntervalCollectionProperty && // - this._intervals.equals(other._intervals, Property.equals)); - }; + // Add shaders + var vertexShaderId = addToArray(shaders, { + type : WebGLConstants.VERTEX_SHADER, + extras : { + _pipeline : { + source : vertexShader, + extension : '.glsl' + } + } + }); - /** - * @private - */ - TimeIntervalCollectionProperty.prototype._intervalsChanged = function() { - this._definitionChanged.raiseEvent(this); - }; + var fragmentShaderId = addToArray(shaders, { + type : WebGLConstants.FRAGMENT_SHADER, + extras : { + _pipeline : { + source : fragmentShader, + extension : '.glsl' + } + } + }); - return TimeIntervalCollectionProperty; -}); + // Add program + var programAttributes = Object.keys(techniqueAttributes); + var programId = addToArray(programs, { + attributes : programAttributes, + fragmentShader : fragmentShaderId, + vertexShader : vertexShaderId + }); -define('DataSources/VelocityVectorProperty',[ - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/JulianDate', - './Property' - ], function( - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - JulianDate, - Property) { - 'use strict'; + var techniqueId = addToArray(techniques, { + attributes : techniqueAttributes, + parameters : techniqueParameters, + program : programId, + states : techniqueStates, + uniforms : techniqueUniforms + }); - /** - * A {@link Property} which evaluates to a {@link Cartesian3} vector - * based on the velocity of the provided {@link PositionProperty}. - * - * @alias VelocityVectorProperty - * @constructor - * - * @param {Property} [position] The position property used to compute the velocity. - * @param {Boolean} [normalize=true] Whether to normalize the computed velocity vector. - * - * @example - * //Create an entity with a billboard rotated to match its velocity. - * var position = new Cesium.SampledProperty(); - * position.addSamples(...); - * var entity = viewer.entities.add({ - * position : position, - * billboard : { - * image : 'image.png', - * alignedAxis : new Cesium.VelocityVectorProperty(position, true) // alignedAxis must be a unit vector - * } - * })); - */ - function VelocityVectorProperty(position, normalize) { - this._position = undefined; - this._subscription = undefined; - this._definitionChanged = new Event(); - this._normalize = defaultValue(normalize, true); + return techniqueId; + } - this.position = position; + function getPBRValueType(paramName) { + switch (paramName) { + case 'baseColorFactor': + return WebGLConstants.FLOAT_VEC4; + case 'metallicFactor': + return WebGLConstants.FLOAT; + case 'roughnessFactor': + return WebGLConstants.FLOAT; + case 'baseColorTexture': + return WebGLConstants.SAMPLER_2D; + case 'metallicRoughnessTexture': + return WebGLConstants.SAMPLER_2D; + case 'normalTexture': + return WebGLConstants.SAMPLER_2D; + case 'occlusionTexture': + return WebGLConstants.SAMPLER_2D; + case 'emissiveTexture': + return WebGLConstants.SAMPLER_2D; + case 'emissiveFactor': + return WebGLConstants.FLOAT_VEC3; + case 'doubleSided': + return WebGLConstants.BOOL; + } } - defineProperties(VelocityVectorProperty.prototype, { - /** - * Gets a value indicating if this property is constant. - * @memberof VelocityVectorProperty.prototype - * - * @type {Boolean} - * @readonly - */ - isConstant : { - get : function() { - return Property.isConstant(this._position); - } - }, - /** - * Gets the event that is raised whenever the definition of this property changes. - * @memberof VelocityVectorProperty.prototype - * - * @type {Event} - * @readonly - */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - /** - * Gets or sets the position property used to compute the velocity vector. - * @memberof VelocityVectorProperty.prototype - * - * @type {Property} - */ - position : { - get : function() { - return this._position; - }, - set : function(value) { - var oldValue = this._position; - if (oldValue !== value) { - if (defined(oldValue)) { - this._subscription(); - } + function getShaderVariable(type) { + if (type === 'SCALAR') { + return 'float'; + } + return type.toLowerCase(); + } - this._position = value; + function ensureSemanticExistenceForPrimitive(gltf, primitive) { + var accessors = gltf.accessors; + var materials = gltf.materials; + var techniques = gltf.techniques; + var programs = gltf.programs; + var shaders = gltf.shaders; + var targets = primitive.targets; - if (defined(value)) { - this._subscription = value._definitionChanged.addEventListener(function() { - this._definitionChanged.raiseEvent(this); - }, this); + var attributes = primitive.attributes; + for (var target in targets) { + if (defined(target)) { + var targetAttributes = targets[target]; + for (var attribute in targetAttributes) { + if (attribute !== 'extras') { + attributes[attribute + '_' + target] = targetAttributes[attribute]; } - - this._definitionChanged.raiseEvent(this); } } - }, - /** - * Gets or sets whether the vector produced by this property - * will be normalized or not. - * @memberof VelocityVectorProperty.prototype - * - * @type {Boolean} - */ - normalize : { - get : function() { - return this._normalize; - }, - set : function(value) { - if (this._normalize === value) { - return; - } + } + var material = materials[primitive.material]; + var technique = techniques[material.technique]; + var program = programs[technique.program]; + var vertexShader = shaders[program.vertexShader]; - this._normalize = value; - this._definitionChanged.raiseEvent(this); + for (var semantic in attributes) { + if (attributes.hasOwnProperty(semantic)) { + if (!defined(techniqueParameterForSemantic(technique, semantic))) { + var accessorId = attributes[semantic]; + var accessor = accessors[accessorId]; + var lowerCase = semantic.toLowerCase(); + if (lowerCase.charAt(0) === '_') { + lowerCase = lowerCase.slice(1); + } + var attributeName = 'a_' + lowerCase; + technique.parameters[lowerCase] = { + semantic: semantic, + type: accessor.componentType + }; + technique.attributes[attributeName] = lowerCase; + program.attributes.push(attributeName); + var pipelineExtras = vertexShader.extras._pipeline; + var shaderText = pipelineExtras.source; + shaderText = 'attribute ' + getShaderVariable(accessor.type) + ' ' + attributeName + ';\n' + shaderText; + pipelineExtras.source = shaderText; + } } } - }); - - var position1Scratch = new Cartesian3(); - var position2Scratch = new Cartesian3(); - var timeScratch = new JulianDate(); - var step = 1.0 / 60.0; + } - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} [time] The time for which to retrieve the value. - * @param {Cartesian3} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Cartesian3} The modified result parameter or a new instance if the result parameter was not supplied. - */ - VelocityVectorProperty.prototype.getValue = function(time, result) { - return this._getValue(time, result); - }; + function ensureSemanticExistence(gltf) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + ensureSemanticExistenceForPrimitive(gltf, primitive); + }); + }); + } - /** - * @private - */ - VelocityVectorProperty.prototype._getValue = function(time, velocityResult, positionResult) { - if (!defined(time)) { - throw new DeveloperError('time is required'); - } - - if (!defined(velocityResult)) { - velocityResult = new Cartesian3(); - } + function splitIncompatibleMaterials(gltf) { + var accessors = gltf.accessors; + var materials = gltf.materials; + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + var materialId = primitive.material; + var material = materials[materialId]; - var property = this._position; - if (Property.isConstant(property)) { - return this._normalize ? undefined : Cartesian3.clone(Cartesian3.ZERO, velocityResult); - } + var jointAccessorId = primitive.attributes.JOINTS_0; + var componentType; + var type; + if (defined(jointAccessorId)) { + var jointAccessor = accessors[jointAccessorId]; + componentType = jointAccessor.componentType; + type = jointAccessor.type; + } + var isSkinned = defined(jointAccessorId); + var hasVertexColors = defined(primitive.attributes.COLOR_0); + + var primitiveInfo = material.extras._pipeline.primitive; + if (!defined(primitiveInfo)) { + material.extras._pipeline.primitive = { + skinning : { + skinned : isSkinned, + componentType : componentType, + type : type + }, + hasVertexColors : hasVertexColors + }; + } else if ((primitiveInfo.skinning.skinned !== isSkinned) || (primitiveInfo.skinning.type !== type) || (primitiveInfo.hasVertexColors !== hasVertexColors)) { + // This primitive uses the same material as another one that either: + // * Isn't skinned + // * Uses a different type to store joints and weights + // * Doesn't have vertex colors + var clonedMaterial = clone(material, true); + clonedMaterial.extras._pipeline.skinning = { + skinning : { + skinned : isSkinned, + componentType : componentType, + type : type + }, + hasVertexColors : hasVertexColors + }; + // Split this off as a separate material + materialId = addToArray(materials, clonedMaterial); + primitive.material = materialId; + } + }); + }); + } - var position1 = property.getValue(time, position1Scratch); - var position2 = property.getValue(JulianDate.addSeconds(time, step, timeScratch), position2Scratch); + return processPbrMetallicRoughness; +}); - //If we don't have a position for now, return undefined. - if (!defined(position1)) { - return undefined; - } +define('Scene/AttributeType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - //If we don't have a position for now + step, see if we have a position for now - step. - if (!defined(position2)) { - position2 = position1; - position1 = property.getValue(JulianDate.addSeconds(time, -step, timeScratch), position2Scratch); + /** + * An enum describing the attribute type for glTF and 3D Tiles. + * + * @exports AttributeType + * + * @private + */ + var AttributeType = { + /** + * The attribute is a single component. + * + * @type {String} + * @constant + */ + SCALAR : 'SCALAR', - if (!defined(position1)) { - return undefined; - } - } + /** + * The attribute is a two-component vector. + * + * @type {String} + * @constant + */ + VEC2 : 'VEC2', - if (Cartesian3.equals(position1, position2)) { - return this._normalize ? undefined : Cartesian3.clone(Cartesian3.ZERO, velocityResult); - } + /** + * The attribute is a three-component vector. + * + * @type {String} + * @constant + */ + VEC3 : 'VEC3', - if (defined(positionResult)) { - position1.clone(positionResult); - } + /** + * The attribute is a four-component vector. + * + * @type {String} + * @constant + */ + VEC4 : 'VEC4', - var velocity = Cartesian3.subtract(position2, position1, velocityResult); - if (this._normalize) { - return Cartesian3.normalize(velocity, velocityResult); - } + /** + * The attribute is a 2x2 matrix. + * + * @type {String} + * @constant + */ + MAT2 : 'MAT2', - return Cartesian3.divideByScalar(velocity, step, velocityResult); - }; + /** + * The attribute is a 3x3 matrix. + * + * @type {String} + * @constant + */ + MAT3 : 'MAT3', - /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. - */ - VelocityVectorProperty.prototype.equals = function(other) { - return this === other ||// - (other instanceof VelocityVectorProperty && - Property.equals(this._position, other._position)); + /** + * The attribute is a 4x4 matrix. + * + * @type {String} + * @constant + */ + MAT4 : 'MAT4' }; - return VelocityVectorProperty; + return freezeObject(AttributeType); }); -define('DataSources/VelocityOrientationProperty',[ - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Ellipsoid', - '../Core/Event', +define('Scene/Axis',[ + '../Core/Check', + '../Core/freezeObject', + '../Core/Math', '../Core/Matrix3', - '../Core/Quaternion', - '../Core/Transforms', - './Property', - './VelocityVectorProperty' + '../Core/Matrix4' ], function( - Cartesian3, - defaultValue, - defined, - defineProperties, - Ellipsoid, - Event, + Check, + freezeObject, + CesiumMath, Matrix3, - Quaternion, - Transforms, - Property, - VelocityVectorProperty) { + Matrix4) { 'use strict'; /** - * A {@link Property} which evaluates to a {@link Quaternion} rotation - * based on the velocity of the provided {@link PositionProperty}. - * - * @alias VelocityOrientationProperty - * @constructor - * - * @param {Property} [position] The position property used to compute the orientation. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine which way is up. + * An enum describing the x, y, and z axes and helper conversion functions. * - * @example - * //Create an entity with position and orientation. - * var position = new Cesium.SampledProperty(); - * position.addSamples(...); - * var entity = viewer.entities.add({ - * position : position, - * orientation : new Cesium.VelocityOrientationProperty(position) - * })); + * @exports Axis + * @private */ - function VelocityOrientationProperty(position, ellipsoid) { - this._velocityVectorProperty = new VelocityVectorProperty(position, true); - this._subscription = undefined; - this._ellipsoid = undefined; - this._definitionChanged = new Event(); + var Axis = { + /** + * Denotes the x-axis. + * + * @type {Number} + * @constant + */ + X : 0, - this.ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + /** + * Denotes the y-axis. + * + * @type {Number} + * @constant + */ + Y : 1, - var that = this; - this._velocityVectorProperty.definitionChanged.addEventListener(function() { - that._definitionChanged.raiseEvent(that); - }); - } + /** + * Denotes the z-axis. + * + * @type {Number} + * @constant + */ + Z : 2, - defineProperties(VelocityOrientationProperty.prototype, { /** - * Gets a value indicating if this property is constant. - * @memberof VelocityOrientationProperty.prototype + * Matrix used to convert from y-up to z-up * - * @type {Boolean} - * @readonly + * @type {Matrix4} + * @constant */ - isConstant : { - get : function() { - return Property.isConstant(this._velocityVectorProperty); - } - }, + Y_UP_TO_Z_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)), + /** - * Gets the event that is raised whenever the definition of this property changes. - * @memberof VelocityOrientationProperty.prototype + * Matrix used to convert from z-up to y-up * - * @type {Event} - * @readonly + * @type {Matrix4} + * @constant */ - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, + Z_UP_TO_Y_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationX(-CesiumMath.PI_OVER_TWO)), + /** - * Gets or sets the position property used to compute orientation. - * @memberof VelocityOrientationProperty.prototype + * Matrix used to convert from x-up to z-up * - * @type {Property} + * @type {Matrix4} + * @constant */ - position : { - get : function() { - return this._velocityVectorProperty.position; - }, - set : function(value) { - this._velocityVectorProperty.position = value; - } - }, + X_UP_TO_Z_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationY(-CesiumMath.PI_OVER_TWO)), + /** - * Gets or sets the ellipsoid used to determine which way is up. - * @memberof VelocityOrientationProperty.prototype + * Matrix used to convert from z-up to x-up * - * @type {Property} + * @type {Matrix4} + * @constant */ - ellipsoid : { - get : function() { - return this._ellipsoid; - }, - set : function(value) { - var oldValue = this._ellipsoid; - if (oldValue !== value) { - this._ellipsoid = value; - this._definitionChanged.raiseEvent(this); - } - } - } - }); + Z_UP_TO_X_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationY(CesiumMath.PI_OVER_TWO)), - var positionScratch = new Cartesian3(); - var velocityScratch = new Cartesian3(); - var rotationScratch = new Matrix3(); + /** + * Matrix used to convert from x-up to y-up + * + * @type {Matrix4} + * @constant + */ + X_UP_TO_Y_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationZ(CesiumMath.PI_OVER_TWO)), - /** - * Gets the value of the property at the provided time. - * - * @param {JulianDate} [time] The time for which to retrieve the value. - * @param {Quaternion} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Quaternion} The modified result parameter or a new instance if the result parameter was not supplied. - */ - VelocityOrientationProperty.prototype.getValue = function(time, result) { - var velocity = this._velocityVectorProperty._getValue(time, velocityScratch, positionScratch); + /** + * Matrix used to convert from y-up to x-up + * + * @type {Matrix4} + * @constant + */ + Y_UP_TO_X_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationZ(-CesiumMath.PI_OVER_TWO)), - if (!defined(velocity)) { - return undefined; + /** + * Gets the axis by name + * + * @param {String} name The name of the axis. + * @returns {Number} The axis enum. + */ + fromName : function(name) { + Check.typeOf.string('name', name); + + return Axis[name]; } - - Transforms.rotationMatrixFromPositionVelocity(positionScratch, velocity, this._ellipsoid, rotationScratch); - return Quaternion.fromRotationMatrix(rotationScratch, result); }; + return freezeObject(Axis); +}); + +define('Scene/JobType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** - * Compares this property to the provided property and returns - * <code>true</code> if they are equal, <code>false</code> otherwise. - * - * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @private */ - VelocityOrientationProperty.prototype.equals = function(other) { - return this === other ||// - (other instanceof VelocityOrientationProperty && - Property.equals(this._velocityVectorProperty, other._velocityVectorProperty) && - (this._ellipsoid === other._ellipsoid || - this._ellipsoid.equals(other._ellipsoid))); + var JobType = { + TEXTURE : 0, + PROGRAM : 1, + BUFFER : 2, + NUMBER_OF_JOB_TYPES : 3 }; - return VelocityOrientationProperty; + return freezeObject(JobType); }); -define('DataSources/CzmlDataSource',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', +define('Scene/ModelAnimationCache',[ + './AttributeType', '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/ClockRange', - '../Core/ClockStep', - '../Core/Color', - '../Core/CornerType', - '../Core/createGuid', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/Ellipsoid', - '../Core/Event', - '../Core/ExtrapolationType', - '../Core/getAbsoluteUri', - '../Core/getFilenameFromUri', - '../Core/HermitePolynomialApproximation', - '../Core/isArray', - '../Core/Iso8601', - '../Core/joinUrls', - '../Core/JulianDate', - '../Core/LagrangePolynomialApproximation', - '../Core/LinearApproximation', - '../Core/loadJson', - '../Core/Math', - '../Core/NearFarScalar', - '../Core/objectToQuery', + '../Core/LinearSpline', + '../Core/Matrix4', '../Core/Quaternion', - '../Core/Rectangle', - '../Core/ReferenceFrame', - '../Core/RuntimeError', - '../Core/Spherical', - '../Core/TimeInterval', - '../Core/TimeIntervalCollection', - '../Scene/ColorBlendMode', - '../Scene/HeightReference', - '../Scene/HorizontalOrigin', - '../Scene/LabelStyle', - '../Scene/ShadowMode', - '../Scene/VerticalOrigin', - '../ThirdParty/Uri', - '../ThirdParty/when', - './BillboardGraphics', - './BoxGraphics', - './ColorMaterialProperty', - './CompositeMaterialProperty', - './CompositePositionProperty', - './CompositeProperty', - './ConstantPositionProperty', - './ConstantProperty', - './CorridorGraphics', - './CylinderGraphics', - './DataSource', - './DataSourceClock', - './EllipseGraphics', - './EllipsoidGraphics', - './EntityCluster', - './EntityCollection', - './GridMaterialProperty', - './ImageMaterialProperty', - './LabelGraphics', - './ModelGraphics', - './NodeTransformationProperty', - './PathGraphics', - './PointGraphics', - './PolygonGraphics', - './PolylineArrowMaterialProperty', - './PolylineDashMaterialProperty', - './PolylineGlowMaterialProperty', - './PolylineGraphics', - './PolylineOutlineMaterialProperty', - './PositionPropertyArray', - './PropertyArray', - './PropertyBag', - './RectangleGraphics', - './ReferenceProperty', - './Rotation', - './SampledPositionProperty', - './SampledProperty', - './StripeMaterialProperty', - './StripeOrientation', - './TimeIntervalCollectionPositionProperty', - './TimeIntervalCollectionProperty', - './VelocityOrientationProperty', - './VelocityVectorProperty', - './WallGraphics' + '../Core/QuaternionSpline', + '../Core/WebGLConstants', + '../Core/WeightSpline', + '../ThirdParty/GltfPipeline/getAccessorByteStride', + '../ThirdParty/GltfPipeline/numberOfComponentsForType' ], function( - BoundingRectangle, - Cartesian2, + AttributeType, Cartesian3, - Cartographic, - ClockRange, - ClockStep, - Color, - CornerType, - createGuid, + ComponentDatatype, defaultValue, defined, - defineProperties, - DeveloperError, - DistanceDisplayCondition, - Ellipsoid, - Event, - ExtrapolationType, - getAbsoluteUri, - getFilenameFromUri, - HermitePolynomialApproximation, - isArray, - Iso8601, - joinUrls, - JulianDate, - LagrangePolynomialApproximation, - LinearApproximation, - loadJson, - CesiumMath, - NearFarScalar, - objectToQuery, + LinearSpline, + Matrix4, Quaternion, - Rectangle, - ReferenceFrame, - RuntimeError, - Spherical, - TimeInterval, - TimeIntervalCollection, - ColorBlendMode, - HeightReference, - HorizontalOrigin, - LabelStyle, - ShadowMode, - VerticalOrigin, - Uri, - when, - BillboardGraphics, - BoxGraphics, - ColorMaterialProperty, - CompositeMaterialProperty, - CompositePositionProperty, - CompositeProperty, - ConstantPositionProperty, - ConstantProperty, - CorridorGraphics, - CylinderGraphics, - DataSource, - DataSourceClock, - EllipseGraphics, - EllipsoidGraphics, - EntityCluster, - EntityCollection, - GridMaterialProperty, - ImageMaterialProperty, - LabelGraphics, - ModelGraphics, - NodeTransformationProperty, - PathGraphics, - PointGraphics, - PolygonGraphics, - PolylineArrowMaterialProperty, - PolylineDashMaterialProperty, - PolylineGlowMaterialProperty, - PolylineGraphics, - PolylineOutlineMaterialProperty, - PositionPropertyArray, - PropertyArray, - PropertyBag, - RectangleGraphics, - ReferenceProperty, - Rotation, - SampledPositionProperty, - SampledProperty, - StripeMaterialProperty, - StripeOrientation, - TimeIntervalCollectionPositionProperty, - TimeIntervalCollectionProperty, - VelocityOrientationProperty, - VelocityVectorProperty, - WallGraphics) { + QuaternionSpline, + WebGLConstants, + WeightSpline, + getAccessorByteStride, + numberOfComponentsForType) { 'use strict'; - // A marker type to distinguish CZML properties where we need to end up with a unit vector. - // The data is still loaded into Cartesian3 objects but they are normalized. - function UnitCartesian3() {} - UnitCartesian3.packedLength = Cartesian3.packedLength; - UnitCartesian3.unpack = Cartesian3.unpack; - UnitCartesian3.pack = Cartesian3.pack; - - // As a side note, for the purposes of CZML, Quaternion always indicates a unit quaternion. - - var currentId; - - function createReferenceProperty(entityCollection, referenceString) { - if (referenceString[0] === '#') { - referenceString = currentId + referenceString; - } - return ReferenceProperty.fromString(entityCollection, referenceString); - } - - function createSpecializedProperty(type, entityCollection, packetData) { - if (defined(packetData.reference)) { - return createReferenceProperty(entityCollection, packetData.reference); - } - - if (defined(packetData.velocityReference)) { - var referenceProperty = createReferenceProperty(entityCollection, packetData.velocityReference); - switch (type) { - case Cartesian3: - case UnitCartesian3: - return new VelocityVectorProperty(referenceProperty, type === UnitCartesian3); - case Quaternion: - return new VelocityOrientationProperty(referenceProperty); - } - } - - throw new RuntimeError(JSON.stringify(packetData) + ' is not valid CZML.'); - } - - var scratchCartesian = new Cartesian3(); - var scratchSpherical = new Spherical(); - var scratchCartographic = new Cartographic(); - var scratchTimeInterval = new TimeInterval(); - var scratchQuaternion = new Quaternion(); - - function unwrapColorInterval(czmlInterval) { - var rgbaf = czmlInterval.rgbaf; - if (defined(rgbaf)) { - return rgbaf; - } - - var rgba = czmlInterval.rgba; - if (!defined(rgba)) { - return undefined; - } - - var length = rgba.length; - if (length === Color.packedLength) { - return [Color.byteToFloat(rgba[0]), Color.byteToFloat(rgba[1]), Color.byteToFloat(rgba[2]), Color.byteToFloat(rgba[3])]; - } - - rgbaf = new Array(length); - for (var i = 0; i < length; i += 5) { - rgbaf[i] = rgba[i]; - rgbaf[i + 1] = Color.byteToFloat(rgba[i + 1]); - rgbaf[i + 2] = Color.byteToFloat(rgba[i + 2]); - rgbaf[i + 3] = Color.byteToFloat(rgba[i + 3]); - rgbaf[i + 4] = Color.byteToFloat(rgba[i + 4]); - } - return rgbaf; - } - - function unwrapUriInterval(czmlInterval, sourceUri, query) { - var result = defaultValue(czmlInterval.uri, czmlInterval); - if (defined(sourceUri)) { - result = getAbsoluteUri(result, getAbsoluteUri(sourceUri)); - - if (defined(query)) { - result = joinUrls(result, '?' + query, false); - } - } - return result; - } - - function unwrapRectangleInterval(czmlInterval) { - var wsen = czmlInterval.wsen; - if (defined(wsen)) { - return wsen; - } - - var wsenDegrees = czmlInterval.wsenDegrees; - if (!defined(wsenDegrees)) { - return undefined; - } - - var length = wsenDegrees.length; - if (length === Rectangle.packedLength) { - return [CesiumMath.toRadians(wsenDegrees[0]), CesiumMath.toRadians(wsenDegrees[1]), CesiumMath.toRadians(wsenDegrees[2]), CesiumMath.toRadians(wsenDegrees[3])]; - } - - wsen = new Array(length); - for (var i = 0; i < length; i += 5) { - wsen[i] = wsenDegrees[i]; - wsen[i + 1] = CesiumMath.toRadians(wsenDegrees[i + 1]); - wsen[i + 2] = CesiumMath.toRadians(wsenDegrees[i + 2]); - wsen[i + 3] = CesiumMath.toRadians(wsenDegrees[i + 3]); - wsen[i + 4] = CesiumMath.toRadians(wsenDegrees[i + 4]); - } - return wsen; - } - - function convertUnitSphericalToCartesian(unitSpherical) { - var length = unitSpherical.length; - scratchSpherical.magnitude = 1.0; - if (length === 2) { - scratchSpherical.clock = unitSpherical[0]; - scratchSpherical.cone = unitSpherical[1]; - Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); - return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; - } - - var result = new Array(length / 3 * 4); - for (var i = 0, j = 0; i < length; i += 3, j += 4) { - result[j] = unitSpherical[i]; - - scratchSpherical.clock = unitSpherical[i + 1]; - scratchSpherical.cone = unitSpherical[i + 2]; - Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); - - result[j + 1] = scratchCartesian.x; - result[j + 2] = scratchCartesian.y; - result[j + 3] = scratchCartesian.z; - } - return result; + /** + * @private + */ + function ModelAnimationCache() { } - function convertSphericalToCartesian(spherical) { - var length = spherical.length; - if (length === 3) { - scratchSpherical.clock = spherical[0]; - scratchSpherical.cone = spherical[1]; - scratchSpherical.magnitude = spherical[2]; - Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); - return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; - } - - var result = new Array(length); - for (var i = 0; i < length; i += 4) { - result[i] = spherical[i]; - - scratchSpherical.clock = spherical[i + 1]; - scratchSpherical.cone = spherical[i + 2]; - scratchSpherical.magnitude = spherical[i + 3]; - Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); - - result[i + 1] = scratchCartesian.x; - result[i + 2] = scratchCartesian.y; - result[i + 3] = scratchCartesian.z; - } - return result; - } + var dataUriRegex = /^data\:/i; - function convertCartographicRadiansToCartesian(cartographicRadians) { - var length = cartographicRadians.length; - if (length === 3) { - scratchCartographic.longitude = cartographicRadians[0]; - scratchCartographic.latitude = cartographicRadians[1]; - scratchCartographic.height = cartographicRadians[2]; - Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); - return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; - } + function getAccessorKey(model, accessor) { + var gltf = model.gltf; + var buffers = gltf.buffers; + var bufferViews = gltf.bufferViews; - var result = new Array(length); - for (var i = 0; i < length; i += 4) { - result[i] = cartographicRadians[i]; + var bufferView = bufferViews[accessor.bufferView]; + var buffer = buffers[bufferView.buffer]; - scratchCartographic.longitude = cartographicRadians[i + 1]; - scratchCartographic.latitude = cartographicRadians[i + 2]; - scratchCartographic.height = cartographicRadians[i + 3]; - Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); + var byteOffset = bufferView.byteOffset + accessor.byteOffset; + var byteLength = accessor.count * numberOfComponentsForType(accessor.type); - result[i + 1] = scratchCartesian.x; - result[i + 2] = scratchCartesian.y; - result[i + 3] = scratchCartesian.z; - } - return result; + var uriKey = dataUriRegex.test(buffer.uri) ? '' : buffer.uri; + return model.cacheKey + '//' + uriKey + '/' + byteOffset + '/' + byteLength; } - function convertCartographicDegreesToCartesian(cartographicDegrees) { - var length = cartographicDegrees.length; - if (length === 3) { - scratchCartographic.longitude = CesiumMath.toRadians(cartographicDegrees[0]); - scratchCartographic.latitude = CesiumMath.toRadians(cartographicDegrees[1]); - scratchCartographic.height = cartographicDegrees[2]; - Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); - return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; - } - - var result = new Array(length); - for (var i = 0; i < length; i += 4) { - result[i] = cartographicDegrees[i]; + var cachedAnimationParameters = { + }; - scratchCartographic.longitude = CesiumMath.toRadians(cartographicDegrees[i + 1]); - scratchCartographic.latitude = CesiumMath.toRadians(cartographicDegrees[i + 2]); - scratchCartographic.height = cartographicDegrees[i + 3]; - Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic, scratchCartesian); + ModelAnimationCache.getAnimationParameterValues = function(model, accessor) { + var key = getAccessorKey(model, accessor); + var values = cachedAnimationParameters[key]; - result[i + 1] = scratchCartesian.x; - result[i + 2] = scratchCartesian.y; - result[i + 3] = scratchCartesian.z; - } - return result; - } + if (!defined(values)) { + // Cache miss + var gltf = model.gltf; - function unwrapCartesianInterval(czmlInterval) { - var cartesian = czmlInterval.cartesian; - if (defined(cartesian)) { - return cartesian; - } + var buffers = gltf.buffers; + var bufferViews = gltf.bufferViews; - var cartesianVelocity = czmlInterval.cartesianVelocity; - if (defined(cartesianVelocity)) { - return cartesianVelocity; - } + var bufferView = bufferViews[accessor.bufferView]; + var bufferId = bufferView.buffer; + var buffer = buffers[bufferId]; + var source = buffer.extras._pipeline.source; - var unitCartesian = czmlInterval.unitCartesian; - if (defined(unitCartesian)) { - return unitCartesian; - } + var componentType = accessor.componentType; + var type = accessor.type; + var numberOfComponents = numberOfComponentsForType(type); + var count = accessor.count; + var byteStride = getAccessorByteStride(gltf, accessor); - var unitSpherical = czmlInterval.unitSpherical; - if (defined(unitSpherical)) { - return convertUnitSphericalToCartesian(unitSpherical); - } + values = new Array(count); + var accessorByteOffset = defaultValue(accessor.byteOffset, 0); + var byteOffset = bufferView.byteOffset + accessorByteOffset; + for (var i = 0; i < count; i++) { + var typedArrayView = ComponentDatatype.createArrayBufferView(componentType, source.buffer, source.byteOffset + byteOffset, numberOfComponents); + if (type === 'SCALAR') { + values[i] = typedArrayView[0]; + } else if (type === 'VEC3') { + values[i] = Cartesian3.fromArray(typedArrayView); + } else if (type === 'VEC4') { + values[i] = Quaternion.unpack(typedArrayView); + } + byteOffset += byteStride; + } + // GLTF_SPEC: Support more parameter types when glTF supports targeting materials. https://github.com/KhronosGroup/glTF/issues/142 - var spherical = czmlInterval.spherical; - if (defined(spherical)) { - return convertSphericalToCartesian(spherical); + if (defined(model.cacheKey)) { + // Only cache when we can create a unique id + cachedAnimationParameters[key] = values; + } } - var cartographicRadians = czmlInterval.cartographicRadians; - if (defined(cartographicRadians)) { - return convertCartographicRadiansToCartesian(cartographicRadians); - } + return values; + }; - var cartographicDegrees = czmlInterval.cartographicDegrees; - if (defined(cartographicDegrees)) { - return convertCartographicDegreesToCartesian(cartographicDegrees); - } + var cachedAnimationSplines = { + }; - throw new RuntimeError(JSON.stringify(czmlInterval) + ' is not a valid CZML interval.'); + function getAnimationSplineKey(model, animationName, samplerName) { + return model.cacheKey + '//' + animationName + '/' + samplerName; } - function normalizePackedCartesianArray(array, startingIndex) { - Cartesian3.unpack(array, startingIndex, scratchCartesian); - Cartesian3.normalize(scratchCartesian, scratchCartesian); - Cartesian3.pack(scratchCartesian, array, startingIndex); + function ConstantSpline(value) { + this._value = value; } + ConstantSpline.prototype.evaluate = function(time, result) { + return this._value; + }; - function unwrapUnitCartesianInterval(czmlInterval) { - var cartesian = unwrapCartesianInterval(czmlInterval); - if (cartesian.length === 3) { - normalizePackedCartesianArray(cartesian, 0); - return cartesian; - } - - for (var i = 1; i < cartesian.length; i += 4) { - normalizePackedCartesianArray(cartesian, i); - } - - return cartesian; - } + ModelAnimationCache.getAnimationSpline = function(model, animationName, animation, samplerName, sampler, input, path, output) { + var key = getAnimationSplineKey(model, animationName, samplerName); + var spline = cachedAnimationSplines[key]; - function normalizePackedQuaternionArray(array, startingIndex) { - Quaternion.unpack(array, startingIndex, scratchQuaternion); - Quaternion.normalize(scratchQuaternion, scratchQuaternion); - Quaternion.pack(scratchQuaternion, array, startingIndex); - } + if (!defined(spline)) { + var times = input; + var controlPoints = output; - function unwrapQuaternionInterval(czmlInterval) { - var unitQuaternion = czmlInterval.unitQuaternion; - if (defined(unitQuaternion)) { - if (unitQuaternion.length === 4) { - normalizePackedQuaternionArray(unitQuaternion, 0); - return unitQuaternion; + if ((times.length === 1) && (controlPoints.length === 1)) { + spline = new ConstantSpline(controlPoints[0]); + } else if (sampler.interpolation === 'LINEAR') { + if (path === 'translation' || path === 'scale') { + spline = new LinearSpline({ + times : times, + points : controlPoints + }); + } else if (path === 'rotation') { + spline = new QuaternionSpline({ + times : times, + points : controlPoints + }); + } else if (path === 'weights') { + spline = new WeightSpline({ + times : times, + weights : controlPoints + }); + } + // GLTF_SPEC: Support more parameter types when glTF supports targeting materials. https://github.com/KhronosGroup/glTF/issues/142 } - for (var i = 1; i < unitQuaternion.length; i += 5) { - normalizePackedQuaternionArray(unitQuaternion, i); + if (defined(model.cacheKey)) { + // Only cache when we can create a unique id + cachedAnimationSplines[key] = spline; } } - return unitQuaternion; - } - - function getPropertyType(czmlInterval) { - // The associations in this function need to be kept in sync with the - // associations in unwrapInterval. - - // Intentionally omitted due to conficts in CZML property names: - // * Image (conflicts with Uri) - // * Rotation (conflicts with Number) - // - // cartesianVelocity is also omitted due to incomplete support for - // derivative information in CZML properties. - // (Currently cartesianVelocity is hacked directly into the position processing code) - if (typeof czmlInterval === 'boolean') { - return Boolean; - } else if (typeof czmlInterval === 'number') { - return Number; - } else if (typeof czmlInterval === 'string') { - return String; - } else if (czmlInterval.hasOwnProperty('array')) { - return Array; - } else if (czmlInterval.hasOwnProperty('boolean')) { - return Boolean; - } else if (czmlInterval.hasOwnProperty('boundingRectangle')) { - return BoundingRectangle; - } else if (czmlInterval.hasOwnProperty('cartesian2')) { - return Cartesian2; - } else if (czmlInterval.hasOwnProperty('cartesian') || - czmlInterval.hasOwnProperty('spherical') || - czmlInterval.hasOwnProperty('cartographicRadians') || - czmlInterval.hasOwnProperty('cartographicDegrees')) { - return Cartesian3; - } else if (czmlInterval.hasOwnProperty('unitCartesian') || - czmlInterval.hasOwnProperty('unitSpherical')) { - return UnitCartesian3; - } else if (czmlInterval.hasOwnProperty('rgba') || - czmlInterval.hasOwnProperty('rgbaf')) { - return Color; - } else if (czmlInterval.hasOwnProperty('colorBlendMode')) { - return ColorBlendMode; - } else if (czmlInterval.hasOwnProperty('cornerType')) { - return CornerType; - } else if (czmlInterval.hasOwnProperty('heightReference')) { - return HeightReference; - } else if (czmlInterval.hasOwnProperty('horizontalOrigin')) { - return HorizontalOrigin; - } else if (czmlInterval.hasOwnProperty('date')) { - return JulianDate; - } else if (czmlInterval.hasOwnProperty('labelStyle')) { - return LabelStyle; - } else if (czmlInterval.hasOwnProperty('number')) { - return Number; - } else if (czmlInterval.hasOwnProperty('nearFarScalar')) { - return NearFarScalar; - } else if (czmlInterval.hasOwnProperty('distanceDisplayCondition')) { - return DistanceDisplayCondition; - } else if (czmlInterval.hasOwnProperty('object') || - czmlInterval.hasOwnProperty('value')) { - return Object; - } else if (czmlInterval.hasOwnProperty('unitQuaternion')) { - return Quaternion; - } else if (czmlInterval.hasOwnProperty('shadowMode')) { - return ShadowMode; - } else if (czmlInterval.hasOwnProperty('string')) { - return String; - } else if (czmlInterval.hasOwnProperty('stripeOrientation')) { - return StripeOrientation; - } else if (czmlInterval.hasOwnProperty('wsen') || - czmlInterval.hasOwnProperty('wsenDegrees')) { - return Rectangle; - } else if (czmlInterval.hasOwnProperty('uri')) { - return Uri; - } else if (czmlInterval.hasOwnProperty('verticalOrigin')) { - return VerticalOrigin; - } - // fallback case - return Object; - } - - function unwrapInterval(type, czmlInterval, sourceUri, query) { - // The associations in this function need to be kept in sync with the - // associations in getPropertyType - switch (type) { - case Array: - return czmlInterval.array; - case Boolean: - return defaultValue(czmlInterval['boolean'], czmlInterval); - case BoundingRectangle: - return czmlInterval.boundingRectangle; - case Cartesian2: - return czmlInterval.cartesian2; - case Cartesian3: - return unwrapCartesianInterval(czmlInterval); - case UnitCartesian3: - return unwrapUnitCartesianInterval(czmlInterval); - case Color: - return unwrapColorInterval(czmlInterval); - case ColorBlendMode: - return ColorBlendMode[defaultValue(czmlInterval.colorBlendMode, czmlInterval)]; - case CornerType: - return CornerType[defaultValue(czmlInterval.cornerType, czmlInterval)]; - case HeightReference: - return HeightReference[defaultValue(czmlInterval.heightReference, czmlInterval)]; - case HorizontalOrigin: - return HorizontalOrigin[defaultValue(czmlInterval.horizontalOrigin, czmlInterval)]; - case Image: - return unwrapUriInterval(czmlInterval, sourceUri, query); - case JulianDate: - return JulianDate.fromIso8601(defaultValue(czmlInterval.date, czmlInterval)); - case LabelStyle: - return LabelStyle[defaultValue(czmlInterval.labelStyle, czmlInterval)]; - case Number: - return defaultValue(czmlInterval.number, czmlInterval); - case NearFarScalar: - return czmlInterval.nearFarScalar; - case DistanceDisplayCondition: - return czmlInterval.distanceDisplayCondition; - case Object: - return defaultValue(defaultValue(czmlInterval.object, czmlInterval.value), czmlInterval); - case Quaternion: - return unwrapQuaternionInterval(czmlInterval); - case Rotation: - return defaultValue(czmlInterval.number, czmlInterval); - case ShadowMode: - return ShadowMode[defaultValue(defaultValue(czmlInterval.shadowMode, czmlInterval.shadows), czmlInterval)]; - case String: - return defaultValue(czmlInterval.string, czmlInterval); - case StripeOrientation: - return StripeOrientation[defaultValue(czmlInterval.stripeOrientation, czmlInterval)]; - case Rectangle: - return unwrapRectangleInterval(czmlInterval); - case Uri: - return unwrapUriInterval(czmlInterval, sourceUri, query); - case VerticalOrigin: - return VerticalOrigin[defaultValue(czmlInterval.verticalOrigin, czmlInterval)]; - default: - throw new RuntimeError(type); - } - } - var interpolators = { - HERMITE : HermitePolynomialApproximation, - LAGRANGE : LagrangePolynomialApproximation, - LINEAR : LinearApproximation + return spline; }; - function updateInterpolationSettings(packetData, property) { - var interpolationAlgorithm = packetData.interpolationAlgorithm; - if (defined(interpolationAlgorithm) || defined(packetData.interpolationDegree)) { - property.setInterpolationOptions({ - interpolationAlgorithm : interpolators[interpolationAlgorithm], - interpolationDegree : packetData.interpolationDegree - }); - } - - var forwardExtrapolationType = packetData.forwardExtrapolationType; - if (defined(forwardExtrapolationType)) { - property.forwardExtrapolationType = ExtrapolationType[forwardExtrapolationType]; - } - - var forwardExtrapolationDuration = packetData.forwardExtrapolationDuration; - if (defined(forwardExtrapolationDuration)) { - property.forwardExtrapolationDuration = forwardExtrapolationDuration; - } - - var backwardExtrapolationType = packetData.backwardExtrapolationType; - if (defined(backwardExtrapolationType)) { - property.backwardExtrapolationType = ExtrapolationType[backwardExtrapolationType]; - } - - var backwardExtrapolationDuration = packetData.backwardExtrapolationDuration; - if (defined(backwardExtrapolationDuration)) { - property.backwardExtrapolationDuration = backwardExtrapolationDuration; - } - } - - var iso8601Scratch = { - iso8601 : undefined + var cachedSkinInverseBindMatrices = { }; - function processProperty(type, object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection, query) { - var combinedInterval; - var packetInterval = packetData.interval; - if (defined(packetInterval)) { - iso8601Scratch.iso8601 = packetInterval; - combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); - if (defined(constrainedInterval)) { - combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); - } - } else if (defined(constrainedInterval)) { - combinedInterval = constrainedInterval; - } + ModelAnimationCache.getSkinInverseBindMatrices = function(model, accessor) { + var key = getAccessorKey(model, accessor); + var matrices = cachedSkinInverseBindMatrices[key]; - var packedLength; - var isSampled; - var unwrappedInterval; - var unwrappedIntervalLength; + if (!defined(matrices)) { + // Cache miss + var gltf = model.gltf; + var buffers = gltf.buffers; + var bufferViews = gltf.bufferViews; - // CZML properties can be defined in many ways. Most ways represent a structure for - // encoding a single value (number, string, cartesian, etc.) Regardless of the value type, - // if it encodes a single value it will get loaded into a ConstantProperty eventually. - // Alternatively, there are ways of defining a property that require specialized - // client-side representation. Currently, these are ReferenceProperty, - // and client-side velocity computation properties such as VelocityVectorProperty. - var isValue = !defined(packetData.reference) && !defined(packetData.velocityReference); - var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL); + var bufferViewId = accessor.bufferView; + var bufferView = bufferViews[bufferViewId]; + var bufferId = bufferView.buffer; + var buffer = buffers[bufferId]; + var source = buffer.extras._pipeline.source; - if (isValue) { - unwrappedInterval = unwrapInterval(type, packetData, sourceUri, query); - packedLength = defaultValue(type.packedLength, 1); - unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1); - isSampled = !defined(packetData.array) && (typeof unwrappedInterval !== 'string') && (unwrappedIntervalLength > packedLength) && (type !== Object); - } + var componentType = accessor.componentType; + var type = accessor.type; + var count = accessor.count; + var byteStride = getAccessorByteStride(gltf, accessor); + var byteOffset = bufferView.byteOffset + accessor.byteOffset; + var numberOfComponents = numberOfComponentsForType(type); - //Rotation is a special case because it represents a native type (Number) - //and therefore does not need to be unpacked when loaded as a constant value. - var needsUnpacking = typeof type.unpack === 'function' && type !== Rotation; + matrices = new Array(count); - //Any time a constant value is assigned, it completely blows away anything else. - if (!isSampled && !hasInterval) { - if (isValue) { - object[propertyName] = new ConstantProperty(needsUnpacking ? type.unpack(unwrappedInterval, 0) : unwrappedInterval); - } else { - object[propertyName] = createSpecializedProperty(type, entityCollection, packetData); + if ((componentType === WebGLConstants.FLOAT) && (type === AttributeType.MAT4)) { + for (var i = 0; i < count; ++i) { + var typedArrayView = ComponentDatatype.createArrayBufferView(componentType, source.buffer, source.byteOffset + byteOffset, numberOfComponents); + matrices[i] = Matrix4.fromArray(typedArrayView); + byteOffset += byteStride; + } } - return; + + cachedSkinInverseBindMatrices[key] = matrices; } - var property = object[propertyName]; + return matrices; + }; - var epoch; - var packetEpoch = packetData.epoch; - if (defined(packetEpoch)) { - epoch = JulianDate.fromIso8601(packetEpoch); - } + return ModelAnimationCache; +}); - //Without an interval, any sampled value is infinite, meaning it completely - //replaces any non-sampled property that may exist. - if (isSampled && !hasInterval) { - if (!(property instanceof SampledProperty)) { - property = new SampledProperty(type); - object[propertyName] = property; - } - property.addSamplesPackedArray(unwrappedInterval, epoch); - updateInterpolationSettings(packetData, property); - return; - } +define('Scene/ModelAnimationLoop',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - var interval; + /** + * Determines if and how a glTF animation is looped. + * + * @exports ModelAnimationLoop + * + * @see ModelAnimationCollection#add + */ + var ModelAnimationLoop = { + /** + * Play the animation once; do not loop it. + * + * @type {Number} + * @constant + */ + NONE : 0, - //A constant value with an interval is normally part of a TimeIntervalCollection, - //However, if the current property is not a time-interval collection, we need - //to turn it into a Composite, preserving the old data with the new interval. - if (!isSampled && hasInterval) { - //Create a new interval for the constant value. - combinedInterval = combinedInterval.clone(); - if (isValue) { - combinedInterval.data = needsUnpacking ? type.unpack(unwrappedInterval, 0) : unwrappedInterval; - } else { - combinedInterval.data = createSpecializedProperty(type, entityCollection, packetData); - } + /** + * Loop the animation playing it from the start immediately after it stops. + * + * @type {Number} + * @constant + */ + REPEAT : 1, - //If no property exists, simply use a new interval collection - if (!defined(property)) { - if (isValue) { - property = new TimeIntervalCollectionProperty(); - } else { - property = new CompositeProperty(); - } - object[propertyName] = property; - } + /** + * Loop the animation. First, playing it forward, then in reverse, then forward, and so on. + * + * @type {Number} + * @constant + */ + MIRRORED_REPEAT : 2 + }; - if (isValue && property instanceof TimeIntervalCollectionProperty) { - //If we create a collection, or it already existed, use it. - property.intervals.addInterval(combinedInterval); - } else if (property instanceof CompositeProperty) { - //If the collection was already a CompositeProperty, use it. - if (isValue) { - combinedInterval.data = new ConstantProperty(combinedInterval.data); - } - property.intervals.addInterval(combinedInterval); - } else { - //Otherwise, create a CompositeProperty but preserve the existing data. + return freezeObject(ModelAnimationLoop); +}); - //Put the old property in an infinite interval. - interval = Iso8601.MAXIMUM_INTERVAL.clone(); - interval.data = property; +define('Scene/ModelAnimationState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - //Create the composite. - property = new CompositeProperty(); - object[propertyName] = property; + /** + * @private + */ + return freezeObject({ + STOPPED : 0, + ANIMATING : 1 + }); +}); - //add the old property interval - property.intervals.addInterval(interval); +define('Scene/ModelAnimation',[ + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/Event', + '../Core/JulianDate', + './ModelAnimationLoop', + './ModelAnimationState' + ], function( + defaultValue, + defineProperties, + Event, + JulianDate, + ModelAnimationLoop, + ModelAnimationState) { + 'use strict'; - //Change the new data to a ConstantProperty and add it. - if (isValue) { - combinedInterval.data = new ConstantProperty(combinedInterval.data); - } - property.intervals.addInterval(combinedInterval); - } + /** + * An active glTF animation. A glTF asset can contain animations. An active animation + * is an animation that is currently playing or scheduled to be played because it was + * added to a model's {@link ModelAnimationCollection}. An active animation is an + * instance of an animation; for example, there can be multiple active animations + * for the same glTF animation, each with a different start time. + * <p> + * Create this by calling {@link ModelAnimationCollection#add}. + * </p> + * + * @alias ModelAnimation + * @internalConstructor + * + * @see ModelAnimationCollection#add + */ + function ModelAnimation(options, model, runtimeAnimation) { + this._name = runtimeAnimation.name; + this._startTime = JulianDate.clone(options.startTime); + this._delay = defaultValue(options.delay, 0.0); // in seconds + this._stopTime = options.stopTime; - return; - } + /** + * When <code>true</code>, the animation is removed after it stops playing. + * This is slightly more efficient that not removing it, but if, for example, + * time is reversed, the animation is not played again. + * + * @type {Boolean} + * @default false + */ + this.removeOnStop = defaultValue(options.removeOnStop, false); - //isSampled && hasInterval - if (!defined(property)) { - property = new CompositeProperty(); - object[propertyName] = property; - } + this._speedup = defaultValue(options.speedup, 1.0); + this._reverse = defaultValue(options.reverse, false); + this._loop = defaultValue(options.loop, ModelAnimationLoop.NONE); - //create a CompositeProperty but preserve the existing data. - if (!(property instanceof CompositeProperty)) { - //Put the old property in an infinite interval. - interval = Iso8601.MAXIMUM_INTERVAL.clone(); - interval.data = property; + /** + * The event fired when this animation is started. This can be used, for + * example, to play a sound or start a particle system, when the animation starts. + * <p> + * This event is fired at the end of the frame after the scene is rendered. + * </p> + * + * @type {Event} + * @default new Event() + * + * @example + * animation.start.addEventListener(function(model, animation) { + * console.log('Animation started: ' + animation.name); + * }); + */ + this.start = new Event(); - //Create the composite. - property = new CompositeProperty(); - object[propertyName] = property; + /** + * The event fired when on each frame when this animation is updated. The + * current time of the animation, relative to the glTF animation time span, is + * passed to the event, which allows, for example, starting new animations at a + * specific time relative to a playing animation. + * <p> + * This event is fired at the end of the frame after the scene is rendered. + * </p> + * + * @type {Event} + * @default new Event() + * + * @example + * animation.update.addEventListener(function(model, animation, time) { + * console.log('Animation updated: ' + animation.name + '. glTF animation time: ' + time); + * }); + */ + this.update = new Event(); - //add the old property interval - property.intervals.addInterval(interval); - } + /** + * The event fired when this animation is stopped. This can be used, for + * example, to play a sound or start a particle system, when the animation stops. + * <p> + * This event is fired at the end of the frame after the scene is rendered. + * </p> + * + * @type {Event} + * @default new Event() + * + * @example + * animation.stop.addEventListener(function(model, animation) { + * console.log('Animation stopped: ' + animation.name); + * }); + */ + this.stop = new Event(); - //Check if the interval already exists in the composite - var intervals = property.intervals; - interval = intervals.findInterval(combinedInterval); - if (!defined(interval) || !(interval.data instanceof SampledProperty)) { - //If not, create a SampledProperty for it. - interval = combinedInterval.clone(); - interval.data = new SampledProperty(type); - intervals.addInterval(interval); - } - interval.data.addSamplesPackedArray(unwrappedInterval, epoch); - updateInterpolationSettings(packetData, interval.data); - } + this._state = ModelAnimationState.STOPPED; + this._runtimeAnimation = runtimeAnimation; - function processPacketData(type, object, propertyName, packetData, interval, sourceUri, entityCollection, query) { - if (!defined(packetData)) { - return; - } + // Set during animation update + this._computedStartTime = undefined; + this._duration = undefined; - if (isArray(packetData)) { - for (var i = 0, len = packetData.length; i < len; i++) { - processProperty(type, object, propertyName, packetData[i], interval, sourceUri, entityCollection, query); - } - } else { - processProperty(type, object, propertyName, packetData, interval, sourceUri, entityCollection, query); - } + // To avoid allocations in ModelAnimationCollection.update + var that = this; + this._raiseStartEvent = function() { + that.start.raiseEvent(model, that); + }; + this._updateEventTime = 0.0; + this._raiseUpdateEvent = function() { + that.update.raiseEvent(model, that, that._updateEventTime); + }; + this._raiseStopEvent = function() { + that.stop.raiseEvent(model, that); + }; } - function processPositionProperty(object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection, query) { - var combinedInterval; - var packetInterval = packetData.interval; - if (defined(packetInterval)) { - iso8601Scratch.iso8601 = packetInterval; - combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); - if (defined(constrainedInterval)) { - combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); + defineProperties(ModelAnimation.prototype, { + /** + * The glTF animation name that identifies this animation. + * + * @memberof ModelAnimation.prototype + * + * @type {String} + * @readonly + */ + name : { + get : function() { + return this._name; } - } else if (defined(constrainedInterval)) { - combinedInterval = constrainedInterval; - } - - var referenceFrame; - var unwrappedInterval; - var isSampled = false; - var unwrappedIntervalLength; - var numberOfDerivatives = defined(packetData.cartesianVelocity) ? 1 : 0; - var packedLength = Cartesian3.packedLength * (numberOfDerivatives + 1); - var isValue = !defined(packetData.reference); - var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL); + }, - if (isValue) { - if (defined(packetData.referenceFrame)) { - referenceFrame = ReferenceFrame[packetData.referenceFrame]; + /** + * The scene time to start playing this animation. When this is <code>undefined</code>, + * the animation starts at the next frame. + * + * @memberof ModelAnimation.prototype + * + * @type {JulianDate} + * @readonly + * + * @default undefined + */ + startTime : { + get : function() { + return this._startTime; } - referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); - unwrappedInterval = unwrapCartesianInterval(packetData); - unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1); - isSampled = unwrappedIntervalLength > packedLength; - } + }, - //Any time a constant value is assigned, it completely blows away anything else. - if (!isSampled && !hasInterval) { - if (isValue) { - object[propertyName] = new ConstantPositionProperty(Cartesian3.unpack(unwrappedInterval), referenceFrame); - } else { - object[propertyName] = createReferenceProperty(entityCollection, packetData.reference); + /** + * The delay, in seconds, from {@link ModelAnimation#startTime} to start playing. + * + * @memberof ModelAnimation.prototype + * + * @type {Number} + * @readonly + * + * @default undefined + */ + delay : { + get : function() { + return this._delay; } - return; - } - - var property = object[propertyName]; - - var epoch; - var packetEpoch = packetData.epoch; - if (defined(packetEpoch)) { - epoch = JulianDate.fromIso8601(packetEpoch); - } + }, - //Without an interval, any sampled value is infinite, meaning it completely - //replaces any non-sampled property that may exist. - if (isSampled && !hasInterval) { - if (!(property instanceof SampledPositionProperty) || (defined(referenceFrame) && property.referenceFrame !== referenceFrame)) { - property = new SampledPositionProperty(referenceFrame, numberOfDerivatives); - object[propertyName] = property; + /** + * The scene time to stop playing this animation. When this is <code>undefined</code>, + * the animation is played for its full duration and perhaps repeated depending on + * {@link ModelAnimation#loop}. + * + * @memberof ModelAnimation.prototype + * + * @type {JulianDate} + * @readonly + * + * @default undefined + */ + stopTime : { + get : function() { + return this._stopTime; } - property.addSamplesPackedArray(unwrappedInterval, epoch); - updateInterpolationSettings(packetData, property); - return; - } + }, - var interval; + /** + * Values greater than <code>1.0</code> increase the speed that the animation is played relative + * to the scene clock speed; values less than <code>1.0</code> decrease the speed. A value of + * <code>1.0</code> plays the animation at the speed in the glTF animation mapped to the scene + * clock speed. For example, if the scene is played at 2x real-time, a two-second glTF animation + * will play in one second even if <code>speedup</code> is <code>1.0</code>. + * + * @memberof ModelAnimation.prototype + * + * @type {Number} + * @readonly + * + * @default 1.0 + */ + speedup : { + get : function() { + return this._speedup; + } + }, - //A constant value with an interval is normally part of a TimeIntervalCollection, - //However, if the current property is not a time-interval collection, we need - //to turn it into a Composite, preserving the old data with the new interval. - if (!isSampled && hasInterval) { - //Create a new interval for the constant value. - combinedInterval = combinedInterval.clone(); - if (isValue) { - combinedInterval.data = Cartesian3.unpack(unwrappedInterval); - } else { - combinedInterval.data = createReferenceProperty(entityCollection, packetData.reference); + /** + * When <code>true</code>, the animation is played in reverse. + * + * @memberof ModelAnimation.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + reverse : { + get : function() { + return this._reverse; } + }, - //If no property exists, simply use a new interval collection - if (!defined(property)) { - if (isValue) { - property = new TimeIntervalCollectionPositionProperty(referenceFrame); - } else { - property = new CompositePositionProperty(referenceFrame); - } - object[propertyName] = property; + /** + * Determines if and how the animation is looped. + * + * @memberof ModelAnimation.prototype + * + * @type {ModelAnimationLoop} + * @readonly + * + * @default {@link ModelAnimationLoop.NONE} + */ + loop : { + get : function() { + return this._loop; } + } + }); - if (isValue && property instanceof TimeIntervalCollectionPositionProperty && (defined(referenceFrame) && property.referenceFrame === referenceFrame)) { - //If we create a collection, or it already existed, use it. - property.intervals.addInterval(combinedInterval); - } else if (property instanceof CompositePositionProperty) { - //If the collection was already a CompositePositionProperty, use it. - if (isValue) { - combinedInterval.data = new ConstantPositionProperty(combinedInterval.data, referenceFrame); - } - property.intervals.addInterval(combinedInterval); - } else { - //Otherwise, create a CompositePositionProperty but preserve the existing data. + return ModelAnimation; +}); - //Put the old property in an infinite interval. - interval = Iso8601.MAXIMUM_INTERVAL.clone(); - interval.data = property; +define('Scene/ModelAnimationCollection',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/JulianDate', + '../Core/Math', + './ModelAnimation', + './ModelAnimationLoop', + './ModelAnimationState' + ], function( + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + JulianDate, + CesiumMath, + ModelAnimation, + ModelAnimationLoop, + ModelAnimationState) { + 'use strict'; - //Create the composite. - property = new CompositePositionProperty(property.referenceFrame); - object[propertyName] = property; + /** + * A collection of active model animations. Access this using {@link Model#activeAnimations}. + * + * @alias ModelAnimationCollection + * @internalConstructor + * + * @see Model#activeAnimations + */ + function ModelAnimationCollection(model) { + /** + * The event fired when an animation is added to the collection. This can be used, for + * example, to keep a UI in sync. + * + * @type {Event} + * @default new Event() + * + * @example + * model.activeAnimations.animationAdded.addEventListener(function(model, animation) { + * console.log('Animation added: ' + animation.name); + * }); + */ + this.animationAdded = new Event(); - //add the old property interval - property.intervals.addInterval(interval); + /** + * The event fired when an animation is removed from the collection. This can be used, for + * example, to keep a UI in sync. + * + * @type {Event} + * @default new Event() + * + * @example + * model.activeAnimations.animationRemoved.addEventListener(function(model, animation) { + * console.log('Animation removed: ' + animation.name); + * }); + */ + this.animationRemoved = new Event(); - //Change the new data to a ConstantPositionProperty and add it. - if (isValue) { - combinedInterval.data = new ConstantPositionProperty(combinedInterval.data, referenceFrame); - } - property.intervals.addInterval(combinedInterval); - } + this._model = model; + this._scheduledAnimations = []; + this._previousTime = undefined; + } - return; + defineProperties(ModelAnimationCollection.prototype, { + /** + * The number of animations in the collection. + * + * @memberof ModelAnimationCollection.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._scheduledAnimations.length; + } } + }); - //isSampled && hasInterval - if (!defined(property)) { - property = new CompositePositionProperty(referenceFrame); - object[propertyName] = property; - } else if (!(property instanceof CompositePositionProperty)) { - //create a CompositeProperty but preserve the existing data. - //Put the old property in an infinite interval. - interval = Iso8601.MAXIMUM_INTERVAL.clone(); - interval.data = property; + function add(collection, index, options) { + var model = collection._model; + var animations = model._runtime.animations; + var animation = animations[index]; + var scheduledAnimation = new ModelAnimation(options, model, animation); + collection._scheduledAnimations.push(scheduledAnimation); + collection.animationAdded.raiseEvent(model, scheduledAnimation); + return scheduledAnimation; + } - //Create the composite. - property = new CompositePositionProperty(property.referenceFrame); - object[propertyName] = property; + /** + * Creates and adds an animation with the specified initial properties to the collection. + * <p> + * This raises the {@link ModelAnimationCollection#animationAdded} event so, for example, a UI can stay in sync. + * </p> + * + * @param {Object} options Object with the following properties: + * @param {String} [options.name] The glTF animation name that identifies the animation. Must be defined if <code>options.id</code> is <code>undefined</code>. + * @param {Number} [options.index] The glTF animation index that identifies the animation. Must be defined if <code>options.name</code> is <code>undefined</code>. + * @param {JulianDate} [options.startTime] The scene time to start playing the animation. When this is <code>undefined</code>, the animation starts at the next frame. + * @param {Number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. + * @param {JulianDate} [options.stopTime] The scene time to stop playing the animation. When this is <code>undefined</code>, the animation is played for its full duration. + * @param {Boolean} [options.removeOnStop=false] When <code>true</code>, the animation is removed after it stops playing. + * @param {Number} [options.speedup=1.0] Values greater than <code>1.0</code> increase the speed that the animation is played relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. + * @param {Boolean} [options.reverse=false] When <code>true</code>, the animation is played in reverse. + * @param {ModelAnimationLoop} [options.loop=ModelAnimationLoop.NONE] Determines if and how the animation is looped. + * @returns {ModelAnimation} The animation that was added to the collection. + * + * @exception {DeveloperError} Animations are not loaded. Wait for the {@link Model#readyPromise} to resolve. + * @exception {DeveloperError} options.name must be a valid animation name. + * @exception {DeveloperError} options.index must be a valid animation index. + * @exception {DeveloperError} Either options.name or options.index must be defined. + * @exception {DeveloperError} options.speedup must be greater than zero. + * + * @example + * // Example 1. Add an animation by name + * model.activeAnimations.add({ + * name : 'animation name' + * }); + * + * // Example 2. Add an animation by index + * model.activeAnimations.add({ + * index : 0 + * }); + * + * @example + * // Example 3. Add an animation and provide all properties and events + * var startTime = Cesium.JulianDate.now(); + * + * var animation = model.activeAnimations.add({ + * name : 'another animation name', + * startTime : startTime, + * delay : 0.0, // Play at startTime (default) + * stopTime : Cesium.JulianDate.addSeconds(startTime, 4.0, new Cesium.JulianDate()), + * removeOnStop : false, // Do not remove when animation stops (default) + * speedup : 2.0, // Play at double speed + * reverse : true, // Play in reverse + * loop : Cesium.ModelAnimationLoop.REPEAT // Loop the animation + * }); + * + * animation.start.addEventListener(function(model, animation) { + * console.log('Animation started: ' + animation.name); + * }); + * animation.update.addEventListener(function(model, animation, time) { + * console.log('Animation updated: ' + animation.name + '. glTF animation time: ' + time); + * }); + * animation.stop.addEventListener(function(model, animation) { + * console.log('Animation stopped: ' + animation.name); + * }); + */ + ModelAnimationCollection.prototype.add = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //add the old property interval - property.intervals.addInterval(interval); - } + var model = this._model; + var animations = model._runtime.animations; - //Check if the interval already exists in the composite - var intervals = property.intervals; - interval = intervals.findInterval(combinedInterval); - if (!defined(interval) || !(interval.data instanceof SampledPositionProperty) || (defined(referenceFrame) && interval.data.referenceFrame !== referenceFrame)) { - //If not, create a SampledPositionProperty for it. - interval = combinedInterval.clone(); - interval.data = new SampledPositionProperty(referenceFrame, numberOfDerivatives); - intervals.addInterval(interval); + if (!defined(animations)) { + throw new DeveloperError('Animations are not loaded. Wait for Model.readyPromise to resolve.'); } - interval.data.addSamplesPackedArray(unwrappedInterval, epoch); - updateInterpolationSettings(packetData, interval.data); - } - - function processPositionPacketData(object, propertyName, packetData, interval, sourceUri, entityCollection, query) { - if (!defined(packetData)) { - return; + if (!defined(options.name) && !defined(options.index)) { + throw new DeveloperError('Either options.name or options.index must be defined.'); } - - if (isArray(packetData)) { - for (var i = 0, len = packetData.length; i < len; i++) { - processPositionProperty(object, propertyName, packetData[i], interval, sourceUri, entityCollection, query); - } - } else { - processPositionProperty(object, propertyName, packetData, interval, sourceUri, entityCollection, query); + if (defined(options.speedup) && (options.speedup <= 0.0)) { + throw new DeveloperError('options.speedup must be greater than zero.'); } - } - - function processMaterialProperty(object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection, query) { - var combinedInterval; - var packetInterval = packetData.interval; - if (defined(packetInterval)) { - iso8601Scratch.iso8601 = packetInterval; - combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); - if (defined(constrainedInterval)) { - combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); - } - } else if (defined(constrainedInterval)) { - combinedInterval = constrainedInterval; + if (defined(options.index) && (options.index >= animations.length || options.index < 0)) { + throw new DeveloperError('options.index must be a valid animation index.'); + } + + if (defined(options.index)) { + return add(this, options.index, options); } - var property = object[propertyName]; - var existingMaterial; - var existingInterval; - - if (defined(combinedInterval)) { - if (!(property instanceof CompositeMaterialProperty)) { - property = new CompositeMaterialProperty(); - object[propertyName] = property; - } - //See if we already have data at that interval. - var thisIntervals = property.intervals; - existingInterval = thisIntervals.findInterval({ - start : combinedInterval.start, - stop : combinedInterval.stop - }); - if (defined(existingInterval)) { - //We have an interval, but we need to make sure the - //new data is the same type of material as the old data. - existingMaterial = existingInterval.data; - } else { - //If not, create it. - existingInterval = combinedInterval.clone(); - thisIntervals.addInterval(existingInterval); + // Find the index of the animation with the given name + var index; + var length = animations.length; + for (var i = 0; i < length; ++i) { + if (animations[i].name === options.name) { + index = i; + break; } - } else { - existingMaterial = property; } - var materialData; - if (defined(packetData.solidColor)) { - if (!(existingMaterial instanceof ColorMaterialProperty)) { - existingMaterial = new ColorMaterialProperty(); - } - materialData = packetData.solidColor; - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, undefined, entityCollection); - } else if (defined(packetData.grid)) { - if (!(existingMaterial instanceof GridMaterialProperty)) { - existingMaterial = new GridMaterialProperty(); - } - materialData = packetData.grid; - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection, query); - processPacketData(Number, existingMaterial, 'cellAlpha', materialData.cellAlpha, undefined, sourceUri, entityCollection, query); - processPacketData(Cartesian2, existingMaterial, 'lineCount', materialData.lineCount, undefined, sourceUri, entityCollection, query); - processPacketData(Cartesian2, existingMaterial, 'lineThickness', materialData.lineThickness, undefined, sourceUri, entityCollection, query); - processPacketData(Cartesian2, existingMaterial, 'lineOffset', materialData.lineOffset, undefined, sourceUri, entityCollection, query); - } else if (defined(packetData.image)) { - if (!(existingMaterial instanceof ImageMaterialProperty)) { - existingMaterial = new ImageMaterialProperty(); - } - materialData = packetData.image; - processPacketData(Image, existingMaterial, 'image', materialData.image, undefined, sourceUri, entityCollection, query); - processPacketData(Cartesian2, existingMaterial, 'repeat', materialData.repeat, undefined, sourceUri, entityCollection, query); - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection, query); - processPacketData(Boolean, existingMaterial, 'transparent', materialData.transparent, undefined, sourceUri, entityCollection, query); - } else if (defined(packetData.stripe)) { - if (!(existingMaterial instanceof StripeMaterialProperty)) { - existingMaterial = new StripeMaterialProperty(); - } - materialData = packetData.stripe; - processPacketData(StripeOrientation, existingMaterial, 'orientation', materialData.orientation, undefined, sourceUri, entityCollection, query); - processPacketData(Color, existingMaterial, 'evenColor', materialData.evenColor, undefined, sourceUri, entityCollection, query); - processPacketData(Color, existingMaterial, 'oddColor', materialData.oddColor, undefined, sourceUri, entityCollection, query); - processPacketData(Number, existingMaterial, 'offset', materialData.offset, undefined, sourceUri, entityCollection, query); - processPacketData(Number, existingMaterial, 'repeat', materialData.repeat, undefined, sourceUri, entityCollection, query); - } else if (defined(packetData.polylineOutline)) { - if (!(existingMaterial instanceof PolylineOutlineMaterialProperty)) { - existingMaterial = new PolylineOutlineMaterialProperty(); - } - materialData = packetData.polylineOutline; - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection, query); - processPacketData(Color, existingMaterial, 'outlineColor', materialData.outlineColor, undefined, sourceUri, entityCollection, query); - processPacketData(Number, existingMaterial, 'outlineWidth', materialData.outlineWidth, undefined, sourceUri, entityCollection, query); - } else if (defined(packetData.polylineGlow)) { - if (!(existingMaterial instanceof PolylineGlowMaterialProperty)) { - existingMaterial = new PolylineGlowMaterialProperty(); - } - materialData = packetData.polylineGlow; - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, sourceUri, entityCollection, query); - processPacketData(Number, existingMaterial, 'glowPower', materialData.glowPower, undefined, sourceUri, entityCollection, query); - } else if (defined(packetData.polylineArrow)) { - if (!(existingMaterial instanceof PolylineArrowMaterialProperty)) { - existingMaterial = new PolylineArrowMaterialProperty(); - } - materialData = packetData.polylineArrow; - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, undefined, entityCollection); - } else if (defined(packetData.polylineDash)) { - if (!(existingMaterial instanceof PolylineDashMaterialProperty)) { - existingMaterial = new PolylineDashMaterialProperty(); - } - materialData = packetData.polylineDash; - processPacketData(Color, existingMaterial, 'color', materialData.color, undefined, undefined, entityCollection); - processPacketData(Color, existingMaterial, 'gapColor', materialData.gapColor, undefined, undefined, entityCollection); - processPacketData(Number, existingMaterial, 'dashLength', materialData.dashLength, undefined, sourceUri, entityCollection, query); - processPacketData(Number, existingMaterial, 'dashPattern', materialData.dashPattern, undefined, sourceUri, entityCollection, query); + if (!defined(index)) { + throw new DeveloperError('options.name must be a valid animation name.'); } + + return add(this, index, options); + }; - if (defined(existingInterval)) { - existingInterval.data = existingMaterial; - } else { - object[propertyName] = existingMaterial; + /** + * Creates and adds an animation with the specified initial properties to the collection + * for each animation in the model. + * <p> + * This raises the {@link ModelAnimationCollection#animationAdded} event for each model so, for example, a UI can stay in sync. + * </p> + * + * @param {Object} [options] Object with the following properties: + * @param {JulianDate} [options.startTime] The scene time to start playing the animations. When this is <code>undefined</code>, the animations starts at the next frame. + * @param {Number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. + * @param {JulianDate} [options.stopTime] The scene time to stop playing the animations. When this is <code>undefined</code>, the animations are played for its full duration. + * @param {Boolean} [options.removeOnStop=false] When <code>true</code>, the animations are removed after they stop playing. + * @param {Number} [options.speedup=1.0] Values greater than <code>1.0</code> increase the speed that the animations play relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. + * @param {Boolean} [options.reverse=false] When <code>true</code>, the animations are played in reverse. + * @param {ModelAnimationLoop} [options.loop=ModelAnimationLoop.NONE] Determines if and how the animations are looped. + * @returns {ModelAnimation[]} An array of {@link ModelAnimation} objects, one for each animation added to the collection. If there are no glTF animations, the array is empty. + * + * @exception {DeveloperError} Animations are not loaded. Wait for the {@link Model#readyPromise} to resolve. + * @exception {DeveloperError} options.speedup must be greater than zero. + * + * @example + * model.activeAnimations.addAll({ + * speedup : 0.5, // Play at half-speed + * loop : Cesium.ModelAnimationLoop.REPEAT // Loop the animations + * }); + */ + ModelAnimationCollection.prototype.addAll = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + if (!defined(this._model._runtime.animations)) { + throw new DeveloperError('Animations are not loaded. Wait for Model.readyPromise to resolve.'); } - } - function processMaterialPacketData(object, propertyName, packetData, interval, sourceUri, entityCollection, query) { - if (!defined(packetData)) { - return; + if (defined(options.speedup) && (options.speedup <= 0.0)) { + throw new DeveloperError('options.speedup must be greater than zero.'); + } + + var scheduledAnimations = []; + var model = this._model; + var animations = model._runtime.animations; + var length = animations.length; + for (var i = 0; i < length; ++i) { + scheduledAnimations.push(add(this, i, options)); } + return scheduledAnimations; + }; - if (isArray(packetData)) { - for (var i = 0, len = packetData.length; i < len; i++) { - processMaterialProperty(object, propertyName, packetData[i], interval, sourceUri, entityCollection, query); + /** + * Removes an animation from the collection. + * <p> + * This raises the {@link ModelAnimationCollection#animationRemoved} event so, for example, a UI can stay in sync. + * </p> + * <p> + * An animation can also be implicitly removed from the collection by setting {@link ModelAnimation#removeOnStop} to + * <code>true</code>. The {@link ModelAnimationCollection#animationRemoved} event is still fired when the animation is removed. + * </p> + * + * @param {ModelAnimation} animation The animation to remove. + * @returns {Boolean} <code>true</code> if the animation was removed; <code>false</code> if the animation was not found in the collection. + * + * @example + * var a = model.activeAnimations.add({ + * name : 'animation name' + * }); + * model.activeAnimations.remove(a); // Returns true + */ + ModelAnimationCollection.prototype.remove = function(animation) { + if (defined(animation)) { + var animations = this._scheduledAnimations; + var i = animations.indexOf(animation); + if (i !== -1) { + animations.splice(i, 1); + this.animationRemoved.raiseEvent(this._model, animation); + return true; } - } else { - processMaterialProperty(object, propertyName, packetData, interval, sourceUri, entityCollection, query); } - } - function processName(entity, packet, entityCollection, sourceUri, query) { - entity.name = defaultValue(packet.name, entity.name); - } + return false; + }; - function processDescription(entity, packet, entityCollection, sourceUri, query) { - var descriptionData = packet.description; - if (defined(descriptionData)) { - processPacketData(String, entity, 'description', descriptionData, undefined, sourceUri, entityCollection, query); - } - } + /** + * Removes all animations from the collection. + * <p> + * This raises the {@link ModelAnimationCollection#animationRemoved} event for each + * animation so, for example, a UI can stay in sync. + * </p> + */ + ModelAnimationCollection.prototype.removeAll = function() { + var model = this._model; + var animations = this._scheduledAnimations; + var length = animations.length; - function processPosition(entity, packet, entityCollection, sourceUri, query) { - var positionData = packet.position; - if (defined(positionData)) { - processPositionPacketData(entity, 'position', positionData, undefined, sourceUri, entityCollection, query); - } - } + this._scheduledAnimations = []; - function processViewFrom(entity, packet, entityCollection, sourceUri, query) { - var viewFromData = packet.viewFrom; - if (defined(viewFromData)) { - processPacketData(Cartesian3, entity, 'viewFrom', viewFromData, undefined, sourceUri, entityCollection, query); + for (var i = 0; i < length; ++i) { + this.animationRemoved.raiseEvent(model, animations[i]); } - } + }; - function processOrientation(entity, packet, entityCollection, sourceUri, query) { - var orientationData = packet.orientation; - if (defined(orientationData)) { - processPacketData(Quaternion, entity, 'orientation', orientationData, undefined, sourceUri, entityCollection, query); + /** + * Determines whether this collection contains a given animation. + * + * @param {ModelAnimation} animation The animation to check for. + * @returns {Boolean} <code>true</code> if this collection contains the animation, <code>false</code> otherwise. + */ + ModelAnimationCollection.prototype.contains = function(animation) { + if (defined(animation)) { + return (this._scheduledAnimations.indexOf(animation) !== -1); } - } - function processProperties(entity, packet, entityCollection, sourceUri, query) { - var propertiesData = packet.properties; - if (defined(propertiesData)) { - if (!defined(entity.properties)) { - entity.properties = new PropertyBag(); - } - //We cannot simply call processPacketData(entity, 'properties', propertyData, undefined, sourceUri, entityCollection) - //because each property of "properties" may vary separately. - //The properties will be accessible as entity.properties.myprop.getValue(time). + return false; + }; - for (var key in propertiesData) { - if (propertiesData.hasOwnProperty(key)) { - if (!entity.properties.hasProperty(key)) { - entity.properties.addProperty(key); - } + /** + * Returns the animation in the collection at the specified index. Indices are zero-based + * and increase as animations are added. Removing an animation shifts all animations after + * it to the left, changing their indices. This function is commonly used to iterate over + * all the animations in the collection. + * + * @param {Number} index The zero-based index of the animation. + * @returns {ModelAnimation} The animation at the specified index. + * + * @example + * // Output the names of all the animations in the collection. + * var animations = model.activeAnimations; + * var length = animations.length; + * for (var i = 0; i < length; ++i) { + * console.log(animations.get(i).name); + * } + */ + ModelAnimationCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); + } + + return this._scheduledAnimations[index]; + }; - var propertyData = propertiesData[key]; - if (isArray(propertyData)) { - for (var i = 0, len = propertyData.length; i < len; i++) { - processProperty(getPropertyType(propertyData[i]), entity.properties, key, propertyData[i], undefined, sourceUri, entityCollection, query); - } - } else { - processProperty(getPropertyType(propertyData), entity.properties, key, propertyData, undefined, sourceUri, entityCollection, query); - } - } - } + function animateChannels(runtimeAnimation, localAnimationTime) { + var channelEvaluators = runtimeAnimation.channelEvaluators; + var length = channelEvaluators.length; + for (var i = 0; i < length; ++i) { + channelEvaluators[i](localAnimationTime); } } - function processArrayPacketData(object, propertyName, packetData, entityCollection) { - var references = packetData.references; - if (defined(references)) { - var properties = references.map(function(reference) { - return createReferenceProperty(entityCollection, reference); - }); + var animationsToRemove = []; - var iso8601Interval = packetData.interval; - if (defined(iso8601Interval)) { - iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); - if (!(object[propertyName] instanceof CompositePositionProperty)) { - iso8601Interval.data = new PropertyArray(properties); - var property = new CompositeProperty(); - property.intervals.addInterval(iso8601Interval); - object[propertyName] = property; - } - } else { - object[propertyName] = new PropertyArray(properties); - } - } else { - processPacketData(Array, object, propertyName, packetData, undefined, undefined, entityCollection); - } + function createAnimationRemovedFunction(modelAnimationCollection, model, animation) { + return function() { + modelAnimationCollection.animationRemoved.raiseEvent(model, animation); + }; } - function processArray(object, propertyName, packetData, entityCollection) { - if (!defined(packetData)) { - return; + /** + * @private + */ + ModelAnimationCollection.prototype.update = function(frameState) { + var scheduledAnimations = this._scheduledAnimations; + var length = scheduledAnimations.length; + + if (length === 0) { + // No animations - quick return for performance + this._previousTime = undefined; + return false; } - if (isArray(packetData)) { - for (var i = 0, length = packetData.length; i < length; ++i) { - processArrayPacketData(object, propertyName, packetData[i], entityCollection); - } - } else { - processArrayPacketData(object, propertyName, packetData, entityCollection); + if (JulianDate.equals(frameState.time, this._previousTime)) { + // Animations are currently only time-dependent so do not animate when paused or picking + return false; } - } + this._previousTime = JulianDate.clone(frameState.time, this._previousTime); - function processPositionsPacketData(object, propertyName, positionsData, entityCollection) { - if (defined(positionsData.references)) { - var properties = positionsData.references.map(function(reference) { - return createReferenceProperty(entityCollection, reference); - }); + var animationOccured = false; + var sceneTime = frameState.time; + var model = this._model; - var iso8601Interval = positionsData.interval; - if (defined(iso8601Interval)) { - iso8601Interval = TimeInterval.fromIso8601(iso8601Interval); - if (!(object[propertyName] instanceof CompositePositionProperty)) { - iso8601Interval.data = new PositionPropertyArray(properties); - var property = new CompositePositionProperty(); - property.intervals.addInterval(iso8601Interval); - object[propertyName] = property; - } - } else { - object[propertyName] = new PositionPropertyArray(properties); - } - } else { - if (defined(positionsData.cartesian)) { - positionsData.array = Cartesian3.unpackArray(positionsData.cartesian); - } else if (defined(positionsData.cartographicRadians)) { - positionsData.array = Cartesian3.fromRadiansArrayHeights(positionsData.cartographicRadians); - } else if (defined(positionsData.cartographicDegrees)) { - positionsData.array = Cartesian3.fromDegreesArrayHeights(positionsData.cartographicDegrees); + for (var i = 0; i < length; ++i) { + var scheduledAnimation = scheduledAnimations[i]; + var runtimeAnimation = scheduledAnimation._runtimeAnimation; + + if (!defined(scheduledAnimation._computedStartTime)) { + scheduledAnimation._computedStartTime = JulianDate.addSeconds(defaultValue(scheduledAnimation.startTime, sceneTime), scheduledAnimation.delay, new JulianDate()); } - if (defined(positionsData.array)) { - processPacketData(Array, object, propertyName, positionsData, undefined, undefined, entityCollection); + if (!defined(scheduledAnimation._duration)) { + scheduledAnimation._duration = runtimeAnimation.stopTime * (1.0 / scheduledAnimation.speedup); } - } - } - function processPositions(object, propertyName, positionsData, entityCollection) { - if (!defined(positionsData)) { - return; - } + var startTime = scheduledAnimation._computedStartTime; + var duration = scheduledAnimation._duration; + var stopTime = scheduledAnimation.stopTime; - if (isArray(positionsData)) { - for (var i = 0, length = positionsData.length; i < length; i++) { - processPositionsPacketData(object, propertyName, positionsData[i], entityCollection); - } - } else { - processPositionsPacketData(object, propertyName, positionsData, entityCollection); - } - } + // [0.0, 1.0] normalized local animation time + var delta = (duration !== 0.0) ? (JulianDate.secondsDifference(sceneTime, startTime) / duration) : 0.0; + var pastStartTime = (delta >= 0.0); - function processAvailability(entity, packet, entityCollection, sourceUri, query) { - var interval; - var packetData = packet.availability; - if (!defined(packetData)) { - return; - } + // Play animation if + // * we are after the start time or the animation is being repeated, and + // * before the end of the animation's duration or the animation is being repeated, and + // * we did not reach a user-provided stop time. - var intervals; - if (isArray(packetData)) { - var length = packetData.length; - for (var i = 0; i < length; i++) { - if (!defined(intervals)) { - intervals = new TimeIntervalCollection(); + var repeat = ((scheduledAnimation.loop === ModelAnimationLoop.REPEAT) || + (scheduledAnimation.loop === ModelAnimationLoop.MIRRORED_REPEAT)); + + var play = (pastStartTime || (repeat && !defined(scheduledAnimation.startTime))) && + ((delta <= 1.0) || repeat) && + (!defined(stopTime) || JulianDate.lessThanOrEquals(sceneTime, stopTime)); + + if (play) { + // STOPPED -> ANIMATING state transition? + if (scheduledAnimation._state === ModelAnimationState.STOPPED) { + scheduledAnimation._state = ModelAnimationState.ANIMATING; + if (scheduledAnimation.start.numberOfListeners > 0) { + frameState.afterRender.push(scheduledAnimation._raiseStartEvent); + } } - iso8601Scratch.iso8601 = packetData[i]; - interval = TimeInterval.fromIso8601(iso8601Scratch); - intervals.addInterval(interval); - } - } else { - iso8601Scratch.iso8601 = packetData; - interval = TimeInterval.fromIso8601(iso8601Scratch); - intervals = new TimeIntervalCollection(); - intervals.addInterval(interval); - } - entity.availability = intervals; - } - function processAlignedAxis(billboard, packetData, interval, sourceUri, entityCollection, query) { - if (!defined(packetData)) { - return; - } + // Truncate to [0.0, 1.0] for repeating animations + if (scheduledAnimation.loop === ModelAnimationLoop.REPEAT) { + delta = delta - Math.floor(delta); + } else if (scheduledAnimation.loop === ModelAnimationLoop.MIRRORED_REPEAT) { + var floor = Math.floor(delta); + var fract = delta - floor; + // When even use (1.0 - fract) to mirror repeat + delta = (floor % 2 === 1.0) ? (1.0 - fract) : fract; + } - processPacketData(UnitCartesian3, billboard, 'alignedAxis', packetData, interval, sourceUri, entityCollection, query); - } + if (scheduledAnimation.reverse) { + delta = 1.0 - delta; + } - function processBillboard(entity, packet, entityCollection, sourceUri, query) { - var billboardData = packet.billboard; - if (!defined(billboardData)) { - return; - } + var localAnimationTime = delta * duration * scheduledAnimation.speedup; + // Clamp in case floating-point roundoff goes outside the animation's first or last keyframe + localAnimationTime = CesiumMath.clamp(localAnimationTime, runtimeAnimation.startTime, runtimeAnimation.stopTime); - var interval; - var intervalString = billboardData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + animateChannels(runtimeAnimation, localAnimationTime); - var billboard = entity.billboard; - if (!defined(billboard)) { - entity.billboard = billboard = new BillboardGraphics(); - } + if (scheduledAnimation.update.numberOfListeners > 0) { + scheduledAnimation._updateEventTime = localAnimationTime; + frameState.afterRender.push(scheduledAnimation._raiseUpdateEvent); + } + animationOccured = true; + } else if (pastStartTime && (scheduledAnimation._state === ModelAnimationState.ANIMATING)) { + // ANIMATING -> STOPPED state transition? + scheduledAnimation._state = ModelAnimationState.STOPPED; + if (scheduledAnimation.stop.numberOfListeners > 0) { + frameState.afterRender.push(scheduledAnimation._raiseStopEvent); + } - processPacketData(Boolean, billboard, 'show', billboardData.show, interval, sourceUri, entityCollection, query); - processPacketData(Image, billboard, 'image', billboardData.image, interval, sourceUri, entityCollection, query); - processPacketData(Number, billboard, 'scale', billboardData.scale, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian2, billboard, 'pixelOffset', billboardData.pixelOffset, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian3, billboard, 'eyeOffset', billboardData.eyeOffset, interval, sourceUri, entityCollection, query); - processPacketData(HorizontalOrigin, billboard, 'horizontalOrigin', billboardData.horizontalOrigin, interval, sourceUri, entityCollection, query); - processPacketData(VerticalOrigin, billboard, 'verticalOrigin', billboardData.verticalOrigin, interval, sourceUri, entityCollection, query); - processPacketData(HeightReference, billboard, 'heightReference', billboardData.heightReference, interval, sourceUri, entityCollection, query); - processPacketData(Color, billboard, 'color', billboardData.color, interval, sourceUri, entityCollection, query); - processPacketData(Rotation, billboard, 'rotation', billboardData.rotation, interval, sourceUri, entityCollection, query); - processAlignedAxis(billboard, billboardData.alignedAxis, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, billboard, 'sizeInMeters', billboardData.sizeInMeters, interval, sourceUri, entityCollection, query); - processPacketData(Number, billboard, 'width', billboardData.width, interval, sourceUri, entityCollection, query); - processPacketData(Number, billboard, 'height', billboardData.height, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, billboard, 'scaleByDistance', billboardData.scaleByDistance, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, billboard, 'translucencyByDistance', billboardData.translucencyByDistance, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, billboard, 'pixelOffsetScaleByDistance', billboardData.pixelOffsetScaleByDistance, interval, sourceUri, entityCollection, query); - processPacketData(BoundingRectangle, billboard, 'imageSubRegion', billboardData.imageSubRegion, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, billboard, 'distanceDisplayCondition', billboardData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - processPacketData(Number, billboard, 'disableDepthTestDistance', billboardData.disableDepthTestDistance, interval, sourceUri, entityCollection, query); - } - - function processBox(entity, packet, entityCollection, sourceUri, query) { - var boxData = packet.box; - if (!defined(boxData)) { - return; + if (scheduledAnimation.removeOnStop) { + animationsToRemove.push(scheduledAnimation); + } + } } - var interval; - var intervalString = boxData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); + // Remove animations that stopped + length = animationsToRemove.length; + for (var j = 0; j < length; ++j) { + var animationToRemove = animationsToRemove[j]; + scheduledAnimations.splice(scheduledAnimations.indexOf(animationToRemove), 1); + frameState.afterRender.push(createAnimationRemovedFunction(this, model, animationToRemove)); } + animationsToRemove.length = 0; - var box = entity.box; - if (!defined(box)) { - entity.box = box = new BoxGraphics(); - } + return animationOccured; + }; - processPacketData(Boolean, box, 'show', boxData.show, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian3, box, 'dimensions', boxData.dimensions, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, box, 'fill', boxData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(box, 'material', boxData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, box, 'outline', boxData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, box, 'outlineColor', boxData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, box, 'outlineWidth', boxData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, box, 'shadows', boxData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, box, 'distanceDisplayCondition', boxData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } + return ModelAnimationCollection; +}); - function processCorridor(entity, packet, entityCollection, sourceUri, query) { - var corridorData = packet.corridor; - if (!defined(corridorData)) { - return; - } +define('Scene/ModelLoadResources',[ + '../Core/Queue' + ], function( + Queue) { + 'use strict'; - var interval; - var intervalString = corridorData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + /** + * @private + */ + function ModelLoadResources() { + this.vertexBuffersToCreate = new Queue(); + this.indexBuffersToCreate = new Queue(); + this.buffers = {}; + this.pendingBufferLoads = 0; - var corridor = entity.corridor; - if (!defined(corridor)) { - entity.corridor = corridor = new CorridorGraphics(); - } + this.programsToCreate = new Queue(); + this.shaders = {}; + this.pendingShaderLoads = 0; - processPacketData(Boolean, corridor, 'show', corridorData.show, interval, sourceUri, entityCollection, query); - processPositions(corridor, 'positions', corridorData.positions, entityCollection); - processPacketData(Number, corridor, 'width', corridorData.width, interval, sourceUri, entityCollection, query); - processPacketData(Number, corridor, 'height', corridorData.height, interval, sourceUri, entityCollection, query); - processPacketData(Number, corridor, 'extrudedHeight', corridorData.extrudedHeight, interval, sourceUri, entityCollection, query); - processPacketData(CornerType, corridor, 'cornerType', corridorData.cornerType, interval, sourceUri, entityCollection, query); - processPacketData(Number, corridor, 'granularity', corridorData.granularity, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, corridor, 'fill', corridorData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(corridor, 'material', corridorData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, corridor, 'outline', corridorData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, corridor, 'outlineColor', corridorData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, corridor, 'outlineWidth', corridorData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, corridor, 'shadows', corridorData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, corridor, 'distanceDisplayCondition', corridorData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } - - function processCylinder(entity, packet, entityCollection, sourceUri, query) { - var cylinderData = packet.cylinder; - if (!defined(cylinderData)) { - return; - } + this.texturesToCreate = new Queue(); + this.pendingTextureLoads = 0; - var interval; - var intervalString = cylinderData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + this.texturesToCreateFromBufferView = new Queue(); + this.pendingBufferViewToImage = 0; - var cylinder = entity.cylinder; - if (!defined(cylinder)) { - entity.cylinder = cylinder = new CylinderGraphics(); - } + this.createSamplers = true; + this.createSkins = true; + this.createRuntimeAnimations = true; + this.createVertexArrays = true; + this.createRenderStates = true; + this.createUniformMaps = true; + this.createRuntimeNodes = true; - processPacketData(Boolean, cylinder, 'show', cylinderData.show, interval, sourceUri, entityCollection, query); - processPacketData(Number, cylinder, 'length', cylinderData.length, interval, sourceUri, entityCollection, query); - processPacketData(Number, cylinder, 'topRadius', cylinderData.topRadius, interval, sourceUri, entityCollection, query); - processPacketData(Number, cylinder, 'bottomRadius', cylinderData.bottomRadius, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, cylinder, 'fill', cylinderData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(cylinder, 'material', cylinderData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, cylinder, 'outline', cylinderData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, cylinder, 'outlineColor', cylinderData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, cylinder, 'outlineWidth', cylinderData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(Number, cylinder, 'numberOfVerticalLines', cylinderData.numberOfVerticalLines, interval, sourceUri, entityCollection, query); - processPacketData(Number, cylinder, 'slices', cylinderData.slices, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, cylinder, 'shadows', cylinderData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, cylinder, 'distanceDisplayCondition', cylinderData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); + this.skinnedNodesIds = []; } - function processDocument(packet, dataSource) { - var version = packet.version; - if (defined(version)) { - if (typeof version === 'string') { - var tokens = version.split('.'); - if (tokens.length === 2) { - if (tokens[0] !== '1') { - throw new RuntimeError('Cesium only supports CZML version 1.'); - } - dataSource._version = version; - } - } - } + /** + * This function differs from the normal subarray function + * because it takes offset and length, rather than begin and end. + */ + function getSubarray(array, offset, length) { + return array.subarray(offset, offset + length); + } - if (!defined(dataSource._version)) { - throw new RuntimeError('CZML version information invalid. It is expected to be a property on the document object in the <Major>.<Minor> version format.'); - } + ModelLoadResources.prototype.getBuffer = function(bufferView) { + return getSubarray(this.buffers[bufferView.buffer], bufferView.byteOffset, bufferView.byteLength); + }; - var documentPacket = dataSource._documentPacket; + ModelLoadResources.prototype.finishedPendingBufferLoads = function() { + return (this.pendingBufferLoads === 0); + }; - if (defined(packet.name)) { - documentPacket.name = packet.name; - } + ModelLoadResources.prototype.finishedBuffersCreation = function() { + return ((this.pendingBufferLoads === 0) && + (this.vertexBuffersToCreate.length === 0) && + (this.indexBuffersToCreate.length === 0)); + }; - var clockPacket = packet.clock; - if (defined(clockPacket)) { - var clock = documentPacket.clock; - if (!defined(clock)) { - documentPacket.clock = { - interval : clockPacket.interval, - currentTime : clockPacket.currentTime, - range : clockPacket.range, - step : clockPacket.step, - multiplier : clockPacket.multiplier - }; - } else { - clock.interval = defaultValue(clockPacket.interval, clock.interval); - clock.currentTime = defaultValue(clockPacket.currentTime, clock.currentTime); - clock.range = defaultValue(clockPacket.range, clock.range); - clock.step = defaultValue(clockPacket.step, clock.step); - clock.multiplier = defaultValue(clockPacket.multiplier, clock.multiplier); - } - } - } + ModelLoadResources.prototype.finishedProgramCreation = function() { + return ((this.pendingShaderLoads === 0) && (this.programsToCreate.length === 0)); + }; - function processEllipse(entity, packet, entityCollection, sourceUri, query) { - var ellipseData = packet.ellipse; - if (!defined(ellipseData)) { - return; - } + ModelLoadResources.prototype.finishedTextureCreation = function() { + var finishedPendingLoads = (this.pendingTextureLoads === 0); + var finishedResourceCreation = + (this.texturesToCreate.length === 0) && + (this.texturesToCreateFromBufferView.length === 0); - var interval; - var intervalString = ellipseData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + return finishedPendingLoads && finishedResourceCreation; + }; - var ellipse = entity.ellipse; - if (!defined(ellipse)) { - entity.ellipse = ellipse = new EllipseGraphics(); - } + ModelLoadResources.prototype.finishedEverythingButTextureCreation = function() { + var finishedPendingLoads = + (this.pendingBufferLoads === 0) && + (this.pendingShaderLoads === 0); + var finishedResourceCreation = + (this.vertexBuffersToCreate.length === 0) && + (this.indexBuffersToCreate.length === 0) && + (this.programsToCreate.length === 0) && + (this.pendingBufferViewToImage === 0); - processPacketData(Boolean, ellipse, 'show', ellipseData.show, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'semiMajorAxis', ellipseData.semiMajorAxis, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'semiMinorAxis', ellipseData.semiMinorAxis, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'height', ellipseData.height, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'extrudedHeight', ellipseData.extrudedHeight, interval, sourceUri, entityCollection, query); - processPacketData(Rotation, ellipse, 'rotation', ellipseData.rotation, interval, sourceUri, entityCollection, query); - processPacketData(Rotation, ellipse, 'stRotation', ellipseData.stRotation, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'granularity', ellipseData.granularity, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, ellipse, 'fill', ellipseData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(ellipse, 'material', ellipseData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, ellipse, 'outline', ellipseData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, ellipse, 'outlineColor', ellipseData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'outlineWidth', ellipseData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipse, 'numberOfVerticalLines', ellipseData.numberOfVerticalLines, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, ellipse, 'shadows', ellipseData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, ellipse, 'distanceDisplayCondition', ellipseData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } - - function processEllipsoid(entity, packet, entityCollection, sourceUri, query) { - var ellipsoidData = packet.ellipsoid; - if (!defined(ellipsoidData)) { - return; - } + return finishedPendingLoads && finishedResourceCreation; + }; - var interval; - var intervalString = ellipsoidData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + ModelLoadResources.prototype.finished = function() { + return this.finishedTextureCreation() && this.finishedEverythingButTextureCreation(); + }; - var ellipsoid = entity.ellipsoid; - if (!defined(ellipsoid)) { - entity.ellipsoid = ellipsoid = new EllipsoidGraphics(); - } + return ModelLoadResources; +}); + +define('Scene/ModelMaterial',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError' + ], function( + defined, + defineProperties, + DeveloperError) { + 'use strict'; - processPacketData(Boolean, ellipsoid, 'show', ellipsoidData.show, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian3, ellipsoid, 'radii', ellipsoidData.radii, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, ellipsoid, 'fill', ellipsoidData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(ellipsoid, 'material', ellipsoidData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, ellipsoid, 'outline', ellipsoidData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, ellipsoid, 'outlineColor', ellipsoidData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipsoid, 'outlineWidth', ellipsoidData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipsoid, 'stackPartitions', ellipsoidData.stackPartitions, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipsoid, 'slicePartitions', ellipsoidData.slicePartitions, interval, sourceUri, entityCollection, query); - processPacketData(Number, ellipsoid, 'subdivisions', ellipsoidData.subdivisions, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, ellipsoid, 'shadows', ellipsoidData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, ellipsoid, 'distanceDisplayCondition', ellipsoidData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); + /** + * A model's material with modifiable parameters. A glTF material + * contains parameters defined by the material's technique with values + * defined by the technique and potentially overridden by the material. + * This class allows changing these values at runtime. + * <p> + * Use {@link Model#getMaterial} to create an instance. + * </p> + * + * @alias ModelMaterial + * @internalConstructor + * + * @see Model#getMaterial + */ + function ModelMaterial(model, material, id) { + this._name = material.name; + this._id = id; + this._uniformMap = model._uniformMaps[id]; } - function processLabel(entity, packet, entityCollection, sourceUri, query) { - var labelData = packet.label; - if (!defined(labelData)) { - return; - } + defineProperties(ModelMaterial.prototype, { + /** + * The value of the <code>name</code> property of this material. This is the + * name assigned by the artist when the asset is created. This can be + * different than the name of the material property ({@link ModelMaterial#id}), + * which is internal to glTF. + * + * @memberof ModelMaterial.prototype + * + * @type {String} + * @readonly + */ + name : { + get : function() { + return this._name; + } + }, - var interval; - var intervalString = labelData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); + /** + * The name of the glTF JSON property for this material. This is guaranteed + * to be unique among all materials. It may not match the material's <code> + * name</code> property (@link ModelMaterial#name), which is assigned by + * the artist when the asset is created. + * + * @memberof ModelMaterial.prototype + * + * @type {String} + * @readonly + */ + id : { + get : function() { + return this._id; + } } + }); - var label = entity.label; - if (!defined(label)) { - entity.label = label = new LabelGraphics(); + /** + * Assigns a value to a material parameter. The type for <code>value</code> + * depends on the glTF type of the parameter. It will be a floating-point + * number, Cartesian, or matrix. + * + * @param {String} name The name of the parameter. + * @param {Object} [value] The value to assign to the parameter. + * + * @exception {DeveloperError} name must match a parameter name in the material's technique that is targetable and not optimized out. + * + * @example + * material.setValue('diffuse', new Cesium.Cartesian4(1.0, 0.0, 0.0, 1.0)); // vec4 + * material.setValue('shininess', 256.0); // scalar + */ + ModelMaterial.prototype.setValue = function(name, value) { + if (!defined(name)) { + throw new DeveloperError('name is required.'); } + + var v = this._uniformMap.values[name]; - processPacketData(Boolean, label, 'show', labelData.show, interval, sourceUri, entityCollection, query); - processPacketData(String, label, 'text', labelData.text, interval, sourceUri, entityCollection, query); - processPacketData(String, label, 'font', labelData.font, interval, sourceUri, entityCollection, query); - processPacketData(LabelStyle, label, 'style', labelData.style, interval, sourceUri, entityCollection, query); - processPacketData(Number, label, 'scale', labelData.scale, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, label, 'showBackground', labelData.showBackground, interval, sourceUri, entityCollection, query); - processPacketData(Color, label, 'backgroundColor', labelData.backgroundColor, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian2, label, 'backgroundPadding', labelData.backgroundPadding, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian2, label, 'pixelOffset', labelData.pixelOffset, interval, sourceUri, entityCollection, query); - processPacketData(Cartesian3, label, 'eyeOffset', labelData.eyeOffset, interval, sourceUri, entityCollection, query); - processPacketData(HorizontalOrigin, label, 'horizontalOrigin', labelData.horizontalOrigin, interval, sourceUri, entityCollection, query); - processPacketData(VerticalOrigin, label, 'verticalOrigin', labelData.verticalOrigin, interval, sourceUri, entityCollection, query); - processPacketData(HeightReference, label, 'heightReference', labelData.heightReference, interval, sourceUri, entityCollection, query); - processPacketData(Color, label, 'fillColor', labelData.fillColor, interval, sourceUri, entityCollection, query); - processPacketData(Color, label, 'outlineColor', labelData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, label, 'outlineWidth', labelData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, label, 'translucencyByDistance', labelData.translucencyByDistance, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, label, 'pixelOffsetScaleByDistance', labelData.pixelOffsetScaleByDistance, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, label, 'scaleByDistance', labelData.scaleByDistance, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, label, 'distanceDisplayCondition', labelData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - processPacketData(Number, label, 'disableDepthTestDistance', labelData.disableDepthTestDistance, interval, sourceUri, entityCollection, query); - } - - function processModel(entity, packet, entityCollection, sourceUri, query) { - var modelData = packet.model; - if (!defined(modelData)) { - return; + if (!defined(v)) { + throw new DeveloperError('name must match a parameter name in the material\'s technique that is targetable and not optimized out.'); } + + v.value = v.clone(value, v.value); + }; - var interval; - var intervalString = modelData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); + /** + * Returns the value of the parameter with the given <code>name</code>. The type of the + * returned object depends on the glTF type of the parameter. It will be a floating-point + * number, Cartesian, or matrix. + * + * @param {String} name The name of the parameter. + * @returns {Object} The value of the parameter or <code>undefined</code> if the parameter does not exist. + */ + ModelMaterial.prototype.getValue = function(name) { + if (!defined(name)) { + throw new DeveloperError('name is required.'); } + + var v = this._uniformMap.values[name]; - var model = entity.model; - if (!defined(model)) { - entity.model = model = new ModelGraphics(); + if (!defined(v)) { + return undefined; } - processPacketData(Boolean, model, 'show', modelData.show, interval, sourceUri, entityCollection, query); - processPacketData(Uri, model, 'uri', modelData.gltf, interval, sourceUri, entityCollection, query); - processPacketData(Number, model, 'scale', modelData.scale, interval, sourceUri, entityCollection, query); - processPacketData(Number, model, 'minimumPixelSize', modelData.minimumPixelSize, interval, sourceUri, entityCollection, query); - processPacketData(Number, model, 'maximumScale', modelData.maximumScale, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, model, 'incrementallyLoadTextures', modelData.incrementallyLoadTextures, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, model, 'runAnimations', modelData.runAnimations, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, model, 'clampAnimations', modelData.clampAnimations, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, model, 'shadows', modelData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(HeightReference, model, 'heightReference', modelData.heightReference, interval, sourceUri, entityCollection, query); - processPacketData(Color, model, 'silhouetteColor', modelData.silhouetteColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, model, 'silhouetteSize', modelData.silhouetteSize, interval, sourceUri, entityCollection, query); - processPacketData(Color, model, 'color', modelData.color, interval, sourceUri, entityCollection, query); - processPacketData(ColorBlendMode, model, 'colorBlendMode', modelData.colorBlendMode, interval, sourceUri, entityCollection, query); - processPacketData(Number, model, 'colorBlendAmount', modelData.colorBlendAmount, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, model, 'distanceDisplayCondition', modelData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); + return v.value; + }; - var nodeTransformationsData = modelData.nodeTransformations; - if (defined(nodeTransformationsData)) { - if (isArray(nodeTransformationsData)) { - for (var i = 0, len = nodeTransformationsData.length; i < len; i++) { - processNodeTransformations(model, nodeTransformationsData[i], interval, sourceUri, entityCollection, query); - } - } else { - processNodeTransformations(model, nodeTransformationsData, interval, sourceUri, entityCollection, query); - } + return ModelMaterial; +}); + +define('Scene/ModelMesh',[ + '../Core/defineProperties' + ], function( + defineProperties) { + 'use strict'; + + /** + * A model's mesh and its materials. + * <p> + * Use {@link Model#getMesh} to create an instance. + * </p> + * + * @alias ModelMesh + * @internalConstructor + * + * @see Model#getMesh + */ + function ModelMesh(mesh, runtimeMaterialsById, id) { + var materials = []; + var primitives = mesh.primitives; + var length = primitives.length; + for (var i = 0; i < length; ++i) { + var p = primitives[i]; + materials[i] = runtimeMaterialsById[p.material]; } + + this._name = mesh.name; + this._materials = materials; + this._id = id; } - function processNodeTransformations(model, nodeTransformationsData, constrainedInterval, sourceUri, entityCollection, query) { - var combinedInterval; - var packetInterval = nodeTransformationsData.interval; - if (defined(packetInterval)) { - iso8601Scratch.iso8601 = packetInterval; - combinedInterval = TimeInterval.fromIso8601(iso8601Scratch); - if (defined(constrainedInterval)) { - combinedInterval = TimeInterval.intersect(combinedInterval, constrainedInterval, scratchTimeInterval); + defineProperties(ModelMesh.prototype, { + /** + * The value of the <code>name</code> property of this mesh. This is the + * name assigned by the artist when the asset is created. This can be + * different than the name of the mesh property ({@link ModelMesh#id}), + * which is internal to glTF. + * + * @memberof ModelMesh.prototype + * + * @type {String} + * @readonly + */ + name : { + get : function() { + return this._name; } - } else if (defined(constrainedInterval)) { - combinedInterval = constrainedInterval; - } + }, - var nodeTransformations = model.nodeTransformations; - var nodeNames = Object.keys(nodeTransformationsData); - for (var i = 0, len = nodeNames.length; i < len; ++i) { - var nodeName = nodeNames[i]; + /** + * The name of the glTF JSON property for this mesh. This is guaranteed + * to be unique among all meshes. It may not match the mesh's <code> + * name</code> property (@link ModelMesh#name), which is assigned by + * the artist when the asset is created. + * + * @memberof ModelMesh.prototype + * + * @type {String} + * @readonly + */ + id : { + get : function() { + return this._id; + } + }, - if (nodeName === 'interval') { - continue; + /** + * An array of {@link ModelMaterial} instances indexed by the mesh's + * primitive indices. + * + * @memberof ModelMesh.prototype + * + * @type {ModelMaterial[]} + * @readonly + */ + materials : { + get : function() { + return this._materials; } + } + }); - var nodeTransformationData = nodeTransformationsData[nodeName]; + return ModelMesh; +}); - if (!defined(nodeTransformationData)) { - continue; - } +define('Scene/ModelNode',[ + '../Core/defineProperties', + '../Core/Matrix4' + ], function( + defineProperties, + Matrix4) { + 'use strict'; - if (!defined(nodeTransformations)) { - model.nodeTransformations = nodeTransformations = new PropertyBag(); + /** + * A model node with a transform for user-defined animations. A glTF asset can + * contain animations that target a node's transform. This class allows + * changing a node's transform externally so animation can be driven by another + * source, not just an animation in the glTF asset. + * <p> + * Use {@link Model#getNode} to create an instance. + * </p> + * + * @alias ModelNode + * @internalConstructor + * + * + * @example + * var node = model.getNode('LOD3sp'); + * node.matrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix); + * + * @see Model#getNode + */ + function ModelNode(model, node, runtimeNode, id, matrix) { + this._model = model; + this._runtimeNode = runtimeNode; + this._name = node.name; + this._id = id; + + /** + * @private + */ + this.useMatrix = false; + + this._show = true; + this._matrix = Matrix4.clone(matrix); + } + + defineProperties(ModelNode.prototype, { + /** + * The value of the <code>name</code> property of this node. This is the + * name assigned by the artist when the asset is created. This can be + * different than the name of the node property ({@link ModelNode#id}), + * which is internal to glTF. + * + * @memberof ModelNode.prototype + * + * @type {String} + * @readonly + */ + name : { + get : function() { + return this._name; } + }, - if (!nodeTransformations.hasProperty(nodeName)) { - nodeTransformations.addProperty(nodeName); + /** + * The name of the glTF JSON property for this node. This is guaranteed + * to be unique among all nodes. It may not match the node's <code> + * name</code> property (@link ModelNode#name), which is assigned by + * the artist when the asset is created. + * + * @memberof ModelNode.prototype + * + * @type {String} + * @readonly + */ + id : { + get : function() { + return this._id; } + }, - var nodeTransformation = nodeTransformations[nodeName]; - if (!defined(nodeTransformation)) { - nodeTransformations[nodeName] = nodeTransformation = new NodeTransformationProperty(); + /** + * Determines if this node and its children will be shown. + * + * @memberof ModelNode.prototype + * @type {Boolean} + * + * @default true + */ + show : { + get : function() { + return this._show; + }, + set : function(value) { + if (this._show !== value) { + this._show = value; + this._model._perNodeShowDirty = true; + } } + }, - processPacketData(Cartesian3, nodeTransformation, 'translation', nodeTransformationData.translation, combinedInterval, sourceUri, entityCollection, query); - processPacketData(Quaternion, nodeTransformation, 'rotation', nodeTransformationData.rotation, combinedInterval, sourceUri, entityCollection, query); - processPacketData(Cartesian3, nodeTransformation, 'scale', nodeTransformationData.scale, combinedInterval, sourceUri, entityCollection, query); - } - } + /** + * The node's 4x4 matrix transform from its local coordinates to + * its parent's. + * <p> + * For changes to take effect, this property must be assigned to; + * setting individual elements of the matrix will not work. + * </p> + * + * @memberof ModelNode.prototype + * @type {Matrix4} + */ + matrix : { + get : function() { + return this._matrix; + }, + set : function(value) { + this._matrix = Matrix4.clone(value, this._matrix); + this.useMatrix = true; - function processPath(entity, packet, entityCollection, sourceUri, query) { - var pathData = packet.path; - if (!defined(pathData)) { - return; + var model = this._model; + model._cesiumAnimationsDirty = true; + this._runtimeNode.dirtyNumber = model._maxDirtyNumber; + } } + }); - var interval; - var intervalString = pathData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + /** + * @private + */ + ModelNode.prototype.setMatrix = function(matrix) { + // Update matrix but do not set the dirty flag since this is used internally + // to keep the matrix in-sync during a glTF animation. + Matrix4.clone(matrix, this._matrix); + }; - var path = entity.path; - if (!defined(path)) { - entity.path = path = new PathGraphics(); - } + return ModelNode; +}); - processPacketData(Boolean, path, 'show', pathData.show, interval, sourceUri, entityCollection, query); - processPacketData(Number, path, 'width', pathData.width, interval, sourceUri, entityCollection, query); - processPacketData(Number, path, 'resolution', pathData.resolution, interval, sourceUri, entityCollection, query); - processPacketData(Number, path, 'leadTime', pathData.leadTime, interval, sourceUri, entityCollection, query); - processPacketData(Number, path, 'trailTime', pathData.trailTime, interval, sourceUri, entityCollection, query); - processMaterialPacketData(path, 'material', pathData.material, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, path, 'distanceDisplayCondition', pathData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } +define('Scene/ModelUtility',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/defined', + '../Core/defineProperties', + '../Core/Matrix2', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/Quaternion', + '../Core/RuntimeError', + '../Core/WebGLConstants', + '../Renderer/ShaderSource', + './AttributeType' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + defined, + defineProperties, + Matrix2, + Matrix3, + Matrix4, + Quaternion, + RuntimeError, + WebGLConstants, + ShaderSource, + AttributeType) { + 'use strict'; - function processPoint(entity, packet, entityCollection, sourceUri, query) { - var pointData = packet.point; - if (!defined(pointData)) { - return; + /** + * @private + */ + var ModelUtility = {}; + + ModelUtility.getAccessorMinMax = function(gltf, accessorId) { + var accessor = gltf.accessors[accessorId]; + var extensions = accessor.extensions; + var accessorMin = accessor.min; + var accessorMax = accessor.max; + // If this accessor is quantized, we should use the decoded min and max + if (defined(extensions)) { + var quantizedAttributes = extensions.WEB3D_quantized_attributes; + if (defined(quantizedAttributes)) { + accessorMin = quantizedAttributes.decodedMin; + accessorMax = quantizedAttributes.decodedMax; + } } + return { + min : accessorMin, + max : accessorMax + }; + }; - var interval; - var intervalString = pointData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); + ModelUtility.getAttributeOrUniformBySemantic = function(gltf, semantic, programId) { + var techniques = gltf.techniques; + var parameter; + for (var techniqueName in techniques) { + if (techniques.hasOwnProperty(techniqueName)) { + var technique = techniques[techniqueName]; + if (defined(programId) && (technique.program !== programId)) { + continue; + } + var parameters = technique.parameters; + var attributes = technique.attributes; + var uniforms = technique.uniforms; + for (var attributeName in attributes) { + if (attributes.hasOwnProperty(attributeName)) { + parameter = parameters[attributes[attributeName]]; + if (defined(parameter) && parameter.semantic === semantic) { + return attributeName; + } + } + } + for (var uniformName in uniforms) { + if (uniforms.hasOwnProperty(uniformName)) { + parameter = parameters[uniforms[uniformName]]; + if (defined(parameter) && parameter.semantic === semantic) { + return uniformName; + } + } + } + } } + return undefined; + }; - var point = entity.point; - if (!defined(point)) { - entity.point = point = new PointGraphics(); + ModelUtility.getDiffuseAttributeOrUniform = function(gltf, programId) { + var diffuseUniformName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'COLOR_0', programId); + if (!defined(diffuseUniformName)) { + diffuseUniformName = ModelUtility.getAttributeOrUniformBySemantic(gltf, '_3DTILESDIFFUSE', programId); } + return diffuseUniformName; + }; - processPacketData(Boolean, point, 'show', pointData.show, interval, sourceUri, entityCollection, query); - processPacketData(Number, point, 'pixelSize', pointData.pixelSize, interval, sourceUri, entityCollection, query); - processPacketData(HeightReference, point, 'heightReference', pointData.heightReference, interval, sourceUri, entityCollection, query); - processPacketData(Color, point, 'color', pointData.color, interval, sourceUri, entityCollection, query); - processPacketData(Color, point, 'outlineColor', pointData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, point, 'outlineWidth', pointData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, point, 'scaleByDistance', pointData.scaleByDistance, interval, sourceUri, entityCollection, query); - processPacketData(NearFarScalar, point, 'translucencyByDistance', pointData.translucencyByDistance, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, point, 'distanceDisplayCondition', pointData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - processPacketData(Number, point, 'disableDepthTestDistance', pointData.disableDepthTestDistance, interval, sourceUri, entityCollection, query); - } + var nodeTranslationScratch = new Cartesian3(); + var nodeQuaternionScratch = new Quaternion(); + var nodeScaleScratch = new Cartesian3(); - function processPolygon(entity, packet, entityCollection, sourceUri, query) { - var polygonData = packet.polygon; - if (!defined(polygonData)) { - return; + ModelUtility.getTransform = function(node, result) { + if (defined(node.matrix)) { + return Matrix4.fromColumnMajorArray(node.matrix, result); } - var interval; - var intervalString = polygonData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + return Matrix4.fromTranslationQuaternionRotationScale( + Cartesian3.fromArray(node.translation, 0, nodeTranslationScratch), + Quaternion.unpack(node.rotation, 0, nodeQuaternionScratch), + Cartesian3.fromArray(node.scale, 0, nodeScaleScratch), + result); + }; - var polygon = entity.polygon; - if (!defined(polygon)) { - entity.polygon = polygon = new PolygonGraphics(); - } + ModelUtility.getUsedExtensions = function(gltf) { + var extensionsUsed = gltf.extensionsUsed; + var cachedExtensionsUsed = {}; - processPacketData(Boolean, polygon, 'show', polygonData.show, interval, sourceUri, entityCollection, query); - processPositions(polygon, 'hierarchy', polygonData.positions, entityCollection); - processPacketData(Number, polygon, 'height', polygonData.height, interval, sourceUri, entityCollection, query); - processPacketData(Number, polygon, 'extrudedHeight', polygonData.extrudedHeight, interval, sourceUri, entityCollection, query); - processPacketData(Rotation, polygon, 'stRotation', polygonData.stRotation, interval, sourceUri, entityCollection, query); - processPacketData(Number, polygon, 'granularity', polygonData.granularity, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, polygon, 'fill', polygonData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(polygon, 'material', polygonData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, polygon, 'outline', polygonData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, polygon, 'outlineColor', polygonData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, polygon, 'outlineWidth', polygonData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, polygon, 'perPositionHeight', polygonData.perPositionHeight, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, polygon, 'closeTop', polygonData.closeTop, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, polygon, 'closeBottom', polygonData.closeBottom, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, polygon, 'shadows', polygonData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, polygon, 'distanceDisplayCondition', polygonData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } - - function processPolyline(entity, packet, entityCollection, sourceUri, query) { - var polylineData = packet.polyline; - if (!defined(polylineData)) { - return; + if (defined(extensionsUsed)) { + var extensionsUsedLength = extensionsUsed.length; + for (var i = 0; i < extensionsUsedLength; i++) { + var extension = extensionsUsed[i]; + cachedExtensionsUsed[extension] = true; + } } + return cachedExtensionsUsed; + }; - var interval; - var intervalString = polylineData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); - } + ModelUtility.getRequiredExtensions = function(gltf) { + var extensionsRequired = gltf.extensionsRequired; + var cachedExtensionsRequired = {}; - var polyline = entity.polyline; - if (!defined(polyline)) { - entity.polyline = polyline = new PolylineGraphics(); + if (defined(extensionsRequired)) { + var extensionsRequiredLength = extensionsRequired.length; + for (var i = 0; i < extensionsRequiredLength; i++) { + var extension = extensionsRequired[i]; + cachedExtensionsRequired[extension] = true; + } } - processPacketData(Boolean, polyline, 'show', polylineData.show, interval, sourceUri, entityCollection, query); - processPositions(polyline, 'positions', polylineData.positions, entityCollection); - processPacketData(Number, polyline, 'width', polylineData.width, interval, sourceUri, entityCollection, query); - processPacketData(Number, polyline, 'granularity', polylineData.granularity, interval, sourceUri, entityCollection, query); - processMaterialPacketData(polyline, 'material', polylineData.material, interval, sourceUri, entityCollection, query); - processMaterialPacketData(polyline, 'depthFailMaterial', polylineData.depthFailMaterial, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, polyline, 'followSurface', polylineData.followSurface, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, polyline, 'shadows', polylineData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, polyline, 'distanceDisplayCondition', polylineData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } + return cachedExtensionsRequired; + }; - function processRectangle(entity, packet, entityCollection, sourceUri, query) { - var rectangleData = packet.rectangle; - if (!defined(rectangleData)) { - return; + ModelUtility.checkSupportedExtensions = function(extensionsRequired) { + for (var extension in extensionsRequired) { + if (extensionsRequired.hasOwnProperty(extension)) { + if (extension !== 'CESIUM_RTC' && + extension !== 'KHR_technique_webgl' && + extension !== 'KHR_binary_glTF' && + extension !== 'KHR_materials_common' && + extension !== 'WEB3D_quantized_attributes') { + throw new RuntimeError('Unsupported glTF Extension: ' + extension); + } + } } + }; - var interval; - var intervalString = rectangleData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); + ModelUtility.checkSupportedGlExtensions = function(extensionsUsed, context) { + if (defined(extensionsUsed)) { + var glExtensionsUsedLength = extensionsUsed.length; + for (var i = 0; i < glExtensionsUsedLength; i++) { + var extension = extensionsUsed[i]; + if (extension !== 'OES_element_index_uint') { + throw new RuntimeError('Unsupported WebGL Extension: ' + extension); + } else if (!context.elementIndexUint) { + throw new RuntimeError('OES_element_index_uint WebGL extension is not enabled.'); + } + } } + }; - var rectangle = entity.rectangle; - if (!defined(rectangle)) { - entity.rectangle = rectangle = new RectangleGraphics(); - } + function replaceAllButFirstInString(string, find, replace) { + var index = string.indexOf(find); + return string.replace(new RegExp(find, 'g'), function(match, offset) { + return index === offset ? match : replace; + }); + } - processPacketData(Boolean, rectangle, 'show', rectangleData.show, interval, sourceUri, entityCollection, query); - processPacketData(Rectangle, rectangle, 'coordinates', rectangleData.coordinates, interval, sourceUri, entityCollection, query); - processPacketData(Number, rectangle, 'height', rectangleData.height, interval, sourceUri, entityCollection, query); - processPacketData(Number, rectangle, 'extrudedHeight', rectangleData.extrudedHeight, interval, sourceUri, entityCollection, query); - processPacketData(Rotation, rectangle, 'rotation', rectangleData.rotation, interval, sourceUri, entityCollection, query); - processPacketData(Rotation, rectangle, 'stRotation', rectangleData.stRotation, interval, sourceUri, entityCollection, query); - processPacketData(Number, rectangle, 'granularity', rectangleData.granularity, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, rectangle, 'fill', rectangleData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(rectangle, 'material', rectangleData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, rectangle, 'outline', rectangleData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, rectangle, 'outlineColor', rectangleData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, rectangle, 'outlineWidth', rectangleData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, rectangle, 'closeTop', rectangleData.closeTop, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, rectangle, 'closeBottom', rectangleData.closeBottom, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, rectangle, 'shadows', rectangleData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, rectangle, 'distanceDisplayCondition', rectangleData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } - - function processWall(entity, packet, entityCollection, sourceUri, query) { - var wallData = packet.wall; - if (!defined(wallData)) { - return; + function getQuantizedAttributes(gltf, accessorId) { + var accessor = gltf.accessors[accessorId]; + var extensions = accessor.extensions; + if (defined(extensions)) { + return extensions.WEB3D_quantized_attributes; } + return undefined; + } - var interval; - var intervalString = wallData.interval; - if (defined(intervalString)) { - iso8601Scratch.iso8601 = intervalString; - interval = TimeInterval.fromIso8601(iso8601Scratch); + function getAttributeVariableName(gltf, primitive, attributeSemantic) { + var materialId = primitive.material; + var material = gltf.materials[materialId]; + var techniqueId = material.technique; + var technique = gltf.techniques[techniqueId]; + for (var parameter in technique.parameters) { + if (technique.parameters.hasOwnProperty(parameter)) { + var semantic = technique.parameters[parameter].semantic; + if (semantic === attributeSemantic) { + var attributes = technique.attributes; + for (var attributeVarName in attributes) { + if (attributes.hasOwnProperty(attributeVarName)) { + var name = attributes[attributeVarName]; + if (name === parameter) { + return attributeVarName; + } + } + } + } + } } + return undefined; + } - var wall = entity.wall; - if (!defined(wall)) { - entity.wall = wall = new WallGraphics(); - } + ModelUtility.modifyShaderForQuantizedAttributes = function(gltf, primitive, shader) { + var quantizedUniforms = {}; + var attributes = primitive.attributes; + for (var attributeSemantic in attributes) { + if (attributes.hasOwnProperty(attributeSemantic)) { + var attributeVarName = getAttributeVariableName(gltf, primitive, attributeSemantic); + var accessorId = primitive.attributes[attributeSemantic]; - processPacketData(Boolean, wall, 'show', wallData.show, interval, sourceUri, entityCollection, query); - processPositions(wall, 'positions', wallData.positions, entityCollection); - processArray(wall, 'minimumHeights', wallData.minimumHeights, entityCollection); - processArray(wall, 'maximumHeights', wallData.maximumHeights, entityCollection); - processPacketData(Number, wall, 'granularity', wallData.granularity, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, wall, 'fill', wallData.fill, interval, sourceUri, entityCollection, query); - processMaterialPacketData(wall, 'material', wallData.material, interval, sourceUri, entityCollection, query); - processPacketData(Boolean, wall, 'outline', wallData.outline, interval, sourceUri, entityCollection, query); - processPacketData(Color, wall, 'outlineColor', wallData.outlineColor, interval, sourceUri, entityCollection, query); - processPacketData(Number, wall, 'outlineWidth', wallData.outlineWidth, interval, sourceUri, entityCollection, query); - processPacketData(ShadowMode, wall, 'shadows', wallData.shadows, interval, sourceUri, entityCollection, query); - processPacketData(DistanceDisplayCondition, wall, 'distanceDisplayCondition', wallData.distanceDisplayCondition, interval, sourceUri, entityCollection, query); - } + if (attributeSemantic.charAt(0) === '_') { + attributeSemantic = attributeSemantic.substring(1); + } + var decodeUniformVarName = 'gltf_u_dec_' + attributeSemantic.toLowerCase(); - function processCzmlPacket(packet, entityCollection, updaterFunctions, sourceUri, dataSource, query) { - var objectId = packet.id; - if (!defined(objectId)) { - objectId = createGuid(); + var decodeUniformVarNameScale = decodeUniformVarName + '_scale'; + var decodeUniformVarNameTranslate = decodeUniformVarName + '_translate'; + if (!defined(quantizedUniforms[decodeUniformVarName]) && !defined(quantizedUniforms[decodeUniformVarNameScale])) { + var quantizedAttributes = getQuantizedAttributes(gltf, accessorId); + if (defined(quantizedAttributes)) { + var decodeMatrix = quantizedAttributes.decodeMatrix; + var newMain = 'gltf_decoded_' + attributeSemantic; + var decodedAttributeVarName = attributeVarName.replace('a_', 'gltf_a_dec_'); + var size = Math.floor(Math.sqrt(decodeMatrix.length)); + + // replace usages of the original attribute with the decoded version, but not the declaration + shader = replaceAllButFirstInString(shader, attributeVarName, decodedAttributeVarName); + // declare decoded attribute + var variableType; + if (size > 2) { + variableType = 'vec' + (size - 1); + } else { + variableType = 'float'; + } + shader = variableType + ' ' + decodedAttributeVarName + ';\n' + shader; + // splice decode function into the shader - attributes are pre-multiplied with the decode matrix + // uniform in the shader (32-bit floating point) + var decode = ''; + if (size === 5) { + // separate scale and translate since glsl doesn't have mat5 + shader = 'uniform mat4 ' + decodeUniformVarNameScale + ';\n' + shader; + shader = 'uniform vec4 ' + decodeUniformVarNameTranslate + ';\n' + shader; + decode = '\n' + + 'void main() {\n' + + ' ' + decodedAttributeVarName + ' = ' + decodeUniformVarNameScale + ' * ' + attributeVarName + ' + ' + decodeUniformVarNameTranslate + ';\n' + + ' ' + newMain + '();\n' + + '}\n'; + + quantizedUniforms[decodeUniformVarNameScale] = {mat : 4}; + quantizedUniforms[decodeUniformVarNameTranslate] = {vec : 4}; + } + else { + shader = 'uniform mat' + size + ' ' + decodeUniformVarName + ';\n' + shader; + decode = '\n' + + 'void main() {\n' + + ' ' + decodedAttributeVarName + ' = ' + variableType + '(' + decodeUniformVarName + ' * vec' + size + '(' + attributeVarName + ',1.0));\n' + + ' ' + newMain + '();\n' + + '}\n'; + + quantizedUniforms[decodeUniformVarName] = {mat : size}; + } + shader = ShaderSource.replaceMain(shader, newMain); + shader += decode; + } + } + } } + return { + shader : shader, + uniforms : quantizedUniforms + }; + }; - currentId = objectId; + function getScalarUniformFunction(value) { + var that = { + value : value, + clone : function(source, result) { + return source; + }, + func : function() { + return that.value; + } + }; + return that; + } - if (!defined(dataSource._version) && objectId !== 'document') { - throw new RuntimeError('The first CZML packet is required to be the document object.'); - } + function getVec2UniformFunction(value) { + var that = { + value : Cartesian2.fromArray(value), + clone : Cartesian2.clone, + func : function() { + return that.value; + } + }; + return that; + } - if (packet['delete'] === true) { - entityCollection.removeById(objectId); - } else if (objectId === 'document') { - processDocument(packet, dataSource); - } else { - var entity = entityCollection.getOrCreateEntity(objectId); + function getVec3UniformFunction(value) { + var that = { + value : Cartesian3.fromArray(value), + clone : Cartesian3.clone, + func : function() { + return that.value; + } + }; + return that; + } - var parentId = packet.parent; - if (defined(parentId)) { - entity.parent = entityCollection.getOrCreateEntity(parentId); + function getVec4UniformFunction(value) { + var that = { + value : Cartesian4.fromArray(value), + clone : Cartesian4.clone, + func : function() { + return that.value; + } + }; + return that; + } + + function getMat2UniformFunction(value) { + var that = { + value : Matrix2.fromColumnMajorArray(value), + clone : Matrix2.clone, + func : function() { + return that.value; } + }; + return that; + } - for (var i = updaterFunctions.length - 1; i > -1; i--) { - updaterFunctions[i](entity, packet, entityCollection, sourceUri, query); + function getMat3UniformFunction(value) { + var that = { + value : Matrix3.fromColumnMajorArray(value), + clone : Matrix3.clone, + func : function() { + return that.value; } - } + }; + return that; + } - currentId = undefined; + function getMat4UniformFunction(value) { + var that = { + value : Matrix4.fromColumnMajorArray(value), + clone : Matrix4.clone, + func : function() { + return that.value; + } + }; + return that; } - function updateClock(dataSource) { - var clock; - var clockPacket = dataSource._documentPacket.clock; - if (!defined(clockPacket)) { - if (!defined(dataSource._clock)) { - var availability = dataSource._entityCollection.computeAvailability(); - if (!availability.start.equals(Iso8601.MINIMUM_VALUE)) { - var startTime = availability.start; - var stopTime = availability.stop; - var totalSeconds = JulianDate.secondsDifference(stopTime, startTime); - var multiplier = Math.round(totalSeconds / 120.0); + /////////////////////////////////////////////////////////////////////////// - clock = new DataSourceClock(); - clock.startTime = JulianDate.clone(startTime); - clock.stopTime = JulianDate.clone(stopTime); - clock.clockRange = ClockRange.LOOP_STOP; - clock.multiplier = multiplier; - clock.currentTime = JulianDate.clone(startTime); - clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; - dataSource._clock = clock; - return true; + function DelayLoadedTextureUniform(value, textures, defaultTexture) { + this._value = undefined; + this._textureId = value.index; + this._textures = textures; + this._defaultTexture = defaultTexture; + } + + defineProperties(DelayLoadedTextureUniform.prototype, { + value : { + get : function() { + // Use the default texture (1x1 white) until the model's texture is loaded + if (!defined(this._value)) { + var texture = this._textures[this._textureId]; + if (defined(texture)) { + this._value = texture; + } else { + return this._defaultTexture; + } } + + return this._value; + }, + set : function(value) { + this._value = value; } - return false; } + }); - if (defined(dataSource._clock)) { - clock = dataSource._clock.clone(); - } else { - clock = new DataSourceClock(); - clock.startTime = Iso8601.MINIMUM_VALUE.clone(); - clock.stopTime = Iso8601.MAXIMUM_VALUE.clone(); - clock.currentTime = Iso8601.MINIMUM_VALUE.clone(); - clock.clockRange = ClockRange.LOOP_STOP; - clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; - clock.multiplier = 1.0; - } - if (defined(clockPacket.interval)) { - iso8601Scratch.iso8601 = clockPacket.interval; - var interval = TimeInterval.fromIso8601(iso8601Scratch); - clock.startTime = interval.start; - clock.stopTime = interval.stop; - } - if (defined(clockPacket.currentTime)) { - clock.currentTime = JulianDate.fromIso8601(clockPacket.currentTime); - } - if (defined(clockPacket.range)) { - clock.clockRange = defaultValue(ClockRange[clockPacket.range], ClockRange.LOOP_STOP); - } - if (defined(clockPacket.step)) { - clock.clockStep = defaultValue(ClockStep[clockPacket.step], ClockStep.SYSTEM_CLOCK_MULTIPLIER); - } - if (defined(clockPacket.multiplier)) { - clock.multiplier = clockPacket.multiplier; - } + DelayLoadedTextureUniform.prototype.clone = function(source) { + return source; + }; - if (!clock.equals(dataSource._clock)) { - dataSource._clock = clock.clone(dataSource._clock); - return true; - } + DelayLoadedTextureUniform.prototype.func = undefined; - return false; + /////////////////////////////////////////////////////////////////////////// + + function getTextureUniformFunction(value, texture, defaultTexture) { + var uniform = new DelayLoadedTextureUniform(value, texture, defaultTexture); + // Define function here to access closure since 'this' can't be + // used when the Renderer sets uniforms. + uniform.func = function() { + return uniform.value; + }; + return uniform; } - function load(dataSource, czml, options, clear) { - if (!defined(czml)) { - throw new DeveloperError('czml is required.'); - } - - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var promise = czml; - var sourceUri = options.sourceUri; - var query = defined(options.query) ? objectToQuery(options.query) : undefined; + var gltfUniformFunctions = {}; + gltfUniformFunctions[WebGLConstants.FLOAT] = getScalarUniformFunction; + gltfUniformFunctions[WebGLConstants.FLOAT_VEC2] = getVec2UniformFunction; + gltfUniformFunctions[WebGLConstants.FLOAT_VEC3] = getVec3UniformFunction; + gltfUniformFunctions[WebGLConstants.FLOAT_VEC4] = getVec4UniformFunction; + gltfUniformFunctions[WebGLConstants.INT] = getScalarUniformFunction; + gltfUniformFunctions[WebGLConstants.INT_VEC2] = getVec2UniformFunction; + gltfUniformFunctions[WebGLConstants.INT_VEC3] = getVec3UniformFunction; + gltfUniformFunctions[WebGLConstants.INT_VEC4] = getVec4UniformFunction; + gltfUniformFunctions[WebGLConstants.BOOL] = getScalarUniformFunction; + gltfUniformFunctions[WebGLConstants.BOOL_VEC2] = getVec2UniformFunction; + gltfUniformFunctions[WebGLConstants.BOOL_VEC3] = getVec3UniformFunction; + gltfUniformFunctions[WebGLConstants.BOOL_VEC4] = getVec4UniformFunction; + gltfUniformFunctions[WebGLConstants.FLOAT_MAT2] = getMat2UniformFunction; + gltfUniformFunctions[WebGLConstants.FLOAT_MAT3] = getMat3UniformFunction; + gltfUniformFunctions[WebGLConstants.FLOAT_MAT4] = getMat4UniformFunction; + gltfUniformFunctions[WebGLConstants.SAMPLER_2D] = getTextureUniformFunction; + // GLTF_SPEC: Support SAMPLER_CUBE. https://github.com/KhronosGroup/glTF/issues/40 - // If the czml is a URL - if (typeof czml === 'string') { - if (defined(query)) { - czml = joinUrls(czml, '?' + query, false); - } - promise = loadJson(czml); - sourceUri = defaultValue(sourceUri, czml); - } + ModelUtility.createUniformFunction = function(type, value, textures, defaultTexture) { + return gltfUniformFunctions[type](value, textures, defaultTexture); + }; - DataSource.setLoading(dataSource, true); + function scaleFromMatrix5Array(matrix) { + return [matrix[0], matrix[1], matrix[2], matrix[3], + matrix[5], matrix[6], matrix[7], matrix[8], + matrix[10], matrix[11], matrix[12], matrix[13], + matrix[15], matrix[16], matrix[17], matrix[18]]; + } - return when(promise, function(czml) { - return loadCzml(dataSource, czml, sourceUri, clear, query); - }).otherwise(function(error) { - DataSource.setLoading(dataSource, false); - dataSource._error.raiseEvent(dataSource, error); - console.log(error); - return when.reject(error); - }); + function translateFromMatrix5Array(matrix) { + return [matrix[20], matrix[21], matrix[22], matrix[23]]; } - function loadCzml(dataSource, czml, sourceUri, clear, query) { - DataSource.setLoading(dataSource, true); - var entityCollection = dataSource._entityCollection; + ModelUtility.createUniformsForQuantizedAttributes = function(gltf, primitive, quantizedUniforms) { + var accessors = gltf.accessors; + var setUniforms = {}; + var uniformMap = {}; - if (clear) { - dataSource._version = undefined; - dataSource._documentPacket = new DocumentPacket(); - entityCollection.removeAll(); - } + var attributes = primitive.attributes; + for (var attribute in attributes) { + if (attributes.hasOwnProperty(attribute)) { + var accessorId = attributes[attribute]; + var a = accessors[accessorId]; + var extensions = a.extensions; - CzmlDataSource._processCzml(czml, entityCollection, sourceUri, undefined, dataSource, query); + if (attribute.charAt(0) === '_') { + attribute = attribute.substring(1); + } - var raiseChangedEvent = updateClock(dataSource); + if (defined(extensions)) { + var quantizedAttributes = extensions.WEB3D_quantized_attributes; + if (defined(quantizedAttributes)) { + var decodeMatrix = quantizedAttributes.decodeMatrix; + var uniformVariable = 'gltf_u_dec_' + attribute.toLowerCase(); - var documentPacket = dataSource._documentPacket; - if (defined(documentPacket.name) && dataSource._name !== documentPacket.name) { - dataSource._name = documentPacket.name; - raiseChangedEvent = true; - } else if (!defined(dataSource._name) && defined(sourceUri)) { - dataSource._name = getFilenameFromUri(sourceUri); - raiseChangedEvent = true; + switch (a.type) { + case AttributeType.SCALAR: + uniformMap[uniformVariable] = getMat2UniformFunction(decodeMatrix).func; + setUniforms[uniformVariable] = true; + break; + case AttributeType.VEC2: + uniformMap[uniformVariable] = getMat3UniformFunction(decodeMatrix).func; + setUniforms[uniformVariable] = true; + break; + case AttributeType.VEC3: + uniformMap[uniformVariable] = getMat4UniformFunction(decodeMatrix).func; + setUniforms[uniformVariable] = true; + break; + case AttributeType.VEC4: + // VEC4 attributes are split into scale and translate because there is no mat5 in GLSL + var uniformVariableScale = uniformVariable + '_scale'; + var uniformVariableTranslate = uniformVariable + '_translate'; + uniformMap[uniformVariableScale] = getMat4UniformFunction(scaleFromMatrix5Array(decodeMatrix)).func; + uniformMap[uniformVariableTranslate] = getVec4UniformFunction(translateFromMatrix5Array(decodeMatrix)).func; + setUniforms[uniformVariableScale] = true; + setUniforms[uniformVariableTranslate] = true; + break; + } + } + } + } } - DataSource.setLoading(dataSource, false); - if (raiseChangedEvent) { - dataSource._changed.raiseEvent(dataSource); + // If there are any unset quantized uniforms in this program, they should be set to the identity + for (var quantizedUniform in quantizedUniforms) { + if (quantizedUniforms.hasOwnProperty(quantizedUniform)) { + if (!setUniforms[quantizedUniform]) { + var properties = quantizedUniforms[quantizedUniform]; + if (defined(properties.mat)) { + if (properties.mat === 2) { + uniformMap[quantizedUniform] = getMat2UniformFunction(Matrix2.IDENTITY).func; + } else if (properties.mat === 3) { + uniformMap[quantizedUniform] = getMat3UniformFunction(Matrix3.IDENTITY).func; + } else if (properties.mat === 4) { + uniformMap[quantizedUniform] = getMat4UniformFunction(Matrix4.IDENTITY).func; + } + } + if (defined(properties.vec)) { + if (properties.vec === 4) { + uniformMap[quantizedUniform] = getVec4UniformFunction([0, 0, 0, 0]).func; + } + } + } + } } - - return dataSource; - } - - function DocumentPacket() { - this.name = undefined; - this.clock = undefined; - } - - /** - * A {@link DataSource} which processes {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/CZML-Guide|CZML}. - * @alias CzmlDataSource - * @constructor - * - * @param {String} [name] An optional name for the data source. This value will be overwritten if a loaded document contains a name. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=CZML.html|Cesium Sandcastle CZML Demo} - */ - function CzmlDataSource(name) { - this._name = name; - this._changed = new Event(); - this._error = new Event(); - this._isLoading = false; - this._loading = new Event(); - this._clock = undefined; - this._documentPacket = new DocumentPacket(); - this._version = undefined; - this._entityCollection = new EntityCollection(this); - this._entityCluster = new EntityCluster(); - } - - /** - * Creates a Promise to a new instance loaded with the provided CZML data. - * - * @param {String|Object} czml A url or CZML object to be processed. - * @param {Object} [options] An object with the following properties: - * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. - * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. - * @returns {Promise.<CzmlDataSource>} A promise that resolves to the new instance once the data is processed. - */ - CzmlDataSource.load = function(czml, options) { - return new CzmlDataSource().load(czml, options); + return uniformMap; }; - defineProperties(CzmlDataSource.prototype, { - /** - * Gets a human-readable name for this instance. - * @memberof CzmlDataSource.prototype - * @type {String} - */ - name : { - get : function() { - return this._name; - } + // This doesn't support LOCAL, which we could add if it is ever used. + var scratchTranslationRtc = new Cartesian3(); + var gltfSemanticUniforms = { + MODEL : function(uniformState, model) { + return function() { + return uniformState.model; + }; }, - /** - * Gets the clock settings defined by the loaded CZML. If no clock is explicitly - * defined in the CZML, the combined availability of all objects is returned. If - * only static data exists, this value is undefined. - * @memberof CzmlDataSource.prototype - * @type {DataSourceClock} - */ - clock : { - get : function() { - return this._clock; - } + VIEW : function(uniformState, model) { + return function() { + return uniformState.view; + }; }, - /** - * Gets the collection of {@link Entity} instances. - * @memberof CzmlDataSource.prototype - * @type {EntityCollection} - */ - entities : { - get : function() { - return this._entityCollection; - } + PROJECTION : function(uniformState, model) { + return function() { + return uniformState.projection; + }; }, - /** - * Gets a value indicating if the data source is currently loading data. - * @memberof CzmlDataSource.prototype - * @type {Boolean} - */ - isLoading : { - get : function() { - return this._isLoading; - } + MODELVIEW : function(uniformState, model) { + return function() { + return uniformState.modelView; + }; }, - /** - * Gets an event that will be raised when the underlying data changes. - * @memberof CzmlDataSource.prototype - * @type {Event} - */ - changedEvent : { - get : function() { - return this._changed; - } + CESIUM_RTC_MODELVIEW : function(uniformState, model) { + // CESIUM_RTC extension + var mvRtc = new Matrix4(); + return function() { + if (defined(model._rtcCenter)) { + Matrix4.getTranslation(uniformState.model, scratchTranslationRtc); + Cartesian3.add(scratchTranslationRtc, model._rtcCenter, scratchTranslationRtc); + Matrix4.multiplyByPoint(uniformState.view, scratchTranslationRtc, scratchTranslationRtc); + return Matrix4.setTranslation(uniformState.modelView, scratchTranslationRtc, mvRtc); + } + return uniformState.modelView; + }; }, - /** - * Gets an event that will be raised if an error is encountered during processing. - * @memberof CzmlDataSource.prototype - * @type {Event} - */ - errorEvent : { - get : function() { - return this._error; - } + MODELVIEWPROJECTION : function(uniformState, model) { + return function() { + return uniformState.modelViewProjection; + }; }, - /** - * Gets an event that will be raised when the data source either starts or stops loading. - * @memberof CzmlDataSource.prototype - * @type {Event} - */ - loadingEvent : { - get : function() { - return this._loading; - } + MODELINVERSE : function(uniformState, model) { + return function() { + return uniformState.inverseModel; + }; }, - /** - * Gets whether or not this data source should be displayed. - * @memberof CzmlDataSource.prototype - * @type {Boolean} - */ - show : { - get : function() { - return this._entityCollection.show; - }, - set : function(value) { - this._entityCollection.show = value; - } + VIEWINVERSE : function(uniformState, model) { + return function() { + return uniformState.inverseView; + }; }, - - /** - * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. - * - * @memberof CzmlDataSource.prototype - * @type {EntityCluster} - */ - clustering : { - get : function() { - return this._entityCluster; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value must be defined.'); - } - this._entityCluster = value; - } + PROJECTIONINVERSE : function(uniformState, model) { + return function() { + return uniformState.inverseProjection; + }; + }, + MODELVIEWINVERSE : function(uniformState, model) { + return function() { + return uniformState.inverseModelView; + }; + }, + MODELVIEWPROJECTIONINVERSE : function(uniformState, model) { + return function() { + return uniformState.inverseModelViewProjection; + }; + }, + MODELINVERSETRANSPOSE : function(uniformState, model) { + return function() { + return uniformState.inverseTransposeModel; + }; + }, + MODELVIEWINVERSETRANSPOSE : function(uniformState, model) { + return function() { + return uniformState.normal; + }; + }, + VIEWPORT : function(uniformState, model) { + return function() { + return uniformState.viewportCartesian4; + }; } - }); - - /** - * Gets the array of CZML processing functions. - * @memberof CzmlDataSource - * @type Array - */ - CzmlDataSource.updaters = [ - processBillboard, // - processBox, // - processCorridor, // - processCylinder, // - processEllipse, // - processEllipsoid, // - processLabel, // - processModel, // - processName, // - processDescription, // - processPath, // - processPoint, // - processPolygon, // - processPolyline, // - processProperties, // - processRectangle, // - processPosition, // - processViewFrom, // - processWall, // - processOrientation, // - processAvailability]; - - /** - * Processes the provided url or CZML object without clearing any existing data. - * - * @param {String|Object} czml A url or CZML object to be processed. - * @param {Object} [options] An object with the following properties: - * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. - * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. - * @returns {Promise.<CzmlDataSource>} A promise that resolves to this instances once the data is processed. - */ - CzmlDataSource.prototype.process = function(czml, options) { - return load(this, czml, options, false); - }; - - /** - * Loads the provided url or CZML object, replacing any existing data. - * - * @param {String|Object} czml A url or CZML object to be processed. - * @param {Object} [options] An object with the following properties: - * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. - * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. - * @returns {Promise.<CzmlDataSource>} A promise that resolves to this instances once the data is processed. - */ - CzmlDataSource.prototype.load = function(czml, options) { - return load(this, czml, options, true); + // JOINTMATRIX created in createCommand() }; - /** - * A helper function used by custom CZML updater functions - * which creates or updates a {@link Property} from a CZML packet. - * @function - * - * @param {Function} type The constructor function for the property being processed. - * @param {Object} object The object on which the property will be added or updated. - * @param {String} propertyName The name of the property on the object. - * @param {Object} packetData The CZML packet being processed. - * @param {TimeInterval} interval A constraining interval for which the data is valid. - * @param {String} sourceUri The originating uri of the data being processed. - * @param {EntityCollection} entityCollection The collection being processsed. - */ - CzmlDataSource.processPacketData = processPacketData; - - /** - * A helper function used by custom CZML updater functions - * which creates or updates a {@link PositionProperty} from a CZML packet. - * @function - * - * @param {Object} object The object on which the property will be added or updated. - * @param {String} propertyName The name of the property on the object. - * @param {Object} packetData The CZML packet being processed. - * @param {TimeInterval} interval A constraining interval for which the data is valid. - * @param {String} sourceUri The originating uri of the data being processed. - * @param {EntityCollection} entityCollection The collection being processsed. - */ - CzmlDataSource.processPositionPacketData = processPositionPacketData; - - /** - * A helper function used by custom CZML updater functions - * which creates or updates a {@link MaterialProperty} from a CZML packet. - * @function - * - * @param {Object} object The object on which the property will be added or updated. - * @param {String} propertyName The name of the property on the object. - * @param {Object} packetData The CZML packet being processed. - * @param {TimeInterval} interval A constraining interval for which the data is valid. - * @param {String} sourceUri The originating uri of the data being processed. - * @param {EntityCollection} entityCollection The collection being processsed. - */ - CzmlDataSource.processMaterialPacketData = processMaterialPacketData; - - CzmlDataSource._processCzml = function(czml, entityCollection, sourceUri, updaterFunctions, dataSource, query) { - updaterFunctions = defined(updaterFunctions) ? updaterFunctions : CzmlDataSource.updaters; - - if (isArray(czml)) { - for (var i = 0, len = czml.length; i < len; i++) { - processCzmlPacket(czml[i], entityCollection, updaterFunctions, sourceUri, dataSource, query); - } - } else { - processCzmlPacket(czml, entityCollection, updaterFunctions, sourceUri, dataSource, query); - } + ModelUtility.getGltfSemanticUniforms = function() { + return gltfSemanticUniforms; }; - return CzmlDataSource; + return ModelUtility; }); -define('DataSources/DataSourceCollection',[ +define('Scene/Model',[ + '../Core/BoundingSphere', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/ClippingPlaneCollection', + '../Core/clone', + '../Core/Color', + '../Core/combine', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Event', - '../ThirdParty/when' + '../Core/DistanceDisplayCondition', + '../Core/FeatureDetection', + '../Core/getAbsoluteUri', + '../Core/getMagic', + '../Core/getStringFromTypedArray', + '../Core/IndexDatatype', + '../Core/loadCRN', + '../Core/loadImageFromTypedArray', + '../Core/loadKTX', + '../Core/Math', + '../Core/Matrix2', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/PixelFormat', + '../Core/Plane', + '../Core/PrimitiveType', + '../Core/Resource', + '../Core/Quaternion', + '../Core/Queue', + '../Core/RuntimeError', + '../Core/Transforms', + '../Core/WebGLConstants', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/Sampler', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/Texture', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', + '../Renderer/VertexArray', + '../ThirdParty/GltfPipeline/addDefaults', + '../ThirdParty/GltfPipeline/addPipelineExtras', + '../ThirdParty/GltfPipeline/ForEach', + '../ThirdParty/GltfPipeline/getAccessorByteStride', + '../ThirdParty/GltfPipeline/numberOfComponentsForType', + '../ThirdParty/GltfPipeline/parseBinaryGltf', + '../ThirdParty/GltfPipeline/processModelMaterialsCommon', + '../ThirdParty/GltfPipeline/processPbrMetallicRoughness', + '../ThirdParty/GltfPipeline/updateVersion', + '../ThirdParty/Uri', + '../ThirdParty/when', + './AttributeType', + './Axis', + './BlendingState', + './ColorBlendMode', + './HeightReference', + './JobType', + './ModelAnimationCache', + './ModelAnimationCollection', + './ModelLoadResources', + './ModelMaterial', + './ModelMesh', + './ModelNode', + './ModelUtility', + './SceneMode', + './ShadowMode' ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + ClippingPlaneCollection, + clone, + Color, + combine, defaultValue, defined, defineProperties, + deprecationWarning, destroyObject, DeveloperError, - Event, - when) { + DistanceDisplayCondition, + FeatureDetection, + getAbsoluteUri, + getMagic, + getStringFromTypedArray, + IndexDatatype, + loadCRN, + loadImageFromTypedArray, + loadKTX, + CesiumMath, + Matrix2, + Matrix3, + Matrix4, + PixelFormat, + Plane, + PrimitiveType, + Resource, + Quaternion, + Queue, + RuntimeError, + Transforms, + WebGLConstants, + Buffer, + BufferUsage, + DrawCommand, + Pass, + RenderState, + Sampler, + ShaderProgram, + ShaderSource, + Texture, + TextureMinificationFilter, + TextureWrap, + VertexArray, + addDefaults, + addPipelineExtras, + ForEach, + getAccessorByteStride, + numberOfComponentsForType, + parseBinaryGltf, + processModelMaterialsCommon, + processPbrMetallicRoughness, + updateVersion, + Uri, + when, + AttributeType, + Axis, + BlendingState, + ColorBlendMode, + HeightReference, + JobType, + ModelAnimationCache, + ModelAnimationCollection, + ModelLoadResources, + ModelMaterial, + ModelMesh, + ModelNode, + ModelUtility, + SceneMode, + ShadowMode) { 'use strict'; - /** - * A collection of {@link DataSource} instances. - * @alias DataSourceCollection - * @constructor - */ - function DataSourceCollection() { - this._dataSources = []; - this._dataSourceAdded = new Event(); - this._dataSourceRemoved = new Event(); + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; } - defineProperties(DataSourceCollection.prototype, { - /** - * Gets the number of data sources in this collection. - * @memberof DataSourceCollection.prototype - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._dataSources.length; - } - }, - - /** - * An event that is raised when a data source is added to the collection. - * Event handlers are passed the data source that was added. - * @memberof DataSourceCollection.prototype - * @type {Event} - * @readonly - */ - dataSourceAdded : { - get : function() { - return this._dataSourceAdded; - } - }, - - /** - * An event that is raised when a data source is removed from the collection. - * Event handlers are passed the data source that was removed. - * @memberof DataSourceCollection.prototype - * @type {Event} - * @readonly - */ - dataSourceRemoved : { - get : function() { - return this._dataSourceRemoved; - } - } - }); + var boundingSphereCartesian3Scratch = new Cartesian3(); - /** - * Adds a data source to the collection. - * - * @param {DataSource|Promise.<DataSource>} dataSource A data source or a promise to a data source to add to the collection. - * When passing a promise, the data source will not actually be added - * to the collection until the promise resolves successfully. - * @returns {Promise.<DataSource>} A Promise that resolves once the data source has been added to the collection. - */ - DataSourceCollection.prototype.add = function(dataSource) { - if (!defined(dataSource)) { - throw new DeveloperError('dataSource is required.'); - } - - var that = this; - var dataSources = this._dataSources; - return when(dataSource, function(value) { - //Only add the data source if removeAll has not been called - //Since it was added. - if (dataSources === that._dataSources) { - that._dataSources.push(value); - that._dataSourceAdded.raiseEvent(that, value); - } - return value; - }); + var ModelState = { + NEEDS_LOAD : 0, + LOADING : 1, + LOADED : 2, // Renderable, but textures can still be pending when incrementallyLoadTextures is true. + FAILED : 3 }; - /** - * Removes a data source from this collection, if present. - * - * @param {DataSource} dataSource The data source to remove. - * @param {Boolean} [destroy=false] Whether to destroy the data source in addition to removing it. - * @returns {Boolean} true if the data source was in the collection and was removed, - * false if the data source was not in the collection. - */ - DataSourceCollection.prototype.remove = function(dataSource, destroy) { - destroy = defaultValue(destroy, false); - - var index = this._dataSources.indexOf(dataSource); - if (index !== -1) { - this._dataSources.splice(index, 1); - this._dataSourceRemoved.raiseEvent(this, dataSource); - - if (destroy && typeof dataSource.destroy === 'function') { - dataSource.destroy(); - } + // glTF MIME types discussed in https://github.com/KhronosGroup/glTF/issues/412 and https://github.com/KhronosGroup/glTF/issues/943 + var defaultModelAccept = 'model/gltf-binary,model/gltf+json;q=0.8,application/json;q=0.2,*/*;q=0.01'; - return true; - } + /////////////////////////////////////////////////////////////////////////// - return false; - }; + function setCachedGltf(model, cachedGltf) { + model._cachedGltf = cachedGltf; + } - /** - * Removes all data sources from this collection. - * - * @param {Boolean} [destroy=false] whether to destroy the data sources in addition to removing them. - */ - DataSourceCollection.prototype.removeAll = function(destroy) { - destroy = defaultValue(destroy, false); + // glTF JSON can be big given embedded geometry, textures, and animations, so we + // cache it across all models using the same url/cache-key. This also reduces the + // slight overhead in assigning defaults to missing values. + // + // Note that this is a global cache, compared to renderer resources, which + // are cached per context. + function CachedGltf(options) { + this._gltf = options.gltf; + this.ready = options.ready; + this.modelsToLoad = []; + this.count = 0; + } - var dataSources = this._dataSources; - for (var i = 0, len = dataSources.length; i < len; ++i) { - var dataSource = dataSources[i]; - this._dataSourceRemoved.raiseEvent(this, dataSource); + defineProperties(CachedGltf.prototype, { + gltf : { + set : function(value) { + this._gltf = value; + }, - if (destroy && typeof dataSource.destroy === 'function') { - dataSource.destroy(); + get : function() { + return this._gltf; } } - this._dataSources = []; - }; - - /** - * Checks to see if the collection contains a given data source. - * - * @param {DataSource} dataSource The data source to check for. - * @returns {Boolean} true if the collection contains the data source, false otherwise. - */ - DataSourceCollection.prototype.contains = function(dataSource) { - return this.indexOf(dataSource) !== -1; - }; + }); - /** - * Determines the index of a given data source in the collection. - * - * @param {DataSource} dataSource The data source to find the index of. - * @returns {Number} The index of the data source in the collection, or -1 if the data source does not exist in the collection. - */ - DataSourceCollection.prototype.indexOf = function(dataSource) { - return this._dataSources.indexOf(dataSource); - }; + CachedGltf.prototype.makeReady = function(gltfJson) { + this.gltf = gltfJson; - /** - * Gets a data source by index from the collection. - * - * @param {Number} index the index to retrieve. - * @returns {DataSource} The data source at the specified index. - */ - DataSourceCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); + var models = this.modelsToLoad; + var length = models.length; + for (var i = 0; i < length; ++i) { + var m = models[i]; + if (!m.isDestroyed()) { + setCachedGltf(m, this); + } } - - return this._dataSources[index]; + this.modelsToLoad = undefined; + this.ready = true; }; - /** - * Returns true if this object was destroyed; otherwise, false. - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} true if this object was destroyed; otherwise, false. - * - * @see DataSourceCollection#destroy - */ - DataSourceCollection.prototype.isDestroyed = function() { - return false; - }; + var gltfCache = {}; + + /////////////////////////////////////////////////////////////////////////// /** - * Destroys the resources held by all data sources in this collection. Explicitly destroying this - * object allows for deterministic release of WebGL resources, instead of relying on the garbage - * collector. Once this object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. + * A 3D model based on glTF, the runtime asset format for WebGL, OpenGL ES, and OpenGL. + * <p> + * Cesium includes support for geometry and materials, glTF animations, and glTF skinning. + * In addition, individual glTF nodes are pickable with {@link Scene#pick} and animatable + * with {@link Model#getNode}. glTF cameras and lights are not currently supported. + * </p> + * <p> + * An external glTF asset is created with {@link Model.fromGltf}. glTF JSON can also be + * created at runtime and passed to this constructor function. In either case, the + * {@link Model#readyPromise} is resolved when the model is ready to render, i.e., + * when the external binary, image, and shader files are downloaded and the WebGL + * resources are created. + * </p> + * <p> + * For high-precision rendering, Cesium supports the CESIUM_RTC extension, which introduces the + * CESIUM_RTC_MODELVIEW parameter semantic that says the node is in WGS84 coordinates translated + * relative to a local origin. + * </p> * - * @returns {undefined} + * @alias Model + * @constructor * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * @param {Object} [options] Object with the following properties: + * @param {Object|ArrayBuffer|Uint8Array} [options.gltf] The object for the glTF JSON or an arraybuffer of Binary glTF defined by the KHR_binary_glTF extension. + * @param {Resource|String} [options.basePath=''] The base path that paths in the glTF JSON are relative to. + * @param {Boolean} [options.show=true] Determines if the model primitive will be shown. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. + * @param {Number} [options.scale=1.0] A uniform scale applied to this model. + * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. + * @param {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. + * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}. + * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. + * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. + * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. + * @param {HeightReference} [options.heightReference] Determines how the model is drawn relative to terrain. + * @param {Scene} [options.scene] Must be passed in for models that use the height reference property. + * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. + * @param {Color} [options.color=Color.WHITE] A color that blends with the model's rendered color. + * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. + * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. + * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. + * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. Clipping planes are not currently supported in Internet Explorer. * + * @exception {DeveloperError} bgltf is not a valid Binary glTF file. + * @exception {DeveloperError} Only glTF Binary version 1 is supported. * - * @example - * dataSourceCollection = dataSourceCollection && dataSourceCollection.destroy(); + * @see Model.fromGltf * - * @see DataSourceCollection#isDestroyed + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle Models Demo} */ - DataSourceCollection.prototype.destroy = function() { - this.removeAll(true); - return destroyObject(this); - }; + function Model(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - return DataSourceCollection; -}); + var cacheKey = options.cacheKey; + this._cacheKey = cacheKey; + this._cachedGltf = undefined; + this._releaseGltfJson = defaultValue(options.releaseGltfJson, false); -define('DataSources/EllipseGeometryUpdater',[ - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/EllipseGeometry', - '../Core/EllipseOutlineGeometry', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/oneTimeWarning', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/GroundPrimitive', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' - ], function( - Color, - ColorGeometryInstanceAttribute, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - EllipseGeometry, - EllipseOutlineGeometry, - Event, - GeometryInstance, - Iso8601, - oneTimeWarning, - ShowGeometryInstanceAttribute, - GroundPrimitive, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { - 'use strict'; + var cachedGltf; + if (defined(cacheKey) && defined(gltfCache[cacheKey]) && gltfCache[cacheKey].ready) { + // glTF JSON is in cache and ready + cachedGltf = gltfCache[cacheKey]; + ++cachedGltf.count; + } else { + // glTF was explicitly provided, e.g., when a user uses the Model constructor directly + var gltf = options.gltf; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + if (defined(gltf)) { + if (gltf instanceof ArrayBuffer) { + gltf = new Uint8Array(gltf); + } + + if (gltf instanceof Uint8Array) { + // Binary glTF + var parsedGltf = parseBinaryGltf(gltf); + + cachedGltf = new CachedGltf({ + gltf : parsedGltf, + ready : true + }); + } else { + // Normal glTF (JSON) + cachedGltf = new CachedGltf({ + gltf : options.gltf, + ready : true + }); + } - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.center = undefined; - this.semiMajorAxis = undefined; - this.semiMinorAxis = undefined; - this.rotation = undefined; - this.height = undefined; - this.extrudedHeight = undefined; - this.granularity = undefined; - this.stRotation = undefined; - this.numberOfVerticalLines = undefined; - } + cachedGltf.count = 1; - /** - * A {@link GeometryUpdater} for ellipses. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias EllipseGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function EllipseGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + if (defined(cacheKey)) { + gltfCache[cacheKey] = cachedGltf; + } + } } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(EllipseGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._isClosed = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._onTerrain = false; - this._options = new GeometryOptions(entity); + setCachedGltf(this, cachedGltf); - this._onEntityPropertyChanged(entity, 'ellipse', entity.ellipse, undefined); - } + var basePath = defaultValue(options.basePath, ''); + this._resource = Resource.createIfNeeded(basePath); - defineProperties(EllipseGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof EllipseGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof EllipseGeometryUpdater - * @type {Appearance} + * Determines if the model primitive will be shown. + * + * @type {Boolean} + * + * @default true */ - materialAppearanceType : { - value : MaterialAppearance - } - }); + this.show = defaultValue(options.show, true); - defineProperties(EllipseGeometryUpdater.prototype, { /** - * Gets the entity associated with this geometry. - * @memberof EllipseGeometryUpdater.prototype + * The silhouette color. * - * @type {Entity} - * @readonly + * @type {Color} + * + * @default Color.RED */ - entity : { - get : function() { - return this._entity; - } - }, + this.silhouetteColor = defaultValue(options.silhouetteColor, Color.RED); + this._silhouetteColor = new Color(); + this._silhouetteColorPreviousAlpha = 1.0; + this._normalAttributeName = undefined; + /** - * Gets a value indicating if the geometry has a fill component. - * @memberof EllipseGeometryUpdater.prototype + * The size of the silhouette in pixels. * - * @type {Boolean} - * @readonly + * @type {Number} + * + * @default 0.0 */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, + this.silhouetteSize = defaultValue(options.silhouetteSize, 0.0); + /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof EllipseGeometryUpdater.prototype + * The 4x4 transformation matrix that transforms the model from model to world coordinates. + * When this is the identity matrix, the model is drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. * - * @type {Boolean} - * @readonly + * @type {Matrix4} + * + * @default {@link Matrix4.IDENTITY} + * + * @example + * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); + * m.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._modelMatrix = Matrix4.clone(this.modelMatrix); + this._clampedModelMatrix = undefined; + /** - * Gets the material property used to fill the geometry. - * @memberof EllipseGeometryUpdater.prototype + * A uniform scale applied to this model before the {@link Model#modelMatrix}. + * Values greater than <code>1.0</code> increase the size of the model; values + * less than <code>1.0</code> decrease. * - * @type {MaterialProperty} - * @readonly + * @type {Number} + * + * @default 1.0 */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, + this.scale = defaultValue(options.scale, 1.0); + this._scale = this.scale; + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof EllipseGeometryUpdater.prototype + * The approximate minimum pixel size of the model regardless of zoom. + * This can be used to ensure that a model is visible even when the viewer + * zooms out. When <code>0.0</code>, no minimum size is enforced. * - * @type {Boolean} - * @readonly + * @type {Number} + * + * @default 0.0 */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, + this.minimumPixelSize = defaultValue(options.minimumPixelSize, 0.0); + this._minimumPixelSize = this.minimumPixelSize; + /** - * Gets a value indicating if outline visibility varies with simulation time. - * @memberof EllipseGeometryUpdater.prototype + * The maximum scale size for a model. This can be used to give + * an upper limit to the {@link Model#minimumPixelSize}, ensuring that the model + * is never an unreasonable scale. * - * @type {Boolean} - * @readonly + * @type {Number} */ - hasConstantOutline : { - get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); - } - }, + this.maximumScale = options.maximumScale; + this._maximumScale = this.maximumScale; + /** - * Gets the {@link Color} property for the geometry outline. - * @memberof EllipseGeometryUpdater.prototype + * User-defined object returned when the model is picked. * - * @type {Property} - * @readonly + * @type Object + * + * @default undefined + * + * @see Scene#pick */ - outlineColorProperty : { - get : function() { - return this._outlineColorProperty; - } - }, + this.id = options.id; + this._id = options.id; + /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof EllipseGeometryUpdater.prototype + * Returns the height reference of the model * - * @type {Number} - * @readonly + * @memberof Model.prototype + * + * @type {HeightReference} + * + * @default HeightReference.NONE */ - outlineWidth : { - get : function() { - return this._outlineWidth; - } - }, + this.heightReference = defaultValue(options.heightReference, HeightReference.NONE); + this._heightReference = this.heightReference; + this._heightChanged = false; + this._removeUpdateHeightCallback = undefined; + var scene = options.scene; + this._scene = scene; + if (defined(scene) && defined(scene.terrainProviderChanged)) { + this._terrainProviderChangedCallback = scene.terrainProviderChanged.addEventListener(function() { + this._heightChanged = true; + }, this); + } + /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof EllipseGeometryUpdater.prototype + * Used for picking primitives that wrap a model. * - * @type {Property} - * @readonly + * @private */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; - } - }, + this._pickObject = options.pickObject; + this._allowPicking = defaultValue(options.allowPicking, true); + + this._ready = false; + this._readyPromise = when.defer(); + /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof EllipseGeometryUpdater.prototype + * The currently playing glTF animations. * - * @type {Property} - * @readonly + * @type {ModelAnimationCollection} */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayConditionProperty; - } - }, + this.activeAnimations = new ModelAnimationCollection(this); + /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof EllipseGeometryUpdater.prototype + * Determines if the model's animations should hold a pose over frames where no keyframes are specified. * * @type {Boolean} - * @readonly */ - isDynamic : { - get : function() { - return this._dynamic; - } - }, + this.clampAnimations = defaultValue(options.clampAnimations, true); + + this._defaultTexture = undefined; + this._incrementallyLoadTextures = defaultValue(options.incrementallyLoadTextures, true); + this._asynchronous = defaultValue(options.asynchronous, true); + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof EllipseGeometryUpdater.prototype + * Determines whether the model casts or receives shadows from each light source. * - * @type {Boolean} - * @readonly + * @type {ShadowMode} + * + * @default ShadowMode.ENABLED */ - isClosed : { - get : function() { - return this._isClosed; - } - }, + this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); + this._shadows = this.shadows; + /** - * Gets a value indicating if the geometry should be drawn on terrain. - * @memberof EllipseGeometryUpdater.prototype + * A color that blends with the model's rendered color. * - * @type {Boolean} - * @readonly + * @type {Color} + * + * @default Color.WHITE */ - onTerrain : { - get : function() { - return this._onTerrain; - } - }, + this.color = defaultValue(options.color, Color.WHITE); + this._color = new Color(); + this._colorPreviousAlpha = 1.0; + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof EllipseGeometryUpdater.prototype + * Defines how the color blends with the model. * - * @type {Boolean} - * @readonly + * @type {ColorBlendMode} + * + * @default ColorBlendMode.HIGHLIGHT */ - geometryChanged : { - get : function() { - return this._geometryChanged; - } - } - }); + this.colorBlendMode = defaultValue(options.colorBlendMode, ColorBlendMode.HIGHLIGHT); - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - EllipseGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + /** + * Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. + * A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with + * any value in-between resulting in a mix of the two. + * + * @type {Number} + * + * @default 0.5 + */ + this.colorBlendAmount = defaultValue(options.colorBlendAmount, 0.5); - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - EllipseGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; + /** + * The {@link ClippingPlaneCollection} used to selectively disable rendering the model. Clipping planes are not currently supported in Internet Explorer. + * + * @type {ClippingPlaneCollection} + */ + this.clippingPlanes = options.clippingPlanes; - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - EllipseGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the model. A glTF primitive corresponds + * to one draw command. A glTF mesh has an array of primitives, often of length one. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + this._debugShowBoundingVolume = false; - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the model in wireframe. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugWireframe = defaultValue(options.debugWireframe, false); + this._debugWireframe = false; - var attributes; + this._distanceDisplayCondition = options.distanceDisplayCondition; - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; - } + // Undocumented options + this._addBatchIdToGeneratedShaders = options.addBatchIdToGeneratedShaders; + this._precreatedAttributes = options.precreatedAttributes; + this._vertexShaderLoaded = options.vertexShaderLoaded; + this._fragmentShaderLoaded = options.fragmentShaderLoaded; + this._uniformMapLoaded = options.uniformMapLoaded; + this._pickVertexShaderLoaded = options.pickVertexShaderLoaded; + this._pickFragmentShaderLoaded = options.pickFragmentShaderLoaded; + this._pickUniformMapLoaded = options.pickUniformMapLoaded; + this._ignoreCommands = defaultValue(options.ignoreCommands, false); + this._requestType = options.requestType; + this._upAxis = defaultValue(options.upAxis, Axis.Y); - return new GeometryInstance({ - id : entity, - geometry : new EllipseGeometry(this._options), - attributes : attributes - }); - }; + /** + * @private + * @readonly + */ + this.cull = defaultValue(options.cull, true); - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - EllipseGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + /** + * @private + * @readonly + */ + this.opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + this._computedModelMatrix = new Matrix4(); // Derived from modelMatrix and scale + this._modelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); // Derived from modelMatrix, scale, and the current view matrix + this._initialRadius = undefined; // Radius without model's scale property, model-matrix scale, animations, or skins + this._boundingSphere = undefined; + this._scaledBoundingSphere = new BoundingSphere(); + this._state = ModelState.NEEDS_LOAD; + this._loadResources = undefined; - return new GeometryInstance({ - id : entity, - geometry : new EllipseOutlineGeometry(this._options), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) - } - }); - }; + this._mode = undefined; - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - EllipseGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + this._perNodeShowDirty = false; // true when the Cesium API was used to change a node's show property + this._cesiumAnimationsDirty = false; // true when the Cesium API, not a glTF animation, changed a node transform + this._dirty = false; // true when the model was transformed this frame + this._maxDirtyNumber = 0; // Used in place of a dirty boolean flag to avoid an extra graph traversal - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - EllipseGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + this._runtime = { + animations : undefined, + rootNodes : undefined, + nodes : undefined, // Indexed with the node property's name, i.e., glTF id + nodesByName : undefined, // Indexed with name property in the node + skinnedNodes : undefined, + meshesByName : undefined, // Indexed with the name property in the mesh + materialsByName : undefined, // Indexed with the name property in the material + materialsById : undefined // Indexed with the material's property name + }; - EllipseGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'ellipse')) { - return; - } + this._uniformMaps = {}; // Not cached since it can be targeted by glTF animation + this._extensionsUsed = undefined; // Cached used glTF extensions + this._extensionsRequired = undefined; // Cached required glTF extensions + this._quantizedUniforms = {}; // Quantized uniforms for each program for WEB3D_quantized_attributes + this._programPrimitives = {}; + this._rendererResources = { // Cached between models with the same url/cache-key + buffers : {}, + vertexArrays : {}, + programs : {}, + pickPrograms : {}, + silhouettePrograms : {}, + textures : {}, + samplers : {}, + renderStates : {} + }; + this._cachedRendererResources = undefined; + this._loadRendererResourcesFromCache = false; + this._updatedGltfVersion = false; - var ellipse = this._entity.ellipse; + this._cachedGeometryByteLength = 0; + this._cachedTexturesByteLength = 0; + this._geometryByteLength = 0; + this._texturesByteLength = 0; + this._trianglesLength = 0; - if (!defined(ellipse)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + this._nodeCommands = []; + this._pickIds = []; - var fillProperty = ellipse.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + // CESIUM_RTC extension + this._rtcCenter = undefined; // reference to either 3D or 2D + this._rtcCenterEye = undefined; // in eye coordinates + this._rtcCenter3D = undefined; // in world coordinates + this._rtcCenter2D = undefined; // in projected world coordinates - var outlineProperty = ellipse.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); - } + this._packedClippingPlanes = []; + } - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + defineProperties(Model.prototype, { + /** + * The object for the glTF JSON, including properties with default values omitted + * from the JSON provided to this model. + * + * @memberof Model.prototype + * + * @type {Object} + * @readonly + * + * @default undefined + */ + gltf : { + get : function() { + return defined(this._cachedGltf) ? this._cachedGltf.gltf : undefined; } - return; - } - - var position = this._entity.position; - var semiMajorAxis = ellipse.semiMajorAxis; - var semiMinorAxis = ellipse.semiMinorAxis; + }, - var show = ellipse.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(position) || !defined(semiMajorAxis) || !defined(semiMinorAxis))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + /** + * When <code>true</code>, the glTF JSON is not stored with the model once the model is + * loaded (when {@link Model#ready} is <code>true</code>). This saves memory when + * geometry, textures, and animations are embedded in the .gltf file, which is the + * default for the {@link https://cesiumjs.org/convertmodel.html|Cesium model converter}. + * This is especially useful for cases like 3D buildings, where each .gltf model is unique + * and caching the glTF JSON is not effective. + * + * @memberof Model.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + * + * @private + */ + releaseGltfJson : { + get : function() { + return this._releaseGltfJson; } - return; - } - - var material = defaultValue(ellipse.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(ellipse.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(ellipse.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(ellipse.distanceDisplayCondition, defaultDistanceDisplayCondition); - - var rotation = ellipse.rotation; - var height = ellipse.height; - var extrudedHeight = ellipse.extrudedHeight; - var granularity = ellipse.granularity; - var stRotation = ellipse.stRotation; - var outlineWidth = ellipse.outlineWidth; - var numberOfVerticalLines = ellipse.numberOfVerticalLines; - var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && - isColorMaterial && GroundPrimitive.isSupported(this._scene); - - if (outlineEnabled && onTerrain) { - oneTimeWarning(oneTimeWarning.geometryOutlines); - outlineEnabled = false; - } - - this._fillEnabled = fillEnabled; - this._onTerrain = onTerrain; - this._isClosed = defined(extrudedHeight) || onTerrain; - this._outlineEnabled = outlineEnabled; + }, - if (!position.isConstant || // - !semiMajorAxis.isConstant || // - !semiMinorAxis.isConstant || // - !Property.isConstant(rotation) || // - !Property.isConstant(height) || // - !Property.isConstant(extrudedHeight) || // - !Property.isConstant(granularity) || // - !Property.isConstant(stRotation) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(numberOfVerticalLines) || // - (onTerrain && !Property.isConstant(material))) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + /** + * The key identifying this model in the model cache for glTF JSON, renderer resources, and animations. + * Caching saves memory and improves loading speed when several models with the same url are created. + * <p> + * This key is automatically generated when the model is created with {@link Model.fromGltf}. If the model + * is created directly from glTF JSON using the {@link Model} constructor, this key can be manually + * provided; otherwise, the model will not be changed. + * </p> + * + * @memberof Model.prototype + * + * @type {String} + * @readonly + * + * @private + */ + cacheKey : { + get : function() { + return this._cacheKey; } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.center = position.getValue(Iso8601.MINIMUM_VALUE, options.center); - options.semiMajorAxis = semiMajorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMajorAxis); - options.semiMinorAxis = semiMinorAxis.getValue(Iso8601.MINIMUM_VALUE, options.semiMinorAxis); - options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.numberOfVerticalLines = defined(numberOfVerticalLines) ? numberOfVerticalLines.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); - } - }; - - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @param {PrimitiveCollection} groundPrimitives The ground primitives collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - EllipseGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); - } - - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); - } - - return new DynamicGeometryUpdater(primitives, groundPrimitives, this); - }; - - /** - * @private - */ - function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { - this._primitives = primitives; - this._groundPrimitives = groundPrimitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); - } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var geometryUpdater = this._geometryUpdater; - var onTerrain = geometryUpdater._onTerrain; - - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._outlinePrimitive = undefined; - } - this._primitive = undefined; - - - var entity = geometryUpdater._entity; - var ellipse = entity.ellipse; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(ellipse.show, time, true)) { - return; - } - - var options = this._options; - var center = Property.getValueOrUndefined(entity.position, time, options.center); - var semiMajorAxis = Property.getValueOrUndefined(ellipse.semiMajorAxis, time); - var semiMinorAxis = Property.getValueOrUndefined(ellipse.semiMinorAxis, time); - if (!defined(center) || !defined(semiMajorAxis) || !defined(semiMinorAxis)) { - return; - } - - options.center = center; - options.semiMajorAxis = semiMajorAxis; - options.semiMinorAxis = semiMinorAxis; - options.rotation = Property.getValueOrUndefined(ellipse.rotation, time); - options.height = Property.getValueOrUndefined(ellipse.height, time); - options.extrudedHeight = Property.getValueOrUndefined(ellipse.extrudedHeight, time); - options.granularity = Property.getValueOrUndefined(ellipse.granularity, time); - options.stRotation = Property.getValueOrUndefined(ellipse.stRotation, time); - options.numberOfVerticalLines = Property.getValueOrUndefined(ellipse.numberOfVerticalLines, time); - - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); - - var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - - if (Property.getValueOrDefault(ellipse.fill, time, true)) { - var fillMaterialProperty = geometryUpdater.fillMaterialProperty; - var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); - this._material = material; - - if (onTerrain) { - var currentColor = Color.WHITE; - if (defined(fillMaterialProperty.color)) { - currentColor = fillMaterialProperty.color.getValue(time); - } - - this._primitive = groundPrimitives.add(new GroundPrimitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new EllipseGeometry(options), - attributes: { - color: ColorGeometryInstanceAttribute.fromColor(currentColor), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - asynchronous : false, - shadows : shadows - })); - } else { - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : defined(options.extrudedHeight) - }); - options.vertexFormat = appearance.vertexFormat; + }, - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new EllipseGeometry(options) - }), - attributes : { - distanceDisplayCondition : distanceDisplayConditionAttribute - }, - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + /** + * The base path that paths in the glTF JSON are relative to. The base + * path is the same path as the path containing the .gltf file + * minus the .gltf file, when binary, image, and shader files are + * in the same directory as the .gltf. When this is <code>''</code>, + * the app's base path is used. + * + * @memberof Model.prototype + * + * @type {String} + * @readonly + * + * @default '' + */ + basePath : { + get : function() { + return this._resource.url; } - } - - if (!onTerrain && Property.getValueOrDefault(ellipse.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - - var outlineColor = Property.getValueOrClonedDefault(ellipse.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(ellipse.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; - - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new EllipseOutlineGeometry(options), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) - } - }), - asynchronous : false, - shadows : shadows - })); - } - }; - - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; - - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; - - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (this._geometryUpdater._onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - } - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; - - return EllipseGeometryUpdater; -}); + }, -define('DataSources/EllipsoidGeometryUpdater',[ - '../Core/Cartesian3', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/EllipsoidGeometry', - '../Core/EllipsoidOutlineGeometry', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/Matrix4', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/SceneMode', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' - ], function( - Cartesian3, - Color, - ColorGeometryInstanceAttribute, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - EllipsoidGeometry, - EllipsoidOutlineGeometry, - Event, - GeometryInstance, - Iso8601, - Matrix4, - ShowGeometryInstanceAttribute, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - SceneMode, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { - 'use strict'; + /** + * The model's bounding sphere in its local coordinate system. This does not take into + * account glTF animations and skins nor does it take into account {@link Model#minimumPixelSize}. + * + * @memberof Model.prototype + * + * @type {BoundingSphere} + * @readonly + * + * @default undefined + * + * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * + * @example + * // Center in WGS84 coordinates + * var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3()); + */ + boundingSphere : { + get : function() { + if (this._state !== ModelState.LOADED) { + throw new DeveloperError('The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.'); + } + + var modelMatrix = this.modelMatrix; + if ((this.heightReference !== HeightReference.NONE) && this._clampedModelMatrix) { + modelMatrix = this._clampedModelMatrix; + } - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var nonUniformScale = Matrix4.getScale(modelMatrix, boundingSphereCartesian3Scratch); + var scale = defined(this.maximumScale) ? Math.min(this.maximumScale, this.scale) : this.scale; + Cartesian3.multiplyByScalar(nonUniformScale, scale, nonUniformScale); - var radiiScratch = new Cartesian3(); - var scratchColor = new Color(); - var unitSphere = new Cartesian3(1, 1, 1); + var scaledBoundingSphere = this._scaledBoundingSphere; + scaledBoundingSphere.center = Cartesian3.multiplyComponents(this._boundingSphere.center, nonUniformScale, scaledBoundingSphere.center); + scaledBoundingSphere.radius = Cartesian3.maximumComponent(nonUniformScale) * this._initialRadius; - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.radii = undefined; - this.stackPartitions = undefined; - this.slicePartitions = undefined; - this.subdivisions = undefined; - } + if (defined(this._rtcCenter)) { + Cartesian3.add(this._rtcCenter, scaledBoundingSphere.center, scaledBoundingSphere.center); + } - /** - * A {@link GeometryUpdater} for ellipsoids. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias EllipsoidGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function EllipsoidGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); - } - - this._scene = scene; - this._entity = entity; - this._entitySubscription = entity.definitionChanged.addEventListener(EllipsoidGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'ellipsoid', entity.ellipsoid, undefined); - } + return scaledBoundingSphere; + } + }, - defineProperties(EllipsoidGeometryUpdater, { /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof EllipsoidGeometryUpdater - * @type {Appearance} + * When <code>true</code>, this model is ready to render, i.e., the external binary, image, + * and shader files were downloaded and the WebGL resources were created. This is set to + * <code>true</code> right before {@link Model#readyPromise} is resolved. + * + * @memberof Model.prototype + * + * @type {Boolean} + * @readonly + * + * @default false */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance + ready : { + get : function() { + return this._ready; + } }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof EllipsoidGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance - } - }); - defineProperties(EllipsoidGeometryUpdater.prototype, { /** - * Gets the entity associated with this geometry. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the promise that will be resolved when this model is ready to render, i.e., when the external binary, image, + * and shader files were downloaded and the WebGL resources were created. + * <p> + * This promise is resolved at the end of the frame before the first frame the model is rendered in. + * </p> * - * @type {Entity} + * @memberof Model.prototype + * @type {Promise.<Model>} * @readonly + * + * @example + * // Play all animations at half-speed when the model is ready to render + * Cesium.when(model.readyPromise).then(function(model) { + * model.activeAnimations.addAll({ + * speedup : 0.5 + * }); + * }).otherwise(function(error){ + * window.alert(error); + * }); + * + * @see Model#ready */ - entity : { + readyPromise : { get : function() { - return this._entity; + return this._readyPromise.promise; } }, + /** - * Gets a value indicating if the geometry has a fill component. - * @memberof EllipsoidGeometryUpdater.prototype + * Determines if model WebGL resource creation will be spread out over several frames or + * block until completion once all glTF files are loaded. + * + * @memberof Model.prototype * * @type {Boolean} * @readonly + * + * @default true */ - fillEnabled : { + asynchronous : { get : function() { - return this._fillEnabled; + return this._asynchronous; } }, + /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof EllipsoidGeometryUpdater.prototype + * When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * + * @memberof Model.prototype * * @type {Boolean} * @readonly + * + * @default true */ - hasConstantFill : { + allowPicking : { get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); + return this._allowPicking; } }, + /** - * Gets the material property used to fill the geometry. - * @memberof EllipsoidGeometryUpdater.prototype + * Determine if textures may continue to stream in after the model is loaded. * - * @type {MaterialProperty} + * @memberof Model.prototype + * + * @type {Boolean} * @readonly + * + * @default true */ - fillMaterialProperty : { + incrementallyLoadTextures : { get : function() { - return this._materialProperty; + return this._incrementallyLoadTextures; } }, + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof EllipsoidGeometryUpdater.prototype + * Return the number of pending texture loads. * - * @type {Boolean} + * @memberof Model.prototype + * + * @type {Number} * @readonly */ - outlineEnabled : { + pendingTextureLoads : { get : function() { - return this._outlineEnabled; + return defined(this._loadResources) ? this._loadResources.pendingTextureLoads : 0; } }, + /** - * Gets a value indicating if outline visibility varies with simulation time. - * @memberof EllipsoidGeometryUpdater.prototype + * Returns true if the model was transformed this frame + * + * @memberof Model.prototype * * @type {Boolean} * @readonly + * + * @private */ - hasConstantOutline : { + dirty : { get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); + return this._dirty; } }, + /** - * Gets the {@link Color} property for the geometry outline. - * @memberof EllipsoidGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * Gets or sets the condition specifying at what distance from the camera that this model will be displayed. + * @memberof Model.prototype + * @type {DistanceDisplayCondition} + * @default undefined */ - outlineColorProperty : { + distanceDisplayCondition : { get : function() { - return this._outlineColorProperty; + return this._distanceDisplayCondition; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far must be greater than near'); + } + this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); + } + }, + + extensionsUsed : { + get : function() { + if (!defined(this._extensionsUsed)) { + this._extensionsUsed = ModelUtility.getUsedExtensions(this.gltf); + } + return this._extensionsUsed; } }, + + extensionsRequired : { + get : function() { + if (!defined(this._extensionsRequired)) { + this._extensionsRequired = ModelUtility.getRequiredExtensions(this.gltf); + } + return this._extensionsRequired; + } + }, + /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the model's up-axis. + * By default models are y-up according to the glTF spec, however geo-referenced models will typically be z-up. + * + * @memberof Model.prototype * * @type {Number} + * @default Axis.Y * @readonly + * + * @private */ - outlineWidth : { + upAxis : { get : function() { - return this._outlineWidth; + return this._upAxis; } }, + /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the model's triangle count. * - * @type {Property} - * @readonly + * @private */ - shadowsProperty : { + trianglesLength : { get : function() { - return this._shadowsProperty; + return this._trianglesLength; } }, + /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the model's geometry memory in bytes. This includes all vertex and index buffers. * - * @type {Property} - * @readonly + * @private */ - distanceDisplayConditionProperty : { + geometryByteLength : { get : function() { - return this._distanceDisplayConditionProperty; + return this._geometryByteLength; } }, + /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the model's texture memory in bytes. * - * @type {Boolean} - * @readonly + * @private */ - isDynamic : { + texturesByteLength : { get : function() { - return this._dynamic; + return this._texturesByteLength; } }, + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the model's cached geometry memory in bytes. This includes all vertex and index buffers. * - * @type {Boolean} - * @readonly + * @private */ - isClosed : { - value : true + cachedGeometryByteLength : { + get : function() { + return this._cachedGeometryByteLength; + } }, + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof EllipsoidGeometryUpdater.prototype + * Gets the model's cached texture memory in bytes. * - * @type {Boolean} - * @readonly + * @private */ - geometryChanged : { + cachedTexturesByteLength : { get : function() { - return this._geometryChanged; + return this._cachedTexturesByteLength; + } + } + }); + + function silhouetteSupported(context) { + return context.stencilBuffer; + } + + /** + * Determines if silhouettes are supported. + * + * @param {Scene} scene The scene. + * @returns {Boolean} <code>true</code> if silhouettes are supported; otherwise, returns <code>false</code> + */ + Model.silhouetteSupported = function(scene) { + return silhouetteSupported(scene.context); + }; + + function containsGltfMagic(uint8Array) { + var magic = getMagic(uint8Array); + return magic === 'glTF'; + } + + /** + * <p> + * Creates a model from a glTF asset. When the model is ready to render, i.e., when the external binary, image, + * and shader files are downloaded and the WebGL resources are created, the {@link Model#readyPromise} is resolved. + * </p> + * <p> + * The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the + * KHR_binary_glTF extension with a .glb extension. + * </p> + * <p> + * For high-precision rendering, Cesium supports the CESIUM_RTC extension, which introduces the + * CESIUM_RTC_MODELVIEW parameter semantic that says the node is in WGS84 coordinates translated + * relative to a local origin. + * </p> + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url to the .gltf file. + * @param {Resource|String} [options.basePath] The base path that paths in the glTF JSON are relative to. + * @param {Boolean} [options.show=true] Determines if the model primitive will be shown. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. + * @param {Number} [options.scale=1.0] A uniform scale applied to this model. + * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. + * @param {Number} [options.maximumScale] The maximum scale for the model. + * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}. + * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. + * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each {@link DrawCommand} in the model. + * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. + * @param {HeightReference} [options.heightReference] Determines how the model is drawn relative to terrain. + * @param {Scene} [options.scene] Must be passed in for models that use the height reference property. + * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. + * @param {Color} [options.color=Color.WHITE] A color that blends with the model's rendered color. + * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. + * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. + * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. + * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. Clipping planes are not currently supported in Internet Explorer. + * + * @returns {Model} The newly created model. + * + * @exception {DeveloperError} bgltf is not a valid Binary glTF file. + * @exception {DeveloperError} Only glTF Binary version 1 is supported. + * + * @example + * // Example 1. Create a model from a glTF asset + * var model = scene.primitives.add(Cesium.Model.fromGltf({ + * url : './duck/duck.gltf' + * })); + * + * @example + * // Example 2. Create model and provide all properties and events + * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); + * var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); + * + * var model = scene.primitives.add(Cesium.Model.fromGltf({ + * url : './duck/duck.gltf', + * show : true, // default + * modelMatrix : modelMatrix, + * scale : 2.0, // double size + * minimumPixelSize : 128, // never smaller than 128 pixels + * maximumScale: 20000, // never larger than 20000 * model size (overrides minimumPixelSize) + * allowPicking : false, // not pickable + * debugShowBoundingVolume : false, // default + * debugWireframe : false + * })); + * + * model.readyPromise.then(function(model) { + * // Play all animations when the model is ready to render + * model.activeAnimations.addAll(); + * }); + */ + Model.fromGltf = function(options) { + if (!defined(options) || !defined(options.url)) { + throw new DeveloperError('options.url is required'); + } + + if (defined(options.headers)) { + deprecationWarning('Model.fromGltf.headers', 'The options.headers parameter has been deprecated. Specify options.url as a Resource instance and set the headers property there.'); + } + + var url = options.url; + options = clone(options); + + // Create resource for the model file + var modelResource = Resource.createIfNeeded(url, { + headers : options.headers + }); + + // Setup basePath to get dependent files + var basePath = defaultValue(options.basePath, modelResource.clone()); + var resource = Resource.createIfNeeded(basePath, { + headers : options.headers + }); + + // If no cache key is provided, use the absolute URL, since two URLs with + // different relative paths could point to the same model. + var cacheKey = defaultValue(options.cacheKey, getAbsoluteUri(modelResource.url)); + if (defined(options.basePath) && !defined(options.cacheKey)) { + cacheKey += resource.url; + } + options.cacheKey = cacheKey; + options.basePath = resource; + + var model = new Model(options); + + var cachedGltf = gltfCache[cacheKey]; + if (!defined(cachedGltf)) { + cachedGltf = new CachedGltf({ + ready : false + }); + cachedGltf.count = 1; + cachedGltf.modelsToLoad.push(model); + setCachedGltf(model, cachedGltf); + gltfCache[cacheKey] = cachedGltf; + + // Add Accept header if we need it + if (!defined(modelResource.headers.Accept)) { + modelResource.headers.Accept = defaultModelAccept; + } + + modelResource.fetchArrayBuffer().then(function(arrayBuffer) { + var array = new Uint8Array(arrayBuffer); + if (containsGltfMagic(array)) { + // Load binary glTF + var parsedGltf = parseBinaryGltf(array); + // KHR_binary_glTF is from the beginning of the binary section + cachedGltf.makeReady(parsedGltf, array); + } else { + // Load text (JSON) glTF + var json = getStringFromTypedArray(array); + cachedGltf.makeReady(JSON.parse(json)); + } + }).otherwise(getFailedLoadFunction(model, 'model', url)); + } else if (!cachedGltf.ready) { + // Cache hit but the fetchArrayBuffer() or fetchText() request is still pending + ++cachedGltf.count; + cachedGltf.modelsToLoad.push(model); + } + // else if the cached glTF is defined and ready, the + // model constructor will pick it up using the cache key. + + return model; + }; + + /** + * For the unit tests to verify model caching. + * + * @private + */ + Model._gltfCache = gltfCache; + + function getRuntime(model, runtimeName, name) { + if (model._state !== ModelState.LOADED) { + throw new DeveloperError('The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.'); + } + + if (!defined(name)) { + throw new DeveloperError('name is required.'); + } + + return (model._runtime[runtimeName])[name]; + } + + /** + * Returns the glTF node with the given <code>name</code> property. This is used to + * modify a node's transform for animation outside of glTF animations. + * + * @param {String} name The glTF name of the node. + * @returns {ModelNode} The node or <code>undefined</code> if no node with <code>name</code> exists. + * + * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * + * @example + * // Apply non-uniform scale to node LOD3sp + * var node = model.getNode('LOD3sp'); + * node.matrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix); + */ + Model.prototype.getNode = function(name) { + var node = getRuntime(this, 'nodesByName', name); + return defined(node) ? node.publicNode : undefined; + }; + + /** + * Returns the glTF mesh with the given <code>name</code> property. + * + * @param {String} name The glTF name of the mesh. + * + * @returns {ModelMesh} The mesh or <code>undefined</code> if no mesh with <code>name</code> exists. + * + * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + */ + Model.prototype.getMesh = function(name) { + return getRuntime(this, 'meshesByName', name); + }; + + /** + * Returns the glTF material with the given <code>name</code> property. + * + * @param {String} name The glTF name of the material. + * @returns {ModelMaterial} The material or <code>undefined</code> if no material with <code>name</code> exists. + * + * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + */ + Model.prototype.getMaterial = function(name) { + return getRuntime(this, 'materialsByName', name); + }; + + var aMinScratch = new Cartesian3(); + var aMaxScratch = new Cartesian3(); + + function computeBoundingSphere(model) { + var gltf = model.gltf; + var gltfNodes = gltf.nodes; + var gltfMeshes = gltf.meshes; + var rootNodes = gltf.scenes[gltf.scene].nodes; + var rootNodesLength = rootNodes.length; + + var nodeStack = []; + + var min = new Cartesian3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + var max = new Cartesian3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + + for (var i = 0; i < rootNodesLength; ++i) { + var n = gltfNodes[rootNodes[i]]; + n._transformToRoot = ModelUtility.getTransform(n); + nodeStack.push(n); + + while (nodeStack.length > 0) { + n = nodeStack.pop(); + var transformToRoot = n._transformToRoot; + + var meshId = n.mesh; + if (defined(meshId)) { + var mesh = gltfMeshes[meshId]; + var primitives = mesh.primitives; + var primitivesLength = primitives.length; + for (var m = 0; m < primitivesLength; ++m) { + var positionAccessor = primitives[m].attributes.POSITION; + if (defined(positionAccessor)) { + var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor); + var aMin = Cartesian3.fromArray(minMax.min, 0, aMinScratch); + var aMax = Cartesian3.fromArray(minMax.max, 0, aMaxScratch); + if (defined(min) && defined(max)) { + Matrix4.multiplyByPoint(transformToRoot, aMin, aMin); + Matrix4.multiplyByPoint(transformToRoot, aMax, aMax); + Cartesian3.minimumByComponent(min, aMin, min); + Cartesian3.maximumByComponent(max, aMax, max); + } + } + } + } + + var children = n.children; + var childrenLength = children.length; + for (var k = 0; k < childrenLength; ++k) { + var child = gltfNodes[children[k]]; + child._transformToRoot = ModelUtility.getTransform(child); + Matrix4.multiplyTransformation(transformToRoot, child._transformToRoot, child._transformToRoot); + nodeStack.push(child); + } + delete n._transformToRoot; + } + } + + var boundingSphere = BoundingSphere.fromCornerPoints(min, max); + if (model._upAxis === Axis.Y) { + BoundingSphere.transformWithoutScale(boundingSphere, Axis.Y_UP_TO_Z_UP, boundingSphere); + } else if (model._upAxis === Axis.X) { + BoundingSphere.transformWithoutScale(boundingSphere, Axis.X_UP_TO_Z_UP, boundingSphere); + } + return boundingSphere; + } + + /////////////////////////////////////////////////////////////////////////// + + function getFailedLoadFunction(model, type, path) { + return function() { + model._state = ModelState.FAILED; + model._readyPromise.reject(new RuntimeError('Failed to load ' + type + ': ' + path)); + }; + } + + function addBuffersToLoadResources(model) { + var gltf = model.gltf; + var loadResources = model._loadResources; + ForEach.buffer(gltf, function(buffer, id) { + loadResources.buffers[id] = buffer.extras._pipeline.source; + }); + } + + function bufferLoad(model, id) { + return function(arrayBuffer) { + var loadResources = model._loadResources; + var buffer = new Uint8Array(arrayBuffer); + --loadResources.pendingBufferLoads; + model.gltf.buffers[id].extras._pipeline.source = buffer; + }; + } + + function parseBuffers(model) { + var loadResources = model._loadResources; + // Iterate this way for compatibility with objects and arrays + var buffers = model.gltf.buffers; + for (var id in buffers) { + if (buffers.hasOwnProperty(id)) { + var buffer = buffers[id]; + buffer.extras = defaultValue(buffer.extras, {}); + buffer.extras._pipeline = defaultValue(buffer.extras._pipeline, {}); + if (defined(buffer.extras._pipeline.source)) { + loadResources.buffers[id] = buffer.extras._pipeline.source; + } else { + var bufferResource = model._resource.getDerivedResource({ + url : buffer.uri + }); + ++loadResources.pendingBufferLoads; + bufferResource.fetchArrayBuffer().then(bufferLoad(model, id)).otherwise(getFailedLoadFunction(model, 'buffer', bufferResource.url)); + } + } + } + } + + function parseBufferViews(model) { + var bufferViews = model.gltf.bufferViews; + + var vertexBuffersToCreate = model._loadResources.vertexBuffersToCreate; + + // Only ARRAY_BUFFER here. ELEMENT_ARRAY_BUFFER created below. + ForEach.bufferView(model.gltf, function(bufferView, id) { + if (bufferView.target === WebGLConstants.ARRAY_BUFFER) { + vertexBuffersToCreate.enqueue(id); + } + }); + + var indexBuffersToCreate = model._loadResources.indexBuffersToCreate; + var indexBufferIds = {}; + + // The Cesium Renderer requires knowing the datatype for an index buffer + // at creation type, which is not part of the glTF bufferview so loop + // through glTF accessors to create the bufferview's index buffer. + ForEach.accessor(model.gltf, function(accessor) { + var bufferViewId = accessor.bufferView; + var bufferView = bufferViews[bufferViewId]; + + if ((bufferView.target === WebGLConstants.ELEMENT_ARRAY_BUFFER) && !defined(indexBufferIds[bufferViewId])) { + indexBufferIds[bufferViewId] = true; + indexBuffersToCreate.enqueue({ + id : bufferViewId, + componentType : accessor.componentType + }); + } + }); + } + + function shaderLoad(model, type, id) { + return function(source) { + var loadResources = model._loadResources; + loadResources.shaders[id] = { + source : source, + type : type, + bufferView : undefined + }; + --loadResources.pendingShaderLoads; + model.gltf.shaders[id].extras._pipeline.source = source; + }; + } + + function parseShaders(model) { + var gltf = model.gltf; + var buffers = gltf.buffers; + var bufferViews = gltf.bufferViews; + ForEach.shader(gltf, function(shader, id) { + // Shader references either uri (external or base64-encoded) or bufferView + if (defined(shader.bufferView)) { + var bufferViewId = shader.bufferView; + var bufferView = bufferViews[bufferViewId]; + var bufferId = bufferView.buffer; + var buffer = buffers[bufferId]; + var source = getStringFromTypedArray(buffer.extras._pipeline.source, bufferView.byteOffset, bufferView.byteLength); + model._loadResources.shaders[id] = { + source : source, + bufferView : undefined + }; + shader.extras._pipeline.source = source; + } else if (defined(shader.extras._pipeline.source)) { + model._loadResources.shaders[id] = { + source : shader.extras._pipeline.source, + bufferView : undefined + }; + } else { + ++model._loadResources.pendingShaderLoads; + + var shaderResource = model._resource.getDerivedResource({ + url : shader.uri + }); + + shaderResource.fetchText().then(shaderLoad(model, shader.type, id)).otherwise(getFailedLoadFunction(model, 'shader', shaderResource.url)); + } + }); + } + + function parsePrograms(model) { + ForEach.program(model.gltf, function(program, id) { + model._loadResources.programsToCreate.enqueue(id); + }); + } + + function imageLoad(model, textureId, imageId) { + return function(image) { + var gltf = model.gltf; + var loadResources = model._loadResources; + --loadResources.pendingTextureLoads; + loadResources.texturesToCreate.enqueue({ + id : textureId, + image : image, + bufferView : image.bufferView, + width : image.width, + height : image.height, + internalFormat : image.internalFormat + }); + gltf.images[imageId].extras._pipeline.source = image; + }; + } + + var ktxRegex = /(^data:image\/ktx)|(\.ktx$)/i; + var crnRegex = /(^data:image\/crn)|(\.crn$)/i; + + function parseTextures(model, context) { + var gltf = model.gltf; + var images = gltf.images; + var uri; + ForEach.texture(gltf, function(texture, id) { + var imageId = texture.source; + var gltfImage = images[imageId]; + var extras = gltfImage.extras; + + var bufferViewId = gltfImage.bufferView; + var mimeType = gltfImage.mimeType; + uri = gltfImage.uri; + + // First check for a compressed texture + if (defined(extras) && defined(extras.compressedImage3DTiles)) { + var crunch = extras.compressedImage3DTiles.crunch; + var s3tc = extras.compressedImage3DTiles.s3tc; + var pvrtc = extras.compressedImage3DTiles.pvrtc1; + var etc1 = extras.compressedImage3DTiles.etc1; + + if (context.s3tc && defined(crunch)) { + mimeType = crunch.mimeType; + if (defined(crunch.bufferView)) { + bufferViewId = crunch.bufferView; + } else { + uri = crunch.uri; + } + } else if (context.s3tc && defined(s3tc)) { + mimeType = s3tc.mimeType; + if (defined(s3tc.bufferView)) { + bufferViewId = s3tc.bufferView; + } else { + uri = s3tc.uri; + } + } else if (context.pvrtc && defined(pvrtc)) { + mimeType = pvrtc.mimeType; + if (defined(pvrtc.bufferView)) { + bufferViewId = pvrtc.bufferView; + } else { + uri = pvrtc.uri; + } + } else if (context.etc1 && defined(etc1)) { + mimeType = etc1.mimeType; + if (defined(etc1.bufferView)) { + bufferViewId = etc1.bufferView; + } else { + uri = etc1.uri; + } + } + } + + // Image references either uri (external or base64-encoded) or bufferView + if (defined(bufferViewId)) { + model._loadResources.texturesToCreateFromBufferView.enqueue({ + id : id, + image : undefined, + bufferView : bufferViewId, + mimeType : mimeType + }); + } else { + ++model._loadResources.pendingTextureLoads; + + var imageResource = model._resource.getDerivedResource({ + url : uri + }); + + var promise; + if (ktxRegex.test(uri)) { + promise = loadKTX(imageResource); + } else if (crnRegex.test(uri)) { + promise = loadCRN(imageResource); + } else { + promise = imageResource.fetchImage(); + } + promise.then(imageLoad(model, id, imageId)).otherwise(getFailedLoadFunction(model, 'image', imageResource.url)); + } + }); + } + + function parseNodes(model) { + var runtimeNodes = {}; + var runtimeNodesByName = {}; + var skinnedNodes = []; + + var skinnedNodesIds = model._loadResources.skinnedNodesIds; + + ForEach.node(model.gltf, function(node, id) { + var runtimeNode = { + // Animation targets + matrix : undefined, + translation : undefined, + rotation : undefined, + scale : undefined, + + // Per-node show inherited from parent + computedShow : true, + + // Computed transforms + transformToRoot : new Matrix4(), + computedMatrix : new Matrix4(), + dirtyNumber : 0, // The frame this node was made dirty by an animation; for graph traversal + + // Rendering + commands : [], // empty for transform, light, and camera nodes + + // Skinned node + inverseBindMatrices : undefined, // undefined when node is not skinned + bindShapeMatrix : undefined, // undefined when node is not skinned or identity + joints : [], // empty when node is not skinned + computedJointMatrices : [], // empty when node is not skinned + + // Joint node + jointName : node.jointName, // undefined when node is not a joint + + weights : [], + + // Graph pointers + children : [], // empty for leaf nodes + parents : [], // empty for root nodes + + // Publicly-accessible ModelNode instance to modify animation targets + publicNode : undefined + }; + runtimeNode.publicNode = new ModelNode(model, node, runtimeNode, id, ModelUtility.getTransform(node)); + + runtimeNodes[id] = runtimeNode; + runtimeNodesByName[node.name] = runtimeNode; + + if (defined(node.skin)) { + skinnedNodesIds.push(id); + skinnedNodes.push(runtimeNode); + } + }); + + model._runtime.nodes = runtimeNodes; + model._runtime.nodesByName = runtimeNodesByName; + model._runtime.skinnedNodes = skinnedNodes; + } + + function parseMaterials(model) { + var runtimeMaterialsByName = {}; + var runtimeMaterialsById = {}; + var uniformMaps = model._uniformMaps; + + ForEach.material(model.gltf, function(material, id) { + // Allocated now so ModelMaterial can keep a reference to it. + uniformMaps[id] = { + uniformMap : undefined, + values : undefined, + jointMatrixUniformName : undefined, + morphWeightsUniformName : undefined + }; + + var modelMaterial = new ModelMaterial(model, material, id); + runtimeMaterialsByName[material.name] = modelMaterial; + runtimeMaterialsById[id] = modelMaterial; + }); + + model._runtime.materialsByName = runtimeMaterialsByName; + model._runtime.materialsById = runtimeMaterialsById; + } + + function parseMeshes(model) { + var runtimeMeshesByName = {}; + var runtimeMaterialsById = model._runtime.materialsById; + + ForEach.mesh(model.gltf, function(mesh, id) { + runtimeMeshesByName[mesh.name] = new ModelMesh(mesh, runtimeMaterialsById, id); + if (defined(model.extensionsUsed.WEB3D_quantized_attributes)) { + // Cache primitives according to their program + var primitives = mesh.primitives; + var primitivesLength = primitives.length; + for (var i = 0; i < primitivesLength; i++) { + var primitive = primitives[i]; + var programId = getProgramForPrimitive(model, primitive); + var programPrimitives = model._programPrimitives[programId]; + if (!defined(programPrimitives)) { + programPrimitives = []; + model._programPrimitives[programId] = programPrimitives; + } + programPrimitives.push(primitive); + } + } + }); + + model._runtime.meshesByName = runtimeMeshesByName; + } + + /////////////////////////////////////////////////////////////////////////// + + var CreateVertexBufferJob = function() { + this.id = undefined; + this.model = undefined; + this.context = undefined; + }; + + CreateVertexBufferJob.prototype.set = function(id, model, context) { + this.id = id; + this.model = model; + this.context = context; + }; + + CreateVertexBufferJob.prototype.execute = function() { + createVertexBuffer(this.id, this.model, this.context); + }; + + /////////////////////////////////////////////////////////////////////////// + + function createVertexBuffer(bufferViewId, model, context) { + var loadResources = model._loadResources; + var bufferViews = model.gltf.bufferViews; + var bufferView = bufferViews[bufferViewId]; + + var vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : loadResources.getBuffer(bufferView), + usage : BufferUsage.STATIC_DRAW + }); + vertexBuffer.vertexArrayDestroyable = false; + model._rendererResources.buffers[bufferViewId] = vertexBuffer; + model._geometryByteLength += vertexBuffer.sizeInBytes; + } + + /////////////////////////////////////////////////////////////////////////// + + var CreateIndexBufferJob = function() { + this.id = undefined; + this.componentType = undefined; + this.model = undefined; + this.context = undefined; + }; + + CreateIndexBufferJob.prototype.set = function(id, componentType, model, context) { + this.id = id; + this.componentType = componentType; + this.model = model; + this.context = context; + }; + + CreateIndexBufferJob.prototype.execute = function() { + createIndexBuffer(this.id, this.componentType, this.model, this.context); + }; + + /////////////////////////////////////////////////////////////////////////// + + function createIndexBuffer(bufferViewId, componentType, model, context) { + var loadResources = model._loadResources; + var bufferViews = model.gltf.bufferViews; + var bufferView = bufferViews[bufferViewId]; + + var indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : loadResources.getBuffer(bufferView), + usage : BufferUsage.STATIC_DRAW, + indexDatatype : componentType + }); + indexBuffer.vertexArrayDestroyable = false; + model._rendererResources.buffers[bufferViewId] = indexBuffer; + model._geometryByteLength += indexBuffer.sizeInBytes; + } + + var scratchVertexBufferJob = new CreateVertexBufferJob(); + var scratchIndexBufferJob = new CreateIndexBufferJob(); + + function createBuffers(model, frameState) { + var loadResources = model._loadResources; + + if (loadResources.pendingBufferLoads !== 0) { + return; + } + + var context = frameState.context; + var vertexBuffersToCreate = loadResources.vertexBuffersToCreate; + var indexBuffersToCreate = loadResources.indexBuffersToCreate; + var i; + + if (model.asynchronous) { + while (vertexBuffersToCreate.length > 0) { + scratchVertexBufferJob.set(vertexBuffersToCreate.peek(), model, context); + if (!frameState.jobScheduler.execute(scratchVertexBufferJob, JobType.BUFFER)) { + break; + } + vertexBuffersToCreate.dequeue(); + } + + while (indexBuffersToCreate.length > 0) { + i = indexBuffersToCreate.peek(); + scratchIndexBufferJob.set(i.id, i.componentType, model, context); + if (!frameState.jobScheduler.execute(scratchIndexBufferJob, JobType.BUFFER)) { + break; + } + indexBuffersToCreate.dequeue(); + } + } else { + while (vertexBuffersToCreate.length > 0) { + createVertexBuffer(vertexBuffersToCreate.dequeue(), model, context); + } + + while (indexBuffersToCreate.length > 0) { + i = indexBuffersToCreate.dequeue(); + createIndexBuffer(i.id, i.componentType, model, context); + } + } + } + + function createAttributeLocations(model, attributes) { + var attributeLocations = {}; + var length = attributes.length; + var i; + + // Set the position attribute to the 0th index. In some WebGL implementations the shader + // will not work correctly if the 0th attribute is not active. For example, some glTF models + // list the normal attribute first but derived shaders like the cast-shadows shader do not use + // the normal attribute. + for (i = 1; i < length; ++i) { + var attribute = attributes[i]; + if (/pos/i.test(attribute)) { + attributes[i] = attributes[0]; + attributes[0] = attribute; + break; } } - }); - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - EllipsoidGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + for (i = 0; i < length; ++i) { + attributeLocations[attributes[i]] = i; + } - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - EllipsoidGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; + return attributeLocations; + } - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + function getProgramForPrimitive(model, primitive) { + var gltf = model.gltf; + var materialId = primitive.material; + var material = gltf.materials[materialId]; + var techniqueId = material.technique; + var technique = gltf.techniques[techniqueId]; + return technique.program; + } + + function modifyShaderForQuantizedAttributes(shader, programName, model) { + var primitive; + var primitives = model._programPrimitives[programName]; + for (var i = 0; i < primitives.length; i++) { + primitive = primitives[i]; + if (getProgramForPrimitive(model, primitive) === programName) { + break; + } } - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); + var result = ModelUtility.modifyShaderForQuantizedAttributes(model.gltf, primitive, shader); + model._quantizedUniforms[programName] = result.uniforms; + + // This is not needed after the program is processed, free the memory + model._programPrimitives[programName] = undefined; + + return result.shader; + } + + function hasPremultipliedAlpha(model) { + var gltf = model.gltf; + return defined(gltf.asset) ? defaultValue(gltf.asset.premultipliedAlpha, false) : false; + } + + function modifyShaderForColor(shader, premultipliedAlpha) { + shader = ShaderSource.replaceMain(shader, 'gltf_blend_main'); + shader += + 'uniform vec4 gltf_color; \n' + + 'uniform float gltf_colorBlend; \n' + + 'void main() \n' + + '{ \n' + + ' gltf_blend_main(); \n'; + + // Un-premultiply the alpha so that blending is correct. + + // Avoid divide-by-zero. The code below is equivalent to: + // if (gl_FragColor.a > 0.0) + // { + // gl_FragColor.rgb /= gl_FragColor.a; + // } + + if (premultipliedAlpha) { + shader += + ' float alpha = 1.0 - ceil(gl_FragColor.a) + gl_FragColor.a; \n' + + ' gl_FragColor.rgb /= alpha; \n'; } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var attributes; + shader += + ' gl_FragColor.rgb = mix(gl_FragColor.rgb, gltf_color.rgb, gltf_colorBlend); \n' + + ' float highlight = ceil(gltf_colorBlend); \n' + + ' gl_FragColor.rgb *= mix(gltf_color.rgb, vec3(1.0), highlight); \n' + + ' gl_FragColor.a *= gltf_color.a; \n' + + '} \n'; - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; + return shader; + } + + function modifyShader(shader, programName, callback) { + if (defined(callback)) { + shader = callback(shader, programName); } + return shader; + } - return new GeometryInstance({ - id : entity, - geometry : new EllipsoidGeometry(this._options), - modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), - attributes : attributes - }); + var CreateProgramJob = function() { + this.id = undefined; + this.model = undefined; + this.context = undefined; }; - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + CreateProgramJob.prototype.set = function(id, model, context) { + this.id = id; + this.model = model; + this.context = context; + }; + + CreateProgramJob.prototype.execute = function() { + createProgram(this.id, this.model, this.context); + }; + + /////////////////////////////////////////////////////////////////////////// + + function createProgram(id, model, context) { + var programs = model.gltf.programs; + var shaders = model.gltf.shaders; + var program = programs[id]; + + var attributeLocations = createAttributeLocations(model, program.attributes); + var vs = shaders[program.vertexShader].extras._pipeline.source; + var fs = shaders[program.fragmentShader].extras._pipeline.source; + + // Add pre-created attributes to attributeLocations + var attributesLength = program.attributes.length; + var precreatedAttributes = model._precreatedAttributes; + if (defined(precreatedAttributes)) { + for (var attrName in precreatedAttributes) { + if (precreatedAttributes.hasOwnProperty(attrName)) { + attributeLocations[attrName] = attributesLength++; + } + } } - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + if (model.extensionsUsed.WEB3D_quantized_attributes) { + vs = modifyShaderForQuantizedAttributes(vs, id, model); } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var premultipliedAlpha = hasPremultipliedAlpha(model); + var finalFS = modifyShaderForColor(fs, premultipliedAlpha); + if (ClippingPlaneCollection.isSupported()) { + finalFS = modifyShaderForClippingPlanes(finalFS); + } - return new GeometryInstance({ - id : entity, - geometry : new EllipsoidOutlineGeometry(this._options), - modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) - } + var drawVS = modifyShader(vs, id, model._vertexShaderLoaded); + var drawFS = modifyShader(finalFS, id, model._fragmentShaderLoaded); + + model._rendererResources.programs[id] = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : drawVS, + fragmentShaderSource : drawFS, + attributeLocations : attributeLocations }); - }; - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - EllipsoidGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + if (model.allowPicking) { + // PERFORMANCE_IDEA: Can optimize this shader with a glTF hint. https://github.com/KhronosGroup/glTF/issues/181 + var pickVS = modifyShader(vs, id, model._pickVertexShaderLoaded); + var pickFS = modifyShader(fs, id, model._pickFragmentShaderLoaded); - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - EllipsoidGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + if (!model._pickFragmentShaderLoaded) { + pickFS = ShaderSource.createPickFragmentShaderSource(fs, 'uniform'); + } - EllipsoidGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'ellipsoid')) { + model._rendererResources.pickPrograms[id] = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : pickVS, + fragmentShaderSource : pickFS, + attributeLocations : attributeLocations + }); + } + } + + var scratchCreateProgramJob = new CreateProgramJob(); + + function createPrograms(model, frameState) { + var loadResources = model._loadResources; + var programsToCreate = loadResources.programsToCreate; + + if (loadResources.pendingShaderLoads !== 0) { return; } - var ellipsoid = entity.ellipsoid; + // PERFORMANCE_IDEA: this could be more fine-grained by looking + // at the shader's bufferView's to determine the buffer dependencies. + if (loadResources.pendingBufferLoads !== 0) { + return; + } - if (!defined(ellipsoid)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + var context = frameState.context; + + if (model.asynchronous) { + while (programsToCreate.length > 0) { + scratchCreateProgramJob.set(programsToCreate.peek(), model, context); + if (!frameState.jobScheduler.execute(scratchCreateProgramJob, JobType.PROGRAM)) { + break; + } + programsToCreate.dequeue(); + } + } else { + // Create all loaded programs this frame + while (programsToCreate.length > 0) { + createProgram(programsToCreate.dequeue(), model, context); } - return; } + } - var fillProperty = ellipsoid.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + function getOnImageCreatedFromTypedArray(loadResources, gltfTexture) { + return function(image) { + loadResources.texturesToCreate.enqueue({ + id : gltfTexture.id, + image : image, + bufferView : undefined + }); - var outlineProperty = ellipsoid.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + --loadResources.pendingBufferViewToImage; + }; + } + + function loadTexturesFromBufferViews(model) { + var loadResources = model._loadResources; + + if (loadResources.pendingBufferLoads !== 0) { + return; } - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + while (loadResources.texturesToCreateFromBufferView.length > 0) { + var gltfTexture = loadResources.texturesToCreateFromBufferView.dequeue(); + + var gltf = model.gltf; + var bufferView = gltf.bufferViews[gltfTexture.bufferView]; + var imageId = gltf.textures[gltfTexture.id].source; + + var onerror = getFailedLoadFunction(model, 'image', 'id: ' + gltfTexture.id + ', bufferView: ' + gltfTexture.bufferView); + + if (gltfTexture.mimeType === 'image/ktx') { + loadKTX(loadResources.getBuffer(bufferView)).then(imageLoad(model, gltfTexture.id, imageId)).otherwise(onerror); + ++model._loadResources.pendingTextureLoads; + } else if (gltfTexture.mimeType === 'image/crn') { + loadCRN(loadResources.getBuffer(bufferView)).then(imageLoad(model, gltfTexture.id, imageId)).otherwise(onerror); + ++model._loadResources.pendingTextureLoads; + } else { + var onload = getOnImageCreatedFromTypedArray(loadResources, gltfTexture); + loadImageFromTypedArray(loadResources.getBuffer(bufferView), gltfTexture.mimeType) + .then(onload).otherwise(onerror); + ++loadResources.pendingBufferViewToImage; } - return; } + } - var position = entity.position; - var radii = ellipsoid.radii; + function createSamplers(model, context) { + var loadResources = model._loadResources; - var show = ellipsoid.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(position) || !defined(radii))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + if (loadResources.createSamplers) { + loadResources.createSamplers = false; + + var rendererSamplers = model._rendererResources.samplers; + var samplers = model.gltf.samplers; + for (var id in samplers) { + if (samplers.hasOwnProperty(id)) { + var sampler = samplers[id]; + + rendererSamplers[id] = new Sampler({ + wrapS : sampler.wrapS, + wrapT : sampler.wrapT, + minificationFilter : sampler.minFilter, + magnificationFilter : sampler.magFilter + }); + } } - return; } + } - var material = defaultValue(ellipsoid.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(ellipsoid.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(ellipsoid.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(ellipsoid.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(ellipsoid.distanceDisplayCondition, defaultDistanceDisplayCondition); + /////////////////////////////////////////////////////////////////////////// - this._fillEnabled = fillEnabled; - this._outlineEnabled = outlineEnabled; + var CreateTextureJob = function() { + this.gltfTexture = undefined; + this.model = undefined; + this.context = undefined; + }; - var stackPartitions = ellipsoid.stackPartitions; - var slicePartitions = ellipsoid.slicePartitions; - var outlineWidth = ellipsoid.outlineWidth; - var subdivisions = ellipsoid.subdivisions; + CreateTextureJob.prototype.set = function(gltfTexture, model, context) { + this.gltfTexture = gltfTexture; + this.model = model; + this.context = context; + }; - if (!position.isConstant || // - !Property.isConstant(entity.orientation) || // - !radii.isConstant || // - !Property.isConstant(stackPartitions) || // - !Property.isConstant(slicePartitions) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(subdivisions)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + CreateTextureJob.prototype.execute = function() { + createTexture(this.gltfTexture, this.model, this.context); + }; + + /////////////////////////////////////////////////////////////////////////// + + function createTexture(gltfTexture, model, context) { + var textures = model.gltf.textures; + var texture = textures[gltfTexture.id]; + + var rendererSamplers = model._rendererResources.samplers; + var sampler = rendererSamplers[texture.sampler]; + sampler = defaultValue(sampler, new Sampler({ + wrapS : TextureWrap.REPEAT, + wrapT : TextureWrap.REPEAT + })); + + var internalFormat = gltfTexture.internalFormat; + + var mipmap = + (!(defined(internalFormat) && PixelFormat.isCompressedFormat(internalFormat))) && + ((sampler.minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || + (sampler.minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || + (sampler.minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || + (sampler.minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR)); + var requiresNpot = mipmap || + (sampler.wrapS === TextureWrap.REPEAT) || + (sampler.wrapS === TextureWrap.MIRRORED_REPEAT) || + (sampler.wrapT === TextureWrap.REPEAT) || + (sampler.wrapT === TextureWrap.MIRRORED_REPEAT); + + var tx; + var source = gltfTexture.image; + + if (defined(internalFormat) && texture.target === WebGLConstants.TEXTURE_2D) { + tx = new Texture({ + context : context, + source : { + arrayBufferView : gltfTexture.bufferView + }, + width : gltfTexture.width, + height : gltfTexture.height, + pixelFormat : internalFormat, + sampler : sampler + }); + } else if (defined(source)) { + var npot = !CesiumMath.isPowerOfTwo(source.width) || !CesiumMath.isPowerOfTwo(source.height); + + if (requiresNpot && npot) { + // WebGL requires power-of-two texture dimensions for mipmapping and REPEAT/MIRRORED_REPEAT wrap modes. + var canvas = document.createElement('canvas'); + canvas.width = CesiumMath.nextPowerOfTwo(source.width); + canvas.height = CesiumMath.nextPowerOfTwo(source.height); + var canvasContext = canvas.getContext('2d'); + canvasContext.drawImage(source, 0, 0, source.width, source.height, 0, 0, canvas.width, canvas.height); + source = canvas; + } + + if (texture.target === WebGLConstants.TEXTURE_2D) { + tx = new Texture({ + context : context, + source : source, + pixelFormat : texture.internalFormat, + pixelDatatype : texture.type, + sampler : sampler, + flipY : false + }); + // GLTF_SPEC: Support TEXTURE_CUBE_MAP. https://github.com/KhronosGroup/glTF/issues/40 + if (mipmap) { + tx.generateMipmap(); + } + } + } + if (defined(tx)) { + model._rendererResources.textures[gltfTexture.id] = tx; + model._texturesByteLength += tx.sizeInBytes; + } + } + + var scratchCreateTextureJob = new CreateTextureJob(); + + function createTextures(model, frameState) { + var context = frameState.context; + var texturesToCreate = model._loadResources.texturesToCreate; + + if (model.asynchronous) { + while (texturesToCreate.length > 0) { + scratchCreateTextureJob.set(texturesToCreate.peek(), model, context); + if (!frameState.jobScheduler.execute(scratchCreateTextureJob, JobType.TEXTURE)) { + break; + } + texturesToCreate.dequeue(); } } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.radii = radii.getValue(Iso8601.MINIMUM_VALUE, options.radii); - options.stackPartitions = defined(stackPartitions) ? stackPartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.slicePartitions = defined(slicePartitions) ? slicePartitions.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.subdivisions = defined(subdivisions) ? subdivisions.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); + // Create all loaded textures this frame + while (texturesToCreate.length > 0) { + createTexture(texturesToCreate.dequeue(), model, context); + } } - }; + } - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - EllipsoidGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); + function getAttributeLocations(model, primitive) { + var gltf = model.gltf; + var techniques = gltf.techniques; + var materials = gltf.materials; + + // Retrieve the compiled shader program to assign index values to attributes + var attributeLocations = {}; + + var location; + var index; + var technique = techniques[materials[primitive.material].technique]; + var parameters = technique.parameters; + var attributes = technique.attributes; + var program = model._rendererResources.programs[technique.program]; + var programVertexAttributes = program.vertexAttributes; + var programAttributeLocations = program._attributeLocations; + + // Note: WebGL shader compiler may have optimized and removed some attributes from programVertexAttributes + for (location in programVertexAttributes) { + if (programVertexAttributes.hasOwnProperty(location)) { + var attribute = attributes[location]; + index = programVertexAttributes[location].index; + if (defined(attribute)) { + var parameter = parameters[attribute]; + attributeLocations[parameter.semantic] = index; + } + } } - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); + // Always add pre-created attributes. + // Some pre-created attributes, like per-instance pickIds, may be compiled out of the draw program + // but should be included in the list of attribute locations for the pick program. + // This is safe to do since programVertexAttributes and programAttributeLocations are equivalent except + // that programVertexAttributes optimizes out unused attributes. + var precreatedAttributes = model._precreatedAttributes; + if (defined(precreatedAttributes)) { + for (location in precreatedAttributes) { + if (precreatedAttributes.hasOwnProperty(location)) { + index = programAttributeLocations[location]; + attributeLocations[location] = index; + } + } } - - return new DynamicGeometryUpdater(primitives, this); - }; - /** - * @private - */ - function DynamicGeometryUpdater(primitives, geometryUpdater) { - this._entity = geometryUpdater._entity; - this._scene = geometryUpdater._scene; - this._primitives = primitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); - this._modelMatrix = new Matrix4(); - this._material = undefined; - this._attributes = undefined; - this._outlineAttributes = undefined; - this._lastSceneMode = undefined; - this._lastShow = undefined; - this._lastOutlineShow = undefined; - this._lastOutlineWidth = undefined; - this._lastOutlineColor = undefined; + return attributeLocations; } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + + function mapJointNames(forest, nodes) { + var length = forest.length; + var jointNodes = {}; + for (var i = 0; i < length; ++i) { + var stack = [forest[i]]; // Push root node of tree + + while (stack.length > 0) { + var id = stack.pop(); + var n = nodes[id]; + + if (defined(n)) { + jointNodes[id] = id; + } + + var children = n.children; + var childrenLength = children.length; + for (var k = 0; k < childrenLength; ++k) { + stack.push(children[k]); + } + } } - - var entity = this._entity; - var ellipsoid = entity.ellipsoid; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(ellipsoid.show, time, true)) { - if (defined(this._primitive)) { - this._primitive.show = false; + return jointNodes; + } + + function createJoints(model, runtimeSkins) { + var gltf = model.gltf; + var skins = gltf.skins; + var nodes = gltf.nodes; + var runtimeNodes = model._runtime.nodes; + + var skinnedNodesIds = model._loadResources.skinnedNodesIds; + var length = skinnedNodesIds.length; + for (var j = 0; j < length; ++j) { + var id = skinnedNodesIds[j]; + var skinnedNode = runtimeNodes[id]; + var node = nodes[id]; + + var runtimeSkin = runtimeSkins[node.skin]; + skinnedNode.inverseBindMatrices = runtimeSkin.inverseBindMatrices; + skinnedNode.bindShapeMatrix = runtimeSkin.bindShapeMatrix; + + // 1. Find nodes with the names in node.skeletons (the node's skeletons) + // 2. These nodes form the root nodes of the forest to search for each joint in skin.jointNames. This search uses jointName, not the node's name. + // 3. Search for the joint name among the gltf node hierarchy instead of the runtime node hierarchy. Child links aren't set up yet for runtime nodes. + var forest = []; + var skin = skins[node.skin]; + if (defined(skin.skeleton)) { + forest.push(skin.skeleton); } - if (defined(this._outlinePrimitive)) { - this._outlinePrimitive.show = false; + var mappedJointNames = mapJointNames(forest, nodes); + var gltfJointNames = skins[node.skin].joints; + var jointNamesLength = gltfJointNames.length; + for (var i = 0; i < jointNamesLength; ++i) { + var jointName = gltfJointNames[i]; + var nodeId = mappedJointNames[jointName]; + var jointNode = runtimeNodes[nodeId]; + skinnedNode.joints.push(jointNode); } + } + } + + function createSkins(model) { + var loadResources = model._loadResources; + + if (loadResources.pendingBufferLoads !== 0) { return; } - var radii = Property.getValueOrUndefined(ellipsoid.radii, time, radiiScratch); - var modelMatrix = entity.computeModelMatrix(time, this._modelMatrix); - if (!defined(modelMatrix) || !defined(radii)) { - if (defined(this._primitive)) { - this._primitive.show = false; + if (!loadResources.createSkins) { + return; + } + loadResources.createSkins = false; + + var gltf = model.gltf; + var accessors = gltf.accessors; + var runtimeSkins = {}; + + ForEach.skin(gltf, function(skin, id) { + var accessor = accessors[skin.inverseBindMatrices]; + + var bindShapeMatrix; + if (!Matrix4.equals(skin.bindShapeMatrix, Matrix4.IDENTITY)) { + bindShapeMatrix = Matrix4.clone(skin.bindShapeMatrix); } - if (defined(this._outlinePrimitive)) { - this._outlinePrimitive.show = false; + runtimeSkins[id] = { + inverseBindMatrices : ModelAnimationCache.getSkinInverseBindMatrices(model, accessor), + bindShapeMatrix : bindShapeMatrix // not used when undefined + }; + }); + + createJoints(model, runtimeSkins); + } + + function getChannelEvaluator(model, runtimeNode, targetPath, spline) { + return function(localAnimationTime) { + // Workaround for https://github.com/KhronosGroup/glTF/issues/219 + + //if (targetPath === 'translation') { + // return; + //} + if (defined(spline)) { + localAnimationTime = model.clampAnimations ? spline.clampTime(localAnimationTime) : spline.wrapTime(localAnimationTime); + runtimeNode[targetPath] = spline.evaluate(localAnimationTime, runtimeNode[targetPath]); + runtimeNode.dirtyNumber = model._maxDirtyNumber; } + }; + } + + function createRuntimeAnimations(model) { + var loadResources = model._loadResources; + + if (!loadResources.finishedPendingBufferLoads()) { return; } - //Compute attributes and material. - var appearance; - var showFill = Property.getValueOrDefault(ellipsoid.fill, time, true); - var showOutline = Property.getValueOrDefault(ellipsoid.outline, time, false); - var outlineColor = Property.getValueOrClonedDefault(ellipsoid.outlineColor, time, Color.BLACK, scratchColor); - var material = MaterialProperty.getValue(time, defaultValue(ellipsoid.material, defaultMaterial), this._material); - this._material = material; + if (!loadResources.createRuntimeAnimations) { + return; + } + loadResources.createRuntimeAnimations = false; - // Check properties that could trigger a primitive rebuild. - var stackPartitions = Property.getValueOrUndefined(ellipsoid.stackPartitions, time); - var slicePartitions = Property.getValueOrUndefined(ellipsoid.slicePartitions, time); - var subdivisions = Property.getValueOrUndefined(ellipsoid.subdivisions, time); - var outlineWidth = Property.getValueOrDefault(ellipsoid.outlineWidth, time, 1.0); + model._runtime.animations = []; - //In 3D we use a fast path by modifying Primitive.modelMatrix instead of regenerating the primitive every frame. - var sceneMode = this._scene.mode; - var in3D = sceneMode === SceneMode.SCENE3D; + var runtimeNodes = model._runtime.nodes; + var animations = model.gltf.animations; + var accessors = model.gltf.accessors; - var options = this._options; + var length = animations.length; + for (var i = 0; i < length; ++i) { + var animation = animations[i]; + var channels = animation.channels; + var samplers = animation.samplers; - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + // Find start and stop time for the entire animation + var startTime = Number.MAX_VALUE; + var stopTime = -Number.MAX_VALUE; - var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + var channelsLength = channels.length; + var channelEvaluators = new Array(channelsLength); - //We only rebuild the primitive if something other than the radii has changed - //For the radii, we use unit sphere and then deform it with a scale matrix. - var rebuildPrimitives = !in3D || this._lastSceneMode !== sceneMode || !defined(this._primitive) || // - options.stackPartitions !== stackPartitions || options.slicePartitions !== slicePartitions || // - options.subdivisions !== subdivisions || this._lastOutlineWidth !== outlineWidth; + for (var j = 0; j < channelsLength; ++j) { + var channel = channels[j]; + var target = channel.target; + var path = target.path; + var sampler = samplers[channel.sampler]; + var input = ModelAnimationCache.getAnimationParameterValues(model, accessors[sampler.input]); + var output = ModelAnimationCache.getAnimationParameterValues(model, accessors[sampler.output]); - if (rebuildPrimitives) { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._lastSceneMode = sceneMode; - this._lastOutlineWidth = outlineWidth; + startTime = Math.min(startTime, input[0]); + stopTime = Math.max(stopTime, input[input.length - 1]); - options.stackPartitions = stackPartitions; - options.slicePartitions = slicePartitions; - options.subdivisions = subdivisions; - options.radii = in3D ? unitSphere : radii; + var spline = ModelAnimationCache.getAnimationSpline(model, i, animation, channel.sampler, sampler, input, path, output); - appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : true - }); - options.vertexFormat = appearance.vertexFormat; + // GLTF_SPEC: Support more targets like materials. https://github.com/KhronosGroup/glTF/issues/142 + channelEvaluators[j] = getChannelEvaluator(model, runtimeNodes[target.node], target.path, spline); + } - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new EllipsoidGeometry(options), - modelMatrix : !in3D ? modelMatrix : undefined, - attributes : { - show : new ShowGeometryInstanceAttribute(showFill), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + model._runtime.animations[i] = { + name : animation.name, + startTime : startTime, + stopTime : stopTime, + channelEvaluators : channelEvaluators + }; + } + } - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + function createVertexArrays(model, context) { + var loadResources = model._loadResources; - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new EllipsoidOutlineGeometry(options), - modelMatrix : !in3D ? modelMatrix : undefined, - attributes : { - show : new ShowGeometryInstanceAttribute(showOutline), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : distanceDisplayConditionAttribute + if (!loadResources.finishedBuffersCreation() || !loadResources.finishedProgramCreation()) { + return; + } + + if (!loadResources.createVertexArrays) { + return; + } + loadResources.createVertexArrays = false; + + var rendererBuffers = model._rendererResources.buffers; + var rendererVertexArrays = model._rendererResources.vertexArrays; + var gltf = model.gltf; + var accessors = gltf.accessors; + var meshes = gltf.meshes; + + for (var meshId in meshes) { + if (meshes.hasOwnProperty(meshId)) { + var primitives = meshes[meshId].primitives; + var primitivesLength = primitives.length; + + for (var i = 0; i < primitivesLength; ++i) { + var primitive = primitives[i]; + + // GLTF_SPEC: This does not take into account attribute arrays, + // indicated by when an attribute points to a parameter with a + // count property. + // + // https://github.com/KhronosGroup/glTF/issues/258 + + var attributeLocations = getAttributeLocations(model, primitive); + var attributeName; + var attributeLocation; + var attribute; + var attributes = []; + var primitiveAttributes = primitive.attributes; + for (attributeName in primitiveAttributes) { + if (primitiveAttributes.hasOwnProperty(attributeName)) { + attributeLocation = attributeLocations[attributeName]; + // Skip if the attribute is not used by the material, e.g., because the asset was exported + // with an attribute that wasn't used and the asset wasn't optimized. + if (defined(attributeLocation)) { + var a = accessors[primitiveAttributes[attributeName]]; + var normalize = false; + if (defined(a.normalized) && a.normalized) { + normalize = true; + } + + attributes.push({ + index : attributeLocation, + vertexBuffer : rendererBuffers[a.bufferView], + componentsPerAttribute : numberOfComponentsForType(a.type), + componentDatatype : a.componentType, + normalize : normalize, + offsetInBytes : a.byteOffset, + strideInBytes : getAccessorByteStride(gltf, a) + }); + } + } } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : outlineColor.alpha !== 1.0, - renderState : { - lineWidth : this._geometryUpdater._scene.clampLineWidth(outlineWidth) + + // Add pre-created attributes + var precreatedAttributes = model._precreatedAttributes; + if (defined(precreatedAttributes)) { + for (attributeName in precreatedAttributes) { + if (precreatedAttributes.hasOwnProperty(attributeName)) { + attributeLocation = attributeLocations[attributeName]; + if (defined(attributeLocation)) { + attribute = precreatedAttributes[attributeName]; + attribute.index = attributeLocation; + attributes.push(attribute); + } + } + } } - }), - asynchronous : false, - shadows : shadows - })); - this._lastShow = showFill; - this._lastOutlineShow = showOutline; - this._lastOutlineColor = Color.clone(outlineColor, this._lastOutlineColor); - this._lastDistanceDisplayCondition = distanceDisplayCondition; - } else if (this._primitive.ready) { - //Update attributes only. - var primitive = this._primitive; - var outlinePrimitive = this._outlinePrimitive; + var indexBuffer; + if (defined(primitive.indices)) { + var accessor = accessors[primitive.indices]; + indexBuffer = rendererBuffers[accessor.bufferView]; + } + rendererVertexArrays[meshId + '.primitive.' + i] = new VertexArray({ + context : context, + attributes : attributes, + indexBuffer : indexBuffer + }); + } + } + } + } - primitive.show = true; - outlinePrimitive.show = true; + function getBooleanStates(states) { + // GLTF_SPEC: SAMPLE_ALPHA_TO_COVERAGE not used by Cesium + var booleanStates = {}; + booleanStates[WebGLConstants.BLEND] = false; + booleanStates[WebGLConstants.CULL_FACE] = false; + booleanStates[WebGLConstants.DEPTH_TEST] = false; + booleanStates[WebGLConstants.POLYGON_OFFSET_FILL] = false; - appearance = primitive.appearance; - appearance.material = material; + var enable = states.enable; + var length = enable.length; + var i; + for (i = 0; i < length; ++i) { + booleanStates[enable[i]] = true; + } - var attributes = this._attributes; - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(entity); - this._attributes = attributes; - } - if (showFill !== this._lastShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(showFill, attributes.show); - this._lastShow = showFill; - } + return booleanStates; + } - var outlineAttributes = this._outlineAttributes; + function createRenderStates(model, context) { + var loadResources = model._loadResources; + var techniques = model.gltf.techniques; - if (!defined(outlineAttributes)) { - outlineAttributes = outlinePrimitive.getGeometryInstanceAttributes(entity); - this._outlineAttributes = outlineAttributes; + if (loadResources.createRenderStates) { + loadResources.createRenderStates = false; + for (var id in techniques) { + if (techniques.hasOwnProperty(id)) { + createRenderStateForTechnique(model, id, context); + } } + } + } - if (showOutline !== this._lastOutlineShow) { - outlineAttributes.show = ShowGeometryInstanceAttribute.toValue(showOutline, outlineAttributes.show); - this._lastOutlineShow = showOutline; - } + function createRenderStateForTechnique(model, id, context) { + var rendererRenderStates = model._rendererResources.renderStates; + var techniques = model.gltf.techniques; + var technique = techniques[id]; + var states = technique.states; - if (!Color.equals(outlineColor, this._lastOutlineColor)) { - outlineAttributes.color = ColorGeometryInstanceAttribute.toValue(outlineColor, outlineAttributes.color); - Color.clone(outlineColor, this._lastOutlineColor); + var booleanStates = getBooleanStates(states); + var statesFunctions = defaultValue(states.functions, defaultValue.EMPTY_OBJECT); + var blendColor = defaultValue(statesFunctions.blendColor, [0.0, 0.0, 0.0, 0.0]); + var blendEquationSeparate = defaultValue(statesFunctions.blendEquationSeparate, [ + WebGLConstants.FUNC_ADD, + WebGLConstants.FUNC_ADD]); + var blendFuncSeparate = defaultValue(statesFunctions.blendFuncSeparate, [ + WebGLConstants.ONE, + WebGLConstants.ZERO, + WebGLConstants.ONE, + WebGLConstants.ZERO]); + var colorMask = defaultValue(statesFunctions.colorMask, [true, true, true, true]); + var depthRange = defaultValue(statesFunctions.depthRange, [0.0, 1.0]); + var polygonOffset = defaultValue(statesFunctions.polygonOffset, [0.0, 0.0]); + + // Change the render state to use traditional alpha blending instead of premultiplied alpha blending + if (booleanStates[WebGLConstants.BLEND] && hasPremultipliedAlpha(model)) { + if ((blendFuncSeparate[0] === WebGLConstants.ONE) && (blendFuncSeparate[1] === WebGLConstants.ONE_MINUS_SRC_ALPHA)) { + blendFuncSeparate[0] = WebGLConstants.SRC_ALPHA; + blendFuncSeparate[1] = WebGLConstants.ONE_MINUS_SRC_ALPHA; + blendFuncSeparate[2] = WebGLConstants.SRC_ALPHA; + blendFuncSeparate[3] = WebGLConstants.ONE_MINUS_SRC_ALPHA; } + } - if (!DistanceDisplayCondition.equals(distanceDisplayCondition, this._lastDistanceDisplayCondition)) { - attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); - outlineAttributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, outlineAttributes.distanceDisplayCondition); - DistanceDisplayCondition.clone(distanceDisplayCondition, this._lastDistanceDisplayCondition); + rendererRenderStates[id] = RenderState.fromCache({ + frontFace : defined(statesFunctions.frontFace) ? statesFunctions.frontFace[0] : WebGLConstants.CCW, + cull : { + enabled : booleanStates[WebGLConstants.CULL_FACE], + face : defined(statesFunctions.cullFace) ? statesFunctions.cullFace[0] : WebGLConstants.BACK + }, + lineWidth : defined(statesFunctions.lineWidth) ? statesFunctions.lineWidth[0] : 1.0, + polygonOffset : { + enabled : booleanStates[WebGLConstants.POLYGON_OFFSET_FILL], + factor : polygonOffset[0], + units : polygonOffset[1] + }, + depthRange : { + near : depthRange[0], + far : depthRange[1] + }, + depthTest : { + enabled : booleanStates[WebGLConstants.DEPTH_TEST], + func : defined(statesFunctions.depthFunc) ? statesFunctions.depthFunc[0] : WebGLConstants.LESS + }, + colorMask : { + red : colorMask[0], + green : colorMask[1], + blue : colorMask[2], + alpha : colorMask[3] + }, + depthMask : defined(statesFunctions.depthMask) ? statesFunctions.depthMask[0] : true, + blending : { + enabled : booleanStates[WebGLConstants.BLEND], + color : { + red : blendColor[0], + green : blendColor[1], + blue : blendColor[2], + alpha : blendColor[3] + }, + equationRgb : blendEquationSeparate[0], + equationAlpha : blendEquationSeparate[1], + functionSourceRgb : blendFuncSeparate[0], + functionDestinationRgb : blendFuncSeparate[1], + functionSourceAlpha : blendFuncSeparate[2], + functionDestinationAlpha : blendFuncSeparate[3] } - } + }); + } - if (in3D) { - //Since we are scaling a unit sphere, we can't let any of the values go to zero. - //Instead we clamp them to a small value. To the naked eye, this produces the same results - //that you get passing EllipsoidGeometry a radii with a zero component. - radii.x = Math.max(radii.x, 0.001); - radii.y = Math.max(radii.y, 0.001); - radii.z = Math.max(radii.z, 0.001); + /////////////////////////////////////////////////////////////////////////// - modelMatrix = Matrix4.multiplyByScale(modelMatrix, radii, modelMatrix); - this._primitive.modelMatrix = modelMatrix; - this._outlinePrimitive.modelMatrix = modelMatrix; + var gltfUniformsFromNode = { + MODEL : function(uniformState, model, runtimeNode) { + return function() { + return runtimeNode.computedMatrix; + }; + }, + VIEW : function(uniformState, model, runtimeNode) { + return function() { + return uniformState.view; + }; + }, + PROJECTION : function(uniformState, model, runtimeNode) { + return function() { + return uniformState.projection; + }; + }, + MODELVIEW : function(uniformState, model, runtimeNode) { + var mv = new Matrix4(); + return function() { + return Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv); + }; + }, + CESIUM_RTC_MODELVIEW : function(uniformState, model, runtimeNode) { + // CESIUM_RTC extension + var mvRtc = new Matrix4(); + return function() { + Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mvRtc); + return Matrix4.setTranslation(mvRtc, model._rtcCenterEye, mvRtc); + }; + }, + MODELVIEWPROJECTION : function(uniformState, model, runtimeNode) { + var mvp = new Matrix4(); + return function() { + Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mvp); + return Matrix4.multiply(uniformState._projection, mvp, mvp); + }; + }, + MODELINVERSE : function(uniformState, model, runtimeNode) { + var mInverse = new Matrix4(); + return function() { + return Matrix4.inverse(runtimeNode.computedMatrix, mInverse); + }; + }, + VIEWINVERSE : function(uniformState, model) { + return function() { + return uniformState.inverseView; + }; + }, + PROJECTIONINVERSE : function(uniformState, model, runtimeNode) { + return function() { + return uniformState.inverseProjection; + }; + }, + MODELVIEWINVERSE : function(uniformState, model, runtimeNode) { + var mv = new Matrix4(); + var mvInverse = new Matrix4(); + return function() { + Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv); + return Matrix4.inverse(mv, mvInverse); + }; + }, + MODELVIEWPROJECTIONINVERSE : function(uniformState, model, runtimeNode) { + var mvp = new Matrix4(); + var mvpInverse = new Matrix4(); + return function() { + Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mvp); + Matrix4.multiply(uniformState._projection, mvp, mvp); + return Matrix4.inverse(mvp, mvpInverse); + }; + }, + MODELINVERSETRANSPOSE : function(uniformState, model, runtimeNode) { + var mInverse = new Matrix4(); + var mInverseTranspose = new Matrix3(); + return function() { + Matrix4.inverse(runtimeNode.computedMatrix, mInverse); + Matrix4.getRotation(mInverse, mInverseTranspose); + return Matrix3.transpose(mInverseTranspose, mInverseTranspose); + }; + }, + MODELVIEWINVERSETRANSPOSE : function(uniformState, model, runtimeNode) { + var mv = new Matrix4(); + var mvInverse = new Matrix4(); + var mvInverseTranspose = new Matrix3(); + return function() { + Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv); + Matrix4.inverse(mv, mvInverse); + Matrix4.getRotation(mvInverse, mvInverseTranspose); + return Matrix3.transpose(mvInverseTranspose, mvInverseTranspose); + }; + }, + VIEWPORT : function(uniformState, model, runtimeNode) { + return function() { + return uniformState.viewportCartesian4; + }; } }; - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; - - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; - - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; - - return EllipsoidGeometryUpdater; -}); - -define('DataSources/StaticGeometryColorBatch',[ - '../Core/AssociativeArray', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defined', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/Primitive', - './BoundingSphereState', - './ColorMaterialProperty', - './MaterialProperty', - './Property' - ], function( - AssociativeArray, - Color, - ColorGeometryInstanceAttribute, - defined, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - ShowGeometryInstanceAttribute, - Primitive, - BoundingSphereState, - ColorMaterialProperty, - MaterialProperty, - Property) { - 'use strict'; + function getUniformFunctionFromSource(source, model, semantic, uniformState) { + var runtimeNode = model._runtime.nodes[source]; + return gltfUniformsFromNode[semantic](uniformState, model, runtimeNode); + } - var colorScratch = new Color(); - var distanceDisplayConditionScratch = new DistanceDisplayCondition(); + function createUniformMaps(model, context) { + var loadResources = model._loadResources; - function Batch(primitives, translucent, appearanceType, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) { - this.translucent = translucent; - this.appearanceType = appearanceType; - this.depthFailAppearanceType = depthFailAppearanceType; - this.depthFailMaterialProperty = depthFailMaterialProperty; - this.depthFailMaterial = undefined; - this.closed = closed; - this.shadows = shadows; - this.primitives = primitives; - this.createPrimitive = false; - this.waitingOnCreate = false; - this.primitive = undefined; - this.oldPrimitive = undefined; - this.geometry = new AssociativeArray(); - this.updaters = new AssociativeArray(); - this.updatersWithAttributes = new AssociativeArray(); - this.attributes = new AssociativeArray(); - this.subscriptions = new AssociativeArray(); - this.showsUpdated = new AssociativeArray(); - this.itemsToRemove = []; - this.invalidated = false; + if (!loadResources.finishedProgramCreation()) { + return; + } - var removeMaterialSubscription; - if (defined(depthFailMaterialProperty)) { - removeMaterialSubscription = depthFailMaterialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); + if (!loadResources.createUniformMaps) { + return; } - this.removeMaterialSubscription = removeMaterialSubscription; - } + loadResources.createUniformMaps = false; - Batch.prototype.onMaterialChanged = function() { - this.invalidated = true; - }; + var gltf = model.gltf; + var materials = gltf.materials; + var techniques = gltf.techniques; + var uniformMaps = model._uniformMaps; - Batch.prototype.isMaterial = function(updater) { - var material = this.depthFailMaterialProperty; - var updaterMaterial = updater.depthFailMaterialProperty; - if (updaterMaterial === material) { - return true; - } - if (defined(material)) { - return material.equals(updaterMaterial); - } - return false; - }; + var textures = model._rendererResources.textures; + var defaultTexture = model._defaultTexture; - Batch.prototype.add = function(updater, instance) { - var id = updater.entity.id; - this.createPrimitive = true; - this.geometry.set(id, instance); - this.updaters.set(id, updater); - if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { - this.updatersWithAttributes.set(id, updater); - } else { - var that = this; - this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { - if (propertyName === 'isShowing') { - that.showsUpdated.set(entity.id, updater); - } - })); - } - }; + for (var materialId in materials) { + if (materials.hasOwnProperty(materialId)) { + var material = materials[materialId]; + var instanceParameters; + instanceParameters = material.values; + var technique = techniques[material.technique]; + var parameters = technique.parameters; + var uniforms = technique.uniforms; - Batch.prototype.remove = function(updater) { - var id = updater.entity.id; - this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; - if (this.updaters.remove(id)) { - this.updatersWithAttributes.remove(id); - var unsubscribe = this.subscriptions.get(id); - if (defined(unsubscribe)) { - unsubscribe(); - this.subscriptions.remove(id); - } - } - }; + var uniformMap = {}; + var uniformValues = {}; + var jointMatrixUniformName; + var morphWeightsUniformName; - Batch.prototype.update = function(time) { - var isUpdated = true; - var removedCount = 0; - var primitive = this.primitive; - var primitives = this.primitives; - var attributes; - var i; + // Uniform parameters + for (var name in uniforms) { + if (uniforms.hasOwnProperty(name) && name !== 'extras') { + var parameterName = uniforms[name]; + var parameter = parameters[parameterName]; - if (this.createPrimitive) { - var geometries = this.geometry.values; - var geometriesLength = geometries.length; - if (geometriesLength > 0) { - if (defined(primitive)) { - if (!defined(this.oldPrimitive)) { - this.oldPrimitive = primitive; - } else { - primitives.remove(primitive); - } - } + // GLTF_SPEC: This does not take into account uniform arrays, + // indicated by parameters with a count property. + // + // https://github.com/KhronosGroup/glTF/issues/258 - for (i = 0; i < geometriesLength; i++) { - var geometryItem = geometries[i]; - var originalAttributes = geometryItem.attributes; - attributes = this.attributes.get(geometryItem.id.id); + // GLTF_SPEC: In this implementation, material parameters with a + // semantic or targeted via a source (for animation) are not + // targetable for material animations. Is this too strict? + // + // https://github.com/KhronosGroup/glTF/issues/142 - if (defined(attributes)) { - if (defined(originalAttributes.show)) { - originalAttributes.show.value = attributes.show; - } - if (defined(originalAttributes.color)) { - originalAttributes.color.value = attributes.color; - } - if (defined(originalAttributes.depthFailColor)) { - originalAttributes.depthFailColor.value = attributes.depthFailColor; + if (defined(instanceParameters[parameterName])) { + // Parameter overrides by the instance technique + var uv = ModelUtility.createUniformFunction(parameter.type, instanceParameters[parameterName], textures, defaultTexture); + uniformMap[name] = uv.func; + uniformValues[parameterName] = uv; + } else if (defined(parameter.node)) { + uniformMap[name] = getUniformFunctionFromSource(parameter.node, model, parameter.semantic, context.uniformState); + } else if (defined(parameter.semantic)) { + if (parameter.semantic === 'JOINTMATRIX') { + jointMatrixUniformName = name; + } else if (parameter.semantic === 'MORPHWEIGHTS') { + morphWeightsUniformName = name; + } else { + // Map glTF semantic to Cesium automatic uniform + uniformMap[name] = ModelUtility.getGltfSemanticUniforms()[parameter.semantic](context.uniformState, model); + } + } else if (defined(parameter.value)) { + // Technique value that isn't overridden by a material + var uv2 = ModelUtility.createUniformFunction(parameter.type, parameter.value, textures, defaultTexture); + uniformMap[name] = uv2.func; + uniformValues[parameterName] = uv2; } } } - var depthFailAppearance; - if (defined(this.depthFailAppearanceType)) { - if (defined(this.depthFailMaterialProperty)) { - this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); - } - depthFailAppearance = new this.depthFailAppearanceType({ - material : this.depthFailMaterial, - translucent : this.translucent, - closed : this.closed - }); - } - - primitive = new Primitive({ - asynchronous : true, - geometryInstances : geometries, - appearance : new this.appearanceType({ - translucent : this.translucent, - closed : this.closed - }), - depthFailAppearance : depthFailAppearance, - shadows : this.shadows - }); - primitives.add(primitive); - isUpdated = false; - } else { - if (defined(primitive)) { - primitives.remove(primitive); - primitive = undefined; - } - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; - } + var u = uniformMaps[materialId]; + u.uniformMap = uniformMap; // uniform name -> function for the renderer + u.values = uniformValues; // material parameter name -> ModelMaterial for modifying the parameter at runtime + u.jointMatrixUniformName = jointMatrixUniformName; + u.morphWeightsUniformName = morphWeightsUniformName; } + } + } - this.attributes.removeAll(); - this.primitive = primitive; - this.createPrimitive = false; - this.waitingOnCreate = true; - } else if (defined(primitive) && primitive.ready) { - if (defined(this.oldPrimitive)) { - primitives.remove(this.oldPrimitive); - this.oldPrimitive = undefined; - } + function createUniformsForQuantizedAttributes(model, primitive) { + var programId = getProgramForPrimitive(model, primitive); + var quantizedUniforms = model._quantizedUniforms[programId]; + return ModelUtility.createUniformsForQuantizedAttributes(model.gltf, primitive, quantizedUniforms); + } - if (defined(this.depthFailAppearanceType) && !(this.depthFailMaterialProperty instanceof ColorMaterialProperty)) { - this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); - this.primitive.depthFailAppearance.material = this.depthFailMaterial; - } + function createPickColorFunction(color) { + return function() { + return color; + }; + } - var updatersWithAttributes = this.updatersWithAttributes.values; - var length = updatersWithAttributes.length; - var waitingOnCreate = this.waitingOnCreate; - for (i = 0; i < length; i++) { - var updater = updatersWithAttributes[i]; - var instance = this.geometry.get(updater.entity.id); + function createJointMatricesFunction(runtimeNode) { + return function() { + return runtimeNode.computedJointMatrices; + }; + } - attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); - } + function createMorphWeightsFunction(runtimeNode) { + return function() { + return runtimeNode.weights; + }; + } - if (!updater.fillMaterialProperty.isConstant || waitingOnCreate) { - var colorProperty = updater.fillMaterialProperty.color; - colorProperty.getValue(time, colorScratch); - if (!Color.equals(attributes._lastColor, colorScratch)) { - attributes._lastColor = Color.clone(colorScratch, attributes._lastColor); - attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); - if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { - this.itemsToRemove[removedCount++] = updater; - } - } - } + function createSilhouetteColorFunction(model) { + return function() { + return model.silhouetteColor; + }; + } - if (defined(this.depthFailAppearanceType) && this.depthFailAppearanceType instanceof ColorMaterialProperty && (!updater.depthFailMaterialProperty.isConstant || waitingOnCreate)) { - var depthFailColorProperty = updater.depthFailMaterialProperty.color; - depthFailColorProperty.getValue(time, colorScratch); - if (!Color.equals(attributes._lastDepthFailColor, colorScratch)) { - attributes._lastDepthFailColor = Color.clone(colorScratch, attributes._lastDepthFailColor); - attributes.depthFailColor = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.depthFailColor); - } - } + function createSilhouetteSizeFunction(model) { + return function() { + return model.silhouetteSize; + }; + } - var show = updater.entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); - } + function createColorFunction(model) { + return function() { + return model.color; + }; + } - var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; - if (!Property.isConstant(distanceDisplayConditionProperty)) { - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); - if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { - attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); - attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); - } - } + function createClippingPlanesLengthFunction(model) { + return function() { + return model._packedClippingPlanes.length; + }; + } + + function createClippingPlanesUnionRegionsFunction(model) { + return function() { + var clippingPlanes = model.clippingPlanes; + if (!defined(clippingPlanes)) { + return false; } - this.updateShows(primitive); - this.waitingOnCreate = false; - } else if (defined(primitive) && !primitive.ready) { - isUpdated = false; - } - this.itemsToRemove.length = removedCount; - return isUpdated; - }; + return clippingPlanes.unionClippingRegions; + }; + } - Batch.prototype.updateShows = function(primitive) { - var showsUpdated = this.showsUpdated.values; - var length = showsUpdated.length; - for (var i = 0; i < length; i++) { - var updater = showsUpdated[i]; - var instance = this.geometry.get(updater.entity.id); + function createClippingPlanesFunction(model) { + return function() { + var clippingPlanes = model.clippingPlanes; + var packedPlanes = model._packedClippingPlanes; - var attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); + if (defined(clippingPlanes) && clippingPlanes.enabled) { + clippingPlanes.transformAndPackPlanes(model._modelViewMatrix, packedPlanes); } - var show = updater.entity.isShowing; - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + return packedPlanes; + }; + } + + function createClippingPlanesEdgeStyleFunction(model) { + return function() { + var clippingPlanes = model.clippingPlanes; + if (!defined(clippingPlanes)) { + return Color.WHITE.withAlpha(0.0); } - } - this.showsUpdated.removeAll(); - }; - Batch.prototype.contains = function(entity) { - return this.updaters.contains(entity.id); - }; + var style = Color.clone(clippingPlanes.edgeColor); + style.alpha = clippingPlanes.edgeWidth; + return style; + }; + } - Batch.prototype.getBoundingSphere = function(entity, result) { - var primitive = this.primitive; - if (!primitive.ready) { - return BoundingSphereState.PENDING; - } - var attributes = primitive.getGeometryInstanceAttributes(entity); - if (!defined(attributes) || !defined(attributes.boundingSphere) ||// - (defined(attributes.show) && attributes.show[0] === 0)) { - return BoundingSphereState.FAILED; + function createColorBlendFunction(model) { + return function() { + return ColorBlendMode.getColorBlend(model.colorBlendMode, model.colorBlendAmount); + }; + } + + function triangleCountFromPrimitiveIndices(primitive, indicesCount) { + switch (primitive.mode) { + case PrimitiveType.TRIANGLES: + return (indicesCount / 3); + case PrimitiveType.TRIANGLE_STRIP: + case PrimitiveType.TRIANGLE_FAN: + return Math.max(indicesCount - 2, 0); + default: + return 0; } - attributes.boundingSphere.clone(result); - return BoundingSphereState.DONE; - }; + } - Batch.prototype.removeAllPrimitives = function() { - var primitives = this.primitives; + function createCommand(model, gltfNode, runtimeNode, context, scene3DOnly) { + var nodeCommands = model._nodeCommands; + var pickIds = model._pickIds; + var allowPicking = model.allowPicking; + var runtimeMeshesByName = model._runtime.meshesByName; - var primitive = this.primitive; - if (defined(primitive)) { - primitives.remove(primitive); - this.primitive = undefined; - this.geometry.removeAll(); - this.updaters.removeAll(); - } + var resources = model._rendererResources; + var rendererVertexArrays = resources.vertexArrays; + var rendererPrograms = resources.programs; + var rendererPickPrograms = resources.pickPrograms; + var rendererRenderStates = resources.renderStates; + var uniformMaps = model._uniformMaps; - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; - } - }; + var gltf = model.gltf; + var accessors = gltf.accessors; + var gltfMeshes = gltf.meshes; + var techniques = gltf.techniques; + var materials = gltf.materials; - Batch.prototype.destroy = function() { - var primitive = this.primitive; - var primitives = this.primitives; - if (defined(primitive)) { - primitives.remove(primitive); - } - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - } - if(defined(this.removeMaterialSubscription)) { - this.removeMaterialSubscription(); - } - }; + var id = gltfNode.mesh; + var mesh = gltfMeshes[id]; - /** - * @private - */ - function StaticGeometryColorBatch(primitives, appearanceType, depthFailAppearanceType, closed, shadows) { - this._solidItems = []; - this._translucentItems = []; - this._primitives = primitives; - this._appearanceType = appearanceType; - this._depthFailAppearanceType = depthFailAppearanceType; - this._closed = closed; - this._shadows = shadows; - } + var primitives = mesh.primitives; + var length = primitives.length; - StaticGeometryColorBatch.prototype.add = function(time, updater) { - var items; - var translucent; - var instance = updater.createFillGeometryInstance(time); - if (instance.attributes.color.value[3] === 255) { - items = this._solidItems; - translucent = false; - } else { - items = this._translucentItems; - translucent = true; - } + // The glTF node hierarchy is a DAG so a node can have more than one + // parent, so a node may already have commands. If so, append more + // since they will have a different model matrix. - var length = items.length; - for (var i = 0; i < length; i++) { - var item = items[i]; - if (item.isMaterial(updater)) { - item.add(updater, instance); - return; + for (var i = 0; i < length; ++i) { + var primitive = primitives[i]; + var ix = accessors[primitive.indices]; + var material = materials[primitive.material]; + var technique = techniques[material.technique]; + var programId = technique.program; + + var boundingSphere; + var positionAccessor = primitive.attributes.POSITION; + if (defined(positionAccessor)) { + var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor); + boundingSphere = BoundingSphere.fromCornerPoints(Cartesian3.fromArray(minMax.min), Cartesian3.fromArray(minMax.max)); } - } - var batch = new Batch(this._primitives, translucent, this._appearanceType, this._depthFailAppearanceType, updater.depthFailMaterialProperty, this._closed, this._shadows); - batch.add(updater, instance); - items.push(batch); - }; - function removeItem(items, updater) { - var length = items.length; - for (var i = length - 1; i >= 0; i--) { - var item = items[i]; - if (item.remove(updater)) { - if (item.updaters.length === 0) { - items.splice(i, 1); - item.destroy(); - return true; - } + var vertexArray = rendererVertexArrays[id + '.primitive.' + i]; + var offset; + var count; + if (defined(ix)) { + count = ix.count; + offset = (ix.byteOffset / IndexDatatype.getSizeInBytes(ix.componentType)); // glTF has offset in bytes. Cesium has offsets in indices + } + else { + var positions = accessors[primitive.attributes.POSITION]; + count = positions.count; + offset = 0; } - } - return false; - } - StaticGeometryColorBatch.prototype.remove = function(updater) { - if (!removeItem(this._solidItems, updater)) { - removeItem(this._translucentItems, updater); - } - }; + // Update model triangle count using number of indices + model._trianglesLength += triangleCountFromPrimitiveIndices(primitive, count); - function moveItems(batch, items, time) { - var itemsMoved = false; - var length = items.length; - for (var i = 0; i < length; ++i) { - var item = items[i]; - var itemsToRemove = item.itemsToRemove; - var itemsToMoveLength = itemsToRemove.length; - if (itemsToMoveLength > 0) { - for (i = 0; i < itemsToMoveLength; i++) { - var updater = itemsToRemove[i]; - item.remove(updater); - batch.add(time, updater); - itemsMoved = true; - } + var um = uniformMaps[primitive.material]; + var uniformMap = um.uniformMap; + if (defined(um.jointMatrixUniformName)) { + var jointUniformMap = {}; + jointUniformMap[um.jointMatrixUniformName] = createJointMatricesFunction(runtimeNode); + + uniformMap = combine(uniformMap, jointUniformMap); } - } - return itemsMoved; - } + if (defined(um.morphWeightsUniformName)) { + var morphWeightsUniformMap = {}; + morphWeightsUniformMap[um.morphWeightsUniformName] = createMorphWeightsFunction(runtimeNode); - function updateItems(batch, items, time, isUpdated) { - var length = items.length; - var i; - for (i = length - 1; i >= 0; i--) { - var item = items[i]; - if (item.invalidated) { - items.splice(i, 1); - var updaters = item.updaters.values; - var updatersLength = updaters.length; - for (var h = 0; h < updatersLength; h++) { - batch.add(time, updaters[h]); - } - item.destroy(); + uniformMap = combine(uniformMap, morphWeightsUniformMap); } - } - length = items.length; - for (i = 0; i < length; ++i) { - isUpdated = items[i].update(time) && isUpdated; - } - return isUpdated; - } + uniformMap = combine(uniformMap, { + gltf_color : createColorFunction(model), + gltf_colorBlend : createColorBlendFunction(model), + gltf_clippingPlanesLength: createClippingPlanesLengthFunction(model), + gltf_clippingPlanesUnionRegions: createClippingPlanesUnionRegionsFunction(model), + gltf_clippingPlanes: createClippingPlanesFunction(model, context), + gltf_clippingPlanesEdgeStyle: createClippingPlanesEdgeStyleFunction(model) + }); - StaticGeometryColorBatch.prototype.update = function(time) { - //Perform initial update - var isUpdated = updateItems(this, this._solidItems, time, true); - isUpdated = updateItems(this, this._translucentItems, time, isUpdated) && isUpdated; + // Allow callback to modify the uniformMap + if (defined(model._uniformMapLoaded)) { + uniformMap = model._uniformMapLoaded(uniformMap, programId, runtimeNode); + } - //If any items swapped between solid/translucent, we need to - //move them between batches - var solidsMoved = moveItems(this, this._solidItems, time); - var translucentsMoved = moveItems(this, this._translucentItems, time); + // Add uniforms for decoding quantized attributes if used + if (model.extensionsUsed.WEB3D_quantized_attributes) { + var quantizedUniformMap = createUniformsForQuantizedAttributes(model, primitive); + uniformMap = combine(uniformMap, quantizedUniformMap); + } - //If we moved anything around, we need to re-build the primitive - if (solidsMoved || translucentsMoved) { - isUpdated = updateItems(this, this._solidItems, time, isUpdated) && isUpdated; - isUpdated = updateItems(this, this._translucentItems, time, isUpdated)&& isUpdated; - } + var rs = rendererRenderStates[material.technique]; - return isUpdated; - }; + // GLTF_SPEC: Offical means to determine translucency. https://github.com/KhronosGroup/glTF/issues/105 + var isTranslucent = rs.blending.enabled; - function getBoundingSphere(items, entity, result) { - var length = items.length; - for (var i = 0; i < length; i++) { - var item = items[i]; - if(item.contains(entity)){ - return item.getBoundingSphere(entity, result); + var owner = model._pickObject; + if (!defined(owner)) { + owner = { + primitive : model, + id : model.id, + node : runtimeNode.publicNode, + mesh : runtimeMeshesByName[mesh.name] + }; } - } - return BoundingSphereState.FAILED; - } - - StaticGeometryColorBatch.prototype.getBoundingSphere = function(entity, result) { - var boundingSphere = getBoundingSphere(this._solidItems, entity, result); - if (boundingSphere === BoundingSphereState.FAILED) { - return getBoundingSphere(this._translucentItems, entity, result); - } - return boundingSphere; - }; - function removeAllPrimitives(items) { - var length = items.length; - for (var i = 0; i < length; i++) { - items[i].destroy(); - } - items.length = 0; - } + var castShadows = ShadowMode.castShadows(model._shadows); + var receiveShadows = ShadowMode.receiveShadows(model._shadows); - StaticGeometryColorBatch.prototype.removeAllPrimitives = function() { - removeAllPrimitives(this._solidItems); - removeAllPrimitives(this._translucentItems); - }; + var command = new DrawCommand({ + boundingVolume : new BoundingSphere(), // updated in update() + cull : model.cull, + modelMatrix : new Matrix4(), // computed in update() + primitiveType : primitive.mode, + vertexArray : vertexArray, + count : count, + offset : offset, + shaderProgram : rendererPrograms[technique.program], + castShadows : castShadows, + receiveShadows : receiveShadows, + uniformMap : uniformMap, + renderState : rs, + owner : owner, + pass : isTranslucent ? Pass.TRANSLUCENT : model.opaquePass + }); - return StaticGeometryColorBatch; -}); + var pickCommand; -define('DataSources/StaticGeometryPerMaterialBatch',[ - '../Core/AssociativeArray', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defined', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/Primitive', - './BoundingSphereState', - './ColorMaterialProperty', - './MaterialProperty', - './Property' - ], function( - AssociativeArray, - Color, - ColorGeometryInstanceAttribute, - defined, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - ShowGeometryInstanceAttribute, - Primitive, - BoundingSphereState, - ColorMaterialProperty, - MaterialProperty, - Property) { - 'use strict'; + if (allowPicking) { + var pickUniformMap; - var distanceDisplayConditionScratch = new DistanceDisplayCondition(); + // Callback to override default model picking + if (defined(model._pickFragmentShaderLoaded)) { + if (defined(model._pickUniformMapLoaded)) { + pickUniformMap = model._pickUniformMapLoaded(uniformMap); + } else { + // This is unlikely, but could happen if the override shader does not + // need new uniforms since, for example, its pick ids are coming from + // a vertex attribute or are baked into the shader source. + pickUniformMap = combine(uniformMap); + } + } else { + var pickId = context.createPickId(owner); + pickIds.push(pickId); + var pickUniforms = { + czm_pickColor : createPickColorFunction(pickId.color) + }; + pickUniformMap = combine(uniformMap, pickUniforms); + } - function Batch(primitives, appearanceType, materialProperty, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) { - this.primitives = primitives; - this.appearanceType = appearanceType; - this.materialProperty = materialProperty; - this.depthFailAppearanceType = depthFailAppearanceType; - this.depthFailMaterialProperty = depthFailMaterialProperty; - this.closed = closed; - this.shadows = shadows; - this.updaters = new AssociativeArray(); - this.createPrimitive = true; - this.primitive = undefined; - this.oldPrimitive = undefined; - this.geometry = new AssociativeArray(); - this.material = undefined; - this.depthFailMaterial = undefined; - this.updatersWithAttributes = new AssociativeArray(); - this.attributes = new AssociativeArray(); - this.invalidated = false; - this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); - this.subscriptions = new AssociativeArray(); - this.showsUpdated = new AssociativeArray(); - } + pickCommand = new DrawCommand({ + boundingVolume : new BoundingSphere(), // updated in update() + cull : model.cull, + modelMatrix : new Matrix4(), // computed in update() + primitiveType : primitive.mode, + vertexArray : vertexArray, + count : count, + offset : offset, + shaderProgram : rendererPickPrograms[technique.program], + uniformMap : pickUniformMap, + renderState : rs, + owner : owner, + pass : isTranslucent ? Pass.TRANSLUCENT : model.opaquePass + }); + } - Batch.prototype.onMaterialChanged = function() { - this.invalidated = true; - }; + var command2D; + var pickCommand2D; + if (!scene3DOnly) { + command2D = DrawCommand.shallowClone(command); + command2D.boundingVolume = new BoundingSphere(); // updated in update() + command2D.modelMatrix = new Matrix4(); // updated in update() - Batch.prototype.isMaterial = function(updater) { - var material = this.materialProperty; - var updaterMaterial = updater.fillMaterialProperty; - var depthFailMaterial = this.depthFailMaterialProperty; - var updaterDepthFailMaterial = updater.depthFailMaterialProperty; + if (allowPicking) { + pickCommand2D = DrawCommand.shallowClone(pickCommand); + pickCommand2D.boundingVolume = new BoundingSphere(); // updated in update() + pickCommand2D.modelMatrix = new Matrix4(); // updated in update() + } + } - if (updaterMaterial === material && updaterDepthFailMaterial === depthFailMaterial) { - return true; + var nodeCommand = { + show : true, + boundingSphere : boundingSphere, + command : command, + pickCommand : pickCommand, + command2D : command2D, + pickCommand2D : pickCommand2D, + // Generated on demand when silhouette size is greater than 0.0 and silhouette alpha is greater than 0.0 + silhouetteModelCommand : undefined, + silhouetteModelCommand2D : undefined, + silhouetteColorCommand : undefined, + silhouetteColorCommand2D : undefined, + // Generated on demand when color alpha is less than 1.0 + translucentCommand : undefined, + translucentCommand2D : undefined + }; + runtimeNode.commands.push(nodeCommand); + nodeCommands.push(nodeCommand); } - var equals = defined(material) && material.equals(updaterMaterial); - equals = ((!defined(depthFailMaterial) && !defined(updaterDepthFailMaterial)) || (defined(depthFailMaterial) && depthFailMaterial.equals(updaterDepthFailMaterial))) && equals; - return equals; - }; - Batch.prototype.add = function(time, updater) { - var id = updater.entity.id; - this.updaters.set(id, updater); - this.geometry.set(id, updater.createFillGeometryInstance(time)); - if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { - this.updatersWithAttributes.set(id, updater); - } else { - var that = this; - this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { - if (propertyName === 'isShowing') { - that.showsUpdated.set(entity.id, updater); - } - })); + } + + function createRuntimeNodes(model, context, scene3DOnly) { + var loadResources = model._loadResources; + + if (!loadResources.finishedEverythingButTextureCreation()) { + return; } - this.createPrimitive = true; - }; - Batch.prototype.remove = function(updater) { - var id = updater.entity.id; - this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; - if (this.updaters.remove(id)) { - this.updatersWithAttributes.remove(id); - var unsubscribe = this.subscriptions.get(id); - if (defined(unsubscribe)) { - unsubscribe(); - this.subscriptions.remove(id); - } + if (!loadResources.createRuntimeNodes) { + return; } - return this.createPrimitive; - }; + loadResources.createRuntimeNodes = false; - var colorScratch = new Color(); + var rootNodes = []; + var runtimeNodes = model._runtime.nodes; - Batch.prototype.update = function(time) { - var isUpdated = true; - var primitive = this.primitive; - var primitives = this.primitives; - var geometries = this.geometry.values; - var attributes; - var i; + var gltf = model.gltf; + var nodes = gltf.nodes; + var skins = gltf.skins; - if (this.createPrimitive) { - var geometriesLength = geometries.length; - if (geometriesLength > 0) { - if (defined(primitive)) { - if (!defined(this.oldPrimitive)) { - this.oldPrimitive = primitive; - } else { - primitives.remove(primitive); - } - } + var scene = gltf.scenes[gltf.scene]; + var sceneNodes = scene.nodes; + var length = sceneNodes.length; - for (i = 0; i < geometriesLength; i++) { - var geometry = geometries[i]; - var originalAttributes = geometry.attributes; - attributes = this.attributes.get(geometry.id.id); + var stack = []; + var seen = {}; - if (defined(attributes)) { - if (defined(originalAttributes.show)) { - originalAttributes.show.value = attributes.show; - } - if (defined(originalAttributes.color)) { - originalAttributes.color.value = attributes.color; - } - if (defined(originalAttributes.depthFailColor)) { - originalAttributes.depthFailColor.value = attributes.depthFailColor; - } - } - } + for (var i = 0; i < length; ++i) { + stack.push({ + parentRuntimeNode : undefined, + gltfNode : nodes[sceneNodes[i]], + id : sceneNodes[i] + }); - this.material = MaterialProperty.getValue(time, this.materialProperty, this.material); + var skeletonIds = []; + while (stack.length > 0) { + var n = stack.pop(); + seen[n.id] = true; + var parentRuntimeNode = n.parentRuntimeNode; + var gltfNode = n.gltfNode; - var depthFailAppearance; - if (defined(this.depthFailMaterialProperty)) { - var translucent; - if (this.depthFailMaterialProperty instanceof MaterialProperty) { - this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); - translucent = this.depthFailMaterial.isTranslucent(); + // Node hierarchy is a DAG so a node can have more than one parent so it may already exist + var runtimeNode = runtimeNodes[n.id]; + if (runtimeNode.parents.length === 0) { + if (defined(gltfNode.matrix)) { + runtimeNode.matrix = Matrix4.fromColumnMajorArray(gltfNode.matrix); } else { - translucent = this.material.isTranslucent(); + // TRS converted to Cesium types + var rotation = gltfNode.rotation; + runtimeNode.translation = Cartesian3.fromArray(gltfNode.translation); + runtimeNode.rotation = Quaternion.unpack(rotation); + runtimeNode.scale = Cartesian3.fromArray(gltfNode.scale); } - depthFailAppearance = new this.depthFailAppearanceType({ - material : this.depthFailMaterial, - translucent : translucent, - closed : this.closed - }); } - primitive = new Primitive({ - asynchronous : true, - geometryInstances : geometries, - appearance : new this.appearanceType({ - material : this.material, - translucent : this.material.isTranslucent(), - closed : this.closed - }), - depthFailAppearance : depthFailAppearance, - shadows : this.shadows - }); - - primitives.add(primitive); - isUpdated = false; - } else { - if (defined(primitive)) { - primitives.remove(primitive); - primitive = undefined; - } - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; + if (defined(parentRuntimeNode)) { + parentRuntimeNode.children.push(runtimeNode); + runtimeNode.parents.push(parentRuntimeNode); + } else { + rootNodes.push(runtimeNode); } - } - - this.attributes.removeAll(); - this.primitive = primitive; - this.createPrimitive = false; - } else if (defined(primitive) && primitive.ready) { - if (defined(this.oldPrimitive)) { - primitives.remove(this.oldPrimitive); - this.oldPrimitive = undefined; - } - - this.material = MaterialProperty.getValue(time, this.materialProperty, this.material); - this.primitive.appearance.material = this.material; - - if (defined(this.depthFailAppearanceType) && !(this.depthFailMaterialProperty instanceof ColorMaterialProperty)) { - this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); - this.primitive.depthFailAppearance.material = this.depthFailMaterial; - } - - var updatersWithAttributes = this.updatersWithAttributes.values; - var length = updatersWithAttributes.length; - for (i = 0; i < length; i++) { - var updater = updatersWithAttributes[i]; - var entity = updater.entity; - var instance = this.geometry.get(entity.id); - attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); + if (defined(gltfNode.mesh)) { + createCommand(model, gltfNode, runtimeNode, context, scene3DOnly); } - if (defined(this.depthFailAppearanceType) && this.depthFailAppearanceType instanceof ColorMaterialProperty && !updater.depthFailMaterialProperty.isConstant) { - var depthFailColorProperty = updater.depthFailMaterialProperty.color; - depthFailColorProperty.getValue(time, colorScratch); - if (!Color.equals(attributes._lastDepthFailColor, colorScratch)) { - attributes._lastDepthFailColor = Color.clone(colorScratch, attributes._lastDepthFailColor); - attributes.depthFailColor = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.depthFailColor); + var children = gltfNode.children; + var childrenLength = children.length; + for (var j = 0; j < childrenLength; j++) { + var childId = children[j]; + if (!seen[childId]) { + stack.push({ + parentRuntimeNode : runtimeNode, + gltfNode : nodes[childId], + id : children[j] + }); } } - var show = entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + var skin = gltfNode.skin; + if (defined(skin)) { + skeletonIds.push(skins[skin].skeleton); } - var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; - if (!Property.isConstant(distanceDisplayConditionProperty)) { - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); - if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { - attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); - attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); + if (stack.length === 0) { + for (var k = 0; k < skeletonIds.length; k++) { + var skeleton = skeletonIds[k]; + if (!seen[skeleton]) { + stack.push({ + parentRuntimeNode : undefined, + gltfNode : nodes[skeleton], + id : skeleton + }); + } } } } - - this.updateShows(primitive); - } else if (defined(primitive) && !primitive.ready) { - isUpdated = false; } - return isUpdated; - }; - Batch.prototype.updateShows = function(primitive) { - var showsUpdated = this.showsUpdated.values; - var length = showsUpdated.length; - for (var i = 0; i < length; i++) { - var updater = showsUpdated[i]; - var entity = updater.entity; - var instance = this.geometry.get(entity.id); + model._runtime.rootNodes = rootNodes; + model._runtime.nodes = runtimeNodes; + } - var attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); + function getGeometryByteLength(buffers) { + var memory = 0; + for (var id in buffers) { + if (buffers.hasOwnProperty(id)) { + memory += buffers[id].sizeInBytes; } + } + return memory; + } - var show = entity.isShowing; - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + function getTexturesByteLength(textures) { + var memory = 0; + for (var id in textures) { + if (textures.hasOwnProperty(id)) { + memory += textures[id].sizeInBytes; } } - this.showsUpdated.removeAll(); - }; + return memory; + } - Batch.prototype.contains = function(entity) { - return this.updaters.contains(entity.id); - }; + function createResources(model, frameState) { + var context = frameState.context; + var scene3DOnly = frameState.scene3DOnly; - Batch.prototype.getBoundingSphere = function(entity, result) { - var primitive = this.primitive; - if (!primitive.ready) { - return BoundingSphereState.PENDING; - } - var attributes = primitive.getGeometryInstanceAttributes(entity); - if (!defined(attributes) || !defined(attributes.boundingSphere) || - (defined(attributes.show) && attributes.show[0] === 0)) { - return BoundingSphereState.FAILED; - } - attributes.boundingSphere.clone(result); - return BoundingSphereState.DONE; - }; + ModelUtility.checkSupportedGlExtensions(model.gltf.glExtensionsUsed, context); + if (model._loadRendererResourcesFromCache) { + var resources = model._rendererResources; + var cachedResources = model._cachedRendererResources; - Batch.prototype.destroy = function() { - var primitive = this.primitive; - var primitives = this.primitives; - if (defined(primitive)) { - primitives.remove(primitive); + resources.buffers = cachedResources.buffers; + resources.vertexArrays = cachedResources.vertexArrays; + resources.programs = cachedResources.programs; + resources.pickPrograms = cachedResources.pickPrograms; + resources.silhouettePrograms = cachedResources.silhouettePrograms; + resources.textures = cachedResources.textures; + resources.samplers = cachedResources.samplers; + resources.renderStates = cachedResources.renderStates; + + // Vertex arrays are unique to this model, create instead of using the cache. + if (defined(model._precreatedAttributes)) { + createVertexArrays(model, context); + } + + model._cachedGeometryByteLength += getGeometryByteLength(cachedResources.buffers); + model._cachedTexturesByteLength += getTexturesByteLength(cachedResources.textures); + } else { + createBuffers(model, frameState); // using glTF bufferViews + createPrograms(model, frameState); + createSamplers(model, context); + loadTexturesFromBufferViews(model); + createTextures(model, frameState); } - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); + + createSkins(model); + createRuntimeAnimations(model); + + if (!model._loadRendererResourcesFromCache) { + createVertexArrays(model, context); // using glTF meshes + createRenderStates(model, context); // using glTF materials/techniques/states + // Long-term, we might not cache render states if they could change + // due to an animation, e.g., a uniform going from opaque to transparent. + // Could use copy-on-write if it is worth it. Probably overkill. } - this.removeMaterialSubscription(); - }; - /** - * @private - */ - function StaticGeometryPerMaterialBatch(primitives, appearanceType, depthFailAppearanceType, closed, shadows) { - this._items = []; - this._primitives = primitives; - this._appearanceType = appearanceType; - this._depthFailAppearanceType = depthFailAppearanceType; - this._closed = closed; - this._shadows = shadows; + createUniformMaps(model, context); // using glTF materials/techniques + createRuntimeNodes(model, context, scene3DOnly); // using glTF scene } - StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) { - var items = this._items; - var length = items.length; - for (var i = 0; i < length; i++) { - var item = items[i]; - if (item.isMaterial(updater)) { - item.add(time, updater); - return; - } - } - var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._depthFailAppearanceType, updater.depthFailMaterialProperty, this._closed, this._shadows); - batch.add(time, updater); - items.push(batch); - }; + /////////////////////////////////////////////////////////////////////////// - StaticGeometryPerMaterialBatch.prototype.remove = function(updater) { - var items = this._items; - var length = items.length; - for (var i = length - 1; i >= 0; i--) { - var item = items[i]; - if (item.remove(updater)) { - if (item.updaters.length === 0) { - items.splice(i, 1); - item.destroy(); - } - break; - } + function getNodeMatrix(node, result) { + var publicNode = node.publicNode; + var publicMatrix = publicNode.matrix; + + if (publicNode.useMatrix && defined(publicMatrix)) { + // Public matrix overrides orginial glTF matrix and glTF animations + Matrix4.clone(publicMatrix, result); + } else if (defined(node.matrix)) { + Matrix4.clone(node.matrix, result); + } else { + Matrix4.fromTranslationQuaternionRotationScale(node.translation, node.rotation, node.scale, result); + // Keep matrix returned by the node in-sync if the node is targeted by an animation. Only TRS nodes can be targeted. + publicNode.setMatrix(result); } - }; + } - StaticGeometryPerMaterialBatch.prototype.update = function(time) { - var i; - var items = this._items; - var length = items.length; + var scratchNodeStack = []; + var scratchComputedTranslation = new Cartesian4(); + var scratchComputedMatrixIn2D = new Matrix4(); - for (i = length - 1; i >= 0; i--) { - var item = items[i]; - if (item.invalidated) { - items.splice(i, 1); - var updaters = item.updaters.values; - var updatersLength = updaters.length; - for (var h = 0; h < updatersLength; h++) { - this.add(time, updaters[h]); + function updateNodeHierarchyModelMatrix(model, modelTransformChanged, justLoaded, projection) { + var maxDirtyNumber = model._maxDirtyNumber; + var allowPicking = model.allowPicking; + + var rootNodes = model._runtime.rootNodes; + var length = rootNodes.length; + + var nodeStack = scratchNodeStack; + var computedModelMatrix = model._computedModelMatrix; + + if ((model._mode !== SceneMode.SCENE3D) && !model._ignoreCommands) { + var translation = Matrix4.getColumn(computedModelMatrix, 3, scratchComputedTranslation); + if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) { + computedModelMatrix = Transforms.basisTo2D(projection, computedModelMatrix, scratchComputedMatrixIn2D); + model._rtcCenter = model._rtcCenter3D; + } else { + var center = model.boundingSphere.center; + var to2D = Transforms.wgs84To2DModelMatrix(projection, center, scratchComputedMatrixIn2D); + computedModelMatrix = Matrix4.multiply(to2D, computedModelMatrix, scratchComputedMatrixIn2D); + + if (defined(model._rtcCenter)) { + Matrix4.setTranslation(computedModelMatrix, Cartesian4.UNIT_W, computedModelMatrix); + model._rtcCenter = model._rtcCenter2D; } - item.destroy(); } } - var isUpdated = true; - for (i = 0; i < length; i++) { - isUpdated = items[i].update(time) && isUpdated; - } - return isUpdated; - }; + for (var i = 0; i < length; ++i) { + var n = rootNodes[i]; - StaticGeometryPerMaterialBatch.prototype.getBoundingSphere = function(entity, result) { - var items = this._items; - var length = items.length; - for (var i = 0; i < length; i++) { - var item = items[i]; - if(item.contains(entity)){ - return item.getBoundingSphere(entity, result); - } - } - return BoundingSphereState.FAILED; - }; + getNodeMatrix(n, n.transformToRoot); + nodeStack.push(n); - StaticGeometryPerMaterialBatch.prototype.removeAllPrimitives = function() { - var items = this._items; - var length = items.length; - for (var i = 0; i < length; i++) { - items[i].destroy(); - } - this._items.length = 0; - }; + while (nodeStack.length > 0) { + n = nodeStack.pop(); + var transformToRoot = n.transformToRoot; + var commands = n.commands; - return StaticGeometryPerMaterialBatch; -}); + if ((n.dirtyNumber === maxDirtyNumber) || modelTransformChanged || justLoaded) { + var nodeMatrix = Matrix4.multiplyTransformation(computedModelMatrix, transformToRoot, n.computedMatrix); + var commandsLength = commands.length; + if (commandsLength > 0) { + // Node has meshes, which has primitives. Update their commands. + for (var j = 0; j < commandsLength; ++j) { + var primitiveCommand = commands[j]; + var command = primitiveCommand.command; + Matrix4.clone(nodeMatrix, command.modelMatrix); -define('DataSources/StaticGroundGeometryColorBatch',[ - '../Core/AssociativeArray', - '../Core/Color', - '../Core/defined', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/GroundPrimitive', - './BoundingSphereState', - './Property' - ], function( - AssociativeArray, - Color, - defined, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - ShowGeometryInstanceAttribute, - GroundPrimitive, - BoundingSphereState, - Property) { - 'use strict'; + // PERFORMANCE_IDEA: Can use transformWithoutScale if no node up to the root has scale (including animation) + BoundingSphere.transform(primitiveCommand.boundingSphere, command.modelMatrix, command.boundingVolume); - var colorScratch = new Color(); - var distanceDisplayConditionScratch = new DistanceDisplayCondition(); + if (defined(model._rtcCenter)) { + Cartesian3.add(model._rtcCenter, command.boundingVolume.center, command.boundingVolume.center); + } - function Batch(primitives, color, key) { - this.primitives = primitives; - this.color = color; - this.key = key; - this.createPrimitive = false; - this.waitingOnCreate = false; - this.primitive = undefined; - this.oldPrimitive = undefined; - this.geometry = new AssociativeArray(); - this.updaters = new AssociativeArray(); - this.updatersWithAttributes = new AssociativeArray(); - this.attributes = new AssociativeArray(); - this.subscriptions = new AssociativeArray(); - this.showsUpdated = new AssociativeArray(); - this.itemsToRemove = []; - this.isDirty = false; - } + if (allowPicking) { + var pickCommand = primitiveCommand.pickCommand; + Matrix4.clone(command.modelMatrix, pickCommand.modelMatrix); + BoundingSphere.clone(command.boundingVolume, pickCommand.boundingVolume); + } - Batch.prototype.add = function(updater, instance) { - var id = updater.entity.id; - this.createPrimitive = true; - this.geometry.set(id, instance); - this.updaters.set(id, updater); - if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { - this.updatersWithAttributes.set(id, updater); - } else { - var that = this; - this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { - if (propertyName === 'isShowing') { - that.showsUpdated.set(entity.id, updater); + // If the model crosses the IDL in 2D, it will be drawn in one viewport, but part of it + // will be clipped by the viewport. We create a second command that translates the model + // model matrix to the opposite side of the map so the part that was clipped in one viewport + // is drawn in the other. + command = primitiveCommand.command2D; + if (defined(command) && model._mode === SceneMode.SCENE2D) { + Matrix4.clone(nodeMatrix, command.modelMatrix); + command.modelMatrix[13] -= CesiumMath.sign(command.modelMatrix[13]) * 2.0 * CesiumMath.PI * projection.ellipsoid.maximumRadius; + BoundingSphere.transform(primitiveCommand.boundingSphere, command.modelMatrix, command.boundingVolume); + + if (allowPicking) { + var pickCommand2D = primitiveCommand.pickCommand2D; + Matrix4.clone(command.modelMatrix, pickCommand2D.modelMatrix); + BoundingSphere.clone(command.boundingVolume, pickCommand2D.boundingVolume); + } + } + } + } } - })); - } - }; - Batch.prototype.remove = function(updater) { - var id = updater.entity.id; - this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; - if (this.updaters.remove(id)) { - this.updatersWithAttributes.remove(id); - var unsubscribe = this.subscriptions.get(id); - if (defined(unsubscribe)) { - unsubscribe(); - this.subscriptions.remove(id); - } - } - }; + var children = n.children; + var childrenLength = children.length; + for (var k = 0; k < childrenLength; ++k) { + var child = children[k]; - var scratchArray = new Array(4); + // A node's transform needs to be updated if + // - It was targeted for animation this frame, or + // - Any of its ancestors were targeted for animation this frame - Batch.prototype.update = function(time) { - var isUpdated = true; - var removedCount = 0; - var primitive = this.primitive; - var primitives = this.primitives; - var attributes; - var i; + // PERFORMANCE_IDEA: if a child has multiple parents and only one of the parents + // is dirty, all the subtrees for each child instance will be dirty; we probably + // won't see this in the wild often. + child.dirtyNumber = Math.max(child.dirtyNumber, n.dirtyNumber); - if (this.createPrimitive) { - var geometries = this.geometry.values; - var geometriesLength = geometries.length; - if (geometriesLength > 0) { - if (defined(primitive)) { - if (!defined(this.oldPrimitive)) { - this.oldPrimitive = primitive; - } else { - primitives.remove(primitive); + if ((child.dirtyNumber === maxDirtyNumber) || justLoaded) { + // Don't check for modelTransformChanged since if only the model's model matrix changed, + // we do not need to rebuild the local transform-to-root, only the final + // [model's-model-matrix][transform-to-root] above. + getNodeMatrix(child, child.transformToRoot); + Matrix4.multiplyTransformation(transformToRoot, child.transformToRoot, child.transformToRoot); } + + nodeStack.push(child); } + } + } - for (i = 0; i < geometriesLength; i++) { - var geometryItem = geometries[i]; - var originalAttributes = geometryItem.attributes; - attributes = this.attributes.get(geometryItem.id.id); + ++model._maxDirtyNumber; + } - if (defined(attributes)) { - if (defined(originalAttributes.show)) { - originalAttributes.show.value = attributes.show; - } - if (defined(originalAttributes.color)) { - originalAttributes.color.value = attributes.color; - } - } - } + var scratchObjectSpace = new Matrix4(); - primitive = new GroundPrimitive({ - asynchronous : true, - geometryInstances : geometries - }); - primitives.add(primitive); - isUpdated = false; - } else { - if (defined(primitive)) { - primitives.remove(primitive); - primitive = undefined; + function applySkins(model) { + var skinnedNodes = model._runtime.skinnedNodes; + var length = skinnedNodes.length; + + for (var i = 0; i < length; ++i) { + var node = skinnedNodes[i]; + + scratchObjectSpace = Matrix4.inverseTransformation(node.transformToRoot, scratchObjectSpace); + + var computedJointMatrices = node.computedJointMatrices; + var joints = node.joints; + var bindShapeMatrix = node.bindShapeMatrix; + var inverseBindMatrices = node.inverseBindMatrices; + var inverseBindMatricesLength = inverseBindMatrices.length; + + for (var m = 0; m < inverseBindMatricesLength; ++m) { + // [joint-matrix] = [node-to-root^-1][joint-to-root][inverse-bind][bind-shape] + if (!defined(computedJointMatrices[m])) { + computedJointMatrices[m] = new Matrix4(); } - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; + computedJointMatrices[m] = Matrix4.multiplyTransformation(scratchObjectSpace, joints[m].transformToRoot, computedJointMatrices[m]); + computedJointMatrices[m] = Matrix4.multiplyTransformation(computedJointMatrices[m], inverseBindMatrices[m], computedJointMatrices[m]); + if (defined(bindShapeMatrix)) { + // Optimization for when bind shape matrix is the identity. + computedJointMatrices[m] = Matrix4.multiplyTransformation(computedJointMatrices[m], bindShapeMatrix, computedJointMatrices[m]); } } + } + } - this.attributes.removeAll(); - this.primitive = primitive; - this.createPrimitive = false; - this.waitingOnCreate = true; - } else if (defined(primitive) && primitive.ready) { - if (defined(this.oldPrimitive)) { - primitives.remove(this.oldPrimitive); - this.oldPrimitive = undefined; - } - var updatersWithAttributes = this.updatersWithAttributes.values; - var length = updatersWithAttributes.length; - var waitingOnCreate = this.waitingOnCreate; - for (i = 0; i < length; i++) { - var updater = updatersWithAttributes[i]; - var instance = this.geometry.get(updater.entity.id); + function updatePerNodeShow(model) { + // Totally not worth it, but we could optimize this: + // http://blogs.agi.com/insight3d/index.php/2008/02/13/deletion-in-bounding-volume-hierarchies/ - attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); - } + var rootNodes = model._runtime.rootNodes; + var length = rootNodes.length; - if (!updater.fillMaterialProperty.isConstant || waitingOnCreate) { - var colorProperty = updater.fillMaterialProperty.color; - colorProperty.getValue(time, colorScratch); + var nodeStack = scratchNodeStack; - if (!Color.equals(attributes._lastColor, colorScratch)) { - attributes._lastColor = Color.clone(colorScratch, attributes._lastColor); - var color = this.color; - var newColor = colorScratch.toBytes(scratchArray); - if (color[0] !== newColor[0] || color[1] !== newColor[1] || - color[2] !== newColor[2] || color[3] !== newColor[3]) { - this.itemsToRemove[removedCount++] = updater; - } - } - } + for (var i = 0; i < length; ++i) { + var n = rootNodes[i]; + n.computedShow = n.publicNode.show; + nodeStack.push(n); - var show = updater.entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + while (nodeStack.length > 0) { + n = nodeStack.pop(); + var show = n.computedShow; + + var nodeCommands = n.commands; + var nodeCommandsLength = nodeCommands.length; + for (var j = 0; j < nodeCommandsLength; ++j) { + nodeCommands[j].show = show; } + // if commandsLength is zero, the node has a light or camera - var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; - if (!Property.isConstant(distanceDisplayConditionProperty)) { - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); - if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { - attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); - attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); - } + var children = n.children; + var childrenLength = children.length; + for (var k = 0; k < childrenLength; ++k) { + var child = children[k]; + // Parent needs to be shown for child to be shown. + child.computedShow = show && child.publicNode.show; + nodeStack.push(child); } } - - this.updateShows(primitive); - this.waitingOnCreate = false; - } else if (defined(primitive) && !primitive.ready) { - isUpdated = false; } - this.itemsToRemove.length = removedCount; - return isUpdated; - }; - - Batch.prototype.updateShows = function(primitive) { - var showsUpdated = this.showsUpdated.values; - var length = showsUpdated.length; - for (var i = 0; i < length; i++) { - var updater = showsUpdated[i]; - var instance = this.geometry.get(updater.entity.id); + } - var attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); - } + function updatePickIds(model, context) { + var id = model.id; + if (model._id !== id) { + model._id = id; - var show = updater.entity.isShowing; - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + var pickIds = model._pickIds; + var length = pickIds.length; + for (var i = 0; i < length; ++i) { + pickIds[i].object.id = id; } } - this.showsUpdated.removeAll(); - }; + } - Batch.prototype.contains = function(entity) { - return this.updaters.contains(entity.id); - }; + function updateWireframe(model) { + if (model._debugWireframe !== model.debugWireframe) { + model._debugWireframe = model.debugWireframe; - Batch.prototype.getBoundingSphere = function(entity, result) { - var primitive = this.primitive; - if (!primitive.ready) { - return BoundingSphereState.PENDING; - } + // This assumes the original primitive was TRIANGLES and that the triangles + // are connected for the wireframe to look perfect. + var primitiveType = model.debugWireframe ? PrimitiveType.LINES : PrimitiveType.TRIANGLES; + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; - var bs = primitive.getBoundingSphere(entity); - if (!defined(bs)) { - return BoundingSphereState.FAILED; + for (var i = 0; i < length; ++i) { + nodeCommands[i].command.primitiveType = primitiveType; + } } + } - bs.clone(result); - return BoundingSphereState.DONE; - }; - - Batch.prototype.removeAllPrimitives = function() { - var primitives = this.primitives; + function updateShowBoundingVolume(model) { + if (model.debugShowBoundingVolume !== model._debugShowBoundingVolume) { + model._debugShowBoundingVolume = model.debugShowBoundingVolume; - var primitive = this.primitive; - if (defined(primitive)) { - primitives.remove(primitive); - this.primitive = undefined; - this.geometry.removeAll(); - this.updaters.removeAll(); - } + var debugShowBoundingVolume = model.debugShowBoundingVolume; + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; + for (var i = 0; i < length; ++i) { + nodeCommands[i].command.debugShowBoundingVolume = debugShowBoundingVolume; + } } - }; - - /** - * @private - */ - function StaticGroundGeometryColorBatch(primitives) { - this._batches = new AssociativeArray(); - this._primitives = primitives; } - StaticGroundGeometryColorBatch.prototype.add = function(time, updater) { - var instance = updater.createFillGeometryInstance(time); - var batches = this._batches; - // instance.attributes.color.value is a Uint8Array, so just read it as a Uint32 and make that the key - var batchKey = new Uint32Array(instance.attributes.color.value.buffer)[0]; - var batch; - if (batches.contains(batchKey)) { - batch = batches.get(batchKey); - } else { - batch = new Batch(this._primitives, instance.attributes.color.value, batchKey); - batches.set(batchKey, batch); - } - batch.add(updater, instance); - return batch; - }; + function updateShadows(model) { + if (model.shadows !== model._shadows) { + model._shadows = model.shadows; - StaticGroundGeometryColorBatch.prototype.remove = function(updater) { - var batchesArray = this._batches.values; - var count = batchesArray.length; - for (var i = 0; i < count; ++i) { - if (batchesArray[i].remove(updater)) { - return; + var castShadows = ShadowMode.castShadows(model.shadows); + var receiveShadows = ShadowMode.receiveShadows(model.shadows); + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; + + for (var i = 0; i < length; i++) { + var nodeCommand = nodeCommands[i]; + nodeCommand.command.castShadows = castShadows; + nodeCommand.command.receiveShadows = receiveShadows; } } - }; + } - StaticGroundGeometryColorBatch.prototype.update = function(time) { - var i; - var updater; + function getTranslucentRenderState(renderState) { + var rs = clone(renderState, true); + rs.cull.enabled = false; + rs.depthTest.enabled = true; + rs.depthMask = false; + rs.blending = BlendingState.ALPHA_BLEND; - //Perform initial update - var isUpdated = true; - var batches = this._batches; - var batchesArray = batches.values; - var batchCount = batchesArray.length; - for (i = 0; i < batchCount; ++i) { - isUpdated = batchesArray[i].update(time) && isUpdated; - } + return RenderState.fromCache(rs); + } - //If any items swapped between batches we need to move them - for (i = 0; i < batchCount; ++i) { - var oldBatch = batchesArray[i]; - var itemsToRemove = oldBatch.itemsToRemove; - var itemsToMoveLength = itemsToRemove.length; - for (var j = 0; j < itemsToMoveLength; j++) { - updater = itemsToRemove[j]; - oldBatch.remove(updater); - var newBatch = this.add(time, updater); - oldBatch.isDirty = true; - newBatch.isDirty = true; - } - } + function deriveTranslucentCommand(command) { + var translucentCommand = DrawCommand.shallowClone(command); + translucentCommand.pass = Pass.TRANSLUCENT; + translucentCommand.renderState = getTranslucentRenderState(command.renderState); + return translucentCommand; + } - //If we moved anything around, we need to re-build the primitive and remove empty batches - var batchesArrayCopy = batchesArray.slice(); - var batchesCopyCount = batchesArrayCopy.length; - for (i = 0; i < batchesCopyCount; ++i) { - var batch = batchesArrayCopy[i]; - if (batch.isDirty) { - isUpdated = batchesArrayCopy[i].update(time) && isUpdated; - batch.isDirty = false; - } - if (batch.geometry.length === 0) { - batches.remove(batch.key); + function updateColor(model, frameState) { + // Generate translucent commands when the blend color has an alpha in the range (0.0, 1.0) exclusive + var scene3DOnly = frameState.scene3DOnly; + var alpha = model.color.alpha; + if ((alpha > 0.0) && (alpha < 1.0)) { + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; + if (!defined(nodeCommands[0].translucentCommand)) { + for (var i = 0; i < length; ++i) { + var nodeCommand = nodeCommands[i]; + var command = nodeCommand.command; + nodeCommand.translucentCommand = deriveTranslucentCommand(command); + if (!scene3DOnly) { + var command2D = nodeCommand.command2D; + nodeCommand.translucentCommand2D = deriveTranslucentCommand(command2D); + } + } } } + } - return isUpdated; - }; - - StaticGroundGeometryColorBatch.prototype.getBoundingSphere = function(entity, result) { - var batchesArray = this._batches.values; - var batchCount = batchesArray.length; - for (var i = 0; i < batchCount; ++i) { - var batch = batchesArray[i]; - if (batch.contains(entity)) { - return batch.getBoundingSphere(entity, result); + function getProgramId(model, program) { + var programs = model._rendererResources.programs; + for (var id in programs) { + if (programs.hasOwnProperty(id)) { + if (programs[id] === program) { + return id; + } } } + } - return BoundingSphereState.FAILED; - }; + function createSilhouetteProgram(model, program, frameState) { + var vs = program.vertexShaderSource.sources[0]; + var attributeLocations = program._attributeLocations; + var normalAttributeName = model._normalAttributeName; - StaticGroundGeometryColorBatch.prototype.removeAllPrimitives = function() { - var batchesArray = this._batches.values; - var batchCount = batchesArray.length; - for (var i = 0; i < batchCount; ++i) { - batchesArray[i].removeAllPrimitives(); - } - }; + // Modified from http://forum.unity3d.com/threads/toon-outline-but-with-diffuse-surface.24668/ + vs = ShaderSource.replaceMain(vs, 'gltf_silhouette_main'); + vs += + 'uniform float gltf_silhouetteSize; \n' + + 'void main() \n' + + '{ \n' + + ' gltf_silhouette_main(); \n' + + ' vec3 n = normalize(czm_normal3D * ' + normalAttributeName + '); \n' + + ' n.x *= czm_projection[0][0]; \n' + + ' n.y *= czm_projection[1][1]; \n' + + ' vec4 clip = gl_Position; \n' + + ' clip.xy += n.xy * clip.w * gltf_silhouetteSize / czm_viewport.z; \n' + + ' gl_Position = clip; \n' + + '}'; - return StaticGroundGeometryColorBatch; -}); + var fs = + 'uniform vec4 gltf_silhouetteColor; \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragColor = gltf_silhouetteColor; \n' + + '}'; -define('DataSources/StaticOutlineGeometryBatch',[ - '../Core/AssociativeArray', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defined', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - './BoundingSphereState', - './Property' - ], function( - AssociativeArray, - Color, - ColorGeometryInstanceAttribute, - defined, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - ShowGeometryInstanceAttribute, - PerInstanceColorAppearance, - Primitive, - BoundingSphereState, - Property) { - 'use strict'; + return ShaderProgram.fromCache({ + context : frameState.context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } - function Batch(primitives, translucent, width, shadows) { - this.translucent = translucent; - this.width = width; - this.shadows = shadows; - this.primitives = primitives; - this.createPrimitive = false; - this.waitingOnCreate = false; - this.primitive = undefined; - this.oldPrimitive = undefined; - this.geometry = new AssociativeArray(); - this.updaters = new AssociativeArray(); - this.updatersWithAttributes = new AssociativeArray(); - this.attributes = new AssociativeArray(); - this.itemsToRemove = []; - this.subscriptions = new AssociativeArray(); - this.showsUpdated = new AssociativeArray(); + function hasSilhouette(model, frameState) { + return silhouetteSupported(frameState.context) && (model.silhouetteSize > 0.0) && (model.silhouetteColor.alpha > 0.0) && defined(model._normalAttributeName); } - Batch.prototype.add = function(updater, instance) { - var id = updater.entity.id; - this.createPrimitive = true; - this.geometry.set(id, instance); - this.updaters.set(id, updater); - if (!updater.hasConstantOutline || !updater.outlineColorProperty.isConstant || !Property.isConstant(updater.distanceDisplayConditionProperty)) { - this.updatersWithAttributes.set(id, updater); - } else { - var that = this; - this.subscriptions.set(id, updater.entity.definitionChanged.addEventListener(function(entity, propertyName, newValue, oldValue) { - if (propertyName === 'isShowing') { - that.showsUpdated.set(entity.id, updater); - } - })); - } - }; - Batch.prototype.remove = function(updater) { - var id = updater.entity.id; - this.createPrimitive = this.geometry.remove(id) || this.createPrimitive; - if (this.updaters.remove(id)) { - this.updatersWithAttributes.remove(id); - var unsubscribe = this.subscriptions.get(id); - if (defined(unsubscribe)) { - unsubscribe(); - this.subscriptions.remove(id); + function hasTranslucentCommands(model) { + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; + for (var i = 0; i < length; ++i) { + var nodeCommand = nodeCommands[i]; + var command = nodeCommand.command; + if (command.pass === Pass.TRANSLUCENT) { + return true; } } - }; + return false; + } - var colorScratch = new Color(); - var distanceDisplayConditionScratch = new DistanceDisplayCondition(); + function isTranslucent(model) { + return (model.color.alpha > 0.0) && (model.color.alpha < 1.0); + } - Batch.prototype.update = function(time) { - var isUpdated = true; - var removedCount = 0; - var primitive = this.primitive; - var primitives = this.primitives; - var attributes; - var i; + function isInvisible(model) { + return (model.color.alpha === 0.0); + } - if (this.createPrimitive) { - var geometries = this.geometry.values; - var geometriesLength = geometries.length; - if (geometriesLength > 0) { - if (defined(primitive)) { - if (!defined(this.oldPrimitive)) { - this.oldPrimitive = primitive; - } else { - primitives.remove(primitive); - } - } + function alphaDirty(currAlpha, prevAlpha) { + // Returns whether the alpha state has changed between invisible, translucent, or opaque + return (Math.floor(currAlpha) !== Math.floor(prevAlpha)) || (Math.ceil(currAlpha) !== Math.ceil(prevAlpha)); + } - for (i = 0; i < geometriesLength; i++) { - var geometryItem = geometries[i]; - var originalAttributes = geometryItem.attributes; - attributes = this.attributes.get(geometryItem.id.id); + var silhouettesLength = 0; - if (defined(attributes)) { - if (defined(originalAttributes.show)) { - originalAttributes.show.value = attributes.show; - } - if (defined(originalAttributes.color)) { - originalAttributes.color.value = attributes.color; - } - } - } + function createSilhouetteCommands(model, frameState) { + // Wrap around after exceeding the 8-bit stencil limit. + // The reference is unique to each model until this point. + var stencilReference = (++silhouettesLength) % 255; + + // If the model is translucent the silhouette needs to be in the translucent pass. + // Otherwise the silhouette would be rendered before the model. + var silhouetteTranslucent = hasTranslucentCommands(model) || isTranslucent(model) || (model.silhouetteColor.alpha < 1.0); + var silhouettePrograms = model._rendererResources.silhouettePrograms; + var scene3DOnly = frameState.scene3DOnly; + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; + for (var i = 0; i < length; ++i) { + var nodeCommand = nodeCommands[i]; + var command = nodeCommand.command; - primitive = new Primitive({ - asynchronous : true, - geometryInstances : geometries, - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : this.translucent, - renderState : { - lineWidth : this.width - } - }), - shadows : this.shadows - }); + // Create model command + var modelCommand = isTranslucent(model) ? nodeCommand.translucentCommand : command; + var silhouetteModelCommand = DrawCommand.shallowClone(modelCommand); + var renderState = clone(modelCommand.renderState); - primitives.add(primitive); - isUpdated = false; - } else { - if (defined(primitive)) { - primitives.remove(primitive); - primitive = undefined; - } - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; + // Write the reference value into the stencil buffer. + renderState.stencilTest = { + enabled : true, + frontFunction : WebGLConstants.ALWAYS, + backFunction : WebGLConstants.ALWAYS, + reference : stencilReference, + mask : ~0, + frontOperation : { + fail : WebGLConstants.KEEP, + zFail : WebGLConstants.KEEP, + zPass : WebGLConstants.REPLACE + }, + backOperation : { + fail : WebGLConstants.KEEP, + zFail : WebGLConstants.KEEP, + zPass : WebGLConstants.REPLACE } - } + }; - this.attributes.removeAll(); - this.primitive = primitive; - this.createPrimitive = false; - this.waitingOnCreate = true; - } else if (defined(primitive) && primitive.ready) { - if (defined(this.oldPrimitive)) { - primitives.remove(this.oldPrimitive); - this.oldPrimitive = undefined; + if (isInvisible(model)) { + // When the model is invisible disable color and depth writes but still write into the stencil buffer + renderState.colorMask = { + red : false, + green : false, + blue : false, + alpha : false + }; + renderState.depthMask = false; } + renderState = RenderState.fromCache(renderState); + silhouetteModelCommand.renderState = renderState; + nodeCommand.silhouetteModelCommand = silhouetteModelCommand; - var updatersWithAttributes = this.updatersWithAttributes.values; - var length = updatersWithAttributes.length; - var waitingOnCreate = this.waitingOnCreate; - for (i = 0; i < length; i++) { - var updater = updatersWithAttributes[i]; - var instance = this.geometry.get(updater.entity.id); - - attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); - } - - if (!updater.outlineColorProperty.isConstant || waitingOnCreate) { - var outlineColorProperty = updater.outlineColorProperty; - outlineColorProperty.getValue(time, colorScratch); - if (!Color.equals(attributes._lastColor, colorScratch)) { - attributes._lastColor = Color.clone(colorScratch, attributes._lastColor); - attributes.color = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.color); - if ((this.translucent && attributes.color[3] === 255) || (!this.translucent && attributes.color[3] !== 255)) { - this.itemsToRemove[removedCount++] = updater; - } - } - } + // Create color command + var silhouetteColorCommand = DrawCommand.shallowClone(command); + renderState = clone(command.renderState, true); + renderState.depthTest.enabled = true; + renderState.cull.enabled = false; + if (silhouetteTranslucent) { + silhouetteColorCommand.pass = Pass.TRANSLUCENT; + renderState.depthMask = false; + renderState.blending = BlendingState.ALPHA_BLEND; + } - var show = updater.entity.isShowing && (updater.hasConstantOutline || updater.isOutlineVisible(time)); - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + // Only render silhouette if the value in the stencil buffer equals the reference + renderState.stencilTest = { + enabled : true, + frontFunction : WebGLConstants.NOTEQUAL, + backFunction : WebGLConstants.NOTEQUAL, + reference : stencilReference, + mask : ~0, + frontOperation : { + fail : WebGLConstants.KEEP, + zFail : WebGLConstants.KEEP, + zPass : WebGLConstants.KEEP + }, + backOperation : { + fail : WebGLConstants.KEEP, + zFail : WebGLConstants.KEEP, + zPass : WebGLConstants.KEEP } + }; + renderState = RenderState.fromCache(renderState); - var distanceDisplayConditionProperty = updater.distanceDisplayConditionProperty; - if (!Property.isConstant(distanceDisplayConditionProperty)) { - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time, distanceDisplayConditionScratch); - if (!DistanceDisplayCondition.equals(distanceDisplayCondition, attributes._lastDistanceDisplayCondition)) { - attributes._lastDistanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition, attributes._lastDistanceDisplayCondition); - attributes.distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.toValue(distanceDisplayCondition, attributes.distanceDisplayCondition); - } - } + // If the silhouette program has already been cached use it + var program = command.shaderProgram; + var id = getProgramId(model, program); + var silhouetteProgram = silhouettePrograms[id]; + if (!defined(silhouetteProgram)) { + silhouetteProgram = createSilhouetteProgram(model, program, frameState); + silhouettePrograms[id] = silhouetteProgram; } - this.updateShows(primitive); - this.waitingOnCreate = false; - } else if (defined(primitive) && !primitive.ready) { - isUpdated = false; - } - - this.itemsToRemove.length = removedCount; - return isUpdated; - }; + var silhouetteUniformMap = combine(command.uniformMap, { + gltf_silhouetteColor : createSilhouetteColorFunction(model), + gltf_silhouetteSize : createSilhouetteSizeFunction(model) + }); - Batch.prototype.updateShows = function(primitive) { - var showsUpdated = this.showsUpdated.values; - var length = showsUpdated.length; - for (var i = 0; i < length; i++) { - var updater = showsUpdated[i]; - var instance = this.geometry.get(updater.entity.id); + silhouetteColorCommand.renderState = renderState; + silhouetteColorCommand.shaderProgram = silhouetteProgram; + silhouetteColorCommand.uniformMap = silhouetteUniformMap; + silhouetteColorCommand.castShadows = false; + silhouetteColorCommand.receiveShadows = false; + nodeCommand.silhouetteColorCommand = silhouetteColorCommand; - var attributes = this.attributes.get(instance.id.id); - if (!defined(attributes)) { - attributes = primitive.getGeometryInstanceAttributes(instance.id); - this.attributes.set(instance.id.id, attributes); - } + if (!scene3DOnly) { + var command2D = nodeCommand.command2D; + var silhouetteModelCommand2D = DrawCommand.shallowClone(silhouetteModelCommand); + silhouetteModelCommand2D.boundingVolume = command2D.boundingVolume; + silhouetteModelCommand2D.modelMatrix = command2D.modelMatrix; + nodeCommand.silhouetteModelCommand2D = silhouetteModelCommand2D; - var show = updater.entity.isShowing; - var currentShow = attributes.show[0] === 1; - if (show !== currentShow) { - attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show); + var silhouetteColorCommand2D = DrawCommand.shallowClone(silhouetteColorCommand); + silhouetteModelCommand2D.boundingVolume = command2D.boundingVolume; + silhouetteModelCommand2D.modelMatrix = command2D.modelMatrix; + nodeCommand.silhouetteColorCommand2D = silhouetteColorCommand2D; } } - this.showsUpdated.removeAll(); - }; + } - Batch.prototype.contains = function(entity) { - return this.updaters.contains(entity.id); - }; + function modifyShaderForClippingPlanes(shader) { + shader = ShaderSource.replaceMain(shader, 'gltf_clip_main'); + shader += + 'uniform int gltf_clippingPlanesLength; \n' + + 'uniform bool gltf_clippingPlanesUnionRegions; \n' + + 'uniform vec4 gltf_clippingPlanes[czm_maxClippingPlanes]; \n' + + 'uniform vec4 gltf_clippingPlanesEdgeStyle; \n' + + 'void main() \n' + + '{ \n' + + ' gltf_clip_main(); \n' + + ' if (gltf_clippingPlanesLength > 0) \n' + + ' { \n' + + ' float clipDistance; \n' + + ' if (gltf_clippingPlanesUnionRegions) \n' + + ' { \n' + + ' clipDistance = czm_discardIfClippedWithUnion(gltf_clippingPlanes, gltf_clippingPlanesLength); \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' clipDistance = czm_discardIfClippedWithIntersect(gltf_clippingPlanes, gltf_clippingPlanesLength); \n' + + ' } \n' + + ' \n' + + ' vec4 clippingPlanesEdgeColor = vec4(1.0); \n' + + ' clippingPlanesEdgeColor.rgb = gltf_clippingPlanesEdgeStyle.rgb; \n' + + ' float clippingPlanesEdgeWidth = gltf_clippingPlanesEdgeStyle.a; \n' + + ' if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n' + + ' { \n' + + ' gl_FragColor = clippingPlanesEdgeColor; \n' + + ' } \n' + + ' } \n' + + '} \n'; - Batch.prototype.getBoundingSphere = function(entity, result) { - var primitive = this.primitive; - if (!primitive.ready) { - return BoundingSphereState.PENDING; - } - var attributes = primitive.getGeometryInstanceAttributes(entity); - if (!defined(attributes) || !defined(attributes.boundingSphere) ||// - (defined(attributes.show) && attributes.show[0] === 0)) { - return BoundingSphereState.FAILED; + return shader; + } + + function updateSilhouette(model, frameState) { + // Generate silhouette commands when the silhouette size is greater than 0.0 and the alpha is greater than 0.0 + // There are two silhouette commands: + // 1. silhouetteModelCommand : render model normally while enabling stencil mask + // 2. silhouetteColorCommand : render enlarged model with a solid color while enabling stencil tests + if (!hasSilhouette(model, frameState)) { + return; } - attributes.boundingSphere.clone(result); - return BoundingSphereState.DONE; - }; - Batch.prototype.removeAllPrimitives = function() { - var primitives = this.primitives; + var nodeCommands = model._nodeCommands; + var dirty = alphaDirty(model.color.alpha, model._colorPreviousAlpha) || + alphaDirty(model.silhouetteColor.alpha, model._silhouetteColorPreviousAlpha) || + !defined(nodeCommands[0].silhouetteModelCommand); - var primitive = this.primitive; - if (defined(primitive)) { - primitives.remove(primitive); - this.primitive = undefined; - this.geometry.removeAll(); - this.updaters.removeAll(); - } + model._colorPreviousAlpha = model.color.alpha; + model._silhouetteColorPreviousAlpha = model.silhouetteColor.alpha; - var oldPrimitive = this.oldPrimitive; - if (defined(oldPrimitive)) { - primitives.remove(oldPrimitive); - this.oldPrimitive = undefined; + if (dirty) { + createSilhouetteCommands(model, frameState); } - }; - - /** - * @private - */ - function StaticOutlineGeometryBatch(primitives, scene, shadows) { - this._primitives = primitives; - this._scene = scene; - this._shadows = shadows; - this._solidBatches = new AssociativeArray(); - this._translucentBatches = new AssociativeArray(); } - StaticOutlineGeometryBatch.prototype.add = function(time, updater) { - var instance = updater.createOutlineGeometryInstance(time); - var width = this._scene.clampLineWidth(updater.outlineWidth); - var batches; - var batch; - if (instance.attributes.color.value[3] === 255) { - batches = this._solidBatches; - batch = batches.get(width); - if (!defined(batch)) { - batch = new Batch(this._primitives, false, width, this._shadows); - batches.set(width, batch); - } - batch.add(updater, instance); - } else { - batches = this._translucentBatches; - batch = batches.get(width); - if (!defined(batch)) { - batch = new Batch(this._primitives, true, width, this._shadows); - batches.set(width, batch); - } - batch.add(updater, instance); + + function updateClippingPlanes(model) { + var clippingPlanes = model.clippingPlanes; + var length = 0; + if (defined(clippingPlanes) && clippingPlanes.enabled) { + length = clippingPlanes.length; } - }; - StaticOutlineGeometryBatch.prototype.remove = function(updater) { - var i; + var packedPlanes = model._packedClippingPlanes; + var packedLength = packedPlanes.length; + if (packedLength !== length) { + packedPlanes.length = length; - var solidBatches = this._solidBatches.values; - var solidBatchesLength = solidBatches.length; - for (i = 0; i < solidBatchesLength; i++) { - if (solidBatches[i].remove(updater)) { - return; + for (var i = packedLength; i < length; ++i) { + packedPlanes[i] = new Cartesian4(); } } + } - var translucentBatches = this._translucentBatches.values; - var translucentBatchesLength = translucentBatches.length; - for (i = 0; i < translucentBatchesLength; i++) { - if (translucentBatches[i].remove(updater)) { - return; - } - } - }; + var scratchBoundingSphere = new BoundingSphere(); - StaticOutlineGeometryBatch.prototype.update = function(time) { - var i; - var x; - var updater; - var batch; - var solidBatches = this._solidBatches.values; - var solidBatchesLength = solidBatches.length; - var translucentBatches = this._translucentBatches.values; - var translucentBatchesLength = translucentBatches.length; - var itemsToRemove; - var isUpdated = true; - var needUpdate = false; + function scaleInPixels(positionWC, radius, frameState) { + scratchBoundingSphere.center = positionWC; + scratchBoundingSphere.radius = radius; + return frameState.camera.getPixelSize(scratchBoundingSphere, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); + } - do { - needUpdate = false; - for (x = 0; x < solidBatchesLength; x++) { - batch = solidBatches[x]; - //Perform initial update - isUpdated = batch.update(time); + var scratchPosition = new Cartesian3(); + var scratchCartographic = new Cartographic(); - //If any items swapped between solid/translucent, we need to - //move them between batches - itemsToRemove = batch.itemsToRemove; - var solidsToMoveLength = itemsToRemove.length; - if (solidsToMoveLength > 0) { - needUpdate = true; - for (i = 0; i < solidsToMoveLength; i++) { - updater = itemsToRemove[i]; - batch.remove(updater); - this.add(time, updater); - } - } + function getScale(model, frameState) { + var scale = model.scale; + + if (model.minimumPixelSize !== 0.0) { + // Compute size of bounding sphere in pixels + var context = frameState.context; + var maxPixelSize = Math.max(context.drawingBufferWidth, context.drawingBufferHeight); + var m = defined(model._clampedModelMatrix) ? model._clampedModelMatrix : model.modelMatrix; + scratchPosition.x = m[12]; + scratchPosition.y = m[13]; + scratchPosition.z = m[14]; + + if (defined(model._rtcCenter)) { + Cartesian3.add(model._rtcCenter, scratchPosition, scratchPosition); } - for (x = 0; x < translucentBatchesLength; x++) { - batch = translucentBatches[x]; - //Perform initial update - isUpdated = batch.update(time); - //If any items swapped between solid/translucent, we need to - //move them between batches - itemsToRemove = batch.itemsToRemove; - var translucentToMoveLength = itemsToRemove.length; - if (translucentToMoveLength > 0) { - needUpdate = true; - for (i = 0; i < translucentToMoveLength; i++) { - updater = itemsToRemove[i]; - batch.remove(updater); - this.add(time, updater); - } - } + if (model._mode !== SceneMode.SCENE3D) { + var projection = frameState.mapProjection; + var cartographic = projection.ellipsoid.cartesianToCartographic(scratchPosition, scratchCartographic); + projection.project(cartographic, scratchPosition); + Cartesian3.fromElements(scratchPosition.z, scratchPosition.x, scratchPosition.y, scratchPosition); } - } while (needUpdate); - return isUpdated; - }; + var radius = model.boundingSphere.radius; + var metersPerPixel = scaleInPixels(scratchPosition, radius, frameState); - StaticOutlineGeometryBatch.prototype.getBoundingSphere = function(entity, result) { - var i; + // metersPerPixel is always > 0.0 + var pixelsPerMeter = 1.0 / metersPerPixel; + var diameterInPixels = Math.min(pixelsPerMeter * (2.0 * radius), maxPixelSize); - var solidBatches = this._solidBatches.values; - var solidBatchesLength = solidBatches.length; - for (i = 0; i < solidBatchesLength; i++) { - var solidBatch = solidBatches[i]; - if(solidBatch.contains(entity)){ - return solidBatch.getBoundingSphere(entity, result); + // Maintain model's minimum pixel size + if (diameterInPixels < model.minimumPixelSize) { + scale = (model.minimumPixelSize * metersPerPixel) / (2.0 * model._initialRadius); } } - var translucentBatches = this._translucentBatches.values; - var translucentBatchesLength = translucentBatches.length; - for (i = 0; i < translucentBatchesLength; i++) { - var translucentBatch = translucentBatches[i]; - if(translucentBatch.contains(entity)){ - return translucentBatch.getBoundingSphere(entity, result); - } + return defined(model.maximumScale) ? Math.min(model.maximumScale, scale) : scale; + } + + function releaseCachedGltf(model) { + if (defined(model._cacheKey) && defined(model._cachedGltf) && (--model._cachedGltf.count === 0)) { + delete gltfCache[model._cacheKey]; } + model._cachedGltf = undefined; + } - return BoundingSphereState.FAILED; - }; + /////////////////////////////////////////////////////////////////////////// - StaticOutlineGeometryBatch.prototype.removeAllPrimitives = function() { - var i; + function CachedRendererResources(context, cacheKey) { + this.buffers = undefined; + this.vertexArrays = undefined; + this.programs = undefined; + this.pickPrograms = undefined; + this.silhouettePrograms = undefined; + this.textures = undefined; + this.samplers = undefined; + this.renderStates = undefined; + this.ready = false; - var solidBatches = this._solidBatches.values; - var solidBatchesLength = solidBatches.length; - for (i = 0; i < solidBatchesLength; i++) { - solidBatches[i].removeAllPrimitives(); + this.context = context; + this.cacheKey = cacheKey; + this.count = 0; + } + + function destroy(property) { + for (var name in property) { + if (property.hasOwnProperty(name)) { + property[name].destroy(); + } } + } - var translucentBatches = this._translucentBatches.values; - var translucentBatchesLength = translucentBatches.length; - for (i = 0; i < translucentBatchesLength; i++) { - translucentBatches[i].removeAllPrimitives(); + function destroyCachedRendererResources(resources) { + destroy(resources.buffers); + destroy(resources.vertexArrays); + destroy(resources.programs); + destroy(resources.pickPrograms); + destroy(resources.silhouettePrograms); + destroy(resources.textures); + } + + CachedRendererResources.prototype.release = function() { + if (--this.count === 0) { + if (defined(this.cacheKey)) { + // Remove if this was cached + delete this.context.cache.modelRendererResourceCache[this.cacheKey]; + } + destroyCachedRendererResources(this); + return destroyObject(this); } + + return undefined; }; - return StaticOutlineGeometryBatch; -}); + /////////////////////////////////////////////////////////////////////////// -define('DataSources/GeometryVisualizer',[ - '../Core/AssociativeArray', - '../Core/BoundingSphere', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Scene/ShadowMode', - './BoundingSphereState', - './ColorMaterialProperty', - './StaticGeometryColorBatch', - './StaticGeometryPerMaterialBatch', - './StaticGroundGeometryColorBatch', - './StaticOutlineGeometryBatch' - ], function( - AssociativeArray, - BoundingSphere, - defined, - destroyObject, - DeveloperError, - ShadowMode, - BoundingSphereState, - ColorMaterialProperty, - StaticGeometryColorBatch, - StaticGeometryPerMaterialBatch, - StaticGroundGeometryColorBatch, - StaticOutlineGeometryBatch) { - 'use strict'; + function getUpdateHeightCallback(model, ellipsoid, cartoPosition) { + return function(clampedPosition) { + if (model.heightReference === HeightReference.RELATIVE_TO_GROUND) { + var clampedCart = ellipsoid.cartesianToCartographic(clampedPosition, scratchCartographic); + clampedCart.height += cartoPosition.height; + ellipsoid.cartographicToCartesian(clampedCart, clampedPosition); + } - var emptyArray = []; + var clampedModelMatrix = model._clampedModelMatrix; - function DynamicGeometryBatch(primitives, groundPrimitives) { - this._primitives = primitives; - this._groundPrimitives = groundPrimitives; - this._dynamicUpdaters = new AssociativeArray(); + // Modify clamped model matrix to use new height + Matrix4.clone(model.modelMatrix, clampedModelMatrix); + clampedModelMatrix[12] = clampedPosition.x; + clampedModelMatrix[13] = clampedPosition.y; + clampedModelMatrix[14] = clampedPosition.z; + + model._heightChanged = true; + }; } - DynamicGeometryBatch.prototype.add = function(time, updater) { - this._dynamicUpdaters.set(updater.entity.id, updater.createDynamicUpdater(this._primitives, this._groundPrimitives)); - }; - DynamicGeometryBatch.prototype.remove = function(updater) { - var id = updater.entity.id; - var dynamicUpdater = this._dynamicUpdaters.get(id); - if (defined(dynamicUpdater)) { - this._dynamicUpdaters.remove(id); - dynamicUpdater.destroy(); + function updateClamping(model) { + if (defined(model._removeUpdateHeightCallback)) { + model._removeUpdateHeightCallback(); + model._removeUpdateHeightCallback = undefined; } - }; - DynamicGeometryBatch.prototype.update = function(time) { - var geometries = this._dynamicUpdaters.values; - for (var i = 0, len = geometries.length; i < len; i++) { - geometries[i].update(time); + var scene = model._scene; + if (!defined(scene) || !defined(scene.globe) || (model.heightReference === HeightReference.NONE)) { + if (model.heightReference !== HeightReference.NONE) { + throw new DeveloperError('Height reference is not supported without a scene and globe.'); + } + model._clampedModelMatrix = undefined; + return; } - return true; - }; - DynamicGeometryBatch.prototype.removeAllPrimitives = function() { - var geometries = this._dynamicUpdaters.values; - for (var i = 0, len = geometries.length; i < len; i++) { - geometries[i].destroy(); - } - this._dynamicUpdaters.removeAll(); - }; + var globe = scene.globe; + var ellipsoid = globe.ellipsoid; - DynamicGeometryBatch.prototype.getBoundingSphere = function(entity, result) { - var updater = this._dynamicUpdaters.get(entity.id); - if (defined(updater) && defined(updater.getBoundingSphere)) { - return updater.getBoundingSphere(entity, result); - } - return BoundingSphereState.FAILED; - }; + // Compute cartographic position so we don't recompute every update + var modelMatrix = model.modelMatrix; + scratchPosition.x = modelMatrix[12]; + scratchPosition.y = modelMatrix[13]; + scratchPosition.z = modelMatrix[14]; + var cartoPosition = ellipsoid.cartesianToCartographic(scratchPosition); - function removeUpdater(that, updater) { - //We don't keep track of which batch an updater is in, so just remove it from all of them. - var batches = that._batches; - var length = batches.length; - for (var i = 0; i < length; i++) { - batches[i].remove(updater); + if (!defined(model._clampedModelMatrix)) { + model._clampedModelMatrix = Matrix4.clone(modelMatrix, new Matrix4()); } - } - function insertUpdaterIntoBatch(that, time, updater) { - if (updater.isDynamic) { - that._dynamicBatch.add(time, updater); - return; - } + // Install callback to handle updating of terrain tiles + var surface = globe._surface; + model._removeUpdateHeightCallback = surface.updateHeight(cartoPosition, getUpdateHeightCallback(model, ellipsoid, cartoPosition)); - var shadows; - if (updater.outlineEnabled || updater.fillEnabled) { - shadows = updater.shadowsProperty.getValue(time); - } + // Set the correct height now + var height = globe.getHeight(cartoPosition); + if (defined(height)) { + // Get callback with cartoPosition being the non-clamped position + var cb = getUpdateHeightCallback(model, ellipsoid, cartoPosition); - if (updater.outlineEnabled) { - that._outlineBatches[shadows].add(time, updater); + // Compute the clamped cartesian and call updateHeight callback + Cartographic.clone(cartoPosition, scratchCartographic); + scratchCartographic.height = height; + ellipsoid.cartographicToCartesian(scratchCartographic, scratchPosition); + cb(scratchPosition); } + } - var multiplier = 0; - if (defined(updater.depthFailMaterialProperty)) { - multiplier = updater.depthFailMaterialProperty instanceof ColorMaterialProperty ? 1 : 2; - } + var scratchDisplayConditionCartesian = new Cartesian3(); + var scratchDistanceDisplayConditionCartographic = new Cartographic(); - var index; - if (defined(shadows)) { - index = shadows + multiplier * ShadowMode.NUMBER_OF_SHADOW_MODES; - } + function distanceDisplayConditionVisible(model, frameState) { + var distance2; + var ddc = model.distanceDisplayCondition; + var nearSquared = ddc.near * ddc.near; + var farSquared = ddc.far * ddc.far; - if (updater.fillEnabled) { - if (updater.onTerrain) { - that._groundColorBatch.add(time, updater); - } else if (updater.isClosed) { - if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { - that._closedColorBatches[index].add(time, updater); - } else { - that._closedMaterialBatches[index].add(time, updater); - } - } else if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { - that._openColorBatches[index].add(time, updater); - } else { - that._openMaterialBatches[index].add(time, updater); + if (frameState.mode === SceneMode.SCENE2D) { + var frustum2DWidth = frameState.camera.frustum.right - frameState.camera.frustum.left; + distance2 = frustum2DWidth * 0.5; + distance2 = distance2 * distance2; + } else { + // Distance to center of primitive's reference frame + var position = Matrix4.getTranslation(model.modelMatrix, scratchDisplayConditionCartesian); + if (frameState.mode === SceneMode.COLUMBUS_VIEW) { + var projection = frameState.mapProjection; + var ellipsoid = projection.ellipsoid; + var cartographic = ellipsoid.cartesianToCartographic(position, scratchDistanceDisplayConditionCartographic); + position = projection.project(cartographic, position); + Cartesian3.fromElements(position.z, position.x, position.y, position); } + distance2 = Cartesian3.distanceSquared(position, frameState.camera.positionWC); } + + return (distance2 >= nearSquared) && (distance2 <= farSquared); } /** - * A general purpose visualizer for geometry represented by {@link Primitive} instances. - * @alias GeometryVisualizer - * @constructor + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> * - * @param {GeometryUpdater} type The updater to be used for creating the geometry. - * @param {Scene} scene The scene the primitives will be rendered in. - * @param {EntityCollection} entityCollection The entityCollection to visualize. + * @exception {RuntimeError} Failed to load external reference. */ - function GeometryVisualizer(type, scene, entityCollection) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - if (!defined(entityCollection)) { - throw new DeveloperError('entityCollection is required.'); + Model.prototype.update = function(frameState) { + if (frameState.mode === SceneMode.MORPHING) { + return; } - - this._type = type; - var primitives = scene.primitives; - var groundPrimitives = scene.groundPrimitives; - this._scene = scene; - this._primitives = primitives; - this._groundPrimitives = groundPrimitives; - this._entityCollection = undefined; - this._addedObjects = new AssociativeArray(); - this._removedObjects = new AssociativeArray(); - this._changedObjects = new AssociativeArray(); + var context = frameState.context; + this._defaultTexture = context.defaultTexture; - var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES; - this._outlineBatches = new Array(numberOfShadowModes); - this._closedColorBatches = new Array(numberOfShadowModes * 3); - this._closedMaterialBatches = new Array(numberOfShadowModes * 3); - this._openColorBatches = new Array(numberOfShadowModes * 3); - this._openMaterialBatches = new Array(numberOfShadowModes * 3); + if ((this._state === ModelState.NEEDS_LOAD) && defined(this.gltf)) { + // Use renderer resources from cache instead of loading/creating them? + var cachedRendererResources; + var cacheKey = this.cacheKey; + if (defined(cacheKey)) { + context.cache.modelRendererResourceCache = defaultValue(context.cache.modelRendererResourceCache, {}); + var modelCaches = context.cache.modelRendererResourceCache; - for (var i = 0; i < numberOfShadowModes; ++i) { - this._outlineBatches[i] = new StaticOutlineGeometryBatch(primitives, scene, i); + cachedRendererResources = modelCaches[this.cacheKey]; + if (defined(cachedRendererResources)) { + if (!cachedRendererResources.ready) { + // Cached resources for the model are not loaded yet. We'll + // try again every frame until they are. + return; + } - this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, undefined, true, i); - this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, undefined, true, i); - this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, undefined, false, i); - this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, undefined, false, i); + ++cachedRendererResources.count; + this._loadRendererResourcesFromCache = true; + } else { + cachedRendererResources = new CachedRendererResources(context, cacheKey); + cachedRendererResources.count = 1; + modelCaches[this.cacheKey] = cachedRendererResources; + } + this._cachedRendererResources = cachedRendererResources; + } else { + cachedRendererResources = new CachedRendererResources(context); + cachedRendererResources.count = 1; + this._cachedRendererResources = cachedRendererResources; + } - this._closedColorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.perInstanceColorAppearanceType, true, i); - this._closedMaterialBatches[i + numberOfShadowModes] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.perInstanceColorAppearanceType, true, i); - this._openColorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.perInstanceColorAppearanceType, false, i); - this._openMaterialBatches[i + numberOfShadowModes] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.perInstanceColorAppearanceType, false, i); + this._state = ModelState.LOADING; + if (this._state !== ModelState.FAILED) { + var extensions = this.gltf.extensions; + if (defined(extensions) && defined(extensions.CESIUM_RTC)) { + var center = Cartesian3.fromArray(extensions.CESIUM_RTC.center); + if (!Cartesian3.equals(center, Cartesian3.ZERO)) { + this._rtcCenter3D = center; - this._closedColorBatches[i + numberOfShadowModes * 2] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.materialAppearanceType, true, i); - this._closedMaterialBatches[i + numberOfShadowModes * 2] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.materialAppearanceType, true, i); - this._openColorBatches[i + numberOfShadowModes * 2] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.materialAppearanceType, false, i); - this._openMaterialBatches[i + numberOfShadowModes * 2] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.materialAppearanceType, false, i); - } + var projection = frameState.mapProjection; + var ellipsoid = projection.ellipsoid; + var cartographic = ellipsoid.cartesianToCartographic(this._rtcCenter3D); + var projectedCart = projection.project(cartographic); + Cartesian3.fromElements(projectedCart.z, projectedCart.x, projectedCart.y, projectedCart); + this._rtcCenter2D = projectedCart; - this._groundColorBatch = new StaticGroundGeometryColorBatch(groundPrimitives); - this._dynamicBatch = new DynamicGeometryBatch(primitives, groundPrimitives); + this._rtcCenterEye = new Cartesian3(); + this._rtcCenter = this._rtcCenter3D; + } + } - this._batches = this._outlineBatches.concat(this._closedColorBatches, this._closedMaterialBatches, this._openColorBatches, this._openMaterialBatches, this._groundColorBatch, this._dynamicBatch); + this._loadResources = new ModelLoadResources(); + if (!this._loadRendererResourcesFromCache) { + // Buffers are required to updateVersion + parseBuffers(this); + } + } + } - this._subscriptions = new AssociativeArray(); - this._updaters = new AssociativeArray(); + var loadResources = this._loadResources; + var incrementallyLoadTextures = this._incrementallyLoadTextures; + var justLoaded = false; - this._entityCollection = entityCollection; - entityCollection.collectionChanged.addEventListener(GeometryVisualizer.prototype._onCollectionChanged, this); - this._onCollectionChanged(entityCollection, entityCollection.values, emptyArray); - } + if (this._state === ModelState.LOADING) { + // Transition from LOADING -> LOADED once resources are downloaded and created. + // Textures may continue to stream in while in the LOADED state. + if (loadResources.pendingBufferLoads === 0) { + if (!this._updatedGltfVersion) { + var options = { + optimizeForCesium: true, + addBatchIdToGeneratedShaders : this._addBatchIdToGeneratedShaders + }; + frameState.brdfLutGenerator.update(frameState); + updateVersion(this.gltf); + ModelUtility.checkSupportedExtensions(this.extensionsRequired); + addPipelineExtras(this.gltf); + addDefaults(this.gltf); + processModelMaterialsCommon(this.gltf, options); + processPbrMetallicRoughness(this.gltf, options); + // We do this after to make sure that the ids don't change + addBuffersToLoadResources(this); - /** - * Updates all of the primitives created by this visualizer to match their - * Entity counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * @returns {Boolean} True if the visualizer successfully updated to the provided time, - * false if the visualizer is waiting for asynchronous primitives to be created. - */ - GeometryVisualizer.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + if (!this._loadRendererResourcesFromCache) { + parseBufferViews(this); + parseShaders(this); + parsePrograms(this); + parseTextures(this, context); + } + parseMaterials(this); + parseMeshes(this); + parseNodes(this); + + this._boundingSphere = computeBoundingSphere(this); + this._initialRadius = this._boundingSphere.radius; + this._updatedGltfVersion = true; + } + if (this._updatedGltfVersion && loadResources.pendingShaderLoads === 0) { + createResources(this, frameState); + } + } + if (loadResources.finished() || + (incrementallyLoadTextures && loadResources.finishedEverythingButTextureCreation())) { + this._state = ModelState.LOADED; + justLoaded = true; + } } - - var addedObjects = this._addedObjects; - var added = addedObjects.values; - var removedObjects = this._removedObjects; - var removed = removedObjects.values; - var changedObjects = this._changedObjects; - var changed = changedObjects.values; - var i; - var entity; - var id; - var updater; + // Incrementally stream textures. + if (defined(loadResources) && (this._state === ModelState.LOADED)) { + if (incrementallyLoadTextures && !justLoaded) { + createResources(this, frameState); + } - for (i = changed.length - 1; i > -1; i--) { - entity = changed[i]; - id = entity.id; - updater = this._updaters.get(id); + if (loadResources.finished()) { + this._loadResources = undefined; // Clear CPU memory since WebGL resources were created. - //If in a single update, an entity gets removed and a new instance - //re-added with the same id, the updater no longer tracks the - //correct entity, we need to both remove the old one and - //add the new one, which is done by pushing the entity - //onto the removed/added lists. - if (updater.entity === entity) { - removeUpdater(this, updater); - insertUpdaterIntoBatch(this, time, updater); - } else { - removed.push(entity); - added.push(entity); + var resources = this._rendererResources; + var cachedResources = this._cachedRendererResources; + + cachedResources.buffers = resources.buffers; + cachedResources.vertexArrays = resources.vertexArrays; + cachedResources.programs = resources.programs; + cachedResources.pickPrograms = resources.pickPrograms; + cachedResources.silhouettePrograms = resources.silhouettePrograms; + cachedResources.textures = resources.textures; + cachedResources.samplers = resources.samplers; + cachedResources.renderStates = resources.renderStates; + cachedResources.ready = true; + + // The normal attribute name is required for silhouettes, so get it before the gltf JSON is released + this._normalAttributeName = ModelUtility.getAttributeOrUniformBySemantic(this.gltf, 'NORMAL'); + + // Vertex arrays are unique to this model, do not store in cache. + if (defined(this._precreatedAttributes)) { + cachedResources.vertexArrays = {}; + } + + if (this.releaseGltfJson) { + releaseCachedGltf(this); + } } } - for (i = removed.length - 1; i > -1; i--) { - entity = removed[i]; - id = entity.id; - updater = this._updaters.get(id); - removeUpdater(this, updater); - updater.destroy(); - this._updaters.remove(id); - this._subscriptions.get(id)(); - this._subscriptions.remove(id); - } + var silhouette = hasSilhouette(this, frameState); + var translucent = isTranslucent(this); + var invisible = isInvisible(this); + var displayConditionPassed = defined(this.distanceDisplayCondition) ? distanceDisplayConditionVisible(this, frameState) : true; + var show = this.show && displayConditionPassed && (this.scale !== 0.0) && (!invisible || silhouette); - for (i = added.length - 1; i > -1; i--) { - entity = added[i]; - id = entity.id; - updater = new this._type(entity, this._scene); - this._updaters.set(id, updater); - insertUpdaterIntoBatch(this, time, updater); - this._subscriptions.set(id, updater.geometryChanged.addEventListener(GeometryVisualizer._onGeometryChanged, this)); - } + if ((show && this._state === ModelState.LOADED) || justLoaded) { + var animated = this.activeAnimations.update(frameState) || this._cesiumAnimationsDirty; + this._cesiumAnimationsDirty = false; + this._dirty = false; + var modelMatrix = this.modelMatrix; - addedObjects.removeAll(); - removedObjects.removeAll(); - changedObjects.removeAll(); + var modeChanged = frameState.mode !== this._mode; + this._mode = frameState.mode; - var isUpdated = true; - var batches = this._batches; - var length = batches.length; - for (i = 0; i < length; i++) { - isUpdated = batches[i].update(time) && isUpdated; - } + // Model's model matrix needs to be updated + var modelTransformChanged = !Matrix4.equals(this._modelMatrix, modelMatrix) || + (this._scale !== this.scale) || + (this._minimumPixelSize !== this.minimumPixelSize) || (this.minimumPixelSize !== 0.0) || // Minimum pixel size changed or is enabled + (this._maximumScale !== this.maximumScale) || + (this._heightReference !== this.heightReference) || this._heightChanged || + modeChanged; - return isUpdated; - }; + if (modelTransformChanged || justLoaded) { + Matrix4.clone(modelMatrix, this._modelMatrix); - var getBoundingSphereArrayScratch = []; - var getBoundingSphereBoundingSphereScratch = new BoundingSphere(); + updateClamping(this); - /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private - */ - GeometryVisualizer.prototype.getBoundingSphere = function(entity, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); + if (defined(this._clampedModelMatrix)) { + modelMatrix = this._clampedModelMatrix; + } + + this._scale = this.scale; + this._minimumPixelSize = this.minimumPixelSize; + this._maximumScale = this.maximumScale; + this._heightReference = this.heightReference; + this._heightChanged = false; + + var scale = getScale(this, frameState); + var computedModelMatrix = this._computedModelMatrix; + Matrix4.multiplyByUniformScale(modelMatrix, scale, computedModelMatrix); + if (this._upAxis === Axis.Y) { + Matrix4.multiplyTransformation(computedModelMatrix, Axis.Y_UP_TO_Z_UP, computedModelMatrix); + } else if (this._upAxis === Axis.X) { + Matrix4.multiplyTransformation(computedModelMatrix, Axis.X_UP_TO_Z_UP, computedModelMatrix); + } + } + + var clippingPlanes = this.clippingPlanes; + if (defined(clippingPlanes) && clippingPlanes.enabled) { + Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); + } + + // Update modelMatrix throughout the graph as needed + if (animated || modelTransformChanged || justLoaded) { + updateNodeHierarchyModelMatrix(this, modelTransformChanged, justLoaded, frameState.mapProjection); + this._dirty = true; + + if (animated || justLoaded) { + // Apply skins if animation changed any node transforms + applySkins(this); + } + } + + if (this._perNodeShowDirty) { + this._perNodeShowDirty = false; + updatePerNodeShow(this); + } + updatePickIds(this, context); + updateWireframe(this); + updateShowBoundingVolume(this); + updateShadows(this); + updateColor(this, frameState); + updateSilhouette(this, frameState); + updateClippingPlanes(this, frameState); } - if (!defined(result)) { - throw new DeveloperError('result is required.'); + + if (justLoaded) { + // Called after modelMatrix update. + var model = this; + frameState.afterRender.push(function() { + model._ready = true; + model._readyPromise.resolve(model); + }); + return; } - - var boundingSpheres = getBoundingSphereArrayScratch; - var tmp = getBoundingSphereBoundingSphereScratch; - var count = 0; - var state = BoundingSphereState.DONE; - var batches = this._batches; - var batchesLength = batches.length; + // We don't check show at the top of the function since we + // want to be able to progressively load models when they are not shown, + // and then have them visible immediately when show is set to true. + if (show && !this._ignoreCommands) { + // PERFORMANCE_IDEA: This is terrible + var commandList = frameState.commandList; + var passes = frameState.passes; + var nodeCommands = this._nodeCommands; + var length = nodeCommands.length; + var i; + var nc; + + var idl2D = frameState.mapProjection.ellipsoid.maximumRadius * CesiumMath.PI; + var boundingVolume; - for (var i = 0; i < batchesLength; i++) { - state = batches[i].getBoundingSphere(entity, tmp); - if (state === BoundingSphereState.PENDING) { - return BoundingSphereState.PENDING; - } else if (state === BoundingSphereState.DONE) { - boundingSpheres[count] = BoundingSphere.clone(tmp, boundingSpheres[count]); - count++; + if (passes.render) { + for (i = 0; i < length; ++i) { + nc = nodeCommands[i]; + if (nc.show) { + var command = translucent ? nc.translucentCommand : nc.command; + command = silhouette ? nc.silhouetteModelCommand : command; + commandList.push(command); + boundingVolume = nc.command.boundingVolume; + if (frameState.mode === SceneMode.SCENE2D && + (boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) { + var command2D = translucent ? nc.translucentCommand2D : nc.command2D; + command2D = silhouette ? nc.silhouetteModelCommand2D : command2D; + commandList.push(command2D); + } + } + } + + if (silhouette) { + // Render second silhouette pass + for (i = 0; i < length; ++i) { + nc = nodeCommands[i]; + if (nc.show) { + commandList.push(nc.silhouetteColorCommand); + boundingVolume = nc.command.boundingVolume; + if (frameState.mode === SceneMode.SCENE2D && + (boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) { + commandList.push(nc.silhouetteColorCommand2D); + } + } + } + } } - } - if (count === 0) { - return BoundingSphereState.FAILED; - } + if (passes.pick && this.allowPicking) { + for (i = 0; i < length; ++i) { + nc = nodeCommands[i]; + if (nc.show) { + var pickCommand = nc.pickCommand; + commandList.push(pickCommand); - boundingSpheres.length = count; - BoundingSphere.fromBoundingSpheres(boundingSpheres, result); - return BoundingSphereState.DONE; + boundingVolume = pickCommand.boundingVolume; + if (frameState.mode === SceneMode.SCENE2D && + (boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) { + commandList.push(nc.pickCommand2D); + } + } + } + } + } }; /** * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see Model#destroy */ - GeometryVisualizer.prototype.isDestroyed = function() { + Model.prototype.isDestroyed = function() { return false; }; /** - * Removes and destroys all primitives created by this instance. + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * model = model && model.destroy(); + * + * @see Model#isDestroyed */ - GeometryVisualizer.prototype.destroy = function() { - this._entityCollection.collectionChanged.removeEventListener(GeometryVisualizer.prototype._onCollectionChanged, this); - this._addedObjects.removeAll(); - this._removedObjects.removeAll(); - - var i; - var batches = this._batches; - var length = batches.length; - for (i = 0; i < length; i++) { - batches[i].removeAllPrimitives(); + Model.prototype.destroy = function() { + // Vertex arrays are unique to this model, destroy here. + if (defined(this._precreatedAttributes)) { + destroy(this._rendererResources.vertexArrays); } - var subscriptions = this._subscriptions.values; - length = subscriptions.length; - for (i = 0; i < length; i++) { - subscriptions[i](); + if (defined(this._removeUpdateHeightCallback)) { + this._removeUpdateHeightCallback(); + this._removeUpdateHeightCallback = undefined; } - this._subscriptions.removeAll(); - return destroyObject(this); - }; - - /** - * @private - */ - GeometryVisualizer._onGeometryChanged = function(updater) { - var removedObjects = this._removedObjects; - var changedObjects = this._changedObjects; - var entity = updater.entity; - var id = entity.id; - - if (!defined(removedObjects.get(id)) && !defined(changedObjects.get(id))) { - changedObjects.set(id, entity); + if (defined(this._terrainProviderChangedCallback)) { + this._terrainProviderChangedCallback(); + this._terrainProviderChangedCallback = undefined; } - }; - /** - * @private - */ - GeometryVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed) { - var addedObjects = this._addedObjects; - var removedObjects = this._removedObjects; - var changedObjects = this._changedObjects; + this._rendererResources = undefined; + this._cachedRendererResources = this._cachedRendererResources && this._cachedRendererResources.release(); - var i; - var id; - var entity; - for (i = removed.length - 1; i > -1; i--) { - entity = removed[i]; - id = entity.id; - if (!addedObjects.remove(id)) { - removedObjects.set(id, entity); - changedObjects.remove(id); - } + var pickIds = this._pickIds; + var length = pickIds.length; + for (var i = 0; i < length; ++i) { + pickIds[i].destroy(); } - for (i = added.length - 1; i > -1; i--) { - entity = added[i]; - id = entity.id; - if (removedObjects.remove(id)) { - changedObjects.set(id, entity); - } else { - addedObjects.set(id, entity); - } - } + releaseCachedGltf(this); + + return destroyObject(this); }; - return GeometryVisualizer; + return Model; }); -define('DataSources/LabelVisualizer',[ +define('DataSources/ModelVisualizer',[ '../Core/AssociativeArray', - '../Core/Cartesian2', - '../Core/Cartesian3', + '../Core/BoundingSphere', '../Core/Color', - '../Core/defaultValue', '../Core/defined', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/NearFarScalar', + '../Core/Matrix4', + '../Core/Resource', + '../Scene/ColorBlendMode', '../Scene/HeightReference', - '../Scene/HorizontalOrigin', - '../Scene/LabelStyle', - '../Scene/VerticalOrigin', + '../Scene/Model', + '../Scene/ModelAnimationLoop', + '../Scene/ShadowMode', './BoundingSphereState', './Property' ], function( AssociativeArray, - Cartesian2, - Cartesian3, + BoundingSphere, Color, - defaultValue, defined, destroyObject, DeveloperError, - DistanceDisplayCondition, - NearFarScalar, + Matrix4, + Resource, + ColorBlendMode, HeightReference, - HorizontalOrigin, - LabelStyle, - VerticalOrigin, + Model, + ModelAnimationLoop, + ShadowMode, BoundingSphereState, Property) { 'use strict'; var defaultScale = 1.0; - var defaultFont = '30px sans-serif'; - var defaultStyle = LabelStyle.FILL; - var defaultFillColor = Color.WHITE; - var defaultOutlineColor = Color.BLACK; - var defaultOutlineWidth = 1.0; - var defaultShowBackground = false; - var defaultBackgroundColor = new Color(0.165, 0.165, 0.165, 0.8); - var defaultBackgroundPadding = new Cartesian2(7, 5); - var defaultPixelOffset = Cartesian2.ZERO; - var defaultEyeOffset = Cartesian3.ZERO; + var defaultMinimumPixelSize = 0.0; + var defaultIncrementallyLoadTextures = true; + var defaultClampAnimations = true; + var defaultShadows = ShadowMode.ENABLED; var defaultHeightReference = HeightReference.NONE; - var defaultHorizontalOrigin = HorizontalOrigin.CENTER; - var defaultVerticalOrigin = VerticalOrigin.CENTER; - var defaultDisableDepthTestDistance = 0.0; - - var position = new Cartesian3(); - var fillColor = new Color(); - var outlineColor = new Color(); - var backgroundColor = new Color(); - var backgroundPadding = new Cartesian2(); - var eyeOffset = new Cartesian3(); - var pixelOffset = new Cartesian2(); - var translucencyByDistance = new NearFarScalar(); - var pixelOffsetScaleByDistance = new NearFarScalar(); - var scaleByDistance = new NearFarScalar(); - var distanceDisplayCondition = new DistanceDisplayCondition(); + var defaultSilhouetteColor = Color.RED; + var defaultSilhouetteSize = 0.0; + var defaultColor = Color.WHITE; + var defaultColorBlendMode = ColorBlendMode.HIGHLIGHT; + var defaultColorBlendAmount = 0.5; - function EntityData(entity) { - this.entity = entity; - this.label = undefined; - this.index = undefined; - } + var modelMatrixScratch = new Matrix4(); + var nodeMatrixScratch = new Matrix4(); /** - * A {@link Visualizer} which maps the {@link LabelGraphics} instance - * in {@link Entity#label} to a {@link Label}. - * @alias LabelVisualizer + * A {@link Visualizer} which maps {@link Entity#model} to a {@link Model}. + * @alias ModelVisualizer * @constructor * - * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities. + * @param {Scene} scene The scene the primitives will be rendered in. * @param {EntityCollection} entityCollection The entityCollection to visualize. */ - function LabelVisualizer(entityCluster, entityCollection) { - if (!defined(entityCluster)) { - throw new DeveloperError('entityCluster is required.'); + function ModelVisualizer(scene, entityCollection) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); } if (!defined(entityCollection)) { throw new DeveloperError('entityCollection is required.'); } - entityCollection.collectionChanged.addEventListener(LabelVisualizer.prototype._onCollectionChanged, this); + entityCollection.collectionChanged.addEventListener(ModelVisualizer.prototype._onCollectionChanged, this); - this._cluster = entityCluster; + this._scene = scene; + this._primitives = scene.primitives; this._entityCollection = entityCollection; - this._items = new AssociativeArray(); - + this._modelHash = {}; + this._entitiesToVisualize = new AssociativeArray(); this._onCollectionChanged(entityCollection, entityCollection.values, [], []); } /** - * Updates the primitives created by this visualizer to match their + * Updates models created this visualizer to match their * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. * @returns {Boolean} This function always returns true. */ - LabelVisualizer.prototype.update = function(time) { + ModelVisualizer.prototype.update = function(time) { if (!defined(time)) { throw new DeveloperError('time is required.'); } - var items = this._items.values; - var cluster = this._cluster; + var entities = this._entitiesToVisualize.values; + var modelHash = this._modelHash; + var primitives = this._primitives; - for (var i = 0, len = items.length; i < len; i++) { - var item = items[i]; - var entity = item.entity; - var labelGraphics = entity._label; - var text; - var label = item.label; - var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(labelGraphics._show, time, true); + for (var i = 0, len = entities.length; i < len; i++) { + var entity = entities[i]; + var modelGraphics = entity._model; + + var resource; + var modelData = modelHash[entity.id]; + var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(modelGraphics._show, time, true); + var modelMatrix; if (show) { - position = Property.getValueOrUndefined(entity._position, time, position); - text = Property.getValueOrUndefined(labelGraphics._text, time); - show = defined(position) && defined(text); + modelMatrix = entity.computeModelMatrix(time, modelMatrixScratch); + resource = Resource.createIfNeeded(Property.getValueOrUndefined(modelGraphics._uri, time)); + show = defined(modelMatrix) && defined(resource); } if (!show) { - //don't bother creating or updating anything else - returnPrimitive(item, entity, cluster); + if (defined(modelData)) { + modelData.modelPrimitive.show = false; + } continue; } - if (!Property.isConstant(entity._position)) { - cluster._clusterDirty = true; - } + var model = defined(modelData) ? modelData.modelPrimitive : undefined; + if (!defined(model) || resource.url !== modelData.url) { + if (defined(model)) { + primitives.removeAndDestroy(model); + delete modelHash[entity.id]; + } + model = Model.fromGltf({ + url : resource, + incrementallyLoadTextures : Property.getValueOrDefault(modelGraphics._incrementallyLoadTextures, time, defaultIncrementallyLoadTextures), + scene : this._scene + }); - if (!defined(label)) { - label = cluster.getLabel(entity); - label.id = entity; - item.label = label; + model.readyPromise.otherwise(onModelError); + + model.id = entity; + primitives.add(model); + + modelData = { + modelPrimitive : model, + url : resource.url, + animationsRunning : false, + nodeTransformationsScratch : {}, + originalNodeMatrixHash : {} + }; + modelHash[entity.id] = modelData; } - label.show = true; - label.position = position; - label.text = text; - label.scale = Property.getValueOrDefault(labelGraphics._scale, time, defaultScale); - label.font = Property.getValueOrDefault(labelGraphics._font, time, defaultFont); - label.style = Property.getValueOrDefault(labelGraphics._style, time, defaultStyle); - label.fillColor = Property.getValueOrDefault(labelGraphics._fillColor, time, defaultFillColor, fillColor); - label.outlineColor = Property.getValueOrDefault(labelGraphics._outlineColor, time, defaultOutlineColor, outlineColor); - label.outlineWidth = Property.getValueOrDefault(labelGraphics._outlineWidth, time, defaultOutlineWidth); - label.showBackground = Property.getValueOrDefault(labelGraphics._showBackground, time, defaultShowBackground); - label.backgroundColor = Property.getValueOrDefault(labelGraphics._backgroundColor, time, defaultBackgroundColor, backgroundColor); - label.backgroundPadding = Property.getValueOrDefault(labelGraphics._backgroundPadding, time, defaultBackgroundPadding, backgroundPadding); - label.pixelOffset = Property.getValueOrDefault(labelGraphics._pixelOffset, time, defaultPixelOffset, pixelOffset); - label.eyeOffset = Property.getValueOrDefault(labelGraphics._eyeOffset, time, defaultEyeOffset, eyeOffset); - label.heightReference = Property.getValueOrDefault(labelGraphics._heightReference, time, defaultHeightReference); - label.horizontalOrigin = Property.getValueOrDefault(labelGraphics._horizontalOrigin, time, defaultHorizontalOrigin); - label.verticalOrigin = Property.getValueOrDefault(labelGraphics._verticalOrigin, time, defaultVerticalOrigin); - label.translucencyByDistance = Property.getValueOrUndefined(labelGraphics._translucencyByDistance, time, translucencyByDistance); - label.pixelOffsetScaleByDistance = Property.getValueOrUndefined(labelGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance); - label.scaleByDistance = Property.getValueOrUndefined(labelGraphics._scaleByDistance, time, scaleByDistance); - label.distanceDisplayCondition = Property.getValueOrUndefined(labelGraphics._distanceDisplayCondition, time, distanceDisplayCondition); - label.disableDepthTestDistance = Property.getValueOrDefault(labelGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); + model.show = true; + model.scale = Property.getValueOrDefault(modelGraphics._scale, time, defaultScale); + model.minimumPixelSize = Property.getValueOrDefault(modelGraphics._minimumPixelSize, time, defaultMinimumPixelSize); + model.maximumScale = Property.getValueOrUndefined(modelGraphics._maximumScale, time); + model.modelMatrix = Matrix4.clone(modelMatrix, model.modelMatrix); + model.shadows = Property.getValueOrDefault(modelGraphics._shadows, time, defaultShadows); + model.heightReference = Property.getValueOrDefault(modelGraphics._heightReference, time, defaultHeightReference); + model.distanceDisplayCondition = Property.getValueOrUndefined(modelGraphics._distanceDisplayCondition, time); + model.silhouetteColor = Property.getValueOrDefault(modelGraphics._silhouetteColor, time, defaultSilhouetteColor, model._silhouetteColor); + model.silhouetteSize = Property.getValueOrDefault(modelGraphics._silhouetteSize, time, defaultSilhouetteSize); + model.color = Property.getValueOrDefault(modelGraphics._color, time, defaultColor, model._color); + model.colorBlendMode = Property.getValueOrDefault(modelGraphics._colorBlendMode, time, defaultColorBlendMode); + model.colorBlendAmount = Property.getValueOrDefault(modelGraphics._colorBlendAmount, time, defaultColorBlendAmount); + model.clippingPlanes = Property.getValueOrUndefined(modelGraphics._clippingPlanes, time); + model.clampAnimations = Property.getValueOrDefault(modelGraphics._clampAnimations, time, defaultClampAnimations); + + if (model.ready) { + var runAnimations = Property.getValueOrDefault(modelGraphics._runAnimations, time, true); + if (modelData.animationsRunning !== runAnimations) { + if (runAnimations) { + model.activeAnimations.addAll({ + loop : ModelAnimationLoop.REPEAT + }); + } else { + model.activeAnimations.removeAll(); + } + modelData.animationsRunning = runAnimations; + } + + // Apply node transformations + var nodeTransformations = Property.getValueOrUndefined(modelGraphics._nodeTransformations, time, modelData.nodeTransformationsScratch); + if (defined(nodeTransformations)) { + var originalNodeMatrixHash = modelData.originalNodeMatrixHash; + var nodeNames = Object.keys(nodeTransformations); + for (var nodeIndex = 0, nodeLength = nodeNames.length; nodeIndex < nodeLength; ++nodeIndex) { + var nodeName = nodeNames[nodeIndex]; + + var nodeTransformation = nodeTransformations[nodeName]; + if (!defined(nodeTransformation)) { + continue; + } + + var modelNode = model.getNode(nodeName); + if (!defined(modelNode)) { + continue; + } + + var originalNodeMatrix = originalNodeMatrixHash[nodeName]; + if (!defined(originalNodeMatrix)) { + originalNodeMatrix = modelNode.matrix.clone(); + originalNodeMatrixHash[nodeName] = originalNodeMatrix; + } + + var transformationMatrix = Matrix4.fromTranslationRotationScale(nodeTransformation, nodeMatrixScratch); + modelNode.matrix = Matrix4.multiply(originalNodeMatrix, transformationMatrix, transformationMatrix); + } + } + } } + return true; }; + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + ModelVisualizer.prototype.isDestroyed = function() { + return false; + }; + + /** + * Removes and destroys all primitives created by this instance. + */ + ModelVisualizer.prototype.destroy = function() { + this._entityCollection.collectionChanged.removeEventListener(ModelVisualizer.prototype._onCollectionChanged, this); + var entities = this._entitiesToVisualize.values; + var modelHash = this._modelHash; + var primitives = this._primitives; + for (var i = entities.length - 1; i > -1; i--) { + removeModel(this, entities[i], modelHash, primitives); + } + return destroyObject(this); + }; + /** * Computes a bounding sphere which encloses the visualization produced for the specified entity. * The bounding sphere is in the fixed frame of the scene's globe. @@ -131770,7 +144235,7 @@ define('DataSources/LabelVisualizer',[ * BoundingSphereState.FAILED if the entity has no visualization in the current scene. * @private */ - LabelVisualizer.prototype.getBoundingSphere = function(entity, result) { + ModelVisualizer.prototype.getBoundingSphere = function(entity, result) { if (!defined(entity)) { throw new DeveloperError('entity is required.'); } @@ -131778,35121 +144243,36142 @@ define('DataSources/LabelVisualizer',[ throw new DeveloperError('result is required.'); } - var item = this._items.get(entity.id); - if (!defined(item) || !defined(item.label)) { + var modelData = this._modelHash[entity.id]; + if (!defined(modelData)) { return BoundingSphereState.FAILED; } - var label = item.label; - result.center = Cartesian3.clone(defaultValue(label._clampedPosition, label.position), result.center); - result.radius = 0; - return BoundingSphereState.DONE; - }; + var model = modelData.modelPrimitive; + if (!defined(model) || !model.show) { + return BoundingSphereState.FAILED; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - LabelVisualizer.prototype.isDestroyed = function() { - return false; - }; + if (!model.ready) { + return BoundingSphereState.PENDING; + } - /** - * Removes and destroys all primitives created by this instance. - */ - LabelVisualizer.prototype.destroy = function() { - this._entityCollection.collectionChanged.removeEventListener(LabelVisualizer.prototype._onCollectionChanged, this); - var entities = this._entityCollection.values; - for (var i = 0; i < entities.length; i++) { - this._cluster.removeLabel(entities[i]); + if (model.heightReference === HeightReference.NONE) { + BoundingSphere.transform(model.boundingSphere, model.modelMatrix, result); + } else { + if (!defined(model._clampedModelMatrix)) { + return BoundingSphereState.PENDING; + } + BoundingSphere.transform(model.boundingSphere, model._clampedModelMatrix, result); } - return destroyObject(this); + return BoundingSphereState.DONE; }; - LabelVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { + /** + * @private + */ + ModelVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { var i; var entity; - var items = this._items; - var cluster = this._cluster; + var entities = this._entitiesToVisualize; + var modelHash = this._modelHash; + var primitives = this._primitives; for (i = added.length - 1; i > -1; i--) { entity = added[i]; - if (defined(entity._label) && defined(entity._position)) { - items.set(entity.id, new EntityData(entity)); + if (defined(entity._model) && defined(entity._position)) { + entities.set(entity.id, entity); } } for (i = changed.length - 1; i > -1; i--) { entity = changed[i]; - if (defined(entity._label) && defined(entity._position)) { - if (!items.contains(entity.id)) { - items.set(entity.id, new EntityData(entity)); - } + if (defined(entity._model) && defined(entity._position)) { + clearNodeTransformationsScratch(entity, modelHash); + entities.set(entity.id, entity); } else { - returnPrimitive(items.get(entity.id), entity, cluster); - items.remove(entity.id); + removeModel(this, entity, modelHash, primitives); + entities.remove(entity.id); } } for (i = removed.length - 1; i > -1; i--) { entity = removed[i]; - returnPrimitive(items.get(entity.id), entity, cluster); - items.remove(entity.id); + removeModel(this, entity, modelHash, primitives); + entities.remove(entity.id); } }; - function returnPrimitive(item, entity, cluster) { - if (defined(item)) { - item.label = undefined; - cluster.removeLabel(entity); + function removeModel(visualizer, entity, modelHash, primitives) { + var modelData = modelHash[entity.id]; + if (defined(modelData)) { + primitives.removeAndDestroy(modelData.modelPrimitive); + delete modelHash[entity.id]; } } - return LabelVisualizer; -}); - -define('ThirdParty/GltfPipeline/addToArray',[], function() { - 'use strict'; + function clearNodeTransformationsScratch(entity, modelHash) { + var modelData = modelHash[entity.id]; + if (defined(modelData)) { + modelData.nodeTransformationsScratch = {}; + } + } - function addToArray(array, element) { - array.push(element); - return array.length - 1; + function onModelError(error) { + console.error(error); } - return addToArray; + + return ModelVisualizer; }); -define('ThirdParty/GltfPipeline/ForEach',[ - '../../Core/defined' +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PolylineCommon',[],function() { + 'use strict'; + return "void clipLineSegmentToNearPlane(\n\ +vec3 p0,\n\ +vec3 p1,\n\ +out vec4 positionWC,\n\ +out bool clipped,\n\ +out bool culledByNearPlane)\n\ +{\n\ +culledByNearPlane = false;\n\ +clipped = false;\n\ +vec3 p1ToP0 = p1 - p0;\n\ +float magnitude = length(p1ToP0);\n\ +vec3 direction = normalize(p1ToP0);\n\ +float endPoint0Distance = -(czm_currentFrustum.x + p0.z);\n\ +float denominator = -direction.z;\n\ +if (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7)\n\ +{\n\ +culledByNearPlane = true;\n\ +}\n\ +else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7)\n\ +{\n\ +float t = (czm_currentFrustum.x + p0.z) / denominator;\n\ +if (t < 0.0 || t > magnitude)\n\ +{\n\ +culledByNearPlane = true;\n\ +}\n\ +else\n\ +{\n\ +p0 = p0 + t * direction;\n\ +clipped = true;\n\ +}\n\ +}\n\ +positionWC = czm_eyeToWindowCoordinates(vec4(p0, 1.0));\n\ +}\n\ +vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)\n\ +{\n\ +vec4 endPointWC, p0, p1;\n\ +bool culledByNearPlane, clipped;\n\ +#ifdef POLYLINE_DASH\n\ +vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);\n\ +vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);\n\ +vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);\n\ +vec2 lineDir;\n\ +if (usePrevious) {\n\ +lineDir = normalize(positionWindow.xy - previousWindow.xy);\n\ +}\n\ +else {\n\ +lineDir = normalize(nextWindow.xy - positionWindow.xy);\n\ +}\n\ +angle = atan(lineDir.x, lineDir.y) - 1.570796327;\n\ +angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;\n\ +#endif\n\ +clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane);\n\ +clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane);\n\ +clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane);\n\ +if (culledByNearPlane)\n\ +{\n\ +return vec4(0.0, 0.0, 0.0, 1.0);\n\ +}\n\ +vec2 prevWC = normalize(p0.xy - endPointWC.xy);\n\ +vec2 nextWC = normalize(p1.xy - endPointWC.xy);\n\ +float expandWidth = width * 0.5;\n\ +vec2 direction;\n\ +if (czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))\n\ +{\n\ +direction = vec2(-nextWC.y, nextWC.x);\n\ +}\n\ +else if (czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) || clipped)\n\ +{\n\ +direction = vec2(prevWC.y, -prevWC.x);\n\ +}\n\ +else\n\ +{\n\ +vec2 normal = vec2(-nextWC.y, nextWC.x);\n\ +direction = normalize((nextWC + prevWC) * 0.5);\n\ +if (dot(direction, normal) < 0.0)\n\ +{\n\ +direction = -direction;\n\ +}\n\ +float sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);\n\ +expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);\n\ +}\n\ +vec2 offset = direction * expandDirection * expandWidth * czm_resolutionScale;\n\ +return vec4(endPointWC.xy + offset, -endPointWC.z, 1.0);\n\ +}\n\ +vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)\n\ +{\n\ +vec4 positionEC = czm_modelViewRelativeToEye * position;\n\ +vec4 prevEC = czm_modelViewRelativeToEye * previous;\n\ +vec4 nextEC = czm_modelViewRelativeToEye * next;\n\ +return getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PolylineFS',[],function() { + 'use strict'; + return "#ifdef VECTOR_TILE\n\ +uniform vec4 u_highlightColor;\n\ +#endif\n\ +varying vec2 v_st;\n\ +void main()\n\ +{\n\ +czm_materialInput materialInput;\n\ +materialInput.s = v_st.s;\n\ +materialInput.st = v_st;\n\ +materialInput.str = vec3(v_st, 0.0);\n\ +czm_material material = czm_getMaterial(materialInput);\n\ +gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ +#ifdef VECTOR_TILE\n\ +gl_FragColor *= u_highlightColor;\n\ +#endif\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PolylineVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 position2DHigh;\n\ +attribute vec3 position2DLow;\n\ +attribute vec3 prevPosition3DHigh;\n\ +attribute vec3 prevPosition3DLow;\n\ +attribute vec3 prevPosition2DHigh;\n\ +attribute vec3 prevPosition2DLow;\n\ +attribute vec3 nextPosition3DHigh;\n\ +attribute vec3 nextPosition3DLow;\n\ +attribute vec3 nextPosition2DHigh;\n\ +attribute vec3 nextPosition2DLow;\n\ +attribute vec4 texCoordExpandAndBatchIndex;\n\ +varying vec2 v_st;\n\ +varying float v_width;\n\ +varying vec4 czm_pickColor;\n\ +varying float v_polylineAngle;\n\ +void main()\n\ +{\n\ +float texCoord = texCoordExpandAndBatchIndex.x;\n\ +float expandDir = texCoordExpandAndBatchIndex.y;\n\ +bool usePrev = texCoordExpandAndBatchIndex.z < 0.0;\n\ +float batchTableIndex = texCoordExpandAndBatchIndex.w;\n\ +vec2 widthAndShow = batchTable_getWidthAndShow(batchTableIndex);\n\ +float width = widthAndShow.x + 0.5;\n\ +float show = widthAndShow.y;\n\ +if (width < 1.0)\n\ +{\n\ +show = 0.0;\n\ +}\n\ +vec4 pickColor = batchTable_getPickColor(batchTableIndex);\n\ +vec4 p, prev, next;\n\ +if (czm_morphTime == 1.0)\n\ +{\n\ +p = czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz);\n\ +prev = czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz);\n\ +next = czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz);\n\ +}\n\ +else if (czm_morphTime == 0.0)\n\ +{\n\ +p = czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy);\n\ +prev = czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy);\n\ +next = czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy);\n\ +}\n\ +else\n\ +{\n\ +p = czm_columbusViewMorph(\n\ +czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy),\n\ +czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz),\n\ +czm_morphTime);\n\ +prev = czm_columbusViewMorph(\n\ +czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy),\n\ +czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz),\n\ +czm_morphTime);\n\ +next = czm_columbusViewMorph(\n\ +czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy),\n\ +czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz),\n\ +czm_morphTime);\n\ +}\n\ +#ifdef DISTANCE_DISPLAY_CONDITION\n\ +vec3 centerHigh = batchTable_getCenterHigh(batchTableIndex);\n\ +vec4 centerLowAndRadius = batchTable_getCenterLowAndRadius(batchTableIndex);\n\ +vec3 centerLow = centerLowAndRadius.xyz;\n\ +float radius = centerLowAndRadius.w;\n\ +vec2 distanceDisplayCondition = batchTable_getDistanceDisplayCondition(batchTableIndex);\n\ +float lengthSq;\n\ +if (czm_sceneMode == czm_sceneMode2D)\n\ +{\n\ +lengthSq = czm_eyeHeight2D.y;\n\ +}\n\ +else\n\ +{\n\ +vec4 center = czm_translateRelativeToEye(centerHigh.xyz, centerLow.xyz);\n\ +lengthSq = max(0.0, dot(center.xyz, center.xyz) - radius * radius);\n\ +}\n\ +float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x;\n\ +float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y;\n\ +if (lengthSq < nearSq || lengthSq > farSq)\n\ +{\n\ +show = 0.0;\n\ +}\n\ +#endif\n\ +vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\n\ +gl_Position = czm_viewportOrthographic * positionWC * show;\n\ +v_st = vec2(texCoord, clamp(expandDir, 0.0, 1.0));\n\ +v_width = width;\n\ +czm_pickColor = pickColor;\n\ +}\n\ +"; +}); +define('Scene/Polyline',[ + '../Core/arrayRemoveDuplicates', + '../Core/BoundingSphere', + '../Core/Cartesian3', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/Matrix4', + '../Core/PolylinePipeline', + './Material' ], function( - defined) { + arrayRemoveDuplicates, + BoundingSphere, + Cartesian3, + Color, + defaultValue, + defined, + defineProperties, + DeveloperError, + DistanceDisplayCondition, + Matrix4, + PolylinePipeline, + Material) { 'use strict'; /** - * Contains traversal functions for processing elements of the glTF hierarchy. + * A renderable polyline. Create this by calling {@link PolylineCollection#add} + * + * @alias Polyline + * @internalConstructor + * + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.show=true] <code>true</code> if this polyline will be shown; otherwise, <code>false</code>. + * @param {Number} [options.width=1.0] The width of the polyline in pixels. + * @param {Boolean} [options.loop=false] Whether a line segment will be added between the last and first line positions to make this line a loop. + * @param {Material} [options.material=Material.ColorType] The material. + * @param {Cartesian3[]} [options.positions] The positions. + * @param {Object} [options.id] The user-defined object to be returned when this polyline is picked. + * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this polyline will be displayed. + * @param {PolylineCollection} polylineCollection The renderable polyline collection. + * + * @see PolylineCollection + * */ - var ForEach = {}; - - ForEach.object = function(arrayOfObjects, handler) { - if (defined(arrayOfObjects)) { - for (var i = 0; i < arrayOfObjects.length; i++) { - var object = arrayOfObjects[i]; - var returnValue = handler(object, i); - if (typeof returnValue === 'number') { - i += returnValue; - } - else if (returnValue) { - break; - } - } - } - }; - - ForEach.topLevel = function(gltf, name, handler) { - var arrayOfObjects = gltf[name]; - ForEach.object(arrayOfObjects, handler); - }; + function Polyline(options, polylineCollection) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - ForEach.accessor = function(gltf, handler) { - ForEach.topLevel(gltf, 'accessors', handler); - }; + this._show = defaultValue(options.show, true); + this._width = defaultValue(options.width, 1.0); + this._loop = defaultValue(options.loop, false); + this._distanceDisplayCondition = options.distanceDisplayCondition; - ForEach.accessorWithSemantic = function(gltf, semantic, handler) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) { - if (attributeSemantic.indexOf(semantic) === 0) { - handler(accessorId, attributeSemantic, primitive); - } - }); + this._material = options.material; + if (!defined(this._material)) { + this._material = Material.fromType(Material.ColorType, { + color : new Color(1.0, 1.0, 1.0, 1.0) }); - }); - }; - - ForEach.animation = function(gltf, handler) { - ForEach.topLevel(gltf, 'animations', handler); - }; - - ForEach.animationSampler = function(animation, handler) { - var samplers = animation.samplers; - if (defined(samplers)) { - ForEach.object(samplers, handler); - } - }; - - ForEach.buffer = function(gltf, handler) { - ForEach.topLevel(gltf, 'buffers', handler); - }; - - ForEach.bufferView = function(gltf, handler) { - ForEach.topLevel(gltf, 'bufferViews', handler); - }; - - ForEach.camera = function(gltf, handler) { - ForEach.topLevel(gltf, 'cameras', handler); - }; - - ForEach.image = function(gltf, handler) { - ForEach.topLevel(gltf, 'images', handler); - }; - - ForEach.material = function(gltf, handler) { - ForEach.topLevel(gltf, 'materials', handler); - }; - - ForEach.materialValue = function(material, handler) { - var values = material.values; - if (defined(values)) { - for (var name in values) { - if (values.hasOwnProperty(name)) { - handler(values[name], name); - } - } } - }; - - ForEach.mesh = function(gltf, handler) { - ForEach.topLevel(gltf, 'meshes', handler); - }; - ForEach.meshPrimitive = function(mesh, handler) { - var primitives = mesh.primitives; - if (defined(primitives)) { - var primitivesLength = primitives.length; - for (var i = 0; i < primitivesLength; i++) { - var primitive = primitives[i]; - handler(primitive, i); - } + var positions = options.positions; + if (!defined(positions)) { + positions = []; } - }; - ForEach.meshPrimitiveAttribute = function(primitive, handler) { - var attributes = primitive.attributes; - if (defined(attributes)) { - for (var semantic in attributes) { - if (attributes.hasOwnProperty(semantic)) { - handler(attributes[semantic], semantic); - } - } - } - }; + this._positions = positions; + this._actualPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); - ForEach.meshPrimitiveTargetAttribute = function(primitive, handler) { - var targets = primitive.targets; - if (defined(targets)) { - for (var targetId in targets) { - if (targets.hasOwnProperty(targetId)) { - var target = targets[targetId]; - for (var attributeId in target) { - if (target.hasOwnProperty(attributeId) && attributeId !== 'extras') { - handler(target[attributeId], attributeId); - } - } - } + if (this._loop && this._actualPositions.length > 2) { + if (this._actualPositions === this._positions) { + this._actualPositions = positions.slice(); } + this._actualPositions.push(Cartesian3.clone(this._actualPositions[0])); } - }; - ForEach.node = function(gltf, handler) { - ForEach.topLevel(gltf, 'nodes', handler); - }; + this._length = this._actualPositions.length; + this._id = options.id; - ForEach.nodeInTree = function(gltf, nodeIds, handler) { - var nodes = gltf.nodes; - if (defined(nodes)) { - for (var i = 0; i < nodeIds.length; i++) { - var nodeId = nodeIds[i]; - var node = nodes[nodeId]; - if (defined(node)) { - handler(node, nodeId); - var children = node.children; - if (defined(children)) { - ForEach.nodeInTree(gltf, children, handler); - } - } - } + var modelMatrix; + if (defined(polylineCollection)) { + modelMatrix = Matrix4.clone(polylineCollection.modelMatrix); } - }; - ForEach.nodeInScene = function(gltf, scene, handler) { - var sceneNodeIds = scene.nodes; - if (defined(sceneNodeIds)) { - ForEach.nodeInTree(gltf, sceneNodeIds, handler); - } - }; + this._modelMatrix = modelMatrix; + this._segments = PolylinePipeline.wrapLongitude(this._actualPositions, modelMatrix); - ForEach.program = function(gltf, handler) { - ForEach.topLevel(gltf, 'programs', handler); - }; + this._actualLength = undefined; - ForEach.sampler = function(gltf, handler) { - ForEach.topLevel(gltf, 'samplers', handler); - }; + this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); //eslint-disable-line no-use-before-define + this._polylineCollection = polylineCollection; + this._dirty = false; + this._pickId = undefined; + this._boundingVolume = BoundingSphere.fromPoints(this._actualPositions); + this._boundingVolumeWC = BoundingSphere.transform(this._boundingVolume, this._modelMatrix); + this._boundingVolume2D = new BoundingSphere(); // modified in PolylineCollection + } - ForEach.scene = function(gltf, handler) { - ForEach.topLevel(gltf, 'scenes', handler); - }; + var POSITION_INDEX = Polyline.POSITION_INDEX = 0; + var SHOW_INDEX = Polyline.SHOW_INDEX = 1; + var WIDTH_INDEX = Polyline.WIDTH_INDEX = 2; + var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 3; + var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 4; + var DISTANCE_DISPLAY_CONDITION = Polyline.DISTANCE_DISPLAY_CONDITION = 5; + var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 6; - ForEach.shader = function(gltf, handler) { - ForEach.topLevel(gltf, 'shaders', handler); - }; + function makeDirty(polyline, propertyChanged) { + ++polyline._propertiesChanged[propertyChanged]; + var polylineCollection = polyline._polylineCollection; + if (defined(polylineCollection)) { + polylineCollection._updatePolyline(polyline, propertyChanged); + polyline._dirty = true; + } + } - ForEach.skin = function(gltf, handler) { - ForEach.topLevel(gltf, 'skins', handler); - }; + defineProperties(Polyline.prototype, { - ForEach.techniqueAttribute = function(technique, handler) { - var attributes = technique.attributes; - if (defined(attributes)) { - for (var semantic in attributes) { - if (attributes.hasOwnProperty(semantic)) { - if (handler(attributes[semantic], semantic)) { - break; - } + /** + * Determines if this polyline will be shown. Use this to hide or show a polyline, instead + * of removing it and re-adding it to the collection. + * @memberof Polyline.prototype + * @type {Boolean} + */ + show: { + get: function() { + return this._show; + }, + set: function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (value !== this._show) { + this._show = value; + makeDirty(this, SHOW_INDEX); } } - } - }; + }, + + /** + * Gets or sets the positions of the polyline. + * @memberof Polyline.prototype + * @type {Cartesian3[]} + * @example + * polyline.positions = Cesium.Cartesian3.fromDegreesArray([ + * 0.0, 0.0, + * 10.0, 0.0, + * 0.0, 20.0 + * ]); + */ + positions : { + get: function() { + return this._positions; + }, + set: function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var positions = arrayRemoveDuplicates(value, Cartesian3.equalsEpsilon); - ForEach.techniqueParameter = function(technique, handler) { - var parameters = technique.parameters; - if (defined(parameters)) { - for (var parameterName in parameters) { - if (parameters.hasOwnProperty(parameterName)) { - if (handler(parameters[parameterName], parameterName)) { - break; + if (this._loop && positions.length > 2) { + if (positions === value) { + positions = value.slice(); } + positions.push(Cartesian3.clone(positions[0])); } - } - } - }; - ForEach.technique = function(gltf, handler) { - ForEach.topLevel(gltf, 'techniques', handler); - }; - - ForEach.texture = function(gltf, handler) { - ForEach.topLevel(gltf, 'textures', handler); - }; - - return ForEach; -}); + if (this._actualPositions.length !== positions.length || this._actualPositions.length !== this._length) { + makeDirty(this, POSITION_SIZE_INDEX); + } -define('ThirdParty/GltfPipeline/addDefaults',[ - './addToArray', - './ForEach', - '../../Core/clone', - '../../Core/defaultValue', - '../../Core/defined', - '../../Core/WebGLConstants' - ], function( - addToArray, - ForEach, - clone, - defaultValue, - defined, - WebGLConstants) { - 'use strict'; + this._positions = value; + this._actualPositions = positions; + this._length = positions.length; + this._boundingVolume = BoundingSphere.fromPoints(this._actualPositions, this._boundingVolume); + this._boundingVolumeWC = BoundingSphere.transform(this._boundingVolume, this._modelMatrix, this._boundingVolumeWC); + makeDirty(this, POSITION_INDEX); - var gltfTemplate = { - accessors: [], - animations : [ - { - channels : [], - samplers : [ - { - interpolation : 'LINEAR' - } - ] - } - ], - asset : {}, - buffers : [ - { - byteLength: 0, - type: 'arraybuffer' - } - ], - bufferViews: [ - { - byteLength: 0 + this.update(); } - ], - cameras: [], - images: [], - materials: [ - { - values: function(material) { - var extensions = defaultValue(material.extensions, {}); - var materialsCommon = extensions.KHR_materials_common; - if (!defined(materialsCommon)) { - return {}; - } - }, - extensions: function(material) { - var extensions = defaultValue(material.extensions, {}); - var materialsCommon = extensions.KHR_materials_common; - if (defined(materialsCommon)) { - var technique = materialsCommon.technique; - var defaults = { - ambient: [0.0, 0.0, 0.0, 1.0], - emission: [0.0, 0.0, 0.0, 1.0], - transparency: 1.0 - }; - if (technique !== 'CONSTANT') { - defaults.diffuse = [0.0, 0.0, 0.0, 1.0]; - if (technique !== 'LAMBERT') { - defaults.specular = [0.0, 0.0, 0.0, 1.0]; - defaults.shininess = 0.0; - } - } - return { - KHR_materials_common: { - doubleSided: false, - transparent: false, - values: defaults - } - }; - } + }, + + /** + * Gets or sets the surface appearance of the polyline. This can be one of several built-in {@link Material} objects or a custom material, scripted with + * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}. + * @memberof Polyline.prototype + * @type {Material} + */ + material: { + get: function() { + return this._material; + }, + set: function(material) { + if (!defined(material)) { + throw new DeveloperError('material is required.'); } - } - ], - meshes : [ - { - primitives : [ - { - attributes : {}, - mode : WebGLConstants.TRIANGLES - } - ] - } - ], - nodes : [ - { - children : [], - matrix : function(node) { - if (!defined(node.translation) && !defined(node.rotation) && !defined(node.scale)) { - return [ - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ]; - } - }, - rotation : function(node) { - if (defined(node.translation) || defined(node.scale)) { - return [0.0, 0.0, 0.0, 1.0]; - } - }, - scale : function(node) { - if (defined(node.translation) || defined(node.rotation)) { - return [1.0, 1.0, 1.0]; - } - }, - translation : function(node) { - if (defined(node.rotation) || defined(node.scale)) { - return [0.0, 0.0, 0.0]; - } + + if (this._material !== material) { + this._material = material; + makeDirty(this, MATERIAL_INDEX); } } - ], - programs : [ - { - attributes : [] - } - ], - samplers : [ - { - magFilter: WebGLConstants.LINEAR, - minFilter : WebGLConstants.NEAREST_MIPMAP_LINEAR, - wrapS : WebGLConstants.REPEAT, - wrapT : WebGLConstants.REPEAT - } - ], - scenes : [ - { - nodes : [] - } - ], - shaders : [], - skins : [ - { - bindShapeMatrix : [ - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ] - } - ], - techniques : [ - { - parameters: {}, - attributes: {}, - uniforms: {}, - states: { - enable: [] + }, + + /** + * Gets or sets the width of the polyline. + * @memberof Polyline.prototype + * @type {Number} + */ + width: { + get: function() { + return this._width; + }, + set: function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + var width = this._width; + if (value !== width) { + this._width = value; + makeDirty(this, WIDTH_INDEX); } } - ], - textures : [ - { - format: WebGLConstants.RGBA, - internalFormat: WebGLConstants.RGBA, - target: WebGLConstants.TEXTURE_2D, - type: WebGLConstants.UNSIGNED_BYTE - } - ], - extensionsUsed : [], - extensionsRequired : [] - }; + }, - function addDefaultsFromTemplate(object, template) { - for (var id in template) { - if (template.hasOwnProperty(id)) { - var templateValue = template[id]; - if (typeof templateValue === 'function') { - templateValue = templateValue(object); + /** + * Gets or sets whether a line segment will be added between the first and last polyline positions. + * @memberof Polyline.prototype + * @type {Boolean} + */ + loop: { + get: function() { + return this._loop; + }, + set: function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); } - if (defined(templateValue)) { - if (typeof templateValue === 'object') { - if (Array.isArray(templateValue)) { - var arrayValue = defaultValue(object[id], []); - if (templateValue.length > 0) { - var arrayTemplate = templateValue[0]; - if (typeof arrayTemplate === 'object') { - var arrayValueLength = arrayValue.length; - for (var i = 0; i < arrayValueLength; i++) { - addDefaultsFromTemplate(arrayValue[i], arrayTemplate); - } - } else { - arrayValue = defaultValue(object[id], templateValue); - } + + if (value !== this._loop) { + var positions = this._actualPositions; + if (value) { + if (positions.length > 2 && !Cartesian3.equals(positions[0], positions[positions.length - 1])) { + if (positions.length === this._positions.length) { + this._actualPositions = positions = this._positions.slice(); } - object[id] = arrayValue; + positions.push(Cartesian3.clone(positions[0])); + } + } else if (positions.length > 2 && Cartesian3.equals(positions[0], positions[positions.length - 1])) { + if (positions.length - 1 === this._positions.length) { + this._actualPositions = this._positions; } else { - var applyTemplate = templateValue['*']; - object[id] = defaultValue(object[id], {}); - var objectValue = object[id]; - if (defined(applyTemplate)) { - for (var subId in objectValue) { - if (objectValue.hasOwnProperty(subId) && subId !== 'extras') { - var subObject = objectValue[subId]; - addDefaultsFromTemplate(subObject, applyTemplate); - } - } - } else { - addDefaultsFromTemplate(objectValue, templateValue); - } + positions.pop(); } - } else { - object[id] = defaultValue(object[id], templateValue); } + + this._loop = value; + makeDirty(this, POSITION_SIZE_INDEX); } } - } - } - - var defaultMaterial = { - values : { - emission : [ - 0.5, 0.5, 0.5, 1.0 - ] }, - extras : { - _pipeline: {} - } - }; - var defaultTechnique = { - attributes : { - a_position : 'position' - }, - parameters : { - modelViewMatrix : { - semantic : 'MODELVIEW', - type : WebGLConstants.FLOAT_MAT4 - }, - projectionMatrix : { - semantic : 'PROJECTION', - type : WebGLConstants.FLOAT_MAT4 - }, - emission : { - type : WebGLConstants.FLOAT_VEC4, - value : [ - 0.5, 0.5, 0.5, 1.0 - ] + /** + * Gets or sets the user-defined object returned when the polyline is picked. + * @memberof Polyline.prototype + * @type {Object} + */ + id : { + get : function() { + return this._id; }, - position : { - semantic: 'POSITION', - type: WebGLConstants.FLOAT_VEC3 + set : function(value) { + this._id = value; + if (defined(this._pickId)) { + this._pickId.object.id = value; + } } }, - states : { - enable : [ - WebGLConstants.CULL_FACE, - WebGLConstants.DEPTH_TEST - ] - }, - uniforms : { - u_modelViewMatrix : 'modelViewMatrix', - u_projectionMatrix : 'projectionMatrix', - u_emission : 'emission' - } - }; - - var defaultProgram = { - attributes : [ - 'a_position' - ] - }; - - var defaultVertexShader = { - type : WebGLConstants.VERTEX_SHADER, - extras : { - _pipeline : { - extension : '.vert', - source : '' + - 'precision highp float;\n' + - '\n' + - 'uniform mat4 u_modelViewMatrix;\n' + - 'uniform mat4 u_projectionMatrix;\n' + - '\n' + - 'attribute vec3 a_position;\n' + - '\n' + - 'void main (void)\n' + - '{\n' + - ' gl_Position = u_projectionMatrix * u_modelViewMatrix * vec4(a_position, 1.0);\n' + - '}\n' - } - } - }; - - var defaultFragmentShader = { - type : WebGLConstants.FRAGMENT_SHADER, - extras : { - _pipeline : { - extension: '.frag', - source : '' + - 'precision highp float;\n' + - '\n' + - 'uniform vec4 u_emission;\n' + - '\n' + - 'void main(void)\n' + - '{\n' + - ' gl_FragColor = u_emission;\n' + - '}\n' - } - } - }; - - function addDefaultMaterial(gltf) { - var materials = gltf.materials; - var meshes = gltf.meshes; - - var defaultMaterialId; - var meshesLength = meshes.length; - for (var meshId = 0; meshId < meshesLength; meshId++) { - var mesh = meshes[meshId]; - var primitives = mesh.primitives; - var primitivesLength = primitives.length; - for (var j = 0; j < primitivesLength; j++) { - var primitive = primitives[j]; - if (!defined(primitive.material)) { - if (!defined(defaultMaterialId)) { - defaultMaterialId = addToArray(materials, clone(defaultMaterial, true)); - } - primitive.material = defaultMaterialId; + /** + * Gets or sets the condition specifying at what distance from the camera that this polyline will be displayed. + * @memberof Polyline.prototype + * @type {DistanceDisplayCondition} + * @default undefined + */ + distanceDisplayCondition : { + get : function() { + return this._distanceDisplayCondition; + }, + set : function(value) { + if (defined(value) && value.far <= value.near) { + throw new DeveloperError('far distance must be greater than near distance.'); } - } - } - } - - function addDefaultTechnique(gltf) { - var materials = gltf.materials; - var techniques = gltf.techniques; - var programs = gltf.programs; - var shaders = gltf.shaders; - - var defaultTechniqueId; - - var materialsLength = materials.length; - for (var materialId = 0; materialId < materialsLength; materialId++) { - var material = materials[materialId]; - var techniqueId = material.technique; - var extensions = defaultValue(material.extensions, {}); - var materialsCommon = extensions.KHR_materials_common; - if (!defined(techniqueId)) { - if (!defined(defaultTechniqueId) && !defined(materialsCommon)) { - var technique = clone(defaultTechnique, true); - defaultTechniqueId = addToArray(techniques, technique); - - var program = clone(defaultProgram, true); - technique.program = addToArray(programs, program); - - var vertexShader = clone(defaultVertexShader, true); - program.vertexShader = addToArray(shaders, vertexShader); - - var fragmentShader = clone(defaultFragmentShader, true); - program.fragmentShader = addToArray(shaders, fragmentShader); + if (!DistanceDisplayCondition.equals(value, this._distanceDisplayCondition)) { + this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); + makeDirty(this, DISTANCE_DISPLAY_CONDITION); } - material.technique = defaultTechniqueId; } } - } - - function addDefaultByteOffsets(gltf) { - var accessors = gltf.accessors; + }); - var accessorLength = accessors.length; - for (var i = 0; i < accessorLength; i++) { - var accessor = accessors[i]; - if (!defined(accessor.byteOffset)) { - accessor.byteOffset = 0; - } + /** + * @private + */ + Polyline.prototype.update = function() { + var modelMatrix = Matrix4.IDENTITY; + if (defined(this._polylineCollection)) { + modelMatrix = this._polylineCollection.modelMatrix; } - var bufferViews = gltf.bufferViews; + var segmentPositionsLength = this._segments.positions.length; + var segmentLengths = this._segments.lengths; - var bufferViewsLength = bufferViews.length; - for (var j = 0; j < bufferViewsLength; j++) { - var bufferView = bufferViews[j]; - if (!defined(bufferView.byteOffset)) { - bufferView.byteOffset = 0; - } + var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; + if (!Matrix4.equals(modelMatrix, this._modelMatrix) || positionsChanged) { + this._segments = PolylinePipeline.wrapLongitude(this._actualPositions, modelMatrix); + this._boundingVolumeWC = BoundingSphere.transform(this._boundingVolume, modelMatrix, this._boundingVolumeWC); } - } - function selectDefaultScene(gltf) { - if (defined(gltf.scenes) && !defined(gltf.scene)) { - gltf.scene = 0; - } - } + this._modelMatrix = Matrix4.clone(modelMatrix, this._modelMatrix); - function optimizeForCesium(gltf) { - // Give the diffuse uniform a semantic to support color replacement in 3D Tiles - var techniques = gltf.techniques; - var techniquesLength = techniques.length; - for (var techniqueId = 0; techniqueId < techniquesLength; techniqueId++) { - var technique = techniques[techniqueId]; - var parameters = technique.parameters; - if (defined(parameters.diffuse)) { - parameters.diffuse.semantic = '_3DTILESDIFFUSE'; + if (this._segments.positions.length !== segmentPositionsLength) { + // number of positions changed + makeDirty(this, POSITION_SIZE_INDEX); + } else { + var length = segmentLengths.length; + for (var i = 0; i < length; ++i) { + if (segmentLengths[i] !== this._segments.lengths[i]) { + // indices changed + makeDirty(this, POSITION_SIZE_INDEX); + break; + } } } - } + }; - function inferBufferViewTargets(gltf) { - // If bufferView elements are missing targets, we can infer their type from their use - var needsTarget = {}; - var shouldTraverse = 0; - ForEach.bufferView(gltf, function(bufferView, bufferViewId) { - if (!defined(bufferView.target)) { - needsTarget[bufferViewId] = true; - shouldTraverse++; - } - }); - if (shouldTraverse > 0) { - var accessors = gltf.accessors; - var bufferViews = gltf.bufferViews; - ForEach.mesh(gltf, function (mesh) { - ForEach.meshPrimitive(mesh, function (primitive) { - var indices = primitive.indices; - if (defined(indices)) { - var accessor = accessors[indices]; - var bufferViewId = accessor.bufferView; - if (needsTarget[bufferViewId]) { - var bufferView = bufferViews[bufferViewId]; - if (defined(bufferView)) { - bufferView.target = WebGLConstants.ELEMENT_ARRAY_BUFFER; - needsTarget[bufferViewId] = false; - shouldTraverse--; - } - } - } - ForEach.meshPrimitiveAttribute(primitive, function (accessorId) { - var accessor = accessors[accessorId]; - var bufferViewId = accessor.bufferView; - if (needsTarget[bufferViewId]) { - var bufferView = bufferViews[bufferViewId]; - if (defined(bufferView)) { - bufferView.target = WebGLConstants.ARRAY_BUFFER; - needsTarget[bufferViewId] = false; - shouldTraverse--; - } - } - }); - ForEach.meshPrimitiveTargetAttribute(primitive, function (targetAttribute) { - var bufferViewId = accessors[targetAttribute].bufferView; - if (needsTarget[bufferViewId]) { - var bufferView = bufferViews[bufferViewId]; - if (defined(bufferView)) { - bufferView.target = WebGLConstants.ARRAY_BUFFER; - needsTarget[bufferViewId] = false; - shouldTraverse--; - } - } - }); - }); - if (shouldTraverse === 0) { - return true; - } + /** + * @private + */ + Polyline.prototype.getPickId = function(context) { + if (!defined(this._pickId)) { + this._pickId = context.createPickId({ + primitive : this, + collection : this._polylineCollection, + id : this._id }); } - } + return this._pickId; + }; - /** - * Adds default glTF values if they don't exist. - * - * The glTF asset must be initialized for the pipeline. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.optimizeForCesium] Optimize the defaults for Cesium. Uses the Cesium sun as the default light source. - * @returns {Object} The modified glTF. - * - * @see addPipelineExtras - * @see loadGltfUris - */ - function addDefaults(gltf, options) { - options = defaultValue(options, {}); - addDefaultsFromTemplate(gltf, gltfTemplate); - addDefaultMaterial(gltf); - addDefaultTechnique(gltf); - addDefaultByteOffsets(gltf); - selectDefaultScene(gltf); - inferBufferViewTargets(gltf); - if (options.optimizeForCesium) { - optimizeForCesium(gltf); + Polyline.prototype._clean = function() { + this._dirty = false; + var properties = this._propertiesChanged; + for ( var k = 0; k < NUMBER_OF_PROPERTIES - 1; ++k) { + properties[k] = 0; } - return gltf; - } + }; - return addDefaults; + Polyline.prototype._destroy = function() { + this._pickId = this._pickId && this._pickId.destroy(); + this._material = this._material && this._material.destroy(); + this._polylineCollection = undefined; + }; + + return Polyline; }); -define('ThirdParty/GltfPipeline/addPipelineExtras',[ - '../../Core/defaultValue', - '../../Core/defined' +define('Scene/PolylineCollection',[ + '../Core/BoundingSphere', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/Color', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/EncodedCartesian3', + '../Core/IndexDatatype', + '../Core/Intersect', + '../Core/Math', + '../Core/Matrix4', + '../Core/Plane', + '../Core/RuntimeError', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/ContextLimits', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/Texture', + '../Renderer/VertexArray', + '../Shaders/PolylineCommon', + '../Shaders/PolylineFS', + '../Shaders/PolylineVS', + './BatchTable', + './BlendingState', + './Material', + './Polyline', + './SceneMode' ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + Color, + combine, + ComponentDatatype, defaultValue, - defined) { + defined, + defineProperties, + destroyObject, + DeveloperError, + EncodedCartesian3, + IndexDatatype, + Intersect, + CesiumMath, + Matrix4, + Plane, + RuntimeError, + Buffer, + BufferUsage, + ContextLimits, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + Texture, + VertexArray, + PolylineCommon, + PolylineFS, + PolylineVS, + BatchTable, + BlendingState, + Material, + Polyline, + SceneMode) { 'use strict'; - // Objects with these ids should not have extras added - var exceptions = { - attributes: true, - uniforms: true, - extensions: true, - values: true, - samplers: true + var SHOW_INDEX = Polyline.SHOW_INDEX; + var WIDTH_INDEX = Polyline.WIDTH_INDEX; + var POSITION_INDEX = Polyline.POSITION_INDEX; + var MATERIAL_INDEX = Polyline.MATERIAL_INDEX; + //POSITION_SIZE_INDEX is needed for when the polyline's position array changes size. + //When it does, we need to recreate the indicesBuffer. + var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX; + var DISTANCE_DISPLAY_CONDITION = Polyline.DISTANCE_DISPLAY_CONDITION; + var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES; + + var attributeLocations = { + texCoordExpandAndBatchIndex : 0, + position3DHigh : 1, + position3DLow : 2, + position2DHigh : 3, + position2DLow : 4, + prevPosition3DHigh : 5, + prevPosition3DLow : 6, + prevPosition2DHigh : 7, + prevPosition2DLow : 8, + nextPosition3DHigh : 9, + nextPosition3DLow : 10, + nextPosition2DHigh : 11, + nextPosition2DLow : 12 }; /** - * Adds extras._pipeline to each object that can have extras in the glTF asset. + * A renderable collection of polylines. + * <br /><br /> + * <div align="center"> + * <img src="Images/Polyline.png" width="400" height="300" /><br /> + * Example polylines + * </div> + * <br /><br /> + * Polylines are added and removed from the collection using {@link PolylineCollection#add} + * and {@link PolylineCollection#remove}. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The glTF asset with the added pipeline extras. + * @alias PolylineCollection + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each polyline from model to world coordinates. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * + * @performance For best performance, prefer a few collections, each with many polylines, to + * many collections with only a few polylines each. Organize collections so that polylines + * with the same update frequency are in the same collection, i.e., polylines that do not + * change should be in one collection; polylines that change every frame should be in another + * collection; and so on. + * + * @see PolylineCollection#add + * @see PolylineCollection#remove + * @see Polyline + * @see LabelCollection + * + * @example + * // Create a polyline collection with two polylines + * var polylines = new Cesium.PolylineCollection(); + * polylines.add({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * -75.10, 39.57, + * -77.02, 38.53, + * -80.50, 35.14, + * -80.12, 25.46]), + * width : 2 + * }); + * + * polylines.add({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * -73.10, 37.57, + * -75.02, 36.53, + * -78.50, 33.14, + * -78.12, 23.46]), + * width : 4 + * }); */ - function addPipelineExtras(gltf) { - var objectStack = []; - for (var rootArrayId in gltf) { - if (gltf.hasOwnProperty(rootArrayId)) { - var rootArray = gltf[rootArrayId]; - var rootArrayLength = rootArray.length; - for (var i = 0; i < rootArrayLength; i++) { - var rootObject = rootArray[i]; - if (defined(rootObject) && typeof rootObject === 'object') { - rootObject.extras = defaultValue(rootObject.extras, {}); - rootObject.extras._pipeline = defaultValue(rootObject.extras._pipeline, {}); - objectStack.push(rootObject); - } - } - } - } - while (objectStack.length > 0) { - var object = objectStack.pop(); - for (var propertyId in object) { - if (object.hasOwnProperty(propertyId)) { - var property = object[propertyId]; - if (defined(property) && typeof property === 'object' && propertyId !== 'extras') { - objectStack.push(property); - if (!exceptions[propertyId] && !Array.isArray(property)) { - property.extras = defaultValue(property.extras, {}); - property.extras._pipeline = defaultValue(property.extras._pipeline, {}); - } - } - } - } - } - gltf.extras = defaultValue(gltf.extras, {}); - gltf.extras._pipeline = defaultValue(gltf.extras._pipeline, {}); - gltf.asset = defaultValue(gltf.asset, {}); - gltf.asset.extras = defaultValue(gltf.asset.extras, {}); - if (defined(gltf.asset.extras) && typeof(gltf.asset.extras) !== 'object') { - gltf.asset.extras = { - extras : gltf.asset.extras - }; - } - gltf.asset.extras._pipeline = defaultValue(gltf.asset.extras._pipeline, {}); - return gltf; - } - return addPipelineExtras; -}); + function PolylineCollection(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); -define('ThirdParty/GltfPipeline/byteLengthForComponentType',[ - '../../Core/WebGLConstants' - ], function( - WebGLConstants) { - 'use strict'; + /** + * The 4x4 transformation matrix that transforms each polyline in this collection from model to world coordinates. + * When this is the identity matrix, the polylines are drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. + * + * @type {Matrix4} + * @default {@link Matrix4.IDENTITY} + */ + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); - /** - * Utility function for retrieving the byte length of a component type. - * As per the spec: - * 5120 (BYTE) : 1 - * 5121 (UNSIGNED_BYTE) : 1 - * 5122 (SHORT) : 2 - * 5123 (UNSIGNED_SHORT) : 2 - * 5126 (FLOAT) : 4 - * 5125 (UNSIGNED_INT) : 4 - * - * @param {Number} [componentType] - * @returns {Number} The byte length of the component type. - */ - function byteLengthForComponentType(componentType) { - switch (componentType) { - case WebGLConstants.BYTE: - case WebGLConstants.UNSIGNED_BYTE: - return 1; - case WebGLConstants.SHORT: - case WebGLConstants.UNSIGNED_SHORT: - return 2; - case WebGLConstants.FLOAT: - case WebGLConstants.UNSIGNED_INT: - return 4; - } - } - return byteLengthForComponentType; -}); + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the primitive. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); -define('ThirdParty/GltfPipeline/numberOfComponentsForType',[], function() { - 'use strict'; + this._opaqueRS = undefined; + this._translucentRS = undefined; - /** - * Utility function for retrieving the number of components in a given type. - * As per the spec: - * 'SCALAR' : 1 - * 'VEC2' : 2 - * 'VEC3' : 3 - * 'VEC4' : 4 - * 'MAT2' : 4 - * 'MAT3' : 9 - * 'MAT4' : 16 - * - * @param {String} type glTF type - * @returns {Number} The number of components in that type. - */ - function numberOfComponentsForType(type) { - switch (type) { - case 'SCALAR': - return 1; - case 'VEC2': - return 2; - case 'VEC3': - return 3; - case 'VEC4': - case 'MAT2': - return 4; - case 'MAT3': - return 9; - case 'MAT4': - return 16; - } + this._colorCommands = []; + this._pickCommands = []; + + this._polylinesUpdated = false; + this._polylinesRemoved = false; + this._createVertexArray = false; + this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); + this._polylines = []; + this._polylineBuckets = {}; + + // The buffer usage is determined based on the usage of the attribute over time. + this._positionBufferUsage = { bufferUsage : BufferUsage.STATIC_DRAW, frameCount : 0 }; + + this._mode = undefined; + + this._polylinesToUpdate = []; + this._vertexArrays = []; + this._positionBuffer = undefined; + this._texCoordExpandAndBatchIndexBuffer = undefined; + + this._batchTable = undefined; + this._createBatchTable = false; + + // Only used by Vector3DTilePoints + this._useHighlightColor = false; + this._highlightColor = Color.clone(Color.WHITE); + + var that = this; + this._uniformMap = { + u_highlightColor : function() { + return that._highlightColor; + } + }; } - return numberOfComponentsForType; -}); -define('ThirdParty/GltfPipeline/getAccessorByteStride',[ - './byteLengthForComponentType', - './numberOfComponentsForType', - '../../Core/defined' - ], function( - byteLengthForComponentType, - numberOfComponentsForType, - defined) { - 'use strict'; + defineProperties(PolylineCollection.prototype, { + /** + * Returns the number of polylines in this collection. This is commonly used with + * {@link PolylineCollection#get} to iterate over all the polylines + * in the collection. + * @memberof PolylineCollection.prototype + * @type {Number} + */ + length : { + get : function() { + removePolylines(this); + return this._polylines.length; + } + } + }); /** - * Returns the byte stride of the provided accessor. - * If the byteStride is 0, it is calculated based on type and componentType + * Creates and adds a polyline with the specified initial properties to the collection. + * The added polyline is returned so it can be modified or removed from the collection later. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor. - * @returns {Number} The byte stride of the accessor. - */ - function getAccessorByteStride(gltf, accessor) { - var bufferView = gltf.bufferViews[accessor.bufferView]; - if (defined(bufferView.byteStride) && bufferView.byteStride > 0) { - return bufferView.byteStride; - } - return byteLengthForComponentType(accessor.componentType) * numberOfComponentsForType(accessor.type); - } - return getAccessorByteStride; -}); - -define('ThirdParty/GltfPipeline/removeExtensionsRequired',[ - '../../Core/defined' - ], function( - defined) { - 'use strict'; + * @param {Object}[polyline] A template describing the polyline's properties as shown in Example 1. + * @returns {Polyline} The polyline that was added to the collection. + * + * @performance After calling <code>add</code>, {@link PolylineCollection#update} is called and + * the collection's vertex buffer is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. + * For best performance, add as many polylines as possible before calling <code>update</code>. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Example 1: Add a polyline, specifying all the default values. + * var p = polylines.add({ + * show : true, + * positions : ellipsoid.cartographicArrayToCartesianArray([ + Cesium.Cartographic.fromDegrees(-75.10, 39.57), + Cesium.Cartographic.fromDegrees(-77.02, 38.53)]), + * width : 1 + * }); + * + * @see PolylineCollection#remove + * @see PolylineCollection#removeAll + * @see PolylineCollection#update + */ + PolylineCollection.prototype.add = function(polyline) { + var p = new Polyline(polyline, this); + p._index = this._polylines.length; + this._polylines.push(p); + this._createVertexArray = true; + this._createBatchTable = true; + return p; + }; /** - * Removes an extension from gltf.extensionsRequired if it is present. + * Removes a polyline from the collection. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. + * @param {Polyline} polyline The polyline to remove. + * @returns {Boolean} <code>true</code> if the polyline was removed; <code>false</code> if the polyline was not found in the collection. + * + * @performance After calling <code>remove</code>, {@link PolylineCollection#update} is called and + * the collection's vertex buffer is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. + * For best performance, remove as many polylines as possible before calling <code>update</code>. + * If you intend to temporarily hide a polyline, it is usually more efficient to call + * {@link Polyline#show} instead of removing and re-adding the polyline. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * var p = polylines.add(...); + * polylines.remove(p); // Returns true + * + * @see PolylineCollection#add + * @see PolylineCollection#removeAll + * @see PolylineCollection#update + * @see Polyline#show */ - function removeExtensionsRequired(gltf, extension) { - var extensionsRequired = gltf.extensionsRequired; - if (defined(extensionsRequired)) { - var index = extensionsRequired.indexOf(extension); - if (index >= 0) { - extensionsRequired.splice(index, 1); - } - if (extensionsRequired.length === 0) { - delete gltf.extensionsRequired; + PolylineCollection.prototype.remove = function(polyline) { + if (this.contains(polyline)) { + this._polylines[polyline._index] = undefined; // Removed later + this._polylinesRemoved = true; + this._createVertexArray = true; + this._createBatchTable = true; + if (defined(polyline._bucket)) { + var bucket = polyline._bucket; + bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.destroy(); + bucket.pickShaderProgram = bucket.pickShaderProgram && bucket.pickShaderProgram.destroy(); } + polyline._destroy(); + return true; } - } - - return removeExtensionsRequired; -}); -define('ThirdParty/GltfPipeline/removeExtensionsUsed',[ - './removeExtensionsRequired', - '../../Core/defined' - ], function( - removeExtensionsRequired, - defined) { - 'use strict'; + return false; + }; /** - * Removes an extension from gltf.extensionsUsed and gltf.extensionsRequired if it is present. + * Removes all polylines from the collection. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. + * @performance <code>O(n)</code>. It is more efficient to remove all the polylines + * from a collection and then add new ones than to create a new collection entirely. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * polylines.add(...); + * polylines.add(...); + * polylines.removeAll(); + * + * @see PolylineCollection#add + * @see PolylineCollection#remove + * @see PolylineCollection#update */ - function removeExtensionsUsed(gltf, extension) { - var extensionsUsed = gltf.extensionsUsed; - if (defined(extensionsUsed)) { - var index = extensionsUsed.indexOf(extension); - if (index >= 0) { - extensionsUsed.splice(index, 1); - } - removeExtensionsRequired(gltf, extension); - if (extensionsUsed.length === 0) { - delete gltf.extensionsUsed; - } - } - } - return removeExtensionsUsed; -}); - -define('ThirdParty/GltfPipeline/addExtensionsUsed',[ - '../../Core/defined' - ], function( - defined) { - 'use strict'; + PolylineCollection.prototype.removeAll = function() { + releaseShaders(this); + destroyPolylines(this); + this._polylineBuckets = {}; + this._polylinesRemoved = false; + this._polylines.length = 0; + this._polylinesToUpdate.length = 0; + this._createVertexArray = true; + }; /** - * Adds an extension to gltf.extensionsUsed if it does not already exist. - * Initializes extensionsUsed if it is not defined. + * Determines if this collection contains the specified polyline. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to add. + * @param {Polyline} polyline The polyline to check for. + * @returns {Boolean} true if this collection contains the polyline, false otherwise. + * + * @see PolylineCollection#get */ - function addExtensionsUsed(gltf, extension) { - var extensionsUsed = gltf.extensionsUsed; - if (!defined(extensionsUsed)) { - extensionsUsed = []; - gltf.extensionsUsed = extensionsUsed; - } - if (extensionsUsed.indexOf(extension) < 0) { - extensionsUsed.push(extension); - } - } - return addExtensionsUsed; -}); - -define('ThirdParty/GltfPipeline/addExtensionsRequired',[ - './addExtensionsUsed', - '../../Core/defined' - ], function( - addExtensionsUsed, - defined) { - 'use strict'; + PolylineCollection.prototype.contains = function(polyline) { + return defined(polyline) && polyline._polylineCollection === this; + }; /** - * Adds an extension to gltf.extensionsRequired if it does not already exist. - * Initializes extensionsRequired if it is not defined. + * Returns the polyline in the collection at the specified index. Indices are zero-based + * and increase as polylines are added. Removing a polyline shifts all polylines after + * it to the left, changing their indices. This function is commonly used with + * {@link PolylineCollection#length} to iterate over all the polylines + * in the collection. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to add. + * @param {Number} index The zero-based index of the polyline. + * @returns {Polyline} The polyline at the specified index. + * + * @performance If polylines were removed from the collection and + * {@link PolylineCollection#update} was not called, an implicit <code>O(n)</code> + * operation is performed. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * // Toggle the show property of every polyline in the collection + * var len = polylines.length; + * for (var i = 0; i < len; ++i) { + * var p = polylines.get(i); + * p.show = !p.show; + * } + * + * @see PolylineCollection#length */ - function addExtensionsRequired(gltf, extension) { - var extensionsRequired = gltf.extensionsRequired; - if (!defined(extensionsRequired)) { - extensionsRequired = []; - gltf.extensionsRequired = extensionsRequired; + PolylineCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); } - if (extensionsRequired.indexOf(extension) < 0) { - extensionsRequired.push(extension); + + removePolylines(this); + return this._polylines[index]; + }; + + function createBatchTable(collection, context) { + if (defined(collection._batchTable)) { + collection._batchTable.destroy(); } - addExtensionsUsed(gltf, extension); - } - return addExtensionsRequired; -}); -define('ThirdParty/GltfPipeline/updateVersion',[ - './addExtensionsRequired', - './addToArray', - './ForEach', - './getAccessorByteStride', - './numberOfComponentsForType', - '../../Core/Cartesian3', - '../../Core/Math', - '../../Core/clone', - '../../Core/ComponentDatatype', - '../../Core/defaultValue', - '../../Core/defined', - '../../Core/Quaternion', - '../../Core/WebGLConstants' - ], function( - addExtensionsRequired, - addToArray, - ForEach, - getAccessorByteStride, - numberOfComponentsForType, - Cartesian3, - CesiumMath, - clone, - ComponentDatatype, - defaultValue, - defined, - Quaternion, - WebGLConstants) { - 'use strict'; + var attributes = [{ + functionName : 'batchTable_getWidthAndShow', + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + componentsPerAttribute : 2 + }, { + functionName : 'batchTable_getPickColor', + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + componentsPerAttribute : 4, + normalize : true + }, { + functionName : 'batchTable_getCenterHigh', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + }, { + functionName : 'batchTable_getCenterLowAndRadius', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 4 + }, { + functionName : 'batchTable_getDistanceDisplayCondition', + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2 + }]; - var updateFunctions = { - '0.8' : glTF08to10, - '1.0' : glTF10to20, - '2.0' : undefined - }; + collection._batchTable = new BatchTable(context, attributes, collection._polylines.length); + } + + var scratchUpdatePolylineEncodedCartesian = new EncodedCartesian3(); + var scratchUpdatePolylineCartesian4 = new Cartesian4(); + var scratchNearFarCartesian2 = new Cartesian2(); /** - * Update the glTF version to the latest version (2.0), or targetVersion if specified. - * Applies changes made to the glTF spec between revisions so that the core library - * only has to handle the latest version. + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} [options] Options for updating the glTF. - * @param {String} [options.targetVersion] The glTF will be upgraded until it hits the specified version. - * @returns {Object} The updated glTF asset. + * @exception {RuntimeError} Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero. */ - function updateVersion(gltf, options) { - options = defaultValue(options, {}); - var targetVersion = options.targetVersion; - var version = gltf.version; - - gltf.asset = defaultValue(gltf.asset, { - version: '1.0' - }); + PolylineCollection.prototype.update = function(frameState) { + removePolylines(this); - version = defaultValue(version, gltf.asset.version); - // invalid version - if (!updateFunctions.hasOwnProperty(version)) { - // try truncating trailing version numbers, could be a number as well if it is 0.8 - if (defined(version)) { - version = ('' + version).substring(0, 3); - } - // default to 1.0 if it cannot be determined - if (!updateFunctions.hasOwnProperty(version)) { - version = '1.0'; - } + if (this._polylines.length === 0) { + return; } - var updateFunction = updateFunctions[version]; + updateMode(this, frameState); - while (defined(updateFunction)) { - if (version === targetVersion) { - break; + var context = frameState.context; + var projection = frameState.mapProjection; + var polyline; + var properties = this._propertiesChanged; + + if (this._createBatchTable) { + if (ContextLimits.maximumVertexTextureImageUnits === 0) { + throw new RuntimeError('Vertex texture fetch support is required to render polylines. The maximum number of vertex texture image units must be greater than zero.'); } - updateFunction(gltf); - version = gltf.asset.version; - updateFunction = updateFunctions[version]; + createBatchTable(this, context); + this._createBatchTable = false; } - return gltf; - } - function updateInstanceTechniques(gltf) { - var materials = gltf.materials; - for (var materialId in materials) { - if (materials.hasOwnProperty(materialId)) { - var material = materials[materialId]; - var instanceTechnique = material.instanceTechnique; - if (defined(instanceTechnique)) { - material.technique = instanceTechnique.technique; - material.values = instanceTechnique.values; - delete material.instanceTechnique; + if (this._createVertexArray || computeNewBuffersUsage(this)) { + createVertexArrays(this, context, projection); + } else if (this._polylinesUpdated) { + // Polylines were modified, but no polylines were added or removed. + var polylinesToUpdate = this._polylinesToUpdate; + if (this._mode !== SceneMode.SCENE3D) { + var updateLength = polylinesToUpdate.length; + for ( var i = 0; i < updateLength; ++i) { + polyline = polylinesToUpdate[i]; + polyline.update(); } } - } - } - function setPrimitiveModes(gltf) { - var meshes = gltf.meshes; - for (var meshId in meshes) { - if (meshes.hasOwnProperty(meshId)) { - var mesh = meshes[meshId]; - var primitives = mesh.primitives; - if (defined(primitives)) { - var primitivesLength = primitives.length; - for (var i = 0; i < primitivesLength; i++) { - var primitive = primitives[i]; - var defaultMode = defaultValue(primitive.primitive, WebGLConstants.TRIANGLES); - primitive.mode = defaultValue(primitive.mode, defaultMode); - delete primitive.primitive; + // if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. + // if a polyline's material changes, we need to recreate the VAOs and VBOs because they will be batched differently. + if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX]) { + createVertexArrays(this, context, projection); + } else { + var length = polylinesToUpdate.length; + var polylineBuckets = this._polylineBuckets; + for ( var ii = 0; ii < length; ++ii) { + polyline = polylinesToUpdate[ii]; + properties = polyline._propertiesChanged; + var bucket = polyline._bucket; + var index = 0; + for (var x in polylineBuckets) { + if (polylineBuckets.hasOwnProperty(x)) { + if (polylineBuckets[x] === bucket) { + if (properties[POSITION_INDEX]) { + bucket.writeUpdate(index, polyline, this._positionBuffer, projection); + } + break; + } + index += polylineBuckets[x].lengthOfPositions; + } } - } - } - } - } - function updateNodes(gltf) { - var nodes = gltf.nodes; - var axis = new Cartesian3(); - var quat = new Quaternion(); - for (var nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - var node = nodes[nodeId]; - if (defined(node.rotation)) { - var rotation = node.rotation; - Cartesian3.fromArray(rotation, 0, axis); - Quaternion.fromAxisAngle(axis, rotation[3], quat); - node.rotation = [quat.x, quat.y, quat.z, quat.w]; - } - var instanceSkin = node.instanceSkin; - if (defined(instanceSkin)) { - node.skeletons = instanceSkin.skeletons; - node.skin = instanceSkin.skin; - node.meshes = instanceSkin.meshes; - delete node.instanceSkin; - } - } - } - } + if (properties[SHOW_INDEX] || properties[WIDTH_INDEX]) { + this._batchTable.setBatchedAttribute(polyline._index, 0, new Cartesian2(polyline._width, polyline._show)); + } - function updateAnimations(gltf) { - var animations = gltf.animations; - var accessors = gltf.accessors; - var bufferViews = gltf.bufferViews; - var buffers = gltf.buffers; - var updatedAccessors = {}; - var axis = new Cartesian3(); - var quat = new Quaternion(); - for (var animationId in animations) { - if (animations.hasOwnProperty(animationId)) { - var animation = animations[animationId]; - var channels = animation.channels; - var parameters = animation.parameters; - var samplers = animation.samplers; - if (defined(channels)) { - var channelsLength = channels.length; - for (var i = 0; i < channelsLength; ++i) { - var channel = channels[i]; - if (channel.target.path === 'rotation') { - var accessorId = parameters[samplers[channel.sampler].output]; - if (defined(updatedAccessors[accessorId])) { - continue; - } - updatedAccessors[accessorId] = true; - var accessor = accessors[accessorId]; - var bufferView = bufferViews[accessor.bufferView]; - var buffer = buffers[bufferView.buffer]; - var source = buffer.extras._pipeline.source; - var byteOffset = source.byteOffset + bufferView.byteOffset + accessor.byteOffset; - var componentType = accessor.componentType; - var count = accessor.count; - var componentsLength = numberOfComponentsForType(accessor.type); - var length = accessor.count * componentsLength; - var typedArray = ComponentDatatype.createArrayBufferView(componentType, source.buffer, byteOffset, length); + if (this._batchTable.attributes.length > 2) { + if (properties[POSITION_INDEX] || properties[POSITION_SIZE_INDEX]) { + var boundingSphere = frameState.mode === SceneMode.SCENE2D ? polyline._boundingVolume2D : polyline._boundingVolumeWC; + var encodedCenter = EncodedCartesian3.fromCartesian(boundingSphere.center, scratchUpdatePolylineEncodedCartesian); + var low = Cartesian4.fromElements(encodedCenter.low.x, encodedCenter.low.y, encodedCenter.low.z, boundingSphere.radius, scratchUpdatePolylineCartesian4); + this._batchTable.setBatchedAttribute(polyline._index, 2, encodedCenter.high); + this._batchTable.setBatchedAttribute(polyline._index, 3, low); + } - for (var j = 0; j < count; j++) { - var offset = j * componentsLength; - Cartesian3.unpack(typedArray, offset, axis); - var angle = typedArray[offset + 3]; - Quaternion.fromAxisAngle(axis, angle, quat); - Quaternion.pack(quat, typedArray, offset); + if (properties[DISTANCE_DISPLAY_CONDITION]) { + var nearFarCartesian = scratchNearFarCartesian2; + nearFarCartesian.x = 0.0; + nearFarCartesian.y = Number.MAX_VALUE; + + var distanceDisplayCondition = polyline.distanceDisplayCondition; + if (defined(distanceDisplayCondition)) { + nearFarCartesian.x = distanceDisplayCondition.near; + nearFarCartesian.y = distanceDisplayCondition.far; } + + this._batchTable.setBatchedAttribute(polyline._index, 4, nearFarCartesian); } } - } - } - } - } - function removeTechniquePasses(gltf) { - var techniques = gltf.techniques; - for (var techniqueId in techniques) { - if (techniques.hasOwnProperty(techniqueId)) { - var technique = techniques[techniqueId]; - var passes = technique.passes; - if (defined(passes)) { - var passName = defaultValue(technique.pass, 'defaultPass'); - if (passes.hasOwnProperty(passName)) { - var pass = passes[passName]; - var instanceProgram = pass.instanceProgram; - technique.attributes = defaultValue(technique.attributes, instanceProgram.attributes); - technique.program = defaultValue(technique.program, instanceProgram.program); - technique.uniforms = defaultValue(technique.uniforms, instanceProgram.uniforms); - technique.states = defaultValue(technique.states, pass.states); - } - delete technique.passes; - delete technique.pass; + polyline._clean(); } } + polylinesToUpdate.length = 0; + this._polylinesUpdated = false; } - } - function glTF08to10(gltf) { - if (!defined(gltf.asset)) { - gltf.asset = {}; - } - var asset = gltf.asset; - asset.version = '1.0'; - // profile should be an object, not a string - if (!defined(asset.profile) || (typeof asset.profile === 'string')) { - asset.profile = {}; - } - // version property should be in asset, not on the root element - if (defined(gltf.version)) { - delete gltf.version; - } - // material.instanceTechnique properties should be directly on the material - updateInstanceTechniques(gltf); - // primitive.primitive should be primitive.mode - setPrimitiveModes(gltf); - // node rotation should be quaternion, not axis-angle - // node.instanceSkin is deprecated - updateNodes(gltf); - // animations that target rotations should be quaternion, not axis-angle - updateAnimations(gltf); - // technique.pass and techniques.passes are deprecated - removeTechniquePasses(gltf); - // gltf.lights -> khrMaterialsCommon.lights - if (defined(gltf.lights)) { - var extensions = defaultValue(gltf.extensions, {}); - gltf.extensions = extensions; - var materialsCommon = defaultValue(extensions.KHR_materials_common, {}); - extensions.KHR_materials_common = materialsCommon; - materialsCommon.lights = gltf.lights; - delete gltf.lights; + properties = this._propertiesChanged; + for ( var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { + properties[k] = 0; } - // gltf.allExtensions -> extensionsUsed - if (defined(gltf.allExtensions)) { - gltf.extensionsUsed = gltf.allExtensions; - gltf.allExtensions = undefined; + + var modelMatrix = Matrix4.IDENTITY; + if (frameState.mode === SceneMode.SCENE3D) { + modelMatrix = this.modelMatrix; } - } - function removeAnimationSamplersIndirection(gltf) { - var animations = gltf.animations; - for (var animationId in animations) { - if (animations.hasOwnProperty(animationId)) { - var animation = animations[animationId]; - var parameters = animation.parameters; - if (defined(parameters)) { - var samplers = animation.samplers; - for (var samplerId in samplers) { - if (samplers.hasOwnProperty(samplerId)) { - var sampler = samplers[samplerId]; - sampler.input = parameters[sampler.input]; - sampler.output = parameters[sampler.output]; - } - } - delete animation.parameters; + var pass = frameState.passes; + var useDepthTest = (frameState.morphTime !== 0.0); + + if (!defined(this._opaqueRS) || this._opaqueRS.depthTest.enabled !== useDepthTest) { + this._opaqueRS = RenderState.fromCache({ + depthMask : useDepthTest, + depthTest : { + enabled : useDepthTest } - } + }); } - } - function objectToArray(object, mapping) { - var array = []; - for (var id in object) { - if (object.hasOwnProperty(id)) { - var value = object[id]; - mapping[id] = array.length; - array.push(value); - if (!defined(value.name) && typeof(value) === 'object') { - value.name = id; + if (!defined(this._translucentRS) || this._translucentRS.depthTest.enabled !== useDepthTest) { + this._translucentRS = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND, + depthMask : !useDepthTest, + depthTest : { + enabled : useDepthTest } - } + }); } - return array; - } - function objectsToArrays(gltf) { - var i; - var globalMapping = { - accessors: {}, - animations: {}, - bufferViews: {}, - buffers: {}, - cameras: {}, - materials: {}, - meshes: {}, - nodes: {}, - programs: {}, - shaders: {}, - skins: {}, - techniques: {} - }; + this._batchTable.update(frameState); - // Map joint names to id names - var jointName; - var jointNameToId = {}; - var nodes = gltf.nodes; - for (var id in nodes) { - if (nodes.hasOwnProperty(id)) { - jointName = nodes[id].jointName; - if (defined(jointName)) { - jointNameToId[jointName] = id; - } - } + if (pass.render) { + var colorList = this._colorCommands; + createCommandLists(this, frameState, colorList, modelMatrix, true); } - // Convert top level objects to arrays - for (var topLevelId in gltf) { - if (gltf.hasOwnProperty(topLevelId) && topLevelId !== 'extras' && topLevelId !== 'asset' && topLevelId !== 'extensions') { - var objectMapping = {}; - var object = gltf[topLevelId]; - if (typeof(object) === 'object' && !Array.isArray(object)) { - gltf[topLevelId] = objectToArray(object, objectMapping); - globalMapping[topLevelId] = objectMapping; - if (topLevelId === 'animations') { - objectMapping = {}; - object.samplers = objectToArray(object.samplers, objectMapping); - globalMapping[topLevelId].samplers = objectMapping; - } - } - } + if (pass.pick) { + var pickList = this._pickCommands; + createCommandLists(this, frameState, pickList, modelMatrix, false); } + }; - // Remap joint names to array indexes - for (jointName in jointNameToId) { - if (jointNameToId.hasOwnProperty(jointName)) { - jointNameToId[jointName] = globalMapping.nodes[jointNameToId[jointName]]; - } - } + var boundingSphereScratch = new BoundingSphere(); + var boundingSphereScratch2 = new BoundingSphere(); - // Fix references - if (defined(gltf.scene)) { - gltf.scene = globalMapping.scenes[gltf.scene]; - } - ForEach.bufferView(gltf, function(bufferView) { - if (defined(bufferView.buffer)) { - bufferView.buffer = globalMapping.buffers[bufferView.buffer]; - } - }); - ForEach.accessor(gltf, function(accessor) { - if (defined(accessor.bufferView)) { - accessor.bufferView = globalMapping.bufferViews[accessor.bufferView]; - } - }); - ForEach.shader(gltf, function(shader) { - var extensions = shader.extensions; - if (defined(extensions)) { - var binaryGltf = extensions.KHR_binary_glTF; - if (defined(binaryGltf)) { - shader.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; - delete extensions.KHR_binary_glTF; - } - if (Object.keys(extensions).length === 0) { - delete shader.extensions; - } - } - }); - ForEach.program(gltf, function(program) { - if (defined(program.vertexShader)) { - program.vertexShader = globalMapping.shaders[program.vertexShader]; - } - if (defined(program.fragmentShader)) { - program.fragmentShader = globalMapping.shaders[program.fragmentShader]; - } - }); - ForEach.technique(gltf, function(technique) { - if (defined(technique.program)) { - technique.program = globalMapping.programs[technique.program]; - } - ForEach.techniqueParameter(technique, function(parameter) { - if (defined(parameter.node)) { - parameter.node = globalMapping.nodes[parameter.node]; - } - var value = parameter.value; - if (defined(value)) { - if (Array.isArray(value)) { - if (value.length === 1) { - var textureId = value[0]; - if (typeof textureId === 'string') { - value[0] = globalMapping.textures[textureId]; + function createCommandLists(polylineCollection, frameState, commands, modelMatrix, renderPass) { + var context = frameState.context; + var commandList = frameState.commandList; + + var commandsLength = commands.length; + var commandIndex = 0; + var cloneBoundingSphere = true; + + var vertexArrays = polylineCollection._vertexArrays; + var debugShowBoundingVolume = polylineCollection.debugShowBoundingVolume; + + var batchTable = polylineCollection._batchTable; + var uniformCallback = batchTable.getUniformMapCallback(); + + var length = vertexArrays.length; + for ( var m = 0; m < length; ++m) { + var va = vertexArrays[m]; + var buckets = va.buckets; + var bucketLength = buckets.length; + + for ( var n = 0; n < bucketLength; ++n) { + var bucketLocator = buckets[n]; + + var offset = bucketLocator.offset; + var sp = renderPass ? bucketLocator.bucket.shaderProgram : bucketLocator.bucket.pickShaderProgram; + + var polylines = bucketLocator.bucket.polylines; + var polylineLength = polylines.length; + var currentId; + var currentMaterial; + var count = 0; + var command; + var uniformMap; + + for (var s = 0; s < polylineLength; ++s) { + var polyline = polylines[s]; + var mId = createMaterialId(polyline._material); + if (mId !== currentId) { + if (defined(currentId) && count > 0) { + var translucent = currentMaterial.isTranslucent(); + + if (commandIndex >= commandsLength) { + command = new DrawCommand({ + owner : polylineCollection + }); + commands.push(command); + } else { + command = commands[commandIndex]; } + + ++commandIndex; + + uniformMap = combine(uniformCallback(currentMaterial._uniforms), polylineCollection._uniformMap); + + command.boundingVolume = BoundingSphere.clone(boundingSphereScratch, command.boundingVolume); + command.modelMatrix = modelMatrix; + command.shaderProgram = sp; + command.vertexArray = va.va; + command.renderState = translucent ? polylineCollection._translucentRS : polylineCollection._opaqueRS; + command.pass = translucent ? Pass.TRANSLUCENT : Pass.OPAQUE; + command.debugShowBoundingVolume = renderPass ? debugShowBoundingVolume : false; + + command.uniformMap = uniformMap; + command.count = count; + command.offset = offset; + + offset += count; + count = 0; + cloneBoundingSphere = true; + + commandList.push(command); } + + currentMaterial = polyline._material; + currentMaterial.update(context); + currentId = mId; } - else if (typeof value === 'string') { - parameter.value = [globalMapping.textures[value]]; + + var locators = polyline._locatorBuckets; + var locatorLength = locators.length; + for (var t = 0; t < locatorLength; ++t) { + var locator = locators[t]; + if (locator.locator === bucketLocator) { + count += locator.count; + } } - } - }); - }); - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - if (defined(primitive.indices)) { - primitive.indices = globalMapping.accessors[primitive.indices]; - } - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { - primitive.attributes[semantic] = globalMapping.accessors[accessorId]; - }); - if (defined(primitive.material)) { - primitive.material = globalMapping.materials[primitive.material]; - } - }); - }); - ForEach.node(gltf, function(node) { - var children = node.children; - if (defined(children)) { - var childrenLength = children.length; - for (i = 0; i < childrenLength; i++) { - children[i] = globalMapping.nodes[children[i]]; - } - } - if (defined(node.meshes)) { - // Split out meshes on nodes - var meshes = node.meshes; - var meshesLength = meshes.length; - if (meshesLength > 0) { - node.mesh = globalMapping.meshes[meshes[0]]; - for (i = 1; i < meshesLength; i++) { - var meshNode = { - mesh: globalMapping.meshes[meshes[i]], - extras: { - _pipeline: {} - } - }; - var meshNodeId = addToArray(gltf.nodes, meshNode); - if (!defined(children)) { - children = []; - node.children = children; + + var boundingVolume; + if (frameState.mode === SceneMode.SCENE3D) { + boundingVolume = polyline._boundingVolumeWC; + } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { + boundingVolume = polyline._boundingVolume2D; + } else if (frameState.mode === SceneMode.SCENE2D) { + if (defined(polyline._boundingVolume2D)) { + boundingVolume = BoundingSphere.clone(polyline._boundingVolume2D, boundingSphereScratch2); + boundingVolume.center.x = 0.0; } - children.push(meshNodeId); + } else if (defined(polyline._boundingVolumeWC) && defined(polyline._boundingVolume2D)) { + boundingVolume = BoundingSphere.union(polyline._boundingVolumeWC, polyline._boundingVolume2D, boundingSphereScratch2); + } + + if (cloneBoundingSphere) { + cloneBoundingSphere = false; + BoundingSphere.clone(boundingVolume, boundingSphereScratch); + } else { + BoundingSphere.union(boundingVolume, boundingSphereScratch, boundingSphereScratch); } } - delete node.meshes; - } - if (defined(node.camera)) { - node.camera = globalMapping.cameras[node.camera]; - } - if (defined(node.skeletons)) { - // Assign skeletons to skins - var skeletons = node.skeletons; - var skeletonsLength = skeletons.length; - if ((skeletonsLength > 0) && defined(node.skin)) { - var skin = gltf.skins[globalMapping.skins[node.skin]]; - skin.skeleton = globalMapping.nodes[skeletons[0]]; - } - delete node.skeletons; - } - if (defined(node.skin)) { - node.skin = globalMapping.skins[node.skin]; - } - if (defined(node.jointName)) { - delete(node.jointName); - } - }); - ForEach.skin(gltf, function(skin) { - if (defined(skin.inverseBindMatrices)) { - skin.inverseBindMatrices = globalMapping.accessors[skin.inverseBindMatrices]; - } - var joints = []; - var jointNames = skin.jointNames; - if (defined(jointNames)) { - for (i = 0; i < jointNames.length; i++) { - joints[i] = jointNameToId[jointNames[i]]; + + if (defined(currentId) && count > 0) { + if (commandIndex >= commandsLength) { + command = new DrawCommand({ + owner : polylineCollection + }); + commands.push(command); + } else { + command = commands[commandIndex]; + } + + ++commandIndex; + + uniformMap = combine(uniformCallback(currentMaterial._uniforms), polylineCollection._uniformMap); + + command.boundingVolume = BoundingSphere.clone(boundingSphereScratch, command.boundingVolume); + command.modelMatrix = modelMatrix; + command.shaderProgram = sp; + command.vertexArray = va.va; + command.renderState = currentMaterial.isTranslucent() ? polylineCollection._translucentRS : polylineCollection._opaqueRS; + command.pass = currentMaterial.isTranslucent() ? Pass.TRANSLUCENT : Pass.OPAQUE; + command.debugShowBoundingVolume = renderPass ? debugShowBoundingVolume : false; + + command.uniformMap = uniformMap; + command.count = count; + command.offset = offset; + + cloneBoundingSphere = true; + + commandList.push(command); } - skin.joints = joints; - delete skin.jointNames; + + currentId = undefined; } - }); - ForEach.scene(gltf, function(scene) { - var sceneNodes = scene.nodes; - if (defined(sceneNodes)) { - var sceneNodesLength = sceneNodes.length; - for (i = 0; i < sceneNodesLength; i++) { - sceneNodes[i] = globalMapping.nodes[sceneNodes[i]]; - } + } + + commands.length = commandIndex; + } + + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see PolylineCollection#destroy + */ + PolylineCollection.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * polylines = polylines && polylines.destroy(); + * + * @see PolylineCollection#isDestroyed + */ + PolylineCollection.prototype.destroy = function() { + destroyVertexArrays(this); + releaseShaders(this); + destroyPolylines(this); + this._batchTable = this._batchTable && this._batchTable.destroy(); + return destroyObject(this); + }; + + function computeNewBuffersUsage(collection) { + var usageChanged = false; + var properties = collection._propertiesChanged; + var bufferUsage = collection._positionBufferUsage; + if (properties[POSITION_INDEX]) { + if (bufferUsage.bufferUsage !== BufferUsage.STREAM_DRAW) { + usageChanged = true; + bufferUsage.bufferUsage = BufferUsage.STREAM_DRAW; + bufferUsage.frameCount = 100; + } else { + bufferUsage.frameCount = 100; } - }); - ForEach.animation(gltf, function(animation) { - var samplerMapping = {}; - animation.samplers = objectToArray(animation.samplers, samplerMapping); - ForEach.animationSampler(animation, function(sampler) { - sampler.input = globalMapping.accessors[sampler.input]; - sampler.output = globalMapping.accessors[sampler.output]; - }); - var channels = animation.channels; - if (defined(channels)) { - var channelsLength = channels.length; - for (i = 0; i < channelsLength; i++) { - var channel = channels[i]; - channel.sampler = samplerMapping[channel.sampler]; - var target = channel.target; - if (defined(target)) { - target.node = globalMapping.nodes[target.id]; - delete target.id; - } - } + } else if (bufferUsage.bufferUsage !== BufferUsage.STATIC_DRAW) { + if (bufferUsage.frameCount === 0) { + usageChanged = true; + bufferUsage.bufferUsage = BufferUsage.STATIC_DRAW; + } else { + bufferUsage.frameCount--; } - }); - ForEach.material(gltf, function(material) { - if (defined(material.technique)) { - material.technique = globalMapping.techniques[material.technique]; + } + + return usageChanged; + } + + var emptyVertexBuffer = [0.0, 0.0, 0.0]; + + function createVertexArrays(collection, context, projection) { + collection._createVertexArray = false; + releaseShaders(collection); + destroyVertexArrays(collection); + sortPolylinesIntoBuckets(collection); + + //stores all of the individual indices arrays. + var totalIndices = [[]]; + var indices = totalIndices[0]; + + var batchTable = collection._batchTable; + var useHighlightColor = collection._useHighlightColor; + + //used to determine the vertexBuffer offset if the indicesArray goes over 64k. + //if it's the same polyline while it goes over 64k, the offset needs to backtrack componentsPerAttribute * componentDatatype bytes + //so that the polyline looks contiguous. + //if the polyline ends at the 64k mark, then the offset is just 64k * componentsPerAttribute * componentDatatype + var vertexBufferOffset = [0]; + var offset = 0; + var vertexArrayBuckets = [[]]; + var totalLength = 0; + var polylineBuckets = collection._polylineBuckets; + var x; + var bucket; + for (x in polylineBuckets) { + if (polylineBuckets.hasOwnProperty(x)) { + bucket = polylineBuckets[x]; + bucket.updateShader(context, batchTable, useHighlightColor); + totalLength += bucket.lengthOfPositions; } - ForEach.materialValue(material, function(value, name) { - if (Array.isArray(value)) { - if (value.length === 1) { - var textureId = value[0]; - if (typeof textureId === 'string') { - value[0] = globalMapping.textures[textureId]; + } + + if (totalLength > 0) { + var mode = collection._mode; + + var positionArray = new Float32Array(6 * totalLength * 3); + var texCoordExpandAndBatchIndexArray = new Float32Array(totalLength * 4); + var position3DArray; + + var positionIndex = 0; + var colorIndex = 0; + var texCoordExpandAndBatchIndexIndex = 0; + for (x in polylineBuckets) { + if (polylineBuckets.hasOwnProperty(x)) { + bucket = polylineBuckets[x]; + bucket.write(positionArray, texCoordExpandAndBatchIndexArray, positionIndex, colorIndex, texCoordExpandAndBatchIndexIndex, batchTable, context, projection); + + if (mode === SceneMode.MORPHING) { + if (!defined(position3DArray)) { + position3DArray = new Float32Array(6 * totalLength * 3); } + bucket.writeForMorph(position3DArray, positionIndex); } - } - else if (typeof value === 'string') { - material.values[name] = { - index : globalMapping.textures[value] - }; - } - }); - var extensions = material.extensions; - if (defined(extensions)) { - var materialsCommon = extensions.KHR_materials_common; - if (defined(materialsCommon)) { - ForEach.materialValue(materialsCommon, function(value, name) { - if (Array.isArray(value)) { - if (value.length === 1) { - var textureId = value[0]; - if (typeof textureId === 'string') { - value[0] = globalMapping.textures[textureId]; - } - } - } - else if (typeof value === 'string') { - materialsCommon.values[name] = { - index: globalMapping.textures[value] - }; - } - }); + + var bucketLength = bucket.lengthOfPositions; + positionIndex += 6 * bucketLength * 3; + colorIndex += bucketLength * 4; + texCoordExpandAndBatchIndexIndex += bucketLength * 4; + offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } } - }); - ForEach.image(gltf, function(image) { - var extensions = image.extensions; - if (defined(extensions)) { - var binaryGltf = extensions.KHR_binary_glTF; - if (defined(binaryGltf)) { - image.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; - image.mimeType = binaryGltf.mimeType; - delete extensions.KHR_binary_glTF; - } - if (Object.keys(extensions).length === 0) { - delete image.extensions; - } + + var positionBufferUsage = collection._positionBufferUsage.bufferUsage; + var texCoordExpandAndBatchIndexBufferUsage = BufferUsage.STATIC_DRAW; + + collection._positionBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : positionArray, + usage : positionBufferUsage + }); + var position3DBuffer; + if (defined(position3DArray)) { + position3DBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : position3DArray, + usage : positionBufferUsage + }); } - if (defined(image.extras)) { - var compressedImages = image.extras.compressedImage3DTiles; - for (var type in compressedImages) { - if (compressedImages.hasOwnProperty(type)) { - var compressedImage = compressedImages[type]; - var compressedExtensions = compressedImage.extensions; - if (defined(compressedExtensions)) { - var compressedBinaryGltf = compressedExtensions.KHR_binary_glTF; - if (defined(compressedBinaryGltf)) { - compressedImage.bufferView = globalMapping.bufferViews[compressedBinaryGltf.bufferView]; - compressedImage.mimeType = compressedBinaryGltf.mimeType; - delete compressedExtensions.KHR_binary_glTF; - } - if (Object.keys(compressedExtensions).length === 0) { - delete compressedImage.extensions; - } - } + collection._texCoordExpandAndBatchIndexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : texCoordExpandAndBatchIndexArray, + usage : texCoordExpandAndBatchIndexBufferUsage + }); + + var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; + var texCoordExpandAndBatchIndexSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + + var vbo = 0; + var numberOfIndicesArrays = totalIndices.length; + for ( var k = 0; k < numberOfIndicesArrays; ++k) { + indices = totalIndices[k]; + + if (indices.length > 0) { + var indicesArray = new Uint16Array(indices); + var indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : indicesArray, + usage : BufferUsage.STATIC_DRAW, + indexDatatype : IndexDatatype.UNSIGNED_SHORT + }); + + vbo += vertexBufferOffset[k]; + + var positionHighOffset = 6 * (k * (positionSizeInBytes * CesiumMath.SIXTY_FOUR_KILOBYTES) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) + var positionLowOffset = positionSizeInBytes + positionHighOffset; + var prevPositionHighOffset = positionSizeInBytes + positionLowOffset; + var prevPositionLowOffset = positionSizeInBytes + prevPositionHighOffset; + var nextPositionHighOffset = positionSizeInBytes + prevPositionLowOffset; + var nextPositionLowOffset = positionSizeInBytes + nextPositionHighOffset; + var vertexTexCoordExpandAndBatchIndexBufferOffset = k * (texCoordExpandAndBatchIndexSizeInBytes * CesiumMath.SIXTY_FOUR_KILOBYTES) - vbo * texCoordExpandAndBatchIndexSizeInBytes; + + var attributes = [{ + index : attributeLocations.position3DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.position3DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.position2DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.position2DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.prevPosition3DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.prevPosition3DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.prevPosition2DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.prevPosition2DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.nextPosition3DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.nextPosition3DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.nextPosition2DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.nextPosition2DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeLocations.texCoordExpandAndBatchIndex, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + vertexBuffer : collection._texCoordExpandAndBatchIndexBuffer, + offsetInBytes : vertexTexCoordExpandAndBatchIndexBufferOffset + }]; + + var buffer3D; + var bufferProperty3D; + var buffer2D; + var bufferProperty2D; + + if (mode === SceneMode.SCENE3D) { + buffer3D = collection._positionBuffer; + bufferProperty3D = 'vertexBuffer'; + buffer2D = emptyVertexBuffer; + bufferProperty2D = 'value'; + } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { + buffer3D = emptyVertexBuffer; + bufferProperty3D = 'value'; + buffer2D = collection._positionBuffer; + bufferProperty2D = 'vertexBuffer'; + } else { + buffer3D = position3DBuffer; + bufferProperty3D = 'vertexBuffer'; + buffer2D = collection._positionBuffer; + bufferProperty2D = 'vertexBuffer'; } + + attributes[0][bufferProperty3D] = buffer3D; + attributes[1][bufferProperty3D] = buffer3D; + attributes[2][bufferProperty2D] = buffer2D; + attributes[3][bufferProperty2D] = buffer2D; + attributes[4][bufferProperty3D] = buffer3D; + attributes[5][bufferProperty3D] = buffer3D; + attributes[6][bufferProperty2D] = buffer2D; + attributes[7][bufferProperty2D] = buffer2D; + attributes[8][bufferProperty3D] = buffer3D; + attributes[9][bufferProperty3D] = buffer3D; + attributes[10][bufferProperty2D] = buffer2D; + attributes[11][bufferProperty2D] = buffer2D; + + var va = new VertexArray({ + context : context, + attributes : attributes, + indexBuffer : indexBuffer + }); + collection._vertexArrays.push({ + va : va, + buckets : vertexArrayBuckets[k] + }); } } - }); - ForEach.texture(gltf, function(texture) { - if (defined(texture.sampler)) { - texture.sampler = globalMapping.samplers[texture.sampler]; - } - if (defined(texture.source)) { - texture.source = globalMapping.images[texture.source]; - } - }); + } } - function stripProfile(gltf) { - var asset = gltf.asset; - delete asset.profile; + function replacer(key, value) { + if (value instanceof Texture) { + return value.id; + } + + return value; } - var knownExtensions = { - CESIUM_RTC : true, - KHR_materials_common : true, - WEB3D_quantized_attributes : true - }; - function requireKnownExtensions(gltf) { - var extensionsUsed = gltf.extensionsUsed; - gltf.extensionsRequired = defaultValue(gltf.extensionsRequired, []); - if (defined(extensionsUsed)) { - var extensionsUsedLength = extensionsUsed.length; - for (var i = 0; i < extensionsUsedLength; i++) { - var extension = extensionsUsed[i]; - if (defined(knownExtensions[extension])) { - gltf.extensionsRequired.push(extension); - } - } + var scratchUniformArray = []; + function createMaterialId(material) { + var uniforms = Material._uniformList[material.type]; + var length = uniforms.length; + scratchUniformArray.length = 2.0 * length; + + var index = 0; + for (var i = 0; i < length; ++i) { + var uniform = uniforms[i]; + scratchUniformArray[index] = uniform; + scratchUniformArray[index + 1] = material._uniforms[uniform](); + index += 2; } - } - function removeBufferType(gltf) { - ForEach.buffer(gltf, function(buffer) { - delete buffer.type; - }); + return material.type + ':' + JSON.stringify(scratchUniformArray, replacer); } - function requireAttributeSetIndex(gltf) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { - if (semantic === 'TEXCOORD') { - primitive.attributes.TEXCOORD_0 = accessorId; - } else if (semantic === 'COLOR') { - primitive.attributes.COLOR_0 = accessorId; - } - }); - delete primitive.attributes.TEXCOORD; - delete primitive.attributes.COLOR; - }); - }); - ForEach.technique(gltf, function(technique) { - ForEach.techniqueParameter(technique, function(parameter) { - var semantic = parameter.semantic; - if (defined(semantic)) { - if (semantic === 'TEXCOORD') { - parameter.semantic = 'TEXCOORD_0'; - } else if (semantic === 'COLOR') { - parameter.semantic = 'COLOR_0'; - } + function sortPolylinesIntoBuckets(collection) { + var mode = collection._mode; + var modelMatrix = collection._modelMatrix; + + var polylineBuckets = collection._polylineBuckets = {}; + var polylines = collection._polylines; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + var p = polylines[i]; + if (p._actualPositions.length > 1) { + p.update(); + var material = p.material; + var value = polylineBuckets[material.type]; + if (!defined(value)) { + value = polylineBuckets[material.type] = new PolylineBucket(material, mode, modelMatrix); } - }); - }); + value.addPolyline(p); + } + } } - var knownSemantics = { - POSITION: true, - NORMAL: true, - TEXCOORD: true, - COLOR: true, - JOINT: true, - WEIGHT: true - }; - function underscoreApplicationSpecificSemantics(gltf) { - var mappedSemantics = {}; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - /* jshint unused:vars */ - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { - if (semantic.charAt(0) !== '_') { - var setIndex = semantic.search(/_[0-9]+/g); - var strippedSemantic = semantic; - if (setIndex >= 0) { - strippedSemantic = semantic.substring(0, setIndex); - } - if (!defined(knownSemantics[strippedSemantic])) { - var newSemantic = '_' + semantic; - mappedSemantics[semantic] = newSemantic; - } - } - }); - for (var semantic in mappedSemantics) { - if (mappedSemantics.hasOwnProperty(semantic)) { - var mappedSemantic = mappedSemantics[semantic]; - var accessorId = primitive.attributes[semantic]; - if (defined(accessorId)) { - delete primitive.attributes[semantic]; - primitive.attributes[mappedSemantic] = accessorId; - } - } - } - }); - }); - ForEach.technique(gltf, function(technique) { - ForEach.techniqueParameter(technique, function(parameter) { - var mappedSemantic = mappedSemantics[parameter.semantic]; - if (defined(mappedSemantic)) { - parameter.semantic = mappedSemantic; - } - }); - }); + function updateMode(collection, frameState) { + var mode = frameState.mode; + + if (collection._mode !== mode || (!Matrix4.equals(collection._modelMatrix, collection.modelMatrix))) { + collection._mode = mode; + collection._modelMatrix = Matrix4.clone(collection.modelMatrix); + collection._createVertexArray = true; + } } - function removeScissorFromTechniques(gltf) { - ForEach.technique(gltf, function(technique) { - var techniqueStates = technique.states; - if (defined(techniqueStates)) { - var techniqueFunctions = techniqueStates.functions; - if (defined(techniqueFunctions)) { - delete techniqueFunctions.scissor; - } - var enableStates = techniqueStates.enable; - if (defined(enableStates)) { - var scissorIndex = enableStates.indexOf(WebGLConstants.SCISSOR_TEST); - if (scissorIndex >= 0) { - enableStates.splice(scissorIndex, 1); - } + function removePolylines(collection) { + if (collection._polylinesRemoved) { + collection._polylinesRemoved = false; + + var polylines = []; + + var length = collection._polylines.length; + for ( var i = 0, j = 0; i < length; ++i) { + var polyline = collection._polylines[i]; + if (defined(polyline)) { + polyline._index = j++; + polylines.push(polyline); } } - }); + + collection._polylines = polylines; + } } - function clampTechniqueFunctionStates(gltf) { - ForEach.technique(gltf, function(technique) { - var techniqueStates = technique.states; - if (defined(techniqueStates)) { - var functions = techniqueStates.functions; - if (defined(functions)) { - var blendColor = functions.blendColor; - if (defined(blendColor)) { - for (var i = 0; i < 4; i++) { - blendColor[i] = CesiumMath.clamp(blendColor[i], 0.0, 1.0); - } - } - var depthRange = functions.depthRange; - if (defined(depthRange)) { - depthRange[1] = CesiumMath.clamp(depthRange[1], 0.0, 1.0); - depthRange[0] = CesiumMath.clamp(depthRange[0], 0.0, depthRange[1]); - } + function releaseShaders(collection) { + var polylines = collection._polylines; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + if (defined(polylines[i])) { + var bucket = polylines[i]._bucket; + if (defined(bucket)) { + bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.destroy(); } } - }); + } } - function clampCameraParameters(gltf) { - ForEach.camera(gltf, function(camera) { - var perspective = camera.perspective; - if (defined(perspective)) { - var aspectRatio = perspective.aspectRatio; - if (defined(aspectRatio) && aspectRatio === 0.0) { - delete perspective.aspectRatio; - } - var yfov = perspective.yfov; - if (defined(yfov) && yfov === 0.0) { - perspective.yfov = 1.0; - } - } - }); + function destroyVertexArrays(collection) { + var length = collection._vertexArrays.length; + for ( var t = 0; t < length; ++t) { + collection._vertexArrays[t].va.destroy(); + } + collection._vertexArrays.length = 0; } - function requireByteLength(gltf) { - ForEach.buffer(gltf, function(buffer) { - if (!defined(buffer.byteLength)) { - buffer.byteLength = buffer.extras._pipeline.source.length; - } - }); - ForEach.bufferView(gltf, function(bufferView) { - if (!defined(bufferView.byteLength)) { - var bufferViewBufferId = bufferView.buffer; - var bufferViewBuffer = gltf.buffers[bufferViewBufferId]; - bufferView.byteLength = bufferViewBuffer.byteLength; + PolylineCollection.prototype._updatePolyline = function(polyline, propertyChanged) { + this._polylinesUpdated = true; + this._polylinesToUpdate.push(polyline); + ++this._propertiesChanged[propertyChanged]; + }; + + function destroyPolylines(collection) { + var polylines = collection._polylines; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + if (defined(polylines[i])) { + polylines[i]._destroy(); } - }); + } } - function moveByteStrideToBufferView(gltf) { - var bufferViews = gltf.bufferViews; - var bufferViewsToDelete = {}; - ForEach.accessor(gltf, function(accessor) { - var oldBufferViewId = accessor.bufferView; - if (defined(oldBufferViewId)) { - if (!defined(bufferViewsToDelete[oldBufferViewId])) { - bufferViewsToDelete[oldBufferViewId] = true; - } - var bufferView = clone(bufferViews[oldBufferViewId]); - var accessorByteStride = (defined(accessor.byteStride) && accessor.byteStride !== 0) ? accessor.byteStride : getAccessorByteStride(gltf, accessor); - if (defined(accessorByteStride)) { - bufferView.byteStride = accessorByteStride; - if (bufferView.byteStride !== 0) { - bufferView.byteLength = accessor.count * accessorByteStride; - } - bufferView.byteOffset += accessor.byteOffset; - accessor.byteOffset = 0; - delete accessor.byteStride; - } - accessor.bufferView = addToArray(bufferViews, bufferView); - } - }); + function VertexArrayBucketLocator(count, offset, bucket) { + this.count = count; + this.offset = offset; + this.bucket = bucket; + } - var bufferViewShiftMap = {}; - var bufferViewRemovalCount = 0; - /* jshint unused:vars */ - ForEach.bufferView(gltf, function(bufferView, bufferViewId) { - if (defined(bufferViewsToDelete[bufferViewId])) { - bufferViewRemovalCount++; - } else { - bufferViewShiftMap[bufferViewId] = bufferViewId - bufferViewRemovalCount; - } - }); + function PolylineBucket(material, mode, modelMatrix) { + this.polylines = []; + this.lengthOfPositions = 0; + this.material = material; + this.shaderProgram = undefined; + this.pickShaderProgram = undefined; + this.mode = mode; + this.modelMatrix = modelMatrix; + } - var removedCount = 0; - for (var bufferViewId in bufferViewsToDelete) { - if (defined(bufferViewId)) { - var index = parseInt(bufferViewId) - removedCount; - bufferViews.splice(index, 1); - removedCount++; - } + PolylineBucket.prototype.addPolyline = function(p) { + var polylines = this.polylines; + polylines.push(p); + p._actualLength = this.getPolylinePositionsLength(p); + this.lengthOfPositions += p._actualLength; + p._bucket = this; + }; + + PolylineBucket.prototype.updateShader = function(context, batchTable, useHighlightColor) { + if (defined(this.shaderProgram)) { + return; } - ForEach.accessor(gltf, function(accessor) { - var accessorBufferView = accessor.bufferView; - if (defined(accessorBufferView)) { - accessor.bufferView = bufferViewShiftMap[accessorBufferView]; - } + var defines = ['DISTANCE_DISPLAY_CONDITION']; + if (useHighlightColor) { + defines.push('VECTOR_TILE'); + } + + // Check for use of v_polylineAngle in material shader + if (this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== -1) { + defines.push('POLYLINE_DASH'); + } + + var fs = new ShaderSource({ + defines : defines, + sources : [this.material.shaderSource, PolylineFS] }); - ForEach.shader(gltf, function(shader) { - var shaderBufferView = shader.bufferView; - if (defined(shaderBufferView)) { - shader.bufferView = bufferViewShiftMap[shaderBufferView]; - } + var vsSource = batchTable.getVertexShaderCallback()(PolylineVS); + var vs = new ShaderSource({ + defines : defines, + sources : [PolylineCommon, vsSource] }); - ForEach.image(gltf, function(image) { - var imageBufferView = image.bufferView; - if (defined(imageBufferView)) { - image.bufferView = bufferViewShiftMap[imageBufferView]; - } - if (defined(image.extras)) { - var compressedImages = image.extras.compressedImage3DTiles; - for (var type in compressedImages) { - if (compressedImages.hasOwnProperty(type)) { - var compressedImage = compressedImages[type]; - var compressedImageBufferView = compressedImage.bufferView; - if (defined(compressedImageBufferView)) { - compressedImage.bufferView = bufferViewShiftMap[compressedImageBufferView]; - } - } - } - } + var fsPick = new ShaderSource({ + sources : fs.sources, + pickColorQualifier : 'varying' }); - } - function stripTechniqueAttributeValues(gltf) { - ForEach.technique(gltf, function(technique) { - ForEach.techniqueAttribute(technique, function(attribute) { - var parameter = technique.parameters[attribute]; - if (defined(parameter.value)) { - delete parameter.value; - } - }); + this.shaderProgram = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations }); - } - function stripTechniqueParameterCount(gltf) { - ForEach.technique(gltf, function(technique) { - ForEach.techniqueParameter(technique, function(parameter) { - if (defined(parameter.count)) { - var semantic = parameter.semantic; - if (!defined(semantic) || (semantic !== 'JOINTMATRIX' && semantic.indexOf('_') !== 0)) { - delete parameter.count; - } - } - }); + this.pickShaderProgram = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fsPick, + attributeLocations : attributeLocations }); - } + }; - function addKHRTechniqueExtension(gltf) { - var techniques = gltf.techniques; - if (defined(techniques) && techniques.length > 0) { - addExtensionsRequired(gltf, 'KHR_technique_webgl'); - } + function intersectsIDL(polyline) { + return Cartesian3.dot(Cartesian3.UNIT_X, polyline._boundingVolume.center) < 0 || + polyline._boundingVolume.intersectPlane(Plane.ORIGIN_ZX_PLANE) === Intersect.INTERSECTING; } - function glTF10to20(gltf) { - if (!defined(gltf.asset)) { - gltf.asset = {}; + PolylineBucket.prototype.getPolylinePositionsLength = function(polyline) { + var length; + if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { + length = polyline._actualPositions.length; + return length * 4.0 - 4.0; } - var asset = gltf.asset; - asset.version = '2.0'; - // material.instanceTechnique properties should be directly on the material. instanceTechnique is a gltf 0.8 property but is seen in some 1.0 models. - updateInstanceTechniques(gltf); - // animation.samplers now refers directly to accessors and animation.parameters should be removed - removeAnimationSamplersIndirection(gltf); - // top-level objects are now arrays referenced by index instead of id - objectsToArrays(gltf); - // asset.profile no longer exists - stripProfile(gltf); - // move known extensions from extensionsUsed to extensionsRequired - requireKnownExtensions(gltf); - // bufferView.byteLength and buffer.byteLength are required - requireByteLength(gltf); - // byteStride moved from accessor to bufferView - moveByteStrideToBufferView(gltf); - // buffer.type is unnecessary and should be removed - removeBufferType(gltf); - // TEXCOORD and COLOR attributes must be written with a set index (TEXCOORD_#) - requireAttributeSetIndex(gltf); - // Add underscores to application-specific parameters - underscoreApplicationSpecificSemantics(gltf); - // remove scissor from techniques - removeScissorFromTechniques(gltf); - // clamp technique function states to min/max - clampTechniqueFunctionStates(gltf); - // clamp camera parameters - clampCameraParameters(gltf); - // a technique parameter specified as an attribute cannot have a value - stripTechniqueAttributeValues(gltf); - // only techniques with a JOINTMATRIX or application specific semantic may have a defined count property - stripTechniqueParameterCount(gltf); - // add KHR_technique_webgl extension - addKHRTechniqueExtension(gltf); - } - return updateVersion; -}); - -define('ThirdParty/GltfPipeline/parseBinaryGltf',[ - './addPipelineExtras', - './removeExtensionsUsed', - './updateVersion', - '../../Core/ComponentDatatype', - '../../Core/defined', - '../../Core/DeveloperError', - '../../Core/getMagic', - '../../Core/getStringFromTypedArray', - '../../Core/WebGLConstants' - ], function( - addPipelineExtras, - removeExtensionsUsed, - updateVersion, - ComponentDatatype, - defined, - DeveloperError, - getMagic, - getStringFromTypedArray, - WebGLConstants) { - 'use strict'; - /** - * Parses a binary glTF buffer into glTF JSON. - * - * @param {Uint8Array} data The binary glTF data to parse. - * @returns {Object} The parsed binary glTF. - */ - function parseBinaryGltf(data) { - var headerView = ComponentDatatype.createArrayBufferView(WebGLConstants.INT, data.buffer, data.byteOffset, 5); - - // Check that the magic string is present - var magic = getMagic(data); - if (magic !== 'glTF') { - throw new DeveloperError('File is not valid binary glTF'); + var count = 0; + var segmentLengths = polyline._segments.lengths; + length = segmentLengths.length; + for (var i = 0; i < length; ++i) { + count += segmentLengths[i] * 4.0 - 4.0; } - // Check that the version is 1 or 2 - var version = headerView[1]; - if (version !== 1 && version !== 2) { - throw new DeveloperError('Binary glTF version is not 1 or 2'); - } + return count; + }; - var gltf; - var buffers; - var length; - // Load binary glTF version 1 - if (version === 1) { - length = headerView[2]; - var contentLength = headerView[3]; - var contentFormat = headerView[4]; + var scratchWritePosition = new Cartesian3(); + var scratchWritePrevPosition = new Cartesian3(); + var scratchWriteNextPosition = new Cartesian3(); + var scratchWriteVector = new Cartesian3(); + var scratchPickColorCartesian = new Cartesian4(); + var scratchWidthShowCartesian = new Cartesian2(); - // Check that the content format is 0, indicating that it is JSON - if (contentFormat !== 0) { - throw new DeveloperError('Binary glTF scene format is not JSON'); - } + PolylineBucket.prototype.write = function(positionArray, texCoordExpandAndBatchIndexArray, positionIndex, colorIndex, texCoordExpandAndBatchIndexIndex, batchTable, context, projection) { + var mode = this.mode; + var maxLon = projection.ellipsoid.maximumRadius * CesiumMath.PI; - var jsonStart = 20; - var binaryStart = jsonStart + contentLength; + var polylines = this.polylines; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + var polyline = polylines[i]; + var width = polyline.width; + var show = polyline.show && width > 0.0; + var polylineBatchIndex = polyline._index; + var segments = this.getSegments(polyline, projection); + var positions = segments.positions; + var lengths = segments.lengths; + var positionsLength = positions.length; - var contentString = getStringFromTypedArray(data, jsonStart, contentLength); - gltf = JSON.parse(contentString); + var pickColor = polyline.getPickId(context).color; - var binaryData = data.subarray(binaryStart, length); + var segmentIndex = 0; + var count = 0; + var position; - buffers = gltf.buffers; - if (defined(buffers) && Object.keys(buffers).length > 0) { - var binaryGltfBuffer = buffers.binary_glTF; - // In some older models, the binary glTF buffer is named KHR_binary_glTF - if (!defined(binaryGltfBuffer)) { - binaryGltfBuffer = buffers.KHR_binary_glTF; - } - if (defined(binaryGltfBuffer)) { - binaryGltfBuffer.extras = { - _pipeline: { - source: binaryData - } - }; + for ( var j = 0; j < positionsLength; ++j) { + if (j === 0) { + if (polyline._loop) { + position = positions[positionsLength - 2]; + } else { + position = scratchWriteVector; + Cartesian3.subtract(positions[0], positions[1], position); + Cartesian3.add(positions[0], position, position); + } + } else { + position = positions[j - 1]; } - } - // Update to glTF 2.0 - updateVersion(gltf); - // Remove the KHR_binary_glTF extension - removeExtensionsUsed(gltf, 'KHR_binary_glTF'); - addPipelineExtras(gltf); - } - // Load binary glTF version 2 - if (version === 2) { - length = headerView[2]; - var byteOffset = 12; - var binaryBuffer; - while (byteOffset < length) { - var chunkHeaderView = ComponentDatatype.createArrayBufferView(WebGLConstants.INT, data.buffer, data.byteOffset + byteOffset, 2); - var chunkLength = chunkHeaderView[0]; - var chunkType = chunkHeaderView[1]; - byteOffset += 8; - var chunkBuffer = data.subarray(byteOffset, byteOffset + chunkLength); - byteOffset += chunkLength; - // Load JSON chunk - if (chunkType === 0x4E4F534A) { - var jsonString = getStringFromTypedArray(chunkBuffer); - gltf = JSON.parse(jsonString); - addPipelineExtras(gltf); - } - // Load Binary chunk - else if (chunkType === 0x004E4942) { - binaryBuffer = chunkBuffer; + Cartesian3.clone(position, scratchWritePrevPosition); + Cartesian3.clone(positions[j], scratchWritePosition); + + if (j === positionsLength - 1) { + if (polyline._loop) { + position = positions[1]; + } else { + position = scratchWriteVector; + Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], position); + Cartesian3.add(positions[positionsLength - 1], position, position); + } + } else { + position = positions[j + 1]; } - } - if (defined(gltf) && defined(binaryBuffer)) { - buffers = gltf.buffers; - if (defined(buffers) && buffers.length > 0) { - var buffer = buffers[0]; - buffer.extras._pipeline.source = binaryBuffer; + + Cartesian3.clone(position, scratchWriteNextPosition); + + var segmentLength = lengths[segmentIndex]; + if (j === count + segmentLength) { + count += segmentLength; + ++segmentIndex; } - } - } - return gltf; - } - return parseBinaryGltf; -}); -define('ThirdParty/GltfPipeline/techniqueParameterForSemantic',[ - '../../Core/defined' - ], function( - defined) { - 'use strict'; + var segmentStart = j - count === 0; + var segmentEnd = j === count + lengths[segmentIndex] - 1; - /** - * Retrieves the technique parameter that has a matching semantic. - * - * @param {Object} technique A javascript object containing a glTF technique. - * @param {String} semantic The search string for semantics. - * @returns {String} The technique parameter with matching semantic. - * - * @private - */ - function techniqueParameterForSemantic(technique, semantic) { - var parameters = technique.parameters; - for (var parameterName in parameters) { - if (parameters.hasOwnProperty(parameterName)) { - var parameter = parameters[parameterName]; - var parameterSemantic = parameter.semantic; - if (defined(parameterSemantic) && parameterSemantic === semantic) { - return parameterName; + if (mode === SceneMode.SCENE2D) { + scratchWritePrevPosition.z = 0.0; + scratchWritePosition.z = 0.0; + scratchWriteNextPosition.z = 0.0; } - } - } - } - return techniqueParameterForSemantic; -}); -define('ThirdParty/GltfPipeline/webGLConstantToGlslType',[ - '../../Core/WebGLConstants' - ], function( - WebGLConstants) { - 'use strict'; + if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { + if ((segmentStart || segmentEnd) && maxLon - Math.abs(scratchWritePosition.x) < 1.0) { + if ((scratchWritePosition.x < 0.0 && scratchWritePrevPosition.x > 0.0) || + (scratchWritePosition.x > 0.0 && scratchWritePrevPosition.x < 0.0)) { + Cartesian3.clone(scratchWritePosition, scratchWritePrevPosition); + } - function webGLConstantToGlslType(webGLValue) { - switch (webGLValue) { - case WebGLConstants.FLOAT: - return 'float'; - case WebGLConstants.FLOAT_VEC2: - return 'vec2'; - case WebGLConstants.FLOAT_VEC3: - return 'vec3'; - case WebGLConstants.FLOAT_VEC4: - return 'vec4'; - case WebGLConstants.FLOAT_MAT2: - return 'mat2'; - case WebGLConstants.FLOAT_MAT3: - return 'mat3'; - case WebGLConstants.FLOAT_MAT4: - return 'mat4'; - case WebGLConstants.SAMPLER_2D: - return 'sampler2D'; - case WebGLConstants.BOOL: - return 'bool'; - } - } - return webGLConstantToGlslType; -}); + if ((scratchWritePosition.x < 0.0 && scratchWriteNextPosition.x > 0.0) || + (scratchWritePosition.x > 0.0 && scratchWriteNextPosition.x < 0.0)) { + Cartesian3.clone(scratchWritePosition, scratchWriteNextPosition); + } + } + } -define('ThirdParty/GltfPipeline/glslTypeToWebGLConstant',[ - '../../Core/WebGLConstants' - ], function( - WebGLConstants) { - 'use strict'; + var startK = (segmentStart) ? 2 : 0; + var endK = (segmentEnd) ? 2 : 4; - function glslTypeToWebGLConstant(glslType) { - switch (glslType) { - case 'float': - return WebGLConstants.FLOAT; - case 'vec2': - return WebGLConstants.FLOAT_VEC2; - case 'vec3': - return WebGLConstants.FLOAT_VEC3; - case 'vec4': - return WebGLConstants.FLOAT_VEC4; - case 'mat2': - return WebGLConstants.FLOAT_MAT2; - case 'mat3': - return WebGLConstants.FLOAT_MAT3; - case 'mat4': - return WebGLConstants.FLOAT_MAT4; - case 'sampler2D': - return WebGLConstants.SAMPLER_2D; - } - } - return glslTypeToWebGLConstant; -}); + for (var k = startK; k < endK; ++k) { + EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); + EncodedCartesian3.writeElements(scratchWritePrevPosition, positionArray, positionIndex + 6); + EncodedCartesian3.writeElements(scratchWriteNextPosition, positionArray, positionIndex + 12); -define('ThirdParty/GltfPipeline/processModelMaterialsCommon',[ - './addToArray', - './ForEach', - './numberOfComponentsForType', - './techniqueParameterForSemantic', - './webGLConstantToGlslType', - './glslTypeToWebGLConstant', - '../../Core/clone', - '../../Core/defined', - '../../Core/defaultValue', - '../../Core/WebGLConstants' - ], function( - addToArray, - ForEach, - numberOfComponentsForType, - techniqueParameterForSemantic, - webGLConstantToGlslType, - glslTypeToWebGLConstant, - clone, - defined, - defaultValue, - WebGLConstants) { - 'use strict'; + var direction = (k - 2 < 0) ? -1.0 : 1.0; + texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex] = j / (positionsLength - 1); // s tex coord + texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex + 1] = 2 * (k % 2) - 1; // expand direction + texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex + 2] = direction; + texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex + 3] = polylineBatchIndex; + + positionIndex += 6 * 3; + texCoordExpandAndBatchIndexIndex += 4; + } + } - /** - * @private - */ - function processModelMaterialsCommon(gltf, options) { - options = defaultValue(options, {}); + var colorCartesian = scratchPickColorCartesian; + colorCartesian.x = Color.floatToByte(pickColor.red); + colorCartesian.y = Color.floatToByte(pickColor.green); + colorCartesian.z = Color.floatToByte(pickColor.blue); + colorCartesian.w = Color.floatToByte(pickColor.alpha); - if (!defined(gltf)) { - return undefined; - } + var widthShowCartesian = scratchWidthShowCartesian; + widthShowCartesian.x = width; + widthShowCartesian.y = show ? 1.0 : 0.0; - var hasExtension = false; - var extensionsRequired = gltf.extensionsRequired; - var extensionsUsed = gltf.extensionsUsed; - if (defined(extensionsUsed)) { - var index = extensionsUsed.indexOf('KHR_materials_common'); - if (index >= 0) { - extensionsUsed.splice(index, 1); - hasExtension = true; + var boundingSphere = mode === SceneMode.SCENE2D ? polyline._boundingVolume2D : polyline._boundingVolumeWC; + var encodedCenter = EncodedCartesian3.fromCartesian(boundingSphere.center, scratchUpdatePolylineEncodedCartesian); + var high = encodedCenter.high; + var low = Cartesian4.fromElements(encodedCenter.low.x, encodedCenter.low.y, encodedCenter.low.z, boundingSphere.radius, scratchUpdatePolylineCartesian4); + + var nearFarCartesian = scratchNearFarCartesian2; + nearFarCartesian.x = 0.0; + nearFarCartesian.y = Number.MAX_VALUE; + + var distanceDisplayCondition = polyline.distanceDisplayCondition; + if (defined(distanceDisplayCondition)) { + nearFarCartesian.x = distanceDisplayCondition.near; + nearFarCartesian.y = distanceDisplayCondition.far; } - if (defined(extensionsRequired)) { - index = extensionsRequired.indexOf('KHR_materials_common'); - if (index >= 0) { - extensionsRequired.splice(index, 1); - } + + batchTable.setBatchedAttribute(polylineBatchIndex, 0, widthShowCartesian); + batchTable.setBatchedAttribute(polylineBatchIndex, 1, colorCartesian); + + if (batchTable.attributes.length > 2) { + batchTable.setBatchedAttribute(polylineBatchIndex, 2, high); + batchTable.setBatchedAttribute(polylineBatchIndex, 3, low); + batchTable.setBatchedAttribute(polylineBatchIndex, 4, nearFarCartesian); } } + }; - if (hasExtension) { - if (!defined(gltf.programs)) { - gltf.programs = []; - } - if (!defined(gltf.shaders)) { - gltf.shaders = []; - } - if (!defined(gltf.techniques)) { - gltf.techniques = []; - } - lightDefaults(gltf); + var morphPositionScratch = new Cartesian3(); + var morphPrevPositionScratch = new Cartesian3(); + var morphNextPositionScratch = new Cartesian3(); + var morphVectorScratch = new Cartesian3(); - var lightParameters = generateLightParameters(gltf); + PolylineBucket.prototype.writeForMorph = function(positionArray, positionIndex) { + var modelMatrix = this.modelMatrix; + var polylines = this.polylines; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + var polyline = polylines[i]; + var positions = polyline._segments.positions; + var lengths = polyline._segments.lengths; + var positionsLength = positions.length; - // Pre-processing to assign skinning info and address incompatibilities - splitIncompatibleSkins(gltf); + var segmentIndex = 0; + var count = 0; - var techniques = {}; - ForEach.material(gltf, function(material) { - if (defined(material.extensions) && defined(material.extensions.KHR_materials_common)) { - var khrMaterialsCommon = material.extensions.KHR_materials_common; - var techniqueKey = getTechniqueKey(khrMaterialsCommon); - var technique = techniques[techniqueKey]; - if (!defined(technique)) { - technique = generateTechnique(gltf, khrMaterialsCommon, lightParameters, options); - techniques[techniqueKey] = technique; + for ( var j = 0; j < positionsLength; ++j) { + var prevPosition; + if (j === 0) { + if (polyline._loop) { + prevPosition = positions[positionsLength - 2]; + } else { + prevPosition = morphVectorScratch; + Cartesian3.subtract(positions[0], positions[1], prevPosition); + Cartesian3.add(positions[0], prevPosition, prevPosition); } + } else { + prevPosition = positions[j - 1]; + } - // Take advantage of the fact that we generate techniques that use the - // same parameter names as the extension values. - material.values = {}; - var values = khrMaterialsCommon.values; - for (var valueName in values) { - if (values.hasOwnProperty(valueName)) { - var value = values[valueName]; - material.values[valueName] = value; - } - } + prevPosition = Matrix4.multiplyByPoint(modelMatrix, prevPosition, morphPrevPositionScratch); - material.technique = technique; + var position = Matrix4.multiplyByPoint(modelMatrix, positions[j], morphPositionScratch); - delete material.extensions.KHR_materials_common; - if (Object.keys(material.extensions).length === 0) { - delete material.extensions; + var nextPosition; + if (j === positionsLength - 1) { + if (polyline._loop) { + nextPosition = positions[1]; + } else { + nextPosition = morphVectorScratch; + Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], nextPosition); + Cartesian3.add(positions[positionsLength - 1], nextPosition, nextPosition); } + } else { + nextPosition = positions[j + 1]; } - }); - if (defined(gltf.extensions)) { - delete gltf.extensions.KHR_materials_common; - if (Object.keys(gltf.extensions).length === 0) { - delete gltf.extensions; + nextPosition = Matrix4.multiplyByPoint(modelMatrix, nextPosition, morphNextPositionScratch); + + var segmentLength = lengths[segmentIndex]; + if (j === count + segmentLength) { + count += segmentLength; + ++segmentIndex; } - } - // If any primitives have semantics that aren't declared in the generated - // shaders, we want to preserve them. - ensureSemanticExistence(gltf); - } + var segmentStart = j - count === 0; + var segmentEnd = j === count + lengths[segmentIndex] - 1; - return gltf; - } + var startK = (segmentStart) ? 2 : 0; + var endK = (segmentEnd) ? 2 : 4; - function generateLightParameters(gltf) { - var result = {}; + for (var k = startK; k < endK; ++k) { + EncodedCartesian3.writeElements(position, positionArray, positionIndex); + EncodedCartesian3.writeElements(prevPosition, positionArray, positionIndex + 6); + EncodedCartesian3.writeElements(nextPosition, positionArray, positionIndex + 12); - var lights; - if (defined(gltf.extensions) && defined(gltf.extensions.KHR_materials_common)) { - lights = gltf.extensions.KHR_materials_common.lights; + positionIndex += 6 * 3; + } + } } + }; - if (defined(lights)) { - // Figure out which node references the light - var nodes = gltf.nodes; - for (var nodeName in nodes) { - if (nodes.hasOwnProperty(nodeName)) { - var node = nodes[nodeName]; - if (defined(node.extensions) && defined(node.extensions.KHR_materials_common)) { - var nodeLightId = node.extensions.KHR_materials_common.light; - if (defined(nodeLightId) && defined(lights[nodeLightId])) { - lights[nodeLightId].node = nodeName; - } - delete node.extensions.KHR_materials_common; - } + var scratchSegmentLengths = new Array(1); + + PolylineBucket.prototype.updateIndices = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { + var vaCount = vertexArrayBuckets.length - 1; + var bucketLocator = new VertexArrayBucketLocator(0, offset, this); + vertexArrayBuckets[vaCount].push(bucketLocator); + var count = 0; + var indices = totalIndices[totalIndices.length - 1]; + var indicesCount = 0; + if (indices.length > 0) { + indicesCount = indices[indices.length - 1] + 1; + } + var polylines = this.polylines; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + + var polyline = polylines[i]; + polyline._locatorBuckets = []; + + var segments; + if (this.mode === SceneMode.SCENE3D) { + segments = scratchSegmentLengths; + var positionsLength = polyline._actualPositions.length; + if (positionsLength > 0) { + segments[0] = positionsLength; + } else { + continue; } + } else { + segments = polyline._segments.lengths; } - // Add light parameters to result - var lightCount = 0; - for (var lightName in lights) { - if (lights.hasOwnProperty(lightName)) { - var light = lights[lightName]; - var lightType = light.type; - if ((lightType !== 'ambient') && !defined(light.node)) { - delete lights[lightName]; - continue; - } - var lightBaseName = 'light' + lightCount.toString(); - light.baseName = lightBaseName; - switch (lightType) { - case 'ambient': - var ambient = light.ambient; - result[lightBaseName + 'Color'] = { - type: WebGLConstants.FLOAT_VEC3, - value: ambient.color - }; - break; - case 'directional': - var directional = light.directional; - result[lightBaseName + 'Color'] = { - type: WebGLConstants.FLOAT_VEC3, - value: directional.color - }; - if (defined(light.node)) { - result[lightBaseName + 'Transform'] = { - node: light.node, - semantic: 'MODELVIEW', - type: WebGLConstants.FLOAT_MAT4 - }; - } - break; - case 'point': - var point = light.point; - result[lightBaseName + 'Color'] = { - type: WebGLConstants.FLOAT_VEC3, - value: point.color - }; - if (defined(light.node)) { - result[lightBaseName + 'Transform'] = { - node: light.node, - semantic: 'MODELVIEW', - type: WebGLConstants.FLOAT_MAT4 - }; - } - result[lightBaseName + 'Attenuation'] = { - type: WebGLConstants.FLOAT_VEC3, - value: [point.constantAttenuation, point.linearAttenuation, point.quadraticAttenuation] - }; - break; - case 'spot': - var spot = light.spot; - result[lightBaseName + 'Color'] = { - type: WebGLConstants.FLOAT_VEC3, - value: spot.color - }; - if (defined(light.node)) { - result[lightBaseName + 'Transform'] = { - node: light.node, - semantic: 'MODELVIEW', - type: WebGLConstants.FLOAT_MAT4 - }; - result[lightBaseName + 'InverseTransform'] = { - node: light.node, - semantic: 'MODELVIEWINVERSE', - type: WebGLConstants.FLOAT_MAT4, - useInFragment: true - }; - } - result[lightBaseName + 'Attenuation'] = { - type: WebGLConstants.FLOAT_VEC3, - value: [spot.constantAttenuation, spot.linearAttenuation, spot.quadraticAttenuation] - }; + var numberOfSegments = segments.length; + if (numberOfSegments > 0) { + var segmentIndexCount = 0; + for ( var j = 0; j < numberOfSegments; ++j) { + var segmentLength = segments[j] - 1.0; + for ( var k = 0; k < segmentLength; ++k) { + if (indicesCount + 4 > CesiumMath.SIXTY_FOUR_KILOBYTES) { + polyline._locatorBuckets.push({ + locator : bucketLocator, + count : segmentIndexCount + }); + segmentIndexCount = 0; + vertexBufferOffset.push(4); + indices = []; + totalIndices.push(indices); + indicesCount = 0; + bucketLocator.count = count; + count = 0; + offset = 0; + bucketLocator = new VertexArrayBucketLocator(0, 0, this); + vertexArrayBuckets[++vaCount] = [bucketLocator]; + } - result[lightBaseName + 'FallOff'] = { - type: WebGLConstants.FLOAT_VEC2, - value: [spot.fallOffAngle, spot.fallOffExponent] - }; - break; + indices.push(indicesCount, indicesCount + 2, indicesCount + 1); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + + segmentIndexCount += 6; + count += 6; + offset += 6; + indicesCount += 4; } - ++lightCount; + } + + polyline._locatorBuckets.push({ + locator : bucketLocator, + count : segmentIndexCount + }); + + if (indicesCount + 4 > CesiumMath.SIXTY_FOUR_KILOBYTES) { + vertexBufferOffset.push(0); + indices = []; + totalIndices.push(indices); + indicesCount = 0; + bucketLocator.count = count; + offset = 0; + count = 0; + bucketLocator = new VertexArrayBucketLocator(0, 0, this); + vertexArrayBuckets[++vaCount] = [bucketLocator]; } } + polyline._clean(); } + bucketLocator.count = count; + return offset; + }; - return result; - } + PolylineBucket.prototype.getPolylineStartIndex = function(polyline) { + var polylines = this.polylines; + var positionIndex = 0; + var length = polylines.length; + for ( var i = 0; i < length; ++i) { + var p = polylines[i]; + if (p === polyline) { + break; + } + positionIndex += p._actualLength; + } + return positionIndex; + }; - function generateTechnique(gltf, khrMaterialsCommon, lightParameters, options) { - var optimizeForCesium = defaultValue(options.optimizeForCesium, false); - var hasCesiumRTCExtension = defined(gltf.extensions) && defined(gltf.extensions.CESIUM_RTC); - var addBatchIdToGeneratedShaders = defaultValue(options.addBatchIdToGeneratedShaders, false); + var scratchSegments = { + positions : undefined, + lengths : undefined + }; + var scratchLengths = new Array(1); + var pscratch = new Cartesian3(); + var scratchCartographic = new Cartographic(); - var techniques = gltf.techniques; - var shaders = gltf.shaders; - var programs = gltf.programs; - var lightingModel = khrMaterialsCommon.technique.toUpperCase(); - var lights; - if (defined(gltf.extensions) && defined(gltf.extensions.KHR_materials_common)) { - lights = gltf.extensions.KHR_materials_common.lights; + PolylineBucket.prototype.getSegments = function(polyline, projection) { + var positions = polyline._actualPositions; + + if (this.mode === SceneMode.SCENE3D) { + scratchLengths[0] = positions.length; + scratchSegments.positions = positions; + scratchSegments.lengths = scratchLengths; + return scratchSegments; } - var parameterValues = khrMaterialsCommon.values; - if (defined(khrMaterialsCommon.transparent)) { - parameterValues.transparent = khrMaterialsCommon.transparent; + + if (intersectsIDL(polyline)) { + positions = polyline._segments.positions; } - if (defined(khrMaterialsCommon.doubleSided)) { - parameterValues.doubleSided = khrMaterialsCommon.doubleSided; + + var ellipsoid = projection.ellipsoid; + var newPositions = []; + var modelMatrix = this.modelMatrix; + var length = positions.length; + var position; + var p = pscratch; + + for ( var n = 0; n < length; ++n) { + position = positions[n]; + p = Matrix4.multiplyByPoint(modelMatrix, position, p); + newPositions.push(projection.project(ellipsoid.cartesianToCartographic(p, scratchCartographic))); } - var jointCount = defaultValue(khrMaterialsCommon.jointCount, 0); - var hasSkinning = jointCount > 0; - var skinningInfo = {}; - if (hasSkinning) { - skinningInfo = khrMaterialsCommon.extras._pipeline.skinning; + if (newPositions.length > 0) { + polyline._boundingVolume2D = BoundingSphere.fromPoints(newPositions, polyline._boundingVolume2D); + var center2D = polyline._boundingVolume2D.center; + polyline._boundingVolume2D.center = new Cartesian3(center2D.z, center2D.x, center2D.y); } - var vertexShader = 'precision highp float;\n'; - var fragmentShader = 'precision highp float;\n'; + scratchSegments.positions = newPositions; + scratchSegments.lengths = polyline._segments.lengths; + return scratchSegments; + }; - var hasNormals = (lightingModel !== 'CONSTANT'); + var scratchPositionsArray; - // Add techniques - var techniqueParameters = { - // Add matrices - modelViewMatrix: { - semantic: hasCesiumRTCExtension ? 'CESIUM_RTC_MODELVIEW' : 'MODELVIEW', - type: WebGLConstants.FLOAT_MAT4 - }, - projectionMatrix: { - semantic: 'PROJECTION', - type: WebGLConstants.FLOAT_MAT4 - } - }; + PolylineBucket.prototype.writeUpdate = function(index, polyline, positionBuffer, projection) { + var mode = this.mode; + var maxLon = projection.ellipsoid.maximumRadius * CesiumMath.PI; - if (hasNormals) { - techniqueParameters.normalMatrix = { - semantic: 'MODELVIEWINVERSETRANSPOSE', - type: WebGLConstants.FLOAT_MAT3 - }; - } + var positionsLength = polyline._actualLength; + if (positionsLength) { + index += this.getPolylineStartIndex(polyline); - if (hasSkinning) { - techniqueParameters.jointMatrix = { - count: jointCount, - semantic: 'JOINTMATRIX', - type: WebGLConstants.FLOAT_MAT4 - }; - } + var positionArray = scratchPositionsArray; + var positionsArrayLength = 6 * positionsLength * 3; - // Add material parameters - var lowerCase; - var hasTexCoords = false; - for (var name in parameterValues) { - //generate shader parameters for KHR_materials_common attributes - //(including a check, because some boolean flags should not be used as shader parameters) - if (parameterValues.hasOwnProperty(name) && (name !== 'transparent') && (name !== 'doubleSided')) { - var valType = getKHRMaterialsCommonValueType(name, parameterValues[name]); - lowerCase = name.toLowerCase(); - if (!hasTexCoords && (valType === WebGLConstants.SAMPLER_2D)) { - hasTexCoords = true; - } - techniqueParameters[lowerCase] = { - type: valType - }; + if (!defined(positionArray) || positionArray.length < positionsArrayLength) { + positionArray = scratchPositionsArray = new Float32Array(positionsArrayLength); + } else if (positionArray.length > positionsArrayLength) { + positionArray = new Float32Array(positionArray.buffer, 0, positionsArrayLength); } - } - // Give the diffuse uniform a semantic to support color replacement in 3D Tiles - if (defined(techniqueParameters.diffuse) && optimizeForCesium) { - techniqueParameters.diffuse.semantic = '_3DTILESDIFFUSE'; - } + var segments = this.getSegments(polyline, projection); + var positions = segments.positions; + var lengths = segments.lengths; - // Copy light parameters into technique parameters - if (defined(lightParameters)) { - for (var lightParamName in lightParameters) { - if (lightParameters.hasOwnProperty(lightParamName)) { - techniqueParameters[lightParamName] = lightParameters[lightParamName]; - } - } - } + var positionIndex = 0; + var segmentIndex = 0; + var count = 0; + var position; - // Generate uniforms object before attributes are added - var techniqueUniforms = {}; - for (var paramName in techniqueParameters) { - if (techniqueParameters.hasOwnProperty(paramName) && paramName !== 'extras') { - var param = techniqueParameters[paramName]; - techniqueUniforms['u_' + paramName] = paramName; - var arraySize = defined(param.count) ? '[' + param.count + ']' : ''; - if (((param.type !== WebGLConstants.FLOAT_MAT3) && (param.type !== WebGLConstants.FLOAT_MAT4)) || - param.useInFragment) { - fragmentShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; - delete param.useInFragment; + positionsLength = positions.length; + for ( var i = 0; i < positionsLength; ++i) { + if (i === 0) { + if (polyline._loop) { + position = positions[positionsLength - 2]; + } else { + position = scratchWriteVector; + Cartesian3.subtract(positions[0], positions[1], position); + Cartesian3.add(positions[0], position, position); + } } else { - vertexShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; + position = positions[i - 1]; } - } - } - // Add attributes with semantics - var vertexShaderMain = ''; - if (hasSkinning) { - var i, j; - var numberOfComponents = numberOfComponentsForType(skinningInfo.type); - var matrix = false; - if (skinningInfo.type.indexOf('MAT') === 0) { - matrix = true; - numberOfComponents = Math.sqrt(numberOfComponents); - } - if (!matrix) { - for (i = 0; i < numberOfComponents; i++) { - if (i === 0) { - vertexShaderMain += ' mat4 skinMat = '; + Cartesian3.clone(position, scratchWritePrevPosition); + Cartesian3.clone(positions[i], scratchWritePosition); + + if (i === positionsLength - 1) { + if (polyline._loop) { + position = positions[1]; } else { - vertexShaderMain += ' skinMat += '; + position = scratchWriteVector; + Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], position); + Cartesian3.add(positions[positionsLength - 1], position, position); } - vertexShaderMain += 'a_weight[' + i + '] * u_jointMatrix[int(a_joint[' + i + '])];\n'; + } else { + position = positions[i + 1]; } - } else { - for (i = 0; i < numberOfComponents; i++) { - for (j = 0; j < numberOfComponents; j++) { - if (i === 0 && j === 0) { - vertexShaderMain += ' mat4 skinMat = '; - } else { - vertexShaderMain += ' skinMat += '; + + Cartesian3.clone(position, scratchWriteNextPosition); + + var segmentLength = lengths[segmentIndex]; + if (i === count + segmentLength) { + count += segmentLength; + ++segmentIndex; + } + + var segmentStart = i - count === 0; + var segmentEnd = i === count + lengths[segmentIndex] - 1; + + if (mode === SceneMode.SCENE2D) { + scratchWritePrevPosition.z = 0.0; + scratchWritePosition.z = 0.0; + scratchWriteNextPosition.z = 0.0; + } + + if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { + if ((segmentStart || segmentEnd) && maxLon - Math.abs(scratchWritePosition.x) < 1.0) { + if ((scratchWritePosition.x < 0.0 && scratchWritePrevPosition.x > 0.0) || + (scratchWritePosition.x > 0.0 && scratchWritePrevPosition.x < 0.0)) { + Cartesian3.clone(scratchWritePosition, scratchWritePrevPosition); + } + + if ((scratchWritePosition.x < 0.0 && scratchWriteNextPosition.x > 0.0) || + (scratchWritePosition.x > 0.0 && scratchWriteNextPosition.x < 0.0)) { + Cartesian3.clone(scratchWritePosition, scratchWriteNextPosition); } - vertexShaderMain += 'a_weight[' + i + '][' + j + '] * u_jointMatrix[int(a_joint[' + i + '][' + j + '])];\n'; } } - } - } - // Add position always - var techniqueAttributes = { - a_position: 'position' - }; - techniqueParameters.position = { - semantic: 'POSITION', - type: WebGLConstants.FLOAT_VEC3 - }; - vertexShader += 'attribute vec3 a_position;\n'; - vertexShader += 'varying vec3 v_positionEC;\n'; - if (hasSkinning) { - vertexShaderMain += ' vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);\n'; - } else { - vertexShaderMain += ' vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);\n'; - } - vertexShaderMain += ' v_positionEC = pos.xyz;\n'; - vertexShaderMain += ' gl_Position = u_projectionMatrix * pos;\n'; - fragmentShader += 'varying vec3 v_positionEC;\n'; + var startJ = (segmentStart) ? 2 : 0; + var endJ = (segmentEnd) ? 2 : 4; - // Add normal if we don't have constant lighting - if (hasNormals) { - techniqueAttributes.a_normal = 'normal'; - techniqueParameters.normal = { - semantic: 'NORMAL', - type: WebGLConstants.FLOAT_VEC3 - }; - vertexShader += 'attribute vec3 a_normal;\n'; - vertexShader += 'varying vec3 v_normal;\n'; - if (hasSkinning) { - vertexShaderMain += ' v_normal = u_normalMatrix * mat3(skinMat) * a_normal;\n'; - } else { - vertexShaderMain += ' v_normal = u_normalMatrix * a_normal;\n'; + for (var j = startJ; j < endJ; ++j) { + EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); + EncodedCartesian3.writeElements(scratchWritePrevPosition, positionArray, positionIndex + 6); + EncodedCartesian3.writeElements(scratchWriteNextPosition, positionArray, positionIndex + 12); + positionIndex += 6 * 3; + } } - fragmentShader += 'varying vec3 v_normal;\n'; + positionBuffer.copyFromArrayView(positionArray, 6 * 3 * Float32Array.BYTES_PER_ELEMENT * index); } + }; - // Add texture coordinates if the material uses them - var v_texcoord; - if (hasTexCoords) { - techniqueAttributes.a_texcoord_0 = 'texcoord_0'; - techniqueParameters.texcoord_0 = { - semantic: 'TEXCOORD_0', - type: WebGLConstants.FLOAT_VEC2 - }; + return PolylineCollection; +}); - v_texcoord = 'v_texcoord_0'; - vertexShader += 'attribute vec2 a_texcoord_0;\n'; - vertexShader += 'varying vec2 ' + v_texcoord + ';\n'; - vertexShaderMain += ' ' + v_texcoord + ' = a_texcoord_0;\n'; +define('DataSources/ScaledPositionProperty',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Ellipsoid', + '../Core/Event', + '../Core/ReferenceFrame', + './Property' + ], function( + defined, + defineProperties, + DeveloperError, + Ellipsoid, + Event, + ReferenceFrame, + Property) { + 'use strict'; - fragmentShader += 'varying vec2 ' + v_texcoord + ';\n'; + /** + * This is a temporary class for scaling position properties to the WGS84 surface. + * It will go away or be refactored to support data with arbitrary height references. + * @private + */ + function ScaledPositionProperty(value) { + this._definitionChanged = new Event(); + this._value = undefined; + this._removeSubscription = undefined; + this.setValue(value); + } + + defineProperties(ScaledPositionProperty.prototype, { + isConstant : { + get : function() { + return Property.isConstant(this._value); + } + }, + definitionChanged : { + get : function() { + return this._definitionChanged; + } + }, + referenceFrame : { + get : function() { + return defined(this._value) ? this._value.referenceFrame : ReferenceFrame.FIXED; + } } + }); - if (hasSkinning) { - techniqueAttributes.a_joint = 'joint'; - var attributeType = getShaderVariable(skinningInfo.type); - var webGLConstant = glslTypeToWebGLConstant(attributeType); + ScaledPositionProperty.prototype.getValue = function(time, result) { + return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); + }; - techniqueParameters.joint = { - semantic: 'JOINT', - type: webGLConstant - }; - techniqueAttributes.a_weight = 'weight'; - techniqueParameters.weight = { - semantic: 'WEIGHT', - type: webGLConstant - }; + ScaledPositionProperty.prototype.setValue = function(value) { + if (this._value !== value) { + this._value = value; - vertexShader += 'attribute ' + attributeType + ' a_joint;\n'; - vertexShader += 'attribute ' + attributeType + ' a_weight;\n'; + if (defined(this._removeSubscription)) { + this._removeSubscription(); + this._removeSubscription = undefined; + } + + if (defined(value)) { + this._removeSubscription = value.definitionChanged.addEventListener(this._raiseDefinitionChanged, this); + } + this._definitionChanged.raiseEvent(this); } + }; - if (addBatchIdToGeneratedShaders) { - techniqueAttributes.a_batchId = 'batchId'; - techniqueParameters.batchId = { - semantic: '_BATCHID', - type: WebGLConstants.FLOAT - }; - vertexShader += 'attribute float a_batchId;\n'; + ScaledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(referenceFrame)) { + throw new DeveloperError('referenceFrame is required.'); + } + + if (!defined(this._value)) { + return undefined; } - var hasSpecular = hasNormals && ((lightingModel === 'BLINN') || (lightingModel === 'PHONG')) && - defined(techniqueParameters.specular) && defined(techniqueParameters.shininess) && - (techniqueParameters.shininess > 0.0); + result = this._value.getValueInReferenceFrame(time, referenceFrame, result); + return defined(result) ? Ellipsoid.WGS84.scaleToGeodeticSurface(result, result) : undefined; + }; - // Generate lighting code blocks - var hasNonAmbientLights = false; - var hasAmbientLights = false; - var fragmentLightingBlock = ''; - for (var lightName in lights) { - if (lights.hasOwnProperty(lightName)) { - var light = lights[lightName]; - var lightType = light.type.toLowerCase(); - var lightBaseName = light.baseName; - fragmentLightingBlock += ' {\n'; - var lightColorName = 'u_' + lightBaseName + 'Color'; - var varyingDirectionName; - var varyingPositionName; - if (lightType === 'ambient') { - hasAmbientLights = true; - fragmentLightingBlock += ' ambientLight += ' + lightColorName + ';\n'; - } else if (hasNormals) { - hasNonAmbientLights = true; - varyingDirectionName = 'v_' + lightBaseName + 'Direction'; - varyingPositionName = 'v_' + lightBaseName + 'Position'; + ScaledPositionProperty.prototype.equals = function(other) { + return this === other || (other instanceof ScaledPositionProperty && this._value === other._value); + }; - if (lightType !== 'point') { - vertexShader += 'varying vec3 ' + varyingDirectionName + ';\n'; - fragmentShader += 'varying vec3 ' + varyingDirectionName + ';\n'; + ScaledPositionProperty.prototype._raiseDefinitionChanged = function() { + this._definitionChanged.raiseEvent(this); + }; - vertexShaderMain += ' ' + varyingDirectionName + ' = mat3(u_' + lightBaseName + 'Transform) * vec3(0.,0.,1.);\n'; - if (lightType === 'directional') { - fragmentLightingBlock += ' vec3 l = normalize(' + varyingDirectionName + ');\n'; - } - } + return ScaledPositionProperty; +}); - if (lightType !== 'directional') { - vertexShader += 'varying vec3 ' + varyingPositionName + ';\n'; - fragmentShader += 'varying vec3 ' + varyingPositionName + ';\n'; +define('DataSources/PathVisualizer',[ + '../Core/AssociativeArray', + '../Core/Cartesian3', + '../Core/defined', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/JulianDate', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/ReferenceFrame', + '../Core/TimeInterval', + '../Core/Transforms', + '../Scene/PolylineCollection', + '../Scene/SceneMode', + './CompositePositionProperty', + './ConstantPositionProperty', + './MaterialProperty', + './Property', + './ReferenceProperty', + './SampledPositionProperty', + './ScaledPositionProperty', + './TimeIntervalCollectionPositionProperty' + ], function( + AssociativeArray, + Cartesian3, + defined, + destroyObject, + DeveloperError, + JulianDate, + Matrix3, + Matrix4, + ReferenceFrame, + TimeInterval, + Transforms, + PolylineCollection, + SceneMode, + CompositePositionProperty, + ConstantPositionProperty, + MaterialProperty, + Property, + ReferenceProperty, + SampledPositionProperty, + ScaledPositionProperty, + TimeIntervalCollectionPositionProperty) { + 'use strict'; - vertexShaderMain += ' ' + varyingPositionName + ' = u_' + lightBaseName + 'Transform[3].xyz;\n'; - fragmentLightingBlock += ' vec3 VP = ' + varyingPositionName + ' - v_positionEC;\n'; - fragmentLightingBlock += ' vec3 l = normalize(VP);\n'; - fragmentLightingBlock += ' float range = length(VP);\n'; - fragmentLightingBlock += ' float attenuation = 1.0 / (u_' + lightBaseName + 'Attenuation.x + '; - fragmentLightingBlock += '(u_' + lightBaseName + 'Attenuation.y * range) + '; - fragmentLightingBlock += '(u_' + lightBaseName + 'Attenuation.z * range * range));\n'; - } else { - fragmentLightingBlock += ' float attenuation = 1.0;\n'; - } + var defaultResolution = 60.0; + var defaultWidth = 1.0; - if (lightType === 'spot') { - fragmentLightingBlock += ' float spotDot = dot(l, normalize(' + varyingDirectionName + '));\n'; - fragmentLightingBlock += ' if (spotDot < cos(u_' + lightBaseName + 'FallOff.x * 0.5))\n'; - fragmentLightingBlock += ' {\n'; - fragmentLightingBlock += ' attenuation = 0.0;\n'; - fragmentLightingBlock += ' }\n'; - fragmentLightingBlock += ' else\n'; - fragmentLightingBlock += ' {\n'; - fragmentLightingBlock += ' attenuation *= max(0.0, pow(spotDot, u_' + lightBaseName + 'FallOff.y));\n'; - fragmentLightingBlock += ' }\n'; - } + var scratchTimeInterval = new TimeInterval(); + var subSampleCompositePropertyScratch = new TimeInterval(); + var subSampleIntervalPropertyScratch = new TimeInterval(); - fragmentLightingBlock += ' diffuseLight += ' + lightColorName + '* max(dot(normal,l), 0.) * attenuation;\n'; + function EntityData(entity) { + this.entity = entity; + this.polyline = undefined; + this.index = undefined; + this.updater = undefined; + } - if (hasSpecular) { - if (lightingModel === 'BLINN') { - fragmentLightingBlock += ' vec3 h = normalize(l + viewDir);\n'; - fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n'; - } else { // PHONG - fragmentLightingBlock += ' vec3 reflectDir = reflect(-l, normal);\n'; - fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n'; - } - fragmentLightingBlock += ' specularLight += ' + lightColorName + ' * specularIntensity;\n'; + function subSampleSampledProperty(property, start, stop, times, updateTime, referenceFrame, maximumStep, startingIndex, result) { + var r = startingIndex; + //Always step exactly on start (but only use it if it exists.) + var tmp; + tmp = property.getValueInReferenceFrame(start, referenceFrame, result[r]); + if (defined(tmp)) { + result[r++] = tmp; + } + + var steppedOnNow = !defined(updateTime) || JulianDate.lessThanOrEquals(updateTime, start) || JulianDate.greaterThanOrEquals(updateTime, stop); + + //Iterate over all interval times and add the ones that fall in our + //time range. Note that times can contain data outside of + //the intervals range. This is by design for use with interpolation. + var t = 0; + var len = times.length; + var current = times[t]; + var loopStop = stop; + var sampling = false; + var sampleStepsToTake; + var sampleStepsTaken; + var sampleStepSize; + + while (t < len) { + if (!steppedOnNow && JulianDate.greaterThanOrEquals(current, updateTime)) { + tmp = property.getValueInReferenceFrame(updateTime, referenceFrame, result[r]); + if (defined(tmp)) { + result[r++] = tmp; + } + steppedOnNow = true; + } + if (JulianDate.greaterThan(current, start) && JulianDate.lessThan(current, loopStop) && !current.equals(updateTime)) { + tmp = property.getValueInReferenceFrame(current, referenceFrame, result[r]); + if (defined(tmp)) { + result[r++] = tmp; + } + } + + if (t < (len - 1)) { + if (maximumStep > 0 && !sampling) { + var next = times[t + 1]; + var secondsUntilNext = JulianDate.secondsDifference(next, current); + sampling = secondsUntilNext > maximumStep; + + if (sampling) { + sampleStepsToTake = Math.ceil(secondsUntilNext / maximumStep); + sampleStepsTaken = 0; + sampleStepSize = secondsUntilNext / Math.max(sampleStepsToTake, 2); + sampleStepsToTake = Math.max(sampleStepsToTake - 1, 1); } } - fragmentLightingBlock += ' }\n'; + + if (sampling && sampleStepsTaken < sampleStepsToTake) { + current = JulianDate.addSeconds(current, sampleStepSize, new JulianDate()); + sampleStepsTaken++; + continue; + } } + sampling = false; + t++; + current = times[t]; } - if (!hasAmbientLights) { - // Add an ambient light if we don't have one - fragmentLightingBlock += ' ambientLight += vec3(0.2, 0.2, 0.2);\n'; + //Always step exactly on stop (but only use it if it exists.) + tmp = property.getValueInReferenceFrame(stop, referenceFrame, result[r]); + if (defined(tmp)) { + result[r++] = tmp; } - if (!hasNonAmbientLights && (lightingModel !== 'CONSTANT')) { - if (optimizeForCesium) { - fragmentLightingBlock += ' vec3 l = normalize(czm_sunDirectionEC);\n'; - } else { - fragmentLightingBlock += ' vec3 l = vec3(0.0, 0.0, 1.0);\n'; - } - var minimumLighting = optimizeForCesium ? '0.2' : '0.0'; // Use strings instead of values as 0.0 -> 0 when stringified - fragmentLightingBlock += ' diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal,l), ' + minimumLighting + ');\n'; + return r; + } - if (hasSpecular) { - if (lightingModel === 'BLINN') { - fragmentLightingBlock += ' vec3 h = normalize(l + viewDir);\n'; - fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n'; - } else { // PHONG - fragmentLightingBlock += ' vec3 reflectDir = reflect(-l, normal);\n'; - fragmentLightingBlock += ' float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n'; + function subSampleGenericProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { + var tmp; + var i = 0; + var index = startingIndex; + var time = start; + var stepSize = Math.max(maximumStep, 60); + var steppedOnNow = !defined(updateTime) || JulianDate.lessThanOrEquals(updateTime, start) || JulianDate.greaterThanOrEquals(updateTime, stop); + while (JulianDate.lessThan(time, stop)) { + if (!steppedOnNow && JulianDate.greaterThanOrEquals(time, updateTime)) { + steppedOnNow = true; + tmp = property.getValueInReferenceFrame(updateTime, referenceFrame, result[index]); + if (defined(tmp)) { + result[index] = tmp; + index++; } - - fragmentLightingBlock += ' specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity;\n'; } + tmp = property.getValueInReferenceFrame(time, referenceFrame, result[index]); + if (defined(tmp)) { + result[index] = tmp; + index++; + } + i++; + time = JulianDate.addSeconds(start, stepSize * i, new JulianDate()); + } + //Always sample stop. + tmp = property.getValueInReferenceFrame(stop, referenceFrame, result[index]); + if (defined(tmp)) { + result[index] = tmp; + index++; } + return index; + } - vertexShader += 'void main(void) {\n'; - vertexShader += vertexShaderMain; - vertexShader += '}\n'; + function subSampleIntervalProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { + subSampleIntervalPropertyScratch.start = start; + subSampleIntervalPropertyScratch.stop = stop; - fragmentShader += 'void main(void) {\n'; - var colorCreationBlock = ' vec3 color = vec3(0.0, 0.0, 0.0);\n'; - if (hasNormals) { - fragmentShader += ' vec3 normal = normalize(v_normal);\n'; - if (khrMaterialsCommon.doubleSided) { - fragmentShader += ' if (gl_FrontFacing == false)\n'; - fragmentShader += ' {\n'; - fragmentShader += ' normal = -normal;\n'; - fragmentShader += ' }\n'; + var index = startingIndex; + var intervals = property.intervals; + for (var i = 0; i < intervals.length; i++) { + var interval = intervals.get(i); + if (!TimeInterval.intersect(interval, subSampleIntervalPropertyScratch, scratchTimeInterval).isEmpty) { + var time = interval.start; + if (!interval.isStartIncluded) { + if (interval.isStopIncluded) { + time = interval.stop; + } else { + time = JulianDate.addSeconds(interval.start, JulianDate.secondsDifference(interval.stop, interval.start) / 2, new JulianDate()); + } + } + var tmp = property.getValueInReferenceFrame(time, referenceFrame, result[index]); + if (defined(tmp)) { + result[index] = tmp; + index++; + } } } + return index; + } + + function subSampleConstantProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { + var tmp = property.getValueInReferenceFrame(start, referenceFrame, result[startingIndex]); + if (defined(tmp)) { + result[startingIndex++] = tmp; + } + return startingIndex; + } + + function subSampleCompositeProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { + subSampleCompositePropertyScratch.start = start; + subSampleCompositePropertyScratch.stop = stop; + + var index = startingIndex; + var intervals = property.intervals; + for (var i = 0; i < intervals.length; i++) { + var interval = intervals.get(i); + if (!TimeInterval.intersect(interval, subSampleCompositePropertyScratch, scratchTimeInterval).isEmpty) { + var intervalStart = interval.start; + var intervalStop = interval.stop; - var finalColorComputation; - if (lightingModel !== 'CONSTANT') { - if (defined(techniqueParameters.diffuse)) { - if (techniqueParameters.diffuse.type === WebGLConstants.SAMPLER_2D) { - fragmentShader += ' vec4 diffuse = texture2D(u_diffuse, ' + v_texcoord + ');\n'; - } else { - fragmentShader += ' vec4 diffuse = u_diffuse;\n'; + var sampleStart = start; + if (JulianDate.greaterThan(intervalStart, sampleStart)) { + sampleStart = intervalStart; } - fragmentShader += ' vec3 diffuseLight = vec3(0.0, 0.0, 0.0);\n'; - colorCreationBlock += ' color += diffuse.rgb * diffuseLight;\n'; - } - if (hasSpecular) { - if (techniqueParameters.specular.type === WebGLConstants.SAMPLER_2D) { - fragmentShader += ' vec3 specular = texture2D(u_specular, ' + v_texcoord + ').rgb;\n'; - } else { - fragmentShader += ' vec3 specular = u_specular.rgb;\n'; + var sampleStop = stop; + if (JulianDate.lessThan(intervalStop, sampleStop)) { + sampleStop = intervalStop; } - fragmentShader += ' vec3 specularLight = vec3(0.0, 0.0, 0.0);\n'; - colorCreationBlock += ' color += specular * specularLight;\n'; - } - if (defined(techniqueParameters.transparency)) { - finalColorComputation = ' gl_FragColor = vec4(color * diffuse.a * u_transparency, diffuse.a * u_transparency);\n'; - } else { - finalColorComputation = ' gl_FragColor = vec4(color * diffuse.a, diffuse.a);\n'; + index = reallySubSample(interval.data, sampleStart, sampleStop, updateTime, referenceFrame, maximumStep, index, result); } + } + return index; + } + + function reallySubSample(property, start, stop, updateTime, referenceFrame, maximumStep, index, result) { + //Unwrap any references until we have the actual property. + while (property instanceof ReferenceProperty) { + property = property.resolvedProperty; + } + + if (property instanceof SampledPositionProperty) { + var times = property._property._times; + index = subSampleSampledProperty(property, start, stop, times, updateTime, referenceFrame, maximumStep, index, result); + } else if (property instanceof CompositePositionProperty) { + index = subSampleCompositeProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); + } else if (property instanceof TimeIntervalCollectionPositionProperty) { + index = subSampleIntervalProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); + } else if (property instanceof ConstantPositionProperty || + (property instanceof ScaledPositionProperty && Property.isConstant(property))) { + index = subSampleConstantProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); } else { - if (defined(techniqueParameters.transparency)) { - finalColorComputation = ' gl_FragColor = vec4(color * u_transparency, u_transparency);\n'; - } else { - finalColorComputation = ' gl_FragColor = vec4(color, 1.0);\n'; - } + //Fallback to generic sampling. + index = subSampleGenericProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); } + return index; + } - if (defined(techniqueParameters.emission)) { - if (techniqueParameters.emission.type === WebGLConstants.SAMPLER_2D) { - fragmentShader += ' vec3 emission = texture2D(u_emission, ' + v_texcoord + ').rgb;\n'; - } else { - fragmentShader += ' vec3 emission = u_emission.rgb;\n'; - } - colorCreationBlock += ' color += emission;\n'; + function subSample(property, start, stop, updateTime, referenceFrame, maximumStep, result) { + if (!defined(result)) { + result = []; } - if (defined(techniqueParameters.ambient) || (lightingModel !== 'CONSTANT')) { - if (defined(techniqueParameters.ambient)) { - if (techniqueParameters.ambient.type === WebGLConstants.SAMPLER_2D) { - fragmentShader += ' vec3 ambient = texture2D(u_ambient, ' + v_texcoord + ').rgb;\n'; - } else { - fragmentShader += ' vec3 ambient = u_ambient.rgb;\n'; - } - } else { - fragmentShader += ' vec3 ambient = diffuse.rgb;\n'; + var length = reallySubSample(property, start, stop, updateTime, referenceFrame, maximumStep, 0, result); + result.length = length; + return result; + } + + var toFixedScratch = new Matrix3(); + function PolylineUpdater(scene, referenceFrame) { + this._unusedIndexes = []; + this._polylineCollection = new PolylineCollection(); + this._scene = scene; + this._referenceFrame = referenceFrame; + scene.primitives.add(this._polylineCollection); + } + + PolylineUpdater.prototype.update = function(time) { + if (this._referenceFrame === ReferenceFrame.INERTIAL) { + var toFixed = Transforms.computeIcrfToFixedMatrix(time, toFixedScratch); + if (!defined(toFixed)) { + toFixed = Transforms.computeTemeToPseudoFixedMatrix(time, toFixedScratch); } - colorCreationBlock += ' color += ambient * ambientLight;\n'; + Matrix4.fromRotationTranslation(toFixed, Cartesian3.ZERO, this._polylineCollection.modelMatrix); } - fragmentShader += ' vec3 viewDir = -normalize(v_positionEC);\n'; - fragmentShader += ' vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n'; + }; - // Add in light computations - fragmentShader += fragmentLightingBlock; + PolylineUpdater.prototype.updateObject = function(time, item) { + var entity = item.entity; + var pathGraphics = entity._path; + var positionProperty = entity._position; - fragmentShader += colorCreationBlock; - fragmentShader += finalColorComputation; - fragmentShader += '}\n'; + var sampleStart; + var sampleStop; + var showProperty = pathGraphics._show; + var polyline = item.polyline; + var show = entity.isShowing && (!defined(showProperty) || showProperty.getValue(time)); - var techniqueStates; - if (parameterValues.transparent) { - techniqueStates = { - enable: [ - WebGLConstants.DEPTH_TEST, - WebGLConstants.BLEND - ], - functions: { - depthMask : [false], - blendEquationSeparate: [ - WebGLConstants.FUNC_ADD, - WebGLConstants.FUNC_ADD - ], - blendFuncSeparate: [ - WebGLConstants.ONE, - WebGLConstants.ONE_MINUS_SRC_ALPHA, - WebGLConstants.ONE, - WebGLConstants.ONE_MINUS_SRC_ALPHA - ] - } - }; - } else if (khrMaterialsCommon.doubleSided) { - techniqueStates = { - enable: [ - WebGLConstants.DEPTH_TEST - ] - }; - } else { // Not transparent or double sided - techniqueStates = { - enable: [ - WebGLConstants.CULL_FACE, - WebGLConstants.DEPTH_TEST - ] - }; - } + //While we want to show the path, there may not actually be anything to show + //depending on lead/trail settings. Compute the interval of the path to + //show and check against actual availability. + if (show) { + var leadTime = Property.getValueOrUndefined(pathGraphics._leadTime, time); + var trailTime = Property.getValueOrUndefined(pathGraphics._trailTime, time); + var availability = entity._availability; + var hasAvailability = defined(availability); + var hasLeadTime = defined(leadTime); + var hasTrailTime = defined(trailTime); - // Add shaders - var vertexShaderId = addToArray(shaders, { - type: WebGLConstants.VERTEX_SHADER, - extras: { - _pipeline: { - source: vertexShader, - extension: '.glsl' - } - } - }); + //Objects need to have either defined availability or both a lead and trail time in order to + //draw a path (since we can't draw "infinite" paths. + show = hasAvailability || (hasLeadTime && hasTrailTime); - var fragmentShaderId = addToArray(shaders, { - type: WebGLConstants.FRAGMENT_SHADER, - extras: { - _pipeline: { - source: fragmentShader, - extension: '.glsl' + //The final step is to compute the actual start/stop times of the path to show. + //If current time is outside of the availability interval, there's a chance that + //we won't have to draw anything anyway. + if (show) { + if (hasTrailTime) { + sampleStart = JulianDate.addSeconds(time, -trailTime, new JulianDate()); + } + if (hasLeadTime) { + sampleStop = JulianDate.addSeconds(time, leadTime, new JulianDate()); } - } - }); - // Add program - var programAttributes = Object.keys(techniqueAttributes); - var programId = addToArray(programs, { - attributes: programAttributes, - fragmentShader: fragmentShaderId, - vertexShader: vertexShaderId - }); + if (hasAvailability) { + var start = availability.start; + var stop = availability.stop; - var techniqueId = addToArray(techniques, { - attributes: techniqueAttributes, - parameters: techniqueParameters, - program: programId, - states: techniqueStates, - uniforms: techniqueUniforms - }); + if (!hasTrailTime || JulianDate.greaterThan(start, sampleStart)) { + sampleStart = start; + } - return techniqueId; - } + if (!hasLeadTime || JulianDate.lessThan(stop, sampleStop)) { + sampleStop = stop; + } + } + show = JulianDate.lessThan(sampleStart, sampleStop); + } + } - function getKHRMaterialsCommonValueType(paramName, paramValue) { - var value; + if (!show) { + //don't bother creating or updating anything else + if (defined(polyline)) { + this._unusedIndexes.push(item.index); + item.polyline = undefined; + polyline.show = false; + item.index = undefined; + } + return; + } - // Backwards compatibility for COLLADA2GLTF v1.0-draft when it encoding - // materials using KHR_materials_common with explicit type/value members - if (defined(paramValue.value)) { - value = paramValue.value; - } else if (defined(paramValue.index)) { - value = [paramValue.index]; - } else { - value = paramValue; + if (!defined(polyline)) { + var unusedIndexes = this._unusedIndexes; + var length = unusedIndexes.length; + if (length > 0) { + var index = unusedIndexes.pop(); + polyline = this._polylineCollection.get(index); + item.index = index; + } else { + item.index = this._polylineCollection.length; + polyline = this._polylineCollection.add(); + } + polyline.id = entity; + item.polyline = polyline; } - switch (paramName) { - case 'ambient': - return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; - case 'diffuse': - return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; - case 'emission': - return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; - case 'specular': - return value.length === 1 ? WebGLConstants.SAMPLER_2D : WebGLConstants.FLOAT_VEC4; - case 'shininess': - return WebGLConstants.FLOAT; - case 'transparency': - return WebGLConstants.FLOAT; + var resolution = Property.getValueOrDefault(pathGraphics._resolution, time, defaultResolution); - // these two are usually not used directly within shaders, - // they are just added here for completeness - case 'transparent': - return WebGLConstants.BOOL; - case 'doubleSided': - return WebGLConstants.BOOL; + polyline.show = true; + polyline.positions = subSample(positionProperty, sampleStart, sampleStop, time, this._referenceFrame, resolution, polyline.positions.slice()); + polyline.material = MaterialProperty.getValue(time, pathGraphics._material, polyline.material); + polyline.width = Property.getValueOrDefault(pathGraphics._width, time, defaultWidth); + polyline.distanceDisplayCondition = Property.getValueOrUndefined(pathGraphics._distanceDisplayCondition, time, polyline.distanceDisplayCondition); + }; + + PolylineUpdater.prototype.removeObject = function(item) { + var polyline = item.polyline; + if (defined(polyline)) { + this._unusedIndexes.push(item.index); + item.polyline = undefined; + polyline.show = false; + polyline.id = undefined; + item.index = undefined; } - } + }; - function getTechniqueKey(khrMaterialsCommon) { - var techniqueKey = ''; - techniqueKey += 'technique:' + khrMaterialsCommon.technique + ';'; + PolylineUpdater.prototype.destroy = function() { + this._scene.primitives.remove(this._polylineCollection); + return destroyObject(this); + }; - var values = khrMaterialsCommon.values; - var keys = Object.keys(values).sort(); - var keysCount = keys.length; - for (var i = 0; i < keysCount; ++i) { - var name = keys[i]; - if (values.hasOwnProperty(name)) { - techniqueKey += name + ':' + getKHRMaterialsCommonValueType(name, values[name]); - techniqueKey += ';'; - } + /** + * A {@link Visualizer} which maps {@link Entity#path} to a {@link Polyline}. + * @alias PathVisualizer + * @constructor + * + * @param {Scene} scene The scene the primitives will be rendered in. + * @param {EntityCollection} entityCollection The entityCollection to visualize. + */ + function PathVisualizer(scene, entityCollection) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); } - - var doubleSided = defaultValue(khrMaterialsCommon.doubleSided, defaultValue(khrMaterialsCommon.values.doubleSided, false)); - techniqueKey += doubleSided.toString() + ';'; - var transparent = defaultValue(khrMaterialsCommon.transparent, defaultValue(khrMaterialsCommon.values.transparent, false)); - techniqueKey += transparent.toString() + ';'; - var jointCount = defaultValue(khrMaterialsCommon.jointCount, 0); - techniqueKey += jointCount.toString() + ';'; - if (jointCount > 0) { - var skinningInfo = khrMaterialsCommon.extras._pipeline.skinning; - techniqueKey += skinningInfo.type + ';'; + if (!defined(entityCollection)) { + throw new DeveloperError('entityCollection is required.'); } + + entityCollection.collectionChanged.addEventListener(PathVisualizer.prototype._onCollectionChanged, this); - return techniqueKey; + this._scene = scene; + this._updaters = {}; + this._entityCollection = entityCollection; + this._items = new AssociativeArray(); + + this._onCollectionChanged(entityCollection, entityCollection.values, [], []); } - function lightDefaults(gltf) { - if (!defined(gltf.extensions)) { - gltf.extensions = {}; + /** + * Updates all of the primitives created by this visualizer to match their + * Entity counterpart at the given time. + * + * @param {JulianDate} time The time to update to. + * @returns {Boolean} This function always returns true. + */ + PathVisualizer.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - var extensions = gltf.extensions; - - if (!defined(extensions.KHR_materials_common)) { - extensions.KHR_materials_common = {}; + + var updaters = this._updaters; + for ( var key in updaters) { + if (updaters.hasOwnProperty(key)) { + updaters[key].update(time); + } } - var khrMaterialsCommon = extensions.KHR_materials_common; - if (!defined(khrMaterialsCommon.lights)) { - khrMaterialsCommon.lights = {}; - } - var lights = khrMaterialsCommon.lights; + var items = this._items.values; + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + var entity = item.entity; + var positionProperty = entity._position; - var lightsLength = lights.length; - for (var lightId = 0; lightId < lightsLength; lightId++) { - var light = lights[lightId]; - if (light.type === 'ambient') { - if (!defined(light.ambient)) { - light.ambient = {}; - } - var ambientLight = light.ambient; + var lastUpdater = item.updater; - if (!defined(ambientLight.color)) { - ambientLight.color = [1.0, 1.0, 1.0]; - } - } else if (light.type === 'directional') { - if (!defined(light.directional)) { - light.directional = {}; - } - var directionalLight = light.directional; + var frameToVisualize = ReferenceFrame.FIXED; + if (this._scene.mode === SceneMode.SCENE3D) { + frameToVisualize = positionProperty.referenceFrame; + } - if (!defined(directionalLight.color)) { - directionalLight.color = [1.0, 1.0, 1.0]; - } - } else if (light.type === 'point') { - if (!defined(light.point)) { - light.point = {}; - } - var pointLight = light.point; + var currentUpdater = this._updaters[frameToVisualize]; - if (!defined(pointLight.color)) { - pointLight.color = [1.0, 1.0, 1.0]; - } + if ((lastUpdater === currentUpdater) && (defined(currentUpdater))) { + currentUpdater.updateObject(time, item); + continue; + } - pointLight.constantAttenuation = defaultValue(pointLight.constantAttenuation, 1.0); - pointLight.linearAttenuation = defaultValue(pointLight.linearAttenuation, 0.0); - pointLight.quadraticAttenuation = defaultValue(pointLight.quadraticAttenuation, 0.0); - } else if (light.type === 'spot') { - if (!defined(light.spot)) { - light.spot = {}; - } - var spotLight = light.spot; + if (defined(lastUpdater)) { + lastUpdater.removeObject(item); + } - if (!defined(spotLight.color)) { - spotLight.color = [1.0, 1.0, 1.0]; - } + if (!defined(currentUpdater)) { + currentUpdater = new PolylineUpdater(this._scene, frameToVisualize); + currentUpdater.update(time); + this._updaters[frameToVisualize] = currentUpdater; + } - spotLight.constantAttenuation = defaultValue(spotLight.constantAttenuation, 1.0); - spotLight.fallOffAngle = defaultValue(spotLight.fallOffAngle, 3.14159265); - spotLight.fallOffExponent = defaultValue(spotLight.fallOffExponent, 0.0); - spotLight.linearAttenuation = defaultValue(spotLight.linearAttenuation, 0.0); - spotLight.quadraticAttenuation = defaultValue(spotLight.quadraticAttenuation, 0.0); + item.updater = currentUpdater; + if (defined(currentUpdater)) { + currentUpdater.updateObject(time, item); } } - } + return true; + }; - function getShaderVariable(type) { - if (type === 'SCALAR') { - return 'float'; + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + PathVisualizer.prototype.isDestroyed = function() { + return false; + }; + + /** + * Removes and destroys all primitives created by this instance. + */ + PathVisualizer.prototype.destroy = function() { + this._entityCollection.collectionChanged.removeEventListener(PathVisualizer.prototype._onCollectionChanged, this); + + var updaters = this._updaters; + for ( var key in updaters) { + if (updaters.hasOwnProperty(key)) { + updaters[key].destroy(); + } } - return type.toLowerCase(); - } - function ensureSemanticExistenceForPrimitive(gltf, primitive) { - var accessors = gltf.accessors; - var materials = gltf.materials; - var techniques = gltf.techniques; - var programs = gltf.programs; - var shaders = gltf.shaders; + return destroyObject(this); + }; - var attributes = primitive.attributes; - var material = materials[primitive.material]; - var technique = techniques[material.technique]; - var program = programs[technique.program]; - var vertexShader = shaders[program.vertexShader]; + PathVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { + var i; + var entity; + var item; + var items = this._items; - for (var semantic in attributes) { - if (attributes.hasOwnProperty(semantic)) { - if (!defined(techniqueParameterForSemantic(technique, semantic))) { - var accessorId = attributes[semantic]; - var accessor = accessors[accessorId]; - var lowerCase = semantic.toLowerCase(); - if (lowerCase.charAt(0) === '_') { - lowerCase = lowerCase.slice(1); - } - var attributeName = 'a_' + lowerCase; - technique.parameters[lowerCase] = { - semantic: semantic, - type: accessor.componentType - }; - technique.attributes[attributeName] = lowerCase; - program.attributes.push(attributeName); - var pipelineExtras = vertexShader.extras._pipeline; - var shaderText = pipelineExtras.source; - shaderText = 'attribute ' + getShaderVariable(accessor.type) + ' ' + attributeName + ';\n' + shaderText; - pipelineExtras.source = shaderText; - } + for (i = added.length - 1; i > -1; i--) { + entity = added[i]; + if (defined(entity._path) && defined(entity._position)) { + items.set(entity.id, new EntityData(entity)); } } - } - - function ensureSemanticExistence(gltf) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ensureSemanticExistenceForPrimitive(gltf, primitive); - }); - }); - } - function splitIncompatibleSkins(gltf) { - var accessors = gltf.accessors; - var materials = gltf.materials; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - var materialId = primitive.material; - var material = materials[materialId]; + for (i = changed.length - 1; i > -1; i--) { + entity = changed[i]; + if (defined(entity._path) && defined(entity._position)) { + if (!items.contains(entity.id)) { + items.set(entity.id, new EntityData(entity)); + } + } else { + item = items.get(entity.id); + if (defined(item)) { + item.updater.removeObject(item); + items.remove(entity.id); + } + } + } - if (defined(material.extensions) && defined(material.extensions.KHR_materials_common)) { - var khrMaterialsCommon = material.extensions.KHR_materials_common; - var jointAccessorId = primitive.attributes.JOINT; - var componentType; - var type; - if (defined(jointAccessorId)) { - var jointAccessor = accessors[jointAccessorId]; - componentType = jointAccessor.componentType; - type = jointAccessor.type; - } - var isSkinned = defined(jointAccessorId); + for (i = removed.length - 1; i > -1; i--) { + entity = removed[i]; + item = items.get(entity.id); + if (defined(item)) { + if (defined(item.updater)) { + item.updater.removeObject(item); + } + items.remove(entity.id); + } + } + }; - var skinningInfo = khrMaterialsCommon.extras._pipeline.skinning; - if (!defined(skinningInfo)) { - khrMaterialsCommon.extras._pipeline.skinning = { - skinned: isSkinned, - componentType: componentType, - type: type - }; - } else if ((skinningInfo.skinned !== isSkinned) || (skinningInfo.type !== type)) { - // This primitive uses the same material as another one that either isn't skinned or uses a different type to store joints and weights - var clonedMaterial = clone(material, true); - clonedMaterial.extensions.KHR_materials_common.extras._pipeline.skinning = { - skinned: isSkinned, - componentType: componentType, - type: type - }; - // Split this off as a separate material - materialId = addToArray(materials, clonedMaterial); - primitive.material = materialId; - } - } - }); - }); - } + //for testing + PathVisualizer._subSample = subSample; - return processModelMaterialsCommon; + return PathVisualizer; }); -define('ThirdParty/GltfPipeline/processPbrMetallicRoughness',[ - './addToArray', - './ForEach', - './numberOfComponentsForType', - './techniqueParameterForSemantic', - './webGLConstantToGlslType', - './glslTypeToWebGLConstant', - '../../Core/clone', - '../../Core/defined', - '../../Core/defaultValue', - '../../Core/WebGLConstants' +define('DataSources/PlaneGeometryUpdater',[ + '../Core/PlaneGeometry', + '../Core/PlaneOutlineGeometry', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/Matrix4', + '../Core/ShowGeometryInstanceAttribute', + '../Core/Quaternion', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' ], function( - addToArray, - ForEach, - numberOfComponentsForType, - techniqueParameterForSemantic, - webGLConstantToGlslType, - glslTypeToWebGLConstant, - clone, - defined, + PlaneGeometry, + PlaneOutlineGeometry, + Cartesian2, + Cartesian3, + Color, + ColorGeometryInstanceAttribute, defaultValue, - WebGLConstants) { + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + Matrix4, + ShowGeometryInstanceAttribute, + Quaternion, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { 'use strict'; + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.plane = undefined; + this.dimensions = undefined; + } + /** - * @private + * A {@link GeometryUpdater} for planes. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias PlaneGeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - function processPbrMetallicRoughness(gltf, options) { - options = defaultValue(options, {}); + function PlaneGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(PlaneGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'plane', entity.plane, undefined); + } - var hasPbrMetallicRoughness = false; - ForEach.material(gltf, function(material) { - if (defined(material.pbrMetallicRoughness)) { - hasPbrMetallicRoughness = true; - } - }); + defineProperties(PlaneGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof PlaneGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof PlaneGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); - if (hasPbrMetallicRoughness) { - if (!defined(gltf.programs)) { - gltf.programs = []; + defineProperties(PlaneGeometryUpdater.prototype, { + /** + * Gets the entity associated with this geometry. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Entity} + * @readonly + */ + entity : { + get : function() { + return this._entity; } - if (!defined(gltf.shaders)) { - gltf.shaders = []; + }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + fillEnabled : { + get : function() { + return this._fillEnabled; } - if (!defined(gltf.techniques)) { - gltf.techniques = []; + }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantFill : { + get : function() { + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); + } + }, + /** + * Gets the material property used to fill the geometry. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly + */ + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, + /** + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Number} + * @readonly + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + } + }, + /** + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, + /** + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayConditionProperty; + } + }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isDynamic : { + get : function() { + return this._dynamic; + } + }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isClosed : { + value : false + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof PlaneGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { + get : function() { + return this._geometryChanged; } + } + }); + + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + PlaneGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; - // Pre-processing to assign skinning info and address incompatibilities - splitIncompatibleSkins(gltf); + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + PlaneGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; - ForEach.material(gltf, function(material) { - var pbrMetallicRoughness = material.pbrMetallicRoughness; - if (defined(pbrMetallicRoughness)) { - var technique = generateTechnique(gltf, material, options); + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + PlaneGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - material.values = pbrMetallicRoughness; - material.technique = technique; - delete material.pbrMetallicRoughness; - } - }); + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - // If any primitives have semantics that aren't declared in the generated - // shaders, we want to preserve them. - ensureSemanticExistence(gltf); + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; } - return gltf; - } + var planeGraphics = entity.plane; + var options = this._options; + var modelMatrix = entity.computeModelMatrix(time); + var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane); + var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions); + if (!defined(modelMatrix) || !defined(plane) || !defined(dimensions)) { + return; + } - function generateTechnique(gltf, material, options) { - var optimizeForCesium = defaultValue(options.optimizeForCesium, false); - var hasCesiumRTCExtension = defined(gltf.extensions) && defined(gltf.extensions.CESIUM_RTC); - var addBatchIdToGeneratedShaders = defaultValue(options.addBatchIdToGeneratedShaders, false); + options.plane = plane; + options.dimensions = dimensions; - var techniques = gltf.techniques; - var shaders = gltf.shaders; - var programs = gltf.programs; + modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, modelMatrix); - var parameterValues = material.pbrMetallicRoughness; - for (var additional in material) { - if (material.hasOwnProperty(additional) && ((additional.indexOf('Texture') >= 0) || additional.indexOf('Factor') >= 0) || additional === 'doubleSided') { - parameterValues[additional] = material[additional]; - } + return new GeometryInstance({ + id : entity, + geometry : new PlaneGeometry(this._options), + modelMatrix : modelMatrix, + attributes : attributes + }); + }; + + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + PlaneGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + + var planeGraphics = entity.plane; + var options = this._options; + var modelMatrix = entity.computeModelMatrix(time); + var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane); + var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions); + if (!defined(modelMatrix) || !defined(plane) || !defined(dimensions)) { + return; } - var vertexShader = 'precision highp float;\n'; - var fragmentShader = 'precision highp float;\n'; + options.plane = plane; + options.dimensions = dimensions; - var skin; - if (defined(gltf.skins)) { - skin = gltf.skins[0]; - } - var joints = (defined(skin)) ? skin.joints : []; - var jointCount = joints.length; - var skinningInfo = material.extras._pipeline.skinning; - var hasSkinning = defined(skinningInfo.type); + modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, modelMatrix); - var hasNormals = true; - var hasTangents = false; - var hasMorphTargets = false; - var morphTargets; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - var targets = primitive.targets; - if (!hasMorphTargets && defined(targets)) { - hasMorphTargets = true; - morphTargets = targets; - } - var attributes = primitive.attributes; - for (var attribute in attributes) { - if (attribute.indexOf('TANGENT') >= 0) { - hasTangents = true; - } - } - }); + return new GeometryInstance({ + id : entity, + geometry : new PlaneOutlineGeometry(), + modelMatrix : modelMatrix, + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } }); + }; - // Add techniques - var techniqueParameters = { - // Add matrices - modelViewMatrix : { - semantic : hasCesiumRTCExtension ? 'CESIUM_RTC_MODELVIEW' : 'MODELVIEW', - type : WebGLConstants.FLOAT_MAT4 - }, - projectionMatrix : { - semantic : 'PROJECTION', - type : WebGLConstants.FLOAT_MAT4 - } - }; + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + PlaneGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - if (hasNormals) { - techniqueParameters.normalMatrix = { - semantic : 'MODELVIEWINVERSETRANSPOSE', - type : WebGLConstants.FLOAT_MAT3 - }; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + PlaneGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; + + PlaneGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'plane')) { + return; } + var planeGraphics = this._entity.plane; - if (hasSkinning) { - techniqueParameters.jointMatrix = { - count : jointCount, - semantic : 'JOINTMATRIX', - type : WebGLConstants.FLOAT_MAT4 - }; + if (!defined(planeGraphics)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; } - if (hasMorphTargets) { - techniqueParameters.morphWeights = { - count : morphTargets.length, - semantic : 'MORPHWEIGHTS', - type : WebGLConstants.FLOAT - }; + var fillProperty = planeGraphics.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = planeGraphics.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); } - // Add material parameters - var hasTexCoords = false; - for (var name in parameterValues) { - //generate shader parameters - if (parameterValues.hasOwnProperty(name)) { - var valType = getPBRValueType(name); - if (!hasTexCoords && (valType === WebGLConstants.SAMPLER_2D)) { - hasTexCoords = true; - } - techniqueParameters[name] = { - type : valType - }; + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); } + return; } - // Generate uniforms object before attributes are added - var techniqueUniforms = {}; - for (var paramName in techniqueParameters) { - if (techniqueParameters.hasOwnProperty(paramName) && paramName !== 'extras') { - var param = techniqueParameters[paramName]; - techniqueUniforms['u_' + paramName] = paramName; - var arraySize = defined(param.count) ? '[' + param.count + ']' : ''; - if (((param.type !== WebGLConstants.FLOAT_MAT3) && (param.type !== WebGLConstants.FLOAT_MAT4) && (paramName !== 'morphWeights')) || - param.useInFragment) { - fragmentShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; - delete param.useInFragment; - } else { - vertexShader += 'uniform ' + webGLConstantToGlslType(param.type) + ' u_' + paramName + arraySize + ';\n'; - } + var plane = planeGraphics.plane; + var dimensions = planeGraphics.dimensions; + var position = entity.position; + + var show = planeGraphics.show; + if (!defined(plane) || !defined(dimensions) || !defined(position) || (defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); } + return; } - // Add attributes with semantics - var vertexShaderMain = ''; - if (hasSkinning) { - var i, j; - var numberOfComponents = numberOfComponentsForType(skinningInfo.type); - var matrix = false; - if (skinningInfo.type.indexOf('MAT') === 0) { - matrix = true; - numberOfComponents = Math.sqrt(numberOfComponents); - } - if (!matrix) { - for (i = 0; i < numberOfComponents; i++) { - if (i === 0) { - vertexShaderMain += ' mat4 skinMatrix = '; - } else { - vertexShaderMain += ' skinMatrix += '; - } - vertexShaderMain += 'a_weight[' + i + '] * u_jointMatrix[int(a_joint[' + i + '])];\n'; - } - } else { - for (i = 0; i < numberOfComponents; i++) { - for (j = 0; j < numberOfComponents; j++) { - if (i === 0 && j === 0) { - vertexShaderMain += ' mat4 skinMatrix = '; - } else { - vertexShaderMain += ' skinMatrix += '; - } - vertexShaderMain += 'a_weight[' + i + '][' + j + '] * u_jointMatrix[int(a_joint[' + i + '][' + j + '])];\n'; - } - } + var material = defaultValue(planeGraphics.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(planeGraphics.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(planeGraphics.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(planeGraphics.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(planeGraphics.distanceDisplayCondition, defaultDistanceDisplayCondition); + + var outlineWidth = planeGraphics.outlineWidth; + + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; + + if (!position.isConstant || // + !Property.isConstant(entity.orientation) || // + !plane.isConstant || // + !dimensions.isConstant || // + !Property.isConstant(outlineWidth)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.plane = plane.getValue(Iso8601.MINIMUM_VALUE, options.plane); + options.dimensions = dimensions.getValue(Iso8601.MINIMUM_VALUE, options.dimensions); + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); } + }; - // Add position always - var techniqueAttributes = { - a_position : 'position' - }; - techniqueParameters.position = { - semantic : 'POSITION', - type : WebGLConstants.FLOAT_VEC3 - }; - vertexShader += 'attribute vec3 a_position;\n'; - vertexShader += 'varying vec3 v_positionEC;\n'; - if (optimizeForCesium) { - vertexShader += 'varying vec3 v_positionWC;\n'; + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + PlaneGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } - // Morph Target Weighting - vertexShaderMain += ' vec3 weightedPosition = a_position;\n'; - if (hasNormals) { - vertexShaderMain += ' vec3 weightedNormal = a_normal;\n'; - } - if (hasTangents) { - vertexShaderMain += ' vec3 weightedTangent = a_tangent;\n'; - } - if (hasMorphTargets) { - for (var k = 0; k < morphTargets.length; k++) { - var targetAttributes = morphTargets[k]; - for (var targetAttribute in targetAttributes) { - if (targetAttributes.hasOwnProperty(targetAttribute) && targetAttribute !== 'extras') { - var attributeLower = targetAttribute.toLowerCase() + '_' + k; - techniqueAttributes['a_' + attributeLower] = attributeLower; - techniqueParameters[attributeLower] = { - semantic : targetAttribute + '_' + k, - type : WebGLConstants.FLOAT_VEC3 - }; - vertexShader += 'attribute vec3 a_' + attributeLower + ';\n'; - if (targetAttribute === 'POSITION') { - vertexShaderMain += ' weightedPosition += u_morphWeights[' + k + '] * a_' + attributeLower + ';\n'; - } else if (targetAttribute === 'NORMAL') { - vertexShaderMain += ' weightedNormal += u_morphWeights[' + k + '] * a_' + attributeLower + ';\n'; - } else if (targetAttribute === 'TANGENT') { - vertexShaderMain += ' weightedTangent += u_morphWeights[' + k + '] * a_' + attributeLower + ';\n'; - } - } - } - } + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); } + + return new DynamicGeometryUpdater(primitives, this); + }; - // Final position computation - if (hasSkinning) { - vertexShaderMain += ' vec4 position = skinMatrix * vec4(weightedPosition, 1.0);\n'; - } else { - vertexShaderMain += ' vec4 position = vec4(weightedPosition, 1.0);\n'; + /** + * @private + */ + function DynamicGeometryUpdater(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - if (optimizeForCesium) { - vertexShaderMain += ' v_positionWC = (czm_model * position).xyz;\n'; + + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._primitive = undefined; + this._outlinePrimitive = undefined; + + var geometryUpdater = this._geometryUpdater; + var entity = geometryUpdater._entity; + var planeGraphics = entity.plane; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(planeGraphics.show, time, true)) { + return; } - vertexShaderMain += ' position = u_modelViewMatrix * position;\n'; - vertexShaderMain += ' v_positionEC = position.xyz;\n'; - vertexShaderMain += ' gl_Position = u_projectionMatrix * position;\n'; - fragmentShader += 'varying vec3 v_positionEC;\n'; - if (optimizeForCesium) { - fragmentShader += 'varying vec3 v_positionWC;\n'; + + var options = this._options; + var modelMatrix = entity.computeModelMatrix(time); + var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane); + var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions); + if (!defined(modelMatrix) || !defined(plane) || !defined(dimensions)) { + return; } - // Final normal computation - if (hasNormals) { - techniqueAttributes.a_normal = 'normal'; - techniqueParameters.normal = { - semantic : 'NORMAL', - type : WebGLConstants.FLOAT_VEC3 - }; - vertexShader += 'attribute vec3 a_normal;\n'; - vertexShader += 'varying vec3 v_normal;\n'; - if (hasSkinning) { - vertexShaderMain += ' v_normal = u_normalMatrix * mat3(skinMatrix) * weightedNormal;\n'; - } else { - vertexShaderMain += ' v_normal = u_normalMatrix * weightedNormal;\n'; - } + options.plane = plane; + options.dimensions = dimensions; - fragmentShader += 'varying vec3 v_normal;\n'; - } + modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, modelMatrix); - // Read tangents if available - if (hasTangents) { - techniqueAttributes.a_tangent = 'tangent'; - techniqueParameters.tangent = { - semantic : 'TANGENT', - type : WebGLConstants.FLOAT_VEC3 - }; - vertexShader += 'attribute vec3 a_tangent;\n'; - vertexShader += 'varying vec3 v_tangent;\n'; - vertexShaderMain += ' v_tangent = (u_modelViewMatrix * vec4(weightedTangent, 1.0)).xyz;\n'; + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); - fragmentShader += 'varying vec3 v_tangent;\n'; - } + var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; + var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - // Add texture coordinates if the material uses them - var v_texcoord; - if (hasTexCoords) { - techniqueAttributes.a_texcoord_0 = 'texcoord_0'; - techniqueParameters.texcoord_0 = { - semantic : 'TEXCOORD_0', - type : WebGLConstants.FLOAT_VEC2 - }; + if (Property.getValueOrDefault(planeGraphics.fill, time, true)) { + var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + this._material = material; - v_texcoord = 'v_texcoord_0'; - vertexShader += 'attribute vec2 a_texcoord_0;\n'; - vertexShader += 'varying vec2 ' + v_texcoord + ';\n'; - vertexShaderMain += ' ' + v_texcoord + ' = a_texcoord_0;\n'; + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; - fragmentShader += 'varying vec2 ' + v_texcoord + ';\n'; + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PlaneGeometry(), + modelMatrix : modelMatrix, + attributes : { + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); } - // Add skinning information if available - if (hasSkinning) { - techniqueAttributes.a_joint = 'joint'; - var attributeType = getShaderVariable(skinningInfo.type); - var webGLConstant = glslTypeToWebGLConstant(attributeType); + if (Property.getValueOrDefault(planeGraphics.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - techniqueParameters.joint = { - semantic : 'JOINTS_0', - type : webGLConstant - }; - techniqueAttributes.a_weight = 'weight'; - techniqueParameters.weight = { - semantic : 'WEIGHTS_0', - type : webGLConstant - }; + var outlineColor = Property.getValueOrClonedDefault(planeGraphics.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(planeGraphics.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; - vertexShader += 'attribute ' + attributeType + ' a_joint;\n'; - vertexShader += 'attribute ' + attributeType + ' a_weight;\n'; + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PlaneOutlineGeometry(), + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : distanceDisplayConditionAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); } + }; - if (addBatchIdToGeneratedShaders) { - techniqueAttributes.a_batchId = 'batchId'; - techniqueParameters.batchId = { - semantic: '_BATCHID', - type: WebGLConstants.FLOAT - }; - vertexShader += 'attribute float a_batchId;\n'; + var scratchTranslation = new Cartesian3(); + var scratchNormal = new Cartesian3(); + var scratchScale = new Cartesian3(); + function createPrimitiveMatrix (plane, dimensions, modelMatrix, result) { + var normal; + var distance; + if (defined(plane)) { + normal = plane.normal; + distance = plane.distance; + } else { + normal = Cartesian3.clone(Cartesian3.UNIT_X, scratchNormal); + distance = 0.0; } - vertexShader += 'void main(void) \n{\n'; - vertexShader += vertexShaderMain; - vertexShader += '}\n'; + if (!defined(dimensions)) { + dimensions = new Cartesian2(1.0, 1.0); + } - // Fragment shader lighting - fragmentShader += 'const float M_PI = 3.141592653589793;\n'; + var translation = Cartesian3.multiplyByScalar(normal, -distance, scratchTranslation); + translation = Matrix4.multiplyByPoint(modelMatrix, translation, translation); - fragmentShader += 'vec3 lambertianDiffuse(vec3 baseColor) \n' + - '{\n' + - ' return baseColor / M_PI;\n' + - '}\n\n'; + var transformedNormal = Matrix4.multiplyByPointAsVector(modelMatrix, normal, scratchNormal); + Cartesian3.normalize(transformedNormal, transformedNormal); + var rotation = getRotationMatrix(transformedNormal, Cartesian3.UNIT_Z); - fragmentShader += 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' + - '{\n' + - ' return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);\n' + - '}\n\n'; + var scale = Cartesian2.clone(dimensions, scratchScale); + scale.z = 1.0; - fragmentShader += 'vec3 fresnelSchlick(float metalness, float VdotH) \n' + - '{\n' + - ' return metalness + (vec3(1.0) - metalness) * pow(1.0 - VdotH, 5.0);\n' + - '}\n\n'; + return Matrix4.fromTranslationQuaternionRotationScale(translation, rotation, scale, result); + } - fragmentShader += 'float smithVisibilityG1(float NdotV, float roughness) \n' + - '{\n' + - ' float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n' + - ' return NdotV / (NdotV * (1.0 - k) + k);\n' + - '}\n\n'; + // get a rotation according to a normal + var scratchAxis = new Cartesian3(); + var scratchQuaternion = new Quaternion(); + function getRotationMatrix(direction, up) { + var angle = Cartesian3.angleBetween(direction, up); + if (angle === 0.0) { + return Quaternion.clone(Quaternion.IDENTITY, scratchQuaternion); + } - fragmentShader += 'float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n' + - '{\n' + - ' return smithVisibilityG1(NdotL, roughness) * smithVisibilityG1(NdotV, roughness);\n' + - '}\n\n'; + var axis = Cartesian3.cross(up, direction, scratchAxis); + return Quaternion.fromAxisAngle(axis, angle, scratchQuaternion); + } - fragmentShader += 'float GGX(float roughness, float NdotH) \n' + - '{\n' + - ' float roughnessSquared = roughness * roughness;\n' + - ' float f = (NdotH * roughnessSquared - NdotH) * NdotH + 1.0;\n' + - ' return roughnessSquared / (M_PI * f * f);\n' + - '}\n\n'; + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; - fragmentShader += 'void main(void) \n{\n'; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - // Add normal mapping to fragment shader - if (hasNormals) { - fragmentShader += ' vec3 ng = normalize(v_normal);\n'; - if (defined(parameterValues.normalTexture)) { - if (hasTangents) { - // Read tangents from varying - fragmentShader += ' vec3 t = normalize(v_tangent);\n'; - fragmentShader += ' vec3 b = normalize(cross(ng, t));\n'; - fragmentShader += ' mat3 tbn = mat3(t, b, ng);\n'; - fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + v_texcoord + ').rgb;\n'; - fragmentShader += ' n = normalize(tbn * (2.0 * n - 1.0));\n'; - } else { - // Add standard derivatives extension - fragmentShader = '#ifdef GL_OES_standard_derivatives\n' + - '#extension GL_OES_standard_derivatives : enable\n' + - '#endif\n' + - fragmentShader; - // Compute tangents - fragmentShader += '#ifdef GL_OES_standard_derivatives\n'; - fragmentShader += ' vec3 pos_dx = dFdx(v_positionEC);\n'; - fragmentShader += ' vec3 pos_dy = dFdy(v_positionEC);\n'; - fragmentShader += ' vec3 tex_dx = dFdx(vec3(' + v_texcoord + ',0.0));\n'; - fragmentShader += ' vec3 tex_dy = dFdy(vec3(' + v_texcoord + ',0.0));\n'; - fragmentShader += ' vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n'; - fragmentShader += ' t = normalize(t - ng * dot(ng, t));\n'; - fragmentShader += ' vec3 b = normalize(cross(ng, t));\n'; - fragmentShader += ' mat3 tbn = mat3(t, b, ng);\n'; - fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + v_texcoord + ').rgb;\n'; - fragmentShader += ' n = normalize(tbn * (2.0 * n - 1.0));\n'; - fragmentShader += '#else\n'; - fragmentShader += ' vec3 n = ng;\n'; - fragmentShader += '#endif\n'; - } - } else { - fragmentShader += ' vec3 n = ng;\n'; - } - if (parameterValues.doubleSided) { - fragmentShader += ' if (!gl_FrontFacing)\n'; - fragmentShader += ' {\n'; - fragmentShader += ' n = -n;\n'; - fragmentShader += ' }\n'; - } - } + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; - // Add base color to fragment shader - if (defined(parameterValues.baseColorTexture)) { - fragmentShader += ' vec4 baseColorWithAlpha = texture2D(u_baseColorTexture, ' + v_texcoord + ');\n'; - if (defined(parameterValues.baseColorFactor)) { - fragmentShader += ' baseColorWithAlpha *= u_baseColorFactor;\n'; - } - } else { - if (defined(parameterValues.baseColorFactor)) { - fragmentShader += ' vec4 baseColorWithAlpha = u_baseColorFactor;\n'; - } else { - fragmentShader += ' vec4 baseColorWithAlpha = vec4(1.0);\n'; - } - } - fragmentShader += ' vec3 baseColor = baseColorWithAlpha.rgb;\n'; - // Add metallic-roughness to fragment shader - if (defined(parameterValues.metallicRoughnessTexture)) { - fragmentShader += ' vec3 metallicRoughness = texture2D(u_metallicRoughnessTexture, ' + v_texcoord + ').rgb;\n'; - fragmentShader += ' float metalness = clamp(metallicRoughness.b, 0.0, 1.0);\n'; - fragmentShader += ' float roughness = clamp(metallicRoughness.g, 0.04, 1.0);\n'; - if (defined(parameterValues.metallicFactor)) { - fragmentShader += ' metalness *= u_metallicFactor;\n'; - } - if (defined(parameterValues.roughnessFactor)) { - fragmentShader += ' roughness *= u_roughnessFactor;\n'; - } - } else { - if (defined(parameterValues.metallicFactor)) { - fragmentShader += ' float metalness = clamp(u_metallicFactor, 0.0, 1.0);\n'; - } else { - fragmentShader += ' float metalness = 1.0;\n'; - } - if (defined(parameterValues.roughnessFactor)) { - fragmentShader += ' float roughness = clamp(u_roughnessFactor, 0.04, 1.0);\n'; - } else { - fragmentShader += ' float roughness = 1.0;\n'; + return PlaneGeometryUpdater; +}); + +define('Scene/createBillboardPointCallback',[],function() { + 'use strict'; + + /** + * Creates a {@link createBillboardPointCallback~CanvasFunction} that will create a canvas with a point. + * + * @param {Number} centerAlpha The alpha of the center of the point. The value must be in the range [0.0, 1.0]. + * @param {String} cssColor The CSS color string. + * @param {String} cssOutlineColor The CSS color of the point outline. + * @param {Number} cssOutlineWidth The width of the outline in pixels. + * @param {Number} pixelSize The size of the point in pixels. + * @return {createBillboardPointCallback~CanvasFunction} The function that will return a canvas with the point drawn on it. + * + * @private + */ + function createBillboardPointCallback(centerAlpha, cssColor, cssOutlineColor, cssOutlineWidth, pixelSize) { + return function() { + var canvas = document.createElement('canvas'); + + var length = pixelSize + (2 * cssOutlineWidth); + canvas.height = canvas.width = length; + + var context2D = canvas.getContext('2d'); + context2D.clearRect(0, 0, length, length); + + if (cssOutlineWidth !== 0) { + context2D.beginPath(); + context2D.arc(length / 2, length / 2, length / 2, 0, 2 * Math.PI, true); + context2D.closePath(); + context2D.fillStyle = cssOutlineColor; + context2D.fill(); + // Punch a hole in the center if needed. + if (centerAlpha < 1.0) { + context2D.save(); + context2D.globalCompositeOperation = 'destination-out'; + context2D.beginPath(); + context2D.arc(length / 2, length / 2, pixelSize / 2, 0, 2 * Math.PI, true); + context2D.closePath(); + context2D.fillStyle = 'black'; + context2D.fill(); + context2D.restore(); + } } - } - fragmentShader += ' vec3 v = -normalize(v_positionEC);\n'; - // Generate fragment shader's lighting block - fragmentShader += ' vec3 lightColor = vec3(1.0, 1.0, 1.0);\n'; - if (optimizeForCesium) { - fragmentShader += ' vec3 l = normalize(czm_sunDirectionEC);\n'; - } else { - fragmentShader += ' vec3 l = vec3(0.0, 0.0, 1.0);\n'; - } - fragmentShader += ' vec3 h = normalize(v + l);\n'; - if (optimizeForCesium) { - fragmentShader += ' vec3 r = normalize(czm_inverseViewRotation * normalize(reflect(v, n)));\n'; - // Figure out if the reflection vector hits the ellipsoid - fragmentShader += ' czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\n'; - fragmentShader += ' float vertexRadius = length(v_positionWC);\n'; - fragmentShader += ' float horizonDotNadir = 1.0 - ellipsoid.radii.x / vertexRadius;\n'; - fragmentShader += ' float reflectionDotNadir = dot(r, normalize(v_positionWC));\n'; - // Flipping the X vector is a cheap way to get the inverse of czm_temeToPseudoFixed, since that's a rotation about Z. - fragmentShader += ' r.x = -r.x;\n'; - fragmentShader += ' r = -normalize(czm_temeToPseudoFixed * r);\n'; - fragmentShader += ' r.x = -r.x;\n'; - } else { - fragmentShader += ' vec3 r = normalize(reflect(v, n));\n'; - } - fragmentShader += ' float NdotL = clamp(dot(n, l), 0.001, 1.0);\n'; - fragmentShader += ' float NdotV = abs(dot(n, v)) + 0.001;\n'; - fragmentShader += ' float NdotH = clamp(dot(n, h), 0.0, 1.0);\n'; - fragmentShader += ' float LdotH = clamp(dot(l, h), 0.0, 1.0);\n'; - fragmentShader += ' float VdotH = clamp(dot(v, h), 0.0, 1.0);\n'; + context2D.beginPath(); + context2D.arc(length / 2, length / 2, pixelSize / 2, 0, 2 * Math.PI, true); + context2D.closePath(); + context2D.fillStyle = cssColor; + context2D.fill(); - fragmentShader += ' vec3 f0 = vec3(0.04);\n'; - fragmentShader += ' float alpha = roughness * roughness;\n'; - fragmentShader += ' vec3 diffuseColor = baseColor * (1.0 - metalness);\n'; - fragmentShader += ' vec3 specularColor = mix(f0, baseColor, metalness);\n'; - fragmentShader += ' float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n'; - fragmentShader += ' vec3 r90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));\n'; - fragmentShader += ' vec3 r0 = specularColor.rgb;\n'; + return canvas; + }; + } - fragmentShader += ' vec3 F = fresnelSchlick2(r0, r90, VdotH);\n'; - fragmentShader += ' float G = smithVisibilityGGX(alpha, NdotL, NdotV);\n'; - fragmentShader += ' float D = GGX(alpha, NdotH);\n'; + /** + * A function that returns a canvas containing an image of a point. + * @callback createBillboardPointCallback~CanvasFunction + * @returns {HTMLCanvasElement} The result of the calculation. + */ - fragmentShader += ' vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(baseColor);\n'; - fragmentShader += ' vec3 specularContribution = F * G * D / (4.0 * NdotL * NdotV);\n'; - fragmentShader += ' vec3 color = NdotL * lightColor * (diffuseContribution + specularContribution);\n'; + return createBillboardPointCallback; +}); - if (optimizeForCesium) { - fragmentShader += ' float inverseRoughness = 1.0 - roughness;\n'; - fragmentShader += ' inverseRoughness *= inverseRoughness;\n'; - fragmentShader += ' vec3 sceneSkyBox = textureCube(czm_environmentMap, r).rgb * inverseRoughness;\n'; +define('DataSources/PointVisualizer',[ + '../Core/AssociativeArray', + '../Core/Cartesian3', + '../Core/Color', + '../Core/defined', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/NearFarScalar', + '../Scene/createBillboardPointCallback', + '../Scene/HeightReference', + './BoundingSphereState', + './Property' + ], function( + AssociativeArray, + Cartesian3, + Color, + defined, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + NearFarScalar, + createBillboardPointCallback, + HeightReference, + BoundingSphereState, + Property) { + 'use strict'; - fragmentShader += ' float atmosphereHeight = 0.05;\n'; - fragmentShader += ' float blendRegionSize = 0.1 * ((1.0 - inverseRoughness) * 8.0 + 1.1 - horizonDotNadir);\n'; - fragmentShader += ' float farAboveHorizon = clamp(horizonDotNadir - blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n'; - fragmentShader += ' float aroundHorizon = clamp(horizonDotNadir + blendRegionSize * 0.5, 1.0e-10 - blendRegionSize, 0.99999);\n'; - fragmentShader += ' float farBelowHorizon = clamp(horizonDotNadir + blendRegionSize * 1.5, 1.0e-10 - blendRegionSize, 0.99999);\n'; - fragmentShader += ' float smoothstepHeight = smoothstep(0.0, atmosphereHeight, horizonDotNadir);\n'; - fragmentShader += ' float lightScale = smoothstepHeight * 1.5 + 1.0;\n'; + var defaultColor = Color.WHITE; + var defaultOutlineColor = Color.BLACK; + var defaultOutlineWidth = 0.0; + var defaultPixelSize = 1.0; + var defaultDisableDepthTestDistance = 0.0; - fragmentShader += ' vec3 diffuseIrradiance = mix(vec3(0.5), vec3(0.05), smoothstepHeight);\n'; - fragmentShader += ' vec3 belowHorizonColor = mix(vec3(0.1, 0.2, 0.4), vec3(0.2, 0.5, 0.7), smoothstepHeight);\n'; - fragmentShader += ' vec3 nadirColor = belowHorizonColor * 0.5;\n'; - fragmentShader += ' vec3 aboveHorizonColor = vec3(0.8, 0.9, 0.95);\n'; - fragmentShader += ' vec3 blueSkyColor = mix(vec3(0.09, 0.13, 0.24), aboveHorizonColor, reflectionDotNadir * inverseRoughness * 0.5 + 0.5);\n'; - fragmentShader += ' vec3 zenithColor = mix(blueSkyColor, sceneSkyBox, smoothstepHeight);\n'; + var color = new Color(); + var position = new Cartesian3(); + var outlineColor = new Color(); + var scaleByDistance = new NearFarScalar(); + var translucencyByDistance = new NearFarScalar(); + var distanceDisplayCondition = new DistanceDisplayCondition(); - fragmentShader += ' vec3 specularIrradiance = mix(zenithColor, aboveHorizonColor, smoothstep(farAboveHorizon, aroundHorizon, reflectionDotNadir) * inverseRoughness);\n'; - fragmentShader += ' specularIrradiance = mix(specularIrradiance, belowHorizonColor, smoothstep(aroundHorizon, farBelowHorizon, reflectionDotNadir) * inverseRoughness);\n'; - fragmentShader += ' specularIrradiance = mix(specularIrradiance, nadirColor, smoothstep(farBelowHorizon, 1.0, reflectionDotNadir) * inverseRoughness);\n'; + function EntityData(entity) { + this.entity = entity; + this.pointPrimitive = undefined; + this.billboard = undefined; + this.color = undefined; + this.outlineColor = undefined; + this.pixelSize = undefined; + this.outlineWidth = undefined; + } - fragmentShader += ' vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n'; - fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * (specularColor * brdfLut.x + brdfLut.y));\n'; - fragmentShader += ' color = color * lightScale + IBLColor;\n'; + /** + * A {@link Visualizer} which maps {@link Entity#point} to a {@link PointPrimitive}. + * @alias PointVisualizer + * @constructor + * + * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities. + * @param {EntityCollection} entityCollection The entityCollection to visualize. + */ + function PointVisualizer(entityCluster, entityCollection) { + if (!defined(entityCluster)) { + throw new DeveloperError('entityCluster is required.'); + } + if (!defined(entityCollection)) { + throw new DeveloperError('entityCollection is required.'); } + + entityCollection.collectionChanged.addEventListener(PointVisualizer.prototype._onCollectionChanged, this); - if (defined(parameterValues.occlusionTexture)) { - fragmentShader += ' color *= texture2D(u_occlusionTexture, ' + v_texcoord + ').r;\n'; + this._cluster = entityCluster; + this._entityCollection = entityCollection; + this._items = new AssociativeArray(); + this._onCollectionChanged(entityCollection, entityCollection.values, [], []); + } + + /** + * Updates the primitives created by this visualizer to match their + * Entity counterpart at the given time. + * + * @param {JulianDate} time The time to update to. + * @returns {Boolean} This function always returns true. + */ + PointVisualizer.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - if (defined(parameterValues.emissiveTexture)) { - fragmentShader += ' vec3 emissive = texture2D(u_emissiveTexture, ' + v_texcoord + ').rgb;\n'; - if (defined(parameterValues.emissiveFactor)) { - fragmentShader += ' emissive *= u_emissiveFactor;\n'; + + var items = this._items.values; + var cluster = this._cluster; + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + var entity = item.entity; + var pointGraphics = entity._point; + var pointPrimitive = item.pointPrimitive; + var billboard = item.billboard; + var heightReference = Property.getValueOrDefault(pointGraphics._heightReference, time, HeightReference.NONE); + var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(pointGraphics._show, time, true); + if (show) { + position = Property.getValueOrUndefined(entity._position, time, position); + show = defined(position); } - fragmentShader += ' color += emissive;\n'; - } - else { - if (defined(parameterValues.emissiveFactor)) { - fragmentShader += ' color += u_emissiveFactor;\n'; + if (!show) { + returnPrimitive(item, entity, cluster); + continue; } - } - // Final color - var alphaMode = material.alphaMode; - if (defined(alphaMode)) { - if (alphaMode === 'MASK') { - var alphaCutoff = material.alphaCutoff; - if (defined(alphaCutoff)) { - fragmentShader += ' gl_FragColor = vec4(color, int(baseColorWithAlpha.a >= ' + alphaCutoff + '));\n'; - } else { - fragmentShader += ' gl_FragColor = vec4(color, 1.0);\n'; - } - } else if (alphaMode === 'BLEND') { - fragmentShader += ' gl_FragColor = vec4(color, baseColorWithAlpha.a);\n'; - } else { - fragmentShader += ' gl_FragColor = vec4(color, 1.0);\n'; + if (!Property.isConstant(entity._position)) { + cluster._clusterDirty = true; } - } else { - fragmentShader += ' gl_FragColor = vec4(color, 1.0);\n'; - } - fragmentShader += '}\n'; - var techniqueStates; - if (defined(alphaMode) && alphaMode !== 'OPAQUE') { - techniqueStates = { - enable: [ - WebGLConstants.DEPTH_TEST, - WebGLConstants.BLEND - ], - functions: { - depthMask : [false], - blendEquationSeparate: [ - WebGLConstants.FUNC_ADD, - WebGLConstants.FUNC_ADD - ], - blendFuncSeparate: [ - WebGLConstants.ONE, - WebGLConstants.ONE_MINUS_SRC_ALPHA, - WebGLConstants.ONE, - WebGLConstants.ONE_MINUS_SRC_ALPHA - ] + var needsRedraw = false; + if ((heightReference !== HeightReference.NONE) && !defined(billboard)) { + if (defined(pointPrimitive)) { + returnPrimitive(item, entity, cluster); + pointPrimitive = undefined; } - }; - } else if (parameterValues.doubleSided) { - techniqueStates = { - enable : [ - WebGLConstants.DEPTH_TEST - ] - }; - } else { - techniqueStates = { - enable : [ - WebGLConstants.CULL_FACE, - WebGLConstants.DEPTH_TEST - ] - }; - } - // Add shaders - var vertexShaderId = addToArray(shaders, { - type : WebGLConstants.VERTEX_SHADER, - extras : { - _pipeline : { - source : vertexShader, - extension : '.glsl' + billboard = cluster.getBillboard(entity); + billboard.id = entity; + billboard.image = undefined; + item.billboard = billboard; + needsRedraw = true; + } else if ((heightReference === HeightReference.NONE) && !defined(pointPrimitive)) { + if (defined(billboard)) { + returnPrimitive(item, entity, cluster); + billboard = undefined; } + + pointPrimitive = cluster.getPoint(entity); + pointPrimitive.id = entity; + item.pointPrimitive = pointPrimitive; } - }); - var fragmentShaderId = addToArray(shaders, { - type : WebGLConstants.FRAGMENT_SHADER, - extras : { - _pipeline : { - source : fragmentShader, - extension : '.glsl' + if (defined(pointPrimitive)) { + pointPrimitive.show = true; + pointPrimitive.position = position; + pointPrimitive.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance); + pointPrimitive.translucencyByDistance = Property.getValueOrUndefined(pointGraphics._translucencyByDistance, time, translucencyByDistance); + pointPrimitive.color = Property.getValueOrDefault(pointGraphics._color, time, defaultColor, color); + pointPrimitive.outlineColor = Property.getValueOrDefault(pointGraphics._outlineColor, time, defaultOutlineColor, outlineColor); + pointPrimitive.outlineWidth = Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth); + pointPrimitive.pixelSize = Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize); + pointPrimitive.distanceDisplayCondition = Property.getValueOrUndefined(pointGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + pointPrimitive.disableDepthTestDistance = Property.getValueOrDefault(pointGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); + } else if (defined(billboard)) { + billboard.show = true; + billboard.position = position; + billboard.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance); + billboard.translucencyByDistance = Property.getValueOrUndefined(pointGraphics._translucencyByDistance, time, translucencyByDistance); + billboard.distanceDisplayCondition = Property.getValueOrUndefined(pointGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + billboard.disableDepthTestDistance = Property.getValueOrDefault(pointGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); + billboard.heightReference = heightReference; + + var newColor = Property.getValueOrDefault(pointGraphics._color, time, defaultColor, color); + var newOutlineColor = Property.getValueOrDefault(pointGraphics._outlineColor, time, defaultOutlineColor, outlineColor); + var newOutlineWidth = Math.round(Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth)); + var newPixelSize = Math.max(1, Math.round(Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize))); + + if (newOutlineWidth > 0) { + billboard.scale = 1.0; + needsRedraw = needsRedraw || // + newOutlineWidth !== item.outlineWidth || // + newPixelSize !== item.pixelSize || // + !Color.equals(newColor, item.color) || // + !Color.equals(newOutlineColor, item.outlineColor); + } else { + billboard.scale = newPixelSize / 50.0; + newPixelSize = 50.0; + needsRedraw = needsRedraw || // + newOutlineWidth !== item.outlineWidth || // + !Color.equals(newColor, item.color) || // + !Color.equals(newOutlineColor, item.outlineColor); } - } - }); - // Add program - var programAttributes = Object.keys(techniqueAttributes); - var programId = addToArray(programs, { - attributes : programAttributes, - fragmentShader : fragmentShaderId, - vertexShader : vertexShaderId - }); + if (needsRedraw) { + item.color = Color.clone(newColor, item.color); + item.outlineColor = Color.clone(newOutlineColor, item.outlineColor); + item.pixelSize = newPixelSize; + item.outlineWidth = newOutlineWidth; - var techniqueId = addToArray(techniques, { - attributes : techniqueAttributes, - parameters : techniqueParameters, - program : programId, - states : techniqueStates, - uniforms : techniqueUniforms - }); + var centerAlpha = newColor.alpha; + var cssColor = newColor.toCssColorString(); + var cssOutlineColor = newOutlineColor.toCssColorString(); + var textureId = JSON.stringify([cssColor, newPixelSize, cssOutlineColor, newOutlineWidth]); - return techniqueId; - } + billboard.setImage(textureId, createBillboardPointCallback(centerAlpha, cssColor, cssOutlineColor, newOutlineWidth, newPixelSize)); + } + } + } + return true; + }; - function getPBRValueType(paramName) { - switch (paramName) { - case 'baseColorFactor': - return WebGLConstants.FLOAT_VEC4; - case 'metallicFactor': - return WebGLConstants.FLOAT; - case 'roughnessFactor': - return WebGLConstants.FLOAT; - case 'baseColorTexture': - return WebGLConstants.SAMPLER_2D; - case 'metallicRoughnessTexture': - return WebGLConstants.SAMPLER_2D; - case 'normalTexture': - return WebGLConstants.SAMPLER_2D; - case 'occlusionTexture': - return WebGLConstants.SAMPLER_2D; - case 'emissiveTexture': - return WebGLConstants.SAMPLER_2D; - case 'emissiveFactor': - return WebGLConstants.FLOAT_VEC3; - case 'doubleSided': - return WebGLConstants.BOOL; + /** + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. + * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private + */ + PointVisualizer.prototype.getBoundingSphere = function(entity, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); } - } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var item = this._items.get(entity.id); + if (!defined(item) || !(defined(item.pointPrimitive) || defined(item.billboard))) { + return BoundingSphereState.FAILED; + } + + if (defined(item.pointPrimitive)) { + result.center = Cartesian3.clone(item.pointPrimitive.position, result.center); + } else { + var billboard = item.billboard; + if (!defined(billboard._clampedPosition)) { + return BoundingSphereState.PENDING; + } + result.center = Cartesian3.clone(billboard._clampedPosition, result.center); + } + + result.radius = 0; + return BoundingSphereState.DONE; + }; - function getShaderVariable(type) { - if (type === 'SCALAR') { - return 'float'; + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + PointVisualizer.prototype.isDestroyed = function() { + return false; + }; + + /** + * Removes and destroys all primitives created by this instance. + */ + PointVisualizer.prototype.destroy = function() { + this._entityCollection.collectionChanged.removeEventListener(PointVisualizer.prototype._onCollectionChanged, this); + var entities = this._entityCollection.values; + for (var i = 0; i < entities.length; i++) { + this._cluster.removePoint(entities[i]); } - return type.toLowerCase(); - } + return destroyObject(this); + }; - function ensureSemanticExistenceForPrimitive(gltf, primitive) { - var accessors = gltf.accessors; - var materials = gltf.materials; - var techniques = gltf.techniques; - var programs = gltf.programs; - var shaders = gltf.shaders; - var targets = primitive.targets; + PointVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { + var i; + var entity; + var items = this._items; + var cluster = this._cluster; - var attributes = primitive.attributes; - for (var target in targets) { - if (defined(target)) { - var targetAttributes = targets[target]; - for (var attribute in targetAttributes) { - if (attribute !== 'extras') { - attributes[attribute + '_' + target] = targetAttributes[attribute]; - } - } + for (i = added.length - 1; i > -1; i--) { + entity = added[i]; + if (defined(entity._point) && defined(entity._position)) { + items.set(entity.id, new EntityData(entity)); } } - var material = materials[primitive.material]; - var technique = techniques[material.technique]; - var program = programs[technique.program]; - var vertexShader = shaders[program.vertexShader]; - for (var semantic in attributes) { - if (attributes.hasOwnProperty(semantic)) { - if (!defined(techniqueParameterForSemantic(technique, semantic))) { - var accessorId = attributes[semantic]; - var accessor = accessors[accessorId]; - var lowerCase = semantic.toLowerCase(); - if (lowerCase.charAt(0) === '_') { - lowerCase = lowerCase.slice(1); - } - var attributeName = 'a_' + lowerCase; - technique.parameters[lowerCase] = { - semantic: semantic, - type: accessor.componentType - }; - technique.attributes[attributeName] = lowerCase; - program.attributes.push(attributeName); - var pipelineExtras = vertexShader.extras._pipeline; - var shaderText = pipelineExtras.source; - shaderText = 'attribute ' + getShaderVariable(accessor.type) + ' ' + attributeName + ';\n' + shaderText; - pipelineExtras.source = shaderText; + for (i = changed.length - 1; i > -1; i--) { + entity = changed[i]; + if (defined(entity._point) && defined(entity._position)) { + if (!items.contains(entity.id)) { + items.set(entity.id, new EntityData(entity)); } + } else { + returnPrimitive(items.get(entity.id), entity, cluster); + items.remove(entity.id); } } - } - - function ensureSemanticExistence(gltf) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ensureSemanticExistenceForPrimitive(gltf, primitive); - }); - }); - } - - function splitIncompatibleSkins(gltf) { - var accessors = gltf.accessors; - var materials = gltf.materials; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - var materialId = primitive.material; - var material = materials[materialId]; - var jointAccessorId = primitive.attributes.JOINTS_0; - var componentType; - var type; - if (defined(jointAccessorId)) { - var jointAccessor = accessors[jointAccessorId]; - componentType = jointAccessor.componentType; - type = jointAccessor.type; - } - var isSkinned = defined(jointAccessorId); + for (i = removed.length - 1; i > -1; i--) { + entity = removed[i]; + returnPrimitive(items.get(entity.id), entity, cluster); + items.remove(entity.id); + } + }; - var skinningInfo = material.extras._pipeline.skinning; - if (!defined(skinningInfo)) { - material.extras._pipeline.skinning = { - skinned : isSkinned, - componentType : componentType, - type : type - }; - } else if ((skinningInfo.skinned !== isSkinned) || (skinningInfo.type !== type)) { - // This primitive uses the same material as another one that either isn't skinned or uses a different type to store joints and weights - var clonedMaterial = clone(material, true); - clonedMaterial.material.extras._pipeline.skinning = { - skinned : isSkinned, - componentType : componentType, - type : type - }; - // Split this off as a separate material - materialId = addToArray(materials, clonedMaterial); - primitive.material = materialId; - } - }); - }); + function returnPrimitive(item, entity, cluster) { + if (defined(item)) { + var pointPrimitive = item.pointPrimitive; + if (defined(pointPrimitive)) { + item.pointPrimitive = undefined; + cluster.removePoint(entity); + return; + } + var billboard = item.billboard; + if (defined(billboard)) { + item.billboard = undefined; + cluster.removeBillboard(entity); + } + } } - return processPbrMetallicRoughness; + return PointVisualizer; }); -define('Scene/AttributeType',[ - '../Core/freezeObject' +define('DataSources/PolygonGeometryUpdater',[ + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/isArray', + '../Core/Iso8601', + '../Core/oneTimeWarning', + '../Core/PolygonGeometry', + '../Core/PolygonHierarchy', + '../Core/PolygonOutlineGeometry', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/GroundPrimitive', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' ], function( - freezeObject) { + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + isArray, + Iso8601, + oneTimeWarning, + PolygonGeometry, + PolygonHierarchy, + PolygonOutlineGeometry, + ShowGeometryInstanceAttribute, + GroundPrimitive, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { 'use strict'; + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.polygonHierarchy = undefined; + this.perPositionHeight = undefined; + this.closeTop = undefined; + this.closeBottom = undefined; + this.height = undefined; + this.extrudedHeight = undefined; + this.granularity = undefined; + this.stRotation = undefined; + } + /** - * An enum describing the attribute type for glTF and 3D Tiles. - * - * @exports AttributeType + * A {@link GeometryUpdater} for polygons. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias PolygonGeometryUpdater + * @constructor * - * @private + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - var AttributeType = { - /** - * The attribute is a single component. - * - * @type {String} - * @constant - */ - SCALAR : 'SCALAR', + function PolygonGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(PolygonGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._isClosed = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._onTerrain = false; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'polygon', entity.polygon, undefined); + } + defineProperties(PolygonGeometryUpdater, { /** - * The attribute is a two-component vector. - * - * @type {String} - * @constant + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof PolygonGeometryUpdater + * @type {Appearance} */ - VEC2 : 'VEC2', - + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, /** - * The attribute is a three-component vector. - * - * @type {String} - * @constant + * Gets the type of Appearance to use for material-based geometry. + * @memberof PolygonGeometryUpdater + * @type {Appearance} */ - VEC3 : 'VEC3', + materialAppearanceType : { + value : MaterialAppearance + } + }); + defineProperties(PolygonGeometryUpdater.prototype, { /** - * The attribute is a four-component vector. + * Gets the entity associated with this geometry. + * @memberof PolygonGeometryUpdater.prototype * - * @type {String} - * @constant + * @type {Entity} + * @readonly */ - VEC4 : 'VEC4', - + entity : { + get : function() { + return this._entity; + } + }, /** - * The attribute is a 2x2 matrix. + * Gets a value indicating if the geometry has a fill component. + * @memberof PolygonGeometryUpdater.prototype * - * @type {String} - * @constant + * @type {Boolean} + * @readonly */ - MAT2 : 'MAT2', - + fillEnabled : { + get : function() { + return this._fillEnabled; + } + }, /** - * The attribute is a 3x3 matrix. + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof PolygonGeometryUpdater.prototype * - * @type {String} - * @constant + * @type {Boolean} + * @readonly */ - MAT3 : 'MAT3', - + hasConstantFill : { + get : function() { + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); + } + }, /** - * The attribute is a 4x4 matrix. + * Gets the material property used to fill the geometry. + * @memberof PolygonGeometryUpdater.prototype * - * @type {String} - * @constant + * @type {MaterialProperty} + * @readonly */ - MAT4 : 'MAT4' - }; - - return freezeObject(AttributeType); -}); - -define('Scene/Axis',[ - '../Core/Check', - '../Core/freezeObject', - '../Core/Math', - '../Core/Matrix3', - '../Core/Matrix4' - ], function( - Check, - freezeObject, - CesiumMath, - Matrix3, - Matrix4) { - 'use strict'; - - /** - * An enum describing the x, y, and z axes and helper conversion functions. - * - * @exports Axis - * @private - */ - var Axis = { + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, /** - * Denotes the x-axis. + * Gets a value indicating if the geometry has an outline component. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Number} - * @constant + * @type {Boolean} + * @readonly */ - X : 0, - + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, /** - * Denotes the y-axis. + * Gets a value indicating if the geometry has an outline component. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Number} - * @constant + * @type {Boolean} + * @readonly */ - Y : 1, - + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, /** - * Denotes the z-axis. + * Gets the {@link Color} property for the geometry outline. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Number} - * @constant + * @type {Property} + * @readonly */ - Z : 2, - + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, /** - * Matrix used to convert from y-up to z-up + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Matrix4} - * @constant + * @type {Number} + * @readonly */ - Y_UP_TO_Z_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)), - + outlineWidth : { + get : function() { + return this._outlineWidth; + } + }, /** - * Matrix used to convert from z-up to y-up + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Matrix4} - * @constant + * @type {Property} + * @readonly */ - Z_UP_TO_Y_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationX(-CesiumMath.PI_OVER_TWO)), - + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, /** - * Matrix used to convert from x-up to z-up + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Matrix4} - * @constant + * @type {Property} + * @readonly */ - X_UP_TO_Z_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationY(-CesiumMath.PI_OVER_TWO)), - + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayConditionProperty; + } + }, /** - * Matrix used to convert from z-up to x-up + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Matrix4} - * @constant + * @type {Boolean} + * @readonly */ - Z_UP_TO_X_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationY(CesiumMath.PI_OVER_TWO)), - + isDynamic : { + get : function() { + return this._dynamic; + } + }, /** - * Matrix used to convert from x-up to y-up + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Matrix4} - * @constant + * @type {Boolean} + * @readonly */ - X_UP_TO_Y_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationZ(CesiumMath.PI_OVER_TWO)), - + isClosed : { + get : function() { + return this._isClosed; + } + }, /** - * Matrix used to convert from y-up to x-up + * Gets a value indicating if the geometry should be drawn on terrain. + * @memberof PolygonGeometryUpdater.prototype * - * @type {Matrix4} - * @constant + * @type {Boolean} + * @readonly */ - Y_UP_TO_X_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationZ(-CesiumMath.PI_OVER_TWO)), - + onTerrain : { + get : function() { + return this._onTerrain; + } + }, /** - * Gets the axis by name + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof PolygonGeometryUpdater.prototype * - * @param {String} name The name of the axis. - * @returns {Number} The axis enum. + * @type {Boolean} + * @readonly */ - fromName : function(name) { - Check.typeOf.string('name', name); - - return Axis[name]; + geometryChanged : { + get : function() { + return this._geometryChanged; + } } - }; + }); - return freezeObject(Axis); -}); + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + PolygonGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; -define('Scene/getAttributeOrUniformBySemantic',[ - '../Core/defined' - ], function( - defined) { - 'use strict'; + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + PolygonGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; /** - * Return the uniform or attribute that has the given semantic. + * Creates the geometry instance which represents the fill of the geometry. * - * @private + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. */ - function getAttributeOrUniformBySemantic(gltf, semantic) { - var techniques = gltf.techniques; - var parameter; - for (var techniqueName in techniques) { - if (techniques.hasOwnProperty(techniqueName)) { - var technique = techniques[techniqueName]; - var parameters = technique.parameters; - var attributes = technique.attributes; - var uniforms = technique.uniforms; - for (var attributeName in attributes) { - if (attributes.hasOwnProperty(attributeName)) { - parameter = parameters[attributes[attributeName]]; - if (defined(parameter) && parameter.semantic === semantic) { - return attributeName; - } - } - } - for (var uniformName in uniforms) { - if (uniforms.hasOwnProperty(uniformName)) { - parameter = parameters[uniforms[uniformName]]; - if (defined(parameter) && parameter.semantic === semantic) { - return uniformName; - } - } - } - } + PolygonGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - return undefined; - } - return getAttributeOrUniformBySemantic; -}); + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); -define('Scene/JobType',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + } + + return new GeometryInstance({ + id : entity, + geometry : new PolygonGeometry(this._options), + attributes : attributes + }); + }; /** - * @private + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. */ - var JobType = { - TEXTURE : 0, - PROGRAM : 1, - BUFFER : 2, - NUMBER_OF_JOB_TYPES : 3 - }; + PolygonGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - return freezeObject(JobType); -}); + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); -define('Scene/ModelAnimationCache',[ - './AttributeType', - '../Core/Cartesian3', - '../Core/ComponentDatatype', - '../Core/defaultValue', - '../Core/defined', - '../Core/LinearSpline', - '../Core/Matrix4', - '../Core/Quaternion', - '../Core/QuaternionSpline', - '../Core/WebGLConstants', - '../Core/WeightSpline', - '../ThirdParty/GltfPipeline/getAccessorByteStride', - '../ThirdParty/GltfPipeline/numberOfComponentsForType' - ], function( - AttributeType, - Cartesian3, - ComponentDatatype, - defaultValue, - defined, - LinearSpline, - Matrix4, - Quaternion, - QuaternionSpline, - WebGLConstants, - WeightSpline, - getAccessorByteStride, - numberOfComponentsForType) { - 'use strict'; + return new GeometryInstance({ + id : entity, + geometry : new PolygonOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); + }; /** - * @private + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - function ModelAnimationCache() { - } + PolygonGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - var dataUriRegex = /^data\:/i; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + PolygonGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; - function getAccessorKey(model, accessor) { - var gltf = model.gltf; - var buffers = gltf.buffers; - var bufferViews = gltf.bufferViews; + PolygonGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'polygon')) { + return; + } - var bufferView = bufferViews[accessor.bufferView]; - var buffer = buffers[bufferView.buffer]; + var polygon = this._entity.polygon; - var byteOffset = bufferView.byteOffset + accessor.byteOffset; - var byteLength = accessor.count * numberOfComponentsForType(accessor.type); + if (!defined(polygon)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - var uriKey = dataUriRegex.test(buffer.uri) ? '' : buffer.uri; - return model.cacheKey + '//' + uriKey + '/' + byteOffset + '/' + byteLength; - } + var fillProperty = polygon.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; - var cachedAnimationParameters = { - }; + var perPositionHeightProperty = polygon.perPositionHeight; + var perPositionHeightEnabled = defined(perPositionHeightProperty) && (perPositionHeightProperty.isConstant ? perPositionHeightProperty.getValue(Iso8601.MINIMUM_VALUE) : true); - ModelAnimationCache.getAnimationParameterValues = function(model, accessor) { - var key = getAccessorKey(model, accessor); - var values = cachedAnimationParameters[key]; + var outlineProperty = polygon.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } - if (!defined(values)) { - // Cache miss - var gltf = model.gltf; + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - var buffers = gltf.buffers; - var bufferViews = gltf.bufferViews; + var hierarchy = polygon.hierarchy; - var bufferView = bufferViews[accessor.bufferView]; - var bufferId = bufferView.buffer; - var buffer = buffers[bufferId]; - var source = buffer.extras._pipeline.source; + var show = polygon.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(hierarchy))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - var componentType = accessor.componentType; - var type = accessor.type; - var numberOfComponents = numberOfComponentsForType(type); - var count = accessor.count; - var byteStride = getAccessorByteStride(gltf, accessor); + var material = defaultValue(polygon.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(polygon.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(polygon.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(polygon.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(polygon.distanceDisplayCondition, defaultDistanceDisplayCondition); - values = new Array(count); - var accessorByteOffset = defaultValue(accessor.byteOffset, 0); - var byteOffset = bufferView.byteOffset + accessorByteOffset; - for (var i = 0; i < count; i++) { - var typedArrayView = ComponentDatatype.createArrayBufferView(componentType, source.buffer, source.byteOffset + byteOffset, numberOfComponents); - if (type === 'SCALAR') { - values[i] = typedArrayView[0]; - } else if (type === 'VEC3') { - values[i] = Cartesian3.fromArray(typedArrayView); - } else if (type === 'VEC4') { - values[i] = Quaternion.unpack(typedArrayView); - } - byteOffset += byteStride; + var height = polygon.height; + var extrudedHeight = polygon.extrudedHeight; + var granularity = polygon.granularity; + var stRotation = polygon.stRotation; + var outlineWidth = polygon.outlineWidth; + var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && isColorMaterial && + !perPositionHeightEnabled && GroundPrimitive.isSupported(this._scene); + + if (outlineEnabled && onTerrain) { + oneTimeWarning(oneTimeWarning.geometryOutlines); + outlineEnabled = false; + } + + var perPositionHeight = polygon.perPositionHeight; + var closeTop = polygon.closeTop; + var closeBottom = polygon.closeBottom; + + this._fillEnabled = fillEnabled; + this._onTerrain = onTerrain; + this._outlineEnabled = outlineEnabled; + + if (!hierarchy.isConstant || // + !Property.isConstant(height) || // + !Property.isConstant(extrudedHeight) || // + !Property.isConstant(granularity) || // + !Property.isConstant(stRotation) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(perPositionHeightProperty) || // + !Property.isConstant(perPositionHeight) || // + !Property.isConstant(closeTop) || // + !Property.isConstant(closeBottom) || // + (onTerrain && !Property.isConstant(material))) { + + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); } - // GLTF_SPEC: Support more parameter types when glTF supports targeting materials. https://github.com/KhronosGroup/glTF/issues/142 + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - if (defined(model.cacheKey)) { - // Only cache when we can create a unique id - cachedAnimationParameters[key] = values; + var hierarchyValue = hierarchy.getValue(Iso8601.MINIMUM_VALUE); + if (isArray(hierarchyValue)) { + hierarchyValue = new PolygonHierarchy(hierarchyValue); } - } - return values; - }; + var heightValue = Property.getValueOrUndefined(height, Iso8601.MINIMUM_VALUE); + var closeTopValue = Property.getValueOrDefault(closeTop, Iso8601.MINIMUM_VALUE, true); + var closeBottomValue = Property.getValueOrDefault(closeBottom, Iso8601.MINIMUM_VALUE, true); + var extrudedHeightValue = Property.getValueOrUndefined(extrudedHeight, Iso8601.MINIMUM_VALUE); - var cachedAnimationSplines = { + options.polygonHierarchy = hierarchyValue; + options.height = heightValue; + options.extrudedHeight = extrudedHeightValue; + options.granularity = Property.getValueOrUndefined(granularity, Iso8601.MINIMUM_VALUE); + options.stRotation = Property.getValueOrUndefined(stRotation, Iso8601.MINIMUM_VALUE); + options.perPositionHeight = Property.getValueOrUndefined(perPositionHeight, Iso8601.MINIMUM_VALUE); + options.closeTop = closeTopValue; + options.closeBottom = closeBottomValue; + this._outlineWidth = Property.getValueOrDefault(outlineWidth, Iso8601.MINIMUM_VALUE, 1.0); + this._isClosed = defined(extrudedHeightValue) && extrudedHeightValue !== heightValue && closeTopValue && closeBottomValue; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } }; - function getAnimationSplineKey(model, animationName, samplerName) { - return model.cacheKey + '//' + animationName + '/' + samplerName; - } + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @param {PrimitiveCollection} groundPrimitives The ground primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } - function ConstantSpline(value) { - this._value = value; - } - ConstantSpline.prototype.evaluate = function(time, result) { - return this._value; + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, groundPrimitives, this); }; - ModelAnimationCache.getAnimationSpline = function(model, animationName, animation, samplerName, sampler, input, path, output) { - var key = getAnimationSplineKey(model, animationName, samplerName); - var spline = cachedAnimationSplines[key]; - - if (!defined(spline)) { - var times = input; - var controlPoints = output; + /** + * @private + */ + function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { + this._primitives = primitives; + this._groundPrimitives = groundPrimitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + } - if ((times.length === 1) && (controlPoints.length === 1)) { - spline = new ConstantSpline(controlPoints[0]); - } else if (sampler.interpolation === 'LINEAR') { - if (path === 'translation' || path === 'scale') { - spline = new LinearSpline({ - times : times, - points : controlPoints - }); - } else if (path === 'rotation') { - spline = new QuaternionSpline({ - times : times, - points : controlPoints - }); - } else if (path === 'weights') { - spline = new WeightSpline({ - times : times, - weights : controlPoints - }); - } - // GLTF_SPEC: Support more parameter types when glTF supports targeting materials. https://github.com/KhronosGroup/glTF/issues/142 - } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var geometryUpdater = this._geometryUpdater; + var onTerrain = geometryUpdater._onTerrain; - if (defined(model.cacheKey)) { - // Only cache when we can create a unique id - cachedAnimationSplines[key] = spline; - } + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._outlinePrimitive = undefined; } + this._primitive = undefined; - return spline; - }; + var entity = geometryUpdater._entity; + var polygon = entity.polygon; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(polygon.show, time, true)) { + return; + } - var cachedSkinInverseBindMatrices = { - }; + var options = this._options; + var hierarchy = Property.getValueOrUndefined(polygon.hierarchy, time); + if (!defined(hierarchy)) { + return; + } - ModelAnimationCache.getSkinInverseBindMatrices = function(model, accessor) { - var key = getAccessorKey(model, accessor); - var matrices = cachedSkinInverseBindMatrices[key]; + if (isArray(hierarchy)) { + options.polygonHierarchy = new PolygonHierarchy(hierarchy); + } else { + options.polygonHierarchy = hierarchy; + } - if (!defined(matrices)) { - // Cache miss - var gltf = model.gltf; - var buffers = gltf.buffers; - var bufferViews = gltf.bufferViews; + var closeTopValue = Property.getValueOrDefault(polygon.closeTop, time, true); + var closeBottomValue = Property.getValueOrDefault(polygon.closeBottom, time, true); - var bufferViewId = accessor.bufferView; - var bufferView = bufferViews[bufferViewId]; - var bufferId = bufferView.buffer; - var buffer = buffers[bufferId]; - var source = buffer.extras._pipeline.source; + options.height = Property.getValueOrUndefined(polygon.height, time); + options.extrudedHeight = Property.getValueOrUndefined(polygon.extrudedHeight, time); + options.granularity = Property.getValueOrUndefined(polygon.granularity, time); + options.stRotation = Property.getValueOrUndefined(polygon.stRotation, time); + options.perPositionHeight = Property.getValueOrUndefined(polygon.perPositionHeight, time); + options.closeTop = closeTopValue; + options.closeBottom = closeBottomValue; - var componentType = accessor.componentType; - var type = accessor.type; - var count = accessor.count; - var byteStride = getAccessorByteStride(gltf, accessor); - var byteOffset = bufferView.byteOffset + accessor.byteOffset; - var numberOfComponents = numberOfComponentsForType(type); + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); - matrices = new Array(count); + if (Property.getValueOrDefault(polygon.fill, time, true)) { + var fillMaterialProperty = geometryUpdater.fillMaterialProperty; + var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); + this._material = material; - if ((componentType === WebGLConstants.FLOAT) && (type === AttributeType.MAT4)) { - for (var i = 0; i < count; ++i) { - var typedArrayView = ComponentDatatype.createArrayBufferView(componentType, source.buffer, source.byteOffset + byteOffset, numberOfComponents); - matrices[i] = Matrix4.fromArray(typedArrayView); - byteOffset += byteStride; + if (onTerrain) { + var currentColor = Color.WHITE; + if (defined(fillMaterialProperty.color)) { + currentColor = fillMaterialProperty.color.getValue(time); } - } - cachedSkinInverseBindMatrices[key] = matrices; + this._primitive = groundPrimitives.add(new GroundPrimitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PolygonGeometry(options), + attributes: { + color: ColorGeometryInstanceAttribute.fromColor(currentColor) + } + }), + asynchronous : false, + shadows : shadows + })); + } else { + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : defined(options.extrudedHeight) && options.extrudedHeight !== options.height && closeTopValue && closeBottomValue + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PolygonGeometry(options) + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); + } } - return matrices; - }; + if (!onTerrain && Property.getValueOrDefault(polygon.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - return ModelAnimationCache; -}); + var outlineColor = Property.getValueOrClonedDefault(polygon.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(polygon.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; -define('Scene/ModelAnimationLoop',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PolygonOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } + }; - /** - * Determines if and how a glTF animation is looped. - * - * @exports ModelAnimationLoop - * - * @see ModelAnimationCollection#add - */ - var ModelAnimationLoop = { - /** - * Play the animation once; do not loop it. - * - * @type {Number} - * @constant - */ - NONE : 0, + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; - /** - * Loop the animation playing it from the start immediately after it stops. - * - * @type {Number} - * @constant - */ - REPEAT : 1, + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - /** - * Loop the animation. First, playing it forward, then in reverse, then forward, and so on. - * - * @type {Number} - * @constant - */ - MIRRORED_REPEAT : 2 + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (this._geometryUpdater._onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + } + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); }; - return freezeObject(ModelAnimationLoop); + return PolygonGeometryUpdater; }); -define('Scene/ModelAnimationState',[ - '../Core/freezeObject' - ], function( - freezeObject) { +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/PolylineColorAppearanceVS',[],function() { 'use strict'; - - /** - * @private - */ - return freezeObject({ - STOPPED : 0, - ANIMATING : 1 - }); + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 prevPosition3DHigh;\n\ +attribute vec3 prevPosition3DLow;\n\ +attribute vec3 nextPosition3DHigh;\n\ +attribute vec3 nextPosition3DLow;\n\ +attribute vec2 expandAndWidth;\n\ +attribute vec4 color;\n\ +attribute float batchId;\n\ +varying vec4 v_color;\n\ +void main()\n\ +{\n\ +float expandDir = expandAndWidth.x;\n\ +float width = abs(expandAndWidth.y) + 0.5;\n\ +bool usePrev = expandAndWidth.y < 0.0;\n\ +vec4 p = czm_computePosition();\n\ +vec4 prev = czm_computePrevPosition();\n\ +vec4 next = czm_computeNextPosition();\n\ +v_color = color;\n\ +float angle;\n\ +vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);\n\ +gl_Position = czm_viewportOrthographic * positionWC;\n\ +}\n\ +"; }); - -define('Scene/ModelAnimation',[ +define('Scene/PolylineColorAppearance',[ '../Core/defaultValue', '../Core/defineProperties', - '../Core/Event', - '../Core/JulianDate', - './ModelAnimationLoop', - './ModelAnimationState' + '../Core/VertexFormat', + '../Shaders/Appearances/PerInstanceFlatColorAppearanceFS', + '../Shaders/Appearances/PolylineColorAppearanceVS', + '../Shaders/PolylineCommon', + './Appearance' ], function( defaultValue, defineProperties, - Event, - JulianDate, - ModelAnimationLoop, - ModelAnimationState) { + VertexFormat, + PerInstanceFlatColorAppearanceFS, + PolylineColorAppearanceVS, + PolylineCommon, + Appearance) { 'use strict'; + var defaultVertexShaderSource = PolylineCommon + '\n' + PolylineColorAppearanceVS; + var defaultFragmentShaderSource = PerInstanceFlatColorAppearanceFS; + /** - * An active glTF animation. A glTF asset can contain animations. An active animation - * is an animation that is currently playing or scheduled to be played because it was - * added to a model's {@link ModelAnimationCollection}. An active animation is an - * instance of an animation; for example, there can be multiple active animations - * for the same glTF animation, each with a different start time. - * <p> - * Create this by calling {@link ModelAnimationCollection#add}. - * </p> + * An appearance for {@link GeometryInstance} instances with color attributes and {@link PolylineGeometry}. + * This allows several geometry instances, each with a different color, to + * be drawn with the same {@link Primitive}. * - * @alias ModelAnimation - * @internalConstructor + * @alias PolylineColorAppearance + * @constructor * - * @see ModelAnimationCollection#add + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineColorAppearance#renderState} has alpha blending enabled. + * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {RenderState} [options.renderState] Optional render state to override the default render state. + * + * @example + * // A solid white line segment + * var primitive = new Cesium.Primitive({ + * geometryInstances : new Cesium.GeometryInstance({ + * geometry : new Cesium.PolylineGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * 0.0, 0.0, + * 5.0, 0.0 + * ]), + * width : 10.0, + * vertexFormat : Cesium.PolylineColorAppearance.VERTEX_FORMAT + * }), + * attributes : { + * color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0)) + * } + * }), + * appearance : new Cesium.PolylineColorAppearance({ + * translucent : false + * }) + * }); */ - function ModelAnimation(options, model, runtimeAnimation) { - this._name = runtimeAnimation.name; - this._startTime = JulianDate.clone(options.startTime); - this._delay = defaultValue(options.delay, 0.0); // in seconds - this._stopTime = options.stopTime; - - /** - * When <code>true</code>, the animation is removed after it stops playing. - * This is slightly more efficient that not removing it, but if, for example, - * time is reversed, the animation is not played again. - * - * @type {Boolean} - * @default false - */ - this.removeOnStop = defaultValue(options.removeOnStop, false); - - this._speedup = defaultValue(options.speedup, 1.0); - this._reverse = defaultValue(options.reverse, false); - this._loop = defaultValue(options.loop, ModelAnimationLoop.NONE); + function PolylineColorAppearance(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The event fired when this animation is started. This can be used, for - * example, to play a sound or start a particle system, when the animation starts. - * <p> - * This event is fired at the end of the frame after the scene is rendered. - * </p> - * - * @type {Event} - * @default new Event() - * - * @example - * animation.start.addEventListener(function(model, animation) { - * console.log('Animation started: ' + animation.name); - * }); - */ - this.start = new Event(); + var translucent = defaultValue(options.translucent, true); + var closed = false; + var vertexFormat = PolylineColorAppearance.VERTEX_FORMAT; /** - * The event fired when on each frame when this animation is updated. The - * current time of the animation, relative to the glTF animation time span, is - * passed to the event, which allows, for example, starting new animations at a - * specific time relative to a playing animation. - * <p> - * This event is fired at the end of the frame after the scene is rendered. - * </p> + * This property is part of the {@link Appearance} interface, but is not + * used by {@link PolylineColorAppearance} since a fully custom fragment shader is used. * - * @type {Event} - * @default new Event() + * @type Material * - * @example - * animation.update.addEventListener(function(model, animation, time) { - * console.log('Animation updated: ' + animation.name + '. glTF animation time: ' + time); - * }); + * @default undefined */ - this.update = new Event(); + this.material = undefined; /** - * The event fired when this animation is stopped. This can be used, for - * example, to play a sound or start a particle system, when the animation stops. - * <p> - * This event is fired at the end of the frame after the scene is rendered. - * </p> + * When <code>true</code>, the geometry is expected to appear translucent so + * {@link PolylineColorAppearance#renderState} has alpha blending enabled. * - * @type {Event} - * @default new Event() + * @type {Boolean} * - * @example - * animation.stop.addEventListener(function(model, animation) { - * console.log('Animation stopped: ' + animation.name); - * }); + * @default true */ - this.stop = new Event(); + this.translucent = translucent; - this._state = ModelAnimationState.STOPPED; - this._runtimeAnimation = runtimeAnimation; + this._vertexShaderSource = defaultValue(options.vertexShaderSource, defaultVertexShaderSource); + this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, defaultFragmentShaderSource); + this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); + this._closed = closed; - // Set during animation update - this._computedStartTime = undefined; - this._duration = undefined; + // Non-derived members - // To avoid allocations in ModelAnimationCollection.update - var that = this; - this._raiseStartEvent = function() { - that.start.raiseEvent(model, that); - }; - this._updateEventTime = 0.0; - this._raiseUpdateEvent = function() { - that.update.raiseEvent(model, that, that._updateEventTime); - }; - this._raiseStopEvent = function() { - that.stop.raiseEvent(model, that); - }; + this._vertexFormat = vertexFormat; } - defineProperties(ModelAnimation.prototype, { + defineProperties(PolylineColorAppearance.prototype, { /** - * The glTF animation name that identifies this animation. + * The GLSL source code for the vertex shader. * - * @memberof ModelAnimation.prototype + * @memberof PolylineColorAppearance.prototype * * @type {String} * @readonly */ - name : { - get : function() { - return this._name; - } - }, - - /** - * The scene time to start playing this animation. When this is <code>undefined</code>, - * the animation starts at the next frame. - * - * @memberof ModelAnimation.prototype - * - * @type {JulianDate} - * @readonly - * - * @default undefined - */ - startTime : { - get : function() { - return this._startTime; - } - }, - - /** - * The delay, in seconds, from {@link ModelAnimation#startTime} to start playing. - * - * @memberof ModelAnimation.prototype - * - * @type {Number} - * @readonly - * - * @default undefined - */ - delay : { + vertexShaderSource : { get : function() { - return this._delay; + return this._vertexShaderSource; } }, /** - * The scene time to stop playing this animation. When this is <code>undefined</code>, - * the animation is played for its full duration and perhaps repeated depending on - * {@link ModelAnimation#loop}. + * The GLSL source code for the fragment shader. * - * @memberof ModelAnimation.prototype + * @memberof PolylineColorAppearance.prototype * - * @type {JulianDate} + * @type {String} * @readonly - * - * @default undefined */ - stopTime : { + fragmentShaderSource : { get : function() { - return this._stopTime; + return this._fragmentShaderSource; } }, /** - * Values greater than <code>1.0</code> increase the speed that the animation is played relative - * to the scene clock speed; values less than <code>1.0</code> decrease the speed. A value of - * <code>1.0</code> plays the animation at the speed in the glTF animation mapped to the scene - * clock speed. For example, if the scene is played at 2x real-time, a two-second glTF animation - * will play in one second even if <code>speedup</code> is <code>1.0</code>. + * The WebGL fixed-function state to use when rendering the geometry. + * <p> + * The render state can be explicitly defined when constructing a {@link PolylineColorAppearance} + * instance, or it is set implicitly via {@link PolylineColorAppearance#translucent}. + * </p> * - * @memberof ModelAnimation.prototype + * @memberof PolylineColorAppearance.prototype * - * @type {Number} + * @type {Object} * @readonly - * - * @default 1.0 */ - speedup : { + renderState : { get : function() { - return this._speedup; + return this._renderState; } }, /** - * When <code>true</code>, the animation is played in reverse. + * When <code>true</code>, the geometry is expected to be closed so + * {@link PolylineColorAppearance#renderState} has backface culling enabled. + * This is always <code>false</code> for <code>PolylineColorAppearance</code>. * - * @memberof ModelAnimation.prototype + * @memberof PolylineColorAppearance.prototype * * @type {Boolean} * @readonly * * @default false */ - reverse : { + closed : { get : function() { - return this._reverse; + return this._closed; } }, /** - * Determines if and how the animation is looped. + * The {@link VertexFormat} that this appearance instance is compatible with. + * A geometry can have more vertex attributes and still be compatible - at a + * potential performance cost - but it can't have less. * - * @memberof ModelAnimation.prototype + * @memberof PolylineColorAppearance.prototype * - * @type {ModelAnimationLoop} + * @type VertexFormat * @readonly * - * @default {@link ModelAnimationLoop.NONE} + * @default {@link PolylineColorAppearance.VERTEX_FORMAT} */ - loop : { + vertexFormat : { get : function() { - return this._loop; + return this._vertexFormat; } } }); - return ModelAnimation; -}); - -define('Scene/ModelAnimationCollection',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/JulianDate', - '../Core/Math', - './ModelAnimation', - './ModelAnimationLoop', - './ModelAnimationState' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - JulianDate, - CesiumMath, - ModelAnimation, - ModelAnimationLoop, - ModelAnimationState) { - 'use strict'; - /** - * A collection of active model animations. Access this using {@link Model#activeAnimations}. + * The {@link VertexFormat} that all {@link PolylineColorAppearance} instances + * are compatible with. This requires only a <code>position</code> attribute. * - * @alias ModelAnimationCollection - * @internalConstructor + * @type VertexFormat * - * @see Model#activeAnimations + * @constant */ - function ModelAnimationCollection(model) { - /** - * The event fired when an animation is added to the collection. This can be used, for - * example, to keep a UI in sync. - * - * @type {Event} - * @default new Event() - * - * @example - * model.activeAnimations.animationAdded.addEventListener(function(model, animation) { - * console.log('Animation added: ' + animation.name); - * }); - */ - this.animationAdded = new Event(); - - /** - * The event fired when an animation is removed from the collection. This can be used, for - * example, to keep a UI in sync. - * - * @type {Event} - * @default new Event() - * - * @example - * model.activeAnimations.animationRemoved.addEventListener(function(model, animation) { - * console.log('Animation removed: ' + animation.name); - * }); - */ - this.animationRemoved = new Event(); - - this._model = model; - this._scheduledAnimations = []; - this._previousTime = undefined; - } - - defineProperties(ModelAnimationCollection.prototype, { - /** - * The number of animations in the collection. - * - * @memberof ModelAnimationCollection.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._scheduledAnimations.length; - } - } - }); - - function add(collection, index, options) { - var model = collection._model; - var animations = model._runtime.animations; - var animation = animations[index]; - var scheduledAnimation = new ModelAnimation(options, model, animation); - collection._scheduledAnimations.push(scheduledAnimation); - collection.animationAdded.raiseEvent(model, scheduledAnimation); - return scheduledAnimation; - } + PolylineColorAppearance.VERTEX_FORMAT = VertexFormat.POSITION_ONLY; /** - * Creates and adds an animation with the specified initial properties to the collection. - * <p> - * This raises the {@link ModelAnimationCollection#animationAdded} event so, for example, a UI can stay in sync. - * </p> - * - * @param {Object} options Object with the following properties: - * @param {String} [options.name] The glTF animation name that identifies the animation. Must be defined if <code>options.id</code> is <code>undefined</code>. - * @param {Number} [options.index] The glTF animation index that identifies the animation. Must be defined if <code>options.name</code> is <code>undefined</code>. - * @param {JulianDate} [options.startTime] The scene time to start playing the animation. When this is <code>undefined</code>, the animation starts at the next frame. - * @param {Number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. - * @param {JulianDate} [options.stopTime] The scene time to stop playing the animation. When this is <code>undefined</code>, the animation is played for its full duration. - * @param {Boolean} [options.removeOnStop=false] When <code>true</code>, the animation is removed after it stops playing. - * @param {Number} [options.speedup=1.0] Values greater than <code>1.0</code> increase the speed that the animation is played relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. - * @param {Boolean} [options.reverse=false] When <code>true</code>, the animation is played in reverse. - * @param {ModelAnimationLoop} [options.loop=ModelAnimationLoop.NONE] Determines if and how the animation is looped. - * @returns {ModelAnimation} The animation that was added to the collection. - * - * @exception {DeveloperError} Animations are not loaded. Wait for the {@link Model#readyPromise} to resolve. - * @exception {DeveloperError} options.name must be a valid animation name. - * @exception {DeveloperError} options.index must be a valid animation index. - * @exception {DeveloperError} Either options.name or options.index must be defined. - * @exception {DeveloperError} options.speedup must be greater than zero. - * - * @example - * // Example 1. Add an animation by name - * model.activeAnimations.add({ - * name : 'animation name' - * }); - * - * // Example 2. Add an animation by index - * model.activeAnimations.add({ - * index : 0 - * }); - * - * @example - * // Example 3. Add an animation and provide all properties and events - * var startTime = Cesium.JulianDate.now(); + * Procedurally creates the full GLSL fragment shader source. * - * var animation = model.activeAnimations.add({ - * name : 'another animation name', - * startTime : startTime, - * delay : 0.0, // Play at startTime (default) - * stopTime : Cesium.JulianDate.addSeconds(startTime, 4.0, new Cesium.JulianDate()), - * removeOnStop : false, // Do not remove when animation stops (default) - * speedup : 2.0, // Play at double speed - * reverse : true, // Play in reverse - * loop : Cesium.ModelAnimationLoop.REPEAT // Loop the animation - * }); + * @function * - * animation.start.addEventListener(function(model, animation) { - * console.log('Animation started: ' + animation.name); - * }); - * animation.update.addEventListener(function(model, animation, time) { - * console.log('Animation updated: ' + animation.name + '. glTF animation time: ' + time); - * }); - * animation.stop.addEventListener(function(model, animation) { - * console.log('Animation stopped: ' + animation.name); - * }); + * @returns {String} The full GLSL fragment shader source. */ - ModelAnimationCollection.prototype.add = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var model = this._model; - var animations = model._runtime.animations; - - if (!defined(animations)) { - throw new DeveloperError('Animations are not loaded. Wait for Model.readyPromise to resolve.'); - } - if (!defined(options.name) && !defined(options.index)) { - throw new DeveloperError('Either options.name or options.index must be defined.'); - } - if (defined(options.speedup) && (options.speedup <= 0.0)) { - throw new DeveloperError('options.speedup must be greater than zero.'); - } - if (defined(options.index) && (options.index >= animations.length || options.index < 0)) { - throw new DeveloperError('options.index must be a valid animation index.'); - } - - if (defined(options.index)) { - return add(this, options.index, options); - } - - // Find the index of the animation with the given name - var index; - var length = animations.length; - for (var i = 0; i < length; ++i) { - if (animations[i].name === options.name) { - index = i; - break; - } - } - - if (!defined(index)) { - throw new DeveloperError('options.name must be a valid animation name.'); - } - - return add(this, index, options); - }; + PolylineColorAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; /** - * Creates and adds an animation with the specified initial properties to the collection - * for each animation in the model. - * <p> - * This raises the {@link ModelAnimationCollection#animationAdded} event for each model so, for example, a UI can stay in sync. - * </p> - * - * @param {Object} [options] Object with the following properties: - * @param {JulianDate} [options.startTime] The scene time to start playing the animations. When this is <code>undefined</code>, the animations starts at the next frame. - * @param {Number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. - * @param {JulianDate} [options.stopTime] The scene time to stop playing the animations. When this is <code>undefined</code>, the animations are played for its full duration. - * @param {Boolean} [options.removeOnStop=false] When <code>true</code>, the animations are removed after they stop playing. - * @param {Number} [options.speedup=1.0] Values greater than <code>1.0</code> increase the speed that the animations play relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. - * @param {Boolean} [options.reverse=false] When <code>true</code>, the animations are played in reverse. - * @param {ModelAnimationLoop} [options.loop=ModelAnimationLoop.NONE] Determines if and how the animations are looped. - * @returns {ModelAnimation[]} An array of {@link ModelAnimation} objects, one for each animation added to the collection. If there are no glTF animations, the array is empty. + * Determines if the geometry is translucent based on {@link PolylineColorAppearance#translucent}. * - * @exception {DeveloperError} Animations are not loaded. Wait for the {@link Model#readyPromise} to resolve. - * @exception {DeveloperError} options.speedup must be greater than zero. + * @function * - * @example - * model.activeAnimations.addAll({ - * speedup : 0.5, // Play at half-speed - * loop : Cesium.ModelAnimationLoop.REPEAT // Loop the animations - * }); + * @returns {Boolean} <code>true</code> if the appearance is translucent. */ - ModelAnimationCollection.prototype.addAll = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (!defined(this._model._runtime.animations)) { - throw new DeveloperError('Animations are not loaded. Wait for Model.readyPromise to resolve.'); - } - - if (defined(options.speedup) && (options.speedup <= 0.0)) { - throw new DeveloperError('options.speedup must be greater than zero.'); - } - - var scheduledAnimations = []; - var model = this._model; - var animations = model._runtime.animations; - var length = animations.length; - for (var i = 0; i < length; ++i) { - scheduledAnimations.push(add(this, i, options)); - } - return scheduledAnimations; - }; + PolylineColorAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; /** - * Removes an animation from the collection. - * <p> - * This raises the {@link ModelAnimationCollection#animationRemoved} event so, for example, a UI can stay in sync. - * </p> - * <p> - * An animation can also be implicitly removed from the collection by setting {@link ModelAnimation#removeOnStop} to - * <code>true</code>. The {@link ModelAnimationCollection#animationRemoved} event is still fired when the animation is removed. - * </p> + * Creates a render state. This is not the final render state instance; instead, + * it can contain a subset of render state properties identical to the render state + * created in the context. * - * @param {ModelAnimation} animation The animation to remove. - * @returns {Boolean} <code>true</code> if the animation was removed; <code>false</code> if the animation was not found in the collection. + * @function * - * @example - * var a = model.activeAnimations.add({ - * name : 'animation name' - * }); - * model.activeAnimations.remove(a); // Returns true + * @returns {Object} The render state. */ - ModelAnimationCollection.prototype.remove = function(animation) { - if (defined(animation)) { - var animations = this._scheduledAnimations; - var i = animations.indexOf(animation); - if (i !== -1) { - animations.splice(i, 1); - this.animationRemoved.raiseEvent(this._model, animation); - return true; - } - } - - return false; - }; + PolylineColorAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; - /** - * Removes all animations from the collection. - * <p> - * This raises the {@link ModelAnimationCollection#animationRemoved} event for each - * animation so, for example, a UI can stay in sync. - * </p> - */ - ModelAnimationCollection.prototype.removeAll = function() { - var model = this._model; - var animations = this._scheduledAnimations; - var length = animations.length; + return PolylineColorAppearance; +}); - this._scheduledAnimations = []; +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Appearances/PolylineMaterialAppearanceVS',[],function() { + 'use strict'; + return "attribute vec3 position3DHigh;\n\ +attribute vec3 position3DLow;\n\ +attribute vec3 prevPosition3DHigh;\n\ +attribute vec3 prevPosition3DLow;\n\ +attribute vec3 nextPosition3DHigh;\n\ +attribute vec3 nextPosition3DLow;\n\ +attribute vec2 expandAndWidth;\n\ +attribute vec2 st;\n\ +attribute float batchId;\n\ +varying float v_width;\n\ +varying vec2 v_st;\n\ +varying float v_polylineAngle;\n\ +void main()\n\ +{\n\ +float expandDir = expandAndWidth.x;\n\ +float width = abs(expandAndWidth.y) + 0.5;\n\ +bool usePrev = expandAndWidth.y < 0.0;\n\ +vec4 p = czm_computePosition();\n\ +vec4 prev = czm_computePrevPosition();\n\ +vec4 next = czm_computeNextPosition();\n\ +v_width = width;\n\ +v_st = st;\n\ +vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\n\ +gl_Position = czm_viewportOrthographic * positionWC;\n\ +}\n\ +"; +}); +define('Scene/PolylineMaterialAppearance',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/VertexFormat', + '../Shaders/Appearances/PolylineMaterialAppearanceVS', + '../Shaders/PolylineCommon', + '../Shaders/PolylineFS', + './Appearance', + './Material' + ], function( + defaultValue, + defined, + defineProperties, + VertexFormat, + PolylineMaterialAppearanceVS, + PolylineCommon, + PolylineFS, + Appearance, + Material) { + 'use strict'; - for (var i = 0; i < length; ++i) { - this.animationRemoved.raiseEvent(model, animations[i]); - } - }; + var defaultVertexShaderSource = PolylineCommon + '\n' + PolylineMaterialAppearanceVS; + var defaultFragmentShaderSource = PolylineFS; /** - * Determines whether this collection contains a given animation. + * An appearance for {@link PolylineGeometry} that supports shading with materials. * - * @param {ModelAnimation} animation The animation to check for. - * @returns {Boolean} <code>true</code> if this collection contains the animation, <code>false</code> otherwise. - */ - ModelAnimationCollection.prototype.contains = function(animation) { - if (defined(animation)) { - return (this._scheduledAnimations.indexOf(animation) !== -1); - } - - return false; - }; - - /** - * Returns the animation in the collection at the specified index. Indices are zero-based - * and increase as animations are added. Removing an animation shifts all animations after - * it to the left, changing their indices. This function is commonly used to iterate over - * all the animations in the collection. + * @alias PolylineMaterialAppearance + * @constructor * - * @param {Number} index The zero-based index of the animation. - * @returns {ModelAnimation} The animation at the specified index. + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. + * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. + * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {RenderState} [options.renderState] Optional render state to override the default render state. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} * * @example - * // Output the names of all the animations in the collection. - * var animations = model.activeAnimations; - * var length = animations.length; - * for (var i = 0; i < length; ++i) { - * console.log(animations.get(i).name); - * } - */ - ModelAnimationCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - return this._scheduledAnimations[index]; - }; - - function animateChannels(runtimeAnimation, localAnimationTime) { - var channelEvaluators = runtimeAnimation.channelEvaluators; - var length = channelEvaluators.length; - for (var i = 0; i < length; ++i) { - channelEvaluators[i](localAnimationTime); - } - } - - var animationsToRemove = []; - - function createAnimationRemovedFunction(modelAnimationCollection, model, animation) { - return function() { - modelAnimationCollection.animationRemoved.raiseEvent(model, animation); - }; - } - - /** - * @private + * var primitive = new Cesium.Primitive({ + * geometryInstances : new Cesium.GeometryInstance({ + * geometry : new Cesium.PolylineGeometry({ + * positions : Cesium.Cartesian3.fromDegreesArray([ + * 0.0, 0.0, + * 5.0, 0.0 + * ]), + * width : 10.0, + * vertexFormat : Cesium.PolylineMaterialAppearance.VERTEX_FORMAT + * }) + * }), + * appearance : new Cesium.PolylineMaterialAppearance({ + * material : Cesium.Material.fromType('Color') + * }) + * }); */ - ModelAnimationCollection.prototype.update = function(frameState) { - var scheduledAnimations = this._scheduledAnimations; - var length = scheduledAnimations.length; - - if (length === 0) { - // No animations - quick return for performance - this._previousTime = undefined; - return false; - } - - if (JulianDate.equals(frameState.time, this._previousTime)) { - // Animations are currently only time-dependent so do not animate when paused or picking - return false; - } - this._previousTime = JulianDate.clone(frameState.time, this._previousTime); - - var animationOccured = false; - var sceneTime = frameState.time; - var model = this._model; - - for (var i = 0; i < length; ++i) { - var scheduledAnimation = scheduledAnimations[i]; - var runtimeAnimation = scheduledAnimation._runtimeAnimation; - - if (!defined(scheduledAnimation._computedStartTime)) { - scheduledAnimation._computedStartTime = JulianDate.addSeconds(defaultValue(scheduledAnimation.startTime, sceneTime), scheduledAnimation.delay, new JulianDate()); - } - - if (!defined(scheduledAnimation._duration)) { - scheduledAnimation._duration = runtimeAnimation.stopTime * (1.0 / scheduledAnimation.speedup); - } - - var startTime = scheduledAnimation._computedStartTime; - var duration = scheduledAnimation._duration; - var stopTime = scheduledAnimation.stopTime; - - // [0.0, 1.0] normalized local animation time - var delta = (duration !== 0.0) ? (JulianDate.secondsDifference(sceneTime, startTime) / duration) : 0.0; - var pastStartTime = (delta >= 0.0); - - // Play animation if - // * we are after the start time or the animation is being repeated, and - // * before the end of the animation's duration or the animation is being repeated, and - // * we did not reach a user-provided stop time. - - var repeat = ((scheduledAnimation.loop === ModelAnimationLoop.REPEAT) || - (scheduledAnimation.loop === ModelAnimationLoop.MIRRORED_REPEAT)); - - var play = (pastStartTime || (repeat && !defined(scheduledAnimation.startTime))) && - ((delta <= 1.0) || repeat) && - (!defined(stopTime) || JulianDate.lessThanOrEquals(sceneTime, stopTime)); + function PolylineMaterialAppearance(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (play) { - // STOPPED -> ANIMATING state transition? - if (scheduledAnimation._state === ModelAnimationState.STOPPED) { - scheduledAnimation._state = ModelAnimationState.ANIMATING; - if (scheduledAnimation.start.numberOfListeners > 0) { - frameState.afterRender.push(scheduledAnimation._raiseStartEvent); - } - } + var translucent = defaultValue(options.translucent, true); + var closed = false; + var vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT; - // Truncate to [0.0, 1.0] for repeating animations - if (scheduledAnimation.loop === ModelAnimationLoop.REPEAT) { - delta = delta - Math.floor(delta); - } else if (scheduledAnimation.loop === ModelAnimationLoop.MIRRORED_REPEAT) { - var floor = Math.floor(delta); - var fract = delta - floor; - // When even use (1.0 - fract) to mirror repeat - delta = (floor % 2 === 1.0) ? (1.0 - fract) : fract; - } + /** + * The material used to determine the fragment color. Unlike other {@link PolylineMaterialAppearance} + * properties, this is not read-only, so an appearance's material can change on the fly. + * + * @type Material + * + * @default {@link Material.ColorType} + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + */ + this.material = defined(options.material) ? options.material : Material.fromType(Material.ColorType); - if (scheduledAnimation.reverse) { - delta = 1.0 - delta; - } + /** + * When <code>true</code>, the geometry is expected to appear translucent so + * {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. + * + * @type {Boolean} + * + * @default true + */ + this.translucent = translucent; - var localAnimationTime = delta * duration * scheduledAnimation.speedup; - // Clamp in case floating-point roundoff goes outside the animation's first or last keyframe - localAnimationTime = CesiumMath.clamp(localAnimationTime, runtimeAnimation.startTime, runtimeAnimation.stopTime); + this._vertexShaderSource = defaultValue(options.vertexShaderSource, defaultVertexShaderSource); + this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, defaultFragmentShaderSource); + this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); + this._closed = closed; - animateChannels(runtimeAnimation, localAnimationTime); + // Non-derived members - if (scheduledAnimation.update.numberOfListeners > 0) { - scheduledAnimation._updateEventTime = localAnimationTime; - frameState.afterRender.push(scheduledAnimation._raiseUpdateEvent); - } - animationOccured = true; - } else if (pastStartTime && (scheduledAnimation._state === ModelAnimationState.ANIMATING)) { - // ANIMATING -> STOPPED state transition? - scheduledAnimation._state = ModelAnimationState.STOPPED; - if (scheduledAnimation.stop.numberOfListeners > 0) { - frameState.afterRender.push(scheduledAnimation._raiseStopEvent); - } + this._vertexFormat = vertexFormat; + } - if (scheduledAnimation.removeOnStop) { - animationsToRemove.push(scheduledAnimation); + defineProperties(PolylineMaterialAppearance.prototype, { + /** + * The GLSL source code for the vertex shader. + * + * @memberof PolylineMaterialAppearance.prototype + * + * @type {String} + * @readonly + */ + vertexShaderSource : { + get : function() { + var vs = this._vertexShaderSource; + if (this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== -1) { + vs = '#define POLYLINE_DASH\n' + vs; } + return vs; } - } - - // Remove animations that stopped - length = animationsToRemove.length; - for (var j = 0; j < length; ++j) { - var animationToRemove = animationsToRemove[j]; - scheduledAnimations.splice(scheduledAnimations.indexOf(animationToRemove), 1); - frameState.afterRender.push(createAnimationRemovedFunction(this, model, animationToRemove)); - } - animationsToRemove.length = 0; - - return animationOccured; - }; - - return ModelAnimationCollection; -}); - -define('Scene/ModelMaterial',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError' - ], function( - defined, - defineProperties, - DeveloperError) { - 'use strict'; + }, - /** - * A model's material with modifiable parameters. A glTF material - * contains parameters defined by the material's technique with values - * defined by the technique and potentially overridden by the material. - * This class allows changing these values at runtime. - * <p> - * Use {@link Model#getMaterial} to create an instance. - * </p> - * - * @alias ModelMaterial - * @internalConstructor - * - * @see Model#getMaterial - */ - function ModelMaterial(model, material, id) { - this._name = material.name; - this._id = id; - this._uniformMap = model._uniformMaps[id]; - } + /** + * The GLSL source code for the fragment shader. + * + * @memberof PolylineMaterialAppearance.prototype + * + * @type {String} + * @readonly + */ + fragmentShaderSource : { + get : function() { + return this._fragmentShaderSource; + } + }, - defineProperties(ModelMaterial.prototype, { /** - * The value of the <code>name</code> property of this material. This is the - * name assigned by the artist when the asset is created. This can be - * different than the name of the material property ({@link ModelMaterial#id}), - * which is internal to glTF. + * The WebGL fixed-function state to use when rendering the geometry. + * <p> + * The render state can be explicitly defined when constructing a {@link PolylineMaterialAppearance} + * instance, or it is set implicitly via {@link PolylineMaterialAppearance#translucent} + * and {@link PolylineMaterialAppearance#closed}. + * </p> * - * @memberof ModelMaterial.prototype + * @memberof PolylineMaterialAppearance.prototype * - * @type {String} + * @type {Object} * @readonly */ - name : { + renderState : { get : function() { - return this._name; + return this._renderState; } }, /** - * The name of the glTF JSON property for this material. This is guaranteed - * to be unique among all materials. It may not match the material's <code> - * name</code> property (@link ModelMaterial#name), which is assigned by - * the artist when the asset is created. + * When <code>true</code>, the geometry is expected to be closed so + * {@link PolylineMaterialAppearance#renderState} has backface culling enabled. + * This is always <code>false</code> for <code>PolylineMaterialAppearance</code>. * - * @memberof ModelMaterial.prototype + * @memberof PolylineMaterialAppearance.prototype * - * @type {String} + * @type {Boolean} * @readonly + * + * @default false */ - id : { + closed : { get : function() { - return this._id; + return this._closed; + } + }, + + /** + * The {@link VertexFormat} that this appearance instance is compatible with. + * A geometry can have more vertex attributes and still be compatible - at a + * potential performance cost - but it can't have less. + * + * @memberof PolylineMaterialAppearance.prototype + * + * @type VertexFormat + * @readonly + * + * @default {@link PolylineMaterialAppearance.VERTEX_FORMAT} + */ + vertexFormat : { + get : function() { + return this._vertexFormat; } } }); /** - * Assigns a value to a material parameter. The type for <code>value</code> - * depends on the glTF type of the parameter. It will be a floating-point - * number, Cartesian, or matrix. - * - * @param {String} name The name of the parameter. - * @param {Object} [value] The value to assign to the parameter. + * The {@link VertexFormat} that all {@link PolylineMaterialAppearance} instances + * are compatible with. This requires <code>position</code> and <code>st</code> attributes. * - * @exception {DeveloperError} name must match a parameter name in the material's technique that is targetable and not optimized out. + * @type VertexFormat * - * @example - * material.setValue('diffuse', new Cesium.Cartesian4(1.0, 0.0, 0.0, 1.0)); // vec4 - * material.setValue('shininess', 256.0); // scalar + * @constant */ - ModelMaterial.prototype.setValue = function(name, value) { - if (!defined(name)) { - throw new DeveloperError('name is required.'); - } - - var v = this._uniformMap.values[name]; - - if (!defined(v)) { - throw new DeveloperError('name must match a parameter name in the material\'s technique that is targetable and not optimized out.'); - } - - v.value = v.clone(value, v.value); - }; + PolylineMaterialAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_ST; /** - * Returns the value of the parameter with the given <code>name</code>. The type of the - * returned object depends on the glTF type of the parameter. It will be a floating-point - * number, Cartesian, or matrix. + * Procedurally creates the full GLSL fragment shader source. For {@link PolylineMaterialAppearance}, + * this is derived from {@link PolylineMaterialAppearance#fragmentShaderSource} and {@link PolylineMaterialAppearance#material}. * - * @param {String} name The name of the parameter. - * @returns {Object} The value of the parameter or <code>undefined</code> if the parameter does not exist. + * @function + * + * @returns {String} The full GLSL fragment shader source. */ - ModelMaterial.prototype.getValue = function(name) { - if (!defined(name)) { - throw new DeveloperError('name is required.'); - } - - var v = this._uniformMap.values[name]; + PolylineMaterialAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; - if (!defined(v)) { - return undefined; - } + /** + * Determines if the geometry is translucent based on {@link PolylineMaterialAppearance#translucent} and {@link Material#isTranslucent}. + * + * @function + * + * @returns {Boolean} <code>true</code> if the appearance is translucent. + */ + PolylineMaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; - return v.value; - }; + /** + * Creates a render state. This is not the final render state instance; instead, + * it can contain a subset of render state properties identical to the render state + * created in the context. + * + * @function + * + * @returns {Object} The render state. + */ + PolylineMaterialAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; - return ModelMaterial; + return PolylineMaterialAppearance; }); -define('Scene/ModelMesh',[ - '../Core/defineProperties' +define('DataSources/PolylineGeometryUpdater',[ + '../Core/BoundingSphere', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/PolylineGeometry', + '../Core/PolylinePipeline', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/PolylineCollection', + '../Scene/PolylineColorAppearance', + '../Scene/PolylineMaterialAppearance', + '../Scene/ShadowMode', + './BoundingSphereState', + './ColorMaterialProperty', + './ConstantProperty', + './MaterialProperty', + './Property' ], function( - defineProperties) { + BoundingSphere, + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + PolylineGeometry, + PolylinePipeline, + ShowGeometryInstanceAttribute, + PolylineCollection, + PolylineColorAppearance, + PolylineMaterialAppearance, + ShadowMode, + BoundingSphereState, + ColorMaterialProperty, + ConstantProperty, + MaterialProperty, + Property) { 'use strict'; + //We use this object to create one polyline collection per-scene. + var polylineCollections = {}; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.positions = undefined; + this.width = undefined; + this.followSurface = undefined; + this.granularity = undefined; + } + /** - * A model's mesh and its materials. - * <p> - * Use {@link Model#getMesh} to create an instance. - * </p> - * - * @alias ModelMesh - * @internalConstructor + * A {@link GeometryUpdater} for polylines. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias PolylineGeometryUpdater + * @constructor * - * @see Model#getMesh + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. */ - function ModelMesh(mesh, runtimeMaterialsById, id) { - var materials = []; - var primitives = mesh.primitives; - var length = primitives.length; - for (var i = 0; i < length; ++i) { - var p = primitives[i]; - materials[i] = runtimeMaterialsById[p.material]; + function PolylineGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); } - - this._name = mesh.name; - this._materials = materials; - this._id = id; + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(PolylineGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._depthFailMaterialProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'polyline', entity.polyline, undefined); } - defineProperties(ModelMesh.prototype, { + defineProperties(PolylineGeometryUpdater, { /** - * The value of the <code>name</code> property of this mesh. This is the - * name assigned by the artist when the asset is created. This can be - * different than the name of the mesh property ({@link ModelMesh#id}), - * which is internal to glTF. - * - * @memberof ModelMesh.prototype + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof PolylineGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PolylineColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof PolylineGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : PolylineMaterialAppearance + } + }); + + defineProperties(PolylineGeometryUpdater.prototype, { + /** + * Gets the entity associated with this geometry. + * @memberof PolylineGeometryUpdater.prototype * - * @type {String} + * @type {Entity} * @readonly */ - name : { + entity : { get : function() { - return this._name; + return this._entity; } }, - /** - * The name of the glTF JSON property for this mesh. This is guaranteed - * to be unique among all meshes. It may not match the mesh's <code> - * name</code> property (@link ModelMesh#name), which is assigned by - * the artist when the asset is created. + * Gets a value indicating if the geometry has a fill component. + * @memberof PolylineGeometryUpdater.prototype * - * @memberof ModelMesh.prototype + * @type {Boolean} + * @readonly + */ + fillEnabled : { + get : function() { + return this._fillEnabled; + } + }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof PolylineGeometryUpdater.prototype * - * @type {String} + * @type {Boolean} * @readonly */ - id : { + hasConstantFill : { get : function() { - return this._id; + return !this._fillEnabled || (!defined(this._entity.availability) && Property.isConstant(this._showProperty)); } }, - /** - * An array of {@link ModelMaterial} instances indexed by the mesh's - * primitive indices. + * Gets the material property used to fill the geometry. + * @memberof PolylineGeometryUpdater.prototype * - * @memberof ModelMesh.prototype + * @type {MaterialProperty} + * @readonly + */ + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, + /** + * Gets the material property used to fill the geometry when it fails the depth test. + * @memberof PolylineGeometryUpdater.prototype * - * @type {ModelMaterial[]} + * @type {MaterialProperty} * @readonly */ - materials : { + depthFailMaterialProperty : { get : function() { - return this._materials; + return this._depthFailMaterialProperty; } - } - }); - - return ModelMesh; -}); - -define('Scene/ModelNode',[ - '../Core/defineProperties', - '../Core/Matrix4' - ], function( - defineProperties, - Matrix4) { - 'use strict'; - - /** - * A model node with a transform for user-defined animations. A glTF asset can - * contain animations that target a node's transform. This class allows - * changing a node's transform externally so animation can be driven by another - * source, not just an animation in the glTF asset. - * <p> - * Use {@link Model#getNode} to create an instance. - * </p> - * - * @alias ModelNode - * @internalConstructor - * - * - * @example - * var node = model.getNode('LOD3sp'); - * node.matrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix); - * - * @see Model#getNode - */ - function ModelNode(model, node, runtimeNode, id, matrix) { - this._model = model; - this._runtimeNode = runtimeNode; - this._name = node.name; - this._id = id; - + }, /** - * @private + * Gets a value indicating if the geometry has an outline component. + * @memberof PolylineGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly */ - this.useMatrix = false; - - this._show = true; - this._matrix = Matrix4.clone(matrix); - } - - defineProperties(ModelNode.prototype, { + outlineEnabled : { + value : false + }, /** - * The value of the <code>name</code> property of this node. This is the - * name assigned by the artist when the asset is created. This can be - * different than the name of the node property ({@link ModelNode#id}), - * which is internal to glTF. + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof PolylineGeometryUpdater.prototype * - * @memberof ModelNode.prototype + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { + value : true + }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof PolylineGeometryUpdater.prototype * - * @type {String} + * @type {Property} * @readonly */ - name : { + outlineColorProperty : { + value : undefined + }, + /** + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof PolylineGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + shadowsProperty : { get : function() { - return this._name; + return this._shadowsProperty; } }, - /** - * The name of the glTF JSON property for this node. This is guaranteed - * to be unique among all nodes. It may not match the node's <code> - * name</code> property (@link ModelNode#name), which is assigned by - * the artist when the asset is created. - * - * @memberof ModelNode.prototype + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof PolylineGeometryUpdater.prototype * - * @type {String} + * @type {Property} * @readonly */ - id : { + distanceDisplayConditionProperty : { get : function() { - return this._id; + return this._distanceDisplayConditionProperty; } }, - /** - * Determines if this node and its children will be shown. + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof PolylineGeometryUpdater.prototype * - * @memberof ModelNode.prototype * @type {Boolean} - * - * @default true + * @readonly */ - show : { + isDynamic : { get : function() { - return this._show; - }, - set : function(value) { - if (this._show !== value) { - this._show = value; - this._model._perNodeShowDirty = true; - } + return this._dynamic; } }, - /** - * The node's 4x4 matrix transform from its local coordinates to - * its parent's. - * <p> - * For changes to take effect, this property must be assigned to; - * setting individual elements of the matrix will not work. - * </p> + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof PolylineGeometryUpdater.prototype * - * @memberof ModelNode.prototype - * @type {Matrix4} + * @type {Boolean} + * @readonly */ - matrix : { + isClosed : { + value : false + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof PolylineGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { get : function() { - return this._matrix; - }, - set : function(value) { - this._matrix = Matrix4.clone(value, this._matrix); - this.useMatrix = true; - - var model = this._model; - model._cesiumAnimationsDirty = true; - this._runtimeNode.dirtyNumber = model._maxDirtyNumber; + return this._geometryChanged; } } }); /** - * @private + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. */ - ModelNode.prototype.setMatrix = function(matrix) { - // Update matrix but do not set the dirty flag since this is used internally - // to keep the matrix in-sync during a glTF animation. - Matrix4.clone(matrix, this._matrix); + PolylineGeometryUpdater.prototype.isOutlineVisible = function(time) { + return false; }; - return ModelNode; -}); - -define('Scene/Model',[ - '../Core/BoundingSphere', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', - '../Core/clone', - '../Core/Color', - '../Core/combine', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/FeatureDetection', - '../Core/getAbsoluteUri', - '../Core/getBaseUri', - '../Core/getMagic', - '../Core/getStringFromTypedArray', - '../Core/IndexDatatype', - '../Core/joinUrls', - '../Core/loadArrayBuffer', - '../Core/loadCRN', - '../Core/loadImage', - '../Core/loadImageFromTypedArray', - '../Core/loadKTX', - '../Core/loadText', - '../Core/Math', - '../Core/Matrix2', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/PixelFormat', - '../Core/Plane', - '../Core/PrimitiveType', - '../Core/Quaternion', - '../Core/Queue', - '../Core/RuntimeError', - '../Core/Transforms', - '../Core/WebGLConstants', - '../Renderer/Buffer', - '../Renderer/BufferUsage', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/Sampler', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/Texture', - '../Renderer/TextureMinificationFilter', - '../Renderer/TextureWrap', - '../Renderer/VertexArray', - '../ThirdParty/GltfPipeline/addDefaults', - '../ThirdParty/GltfPipeline/addPipelineExtras', - '../ThirdParty/GltfPipeline/ForEach', - '../ThirdParty/GltfPipeline/getAccessorByteStride', - '../ThirdParty/GltfPipeline/numberOfComponentsForType', - '../ThirdParty/GltfPipeline/parseBinaryGltf', - '../ThirdParty/GltfPipeline/processModelMaterialsCommon', - '../ThirdParty/GltfPipeline/processPbrMetallicRoughness', - '../ThirdParty/GltfPipeline/updateVersion', - '../ThirdParty/Uri', - '../ThirdParty/when', - './AttributeType', - './Axis', - './BlendingState', - './ColorBlendMode', - './getAttributeOrUniformBySemantic', - './HeightReference', - './JobType', - './ModelAnimationCache', - './ModelAnimationCollection', - './ModelMaterial', - './ModelMesh', - './ModelNode', - './SceneMode', - './ShadowMode' - ], function( - BoundingSphere, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - clone, - Color, - combine, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - FeatureDetection, - getAbsoluteUri, - getBaseUri, - getMagic, - getStringFromTypedArray, - IndexDatatype, - joinUrls, - loadArrayBuffer, - loadCRN, - loadImage, - loadImageFromTypedArray, - loadKTX, - loadText, - CesiumMath, - Matrix2, - Matrix3, - Matrix4, - PixelFormat, - Plane, - PrimitiveType, - Quaternion, - Queue, - RuntimeError, - Transforms, - WebGLConstants, - Buffer, - BufferUsage, - DrawCommand, - Pass, - RenderState, - Sampler, - ShaderProgram, - ShaderSource, - Texture, - TextureMinificationFilter, - TextureWrap, - VertexArray, - addDefaults, - addPipelineExtras, - ForEach, - getAccessorByteStride, - numberOfComponentsForType, - parseBinaryGltf, - processModelMaterialsCommon, - processPbrMetallicRoughness, - updateVersion, - Uri, - when, - AttributeType, - Axis, - BlendingState, - ColorBlendMode, - getAttributeOrUniformBySemantic, - HeightReference, - JobType, - ModelAnimationCache, - ModelAnimationCollection, - ModelMaterial, - ModelMesh, - ModelNode, - SceneMode, - ShadowMode) { - 'use strict'; - - // Bail out if the browser doesn't support typed arrays, to prevent the setup function - // from failing, since we won't be able to create a WebGL context anyway. - if (!FeatureDetection.supportsTypedArrays()) { - return {}; - } - - var boundingSphereCartesian3Scratch = new Cartesian3(); - - var ModelState = { - NEEDS_LOAD : 0, - LOADING : 1, - LOADED : 2, // Renderable, but textures can still be pending when incrementallyLoadTextures is true. - FAILED : 3 + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + PolylineGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time); }; - // glTF MIME types discussed in https://github.com/KhronosGroup/glTF/issues/412 and https://github.com/KhronosGroup/glTF/issues/943 - var defaultModelAccept = 'model/gltf-binary,model/gltf+json;q=0.8,application/json;q=0.2,*/*;q=0.01'; - - function LoadResources() { - this.vertexBuffersToCreate = new Queue(); - this.indexBuffersToCreate = new Queue(); - this.buffers = {}; - this.pendingBufferLoads = 0; - - this.programsToCreate = new Queue(); - this.shaders = {}; - this.pendingShaderLoads = 0; - - this.texturesToCreate = new Queue(); - this.pendingTextureLoads = 0; + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + PolylineGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - this.texturesToCreateFromBufferView = new Queue(); - this.pendingBufferViewToImage = 0; + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - this.createSamplers = true; - this.createSkins = true; - this.createRuntimeAnimations = true; - this.createVertexArrays = true; - this.createRenderStates = true; - this.createUniformMaps = true; - this.createRuntimeNodes = true; + var attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; - this.skinnedNodesIds = []; - } + var currentColor; + if (this._materialProperty instanceof ColorMaterialProperty) { + currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor); + } - LoadResources.prototype.getBuffer = function(bufferView) { - return getSubarray(this.buffers[bufferView.buffer], bufferView.byteOffset, bufferView.byteLength); - }; + if (defined(this._depthFailMaterialProperty) && this._depthFailMaterialProperty instanceof ColorMaterialProperty) { + currentColor = Color.WHITE; + if (defined(this._depthFailMaterialProperty.color) && (this._depthFailMaterialProperty.color.isConstant || isAvailable)) { + currentColor = this._depthFailMaterialProperty.color.getValue(time); + } + attributes.depthFailColor = ColorGeometryInstanceAttribute.fromColor(currentColor); + } - LoadResources.prototype.finishedPendingBufferLoads = function() { - return (this.pendingBufferLoads === 0); + return new GeometryInstance({ + id : entity, + geometry : new PolylineGeometry(this._options), + attributes : attributes + }); }; - LoadResources.prototype.finishedBuffersCreation = function() { - return ((this.pendingBufferLoads === 0) && - (this.vertexBuffersToCreate.length === 0) && - (this.indexBuffersToCreate.length === 0)); - }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); + }; - LoadResources.prototype.finishedProgramCreation = function() { - return ((this.pendingShaderLoads === 0) && (this.programsToCreate.length === 0)); + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + PolylineGeometryUpdater.prototype.isDestroyed = function() { + return false; }; - LoadResources.prototype.finishedTextureCreation = function() { - var finishedPendingLoads = (this.pendingTextureLoads === 0); - var finishedResourceCreation = - (this.texturesToCreate.length === 0) && - (this.texturesToCreateFromBufferView.length === 0); - - return finishedPendingLoads && finishedResourceCreation; + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + PolylineGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); }; - LoadResources.prototype.finishedEverythingButTextureCreation = function() { - var finishedPendingLoads = - (this.pendingBufferLoads === 0) && - (this.pendingShaderLoads === 0); - var finishedResourceCreation = - (this.vertexBuffersToCreate.length === 0) && - (this.indexBuffersToCreate.length === 0) && - (this.programsToCreate.length === 0) && - (this.pendingBufferViewToImage === 0); + PolylineGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'polyline')) { + return; + } - return finishedPendingLoads && finishedResourceCreation; - }; + var polyline = this._entity.polyline; - LoadResources.prototype.finished = function() { - return this.finishedTextureCreation() && this.finishedEverythingButTextureCreation(); - }; + if (!defined(polyline)) { + if (this._fillEnabled) { + this._fillEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - /////////////////////////////////////////////////////////////////////////// + var positionsProperty = polyline.positions; - function setCachedGltf(model, cachedGltf) { - model._cachedGltf = cachedGltf; - } + var show = polyline.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(positionsProperty))) { + if (this._fillEnabled) { + this._fillEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - // glTF JSON can be big given embedded geometry, textures, and animations, so we - // cache it across all models using the same url/cache-key. This also reduces the - // slight overhead in assigning defaults to missing values. - // - // Note that this is a global cache, compared to renderer resources, which - // are cached per context. - function CachedGltf(options) { - this._gltf = options.gltf; - this.ready = options.ready; - this.modelsToLoad = []; - this.count = 0; - } + var material = defaultValue(polyline.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._depthFailMaterialProperty = polyline.depthFailMaterial; + this._showProperty = defaultValue(show, defaultShow); + this._shadowsProperty = defaultValue(polyline.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(polyline.distanceDisplayCondition, defaultDistanceDisplayCondition); + this._fillEnabled = true; - defineProperties(CachedGltf.prototype, { - gltf : { - set : function(value) { - this._gltf = value; - }, + var width = polyline.width; + var followSurface = polyline.followSurface; + var granularity = polyline.granularity; - get : function() { - return this._gltf; + if (!positionsProperty.isConstant || !Property.isConstant(width) || + !Property.isConstant(followSurface) || !Property.isConstant(granularity)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); } - } - }); + } else { + var options = this._options; + var positions = positionsProperty.getValue(Iso8601.MINIMUM_VALUE, options.positions); - CachedGltf.prototype.makeReady = function(gltfJson) { - this.gltf = gltfJson; + //Because of the way we currently handle reference properties, + //we can't automatically assume the positions are always valid. + if (!defined(positions) || positions.length < 2) { + if (this._fillEnabled) { + this._fillEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - var models = this.modelsToLoad; - var length = models.length; - for (var i = 0; i < length; ++i) { - var m = models[i]; - if (!m.isDestroyed()) { - setCachedGltf(m, this); + var vertexFormat; + if (isColorMaterial && (!defined(this._depthFailMaterialProperty) || this._depthFailMaterialProperty instanceof ColorMaterialProperty)) { + vertexFormat = PolylineColorAppearance.VERTEX_FORMAT; + } else { + vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT; } + + options.vertexFormat = vertexFormat; + options.positions = positions; + options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.followSurface = defined(followSurface) ? followSurface.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); } - this.modelsToLoad = undefined; - this.ready = true; }; - var gltfCache = {}; - - /////////////////////////////////////////////////////////////////////////// - /** - * A 3D model based on glTF, the runtime asset format for WebGL, OpenGL ES, and OpenGL. - * <p> - * Cesium includes support for geometry and materials, glTF animations, and glTF skinning. - * In addition, individual glTF nodes are pickable with {@link Scene#pick} and animatable - * with {@link Model#getNode}. glTF cameras and lights are not currently supported. - * </p> - * <p> - * An external glTF asset is created with {@link Model.fromGltf}. glTF JSON can also be - * created at runtime and passed to this constructor function. In either case, the - * {@link Model#readyPromise} is resolved when the model is ready to render, i.e., - * when the external binary, image, and shader files are downloaded and the WebGL - * resources are created. - * </p> - * <p> - * For high-precision rendering, Cesium supports the CESIUM_RTC extension, which introduces the - * CESIUM_RTC_MODELVIEW parameter semantic that says the node is in WGS84 coordinates translated - * relative to a local origin. - * </p> - * - * @alias Model - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Object|ArrayBuffer|Uint8Array} [options.gltf] The object for the glTF JSON or an arraybuffer of Binary glTF defined by the KHR_binary_glTF extension. - * @param {String} [options.basePath=''] The base path that paths in the glTF JSON are relative to. - * @param {Boolean} [options.show=true] Determines if the model primitive will be shown. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. - * @param {Number} [options.scale=1.0] A uniform scale applied to this model. - * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. - * @param {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. - * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. - * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. - * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. - * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. - * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. - * @param {HeightReference} [options.heightReference] Determines how the model is drawn relative to terrain. - * @param {Scene} [options.scene] Must be passed in for models that use the height reference property. - * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. - * @param {Color} [options.color=Color.WHITE] A color that blends with the model's rendered color. - * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. - * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. - * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. - * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. - * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. Clipping planes are not currently supported in Internet Explorer. - * - * @exception {DeveloperError} bgltf is not a valid Binary glTF file. - * @exception {DeveloperError} Only glTF Binary version 1 is supported. + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. * - * @see Model.fromGltf + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle Models Demo} + * @exception {DeveloperError} This instance does not represent dynamic geometry. */ - function Model(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } - var cacheKey = options.cacheKey; - this._cacheKey = cacheKey; - this._cachedGltf = undefined; - this._releaseGltfJson = defaultValue(options.releaseGltfJson, false); + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, this); + }; - var cachedGltf; - if (defined(cacheKey) && defined(gltfCache[cacheKey]) && gltfCache[cacheKey].ready) { - // glTF JSON is in cache and ready - cachedGltf = gltfCache[cacheKey]; - ++cachedGltf.count; - } else { - // glTF was explicitly provided, e.g., when a user uses the Model constructor directly - var gltf = options.gltf; + /** + * @private + */ + var generateCartesianArcOptions = { + positions : undefined, + granularity : undefined, + height : undefined, + ellipsoid : undefined + }; + + function DynamicGeometryUpdater(primitives, geometryUpdater) { + var sceneId = geometryUpdater._scene.id; + + var polylineCollection = polylineCollections[sceneId]; + if (!defined(polylineCollection) || polylineCollection.isDestroyed()) { + polylineCollection = new PolylineCollection(); + polylineCollections[sceneId] = polylineCollection; + primitives.add(polylineCollection); + } else if (!primitives.contains(polylineCollection)) { + primitives.add(polylineCollection); + } + + var line = polylineCollection.add(); + line.id = geometryUpdater._entity; + + this._line = line; + this._primitives = primitives; + this._geometryUpdater = geometryUpdater; + this._positions = []; + + } + DynamicGeometryUpdater.prototype.update = function(time) { + var geometryUpdater = this._geometryUpdater; + var entity = geometryUpdater._entity; + var polyline = entity.polyline; + var line = this._line; + + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(polyline._show, time, true)) { + line.show = false; + return; + } + + var positionsProperty = polyline.positions; + var positions = Property.getValueOrUndefined(positionsProperty, time, this._positions); + if (!defined(positions) || positions.length < 2) { + line.show = false; + return; + } - if (defined(gltf)) { - if (gltf instanceof ArrayBuffer) { - gltf = new Uint8Array(gltf); - } + var followSurface = Property.getValueOrDefault(polyline._followSurface, time, true); + var globe = geometryUpdater._scene.globe; + if (followSurface && defined(globe)) { + generateCartesianArcOptions.ellipsoid = globe.ellipsoid; + generateCartesianArcOptions.positions = positions; + generateCartesianArcOptions.granularity = Property.getValueOrUndefined(polyline._granularity, time); + generateCartesianArcOptions.height = PolylinePipeline.extractHeights(positions, globe.ellipsoid); + positions = PolylinePipeline.generateCartesianArc(generateCartesianArcOptions); + } - if (gltf instanceof Uint8Array) { - // Binary glTF - var parsedGltf = parseBinaryGltf(gltf); + line.show = true; + line.positions = positions.slice(); + line.material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, line.material); + line.width = Property.getValueOrDefault(polyline._width, time, 1); + line.distanceDisplayCondition = Property.getValueOrUndefined(polyline._distanceDisplayCondition, time, line.distanceDisplayCondition); + }; - cachedGltf = new CachedGltf({ - gltf : parsedGltf, - ready : true - }); - } else { - // Normal glTF (JSON) - cachedGltf = new CachedGltf({ - gltf : options.gltf, - ready : true - }); - } + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + var line = this._line; + if (line.show && line.positions.length > 0) { + BoundingSphere.fromPoints(line.positions, result); + return BoundingSphereState.DONE; + } + return BoundingSphereState.FAILED; + }; - cachedGltf.count = 1; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - if (defined(cacheKey)) { - gltfCache[cacheKey] = cachedGltf; - } - } + DynamicGeometryUpdater.prototype.destroy = function() { + var geometryUpdater = this._geometryUpdater; + var sceneId = geometryUpdater._scene.id; + var polylineCollection = polylineCollections[sceneId]; + polylineCollection.remove(this._line); + if (polylineCollection.length === 0) { + this._primitives.removeAndDestroy(polylineCollection); + delete polylineCollections[sceneId]; } - setCachedGltf(this, cachedGltf); + destroyObject(this); + }; - this._basePath = defaultValue(options.basePath, ''); - var baseUri = getBaseUri(document.location.href); - this._baseUri = joinUrls(baseUri, this._basePath); + return PolylineGeometryUpdater; +}); - /** - * Determines if the model primitive will be shown. - * - * @type {Boolean} - * - * @default true - */ - this.show = defaultValue(options.show, true); +define('DataSources/PolylineVolumeGeometryUpdater',[ + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/PolylineVolumeGeometry', + '../Core/PolylineVolumeOutlineGeometry', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' + ], function( + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + PolylineVolumeGeometry, + PolylineVolumeOutlineGeometry, + ShowGeometryInstanceAttribute, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { + 'use strict'; - /** - * The silhouette color. - * - * @type {Color} - * - * @default Color.RED - */ - this.silhouetteColor = defaultValue(options.silhouetteColor, Color.RED); - this._silhouetteColor = new Color(); - this._silhouetteColorPreviousAlpha = 1.0; - this._normalAttributeName = undefined; + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); - /** - * The size of the silhouette in pixels. - * - * @type {Number} - * - * @default 0.0 - */ - this.silhouetteSize = defaultValue(options.silhouetteSize, 0.0); + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.polylinePositions = undefined; + this.shapePositions = undefined; + this.cornerType = undefined; + this.granularity = undefined; + } - /** - * The 4x4 transformation matrix that transforms the model from model to world coordinates. - * When this is the identity matrix, the model is drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. - * - * @type {Matrix4} - * - * @default {@link Matrix4.IDENTITY} - * - * @example - * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); - * m.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); - */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - this._modelMatrix = Matrix4.clone(this.modelMatrix); - this._clampedModelMatrix = undefined; + /** + * A {@link GeometryUpdater} for polyline volumes. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias PolylineVolumeGeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. + */ + function PolylineVolumeGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(PolylineVolumeGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'polylineVolume', entity.polylineVolume, undefined); + } + defineProperties(PolylineVolumeGeometryUpdater, { /** - * A uniform scale applied to this model before the {@link Model#modelMatrix}. - * Values greater than <code>1.0</code> increase the size of the model; values - * less than <code>1.0</code> decrease. - * - * @type {Number} - * - * @default 1.0 + * Gets the type of appearance to use for simple color-based geometry. + * @memberof PolylineVolumeGeometryUpdater + * @type {Appearance} */ - this.scale = defaultValue(options.scale, 1.0); - this._scale = this.scale; - + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, /** - * The approximate minimum pixel size of the model regardless of zoom. - * This can be used to ensure that a model is visible even when the viewer - * zooms out. When <code>0.0</code>, no minimum size is enforced. - * - * @type {Number} - * - * @default 0.0 + * Gets the type of appearance to use for material-based geometry. + * @memberof PolylineVolumeGeometryUpdater + * @type {Appearance} */ - this.minimumPixelSize = defaultValue(options.minimumPixelSize, 0.0); - this._minimumPixelSize = this.minimumPixelSize; + materialAppearanceType : { + value : MaterialAppearance + } + }); + defineProperties(PolylineVolumeGeometryUpdater.prototype, { /** - * The maximum scale size for a model. This can be used to give - * an upper limit to the {@link Model#minimumPixelSize}, ensuring that the model - * is never an unreasonable scale. + * Gets the entity associated with this geometry. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @type {Number} + * @type {Entity} + * @readonly */ - this.maximumScale = options.maximumScale; - this._maximumScale = this.maximumScale; - + entity : { + get : function() { + return this._entity; + } + }, /** - * User-defined object returned when the model is picked. - * - * @type Object - * - * @default undefined + * Gets a value indicating if the geometry has a fill component. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @see Scene#pick + * @type {Boolean} + * @readonly */ - this.id = options.id; - this._id = options.id; - + fillEnabled : { + get : function() { + return this._fillEnabled; + } + }, /** - * Returns the height reference of the model - * - * @memberof Model.prototype - * - * @type {HeightReference} + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @default HeightReference.NONE + * @type {Boolean} + * @readonly */ - this.heightReference = defaultValue(options.heightReference, HeightReference.NONE); - this._heightReference = this.heightReference; - this._heightChanged = false; - this._removeUpdateHeightCallback = undefined; - var scene = options.scene; - this._scene = scene; - if (defined(scene) && defined(scene.terrainProviderChanged)) { - this._terrainProviderChangedCallback = scene.terrainProviderChanged.addEventListener(function() { - this._heightChanged = true; - }, this); - } - + hasConstantFill : { + get : function() { + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); + } + }, /** - * Used for picking primitives that wrap a model. + * Gets the material property used to fill the geometry. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @private + * @type {MaterialProperty} + * @readonly */ - this._pickObject = options.pickObject; - this._allowPicking = defaultValue(options.allowPicking, true); - - this._ready = false; - this._readyPromise = when.defer(); - + fillMaterialProperty : { + get : function() { + return this._materialProperty; + } + }, /** - * The currently playing glTF animations. + * Gets a value indicating if the geometry has an outline component. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @type {ModelAnimationCollection} + * @type {Boolean} + * @readonly */ - this.activeAnimations = new ModelAnimationCollection(this); - + outlineEnabled : { + get : function() { + return this._outlineEnabled; + } + }, /** - * Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * Gets a value indicating if the geometry has an outline component. + * @memberof PolylineVolumeGeometryUpdater.prototype * * @type {Boolean} + * @readonly */ - this.clampAnimations = defaultValue(options.clampAnimations, true); - - this._defaultTexture = undefined; - this._incrementallyLoadTextures = defaultValue(options.incrementallyLoadTextures, true); - this._asynchronous = defaultValue(options.asynchronous, true); - + hasConstantOutline : { + get : function() { + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); + } + }, /** - * Determines whether the model casts or receives shadows from each light source. - * - * @type {ShadowMode} + * Gets the {@link Color} property for the geometry outline. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @default ShadowMode.ENABLED + * @type {Property} + * @readonly */ - this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); - this._shadows = this.shadows; - + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, /** - * A color that blends with the model's rendered color. - * - * @type {Color} + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @default Color.WHITE + * @type {Number} + * @readonly */ - this.color = defaultValue(options.color, Color.WHITE); - this._color = new Color(); - this._colorPreviousAlpha = 1.0; - + outlineWidth : { + get : function() { + return this._outlineWidth; + } + }, /** - * Defines how the color blends with the model. - * - * @type {ColorBlendMode} + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @default ColorBlendMode.HIGHLIGHT + * @type {Property} + * @readonly */ - this.colorBlendMode = defaultValue(options.colorBlendMode, ColorBlendMode.HIGHLIGHT); - + shadowsProperty : { + get : function() { + return this._shadowsProperty; + } + }, /** - * Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. - * A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with - * any value in-between resulting in a mix of the two. - * - * @type {Number} + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @default 0.5 + * @type {Property} + * @readonly */ - this.colorBlendAmount = defaultValue(options.colorBlendAmount, 0.5); - + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayConditionProperty; + } + }, /** - * The {@link ClippingPlaneCollection} used to selectively disable rendering the model. Clipping planes are not currently supported in Internet Explorer. + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof PolylineVolumeGeometryUpdater.prototype * - * @type {ClippingPlaneCollection} + * @type {Boolean} + * @readonly */ - this.clippingPlanes = options.clippingPlanes; - + isDynamic : { + get : function() { + return this._dynamic; + } + }, /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the model. A glTF primitive corresponds - * to one draw command. A glTF mesh has an array of primitives, often of length one. - * </p> + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof PolylineVolumeGeometryUpdater.prototype * * @type {Boolean} - * - * @default false + * @readonly */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - this._debugShowBoundingVolume = false; - + isClosed : { + value : true + }, /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the model in wireframe. - * </p> + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof PolylineVolumeGeometryUpdater.prototype * * @type {Boolean} - * - * @default false + * @readonly */ - this.debugWireframe = defaultValue(options.debugWireframe, false); - this._debugWireframe = false; + geometryChanged : { + get : function() { + return this._geometryChanged; + } + } + }); - this._distanceDisplayCondition = options.distanceDisplayCondition; + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + PolylineVolumeGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; - // Undocumented options - this._addBatchIdToGeneratedShaders = options.addBatchIdToGeneratedShaders; - this._precreatedAttributes = options.precreatedAttributes; - this._vertexShaderLoaded = options.vertexShaderLoaded; - this._fragmentShaderLoaded = options.fragmentShaderLoaded; - this._uniformMapLoaded = options.uniformMapLoaded; - this._pickVertexShaderLoaded = options.pickVertexShaderLoaded; - this._pickFragmentShaderLoaded = options.pickFragmentShaderLoaded; - this._pickUniformMapLoaded = options.pickUniformMapLoaded; - this._ignoreCommands = defaultValue(options.ignoreCommands, false); - this._requestType = options.requestType; - this._upAxis = defaultValue(options.upAxis, Axis.Y); + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + PolylineVolumeGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; - /** - * @private - * @readonly - */ - this.cull = defaultValue(options.cull, true); + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + PolylineVolumeGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - /** - * @private - * @readonly - */ - this.opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - this._computedModelMatrix = new Matrix4(); // Derived from modelMatrix and scale - this._modelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); // Derived from modelMatrix, scale, and the current view matrix - this._initialRadius = undefined; // Radius without model's scale property, model-matrix scale, animations, or skins - this._boundingSphere = undefined; - this._scaledBoundingSphere = new BoundingSphere(); - this._state = ModelState.NEEDS_LOAD; - this._loadResources = undefined; + var attributes; - this._mode = undefined; + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + } - this._perNodeShowDirty = false; // true when the Cesium API was used to change a node's show property - this._cesiumAnimationsDirty = false; // true when the Cesium API, not a glTF animation, changed a node transform - this._dirty = false; // true when the model was transformed this frame - this._maxDirtyNumber = 0; // Used in place of a dirty boolean flag to avoid an extra graph traversal + return new GeometryInstance({ + id : entity, + geometry : new PolylineVolumeGeometry(this._options), + attributes : attributes + }); + }; - this._runtime = { - animations : undefined, - rootNodes : undefined, - nodes : undefined, // Indexed with the node property's name, i.e., glTF id - nodesByName : undefined, // Indexed with name property in the node - skinnedNodes : undefined, - meshesByName : undefined, // Indexed with the name property in the mesh - materialsByName : undefined, // Indexed with the name property in the material - materialsById : undefined // Indexed with the material's property name - }; + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + PolylineVolumeGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } - this._uniformMaps = {}; // Not cached since it can be targeted by glTF animation - this._extensionsUsed = undefined; // Cached used glTF extensions - this._extensionsRequired = undefined; // Cached required glTF extensions - this._quantizedUniforms = {}; // Quantized uniforms for each program for WEB3D_quantized_attributes - this._programPrimitives = {}; - this._rendererResources = { // Cached between models with the same url/cache-key - buffers : {}, - vertexArrays : {}, - programs : {}, - pickPrograms : {}, - silhouettePrograms : {}, - textures : {}, - samplers : {}, - renderStates : {} - }; - this._cachedRendererResources = undefined; - this._loadRendererResourcesFromCache = false; - this._updatedGltfVersion = false; + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - this._cachedGeometryByteLength = 0; - this._cachedTexturesByteLength = 0; - this._geometryByteLength = 0; - this._texturesByteLength = 0; - this._trianglesLength = 0; + return new GeometryInstance({ + id : entity, + geometry : new PolylineVolumeOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); + }; - this._nodeCommands = []; - this._pickIds = []; + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + PolylineVolumeGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - // CESIUM_RTC extension - this._rtcCenter = undefined; // reference to either 3D or 2D - this._rtcCenterEye = undefined; // in eye coordinates - this._rtcCenter3D = undefined; // in world coordinates - this._rtcCenter2D = undefined; // in projected world coordinates + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + PolylineVolumeGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; - this._packedClippingPlanes = []; + PolylineVolumeGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'polylineVolume')) { + return; + } + + var polylineVolume = this._entity.polylineVolume; + + if (!defined(polylineVolume)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var fillProperty = polylineVolume.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = polylineVolume.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } + + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var positions = polylineVolume.positions; + var shape = polylineVolume.shape; + + var show = polylineVolume.show; + if (!defined(positions) || !defined(shape) || (defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(polylineVolume.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(polylineVolume.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(polylineVolume.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(polylineVolume.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(polylineVolume.distanceDisplayCondition, defaultDistanceDisplayCondition); + + var granularity = polylineVolume.granularity; + var outlineWidth = polylineVolume.outlineWidth; + var cornerType = polylineVolume.cornerType; + + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; + + if (!positions.isConstant || // + !shape.isConstant || // + !Property.isConstant(granularity) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(cornerType)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.polylinePositions = positions.getValue(Iso8601.MINIMUM_VALUE, options.polylinePositions); + options.shapePositions = shape.getValue(Iso8601.MINIMUM_VALUE, options.shape); + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.cornerType = defined(cornerType) ? cornerType.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } + }; + + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + PolylineVolumeGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } + + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, this); + }; + + /** + * @private + */ + function DynamicGeometryUpdater(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._primitive = undefined; + this._outlinePrimitive = undefined; - defineProperties(Model.prototype, { + var geometryUpdater = this._geometryUpdater; + var entity = geometryUpdater._entity; + var polylineVolume = entity.polylineVolume; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(polylineVolume.show, time, true)) { + return; + } + + var options = this._options; + var positions = Property.getValueOrUndefined(polylineVolume.positions, time, options.polylinePositions); + var shape = Property.getValueOrUndefined(polylineVolume.shape, time); + if (!defined(positions) || !defined(shape)) { + return; + } + + options.polylinePositions = positions; + options.shapePositions = shape; + options.granularity = Property.getValueOrUndefined(polylineVolume.granularity, time); + options.cornerType = Property.getValueOrUndefined(polylineVolume.cornerType, time); + + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + + if (!defined(polylineVolume.fill) || polylineVolume.fill.getValue(time)) { + var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + this._material = material; + + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : true + }); + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PolylineVolumeGeometry(options) + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); + } + + if (defined(polylineVolume.outline) && polylineVolume.outline.getValue(time)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = Property.getValueOrClonedDefault(polylineVolume.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(polylineVolume.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; + + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new PolylineVolumeOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } + }; + + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; + + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; + + return PolylineVolumeGeometryUpdater; +}); + +define('DataSources/RectangleGeometryUpdater',[ + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/oneTimeWarning', + '../Core/RectangleGeometry', + '../Core/RectangleOutlineGeometry', + '../Core/ShowGeometryInstanceAttribute', + '../Scene/GroundPrimitive', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' + ], function( + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + oneTimeWarning, + RectangleGeometry, + RectangleOutlineGeometry, + ShowGeometryInstanceAttribute, + GroundPrimitive, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { + 'use strict'; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.rectangle = undefined; + this.closeBottom = undefined; + this.closeTop = undefined; + this.height = undefined; + this.extrudedHeight = undefined; + this.granularity = undefined; + this.stRotation = undefined; + this.rotation = undefined; + } + + /** + * A {@link GeometryUpdater} for rectangles. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias RectangleGeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. + */ + function RectangleGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(RectangleGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._isClosed = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._onTerrain = false; + this._options = new GeometryOptions(entity); + + this._onEntityPropertyChanged(entity, 'rectangle', entity.rectangle, undefined); + } + + defineProperties(RectangleGeometryUpdater, { /** - * The object for the glTF JSON, including properties with default values omitted - * from the JSON provided to this model. - * - * @memberof Model.prototype + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof RectangleGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof RectangleGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); + + defineProperties(RectangleGeometryUpdater.prototype, { + /** + * Gets the entity associated with this geometry. + * @memberof RectangleGeometryUpdater.prototype * - * @type {Object} + * @type {Entity} * @readonly - * - * @default undefined */ - gltf : { + entity : { get : function() { - return defined(this._cachedGltf) ? this._cachedGltf.gltf : undefined; + return this._entity; } }, - /** - * When <code>true</code>, the glTF JSON is not stored with the model once the model is - * loaded (when {@link Model#ready} is <code>true</code>). This saves memory when - * geometry, textures, and animations are embedded in the .gltf file, which is the - * default for the {@link http://cesiumjs.org/convertmodel.html|Cesium model converter}. - * This is especially useful for cases like 3D buildings, where each .gltf model is unique - * and caching the glTF JSON is not effective. - * - * @memberof Model.prototype + * Gets a value indicating if the geometry has a fill component. + * @memberof RectangleGeometryUpdater.prototype * * @type {Boolean} * @readonly - * - * @default false - * - * @private */ - releaseGltfJson : { + fillEnabled : { get : function() { - return this._releaseGltfJson; + return this._fillEnabled; } }, - /** - * The key identifying this model in the model cache for glTF JSON, renderer resources, and animations. - * Caching saves memory and improves loading speed when several models with the same url are created. - * <p> - * This key is automatically generated when the model is created with {@link Model.fromGltf}. If the model - * is created directly from glTF JSON using the {@link Model} constructor, this key can be manually - * provided; otherwise, the model will not be changed. - * </p> - * - * @memberof Model.prototype + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof RectangleGeometryUpdater.prototype * - * @type {String} + * @type {Boolean} * @readonly - * - * @private */ - cacheKey : { + hasConstantFill : { get : function() { - return this._cacheKey; + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, - /** - * The base path that paths in the glTF JSON are relative to. The base - * path is the same path as the path containing the .gltf file - * minus the .gltf file, when binary, image, and shader files are - * in the same directory as the .gltf. When this is <code>''</code>, - * the app's base path is used. - * - * @memberof Model.prototype + * Gets the material property used to fill the geometry. + * @memberof RectangleGeometryUpdater.prototype * - * @type {String} + * @type {MaterialProperty} * @readonly - * - * @default '' */ - basePath : { + fillMaterialProperty : { get : function() { - return this._basePath; + return this._materialProperty; } }, - /** - * The model's bounding sphere in its local coordinate system. This does not take into - * account glTF animations and skins nor does it take into account {@link Model#minimumPixelSize}. - * - * @memberof Model.prototype + * Gets a value indicating if the geometry has an outline component. + * @memberof RectangleGeometryUpdater.prototype * - * @type {BoundingSphere} + * @type {Boolean} * @readonly - * - * @default undefined - * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. - * - * @example - * // Center in WGS84 coordinates - * var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3()); */ - boundingSphere : { + outlineEnabled : { get : function() { - if (this._state !== ModelState.LOADED) { - throw new DeveloperError('The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.'); - } - - var modelMatrix = this.modelMatrix; - if ((this.heightReference !== HeightReference.NONE) && this._clampedModelMatrix) { - modelMatrix = this._clampedModelMatrix; - } - - var nonUniformScale = Matrix4.getScale(modelMatrix, boundingSphereCartesian3Scratch); - var scale = defined(this.maximumScale) ? Math.min(this.maximumScale, this.scale) : this.scale; - Cartesian3.multiplyByScalar(nonUniformScale, scale, nonUniformScale); - - var scaledBoundingSphere = this._scaledBoundingSphere; - scaledBoundingSphere.center = Cartesian3.multiplyComponents(this._boundingSphere.center, nonUniformScale, scaledBoundingSphere.center); - scaledBoundingSphere.radius = Cartesian3.maximumComponent(nonUniformScale) * this._initialRadius; - - if (defined(this._rtcCenter)) { - Cartesian3.add(this._rtcCenter, scaledBoundingSphere.center, scaledBoundingSphere.center); - } - - return scaledBoundingSphere; + return this._outlineEnabled; } }, - /** - * When <code>true</code>, this model is ready to render, i.e., the external binary, image, - * and shader files were downloaded and the WebGL resources were created. This is set to - * <code>true</code> right before {@link Model#readyPromise} is resolved. - * - * @memberof Model.prototype + * Gets a value indicating if the geometry has an outline component. + * @memberof RectangleGeometryUpdater.prototype * * @type {Boolean} * @readonly - * - * @default false */ - ready : { + hasConstantOutline : { get : function() { - return this._ready; + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); } }, - /** - * Gets the promise that will be resolved when this model is ready to render, i.e., when the external binary, image, - * and shader files were downloaded and the WebGL resources were created. - * <p> - * This promise is resolved at the end of the frame before the first frame the model is rendered in. - * </p> + * Gets the {@link Color} property for the geometry outline. + * @memberof RectangleGeometryUpdater.prototype * - * @memberof Model.prototype - * @type {Promise.<Model>} + * @type {Property} * @readonly + */ + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, + /** + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof RectangleGeometryUpdater.prototype * - * @example - * // Play all animations at half-speed when the model is ready to render - * Cesium.when(model.readyPromise).then(function(model) { - * model.activeAnimations.addAll({ - * speedup : 0.5 - * }); - * }).otherwise(function(error){ - * window.alert(error); - * }); + * @type {Number} + * @readonly + */ + outlineWidth : { + get : function() { + return this._outlineWidth; + } + }, + /** + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof RectangleGeometryUpdater.prototype * - * @see Model#ready + * @type {Property} + * @readonly */ - readyPromise : { + shadowsProperty : { get : function() { - return this._readyPromise.promise; + return this._shadowsProperty; } }, - /** - * Determines if model WebGL resource creation will be spread out over several frames or - * block until completion once all glTF files are loaded. + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof RectangleGeometryUpdater.prototype * - * @memberof Model.prototype + * @type {Property} + * @readonly + */ + distanceDisplayConditionProperty : { + get : function() { + return this._distanceDisplayConditionProperty; + } + }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof RectangleGeometryUpdater.prototype * * @type {Boolean} * @readonly - * - * @default true */ - asynchronous : { + isDynamic : { get : function() { - return this._asynchronous; + return this._dynamic; } }, - /** - * When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * - * @memberof Model.prototype + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof RectangleGeometryUpdater.prototype * * @type {Boolean} * @readonly - * - * @default true */ - allowPicking : { + isClosed : { get : function() { - return this._allowPicking; + return this._isClosed; } }, - /** - * Determine if textures may continue to stream in after the model is loaded. - * - * @memberof Model.prototype + * Gets a value indicating if the geometry should be drawn on terrain. + * @memberof RectangleGeometryUpdater.prototype * * @type {Boolean} * @readonly - * - * @default true */ - incrementallyLoadTextures : { + onTerrain : { get : function() { - return this._incrementallyLoadTextures; + return this._onTerrain; } }, - /** - * Return the number of pending texture loads. - * - * @memberof Model.prototype + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof RectangleGeometryUpdater.prototype * - * @type {Number} + * @type {Boolean} * @readonly */ - pendingTextureLoads : { + geometryChanged : { get : function() { - return defined(this._loadResources) ? this._loadResources.pendingTextureLoads : 0; + return this._geometryChanged; + } + } + }); + + /** + * Checks if the geometry is outlined at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + RectangleGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; + + /** + * Checks if the geometry is filled at the provided time. + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + RectangleGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; + + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + RectangleGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + + var attributes; + + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + } + + return new GeometryInstance({ + id : entity, + geometry : new RectangleGeometry(this._options), + attributes : attributes + }); + }; + + /** + * Creates the geometry instance which represents the outline of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + RectangleGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); + } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + + return new GeometryInstance({ + id : entity, + geometry : new RectangleOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + RectangleGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + RectangleGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); + }; + + RectangleGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'rectangle')) { + return; + } + + var rectangle = this._entity.rectangle; + + if (!defined(rectangle)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var fillProperty = rectangle.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + + var outlineProperty = rectangle.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } + + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var coordinates = rectangle.coordinates; + + var show = rectangle.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(coordinates))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } + + var material = defaultValue(rectangle.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(rectangle.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(rectangle.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(rectangle.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(rectangle.distanceDisplayCondition, defaultDistanceDisplayCondition); + + var height = rectangle.height; + var extrudedHeight = rectangle.extrudedHeight; + var granularity = rectangle.granularity; + var stRotation = rectangle.stRotation; + var rotation = rectangle.rotation; + var outlineWidth = rectangle.outlineWidth; + var closeBottom = rectangle.closeBottom; + var closeTop = rectangle.closeTop; + var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && + isColorMaterial && GroundPrimitive.isSupported(this._scene); + + if (outlineEnabled && onTerrain) { + oneTimeWarning(oneTimeWarning.geometryOutlines); + outlineEnabled = false; + } + + this._fillEnabled = fillEnabled; + this._onTerrain = onTerrain; + this._outlineEnabled = outlineEnabled; + + if (!coordinates.isConstant || // + !Property.isConstant(height) || // + !Property.isConstant(extrudedHeight) || // + !Property.isConstant(granularity) || // + !Property.isConstant(stRotation) || // + !Property.isConstant(rotation) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(closeBottom) || // + !Property.isConstant(closeTop) || // + (onTerrain && !Property.isConstant(material))) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); + } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.rectangle = coordinates.getValue(Iso8601.MINIMUM_VALUE, options.rectangle); + options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.closeBottom = defined(closeBottom) ? closeBottom.getValue(Iso8601.MINIMUM_VALUE) : undefined; + options.closeTop = defined(closeTop) ? closeTop.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._isClosed = defined(extrudedHeight) && defined(options.closeTop) && defined(options.closeBottom) && options.closeTop && options.closeBottom; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); + } + }; + + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @param {PrimitiveCollection} groundPrimitives The primitive collection to use for GroundPrimitives. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + RectangleGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); + } + + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, groundPrimitives, this); + }; + + /** + * @private + */ + function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { + this._primitives = primitives; + this._groundPrimitives = groundPrimitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); + } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var geometryUpdater = this._geometryUpdater; + var onTerrain = geometryUpdater._onTerrain; + + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._outlinePrimitive = undefined; + } + this._primitive = undefined; + + var entity = geometryUpdater._entity; + var rectangle = entity.rectangle; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(rectangle.show, time, true)) { + return; + } + + var options = this._options; + var coordinates = Property.getValueOrUndefined(rectangle.coordinates, time, options.rectangle); + if (!defined(coordinates)) { + return; + } + + options.rectangle = coordinates; + options.height = Property.getValueOrUndefined(rectangle.height, time); + options.extrudedHeight = Property.getValueOrUndefined(rectangle.extrudedHeight, time); + options.granularity = Property.getValueOrUndefined(rectangle.granularity, time); + options.stRotation = Property.getValueOrUndefined(rectangle.stRotation, time); + options.rotation = Property.getValueOrUndefined(rectangle.rotation, time); + options.closeBottom = Property.getValueOrUndefined(rectangle.closeBottom, time); + options.closeTop = Property.getValueOrUndefined(rectangle.closeTop, time); + + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + + if (Property.getValueOrDefault(rectangle.fill, time, true)) { + var fillMaterialProperty = geometryUpdater.fillMaterialProperty; + var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); + this._material = material; + + if (onTerrain) { + var currentColor = Color.WHITE; + if (defined(fillMaterialProperty.color)) { + currentColor = fillMaterialProperty.color.getValue(time); + } + + this._primitive = groundPrimitives.add(new GroundPrimitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new RectangleGeometry(options), + attributes: { + color: ColorGeometryInstanceAttribute.fromColor(currentColor) + } + }), + asynchronous : false, + shadows : shadows + })); + } else { + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : defined(options.extrudedHeight) + }); + + options.vertexFormat = appearance.vertexFormat; + + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new RectangleGeometry(options) + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); } + } + + if (!onTerrain && Property.getValueOrDefault(rectangle.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + + var outlineColor = Property.getValueOrClonedDefault(rectangle.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(rectangle.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; + + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new RectangleOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } + }; + + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; + + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; + + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + var groundPrimitives = this._groundPrimitives; + if (this._geometryUpdater._onTerrain) { + groundPrimitives.removeAndDestroy(this._primitive); + } else { + primitives.removeAndDestroy(this._primitive); + } + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; + + return RectangleGeometryUpdater; +}); + +define('DataSources/WallGeometryUpdater',[ + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DistanceDisplayCondition', + '../Core/DistanceDisplayConditionGeometryInstanceAttribute', + '../Core/Event', + '../Core/GeometryInstance', + '../Core/Iso8601', + '../Core/ShowGeometryInstanceAttribute', + '../Core/WallGeometry', + '../Core/WallOutlineGeometry', + '../Scene/MaterialAppearance', + '../Scene/PerInstanceColorAppearance', + '../Scene/Primitive', + '../Scene/ShadowMode', + './ColorMaterialProperty', + './ConstantProperty', + './dynamicGeometryGetBoundingSphere', + './MaterialProperty', + './Property' + ], function( + Color, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + DistanceDisplayCondition, + DistanceDisplayConditionGeometryInstanceAttribute, + Event, + GeometryInstance, + Iso8601, + ShowGeometryInstanceAttribute, + WallGeometry, + WallOutlineGeometry, + MaterialAppearance, + PerInstanceColorAppearance, + Primitive, + ShadowMode, + ColorMaterialProperty, + ConstantProperty, + dynamicGeometryGetBoundingSphere, + MaterialProperty, + Property) { + 'use strict'; + + var defaultMaterial = new ColorMaterialProperty(Color.WHITE); + var defaultShow = new ConstantProperty(true); + var defaultFill = new ConstantProperty(true); + var defaultOutline = new ConstantProperty(false); + var defaultOutlineColor = new ConstantProperty(Color.BLACK); + var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); + var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var scratchColor = new Color(); + + function GeometryOptions(entity) { + this.id = entity; + this.vertexFormat = undefined; + this.positions = undefined; + this.minimumHeights = undefined; + this.maximumHeights = undefined; + this.granularity = undefined; + } + + /** + * A {@link GeometryUpdater} for walls. + * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. + * @alias WallGeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. + */ + function WallGeometryUpdater(entity, scene) { + if (!defined(entity)) { + throw new DeveloperError('entity is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + this._entity = entity; + this._scene = scene; + this._entitySubscription = entity.definitionChanged.addEventListener(WallGeometryUpdater.prototype._onEntityPropertyChanged, this); + this._fillEnabled = false; + this._dynamic = false; + this._outlineEnabled = false; + this._geometryChanged = new Event(); + this._showProperty = undefined; + this._materialProperty = undefined; + this._hasConstantOutline = true; + this._showOutlineProperty = undefined; + this._outlineColorProperty = undefined; + this._outlineWidth = 1.0; + this._shadowsProperty = undefined; + this._distanceDisplayConditionProperty = undefined; + this._options = new GeometryOptions(entity); + this._onEntityPropertyChanged(entity, 'wall', entity.wall, undefined); + } + + defineProperties(WallGeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof WallGeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + value : PerInstanceColorAppearance }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof WallGeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + value : MaterialAppearance + } + }); + defineProperties(WallGeometryUpdater.prototype, { /** - * Returns true if the model was transformed this frame + * Gets the entity associated with this geometry. + * @memberof WallGeometryUpdater.prototype * - * @memberof Model.prototype + * @type {Entity} + * @readonly + */ + entity : { + get : function() { + return this._entity; + } + }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof WallGeometryUpdater.prototype * * @type {Boolean} * @readonly + */ + fillEnabled : { + get : function() { + return this._fillEnabled; + } + }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof WallGeometryUpdater.prototype * - * @private + * @type {Boolean} + * @readonly */ - dirty : { + hasConstantFill : { get : function() { - return this._dirty; + return !this._fillEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._fillProperty)); } }, - /** - * Gets or sets the condition specifying at what distance from the camera that this model will be displayed. - * @memberof Model.prototype - * @type {DistanceDisplayCondition} - * @default undefined + * Gets the material property used to fill the geometry. + * @memberof WallGeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly */ - distanceDisplayCondition : { + fillMaterialProperty : { get : function() { - return this._distanceDisplayCondition; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far must be greater than near'); - } - this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); + return this._materialProperty; } }, - - extensionsUsed : { + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof WallGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + outlineEnabled : { get : function() { - if (!defined(this._extensionsUsed)) { - this._extensionsUsed = getUsedExtensions(this); - } - return this._extensionsUsed; + return this._outlineEnabled; } }, - - extensionsRequired : { + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof WallGeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { get : function() { - if (!defined(this._extensionsRequired)) { - this._extensionsRequired = getRequiredExtensions(this); - } - return this._extensionsRequired; + return !this._outlineEnabled || + (!defined(this._entity.availability) && + Property.isConstant(this._showProperty) && + Property.isConstant(this._showOutlineProperty)); } }, - /** - * Gets the model's up-axis. - * By default models are y-up according to the glTF spec, however geo-referenced models will typically be z-up. + * Gets the {@link Color} property for the geometry outline. + * @memberof WallGeometryUpdater.prototype * - * @memberof Model.prototype + * @type {Property} + * @readonly + */ + outlineColorProperty : { + get : function() { + return this._outlineColorProperty; + } + }, + /** + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof WallGeometryUpdater.prototype * * @type {Number} - * @default Axis.Y * @readonly - * - * @private */ - upAxis : { + outlineWidth : { get : function() { - return this._upAxis; + return this._outlineWidth; } }, - /** - * Gets the model's triangle count. + * Gets the property specifying whether the geometry + * casts or receives shadows from each light source. + * @memberof WallGeometryUpdater.prototype * - * @private + * @type {Property} + * @readonly */ - trianglesLength : { + shadowsProperty : { get : function() { - return this._trianglesLength; + return this._shadowsProperty; } }, - /** - * Gets the model's geometry memory in bytes. This includes all vertex and index buffers. + * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. + * @memberof WallGeometryUpdater.prototype * - * @private + * @type {Property} + * @readonly */ - geometryByteLength : { + distanceDisplayConditionProperty : { get : function() { - return this._geometryByteLength; + return this._distanceDisplayConditionProperty; } }, - /** - * Gets the model's texture memory in bytes. + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof WallGeometryUpdater.prototype * - * @private + * @type {Boolean} + * @readonly */ - texturesByteLength : { + isDynamic : { get : function() { - return this._texturesByteLength; + return this._dynamic; } }, - /** - * Gets the model's cached geometry memory in bytes. This includes all vertex and index buffers. + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof WallGeometryUpdater.prototype * - * @private + * @type {Boolean} + * @readonly */ - cachedGeometryByteLength : { + isClosed : { get : function() { - return this._cachedGeometryByteLength; + return false; } }, - /** - * Gets the model's cached texture memory in bytes. + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof WallGeometryUpdater.prototype * - * @private + * @type {Boolean} + * @readonly */ - cachedTexturesByteLength : { + geometryChanged : { get : function() { - return this._cachedTexturesByteLength; + return this._geometryChanged; } } }); - function silhouetteSupported(context) { - return context.stencilBuffer; - } - /** - * Determines if silhouettes are supported. + * Checks if the geometry is outlined at the provided time. * - * @param {Scene} scene The scene. - * @returns {Boolean} <code>true</code> if silhouettes are supported; otherwise, returns <code>false</code> - */ - Model.silhouetteSupported = function(scene) { - return silhouetteSupported(scene.context); - }; - - /** - * This function differs from the normal subarray function - * because it takes offset and length, rather than begin and end. + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. */ - function getSubarray(array, offset, length) { - return array.subarray(offset, offset + length); - } - - function containsGltfMagic(uint8Array) { - var magic = getMagic(uint8Array); - return magic === 'glTF'; - } - - /** - * <p> - * Creates a model from a glTF asset. When the model is ready to render, i.e., when the external binary, image, - * and shader files are downloaded and the WebGL resources are created, the {@link Model#readyPromise} is resolved. - * </p> - * <p> - * The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the - * KHR_binary_glTF extension with a .glb extension. - * </p> - * <p> - * For high-precision rendering, Cesium supports the CESIUM_RTC extension, which introduces the - * CESIUM_RTC_MODELVIEW parameter semantic that says the node is in WGS84 coordinates translated - * relative to a local origin. - * </p> - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url to the .gltf file. - * @param {Object} [options.headers] HTTP headers to send with the request. - * @param {String} [options.basePath] The base path that paths in the glTF JSON are relative to. - * @param {Boolean} [options.show=true] Determines if the model primitive will be shown. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. - * @param {Number} [options.scale=1.0] A uniform scale applied to this model. - * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. - * @param {Number} [options.maximumScale] The maximum scale for the model. - * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. - * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. - * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. - * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each {@link DrawCommand} in the model. - * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. - * - * @returns {Model} The newly created model. - * - * @exception {DeveloperError} bgltf is not a valid Binary glTF file. - * @exception {DeveloperError} Only glTF Binary version 1 is supported. - * - * @example - * // Example 1. Create a model from a glTF asset - * var model = scene.primitives.add(Cesium.Model.fromGltf({ - * url : './duck/duck.gltf' - * })); - * - * @example - * // Example 2. Create model and provide all properties and events - * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); - * var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); - * - * var model = scene.primitives.add(Cesium.Model.fromGltf({ - * url : './duck/duck.gltf', - * show : true, // default - * modelMatrix : modelMatrix, - * scale : 2.0, // double size - * minimumPixelSize : 128, // never smaller than 128 pixels - * maximumScale: 20000, // never larger than 20000 * model size (overrides minimumPixelSize) - * allowPicking : false, // not pickable - * debugShowBoundingVolume : false, // default - * debugWireframe : false - * })); + WallGeometryUpdater.prototype.isOutlineVisible = function(time) { + var entity = this._entity; + return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + }; + + /** + * Checks if the geometry is filled at the provided time. * - * model.readyPromise.then(function(model) { - * // Play all animations when the model is ready to render - * model.activeAnimations.addAll(); - * }); + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. */ - Model.fromGltf = function(options) { - if (!defined(options) || !defined(options.url)) { - throw new DeveloperError('options.url is required'); - } - - var url = options.url; - // If no cache key is provided, use the absolute URL, since two URLs with - // different relative paths could point to the same model. - var cacheKey = defaultValue(options.cacheKey, getAbsoluteUri(url)); - var basePath = defaultValue(options.basePath, getBaseUri(url, true)); + WallGeometryUpdater.prototype.isFilled = function(time) { + var entity = this._entity; + return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + }; - options = clone(options); - if (defined(options.basePath) && !defined(options.cacheKey)) { - cacheKey += basePath; + /** + * Creates the geometry instance which represents the fill of the geometry. + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + WallGeometryUpdater.prototype.createFillGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - options.cacheKey = cacheKey; - options.basePath = basePath; - var model = new Model(options); - - options.headers = defined(options.headers) ? clone(options.headers) : {}; - if (!defined(options.headers.Accept)) { - options.headers.Accept = defaultModelAccept; + if (!this._fillEnabled) { + throw new DeveloperError('This instance does not represent a filled geometry.'); } + + var entity = this._entity; + var isAvailable = entity.isAvailable(time); - var cachedGltf = gltfCache[cacheKey]; - if (!defined(cachedGltf)) { - cachedGltf = new CachedGltf({ - ready : false - }); - cachedGltf.count = 1; - cachedGltf.modelsToLoad.push(model); - setCachedGltf(model, cachedGltf); - gltfCache[cacheKey] = cachedGltf; + var attributes; - loadArrayBuffer(url, options.headers).then(function(arrayBuffer) { - var array = new Uint8Array(arrayBuffer); - if (containsGltfMagic(array)) { - // Load binary glTF - var parsedGltf = parseBinaryGltf(array); - // KHR_binary_glTF is from the beginning of the binary section - cachedGltf.makeReady(parsedGltf, array); - } else { - // Load text (JSON) glTF - var json = getStringFromTypedArray(array); - cachedGltf.makeReady(JSON.parse(json)); - } - }).otherwise(getFailedLoadFunction(model, 'model', url)); - } else if (!cachedGltf.ready) { - // Cache hit but the loadArrayBuffer() or loadText() request is still pending - ++cachedGltf.count; - cachedGltf.modelsToLoad.push(model); + var color; + var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + if (this._materialProperty instanceof ColorMaterialProperty) { + var currentColor = Color.WHITE; + if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { + currentColor = this._materialProperty.color.getValue(time); + } + color = ColorGeometryInstanceAttribute.fromColor(currentColor); + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute, + color : color + }; + } else { + attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; } - // else if the cached glTF is defined and ready, the - // model constructor will pick it up using the cache key. - return model; + return new GeometryInstance({ + id : entity, + geometry : new WallGeometry(this._options), + attributes : attributes + }); }; /** - * For the unit tests to verify model caching. + * Creates the geometry instance which represents the outline of the geometry. * - * @private + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. */ - Model._gltfCache = gltfCache; - - function getRuntime(model, runtimeName, name) { - if (model._state !== ModelState.LOADED) { - throw new DeveloperError('The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.'); + WallGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); } - if (!defined(name)) { - throw new DeveloperError('name is required.'); + if (!this._outlineEnabled) { + throw new DeveloperError('This instance does not represent an outlined geometry.'); } - return (model._runtime[runtimeName])[name]; - } + var entity = this._entity; + var isAvailable = entity.isAvailable(time); + var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); + var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - /** - * Returns the glTF node with the given <code>name</code> property. This is used to - * modify a node's transform for animation outside of glTF animations. - * - * @param {String} name The glTF name of the node. - * @returns {ModelNode} The node or <code>undefined</code> if no node with <code>name</code> exists. - * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. - * - * @example - * // Apply non-uniform scale to node LOD3sp - * var node = model.getNode('LOD3sp'); - * node.matrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix); - */ - Model.prototype.getNode = function(name) { - var node = getRuntime(this, 'nodesByName', name); - return defined(node) ? node.publicNode : undefined; + return new GeometryInstance({ + id : entity, + geometry : new WallOutlineGeometry(this._options), + attributes : { + show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), + color : ColorGeometryInstanceAttribute.fromColor(outlineColor), + distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + } + }); }; /** - * Returns the glTF mesh with the given <code>name</code> property. - * - * @param {String} name The glTF name of the mesh. - * - * @returns {ModelMesh} The mesh or <code>undefined</code> if no mesh with <code>name</code> exists. + * Returns true if this object was destroyed; otherwise, false. * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - Model.prototype.getMesh = function(name) { - return getRuntime(this, 'meshesByName', name); + WallGeometryUpdater.prototype.isDestroyed = function() { + return false; }; /** - * Returns the glTF material with the given <code>name</code> property. - * - * @param {String} name The glTF name of the material. - * @returns {ModelMaterial} The material or <code>undefined</code> if no material with <code>name</code> exists. + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ - Model.prototype.getMaterial = function(name) { - return getRuntime(this, 'materialsByName', name); + WallGeometryUpdater.prototype.destroy = function() { + this._entitySubscription(); + destroyObject(this); }; - var aMinScratch = new Cartesian3(); - var aMaxScratch = new Cartesian3(); + WallGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { + if (!(propertyName === 'availability' || propertyName === 'wall')) { + return; + } - function getAccessorMinMax(gltf, accessorId) { - var accessor = gltf.accessors[accessorId]; - var extensions = accessor.extensions; - var accessorMin = accessor.min; - var accessorMax = accessor.max; - // If this accessor is quantized, we should use the decoded min and max - if (defined(extensions)) { - var quantizedAttributes = extensions.WEB3D_quantized_attributes; - if (defined(quantizedAttributes)) { - accessorMin = quantizedAttributes.decodedMin; - accessorMax = quantizedAttributes.decodedMax; + var wall = this._entity.wall; + + if (!defined(wall)) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); } + return; } - return { - min : accessorMin, - max : accessorMax - }; - } - function computeBoundingSphere(model) { - var gltf = model.gltf; - var gltfNodes = gltf.nodes; - var gltfMeshes = gltf.meshes; - var rootNodes = gltf.scenes[gltf.scene].nodes; - var rootNodesLength = rootNodes.length; + var fillProperty = wall.fill; + var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; - var nodeStack = []; + var outlineProperty = wall.outline; + var outlineEnabled = defined(outlineProperty); + if (outlineEnabled && outlineProperty.isConstant) { + outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + } - var min = new Cartesian3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); - var max = new Cartesian3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + if (!fillEnabled && !outlineEnabled) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - for (var i = 0; i < rootNodesLength; ++i) { - var n = gltfNodes[rootNodes[i]]; - n._transformToRoot = getTransform(n); - nodeStack.push(n); + var positions = wall.positions; - while (nodeStack.length > 0) { - n = nodeStack.pop(); - var transformToRoot = n._transformToRoot; + var show = wall.show; + if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // + (!defined(positions))) { + if (this._fillEnabled || this._outlineEnabled) { + this._fillEnabled = false; + this._outlineEnabled = false; + this._geometryChanged.raiseEvent(this); + } + return; + } - var meshId = n.mesh; - if (defined(meshId)) { - var mesh = gltfMeshes[meshId]; - var primitives = mesh.primitives; - var primitivesLength = primitives.length; - for (var m = 0; m < primitivesLength; ++m) { - var positionAccessor = primitives[m].attributes.POSITION; - if (defined(positionAccessor)) { - var minMax = getAccessorMinMax(gltf, positionAccessor); - var aMin = Cartesian3.fromArray(minMax.min, 0, aMinScratch); - var aMax = Cartesian3.fromArray(minMax.max, 0, aMaxScratch); - if (defined(min) && defined(max)) { - Matrix4.multiplyByPoint(transformToRoot, aMin, aMin); - Matrix4.multiplyByPoint(transformToRoot, aMax, aMax); - Cartesian3.minimumByComponent(min, aMin, min); - Cartesian3.maximumByComponent(max, aMax, max); - } - } - } - } + var material = defaultValue(wall.material, defaultMaterial); + var isColorMaterial = material instanceof ColorMaterialProperty; + this._materialProperty = material; + this._fillProperty = defaultValue(fillProperty, defaultFill); + this._showProperty = defaultValue(show, defaultShow); + this._showOutlineProperty = defaultValue(wall.outline, defaultOutline); + this._outlineColorProperty = outlineEnabled ? defaultValue(wall.outlineColor, defaultOutlineColor) : undefined; + this._shadowsProperty = defaultValue(wall.shadows, defaultShadows); + this._distanceDisplayConditionProperty = defaultValue(wall.distanceDisplayCondition, defaultDistanceDisplayCondition); - var children = n.children; - var childrenLength = children.length; - for (var k = 0; k < childrenLength; ++k) { - var child = gltfNodes[children[k]]; - child._transformToRoot = getTransform(child); - Matrix4.multiplyTransformation(transformToRoot, child._transformToRoot, child._transformToRoot); - nodeStack.push(child); - } - delete n._transformToRoot; + var minimumHeights = wall.minimumHeights; + var maximumHeights = wall.maximumHeights; + var outlineWidth = wall.outlineWidth; + var granularity = wall.granularity; + + this._fillEnabled = fillEnabled; + this._outlineEnabled = outlineEnabled; + + if (!positions.isConstant || // + !Property.isConstant(minimumHeights) || // + !Property.isConstant(maximumHeights) || // + !Property.isConstant(outlineWidth) || // + !Property.isConstant(granularity)) { + if (!this._dynamic) { + this._dynamic = true; + this._geometryChanged.raiseEvent(this); } + } else { + var options = this._options; + options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + options.positions = positions.getValue(Iso8601.MINIMUM_VALUE, options.positions); + options.minimumHeights = defined(minimumHeights) ? minimumHeights.getValue(Iso8601.MINIMUM_VALUE, options.minimumHeights) : undefined; + options.maximumHeights = defined(maximumHeights) ? maximumHeights.getValue(Iso8601.MINIMUM_VALUE, options.maximumHeights) : undefined; + options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; + this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; + this._dynamic = false; + this._geometryChanged.raiseEvent(this); } + }; - var boundingSphere = BoundingSphere.fromCornerPoints(min, max); - if (model._upAxis === Axis.Y) { - BoundingSphere.transformWithoutScale(boundingSphere, Axis.Y_UP_TO_Z_UP, boundingSphere); - } else if (model._upAxis === Axis.X) { - BoundingSphere.transformWithoutScale(boundingSphere, Axis.X_UP_TO_Z_UP, boundingSphere); + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + WallGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { + if (!this._dynamic) { + throw new DeveloperError('This instance does not represent dynamic geometry.'); } - return boundingSphere; - } - - /////////////////////////////////////////////////////////////////////////// - - function getFailedLoadFunction(model, type, path) { - return function() { - model._state = ModelState.FAILED; - model._readyPromise.reject(new RuntimeError('Failed to load ' + type + ': ' + path)); - }; - } - function addBuffersToLoadResources(model) { - var gltf = model.gltf; - var loadResources = model._loadResources; - ForEach.buffer(gltf, function(buffer, id) { - loadResources.buffers[id] = buffer.extras._pipeline.source; - }); - } + if (!defined(primitives)) { + throw new DeveloperError('primitives is required.'); + } + + return new DynamicGeometryUpdater(primitives, this); + }; - function bufferLoad(model, id) { - return function(arrayBuffer) { - var loadResources = model._loadResources; - var buffer = new Uint8Array(arrayBuffer); - --loadResources.pendingBufferLoads; - model.gltf.buffers[id].extras._pipeline.source = buffer; - }; + /** + * @private + */ + function DynamicGeometryUpdater(primitives, geometryUpdater) { + this._primitives = primitives; + this._primitive = undefined; + this._outlinePrimitive = undefined; + this._geometryUpdater = geometryUpdater; + this._options = new GeometryOptions(geometryUpdater._entity); } + DynamicGeometryUpdater.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + this._primitive = undefined; + this._outlinePrimitive = undefined; - function parseBuffers(model) { - var loadResources = model._loadResources; - // Iterate this way for compatibility with objects and arrays - var buffers = model.gltf.buffers; - for (var id in buffers) { - if (buffers.hasOwnProperty(id)) { - var buffer = buffers[id]; - buffer.extras = defaultValue(buffer.extras, {}); - buffer.extras._pipeline = defaultValue(buffer.extras._pipeline, {}); - if (defined(buffer.extras._pipeline.source)) { - loadResources.buffers[id] = buffer.extras._pipeline.source; - } else { - var bufferPath = joinUrls(model._baseUri, buffer.uri); - ++loadResources.pendingBufferLoads; - loadArrayBuffer(bufferPath).then(bufferLoad(model, id)).otherwise(getFailedLoadFunction(model, 'buffer', bufferPath)); - } - } + var geometryUpdater = this._geometryUpdater; + var entity = geometryUpdater._entity; + var wall = entity.wall; + if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(wall.show, time, true)) { + return; } - } - function parseBufferViews(model) { - var bufferViews = model.gltf.bufferViews; + var options = this._options; + var positions = Property.getValueOrUndefined(wall.positions, time, options.positions); + if (!defined(positions)) { + return; + } - var vertexBuffersToCreate = model._loadResources.vertexBuffersToCreate; + options.positions = positions; + options.minimumHeights = Property.getValueOrUndefined(wall.minimumHeights, time, options.minimumHeights); + options.maximumHeights = Property.getValueOrUndefined(wall.maximumHeights, time, options.maximumHeights); + options.granularity = Property.getValueOrUndefined(wall.granularity, time); - // Only ARRAY_BUFFER here. ELEMENT_ARRAY_BUFFER created below. - ForEach.bufferView(model.gltf, function(bufferView, id) { - if (bufferView.target === WebGLConstants.ARRAY_BUFFER) { - vertexBuffersToCreate.enqueue(id); - } - }); + var shadows = this._geometryUpdater.shadowsProperty.getValue(time); - var indexBuffersToCreate = model._loadResources.indexBuffersToCreate; - var indexBufferIds = {}; + if (Property.getValueOrDefault(wall.fill, time, true)) { + var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); + this._material = material; - // The Cesium Renderer requires knowing the datatype for an index buffer - // at creation type, which is not part of the glTF bufferview so loop - // through glTF accessors to create the bufferview's index buffer. - ForEach.accessor(model.gltf, function(accessor) { - var bufferViewId = accessor.bufferView; - var bufferView = bufferViews[bufferViewId]; + var appearance = new MaterialAppearance({ + material : material, + translucent : material.isTranslucent(), + closed : defined(options.extrudedHeight) + }); + options.vertexFormat = appearance.vertexFormat; - if ((bufferView.target === WebGLConstants.ELEMENT_ARRAY_BUFFER) && !defined(indexBufferIds[bufferViewId])) { - indexBufferIds[bufferViewId] = true; - indexBuffersToCreate.enqueue({ - id : bufferViewId, - componentType : accessor.componentType - }); - } - }); - } + this._primitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new WallGeometry(options) + }), + appearance : appearance, + asynchronous : false, + shadows : shadows + })); + } - function shaderLoad(model, type, id) { - return function(source) { - var loadResources = model._loadResources; - loadResources.shaders[id] = { - source : source, - type : type, - bufferView : undefined - }; - --loadResources.pendingShaderLoads; - model.gltf.shaders[id].extras._pipeline.source = source; - }; - } + if (Property.getValueOrDefault(wall.outline, time, false)) { + options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; - function parseShaders(model) { - var gltf = model.gltf; - var buffers = gltf.buffers; - var bufferViews = gltf.bufferViews; - ForEach.shader(gltf, function(shader, id) { - // Shader references either uri (external or base64-encoded) or bufferView - if (defined(shader.bufferView)) { - var bufferViewId = shader.bufferView; - var bufferView = bufferViews[bufferViewId]; - var bufferId = bufferView.buffer; - var buffer = buffers[bufferId]; - var source = getStringFromTypedArray(buffer.extras._pipeline.source, bufferView.byteOffset, bufferView.byteLength); - model._loadResources.shaders[id] = { - source : source, - bufferView : undefined - }; - shader.extras._pipeline.source = source; - } else if (defined(shader.extras._pipeline.source)) { - model._loadResources.shaders[id] = { - source : shader.extras._pipeline.source, - bufferView : undefined - }; - } else { - ++model._loadResources.pendingShaderLoads; - var shaderPath = joinUrls(model._baseUri, shader.uri); - loadText(shaderPath).then(shaderLoad(model, shader.type, id)).otherwise(getFailedLoadFunction(model, 'shader', shaderPath)); - } - }); - } + var outlineColor = Property.getValueOrClonedDefault(wall.outlineColor, time, Color.BLACK, scratchColor); + var outlineWidth = Property.getValueOrDefault(wall.outlineWidth, time, 1.0); + var translucent = outlineColor.alpha !== 1.0; - function parsePrograms(model) { - ForEach.program(model.gltf, function(program, id) { - model._loadResources.programsToCreate.enqueue(id); - }); - } + this._outlinePrimitive = primitives.add(new Primitive({ + geometryInstances : new GeometryInstance({ + id : entity, + geometry : new WallOutlineGeometry(options), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : translucent, + renderState : { + lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + }), + asynchronous : false, + shadows : shadows + })); + } + }; - function imageLoad(model, textureId, imageId) { - return function(image) { - var gltf = model.gltf; - var loadResources = model._loadResources; - --loadResources.pendingTextureLoads; - loadResources.texturesToCreate.enqueue({ - id : textureId, - image : image, - bufferView : image.bufferView, - width : image.width, - height : image.height, - internalFormat : image.internalFormat - }); - gltf.images[imageId].extras._pipeline.source = image; - }; - } + DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { + return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + }; - var ktxRegex = /(^data:image\/ktx)|(\.ktx$)/i; - var crnRegex = /(^data:image\/crn)|(\.crn$)/i; + DynamicGeometryUpdater.prototype.isDestroyed = function() { + return false; + }; - function parseTextures(model, context) { - var gltf = model.gltf; - var images = gltf.images; - var uri; - ForEach.texture(gltf, function(texture, id) { - var imageId = texture.source; - var gltfImage = images[imageId]; - var extras = gltfImage.extras; + DynamicGeometryUpdater.prototype.destroy = function() { + var primitives = this._primitives; + primitives.removeAndDestroy(this._primitive); + primitives.removeAndDestroy(this._outlinePrimitive); + destroyObject(this); + }; - var bufferViewId = gltfImage.bufferView; - var mimeType = gltfImage.mimeType; - uri = gltfImage.uri; + return WallGeometryUpdater; +}); - // First check for a compressed texture - if (defined(extras) && defined(extras.compressedImage3DTiles)) { - var crunch = extras.compressedImage3DTiles.crunch; - var s3tc = extras.compressedImage3DTiles.s3tc; - var pvrtc = extras.compressedImage3DTiles.pvrtc1; - var etc1 = extras.compressedImage3DTiles.etc1; +define('DataSources/DataSourceDisplay',[ + '../Core/BoundingSphere', + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/EventHelper', + '../Scene/GroundPrimitive', + './BillboardVisualizer', + './BoundingSphereState', + './BoxGeometryUpdater', + './CorridorGeometryUpdater', + './CustomDataSource', + './CylinderGeometryUpdater', + './EllipseGeometryUpdater', + './EllipsoidGeometryUpdater', + './GeometryVisualizer', + './LabelVisualizer', + './ModelVisualizer', + './PathVisualizer', + './PlaneGeometryUpdater', + './PointVisualizer', + './PolygonGeometryUpdater', + './PolylineGeometryUpdater', + './PolylineVolumeGeometryUpdater', + './RectangleGeometryUpdater', + './WallGeometryUpdater' + ], function( + BoundingSphere, + Check, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + EventHelper, + GroundPrimitive, + BillboardVisualizer, + BoundingSphereState, + BoxGeometryUpdater, + CorridorGeometryUpdater, + CustomDataSource, + CylinderGeometryUpdater, + EllipseGeometryUpdater, + EllipsoidGeometryUpdater, + GeometryVisualizer, + LabelVisualizer, + ModelVisualizer, + PathVisualizer, + PlaneGeometryUpdater, + PointVisualizer, + PolygonGeometryUpdater, + PolylineGeometryUpdater, + PolylineVolumeGeometryUpdater, + RectangleGeometryUpdater, + WallGeometryUpdater) { + 'use strict'; - if (context.s3tc && defined(crunch)) { - mimeType = crunch.mimeType; - if (defined(crunch.bufferView)) { - bufferViewId = crunch.bufferView; - } else { - uri = crunch.uri; - } - } else if (context.s3tc && defined(s3tc)) { - mimeType = s3tc.mimeType; - if (defined(s3tc.bufferView)) { - bufferViewId = s3tc.bufferView; - } else { - uri = s3tc.uri; - } - } else if (context.pvrtc && defined(pvrtc)) { - mimeType = pvrtc.mimeType; - if (defined(pvrtc.bufferView)) { - bufferViewId = pvrtc.bufferView; - } else { - uri = pvrtc.uri; - } - } else if (context.etc1 && defined(etc1)) { - mimeType = etc1.mimeType; - if (defined(etc1.bufferView)) { - bufferViewId = etc1.bufferView; - } else { - uri = etc1.uri; - } - } - } + /** + * Visualizes a collection of {@link DataSource} instances. + * @alias DataSourceDisplay + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Scene} options.scene The scene in which to display the data. + * @param {DataSourceCollection} options.dataSourceCollection The data sources to display. + * @param {DataSourceDisplay~VisualizersCallback} [options.visualizersCallback=DataSourceDisplay.defaultVisualizersCallback] + * A function which creates an array of visualizers used for visualization. + * If undefined, all standard visualizers are used. + */ + function DataSourceDisplay(options) { + Check.typeOf.object('options', options); + Check.typeOf.object('options.scene', options.scene); + Check.typeOf.object('options.dataSourceCollection', options.dataSourceCollection); + + GroundPrimitive.initializeTerrainHeights(); - // Image references either uri (external or base64-encoded) or bufferView - if (defined(bufferViewId)) { - model._loadResources.texturesToCreateFromBufferView.enqueue({ - id : id, - image : undefined, - bufferView : bufferViewId, - mimeType : mimeType - }); - } else { - ++model._loadResources.pendingTextureLoads; - uri = new Uri(uri); - var imagePath = joinUrls(model._baseUri, uri); + var scene = options.scene; + var dataSourceCollection = options.dataSourceCollection; - var promise; - if (ktxRegex.test(imagePath)) { - promise = loadKTX(imagePath); - } else if (crnRegex.test(imagePath)) { - promise = loadCRN(imagePath); - } else { - promise = loadImage(imagePath); - } - promise.then(imageLoad(model, id, imageId)).otherwise(getFailedLoadFunction(model, 'image', imagePath)); - } - }); - } + this._eventHelper = new EventHelper(); + this._eventHelper.add(dataSourceCollection.dataSourceAdded, this._onDataSourceAdded, this); + this._eventHelper.add(dataSourceCollection.dataSourceRemoved, this._onDataSourceRemoved, this); - var nodeTranslationScratch = new Cartesian3(); - var nodeQuaternionScratch = new Quaternion(); - var nodeScaleScratch = new Cartesian3(); + this._dataSourceCollection = dataSourceCollection; + this._scene = scene; + this._visualizersCallback = defaultValue(options.visualizersCallback, DataSourceDisplay.defaultVisualizersCallback); - function getTransform(node) { - if (defined(node.matrix)) { - return Matrix4.fromArray(node.matrix); + for (var i = 0, len = dataSourceCollection.length; i < len; i++) { + this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i)); } - return Matrix4.fromTranslationQuaternionRotationScale( - Cartesian3.fromArray(node.translation, 0, nodeTranslationScratch), - Quaternion.unpack(node.rotation, 0, nodeQuaternionScratch), - Cartesian3.fromArray(node.scale, 0, nodeScaleScratch)); - } - - function parseNodes(model) { - var runtimeNodes = {}; - var runtimeNodesByName = {}; - var skinnedNodes = []; + var defaultDataSource = new CustomDataSource(); + this._onDataSourceAdded(undefined, defaultDataSource); + this._defaultDataSource = defaultDataSource; - var skinnedNodesIds = model._loadResources.skinnedNodesIds; + this._ready = false; + } - ForEach.node(model.gltf, function(node, id) { - var runtimeNode = { - // Animation targets - matrix : undefined, - translation : undefined, - rotation : undefined, - scale : undefined, + /** + * Gets or sets the default function which creates an array of visualizers used for visualization. + * By default, this function uses all standard visualizers. + * + * @member + * @type {DataSourceDisplay~VisualizersCallback} + */ + DataSourceDisplay.defaultVisualizersCallback = function(scene, entityCluster, dataSource) { + var entities = dataSource.entities; + return [new BillboardVisualizer(entityCluster, entities), + new GeometryVisualizer(BoxGeometryUpdater, scene, entities), + new GeometryVisualizer(CylinderGeometryUpdater, scene, entities), + new GeometryVisualizer(CorridorGeometryUpdater, scene, entities), + new GeometryVisualizer(EllipseGeometryUpdater, scene, entities), + new GeometryVisualizer(EllipsoidGeometryUpdater, scene, entities), + new GeometryVisualizer(PlaneGeometryUpdater, scene, entities), + new GeometryVisualizer(PolygonGeometryUpdater, scene, entities), + new GeometryVisualizer(PolylineGeometryUpdater, scene, entities), + new GeometryVisualizer(PolylineVolumeGeometryUpdater, scene, entities), + new GeometryVisualizer(RectangleGeometryUpdater, scene, entities), + new GeometryVisualizer(WallGeometryUpdater, scene, entities), + new LabelVisualizer(entityCluster, entities), + new ModelVisualizer(scene, entities), + new PointVisualizer(entityCluster, entities), + new PathVisualizer(scene, entities)]; + }; - // Per-node show inherited from parent - computedShow : true, + defineProperties(DataSourceDisplay.prototype, { + /** + * Gets the scene associated with this display. + * @memberof DataSourceDisplay.prototype + * @type {Scene} + */ + scene : { + get : function() { + return this._scene; + } + }, + /** + * Gets the collection of data sources to display. + * @memberof DataSourceDisplay.prototype + * @type {DataSourceCollection} + */ + dataSources : { + get : function() { + return this._dataSourceCollection; + } + }, + /** + * Gets the default data source instance which can be used to + * manually create and visualize entities not tied to + * a specific data source. This instance is always available + * and does not appear in the list dataSources collection. + * @memberof DataSourceDisplay.prototype + * @type {CustomDataSource} + */ + defaultDataSource : { + get : function() { + return this._defaultDataSource; + } + }, - // Computed transforms - transformToRoot : new Matrix4(), - computedMatrix : new Matrix4(), - dirtyNumber : 0, // The frame this node was made dirty by an animation; for graph traversal + /** + * Gets a value indicating whether or not all entities in the data source are ready + * @memberof DataSourceDisplay.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; + } + } + }); - // Rendering - commands : [], // empty for transform, light, and camera nodes + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see DataSourceDisplay#destroy + */ + DataSourceDisplay.prototype.isDestroyed = function() { + return false; + }; - // Skinned node - inverseBindMatrices : undefined, // undefined when node is not skinned - bindShapeMatrix : undefined, // undefined when node is not skinned or identity - joints : [], // empty when node is not skinned - computedJointMatrices : [], // empty when node is not skinned + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * dataSourceDisplay = dataSourceDisplay.destroy(); + * + * @see DataSourceDisplay#isDestroyed + */ + DataSourceDisplay.prototype.destroy = function() { + this._eventHelper.removeAll(); - // Joint node - jointName : node.jointName, // undefined when node is not a joint + var dataSourceCollection = this._dataSourceCollection; + for (var i = 0, length = dataSourceCollection.length; i < length; ++i) { + this._onDataSourceRemoved(this._dataSourceCollection, dataSourceCollection.get(i)); + } + this._onDataSourceRemoved(undefined, this._defaultDataSource); - weights : [], + return destroyObject(this); + }; - // Graph pointers - children : [], // empty for leaf nodes - parents : [], // empty for root nodes + /** + * Updates the display to the provided time. + * + * @param {JulianDate} time The simulation time. + * @returns {Boolean} True if all data sources are ready to be displayed, false otherwise. + */ + DataSourceDisplay.prototype.update = function(time) { + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + + if (!GroundPrimitive._initialized) { + this._ready = false; + return false; + } - // Publicly-accessible ModelNode instance to modify animation targets - publicNode : undefined - }; - runtimeNode.publicNode = new ModelNode(model, node, runtimeNode, id, getTransform(node)); + var result = true; - runtimeNodes[id] = runtimeNode; - runtimeNodesByName[node.name] = runtimeNode; + var i; + var x; + var visualizers; + var vLength; + var dataSources = this._dataSourceCollection; + var length = dataSources.length; + for (i = 0; i < length; i++) { + var dataSource = dataSources.get(i); + if (defined(dataSource.update)) { + result = dataSource.update(time) && result; + } - if (defined(node.skin)) { - skinnedNodesIds.push(id); - skinnedNodes.push(runtimeNode); + visualizers = dataSource._visualizers; + vLength = visualizers.length; + for (x = 0; x < vLength; x++) { + result = visualizers[x].update(time) && result; } - }); + } - model._runtime.nodes = runtimeNodes; - model._runtime.nodesByName = runtimeNodesByName; - model._runtime.skinnedNodes = skinnedNodes; - } + visualizers = this._defaultDataSource._visualizers; + vLength = visualizers.length; + for (x = 0; x < vLength; x++) { + result = visualizers[x].update(time) && result; + } - function parseMaterials(model) { - var runtimeMaterialsByName = {}; - var runtimeMaterialsById = {}; - var uniformMaps = model._uniformMaps; + this._ready = result; - ForEach.material(model.gltf, function(material, id) { - // Allocated now so ModelMaterial can keep a reference to it. - uniformMaps[id] = { - uniformMap : undefined, - values : undefined, - jointMatrixUniformName : undefined, - morphWeightsUniformName : undefined - }; + return result; + }; - var modelMaterial = new ModelMaterial(model, material, id); - runtimeMaterialsByName[material.name] = modelMaterial; - runtimeMaterialsById[id] = modelMaterial; - }); + var getBoundingSphereArrayScratch = []; + var getBoundingSphereBoundingSphereScratch = new BoundingSphere(); - model._runtime.materialsByName = runtimeMaterialsByName; - model._runtime.materialsById = runtimeMaterialsById; - } + /** + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. + * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {Boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. + * If false, the the function will halt and return pending if any of the bounding spheres are pending. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private + */ + DataSourceDisplay.prototype.getBoundingSphere = function(entity, allowPartial, result) { + if (!defined(entity)) { + throw new DeveloperError('entity is required.'); + } + if (!defined(allowPartial)) { + throw new DeveloperError('allowPartial is required.'); + } + if (!defined(result)) { + throw new DeveloperError('result is required.'); + } + + if (!this._ready) { + return BoundingSphereState.PENDING; + } - function parseMeshes(model) { - var runtimeMeshesByName = {}; - var runtimeMaterialsById = model._runtime.materialsById; + var i; + var length; + var dataSource = this._defaultDataSource; + if (!dataSource.entities.contains(entity)) { + dataSource = undefined; - ForEach.mesh(model.gltf, function(mesh, id) { - runtimeMeshesByName[mesh.name] = new ModelMesh(mesh, runtimeMaterialsById, id); - if (defined(model.extensionsUsed.WEB3D_quantized_attributes)) { - // Cache primitives according to their program - var primitives = mesh.primitives; - var primitivesLength = primitives.length; - for (var i = 0; i < primitivesLength; i++) { - var primitive = primitives[i]; - var programId = getProgramForPrimitive(model, primitive); - var programPrimitives = model._programPrimitives[programId]; - if (!defined(programPrimitives)) { - programPrimitives = []; - model._programPrimitives[programId] = programPrimitives; - } - programPrimitives.push(primitive); + var dataSources = this._dataSourceCollection; + length = dataSources.length; + for (i = 0; i < length; i++) { + var d = dataSources.get(i); + if (d.entities.contains(entity)) { + dataSource = d; + break; } } - }); - - model._runtime.meshesByName = runtimeMeshesByName; - } - - function getUsedExtensions(model) { - var extensionsUsed = model.gltf.extensionsUsed; - var cachedExtensionsUsed = {}; + } - if (defined(extensionsUsed)) { - var extensionsUsedLength = extensionsUsed.length; - for (var i = 0; i < extensionsUsedLength; i++) { - var extension = extensionsUsed[i]; - cachedExtensionsUsed[extension] = true; - } + if (!defined(dataSource)) { + return BoundingSphereState.FAILED; } - return cachedExtensionsUsed; - } - function getRequiredExtensions(model) { - var extensionsRequired = model.gltf.extensionsRequired; - var cachedExtensionsRequired = {}; + var boundingSpheres = getBoundingSphereArrayScratch; + var tmp = getBoundingSphereBoundingSphereScratch; - if (defined(extensionsRequired)) { - var extensionsRequiredLength = extensionsRequired.length; - for (var i = 0; i < extensionsRequiredLength; i++) { - var extension = extensionsRequired[i]; - cachedExtensionsRequired[extension] = true; + var count = 0; + var state = BoundingSphereState.DONE; + var visualizers = dataSource._visualizers; + var visualizersLength = visualizers.length; + + for (i = 0; i < visualizersLength; i++) { + var visualizer = visualizers[i]; + if (defined(visualizer.getBoundingSphere)) { + state = visualizers[i].getBoundingSphere(entity, tmp); + if (!allowPartial && state === BoundingSphereState.PENDING) { + return BoundingSphereState.PENDING; + } else if (state === BoundingSphereState.DONE) { + boundingSpheres[count] = BoundingSphere.clone(tmp, boundingSpheres[count]); + count++; + } } } - return cachedExtensionsRequired; - } - - /////////////////////////////////////////////////////////////////////////// - - var CreateVertexBufferJob = function() { - this.id = undefined; - this.model = undefined; - this.context = undefined; - }; + if (count === 0) { + return BoundingSphereState.FAILED; + } - CreateVertexBufferJob.prototype.set = function(id, model, context) { - this.id = id; - this.model = model; - this.context = context; + boundingSpheres.length = count; + BoundingSphere.fromBoundingSpheres(boundingSpheres, result); + return BoundingSphereState.DONE; }; - CreateVertexBufferJob.prototype.execute = function() { - createVertexBuffer(this.id, this.model, this.context); - }; + DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource) { + var scene = this._scene; - /////////////////////////////////////////////////////////////////////////// + var entityCluster = dataSource.clustering; + entityCluster._initialize(scene); - function createVertexBuffer(bufferViewId, model, context) { - var loadResources = model._loadResources; - var bufferViews = model.gltf.bufferViews; - var bufferView = bufferViews[bufferViewId]; + scene.primitives.add(entityCluster); - var vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : loadResources.getBuffer(bufferView), - usage : BufferUsage.STATIC_DRAW - }); - vertexBuffer.vertexArrayDestroyable = false; - model._rendererResources.buffers[bufferViewId] = vertexBuffer; - model._geometryByteLength += vertexBuffer.sizeInBytes; - } + dataSource._visualizers = this._visualizersCallback(scene, entityCluster, dataSource); + }; - /////////////////////////////////////////////////////////////////////////// + DataSourceDisplay.prototype._onDataSourceRemoved = function(dataSourceCollection, dataSource) { + var scene = this._scene; + var entityCluster = dataSource.clustering; + scene.primitives.remove(entityCluster); - var CreateIndexBufferJob = function() { - this.id = undefined; - this.componentType = undefined; - this.model = undefined; - this.context = undefined; - }; + var visualizers = dataSource._visualizers; + var length = visualizers.length; + for (var i = 0; i < length; i++) { + visualizers[i].destroy(); + } - CreateIndexBufferJob.prototype.set = function(id, componentType, model, context) { - this.id = id; - this.componentType = componentType; - this.model = model; - this.context = context; + dataSource._visualizers = undefined; }; - CreateIndexBufferJob.prototype.execute = function() { - createIndexBuffer(this.id, this.componentType, this.model, this.context); - }; + /** + * A function which creates an array of visualizers used for visualization. + * @callback DataSourceDisplay~VisualizersCallback + * + * @param {Scene} scene The scene to create visualizers for. + * @param {DataSource} dataSource The data source to create visualizers for. + * @returns {Visualizer[]} An array of visualizers used for visualization. + * + * @example + * function createVisualizers(scene, dataSource) { + * return [new Cesium.BillboardVisualizer(scene, dataSource.entities)]; + * } + */ - /////////////////////////////////////////////////////////////////////////// + return DataSourceDisplay; +}); - function createIndexBuffer(bufferViewId, componentType, model, context) { - var loadResources = model._loadResources; - var bufferViews = model.gltf.bufferViews; - var bufferView = bufferViews[bufferViewId]; +define('DataSources/DynamicGeometryUpdater',[ + '../Core/DeveloperError' + ], function( + DeveloperError) { + 'use strict'; - var indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : loadResources.getBuffer(bufferView), - usage : BufferUsage.STATIC_DRAW, - indexDatatype : componentType - }); - indexBuffer.vertexArrayDestroyable = false; - model._rendererResources.buffers[bufferViewId] = indexBuffer; - model._geometryByteLength += indexBuffer.sizeInBytes; + /** + * Defines the interface for a dynamic geometry updater. A DynamicGeometryUpdater + * is responsible for handling visualization of a specific type of geometry + * that needs to be recomputed based on simulation time. + * This object is never used directly by client code, but is instead created by + * {@link GeometryUpdater} implementations which contain dynamic geometry. + * + * This type defines an interface and cannot be instantiated directly. + * + * @alias DynamicGeometryUpdater + * @constructor + */ + function DynamicGeometryUpdater() { + DeveloperError.throwInstantiationError(); } - var scratchVertexBufferJob = new CreateVertexBufferJob(); - var scratchIndexBufferJob = new CreateIndexBufferJob(); - - function createBuffers(model, frameState) { - var loadResources = model._loadResources; - - if (loadResources.pendingBufferLoads !== 0) { - return; - } - - var context = frameState.context; - var vertexBuffersToCreate = loadResources.vertexBuffersToCreate; - var indexBuffersToCreate = loadResources.indexBuffersToCreate; - var i; + /** + * Updates the geometry to the specified time. + * @memberof DynamicGeometryUpdater + * @function + * + * @param {JulianDate} time The current time. + */ + DynamicGeometryUpdater.prototype.update = DeveloperError.throwInstantiationError; - if (model.asynchronous) { - while (vertexBuffersToCreate.length > 0) { - scratchVertexBufferJob.set(vertexBuffersToCreate.peek(), model, context); - if (!frameState.jobScheduler.execute(scratchVertexBufferJob, JobType.BUFFER)) { - break; - } - vertexBuffersToCreate.dequeue(); - } + /** + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. + * @function + * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private + */ + DynamicGeometryUpdater.prototype.getBoundingSphere = DeveloperError.throwInstantiationError; - while (indexBuffersToCreate.length > 0) { - i = indexBuffersToCreate.peek(); - scratchIndexBufferJob.set(i.id, i.componentType, model, context); - if (!frameState.jobScheduler.execute(scratchIndexBufferJob, JobType.BUFFER)) { - break; - } - indexBuffersToCreate.dequeue(); - } - } else { - while (vertexBuffersToCreate.length > 0) { - createVertexBuffer(vertexBuffersToCreate.dequeue(), model, context); - } + /** + * Returns true if this object was destroyed; otherwise, false. + * @memberof DynamicGeometryUpdater + * @function + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + DynamicGeometryUpdater.prototype.isDestroyed = DeveloperError.throwInstantiationError; - while (indexBuffersToCreate.length > 0) { - i = indexBuffersToCreate.dequeue(); - createIndexBuffer(i.id, i.componentType, model, context); - } - } - } + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @memberof DynamicGeometryUpdater + * @function + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + DynamicGeometryUpdater.prototype.destroy = DeveloperError.throwInstantiationError; - function createAttributeLocations(model, attributes) { - var attributeLocations = {}; - var length = attributes.length; - var i; + return DynamicGeometryUpdater; +}); - // Set the position attribute to the 0th index. In some WebGL implementations the shader - // will not work correctly if the 0th attribute is not active. For example, some glTF models - // list the normal attribute first but derived shaders like the cast-shadows shader do not use - // the normal attribute. - for (i = 1; i < length; ++i) { - var attribute = attributes[i]; - if (/pos/i.test(attribute)) { - attributes[i] = attributes[0]; - attributes[0] = attribute; - break; - } - } +define('DataSources/EntityView',[ + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Ellipsoid', + '../Core/HeadingPitchRange', + '../Core/JulianDate', + '../Core/Math', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/Transforms', + '../Scene/SceneMode' + ], function( + Cartesian3, + defaultValue, + defined, + defineProperties, + DeveloperError, + Ellipsoid, + HeadingPitchRange, + JulianDate, + CesiumMath, + Matrix3, + Matrix4, + Transforms, + SceneMode) { + 'use strict'; - for (i = 0; i < length; ++i) { - attributeLocations[attributes[i]] = i; - } + var updateTransformMatrix3Scratch1 = new Matrix3(); + var updateTransformMatrix3Scratch2 = new Matrix3(); + var updateTransformMatrix3Scratch3 = new Matrix3(); + var updateTransformMatrix4Scratch = new Matrix4(); + var updateTransformCartesian3Scratch1 = new Cartesian3(); + var updateTransformCartesian3Scratch2 = new Cartesian3(); + var updateTransformCartesian3Scratch3 = new Cartesian3(); + var updateTransformCartesian3Scratch4 = new Cartesian3(); + var updateTransformCartesian3Scratch5 = new Cartesian3(); + var updateTransformCartesian3Scratch6 = new Cartesian3(); + var deltaTime = new JulianDate(); + var northUpAxisFactor = 1.25; // times ellipsoid's maximum radius - return attributeLocations; - } + function updateTransform(that, camera, updateLookAt, saveCamera, positionProperty, time, ellipsoid) { + var mode = that.scene.mode; + var cartesian = positionProperty.getValue(time, that._lastCartesian); + if (defined(cartesian)) { + var hasBasis = false; + var invertVelocity = false; + var xBasis; + var yBasis; + var zBasis; - function replaceAllButFirstInString(string, find, replace) { - var index = string.indexOf(find); - return string.replace(new RegExp(find, 'g'), function(match, offset, all) { - return index === offset ? match : replace; - }); - } + if (mode === SceneMode.SCENE3D) { + // The time delta was determined based on how fast satellites move compared to vehicles near the surface. + // Slower moving vehicles will most likely default to east-north-up, while faster ones will be VVLH. + JulianDate.addSeconds(time, 0.001, deltaTime); + var deltaCartesian = positionProperty.getValue(deltaTime, updateTransformCartesian3Scratch1); - function getProgramForPrimitive(model, primitive) { - var gltf = model.gltf; - var materialId = primitive.material; - var material = gltf.materials[materialId]; - var techniqueId = material.technique; - var technique = gltf.techniques[techniqueId]; - return technique.program; - } + // If no valid position at (time + 0.001), sample at (time - 0.001) and invert the vector + if (!defined(deltaCartesian)) { + JulianDate.addSeconds(time, -0.001, deltaTime); + deltaCartesian = positionProperty.getValue(deltaTime, updateTransformCartesian3Scratch1); + invertVelocity = true; + } - function getQuantizedAttributes(model, accessorId) { - var gltf = model.gltf; - var accessor = gltf.accessors[accessorId]; - var extensions = accessor.extensions; - if (defined(extensions)) { - return extensions.WEB3D_quantized_attributes; - } - return undefined; - } + if (defined(deltaCartesian)) { + var toInertial = Transforms.computeFixedToIcrfMatrix(time, updateTransformMatrix3Scratch1); + var toInertialDelta = Transforms.computeFixedToIcrfMatrix(deltaTime, updateTransformMatrix3Scratch2); + var toFixed; - function getAttributeVariableName(model, primitive, attributeSemantic) { - var gltf = model.gltf; - var materialId = primitive.material; - var material = gltf.materials[materialId]; - var techniqueId = material.technique; - var technique = gltf.techniques[techniqueId]; - for (var parameter in technique.parameters) { - if (technique.parameters.hasOwnProperty(parameter)) { - var semantic = technique.parameters[parameter].semantic; - if (semantic === attributeSemantic) { - var attributes = technique.attributes; - for (var attributeVarName in attributes) { - if (attributes.hasOwnProperty(attributeVarName)) { - var name = attributes[attributeVarName]; - if (name === parameter) { - return attributeVarName; - } - } + if (!defined(toInertial) || !defined(toInertialDelta)) { + toFixed = Transforms.computeTemeToPseudoFixedMatrix(time, updateTransformMatrix3Scratch3); + toInertial = Matrix3.transpose(toFixed, updateTransformMatrix3Scratch1); + toInertialDelta = Transforms.computeTemeToPseudoFixedMatrix(deltaTime, updateTransformMatrix3Scratch2); + Matrix3.transpose(toInertialDelta, toInertialDelta); + } else { + toFixed = Matrix3.transpose(toInertial, updateTransformMatrix3Scratch3); } - } - } - } - return undefined; - } - - function modifyShaderForQuantizedAttributes(shader, programName, model, context) { - var quantizedUniforms = {}; - model._quantizedUniforms[programName] = quantizedUniforms; - var primitives = model._programPrimitives[programName]; - for (var i = 0; i < primitives.length; i++) { - var primitive = primitives[i]; - if (getProgramForPrimitive(model, primitive) === programName) { - for (var attributeSemantic in primitive.attributes) { - if (primitive.attributes.hasOwnProperty(attributeSemantic)) { - var attributeVarName = getAttributeVariableName(model, primitive, attributeSemantic); - var accessorId = primitive.attributes[attributeSemantic]; + var inertialCartesian = Matrix3.multiplyByVector(toInertial, cartesian, updateTransformCartesian3Scratch5); + var inertialDeltaCartesian = Matrix3.multiplyByVector(toInertialDelta, deltaCartesian, updateTransformCartesian3Scratch6); - if (attributeSemantic.charAt(0) === '_') { - attributeSemantic = attributeSemantic.substring(1); - } - var decodeUniformVarName = 'gltf_u_dec_' + attributeSemantic.toLowerCase(); - - var decodeUniformVarNameScale = decodeUniformVarName + '_scale'; - var decodeUniformVarNameTranslate = decodeUniformVarName + '_translate'; - if (!defined(quantizedUniforms[decodeUniformVarName]) && !defined(quantizedUniforms[decodeUniformVarNameScale])) { - var quantizedAttributes = getQuantizedAttributes(model, accessorId); - if (defined(quantizedAttributes)) { - var decodeMatrix = quantizedAttributes.decodeMatrix; - var newMain = 'gltf_decoded_' + attributeSemantic; - var decodedAttributeVarName = attributeVarName.replace('a_', 'gltf_a_dec_'); - var size = Math.floor(Math.sqrt(decodeMatrix.length)); - - // replace usages of the original attribute with the decoded version, but not the declaration - shader = replaceAllButFirstInString(shader, attributeVarName, decodedAttributeVarName); - // declare decoded attribute - var variableType; - if (size > 2) { - variableType = 'vec' + (size - 1); - } else { - variableType = 'float'; - } - shader = variableType + ' ' + decodedAttributeVarName + ';\n' + shader; - // splice decode function into the shader - attributes are pre-multiplied with the decode matrix - // uniform in the shader (32-bit floating point) - var decode = ''; - if (size === 5) { - // separate scale and translate since glsl doesn't have mat5 - shader = 'uniform mat4 ' + decodeUniformVarNameScale + ';\n' + shader; - shader = 'uniform vec4 ' + decodeUniformVarNameTranslate + ';\n' + shader; - decode = '\n' + - 'void main() {\n' + - ' ' + decodedAttributeVarName + ' = ' + decodeUniformVarNameScale + ' * ' + attributeVarName + ' + ' + decodeUniformVarNameTranslate + ';\n' + - ' ' + newMain + '();\n' + - '}\n'; - - quantizedUniforms[decodeUniformVarNameScale] = {mat : 4}; - quantizedUniforms[decodeUniformVarNameTranslate] = {vec : 4}; - } - else { - shader = 'uniform mat' + size + ' ' + decodeUniformVarName + ';\n' + shader; - decode = '\n' + - 'void main() {\n' + - ' ' + decodedAttributeVarName + ' = ' + variableType + '(' + decodeUniformVarName + ' * vec' + size + '(' + attributeVarName + ',1.0));\n' + - ' ' + newMain + '();\n' + - '}\n'; - - quantizedUniforms[decodeUniformVarName] = {mat : size}; - } - shader = ShaderSource.replaceMain(shader, newMain); - shader += decode; - } - } - } - } - } - } - // This is not needed after the program is processed, free the memory - model._programPrimitives[programName] = undefined; - return shader; - } + Cartesian3.subtract(inertialCartesian, inertialDeltaCartesian, updateTransformCartesian3Scratch4); + var inertialVelocity = Cartesian3.magnitude(updateTransformCartesian3Scratch4) * 1000.0; // meters/sec - function hasPremultipliedAlpha(model) { - var gltf = model.gltf; - return defined(gltf.asset) ? defaultValue(gltf.asset.premultipliedAlpha, false) : false; - } + // http://en.wikipedia.org/wiki/Standard_gravitational_parameter + // Consider adding this to Cesium.Ellipsoid? + var mu = 3.986004418e14; // m^3 / sec^2 - function modifyShaderForColor(shader, premultipliedAlpha) { - shader = ShaderSource.replaceMain(shader, 'gltf_blend_main'); - shader += - 'uniform vec4 gltf_color; \n' + - 'uniform float gltf_colorBlend; \n' + - 'void main() \n' + - '{ \n' + - ' gltf_blend_main(); \n'; + var semiMajorAxis = -mu / (inertialVelocity * inertialVelocity - (2 * mu / Cartesian3.magnitude(inertialCartesian))); - // Un-premultiply the alpha so that blending is correct. + if (semiMajorAxis < 0 || semiMajorAxis > northUpAxisFactor * ellipsoid.maximumRadius) { + // North-up viewing from deep space. - // Avoid divide-by-zero. The code below is equivalent to: - // if (gl_FragColor.a > 0.0) - // { - // gl_FragColor.rgb /= gl_FragColor.a; - // } + // X along the nadir + xBasis = updateTransformCartesian3Scratch2; + Cartesian3.normalize(cartesian, xBasis); + Cartesian3.negate(xBasis, xBasis); - if (premultipliedAlpha) { - shader += - ' float alpha = 1.0 - ceil(gl_FragColor.a) + gl_FragColor.a; \n' + - ' gl_FragColor.rgb /= alpha; \n'; - } + // Z is North + zBasis = Cartesian3.clone(Cartesian3.UNIT_Z, updateTransformCartesian3Scratch3); - shader += - ' gl_FragColor.rgb = mix(gl_FragColor.rgb, gltf_color.rgb, gltf_colorBlend); \n' + - ' float highlight = ceil(gltf_colorBlend); \n' + - ' gl_FragColor.rgb *= mix(gltf_color.rgb, vec3(1.0), highlight); \n' + - ' gl_FragColor.a *= gltf_color.a; \n' + - '} \n'; + // Y is along the cross of z and x (right handed basis / in the direction of motion) + yBasis = Cartesian3.cross(zBasis, xBasis, updateTransformCartesian3Scratch1); + if (Cartesian3.magnitude(yBasis) > CesiumMath.EPSILON7) { + Cartesian3.normalize(xBasis, xBasis); + Cartesian3.normalize(yBasis, yBasis); - return shader; - } + zBasis = Cartesian3.cross(xBasis, yBasis, updateTransformCartesian3Scratch3); + Cartesian3.normalize(zBasis, zBasis); - function modifyShader(shader, programName, callback) { - if (defined(callback)) { - shader = callback(shader, programName); - } - return shader; - } + hasBasis = true; + } + } else if (!Cartesian3.equalsEpsilon(cartesian, deltaCartesian, CesiumMath.EPSILON7)) { + // Approximation of VVLH (Vehicle Velocity Local Horizontal) with the Z-axis flipped. - var CreateProgramJob = function() { - this.id = undefined; - this.model = undefined; - this.context = undefined; - }; + // Z along the position + zBasis = updateTransformCartesian3Scratch2; + Cartesian3.normalize(inertialCartesian, zBasis); + Cartesian3.normalize(inertialDeltaCartesian, inertialDeltaCartesian); - CreateProgramJob.prototype.set = function(id, model, context) { - this.id = id; - this.model = model; - this.context = context; - }; + // Y is along the angular momentum vector (e.g. "orbit normal") + yBasis = Cartesian3.cross(zBasis, inertialDeltaCartesian, updateTransformCartesian3Scratch3); - CreateProgramJob.prototype.execute = function() { - createProgram(this.id, this.model, this.context); - }; + if(invertVelocity) { + yBasis = Cartesian3.multiplyByScalar(yBasis, -1, yBasis); + } - /////////////////////////////////////////////////////////////////////////// + if (!Cartesian3.equalsEpsilon(yBasis, Cartesian3.ZERO, CesiumMath.EPSILON7)) { + // X is along the cross of y and z (right handed basis / in the direction of motion) + xBasis = Cartesian3.cross(yBasis, zBasis, updateTransformCartesian3Scratch1); - function createProgram(id, model, context) { - var programs = model.gltf.programs; - var shaders = model.gltf.shaders; - var program = programs[id]; + Matrix3.multiplyByVector(toFixed, xBasis, xBasis); + Matrix3.multiplyByVector(toFixed, yBasis, yBasis); + Matrix3.multiplyByVector(toFixed, zBasis, zBasis); - var attributeLocations = createAttributeLocations(model, program.attributes); - var vs = shaders[program.vertexShader].extras._pipeline.source; - var fs = shaders[program.fragmentShader].extras._pipeline.source; + Cartesian3.normalize(xBasis, xBasis); + Cartesian3.normalize(yBasis, yBasis); + Cartesian3.normalize(zBasis, zBasis); - // Add pre-created attributes to attributeLocations - var attributesLength = program.attributes.length; - var precreatedAttributes = model._precreatedAttributes; - if (defined(precreatedAttributes)) { - for (var attrName in precreatedAttributes) { - if (precreatedAttributes.hasOwnProperty(attrName)) { - attributeLocations[attrName] = attributesLength++; + hasBasis = true; + } + } } } - } - if (model.extensionsUsed.WEB3D_quantized_attributes) { - vs = modifyShaderForQuantizedAttributes(vs, id, model, context); - } + if (defined(that.boundingSphere)) { + cartesian = that.boundingSphere.center; + } - var premultipliedAlpha = hasPremultipliedAlpha(model); - var finalFS = modifyShaderForColor(fs, premultipliedAlpha); - if (!FeatureDetection.isInternetExplorer()) { - finalFS = modifyShaderForClippingPlanes(finalFS); - } + var position; + var direction; + var up; - var drawVS = modifyShader(vs, id, model._vertexShaderLoaded); - var drawFS = modifyShader(finalFS, id, model._fragmentShaderLoaded); + if (saveCamera) { + position = Cartesian3.clone(camera.position, updateTransformCartesian3Scratch4); + direction = Cartesian3.clone(camera.direction, updateTransformCartesian3Scratch5); + up = Cartesian3.clone(camera.up, updateTransformCartesian3Scratch6); + } - model._rendererResources.programs[id] = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : drawVS, - fragmentShaderSource : drawFS, - attributeLocations : attributeLocations - }); + var transform = updateTransformMatrix4Scratch; + if (hasBasis) { + transform[0] = xBasis.x; + transform[1] = xBasis.y; + transform[2] = xBasis.z; + transform[3] = 0.0; + transform[4] = yBasis.x; + transform[5] = yBasis.y; + transform[6] = yBasis.z; + transform[7] = 0.0; + transform[8] = zBasis.x; + transform[9] = zBasis.y; + transform[10] = zBasis.z; + transform[11] = 0.0; + transform[12] = cartesian.x; + transform[13] = cartesian.y; + transform[14] = cartesian.z; + transform[15] = 0.0; + } else { + // Stationary or slow-moving, low-altitude objects use East-North-Up. + Transforms.eastNorthUpToFixedFrame(cartesian, ellipsoid, transform); + } - if (model.allowPicking) { - // PERFORMANCE_IDEA: Can optimize this shader with a glTF hint. https://github.com/KhronosGroup/glTF/issues/181 - var pickVS = modifyShader(vs, id, model._pickVertexShaderLoaded); - var pickFS = modifyShader(fs, id, model._pickFragmentShaderLoaded); + camera._setTransform(transform); - if (!model._pickFragmentShaderLoaded) { - pickFS = ShaderSource.createPickFragmentShaderSource(fs, 'uniform'); + if (saveCamera) { + Cartesian3.clone(position, camera.position); + Cartesian3.clone(direction, camera.direction); + Cartesian3.clone(up, camera.up); + Cartesian3.cross(direction, up, camera.right); } + } - model._rendererResources.pickPrograms[id] = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : pickVS, - fragmentShaderSource : pickFS, - attributeLocations : attributeLocations - }); + if (updateLookAt) { + var offset = (mode === SceneMode.SCENE2D || Cartesian3.equals(that._offset3D, Cartesian3.ZERO)) ? undefined : that._offset3D; + camera.lookAtTransform(camera.transform, offset); } } - var scratchCreateProgramJob = new CreateProgramJob(); + /** + * A utility object for tracking an entity with the camera. + * @alias EntityView + * @constructor + * + * @param {Entity} entity The entity to track with the camera. + * @param {Scene} scene The scene to use. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use for orienting the camera. + */ + function EntityView(entity, scene, ellipsoid) { - function createPrograms(model, frameState) { - var loadResources = model._loadResources; - var programsToCreate = loadResources.programsToCreate; + /** + * The entity to track with the camera. + * @type {Entity} + */ + this.entity = entity; - if (loadResources.pendingShaderLoads !== 0) { - return; - } + /** + * The scene in which to track the object. + * @type {Scene} + */ + this.scene = scene; - // PERFORMANCE_IDEA: this could be more fine-grained by looking - // at the shader's bufferView's to determine the buffer dependencies. - if (loadResources.pendingBufferLoads !== 0) { - return; - } + /** + * The ellipsoid to use for orienting the camera. + * @type {Ellipsoid} + */ + this.ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - var context = frameState.context; + /** + * The bounding sphere of the object. + * @type {BoundingSphere} + */ + this.boundingSphere = undefined; - if (model.asynchronous) { - while (programsToCreate.length > 0) { - scratchCreateProgramJob.set(programsToCreate.peek(), model, context); - if (!frameState.jobScheduler.execute(scratchCreateProgramJob, JobType.PROGRAM)) { - break; - } - programsToCreate.dequeue(); - } - } else { - // Create all loaded programs this frame - while (programsToCreate.length > 0) { - createProgram(programsToCreate.dequeue(), model, context); - } - } - } + //Shadow copies of the objects so we can detect changes. + this._lastEntity = undefined; + this._mode = undefined; - function getOnImageCreatedFromTypedArray(loadResources, gltfTexture) { - return function(image) { - loadResources.texturesToCreate.enqueue({ - id : gltfTexture.id, - image : image, - bufferView : undefined - }); + this._lastCartesian = new Cartesian3(); + this._defaultOffset3D = undefined; - --loadResources.pendingBufferViewToImage; - }; + this._offset3D = new Cartesian3(); } - function loadTexturesFromBufferViews(model) { - var loadResources = model._loadResources; - - if (loadResources.pendingBufferLoads !== 0) { - return; + // STATIC properties defined here, not per-instance. + defineProperties(EntityView, { + /** + * Gets or sets a camera offset that will be used to + * initialize subsequent EntityViews. + * @memberof EntityView + * @type {Cartesian3} + */ + defaultOffset3D : { + get : function() { + return this._defaultOffset3D; + }, + set : function(vector) { + this._defaultOffset3D = Cartesian3.clone(vector, new Cartesian3()); + } } + }); - while (loadResources.texturesToCreateFromBufferView.length > 0) { - var gltfTexture = loadResources.texturesToCreateFromBufferView.dequeue(); + // Initialize the static property. + EntityView.defaultOffset3D = new Cartesian3(-14000, 3500, 3500); - var gltf = model.gltf; - var bufferView = gltf.bufferViews[gltfTexture.bufferView]; - var imageId = gltf.textures[gltfTexture.id].source; + var scratchHeadingPitchRange = new HeadingPitchRange(); + var scratchCartesian = new Cartesian3(); - var onerror = getFailedLoadFunction(model, 'image', 'id: ' + gltfTexture.id + ', bufferView: ' + gltfTexture.bufferView); + /** + * Should be called each animation frame to update the camera + * to the latest settings. + * @param {JulianDate} time The current animation time. + * @param {BoundingSphere} boundingSphere bounding sphere of the object. + * + */ + EntityView.prototype.update = function(time, boundingSphere) { + var scene = this.scene; + var entity = this.entity; + var ellipsoid = this.ellipsoid; - if (gltfTexture.mimeType === 'image/ktx') { - loadKTX(loadResources.getBuffer(bufferView)).then(imageLoad(model, gltfTexture.id, imageId)).otherwise(onerror); - ++model._loadResources.pendingTextureLoads; - } else if (gltfTexture.mimeType === 'image/crn') { - loadCRN(loadResources.getBuffer(bufferView)).then(imageLoad(model, gltfTexture.id, imageId)).otherwise(onerror); - ++model._loadResources.pendingTextureLoads; - } else { - var onload = getOnImageCreatedFromTypedArray(loadResources, gltfTexture); - loadImageFromTypedArray(loadResources.getBuffer(bufferView), gltfTexture.mimeType) - .then(onload).otherwise(onerror); - ++loadResources.pendingBufferViewToImage; - } + if (!defined(time)) { + throw new DeveloperError('time is required.'); + } + if (!defined(scene)) { + throw new DeveloperError('EntityView.scene is required.'); + } + if (!defined(entity)) { + throw new DeveloperError('EntityView.entity is required.'); + } + if (!defined(ellipsoid)) { + throw new DeveloperError('EntityView.ellipsoid is required.'); + } + if (!defined(entity.position)) { + throw new DeveloperError('entity.position is required.'); + } + + var sceneMode = scene.mode; + if (sceneMode === SceneMode.MORPHING) { + return; } - } - function createSamplers(model, context) { - var loadResources = model._loadResources; + var positionProperty = entity.position; + var objectChanged = entity !== this._lastEntity; + var sceneModeChanged = sceneMode !== this._mode; - if (loadResources.createSamplers) { - loadResources.createSamplers = false; + var offset3D = this._offset3D; + var camera = scene.camera; - var rendererSamplers = model._rendererResources.samplers; - var samplers = model.gltf.samplers; - for (var id in samplers) { - if (samplers.hasOwnProperty(id)) { - var sampler = samplers[id]; + var updateLookAt = objectChanged || sceneModeChanged; + var saveCamera = true; - rendererSamplers[id] = new Sampler({ - wrapS : sampler.wrapS, - wrapT : sampler.wrapT, - minificationFilter : sampler.minFilter, - magnificationFilter : sampler.magFilter - }); + if (objectChanged) { + var viewFromProperty = entity.viewFrom; + var hasViewFrom = defined(viewFromProperty); + + if (!hasViewFrom && defined(boundingSphere)) { + //The default HPR is not ideal for high altitude objects so + //we scale the pitch as we get further from the earth for a more + //downward view. + scratchHeadingPitchRange.pitch = -CesiumMath.PI_OVER_FOUR; + scratchHeadingPitchRange.range = 0; + var position = positionProperty.getValue(time, scratchCartesian); + if (defined(position)) { + var factor = 2 - 1 / Math.max(1, Cartesian3.magnitude(position) / ellipsoid.maximumRadius); + scratchHeadingPitchRange.pitch *= factor; } + + camera.viewBoundingSphere(boundingSphere, scratchHeadingPitchRange); + this.boundingSphere = boundingSphere; + updateLookAt = false; + saveCamera = false; + } else if (!hasViewFrom || !defined(viewFromProperty.getValue(time, offset3D))) { + Cartesian3.clone(EntityView._defaultOffset3D, offset3D); } + } else if (!sceneModeChanged && scene.mode !== SceneMode.MORPHING && this._mode !== SceneMode.SCENE2D) { + Cartesian3.clone(camera.position, offset3D); } - } - - /////////////////////////////////////////////////////////////////////////// - var CreateTextureJob = function() { - this.gltfTexture = undefined; - this.model = undefined; - this.context = undefined; - }; + this._lastEntity = entity; + this._mode = scene.mode !== SceneMode.MORPHING ? scene.mode : this._mode; - CreateTextureJob.prototype.set = function(gltfTexture, model, context) { - this.gltfTexture = gltfTexture; - this.model = model; - this.context = context; + if (scene.mode !== SceneMode.MORPHING) { + updateTransform(this, camera, updateLookAt, saveCamera, positionProperty, time, ellipsoid); + } }; - CreateTextureJob.prototype.execute = function() { - createTexture(this.gltfTexture, this.model, this.context); - }; + return EntityView; +}); - /////////////////////////////////////////////////////////////////////////// +/** +@license +topojson - https://github.com/mbostock/topojson - function createTexture(gltfTexture, model, context) { - var textures = model.gltf.textures; - var texture = textures[gltfTexture.id]; +Copyright (c) 2012, Michael Bostock +All rights reserved. - var rendererSamplers = model._rendererResources.samplers; - var sampler = rendererSamplers[texture.sampler]; - sampler = defaultValue(sampler, new Sampler({ - wrapS : TextureWrap.REPEAT, - wrapT : TextureWrap.REPEAT - })); +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: - var internalFormat = gltfTexture.internalFormat; +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. - var mipmap = - (!(defined(internalFormat) && PixelFormat.isCompressedFormat(internalFormat))) && - ((sampler.minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) || - (sampler.minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) || - (sampler.minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) || - (sampler.minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR)); - var requiresNpot = mipmap || - (sampler.wrapS === TextureWrap.REPEAT) || - (sampler.wrapS === TextureWrap.MIRRORED_REPEAT) || - (sampler.wrapT === TextureWrap.REPEAT) || - (sampler.wrapT === TextureWrap.MIRRORED_REPEAT); +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - var tx; - var source = gltfTexture.image; +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. - if (defined(internalFormat) && texture.target === WebGLConstants.TEXTURE_2D) { - tx = new Texture({ - context : context, - source : { - arrayBufferView : gltfTexture.bufferView - }, - width : gltfTexture.width, - height : gltfTexture.height, - pixelFormat : internalFormat, - sampler : sampler - }); - } else if (defined(source)) { - var npot = !CesiumMath.isPowerOfTwo(source.width) || !CesiumMath.isPowerOfTwo(source.height); +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ - if (requiresNpot && npot) { - // WebGL requires power-of-two texture dimensions for mipmapping and REPEAT/MIRRORED_REPEAT wrap modes. - var canvas = document.createElement('canvas'); - canvas.width = CesiumMath.nextPowerOfTwo(source.width); - canvas.height = CesiumMath.nextPowerOfTwo(source.height); - var canvasContext = canvas.getContext('2d'); - canvasContext.drawImage(source, 0, 0, source.width, source.height, 0, 0, canvas.width, canvas.height); - source = canvas; - } +!function() { + var topojson = { + version: "1.6.18", + mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); }, + meshArcs: meshArcs, + merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); }, + mergeArcs: mergeArcs, + feature: featureOrCollection, + neighbors: neighbors, + presimplify: presimplify + }; - if (texture.target === WebGLConstants.TEXTURE_2D) { - tx = new Texture({ - context : context, - source : source, - pixelFormat : texture.internalFormat, - pixelDatatype : texture.type, - sampler : sampler, - flipY : false - }); - // GLTF_SPEC: Support TEXTURE_CUBE_MAP. https://github.com/KhronosGroup/glTF/issues/40 - if (mipmap) { - tx.generateMipmap(); - } - } - } - if (defined(tx)) { - model._rendererResources.textures[gltfTexture.id] = tx; - model._texturesByteLength += tx.sizeInBytes; - } - } + function stitchArcs(topology, arcs) { + var stitchedArcs = {}, + fragmentByStart = {}, + fragmentByEnd = {}, + fragments = [], + emptyIndex = -1; - var scratchCreateTextureJob = new CreateTextureJob(); + // Stitch empty arcs first, since they may be subsumed by other arcs. + arcs.forEach(function(i, j) { + var arc = topology.arcs[i < 0 ? ~i : i], t; + if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { + t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; + } + }); - function createTextures(model, frameState) { - var context = frameState.context; - var texturesToCreate = model._loadResources.texturesToCreate; + arcs.forEach(function(i) { + var e = ends(i), + start = e[0], + end = e[1], + f, g; - if (model.asynchronous) { - while (texturesToCreate.length > 0) { - scratchCreateTextureJob.set(texturesToCreate.peek(), model, context); - if (!frameState.jobScheduler.execute(scratchCreateTextureJob, JobType.TEXTURE)) { - break; - } - texturesToCreate.dequeue(); - } + if (f = fragmentByEnd[start]) { + delete fragmentByEnd[f.end]; + f.push(i); + f.end = end; + if (g = fragmentByStart[end]) { + delete fragmentByStart[g.start]; + var fg = g === f ? f : f.concat(g); + fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; } else { - // Create all loaded textures this frame - while (texturesToCreate.length > 0) { - createTexture(texturesToCreate.dequeue(), model, context); - } - } - } - - function getAttributeLocations(model, primitive) { - var gltf = model.gltf; - var techniques = gltf.techniques; - var materials = gltf.materials; - - // Retrieve the compiled shader program to assign index values to attributes - var attributeLocations = {}; - - var location; - var index; - var technique = techniques[materials[primitive.material].technique]; - var parameters = technique.parameters; - var attributes = technique.attributes; - var program = model._rendererResources.programs[technique.program]; - var programVertexAttributes = program.vertexAttributes; - var programAttributeLocations = program._attributeLocations; - - // Note: WebGL shader compiler may have optimized and removed some attributes from programVertexAttributes - for (location in programVertexAttributes) { - if (programVertexAttributes.hasOwnProperty(location)) { - var attribute = attributes[location]; - index = programVertexAttributes[location].index; - if (defined(attribute)) { - var parameter = parameters[attribute]; - attributeLocations[parameter.semantic] = index; - } - } + fragmentByStart[f.start] = fragmentByEnd[f.end] = f; } - - // Always add pre-created attributes. - // Some pre-created attributes, like per-instance pickIds, may be compiled out of the draw program - // but should be included in the list of attribute locations for the pick program. - // This is safe to do since programVertexAttributes and programAttributeLocations are equivalent except - // that programVertexAttributes optimizes out unused attributes. - var precreatedAttributes = model._precreatedAttributes; - if (defined(precreatedAttributes)) { - for (location in precreatedAttributes) { - if (precreatedAttributes.hasOwnProperty(location)) { - index = programAttributeLocations[location]; - attributeLocations[location] = index; - } - } + } else if (f = fragmentByStart[end]) { + delete fragmentByStart[f.start]; + f.unshift(i); + f.start = start; + if (g = fragmentByEnd[start]) { + delete fragmentByEnd[g.end]; + var gf = g === f ? f : g.concat(f); + fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; + } else { + fragmentByStart[f.start] = fragmentByEnd[f.end] = f; } + } else { + f = [i]; + fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; + } + }); - return attributeLocations; + function ends(i) { + var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; + if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); + else p1 = arc[arc.length - 1]; + return i < 0 ? [p1, p0] : [p0, p1]; } - function mapJointNames(forest, nodes) { - var length = forest.length; - var jointNodes = {}; - for (var i = 0; i < length; ++i) { - var stack = [forest[i]]; // Push root node of tree + function flush(fragmentByEnd, fragmentByStart) { + for (var k in fragmentByEnd) { + var f = fragmentByEnd[k]; + delete fragmentByStart[f.start]; + delete f.start; + delete f.end; + f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); + fragments.push(f); + } + } - while (stack.length > 0) { - var id = stack.pop(); - var n = nodes[id]; + flush(fragmentByEnd, fragmentByStart); + flush(fragmentByStart, fragmentByEnd); + arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); - if (defined(n)) { - jointNodes[id] = id; - } + return fragments; + } - var children = n.children; - var childrenLength = children.length; - for (var k = 0; k < childrenLength; ++k) { - stack.push(children[k]); - } - } - } - return jointNodes; - } + function meshArcs(topology, o, filter) { + var arcs = []; - function createJoints(model, runtimeSkins) { - var gltf = model.gltf; - var skins = gltf.skins; - var nodes = gltf.nodes; - var runtimeNodes = model._runtime.nodes; + if (arguments.length > 1) { + var geomsByArc = [], + geom; - var skinnedNodesIds = model._loadResources.skinnedNodesIds; - var length = skinnedNodesIds.length; - for (var j = 0; j < length; ++j) { - var id = skinnedNodesIds[j]; - var skinnedNode = runtimeNodes[id]; - var node = nodes[id]; + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } - var runtimeSkin = runtimeSkins[node.skin]; - skinnedNode.inverseBindMatrices = runtimeSkin.inverseBindMatrices; - skinnedNode.bindShapeMatrix = runtimeSkin.bindShapeMatrix; + function line(arcs) { + arcs.forEach(arc); + } - // 1. Find nodes with the names in node.skeletons (the node's skeletons) - // 2. These nodes form the root nodes of the forest to search for each joint in skin.jointNames. This search uses jointName, not the node's name. - // 3. Search for the joint name among the gltf node hierarchy instead of the runtime node hierarchy. Child links aren't set up yet for runtime nodes. - var forest = []; - var skin = skins[node.skin]; - if (defined(skin.skeleton)) { - forest.push(skin.skeleton); - } + function polygon(arcs) { + arcs.forEach(line); + } - var mappedJointNames = mapJointNames(forest, nodes); - var gltfJointNames = skins[node.skin].joints; - var jointNamesLength = gltfJointNames.length; - for (var i = 0; i < jointNamesLength; ++i) { - var jointName = gltfJointNames[i]; - var nodeId = mappedJointNames[jointName]; - var jointNode = runtimeNodes[nodeId]; - skinnedNode.joints.push(jointNode); - } - } - } + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } - function createSkins(model) { - var loadResources = model._loadResources; + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs) { arcs.forEach(polygon); } + }; - if (loadResources.pendingBufferLoads !== 0) { - return; - } + geometry(o); - if (!loadResources.createSkins) { - return; - } - loadResources.createSkins = false; + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + } - var gltf = model.gltf; - var accessors = gltf.accessors; - var runtimeSkins = {}; + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } - ForEach.skin(gltf, function(skin, id) { - var accessor = accessors[skin.inverseBindMatrices]; + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; - var bindShapeMatrix; - if (!Matrix4.equals(skin.bindShapeMatrix, Matrix4.IDENTITY)) { - bindShapeMatrix = Matrix4.clone(skin.bindShapeMatrix); - } + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); - runtimeSkins[id] = { - inverseBindMatrices : ModelAnimationCache.getSkinInverseBindMatrices(model, accessor), - bindShapeMatrix : bindShapeMatrix // not used when undefined - }; + function register(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); }); + }); + polygons.push(polygon); + } - createJoints(model, runtimeSkins); + function exterior(ring) { + return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? } - function getChannelEvaluator(model, runtimeNode, targetPath, spline) { - return function(localAnimationTime) { - // Workaround for https://github.com/KhronosGroup/glTF/issues/219 + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); - //if (targetPath === 'translation') { - // return; - //} - if (defined(spline)) { - localAnimationTime = model.clampAnimations ? spline.clampTime(localAnimationTime) : spline.wrapTime(localAnimationTime); - runtimeNode[targetPath] = spline.evaluate(localAnimationTime, runtimeNode[targetPath]); - runtimeNode.dirtyNumber = model._maxDirtyNumber; - } - }; - } + polygons.forEach(function(polygon) { + delete polygon._; + }); - function createRuntimeAnimations(model) { - var loadResources = model._loadResources; + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = []; - if (!loadResources.finishedPendingBufferLoads()) { - return; - } + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); - if (!loadResources.createRuntimeAnimations) { - return; + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // this exterior ring has the same winding order + // as any exterior ring in the original polygons. + if ((n = arcs.length) > 1) { + var sgn = exterior(polygons[0][0]); + for (var i = 0, t; i < n; ++i) { + if (sgn === exterior(arcs[i])) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; + break; + } + } } - loadResources.createRuntimeAnimations = false; - model._runtime.animations = []; + return arcs; + }) + }; + } - var runtimeNodes = model._runtime.nodes; - var animations = model.gltf.animations; - var accessors = model.gltf.accessors; + function featureOrCollection(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature(topology, o); }) + } : feature(topology, o); + } - var length = animations.length; - for (var i = 0; i < length; ++i) { - var animation = animations[i]; - var channels = animation.channels; - var samplers = animation.samplers; + function feature(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } - // Find start and stop time for the entire animation - var startTime = Number.MAX_VALUE; - var stopTime = -Number.MAX_VALUE; + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; - var channelsLength = channels.length; - var channelEvaluators = new Array(channelsLength); + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); + } - for (var j = 0; j < channelsLength; ++j) { - var channel = channels[j]; - var target = channel.target; - var path = target.path; - var sampler = samplers[channel.sampler]; - var input = ModelAnimationCache.getAnimationParameterValues(model, accessors[sampler.input]); - var output = ModelAnimationCache.getAnimationParameterValues(model, accessors[sampler.output]); + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; + } - startTime = Math.min(startTime, input[0]); - stopTime = Math.max(stopTime, input[input.length - 1]); + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; + } - var spline = ModelAnimationCache.getAnimationSpline(model, i, animation, channel.sampler, sampler, input, path, output); + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; + } - // GLTF_SPEC: Support more targets like materials. https://github.com/KhronosGroup/glTF/issues/142 - channelEvaluators[j] = getChannelEvaluator(model, runtimeNodes[target.node], target.path, spline); - } + function polygon(arcs) { + return arcs.map(ring); + } - model._runtime.animations[i] = { - name : animation.name, - startTime : startTime, - stopTime : stopTime, - channelEvaluators : channelEvaluators - }; - } + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; } - function createVertexArrays(model, context) { - var loadResources = model._loadResources; + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; - if (!loadResources.finishedBuffersCreation() || !loadResources.finishedProgramCreation()) { - return; - } + return geometry(o); + } - if (!loadResources.createVertexArrays) { - return; - } - loadResources.createVertexArrays = false; + function reverse(array, n) { + var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } - var rendererBuffers = model._rendererResources.buffers; - var rendererVertexArrays = model._rendererResources.vertexArrays; - var gltf = model.gltf; - var accessors = gltf.accessors; - var meshes = gltf.meshes; + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } - for (var meshId in meshes) { - if (meshes.hasOwnProperty(meshId)) { - var primitives = meshes[meshId].primitives; - var primitivesLength = primitives.length; + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); - for (var i = 0; i < primitivesLength; ++i) { - var primitive = primitives[i]; + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } - // GLTF_SPEC: This does not take into account attribute arrays, - // indicated by when an attribute points to a parameter with a - // count property. - // - // https://github.com/KhronosGroup/glTF/issues/258 + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } - var attributeLocations = getAttributeLocations(model, primitive); - var attributeName; - var attributeLocation; - var attribute; - var attributes = []; - var primitiveAttributes = primitive.attributes; - for (attributeName in primitiveAttributes) { - if (primitiveAttributes.hasOwnProperty(attributeName)) { - attributeLocation = attributeLocations[attributeName]; - // Skip if the attribute is not used by the material, e.g., because the asset was exported - // with an attribute that wasn't used and the asset wasn't optimized. - if (defined(attributeLocation)) { - var a = accessors[primitiveAttributes[attributeName]]; - var normalize = false; - if (defined(a.normalized) && a.normalized) { - normalize = true; - } + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } - attributes.push({ - index : attributeLocation, - vertexBuffer : rendererBuffers[a.bufferView], - componentsPerAttribute : numberOfComponentsForType(a.type), - componentDatatype : a.componentType, - normalize : normalize, - offsetInBytes : a.byteOffset, - strideInBytes : getAccessorByteStride(gltf, a) - }); - } - } - } + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; - // Add pre-created attributes - var precreatedAttributes = model._precreatedAttributes; - if (defined(precreatedAttributes)) { - for (attributeName in precreatedAttributes) { - if (precreatedAttributes.hasOwnProperty(attributeName)) { - attributeLocation = attributeLocations[attributeName]; - if (defined(attributeLocation)) { - attribute = precreatedAttributes[attributeName]; - attribute.index = attributeLocation; - attributes.push(attribute); - } - } - } - } + objects.forEach(geometry); - var indexBuffer; - if (defined(primitive.indices)) { - var accessor = accessors[primitive.indices]; - indexBuffer = rendererBuffers[accessor.bufferView]; - } - rendererVertexArrays[meshId + '.primitive.' + i] = new VertexArray({ - context : context, - attributes : attributes, - indexBuffer : indexBuffer - }); - } - } + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); } + } } - function getBooleanStates(states) { - // GLTF_SPEC: SAMPLE_ALPHA_TO_COVERAGE not used by Cesium - var booleanStates = {}; - booleanStates[WebGLConstants.BLEND] = false; - booleanStates[WebGLConstants.CULL_FACE] = false; - booleanStates[WebGLConstants.DEPTH_TEST] = false; - booleanStates[WebGLConstants.POLYGON_OFFSET_FILL] = false; + return neighbors; + } - var enable = states.enable; - var length = enable.length; - var i; - for (i = 0; i < length; ++i) { - booleanStates[enable[i]] = true; - } + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); - return booleanStates; - } + if (!triangleArea) triangleArea = cartesianTriangleArea; - function createRenderStates(model, context) { - var loadResources = model._loadResources; - var techniques = model.gltf.techniques; + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle; - if (loadResources.createRenderStates) { - loadResources.createRenderStates = false; - for (var id in techniques) { - if (techniques.hasOwnProperty(id)) { - createRenderStateForTechnique(model, id, context); - } - } - } - } + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (var i = 0, n = arc.length, p; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } - function createRenderStateForTechnique(model, id, context) { - var rendererRenderStates = model._rendererResources.renderStates; - var techniques = model.gltf.techniques; - var technique = techniques[id]; - var states = technique.states; + for (var i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); + triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); + heap.push(triangle); + } - var booleanStates = getBooleanStates(states); - var statesFunctions = defaultValue(states.functions, defaultValue.EMPTY_OBJECT); - var blendColor = defaultValue(statesFunctions.blendColor, [0.0, 0.0, 0.0, 0.0]); - var blendEquationSeparate = defaultValue(statesFunctions.blendEquationSeparate, [ - WebGLConstants.FUNC_ADD, - WebGLConstants.FUNC_ADD]); - var blendFuncSeparate = defaultValue(statesFunctions.blendFuncSeparate, [ - WebGLConstants.ONE, - WebGLConstants.ZERO, - WebGLConstants.ONE, - WebGLConstants.ZERO]); - var colorMask = defaultValue(statesFunctions.colorMask, [true, true, true, true]); - var depthRange = defaultValue(statesFunctions.depthRange, [0.0, 1.0]); - var polygonOffset = defaultValue(statesFunctions.polygonOffset, [0.0, 0.0]); + for (var i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } - // Change the render state to use traditional alpha blending instead of premultiplied alpha blending - if (booleanStates[WebGLConstants.BLEND] && hasPremultipliedAlpha(model)) { - if ((blendFuncSeparate[0] === WebGLConstants.ONE) && (blendFuncSeparate[1] === WebGLConstants.ONE_MINUS_SRC_ALPHA)) { - blendFuncSeparate[0] = WebGLConstants.SRC_ALPHA; - blendFuncSeparate[1] = WebGLConstants.ONE_MINUS_SRC_ALPHA; - blendFuncSeparate[2] = WebGLConstants.SRC_ALPHA; - blendFuncSeparate[3] = WebGLConstants.ONE_MINUS_SRC_ALPHA; - } - } + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; - rendererRenderStates[id] = RenderState.fromCache({ - frontFace : defined(statesFunctions.frontFace) ? statesFunctions.frontFace[0] : WebGLConstants.CCW, - cull : { - enabled : booleanStates[WebGLConstants.CULL_FACE], - face : defined(statesFunctions.cullFace) ? statesFunctions.cullFace[0] : WebGLConstants.BACK - }, - lineWidth : defined(statesFunctions.lineWidth) ? statesFunctions.lineWidth[0] : 1.0, - polygonOffset : { - enabled : booleanStates[WebGLConstants.POLYGON_OFFSET_FILL], - factor : polygonOffset[0], - units : polygonOffset[1] - }, - depthRange : { - near : depthRange[0], - far : depthRange[1] - }, - depthTest : { - enabled : booleanStates[WebGLConstants.DEPTH_TEST], - func : defined(statesFunctions.depthFunc) ? statesFunctions.depthFunc[0] : WebGLConstants.LESS - }, - colorMask : { - red : colorMask[0], - green : colorMask[1], - blue : colorMask[2], - alpha : colorMask[3] - }, - depthMask : defined(statesFunctions.depthMask) ? statesFunctions.depthMask[0] : true, - blending : { - enabled : booleanStates[WebGLConstants.BLEND], - color : { - red : blendColor[0], - green : blendColor[1], - blue : blendColor[2], - alpha : blendColor[3] - }, - equationRgb : blendEquationSeparate[0], - equationAlpha : blendEquationSeparate[1], - functionSourceRgb : blendFuncSeparate[0], - functionDestinationRgb : blendFuncSeparate[1], - functionSourceAlpha : blendFuncSeparate[2], - functionDestinationAlpha : blendFuncSeparate[3] - } - }); - } + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; - // This doesn't support LOCAL, which we could add if it is ever used. - var scratchTranslationRtc = new Cartesian3(); - var gltfSemanticUniforms = { - MODEL : function(uniformState, model) { - return function() { - return uniformState.model; - }; - }, - VIEW : function(uniformState, model) { - return function() { - return uniformState.view; - }; - }, - PROJECTION : function(uniformState, model) { - return function() { - return uniformState.projection; - }; - }, - MODELVIEW : function(uniformState, model) { - return function() { - return uniformState.modelView; - }; - }, - CESIUM_RTC_MODELVIEW : function(uniformState, model) { - // CESIUM_RTC extension - var mvRtc = new Matrix4(); - return function() { - if (defined(model._rtcCenter)) { - Matrix4.getTranslation(uniformState.model, scratchTranslationRtc); - Cartesian3.add(scratchTranslationRtc, model._rtcCenter, scratchTranslationRtc); - Matrix4.multiplyByPoint(uniformState.view, scratchTranslationRtc, scratchTranslationRtc); - return Matrix4.setTranslation(uniformState.modelView, scratchTranslationRtc, mvRtc); - } - return uniformState.modelView; - }; - }, - MODELVIEWPROJECTION : function(uniformState, model) { - return function() { - return uniformState.modelViewProjection; - }; - }, - MODELINVERSE : function(uniformState, model) { - return function() { - return uniformState.inverseModel; - }; - }, - VIEWINVERSE : function(uniformState, model) { - return function() { - return uniformState.inverseView; - }; - }, - PROJECTIONINVERSE : function(uniformState, model) { - return function() { - return uniformState.inverseProjection; - }; - }, - MODELVIEWINVERSE : function(uniformState, model) { - return function() { - return uniformState.inverseModelView; - }; - }, - MODELVIEWPROJECTIONINVERSE : function(uniformState, model) { - return function() { - return uniformState.inverseModelViewProjection; - }; - }, - MODELINVERSETRANSPOSE : function(uniformState, model) { - return function() { - return uniformState.inverseTransposeModel; - }; - }, - MODELVIEWINVERSETRANSPOSE : function(uniformState, model) { - return function() { - return uniformState.normal; - }; - }, - VIEWPORT : function(uniformState, model) { - return function() { - return uniformState.viewportCartesian4; - }; + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); } - // JOINTMATRIX created in createCommand() - }; - - /////////////////////////////////////////////////////////////////////////// - - function getScalarUniformFunction(value, model) { - var that = { - value : value, - clone : function(source, result) { - return source; - }, - func : function() { - return that.value; - } - }; - return that; - } - function getVec2UniformFunction(value, model) { - var that = { - value : Cartesian2.fromArray(value), - clone : Cartesian2.clone, - func : function() { - return that.value; - } - }; - return that; - } + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } - function getVec3UniformFunction(value, model) { - var that = { - value : Cartesian3.fromArray(value), - clone : Cartesian3.clone, - func : function() { - return that.value; - } - }; - return that; - } + arc.forEach(relative); + }); - function getVec4UniformFunction(value, model) { - var that = { - value : Cartesian4.fromArray(value), - clone : Cartesian4.clone, - func : function() { - return that.value; - } - }; - return that; + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); } - function getMat2UniformFunction(value, model) { - var that = { - value : Matrix2.fromColumnMajorArray(value), - clone : Matrix2.clone, - func : function() { - return that.value; - } - }; - return that; - } + return topology; + } + function cartesianRingArea(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; - function getMat3UniformFunction(value, model) { - var that = { - value : Matrix3.fromColumnMajorArray(value), - clone : Matrix3.clone, - func : function() { - return that.value; - } - }; - return that; + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; } - function getMat4UniformFunction(value, model) { - var that = { - value : Matrix4.fromColumnMajorArray(value), - clone : Matrix4.clone, - func : function() { - return that.value; - } - }; - return that; - } + return area * .5; + } - /////////////////////////////////////////////////////////////////////////// + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } - function DelayLoadedTextureUniform(value, model) { - this._value = undefined; - this._textureId = value.index; - this._model = model; - } + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } - defineProperties(DelayLoadedTextureUniform.prototype, { - value : { - get : function() { - // Use the default texture (1x1 white) until the model's texture is loaded - if (!defined(this._value)) { - var texture = this._model._rendererResources.textures[this._textureId]; - if (defined(texture)) { - this._value = texture; - } else { - return this._model._defaultTexture; - } - } + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; - return this._value; - }, - set : function(value) { - this._value = value; - } - } - }); + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; - DelayLoadedTextureUniform.prototype.clone = function(source, result) { - return source; + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; }; - DelayLoadedTextureUniform.prototype.func = undefined; + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; - /////////////////////////////////////////////////////////////////////////// + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } - function getTextureUniformFunction(value, model) { - var uniform = new DelayLoadedTextureUniform(value, model); - // Define function here to access closure since 'this' can't be - // used when the Renderer sets uniforms. - uniform.func = function() { - return uniform.value; - }; - return uniform; + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } } - var gltfUniformFunctions = {}; - gltfUniformFunctions[WebGLConstants.FLOAT] = getScalarUniformFunction; - gltfUniformFunctions[WebGLConstants.FLOAT_VEC2] = getVec2UniformFunction; - gltfUniformFunctions[WebGLConstants.FLOAT_VEC3] = getVec3UniformFunction; - gltfUniformFunctions[WebGLConstants.FLOAT_VEC4] = getVec4UniformFunction; - gltfUniformFunctions[WebGLConstants.INT] = getScalarUniformFunction; - gltfUniformFunctions[WebGLConstants.INT_VEC2] = getVec2UniformFunction; - gltfUniformFunctions[WebGLConstants.INT_VEC3] = getVec3UniformFunction; - gltfUniformFunctions[WebGLConstants.INT_VEC4] = getVec4UniformFunction; - gltfUniformFunctions[WebGLConstants.BOOL] = getScalarUniformFunction; - gltfUniformFunctions[WebGLConstants.BOOL_VEC2] = getVec2UniformFunction; - gltfUniformFunctions[WebGLConstants.BOOL_VEC3] = getVec3UniformFunction; - gltfUniformFunctions[WebGLConstants.BOOL_VEC4] = getVec4UniformFunction; - gltfUniformFunctions[WebGLConstants.FLOAT_MAT2] = getMat2UniformFunction; - gltfUniformFunctions[WebGLConstants.FLOAT_MAT3] = getMat3UniformFunction; - gltfUniformFunctions[WebGLConstants.FLOAT_MAT4] = getMat4UniformFunction; - gltfUniformFunctions[WebGLConstants.SAMPLER_2D] = getTextureUniformFunction; - // GLTF_SPEC: Support SAMPLER_CUBE. https://github.com/KhronosGroup/glTF/issues/40 + return heap; + } - var gltfUniformsFromNode = { - MODEL : function(uniformState, model, runtimeNode) { - return function() { - return runtimeNode.computedMatrix; - }; - }, - VIEW : function(uniformState, model, runtimeNode) { - return function() { - return uniformState.view; - }; - }, - PROJECTION : function(uniformState, model, runtimeNode) { - return function() { - return uniformState.projection; - }; - }, - MODELVIEW : function(uniformState, model, runtimeNode) { - var mv = new Matrix4(); - return function() { - return Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv); - }; - }, - CESIUM_RTC_MODELVIEW : function(uniformState, model, runtimeNode) { - // CESIUM_RTC extension - var mvRtc = new Matrix4(); - return function() { - Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mvRtc); - return Matrix4.setTranslation(mvRtc, model._rtcCenterEye, mvRtc); - }; - }, - MODELVIEWPROJECTION : function(uniformState, model, runtimeNode) { - var mvp = new Matrix4(); - return function() { - Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mvp); - return Matrix4.multiply(uniformState._projection, mvp, mvp); - }; - }, - MODELINVERSE : function(uniformState, model, runtimeNode) { - var mInverse = new Matrix4(); - return function() { - return Matrix4.inverse(runtimeNode.computedMatrix, mInverse); - }; - }, - VIEWINVERSE : function(uniformState, model) { - return function() { - return uniformState.inverseView; - }; - }, - PROJECTIONINVERSE : function(uniformState, model, runtimeNode) { - return function() { - return uniformState.inverseProjection; - }; - }, - MODELVIEWINVERSE : function(uniformState, model, runtimeNode) { - var mv = new Matrix4(); - var mvInverse = new Matrix4(); - return function() { - Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv); - return Matrix4.inverse(mv, mvInverse); - }; - }, - MODELVIEWPROJECTIONINVERSE : function(uniformState, model, runtimeNode) { - var mvp = new Matrix4(); - var mvpInverse = new Matrix4(); - return function() { - Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mvp); - Matrix4.multiply(uniformState._projection, mvp, mvp); - return Matrix4.inverse(mvp, mvpInverse); - }; - }, - MODELINVERSETRANSPOSE : function(uniformState, model, runtimeNode) { - var mInverse = new Matrix4(); - var mInverseTranspose = new Matrix3(); - return function() { - Matrix4.inverse(runtimeNode.computedMatrix, mInverse); - Matrix4.getRotation(mInverse, mInverseTranspose); - return Matrix3.transpose(mInverseTranspose, mInverseTranspose); - }; - }, - MODELVIEWINVERSETRANSPOSE : function(uniformState, model, runtimeNode) { - var mv = new Matrix4(); - var mvInverse = new Matrix4(); - var mvInverseTranspose = new Matrix3(); - return function() { - Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv); - Matrix4.inverse(mv, mvInverse); - Matrix4.getRotation(mvInverse, mvInverseTranspose); - return Matrix3.transpose(mvInverseTranspose, mvInverseTranspose); - }; - }, - VIEWPORT : function(uniformState, model, runtimeNode) { - return function() { - return uniformState.viewportCartesian4; - }; - } + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; }; + } - function getUniformFunctionFromSource(source, model, semantic, uniformState) { - var runtimeNode = model._runtime.nodes[source]; - return gltfUniformsFromNode[semantic](uniformState, model, runtimeNode); - } - - function createUniformMaps(model, context) { - var loadResources = model._loadResources; - - if (!loadResources.finishedProgramCreation()) { - return; - } + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = (point[0] - dx) / kx | 0, + y1 = (point[1] - dy) / ky | 0; + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } - if (!loadResources.createUniformMaps) { - return; - } - loadResources.createUniformMaps = false; + function noop() {} - var gltf = model.gltf; - var materials = gltf.materials; - var techniques = gltf.techniques; - var uniformMaps = model._uniformMaps; + if (typeof define === "function" && define.amd) define('ThirdParty/topojson',topojson); + else if (typeof module === "object" && module.exports) module.exports = topojson; + else this.topojson = topojson; +}(); - for (var materialId in materials) { - if (materials.hasOwnProperty(materialId)) { - var material = materials[materialId]; - var instanceParameters; - instanceParameters = material.values; - var technique = techniques[material.technique]; - var parameters = technique.parameters; - var uniforms = technique.uniforms; +define('DataSources/GeoJsonDataSource',[ + '../Core/Cartesian3', + '../Core/Color', + '../Core/createGuid', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/getFilenameFromUri', + '../Core/PinBuilder', + '../Core/PolygonHierarchy', + '../Core/Resource', + '../Core/RuntimeError', + '../Scene/HeightReference', + '../Scene/VerticalOrigin', + '../ThirdParty/topojson', + '../ThirdParty/when', + './BillboardGraphics', + './CallbackProperty', + './ColorMaterialProperty', + './ConstantPositionProperty', + './ConstantProperty', + './CorridorGraphics', + './DataSource', + './EntityCluster', + './EntityCollection', + './PolygonGraphics', + './PolylineGraphics' + ], function( + Cartesian3, + Color, + createGuid, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + getFilenameFromUri, + PinBuilder, + PolygonHierarchy, + Resource, + RuntimeError, + HeightReference, + VerticalOrigin, + topojson, + when, + BillboardGraphics, + CallbackProperty, + ColorMaterialProperty, + ConstantPositionProperty, + ConstantProperty, + CorridorGraphics, + DataSource, + EntityCluster, + EntityCollection, + PolygonGraphics, + PolylineGraphics) { + 'use strict'; - var uniformMap = {}; - var uniformValues = {}; - var jointMatrixUniformName; - var morphWeightsUniformName; + function defaultCrsFunction(coordinates) { + return Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2]); + } - // Uniform parameters - for (var name in uniforms) { - if (uniforms.hasOwnProperty(name) && name !== 'extras') { - var parameterName = uniforms[name]; - var parameter = parameters[parameterName]; + var crsNames = { + 'urn:ogc:def:crs:OGC:1.3:CRS84' : defaultCrsFunction, + 'EPSG:4326' : defaultCrsFunction, + 'urn:ogc:def:crs:EPSG::4326' : defaultCrsFunction + }; - // GLTF_SPEC: This does not take into account uniform arrays, - // indicated by parameters with a count property. - // - // https://github.com/KhronosGroup/glTF/issues/258 + var crsLinkHrefs = {}; + var crsLinkTypes = {}; + var defaultMarkerSize = 48; + var defaultMarkerSymbol; + var defaultMarkerColor = Color.ROYALBLUE; + var defaultStroke = Color.YELLOW; + var defaultStrokeWidth = 2; + var defaultFill = Color.fromBytes(255, 255, 0, 100); + var defaultClampToGround = false; - // GLTF_SPEC: In this implementation, material parameters with a - // semantic or targeted via a source (for animation) are not - // targetable for material animations. Is this too strict? - // - // https://github.com/KhronosGroup/glTF/issues/142 + var sizes = { + small : 24, + medium : 48, + large : 64 + }; - if (defined(instanceParameters[parameterName])) { - // Parameter overrides by the instance technique - var uv = gltfUniformFunctions[parameter.type](instanceParameters[parameterName], model); - uniformMap[name] = uv.func; - uniformValues[parameterName] = uv; - } else if (defined(parameter.node)) { - uniformMap[name] = getUniformFunctionFromSource(parameter.node, model, parameter.semantic, context.uniformState); - } else if (defined(parameter.semantic)) { - if (parameter.semantic === 'JOINTMATRIX') { - jointMatrixUniformName = name; - } else if (parameter.semantic === 'MORPHWEIGHTS') { - morphWeightsUniformName = name; - } else { - // Map glTF semantic to Cesium automatic uniform - uniformMap[name] = gltfSemanticUniforms[parameter.semantic](context.uniformState, model); - } - } else if (defined(parameter.value)) { - // Technique value that isn't overridden by a material - var uv2 = gltfUniformFunctions[parameter.type](parameter.value, model); - uniformMap[name] = uv2.func; - uniformValues[parameterName] = uv2; - } + var simpleStyleIdentifiers = ['title', 'description', // + 'marker-size', 'marker-symbol', 'marker-color', 'stroke', // + 'stroke-opacity', 'stroke-width', 'fill', 'fill-opacity']; + + function defaultDescribe(properties, nameProperty) { + var html = ''; + for ( var key in properties) { + if (properties.hasOwnProperty(key)) { + if (key === nameProperty || simpleStyleIdentifiers.indexOf(key) !== -1) { + continue; + } + var value = properties[key]; + if (defined(value)) { + if (typeof value === 'object') { + html += '<tr><th>' + key + '</th><td>' + defaultDescribe(value) + '</td></tr>'; + } else { + html += '<tr><th>' + key + '</th><td>' + value + '</td></tr>'; } } - - var u = uniformMaps[materialId]; - u.uniformMap = uniformMap; // uniform name -> function for the renderer - u.values = uniformValues; // material parameter name -> ModelMaterial for modifying the parameter at runtime - u.jointMatrixUniformName = jointMatrixUniformName; - u.morphWeightsUniformName = morphWeightsUniformName; } } + + if (html.length > 0) { + html = '<table class="cesium-infoBox-defaultTable"><tbody>' + html + '</tbody></table>'; + } + + return html; } - function scaleFromMatrix5Array(matrix) { - return [matrix[0], matrix[1], matrix[2], matrix[3], - matrix[5], matrix[6], matrix[7], matrix[8], - matrix[10], matrix[11], matrix[12], matrix[13], - matrix[15], matrix[16], matrix[17], matrix[18]]; + function createDescriptionCallback(describe, properties, nameProperty) { + var description; + return function(time, result) { + if (!defined(description)) { + description = describe(properties, nameProperty); + } + return description; + }; } - function translateFromMatrix5Array(matrix) { - return [matrix[20], matrix[21], matrix[22], matrix[23]]; + function defaultDescribeProperty(properties, nameProperty) { + return new CallbackProperty(createDescriptionCallback(defaultDescribe, properties, nameProperty), true); } - function createUniformsForQuantizedAttributes(model, primitive, context) { - var gltf = model.gltf; - var accessors = gltf.accessors; - var programId = getProgramForPrimitive(model, primitive); - var quantizedUniforms = model._quantizedUniforms[programId]; - var setUniforms = {}; - var uniformMap = {}; + //GeoJSON specifies only the Feature object has a usable id property + //But since "multi" geometries create multiple entity, + //we can't use it for them either. + function createObject(geoJson, entityCollection, describe) { + var id = geoJson.id; + if (!defined(id) || geoJson.type !== 'Feature') { + id = createGuid(); + } else { + var i = 2; + var finalId = id; + while (defined(entityCollection.getById(finalId))) { + finalId = id + '_' + i; + i++; + } + id = finalId; + } - for (var attribute in primitive.attributes) { - if (primitive.attributes.hasOwnProperty(attribute)) { - var accessorId = primitive.attributes[attribute]; - var a = accessors[accessorId]; - var extensions = a.extensions; + var entity = entityCollection.getOrCreateEntity(id); + var properties = geoJson.properties; + if (defined(properties)) { + entity.properties = properties; - if (attribute.charAt(0) === '_') { - attribute = attribute.substring(1); - } + var nameProperty; - if (defined(extensions)) { - var quantizedAttributes = extensions.WEB3D_quantized_attributes; - if (defined(quantizedAttributes)) { - var decodeMatrix = quantizedAttributes.decodeMatrix; - var uniformVariable = 'gltf_u_dec_' + attribute.toLowerCase(); + //Check for the simplestyle specified name first. + var name = properties.title; + if (defined(name)) { + entity.name = name; + nameProperty = 'title'; + } else { + //Else, find the name by selecting an appropriate property. + //The name will be obtained based on this order: + //1) The first case-insensitive property with the name 'title', + //2) The first case-insensitive property with the name 'name', + //3) The first property containing the word 'title'. + //4) The first property containing the word 'name', + var namePropertyPrecedence = Number.MAX_VALUE; + for ( var key in properties) { + if (properties.hasOwnProperty(key) && properties[key]) { + var lowerKey = key.toLowerCase(); - switch (a.type) { - case AttributeType.SCALAR: - uniformMap[uniformVariable] = getMat2UniformFunction(decodeMatrix, model).func; - setUniforms[uniformVariable] = true; - break; - case AttributeType.VEC2: - uniformMap[uniformVariable] = getMat3UniformFunction(decodeMatrix, model).func; - setUniforms[uniformVariable] = true; - break; - case AttributeType.VEC3: - uniformMap[uniformVariable] = getMat4UniformFunction(decodeMatrix, model).func; - setUniforms[uniformVariable] = true; - break; - case AttributeType.VEC4: - // VEC4 attributes are split into scale and translate because there is no mat5 in GLSL - var uniformVariableScale = uniformVariable + '_scale'; - var uniformVariableTranslate = uniformVariable + '_translate'; - uniformMap[uniformVariableScale] = getMat4UniformFunction(scaleFromMatrix5Array(decodeMatrix), model).func; - uniformMap[uniformVariableTranslate] = getVec4UniformFunction(translateFromMatrix5Array(decodeMatrix), model).func; - setUniforms[uniformVariableScale] = true; - setUniforms[uniformVariableTranslate] = true; - break; + if (namePropertyPrecedence > 1 && lowerKey === 'title') { + namePropertyPrecedence = 1; + nameProperty = key; + break; + } else if (namePropertyPrecedence > 2 && lowerKey === 'name') { + namePropertyPrecedence = 2; + nameProperty = key; + } else if (namePropertyPrecedence > 3 && /title/i.test(key)) { + namePropertyPrecedence = 3; + nameProperty = key; + } else if (namePropertyPrecedence > 4 && /name/i.test(key)) { + namePropertyPrecedence = 4; + nameProperty = key; } } } + if (defined(nameProperty)) { + entity.name = properties[nameProperty]; + } } - } - // If there are any unset quantized uniforms in this program, they should be set to the identity - for (var quantizedUniform in quantizedUniforms) { - if (quantizedUniforms.hasOwnProperty(quantizedUniform)) { - if (!setUniforms[quantizedUniform]) { - var properties = quantizedUniforms[quantizedUniform]; - if (defined(properties.mat)) { - if (properties.mat === 2) { - uniformMap[quantizedUniform] = getMat2UniformFunction(Matrix2.IDENTITY, model).func; - } else if (properties.mat === 3) { - uniformMap[quantizedUniform] = getMat3UniformFunction(Matrix3.IDENTITY, model).func; - } else if (properties.mat === 4) { - uniformMap[quantizedUniform] = getMat4UniformFunction(Matrix4.IDENTITY, model).func; - } - } - if (defined(properties.vec)) { - if (properties.vec === 4) { - uniformMap[quantizedUniform] = getVec4UniformFunction([0, 0, 0, 0], model).func; - } - } - } + var description = properties.description; + if (description !== null) { + entity.description = !defined(description) ? describe(properties, nameProperty) : new ConstantProperty(description); } } - return uniformMap; + return entity; } - function createPickColorFunction(color) { - return function() { - return color; - }; + function coordinatesArrayToCartesianArray(coordinates, crsFunction) { + var positions = new Array(coordinates.length); + for (var i = 0; i < coordinates.length; i++) { + positions[i] = crsFunction(coordinates[i]); + } + return positions; } - function createJointMatricesFunction(runtimeNode) { - return function() { - return runtimeNode.computedJointMatrices; - }; - } + var geoJsonObjectTypes = { + Feature : processFeature, + FeatureCollection : processFeatureCollection, + GeometryCollection : processGeometryCollection, + LineString : processLineString, + MultiLineString : processMultiLineString, + MultiPoint : processMultiPoint, + MultiPolygon : processMultiPolygon, + Point : processPoint, + Polygon : processPolygon, + Topology : processTopology + }; - function createMorphWeightsFunction(runtimeNode) { - return function() { - return runtimeNode.weights; - }; - } + var geometryTypes = { + GeometryCollection : processGeometryCollection, + LineString : processLineString, + MultiLineString : processMultiLineString, + MultiPoint : processMultiPoint, + MultiPolygon : processMultiPolygon, + Point : processPoint, + Polygon : processPolygon, + Topology : processTopology + }; - function createSilhouetteColorFunction(model) { - return function() { - return model.silhouetteColor; - }; - } + // GeoJSON processing functions + function processFeature(dataSource, feature, notUsed, crsFunction, options) { + if (feature.geometry === null) { + //Null geometry is allowed, so just create an empty entity instance for it. + createObject(feature, dataSource._entityCollection, options.describe); + return; + } - function createSilhouetteSizeFunction(model) { - return function() { - return model.silhouetteSize; - }; - } + if (!defined(feature.geometry)) { + throw new RuntimeError('feature.geometry is required.'); + } - function createColorFunction(model) { - return function() { - return model.color; - }; + var geometryType = feature.geometry.type; + var geometryHandler = geometryTypes[geometryType]; + if (!defined(geometryHandler)) { + throw new RuntimeError('Unknown geometry type: ' + geometryType); + } + geometryHandler(dataSource, feature, feature.geometry, crsFunction, options); } - function createClippingPlanesLengthFunction(model) { - return function() { - return model._packedClippingPlanes.length; - }; + function processFeatureCollection(dataSource, featureCollection, notUsed, crsFunction, options) { + var features = featureCollection.features; + for (var i = 0, len = features.length; i < len; i++) { + processFeature(dataSource, features[i], undefined, crsFunction, options); + } } - function createClippingPlanesUnionRegionsFunction(model) { - return function() { - var clippingPlanes = model.clippingPlanes; - if (!defined(clippingPlanes)) { - return false; + function processGeometryCollection(dataSource, geoJson, geometryCollection, crsFunction, options) { + var geometries = geometryCollection.geometries; + for (var i = 0, len = geometries.length; i < len; i++) { + var geometry = geometries[i]; + var geometryType = geometry.type; + var geometryHandler = geometryTypes[geometryType]; + if (!defined(geometryHandler)) { + throw new RuntimeError('Unknown geometry type: ' + geometryType); } - - return clippingPlanes.unionClippingRegions; - }; + geometryHandler(dataSource, geoJson, geometry, crsFunction, options); + } } - function createClippingPlanesFunction(model) { - return function() { - var clippingPlanes = model.clippingPlanes; - var packedPlanes = model._packedClippingPlanes; + function createPoint(dataSource, geoJson, crsFunction, coordinates, options) { + var symbol = options.markerSymbol; + var color = options.markerColor; + var size = options.markerSize; - if (defined(clippingPlanes) && clippingPlanes.enabled) { - clippingPlanes.transformAndPackPlanes(model._modelViewMatrix, packedPlanes); + var properties = geoJson.properties; + if (defined(properties)) { + var cssColor = properties['marker-color']; + if (defined(cssColor)) { + color = Color.fromCssColorString(cssColor); } - return packedPlanes; - }; - } - - function createClippingPlanesEdgeStyleFunction(model) { - return function() { - var clippingPlanes = model.clippingPlanes; - if (!defined(clippingPlanes)) { - return Color.WHITE.withAlpha(0.0); + size = defaultValue(sizes[properties['marker-size']], size); + var markerSymbol = properties['marker-symbol']; + if (defined(markerSymbol)) { + symbol = markerSymbol; } + } - var style = Color.clone(clippingPlanes.edgeColor); - style.alpha = clippingPlanes.edgeWidth; - return style; - }; - } + var canvasOrPromise; + if (defined(symbol)) { + if (symbol.length === 1) { + canvasOrPromise = dataSource._pinBuilder.fromText(symbol.toUpperCase(), color, size); + } else { + canvasOrPromise = dataSource._pinBuilder.fromMakiIconId(symbol, color, size); + } + } else { + canvasOrPromise = dataSource._pinBuilder.fromColor(color, size); + } - function createColorBlendFunction(model) { - return function() { - return ColorBlendMode.getColorBlend(model.colorBlendMode, model.colorBlendAmount); - }; - } + var billboard = new BillboardGraphics(); + billboard.verticalOrigin = new ConstantProperty(VerticalOrigin.BOTTOM); - function triangleCountFromPrimitiveIndices(primitive, indicesCount) { - switch (primitive.mode) { - case PrimitiveType.TRIANGLES: - return (indicesCount / 3); - case PrimitiveType.TRIANGLE_STRIP: - case PrimitiveType.TRIANGLE_FAN: - return Math.max(indicesCount - 2, 0); - default: - return 0; + // Clamp to ground if there isn't a height specified + if (coordinates.length === 2 && options.clampToGround) { + billboard.heightReference = HeightReference.CLAMP_TO_GROUND; } - } - function createCommand(model, gltfNode, runtimeNode, context, scene3DOnly) { - var nodeCommands = model._nodeCommands; - var pickIds = model._pickIds; - var allowPicking = model.allowPicking; - var runtimeMeshesByName = model._runtime.meshesByName; - - var resources = model._rendererResources; - var rendererVertexArrays = resources.vertexArrays; - var rendererPrograms = resources.programs; - var rendererPickPrograms = resources.pickPrograms; - var rendererRenderStates = resources.renderStates; - var uniformMaps = model._uniformMaps; + var entity = createObject(geoJson, dataSource._entityCollection, options.describe); + entity.billboard = billboard; + entity.position = new ConstantPositionProperty(crsFunction(coordinates)); - var gltf = model.gltf; - var accessors = gltf.accessors; - var gltfMeshes = gltf.meshes; - var techniques = gltf.techniques; - var materials = gltf.materials; + var promise = when(canvasOrPromise).then(function(image) { + billboard.image = new ConstantProperty(image); + }).otherwise(function() { + billboard.image = new ConstantProperty(dataSource._pinBuilder.fromColor(color, size)); + }); - var id = gltfNode.mesh; - var mesh = gltfMeshes[id]; + dataSource._promises.push(promise); + } - var primitives = mesh.primitives; - var length = primitives.length; + function processPoint(dataSource, geoJson, geometry, crsFunction, options) { + createPoint(dataSource, geoJson, crsFunction, geometry.coordinates, options); + } - // The glTF node hierarchy is a DAG so a node can have more than one - // parent, so a node may already have commands. If so, append more - // since they will have a different model matrix. + function processMultiPoint(dataSource, geoJson, geometry, crsFunction, options) { + var coordinates = geometry.coordinates; + for (var i = 0; i < coordinates.length; i++) { + createPoint(dataSource, geoJson, crsFunction, coordinates[i], options); + } + } - for (var i = 0; i < length; ++i) { - var primitive = primitives[i]; - var ix = accessors[primitive.indices]; - var material = materials[primitive.material]; - var technique = techniques[material.technique]; - var programId = technique.program; + function createLineString(dataSource, geoJson, crsFunction, coordinates, options) { + var material = options.strokeMaterialProperty; + var widthProperty = options.strokeWidthProperty; - var boundingSphere; - var positionAccessor = primitive.attributes.POSITION; - if (defined(positionAccessor)) { - var minMax = getAccessorMinMax(gltf, positionAccessor); - boundingSphere = BoundingSphere.fromCornerPoints(Cartesian3.fromArray(minMax.min), Cartesian3.fromArray(minMax.max)); + var properties = geoJson.properties; + if (defined(properties)) { + var width = properties['stroke-width']; + if (defined(width)) { + widthProperty = new ConstantProperty(width); } - var vertexArray = rendererVertexArrays[id + '.primitive.' + i]; - var offset; - var count; - if (defined(ix)) { - count = ix.count; - offset = (ix.byteOffset / IndexDatatype.getSizeInBytes(ix.componentType)); // glTF has offset in bytes. Cesium has offsets in indices + var color; + var stroke = properties.stroke; + if (defined(stroke)) { + color = Color.fromCssColorString(stroke); } - else { - var positions = accessors[primitive.attributes.POSITION]; - count = positions.count; - offset = 0; + var opacity = properties['stroke-opacity']; + if (defined(opacity) && opacity !== 1.0) { + if (!defined(color)) { + color = material.color.clone(); + } + color.alpha = opacity; } - - // Update model triangle count using number of indices - model._trianglesLength += triangleCountFromPrimitiveIndices(primitive, count); - - var um = uniformMaps[primitive.material]; - var uniformMap = um.uniformMap; - if (defined(um.jointMatrixUniformName)) { - var jointUniformMap = {}; - jointUniformMap[um.jointMatrixUniformName] = createJointMatricesFunction(runtimeNode); - - uniformMap = combine(uniformMap, jointUniformMap); + if (defined(color)) { + material = new ColorMaterialProperty(color); } - if (defined(um.morphWeightsUniformName)) { - var morphWeightsUniformMap = {}; - morphWeightsUniformMap[um.morphWeightsUniformName] = createMorphWeightsFunction(runtimeNode); + } - uniformMap = combine(uniformMap, morphWeightsUniformMap); - } + var entity = createObject(geoJson, dataSource._entityCollection, options.describe); + var graphics; + if (options.clampToGround) { + graphics = new CorridorGraphics(); + entity.corridor = graphics; + } else { + graphics = new PolylineGraphics(); + entity.polyline = graphics; + } - uniformMap = combine(uniformMap, { - gltf_color : createColorFunction(model), - gltf_colorBlend : createColorBlendFunction(model), - gltf_clippingPlanesLength: createClippingPlanesLengthFunction(model), - gltf_clippingPlanesUnionRegions: createClippingPlanesUnionRegionsFunction(model), - gltf_clippingPlanes: createClippingPlanesFunction(model, context), - gltf_clippingPlanesEdgeStyle: createClippingPlanesEdgeStyleFunction(model) - }); + graphics.material = material; + graphics.width = widthProperty; + graphics.positions = new ConstantProperty(coordinatesArrayToCartesianArray(coordinates, crsFunction)); + } - // Allow callback to modify the uniformMap - if (defined(model._uniformMapLoaded)) { - uniformMap = model._uniformMapLoaded(uniformMap, programId, runtimeNode); - } + function processLineString(dataSource, geoJson, geometry, crsFunction, options) { + createLineString(dataSource, geoJson, crsFunction, geometry.coordinates, options); + } - // Add uniforms for decoding quantized attributes if used - if (model.extensionsUsed.WEB3D_quantized_attributes) { - var quantizedUniformMap = createUniformsForQuantizedAttributes(model, primitive, context); - uniformMap = combine(uniformMap, quantizedUniformMap); - } + function processMultiLineString(dataSource, geoJson, geometry, crsFunction, options) { + var lineStrings = geometry.coordinates; + for (var i = 0; i < lineStrings.length; i++) { + createLineString(dataSource, geoJson, crsFunction, lineStrings[i], options); + } + } - var rs = rendererRenderStates[material.technique]; + function createPolygon(dataSource, geoJson, crsFunction, coordinates, options) { + if (coordinates.length === 0 || coordinates[0].length === 0) { + return; + } - // GLTF_SPEC: Offical means to determine translucency. https://github.com/KhronosGroup/glTF/issues/105 - var isTranslucent = rs.blending.enabled; + var outlineColorProperty = options.strokeMaterialProperty.color; + var material = options.fillMaterialProperty; + var widthProperty = options.strokeWidthProperty; - var owner = model._pickObject; - if (!defined(owner)) { - owner = { - primitive : model, - id : model.id, - node : runtimeNode.publicNode, - mesh : runtimeMeshesByName[mesh.name] - }; + var properties = geoJson.properties; + if (defined(properties)) { + var width = properties['stroke-width']; + if (defined(width)) { + widthProperty = new ConstantProperty(width); } - var castShadows = ShadowMode.castShadows(model._shadows); - var receiveShadows = ShadowMode.receiveShadows(model._shadows); - - var command = new DrawCommand({ - boundingVolume : new BoundingSphere(), // updated in update() - cull : model.cull, - modelMatrix : new Matrix4(), // computed in update() - primitiveType : primitive.mode, - vertexArray : vertexArray, - count : count, - offset : offset, - shaderProgram : rendererPrograms[technique.program], - castShadows : castShadows, - receiveShadows : receiveShadows, - uniformMap : uniformMap, - renderState : rs, - owner : owner, - pass : isTranslucent ? Pass.TRANSLUCENT : model.opaquePass - }); - - var pickCommand; - - if (allowPicking) { - var pickUniformMap; - - // Callback to override default model picking - if (defined(model._pickFragmentShaderLoaded)) { - if (defined(model._pickUniformMapLoaded)) { - pickUniformMap = model._pickUniformMapLoaded(uniformMap); - } else { - // This is unlikely, but could happen if the override shader does not - // need new uniforms since, for example, its pick ids are coming from - // a vertex attribute or are baked into the shader source. - pickUniformMap = combine(uniformMap); - } - } else { - var pickId = context.createPickId(owner); - pickIds.push(pickId); - var pickUniforms = { - czm_pickColor : createPickColorFunction(pickId.color) - }; - pickUniformMap = combine(uniformMap, pickUniforms); + var color; + var stroke = properties.stroke; + if (defined(stroke)) { + color = Color.fromCssColorString(stroke); + } + var opacity = properties['stroke-opacity']; + if (defined(opacity) && opacity !== 1.0) { + if (!defined(color)) { + color = options.strokeMaterialProperty.color.clone(); } - - pickCommand = new DrawCommand({ - boundingVolume : new BoundingSphere(), // updated in update() - cull : model.cull, - modelMatrix : new Matrix4(), // computed in update() - primitiveType : primitive.mode, - vertexArray : vertexArray, - count : count, - offset : offset, - shaderProgram : rendererPickPrograms[technique.program], - uniformMap : pickUniformMap, - renderState : rs, - owner : owner, - pass : isTranslucent ? Pass.TRANSLUCENT : model.opaquePass - }); + color.alpha = opacity; } - var command2D; - var pickCommand2D; - if (!scene3DOnly) { - command2D = DrawCommand.shallowClone(command); - command2D.boundingVolume = new BoundingSphere(); // updated in update() - command2D.modelMatrix = new Matrix4(); // updated in update() + if (defined(color)) { + outlineColorProperty = new ConstantProperty(color); + } - if (allowPicking) { - pickCommand2D = DrawCommand.shallowClone(pickCommand); - pickCommand2D.boundingVolume = new BoundingSphere(); // updated in update() - pickCommand2D.modelMatrix = new Matrix4(); // updated in update() + var fillColor; + var fill = properties.fill; + if (defined(fill)) { + fillColor = Color.fromCssColorString(fill); + fillColor.alpha = material.color.alpha; + } + opacity = properties['fill-opacity']; + if (defined(opacity) && opacity !== material.color.alpha) { + if (!defined(fillColor)) { + fillColor = material.color.clone(); } + fillColor.alpha = opacity; + } + if (defined(fillColor)) { + material = new ColorMaterialProperty(fillColor); } - - var nodeCommand = { - show : true, - boundingSphere : boundingSphere, - command : command, - pickCommand : pickCommand, - command2D : command2D, - pickCommand2D : pickCommand2D, - // Generated on demand when silhouette size is greater than 0.0 and silhouette alpha is greater than 0.0 - silhouetteModelCommand : undefined, - silhouetteModelCommand2D : undefined, - silhouetteColorCommand : undefined, - silhouetteColorCommand2D : undefined, - // Generated on demand when color alpha is less than 1.0 - translucentCommand : undefined, - translucentCommand2D : undefined - }; - runtimeNode.commands.push(nodeCommand); - nodeCommands.push(nodeCommand); } - } - - function createRuntimeNodes(model, context, scene3DOnly) { - var loadResources = model._loadResources; + var polygon = new PolygonGraphics(); + polygon.outline = new ConstantProperty(true); + polygon.outlineColor = outlineColorProperty; + polygon.outlineWidth = widthProperty; + polygon.material = material; - if (!loadResources.finishedEverythingButTextureCreation()) { - return; + var holes = []; + for (var i = 1, len = coordinates.length; i < len; i++) { + holes.push(new PolygonHierarchy(coordinatesArrayToCartesianArray(coordinates[i], crsFunction))); } - if (!loadResources.createRuntimeNodes) { - return; + var positions = coordinates[0]; + polygon.hierarchy = new ConstantProperty(new PolygonHierarchy(coordinatesArrayToCartesianArray(positions, crsFunction), holes)); + if (positions[0].length > 2) { + polygon.perPositionHeight = new ConstantProperty(true); + } else if (!options.clampToGround) { + polygon.height = 0; } - loadResources.createRuntimeNodes = false; - - var rootNodes = []; - var runtimeNodes = model._runtime.nodes; - var gltf = model.gltf; - var nodes = gltf.nodes; - var skins = gltf.skins; + var entity = createObject(geoJson, dataSource._entityCollection, options.describe); + entity.polygon = polygon; + } - var scene = gltf.scenes[gltf.scene]; - var sceneNodes = scene.nodes; - var length = sceneNodes.length; + function processPolygon(dataSource, geoJson, geometry, crsFunction, options) { + createPolygon(dataSource, geoJson, crsFunction, geometry.coordinates, options); + } - var stack = []; - var seen = {}; + function processMultiPolygon(dataSource, geoJson, geometry, crsFunction, options) { + var polygons = geometry.coordinates; + for (var i = 0; i < polygons.length; i++) { + createPolygon(dataSource, geoJson, crsFunction, polygons[i], options); + } + } - for (var i = 0; i < length; ++i) { - stack.push({ - parentRuntimeNode : undefined, - gltfNode : nodes[sceneNodes[i]], - id : sceneNodes[i] - }); + function processTopology(dataSource, geoJson, geometry, crsFunction, options) { + for ( var property in geometry.objects) { + if (geometry.objects.hasOwnProperty(property)) { + var feature = topojson.feature(geometry, geometry.objects[property]); + var typeHandler = geoJsonObjectTypes[feature.type]; + typeHandler(dataSource, feature, feature, crsFunction, options); + } + } + } - var skeletonIds = []; - while (stack.length > 0) { - var n = stack.pop(); - seen[n.id] = true; - var parentRuntimeNode = n.parentRuntimeNode; - var gltfNode = n.gltfNode; + /** + * A {@link DataSource} which processes both + * {@link http://www.geojson.org/|GeoJSON} and {@link https://github.com/mbostock/topojson|TopoJSON} data. + * {@link https://github.com/mapbox/simplestyle-spec|simplestyle-spec} properties will also be used if they + * are present. + * + * @alias GeoJsonDataSource + * @constructor + * + * @param {String} [name] The name of this data source. If undefined, a name will be taken from + * the name of the GeoJSON file. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=GeoJSON%20and%20TopoJSON.html|Cesium Sandcastle GeoJSON and TopoJSON Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=GeoJSON%20simplestyle.html|Cesium Sandcastle GeoJSON simplestyle Demo} + * + * @example + * var viewer = new Cesium.Viewer('cesiumContainer'); + * viewer.dataSources.add(Cesium.GeoJsonDataSource.load('../../SampleData/ne_10m_us_states.topojson', { + * stroke: Cesium.Color.HOTPINK, + * fill: Cesium.Color.PINK, + * strokeWidth: 3, + * markerSymbol: '?' + * })); + */ + function GeoJsonDataSource(name) { + this._name = name; + this._changed = new Event(); + this._error = new Event(); + this._isLoading = false; + this._loading = new Event(); + this._entityCollection = new EntityCollection(this); + this._promises = []; + this._pinBuilder = new PinBuilder(); + this._entityCluster = new EntityCluster(); + } - // Node hierarchy is a DAG so a node can have more than one parent so it may already exist - var runtimeNode = runtimeNodes[n.id]; - if (runtimeNode.parents.length === 0) { - if (defined(gltfNode.matrix)) { - runtimeNode.matrix = Matrix4.fromColumnMajorArray(gltfNode.matrix); - } else { - // TRS converted to Cesium types - var rotation = gltfNode.rotation; - runtimeNode.translation = Cartesian3.fromArray(gltfNode.translation); - runtimeNode.rotation = Quaternion.unpack(rotation); - runtimeNode.scale = Cartesian3.fromArray(gltfNode.scale); - } - } + /** + * Creates a Promise to a new instance loaded with the provided GeoJSON or TopoJSON data. + * + * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. + * @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. + * @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. + * @param {Color} [options.markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point. + * @param {Color} [options.stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines. + * @param {Number} [options.strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. + * @param {Color} [options.fill=GeoJsonDataSource.fill] The default color for polygon interiors. + * @param {Boolean} [options.clampToGround=GeoJsonDataSource.clampToGround] true if we want the geometry features (polygons or linestrings) clamped to the ground. If true, lines will use corridors so use Entity.corridor instead of Entity.polyline. + * + * @returns {Promise.<GeoJsonDataSource>} A promise that will resolve when the data is loaded. + */ + GeoJsonDataSource.load = function(data, options) { + return new GeoJsonDataSource().load(data, options); + }; - if (defined(parentRuntimeNode)) { - parentRuntimeNode.children.push(runtimeNode); - runtimeNode.parents.push(parentRuntimeNode); - } else { - rootNodes.push(runtimeNode); - } + defineProperties(GeoJsonDataSource, { + /** + * Gets or sets the default size of the map pin created for each point, in pixels. + * @memberof GeoJsonDataSource + * @type {Number} + * @default 48 + */ + markerSize : { + get : function() { + return defaultMarkerSize; + }, + set : function(value) { + defaultMarkerSize = value; + } + }, + /** + * Gets or sets the default symbol of the map pin created for each point. + * This can be any valid {@link http://mapbox.com/maki/|Maki} identifier, any single character, + * or blank if no symbol is to be used. + * @memberof GeoJsonDataSource + * @type {String} + */ + markerSymbol : { + get : function() { + return defaultMarkerSymbol; + }, + set : function(value) { + defaultMarkerSymbol = value; + } + }, + /** + * Gets or sets the default color of the map pin created for each point. + * @memberof GeoJsonDataSource + * @type {Color} + * @default Color.ROYALBLUE + */ + markerColor : { + get : function() { + return defaultMarkerColor; + }, + set : function(value) { + defaultMarkerColor = value; + } + }, + /** + * Gets or sets the default color of polylines and polygon outlines. + * @memberof GeoJsonDataSource + * @type {Color} + * @default Color.BLACK + */ + stroke : { + get : function() { + return defaultStroke; + }, + set : function(value) { + defaultStroke = value; + } + }, + /** + * Gets or sets the default width of polylines and polygon outlines. + * @memberof GeoJsonDataSource + * @type {Number} + * @default 2.0 + */ + strokeWidth : { + get : function() { + return defaultStrokeWidth; + }, + set : function(value) { + defaultStrokeWidth = value; + } + }, + /** + * Gets or sets default color for polygon interiors. + * @memberof GeoJsonDataSource + * @type {Color} + * @default Color.YELLOW + */ + fill : { + get : function() { + return defaultFill; + }, + set : function(value) { + defaultFill = value; + } + }, + /** + * Gets or sets default of whether to clamp to the ground. + * @memberof GeoJsonDataSource + * @type {Boolean} + * @default false + */ + clampToGround : { + get : function() { + return defaultClampToGround; + }, + set : function(value) { + defaultClampToGround = value; + } + }, - if (defined(gltfNode.mesh)) { - createCommand(model, gltfNode, runtimeNode, context, scene3DOnly); - } + /** + * Gets an object that maps the name of a crs to a callback function which takes a GeoJSON coordinate + * and transforms it into a WGS84 Earth-fixed Cartesian. Older versions of GeoJSON which + * supported the EPSG type can be added to this list as well, by specifying the complete EPSG name, + * for example 'EPSG:4326'. + * @memberof GeoJsonDataSource + * @type {Object} + */ + crsNames : { + get : function() { + return crsNames; + } + }, - var children = gltfNode.children; - var childrenLength = children.length; - for (var j = 0; j < childrenLength; j++) { - var childId = children[j]; - if (!seen[childId]) { - stack.push({ - parentRuntimeNode : runtimeNode, - gltfNode : nodes[childId], - id : children[j] - }); - } - } + /** + * Gets an object that maps the href property of a crs link to a callback function + * which takes the crs properties object and returns a Promise that resolves + * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian. + * Items in this object take precedence over those defined in <code>crsLinkHrefs</code>, assuming + * the link has a type specified. + * @memberof GeoJsonDataSource + * @type {Object} + */ + crsLinkHrefs : { + get : function() { + return crsLinkHrefs; + } + }, - var skin = gltfNode.skin; - if (defined(skin)) { - skeletonIds.push(skins[skin].skeleton); - } + /** + * Gets an object that maps the type property of a crs link to a callback function + * which takes the crs properties object and returns a Promise that resolves + * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian. + * Items in <code>crsLinkHrefs</code> take precedence over this object. + * @memberof GeoJsonDataSource + * @type {Object} + */ + crsLinkTypes : { + get : function() { + return crsLinkTypes; + } + } + }); - if (stack.length === 0) { - for (var k = 0; k < skeletonIds.length; k++) { - var skeleton = skeletonIds[k]; - if (!seen[skeleton]) { - stack.push({ - parentRuntimeNode : undefined, - gltfNode : nodes[skeleton], - id : skeleton - }); - } - } + defineProperties(GeoJsonDataSource.prototype, { + /** + * Gets or sets a human-readable name for this instance. + * @memberof GeoJsonDataSource.prototype + * @type {String} + */ + name : { + get : function() { + return this._name; + }, + set : function(value) { + if (this._name !== value) { + this._name = value; + this._changed.raiseEvent(this); } } - } - - model._runtime.rootNodes = rootNodes; - model._runtime.nodes = runtimeNodes; - } + }, + /** + * This DataSource only defines static data, therefore this property is always undefined. + * @memberof GeoJsonDataSource.prototype + * @type {DataSourceClock} + */ + clock : { + value : undefined, + writable : false + }, + /** + * Gets the collection of {@link Entity} instances. + * @memberof GeoJsonDataSource.prototype + * @type {EntityCollection} + */ + entities : { + get : function() { + return this._entityCollection; + } + }, + /** + * Gets a value indicating if the data source is currently loading data. + * @memberof GeoJsonDataSource.prototype + * @type {Boolean} + */ + isLoading : { + get : function() { + return this._isLoading; + } + }, + /** + * Gets an event that will be raised when the underlying data changes. + * @memberof GeoJsonDataSource.prototype + * @type {Event} + */ + changedEvent : { + get : function() { + return this._changed; + } + }, + /** + * Gets an event that will be raised if an error is encountered during processing. + * @memberof GeoJsonDataSource.prototype + * @type {Event} + */ + errorEvent : { + get : function() { + return this._error; + } + }, + /** + * Gets an event that will be raised when the data source either starts or stops loading. + * @memberof GeoJsonDataSource.prototype + * @type {Event} + */ + loadingEvent : { + get : function() { + return this._loading; + } + }, + /** + * Gets whether or not this data source should be displayed. + * @memberof GeoJsonDataSource.prototype + * @type {Boolean} + */ + show : { + get : function() { + return this._entityCollection.show; + }, + set : function(value) { + this._entityCollection.show = value; + } + }, - function getGeometryByteLength(buffers) { - var memory = 0; - for (var id in buffers) { - if (buffers.hasOwnProperty(id)) { - memory += buffers[id].sizeInBytes; + /** + * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. + * + * @memberof GeoJsonDataSource.prototype + * @type {EntityCluster} + */ + clustering : { + get : function() { + return this._entityCluster; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value must be defined.'); + } + this._entityCluster = value; } } - return memory; - } + }); - function getTexturesByteLength(textures) { - var memory = 0; - for (var id in textures) { - if (textures.hasOwnProperty(id)) { - memory += textures[id].sizeInBytes; - } + /** + * Asynchronously loads the provided GeoJSON or TopoJSON data, replacing any existing data. + * + * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. + * @param {GeoJsonDataSource~describe} [options.describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string), + * which converts the properties into an html description. + * @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. + * @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. + * @param {Color} [options.markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point. + * @param {Color} [options.stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines. + * @param {Number} [options.strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. + * @param {Color} [options.fill=GeoJsonDataSource.fill] The default color for polygon interiors. + * @param {Boolean} [options.clampToGround=GeoJsonDataSource.clampToGround] true if we want the features clamped to the ground. + * + * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. + */ + GeoJsonDataSource.prototype.load = function(data, options) { + if (!defined(data)) { + throw new DeveloperError('data is required.'); } - return memory; - } - - function createResources(model, frameState) { - var context = frameState.context; - var scene3DOnly = frameState.scene3DOnly; - - checkSupportedGlExtensions(model, context); - if (model._loadRendererResourcesFromCache) { - var resources = model._rendererResources; - var cachedResources = model._cachedRendererResources; - - resources.buffers = cachedResources.buffers; - resources.vertexArrays = cachedResources.vertexArrays; - resources.programs = cachedResources.programs; - resources.pickPrograms = cachedResources.pickPrograms; - resources.silhouettePrograms = cachedResources.silhouettePrograms; - resources.textures = cachedResources.textures; - resources.samplers = cachedResources.samplers; - resources.renderStates = cachedResources.renderStates; - - // Vertex arrays are unique to this model, create instead of using the cache. - if (defined(model._precreatedAttributes)) { - createVertexArrays(model, context); - } + + DataSource.setLoading(this, true); - model._cachedGeometryByteLength += getGeometryByteLength(cachedResources.buffers); - model._cachedTexturesByteLength += getTexturesByteLength(cachedResources.textures); - } else { - createBuffers(model, frameState); // using glTF bufferViews - createPrograms(model, frameState); - createSamplers(model, context); - loadTexturesFromBufferViews(model); - createTextures(model, frameState); - } + var promise = data; + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var sourceUri = options.sourceUri; + if (typeof data === 'string' || (data instanceof Resource)) { + data = Resource.createIfNeeded(data); - createSkins(model); - createRuntimeAnimations(model); + promise = data.fetchJson(); - if (!model._loadRendererResourcesFromCache) { - createVertexArrays(model, context); // using glTF meshes - createRenderStates(model, context); // using glTF materials/techniques/states - // Long-term, we might not cache render states if they could change - // due to an animation, e.g., a uniform going from opaque to transparent. - // Could use copy-on-write if it is worth it. Probably overkill. + sourceUri = defaultValue(sourceUri, data.getUrlComponent()); } - createUniformMaps(model, context); // using glTF materials/techniques - createRuntimeNodes(model, context, scene3DOnly); // using glTF scene - } + options = { + describe: defaultValue(options.describe, defaultDescribeProperty), + markerSize : defaultValue(options.markerSize, defaultMarkerSize), + markerSymbol : defaultValue(options.markerSymbol, defaultMarkerSymbol), + markerColor : defaultValue(options.markerColor, defaultMarkerColor), + strokeWidthProperty : new ConstantProperty(defaultValue(options.strokeWidth, defaultStrokeWidth)), + strokeMaterialProperty : new ColorMaterialProperty(defaultValue(options.stroke, defaultStroke)), + fillMaterialProperty : new ColorMaterialProperty(defaultValue(options.fill, defaultFill)), + clampToGround : defaultValue(options.clampToGround, defaultClampToGround) + }; - /////////////////////////////////////////////////////////////////////////// + var that = this; + return when(promise, function(geoJson) { + return load(that, geoJson, options, sourceUri); + }).otherwise(function(error) { + DataSource.setLoading(that, false); + that._error.raiseEvent(that, error); + console.log(error); + return when.reject(error); + }); + }; - function getNodeMatrix(node, result) { - var publicNode = node.publicNode; - var publicMatrix = publicNode.matrix; + function load(that, geoJson, options, sourceUri) { + var name; + if (defined(sourceUri)) { + name = getFilenameFromUri(sourceUri); + } - if (publicNode.useMatrix && defined(publicMatrix)) { - // Public matrix overrides orginial glTF matrix and glTF animations - Matrix4.clone(publicMatrix, result); - } else if (defined(node.matrix)) { - Matrix4.clone(node.matrix, result); - } else { - Matrix4.fromTranslationQuaternionRotationScale(node.translation, node.rotation, node.scale, result); - // Keep matrix returned by the node in-sync if the node is targeted by an animation. Only TRS nodes can be targeted. - publicNode.setMatrix(result); + if (defined(name) && that._name !== name) { + that._name = name; + that._changed.raiseEvent(that); } - } - var scratchNodeStack = []; - var scratchComputedTranslation = new Cartesian4(); - var scratchComputedMatrixIn2D = new Matrix4(); + var typeHandler = geoJsonObjectTypes[geoJson.type]; + if (!defined(typeHandler)) { + throw new RuntimeError('Unsupported GeoJSON object type: ' + geoJson.type); + } - function updateNodeHierarchyModelMatrix(model, modelTransformChanged, justLoaded, projection) { - var maxDirtyNumber = model._maxDirtyNumber; - var allowPicking = model.allowPicking; + //Check for a Coordinate Reference System. + var crs = geoJson.crs; + var crsFunction = crs !== null ? defaultCrsFunction : null; - var rootNodes = model._runtime.rootNodes; - var length = rootNodes.length; + if (defined(crs)) { + if (!defined(crs.properties)) { + throw new RuntimeError('crs.properties is undefined.'); + } - var nodeStack = scratchNodeStack; - var computedModelMatrix = model._computedModelMatrix; + var properties = crs.properties; + if (crs.type === 'name') { + crsFunction = crsNames[properties.name]; + if (!defined(crsFunction)) { + throw new RuntimeError('Unknown crs name: ' + properties.name); + } + } else if (crs.type === 'link') { + var handler = crsLinkHrefs[properties.href]; + if (!defined(handler)) { + handler = crsLinkTypes[properties.type]; + } - if ((model._mode !== SceneMode.SCENE3D) && !model._ignoreCommands) { - var translation = Matrix4.getColumn(computedModelMatrix, 3, scratchComputedTranslation); - if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) { - computedModelMatrix = Transforms.basisTo2D(projection, computedModelMatrix, scratchComputedMatrixIn2D); - model._rtcCenter = model._rtcCenter3D; - } else { - var center = model.boundingSphere.center; - var to2D = Transforms.wgs84To2DModelMatrix(projection, center, scratchComputedMatrixIn2D); - computedModelMatrix = Matrix4.multiply(to2D, computedModelMatrix, scratchComputedMatrixIn2D); + if (!defined(handler)) { + throw new RuntimeError('Unable to resolve crs link: ' + JSON.stringify(properties)); + } - if (defined(model._rtcCenter)) { - Matrix4.setTranslation(computedModelMatrix, Cartesian4.UNIT_W, computedModelMatrix); - model._rtcCenter = model._rtcCenter2D; + crsFunction = handler(properties); + } else if (crs.type === 'EPSG') { + crsFunction = crsNames['EPSG:' + properties.code]; + if (!defined(crsFunction)) { + throw new RuntimeError('Unknown crs EPSG code: ' + properties.code); } + } else { + throw new RuntimeError('Unknown crs type: ' + crs.type); } } - for (var i = 0; i < length; ++i) { - var n = rootNodes[i]; - - getNodeMatrix(n, n.transformToRoot); - nodeStack.push(n); - - while (nodeStack.length > 0) { - n = nodeStack.pop(); - var transformToRoot = n.transformToRoot; - var commands = n.commands; - - if ((n.dirtyNumber === maxDirtyNumber) || modelTransformChanged || justLoaded) { - var nodeMatrix = Matrix4.multiplyTransformation(computedModelMatrix, transformToRoot, n.computedMatrix); - var commandsLength = commands.length; - if (commandsLength > 0) { - // Node has meshes, which has primitives. Update their commands. - for (var j = 0; j < commandsLength; ++j) { - var primitiveCommand = commands[j]; - var command = primitiveCommand.command; - Matrix4.clone(nodeMatrix, command.modelMatrix); - - // PERFORMANCE_IDEA: Can use transformWithoutScale if no node up to the root has scale (including animation) - BoundingSphere.transform(primitiveCommand.boundingSphere, command.modelMatrix, command.boundingVolume); - - if (defined(model._rtcCenter)) { - Cartesian3.add(model._rtcCenter, command.boundingVolume.center, command.boundingVolume.center); - } - - if (allowPicking) { - var pickCommand = primitiveCommand.pickCommand; - Matrix4.clone(command.modelMatrix, pickCommand.modelMatrix); - BoundingSphere.clone(command.boundingVolume, pickCommand.boundingVolume); - } - - // If the model crosses the IDL in 2D, it will be drawn in one viewport, but part of it - // will be clipped by the viewport. We create a second command that translates the model - // model matrix to the opposite side of the map so the part that was clipped in one viewport - // is drawn in the other. - command = primitiveCommand.command2D; - if (defined(command) && model._mode === SceneMode.SCENE2D) { - Matrix4.clone(nodeMatrix, command.modelMatrix); - command.modelMatrix[13] -= CesiumMath.sign(command.modelMatrix[13]) * 2.0 * CesiumMath.PI * projection.ellipsoid.maximumRadius; - BoundingSphere.transform(primitiveCommand.boundingSphere, command.modelMatrix, command.boundingVolume); - - if (allowPicking) { - var pickCommand2D = primitiveCommand.pickCommand2D; - Matrix4.clone(command.modelMatrix, pickCommand2D.modelMatrix); - BoundingSphere.clone(command.boundingVolume, pickCommand2D.boundingVolume); - } - } - } - } - } - - var children = n.children; - var childrenLength = children.length; - for (var k = 0; k < childrenLength; ++k) { - var child = children[k]; - - // A node's transform needs to be updated if - // - It was targeted for animation this frame, or - // - Any of its ancestors were targeted for animation this frame - - // PERFORMANCE_IDEA: if a child has multiple parents and only one of the parents - // is dirty, all the subtrees for each child instance will be dirty; we probably - // won't see this in the wild often. - child.dirtyNumber = Math.max(child.dirtyNumber, n.dirtyNumber); - - if ((child.dirtyNumber === maxDirtyNumber) || justLoaded) { - // Don't check for modelTransformChanged since if only the model's model matrix changed, - // we do not need to rebuild the local transform-to-root, only the final - // [model's-model-matrix][transform-to-root] above. - getNodeMatrix(child, child.transformToRoot); - Matrix4.multiplyTransformation(transformToRoot, child.transformToRoot, child.transformToRoot); - } + return when(crsFunction, function(crsFunction) { + that._entityCollection.removeAll(); - nodeStack.push(child); - } + // null is a valid value for the crs, but means the entire load process becomes a no-op + // because we can't assume anything about the coordinates. + if (crsFunction !== null) { + typeHandler(that, geoJson, geoJson, crsFunction, options); } - } - ++model._maxDirtyNumber; + return when.all(that._promises, function() { + that._promises.length = 0; + DataSource.setLoading(that, false); + return that; + }); + }); } - var scratchObjectSpace = new Matrix4(); + /** + * This callback is displayed as part of the GeoJsonDataSource class. + * @callback GeoJsonDataSource~describe + * @param {Object} properties The properties of the feature. + * @param {String} nameProperty The property key that Cesium estimates to have the name of the feature. + */ - function applySkins(model) { - var skinnedNodes = model._runtime.skinnedNodes; - var length = skinnedNodes.length; + return GeoJsonDataSource; +}); - for (var i = 0; i < length; ++i) { - var node = skinnedNodes[i]; +define('DataSources/GeometryUpdater',[ + '../Core/defineProperties', + '../Core/DeveloperError' + ], function( + defineProperties, + DeveloperError) { + 'use strict'; - scratchObjectSpace = Matrix4.inverseTransformation(node.transformToRoot, scratchObjectSpace); + /** + * Defines the interface for a geometry updater. A GeometryUpdater maps + * geometry defined as part of a {@link Entity} into {@link Geometry} + * instances. These instances are then visualized by {@link GeometryVisualizer}. + * + * This type defines an interface and cannot be instantiated directly. + * + * @alias GeometryUpdater + * @constructor + * + * @param {Entity} entity The entity containing the geometry to be visualized. + * @param {Scene} scene The scene where visualization is taking place. + * + * @see EllipseGeometryUpdater + * @see EllipsoidGeometryUpdater + * @see PolygonGeometryUpdater + * @see PolylineGeometryUpdater + * @see RectangleGeometryUpdater + * @see WallGeometryUpdater + */ + function GeometryUpdater(entity, scene) { + DeveloperError.throwInstantiationError(); + } - var computedJointMatrices = node.computedJointMatrices; - var joints = node.joints; - var bindShapeMatrix = node.bindShapeMatrix; - var inverseBindMatrices = node.inverseBindMatrices; - var inverseBindMatricesLength = inverseBindMatrices.length; + defineProperties(GeometryUpdater, { + /** + * Gets the type of Appearance to use for simple color-based geometry. + * @memberof GeometryUpdater + * @type {Appearance} + */ + perInstanceColorAppearanceType : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the type of Appearance to use for material-based geometry. + * @memberof GeometryUpdater + * @type {Appearance} + */ + materialAppearanceType : { + get : DeveloperError.throwInstantiationError + } + }); - for (var m = 0; m < inverseBindMatricesLength; ++m) { - // [joint-matrix] = [node-to-root^-1][joint-to-root][inverse-bind][bind-shape] - if (!defined(computedJointMatrices[m])) { - computedJointMatrices[m] = new Matrix4(); - } - computedJointMatrices[m] = Matrix4.multiplyTransformation(scratchObjectSpace, joints[m].transformToRoot, computedJointMatrices[m]); - computedJointMatrices[m] = Matrix4.multiplyTransformation(computedJointMatrices[m], inverseBindMatrices[m], computedJointMatrices[m]); - if (defined(bindShapeMatrix)) { - // Optimization for when bind shape matrix is the identity. - computedJointMatrices[m] = Matrix4.multiplyTransformation(computedJointMatrices[m], bindShapeMatrix, computedJointMatrices[m]); - } - } + defineProperties(GeometryUpdater.prototype, { + /** + * Gets the entity associated with this geometry. + * @memberof GeometryUpdater.prototype + * + * @type {Entity} + * @readonly + */ + entity : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets a value indicating if the geometry has a fill component. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + fillEnabled : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets a value indicating if fill visibility varies with simulation time. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantFill : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the material property used to fill the geometry. + * @memberof GeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly + */ + fillMaterialProperty : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets a value indicating if the geometry has an outline component. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + outlineEnabled : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets a value indicating if outline visibility varies with simulation time. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + hasConstantOutline : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the {@link Color} property for the geometry outline. + * @memberof GeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + outlineColorProperty : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets the constant with of the geometry outline, in pixels. + * This value is only valid if isDynamic is false. + * @memberof GeometryUpdater.prototype + * + * @type {Number} + * @readonly + */ + outlineWidth : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets a value indicating if the geometry is time-varying. + * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} + * returned by GeometryUpdater#createDynamicUpdater. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isDynamic : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets a value indicating if the geometry is closed. + * This property is only valid for static geometry. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + isClosed : { + get : DeveloperError.throwInstantiationError + }, + /** + * Gets an event that is raised whenever the public properties + * of this updater change. + * @memberof GeometryUpdater.prototype + * + * @type {Boolean} + * @readonly + */ + geometryChanged : { + get : DeveloperError.throwInstantiationError } - } + }); - function updatePerNodeShow(model) { - // Totally not worth it, but we could optimize this: - // http://blogs.agi.com/insight3d/index.php/2008/02/13/deletion-in-bounding-volume-hierarchies/ + /** + * Checks if the geometry is outlined at the provided time. + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + */ + GeometryUpdater.prototype.isOutlineVisible = DeveloperError.throwInstantiationError; - var rootNodes = model._runtime.rootNodes; - var length = rootNodes.length; + /** + * Checks if the geometry is filled at the provided time. + * @function + * + * @param {JulianDate} time The time for which to retrieve visibility. + * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + */ + GeometryUpdater.prototype.isFilled = DeveloperError.throwInstantiationError; - var nodeStack = scratchNodeStack; + /** + * Creates the geometry instance which represents the fill of the geometry. + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent a filled geometry. + */ + GeometryUpdater.prototype.createFillGeometryInstance = DeveloperError.throwInstantiationError; - for (var i = 0; i < length; ++i) { - var n = rootNodes[i]; - n.computedShow = n.publicNode.show; - nodeStack.push(n); + /** + * Creates the geometry instance which represents the outline of the geometry. + * @function + * + * @param {JulianDate} time The time to use when retrieving initial attribute values. + * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. + * + * @exception {DeveloperError} This instance does not represent an outlined geometry. + */ + GeometryUpdater.prototype.createOutlineGeometryInstance = DeveloperError.throwInstantiationError; - while (nodeStack.length > 0) { - n = nodeStack.pop(); - var show = n.computedShow; + /** + * Returns true if this object was destroyed; otherwise, false. + * @function + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + */ + GeometryUpdater.prototype.isDestroyed = DeveloperError.throwInstantiationError; - var nodeCommands = n.commands; - var nodeCommandsLength = nodeCommands.length; - for (var j = 0; j < nodeCommandsLength; ++j) { - nodeCommands[j].show = show; - } - // if commandsLength is zero, the node has a light or camera + /** + * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * @function + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + GeometryUpdater.prototype.destroy = DeveloperError.throwInstantiationError; - var children = n.children; - var childrenLength = children.length; - for (var k = 0; k < childrenLength; ++k) { - var child = children[k]; - // Parent needs to be shown for child to be shown. - child.computedShow = show && child.publicNode.show; - nodeStack.push(child); - } - } - } - } + /** + * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * @function + * + * @param {PrimitiveCollection} primitives The primitive collection to use. + * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * + * @exception {DeveloperError} This instance does not represent dynamic geometry. + */ + GeometryUpdater.prototype.createDynamicUpdater = DeveloperError.throwInstantiationError; - function updatePickIds(model, context) { - var id = model.id; - if (model._id !== id) { - model._id = id; + return GeometryUpdater; +}); - var pickIds = model._pickIds; - var length = pickIds.length; - for (var i = 0; i < length; ++i) { - pickIds[i].object.id = id; - } - } +define('DataSources/KmlCamera',[], function() { + 'use strict'; + /** + * Representation of <Camera> from KML + * @alias KmlCamera + * @constructor + * + * @param {Cartesian3} position camera position + * @param {HeadingPitchRoll} headingPitchRoll camera orientation + */ + function KmlCamera(position, headingPitchRoll) { + this.position = position; + this.headingPitchRoll = headingPitchRoll; } - function updateWireframe(model) { - if (model._debugWireframe !== model.debugWireframe) { - model._debugWireframe = model.debugWireframe; + return KmlCamera; +}); - // This assumes the original primitive was TRIANGLES and that the triangles - // are connected for the wireframe to look perfect. - var primitiveType = model.debugWireframe ? PrimitiveType.LINES : PrimitiveType.TRIANGLES; - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define('ThirdParty/Autolinker',[], function () { + return (root['Autolinker'] = factory()); + }); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + root['Autolinker'] = factory(); + } +}(this, function () { - for (var i = 0; i < length; ++i) { - nodeCommands[i].command.primitiveType = primitiveType; - } - } - } +/*! + * Autolinker.js + * 0.17.1 + * + * Copyright(c) 2015 Gregory Jacobs <greg@greg-jacobs.com> + * MIT Licensed. http://www.opensource.org/licenses/mit-license.php + * + * https://github.com/gregjacobs/Autolinker.js + */ +/** + * @class Autolinker + * @extends Object + * + * Utility class used to process a given string of text, and wrap the matches in + * the appropriate anchor (<a>) tags to turn them into links. + * + * Any of the configuration options may be provided in an Object (map) provided + * to the Autolinker constructor, which will configure how the {@link #link link()} + * method will process the links. + * + * For example: + * + * var autolinker = new Autolinker( { + * newWindow : false, + * truncate : 30 + * } ); + * + * var html = autolinker.link( "Joe went to www.yahoo.com" ); + * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>' + * + * + * The {@link #static-link static link()} method may also be used to inline options into a single call, which may + * be more convenient for one-off uses. For example: + * + * var html = Autolinker.link( "Joe went to www.yahoo.com", { + * newWindow : false, + * truncate : 30 + * } ); + * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>' + * + * + * ## Custom Replacements of Links + * + * If the configuration options do not provide enough flexibility, a {@link #replaceFn} + * may be provided to fully customize the output of Autolinker. This function is + * called once for each URL/Email/Phone#/Twitter Handle/Hashtag match that is + * encountered. + * + * For example: + * + * var input = "..."; // string with URLs, Email Addresses, Phone #s, Twitter Handles, and Hashtags + * + * var linkedText = Autolinker.link( input, { + * replaceFn : function( autolinker, match ) { + * console.log( "href = ", match.getAnchorHref() ); + * console.log( "text = ", match.getAnchorText() ); + * + * switch( match.getType() ) { + * case 'url' : + * console.log( "url: ", match.getUrl() ); + * + * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes + * tag.setAttr( 'rel', 'nofollow' ); + * tag.addClass( 'external-link' ); + * + * return tag; + * + * } else { + * return true; // let Autolinker perform its normal anchor tag replacement + * } + * + * case 'email' : + * var email = match.getEmail(); + * console.log( "email: ", email ); + * + * if( email === "my@own.address" ) { + * return false; // don't auto-link this particular email address; leave as-is + * } else { + * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`) + * } + * + * case 'phone' : + * var phoneNumber = match.getPhoneNumber(); + * console.log( phoneNumber ); + * + * return '<a href="http://newplace.to.link.phone.numbers.to/">' + phoneNumber + '</a>'; + * + * case 'twitter' : + * var twitterHandle = match.getTwitterHandle(); + * console.log( twitterHandle ); + * + * return '<a href="http://newplace.to.link.twitter.handles.to/">' + twitterHandle + '</a>'; + * + * case 'hashtag' : + * var hashtag = match.getHashtag(); + * console.log( hashtag ); + * + * return '<a href="http://newplace.to.link.hashtag.handles.to/">' + hashtag + '</a>'; + * } + * } + * } ); + * + * + * The function may return the following values: + * + * - `true` (Boolean): Allow Autolinker to replace the match as it normally would. + * - `false` (Boolean): Do not replace the current match at all - leave as-is. + * - Any String: If a string is returned from the function, the string will be used directly as the replacement HTML for + * the match. + * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify an HTML tag before writing out its HTML text. + * + * @constructor + * @param {Object} [config] The configuration options for the Autolinker instance, specified in an Object (map). + */ +var Autolinker = function( cfg ) { + Autolinker.Util.assign( this, cfg ); // assign the properties of `cfg` onto the Autolinker instance. Prototype properties will be used for missing configs. - function updateShowBoundingVolume(model) { - if (model.debugShowBoundingVolume !== model._debugShowBoundingVolume) { - model._debugShowBoundingVolume = model.debugShowBoundingVolume; + // Validate the value of the `hashtag` cfg. + var hashtag = this.hashtag; + if( hashtag !== false && hashtag !== 'twitter' && hashtag !== 'facebook' ) { + throw new Error( "invalid `hashtag` cfg - see docs" ); + } +}; - var debugShowBoundingVolume = model.debugShowBoundingVolume; - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; +Autolinker.prototype = { + constructor : Autolinker, // fix constructor property - for (var i = 0; i < length; ++i) { - nodeCommands[i].command.debugShowBoundingVolume = debugShowBoundingVolume; - } - } - } + /** + * @cfg {Boolean} urls + * + * `true` if miscellaneous URLs should be automatically linked, `false` if they should not be. + */ + urls : true, - function updateShadows(model) { - if (model.shadows !== model._shadows) { - model._shadows = model.shadows; + /** + * @cfg {Boolean} email + * + * `true` if email addresses should be automatically linked, `false` if they should not be. + */ + email : true, - var castShadows = ShadowMode.castShadows(model.shadows); - var receiveShadows = ShadowMode.receiveShadows(model.shadows); - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; + /** + * @cfg {Boolean} twitter + * + * `true` if Twitter handles ("@example") should be automatically linked, `false` if they should not be. + */ + twitter : true, - for (var i = 0; i < length; i++) { - var nodeCommand = nodeCommands[i]; - nodeCommand.command.castShadows = castShadows; - nodeCommand.command.receiveShadows = receiveShadows; - } - } - } + /** + * @cfg {Boolean} phone + * + * `true` if Phone numbers ("(555)555-5555") should be automatically linked, `false` if they should not be. + */ + phone: true, - function getTranslucentRenderState(renderState) { - var rs = clone(renderState, true); - rs.cull.enabled = false; - rs.depthTest.enabled = true; - rs.depthMask = false; - rs.blending = BlendingState.ALPHA_BLEND; + /** + * @cfg {Boolean/String} hashtag + * + * A string for the service name to have hashtags (ex: "#myHashtag") + * auto-linked to. The currently-supported values are: + * + * - 'twitter' + * - 'facebook' + * + * Pass `false` to skip auto-linking of hashtags. + */ + hashtag : false, - return RenderState.fromCache(rs); - } + /** + * @cfg {Boolean} newWindow + * + * `true` if the links should open in a new window, `false` otherwise. + */ + newWindow : true, - function deriveTranslucentCommand(command) { - var translucentCommand = DrawCommand.shallowClone(command); - translucentCommand.pass = Pass.TRANSLUCENT; - translucentCommand.renderState = getTranslucentRenderState(command.renderState); - return translucentCommand; - } + /** + * @cfg {Boolean} stripPrefix + * + * `true` if 'http://' or 'https://' and/or the 'www.' should be stripped + * from the beginning of URL links' text, `false` otherwise. + */ + stripPrefix : true, - function updateColor(model, frameState) { - // Generate translucent commands when the blend color has an alpha in the range (0.0, 1.0) exclusive - var scene3DOnly = frameState.scene3DOnly; - var alpha = model.color.alpha; - if ((alpha > 0.0) && (alpha < 1.0)) { - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; - if (!defined(nodeCommands[0].translucentCommand)) { - for (var i = 0; i < length; ++i) { - var nodeCommand = nodeCommands[i]; - var command = nodeCommand.command; - nodeCommand.translucentCommand = deriveTranslucentCommand(command); - if (!scene3DOnly) { - var command2D = nodeCommand.command2D; - nodeCommand.translucentCommand2D = deriveTranslucentCommand(command2D); - } - } - } - } - } + /** + * @cfg {Number} truncate + * + * A number for how many characters long matched text should be truncated to inside the text of + * a link. If the matched text is over this number of characters, it will be truncated to this length by + * adding a two period ellipsis ('..') to the end of the string. + * + * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file' truncated to 25 characters might look + * something like this: 'yahoo.com/some/long/pat..' + */ + truncate : undefined, - function getProgramId(model, program) { - var programs = model._rendererResources.programs; - for (var id in programs) { - if (programs.hasOwnProperty(id)) { - if (programs[id] === program) { - return id; - } - } - } - } + /** + * @cfg {String} className + * + * A CSS class name to add to the generated links. This class will be added to all links, as well as this class + * plus match suffixes for styling url/email/phone/twitter/hashtag links differently. + * + * For example, if this config is provided as "myLink", then: + * + * - URL links will have the CSS classes: "myLink myLink-url" + * - Email links will have the CSS classes: "myLink myLink-email", and + * - Twitter links will have the CSS classes: "myLink myLink-twitter" + * - Phone links will have the CSS classes: "myLink myLink-phone" + * - Hashtag links will have the CSS classes: "myLink myLink-hashtag" + */ + className : "", - function createSilhouetteProgram(model, program, frameState) { - var vs = program.vertexShaderSource.sources[0]; - var attributeLocations = program._attributeLocations; - var normalAttributeName = model._normalAttributeName; + /** + * @cfg {Function} replaceFn + * + * A function to individually process each match found in the input string. + * + * See the class's description for usage. + * + * This function is called with the following parameters: + * + * @cfg {Autolinker} replaceFn.autolinker The Autolinker instance, which may be used to retrieve child objects from (such + * as the instance's {@link #getTagBuilder tag builder}). + * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which can be used to retrieve information about the + * match that the `replaceFn` is currently processing. See {@link Autolinker.match.Match} subclasses for details. + */ - // Modified from http://forum.unity3d.com/threads/toon-outline-but-with-diffuse-surface.24668/ - vs = ShaderSource.replaceMain(vs, 'gltf_silhouette_main'); - vs += - 'uniform float gltf_silhouetteSize; \n' + - 'void main() \n' + - '{ \n' + - ' gltf_silhouette_main(); \n' + - ' vec3 n = normalize(czm_normal3D * ' + normalAttributeName + '); \n' + - ' n.x *= czm_projection[0][0]; \n' + - ' n.y *= czm_projection[1][1]; \n' + - ' vec4 clip = gl_Position; \n' + - ' clip.xy += n.xy * clip.w * gltf_silhouetteSize / czm_viewport.z; \n' + - ' gl_Position = clip; \n' + - '}'; - var fs = - 'uniform vec4 gltf_silhouetteColor; \n' + - 'void main() \n' + - '{ \n' + - ' gl_FragColor = gltf_silhouetteColor; \n' + - '}'; + /** + * @private + * @property {Autolinker.htmlParser.HtmlParser} htmlParser + * + * The HtmlParser instance used to skip over HTML tags, while finding text nodes to process. This is lazily instantiated + * in the {@link #getHtmlParser} method. + */ + htmlParser : undefined, - return ShaderProgram.fromCache({ - context : frameState.context, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } + /** + * @private + * @property {Autolinker.matchParser.MatchParser} matchParser + * + * The MatchParser instance used to find matches in the text nodes of an input string passed to + * {@link #link}. This is lazily instantiated in the {@link #getMatchParser} method. + */ + matchParser : undefined, - function hasSilhouette(model, frameState) { - return silhouetteSupported(frameState.context) && (model.silhouetteSize > 0.0) && (model.silhouetteColor.alpha > 0.0) && defined(model._normalAttributeName); - } + /** + * @private + * @property {Autolinker.AnchorTagBuilder} tagBuilder + * + * The AnchorTagBuilder instance used to build match replacement anchor tags. Note: this is lazily instantiated + * in the {@link #getTagBuilder} method. + */ + tagBuilder : undefined, - function hasTranslucentCommands(model) { - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; - for (var i = 0; i < length; ++i) { - var nodeCommand = nodeCommands[i]; - var command = nodeCommand.command; - if (command.pass === Pass.TRANSLUCENT) { - return true; - } - } - return false; - } + /** + * Automatically links URLs, Email addresses, Phone numbers, Twitter + * handles, and Hashtags found in the given chunk of HTML. Does not link + * URLs found within HTML tags. + * + * For instance, if given the text: `You should go to http://www.yahoo.com`, + * then the result will be `You should go to + * <a href="http://www.yahoo.com">http://www.yahoo.com</a>` + * + * This method finds the text around any HTML elements in the input + * `textOrHtml`, which will be the text that is processed. Any original HTML + * elements will be left as-is, as well as the text that is already wrapped + * in anchor (<a>) tags. + * + * @param {String} textOrHtml The HTML or text to autolink matches within + * (depending on if the {@link #urls}, {@link #email}, {@link #phone}, + * {@link #twitter}, and {@link #hashtag} options are enabled). + * @return {String} The HTML, with matches automatically linked. + */ + link : function( textOrHtml ) { + var htmlParser = this.getHtmlParser(), + htmlNodes = htmlParser.parse( textOrHtml ), + anchorTagStackCount = 0, // used to only process text around anchor tags, and any inner text/html they may have + resultHtml = []; + + for( var i = 0, len = htmlNodes.length; i < len; i++ ) { + var node = htmlNodes[ i ], + nodeType = node.getType(), + nodeText = node.getText(); + + if( nodeType === 'element' ) { + // Process HTML nodes in the input `textOrHtml` + if( node.getTagName() === 'a' ) { + if( !node.isClosing() ) { // it's the start <a> tag + anchorTagStackCount++; + } else { // it's the end </a> tag + anchorTagStackCount = Math.max( anchorTagStackCount - 1, 0 ); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0 + } + } + resultHtml.push( nodeText ); // now add the text of the tag itself verbatim - function isTranslucent(model) { - return (model.color.alpha > 0.0) && (model.color.alpha < 1.0); - } + } else if( nodeType === 'entity' || nodeType === 'comment' ) { + resultHtml.push( nodeText ); // append HTML entity nodes (such as ' ') or HTML comments (such as '<!-- Comment -->') verbatim - function isInvisible(model) { - return (model.color.alpha === 0.0); - } + } else { + // Process text nodes in the input `textOrHtml` + if( anchorTagStackCount === 0 ) { + // If we're not within an <a> tag, process the text node to linkify + var linkifiedStr = this.linkifyStr( nodeText ); + resultHtml.push( linkifiedStr ); - function alphaDirty(currAlpha, prevAlpha) { - // Returns whether the alpha state has changed between invisible, translucent, or opaque - return (Math.floor(currAlpha) !== Math.floor(prevAlpha)) || (Math.ceil(currAlpha) !== Math.ceil(prevAlpha)); - } + } else { + // `text` is within an <a> tag, simply append the text - we do not want to autolink anything + // already within an <a>...</a> tag + resultHtml.push( nodeText ); + } + } + } - var silhouettesLength = 0; + return resultHtml.join( "" ); + }, - function createSilhouetteCommands(model, frameState) { - // Wrap around after exceeding the 8-bit stencil limit. - // The reference is unique to each model until this point. - var stencilReference = (++silhouettesLength) % 255; + /** + * Process the text that lies in between HTML tags, performing the anchor + * tag replacements for the matches, and returns the string with the + * replacements made. + * + * This method does the actual wrapping of matches with anchor tags. + * + * @private + * @param {String} str The string of text to auto-link. + * @return {String} The text with anchor tags auto-filled. + */ + linkifyStr : function( str ) { + return this.getMatchParser().replace( str, this.createMatchReturnVal, this ); + }, - // If the model is translucent the silhouette needs to be in the translucent pass. - // Otherwise the silhouette would be rendered before the model. - var silhouetteTranslucent = hasTranslucentCommands(model) || isTranslucent(model) || (model.silhouetteColor.alpha < 1.0); - var silhouettePrograms = model._rendererResources.silhouettePrograms; - var scene3DOnly = frameState.scene3DOnly; - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; - for (var i = 0; i < length; ++i) { - var nodeCommand = nodeCommands[i]; - var command = nodeCommand.command; - // Create model command - var modelCommand = isTranslucent(model) ? nodeCommand.translucentCommand : command; - var silhouetteModelCommand = DrawCommand.shallowClone(modelCommand); - var renderState = clone(modelCommand.renderState); + /** + * Creates the return string value for a given match in the input string, + * for the {@link #linkifyStr} method. + * + * This method handles the {@link #replaceFn}, if one was provided. + * + * @private + * @param {Autolinker.match.Match} match The Match object that represents the match. + * @return {String} The string that the `match` should be replaced with. This is usually the anchor tag string, but + * may be the `matchStr` itself if the match is not to be replaced. + */ + createMatchReturnVal : function( match ) { + // Handle a custom `replaceFn` being provided + var replaceFnResult; + if( this.replaceFn ) { + replaceFnResult = this.replaceFn.call( this, this, match ); // Autolinker instance is the context, and the first arg + } - // Write the reference value into the stencil buffer. - renderState.stencilTest = { - enabled : true, - frontFunction : WebGLConstants.ALWAYS, - backFunction : WebGLConstants.ALWAYS, - reference : stencilReference, - mask : ~0, - frontOperation : { - fail : WebGLConstants.KEEP, - zFail : WebGLConstants.KEEP, - zPass : WebGLConstants.REPLACE - }, - backOperation : { - fail : WebGLConstants.KEEP, - zFail : WebGLConstants.KEEP, - zPass : WebGLConstants.REPLACE - } - }; + if( typeof replaceFnResult === 'string' ) { + return replaceFnResult; // `replaceFn` returned a string, use that - if (isInvisible(model)) { - // When the model is invisible disable color and depth writes but still write into the stencil buffer - renderState.colorMask = { - red : false, - green : false, - blue : false, - alpha : false - }; - renderState.depthMask = false; - } - renderState = RenderState.fromCache(renderState); - silhouetteModelCommand.renderState = renderState; - nodeCommand.silhouetteModelCommand = silhouetteModelCommand; + } else if( replaceFnResult === false ) { + return match.getMatchedText(); // no replacement for the match - // Create color command - var silhouetteColorCommand = DrawCommand.shallowClone(command); - renderState = clone(command.renderState, true); - renderState.depthTest.enabled = true; - renderState.cull.enabled = false; - if (silhouetteTranslucent) { - silhouetteColorCommand.pass = Pass.TRANSLUCENT; - renderState.depthMask = false; - renderState.blending = BlendingState.ALPHA_BLEND; - } + } else if( replaceFnResult instanceof Autolinker.HtmlTag ) { + return replaceFnResult.toAnchorString(); - // Only render silhouette if the value in the stencil buffer equals the reference - renderState.stencilTest = { - enabled : true, - frontFunction : WebGLConstants.NOTEQUAL, - backFunction : WebGLConstants.NOTEQUAL, - reference : stencilReference, - mask : ~0, - frontOperation : { - fail : WebGLConstants.KEEP, - zFail : WebGLConstants.KEEP, - zPass : WebGLConstants.KEEP - }, - backOperation : { - fail : WebGLConstants.KEEP, - zFail : WebGLConstants.KEEP, - zPass : WebGLConstants.KEEP - } - }; - renderState = RenderState.fromCache(renderState); + } else { // replaceFnResult === true, or no/unknown return value from function + // Perform Autolinker's default anchor tag generation + var tagBuilder = this.getTagBuilder(), + anchorTag = tagBuilder.build( match ); // returns an Autolinker.HtmlTag instance - // If the silhouette program has already been cached use it - var program = command.shaderProgram; - var id = getProgramId(model, program); - var silhouetteProgram = silhouettePrograms[id]; - if (!defined(silhouetteProgram)) { - silhouetteProgram = createSilhouetteProgram(model, program, frameState); - silhouettePrograms[id] = silhouetteProgram; - } + return anchorTag.toAnchorString(); + } + }, - var silhouetteUniformMap = combine(command.uniformMap, { - gltf_silhouetteColor : createSilhouetteColorFunction(model), - gltf_silhouetteSize : createSilhouetteSizeFunction(model) - }); - silhouetteColorCommand.renderState = renderState; - silhouetteColorCommand.shaderProgram = silhouetteProgram; - silhouetteColorCommand.uniformMap = silhouetteUniformMap; - silhouetteColorCommand.castShadows = false; - silhouetteColorCommand.receiveShadows = false; - nodeCommand.silhouetteColorCommand = silhouetteColorCommand; + /** + * Lazily instantiates and returns the {@link #htmlParser} instance for this Autolinker instance. + * + * @protected + * @return {Autolinker.htmlParser.HtmlParser} + */ + getHtmlParser : function() { + var htmlParser = this.htmlParser; - if (!scene3DOnly) { - var command2D = nodeCommand.command2D; - var silhouetteModelCommand2D = DrawCommand.shallowClone(silhouetteModelCommand); - silhouetteModelCommand2D.boundingVolume = command2D.boundingVolume; - silhouetteModelCommand2D.modelMatrix = command2D.modelMatrix; - nodeCommand.silhouetteModelCommand2D = silhouetteModelCommand2D; + if( !htmlParser ) { + htmlParser = this.htmlParser = new Autolinker.htmlParser.HtmlParser(); + } - var silhouetteColorCommand2D = DrawCommand.shallowClone(silhouetteColorCommand); - silhouetteModelCommand2D.boundingVolume = command2D.boundingVolume; - silhouetteModelCommand2D.modelMatrix = command2D.modelMatrix; - nodeCommand.silhouetteColorCommand2D = silhouetteColorCommand2D; - } - } - } + return htmlParser; + }, - function modifyShaderForClippingPlanes(shader) { - shader = ShaderSource.replaceMain(shader, 'gltf_clip_main'); - shader += - 'uniform int gltf_clippingPlanesLength; \n' + - 'uniform bool gltf_clippingPlanesUnionRegions; \n' + - 'uniform vec4 gltf_clippingPlanes[czm_maxClippingPlanes]; \n' + - 'uniform vec4 gltf_clippingPlanesEdgeStyle; \n' + - 'void main() \n' + - '{ \n' + - ' gltf_clip_main(); \n' + - ' if (gltf_clippingPlanesLength > 0) \n' + - ' { \n' + - ' float clipDistance; \n' + - ' if (gltf_clippingPlanesUnionRegions) \n' + - ' { \n' + - ' clipDistance = czm_discardIfClippedWithUnion(gltf_clippingPlanes, gltf_clippingPlanesLength); \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' clipDistance = czm_discardIfClippedWithIntersect(gltf_clippingPlanes, gltf_clippingPlanesLength); \n' + - ' } \n' + - ' \n' + - ' vec4 clippingPlanesEdgeColor = vec4(1.0); \n' + - ' clippingPlanesEdgeColor.rgb = gltf_clippingPlanesEdgeStyle.rgb; \n' + - ' float clippingPlanesEdgeWidth = gltf_clippingPlanesEdgeStyle.a; \n' + - ' if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n' + - ' { \n' + - ' gl_FragColor = clippingPlanesEdgeColor; \n' + - ' } \n' + - ' } \n' + - '} \n'; - return shader; - } + /** + * Lazily instantiates and returns the {@link #matchParser} instance for this Autolinker instance. + * + * @protected + * @return {Autolinker.matchParser.MatchParser} + */ + getMatchParser : function() { + var matchParser = this.matchParser; - function updateSilhouette(model, frameState) { - // Generate silhouette commands when the silhouette size is greater than 0.0 and the alpha is greater than 0.0 - // There are two silhouette commands: - // 1. silhouetteModelCommand : render model normally while enabling stencil mask - // 2. silhouetteColorCommand : render enlarged model with a solid color while enabling stencil tests - if (!hasSilhouette(model, frameState)) { - return; - } + if( !matchParser ) { + matchParser = this.matchParser = new Autolinker.matchParser.MatchParser( { + urls : this.urls, + email : this.email, + twitter : this.twitter, + phone : this.phone, + hashtag : this.hashtag, + stripPrefix : this.stripPrefix + } ); + } - var nodeCommands = model._nodeCommands; - var dirty = alphaDirty(model.color.alpha, model._colorPreviousAlpha) || - alphaDirty(model.silhouetteColor.alpha, model._silhouetteColorPreviousAlpha) || - !defined(nodeCommands[0].silhouetteModelCommand); + return matchParser; + }, - model._colorPreviousAlpha = model.color.alpha; - model._silhouetteColorPreviousAlpha = model.silhouetteColor.alpha; - if (dirty) { - createSilhouetteCommands(model, frameState); - } - } + /** + * Returns the {@link #tagBuilder} instance for this Autolinker instance, lazily instantiating it + * if it does not yet exist. + * + * This method may be used in a {@link #replaceFn} to generate the {@link Autolinker.HtmlTag HtmlTag} instance that + * Autolinker would normally generate, and then allow for modifications before returning it. For example: + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance + * tag.setAttr( 'rel', 'nofollow' ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a> + * + * @return {Autolinker.AnchorTagBuilder} + */ + getTagBuilder : function() { + var tagBuilder = this.tagBuilder; - function updateClippingPlanes(model) { - var clippingPlanes = model.clippingPlanes; - var length = 0; - if (defined(clippingPlanes) && clippingPlanes.enabled) { - length = clippingPlanes.length; - } + if( !tagBuilder ) { + tagBuilder = this.tagBuilder = new Autolinker.AnchorTagBuilder( { + newWindow : this.newWindow, + truncate : this.truncate, + className : this.className + } ); + } - var packedPlanes = model._packedClippingPlanes; - var packedLength = packedPlanes.length; - if (packedLength !== length) { - packedPlanes.length = length; + return tagBuilder; + } - for (var i = packedLength; i < length; ++i) { - packedPlanes[i] = new Cartesian4(); - } - } - } +}; - var scratchBoundingSphere = new BoundingSphere(); - function scaleInPixels(positionWC, radius, frameState) { - scratchBoundingSphere.center = positionWC; - scratchBoundingSphere.radius = radius; - return frameState.camera.getPixelSize(scratchBoundingSphere, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); - } +/** + * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles, + * and Hashtags found in the given chunk of HTML. Does not link URLs found + * within HTML tags. + * + * For instance, if given the text: `You should go to http://www.yahoo.com`, + * then the result will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>` + * + * Example: + * + * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } ); + * // Produces: "Go to <a href="http://google.com">google.com</a>" + * + * @static + * @param {String} textOrHtml The HTML or text to find matches within (depending + * on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #twitter}, + * and {@link #hashtag} options are enabled). + * @param {Object} [options] Any of the configuration options for the Autolinker + * class, specified in an Object (map). See the class description for an + * example call. + * @return {String} The HTML text, with matches automatically linked. + */ +Autolinker.link = function( textOrHtml, options ) { + var autolinker = new Autolinker( options ); + return autolinker.link( textOrHtml ); +}; - var scratchPosition = new Cartesian3(); - var scratchCartographic = new Cartographic(); - function getScale(model, frameState) { - var scale = model.scale; +// Autolinker Namespaces +Autolinker.match = {}; +Autolinker.htmlParser = {}; +Autolinker.matchParser = {}; - if (model.minimumPixelSize !== 0.0) { - // Compute size of bounding sphere in pixels - var context = frameState.context; - var maxPixelSize = Math.max(context.drawingBufferWidth, context.drawingBufferHeight); - var m = defined(model._clampedModelMatrix) ? model._clampedModelMatrix : model.modelMatrix; - scratchPosition.x = m[12]; - scratchPosition.y = m[13]; - scratchPosition.z = m[14]; +/*global Autolinker */ +/*jshint eqnull:true, boss:true */ +/** + * @class Autolinker.Util + * @singleton + * + * A few utility methods for Autolinker. + */ +Autolinker.Util = { - if (defined(model._rtcCenter)) { - Cartesian3.add(model._rtcCenter, scratchPosition, scratchPosition); - } + /** + * @property {Function} abstractMethod + * + * A function object which represents an abstract method. + */ + abstractMethod : function() { throw "abstract"; }, - if (model._mode !== SceneMode.SCENE3D) { - var projection = frameState.mapProjection; - var cartographic = projection.ellipsoid.cartesianToCartographic(scratchPosition, scratchCartographic); - projection.project(cartographic, scratchPosition); - Cartesian3.fromElements(scratchPosition.z, scratchPosition.x, scratchPosition.y, scratchPosition); - } - var radius = model.boundingSphere.radius; - var metersPerPixel = scaleInPixels(scratchPosition, radius, frameState); + /** + * @private + * @property {RegExp} trimRegex + * + * The regular expression used to trim the leading and trailing whitespace + * from a string. + */ + trimRegex : /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - // metersPerPixel is always > 0.0 - var pixelsPerMeter = 1.0 / metersPerPixel; - var diameterInPixels = Math.min(pixelsPerMeter * (2.0 * radius), maxPixelSize); - // Maintain model's minimum pixel size - if (diameterInPixels < model.minimumPixelSize) { - scale = (model.minimumPixelSize * metersPerPixel) / (2.0 * model._initialRadius); - } - } + /** + * Assigns (shallow copies) the properties of `src` onto `dest`. + * + * @param {Object} dest The destination object. + * @param {Object} src The source object. + * @return {Object} The destination object (`dest`) + */ + assign : function( dest, src ) { + for( var prop in src ) { + if( src.hasOwnProperty( prop ) ) { + dest[ prop ] = src[ prop ]; + } + } - return defined(model.maximumScale) ? Math.min(model.maximumScale, scale) : scale; - } + return dest; + }, - function releaseCachedGltf(model) { - if (defined(model._cacheKey) && defined(model._cachedGltf) && (--model._cachedGltf.count === 0)) { - delete gltfCache[model._cacheKey]; - } - model._cachedGltf = undefined; - } - function checkSupportedExtensions(model) { - var extensionsRequired = model.extensionsRequired; - for (var extension in extensionsRequired) { - if (extensionsRequired.hasOwnProperty(extension)) { - if (extension !== 'CESIUM_RTC' && - extension !== 'KHR_technique_webgl' && - extension !== 'KHR_binary_glTF' && - extension !== 'KHR_materials_common' && - extension !== 'WEB3D_quantized_attributes') { - throw new RuntimeError('Unsupported glTF Extension: ' + extension); - } - } - } - } + /** + * Extends `superclass` to create a new subclass, adding the `protoProps` to the new subclass's prototype. + * + * @param {Function} superclass The constructor function for the superclass. + * @param {Object} protoProps The methods/properties to add to the subclass's prototype. This may contain the + * special property `constructor`, which will be used as the new subclass's constructor function. + * @return {Function} The new subclass function. + */ + extend : function( superclass, protoProps ) { + var superclassProto = superclass.prototype; - function checkSupportedGlExtensions(model, context) { - var glExtensionsUsed = model.gltf.glExtensionsUsed; - if (defined(glExtensionsUsed)) { - var glExtensionsUsedLength = glExtensionsUsed.length; - for (var i = 0; i < glExtensionsUsedLength; i++) { - var extension = glExtensionsUsed[i]; - if (extension !== 'OES_element_index_uint') { - throw new RuntimeError('Unsupported WebGL Extension: ' + extension); - } else if (!context.elementIndexUint) { - throw new RuntimeError('OES_element_index_uint WebGL extension is not enabled.'); - } - } - } - } + var F = function() {}; + F.prototype = superclassProto; - /////////////////////////////////////////////////////////////////////////// + var subclass; + if( protoProps.hasOwnProperty( 'constructor' ) ) { + subclass = protoProps.constructor; + } else { + subclass = function() { superclassProto.constructor.apply( this, arguments ); }; + } - function CachedRendererResources(context, cacheKey) { - this.buffers = undefined; - this.vertexArrays = undefined; - this.programs = undefined; - this.pickPrograms = undefined; - this.silhouettePrograms = undefined; - this.textures = undefined; - this.samplers = undefined; - this.renderStates = undefined; - this.ready = false; + var subclassProto = subclass.prototype = new F(); // set up prototype chain + subclassProto.constructor = subclass; // fix constructor property + subclassProto.superclass = superclassProto; - this.context = context; - this.cacheKey = cacheKey; - this.count = 0; - } + delete protoProps.constructor; // don't re-assign constructor property to the prototype, since a new function may have been created (`subclass`), which is now already there + Autolinker.Util.assign( subclassProto, protoProps ); - function destroy(property) { - for (var name in property) { - if (property.hasOwnProperty(name)) { - property[name].destroy(); - } - } - } + return subclass; + }, - function destroyCachedRendererResources(resources) { - destroy(resources.buffers); - destroy(resources.vertexArrays); - destroy(resources.programs); - destroy(resources.pickPrograms); - destroy(resources.silhouettePrograms); - destroy(resources.textures); - } - CachedRendererResources.prototype.release = function() { - if (--this.count === 0) { - if (defined(this.cacheKey)) { - // Remove if this was cached - delete this.context.cache.modelRendererResourceCache[this.cacheKey]; - } - destroyCachedRendererResources(this); - return destroyObject(this); - } + /** + * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the + * end of the string (by default, two periods: '..'). If the `str` length does not exceed + * `len`, the string will be returned unchanged. + * + * @param {String} str The string to truncate and add an ellipsis to. + * @param {Number} truncateLen The length to truncate the string at. + * @param {String} [ellipsisChars=..] The ellipsis character(s) to add to the end of `str` + * when truncated. Defaults to '..' + */ + ellipsis : function( str, truncateLen, ellipsisChars ) { + if( str.length > truncateLen ) { + ellipsisChars = ( ellipsisChars == null ) ? '..' : ellipsisChars; + str = str.substring( 0, truncateLen - ellipsisChars.length ) + ellipsisChars; + } + return str; + }, - return undefined; - }; - /////////////////////////////////////////////////////////////////////////// + /** + * Supports `Array.prototype.indexOf()` functionality for old IE (IE8 and below). + * + * @param {Array} arr The array to find an element of. + * @param {*} element The element to find in the array, and return the index of. + * @return {Number} The index of the `element`, or -1 if it was not found. + */ + indexOf : function( arr, element ) { + if( Array.prototype.indexOf ) { + return arr.indexOf( element ); - function getUpdateHeightCallback(model, ellipsoid, cartoPosition) { - return function(clampedPosition) { - if (model.heightReference === HeightReference.RELATIVE_TO_GROUND) { - var clampedCart = ellipsoid.cartesianToCartographic(clampedPosition, scratchCartographic); - clampedCart.height += cartoPosition.height; - ellipsoid.cartographicToCartesian(clampedCart, clampedPosition); - } + } else { + for( var i = 0, len = arr.length; i < len; i++ ) { + if( arr[ i ] === element ) return i; + } + return -1; + } + }, - var clampedModelMatrix = model._clampedModelMatrix; - // Modify clamped model matrix to use new height - Matrix4.clone(model.modelMatrix, clampedModelMatrix); - clampedModelMatrix[12] = clampedPosition.x; - clampedModelMatrix[13] = clampedPosition.y; - clampedModelMatrix[14] = clampedPosition.z; - model._heightChanged = true; - }; - } + /** + * Performs the functionality of what modern browsers do when `String.prototype.split()` is called + * with a regular expression that contains capturing parenthesis. + * + * For example: + * + * // Modern browsers: + * "a,b,c".split( /(,)/ ); // --> [ 'a', ',', 'b', ',', 'c' ] + * + * // Old IE (including IE8): + * "a,b,c".split( /(,)/ ); // --> [ 'a', 'b', 'c' ] + * + * This method emulates the functionality of modern browsers for the old IE case. + * + * @param {String} str The string to split. + * @param {RegExp} splitRegex The regular expression to split the input `str` on. The splitting + * character(s) will be spliced into the array, as in the "modern browsers" example in the + * description of this method. + * Note #1: the supplied regular expression **must** have the 'g' flag specified. + * Note #2: for simplicity's sake, the regular expression does not need + * to contain capturing parenthesis - it will be assumed that any match has them. + * @return {String[]} The split array of strings, with the splitting character(s) included. + */ + splitAndCapture : function( str, splitRegex ) { + if( !splitRegex.global ) throw new Error( "`splitRegex` must have the 'g' flag set" ); - function updateClamping(model) { - if (defined(model._removeUpdateHeightCallback)) { - model._removeUpdateHeightCallback(); - model._removeUpdateHeightCallback = undefined; - } + var result = [], + lastIdx = 0, + match; - var scene = model._scene; - if (!defined(scene) || (model.heightReference === HeightReference.NONE)) { - if (model.heightReference !== HeightReference.NONE) { - throw new DeveloperError('Height reference is not supported without a scene.'); - } - model._clampedModelMatrix = undefined; - return; - } + while( match = splitRegex.exec( str ) ) { + result.push( str.substring( lastIdx, match.index ) ); + result.push( match[ 0 ] ); // push the splitting char(s) - var globe = scene.globe; - var ellipsoid = globe.ellipsoid; + lastIdx = match.index + match[ 0 ].length; + } + result.push( str.substring( lastIdx ) ); - // Compute cartographic position so we don't recompute every update - var modelMatrix = model.modelMatrix; - scratchPosition.x = modelMatrix[12]; - scratchPosition.y = modelMatrix[13]; - scratchPosition.z = modelMatrix[14]; - var cartoPosition = ellipsoid.cartesianToCartographic(scratchPosition); + return result; + }, - if (!defined(model._clampedModelMatrix)) { - model._clampedModelMatrix = Matrix4.clone(modelMatrix, new Matrix4()); - } - // Install callback to handle updating of terrain tiles - var surface = globe._surface; - model._removeUpdateHeightCallback = surface.updateHeight(cartoPosition, getUpdateHeightCallback(model, ellipsoid, cartoPosition)); + /** + * Trims the leading and trailing whitespace from a string. + * + * @param {String} str The string to trim. + * @return {String} + */ + trim : function( str ) { + return str.replace( this.trimRegex, '' ); + } - // Set the correct height now - var height = globe.getHeight(cartoPosition); - if (defined(height)) { - // Get callback with cartoPosition being the non-clamped position - var cb = getUpdateHeightCallback(model, ellipsoid, cartoPosition); +}; +/*global Autolinker */ +/*jshint boss:true */ +/** + * @class Autolinker.HtmlTag + * @extends Object + * + * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically. + * + * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use + * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}. + * + * ## Examples + * + * Example instantiation: + * + * var tag = new Autolinker.HtmlTag( { + * tagName : 'a', + * attrs : { 'href': 'http://google.com', 'class': 'external-link' }, + * innerHtml : 'Google' + * } ); + * + * tag.toAnchorString(); // <a href="http://google.com" class="external-link">Google</a> + * + * // Individual accessor methods + * tag.getTagName(); // 'a' + * tag.getAttr( 'href' ); // 'http://google.com' + * tag.hasClass( 'external-link' ); // true + * + * + * Using mutator methods (which may be used in combination with instantiation config properties): + * + * var tag = new Autolinker.HtmlTag(); + * tag.setTagName( 'a' ); + * tag.setAttr( 'href', 'http://google.com' ); + * tag.addClass( 'external-link' ); + * tag.setInnerHtml( 'Google' ); + * + * tag.getTagName(); // 'a' + * tag.getAttr( 'href' ); // 'http://google.com' + * tag.hasClass( 'external-link' ); // true + * + * tag.toAnchorString(); // <a href="http://google.com" class="external-link">Google</a> + * + * + * ## Example use within a {@link Autolinker#replaceFn replaceFn} + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text + * tag.setAttr( 'rel', 'nofollow' ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a> + * + * + * ## Example use with a new tag for the replacement + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = new Autolinker.HtmlTag( { + * tagName : 'button', + * attrs : { 'title': 'Load URL: ' + match.getAnchorHref() }, + * innerHtml : 'Load URL: ' + match.getAnchorText() + * } ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test <button title="Load URL: http://google.com">Load URL: google.com</button> + */ +Autolinker.HtmlTag = Autolinker.Util.extend( Object, { - // Compute the clamped cartesian and call updateHeight callback - Cartographic.clone(cartoPosition, scratchCartographic); - scratchCartographic.height = height; - ellipsoid.cartographicToCartesian(scratchCartographic, scratchPosition); - cb(scratchPosition); - } - } + /** + * @cfg {String} tagName + * + * The tag name. Ex: 'a', 'button', etc. + * + * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toAnchorString} + * is executed. + */ - var scratchDisplayConditionCartesian = new Cartesian3(); - var scratchDistanceDisplayConditionCartographic = new Cartographic(); + /** + * @cfg {Object.<String, String>} attrs + * + * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the + * values are the attribute values. + */ - function distanceDisplayConditionVisible(model, frameState) { - var distance2; - var ddc = model.distanceDisplayCondition; - var nearSquared = ddc.near * ddc.near; - var farSquared = ddc.far * ddc.far; + /** + * @cfg {String} innerHtml + * + * The inner HTML for the tag. + * + * Note the camel case name on `innerHtml`. Acronyms are camelCased in this utility (such as not to run into the acronym + * naming inconsistency that the DOM developers created with `XMLHttpRequest`). You may alternatively use {@link #innerHTML} + * if you prefer, but this one is recommended. + */ - if (frameState.mode === SceneMode.SCENE2D) { - var frustum2DWidth = frameState.camera.frustum.right - frameState.camera.frustum.left; - distance2 = frustum2DWidth * 0.5; - distance2 = distance2 * distance2; - } else { - // Distance to center of primitive's reference frame - var position = Matrix4.getTranslation(model.modelMatrix, scratchDisplayConditionCartesian); - if (frameState.mode === SceneMode.COLUMBUS_VIEW) { - var projection = frameState.mapProjection; - var ellipsoid = projection.ellipsoid; - var cartographic = ellipsoid.cartesianToCartographic(position, scratchDistanceDisplayConditionCartographic); - position = projection.project(cartographic, position); - Cartesian3.fromElements(position.z, position.x, position.y, position); - } - distance2 = Cartesian3.distanceSquared(position, frameState.camera.positionWC); - } + /** + * @cfg {String} innerHTML + * + * Alias of {@link #innerHtml}, accepted for consistency with the browser DOM api, but prefer the camelCased version + * for acronym names. + */ - return (distance2 >= nearSquared) && (distance2 <= farSquared); - } - /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> - * - * @exception {RuntimeError} Failed to load external reference. - */ - Model.prototype.update = function(frameState) { - if (frameState.mode === SceneMode.MORPHING) { - return; - } + /** + * @protected + * @property {RegExp} whitespaceRegex + * + * Regular expression used to match whitespace in a string of CSS classes. + */ + whitespaceRegex : /\s+/, - var context = frameState.context; - this._defaultTexture = context.defaultTexture; - if ((this._state === ModelState.NEEDS_LOAD) && defined(this.gltf)) { - // Use renderer resources from cache instead of loading/creating them? - var cachedRendererResources; - var cacheKey = this.cacheKey; - if (defined(cacheKey)) { - context.cache.modelRendererResourceCache = defaultValue(context.cache.modelRendererResourceCache, {}); - var modelCaches = context.cache.modelRendererResourceCache; + /** + * @constructor + * @param {Object} [cfg] The configuration properties for this class, in an Object (map) + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); - cachedRendererResources = modelCaches[this.cacheKey]; - if (defined(cachedRendererResources)) { - if (!cachedRendererResources.ready) { - // Cached resources for the model are not loaded yet. We'll - // try again every frame until they are. - return; - } + this.innerHtml = this.innerHtml || this.innerHTML; // accept either the camelCased form or the fully capitalized acronym + }, - ++cachedRendererResources.count; - this._loadRendererResourcesFromCache = true; - } else { - cachedRendererResources = new CachedRendererResources(context, cacheKey); - cachedRendererResources.count = 1; - modelCaches[this.cacheKey] = cachedRendererResources; - } - this._cachedRendererResources = cachedRendererResources; - } else { - cachedRendererResources = new CachedRendererResources(context); - cachedRendererResources.count = 1; - this._cachedRendererResources = cachedRendererResources; - } - this._state = ModelState.LOADING; - if (this._state !== ModelState.FAILED) { - var extensions = this.gltf.extensions; - if (defined(extensions) && defined(extensions.CESIUM_RTC)) { - var center = Cartesian3.fromArray(extensions.CESIUM_RTC.center); - if (!Cartesian3.equals(center, Cartesian3.ZERO)) { - this._rtcCenter3D = center; + /** + * Sets the tag name that will be used to generate the tag with. + * + * @param {String} tagName + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setTagName : function( tagName ) { + this.tagName = tagName; + return this; + }, - var projection = frameState.mapProjection; - var ellipsoid = projection.ellipsoid; - var cartographic = ellipsoid.cartesianToCartographic(this._rtcCenter3D); - var projectedCart = projection.project(cartographic); - Cartesian3.fromElements(projectedCart.z, projectedCart.x, projectedCart.y, projectedCart); - this._rtcCenter2D = projectedCart; - this._rtcCenterEye = new Cartesian3(); - this._rtcCenter = this._rtcCenter3D; - } - } + /** + * Retrieves the tag name. + * + * @return {String} + */ + getTagName : function() { + return this.tagName || ""; + }, - this._loadResources = new LoadResources(); - if (!this._loadRendererResourcesFromCache) { - // Buffers are required to updateVersion - parseBuffers(this); - } - } - } - var loadResources = this._loadResources; - var incrementallyLoadTextures = this._incrementallyLoadTextures; - var justLoaded = false; + /** + * Sets an attribute on the HtmlTag. + * + * @param {String} attrName The attribute name to set. + * @param {String} attrValue The attribute value to set. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setAttr : function( attrName, attrValue ) { + var tagAttrs = this.getAttrs(); + tagAttrs[ attrName ] = attrValue; - if (this._state === ModelState.LOADING) { - // Transition from LOADING -> LOADED once resources are downloaded and created. - // Textures may continue to stream in while in the LOADED state. - if (loadResources.pendingBufferLoads === 0) { - if (!this._updatedGltfVersion) { - var options = { - optimizeForCesium: true, - addBatchIdToGeneratedShaders : this._addBatchIdToGeneratedShaders - }; - frameState.brdfLutGenerator.update(frameState); - updateVersion(this.gltf); - checkSupportedExtensions(this); - addPipelineExtras(this.gltf); - addDefaults(this.gltf); - processModelMaterialsCommon(this.gltf, options); - processPbrMetallicRoughness(this.gltf, options); - // We do this after to make sure that the ids don't change - addBuffersToLoadResources(this); + return this; + }, - if (!this._loadRendererResourcesFromCache) { - parseBufferViews(this); - parseShaders(this); - parsePrograms(this); - parseTextures(this, context); - } - parseMaterials(this); - parseMeshes(this); - parseNodes(this); - this._boundingSphere = computeBoundingSphere(this); - this._initialRadius = this._boundingSphere.radius; - this._updatedGltfVersion = true; - } - if (this._updatedGltfVersion && loadResources.pendingShaderLoads === 0) { - createResources(this, frameState); - } - } - if (loadResources.finished() || - (incrementallyLoadTextures && loadResources.finishedEverythingButTextureCreation())) { - this._state = ModelState.LOADED; - justLoaded = true; - } - } + /** + * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`. + * + * @param {String} name The attribute name to retrieve. + * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag. + */ + getAttr : function( attrName ) { + return this.getAttrs()[ attrName ]; + }, - // Incrementally stream textures. - if (defined(loadResources) && (this._state === ModelState.LOADED)) { - if (incrementallyLoadTextures && !justLoaded) { - createResources(this, frameState); - } - if (loadResources.finished()) { - this._loadResources = undefined; // Clear CPU memory since WebGL resources were created. + /** + * Sets one or more attributes on the HtmlTag. + * + * @param {Object.<String, String>} attrs A key/value Object (map) of the attributes to set. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setAttrs : function( attrs ) { + var tagAttrs = this.getAttrs(); + Autolinker.Util.assign( tagAttrs, attrs ); - var resources = this._rendererResources; - var cachedResources = this._cachedRendererResources; + return this; + }, - cachedResources.buffers = resources.buffers; - cachedResources.vertexArrays = resources.vertexArrays; - cachedResources.programs = resources.programs; - cachedResources.pickPrograms = resources.pickPrograms; - cachedResources.silhouettePrograms = resources.silhouettePrograms; - cachedResources.textures = resources.textures; - cachedResources.samplers = resources.samplers; - cachedResources.renderStates = resources.renderStates; - cachedResources.ready = true; - // The normal attribute name is required for silhouettes, so get it before the gltf JSON is released - this._normalAttributeName = getAttributeOrUniformBySemantic(this.gltf, 'NORMAL'); + /** + * Retrieves the attributes Object (map) for the HtmlTag. + * + * @return {Object.<String, String>} A key/value object of the attributes for the HtmlTag. + */ + getAttrs : function() { + return this.attrs || ( this.attrs = {} ); + }, - // Vertex arrays are unique to this model, do not store in cache. - if (defined(this._precreatedAttributes)) { - cachedResources.vertexArrays = {}; - } - if (this.releaseGltfJson) { - releaseCachedGltf(this); - } - } - } + /** + * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag. + * + * @param {String} cssClass One or more space-separated CSS classes to set (overwrite). + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setClass : function( cssClass ) { + return this.setAttr( 'class', cssClass ); + }, - var silhouette = hasSilhouette(this, frameState); - var translucent = isTranslucent(this); - var invisible = isInvisible(this); - var displayConditionPassed = defined(this.distanceDisplayCondition) ? distanceDisplayConditionVisible(this, frameState) : true; - var show = this.show && displayConditionPassed && (this.scale !== 0.0) && (!invisible || silhouette); - if ((show && this._state === ModelState.LOADED) || justLoaded) { - var animated = this.activeAnimations.update(frameState) || this._cesiumAnimationsDirty; - this._cesiumAnimationsDirty = false; - this._dirty = false; - var modelMatrix = this.modelMatrix; + /** + * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes. + * + * @param {String} cssClass One or more space-separated CSS classes to add. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + addClass : function( cssClass ) { + var classAttr = this.getClass(), + whitespaceRegex = this.whitespaceRegex, + indexOf = Autolinker.Util.indexOf, // to support IE8 and below + classes = ( !classAttr ) ? [] : classAttr.split( whitespaceRegex ), + newClasses = cssClass.split( whitespaceRegex ), + newClass; + + while( newClass = newClasses.shift() ) { + if( indexOf( classes, newClass ) === -1 ) { + classes.push( newClass ); + } + } + + this.getAttrs()[ 'class' ] = classes.join( " " ); + return this; + }, - var modeChanged = frameState.mode !== this._mode; - this._mode = frameState.mode; - // Model's model matrix needs to be updated - var modelTransformChanged = !Matrix4.equals(this._modelMatrix, modelMatrix) || - (this._scale !== this.scale) || - (this._minimumPixelSize !== this.minimumPixelSize) || (this.minimumPixelSize !== 0.0) || // Minimum pixel size changed or is enabled - (this._maximumScale !== this.maximumScale) || - (this._heightReference !== this.heightReference) || this._heightChanged || - modeChanged; + /** + * Convenience method to remove one or more CSS classes from the HtmlTag. + * + * @param {String} cssClass One or more space-separated CSS classes to remove. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + removeClass : function( cssClass ) { + var classAttr = this.getClass(), + whitespaceRegex = this.whitespaceRegex, + indexOf = Autolinker.Util.indexOf, // to support IE8 and below + classes = ( !classAttr ) ? [] : classAttr.split( whitespaceRegex ), + removeClasses = cssClass.split( whitespaceRegex ), + removeClass; - if (modelTransformChanged || justLoaded) { - Matrix4.clone(modelMatrix, this._modelMatrix); + while( classes.length && ( removeClass = removeClasses.shift() ) ) { + var idx = indexOf( classes, removeClass ); + if( idx !== -1 ) { + classes.splice( idx, 1 ); + } + } - updateClamping(this); + this.getAttrs()[ 'class' ] = classes.join( " " ); + return this; + }, - if (defined(this._clampedModelMatrix)) { - modelMatrix = this._clampedModelMatrix; - } - this._scale = this.scale; - this._minimumPixelSize = this.minimumPixelSize; - this._maximumScale = this.maximumScale; - this._heightReference = this.heightReference; - this._heightChanged = false; + /** + * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when + * there are multiple. + * + * @return {String} + */ + getClass : function() { + return this.getAttrs()[ 'class' ] || ""; + }, - var scale = getScale(this, frameState); - var computedModelMatrix = this._computedModelMatrix; - Matrix4.multiplyByUniformScale(modelMatrix, scale, computedModelMatrix); - if (this._upAxis === Axis.Y) { - Matrix4.multiplyTransformation(computedModelMatrix, Axis.Y_UP_TO_Z_UP, computedModelMatrix); - } else if (this._upAxis === Axis.X) { - Matrix4.multiplyTransformation(computedModelMatrix, Axis.X_UP_TO_Z_UP, computedModelMatrix); - } - } - var clippingPlanes = this.clippingPlanes; - if (defined(clippingPlanes) && clippingPlanes.enabled) { - Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); - } + /** + * Convenience method to check if the tag has a CSS class or not. + * + * @param {String} cssClass The CSS class to check for. + * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise. + */ + hasClass : function( cssClass ) { + return ( ' ' + this.getClass() + ' ' ).indexOf( ' ' + cssClass + ' ' ) !== -1; + }, - // Update modelMatrix throughout the graph as needed - if (animated || modelTransformChanged || justLoaded) { - updateNodeHierarchyModelMatrix(this, modelTransformChanged, justLoaded, frameState.mapProjection); - this._dirty = true; - if (animated || justLoaded) { - // Apply skins if animation changed any node transforms - applySkins(this); - } - } + /** + * Sets the inner HTML for the tag. + * + * @param {String} html The inner HTML to set. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setInnerHtml : function( html ) { + this.innerHtml = html; - if (this._perNodeShowDirty) { - this._perNodeShowDirty = false; - updatePerNodeShow(this); - } - updatePickIds(this, context); - updateWireframe(this); - updateShowBoundingVolume(this); - updateShadows(this); - updateColor(this, frameState); - updateSilhouette(this, frameState); - updateClippingPlanes(this, frameState); - } + return this; + }, - if (justLoaded) { - // Called after modelMatrix update. - var model = this; - frameState.afterRender.push(function() { - model._ready = true; - model._readyPromise.resolve(model); - }); - return; - } - // We don't check show at the top of the function since we - // want to be able to progressively load models when they are not shown, - // and then have them visible immediately when show is set to true. - if (show && !this._ignoreCommands) { - // PERFORMANCE_IDEA: This is terrible - var commandList = frameState.commandList; - var passes = frameState.passes; - var nodeCommands = this._nodeCommands; - var length = nodeCommands.length; - var i; - var nc; + /** + * Retrieves the inner HTML for the tag. + * + * @return {String} + */ + getInnerHtml : function() { + return this.innerHtml || ""; + }, - var idl2D = frameState.mapProjection.ellipsoid.maximumRadius * CesiumMath.PI; - var boundingVolume; - if (passes.render) { - for (i = 0; i < length; ++i) { - nc = nodeCommands[i]; - if (nc.show) { - var command = translucent ? nc.translucentCommand : nc.command; - command = silhouette ? nc.silhouetteModelCommand : command; - commandList.push(command); - boundingVolume = nc.command.boundingVolume; - if (frameState.mode === SceneMode.SCENE2D && - (boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) { - var command2D = translucent ? nc.translucentCommand2D : nc.command2D; - command2D = silhouette ? nc.silhouetteModelCommand2D : command2D; - commandList.push(command2D); - } - } - } + /** + * Override of superclass method used to generate the HTML string for the tag. + * + * @return {String} + */ + toAnchorString : function() { + var tagName = this.getTagName(), + attrsStr = this.buildAttrsStr(); - if (silhouette) { - // Render second silhouette pass - for (i = 0; i < length; ++i) { - nc = nodeCommands[i]; - if (nc.show) { - commandList.push(nc.silhouetteColorCommand); - boundingVolume = nc.command.boundingVolume; - if (frameState.mode === SceneMode.SCENE2D && - (boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) { - commandList.push(nc.silhouetteColorCommand2D); - } - } - } - } - } + attrsStr = ( attrsStr ) ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes - if (passes.pick && this.allowPicking) { - for (i = 0; i < length; ++i) { - nc = nodeCommands[i]; - if (nc.show) { - var pickCommand = nc.pickCommand; - commandList.push(pickCommand); + return [ '<', tagName, attrsStr, '>', this.getInnerHtml(), '</', tagName, '>' ].join( "" ); + }, - boundingVolume = pickCommand.boundingVolume; - if (frameState.mode === SceneMode.SCENE2D && - (boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) { - commandList.push(nc.pickCommand2D); - } - } - } - } - } - }; - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see Model#destroy - */ - Model.prototype.isDestroyed = function() { - return false; - }; + /** + * Support method for {@link #toAnchorString}, returns the string space-separated key="value" pairs, used to populate + * the stringified HtmlTag. + * + * @protected + * @return {String} Example return: `attr1="value1" attr2="value2"` + */ + buildAttrsStr : function() { + if( !this.attrs ) return ""; // no `attrs` Object (map) has been set, return empty string - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * model = model && model.destroy(); - * - * @see Model#isDestroyed - */ - Model.prototype.destroy = function() { - // Vertex arrays are unique to this model, destroy here. - if (defined(this._precreatedAttributes)) { - destroy(this._rendererResources.vertexArrays); - } + var attrs = this.getAttrs(), + attrsArr = []; - if (defined(this._removeUpdateHeightCallback)) { - this._removeUpdateHeightCallback(); - this._removeUpdateHeightCallback = undefined; - } + for( var prop in attrs ) { + if( attrs.hasOwnProperty( prop ) ) { + attrsArr.push( prop + '="' + attrs[ prop ] + '"' ); + } + } + return attrsArr.join( " " ); + } - if (defined(this._terrainProviderChangedCallback)) { - this._terrainProviderChangedCallback(); - this._terrainProviderChangedCallback = undefined; - } +} ); - this._rendererResources = undefined; - this._cachedRendererResources = this._cachedRendererResources && this._cachedRendererResources.release(); +/*global Autolinker */ +/*jshint sub:true */ +/** + * @protected + * @class Autolinker.AnchorTagBuilder + * @extends Object + * + * Builds anchor (<a>) tags for the Autolinker utility when a match is found. + * + * Normally this class is instantiated, configured, and used internally by an {@link Autolinker} instance, but may + * actually be retrieved in a {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag} instances + * which may be modified before returning from the {@link Autolinker#replaceFn replaceFn}. For example: + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance + * tag.setAttr( 'rel', 'nofollow' ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a> + */ +Autolinker.AnchorTagBuilder = Autolinker.Util.extend( Object, { - var pickIds = this._pickIds; - var length = pickIds.length; - for (var i = 0; i < length; ++i) { - pickIds[i].destroy(); - } + /** + * @cfg {Boolean} newWindow + * @inheritdoc Autolinker#newWindow + */ - releaseCachedGltf(this); + /** + * @cfg {Number} truncate + * @inheritdoc Autolinker#truncate + */ - return destroyObject(this); - }; + /** + * @cfg {String} className + * @inheritdoc Autolinker#className + */ - return Model; -}); -define('DataSources/ModelVisualizer',[ - '../Core/AssociativeArray', - '../Core/BoundingSphere', - '../Core/Color', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Matrix4', - '../Scene/ColorBlendMode', - '../Scene/HeightReference', - '../Scene/Model', - '../Scene/ModelAnimationLoop', - '../Scene/ShadowMode', - './BoundingSphereState', - './Property' - ], function( - AssociativeArray, - BoundingSphere, - Color, - defined, - destroyObject, - DeveloperError, - Matrix4, - ColorBlendMode, - HeightReference, - Model, - ModelAnimationLoop, - ShadowMode, - BoundingSphereState, - Property) { - 'use strict'; + /** + * @constructor + * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map). + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + }, - var defaultScale = 1.0; - var defaultMinimumPixelSize = 0.0; - var defaultIncrementallyLoadTextures = true; - var defaultClampAnimations = true; - var defaultShadows = ShadowMode.ENABLED; - var defaultHeightReference = HeightReference.NONE; - var defaultSilhouetteColor = Color.RED; - var defaultSilhouetteSize = 0.0; - var defaultColor = Color.WHITE; - var defaultColorBlendMode = ColorBlendMode.HIGHLIGHT; - var defaultColorBlendAmount = 0.5; - var modelMatrixScratch = new Matrix4(); - var nodeMatrixScratch = new Matrix4(); + /** + * Generates the actual anchor (<a>) tag to use in place of the + * matched text, via its `match` object. + * + * @param {Autolinker.match.Match} match The Match instance to generate an + * anchor tag from. + * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag. + */ + build : function( match ) { + var tag = new Autolinker.HtmlTag( { + tagName : 'a', + attrs : this.createAttrs( match.getType(), match.getAnchorHref() ), + innerHtml : this.processAnchorText( match.getAnchorText() ) + } ); - /** - * A {@link Visualizer} which maps {@link Entity#model} to a {@link Model}. - * @alias ModelVisualizer - * @constructor - * - * @param {Scene} scene The scene the primitives will be rendered in. - * @param {EntityCollection} entityCollection The entityCollection to visualize. - */ - function ModelVisualizer(scene, entityCollection) { - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - if (!defined(entityCollection)) { - throw new DeveloperError('entityCollection is required.'); - } - - entityCollection.collectionChanged.addEventListener(ModelVisualizer.prototype._onCollectionChanged, this); + return tag; + }, - this._scene = scene; - this._primitives = scene.primitives; - this._entityCollection = entityCollection; - this._modelHash = {}; - this._entitiesToVisualize = new AssociativeArray(); - this._onCollectionChanged(entityCollection, entityCollection.values, [], []); - } - /** - * Updates models created this visualizer to match their - * Entity counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. - */ - ModelVisualizer.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var entities = this._entitiesToVisualize.values; - var modelHash = this._modelHash; - var primitives = this._primitives; + /** + * Creates the Object (map) of the HTML attributes for the anchor (<a>) + * tag being generated. + * + * @protected + * @param {"url"/"email"/"phone"/"twitter"/"hashtag"} matchType The type of + * match that an anchor tag is being generated for. + * @param {String} href The href for the anchor tag. + * @return {Object} A key/value Object (map) of the anchor tag's attributes. + */ + createAttrs : function( matchType, anchorHref ) { + var attrs = { + 'href' : anchorHref // we'll always have the `href` attribute + }; - for (var i = 0, len = entities.length; i < len; i++) { - var entity = entities[i]; - var modelGraphics = entity._model; + var cssClass = this.createCssClass( matchType ); + if( cssClass ) { + attrs[ 'class' ] = cssClass; + } + if( this.newWindow ) { + attrs[ 'target' ] = "_blank"; + } - var uri; - var modelData = modelHash[entity.id]; - var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(modelGraphics._show, time, true); + return attrs; + }, - var modelMatrix; - if (show) { - modelMatrix = entity.computeModelMatrix(time, modelMatrixScratch); - uri = Property.getValueOrUndefined(modelGraphics._uri, time); - show = defined(modelMatrix) && defined(uri); - } - if (!show) { - if (defined(modelData)) { - modelData.modelPrimitive.show = false; - } - continue; - } + /** + * Creates the CSS class that will be used for a given anchor tag, based on + * the `matchType` and the {@link #className} config. + * + * @private + * @param {"url"/"email"/"phone"/"twitter"/"hashtag"} matchType The type of + * match that an anchor tag is being generated for. + * @return {String} The CSS class string for the link. Example return: + * "myLink myLink-url". If no {@link #className} was configured, returns + * an empty string. + */ + createCssClass : function( matchType ) { + var className = this.className; - var model = defined(modelData) ? modelData.modelPrimitive : undefined; - if (!defined(model) || uri !== modelData.uri) { - if (defined(model)) { - primitives.removeAndDestroy(model); - delete modelHash[entity.id]; - } - model = Model.fromGltf({ - url : uri, - incrementallyLoadTextures : Property.getValueOrDefault(modelGraphics._incrementallyLoadTextures, time, defaultIncrementallyLoadTextures), - scene : this._scene - }); + if( !className ) + return ""; + else + return className + " " + className + "-" + matchType; // ex: "myLink myLink-url", "myLink myLink-email", "myLink myLink-phone", "myLink myLink-twitter", or "myLink myLink-hashtag" + }, - model.readyPromise.otherwise(onModelError); - model.id = entity; - primitives.add(model); + /** + * Processes the `anchorText` by truncating the text according to the + * {@link #truncate} config. + * + * @private + * @param {String} anchorText The anchor tag's text (i.e. what will be + * displayed). + * @return {String} The processed `anchorText`. + */ + processAnchorText : function( anchorText ) { + anchorText = this.doTruncate( anchorText ); - modelData = { - modelPrimitive : model, - uri : uri, - animationsRunning : false, - nodeTransformationsScratch : {}, - originalNodeMatrixHash : {} - }; - modelHash[entity.id] = modelData; - } + return anchorText; + }, - model.show = true; - model.scale = Property.getValueOrDefault(modelGraphics._scale, time, defaultScale); - model.minimumPixelSize = Property.getValueOrDefault(modelGraphics._minimumPixelSize, time, defaultMinimumPixelSize); - model.maximumScale = Property.getValueOrUndefined(modelGraphics._maximumScale, time); - model.modelMatrix = Matrix4.clone(modelMatrix, model.modelMatrix); - model.shadows = Property.getValueOrDefault(modelGraphics._shadows, time, defaultShadows); - model.heightReference = Property.getValueOrDefault(modelGraphics._heightReference, time, defaultHeightReference); - model.distanceDisplayCondition = Property.getValueOrUndefined(modelGraphics._distanceDisplayCondition, time); - model.silhouetteColor = Property.getValueOrDefault(modelGraphics._silhouetteColor, time, defaultSilhouetteColor, model._silhouetteColor); - model.silhouetteSize = Property.getValueOrDefault(modelGraphics._silhouetteSize, time, defaultSilhouetteSize); - model.color = Property.getValueOrDefault(modelGraphics._color, time, defaultColor, model._color); - model.colorBlendMode = Property.getValueOrDefault(modelGraphics._colorBlendMode, time, defaultColorBlendMode); - model.colorBlendAmount = Property.getValueOrDefault(modelGraphics._colorBlendAmount, time, defaultColorBlendAmount); - model.clippingPlanes = Property.getValueOrUndefined(modelGraphics._clippingPlanes, time); - model.clampAnimations = Property.getValueOrDefault(modelGraphics._clampAnimations, time, defaultClampAnimations); - if (model.ready) { - var runAnimations = Property.getValueOrDefault(modelGraphics._runAnimations, time, true); - if (modelData.animationsRunning !== runAnimations) { - if (runAnimations) { - model.activeAnimations.addAll({ - loop : ModelAnimationLoop.REPEAT - }); - } else { - model.activeAnimations.removeAll(); - } - modelData.animationsRunning = runAnimations; - } + /** + * Performs the truncation of the `anchorText`, if the `anchorText` is + * longer than the {@link #truncate} option. Truncates the text to 2 + * characters fewer than the {@link #truncate} option, and adds ".." to the + * end. + * + * @private + * @param {String} text The anchor tag's text (i.e. what will be displayed). + * @return {String} The truncated anchor text. + */ + doTruncate : function( anchorText ) { + return Autolinker.Util.ellipsis( anchorText, this.truncate || Number.POSITIVE_INFINITY ); + } - // Apply node transformations - var nodeTransformations = Property.getValueOrUndefined(modelGraphics._nodeTransformations, time, modelData.nodeTransformationsScratch); - if (defined(nodeTransformations)) { - var originalNodeMatrixHash = modelData.originalNodeMatrixHash; - var nodeNames = Object.keys(nodeTransformations); - for (var nodeIndex = 0, nodeLength = nodeNames.length; nodeIndex < nodeLength; ++nodeIndex) { - var nodeName = nodeNames[nodeIndex]; +} ); +/*global Autolinker */ +/** + * @private + * @class Autolinker.htmlParser.HtmlParser + * @extends Object + * + * An HTML parser implementation which simply walks an HTML string and returns an array of + * {@link Autolinker.htmlParser.HtmlNode HtmlNodes} that represent the basic HTML structure of the input string. + * + * Autolinker uses this to only link URLs/emails/Twitter handles within text nodes, effectively ignoring / "walking + * around" HTML tags. + */ +Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, { - var nodeTransformation = nodeTransformations[nodeName]; - if (!defined(nodeTransformation)) { - continue; - } + /** + * @private + * @property {RegExp} htmlRegex + * + * The regular expression used to pull out HTML tags from a string. Handles namespaced HTML tags and + * attribute names, as specified by http://www.w3.org/TR/html-markup/syntax.html. + * + * Capturing groups: + * + * 1. The "!DOCTYPE" tag name, if a tag is a <!DOCTYPE> tag. + * 2. If it is an end tag, this group will have the '/'. + * 3. If it is a comment tag, this group will hold the comment text (i.e. + * the text inside the `<!--` and `-->`. + * 4. The tag name for all tags (other than the <!DOCTYPE> tag) + */ + htmlRegex : (function() { + var commentTagRegex = /!--([\s\S]+?)--/, + tagNameRegex = /[0-9a-zA-Z][0-9a-zA-Z:]*/, + attrNameRegex = /[^\s\0"'>\/=\x01-\x1F\x7F]+/, // the unicode range accounts for excluding control chars, and the delete char + attrValueRegex = /(?:"[^"]*?"|'[^']*?'|[^'"=<>`\s]+)/, // double quoted, single quoted, or unquoted attribute values + nameEqualsValueRegex = attrNameRegex.source + '(?:\\s*=\\s*' + attrValueRegex.source + ')?'; // optional '=[value]' - var modelNode = model.getNode(nodeName); - if (!defined(modelNode)) { - continue; - } + return new RegExp( [ + // for <!DOCTYPE> tag. Ex: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">) + '(?:', + '<(!DOCTYPE)', // *** Capturing Group 1 - If it's a doctype tag - var originalNodeMatrix = originalNodeMatrixHash[nodeName]; - if (!defined(originalNodeMatrix)) { - originalNodeMatrix = modelNode.matrix.clone(); - originalNodeMatrixHash[nodeName] = originalNodeMatrix; - } + // Zero or more attributes following the tag name + '(?:', + '\\s+', // one or more whitespace chars before an attribute - var transformationMatrix = Matrix4.fromTranslationRotationScale(nodeTransformation, nodeMatrixScratch); - modelNode.matrix = Matrix4.multiply(originalNodeMatrix, transformationMatrix, transformationMatrix); - } - } - } - } + // Either: + // A. attr="value", or + // B. "value" alone (To cover example doctype tag: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">) + '(?:', nameEqualsValueRegex, '|', attrValueRegex.source + ')', + ')*', + '>', + ')', - return true; - }; + '|', - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - ModelVisualizer.prototype.isDestroyed = function() { - return false; - }; + // All other HTML tags (i.e. tags that are not <!DOCTYPE>) + '(?:', + '<(/)?', // Beginning of a tag or comment. Either '<' for a start tag, or '</' for an end tag. + // *** Capturing Group 2: The slash or an empty string. Slash ('/') for end tag, empty string for start or self-closing tag. - /** - * Removes and destroys all primitives created by this instance. - */ - ModelVisualizer.prototype.destroy = function() { - this._entityCollection.collectionChanged.removeEventListener(ModelVisualizer.prototype._onCollectionChanged, this); - var entities = this._entitiesToVisualize.values; - var modelHash = this._modelHash; - var primitives = this._primitives; - for (var i = entities.length - 1; i > -1; i--) { - removeModel(this, entities[i], modelHash, primitives); - } - return destroyObject(this); - }; + '(?:', + commentTagRegex.source, // *** Capturing Group 3 - A Comment Tag's Text - /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private - */ - ModelVisualizer.prototype.getBoundingSphere = function(entity, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); - } - if (!defined(result)) { - throw new DeveloperError('result is required.'); - } - - var modelData = this._modelHash[entity.id]; - if (!defined(modelData)) { - return BoundingSphereState.FAILED; - } + '|', - var model = modelData.modelPrimitive; - if (!defined(model) || !model.show) { - return BoundingSphereState.FAILED; - } + '(?:', - if (!model.ready) { - return BoundingSphereState.PENDING; - } + // *** Capturing Group 4 - The tag name + '(' + tagNameRegex.source + ')', - if (model.heightReference === HeightReference.NONE) { - BoundingSphere.transform(model.boundingSphere, model.modelMatrix, result); - } else { - if (!defined(model._clampedModelMatrix)) { - return BoundingSphereState.PENDING; - } - BoundingSphere.transform(model.boundingSphere, model._clampedModelMatrix, result); - } - return BoundingSphereState.DONE; - }; + // Zero or more attributes following the tag name + '(?:', + '\\s+', // one or more whitespace chars before an attribute + nameEqualsValueRegex, // attr="value" (with optional ="value" part) + ')*', - /** - * @private - */ - ModelVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { - var i; - var entity; - var entities = this._entitiesToVisualize; - var modelHash = this._modelHash; - var primitives = this._primitives; + '\\s*/?', // any trailing spaces and optional '/' before the closing '>' - for (i = added.length - 1; i > -1; i--) { - entity = added[i]; - if (defined(entity._model) && defined(entity._position)) { - entities.set(entity.id, entity); - } - } + ')', + ')', + '>', + ')' + ].join( "" ), 'gi' ); + } )(), - for (i = changed.length - 1; i > -1; i--) { - entity = changed[i]; - if (defined(entity._model) && defined(entity._position)) { - clearNodeTransformationsScratch(entity, modelHash); - entities.set(entity.id, entity); - } else { - removeModel(this, entity, modelHash, primitives); - entities.remove(entity.id); - } - } + /** + * @private + * @property {RegExp} htmlCharacterEntitiesRegex + * + * The regular expression that matches common HTML character entities. + * + * Ignoring & as it could be part of a query string -- handling it separately. + */ + htmlCharacterEntitiesRegex: /( | |<|<|>|>|"|"|')/gi, - for (i = removed.length - 1; i > -1; i--) { - entity = removed[i]; - removeModel(this, entity, modelHash, primitives); - entities.remove(entity.id); - } - }; - function removeModel(visualizer, entity, modelHash, primitives) { - var modelData = modelHash[entity.id]; - if (defined(modelData)) { - primitives.removeAndDestroy(modelData.modelPrimitive); - delete modelHash[entity.id]; - } - } + /** + * Parses an HTML string and returns a simple array of {@link Autolinker.htmlParser.HtmlNode HtmlNodes} + * to represent the HTML structure of the input string. + * + * @param {String} html The HTML to parse. + * @return {Autolinker.htmlParser.HtmlNode[]} + */ + parse : function( html ) { + var htmlRegex = this.htmlRegex, + currentResult, + lastIndex = 0, + textAndEntityNodes, + nodes = []; // will be the result of the method - function clearNodeTransformationsScratch(entity, modelHash) { - var modelData = modelHash[entity.id]; - if (defined(modelData)) { - modelData.nodeTransformationsScratch = {}; - } - } + while( ( currentResult = htmlRegex.exec( html ) ) !== null ) { + var tagText = currentResult[ 0 ], + commentText = currentResult[ 3 ], // if we've matched a comment + tagName = currentResult[ 1 ] || currentResult[ 4 ], // The <!DOCTYPE> tag (ex: "!DOCTYPE"), or another tag (ex: "a" or "img") + isClosingTag = !!currentResult[ 2 ], + inBetweenTagsText = html.substring( lastIndex, currentResult.index ); - function onModelError(error) { - console.error(error); - } + // Push TextNodes and EntityNodes for any text found between tags + if( inBetweenTagsText ) { + textAndEntityNodes = this.parseTextAndEntityNodes( inBetweenTagsText ); + nodes.push.apply( nodes, textAndEntityNodes ); + } - return ModelVisualizer; -}); + // Push the CommentNode or ElementNode + if( commentText ) { + nodes.push( this.createCommentNode( tagText, commentText ) ); + } else { + nodes.push( this.createElementNode( tagText, tagName, isClosingTag ) ); + } -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PolylineCommon',[],function() { - 'use strict'; - return "void clipLineSegmentToNearPlane(\n\ -vec3 p0,\n\ -vec3 p1,\n\ -out vec4 positionWC,\n\ -out bool clipped,\n\ -out bool culledByNearPlane)\n\ -{\n\ -culledByNearPlane = false;\n\ -clipped = false;\n\ -vec3 p1ToP0 = p1 - p0;\n\ -float magnitude = length(p1ToP0);\n\ -vec3 direction = normalize(p1ToP0);\n\ -float endPoint0Distance = -(czm_currentFrustum.x + p0.z);\n\ -float denominator = -direction.z;\n\ -if (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7)\n\ -{\n\ -culledByNearPlane = true;\n\ -}\n\ -else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7)\n\ -{\n\ -float t = (czm_currentFrustum.x + p0.z) / denominator;\n\ -if (t < 0.0 || t > magnitude)\n\ -{\n\ -culledByNearPlane = true;\n\ -}\n\ -else\n\ -{\n\ -p0 = p0 + t * direction;\n\ -clipped = true;\n\ -}\n\ -}\n\ -positionWC = czm_eyeToWindowCoordinates(vec4(p0, 1.0));\n\ -}\n\ -vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle) {\n\ -vec4 endPointWC, p0, p1;\n\ -bool culledByNearPlane, clipped;\n\ -vec4 positionEC = czm_modelViewRelativeToEye * position;\n\ -vec4 prevEC = czm_modelViewRelativeToEye * previous;\n\ -vec4 nextEC = czm_modelViewRelativeToEye * next;\n\ -vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);\n\ -vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);\n\ -vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);\n\ -#ifdef POLYLINE_DASH\n\ -vec2 lineDir;\n\ -if (usePrevious) {\n\ -lineDir = normalize(positionWindow.xy - previousWindow.xy);\n\ -}\n\ -else {\n\ -lineDir = normalize(nextWindow.xy - positionWindow.xy);\n\ -}\n\ -angle = atan(lineDir.x, lineDir.y) - 1.570796327;\n\ -angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;\n\ -#endif\n\ -clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, clipped, culledByNearPlane);\n\ -clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, clipped, culledByNearPlane);\n\ -clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, endPointWC, clipped, culledByNearPlane);\n\ -if (culledByNearPlane)\n\ -{\n\ -return vec4(0.0, 0.0, 0.0, 1.0);\n\ -}\n\ -vec2 prevWC = normalize(p0.xy - endPointWC.xy);\n\ -vec2 nextWC = normalize(p1.xy - endPointWC.xy);\n\ -float expandWidth = width * 0.5;\n\ -vec2 direction;\n\ -if (czm_equalsEpsilon(previous.xyz - position.xyz, vec3(0.0), czm_epsilon1) || czm_equalsEpsilon(prevWC, -nextWC, czm_epsilon1))\n\ -{\n\ -direction = vec2(-nextWC.y, nextWC.x);\n\ -}\n\ -else if (czm_equalsEpsilon(next.xyz - position.xyz, vec3(0.0), czm_epsilon1) || clipped)\n\ -{\n\ -direction = vec2(prevWC.y, -prevWC.x);\n\ -}\n\ -else\n\ -{\n\ -vec2 normal = vec2(-nextWC.y, nextWC.x);\n\ -direction = normalize((nextWC + prevWC) * 0.5);\n\ -if (dot(direction, normal) < 0.0)\n\ -{\n\ -direction = -direction;\n\ -}\n\ -float sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x);\n\ -expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);\n\ -}\n\ -vec2 offset = direction * expandDirection * expandWidth * czm_resolutionScale;\n\ -return vec4(endPointWC.xy + offset, -endPointWC.z, 1.0);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PolylineFS',[],function() { - 'use strict'; - return "varying vec2 v_st;\n\ -void main()\n\ -{\n\ -czm_materialInput materialInput;\n\ -materialInput.s = v_st.s;\n\ -materialInput.st = v_st;\n\ -materialInput.str = vec3(v_st, 0.0);\n\ -czm_material material = czm_getMaterial(materialInput);\n\ -gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PolylineVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 position2DHigh;\n\ -attribute vec3 position2DLow;\n\ -attribute vec3 prevPosition3DHigh;\n\ -attribute vec3 prevPosition3DLow;\n\ -attribute vec3 prevPosition2DHigh;\n\ -attribute vec3 prevPosition2DLow;\n\ -attribute vec3 nextPosition3DHigh;\n\ -attribute vec3 nextPosition3DLow;\n\ -attribute vec3 nextPosition2DHigh;\n\ -attribute vec3 nextPosition2DLow;\n\ -attribute vec4 texCoordExpandAndBatchIndex;\n\ -varying vec2 v_st;\n\ -varying float v_width;\n\ -varying vec4 czm_pickColor;\n\ -varying float v_polylineAngle;\n\ -void main()\n\ -{\n\ -float texCoord = texCoordExpandAndBatchIndex.x;\n\ -float expandDir = texCoordExpandAndBatchIndex.y;\n\ -bool usePrev = texCoordExpandAndBatchIndex.z < 0.0;\n\ -float batchTableIndex = texCoordExpandAndBatchIndex.w;\n\ -vec2 widthAndShow = batchTable_getWidthAndShow(batchTableIndex);\n\ -float width = widthAndShow.x + 0.5;\n\ -float show = widthAndShow.y;\n\ -if (width < 1.0)\n\ -{\n\ -show = 0.0;\n\ -}\n\ -vec4 pickColor = batchTable_getPickColor(batchTableIndex);\n\ -vec4 p, prev, next;\n\ -if (czm_morphTime == 1.0)\n\ -{\n\ -p = czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz);\n\ -prev = czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz);\n\ -next = czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz);\n\ -}\n\ -else if (czm_morphTime == 0.0)\n\ -{\n\ -p = czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy);\n\ -prev = czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy);\n\ -next = czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy);\n\ -}\n\ -else\n\ -{\n\ -p = czm_columbusViewMorph(\n\ -czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy),\n\ -czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz),\n\ -czm_morphTime);\n\ -prev = czm_columbusViewMorph(\n\ -czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy),\n\ -czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz),\n\ -czm_morphTime);\n\ -next = czm_columbusViewMorph(\n\ -czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy),\n\ -czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz),\n\ -czm_morphTime);\n\ -}\n\ -#ifdef DISTANCE_DISPLAY_CONDITION\n\ -vec3 centerHigh = batchTable_getCenterHigh(batchTableIndex);\n\ -vec4 centerLowAndRadius = batchTable_getCenterLowAndRadius(batchTableIndex);\n\ -vec3 centerLow = centerLowAndRadius.xyz;\n\ -float radius = centerLowAndRadius.w;\n\ -vec2 distanceDisplayCondition = batchTable_getDistanceDisplayCondition(batchTableIndex);\n\ -float lengthSq;\n\ -if (czm_sceneMode == czm_sceneMode2D)\n\ -{\n\ -lengthSq = czm_eyeHeight2D.y;\n\ -}\n\ -else\n\ -{\n\ -vec4 center = czm_translateRelativeToEye(centerHigh.xyz, centerLow.xyz);\n\ -lengthSq = max(0.0, dot(center.xyz, center.xyz) - radius * radius);\n\ -}\n\ -float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x;\n\ -float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y;\n\ -if (lengthSq < nearSq || lengthSq > farSq)\n\ -{\n\ -show = 0.0;\n\ -}\n\ -#endif\n\ -vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\n\ -gl_Position = czm_viewportOrthographic * positionWC * show;\n\ -v_st = vec2(texCoord, clamp(expandDir, 0.0, 1.0));\n\ -v_width = width;\n\ -czm_pickColor = pickColor;\n\ -}\n\ -"; -}); -define('Scene/Polyline',[ - '../Core/arrayRemoveDuplicates', - '../Core/BoundingSphere', - '../Core/Cartesian3', - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/Matrix4', - '../Core/PolylinePipeline', - './Material' - ], function( - arrayRemoveDuplicates, - BoundingSphere, - Cartesian3, - Color, - defaultValue, - defined, - defineProperties, - DeveloperError, - DistanceDisplayCondition, - Matrix4, - PolylinePipeline, - Material) { - 'use strict'; + lastIndex = currentResult.index + tagText.length; + } - /** - * A renderable polyline. Create this by calling {@link PolylineCollection#add} - * - * @alias Polyline - * @internalConstructor - * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] <code>true</code> if this polyline will be shown; otherwise, <code>false</code>. - * @param {Number} [options.width=1.0] The width of the polyline in pixels. - * @param {Boolean} [options.loop=false] Whether a line segment will be added between the last and first line positions to make this line a loop. - * @param {Material} [options.material=Material.ColorType] The material. - * @param {Cartesian3[]} [options.positions] The positions. - * @param {Object} [options.id] The user-defined object to be returned when this polyline is picked. - * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this polyline will be displayed. - * @param {PolylineCollection} polylineCollection The renderable polyline collection. - * - * @see PolylineCollection - * - */ - function Polyline(options, polylineCollection) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + // Process any remaining text after the last HTML element. Will process all of the text if there were no HTML elements. + if( lastIndex < html.length ) { + var text = html.substring( lastIndex ); - this._show = defaultValue(options.show, true); - this._width = defaultValue(options.width, 1.0); - this._loop = defaultValue(options.loop, false); - this._distanceDisplayCondition = options.distanceDisplayCondition; + // Push TextNodes and EntityNodes for any text found between tags + if( text ) { + textAndEntityNodes = this.parseTextAndEntityNodes( text ); + nodes.push.apply( nodes, textAndEntityNodes ); + } + } - this._material = options.material; - if (!defined(this._material)) { - this._material = Material.fromType(Material.ColorType, { - color : new Color(1.0, 1.0, 1.0, 1.0) - }); - } + return nodes; + }, - var positions = options.positions; - if (!defined(positions)) { - positions = []; - } - this._positions = positions; - this._actualPositions = arrayRemoveDuplicates(positions, Cartesian3.equalsEpsilon); + /** + * Parses text and HTML entity nodes from a given string. The input string + * should not have any HTML tags (elements) within it. + * + * @private + * @param {String} text The text to parse. + * @return {Autolinker.htmlParser.HtmlNode[]} An array of HtmlNodes to + * represent the {@link Autolinker.htmlParser.TextNode TextNodes} and + * {@link Autolinker.htmlParser.EntityNode EntityNodes} found. + */ + parseTextAndEntityNodes : function( text ) { + var nodes = [], + textAndEntityTokens = Autolinker.Util.splitAndCapture( text, this.htmlCharacterEntitiesRegex ); // split at HTML entities, but include the HTML entities in the results array - if (this._loop && this._actualPositions.length > 2) { - if (this._actualPositions === this._positions) { - this._actualPositions = positions.slice(); - } - this._actualPositions.push(Cartesian3.clone(this._actualPositions[0])); - } + // Every even numbered token is a TextNode, and every odd numbered token is an EntityNode + // For example: an input `text` of "Test "this" today" would turn into the + // `textAndEntityTokens`: [ 'Test ', '"', 'this', '"', ' today' ] + for( var i = 0, len = textAndEntityTokens.length; i < len; i += 2 ) { + var textToken = textAndEntityTokens[ i ], + entityToken = textAndEntityTokens[ i + 1 ]; - this._length = this._actualPositions.length; - this._id = options.id; + if( textToken ) nodes.push( this.createTextNode( textToken ) ); + if( entityToken ) nodes.push( this.createEntityNode( entityToken ) ); + } + return nodes; + }, - var modelMatrix; - if (defined(polylineCollection)) { - modelMatrix = Matrix4.clone(polylineCollection.modelMatrix); - } - this._modelMatrix = modelMatrix; - this._segments = PolylinePipeline.wrapLongitude(this._actualPositions, modelMatrix); + /** + * Factory method to create an {@link Autolinker.htmlParser.CommentNode CommentNode}. + * + * @private + * @param {String} tagText The full text of the tag (comment) that was + * matched, including its <!-- and -->. + * @param {String} comment The full text of the comment that was matched. + */ + createCommentNode : function( tagText, commentText ) { + return new Autolinker.htmlParser.CommentNode( { + text: tagText, + comment: Autolinker.Util.trim( commentText ) + } ); + }, - this._actualLength = undefined; - this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); //eslint-disable-line no-use-before-define - this._polylineCollection = polylineCollection; - this._dirty = false; - this._pickId = undefined; - this._boundingVolume = BoundingSphere.fromPoints(this._actualPositions); - this._boundingVolumeWC = BoundingSphere.transform(this._boundingVolume, this._modelMatrix); - this._boundingVolume2D = new BoundingSphere(); // modified in PolylineCollection - } + /** + * Factory method to create an {@link Autolinker.htmlParser.ElementNode ElementNode}. + * + * @private + * @param {String} tagText The full text of the tag (element) that was + * matched, including its attributes. + * @param {String} tagName The name of the tag. Ex: An <img> tag would + * be passed to this method as "img". + * @param {Boolean} isClosingTag `true` if it's a closing tag, false + * otherwise. + * @return {Autolinker.htmlParser.ElementNode} + */ + createElementNode : function( tagText, tagName, isClosingTag ) { + return new Autolinker.htmlParser.ElementNode( { + text : tagText, + tagName : tagName.toLowerCase(), + closing : isClosingTag + } ); + }, - var POSITION_INDEX = Polyline.POSITION_INDEX = 0; - var SHOW_INDEX = Polyline.SHOW_INDEX = 1; - var WIDTH_INDEX = Polyline.WIDTH_INDEX = 2; - var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 3; - var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 4; - var DISTANCE_DISPLAY_CONDITION = Polyline.DISTANCE_DISPLAY_CONDITION = 5; - var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 6; - function makeDirty(polyline, propertyChanged) { - ++polyline._propertiesChanged[propertyChanged]; - var polylineCollection = polyline._polylineCollection; - if (defined(polylineCollection)) { - polylineCollection._updatePolyline(polyline, propertyChanged); - polyline._dirty = true; - } - } + /** + * Factory method to create a {@link Autolinker.htmlParser.EntityNode EntityNode}. + * + * @private + * @param {String} text The text that was matched for the HTML entity (such + * as '&nbsp;'). + * @return {Autolinker.htmlParser.EntityNode} + */ + createEntityNode : function( text ) { + return new Autolinker.htmlParser.EntityNode( { text: text } ); + }, - defineProperties(Polyline.prototype, { - /** - * Determines if this polyline will be shown. Use this to hide or show a polyline, instead - * of removing it and re-adding it to the collection. - * @memberof Polyline.prototype - * @type {Boolean} - */ - show: { - get: function() { - return this._show; - }, - set: function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (value !== this._show) { - this._show = value; - makeDirty(this, SHOW_INDEX); - } - } - }, + /** + * Factory method to create a {@link Autolinker.htmlParser.TextNode TextNode}. + * + * @private + * @param {String} text The text that was matched. + * @return {Autolinker.htmlParser.TextNode} + */ + createTextNode : function( text ) { + return new Autolinker.htmlParser.TextNode( { text: text } ); + } - /** - * Gets or sets the positions of the polyline. - * @memberof Polyline.prototype - * @type {Cartesian3[]} - * @example - * polyline.positions = Cesium.Cartesian3.fromDegreesArray([ - * 0.0, 0.0, - * 10.0, 0.0, - * 0.0, 20.0 - * ]); - */ - positions : { - get: function() { - return this._positions; - }, - set: function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var positions = arrayRemoveDuplicates(value, Cartesian3.equalsEpsilon); +} ); +/*global Autolinker */ +/** + * @abstract + * @class Autolinker.htmlParser.HtmlNode + * + * Represents an HTML node found in an input string. An HTML node is one of the following: + * + * 1. An {@link Autolinker.htmlParser.ElementNode ElementNode}, which represents HTML tags. + * 2. A {@link Autolinker.htmlParser.TextNode TextNode}, which represents text outside or within HTML tags. + * 3. A {@link Autolinker.htmlParser.EntityNode EntityNode}, which represents one of the known HTML + * entities that Autolinker looks for. This includes common ones such as &quot; and &nbsp; + */ +Autolinker.htmlParser.HtmlNode = Autolinker.Util.extend( Object, { + + /** + * @cfg {String} text (required) + * + * The original text that was matched for the HtmlNode. + * + * - In the case of an {@link Autolinker.htmlParser.ElementNode ElementNode}, this will be the tag's + * text. + * - In the case of a {@link Autolinker.htmlParser.TextNode TextNode}, this will be the text itself. + * - In the case of a {@link Autolinker.htmlParser.EntityNode EntityNode}, this will be the text of + * the HTML entity. + */ + text : "", + + + /** + * @constructor + * @param {Object} cfg The configuration properties for the Match instance, specified in an Object (map). + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + }, - if (this._loop && positions.length > 2) { - if (positions === value) { - positions = value.slice(); - } - positions.push(Cartesian3.clone(positions[0])); - } + + /** + * Returns a string name for the type of node that this class represents. + * + * @abstract + * @return {String} + */ + getType : Autolinker.Util.abstractMethod, + + + /** + * Retrieves the {@link #text} for the HtmlNode. + * + * @return {String} + */ + getText : function() { + return this.text; + } - if (this._actualPositions.length !== positions.length || this._actualPositions.length !== this._length) { - makeDirty(this, POSITION_SIZE_INDEX); - } +} ); +/*global Autolinker */ +/** + * @class Autolinker.htmlParser.CommentNode + * @extends Autolinker.htmlParser.HtmlNode + * + * Represents an HTML comment node that has been parsed by the + * {@link Autolinker.htmlParser.HtmlParser}. + * + * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more + * details. + */ +Autolinker.htmlParser.CommentNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { - this._positions = value; - this._actualPositions = positions; - this._length = positions.length; - this._boundingVolume = BoundingSphere.fromPoints(this._actualPositions, this._boundingVolume); - this._boundingVolumeWC = BoundingSphere.transform(this._boundingVolume, this._modelMatrix, this._boundingVolumeWC); - makeDirty(this, POSITION_INDEX); + /** + * @cfg {String} comment (required) + * + * The text inside the comment tag. This text is stripped of any leading or + * trailing whitespace. + */ + comment : '', - this.update(); - } - }, - /** - * Gets or sets the surface appearance of the polyline. This can be one of several built-in {@link Material} objects or a custom material, scripted with - * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}. - * @memberof Polyline.prototype - * @type {Material} - */ - material: { - get: function() { - return this._material; - }, - set: function(material) { - if (!defined(material)) { - throw new DeveloperError('material is required.'); - } - - if (this._material !== material) { - this._material = material; - makeDirty(this, MATERIAL_INDEX); - } - } - }, + /** + * Returns a string name for the type of node that this class represents. + * + * @return {String} + */ + getType : function() { + return 'comment'; + }, - /** - * Gets or sets the width of the polyline. - * @memberof Polyline.prototype - * @type {Number} - */ - width: { - get: function() { - return this._width; - }, - set: function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - var width = this._width; - if (value !== width) { - this._width = value; - makeDirty(this, WIDTH_INDEX); - } - } - }, - /** - * Gets or sets whether a line segment will be added between the first and last polyline positions. - * @memberof Polyline.prototype - * @type {Boolean} - */ - loop: { - get: function() { - return this._loop; - }, - set: function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (value !== this._loop) { - var positions = this._actualPositions; - if (value) { - if (positions.length > 2 && !Cartesian3.equals(positions[0], positions[positions.length - 1])) { - if (positions.length === this._positions.length) { - this._actualPositions = positions = this._positions.slice(); - } - positions.push(Cartesian3.clone(positions[0])); - } - } else if (positions.length > 2 && Cartesian3.equals(positions[0], positions[positions.length - 1])) { - if (positions.length - 1 === this._positions.length) { - this._actualPositions = this._positions; - } else { - positions.pop(); - } - } + /** + * Returns the comment inside the comment tag. + * + * @return {String} + */ + getComment : function() { + return this.comment; + } - this._loop = value; - makeDirty(this, POSITION_SIZE_INDEX); - } - } - }, +} ); +/*global Autolinker */ +/** + * @class Autolinker.htmlParser.ElementNode + * @extends Autolinker.htmlParser.HtmlNode + * + * Represents an HTML element node that has been parsed by the {@link Autolinker.htmlParser.HtmlParser}. + * + * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more details. + */ +Autolinker.htmlParser.ElementNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { + + /** + * @cfg {String} tagName (required) + * + * The name of the tag that was matched. + */ + tagName : '', + + /** + * @cfg {Boolean} closing (required) + * + * `true` if the element (tag) is a closing tag, `false` if its an opening tag. + */ + closing : false, - /** - * Gets or sets the user-defined object returned when the polyline is picked. - * @memberof Polyline.prototype - * @type {Object} - */ - id : { - get : function() { - return this._id; - }, - set : function(value) { - this._id = value; - if (defined(this._pickId)) { - this._pickId.object.id = value; - } - } - }, + + /** + * Returns a string name for the type of node that this class represents. + * + * @return {String} + */ + getType : function() { + return 'element'; + }, + - /** - * Gets or sets the condition specifying at what distance from the camera that this polyline will be displayed. - * @memberof Polyline.prototype - * @type {DistanceDisplayCondition} - * @default undefined - */ - distanceDisplayCondition : { - get : function() { - return this._distanceDisplayCondition; - }, - set : function(value) { - if (defined(value) && value.far <= value.near) { - throw new DeveloperError('far distance must be greater than near distance.'); - } - if (!DistanceDisplayCondition.equals(value, this._distanceDisplayCondition)) { - this._distanceDisplayCondition = DistanceDisplayCondition.clone(value, this._distanceDisplayCondition); - makeDirty(this, DISTANCE_DISPLAY_CONDITION); - } - } - } - }); + /** + * Returns the HTML element's (tag's) name. Ex: for an <img> tag, returns "img". + * + * @return {String} + */ + getTagName : function() { + return this.tagName; + }, + + + /** + * Determines if the HTML element (tag) is a closing tag. Ex: <div> returns + * `false`, while </div> returns `true`. + * + * @return {Boolean} + */ + isClosing : function() { + return this.closing; + } + +} ); +/*global Autolinker */ +/** + * @class Autolinker.htmlParser.EntityNode + * @extends Autolinker.htmlParser.HtmlNode + * + * Represents a known HTML entity node that has been parsed by the {@link Autolinker.htmlParser.HtmlParser}. + * Ex: '&nbsp;', or '&#160;' (which will be retrievable from the {@link #getText} method. + * + * Note that this class will only be returned from the HtmlParser for the set of checked HTML entity nodes + * defined by the {@link Autolinker.htmlParser.HtmlParser#htmlCharacterEntitiesRegex}. + * + * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more details. + */ +Autolinker.htmlParser.EntityNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { + + /** + * Returns a string name for the type of node that this class represents. + * + * @return {String} + */ + getType : function() { + return 'entity'; + } + +} ); +/*global Autolinker */ +/** + * @class Autolinker.htmlParser.TextNode + * @extends Autolinker.htmlParser.HtmlNode + * + * Represents a text node that has been parsed by the {@link Autolinker.htmlParser.HtmlParser}. + * + * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more details. + */ +Autolinker.htmlParser.TextNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { + + /** + * Returns a string name for the type of node that this class represents. + * + * @return {String} + */ + getType : function() { + return 'text'; + } + +} ); +/*global Autolinker */ +/** + * @private + * @class Autolinker.matchParser.MatchParser + * @extends Object + * + * Used by Autolinker to parse potential matches, given an input string of text. + * + * The MatchParser is fed a non-HTML string in order to search for matches. + * Autolinker first uses the {@link Autolinker.htmlParser.HtmlParser} to "walk + * around" HTML tags, and then the text around the HTML tags is passed into the + * MatchParser in order to find the actual matches. + */ +Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, { - /** - * @private - */ - Polyline.prototype.update = function() { - var modelMatrix = Matrix4.IDENTITY; - if (defined(this._polylineCollection)) { - modelMatrix = this._polylineCollection.modelMatrix; - } + /** + * @cfg {Boolean} urls + * @inheritdoc Autolinker#urls + */ + urls : true, - var segmentPositionsLength = this._segments.positions.length; - var segmentLengths = this._segments.lengths; + /** + * @cfg {Boolean} email + * @inheritdoc Autolinker#email + */ + email : true, - var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; - if (!Matrix4.equals(modelMatrix, this._modelMatrix) || positionsChanged) { - this._segments = PolylinePipeline.wrapLongitude(this._actualPositions, modelMatrix); - this._boundingVolumeWC = BoundingSphere.transform(this._boundingVolume, modelMatrix, this._boundingVolumeWC); - } + /** + * @cfg {Boolean} twitter + * @inheritdoc Autolinker#twitter + */ + twitter : true, - this._modelMatrix = Matrix4.clone(modelMatrix, this._modelMatrix); + /** + * @cfg {Boolean} phone + * @inheritdoc Autolinker#phone + */ + phone: true, - if (this._segments.positions.length !== segmentPositionsLength) { - // number of positions changed - makeDirty(this, POSITION_SIZE_INDEX); - } else { - var length = segmentLengths.length; - for (var i = 0; i < length; ++i) { - if (segmentLengths[i] !== this._segments.lengths[i]) { - // indices changed - makeDirty(this, POSITION_SIZE_INDEX); - break; - } - } - } - }; + /** + * @cfg {Boolean/String} hashtag + * @inheritdoc Autolinker#hashtag + */ + hashtag : false, - /** - * @private - */ - Polyline.prototype.getPickId = function(context) { - if (!defined(this._pickId)) { - this._pickId = context.createPickId({ - primitive : this, - collection : this._polylineCollection, - id : this._id - }); - } - return this._pickId; - }; + /** + * @cfg {Boolean} stripPrefix + * @inheritdoc Autolinker#stripPrefix + */ + stripPrefix : true, - Polyline.prototype._clean = function() { - this._dirty = false; - var properties = this._propertiesChanged; - for ( var k = 0; k < NUMBER_OF_PROPERTIES - 1; ++k) { - properties[k] = 0; - } - }; - Polyline.prototype._destroy = function() { - this._pickId = this._pickId && this._pickId.destroy(); - this._material = this._material && this._material.destroy(); - this._polylineCollection = undefined; - }; + /** + * @private + * @property {RegExp} matcherRegex + * + * The regular expression that matches URLs, email addresses, phone #s, + * Twitter handles, and Hashtags. + * + * This regular expression has the following capturing groups: + * + * 1. Group that is used to determine if there is a Twitter handle match + * (i.e. \@someTwitterUser). Simply check for its existence to determine + * if there is a Twitter handle match. The next couple of capturing + * groups give information about the Twitter handle match. + * 2. The whitespace character before the \@sign in a Twitter handle. This + * is needed because there are no lookbehinds in JS regular expressions, + * and can be used to reconstruct the original string in a replace(). + * 3. The Twitter handle itself in a Twitter match. If the match is + * '@someTwitterUser', the handle is 'someTwitterUser'. + * 4. Group that matches an email address. Used to determine if the match + * is an email address, as well as holding the full address. Ex: + * 'me@my.com' + * 5. Group that matches a URL in the input text. Ex: 'http://google.com', + * 'www.google.com', or just 'google.com'. This also includes a path, + * url parameters, or hash anchors. Ex: google.com/path/to/file?q1=1&q2=2#myAnchor + * 6. Group that matches a protocol URL (i.e. 'http://google.com'). This is + * used to match protocol URLs with just a single word, like 'http://localhost', + * where we won't double check that the domain name has at least one '.' + * in it. + * 7. A protocol-relative ('//') match for the case of a 'www.' prefixed + * URL. Will be an empty string if it is not a protocol-relative match. + * We need to know the character before the '//' in order to determine + * if it is a valid match or the // was in a string we don't want to + * auto-link. + * 8. A protocol-relative ('//') match for the case of a known TLD prefixed + * URL. Will be an empty string if it is not a protocol-relative match. + * See #6 for more info. + * 9. Group that is used to determine if there is a phone number match. The + * next 3 groups give segments of the phone number. + * 10. Group that is used to determine if there is a Hashtag match + * (i.e. \#someHashtag). Simply check for its existence to determine if + * there is a Hashtag match. The next couple of capturing groups give + * information about the Hashtag match. + * 11. The whitespace character before the #sign in a Hashtag handle. This + * is needed because there are no look-behinds in JS regular + * expressions, and can be used to reconstruct the original string in a + * replace(). + * 12. The Hashtag itself in a Hashtag match. If the match is + * '#someHashtag', the hashtag is 'someHashtag'. + */ + matcherRegex : (function() { + var twitterRegex = /(^|[^\w])@(\w{1,15})/, // For matching a twitter handle. Ex: @gregory_jacobs - return Polyline; -}); + hashtagRegex = /(^|[^\w])#(\w{1,15})/, // For matching a Hashtag. Ex: #games -define('Scene/PolylineCollection',[ - '../Core/BoundingSphere', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', - '../Core/Color', - '../Core/ComponentDatatype', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/EncodedCartesian3', - '../Core/IndexDatatype', - '../Core/Intersect', - '../Core/Math', - '../Core/Matrix4', - '../Core/Plane', - '../Core/RuntimeError', - '../Renderer/Buffer', - '../Renderer/BufferUsage', - '../Renderer/ContextLimits', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/Texture', - '../Renderer/VertexArray', - '../Shaders/PolylineCommon', - '../Shaders/PolylineFS', - '../Shaders/PolylineVS', - './BatchTable', - './BlendingState', - './Material', - './Polyline', - './SceneMode' - ], function( - BoundingSphere, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - Color, - ComponentDatatype, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - EncodedCartesian3, - IndexDatatype, - Intersect, - CesiumMath, - Matrix4, - Plane, - RuntimeError, - Buffer, - BufferUsage, - ContextLimits, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - Texture, - VertexArray, - PolylineCommon, - PolylineFS, - PolylineVS, - BatchTable, - BlendingState, - Material, - Polyline, - SceneMode) { - 'use strict'; + emailRegex = /(?:[\-;:&=\+\$,\w\.]+@)/, // something@ for email addresses (a.k.a. local-part) + phoneRegex = /(?:\+?\d{1,3}[-\s.])?\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/, // ex: (123) 456-7890, 123 456 7890, 123-456-7890, etc. + protocolRegex = /(?:[A-Za-z][-.+A-Za-z0-9]+:(?![A-Za-z][-.+A-Za-z0-9]+:\/\/)(?!\d+\/?)(?:\/\/)?)/, // match protocol, allow in format "http://" or "mailto:". However, do not match the first part of something like 'link:http://www.google.com' (i.e. don't match "link:"). Also, make sure we don't interpret 'google.com:8000' as if 'google.com' was a protocol here (i.e. ignore a trailing port number in this regex) + wwwRegex = /(?:www\.)/, // starting with 'www.' + domainNameRegex = /[A-Za-z0-9\.\-]*[A-Za-z0-9\-]/, // anything looking at all like a domain, non-unicode domains, not ending in a period + tldRegex = /\.(?:international|construction|contractors|enterprises|photography|productions|foundation|immobilien|industries|management|properties|technology|christmas|community|directory|education|equipment|institute|marketing|solutions|vacations|bargains|boutique|builders|catering|cleaning|clothing|computer|democrat|diamonds|graphics|holdings|lighting|partners|plumbing|supplies|training|ventures|academy|careers|company|cruises|domains|exposed|flights|florist|gallery|guitars|holiday|kitchen|neustar|okinawa|recipes|rentals|reviews|shiksha|singles|support|systems|agency|berlin|camera|center|coffee|condos|dating|estate|events|expert|futbol|kaufen|luxury|maison|monash|museum|nagoya|photos|repair|report|social|supply|tattoo|tienda|travel|viajes|villas|vision|voting|voyage|actor|build|cards|cheap|codes|dance|email|glass|house|mango|ninja|parts|photo|shoes|solar|today|tokyo|tools|watch|works|aero|arpa|asia|best|bike|blue|buzz|camp|club|cool|coop|farm|fish|gift|guru|info|jobs|kiwi|kred|land|limo|link|menu|mobi|moda|name|pics|pink|post|qpon|rich|ruhr|sexy|tips|vote|voto|wang|wien|wiki|zone|bar|bid|biz|cab|cat|ceo|com|edu|gov|int|kim|mil|net|onl|org|pro|pub|red|tel|uno|wed|xxx|xyz|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/, // match our known top level domains (TLDs) - var SHOW_INDEX = Polyline.SHOW_INDEX; - var WIDTH_INDEX = Polyline.WIDTH_INDEX; - var POSITION_INDEX = Polyline.POSITION_INDEX; - var MATERIAL_INDEX = Polyline.MATERIAL_INDEX; - //POSITION_SIZE_INDEX is needed for when the polyline's position array changes size. - //When it does, we need to recreate the indicesBuffer. - var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX; - var DISTANCE_DISPLAY_CONDITION = Polyline.DISTANCE_DISPLAY_CONDITION; - var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES; + // Allow optional path, query string, and hash anchor, not ending in the following characters: "?!:,.;" + // http://blog.codinghorror.com/the-problem-with-urls/ + urlSuffixRegex = /[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]?!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]]/; - var attributeLocations = { - texCoordExpandAndBatchIndex : 0, - position3DHigh : 1, - position3DLow : 2, - position2DHigh : 3, - position2DLow : 4, - prevPosition3DHigh : 5, - prevPosition3DLow : 6, - prevPosition2DHigh : 7, - prevPosition2DLow : 8, - nextPosition3DHigh : 9, - nextPosition3DLow : 10, - nextPosition2DHigh : 11, - nextPosition2DLow : 12 - }; + return new RegExp( [ + '(', // *** Capturing group $1, which can be used to check for a twitter handle match. Use group $3 for the actual twitter handle though. $2 may be used to reconstruct the original string in a replace() + // *** Capturing group $2, which matches the whitespace character before the '@' sign (needed because of no lookbehinds), and + // *** Capturing group $3, which matches the actual twitter handle + twitterRegex.source, + ')', - /** - * A renderable collection of polylines. - * <br /><br /> - * <div align="center"> - * <img src="Images/Polyline.png" width="400" height="300" /><br /> - * Example polylines - * </div> - * <br /><br /> - * Polylines are added and removed from the collection using {@link PolylineCollection#add} - * and {@link PolylineCollection#remove}. - * - * @alias PolylineCollection - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each polyline from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * - * @performance For best performance, prefer a few collections, each with many polylines, to - * many collections with only a few polylines each. Organize collections so that polylines - * with the same update frequency are in the same collection, i.e., polylines that do not - * change should be in one collection; polylines that change every frame should be in another - * collection; and so on. - * - * @see PolylineCollection#add - * @see PolylineCollection#remove - * @see Polyline - * @see LabelCollection - * - * @example - * // Create a polyline collection with two polylines - * var polylines = new Cesium.PolylineCollection(); - * polylines.add({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * -75.10, 39.57, - * -77.02, 38.53, - * -80.50, 35.14, - * -80.12, 25.46]), - * width : 2 - * }); - * - * polylines.add({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * -73.10, 37.57, - * -75.02, 36.53, - * -78.50, 33.14, - * -78.12, 23.46]), - * width : 4 - * }); - */ - function PolylineCollection(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + '|', - /** - * The 4x4 transformation matrix that transforms each polyline in this collection from model to world coordinates. - * When this is the identity matrix, the polylines are drawn in world coordinates, i.e., Earth's WGS84 coordinates. - * Local reference frames can be used by providing a different transformation matrix, like that returned - * by {@link Transforms.eastNorthUpToFixedFrame}. - * - * @type {Matrix4} - * @default {@link Matrix4.IDENTITY} - */ - this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + '(', // *** Capturing group $4, which is used to determine an email match + emailRegex.source, + domainNameRegex.source, + tldRegex.source, + ')', - /** - * This property is for debugging only; it is not for production use nor is it optimized. - * <p> - * Draws the bounding sphere for each draw command in the primitive. - * </p> - * - * @type {Boolean} - * - * @default false - */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + '|', - this._opaqueRS = undefined; - this._translucentRS = undefined; + '(', // *** Capturing group $5, which is used to match a URL + '(?:', // parens to cover match for protocol (optional), and domain + '(', // *** Capturing group $6, for a protocol-prefixed url (ex: http://google.com) + protocolRegex.source, + domainNameRegex.source, + ')', - this._colorCommands = []; - this._pickCommands = []; + '|', - this._polylinesUpdated = false; - this._polylinesRemoved = false; - this._createVertexArray = false; - this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); - this._polylines = []; - this._polylineBuckets = {}; + '(?:', // non-capturing paren for a 'www.' prefixed url (ex: www.google.com) + '(.?//)?', // *** Capturing group $7 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character + wwwRegex.source, + domainNameRegex.source, + ')', + + '|', + + '(?:', // non-capturing paren for known a TLD url (ex: google.com) + '(.?//)?', // *** Capturing group $8 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character + domainNameRegex.source, + tldRegex.source, + ')', + ')', + + '(?:' + urlSuffixRegex.source + ')?', // match for path, query string, and/or hash anchor - optional + ')', + + '|', + + // this setup does not scale well for open extension :( Need to rethink design of autolinker... + // *** Capturing group $9, which matches a (USA for now) phone number + '(', + phoneRegex.source, + ')', + + '|', + + '(', // *** Capturing group $10, which can be used to check for a Hashtag match. Use group $12 for the actual Hashtag though. $11 may be used to reconstruct the original string in a replace() + // *** Capturing group $11, which matches the whitespace character before the '#' sign (needed because of no lookbehinds), and + // *** Capturing group $12, which matches the actual Hashtag + hashtagRegex.source, + ')' + ].join( "" ), 'gi' ); + } )(), + + /** + * @private + * @property {RegExp} charBeforeProtocolRelMatchRegex + * + * The regular expression used to retrieve the character before a + * protocol-relative URL match. + * + * This is used in conjunction with the {@link #matcherRegex}, which needs + * to grab the character before a protocol-relative '//' due to the lack of + * a negative look-behind in JavaScript regular expressions. The character + * before the match is stripped from the URL. + */ + charBeforeProtocolRelMatchRegex : /^(.)?\/\//, + + /** + * @private + * @property {Autolinker.MatchValidator} matchValidator + * + * The MatchValidator object, used to filter out any false positives from + * the {@link #matcherRegex}. See {@link Autolinker.MatchValidator} for details. + */ + + + /** + * @constructor + * @param {Object} [cfg] The configuration options for the AnchorTagBuilder + * instance, specified in an Object (map). + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + + this.matchValidator = new Autolinker.MatchValidator(); + }, + + + /** + * Parses the input `text` to search for matches, and calls the `replaceFn` + * to allow replacements of the matches. Returns the `text` with matches + * replaced. + * + * @param {String} text The text to search and repace matches in. + * @param {Function} replaceFn The iterator function to handle the + * replacements. The function takes a single argument, a {@link Autolinker.match.Match} + * object, and should return the text that should make the replacement. + * @param {Object} [contextObj=window] The context object ("scope") to run + * the `replaceFn` in. + * @return {String} + */ + replace : function( text, replaceFn, contextObj ) { + var me = this; // for closure + + return text.replace( this.matcherRegex, function( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 ) { + var matchDescObj = me.processCandidateMatch( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 ); // "match description" object + + // Return out with no changes for match types that are disabled (url, + // email, phone, etc.), or for matches that are invalid (false + // positives from the matcherRegex, which can't use look-behinds + // since they are unavailable in JS). + if( !matchDescObj ) { + return matchStr; + + } else { + // Generate replacement text for the match from the `replaceFn` + var replaceStr = replaceFn.call( contextObj, matchDescObj.match ); + return matchDescObj.prefixStr + replaceStr + matchDescObj.suffixStr; + } + } ); + }, + + + /** + * Processes a candidate match from the {@link #matcherRegex}. + * + * Not all matches found by the regex are actual URL/Email/Phone/Twitter/Hashtag + * matches, as determined by the {@link #matchValidator}. In this case, the + * method returns `null`. Otherwise, a valid Object with `prefixStr`, + * `match`, and `suffixStr` is returned. + * + * @private + * @param {String} matchStr The full match that was found by the + * {@link #matcherRegex}. + * @param {String} twitterMatch The matched text of a Twitter handle, if the + * match is a Twitter match. + * @param {String} twitterHandlePrefixWhitespaceChar The whitespace char + * before the @ sign in a Twitter handle match. This is needed because of + * no lookbehinds in JS regexes, and is need to re-include the character + * for the anchor tag replacement. + * @param {String} twitterHandle The actual Twitter user (i.e the word after + * the @ sign in a Twitter match). + * @param {String} emailAddressMatch The matched email address for an email + * address match. + * @param {String} urlMatch The matched URL string for a URL match. + * @param {String} protocolUrlMatch The match URL string for a protocol + * match. Ex: 'http://yahoo.com'. This is used to match something like + * 'http://localhost', where we won't double check that the domain name + * has at least one '.' in it. + * @param {String} wwwProtocolRelativeMatch The '//' for a protocol-relative + * match from a 'www' url, with the character that comes before the '//'. + * @param {String} tldProtocolRelativeMatch The '//' for a protocol-relative + * match from a TLD (top level domain) match, with the character that + * comes before the '//'. + * @param {String} phoneMatch The matched text of a phone number + * @param {String} hashtagMatch The matched text of a Twitter + * Hashtag, if the match is a Hashtag match. + * @param {String} hashtagPrefixWhitespaceChar The whitespace char + * before the # sign in a Hashtag match. This is needed because of no + * lookbehinds in JS regexes, and is need to re-include the character for + * the anchor tag replacement. + * @param {String} hashtag The actual Hashtag (i.e the word + * after the # sign in a Hashtag match). + * + * @return {Object} A "match description object". This will be `null` if the + * match was invalid, or if a match type is disabled. Otherwise, this will + * be an Object (map) with the following properties: + * @return {String} return.prefixStr The char(s) that should be prepended to + * the replacement string. These are char(s) that were needed to be + * included from the regex match that were ignored by processing code, and + * should be re-inserted into the replacement stream. + * @return {String} return.suffixStr The char(s) that should be appended to + * the replacement string. These are char(s) that were needed to be + * included from the regex match that were ignored by processing code, and + * should be re-inserted into the replacement stream. + * @return {Autolinker.match.Match} return.match The Match object that + * represents the match that was found. + */ + processCandidateMatch : function( + matchStr, twitterMatch, twitterHandlePrefixWhitespaceChar, twitterHandle, + emailAddressMatch, urlMatch, protocolUrlMatch, wwwProtocolRelativeMatch, + tldProtocolRelativeMatch, phoneMatch, hashtagMatch, + hashtagPrefixWhitespaceChar, hashtag + ) { + // Note: The `matchStr` variable wil be fixed up to remove characters that are no longer needed (which will + // be added to `prefixStr` and `suffixStr`). - // The buffer usage is determined based on the usage of the attribute over time. - this._positionBufferUsage = { bufferUsage : BufferUsage.STATIC_DRAW, frameCount : 0 }; + var protocolRelativeMatch = wwwProtocolRelativeMatch || tldProtocolRelativeMatch, + match, // Will be an Autolinker.match.Match object - this._mode = undefined; + prefixStr = "", // A string to use to prefix the anchor tag that is created. This is needed for the Twitter and Hashtag matches. + suffixStr = ""; // A string to suffix the anchor tag that is created. This is used if there is a trailing parenthesis that should not be auto-linked. - this._polylinesToUpdate = []; - this._vertexArrays = []; - this._positionBuffer = undefined; - this._texCoordExpandAndBatchIndexBuffer = undefined; + // Return out with `null` for match types that are disabled (url, email, + // twitter, hashtag), or for matches that are invalid (false positives + // from the matcherRegex, which can't use look-behinds since they are + // unavailable in JS). + if( + ( urlMatch && !this.urls ) || + ( emailAddressMatch && !this.email ) || + ( phoneMatch && !this.phone ) || + ( twitterMatch && !this.twitter ) || + ( hashtagMatch && !this.hashtag ) || + !this.matchValidator.isValidMatch( urlMatch, protocolUrlMatch, protocolRelativeMatch ) + ) { + return null; + } - this._batchTable = undefined; - this._createBatchTable = false; - } + // Handle a closing parenthesis at the end of the match, and exclude it + // if there is not a matching open parenthesis + // in the match itself. + if( this.matchHasUnbalancedClosingParen( matchStr ) ) { + matchStr = matchStr.substr( 0, matchStr.length - 1 ); // remove the trailing ")" + suffixStr = ")"; // this will be added after the generated <a> tag + } - defineProperties(PolylineCollection.prototype, { - /** - * Returns the number of polylines in this collection. This is commonly used with - * {@link PolylineCollection#get} to iterate over all the polylines - * in the collection. - * @memberof PolylineCollection.prototype - * @type {Number} - */ - length : { - get : function() { - removePolylines(this); - return this._polylines.length; - } - } - }); + if( emailAddressMatch ) { + match = new Autolinker.match.Email( { matchedText: matchStr, email: emailAddressMatch } ); - /** - * Creates and adds a polyline with the specified initial properties to the collection. - * The added polyline is returned so it can be modified or removed from the collection later. - * - * @param {Object}[polyline] A template describing the polyline's properties as shown in Example 1. - * @returns {Polyline} The polyline that was added to the collection. - * - * @performance After calling <code>add</code>, {@link PolylineCollection#update} is called and - * the collection's vertex buffer is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. - * For best performance, add as many polylines as possible before calling <code>update</code>. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Example 1: Add a polyline, specifying all the default values. - * var p = polylines.add({ - * show : true, - * positions : ellipsoid.cartographicArrayToCartesianArray([ - Cesium.Cartographic.fromDegrees(-75.10, 39.57), - Cesium.Cartographic.fromDegrees(-77.02, 38.53)]), - * width : 1 - * }); - * - * @see PolylineCollection#remove - * @see PolylineCollection#removeAll - * @see PolylineCollection#update - */ - PolylineCollection.prototype.add = function(polyline) { - var p = new Polyline(polyline, this); - p._index = this._polylines.length; - this._polylines.push(p); - this._createVertexArray = true; - this._createBatchTable = true; - return p; - }; + } else if( twitterMatch ) { + // fix up the `matchStr` if there was a preceding whitespace char, + // which was needed to determine the match itself (since there are + // no look-behinds in JS regexes) + if( twitterHandlePrefixWhitespaceChar ) { + prefixStr = twitterHandlePrefixWhitespaceChar; + matchStr = matchStr.slice( 1 ); // remove the prefixed whitespace char from the match + } + match = new Autolinker.match.Twitter( { matchedText: matchStr, twitterHandle: twitterHandle } ); - /** - * Removes a polyline from the collection. - * - * @param {Polyline} polyline The polyline to remove. - * @returns {Boolean} <code>true</code> if the polyline was removed; <code>false</code> if the polyline was not found in the collection. - * - * @performance After calling <code>remove</code>, {@link PolylineCollection#update} is called and - * the collection's vertex buffer is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. - * For best performance, remove as many polylines as possible before calling <code>update</code>. - * If you intend to temporarily hide a polyline, it is usually more efficient to call - * {@link Polyline#show} instead of removing and re-adding the polyline. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * var p = polylines.add(...); - * polylines.remove(p); // Returns true - * - * @see PolylineCollection#add - * @see PolylineCollection#removeAll - * @see PolylineCollection#update - * @see Polyline#show - */ - PolylineCollection.prototype.remove = function(polyline) { - if (this.contains(polyline)) { - this._polylines[polyline._index] = undefined; // Removed later - this._polylinesRemoved = true; - this._createVertexArray = true; - this._createBatchTable = true; - if (defined(polyline._bucket)) { - var bucket = polyline._bucket; - bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.destroy(); - bucket.pickShaderProgram = bucket.pickShaderProgram && bucket.pickShaderProgram.destroy(); - } - polyline._destroy(); - return true; - } + } else if( phoneMatch ) { + // remove non-numeric values from phone number string + var cleanNumber = matchStr.replace( /\D/g, '' ); + match = new Autolinker.match.Phone( { matchedText: matchStr, number: cleanNumber } ); - return false; - }; + } else if( hashtagMatch ) { + // fix up the `matchStr` if there was a preceding whitespace char, + // which was needed to determine the match itself (since there are + // no look-behinds in JS regexes) + if( hashtagPrefixWhitespaceChar ) { + prefixStr = hashtagPrefixWhitespaceChar; + matchStr = matchStr.slice( 1 ); // remove the prefixed whitespace char from the match + } + match = new Autolinker.match.Hashtag( { matchedText: matchStr, serviceName: this.hashtag, hashtag: hashtag } ); - /** - * Removes all polylines from the collection. - * - * @performance <code>O(n)</code>. It is more efficient to remove all the polylines - * from a collection and then add new ones than to create a new collection entirely. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * polylines.add(...); - * polylines.add(...); - * polylines.removeAll(); - * - * @see PolylineCollection#add - * @see PolylineCollection#remove - * @see PolylineCollection#update - */ - PolylineCollection.prototype.removeAll = function() { - releaseShaders(this); - destroyPolylines(this); - this._polylineBuckets = {}; - this._polylinesRemoved = false; - this._polylines.length = 0; - this._polylinesToUpdate.length = 0; - this._createVertexArray = true; - }; + } else { // url match + // If it's a protocol-relative '//' match, remove the character + // before the '//' (which the matcherRegex needed to match due to + // the lack of a negative look-behind in JavaScript regular + // expressions) + if( protocolRelativeMatch ) { + var charBeforeMatch = protocolRelativeMatch.match( this.charBeforeProtocolRelMatchRegex )[ 1 ] || ""; - /** - * Determines if this collection contains the specified polyline. - * - * @param {Polyline} polyline The polyline to check for. - * @returns {Boolean} true if this collection contains the polyline, false otherwise. - * - * @see PolylineCollection#get - */ - PolylineCollection.prototype.contains = function(polyline) { - return defined(polyline) && polyline._polylineCollection === this; - }; + if( charBeforeMatch ) { // fix up the `matchStr` if there was a preceding char before a protocol-relative match, which was needed to determine the match itself (since there are no look-behinds in JS regexes) + prefixStr = charBeforeMatch; + matchStr = matchStr.slice( 1 ); // remove the prefixed char from the match + } + } - /** - * Returns the polyline in the collection at the specified index. Indices are zero-based - * and increase as polylines are added. Removing a polyline shifts all polylines after - * it to the left, changing their indices. This function is commonly used with - * {@link PolylineCollection#length} to iterate over all the polylines - * in the collection. - * - * @param {Number} index The zero-based index of the polyline. - * @returns {Polyline} The polyline at the specified index. - * - * @performance If polylines were removed from the collection and - * {@link PolylineCollection#update} was not called, an implicit <code>O(n)</code> - * operation is performed. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @example - * // Toggle the show property of every polyline in the collection - * var len = polylines.length; - * for (var i = 0; i < len; ++i) { - * var p = polylines.get(i); - * p.show = !p.show; - * } - * - * @see PolylineCollection#length - */ - PolylineCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - removePolylines(this); - return this._polylines[index]; - }; + match = new Autolinker.match.Url( { + matchedText : matchStr, + url : matchStr, + protocolUrlMatch : !!protocolUrlMatch, + protocolRelativeMatch : !!protocolRelativeMatch, + stripPrefix : this.stripPrefix + } ); + } - function createBatchTable(collection, context) { - if (defined(collection._batchTable)) { - collection._batchTable.destroy(); - } + return { + prefixStr : prefixStr, + suffixStr : suffixStr, + match : match + }; + }, - var attributes = [{ - functionName : 'batchTable_getWidthAndShow', - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - componentsPerAttribute : 2 - }, { - functionName : 'batchTable_getPickColor', - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - componentsPerAttribute : 4, - normalize : true - }, { - functionName : 'batchTable_getCenterHigh', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 3 - }, { - functionName : 'batchTable_getCenterLowAndRadius', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 4 - }, { - functionName : 'batchTable_getDistanceDisplayCondition', - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2 - }]; - collection._batchTable = new BatchTable(context, attributes, collection._polylines.length); - } + /** + * Determines if a match found has an unmatched closing parenthesis. If so, + * this parenthesis will be removed from the match itself, and appended + * after the generated anchor tag in {@link #processCandidateMatch}. + * + * A match may have an extra closing parenthesis at the end of the match + * because the regular expression must include parenthesis for URLs such as + * "wikipedia.com/something_(disambiguation)", which should be auto-linked. + * + * However, an extra parenthesis *will* be included when the URL itself is + * wrapped in parenthesis, such as in the case of "(wikipedia.com/something_(disambiguation))". + * In this case, the last closing parenthesis should *not* be part of the + * URL itself, and this method will return `true`. + * + * @private + * @param {String} matchStr The full match string from the {@link #matcherRegex}. + * @return {Boolean} `true` if there is an unbalanced closing parenthesis at + * the end of the `matchStr`, `false` otherwise. + */ + matchHasUnbalancedClosingParen : function( matchStr ) { + var lastChar = matchStr.charAt( matchStr.length - 1 ); - var scratchUpdatePolylineEncodedCartesian = new EncodedCartesian3(); - var scratchUpdatePolylineCartesian4 = new Cartesian4(); - var scratchNearFarCartesian2 = new Cartesian2(); + if( lastChar === ')' ) { + var openParensMatch = matchStr.match( /\(/g ), + closeParensMatch = matchStr.match( /\)/g ), + numOpenParens = ( openParensMatch && openParensMatch.length ) || 0, + numCloseParens = ( closeParensMatch && closeParensMatch.length ) || 0; - /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> - * - * @exception {RuntimeError} Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero. - */ - PolylineCollection.prototype.update = function(frameState) { - removePolylines(this); + if( numOpenParens < numCloseParens ) { + return true; + } + } - if (this._polylines.length === 0) { - return; - } + return false; + } - updateMode(this, frameState); +} ); +/*global Autolinker */ +/*jshint scripturl:true */ +/** + * @private + * @class Autolinker.MatchValidator + * @extends Object + * + * Used by Autolinker to filter out false positives from the + * {@link Autolinker.matchParser.MatchParser#matcherRegex}. + * + * Due to the limitations of regular expressions (including the missing feature + * of look-behinds in JS regular expressions), we cannot always determine the + * validity of a given match. This class applies a bit of additional logic to + * filter out any false positives that have been matched by the + * {@link Autolinker.matchParser.MatchParser#matcherRegex}. + */ +Autolinker.MatchValidator = Autolinker.Util.extend( Object, { - var context = frameState.context; - var projection = frameState.mapProjection; - var polyline; - var properties = this._propertiesChanged; + /** + * @private + * @property {RegExp} invalidProtocolRelMatchRegex + * + * The regular expression used to check a potential protocol-relative URL + * match, coming from the {@link Autolinker.matchParser.MatchParser#matcherRegex}. + * A protocol-relative URL is, for example, "//yahoo.com" + * + * This regular expression checks to see if there is a word character before + * the '//' match in order to determine if we should actually autolink a + * protocol-relative URL. This is needed because there is no negative + * look-behind in JavaScript regular expressions. + * + * For instance, we want to autolink something like "Go to: //google.com", + * but we don't want to autolink something like "abc//google.com" + */ + invalidProtocolRelMatchRegex : /^[\w]\/\//, - if (this._createBatchTable) { - if (ContextLimits.maximumVertexTextureImageUnits === 0) { - throw new RuntimeError('Vertex texture fetch support is required to render polylines. The maximum number of vertex texture image units must be greater than zero.'); - } - createBatchTable(this, context); - this._createBatchTable = false; - } + /** + * Regex to test for a full protocol, with the two trailing slashes. Ex: 'http://' + * + * @private + * @property {RegExp} hasFullProtocolRegex + */ + hasFullProtocolRegex : /^[A-Za-z][-.+A-Za-z0-9]+:\/\//, - if (this._createVertexArray || computeNewBuffersUsage(this)) { - createVertexArrays(this, context, projection); - } else if (this._polylinesUpdated) { - // Polylines were modified, but no polylines were added or removed. - var polylinesToUpdate = this._polylinesToUpdate; - if (this._mode !== SceneMode.SCENE3D) { - var updateLength = polylinesToUpdate.length; - for ( var i = 0; i < updateLength; ++i) { - polyline = polylinesToUpdate[i]; - polyline.update(); - } - } + /** + * Regex to find the URI scheme, such as 'mailto:'. + * + * This is used to filter out 'javascript:' and 'vbscript:' schemes. + * + * @private + * @property {RegExp} uriSchemeRegex + */ + uriSchemeRegex : /^[A-Za-z][-.+A-Za-z0-9]+:/, - // if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. - // if a polyline's material changes, we need to recreate the VAOs and VBOs because they will be batched differently. - if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX]) { - createVertexArrays(this, context, projection); - } else { - var length = polylinesToUpdate.length; - var polylineBuckets = this._polylineBuckets; - for ( var ii = 0; ii < length; ++ii) { - polyline = polylinesToUpdate[ii]; - properties = polyline._propertiesChanged; - var bucket = polyline._bucket; - var index = 0; - for (var x in polylineBuckets) { - if (polylineBuckets.hasOwnProperty(x)) { - if (polylineBuckets[x] === bucket) { - if (properties[POSITION_INDEX]) { - bucket.writeUpdate(index, polyline, this._positionBuffer, projection); - } - break; - } - index += polylineBuckets[x].lengthOfPositions; - } - } + /** + * Regex to determine if at least one word char exists after the protocol (i.e. after the ':') + * + * @private + * @property {RegExp} hasWordCharAfterProtocolRegex + */ + hasWordCharAfterProtocolRegex : /:[^\s]*?[A-Za-z]/, - if (properties[SHOW_INDEX] || properties[WIDTH_INDEX]) { - this._batchTable.setBatchedAttribute(polyline._index, 0, new Cartesian2(polyline._width, polyline._show)); - } - if (this._batchTable.attributes.length > 2) { - if (properties[POSITION_INDEX] || properties[POSITION_SIZE_INDEX]) { - var boundingSphere = frameState.mode === SceneMode.SCENE2D ? polyline._boundingVolume2D : polyline._boundingVolumeWC; - var encodedCenter = EncodedCartesian3.fromCartesian(boundingSphere.center, scratchUpdatePolylineEncodedCartesian); - var low = Cartesian4.fromElements(encodedCenter.low.x, encodedCenter.low.y, encodedCenter.low.z, boundingSphere.radius, scratchUpdatePolylineCartesian4); - this._batchTable.setBatchedAttribute(polyline._index, 2, encodedCenter.high); - this._batchTable.setBatchedAttribute(polyline._index, 3, low); - } + /** + * Determines if a given match found by the {@link Autolinker.matchParser.MatchParser} + * is valid. Will return `false` for: + * + * 1) URL matches which do not have at least have one period ('.') in the + * domain name (effectively skipping over matches like "abc:def"). + * However, URL matches with a protocol will be allowed (ex: 'http://localhost') + * 2) URL matches which do not have at least one word character in the + * domain name (effectively skipping over matches like "git:1.0"). + * 3) A protocol-relative url match (a URL beginning with '//') whose + * previous character is a word character (effectively skipping over + * strings like "abc//google.com") + * + * Otherwise, returns `true`. + * + * @param {String} urlMatch The matched URL, if there was one. Will be an + * empty string if the match is not a URL match. + * @param {String} protocolUrlMatch The match URL string for a protocol + * match. Ex: 'http://yahoo.com'. This is used to match something like + * 'http://localhost', where we won't double check that the domain name + * has at least one '.' in it. + * @param {String} protocolRelativeMatch The protocol-relative string for a + * URL match (i.e. '//'), possibly with a preceding character (ex, a + * space, such as: ' //', or a letter, such as: 'a//'). The match is + * invalid if there is a word character preceding the '//'. + * @return {Boolean} `true` if the match given is valid and should be + * processed, or `false` if the match is invalid and/or should just not be + * processed. + */ + isValidMatch : function( urlMatch, protocolUrlMatch, protocolRelativeMatch ) { + if( + ( protocolUrlMatch && !this.isValidUriScheme( protocolUrlMatch ) ) || + this.urlMatchDoesNotHaveProtocolOrDot( urlMatch, protocolUrlMatch ) || // At least one period ('.') must exist in the URL match for us to consider it an actual URL, *unless* it was a full protocol match (like 'http://localhost') + this.urlMatchDoesNotHaveAtLeastOneWordChar( urlMatch, protocolUrlMatch ) || // At least one letter character must exist in the domain name after a protocol match. Ex: skip over something like "git:1.0" + this.isInvalidProtocolRelativeMatch( protocolRelativeMatch ) // A protocol-relative match which has a word character in front of it (so we can skip something like "abc//google.com") + ) { + return false; + } - if (properties[DISTANCE_DISPLAY_CONDITION]) { - var nearFarCartesian = scratchNearFarCartesian2; - nearFarCartesian.x = 0.0; - nearFarCartesian.y = Number.MAX_VALUE; + return true; + }, - var distanceDisplayCondition = polyline.distanceDisplayCondition; - if (defined(distanceDisplayCondition)) { - nearFarCartesian.x = distanceDisplayCondition.near; - nearFarCartesian.y = distanceDisplayCondition.far; - } - this._batchTable.setBatchedAttribute(polyline._index, 4, nearFarCartesian); - } - } + /** + * Determines if the URI scheme is a valid scheme to be autolinked. Returns + * `false` if the scheme is 'javascript:' or 'vbscript:' + * + * @private + * @param {String} uriSchemeMatch The match URL string for a full URI scheme + * match. Ex: 'http://yahoo.com' or 'mailto:a@a.com'. + * @return {Boolean} `true` if the scheme is a valid one, `false` otherwise. + */ + isValidUriScheme : function( uriSchemeMatch ) { + var uriScheme = uriSchemeMatch.match( this.uriSchemeRegex )[ 0 ].toLowerCase(); - polyline._clean(); - } - } - polylinesToUpdate.length = 0; - this._polylinesUpdated = false; - } + return ( uriScheme !== 'javascript:' && uriScheme !== 'vbscript:' ); + }, - properties = this._propertiesChanged; - for ( var k = 0; k < NUMBER_OF_PROPERTIES; ++k) { - properties[k] = 0; - } - var modelMatrix = Matrix4.IDENTITY; - if (frameState.mode === SceneMode.SCENE3D) { - modelMatrix = this.modelMatrix; - } + /** + * Determines if a URL match does not have either: + * + * a) a full protocol (i.e. 'http://'), or + * b) at least one dot ('.') in the domain name (for a non-full-protocol + * match). + * + * Either situation is considered an invalid URL (ex: 'git:d' does not have + * either the '://' part, or at least one dot in the domain name. If the + * match was 'git:abc.com', we would consider this valid.) + * + * @private + * @param {String} urlMatch The matched URL, if there was one. Will be an + * empty string if the match is not a URL match. + * @param {String} protocolUrlMatch The match URL string for a protocol + * match. Ex: 'http://yahoo.com'. This is used to match something like + * 'http://localhost', where we won't double check that the domain name + * has at least one '.' in it. + * @return {Boolean} `true` if the URL match does not have a full protocol, + * or at least one dot ('.') in a non-full-protocol match. + */ + urlMatchDoesNotHaveProtocolOrDot : function( urlMatch, protocolUrlMatch ) { + return ( !!urlMatch && ( !protocolUrlMatch || !this.hasFullProtocolRegex.test( protocolUrlMatch ) ) && urlMatch.indexOf( '.' ) === -1 ); + }, - var pass = frameState.passes; - var useDepthTest = (frameState.morphTime !== 0.0); - if (!defined(this._opaqueRS) || this._opaqueRS.depthTest.enabled !== useDepthTest) { - this._opaqueRS = RenderState.fromCache({ - depthMask : useDepthTest, - depthTest : { - enabled : useDepthTest - } - }); - } + /** + * Determines if a URL match does not have at least one word character after + * the protocol (i.e. in the domain name). + * + * At least one letter character must exist in the domain name after a + * protocol match. Ex: skip over something like "git:1.0" + * + * @private + * @param {String} urlMatch The matched URL, if there was one. Will be an + * empty string if the match is not a URL match. + * @param {String} protocolUrlMatch The match URL string for a protocol + * match. Ex: 'http://yahoo.com'. This is used to know whether or not we + * have a protocol in the URL string, in order to check for a word + * character after the protocol separator (':'). + * @return {Boolean} `true` if the URL match does not have at least one word + * character in it after the protocol, `false` otherwise. + */ + urlMatchDoesNotHaveAtLeastOneWordChar : function( urlMatch, protocolUrlMatch ) { + if( urlMatch && protocolUrlMatch ) { + return !this.hasWordCharAfterProtocolRegex.test( urlMatch ); + } else { + return false; + } + }, - if (!defined(this._translucentRS) || this._translucentRS.depthTest.enabled !== useDepthTest) { - this._translucentRS = RenderState.fromCache({ - blending : BlendingState.ALPHA_BLEND, - depthMask : !useDepthTest, - depthTest : { - enabled : useDepthTest - } - }); - } - this._batchTable.update(frameState); + /** + * Determines if a protocol-relative match is an invalid one. This method + * returns `true` if there is a `protocolRelativeMatch`, and that match + * contains a word character before the '//' (i.e. it must contain + * whitespace or nothing before the '//' in order to be considered valid). + * + * @private + * @param {String} protocolRelativeMatch The protocol-relative string for a + * URL match (i.e. '//'), possibly with a preceding character (ex, a + * space, such as: ' //', or a letter, such as: 'a//'). The match is + * invalid if there is a word character preceding the '//'. + * @return {Boolean} `true` if it is an invalid protocol-relative match, + * `false` otherwise. + */ + isInvalidProtocolRelativeMatch : function( protocolRelativeMatch ) { + return ( !!protocolRelativeMatch && this.invalidProtocolRelMatchRegex.test( protocolRelativeMatch ) ); + } - if (pass.render) { - var colorList = this._colorCommands; - createCommandLists(this, frameState, colorList, modelMatrix, true); - } +} ); +/*global Autolinker */ +/** + * @abstract + * @class Autolinker.match.Match + * + * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a + * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match. + * + * For example: + * + * var input = "..."; // string with URLs, Email Addresses, and Twitter Handles + * + * var linkedText = Autolinker.link( input, { + * replaceFn : function( autolinker, match ) { + * console.log( "href = ", match.getAnchorHref() ); + * console.log( "text = ", match.getAnchorText() ); + * + * switch( match.getType() ) { + * case 'url' : + * console.log( "url: ", match.getUrl() ); + * + * case 'email' : + * console.log( "email: ", match.getEmail() ); + * + * case 'twitter' : + * console.log( "twitter: ", match.getTwitterHandle() ); + * } + * } + * } ); + * + * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}. + */ +Autolinker.match.Match = Autolinker.Util.extend( Object, { + + /** + * @cfg {String} matchedText (required) + * + * The original text that was matched. + */ + + + /** + * @constructor + * @param {Object} cfg The configuration properties for the Match instance, specified in an Object (map). + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + }, - if (pass.pick) { - var pickList = this._pickCommands; - createCommandLists(this, frameState, pickList, modelMatrix, false); - } - }; + + /** + * Returns a string name for the type of match that this class represents. + * + * @abstract + * @return {String} + */ + getType : Autolinker.Util.abstractMethod, + + + /** + * Returns the original text that was matched. + * + * @return {String} + */ + getMatchedText : function() { + return this.matchedText; + }, + - var boundingSphereScratch = new BoundingSphere(); - var boundingSphereScratch2 = new BoundingSphere(); + /** + * Returns the anchor href that should be generated for the match. + * + * @abstract + * @return {String} + */ + getAnchorHref : Autolinker.Util.abstractMethod, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @abstract + * @return {String} + */ + getAnchorText : Autolinker.Util.abstractMethod - function createCommandLists(polylineCollection, frameState, commands, modelMatrix, renderPass) { - var context = frameState.context; - var commandList = frameState.commandList; +} ); +/*global Autolinker */ +/** + * @class Autolinker.match.Email + * @extends Autolinker.match.Match + * + * Represents a Email match found in an input string which should be Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more details. + */ +Autolinker.match.Email = Autolinker.Util.extend( Autolinker.match.Match, { + + /** + * @cfg {String} email (required) + * + * The email address that was matched. + */ + - var commandsLength = commands.length; - var commandIndex = 0; - var cloneBoundingSphere = true; + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'email'; + }, + + + /** + * Returns the email address that was matched. + * + * @return {String} + */ + getEmail : function() { + return this.email; + }, + - var vertexArrays = polylineCollection._vertexArrays; - var debugShowBoundingVolume = polylineCollection.debugShowBoundingVolume; + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + return 'mailto:' + this.email; + }, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + return this.email; + } + +} ); +/*global Autolinker */ +/** + * @class Autolinker.match.Hashtag + * @extends Autolinker.match.Match + * + * Represents a Hashtag match found in an input string which should be + * Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more + * details. + */ +Autolinker.match.Hashtag = Autolinker.Util.extend( Autolinker.match.Match, { - var batchTable = polylineCollection._batchTable; - var uniformCallback = batchTable.getUniformMapCallback(); + /** + * @cfg {String} serviceName (required) + * + * The service to point hashtag matches to. See {@link Autolinker#hashtag} + * for available values. + */ - var length = vertexArrays.length; - for ( var m = 0; m < length; ++m) { - var va = vertexArrays[m]; - var buckets = va.buckets; - var bucketLength = buckets.length; + /** + * @cfg {String} hashtag (required) + * + * The Hashtag that was matched, without the '#'. + */ - for ( var n = 0; n < bucketLength; ++n) { - var bucketLocator = buckets[n]; - var offset = bucketLocator.offset; - var sp = renderPass ? bucketLocator.bucket.shaderProgram : bucketLocator.bucket.pickShaderProgram; + /** + * Returns the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'hashtag'; + }, - var polylines = bucketLocator.bucket.polylines; - var polylineLength = polylines.length; - var currentId; - var currentMaterial; - var count = 0; - var command; - for (var s = 0; s < polylineLength; ++s) { - var polyline = polylines[s]; - var mId = createMaterialId(polyline._material); - if (mId !== currentId) { - if (defined(currentId) && count > 0) { - var translucent = currentMaterial.isTranslucent(); + /** + * Returns the matched hashtag. + * + * @return {String} + */ + getHashtag : function() { + return this.hashtag; + }, - if (commandIndex >= commandsLength) { - command = new DrawCommand({ - owner : polylineCollection - }); - commands.push(command); - } else { - command = commands[commandIndex]; - } - ++commandIndex; + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + var serviceName = this.serviceName, + hashtag = this.hashtag; - command.boundingVolume = BoundingSphere.clone(boundingSphereScratch, command.boundingVolume); - command.modelMatrix = modelMatrix; - command.shaderProgram = sp; - command.vertexArray = va.va; - command.renderState = translucent ? polylineCollection._translucentRS : polylineCollection._opaqueRS; - command.pass = translucent ? Pass.TRANSLUCENT : Pass.OPAQUE; - command.debugShowBoundingVolume = renderPass ? debugShowBoundingVolume : false; + switch( serviceName ) { + case 'twitter' : + return 'https://twitter.com/hashtag/' + hashtag; + case 'facebook' : + return 'https://www.facebook.com/hashtag/' + hashtag; - command.uniformMap = uniformCallback(currentMaterial._uniforms); - command.count = count; - command.offset = offset; + default : // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case. + throw new Error( 'Unknown service name to point hashtag to: ', serviceName ); + } + }, - offset += count; - count = 0; - cloneBoundingSphere = true; - commandList.push(command); - } + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + return '#' + this.hashtag; + } - currentMaterial = polyline._material; - currentMaterial.update(context); - currentId = mId; - } +} ); +/*global Autolinker */ +/** + * @class Autolinker.match.Phone + * @extends Autolinker.match.Match + * + * Represents a Phone number match found in an input string which should be + * Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more + * details. + */ +Autolinker.match.Phone = Autolinker.Util.extend( Autolinker.match.Match, { - var locators = polyline._locatorBuckets; - var locatorLength = locators.length; - for (var t = 0; t < locatorLength; ++t) { - var locator = locators[t]; - if (locator.locator === bucketLocator) { - count += locator.count; - } - } + /** + * @cfg {String} number (required) + * + * The phone number that was matched. + */ - var boundingVolume; - if (frameState.mode === SceneMode.SCENE3D) { - boundingVolume = polyline._boundingVolumeWC; - } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { - boundingVolume = polyline._boundingVolume2D; - } else if (frameState.mode === SceneMode.SCENE2D) { - if (defined(polyline._boundingVolume2D)) { - boundingVolume = BoundingSphere.clone(polyline._boundingVolume2D, boundingSphereScratch2); - boundingVolume.center.x = 0.0; - } - } else if (defined(polyline._boundingVolumeWC) && defined(polyline._boundingVolume2D)) { - boundingVolume = BoundingSphere.union(polyline._boundingVolumeWC, polyline._boundingVolume2D, boundingSphereScratch2); - } - if (cloneBoundingSphere) { - cloneBoundingSphere = false; - BoundingSphere.clone(boundingVolume, boundingSphereScratch); - } else { - BoundingSphere.union(boundingVolume, boundingSphereScratch, boundingSphereScratch); - } - } + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'phone'; + }, - if (defined(currentId) && count > 0) { - if (commandIndex >= commandsLength) { - command = new DrawCommand({ - owner : polylineCollection - }); - commands.push(command); - } else { - command = commands[commandIndex]; - } - ++commandIndex; + /** + * Returns the phone number that was matched. + * + * @return {String} + */ + getNumber: function() { + return this.number; + }, - command.boundingVolume = BoundingSphere.clone(boundingSphereScratch, command.boundingVolume); - command.modelMatrix = modelMatrix; - command.shaderProgram = sp; - command.vertexArray = va.va; - command.renderState = currentMaterial.isTranslucent() ? polylineCollection._translucentRS : polylineCollection._opaqueRS; - command.pass = currentMaterial.isTranslucent() ? Pass.TRANSLUCENT : Pass.OPAQUE; - command.debugShowBoundingVolume = renderPass ? debugShowBoundingVolume : false; - command.uniformMap = uniformCallback(currentMaterial._uniforms); - command.count = count; - command.offset = offset; + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + return 'tel:' + this.number; + }, - cloneBoundingSphere = true; - commandList.push(command); - } + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + return this.matchedText; + } - currentId = undefined; - } - } +} ); - commands.length = commandIndex; - } +/*global Autolinker */ +/** + * @class Autolinker.match.Twitter + * @extends Autolinker.match.Match + * + * Represents a Twitter match found in an input string which should be Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more details. + */ +Autolinker.match.Twitter = Autolinker.Util.extend( Autolinker.match.Match, { + + /** + * @cfg {String} twitterHandle (required) + * + * The Twitter handle that was matched. + */ + - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see PolylineCollection#destroy - */ - PolylineCollection.prototype.isDestroyed = function() { - return false; - }; + /** + * Returns the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'twitter'; + }, + + + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getTwitterHandle : function() { + return this.twitterHandle; + }, + - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * polylines = polylines && polylines.destroy(); - * - * @see PolylineCollection#isDestroyed - */ - PolylineCollection.prototype.destroy = function() { - destroyVertexArrays(this); - releaseShaders(this); - destroyPolylines(this); - this._batchTable = this._batchTable && this._batchTable.destroy(); - return destroyObject(this); - }; + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + return 'https://twitter.com/' + this.twitterHandle; + }, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + return '@' + this.twitterHandle; + } + +} ); +/*global Autolinker */ +/** + * @class Autolinker.match.Url + * @extends Autolinker.match.Match + * + * Represents a Url match found in an input string which should be Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more details. + */ +Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, { + + /** + * @cfg {String} url (required) + * + * The url that was matched. + */ + + /** + * @cfg {Boolean} protocolUrlMatch (required) + * + * `true` if the URL is a match which already has a protocol (i.e. 'http://'), `false` if the match was from a 'www' or + * known TLD match. + */ + + /** + * @cfg {Boolean} protocolRelativeMatch (required) + * + * `true` if the URL is a protocol-relative match. A protocol-relative match is a URL that starts with '//', + * and will be either http:// or https:// based on the protocol that the site is loaded under. + */ + + /** + * @cfg {Boolean} stripPrefix (required) + * @inheritdoc Autolinker#stripPrefix + */ + - function computeNewBuffersUsage(collection) { - var usageChanged = false; - var properties = collection._propertiesChanged; - var bufferUsage = collection._positionBufferUsage; - if (properties[POSITION_INDEX]) { - if (bufferUsage.bufferUsage !== BufferUsage.STREAM_DRAW) { - usageChanged = true; - bufferUsage.bufferUsage = BufferUsage.STREAM_DRAW; - bufferUsage.frameCount = 100; - } else { - bufferUsage.frameCount = 100; - } - } else if (bufferUsage.bufferUsage !== BufferUsage.STATIC_DRAW) { - if (bufferUsage.frameCount === 0) { - usageChanged = true; - bufferUsage.bufferUsage = BufferUsage.STATIC_DRAW; - } else { - bufferUsage.frameCount--; - } - } + /** + * @private + * @property {RegExp} urlPrefixRegex + * + * A regular expression used to remove the 'http://' or 'https://' and/or the 'www.' from URLs. + */ + urlPrefixRegex: /^(https?:\/\/)?(www\.)?/i, + + /** + * @private + * @property {RegExp} protocolRelativeRegex + * + * The regular expression used to remove the protocol-relative '//' from the {@link #url} string, for purposes + * of {@link #getAnchorText}. A protocol-relative URL is, for example, "//yahoo.com" + */ + protocolRelativeRegex : /^\/\//, + + /** + * @private + * @property {Boolean} protocolPrepended + * + * Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the + * {@link #url} did not have a protocol) + */ + protocolPrepended : false, + - return usageChanged; - } + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'url'; + }, + + + /** + * Returns the url that was matched, assuming the protocol to be 'http://' if the original + * match was missing a protocol. + * + * @return {String} + */ + getUrl : function() { + var url = this.url; + + // if the url string doesn't begin with a protocol, assume 'http://' + if( !this.protocolRelativeMatch && !this.protocolUrlMatch && !this.protocolPrepended ) { + url = this.url = 'http://' + url; + + this.protocolPrepended = true; + } + + return url; + }, + - var emptyVertexBuffer = [0.0, 0.0, 0.0]; + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + var url = this.getUrl(); + + return url.replace( /&/g, '&' ); // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html + }, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + var anchorText = this.getUrl(); + + if( this.protocolRelativeMatch ) { + // Strip off any protocol-relative '//' from the anchor text + anchorText = this.stripProtocolRelativePrefix( anchorText ); + } + if( this.stripPrefix ) { + anchorText = this.stripUrlPrefix( anchorText ); + } + anchorText = this.removeTrailingSlash( anchorText ); // remove trailing slash, if there is one + + return anchorText; + }, + + + // --------------------------------------- + + // Utility Functionality + + /** + * Strips the URL prefix (such as "http://" or "https://") from the given text. + * + * @private + * @param {String} text The text of the anchor that is being generated, for which to strip off the + * url prefix (such as stripping off "http://") + * @return {String} The `anchorText`, with the prefix stripped. + */ + stripUrlPrefix : function( text ) { + return text.replace( this.urlPrefixRegex, '' ); + }, + + + /** + * Strips any protocol-relative '//' from the anchor text. + * + * @private + * @param {String} text The text of the anchor that is being generated, for which to strip off the + * protocol-relative prefix (such as stripping off "//") + * @return {String} The `anchorText`, with the protocol-relative prefix stripped. + */ + stripProtocolRelativePrefix : function( text ) { + return text.replace( this.protocolRelativeRegex, '' ); + }, + + + /** + * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed. + * + * @private + * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing + * slash ('/') that may exist. + * @return {String} The `anchorText`, with the trailing slash removed. + */ + removeTrailingSlash : function( anchorText ) { + if( anchorText.charAt( anchorText.length - 1 ) === '/' ) { + anchorText = anchorText.slice( 0, -1 ); + } + return anchorText; + } + +} ); +return Autolinker; - function createVertexArrays(collection, context, projection) { - collection._createVertexArray = false; - releaseShaders(collection); - destroyVertexArrays(collection); - sortPolylinesIntoBuckets(collection); +})); - //stores all of the individual indices arrays. - var totalIndices = [[]]; - var indices = totalIndices[0]; +/** +@license + Copyright (c) 2013 Gildas Lormeau. All rights reserved. - var batchTable = collection._batchTable; + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: - //used to determine the vertexBuffer offset if the indicesArray goes over 64k. - //if it's the same polyline while it goes over 64k, the offset needs to backtrack componentsPerAttribute * componentDatatype bytes - //so that the polyline looks contiguous. - //if the polyline ends at the 64k mark, then the offset is just 64k * componentsPerAttribute * componentDatatype - var vertexBufferOffset = [0]; - var offset = 0; - var vertexArrayBuckets = [[]]; - var totalLength = 0; - var polylineBuckets = collection._polylineBuckets; - var x; - var bucket; - for (x in polylineBuckets) { - if (polylineBuckets.hasOwnProperty(x)) { - bucket = polylineBuckets[x]; - bucket.updateShader(context, batchTable); - totalLength += bucket.lengthOfPositions; - } - } + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. - if (totalLength > 0) { - var mode = collection._mode; + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. - var positionArray = new Float32Array(6 * totalLength * 3); - var texCoordExpandAndBatchIndexArray = new Float32Array(totalLength * 4); - var position3DArray; + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. - var positionIndex = 0; - var colorIndex = 0; - var texCoordExpandAndBatchIndexIndex = 0; - for (x in polylineBuckets) { - if (polylineBuckets.hasOwnProperty(x)) { - bucket = polylineBuckets[x]; - bucket.write(positionArray, texCoordExpandAndBatchIndexArray, positionIndex, colorIndex, texCoordExpandAndBatchIndexIndex, batchTable, context, projection); + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, + INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**/ - if (mode === SceneMode.MORPHING) { - if (!defined(position3DArray)) { - position3DArray = new Float32Array(6 * totalLength * 3); - } - bucket.writeForMorph(position3DArray, positionIndex); - } +define('ThirdParty/zip',[ + '../Core/buildModuleUrl', + '../Core/defineProperties' + ], function( + buildModuleUrl, + defineProperties) { + var tmp = {}; - var bucketLength = bucket.lengthOfPositions; - positionIndex += 6 * bucketLength * 3; - colorIndex += bucketLength * 4; - texCoordExpandAndBatchIndexIndex += bucketLength * 4; - offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); - } - } +(function(obj) { - var positionBufferUsage = collection._positionBufferUsage.bufferUsage; - var texCoordExpandAndBatchIndexBufferUsage = BufferUsage.STATIC_DRAW; + var ERR_BAD_FORMAT = "File format is not recognized."; + var ERR_ENCRYPTED = "File contains encrypted entry."; + var ERR_ZIP64 = "File is using Zip64 (4gb+ file size)."; + var ERR_READ = "Error while reading zip file."; + var ERR_WRITE = "Error while writing zip file."; + var ERR_WRITE_DATA = "Error while writing file data."; + var ERR_READ_DATA = "Error while reading file data."; + var ERR_DUPLICATED_NAME = "File already exists."; + var CHUNK_SIZE = 512 * 1024; - collection._positionBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : positionArray, - usage : positionBufferUsage - }); - var position3DBuffer; - if (defined(position3DArray)) { - position3DBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : position3DArray, - usage : positionBufferUsage - }); - } - collection._texCoordExpandAndBatchIndexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : texCoordExpandAndBatchIndexArray, - usage : texCoordExpandAndBatchIndexBufferUsage - }); + var INFLATE_JS = "inflate.js"; + var DEFLATE_JS = "deflate.js"; - var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; - var texCoordExpandAndBatchIndexSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + var TEXT_PLAIN = "text/plain"; - var vbo = 0; - var numberOfIndicesArrays = totalIndices.length; - for ( var k = 0; k < numberOfIndicesArrays; ++k) { - indices = totalIndices[k]; + var MESSAGE_EVENT = "message"; - if (indices.length > 0) { - var indicesArray = new Uint16Array(indices); - var indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : indicesArray, - usage : BufferUsage.STATIC_DRAW, - indexDatatype : IndexDatatype.UNSIGNED_SHORT - }); + var appendABViewSupported; + try { + appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0; + } catch (e) { + } - vbo += vertexBufferOffset[k]; + function Crc32() { + var crc = -1, that = this; + that.append = function(data) { + var offset, table = that.table; + for (offset = 0; offset < data.length; offset++) + crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF]; + }; + that.get = function() { + return ~crc; + }; + } + Crc32.prototype.table = (function() { + var i, j, t, table = []; + for (i = 0; i < 256; i++) { + t = i; + for (j = 0; j < 8; j++) + if (t & 1) + t = (t >>> 1) ^ 0xEDB88320; + else + t = t >>> 1; + table[i] = t; + } + return table; + })(); - var positionHighOffset = 6 * (k * (positionSizeInBytes * CesiumMath.SIXTY_FOUR_KILOBYTES) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) - var positionLowOffset = positionSizeInBytes + positionHighOffset; - var prevPositionHighOffset = positionSizeInBytes + positionLowOffset; - var prevPositionLowOffset = positionSizeInBytes + prevPositionHighOffset; - var nextPositionHighOffset = positionSizeInBytes + prevPositionLowOffset; - var nextPositionLowOffset = positionSizeInBytes + nextPositionHighOffset; - var vertexTexCoordExpandAndBatchIndexBufferOffset = k * (texCoordExpandAndBatchIndexSizeInBytes * CesiumMath.SIXTY_FOUR_KILOBYTES) - vbo * texCoordExpandAndBatchIndexSizeInBytes; + function blobSlice(blob, index, length) { + if (blob.slice) + return blob.slice(index, index + length); + else if (blob.webkitSlice) + return blob.webkitSlice(index, index + length); + else if (blob.mozSlice) + return blob.mozSlice(index, index + length); + else if (blob.msSlice) + return blob.msSlice(index, index + length); + } - var attributes = [{ - index : attributeLocations.position3DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.position3DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.position2DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.position2DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.prevPosition3DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : prevPositionHighOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.prevPosition3DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : prevPositionLowOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.prevPosition2DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : prevPositionHighOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.prevPosition2DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : prevPositionLowOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.nextPosition3DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : nextPositionHighOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.nextPosition3DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : nextPositionLowOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.nextPosition2DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : nextPositionHighOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.nextPosition2DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : nextPositionLowOffset, - strideInBytes : 6 * positionSizeInBytes - }, { - index : attributeLocations.texCoordExpandAndBatchIndex, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : collection._texCoordExpandAndBatchIndexBuffer, - offsetInBytes : vertexTexCoordExpandAndBatchIndexBufferOffset - }]; + function getDataHelper(byteLength, bytes) { + var dataBuffer, dataArray; + dataBuffer = new ArrayBuffer(byteLength); + dataArray = new Uint8Array(dataBuffer); + if (bytes) + dataArray.set(bytes, 0); + return { + buffer : dataBuffer, + array : dataArray, + view : new DataView(dataBuffer) + }; + } - var buffer3D; - var bufferProperty3D; - var buffer2D; - var bufferProperty2D; + // Readers + function Reader() { + } - if (mode === SceneMode.SCENE3D) { - buffer3D = collection._positionBuffer; - bufferProperty3D = 'vertexBuffer'; - buffer2D = emptyVertexBuffer; - bufferProperty2D = 'value'; - } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - buffer3D = emptyVertexBuffer; - bufferProperty3D = 'value'; - buffer2D = collection._positionBuffer; - bufferProperty2D = 'vertexBuffer'; - } else { - buffer3D = position3DBuffer; - bufferProperty3D = 'vertexBuffer'; - buffer2D = collection._positionBuffer; - bufferProperty2D = 'vertexBuffer'; - } + function TextReader(text) { + var that = this, blobReader; - attributes[0][bufferProperty3D] = buffer3D; - attributes[1][bufferProperty3D] = buffer3D; - attributes[2][bufferProperty2D] = buffer2D; - attributes[3][bufferProperty2D] = buffer2D; - attributes[4][bufferProperty3D] = buffer3D; - attributes[5][bufferProperty3D] = buffer3D; - attributes[6][bufferProperty2D] = buffer2D; - attributes[7][bufferProperty2D] = buffer2D; - attributes[8][bufferProperty3D] = buffer3D; - attributes[9][bufferProperty3D] = buffer3D; - attributes[10][bufferProperty2D] = buffer2D; - attributes[11][bufferProperty2D] = buffer2D; + function init(callback, onerror) { + var blob = new Blob([ text ], { + type : TEXT_PLAIN + }); + blobReader = new BlobReader(blob); + blobReader.init(function() { + that.size = blobReader.size; + callback(); + }, onerror); + } - var va = new VertexArray({ - context : context, - attributes : attributes, - indexBuffer : indexBuffer - }); - collection._vertexArrays.push({ - va : va, - buckets : vertexArrayBuckets[k] - }); - } - } - } - } + function readUint8Array(index, length, callback, onerror) { + blobReader.readUint8Array(index, length, callback, onerror); + } - function replacer(key, value) { - if (value instanceof Texture) { - return value.id; - } + that.size = 0; + that.init = init; + that.readUint8Array = readUint8Array; + } + TextReader.prototype = new Reader(); + TextReader.prototype.constructor = TextReader; - return value; - } + function Data64URIReader(dataURI) { + var that = this, dataStart; - var scratchUniformArray = []; - function createMaterialId(material) { - var uniforms = Material._uniformList[material.type]; - var length = uniforms.length; - scratchUniformArray.length = 2.0 * length; + function init(callback) { + var dataEnd = dataURI.length; + while (dataURI.charAt(dataEnd - 1) == "=") + dataEnd--; + dataStart = dataURI.indexOf(",") + 1; + that.size = Math.floor((dataEnd - dataStart) * 0.75); + callback(); + } - var index = 0; - for (var i = 0; i < length; ++i) { - var uniform = uniforms[i]; - scratchUniformArray[index] = uniform; - scratchUniformArray[index + 1] = material._uniforms[uniform](); - index += 2; - } + function readUint8Array(index, length, callback) { + var i, data = getDataHelper(length); + var start = Math.floor(index / 3) * 4; + var end = Math.ceil((index + length) / 3) * 4; + var bytes = window.atob(dataURI.substring(start + dataStart, end + dataStart)); + var delta = index - Math.floor(start / 4) * 3; + for (i = delta; i < delta + length; i++) + data.array[i - delta] = bytes.charCodeAt(i); + callback(data.array); + } - return material.type + ':' + JSON.stringify(scratchUniformArray, replacer); - } + that.size = 0; + that.init = init; + that.readUint8Array = readUint8Array; + } + Data64URIReader.prototype = new Reader(); + Data64URIReader.prototype.constructor = Data64URIReader; - function sortPolylinesIntoBuckets(collection) { - var mode = collection._mode; - var modelMatrix = collection._modelMatrix; + function BlobReader(blob) { + var that = this; - var polylineBuckets = collection._polylineBuckets = {}; - var polylines = collection._polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - var p = polylines[i]; - if (p._actualPositions.length > 1) { - p.update(); - var material = p.material; - var value = polylineBuckets[material.type]; - if (!defined(value)) { - value = polylineBuckets[material.type] = new PolylineBucket(material, mode, modelMatrix); - } - value.addPolyline(p); - } - } - } + function init(callback) { + this.size = blob.size; + callback(); + } - function updateMode(collection, frameState) { - var mode = frameState.mode; + function readUint8Array(index, length, callback, onerror) { + var reader = new FileReader(); + reader.onload = function(e) { + callback(new Uint8Array(e.target.result)); + }; + reader.onerror = onerror; + reader.readAsArrayBuffer(blobSlice(blob, index, length)); + } - if (collection._mode !== mode || (!Matrix4.equals(collection._modelMatrix, collection.modelMatrix))) { - collection._mode = mode; - collection._modelMatrix = Matrix4.clone(collection.modelMatrix); - collection._createVertexArray = true; - } - } + that.size = 0; + that.init = init; + that.readUint8Array = readUint8Array; + } + BlobReader.prototype = new Reader(); + BlobReader.prototype.constructor = BlobReader; - function removePolylines(collection) { - if (collection._polylinesRemoved) { - collection._polylinesRemoved = false; + // Writers - var polylines = []; + function Writer() { + } + Writer.prototype.getData = function(callback) { + callback(this.data); + }; - var length = collection._polylines.length; - for ( var i = 0, j = 0; i < length; ++i) { - var polyline = collection._polylines[i]; - if (defined(polyline)) { - polyline._index = j++; - polylines.push(polyline); - } - } + function TextWriter(encoding) { + var that = this, blob; - collection._polylines = polylines; - } - } + function init(callback) { + blob = new Blob([], { + type : TEXT_PLAIN + }); + callback(); + } - function releaseShaders(collection) { - var polylines = collection._polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - if (defined(polylines[i])) { - var bucket = polylines[i]._bucket; - if (defined(bucket)) { - bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.destroy(); - } - } - } - } + function writeUint8Array(array, callback) { + blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], { + type : TEXT_PLAIN + }); + callback(); + } - function destroyVertexArrays(collection) { - var length = collection._vertexArrays.length; - for ( var t = 0; t < length; ++t) { - collection._vertexArrays[t].va.destroy(); - } - collection._vertexArrays.length = 0; - } + function getData(callback, onerror) { + var reader = new FileReader(); + reader.onload = function(e) { + callback(e.target.result); + }; + reader.onerror = onerror; + reader.readAsText(blob, encoding); + } - PolylineCollection.prototype._updatePolyline = function(polyline, propertyChanged) { - this._polylinesUpdated = true; - this._polylinesToUpdate.push(polyline); - ++this._propertiesChanged[propertyChanged]; - }; + that.init = init; + that.writeUint8Array = writeUint8Array; + that.getData = getData; + } + TextWriter.prototype = new Writer(); + TextWriter.prototype.constructor = TextWriter; - function destroyPolylines(collection) { - var polylines = collection._polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - if (defined(polylines[i])) { - polylines[i]._destroy(); - } - } - } + function Data64URIWriter(contentType) { + var that = this, data = "", pending = ""; - function VertexArrayBucketLocator(count, offset, bucket) { - this.count = count; - this.offset = offset; - this.bucket = bucket; - } + function init(callback) { + data += "data:" + (contentType || "") + ";base64,"; + callback(); + } - function PolylineBucket(material, mode, modelMatrix) { - this.polylines = []; - this.lengthOfPositions = 0; - this.material = material; - this.shaderProgram = undefined; - this.pickShaderProgram = undefined; - this.mode = mode; - this.modelMatrix = modelMatrix; - } + function writeUint8Array(array, callback) { + var i, delta = pending.length, dataString = pending; + pending = ""; + for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++) + dataString += String.fromCharCode(array[i]); + for (; i < array.length; i++) + pending += String.fromCharCode(array[i]); + if (dataString.length > 2) + data += window.btoa(dataString); + else + pending = dataString; + callback(); + } - PolylineBucket.prototype.addPolyline = function(p) { - var polylines = this.polylines; - polylines.push(p); - p._actualLength = this.getPolylinePositionsLength(p); - this.lengthOfPositions += p._actualLength; - p._bucket = this; - }; + function getData(callback) { + callback(data + window.btoa(pending)); + } - PolylineBucket.prototype.updateShader = function(context, batchTable) { - if (defined(this.shaderProgram)) { - return; - } + that.init = init; + that.writeUint8Array = writeUint8Array; + that.getData = getData; + } + Data64URIWriter.prototype = new Writer(); + Data64URIWriter.prototype.constructor = Data64URIWriter; - var defines = ['DISTANCE_DISPLAY_CONDITION']; + function BlobWriter(contentType) { + var blob, that = this; - var fs = new ShaderSource({ - sources : [this.material.shaderSource, PolylineFS] - }); + function init(callback) { + blob = new Blob([], { + type : contentType + }); + callback(); + } - // Check for use of v_polylineAngle in material shader - if (this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== -1) { - defines.push('POLYLINE_DASH'); - } + function writeUint8Array(array, callback) { + blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], { + type : contentType + }); + callback(); + } - var vsSource = batchTable.getVertexShaderCallback()(PolylineVS); - var vs = new ShaderSource({ - defines : defines, - sources : [PolylineCommon, vsSource] - }); + function getData(callback) { + callback(blob); + } - var fsPick = new ShaderSource({ - sources : fs.sources, - pickColorQualifier : 'varying' - }); + that.init = init; + that.writeUint8Array = writeUint8Array; + that.getData = getData; + } + BlobWriter.prototype = new Writer(); + BlobWriter.prototype.constructor = BlobWriter; - this.shaderProgram = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); + // inflate/deflate core functions - this.pickShaderProgram = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : vs, - fragmentShaderSource : fsPick, - attributeLocations : attributeLocations - }); - }; + function launchWorkerProcess(worker, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { + var chunkIndex = 0, index, outputSize; - function intersectsIDL(polyline) { - return Cartesian3.dot(Cartesian3.UNIT_X, polyline._boundingVolume.center) < 0 || - polyline._boundingVolume.intersectPlane(Plane.ORIGIN_ZX_PLANE) === Intersect.INTERSECTING; - } + function onflush() { + worker.removeEventListener(MESSAGE_EVENT, onmessage, false); + onend(outputSize); + } - PolylineBucket.prototype.getPolylinePositionsLength = function(polyline) { - var length; - if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { - length = polyline._actualPositions.length; - return length * 4.0 - 4.0; - } + function onmessage(event) { + var message = event.data, data = message.data; - var count = 0; - var segmentLengths = polyline._segments.lengths; - length = segmentLengths.length; - for (var i = 0; i < length; ++i) { - count += segmentLengths[i] * 4.0 - 4.0; - } + if (message.onappend) { + outputSize += data.length; + writer.writeUint8Array(data, function() { + onappend(false, data); + step(); + }, onwriteerror); + } + if (message.onflush) + if (data) { + outputSize += data.length; + writer.writeUint8Array(data, function() { + onappend(false, data); + onflush(); + }, onwriteerror); + } else + onflush(); + if (message.progress && onprogress) + onprogress(index + message.current, size); + } - return count; - }; + function step() { + index = chunkIndex * CHUNK_SIZE; + if (index < size) + reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { + worker.postMessage({ + append : true, + data : array + }); + chunkIndex++; + if (onprogress) + onprogress(index, size); + onappend(true, array); + }, onreaderror); + else + worker.postMessage({ + flush : true + }); + } - var scratchWritePosition = new Cartesian3(); - var scratchWritePrevPosition = new Cartesian3(); - var scratchWriteNextPosition = new Cartesian3(); - var scratchWriteVector = new Cartesian3(); - var scratchPickColorCartesian = new Cartesian4(); - var scratchWidthShowCartesian = new Cartesian2(); + outputSize = 0; + worker.addEventListener(MESSAGE_EVENT, onmessage, false); + step(); + } - PolylineBucket.prototype.write = function(positionArray, texCoordExpandAndBatchIndexArray, positionIndex, colorIndex, texCoordExpandAndBatchIndexIndex, batchTable, context, projection) { - var mode = this.mode; - var maxLon = projection.ellipsoid.maximumRadius * CesiumMath.PI; + function launchProcess(process, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { + var chunkIndex = 0, index, outputSize = 0; - var polylines = this.polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - var polyline = polylines[i]; - var width = polyline.width; - var show = polyline.show && width > 0.0; - var polylineBatchIndex = polyline._index; - var segments = this.getSegments(polyline, projection); - var positions = segments.positions; - var lengths = segments.lengths; - var positionsLength = positions.length; + function step() { + var outputData; + index = chunkIndex * CHUNK_SIZE; + if (index < size) + reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) { + var outputData = process.append(inputData, function() { + if (onprogress) + onprogress(offset + index, size); + }); + outputSize += outputData.length; + onappend(true, inputData); + writer.writeUint8Array(outputData, function() { + onappend(false, outputData); + chunkIndex++; + setTimeout(step, 1); + }, onwriteerror); + if (onprogress) + onprogress(index, size); + }, onreaderror); + else { + outputData = process.flush(); + if (outputData) { + outputSize += outputData.length; + writer.writeUint8Array(outputData, function() { + onappend(false, outputData); + onend(outputSize); + }, onwriteerror); + } else + onend(outputSize); + } + } - var pickColor = polyline.getPickId(context).color; + step(); + } - var segmentIndex = 0; - var count = 0; - var position; + function inflate(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { + var worker, crc32 = new Crc32(); - for ( var j = 0; j < positionsLength; ++j) { - if (j === 0) { - if (polyline._loop) { - position = positions[positionsLength - 2]; - } else { - position = scratchWriteVector; - Cartesian3.subtract(positions[0], positions[1], position); - Cartesian3.add(positions[0], position, position); - } - } else { - position = positions[j - 1]; - } + function oninflateappend(sending, array) { + if (computeCrc32 && !sending) + crc32.append(array); + } - Cartesian3.clone(position, scratchWritePrevPosition); - Cartesian3.clone(positions[j], scratchWritePosition); + function oninflateend(outputSize) { + onend(outputSize, crc32.get()); + } - if (j === positionsLength - 1) { - if (polyline._loop) { - position = positions[1]; - } else { - position = scratchWriteVector; - Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], position); - Cartesian3.add(positions[positionsLength - 1], position, position); - } - } else { - position = positions[j + 1]; - } + if (obj.zip.useWebWorkers) { + worker = new Worker(obj.zip.workerScriptsPath + INFLATE_JS); + launchWorkerProcess(worker, reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); + } else + launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); + return worker; + } - Cartesian3.clone(position, scratchWriteNextPosition); + function deflate(reader, writer, level, onend, onprogress, onreaderror, onwriteerror) { + var worker, crc32 = new Crc32(); - var segmentLength = lengths[segmentIndex]; - if (j === count + segmentLength) { - count += segmentLength; - ++segmentIndex; - } + function ondeflateappend(sending, array) { + if (sending) + crc32.append(array); + } - var segmentStart = j - count === 0; - var segmentEnd = j === count + lengths[segmentIndex] - 1; + function ondeflateend(outputSize) { + onend(outputSize, crc32.get()); + } - if (mode === SceneMode.SCENE2D) { - scratchWritePrevPosition.z = 0.0; - scratchWritePosition.z = 0.0; - scratchWriteNextPosition.z = 0.0; - } + function onmessage() { + worker.removeEventListener(MESSAGE_EVENT, onmessage, false); + launchWorkerProcess(worker, reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); + } - if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { - if ((segmentStart || segmentEnd) && maxLon - Math.abs(scratchWritePosition.x) < 1.0) { - if ((scratchWritePosition.x < 0.0 && scratchWritePrevPosition.x > 0.0) || - (scratchWritePosition.x > 0.0 && scratchWritePrevPosition.x < 0.0)) { - Cartesian3.clone(scratchWritePosition, scratchWritePrevPosition); - } + if (obj.zip.useWebWorkers) { + worker = new Worker(obj.zip.workerScriptsPath + DEFLATE_JS); + worker.addEventListener(MESSAGE_EVENT, onmessage, false); + worker.postMessage({ + init : true, + level : level + }); + } else + launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); + return worker; + } - if ((scratchWritePosition.x < 0.0 && scratchWriteNextPosition.x > 0.0) || - (scratchWritePosition.x > 0.0 && scratchWriteNextPosition.x < 0.0)) { - Cartesian3.clone(scratchWritePosition, scratchWriteNextPosition); - } - } - } + function copy(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { + var chunkIndex = 0, crc32 = new Crc32(); - var startK = (segmentStart) ? 2 : 0; - var endK = (segmentEnd) ? 2 : 4; + function step() { + var index = chunkIndex * CHUNK_SIZE; + if (index < size) + reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { + if (computeCrc32) + crc32.append(array); + if (onprogress) + onprogress(index, size, array); + writer.writeUint8Array(array, function() { + chunkIndex++; + step(); + }, onwriteerror); + }, onreaderror); + else + onend(size, crc32.get()); + } - for (var k = startK; k < endK; ++k) { - EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); - EncodedCartesian3.writeElements(scratchWritePrevPosition, positionArray, positionIndex + 6); - EncodedCartesian3.writeElements(scratchWriteNextPosition, positionArray, positionIndex + 12); + step(); + } - var direction = (k - 2 < 0) ? -1.0 : 1.0; - texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex] = j / (positionsLength - 1); // s tex coord - texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex + 1] = 2 * (k % 2) - 1; // expand direction - texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex + 2] = direction; - texCoordExpandAndBatchIndexArray[texCoordExpandAndBatchIndexIndex + 3] = polylineBatchIndex; + // ZipReader - positionIndex += 6 * 3; - texCoordExpandAndBatchIndexIndex += 4; - } - } + function decodeASCII(str) { + var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', + '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', + '\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', + '\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6', + '\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3', + '\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE', + '\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE', + '\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7', + '\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ]; + for (i = 0; i < str.length; i++) { + charCode = str.charCodeAt(i) & 0xFF; + if (charCode > 127) + out += extendedASCII[charCode - 128]; + else + out += String.fromCharCode(charCode); + } + return out; + } - var colorCartesian = scratchPickColorCartesian; - colorCartesian.x = Color.floatToByte(pickColor.red); - colorCartesian.y = Color.floatToByte(pickColor.green); - colorCartesian.z = Color.floatToByte(pickColor.blue); - colorCartesian.w = Color.floatToByte(pickColor.alpha); + function decodeUTF8(string) { + return decodeURIComponent(escape(string)); + } - var widthShowCartesian = scratchWidthShowCartesian; - widthShowCartesian.x = width; - widthShowCartesian.y = show ? 1.0 : 0.0; + function getString(bytes) { + var i, str = ""; + for (i = 0; i < bytes.length; i++) + str += String.fromCharCode(bytes[i]); + return str; + } - var boundingSphere = mode === SceneMode.SCENE2D ? polyline._boundingVolume2D : polyline._boundingVolumeWC; - var encodedCenter = EncodedCartesian3.fromCartesian(boundingSphere.center, scratchUpdatePolylineEncodedCartesian); - var high = encodedCenter.high; - var low = Cartesian4.fromElements(encodedCenter.low.x, encodedCenter.low.y, encodedCenter.low.z, boundingSphere.radius, scratchUpdatePolylineCartesian4); + function getDate(timeRaw) { + var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff; + try { + return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, + (time & 0x001F) * 2, 0); + } catch (e) { + } + } - var nearFarCartesian = scratchNearFarCartesian2; - nearFarCartesian.x = 0.0; - nearFarCartesian.y = Number.MAX_VALUE; + function readCommonHeader(entry, data, index, centralDirectory, onerror) { + entry.version = data.view.getUint16(index, true); + entry.bitFlag = data.view.getUint16(index + 2, true); + entry.compressionMethod = data.view.getUint16(index + 4, true); + entry.lastModDateRaw = data.view.getUint32(index + 6, true); + entry.lastModDate = getDate(entry.lastModDateRaw); + if ((entry.bitFlag & 0x01) === 0x01) { + onerror(ERR_ENCRYPTED); + return; + } + if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) { + entry.crc32 = data.view.getUint32(index + 10, true); + entry.compressedSize = data.view.getUint32(index + 14, true); + entry.uncompressedSize = data.view.getUint32(index + 18, true); + } + if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) { + onerror(ERR_ZIP64); + return; + } + entry.filenameLength = data.view.getUint16(index + 22, true); + entry.extraFieldLength = data.view.getUint16(index + 24, true); + } - var distanceDisplayCondition = polyline.distanceDisplayCondition; - if (defined(distanceDisplayCondition)) { - nearFarCartesian.x = distanceDisplayCondition.near; - nearFarCartesian.y = distanceDisplayCondition.far; - } + function createZipReader(reader, onerror) { + function Entry() { + } - batchTable.setBatchedAttribute(polylineBatchIndex, 0, widthShowCartesian); - batchTable.setBatchedAttribute(polylineBatchIndex, 1, colorCartesian); + Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) { + var that = this, worker; - if (batchTable.attributes.length > 2) { - batchTable.setBatchedAttribute(polylineBatchIndex, 2, high); - batchTable.setBatchedAttribute(polylineBatchIndex, 3, low); - batchTable.setBatchedAttribute(polylineBatchIndex, 4, nearFarCartesian); - } - } - }; + function terminate(callback, param) { + if (worker) + worker.terminate(); + worker = null; + if (callback) + callback(param); + } - var morphPositionScratch = new Cartesian3(); - var morphPrevPositionScratch = new Cartesian3(); - var morphNextPositionScratch = new Cartesian3(); - var morphVectorScratch = new Cartesian3(); + function testCrc32(crc32) { + var dataCrc32 = getDataHelper(4); + dataCrc32.view.setUint32(0, crc32); + return that.crc32 == dataCrc32.view.getUint32(0); + } - PolylineBucket.prototype.writeForMorph = function(positionArray, positionIndex) { - var modelMatrix = this.modelMatrix; - var polylines = this.polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - var polyline = polylines[i]; - var positions = polyline._segments.positions; - var lengths = polyline._segments.lengths; - var positionsLength = positions.length; + function getWriterData(uncompressedSize, crc32) { + if (checkCrc32 && !testCrc32(crc32)) + onreaderror(); + else + writer.getData(function(data) { + terminate(onend, data); + }); + } - var segmentIndex = 0; - var count = 0; + function onreaderror() { + terminate(onerror, ERR_READ_DATA); + } - for ( var j = 0; j < positionsLength; ++j) { - var prevPosition; - if (j === 0) { - if (polyline._loop) { - prevPosition = positions[positionsLength - 2]; - } else { - prevPosition = morphVectorScratch; - Cartesian3.subtract(positions[0], positions[1], prevPosition); - Cartesian3.add(positions[0], prevPosition, prevPosition); - } - } else { - prevPosition = positions[j - 1]; - } + function onwriteerror() { + terminate(onerror, ERR_WRITE_DATA); + } - prevPosition = Matrix4.multiplyByPoint(modelMatrix, prevPosition, morphPrevPositionScratch); + reader.readUint8Array(that.offset, 30, function(bytes) { + var data = getDataHelper(bytes.length, bytes), dataOffset; + if (data.view.getUint32(0) != 0x504b0304) { + onerror(ERR_BAD_FORMAT); + return; + } + readCommonHeader(that, data, 4, false, onerror); + dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength; + writer.init(function() { + if (that.compressionMethod === 0) + copy(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); + else + worker = inflate(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); + }, onwriteerror); + }, onreaderror); + }; - var position = Matrix4.multiplyByPoint(modelMatrix, positions[j], morphPositionScratch); + function seekEOCDR(offset, entriesCallback) { + reader.readUint8Array(reader.size - offset, offset, function(bytes) { + var dataView = getDataHelper(bytes.length, bytes).view; + if (dataView.getUint32(0) != 0x504b0506) { + seekEOCDR(offset + 1, entriesCallback); + } else { + entriesCallback(dataView); + } + }, function() { + onerror(ERR_READ); + }); + } - var nextPosition; - if (j === positionsLength - 1) { - if (polyline._loop) { - nextPosition = positions[1]; - } else { - nextPosition = morphVectorScratch; - Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], nextPosition); - Cartesian3.add(positions[positionsLength - 1], nextPosition, nextPosition); - } - } else { - nextPosition = positions[j + 1]; - } + return { + getEntries : function(callback) { + if (reader.size < 22) { + onerror(ERR_BAD_FORMAT); + return; + } + // look for End of central directory record + seekEOCDR(22, function(dataView) { + var datalength, fileslength; + datalength = dataView.getUint32(16, true); + fileslength = dataView.getUint16(8, true); + reader.readUint8Array(datalength, reader.size - datalength, function(bytes) { + var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes); + for (i = 0; i < fileslength; i++) { + entry = new Entry(); + if (data.view.getUint32(index) != 0x504b0102) { + onerror(ERR_BAD_FORMAT); + return; + } + readCommonHeader(entry, data, index + 6, true, onerror); + entry.commentLength = data.view.getUint16(index + 32, true); + entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10); + entry.offset = data.view.getUint32(index + 42, true); + filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength)); + entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename); + if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/") + entry.directory = true; + comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46 + + entry.filenameLength + entry.extraFieldLength + entry.commentLength)); + entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment); + entries.push(entry); + index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength; + } + callback(entries); + }, function() { + onerror(ERR_READ); + }); + }); + }, + close : function(callback) { + if (callback) + callback(); + } + }; + } - nextPosition = Matrix4.multiplyByPoint(modelMatrix, nextPosition, morphNextPositionScratch); + // ZipWriter - var segmentLength = lengths[segmentIndex]; - if (j === count + segmentLength) { - count += segmentLength; - ++segmentIndex; - } + function encodeUTF8(string) { + return unescape(encodeURIComponent(string)); + } - var segmentStart = j - count === 0; - var segmentEnd = j === count + lengths[segmentIndex] - 1; + function getBytes(str) { + var i, array = []; + for (i = 0; i < str.length; i++) + array.push(str.charCodeAt(i)); + return array; + } - var startK = (segmentStart) ? 2 : 0; - var endK = (segmentEnd) ? 2 : 4; + function createZipWriter(writer, onerror, dontDeflate) { + var worker, files = {}, filenames = [], datalength = 0; - for (var k = startK; k < endK; ++k) { - EncodedCartesian3.writeElements(position, positionArray, positionIndex); - EncodedCartesian3.writeElements(prevPosition, positionArray, positionIndex + 6); - EncodedCartesian3.writeElements(nextPosition, positionArray, positionIndex + 12); + function terminate(callback, message) { + if (worker) + worker.terminate(); + worker = null; + if (callback) + callback(message); + } - positionIndex += 6 * 3; - } - } - } - }; + function onwriteerror() { + terminate(onerror, ERR_WRITE); + } - var scratchSegmentLengths = new Array(1); + function onreaderror() { + terminate(onerror, ERR_READ_DATA); + } - PolylineBucket.prototype.updateIndices = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { - var vaCount = vertexArrayBuckets.length - 1; - var bucketLocator = new VertexArrayBucketLocator(0, offset, this); - vertexArrayBuckets[vaCount].push(bucketLocator); - var count = 0; - var indices = totalIndices[totalIndices.length - 1]; - var indicesCount = 0; - if (indices.length > 0) { - indicesCount = indices[indices.length - 1] + 1; - } - var polylines = this.polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { + return { + add : function(name, reader, onend, onprogress, options) { + var header, filename, date; - var polyline = polylines[i]; - polyline._locatorBuckets = []; + function writeHeader(callback) { + var data; + date = options.lastModDate || new Date(); + header = getDataHelper(26); + files[name] = { + headerArray : header.array, + directory : options.directory, + filename : filename, + offset : datalength, + comment : getBytes(encodeUTF8(options.comment || "")) + }; + header.view.setUint32(0, 0x14000808); + if (options.version) + header.view.setUint8(0, options.version); + if (!dontDeflate && options.level !== 0 && !options.directory) + header.view.setUint16(4, 0x0800); + header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true); + header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true); + header.view.setUint16(22, filename.length, true); + data = getDataHelper(30 + filename.length); + data.view.setUint32(0, 0x504b0304); + data.array.set(header.array, 4); + data.array.set(filename, 30); + datalength += data.array.length; + writer.writeUint8Array(data.array, callback, onwriteerror); + } - var segments; - if (this.mode === SceneMode.SCENE3D) { - segments = scratchSegmentLengths; - var positionsLength = polyline._actualPositions.length; - if (positionsLength > 0) { - segments[0] = positionsLength; - } else { - continue; - } - } else { - segments = polyline._segments.lengths; - } + function writeFooter(compressedLength, crc32) { + var footer = getDataHelper(16); + datalength += compressedLength || 0; + footer.view.setUint32(0, 0x504b0708); + if (typeof crc32 != "undefined") { + header.view.setUint32(10, crc32, true); + footer.view.setUint32(4, crc32, true); + } + if (reader) { + footer.view.setUint32(8, compressedLength, true); + header.view.setUint32(14, compressedLength, true); + footer.view.setUint32(12, reader.size, true); + header.view.setUint32(18, reader.size, true); + } + writer.writeUint8Array(footer.array, function() { + datalength += 16; + terminate(onend); + }, onwriteerror); + } - var numberOfSegments = segments.length; - if (numberOfSegments > 0) { - var segmentIndexCount = 0; - for ( var j = 0; j < numberOfSegments; ++j) { - var segmentLength = segments[j] - 1.0; - for ( var k = 0; k < segmentLength; ++k) { - if (indicesCount + 4 > CesiumMath.SIXTY_FOUR_KILOBYTES) { - polyline._locatorBuckets.push({ - locator : bucketLocator, - count : segmentIndexCount - }); - segmentIndexCount = 0; - vertexBufferOffset.push(4); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - count = 0; - offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; - } + function writeFile() { + options = options || {}; + name = name.trim(); + if (options.directory && name.charAt(name.length - 1) != "/") + name += "/"; + if (files.hasOwnProperty(name)) { + onerror(ERR_DUPLICATED_NAME); + return; + } + filename = getBytes(encodeUTF8(name)); + filenames.push(name); + writeHeader(function() { + if (reader) + if (dontDeflate || options.level === 0) + copy(reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror); + else + worker = deflate(reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror); + else + writeFooter(); + }, onwriteerror); + } - indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + if (reader) + reader.init(writeFile, onreaderror); + else + writeFile(); + }, + close : function(callback) { + var data, length = 0, index = 0, indexFilename, file; + for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { + file = files[filenames[indexFilename]]; + length += 46 + file.filename.length + file.comment.length; + } + data = getDataHelper(length + 22); + for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { + file = files[filenames[indexFilename]]; + data.view.setUint32(index, 0x504b0102); + data.view.setUint16(index + 4, 0x1400); + data.array.set(file.headerArray, index + 6); + data.view.setUint16(index + 32, file.comment.length, true); + if (file.directory) + data.view.setUint8(index + 38, 0x10); + data.view.setUint32(index + 42, file.offset, true); + data.array.set(file.filename, index + 46); + data.array.set(file.comment, index + 46 + file.filename.length); + index += 46 + file.filename.length + file.comment.length; + } + data.view.setUint32(index, 0x504b0506); + data.view.setUint16(index + 8, filenames.length, true); + data.view.setUint16(index + 10, filenames.length, true); + data.view.setUint32(index + 12, length, true); + data.view.setUint32(index + 16, datalength, true); + writer.writeUint8Array(data.array, function() { + terminate(function() { + writer.getData(callback); + }); + }, onwriteerror); + } + }; + } - segmentIndexCount += 6; - count += 6; - offset += 6; - indicesCount += 4; - } - } + obj.zip = { + Reader : Reader, + Writer : Writer, + BlobReader : BlobReader, + Data64URIReader : Data64URIReader, + TextReader : TextReader, + BlobWriter : BlobWriter, + Data64URIWriter : Data64URIWriter, + TextWriter : TextWriter, + createReader : function(reader, callback, onerror) { + reader.init(function() { + callback(createZipReader(reader, onerror)); + }, onerror); + }, + createWriter : function(writer, callback, onerror, dontDeflate) { + writer.init(function() { + callback(createZipWriter(writer, onerror, dontDeflate)); + }, onerror); + }, + useWebWorkers : true + }; - polyline._locatorBuckets.push({ - locator : bucketLocator, - count : segmentIndexCount - }); + var workerScriptsPath; - if (indicesCount + 4 > CesiumMath.SIXTY_FOUR_KILOBYTES) { - vertexBufferOffset.push(0); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - offset = 0; - count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; + defineProperties(obj.zip, { + 'workerScriptsPath' : { + get : function() { + if (typeof workerScriptsPath === 'undefined') { + workerScriptsPath = buildModuleUrl('ThirdParty/Workers/'); } + return workerScriptsPath; } - polyline._clean(); - } - bucketLocator.count = count; - return offset; - }; - - PolylineBucket.prototype.getPolylineStartIndex = function(polyline) { - var polylines = this.polylines; - var positionIndex = 0; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - var p = polylines[i]; - if (p === polyline) { - break; - } - positionIndex += p._actualLength; } - return positionIndex; - }; - - var scratchSegments = { - positions : undefined, - lengths : undefined - }; - var scratchLengths = new Array(1); - var pscratch = new Cartesian3(); - var scratchCartographic = new Cartographic(); + }); - PolylineBucket.prototype.getSegments = function(polyline, projection) { - var positions = polyline._actualPositions; +})(tmp); - if (this.mode === SceneMode.SCENE3D) { - scratchLengths[0] = positions.length; - scratchSegments.positions = positions; - scratchSegments.lengths = scratchLengths; - return scratchSegments; - } + return tmp.zip; +}); - if (intersectsIDL(polyline)) { - positions = polyline._segments.positions; - } +define('DataSources/KmlLookAt',[], function() { + 'use strict'; + /** + * @alias KmlLookAt + * @constructor + * + * @param {Cartesian3} position camera position + * @param {HeadingPitchRange} headingPitchRange camera orientation + */ + function KmlLookAt(position, headingPitchRange) { + this.position = position; + this.headingPitchRange = headingPitchRange; + } - var ellipsoid = projection.ellipsoid; - var newPositions = []; - var modelMatrix = this.modelMatrix; - var length = positions.length; - var position; - var p = pscratch; + return KmlLookAt; +}); - for ( var n = 0; n < length; ++n) { - position = positions[n]; - p = Matrix4.multiplyByPoint(modelMatrix, position, p); - newPositions.push(projection.project(ellipsoid.cartesianToCartographic(p, scratchCartographic))); - } +define('DataSources/KmlTour',[ + '../Core/Event', + '../Core/defined' + ], function( + Event, + defined + ) { + 'use strict'; + /** + * @alias KMLTour + * @constructor + * + * @param {String} name name parsed from KML + * @param {String} id id parsed from KML + * @param {Array} playlist array with KMLTourFlyTos, KMLTourWaits and KMLTourSoundCues + */ + function KmlTour(name, id) { + /** + * Id of kml gx:Tour entry + */ + this.id = id; + /** + * Tour name + */ + this.name = name; + /** + * Index of current entry from playlist + * @type Number + */ + this.playlistIndex = 0; + /** + * Array of playlist entries + * @type Array + */ + this.playlist = []; + /** + * Event will be called when tour starts to play, + * before any playlist entry starts to play. + * @type Event + */ + this.tourStart = new Event(); + /** + * Event will be called when all playlist entries are + * played, or tour playback being canceled. + * + * If tour playback was terminated, event callback will + * be called with terminated=true parameter. + * @type Event + */ + this.tourEnd = new Event(); + /** + * Event will be called when entry from playlist starts to play. + * + * Event callback will be called with curent entry as first parameter. + * @type Event + */ + this.entryStart = new Event(); + /** + * Event will be called when entry from playlist ends to play. + * + * Event callback will be called with following parameters: + * 1. entry - entry + * 2. terminated - true if playback was terminated by calling {@link KmlTour#stop} + * @type Event + */ + this.entryEnd = new Event(); - if (newPositions.length > 0) { - polyline._boundingVolume2D = BoundingSphere.fromPoints(newPositions, polyline._boundingVolume2D); - var center2D = polyline._boundingVolume2D.center; - polyline._boundingVolume2D.center = new Cartesian3(center2D.z, center2D.x, center2D.y); - } + this._activeEntries = []; + } - scratchSegments.positions = newPositions; - scratchSegments.lengths = polyline._segments.lengths; - return scratchSegments; + /** + * Add entry to this tour playlist. + * + * @param {KmlTourFlyTo|KmlTourWait} entry an entry to add to the playlist. + */ + KmlTour.prototype.addPlaylistEntry = function(entry) { + this.playlist.push(entry); }; - var scratchPositionsArray; - - PolylineBucket.prototype.writeUpdate = function(index, polyline, positionBuffer, projection) { - var mode = this.mode; - var maxLon = projection.ellipsoid.maximumRadius * CesiumMath.PI; - - var positionsLength = polyline._actualLength; - if (positionsLength) { - index += this.getPolylineStartIndex(polyline); - - var positionArray = scratchPositionsArray; - var positionsArrayLength = 6 * positionsLength * 3; + /** + * Play this tour. + * + * @param {Viewer} viewer viewer widget. + * @param {Object} [cameraOptions] these options will be merged with {@link Camera#flyTo} + * options for FlyTo playlist entries. + */ + KmlTour.prototype.play = function(viewer, cameraOptions) { + this.tourStart.raiseEvent(); - if (!defined(positionArray) || positionArray.length < positionsArrayLength) { - positionArray = scratchPositionsArray = new Float32Array(positionsArrayLength); - } else if (positionArray.length > positionsArrayLength) { - positionArray = new Float32Array(positionArray.buffer, 0, positionsArrayLength); + var tour = this; + playEntry.call(this, viewer, cameraOptions, function(terminated) { + tour.playlistIndex = 0; + // Stop nonblocking entries + if (!terminated) { + cancelAllEntries(tour._activeEntries); } + tour.tourEnd.raiseEvent(terminated); + }); + }; - var segments = this.getSegments(polyline, projection); - var positions = segments.positions; - var lengths = segments.lengths; - - var positionIndex = 0; - var segmentIndex = 0; - var count = 0; - var position; - - positionsLength = positions.length; - for ( var i = 0; i < positionsLength; ++i) { - if (i === 0) { - if (polyline._loop) { - position = positions[positionsLength - 2]; - } else { - position = scratchWriteVector; - Cartesian3.subtract(positions[0], positions[1], position); - Cartesian3.add(positions[0], position, position); - } - } else { - position = positions[i - 1]; - } - - Cartesian3.clone(position, scratchWritePrevPosition); - Cartesian3.clone(positions[i], scratchWritePosition); - - if (i === positionsLength - 1) { - if (polyline._loop) { - position = positions[1]; - } else { - position = scratchWriteVector; - Cartesian3.subtract(positions[positionsLength - 1], positions[positionsLength - 2], position); - Cartesian3.add(positions[positionsLength - 1], position, position); - } - } else { - position = positions[i + 1]; - } - - Cartesian3.clone(position, scratchWriteNextPosition); - - var segmentLength = lengths[segmentIndex]; - if (i === count + segmentLength) { - count += segmentLength; - ++segmentIndex; - } - - var segmentStart = i - count === 0; - var segmentEnd = i === count + lengths[segmentIndex] - 1; - - if (mode === SceneMode.SCENE2D) { - scratchWritePrevPosition.z = 0.0; - scratchWritePosition.z = 0.0; - scratchWriteNextPosition.z = 0.0; - } + /** + * Stop curently playing tour. + */ + KmlTour.prototype.stop = function() { + cancelAllEntries(this._activeEntries); + }; - if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { - if ((segmentStart || segmentEnd) && maxLon - Math.abs(scratchWritePosition.x) < 1.0) { - if ((scratchWritePosition.x < 0.0 && scratchWritePrevPosition.x > 0.0) || - (scratchWritePosition.x > 0.0 && scratchWritePrevPosition.x < 0.0)) { - Cartesian3.clone(scratchWritePosition, scratchWritePrevPosition); - } + /** + * Stop all activeEntries. + * @param {Array} activeEntries + */ + function cancelAllEntries(activeEntries) { + for(var entry = activeEntries.pop(); entry !== undefined; entry = activeEntries.pop()) { + entry.stop(); + } + } - if ((scratchWritePosition.x < 0.0 && scratchWriteNextPosition.x > 0.0) || - (scratchWritePosition.x > 0.0 && scratchWriteNextPosition.x < 0.0)) { - Cartesian3.clone(scratchWritePosition, scratchWriteNextPosition); - } + /** + * Play playlist entry. + * This function is called recursevly with playNext + * and iterates over all entries from playlist. + * + * @param {ViewerWidget} viewer Cesium viewer. + * @param {Object} cameraOptions see {@link Camera#flyTo}. + * @param {Function} allDone a function will be called when all entries from playlist + * being played or user call {@link KmlTour#stop}. + */ + function playEntry(viewer, cameraOptions, allDone) { + var entry = this.playlist[this.playlistIndex]; + if (entry) { + var _playNext = playNext.bind(this, viewer, cameraOptions, allDone); + this._activeEntries.push(entry); + this.entryStart.raiseEvent(entry); + if (entry.blocking) { + entry.play(_playNext, viewer.scene.camera, cameraOptions); + } + else { + var tour = this; + entry.play(function() { + tour.entryEnd.raiseEvent(entry); + var indx = tour._activeEntries.indexOf(entry); + if (indx >= 0) { + tour._activeEntries.splice(indx, 1); } - } + }); + _playNext(viewer, cameraOptions, allDone); + } + } + else if(defined(allDone)) { + allDone(false); + } + } - var startJ = (segmentStart) ? 2 : 0; - var endJ = (segmentEnd) ? 2 : 4; + /** + * Increment playlistIndex and call playEntry + * if terminated isn't true. + * + * @param {ViewerWidget} viewer passed for recursion. + * @param {Object} cameraOptions passed for recursion. + * @param {Function} allDone passed for recursion. + * @param {Boolean} terminated true if active entry was terminated, + * and the whole tour should be terminated. + */ + function playNext(viewer, cameraOptions, allDone, terminated) { + var entry = this.playlist[this.playlistIndex]; + this.entryEnd.raiseEvent(entry, terminated); - for (var j = startJ; j < endJ; ++j) { - EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); - EncodedCartesian3.writeElements(scratchWritePrevPosition, positionArray, positionIndex + 6); - EncodedCartesian3.writeElements(scratchWriteNextPosition, positionArray, positionIndex + 12); - positionIndex += 6 * 3; - } + if (terminated) { + allDone(terminated); + } + else { + var indx = this._activeEntries.indexOf(entry); + if (indx >= 0) { + this._activeEntries.splice(indx, 1); } - - positionBuffer.copyFromArrayView(positionArray, 6 * 3 * Float32Array.BYTES_PER_ELEMENT * index); + this.playlistIndex++; + playEntry.call(this, viewer, cameraOptions, allDone); } - }; + } - return PolylineCollection; + return KmlTour; }); -define('DataSources/ScaledPositionProperty',[ +define('DataSources/KmlTourFlyTo',[ '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/Event', - '../Core/ReferenceFrame', - './Property' + '../Core/combine', + '../Core/BoundingSphere', + '../Core/EasingFunction' ], function( defined, - defineProperties, - DeveloperError, - Ellipsoid, - Event, - ReferenceFrame, - Property) { + combine, + BoundingSphere, + EasingFunction + ) { 'use strict'; + /** + * @alias KmlTourFlyTo + * @constructor + * + * @param {Number} duration entry duration + * @param {String} flyToMode KML fly to mode: bounce, smooth, etc + * @param {KmlCamera|KmlLookAt} view KmlCamera or KmlLookAt + */ + function KmlTourFlyTo(duration, flyToMode, view) { + this.type = 'KmlTourFlyTo'; + this.blocking = true; + this.activeCamera = null; + this.activeCallback = null; + + this.duration = duration; + this.view = view; + this.flyToMode = flyToMode; + } + + /** + * Play this playlist entry + * + * @param {KmlTourFlyTo~DoneCallback} done function which will be called when playback ends + * @param {Camera} camera Cesium camera + * @param {Object} [cameraOptions] which will be merged with camera flyTo options. See {@link Camera#flyTo} + */ + KmlTourFlyTo.prototype.play = function(done, camera, cameraOptions) { + this.activeCamera = camera; + if (defined(done) && done !== null) { + var self = this; + this.activeCallback = function(terminated) { + delete self.activeCallback; + delete self.activeCamera; + done(defined(terminated) ? false : terminated); + }; + } + + var options = this.getCameraOptions(cameraOptions); + if (this.view.headingPitchRoll) { + camera.flyTo(options); + } + else if (this.view.headingPitchRange) { + var target = new BoundingSphere(this.view.position); + camera.flyToBoundingSphere(target, options); + } + }; /** - * This is a temporary class for scaling position properties to the WGS84 surface. - * It will go away or be refactored to support data with arbitrary height references. - * @private + * Stop execution of curent entry. Cancel camera flyTo */ - function ScaledPositionProperty(value) { - this._definitionChanged = new Event(); - this._value = undefined; - this._removeSubscription = undefined; - this.setValue(value); - } - - defineProperties(ScaledPositionProperty.prototype, { - isConstant : { - get : function() { - return Property.isConstant(this._value); - } - }, - definitionChanged : { - get : function() { - return this._definitionChanged; - } - }, - referenceFrame : { - get : function() { - return defined(this._value) ? this._value.referenceFrame : ReferenceFrame.FIXED; - } + KmlTourFlyTo.prototype.stop = function() { + if (defined(this.activeCamera)) { + this.activeCamera.cancelFlight(); + } + if (defined(this.activeCallback)) { + this.activeCallback(true); } - }); - - ScaledPositionProperty.prototype.getValue = function(time, result) { - return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); }; - ScaledPositionProperty.prototype.setValue = function(value) { - if (this._value !== value) { - this._value = value; - - if (defined(this._removeSubscription)) { - this._removeSubscription(); - this._removeSubscription = undefined; - } + /** + * Returns options for {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} + * depends on this.view type. + * + * @param {Object} cameraOptions options to merge with generated. See {@link Camera#flyTo} + * @returns {Object} {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} options + */ + KmlTourFlyTo.prototype.getCameraOptions = function(cameraOptions) { + var options = { + duration: this.duration + }; - if (defined(value)) { - this._removeSubscription = value.definitionChanged.addEventListener(this._raiseDefinitionChanged, this); - } - this._definitionChanged.raiseEvent(this); + if (defined(this.activeCallback)) { + options.complete = this.activeCallback; } - }; - ScaledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + if (this.flyToMode === 'smooth' ) { + options.easingFunction = EasingFunction.LINEAR_NONE; } - if (!defined(referenceFrame)) { - throw new DeveloperError('referenceFrame is required.'); + + if (this.view.headingPitchRoll) { + options.destination = this.view.position; + options.orientation = this.view.headingPitchRoll; } - - if (!defined(this._value)) { - return undefined; + else if (this.view.headingPitchRange) { + options.offset = this.view.headingPitchRange; } - result = this._value.getValueInReferenceFrame(time, referenceFrame, result); - return defined(result) ? Ellipsoid.WGS84.scaleToGeodeticSurface(result, result) : undefined; + if (defined(cameraOptions)) { + options = combine(options, cameraOptions); + } + return options; }; - ScaledPositionProperty.prototype.equals = function(other) { - return this === other || (other instanceof ScaledPositionProperty && this._value === other._value); + /** + * A function that will be executed when the flight completes. + * @callback KmlTourFlyTo~DoneCallback + * + * @param {Boolean} terminated true if {@link KmlTourFlyTo#stop} was + * called before entry done playback. + */ + + return KmlTourFlyTo; +}); + +define('DataSources/KmlTourWait',[ + '../Core/defined' + ], function( + defined + ) { + 'use strict'; + /** + * @alias KmlTourWait + * @constructor + * + * @param {Number} duration entry duration + */ + function KmlTourWait(duration) { + this.type = 'KmlTourWait'; + this.blocking = true; + this.duration = duration; + + this.timeout = null; + } + + /** + * Play this playlist entry + * + * @param {KmlTourWait~DoneCallback} done function which will be called when playback ends + */ + KmlTourWait.prototype.play = function(done) { + var self = this; + this.activeCallback = done; + this.timeout = setTimeout(function() { + delete self.activeCallback; + done(false); + }, this.duration * 1000); }; - ScaledPositionProperty.prototype._raiseDefinitionChanged = function() { - this._definitionChanged.raiseEvent(this); + /** + * Stop execution of curent entry, cancel curent timeout + */ + KmlTourWait.prototype.stop = function() { + clearTimeout(this.timeout); + if (defined(this.activeCallback)) { + this.activeCallback(true); + } }; - return ScaledPositionProperty; + /** + * A function which will be called when playback ends. + * + * @callback KmlTourWait~DoneCallback + * @param {Boolean} terminated true if {@link KmlTourWait#stop} was + * called before entry done playback. + */ + + return KmlTourWait; }); -define('DataSources/PathVisualizer',[ +define('DataSources/KmlDataSource',[ '../Core/AssociativeArray', + '../Core/BoundingRectangle', + '../Core/Cartesian2', '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/ClockRange', + '../Core/ClockStep', + '../Core/Color', + '../Core/createGuid', + '../Core/defaultValue', '../Core/defined', - '../Core/destroyObject', + '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/DeveloperError', + '../Core/Ellipsoid', + '../Core/Event', + '../Core/getExtensionFromUri', + '../Core/getFilenameFromUri', + '../Core/Iso8601', '../Core/JulianDate', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/ReferenceFrame', + '../Core/Math', + '../Core/NearFarScalar', + '../Core/objectToQuery', + '../Core/oneTimeWarning', + '../Core/PinBuilder', + '../Core/PolygonHierarchy', + '../Core/queryToObject', + '../Core/Rectangle', + '../Core/Resource', + '../Core/RuntimeError', '../Core/TimeInterval', - '../Core/Transforms', - '../Scene/PolylineCollection', + '../Core/TimeIntervalCollection', + '../Core/HeadingPitchRoll', + '../Core/HeadingPitchRange', + '../Scene/HeightReference', + '../Scene/HorizontalOrigin', + '../Scene/LabelStyle', '../Scene/SceneMode', + '../ThirdParty/Autolinker', + '../ThirdParty/Uri', + '../ThirdParty/when', + '../ThirdParty/zip', + './BillboardGraphics', './CompositePositionProperty', - './ConstantPositionProperty', - './MaterialProperty', - './Property', + './CorridorGraphics', + './DataSource', + './DataSourceClock', + './Entity', + './EntityCluster', + './EntityCollection', + './LabelGraphics', + './PathGraphics', + './PolygonGraphics', + './PolylineGraphics', + './PositionPropertyArray', + './RectangleGraphics', './ReferenceProperty', './SampledPositionProperty', './ScaledPositionProperty', - './TimeIntervalCollectionPositionProperty' + './TimeIntervalCollectionProperty', + './WallGraphics', + './KmlLookAt', + './KmlCamera', + './KmlTour', + './KmlTourFlyTo', + './KmlTourWait' ], function( AssociativeArray, + BoundingRectangle, + Cartesian2, Cartesian3, + Cartographic, + ClockRange, + ClockStep, + Color, + createGuid, + defaultValue, defined, - destroyObject, + defineProperties, + deprecationWarning, DeveloperError, + Ellipsoid, + Event, + getExtensionFromUri, + getFilenameFromUri, + Iso8601, JulianDate, - Matrix3, - Matrix4, - ReferenceFrame, + CesiumMath, + NearFarScalar, + objectToQuery, + oneTimeWarning, + PinBuilder, + PolygonHierarchy, + queryToObject, + Rectangle, + Resource, + RuntimeError, TimeInterval, - Transforms, - PolylineCollection, + TimeIntervalCollection, + HeadingPitchRoll, + HeadingPitchRange, + HeightReference, + HorizontalOrigin, + LabelStyle, SceneMode, + Autolinker, + Uri, + when, + zip, + BillboardGraphics, CompositePositionProperty, - ConstantPositionProperty, - MaterialProperty, - Property, + CorridorGraphics, + DataSource, + DataSourceClock, + Entity, + EntityCluster, + EntityCollection, + LabelGraphics, + PathGraphics, + PolygonGraphics, + PolylineGraphics, + PositionPropertyArray, + RectangleGraphics, ReferenceProperty, SampledPositionProperty, ScaledPositionProperty, - TimeIntervalCollectionPositionProperty) { + TimeIntervalCollectionProperty, + WallGraphics, + KmlLookAt, + KmlCamera, + KmlTour, + KmlTourFlyTo, + KmlTourWait) { 'use strict'; - var defaultResolution = 60.0; - var defaultWidth = 1.0; - - var scratchTimeInterval = new TimeInterval(); - var subSampleCompositePropertyScratch = new TimeInterval(); - var subSampleIntervalPropertyScratch = new TimeInterval(); - - function EntityData(entity) { - this.entity = entity; - this.polyline = undefined; - this.index = undefined; - this.updater = undefined; + // IE 8 doesn't have a DOM parser and can't run Cesium anyway, so just bail. + if (typeof DOMParser === 'undefined') { + return {}; } - function subSampleSampledProperty(property, start, stop, times, updateTime, referenceFrame, maximumStep, startingIndex, result) { - var r = startingIndex; - //Always step exactly on start (but only use it if it exists.) - var tmp; - tmp = property.getValueInReferenceFrame(start, referenceFrame, result[r]); - if (defined(tmp)) { - result[r++] = tmp; - } - - var steppedOnNow = !defined(updateTime) || JulianDate.lessThanOrEquals(updateTime, start) || JulianDate.greaterThanOrEquals(updateTime, stop); - - //Iterate over all interval times and add the ones that fall in our - //time range. Note that times can contain data outside of - //the intervals range. This is by design for use with interpolation. - var t = 0; - var len = times.length; - var current = times[t]; - var loopStop = stop; - var sampling = false; - var sampleStepsToTake; - var sampleStepsTaken; - var sampleStepSize; - - while (t < len) { - if (!steppedOnNow && JulianDate.greaterThanOrEquals(current, updateTime)) { - tmp = property.getValueInReferenceFrame(updateTime, referenceFrame, result[r]); - if (defined(tmp)) { - result[r++] = tmp; - } - steppedOnNow = true; - } - if (JulianDate.greaterThan(current, start) && JulianDate.lessThan(current, loopStop) && !current.equals(updateTime)) { - tmp = property.getValueInReferenceFrame(current, referenceFrame, result[r]); - if (defined(tmp)) { - result[r++] = tmp; - } - } - - if (t < (len - 1)) { - if (maximumStep > 0 && !sampling) { - var next = times[t + 1]; - var secondsUntilNext = JulianDate.secondsDifference(next, current); - sampling = secondsUntilNext > maximumStep; + //This is by no means an exhaustive list of MIME types. + //The purpose of this list is to be able to accurately identify content embedded + //in KMZ files. Eventually, we can make this configurable by the end user so they can add + //there own content types if they have KMZ files that require it. + var MimeTypes = { + avi : 'video/x-msvideo', + bmp : 'image/bmp', + bz2 : 'application/x-bzip2', + chm : 'application/vnd.ms-htmlhelp', + css : 'text/css', + csv : 'text/csv', + doc : 'application/msword', + dvi : 'application/x-dvi', + eps : 'application/postscript', + flv : 'video/x-flv', + gif : 'image/gif', + gz : 'application/x-gzip', + htm : 'text/html', + html : 'text/html', + ico : 'image/vnd.microsoft.icon', + jnlp : 'application/x-java-jnlp-file', + jpeg : 'image/jpeg', + jpg : 'image/jpeg', + m3u : 'audio/x-mpegurl', + m4v : 'video/mp4', + mathml : 'application/mathml+xml', + mid : 'audio/midi', + midi : 'audio/midi', + mov : 'video/quicktime', + mp3 : 'audio/mpeg', + mp4 : 'video/mp4', + mp4v : 'video/mp4', + mpeg : 'video/mpeg', + mpg : 'video/mpeg', + odp : 'application/vnd.oasis.opendocument.presentation', + ods : 'application/vnd.oasis.opendocument.spreadsheet', + odt : 'application/vnd.oasis.opendocument.text', + ogg : 'application/ogg', + pdf : 'application/pdf', + png : 'image/png', + pps : 'application/vnd.ms-powerpoint', + ppt : 'application/vnd.ms-powerpoint', + ps : 'application/postscript', + qt : 'video/quicktime', + rdf : 'application/rdf+xml', + rss : 'application/rss+xml', + rtf : 'application/rtf', + svg : 'image/svg+xml', + swf : 'application/x-shockwave-flash', + text : 'text/plain', + tif : 'image/tiff', + tiff : 'image/tiff', + txt : 'text/plain', + wav : 'audio/x-wav', + wma : 'audio/x-ms-wma', + wmv : 'video/x-ms-wmv', + xml : 'application/xml', + zip : 'application/zip', - if (sampling) { - sampleStepsToTake = Math.ceil(secondsUntilNext / maximumStep); - sampleStepsTaken = 0; - sampleStepSize = secondsUntilNext / Math.max(sampleStepsToTake, 2); - sampleStepsToTake = Math.max(sampleStepsToTake - 1, 1); - } - } + detectFromFilename : function(filename) { + var ext = filename.toLowerCase(); + ext = getExtensionFromUri(ext); + return MimeTypes[ext]; + } + }; - if (sampling && sampleStepsTaken < sampleStepsToTake) { - current = JulianDate.addSeconds(current, sampleStepSize, new JulianDate()); - sampleStepsTaken++; - continue; - } + var parser = new DOMParser(); + var autolinker = new Autolinker({ + stripPrefix : false, + twitter : false, + email : false, + replaceFn : function(linker, match) { + if (!match.protocolUrlMatch) { + //Prevent matching of non-explicit urls. + //i.e. foo.id won't match but http://foo.id will + return false; } - sampling = false; - t++; - current = times[t]; } + }); - //Always step exactly on stop (but only use it if it exists.) - tmp = property.getValueInReferenceFrame(stop, referenceFrame, result[r]); - if (defined(tmp)) { - result[r++] = tmp; - } + var BILLBOARD_SIZE = 32; - return r; + var BILLBOARD_NEAR_DISTANCE = 2414016; + var BILLBOARD_NEAR_RATIO = 1.0; + var BILLBOARD_FAR_DISTANCE = 1.6093e+7; + var BILLBOARD_FAR_RATIO = 0.1; + + function isZipFile(blob) { + var magicBlob = blob.slice(0, Math.min(4, blob.size)); + var deferred = when.defer(); + var reader = new FileReader(); + reader.addEventListener('load', function() { + deferred.resolve(new DataView(reader.result).getUint32(0, false) === 0x504b0304); + }); + reader.addEventListener('error', function() { + deferred.reject(reader.error); + }); + reader.readAsArrayBuffer(magicBlob); + return deferred.promise; } - function subSampleGenericProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { - var tmp; - var i = 0; - var index = startingIndex; - var time = start; - var stepSize = Math.max(maximumStep, 60); - var steppedOnNow = !defined(updateTime) || JulianDate.lessThanOrEquals(updateTime, start) || JulianDate.greaterThanOrEquals(updateTime, stop); - while (JulianDate.lessThan(time, stop)) { - if (!steppedOnNow && JulianDate.greaterThanOrEquals(time, updateTime)) { - steppedOnNow = true; - tmp = property.getValueInReferenceFrame(updateTime, referenceFrame, result[index]); - if (defined(tmp)) { - result[index] = tmp; - index++; - } - } - tmp = property.getValueInReferenceFrame(time, referenceFrame, result[index]); - if (defined(tmp)) { - result[index] = tmp; - index++; - } - i++; - time = JulianDate.addSeconds(start, stepSize * i, new JulianDate()); - } - //Always sample stop. - tmp = property.getValueInReferenceFrame(stop, referenceFrame, result[index]); - if (defined(tmp)) { - result[index] = tmp; - index++; - } - return index; + function readBlobAsText(blob) { + var deferred = when.defer(); + var reader = new FileReader(); + reader.addEventListener('load', function() { + deferred.resolve(reader.result); + }); + reader.addEventListener('error', function() { + deferred.reject(reader.error); + }); + reader.readAsText(blob); + return deferred.promise; } - function subSampleIntervalProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { - subSampleIntervalPropertyScratch.start = start; - subSampleIntervalPropertyScratch.stop = stop; + function insertNamespaces(text) { + var namespaceMap = { + xsi : 'http://www.w3.org/2001/XMLSchema-instance' + }; + var firstPart, lastPart, reg, declaration; - var index = startingIndex; - var intervals = property.intervals; - for (var i = 0; i < intervals.length; i++) { - var interval = intervals.get(i); - if (!TimeInterval.intersect(interval, subSampleIntervalPropertyScratch, scratchTimeInterval).isEmpty) { - var time = interval.start; - if (!interval.isStartIncluded) { - if (interval.isStopIncluded) { - time = interval.stop; - } else { - time = JulianDate.addSeconds(interval.start, JulianDate.secondsDifference(interval.stop, interval.start) / 2, new JulianDate()); + for (var key in namespaceMap) { + if (namespaceMap.hasOwnProperty(key)) { + reg = RegExp('[< ]' + key + ':'); + declaration = 'xmlns:' + key + '='; + if (reg.test(text) && text.indexOf(declaration) === -1) { + if (!defined(firstPart)) { + firstPart = text.substr(0, text.indexOf('<kml') + 4); + lastPart = text.substr(firstPart.length); } - } - var tmp = property.getValueInReferenceFrame(time, referenceFrame, result[index]); - if (defined(tmp)) { - result[index] = tmp; - index++; + firstPart += ' ' + declaration + '"' + namespaceMap[key] + '"'; } } } - return index; - } - function subSampleConstantProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { - var tmp = property.getValueInReferenceFrame(start, referenceFrame, result[startingIndex]); - if (defined(tmp)) { - result[startingIndex++] = tmp; + if (defined(firstPart)) { + text = firstPart + lastPart; } - return startingIndex; - } - - function subSampleCompositeProperty(property, start, stop, updateTime, referenceFrame, maximumStep, startingIndex, result) { - subSampleCompositePropertyScratch.start = start; - subSampleCompositePropertyScratch.stop = stop; - - var index = startingIndex; - var intervals = property.intervals; - for (var i = 0; i < intervals.length; i++) { - var interval = intervals.get(i); - if (!TimeInterval.intersect(interval, subSampleCompositePropertyScratch, scratchTimeInterval).isEmpty) { - var intervalStart = interval.start; - var intervalStop = interval.stop; - var sampleStart = start; - if (JulianDate.greaterThan(intervalStart, sampleStart)) { - sampleStart = intervalStart; - } + return text; + } - var sampleStop = stop; - if (JulianDate.lessThan(intervalStop, sampleStop)) { - sampleStop = intervalStop; - } + function removeDuplicateNamespaces(text) { + var index = text.indexOf('xmlns:'); + var endDeclaration = text.indexOf('>', index); + var namespace, startIndex, endIndex; - index = reallySubSample(interval.data, sampleStart, sampleStop, updateTime, referenceFrame, maximumStep, index, result); + while ((index !== -1) && (index < endDeclaration)) { + namespace = text.slice(index, text.indexOf('\"', index)); + startIndex = index; + index = text.indexOf(namespace, index + 1); + if (index !== -1) { + endIndex = text.indexOf('\"', (text.indexOf('\"', index) + 1)); + text = text.slice(0, index -1) + text.slice(endIndex + 1, text.length); + index = text.indexOf('xmlns:', startIndex - 1); + } else { + index = text.indexOf('xmlns:', startIndex + 1); } } - return index; - } - - function reallySubSample(property, start, stop, updateTime, referenceFrame, maximumStep, index, result) { - //Unwrap any references until we have the actual property. - while (property instanceof ReferenceProperty) { - property = property.resolvedProperty; - } - if (property instanceof SampledPositionProperty) { - var times = property._property._times; - index = subSampleSampledProperty(property, start, stop, times, updateTime, referenceFrame, maximumStep, index, result); - } else if (property instanceof CompositePositionProperty) { - index = subSampleCompositeProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); - } else if (property instanceof TimeIntervalCollectionPositionProperty) { - index = subSampleIntervalProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); - } else if (property instanceof ConstantPositionProperty || - (property instanceof ScaledPositionProperty && Property.isConstant(property))) { - index = subSampleConstantProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); - } else { - //Fallback to generic sampling. - index = subSampleGenericProperty(property, start, stop, updateTime, referenceFrame, maximumStep, index, result); - } - return index; + return text; } - function subSample(property, start, stop, updateTime, referenceFrame, maximumStep, result) { - if (!defined(result)) { - result = []; - } - - var length = reallySubSample(property, start, stop, updateTime, referenceFrame, maximumStep, 0, result); - result.length = length; - return result; + function loadXmlFromZip(entry, uriResolver, deferred) { + entry.getData(new zip.TextWriter(), function(text) { + text = insertNamespaces(text); + text = removeDuplicateNamespaces(text); + uriResolver.kml = parser.parseFromString(text, 'application/xml'); + deferred.resolve(); + }); } - var toFixedScratch = new Matrix3(); - function PolylineUpdater(scene, referenceFrame) { - this._unusedIndexes = []; - this._polylineCollection = new PolylineCollection(); - this._scene = scene; - this._referenceFrame = referenceFrame; - scene.primitives.add(this._polylineCollection); + function loadDataUriFromZip(entry, uriResolver, deferred) { + var mimeType = defaultValue(MimeTypes.detectFromFilename(entry.filename), 'application/octet-stream'); + entry.getData(new zip.Data64URIWriter(mimeType), function(dataUri) { + uriResolver[entry.filename] = dataUri; + deferred.resolve(); + }); } - PolylineUpdater.prototype.update = function(time) { - if (this._referenceFrame === ReferenceFrame.INERTIAL) { - var toFixed = Transforms.computeIcrfToFixedMatrix(time, toFixedScratch); - if (!defined(toFixed)) { - toFixed = Transforms.computeTemeToPseudoFixedMatrix(time, toFixedScratch); - } - Matrix4.fromRotationTranslation(toFixed, Cartesian3.ZERO, this._polylineCollection.modelMatrix); - } - }; - - PolylineUpdater.prototype.updateObject = function(time, item) { - var entity = item.entity; - var pathGraphics = entity._path; - var positionProperty = entity._position; - - var sampleStart; - var sampleStop; - var showProperty = pathGraphics._show; - var polyline = item.polyline; - var show = entity.isShowing && (!defined(showProperty) || showProperty.getValue(time)); - - //While we want to show the path, there may not actually be anything to show - //depending on lead/trail settings. Compute the interval of the path to - //show and check against actual availability. - if (show) { - var leadTime = Property.getValueOrUndefined(pathGraphics._leadTime, time); - var trailTime = Property.getValueOrUndefined(pathGraphics._trailTime, time); - var availability = entity._availability; - var hasAvailability = defined(availability); - var hasLeadTime = defined(leadTime); - var hasTrailTime = defined(trailTime); - - //Objects need to have either defined availability or both a lead and trail time in order to - //draw a path (since we can't draw "infinite" paths. - show = hasAvailability || (hasLeadTime && hasTrailTime); - - //The final step is to compute the actual start/stop times of the path to show. - //If current time is outside of the availability interval, there's a chance that - //we won't have to draw anything anyway. - if (show) { - if (hasTrailTime) { - sampleStart = JulianDate.addSeconds(time, -trailTime, new JulianDate()); - } - if (hasLeadTime) { - sampleStop = JulianDate.addSeconds(time, leadTime, new JulianDate()); - } - - if (hasAvailability) { - var start = availability.start; - var stop = availability.stop; - - if (!hasTrailTime || JulianDate.greaterThan(start, sampleStart)) { - sampleStart = start; - } - - if (!hasLeadTime || JulianDate.lessThan(stop, sampleStop)) { - sampleStop = stop; - } + function embedDataUris(div, elementType, attributeName, uriResolver) { + var keys = uriResolver.keys; + var baseUri = new Uri('.'); + var elements = div.querySelectorAll(elementType); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + var value = element.getAttribute(attributeName); + var uri = new Uri(value).resolve(baseUri).toString(); + var index = keys.indexOf(uri); + if (index !== -1) { + var key = keys[index]; + element.setAttribute(attributeName, uriResolver[key]); + if (elementType === 'a' && element.getAttribute('download') === null) { + element.setAttribute('download', key); } - show = JulianDate.lessThan(sampleStart, sampleStop); } } + } - if (!show) { - //don't bother creating or updating anything else - if (defined(polyline)) { - this._unusedIndexes.push(item.index); - item.polyline = undefined; - polyline.show = false; - item.index = undefined; - } - return; + function applyBasePath(div, elementType, attributeName, sourceResource) { + var elements = div.querySelectorAll(elementType); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + var value = element.getAttribute(attributeName); + var resource = resolveHref(value, sourceResource); + element.setAttribute(attributeName, resource.url); } + } - if (!defined(polyline)) { - var unusedIndexes = this._unusedIndexes; - var length = unusedIndexes.length; - if (length > 0) { - var index = unusedIndexes.pop(); - polyline = this._polylineCollection.get(index); - item.index = index; - } else { - item.index = this._polylineCollection.length; - polyline = this._polylineCollection.add(); - } - polyline.id = entity; - item.polyline = polyline; + // an optional context is passed to allow for some malformed kmls (those with multiple geometries with same ids) to still parse + // correctly, as they do in Google Earth. + function createEntity(node, entityCollection, context) { + var id = queryStringAttribute(node, 'id'); + id = defined(id) && id.length !== 0 ? id : createGuid(); + if (defined(context)) { + id = context + id; } - var resolution = Property.getValueOrDefault(pathGraphics._resolution, time, defaultResolution); - - polyline.show = true; - polyline.positions = subSample(positionProperty, sampleStart, sampleStop, time, this._referenceFrame, resolution, polyline.positions.slice()); - polyline.material = MaterialProperty.getValue(time, pathGraphics._material, polyline.material); - polyline.width = Property.getValueOrDefault(pathGraphics._width, time, defaultWidth); - polyline.distanceDisplayCondition = Property.getValueOrUndefined(pathGraphics._distanceDisplayCondition, time, polyline.distanceDisplayCondition); - }; - - PolylineUpdater.prototype.removeObject = function(item) { - var polyline = item.polyline; - if (defined(polyline)) { - this._unusedIndexes.push(item.index); - item.polyline = undefined; - polyline.show = false; - polyline.id = undefined; - item.index = undefined; + // If we have a duplicate ID just generate one. + // This isn't valid KML but Google Earth handles this case. + var entity = entityCollection.getById(id); + if (defined(entity)) { + id = createGuid(); + if (defined(context)) { + id = context + id; + } } - }; - - PolylineUpdater.prototype.destroy = function() { - this._scene.primitives.remove(this._polylineCollection); - return destroyObject(this); - }; - /** - * A {@link Visualizer} which maps {@link Entity#path} to a {@link Polyline}. - * @alias PathVisualizer - * @constructor - * - * @param {Scene} scene The scene the primitives will be rendered in. - * @param {EntityCollection} entityCollection The entityCollection to visualize. - */ - function PathVisualizer(scene, entityCollection) { - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - if (!defined(entityCollection)) { - throw new DeveloperError('entityCollection is required.'); + entity = entityCollection.add(new Entity({id : id})); + if (!defined(entity.kml)) { + entity.addProperty('kml'); + entity.kml = new KmlFeatureData(); } - - entityCollection.collectionChanged.addEventListener(PathVisualizer.prototype._onCollectionChanged, this); - - this._scene = scene; - this._updaters = {}; - this._entityCollection = entityCollection; - this._items = new AssociativeArray(); + return entity; + } - this._onCollectionChanged(entityCollection, entityCollection.values, [], []); + function isExtrudable(altitudeMode, gxAltitudeMode) { + return altitudeMode === 'absolute' || altitudeMode === 'relativeToGround' || gxAltitudeMode === 'relativeToSeaFloor'; } - /** - * Updates all of the primitives created by this visualizer to match their - * Entity counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. - */ - PathVisualizer.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var updaters = this._updaters; - for ( var key in updaters) { - if (updaters.hasOwnProperty(key)) { - updaters[key].update(time); - } + function readCoordinate(value) { + //Google Earth treats empty or missing coordinates as 0. + if (!defined(value)) { + return Cartesian3.fromDegrees(0, 0, 0); } - var items = this._items.values; - for (var i = 0, len = items.length; i < len; i++) { - var item = items[i]; - var entity = item.entity; - var positionProperty = entity._position; - - var lastUpdater = item.updater; - - var frameToVisualize = ReferenceFrame.FIXED; - if (this._scene.mode === SceneMode.SCENE3D) { - frameToVisualize = positionProperty.referenceFrame; - } - - var currentUpdater = this._updaters[frameToVisualize]; + var digits = value.match(/[^\s,\n]+/g); + if (!defined(digits)) { + return Cartesian3.fromDegrees(0, 0, 0); + } - if ((lastUpdater === currentUpdater) && (defined(currentUpdater))) { - currentUpdater.updateObject(time, item); - continue; - } + var longitude = parseFloat(digits[0]); + var latitude = parseFloat(digits[1]); + var height = parseFloat(digits[2]); - if (defined(lastUpdater)) { - lastUpdater.removeObject(item); - } + longitude = isNaN(longitude) ? 0.0 : longitude; + latitude = isNaN(latitude) ? 0.0 : latitude; + height = isNaN(height) ? 0.0 : height; - if (!defined(currentUpdater)) { - currentUpdater = new PolylineUpdater(this._scene, frameToVisualize); - currentUpdater.update(time); - this._updaters[frameToVisualize] = currentUpdater; - } + return Cartesian3.fromDegrees(longitude, latitude, height); + } - item.updater = currentUpdater; - if (defined(currentUpdater)) { - currentUpdater.updateObject(time, item); - } + function readCoordinates(element) { + if (!defined(element)) { + return undefined; } - return true; - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - PathVisualizer.prototype.isDestroyed = function() { - return false; - }; - /** - * Removes and destroys all primitives created by this instance. - */ - PathVisualizer.prototype.destroy = function() { - this._entityCollection.collectionChanged.removeEventListener(PathVisualizer.prototype._onCollectionChanged, this); + var tuples = element.textContent.match(/[^\s\n]+/g); + if (!defined(tuples)) { + return undefined; + } - var updaters = this._updaters; - for ( var key in updaters) { - if (updaters.hasOwnProperty(key)) { - updaters[key].destroy(); - } + var length = tuples.length; + var result = new Array(length); + var resultIndex = 0; + for (var i = 0; i < length; i++) { + result[resultIndex++] = readCoordinate(tuples[i]); } + return result; + } - return destroyObject(this); + var kmlNamespaces = [null, undefined, 'http://www.opengis.net/kml/2.2', 'http://earth.google.com/kml/2.2', 'http://earth.google.com/kml/2.1', 'http://earth.google.com/kml/2.0']; + var gxNamespaces = ['http://www.google.com/kml/ext/2.2']; + var atomNamespaces = ['http://www.w3.org/2005/Atom']; + var namespaces = { + kml : kmlNamespaces, + gx : gxNamespaces, + atom : atomNamespaces, + kmlgx : kmlNamespaces.concat(gxNamespaces) }; - PathVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { - var i; - var entity; - var item; - var items = this._items; - - for (i = added.length - 1; i > -1; i--) { - entity = added[i]; - if (defined(entity._path) && defined(entity._position)) { - items.set(entity.id, new EntityData(entity)); - } + function queryNumericAttribute(node, attributeName) { + if (!defined(node)) { + return undefined; } - for (i = changed.length - 1; i > -1; i--) { - entity = changed[i]; - if (defined(entity._path) && defined(entity._position)) { - if (!items.contains(entity.id)) { - items.set(entity.id, new EntityData(entity)); - } - } else { - item = items.get(entity.id); - if (defined(item)) { - item.updater.removeObject(item); - items.remove(entity.id); - } - } + var value = node.getAttribute(attributeName); + if (value !== null) { + var result = parseFloat(value); + return !isNaN(result) ? result : undefined; } + return undefined; + } - for (i = removed.length - 1; i > -1; i--) { - entity = removed[i]; - item = items.get(entity.id); - if (defined(item)) { - if (defined(item.updater)) { - item.updater.removeObject(item); - } - items.remove(entity.id); - } + function queryStringAttribute(node, attributeName) { + if (!defined(node)) { + return undefined; } - }; - - //for testing - PathVisualizer._subSample = subSample; - - return PathVisualizer; -}); + var value = node.getAttribute(attributeName); + return value !== null ? value : undefined; + } -define('DataSources/PlaneGeometryUpdater',[ - '../Core/PlaneGeometry', - '../Core/PlaneOutlineGeometry', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/Matrix4', - '../Core/ShowGeometryInstanceAttribute', - '../Core/Quaternion', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' - ], function( - PlaneGeometry, - PlaneOutlineGeometry, - Cartesian2, - Cartesian3, - Color, - ColorGeometryInstanceAttribute, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - Matrix4, - ShowGeometryInstanceAttribute, - Quaternion, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { - 'use strict'; + function queryFirstNode(node, tagName, namespace) { + if (!defined(node)) { + return undefined; + } + var childNodes = node.childNodes; + var length = childNodes.length; + for (var q = 0; q < length; q++) { + var child = childNodes[q]; + if (child.localName === tagName && namespace.indexOf(child.namespaceURI) !== -1) { + return child; + } + } + return undefined; + } - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + function queryNodes(node, tagName, namespace) { + if (!defined(node)) { + return undefined; + } + var result = []; + var childNodes = node.getElementsByTagNameNS('*', tagName); + var length = childNodes.length; + for (var q = 0; q < length; q++) { + var child = childNodes[q]; + if (child.localName === tagName && namespace.indexOf(child.namespaceURI) !== -1) { + result.push(child); + } + } + return result; + } - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.plane = undefined; - this.dimensions = undefined; + function queryChildNodes(node, tagName, namespace) { + if (!defined(node)) { + return []; + } + var result = []; + var childNodes = node.childNodes; + var length = childNodes.length; + for (var q = 0; q < length; q++) { + var child = childNodes[q]; + if (child.localName === tagName && namespace.indexOf(child.namespaceURI) !== -1) { + result.push(child); + } + } + return result; } - /** - * A {@link GeometryUpdater} for planes. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias PlaneGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function PlaneGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); + function queryNumericValue(node, tagName, namespace) { + var resultNode = queryFirstNode(node, tagName, namespace); + if (defined(resultNode)) { + var result = parseFloat(resultNode.textContent); + return !isNaN(result) ? result : undefined; } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + return undefined; + } + + function queryStringValue(node, tagName, namespace) { + var result = queryFirstNode(node, tagName, namespace); + if (defined(result)) { + return result.textContent.trim(); } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(PlaneGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'plane', entity.plane, undefined); + return undefined; } - defineProperties(PlaneGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof PlaneGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof PlaneGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance + function queryBooleanValue(node, tagName, namespace) { + var result = queryFirstNode(node, tagName, namespace); + if (defined(result)) { + var value = result.textContent.trim(); + return value === '1' || /^true$/i.test(value); } - }); + return undefined; + } - defineProperties(PlaneGeometryUpdater.prototype, { - /** - * Gets the entity associated with this geometry. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Entity} - * @readonly - */ - entity : { - get : function() { - return this._entity; - } - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, - /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, - /** - * Gets the material property used to fill the geometry. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly - */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); - } - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - outlineColorProperty : { - get : function() { - return this._outlineColorProperty; - } - }, - /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Number} - * @readonly - */ - outlineWidth : { - get : function() { - return this._outlineWidth; - } - }, - /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; - } - }, - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayConditionProperty; - } - }, - /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isDynamic : { - get : function() { - return this._dynamic; - } - }, - /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isClosed : { - value : false - }, - /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof PlaneGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - geometryChanged : { - get : function() { - return this._geometryChanged; + function resolveHref(href, sourceResource, uriResolver) { + if (!defined(href)) { + return undefined; + } + + var resource; + if (defined(uriResolver)) { + var blob = uriResolver[href]; + if (defined(blob)) { + resource = new Resource({ + url: blob + }); + } else { + // Needed for multiple levels of KML files in a KMZ + var baseUri = new Uri(sourceResource.getUrlComponent()); + var uri = new Uri(href); + blob = uriResolver[uri.resolve(baseUri)]; + if (defined(blob)) { + resource = new Resource({ + url: blob + }); + } } } - }); - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - PlaneGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + if (!defined(resource)) { + resource = sourceResource.getDerivedResource({ + url: href + }); + } - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - PlaneGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; + return resource; + } - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - PlaneGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + var colorOptions = {}; + + function parseColorString(value, isRandom) { + if (!defined(value) || /^\s*$/gm.test(value)) { + return undefined; } - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); + if (value[0] === '#') { + value = value.substring(1); } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var attributes; + var alpha = parseInt(value.substring(0, 2), 16) / 255.0; + var blue = parseInt(value.substring(2, 4), 16) / 255.0; + var green = parseInt(value.substring(4, 6), 16) / 255.0; + var red = parseInt(value.substring(6, 8), 16) / 255.0; - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; + if (!isRandom) { + return new Color(red, green, blue, alpha); + } + + if (red > 0) { + colorOptions.maximumRed = red; } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; + colorOptions.red = 0; + } + if (green > 0) { + colorOptions.maximumGreen = green; + } else { + colorOptions.green = 0; } + if (blue > 0) { + colorOptions.maximumBlue = blue; + } else { + colorOptions.blue = 0; + } + colorOptions.alpha = alpha; + return Color.fromRandom(colorOptions); + } - var planeGraphics = entity.plane; - var options = this._options; - var modelMatrix = entity.computeModelMatrix(time); - var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane); - var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions); - if (!defined(modelMatrix) || !defined(plane) || !defined(dimensions)) { - return; + function queryColorValue(node, tagName, namespace) { + var value = queryStringValue(node, tagName, namespace); + if (!defined(value)) { + return undefined; } + return parseColorString(value, queryStringValue(node, 'colorMode', namespace) === 'random'); + } - options.plane = plane; - options.dimensions = dimensions; + function processTimeStamp(featureNode) { + var node = queryFirstNode(featureNode, 'TimeStamp', namespaces.kmlgx); + var whenString = queryStringValue(node, 'when', namespaces.kmlgx); - modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, modelMatrix); + if (!defined(node) || !defined(whenString) || whenString.length === 0) { + return undefined; + } - return new GeometryInstance({ - id : entity, - geometry : new PlaneGeometry(this._options), - modelMatrix : modelMatrix, - attributes : attributes - }); - }; + //According to the KML spec, a TimeStamp represents a "single moment in time" + //However, since Cesium animates much differently than Google Earth, that doesn't + //Make much sense here. Instead, we use the TimeStamp as the moment the feature + //comes into existence. This works much better and gives a similar feel to + //GE's experience. + var when = JulianDate.fromIso8601(whenString); + var result = new TimeIntervalCollection(); + result.addInterval(new TimeInterval({ + start : when, + stop : Iso8601.MAXIMUM_VALUE + })); + return result; + } - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - PlaneGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + function processTimeSpan(featureNode) { + var node = queryFirstNode(featureNode, 'TimeSpan', namespaces.kmlgx); + if (!defined(node)) { + return undefined; } + var result; - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + var beginNode = queryFirstNode(node, 'begin', namespaces.kmlgx); + var beginDate = defined(beginNode) ? JulianDate.fromIso8601(beginNode.textContent) : undefined; - var planeGraphics = entity.plane; - var options = this._options; - var modelMatrix = entity.computeModelMatrix(time); - var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane); - var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions); - if (!defined(modelMatrix) || !defined(plane) || !defined(dimensions)) { - return; + var endNode = queryFirstNode(node, 'end', namespaces.kmlgx); + var endDate = defined(endNode) ? JulianDate.fromIso8601(endNode.textContent) : undefined; + + if (defined(beginDate) && defined(endDate)) { + if (JulianDate.lessThan(endDate, beginDate)) { + var tmp = beginDate; + beginDate = endDate; + endDate = tmp; + } + result = new TimeIntervalCollection(); + result.addInterval(new TimeInterval({ + start : beginDate, + stop : endDate + })); + } else if (defined(beginDate)) { + result = new TimeIntervalCollection(); + result.addInterval(new TimeInterval({ + start : beginDate, + stop : Iso8601.MAXIMUM_VALUE + })); + } else if (defined(endDate)) { + result = new TimeIntervalCollection(); + result.addInterval(new TimeInterval({ + start : Iso8601.MINIMUM_VALUE, + stop : endDate + })); } - options.plane = plane; - options.dimensions = dimensions; + return result; + } - modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, modelMatrix); + function createDefaultBillboard() { + var billboard = new BillboardGraphics(); + billboard.width = BILLBOARD_SIZE; + billboard.height = BILLBOARD_SIZE; + billboard.scaleByDistance = new NearFarScalar(BILLBOARD_NEAR_DISTANCE, BILLBOARD_NEAR_RATIO, BILLBOARD_FAR_DISTANCE, BILLBOARD_FAR_RATIO); + billboard.pixelOffsetScaleByDistance = new NearFarScalar(BILLBOARD_NEAR_DISTANCE, BILLBOARD_NEAR_RATIO, BILLBOARD_FAR_DISTANCE, BILLBOARD_FAR_RATIO); + return billboard; + } - return new GeometryInstance({ - id : entity, - geometry : new PlaneOutlineGeometry(), - modelMatrix : modelMatrix, - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) - } - }); - }; + function createDefaultPolygon() { + var polygon = new PolygonGraphics(); + polygon.outline = true; + polygon.outlineColor = Color.WHITE; + return polygon; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - PlaneGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + function createDefaultLabel() { + var label = new LabelGraphics(); + label.translucencyByDistance = new NearFarScalar(3000000, 1.0, 5000000, 0.0); + label.pixelOffset = new Cartesian2(17, 0); + label.horizontalOrigin = HorizontalOrigin.LEFT; + label.font = '16px sans-serif'; + label.style = LabelStyle.FILL_AND_OUTLINE; + return label; + } - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - PlaneGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + function getIconHref(iconNode, dataSource, sourceResource, uriResolver, canRefresh) { + var href = queryStringValue(iconNode, 'href', namespaces.kml); + if (!defined(href) || (href.length === 0)) { + return undefined; + } - PlaneGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'position' || propertyName === 'orientation' || propertyName === 'plane')) { - return; + if (href.indexOf('root://icons/palette-') === 0) { + var palette = href.charAt(21); + + // Get the icon number + var x = defaultValue(queryNumericValue(iconNode, 'x', namespaces.gx), 0); + var y = defaultValue(queryNumericValue(iconNode, 'y', namespaces.gx), 0); + x = Math.min(x / 32, 7); + y = 7 - Math.min(y / 32, 7); + var iconNum = (8 * y) + x; + + href = 'https://maps.google.com/mapfiles/kml/pal' + palette + '/icon' + iconNum + '.png'; } - var planeGraphics = this._entity.plane; - if (!defined(planeGraphics)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + var hrefResource = resolveHref(href, sourceResource, uriResolver); + + if (canRefresh) { + var refreshMode = queryStringValue(iconNode, 'refreshMode', namespaces.kml); + var viewRefreshMode = queryStringValue(iconNode, 'viewRefreshMode', namespaces.kml); + if (refreshMode === 'onInterval' || refreshMode === 'onExpire') { + oneTimeWarning('kml-refreshMode-' + refreshMode, 'KML - Unsupported Icon refreshMode: ' + refreshMode); + } else if (viewRefreshMode === 'onStop' || viewRefreshMode === 'onRegion') { + oneTimeWarning('kml-refreshMode-' + viewRefreshMode, 'KML - Unsupported Icon viewRefreshMode: ' + viewRefreshMode); } - return; - } - var fillProperty = planeGraphics.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + var viewBoundScale = defaultValue(queryStringValue(iconNode, 'viewBoundScale', namespaces.kml), 1.0); + var defaultViewFormat = (viewRefreshMode === 'onStop') ? 'BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]' : ''; + var viewFormat = defaultValue(queryStringValue(iconNode, 'viewFormat', namespaces.kml), defaultViewFormat); + var httpQuery = queryStringValue(iconNode, 'httpQuery', namespaces.kml); + if (defined(viewFormat)) { + hrefResource.addQueryParameters(queryToObject(cleanupString(viewFormat))); + } + if (defined(httpQuery)) { + hrefResource.addQueryParameters(queryToObject(cleanupString(httpQuery))); + } - var outlineProperty = planeGraphics.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + processNetworkLinkQueryString(hrefResource, dataSource._camera, dataSource._canvas, viewBoundScale, dataSource._lastCameraView.bbox); + + return hrefResource; } - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + return hrefResource; + } + + function processBillboardIcon(dataSource, node, targetEntity, sourceResource, uriResolver) { + var scale = queryNumericValue(node, 'scale', namespaces.kml); + var heading = queryNumericValue(node, 'heading', namespaces.kml); + var color = queryColorValue(node, 'color', namespaces.kml); + + var iconNode = queryFirstNode(node, 'Icon', namespaces.kml); + var icon = getIconHref(iconNode, dataSource, sourceResource, uriResolver, false); + + // If icon tags are present but blank, we do not want to show an icon + if (defined(iconNode) && !defined(icon)) { + icon = false; } - var plane = planeGraphics.plane; - var dimensions = planeGraphics.dimensions; - var position = entity.position; + var x = queryNumericValue(iconNode, 'x', namespaces.gx); + var y = queryNumericValue(iconNode, 'y', namespaces.gx); + var w = queryNumericValue(iconNode, 'w', namespaces.gx); + var h = queryNumericValue(iconNode, 'h', namespaces.gx); - var show = planeGraphics.show; - if (!defined(plane) || !defined(dimensions) || !defined(position) || (defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + var hotSpotNode = queryFirstNode(node, 'hotSpot', namespaces.kml); + var hotSpotX = queryNumericAttribute(hotSpotNode, 'x'); + var hotSpotY = queryNumericAttribute(hotSpotNode, 'y'); + var hotSpotXUnit = queryStringAttribute(hotSpotNode, 'xunits'); + var hotSpotYUnit = queryStringAttribute(hotSpotNode, 'yunits'); + + var billboard = targetEntity.billboard; + if (!defined(billboard)) { + billboard = createDefaultBillboard(); + targetEntity.billboard = billboard; } - var material = defaultValue(planeGraphics.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(planeGraphics.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(planeGraphics.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(planeGraphics.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(planeGraphics.distanceDisplayCondition, defaultDistanceDisplayCondition); + billboard.image = icon; + billboard.scale = scale; + billboard.color = color; - var outlineWidth = planeGraphics.outlineWidth; + if (defined(x) || defined(y) || defined(w) || defined(h)) { + billboard.imageSubRegion = new BoundingRectangle(x, y, w, h); + } - this._fillEnabled = fillEnabled; - this._outlineEnabled = outlineEnabled; + //GE treats a heading of zero as no heading + //You can still point north using a 360 degree angle (or any multiple of 360) + if (defined(heading) && heading !== 0) { + billboard.rotation = CesiumMath.toRadians(-heading); + billboard.alignedAxis = Cartesian3.UNIT_Z; + } - if (!position.isConstant || // - !Property.isConstant(entity.orientation) || // - !plane.isConstant || // - !dimensions.isConstant || // - !Property.isConstant(outlineWidth)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + //Hotpot is the KML equivalent of pixel offset + //The hotspot origin is the lower left, but we leave + //our billboard origin at the center and simply + //modify the pixel offset to take this into account + scale = defaultValue(scale, 1.0); + + var xOffset; + var yOffset; + if (defined(hotSpotX)) { + if (hotSpotXUnit === 'pixels') { + xOffset = -hotSpotX * scale; + } else if (hotSpotXUnit === 'insetPixels') { + xOffset = (hotSpotX - BILLBOARD_SIZE) * scale; + } else if (hotSpotXUnit === 'fraction') { + xOffset = -hotSpotX * BILLBOARD_SIZE * scale; } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.plane = plane.getValue(Iso8601.MINIMUM_VALUE, options.plane); - options.dimensions = dimensions.getValue(Iso8601.MINIMUM_VALUE, options.dimensions); - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); + xOffset += BILLBOARD_SIZE * 0.5 * scale; } - }; - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - PlaneGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); - } + if (defined(hotSpotY)) { + if (hotSpotYUnit === 'pixels') { + yOffset = hotSpotY * scale; + } else if (hotSpotYUnit === 'insetPixels') { + yOffset = (-hotSpotY + BILLBOARD_SIZE) * scale; + } else if (hotSpotYUnit === 'fraction') { + yOffset = hotSpotY * BILLBOARD_SIZE * scale; + } - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); + yOffset -= BILLBOARD_SIZE * 0.5 * scale; } - - return new DynamicGeometryUpdater(primitives, this); - }; - /** - * @private - */ - function DynamicGeometryUpdater(primitives, geometryUpdater) { - this._primitives = primitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); + if (defined(xOffset) || defined(yOffset)) { + billboard.pixelOffset = new Cartesian2(xOffset, yOffset); + } } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + + function applyStyle(dataSource, styleNode, targetEntity, sourceResource, uriResolver) { + for (var i = 0, len = styleNode.childNodes.length; i < len; i++) { + var node = styleNode.childNodes.item(i); + if (node.localName === 'IconStyle') { + processBillboardIcon(dataSource, node, targetEntity, sourceResource, uriResolver); + } else if (node.localName === 'LabelStyle') { + var label = targetEntity.label; + if (!defined(label)) { + label = createDefaultLabel(); + targetEntity.label = label; + } + label.scale = defaultValue(queryNumericValue(node, 'scale', namespaces.kml), label.scale); + label.fillColor = defaultValue(queryColorValue(node, 'color', namespaces.kml), label.fillColor); + label.text = targetEntity.name; + } else if (node.localName === 'LineStyle') { + var polyline = targetEntity.polyline; + if (!defined(polyline)) { + polyline = new PolylineGraphics(); + targetEntity.polyline = polyline; + } + polyline.width = queryNumericValue(node, 'width', namespaces.kml); + polyline.material = queryColorValue(node, 'color', namespaces.kml); + if (defined(queryColorValue(node, 'outerColor', namespaces.gx))) { + oneTimeWarning('kml-gx:outerColor', 'KML - gx:outerColor is not supported in a LineStyle'); + } + if (defined(queryNumericValue(node, 'outerWidth', namespaces.gx))) { + oneTimeWarning('kml-gx:outerWidth', 'KML - gx:outerWidth is not supported in a LineStyle'); + } + if (defined(queryNumericValue(node, 'physicalWidth', namespaces.gx))) { + oneTimeWarning('kml-gx:physicalWidth', 'KML - gx:physicalWidth is not supported in a LineStyle'); + } + if (defined(queryBooleanValue(node, 'labelVisibility', namespaces.gx))) { + oneTimeWarning('kml-gx:labelVisibility', 'KML - gx:labelVisibility is not supported in a LineStyle'); + } + } else if (node.localName === 'PolyStyle') { + var polygon = targetEntity.polygon; + if (!defined(polygon)) { + polygon = createDefaultPolygon(); + targetEntity.polygon = polygon; + } + polygon.material = defaultValue(queryColorValue(node, 'color', namespaces.kml), polygon.material); + polygon.fill = defaultValue(queryBooleanValue(node, 'fill', namespaces.kml), polygon.fill); + polygon.outline = defaultValue(queryBooleanValue(node, 'outline', namespaces.kml), polygon.outline); + } else if (node.localName === 'BalloonStyle') { + var bgColor = defaultValue(parseColorString(queryStringValue(node, 'bgColor', namespaces.kml)), Color.WHITE); + var textColor = defaultValue(parseColorString(queryStringValue(node, 'textColor', namespaces.kml)), Color.BLACK); + var text = queryStringValue(node, 'text', namespaces.kml); + + //This is purely an internal property used in style processing, + //it never ends up on the final entity. + targetEntity.addProperty('balloonStyle'); + targetEntity.balloonStyle = { + bgColor : bgColor, + textColor : textColor, + text : text + }; + } else if (node.localName === 'ListStyle') { + var listItemType = queryStringValue(node, 'listItemType', namespaces.kml); + if (listItemType === 'radioFolder' || listItemType === 'checkOffOnly') { + oneTimeWarning('kml-listStyle-' + listItemType, 'KML - Unsupported ListStyle with listItemType: ' + listItemType); + } + } } - - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._primitive = undefined; - this._outlinePrimitive = undefined; + } - var geometryUpdater = this._geometryUpdater; - var entity = geometryUpdater._entity; - var planeGraphics = entity.plane; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(planeGraphics.show, time, true)) { - return; + //Processes and merges any inline styles for the provided node into the provided entity. + function computeFinalStyle(dataSource, placeMark, styleCollection, sourceResource, uriResolver) { + var result = new Entity(); + var styleEntity; + + //Google earth seems to always use the last inline Style/StyleMap only + var styleIndex = -1; + var childNodes = placeMark.childNodes; + var length = childNodes.length; + for (var q = 0; q < length; q++) { + var child = childNodes[q]; + if (child.localName === 'Style' || child.localName === 'StyleMap') { + styleIndex = q; + } } - var options = this._options; - var modelMatrix = entity.computeModelMatrix(time); - var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane); - var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions); - if (!defined(modelMatrix) || !defined(plane) || !defined(dimensions)) { - return; + if (styleIndex !== -1) { + var inlineStyleNode = childNodes[styleIndex]; + if (inlineStyleNode.localName === 'Style') { + applyStyle(dataSource, inlineStyleNode, result, sourceResource, uriResolver); + } else { // StyleMap + var pairs = queryChildNodes(inlineStyleNode, 'Pair', namespaces.kml); + for (var p = 0; p < pairs.length; p++) { + var pair = pairs[p]; + var key = queryStringValue(pair, 'key', namespaces.kml); + if (key === 'normal') { + var styleUrl = queryStringValue(pair, 'styleUrl', namespaces.kml); + if (defined(styleUrl)) { + styleEntity = styleCollection.getById(styleUrl); + if (!defined(styleEntity)) { + styleEntity = styleCollection.getById('#' + styleUrl); + } + if (defined(styleEntity)) { + result.merge(styleEntity); + } + } else { + var node = queryFirstNode(pair, 'Style', namespaces.kml); + applyStyle(dataSource, node, result, sourceResource, uriResolver); + } + } else { + oneTimeWarning('kml-styleMap-' + key, 'KML - Unsupported StyleMap key: ' + key); + } + } + } } - options.plane = plane; - options.dimensions = dimensions; + //Google earth seems to always use the first external style only. + var externalStyle = queryStringValue(placeMark, 'styleUrl', namespaces.kml); + if (defined(externalStyle)) { + var id = externalStyle; + if (externalStyle[0] !== '#' && externalStyle.indexOf('#') !== -1) { + var tokens = externalStyle.split('#'); + var uri = tokens[0]; + var resource = sourceResource.getDerivedResource({ + url: uri + }); - modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, modelMatrix); + id = resource.getUrlComponent() + '#' + tokens[1]; + } - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + styleEntity = styleCollection.getById(id); + if (!defined(styleEntity)) { + styleEntity = styleCollection.getById('#' + id); + } + if (defined(styleEntity)) { + result.merge(styleEntity); + } + } - var distanceDisplayConditionProperty = this._geometryUpdater.distanceDisplayConditionProperty; - var distanceDisplayCondition = distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + return result; + } - if (Property.getValueOrDefault(planeGraphics.fill, time, true)) { - var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - this._material = material; + //Asynchronously processes an external style file. + function processExternalStyles(dataSource, resource, styleCollection) { + return resource.fetchXML().then(function(styleKml) { + return processStyles(dataSource, styleKml, styleCollection, resource, true); + }); + } - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : true - }); - options.vertexFormat = appearance.vertexFormat; + //Processes all shared and external styles and stores + //their id into the provided styleCollection. + //Returns an array of promises that will resolve when + //each style is loaded. + function processStyles(dataSource, kml, styleCollection, sourceResource, isExternal, uriResolver) { + var i; + var id; + var styleEntity; - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PlaneGeometry(), - modelMatrix : modelMatrix, - attributes : { - distanceDisplayCondition : distanceDisplayConditionAttribute + var node; + var styleNodes = queryNodes(kml, 'Style', namespaces.kml); + if (defined(styleNodes)) { + var styleNodesLength = styleNodes.length; + for (i = 0; i < styleNodesLength; i++) { + node = styleNodes[i]; + id = queryStringAttribute(node, 'id'); + if (defined(id)) { + id = '#' + id; + if (isExternal && defined(sourceResource)) { + id = sourceResource.getUrlComponent() + id; } - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + if (!defined(styleCollection.getById(id))) { + styleEntity = new Entity({ + id : id + }); + styleCollection.add(styleEntity); + applyStyle(dataSource, node, styleEntity, sourceResource, uriResolver); + } + } + } } - if (Property.getValueOrDefault(planeGraphics.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + var styleMaps = queryNodes(kml, 'StyleMap', namespaces.kml); + if (defined(styleMaps)) { + var styleMapsLength = styleMaps.length; + for (i = 0; i < styleMapsLength; i++) { + var styleMap = styleMaps[i]; + id = queryStringAttribute(styleMap, 'id'); + if (defined(id)) { + var pairs = queryChildNodes(styleMap, 'Pair', namespaces.kml); + for (var p = 0; p < pairs.length; p++) { + var pair = pairs[p]; + var key = queryStringValue(pair, 'key', namespaces.kml); + if (key === 'normal') { + id = '#' + id; + if (isExternal && defined(sourceResource)) { + id = sourceResource.getUrlComponent() + id; + } + if (!defined(styleCollection.getById(id))) { + styleEntity = styleCollection.getOrCreateEntity(id); - var outlineColor = Property.getValueOrClonedDefault(planeGraphics.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(planeGraphics.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + var styleUrl = queryStringValue(pair, 'styleUrl', namespaces.kml); + if (defined(styleUrl)) { + if (styleUrl[0] !== '#') { + styleUrl = '#' + styleUrl; + } - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PlaneOutlineGeometry(), - modelMatrix : modelMatrix, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : distanceDisplayConditionAttribute - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + if (isExternal && defined(sourceResource)) { + styleUrl = sourceResource.getUrlComponent() + styleUrl; + } + var base = styleCollection.getById(styleUrl); + + if (defined(base)) { + styleEntity.merge(base); + } + } else { + node = queryFirstNode(pair, 'Style', namespaces.kml); + applyStyle(dataSource, node, styleEntity, sourceResource, uriResolver); + } + } + } else { + oneTimeWarning('kml-styleMap-' + key, 'KML - Unsupported StyleMap key: ' + key); + } } - }), - asynchronous : false, - shadows : shadows - })); + } + } + } + + var promises = []; + var styleUrlNodes = kml.getElementsByTagName('styleUrl'); + var styleUrlNodesLength = styleUrlNodes.length; + for (i = 0; i < styleUrlNodesLength; i++) { + var styleReference = styleUrlNodes[i].textContent; + if (styleReference[0] !== '#') { + //According to the spec, all local styles should start with a # + //and everything else is an external style that has a # seperating + //the URL of the document and the style. However, Google Earth + //also accepts styleUrls without a # as meaning a local style. + var tokens = styleReference.split('#'); + if (tokens.length === 2) { + var uri = tokens[0]; + var resource = sourceResource.getDerivedResource({ + url: uri + }); + + promises.push(processExternalStyles(dataSource, resource, styleCollection)); + } + } + } + + return promises; + } + + function createDropLine(entityCollection, entity, styleEntity) { + var entityPosition = new ReferenceProperty(entityCollection, entity.id, ['position']); + var surfacePosition = new ScaledPositionProperty(entity.position); + entity.polyline = defined(styleEntity.polyline) ? styleEntity.polyline.clone() : new PolylineGraphics(); + entity.polyline.positions = new PositionPropertyArray([entityPosition, surfacePosition]); + } + + function heightReferenceFromAltitudeMode(altitudeMode, gxAltitudeMode) { + if (!defined(altitudeMode) && !defined(gxAltitudeMode) || altitudeMode === 'clampToGround') { + return HeightReference.CLAMP_TO_GROUND; + } + + if (altitudeMode === 'relativeToGround') { + return HeightReference.RELATIVE_TO_GROUND; + } + + if (altitudeMode === 'absolute') { + return HeightReference.NONE; + } + + if (gxAltitudeMode === 'clampToSeaFloor') { + oneTimeWarning('kml-gx:altitudeMode-clampToSeaFloor', 'KML - <gx:altitudeMode>:clampToSeaFloor is currently not supported, using <kml:altitudeMode>:clampToGround.'); + return HeightReference.CLAMP_TO_GROUND; } - }; - var scratchTranslation = new Cartesian3(); - var scratchNormal = new Cartesian3(); - var scratchScale = new Cartesian3(); - function createPrimitiveMatrix (plane, dimensions, modelMatrix, result) { - var normal; - var distance; - if (defined(plane)) { - normal = plane.normal; - distance = plane.distance; - } else { - normal = Cartesian3.clone(Cartesian3.UNIT_X, scratchNormal); - distance = 0.0; + if (gxAltitudeMode === 'relativeToSeaFloor') { + oneTimeWarning('kml-gx:altitudeMode-relativeToSeaFloor', 'KML - <gx:altitudeMode>:relativeToSeaFloor is currently not supported, using <kml:altitudeMode>:relativeToGround.'); + return HeightReference.RELATIVE_TO_GROUND; } - if (!defined(dimensions)) { - dimensions = new Cartesian2(1.0, 1.0); + if (defined(altitudeMode)) { + oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown <kml:altitudeMode>:' + altitudeMode + ', using <kml:altitudeMode>:CLAMP_TO_GROUND.'); + } else { + oneTimeWarning('kml-gx:altitudeMode-unknown', 'KML - Unknown <gx:altitudeMode>:' + gxAltitudeMode + ', using <kml:altitudeMode>:CLAMP_TO_GROUND.'); } - var translation = Cartesian3.multiplyByScalar(normal, -distance, scratchTranslation); - translation = Matrix4.multiplyByPoint(modelMatrix, translation, translation); + // Clamp to ground is the default + return HeightReference.CLAMP_TO_GROUND; + } - var transformedNormal = Matrix4.multiplyByPointAsVector(modelMatrix, normal, scratchNormal); - Cartesian3.normalize(transformedNormal, transformedNormal); - var rotation = getRotationMatrix(transformedNormal, Cartesian3.UNIT_Z); + function createPositionPropertyFromAltitudeMode(property, altitudeMode, gxAltitudeMode) { + if (gxAltitudeMode === 'relativeToSeaFloor' || altitudeMode === 'absolute' || altitudeMode === 'relativeToGround') { + //Just return the ellipsoid referenced property until we support MSL + return property; + } - var scale = Cartesian2.clone(dimensions, scratchScale); - scale.z = 1.0; + if ((defined(altitudeMode) && altitudeMode !== 'clampToGround') || // + (defined(gxAltitudeMode) && gxAltitudeMode !== 'clampToSeaFloor')) { + oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + defaultValue(altitudeMode, gxAltitudeMode)); + } - return Matrix4.fromTranslationQuaternionRotationScale(translation, rotation, scale, result); + // Clamp to ground is the default + return new ScaledPositionProperty(property); } - // get a rotation according to a normal - var scratchAxis = new Cartesian3(); - var scratchQuaternion = new Quaternion(); - function getRotationMatrix(direction, up) { - var angle = Cartesian3.angleBetween(direction, up); - if (angle === 0.0) { - return Quaternion.clone(Quaternion.IDENTITY, scratchQuaternion); + function createPositionPropertyArrayFromAltitudeMode(properties, altitudeMode, gxAltitudeMode) { + if (!defined(properties)) { + return undefined; } - var axis = Cartesian3.cross(up, direction, scratchAxis); - return Quaternion.fromAxisAngle(axis, angle, scratchQuaternion); - } + if (gxAltitudeMode === 'relativeToSeaFloor' || altitudeMode === 'absolute' || altitudeMode === 'relativeToGround') { + //Just return the ellipsoid referenced property until we support MSL + return properties; + } - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; + if ((defined(altitudeMode) && altitudeMode !== 'clampToGround') || // + (defined(gxAltitudeMode) && gxAltitudeMode !== 'clampToSeaFloor')) { + oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + defaultValue(altitudeMode, gxAltitudeMode)); + } - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + // Clamp to ground is the default + var propertiesLength = properties.length; + for (var i = 0; i < propertiesLength; i++) { + var property = properties[i]; + Ellipsoid.WGS84.scaleToGeodeticSurface(property, property); + } + return properties; + } - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; + function processPositionGraphics(dataSource, entity, styleEntity, heightReference) { + var label = entity.label; + if (!defined(label)) { + label = defined(styleEntity.label) ? styleEntity.label.clone() : createDefaultLabel(); + entity.label = label; + } + label.text = entity.name; - return PlaneGeometryUpdater; -}); + var billboard = entity.billboard; + if (!defined(billboard)) { + billboard = defined(styleEntity.billboard) ? styleEntity.billboard.clone() : createDefaultBillboard(); + entity.billboard = billboard; + } -define('DataSources/PointVisualizer',[ - '../Core/AssociativeArray', - '../Core/Cartesian3', - '../Core/Color', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/NearFarScalar', - '../Scene/HeightReference', - './BoundingSphereState', - './Property' - ], function( - AssociativeArray, - Cartesian3, - Color, - defined, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - NearFarScalar, - HeightReference, - BoundingSphereState, - Property) { - 'use strict'; + if (!defined(billboard.image)) { + billboard.image = dataSource._pinBuilder.fromColor(Color.YELLOW, 64); - var defaultColor = Color.WHITE; - var defaultOutlineColor = Color.BLACK; - var defaultOutlineWidth = 0.0; - var defaultPixelSize = 1.0; - var defaultDisableDepthTestDistance = 0.0; + // If there were empty <Icon> tags in the KML, then billboard.image was set to false above + // However, in this case, the false value would have been converted to a property afterwards + // Thus, we check if billboard.image is defined with value of false + } else if (!billboard.image.getValue()) { + billboard.image = undefined; + } - var color = new Color(); - var position = new Cartesian3(); - var outlineColor = new Color(); - var scaleByDistance = new NearFarScalar(); - var translucencyByDistance = new NearFarScalar(); - var distanceDisplayCondition = new DistanceDisplayCondition(); + var scale = 1.0; + if (defined(billboard.scale)) { + scale = billboard.scale.getValue(); + if (scale !== 0) { + label.pixelOffset = new Cartesian2((scale * 16) + 1, 0); + } else { + //Minor tweaks to better match Google Earth. + label.pixelOffset = undefined; + label.horizontalOrigin = undefined; + } + } - function EntityData(entity) { - this.entity = entity; - this.pointPrimitive = undefined; - this.billboard = undefined; - this.color = undefined; - this.outlineColor = undefined; - this.pixelSize = undefined; - this.outlineWidth = undefined; + if (defined(heightReference) && dataSource._clampToGround) { + billboard.heightReference = heightReference; + label.heightReference = heightReference; + } } - /** - * A {@link Visualizer} which maps {@link Entity#point} to a {@link PointPrimitive}. - * @alias PointVisualizer - * @constructor - * - * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities. - * @param {EntityCollection} entityCollection The entityCollection to visualize. - */ - function PointVisualizer(entityCluster, entityCollection) { - if (!defined(entityCluster)) { - throw new DeveloperError('entityCluster is required.'); - } - if (!defined(entityCollection)) { - throw new DeveloperError('entityCollection is required.'); + function processPathGraphics(entity, styleEntity) { + var path = entity.path; + if (!defined(path)) { + path = new PathGraphics(); + path.leadTime = 0; + entity.path = path; } - - entityCollection.collectionChanged.addEventListener(PointVisualizer.prototype._onCollectionChanged, this); - this._cluster = entityCluster; - this._entityCollection = entityCollection; - this._items = new AssociativeArray(); - this._onCollectionChanged(entityCollection, entityCollection.values, [], []); + var polyline = styleEntity.polyline; + if (defined(polyline)) { + path.material = polyline.material; + path.width = polyline.width; + } } - /** - * Updates the primitives created by this visualizer to match their - * Entity counterpart at the given time. - * - * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. - */ - PointVisualizer.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + function processPoint(dataSource, entityCollection, geometryNode, entity, styleEntity) { + var coordinatesString = queryStringValue(geometryNode, 'coordinates', namespaces.kml); + var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); + var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); + var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); + + var position = readCoordinate(coordinatesString); + + entity.position = position; + processPositionGraphics(dataSource, entity, styleEntity, heightReferenceFromAltitudeMode(altitudeMode, gxAltitudeMode)); + + if (extrude && isExtrudable(altitudeMode, gxAltitudeMode)) { + createDropLine(entityCollection, entity, styleEntity); } - - var items = this._items.values; - var cluster = this._cluster; - for (var i = 0, len = items.length; i < len; i++) { - var item = items[i]; - var entity = item.entity; - var pointGraphics = entity._point; - var pointPrimitive = item.pointPrimitive; - var billboard = item.billboard; - var heightReference = Property.getValueOrDefault(pointGraphics._heightReference, time, HeightReference.NONE); - var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(pointGraphics._show, time, true); - if (show) { - position = Property.getValueOrUndefined(entity._position, time, position); - show = defined(position); - } - if (!show) { - returnPrimitive(item, entity, cluster); - continue; - } - if (!Property.isConstant(entity._position)) { - cluster._clusterDirty = true; - } + return true; + } - var needsRedraw = false; - if ((heightReference !== HeightReference.NONE) && !defined(billboard)) { - if (defined(pointPrimitive)) { - returnPrimitive(item, entity, cluster); - pointPrimitive = undefined; - } + function processLineStringOrLinearRing(dataSource, entityCollection, geometryNode, entity, styleEntity) { + var coordinatesNode = queryFirstNode(geometryNode, 'coordinates', namespaces.kml); + var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); + var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); + var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); + var tessellate = queryBooleanValue(geometryNode, 'tessellate', namespaces.kml); + var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); - billboard = cluster.getBillboard(entity); - billboard.id = entity; - billboard.image = undefined; - item.billboard = billboard; - needsRedraw = true; - } else if ((heightReference === HeightReference.NONE) && !defined(pointPrimitive)) { - if (defined(billboard)) { - returnPrimitive(item, entity, cluster); - billboard = undefined; - } + if (defined(queryNumericValue(geometryNode, 'drawOrder', namespaces.gx))) { + oneTimeWarning('kml-gx:drawOrder', 'KML - gx:drawOrder is not supported in LineStrings'); + } - pointPrimitive = cluster.getPoint(entity); - pointPrimitive.id = entity; - item.pointPrimitive = pointPrimitive; + var coordinates = readCoordinates(coordinatesNode); + var polyline = styleEntity.polyline; + if (canExtrude && extrude) { + var wall = new WallGraphics(); + entity.wall = wall; + wall.positions = coordinates; + var polygon = styleEntity.polygon; + + if (defined(polygon)) { + wall.fill = polygon.fill; + wall.material = polygon.material; } - if (defined(pointPrimitive)) { - pointPrimitive.show = true; - pointPrimitive.position = position; - pointPrimitive.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance); - pointPrimitive.translucencyByDistance = Property.getValueOrUndefined(pointGraphics._translucencyByDistance, time, translucencyByDistance); - pointPrimitive.color = Property.getValueOrDefault(pointGraphics._color, time, defaultColor, color); - pointPrimitive.outlineColor = Property.getValueOrDefault(pointGraphics._outlineColor, time, defaultOutlineColor, outlineColor); - pointPrimitive.outlineWidth = Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth); - pointPrimitive.pixelSize = Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize); - pointPrimitive.distanceDisplayCondition = Property.getValueOrUndefined(pointGraphics._distanceDisplayCondition, time, distanceDisplayCondition); - pointPrimitive.disableDepthTestDistance = Property.getValueOrDefault(pointGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); - } else if (defined(billboard)) { - billboard.show = true; - billboard.position = position; - billboard.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance); - billboard.translucencyByDistance = Property.getValueOrUndefined(pointGraphics._translucencyByDistance, time, translucencyByDistance); - billboard.distanceDisplayCondition = Property.getValueOrUndefined(pointGraphics._distanceDisplayCondition, time, distanceDisplayCondition); - billboard.disableDepthTestDistance = Property.getValueOrDefault(pointGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); - billboard.heightReference = heightReference; + //Always outline walls so they show up in 2D. + wall.outline = true; + if (defined(polyline)) { + wall.outlineColor = defined(polyline.material) ? polyline.material.color : Color.WHITE; + wall.outlineWidth = polyline.width; + } else if (defined(polygon)) { + wall.outlineColor = defined(polygon.material) ? polygon.material.color : Color.WHITE; + } + } else if (dataSource._clampToGround && !canExtrude && tessellate) { + var corridor = new CorridorGraphics(); + entity.corridor = corridor; + corridor.positions = coordinates; + if (defined(polyline)) { + corridor.material = defined(polyline.material) ? polyline.material.color.getValue(Iso8601.MINIMUM_VALUE) : Color.WHITE; + corridor.width = defaultValue(polyline.width, 1.0); + } else { + corridor.material = Color.WHITE; + corridor.width = 1.0; + } + } else { + polyline = defined(polyline) ? polyline.clone() : new PolylineGraphics(); + entity.polyline = polyline; + polyline.positions = createPositionPropertyArrayFromAltitudeMode(coordinates, altitudeMode, gxAltitudeMode); + if (!tessellate || canExtrude) { + polyline.followSurface = false; + } + } - var newColor = Property.getValueOrDefault(pointGraphics._color, time, defaultColor, color); - var newOutlineColor = Property.getValueOrDefault(pointGraphics._outlineColor, time, defaultOutlineColor, outlineColor); - var newOutlineWidth = Math.round(Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth)); - var newPixelSize = Math.max(1, Math.round(Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize))); + return true; + } - if (newOutlineWidth > 0) { - billboard.scale = 1.0; - needsRedraw = needsRedraw || // - newOutlineWidth !== item.outlineWidth || // - newPixelSize !== item.pixelSize || // - !Color.equals(newColor, item.color) || // - !Color.equals(newOutlineColor, item.outlineColor); - } else { - billboard.scale = newPixelSize / 50.0; - newPixelSize = 50.0; - needsRedraw = needsRedraw || // - newOutlineWidth !== item.outlineWidth || // - !Color.equals(newColor, item.color) || // - !Color.equals(newOutlineColor, item.outlineColor); - } + function processPolygon(dataSource, entityCollection, geometryNode, entity, styleEntity) { + var outerBoundaryIsNode = queryFirstNode(geometryNode, 'outerBoundaryIs', namespaces.kml); + var linearRingNode = queryFirstNode(outerBoundaryIsNode, 'LinearRing', namespaces.kml); + var coordinatesNode = queryFirstNode(linearRingNode, 'coordinates', namespaces.kml); + var coordinates = readCoordinates(coordinatesNode); + var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); + var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); + var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); + var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); - if (needsRedraw) { - item.color = Color.clone(newColor, item.color); - item.outlineColor = Color.clone(newOutlineColor, item.outlineColor); - item.pixelSize = newPixelSize; - item.outlineWidth = newOutlineWidth; + var polygon = defined(styleEntity.polygon) ? styleEntity.polygon.clone() : createDefaultPolygon(); - var centerAlpha = newColor.alpha; - var cssColor = newColor.toCssColorString(); - var cssOutlineColor = newOutlineColor.toCssColorString(); - var textureId = JSON.stringify([cssColor, newPixelSize, cssOutlineColor, newOutlineWidth]); + var polyline = styleEntity.polyline; + if (defined(polyline)) { + polygon.outlineColor = defined(polyline.material) ? polyline.material.color : Color.WHITE; + polygon.outlineWidth = polyline.width; + } + entity.polygon = polygon; + + if (canExtrude) { + polygon.perPositionHeight = true; + polygon.extrudedHeight = extrude ? 0 : undefined; + } else if (!dataSource._clampToGround) { + polygon.height = 0; + } - billboard.setImage(textureId, createCallback(centerAlpha, cssColor, cssOutlineColor, newOutlineWidth, newPixelSize)); + if (defined(coordinates)) { + var hierarchy = new PolygonHierarchy(coordinates); + var innerBoundaryIsNodes = queryChildNodes(geometryNode, 'innerBoundaryIs', namespaces.kml); + for (var j = 0; j < innerBoundaryIsNodes.length; j++) { + linearRingNode = queryChildNodes(innerBoundaryIsNodes[j], 'LinearRing', namespaces.kml); + for (var k = 0; k < linearRingNode.length; k++) { + coordinatesNode = queryFirstNode(linearRingNode[k], 'coordinates', namespaces.kml); + coordinates = readCoordinates(coordinatesNode); + if (defined(coordinates)) { + hierarchy.holes.push(new PolygonHierarchy(coordinates)); + } } } + polygon.hierarchy = hierarchy; } + return true; - }; + } - /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private - */ - PointVisualizer.prototype.getBoundingSphere = function(entity, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); + function processTrack(dataSource, entityCollection, geometryNode, entity, styleEntity) { + var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); + var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); + var coordNodes = queryChildNodes(geometryNode, 'coord', namespaces.gx); + var angleNodes = queryChildNodes(geometryNode, 'angles', namespaces.gx); + var timeNodes = queryChildNodes(geometryNode, 'when', namespaces.kml); + var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); + var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); + + if (angleNodes.length > 0) { + oneTimeWarning('kml-gx:angles', 'KML - gx:angles are not supported in gx:Tracks'); } - if (!defined(result)) { - throw new DeveloperError('result is required.'); + + var length = Math.min(coordNodes.length, timeNodes.length); + var coordinates = []; + var times = []; + for (var i = 0; i < length; i++) { + var position = readCoordinate(coordNodes[i].textContent); + coordinates.push(position); + times.push(JulianDate.fromIso8601(timeNodes[i].textContent)); } - - var item = this._items.get(entity.id); - if (!defined(item) || !(defined(item.pointPrimitive) || defined(item.billboard))) { - return BoundingSphereState.FAILED; + var property = new SampledPositionProperty(); + property.addSamples(times, coordinates); + entity.position = property; + processPositionGraphics(dataSource, entity, styleEntity, heightReferenceFromAltitudeMode(altitudeMode, gxAltitudeMode)); + processPathGraphics(entity, styleEntity); + + entity.availability = new TimeIntervalCollection(); + + if (timeNodes.length > 0) { + entity.availability.addInterval(new TimeInterval({ + start : times[0], + stop : times[times.length - 1] + })); } - if (defined(item.pointPrimitive)) { - result.center = Cartesian3.clone(item.pointPrimitive.position, result.center); - } else { - var billboard = item.billboard; - if (!defined(billboard._clampedPosition)) { - return BoundingSphereState.PENDING; - } - result.center = Cartesian3.clone(billboard._clampedPosition, result.center); + if (canExtrude && extrude) { + createDropLine(entityCollection, entity, styleEntity); } - result.radius = 0; - return BoundingSphereState.DONE; - }; + return true; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - PointVisualizer.prototype.isDestroyed = function() { - return false; - }; + function addToMultiTrack(times, positions, composite, availability, dropShowProperty, extrude, altitudeMode, gxAltitudeMode, includeEndPoints) { + var start = times[0]; + var stop = times[times.length - 1]; - /** - * Removes and destroys all primitives created by this instance. - */ - PointVisualizer.prototype.destroy = function() { - this._entityCollection.collectionChanged.removeEventListener(PointVisualizer.prototype._onCollectionChanged, this); - var entities = this._entityCollection.values; - for (var i = 0; i < entities.length; i++) { - this._cluster.removePoint(entities[i]); - } - return destroyObject(this); - }; + var data = new SampledPositionProperty(); + data.addSamples(times, positions); - PointVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) { - var i; - var entity; - var items = this._items; - var cluster = this._cluster; + composite.intervals.addInterval(new TimeInterval({ + start : start, + stop : stop, + isStartIncluded : includeEndPoints, + isStopIncluded : includeEndPoints, + data : createPositionPropertyFromAltitudeMode(data, altitudeMode, gxAltitudeMode) + })); + availability.addInterval(new TimeInterval({ + start : start, + stop : stop, + isStartIncluded : includeEndPoints, + isStopIncluded : includeEndPoints + })); + dropShowProperty.intervals.addInterval(new TimeInterval({ + start : start, + stop : stop, + isStartIncluded : includeEndPoints, + isStopIncluded : includeEndPoints, + data : extrude + })); + } - for (i = added.length - 1; i > -1; i--) { - entity = added[i]; - if (defined(entity._point) && defined(entity._position)) { - items.set(entity.id, new EntityData(entity)); + function processMultiTrack(dataSource, entityCollection, geometryNode, entity, styleEntity) { + // Multitrack options do not work in GE as detailed in the spec, + // rather than altitudeMode being at the MultiTrack level, + // GE just defers all settings to the underlying track. + + var interpolate = queryBooleanValue(geometryNode, 'interpolate', namespaces.gx); + var trackNodes = queryChildNodes(geometryNode, 'Track', namespaces.gx); + + var times; + var lastStop; + var lastStopPosition; + var needDropLine = false; + var dropShowProperty = new TimeIntervalCollectionProperty(); + var availability = new TimeIntervalCollection(); + var composite = new CompositePositionProperty(); + for (var i = 0, len = trackNodes.length; i < len; i++) { + var trackNode = trackNodes[i]; + var timeNodes = queryChildNodes(trackNode, 'when', namespaces.kml); + var coordNodes = queryChildNodes(trackNode, 'coord', namespaces.gx); + var altitudeMode = queryStringValue(trackNode, 'altitudeMode', namespaces.kml); + var gxAltitudeMode = queryStringValue(trackNode, 'altitudeMode', namespaces.gx); + var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); + var extrude = queryBooleanValue(trackNode, 'extrude', namespaces.kml); + + var length = Math.min(coordNodes.length, timeNodes.length); + + var positions = []; + times = []; + for (var x = 0; x < length; x++) { + var position = readCoordinate(coordNodes[x].textContent); + positions.push(position); + times.push(JulianDate.fromIso8601(timeNodes[x].textContent)); } - } - for (i = changed.length - 1; i > -1; i--) { - entity = changed[i]; - if (defined(entity._point) && defined(entity._position)) { - if (!items.contains(entity.id)) { - items.set(entity.id, new EntityData(entity)); + if (interpolate) { + //If we are interpolating, then we need to fill in the end of + //the last track and the beginning of this one with a sampled + //property. From testing in Google Earth, this property + //is never extruded and always absolute. + if (defined(lastStop)) { + addToMultiTrack([lastStop, times[0]], [lastStopPosition, positions[0]], composite, availability, dropShowProperty, false, 'absolute', undefined, false); } - } else { - returnPrimitive(items.get(entity.id), entity, cluster); - items.remove(entity.id); + lastStop = times[length - 1]; + lastStopPosition = positions[positions.length - 1]; } + + addToMultiTrack(times, positions, composite, availability, dropShowProperty, canExtrude && extrude, altitudeMode, gxAltitudeMode, true); + needDropLine = needDropLine || (canExtrude && extrude); } - for (i = removed.length - 1; i > -1; i--) { - entity = removed[i]; - returnPrimitive(items.get(entity.id), entity, cluster); - items.remove(entity.id); + entity.availability = availability; + entity.position = composite; + processPositionGraphics(dataSource, entity, styleEntity); + processPathGraphics(entity, styleEntity); + if (needDropLine) { + createDropLine(entityCollection, entity, styleEntity); + entity.polyline.show = dropShowProperty; } + + return true; + } + + var geometryTypes = { + Point : processPoint, + LineString : processLineStringOrLinearRing, + LinearRing : processLineStringOrLinearRing, + Polygon : processPolygon, + Track : processTrack, + MultiTrack : processMultiTrack, + MultiGeometry : processMultiGeometry, + Model : processUnsupportedGeometry }; - function returnPrimitive(item, entity, cluster) { - if (defined(item)) { - var pointPrimitive = item.pointPrimitive; - if (defined(pointPrimitive)) { - item.pointPrimitive = undefined; - cluster.removePoint(entity); - return; - } - var billboard = item.billboard; - if (defined(billboard)) { - item.billboard = undefined; - cluster.removeBillboard(entity); + function processMultiGeometry(dataSource, entityCollection, geometryNode, entity, styleEntity, context) { + var childNodes = geometryNode.childNodes; + var hasGeometry = false; + for (var i = 0, len = childNodes.length; i < len; i++) { + var childNode = childNodes.item(i); + var geometryProcessor = geometryTypes[childNode.localName]; + if (defined(geometryProcessor)) { + var childEntity = createEntity(childNode, entityCollection, context); + childEntity.parent = entity; + childEntity.name = entity.name; + childEntity.availability = entity.availability; + childEntity.description = entity.description; + childEntity.kml = entity.kml; + if (geometryProcessor(dataSource, entityCollection, childNode, childEntity, styleEntity)) { + hasGeometry = true; + } } } + + return hasGeometry; } - function createCallback(centerAlpha, cssColor, cssOutlineColor, cssOutlineWidth, newPixelSize) { - return function(id) { - var canvas = document.createElement('canvas'); + function processUnsupportedGeometry(dataSource, entityCollection, geometryNode, entity, styleEntity) { + oneTimeWarning('kml-unsupportedGeometry', 'KML - Unsupported geometry: ' + geometryNode.localName); + return false; + } - var length = newPixelSize + (2 * cssOutlineWidth); - canvas.height = canvas.width = length; + function processExtendedData(node, entity) { + var extendedDataNode = queryFirstNode(node, 'ExtendedData', namespaces.kml); - var context2D = canvas.getContext('2d'); - context2D.clearRect(0, 0, length, length); + if (!defined(extendedDataNode)) { + return undefined; + } - if (cssOutlineWidth !== 0) { - context2D.beginPath(); - context2D.arc(length / 2, length / 2, length / 2, 0, 2 * Math.PI, true); - context2D.closePath(); - context2D.fillStyle = cssOutlineColor; - context2D.fill(); - // Punch a hole in the center if needed. - if (centerAlpha < 1.0) { - context2D.save(); - context2D.globalCompositeOperation = 'destination-out'; - context2D.beginPath(); - context2D.arc(length / 2, length / 2, newPixelSize / 2, 0, 2 * Math.PI, true); - context2D.closePath(); - context2D.fillStyle = 'black'; - context2D.fill(); - context2D.restore(); + if (defined(queryFirstNode(extendedDataNode, 'SchemaData', namespaces.kml))) { + oneTimeWarning('kml-schemaData', 'KML - SchemaData is unsupported'); + } + if (defined(queryStringAttribute(extendedDataNode, 'xmlns:prefix'))) { + oneTimeWarning('kml-extendedData', 'KML - ExtendedData with xmlns:prefix is unsupported'); + } + + var result = {}; + var dataNodes = queryChildNodes(extendedDataNode, 'Data', namespaces.kml); + if (defined(dataNodes)) { + var length = dataNodes.length; + for (var i = 0; i < length; i++) { + var dataNode = dataNodes[i]; + var name = queryStringAttribute(dataNode, 'name'); + if (defined(name)) { + result[name] = { + displayName : queryStringValue(dataNode, 'displayName', namespaces.kml), + value : queryStringValue(dataNode, 'value', namespaces.kml) + }; } } - - context2D.beginPath(); - context2D.arc(length / 2, length / 2, newPixelSize / 2, 0, 2 * Math.PI, true); - context2D.closePath(); - context2D.fillStyle = cssColor; - context2D.fill(); - - return canvas; - }; + } + entity.kml.extendedData = result; } + var scratchDiv = document.createElement('div'); - return PointVisualizer; -}); + function processDescription(node, entity, styleEntity, uriResolver, sourceResource) { + var i; + var key; + var keys; -define('DataSources/PolygonGeometryUpdater',[ - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/isArray', - '../Core/Iso8601', - '../Core/oneTimeWarning', - '../Core/PolygonGeometry', - '../Core/PolygonHierarchy', - '../Core/PolygonOutlineGeometry', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/GroundPrimitive', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' - ], function( - Color, - ColorGeometryInstanceAttribute, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - isArray, - Iso8601, - oneTimeWarning, - PolygonGeometry, - PolygonHierarchy, - PolygonOutlineGeometry, - ShowGeometryInstanceAttribute, - GroundPrimitive, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { - 'use strict'; + var kmlData = entity.kml; + var extendedData = kmlData.extendedData; + var description = queryStringValue(node, 'description', namespaces.kml); - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + var balloonStyle = defaultValue(entity.balloonStyle, styleEntity.balloonStyle); - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.polygonHierarchy = undefined; - this.perPositionHeight = undefined; - this.closeTop = undefined; - this.closeBottom = undefined; - this.height = undefined; - this.extrudedHeight = undefined; - this.granularity = undefined; - this.stRotation = undefined; - } + var background = Color.WHITE; + var foreground = Color.BLACK; + var text = description; - /** - * A {@link GeometryUpdater} for polygons. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias PolygonGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function PolygonGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + if (defined(balloonStyle)) { + background = defaultValue(balloonStyle.bgColor, Color.WHITE); + foreground = defaultValue(balloonStyle.textColor, Color.BLACK); + text = defaultValue(balloonStyle.text, description); } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(PolygonGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._isClosed = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._onTerrain = false; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'polygon', entity.polygon, undefined); - } - defineProperties(PolygonGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof PolygonGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof PolygonGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance - } - }); + var value; + if (defined(text)) { + text = text.replace('$[name]', defaultValue(entity.name, '')); + text = text.replace('$[description]', defaultValue(description, '')); + text = text.replace('$[address]', defaultValue(kmlData.address, '')); + text = text.replace('$[Snippet]', defaultValue(kmlData.snippet, '')); + text = text.replace('$[id]', entity.id); - defineProperties(PolygonGeometryUpdater.prototype, { - /** - * Gets the entity associated with this geometry. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Entity} - * @readonly - */ - entity : { - get : function() { - return this._entity; - } - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, - /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, - /** - * Gets the material property used to fill the geometry. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly - */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); - } - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - outlineColorProperty : { - get : function() { - return this._outlineColorProperty; - } - }, - /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Number} - * @readonly - */ - outlineWidth : { - get : function() { - return this._outlineWidth; - } - }, - /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; - } - }, - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayConditionProperty; - } - }, - /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isDynamic : { - get : function() { - return this._dynamic; - } - }, - /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isClosed : { - get : function() { - return this._isClosed; - } - }, - /** - * Gets a value indicating if the geometry should be drawn on terrain. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - onTerrain : { - get : function() { - return this._onTerrain; + //While not explicitly defined by the OGC spec, in Google Earth + //The appearance of geDirections adds the directions to/from links + //We simply replace this string with nothing. + text = text.replace('$[geDirections]', ''); + + if (defined(extendedData)) { + var matches = text.match(/\$\[.+?\]/g); + if (matches !== null) { + for (i = 0; i < matches.length; i++) { + var token = matches[i]; + var propertyName = token.substr(2, token.length - 3); + var isDisplayName = /\/displayName$/.test(propertyName); + propertyName = propertyName.replace(/\/displayName$/, ''); + + value = extendedData[propertyName]; + if (defined(value)) { + value = isDisplayName ? value.displayName : value.value; + } + if (defined(value)) { + text = text.replace(token, defaultValue(value, '')); + } + } + } } - }, - /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof PolygonGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - geometryChanged : { - get : function() { - return this._geometryChanged; + } else if (defined(extendedData)) { + //If no description exists, build a table out of the extended data + keys = Object.keys(extendedData); + if (keys.length > 0) { + text = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>'; + for (i = 0; i < keys.length; i++) { + key = keys[i]; + value = extendedData[key]; + text += '<tr><th>' + defaultValue(value.displayName, key) + '</th><td>' + defaultValue(value.value, '') + '</td></tr>'; + } + text += '</tbody></table>'; } } - }); - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - PolygonGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + if (!defined(text)) { + //No description + return; + } - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - PolygonGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; + //Turns non-explicit links into clickable links. + text = autolinker.link(text); - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - PolygonGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + //Use a temporary div to manipulate the links + //so that they open in a new window. + scratchDiv.innerHTML = text; + var links = scratchDiv.querySelectorAll('a'); + for (i = 0; i < links.length; i++) { + links[i].setAttribute('target', '_blank'); } - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); + //Rewrite any KMZ embedded urls + if (defined(uriResolver) && uriResolver.keys.length > 1) { + embedDataUris(scratchDiv, 'a', 'href', uriResolver); + embedDataUris(scratchDiv, 'img', 'src', uriResolver); } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var attributes; + //Make relative urls absolute using the sourceResource + applyBasePath(scratchDiv, 'a', 'href', sourceResource); + applyBasePath(scratchDiv, 'img', 'src', sourceResource); - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; + var tmp = '<div class="cesium-infoBox-description-lighter" style="'; + tmp += 'overflow:auto;'; + tmp += 'word-wrap:break-word;'; + tmp += 'background-color:' + background.toCssColorString() + ';'; + tmp += 'color:' + foreground.toCssColorString() + ';'; + tmp += '">'; + tmp += scratchDiv.innerHTML + '</div>'; + scratchDiv.innerHTML = ''; + + //Set the final HTML as the description. + entity.description = tmp; + } + + function processFeature(dataSource, parent, featureNode, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var entity = createEntity(featureNode, entityCollection, context); + var kmlData = entity.kml; + var styleEntity = computeFinalStyle(dataSource, featureNode, styleCollection, sourceResource, uriResolver); + + var name = queryStringValue(featureNode, 'name', namespaces.kml); + entity.name = name; + entity.parent = parent; + + var availability = processTimeSpan(featureNode); + if (!defined(availability)) { + availability = processTimeStamp(featureNode); } + entity.availability = availability; - return new GeometryInstance({ - id : entity, - geometry : new PolygonGeometry(this._options), - attributes : attributes - }); - }; + mergeAvailabilityWithParent(entity); - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - PolygonGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + // Per KML spec "A Feature is visible only if it and all its ancestors are visible." + function ancestryIsVisible(parentEntity) { + if (!parentEntity) { + return true; + } + return parentEntity.show && ancestryIsVisible(parentEntity.parent); } - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + var visibility = queryBooleanValue(featureNode, 'visibility', namespaces.kml); + entity.show = ancestryIsVisible(parent) && defaultValue(visibility, true); + //var open = queryBooleanValue(featureNode, 'open', namespaces.kml); + + var authorNode = queryFirstNode(featureNode, 'author', namespaces.atom); + var author = kmlData.author; + author.name = queryStringValue(authorNode, 'name', namespaces.atom); + author.uri = queryStringValue(authorNode, 'uri', namespaces.atom); + author.email = queryStringValue(authorNode, 'email', namespaces.atom); + + var linkNode = queryFirstNode(featureNode, 'link', namespaces.atom); + var link = kmlData.link; + link.href = queryStringAttribute(linkNode, 'href'); + link.hreflang = queryStringAttribute(linkNode, 'hreflang'); + link.rel = queryStringAttribute(linkNode, 'rel'); + link.type = queryStringAttribute(linkNode, 'type'); + link.title = queryStringAttribute(linkNode, 'title'); + link.length = queryStringAttribute(linkNode, 'length'); + + kmlData.address = queryStringValue(featureNode, 'address', namespaces.kml); + kmlData.phoneNumber = queryStringValue(featureNode, 'phoneNumber', namespaces.kml); + kmlData.snippet = queryStringValue(featureNode, 'Snippet', namespaces.kml); + + processExtendedData(featureNode, entity); + processDescription(featureNode, entity, styleEntity, uriResolver, sourceResource); + processLookAt(featureNode, entity); + processCamera(featureNode, entity); + + if (defined(queryFirstNode(featureNode, 'Region', namespaces.kml))) { + oneTimeWarning('kml-region', 'KML - Placemark Regions are unsupported'); } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - return new GeometryInstance({ - id : entity, - geometry : new PolygonOutlineGeometry(this._options), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) - } - }); - }; + return { + entity : entity, + styleEntity : styleEntity + }; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - PolygonGeometryUpdater.prototype.isDestroyed = function() { - return false; + // Ensure Specs/Data/KML/unsupported.kml is kept up to date with these supported types + var featureTypes = { + Document : processDocument, + Folder : processFolder, + Placemark : processPlacemark, + NetworkLink : processNetworkLink, + GroundOverlay : processGroundOverlay, + PhotoOverlay : processUnsupportedFeature, + ScreenOverlay : processUnsupportedFeature, + Tour : processTour }; - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - PolygonGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + function processDocument(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var featureTypeNames = Object.keys(featureTypes); + var featureTypeNamesLength = featureTypeNames.length; - PolygonGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'polygon')) { - return; + for (var i = 0; i < featureTypeNamesLength; i++) { + var featureName = featureTypeNames[i]; + var processFeatureNode = featureTypes[featureName]; + + var childNodes = node.childNodes; + var length = childNodes.length; + for (var q = 0; q < length; q++) { + var child = childNodes[q]; + if (child.localName === featureName && + ((namespaces.kml.indexOf(child.namespaceURI) !== -1) || (namespaces.gx.indexOf(child.namespaceURI) !== -1))) { + processFeatureNode(dataSource, parent, child, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + } + } } + } - var polygon = this._entity.polygon; + function processFolder(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var r = processFeature(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + processDocument(dataSource, r.entity, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + } - if (!defined(polygon)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + function processPlacemark(dataSource, parent, placemark, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var r = processFeature(dataSource, parent, placemark, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + var entity = r.entity; + var styleEntity = r.styleEntity; + + var hasGeometry = false; + var childNodes = placemark.childNodes; + for (var i = 0, len = childNodes.length; i < len && !hasGeometry; i++) { + var childNode = childNodes.item(i); + var geometryProcessor = geometryTypes[childNode.localName]; + if (defined(geometryProcessor)) { + // pass the placemark entity id as a context for case of defining multiple child entities together to handle case + // where some malformed kmls reuse the same id across placemarks, which works in GE, but is not technically to spec. + geometryProcessor(dataSource, entityCollection, childNode, entity, styleEntity, entity.id); + hasGeometry = true; } - return; } - var fillProperty = polygon.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + if (!hasGeometry) { + entity.merge(styleEntity); + processPositionGraphics(dataSource, entity, styleEntity); + } + } - var perPositionHeightProperty = polygon.perPositionHeight; - var perPositionHeightEnabled = defined(perPositionHeightProperty) && (perPositionHeightProperty.isConstant ? perPositionHeightProperty.getValue(Iso8601.MINIMUM_VALUE) : true); + var playlistNodeProcessors = { + FlyTo: processTourFlyTo, + Wait: processTourWait, + SoundCue: processTourUnsupportedNode, + AnimatedUpdate: processTourUnsupportedNode, + TourControl: processTourUnsupportedNode + }; - var outlineProperty = polygon.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); - } + function processTour(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var name = queryStringValue(node, 'name', namespaces.kml); + var id = queryStringAttribute(node, 'id'); + var tour = new KmlTour(name, id); - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + var playlistNode = queryFirstNode(node, 'Playlist', namespaces.gx); + if(playlistNode) { + var childNodes = playlistNode.childNodes; + for(var i = 0; i < childNodes.length; i++) { + var entryNode = childNodes[i]; + if (entryNode.localName) { + var playlistNodeProcessor = playlistNodeProcessors[entryNode.localName]; + if (playlistNodeProcessor) { + playlistNodeProcessor(tour, entryNode); + } + else { + console.log('Unknown KML Tour playlist entry type ' + entryNode.localName); + } + } } - return; } - var hierarchy = polygon.hierarchy; + if (!defined(dataSource.kmlTours)) { + dataSource.kmlTours = []; + } - var show = polygon.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(hierarchy))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + dataSource.kmlTours.push(tour); + } + + function processTourUnsupportedNode(tour, entryNode) { + oneTimeWarning('KML Tour unsupported node ' + entryNode.localName); + } + + function processTourWait(tour, entryNode) { + var duration = queryNumericValue(entryNode, 'duration', namespaces.gx); + tour.addPlaylistEntry(new KmlTourWait(duration)); + } + + function processTourFlyTo(tour, entryNode) { + var duration = queryNumericValue(entryNode, 'duration', namespaces.gx); + var flyToMode = queryStringValue(entryNode, 'flyToMode', namespaces.gx); + + var t = {kml: {}}; + + processLookAt(entryNode, t); + processCamera(entryNode, t); + + var view = t.kml.lookAt || t.kml.camera; + + var flyto = new KmlTourFlyTo(duration, flyToMode, view); + tour.addPlaylistEntry(flyto); + } + + function processCamera(featureNode, entity) { + var camera = queryFirstNode(featureNode, 'Camera', namespaces.kml); + if(defined(camera)) { + var lon = defaultValue(queryNumericValue(camera, 'longitude', namespaces.kml), 0.0); + var lat = defaultValue(queryNumericValue(camera, 'latitude', namespaces.kml), 0.0); + var altitude = defaultValue(queryNumericValue(camera, 'altitude', namespaces.kml), 0.0); + + var heading = defaultValue(queryNumericValue(camera, 'heading', namespaces.kml), 0.0); + var tilt = defaultValue(queryNumericValue(camera, 'tilt', namespaces.kml), 0.0); + var roll = defaultValue(queryNumericValue(camera, 'roll', namespaces.kml), 0.0); + + var position = Cartesian3.fromDegrees(lon, lat, altitude); + var hpr = HeadingPitchRoll.fromDegrees(heading, tilt - 90.0, roll); + + entity.kml.camera = new KmlCamera(position, hpr); } + } - var material = defaultValue(polygon.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(polygon.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(polygon.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(polygon.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(polygon.distanceDisplayCondition, defaultDistanceDisplayCondition); + function processLookAt(featureNode, entity) { + var lookAt = queryFirstNode(featureNode, 'LookAt', namespaces.kml); + if(defined(lookAt)) { + var lon = defaultValue(queryNumericValue(lookAt, 'longitude', namespaces.kml), 0.0); + var lat = defaultValue(queryNumericValue(lookAt, 'latitude', namespaces.kml), 0.0); + var altitude = defaultValue(queryNumericValue(lookAt, 'altitude', namespaces.kml), 0.0); + var heading = queryNumericValue(lookAt, 'heading', namespaces.kml); + var tilt = queryNumericValue(lookAt, 'tilt', namespaces.kml); + var range = defaultValue(queryNumericValue(lookAt, 'range', namespaces.kml), 0.0); - var height = polygon.height; - var extrudedHeight = polygon.extrudedHeight; - var granularity = polygon.granularity; - var stRotation = polygon.stRotation; - var outlineWidth = polygon.outlineWidth; - var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && isColorMaterial && - !perPositionHeightEnabled && GroundPrimitive.isSupported(this._scene); + tilt = CesiumMath.toRadians(defaultValue(tilt, 0.0)); + heading = CesiumMath.toRadians(defaultValue(heading, 0.0)); - if (outlineEnabled && onTerrain) { - oneTimeWarning(oneTimeWarning.geometryOutlines); - outlineEnabled = false; + var hpr = new HeadingPitchRange(heading, tilt - CesiumMath.PI_OVER_TWO, range); + var viewPoint = Cartesian3.fromDegrees(lon, lat, altitude); + + entity.kml.lookAt = new KmlLookAt(viewPoint, hpr); } + } - var perPositionHeight = polygon.perPositionHeight; - var closeTop = polygon.closeTop; - var closeBottom = polygon.closeBottom; + function processGroundOverlay(dataSource, parent, groundOverlay, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var r = processFeature(dataSource, parent, groundOverlay, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + var entity = r.entity; - this._fillEnabled = fillEnabled; - this._onTerrain = onTerrain; - this._outlineEnabled = outlineEnabled; + var geometry; + var isLatLonQuad = false; - if (!hierarchy.isConstant || // - !Property.isConstant(height) || // - !Property.isConstant(extrudedHeight) || // - !Property.isConstant(granularity) || // - !Property.isConstant(stRotation) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(perPositionHeightProperty) || // - !Property.isConstant(perPositionHeight) || // - !Property.isConstant(closeTop) || // - !Property.isConstant(closeBottom) || // - (onTerrain && !Property.isConstant(material))) { + var positions = readCoordinates(queryFirstNode(groundOverlay, 'LatLonQuad', namespaces.gx)); + if (defined(positions)) { + geometry = createDefaultPolygon(); + geometry.hierarchy = new PolygonHierarchy(positions); + entity.polygon = geometry; + isLatLonQuad = true; + } else { + geometry = new RectangleGraphics(); + entity.rectangle = geometry; - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + var latLonBox = queryFirstNode(groundOverlay, 'LatLonBox', namespaces.kml); + if (defined(latLonBox)) { + var west = queryNumericValue(latLonBox, 'west', namespaces.kml); + var south = queryNumericValue(latLonBox, 'south', namespaces.kml); + var east = queryNumericValue(latLonBox, 'east', namespaces.kml); + var north = queryNumericValue(latLonBox, 'north', namespaces.kml); + + if (defined(west)) { + west = CesiumMath.negativePiToPi(CesiumMath.toRadians(west)); + } + if (defined(south)) { + south = CesiumMath.clampToLatitudeRange(CesiumMath.toRadians(south)); + } + if (defined(east)) { + east = CesiumMath.negativePiToPi(CesiumMath.toRadians(east)); + } + if (defined(north)) { + north = CesiumMath.clampToLatitudeRange(CesiumMath.toRadians(north)); + } + geometry.coordinates = new Rectangle(west, south, east, north); + + var rotation = queryNumericValue(latLonBox, 'rotation', namespaces.kml); + if (defined(rotation)) { + var rotationRadians = CesiumMath.toRadians(rotation); + geometry.rotation = rotationRadians; + geometry.stRotation = rotationRadians; + } } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; + } - var hierarchyValue = hierarchy.getValue(Iso8601.MINIMUM_VALUE); - if (isArray(hierarchyValue)) { - hierarchyValue = new PolygonHierarchy(hierarchyValue); + var iconNode = queryFirstNode(groundOverlay, 'Icon', namespaces.kml); + var href = getIconHref(iconNode, dataSource, sourceResource, uriResolver, true); + if (defined(href)) { + if (isLatLonQuad) { + oneTimeWarning('kml-gx:LatLonQuad', 'KML - gx:LatLonQuad Icon does not support texture projection.'); } + var x = queryNumericValue(iconNode, 'x', namespaces.gx); + var y = queryNumericValue(iconNode, 'y', namespaces.gx); + var w = queryNumericValue(iconNode, 'w', namespaces.gx); + var h = queryNumericValue(iconNode, 'h', namespaces.gx); - var heightValue = Property.getValueOrUndefined(height, Iso8601.MINIMUM_VALUE); - var closeTopValue = Property.getValueOrDefault(closeTop, Iso8601.MINIMUM_VALUE, true); - var closeBottomValue = Property.getValueOrDefault(closeBottom, Iso8601.MINIMUM_VALUE, true); - var extrudedHeightValue = Property.getValueOrUndefined(extrudedHeight, Iso8601.MINIMUM_VALUE); + if (defined(x) || defined(y) || defined(w) || defined(h)) { + oneTimeWarning('kml-groundOverlay-xywh', 'KML - gx:x, gx:y, gx:w, gx:h aren\'t supported for GroundOverlays'); + } - options.polygonHierarchy = hierarchyValue; - options.height = heightValue; - options.extrudedHeight = extrudedHeightValue; - options.granularity = Property.getValueOrUndefined(granularity, Iso8601.MINIMUM_VALUE); - options.stRotation = Property.getValueOrUndefined(stRotation, Iso8601.MINIMUM_VALUE); - options.perPositionHeight = Property.getValueOrUndefined(perPositionHeight, Iso8601.MINIMUM_VALUE); - options.closeTop = closeTopValue; - options.closeBottom = closeBottomValue; - this._outlineWidth = Property.getValueOrDefault(outlineWidth, Iso8601.MINIMUM_VALUE, 1.0); - this._isClosed = defined(extrudedHeightValue) && extrudedHeightValue !== heightValue && closeTopValue && closeBottomValue; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); + geometry.material = href; + geometry.material.color = queryColorValue(groundOverlay, 'color', namespaces.kml); + geometry.material.transparent = true; + } else { + geometry.material = queryColorValue(groundOverlay, 'color', namespaces.kml); + } + + var altitudeMode = queryStringValue(groundOverlay, 'altitudeMode', namespaces.kml); + + if (defined(altitudeMode)) { + if (altitudeMode === 'absolute') { + //Use height above ellipsoid until we support MSL. + geometry.height = queryNumericValue(groundOverlay, 'altitude', namespaces.kml); + } else if (altitudeMode !== 'clampToGround') { + oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + altitudeMode); + } + // else just use the default of 0 until we support 'clampToGround' + } else { + altitudeMode = queryStringValue(groundOverlay, 'altitudeMode', namespaces.gx); + if (altitudeMode === 'relativeToSeaFloor') { + oneTimeWarning('kml-altitudeMode-relativeToSeaFloor', 'KML - altitudeMode relativeToSeaFloor is currently not supported, treating as absolute.'); + geometry.height = queryNumericValue(groundOverlay, 'altitude', namespaces.kml); + } else if (altitudeMode === 'clampToSeaFloor') { + oneTimeWarning('kml-altitudeMode-clampToSeaFloor', 'KML - altitudeMode clampToSeaFloor is currently not supported, treating as clampToGround.'); + } else if (defined(altitudeMode)) { + oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + altitudeMode); + } } + } + + function processUnsupportedFeature(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + dataSource._unsupportedNode.raiseEvent(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver); + oneTimeWarning('kml-unsupportedFeature-' + node.nodeName, 'KML - Unsupported feature: ' + node.nodeName); + } + + var RefreshMode = { + INTERVAL : 0, + EXPIRE : 1, + STOP : 2 }; - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @param {PrimitiveCollection} groundPrimitives The ground primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - PolygonGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); + function cleanupString(s) { + if (!defined(s) || s.length === 0) { + return ''; } - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); + var sFirst = s[0]; + if (sFirst === '&' || sFirst === '?') { + s = s.substring(1); } - - return new DynamicGeometryUpdater(primitives, groundPrimitives, this); - }; - /** - * @private - */ - function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { - this._primitives = primitives; - this._groundPrimitives = groundPrimitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); + return s; } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var geometryUpdater = this._geometryUpdater; - var onTerrain = geometryUpdater._onTerrain; + var zeroRectangle = new Rectangle(); + var scratchCartographic = new Cartographic(); + var scratchCartesian2 = new Cartesian2(); + var scratchCartesian3 = new Cartesian3(); - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._outlinePrimitive = undefined; + function processNetworkLinkQueryString(resource, camera, canvas, viewBoundScale, bbox) { + function fixLatitude(value) { + if (value < -CesiumMath.PI_OVER_TWO) { + return -CesiumMath.PI_OVER_TWO; + } else if (value > CesiumMath.PI_OVER_TWO) { + return CesiumMath.PI_OVER_TWO; + } + return value; } - this._primitive = undefined; - var entity = geometryUpdater._entity; - var polygon = entity.polygon; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(polygon.show, time, true)) { - return; + function fixLongitude(value) { + if (value > CesiumMath.PI) { + return value - CesiumMath.TWO_PI; + } else if (value < -CesiumMath.PI) { + return value + CesiumMath.TWO_PI; + } + + return value; } - var options = this._options; - var hierarchy = Property.getValueOrUndefined(polygon.hierarchy, time); - if (!defined(hierarchy)) { - return; + var queryString = objectToQuery(resource.queryParameters); + + // objectToQuery escapes [ and ], so fix that + queryString = queryString.replace(/%5B/g, '[').replace(/%5D/g, ']'); + + if (defined(camera) && camera._mode !== SceneMode.MORPHING) { + var wgs84 = Ellipsoid.WGS84; + var centerCartesian; + var centerCartographic; + + bbox = defaultValue(bbox, zeroRectangle); + if (defined(canvas)) { + scratchCartesian2.x = canvas.clientWidth * 0.5; + scratchCartesian2.y = canvas.clientHeight * 0.5; + centerCartesian = camera.pickEllipsoid(scratchCartesian2, wgs84, scratchCartesian3); + } + + if (defined(centerCartesian)) { + centerCartographic = wgs84.cartesianToCartographic(centerCartesian, scratchCartographic); + } else { + centerCartographic = Rectangle.center(bbox, scratchCartographic); + centerCartesian = wgs84.cartographicToCartesian(centerCartographic); + } + + if (defined(viewBoundScale) && !CesiumMath.equalsEpsilon(viewBoundScale, 1.0, CesiumMath.EPSILON9)) { + var newHalfWidth = bbox.width * viewBoundScale * 0.5; + var newHalfHeight = bbox.height * viewBoundScale * 0.5; + bbox = new Rectangle(fixLongitude(centerCartographic.longitude - newHalfWidth), + fixLatitude(centerCartographic.latitude - newHalfHeight), + fixLongitude(centerCartographic.longitude + newHalfWidth), + fixLatitude(centerCartographic.latitude + newHalfHeight) + ); + } + + queryString = queryString.replace('[bboxWest]', CesiumMath.toDegrees(bbox.west).toString()); + queryString = queryString.replace('[bboxSouth]', CesiumMath.toDegrees(bbox.south).toString()); + queryString = queryString.replace('[bboxEast]', CesiumMath.toDegrees(bbox.east).toString()); + queryString = queryString.replace('[bboxNorth]', CesiumMath.toDegrees(bbox.north).toString()); + + var lon = CesiumMath.toDegrees(centerCartographic.longitude).toString(); + var lat = CesiumMath.toDegrees(centerCartographic.latitude).toString(); + queryString = queryString.replace('[lookatLon]', lon); + queryString = queryString.replace('[lookatLat]', lat); + queryString = queryString.replace('[lookatTilt]', CesiumMath.toDegrees(camera.pitch).toString()); + queryString = queryString.replace('[lookatHeading]', CesiumMath.toDegrees(camera.heading).toString()); + queryString = queryString.replace('[lookatRange]', Cartesian3.distance(camera.positionWC, centerCartesian)); + queryString = queryString.replace('[lookatTerrainLon]', lon); + queryString = queryString.replace('[lookatTerrainLat]', lat); + queryString = queryString.replace('[lookatTerrainAlt]', centerCartographic.height.toString()); + + wgs84.cartesianToCartographic(camera.positionWC, scratchCartographic); + queryString = queryString.replace('[cameraLon]', CesiumMath.toDegrees(scratchCartographic.longitude).toString()); + queryString = queryString.replace('[cameraLat]', CesiumMath.toDegrees(scratchCartographic.latitude).toString()); + queryString = queryString.replace('[cameraAlt]', CesiumMath.toDegrees(scratchCartographic.height).toString()); + + var frustum = camera.frustum; + var aspectRatio = frustum.aspectRatio; + var horizFov = ''; + var vertFov = ''; + if (defined(aspectRatio)) { + var fov = CesiumMath.toDegrees(frustum.fov); + if (aspectRatio > 1.0) { + horizFov = fov; + vertFov = fov / aspectRatio; + } else { + vertFov = fov; + horizFov = fov * aspectRatio; + } + } + queryString = queryString.replace('[horizFov]', horizFov.toString()); + queryString = queryString.replace('[vertFov]', vertFov.toString()); + } else { + queryString = queryString.replace('[bboxWest]', '-180'); + queryString = queryString.replace('[bboxSouth]', '-90'); + queryString = queryString.replace('[bboxEast]', '180'); + queryString = queryString.replace('[bboxNorth]', '90'); + + queryString = queryString.replace('[lookatLon]', ''); + queryString = queryString.replace('[lookatLat]', ''); + queryString = queryString.replace('[lookatRange]', ''); + queryString = queryString.replace('[lookatTilt]', ''); + queryString = queryString.replace('[lookatHeading]', ''); + queryString = queryString.replace('[lookatTerrainLon]', ''); + queryString = queryString.replace('[lookatTerrainLat]', ''); + queryString = queryString.replace('[lookatTerrainAlt]', ''); + + queryString = queryString.replace('[cameraLon]', ''); + queryString = queryString.replace('[cameraLat]', ''); + queryString = queryString.replace('[cameraAlt]', ''); + queryString = queryString.replace('[horizFov]', ''); + queryString = queryString.replace('[vertFov]', ''); } - if (isArray(hierarchy)) { - options.polygonHierarchy = new PolygonHierarchy(hierarchy); + if (defined(canvas)) { + queryString = queryString.replace('[horizPixels]', canvas.clientWidth); + queryString = queryString.replace('[vertPixels]', canvas.clientHeight); } else { - options.polygonHierarchy = hierarchy; + queryString = queryString.replace('[horizPixels]', ''); + queryString = queryString.replace('[vertPixels]', ''); } - var closeTopValue = Property.getValueOrDefault(polygon.closeTop, time, true); - var closeBottomValue = Property.getValueOrDefault(polygon.closeBottom, time, true); + queryString = queryString.replace('[terrainEnabled]', '1'); + queryString = queryString.replace('[clientVersion]', '1'); + queryString = queryString.replace('[kmlVersion]', '2.2'); + queryString = queryString.replace('[clientName]', 'Cesium'); + queryString = queryString.replace('[language]', 'English'); - options.height = Property.getValueOrUndefined(polygon.height, time); - options.extrudedHeight = Property.getValueOrUndefined(polygon.extrudedHeight, time); - options.granularity = Property.getValueOrUndefined(polygon.granularity, time); - options.stRotation = Property.getValueOrUndefined(polygon.stRotation, time); - options.perPositionHeight = Property.getValueOrUndefined(polygon.perPositionHeight, time); - options.closeTop = closeTopValue; - options.closeBottom = closeBottomValue; + resource.addQueryParameters(queryToObject(queryString)); + } - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + function processNetworkLink(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var r = processFeature(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + var networkEntity = r.entity; - if (Property.getValueOrDefault(polygon.fill, time, true)) { - var fillMaterialProperty = geometryUpdater.fillMaterialProperty; - var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); - this._material = material; + var link = queryFirstNode(node, 'Link', namespaces.kml); - if (onTerrain) { - var currentColor = Color.WHITE; - if (defined(fillMaterialProperty.color)) { - currentColor = fillMaterialProperty.color.getValue(time); + if (!defined(link)) { + link = queryFirstNode(node, 'Url', namespaces.kml); + } + if (defined(link)) { + var href = queryStringValue(link, 'href', namespaces.kml); + var viewRefreshMode; + var viewBoundScale; + if (defined(href)) { + var newSourceUri = href; + href = resolveHref(href, sourceResource, uriResolver); + + // We need to pass in the original path if resolveHref returns a data uri because the network link + // references a document in a KMZ archive + if (/^data:/.test(href.getUrlComponent())) { + // So if sourceUri isn't the kmz file, then its another kml in the archive, so resolve it + if (!/\.kmz/i.test(sourceResource.getUrlComponent())) { + newSourceUri = sourceResource.getDerivedResource({ + url: newSourceUri + }); + } + } else { + newSourceUri = href.clone(); // Not a data uri so use the fully qualified uri + viewRefreshMode = queryStringValue(link, 'viewRefreshMode', namespaces.kml); + viewBoundScale = defaultValue(queryStringValue(link, 'viewBoundScale', namespaces.kml), 1.0); + var defaultViewFormat = (viewRefreshMode === 'onStop') ? 'BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]' : ''; + var viewFormat = defaultValue(queryStringValue(link, 'viewFormat', namespaces.kml), defaultViewFormat); + var httpQuery = queryStringValue(link, 'httpQuery', namespaces.kml); + if (defined(viewFormat)) { + href.addQueryParameters(queryToObject(cleanupString(viewFormat))); + } + if (defined(httpQuery)) { + href.addQueryParameters(queryToObject(cleanupString(httpQuery))); + } + + processNetworkLinkQueryString(href, dataSource._camera, dataSource._canvas, viewBoundScale, dataSource._lastCameraView.bbox); } - this._primitive = groundPrimitives.add(new GroundPrimitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PolygonGeometry(options), - attributes: { - color: ColorGeometryInstanceAttribute.fromColor(currentColor) + var options = { + sourceUri : newSourceUri, + uriResolver : uriResolver, + context : networkEntity.id + }; + var networkLinkCollection = new EntityCollection(); + var promise = load(dataSource, networkLinkCollection, href, options).then(function(rootElement) { + var entities = dataSource._entityCollection; + var newEntities = networkLinkCollection.values; + entities.suspendEvents(); + for (var i = 0; i < newEntities.length; i++) { + var newEntity = newEntities[i]; + if (!defined(newEntity.parent)) { + newEntity.parent = networkEntity; + mergeAvailabilityWithParent(newEntity); } - }), - asynchronous : false, - shadows : shadows - })); - } else { - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : defined(options.extrudedHeight) && options.extrudedHeight !== options.height && closeTopValue && closeBottomValue + + entities.add(newEntity); + } + entities.resumeEvents(); + + // Add network links to a list if we need they will need to be updated + var refreshMode = queryStringValue(link, 'refreshMode', namespaces.kml); + var refreshInterval = defaultValue(queryNumericValue(link, 'refreshInterval', namespaces.kml), 0); + if ((refreshMode === 'onInterval' && refreshInterval > 0 ) || (refreshMode === 'onExpire') || (viewRefreshMode === 'onStop')) { + var networkLinkControl = queryFirstNode(rootElement, 'NetworkLinkControl', namespaces.kml); + var hasNetworkLinkControl = defined(networkLinkControl); + + var now = JulianDate.now(); + var networkLinkInfo = { + id : createGuid(), + href : href, + cookie : {}, + lastUpdated : now, + updating : false, + entity : networkEntity, + viewBoundScale : viewBoundScale, + needsUpdate : false, + cameraUpdateTime : now + }; + + var minRefreshPeriod = 0; + if (hasNetworkLinkControl) { + networkLinkInfo.cookie = queryToObject(defaultValue(queryStringValue(networkLinkControl, 'cookie', namespaces.kml), '')); + minRefreshPeriod = defaultValue(queryNumericValue(networkLinkControl, 'minRefreshPeriod', namespaces.kml), 0); + } + + if (refreshMode === 'onInterval') { + if (hasNetworkLinkControl) { + refreshInterval = Math.max(minRefreshPeriod, refreshInterval); + } + networkLinkInfo.refreshMode = RefreshMode.INTERVAL; + networkLinkInfo.time = refreshInterval; + } else if (refreshMode === 'onExpire') { + var expires; + if (hasNetworkLinkControl) { + expires = queryStringValue(networkLinkControl, 'expires', namespaces.kml); + } + if (defined(expires)) { + try { + var date = JulianDate.fromIso8601(expires); + var diff = JulianDate.secondsDifference(date, now); + if (diff > 0 && diff < minRefreshPeriod) { + JulianDate.addSeconds(now, minRefreshPeriod, date); + } + networkLinkInfo.refreshMode = RefreshMode.EXPIRE; + networkLinkInfo.time = date; + } catch (e) { + oneTimeWarning('kml-refreshMode-onInterval-onExpire', 'KML - NetworkLinkControl expires is not a valid date'); + } + } else { + oneTimeWarning('kml-refreshMode-onExpire', 'KML - refreshMode of onExpire requires the NetworkLinkControl to have an expires element'); + } + } else if (dataSource._camera) { // Only allow onStop refreshes if we have a camera + networkLinkInfo.refreshMode = RefreshMode.STOP; + networkLinkInfo.time = defaultValue(queryNumericValue(link, 'viewRefreshTime', namespaces.kml), 0); + } else { + oneTimeWarning('kml-refrehMode-onStop-noCamera', 'A NetworkLink with viewRefreshMode=onStop requires a camera be passed in when creating the KmlDataSource'); + } + + if (defined(networkLinkInfo.refreshMode)) { + dataSource._networkLinks.set(networkLinkInfo.id, networkLinkInfo); + } + } else if (viewRefreshMode === 'onRegion') { + oneTimeWarning('kml-refrehMode-onRegion', 'KML - Unsupported viewRefreshMode: onRegion'); + } + }).otherwise(function(error) { + oneTimeWarning('An error occured during loading ' + href.url); + dataSource._error.raiseEvent(dataSource, error); }); - options.vertexFormat = appearance.vertexFormat; - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PolygonGeometry(options) - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + promises.push(promise); } } + } - if (!onTerrain && Property.getValueOrDefault(polygon.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + function processFeatureNode(dataSource, node, parent, entityCollection, styleCollection, sourceResource, uriResolver, promises, context) { + var featureProcessor = featureTypes[node.localName]; + if (defined(featureProcessor)) { + featureProcessor(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + } else { + processUnsupportedFeature(dataSource, parent, node, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + } + } - var outlineColor = Property.getValueOrClonedDefault(polygon.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(polygon.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + function loadKml(dataSource, entityCollection, kml, sourceResource, uriResolver, context) { + entityCollection.removeAll(); - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PolygonOutlineGeometry(options), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor) + var promises = []; + var documentElement = kml.documentElement; + var document = documentElement.localName === 'Document' ? documentElement : queryFirstNode(documentElement, 'Document', namespaces.kml); + var name = queryStringValue(document, 'name', namespaces.kml); + if (!defined(name)) { + name = getFilenameFromUri(sourceResource.getUrlComponent()); + } + + // Only set the name from the root document + if (!defined(dataSource._name)) { + dataSource._name = name; + } + + var styleCollection = new EntityCollection(dataSource); + return when.all(processStyles(dataSource, kml, styleCollection, sourceResource, false, uriResolver)).then(function() { + var element = kml.documentElement; + if (element.localName === 'kml') { + var childNodes = element.childNodes; + for (var i = 0; i < childNodes.length; i++) { + var tmp = childNodes[i]; + if (defined(featureTypes[tmp.localName])) { + element = tmp; + break; } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) + } + } + entityCollection.suspendEvents(); + processFeatureNode(dataSource, element, undefined, entityCollection, styleCollection, sourceResource, uriResolver, promises, context); + entityCollection.resumeEvents(); + + return when.all(promises).then(function() { + return kml.documentElement; + }); + }); + } + + function loadKmz(dataSource, entityCollection, blob, sourceResource) { + var deferred = when.defer(); + zip.createReader(new zip.BlobReader(blob), function(reader) { + reader.getEntries(function(entries) { + var promises = []; + var uriResolver = {}; + var docEntry; + var docDefer; + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + if (!entry.directory) { + var innerDefer = when.defer(); + promises.push(innerDefer.promise); + if (/\.kml$/i.test(entry.filename)) { + // We use the first KML document we come across + // https://developers.google.com/kml/documentation/kmzarchives + // Unless we come across a .kml file at the root of the archive because GE does this + if (!defined(docEntry) || !/\//i.test(entry.filename)) { + if (defined(docEntry)) { + // We found one at the root so load the initial kml as a data uri + loadDataUriFromZip(docEntry, uriResolver, docDefer); + } + docEntry = entry; + docDefer = innerDefer; + } else { + // Wasn't the first kml and wasn't at the root + loadDataUriFromZip(entry, uriResolver, innerDefer); + } + } else { + loadDataUriFromZip(entry, uriResolver, innerDefer); + } } - }), - asynchronous : false, - shadows : shadows - })); + } + + // Now load the root KML document + if (defined(docEntry)) { + loadXmlFromZip(docEntry, uriResolver, docDefer); + } + when.all(promises).then(function() { + reader.close(); + if (!defined(uriResolver.kml)) { + deferred.reject(new RuntimeError('KMZ file does not contain a KML document.')); + return; + } + uriResolver.keys = Object.keys(uriResolver); + return loadKml(dataSource, entityCollection, uriResolver.kml, sourceResource, uriResolver); + }).then(deferred.resolve).otherwise(deferred.reject); + }); + }, function(e) { + deferred.reject(e); + }); + + return deferred.promise; + } + + function load(dataSource, entityCollection, data, options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var sourceUri = options.sourceUri; + var uriResolver = options.uriResolver; + var context = options.context; + var query = options.query; + + if (defined(options.query)) { + deprecationWarning('KmlDataSource.query', 'The options.query parameter has been deprecated. Specify data or options.sourceUri as a Resource instance and add query parameters there.'); } - }; - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; + if (defined(dataSource._proxy)) { + deprecationWarning('KmlDataSource.proxy', 'The options.proxy parameter has been deprecated. Specify data or options.sourceUri as a Resource instance and set the proxy property there.'); + } - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + var promise = data; + if (typeof data === 'string' || (data instanceof Resource)) { + data = Resource.createIfNeeded(data, { + proxy: dataSource._proxy, + queryParameters: query + }); - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (this._geometryUpdater._onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); + promise = data.fetchBlob(); + + sourceUri = defaultValue(sourceUri, data.clone()); } else { - primitives.removeAndDestroy(this._primitive); + sourceUri = defaultValue(sourceUri, Resource.DEFAULT.clone()); } - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; - return PolygonGeometryUpdater; -}); + sourceUri = Resource.createIfNeeded(sourceUri); + + // Explicitly set these deprecated properties because we can use the default + // resource which won't have these set. + if (defined(dataSource._proxy)) { + sourceUri.proxy = dataSource._proxy; + } + + if (defined(query)) { + sourceUri.addQueryParameters(query); + } + + return when(promise) + .then(function(dataToLoad) { + if (dataToLoad instanceof Blob) { + return isZipFile(dataToLoad).then(function(isZip) { + if (isZip) { + return loadKmz(dataSource, entityCollection, dataToLoad, sourceUri); + } + return readBlobAsText(dataToLoad).then(function(text) { + //There's no official way to validate if a parse was successful. + //The following check detects the error on various browsers. + + //Insert missing namespaces + text = insertNamespaces(text); + + //Remove Duplicate Namespaces + text = removeDuplicateNamespaces(text); + + //IE raises an exception + var kml; + var error; + try { + kml = parser.parseFromString(text, 'application/xml'); + } catch (e) { + error = e.toString(); + } + + //The parse succeeds on Chrome and Firefox, but the error + //handling is different in each. + if (defined(error) || kml.body || kml.documentElement.tagName === 'parsererror') { + //Firefox has error information as the firstChild nodeValue. + var msg = defined(error) ? error : kml.documentElement.firstChild.nodeValue; -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/PolylineColorAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 prevPosition3DHigh;\n\ -attribute vec3 prevPosition3DLow;\n\ -attribute vec3 nextPosition3DHigh;\n\ -attribute vec3 nextPosition3DLow;\n\ -attribute vec2 expandAndWidth;\n\ -attribute vec4 color;\n\ -attribute float batchId;\n\ -varying vec4 v_color;\n\ -void main()\n\ -{\n\ -float expandDir = expandAndWidth.x;\n\ -float width = abs(expandAndWidth.y) + 0.5;\n\ -bool usePrev = expandAndWidth.y < 0.0;\n\ -vec4 p = czm_computePosition();\n\ -vec4 prev = czm_computePrevPosition();\n\ -vec4 next = czm_computeNextPosition();\n\ -v_color = color;\n\ -float angle;\n\ -vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);\n\ -gl_Position = czm_viewportOrthographic * positionWC;\n\ -}\n\ -"; -}); -define('Scene/PolylineColorAppearance',[ - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/VertexFormat', - '../Shaders/Appearances/PerInstanceFlatColorAppearanceFS', - '../Shaders/Appearances/PolylineColorAppearanceVS', - '../Shaders/PolylineCommon', - './Appearance' - ], function( - defaultValue, - defineProperties, - VertexFormat, - PerInstanceFlatColorAppearanceFS, - PolylineColorAppearanceVS, - PolylineCommon, - Appearance) { - 'use strict'; + //Chrome has it in the body text. + if (!msg) { + msg = kml.body.innerText; + } - var defaultVertexShaderSource = PolylineCommon + '\n' + PolylineColorAppearanceVS; - var defaultFragmentShaderSource = PerInstanceFlatColorAppearanceFS; + //Return the error + throw new RuntimeError(msg); + } + return loadKml(dataSource, entityCollection, kml, sourceUri, uriResolver, context); + }); + }); + } + return loadKml(dataSource, entityCollection, dataToLoad, sourceUri, uriResolver, context); + }) + .otherwise(function(error) { + dataSource._error.raiseEvent(dataSource, error); + console.log(error); + return when.reject(error); + }); + } /** - * An appearance for {@link GeometryInstance} instances with color attributes and {@link PolylineGeometry}. - * This allows several geometry instances, each with a different color, to - * be drawn with the same {@link Primitive}. + * A {@link DataSource} which processes Keyhole Markup Language 2.2 (KML). + * <p> + * KML support in Cesium is incomplete, but a large amount of the standard, + * as well as Google's <code>gx</code> extension namespace, is supported. See Github issue + * {@link https://github.com/AnalyticalGraphicsInc/cesium/issues/873|#873} for a + * detailed list of what is and isn't support. Cesium will also write information to the + * console when it encounters most unsupported features. + * </p> + * <p> + * Non visual feature data, such as <code>atom:author</code> and <code>ExtendedData</code> + * is exposed via an instance of {@link KmlFeatureData}, which is added to each {@link Entity} + * under the <code>kml</code> property. + * </p> * - * @alias PolylineColorAppearance + * @alias KmlDataSource * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineColorAppearance#renderState} has alpha blending enabled. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {RenderState} [options.renderState] Optional render state to override the default render state. + * @param {Object} options An object with the following properties: + * @param {Camera} options.camera The camera that is used for viewRefreshModes and sending camera properties to network links. + * @param {Canvas} options.canvas The canvas that is used for sending viewer properties to network links. + * + * @see {@link http://www.opengeospatial.org/standards/kml/|Open Geospatial Consortium KML Standard} + * @see {@link https://developers.google.com/kml/|Google KML Documentation} + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=KML.html|Cesium Sandcastle KML Demo} * * @example - * // A solid white line segment - * var primitive = new Cesium.Primitive({ - * geometryInstances : new Cesium.GeometryInstance({ - * geometry : new Cesium.PolylineGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * 0.0, 0.0, - * 5.0, 0.0 - * ]), - * width : 10.0, - * vertexFormat : Cesium.PolylineColorAppearance.VERTEX_FORMAT - * }), - * attributes : { - * color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0)) - * } - * }), - * appearance : new Cesium.PolylineColorAppearance({ - * translucent : false - * }) - * }); + * var viewer = new Cesium.Viewer('cesiumContainer'); + * viewer.dataSources.add(Cesium.KmlDataSource.load('../../SampleData/facilities.kmz', + * { + * camera: viewer.scene.camera, + * canvas: viewer.scene.canvas + * }) + * ); */ - function PolylineColorAppearance(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function KmlDataSource(options) { + options = defaultValue(options, {}); + var camera = options.camera; + var canvas = options.canvas; - var translucent = defaultValue(options.translucent, true); - var closed = false; - var vertexFormat = PolylineColorAppearance.VERTEX_FORMAT; + if (!defined(camera)) { + throw new DeveloperError('options.camera is required.'); + } + if (!defined(canvas)) { + throw new DeveloperError('options.canvas is required.'); + } + + this._changed = new Event(); + this._error = new Event(); + this._loading = new Event(); + this._refresh = new Event(); + this._unsupportedNode = new Event(); + + this._clock = undefined; + this._entityCollection = new EntityCollection(this); + this._name = undefined; + this._isLoading = false; + this._proxy = options.proxy; // TODO: Deprecation warning + this._pinBuilder = new PinBuilder(); + this._networkLinks = new AssociativeArray(); + this._entityCluster = new EntityCluster(); + + this._canvas = canvas; + this._camera = camera; + this._lastCameraView = { + position : defined(camera) ? Cartesian3.clone(camera.positionWC) : undefined, + direction : defined(camera) ? Cartesian3.clone(camera.directionWC) : undefined, + up : defined(camera) ? Cartesian3.clone(camera.upWC) : undefined, + bbox : defined(camera) ? camera.computeViewRectangle() : Rectangle.clone(Rectangle.MAX_VALUE) + }; + } + + /** + * Creates a Promise to a new instance loaded with the provided KML data. + * + * @param {String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. + * @param {Object} options An object with the following properties: + * @param {Camera} options.camera The camera that is used for viewRefreshModes and sending camera properties to network links. + * @param {Canvas} options.canvas The canvas that is used for sending viewer properties to network links. + * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links and other KML network features. + * @param {Boolean} [options.clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. If true, lines will use corridors so use Entity.corridor instead of Entity.polyline. + * + * @returns {Promise.<KmlDataSource>} A promise that will resolve to a new KmlDataSource instance once the KML is loaded. + */ + KmlDataSource.load = function(data, options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var dataSource = new KmlDataSource(options); + return dataSource.load(data, options); + }; + defineProperties(KmlDataSource.prototype, { /** - * This property is part of the {@link Appearance} interface, but is not - * used by {@link PolylineColorAppearance} since a fully custom fragment shader is used. - * - * @type Material - * - * @default undefined + * Gets or sets a human-readable name for this instance. + * This will be automatically be set to the KML document name on load. + * @memberof KmlDataSource.prototype + * @type {String} */ - this.material = undefined; - + name : { + get : function() { + return this._name; + }, + set : function(value) { + if (this._name !== value) { + this._name = value; + this._changed.raiseEvent(this); + } + } + }, /** - * When <code>true</code>, the geometry is expected to appear translucent so - * {@link PolylineColorAppearance#renderState} has alpha blending enabled. - * + * Gets the clock settings defined by the loaded KML. This represents the total + * availability interval for all time-dynamic data. If the KML does not contain + * time-dynamic data, this value is undefined. + * @memberof KmlDataSource.prototype + * @type {DataSourceClock} + */ + clock : { + get : function() { + return this._clock; + } + }, + /** + * Gets the collection of {@link Entity} instances. + * @memberof KmlDataSource.prototype + * @type {EntityCollection} + */ + entities : { + get : function() { + return this._entityCollection; + } + }, + /** + * Gets a value indicating if the data source is currently loading data. + * @memberof KmlDataSource.prototype * @type {Boolean} - * - * @default true */ - this.translucent = translucent; - - this._vertexShaderSource = defaultValue(options.vertexShaderSource, defaultVertexShaderSource); - this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, defaultFragmentShaderSource); - this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); - this._closed = closed; - - // Non-derived members - - this._vertexFormat = vertexFormat; - } - - defineProperties(PolylineColorAppearance.prototype, { + isLoading : { + get : function() { + return this._isLoading; + } + }, /** - * The GLSL source code for the vertex shader. - * - * @memberof PolylineColorAppearance.prototype - * - * @type {String} - * @readonly + * Gets an event that will be raised when the underlying data changes. + * @memberof KmlDataSource.prototype + * @type {Event} */ - vertexShaderSource : { + changedEvent : { get : function() { - return this._vertexShaderSource; + return this._changed; } }, - /** - * The GLSL source code for the fragment shader. - * - * @memberof PolylineColorAppearance.prototype - * - * @type {String} - * @readonly + * Gets an event that will be raised if an error is encountered during processing. + * @memberof KmlDataSource.prototype + * @type {Event} */ - fragmentShaderSource : { + errorEvent : { get : function() { - return this._fragmentShaderSource; + return this._error; } }, - /** - * The WebGL fixed-function state to use when rendering the geometry. - * <p> - * The render state can be explicitly defined when constructing a {@link PolylineColorAppearance} - * instance, or it is set implicitly via {@link PolylineColorAppearance#translucent}. - * </p> - * - * @memberof PolylineColorAppearance.prototype - * - * @type {Object} - * @readonly + * Gets an event that will be raised when the data source either starts or stops loading. + * @memberof KmlDataSource.prototype + * @type {Event} */ - renderState : { + loadingEvent : { get : function() { - return this._renderState; + return this._loading; } }, - /** - * When <code>true</code>, the geometry is expected to be closed so - * {@link PolylineColorAppearance#renderState} has backface culling enabled. - * This is always <code>false</code> for <code>PolylineColorAppearance</code>. - * - * @memberof PolylineColorAppearance.prototype - * + * Gets an event that will be raised when the data source refreshes a network link. + * @memberof KmlDataSource.prototype + * @type {Event} + */ + refreshEvent : { + get : function() { + return this._refresh; + } + }, + /** + * Gets an event that will be raised when the data source finds an unsupported node type. + * @memberof KmlDataSource.prototype + * @type {Event} + */ + unsupportedNodeEvent : { + get : function() { + return this._unsupportedNode; + } + }, + /** + * Gets whether or not this data source should be displayed. + * @memberof KmlDataSource.prototype * @type {Boolean} - * @readonly - * - * @default false */ - closed : { + show : { get : function() { - return this._closed; + return this._entityCollection.show; + }, + set : function(value) { + this._entityCollection.show = value; } }, /** - * The {@link VertexFormat} that this appearance instance is compatible with. - * A geometry can have more vertex attributes and still be compatible - at a - * potential performance cost - but it can't have less. - * - * @memberof PolylineColorAppearance.prototype - * - * @type VertexFormat - * @readonly + * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. * - * @default {@link PolylineColorAppearance.VERTEX_FORMAT} + * @memberof KmlDataSource.prototype + * @type {EntityCluster} */ - vertexFormat : { + clustering : { get : function() { - return this._vertexFormat; + return this._entityCluster; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value must be defined.'); + } + this._entityCluster = value; } } }); /** - * The {@link VertexFormat} that all {@link PolylineColorAppearance} instances - * are compatible with. This requires only a <code>position</code> attribute. - * - * @type VertexFormat + * Asynchronously loads the provided KML data, replacing any existing data. * - * @constant + * @param {Resource|String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. + * @param {Object} [options] An object with the following properties: + * @param {Resource|String} [options.sourceUri] Overrides the url to use for resolving relative links and other KML network features. + * @returns {Promise.<KmlDataSource>} A promise that will resolve to this instances once the KML is loaded. + * @param {Boolean} [options.clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. If true, lines will use corridors so use Entity.corridor instead of Entity.polyline. + * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. */ - PolylineColorAppearance.VERTEX_FORMAT = VertexFormat.POSITION_ONLY; + KmlDataSource.prototype.load = function(data, options) { + if (!defined(data)) { + throw new DeveloperError('data is required.'); + } + + options = defaultValue(options, {}); + DataSource.setLoading(this, true); - /** - * Procedurally creates the full GLSL fragment shader source. - * - * @function - * - * @returns {String} The full GLSL fragment shader source. - */ - PolylineColorAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; + var oldName = this._name; + this._name = undefined; + this._clampToGround = defaultValue(options.clampToGround, false); - /** - * Determines if the geometry is translucent based on {@link PolylineColorAppearance#translucent}. - * - * @function - * - * @returns {Boolean} <code>true</code> if the appearance is translucent. - */ - PolylineColorAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; + var that = this; + return load(this, this._entityCollection, data, options).then(function() { + var clock; - /** - * Creates a render state. This is not the final render state instance; instead, - * it can contain a subset of render state properties identical to the render state - * created in the context. - * - * @function - * - * @returns {Object} The render state. - */ - PolylineColorAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; + var availability = that._entityCollection.computeAvailability(); - return PolylineColorAppearance; -}); + var start = availability.start; + var stop = availability.stop; + var isMinStart = JulianDate.equals(start, Iso8601.MINIMUM_VALUE); + var isMaxStop = JulianDate.equals(stop, Iso8601.MAXIMUM_VALUE); + if (!isMinStart || !isMaxStop) { + var date; -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/Appearances/PolylineMaterialAppearanceVS',[],function() { - 'use strict'; - return "attribute vec3 position3DHigh;\n\ -attribute vec3 position3DLow;\n\ -attribute vec3 prevPosition3DHigh;\n\ -attribute vec3 prevPosition3DLow;\n\ -attribute vec3 nextPosition3DHigh;\n\ -attribute vec3 nextPosition3DLow;\n\ -attribute vec2 expandAndWidth;\n\ -attribute vec2 st;\n\ -attribute float batchId;\n\ -varying float v_width;\n\ -varying vec2 v_st;\n\ -varying float v_polylineAngle;\n\ -void main()\n\ -{\n\ -float expandDir = expandAndWidth.x;\n\ -float width = abs(expandAndWidth.y) + 0.5;\n\ -bool usePrev = expandAndWidth.y < 0.0;\n\ -vec4 p = czm_computePosition();\n\ -vec4 prev = czm_computePrevPosition();\n\ -vec4 next = czm_computeNextPosition();\n\ -v_width = width;\n\ -v_st = st;\n\ -vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, v_polylineAngle);\n\ -gl_Position = czm_viewportOrthographic * positionWC;\n\ -}\n\ -"; -}); -define('Scene/PolylineMaterialAppearance',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/VertexFormat', - '../Shaders/Appearances/PolylineMaterialAppearanceVS', - '../Shaders/PolylineCommon', - '../Shaders/PolylineFS', - './Appearance', - './Material' - ], function( - defaultValue, - defined, - defineProperties, - VertexFormat, - PolylineMaterialAppearanceVS, - PolylineCommon, - PolylineFS, - Appearance, - Material) { - 'use strict'; + //If start is min time just start at midnight this morning, local time + if (isMinStart) { + date = new Date(); + date.setHours(0, 0, 0, 0); + start = JulianDate.fromDate(date); + } - var defaultVertexShaderSource = PolylineCommon + '\n' + PolylineMaterialAppearanceVS; - var defaultFragmentShaderSource = PolylineFS; + //If stop is max value just stop at midnight tonight, local time + if (isMaxStop) { + date = new Date(); + date.setHours(24, 0, 0, 0); + stop = JulianDate.fromDate(date); + } + + clock = new DataSourceClock(); + clock.startTime = start; + clock.stopTime = stop; + clock.currentTime = JulianDate.clone(start); + clock.clockRange = ClockRange.LOOP_STOP; + clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; + clock.multiplier = Math.round(Math.min(Math.max(JulianDate.secondsDifference(stop, start) / 60, 1), 3.15569e7)); + } + + var changed = false; + if (clock !== that._clock) { + that._clock = clock; + changed = true; + } + + if (oldName !== that._name) { + changed = true; + } + + if (changed) { + that._changed.raiseEvent(that); + } + + DataSource.setLoading(that, false); + + return that; + }).otherwise(function(error) { + DataSource.setLoading(that, false); + that._error.raiseEvent(that, error); + console.log(error); + return when.reject(error); + }); + }; + + function mergeAvailabilityWithParent(child) { + var parent = child.parent; + if (defined(parent)) { + var parentAvailability = parent.availability; + if (defined(parentAvailability)) { + var childAvailability = child.availability; + if (defined(childAvailability)) { + childAvailability.intersect(parentAvailability); + } else { + child.availability = parentAvailability; + } + } + } + } + + function getNetworkLinkUpdateCallback(dataSource, networkLink, newEntityCollection, networkLinks, processedHref) { + return function(rootElement) { + if (!networkLinks.contains(networkLink.id)) { + // Got into the odd case where a parent network link was updated while a child + // network link update was in flight, so just throw it away. + return; + } + var remove = false; + var networkLinkControl = queryFirstNode(rootElement, 'NetworkLinkControl', namespaces.kml); + var hasNetworkLinkControl = defined(networkLinkControl); + + var minRefreshPeriod = 0; + if (hasNetworkLinkControl) { + if (defined(queryFirstNode(networkLinkControl, 'Update', namespaces.kml))) { + oneTimeWarning('kml-networkLinkControl-update', 'KML - NetworkLinkControl updates aren\'t supported.'); + networkLink.updating = false; + networkLinks.remove(networkLink.id); + return; + } + networkLink.cookie = queryToObject(defaultValue(queryStringValue(networkLinkControl, 'cookie', namespaces.kml), '')); + minRefreshPeriod = defaultValue(queryNumericValue(networkLinkControl, 'minRefreshPeriod', namespaces.kml), 0); + } + + var now = JulianDate.now(); + var refreshMode = networkLink.refreshMode; + if (refreshMode === RefreshMode.INTERVAL) { + if (defined(networkLinkControl)) { + networkLink.time = Math.max(minRefreshPeriod, networkLink.time); + } + } else if (refreshMode === RefreshMode.EXPIRE) { + var expires; + if (defined(networkLinkControl)) { + expires = queryStringValue(networkLinkControl, 'expires', namespaces.kml); + } + if (defined(expires)) { + try { + var date = JulianDate.fromIso8601(expires); + var diff = JulianDate.secondsDifference(date, now); + if (diff > 0 && diff < minRefreshPeriod) { + JulianDate.addSeconds(now, minRefreshPeriod, date); + } + networkLink.time = date; + } catch (e) { + oneTimeWarning('kml-networkLinkControl-expires', 'KML - NetworkLinkControl expires is not a valid date'); + remove = true; + } + } else { + oneTimeWarning('kml-refreshMode-onExpire', 'KML - refreshMode of onExpire requires the NetworkLinkControl to have an expires element'); + remove = true; + } + } + + var networkLinkEntity = networkLink.entity; + var entityCollection = dataSource._entityCollection; + var newEntities = newEntityCollection.values; + + function removeChildren(entity) { + entityCollection.remove(entity); + var children = entity._children; + var count = children.length; + for (var i = 0; i < count; ++i) { + removeChildren(children[i]); + } + } + + // Remove old entities + entityCollection.suspendEvents(); + var entitiesCopy = entityCollection.values.slice(); + var i; + for (i = 0; i < entitiesCopy.length; ++i) { + var entityToRemove = entitiesCopy[i]; + if (entityToRemove.parent === networkLinkEntity) { + entityToRemove.parent = undefined; + removeChildren(entityToRemove); + } + } + entityCollection.resumeEvents(); + + // Add new entities + entityCollection.suspendEvents(); + for (i = 0; i < newEntities.length; i++) { + var newEntity = newEntities[i]; + if (!defined(newEntity.parent)) { + newEntity.parent = networkLinkEntity; + mergeAvailabilityWithParent(newEntity); + } + entityCollection.add(newEntity); + } + entityCollection.resumeEvents(); + + // No refresh information remove it, otherwise update lastUpdate time + if (remove) { + networkLinks.remove(networkLink.id); + } else { + networkLink.lastUpdated = now; + } + + var availability = entityCollection.computeAvailability(); + + var start = availability.start; + var stop = availability.stop; + var isMinStart = JulianDate.equals(start, Iso8601.MINIMUM_VALUE); + var isMaxStop = JulianDate.equals(stop, Iso8601.MAXIMUM_VALUE); + if (!isMinStart || !isMaxStop) { + var clock = dataSource._clock; + + if (clock.startTime !== start || clock.stopTime !== stop) { + clock.startTime = start; + clock.stopTime = stop; + dataSource._changed.raiseEvent(dataSource); + } + } + + networkLink.updating = false; + networkLink.needsUpdate = false; + dataSource._refresh.raiseEvent(dataSource, processedHref.getUrlComponent(true)); + }; + } + + var entitiesToIgnore = new AssociativeArray(); /** - * An appearance for {@link PolylineGeometry} that supports shading with materials. - * - * @alias PolylineMaterialAppearance - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. - * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {RenderState} [options.renderState] Optional render state to override the default render state. - * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + * Updates any NetworkLink that require updating + * @function * - * @example - * var primitive = new Cesium.Primitive({ - * geometryInstances : new Cesium.GeometryInstance({ - * geometry : new Cesium.PolylineGeometry({ - * positions : Cesium.Cartesian3.fromDegreesArray([ - * 0.0, 0.0, - * 5.0, 0.0 - * ]), - * width : 10.0, - * vertexFormat : Cesium.PolylineMaterialAppearance.VERTEX_FORMAT - * }) - * }), - * appearance : new Cesium.PolylineMaterialAppearance({ - * material : Cesium.Material.fromType('Color') - * }) - * }); + * @param {JulianDate} time The simulation time. + * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ - function PolylineMaterialAppearance(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + KmlDataSource.prototype.update = function(time) { + var networkLinks = this._networkLinks; + if (networkLinks.length === 0) { + return true; + } - var translucent = defaultValue(options.translucent, true); - var closed = false; - var vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT; + var now = JulianDate.now(); + var that = this; - /** - * The material used to determine the fragment color. Unlike other {@link PolylineMaterialAppearance} - * properties, this is not read-only, so an appearance's material can change on the fly. - * - * @type Material - * - * @default {@link Material.ColorType} - * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} - */ - this.material = defined(options.material) ? options.material : Material.fromType(Material.ColorType); + entitiesToIgnore.removeAll(); - /** - * When <code>true</code>, the geometry is expected to appear translucent so - * {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. - * - * @type {Boolean} - * - * @default true - */ - this.translucent = translucent; + function recurseIgnoreEntities(entity) { + var children = entity._children; + var count = children.length; + for (var i = 0; i < count; ++i) { + var child = children[i]; + entitiesToIgnore.set(child.id, child); + recurseIgnoreEntities(child); + } + } - this._vertexShaderSource = defaultValue(options.vertexShaderSource, defaultVertexShaderSource); - this._fragmentShaderSource = defaultValue(options.fragmentShaderSource, defaultFragmentShaderSource); - this._renderState = Appearance.getDefaultRenderState(translucent, closed, options.renderState); - this._closed = closed; + var cameraViewUpdate = false; + var lastCameraView = this._lastCameraView; + var camera = this._camera; + if (defined(camera) && + !(camera.positionWC.equalsEpsilon(lastCameraView.position, CesiumMath.EPSILON7) && + camera.directionWC.equalsEpsilon(lastCameraView.direction, CesiumMath.EPSILON7) && + camera.upWC.equalsEpsilon(lastCameraView.up, CesiumMath.EPSILON7))) { - // Non-derived members + // Camera has changed so update the last view + lastCameraView.position = Cartesian3.clone(camera.positionWC); + lastCameraView.direction = Cartesian3.clone(camera.directionWC); + lastCameraView.up = Cartesian3.clone(camera.upWC); + lastCameraView.bbox = camera.computeViewRectangle(); + cameraViewUpdate = true; + } - this._vertexFormat = vertexFormat; - } + var newNetworkLinks = new AssociativeArray(); + var changed = false; + networkLinks.values.forEach(function(networkLink) { + var entity = networkLink.entity; + if (entitiesToIgnore.contains(entity.id)) { + return; + } - defineProperties(PolylineMaterialAppearance.prototype, { - /** - * The GLSL source code for the vertex shader. - * - * @memberof PolylineMaterialAppearance.prototype - * - * @type {String} - * @readonly - */ - vertexShaderSource : { - get : function() { - var vs = this._vertexShaderSource; - if (this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== -1) { - vs = '#define POLYLINE_DASH\n' + vs; + if (!networkLink.updating) { + var doUpdate = false; + if (networkLink.refreshMode === RefreshMode.INTERVAL) { + if (JulianDate.secondsDifference(now, networkLink.lastUpdated) > networkLink.time) { + doUpdate = true; + } + } + else if (networkLink.refreshMode === RefreshMode.EXPIRE) { + if (JulianDate.greaterThan(now, networkLink.time)) { + doUpdate = true; + } + + } else if (networkLink.refreshMode === RefreshMode.STOP) { + if (cameraViewUpdate) { + networkLink.needsUpdate = true; + networkLink.cameraUpdateTime = now; + } + + if (networkLink.needsUpdate && JulianDate.secondsDifference(now, networkLink.cameraUpdateTime) >= networkLink.time) { + doUpdate = true; + } + } + + if (doUpdate) { + recurseIgnoreEntities(entity); + networkLink.updating = true; + var newEntityCollection = new EntityCollection(); + var href = networkLink.href.clone(); + href.addQueryParameters(networkLink.cookie); + processNetworkLinkQueryString(href, that._camera, that._canvas, networkLink.viewBoundScale, lastCameraView.bbox); + load(that, newEntityCollection, href, {context : entity.id}) + .then(getNetworkLinkUpdateCallback(that, networkLink, newEntityCollection, newNetworkLinks, href)) + .otherwise(function(error) { + var msg = 'NetworkLink ' + networkLink.href + ' refresh failed: ' + error; + console.log(msg); + that._error.raiseEvent(that, msg); + }); + changed = true; } - return vs; } - }, + newNetworkLinks.set(networkLink.id, networkLink); + }); + + if (changed) { + this._networkLinks = newNetworkLinks; + this._changed.raiseEvent(this); + } + + return true; + }; + /** + * Contains KML Feature data loaded into the <code>Entity.kml</code> property by {@link KmlDataSource}. + * @alias KmlFeatureData + * @constructor + */ + function KmlFeatureData() { /** - * The GLSL source code for the fragment shader. - * - * @memberof PolylineMaterialAppearance.prototype - * - * @type {String} - * @readonly + * Gets the atom syndication format author field. + * @type Object */ - fragmentShaderSource : { - get : function() { - return this._fragmentShaderSource; - } - }, + this.author = { + /** + * Gets the name. + * @type String + * @alias author.name + * @memberof! KmlFeatureData# + * @property author.name + */ + name : undefined, + /** + * Gets the URI. + * @type String + * @alias author.uri + * @memberof! KmlFeatureData# + * @property author.uri + */ + uri : undefined, + /** + * Gets the email. + * @type String + * @alias author.email + * @memberof! KmlFeatureData# + * @property author.email + */ + email : undefined + }; /** - * The WebGL fixed-function state to use when rendering the geometry. - * <p> - * The render state can be explicitly defined when constructing a {@link PolylineMaterialAppearance} - * instance, or it is set implicitly via {@link PolylineMaterialAppearance#translucent} - * and {@link PolylineMaterialAppearance#closed}. - * </p> - * - * @memberof PolylineMaterialAppearance.prototype - * - * @type {Object} - * @readonly + * Gets the link. + * @type Object */ - renderState : { - get : function() { - return this._renderState; - } - }, + this.link = { + /** + * Gets the href. + * @type String + * @alias link.href + * @memberof! KmlFeatureData# + * @property link.href + */ + href : undefined, + /** + * Gets the language of the linked resource. + * @type String + * @alias link.hreflang + * @memberof! KmlFeatureData# + * @property link.hreflang + */ + hreflang : undefined, + /** + * Gets the link relation. + * @type String + * @alias link.rel + * @memberof! KmlFeatureData# + * @property link.rel + */ + rel : undefined, + /** + * Gets the link type. + * @type String + * @alias link.type + * @memberof! KmlFeatureData# + * @property link.type + */ + type : undefined, + /** + * Gets the link title. + * @type String + * @alias link.title + * @memberof! KmlFeatureData# + * @property link.title + */ + title : undefined, + /** + * Gets the link length. + * @type String + * @alias link.length + * @memberof! KmlFeatureData# + * @property link.length + */ + length : undefined + }; /** - * When <code>true</code>, the geometry is expected to be closed so - * {@link PolylineMaterialAppearance#renderState} has backface culling enabled. - * This is always <code>false</code> for <code>PolylineMaterialAppearance</code>. - * - * @memberof PolylineMaterialAppearance.prototype - * - * @type {Boolean} - * @readonly - * - * @default false + * Gets the unstructured address field. + * @type String */ - closed : { - get : function() { - return this._closed; - } - }, - + this.address = undefined; /** - * The {@link VertexFormat} that this appearance instance is compatible with. - * A geometry can have more vertex attributes and still be compatible - at a - * potential performance cost - but it can't have less. - * - * @memberof PolylineMaterialAppearance.prototype - * - * @type VertexFormat - * @readonly - * - * @default {@link PolylineMaterialAppearance.VERTEX_FORMAT} + * Gets the phone number. + * @type String */ - vertexFormat : { - get : function() { - return this._vertexFormat; - } - } - }); + this.phoneNumber = undefined; + /** + * Gets the snippet. + * @type String + */ + this.snippet = undefined; + /** + * Gets the extended data, parsed into a JSON object. + * Currently only the <code>Data</code> property is supported. + * <code>SchemaData</code> and custom data are ignored. + * @type String + */ + this.extendedData = undefined; + } + + return KmlDataSource; +}); + +define('DataSources/Visualizer',[ + '../Core/DeveloperError' + ], function( + DeveloperError) { + 'use strict'; /** - * The {@link VertexFormat} that all {@link PolylineMaterialAppearance} instances - * are compatible with. This requires <code>position</code> and <code>st</code> attributes. - * - * @type VertexFormat + * Defines the interface for visualizers. Visualizers are plug-ins to + * {@link DataSourceDisplay} that render data associated with + * {@link DataSource} instances. + * This object is an interface for documentation purposes and is not intended + * to be instantiated directly. + * @alias Visualizer + * @constructor * - * @constant + * @see BillboardVisualizer + * @see LabelVisualizer + * @see ModelVisualizer + * @see PathVisualizer + * @see PointVisualizer + * @see GeometryVisualizer */ - PolylineMaterialAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_ST; + function Visualizer() { + DeveloperError.throwInstantiationError(); + } /** - * Procedurally creates the full GLSL fragment shader source. For {@link PolylineMaterialAppearance}, - * this is derived from {@link PolylineMaterialAppearance#fragmentShaderSource} and {@link PolylineMaterialAppearance#material}. - * + * Updates the visualization to the provided time. * @function * - * @returns {String} The full GLSL fragment shader source. + * @param {JulianDate} time The time. + * + * @returns {Boolean} True if the display was updated to the provided time, + * false if the visualizer is waiting for an asynchronous operation to + * complete before data can be updated. */ - PolylineMaterialAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; + Visualizer.prototype.update = DeveloperError.throwInstantiationError; /** - * Determines if the geometry is translucent based on {@link PolylineMaterialAppearance#translucent} and {@link Material#isTranslucent}. + * Computes a bounding sphere which encloses the visualization produced for the specified entity. + * The bounding sphere is in the fixed frame of the scene's globe. * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, + * BoundingSphereState.PENDING if the result is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private + */ + Visualizer.prototype.getBoundingSphere = DeveloperError.throwInstantiationError; + + /** + * Returns true if this object was destroyed; otherwise, false. * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {Boolean} True if this object was destroyed; otherwise, false. */ - PolylineMaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; + Visualizer.prototype.isDestroyed = DeveloperError.throwInstantiationError; /** - * Creates a render state. This is not the final render state instance; instead, - * it can contain a subset of render state properties identical to the render state - * created in the context. - * + * Removes all visualization and cleans up any resources associated with this instance. * @function - * - * @returns {Object} The render state. */ - PolylineMaterialAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; + Visualizer.prototype.destroy = DeveloperError.throwInstantiationError; - return PolylineMaterialAppearance; + return Visualizer; }); -define('DataSources/PolylineGeometryUpdater',[ - '../Core/BoundingSphere', +define('Renderer/ClearCommand',[ '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/PolylineGeometry', - '../Core/PolylinePipeline', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/PolylineCollection', - '../Scene/PolylineColorAppearance', - '../Scene/PolylineMaterialAppearance', - '../Scene/ShadowMode', - './BoundingSphereState', - './ColorMaterialProperty', - './ConstantProperty', - './MaterialProperty', - './Property' + '../Core/freezeObject' ], function( - BoundingSphere, Color, - ColorGeometryInstanceAttribute, defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - PolylineGeometry, - PolylinePipeline, - ShowGeometryInstanceAttribute, - PolylineCollection, - PolylineColorAppearance, - PolylineMaterialAppearance, - ShadowMode, - BoundingSphereState, - ColorMaterialProperty, - ConstantProperty, - MaterialProperty, - Property) { + freezeObject) { 'use strict'; - //We use this object to create one polyline collection per-scene. - var polylineCollections = {}; - - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.positions = undefined; - this.width = undefined; - this.followSurface = undefined; - this.granularity = undefined; - } - /** - * A {@link GeometryUpdater} for polylines. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias PolylineGeometryUpdater - * @constructor + * Represents a command to the renderer for clearing a framebuffer. * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. + * @private */ - function PolylineGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); - } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(PolylineGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._depthFailMaterialProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'polyline', entity.polyline, undefined); - } + function ClearCommand(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - defineProperties(PolylineGeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof PolylineGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PolylineColorAppearance - }, /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof PolylineGeometryUpdater - * @type {Appearance} + * The value to clear the color buffer to. When <code>undefined</code>, the color buffer is not cleared. + * + * @type {Color} + * + * @default undefined */ - materialAppearanceType : { - value : PolylineMaterialAppearance - } - }); + this.color = options.color; - defineProperties(PolylineGeometryUpdater.prototype, { /** - * Gets the entity associated with this geometry. - * @memberof PolylineGeometryUpdater.prototype + * The value to clear the depth buffer to. When <code>undefined</code>, the depth buffer is not cleared. * - * @type {Entity} - * @readonly - */ - entity : { - get : function() { - return this._entity; - } - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof PolylineGeometryUpdater.prototype + * @type {Number} * - * @type {Boolean} - * @readonly + * @default undefined */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, + this.depth = options.depth; + /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof PolylineGeometryUpdater.prototype + * The value to clear the stencil buffer to. When <code>undefined</code>, the stencil buffer is not cleared. * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || (!defined(this._entity.availability) && Property.isConstant(this._showProperty)); - } - }, - /** - * Gets the material property used to fill the geometry. - * @memberof PolylineGeometryUpdater.prototype + * @type {Number} * - * @type {MaterialProperty} - * @readonly + * @default undefined */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, + this.stencil = options.stencil; + /** - * Gets the material property used to fill the geometry when it fails the depth test. - * @memberof PolylineGeometryUpdater.prototype + * The render state to apply when executing the clear command. The following states affect clearing: + * scissor test, color mask, depth mask, and stencil mask. When the render state is + * <code>undefined</code>, the default render state is used. * - * @type {MaterialProperty} - * @readonly - */ - depthFailMaterialProperty : { - get : function() { - return this._depthFailMaterialProperty; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PolylineGeometryUpdater.prototype + * @type {RenderState} * - * @type {Boolean} - * @readonly + * @default undefined */ - outlineEnabled : { - value : false - }, + this.renderState = options.renderState; + /** - * Gets a value indicating if outline visibility varies with simulation time. - * @memberof PolylineGeometryUpdater.prototype + * The framebuffer to clear. * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - value : true - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof PolylineGeometryUpdater.prototype + * @type {Framebuffer} * - * @type {Property} - * @readonly + * @default undefined */ - outlineColorProperty : { - value : undefined - }, + this.framebuffer = options.framebuffer; + /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof PolylineGeometryUpdater.prototype + * The object who created this command. This is useful for debugging command + * execution; it allows you to see who created a command when you only have a + * reference to the command, and can be used to selectively execute commands + * with {@link Scene#debugCommandFilter}. * - * @type {Property} - * @readonly - */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; - } - }, - /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof PolylineGeometryUpdater.prototype + * @type {Object} * - * @type {Property} - * @readonly - */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayConditionProperty; - } - }, - /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof PolylineGeometryUpdater.prototype + * @default undefined * - * @type {Boolean} - * @readonly + * @see Scene#debugCommandFilter */ - isDynamic : { - get : function() { - return this._dynamic; - } - }, + this.owner = options.owner; + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof PolylineGeometryUpdater.prototype + * The pass in which to run this command. * - * @type {Boolean} - * @readonly - */ - isClosed : { - value : false - }, - /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof PolylineGeometryUpdater.prototype + * @type {Pass} * - * @type {Boolean} - * @readonly + * @default undefined */ - geometryChanged : { - get : function() { - return this._geometryChanged; - } - } - }); - - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - PolylineGeometryUpdater.prototype.isOutlineVisible = function(time) { - return false; - }; - - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - PolylineGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time); - }; + this.pass = options.pass; + } /** - * Creates the geometry instance which represents the fill of the geometry. + * Clears color to (0.0, 0.0, 0.0, 0.0); depth to 1.0; and stencil to 0. * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * @type {ClearCommand} * - * @exception {DeveloperError} This instance does not represent a filled geometry. + * @constant */ - PolylineGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - - var attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; - - var currentColor; - if (this._materialProperty instanceof ColorMaterialProperty) { - currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor); - } - - if (defined(this._depthFailMaterialProperty) && this._depthFailMaterialProperty instanceof ColorMaterialProperty) { - currentColor = Color.WHITE; - if (defined(this._depthFailMaterialProperty.color) && (this._depthFailMaterialProperty.color.isConstant || isAvailable)) { - currentColor = this._depthFailMaterialProperty.color.getValue(time); - } - attributes.depthFailColor = ColorGeometryInstanceAttribute.fromColor(currentColor); - } + ClearCommand.ALL = freezeObject(new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0), + depth : 1.0, + stencil : 0.0 + })); - return new GeometryInstance({ - id : entity, - geometry : new PolylineGeometry(this._options), - attributes : attributes - }); + ClearCommand.prototype.execute = function(context, passState) { + context.clear(this, passState); }; - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); - }; + return ClearCommand; +}); - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - PolylineGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; +define('Renderer/ComputeCommand',[ + '../Core/defaultValue', + './Pass' + ], function( + defaultValue, + Pass) { + 'use strict'; /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. + * Represents a command to the renderer for GPU Compute (using old-school GPGPU). * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * @private */ - PolylineGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; - - PolylineGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'polyline')) { - return; - } + function ComputeCommand(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var polyline = this._entity.polyline; + /** + * The vertex array. If none is provided, a viewport quad will be used. + * + * @type {VertexArray} + * @default undefined + */ + this.vertexArray = options.vertexArray; - if (!defined(polyline)) { - if (this._fillEnabled) { - this._fillEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + /** + * The fragment shader source. The default vertex shader is ViewportQuadVS. + * + * @type {ShaderSource} + * @default undefined + */ + this.fragmentShaderSource = options.fragmentShaderSource; - var positionsProperty = polyline.positions; + /** + * The shader program to apply. + * + * @type {ShaderProgram} + * @default undefined + */ + this.shaderProgram = options.shaderProgram; - var show = polyline.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(positionsProperty))) { - if (this._fillEnabled) { - this._fillEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + /** + * An object with functions whose names match the uniforms in the shader program + * and return values to set those uniforms. + * + * @type {Object} + * @default undefined + */ + this.uniformMap = options.uniformMap; - var material = defaultValue(polyline.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._depthFailMaterialProperty = polyline.depthFailMaterial; - this._showProperty = defaultValue(show, defaultShow); - this._shadowsProperty = defaultValue(polyline.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(polyline.distanceDisplayCondition, defaultDistanceDisplayCondition); - this._fillEnabled = true; + /** + * Texture to use for offscreen rendering. + * + * @type {Texture} + * @default undefined + */ + this.outputTexture = options.outputTexture; - var width = polyline.width; - var followSurface = polyline.followSurface; - var granularity = polyline.granularity; + /** + * Function that is called immediately before the ComputeCommand is executed. Used to + * update any renderer resources. Takes the ComputeCommand as its single argument. + * + * @type {Function} + * @default undefined + */ + this.preExecute = options.preExecute; - if (!positionsProperty.isConstant || !Property.isConstant(width) || - !Property.isConstant(followSurface) || !Property.isConstant(granularity)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); - } - } else { - var options = this._options; - var positions = positionsProperty.getValue(Iso8601.MINIMUM_VALUE, options.positions); + /** + * Function that is called after the ComputeCommand is executed. Takes the output + * texture as its single argument. + * + * @type {Function} + * @default undefined + */ + this.postExecute = options.postExecute; - //Because of the way we currently handle reference properties, - //we can't automatically assume the positions are always valid. - if (!defined(positions) || positions.length < 2) { - if (this._fillEnabled) { - this._fillEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + /** + * Whether the renderer resources will persist beyond this call. If not, they + * will be destroyed after completion. + * + * @type {Boolean} + * @default false + */ + this.persists = defaultValue(options.persists, false); - var vertexFormat; - if (isColorMaterial && (!defined(this._depthFailMaterialProperty) || this._depthFailMaterialProperty instanceof ColorMaterialProperty)) { - vertexFormat = PolylineColorAppearance.VERTEX_FORMAT; - } else { - vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT; - } + /** + * The pass when to render. Always compute pass. + * + * @type {Pass} + * @default Pass.COMPUTE; + */ + this.pass = Pass.COMPUTE; - options.vertexFormat = vertexFormat; - options.positions = positions; - options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.followSurface = defined(followSurface) ? followSurface.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); - } - }; + /** + * The object who created this command. This is useful for debugging command + * execution; it allows us to see who created a command when we only have a + * reference to the command, and can be used to selectively execute commands + * with {@link Scene#debugCommandFilter}. + * + * @type {Object} + * @default undefined + * + * @see Scene#debugCommandFilter + */ + this.owner = options.owner; + } /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * Executes the compute command. * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - PolylineGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); - } - - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); - } - - return new DynamicGeometryUpdater(primitives, this); - }; - - /** - * @private + * @param {Context} computeEngine The context that processes the compute command. */ - var generateCartesianArcOptions = { - positions : undefined, - granularity : undefined, - height : undefined, - ellipsoid : undefined - }; - - function DynamicGeometryUpdater(primitives, geometryUpdater) { - var sceneId = geometryUpdater._scene.id; - - var polylineCollection = polylineCollections[sceneId]; - if (!defined(polylineCollection) || polylineCollection.isDestroyed()) { - polylineCollection = new PolylineCollection(); - polylineCollections[sceneId] = polylineCollection; - primitives.add(polylineCollection); - } else if (!primitives.contains(polylineCollection)) { - primitives.add(polylineCollection); - } - - var line = polylineCollection.add(); - line.id = geometryUpdater._entity; - - this._line = line; - this._primitives = primitives; - this._geometryUpdater = geometryUpdater; - this._positions = []; - - } - DynamicGeometryUpdater.prototype.update = function(time) { - var geometryUpdater = this._geometryUpdater; - var entity = geometryUpdater._entity; - var polyline = entity.polyline; - var line = this._line; - - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(polyline._show, time, true)) { - line.show = false; - return; - } - - var positionsProperty = polyline.positions; - var positions = Property.getValueOrUndefined(positionsProperty, time, this._positions); - if (!defined(positions) || positions.length < 2) { - line.show = false; - return; - } - - var followSurface = Property.getValueOrDefault(polyline._followSurface, time, true); - var globe = geometryUpdater._scene.globe; - if (followSurface && defined(globe)) { - generateCartesianArcOptions.ellipsoid = globe.ellipsoid; - generateCartesianArcOptions.positions = positions; - generateCartesianArcOptions.granularity = Property.getValueOrUndefined(polyline._granularity, time); - generateCartesianArcOptions.height = PolylinePipeline.extractHeights(positions, globe.ellipsoid); - positions = PolylinePipeline.generateCartesianArc(generateCartesianArcOptions); - } - - line.show = true; - line.positions = positions.slice(); - line.material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, line.material); - line.width = Property.getValueOrDefault(polyline._width, time, 1); - line.distanceDisplayCondition = Property.getValueOrUndefined(polyline._distanceDisplayCondition, time, line.distanceDisplayCondition); - }; - - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); - } - if (!defined(result)) { - throw new DeveloperError('result is required.'); - } - - var line = this._line; - if (line.show && line.positions.length > 0) { - BoundingSphere.fromPoints(line.positions, result); - return BoundingSphereState.DONE; - } - return BoundingSphereState.FAILED; - }; - - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; - - DynamicGeometryUpdater.prototype.destroy = function() { - var geometryUpdater = this._geometryUpdater; - var sceneId = geometryUpdater._scene.id; - var polylineCollection = polylineCollections[sceneId]; - polylineCollection.remove(this._line); - if (polylineCollection.length === 0) { - this._primitives.removeAndDestroy(polylineCollection); - delete polylineCollections[sceneId]; - } - destroyObject(this); + ComputeCommand.prototype.execute = function(computeEngine) { + computeEngine.execute(this); }; - return PolylineGeometryUpdater; + return ComputeCommand; }); -define('DataSources/PolylineVolumeGeometryUpdater',[ +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/ViewportQuadVS',[],function() { + 'use strict'; + return "attribute vec4 position;\n\ +attribute vec2 textureCoordinates;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +gl_Position = position;\n\ +v_textureCoordinates = textureCoordinates;\n\ +}\n\ +"; +}); +define('Renderer/ComputeEngine',[ + '../Core/BoundingRectangle', + '../Core/Check', '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/PolylineVolumeGeometry', - '../Core/PolylineVolumeOutlineGeometry', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' + '../Core/PrimitiveType', + '../Shaders/ViewportQuadVS', + './ClearCommand', + './DrawCommand', + './Framebuffer', + './RenderState', + './ShaderProgram' ], function( + BoundingRectangle, + Check, Color, - ColorGeometryInstanceAttribute, - defaultValue, defined, - defineProperties, destroyObject, DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - PolylineVolumeGeometry, - PolylineVolumeOutlineGeometry, - ShowGeometryInstanceAttribute, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { + PrimitiveType, + ViewportQuadVS, + ClearCommand, + DrawCommand, + Framebuffer, + RenderState, + ShaderProgram) { 'use strict'; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + /** + * @private + */ + function ComputeEngine(context) { + this._context = context; + } - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.polylinePositions = undefined; - this.shapePositions = undefined; - this.cornerType = undefined; - this.granularity = undefined; + var renderStateScratch; + var drawCommandScratch = new DrawCommand({ + primitiveType : PrimitiveType.TRIANGLES + }); + var clearCommandScratch = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0) + }); + + function createFramebuffer(context, outputTexture) { + return new Framebuffer({ + context : context, + colorTextures : [outputTexture], + destroyAttachments : false + }); } - /** - * A {@link GeometryUpdater} for polyline volumes. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias PolylineVolumeGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function PolylineVolumeGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + function createViewportQuadShader(context, fragmentShaderSource) { + return ShaderProgram.fromCache({ + context : context, + vertexShaderSource : ViewportQuadVS, + fragmentShaderSource : fragmentShaderSource, + attributeLocations : { + position : 0, + textureCoordinates : 1 + } + }); + } + + function createRenderState(width, height) { + if ((!defined(renderStateScratch)) || + (renderStateScratch.viewport.width !== width) || + (renderStateScratch.viewport.height !== height)) { + + renderStateScratch = RenderState.fromCache({ + viewport : new BoundingRectangle(0, 0, width, height) + }); } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(PolylineVolumeGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'polylineVolume', entity.polylineVolume, undefined); + return renderStateScratch; } - defineProperties(PolylineVolumeGeometryUpdater, { - /** - * Gets the type of appearance to use for simple color-based geometry. - * @memberof PolylineVolumeGeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance - }, - /** - * Gets the type of appearance to use for material-based geometry. - * @memberof PolylineVolumeGeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - value : MaterialAppearance + ComputeEngine.prototype.execute = function(computeCommand) { + Check.defined('computeCommand', computeCommand); + + // This may modify the command's resources, so do error checking afterwards + if (defined(computeCommand.preExecute)) { + computeCommand.preExecute(computeCommand); } - }); - defineProperties(PolylineVolumeGeometryUpdater.prototype, { - /** - * Gets the entity associated with this geometry. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Entity} - * @readonly - */ - entity : { - get : function() { - return this._entity; - } - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - fillEnabled : { - get : function() { - return this._fillEnabled; - } - }, - /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); - } - }, - /** - * Gets the material property used to fill the geometry. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly - */ - fillMaterialProperty : { - get : function() { - return this._materialProperty; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - outlineEnabled : { - get : function() { - return this._outlineEnabled; - } - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); - } - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - outlineColorProperty : { - get : function() { - return this._outlineColorProperty; - } - }, - /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Number} - * @readonly - */ - outlineWidth : { - get : function() { - return this._outlineWidth; + if (!defined(computeCommand.fragmentShaderSource) && !defined(computeCommand.shaderProgram)) { + throw new DeveloperError('computeCommand.fragmentShaderSource or computeCommand.shaderProgram is required.'); + } + + Check.defined('computeCommand.outputTexture', computeCommand.outputTexture); + + var outputTexture = computeCommand.outputTexture; + var width = outputTexture.width; + var height = outputTexture.height; + + var context = this._context; + var vertexArray = defined(computeCommand.vertexArray) ? computeCommand.vertexArray : context.getViewportQuadVertexArray(); + var shaderProgram = defined(computeCommand.shaderProgram) ? computeCommand.shaderProgram : createViewportQuadShader(context, computeCommand.fragmentShaderSource); + var framebuffer = createFramebuffer(context, outputTexture); + var renderState = createRenderState(width, height); + var uniformMap = computeCommand.uniformMap; + + var clearCommand = clearCommandScratch; + clearCommand.framebuffer = framebuffer; + clearCommand.renderState = renderState; + clearCommand.execute(context); + + var drawCommand = drawCommandScratch; + drawCommand.vertexArray = vertexArray; + drawCommand.renderState = renderState; + drawCommand.shaderProgram = shaderProgram; + drawCommand.uniformMap = uniformMap; + drawCommand.framebuffer = framebuffer; + drawCommand.execute(context); + + framebuffer.destroy(); + + if (!computeCommand.persists) { + shaderProgram.destroy(); + if (defined(computeCommand.vertexArray)) { + vertexArray.destroy(); } - }, + } + + if (defined(computeCommand.postExecute)) { + computeCommand.postExecute(outputTexture); + } + }; + + ComputeEngine.prototype.isDestroyed = function() { + return false; + }; + + ComputeEngine.prototype.destroy = function() { + return destroyObject(this); + }; + + return ComputeEngine; +}); + +define('Renderer/PassState',[], function() { + 'use strict'; + + /** + * The state for a particular rendering pass. This is used to supplement the state + * in a command being executed. + * + * @private + */ + function PassState(context) { /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof PolylineVolumeGeometryUpdater.prototype + * The context used to execute commands for this pass. * - * @type {Property} - * @readonly + * @type {Context} */ - shadowsProperty : { - get : function() { - return this._shadowsProperty; - } - }, + this.context = context; + /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof PolylineVolumeGeometryUpdater.prototype + * The framebuffer to render to. This framebuffer is used unless a {@link DrawCommand} + * or {@link ClearCommand} explicitly define a framebuffer, which is used for off-screen + * rendering. * - * @type {Property} - * @readonly + * @type {Framebuffer} + * @default undefined */ - distanceDisplayConditionProperty : { - get : function() { - return this._distanceDisplayConditionProperty; - } - }, + this.framebuffer = undefined; + /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof PolylineVolumeGeometryUpdater.prototype + * When defined, this overrides the blending property of a {@link DrawCommand}'s render state. + * This is used to, for example, to allow the renderer to turn off blending during the picking pass. + * <p> + * When this is <code>undefined</code>, the {@link DrawCommand}'s property is used. + * </p> * * @type {Boolean} - * @readonly + * @default undefined */ - isDynamic : { - get : function() { - return this._dynamic; - } - }, + this.blendingEnabled = undefined; + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof PolylineVolumeGeometryUpdater.prototype + * When defined, this overrides the scissor test property of a {@link DrawCommand}'s render state. + * This is used to, for example, to allow the renderer to scissor out the pick region during the picking pass. + * <p> + * When this is <code>undefined</code>, the {@link DrawCommand}'s property is used. + * </p> * - * @type {Boolean} - * @readonly + * @type {Object} + * @default undefined */ - isClosed : { - value : true - }, + this.scissorTest = undefined; + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof PolylineVolumeGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * The viewport used when one is not defined by a {@link DrawCommand}'s render state. + * @type {BoundingRectangle} + * @default undefined */ - geometryChanged : { - get : function() { - return this._geometryChanged; - } - } - }); + this.viewport = undefined; + } - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - PolylineVolumeGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; + return PassState; +}); + +define('Renderer/RenderbufferFormat',[ + '../Core/freezeObject', + '../Core/WebGLConstants' + ], function( + freezeObject, + WebGLConstants) { + 'use strict'; /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + * @private */ - PolylineVolumeGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + var RenderbufferFormat = { + RGBA4 : WebGLConstants.RGBA4, + RGB5_A1 : WebGLConstants.RGB5_A1, + RGB565 : WebGLConstants.RGB565, + DEPTH_COMPONENT16 : WebGLConstants.DEPTH_COMPONENT16, + STENCIL_INDEX8 : WebGLConstants.STENCIL_INDEX8, + DEPTH_STENCIL : WebGLConstants.DEPTH_STENCIL, + + validate : function(renderbufferFormat) { + return ((renderbufferFormat === RenderbufferFormat.RGBA4) || + (renderbufferFormat === RenderbufferFormat.RGB5_A1) || + (renderbufferFormat === RenderbufferFormat.RGB565) || + (renderbufferFormat === RenderbufferFormat.DEPTH_COMPONENT16) || + (renderbufferFormat === RenderbufferFormat.STENCIL_INDEX8) || + (renderbufferFormat === RenderbufferFormat.DEPTH_STENCIL)); + } }; + return freezeObject(RenderbufferFormat); +}); + +define('Renderer/Renderbuffer',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + './ContextLimits', + './RenderbufferFormat' + ], function( + Check, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + ContextLimits, + RenderbufferFormat) { + 'use strict'; + /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. + * @private */ - PolylineVolumeGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + function Renderbuffer(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); - } + Check.defined('options.context', options.context); - var entity = this._entity; - var isAvailable = entity.isAvailable(time); + var context = options.context; + var gl = context._gl; + var maximumRenderbufferSize = ContextLimits.maximumRenderbufferSize; - var attributes; + var format = defaultValue(options.format, RenderbufferFormat.RGBA4); + var width = defined(options.width) ? options.width : gl.drawingBufferWidth; + var height = defined(options.height) ? options.height : gl.drawingBufferHeight; - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; + if (!RenderbufferFormat.validate(format)) { + throw new DeveloperError('Invalid format.'); } - return new GeometryInstance({ - id : entity, - geometry : new PolylineVolumeGeometry(this._options), - attributes : attributes - }); - }; + Check.typeOf.number.greaterThan('width', width, 0); - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - PolylineVolumeGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + if (width > maximumRenderbufferSize) { + throw new DeveloperError('Width must be less than or equal to the maximum renderbuffer size (' + maximumRenderbufferSize + '). Check maximumRenderbufferSize.'); } - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + Check.typeOf.number.greaterThan('height', height, 0); + + if (height > maximumRenderbufferSize) { + throw new DeveloperError('Height must be less than or equal to the maximum renderbuffer size (' + maximumRenderbufferSize + '). Check maximumRenderbufferSize.'); } - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + this._gl = gl; + this._format = format; + this._width = width; + this._height = height; + this._renderbuffer = this._gl.createRenderbuffer(); - return new GeometryInstance({ - id : entity, - geometry : new PolylineVolumeOutlineGeometry(this._options), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height); + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + } + + defineProperties(Renderbuffer.prototype, { + format: { + get : function() { + return this._format; } - }); + }, + width: { + get : function() { + return this._width; + } + }, + height: { + get : function() { + return this._height; + } + } + }); + + Renderbuffer.prototype._getRenderbuffer = function() { + return this._renderbuffer; }; - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - PolylineVolumeGeometryUpdater.prototype.isDestroyed = function() { + Renderbuffer.prototype.isDestroyed = function() { return false; }; + Renderbuffer.prototype.destroy = function() { + this._gl.deleteRenderbuffer(this._renderbuffer); + return destroyObject(this); + }; + + return Renderbuffer; +}); + +define('Renderer/PickFramebuffer',[ + '../Core/BoundingRectangle', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/destroyObject', + './Framebuffer', + './PassState', + './Renderbuffer', + './RenderbufferFormat', + './Texture' + ], function( + BoundingRectangle, + Color, + defaultValue, + defined, + destroyObject, + Framebuffer, + PassState, + Renderbuffer, + RenderbufferFormat, + Texture) { + 'use strict'; + /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * @private */ - PolylineVolumeGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + function PickFramebuffer(context) { + // Override per-command states + var passState = new PassState(context); + passState.blendingEnabled = false; + passState.scissorTest = { + enabled : true, + rectangle : new BoundingRectangle() + }; + passState.viewport = new BoundingRectangle(); - PolylineVolumeGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'polylineVolume')) { - return; - } + this._context = context; + this._fb = undefined; + this._passState = passState; + this._width = 0; + this._height = 0; + } + PickFramebuffer.prototype.begin = function(screenSpaceRectangle) { + var context = this._context; + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; - var polylineVolume = this._entity.polylineVolume; + BoundingRectangle.clone(screenSpaceRectangle, this._passState.scissorTest.rectangle); - if (!defined(polylineVolume)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + // Initially create or recreate renderbuffers and framebuffer used for picking + if ((!defined(this._fb)) || (this._width !== width) || (this._height !== height)) { + this._width = width; + this._height = height; + + this._fb = this._fb && this._fb.destroy(); + this._fb = new Framebuffer({ + context : context, + colorTextures : [new Texture({ + context : context, + width : width, + height : height + })], + depthStencilRenderbuffer : new Renderbuffer({ + context : context, + format : RenderbufferFormat.DEPTH_STENCIL + }) + }); + this._passState.framebuffer = this._fb; } - var fillProperty = polylineVolume.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + this._passState.viewport.width = width; + this._passState.viewport.height = height; - var outlineProperty = polylineVolume.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); - } + return this._passState; + }; - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; - } + var colorScratch = new Color(); - var positions = polylineVolume.positions; - var shape = polylineVolume.shape; + PickFramebuffer.prototype.end = function(screenSpaceRectangle) { + var width = defaultValue(screenSpaceRectangle.width, 1.0); + var height = defaultValue(screenSpaceRectangle.height, 1.0); - var show = polylineVolume.show; - if (!defined(positions) || !defined(shape) || (defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + var context = this._context; + var pixels = context.readPixels({ + x : screenSpaceRectangle.x, + y : screenSpaceRectangle.y, + width : width, + height : height, + framebuffer : this._fb + }); + + var max = Math.max(width, height); + var length = max * max; + var halfWidth = Math.floor(width * 0.5); + var halfHeight = Math.floor(height * 0.5); + + var x = 0; + var y = 0; + var dx = 0; + var dy = -1; + + // Spiral around the center pixel, this is a workaround until + // we can access the depth buffer on all browsers. + + // The region does not have to square and the dimensions do not have to be odd, but + // loop iterations would be wasted. Prefer square regions where the size is odd. + for (var i = 0; i < length; ++i) { + if (-halfWidth <= x && x <= halfWidth && -halfHeight <= y && y <= halfHeight) { + var index = 4 * ((halfHeight - y) * width + x + halfWidth); + + colorScratch.red = Color.byteToFloat(pixels[index]); + colorScratch.green = Color.byteToFloat(pixels[index + 1]); + colorScratch.blue = Color.byteToFloat(pixels[index + 2]); + colorScratch.alpha = Color.byteToFloat(pixels[index + 3]); + + var object = context.getObjectByPickColor(colorScratch); + if (defined(object)) { + return object; + } } - return; + + // if (top right || bottom left corners) || (top left corner) || (bottom right corner + (1, 0)) + // change spiral direction + if (x === y || (x < 0 && -x === y) || (x > 0 && x === 1 - y)) { + var temp = dx; + dx = -dy; + dy = temp; + } + + x += dx; + y += dy; } - var material = defaultValue(polylineVolume.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(polylineVolume.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(polylineVolume.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(polylineVolume.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(polylineVolume.distanceDisplayCondition, defaultDistanceDisplayCondition); + return undefined; + }; - var granularity = polylineVolume.granularity; - var outlineWidth = polylineVolume.outlineWidth; - var cornerType = polylineVolume.cornerType; + PickFramebuffer.prototype.isDestroyed = function() { + return false; + }; - this._fillEnabled = fillEnabled; - this._outlineEnabled = outlineEnabled; + PickFramebuffer.prototype.destroy = function() { + this._fb = this._fb && this._fb.destroy(); + return destroyObject(this); + }; - if (!positions.isConstant || // - !shape.isConstant || // - !Property.isConstant(granularity) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(cornerType)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); + return PickFramebuffer; +}); + +define('Renderer/ShaderCache',[ + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + './ShaderProgram', + './ShaderSource' + ], function( + defined, + defineProperties, + destroyObject, + ShaderProgram, + ShaderSource) { + 'use strict'; + + /** + * @private + */ + function ShaderCache(context) { + this._context = context; + this._shaders = {}; + this._numberOfShaders = 0; + this._shadersToRelease = {}; + } + + defineProperties(ShaderCache.prototype, { + numberOfShaders : { + get : function() { + return this._numberOfShaders; } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.polylinePositions = positions.getValue(Iso8601.MINIMUM_VALUE, options.polylinePositions); - options.shapePositions = shape.getValue(Iso8601.MINIMUM_VALUE, options.shape); - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.cornerType = defined(cornerType) ? cornerType.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); } - }; + }); /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. + * Returns a shader program from the cache, or creates and caches a new shader program, + * given the GLSL vertex and fragment shader source and attribute locations. + * <p> + * The difference between this and {@link ShaderCache#getShaderProgram}, is this is used to + * replace an existing reference to a shader program, which is passed as the first argument. + * </p> * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. + * @param {Object} options Object with the following properties: + * @param {ShaderProgram} [options.shaderProgram] The shader program that is being reassigned. + * @param {String|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. + * @param {String|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. + * @param {Object} options.attributeLocations Indices for the attribute inputs to the vertex shader. + + * @returns {ShaderProgram} The cached or newly created shader program. * - * @exception {DeveloperError} This instance does not represent dynamic geometry. + * + * @example + * this._shaderProgram = context.shaderCache.replaceShaderProgram({ + * shaderProgram : this._shaderProgram, + * vertexShaderSource : vs, + * fragmentShaderSource : fs, + * attributeLocations : attributeLocations + * }); + * + * @see ShaderCache#getShaderProgram */ - PolylineVolumeGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); + ShaderCache.prototype.replaceShaderProgram = function(options) { + if (defined(options.shaderProgram)) { + options.shaderProgram.destroy(); } - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); - } - - return new DynamicGeometryUpdater(primitives, this); + return this.getShaderProgram(options); }; /** - * @private + * Returns a shader program from the cache, or creates and caches a new shader program, + * given the GLSL vertex and fragment shader source and attribute locations. + * + * @param {Object} options Object with the following properties: + * @param {String|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. + * @param {String|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. + * @param {Object} options.attributeLocations Indices for the attribute inputs to the vertex shader. + * + * @returns {ShaderProgram} The cached or newly created shader program. */ - function DynamicGeometryUpdater(primitives, geometryUpdater) { - this._primitives = primitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); - } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + ShaderCache.prototype.getShaderProgram = function(options) { + // convert shaders which are provided as strings into ShaderSource objects + // because ShaderSource handles all the automatic including of built-in functions, etc. + + var vertexShaderSource = options.vertexShaderSource; + var fragmentShaderSource = options.fragmentShaderSource; + var attributeLocations = options.attributeLocations; + + if (typeof vertexShaderSource === 'string') { + vertexShaderSource = new ShaderSource({ + sources : [vertexShaderSource] + }); } - - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._primitive = undefined; - this._outlinePrimitive = undefined; - var geometryUpdater = this._geometryUpdater; - var entity = geometryUpdater._entity; - var polylineVolume = entity.polylineVolume; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(polylineVolume.show, time, true)) { - return; + if (typeof fragmentShaderSource === 'string') { + fragmentShaderSource = new ShaderSource({ + sources : [fragmentShaderSource] + }); } - var options = this._options; - var positions = Property.getValueOrUndefined(polylineVolume.positions, time, options.polylinePositions); - var shape = Property.getValueOrUndefined(polylineVolume.shape, time); - if (!defined(positions) || !defined(shape)) { - return; + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(this._context); + var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(this._context); + + var keyword = vertexShaderText + fragmentShaderText + JSON.stringify(attributeLocations); + var cachedShader; + + if (defined(this._shaders[keyword])) { + cachedShader = this._shaders[keyword]; + + // No longer want to release this if it was previously released. + delete this._shadersToRelease[keyword]; + } else { + var context = this._context; + var shaderProgram = new ShaderProgram({ + gl : context._gl, + logShaderCompilation : context.logShaderCompilation, + debugShaders : context.debugShaders, + vertexShaderSource : vertexShaderSource, + vertexShaderText : vertexShaderText, + fragmentShaderSource : fragmentShaderSource, + fragmentShaderText : fragmentShaderText, + attributeLocations : attributeLocations + }); + + cachedShader = { + cache : this, + shaderProgram : shaderProgram, + keyword : keyword, + derivedKeywords : [], + count : 0 + }; + + // A shader can't be in more than one cache. + shaderProgram._cachedShader = cachedShader; + this._shaders[keyword] = cachedShader; + ++this._numberOfShaders; } - options.polylinePositions = positions; - options.shapePositions = shape; - options.granularity = Property.getValueOrUndefined(polylineVolume.granularity, time); - options.cornerType = Property.getValueOrUndefined(polylineVolume.cornerType, time); + ++cachedShader.count; + return cachedShader.shaderProgram; + }; - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + ShaderCache.prototype.getDerivedShaderProgram = function(shaderProgram, keyword) { + var cachedShader = shaderProgram._cachedShader; + var derivedKeyword = keyword + cachedShader.keyword; + var cachedDerivedShader = this._shaders[derivedKeyword]; + if (!defined(cachedDerivedShader)) { + return undefined; + } - if (!defined(polylineVolume.fill) || polylineVolume.fill.getValue(time)) { - var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - this._material = material; + return cachedDerivedShader.shaderProgram; + }; - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : true + ShaderCache.prototype.createDerivedShaderProgram = function(shaderProgram, keyword, options) { + var cachedShader = shaderProgram._cachedShader; + var derivedKeyword = keyword + cachedShader.keyword; + + var vertexShaderSource = options.vertexShaderSource; + var fragmentShaderSource = options.fragmentShaderSource; + var attributeLocations = options.attributeLocations; + + if (typeof vertexShaderSource === 'string') { + vertexShaderSource = new ShaderSource({ + sources : [vertexShaderSource] }); - options.vertexFormat = appearance.vertexFormat; + } - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PolylineVolumeGeometry(options) - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + if (typeof fragmentShaderSource === 'string') { + fragmentShaderSource = new ShaderSource({ + sources : [fragmentShaderSource] + }); } - if (defined(polylineVolume.outline) && polylineVolume.outline.getValue(time)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + var context = this._context; - var outlineColor = Property.getValueOrClonedDefault(polylineVolume.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(polylineVolume.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(context); + var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(context); - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new PolylineVolumeOutlineGeometry(options), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor) - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) - } - }), - asynchronous : false, - shadows : shadows - })); + var derivedShaderProgram = new ShaderProgram({ + gl : context._gl, + logShaderCompilation : context.logShaderCompilation, + debugShaders : context.debugShaders, + vertexShaderSource : vertexShaderSource, + vertexShaderText : vertexShaderText, + fragmentShaderSource : fragmentShaderSource, + fragmentShaderText : fragmentShaderText, + attributeLocations : attributeLocations + }); + + var derivedCachedShader = { + cache : this, + shaderProgram : derivedShaderProgram, + keyword : derivedKeyword, + derivedKeywords : [], + count : 0 + }; + + cachedShader.derivedKeywords.push(keyword); + derivedShaderProgram._cachedShader = derivedCachedShader; + this._shaders[derivedKeyword] = derivedCachedShader; + return derivedShaderProgram; + }; + + function destroyShader(cache, cachedShader) { + var derivedKeywords = cachedShader.derivedKeywords; + var length = derivedKeywords.length; + for (var i = 0; i < length; ++i) { + var keyword = derivedKeywords[i] + cachedShader.keyword; + var derivedCachedShader = cache._shaders[keyword]; + destroyShader(cache, derivedCachedShader); + } + + delete cache._shaders[cachedShader.keyword]; + cachedShader.shaderProgram.finalDestroy(); + } + + ShaderCache.prototype.destroyReleasedShaderPrograms = function() { + var shadersToRelease = this._shadersToRelease; + + for ( var keyword in shadersToRelease) { + if (shadersToRelease.hasOwnProperty(keyword)) { + var cachedShader = shadersToRelease[keyword]; + destroyShader(this, cachedShader); + --this._numberOfShaders; + } } + + this._shadersToRelease = {}; }; - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); + ShaderCache.prototype.releaseShaderProgram = function(shaderProgram) { + if (defined(shaderProgram)) { + var cachedShader = shaderProgram._cachedShader; + if (cachedShader && (--cachedShader.count === 0)) { + this._shadersToRelease[cachedShader.keyword] = cachedShader; + } + } }; - DynamicGeometryUpdater.prototype.isDestroyed = function() { + ShaderCache.prototype.isDestroyed = function() { return false; }; - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); + ShaderCache.prototype.destroy = function() { + var shaders = this._shaders; + for (var keyword in shaders) { + if (shaders.hasOwnProperty(keyword)) { + shaders[keyword].shaderProgram.finalDestroy(); + } + } + return destroyObject(this); }; - return PolylineVolumeGeometryUpdater; + return ShaderCache; }); -define('DataSources/RectangleGeometryUpdater',[ +define('Renderer/UniformState',[ + './Sampler', + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/oneTimeWarning', - '../Core/RectangleGeometry', - '../Core/RectangleOutlineGeometry', - '../Core/ShowGeometryInstanceAttribute', - '../Scene/GroundPrimitive', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' + '../Core/EncodedCartesian3', + '../Core/Math', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/OrthographicFrustum', + '../Core/Simon1994PlanetaryPositions', + '../Core/Transforms', + '../Scene/SceneMode' ], function( + Sampler, + BoundingRectangle, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, Color, - ColorGeometryInstanceAttribute, defaultValue, defined, defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - oneTimeWarning, - RectangleGeometry, - RectangleOutlineGeometry, - ShowGeometryInstanceAttribute, - GroundPrimitive, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { + EncodedCartesian3, + CesiumMath, + Matrix3, + Matrix4, + OrthographicFrustum, + Simon1994PlanetaryPositions, + Transforms, + SceneMode) { 'use strict'; - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + /** + * @private + */ + function UniformState() { + /** + * @type {Texture} + */ + this.globeDepthTexture = undefined; - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.rectangle = undefined; - this.closeBottom = undefined; - this.closeTop = undefined; - this.height = undefined; - this.extrudedHeight = undefined; - this.granularity = undefined; - this.stRotation = undefined; - this.rotation = undefined; - } + this._viewport = new BoundingRectangle(); + this._viewportCartesian4 = new Cartesian4(); + this._viewportDirty = false; + this._viewportOrthographicMatrix = Matrix4.clone(Matrix4.IDENTITY); + this._viewportTransformation = Matrix4.clone(Matrix4.IDENTITY); + + this._model = Matrix4.clone(Matrix4.IDENTITY); + this._view = Matrix4.clone(Matrix4.IDENTITY); + this._inverseView = Matrix4.clone(Matrix4.IDENTITY); + this._projection = Matrix4.clone(Matrix4.IDENTITY); + this._infiniteProjection = Matrix4.clone(Matrix4.IDENTITY); + this._entireFrustum = new Cartesian2(); + this._currentFrustum = new Cartesian2(); + this._frustumPlanes = new Cartesian4(); + + this._frameState = undefined; + this._temeToPseudoFixed = Matrix3.clone(Matrix4.IDENTITY); + + // Derived members + this._view3DDirty = true; + this._view3D = new Matrix4(); + + this._inverseView3DDirty = true; + this._inverseView3D = new Matrix4(); + + this._inverseModelDirty = true; + this._inverseModel = new Matrix4(); + + this._inverseTransposeModelDirty = true; + this._inverseTransposeModel = new Matrix3(); + + this._viewRotation = new Matrix3(); + this._inverseViewRotation = new Matrix3(); + + this._viewRotation3D = new Matrix3(); + this._inverseViewRotation3D = new Matrix3(); + + this._inverseProjectionDirty = true; + this._inverseProjection = new Matrix4(); + + this._modelViewDirty = true; + this._modelView = new Matrix4(); + + this._modelView3DDirty = true; + this._modelView3D = new Matrix4(); + + this._modelViewRelativeToEyeDirty = true; + this._modelViewRelativeToEye = new Matrix4(); + + this._inverseModelViewDirty = true; + this._inverseModelView = new Matrix4(); + + this._inverseModelView3DDirty = true; + this._inverseModelView3D = new Matrix4(); + + this._viewProjectionDirty = true; + this._viewProjection = new Matrix4(); + + this._inverseViewProjectionDirty = true; + this._inverseViewProjection = new Matrix4(); + + this._modelViewProjectionDirty = true; + this._modelViewProjection = new Matrix4(); + + this._inverseModelViewProjectionDirty = true; + this._inverseModelViewProjection = new Matrix4(); + + this._modelViewProjectionRelativeToEyeDirty = true; + this._modelViewProjectionRelativeToEye = new Matrix4(); + + this._modelViewInfiniteProjectionDirty = true; + this._modelViewInfiniteProjection = new Matrix4(); + + this._normalDirty = true; + this._normal = new Matrix3(); + + this._normal3DDirty = true; + this._normal3D = new Matrix3(); + + this._inverseNormalDirty = true; + this._inverseNormal = new Matrix3(); + + this._inverseNormal3DDirty = true; + this._inverseNormal3D = new Matrix3(); + + this._encodedCameraPositionMCDirty = true; + this._encodedCameraPositionMC = new EncodedCartesian3(); + this._cameraPosition = new Cartesian3(); + + this._sunPositionWC = new Cartesian3(); + this._sunPositionColumbusView = new Cartesian3(); + this._sunDirectionWC = new Cartesian3(); + this._sunDirectionEC = new Cartesian3(); + this._moonDirectionEC = new Cartesian3(); + + this._pass = undefined; + this._mode = undefined; + this._mapProjection = undefined; + this._cameraDirection = new Cartesian3(); + this._cameraRight = new Cartesian3(); + this._cameraUp = new Cartesian3(); + this._frustum2DWidth = 0.0; + this._eyeHeight2D = new Cartesian2(); + this._resolutionScale = 1.0; + this._orthographicIn3D = false; + this._backgroundColor = new Color(); - /** - * A {@link GeometryUpdater} for rectangles. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias RectangleGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function RectangleGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); - } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(RectangleGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._isClosed = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._onTerrain = false; - this._options = new GeometryOptions(entity); + this._brdfLut = new Sampler(); + this._environmentMap = new Sampler(); - this._onEntityPropertyChanged(entity, 'rectangle', entity.rectangle, undefined); + this._fogDensity = undefined; + + this._invertClassificationColor = undefined; + + this._imagerySplitPosition = 0.0; + this._pixelSizePerMeter = undefined; + this._geometricToleranceOverMeter = undefined; + + this._minimumDisableDepthTestDistance = undefined; } - defineProperties(RectangleGeometryUpdater, { + defineProperties(UniformState.prototype, { /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof RectangleGeometryUpdater - * @type {Appearance} + * @memberof UniformState.prototype + * @type {FrameState} + * @readonly */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance + frameState : { + get : function() { + return this._frameState; + } }, /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof RectangleGeometryUpdater - * @type {Appearance} + * @memberof UniformState.prototype + * @type {BoundingRectangle} */ - materialAppearanceType : { - value : MaterialAppearance - } - }); + viewport : { + get : function() { + return this._viewport; + }, + set : function(viewport) { + if (!BoundingRectangle.equals(viewport, this._viewport)) { + BoundingRectangle.clone(viewport, this._viewport); + + var v = this._viewport; + var vc = this._viewportCartesian4; + vc.x = v.x; + vc.y = v.y; + vc.z = v.width; + vc.w = v.height; + + this._viewportDirty = true; + } + } + }, - defineProperties(RectangleGeometryUpdater.prototype, { /** - * Gets the entity associated with this geometry. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Entity} - * @readonly + * @memberof UniformState.prototype + * @private */ - entity : { + viewportCartesian4 : { get : function() { - return this._entity; + return this._viewportCartesian4; + } + }, + + viewportOrthographic : { + get : function() { + cleanViewport(this); + return this._viewportOrthographicMatrix; + } + }, + + viewportTransformation : { + get : function() { + cleanViewport(this); + return this._viewportTransformation; } }, + /** - * Gets a value indicating if the geometry has a fill component. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix4} */ - fillEnabled : { + model : { get : function() { - return this._fillEnabled; + return this._model; + }, + set : function(matrix) { + Matrix4.clone(matrix, this._model); + + this._modelView3DDirty = true; + this._inverseModelView3DDirty = true; + this._inverseModelDirty = true; + this._inverseTransposeModelDirty = true; + this._modelViewDirty = true; + this._inverseModelViewDirty = true; + this._modelViewRelativeToEyeDirty = true; + this._inverseModelViewDirty = true; + this._modelViewProjectionDirty = true; + this._inverseModelViewProjectionDirty = true; + this._modelViewProjectionRelativeToEyeDirty = true; + this._modelViewInfiniteProjectionDirty = true; + this._normalDirty = true; + this._inverseNormalDirty = true; + this._normal3DDirty = true; + this._inverseNormal3DDirty = true; + this._encodedCameraPositionMCDirty = true; } }, + /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix4} */ - hasConstantFill : { + inverseModel : { get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); + if (this._inverseModelDirty) { + this._inverseModelDirty = false; + + Matrix4.inverse(this._model, this._inverseModel); + } + + return this._inverseModel; } }, + /** - * Gets the material property used to fill the geometry. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly + * @memberof UniformState.prototype + * @private */ - fillMaterialProperty : { + inverseTransposeModel : { get : function() { - return this._materialProperty; + var m = this._inverseTransposeModel; + if (this._inverseTransposeModelDirty) { + this._inverseTransposeModelDirty = false; + + Matrix4.getRotation(this.inverseModel, m); + Matrix3.transpose(m, m); + } + + return m; } }, + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix4} */ - outlineEnabled : { + view : { get : function() { - return this._outlineEnabled; + return this._view; } }, + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * The 3D view matrix. In 3D mode, this is identical to {@link UniformState#view}, + * but in 2D and Columbus View it is a synthetic matrix based on the equivalent position + * of the camera in the 3D world. + * @memberof UniformState.prototype + * @type {Matrix4} */ - hasConstantOutline : { + view3D : { get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); + updateView3D(this); + return this._view3D; } }, + /** - * Gets the {@link Color} property for the geometry outline. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * The 3x3 rotation matrix of the current view matrix ({@link UniformState#view}). + * @memberof UniformState.prototype + * @type {Matrix3} */ - outlineColorProperty : { + viewRotation : { get : function() { - return this._outlineColorProperty; + updateView3D(this); + return this._viewRotation; } }, + /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Number} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix3} */ - outlineWidth : { + viewRotation3D : { get : function() { - return this._outlineWidth; + updateView3D(this); + return this._viewRotation3D; } }, + /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix4} */ - shadowsProperty : { + inverseView : { get : function() { - return this._shadowsProperty; + return this._inverseView; } }, + /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * the 4x4 inverse-view matrix that transforms from eye to 3D world coordinates. In 3D mode, this is + * identical to {@link UniformState#inverseView}, but in 2D and Columbus View it is a synthetic matrix + * based on the equivalent position of the camera in the 3D world. + * @memberof UniformState.prototype + * @type {Matrix4} */ - distanceDisplayConditionProperty : { + inverseView3D : { get : function() { - return this._distanceDisplayConditionProperty; + updateInverseView3D(this); + return this._inverseView3D; } }, + /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix3} */ - isDynamic : { + inverseViewRotation : { get : function() { - return this._dynamic; + return this._inverseViewRotation; } }, + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * The 3x3 rotation matrix of the current 3D inverse-view matrix ({@link UniformState#inverseView3D}). + * @memberof UniformState.prototype + * @type {Matrix3} */ - isClosed : { + inverseViewRotation3D : { get : function() { - return this._isClosed; + updateInverseView3D(this); + return this._inverseViewRotation3D; } }, + /** - * Gets a value indicating if the geometry should be drawn on terrain. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix4} */ - onTerrain : { + projection : { get : function() { - return this._onTerrain; + return this._projection; } }, + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof RectangleGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Matrix4} */ - geometryChanged : { + inverseProjection : { get : function() { - return this._geometryChanged; + cleanInverseProjection(this); + return this._inverseProjection; } - } - }); - - /** - * Checks if the geometry is outlined at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - RectangleGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); - }; - - /** - * Checks if the geometry is filled at the provided time. - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - RectangleGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); - }; - - /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - RectangleGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - - var attributes; + }, - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + infiniteProjection : { + get : function() { + return this._infiniteProjection; } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; - } - - return new GeometryInstance({ - id : entity, - geometry : new RectangleGeometry(this._options), - attributes : attributes - }); - }; - - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - RectangleGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); - } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + }, - return new GeometryInstance({ - id : entity, - geometry : new RectangleOutlineGeometry(this._options), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + modelView : { + get : function() { + cleanModelView(this); + return this._modelView; } - }); - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - RectangleGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - RectangleGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; - - RectangleGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'rectangle')) { - return; - } - - var rectangle = this._entity.rectangle; + }, - if (!defined(rectangle)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + /** + * The 3D model-view matrix. In 3D mode, this is equivalent to {@link UniformState#modelView}. In 2D and + * Columbus View, however, it is a synthetic matrix based on the equivalent position of the camera in the 3D world. + * @memberof UniformState.prototype + * @type {Matrix4} + */ + modelView3D : { + get : function() { + cleanModelView3D(this); + return this._modelView3D; } - return; - } - - var fillProperty = rectangle.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; - - var outlineProperty = rectangle.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); - } + }, - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + /** + * Model-view relative to eye matrix. + * + * @memberof UniformState.prototype + * @type {Matrix4} + */ + modelViewRelativeToEye : { + get : function() { + cleanModelViewRelativeToEye(this); + return this._modelViewRelativeToEye; } - return; - } - - var coordinates = rectangle.coordinates; + }, - var show = rectangle.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(coordinates))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + inverseModelView : { + get : function() { + cleanInverseModelView(this); + return this._inverseModelView; } - return; - } - - var material = defaultValue(rectangle.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(rectangle.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(rectangle.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(rectangle.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(rectangle.distanceDisplayCondition, defaultDistanceDisplayCondition); - - var height = rectangle.height; - var extrudedHeight = rectangle.extrudedHeight; - var granularity = rectangle.granularity; - var stRotation = rectangle.stRotation; - var rotation = rectangle.rotation; - var outlineWidth = rectangle.outlineWidth; - var closeBottom = rectangle.closeBottom; - var closeTop = rectangle.closeTop; - var onTerrain = fillEnabled && !defined(height) && !defined(extrudedHeight) && - isColorMaterial && GroundPrimitive.isSupported(this._scene); - - if (outlineEnabled && onTerrain) { - oneTimeWarning(oneTimeWarning.geometryOutlines); - outlineEnabled = false; - } + }, - this._fillEnabled = fillEnabled; - this._onTerrain = onTerrain; - this._outlineEnabled = outlineEnabled; + /** + * The inverse of the 3D model-view matrix. In 3D mode, this is equivalent to {@link UniformState#inverseModelView}. + * In 2D and Columbus View, however, it is a synthetic matrix based on the equivalent position of the camera in the 3D world. + * @memberof UniformState.prototype + * @type {Matrix4} + */ + inverseModelView3D : { + get : function() { + cleanInverseModelView3D(this); + return this._inverseModelView3D; - if (!coordinates.isConstant || // - !Property.isConstant(height) || // - !Property.isConstant(extrudedHeight) || // - !Property.isConstant(granularity) || // - !Property.isConstant(stRotation) || // - !Property.isConstant(rotation) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(closeBottom) || // - !Property.isConstant(closeTop) || // - (onTerrain && !Property.isConstant(material))) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.rectangle = coordinates.getValue(Iso8601.MINIMUM_VALUE, options.rectangle); - options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.stRotation = defined(stRotation) ? stRotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.rotation = defined(rotation) ? rotation.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.closeBottom = defined(closeBottom) ? closeBottom.getValue(Iso8601.MINIMUM_VALUE) : undefined; - options.closeTop = defined(closeTop) ? closeTop.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._isClosed = defined(extrudedHeight) && defined(options.closeTop) && defined(options.closeBottom) && options.closeTop && options.closeBottom; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); - } - }; - - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @param {PrimitiveCollection} groundPrimitives The primitive collection to use for GroundPrimitives. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - RectangleGeometryUpdater.prototype.createDynamicUpdater = function(primitives, groundPrimitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); - } - - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); - } - - return new DynamicGeometryUpdater(primitives, groundPrimitives, this); - }; - - /** - * @private - */ - function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) { - this._primitives = primitives; - this._groundPrimitives = groundPrimitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); - } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - - var geometryUpdater = this._geometryUpdater; - var onTerrain = geometryUpdater._onTerrain; - - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._outlinePrimitive = undefined; - } - this._primitive = undefined; - - var entity = geometryUpdater._entity; - var rectangle = entity.rectangle; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(rectangle.show, time, true)) { - return; - } - - var options = this._options; - var coordinates = Property.getValueOrUndefined(rectangle.coordinates, time, options.rectangle); - if (!defined(coordinates)) { - return; - } - - options.rectangle = coordinates; - options.height = Property.getValueOrUndefined(rectangle.height, time); - options.extrudedHeight = Property.getValueOrUndefined(rectangle.extrudedHeight, time); - options.granularity = Property.getValueOrUndefined(rectangle.granularity, time); - options.stRotation = Property.getValueOrUndefined(rectangle.stRotation, time); - options.rotation = Property.getValueOrUndefined(rectangle.rotation, time); - options.closeBottom = Property.getValueOrUndefined(rectangle.closeBottom, time); - options.closeTop = Property.getValueOrUndefined(rectangle.closeTop, time); + }, - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + viewProjection : { + get : function() { + cleanViewProjection(this); + return this._viewProjection; + } + }, - if (Property.getValueOrDefault(rectangle.fill, time, true)) { - var fillMaterialProperty = geometryUpdater.fillMaterialProperty; - var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material); - this._material = material; + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + inverseViewProjection : { + get : function() { + cleanInverseViewProjection(this); + return this._inverseViewProjection; + } + }, - if (onTerrain) { - var currentColor = Color.WHITE; - if (defined(fillMaterialProperty.color)) { - currentColor = fillMaterialProperty.color.getValue(time); - } + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + modelViewProjection : { + get : function() { + cleanModelViewProjection(this); + return this._modelViewProjection; - this._primitive = groundPrimitives.add(new GroundPrimitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new RectangleGeometry(options), - attributes: { - color: ColorGeometryInstanceAttribute.fromColor(currentColor) - } - }), - asynchronous : false, - shadows : shadows - })); - } else { - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : defined(options.extrudedHeight) - }); + } + }, - options.vertexFormat = appearance.vertexFormat; + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + inverseModelViewProjection : { + get : function() { + cleanInverseModelViewProjection(this); + return this._inverseModelViewProjection; - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new RectangleGeometry(options) - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); } - } + }, - if (!onTerrain && Property.getValueOrDefault(rectangle.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + /** + * Model-view-projection relative to eye matrix. + * + * @memberof UniformState.prototype + * @type {Matrix4} + */ + modelViewProjectionRelativeToEye : { + get : function() { + cleanModelViewProjectionRelativeToEye(this); + return this._modelViewProjectionRelativeToEye; + } + }, - var outlineColor = Property.getValueOrClonedDefault(rectangle.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(rectangle.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + /** + * @memberof UniformState.prototype + * @type {Matrix4} + */ + modelViewInfiniteProjection : { + get : function() { + cleanModelViewInfiniteProjection(this); + return this._modelViewInfiniteProjection; + } + }, - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new RectangleOutlineGeometry(options), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor) - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) - } - }), - asynchronous : false, - shadows : shadows - })); - } - }; + /** + * A 3x3 normal transformation matrix that transforms normal vectors in model coordinates to + * eye coordinates. + * @memberof UniformState.prototype + * @type {Matrix3} + */ + normal : { + get : function() { + cleanNormal(this); + return this._normal; + } + }, - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; + /** + * A 3x3 normal transformation matrix that transforms normal vectors in 3D model + * coordinates to eye coordinates. In 3D mode, this is identical to + * {@link UniformState#normal}, but in 2D and Columbus View it represents the normal transformation + * matrix as if the camera were at an equivalent location in 3D mode. + * @memberof UniformState.prototype + * @type {Matrix3} + */ + normal3D : { + get : function() { + cleanNormal3D(this); + return this._normal3D; - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + } + }, - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - var groundPrimitives = this._groundPrimitives; - if (this._geometryUpdater._onTerrain) { - groundPrimitives.removeAndDestroy(this._primitive); - } else { - primitives.removeAndDestroy(this._primitive); - } - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; + /** + * An inverse 3x3 normal transformation matrix that transforms normal vectors in model coordinates + * to eye coordinates. + * @memberof UniformState.prototype + * @type {Matrix3} + */ + inverseNormal : { + get : function() { + cleanInverseNormal(this); + return this._inverseNormal; + } + }, - return RectangleGeometryUpdater; -}); + /** + * An inverse 3x3 normal transformation matrix that transforms normal vectors in eye coordinates + * to 3D model coordinates. In 3D mode, this is identical to + * {@link UniformState#inverseNormal}, but in 2D and Columbus View it represents the normal transformation + * matrix as if the camera were at an equivalent location in 3D mode. + * @memberof UniformState.prototype + * @type {Matrix3} + */ + inverseNormal3D : { + get : function() { + cleanInverseNormal3D(this); + return this._inverseNormal3D; + } + }, -define('DataSources/WallGeometryUpdater',[ - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/DistanceDisplayCondition', - '../Core/DistanceDisplayConditionGeometryInstanceAttribute', - '../Core/Event', - '../Core/GeometryInstance', - '../Core/Iso8601', - '../Core/ShowGeometryInstanceAttribute', - '../Core/WallGeometry', - '../Core/WallOutlineGeometry', - '../Scene/MaterialAppearance', - '../Scene/PerInstanceColorAppearance', - '../Scene/Primitive', - '../Scene/ShadowMode', - './ColorMaterialProperty', - './ConstantProperty', - './dynamicGeometryGetBoundingSphere', - './MaterialProperty', - './Property' - ], function( - Color, - ColorGeometryInstanceAttribute, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - DistanceDisplayCondition, - DistanceDisplayConditionGeometryInstanceAttribute, - Event, - GeometryInstance, - Iso8601, - ShowGeometryInstanceAttribute, - WallGeometry, - WallOutlineGeometry, - MaterialAppearance, - PerInstanceColorAppearance, - Primitive, - ShadowMode, - ColorMaterialProperty, - ConstantProperty, - dynamicGeometryGetBoundingSphere, - MaterialProperty, - Property) { - 'use strict'; + /** + * The near distance (<code>x</code>) and the far distance (<code>y</code>) of the frustum defined by the camera. + * This is the largest possible frustum, not an individual frustum used for multi-frustum rendering. + * @memberof UniformState.prototype + * @type {Cartesian2} + */ + entireFrustum : { + get : function() { + return this._entireFrustum; + } + }, - var defaultMaterial = new ColorMaterialProperty(Color.WHITE); - var defaultShow = new ConstantProperty(true); - var defaultFill = new ConstantProperty(true); - var defaultOutline = new ConstantProperty(false); - var defaultOutlineColor = new ConstantProperty(Color.BLACK); - var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); - var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); - var scratchColor = new Color(); + /** + * The near distance (<code>x</code>) and the far distance (<code>y</code>) of the frustum defined by the camera. + * This is the individual frustum used for multi-frustum rendering. + * @memberof UniformState.prototype + * @type {Cartesian2} + */ + currentFrustum : { + get : function() { + return this._currentFrustum; + } + }, - function GeometryOptions(entity) { - this.id = entity; - this.vertexFormat = undefined; - this.positions = undefined; - this.minimumHeights = undefined; - this.maximumHeights = undefined; - this.granularity = undefined; - } + /** + * The distances to the frustum planes. The top, bottom, left and right distances are + * the x, y, z, and w components, respectively. + * @memberof UniformState.prototype + * @type {Cartesian4} + */ + frustumPlanes : { + get : function() { + return this._frustumPlanes; + } + }, - /** - * A {@link GeometryUpdater} for walls. - * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}. - * @alias WallGeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. - */ - function WallGeometryUpdater(entity, scene) { - if (!defined(entity)) { - throw new DeveloperError('entity is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); - } - - this._entity = entity; - this._scene = scene; - this._entitySubscription = entity.definitionChanged.addEventListener(WallGeometryUpdater.prototype._onEntityPropertyChanged, this); - this._fillEnabled = false; - this._dynamic = false; - this._outlineEnabled = false; - this._geometryChanged = new Event(); - this._showProperty = undefined; - this._materialProperty = undefined; - this._hasConstantOutline = true; - this._showOutlineProperty = undefined; - this._outlineColorProperty = undefined; - this._outlineWidth = 1.0; - this._shadowsProperty = undefined; - this._distanceDisplayConditionProperty = undefined; - this._options = new GeometryOptions(entity); - this._onEntityPropertyChanged(entity, 'wall', entity.wall, undefined); - } + /** + * The the height (<code>x</code>) and the height squared (<code>y</code>) + * in meters of the camera above the 2D world plane. This uniform is only valid + * when the {@link SceneMode} equal to <code>SCENE2D</code>. + * @memberof UniformState.prototype + * @type {Cartesian2} + */ + eyeHeight2D : { + get : function() { + return this._eyeHeight2D; + } + }, - defineProperties(WallGeometryUpdater, { /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof WallGeometryUpdater - * @type {Appearance} + * The sun position in 3D world coordinates at the current scene time. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - perInstanceColorAppearanceType : { - value : PerInstanceColorAppearance + sunPositionWC : { + get : function() { + return this._sunPositionWC; + } }, + /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof WallGeometryUpdater - * @type {Appearance} + * The sun position in 2D world coordinates at the current scene time. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - materialAppearanceType : { - value : MaterialAppearance - } - }); + sunPositionColumbusView : { + get : function(){ + return this._sunPositionColumbusView; + } + }, - defineProperties(WallGeometryUpdater.prototype, { /** - * Gets the entity associated with this geometry. - * @memberof WallGeometryUpdater.prototype - * - * @type {Entity} - * @readonly + * A normalized vector to the sun in 3D world coordinates at the current scene time. Even in 2D or + * Columbus View mode, this returns the position of the sun in the 3D scene. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - entity : { + sunDirectionWC : { get : function() { - return this._entity; + return this._sunDirectionWC; } }, + /** - * Gets a value indicating if the geometry has a fill component. - * @memberof WallGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * A normalized vector to the sun in eye coordinates at the current scene time. In 3D mode, this + * returns the actual vector from the camera position to the sun position. In 2D and Columbus View, it returns + * the vector from the equivalent 3D camera position to the position of the sun in the 3D scene. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - fillEnabled : { + sunDirectionEC : { get : function() { - return this._fillEnabled; + return this._sunDirectionEC; } }, + /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof WallGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * A normalized vector to the moon in eye coordinates at the current scene time. In 3D mode, this + * returns the actual vector from the camera position to the moon position. In 2D and Columbus View, it returns + * the vector from the equivalent 3D camera position to the position of the moon in the 3D scene. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - hasConstantFill : { + moonDirectionEC : { get : function() { - return !this._fillEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._fillProperty)); + return this._moonDirectionEC; } }, + /** - * Gets the material property used to fill the geometry. - * @memberof WallGeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly + * The high bits of the camera position. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - fillMaterialProperty : { + encodedCameraPositionMCHigh : { get : function() { - return this._materialProperty; + cleanEncodedCameraPositionMC(this); + return this._encodedCameraPositionMC.high; } }, + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof WallGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * The low bits of the camera position. + * @memberof UniformState.prototype + * @type {Cartesian3} */ - outlineEnabled : { + encodedCameraPositionMCLow : { get : function() { - return this._outlineEnabled; + cleanEncodedCameraPositionMC(this); + return this._encodedCameraPositionMC.low; } }, + /** - * Gets a value indicating if the geometry has an outline component. - * @memberof WallGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * A 3x3 matrix that transforms from True Equator Mean Equinox (TEME) axes to the + * pseudo-fixed axes at the Scene's current time. + * @memberof UniformState.prototype + * @type {Matrix3} */ - hasConstantOutline : { + temeToPseudoFixedMatrix : { get : function() { - return !this._outlineEnabled || - (!defined(this._entity.availability) && - Property.isConstant(this._showProperty) && - Property.isConstant(this._showOutlineProperty)); + return this._temeToPseudoFixed; } }, + /** - * Gets the {@link Color} property for the geometry outline. - * @memberof WallGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * Gets the scaling factor for transforming from the canvas + * pixel space to canvas coordinate space. + * @memberof UniformState.prototype + * @type {Number} */ - outlineColorProperty : { + resolutionScale : { get : function() { - return this._outlineColorProperty; + return this._resolutionScale; } }, + /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof WallGeometryUpdater.prototype - * + * A scalar used to mix a color with the fog color based on the distance to the camera. + * @memberof UniformState.prototype * @type {Number} - * @readonly */ - outlineWidth : { + fogDensity : { get : function() { - return this._outlineWidth; + return this._fogDensity; } }, + /** - * Gets the property specifying whether the geometry - * casts or receives shadows from each light source. - * @memberof WallGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * A scalar that represents the geometric tolerance per meter + * @memberof UniformStat.prototype + * @type {Number} */ - shadowsProperty : { + geometricToleranceOverMeter: { + get: function() { + return this._geometricToleranceOverMeter; + } + }, + + /** + * @memberof UniformState.prototype + * @type {Pass} + */ + pass : { get : function() { - return this._shadowsProperty; + return this._pass; } }, + /** - * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed. - * @memberof WallGeometryUpdater.prototype - * - * @type {Property} - * @readonly + * The current background color + * @memberof UniformState.prototype + * @type {Color} */ - distanceDisplayConditionProperty : { + backgroundColor : { get : function() { - return this._distanceDisplayConditionProperty; + return this._backgroundColor; } }, + /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof WallGeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * The look up texture used to find the BRDF for a material + * @memberof UniformState.prototype + * @type {Sampler} */ - isDynamic : { + brdfLut : { get : function() { - return this._dynamic; + return this._brdfLut; } }, + /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof WallGeometryUpdater.prototype + * The environment map of the scene + * @memberof UniformState.prototype + * @type {Sampler} + */ + environmentMap : { + get : function() { + return this._environmentMap; + } + }, + + /** + * @memberof UniformState.prototype + * @type {Number} + */ + imagerySplitPosition : { + get : function() { + return this._imagerySplitPosition; + } + }, + + /** + * The distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always + * be applied. When less than zero, the depth test should never be applied. * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Number} */ - isClosed : { + minimumDisableDepthTestDistance : { get : function() { - return false; + return this._minimumDisableDepthTestDistance; } }, + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof WallGeometryUpdater.prototype + * The highlight color of unclassified 3D Tiles. * - * @type {Boolean} - * @readonly + * @memberof UniformState.prototype + * @type {Color} */ - geometryChanged : { + invertClassificationColor : { get : function() { - return this._geometryChanged; + return this._invertClassificationColor; } } }); + function setView(uniformState, matrix) { + Matrix4.clone(matrix, uniformState._view); + Matrix4.getRotation(matrix, uniformState._viewRotation); + + uniformState._view3DDirty = true; + uniformState._inverseView3DDirty = true; + uniformState._modelViewDirty = true; + uniformState._modelView3DDirty = true; + uniformState._modelViewRelativeToEyeDirty = true; + uniformState._inverseModelViewDirty = true; + uniformState._inverseModelView3DDirty = true; + uniformState._viewProjectionDirty = true; + uniformState._inverseViewProjectionDirty = true; + uniformState._modelViewProjectionDirty = true; + uniformState._modelViewProjectionRelativeToEyeDirty = true; + uniformState._modelViewInfiniteProjectionDirty = true; + uniformState._normalDirty = true; + uniformState._inverseNormalDirty = true; + uniformState._normal3DDirty = true; + uniformState._inverseNormal3DDirty = true; + } + + function setInverseView(uniformState, matrix) { + Matrix4.clone(matrix, uniformState._inverseView); + Matrix4.getRotation(matrix, uniformState._inverseViewRotation); + } + + function setProjection(uniformState, matrix) { + Matrix4.clone(matrix, uniformState._projection); + + uniformState._inverseProjectionDirty = true; + uniformState._viewProjectionDirty = true; + uniformState._inverseViewProjectionDirty = true; + uniformState._modelViewProjectionDirty = true; + uniformState._modelViewProjectionRelativeToEyeDirty = true; + } + + function setInfiniteProjection(uniformState, matrix) { + Matrix4.clone(matrix, uniformState._infiniteProjection); + + uniformState._modelViewInfiniteProjectionDirty = true; + } + + function setCamera(uniformState, camera) { + Cartesian3.clone(camera.positionWC, uniformState._cameraPosition); + Cartesian3.clone(camera.directionWC, uniformState._cameraDirection); + Cartesian3.clone(camera.rightWC, uniformState._cameraRight); + Cartesian3.clone(camera.upWC, uniformState._cameraUp); + uniformState._encodedCameraPositionMCDirty = true; + } + + var transformMatrix = new Matrix3(); + var sunCartographicScratch = new Cartographic(); + function setSunAndMoonDirections(uniformState, frameState) { + if (!defined(Transforms.computeIcrfToFixedMatrix(frameState.time, transformMatrix))) { + transformMatrix = Transforms.computeTemeToPseudoFixedMatrix(frameState.time, transformMatrix); + } + + var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(frameState.time, uniformState._sunPositionWC); + Matrix3.multiplyByVector(transformMatrix, position, position); + + Cartesian3.normalize(position, uniformState._sunDirectionWC); + + position = Matrix3.multiplyByVector(uniformState.viewRotation3D, position, uniformState._sunDirectionEC); + Cartesian3.normalize(position, position); + + position = Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(frameState.time, uniformState._moonDirectionEC); + Matrix3.multiplyByVector(transformMatrix, position, position); + Matrix3.multiplyByVector(uniformState.viewRotation3D, position, position); + Cartesian3.normalize(position, position); + + var projection = frameState.mapProjection; + var ellipsoid = projection.ellipsoid; + var sunCartographic = ellipsoid.cartesianToCartographic(uniformState._sunPositionWC, sunCartographicScratch); + projection.project(sunCartographic, uniformState._sunPositionColumbusView); + } + /** - * Checks if the geometry is outlined at the provided time. + * Synchronizes the frustum's state with the camera state. This is called + * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms + * are set to the right value. * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + * @param {Object} camera The camera to synchronize with. */ - WallGeometryUpdater.prototype.isOutlineVisible = function(time) { - var entity = this._entity; - return this._outlineEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time); + UniformState.prototype.updateCamera = function(camera) { + setView(this, camera.viewMatrix); + setInverseView(this, camera.inverseViewMatrix); + setCamera(this, camera); + + this._entireFrustum.x = camera.frustum.near; + this._entireFrustum.y = camera.frustum.far; + this.updateFrustum(camera.frustum); + + this._orthographicIn3D = this._mode !== SceneMode.SCENE2D && camera.frustum instanceof OrthographicFrustum; }; /** - * Checks if the geometry is filled at the provided time. + * Synchronizes the frustum's state with the uniform state. This is called + * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms + * are set to the right value. * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + * @param {Object} frustum The frustum to synchronize with. */ - WallGeometryUpdater.prototype.isFilled = function(time) { - var entity = this._entity; - return this._fillEnabled && entity.isAvailable(time) && this._showProperty.getValue(time) && this._fillProperty.getValue(time); + UniformState.prototype.updateFrustum = function(frustum) { + setProjection(this, frustum.projectionMatrix); + if (defined(frustum.infiniteProjectionMatrix)) { + setInfiniteProjection(this, frustum.infiniteProjectionMatrix); + } + this._currentFrustum.x = frustum.near; + this._currentFrustum.y = frustum.far; + + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } + + this._frustumPlanes.x = frustum.top; + this._frustumPlanes.y = frustum.bottom; + this._frustumPlanes.z = frustum.left; + this._frustumPlanes.w = frustum.right; + }; + + UniformState.prototype.updatePass = function(pass) { + this._pass = pass; }; /** - * Creates the geometry instance which represents the fill of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. + * Synchronizes frame state with the uniform state. This is called + * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms + * are set to the right value. * - * @exception {DeveloperError} This instance does not represent a filled geometry. + * @param {FrameState} frameState The frameState to synchronize with. */ - WallGeometryUpdater.prototype.createFillGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } + UniformState.prototype.update = function(frameState) { + this._mode = frameState.mode; + this._mapProjection = frameState.mapProjection; - if (!this._fillEnabled) { - throw new DeveloperError('This instance does not represent a filled geometry.'); + var canvas = frameState.context._canvas; + this._resolutionScale = canvas.width / canvas.clientWidth; + + var camera = frameState.camera; + this.updateCamera(camera); + + if (frameState.mode === SceneMode.SCENE2D) { + this._frustum2DWidth = camera.frustum.right - camera.frustum.left; + this._eyeHeight2D.x = this._frustum2DWidth * 0.5; + this._eyeHeight2D.y = this._eyeHeight2D.x * this._eyeHeight2D.x; + } else { + this._frustum2DWidth = 0.0; + this._eyeHeight2D.x = 0.0; + this._eyeHeight2D.y = 0.0; } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var attributes; + setSunAndMoonDirections(this, frameState); - var color; - var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); - var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); - if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; - if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { - currentColor = this._materialProperty.color.getValue(time); - } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; + var brdfLutGenerator = frameState.brdfLutGenerator; + var brdfLut = defined(brdfLutGenerator) ? brdfLutGenerator.colorTexture : undefined; + this._brdfLut = brdfLut; + + this._environmentMap = defaultValue(frameState.environmentMap, frameState.context.defaultCubeMap); + + this._fogDensity = frameState.fog.density; + + this._invertClassificationColor = frameState.invertClassificationColor; + + this._frameState = frameState; + this._temeToPseudoFixed = Transforms.computeTemeToPseudoFixedMatrix(frameState.time, this._temeToPseudoFixed); + + // Convert the relative imagerySplitPosition to absolute pixel coordinates + this._imagerySplitPosition = frameState.imagerySplitPosition * frameState.context.drawingBufferWidth; + var fov = camera.frustum.fov; + var viewport = this._viewport; + var pixelSizePerMeter; + if (viewport.height > viewport.width) { + pixelSizePerMeter = Math.tan(0.5 * fov) * 2.0 / viewport.height; } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; + pixelSizePerMeter = Math.tan(0.5 * fov) * 2.0 / viewport.width; } - return new GeometryInstance({ - id : entity, - geometry : new WallGeometry(this._options), - attributes : attributes - }); - }; + this._geometricToleranceOverMeter = pixelSizePerMeter * frameState.maximumScreenSpaceError; + Color.clone(frameState.backgroundColor, this._backgroundColor); - /** - * Creates the geometry instance which represents the outline of the geometry. - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - WallGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + this._minimumDisableDepthTestDistance = frameState.minimumDisableDepthTestDistance; + this._minimumDisableDepthTestDistance *= this._minimumDisableDepthTestDistance; + if (this._minimumDisableDepthTestDistance === Number.POSITIVE_INFINITY) { + this._minimumDisableDepthTestDistance = -1.0; } + }; - if (!this._outlineEnabled) { - throw new DeveloperError('This instance does not represent an outlined geometry.'); + function cleanViewport(uniformState) { + if (uniformState._viewportDirty) { + var v = uniformState._viewport; + Matrix4.computeOrthographicOffCenter(v.x, v.x + v.width, v.y, v.y + v.height, 0.0, 1.0, uniformState._viewportOrthographicMatrix); + Matrix4.computeViewportTransformation(v, 0.0, 1.0, uniformState._viewportTransformation); + uniformState._viewportDirty = false; } - - var entity = this._entity; - var isAvailable = entity.isAvailable(time); - var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK); - var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); + } - return new GeometryInstance({ - id : entity, - geometry : new WallOutlineGeometry(this._options), - attributes : { - show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), - color : ColorGeometryInstanceAttribute.fromColor(outlineColor), - distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition) + function cleanInverseProjection(uniformState) { + if (uniformState._inverseProjectionDirty) { + uniformState._inverseProjectionDirty = false; + + if (uniformState._mode !== SceneMode.SCENE2D && uniformState._mode !== SceneMode.MORPHING && !uniformState._orthographicIn3D) { + Matrix4.inverse(uniformState._projection, uniformState._inverseProjection); + } else { + Matrix4.clone(Matrix4.ZERO, uniformState._inverseProjection); } - }); - }; + } + } - /** - * Returns true if this object was destroyed; otherwise, false. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - WallGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + // Derived + function cleanModelView(uniformState) { + if (uniformState._modelViewDirty) { + uniformState._modelViewDirty = false; - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - WallGeometryUpdater.prototype.destroy = function() { - this._entitySubscription(); - destroyObject(this); - }; + Matrix4.multiplyTransformation(uniformState._view, uniformState._model, uniformState._modelView); + } + } - WallGeometryUpdater.prototype._onEntityPropertyChanged = function(entity, propertyName, newValue, oldValue) { - if (!(propertyName === 'availability' || propertyName === 'wall')) { - return; + function cleanModelView3D(uniformState) { + if (uniformState._modelView3DDirty) { + uniformState._modelView3DDirty = false; + + Matrix4.multiplyTransformation(uniformState.view3D, uniformState._model, uniformState._modelView3D); } + } - var wall = this._entity.wall; + function cleanInverseModelView(uniformState) { + if (uniformState._inverseModelViewDirty) { + uniformState._inverseModelViewDirty = false; - if (!defined(wall)) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + Matrix4.inverse(uniformState.modelView, uniformState._inverseModelView); } + } - var fillProperty = wall.fill; - var fillEnabled = defined(fillProperty) && fillProperty.isConstant ? fillProperty.getValue(Iso8601.MINIMUM_VALUE) : true; + function cleanInverseModelView3D(uniformState) { + if (uniformState._inverseModelView3DDirty) { + uniformState._inverseModelView3DDirty = false; - var outlineProperty = wall.outline; - var outlineEnabled = defined(outlineProperty); - if (outlineEnabled && outlineProperty.isConstant) { - outlineEnabled = outlineProperty.getValue(Iso8601.MINIMUM_VALUE); + Matrix4.inverse(uniformState.modelView3D, uniformState._inverseModelView3D); } + } - if (!fillEnabled && !outlineEnabled) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + function cleanViewProjection(uniformState) { + if (uniformState._viewProjectionDirty) { + uniformState._viewProjectionDirty = false; + + Matrix4.multiply(uniformState._projection, uniformState._view, uniformState._viewProjection); } + } - var positions = wall.positions; + function cleanInverseViewProjection(uniformState) { + if (uniformState._inverseViewProjectionDirty) { + uniformState._inverseViewProjectionDirty = false; - var show = wall.show; - if ((defined(show) && show.isConstant && !show.getValue(Iso8601.MINIMUM_VALUE)) || // - (!defined(positions))) { - if (this._fillEnabled || this._outlineEnabled) { - this._fillEnabled = false; - this._outlineEnabled = false; - this._geometryChanged.raiseEvent(this); - } - return; + Matrix4.inverse(uniformState.viewProjection, uniformState._inverseViewProjection); } + } - var material = defaultValue(wall.material, defaultMaterial); - var isColorMaterial = material instanceof ColorMaterialProperty; - this._materialProperty = material; - this._fillProperty = defaultValue(fillProperty, defaultFill); - this._showProperty = defaultValue(show, defaultShow); - this._showOutlineProperty = defaultValue(wall.outline, defaultOutline); - this._outlineColorProperty = outlineEnabled ? defaultValue(wall.outlineColor, defaultOutlineColor) : undefined; - this._shadowsProperty = defaultValue(wall.shadows, defaultShadows); - this._distanceDisplayConditionProperty = defaultValue(wall.distanceDisplayCondition, defaultDistanceDisplayCondition); + function cleanModelViewProjection(uniformState) { + if (uniformState._modelViewProjectionDirty) { + uniformState._modelViewProjectionDirty = false; - var minimumHeights = wall.minimumHeights; - var maximumHeights = wall.maximumHeights; - var outlineWidth = wall.outlineWidth; - var granularity = wall.granularity; + Matrix4.multiply(uniformState._projection, uniformState.modelView, uniformState._modelViewProjection); + } + } - this._fillEnabled = fillEnabled; - this._outlineEnabled = outlineEnabled; + function cleanModelViewRelativeToEye(uniformState) { + if (uniformState._modelViewRelativeToEyeDirty) { + uniformState._modelViewRelativeToEyeDirty = false; - if (!positions.isConstant || // - !Property.isConstant(minimumHeights) || // - !Property.isConstant(maximumHeights) || // - !Property.isConstant(outlineWidth) || // - !Property.isConstant(granularity)) { - if (!this._dynamic) { - this._dynamic = true; - this._geometryChanged.raiseEvent(this); - } - } else { - var options = this._options; - options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat; - options.positions = positions.getValue(Iso8601.MINIMUM_VALUE, options.positions); - options.minimumHeights = defined(minimumHeights) ? minimumHeights.getValue(Iso8601.MINIMUM_VALUE, options.minimumHeights) : undefined; - options.maximumHeights = defined(maximumHeights) ? maximumHeights.getValue(Iso8601.MINIMUM_VALUE, options.maximumHeights) : undefined; - options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined; - this._outlineWidth = defined(outlineWidth) ? outlineWidth.getValue(Iso8601.MINIMUM_VALUE) : 1.0; - this._dynamic = false; - this._geometryChanged.raiseEvent(this); + var mv = uniformState.modelView; + var mvRte = uniformState._modelViewRelativeToEye; + mvRte[0] = mv[0]; + mvRte[1] = mv[1]; + mvRte[2] = mv[2]; + mvRte[3] = mv[3]; + mvRte[4] = mv[4]; + mvRte[5] = mv[5]; + mvRte[6] = mv[6]; + mvRte[7] = mv[7]; + mvRte[8] = mv[8]; + mvRte[9] = mv[9]; + mvRte[10] = mv[10]; + mvRte[11] = mv[11]; + mvRte[12] = 0.0; + mvRte[13] = 0.0; + mvRte[14] = 0.0; + mvRte[15] = mv[15]; } - }; + } - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - WallGeometryUpdater.prototype.createDynamicUpdater = function(primitives) { - if (!this._dynamic) { - throw new DeveloperError('This instance does not represent dynamic geometry.'); + function cleanInverseModelViewProjection(uniformState) { + if (uniformState._inverseModelViewProjectionDirty) { + uniformState._inverseModelViewProjectionDirty = false; + + Matrix4.inverse(uniformState.modelViewProjection, uniformState._inverseModelViewProjection); } + } - if (!defined(primitives)) { - throw new DeveloperError('primitives is required.'); + function cleanModelViewProjectionRelativeToEye(uniformState) { + if (uniformState._modelViewProjectionRelativeToEyeDirty) { + uniformState._modelViewProjectionRelativeToEyeDirty = false; + + Matrix4.multiply(uniformState._projection, uniformState.modelViewRelativeToEye, uniformState._modelViewProjectionRelativeToEye); } - - return new DynamicGeometryUpdater(primitives, this); - }; + } - /** - * @private - */ - function DynamicGeometryUpdater(primitives, geometryUpdater) { - this._primitives = primitives; - this._primitive = undefined; - this._outlinePrimitive = undefined; - this._geometryUpdater = geometryUpdater; - this._options = new GeometryOptions(geometryUpdater._entity); + function cleanModelViewInfiniteProjection(uniformState) { + if (uniformState._modelViewInfiniteProjectionDirty) { + uniformState._modelViewInfiniteProjectionDirty = false; + + Matrix4.multiply(uniformState._infiniteProjection, uniformState.modelView, uniformState._modelViewInfiniteProjection); + } } - DynamicGeometryUpdater.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + + function cleanNormal(uniformState) { + if (uniformState._normalDirty) { + uniformState._normalDirty = false; + + var m = uniformState._normal; + Matrix4.getRotation(uniformState.inverseModelView, m); + Matrix3.transpose(m, m); } - - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - this._primitive = undefined; - this._outlinePrimitive = undefined; + } - var geometryUpdater = this._geometryUpdater; - var entity = geometryUpdater._entity; - var wall = entity.wall; - if (!entity.isShowing || !entity.isAvailable(time) || !Property.getValueOrDefault(wall.show, time, true)) { - return; + function cleanNormal3D(uniformState) { + if (uniformState._normal3DDirty) { + uniformState._normal3DDirty = false; + + var m = uniformState._normal3D; + Matrix4.getRotation(uniformState.inverseModelView3D, m); + Matrix3.transpose(m, m); } + } - var options = this._options; - var positions = Property.getValueOrUndefined(wall.positions, time, options.positions); - if (!defined(positions)) { - return; + function cleanInverseNormal(uniformState) { + if (uniformState._inverseNormalDirty) { + uniformState._inverseNormalDirty = false; + + Matrix4.getRotation(uniformState.inverseModelView, uniformState._inverseNormal); } + } - options.positions = positions; - options.minimumHeights = Property.getValueOrUndefined(wall.minimumHeights, time, options.minimumHeights); - options.maximumHeights = Property.getValueOrUndefined(wall.maximumHeights, time, options.maximumHeights); - options.granularity = Property.getValueOrUndefined(wall.granularity, time); + function cleanInverseNormal3D(uniformState) { + if (uniformState._inverseNormal3DDirty) { + uniformState._inverseNormal3DDirty = false; - var shadows = this._geometryUpdater.shadowsProperty.getValue(time); + Matrix4.getRotation(uniformState.inverseModelView3D, uniformState._inverseNormal3D); + } + } - if (Property.getValueOrDefault(wall.fill, time, true)) { - var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material); - this._material = material; + var cameraPositionMC = new Cartesian3(); - var appearance = new MaterialAppearance({ - material : material, - translucent : material.isTranslucent(), - closed : defined(options.extrudedHeight) - }); - options.vertexFormat = appearance.vertexFormat; + function cleanEncodedCameraPositionMC(uniformState) { + if (uniformState._encodedCameraPositionMCDirty) { + uniformState._encodedCameraPositionMCDirty = false; - this._primitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new WallGeometry(options) - }), - appearance : appearance, - asynchronous : false, - shadows : shadows - })); + Matrix4.multiplyByPoint(uniformState.inverseModel, uniformState._cameraPosition, cameraPositionMC); + EncodedCartesian3.fromCartesian(cameraPositionMC, uniformState._encodedCameraPositionMC); } + } - if (Property.getValueOrDefault(wall.outline, time, false)) { - options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT; + var view2Dto3DPScratch = new Cartesian3(); + var view2Dto3DRScratch = new Cartesian3(); + var view2Dto3DUScratch = new Cartesian3(); + var view2Dto3DDScratch = new Cartesian3(); + var view2Dto3DCartographicScratch = new Cartographic(); + var view2Dto3DCartesian3Scratch = new Cartesian3(); + var view2Dto3DMatrix4Scratch = new Matrix4(); - var outlineColor = Property.getValueOrClonedDefault(wall.outlineColor, time, Color.BLACK, scratchColor); - var outlineWidth = Property.getValueOrDefault(wall.outlineWidth, time, 1.0); - var translucent = outlineColor.alpha !== 1.0; + function view2Dto3D(position2D, direction2D, right2D, up2D, frustum2DWidth, mode, projection, result) { + // The camera position and directions are expressed in the 2D coordinate system where the Y axis is to the East, + // the Z axis is to the North, and the X axis is out of the map. Express them instead in the ENU axes where + // X is to the East, Y is to the North, and Z is out of the local horizontal plane. + var p = view2Dto3DPScratch; + p.x = position2D.y; + p.y = position2D.z; + p.z = position2D.x; - this._outlinePrimitive = primitives.add(new Primitive({ - geometryInstances : new GeometryInstance({ - id : entity, - geometry : new WallOutlineGeometry(options), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(outlineColor) - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : translucent, - renderState : { - lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth) - } - }), - asynchronous : false, - shadows : shadows - })); + var r = view2Dto3DRScratch; + r.x = right2D.y; + r.y = right2D.z; + r.z = right2D.x; + + var u = view2Dto3DUScratch; + u.x = up2D.y; + u.y = up2D.z; + u.z = up2D.x; + + var d = view2Dto3DDScratch; + d.x = direction2D.y; + d.y = direction2D.z; + d.z = direction2D.x; + + // In 2D, the camera height is always 12.7 million meters. + // The apparent height is equal to half the frustum width. + if (mode === SceneMode.SCENE2D) { + p.z = frustum2DWidth * 0.5; } - }; - DynamicGeometryUpdater.prototype.getBoundingSphere = function(entity, result) { - return dynamicGeometryGetBoundingSphere(entity, this._primitive, this._outlinePrimitive, result); - }; + // Compute the equivalent camera position in the real (3D) world. + // In 2D and Columbus View, the camera can travel outside the projection, and when it does so + // there's not really any corresponding location in the real world. So clamp the unprojected + // longitude and latitude to their valid ranges. + var cartographic = projection.unproject(p, view2Dto3DCartographicScratch); + cartographic.longitude = CesiumMath.clamp(cartographic.longitude, -Math.PI, Math.PI); + cartographic.latitude = CesiumMath.clamp(cartographic.latitude, -CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO); + var ellipsoid = projection.ellipsoid; + var position3D = ellipsoid.cartographicToCartesian(cartographic, view2Dto3DCartesian3Scratch); - DynamicGeometryUpdater.prototype.isDestroyed = function() { - return false; - }; + // Compute the rotation from the local ENU at the real world camera position to the fixed axes. + var enuToFixed = Transforms.eastNorthUpToFixedFrame(position3D, ellipsoid, view2Dto3DMatrix4Scratch); - DynamicGeometryUpdater.prototype.destroy = function() { - var primitives = this._primitives; - primitives.removeAndDestroy(this._primitive); - primitives.removeAndDestroy(this._outlinePrimitive); - destroyObject(this); - }; + // Transform each camera direction to the fixed axes. + Matrix4.multiplyByPointAsVector(enuToFixed, r, r); + Matrix4.multiplyByPointAsVector(enuToFixed, u, u); + Matrix4.multiplyByPointAsVector(enuToFixed, d, d); - return WallGeometryUpdater; + // Compute the view matrix based on the new fixed-frame camera position and directions. + if (!defined(result)) { + result = new Matrix4(); + } + + result[0] = r.x; + result[1] = u.x; + result[2] = -d.x; + result[3] = 0.0; + result[4] = r.y; + result[5] = u.y; + result[6] = -d.y; + result[7] = 0.0; + result[8] = r.z; + result[9] = u.z; + result[10] = -d.z; + result[11] = 0.0; + result[12] = -Cartesian3.dot(r, position3D); + result[13] = -Cartesian3.dot(u, position3D); + result[14] = Cartesian3.dot(d, position3D); + result[15] = 1.0; + + return result; + } + + function updateView3D(that) { + if (that._view3DDirty) { + if (that._mode === SceneMode.SCENE3D) { + Matrix4.clone(that._view, that._view3D); + } else { + view2Dto3D(that._cameraPosition, that._cameraDirection, that._cameraRight, that._cameraUp, that._frustum2DWidth, that._mode, that._mapProjection, that._view3D); + } + Matrix4.getRotation(that._view3D, that._viewRotation3D); + that._view3DDirty = false; + } + } + + function updateInverseView3D(that){ + if (that._inverseView3DDirty) { + Matrix4.inverseTransformation(that.view3D, that._inverseView3D); + Matrix4.getRotation(that._inverseView3D, that._inverseViewRotation3D); + that._inverseView3DDirty = false; + } + } + + return UniformState; }); -define('DataSources/DataSourceDisplay',[ - '../Core/BoundingSphere', - '../Core/Check', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/EventHelper', - '../Scene/GroundPrimitive', - './BillboardVisualizer', - './BoundingSphereState', - './BoxGeometryUpdater', - './CorridorGeometryUpdater', - './CustomDataSource', - './CylinderGeometryUpdater', - './EllipseGeometryUpdater', - './EllipsoidGeometryUpdater', - './GeometryVisualizer', - './LabelVisualizer', - './ModelVisualizer', - './PathVisualizer', - './PlaneGeometryUpdater', - './PointVisualizer', - './PolygonGeometryUpdater', - './PolylineGeometryUpdater', - './PolylineVolumeGeometryUpdater', - './RectangleGeometryUpdater', - './WallGeometryUpdater' - ], function( - BoundingSphere, - Check, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - EventHelper, - GroundPrimitive, - BillboardVisualizer, - BoundingSphereState, - BoxGeometryUpdater, - CorridorGeometryUpdater, - CustomDataSource, - CylinderGeometryUpdater, - EllipseGeometryUpdater, - EllipsoidGeometryUpdater, - GeometryVisualizer, - LabelVisualizer, - ModelVisualizer, - PathVisualizer, - PlaneGeometryUpdater, - PointVisualizer, - PolygonGeometryUpdater, - PolylineGeometryUpdater, - PolylineVolumeGeometryUpdater, - RectangleGeometryUpdater, - WallGeometryUpdater) { +define('Renderer/Context',[ + '../Core/Check', + '../Core/clone', + '../Core/Color', + '../Core/ComponentDatatype', + '../Core/createGuid', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Geometry', + '../Core/GeometryAttribute', + '../Core/Matrix4', + '../Core/PrimitiveType', + '../Core/RuntimeError', + '../Core/WebGLConstants', + '../Shaders/ViewportQuadVS', + './BufferUsage', + './ClearCommand', + './ContextLimits', + './CubeMap', + './DrawCommand', + './PassState', + './PickFramebuffer', + './RenderState', + './ShaderCache', + './ShaderProgram', + './Texture', + './UniformState', + './VertexArray' +], function( + Check, + clone, + Color, + ComponentDatatype, + createGuid, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + Geometry, + GeometryAttribute, + Matrix4, + PrimitiveType, + RuntimeError, + WebGLConstants, + ViewportQuadVS, + BufferUsage, + ClearCommand, + ContextLimits, + CubeMap, + DrawCommand, + PassState, + PickFramebuffer, + RenderState, + ShaderCache, + ShaderProgram, + Texture, + UniformState, + VertexArray) { 'use strict'; + /*global WebGLRenderingContext*/ - /** - * Visualizes a collection of {@link DataSource} instances. - * @alias DataSourceDisplay - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Scene} options.scene The scene in which to display the data. - * @param {DataSourceCollection} options.dataSourceCollection The data sources to display. - * @param {DataSourceDisplay~VisualizersCallback} [options.visualizersCallback=DataSourceDisplay.defaultVisualizersCallback] - * A function which creates an array of visualizers used for visualization. - * If undefined, all standard visualizers are used. - */ - function DataSourceDisplay(options) { - Check.typeOf.object('options', options); - Check.typeOf.object('options.scene', options.scene); - Check.typeOf.object('options.dataSourceCollection', options.dataSourceCollection); - - GroundPrimitive.initializeTerrainHeights(); + /*global WebGL2RenderingContext*/ - var scene = options.scene; - var dataSourceCollection = options.dataSourceCollection; + function errorToString(gl, error) { + var message = 'WebGL Error: '; + switch (error) { + case gl.INVALID_ENUM: + message += 'INVALID_ENUM'; + break; + case gl.INVALID_VALUE: + message += 'INVALID_VALUE'; + break; + case gl.INVALID_OPERATION: + message += 'INVALID_OPERATION'; + break; + case gl.OUT_OF_MEMORY: + message += 'OUT_OF_MEMORY'; + break; + case gl.CONTEXT_LOST_WEBGL: + message += 'CONTEXT_LOST_WEBGL lost'; + break; + default: + message += 'Unknown (' + error + ')'; + } - this._eventHelper = new EventHelper(); - this._eventHelper.add(dataSourceCollection.dataSourceAdded, this._onDataSourceAdded, this); - this._eventHelper.add(dataSourceCollection.dataSourceRemoved, this._onDataSourceRemoved, this); + return message; + } - this._dataSourceCollection = dataSourceCollection; - this._scene = scene; - this._visualizersCallback = defaultValue(options.visualizersCallback, DataSourceDisplay.defaultVisualizersCallback); + function createErrorMessage(gl, glFunc, glFuncArguments, error) { + var message = errorToString(gl, error) + ': ' + glFunc.name + '('; - for (var i = 0, len = dataSourceCollection.length; i < len; i++) { - this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i)); + for (var i = 0; i < glFuncArguments.length; ++i) { + if (i !== 0) { + message += ', '; + } + message += glFuncArguments[i]; } + message += ');'; - var defaultDataSource = new CustomDataSource(); - this._onDataSourceAdded(undefined, defaultDataSource); - this._defaultDataSource = defaultDataSource; - - this._ready = false; + return message; } - /** - * Gets or sets the default function which creates an array of visualizers used for visualization. - * By default, this function uses all standard visualizers. - * - * @member - * @type {DataSourceDisplay~VisualizersCallback} - */ - DataSourceDisplay.defaultVisualizersCallback = function(scene, entityCluster, dataSource) { - var entities = dataSource.entities; - return [new BillboardVisualizer(entityCluster, entities), - new GeometryVisualizer(BoxGeometryUpdater, scene, entities), - new GeometryVisualizer(CylinderGeometryUpdater, scene, entities), - new GeometryVisualizer(CorridorGeometryUpdater, scene, entities), - new GeometryVisualizer(EllipseGeometryUpdater, scene, entities), - new GeometryVisualizer(EllipsoidGeometryUpdater, scene, entities), - new GeometryVisualizer(PlaneGeometryUpdater, scene, entities), - new GeometryVisualizer(PolygonGeometryUpdater, scene, entities), - new GeometryVisualizer(PolylineGeometryUpdater, scene, entities), - new GeometryVisualizer(PolylineVolumeGeometryUpdater, scene, entities), - new GeometryVisualizer(RectangleGeometryUpdater, scene, entities), - new GeometryVisualizer(WallGeometryUpdater, scene, entities), - new LabelVisualizer(entityCluster, entities), - new ModelVisualizer(scene, entities), - new PointVisualizer(entityCluster, entities), - new PathVisualizer(scene, entities)]; - }; + function throwOnError(gl, glFunc, glFuncArguments) { + var error = gl.getError(); + if (error !== gl.NO_ERROR) { + throw new RuntimeError(createErrorMessage(gl, glFunc, glFuncArguments, error)); + } + } - defineProperties(DataSourceDisplay.prototype, { - /** - * Gets the scene associated with this display. - * @memberof DataSourceDisplay.prototype - * @type {Scene} - */ - scene : { - get : function() { - return this._scene; - } - }, - /** - * Gets the collection of data sources to display. - * @memberof DataSourceDisplay.prototype - * @type {DataSourceCollection} - */ - dataSources : { - get : function() { - return this._dataSourceCollection; - } - }, - /** - * Gets the default data source instance which can be used to - * manually create and visualize entities not tied to - * a specific data source. This instance is always available - * and does not appear in the list dataSources collection. - * @memberof DataSourceDisplay.prototype - * @type {CustomDataSource} - */ - defaultDataSource : { + function makeGetterSetter(gl, propertyName, logFunction) { + return { get : function() { - return this._defaultDataSource; + var value = gl[propertyName]; + logFunction(gl, 'get: ' + propertyName, value); + return gl[propertyName]; + }, + set : function(value) { + gl[propertyName] = value; + logFunction(gl, 'set: ' + propertyName, value); } - }, + }; + } - /** - * Gets a value indicating whether or not all entities in the data source are ready - * @memberof DataSourceDisplay.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } + function wrapGL(gl, logFunction) { + if (!defined(logFunction)) { + return gl; } - }); - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see DataSourceDisplay#destroy - */ - DataSourceDisplay.prototype.isDestroyed = function() { - return false; - }; + function wrapFunction(property) { + return function() { + var result = property.apply(gl, arguments); + logFunction(gl, property, arguments); + return result; + }; + } - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * dataSourceDisplay = dataSourceDisplay.destroy(); - * - * @see DataSourceDisplay#isDestroyed - */ - DataSourceDisplay.prototype.destroy = function() { - this._eventHelper.removeAll(); + var glWrapper = {}; - var dataSourceCollection = this._dataSourceCollection; - for (var i = 0, length = dataSourceCollection.length; i < length; ++i) { - this._onDataSourceRemoved(this._dataSourceCollection, dataSourceCollection.get(i)); + // JavaScript linters normally demand that a for..in loop must directly contain an if, + // but in our loop below, we actually intend to iterate all properties, including + // those in the prototype. + /*eslint-disable guard-for-in*/ + for (var propertyName in gl) { + var property = gl[propertyName]; + + // wrap any functions we encounter, otherwise just copy the property to the wrapper. + if (property instanceof Function) { + glWrapper[propertyName] = wrapFunction(property); + } else { + Object.defineProperty(glWrapper, propertyName, makeGetterSetter(gl, propertyName, logFunction)); + } } - this._onDataSourceRemoved(undefined, this._defaultDataSource); + /*eslint-enable guard-for-in*/ - return destroyObject(this); - }; + return glWrapper; + } + + function getExtension(gl, names) { + var length = names.length; + for (var i = 0; i < length; ++i) { + var extension = gl.getExtension(names[i]); + if (extension) { + return extension; + } + } + + return undefined; + } /** - * Updates the display to the provided time. - * - * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if all data sources are ready to be displayed, false otherwise. + * @private */ - DataSourceDisplay.prototype.update = function(time) { - if (!defined(time)) { - throw new DeveloperError('time is required.'); + function Context(canvas, options) { + // this check must use typeof, not defined, because defined doesn't work with undeclared variables. + if (typeof WebGLRenderingContext === 'undefined') { + throw new RuntimeError('The browser does not support WebGL. Visit http://get.webgl.org.'); } + + Check.defined('canvas', canvas); - if (!GroundPrimitive._initialized) { - this._ready = false; - return false; - } + this._canvas = canvas; - var result = true; + options = clone(options, true); + options = defaultValue(options, {}); + options.allowTextureFilterAnisotropic = defaultValue(options.allowTextureFilterAnisotropic, true); + var webglOptions = defaultValue(options.webgl, {}); - var i; - var x; - var visualizers; - var vLength; - var dataSources = this._dataSourceCollection; - var length = dataSources.length; - for (i = 0; i < length; i++) { - var dataSource = dataSources.get(i); - if (defined(dataSource.update)) { - result = dataSource.update(time) && result; - } + // Override select WebGL defaults + webglOptions.alpha = defaultValue(webglOptions.alpha, false); // WebGL default is true + webglOptions.stencil = defaultValue(webglOptions.stencil, true); // WebGL default is false - visualizers = dataSource._visualizers; - vLength = visualizers.length; - for (x = 0; x < vLength; x++) { - result = visualizers[x].update(time) && result; + var requestWebgl2 = defaultValue(options.requestWebgl2, false) && (typeof WebGL2RenderingContext !== 'undefined'); + var webgl2 = false; + + var glContext; + var getWebGLStub = options.getWebGLStub; + + if (!defined(getWebGLStub)) { + if (requestWebgl2) { + glContext = canvas.getContext('webgl2', webglOptions) || canvas.getContext('experimental-webgl2', webglOptions) || undefined; + if (defined(glContext)) { + webgl2 = true; + } + } + if (!defined(glContext)) { + glContext = canvas.getContext('webgl', webglOptions) || canvas.getContext('experimental-webgl', webglOptions) || undefined; + } + if (!defined(glContext)) { + throw new RuntimeError('The browser supports WebGL, but initialization failed.'); } + } else { + // Use WebGL stub when requested for unit tests + glContext = getWebGLStub(canvas, webglOptions); } - visualizers = this._defaultDataSource._visualizers; - vLength = visualizers.length; - for (x = 0; x < vLength; x++) { - result = visualizers[x].update(time) && result; - } + this._originalGLContext = glContext; + this._gl = glContext; + this._webgl2 = webgl2; + this._id = createGuid(); - this._ready = result; + // Validation and logging disabled by default for speed. + this.validateFramebuffer = false; + this.validateShaderProgram = false; + this.logShaderCompilation = false; - return result; - }; + this._throwOnWebGLError = false; - var getBoundingSphereArrayScratch = []; - var getBoundingSphereBoundingSphereScratch = new BoundingSphere(); + this._shaderCache = new ShaderCache(this); - /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {Boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. - * If false, the the function will halt and return pending if any of the bounding spheres are pending. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private - */ - DataSourceDisplay.prototype.getBoundingSphere = function(entity, allowPartial, result) { - if (!defined(entity)) { - throw new DeveloperError('entity is required.'); - } - if (!defined(allowPartial)) { - throw new DeveloperError('allowPartial is required.'); - } - if (!defined(result)) { - throw new DeveloperError('result is required.'); - } - - if (!this._ready) { - return BoundingSphereState.PENDING; - } + var gl = glContext; - var i; - var length; - var dataSource = this._defaultDataSource; - if (!dataSource.entities.contains(entity)) { - dataSource = undefined; + this._stencilBits = gl.getParameter(gl.STENCIL_BITS); - var dataSources = this._dataSourceCollection; - length = dataSources.length; - for (i = 0; i < length; i++) { - var d = dataSources.get(i); - if (d.entities.contains(entity)) { - dataSource = d; - break; - } - } - } + ContextLimits._maximumCombinedTextureImageUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); // min: 8 + ContextLimits._maximumCubeMapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); // min: 16 + ContextLimits._maximumFragmentUniformVectors = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); // min: 16 + ContextLimits._maximumTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); // min: 8 + ContextLimits._maximumRenderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE); // min: 1 + ContextLimits._maximumTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); // min: 64 + ContextLimits._maximumVaryingVectors = gl.getParameter(gl.MAX_VARYING_VECTORS); // min: 8 + ContextLimits._maximumVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); // min: 8 + ContextLimits._maximumVertexTextureImageUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); // min: 0 + ContextLimits._maximumVertexUniformVectors = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); // min: 128 - if (!defined(dataSource)) { - return BoundingSphereState.FAILED; - } + var aliasedLineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE); // must include 1 + ContextLimits._minimumAliasedLineWidth = aliasedLineWidthRange[0]; + ContextLimits._maximumAliasedLineWidth = aliasedLineWidthRange[1]; - var boundingSpheres = getBoundingSphereArrayScratch; - var tmp = getBoundingSphereBoundingSphereScratch; + var aliasedPointSizeRange = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE); // must include 1 + ContextLimits._minimumAliasedPointSize = aliasedPointSizeRange[0]; + ContextLimits._maximumAliasedPointSize = aliasedPointSizeRange[1]; - var count = 0; - var state = BoundingSphereState.DONE; - var visualizers = dataSource._visualizers; - var visualizersLength = visualizers.length; + var maximumViewportDimensions = gl.getParameter(gl.MAX_VIEWPORT_DIMS); + ContextLimits._maximumViewportWidth = maximumViewportDimensions[0]; + ContextLimits._maximumViewportHeight = maximumViewportDimensions[1]; - for (i = 0; i < visualizersLength; i++) { - var visualizer = visualizers[i]; - if (defined(visualizer.getBoundingSphere)) { - state = visualizers[i].getBoundingSphere(entity, tmp); - if (!allowPartial && state === BoundingSphereState.PENDING) { - return BoundingSphereState.PENDING; - } else if (state === BoundingSphereState.DONE) { - boundingSpheres[count] = BoundingSphere.clone(tmp, boundingSpheres[count]); - count++; - } - } - } + var highpFloat = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); + ContextLimits._highpFloatSupported = highpFloat.precision !== 0; + var highpInt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT); + ContextLimits._highpIntSupported = highpInt.rangeMax !== 0; - if (count === 0) { - return BoundingSphereState.FAILED; - } + this._antialias = gl.getContextAttributes().antialias; - boundingSpheres.length = count; - BoundingSphere.fromBoundingSpheres(boundingSpheres, result); - return BoundingSphereState.DONE; - }; + // Query and initialize extensions + this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']); + this._blendMinmax = !!getExtension(gl, ['EXT_blend_minmax']); + this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']); + this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']); + this._textureFloat = !!getExtension(gl, ['OES_texture_float']); + this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']); + this._debugShaders = getExtension(gl, ['WEBGL_debug_shaders']); - DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource) { - var scene = this._scene; + this._colorBufferFloat = this._webgl2 && !!getExtension(gl, ['EXT_color_buffer_float']); - var entityCluster = dataSource.clustering; - entityCluster._initialize(scene); + this._s3tc = !!getExtension(gl, ['WEBGL_compressed_texture_s3tc', 'MOZ_WEBGL_compressed_texture_s3tc', 'WEBKIT_WEBGL_compressed_texture_s3tc']); + this._pvrtc = !!getExtension(gl, ['WEBGL_compressed_texture_pvrtc', 'WEBKIT_WEBGL_compressed_texture_pvrtc']); + this._etc1 = !!getExtension(gl, ['WEBGL_compressed_texture_etc1']); - scene.primitives.add(entityCluster); + var textureFilterAnisotropic = options.allowTextureFilterAnisotropic ? getExtension(gl, ['EXT_texture_filter_anisotropic', 'WEBKIT_EXT_texture_filter_anisotropic']) : undefined; + this._textureFilterAnisotropic = textureFilterAnisotropic; + ContextLimits._maximumTextureFilterAnisotropy = defined(textureFilterAnisotropic) ? gl.getParameter(textureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 1.0; - dataSource._visualizers = this._visualizersCallback(scene, entityCluster, dataSource); - }; + var glCreateVertexArray; + var glBindVertexArray; + var glDeleteVertexArray; - DataSourceDisplay.prototype._onDataSourceRemoved = function(dataSourceCollection, dataSource) { - var scene = this._scene; - var entityCluster = dataSource.clustering; - scene.primitives.remove(entityCluster); + var glDrawElementsInstanced; + var glDrawArraysInstanced; + var glVertexAttribDivisor; - var visualizers = dataSource._visualizers; - var length = visualizers.length; - for (var i = 0; i < length; i++) { - visualizers[i].destroy(); - } + var glDrawBuffers; - dataSource._visualizers = undefined; - }; + var vertexArrayObject; + var instancedArrays; + var drawBuffers; - /** - * A function which creates an array of visualizers used for visualization. - * @callback DataSourceDisplay~VisualizersCallback - * - * @param {Scene} scene The scene to create visualizers for. - * @param {DataSource} dataSource The data source to create visualizers for. - * @returns {Visualizer[]} An array of visualizers used for visualization. - * - * @example - * function createVisualizers(scene, dataSource) { - * return [new Cesium.BillboardVisualizer(scene, dataSource.entities)]; - * } - */ + if (webgl2) { + var that = this; - return DataSourceDisplay; -}); + glCreateVertexArray = function() { + return that._gl.createVertexArray(); + }; + glBindVertexArray = function(vao) { + that._gl.bindVertexArray(vao); + }; + glDeleteVertexArray = function(vao) { + that._gl.deleteVertexArray(vao); + }; -define('DataSources/DynamicGeometryUpdater',[ - '../Core/DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + glDrawElementsInstanced = function(mode, count, type, offset, instanceCount) { + gl.drawElementsInstanced(mode, count, type, offset, instanceCount); + }; + glDrawArraysInstanced = function(mode, first, count, instanceCount) { + gl.drawArraysInstanced(mode, first, count, instanceCount); + }; + glVertexAttribDivisor = function(index, divisor) { + gl.vertexAttribDivisor(index, divisor); + }; - /** - * Defines the interface for a dynamic geometry updater. A DynamicGeometryUpdater - * is responsible for handling visualization of a specific type of geometry - * that needs to be recomputed based on simulation time. - * This object is never used directly by client code, but is instead created by - * {@link GeometryUpdater} implementations which contain dynamic geometry. - * - * This type defines an interface and cannot be instantiated directly. - * - * @alias DynamicGeometryUpdater - * @constructor - */ - function DynamicGeometryUpdater() { - DeveloperError.throwInstantiationError(); - } + glDrawBuffers = function(buffers) { + gl.drawBuffers(buffers); + }; + } else { + vertexArrayObject = getExtension(gl, ['OES_vertex_array_object']); + if (defined(vertexArrayObject)) { + glCreateVertexArray = function() { + return vertexArrayObject.createVertexArrayOES(); + }; + glBindVertexArray = function(vertexArray) { + vertexArrayObject.bindVertexArrayOES(vertexArray); + }; + glDeleteVertexArray = function(vertexArray) { + vertexArrayObject.deleteVertexArrayOES(vertexArray); + }; + } - /** - * Updates the geometry to the specified time. - * @memberof DynamicGeometryUpdater - * @function - * - * @param {JulianDate} time The current time. - */ - DynamicGeometryUpdater.prototype.update = DeveloperError.throwInstantiationError; + instancedArrays = getExtension(gl, ['ANGLE_instanced_arrays']); + if (defined(instancedArrays)) { + glDrawElementsInstanced = function(mode, count, type, offset, instanceCount) { + instancedArrays.drawElementsInstancedANGLE(mode, count, type, offset, instanceCount); + }; + glDrawArraysInstanced = function(mode, first, count, instanceCount) { + instancedArrays.drawArraysInstancedANGLE(mode, first, count, instanceCount); + }; + glVertexAttribDivisor = function(index, divisor) { + instancedArrays.vertexAttribDivisorANGLE(index, divisor); + }; + } - /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. - * @function - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private - */ - DynamicGeometryUpdater.prototype.getBoundingSphere = DeveloperError.throwInstantiationError; + drawBuffers = getExtension(gl, ['WEBGL_draw_buffers']); + if (defined(drawBuffers)) { + glDrawBuffers = function(buffers) { + drawBuffers.drawBuffersWEBGL(buffers); + }; + } + } - /** - * Returns true if this object was destroyed; otherwise, false. - * @memberof DynamicGeometryUpdater - * @function - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - DynamicGeometryUpdater.prototype.isDestroyed = DeveloperError.throwInstantiationError; + this.glCreateVertexArray = glCreateVertexArray; + this.glBindVertexArray = glBindVertexArray; + this.glDeleteVertexArray = glDeleteVertexArray; - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * @memberof DynamicGeometryUpdater - * @function - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - DynamicGeometryUpdater.prototype.destroy = DeveloperError.throwInstantiationError; + this.glDrawElementsInstanced = glDrawElementsInstanced; + this.glDrawArraysInstanced = glDrawArraysInstanced; + this.glVertexAttribDivisor = glVertexAttribDivisor; - return DynamicGeometryUpdater; -}); + this.glDrawBuffers = glDrawBuffers; -define('DataSources/EntityView',[ - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/HeadingPitchRange', - '../Core/JulianDate', - '../Core/Math', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/Transforms', - '../Scene/SceneMode' - ], function( - Cartesian3, - defaultValue, - defined, - defineProperties, - DeveloperError, - Ellipsoid, - HeadingPitchRange, - JulianDate, - CesiumMath, - Matrix3, - Matrix4, - Transforms, - SceneMode) { - 'use strict'; + this._vertexArrayObject = !!vertexArrayObject; + this._instancedArrays = !!instancedArrays; + this._drawBuffers = !!drawBuffers; - var updateTransformMatrix3Scratch1 = new Matrix3(); - var updateTransformMatrix3Scratch2 = new Matrix3(); - var updateTransformMatrix3Scratch3 = new Matrix3(); - var updateTransformMatrix4Scratch = new Matrix4(); - var updateTransformCartesian3Scratch1 = new Cartesian3(); - var updateTransformCartesian3Scratch2 = new Cartesian3(); - var updateTransformCartesian3Scratch3 = new Cartesian3(); - var updateTransformCartesian3Scratch4 = new Cartesian3(); - var updateTransformCartesian3Scratch5 = new Cartesian3(); - var updateTransformCartesian3Scratch6 = new Cartesian3(); - var deltaTime = new JulianDate(); - var northUpAxisFactor = 1.25; // times ellipsoid's maximum radius + ContextLimits._maximumDrawBuffers = this.drawBuffers ? gl.getParameter(WebGLConstants.MAX_DRAW_BUFFERS) : 1; + ContextLimits._maximumColorAttachments = this.drawBuffers ? gl.getParameter(WebGLConstants.MAX_COLOR_ATTACHMENTS) : 1; - function updateTransform(that, camera, updateLookAt, saveCamera, positionProperty, time, ellipsoid) { - var mode = that.scene.mode; - var cartesian = positionProperty.getValue(time, that._lastCartesian); - if (defined(cartesian)) { - var hasBasis = false; - var invertVelocity = false; - var xBasis; - var yBasis; - var zBasis; + this._clearColor = new Color(0.0, 0.0, 0.0, 0.0); + this._clearDepth = 1.0; + this._clearStencil = 0; - if (mode === SceneMode.SCENE3D) { - // The time delta was determined based on how fast satellites move compared to vehicles near the surface. - // Slower moving vehicles will most likely default to east-north-up, while faster ones will be VVLH. - JulianDate.addSeconds(time, 0.001, deltaTime); - var deltaCartesian = positionProperty.getValue(deltaTime, updateTransformCartesian3Scratch1); + var us = new UniformState(); + var ps = new PassState(this); + var rs = RenderState.fromCache(); - // If no valid position at (time + 0.001), sample at (time - 0.001) and invert the vector - if (!defined(deltaCartesian)) { - JulianDate.addSeconds(time, -0.001, deltaTime); - deltaCartesian = positionProperty.getValue(deltaTime, updateTransformCartesian3Scratch1); - invertVelocity = true; - } + this._defaultPassState = ps; + this._defaultRenderState = rs; + this._defaultTexture = undefined; + this._defaultCubeMap = undefined; - if (defined(deltaCartesian)) { - var toInertial = Transforms.computeFixedToIcrfMatrix(time, updateTransformMatrix3Scratch1); - var toInertialDelta = Transforms.computeFixedToIcrfMatrix(deltaTime, updateTransformMatrix3Scratch2); - var toFixed; + this._us = us; + this._currentRenderState = rs; + this._currentPassState = ps; + this._currentFramebuffer = undefined; + this._maxFrameTextureUnitIndex = 0; - if (!defined(toInertial) || !defined(toInertialDelta)) { - toFixed = Transforms.computeTemeToPseudoFixedMatrix(time, updateTransformMatrix3Scratch3); - toInertial = Matrix3.transpose(toFixed, updateTransformMatrix3Scratch1); - toInertialDelta = Transforms.computeTemeToPseudoFixedMatrix(deltaTime, updateTransformMatrix3Scratch2); - Matrix3.transpose(toInertialDelta, toInertialDelta); - } else { - toFixed = Matrix3.transpose(toInertial, updateTransformMatrix3Scratch3); - } + // Vertex attribute divisor state cache. Workaround for ANGLE (also look at VertexArray.setVertexAttribDivisor) + this._vertexAttribDivisors = []; + this._previousDrawInstanced = false; + for (var i = 0; i < ContextLimits._maximumVertexAttributes; i++) { + this._vertexAttribDivisors.push(0); + } - var inertialCartesian = Matrix3.multiplyByVector(toInertial, cartesian, updateTransformCartesian3Scratch5); - var inertialDeltaCartesian = Matrix3.multiplyByVector(toInertialDelta, deltaCartesian, updateTransformCartesian3Scratch6); + this._pickObjects = {}; + this._nextPickColor = new Uint32Array(1); - Cartesian3.subtract(inertialCartesian, inertialDeltaCartesian, updateTransformCartesian3Scratch4); - var inertialVelocity = Cartesian3.magnitude(updateTransformCartesian3Scratch4) * 1000.0; // meters/sec + /** + * @example + * { + * webgl : { + * alpha : false, + * depth : true, + * stencil : false, + * antialias : true, + * premultipliedAlpha : true, + * preserveDrawingBuffer : false, + * failIfMajorPerformanceCaveat : true + * }, + * allowTextureFilterAnisotropic : true + * } + */ + this.options = options; - // http://en.wikipedia.org/wiki/Standard_gravitational_parameter - // Consider adding this to Cesium.Ellipsoid? - var mu = 3.986004418e14; // m^3 / sec^2 + /** + * A cache of objects tied to this context. Just before the Context is destroyed, + * <code>destroy</code> will be invoked on each object in this object literal that has + * such a method. This is useful for caching any objects that might otherwise + * be stored globally, except they're tied to a particular context, and to manage + * their lifetime. + * + * @type {Object} + */ + this.cache = {}; - var semiMajorAxis = -mu / (inertialVelocity * inertialVelocity - (2 * mu / Cartesian3.magnitude(inertialCartesian))); + RenderState.apply(gl, rs, ps); + } - if (semiMajorAxis < 0 || semiMajorAxis > northUpAxisFactor * ellipsoid.maximumRadius) { - // North-up viewing from deep space. + var defaultFramebufferMarker = {}; - // X along the nadir - xBasis = updateTransformCartesian3Scratch2; - Cartesian3.normalize(cartesian, xBasis); - Cartesian3.negate(xBasis, xBasis); + defineProperties(Context.prototype, { + id : { + get : function() { + return this._id; + } + }, + webgl2 : { + get : function() { + return this._webgl2; + } + }, + canvas : { + get : function() { + return this._canvas; + } + }, + shaderCache : { + get : function() { + return this._shaderCache; + } + }, + uniformState : { + get : function() { + return this._us; + } + }, - // Z is North - zBasis = Cartesian3.clone(Cartesian3.UNIT_Z, updateTransformCartesian3Scratch3); + /** + * The number of stencil bits per pixel in the default bound framebuffer. The minimum is eight bits. + * @memberof Context.prototype + * @type {Number} + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>STENCIL_BITS</code>. + */ + stencilBits : { + get : function() { + return this._stencilBits; + } + }, - // Y is along the cross of z and x (right handed basis / in the direction of motion) - yBasis = Cartesian3.cross(zBasis, xBasis, updateTransformCartesian3Scratch1); - if (Cartesian3.magnitude(yBasis) > CesiumMath.EPSILON7) { - Cartesian3.normalize(xBasis, xBasis); - Cartesian3.normalize(yBasis, yBasis); + /** + * <code>true</code> if the WebGL context supports stencil buffers. + * Stencil buffers are not supported by all systems. + * @memberof Context.prototype + * @type {Boolean} + */ + stencilBuffer : { + get : function() { + return this._stencilBits >= 8; + } + }, - zBasis = Cartesian3.cross(xBasis, yBasis, updateTransformCartesian3Scratch3); - Cartesian3.normalize(zBasis, zBasis); + /** + * <code>true</code> if the WebGL context supports antialiasing. By default + * antialiasing is requested, but it is not supported by all systems. + * @memberof Context.prototype + * @type {Boolean} + */ + antialias : { + get : function() { + return this._antialias; + } + }, - hasBasis = true; - } - } else if (!Cartesian3.equalsEpsilon(cartesian, deltaCartesian, CesiumMath.EPSILON7)) { - // Approximation of VVLH (Vehicle Velocity Local Horizontal) with the Z-axis flipped. + /** + * <code>true</code> if the OES_standard_derivatives extension is supported. This + * extension provides access to <code>dFdx</code>, <code>dFdy</code>, and <code>fwidth</code> + * functions from GLSL. A shader using these functions still needs to explicitly enable the + * extension with <code>#extension GL_OES_standard_derivatives : enable</code>. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/gles/extensions/OES/OES_standard_derivatives.txt|OES_standard_derivatives} + */ + standardDerivatives : { + get : function() { + return this._standardDerivatives || this._webgl2; + } + }, - // Z along the position - zBasis = updateTransformCartesian3Scratch2; - Cartesian3.normalize(inertialCartesian, zBasis); - Cartesian3.normalize(inertialDeltaCartesian, inertialDeltaCartesian); + /** + * <code>true</code> if the EXT_blend_minmax extension is supported. This + * extension extends blending capabilities by adding two new blend equations: + * the minimum or maximum color components of the source and destination colors. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/} + */ + blendMinmax : { + get : function() { + return this._blendMinmax || this._webgl2; + } + }, - // Y is along the angular momentum vector (e.g. "orbit normal") - yBasis = Cartesian3.cross(zBasis, inertialDeltaCartesian, updateTransformCartesian3Scratch3); + /** + * <code>true</code> if the OES_element_index_uint extension is supported. This + * extension allows the use of unsigned int indices, which can improve performance by + * eliminating batch breaking caused by unsigned short indices. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/|OES_element_index_uint} + */ + elementIndexUint : { + get : function() { + return this._elementIndexUint || this._webgl2; + } + }, - if(invertVelocity) { - yBasis = Cartesian3.multiplyByScalar(yBasis, -1, yBasis); - } + /** + * <code>true</code> if WEBGL_depth_texture is supported. This extension provides + * access to depth textures that, for example, can be attached to framebuffers for shadow mapping. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} + */ + depthTexture : { + get : function() { + return this._depthTexture || this._webgl2; + } + }, - if (!Cartesian3.equalsEpsilon(yBasis, Cartesian3.ZERO, CesiumMath.EPSILON7)) { - // X is along the cross of y and z (right handed basis / in the direction of motion) - xBasis = Cartesian3.cross(yBasis, zBasis, updateTransformCartesian3Scratch1); + /** + * <code>true</code> if OES_texture_float is supported. This extension provides + * access to floating point textures that, for example, can be attached to framebuffers for high dynamic range. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/gles/extensions/OES/OES_texture_float.txt|OES_texture_float} + */ + floatingPointTexture : { + get : function() { + return this._textureFloat || this._colorBufferFloat; + } + }, - Matrix3.multiplyByVector(toFixed, xBasis, xBasis); - Matrix3.multiplyByVector(toFixed, yBasis, yBasis); - Matrix3.multiplyByVector(toFixed, zBasis, zBasis); + textureFilterAnisotropic : { + get : function() { + return !!this._textureFilterAnisotropic; + } + }, - Cartesian3.normalize(xBasis, xBasis); - Cartesian3.normalize(yBasis, yBasis); - Cartesian3.normalize(zBasis, zBasis); + /** + * <code>true</code> if WEBGL_texture_compression_s3tc is supported. This extension provides + * access to DXT compressed textures. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/} + */ + s3tc : { + get : function() { + return this._s3tc; + } + }, - hasBasis = true; - } - } - } + /** + * <code>true</code> if WEBGL_texture_compression_pvrtc is supported. This extension provides + * access to PVR compressed textures. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/} + */ + pvrtc : { + get : function() { + return this._pvrtc; } + }, - if (defined(that.boundingSphere)) { - cartesian = that.boundingSphere.center; + /** + * <code>true</code> if WEBGL_texture_compression_etc1 is supported. This extension provides + * access to ETC1 compressed textures. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/} + */ + etc1 : { + get : function() { + return this._etc1; } + }, - var position; - var direction; - var up; + /** + * <code>true</code> if the OES_vertex_array_object extension is supported. This + * extension can improve performance by reducing the overhead of switching vertex arrays. + * When enabled, this extension is automatically used by {@link VertexArray}. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/|OES_vertex_array_object} + */ + vertexArrayObject : { + get : function() { + return this._vertexArrayObject || this._webgl2; + } + }, - if (saveCamera) { - position = Cartesian3.clone(camera.position, updateTransformCartesian3Scratch4); - direction = Cartesian3.clone(camera.direction, updateTransformCartesian3Scratch5); - up = Cartesian3.clone(camera.up, updateTransformCartesian3Scratch6); + /** + * <code>true</code> if the EXT_frag_depth extension is supported. This + * extension provides access to the <code>gl_FragDepthEXT</code> built-in output variable + * from GLSL fragment shaders. A shader using these functions still needs to explicitly enable the + * extension with <code>#extension GL_EXT_frag_depth : enable</code>. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/|EXT_frag_depth} + */ + fragmentDepth : { + get : function() { + return this._fragDepth || this._webgl2; } + }, - var transform = updateTransformMatrix4Scratch; - if (hasBasis) { - transform[0] = xBasis.x; - transform[1] = xBasis.y; - transform[2] = xBasis.z; - transform[3] = 0.0; - transform[4] = yBasis.x; - transform[5] = yBasis.y; - transform[6] = yBasis.z; - transform[7] = 0.0; - transform[8] = zBasis.x; - transform[9] = zBasis.y; - transform[10] = zBasis.z; - transform[11] = 0.0; - transform[12] = cartesian.x; - transform[13] = cartesian.y; - transform[14] = cartesian.z; - transform[15] = 0.0; - } else { - // Stationary or slow-moving, low-altitude objects use East-North-Up. - Transforms.eastNorthUpToFixedFrame(cartesian, ellipsoid, transform); + /** + * <code>true</code> if the ANGLE_instanced_arrays extension is supported. This + * extension provides access to instanced rendering. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays} + */ + instancedArrays : { + get : function() { + return this._instancedArrays || this._webgl2; + } + }, + + /** + * <code>true</code> if the EXT_color_buffer_float extension is supported. This + * extension makes the formats gl.R16F, gl.RG16F, gl.RGBA16F, gl.R32F, gl.RG32F, + * gl.RGBA32F, gl.R11F_G11F_B10F color renderable. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/} + */ + colorBufferFloat : { + get : function() { + return this._colorBufferFloat; } + }, - camera._setTransform(transform); - - if (saveCamera) { - Cartesian3.clone(position, camera.position); - Cartesian3.clone(direction, camera.direction); - Cartesian3.clone(up, camera.up); - Cartesian3.cross(direction, up, camera.right); + /** + * <code>true</code> if the WEBGL_draw_buffers extension is supported. This + * extensions provides support for multiple render targets. The framebuffer object can have mutiple + * color attachments and the GLSL fragment shader can write to the built-in output array <code>gl_FragData</code>. + * A shader using this feature needs to explicitly enable the extension with + * <code>#extension GL_EXT_draw_buffers : enable</code>. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_draw_buffers/|WEBGL_draw_buffers} + */ + drawBuffers : { + get : function() { + return this._drawBuffers || this._webgl2; } - } + }, - if (updateLookAt) { - var offset = (mode === SceneMode.SCENE2D || Cartesian3.equals(that._offset3D, Cartesian3.ZERO)) ? undefined : that._offset3D; - camera.lookAtTransform(camera.transform, offset); - } - } + debugShaders : { + get : function() { + return this._debugShaders; + } + }, - /** - * A utility object for tracking an entity with the camera. - * @alias EntityView - * @constructor - * - * @param {Entity} entity The entity to track with the camera. - * @param {Scene} scene The scene to use. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use for orienting the camera. - */ - function EntityView(entity, scene, ellipsoid) { + throwOnWebGLError : { + get : function() { + return this._throwOnWebGLError; + }, + set : function(value) { + this._throwOnWebGLError = value; + this._gl = wrapGL(this._originalGLContext, value ? throwOnError : undefined); + } + }, /** - * The entity to track with the camera. - * @type {Entity} + * A 1x1 RGBA texture initialized to [255, 255, 255, 255]. This can + * be used as a placeholder texture while other textures are downloaded. + * @memberof Context.prototype + * @type {Texture} */ - this.entity = entity; + defaultTexture : { + get : function() { + if (this._defaultTexture === undefined) { + this._defaultTexture = new Texture({ + context : this, + source : { + width : 1, + height : 1, + arrayBufferView : new Uint8Array([255, 255, 255, 255]) + } + }); + } + + return this._defaultTexture; + } + }, /** - * The scene in which to track the object. - * @type {Scene} + * A cube map, where each face is a 1x1 RGBA texture initialized to + * [255, 255, 255, 255]. This can be used as a placeholder cube map while + * other cube maps are downloaded. + * @memberof Context.prototype + * @type {CubeMap} */ - this.scene = scene; + defaultCubeMap : { + get : function() { + if (this._defaultCubeMap === undefined) { + var face = { + width : 1, + height : 1, + arrayBufferView : new Uint8Array([255, 255, 255, 255]) + }; + + this._defaultCubeMap = new CubeMap({ + context : this, + source : { + positiveX : face, + negativeX : face, + positiveY : face, + negativeY : face, + positiveZ : face, + negativeZ : face + } + }); + } + + return this._defaultCubeMap; + + } + }, /** - * The ellipsoid to use for orienting the camera. - * @type {Ellipsoid} + * The drawingBufferHeight of the underlying GL context. + * @memberof Context.prototype + * @type {Number} + * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} */ - this.ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + drawingBufferHeight : { + get : function() { + return this._gl.drawingBufferHeight; + } + }, /** - * The bounding sphere of the object. - * @type {BoundingSphere} + * The drawingBufferWidth of the underlying GL context. + * @memberof Context.prototype + * @type {Number} + * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferWidth|drawingBufferWidth} */ - this.boundingSphere = undefined; - - //Shadow copies of the objects so we can detect changes. - this._lastEntity = undefined; - this._mode = undefined; - - this._lastCartesian = new Cartesian3(); - this._defaultOffset3D = undefined; - - this._offset3D = new Cartesian3(); - } + drawingBufferWidth : { + get : function() { + return this._gl.drawingBufferWidth; + } + }, - // STATIC properties defined here, not per-instance. - defineProperties(EntityView, { /** - * Gets or sets a camera offset that will be used to - * initialize subsequent EntityViews. - * @memberof EntityView - * @type {Cartesian3} + * Gets an object representing the currently bound framebuffer. While this instance is not an actual + * {@link Framebuffer}, it is used to represent the default framebuffer in calls to + * {@link Texture.FromFramebuffer}. + * @memberof Context.prototype + * @type {Object} */ - defaultOffset3D : { + defaultFramebuffer : { get : function() { - return this._defaultOffset3D; - }, - set : function(vector) { - this._defaultOffset3D = Cartesian3.clone(vector, new Cartesian3()); + return defaultFramebufferMarker; } } }); - // Initialize the static property. - EntityView.defaultOffset3D = new Cartesian3(-14000, 3500, 3500); + /** + * Validates a framebuffer. + * Available in debug builds only. + * @private + */ + function validateFramebuffer(context) { + if (context.validateFramebuffer) { + var gl = context._gl; + var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); - var scratchHeadingPitchRange = new HeadingPitchRange(); - var scratchCartesian = new Cartesian3(); + if (status !== gl.FRAMEBUFFER_COMPLETE) { + var message; - /** - * Should be called each animation frame to update the camera - * to the latest settings. - * @param {JulianDate} time The current animation time. - * @param {BoundingSphere} boundingSphere bounding sphere of the object. - * - */ - EntityView.prototype.update = function(time, boundingSphere) { - var scene = this.scene; - var entity = this.entity; - var ellipsoid = this.ellipsoid; + switch (status) { + case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + message = 'Framebuffer is not complete. Incomplete attachment: at least one attachment point with a renderbuffer or texture attached has its attached object no longer in existence or has an attached image with a width or height of zero, or the color attachment point has a non-color-renderable image attached, or the depth attachment point has a non-depth-renderable image attached, or the stencil attachment point has a non-stencil-renderable image attached. Color-renderable formats include GL_RGBA4, GL_RGB5_A1, and GL_RGB565. GL_DEPTH_COMPONENT16 is the only depth-renderable format. GL_STENCIL_INDEX8 is the only stencil-renderable format.'; + break; + case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + message = 'Framebuffer is not complete. Incomplete dimensions: not all attached images have the same width and height.'; + break; + case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + message = 'Framebuffer is not complete. Missing attachment: no images are attached to the framebuffer.'; + break; + case gl.FRAMEBUFFER_UNSUPPORTED: + message = 'Framebuffer is not complete. Unsupported: the combination of internal formats of the attached images violates an implementation-dependent set of restrictions.'; + break; + } - if (!defined(time)) { - throw new DeveloperError('time is required.'); - } - if (!defined(scene)) { - throw new DeveloperError('EntityView.scene is required.'); - } - if (!defined(entity)) { - throw new DeveloperError('EntityView.entity is required.'); - } - if (!defined(ellipsoid)) { - throw new DeveloperError('EntityView.ellipsoid is required.'); - } - if (!defined(entity.position)) { - throw new DeveloperError('entity.position is required.'); - } - - var sceneMode = scene.mode; - if (sceneMode === SceneMode.MORPHING) { - return; + throw new DeveloperError(message); + } } + } - var positionProperty = entity.position; - var objectChanged = entity !== this._lastEntity; - var sceneModeChanged = sceneMode !== this._mode; + function applyRenderState(context, renderState, passState, clear) { + var previousRenderState = context._currentRenderState; + var previousPassState = context._currentPassState; + context._currentRenderState = renderState; + context._currentPassState = passState; + RenderState.partialApply(context._gl, previousRenderState, renderState, previousPassState, passState, clear); + } - var offset3D = this._offset3D; - var camera = scene.camera; + var scratchBackBufferArray; + // this check must use typeof, not defined, because defined doesn't work with undeclared variables. + if (typeof WebGLRenderingContext !== 'undefined') { + scratchBackBufferArray = [WebGLConstants.BACK]; + } - var updateLookAt = objectChanged || sceneModeChanged; - var saveCamera = true; + function bindFramebuffer(context, framebuffer) { + if (framebuffer !== context._currentFramebuffer) { + context._currentFramebuffer = framebuffer; + var buffers = scratchBackBufferArray; - if (objectChanged) { - var viewFromProperty = entity.viewFrom; - var hasViewFrom = defined(viewFromProperty); + if (defined(framebuffer)) { + framebuffer._bind(); + validateFramebuffer(context); - if (!hasViewFrom && defined(boundingSphere)) { - //The default HPR is not ideal for high altitude objects so - //we scale the pitch as we get further from the earth for a more - //downward view. - scratchHeadingPitchRange.pitch = -CesiumMath.PI_OVER_FOUR; - scratchHeadingPitchRange.range = 0; - var position = positionProperty.getValue(time, scratchCartesian); - if (defined(position)) { - var factor = 2 - 1 / Math.max(1, Cartesian3.magnitude(position) / ellipsoid.maximumRadius); - scratchHeadingPitchRange.pitch *= factor; - } + // TODO: Need a way for a command to give what draw buffers are active. + buffers = framebuffer._getActiveColorAttachments(); + } else { + var gl = context._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } - camera.viewBoundingSphere(boundingSphere, scratchHeadingPitchRange); - this.boundingSphere = boundingSphere; - updateLookAt = false; - saveCamera = false; - } else if (!hasViewFrom || !defined(viewFromProperty.getValue(time, offset3D))) { - Cartesian3.clone(EntityView._defaultOffset3D, offset3D); + if (context.drawBuffers) { + context.glDrawBuffers(buffers); } - } else if (!sceneModeChanged && scene.mode !== SceneMode.MORPHING && this._mode !== SceneMode.SCENE2D) { - Cartesian3.clone(camera.position, offset3D); } + } - this._lastEntity = entity; - this._mode = scene.mode !== SceneMode.MORPHING ? scene.mode : this._mode; + var defaultClearCommand = new ClearCommand(); - if (scene.mode !== SceneMode.MORPHING) { - updateTransform(this, camera, updateLookAt, saveCamera, positionProperty, time, ellipsoid); - } - }; + Context.prototype.clear = function(clearCommand, passState) { + clearCommand = defaultValue(clearCommand, defaultClearCommand); + passState = defaultValue(passState, this._defaultPassState); - return EntityView; -}); + var gl = this._gl; + var bitmask = 0; -/** -@license -topojson - https://github.com/mbostock/topojson + var c = clearCommand.color; + var d = clearCommand.depth; + var s = clearCommand.stencil; -Copyright (c) 2012, Michael Bostock -All rights reserved. + if (defined(c)) { + if (!Color.equals(this._clearColor, c)) { + Color.clone(c, this._clearColor); + gl.clearColor(c.red, c.green, c.blue, c.alpha); + } + bitmask |= gl.COLOR_BUFFER_BIT; + } -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: + if (defined(d)) { + if (d !== this._clearDepth) { + this._clearDepth = d; + gl.clearDepth(d); + } + bitmask |= gl.DEPTH_BUFFER_BIT; + } -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + if (defined(s)) { + if (s !== this._clearStencil) { + this._clearStencil = s; + gl.clearStencil(s); + } + bitmask |= gl.STENCIL_BUFFER_BIT; + } -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + var rs = defaultValue(clearCommand.renderState, this._defaultRenderState); + applyRenderState(this, rs, passState, true); -* The name Michael Bostock may not be used to endorse or promote products - derived from this software without specific prior written permission. + // The command's framebuffer takes presidence over the pass' framebuffer, e.g., for off-screen rendering. + var framebuffer = defaultValue(clearCommand.framebuffer, passState.framebuffer); + bindFramebuffer(this, framebuffer); -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + gl.clear(bitmask); + }; -!function() { - var topojson = { - version: "1.6.18", - mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); }, - meshArcs: meshArcs, - merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); }, - mergeArcs: mergeArcs, - feature: featureOrCollection, - neighbors: neighbors, - presimplify: presimplify - }; + function beginDraw(context, framebuffer, drawCommand, passState) { + var rs = defaultValue(drawCommand._renderState, context._defaultRenderState); - function stitchArcs(topology, arcs) { - var stitchedArcs = {}, - fragmentByStart = {}, - fragmentByEnd = {}, - fragments = [], - emptyIndex = -1; + if (defined(framebuffer) && rs.depthTest) { + if (rs.depthTest.enabled && !framebuffer.hasDepthAttachment) { + throw new DeveloperError('The depth test can not be enabled (drawCommand.renderState.depthTest.enabled) because the framebuffer (drawCommand.framebuffer) does not have a depth or depth-stencil renderbuffer.'); + } + } + + bindFramebuffer(context, framebuffer); - // Stitch empty arcs first, since they may be subsumed by other arcs. - arcs.forEach(function(i, j) { - var arc = topology.arcs[i < 0 ? ~i : i], t; - if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { - t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; - } - }); + applyRenderState(context, rs, passState, false); - arcs.forEach(function(i) { - var e = ends(i), - start = e[0], - end = e[1], - f, g; + var sp = drawCommand._shaderProgram; + sp._bind(); + context._maxFrameTextureUnitIndex = Math.max(context._maxFrameTextureUnitIndex, sp.maximumTextureUnitIndex); + } - if (f = fragmentByEnd[start]) { - delete fragmentByEnd[f.end]; - f.push(i); - f.end = end; - if (g = fragmentByStart[end]) { - delete fragmentByStart[g.start]; - var fg = g === f ? f : f.concat(g); - fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; - } else { - fragmentByStart[f.start] = fragmentByEnd[f.end] = f; + function continueDraw(context, drawCommand) { + var primitiveType = drawCommand._primitiveType; + var va = drawCommand._vertexArray; + var offset = drawCommand._offset; + var count = drawCommand._count; + var instanceCount = drawCommand.instanceCount; + + if (!PrimitiveType.validate(primitiveType)) { + throw new DeveloperError('drawCommand.primitiveType is required and must be valid.'); } - } else if (f = fragmentByStart[end]) { - delete fragmentByStart[f.start]; - f.unshift(i); - f.start = start; - if (g = fragmentByEnd[start]) { - delete fragmentByEnd[g.end]; - var gf = g === f ? f : g.concat(f); - fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; + + Check.defined('drawCommand.vertexArray', va); + Check.typeOf.number.greaterThanOrEquals('drawCommand.offset', offset, 0); + if (defined(count)) { + Check.typeOf.number.greaterThanOrEquals('drawCommand.count', count, 0); + } + Check.typeOf.number.greaterThanOrEquals('drawCommand.instanceCount', instanceCount, 0); + if (instanceCount > 0 && !context.instancedArrays) { + throw new DeveloperError('Instanced arrays extension is not supported'); + } + + context._us.model = defaultValue(drawCommand._modelMatrix, Matrix4.IDENTITY); + drawCommand._shaderProgram._setUniforms(drawCommand._uniformMap, context._us, context.validateShaderProgram); + + va._bind(); + var indexBuffer = va.indexBuffer; + + if (defined(indexBuffer)) { + offset = offset * indexBuffer.bytesPerIndex; // offset in vertices to offset in bytes + count = defaultValue(count, indexBuffer.numberOfIndices); + if (instanceCount === 0) { + context._gl.drawElements(primitiveType, count, indexBuffer.indexDatatype, offset); + } else { + context.glDrawElementsInstanced(primitiveType, count, indexBuffer.indexDatatype, offset, instanceCount); + } } else { - fragmentByStart[f.start] = fragmentByEnd[f.end] = f; + count = defaultValue(count, va.numberOfVertices); + if (instanceCount === 0) { + context._gl.drawArrays(primitiveType, offset, count); + } else { + context.glDrawArraysInstanced(primitiveType, offset, count, instanceCount); + } } - } else { - f = [i]; - fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; - } - }); - function ends(i) { - var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; - if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); - else p1 = arc[arc.length - 1]; - return i < 0 ? [p1, p0] : [p0, p1]; + va._unBind(); } - function flush(fragmentByEnd, fragmentByStart) { - for (var k in fragmentByEnd) { - var f = fragmentByEnd[k]; - delete fragmentByStart[f.start]; - delete f.start; - delete f.end; - f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); - fragments.push(f); - } - } + Context.prototype.draw = function(drawCommand, passState) { + Check.defined('drawCommand', drawCommand); + Check.defined('drawCommand.shaderProgram', drawCommand._shaderProgram); + + passState = defaultValue(passState, this._defaultPassState); + // The command's framebuffer takes presidence over the pass' framebuffer, e.g., for off-screen rendering. + var framebuffer = defaultValue(drawCommand._framebuffer, passState.framebuffer); - flush(fragmentByEnd, fragmentByStart); - flush(fragmentByStart, fragmentByEnd); - arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); + beginDraw(this, framebuffer, drawCommand, passState); + continueDraw(this, drawCommand); + }; - return fragments; - } + Context.prototype.endFrame = function() { + var gl = this._gl; + gl.useProgram(null); - function meshArcs(topology, o, filter) { - var arcs = []; + this._currentFramebuffer = undefined; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); - if (arguments.length > 1) { - var geomsByArc = [], - geom; + var buffers = scratchBackBufferArray; + if (this.drawBuffers) { + this.glDrawBuffers(buffers); + } - function arc(i) { - var j = i < 0 ? ~i : i; - (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); - } + var length = this._maxFrameTextureUnitIndex; + this._maxFrameTextureUnitIndex = 0; - function line(arcs) { - arcs.forEach(arc); - } + for (var i = 0; i < length; ++i) { + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, null); + } + }; - function polygon(arcs) { - arcs.forEach(line); - } + Context.prototype.readPixels = function(readState) { + var gl = this._gl; - function geometry(o) { - if (o.type === "GeometryCollection") o.geometries.forEach(geometry); - else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); - } + readState = readState || {}; + var x = Math.max(readState.x || 0, 0); + var y = Math.max(readState.y || 0, 0); + var width = readState.width || gl.drawingBufferWidth; + var height = readState.height || gl.drawingBufferHeight; + var framebuffer = readState.framebuffer; - var geometryType = { - LineString: line, - MultiLineString: polygon, - Polygon: polygon, - MultiPolygon: function(arcs) { arcs.forEach(polygon); } - }; + Check.typeOf.number.greaterThan('readState.width', width, 0); + Check.typeOf.number.greaterThan('readState.height', height, 0); + + var pixels = new Uint8Array(4 * width * height); - geometry(o); + bindFramebuffer(this, framebuffer); - geomsByArc.forEach(arguments.length < 3 - ? function(geoms) { arcs.push(geoms[0].i); } - : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); - } else { - for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); - } + gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; - } + return pixels; + }; - function mergeArcs(topology, objects) { - var polygonsByArc = {}, - polygons = [], - components = []; + var viewportQuadAttributeLocations = { + position : 0, + textureCoordinates : 1 + }; - objects.forEach(function(o) { - if (o.type === "Polygon") register(o.arcs); - else if (o.type === "MultiPolygon") o.arcs.forEach(register); - }); + Context.prototype.getViewportQuadVertexArray = function() { + // Per-context cache for viewport quads + var vertexArray = this.cache.viewportQuad_vertexArray; - function register(polygon) { - polygon.forEach(function(ring) { - ring.forEach(function(arc) { - (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); - }); - }); - polygons.push(polygon); - } + if (!defined(vertexArray)) { + var geometry = new Geometry({ + attributes : { + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : [ + -1.0, -1.0, + 1.0, -1.0, + 1.0, 1.0, + -1.0, 1.0 + ] + }), - function exterior(ring) { - return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? - } + textureCoordinates : new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : [ + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0 + ] + }) + }, + // Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN + indices : new Uint16Array([0, 1, 2, 0, 2, 3]), + primitiveType : PrimitiveType.TRIANGLES + }); - polygons.forEach(function(polygon) { - if (!polygon._) { - var component = [], - neighbors = [polygon]; - polygon._ = 1; - components.push(component); - while (polygon = neighbors.pop()) { - component.push(polygon); - polygon.forEach(function(ring) { - ring.forEach(function(arc) { - polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { - if (!polygon._) { - polygon._ = 1; - neighbors.push(polygon); - } - }); + vertexArray = VertexArray.fromGeometry({ + context : this, + geometry : geometry, + attributeLocations : viewportQuadAttributeLocations, + bufferUsage : BufferUsage.STATIC_DRAW, + interleave : true }); - }); + + this.cache.viewportQuad_vertexArray = vertexArray; } - } - }); - polygons.forEach(function(polygon) { - delete polygon._; - }); + return vertexArray; + }; - return { - type: "MultiPolygon", - arcs: components.map(function(polygons) { - var arcs = []; + Context.prototype.createViewportQuadCommand = function(fragmentShaderSource, overrides) { + overrides = defaultValue(overrides, defaultValue.EMPTY_OBJECT); - // Extract the exterior (unique) arcs. - polygons.forEach(function(polygon) { - polygon.forEach(function(ring) { - ring.forEach(function(arc) { - if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { - arcs.push(arc); - } - }); - }); + return new DrawCommand({ + vertexArray : this.getViewportQuadVertexArray(), + primitiveType : PrimitiveType.TRIANGLES, + renderState : overrides.renderState, + shaderProgram : ShaderProgram.fromCache({ + context : this, + vertexShaderSource : ViewportQuadVS, + fragmentShaderSource : fragmentShaderSource, + attributeLocations : viewportQuadAttributeLocations + }), + uniformMap : overrides.uniformMap, + owner : overrides.owner, + framebuffer : overrides.framebuffer, + pass : overrides.pass }); + }; - // Stitch the arcs into one or more rings. - arcs = stitchArcs(topology, arcs); + Context.prototype.createPickFramebuffer = function() { + return new PickFramebuffer(this); + }; - // If more than one ring is returned, - // at most one of these rings can be the exterior; - // this exterior ring has the same winding order - // as any exterior ring in the original polygons. - if ((n = arcs.length) > 1) { - var sgn = exterior(polygons[0][0]); - for (var i = 0, t; i < n; ++i) { - if (sgn === exterior(arcs[i])) { - t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; - break; + /** + * Gets the object associated with a pick color. + * + * @param {Color} pickColor The pick color. + * @returns {Object} The object associated with the pick color, or undefined if no object is associated with that color. + * + * @example + * var object = context.getObjectByPickColor(pickColor); + * + * @see Context#createPickId + */ + Context.prototype.getObjectByPickColor = function(pickColor) { + Check.defined('pickColor', pickColor); + + return this._pickObjects[pickColor.toRgba()]; + }; + + function PickId(pickObjects, key, color) { + this._pickObjects = pickObjects; + this.key = key; + this.color = color; + } + + defineProperties(PickId.prototype, { + object : { + get : function() { + return this._pickObjects[this.key]; + }, + set : function(value) { + this._pickObjects[this.key] = value; } - } } + }); - return arcs; - }) + PickId.prototype.destroy = function() { + delete this._pickObjects[this.key]; + return undefined; }; - } - function featureOrCollection(topology, o) { - return o.type === "GeometryCollection" ? { - type: "FeatureCollection", - features: o.geometries.map(function(o) { return feature(topology, o); }) - } : feature(topology, o); - } + /** + * Creates a unique ID associated with the input object for use with color-buffer picking. + * The ID has an RGBA color value unique to this context. You must call destroy() + * on the pick ID when destroying the input object. + * + * @param {Object} object The object to associate with the pick ID. + * @returns {Object} A PickId object with a <code>color</code> property. + * + * @exception {RuntimeError} Out of unique Pick IDs. + * + * + * @example + * this._pickId = context.createPickId({ + * primitive : this, + * id : this.id + * }); + * + * @see Context#getObjectByPickColor + */ + Context.prototype.createPickId = function(object) { + Check.defined('object', object); + + // the increment and assignment have to be separate statements to + // actually detect overflow in the Uint32 value + ++this._nextPickColor[0]; + var key = this._nextPickColor[0]; + if (key === 0) { + // In case of overflow + throw new RuntimeError('Out of unique Pick IDs.'); + } - function feature(topology, o) { - var f = { - type: "Feature", - id: o.id, - properties: o.properties || {}, - geometry: object(topology, o) + this._pickObjects[key] = object; + return new PickId(this._pickObjects, key, Color.fromRgba(key)); }; - if (o.id == null) delete f.id; - return f; - } - function object(topology, o) { - var absolute = transformAbsolute(topology.transform), - arcs = topology.arcs; + Context.prototype.isDestroyed = function() { + return false; + }; - function arc(i, points) { - if (points.length) points.pop(); - for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { - points.push(p = a[k].slice()); - absolute(p, k); - } - if (i < 0) reverse(points, n); - } + Context.prototype.destroy = function() { + // Destroy all objects in the cache that have a destroy method. + var cache = this.cache; + for (var property in cache) { + if (cache.hasOwnProperty(property)) { + var propertyValue = cache[property]; + if (defined(propertyValue.destroy)) { + propertyValue.destroy(); + } + } + } - function point(p) { - p = p.slice(); - absolute(p, 0); - return p; - } + this._shaderCache = this._shaderCache.destroy(); + this._defaultTexture = this._defaultTexture && this._defaultTexture.destroy(); + this._defaultCubeMap = this._defaultCubeMap && this._defaultCubeMap.destroy(); - function line(arcs) { - var points = []; - for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); - if (points.length < 2) points.push(points[0].slice()); - return points; - } + return destroyObject(this); + }; - function ring(arcs) { - var points = line(arcs); - while (points.length < 4) points.push(points[0].slice()); - return points; - } + return Context; +}); - function polygon(arcs) { - return arcs.map(ring); - } +define('Renderer/loadCubeMap',[ + '../Core/Check', + '../Core/defined', + '../Core/DeveloperError', + '../Core/Resource', + '../ThirdParty/when', + './CubeMap' + ], function( + Check, + defined, + DeveloperError, + Resource, + when, + CubeMap) { + 'use strict'; - function geometry(o) { - var t = o.type; - return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} - : t in geometryType ? {type: t, coordinates: geometryType[t](o)} - : null; - } + /** + * Asynchronously loads six images and creates a cube map. Returns a promise that + * will resolve to a {@link CubeMap} once loaded, or reject if any image fails to load. + * + * @exports loadCubeMap + * + * @param {Context} context The context to use to create the cube map. + * @param {Object} urls The source URL of each image. See the example below. + * @returns {Promise.<CubeMap>} a promise that will resolve to the requested {@link CubeMap} when loaded. + * + * @exception {DeveloperError} context is required. + * @exception {DeveloperError} urls is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. + * + * + * @example + * Cesium.loadCubeMap(context, { + * positiveX : 'skybox_px.png', + * negativeX : 'skybox_nx.png', + * positiveY : 'skybox_py.png', + * negativeY : 'skybox_ny.png', + * positiveZ : 'skybox_pz.png', + * negativeZ : 'skybox_nz.png' + * }).then(function(cubeMap) { + * // use the cubemap + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * + * @private + */ + function loadCubeMap(context, urls) { + Check.defined('context', context); + if ((!defined(urls)) || + (!defined(urls.positiveX)) || + (!defined(urls.negativeX)) || + (!defined(urls.positiveY)) || + (!defined(urls.negativeY)) || + (!defined(urls.positiveZ)) || + (!defined(urls.negativeZ))) { + throw new DeveloperError('urls is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.'); + } + + // PERFORMANCE_IDEA: Given the size of some cube maps, we should consider tiling them, which + // would prevent hiccups when uploading, for example, six 4096x4096 textures to the GPU. + // + // Also, it is perhaps acceptable to use the context here in the callbacks, but + // ideally, we would do it in the primitive's update function. - var geometryType = { - Point: function(o) { return point(o.coordinates); }, - MultiPoint: function(o) { return o.coordinates.map(point); }, - LineString: function(o) { return line(o.arcs); }, - MultiLineString: function(o) { return o.arcs.map(line); }, - Polygon: function(o) { return polygon(o.arcs); }, - MultiPolygon: function(o) { return o.arcs.map(polygon); } - }; + var facePromises = [ + Resource.createIfNeeded(urls.positiveX).fetchImage(), + Resource.createIfNeeded(urls.negativeX).fetchImage(), + Resource.createIfNeeded(urls.positiveY).fetchImage(), + Resource.createIfNeeded(urls.negativeY).fetchImage(), + Resource.createIfNeeded(urls.positiveZ).fetchImage(), + Resource.createIfNeeded(urls.negativeZ).fetchImage() + ]; - return geometry(o); - } + return when.all(facePromises, function(images) { + return new CubeMap({ + context : context, + source : { + positiveX : images[0], + negativeX : images[1], + positiveY : images[2], + negativeY : images[3], + positiveZ : images[4], + negativeZ : images[5] + } + }); + }); + } - function reverse(array, n) { - var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; - } + return loadCubeMap; +}); - function bisect(a, x) { - var lo = 0, hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (a[mid] < x) lo = mid + 1; - else hi = mid; - } - return lo; - } +define('Scene/DiscardMissingTileImagePolicy',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/DeveloperError', + '../Core/getImagePixels', + '../Core/Resource', + '../ThirdParty/when' + ], function( + defaultValue, + defined, + DeveloperError, + getImagePixels, + Resource, + when) { + 'use strict'; - function neighbors(objects) { - var indexesByArc = {}, // arc index -> array of object indexes - neighbors = objects.map(function() { return []; }); + /** + * A policy for discarding tile images that match a known image containing a + * "missing" image. + * + * @alias DiscardMissingTileImagePolicy + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.missingImageUrl The URL of the known missing image. + * @param {Cartesian2[]} options.pixelsToCheck An array of {@link Cartesian2} pixel positions to + * compare against the missing image. + * @param {Boolean} [options.disableCheckIfAllPixelsAreTransparent=false] If true, the discard check will be disabled + * if all of the pixelsToCheck in the missingImageUrl have an alpha value of 0. If false, the + * discard check will proceed no matter the values of the pixelsToCheck. + */ + function DiscardMissingTileImagePolicy(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - function line(arcs, i) { - arcs.forEach(function(a) { - if (a < 0) a = ~a; - var o = indexesByArc[a]; - if (o) o.push(i); - else indexesByArc[a] = [i]; - }); - } + if (!defined(options.missingImageUrl)) { + throw new DeveloperError('options.missingImageUrl is required.'); + } - function polygon(arcs, i) { - arcs.forEach(function(arc) { line(arc, i); }); - } + if (!defined(options.pixelsToCheck)) { + throw new DeveloperError('options.pixelsToCheck is required.'); + } + + this._pixelsToCheck = options.pixelsToCheck; + this._missingImagePixels = undefined; + this._missingImageByteLength = undefined; + this._isReady = false; - function geometry(o, i) { - if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); - else if (o.type in geometryType) geometryType[o.type](o.arcs, i); - } + var resource = Resource.createIfNeeded(options.missingImageUrl); - var geometryType = { - LineString: line, - MultiLineString: polygon, - Polygon: polygon, - MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } - }; + var that = this; - objects.forEach(geometry); + function success(image) { + if (defined(image.blob)) { + that._missingImageByteLength = image.blob.size; + } - for (var i in indexesByArc) { - for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { - for (var k = j + 1; k < m; ++k) { - var ij = indexes[j], ik = indexes[k], n; - if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); - if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); - } - } - } + var pixels = getImagePixels(image); - return neighbors; - } + if (options.disableCheckIfAllPixelsAreTransparent) { + var allAreTransparent = true; + var width = image.width; - function presimplify(topology, triangleArea) { - var absolute = transformAbsolute(topology.transform), - relative = transformRelative(topology.transform), - heap = minAreaHeap(); + var pixelsToCheck = options.pixelsToCheck; + for (var i = 0, len = pixelsToCheck.length; allAreTransparent && i < len; ++i) { + var pos = pixelsToCheck[i]; + var index = pos.x * 4 + pos.y * width; + var alpha = pixels[index + 3]; - if (!triangleArea) triangleArea = cartesianTriangleArea; + if (alpha > 0) { + allAreTransparent = false; + } + } - topology.arcs.forEach(function(arc) { - var triangles = [], - maxArea = 0, - triangle; + if (allAreTransparent) { + pixels = undefined; + } + } - // To store each point’s effective area, we create a new array rather than - // extending the passed-in point to workaround a Chrome/V8 bug (getting - // stuck in smi mode). For midpoints, the initial effective area of - // Infinity will be computed in the next step. - for (var i = 0, n = arc.length, p; i < n; ++i) { - p = arc[i]; - absolute(arc[i] = [p[0], p[1], Infinity], i); - } + that._missingImagePixels = pixels; + that._isReady = true; + } - for (var i = 1, n = arc.length - 1; i < n; ++i) { - triangle = arc.slice(i - 1, i + 2); - triangle[1][2] = triangleArea(triangle); - triangles.push(triangle); - heap.push(triangle); - } + function failure() { + // Failed to download "missing" image, so assume that any truly missing tiles + // will also fail to download and disable the discard check. + that._missingImagePixels = undefined; + that._isReady = true; + } - for (var i = 0, n = triangles.length; i < n; ++i) { - triangle = triangles[i]; - triangle.previous = triangles[i - 1]; - triangle.next = triangles[i + 1]; - } + when(resource.fetchImage(true), success, failure); + } - while (triangle = heap.pop()) { - var previous = triangle.previous, - next = triangle.next; + /** + * Determines if the discard policy is ready to process images. + * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + */ + DiscardMissingTileImagePolicy.prototype.isReady = function() { + return this._isReady; + }; - // If the area of the current point is less than that of the previous point - // to be eliminated, use the latter's area instead. This ensures that the - // current point cannot be eliminated without eliminating previously- - // eliminated points. - if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; - else maxArea = triangle[1][2]; + /** + * Given a tile image, decide whether to discard that image. + * + * @param {Image} image An image to test. + * @returns {Boolean} True if the image should be discarded; otherwise, false. + * + * @exception {DeveloperError} <code>shouldDiscardImage</code> must not be called before the discard policy is ready. + */ + DiscardMissingTileImagePolicy.prototype.shouldDiscardImage = function(image) { + if (!this._isReady) { + throw new DeveloperError('shouldDiscardImage must not be called before the discard policy is ready.'); + } + + var pixelsToCheck = this._pixelsToCheck; + var missingImagePixels = this._missingImagePixels; - if (previous) { - previous.next = next; - previous[2] = triangle[2]; - update(previous); + // If missingImagePixels is undefined, it indicates that the discard check has been disabled. + if (!defined(missingImagePixels)) { + return false; } - if (next) { - next.previous = previous; - next[0] = triangle[0]; - update(next); + if (defined(image.blob) && image.blob.size !== this._missingImageByteLength) { + return false; } - } - arc.forEach(relative); - }); + var pixels = getImagePixels(image); + var width = image.width; - function update(triangle) { - heap.remove(triangle); - triangle[1][2] = triangleArea(triangle); - heap.push(triangle); - } + for (var i = 0, len = pixelsToCheck.length; i < len; ++i) { + var pos = pixelsToCheck[i]; + var index = pos.x * 4 + pos.y * width; + for (var offset = 0; offset < 4; ++offset) { + var pixel = index + offset; + if (pixels[pixel] !== missingImagePixels[pixel]) { + return false; + } + } + } + return true; + }; - return topology; - } - function cartesianRingArea(ring) { - var i = -1, - n = ring.length, - a, - b = ring[n - 1], - area = 0; + return DiscardMissingTileImagePolicy; +}); - while (++i < n) { - a = b; - b = ring[i]; - area += a[0] * b[1] - a[1] * b[0]; - } +define('Scene/ImageryLayerFeatureInfo',[ + '../Core/defined' + ], function( + defined) { + 'use strict'; - return area * .5; - } + /** + * Describes a rasterized feature, such as a point, polygon, polyline, etc., in an imagery layer. + * + * @alias ImageryLayerFeatureInfo + * @constructor + */ + function ImageryLayerFeatureInfo() { + /** + * Gets or sets the name of the feature. + * @type {String} + */ + this.name = undefined; - function cartesianTriangleArea(triangle) { - var a = triangle[0], b = triangle[1], c = triangle[2]; - return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); - } + /** + * Gets or sets an HTML description of the feature. The HTML is not trusted and should + * be sanitized before display to the user. + * @type {String} + */ + this.description = undefined; - function compareArea(a, b) { - return a[1][2] - b[1][2]; - } + /** + * Gets or sets the position of the feature, or undefined if the position is not known. + * + * @type {Cartographic} + */ + this.position = undefined; - function minAreaHeap() { - var heap = {}, - array = [], - size = 0; + /** + * Gets or sets the raw data describing the feature. The raw data may be in any + * number of formats, such as GeoJSON, KML, etc. + * @type {Object} + */ + this.data = undefined; - heap.push = function(object) { - up(array[object._ = size] = object, size++); - return size; - }; + /** + * Gets or sets the image layer of the feature. + * @type {Object} + */ + this.imageryLayer = undefined; + } - heap.pop = function() { - if (size <= 0) return; - var removed = array[0], object; - if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); - return removed; - }; + /** + * Configures the name of this feature by selecting an appropriate property. The name will be obtained from + * one of the following sources, in this order: 1) the property with the name 'name', 2) the property with the name 'title', + * 3) the first property containing the word 'name', 4) the first property containing the word 'title'. If + * the name cannot be obtained from any of these sources, the existing name will be left unchanged. + * + * @param {Object} properties An object literal containing the properties of the feature. + */ + ImageryLayerFeatureInfo.prototype.configureNameFromProperties = function(properties) { + var namePropertyPrecedence = 10; + var nameProperty; - heap.remove = function(removed) { - var i = removed._, object; - if (array[i] !== removed) return; // invalid request - if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); - return i; - }; + for (var key in properties) { + if (properties.hasOwnProperty(key) && properties[key]) { + var lowerKey = key.toLowerCase(); - function up(object, i) { - while (i > 0) { - var j = ((i + 1) >> 1) - 1, - parent = array[j]; - if (compareArea(object, parent) >= 0) break; - array[parent._ = i] = parent; - array[object._ = i = j] = object; - } - } + if (namePropertyPrecedence > 1 && lowerKey === 'name') { + namePropertyPrecedence = 1; + nameProperty = key; + } else if (namePropertyPrecedence > 2 && lowerKey === 'title') { + namePropertyPrecedence = 2; + nameProperty = key; + } else if (namePropertyPrecedence > 3 && /name/i.test(key)) { + namePropertyPrecedence = 3; + nameProperty = key; + } else if (namePropertyPrecedence > 4 && /title/i.test(key)) { + namePropertyPrecedence = 4; + nameProperty = key; + } + } + } - function down(object, i) { - while (true) { - var r = (i + 1) << 1, - l = r - 1, - j = i, - child = array[j]; - if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; - if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; - if (j === i) break; - array[child._ = i] = child; - array[object._ = i = j] = object; - } - } + if (defined(nameProperty)) { + this.name = properties[nameProperty]; + } + }; - return heap; - } + /** + * Configures the description of this feature by creating an HTML table of properties and their values. + * + * @param {Object} properties An object literal containing the properties of the feature. + */ + ImageryLayerFeatureInfo.prototype.configureDescriptionFromProperties = function(properties) { + function describe(properties) { + var html = '<table class="cesium-infoBox-defaultTable">'; + for (var key in properties) { + if (properties.hasOwnProperty(key)) { + var value = properties[key]; + if (defined(value)) { + if (typeof value === 'object') { + html += '<tr><td>' + key + '</td><td>' + describe(value) + '</td></tr>'; + } else { + html += '<tr><td>' + key + '</td><td>' + value + '</td></tr>'; + } + } + } + } + html += '</table>'; - function transformAbsolute(transform) { - if (!transform) return noop; - var x0, - y0, - kx = transform.scale[0], - ky = transform.scale[1], - dx = transform.translate[0], - dy = transform.translate[1]; - return function(point, i) { - if (!i) x0 = y0 = 0; - point[0] = (x0 += point[0]) * kx + dx; - point[1] = (y0 += point[1]) * ky + dy; - }; - } + return html; + } - function transformRelative(transform) { - if (!transform) return noop; - var x0, - y0, - kx = transform.scale[0], - ky = transform.scale[1], - dx = transform.translate[0], - dy = transform.translate[1]; - return function(point, i) { - if (!i) x0 = y0 = 0; - var x1 = (point[0] - dx) / kx | 0, - y1 = (point[1] - dy) / ky | 0; - point[0] = x1 - x0; - point[1] = y1 - y0; - x0 = x1; - y0 = y1; + this.description = describe(properties); }; - } - - function noop() {} - if (typeof define === "function" && define.amd) define('ThirdParty/topojson',topojson); - else if (typeof module === "object" && module.exports) module.exports = topojson; - else this.topojson = topojson; -}(); + return ImageryLayerFeatureInfo; +}); -define('DataSources/GeoJsonDataSource',[ - '../Core/Cartesian3', - '../Core/Color', - '../Core/createGuid', - '../Core/defaultValue', +define('Scene/ImageryProvider',[ + '../Core/Check', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/DeveloperError', - '../Core/Event', - '../Core/getFilenameFromUri', - '../Core/loadJson', - '../Core/PinBuilder', - '../Core/PolygonHierarchy', - '../Core/RuntimeError', - '../Scene/HeightReference', - '../Scene/VerticalOrigin', - '../ThirdParty/topojson', - '../ThirdParty/when', - './BillboardGraphics', - './CallbackProperty', - './ColorMaterialProperty', - './ConstantPositionProperty', - './ConstantProperty', - './CorridorGraphics', - './DataSource', - './EntityCluster', - './EntityCollection', - './PolygonGraphics', - './PolylineGraphics' + '../Core/loadCRN', + '../Core/loadKTX', + '../Core/Resource' ], function( - Cartesian3, - Color, - createGuid, - defaultValue, + Check, defined, defineProperties, + deprecationWarning, DeveloperError, - Event, - getFilenameFromUri, - loadJson, - PinBuilder, - PolygonHierarchy, - RuntimeError, - HeightReference, - VerticalOrigin, - topojson, - when, - BillboardGraphics, - CallbackProperty, - ColorMaterialProperty, - ConstantPositionProperty, - ConstantProperty, - CorridorGraphics, - DataSource, - EntityCluster, - EntityCollection, - PolygonGraphics, - PolylineGraphics) { + loadCRN, + loadKTX, + Resource) { 'use strict'; - function defaultCrsFunction(coordinates) { - return Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2]); - } - - var crsNames = { - 'urn:ogc:def:crs:OGC:1.3:CRS84' : defaultCrsFunction, - 'EPSG:4326' : defaultCrsFunction, - 'urn:ogc:def:crs:EPSG::4326' : defaultCrsFunction - }; + /** + * Provides imagery to be displayed on the surface of an ellipsoid. This type describes an + * interface and is not intended to be instantiated directly. + * + * @alias ImageryProvider + * @constructor + * + * @see ArcGisMapServerImageryProvider + * @see BingMapsImageryProvider + * @see createOpenStreetMapImageryProvider + * @see createTileMapServiceImageryProvider + * @see GoogleEarthEnterpriseImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see GridImageryProvider + * @see MapboxImageryProvider + * @see SingleTileImageryProvider + * @see TileCoordinatesImageryProvider + * @see UrlTemplateImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Layers.html|Cesium Sandcastle Imagery Layers Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Layers%20Manipulation.html|Cesium Sandcastle Imagery Manipulation Demo} + */ + function ImageryProvider() { + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * + * @type {Number} + * @default undefined + */ + this.defaultAlpha = undefined; - var crsLinkHrefs = {}; - var crsLinkTypes = {}; - var defaultMarkerSize = 48; - var defaultMarkerSymbol; - var defaultMarkerColor = Color.ROYALBLUE; - var defaultStroke = Color.YELLOW; - var defaultStrokeWidth = 2; - var defaultFill = Color.fromBytes(255, 255, 0, 100); - var defaultClampToGround = false; + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * + * @type {Number} + * @default undefined + */ + this.defaultBrightness = undefined; - var sizes = { - small : 24, - medium : 48, - large : 64 - }; + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * + * @type {Number} + * @default undefined + */ + this.defaultContrast = undefined; - var simpleStyleIdentifiers = ['title', 'description', // - 'marker-size', 'marker-symbol', 'marker-color', 'stroke', // - 'stroke-opacity', 'stroke-width', 'fill', 'fill-opacity']; + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * + * @type {Number} + * @default undefined + */ + this.defaultHue = undefined; - function defaultDescribe(properties, nameProperty) { - var html = ''; - for ( var key in properties) { - if (properties.hasOwnProperty(key)) { - if (key === nameProperty || simpleStyleIdentifiers.indexOf(key) !== -1) { - continue; - } - var value = properties[key]; - if (defined(value)) { - if (typeof value === 'object') { - html += '<tr><th>' + key + '</th><td>' + defaultDescribe(value) + '</td></tr>'; - } else { - html += '<tr><th>' + key + '</th><td>' + value + '</td></tr>'; - } - } - } - } + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * + * @type {Number} + * @default undefined + */ + this.defaultSaturation = undefined; - if (html.length > 0) { - html = '<table class="cesium-infoBox-defaultTable"><tbody>' + html + '</tbody></table>'; - } + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * + * @type {Number} + * @default undefined + */ + this.defaultGamma = undefined; - return html; - } + /** + * The default texture minification filter to apply to this provider. + * + * @type {TextureMinificationFilter} + * @default undefined + */ + this.defaultMinificationFilter = undefined; - function createDescriptionCallback(describe, properties, nameProperty) { - var description; - return function(time, result) { - if (!defined(description)) { - description = describe(properties, nameProperty); - } - return description; - }; - } + /** + * The default texture magnification filter to apply to this provider. + * + * @type {TextureMagnificationFilter} + * @default undefined + */ + this.defaultMagnificationFilter = undefined; - function defaultDescribeProperty(properties, nameProperty) { - return new CallbackProperty(createDescriptionCallback(defaultDescribe, properties, nameProperty), true); + DeveloperError.throwInstantiationError(); } - //GeoJSON specifies only the Feature object has a usable id property - //But since "multi" geometries create multiple entity, - //we can't use it for them either. - function createObject(geoJson, entityCollection, describe) { - var id = geoJson.id; - if (!defined(id) || geoJson.type !== 'Feature') { - id = createGuid(); - } else { - var i = 2; - var finalId = id; - while (defined(entityCollection.getById(finalId))) { - finalId = id + '_' + i; - i++; - } - id = finalId; - } - - var entity = entityCollection.getOrCreateEntity(id); - var properties = geoJson.properties; - if (defined(properties)) { - entity.properties = properties; + defineProperties(ImageryProvider.prototype, { + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof ImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : DeveloperError.throwInstantiationError + }, - var nameProperty; + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof ImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : DeveloperError.throwInstantiationError + }, - //Check for the simplestyle specified name first. - var name = properties.title; - if (defined(name)) { - entity.name = name; - nameProperty = 'title'; - } else { - //Else, find the name by selecting an appropriate property. - //The name will be obtained based on this order: - //1) The first case-insensitive property with the name 'title', - //2) The first case-insensitive property with the name 'name', - //3) The first property containing the word 'title'. - //4) The first property containing the word 'name', - var namePropertyPrecedence = Number.MAX_VALUE; - for ( var key in properties) { - if (properties.hasOwnProperty(key) && properties[key]) { - var lowerKey = key.toLowerCase(); + /** + * Gets the rectangle, in radians, of the imagery provided by the instance. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle: { + get : DeveloperError.throwInstantiationError + }, - if (namePropertyPrecedence > 1 && lowerKey === 'title') { - namePropertyPrecedence = 1; - nameProperty = key; - break; - } else if (namePropertyPrecedence > 2 && lowerKey === 'name') { - namePropertyPrecedence = 2; - nameProperty = key; - } else if (namePropertyPrecedence > 3 && /title/i.test(key)) { - namePropertyPrecedence = 3; - nameProperty = key; - } else if (namePropertyPrecedence > 4 && /name/i.test(key)) { - namePropertyPrecedence = 4; - nameProperty = key; - } - } - } - if (defined(nameProperty)) { - entity.name = properties[nameProperty]; - } - } + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileWidth : { + get : DeveloperError.throwInstantiationError + }, - var description = properties.description; - if (description !== null) { - entity.description = !defined(description) ? describe(properties, nameProperty) : new ConstantProperty(description); - } - } - return entity; - } + /** + * Gets the height of each tile, in pixels. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileHeight : { + get : DeveloperError.throwInstantiationError + }, - function coordinatesArrayToCartesianArray(coordinates, crsFunction) { - var positions = new Array(coordinates.length); - for (var i = 0; i < coordinates.length; i++) { - positions[i] = crsFunction(coordinates[i]); - } - return positions; - } + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : DeveloperError.throwInstantiationError + }, - var geoJsonObjectTypes = { - Feature : processFeature, - FeatureCollection : processFeatureCollection, - GeometryCollection : processGeometryCollection, - LineString : processLineString, - MultiLineString : processMultiLineString, - MultiPoint : processMultiPoint, - MultiPolygon : processMultiPolygon, - Point : processPoint, - Polygon : processPolygon, - Topology : processTopology - }; + /** + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link ImageryProvider#ready} returns true. Generally, + * a minimum level should only be used when the rectangle of the imagery is small + * enough that the number of tiles at the minimum level is small. An imagery + * provider with more than a few tiles at the minimum level will lead to + * rendering problems. + * @memberof ImageryProvider.prototype + * @type {Number} + * @readonly + */ + minimumLevel : { + get : DeveloperError.throwInstantiationError + }, - var geometryTypes = { - GeometryCollection : processGeometryCollection, - LineString : processLineString, - MultiLineString : processMultiLineString, - MultiPoint : processMultiPoint, - MultiPolygon : processMultiPolygon, - Point : processPoint, - Polygon : processPolygon, - Topology : processTopology - }; + /** + * Gets the tiling scheme used by the provider. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {TilingScheme} + * @readonly + */ + tilingScheme : { + get : DeveloperError.throwInstantiationError + }, - // GeoJSON processing functions - function processFeature(dataSource, feature, notUsed, crsFunction, options) { - if (feature.geometry === null) { - //Null geometry is allowed, so just create an empty entity instance for it. - createObject(feature, dataSource._entityCollection, options.describe); - return; - } + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + */ + tileDiscardPolicy : { + get : DeveloperError.throwInstantiationError + }, - if (!defined(feature.geometry)) { - throw new RuntimeError('feature.geometry is required.'); - } + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error.. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof ImageryProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : DeveloperError.throwInstantiationError + }, - var geometryType = feature.geometry.type; - var geometryHandler = geometryTypes[geometryType]; - if (!defined(geometryHandler)) { - throw new RuntimeError('Unknown geometry type: ' + geometryType); - } - geometryHandler(dataSource, feature, feature.geometry, crsFunction, options); - } + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof ImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : DeveloperError.throwInstantiationError + }, - function processFeatureCollection(dataSource, featureCollection, notUsed, crsFunction, options) { - var features = featureCollection.features; - for (var i = 0, len = features.length; i < len; i++) { - processFeature(dataSource, features[i], undefined, crsFunction, options); - } - } + /** + * Gets the proxy used by this provider. + * @memberof ImageryProvider.prototype + * @type {Proxy} + * @readonly + */ + proxy : { + get : DeveloperError.throwInstantiationError + }, - function processGeometryCollection(dataSource, geoJson, geometryCollection, crsFunction, options) { - var geometries = geometryCollection.geometries; - for (var i = 0, len = geometries.length; i < len; i++) { - var geometry = geometries[i]; - var geometryType = geometry.type; - var geometryHandler = geometryTypes[geometryType]; - if (!defined(geometryHandler)) { - throw new RuntimeError('Unknown geometry type: ' + geometryType); - } - geometryHandler(dataSource, geoJson, geometry, crsFunction, options); + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof ImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { + get : DeveloperError.throwInstantiationError } - } - - function createPoint(dataSource, geoJson, crsFunction, coordinates, options) { - var symbol = options.markerSymbol; - var color = options.markerColor; - var size = options.markerSize; + }); - var properties = geoJson.properties; - if (defined(properties)) { - var cssColor = properties['marker-color']; - if (defined(cssColor)) { - color = Color.fromCssColorString(cssColor); - } + /** + * Gets the credits to be displayed when a given tile is displayed. + * @function + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + */ + ImageryProvider.prototype.getTileCredits = DeveloperError.throwInstantiationError; - size = defaultValue(sizes[properties['marker-size']], size); - var markerSymbol = properties['marker-symbol']; - if (defined(markerSymbol)) { - symbol = markerSymbol; - } - } + /** + * Requests the image for a given tile. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @function + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + */ + ImageryProvider.prototype.requestImage = DeveloperError.throwInstantiationError; - var canvasOrPromise; - if (defined(symbol)) { - if (symbol.length === 1) { - canvasOrPromise = dataSource._pinBuilder.fromText(symbol.toUpperCase(), color, size); - } else { - canvasOrPromise = dataSource._pinBuilder.fromMakiIconId(symbol, color, size); - } - } else { - canvasOrPromise = dataSource._pinBuilder.fromColor(color, size); - } + /** + * Asynchronously determines what features, if any, are located at a given longitude and latitude within + * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * This function is optional, so it may not exist on all ImageryProviders. + * + * @function + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. + * + * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + */ + ImageryProvider.prototype.pickFeatures = DeveloperError.throwInstantiationError; - var billboard = new BillboardGraphics(); - billboard.verticalOrigin = new ConstantProperty(VerticalOrigin.BOTTOM); + var ktxRegex = /\.ktx$/i; + var crnRegex = /\.crn$/i; - // Clamp to ground if there isn't a height specified - if (coordinates.length === 2 && options.clampToGround) { - billboard.heightReference = HeightReference.CLAMP_TO_GROUND; + /** + * Loads an image from a given URL. If the server referenced by the URL already has + * too many requests pending, this function will instead return undefined, indicating + * that the request should be retried later. + * + * @param {ImageryProvider} imageryProvider The imagery provider for the URL. + * @param {Resource|String} url The URL of the image. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + */ + ImageryProvider.loadImage = function(imageryProvider, url, request) { + Check.defined('url', url); + + if (defined(request)) { + deprecationWarning('ImageryProvider.loadImage.request', 'The request parameter has been deprecated. Set the request property on the Resource parameter.'); } - var entity = createObject(geoJson, dataSource._entityCollection, options.describe); - entity.billboard = billboard; - entity.position = new ConstantPositionProperty(crsFunction(coordinates)); - - var promise = when(canvasOrPromise).then(function(image) { - billboard.image = new ConstantProperty(image); - }).otherwise(function() { - billboard.image = new ConstantProperty(dataSource._pinBuilder.fromColor(color, size)); + var resource = Resource.createIfNeeded(url, { + request: request }); - dataSource._promises.push(promise); - } - - function processPoint(dataSource, geoJson, geometry, crsFunction, options) { - createPoint(dataSource, geoJson, crsFunction, geometry.coordinates, options); - } - - function processMultiPoint(dataSource, geoJson, geometry, crsFunction, options) { - var coordinates = geometry.coordinates; - for (var i = 0; i < coordinates.length; i++) { - createPoint(dataSource, geoJson, crsFunction, coordinates[i], options); + if (ktxRegex.test(resource)) { + return loadKTX(resource); + } else if (crnRegex.test(resource)) { + return loadCRN(resource); + } else if (defined(imageryProvider.tileDiscardPolicy)) { + return resource.fetchImage(true); } - } - function createLineString(dataSource, geoJson, crsFunction, coordinates, options) { - var material = options.strokeMaterialProperty; - var widthProperty = options.strokeWidthProperty; + return resource.fetchImage(); + }; - var properties = geoJson.properties; - if (defined(properties)) { - var width = properties['stroke-width']; - if (defined(width)) { - widthProperty = new ConstantProperty(width); - } + return ImageryProvider; +}); - var color; - var stroke = properties.stroke; - if (defined(stroke)) { - color = Color.fromCssColorString(stroke); - } - var opacity = properties['stroke-opacity']; - if (defined(opacity) && opacity !== 1.0) { - if (!defined(color)) { - color = material.color.clone(); - } - color.alpha = opacity; - } - if (defined(color)) { - material = new ColorMaterialProperty(color); - } +define('Scene/ArcGisMapServerImageryProvider',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/Credit', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/Event', + '../Core/GeographicTilingScheme', + '../Core/Math', + '../Core/Rectangle', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/TileProviderError', + '../Core/WebMercatorProjection', + '../Core/WebMercatorTilingScheme', + '../ThirdParty/when', + './DiscardMissingTileImagePolicy', + './ImageryLayerFeatureInfo', + './ImageryProvider' + ], function( + Cartesian2, + Cartesian3, + Cartographic, + Credit, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Event, + GeographicTilingScheme, + CesiumMath, + Rectangle, + Resource, + RuntimeError, + TileProviderError, + WebMercatorProjection, + WebMercatorTilingScheme, + when, + DiscardMissingTileImagePolicy, + ImageryLayerFeatureInfo, + ImageryProvider) { + 'use strict'; + + /** + * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are + * used, if available. + * + * @alias ArcGisMapServerImageryProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The URL of the ArcGIS MapServer service. + * @param {String} [options.token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. + * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile + * is invalid and should be discarded. If this value is not specified, a default + * {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a + * {@link NeverTileDiscardPolicy} is used for non-tiled map servers. In the former case, + * we request tile 0,0 at the maximum tile level and check pixels (0,0), (200,20), (20,200), + * (80,110), and (160, 130). If all of these pixels are transparent, the discard check is + * disabled and no tiles are discarded. If any of them have a non-transparent color, any + * tile that has the same values in these pixel locations is discarded. The end result of + * these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure + * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this + * parameter. + * @param {Boolean} [options.usePreCachedTilesIfAvailable=true] If true, the server's pre-cached + * tiles are used if they are available. If false, any pre-cached tiles are ignored and the + * 'export' service is used. + * @param {String} [options.layers] A comma-separated list of the layers to show, or undefined if all layers should be shown. + * @param {Boolean} [options.enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke + * the Identify service on the MapServer and return the features included in the response. If false, + * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) + * without communicating with the server. Set this property to false if you don't want this provider's features to + * be pickable. Can be overridden by setting the {@link ArcGisMapServerImageryProvider#enablePickFeatures} property on the object. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing + * a tiled layer. + * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles. + * This parameter is ignored when accessing a tiled server. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified and used, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * @param {Number} [options.tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server. + * @param {Number} [options.tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server. + * @param {Number} [options.maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing + * a tiled server. + * + * @see BingMapsImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + * + * + * @example + * var esri = new Cesium.ArcGisMapServerImageryProvider({ + * url : 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' + * }); + * + * @see {@link http://resources.esri.com/help/9.3/arcgisserver/apis/rest/|ArcGIS Server REST API} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + function ArcGisMapServerImageryProvider(options) { + options = defaultValue(options, {}); + + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('ArcGisMapServerImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - var entity = createObject(geoJson, dataSource._entityCollection, options.describe); - var graphics; - if (options.clampToGround) { - graphics = new CorridorGraphics(); - entity.corridor = graphics; - } else { - graphics = new PolylineGraphics(); - entity.polyline = graphics; + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); + resource.appendForwardSlash(); + + if (defined(options.token)) { + resource.addQueryParameters({ + token: options.token + }); } - graphics.material = material; - graphics.width = widthProperty; - graphics.positions = new ConstantProperty(coordinatesArrayToCartesianArray(coordinates, crsFunction)); - } + this._resource = resource; + this._tileDiscardPolicy = options.tileDiscardPolicy; - function processLineString(dataSource, geoJson, geometry, crsFunction, options) { - createLineString(dataSource, geoJson, crsFunction, geometry.coordinates, options); - } + this._tileWidth = defaultValue(options.tileWidth, 256); + this._tileHeight = defaultValue(options.tileHeight, 256); + this._maximumLevel = options.maximumLevel; + this._tilingScheme = defaultValue(options.tilingScheme, new GeographicTilingScheme({ ellipsoid : options.ellipsoid })); + this._credit = undefined; + this._useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true); + this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle); + this._layers = options.layers; - function processMultiLineString(dataSource, geoJson, geometry, crsFunction, options) { - var lineStrings = geometry.coordinates; - for (var i = 0; i < lineStrings.length; i++) { - createLineString(dataSource, geoJson, crsFunction, lineStrings[i], options); - } - } + /** + * Gets or sets a value indicating whether feature picking is enabled. If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will + * invoke the "identify" operation on the ArcGIS server and return the features included in the response. If false, + * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) + * without communicating with the server. + * @type {Boolean} + * @default true + */ + this.enablePickFeatures = defaultValue(options.enablePickFeatures, true); - function createPolygon(dataSource, geoJson, crsFunction, coordinates, options) { - if (coordinates.length === 0 || coordinates[0].length === 0) { - return; - } + this._errorEvent = new Event(); - var outlineColorProperty = options.strokeMaterialProperty.color; - var material = options.fillMaterialProperty; - var widthProperty = options.strokeWidthProperty; + this._ready = false; + this._readyPromise = when.defer(); - var properties = geoJson.properties; - if (defined(properties)) { - var width = properties['stroke-width']; - if (defined(width)) { - widthProperty = new ConstantProperty(width); - } + // Grab the details of this MapServer. + var that = this; + var metadataError; - var color; - var stroke = properties.stroke; - if (defined(stroke)) { - color = Color.fromCssColorString(stroke); - } - var opacity = properties['stroke-opacity']; - if (defined(opacity) && opacity !== 1.0) { - if (!defined(color)) { - color = options.strokeMaterialProperty.color.clone(); + function metadataSuccess(data) { + var tileInfo = data.tileInfo; + if (!defined(tileInfo)) { + that._useTiles = false; + } else { + that._tileWidth = tileInfo.rows; + that._tileHeight = tileInfo.cols; + + if (tileInfo.spatialReference.wkid === 102100 || + tileInfo.spatialReference.wkid === 102113) { + that._tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); + } else if (data.tileInfo.spatialReference.wkid === 4326) { + that._tilingScheme = new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); + } else { + var message = 'Tile spatial reference WKID ' + data.tileInfo.spatialReference.wkid + ' is not supported.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + return; } - color.alpha = opacity; - } + that._maximumLevel = data.tileInfo.lods.length - 1; - if (defined(color)) { - outlineColorProperty = new ConstantProperty(color); - } + if (defined(data.fullExtent)) { + if (defined(data.fullExtent.spatialReference) && defined(data.fullExtent.spatialReference.wkid)) { + if (data.fullExtent.spatialReference.wkid === 102100 || + data.fullExtent.spatialReference.wkid === 102113) { - var fillColor; - var fill = properties.fill; - if (defined(fill)) { - fillColor = Color.fromCssColorString(fill); - fillColor.alpha = material.color.alpha; - } - opacity = properties['fill-opacity']; - if (defined(opacity) && opacity !== material.color.alpha) { - if (!defined(fillColor)) { - fillColor = material.color.clone(); + var projection = new WebMercatorProjection(); + var extent = data.fullExtent; + var sw = projection.unproject(new Cartesian3(Math.max(extent.xmin, -that._tilingScheme.ellipsoid.maximumRadius * Math.PI), Math.max(extent.ymin, -that._tilingScheme.ellipsoid.maximumRadius * Math.PI), 0.0)); + var ne = projection.unproject(new Cartesian3(Math.min(extent.xmax, that._tilingScheme.ellipsoid.maximumRadius * Math.PI), Math.min(extent.ymax, that._tilingScheme.ellipsoid.maximumRadius * Math.PI), 0.0)); + that._rectangle = new Rectangle(sw.longitude, sw.latitude, ne.longitude, ne.latitude); + } else if (data.fullExtent.spatialReference.wkid === 4326) { + that._rectangle = Rectangle.fromDegrees(data.fullExtent.xmin, data.fullExtent.ymin, data.fullExtent.xmax, data.fullExtent.ymax); + } else { + var extentMessage = 'fullExtent.spatialReference WKID ' + data.fullExtent.spatialReference.wkid + ' is not supported.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, extentMessage, undefined, undefined, undefined, requestMetadata); + return; + } + } + } else { + that._rectangle = that._tilingScheme.rectangle; } - fillColor.alpha = opacity; - } - if (defined(fillColor)) { - material = new ColorMaterialProperty(fillColor); + + // Install the default tile discard policy if none has been supplied. + if (!defined(that._tileDiscardPolicy)) { + that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ + missingImageUrl : buildImageResource(that, 0, 0, that._maximumLevel).url, + pixelsToCheck : [new Cartesian2(0, 0), new Cartesian2(200, 20), new Cartesian2(20, 200), new Cartesian2(80, 110), new Cartesian2(160, 130)], + disableCheckIfAllPixelsAreTransparent : true + }); + } + + that._useTiles = true; } - } - var polygon = new PolygonGraphics(); - polygon.outline = new ConstantProperty(true); - polygon.outlineColor = outlineColorProperty; - polygon.outlineWidth = widthProperty; - polygon.material = material; + if (defined(data.copyrightText) && data.copyrightText.length > 0) { + that._credit = new Credit({text: data.copyrightText}); + } - var holes = []; - for (var i = 1, len = coordinates.length; i < len; i++) { - holes.push(new PolygonHierarchy(coordinatesArrayToCartesianArray(coordinates[i], crsFunction))); + that._ready = true; + that._readyPromise.resolve(true); + TileProviderError.handleSuccess(metadataError); } - var positions = coordinates[0]; - polygon.hierarchy = new ConstantProperty(new PolygonHierarchy(coordinatesArrayToCartesianArray(positions, crsFunction), holes)); - if (positions[0].length > 2) { - polygon.perPositionHeight = new ConstantProperty(true); - } else if (!options.clampToGround) { - polygon.height = 0; + function metadataFailure(e) { + var message = 'An error occurred while accessing ' + that._resource.url + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + that._readyPromise.reject(new RuntimeError(message)); } - var entity = createObject(geoJson, dataSource._entityCollection, options.describe); - entity.polygon = polygon; - } - - function processPolygon(dataSource, geoJson, geometry, crsFunction, options) { - createPolygon(dataSource, geoJson, crsFunction, geometry.coordinates, options); - } + function requestMetadata() { + var resource = that._resource.getDerivedResource({ + queryParameters: { + f: 'json' + } + }); + var metadata = resource.fetchJsonp(); + when(metadata, metadataSuccess, metadataFailure); + } - function processMultiPolygon(dataSource, geoJson, geometry, crsFunction, options) { - var polygons = geometry.coordinates; - for (var i = 0; i < polygons.length; i++) { - createPolygon(dataSource, geoJson, crsFunction, polygons[i], options); + if (this._useTiles) { + requestMetadata(); + } else { + this._ready = true; + this._readyPromise.resolve(true); } } - function processTopology(dataSource, geoJson, geometry, crsFunction, options) { - for ( var property in geometry.objects) { - if (geometry.objects.hasOwnProperty(property)) { - var feature = topojson.feature(geometry, geometry.objects[property]); - var typeHandler = geoJsonObjectTypes[feature.type]; - typeHandler(dataSource, feature, feature, crsFunction, options); + function buildImageResource(imageryProvider, x, y, level, request) { + var resource; + if (imageryProvider._useTiles) { + resource = imageryProvider._resource.getDerivedResource({ + url: 'tile/' + level + '/' + y + '/' + x, + request: request + }); + } else { + var nativeRectangle = imageryProvider._tilingScheme.tileXYToNativeRectangle(x, y, level); + var bbox = nativeRectangle.west + ',' + nativeRectangle.south + ',' + nativeRectangle.east + ',' + nativeRectangle.north; + + var query = { + bbox: bbox, + size: imageryProvider._tileWidth + ',' + imageryProvider._tileHeight, + format: 'png', + transparent: true, + f: 'image' + }; + + if (imageryProvider._tilingScheme instanceof GeographicTilingScheme) { + query.bboxSR = 4326; + query.imageSR = 4326; + } else { + query.bboxSR = 3857; + query.imageSR = 3857; } + if (imageryProvider.layers) { + query.layers = 'show:' + imageryProvider.layers; + } + + resource = imageryProvider._resource.getDerivedResource({ + url: 'export', + request: request, + queryParameters: query + }); } - } - /** - * A {@link DataSource} which processes both - * {@link http://www.geojson.org/|GeoJSON} and {@link https://github.com/mbostock/topojson|TopoJSON} data. - * {@link https://github.com/mapbox/simplestyle-spec|simplestyle-spec} properties will also be used if they - * are present. - * - * @alias GeoJsonDataSource - * @constructor - * - * @param {String} [name] The name of this data source. If undefined, a name will be taken from - * the name of the GeoJSON file. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=GeoJSON%20and%20TopoJSON.html|Cesium Sandcastle GeoJSON and TopoJSON Demo} - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=GeoJSON%20simplestyle.html|Cesium Sandcastle GeoJSON simplestyle Demo} - * - * @example - * var viewer = new Cesium.Viewer('cesiumContainer'); - * viewer.dataSources.add(Cesium.GeoJsonDataSource.load('../../SampleData/ne_10m_us_states.topojson', { - * stroke: Cesium.Color.HOTPINK, - * fill: Cesium.Color.PINK, - * strokeWidth: 3, - * markerSymbol: '?' - * })); - */ - function GeoJsonDataSource(name) { - this._name = name; - this._changed = new Event(); - this._error = new Event(); - this._isLoading = false; - this._loading = new Event(); - this._entityCollection = new EntityCollection(this); - this._promises = []; - this._pinBuilder = new PinBuilder(); - this._entityCluster = new EntityCluster(); + return resource; } - /** - * Creates a Promise to a new instance loaded with the provided GeoJSON or TopoJSON data. - * - * @param {String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. - * @param {Object} [options] An object with the following properties: - * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. - * @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. - * @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. - * @param {Color} [options.markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point. - * @param {Color} [options.stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines. - * @param {Number} [options.strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. - * @param {Color} [options.fill=GeoJsonDataSource.fill] The default color for polygon interiors. - * @param {Boolean} [options.clampToGround=GeoJsonDataSource.clampToGround] true if we want the geometry features (polygons or linestrings) clamped to the ground. If true, lines will use corridors so use Entity.corridor instead of Entity.polyline. - * - * @returns {Promise.<GeoJsonDataSource>} A promise that will resolve when the data is loaded. - */ - GeoJsonDataSource.load = function(data, options) { - return new GeoJsonDataSource().load(data, options); - }; - - defineProperties(GeoJsonDataSource, { - /** - * Gets or sets the default size of the map pin created for each point, in pixels. - * @memberof GeoJsonDataSource - * @type {Number} - * @default 48 - */ - markerSize : { - get : function() { - return defaultMarkerSize; - }, - set : function(value) { - defaultMarkerSize = value; - } - }, + defineProperties(ArcGisMapServerImageryProvider.prototype, { /** - * Gets or sets the default symbol of the map pin created for each point. - * This can be any valid {@link http://mapbox.com/maki/|Maki} identifier, any single character, - * or blank if no symbol is to be used. - * @memberof GeoJsonDataSource + * Gets the URL of the ArcGIS MapServer. + * @memberof ArcGisMapServerImageryProvider.prototype * @type {String} + * @readonly */ - markerSymbol : { + url : { get : function() { - return defaultMarkerSymbol; - }, - set : function(value) { - defaultMarkerSymbol = value; + return this._resource._url; } }, + /** - * Gets or sets the default color of the map pin created for each point. - * @memberof GeoJsonDataSource - * @type {Color} - * @default Color.ROYALBLUE + * Gets the ArcGIS token used to authenticate with the ArcGis MapServer service. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {String} + * @readonly */ - markerColor : { + token : { get : function() { - return defaultMarkerColor; - }, - set : function(value) { - defaultMarkerColor = value; + return this._resource.queryParameters.token; } }, + /** - * Gets or sets the default color of polylines and polygon outlines. - * @memberof GeoJsonDataSource - * @type {Color} - * @default Color.BLACK + * Gets the proxy used by this provider. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Proxy} + * @readonly */ - stroke : { + proxy : { get : function() { - return defaultStroke; - }, - set : function(value) { - defaultStroke = value; + return this._resource.proxy; } }, + /** - * Gets or sets the default width of polylines and polygon outlines. - * @memberof GeoJsonDataSource + * Gets the width of each tile, in pixels. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} - * @default 2.0 + * @readonly */ - strokeWidth : { + tileWidth : { get : function() { - return defaultStrokeWidth; - }, - set : function(value) { - defaultStrokeWidth = value; + if (!this._ready) { + throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); + } + + return this._tileWidth; } }, + /** - * Gets or sets default color for polygon interiors. - * @memberof GeoJsonDataSource - * @type {Color} - * @default Color.YELLOW + * Gets the height of each tile, in pixels. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number} + * @readonly */ - fill : { + tileHeight: { get : function() { - return defaultFill; - }, - set : function(value) { - defaultFill = value; + if (!this._ready) { + throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + } + + return this._tileHeight; } }, + /** - * Gets or sets default of whether to clamp to the ground. - * @memberof GeoJsonDataSource - * @type {Boolean} - * @default false + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number} + * @readonly */ - clampToGround : { + maximumLevel : { get : function() { - return defaultClampToGround; - }, - set : function(value) { - defaultClampToGround = value; + if (!this._ready) { + throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); + } + + return this._maximumLevel; } }, /** - * Gets an object that maps the name of a crs to a callback function which takes a GeoJSON coordinate - * and transforms it into a WGS84 Earth-fixed Cartesian. Older versions of GeoJSON which - * supported the EPSG type can be added to this list as well, by specifying the complete EPSG name, - * for example 'EPSG:4326'. - * @memberof GeoJsonDataSource - * @type {Object} + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number} + * @readonly */ - crsNames : { + minimumLevel : { get : function() { - return crsNames; + if (!this._ready) { + throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); + } + + return 0; } }, /** - * Gets an object that maps the href property of a crs link to a callback function - * which takes the crs properties object and returns a Promise that resolves - * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian. - * Items in this object take precedence over those defined in <code>crsLinkHrefs</code>, assuming - * the link has a type specified. - * @memberof GeoJsonDataSource - * @type {Object} + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {TilingScheme} + * @readonly */ - crsLinkHrefs : { + tilingScheme : { get : function() { - return crsLinkHrefs; + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme; } }, /** - * Gets an object that maps the type property of a crs link to a callback function - * which takes the crs properties object and returns a Promise that resolves - * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian. - * Items in <code>crsLinkHrefs</code> take precedence over this object. - * @memberof GeoJsonDataSource - * @type {Object} + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Rectangle} + * @readonly */ - crsLinkTypes : { + rectangle : { get : function() { - return crsLinkTypes; + if (!this._ready) { + throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); + } + + return this._rectangle; } - } - }); + }, - defineProperties(GeoJsonDataSource.prototype, { /** - * Gets or sets a human-readable name for this instance. - * @memberof GeoJsonDataSource.prototype - * @type {String} + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly */ - name : { + tileDiscardPolicy : { get : function() { - return this._name; - }, - set : function(value) { - if (this._name !== value) { - this._name = value; - this._changed.raiseEvent(this); + if (!this._ready) { + throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); } + + return this._tileDiscardPolicy; } }, + /** - * This DataSource only defines static data, therefore this property is always undefined. - * @memberof GeoJsonDataSource.prototype - * @type {DataSourceClock} - */ - clock : { - value : undefined, - writable : false - }, - /** - * Gets the collection of {@link Entity} instances. - * @memberof GeoJsonDataSource.prototype - * @type {EntityCollection} + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Event} + * @readonly */ - entities : { + errorEvent : { get : function() { - return this._entityCollection; + return this._errorEvent; } }, + /** - * Gets a value indicating if the data source is currently loading data. - * @memberof GeoJsonDataSource.prototype + * Gets a value indicating whether or not the provider is ready for use. + * @memberof ArcGisMapServerImageryProvider.prototype * @type {Boolean} + * @readonly */ - isLoading : { + ready : { get : function() { - return this._isLoading; + return this._ready; } }, + /** - * Gets an event that will be raised when the underlying data changes. - * @memberof GeoJsonDataSource.prototype - * @type {Event} + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly */ - changedEvent : { + readyPromise : { get : function() { - return this._changed; + return this._readyPromise.promise; } }, + /** - * Gets an event that will be raised if an error is encountered during processing. - * @memberof GeoJsonDataSource.prototype - * @type {Event} + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Credit} + * @readonly */ - errorEvent : { + credit : { get : function() { - return this._error; + return this._credit; } }, + /** - * Gets an event that will be raised when the data source either starts or stops loading. - * @memberof GeoJsonDataSource.prototype - * @type {Event} + * Gets a value indicating whether this imagery provider is using pre-cached tiles from the + * ArcGIS MapServer. If the imagery provider is not yet ready ({@link ArcGisMapServerImageryProvider#ready}), this function + * will return the value of `options.usePreCachedTilesIfAvailable`, even if the MapServer does + * not have pre-cached tiles. + * @memberof ArcGisMapServerImageryProvider.prototype + * + * @type {Boolean} + * @readonly + * @default true */ - loadingEvent : { + usingPrecachedTiles : { get : function() { - return this._loading; + return this._useTiles; } }, + /** - * Gets whether or not this data source should be displayed. - * @memberof GeoJsonDataSource.prototype + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof ArcGisMapServerImageryProvider.prototype + * * @type {Boolean} + * @readonly + * @default true */ - show : { + hasAlphaChannel : { get : function() { - return this._entityCollection.show; - }, - set : function(value) { - this._entityCollection.show = value; + return true; } }, /** - * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. + * Gets the comma-separated list of layer IDs to show. + * @memberof ArcGisMapServerImageryProvider.prototype * - * @memberof GeoJsonDataSource.prototype - * @type {EntityCluster} + * @type {String} */ - clustering : { + layers : { get : function() { - return this._entityCluster; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value must be defined.'); - } - this._entityCluster = value; + return this._layers; } } }); + /** - * Asynchronously loads the provided GeoJSON or TopoJSON data, replacing any existing data. + * Gets the credits to be displayed when a given tile is displayed. * - * @param {String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. - * @param {Object} [options] An object with the following properties: - * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. - * @param {GeoJsonDataSource~describe} [options.describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string), - * which converts the properties into an html description. - * @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. - * @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. - * @param {Color} [options.markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point. - * @param {Color} [options.stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines. - * @param {Number} [options.strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. - * @param {Color} [options.fill=GeoJsonDataSource.fill] The default color for polygon interiors. - * @param {Boolean} [options.clampToGround=GeoJsonDataSource.clampToGround] true if we want the features clamped to the ground. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. * - * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - GeoJsonDataSource.prototype.load = function(data, options) { - if (!defined(data)) { - throw new DeveloperError('data is required.'); + ArcGisMapServerImageryProvider.prototype.getTileCredits = function(x, y, level) { + return undefined; + }; + + /** + * Requests the image for a given tile. This function should + * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + */ + ArcGisMapServerImageryProvider.prototype.requestImage = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); } - DataSource.setLoading(this, true); + return ImageryProvider.loadImage(this, buildImageResource(this, x, y, level, request)); + }; - var promise = data; - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var sourceUri = options.sourceUri; - if (typeof data === 'string') { - if (!defined(sourceUri)) { - sourceUri = data; - } - promise = loadJson(data); + /** + /** + * Asynchronously determines what features, if any, are located at a given longitude and latitude within + * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * + * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + */ + ArcGisMapServerImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + if (!this._ready) { + throw new DeveloperError('pickFeatures must not be called before the imagery provider is ready.'); + } + + if (!this.enablePickFeatures) { + return undefined; } - options = { - describe: defaultValue(options.describe, defaultDescribeProperty), - markerSize : defaultValue(options.markerSize, defaultMarkerSize), - markerSymbol : defaultValue(options.markerSymbol, defaultMarkerSymbol), - markerColor : defaultValue(options.markerColor, defaultMarkerColor), - strokeWidthProperty : new ConstantProperty(defaultValue(options.strokeWidth, defaultStrokeWidth)), - strokeMaterialProperty : new ColorMaterialProperty(defaultValue(options.stroke, defaultStroke)), - fillMaterialProperty : new ColorMaterialProperty(defaultValue(options.fill, defaultFill)), - clampToGround : defaultValue(options.clampToGround, defaultClampToGround) - }; - - var that = this; - return when(promise, function(geoJson) { - return load(that, geoJson, options, sourceUri); - }).otherwise(function(error) { - DataSource.setLoading(that, false); - that._error.raiseEvent(that, error); - console.log(error); - return when.reject(error); - }); - }; + var rectangle = this._tilingScheme.tileXYToNativeRectangle(x, y, level); - function load(that, geoJson, options, sourceUri) { - var name; - if (defined(sourceUri)) { - name = getFilenameFromUri(sourceUri); + var horizontal; + var vertical; + var sr; + if (this._tilingScheme instanceof GeographicTilingScheme) { + horizontal = CesiumMath.toDegrees(longitude); + vertical = CesiumMath.toDegrees(latitude); + sr = '4326'; + } else { + var projected = this._tilingScheme.projection.project(new Cartographic(longitude, latitude, 0.0)); + horizontal = projected.x; + vertical = projected.y; + sr = '3857'; } - if (defined(name) && that._name !== name) { - that._name = name; - that._changed.raiseEvent(that); - } + var layers = 'visible'; + if (defined(this._layers)) { + layers += ':' + this._layers; + } + + var query = { + f: 'json', + tolerance: 2, + geometryType: 'esriGeometryPoint', + geometry: horizontal + ',' + vertical, + mapExtent: rectangle.west + ',' + rectangle.south + ',' + rectangle.east + ',' + rectangle.north, + imageDisplay: this._tileWidth + ',' + this._tileHeight + ',96', + sr: sr, + layers: layers + }; - var typeHandler = geoJsonObjectTypes[geoJson.type]; - if (!defined(typeHandler)) { - throw new RuntimeError('Unsupported GeoJSON object type: ' + geoJson.type); - } + var resource = this._resource.getDerivedResource({ + url: 'identify', + queryParameters: query + }); - //Check for a Coordinate Reference System. - var crs = geoJson.crs; - var crsFunction = crs !== null ? defaultCrsFunction : null; + return resource.fetchJson().then(function(json) { + var result = []; - if (defined(crs)) { - if (!defined(crs.properties)) { - throw new RuntimeError('crs.properties is undefined.'); + var features = json.results; + if (!defined(features)) { + return result; } - var properties = crs.properties; - if (crs.type === 'name') { - crsFunction = crsNames[properties.name]; - if (!defined(crsFunction)) { - throw new RuntimeError('Unknown crs name: ' + properties.name); - } - } else if (crs.type === 'link') { - var handler = crsLinkHrefs[properties.href]; - if (!defined(handler)) { - handler = crsLinkTypes[properties.type]; - } + for (var i = 0; i < features.length; ++i) { + var feature = features[i]; - if (!defined(handler)) { - throw new RuntimeError('Unable to resolve crs link: ' + JSON.stringify(properties)); - } + var featureInfo = new ImageryLayerFeatureInfo(); + featureInfo.data = feature; + featureInfo.name = feature.value; + featureInfo.properties = feature.attributes; + featureInfo.configureDescriptionFromProperties(feature.attributes); - crsFunction = handler(properties); - } else if (crs.type === 'EPSG') { - crsFunction = crsNames['EPSG:' + properties.code]; - if (!defined(crsFunction)) { - throw new RuntimeError('Unknown crs EPSG code: ' + properties.code); + // If this is a point feature, use the coordinates of the point. + if (feature.geometryType === 'esriGeometryPoint' && feature.geometry) { + var wkid = feature.geometry.spatialReference && feature.geometry.spatialReference.wkid ? feature.geometry.spatialReference.wkid : 4326; + if (wkid === 4326 || wkid === 4283) { + featureInfo.position = Cartographic.fromDegrees(feature.geometry.x, feature.geometry.y, feature.geometry.z); + } else if (wkid === 102100 || wkid === 900913 || wkid === 3857) { + var projection = new WebMercatorProjection(); + featureInfo.position = projection.unproject(new Cartesian3(feature.geometry.x, feature.geometry.y, feature.geometry.z)); + } } - } else { - throw new RuntimeError('Unknown crs type: ' + crs.type); - } - } - - return when(crsFunction, function(crsFunction) { - that._entityCollection.removeAll(); - // null is a valid value for the crs, but means the entire load process becomes a no-op - // because we can't assume anything about the coordinates. - if (crsFunction !== null) { - typeHandler(that, geoJson, geoJson, crsFunction, options); + result.push(featureInfo); } - return when.all(that._promises, function() { - that._promises.length = 0; - DataSource.setLoading(that, false); - return that; - }); + return result; }); - } - - /** - * This callback is displayed as part of the GeoJsonDataSource class. - * @callback GeoJsonDataSource~describe - * @param {Object} properties The properties of the feature. - * @param {String} nameProperty The property key that Cesium estimates to have the name of the feature. - */ + }; - return GeoJsonDataSource; + return ArcGisMapServerImageryProvider; }); -define('DataSources/GeometryUpdater',[ - '../Core/defineProperties', - '../Core/DeveloperError' +define('Scene/Cesium3DTileColorBlendMode',[ + '../Core/freezeObject' ], function( - defineProperties, - DeveloperError) { + freezeObject) { 'use strict'; /** - * Defines the interface for a geometry updater. A GeometryUpdater maps - * geometry defined as part of a {@link Entity} into {@link Geometry} - * instances. These instances are then visualized by {@link GeometryVisualizer}. - * - * This type defines an interface and cannot be instantiated directly. - * - * @alias GeometryUpdater - * @constructor - * - * @param {Entity} entity The entity containing the geometry to be visualized. - * @param {Scene} scene The scene where visualization is taking place. + * Defines how per-feature colors set from the Cesium API or declarative styling blend with the source colors from + * the original feature, e.g. glTF material or per-point color in the tile. + * <p> + * When <code>REPLACE</code> or <code>MIX</code> are used and the source color is a glTF material, the technique must assign the + * <code>_3DTILESDIFFUSE</code> semantic to the diffuse color parameter. Otherwise only <code>HIGHLIGHT</code> is supported. + * </p> + * <p> + * A feature whose color evaluates to white (1.0, 1.0, 1.0) is always rendered without color blending, regardless of the + * tileset's color blend mode. + * </p> + * <pre><code> + * "techniques": { + * "technique0": { + * "parameters": { + * "diffuse": { + * "semantic": "_3DTILESDIFFUSE", + * "type": 35666 + * } + * } + * } + * } + * </code></pre> * - * @see EllipseGeometryUpdater - * @see EllipsoidGeometryUpdater - * @see PolygonGeometryUpdater - * @see PolylineGeometryUpdater - * @see RectangleGeometryUpdater - * @see WallGeometryUpdater + * @exports Cesium3DTileColorBlendMode */ - function GeometryUpdater(entity, scene) { - DeveloperError.throwInstantiationError(); - } - - defineProperties(GeometryUpdater, { - /** - * Gets the type of Appearance to use for simple color-based geometry. - * @memberof GeometryUpdater - * @type {Appearance} - */ - perInstanceColorAppearanceType : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the type of Appearance to use for material-based geometry. - * @memberof GeometryUpdater - * @type {Appearance} - */ - materialAppearanceType : { - get : DeveloperError.throwInstantiationError - } - }); - - defineProperties(GeometryUpdater.prototype, { - /** - * Gets the entity associated with this geometry. - * @memberof GeometryUpdater.prototype - * - * @type {Entity} - * @readonly - */ - entity : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets a value indicating if the geometry has a fill component. - * @memberof GeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - fillEnabled : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets a value indicating if fill visibility varies with simulation time. - * @memberof GeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantFill : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the material property used to fill the geometry. - * @memberof GeometryUpdater.prototype - * - * @type {MaterialProperty} - * @readonly - */ - fillMaterialProperty : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets a value indicating if the geometry has an outline component. - * @memberof GeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - outlineEnabled : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets a value indicating if outline visibility varies with simulation time. - * @memberof GeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - hasConstantOutline : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets the {@link Color} property for the geometry outline. - * @memberof GeometryUpdater.prototype - * - * @type {Property} - * @readonly - */ - outlineColorProperty : { - get : DeveloperError.throwInstantiationError - }, + var Cesium3DTileColorBlendMode = { /** - * Gets the constant with of the geometry outline, in pixels. - * This value is only valid if isDynamic is false. - * @memberof GeometryUpdater.prototype + * Multiplies the source color by the feature color. * * @type {Number} - * @readonly - */ - outlineWidth : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets a value indicating if the geometry is time-varying. - * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} - * returned by GeometryUpdater#createDynamicUpdater. - * @memberof GeometryUpdater.prototype - * - * @type {Boolean} - * @readonly - */ - isDynamic : { - get : DeveloperError.throwInstantiationError - }, - /** - * Gets a value indicating if the geometry is closed. - * This property is only valid for static geometry. - * @memberof GeometryUpdater.prototype - * - * @type {Boolean} - * @readonly + * @constant */ - isClosed : { - get : DeveloperError.throwInstantiationError - }, + HIGHLIGHT : 0, + /** - * Gets an event that is raised whenever the public properties - * of this updater change. - * @memberof GeometryUpdater.prototype + * Replaces the source color with the feature color. * - * @type {Boolean} - * @readonly - */ - geometryChanged : { - get : DeveloperError.throwInstantiationError - } - }); - - /** - * Checks if the geometry is outlined at the provided time. - * @function - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. - */ - GeometryUpdater.prototype.isOutlineVisible = DeveloperError.throwInstantiationError; - - /** - * Checks if the geometry is filled at the provided time. - * @function - * - * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. - */ - GeometryUpdater.prototype.isFilled = DeveloperError.throwInstantiationError; - - /** - * Creates the geometry instance which represents the fill of the geometry. - * @function - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent a filled geometry. - */ - GeometryUpdater.prototype.createFillGeometryInstance = DeveloperError.throwInstantiationError; - - /** - * Creates the geometry instance which represents the outline of the geometry. - * @function - * - * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. - * - * @exception {DeveloperError} This instance does not represent an outlined geometry. - */ - GeometryUpdater.prototype.createOutlineGeometryInstance = DeveloperError.throwInstantiationError; - - /** - * Returns true if this object was destroyed; otherwise, false. - * @function - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - */ - GeometryUpdater.prototype.isDestroyed = DeveloperError.throwInstantiationError; - - /** - * Destroys and resources used by the object. Once an object is destroyed, it should not be used. - * @function - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - GeometryUpdater.prototype.destroy = DeveloperError.throwInstantiationError; + * @type {Number} + * @constant + */ + REPLACE : 1, - /** - * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true. - * @function - * - * @param {PrimitiveCollection} primitives The primitive collection to use. - * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame. - * - * @exception {DeveloperError} This instance does not represent dynamic geometry. - */ - GeometryUpdater.prototype.createDynamicUpdater = DeveloperError.throwInstantiationError; + /** + * Blends the source color and feature color together. + * + * @type {Number} + * @constant + */ + MIX : 2 + }; - return GeometryUpdater; + return freezeObject(Cesium3DTileColorBlendMode); }); -define('DataSources/KmlCamera',[], function() { +define('Scene/getBinaryAccessor',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/ComponentDatatype', + '../Core/Matrix2', + '../Core/Matrix3', + '../Core/Matrix4' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + ComponentDatatype, + Matrix2, + Matrix3, + Matrix4) { 'use strict'; + + var ComponentsPerAttribute = { + SCALAR : 1, + VEC2 : 2, + VEC3 : 3, + VEC4 : 4, + MAT2 : 4, + MAT3 : 9, + MAT4 : 16 + }; + + var ClassPerType = { + SCALAR : undefined, + VEC2 : Cartesian2, + VEC3 : Cartesian3, + VEC4 : Cartesian4, + MAT2 : Matrix2, + MAT3 : Matrix3, + MAT4 : Matrix4 + }; + /** - * Representation of <Camera> from KML - * @alias KmlCamera - * @constructor - * - * @param {Cartesian3} position camera position - * @param {HeadingPitchRoll} headingPitchRoll camera orientation + * @private */ - function KmlCamera(position, headingPitchRoll) { - this.position = position; - this.headingPitchRoll = headingPitchRoll; + function getBinaryAccessor(accessor) { + var componentType = accessor.componentType; + var componentDatatype; + if (typeof componentType === 'string') { + componentDatatype = ComponentDatatype.fromName(componentType); + } else { + componentDatatype = componentType; + } + + var componentsPerAttribute = ComponentsPerAttribute[accessor.type]; + var classType = ClassPerType[accessor.type]; + return { + componentsPerAttribute : componentsPerAttribute, + classType : classType, + createArrayBufferView : function(buffer, byteOffset, length) { + return ComponentDatatype.createArrayBufferView(componentDatatype, buffer, byteOffset, componentsPerAttribute * length); + } + }; } - return KmlCamera; + return getBinaryAccessor; }); -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module unless amdModuleId is set - define('ThirdParty/Autolinker',[], function () { - return (root['Autolinker'] = factory()); - }); - } else if (typeof exports === 'object') { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - root['Autolinker'] = factory(); - } -}(this, function () { +define('Scene/Cesium3DTileBatchTable',[ + '../Core/arrayFill', + '../Core/Cartesian2', + '../Core/Cartesian4', + '../Core/Check', + '../Core/clone', + '../Core/Color', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Math', + '../Core/PixelFormat', + '../Core/RuntimeError', + '../Renderer/ContextLimits', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/Sampler', + '../Renderer/ShaderSource', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + './AttributeType', + './BlendingState', + './Cesium3DTileColorBlendMode', + './CullFace', + './getBinaryAccessor', + './StencilFunction', + './StencilOperation' + ], function( + arrayFill, + Cartesian2, + Cartesian4, + Check, + clone, + Color, + combine, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + CesiumMath, + PixelFormat, + RuntimeError, + ContextLimits, + DrawCommand, + Pass, + PixelDatatype, + RenderState, + Sampler, + ShaderSource, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter, + AttributeType, + BlendingState, + Cesium3DTileColorBlendMode, + CullFace, + getBinaryAccessor, + StencilFunction, + StencilOperation) { + 'use strict'; -/*! - * Autolinker.js - * 0.17.1 - * - * Copyright(c) 2015 Gregory Jacobs <greg@greg-jacobs.com> - * MIT Licensed. http://www.opensource.org/licenses/mit-license.php - * - * https://github.com/gregjacobs/Autolinker.js - */ -/** - * @class Autolinker - * @extends Object - * - * Utility class used to process a given string of text, and wrap the matches in - * the appropriate anchor (<a>) tags to turn them into links. - * - * Any of the configuration options may be provided in an Object (map) provided - * to the Autolinker constructor, which will configure how the {@link #link link()} - * method will process the links. - * - * For example: - * - * var autolinker = new Autolinker( { - * newWindow : false, - * truncate : 30 - * } ); - * - * var html = autolinker.link( "Joe went to www.yahoo.com" ); - * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>' - * - * - * The {@link #static-link static link()} method may also be used to inline options into a single call, which may - * be more convenient for one-off uses. For example: - * - * var html = Autolinker.link( "Joe went to www.yahoo.com", { - * newWindow : false, - * truncate : 30 - * } ); - * // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>' - * - * - * ## Custom Replacements of Links - * - * If the configuration options do not provide enough flexibility, a {@link #replaceFn} - * may be provided to fully customize the output of Autolinker. This function is - * called once for each URL/Email/Phone#/Twitter Handle/Hashtag match that is - * encountered. - * - * For example: - * - * var input = "..."; // string with URLs, Email Addresses, Phone #s, Twitter Handles, and Hashtags - * - * var linkedText = Autolinker.link( input, { - * replaceFn : function( autolinker, match ) { - * console.log( "href = ", match.getAnchorHref() ); - * console.log( "text = ", match.getAnchorText() ); - * - * switch( match.getType() ) { - * case 'url' : - * console.log( "url: ", match.getUrl() ); - * - * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) { - * var tag = autolinker.getTagBuilder().build( match ); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes - * tag.setAttr( 'rel', 'nofollow' ); - * tag.addClass( 'external-link' ); - * - * return tag; - * - * } else { - * return true; // let Autolinker perform its normal anchor tag replacement - * } - * - * case 'email' : - * var email = match.getEmail(); - * console.log( "email: ", email ); - * - * if( email === "my@own.address" ) { - * return false; // don't auto-link this particular email address; leave as-is - * } else { - * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`) - * } - * - * case 'phone' : - * var phoneNumber = match.getPhoneNumber(); - * console.log( phoneNumber ); - * - * return '<a href="http://newplace.to.link.phone.numbers.to/">' + phoneNumber + '</a>'; - * - * case 'twitter' : - * var twitterHandle = match.getTwitterHandle(); - * console.log( twitterHandle ); - * - * return '<a href="http://newplace.to.link.twitter.handles.to/">' + twitterHandle + '</a>'; - * - * case 'hashtag' : - * var hashtag = match.getHashtag(); - * console.log( hashtag ); - * - * return '<a href="http://newplace.to.link.hashtag.handles.to/">' + hashtag + '</a>'; - * } - * } - * } ); - * - * - * The function may return the following values: - * - * - `true` (Boolean): Allow Autolinker to replace the match as it normally would. - * - `false` (Boolean): Do not replace the current match at all - leave as-is. - * - Any String: If a string is returned from the function, the string will be used directly as the replacement HTML for - * the match. - * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify an HTML tag before writing out its HTML text. - * - * @constructor - * @param {Object} [config] The configuration options for the Autolinker instance, specified in an Object (map). - */ -var Autolinker = function( cfg ) { - Autolinker.Util.assign( this, cfg ); // assign the properties of `cfg` onto the Autolinker instance. Prototype properties will be used for missing configs. + var DEFAULT_COLOR_VALUE = Color.WHITE; + var DEFAULT_SHOW_VALUE = true; - // Validate the value of the `hashtag` cfg. - var hashtag = this.hashtag; - if( hashtag !== false && hashtag !== 'twitter' && hashtag !== 'facebook' ) { - throw new Error( "invalid `hashtag` cfg - see docs" ); - } -}; + /** + * @private + */ + function Cesium3DTileBatchTable(content, featuresLength, batchTableJson, batchTableBinary, colorChangedCallback) { + /** + * @readonly + */ + this.featuresLength = featuresLength; -Autolinker.prototype = { - constructor : Autolinker, // fix constructor property + this._translucentFeaturesLength = 0; // Number of features in the tile that are translucent - /** - * @cfg {Boolean} urls - * - * `true` if miscellaneous URLs should be automatically linked, `false` if they should not be. - */ - urls : true, + /** + * @private + */ + this.batchTableJson = batchTableJson; - /** - * @cfg {Boolean} email - * - * `true` if email addresses should be automatically linked, `false` if they should not be. - */ - email : true, + /** + * @private + */ + this.batchTableBinary = batchTableBinary; - /** - * @cfg {Boolean} twitter - * - * `true` if Twitter handles ("@example") should be automatically linked, `false` if they should not be. - */ - twitter : true, + var batchTableHierarchy; + var batchTableBinaryProperties; + if (defined(batchTableJson)) { + // Extract the hierarchy and remove it from the batch table json + batchTableHierarchy = batchTableJson.HIERARCHY; + if (defined(batchTableHierarchy)) { + delete batchTableJson.HIERARCHY; + batchTableHierarchy = initializeHierarchy(batchTableHierarchy, batchTableBinary); + } + // Get the binary properties + batchTableBinaryProperties = Cesium3DTileBatchTable.getBinaryProperties(featuresLength, batchTableJson, batchTableBinary); + } - /** - * @cfg {Boolean} phone - * - * `true` if Phone numbers ("(555)555-5555") should be automatically linked, `false` if they should not be. - */ - phone: true, + this._batchTableHierarchy = batchTableHierarchy; + this._batchTableBinaryProperties = batchTableBinaryProperties; - /** - * @cfg {Boolean/String} hashtag - * - * A string for the service name to have hashtags (ex: "#myHashtag") - * auto-linked to. The currently-supported values are: - * - * - 'twitter' - * - 'facebook' - * - * Pass `false` to skip auto-linking of hashtags. - */ - hashtag : false, + // PERFORMANCE_IDEA: These parallel arrays probably generate cache misses in get/set color/show + // and use A LOT of memory. How can we use less memory? + this._showAlphaProperties = undefined; // [Show (0 or 255), Alpha (0 to 255)] property for each feature + this._batchValues = undefined; // Per-feature RGBA (A is based on the color's alpha and feature's show property) - /** - * @cfg {Boolean} newWindow - * - * `true` if the links should open in a new window, `false` otherwise. - */ - newWindow : true, + this._batchValuesDirty = false; + this._batchTexture = undefined; + this._defaultTexture = undefined; - /** - * @cfg {Boolean} stripPrefix - * - * `true` if 'http://' or 'https://' and/or the 'www.' should be stripped - * from the beginning of URL links' text, `false` otherwise. - */ - stripPrefix : true, + this._pickTexture = undefined; + this._pickIds = []; - /** - * @cfg {Number} truncate - * - * A number for how many characters long matched text should be truncated to inside the text of - * a link. If the matched text is over this number of characters, it will be truncated to this length by - * adding a two period ellipsis ('..') to the end of the string. - * - * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file' truncated to 25 characters might look - * something like this: 'yahoo.com/some/long/pat..' - */ - truncate : undefined, + this._content = content; - /** - * @cfg {String} className - * - * A CSS class name to add to the generated links. This class will be added to all links, as well as this class - * plus match suffixes for styling url/email/phone/twitter/hashtag links differently. - * - * For example, if this config is provided as "myLink", then: - * - * - URL links will have the CSS classes: "myLink myLink-url" - * - Email links will have the CSS classes: "myLink myLink-email", and - * - Twitter links will have the CSS classes: "myLink myLink-twitter" - * - Phone links will have the CSS classes: "myLink myLink-phone" - * - Hashtag links will have the CSS classes: "myLink myLink-hashtag" - */ - className : "", + this._colorChangedCallback = colorChangedCallback; - /** - * @cfg {Function} replaceFn - * - * A function to individually process each match found in the input string. - * - * See the class's description for usage. - * - * This function is called with the following parameters: - * - * @cfg {Autolinker} replaceFn.autolinker The Autolinker instance, which may be used to retrieve child objects from (such - * as the instance's {@link #getTagBuilder tag builder}). - * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which can be used to retrieve information about the - * match that the `replaceFn` is currently processing. See {@link Autolinker.match.Match} subclasses for details. - */ + // Dimensions for batch and pick textures + var textureDimensions; + var textureStep; + if (featuresLength > 0) { + // PERFORMANCE_IDEA: this can waste memory in the last row in the uncommon case + // when more than one row is needed (e.g., > 16K features in one tile) + var width = Math.min(featuresLength, ContextLimits.maximumTextureSize); + var height = Math.ceil(featuresLength / ContextLimits.maximumTextureSize); + var stepX = 1.0 / width; + var centerX = stepX * 0.5; + var stepY = 1.0 / height; + var centerY = stepY * 0.5; - /** - * @private - * @property {Autolinker.htmlParser.HtmlParser} htmlParser - * - * The HtmlParser instance used to skip over HTML tags, while finding text nodes to process. This is lazily instantiated - * in the {@link #getHtmlParser} method. - */ - htmlParser : undefined, + textureDimensions = new Cartesian2(width, height); + textureStep = new Cartesian4(stepX, centerX, stepY, centerY); + } - /** - * @private - * @property {Autolinker.matchParser.MatchParser} matchParser - * - * The MatchParser instance used to find matches in the text nodes of an input string passed to - * {@link #link}. This is lazily instantiated in the {@link #getMatchParser} method. - */ - matchParser : undefined, + this._textureDimensions = textureDimensions; + this._textureStep = textureStep; + } - /** - * @private - * @property {Autolinker.AnchorTagBuilder} tagBuilder - * - * The AnchorTagBuilder instance used to build match replacement anchor tags. Note: this is lazily instantiated - * in the {@link #getTagBuilder} method. - */ - tagBuilder : undefined, + defineProperties(Cesium3DTileBatchTable.prototype, { + memorySizeInBytes : { + get : function() { + var memory = 0; + if (defined(this._pickTexture)) { + memory += this._pickTexture.sizeInBytes; + } + if (defined(this._batchTexture)) { + memory += this._batchTexture.sizeInBytes; + } + return memory; + } + } + }); - /** - * Automatically links URLs, Email addresses, Phone numbers, Twitter - * handles, and Hashtags found in the given chunk of HTML. Does not link - * URLs found within HTML tags. - * - * For instance, if given the text: `You should go to http://www.yahoo.com`, - * then the result will be `You should go to - * <a href="http://www.yahoo.com">http://www.yahoo.com</a>` - * - * This method finds the text around any HTML elements in the input - * `textOrHtml`, which will be the text that is processed. Any original HTML - * elements will be left as-is, as well as the text that is already wrapped - * in anchor (<a>) tags. - * - * @param {String} textOrHtml The HTML or text to autolink matches within - * (depending on if the {@link #urls}, {@link #email}, {@link #phone}, - * {@link #twitter}, and {@link #hashtag} options are enabled). - * @return {String} The HTML, with matches automatically linked. - */ - link : function( textOrHtml ) { - var htmlParser = this.getHtmlParser(), - htmlNodes = htmlParser.parse( textOrHtml ), - anchorTagStackCount = 0, // used to only process text around anchor tags, and any inner text/html they may have - resultHtml = []; + function initializeHierarchy(json, binary) { + var i; + var classId; + var binaryAccessor; - for( var i = 0, len = htmlNodes.length; i < len; i++ ) { - var node = htmlNodes[ i ], - nodeType = node.getType(), - nodeText = node.getText(); + var instancesLength = json.instancesLength; + var classes = json.classes; + var classIds = json.classIds; + var parentCounts = json.parentCounts; + var parentIds = json.parentIds; + var parentIdsLength = instancesLength; - if( nodeType === 'element' ) { - // Process HTML nodes in the input `textOrHtml` - if( node.getTagName() === 'a' ) { - if( !node.isClosing() ) { // it's the start <a> tag - anchorTagStackCount++; - } else { // it's the end </a> tag - anchorTagStackCount = Math.max( anchorTagStackCount - 1, 0 ); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0 - } - } - resultHtml.push( nodeText ); // now add the text of the tag itself verbatim + if (defined(classIds.byteOffset)) { + classIds.componentType = defaultValue(classIds.componentType, ComponentDatatype.UNSIGNED_SHORT); + classIds.type = AttributeType.SCALAR; + binaryAccessor = getBinaryAccessor(classIds); + classIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + classIds.byteOffset, instancesLength); + } - } else if( nodeType === 'entity' || nodeType === 'comment' ) { - resultHtml.push( nodeText ); // append HTML entity nodes (such as ' ') or HTML comments (such as '<!-- Comment -->') verbatim + var parentIndexes; + if (defined(parentCounts)) { + if (defined(parentCounts.byteOffset)) { + parentCounts.componentType = defaultValue(parentCounts.componentType, ComponentDatatype.UNSIGNED_SHORT); + parentCounts.type = AttributeType.SCALAR; + binaryAccessor = getBinaryAccessor(parentCounts); + parentCounts = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentCounts.byteOffset, instancesLength); + } + parentIndexes = new Uint16Array(instancesLength); + parentIdsLength = 0; + for (i = 0; i < instancesLength; ++i) { + parentIndexes[i] = parentIdsLength; + parentIdsLength += parentCounts[i]; + } + } - } else { - // Process text nodes in the input `textOrHtml` - if( anchorTagStackCount === 0 ) { - // If we're not within an <a> tag, process the text node to linkify - var linkifiedStr = this.linkifyStr( nodeText ); - resultHtml.push( linkifiedStr ); + if (defined(parentIds) && defined(parentIds.byteOffset)) { + parentIds.componentType = defaultValue(parentIds.componentType, ComponentDatatype.UNSIGNED_SHORT); + parentIds.type = AttributeType.SCALAR; + binaryAccessor = getBinaryAccessor(parentIds); + parentIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentIds.byteOffset, parentIdsLength); + } - } else { - // `text` is within an <a> tag, simply append the text - we do not want to autolink anything - // already within an <a>...</a> tag - resultHtml.push( nodeText ); - } - } - } + var classesLength = classes.length; + for (i = 0; i < classesLength; ++i) { + var classInstancesLength = classes[i].length; + var properties = classes[i].instances; + var binaryProperties = Cesium3DTileBatchTable.getBinaryProperties(classInstancesLength, properties, binary); + classes[i].instances = combine(binaryProperties, properties); + } - return resultHtml.join( "" ); - }, + var classCounts = arrayFill(new Array(classesLength), 0); + var classIndexes = new Uint16Array(instancesLength); + for (i = 0; i < instancesLength; ++i) { + classId = classIds[i]; + classIndexes[i] = classCounts[classId]; + ++classCounts[classId]; + } - /** - * Process the text that lies in between HTML tags, performing the anchor - * tag replacements for the matches, and returns the string with the - * replacements made. - * - * This method does the actual wrapping of matches with anchor tags. - * - * @private - * @param {String} str The string of text to auto-link. - * @return {String} The text with anchor tags auto-filled. - */ - linkifyStr : function( str ) { - return this.getMatchParser().replace( str, this.createMatchReturnVal, this ); - }, + var hierarchy = { + classes : classes, + classIds : classIds, + classIndexes : classIndexes, + parentCounts : parentCounts, + parentIndexes : parentIndexes, + parentIds : parentIds + }; + validateHierarchy(hierarchy); + + return hierarchy; + } - /** - * Creates the return string value for a given match in the input string, - * for the {@link #linkifyStr} method. - * - * This method handles the {@link #replaceFn}, if one was provided. - * - * @private - * @param {Autolinker.match.Match} match The Match object that represents the match. - * @return {String} The string that the `match` should be replaced with. This is usually the anchor tag string, but - * may be the `matchStr` itself if the match is not to be replaced. - */ - createMatchReturnVal : function( match ) { - // Handle a custom `replaceFn` being provided - var replaceFnResult; - if( this.replaceFn ) { - replaceFnResult = this.replaceFn.call( this, this, match ); // Autolinker instance is the context, and the first arg - } + var scratchValidateStack = []; + function validateHierarchy(hierarchy) { + var stack = scratchValidateStack; + stack.length = 0; - if( typeof replaceFnResult === 'string' ) { - return replaceFnResult; // `replaceFn` returned a string, use that + var classIds = hierarchy.classIds; + var instancesLength = classIds.length; - } else if( replaceFnResult === false ) { - return match.getMatchedText(); // no replacement for the match + for (var i = 0; i < instancesLength; ++i) { + validateInstance(hierarchy, i, stack); + } + } - } else if( replaceFnResult instanceof Autolinker.HtmlTag ) { - return replaceFnResult.toAnchorString(); + function validateInstance(hierarchy, instanceIndex, stack) { + var parentCounts = hierarchy.parentCounts; + var parentIds = hierarchy.parentIds; + var parentIndexes = hierarchy.parentIndexes; + var classIds = hierarchy.classIds; + var instancesLength = classIds.length; - } else { // replaceFnResult === true, or no/unknown return value from function - // Perform Autolinker's default anchor tag generation - var tagBuilder = this.getTagBuilder(), - anchorTag = tagBuilder.build( match ); // returns an Autolinker.HtmlTag instance + if (!defined(parentIds)) { + // No need to validate if there are no parents + return; + } - return anchorTag.toAnchorString(); - } - }, + if (instanceIndex >= instancesLength) { + throw new DeveloperError('Parent index ' + instanceIndex + ' exceeds the total number of instances: ' + instancesLength); + } + if (stack.indexOf(instanceIndex) > -1) { + throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); + } + stack.push(instanceIndex); + var parentCount = defined(parentCounts) ? parentCounts[instanceIndex] : 1; + var parentIndex = defined(parentCounts) ? parentIndexes[instanceIndex] : instanceIndex; + for (var i = 0; i < parentCount; ++i) { + var parentId = parentIds[parentIndex + i]; + // Stop the traversal when the instance has no parent (its parentId equals itself), else continue the traversal. + if (parentId !== instanceIndex) { + validateInstance(hierarchy, parentId, stack); + } + } + stack.pop(instanceIndex); + } + + Cesium3DTileBatchTable.getBinaryProperties = function(featuresLength, json, binary) { + var binaryProperties; + for (var name in json) { + if (json.hasOwnProperty(name)) { + var property = json[name]; + var byteOffset = property.byteOffset; + if (defined(byteOffset)) { + // This is a binary property + var componentType = property.componentType; + var type = property.type; + if (!defined(componentType)) { + throw new RuntimeError('componentType is required.'); + } + if (!defined(type)) { + throw new RuntimeError('type is required.'); + } + if (!defined(binary)) { + throw new RuntimeError('Property ' + name + ' requires a batch table binary.'); + } - /** - * Lazily instantiates and returns the {@link #htmlParser} instance for this Autolinker instance. - * - * @protected - * @return {Autolinker.htmlParser.HtmlParser} - */ - getHtmlParser : function() { - var htmlParser = this.htmlParser; + var binaryAccessor = getBinaryAccessor(property); + var componentCount = binaryAccessor.componentsPerAttribute; + var classType = binaryAccessor.classType; + var typedArray = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + byteOffset, featuresLength); - if( !htmlParser ) { - htmlParser = this.htmlParser = new Autolinker.htmlParser.HtmlParser(); - } + if (!defined(binaryProperties)) { + binaryProperties = {}; + } - return htmlParser; - }, + // Store any information needed to access the binary data, including the typed array, + // componentCount (e.g. a VEC4 would be 4), and the type used to pack and unpack (e.g. Cartesian4). + binaryProperties[name] = { + typedArray : typedArray, + componentCount : componentCount, + type : classType + }; + } + } + } + return binaryProperties; + }; + function getByteLength(batchTable) { + var dimensions = batchTable._textureDimensions; + return (dimensions.x * dimensions.y) * 4; + } - /** - * Lazily instantiates and returns the {@link #matchParser} instance for this Autolinker instance. - * - * @protected - * @return {Autolinker.matchParser.MatchParser} - */ - getMatchParser : function() { - var matchParser = this.matchParser; + function getBatchValues(batchTable) { + if (!defined(batchTable._batchValues)) { + // Default batch texture to RGBA = 255: white highlight (RGB) and show/alpha = true/255 (A). + var byteLength = getByteLength(batchTable); + var bytes = new Uint8Array(byteLength); + arrayFill(bytes, 255); + batchTable._batchValues = bytes; + } - if( !matchParser ) { - matchParser = this.matchParser = new Autolinker.matchParser.MatchParser( { - urls : this.urls, - email : this.email, - twitter : this.twitter, - phone : this.phone, - hashtag : this.hashtag, - stripPrefix : this.stripPrefix - } ); - } + return batchTable._batchValues; + } - return matchParser; - }, + function getShowAlphaProperties(batchTable) { + if (!defined(batchTable._showAlphaProperties)) { + var byteLength = 2 * batchTable.featuresLength; + var bytes = new Uint8Array(byteLength); + // [Show = true, Alpha = 255] + arrayFill(bytes, 255); + batchTable._showAlphaProperties = bytes; + } + return batchTable._showAlphaProperties; + } + function checkBatchId(batchId, featuresLength) { + if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); + } + } - /** - * Returns the {@link #tagBuilder} instance for this Autolinker instance, lazily instantiating it - * if it does not yet exist. - * - * This method may be used in a {@link #replaceFn} to generate the {@link Autolinker.HtmlTag HtmlTag} instance that - * Autolinker would normally generate, and then allow for modifications before returning it. For example: - * - * var html = Autolinker.link( "Test google.com", { - * replaceFn : function( autolinker, match ) { - * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance - * tag.setAttr( 'rel', 'nofollow' ); - * - * return tag; - * } - * } ); - * - * // generated html: - * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a> - * - * @return {Autolinker.AnchorTagBuilder} - */ - getTagBuilder : function() { - var tagBuilder = this.tagBuilder; + Cesium3DTileBatchTable.prototype.setShow = function(batchId, show) { + checkBatchId(batchId, this.featuresLength); + Check.typeOf.bool('show', show); + + if (show && !defined(this._showAlphaProperties)) { + // Avoid allocating since the default is show = true + return; + } - if( !tagBuilder ) { - tagBuilder = this.tagBuilder = new Autolinker.AnchorTagBuilder( { - newWindow : this.newWindow, - truncate : this.truncate, - className : this.className - } ); - } + var showAlphaProperties = getShowAlphaProperties(this); + var propertyOffset = batchId * 2; - return tagBuilder; - } + var newShow = show ? 255 : 0; + if (showAlphaProperties[propertyOffset] !== newShow) { + showAlphaProperties[propertyOffset] = newShow; -}; + var batchValues = getBatchValues(this); + // Compute alpha used in the shader based on show and color.alpha properties + var offset = (batchId * 4) + 3; + batchValues[offset] = show ? showAlphaProperties[propertyOffset + 1] : 0; -/** - * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles, - * and Hashtags found in the given chunk of HTML. Does not link URLs found - * within HTML tags. - * - * For instance, if given the text: `You should go to http://www.yahoo.com`, - * then the result will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>` - * - * Example: - * - * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } ); - * // Produces: "Go to <a href="http://google.com">google.com</a>" - * - * @static - * @param {String} textOrHtml The HTML or text to find matches within (depending - * on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #twitter}, - * and {@link #hashtag} options are enabled). - * @param {Object} [options] Any of the configuration options for the Autolinker - * class, specified in an Object (map). See the class description for an - * example call. - * @return {String} The HTML text, with matches automatically linked. - */ -Autolinker.link = function( textOrHtml, options ) { - var autolinker = new Autolinker( options ); - return autolinker.link( textOrHtml ); -}; + this._batchValuesDirty = true; + } + }; + Cesium3DTileBatchTable.prototype.setAllShow = function(show) { + Check.typeOf.bool('show', show); + + var featuresLength = this.featuresLength; + for (var i = 0; i < featuresLength; ++i) { + this.setShow(i, show); + } + }; -// Autolinker Namespaces -Autolinker.match = {}; -Autolinker.htmlParser = {}; -Autolinker.matchParser = {}; + Cesium3DTileBatchTable.prototype.getShow = function(batchId) { + checkBatchId(batchId, this.featuresLength); + + if (!defined(this._showAlphaProperties)) { + // Avoid allocating since the default is show = true + return true; + } -/*global Autolinker */ -/*jshint eqnull:true, boss:true */ -/** - * @class Autolinker.Util - * @singleton - * - * A few utility methods for Autolinker. - */ -Autolinker.Util = { + var offset = batchId * 2; + return (this._showAlphaProperties[offset] === 255); + }; - /** - * @property {Function} abstractMethod - * - * A function object which represents an abstract method. - */ - abstractMethod : function() { throw "abstract"; }, + var scratchColorBytes = new Array(4); + Cesium3DTileBatchTable.prototype.setColor = function(batchId, color) { + checkBatchId(batchId, this.featuresLength); + Check.typeOf.object('color', color); + + if (Color.equals(color, DEFAULT_COLOR_VALUE) && !defined(this._batchValues)) { + // Avoid allocating since the default is white + return; + } - /** - * @private - * @property {RegExp} trimRegex - * - * The regular expression used to trim the leading and trailing whitespace - * from a string. - */ - trimRegex : /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + var newColor = color.toBytes(scratchColorBytes); + var newAlpha = newColor[3]; + var batchValues = getBatchValues(this); + var offset = batchId * 4; - /** - * Assigns (shallow copies) the properties of `src` onto `dest`. - * - * @param {Object} dest The destination object. - * @param {Object} src The source object. - * @return {Object} The destination object (`dest`) - */ - assign : function( dest, src ) { - for( var prop in src ) { - if( src.hasOwnProperty( prop ) ) { - dest[ prop ] = src[ prop ]; - } - } + var showAlphaProperties = getShowAlphaProperties(this); + var propertyOffset = batchId * 2; - return dest; - }, + if ((batchValues[offset] !== newColor[0]) || + (batchValues[offset + 1] !== newColor[1]) || + (batchValues[offset + 2] !== newColor[2]) || + (showAlphaProperties[propertyOffset + 1] !== newAlpha)) { + batchValues[offset] = newColor[0]; + batchValues[offset + 1] = newColor[1]; + batchValues[offset + 2] = newColor[2]; - /** - * Extends `superclass` to create a new subclass, adding the `protoProps` to the new subclass's prototype. - * - * @param {Function} superclass The constructor function for the superclass. - * @param {Object} protoProps The methods/properties to add to the subclass's prototype. This may contain the - * special property `constructor`, which will be used as the new subclass's constructor function. - * @return {Function} The new subclass function. - */ - extend : function( superclass, protoProps ) { - var superclassProto = superclass.prototype; + var wasTranslucent = (showAlphaProperties[propertyOffset + 1] !== 255); - var F = function() {}; - F.prototype = superclassProto; + // Compute alpha used in the shader based on show and color.alpha properties + var show = showAlphaProperties[propertyOffset] !== 0; + batchValues[offset + 3] = show ? newAlpha : 0; + showAlphaProperties[propertyOffset + 1] = newAlpha; - var subclass; - if( protoProps.hasOwnProperty( 'constructor' ) ) { - subclass = protoProps.constructor; - } else { - subclass = function() { superclassProto.constructor.apply( this, arguments ); }; - } + // Track number of translucent features so we know if this tile needs + // opaque commands, translucent commands, or both for rendering. + var isTranslucent = (newAlpha !== 255); + if (isTranslucent && !wasTranslucent) { + ++this._translucentFeaturesLength; + } else if (!isTranslucent && wasTranslucent) { + --this._translucentFeaturesLength; + } - var subclassProto = subclass.prototype = new F(); // set up prototype chain - subclassProto.constructor = subclass; // fix constructor property - subclassProto.superclass = superclassProto; + this._batchValuesDirty = true; - delete protoProps.constructor; // don't re-assign constructor property to the prototype, since a new function may have been created (`subclass`), which is now already there - Autolinker.Util.assign( subclassProto, protoProps ); + if (defined(this._colorChangedCallback)) { + this._colorChangedCallback(batchId, color); + } + } + }; - return subclass; - }, + Cesium3DTileBatchTable.prototype.setAllColor = function(color) { + Check.typeOf.object('color', color); + + var featuresLength = this.featuresLength; + for (var i = 0; i < featuresLength; ++i) { + this.setColor(i, color); + } + }; + Cesium3DTileBatchTable.prototype.getColor = function(batchId, result) { + checkBatchId(batchId, this.featuresLength); + Check.typeOf.object('result', result); + + if (!defined(this._batchValues)) { + return Color.clone(DEFAULT_COLOR_VALUE, result); + } - /** - * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the - * end of the string (by default, two periods: '..'). If the `str` length does not exceed - * `len`, the string will be returned unchanged. - * - * @param {String} str The string to truncate and add an ellipsis to. - * @param {Number} truncateLen The length to truncate the string at. - * @param {String} [ellipsisChars=..] The ellipsis character(s) to add to the end of `str` - * when truncated. Defaults to '..' - */ - ellipsis : function( str, truncateLen, ellipsisChars ) { - if( str.length > truncateLen ) { - ellipsisChars = ( ellipsisChars == null ) ? '..' : ellipsisChars; - str = str.substring( 0, truncateLen - ellipsisChars.length ) + ellipsisChars; - } - return str; - }, + var batchValues = this._batchValues; + var offset = batchId * 4; + var showAlphaProperties = this._showAlphaProperties; + var propertyOffset = batchId * 2; - /** - * Supports `Array.prototype.indexOf()` functionality for old IE (IE8 and below). - * - * @param {Array} arr The array to find an element of. - * @param {*} element The element to find in the array, and return the index of. - * @return {Number} The index of the `element`, or -1 if it was not found. - */ - indexOf : function( arr, element ) { - if( Array.prototype.indexOf ) { - return arr.indexOf( element ); + return Color.fromBytes(batchValues[offset], + batchValues[offset + 1], + batchValues[offset + 2], + showAlphaProperties[propertyOffset + 1], + result); + }; - } else { - for( var i = 0, len = arr.length; i < len; i++ ) { - if( arr[ i ] === element ) return i; - } - return -1; - } - }, + var scratchColor = new Color(); + Cesium3DTileBatchTable.prototype.applyStyle = function(frameState, style) { + if (!defined(style)) { + this.setAllColor(DEFAULT_COLOR_VALUE); + this.setAllShow(true); + return; + } + var content = this._content; + var length = this.featuresLength; + for (var i = 0; i < length; ++i) { + var feature = content.getFeature(i); + var color = defined(style.color) ? style.color.evaluateColor(frameState, feature, scratchColor) : DEFAULT_COLOR_VALUE; + var show = defined(style.show) ? style.show.evaluate(frameState, feature) : DEFAULT_SHOW_VALUE; + this.setColor(i, color); + this.setShow(i, show); + } + }; - /** - * Performs the functionality of what modern browsers do when `String.prototype.split()` is called - * with a regular expression that contains capturing parenthesis. - * - * For example: - * - * // Modern browsers: - * "a,b,c".split( /(,)/ ); // --> [ 'a', ',', 'b', ',', 'c' ] - * - * // Old IE (including IE8): - * "a,b,c".split( /(,)/ ); // --> [ 'a', 'b', 'c' ] - * - * This method emulates the functionality of modern browsers for the old IE case. - * - * @param {String} str The string to split. - * @param {RegExp} splitRegex The regular expression to split the input `str` on. The splitting - * character(s) will be spliced into the array, as in the "modern browsers" example in the - * description of this method. - * Note #1: the supplied regular expression **must** have the 'g' flag specified. - * Note #2: for simplicity's sake, the regular expression does not need - * to contain capturing parenthesis - it will be assumed that any match has them. - * @return {String[]} The split array of strings, with the splitting character(s) included. - */ - splitAndCapture : function( str, splitRegex ) { - if( !splitRegex.global ) throw new Error( "`splitRegex` must have the 'g' flag set" ); + function getBinaryProperty(binaryProperty, index) { + var typedArray = binaryProperty.typedArray; + var componentCount = binaryProperty.componentCount; + if (componentCount === 1) { + return typedArray[index]; + } + return binaryProperty.type.unpack(typedArray, index * componentCount); + } - var result = [], - lastIdx = 0, - match; + function setBinaryProperty(binaryProperty, index, value) { + var typedArray = binaryProperty.typedArray; + var componentCount = binaryProperty.componentCount; + if (componentCount === 1) { + typedArray[index] = value; + } else { + binaryProperty.type.pack(value, typedArray, index * componentCount); + } + } - while( match = splitRegex.exec( str ) ) { - result.push( str.substring( lastIdx, match.index ) ); - result.push( match[ 0 ] ); // push the splitting char(s) + // The size of this array equals the maximum instance count among all loaded tiles, which has the potential to be large. + var scratchVisited = []; + var scratchStack = []; + var marker = 0; + function traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback) { + var classIds = hierarchy.classIds; + var parentCounts = hierarchy.parentCounts; + var parentIds = hierarchy.parentIds; + var parentIndexes = hierarchy.parentIndexes; + var instancesLength = classIds.length; - lastIdx = match.index + match[ 0 ].length; - } - result.push( str.substring( lastIdx ) ); + // Ignore instances that have already been visited. This occurs in diamond inheritance situations. + // Use a marker value to indicate that an instance has been visited, which increments with each run. + // This is more efficient than clearing the visited array every time. + var visited = scratchVisited; + visited.length = Math.max(visited.length, instancesLength); + var visitedMarker = ++marker; - return result; - }, + var stack = scratchStack; + stack.length = 0; + stack.push(instanceIndex); + while (stack.length > 0) { + instanceIndex = stack.pop(); + if (visited[instanceIndex] === visitedMarker) { + // This instance has already been visited, stop traversal + continue; + } + visited[instanceIndex] = visitedMarker; + var result = endConditionCallback(hierarchy, instanceIndex); + if (defined(result)) { + // The end condition was met, stop the traversal and return the result + return result; + } + var parentCount = parentCounts[instanceIndex]; + var parentIndex = parentIndexes[instanceIndex]; + for (var i = 0; i < parentCount; ++i) { + var parentId = parentIds[parentIndex + i]; + // Stop the traversal when the instance has no parent (its parentId equals itself) + // else add the parent to the stack to continue the traversal. + if (parentId !== instanceIndex) { + stack.push(parentId); + } + } + } + } - /** - * Trims the leading and trailing whitespace from a string. - * - * @param {String} str The string to trim. - * @return {String} - */ - trim : function( str ) { - return str.replace( this.trimRegex, '' ); - } + function traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback) { + var hasParent = true; + while (hasParent) { + var result = endConditionCallback(hierarchy, instanceIndex); + if (defined(result)) { + // The end condition was met, stop the traversal and return the result + return result; + } + var parentId = hierarchy.parentIds[instanceIndex]; + hasParent = parentId !== instanceIndex; + instanceIndex = parentId; + } + } -}; -/*global Autolinker */ -/*jshint boss:true */ -/** - * @class Autolinker.HtmlTag - * @extends Object - * - * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically. - * - * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use - * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}. - * - * ## Examples - * - * Example instantiation: - * - * var tag = new Autolinker.HtmlTag( { - * tagName : 'a', - * attrs : { 'href': 'http://google.com', 'class': 'external-link' }, - * innerHtml : 'Google' - * } ); - * - * tag.toAnchorString(); // <a href="http://google.com" class="external-link">Google</a> - * - * // Individual accessor methods - * tag.getTagName(); // 'a' - * tag.getAttr( 'href' ); // 'http://google.com' - * tag.hasClass( 'external-link' ); // true - * - * - * Using mutator methods (which may be used in combination with instantiation config properties): - * - * var tag = new Autolinker.HtmlTag(); - * tag.setTagName( 'a' ); - * tag.setAttr( 'href', 'http://google.com' ); - * tag.addClass( 'external-link' ); - * tag.setInnerHtml( 'Google' ); - * - * tag.getTagName(); // 'a' - * tag.getAttr( 'href' ); // 'http://google.com' - * tag.hasClass( 'external-link' ); // true - * - * tag.toAnchorString(); // <a href="http://google.com" class="external-link">Google</a> - * - * - * ## Example use within a {@link Autolinker#replaceFn replaceFn} - * - * var html = Autolinker.link( "Test google.com", { - * replaceFn : function( autolinker, match ) { - * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text - * tag.setAttr( 'rel', 'nofollow' ); - * - * return tag; - * } - * } ); - * - * // generated html: - * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a> - * - * - * ## Example use with a new tag for the replacement - * - * var html = Autolinker.link( "Test google.com", { - * replaceFn : function( autolinker, match ) { - * var tag = new Autolinker.HtmlTag( { - * tagName : 'button', - * attrs : { 'title': 'Load URL: ' + match.getAnchorHref() }, - * innerHtml : 'Load URL: ' + match.getAnchorText() - * } ); - * - * return tag; - * } - * } ); - * - * // generated html: - * // Test <button title="Load URL: http://google.com">Load URL: google.com</button> - */ -Autolinker.HtmlTag = Autolinker.Util.extend( Object, { + function traverseHierarchy(hierarchy, instanceIndex, endConditionCallback) { + // Traverse over the hierarchy and process each instance with the endConditionCallback. + // When the endConditionCallback returns a value, the traversal stops and that value is returned. + var parentCounts = hierarchy.parentCounts; + var parentIds = hierarchy.parentIds; + if (!defined(parentIds)) { + return endConditionCallback(hierarchy, instanceIndex); + } else if (defined(parentCounts)) { + return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); + } + return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); + } - /** - * @cfg {String} tagName - * - * The tag name. Ex: 'a', 'button', etc. - * - * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toAnchorString} - * is executed. - */ + function hasPropertyInHierarchy(batchTable, batchId, name) { + var hierarchy = batchTable._batchTableHierarchy; + var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instances = hierarchy.classes[classId].instances; + if (defined(instances[name])) { + return true; + } + }); + return defined(result); + } - /** - * @cfg {Object.<String, String>} attrs - * - * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the - * values are the attribute values. - */ + function getPropertyNamesInHierarchy(batchTable, batchId, results) { + var hierarchy = batchTable._batchTableHierarchy; + traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instances = hierarchy.classes[classId].instances; + for (var name in instances) { + if (instances.hasOwnProperty(name)) { + if (results.indexOf(name) === -1) { + results.push(name); + } + } + } + }); + } - /** - * @cfg {String} innerHtml - * - * The inner HTML for the tag. - * - * Note the camel case name on `innerHtml`. Acronyms are camelCased in this utility (such as not to run into the acronym - * naming inconsistency that the DOM developers created with `XMLHttpRequest`). You may alternatively use {@link #innerHTML} - * if you prefer, but this one is recommended. - */ + function getHierarchyProperty(batchTable, batchId, name) { + var hierarchy = batchTable._batchTableHierarchy; + return traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + var indexInClass = hierarchy.classIndexes[instanceIndex]; + var propertyValues = instanceClass.instances[name]; + if (defined(propertyValues)) { + if (defined(propertyValues.typedArray)) { + return getBinaryProperty(propertyValues, indexInClass); + } + return clone(propertyValues[indexInClass], true); + } + }); + } - /** - * @cfg {String} innerHTML - * - * Alias of {@link #innerHtml}, accepted for consistency with the browser DOM api, but prefer the camelCased version - * for acronym names. - */ + function setHierarchyProperty(batchTable, batchId, name, value) { + var hierarchy = batchTable._batchTableHierarchy; + var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + var indexInClass = hierarchy.classIndexes[instanceIndex]; + var propertyValues = instanceClass.instances[name]; + if (defined(propertyValues)) { + if (instanceIndex !== batchId) { + throw new DeveloperError('Inherited property "' + name + '" is read-only.'); + } + if (defined(propertyValues.typedArray)) { + setBinaryProperty(propertyValues, indexInClass, value); + } else { + propertyValues[indexInClass] = clone(value, true); + } + return true; + } + }); + return defined(result); + } + Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + checkBatchId(batchId, this.featuresLength); + Check.typeOf.string('className', className); + + // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if this area becomes a hotspot + var hierarchy = this._batchTableHierarchy; + if (!defined(hierarchy)) { + return false; + } - /** - * @protected - * @property {RegExp} whitespaceRegex - * - * Regular expression used to match whitespace in a string of CSS classes. - */ - whitespaceRegex : /\s+/, + // PERFORMANCE_IDEA : treat class names as integers for faster comparisons + var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + if (instanceClass.name === className) { + return true; + } + }); + return defined(result); + }; + Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { + Check.typeOf.string('className', className); + + return (this.getExactClassName(batchId) === className); + }; - /** - * @constructor - * @param {Object} [cfg] The configuration properties for this class, in an Object (map) - */ - constructor : function( cfg ) { - Autolinker.Util.assign( this, cfg ); + Cesium3DTileBatchTable.prototype.getExactClassName = function(batchId) { + checkBatchId(batchId, this.featuresLength); + + var hierarchy = this._batchTableHierarchy; + if (!defined(hierarchy)) { + return undefined; + } + var classId = hierarchy.classIds[batchId]; + var instanceClass = hierarchy.classes[classId]; + return instanceClass.name; + }; - this.innerHtml = this.innerHtml || this.innerHTML; // accept either the camelCased form or the fully capitalized acronym - }, + Cesium3DTileBatchTable.prototype.hasProperty = function(batchId, name) { + checkBatchId(batchId, this.featuresLength); + Check.typeOf.string('name', name); + + var json = this.batchTableJson; + return (defined(json) && defined(json[name])) || (defined(this._batchTableHierarchy) && hasPropertyInHierarchy(this, batchId, name)); + }; + Cesium3DTileBatchTable.prototype.getPropertyNames = function(batchId, results) { + checkBatchId(batchId, this.featuresLength); + + results = defined(results) ? results : []; + results.length = 0; - /** - * Sets the tag name that will be used to generate the tag with. - * - * @param {String} tagName - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - setTagName : function( tagName ) { - this.tagName = tagName; - return this; - }, + var json = this.batchTableJson; + for (var name in json) { + if (json.hasOwnProperty(name)) { + results.push(name); + } + } + if (defined(this._batchTableHierarchy)) { + getPropertyNamesInHierarchy(this, batchId, results); + } - /** - * Retrieves the tag name. - * - * @return {String} - */ - getTagName : function() { - return this.tagName || ""; - }, + return results; + }; + Cesium3DTileBatchTable.prototype.getProperty = function(batchId, name) { + checkBatchId(batchId, this.featuresLength); + Check.typeOf.string('name', name); + + if (!defined(this.batchTableJson)) { + return undefined; + } - /** - * Sets an attribute on the HtmlTag. - * - * @param {String} attrName The attribute name to set. - * @param {String} attrValue The attribute value to set. - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - setAttr : function( attrName, attrValue ) { - var tagAttrs = this.getAttrs(); - tagAttrs[ attrName ] = attrValue; + if (defined(this._batchTableBinaryProperties)) { + var binaryProperty = this._batchTableBinaryProperties[name]; + if (defined(binaryProperty)) { + return getBinaryProperty(binaryProperty, batchId); + } + } - return this; - }, + var propertyValues = this.batchTableJson[name]; + if (defined(propertyValues)) { + return clone(propertyValues[batchId], true); + } + if (defined(this._batchTableHierarchy)) { + var hierarchyProperty = getHierarchyProperty(this, batchId, name); + if (defined(hierarchyProperty)) { + return hierarchyProperty; + } + } - /** - * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`. - * - * @param {String} name The attribute name to retrieve. - * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag. - */ - getAttr : function( attrName ) { - return this.getAttrs()[ attrName ]; - }, + return undefined; + }; + Cesium3DTileBatchTable.prototype.setProperty = function(batchId, name, value) { + var featuresLength = this.featuresLength; + checkBatchId(batchId, featuresLength); + Check.typeOf.string('name', name); + + if (defined(this._batchTableBinaryProperties)) { + var binaryProperty = this._batchTableBinaryProperties[name]; + if (defined(binaryProperty)) { + setBinaryProperty(binaryProperty, batchId, value); + return; + } + } - /** - * Sets one or more attributes on the HtmlTag. - * - * @param {Object.<String, String>} attrs A key/value Object (map) of the attributes to set. - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - setAttrs : function( attrs ) { - var tagAttrs = this.getAttrs(); - Autolinker.Util.assign( tagAttrs, attrs ); + if (defined(this._batchTableHierarchy)) { + if (setHierarchyProperty(this, batchId, name, value)) { + return; + } + } - return this; - }, + if (!defined(this.batchTableJson)) { + // Tile payload did not have a batch table. Create one for new user-defined properties. + this.batchTableJson = {}; + } + var propertyValues = this.batchTableJson[name]; - /** - * Retrieves the attributes Object (map) for the HtmlTag. - * - * @return {Object.<String, String>} A key/value object of the attributes for the HtmlTag. - */ - getAttrs : function() { - return this.attrs || ( this.attrs = {} ); - }, + if (!defined(propertyValues)) { + // Property does not exist. Create it. + this.batchTableJson[name] = new Array(featuresLength); + propertyValues = this.batchTableJson[name]; + } + propertyValues[batchId] = clone(value, true); + }; - /** - * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag. - * - * @param {String} cssClass One or more space-separated CSS classes to set (overwrite). - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - setClass : function( cssClass ) { - return this.setAttr( 'class', cssClass ); - }, + function getGlslComputeSt(batchTable) { + // GLSL batchId is zero-based: [0, featuresLength - 1] + if (batchTable._textureDimensions.y === 1) { + return 'uniform vec4 tile_textureStep; \n' + + 'vec2 computeSt(float batchId) \n' + + '{ \n' + + ' float stepX = tile_textureStep.x; \n' + + ' float centerX = tile_textureStep.y; \n' + + ' return vec2(centerX + (batchId * stepX), 0.5); \n' + + '} \n'; + } + return 'uniform vec4 tile_textureStep; \n' + + 'uniform vec2 tile_textureDimensions; \n' + + 'vec2 computeSt(float batchId) \n' + + '{ \n' + + ' float stepX = tile_textureStep.x; \n' + + ' float centerX = tile_textureStep.y; \n' + + ' float stepY = tile_textureStep.z; \n' + + ' float centerY = tile_textureStep.w; \n' + + ' float xId = mod(batchId, tile_textureDimensions.x); \n' + + ' float yId = floor(batchId / tile_textureDimensions.x); \n' + + ' return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n' + + '} \n'; + } - /** - * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes. - * - * @param {String} cssClass One or more space-separated CSS classes to add. - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - addClass : function( cssClass ) { - var classAttr = this.getClass(), - whitespaceRegex = this.whitespaceRegex, - indexOf = Autolinker.Util.indexOf, // to support IE8 and below - classes = ( !classAttr ) ? [] : classAttr.split( whitespaceRegex ), - newClasses = cssClass.split( whitespaceRegex ), - newClass; + Cesium3DTileBatchTable.prototype.getVertexShaderCallback = function(handleTranslucent, batchIdAttributeName, diffuseAttributeOrUniformName) { + if (this.featuresLength === 0) { + return; + } - while( newClass = newClasses.shift() ) { - if( indexOf( classes, newClass ) === -1 ) { - classes.push( newClass ); - } - } + var that = this; + return function(source) { + // If the color blend mode is HIGHLIGHT, the highlight color will always be applied in the fragment shader. + // No need to apply the highlight color in the vertex shader as well. + var renamedSource = modifyDiffuse(source, diffuseAttributeOrUniformName, false); + var newMain; - this.getAttrs()[ 'class' ] = classes.join( " " ); - return this; - }, + if (ContextLimits.maximumVertexTextureImageUnits > 0) { + // When VTF is supported, perform per-feature show/hide in the vertex shader + newMain = ''; + if (handleTranslucent) { + newMain += 'uniform bool tile_translucentCommand; \n'; + } + newMain += + 'uniform sampler2D tile_batchTexture; \n' + + 'varying vec4 tile_featureColor; \n' + + 'void main() \n' + + '{ \n' + + ' vec2 st = computeSt(' + batchIdAttributeName + '); \n' + + ' vec4 featureProperties = texture2D(tile_batchTexture, st); \n' + + ' tile_color(featureProperties); \n' + + ' float show = ceil(featureProperties.a); \n' + // 0 - false, non-zeo - true + ' gl_Position *= show; \n'; // Per-feature show/hide + if (handleTranslucent) { + newMain += + ' bool isStyleTranslucent = (featureProperties.a != 1.0); \n' + + ' if (czm_pass == czm_passTranslucent) \n' + + ' { \n' + + ' if (!isStyleTranslucent && !tile_translucentCommand) \n' + // Do not render opaque features in the translucent pass + ' { \n' + + ' gl_Position *= 0.0; \n' + + ' } \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' if (isStyleTranslucent) \n' + // Do not render translucent features in the opaque pass + ' { \n' + + ' gl_Position *= 0.0; \n' + + ' } \n' + + ' } \n'; + } + newMain += + ' tile_featureColor = featureProperties; \n' + + '}'; + } else { + // When VTF is not supported, color blend mode MIX will look incorrect due to the feature's color not being available in the vertex shader + newMain = + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' tile_color(vec4(1.0)); \n' + + ' tile_featureSt = computeSt(' + batchIdAttributeName + '); \n' + + '}'; + } + return renamedSource + '\n' + getGlslComputeSt(that) + newMain; + }; + }; - /** - * Convenience method to remove one or more CSS classes from the HtmlTag. - * - * @param {String} cssClass One or more space-separated CSS classes to remove. - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - removeClass : function( cssClass ) { - var classAttr = this.getClass(), - whitespaceRegex = this.whitespaceRegex, - indexOf = Autolinker.Util.indexOf, // to support IE8 and below - classes = ( !classAttr ) ? [] : classAttr.split( whitespaceRegex ), - removeClasses = cssClass.split( whitespaceRegex ), - removeClass; + function getDefaultShader(source, applyHighlight) { + source = ShaderSource.replaceMain(source, 'tile_main'); - while( classes.length && ( removeClass = removeClasses.shift() ) ) { - var idx = indexOf( classes, removeClass ); - if( idx !== -1 ) { - classes.splice( idx, 1 ); - } - } + if (!applyHighlight) { + return source + + 'void tile_color(vec4 tile_featureColor) \n' + + '{ \n' + + ' tile_main(); \n' + + '} \n'; + } - this.getAttrs()[ 'class' ] = classes.join( " " ); - return this; - }, + // The color blend mode is intended for the RGB channels so alpha is always just multiplied. + // gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) + return source + + 'uniform float tile_colorBlend; \n' + + 'void tile_color(vec4 tile_featureColor) \n' + + '{ \n' + + ' tile_main(); \n' + + ' gl_FragColor.a *= tile_featureColor.a; \n' + + ' float highlight = ceil(tile_colorBlend); \n' + + ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n' + + '} \n'; + } + function modifyDiffuse(source, diffuseAttributeOrUniformName, applyHighlight) { + // If the glTF does not specify the _3DTILESDIFFUSE semantic, return the default shader. + // Otherwise if _3DTILESDIFFUSE is defined prefer the shader below that can switch the color mode at runtime. + if (!defined(diffuseAttributeOrUniformName)) { + return getDefaultShader(source, applyHighlight); + } - /** - * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when - * there are multiple. - * - * @return {String} - */ - getClass : function() { - return this.getAttrs()[ 'class' ] || ""; - }, + // Find the diffuse uniform. Examples matches: + // uniform vec3 u_diffuseColor; + // uniform sampler2D diffuseTexture; + var regex = new RegExp('(uniform|attribute|in)\\s+(vec[34]|sampler2D)\\s+' + diffuseAttributeOrUniformName + ';'); + var uniformMatch = source.match(regex); + if (!defined(uniformMatch)) { + // Could not find uniform declaration of type vec3, vec4, or sampler2D + return getDefaultShader(source, applyHighlight); + } - /** - * Convenience method to check if the tag has a CSS class or not. - * - * @param {String} cssClass The CSS class to check for. - * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise. - */ - hasClass : function( cssClass ) { - return ( ' ' + this.getClass() + ' ' ).indexOf( ' ' + cssClass + ' ' ) !== -1; - }, + var declaration = uniformMatch[0]; + var type = uniformMatch[2]; + source = ShaderSource.replaceMain(source, 'tile_main'); + source = source.replace(declaration, ''); // Remove uniform declaration for now so the replace below doesn't affect it - /** - * Sets the inner HTML for the tag. - * - * @param {String} html The inner HTML to set. - * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. - */ - setInnerHtml : function( html ) { - this.innerHtml = html; + // If the tile color is white, use the source color. This implies the feature has not been styled. + // Highlight: tile_colorBlend is 0.0 and the source color is used + // Replace: tile_colorBlend is 1.0 and the tile color is used + // Mix: tile_colorBlend is between 0.0 and 1.0, causing the source color and tile color to mix + var finalDiffuseFunction = + 'bool isWhite(vec3 color) \n' + + '{ \n' + + ' return all(greaterThan(color, vec3(1.0 - czm_epsilon3))); \n' + + '} \n' + + 'vec4 tile_diffuse_final(vec4 sourceDiffuse, vec4 tileDiffuse) \n' + + '{ \n' + + ' vec4 blendDiffuse = mix(sourceDiffuse, tileDiffuse, tile_colorBlend); \n' + + ' vec4 diffuse = isWhite(tileDiffuse.rgb) ? sourceDiffuse : blendDiffuse; \n' + + ' return vec4(diffuse.rgb, sourceDiffuse.a); \n' + + '} \n'; - return this; - }, + // The color blend mode is intended for the RGB channels so alpha is always just multiplied. + // gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) + var highlight = + ' gl_FragColor.a *= tile_featureColor.a; \n' + + ' float highlight = ceil(tile_colorBlend); \n' + + ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n'; + var setColor; + if (type === 'vec3' || type === 'vec4') { + var sourceDiffuse = (type === 'vec3') ? ('vec4(' + diffuseAttributeOrUniformName + ', 1.0)') : diffuseAttributeOrUniformName; + var replaceDiffuse = (type === 'vec3') ? 'tile_diffuse.xyz' : 'tile_diffuse'; + regex = new RegExp(diffuseAttributeOrUniformName, 'g'); + source = source.replace(regex, replaceDiffuse); + setColor = + ' vec4 source = ' + sourceDiffuse + '; \n' + + ' tile_diffuse = tile_diffuse_final(source, tile_featureColor); \n' + + ' tile_main(); \n'; + } else if (type === 'sampler2D') { + // Regex handles up to one level of nested parentheses: + // E.g. texture2D(u_diffuse, uv) + // E.g. texture2D(u_diffuse, computeUV(index)) + regex = new RegExp('texture2D\\(' + diffuseAttributeOrUniformName + '.*?(\\)\\)|\\))', 'g'); + source = source.replace(regex, 'tile_diffuse_final($&, tile_diffuse)'); + setColor = + ' tile_diffuse = tile_featureColor; \n' + + ' tile_main(); \n'; + } - /** - * Retrieves the inner HTML for the tag. - * - * @return {String} - */ - getInnerHtml : function() { - return this.innerHtml || ""; - }, + source = + 'uniform float tile_colorBlend; \n' + + 'vec4 tile_diffuse = vec4(1.0); \n' + + finalDiffuseFunction + + declaration + '\n' + + source + '\n' + + 'void tile_color(vec4 tile_featureColor) \n' + + '{ \n' + + setColor; + if (applyHighlight) { + source += highlight; + } - /** - * Override of superclass method used to generate the HTML string for the tag. - * - * @return {String} - */ - toAnchorString : function() { - var tagName = this.getTagName(), - attrsStr = this.buildAttrsStr(); + source += '} \n'; + return source; + } - attrsStr = ( attrsStr ) ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes + Cesium3DTileBatchTable.prototype.getFragmentShaderCallback = function(handleTranslucent, diffuseAttributeOrUniformName) { + if (this.featuresLength === 0) { + return; + } + return function(source) { + source = modifyDiffuse(source, diffuseAttributeOrUniformName, true); + if (ContextLimits.maximumVertexTextureImageUnits > 0) { + // When VTF is supported, per-feature show/hide already happened in the fragment shader + source += + 'varying vec4 tile_featureColor; \n' + + 'void main() \n' + + '{ \n' + + ' tile_color(tile_featureColor); \n' + + '}'; + } else { + if (handleTranslucent) { + source += 'uniform bool tile_translucentCommand; \n'; + } + source += + 'uniform sampler2D tile_batchTexture; \n' + + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n' + + ' if (featureProperties.a == 0.0) { \n' + // show: alpha == 0 - false, non-zeo - true + ' discard; \n' + + ' } \n'; - return [ '<', tagName, attrsStr, '>', this.getInnerHtml(), '</', tagName, '>' ].join( "" ); - }, + if (handleTranslucent) { + source += + ' bool isStyleTranslucent = (featureProperties.a != 1.0); \n' + + ' if (czm_pass == czm_passTranslucent) \n' + + ' { \n' + + ' if (!isStyleTranslucent && !tile_translucentCommand) \n' + // Do not render opaque features in the translucent pass + ' { \n' + + ' discard; \n' + + ' } \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' if (isStyleTranslucent) \n' + // Do not render translucent features in the opaque pass + ' { \n' + + ' discard; \n' + + ' } \n' + + ' } \n'; + } + source += + ' tile_color(featureProperties); \n' + + '} \n'; + } + return source; + }; + }; - /** - * Support method for {@link #toAnchorString}, returns the string space-separated key="value" pairs, used to populate - * the stringified HtmlTag. - * - * @protected - * @return {String} Example return: `attr1="value1" attr2="value2"` - */ - buildAttrsStr : function() { - if( !this.attrs ) return ""; // no `attrs` Object (map) has been set, return empty string + Cesium3DTileBatchTable.prototype.getClassificationFragmentShaderCallback = function() { + if (this.featuresLength === 0) { + return; + } + return function(source) { + source = ShaderSource.replaceMain(source, 'tile_main'); + if (ContextLimits.maximumVertexTextureImageUnits > 0) { + // When VTF is supported, per-feature show/hide already happened in the fragment shader + source += + 'varying vec4 tile_featureColor; \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragColor = tile_featureColor; \n' + + '}'; + } else { + source += + 'uniform sampler2D tile_batchTexture; \n' + + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n' + + ' if (featureProperties.a == 0.0) { \n' + // show: alpha == 0 - false, non-zeo - true + ' discard; \n' + + ' } \n' + + ' gl_FragColor = featureProperties; \n' + + '} \n'; + } + return source; + }; + }; - var attrs = this.getAttrs(), - attrsArr = []; + function getColorBlend(batchTable) { + var tileset = batchTable._content._tileset; + var colorBlendMode = tileset.colorBlendMode; + var colorBlendAmount = tileset.colorBlendAmount; + if (colorBlendMode === Cesium3DTileColorBlendMode.HIGHLIGHT) { + return 0.0; + } + if (colorBlendMode === Cesium3DTileColorBlendMode.REPLACE) { + return 1.0; + } + if (colorBlendMode === Cesium3DTileColorBlendMode.MIX) { + // The value 0.0 is reserved for highlight, so clamp to just above 0.0. + return CesiumMath.clamp(colorBlendAmount, CesiumMath.EPSILON4, 1.0); + } + throw new DeveloperError('Invalid color blend mode "' + colorBlendMode + '".'); + } - for( var prop in attrs ) { - if( attrs.hasOwnProperty( prop ) ) { - attrsArr.push( prop + '="' + attrs[ prop ] + '"' ); - } - } - return attrsArr.join( " " ); - } + Cesium3DTileBatchTable.prototype.getUniformMapCallback = function() { + if (this.featuresLength === 0) { + return; + } -} ); + var that = this; + return function(uniformMap) { + var batchUniformMap = { + tile_batchTexture : function() { + // PERFORMANCE_IDEA: we could also use a custom shader that avoids the texture read. + return defaultValue(that._batchTexture, that._defaultTexture); + }, + tile_textureDimensions : function() { + return that._textureDimensions; + }, + tile_textureStep : function() { + return that._textureStep; + }, + tile_colorBlend : function() { + return getColorBlend(that); + } + }; -/*global Autolinker */ -/*jshint sub:true */ -/** - * @protected - * @class Autolinker.AnchorTagBuilder - * @extends Object - * - * Builds anchor (<a>) tags for the Autolinker utility when a match is found. - * - * Normally this class is instantiated, configured, and used internally by an {@link Autolinker} instance, but may - * actually be retrieved in a {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag} instances - * which may be modified before returning from the {@link Autolinker#replaceFn replaceFn}. For example: - * - * var html = Autolinker.link( "Test google.com", { - * replaceFn : function( autolinker, match ) { - * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance - * tag.setAttr( 'rel', 'nofollow' ); - * - * return tag; - * } - * } ); - * - * // generated html: - * // Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a> - */ -Autolinker.AnchorTagBuilder = Autolinker.Util.extend( Object, { + return combine(uniformMap, batchUniformMap); + }; + }; - /** - * @cfg {Boolean} newWindow - * @inheritdoc Autolinker#newWindow - */ + Cesium3DTileBatchTable.prototype.getPickVertexShaderCallback = function(batchIdAttributeName) { + if (this.featuresLength === 0) { + return; + } - /** - * @cfg {Number} truncate - * @inheritdoc Autolinker#truncate - */ + var that = this; + return function(source) { + var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); + var newMain; - /** - * @cfg {String} className - * @inheritdoc Autolinker#className - */ + if (ContextLimits.maximumVertexTextureImageUnits > 0) { + // When VTF is supported, perform per-feature show/hide in the vertex shader + newMain = + 'uniform sampler2D tile_batchTexture; \n' + + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' tile_main(); \n' + + ' vec2 st = computeSt(' + batchIdAttributeName + '); \n' + + ' vec4 featureProperties = texture2D(tile_batchTexture, st); \n' + + ' float show = ceil(featureProperties.a); \n' + // 0 - false, non-zero - true + ' gl_Position *= show; \n' + // Per-feature show/hide + ' tile_featureSt = st; \n' + + '}'; + } else { + newMain = + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' tile_main(); \n' + + ' tile_featureSt = computeSt(' + batchIdAttributeName + '); \n' + + '}'; + } + return renamedSource + '\n' + getGlslComputeSt(that) + newMain; + }; + }; - /** - * @constructor - * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map). - */ - constructor : function( cfg ) { - Autolinker.Util.assign( this, cfg ); - }, + Cesium3DTileBatchTable.prototype.getPickFragmentShaderCallback = function() { + if (this.featuresLength === 0) { + return; + } + + return function(source) { + var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); + var newMain; + + // Pick shaders do not need to take into account per-feature color/alpha. + // (except when alpha is zero, which is treated as if show is false, so + // it does not write depth in the color or pick pass). + if (ContextLimits.maximumVertexTextureImageUnits > 0) { + // When VTF is supported, per-feature show/hide already happened in the fragment shader + newMain = + 'uniform sampler2D tile_pickTexture; \n' + + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' tile_main(); \n' + + ' if (gl_FragColor.a == 0.0) { \n' + // per-feature show: alpha == 0 - false, non-zeo - true + ' discard; \n' + + ' } \n' + + ' gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n' + + '}'; + } else { + newMain = + 'uniform sampler2D tile_pickTexture; \n' + + 'uniform sampler2D tile_batchTexture; \n' + + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n' + + ' if (featureProperties.a == 0.0) { \n' + // per-feature show: alpha == 0 - false, non-zeo - true + ' discard; \n' + + ' } \n' + + ' tile_main(); \n' + + ' if (gl_FragColor.a == 0.0) { \n' + + ' discard; \n' + + ' } \n' + + ' gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n' + + '}'; + } + return renamedSource + '\n' + newMain; + }; + }; - /** - * Generates the actual anchor (<a>) tag to use in place of the - * matched text, via its `match` object. - * - * @param {Autolinker.match.Match} match The Match instance to generate an - * anchor tag from. - * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag. - */ - build : function( match ) { - var tag = new Autolinker.HtmlTag( { - tagName : 'a', - attrs : this.createAttrs( match.getType(), match.getAnchorHref() ), - innerHtml : this.processAnchorText( match.getAnchorText() ) - } ); + Cesium3DTileBatchTable.prototype.getPickVertexShaderCallbackIgnoreShow = function(batchIdAttributeName) { + if (this.featuresLength === 0) { + return; + } - return tag; - }, + var that = this; + return function(source) { + var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); + var newMain = + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' tile_main(); \n' + + ' tile_featureSt = computeSt(' + batchIdAttributeName + '); \n' + + '}'; + return renamedSource + '\n' + getGlslComputeSt(that) + newMain; + }; + }; - /** - * Creates the Object (map) of the HTML attributes for the anchor (<a>) - * tag being generated. - * - * @protected - * @param {"url"/"email"/"phone"/"twitter"/"hashtag"} matchType The type of - * match that an anchor tag is being generated for. - * @param {String} href The href for the anchor tag. - * @return {Object} A key/value Object (map) of the anchor tag's attributes. - */ - createAttrs : function( matchType, anchorHref ) { - var attrs = { - 'href' : anchorHref // we'll always have the `href` attribute - }; + Cesium3DTileBatchTable.prototype.getPickFragmentShaderCallbackIgnoreShow = function() { + if (this.featuresLength === 0) { + return; + } - var cssClass = this.createCssClass( matchType ); - if( cssClass ) { - attrs[ 'class' ] = cssClass; - } - if( this.newWindow ) { - attrs[ 'target' ] = "_blank"; - } + return function(source) { + var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); + var newMain = + 'uniform sampler2D tile_pickTexture; \n' + + 'varying vec2 tile_featureSt; \n' + + 'void main() \n' + + '{ \n' + + ' tile_main(); \n' + + ' gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n' + + '}'; - return attrs; - }, + return renamedSource + '\n' + newMain; + }; + }; + Cesium3DTileBatchTable.prototype.getPickUniformMapCallback = function() { + if (this.featuresLength === 0) { + return; + } - /** - * Creates the CSS class that will be used for a given anchor tag, based on - * the `matchType` and the {@link #className} config. - * - * @private - * @param {"url"/"email"/"phone"/"twitter"/"hashtag"} matchType The type of - * match that an anchor tag is being generated for. - * @return {String} The CSS class string for the link. Example return: - * "myLink myLink-url". If no {@link #className} was configured, returns - * an empty string. - */ - createCssClass : function( matchType ) { - var className = this.className; + var that = this; + return function(uniformMap) { + var batchUniformMap = { + tile_batchTexture : function() { + return defaultValue(that._batchTexture, that._defaultTexture); + }, + tile_textureDimensions : function() { + return that._textureDimensions; + }, + tile_textureStep : function() { + return that._textureStep; + }, + tile_pickTexture : function() { + return that._pickTexture; + } + }; - if( !className ) - return ""; - else - return className + " " + className + "-" + matchType; // ex: "myLink myLink-url", "myLink myLink-email", "myLink myLink-phone", "myLink myLink-twitter", or "myLink myLink-hashtag" - }, + return combine(batchUniformMap, uniformMap); + }; + }; + /////////////////////////////////////////////////////////////////////////// - /** - * Processes the `anchorText` by truncating the text according to the - * {@link #truncate} config. - * - * @private - * @param {String} anchorText The anchor tag's text (i.e. what will be - * displayed). - * @return {String} The processed `anchorText`. - */ - processAnchorText : function( anchorText ) { - anchorText = this.doTruncate( anchorText ); + var StyleCommandsNeeded = { + ALL_OPAQUE : 0, + ALL_TRANSLUCENT : 1, + OPAQUE_AND_TRANSLUCENT : 2 + }; - return anchorText; - }, + Cesium3DTileBatchTable.prototype.addDerivedCommands = function(frameState, commandStart, finalResolution) { + var commandList = frameState.commandList; + var commandEnd = commandList.length; + var tile = this._content._tile; + var tileset = tile._tileset; + var bivariateVisibilityTest = tileset._skipLevelOfDetail && tileset._hasMixedContent && frameState.context.stencilBuffer; + var styleCommandsNeeded = getStyleCommandsNeeded(this); + for (var i = commandStart; i < commandEnd; ++i) { + var command = commandList[i]; + var derivedCommands = command.derivedCommands.tileset; + if (!defined(derivedCommands)) { + derivedCommands = {}; + command.derivedCommands.tileset = derivedCommands; + derivedCommands.originalCommand = deriveCommand(command); + } - /** - * Performs the truncation of the `anchorText`, if the `anchorText` is - * longer than the {@link #truncate} option. Truncates the text to 2 - * characters fewer than the {@link #truncate} option, and adds ".." to the - * end. - * - * @private - * @param {String} text The anchor tag's text (i.e. what will be displayed). - * @return {String} The truncated anchor text. - */ - doTruncate : function( anchorText ) { - return Autolinker.Util.ellipsis( anchorText, this.truncate || Number.POSITIVE_INFINITY ); - } + updateDerivedCommand(derivedCommands.originalCommand, command); -} ); -/*global Autolinker */ -/** - * @private - * @class Autolinker.htmlParser.HtmlParser - * @extends Object - * - * An HTML parser implementation which simply walks an HTML string and returns an array of - * {@link Autolinker.htmlParser.HtmlNode HtmlNodes} that represent the basic HTML structure of the input string. - * - * Autolinker uses this to only link URLs/emails/Twitter handles within text nodes, effectively ignoring / "walking - * around" HTML tags. - */ -Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, { + if (styleCommandsNeeded !== StyleCommandsNeeded.ALL_OPAQUE) { + if (!defined(derivedCommands.translucent)) { + derivedCommands.translucent = deriveTranslucentCommand(derivedCommands.originalCommand); + } + updateDerivedCommand(derivedCommands.translucent, command); + } - /** - * @private - * @property {RegExp} htmlRegex - * - * The regular expression used to pull out HTML tags from a string. Handles namespaced HTML tags and - * attribute names, as specified by http://www.w3.org/TR/html-markup/syntax.html. - * - * Capturing groups: - * - * 1. The "!DOCTYPE" tag name, if a tag is a <!DOCTYPE> tag. - * 2. If it is an end tag, this group will have the '/'. - * 3. If it is a comment tag, this group will hold the comment text (i.e. - * the text inside the `<!--` and `-->`. - * 4. The tag name for all tags (other than the <!DOCTYPE> tag) - */ - htmlRegex : (function() { - var commentTagRegex = /!--([\s\S]+?)--/, - tagNameRegex = /[0-9a-zA-Z][0-9a-zA-Z:]*/, - attrNameRegex = /[^\s\0"'>\/=\x01-\x1F\x7F]+/, // the unicode range accounts for excluding control chars, and the delete char - attrValueRegex = /(?:"[^"]*?"|'[^']*?'|[^'"=<>`\s]+)/, // double quoted, single quoted, or unquoted attribute values - nameEqualsValueRegex = attrNameRegex.source + '(?:\\s*=\\s*' + attrValueRegex.source + ')?'; // optional '=[value]' + if (bivariateVisibilityTest) { + if (command.pass !== Pass.TRANSLUCENT && !finalResolution) { + if (!defined(derivedCommands.zback)) { + derivedCommands.zback = deriveZBackfaceCommand(derivedCommands.originalCommand); + } + tileset._backfaceCommands.push(derivedCommands.zback); + } + if (!defined(derivedCommands.stencil) || tile._selectionDepth !== tile._lastSelectionDepth) { + derivedCommands.stencil = deriveStencilCommand(derivedCommands.originalCommand, tile._selectionDepth); + tile._lastSelectionDepth = tile._selectionDepth; + } + updateDerivedCommand(derivedCommands.stencil, command); + } - return new RegExp( [ - // for <!DOCTYPE> tag. Ex: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">) - '(?:', - '<(!DOCTYPE)', // *** Capturing Group 1 - If it's a doctype tag + var opaqueCommand = bivariateVisibilityTest ? derivedCommands.stencil : derivedCommands.originalCommand; + var translucentCommand = derivedCommands.translucent; - // Zero or more attributes following the tag name - '(?:', - '\\s+', // one or more whitespace chars before an attribute + // If the command was originally opaque: + // * If the styling applied to the tile is all opaque, use the original command + // (with one additional uniform needed for the shader). + // * If the styling is all translucent, use new (cached) derived commands (front + // and back faces) with a translucent render state. + // * If the styling causes both opaque and translucent features in this tile, + // then use both sets of commands. + if (command.pass !== Pass.TRANSLUCENT) { + if (styleCommandsNeeded === StyleCommandsNeeded.ALL_OPAQUE) { + commandList[i] = opaqueCommand; + } + if (styleCommandsNeeded === StyleCommandsNeeded.ALL_TRANSLUCENT) { + commandList[i] = translucentCommand; + } + if (styleCommandsNeeded === StyleCommandsNeeded.OPAQUE_AND_TRANSLUCENT) { + // PERFORMANCE_IDEA: if the tile has multiple commands, we do not know what features are in what + // commands so this case may be overkill. + commandList[i] = opaqueCommand; + commandList.push(translucentCommand); + } + } else { + // Command was originally translucent so no need to derive new commands; + // as of now, a style can't change an originally translucent feature to + // opaque since the style's alpha is modulated, not a replacement. When + // this changes, we need to derive new opaque commands here. + commandList[i] = opaqueCommand; + } + } + }; - // Either: - // A. attr="value", or - // B. "value" alone (To cover example doctype tag: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">) - '(?:', nameEqualsValueRegex, '|', attrValueRegex.source + ')', - ')*', - '>', - ')', + function updateDerivedCommand(derivedCommand, command) { + derivedCommand.castShadows = command.castShadows; + derivedCommand.receiveShadows = command.receiveShadows; + derivedCommand.primitiveType = command.primitiveType; + } - '|', + function getStyleCommandsNeeded(batchTable) { + var translucentFeaturesLength = batchTable._translucentFeaturesLength; - // All other HTML tags (i.e. tags that are not <!DOCTYPE>) - '(?:', - '<(/)?', // Beginning of a tag or comment. Either '<' for a start tag, or '</' for an end tag. - // *** Capturing Group 2: The slash or an empty string. Slash ('/') for end tag, empty string for start or self-closing tag. + if (translucentFeaturesLength === 0) { + return StyleCommandsNeeded.ALL_OPAQUE; + } else if (translucentFeaturesLength === batchTable.featuresLength) { + return StyleCommandsNeeded.ALL_TRANSLUCENT; + } - '(?:', - commentTagRegex.source, // *** Capturing Group 3 - A Comment Tag's Text + return StyleCommandsNeeded.OPAQUE_AND_TRANSLUCENT; + } - '|', + function deriveCommand(command) { + var derivedCommand = DrawCommand.shallowClone(command); - '(?:', + // Add a uniform to indicate if the original command was translucent so + // the shader knows not to cull vertices that were originally transparent + // even though their style is opaque. + var translucentCommand = (derivedCommand.pass === Pass.TRANSLUCENT); - // *** Capturing Group 4 - The tag name - '(' + tagNameRegex.source + ')', + derivedCommand.uniformMap = defined(derivedCommand.uniformMap) ? derivedCommand.uniformMap : {}; + derivedCommand.uniformMap.tile_translucentCommand = function() { + return translucentCommand; + }; - // Zero or more attributes following the tag name - '(?:', - '\\s+', // one or more whitespace chars before an attribute - nameEqualsValueRegex, // attr="value" (with optional ="value" part) - ')*', + return derivedCommand; + } - '\\s*/?', // any trailing spaces and optional '/' before the closing '>' + function deriveTranslucentCommand(command) { + var derivedCommand = DrawCommand.shallowClone(command); + derivedCommand.pass = Pass.TRANSLUCENT; + derivedCommand.renderState = getTranslucentRenderState(command.renderState); + return derivedCommand; + } - ')', - ')', - '>', - ')' - ].join( "" ), 'gi' ); - } )(), + function deriveZBackfaceCommand(command) { + // Write just backface depth of unresolved tiles so resolved stenciled tiles do not appear in front + var derivedCommand = DrawCommand.shallowClone(command); + var rs = clone(derivedCommand.renderState, true); + rs.cull.enabled = true; + rs.cull.face = CullFace.FRONT; + // Back faces do not need to write color. + rs.colorMask = { + red : false, + green : false, + blue : false, + alpha : false + }; + // Push back face depth away from the camera so it is less likely that back faces and front faces of the same tile + // intersect and overlap. This helps avoid flickering for very thin double-sided walls. + rs.polygonOffset = { + enabled : true, + factor : 5.0, + units : 5.0 + }; + derivedCommand.renderState = RenderState.fromCache(rs); + derivedCommand.castShadows = false; + derivedCommand.receiveShadows = false; + return derivedCommand; + } - /** - * @private - * @property {RegExp} htmlCharacterEntitiesRegex - * - * The regular expression that matches common HTML character entities. - * - * Ignoring & as it could be part of a query string -- handling it separately. - */ - htmlCharacterEntitiesRegex: /( | |<|<|>|>|"|"|')/gi, + function deriveStencilCommand(command, reference) { + var derivedCommand = command; + if (command.renderState.depthMask) { // ignore if tile does not write depth (ex. translucent) + // Tiles only draw if their selection depth is >= the tile drawn already. They write their + // selection depth to the stencil buffer to prevent ancestor tiles from drawing on top + derivedCommand = DrawCommand.shallowClone(command); + var rs = clone(derivedCommand.renderState, true); + // Stencil test is masked to the most significant 4 bits so the reference is shifted. + // This is to prevent clearing the stencil before classification which needs the least significant + // bits for increment/decrement operations. + rs.stencilTest.enabled = true; + rs.stencilTest.mask = 0xF0; + rs.stencilTest.reference = reference << 4; + rs.stencilTest.frontFunction = StencilFunction.GREATER_OR_EQUAL; + rs.stencilTest.frontOperation.zPass = StencilOperation.REPLACE; + derivedCommand.renderState = RenderState.fromCache(rs); + } + return derivedCommand; + } + function getTranslucentRenderState(renderState) { + var rs = clone(renderState, true); + rs.cull.enabled = false; + rs.depthTest.enabled = true; + rs.depthMask = false; + rs.blending = BlendingState.ALPHA_BLEND; - /** - * Parses an HTML string and returns a simple array of {@link Autolinker.htmlParser.HtmlNode HtmlNodes} - * to represent the HTML structure of the input string. - * - * @param {String} html The HTML to parse. - * @return {Autolinker.htmlParser.HtmlNode[]} - */ - parse : function( html ) { - var htmlRegex = this.htmlRegex, - currentResult, - lastIndex = 0, - textAndEntityNodes, - nodes = []; // will be the result of the method + return RenderState.fromCache(rs); + } - while( ( currentResult = htmlRegex.exec( html ) ) !== null ) { - var tagText = currentResult[ 0 ], - commentText = currentResult[ 3 ], // if we've matched a comment - tagName = currentResult[ 1 ] || currentResult[ 4 ], // The <!DOCTYPE> tag (ex: "!DOCTYPE"), or another tag (ex: "a" or "img") - isClosingTag = !!currentResult[ 2 ], - inBetweenTagsText = html.substring( lastIndex, currentResult.index ); + /////////////////////////////////////////////////////////////////////////// - // Push TextNodes and EntityNodes for any text found between tags - if( inBetweenTagsText ) { - textAndEntityNodes = this.parseTextAndEntityNodes( inBetweenTagsText ); - nodes.push.apply( nodes, textAndEntityNodes ); - } + function createTexture(batchTable, context, bytes) { + var dimensions = batchTable._textureDimensions; + return new Texture({ + context : context, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + source : { + width : dimensions.x, + height : dimensions.y, + arrayBufferView : bytes + }, + sampler : new Sampler({ + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }) + }); + } - // Push the CommentNode or ElementNode - if( commentText ) { - nodes.push( this.createCommentNode( tagText, commentText ) ); - } else { - nodes.push( this.createElementNode( tagText, tagName, isClosingTag ) ); - } + function createPickTexture(batchTable, context) { + var featuresLength = batchTable.featuresLength; + if (!defined(batchTable._pickTexture) && (featuresLength > 0)) { + var pickIds = batchTable._pickIds; + var byteLength = getByteLength(batchTable); + var bytes = new Uint8Array(byteLength); + var content = batchTable._content; - lastIndex = currentResult.index + tagText.length; - } + // PERFORMANCE_IDEA: we could skip the pick texture completely by allocating + // a continuous range of pickIds and then converting the base pickId + batchId + // to RGBA in the shader. The only consider is precision issues, which might + // not be an issue in WebGL 2. + for (var i = 0; i < featuresLength; ++i) { + var pickId = context.createPickId(content.getFeature(i)); + pickIds.push(pickId); - // Process any remaining text after the last HTML element. Will process all of the text if there were no HTML elements. - if( lastIndex < html.length ) { - var text = html.substring( lastIndex ); + var pickColor = pickId.color; + var offset = i * 4; + bytes[offset] = Color.floatToByte(pickColor.red); + bytes[offset + 1] = Color.floatToByte(pickColor.green); + bytes[offset + 2] = Color.floatToByte(pickColor.blue); + bytes[offset + 3] = Color.floatToByte(pickColor.alpha); + } - // Push TextNodes and EntityNodes for any text found between tags - if( text ) { - textAndEntityNodes = this.parseTextAndEntityNodes( text ); - nodes.push.apply( nodes, textAndEntityNodes ); - } - } + batchTable._pickTexture = createTexture(batchTable, context, bytes); + content._tileset._statistics.batchTableByteLength += batchTable._pickTexture.sizeInBytes; + } + } - return nodes; - }, + function updateBatchTexture(batchTable) { + var dimensions = batchTable._textureDimensions; + // PERFORMANCE_IDEA: Instead of rewriting the entire texture, use fine-grained + // texture updates when less than, for example, 10%, of the values changed. Or + // even just optimize the common case when one feature show/color changed. + batchTable._batchTexture.copyFrom({ + width : dimensions.x, + height : dimensions.y, + arrayBufferView : batchTable._batchValues + }); + } + Cesium3DTileBatchTable.prototype.update = function(tileset, frameState) { + var context = frameState.context; + this._defaultTexture = context.defaultTexture; - /** - * Parses text and HTML entity nodes from a given string. The input string - * should not have any HTML tags (elements) within it. - * - * @private - * @param {String} text The text to parse. - * @return {Autolinker.htmlParser.HtmlNode[]} An array of HtmlNodes to - * represent the {@link Autolinker.htmlParser.TextNode TextNodes} and - * {@link Autolinker.htmlParser.EntityNode EntityNodes} found. - */ - parseTextAndEntityNodes : function( text ) { - var nodes = [], - textAndEntityTokens = Autolinker.Util.splitAndCapture( text, this.htmlCharacterEntitiesRegex ); // split at HTML entities, but include the HTML entities in the results array + if (frameState.passes.pick) { + // Create pick texture on-demand + createPickTexture(this, context); + } - // Every even numbered token is a TextNode, and every odd numbered token is an EntityNode - // For example: an input `text` of "Test "this" today" would turn into the - // `textAndEntityTokens`: [ 'Test ', '"', 'this', '"', ' today' ] - for( var i = 0, len = textAndEntityTokens.length; i < len; i += 2 ) { - var textToken = textAndEntityTokens[ i ], - entityToken = textAndEntityTokens[ i + 1 ]; + if (this._batchValuesDirty) { + this._batchValuesDirty = false; - if( textToken ) nodes.push( this.createTextNode( textToken ) ); - if( entityToken ) nodes.push( this.createEntityNode( entityToken ) ); - } - return nodes; - }, + // Create batch texture on-demand + if (!defined(this._batchTexture)) { + this._batchTexture = createTexture(this, context, this._batchValues); + tileset._statistics.batchTableByteLength += this._batchTexture.sizeInBytes; + } + updateBatchTexture(this); // Apply per-feature show/color updates + } + }; - /** - * Factory method to create an {@link Autolinker.htmlParser.CommentNode CommentNode}. - * - * @private - * @param {String} tagText The full text of the tag (comment) that was - * matched, including its <!-- and -->. - * @param {String} comment The full text of the comment that was matched. - */ - createCommentNode : function( tagText, commentText ) { - return new Autolinker.htmlParser.CommentNode( { - text: tagText, - comment: Autolinker.Util.trim( commentText ) - } ); - }, + Cesium3DTileBatchTable.prototype.isDestroyed = function() { + return false; + }; + Cesium3DTileBatchTable.prototype.destroy = function() { + this._batchTexture = this._batchTexture && this._batchTexture.destroy(); + this._pickTexture = this._pickTexture && this._pickTexture.destroy(); - /** - * Factory method to create an {@link Autolinker.htmlParser.ElementNode ElementNode}. - * - * @private - * @param {String} tagText The full text of the tag (element) that was - * matched, including its attributes. - * @param {String} tagName The name of the tag. Ex: An <img> tag would - * be passed to this method as "img". - * @param {Boolean} isClosingTag `true` if it's a closing tag, false - * otherwise. - * @return {Autolinker.htmlParser.ElementNode} - */ - createElementNode : function( tagText, tagName, isClosingTag ) { - return new Autolinker.htmlParser.ElementNode( { - text : tagText, - tagName : tagName.toLowerCase(), - closing : isClosingTag - } ); - }, + var pickIds = this._pickIds; + var length = pickIds.length; + for (var i = 0; i < length; ++i) { + pickIds[i].destroy(); + } + return destroyObject(this); + }; - /** - * Factory method to create a {@link Autolinker.htmlParser.EntityNode EntityNode}. - * - * @private - * @param {String} text The text that was matched for the HTML entity (such - * as '&nbsp;'). - * @return {Autolinker.htmlParser.EntityNode} - */ - createEntityNode : function( text ) { - return new Autolinker.htmlParser.EntityNode( { text: text } ); - }, + return Cesium3DTileBatchTable; +}); +define('Scene/Cesium3DTileFeature',[ + '../Core/Color', + '../Core/defined', + '../Core/defineProperties' + ], function( + Color, + defined, + defineProperties) { + 'use strict'; - /** - * Factory method to create a {@link Autolinker.htmlParser.TextNode TextNode}. - * - * @private - * @param {String} text The text that was matched. - * @return {Autolinker.htmlParser.TextNode} - */ - createTextNode : function( text ) { - return new Autolinker.htmlParser.TextNode( { text: text } ); - } + /** + * A feature of a {@link Cesium3DTileset}. + * <p> + * Provides access to a feature's properties stored in the tile's batch table, as well + * as the ability to show/hide a feature and change its highlight color via + * {@link Cesium3DTileFeature#show} and {@link Cesium3DTileFeature#color}, respectively. + * </p> + * <p> + * Modifications to a <code>Cesium3DTileFeature</code> object have the lifetime of the tile's + * content. If the tile's content is unloaded, e.g., due to it going out of view and needing + * to free space in the cache for visible tiles, listen to the {@link Cesium3DTileset#tileUnload} event to save any + * modifications. Also listen to the {@link Cesium3DTileset#tileVisible} event to reapply any modifications. + * </p> + * <p> + * Do not construct this directly. Access it through {@link Cesium3DTileContent#getFeature} + * or picking using {@link Scene#pick} and {@link Scene#pickPosition}. + * </p> + * + * @alias Cesium3DTileFeature + * @constructor + * + * @example + * // On mouse over, display all the properties for a feature in the console log. + * handler.setInputAction(function(movement) { + * var feature = scene.pick(movement.endPosition); + * if (feature instanceof Cesium.Cesium3DTileFeature) { + * var propertyNames = feature.getPropertyNames(); + * var length = propertyNames.length; + * for (var i = 0; i < length; ++i) { + * var propertyName = propertyNames[i]; + * console.log(propertyName + ': ' + feature.getProperty(propertyName)); + * } + * } + * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + */ + function Cesium3DTileFeature(content, batchId) { + this._content = content; + this._batchId = batchId; + this._color = undefined; // for calling getColor + } -} ); -/*global Autolinker */ -/** - * @abstract - * @class Autolinker.htmlParser.HtmlNode - * - * Represents an HTML node found in an input string. An HTML node is one of the following: - * - * 1. An {@link Autolinker.htmlParser.ElementNode ElementNode}, which represents HTML tags. - * 2. A {@link Autolinker.htmlParser.TextNode TextNode}, which represents text outside or within HTML tags. - * 3. A {@link Autolinker.htmlParser.EntityNode EntityNode}, which represents one of the known HTML - * entities that Autolinker looks for. This includes common ones such as &quot; and &nbsp; - */ -Autolinker.htmlParser.HtmlNode = Autolinker.Util.extend( Object, { - - /** - * @cfg {String} text (required) - * - * The original text that was matched for the HtmlNode. - * - * - In the case of an {@link Autolinker.htmlParser.ElementNode ElementNode}, this will be the tag's - * text. - * - In the case of a {@link Autolinker.htmlParser.TextNode TextNode}, this will be the text itself. - * - In the case of a {@link Autolinker.htmlParser.EntityNode EntityNode}, this will be the text of - * the HTML entity. - */ - text : "", - - - /** - * @constructor - * @param {Object} cfg The configuration properties for the Match instance, specified in an Object (map). - */ - constructor : function( cfg ) { - Autolinker.Util.assign( this, cfg ); - }, + defineProperties(Cesium3DTileFeature.prototype, { + /** + * Gets or sets if the feature will be shown. This is set for all features + * when a style's show is evaluated. + * + * @memberof Cesium3DTileFeature.prototype + * + * @type {Boolean} + * + * @default true + */ + show : { + get : function() { + return this._content.batchTable.getShow(this._batchId); + }, + set : function(value) { + this._content.batchTable.setShow(this._batchId, value); + } + }, - - /** - * Returns a string name for the type of node that this class represents. - * - * @abstract - * @return {String} - */ - getType : Autolinker.Util.abstractMethod, - - - /** - * Retrieves the {@link #text} for the HtmlNode. - * - * @return {String} - */ - getText : function() { - return this.text; - } + /** + * Gets or sets the highlight color multiplied with the feature's color. When + * this is white, the feature's color is not changed. This is set for all features + * when a style's color is evaluated. + * + * @memberof Cesium3DTileFeature.prototype + * + * @type {Color} + * + * @default {@link Color.WHITE} + */ + color : { + get : function() { + if (!defined(this._color)) { + this._color = new Color(); + } + return this._content.batchTable.getColor(this._batchId, this._color); + }, + set : function(value) { + this._content.batchTable.setColor(this._batchId, value); + } + }, -} ); -/*global Autolinker */ -/** - * @class Autolinker.htmlParser.CommentNode - * @extends Autolinker.htmlParser.HtmlNode - * - * Represents an HTML comment node that has been parsed by the - * {@link Autolinker.htmlParser.HtmlParser}. - * - * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more - * details. - */ -Autolinker.htmlParser.CommentNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { + /** + * Gets the content of the tile containing the feature. + * + * @memberof Cesium3DTileFeature.prototype + * + * @type {Cesium3DTileContent} + * + * @readonly + * @private + */ + content : { + get : function() { + return this._content; + } + }, - /** - * @cfg {String} comment (required) - * - * The text inside the comment tag. This text is stripped of any leading or - * trailing whitespace. - */ - comment : '', + /** + * Gets the tileset containing the feature. + * + * @memberof Cesium3DTileFeature.prototype + * + * @type {Cesium3DTileset} + * + * @readonly + */ + tileset : { + get : function() { + return this._content.tileset; + } + }, + /** + * All objects returned by {@link Scene#pick} have a <code>primitive</code> property. This returns + * the tileset containing the feature. + * + * @memberof Cesium3DTileFeature.prototype + * + * @type {Cesium3DTileset} + * + * @readonly + */ + primitive : { + get : function() { + return this._content.tileset; + } + } + }); - /** - * Returns a string name for the type of node that this class represents. - * - * @return {String} - */ - getType : function() { - return 'comment'; - }, + /** + * Returns whether the feature contains this property. This includes properties from this feature's + * class and inherited classes when using a batch table hierarchy. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} + * + * @param {String} name The case-sensitive name of the property. + * @returns {Boolean} Whether the feature contains this property. + */ + Cesium3DTileFeature.prototype.hasProperty = function(name) { + return this._content.batchTable.hasProperty(this._batchId, name); + }; + /** + * Returns an array of property names for the feature. This includes properties from this feature's + * class and inherited classes when using a batch table hierarchy. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} + * + * @param {String[]} results An array into which to store the results. + * @returns {String[]} The names of the feature's properties. + */ + Cesium3DTileFeature.prototype.getPropertyNames = function(results) { + return this._content.batchTable.getPropertyNames(this._batchId, results); + }; - /** - * Returns the comment inside the comment tag. - * - * @return {String} - */ - getComment : function() { - return this.comment; - } + /** + * Returns a copy of the value of the feature's property with the given name. This includes properties from this feature's + * class and inherited classes when using a batch table hierarchy. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} + * + * @param {String} name The case-sensitive name of the property. + * @returns {*} The value of the property or <code>undefined</code> if the property does not exist. + * + * @example + * // Display all the properties for a feature in the console log. + * var propertyNames = feature.getPropertyNames(); + * var length = propertyNames.length; + * for (var i = 0; i < length; ++i) { + * var propertyName = propertyNames[i]; + * console.log(propertyName + ': ' + feature.getProperty(propertyName)); + * } + */ + Cesium3DTileFeature.prototype.getProperty = function(name) { + return this._content.batchTable.getProperty(this._batchId, name); + }; -} ); -/*global Autolinker */ -/** - * @class Autolinker.htmlParser.ElementNode - * @extends Autolinker.htmlParser.HtmlNode - * - * Represents an HTML element node that has been parsed by the {@link Autolinker.htmlParser.HtmlParser}. - * - * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more details. - */ -Autolinker.htmlParser.ElementNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { - - /** - * @cfg {String} tagName (required) - * - * The name of the tag that was matched. - */ - tagName : '', - - /** - * @cfg {Boolean} closing (required) - * - * `true` if the element (tag) is a closing tag, `false` if its an opening tag. - */ - closing : false, + /** + * Sets the value of the feature's property with the given name. + * <p> + * If a property with the given name doesn't exist, it is created. + * </p> + * + * @param {String} name The case-sensitive name of the property. + * @param {*} value The value of the property that will be copied. + * + * @exception {DeveloperError} Inherited batch table hierarchy property is read only. + * + * @example + * var height = feature.getProperty('Height'); // e.g., the height of a building + * + * @example + * var name = 'clicked'; + * if (feature.getProperty(name)) { + * console.log('already clicked'); + * } else { + * feature.setProperty(name, true); + * console.log('first click'); + * } + */ + Cesium3DTileFeature.prototype.setProperty = function(name, value) { + this._content.batchTable.setProperty(this._batchId, name, value); - - /** - * Returns a string name for the type of node that this class represents. - * - * @return {String} - */ - getType : function() { - return 'element'; - }, - + // PERFORMANCE_IDEA: Probably overkill, but maybe only mark the tile dirty if the + // property is in one of the style's expressions or - if it can be done quickly - + // if the new property value changed the result of an expression. + this._content.featurePropertiesDirty = true; + }; - /** - * Returns the HTML element's (tag's) name. Ex: for an <img> tag, returns "img". - * - * @return {String} - */ - getTagName : function() { - return this.tagName; - }, - - - /** - * Determines if the HTML element (tag) is a closing tag. Ex: <div> returns - * `false`, while </div> returns `true`. - * - * @return {Boolean} - */ - isClosing : function() { - return this.closing; - } - -} ); -/*global Autolinker */ -/** - * @class Autolinker.htmlParser.EntityNode - * @extends Autolinker.htmlParser.HtmlNode - * - * Represents a known HTML entity node that has been parsed by the {@link Autolinker.htmlParser.HtmlParser}. - * Ex: '&nbsp;', or '&#160;' (which will be retrievable from the {@link #getText} method. - * - * Note that this class will only be returned from the HtmlParser for the set of checked HTML entity nodes - * defined by the {@link Autolinker.htmlParser.HtmlParser#htmlCharacterEntitiesRegex}. - * - * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more details. - */ -Autolinker.htmlParser.EntityNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { - - /** - * Returns a string name for the type of node that this class represents. - * - * @return {String} - */ - getType : function() { - return 'entity'; - } - -} ); -/*global Autolinker */ -/** - * @class Autolinker.htmlParser.TextNode - * @extends Autolinker.htmlParser.HtmlNode - * - * Represents a text node that has been parsed by the {@link Autolinker.htmlParser.HtmlParser}. - * - * See this class's superclass ({@link Autolinker.htmlParser.HtmlNode}) for more details. - */ -Autolinker.htmlParser.TextNode = Autolinker.Util.extend( Autolinker.htmlParser.HtmlNode, { - - /** - * Returns a string name for the type of node that this class represents. - * - * @return {String} - */ - getType : function() { - return 'text'; - } - -} ); -/*global Autolinker */ -/** - * @private - * @class Autolinker.matchParser.MatchParser - * @extends Object - * - * Used by Autolinker to parse potential matches, given an input string of text. - * - * The MatchParser is fed a non-HTML string in order to search for matches. - * Autolinker first uses the {@link Autolinker.htmlParser.HtmlParser} to "walk - * around" HTML tags, and then the text around the HTML tags is passed into the - * MatchParser in order to find the actual matches. - */ -Autolinker.matchParser.MatchParser = Autolinker.Util.extend( Object, { + /** + * Returns whether the feature's class name equals <code>className</code>. Unlike {@link Cesium3DTileFeature#isClass} + * this function only checks the feature's exact class and not inherited classes. + * <p> + * This function returns <code>false</code> if no batch table hierarchy is present. + * </p> + * + * @param {String} className The name to check against. + * @returns {Boolean} Whether the feature's class name equals <code>className</code> + * + * @private + */ + Cesium3DTileFeature.prototype.isExactClass = function(className) { + return this._content.batchTable.isExactClass(this._batchId, className); + }; + + /** + * Returns whether the feature's class or any inherited classes are named <code>className</code>. + * <p> + * This function returns <code>false</code> if no batch table hierarchy is present. + * </p> + * + * @param {String} className The name to check against. + * @returns {Boolean} Whether the feature's class or inherited classes are named <code>className</code> + * + * @private + */ + Cesium3DTileFeature.prototype.isClass = function(className) { + return this._content.batchTable.isClass(this._batchId, className); + }; + + /** + * Returns the feature's class name. + * <p> + * This function returns <code>undefined</code> if no batch table hierarchy is present. + * </p> + * + * @returns {String} The feature's class name. + * + * @private + */ + Cesium3DTileFeature.prototype.getExactClassName = function() { + return this._content.batchTable.getExactClassName(this._batchId); + }; - /** - * @cfg {Boolean} urls - * @inheritdoc Autolinker#urls - */ - urls : true, + return Cesium3DTileFeature; +}); - /** - * @cfg {Boolean} email - * @inheritdoc Autolinker#email - */ - email : true, +define('Scene/Cesium3DTileFeatureTable',[ + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined' + ], function( + ComponentDatatype, + defaultValue, + defined) { + 'use strict'; - /** - * @cfg {Boolean} twitter - * @inheritdoc Autolinker#twitter - */ - twitter : true, + /** + * @private + */ + function Cesium3DTileFeatureTable(featureTableJson, featureTableBinary) { + this.json = featureTableJson; + this.buffer = featureTableBinary; + this._cachedTypedArrays = {}; + this.featuresLength = 0; + } - /** - * @cfg {Boolean} phone - * @inheritdoc Autolinker#phone - */ - phone: true, + function getTypedArrayFromBinary(featureTable, semantic, componentType, componentLength, count, byteOffset) { + var cachedTypedArrays = featureTable._cachedTypedArrays; + var typedArray = cachedTypedArrays[semantic]; + if (!defined(typedArray)) { + typedArray = ComponentDatatype.createArrayBufferView(componentType, featureTable.buffer.buffer, featureTable.buffer.byteOffset + byteOffset, count * componentLength); + cachedTypedArrays[semantic] = typedArray; + } + return typedArray; + } - /** - * @cfg {Boolean/String} hashtag - * @inheritdoc Autolinker#hashtag - */ - hashtag : false, + function getTypedArrayFromArray(featureTable, semantic, componentType, array) { + var cachedTypedArrays = featureTable._cachedTypedArrays; + var typedArray = cachedTypedArrays[semantic]; + if (!defined(typedArray)) { + typedArray = ComponentDatatype.createTypedArray(componentType, array); + cachedTypedArrays[semantic] = typedArray; + } + return typedArray; + } - /** - * @cfg {Boolean} stripPrefix - * @inheritdoc Autolinker#stripPrefix - */ - stripPrefix : true, + Cesium3DTileFeatureTable.prototype.getGlobalProperty = function(semantic, componentType, componentLength) { + var jsonValue = this.json[semantic]; + if (!defined(jsonValue)) { + return undefined; + } + if (defined(jsonValue.byteOffset)) { + componentType = defaultValue(componentType, ComponentDatatype.UNSIGNED_INT); + componentLength = defaultValue(componentLength, 1); + return getTypedArrayFromBinary(this, semantic, componentType, componentLength, 1, jsonValue.byteOffset); + } - /** - * @private - * @property {RegExp} matcherRegex - * - * The regular expression that matches URLs, email addresses, phone #s, - * Twitter handles, and Hashtags. - * - * This regular expression has the following capturing groups: - * - * 1. Group that is used to determine if there is a Twitter handle match - * (i.e. \@someTwitterUser). Simply check for its existence to determine - * if there is a Twitter handle match. The next couple of capturing - * groups give information about the Twitter handle match. - * 2. The whitespace character before the \@sign in a Twitter handle. This - * is needed because there are no lookbehinds in JS regular expressions, - * and can be used to reconstruct the original string in a replace(). - * 3. The Twitter handle itself in a Twitter match. If the match is - * '@someTwitterUser', the handle is 'someTwitterUser'. - * 4. Group that matches an email address. Used to determine if the match - * is an email address, as well as holding the full address. Ex: - * 'me@my.com' - * 5. Group that matches a URL in the input text. Ex: 'http://google.com', - * 'www.google.com', or just 'google.com'. This also includes a path, - * url parameters, or hash anchors. Ex: google.com/path/to/file?q1=1&q2=2#myAnchor - * 6. Group that matches a protocol URL (i.e. 'http://google.com'). This is - * used to match protocol URLs with just a single word, like 'http://localhost', - * where we won't double check that the domain name has at least one '.' - * in it. - * 7. A protocol-relative ('//') match for the case of a 'www.' prefixed - * URL. Will be an empty string if it is not a protocol-relative match. - * We need to know the character before the '//' in order to determine - * if it is a valid match or the // was in a string we don't want to - * auto-link. - * 8. A protocol-relative ('//') match for the case of a known TLD prefixed - * URL. Will be an empty string if it is not a protocol-relative match. - * See #6 for more info. - * 9. Group that is used to determine if there is a phone number match. The - * next 3 groups give segments of the phone number. - * 10. Group that is used to determine if there is a Hashtag match - * (i.e. \#someHashtag). Simply check for its existence to determine if - * there is a Hashtag match. The next couple of capturing groups give - * information about the Hashtag match. - * 11. The whitespace character before the #sign in a Hashtag handle. This - * is needed because there are no look-behinds in JS regular - * expressions, and can be used to reconstruct the original string in a - * replace(). - * 12. The Hashtag itself in a Hashtag match. If the match is - * '#someHashtag', the hashtag is 'someHashtag'. - */ - matcherRegex : (function() { - var twitterRegex = /(^|[^\w])@(\w{1,15})/, // For matching a twitter handle. Ex: @gregory_jacobs + return jsonValue; + }; - hashtagRegex = /(^|[^\w])#(\w{1,15})/, // For matching a Hashtag. Ex: #games + Cesium3DTileFeatureTable.prototype.getPropertyArray = function(semantic, componentType, componentLength) { + var jsonValue = this.json[semantic]; + if (!defined(jsonValue)) { + return undefined; + } - emailRegex = /(?:[\-;:&=\+\$,\w\.]+@)/, // something@ for email addresses (a.k.a. local-part) - phoneRegex = /(?:\+?\d{1,3}[-\s.])?\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/, // ex: (123) 456-7890, 123 456 7890, 123-456-7890, etc. - protocolRegex = /(?:[A-Za-z][-.+A-Za-z0-9]+:(?![A-Za-z][-.+A-Za-z0-9]+:\/\/)(?!\d+\/?)(?:\/\/)?)/, // match protocol, allow in format "http://" or "mailto:". However, do not match the first part of something like 'link:http://www.google.com' (i.e. don't match "link:"). Also, make sure we don't interpret 'google.com:8000' as if 'google.com' was a protocol here (i.e. ignore a trailing port number in this regex) - wwwRegex = /(?:www\.)/, // starting with 'www.' - domainNameRegex = /[A-Za-z0-9\.\-]*[A-Za-z0-9\-]/, // anything looking at all like a domain, non-unicode domains, not ending in a period - tldRegex = /\.(?:international|construction|contractors|enterprises|photography|productions|foundation|immobilien|industries|management|properties|technology|christmas|community|directory|education|equipment|institute|marketing|solutions|vacations|bargains|boutique|builders|catering|cleaning|clothing|computer|democrat|diamonds|graphics|holdings|lighting|partners|plumbing|supplies|training|ventures|academy|careers|company|cruises|domains|exposed|flights|florist|gallery|guitars|holiday|kitchen|neustar|okinawa|recipes|rentals|reviews|shiksha|singles|support|systems|agency|berlin|camera|center|coffee|condos|dating|estate|events|expert|futbol|kaufen|luxury|maison|monash|museum|nagoya|photos|repair|report|social|supply|tattoo|tienda|travel|viajes|villas|vision|voting|voyage|actor|build|cards|cheap|codes|dance|email|glass|house|mango|ninja|parts|photo|shoes|solar|today|tokyo|tools|watch|works|aero|arpa|asia|best|bike|blue|buzz|camp|club|cool|coop|farm|fish|gift|guru|info|jobs|kiwi|kred|land|limo|link|menu|mobi|moda|name|pics|pink|post|qpon|rich|ruhr|sexy|tips|vote|voto|wang|wien|wiki|zone|bar|bid|biz|cab|cat|ceo|com|edu|gov|int|kim|mil|net|onl|org|pro|pub|red|tel|uno|wed|xxx|xyz|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/, // match our known top level domains (TLDs) + if (defined(jsonValue.byteOffset)) { + if (defined(jsonValue.componentType)) { + componentType = ComponentDatatype.fromName(jsonValue.componentType); + } + return getTypedArrayFromBinary(this, semantic, componentType, componentLength, this.featuresLength, jsonValue.byteOffset); + } - // Allow optional path, query string, and hash anchor, not ending in the following characters: "?!:,.;" - // http://blog.codinghorror.com/the-problem-with-urls/ - urlSuffixRegex = /[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]?!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]]/; + return getTypedArrayFromArray(this, semantic, componentType, jsonValue); + }; - return new RegExp( [ - '(', // *** Capturing group $1, which can be used to check for a twitter handle match. Use group $3 for the actual twitter handle though. $2 may be used to reconstruct the original string in a replace() - // *** Capturing group $2, which matches the whitespace character before the '@' sign (needed because of no lookbehinds), and - // *** Capturing group $3, which matches the actual twitter handle - twitterRegex.source, - ')', + Cesium3DTileFeatureTable.prototype.getProperty = function(semantic, componentType, componentLength, featureId, result) { + var jsonValue = this.json[semantic]; + if (!defined(jsonValue)) { + return undefined; + } - '|', + var typedArray = this.getPropertyArray(semantic, componentType, componentLength); - '(', // *** Capturing group $4, which is used to determine an email match - emailRegex.source, - domainNameRegex.source, - tldRegex.source, - ')', + if (componentLength === 1) { + return typedArray[featureId]; + } - '|', + for (var i = 0; i < componentLength; ++i) { + result[i] = typedArray[componentLength * featureId + i]; + } - '(', // *** Capturing group $5, which is used to match a URL - '(?:', // parens to cover match for protocol (optional), and domain - '(', // *** Capturing group $6, for a protocol-prefixed url (ex: http://google.com) - protocolRegex.source, - domainNameRegex.source, - ')', + return result; + }; - '|', + return Cesium3DTileFeatureTable; +}); - '(?:', // non-capturing paren for a 'www.' prefixed url (ex: www.google.com) - '(.?//)?', // *** Capturing group $7 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character - wwwRegex.source, - domainNameRegex.source, - ')', +define('Scene/Vector3DTileBatch',[],function() { + 'use strict'; - '|', + /** + * Describes a renderable batch of geometry. + * + * @alias Vector3DTileBatch + * @constructor + * + * @param {Object} options An object with the following properties: + * @param {Number} options.offset The offset of the batch into the indices buffer. + * @param {Number} options.count The number of indices in the batch. + * @param {Color} options.color The color of the geometry in the batch. + * @param {Number[]} options.batchIds An array where each element is the batch id of the geometry in the batch. + * + * @private + */ + function Vector3DTileBatch(options) { + /** + * The offset of the batch into the indices buffer. + * @type {Number} + */ + this.offset = options.offset; + /** + * The number of indices in the batch. + * @type {Number} + */ + this.count = options.count; + /** + * The color of the geometry in the batch. + * @type {Color} + */ + this.color = options.color; + /** + * An array where each element is the batch id of the geometry in the batch. + * @type {Number[]} + */ + this.batchIds = options.batchIds; + } - '(?:', // non-capturing paren for known a TLD url (ex: google.com) - '(.?//)?', // *** Capturing group $8 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character - domainNameRegex.source, - tldRegex.source, - ')', - ')', + return Vector3DTileBatch; +}); - '(?:' + urlSuffixRegex.source + ')?', // match for path, query string, and/or hash anchor - optional - ')', +// JavaScript Expression Parser (JSEP) 0.3.1 +// JSEP may be freely distributed under the MIT License +// http://jsep.from.so/ - '|', +define('ThirdParty/jsep',[],function() { - // this setup does not scale well for open extension :( Need to rethink design of autolinker... - // *** Capturing group $9, which matches a (USA for now) phone number - '(', - phoneRegex.source, - ')', +/*global module: true, exports: true, console: true */ +(function (root) { + 'use strict'; + // Node Types + // ---------- - '|', + // This is the full set of types that any JSEP node can be. + // Store them here to save space when minified + var COMPOUND = 'Compound', + IDENTIFIER = 'Identifier', + MEMBER_EXP = 'MemberExpression', + LITERAL = 'Literal', + THIS_EXP = 'ThisExpression', + CALL_EXP = 'CallExpression', + UNARY_EXP = 'UnaryExpression', + BINARY_EXP = 'BinaryExpression', + LOGICAL_EXP = 'LogicalExpression', + CONDITIONAL_EXP = 'ConditionalExpression', + ARRAY_EXP = 'ArrayExpression', - '(', // *** Capturing group $10, which can be used to check for a Hashtag match. Use group $12 for the actual Hashtag though. $11 may be used to reconstruct the original string in a replace() - // *** Capturing group $11, which matches the whitespace character before the '#' sign (needed because of no lookbehinds), and - // *** Capturing group $12, which matches the actual Hashtag - hashtagRegex.source, - ')' - ].join( "" ), 'gi' ); - } )(), + PERIOD_CODE = 46, // '.' + COMMA_CODE = 44, // ',' + SQUOTE_CODE = 39, // single quote + DQUOTE_CODE = 34, // double quotes + OPAREN_CODE = 40, // ( + CPAREN_CODE = 41, // ) + OBRACK_CODE = 91, // [ + CBRACK_CODE = 93, // ] + QUMARK_CODE = 63, // ? + SEMCOL_CODE = 59, // ; + COLON_CODE = 58, // : - /** - * @private - * @property {RegExp} charBeforeProtocolRelMatchRegex - * - * The regular expression used to retrieve the character before a - * protocol-relative URL match. - * - * This is used in conjunction with the {@link #matcherRegex}, which needs - * to grab the character before a protocol-relative '//' due to the lack of - * a negative look-behind in JavaScript regular expressions. The character - * before the match is stripped from the URL. - */ - charBeforeProtocolRelMatchRegex : /^(.)?\/\//, + throwError = function(message, index) { + var error = new Error(message + ' at character ' + index); + error.index = index; + error.description = message; + throw error; + }, - /** - * @private - * @property {Autolinker.MatchValidator} matchValidator - * - * The MatchValidator object, used to filter out any false positives from - * the {@link #matcherRegex}. See {@link Autolinker.MatchValidator} for details. - */ + // Operations + // ---------- + // Set `t` to `true` to save space (when minified, not gzipped) + t = true, + // Use a quickly-accessible map to store all of the unary operators + // Values are set to `true` (it really doesn't matter) + unary_ops = {'-': t, '!': t, '~': t, '+': t}, + // Also use a map for the binary operations but set their values to their + // binary precedence for quick reference: + // see [Order of operations](http://en.wikipedia.org/wiki/Order_of_operations#Programming_language) + binary_ops = { + '||': 1, '&&': 2, '|': 3, '^': 4, '&': 5, + '==': 6, '!=': 6, '===': 6, '!==': 6, + '<': 7, '>': 7, '<=': 7, '>=': 7, + '<<':8, '>>': 8, '>>>': 8, + '+': 9, '-': 9, + '*': 10, '/': 10, '%': 10 + }, + // Get return the longest key length of any object + getMaxKeyLen = function(obj) { + var max_len = 0, len; + for(var key in obj) { + if((len = key.length) > max_len && obj.hasOwnProperty(key)) { + max_len = len; + } + } + return max_len; + }, + max_unop_len = getMaxKeyLen(unary_ops), + max_binop_len = getMaxKeyLen(binary_ops), + // Literals + // ---------- + // Store the values to return for the various literals we may encounter + literals = { + 'true': true, + 'false': false, + 'null': null + }, + // Except for `this`, which is special. This could be changed to something like `'self'` as well + this_str = 'this', + // Returns the precedence of a binary operator or `0` if it isn't a binary operator + binaryPrecedence = function(op_val) { + return binary_ops[op_val] || 0; + }, + // Utility function (gets called from multiple places) + // Also note that `a && b` and `a || b` are *logical* expressions, not binary expressions + createBinaryExpression = function (operator, left, right) { + var type = (operator === '||' || operator === '&&') ? LOGICAL_EXP : BINARY_EXP; + return { + type: type, + operator: operator, + left: left, + right: right + }; + }, + // `ch` is a character code in the next three functions + isDecimalDigit = function(ch) { + return (ch >= 48 && ch <= 57); // 0...9 + }, + isIdentifierStart = function(ch) { + return (ch === 36) || (ch === 95) || // `$` and `_` + (ch >= 65 && ch <= 90) || // A...Z + (ch >= 97 && ch <= 122) || // a...z + (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator + }, + isIdentifierPart = function(ch) { + return (ch === 36) || (ch === 95) || // `$` and `_` + (ch >= 65 && ch <= 90) || // A...Z + (ch >= 97 && ch <= 122) || // a...z + (ch >= 48 && ch <= 57) || // 0...9 + (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator + }, - /** - * @constructor - * @param {Object} [cfg] The configuration options for the AnchorTagBuilder - * instance, specified in an Object (map). - */ - constructor : function( cfg ) { - Autolinker.Util.assign( this, cfg ); + // Parsing + // ------- + // `expr` is a string with the passed in expression + jsep = function(expr) { + // `index` stores the character number we are currently at while `length` is a constant + // All of the gobbles below will modify `index` as we move along + var index = 0, + charAtFunc = expr.charAt, + charCodeAtFunc = expr.charCodeAt, + exprI = function(i) { return charAtFunc.call(expr, i); }, + exprICode = function(i) { return charCodeAtFunc.call(expr, i); }, + length = expr.length, - this.matchValidator = new Autolinker.MatchValidator(); - }, + // Push `index` up to the next non-space character + gobbleSpaces = function() { + var ch = exprICode(index); + // space or tab + while(ch === 32 || ch === 9) { + ch = exprICode(++index); + } + }, + // The main parsing function. Much of this code is dedicated to ternary expressions + gobbleExpression = function() { + var test = gobbleBinaryExpression(), + consequent, alternate; + gobbleSpaces(); + if(exprICode(index) === QUMARK_CODE) { + // Ternary expression: test ? consequent : alternate + index++; + consequent = gobbleExpression(); + if(!consequent) { + throwError('Expected expression', index); + } + gobbleSpaces(); + if(exprICode(index) === COLON_CODE) { + index++; + alternate = gobbleExpression(); + if(!alternate) { + throwError('Expected expression', index); + } + return { + type: CONDITIONAL_EXP, + test: test, + consequent: consequent, + alternate: alternate + }; + } else { + throwError('Expected :', index); + } + } else { + return test; + } + }, - /** - * Parses the input `text` to search for matches, and calls the `replaceFn` - * to allow replacements of the matches. Returns the `text` with matches - * replaced. - * - * @param {String} text The text to search and repace matches in. - * @param {Function} replaceFn The iterator function to handle the - * replacements. The function takes a single argument, a {@link Autolinker.match.Match} - * object, and should return the text that should make the replacement. - * @param {Object} [contextObj=window] The context object ("scope") to run - * the `replaceFn` in. - * @return {String} - */ - replace : function( text, replaceFn, contextObj ) { - var me = this; // for closure + // Search for the operation portion of the string (e.g. `+`, `===`) + // Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`) + // and move down from 3 to 2 to 1 character until a matching binary operation is found + // then, return that binary operation + gobbleBinaryOp = function() { + gobbleSpaces(); + var biop, to_check = expr.substr(index, max_binop_len), tc_len = to_check.length; + while(tc_len > 0) { + if(binary_ops.hasOwnProperty(to_check)) { + index += tc_len; + return to_check; + } + to_check = to_check.substr(0, --tc_len); + } + return false; + }, - return text.replace( this.matcherRegex, function( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 ) { - var matchDescObj = me.processCandidateMatch( matchStr, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12 ); // "match description" object + // This function is responsible for gobbling an individual expression, + // e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)` + gobbleBinaryExpression = function() { + var ch_i, node, biop, prec, stack, biop_info, left, right, i; - // Return out with no changes for match types that are disabled (url, - // email, phone, etc.), or for matches that are invalid (false - // positives from the matcherRegex, which can't use look-behinds - // since they are unavailable in JS). - if( !matchDescObj ) { - return matchStr; + // First, try to get the leftmost thing + // Then, check to see if there's a binary operator operating on that leftmost thing + left = gobbleToken(); + biop = gobbleBinaryOp(); - } else { - // Generate replacement text for the match from the `replaceFn` - var replaceStr = replaceFn.call( contextObj, matchDescObj.match ); - return matchDescObj.prefixStr + replaceStr + matchDescObj.suffixStr; - } - } ); - }, + // If there wasn't a binary operator, just return the leftmost node + if(!biop) { + return left; + } + // Otherwise, we need to start a stack to properly place the binary operations in their + // precedence structure + biop_info = { value: biop, prec: binaryPrecedence(biop)}; - /** - * Processes a candidate match from the {@link #matcherRegex}. - * - * Not all matches found by the regex are actual URL/Email/Phone/Twitter/Hashtag - * matches, as determined by the {@link #matchValidator}. In this case, the - * method returns `null`. Otherwise, a valid Object with `prefixStr`, - * `match`, and `suffixStr` is returned. - * - * @private - * @param {String} matchStr The full match that was found by the - * {@link #matcherRegex}. - * @param {String} twitterMatch The matched text of a Twitter handle, if the - * match is a Twitter match. - * @param {String} twitterHandlePrefixWhitespaceChar The whitespace char - * before the @ sign in a Twitter handle match. This is needed because of - * no lookbehinds in JS regexes, and is need to re-include the character - * for the anchor tag replacement. - * @param {String} twitterHandle The actual Twitter user (i.e the word after - * the @ sign in a Twitter match). - * @param {String} emailAddressMatch The matched email address for an email - * address match. - * @param {String} urlMatch The matched URL string for a URL match. - * @param {String} protocolUrlMatch The match URL string for a protocol - * match. Ex: 'http://yahoo.com'. This is used to match something like - * 'http://localhost', where we won't double check that the domain name - * has at least one '.' in it. - * @param {String} wwwProtocolRelativeMatch The '//' for a protocol-relative - * match from a 'www' url, with the character that comes before the '//'. - * @param {String} tldProtocolRelativeMatch The '//' for a protocol-relative - * match from a TLD (top level domain) match, with the character that - * comes before the '//'. - * @param {String} phoneMatch The matched text of a phone number - * @param {String} hashtagMatch The matched text of a Twitter - * Hashtag, if the match is a Hashtag match. - * @param {String} hashtagPrefixWhitespaceChar The whitespace char - * before the # sign in a Hashtag match. This is needed because of no - * lookbehinds in JS regexes, and is need to re-include the character for - * the anchor tag replacement. - * @param {String} hashtag The actual Hashtag (i.e the word - * after the # sign in a Hashtag match). - * - * @return {Object} A "match description object". This will be `null` if the - * match was invalid, or if a match type is disabled. Otherwise, this will - * be an Object (map) with the following properties: - * @return {String} return.prefixStr The char(s) that should be prepended to - * the replacement string. These are char(s) that were needed to be - * included from the regex match that were ignored by processing code, and - * should be re-inserted into the replacement stream. - * @return {String} return.suffixStr The char(s) that should be appended to - * the replacement string. These are char(s) that were needed to be - * included from the regex match that were ignored by processing code, and - * should be re-inserted into the replacement stream. - * @return {Autolinker.match.Match} return.match The Match object that - * represents the match that was found. - */ - processCandidateMatch : function( - matchStr, twitterMatch, twitterHandlePrefixWhitespaceChar, twitterHandle, - emailAddressMatch, urlMatch, protocolUrlMatch, wwwProtocolRelativeMatch, - tldProtocolRelativeMatch, phoneMatch, hashtagMatch, - hashtagPrefixWhitespaceChar, hashtag - ) { - // Note: The `matchStr` variable wil be fixed up to remove characters that are no longer needed (which will - // be added to `prefixStr` and `suffixStr`). + right = gobbleToken(); + if(!right) { + throwError("Expected expression after " + biop, index); + } + stack = [left, biop_info, right]; - var protocolRelativeMatch = wwwProtocolRelativeMatch || tldProtocolRelativeMatch, - match, // Will be an Autolinker.match.Match object + // Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm) + while((biop = gobbleBinaryOp())) { + prec = binaryPrecedence(biop); - prefixStr = "", // A string to use to prefix the anchor tag that is created. This is needed for the Twitter and Hashtag matches. - suffixStr = ""; // A string to suffix the anchor tag that is created. This is used if there is a trailing parenthesis that should not be auto-linked. + if(prec === 0) { + break; + } + biop_info = { value: biop, prec: prec }; - // Return out with `null` for match types that are disabled (url, email, - // twitter, hashtag), or for matches that are invalid (false positives - // from the matcherRegex, which can't use look-behinds since they are - // unavailable in JS). - if( - ( urlMatch && !this.urls ) || - ( emailAddressMatch && !this.email ) || - ( phoneMatch && !this.phone ) || - ( twitterMatch && !this.twitter ) || - ( hashtagMatch && !this.hashtag ) || - !this.matchValidator.isValidMatch( urlMatch, protocolUrlMatch, protocolRelativeMatch ) - ) { - return null; - } + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + biop = stack.pop().value; + left = stack.pop(); + node = createBinaryExpression(biop, left, right); + stack.push(node); + } - // Handle a closing parenthesis at the end of the match, and exclude it - // if there is not a matching open parenthesis - // in the match itself. - if( this.matchHasUnbalancedClosingParen( matchStr ) ) { - matchStr = matchStr.substr( 0, matchStr.length - 1 ); // remove the trailing ")" - suffixStr = ")"; // this will be added after the generated <a> tag - } + node = gobbleToken(); + if(!node) { + throwError("Expected expression after " + biop, index); + } + stack.push(biop_info, node); + } - if( emailAddressMatch ) { - match = new Autolinker.match.Email( { matchedText: matchStr, email: emailAddressMatch } ); + i = stack.length - 1; + node = stack[i]; + while(i > 1) { + node = createBinaryExpression(stack[i - 1].value, stack[i - 2], node); + i -= 2; + } + return node; + }, - } else if( twitterMatch ) { - // fix up the `matchStr` if there was a preceding whitespace char, - // which was needed to determine the match itself (since there are - // no look-behinds in JS regexes) - if( twitterHandlePrefixWhitespaceChar ) { - prefixStr = twitterHandlePrefixWhitespaceChar; - matchStr = matchStr.slice( 1 ); // remove the prefixed whitespace char from the match - } - match = new Autolinker.match.Twitter( { matchedText: matchStr, twitterHandle: twitterHandle } ); + // An individual part of a binary expression: + // e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis) + gobbleToken = function() { + var ch, to_check, tc_len; - } else if( phoneMatch ) { - // remove non-numeric values from phone number string - var cleanNumber = matchStr.replace( /\D/g, '' ); - match = new Autolinker.match.Phone( { matchedText: matchStr, number: cleanNumber } ); + gobbleSpaces(); + ch = exprICode(index); - } else if( hashtagMatch ) { - // fix up the `matchStr` if there was a preceding whitespace char, - // which was needed to determine the match itself (since there are - // no look-behinds in JS regexes) - if( hashtagPrefixWhitespaceChar ) { - prefixStr = hashtagPrefixWhitespaceChar; - matchStr = matchStr.slice( 1 ); // remove the prefixed whitespace char from the match - } - match = new Autolinker.match.Hashtag( { matchedText: matchStr, serviceName: this.hashtag, hashtag: hashtag } ); + if(isDecimalDigit(ch) || ch === PERIOD_CODE) { + // Char code 46 is a dot `.` which can start off a numeric literal + return gobbleNumericLiteral(); + } else if(ch === SQUOTE_CODE || ch === DQUOTE_CODE) { + // Single or double quotes + return gobbleStringLiteral(); + } else if(isIdentifierStart(ch) || ch === OPAREN_CODE) { // open parenthesis + // `foo`, `bar.baz` + return gobbleVariable(); + } else if (ch === OBRACK_CODE) { + return gobbleArray(); + } else { + to_check = expr.substr(index, max_unop_len); + tc_len = to_check.length; + while(tc_len > 0) { + if(unary_ops.hasOwnProperty(to_check)) { + index += tc_len; + return { + type: UNARY_EXP, + operator: to_check, + argument: gobbleToken(), + prefix: true + }; + } + to_check = to_check.substr(0, --tc_len); + } - } else { // url match - // If it's a protocol-relative '//' match, remove the character - // before the '//' (which the matcherRegex needed to match due to - // the lack of a negative look-behind in JavaScript regular - // expressions) - if( protocolRelativeMatch ) { - var charBeforeMatch = protocolRelativeMatch.match( this.charBeforeProtocolRelMatchRegex )[ 1 ] || ""; + return false; + } + }, + // Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to + // keep track of everything in the numeric literal and then calling `parseFloat` on that string + gobbleNumericLiteral = function() { + var number = '', ch, chCode; + while(isDecimalDigit(exprICode(index))) { + number += exprI(index++); + } - if( charBeforeMatch ) { // fix up the `matchStr` if there was a preceding char before a protocol-relative match, which was needed to determine the match itself (since there are no look-behinds in JS regexes) - prefixStr = charBeforeMatch; - matchStr = matchStr.slice( 1 ); // remove the prefixed char from the match - } - } + if(exprICode(index) === PERIOD_CODE) { // can start with a decimal marker + number += exprI(index++); - match = new Autolinker.match.Url( { - matchedText : matchStr, - url : matchStr, - protocolUrlMatch : !!protocolUrlMatch, - protocolRelativeMatch : !!protocolRelativeMatch, - stripPrefix : this.stripPrefix - } ); - } + while(isDecimalDigit(exprICode(index))) { + number += exprI(index++); + } + } - return { - prefixStr : prefixStr, - suffixStr : suffixStr, - match : match - }; - }, + ch = exprI(index); + if(ch === 'e' || ch === 'E') { // exponent marker + number += exprI(index++); + ch = exprI(index); + if(ch === '+' || ch === '-') { // exponent sign + number += exprI(index++); + } + while(isDecimalDigit(exprICode(index))) { //exponent itself + number += exprI(index++); + } + if(!isDecimalDigit(exprICode(index-1)) ) { + throwError('Expected exponent (' + number + exprI(index) + ')', index); + } + } - /** - * Determines if a match found has an unmatched closing parenthesis. If so, - * this parenthesis will be removed from the match itself, and appended - * after the generated anchor tag in {@link #processCandidateMatch}. - * - * A match may have an extra closing parenthesis at the end of the match - * because the regular expression must include parenthesis for URLs such as - * "wikipedia.com/something_(disambiguation)", which should be auto-linked. - * - * However, an extra parenthesis *will* be included when the URL itself is - * wrapped in parenthesis, such as in the case of "(wikipedia.com/something_(disambiguation))". - * In this case, the last closing parenthesis should *not* be part of the - * URL itself, and this method will return `true`. - * - * @private - * @param {String} matchStr The full match string from the {@link #matcherRegex}. - * @return {Boolean} `true` if there is an unbalanced closing parenthesis at - * the end of the `matchStr`, `false` otherwise. - */ - matchHasUnbalancedClosingParen : function( matchStr ) { - var lastChar = matchStr.charAt( matchStr.length - 1 ); + chCode = exprICode(index); + // Check to make sure this isn't a variable name that start with a number (123abc) + if(isIdentifierStart(chCode)) { + throwError('Variable names cannot start with a number (' + + number + exprI(index) + ')', index); + } else if(chCode === PERIOD_CODE) { + throwError('Unexpected period', index); + } - if( lastChar === ')' ) { - var openParensMatch = matchStr.match( /\(/g ), - closeParensMatch = matchStr.match( /\)/g ), - numOpenParens = ( openParensMatch && openParensMatch.length ) || 0, - numCloseParens = ( closeParensMatch && closeParensMatch.length ) || 0; + return { + type: LITERAL, + value: parseFloat(number), + raw: number + }; + }, - if( numOpenParens < numCloseParens ) { - return true; - } - } + // Parses a string literal, staring with single or double quotes with basic support for escape codes + // e.g. `"hello world"`, `'this is\nJSEP'` + gobbleStringLiteral = function() { + var str = '', quote = exprI(index++), closed = false, ch; - return false; - } + while(index < length) { + ch = exprI(index++); + if(ch === quote) { + closed = true; + break; + } else if(ch === '\\') { + // Check for all of the common escape codes + ch = exprI(index++); + switch(ch) { + case 'n': str += '\n'; break; + case 'r': str += '\r'; break; + case 't': str += '\t'; break; + case 'b': str += '\b'; break; + case 'f': str += '\f'; break; + case 'v': str += '\x0B'; break; + default : str += '\\' + ch; + } + } else { + str += ch; + } + } -} ); -/*global Autolinker */ -/*jshint scripturl:true */ -/** - * @private - * @class Autolinker.MatchValidator - * @extends Object - * - * Used by Autolinker to filter out false positives from the - * {@link Autolinker.matchParser.MatchParser#matcherRegex}. - * - * Due to the limitations of regular expressions (including the missing feature - * of look-behinds in JS regular expressions), we cannot always determine the - * validity of a given match. This class applies a bit of additional logic to - * filter out any false positives that have been matched by the - * {@link Autolinker.matchParser.MatchParser#matcherRegex}. - */ -Autolinker.MatchValidator = Autolinker.Util.extend( Object, { + if(!closed) { + throwError('Unclosed quote after "'+str+'"', index); + } - /** - * @private - * @property {RegExp} invalidProtocolRelMatchRegex - * - * The regular expression used to check a potential protocol-relative URL - * match, coming from the {@link Autolinker.matchParser.MatchParser#matcherRegex}. - * A protocol-relative URL is, for example, "//yahoo.com" - * - * This regular expression checks to see if there is a word character before - * the '//' match in order to determine if we should actually autolink a - * protocol-relative URL. This is needed because there is no negative - * look-behind in JavaScript regular expressions. - * - * For instance, we want to autolink something like "Go to: //google.com", - * but we don't want to autolink something like "abc//google.com" - */ - invalidProtocolRelMatchRegex : /^[\w]\/\//, + return { + type: LITERAL, + value: str, + raw: quote + str + quote + }; + }, - /** - * Regex to test for a full protocol, with the two trailing slashes. Ex: 'http://' - * - * @private - * @property {RegExp} hasFullProtocolRegex - */ - hasFullProtocolRegex : /^[A-Za-z][-.+A-Za-z0-9]+:\/\//, + // Gobbles only identifiers + // e.g.: `foo`, `_value`, `$x1` + // Also, this function checks if that identifier is a literal: + // (e.g. `true`, `false`, `null`) or `this` + gobbleIdentifier = function() { + var ch = exprICode(index), start = index, identifier; - /** - * Regex to find the URI scheme, such as 'mailto:'. - * - * This is used to filter out 'javascript:' and 'vbscript:' schemes. - * - * @private - * @property {RegExp} uriSchemeRegex - */ - uriSchemeRegex : /^[A-Za-z][-.+A-Za-z0-9]+:/, + if(isIdentifierStart(ch)) { + index++; + } else { + throwError('Unexpected ' + exprI(index), index); + } - /** - * Regex to determine if at least one word char exists after the protocol (i.e. after the ':') - * - * @private - * @property {RegExp} hasWordCharAfterProtocolRegex - */ - hasWordCharAfterProtocolRegex : /:[^\s]*?[A-Za-z]/, + while(index < length) { + ch = exprICode(index); + if(isIdentifierPart(ch)) { + index++; + } else { + break; + } + } + identifier = expr.slice(start, index); + if(literals.hasOwnProperty(identifier)) { + return { + type: LITERAL, + value: literals[identifier], + raw: identifier + }; + } else if(identifier === this_str) { + return { type: THIS_EXP }; + } else { + return { + type: IDENTIFIER, + name: identifier + }; + } + }, - /** - * Determines if a given match found by the {@link Autolinker.matchParser.MatchParser} - * is valid. Will return `false` for: - * - * 1) URL matches which do not have at least have one period ('.') in the - * domain name (effectively skipping over matches like "abc:def"). - * However, URL matches with a protocol will be allowed (ex: 'http://localhost') - * 2) URL matches which do not have at least one word character in the - * domain name (effectively skipping over matches like "git:1.0"). - * 3) A protocol-relative url match (a URL beginning with '//') whose - * previous character is a word character (effectively skipping over - * strings like "abc//google.com") - * - * Otherwise, returns `true`. - * - * @param {String} urlMatch The matched URL, if there was one. Will be an - * empty string if the match is not a URL match. - * @param {String} protocolUrlMatch The match URL string for a protocol - * match. Ex: 'http://yahoo.com'. This is used to match something like - * 'http://localhost', where we won't double check that the domain name - * has at least one '.' in it. - * @param {String} protocolRelativeMatch The protocol-relative string for a - * URL match (i.e. '//'), possibly with a preceding character (ex, a - * space, such as: ' //', or a letter, such as: 'a//'). The match is - * invalid if there is a word character preceding the '//'. - * @return {Boolean} `true` if the match given is valid and should be - * processed, or `false` if the match is invalid and/or should just not be - * processed. - */ - isValidMatch : function( urlMatch, protocolUrlMatch, protocolRelativeMatch ) { - if( - ( protocolUrlMatch && !this.isValidUriScheme( protocolUrlMatch ) ) || - this.urlMatchDoesNotHaveProtocolOrDot( urlMatch, protocolUrlMatch ) || // At least one period ('.') must exist in the URL match for us to consider it an actual URL, *unless* it was a full protocol match (like 'http://localhost') - this.urlMatchDoesNotHaveAtLeastOneWordChar( urlMatch, protocolUrlMatch ) || // At least one letter character must exist in the domain name after a protocol match. Ex: skip over something like "git:1.0" - this.isInvalidProtocolRelativeMatch( protocolRelativeMatch ) // A protocol-relative match which has a word character in front of it (so we can skip something like "abc//google.com") - ) { - return false; - } + // Gobbles a list of arguments within the context of a function call + // or array literal. This function also assumes that the opening character + // `(` or `[` has already been gobbled, and gobbles expressions and commas + // until the terminator character `)` or `]` is encountered. + // e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]` + gobbleArguments = function(termination) { + var ch_i, args = [], node, closed = false; + while(index < length) { + gobbleSpaces(); + ch_i = exprICode(index); + if(ch_i === termination) { // done parsing + closed = true; + index++; + break; + } else if (ch_i === COMMA_CODE) { // between expressions + index++; + } else { + node = gobbleExpression(); + if(!node || node.type === COMPOUND) { + throwError('Expected comma', index); + } + args.push(node); + } + } + if (!closed) { + throwError('Expected ' + String.fromCharCode(termination), index); + } + return args; + }, + + // Gobble a non-literal variable name. This variable name may include properties + // e.g. `foo`, `bar.baz`, `foo['bar'].baz` + // It also gobbles function calls: + // e.g. `Math.acos(obj.angle)` + gobbleVariable = function() { + var ch_i, node; + ch_i = exprICode(index); + + if(ch_i === OPAREN_CODE) { + node = gobbleGroup(); + } else { + node = gobbleIdentifier(); + } + gobbleSpaces(); + ch_i = exprICode(index); + while(ch_i === PERIOD_CODE || ch_i === OBRACK_CODE || ch_i === OPAREN_CODE) { + index++; + if(ch_i === PERIOD_CODE) { + gobbleSpaces(); + node = { + type: MEMBER_EXP, + computed: false, + object: node, + property: gobbleIdentifier() + }; + } else if(ch_i === OBRACK_CODE) { + node = { + type: MEMBER_EXP, + computed: true, + object: node, + property: gobbleExpression() + }; + gobbleSpaces(); + ch_i = exprICode(index); + if(ch_i !== CBRACK_CODE) { + throwError('Unclosed [', index); + } + index++; + } else if(ch_i === OPAREN_CODE) { + // A function call is being made; gobble all the arguments + node = { + type: CALL_EXP, + 'arguments': gobbleArguments(CPAREN_CODE), + callee: node + }; + } + gobbleSpaces(); + ch_i = exprICode(index); + } + return node; + }, - return true; - }, + // Responsible for parsing a group of things within parentheses `()` + // This function assumes that it needs to gobble the opening parenthesis + // and then tries to gobble everything within that parenthesis, assuming + // that the next thing it should see is the close parenthesis. If not, + // then the expression probably doesn't have a `)` + gobbleGroup = function() { + index++; + var node = gobbleExpression(); + gobbleSpaces(); + if(exprICode(index) === CPAREN_CODE) { + index++; + return node; + } else { + throwError('Unclosed (', index); + } + }, + // Responsible for parsing Array literals `[1, 2, 3]` + // This function assumes that it needs to gobble the opening bracket + // and then tries to gobble the expressions as arguments. + gobbleArray = function() { + index++; + return { + type: ARRAY_EXP, + elements: gobbleArguments(CBRACK_CODE) + }; + }, - /** - * Determines if the URI scheme is a valid scheme to be autolinked. Returns - * `false` if the scheme is 'javascript:' or 'vbscript:' - * - * @private - * @param {String} uriSchemeMatch The match URL string for a full URI scheme - * match. Ex: 'http://yahoo.com' or 'mailto:a@a.com'. - * @return {Boolean} `true` if the scheme is a valid one, `false` otherwise. - */ - isValidUriScheme : function( uriSchemeMatch ) { - var uriScheme = uriSchemeMatch.match( this.uriSchemeRegex )[ 0 ].toLowerCase(); + nodes = [], ch_i, node; - return ( uriScheme !== 'javascript:' && uriScheme !== 'vbscript:' ); - }, + while(index < length) { + ch_i = exprICode(index); + // Expressions can be separated by semicolons, commas, or just inferred without any + // separators + if(ch_i === SEMCOL_CODE || ch_i === COMMA_CODE) { + index++; // ignore separators + } else { + // Try to gobble each expression individually + if((node = gobbleExpression())) { + nodes.push(node); + // If we weren't able to find a binary expression and are out of room, then + // the expression passed in probably has too much + } else if(index < length) { + throwError('Unexpected "' + exprI(index) + '"', index); + } + } + } - /** - * Determines if a URL match does not have either: - * - * a) a full protocol (i.e. 'http://'), or - * b) at least one dot ('.') in the domain name (for a non-full-protocol - * match). - * - * Either situation is considered an invalid URL (ex: 'git:d' does not have - * either the '://' part, or at least one dot in the domain name. If the - * match was 'git:abc.com', we would consider this valid.) - * - * @private - * @param {String} urlMatch The matched URL, if there was one. Will be an - * empty string if the match is not a URL match. - * @param {String} protocolUrlMatch The match URL string for a protocol - * match. Ex: 'http://yahoo.com'. This is used to match something like - * 'http://localhost', where we won't double check that the domain name - * has at least one '.' in it. - * @return {Boolean} `true` if the URL match does not have a full protocol, - * or at least one dot ('.') in a non-full-protocol match. - */ - urlMatchDoesNotHaveProtocolOrDot : function( urlMatch, protocolUrlMatch ) { - return ( !!urlMatch && ( !protocolUrlMatch || !this.hasFullProtocolRegex.test( protocolUrlMatch ) ) && urlMatch.indexOf( '.' ) === -1 ); - }, + // If there's only one expression just try returning the expression + if(nodes.length === 1) { + return nodes[0]; + } else { + return { + type: COMPOUND, + body: nodes + }; + } + }; + // To be filled in by the template + jsep.version = '0.3.1'; + jsep.toString = function() { return 'JavaScript Expression Parser (JSEP) v' + jsep.version; }; /** - * Determines if a URL match does not have at least one word character after - * the protocol (i.e. in the domain name). - * - * At least one letter character must exist in the domain name after a - * protocol match. Ex: skip over something like "git:1.0" - * - * @private - * @param {String} urlMatch The matched URL, if there was one. Will be an - * empty string if the match is not a URL match. - * @param {String} protocolUrlMatch The match URL string for a protocol - * match. Ex: 'http://yahoo.com'. This is used to know whether or not we - * have a protocol in the URL string, in order to check for a word - * character after the protocol separator (':'). - * @return {Boolean} `true` if the URL match does not have at least one word - * character in it after the protocol, `false` otherwise. + * @method jsep.addUnaryOp + * @param {string} op_name The name of the unary op to add + * @return jsep */ - urlMatchDoesNotHaveAtLeastOneWordChar : function( urlMatch, protocolUrlMatch ) { - if( urlMatch && protocolUrlMatch ) { - return !this.hasWordCharAfterProtocolRegex.test( urlMatch ); - } else { - return false; - } - }, - + jsep.addUnaryOp = function(op_name) { + max_unop_len = Math.max(op_name.length, max_unop_len); + unary_ops[op_name] = t; return this; + }; /** - * Determines if a protocol-relative match is an invalid one. This method - * returns `true` if there is a `protocolRelativeMatch`, and that match - * contains a word character before the '//' (i.e. it must contain - * whitespace or nothing before the '//' in order to be considered valid). - * - * @private - * @param {String} protocolRelativeMatch The protocol-relative string for a - * URL match (i.e. '//'), possibly with a preceding character (ex, a - * space, such as: ' //', or a letter, such as: 'a//'). The match is - * invalid if there is a word character preceding the '//'. - * @return {Boolean} `true` if it is an invalid protocol-relative match, - * `false` otherwise. + * @method jsep.addBinaryOp + * @param {string} op_name The name of the binary op to add + * @param {number} precedence The precedence of the binary op (can be a float) + * @return jsep */ - isInvalidProtocolRelativeMatch : function( protocolRelativeMatch ) { - return ( !!protocolRelativeMatch && this.invalidProtocolRelMatchRegex.test( protocolRelativeMatch ) ); - } + jsep.addBinaryOp = function(op_name, precedence) { + max_binop_len = Math.max(op_name.length, max_binop_len); + binary_ops[op_name] = precedence; + return this; + }; -} ); -/*global Autolinker */ -/** - * @abstract - * @class Autolinker.match.Match - * - * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a - * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match. - * - * For example: - * - * var input = "..."; // string with URLs, Email Addresses, and Twitter Handles - * - * var linkedText = Autolinker.link( input, { - * replaceFn : function( autolinker, match ) { - * console.log( "href = ", match.getAnchorHref() ); - * console.log( "text = ", match.getAnchorText() ); - * - * switch( match.getType() ) { - * case 'url' : - * console.log( "url: ", match.getUrl() ); - * - * case 'email' : - * console.log( "email: ", match.getEmail() ); - * - * case 'twitter' : - * console.log( "twitter: ", match.getTwitterHandle() ); - * } - * } - * } ); - * - * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}. - */ -Autolinker.match.Match = Autolinker.Util.extend( Object, { - - /** - * @cfg {String} matchedText (required) - * - * The original text that was matched. - */ - - /** - * @constructor - * @param {Object} cfg The configuration properties for the Match instance, specified in an Object (map). + * @method jsep.addLiteral + * @param {string} literal_name The name of the literal to add + * @param {*} literal_value The value of the literal + * @return jsep */ - constructor : function( cfg ) { - Autolinker.Util.assign( this, cfg ); - }, + jsep.addLiteral = function(literal_name, literal_value) { + literals[literal_name] = literal_value; + return this; + }; - - /** - * Returns a string name for the type of match that this class represents. - * - * @abstract - * @return {String} - */ - getType : Autolinker.Util.abstractMethod, - - /** - * Returns the original text that was matched. - * - * @return {String} + * @method jsep.removeUnaryOp + * @param {string} op_name The name of the unary op to remove + * @return jsep */ - getMatchedText : function() { - return this.matchedText; - }, - + jsep.removeUnaryOp = function(op_name) { + delete unary_ops[op_name]; + if(op_name.length === max_unop_len) { + max_unop_len = getMaxKeyLen(unary_ops); + } + return this; + }; /** - * Returns the anchor href that should be generated for the match. - * - * @abstract - * @return {String} - */ - getAnchorHref : Autolinker.Util.abstractMethod, - - - /** - * Returns the anchor text that should be generated for the match. - * - * @abstract - * @return {String} + * @method jsep.removeAllUnaryOps + * @return jsep */ - getAnchorText : Autolinker.Util.abstractMethod + jsep.removeAllUnaryOps = function() { + unary_ops = {}; + max_unop_len = 0; -} ); -/*global Autolinker */ -/** - * @class Autolinker.match.Email - * @extends Autolinker.match.Match - * - * Represents a Email match found in an input string which should be Autolinked. - * - * See this class's superclass ({@link Autolinker.match.Match}) for more details. - */ -Autolinker.match.Email = Autolinker.Util.extend( Autolinker.match.Match, { - - /** - * @cfg {String} email (required) - * - * The email address that was matched. - */ - + return this; + }; /** - * Returns a string name for the type of match that this class represents. - * - * @return {String} - */ - getType : function() { - return 'email'; - }, - - - /** - * Returns the email address that was matched. - * - * @return {String} + * @method jsep.removeBinaryOp + * @param {string} op_name The name of the binary op to remove + * @return jsep */ - getEmail : function() { - return this.email; - }, - + jsep.removeBinaryOp = function(op_name) { + delete binary_ops[op_name]; + if(op_name.length === max_binop_len) { + max_binop_len = getMaxKeyLen(binary_ops); + } + return this; + }; /** - * Returns the anchor href that should be generated for the match. - * - * @return {String} - */ - getAnchorHref : function() { - return 'mailto:' + this.email; - }, - - - /** - * Returns the anchor text that should be generated for the match. - * - * @return {String} + * @method jsep.removeAllBinaryOps + * @return jsep */ - getAnchorText : function() { - return this.email; - } - -} ); -/*global Autolinker */ -/** - * @class Autolinker.match.Hashtag - * @extends Autolinker.match.Match - * - * Represents a Hashtag match found in an input string which should be - * Autolinked. - * - * See this class's superclass ({@link Autolinker.match.Match}) for more - * details. - */ -Autolinker.match.Hashtag = Autolinker.Util.extend( Autolinker.match.Match, { + jsep.removeAllBinaryOps = function() { + binary_ops = {}; + max_binop_len = 0; + + return this; + }; /** - * @cfg {String} serviceName (required) - * - * The service to point hashtag matches to. See {@link Autolinker#hashtag} - * for available values. + * @method jsep.removeLiteral + * @param {string} literal_name The name of the literal to remove + * @return jsep */ + jsep.removeLiteral = function(literal_name) { + delete literals[literal_name]; + return this; + }; /** - * @cfg {String} hashtag (required) - * - * The Hashtag that was matched, without the '#'. + * @method jsep.removeAllLiterals + * @return jsep */ + jsep.removeAllLiterals = function() { + literals = {}; + return this; + }; - /** - * Returns the type of match that this class represents. - * - * @return {String} - */ - getType : function() { - return 'hashtag'; - }, + // In desktop environments, have a way to restore the old value for `jsep` + if (typeof exports === 'undefined') { + var old_jsep = root.jsep; + // The star of the show! It's a function! + root.jsep = jsep; + // And a courteous function willing to move out of the way for other similarly-named objects! + jsep.noConflict = function() { + if(root.jsep === jsep) { + root.jsep = old_jsep; + } + return jsep; + }; + } else { + // In Node.JS environments + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = jsep; + } else { + exports.parse = jsep; + } + } +}(this)); + // `jsep` only exists when running in the browser + if (typeof jsep !== 'undefined') { + return jsep.noConflict(); + } +}); - /** - * Returns the matched hashtag. - * - * @return {String} - */ - getHashtag : function() { - return this.hashtag; - }, +define('Scene/ExpressionNodeType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** + * @private + */ + var ExpressionNodeType = { + VARIABLE : 0, + UNARY : 1, + BINARY : 2, + TERNARY : 3, + CONDITIONAL : 4, + MEMBER : 5, + FUNCTION_CALL : 6, + ARRAY : 7, + REGEX: 8, + VARIABLE_IN_STRING : 9, + LITERAL_NULL : 10, + LITERAL_BOOLEAN : 11, + LITERAL_NUMBER : 12, + LITERAL_STRING : 13, + LITERAL_COLOR : 14, + LITERAL_VECTOR : 15, + LITERAL_REGEX : 16, + LITERAL_UNDEFINED : 17, + BUILTIN_VARIABLE : 18 + }; - /** - * Returns the anchor href that should be generated for the match. - * - * @return {String} - */ - getAnchorHref : function() { - var serviceName = this.serviceName, - hashtag = this.hashtag; + return freezeObject(ExpressionNodeType); +}); - switch( serviceName ) { - case 'twitter' : - return 'https://twitter.com/hashtag/' + hashtag; - case 'facebook' : - return 'https://www.facebook.com/hashtag/' + hashtag; +define('Scene/Expression',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Check', + '../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/isArray', + '../Core/Math', + '../Core/RuntimeError', + '../ThirdParty/jsep', + './ExpressionNodeType' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + Check, + Color, + defined, + defineProperties, + DeveloperError, + isArray, + CesiumMath, + RuntimeError, + jsep, + ExpressionNodeType) { + 'use strict'; - default : // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case. - throw new Error( 'Unknown service name to point hashtag to: ', serviceName ); - } - }, + /** + * An expression for a style applied to a {@link Cesium3DTileset}. + * <p> + * Evaluates an expression defined using the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. + * </p> + * <p> + * Implements the {@link StyleExpression} interface. + * </p> + * + * @alias Expression + * @constructor + * + * @param {String} [expression] The expression defined using the 3D Tiles Styling language. + * @param {Object} [defines] Defines in the style. + * + * @example + * var expression = new Cesium.Expression('(regExp("^Chest").test(${County})) && (${YearBuilt} >= 1970)'); + * expression.evaluate(frameState, feature); // returns true or false depending on the feature's properties + * + * @example + * var expression = new Cesium.Expression('(${Temperature} > 90) ? color("red") : color("white")'); + * expression.evaluateColor(frameState, feature, result); // returns a Cesium.Color object + */ + function Expression(expression, defines) { + Check.typeOf.string('expression', expression); + + this._expression = expression; + expression = replaceDefines(expression, defines); + expression = replaceVariables(removeBackslashes(expression)); + // customize jsep operators + jsep.addBinaryOp('=~', 0); + jsep.addBinaryOp('!~', 0); - /** - * Returns the anchor text that should be generated for the match. - * - * @return {String} - */ - getAnchorText : function() { - return '#' + this.hashtag; - } + var ast; + try { + ast = jsep(expression); + } catch (e) { + throw new RuntimeError(e); + } -} ); -/*global Autolinker */ -/** - * @class Autolinker.match.Phone - * @extends Autolinker.match.Match - * - * Represents a Phone number match found in an input string which should be - * Autolinked. - * - * See this class's superclass ({@link Autolinker.match.Match}) for more - * details. - */ -Autolinker.match.Phone = Autolinker.Util.extend( Autolinker.match.Match, { + this._runtimeAst = createRuntimeAst(this, ast); + } - /** - * @cfg {String} number (required) - * - * The phone number that was matched. - */ + defineProperties(Expression.prototype, { + /** + * Gets the expression defined in the 3D Tiles Styling language. + * + * @memberof Expression.prototype + * + * @type {String} + * @readonly + * + * @default undefined + */ + expression : { + get : function() { + return this._expression; + } + } + }); + // Scratch storage manager while evaluating deep expressions. + // For example, an expression like dot(vec4(${red}), vec4(${green}) * vec4(${blue}) requires 3 scratch Cartesian4's + var scratchStorage = { + arrayIndex : 0, + arrayArray : [[]], + cartesian2Index : 0, + cartesian3Index : 0, + cartesian4Index : 0, + cartesian2Array : [new Cartesian2()], + cartesian3Array : [new Cartesian3()], + cartesian4Array : [new Cartesian4()], + reset : function() { + this.arrayIndex = 0; + this.cartesian2Index = 0; + this.cartesian3Index = 0; + this.cartesian4Index = 0; + }, + getArray : function() { + if (this.arrayIndex >= this.arrayArray.length) { + this.arrayArray.push([]); + } + var array = this.arrayArray[this.arrayIndex++]; + array.length = 0; + return array; + }, + getCartesian2 : function() { + if (this.cartesian2Index >= this.cartesian2Array.length) { + this.cartesian2Array.push(new Cartesian2()); + } + return this.cartesian2Array[this.cartesian2Index++]; + }, + getCartesian3 : function() { + if (this.cartesian3Index >= this.cartesian3Array.length) { + this.cartesian3Array.push(new Cartesian3()); + } + return this.cartesian3Array[this.cartesian3Index++]; + }, + getCartesian4 : function() { + if (this.cartesian4Index >= this.cartesian4Array.length) { + this.cartesian4Array.push(new Cartesian4()); + } + return this.cartesian4Array[this.cartesian4Index++]; + } + }; - /** - * Returns a string name for the type of match that this class represents. - * - * @return {String} - */ - getType : function() { - return 'phone'; - }, + /** + * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of + * the expression in the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} + * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript + * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code> + * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>, + * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is + * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. + * @param {Object} [result] The object onto which to store the result. + * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. + */ + Expression.prototype.evaluate = function(frameState, feature, result) { + scratchStorage.reset(); + var value = this._runtimeAst.evaluate(frameState, feature); + if ((result instanceof Color) && (value instanceof Cartesian4)) { + return Color.fromCartesian4(value, result); + } + if ((value instanceof Cartesian2) || (value instanceof Cartesian3) || (value instanceof Cartesian4)) { + return value.clone(result); + } + return value; + }; + /** + * Evaluates the result of a Color expression, optionally using the provided feature's properties. + * <p> + * This is equivalent to {@link Expression#evaluate} but always returns a {@link Color} object. + * </p> + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. + * @param {Color} [result] The object in which to store the result + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + */ + Expression.prototype.evaluateColor = function(frameState, feature, result) { + scratchStorage.reset(); + var color = this._runtimeAst.evaluate(frameState, feature); + return Color.fromCartesian4(color, result); + }; - /** - * Returns the phone number that was matched. - * - * @return {String} - */ - getNumber: function() { - return this.number; - }, + /** + * Gets the shader function for this expression. + * Returns undefined if the shader function can't be generated from this expression. + * + * @param {String} functionName Name to give to the generated function. + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {String} returnType The return type of the generated function. + * + * @returns {String} The shader function. + * + * @private + */ + Expression.prototype.getShaderFunction = function(functionName, attributePrefix, shaderState, returnType) { + var shaderExpression = this.getShaderExpression(attributePrefix, shaderState); + shaderExpression = returnType + ' ' + functionName + '() \n' + + '{ \n' + + ' return ' + shaderExpression + '; \n' + + '} \n'; - /** - * Returns the anchor href that should be generated for the match. - * - * @return {String} - */ - getAnchorHref : function() { - return 'tel:' + this.number; - }, + return shaderExpression; + }; + /** + * Gets the shader expression for this expression. + * Returns undefined if the shader expression can't be generated from this expression. + * + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * + * @returns {String} The shader expression. + * + * @private + */ + Expression.prototype.getShaderExpression = function(attributePrefix, shaderState) { + return this._runtimeAst.getShaderExpression(attributePrefix, shaderState); + }; - /** - * Returns the anchor text that should be generated for the match. - * - * @return {String} - */ - getAnchorText : function() { - return this.matchedText; - } + var unaryOperators = ['!', '-', '+']; + var binaryOperators = ['+', '-', '*', '/', '%', '===', '!==', '>', '>=', '<', '<=', '&&', '||', '!~', '=~']; -} ); + var variableRegex = /\${(.*?)}/g; // Matches ${variable_name} + var backslashRegex = /\\/g; + var backslashReplacement = '@#%'; + var replacementRegex = /@#%/g; -/*global Autolinker */ -/** - * @class Autolinker.match.Twitter - * @extends Autolinker.match.Match - * - * Represents a Twitter match found in an input string which should be Autolinked. - * - * See this class's superclass ({@link Autolinker.match.Match}) for more details. - */ -Autolinker.match.Twitter = Autolinker.Util.extend( Autolinker.match.Match, { - - /** - * @cfg {String} twitterHandle (required) - * - * The Twitter handle that was matched. - */ - + var scratchColor = new Color(); - /** - * Returns the type of match that this class represents. - * - * @return {String} - */ - getType : function() { - return 'twitter'; - }, - - - /** - * Returns a string name for the type of match that this class represents. - * - * @return {String} - */ - getTwitterHandle : function() { - return this.twitterHandle; - }, - + var unaryFunctions = { + abs : getEvaluateUnaryComponentwise(Math.abs), + sqrt : getEvaluateUnaryComponentwise(Math.sqrt), + cos : getEvaluateUnaryComponentwise(Math.cos), + sin : getEvaluateUnaryComponentwise(Math.sin), + tan : getEvaluateUnaryComponentwise(Math.tan), + acos : getEvaluateUnaryComponentwise(Math.acos), + asin : getEvaluateUnaryComponentwise(Math.asin), + atan : getEvaluateUnaryComponentwise(Math.atan), + radians : getEvaluateUnaryComponentwise(CesiumMath.toRadians), + degrees : getEvaluateUnaryComponentwise(CesiumMath.toDegrees), + sign : getEvaluateUnaryComponentwise(CesiumMath.sign), + floor : getEvaluateUnaryComponentwise(Math.floor), + ceil : getEvaluateUnaryComponentwise(Math.ceil), + round : getEvaluateUnaryComponentwise(Math.round), + exp : getEvaluateUnaryComponentwise(Math.exp), + exp2 : getEvaluateUnaryComponentwise(exp2), + log : getEvaluateUnaryComponentwise(Math.log), + log2 : getEvaluateUnaryComponentwise(log2), + fract : getEvaluateUnaryComponentwise(fract), + length : length, + normalize: normalize + }; - /** - * Returns the anchor href that should be generated for the match. - * - * @return {String} - */ - getAnchorHref : function() { - return 'https://twitter.com/' + this.twitterHandle; - }, - - - /** - * Returns the anchor text that should be generated for the match. - * - * @return {String} - */ - getAnchorText : function() { - return '@' + this.twitterHandle; - } - -} ); -/*global Autolinker */ -/** - * @class Autolinker.match.Url - * @extends Autolinker.match.Match - * - * Represents a Url match found in an input string which should be Autolinked. - * - * See this class's superclass ({@link Autolinker.match.Match}) for more details. - */ -Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, { - - /** - * @cfg {String} url (required) - * - * The url that was matched. - */ - - /** - * @cfg {Boolean} protocolUrlMatch (required) - * - * `true` if the URL is a match which already has a protocol (i.e. 'http://'), `false` if the match was from a 'www' or - * known TLD match. - */ - - /** - * @cfg {Boolean} protocolRelativeMatch (required) - * - * `true` if the URL is a protocol-relative match. A protocol-relative match is a URL that starts with '//', - * and will be either http:// or https:// based on the protocol that the site is loaded under. - */ - - /** - * @cfg {Boolean} stripPrefix (required) - * @inheritdoc Autolinker#stripPrefix - */ - + var binaryFunctions = { + atan2 : getEvaluateBinaryCommponentwise(Math.atan2, false), + pow : getEvaluateBinaryCommponentwise(Math.pow, false), + min : getEvaluateBinaryCommponentwise(Math.min, true), + max : getEvaluateBinaryCommponentwise(Math.max, true), + distance : distance, + dot : dot, + cross : cross + }; - /** - * @private - * @property {RegExp} urlPrefixRegex - * - * A regular expression used to remove the 'http://' or 'https://' and/or the 'www.' from URLs. - */ - urlPrefixRegex: /^(https?:\/\/)?(www\.)?/i, - - /** - * @private - * @property {RegExp} protocolRelativeRegex - * - * The regular expression used to remove the protocol-relative '//' from the {@link #url} string, for purposes - * of {@link #getAnchorText}. A protocol-relative URL is, for example, "//yahoo.com" - */ - protocolRelativeRegex : /^\/\//, - - /** - * @private - * @property {Boolean} protocolPrepended - * - * Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the - * {@link #url} did not have a protocol) - */ - protocolPrepended : false, - + var ternaryFunctions = { + clamp : getEvaluateTernaryCommponentwise(CesiumMath.clamp, true), + mix : getEvaluateTernaryCommponentwise(CesiumMath.lerp, true) + }; - /** - * Returns a string name for the type of match that this class represents. - * - * @return {String} - */ - getType : function() { - return 'url'; - }, - - - /** - * Returns the url that was matched, assuming the protocol to be 'http://' if the original - * match was missing a protocol. - * - * @return {String} - */ - getUrl : function() { - var url = this.url; - - // if the url string doesn't begin with a protocol, assume 'http://' - if( !this.protocolRelativeMatch && !this.protocolUrlMatch && !this.protocolPrepended ) { - url = this.url = 'http://' + url; - - this.protocolPrepended = true; - } - - return url; - }, - + function fract(number) { + return number - Math.floor(number); + } - /** - * Returns the anchor href that should be generated for the match. - * - * @return {String} - */ - getAnchorHref : function() { - var url = this.getUrl(); - - return url.replace( /&/g, '&' ); // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html - }, - - - /** - * Returns the anchor text that should be generated for the match. - * - * @return {String} - */ - getAnchorText : function() { - var anchorText = this.getUrl(); - - if( this.protocolRelativeMatch ) { - // Strip off any protocol-relative '//' from the anchor text - anchorText = this.stripProtocolRelativePrefix( anchorText ); - } - if( this.stripPrefix ) { - anchorText = this.stripUrlPrefix( anchorText ); - } - anchorText = this.removeTrailingSlash( anchorText ); // remove trailing slash, if there is one - - return anchorText; - }, - - - // --------------------------------------- - - // Utility Functionality - - /** - * Strips the URL prefix (such as "http://" or "https://") from the given text. - * - * @private - * @param {String} text The text of the anchor that is being generated, for which to strip off the - * url prefix (such as stripping off "http://") - * @return {String} The `anchorText`, with the prefix stripped. - */ - stripUrlPrefix : function( text ) { - return text.replace( this.urlPrefixRegex, '' ); - }, - - - /** - * Strips any protocol-relative '//' from the anchor text. - * - * @private - * @param {String} text The text of the anchor that is being generated, for which to strip off the - * protocol-relative prefix (such as stripping off "//") - * @return {String} The `anchorText`, with the protocol-relative prefix stripped. - */ - stripProtocolRelativePrefix : function( text ) { - return text.replace( this.protocolRelativeRegex, '' ); - }, - - - /** - * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed. - * - * @private - * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing - * slash ('/') that may exist. - * @return {String} The `anchorText`, with the trailing slash removed. - */ - removeTrailingSlash : function( anchorText ) { - if( anchorText.charAt( anchorText.length - 1 ) === '/' ) { - anchorText = anchorText.slice( 0, -1 ); - } - return anchorText; - } - -} ); -return Autolinker; + function exp2(exponent) { + return Math.pow(2.0,exponent); + } + + function log2(number) { + return CesiumMath.logBase(number, 2.0); + } + + function getEvaluateUnaryComponentwise(operation) { + return function(call, left) { + if (typeof left === 'number') { + return operation(left); + } else if (left instanceof Cartesian2) { + return Cartesian2.fromElements(operation(left.x), operation(left.y), scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3) { + return Cartesian3.fromElements(operation(left.x), operation(left.y), operation(left.z), scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4) { + return Cartesian4.fromElements(operation(left.x), operation(left.y), operation(left.z), operation(left.w), scratchStorage.getCartesian4()); + } + throw new RuntimeError('Function "' + call + '" requires a vector or number argument. Argument is ' + left + '.'); + }; + } + + function getEvaluateBinaryCommponentwise(operation, allowScalar) { + return function(call, left, right) { + if (allowScalar && typeof right === 'number') { + if (typeof left === 'number') { + return operation(left, right); + } else if (left instanceof Cartesian2) { + return Cartesian2.fromElements(operation(left.x, right), operation(left.y, right), scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3) { + return Cartesian3.fromElements(operation(left.x, right), operation(left.y, right), operation(left.z, right), scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4) { + return Cartesian4.fromElements(operation(left.x, right), operation(left.y, right), operation(left.z, right), operation(left.w, right), scratchStorage.getCartesian4()); + } + } -})); + if (typeof left === 'number' && typeof right === 'number') { + return operation(left, right); + } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { + return Cartesian2.fromElements(operation(left.x, right.x), operation(left.y, right.y), scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { + return Cartesian3.fromElements(operation(left.x, right.x), operation(left.y, right.y), operation(left.z, right.z), scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { + return Cartesian4.fromElements(operation(left.x, right.x), operation(left.y, right.y), operation(left.z, right.z), operation(left.w, right.w), scratchStorage.getCartesian4()); + } -/** -@license - Copyright (c) 2013 Gildas Lormeau. All rights reserved. + throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); + }; + } - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + function getEvaluateTernaryCommponentwise(operation, allowScalar) { + return function(call, left, right, test) { + if (allowScalar && typeof test === 'number') { + if (typeof left === 'number' && typeof right === 'number') { + return operation(left, right, test); + } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { + return Cartesian2.fromElements(operation(left.x, right.x, test), operation(left.y, right.y, test), scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { + return Cartesian3.fromElements(operation(left.x, right.x, test), operation(left.y, right.y, test), operation(left.z, right.z, test), scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { + return Cartesian4.fromElements(operation(left.x, right.x, test), operation(left.y, right.y, test), operation(left.z, right.z, test), operation(left.w, right.w, test), scratchStorage.getCartesian4()); + } + } - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. + if (typeof left === 'number' && typeof right === 'number' && typeof test === 'number') { + return operation(left, right, test); + } else if (left instanceof Cartesian2 && right instanceof Cartesian2 && test instanceof Cartesian2) { + return Cartesian2.fromElements(operation(left.x, right.x, test.x), operation(left.y, right.y, test.y), scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3 && right instanceof Cartesian3 && test instanceof Cartesian3) { + return Cartesian3.fromElements(operation(left.x, right.x, test.x), operation(left.y, right.y, test.y), operation(left.z, right.z, test.z), scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4 && right instanceof Cartesian4 && test instanceof Cartesian4) { + return Cartesian4.fromElements(operation(left.x, right.x, test.x), operation(left.y, right.y, test.y), operation(left.z, right.z, test.z), operation(left.w, right.w, test.w), scratchStorage.getCartesian4()); + } - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. + throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ', ' + right + ', and ' + test + '.'); + }; + } - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. + function length(call, left) { + if (typeof left === 'number') { + return Math.abs(left); + } else if (left instanceof Cartesian2) { + return Cartesian2.magnitude(left); + } else if (left instanceof Cartesian3) { + return Cartesian3.magnitude(left); + } else if (left instanceof Cartesian4) { + return Cartesian4.magnitude(left); + } - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, - INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**/ + throw new RuntimeError('Function "' + call + '" requires a vector or number argument. Argument is ' + left + '.'); + } -define('ThirdParty/zip',[ - '../Core/buildModuleUrl', - '../Core/defineProperties' - ], function( - buildModuleUrl, - defineProperties) { - var tmp = {}; + function normalize(call, left) { + if (typeof left === 'number') { + return 1.0; + } else if (left instanceof Cartesian2) { + return Cartesian2.normalize(left, scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3) { + return Cartesian3.normalize(left, scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4) { + return Cartesian4.normalize(left, scratchStorage.getCartesian4()); + } -(function(obj) { + throw new RuntimeError('Function "' + call + '" requires a vector or number argument. Argument is ' + left + '.'); + } - var ERR_BAD_FORMAT = "File format is not recognized."; - var ERR_ENCRYPTED = "File contains encrypted entry."; - var ERR_ZIP64 = "File is using Zip64 (4gb+ file size)."; - var ERR_READ = "Error while reading zip file."; - var ERR_WRITE = "Error while writing zip file."; - var ERR_WRITE_DATA = "Error while writing file data."; - var ERR_READ_DATA = "Error while reading file data."; - var ERR_DUPLICATED_NAME = "File already exists."; - var CHUNK_SIZE = 512 * 1024; + function distance(call, left, right) { + if (typeof left === 'number' && typeof right === 'number') { + return Math.abs(left - right); + } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { + return Cartesian2.distance(left, right); + } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { + return Cartesian3.distance(left, right); + } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { + return Cartesian4.distance(left, right); + } - var INFLATE_JS = "inflate.js"; - var DEFLATE_JS = "deflate.js"; + throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); + } - var TEXT_PLAIN = "text/plain"; + function dot(call, left, right) { + if (typeof left === 'number' && typeof right === 'number') { + return left * right; + } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { + return Cartesian2.dot(left, right); + } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { + return Cartesian3.dot(left, right); + } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { + return Cartesian4.dot(left, right); + } - var MESSAGE_EVENT = "message"; + throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); + } - var appendABViewSupported; - try { - appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0; - } catch (e) { - } + function cross(call, left, right) { + if (left instanceof Cartesian3 && right instanceof Cartesian3) { + return Cartesian3.cross(left, right, scratchStorage.getCartesian3()); + } - function Crc32() { - var crc = -1, that = this; - that.append = function(data) { - var offset, table = that.table; - for (offset = 0; offset < data.length; offset++) - crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF]; - }; - that.get = function() { - return ~crc; - }; - } - Crc32.prototype.table = (function() { - var i, j, t, table = []; - for (i = 0; i < 256; i++) { - t = i; - for (j = 0; j < 8; j++) - if (t & 1) - t = (t >>> 1) ^ 0xEDB88320; - else - t = t >>> 1; - table[i] = t; - } - return table; - })(); + throw new RuntimeError('Function "' + call + '" requires vec3 arguments. Arguments are ' + left + ' and ' + right + '.'); + } - function blobSlice(blob, index, length) { - if (blob.slice) - return blob.slice(index, index + length); - else if (blob.webkitSlice) - return blob.webkitSlice(index, index + length); - else if (blob.mozSlice) - return blob.mozSlice(index, index + length); - else if (blob.msSlice) - return blob.msSlice(index, index + length); - } + function Node(type, value, left, right, test) { + this._type = type; + this._value = value; + this._left = left; + this._right = right; + this._test = test; + this.evaluate = undefined; - function getDataHelper(byteLength, bytes) { - var dataBuffer, dataArray; - dataBuffer = new ArrayBuffer(byteLength); - dataArray = new Uint8Array(dataBuffer); - if (bytes) - dataArray.set(bytes, 0); - return { - buffer : dataBuffer, - array : dataArray, - view : new DataView(dataBuffer) - }; - } + setEvaluateFunction(this); + } - // Readers - function Reader() { - } + function replaceDefines(expression, defines) { + if (!defined(defines)) { + return expression; + } + for (var key in defines) { + if (defines.hasOwnProperty(key)) { + var definePlaceholder = new RegExp('\\$\\{' + key + '\\}', 'g'); + var defineReplace = '(' + defines[key] + ')'; + if (defined(defineReplace)) { + expression = expression.replace(definePlaceholder, defineReplace); + } + } + } + return expression; + } - function TextReader(text) { - var that = this, blobReader; + function removeBackslashes(expression) { + return expression.replace(backslashRegex, backslashReplacement); + } - function init(callback, onerror) { - var blob = new Blob([ text ], { - type : TEXT_PLAIN - }); - blobReader = new BlobReader(blob); - blobReader.init(function() { - that.size = blobReader.size; - callback(); - }, onerror); - } + function replaceBackslashes(expression) { + return expression.replace(replacementRegex, '\\'); + } - function readUint8Array(index, length, callback, onerror) { - blobReader.readUint8Array(index, length, callback, onerror); - } + function replaceVariables(expression) { + var exp = expression; + var result = ''; + var i = exp.indexOf('${'); + while (i >= 0) { + // Check if string is inside quotes + var openSingleQuote = exp.indexOf('\''); + var openDoubleQuote = exp.indexOf('"'); + var closeQuote; + if (openSingleQuote >= 0 && openSingleQuote < i) { + closeQuote = exp.indexOf('\'', openSingleQuote + 1); + result += exp.substr(0, closeQuote + 1); + exp = exp.substr(closeQuote + 1); + i = exp.indexOf('${'); + } else if (openDoubleQuote >= 0 && openDoubleQuote < i) { + closeQuote = exp.indexOf('"', openDoubleQuote + 1); + result += exp.substr(0, closeQuote + 1); + exp = exp.substr(closeQuote + 1); + i = exp.indexOf('${'); + } else { + result += exp.substr(0, i); + var j = exp.indexOf('}'); + if (j < 0) { + throw new RuntimeError('Unmatched {.'); + } + result += 'czm_' + exp.substr(i + 2, j - (i + 2)); + exp = exp.substr(j + 1); + i = exp.indexOf('${'); + } + } + result += exp; + return result; + } - that.size = 0; - that.init = init; - that.readUint8Array = readUint8Array; - } - TextReader.prototype = new Reader(); - TextReader.prototype.constructor = TextReader; + function parseLiteral(ast) { + var type = typeof ast.value; + if (ast.value === null) { + return new Node(ExpressionNodeType.LITERAL_NULL, null); + } else if (type === 'boolean') { + return new Node(ExpressionNodeType.LITERAL_BOOLEAN, ast.value); + } else if (type === 'number') { + return new Node(ExpressionNodeType.LITERAL_NUMBER, ast.value); + } else if (type === 'string') { + if (ast.value.indexOf('${') >= 0) { + return new Node(ExpressionNodeType.VARIABLE_IN_STRING, ast.value); + } + return new Node(ExpressionNodeType.LITERAL_STRING, replaceBackslashes(ast.value)); + } + } - function Data64URIReader(dataURI) { - var that = this, dataStart; + function parseCall(expression, ast) { + var args = ast.arguments; + var argsLength = args.length; + var call; + var val, left, right; - function init(callback) { - var dataEnd = dataURI.length; - while (dataURI.charAt(dataEnd - 1) == "=") - dataEnd--; - dataStart = dataURI.indexOf(",") + 1; - that.size = Math.floor((dataEnd - dataStart) * 0.75); - callback(); - } + // Member function calls + if (ast.callee.type === 'MemberExpression') { + call = ast.callee.property.name; + var object = ast.callee.object; + if (call === 'test' || call === 'exec') { + // Make sure this is called on a valid type + if (object.callee.name !== 'regExp') { + throw new RuntimeError(call + ' is not a function.'); + } + if (argsLength === 0) { + if (call === 'test') { + return new Node(ExpressionNodeType.LITERAL_BOOLEAN, false); + } + return new Node(ExpressionNodeType.LITERAL_NULL, null); + } + left = createRuntimeAst(expression, object); + right = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.FUNCTION_CALL, call, left, right); + } else if (call === 'toString') { + val = createRuntimeAst(expression, object); + return new Node(ExpressionNodeType.FUNCTION_CALL, call, val); + } - function readUint8Array(index, length, callback) { - var i, data = getDataHelper(length); - var start = Math.floor(index / 3) * 4; - var end = Math.ceil((index + length) / 3) * 4; - var bytes = window.atob(dataURI.substring(start + dataStart, end + dataStart)); - var delta = index - Math.floor(start / 4) * 3; - for (i = delta; i < delta + length; i++) - data.array[i - delta] = bytes.charCodeAt(i); - callback(data.array); - } + throw new RuntimeError('Unexpected function call "' + call + '".'); + } - that.size = 0; - that.init = init; - that.readUint8Array = readUint8Array; - } - Data64URIReader.prototype = new Reader(); - Data64URIReader.prototype.constructor = Data64URIReader; + // Non-member function calls + call = ast.callee.name; + if (call === 'color') { + if (argsLength === 0) { + return new Node(ExpressionNodeType.LITERAL_COLOR, call); + } + val = createRuntimeAst(expression, args[0]); + if (defined(args[1])) { + var alpha = createRuntimeAst(expression, args[1]); + return new Node(ExpressionNodeType.LITERAL_COLOR, call, [val, alpha]); + } + return new Node(ExpressionNodeType.LITERAL_COLOR, call, [val]); + } else if (call === 'rgb' || call === 'hsl') { + if (argsLength < 3) { + throw new RuntimeError(call + ' requires three arguments.'); + } + val = [ + createRuntimeAst(expression, args[0]), + createRuntimeAst(expression, args[1]), + createRuntimeAst(expression, args[2]) + ]; + return new Node(ExpressionNodeType.LITERAL_COLOR, call, val); + } else if (call === 'rgba' || call === 'hsla') { + if (argsLength < 4) { + throw new RuntimeError(call + ' requires four arguments.'); + } + val = [ + createRuntimeAst(expression, args[0]), + createRuntimeAst(expression, args[1]), + createRuntimeAst(expression, args[2]), + createRuntimeAst(expression, args[3]) + ]; + return new Node(ExpressionNodeType.LITERAL_COLOR, call, val); + } else if (call === 'vec2' || call === 'vec3' || call === 'vec4') { + // Check for invalid constructors at evaluation time + val = new Array(argsLength); + for (var i = 0; i < argsLength; ++i) { + val[i] = createRuntimeAst(expression, args[i]); + } + return new Node(ExpressionNodeType.LITERAL_VECTOR, call, val); + } else if (call === 'isNaN' || call === 'isFinite') { + if (argsLength === 0) { + if (call === 'isNaN') { + return new Node(ExpressionNodeType.LITERAL_BOOLEAN, true); + } + return new Node(ExpressionNodeType.LITERAL_BOOLEAN, false); + } + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'isExactClass' || call === 'isClass') { + if (argsLength < 1 || argsLength > 1) { + throw new RuntimeError(call + ' requires exactly one argument.'); + } + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'getExactClassName') { + if (argsLength > 0) { + throw new RuntimeError(call + ' does not take any argument.'); + } + return new Node(ExpressionNodeType.UNARY, call); + } else if (defined(unaryFunctions[call])) { + if (argsLength !== 1) { + throw new RuntimeError(call + ' requires exactly one argument.'); + } + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (defined(binaryFunctions[call])) { + if (argsLength !== 2) { + throw new RuntimeError(call + ' requires exactly two arguments.'); + } + left = createRuntimeAst(expression, args[0]); + right = createRuntimeAst(expression, args[1]); + return new Node(ExpressionNodeType.BINARY, call, left, right); + } else if (defined(ternaryFunctions[call])) { + if (argsLength !== 3) { + throw new RuntimeError(call + ' requires exactly three arguments.'); + } + left = createRuntimeAst(expression, args[0]); + right = createRuntimeAst(expression, args[1]); + var test = createRuntimeAst(expression, args[2]); + return new Node(ExpressionNodeType.TERNARY, call, left, right, test); + } else if (call === 'Boolean') { + if (argsLength === 0) { + return new Node(ExpressionNodeType.LITERAL_BOOLEAN, false); + } + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'Number') { + if (argsLength === 0) { + return new Node(ExpressionNodeType.LITERAL_NUMBER, 0); + } + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'String') { + if (argsLength === 0) { + return new Node(ExpressionNodeType.LITERAL_STRING, ''); + } + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'regExp') { + return parseRegex(expression, ast); + } - function BlobReader(blob) { - var that = this; + throw new RuntimeError('Unexpected function call "' + call + '".'); + } - function init(callback) { - this.size = blob.size; - callback(); - } + function parseRegex(expression, ast) { + var args = ast.arguments; + // no arguments, return default regex + if (args.length === 0) { + return new Node(ExpressionNodeType.LITERAL_REGEX, new RegExp()); + } - function readUint8Array(index, length, callback, onerror) { - var reader = new FileReader(); - reader.onload = function(e) { - callback(new Uint8Array(e.target.result)); - }; - reader.onerror = onerror; - reader.readAsArrayBuffer(blobSlice(blob, index, length)); - } + var pattern = createRuntimeAst(expression, args[0]); + var exp; - that.size = 0; - that.init = init; - that.readUint8Array = readUint8Array; - } - BlobReader.prototype = new Reader(); - BlobReader.prototype.constructor = BlobReader; + // optional flag argument supplied + if (args.length > 1) { + var flags = createRuntimeAst(expression, args[1]); + if (isLiteralType(pattern) && isLiteralType(flags)) { + try { + exp = new RegExp(replaceBackslashes(String(pattern._value)), flags._value); + } catch (e) { + throw new RuntimeError(e); + } + return new Node(ExpressionNodeType.LITERAL_REGEX, exp); + } + return new Node(ExpressionNodeType.REGEX, pattern, flags); + } - // Writers + // only pattern argument supplied + if (isLiteralType(pattern)) { + try { + exp = new RegExp(replaceBackslashes(String(pattern._value))); + } catch (e) { + throw new RuntimeError(e); + } + return new Node(ExpressionNodeType.LITERAL_REGEX, exp); + } + return new Node(ExpressionNodeType.REGEX, pattern); + } - function Writer() { - } - Writer.prototype.getData = function(callback) { - callback(this.data); - }; + function parseKeywordsAndVariables(ast) { + if (isVariable(ast.name)) { + var name = getPropertyName(ast.name); + if (name.substr(0, 8) === 'tiles3d_') { + return new Node(ExpressionNodeType.BUILTIN_VARIABLE, name); + } + return new Node(ExpressionNodeType.VARIABLE, name); + } else if (ast.name === 'NaN') { + return new Node(ExpressionNodeType.LITERAL_NUMBER, NaN); + } else if (ast.name === 'Infinity') { + return new Node(ExpressionNodeType.LITERAL_NUMBER, Infinity); + } else if (ast.name === 'undefined') { + return new Node(ExpressionNodeType.LITERAL_UNDEFINED, undefined); + } - function TextWriter(encoding) { - var that = this, blob; + throw new RuntimeError(ast.name + ' is not defined.'); + } - function init(callback) { - blob = new Blob([], { - type : TEXT_PLAIN - }); - callback(); - } + function parseMathConstant(ast) { + var name = ast.property.name; + if (name === 'PI') { + return new Node(ExpressionNodeType.LITERAL_NUMBER, Math.PI); + } else if (name === 'E') { + return new Node(ExpressionNodeType.LITERAL_NUMBER, Math.E); + } + } - function writeUint8Array(array, callback) { - blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], { - type : TEXT_PLAIN - }); - callback(); - } + function parseNumberConstant(ast) { + var name = ast.property.name; + if (name === 'POSITIVE_INFINITY') { + return new Node(ExpressionNodeType.LITERAL_NUMBER, Number.POSITIVE_INFINITY); + } + } - function getData(callback, onerror) { - var reader = new FileReader(); - reader.onload = function(e) { - callback(e.target.result); - }; - reader.onerror = onerror; - reader.readAsText(blob, encoding); - } + function parseMemberExpression(expression, ast) { + if (ast.object.name === 'Math') { + return parseMathConstant(ast); + } else if (ast.object.name === 'Number') { + return parseNumberConstant(ast); + } - that.init = init; - that.writeUint8Array = writeUint8Array; - that.getData = getData; - } - TextWriter.prototype = new Writer(); - TextWriter.prototype.constructor = TextWriter; + var val; + var obj = createRuntimeAst(expression, ast.object); + if (ast.computed) { + val = createRuntimeAst(expression, ast.property); + return new Node(ExpressionNodeType.MEMBER, 'brackets', obj, val); + } - function Data64URIWriter(contentType) { - var that = this, data = "", pending = ""; + val = new Node(ExpressionNodeType.LITERAL_STRING, ast.property.name); + return new Node(ExpressionNodeType.MEMBER, 'dot', obj, val); + } - function init(callback) { - data += "data:" + (contentType || "") + ";base64,"; - callback(); - } + function isLiteralType(node) { + return (node._type >= ExpressionNodeType.LITERAL_NULL); + } - function writeUint8Array(array, callback) { - var i, delta = pending.length, dataString = pending; - pending = ""; - for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++) - dataString += String.fromCharCode(array[i]); - for (; i < array.length; i++) - pending += String.fromCharCode(array[i]); - if (dataString.length > 2) - data += window.btoa(dataString); - else - pending = dataString; - callback(); - } + function isVariable(name) { + return (name.substr(0, 4) === 'czm_'); + } - function getData(callback) { - callback(data + window.btoa(pending)); - } + function getPropertyName(variable) { + return variable.substr(4); + } - that.init = init; - that.writeUint8Array = writeUint8Array; - that.getData = getData; - } - Data64URIWriter.prototype = new Writer(); - Data64URIWriter.prototype.constructor = Data64URIWriter; + function createRuntimeAst(expression, ast) { + var node; + var op; + var left; + var right; - function BlobWriter(contentType) { - var blob, that = this; + if (ast.type === 'Literal') { + node = parseLiteral(ast); + } else if (ast.type === 'CallExpression') { + node = parseCall(expression, ast); + } else if (ast.type === 'Identifier') { + node = parseKeywordsAndVariables(ast); + } else if (ast.type === 'UnaryExpression') { + op = ast.operator; + var child = createRuntimeAst(expression, ast.argument); + if (unaryOperators.indexOf(op) > -1) { + node = new Node(ExpressionNodeType.UNARY, op, child); + } else { + throw new RuntimeError('Unexpected operator "' + op + '".'); + } + } else if (ast.type === 'BinaryExpression') { + op = ast.operator; + left = createRuntimeAst(expression, ast.left); + right = createRuntimeAst(expression, ast.right); + if (binaryOperators.indexOf(op) > -1) { + node = new Node(ExpressionNodeType.BINARY, op, left, right); + } else { + throw new RuntimeError('Unexpected operator "' + op + '".'); + } + } else if (ast.type === 'LogicalExpression') { + op = ast.operator; + left = createRuntimeAst(expression, ast.left); + right = createRuntimeAst(expression, ast.right); + if (binaryOperators.indexOf(op) > -1) { + node = new Node(ExpressionNodeType.BINARY, op, left, right); + } + } else if (ast.type === 'ConditionalExpression') { + var test = createRuntimeAst(expression, ast.test); + left = createRuntimeAst(expression, ast.consequent); + right = createRuntimeAst(expression, ast.alternate); + node = new Node(ExpressionNodeType.CONDITIONAL, '?', left, right, test); + } else if (ast.type === 'MemberExpression') { + node = parseMemberExpression(expression, ast); + } else if (ast.type === 'ArrayExpression') { + var val = []; + for (var i = 0; i < ast.elements.length; i++) { + val[i] = createRuntimeAst(expression, ast.elements[i]); + } + node = new Node(ExpressionNodeType.ARRAY, val); + } else if (ast.type === 'Compound') { + // empty expression or multiple expressions + throw new RuntimeError('Provide exactly one expression.'); + } else { + throw new RuntimeError('Cannot parse expression.'); + } - function init(callback) { - blob = new Blob([], { - type : contentType - }); - callback(); - } + return node; + } - function writeUint8Array(array, callback) { - blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], { - type : contentType - }); - callback(); - } + function setEvaluateFunction(node) { + if (node._type === ExpressionNodeType.CONDITIONAL) { + node.evaluate = node._evaluateConditional; + } else if (node._type === ExpressionNodeType.FUNCTION_CALL) { + if (node._value === 'test') { + node.evaluate = node._evaluateRegExpTest; + } else if (node._value === 'exec') { + node.evaluate = node._evaluateRegExpExec; + } else if (node._value === 'toString') { + node.evaluate = node._evaluateToString; + } + } else if (node._type === ExpressionNodeType.UNARY) { + if (node._value === '!') { + node.evaluate = node._evaluateNot; + } else if (node._value === '-') { + node.evaluate = node._evaluateNegative; + } else if (node._value === '+') { + node.evaluate = node._evaluatePositive; + } else if (node._value === 'isNaN') { + node.evaluate = node._evaluateNaN; + } else if (node._value === 'isFinite') { + node.evaluate = node._evaluateIsFinite; + } else if (node._value === 'isExactClass') { + node.evaluate = node._evaluateIsExactClass; + } else if (node._value === 'isClass') { + node.evaluate = node._evaluateIsClass; + } else if (node._value === 'getExactClassName') { + node.evaluate = node._evaluategetExactClassName; + } else if (node._value === 'Boolean') { + node.evaluate = node._evaluateBooleanConversion; + } else if (node._value === 'Number') { + node.evaluate = node._evaluateNumberConversion; + } else if (node._value === 'String') { + node.evaluate = node._evaluateStringConversion; + } else if (defined(unaryFunctions[node._value])) { + node.evaluate = getEvaluateUnaryFunction(node._value); + } + } else if (node._type === ExpressionNodeType.BINARY) { + if (node._value === '+') { + node.evaluate = node._evaluatePlus; + } else if (node._value === '-') { + node.evaluate = node._evaluateMinus; + } else if (node._value === '*') { + node.evaluate = node._evaluateTimes; + } else if (node._value === '/') { + node.evaluate = node._evaluateDivide; + } else if (node._value === '%') { + node.evaluate = node._evaluateMod; + } else if (node._value === '===') { + node.evaluate = node._evaluateEqualsStrict; + } else if (node._value === '!==') { + node.evaluate = node._evaluateNotEqualsStrict; + } else if (node._value === '<') { + node.evaluate = node._evaluateLessThan; + } else if (node._value === '<=') { + node.evaluate = node._evaluateLessThanOrEquals; + } else if (node._value === '>') { + node.evaluate = node._evaluateGreaterThan; + } else if (node._value === '>=') { + node.evaluate = node._evaluateGreaterThanOrEquals; + } else if (node._value === '&&') { + node.evaluate = node._evaluateAnd; + } else if (node._value === '||') { + node.evaluate = node._evaluateOr; + } else if (node._value === '=~') { + node.evaluate = node._evaluateRegExpMatch; + } else if (node._value === '!~') { + node.evaluate = node._evaluateRegExpNotMatch; + } else if (defined(binaryFunctions[node._value])) { + node.evaluate = getEvaluateBinaryFunction(node._value); + } + } else if (node._type === ExpressionNodeType.TERNARY) { + node.evaluate = getEvaluateTernaryFunction(node._value); + } else if (node._type === ExpressionNodeType.MEMBER) { + if (node._value === 'brackets') { + node.evaluate = node._evaluateMemberBrackets; + } else { + node.evaluate = node._evaluateMemberDot; + } + } else if (node._type === ExpressionNodeType.ARRAY) { + node.evaluate = node._evaluateArray; + } else if (node._type === ExpressionNodeType.VARIABLE) { + node.evaluate = node._evaluateVariable; + } else if (node._type === ExpressionNodeType.VARIABLE_IN_STRING) { + node.evaluate = node._evaluateVariableString; + } else if (node._type === ExpressionNodeType.LITERAL_COLOR) { + node.evaluate = node._evaluateLiteralColor; + } else if (node._type === ExpressionNodeType.LITERAL_VECTOR) { + node.evaluate = node._evaluateLiteralVector; + } else if (node._type === ExpressionNodeType.LITERAL_STRING) { + node.evaluate = node._evaluateLiteralString; + } else if (node._type === ExpressionNodeType.REGEX) { + node.evaluate = node._evaluateRegExp; + } else if (node._type === ExpressionNodeType.BUILTIN_VARIABLE) { + if (node._value === 'tiles3d_tileset_time') { + node.evaluate = evaluateTilesetTime; + } + } else { + node.evaluate = node._evaluateLiteral; + } + } - function getData(callback) { - callback(blob); - } + function evaluateTilesetTime(frameState, feature) { + return feature.content.tileset.timeSinceLoad; + } - that.init = init; - that.writeUint8Array = writeUint8Array; - that.getData = getData; - } - BlobWriter.prototype = new Writer(); - BlobWriter.prototype.constructor = BlobWriter; + function getEvaluateUnaryFunction(call) { + var evaluate = unaryFunctions[call]; + return function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + return evaluate(call, left); + }; + } - // inflate/deflate core functions + function getEvaluateBinaryFunction(call) { + var evaluate = binaryFunctions[call]; + return function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + return evaluate(call, left, right); + }; + } - function launchWorkerProcess(worker, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { - var chunkIndex = 0, index, outputSize; + function getEvaluateTernaryFunction(call) { + var evaluate = ternaryFunctions[call]; + return function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + var test = this._test.evaluate(frameState, feature); + return evaluate(call, left, right, test); + }; + } - function onflush() { - worker.removeEventListener(MESSAGE_EVENT, onmessage, false); - onend(outputSize); - } + Node.prototype._evaluateLiteral = function(frameState, feature) { + return this._value; + }; - function onmessage(event) { - var message = event.data, data = message.data; + Node.prototype._evaluateLiteralColor = function(frameState, feature) { + var color = scratchColor; + var args = this._left; + if (this._value === 'color') { + if (!defined(args)) { + Color.fromBytes(255, 255, 255, 255, color); + } else if (args.length > 1) { + Color.fromCssColorString(args[0].evaluate(frameState, feature), color); + color.alpha = args[1].evaluate(frameState, feature); + } else { + Color.fromCssColorString(args[0].evaluate(frameState, feature), color); + } + } else if (this._value === 'rgb') { + Color.fromBytes( + args[0].evaluate(frameState, feature), + args[1].evaluate(frameState, feature), + args[2].evaluate(frameState, feature), + 255, color); + } else if (this._value === 'rgba') { + // convert between css alpha (0 to 1) and cesium alpha (0 to 255) + var a = args[3].evaluate(frameState, feature) * 255; + Color.fromBytes( + args[0].evaluate(frameState, feature), + args[1].evaluate(frameState, feature), + args[2].evaluate(frameState, feature), + a, color); + } else if (this._value === 'hsl') { + Color.fromHsl( + args[0].evaluate(frameState, feature), + args[1].evaluate(frameState, feature), + args[2].evaluate(frameState, feature), + 1.0, color); + } else if (this._value === 'hsla') { + Color.fromHsl( + args[0].evaluate(frameState, feature), + args[1].evaluate(frameState, feature), + args[2].evaluate(frameState, feature), + args[3].evaluate(frameState, feature), + color); + } + return Cartesian4.fromColor(color, scratchStorage.getCartesian4()); + }; - if (message.onappend) { - outputSize += data.length; - writer.writeUint8Array(data, function() { - onappend(false, data); - step(); - }, onwriteerror); - } - if (message.onflush) - if (data) { - outputSize += data.length; - writer.writeUint8Array(data, function() { - onappend(false, data); - onflush(); - }, onwriteerror); - } else - onflush(); - if (message.progress && onprogress) - onprogress(index + message.current, size); - } + Node.prototype._evaluateLiteralVector = function(frameState, feature) { + // Gather the components that make up the vector, which includes components from interior vectors. + // For example vec3(1, 2, 3) or vec3(vec2(1, 2), 3) are both valid. + // + // If the number of components does not equal the vector's size, then a RuntimeError is thrown - with two exceptions: + // 1. A vector may be constructed from a larger vector and drop the extra components. + // 2. A vector may be constructed from a single component - vec3(1) will become vec3(1, 1, 1). + // + // Examples of invalid constructors include: + // vec4(1, 2) // not enough components + // vec3(vec2(1, 2)) // not enough components + // vec3(1, 2, 3, 4) // too many components + // vec2(vec4(1), 1) // too many components - function step() { - index = chunkIndex * CHUNK_SIZE; - if (index < size) - reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { - worker.postMessage({ - append : true, - data : array - }); - chunkIndex++; - if (onprogress) - onprogress(index, size); - onappend(true, array); - }, onreaderror); - else - worker.postMessage({ - flush : true - }); - } + var components = scratchStorage.getArray(); + var call = this._value; + var args = this._left; + var argsLength = args.length; + for (var i = 0; i < argsLength; ++i) { + var value = args[i].evaluate(frameState, feature); + if (typeof value === 'number') { + components.push(value); + } else if (value instanceof Cartesian2) { + components.push(value.x, value.y); + } else if (value instanceof Cartesian3) { + components.push(value.x, value.y, value.z); + } else if (value instanceof Cartesian4) { + components.push(value.x, value.y, value.z, value.w); + } else { + throw new RuntimeError(call + ' argument must be a vector or number. Argument is ' + value + '.'); + } + } - outputSize = 0; - worker.addEventListener(MESSAGE_EVENT, onmessage, false); - step(); - } + var componentsLength = components.length; + var vectorLength = parseInt(call.charAt(3)); - function launchProcess(process, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { - var chunkIndex = 0, index, outputSize = 0; + if (componentsLength === 0) { + throw new RuntimeError('Invalid ' + call + ' constructor. No valid arguments.'); + } else if ((componentsLength < vectorLength) && (componentsLength > 1)) { + throw new RuntimeError('Invalid ' + call + ' constructor. Not enough arguments.'); + } else if ((componentsLength > vectorLength) && (argsLength > 1)) { + throw new RuntimeError('Invalid ' + call + ' constructor. Too many arguments.'); + } - function step() { - var outputData; - index = chunkIndex * CHUNK_SIZE; - if (index < size) - reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) { - var outputData = process.append(inputData, function() { - if (onprogress) - onprogress(offset + index, size); - }); - outputSize += outputData.length; - onappend(true, inputData); - writer.writeUint8Array(outputData, function() { - onappend(false, outputData); - chunkIndex++; - setTimeout(step, 1); - }, onwriteerror); - if (onprogress) - onprogress(index, size); - }, onreaderror); - else { - outputData = process.flush(); - if (outputData) { - outputSize += outputData.length; - writer.writeUint8Array(outputData, function() { - onappend(false, outputData); - onend(outputSize); - }, onwriteerror); - } else - onend(outputSize); - } - } + if (componentsLength === 1) { + // Add the same component 3 more times + var component = components[0]; + components.push(component, component, component); + } + + if (call === 'vec2') { + return Cartesian2.fromArray(components, 0, scratchStorage.getCartesian2()); + } else if (call === 'vec3') { + return Cartesian3.fromArray(components, 0, scratchStorage.getCartesian3()); + } else if (call === 'vec4') { + return Cartesian4.fromArray(components, 0, scratchStorage.getCartesian4()); + } + }; + + Node.prototype._evaluateLiteralString = function(frameState, feature) { + return this._value; + }; + + Node.prototype._evaluateVariableString = function(frameState, feature) { + var result = this._value; + var match = variableRegex.exec(result); + while (match !== null) { + var placeholder = match[0]; + var variableName = match[1]; + var property = feature.getProperty(variableName); + if (!defined(property)) { + property = ''; + } + result = result.replace(placeholder, property); + match = variableRegex.exec(result); + } + return result; + }; - step(); - } + Node.prototype._evaluateVariable = function(frameState, feature) { + // evaluates to undefined if the property name is not defined for that feature + return feature.getProperty(this._value); + }; - function inflate(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { - var worker, crc32 = new Crc32(); + function checkFeature (ast) { + return (ast._value === 'feature'); + } - function oninflateappend(sending, array) { - if (computeCrc32 && !sending) - crc32.append(array); - } + // PERFORMANCE_IDEA: Determine if parent property needs to be computed before runtime + Node.prototype._evaluateMemberDot = function(frameState, feature) { + if (checkFeature(this._left)) { + return feature.getProperty(this._right.evaluate(frameState, feature)); + } + var property = this._left.evaluate(frameState, feature); + if (!defined(property)) { + return undefined; + } - function oninflateend(outputSize) { - onend(outputSize, crc32.get()); - } + var member = this._right.evaluate(frameState, feature); + if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) { + // Vector components may be accessed with .r, .g, .b, .a and implicitly with .x, .y, .z, .w + if (member === 'r') { + return property.x; + } else if (member === 'g') { + return property.y; + } else if (member === 'b') { + return property.z; + } else if (member === 'a') { + return property.w; + } + } + return property[member]; + }; - if (obj.zip.useWebWorkers) { - worker = new Worker(obj.zip.workerScriptsPath + INFLATE_JS); - launchWorkerProcess(worker, reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); - } else - launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); - return worker; - } + Node.prototype._evaluateMemberBrackets = function(frameState, feature) { + if (checkFeature(this._left)) { + return feature.getProperty(this._right.evaluate(frameState, feature)); + } + var property = this._left.evaluate(frameState, feature); + if (!defined(property)) { + return undefined; + } - function deflate(reader, writer, level, onend, onprogress, onreaderror, onwriteerror) { - var worker, crc32 = new Crc32(); + var member = this._right.evaluate(frameState, feature); + if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) { + // Vector components may be accessed with [0][1][2][3], ['r']['g']['b']['a'] and implicitly with ['x']['y']['z']['w'] + // For Cartesian2 and Cartesian3 out-of-range components will just return undefined + if (member === 0 || member === 'r') { + return property.x; + } else if (member === 1 || member === 'g') { + return property.y; + } else if (member === 2 || member === 'b') { + return property.z; + } else if (member === 3 || member === 'a') { + return property.w; + } + } + return property[member]; + }; - function ondeflateappend(sending, array) { - if (sending) - crc32.append(array); - } + Node.prototype._evaluateArray = function(frameState, feature) { + var array = []; + for (var i = 0; i < this._value.length; i++) { + array[i] = this._value[i].evaluate(frameState, feature); + } + return array; + }; - function ondeflateend(outputSize) { - onend(outputSize, crc32.get()); - } + // PERFORMANCE_IDEA: Have "fast path" functions that deal only with specific types + // that we can assign if we know the types before runtime - function onmessage() { - worker.removeEventListener(MESSAGE_EVENT, onmessage, false); - launchWorkerProcess(worker, reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); - } + Node.prototype._evaluateNot = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + if (typeof left !== 'boolean') { + throw new RuntimeError('Operator "!" requires a boolean argument. Argument is ' + left + '.'); + } + return !left; + }; - if (obj.zip.useWebWorkers) { - worker = new Worker(obj.zip.workerScriptsPath + DEFLATE_JS); - worker.addEventListener(MESSAGE_EVENT, onmessage, false); - worker.postMessage({ - init : true, - level : level - }); - } else - launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); - return worker; - } + Node.prototype._evaluateNegative = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + if (left instanceof Cartesian2) { + return Cartesian2.negate(left, scratchStorage.getCartesian2()); + } else if (left instanceof Cartesian3) { + return Cartesian3.negate(left, scratchStorage.getCartesian3()); + } else if (left instanceof Cartesian4) { + return Cartesian4.negate(left, scratchStorage.getCartesian4()); + } else if (typeof left === 'number') { + return -left; + } - function copy(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { - var chunkIndex = 0, crc32 = new Crc32(); + throw new RuntimeError('Operator "-" requires a vector or number argument. Argument is ' + left + '.'); + }; - function step() { - var index = chunkIndex * CHUNK_SIZE; - if (index < size) - reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { - if (computeCrc32) - crc32.append(array); - if (onprogress) - onprogress(index, size, array); - writer.writeUint8Array(array, function() { - chunkIndex++; - step(); - }, onwriteerror); - }, onreaderror); - else - onend(size, crc32.get()); - } + Node.prototype._evaluatePositive = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); - step(); - } + if (!((left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4) || (typeof left === 'number'))) { + throw new RuntimeError('Operator "+" requires a vector or number argument. Argument is ' + left + '.'); + } - // ZipReader + return left; + }; - function decodeASCII(str) { - var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', - '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', - '\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', - '\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6', - '\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3', - '\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE', - '\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE', - '\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7', - '\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ]; - for (i = 0; i < str.length; i++) { - charCode = str.charCodeAt(i) & 0xFF; - if (charCode > 127) - out += extendedASCII[charCode - 128]; - else - out += String.fromCharCode(charCode); - } - return out; - } + Node.prototype._evaluateLessThan = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); - function decodeUTF8(string) { - return decodeURIComponent(escape(string)); - } + if ((typeof left !== 'number') || (typeof right !== 'number')) { + throw new RuntimeError('Operator "<" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); + } - function getString(bytes) { - var i, str = ""; - for (i = 0; i < bytes.length; i++) - str += String.fromCharCode(bytes[i]); - return str; - } + return left < right; + }; - function getDate(timeRaw) { - var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff; - try { - return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, - (time & 0x001F) * 2, 0); - } catch (e) { - } - } + Node.prototype._evaluateLessThanOrEquals = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); - function readCommonHeader(entry, data, index, centralDirectory, onerror) { - entry.version = data.view.getUint16(index, true); - entry.bitFlag = data.view.getUint16(index + 2, true); - entry.compressionMethod = data.view.getUint16(index + 4, true); - entry.lastModDateRaw = data.view.getUint32(index + 6, true); - entry.lastModDate = getDate(entry.lastModDateRaw); - if ((entry.bitFlag & 0x01) === 0x01) { - onerror(ERR_ENCRYPTED); - return; - } - if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) { - entry.crc32 = data.view.getUint32(index + 10, true); - entry.compressedSize = data.view.getUint32(index + 14, true); - entry.uncompressedSize = data.view.getUint32(index + 18, true); - } - if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) { - onerror(ERR_ZIP64); - return; - } - entry.filenameLength = data.view.getUint16(index + 22, true); - entry.extraFieldLength = data.view.getUint16(index + 24, true); - } + if ((typeof left !== 'number') || (typeof right !== 'number')) { + throw new RuntimeError('Operator "<=" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); + } - function createZipReader(reader, onerror) { - function Entry() { - } + return left <= right; + }; - Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) { - var that = this, worker; + Node.prototype._evaluateGreaterThan = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); - function terminate(callback, param) { - if (worker) - worker.terminate(); - worker = null; - if (callback) - callback(param); - } + if ((typeof left !== 'number') || (typeof right !== 'number')) { + throw new RuntimeError('Operator ">" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); + } - function testCrc32(crc32) { - var dataCrc32 = getDataHelper(4); - dataCrc32.view.setUint32(0, crc32); - return that.crc32 == dataCrc32.view.getUint32(0); - } + return left > right; + }; - function getWriterData(uncompressedSize, crc32) { - if (checkCrc32 && !testCrc32(crc32)) - onreaderror(); - else - writer.getData(function(data) { - terminate(onend, data); - }); - } + Node.prototype._evaluateGreaterThanOrEquals = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); - function onreaderror() { - terminate(onerror, ERR_READ_DATA); - } + if ((typeof left !== 'number') || (typeof right !== 'number')) { + throw new RuntimeError('Operator ">=" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); + } - function onwriteerror() { - terminate(onerror, ERR_WRITE_DATA); - } + return left >= right; + }; - reader.readUint8Array(that.offset, 30, function(bytes) { - var data = getDataHelper(bytes.length, bytes), dataOffset; - if (data.view.getUint32(0) != 0x504b0304) { - onerror(ERR_BAD_FORMAT); - return; - } - readCommonHeader(that, data, 4, false, onerror); - dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength; - writer.init(function() { - if (that.compressionMethod === 0) - copy(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); - else - worker = inflate(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); - }, onwriteerror); - }, onreaderror); - }; + Node.prototype._evaluateOr = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + if (typeof left !== 'boolean') { + throw new RuntimeError('Operator "||" requires boolean arguments. First argument is ' + left + '.'); + } - function seekEOCDR(offset, entriesCallback) { - reader.readUint8Array(reader.size - offset, offset, function(bytes) { - var dataView = getDataHelper(bytes.length, bytes).view; - if (dataView.getUint32(0) != 0x504b0506) { - seekEOCDR(offset + 1, entriesCallback); - } else { - entriesCallback(dataView); - } - }, function() { - onerror(ERR_READ); - }); - } + // short circuit the expression + if (left) { + return true; + } - return { - getEntries : function(callback) { - if (reader.size < 22) { - onerror(ERR_BAD_FORMAT); - return; - } - // look for End of central directory record - seekEOCDR(22, function(dataView) { - var datalength, fileslength; - datalength = dataView.getUint32(16, true); - fileslength = dataView.getUint16(8, true); - reader.readUint8Array(datalength, reader.size - datalength, function(bytes) { - var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes); - for (i = 0; i < fileslength; i++) { - entry = new Entry(); - if (data.view.getUint32(index) != 0x504b0102) { - onerror(ERR_BAD_FORMAT); - return; - } - readCommonHeader(entry, data, index + 6, true, onerror); - entry.commentLength = data.view.getUint16(index + 32, true); - entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10); - entry.offset = data.view.getUint32(index + 42, true); - filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength)); - entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename); - if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/") - entry.directory = true; - comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46 - + entry.filenameLength + entry.extraFieldLength + entry.commentLength)); - entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment); - entries.push(entry); - index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength; - } - callback(entries); - }, function() { - onerror(ERR_READ); - }); - }); - }, - close : function(callback) { - if (callback) - callback(); - } - }; - } + var right = this._right.evaluate(frameState, feature); + if (typeof right !== 'boolean') { + throw new RuntimeError('Operator "||" requires boolean arguments. Second argument is ' + right + '.'); + } - // ZipWriter + return left || right; + }; - function encodeUTF8(string) { - return unescape(encodeURIComponent(string)); - } + Node.prototype._evaluateAnd = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + if (typeof left !== 'boolean') { + throw new RuntimeError('Operator "&&" requires boolean arguments. First argument is ' + left + '.'); + } - function getBytes(str) { - var i, array = []; - for (i = 0; i < str.length; i++) - array.push(str.charCodeAt(i)); - return array; - } + // short circuit the expression + if (!left) { + return false; + } - function createZipWriter(writer, onerror, dontDeflate) { - var worker, files = {}, filenames = [], datalength = 0; + var right = this._right.evaluate(frameState, feature); + if (typeof right !== 'boolean') { + throw new RuntimeError('Operator "&&" requires boolean arguments. Second argument is ' + right + '.'); + } - function terminate(callback, message) { - if (worker) - worker.terminate(); - worker = null; - if (callback) - callback(message); - } + return left && right; + }; - function onwriteerror() { - terminate(onerror, ERR_WRITE); - } + Node.prototype._evaluatePlus = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { + return Cartesian2.add(left, right, scratchStorage.getCartesian2()); + } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { + return Cartesian3.add(left, right, scratchStorage.getCartesian3()); + } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return Cartesian4.add(left, right, scratchStorage.getCartesian4()); + } else if ((typeof left === 'string') || (typeof right === 'string')) { + // If only one argument is a string the other argument calls its toString function. + return left + right; + } else if ((typeof left === 'number') && (typeof right === 'number')) { + return left + right; + } - function onreaderror() { - terminate(onerror, ERR_READ_DATA); - } + throw new RuntimeError('Operator "+" requires vector or number arguments of matching types, or at least one string argument. Arguments are ' + left + ' and ' + right + '.'); + }; - return { - add : function(name, reader, onend, onprogress, options) { - var header, filename, date; + Node.prototype._evaluateMinus = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { + return Cartesian2.subtract(left, right, scratchStorage.getCartesian2()); + } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { + return Cartesian3.subtract(left, right, scratchStorage.getCartesian3()); + } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return Cartesian4.subtract(left, right, scratchStorage.getCartesian4()); + } else if ((typeof left === 'number') && (typeof right === 'number')) { + return left - right; + } - function writeHeader(callback) { - var data; - date = options.lastModDate || new Date(); - header = getDataHelper(26); - files[name] = { - headerArray : header.array, - directory : options.directory, - filename : filename, - offset : datalength, - comment : getBytes(encodeUTF8(options.comment || "")) - }; - header.view.setUint32(0, 0x14000808); - if (options.version) - header.view.setUint8(0, options.version); - if (!dontDeflate && options.level !== 0 && !options.directory) - header.view.setUint16(4, 0x0800); - header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true); - header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true); - header.view.setUint16(22, filename.length, true); - data = getDataHelper(30 + filename.length); - data.view.setUint32(0, 0x504b0304); - data.array.set(header.array, 4); - data.array.set(filename, 30); - datalength += data.array.length; - writer.writeUint8Array(data.array, callback, onwriteerror); - } + throw new RuntimeError('Operator "-" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); + }; - function writeFooter(compressedLength, crc32) { - var footer = getDataHelper(16); - datalength += compressedLength || 0; - footer.view.setUint32(0, 0x504b0708); - if (typeof crc32 != "undefined") { - header.view.setUint32(10, crc32, true); - footer.view.setUint32(4, crc32, true); - } - if (reader) { - footer.view.setUint32(8, compressedLength, true); - header.view.setUint32(14, compressedLength, true); - footer.view.setUint32(12, reader.size, true); - header.view.setUint32(18, reader.size, true); - } - writer.writeUint8Array(footer.array, function() { - datalength += 16; - terminate(onend); - }, onwriteerror); - } + Node.prototype._evaluateTimes = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { + return Cartesian2.multiplyComponents(left, right, scratchStorage.getCartesian2()); + } else if ((right instanceof Cartesian2) && (typeof left === 'number')) { + return Cartesian2.multiplyByScalar(right, left, scratchStorage.getCartesian2()); + } else if ((left instanceof Cartesian2) && (typeof right === 'number')) { + return Cartesian2.multiplyByScalar(left, right, scratchStorage.getCartesian2()); + } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { + return Cartesian3.multiplyComponents(left, right, scratchStorage.getCartesian3()); + } else if ((right instanceof Cartesian3) && (typeof left === 'number')) { + return Cartesian3.multiplyByScalar(right, left, scratchStorage.getCartesian3()); + } else if ((left instanceof Cartesian3) && (typeof right === 'number')) { + return Cartesian3.multiplyByScalar(left, right, scratchStorage.getCartesian3()); + } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return Cartesian4.multiplyComponents(left, right, scratchStorage.getCartesian4()); + } else if ((right instanceof Cartesian4) && (typeof left === 'number')) { + return Cartesian4.multiplyByScalar(right, left, scratchStorage.getCartesian4()); + } else if ((left instanceof Cartesian4) && (typeof right === 'number')) { + return Cartesian4.multiplyByScalar(left, right, scratchStorage.getCartesian4()); + } else if ((typeof left === 'number') && (typeof right === 'number')) { + return left * right; + } - function writeFile() { - options = options || {}; - name = name.trim(); - if (options.directory && name.charAt(name.length - 1) != "/") - name += "/"; - if (files.hasOwnProperty(name)) { - onerror(ERR_DUPLICATED_NAME); - return; - } - filename = getBytes(encodeUTF8(name)); - filenames.push(name); - writeHeader(function() { - if (reader) - if (dontDeflate || options.level === 0) - copy(reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror); - else - worker = deflate(reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror); - else - writeFooter(); - }, onwriteerror); - } + throw new RuntimeError('Operator "*" requires vector or number arguments. If both arguments are vectors they must be matching types. Arguments are ' + left + ' and ' + right + '.'); + }; - if (reader) - reader.init(writeFile, onreaderror); - else - writeFile(); - }, - close : function(callback) { - var data, length = 0, index = 0, indexFilename, file; - for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { - file = files[filenames[indexFilename]]; - length += 46 + file.filename.length + file.comment.length; - } - data = getDataHelper(length + 22); - for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { - file = files[filenames[indexFilename]]; - data.view.setUint32(index, 0x504b0102); - data.view.setUint16(index + 4, 0x1400); - data.array.set(file.headerArray, index + 6); - data.view.setUint16(index + 32, file.comment.length, true); - if (file.directory) - data.view.setUint8(index + 38, 0x10); - data.view.setUint32(index + 42, file.offset, true); - data.array.set(file.filename, index + 46); - data.array.set(file.comment, index + 46 + file.filename.length); - index += 46 + file.filename.length + file.comment.length; - } - data.view.setUint32(index, 0x504b0506); - data.view.setUint16(index + 8, filenames.length, true); - data.view.setUint16(index + 10, filenames.length, true); - data.view.setUint32(index + 12, length, true); - data.view.setUint32(index + 16, datalength, true); - writer.writeUint8Array(data.array, function() { - terminate(function() { - writer.getData(callback); - }); - }, onwriteerror); - } - }; - } + Node.prototype._evaluateDivide = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { + return Cartesian2.divideComponents(left, right, scratchStorage.getCartesian2()); + } else if ((left instanceof Cartesian2) && (typeof right === 'number')) { + return Cartesian2.divideByScalar(left, right, scratchStorage.getCartesian2()); + } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { + return Cartesian3.divideComponents(left, right, scratchStorage.getCartesian3()); + } else if ((left instanceof Cartesian3) && (typeof right === 'number')) { + return Cartesian3.divideByScalar(left, right, scratchStorage.getCartesian3()); + } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return Cartesian4.divideComponents(left, right, scratchStorage.getCartesian4()); + } else if ((left instanceof Cartesian4) && (typeof right === 'number')) { + return Cartesian4.divideByScalar(left, right, scratchStorage.getCartesian4()); + } else if ((typeof left === 'number') && (typeof right === 'number')) { + return left / right; + } - obj.zip = { - Reader : Reader, - Writer : Writer, - BlobReader : BlobReader, - Data64URIReader : Data64URIReader, - TextReader : TextReader, - BlobWriter : BlobWriter, - Data64URIWriter : Data64URIWriter, - TextWriter : TextWriter, - createReader : function(reader, callback, onerror) { - reader.init(function() { - callback(createZipReader(reader, onerror)); - }, onerror); - }, - createWriter : function(writer, callback, onerror, dontDeflate) { - writer.init(function() { - callback(createZipWriter(writer, onerror, dontDeflate)); - }, onerror); - }, - useWebWorkers : true - }; + throw new RuntimeError('Operator "/" requires vector or number arguments of matching types, or a number as the second argument. Arguments are ' + left + ' and ' + right + '.'); + }; - var workerScriptsPath; + Node.prototype._evaluateMod = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { + return Cartesian2.fromElements(left.x % right.x, left.y % right.y, scratchStorage.getCartesian2()); + } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { + return Cartesian3.fromElements(left.x % right.x, left.y % right.y, left.z % right.z, scratchStorage.getCartesian3()); + } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return Cartesian4.fromElements(left.x % right.x, left.y % right.y, left.z % right.z, left.w % right.w, scratchStorage.getCartesian4()); + } else if ((typeof left === 'number') && (typeof right === 'number')) { + return left % right; + } - defineProperties(obj.zip, { - 'workerScriptsPath' : { - get : function() { - if (typeof workerScriptsPath === 'undefined') { - workerScriptsPath = buildModuleUrl('ThirdParty/Workers/'); - } - return workerScriptsPath; - } + throw new RuntimeError('Operator "%" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); + }; + + Node.prototype._evaluateEqualsStrict = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2) || + (right instanceof Cartesian3) && (left instanceof Cartesian3) || + (right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return left.equals(right); } - }); + return left === right; + }; -})(tmp); + Node.prototype._evaluateNotEqualsStrict = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + if ((right instanceof Cartesian2) && (left instanceof Cartesian2) || + (right instanceof Cartesian3) && (left instanceof Cartesian3) || + (right instanceof Cartesian4) && (left instanceof Cartesian4)) { + return !left.equals(right); + } + return left !== right; + }; - return tmp.zip; -}); + Node.prototype._evaluateConditional = function(frameState, feature) { + var test = this._test.evaluate(frameState, feature); -define('DataSources/KmlLookAt',[], function() { - 'use strict'; - /** - * @alias KmlLookAt - * @constructor - * - * @param {Cartesian3} position camera position - * @param {HeadingPitchRange} headingPitchRange camera orientation - */ - function KmlLookAt(position, headingPitchRange) { - this.position = position; - this.headingPitchRange = headingPitchRange; - } + if (typeof test !== 'boolean') { + throw new RuntimeError('Conditional argument of conditional expression must be a boolean. Argument is ' + test + '.'); + } - return KmlLookAt; -}); + if (test) { + return this._left.evaluate(frameState, feature); + } + return this._right.evaluate(frameState, feature); + }; -define('DataSources/KmlTour',[ - '../Core/Event', - '../Core/defined' - ], function( - Event, - defined - ) { - 'use strict'; - /** - * @alias KMLTour - * @constructor - * - * @param {String} name name parsed from KML - * @param {String} id id parsed from KML - * @param {Array} playlist array with KMLTourFlyTos, KMLTourWaits and KMLTourSoundCues - */ - function KmlTour(name, id) { - /** - * Id of kml gx:Tour entry - */ - this.id = id; - /** - * Tour name - */ - this.name = name; - /** - * Index of current entry from playlist - * @type Number - */ - this.playlistIndex = 0; - /** - * Array of playlist entries - * @type Array - */ - this.playlist = []; - /** - * Event will be called when tour starts to play, - * before any playlist entry starts to play. - * @type Event - */ - this.tourStart = new Event(); - /** - * Event will be called when all playlist entries are - * played, or tour playback being canceled. - * - * If tour playback was terminated, event callback will - * be called with terminated=true parameter. - * @type Event - */ - this.tourEnd = new Event(); - /** - * Event will be called when entry from playlist starts to play. - * - * Event callback will be called with curent entry as first parameter. - * @type Event - */ - this.entryStart = new Event(); - /** - * Event will be called when entry from playlist ends to play. - * - * Event callback will be called with following parameters: - * 1. entry - entry - * 2. terminated - true if playback was terminated by calling {@link KmlTour#stop} - * @type Event - */ - this.entryEnd = new Event(); + Node.prototype._evaluateNaN = function(frameState, feature) { + return isNaN(this._left.evaluate(frameState, feature)); + }; - this._activeEntries = []; - } + Node.prototype._evaluateIsFinite = function(frameState, feature) { + return isFinite(this._left.evaluate(frameState, feature)); + }; - /** - * Add entry to this tour playlist. - * - * @param {KmlTourFlyTo|KmlTourWait} entry an entry to add to the playlist. - */ - KmlTour.prototype.addPlaylistEntry = function(entry) { - this.playlist.push(entry); + Node.prototype._evaluateIsExactClass = function(frameState, feature) { + return feature.isExactClass(this._left.evaluate(frameState, feature)); }; - /** - * Play this tour. - * - * @param {Viewer} viewer viewer widget. - * @param {Object} [cameraOptions] these options will be merged with {@link Camera#flyTo} - * options for FlyTo playlist entries. - */ - KmlTour.prototype.play = function(viewer, cameraOptions) { - this.tourStart.raiseEvent(); + Node.prototype._evaluateIsClass = function(frameState, feature) { + return feature.isClass(this._left.evaluate(frameState, feature)); + }; - var tour = this; - playEntry.call(this, viewer, cameraOptions, function(terminated) { - tour.playlistIndex = 0; - // Stop nonblocking entries - if (!terminated) { - cancelAllEntries(tour._activeEntries); - } - tour.tourEnd.raiseEvent(terminated); - }); + Node.prototype._evaluategetExactClassName = function(frameState, feature) { + return feature.getExactClassName(); }; - /** - * Stop curently playing tour. - */ - KmlTour.prototype.stop = function() { - cancelAllEntries(this._activeEntries); + Node.prototype._evaluateBooleanConversion = function(frameState, feature) { + return Boolean(this._left.evaluate(frameState, feature)); }; - /** - * Stop all activeEntries. - * @param {Array} activeEntries - */ - function cancelAllEntries(activeEntries) { - for(var entry = activeEntries.pop(); entry !== undefined; entry = activeEntries.pop()) { - entry.stop(); - } - } + Node.prototype._evaluateNumberConversion = function(frameState, feature) { + return Number(this._left.evaluate(frameState, feature)); + }; - /** - * Play playlist entry. - * This function is called recursevly with playNext - * and iterates over all entries from playlist. - * - * @param {ViewerWidget} viewer Cesium viewer. - * @param {Object} cameraOptions see {@link Camera#flyTo}. - * @param {Function} allDone a function will be called when all entries from playlist - * being played or user call {@link KmlTour#stop}. - */ - function playEntry(viewer, cameraOptions, allDone) { - var entry = this.playlist[this.playlistIndex]; - if (entry) { - var _playNext = playNext.bind(this, viewer, cameraOptions, allDone); - this._activeEntries.push(entry); - this.entryStart.raiseEvent(entry); - if (entry.blocking) { - entry.play(_playNext, viewer.scene.camera, cameraOptions); - } - else { - var tour = this; - entry.play(function() { - tour.entryEnd.raiseEvent(entry); - var indx = tour._activeEntries.indexOf(entry); - if (indx >= 0) { - tour._activeEntries.splice(indx, 1); - } - }); - _playNext(viewer, cameraOptions, allDone); - } + Node.prototype._evaluateStringConversion = function(frameState, feature) { + return String(this._left.evaluate(frameState, feature)); + }; + + Node.prototype._evaluateRegExp = function(frameState, feature) { + var pattern = this._value.evaluate(frameState, feature); + var flags = ''; + + if (defined(this._left)) { + flags = this._left.evaluate(frameState, feature); } - else if(defined(allDone)) { - allDone(false); + + var exp; + try { + exp = new RegExp(pattern, flags); + } catch (e) { + throw new RuntimeError(e); } - } + return exp; + }; - /** - * Increment playlistIndex and call playEntry - * if terminated isn't true. - * - * @param {ViewerWidget} viewer passed for recursion. - * @param {Object} cameraOptions passed for recursion. - * @param {Function} allDone passed for recursion. - * @param {Boolean} terminated true if active entry was terminated, - * and the whole tour should be terminated. - */ - function playNext(viewer, cameraOptions, allDone, terminated) { - var entry = this.playlist[this.playlistIndex]; - this.entryEnd.raiseEvent(entry, terminated); + Node.prototype._evaluateRegExpTest = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); - if (terminated) { - allDone(terminated); + if (!((left instanceof RegExp) && (typeof right === 'string'))) { + throw new RuntimeError('RegExp.test requires the first argument to be a RegExp and the second argument to be a string. Arguments are ' + left + ' and ' + right + '.'); } - else { - var indx = this._activeEntries.indexOf(entry); - if (indx >= 0) { - this._activeEntries.splice(indx, 1); - } - this.playlistIndex++; - playEntry.call(this, viewer, cameraOptions, allDone); + + return left.test(right); + }; + + Node.prototype._evaluateRegExpMatch = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + + if ((left instanceof RegExp) && (typeof right === 'string')) { + return left.test(right); + } else if ((right instanceof RegExp) && (typeof left === 'string')) { + return right.test(left); } - } - return KmlTour; -}); + throw new RuntimeError('Operator "=~" requires one RegExp argument and one string argument. Arguments are ' + left + ' and ' + right + '.'); + }; -define('DataSources/KmlTourFlyTo',[ - '../Core/defined', - '../Core/combine', - '../Core/BoundingSphere', - '../Core/EasingFunction' - ], function( - defined, - combine, - BoundingSphere, - EasingFunction - ) { - 'use strict'; - /** - * @alias KmlTourFlyTo - * @constructor - * - * @param {Number} duration entry duration - * @param {String} flyToMode KML fly to mode: bounce, smooth, etc - * @param {KmlCamera|KmlLookAt} view KmlCamera or KmlLookAt - */ - function KmlTourFlyTo(duration, flyToMode, view) { - this.type = 'KmlTourFlyTo'; - this.blocking = true; - this.activeCamera = null; - this.activeCallback = null; + Node.prototype._evaluateRegExpNotMatch = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); - this.duration = duration; - this.view = view; - this.flyToMode = flyToMode; - } + if ((left instanceof RegExp) && (typeof right === 'string')) { + return !(left.test(right)); + } else if ((right instanceof RegExp) && (typeof left === 'string')) { + return !(right.test(left)); + } - /** - * Play this playlist entry - * - * @param {KmlTourFlyTo~DoneCallback} done function which will be called when playback ends - * @param {Camera} camera Cesium camera - * @param {Object} [cameraOptions] which will be merged with camera flyTo options. See {@link Camera#flyTo} - */ - KmlTourFlyTo.prototype.play = function(done, camera, cameraOptions) { - this.activeCamera = camera; - if (defined(done) && done !== null) { - var self = this; - this.activeCallback = function(terminated) { - delete self.activeCallback; - delete self.activeCamera; - done(defined(terminated) ? false : terminated); - }; + throw new RuntimeError('Operator "!~" requires one RegExp argument and one string argument. Arguments are ' + left + ' and ' + right + '.'); + }; + + Node.prototype._evaluateRegExpExec = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + var right = this._right.evaluate(frameState, feature); + + if (!((left instanceof RegExp) && (typeof right === 'string'))) { + throw new RuntimeError('RegExp.exec requires the first argument to be a RegExp and the second argument to be a string. Arguments are ' + left + ' and ' + right + '.'); } - var options = this.getCameraOptions(cameraOptions); - if (this.view.headingPitchRoll) { - camera.flyTo(options); + var exec = left.exec(right); + if (!defined(exec)) { + return null; } - else if (this.view.headingPitchRange) { - var target = new BoundingSphere(this.view.position); - camera.flyToBoundingSphere(target, options); + return exec[1]; + }; + + Node.prototype._evaluateToString = function(frameState, feature) { + var left = this._left.evaluate(frameState, feature); + if ((left instanceof RegExp) || (left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4)) { + return String(left); } + + throw new RuntimeError('Unexpected function call "' + this._value + '".'); }; - /** - * Stop execution of curent entry. Cancel camera flyTo - */ - KmlTourFlyTo.prototype.stop = function() { - if (defined(this.activeCamera)) { - this.activeCamera.cancelFlight(); + function convertHSLToRGB(ast) { + // Check if the color contains any nested expressions to see if the color can be converted here. + // E.g. "hsl(0.9, 0.6, 0.7)" is able to convert directly to rgb, "hsl(0.9, 0.6, ${Height})" is not. + var channels = ast._left; + var length = channels.length; + for (var i = 0; i < length; ++i) { + if (channels[i]._type !== ExpressionNodeType.LITERAL_NUMBER) { + return undefined; + } } - if (defined(this.activeCallback)) { - this.activeCallback(true); + var h = channels[0]._value; + var s = channels[1]._value; + var l = channels[2]._value; + var a = (length === 4) ? channels[3]._value : 1.0; + return Color.fromHsl(h, s, l, a, scratchColor); + } + + function convertRGBToColor(ast) { + // Check if the color contains any nested expressions to see if the color can be converted here. + // E.g. "rgb(255, 255, 255)" is able to convert directly to Color, "rgb(255, 255, ${Height})" is not. + var channels = ast._left; + var length = channels.length; + for (var i = 0; i < length; ++i) { + if (channels[i]._type !== ExpressionNodeType.LITERAL_NUMBER) { + return undefined; + } + } + var color = scratchColor; + color.red = channels[0]._value / 255.0; + color.green = channels[1]._value / 255.0; + color.blue = channels[2]._value / 255.0; + color.alpha = (length === 4) ? channels[3]._value : 1.0; + return color; + } + + function numberToString(number) { + if (number % 1 === 0) { + // Add a .0 to whole numbers + return number.toFixed(1); } - }; - /** - * Returns options for {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} - * depends on this.view type. - * - * @param {Object} cameraOptions options to merge with generated. See {@link Camera#flyTo} - * @returns {Object} {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} options - */ - KmlTourFlyTo.prototype.getCameraOptions = function(cameraOptions) { - var options = { - duration: this.duration - }; + return number.toString(); + } - if (defined(this.activeCallback)) { - options.complete = this.activeCallback; - } + function colorToVec3(color) { + var r = numberToString(color.red); + var g = numberToString(color.green); + var b = numberToString(color.blue); + return 'vec3(' + r + ', ' + g + ', ' + b + ')'; + } - if (this.flyToMode === 'smooth' ) { - options.easingFunction = EasingFunction.LINEAR_NONE; - } + function colorToVec4(color) { + var r = numberToString(color.red); + var g = numberToString(color.green); + var b = numberToString(color.blue); + var a = numberToString(color.alpha); + return 'vec4(' + r + ', ' + g + ', ' + b + ', ' + a + ')'; + } - if (this.view.headingPitchRoll) { - options.destination = this.view.position; - options.orientation = this.view.headingPitchRoll; - } - else if (this.view.headingPitchRange) { - options.offset = this.view.headingPitchRange; + function getExpressionArray(array, attributePrefix, shaderState, parent) { + var length = array.length; + var expressions = new Array(length); + for (var i = 0; i < length; ++i) { + expressions[i] = array[i].getShaderExpression(attributePrefix, shaderState, parent); } + return expressions; + } - if (defined(cameraOptions)) { - options = combine(options, cameraOptions); - } - return options; - }; + Node.prototype.getShaderExpression = function(attributePrefix, shaderState, parent) { + var color; + var left; + var right; + var test; - /** - * A function that will be executed when the flight completes. - * @callback KmlTourFlyTo~DoneCallback - * - * @param {Boolean} terminated true if {@link KmlTourFlyTo#stop} was - * called before entry done playback. - */ + var type = this._type; + var value = this._value; - return KmlTourFlyTo; -}); + if (defined(this._left)) { + if (isArray(this._left)) { + // Left can be an array if the type is LITERAL_COLOR or LITERAL_VECTOR + left = getExpressionArray(this._left, attributePrefix, shaderState, this); + } else { + left = this._left.getShaderExpression(attributePrefix, shaderState, this); + } + } -define('DataSources/KmlTourWait',[ - '../Core/defined' - ], function( - defined - ) { - 'use strict'; - /** - * @alias KmlTourWait - * @constructor - * - * @param {Number} duration entry duration - */ - function KmlTourWait(duration) { - this.type = 'KmlTourWait'; - this.blocking = true; - this.duration = duration; + if (defined(this._right)) { + right = this._right.getShaderExpression(attributePrefix, shaderState, this); + } - this.timeout = null; - } + if (defined(this._test)) { + test = this._test.getShaderExpression(attributePrefix, shaderState, this); + } - /** - * Play this playlist entry - * - * @param {KmlTourWait~DoneCallback} done function which will be called when playback ends - */ - KmlTourWait.prototype.play = function(done) { - var self = this; - this.activeCallback = done; - this.timeout = setTimeout(function() { - delete self.activeCallback; - done(false); - }, this.duration * 1000); - }; + if (isArray(this._value)) { + // For ARRAY type + value = getExpressionArray(this._value, attributePrefix, shaderState, this); + } - /** - * Stop execution of curent entry, cancel curent timeout - */ - KmlTourWait.prototype.stop = function() { - clearTimeout(this.timeout); - if (defined(this.activeCallback)) { - this.activeCallback(true); + switch (type) { + case ExpressionNodeType.VARIABLE: + return attributePrefix + value; + case ExpressionNodeType.UNARY: + // Supported types: +, -, !, Boolean, Number + if (value === 'Boolean') { + return 'bool(' + left + ')'; + } else if (value === 'Number') { + return 'float(' + left + ')'; + } else if (value === 'round') { + return 'floor(' + left + ' + 0.5)'; + } else if (defined(unaryFunctions[value])) { + return value + '(' + left + ')'; + } else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass') || (value === 'getExactClassName')) { + throw new RuntimeError('Error generating style shader: "' + value + '" is not supported.'); + } else if (defined(unaryFunctions[value])) { + return value + '(' + left + ')'; + } + return value + left; + case ExpressionNodeType.BINARY: + // Supported types: ||, &&, ===, !==, <, >, <=, >=, +, -, *, /, % + if (value === '%') { + return 'mod(' + left + ', ' + right + ')'; + } else if (value === '===') { + return '(' + left + ' == ' + right + ')'; + } else if (value === '!==') { + return '(' + left + ' != ' + right + ')'; + } else if (value === 'atan2') { + return 'atan(' + left + ', ' + right + ')'; + } else if (defined(binaryFunctions[value])) { + return value + '(' + left + ', ' + right + ')'; + } + return '(' + left + ' ' + value + ' ' + right + ')'; + case ExpressionNodeType.TERNARY: + if (defined(ternaryFunctions[value])) { + return value + '(' + left + ', ' + right + ', ' + test + ')'; + } + break; + case ExpressionNodeType.CONDITIONAL: + return '(' + test + ' ? ' + left + ' : ' + right + ')'; + case ExpressionNodeType.MEMBER: + // This is intended for accessing the components of vector properties. String members aren't supported. + // Check for 0.0 rather than 0 because all numbers are previously converted to decimals. + if (right === 'r' || right === 'x' || right === '0.0') { + return left + '[0]'; + } else if (right === 'g' || right === 'y' || right === '1.0') { + return left + '[1]'; + } else if (right === 'b' || right === 'z' || right === '2.0') { + return left + '[2]'; + } else if (right === 'a' || right === 'w' || right === '3.0') { + return left + '[3]'; + } + return left + '[int(' + right + ')]'; + case ExpressionNodeType.FUNCTION_CALL: + throw new RuntimeError('Error generating style shader: "' + value + '" is not supported.'); + case ExpressionNodeType.ARRAY: + if (value.length === 4) { + return 'vec4(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + value[3] + ')'; + } else if (value.length === 3) { + return 'vec3(' + value[0] + ', ' + value[1] + ', ' + value[2] + ')'; + } else if (value.length === 2) { + return 'vec2(' + value[0] + ', ' + value[1] + ')'; + } + throw new RuntimeError('Error generating style shader: Invalid array length. Array length should be 2, 3, or 4.'); + case ExpressionNodeType.REGEX: + throw new RuntimeError('Error generating style shader: Regular expressions are not supported.'); + case ExpressionNodeType.VARIABLE_IN_STRING: + throw new RuntimeError('Error generating style shader: Converting a variable to a string is not supported.'); + case ExpressionNodeType.LITERAL_NULL: + throw new RuntimeError('Error generating style shader: null is not supported.'); + case ExpressionNodeType.LITERAL_BOOLEAN: + return value ? 'true' : 'false'; + case ExpressionNodeType.LITERAL_NUMBER: + return numberToString(value); + case ExpressionNodeType.LITERAL_STRING: + if (defined(parent) && (parent._type === ExpressionNodeType.MEMBER)) { + if (value === 'r' || value === 'g' || value === 'b' || value === 'a' || + value === 'x' || value === 'y' || value === 'z' || value === 'w') { + return value; + } + } + // Check for css color strings + color = Color.fromCssColorString(value, scratchColor); + if (defined(color)) { + return colorToVec3(color); + } + throw new RuntimeError('Error generating style shader: String literals are not supported.'); + case ExpressionNodeType.LITERAL_COLOR: + var args = left; + if (value === 'color') { + if (!defined(args)) { + return 'vec4(1.0)'; + } else if (args.length > 1) { + var rgb = args[0]; + var alpha = args[1]; + if (alpha !== '1.0') { + shaderState.translucent = true; + } + return 'vec4(' + rgb + ', ' + alpha + ')'; + } + return 'vec4(' + args[0] + ', 1.0)'; + } else if (value === 'rgb') { + color = convertRGBToColor(this); + if (defined(color)) { + return colorToVec4(color); + } + return 'vec4(' + args[0] + ' / 255.0, ' + args[1] + ' / 255.0, ' + args[2] + ' / 255.0, 1.0)'; + } else if (value === 'rgba') { + if (args[3] !== '1.0') { + shaderState.translucent = true; + } + color = convertRGBToColor(this); + if (defined(color)) { + return colorToVec4(color); + } + return 'vec4(' + args[0] + ' / 255.0, ' + args[1] + ' / 255.0, ' + args[2] + ' / 255.0, ' + args[3] + ')'; + } else if (value === 'hsl') { + color = convertHSLToRGB(this); + if (defined(color)) { + return colorToVec4(color); + } + return 'vec4(czm_HSLToRGB(vec3(' + args[0] + ', ' + args[1] + ', ' + args[2] + ')), 1.0)'; + } else if (value === 'hsla') { + color = convertHSLToRGB(this); + if (defined(color)) { + if (color.alpha !== 1.0) { + shaderState.translucent = true; + } + return colorToVec4(color); + } + if (args[3] !== '1.0') { + shaderState.translucent = true; + } + return 'vec4(czm_HSLToRGB(vec3(' + args[0] + ', ' + args[1] + ', ' + args[2] + ')), ' + args[3] + ')'; + } + break; + case ExpressionNodeType.LITERAL_VECTOR: + if (!defined(left)) { + throw new DeveloperError('left should always be defined for type ExpressionNodeType.LITERAL_VECTOR'); + } + var length = left.length; + var vectorExpression = value + '('; + for (var i = 0; i < length; ++i) { + vectorExpression += left[i]; + if (i < (length - 1)) { + vectorExpression += ', '; + } + } + vectorExpression += ')'; + return vectorExpression; + case ExpressionNodeType.LITERAL_REGEX: + throw new RuntimeError('Error generating style shader: Regular expressions are not supported.'); + case ExpressionNodeType.LITERAL_UNDEFINED: + throw new RuntimeError('Error generating style shader: undefined is not supported.'); + case ExpressionNodeType.BUILTIN_VARIABLE: + if (value === 'tiles3d_tileset_time') { + return 'u_tilesetTime'; + } } }; - /** - * A function which will be called when playback ends. - * - * @callback KmlTourWait~DoneCallback - * @param {Boolean} terminated true if {@link KmlTourWait#stop} was - * called before entry done playback. - */ - - return KmlTourWait; + return Expression; }); -define('DataSources/KmlDataSource',[ - '../Core/AssociativeArray', - '../Core/BoundingRectangle', - '../Core/Cartesian2', +define('Scene/Vector3DTilePrimitive',[ '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/ClockRange', - '../Core/ClockStep', '../Core/Color', - '../Core/createGuid', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/Event', - '../Core/getAbsoluteUri', - '../Core/getExtensionFromUri', - '../Core/getFilenameFromUri', - '../Core/Iso8601', - '../Core/joinUrls', - '../Core/JulianDate', - '../Core/loadBlob', - '../Core/loadXML', - '../Core/Math', - '../Core/NearFarScalar', - '../Core/objectToQuery', - '../Core/oneTimeWarning', - '../Core/PinBuilder', - '../Core/PolygonHierarchy', - '../Core/Rectangle', - '../Core/RuntimeError', - '../Core/TimeInterval', - '../Core/TimeIntervalCollection', - '../Core/HeadingPitchRoll', - '../Core/HeadingPitchRange', - '../Scene/HeightReference', - '../Scene/HorizontalOrigin', - '../Scene/LabelStyle', - '../Scene/SceneMode', - '../ThirdParty/Autolinker', - '../ThirdParty/Uri', - '../ThirdParty/when', - '../ThirdParty/zip', - './BillboardGraphics', - './CompositePositionProperty', - './CorridorGraphics', - './DataSource', - './DataSourceClock', - './Entity', - './EntityCluster', - './EntityCollection', - './LabelGraphics', - './PathGraphics', - './PolygonGraphics', - './PolylineGraphics', - './PositionPropertyArray', - './RectangleGraphics', - './ReferenceProperty', - './SampledPositionProperty', - './ScaledPositionProperty', - './TimeIntervalCollectionProperty', - './WallGraphics', - './KmlLookAt', - './KmlCamera', - './KmlTour', - './KmlTourFlyTo', - './KmlTourWait' + '../Core/destroyObject', + '../Core/IndexDatatype', + '../Core/Matrix4', + '../Core/PrimitiveType', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArray', + '../Shaders/ShadowVolumeFS', + '../Shaders/ShadowVolumeVS', + './BlendingState', + './Cesium3DTileFeature', + './ClassificationType', + './DepthFunction', + './Expression', + './StencilFunction', + './StencilOperation', + './Vector3DTileBatch' ], function( - AssociativeArray, - BoundingRectangle, - Cartesian2, Cartesian3, - Cartographic, - ClockRange, - ClockStep, Color, - createGuid, + ComponentDatatype, defaultValue, defined, defineProperties, - DeveloperError, - Ellipsoid, - Event, - getAbsoluteUri, - getExtensionFromUri, - getFilenameFromUri, - Iso8601, - joinUrls, - JulianDate, - loadBlob, - loadXML, - CesiumMath, - NearFarScalar, - objectToQuery, - oneTimeWarning, - PinBuilder, - PolygonHierarchy, - Rectangle, - RuntimeError, - TimeInterval, - TimeIntervalCollection, - HeadingPitchRoll, - HeadingPitchRange, - HeightReference, - HorizontalOrigin, - LabelStyle, - SceneMode, - Autolinker, - Uri, - when, - zip, - BillboardGraphics, - CompositePositionProperty, - CorridorGraphics, - DataSource, - DataSourceClock, - Entity, - EntityCluster, - EntityCollection, - LabelGraphics, - PathGraphics, - PolygonGraphics, - PolylineGraphics, - PositionPropertyArray, - RectangleGraphics, - ReferenceProperty, - SampledPositionProperty, - ScaledPositionProperty, - TimeIntervalCollectionProperty, - WallGraphics, - KmlLookAt, - KmlCamera, - KmlTour, - KmlTourFlyTo, - KmlTourWait) { + destroyObject, + IndexDatatype, + Matrix4, + PrimitiveType, + Buffer, + BufferUsage, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + VertexArray, + ShadowVolumeFS, + ShadowVolumeVS, + BlendingState, + Cesium3DTileFeature, + ClassificationType, + DepthFunction, + Expression, + StencilFunction, + StencilOperation, + Vector3DTileBatch) { 'use strict'; - // IE 8 doesn't have a DOM parser and can't run Cesium anyway, so just bail. - if (typeof DOMParser === 'undefined') { - return {}; - } + /** + * Creates a batch of classification meshes. + * + * @alias Vector3DTilePrimitive + * @constructor + * + * @param {Object} options An object with following properties: + * @param {Float32Array} options.positions The positions of the meshes. + * @param {Uint16Array|Uint32Array} options.indices The indices of the triangulated meshes. The indices must be contiguous so that + * the indices for mesh n are in [i, i + indexCounts[n]] where i = sum{indexCounts[0], indexCounts[n - 1]}. + * @param {Uint32Array} options.indexCounts The number of indices for each mesh. + * @param {Uint32Array} options.indexOffsets The offset into the index buffer for each mesh. + * @param {Vector3DTileBatch[]} options.batchedIndices The index offset and count for each batch with the same color. + * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center. + * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched meshes. + * @param {Uint16Array} options.batchIds The batch ids for each mesh. + * @param {Uint16Array} options.vertexBatchIds The batch id for each vertex. + * @param {BoundingSphere} options.boundingVolume The bounding volume for the entire batch of meshes. + * @param {BoundingSphere[]} options.boundingVolumes The bounding volume for each mesh. + * @param {ClassificationType} [options.classificationType] What this tile will classify. + * + * @private + */ + function Vector3DTilePrimitive(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //This is by no means an exhaustive list of MIME types. - //The purpose of this list is to be able to accurately identify content embedded - //in KMZ files. Eventually, we can make this configurable by the end user so they can add - //there own content types if they have KMZ files that require it. - var MimeTypes = { - avi : 'video/x-msvideo', - bmp : 'image/bmp', - bz2 : 'application/x-bzip2', - chm : 'application/vnd.ms-htmlhelp', - css : 'text/css', - csv : 'text/csv', - doc : 'application/msword', - dvi : 'application/x-dvi', - eps : 'application/postscript', - flv : 'video/x-flv', - gif : 'image/gif', - gz : 'application/x-gzip', - htm : 'text/html', - html : 'text/html', - ico : 'image/vnd.microsoft.icon', - jnlp : 'application/x-java-jnlp-file', - jpeg : 'image/jpeg', - jpg : 'image/jpeg', - m3u : 'audio/x-mpegurl', - m4v : 'video/mp4', - mathml : 'application/mathml+xml', - mid : 'audio/midi', - midi : 'audio/midi', - mov : 'video/quicktime', - mp3 : 'audio/mpeg', - mp4 : 'video/mp4', - mp4v : 'video/mp4', - mpeg : 'video/mpeg', - mpg : 'video/mpeg', - odp : 'application/vnd.oasis.opendocument.presentation', - ods : 'application/vnd.oasis.opendocument.spreadsheet', - odt : 'application/vnd.oasis.opendocument.text', - ogg : 'application/ogg', - pdf : 'application/pdf', - png : 'image/png', - pps : 'application/vnd.ms-powerpoint', - ppt : 'application/vnd.ms-powerpoint', - ps : 'application/postscript', - qt : 'video/quicktime', - rdf : 'application/rdf+xml', - rss : 'application/rss+xml', - rtf : 'application/rtf', - svg : 'image/svg+xml', - swf : 'application/x-shockwave-flash', - text : 'text/plain', - tif : 'image/tiff', - tiff : 'image/tiff', - txt : 'text/plain', - wav : 'audio/x-wav', - wma : 'audio/x-ms-wma', - wmv : 'video/x-ms-wmv', - xml : 'application/xml', - zip : 'application/zip', + this._batchTable = options.batchTable; + this._batchIds = options.batchIds; - detectFromFilename : function(filename) { - var ext = filename.toLowerCase(); - ext = getExtensionFromUri(ext); - return MimeTypes[ext]; - } - }; + // These arrays are released after VAO creation. + this._positions = options.positions; + this._vertexBatchIds = options.vertexBatchIds; - var parser = new DOMParser(); - var autolinker = new Autolinker({ - stripPrefix : false, - twitter : false, - email : false, - replaceFn : function(linker, match) { - if (!match.protocolUrlMatch) { - //Prevent matching of non-explicit urls. - //i.e. foo.id won't match but http://foo.id will - return false; - } - } - }); + // These arrays are kept for re-batching indices based on colors. + // If WebGL 2 is supported, indices will be released and re-batching uses buffer-to-buffer copies. + this._indices = options.indices; + this._indexCounts = options.indexCounts; + this._indexOffsets = options.indexOffsets; + this._batchedIndices = options.batchedIndices; - var BILLBOARD_SIZE = 32; + this._boundingVolume = options.boundingVolume; + this._boundingVolumes = options.boundingVolumes; - var BILLBOARD_NEAR_DISTANCE = 2414016; - var BILLBOARD_NEAR_RATIO = 1.0; - var BILLBOARD_FAR_DISTANCE = 1.6093e+7; - var BILLBOARD_FAR_RATIO = 0.1; + this._center = defaultValue(options.center, Cartesian3.ZERO); - function isZipFile(blob) { - var magicBlob = blob.slice(0, Math.min(4, blob.size)); - var deferred = when.defer(); - var reader = new FileReader(); - reader.addEventListener('load', function() { - deferred.resolve(new DataView(reader.result).getUint32(0, false) === 0x504b0304); - }); - reader.addEventListener('error', function() { - deferred.reject(reader.error); - }); - reader.readAsArrayBuffer(magicBlob); - return deferred.promise; - } + this._va = undefined; + this._sp = undefined; + this._spStencil = undefined; + this._spPick = undefined; + this._uniformMap = undefined; - function readBlobAsText(blob) { - var deferred = when.defer(); - var reader = new FileReader(); - reader.addEventListener('load', function() { - deferred.resolve(reader.result); - }); - reader.addEventListener('error', function() { - deferred.reject(reader.error); - }); - reader.readAsText(blob); - return deferred.promise; - } + // Only used with WebGL 2 to ping-pong ibos after copy. + this._vaSwap = undefined; - function insertNamespaces(text) { - var namespaceMap = { - xsi : 'http://www.w3.org/2001/XMLSchema-instance' - }; - var firstPart, lastPart, reg, declaration; + this._rsStencilPreloadPass = undefined; + this._rsStencilDepthPass = undefined; + this._rsColorPass = undefined; + this._rsPickPass = undefined; + this._rsWireframe = undefined; - for (var key in namespaceMap) { - if (namespaceMap.hasOwnProperty(key)) { - reg = RegExp('[< ]' + key + ':'); - declaration = 'xmlns:' + key + '='; - if (reg.test(text) && text.indexOf(declaration) === -1) { - if (!defined(firstPart)) { - firstPart = text.substr(0, text.indexOf('<kml') + 4); - lastPart = text.substr(firstPart.length); - } - firstPart += ' ' + declaration + '"' + namespaceMap[key] + '"'; - } - } - } + this._commands = []; + this._commandsIgnoreShow = []; + this._pickCommands = []; - if (defined(firstPart)) { - text = firstPart + lastPart; - } + this._constantColor = Color.clone(Color.WHITE); + this._highlightColor = this._constantColor; - return text; - } + this._batchDirty = true; + this._pickCommandsDirty = true; + this._framesSinceLastRebatch = 0; - function removeDuplicateNamespaces(text) { - var index = text.indexOf('xmlns:'); - var endDeclaration = text.indexOf('>', index); - var namespace, startIndex, endIndex; + this._updatingAllCommands = false; - while ((index !== -1) && (index < endDeclaration)) { - namespace = text.slice(index, text.indexOf('\"', index)); - startIndex = index; - index = text.indexOf(namespace, index + 1); - if (index !== -1) { - endIndex = text.indexOf('\"', (text.indexOf('\"', index) + 1)); - text = text.slice(0, index -1) + text.slice(endIndex + 1, text.length); - index = text.indexOf('xmlns:', startIndex - 1); - } else { - index = text.indexOf('xmlns:', startIndex + 1); - } - } + this._trianglesLength = this._indices.length / 3; + this._geometryByteLength = this._indices.byteLength + this._positions.byteLength + this._vertexBatchIds.byteLength; - return text; - } + /** + * Draw the wireframe of the classification meshes. + * @type {Boolean} + * @default false + */ + this.debugWireframe = false; + this._debugWireframe = this.debugWireframe; + this._wireframeDirty = false; - function loadXmlFromZip(reader, entry, uriResolver, deferred) { - entry.getData(new zip.TextWriter(), function(text) { - text = insertNamespaces(text); - text = removeDuplicateNamespaces(text); - uriResolver.kml = parser.parseFromString(text, 'application/xml'); - deferred.resolve(); - }); - } + /** + * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only. + * @type {Boolean} + * @default false + */ + this.forceRebatch = false; - function loadDataUriFromZip(reader, entry, uriResolver, deferred) { - var mimeType = defaultValue(MimeTypes.detectFromFilename(entry.filename), 'application/octet-stream'); - entry.getData(new zip.Data64URIWriter(mimeType), function(dataUri) { - uriResolver[entry.filename] = dataUri; - deferred.resolve(); - }); - } + /** + * What this tile will classify. + * @type {ClassificationType} + * @default ClassificationType.BOTH + */ + this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); - function embedDataUris(div, elementType, attributeName, uriResolver) { - var keys = uriResolver.keys; - var baseUri = new Uri('.'); - var elements = div.querySelectorAll(elementType); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - var value = element.getAttribute(attributeName); - var uri = new Uri(value).resolve(baseUri).toString(); - var index = keys.indexOf(uri); - if (index !== -1) { - var key = keys[index]; - element.setAttribute(attributeName, uriResolver[key]); - if (elementType === 'a' && element.getAttribute('download') === null) { - element.setAttribute('download', key); - } - } - } - } + // Hidden options + this._vertexShaderSource = options._vertexShaderSource; + this._fragmentShaderSource = options._fragmentShaderSource; + this._attributeLocations = options._attributeLocations; + this._pickVertexShaderSource = options._pickVertexShaderSource; + this._pickFragmentShaderSource = options._pickFragmentShaderSource; + this._uniformMap = options._uniformMap; + this._pickUniformMap = options._pickUniformMap; + this._modelMatrix = options._modelMatrix; + this._boundingSphere = options._boundingSphere; - function applyBasePath(div, elementType, attributeName, proxy, sourceUri, query) { - var elements = div.querySelectorAll(elementType); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - var value = element.getAttribute(attributeName); - var uri = resolveHref(value, proxy, sourceUri, query); - element.setAttribute(attributeName, uri); - } - } + this._batchIdLookUp = {}; - function proxyUrl(url, proxy, query) { - if (defined(proxy)) { - if (new Uri(url).isAbsolute()) { - url = proxy.getURL(url); - } - } - if (defined(query)) { - url = joinUrls(url, '?' + query, false); + var length = this._batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = this._batchIds[i]; + this._batchIdLookUp[batchId] = i; } - return url; } - // an optional context is passed to allow for some malformed kmls (those with multiple geometries with same ids) to still parse - // correctly, as they do in Google Earth. - function createEntity(node, entityCollection, context) { - var id = queryStringAttribute(node, 'id'); - id = defined(id) && id.length !== 0 ? id : createGuid(); - if (defined(context)) { - id = context + id; - } - - // If we have a duplicate ID just generate one. - // This isn't valid KML but Google Earth handles this case. - var entity = entityCollection.getById(id); - if (defined(entity)) { - id = createGuid(); - if (defined(context)) { - id = context + id; + defineProperties(Vector3DTilePrimitive.prototype, { + /** + * Gets the number of triangles. + * + * @memberof Vector3DTilePrimitive.prototype + * + * @type {Number} + * @readonly + */ + trianglesLength : { + get : function() { + return this._trianglesLength; } - } + }, - entity = entityCollection.add(new Entity({id : id})); - if (!defined(entity.kml)) { - entity.addProperty('kml'); - entity.kml = new KmlFeatureData(); + /** + * Gets the geometry memory in bytes. + * + * @memberof Vector3DTilePrimitive.prototype + * + * @type {Number} + * @readonly + */ + geometryByteLength : { + get : function() { + return this._geometryByteLength; + } } - return entity; - } + }); - function isExtrudable(altitudeMode, gxAltitudeMode) { - return altitudeMode === 'absolute' || altitudeMode === 'relativeToGround' || gxAltitudeMode === 'relativeToSeaFloor'; - } + var defaultAttributeLocations = { + position : 0, + a_batchId : 1 + }; - function readCoordinate(value) { - //Google Earth treats empty or missing coordinates as 0. - if (!defined(value)) { - return Cartesian3.fromDegrees(0, 0, 0); + function createVertexArray(primitive, context) { + if (defined(primitive._va)) { + return; } - var digits = value.match(/[^\s,\n]+/g); - if (!defined(digits)) { - return Cartesian3.fromDegrees(0, 0, 0); - } + var positionBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : primitive._positions, + usage : BufferUsage.STATIC_DRAW + }); + var idBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : primitive._vertexBatchIds, + usage : BufferUsage.STATIC_DRAW + }); + var indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : primitive._indices, + usage : BufferUsage.DYNAMIC_DRAW, + indexDatatype : (primitive._indices.BYTES_PER_ELEMENT === 2) ? IndexDatatype.UNSIGNED_SHORT : IndexDatatype.UNSIGNED_INT + }); - var longitude = parseFloat(digits[0]); - var latitude = parseFloat(digits[1]); - var height = parseFloat(digits[2]); + var vertexAttributes = [{ + index : 0, + vertexBuffer : positionBuffer, + componentDatatype : ComponentDatatype.fromTypedArray(primitive._positions), + componentsPerAttribute : 3 + }, { + index : 1, + vertexBuffer : idBuffer, + componentDatatype : ComponentDatatype.fromTypedArray(primitive._vertexBatchIds), + componentsPerAttribute : 1 + }]; - longitude = isNaN(longitude) ? 0.0 : longitude; - latitude = isNaN(latitude) ? 0.0 : latitude; - height = isNaN(height) ? 0.0 : height; + primitive._va = new VertexArray({ + context : context, + attributes : vertexAttributes, + indexBuffer : indexBuffer + }); - return Cartesian3.fromDegrees(longitude, latitude, height); + if (context.webgl2) { + primitive._vaSwap = new VertexArray({ + context : context, + attributes : vertexAttributes, + indexBuffer : Buffer.createIndexBuffer({ + context : context, + sizeInBytes : indexBuffer.sizeInBytes, + usage : BufferUsage.DYNAMIC_DRAW, + indexDatatype : indexBuffer.indexDatatype + }) + }); + } + + primitive._batchedPositions = undefined; + primitive._transferrableBatchIds = undefined; + primitive._vertexBatchIds = undefined; + primitive._verticesPromise = undefined; } - function readCoordinates(element) { - if (!defined(element)) { - return undefined; + function createShaders(primitive, context) { + if (defined(primitive._sp)) { + return; } - var tuples = element.textContent.match(/[^\s\n]+/g); - if (!defined(tuples)) { - return undefined; - } + var batchTable = primitive._batchTable; + var attributeLocations = defaultValue(primitive._attributeLocations, defaultAttributeLocations); - var length = tuples.length; - var result = new Array(length); - var resultIndex = 0; - for (var i = 0; i < length; i++) { - result[resultIndex++] = readCoordinate(tuples[i]); + var vertexShaderSource = primitive._vertexShaderSource; + if (defined(vertexShaderSource)) { + primitive._sp = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vertexShaderSource, + fragmentShaderSource : primitive._fragmentShaderSource, + attributeLocations : attributeLocations + }); + primitive._spStencil = primitive._sp; + primitive._spPick = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : primitive._pickVertexShaderSource, + fragmentShaderSource : primitive._pickFragmentShaderSource, + attributeLocations : attributeLocations + }); + return; } - return result; - } - var kmlNamespaces = [null, undefined, 'http://www.opengis.net/kml/2.2', 'http://earth.google.com/kml/2.2', 'http://earth.google.com/kml/2.1', 'http://earth.google.com/kml/2.0']; - var gxNamespaces = ['http://www.google.com/kml/ext/2.2']; - var atomNamespaces = ['http://www.w3.org/2005/Atom']; - var namespaces = { - kml : kmlNamespaces, - gx : gxNamespaces, - atom : atomNamespaces, - kmlgx : kmlNamespaces.concat(gxNamespaces) - }; + var vsSource = batchTable.getVertexShaderCallback(false, 'a_batchId', undefined)(ShadowVolumeVS); + var fsSource = batchTable.getFragmentShaderCallback()(ShadowVolumeFS, false, undefined); - function queryNumericAttribute(node, attributeName) { - if (!defined(node)) { - return undefined; - } + var vs = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [vsSource] + }); + var fs = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [fsSource] + }); - var value = node.getAttribute(attributeName); - if (value !== null) { - var result = parseFloat(value); - return !isNaN(result) ? result : undefined; - } - return undefined; - } + primitive._sp = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); - function queryStringAttribute(node, attributeName) { - if (!defined(node)) { - return undefined; - } - var value = node.getAttribute(attributeName); - return value !== null ? value : undefined; - } + vs = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [ShadowVolumeVS] + }); + fs = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [ShadowVolumeFS] + }); - function queryFirstNode(node, tagName, namespace) { - if (!defined(node)) { - return undefined; - } - var childNodes = node.childNodes; - var length = childNodes.length; - for (var q = 0; q < length; q++) { - var child = childNodes[q]; - if (child.localName === tagName && namespace.indexOf(child.namespaceURI) !== -1) { - return child; - } - } - return undefined; - } + primitive._spStencil = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); - function queryNodes(node, tagName, namespace) { - if (!defined(node)) { - return undefined; - } - var result = []; - var childNodes = node.getElementsByTagNameNS('*', tagName); - var length = childNodes.length; - for (var q = 0; q < length; q++) { - var child = childNodes[q]; - if (child.localName === tagName && namespace.indexOf(child.namespaceURI) !== -1) { - result.push(child); - } - } - return result; - } + vsSource = batchTable.getPickVertexShaderCallbackIgnoreShow('a_batchId')(ShadowVolumeVS); + fsSource = batchTable.getPickFragmentShaderCallbackIgnoreShow()(ShadowVolumeFS); - function queryChildNodes(node, tagName, namespace) { - if (!defined(node)) { - return []; - } - var result = []; - var childNodes = node.childNodes; - var length = childNodes.length; - for (var q = 0; q < length; q++) { - var child = childNodes[q]; - if (child.localName === tagName && namespace.indexOf(child.namespaceURI) !== -1) { - result.push(child); - } - } - return result; + var pickVS = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [vsSource] + }); + var pickFS = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [fsSource] + }); + primitive._spPick = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : pickVS, + fragmentShaderSource : pickFS, + attributeLocations : attributeLocations + }); } - function queryNumericValue(node, tagName, namespace) { - var resultNode = queryFirstNode(node, tagName, namespace); - if (defined(resultNode)) { - var result = parseFloat(resultNode.textContent); - return !isNaN(result) ? result : undefined; - } - return undefined; - } + var stencilReference = 0; + var stencilMask = 0x0F; - function queryStringValue(node, tagName, namespace) { - var result = queryFirstNode(node, tagName, namespace); - if (defined(result)) { - return result.textContent.trim(); - } - return undefined; - } + var stencilPreloadRenderState = { + colorMask : { + red : false, + green : false, + blue : false, + alpha : false + }, + stencilTest : { + enabled : true, + frontFunction : StencilFunction.ALWAYS, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.DECREMENT_WRAP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.ALWAYS, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.INCREMENT_WRAP, + zPass : StencilOperation.INCREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : false + }, + depthMask : false + }; - function queryBooleanValue(node, tagName, namespace) { - var result = queryFirstNode(node, tagName, namespace); - if (defined(result)) { - var value = result.textContent.trim(); - return value === '1' || /^true$/i.test(value); + var stencilDepthRenderState = { + colorMask : { + red : false, + green : false, + blue : false, + alpha : false + }, + stencilTest : { + enabled : true, + frontFunction : StencilFunction.ALWAYS, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.INCREMENT_WRAP + }, + backFunction : StencilFunction.ALWAYS, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : true, + func : DepthFunction.LESS_OR_EQUAL + }, + depthMask : false + }; + + var colorRenderState = { + stencilTest : { + enabled : true, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.NOT_EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : false + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND + }; + + var pickRenderState = { + stencilTest : { + enabled : true, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.NOT_EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : stencilReference, + mask : stencilMask + }, + depthTest : { + enabled : false + }, + depthMask : false + }; + + function createRenderStates(primitive) { + if (defined(primitive._rsStencilPreloadPass)) { + return; } - return undefined; + + primitive._rsStencilPreloadPass = RenderState.fromCache(stencilPreloadRenderState); + primitive._rsStencilDepthPass = RenderState.fromCache(stencilDepthRenderState); + primitive._rsColorPass = RenderState.fromCache(colorRenderState); + primitive._rsPickPass = RenderState.fromCache(pickRenderState); } - function resolveHref(href, proxy, sourceUri, uriResolver, query) { - if (!defined(href)) { - return undefined; - } - var hrefResolved = false; - if (defined(uriResolver)) { - var blob = uriResolver[href]; - if (defined(blob)) { - hrefResolved = true; - href = blob; - } else { - // Needed for multiple levels of KML files in a KMZ - var tmpHref = getAbsoluteUri(href, sourceUri); - blob = uriResolver[tmpHref]; - if (defined(blob)) { - hrefResolved = true; - href = blob; - } - } + var modifiedModelViewScratch = new Matrix4(); + var rtcScratch = new Cartesian3(); + + function createUniformMap(primitive, context) { + if (defined(primitive._uniformMap)) { + return; } - if (!hrefResolved) { - if (defined(sourceUri)) { - href = getAbsoluteUri(href, getAbsoluteUri(sourceUri)); + + var uniformMap = { + u_modifiedModelViewProjection : function() { + var viewMatrix = context.uniformState.view; + var projectionMatrix = context.uniformState.projection; + Matrix4.clone(viewMatrix, modifiedModelViewScratch); + Matrix4.multiplyByPoint(modifiedModelViewScratch, primitive._center, rtcScratch); + Matrix4.setTranslation(modifiedModelViewScratch, rtcScratch, modifiedModelViewScratch); + Matrix4.multiply(projectionMatrix, modifiedModelViewScratch, modifiedModelViewScratch); + return modifiedModelViewScratch; + }, + u_highlightColor : function() { + return primitive._highlightColor; } - href = proxyUrl(href, proxy, query); - } - return href; - } + }; - var colorOptions = {}; + primitive._uniformMap = primitive._batchTable.getUniformMapCallback()(uniformMap); + primitive._pickUniformMap = primitive._batchTable.getPickUniformMapCallback()(primitive._uniformMap); + } - function parseColorString(value, isRandom) { - if (!defined(value) || /^\s*$/gm.test(value)) { - return undefined; - } + function copyIndicesCPU(indices, newIndices, currentOffset, offsets, counts, batchIds, batchIdLookUp) { + var sizeInBytes = indices.constructor.BYTES_PER_ELEMENT; - if (value[0] === '#') { - value = value.substring(1); - } + var batchedIdsLength = batchIds.length; + for (var j = 0; j < batchedIdsLength; ++j) { + var batchedId = batchIds[j]; + var index = batchIdLookUp[batchedId]; + var offset = offsets[index]; + var count = counts[index]; - var alpha = parseInt(value.substring(0, 2), 16) / 255.0; - var blue = parseInt(value.substring(2, 4), 16) / 255.0; - var green = parseInt(value.substring(4, 6), 16) / 255.0; - var red = parseInt(value.substring(6, 8), 16) / 255.0; + var subarray = new indices.constructor(indices.buffer, sizeInBytes * offset, count); + newIndices.set(subarray, currentOffset); - if (!isRandom) { - return new Color(red, green, blue, alpha); + offsets[index] = currentOffset; + currentOffset += count; } - if (red > 0) { - colorOptions.maximumRed = red; - } else { - colorOptions.red = 0; - } - if (green > 0) { - colorOptions.maximumGreen = green; - } else { - colorOptions.green = 0; - } - if (blue > 0) { - colorOptions.maximumBlue = blue; - } else { - colorOptions.blue = 0; - } - colorOptions.alpha = alpha; - return Color.fromRandom(colorOptions); + return currentOffset; } - function queryColorValue(node, tagName, namespace) { - var value = queryStringValue(node, tagName, namespace); - if (!defined(value)) { - return undefined; + function rebatchCPU(primitive, batchedIndices) { + var indices = primitive._indices; + var indexOffsets = primitive._indexOffsets; + var indexCounts = primitive._indexCounts; + var batchIdLookUp = primitive._batchIdLookUp; + + var newIndices = new indices.constructor(indices.length); + + var current = batchedIndices.pop(); + var newBatchedIndices = [current]; + + var currentOffset = copyIndicesCPU(indices, newIndices, 0, indexOffsets, indexCounts, current.batchIds, batchIdLookUp); + + current.offset = 0; + current.count = currentOffset; + + while (batchedIndices.length > 0) { + var next = batchedIndices.pop(); + if (Color.equals(next.color, current.color)) { + currentOffset = copyIndicesCPU(indices, newIndices, currentOffset, indexOffsets, indexCounts, next.batchIds, batchIdLookUp); + current.batchIds = current.batchIds.concat(next.batchIds); + current.count = currentOffset - current.offset; + } else { + var offset = currentOffset; + currentOffset = copyIndicesCPU(indices, newIndices, currentOffset, indexOffsets, indexCounts, next.batchIds, batchIdLookUp); + + next.offset = offset; + next.count = currentOffset - offset; + newBatchedIndices.push(next); + current = next; + } } - return parseColorString(value, queryStringValue(node, 'colorMode', namespace) === 'random'); + + primitive._va.indexBuffer.copyFromArrayView(newIndices); + + primitive._indices = newIndices; + primitive._batchedIndices = newBatchedIndices; } - function processTimeStamp(featureNode) { - var node = queryFirstNode(featureNode, 'TimeStamp', namespaces.kmlgx); - var whenString = queryStringValue(node, 'when', namespaces.kmlgx); + function copyIndicesGPU(readBuffer, writeBuffer, currentOffset, offsets, counts, batchIds, batchIdLookUp) { + var sizeInBytes = readBuffer.bytesPerIndex; - if (!defined(node) || !defined(whenString) || whenString.length === 0) { - return undefined; + var batchedIdsLength = batchIds.length; + for (var j = 0; j < batchedIdsLength; ++j) { + var batchedId = batchIds[j]; + var index = batchIdLookUp[batchedId]; + var offset = offsets[index]; + var count = counts[index]; + + writeBuffer.copyFromBuffer(readBuffer, offset * sizeInBytes, currentOffset * sizeInBytes, count * sizeInBytes); + + offsets[index] = currentOffset; + currentOffset += count; } - //According to the KML spec, a TimeStamp represents a "single moment in time" - //However, since Cesium animates much differently than Google Earth, that doesn't - //Make much sense here. Instead, we use the TimeStamp as the moment the feature - //comes into existence. This works much better and gives a similar feel to - //GE's experience. - var when = JulianDate.fromIso8601(whenString); - var result = new TimeIntervalCollection(); - result.addInterval(new TimeInterval({ - start : when, - stop : Iso8601.MAXIMUM_VALUE - })); - return result; + return currentOffset; } - function processTimeSpan(featureNode) { - var node = queryFirstNode(featureNode, 'TimeSpan', namespaces.kmlgx); - if (!defined(node)) { - return undefined; - } - var result; + function rebatchGPU(primitive, batchedIndices) { + var indexOffsets = primitive._indexOffsets; + var indexCounts = primitive._indexCounts; + var batchIdLookUp = primitive._batchIdLookUp; - var beginNode = queryFirstNode(node, 'begin', namespaces.kmlgx); - var beginDate = defined(beginNode) ? JulianDate.fromIso8601(beginNode.textContent) : undefined; + var current = batchedIndices.pop(); + var newBatchedIndices = [current]; - var endNode = queryFirstNode(node, 'end', namespaces.kmlgx); - var endDate = defined(endNode) ? JulianDate.fromIso8601(endNode.textContent) : undefined; + var readBuffer = primitive._va.indexBuffer; + var writeBuffer = primitive._vaSwap.indexBuffer; - if (defined(beginDate) && defined(endDate)) { - if (JulianDate.lessThan(endDate, beginDate)) { - var tmp = beginDate; - beginDate = endDate; - endDate = tmp; + var currentOffset = copyIndicesGPU(readBuffer, writeBuffer, 0, indexOffsets, indexCounts, current.batchIds, batchIdLookUp); + + current.offset = 0; + current.count = currentOffset; + + while (batchedIndices.length > 0) { + var next = batchedIndices.pop(); + if (Color.equals(next.color, current.color)) { + currentOffset = copyIndicesGPU(readBuffer, writeBuffer, currentOffset, indexOffsets, indexCounts, next.batchIds, batchIdLookUp); + current.batchIds = current.batchIds.concat(next.batchIds); + current.count = currentOffset - current.offset; + } else { + var offset = currentOffset; + currentOffset = copyIndicesGPU(readBuffer, writeBuffer, currentOffset, indexOffsets, indexCounts, next.batchIds, batchIdLookUp); + next.offset = offset; + next.count = currentOffset - offset; + newBatchedIndices.push(next); + current = next; } - result = new TimeIntervalCollection(); - result.addInterval(new TimeInterval({ - start : beginDate, - stop : endDate - })); - } else if (defined(beginDate)) { - result = new TimeIntervalCollection(); - result.addInterval(new TimeInterval({ - start : beginDate, - stop : Iso8601.MAXIMUM_VALUE - })); - } else if (defined(endDate)) { - result = new TimeIntervalCollection(); - result.addInterval(new TimeInterval({ - start : Iso8601.MINIMUM_VALUE, - stop : endDate - })); } - return result; - } - - function createDefaultBillboard() { - var billboard = new BillboardGraphics(); - billboard.width = BILLBOARD_SIZE; - billboard.height = BILLBOARD_SIZE; - billboard.scaleByDistance = new NearFarScalar(BILLBOARD_NEAR_DISTANCE, BILLBOARD_NEAR_RATIO, BILLBOARD_FAR_DISTANCE, BILLBOARD_FAR_RATIO); - billboard.pixelOffsetScaleByDistance = new NearFarScalar(BILLBOARD_NEAR_DISTANCE, BILLBOARD_NEAR_RATIO, BILLBOARD_FAR_DISTANCE, BILLBOARD_FAR_RATIO); - return billboard; - } + var temp = primitive._va; + primitive._va = primitive._vaSwap; + primitive._vaSwap = temp; - function createDefaultPolygon() { - var polygon = new PolygonGraphics(); - polygon.outline = true; - polygon.outlineColor = Color.WHITE; - return polygon; + primitive._batchedIndices = newBatchedIndices; } - function createDefaultLabel() { - var label = new LabelGraphics(); - label.translucencyByDistance = new NearFarScalar(3000000, 1.0, 5000000, 0.0); - label.pixelOffset = new Cartesian2(17, 0); - label.horizontalOrigin = HorizontalOrigin.LEFT; - label.font = '16px sans-serif'; - label.style = LabelStyle.FILL_AND_OUTLINE; - return label; + function compareColors(a, b) { + return b.color.toRgba() - a.color.toRgba(); } - function getIconHref(iconNode, dataSource, sourceUri, uriResolver, canRefresh, query) { - var href = queryStringValue(iconNode, 'href', namespaces.kml); - if (!defined(href) || (href.length === 0)) { - return undefined; + // PERFORMANCE_IDEA: For WebGL 2, we can use copyBufferSubData for buffer-to-buffer copies. + // PERFORMANCE_IDEA: Not supported, but we could use glMultiDrawElements here. + function rebatchCommands(primitive, context) { + if (!primitive._batchDirty) { + return false; } - if (href.indexOf('root://icons/palette-') === 0) { - var palette = href.charAt(21); + var batchedIndices = primitive._batchedIndices; + var length = batchedIndices.length; - // Get the icon number - var x = defaultValue(queryNumericValue(iconNode, 'x', namespaces.gx), 0); - var y = defaultValue(queryNumericValue(iconNode, 'y', namespaces.gx), 0); - x = Math.min(x / 32, 7); - y = 7 - Math.min(y / 32, 7); - var iconNum = (8 * y) + x; + var needToRebatch = false; + var colorCounts = {}; - href = 'https://maps.google.com/mapfiles/kml/pal' + palette + '/icon' + iconNum + '.png'; + for (var i = 0; i < length; ++i) { + var color = batchedIndices[i].color; + var rgba = color.toRgba(); + if (defined(colorCounts[rgba])) { + needToRebatch = true; + break; + } else { + colorCounts[rgba] = true; + } } - href = resolveHref(href, dataSource._proxy, sourceUri, uriResolver, query); + if (!needToRebatch) { + primitive._batchDirty = false; + return false; + } - if (canRefresh) { - var refreshMode = queryStringValue(iconNode, 'refreshMode', namespaces.kml); - var viewRefreshMode = queryStringValue(iconNode, 'viewRefreshMode', namespaces.kml); - if (refreshMode === 'onInterval' || refreshMode === 'onExpire') { - oneTimeWarning('kml-refreshMode-' + refreshMode, 'KML - Unsupported Icon refreshMode: ' + refreshMode); - } else if (viewRefreshMode === 'onStop' || viewRefreshMode === 'onRegion') { - oneTimeWarning('kml-refreshMode-' + viewRefreshMode, 'KML - Unsupported Icon viewRefreshMode: ' + viewRefreshMode); - } + if (needToRebatch && !primitive.forceRebatch && primitive._framesSinceLastRebatch < 120) { + ++primitive._framesSinceLastRebatch; + return; + } - var viewBoundScale = defaultValue(queryStringValue(iconNode, 'viewBoundScale', namespaces.kml), 1.0); - var defaultViewFormat = (viewRefreshMode === 'onStop') ? 'BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]' : ''; - var viewFormat = defaultValue(queryStringValue(iconNode, 'viewFormat', namespaces.kml), defaultViewFormat); - var httpQuery = queryStringValue(iconNode, 'httpQuery', namespaces.kml); - var queryString = makeQueryString(viewFormat, httpQuery); + batchedIndices.sort(compareColors); - var icon = joinUrls(href, queryString, false); - return processNetworkLinkQueryString(dataSource._camera, dataSource._canvas, icon, viewBoundScale, dataSource._lastCameraView.bbox); + if (context.webgl2) { + rebatchGPU(primitive, batchedIndices); + } else { + rebatchCPU(primitive, batchedIndices); } - return href; + primitive._framesSinceLastRebatch = 0; + primitive._batchDirty = false; + primitive._pickCommandsDirty = true; + primitive._wireframeDirty = true; + return true; } - function processBillboardIcon(dataSource, node, targetEntity, sourceUri, uriResolver, query) { - var scale = queryNumericValue(node, 'scale', namespaces.kml); - var heading = queryNumericValue(node, 'heading', namespaces.kml); - var color = queryColorValue(node, 'color', namespaces.kml); + function createColorCommands(primitive, context) { + var needsRebatch = rebatchCommands(primitive, context); - var iconNode = queryFirstNode(node, 'Icon', namespaces.kml); - var icon = getIconHref(iconNode, dataSource, sourceUri, uriResolver, false, query); + var commands = primitive._commands; + var batchedIndices = primitive._batchedIndices; + var length = batchedIndices.length; + var commandsLength = length * 3; - // If icon tags are present but blank, we do not want to show an icon - if (defined(iconNode) && !defined(icon)) { - icon = false; + if (defined(commands) && + !needsRebatch && + commands.length === commandsLength) { + return; } - var x = queryNumericValue(iconNode, 'x', namespaces.gx); - var y = queryNumericValue(iconNode, 'y', namespaces.gx); - var w = queryNumericValue(iconNode, 'w', namespaces.gx); - var h = queryNumericValue(iconNode, 'h', namespaces.gx); - - var hotSpotNode = queryFirstNode(node, 'hotSpot', namespaces.kml); - var hotSpotX = queryNumericAttribute(hotSpotNode, 'x'); - var hotSpotY = queryNumericAttribute(hotSpotNode, 'y'); - var hotSpotXUnit = queryStringAttribute(hotSpotNode, 'xunits'); - var hotSpotYUnit = queryStringAttribute(hotSpotNode, 'yunits'); + commands.length = commandsLength; - var billboard = targetEntity.billboard; - if (!defined(billboard)) { - billboard = createDefaultBillboard(); - targetEntity.billboard = billboard; - } + var vertexArray = primitive._va; + var sp = primitive._sp; + var modelMatrix = defaultValue(primitive._modelMatrix, Matrix4.IDENTITY); + var uniformMap = primitive._uniformMap; + var bv = primitive._boundingVolume; - billboard.image = icon; - billboard.scale = scale; - billboard.color = color; + for (var j = 0; j < length; ++j) { + var offset = batchedIndices[j].offset; + var count = batchedIndices[j].count; - if (defined(x) || defined(y) || defined(w) || defined(h)) { - billboard.imageSubRegion = new BoundingRectangle(x, y, w, h); - } + var stencilPreloadCommand = commands[j * 3]; + if (!defined(stencilPreloadCommand)) { + stencilPreloadCommand = commands[j * 3] = new DrawCommand({ + owner : primitive + }); + } - //GE treats a heading of zero as no heading - //You can still point north using a 360 degree angle (or any multiple of 360) - if (defined(heading) && heading !== 0) { - billboard.rotation = CesiumMath.toRadians(-heading); - billboard.alignedAxis = Cartesian3.UNIT_Z; - } + stencilPreloadCommand.vertexArray = vertexArray; + stencilPreloadCommand.modelMatrix = modelMatrix; + stencilPreloadCommand.offset = offset; + stencilPreloadCommand.count = count; + stencilPreloadCommand.renderState = primitive._rsStencilPreloadPass; + stencilPreloadCommand.shaderProgram = sp; + stencilPreloadCommand.uniformMap = uniformMap; + stencilPreloadCommand.boundingVolume = bv; + stencilPreloadCommand.cull = false; + + var stencilDepthCommand = commands[j * 3 + 1]; + if (!defined(stencilDepthCommand)) { + stencilDepthCommand = commands[j * 3 + 1] = new DrawCommand({ + owner : primitive + }); + } - //Hotpot is the KML equivalent of pixel offset - //The hotspot origin is the lower left, but we leave - //our billboard origin at the center and simply - //modify the pixel offset to take this into account - scale = defaultValue(scale, 1.0); + stencilDepthCommand.vertexArray = vertexArray; + stencilDepthCommand.modelMatrix = modelMatrix; + stencilDepthCommand.offset = offset; + stencilDepthCommand.count = count; + stencilDepthCommand.renderState = primitive._rsStencilDepthPass; + stencilDepthCommand.shaderProgram = sp; + stencilDepthCommand.uniformMap = uniformMap; + stencilDepthCommand.boundingVolume = bv; + stencilDepthCommand.cull = false; - var xOffset; - var yOffset; - if (defined(hotSpotX)) { - if (hotSpotXUnit === 'pixels') { - xOffset = -hotSpotX * scale; - } else if (hotSpotXUnit === 'insetPixels') { - xOffset = (hotSpotX - BILLBOARD_SIZE) * scale; - } else if (hotSpotXUnit === 'fraction') { - xOffset = -hotSpotX * BILLBOARD_SIZE * scale; + var colorCommand = commands[j * 3 + 2]; + if (!defined(colorCommand)) { + colorCommand = commands[j * 3 + 2] = new DrawCommand({ + owner : primitive + }); } - xOffset += BILLBOARD_SIZE * 0.5 * scale; + + colorCommand.vertexArray = vertexArray; + colorCommand.modelMatrix = modelMatrix; + colorCommand.offset = offset; + colorCommand.count = count; + colorCommand.renderState = primitive._rsColorPass; + colorCommand.shaderProgram = sp; + colorCommand.uniformMap = uniformMap; + colorCommand.boundingVolume = bv; + colorCommand.cull = false; } - if (defined(hotSpotY)) { - if (hotSpotYUnit === 'pixels') { - yOffset = hotSpotY * scale; - } else if (hotSpotYUnit === 'insetPixels') { - yOffset = (-hotSpotY + BILLBOARD_SIZE) * scale; - } else if (hotSpotYUnit === 'fraction') { - yOffset = hotSpotY * BILLBOARD_SIZE * scale; - } + primitive._commandsDirty = true; + } - yOffset -= BILLBOARD_SIZE * 0.5 * scale; + function createColorCommandsIgnoreShow(primitive, frameState) { + if (primitive.classificationType === ClassificationType.TERRAIN || + !frameState.invertClassification || + (defined(primitive._commandsIgnoreShow) && !primitive._commandsDirty)) { + return; } - if (defined(xOffset) || defined(yOffset)) { - billboard.pixelOffset = new Cartesian2(xOffset, yOffset); - } - } + var commands = primitive._commands; + var commandsIgnoreShow = primitive._commandsIgnoreShow; + var spStencil = primitive._spStencil; - function applyStyle(dataSource, styleNode, targetEntity, sourceUri, uriResolver, query) { - for (var i = 0, len = styleNode.childNodes.length; i < len; i++) { - var node = styleNode.childNodes.item(i); - if (node.localName === 'IconStyle') { - processBillboardIcon(dataSource, node, targetEntity, sourceUri, uriResolver, query); - } else if (node.localName === 'LabelStyle') { - var label = targetEntity.label; - if (!defined(label)) { - label = createDefaultLabel(); - targetEntity.label = label; - } - label.scale = defaultValue(queryNumericValue(node, 'scale', namespaces.kml), label.scale); - label.fillColor = defaultValue(queryColorValue(node, 'color', namespaces.kml), label.fillColor); - label.text = targetEntity.name; - } else if (node.localName === 'LineStyle') { - var polyline = targetEntity.polyline; - if (!defined(polyline)) { - polyline = new PolylineGraphics(); - targetEntity.polyline = polyline; - } - polyline.width = queryNumericValue(node, 'width', namespaces.kml); - polyline.material = queryColorValue(node, 'color', namespaces.kml); - if (defined(queryColorValue(node, 'outerColor', namespaces.gx))) { - oneTimeWarning('kml-gx:outerColor', 'KML - gx:outerColor is not supported in a LineStyle'); - } - if (defined(queryNumericValue(node, 'outerWidth', namespaces.gx))) { - oneTimeWarning('kml-gx:outerWidth', 'KML - gx:outerWidth is not supported in a LineStyle'); - } - if (defined(queryNumericValue(node, 'physicalWidth', namespaces.gx))) { - oneTimeWarning('kml-gx:physicalWidth', 'KML - gx:physicalWidth is not supported in a LineStyle'); - } - if (defined(queryBooleanValue(node, 'labelVisibility', namespaces.gx))) { - oneTimeWarning('kml-gx:labelVisibility', 'KML - gx:labelVisibility is not supported in a LineStyle'); - } - } else if (node.localName === 'PolyStyle') { - var polygon = targetEntity.polygon; - if (!defined(polygon)) { - polygon = createDefaultPolygon(); - targetEntity.polygon = polygon; - } - polygon.material = defaultValue(queryColorValue(node, 'color', namespaces.kml), polygon.material); - polygon.fill = defaultValue(queryBooleanValue(node, 'fill', namespaces.kml), polygon.fill); - polygon.outline = defaultValue(queryBooleanValue(node, 'outline', namespaces.kml), polygon.outline); - } else if (node.localName === 'BalloonStyle') { - var bgColor = defaultValue(parseColorString(queryStringValue(node, 'bgColor', namespaces.kml)), Color.WHITE); - var textColor = defaultValue(parseColorString(queryStringValue(node, 'textColor', namespaces.kml)), Color.BLACK); - var text = queryStringValue(node, 'text', namespaces.kml); + var commandsLength = commands.length; + var length = commandsIgnoreShow.length = commandsLength / 3 * 2; - //This is purely an internal property used in style processing, - //it never ends up on the final entity. - targetEntity.addProperty('balloonStyle'); - targetEntity.balloonStyle = { - bgColor : bgColor, - textColor : textColor, - text : text - }; - } else if (node.localName === 'ListStyle') { - var listItemType = queryStringValue(node, 'listItemType', namespaces.kml); - if (listItemType === 'radioFolder' || listItemType === 'checkOffOnly') { - oneTimeWarning('kml-listStyle-' + listItemType, 'KML - Unsupported ListStyle with listItemType: ' + listItemType); - } - } - } - } + var commandIndex = 0; + for (var j = 0; j < length; j += 2) { + var commandIgnoreShow = commandsIgnoreShow[j] = DrawCommand.shallowClone(commands[commandIndex], commandsIgnoreShow[j]); + commandIgnoreShow.shaderProgram = spStencil; + commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW; - //Processes and merges any inline styles for the provided node into the provided entity. - function computeFinalStyle(entity, dataSource, placeMark, styleCollection, sourceUri, uriResolver, query) { - var result = new Entity(); - var styleEntity; + commandIgnoreShow = commandsIgnoreShow[j + 1] = DrawCommand.shallowClone(commands[commandIndex + 1], commandsIgnoreShow[j + 1]); + commandIgnoreShow.shaderProgram = spStencil; + commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW; - //Google earth seems to always use the last inline Style/StyleMap only - var styleIndex = -1; - var childNodes = placeMark.childNodes; - var length = childNodes.length; - for (var q = 0; q < length; q++) { - var child = childNodes[q]; - if (child.localName === 'Style' || child.localName === 'StyleMap') { - styleIndex = q; - } + commandIndex += 3; } - if (styleIndex !== -1) { - var inlineStyleNode = childNodes[styleIndex]; - if (inlineStyleNode.localName === 'Style') { - applyStyle(dataSource, inlineStyleNode, result, sourceUri, uriResolver, query); - } else { // StyleMap - var pairs = queryChildNodes(inlineStyleNode, 'Pair', namespaces.kml); - for (var p = 0; p < pairs.length; p++) { - var pair = pairs[p]; - var key = queryStringValue(pair, 'key', namespaces.kml); - if (key === 'normal') { - var styleUrl = queryStringValue(pair, 'styleUrl', namespaces.kml); - if (defined(styleUrl)) { - styleEntity = styleCollection.getById(styleUrl); - if (!defined(styleEntity)) { - styleEntity = styleCollection.getById('#' + styleUrl); - } - if (defined(styleEntity)) { - result.merge(styleEntity); - } - } else { - var node = queryFirstNode(pair, 'Style', namespaces.kml); - applyStyle(dataSource, node, result, sourceUri, uriResolver, query); - } - } else { - oneTimeWarning('kml-styleMap-' + key, 'KML - Unsupported StyleMap key: ' + key); - } - } - } + primitive._commandsDirty = false; + } + + function createPickCommands(primitive) { + if (!primitive._pickCommandsDirty) { + return; } - //Google earth seems to always use the first external style only. - var externalStyle = queryStringValue(placeMark, 'styleUrl', namespaces.kml); - if (defined(externalStyle)) { - var id = externalStyle; - if (externalStyle[0] !== '#' && externalStyle.indexOf('#') !== -1) { - var tokens = externalStyle.split('#'); - var uri = tokens[0]; - if (defined(sourceUri)) { - uri = getAbsoluteUri(uri, getAbsoluteUri(sourceUri)); - } - id = uri + '#' + tokens[1]; + var length = primitive._indexOffsets.length; + var pickCommands = primitive._pickCommands; + pickCommands.length = length * 3; + + var vertexArray = primitive._va; + var spStencil = primitive._spStencil; + var spPick = primitive._spPick; + var modelMatrix = defaultValue(primitive._modelMatrix, Matrix4.IDENTITY); + var uniformMap = primitive._pickUniformMap; + + for (var j = 0; j < length; ++j) { + var offset = primitive._indexOffsets[j]; + var count = primitive._indexCounts[j]; + var bv = defined(primitive._boundingVolumes) ? primitive._boundingVolumes[j] : primitive.boundingVolume; + + var stencilPreloadCommand = pickCommands[j * 3]; + if (!defined(stencilPreloadCommand)) { + stencilPreloadCommand = pickCommands[j * 3] = new DrawCommand({ + owner : primitive + }); } - styleEntity = styleCollection.getById(id); - if (!defined(styleEntity)) { - styleEntity = styleCollection.getById('#' + id); + stencilPreloadCommand.vertexArray = vertexArray; + stencilPreloadCommand.modelMatrix = modelMatrix; + stencilPreloadCommand.offset = offset; + stencilPreloadCommand.count = count; + stencilPreloadCommand.renderState = primitive._rsStencilPreloadPass; + stencilPreloadCommand.shaderProgram = spStencil; + stencilPreloadCommand.uniformMap = uniformMap; + stencilPreloadCommand.boundingVolume = bv; + + var stencilDepthCommand = pickCommands[j * 3 + 1]; + if (!defined(stencilDepthCommand)) { + stencilDepthCommand = pickCommands[j * 3 + 1] = new DrawCommand({ + owner : primitive + }); } - if (defined(styleEntity)) { - result.merge(styleEntity); + + stencilDepthCommand.vertexArray = vertexArray; + stencilDepthCommand.modelMatrix = modelMatrix; + stencilDepthCommand.offset = offset; + stencilDepthCommand.count = count; + stencilDepthCommand.renderState = primitive._rsStencilDepthPass; + stencilDepthCommand.shaderProgram = spStencil; + stencilDepthCommand.uniformMap = uniformMap; + stencilDepthCommand.boundingVolume = bv; + + var colorCommand = pickCommands[j * 3 + 2]; + if (!defined(colorCommand)) { + colorCommand = pickCommands[j * 3 + 2] = new DrawCommand({ + owner : primitive + }); } - } - return result; - } + colorCommand.vertexArray = vertexArray; + colorCommand.modelMatrix = modelMatrix; + colorCommand.offset = offset; + colorCommand.count = count; + colorCommand.renderState = primitive._rsPickPass; + colorCommand.shaderProgram = spPick; + colorCommand.uniformMap = uniformMap; + colorCommand.boundingVolume = bv; + } - //Asynchronously processes an external style file. - function processExternalStyles(dataSource, uri, styleCollection, query) { - return loadXML(proxyUrl(uri, dataSource._proxy, query)).then(function(styleKml) { - return processStyles(dataSource, styleKml, styleCollection, uri, true); - }); + primitive._pickCommandsDirty = false; } - //Processes all shared and external styles and stores - //their id into the provided styleCollection. - //Returns an array of promises that will resolve when - //each style is loaded. - function processStyles(dataSource, kml, styleCollection, sourceUri, isExternal, uriResolver, query) { - var i; - var id; - var styleEntity; - - var node; - var styleNodes = queryNodes(kml, 'Style', namespaces.kml); - if (defined(styleNodes)) { - var styleNodesLength = styleNodes.length; - for (i = 0; i < styleNodesLength; i++) { - node = styleNodes[i]; - id = queryStringAttribute(node, 'id'); - if (defined(id)) { - id = '#' + id; - if (isExternal && defined(sourceUri)) { - id = sourceUri + id; - } - if (!defined(styleCollection.getById(id))) { - styleEntity = new Entity({ - id : id - }); - styleCollection.add(styleEntity); - applyStyle(dataSource, node, styleEntity, sourceUri, uriResolver, query); - } - } - } + /** + * Creates features for each mesh and places it at the batch id index of features. + * + * @param {Vector3DTileContent} content The vector tile content. + * @param {Cesium3DTileFeature[]} features An array of features where the polygon features will be placed. + */ + Vector3DTilePrimitive.prototype.createFeatures = function(content, features) { + var batchIds = this._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; + features[batchId] = new Cesium3DTileFeature(content, batchId); } + }; - var styleMaps = queryNodes(kml, 'StyleMap', namespaces.kml); - if (defined(styleMaps)) { - var styleMapsLength = styleMaps.length; - for (i = 0; i < styleMapsLength; i++) { - var styleMap = styleMaps[i]; - id = queryStringAttribute(styleMap, 'id'); - if (defined(id)) { - var pairs = queryChildNodes(styleMap, 'Pair', namespaces.kml); - for (var p = 0; p < pairs.length; p++) { - var pair = pairs[p]; - var key = queryStringValue(pair, 'key', namespaces.kml); - if (key === 'normal') { - id = '#' + id; - if (isExternal && defined(sourceUri)) { - id = sourceUri + id; - } - if (!defined(styleCollection.getById(id))) { - styleEntity = styleCollection.getOrCreateEntity(id); + /** + * Colors the entire tile when enabled is true. The resulting color will be (mesh batch table color * color). + * + * @param {Boolean} enabled Whether to enable debug coloring. + * @param {Color} color The debug color. + */ + Vector3DTilePrimitive.prototype.applyDebugSettings = function(enabled, color) { + this._highlightColor = enabled ? color : this._constantColor; + }; - var styleUrl = queryStringValue(pair, 'styleUrl', namespaces.kml); - if (defined(styleUrl)) { - if (styleUrl[0] !== '#') { - styleUrl = '#' + styleUrl; - } + function clearStyle(polygons, features) { + polygons._updatingAllCommands = true; - if (isExternal && defined(sourceUri)) { - styleUrl = sourceUri + styleUrl; - } - var base = styleCollection.getById(styleUrl); + var batchIds = polygons._batchIds; + var length = batchIds.length; + var i; - if (defined(base)) { - styleEntity.merge(base); - } - } else { - node = queryFirstNode(pair, 'Style', namespaces.kml); - applyStyle(dataSource, node, styleEntity, sourceUri, uriResolver, query); - } - } - } else { - oneTimeWarning('kml-styleMap-' + key, 'KML - Unsupported StyleMap key: ' + key); - } - } - } - } + for (i = 0; i < length; ++i) { + var batchId = batchIds[i]; + var feature = features[batchId]; + + feature.show = true; + feature.color = Color.WHITE; } - var externalStyleHash = {}; - var promises = []; - var styleUrlNodes = kml.getElementsByTagName('styleUrl'); - var styleUrlNodesLength = styleUrlNodes.length; - for (i = 0; i < styleUrlNodesLength; i++) { - var styleReference = styleUrlNodes[i].textContent; - if (styleReference[0] !== '#') { - //According to the spec, all local styles should start with a # - //and everything else is an external style that has a # seperating - //the URL of the document and the style. However, Google Earth - //also accepts styleUrls without a # as meaning a local style. - var tokens = styleReference.split('#'); - if (tokens.length === 2) { - var uri = tokens[0]; - if (!defined(externalStyleHash[uri])) { - if (defined(sourceUri)) { - uri = getAbsoluteUri(uri, getAbsoluteUri(sourceUri)); - } - promises.push(processExternalStyles(dataSource, uri, styleCollection, query)); - } - } - } + var batchedIndices = polygons._batchedIndices; + length = batchedIndices.length; + + for (i = 0; i < length; ++i) { + batchedIndices[i].color = Color.clone(Color.WHITE); } - return promises; + polygons._updatingAllCommands = false; + polygons._batchDirty = true; } - function createDropLine(entityCollection, entity, styleEntity) { - var entityPosition = new ReferenceProperty(entityCollection, entity.id, ['position']); - var surfacePosition = new ScaledPositionProperty(entity.position); - entity.polyline = defined(styleEntity.polyline) ? styleEntity.polyline.clone() : new PolylineGraphics(); - entity.polyline.positions = new PositionPropertyArray([entityPosition, surfacePosition]); - } + var scratchColor = new Color(); - function heightReferenceFromAltitudeMode(altitudeMode, gxAltitudeMode) { - if (!defined(altitudeMode) && !defined(gxAltitudeMode) || altitudeMode === 'clampToGround') { - return HeightReference.CLAMP_TO_GROUND; - } + var DEFAULT_COLOR_VALUE = Color.WHITE; + var DEFAULT_SHOW_VALUE = true; - if (altitudeMode === 'relativeToGround') { - return HeightReference.RELATIVE_TO_GROUND; + var complexExpressionReg = /\$/; + + /** + * Apply a style to the content. + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileStyle} style The style. + * @param {Cesium3DTileFeature[]} features The array of features. + */ + Vector3DTilePrimitive.prototype.applyStyle = function(frameState, style, features) { + if (!defined(style)) { + clearStyle(this, features); + return; } - if (altitudeMode === 'absolute') { - return HeightReference.NONE; + var colorExpression = style.color; + var isSimpleStyle = colorExpression instanceof Expression && !complexExpressionReg.test(colorExpression.expression); + this._updatingAllCommands = isSimpleStyle; + + var batchIds = this._batchIds; + var length = batchIds.length; + var i; + + for (i = 0; i < length; ++i) { + var batchId = batchIds[i]; + var feature = features[batchId]; + + feature.color = defined(style.color) ? style.color.evaluateColor(frameState, feature, scratchColor) : DEFAULT_COLOR_VALUE; + feature.show = defined(style.show) ? style.show.evaluate(frameState, feature) : DEFAULT_SHOW_VALUE; } - if (gxAltitudeMode === 'clampToSeaFloor') { - oneTimeWarning('kml-gx:altitudeMode-clampToSeaFloor', 'KML - <gx:altitudeMode>:clampToSeaFloor is currently not supported, using <kml:altitudeMode>:clampToGround.'); - return HeightReference.CLAMP_TO_GROUND; + if (isSimpleStyle) { + var batchedIndices = this._batchedIndices; + length = batchedIndices.length; + + for (i = 0; i < length; ++i) { + batchedIndices[i].color = Color.clone(Color.WHITE); + } + + this._updatingAllCommands = false; + this._batchDirty = true; } + }; - if (gxAltitudeMode === 'relativeToSeaFloor') { - oneTimeWarning('kml-gx:altitudeMode-relativeToSeaFloor', 'KML - <gx:altitudeMode>:relativeToSeaFloor is currently not supported, using <kml:altitudeMode>:relativeToGround.'); - return HeightReference.RELATIVE_TO_GROUND; + /** + * Call when updating the color of a mesh with batchId changes color. The meshes will need to be re-batched + * on the next update. + * + * @param {Number} batchId The batch id of the meshes whose color has changed. + * @param {Color} color The new polygon color. + */ + Vector3DTilePrimitive.prototype.updateCommands = function(batchId, color) { + if (this._updatingAllCommands) { + return; } - if (defined(altitudeMode)) { - oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown <kml:altitudeMode>:' + altitudeMode + ', using <kml:altitudeMode>:CLAMP_TO_GROUND.'); - } else { - oneTimeWarning('kml-gx:altitudeMode-unknown', 'KML - Unknown <gx:altitudeMode>:' + gxAltitudeMode + ', using <kml:altitudeMode>:CLAMP_TO_GROUND.'); + var batchIdLookUp = this._batchIdLookUp; + var index = batchIdLookUp[batchId]; + if (!defined(index)) { + return; } - // Clamp to ground is the default - return HeightReference.CLAMP_TO_GROUND; - } + var indexOffsets = this._indexOffsets; + var indexCounts = this._indexCounts; - function createPositionPropertyFromAltitudeMode(property, altitudeMode, gxAltitudeMode) { - if (gxAltitudeMode === 'relativeToSeaFloor' || altitudeMode === 'absolute' || altitudeMode === 'relativeToGround') { - //Just return the ellipsoid referenced property until we support MSL - return property; - } + var offset = indexOffsets[index]; + var count = indexCounts[index]; - if ((defined(altitudeMode) && altitudeMode !== 'clampToGround') || // - (defined(gxAltitudeMode) && gxAltitudeMode !== 'clampToSeaFloor')) { - oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + defaultValue(altitudeMode, gxAltitudeMode)); - } + var batchedIndices = this._batchedIndices; + var length = batchedIndices.length; - // Clamp to ground is the default - return new ScaledPositionProperty(property); - } + var i; + for (i = 0; i < length; ++i) { + var batchedOffset = batchedIndices[i].offset; + var batchedCount = batchedIndices[i].count; - function createPositionPropertyArrayFromAltitudeMode(properties, altitudeMode, gxAltitudeMode) { - if (!defined(properties)) { - return undefined; + if (offset >= batchedOffset && offset < batchedOffset + batchedCount) { + break; + } } - if (gxAltitudeMode === 'relativeToSeaFloor' || altitudeMode === 'absolute' || altitudeMode === 'relativeToGround') { - //Just return the ellipsoid referenced property until we support MSL - return properties; - } + batchedIndices.push(new Vector3DTileBatch({ + color : Color.clone(color), + offset : offset, + count : count, + batchIds : [batchId] + })); - if ((defined(altitudeMode) && altitudeMode !== 'clampToGround') || // - (defined(gxAltitudeMode) && gxAltitudeMode !== 'clampToSeaFloor')) { - oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + defaultValue(altitudeMode, gxAltitudeMode)); - } + var startIds = []; + var endIds = []; - // Clamp to ground is the default - var propertiesLength = properties.length; - for (var i = 0; i < propertiesLength; i++) { - var property = properties[i]; - Ellipsoid.WGS84.scaleToGeodeticSurface(property, property); + var batchIds = batchedIndices[i].batchIds; + var batchIdsLength = batchIds.length; + + for (var j = 0; j < batchIdsLength; ++j) { + var id = batchIds[j]; + if (id === batchId) { + continue; + } + + var offsetIndex = batchIdLookUp[id]; + if (indexOffsets[offsetIndex] < offset) { + startIds.push(id); + } else { + endIds.push(id); + } } - return properties; - } - function processPositionGraphics(dataSource, entity, styleEntity, heightReference) { - var label = entity.label; - if (!defined(label)) { - label = defined(styleEntity.label) ? styleEntity.label.clone() : createDefaultLabel(); - entity.label = label; + if (endIds.length !== 0) { + batchedIndices.push(new Vector3DTileBatch({ + color : Color.clone(batchedIndices[i].color), + offset : offset + count, + count : batchedIndices[i].offset + batchedIndices[i].count - (offset + count), + batchIds : endIds + })); } - label.text = entity.name; - var billboard = entity.billboard; - if (!defined(billboard)) { - billboard = defined(styleEntity.billboard) ? styleEntity.billboard.clone() : createDefaultBillboard(); - entity.billboard = billboard; + if (startIds.length !== 0) { + batchedIndices[i].count = offset - batchedIndices[i].offset; + batchedIndices[i].batchIds = startIds; + } else { + batchedIndices.splice(i, 1); } - if (!defined(billboard.image)) { - billboard.image = dataSource._pinBuilder.fromColor(Color.YELLOW, 64); + this._batchDirty = true; + }; - // If there were empty <Icon> tags in the KML, then billboard.image was set to false above - // However, in this case, the false value would have been converted to a property afterwards - // Thus, we check if billboard.image is defined with value of false - } else if (!billboard.image.getValue()) { - billboard.image = undefined; + function queueCommands(frameState, pass, commands, commandsIgnoreShow) { + var commandList = frameState.commandList; + var commandLength = commands.length; + var i; + var command; + for (i = 0; i < commandLength; ++i) { + command = commands[i]; + command.pass = pass; + commandList.push(command); } - var scale = 1.0; - if (defined(billboard.scale)) { - scale = billboard.scale.getValue(); - if (scale !== 0) { - label.pixelOffset = new Cartesian2((scale * 16) + 1, 0); - } else { - //Minor tweaks to better match Google Earth. - label.pixelOffset = undefined; - label.horizontalOrigin = undefined; - } + if (!frameState.invertClassification || !defined(commandsIgnoreShow)) { + return; } - if (defined(heightReference) && dataSource._clampToGround) { - billboard.heightReference = heightReference; - label.heightReference = heightReference; + commandLength = commandsIgnoreShow.length; + for (i = 0; i < commandLength; ++i) { + command = commandsIgnoreShow[i]; + command.pass = pass; + commandList.push(command); } } - function processPathGraphics(dataSource, entity, styleEntity) { - var path = entity.path; - if (!defined(path)) { - path = new PathGraphics(); - path.leadTime = 0; - entity.path = path; + function queueWireframeCommands(frameState, commands) { + var commandList = frameState.commandList; + var commandLength = commands.length; + for (var i = 0; i < commandLength; i += 3) { + var command = commands[i + 2]; + command.pass = Pass.OPAQUE; + commandList.push(command); } + } - var polyline = styleEntity.polyline; - if (defined(polyline)) { - path.material = polyline.material; - path.width = polyline.width; + function updateWireframe(primitive) { + var earlyExit = primitive.debugWireframe === primitive._debugWireframe; + earlyExit = earlyExit && !(primitive.debugWireframe && primitive._wireframeDirty); + if (earlyExit) { + return; } - } - function processPoint(dataSource, entityCollection, geometryNode, entity, styleEntity) { - var coordinatesString = queryStringValue(geometryNode, 'coordinates', namespaces.kml); - var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); - var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); - var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); + if (!defined(primitive._rsWireframe)) { + primitive._rsWireframe = RenderState.fromCache({}); + } - var position = readCoordinate(coordinatesString); + var rs; + var type; - entity.position = position; - processPositionGraphics(dataSource, entity, styleEntity, heightReferenceFromAltitudeMode(altitudeMode, gxAltitudeMode)); + if (primitive.debugWireframe) { + rs = primitive._rsWireframe; + type = PrimitiveType.LINES; + } else { + rs = primitive._rsColorPass; + type = PrimitiveType.TRIANGLES; + } - if (extrude && isExtrudable(altitudeMode, gxAltitudeMode)) { - createDropLine(entityCollection, entity, styleEntity); + var commands = primitive._commands; + var commandLength = commands.length; + for (var i = 0; i < commandLength; i += 3) { + var command = commands[i + 2]; + command.renderState = rs; + command.primitiveType = type; } - return true; + primitive._debugWireframe = primitive.debugWireframe; + primitive._wireframeDirty = false; } - function processLineStringOrLinearRing(dataSource, entityCollection, geometryNode, entity, styleEntity) { - var coordinatesNode = queryFirstNode(geometryNode, 'coordinates', namespaces.kml); - var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); - var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); - var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); - var tessellate = queryBooleanValue(geometryNode, 'tessellate', namespaces.kml); - var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); + /** + * Updates the batches and queues the commands for rendering. + * + * @param {FrameState} frameState The current frame state. + */ + Vector3DTilePrimitive.prototype.update = function(frameState) { + var context = frameState.context; - if (defined(queryNumericValue(geometryNode, 'drawOrder', namespaces.gx))) { - oneTimeWarning('kml-gx:drawOrder', 'KML - gx:drawOrder is not supported in LineStrings'); - } + createVertexArray(this, context); + createShaders(this, context); + createRenderStates(this); + createUniformMap(this, context); - var coordinates = readCoordinates(coordinatesNode); - var polyline = styleEntity.polyline; - if (canExtrude && extrude) { - var wall = new WallGraphics(); - entity.wall = wall; - wall.positions = coordinates; - var polygon = styleEntity.polygon; + var pass; + switch (this.classificationType) { + case ClassificationType.TERRAIN: + pass = Pass.TERRAIN_CLASSIFICATION; + break; + case ClassificationType.CESIUM_3D_TILE: + pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; + break; + default: + pass = Pass.CLASSIFICATION; + } - if (defined(polygon)) { - wall.fill = polygon.fill; - wall.material = polygon.material; - } + var passes = frameState.passes; + if (passes.render) { + createColorCommands(this, context); + createColorCommandsIgnoreShow(this, frameState); + updateWireframe(this); - //Always outline walls so they show up in 2D. - wall.outline = true; - if (defined(polyline)) { - wall.outlineColor = defined(polyline.material) ? polyline.material.color : Color.WHITE; - wall.outlineWidth = polyline.width; - } else if (defined(polygon)) { - wall.outlineColor = defined(polygon.material) ? polygon.material.color : Color.WHITE; - } - } else if (dataSource._clampToGround && !canExtrude && tessellate) { - var corridor = new CorridorGraphics(); - entity.corridor = corridor; - corridor.positions = coordinates; - if (defined(polyline)) { - corridor.material = defined(polyline.material) ? polyline.material.color.getValue(Iso8601.MINIMUM_VALUE) : Color.WHITE; - corridor.width = defaultValue(polyline.width, 1.0); + if (this._debugWireframe) { + queueWireframeCommands(frameState, this._commands); } else { - corridor.material = Color.WHITE; - corridor.width = 1.0; - } - } else { - polyline = defined(polyline) ? polyline.clone() : new PolylineGraphics(); - entity.polyline = polyline; - polyline.positions = createPositionPropertyArrayFromAltitudeMode(coordinates, altitudeMode, gxAltitudeMode); - if (!tessellate || canExtrude) { - polyline.followSurface = false; + queueCommands(frameState, pass, this._commands, this._commandsIgnoreShow); } } - return true; - } - - function processPolygon(dataSource, entityCollection, geometryNode, entity, styleEntity) { - var outerBoundaryIsNode = queryFirstNode(geometryNode, 'outerBoundaryIs', namespaces.kml); - var linearRingNode = queryFirstNode(outerBoundaryIsNode, 'LinearRing', namespaces.kml); - var coordinatesNode = queryFirstNode(linearRingNode, 'coordinates', namespaces.kml); - var coordinates = readCoordinates(coordinatesNode); - var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); - var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); - var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); - var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); + if (passes.pick) { + createPickCommands(this); + queueCommands(frameState, pass, this._pickCommands); + } + }; - var polygon = defined(styleEntity.polygon) ? styleEntity.polygon.clone() : createDefaultPolygon(); + /** + * Returns true if this object was destroyed; otherwise, false. + * <p> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + */ + Vector3DTilePrimitive.prototype.isDestroyed = function() { + return false; + }; - var polyline = styleEntity.polyline; - if (defined(polyline)) { - polygon.outlineColor = defined(polyline.material) ? polyline.material.color : Color.WHITE; - polygon.outlineWidth = polyline.width; - } - entity.polygon = polygon; + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + Vector3DTilePrimitive.prototype.destroy = function() { + this._va = this._va && this._va.destroy(); + this._sp = this._sp && this._sp.destroy(); + this._spPick = this._spPick && this._spPick.destroy(); + this._vaSwap = this._vaSwap && this._vaSwap.destroy(); + return destroyObject(this); + }; - if (canExtrude) { - polygon.perPositionHeight = true; - polygon.extrudedHeight = extrude ? 0 : undefined; - } else if (!dataSource._clampToGround) { - polygon.height = 0; - } + return Vector3DTilePrimitive; +}); - if (defined(coordinates)) { - var hierarchy = new PolygonHierarchy(coordinates); - var innerBoundaryIsNodes = queryChildNodes(geometryNode, 'innerBoundaryIs', namespaces.kml); - for (var j = 0; j < innerBoundaryIsNodes.length; j++) { - linearRingNode = queryChildNodes(innerBoundaryIsNodes[j], 'LinearRing', namespaces.kml); - for (var k = 0; k < linearRingNode.length; k++) { - coordinatesNode = queryFirstNode(linearRingNode[k], 'coordinates', namespaces.kml); - coordinates = readCoordinates(coordinatesNode); - if (defined(coordinates)) { - hierarchy.holes.push(new PolygonHierarchy(coordinates)); - } - } - } - polygon.hierarchy = hierarchy; - } +define('Scene/ClassificationModel',[ + '../Core/arraySlice', + '../Core/BoundingSphere', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/Color', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/FeatureDetection', + '../Core/IndexDatatype', + '../Core/Matrix4', + '../Core/PrimitiveType', + '../Core/Quaternion', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/Transforms', + '../Core/WebGLConstants', + '../ThirdParty/GltfPipeline/ForEach', + '../ThirdParty/GltfPipeline/getAccessorByteStride', + '../ThirdParty/GltfPipeline/numberOfComponentsForType', + '../ThirdParty/GltfPipeline/parseBinaryGltf', + '../ThirdParty/when', + './Axis', + './ClassificationType', + './ModelLoadResources', + './ModelUtility', + './SceneMode', + './Vector3DTileBatch', + './Vector3DTilePrimitive' + ], function( + arraySlice, + BoundingSphere, + Cartesian3, + Cartesian4, + Cartographic, + Color, + combine, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + FeatureDetection, + IndexDatatype, + Matrix4, + PrimitiveType, + Quaternion, + Resource, + RuntimeError, + Transforms, + WebGLConstants, + ForEach, + getAccessorByteStride, + numberOfComponentsForType, + parseBinaryGltf, + when, + Axis, + ClassificationType, + ModelLoadResources, + ModelUtility, + SceneMode, + Vector3DTileBatch, + Vector3DTilePrimitive) { + 'use strict'; - return true; + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; } - function processTrack(dataSource, entityCollection, geometryNode, entity, styleEntity) { - var altitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.kml); - var gxAltitudeMode = queryStringValue(geometryNode, 'altitudeMode', namespaces.gx); - var coordNodes = queryChildNodes(geometryNode, 'coord', namespaces.gx); - var angleNodes = queryChildNodes(geometryNode, 'angles', namespaces.gx); - var timeNodes = queryChildNodes(geometryNode, 'when', namespaces.kml); - var extrude = queryBooleanValue(geometryNode, 'extrude', namespaces.kml); - var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); + var boundingSphereCartesian3Scratch = new Cartesian3(); - if (angleNodes.length > 0) { - oneTimeWarning('kml-gx:angles', 'KML - gx:angles are not supported in gx:Tracks'); - } + var ModelState = { + NEEDS_LOAD : 0, + LOADING : 1, + LOADED : 2, + FAILED : 3 + }; - var length = Math.min(coordNodes.length, timeNodes.length); - var coordinates = []; - var times = []; - for (var i = 0; i < length; i++) { - var position = readCoordinate(coordNodes[i].textContent); - coordinates.push(position); - times.push(JulianDate.fromIso8601(timeNodes[i].textContent)); - } - var property = new SampledPositionProperty(); - property.addSamples(times, coordinates); - entity.position = property; - processPositionGraphics(dataSource, entity, styleEntity, heightReferenceFromAltitudeMode(altitudeMode, gxAltitudeMode)); - processPathGraphics(dataSource, entity, styleEntity); + /////////////////////////////////////////////////////////////////////////// - entity.availability = new TimeIntervalCollection(); + /** + * A 3D model for classifying other 3D assets based on glTF, the runtime asset format for WebGL, OpenGL ES, and OpenGL. + * This is a special case when a model of a 3D tileset becomes a classifier when setting {@link Cesium3DTileset#classificationType}. + * + * @alias ClassificationModel + * @constructor + * + * @private + * + * @param {Object} [options] Object with the following properties: + * @param {Object|ArrayBuffer|Uint8Array} options.gltf The object for the glTF JSON or an arraybuffer of Binary glTF defined by the KHR_binary_glTF extension. + * @param {Resource|String} [options.basePath=''] The base path that paths in the glTF JSON are relative to. + * @param {Boolean} [options.show=true] Determines if the model primitive will be shown. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. + * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. + * @param {ClassificationType} [options.classificationType] What this model will classify. + * + * @exception {DeveloperError} bgltf is not a valid Binary glTF file. + * @exception {DeveloperError} Only glTF Binary version 1 is supported. + * @exception {RuntimeError} Only binary glTF is supported. + * @exception {RuntimeError} Only one node is supported for classification and it must have a mesh. + * @exception {RuntimeError} Only one mesh is supported when using b3dm for classification. + * @exception {RuntimeError} Only one primitive per mesh is supported when using b3dm for classification. + * @exception {RuntimeError} The mesh must have a position attribute. + * @exception {RuntimeError} The mesh must have a batch id attribute. + */ + function ClassificationModel(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (timeNodes.length > 0) { - entity.availability.addInterval(new TimeInterval({ - start : times[0], - stop : times[times.length - 1] - })); + var gltf = options.gltf; + if (gltf instanceof ArrayBuffer) { + gltf = new Uint8Array(gltf); } - if (canExtrude && extrude) { - createDropLine(entityCollection, entity, styleEntity); + if (gltf instanceof Uint8Array) { + // Binary glTF + gltf = parseBinaryGltf(gltf); + } else { + throw new RuntimeError('Only binary glTF is supported as a classifier.'); } - return true; - } + var gltfNodes = gltf.nodes; + var gltfMeshes = gltf.meshes; - function addToMultiTrack(times, positions, composite, availability, dropShowProperty, extrude, altitudeMode, gxAltitudeMode, includeEndPoints) { - var start = times[0]; - var stop = times[times.length - 1]; + var gltfNode = gltfNodes[0]; + var meshId = gltfNode.mesh; + if (gltfNodes.length !== 1 || !defined(meshId)) { + throw new RuntimeError('Only one node is supported for classification and it must have a mesh.'); + } - var data = new SampledPositionProperty(); - data.addSamples(times, positions); + if (gltfMeshes.length !== 1) { + throw new RuntimeError('Only one mesh is supported when using b3dm for classification.'); + } - composite.intervals.addInterval(new TimeInterval({ - start : start, - stop : stop, - isStartIncluded : includeEndPoints, - isStopIncluded : includeEndPoints, - data : createPositionPropertyFromAltitudeMode(data, altitudeMode, gxAltitudeMode) - })); - availability.addInterval(new TimeInterval({ - start : start, - stop : stop, - isStartIncluded : includeEndPoints, - isStopIncluded : includeEndPoints - })); - dropShowProperty.intervals.addInterval(new TimeInterval({ - start : start, - stop : stop, - isStartIncluded : includeEndPoints, - isStopIncluded : includeEndPoints, - data : extrude - })); - } + var gltfPrimitives = gltfMeshes[0].primitives; + if (gltfPrimitives.length !== 1) { + throw new RuntimeError('Only one primitive per mesh is supported when using b3dm for classification.'); + } - function processMultiTrack(dataSource, entityCollection, geometryNode, entity, styleEntity) { - // Multitrack options do not work in GE as detailed in the spec, - // rather than altitudeMode being at the MultiTrack level, - // GE just defers all settings to the underlying track. + var gltfPositionAttribute = gltfPrimitives[0].attributes.POSITION; + if (!defined(gltfPositionAttribute)) { + throw new RuntimeError('The mesh must have a position attribute.'); + } - var interpolate = queryBooleanValue(geometryNode, 'interpolate', namespaces.gx); - var trackNodes = queryChildNodes(geometryNode, 'Track', namespaces.gx); + var gltfBatchIdAttribute = gltfPrimitives[0].attributes._BATCHID; + if (!defined(gltfBatchIdAttribute)) { + throw new RuntimeError('The mesh must have a batch id attribute.'); + } - var times; - var lastStop; - var lastStopPosition; - var needDropLine = false; - var dropShowProperty = new TimeIntervalCollectionProperty(); - var availability = new TimeIntervalCollection(); - var composite = new CompositePositionProperty(); - for (var i = 0, len = trackNodes.length; i < len; i++) { - var trackNode = trackNodes[i]; - var timeNodes = queryChildNodes(trackNode, 'when', namespaces.kml); - var coordNodes = queryChildNodes(trackNode, 'coord', namespaces.gx); - var altitudeMode = queryStringValue(trackNode, 'altitudeMode', namespaces.kml); - var gxAltitudeMode = queryStringValue(trackNode, 'altitudeMode', namespaces.gx); - var canExtrude = isExtrudable(altitudeMode, gxAltitudeMode); - var extrude = queryBooleanValue(trackNode, 'extrude', namespaces.kml); + this._gltf = gltf; - var length = Math.min(coordNodes.length, timeNodes.length); + var basePath = defaultValue(options.basePath, ''); + this._resource = Resource.createIfNeeded(basePath); - var positions = []; - times = []; - for (var x = 0; x < length; x++) { - var position = readCoordinate(coordNodes[x].textContent); - positions.push(position); - times.push(JulianDate.fromIso8601(timeNodes[x].textContent)); - } + /** + * Determines if the model primitive will be shown. + * + * @type {Boolean} + * + * @default true + */ + this.show = defaultValue(options.show, true); - if (interpolate) { - //If we are interpolating, then we need to fill in the end of - //the last track and the beginning of this one with a sampled - //property. From testing in Google Earth, this property - //is never extruded and always absolute. - if (defined(lastStop)) { - addToMultiTrack([lastStop, times[0]], [lastStopPosition, positions[0]], composite, availability, dropShowProperty, false, 'absolute', undefined, false); - } - lastStop = times[length - 1]; - lastStopPosition = positions[positions.length - 1]; - } + /** + * The 4x4 transformation matrix that transforms the model from model to world coordinates. + * When this is the identity matrix, the model is drawn in world coordinates, i.e., Earth's WGS84 coordinates. + * Local reference frames can be used by providing a different transformation matrix, like that returned + * by {@link Transforms.eastNorthUpToFixedFrame}. + * + * @type {Matrix4} + * + * @default {@link Matrix4.IDENTITY} + * + * @example + * var origin = Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 200000.0); + * m.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin); + */ + this.modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._modelMatrix = Matrix4.clone(this.modelMatrix); - addToMultiTrack(times, positions, composite, availability, dropShowProperty, canExtrude && extrude, altitudeMode, gxAltitudeMode, true); - needDropLine = needDropLine || (canExtrude && extrude); - } + this._ready = false; + this._readyPromise = when.defer(); - entity.availability = availability; - entity.position = composite; - processPositionGraphics(dataSource, entity, styleEntity); - processPathGraphics(dataSource, entity, styleEntity); - if (needDropLine) { - createDropLine(entityCollection, entity, styleEntity); - entity.polyline.show = dropShowProperty; - } + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the bounding sphere for each draw command in the model. A glTF primitive corresponds + * to one draw command. A glTF mesh has an array of primitives, often of length one. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + this._debugShowBoundingVolume = false; - return true; - } + /** + * This property is for debugging only; it is not for production use nor is it optimized. + * <p> + * Draws the model in wireframe. + * </p> + * + * @type {Boolean} + * + * @default false + */ + this.debugWireframe = defaultValue(options.debugWireframe, false); + this._debugWireframe = false; - var geometryTypes = { - Point : processPoint, - LineString : processLineStringOrLinearRing, - LinearRing : processLineStringOrLinearRing, - Polygon : processPolygon, - Track : processTrack, - MultiTrack : processMultiTrack, - MultiGeometry : processMultiGeometry, - Model : processUnsupportedGeometry - }; + this._classificationType = options.classificationType; - function processMultiGeometry(dataSource, entityCollection, geometryNode, entity, styleEntity, context) { - var childNodes = geometryNode.childNodes; - var hasGeometry = false; - for (var i = 0, len = childNodes.length; i < len; i++) { - var childNode = childNodes.item(i); - var geometryProcessor = geometryTypes[childNode.localName]; - if (defined(geometryProcessor)) { - var childEntity = createEntity(childNode, entityCollection, context); - childEntity.parent = entity; - childEntity.name = entity.name; - childEntity.availability = entity.availability; - childEntity.description = entity.description; - childEntity.kml = entity.kml; - if (geometryProcessor(dataSource, entityCollection, childNode, childEntity, styleEntity)) { - hasGeometry = true; - } - } - } + // Undocumented options + this._vertexShaderLoaded = options.vertexShaderLoaded; + this._classificationShaderLoaded = options.classificationShaderLoaded; + this._uniformMapLoaded = options.uniformMapLoaded; + this._pickVertexShaderLoaded = options.pickVertexShaderLoaded; + this._pickFragmentShaderLoaded = options.pickFragmentShaderLoaded; + this._pickUniformMapLoaded = options.pickUniformMapLoaded; + this._ignoreCommands = defaultValue(options.ignoreCommands, false); + this._upAxis = defaultValue(options.upAxis, Axis.Y); + this._batchTable = options.batchTable; - return hasGeometry; - } + this._computedModelMatrix = new Matrix4(); // Derived from modelMatrix and axis + this._initialRadius = undefined; // Radius without model's scale property, model-matrix scale, animations, or skins + this._boundingSphere = undefined; + this._scaledBoundingSphere = new BoundingSphere(); + this._state = ModelState.NEEDS_LOAD; + this._loadResources = undefined; - function processUnsupportedGeometry(dataSource, entityCollection, geometryNode, entity, styleEntity) { - oneTimeWarning('kml-unsupportedGeometry', 'KML - Unsupported geometry: ' + geometryNode.localName); - return false; - } + this._mode = undefined; + this._dirty = false; // true when the model was transformed this frame - function processExtendedData(node, entity) { - var extendedDataNode = queryFirstNode(node, 'ExtendedData', namespaces.kml); + this._nodeMatrix = new Matrix4(); + this._primitive = undefined; - if (!defined(extendedDataNode)) { - return undefined; - } + this._extensionsUsed = undefined; // Cached used glTF extensions + this._extensionsRequired = undefined; // Cached required glTF extensions + this._quantizedUniforms = undefined; // Quantized uniforms for WEB3D_quantized_attributes - if (defined(queryFirstNode(extendedDataNode, 'SchemaData', namespaces.kml))) { - oneTimeWarning('kml-schemaData', 'KML - SchemaData is unsupported'); - } - if (defined(queryStringAttribute(extendedDataNode, 'xmlns:prefix'))) { - oneTimeWarning('kml-extendedData', 'KML - ExtendedData with xmlns:prefix is unsupported'); - } + this._buffers = {}; + this._vertexArray = undefined; + this._shaderProgram = undefined; + this._pickShaderProgram = undefined; + this._uniformMap = undefined; - var result = {}; - var dataNodes = queryChildNodes(extendedDataNode, 'Data', namespaces.kml); - if (defined(dataNodes)) { - var length = dataNodes.length; - for (var i = 0; i < length; i++) { - var dataNode = dataNodes[i]; - var name = queryStringAttribute(dataNode, 'name'); - if (defined(name)) { - result[name] = { - displayName : queryStringValue(dataNode, 'displayName', namespaces.kml), - value : queryStringValue(dataNode, 'value', namespaces.kml) - }; - } - } - } - entity.kml.extendedData = result; + this._geometryByteLength = 0; + this._trianglesLength = 0; + + // CESIUM_RTC extension + this._rtcCenter = undefined; // reference to either 3D or 2D + this._rtcCenterEye = undefined; // in eye coordinates + this._rtcCenter3D = undefined; // in world coordinates + this._rtcCenter2D = undefined; // in projected world coordinates } - var scratchDiv = document.createElement('div'); + defineProperties(ClassificationModel.prototype, { + /** + * The object for the glTF JSON, including properties with default values omitted + * from the JSON provided to this model. + * + * @memberof ClassificationModel.prototype + * + * @type {Object} + * @readonly + * + * @default undefined + */ + gltf : { + get : function() { + return this._gltf; + } + }, - function processDescription(node, entity, styleEntity, uriResolver, proxy, sourceUri) { - var i; - var key; - var keys; + /** + * The base path that paths in the glTF JSON are relative to. The base + * path is the same path as the path containing the .gltf file + * minus the .gltf file, when binary, image, and shader files are + * in the same directory as the .gltf. When this is <code>''</code>, + * the app's base path is used. + * + * @memberof ClassificationModel.prototype + * + * @type {String} + * @readonly + * + * @default '' + */ + basePath : { + get : function() { + return this._resource.url; + } + }, - var kmlData = entity.kml; - var extendedData = kmlData.extendedData; - var description = queryStringValue(node, 'description', namespaces.kml); + /** + * The model's bounding sphere in its local coordinate system. + * + * @memberof ClassificationModel.prototype + * + * @type {BoundingSphere} + * @readonly + * + * @default undefined + * + * @exception {DeveloperError} The model is not loaded. Use ClassificationModel.readyPromise or wait for ClassificationModel.ready to be true. + * + * @example + * // Center in WGS84 coordinates + * var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3()); + */ + boundingSphere : { + get : function() { + if (this._state !== ModelState.LOADED) { + throw new DeveloperError('The model is not loaded. Use ClassificationModel.readyPromise or wait for ClassificationModel.ready to be true.'); + } + + var modelMatrix = this.modelMatrix; + var nonUniformScale = Matrix4.getScale(modelMatrix, boundingSphereCartesian3Scratch); - var balloonStyle = defaultValue(entity.balloonStyle, styleEntity.balloonStyle); + var scaledBoundingSphere = this._scaledBoundingSphere; + scaledBoundingSphere.center = Cartesian3.multiplyComponents(this._boundingSphere.center, nonUniformScale, scaledBoundingSphere.center); + scaledBoundingSphere.radius = Cartesian3.maximumComponent(nonUniformScale) * this._initialRadius; - var background = Color.WHITE; - var foreground = Color.BLACK; - var text = description; + if (defined(this._rtcCenter)) { + Cartesian3.add(this._rtcCenter, scaledBoundingSphere.center, scaledBoundingSphere.center); + } - if (defined(balloonStyle)) { - background = defaultValue(balloonStyle.bgColor, Color.WHITE); - foreground = defaultValue(balloonStyle.textColor, Color.BLACK); - text = defaultValue(balloonStyle.text, description); - } + return scaledBoundingSphere; + } + }, - var value; - if (defined(text)) { - text = text.replace('$[name]', defaultValue(entity.name, '')); - text = text.replace('$[description]', defaultValue(description, '')); - text = text.replace('$[address]', defaultValue(kmlData.address, '')); - text = text.replace('$[Snippet]', defaultValue(kmlData.snippet, '')); - text = text.replace('$[id]', entity.id); + /** + * When <code>true</code>, this model is ready to render, i.e., the external binary, image, + * and shader files were downloaded and the WebGL resources were created. This is set to + * <code>true</code> right before {@link ClassificationModel#readyPromise} is resolved. + * + * @memberof ClassificationModel.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + ready : { + get : function() { + return this._ready; + } + }, - //While not explicitly defined by the OGC spec, in Google Earth - //The appearance of geDirections adds the directions to/from links - //We simply replace this string with nothing. - text = text.replace('$[geDirections]', ''); + /** + * Gets the promise that will be resolved when this model is ready to render, i.e., when the external binary, image, + * and shader files were downloaded and the WebGL resources were created. + * <p> + * This promise is resolved at the end of the frame before the first frame the model is rendered in. + * </p> + * + * @memberof ClassificationModel.prototype + * @type {Promise.<ClassificationModel>} + * @readonly + * + * @see ClassificationModel#ready + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + }, - if (defined(extendedData)) { - var matches = text.match(/\$\[.+?\]/g); - if (matches !== null) { - for (i = 0; i < matches.length; i++) { - var token = matches[i]; - var propertyName = token.substr(2, token.length - 3); - var isDisplayName = /\/displayName$/.test(propertyName); - propertyName = propertyName.replace(/\/displayName$/, ''); + /** + * Returns true if the model was transformed this frame + * + * @memberof ClassificationModel.prototype + * + * @type {Boolean} + * @readonly + * + * @private + */ + dirty : { + get : function() { + return this._dirty; + } + }, - value = extendedData[propertyName]; - if (defined(value)) { - value = isDisplayName ? value.displayName : value.value; - } - if (defined(value)) { - text = text.replace(token, defaultValue(value, '')); - } - } + /** + * Returns an object with all of the glTF extensions used. + * + * @memberof ClassificationModel.prototype + * + * @type {Object} + * @readonly + */ + extensionsUsed : { + get : function() { + if (!defined(this._extensionsUsed)) { + this._extensionsUsed = ModelUtility.getUsedExtensions(this.gltf); } + return this._extensionsUsed; } - } else if (defined(extendedData)) { - //If no description exists, build a table out of the extended data - keys = Object.keys(extendedData); - if (keys.length > 0) { - text = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>'; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - value = extendedData[key]; - text += '<tr><th>' + defaultValue(value.displayName, key) + '</th><td>' + defaultValue(value.value, '') + '</td></tr>'; + }, + + /** + * Returns an object with all of the glTF extensions required. + * + * @memberof ClassificationModel.prototype + * + * @type {Object} + * @readonly + */ + extensionsRequired : { + get : function() { + if (!defined(this._extensionsRequired)) { + this._extensionsRequired = ModelUtility.getRequiredExtensions(this.gltf); } - text += '</tbody></table>'; + return this._extensionsRequired; } - } + }, - if (!defined(text)) { - //No description - return; - } + /** + * Gets the model's up-axis. + * By default models are y-up according to the glTF spec, however geo-referenced models will typically be z-up. + * + * @memberof ClassificationModel.prototype + * + * @type {Number} + * @default Axis.Y + * @readonly + * + * @private + */ + upAxis : { + get : function() { + return this._upAxis; + } + }, - //Turns non-explicit links into clickable links. - text = autolinker.link(text); + /** + * Gets the model's triangle count. + * + * @private + */ + trianglesLength : { + get : function() { + return this._trianglesLength; + } + }, - //Use a temporary div to manipulate the links - //so that they open in a new window. - scratchDiv.innerHTML = text; - var links = scratchDiv.querySelectorAll('a'); - for (i = 0; i < links.length; i++) { - links[i].setAttribute('target', '_blank'); - } + /** + * Gets the model's geometry memory in bytes. This includes all vertex and index buffers. + * + * @private + */ + geometryByteLength : { + get : function() { + return this._geometryByteLength; + } + }, - //Rewrite any KMZ embedded urls - if (defined(uriResolver) && uriResolver.keys.length > 1) { - embedDataUris(scratchDiv, 'a', 'href', uriResolver); - embedDataUris(scratchDiv, 'img', 'src', uriResolver); - } + /** + * Gets the model's texture memory in bytes. + * + * @private + */ + texturesByteLength : { + get : function() { + return 0; + } + }, - //Make relative urls absolute using the sourceUri - applyBasePath(scratchDiv, 'a', 'href', proxy, sourceUri); - applyBasePath(scratchDiv, 'img', 'src', proxy, sourceUri); + /** + * Gets the model's classification type. + * @memberof ClassificationModel.prototype + * @type {ClassificationType} + */ + classificationType : { + get : function() { + return this._classificationType; + } + } + }); - var tmp = '<div class="cesium-infoBox-description-lighter" style="'; - tmp += 'overflow:auto;'; - tmp += 'word-wrap:break-word;'; - tmp += 'background-color:' + background.toCssColorString() + ';'; - tmp += 'color:' + foreground.toCssColorString() + ';'; - tmp += '">'; - tmp += scratchDiv.innerHTML + '</div>'; - scratchDiv.innerHTML = ''; + var aMinScratch = new Cartesian3(); + var aMaxScratch = new Cartesian3(); - //Set the final HTML as the description. - entity.description = tmp; - } + function computeBoundingSphere(model) { + var gltf = model.gltf; + var gltfNodes = gltf.nodes; + var gltfMeshes = gltf.meshes; - function processFeature(dataSource, parent, featureNode, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var entity = createEntity(featureNode, entityCollection, context); - var kmlData = entity.kml; - var styleEntity = computeFinalStyle(entity, dataSource, featureNode, styleCollection, sourceUri, uriResolver, query); + var min = new Cartesian3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + var max = new Cartesian3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); - var name = queryStringValue(featureNode, 'name', namespaces.kml); - entity.name = name; - entity.parent = parent; + var n = gltfNodes[0]; + var meshId = n.mesh; - var availability = processTimeSpan(featureNode); - if (!defined(availability)) { - availability = processTimeStamp(featureNode); + var transformToRoot = ModelUtility.getTransform(n); + var mesh = gltfMeshes[meshId]; + var primitive = mesh.primitives[0]; + var positionAccessor = primitive.attributes.POSITION; + var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor); + var aMin = Cartesian3.fromArray(minMax.min, 0, aMinScratch); + var aMax = Cartesian3.fromArray(minMax.max, 0, aMaxScratch); + if (defined(min) && defined(max)) { + Matrix4.multiplyByPoint(transformToRoot, aMin, aMin); + Matrix4.multiplyByPoint(transformToRoot, aMax, aMax); + Cartesian3.minimumByComponent(min, aMin, min); + Cartesian3.maximumByComponent(max, aMax, max); } - entity.availability = availability; - - mergeAvailabilityWithParent(entity); - // Per KML spec "A Feature is visible only if it and all its ancestors are visible." - function ancestryIsVisible(parentEntity) { - if (!parentEntity) { - return true; - } - return parentEntity.show && ancestryIsVisible(parentEntity.parent); + var boundingSphere = BoundingSphere.fromCornerPoints(min, max); + if (model._upAxis === Axis.Y) { + BoundingSphere.transformWithoutScale(boundingSphere, Axis.Y_UP_TO_Z_UP, boundingSphere); + } else if (model._upAxis === Axis.X) { + BoundingSphere.transformWithoutScale(boundingSphere, Axis.X_UP_TO_Z_UP, boundingSphere); } + return boundingSphere; + } - var visibility = queryBooleanValue(featureNode, 'visibility', namespaces.kml); - entity.show = ancestryIsVisible(parent) && defaultValue(visibility, true); - //var open = queryBooleanValue(featureNode, 'open', namespaces.kml); - - var authorNode = queryFirstNode(featureNode, 'author', namespaces.atom); - var author = kmlData.author; - author.name = queryStringValue(authorNode, 'name', namespaces.atom); - author.uri = queryStringValue(authorNode, 'uri', namespaces.atom); - author.email = queryStringValue(authorNode, 'email', namespaces.atom); - - var linkNode = queryFirstNode(featureNode, 'link', namespaces.atom); - var link = kmlData.link; - link.href = queryStringAttribute(linkNode, 'href'); - link.hreflang = queryStringAttribute(linkNode, 'hreflang'); - link.rel = queryStringAttribute(linkNode, 'rel'); - link.type = queryStringAttribute(linkNode, 'type'); - link.title = queryStringAttribute(linkNode, 'title'); - link.length = queryStringAttribute(linkNode, 'length'); - - kmlData.address = queryStringValue(featureNode, 'address', namespaces.kml); - kmlData.phoneNumber = queryStringValue(featureNode, 'phoneNumber', namespaces.kml); - kmlData.snippet = queryStringValue(featureNode, 'Snippet', namespaces.kml); + /////////////////////////////////////////////////////////////////////////// - processExtendedData(featureNode, entity); - processDescription(featureNode, entity, styleEntity, uriResolver, dataSource._proxy, sourceUri); - processLookAt(featureNode, entity); - processCamera(featureNode, entity); + function getFailedLoadFunction(model, type, path) { + return function() { + model._state = ModelState.FAILED; + model._readyPromise.reject(new RuntimeError('Failed to load ' + type + ': ' + path)); + }; + } - if (defined(queryFirstNode(featureNode, 'Region', namespaces.kml))) { - oneTimeWarning('kml-region', 'KML - Placemark Regions are unsupported'); - } + function addBuffersToLoadResources(model) { + var gltf = model.gltf; + var loadResources = model._loadResources; + ForEach.buffer(gltf, function(buffer, id) { + loadResources.buffers[id] = buffer.extras._pipeline.source; + }); + } - return { - entity : entity, - styleEntity : styleEntity + function bufferLoad(model, id) { + return function(arrayBuffer) { + var loadResources = model._loadResources; + var buffer = new Uint8Array(arrayBuffer); + --loadResources.pendingBufferLoads; + model.gltf.buffers[id].extras._pipeline.source = buffer; }; } - // Ensure Specs/Data/KML/unsupported.kml is kept up to date with these supported types - var featureTypes = { - Document : processDocument, - Folder : processFolder, - Placemark : processPlacemark, - NetworkLink : processNetworkLink, - GroundOverlay : processGroundOverlay, - PhotoOverlay : processUnsupportedFeature, - ScreenOverlay : processUnsupportedFeature, - Tour : processTour - }; + function parseBuffers(model) { + var loadResources = model._loadResources; + // Iterate this way for compatibility with objects and arrays + var buffers = model.gltf.buffers; + var length = buffers.length; + for (var i = 0; i < length; ++i) { + var buffer = buffers[i]; + buffer.extras = defaultValue(buffer.extras, {}); + buffer.extras._pipeline = defaultValue(buffer.extras._pipeline, {}); + if (defined(buffer.extras._pipeline.source)) { + loadResources.buffers[i] = buffer.extras._pipeline.source; + } else { + var bufferResource = model._resource.getDerivedResource({ + url : buffer.uri + }); + ++loadResources.pendingBufferLoads; + bufferResource.fetchArrayBuffer().then(bufferLoad(model, i)).otherwise(getFailedLoadFunction(model, 'buffer', bufferResource.uri)); + } + } + } - function processDocument(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var featureTypeNames = Object.keys(featureTypes); - var featureTypeNamesLength = featureTypeNames.length; + function parseBufferViews(model) { + var bufferViews = model.gltf.bufferViews; - for (var i = 0; i < featureTypeNamesLength; i++) { - var featureName = featureTypeNames[i]; - var processFeatureNode = featureTypes[featureName]; + var vertexBuffersToCreate = model._loadResources.vertexBuffersToCreate; - var childNodes = node.childNodes; - var length = childNodes.length; - for (var q = 0; q < length; q++) { - var child = childNodes[q]; - if (child.localName === featureName && - ((namespaces.kml.indexOf(child.namespaceURI) !== -1) || (namespaces.gx.indexOf(child.namespaceURI) !== -1))) { - processFeatureNode(dataSource, parent, child, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - } + // Only ARRAY_BUFFER here. ELEMENT_ARRAY_BUFFER created below. + ForEach.bufferView(model.gltf, function(bufferView, id) { + if (bufferView.target === WebGLConstants.ARRAY_BUFFER) { + vertexBuffersToCreate.enqueue(id); } - } - } + }); - function processFolder(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var r = processFeature(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - processDocument(dataSource, r.entity, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - } + var indexBuffersToCreate = model._loadResources.indexBuffersToCreate; + var indexBufferIds = {}; - function processPlacemark(dataSource, parent, placemark, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var r = processFeature(dataSource, parent, placemark, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - var entity = r.entity; - var styleEntity = r.styleEntity; + // The Cesium Renderer requires knowing the datatype for an index buffer + // at creation type, which is not part of the glTF bufferview so loop + // through glTF accessors to create the bufferview's index buffer. + ForEach.accessor(model.gltf, function(accessor) { + var bufferViewId = accessor.bufferView; + var bufferView = bufferViews[bufferViewId]; - var hasGeometry = false; - var childNodes = placemark.childNodes; - for (var i = 0, len = childNodes.length; i < len && !hasGeometry; i++) { - var childNode = childNodes.item(i); - var geometryProcessor = geometryTypes[childNode.localName]; - if (defined(geometryProcessor)) { - // pass the placemark entity id as a context for case of defining multiple child entities together to handle case - // where some malformed kmls reuse the same id across placemarks, which works in GE, but is not technically to spec. - geometryProcessor(dataSource, entityCollection, childNode, entity, styleEntity, entity.id); - hasGeometry = true; + if ((bufferView.target === WebGLConstants.ELEMENT_ARRAY_BUFFER) && !defined(indexBufferIds[bufferViewId])) { + indexBufferIds[bufferViewId] = true; + indexBuffersToCreate.enqueue({ + id : bufferViewId, + componentType : accessor.componentType + }); } - } + }); + } - if (!hasGeometry) { - entity.merge(styleEntity); - processPositionGraphics(dataSource, entity, styleEntity); - } + function createVertexBuffer(bufferViewId, model) { + var loadResources = model._loadResources; + var bufferViews = model.gltf.bufferViews; + var bufferView = bufferViews[bufferViewId]; + var vertexBuffer = loadResources.getBuffer(bufferView); + model._buffers[bufferViewId] = vertexBuffer; + model._geometryByteLength += vertexBuffer.byteLength; } - var playlistNodeProcessors = { - FlyTo: processTourFlyTo, - Wait: processTourWait, - SoundCue: processTourUnsupportedNode, - AnimatedUpdate: processTourUnsupportedNode, - TourControl: processTourUnsupportedNode - }; + function createIndexBuffer(bufferViewId, componentType, model) { + var loadResources = model._loadResources; + var bufferViews = model.gltf.bufferViews; + var bufferView = bufferViews[bufferViewId]; + var indexBuffer = { + typedArray : loadResources.getBuffer(bufferView), + indexDatatype : componentType + }; + model._buffers[bufferViewId] = indexBuffer; + model._geometryByteLength += indexBuffer.typedArray.byteLength; + } - function processTour(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context) { - var name = queryStringValue(node, 'name', namespaces.kml); - var id = queryStringAttribute(node, 'id'); - var tour = new KmlTour(name, id); + function createBuffers(model) { + var loadResources = model._loadResources; - var playlistNode = queryFirstNode(node, 'Playlist', namespaces.gx); - if(playlistNode) { - var childNodes = playlistNode.childNodes; - for(var i = 0; i < childNodes.length; i++) { - var entryNode = childNodes[i]; - if (entryNode.localName) { - var playlistNodeProcessor = playlistNodeProcessors[entryNode.localName]; - if (playlistNodeProcessor) { - playlistNodeProcessor(tour, entryNode); - } - else { - console.log('Unknown KML Tour playlist entry type ' + entryNode.localName); - } - } - } + if (loadResources.pendingBufferLoads !== 0) { + return; } - if (!defined(dataSource.kmlTours)) { - dataSource.kmlTours = []; + var vertexBuffersToCreate = loadResources.vertexBuffersToCreate; + var indexBuffersToCreate = loadResources.indexBuffersToCreate; + + while (vertexBuffersToCreate.length > 0) { + createVertexBuffer(vertexBuffersToCreate.dequeue(), model); } - dataSource.kmlTours.push(tour); + while (indexBuffersToCreate.length > 0) { + var i = indexBuffersToCreate.dequeue(); + createIndexBuffer(i.id, i.componentType, model); + } } - function processTourUnsupportedNode(tour, entryNode) { - oneTimeWarning('KML Tour unsupported node ' + entryNode.localName); + function modifyShaderForQuantizedAttributes(shader, model) { + var primitive = model.gltf.meshes[0].primitives[0]; + var result = ModelUtility.modifyShaderForQuantizedAttributes(model.gltf, primitive, shader); + model._quantizedUniforms = result.uniforms; + return result.shader; } - function processTourWait(tour, entryNode) { - var duration = queryNumericValue(entryNode, 'duration', namespaces.gx); - tour.addPlaylistEntry(new KmlTourWait(duration)); + function modifyShader(shader, callback) { + if (defined(callback)) { + shader = callback(shader); + } + return shader; } - function processTourFlyTo(tour, entryNode) { - var duration = queryNumericValue(entryNode, 'duration', namespaces.gx); - var flyToMode = queryStringValue(entryNode, 'flyToMode', namespaces.gx); - - var t = {kml: {}}; + function createProgram(model) { + var positionName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'POSITION'); + var batchIdName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, '_BATCHID'); - processLookAt(entryNode, t); - processCamera(entryNode, t); + var attributeLocations = {}; + attributeLocations[positionName] = 0; + attributeLocations[batchIdName] = 1; - var view = t.kml.lookAt || t.kml.camera; + var modelViewProjectionName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'MODELVIEWPROJECTION'); - var flyto = new KmlTourFlyTo(duration, flyToMode, view); - tour.addPlaylistEntry(flyto); - } + var uniformDecl; + var computePosition; - function processCamera(featureNode, entity) { - var camera = queryFirstNode(featureNode, 'Camera', namespaces.kml); - if(defined(camera)) { - var lon = defaultValue(queryNumericValue(camera, 'longitude', namespaces.kml), 0.0); - var lat = defaultValue(queryNumericValue(camera, 'latitude', namespaces.kml), 0.0); - var altitude = defaultValue(queryNumericValue(camera, 'altitude', namespaces.kml), 0.0); + if (!defined(modelViewProjectionName)) { + var projectionName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'PROJECTION'); + var modelViewName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'MODELVIEW'); + if (!defined(modelViewName)) { + modelViewName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'CESIUM_RTC_MODELVIEW'); + } - var heading = defaultValue(queryNumericValue(camera, 'heading', namespaces.kml), 0.0); - var tilt = defaultValue(queryNumericValue(camera, 'tilt', namespaces.kml), 0.0); - var roll = defaultValue(queryNumericValue(camera, 'roll', namespaces.kml), 0.0); + uniformDecl = + 'uniform mat4 ' + modelViewName + ';\n' + + 'uniform mat4 ' + projectionName + ';\n'; + computePosition = ' vec4 positionInClipCoords = ' + projectionName + ' * ' + modelViewName + ' * vec4(' + positionName + ', 1.0);\n'; + } else { + uniformDecl = 'uniform mat4 ' + modelViewProjectionName + ';\n'; + computePosition = ' vec4 positionInClipCoords = ' + modelViewProjectionName + ' * vec4(' + positionName + ', 1.0);\n'; + } - var position = Cartesian3.fromDegrees(lon, lat, altitude); - var hpr = HeadingPitchRoll.fromDegrees(heading, tilt - 90.0, roll); + var vs = + 'attribute vec3 ' + positionName + ';\n' + + 'attribute float ' + batchIdName + ';\n' + + uniformDecl + + 'void main() {\n' + + computePosition + + ' gl_Position = czm_depthClampFarPlane(positionInClipCoords);\n' + + '}\n'; + var fs = + '#ifdef GL_EXT_frag_depth\n' + + '#extension GL_EXT_frag_depth : enable\n' + + '#endif\n' + + 'void main() \n' + + '{ \n' + + ' gl_FragColor = vec4(1.0); \n' + + ' czm_writeDepthClampedToFarPlane();\n' + + '}\n'; - entity.kml.camera = new KmlCamera(position, hpr); + if (model.extensionsUsed.WEB3D_quantized_attributes) { + vs = modifyShaderForQuantizedAttributes(vs, model); } - } - function processLookAt(featureNode, entity) { - var lookAt = queryFirstNode(featureNode, 'LookAt', namespaces.kml); - if(defined(lookAt)) { - var lon = defaultValue(queryNumericValue(lookAt, 'longitude', namespaces.kml), 0.0); - var lat = defaultValue(queryNumericValue(lookAt, 'latitude', namespaces.kml), 0.0); - var altitude = defaultValue(queryNumericValue(lookAt, 'altitude', namespaces.kml), 0.0); - var heading = queryNumericValue(lookAt, 'heading', namespaces.kml); - var tilt = queryNumericValue(lookAt, 'tilt', namespaces.kml); - var range = defaultValue(queryNumericValue(lookAt, 'range', namespaces.kml), 0.0); + var drawVS = modifyShader(vs, model._vertexShaderLoaded); + var drawFS = modifyShader(fs, model._classificationShaderLoaded); - tilt = CesiumMath.toRadians(defaultValue(tilt, 0.0)); - heading = CesiumMath.toRadians(defaultValue(heading, 0.0)); + model._shaderProgram = { + vertexShaderSource : drawVS, + fragmentShaderSource : drawFS, + attributeLocations : attributeLocations + }; - var hpr = new HeadingPitchRange(heading, tilt - CesiumMath.PI_OVER_TWO, range); - var viewPoint = Cartesian3.fromDegrees(lon, lat, altitude); + // PERFORMANCE_IDEA: Can optimize this shader with a glTF hint. https://github.com/KhronosGroup/glTF/issues/181 + var pickVS = modifyShader(vs, model._pickVertexShaderLoaded); + var pickFS = modifyShader(fs, model._pickFragmentShaderLoaded); - entity.kml.lookAt = new KmlLookAt(viewPoint, hpr); - } + model._pickShaderProgram = { + vertexShaderSource : pickVS, + fragmentShaderSource : pickFS, + attributeLocations : attributeLocations + }; } - function processGroundOverlay(dataSource, parent, groundOverlay, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var r = processFeature(dataSource, parent, groundOverlay, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - var entity = r.entity; - - var geometry; - var isLatLonQuad = false; + function getAttributeLocations() { + return { + POSITION : 0, + _BATCHID : 1 + }; + } - var positions = readCoordinates(queryFirstNode(groundOverlay, 'LatLonQuad', namespaces.gx)); - if (defined(positions)) { - geometry = createDefaultPolygon(); - geometry.hierarchy = new PolygonHierarchy(positions); - entity.polygon = geometry; - isLatLonQuad = true; - } else { - geometry = new RectangleGraphics(); - entity.rectangle = geometry; + function createVertexArray(model) { + var loadResources = model._loadResources; + if (!loadResources.finishedBuffersCreation()) { + return; + } - var latLonBox = queryFirstNode(groundOverlay, 'LatLonBox', namespaces.kml); - if (defined(latLonBox)) { - var west = queryNumericValue(latLonBox, 'west', namespaces.kml); - var south = queryNumericValue(latLonBox, 'south', namespaces.kml); - var east = queryNumericValue(latLonBox, 'east', namespaces.kml); - var north = queryNumericValue(latLonBox, 'north', namespaces.kml); + if (defined(model._vertexArray)) { + return; + } - if (defined(west)) { - west = CesiumMath.negativePiToPi(CesiumMath.toRadians(west)); - } - if (defined(south)) { - south = CesiumMath.clampToLatitudeRange(CesiumMath.toRadians(south)); - } - if (defined(east)) { - east = CesiumMath.negativePiToPi(CesiumMath.toRadians(east)); - } - if (defined(north)) { - north = CesiumMath.clampToLatitudeRange(CesiumMath.toRadians(north)); - } - geometry.coordinates = new Rectangle(west, south, east, north); + var rendererBuffers = model._buffers; + var gltf = model.gltf; + var accessors = gltf.accessors; + var meshes = gltf.meshes; + var primitives = meshes[0].primitives; - var rotation = queryNumericValue(latLonBox, 'rotation', namespaces.kml); - if (defined(rotation)) { - var rotationRadians = CesiumMath.toRadians(rotation); - geometry.rotation = rotationRadians; - geometry.stRotation = rotationRadians; + var primitive = primitives[0]; + var attributeLocations = getAttributeLocations(); + var attributes = {}; + var primitiveAttributes = primitive.attributes; + for (var attributeName in primitiveAttributes) { + if (primitiveAttributes.hasOwnProperty(attributeName)) { + var attributeLocation = attributeLocations[attributeName]; + // Skip if the attribute is not used by the material, e.g., because the asset was exported + // with an attribute that wasn't used and the asset wasn't optimized. + if (defined(attributeLocation)) { + var a = accessors[primitiveAttributes[attributeName]]; + attributes[attributeName] = { + index : attributeLocation, + vertexBuffer : rendererBuffers[a.bufferView], + componentsPerAttribute : numberOfComponentsForType(a.type), + componentDatatype : a.componentType, + offsetInBytes : a.byteOffset, + strideInBytes : getAccessorByteStride(gltf, a) + }; } } } - var iconNode = queryFirstNode(groundOverlay, 'Icon', namespaces.kml); - var href = getIconHref(iconNode, dataSource, sourceUri, uriResolver, true, query); - if (defined(href)) { - if (isLatLonQuad) { - oneTimeWarning('kml-gx:LatLonQuad', 'KML - gx:LatLonQuad Icon does not support texture projection.'); - } - var x = queryNumericValue(iconNode, 'x', namespaces.gx); - var y = queryNumericValue(iconNode, 'y', namespaces.gx); - var w = queryNumericValue(iconNode, 'w', namespaces.gx); - var h = queryNumericValue(iconNode, 'h', namespaces.gx); + var indexBuffer; + if (defined(primitive.indices)) { + var accessor = accessors[primitive.indices]; + indexBuffer = rendererBuffers[accessor.bufferView]; + } + model._vertexArray = { + attributes : attributes, + indexBuffer : indexBuffer + }; + } - if (defined(x) || defined(y) || defined(w) || defined(h)) { - oneTimeWarning('kml-groundOverlay-xywh', 'KML - gx:x, gx:y, gx:w, gx:h aren\'t supported for GroundOverlays'); - } + var gltfSemanticUniforms = { + PROJECTION : function(uniformState, model) { + return ModelUtility.getGltfSemanticUniforms().PROJECTION(uniformState, model); + }, + MODELVIEW : function(uniformState, model) { + return ModelUtility.getGltfSemanticUniforms().MODELVIEW(uniformState, model); + }, + CESIUM_RTC_MODELVIEW : function(uniformState, model) { + return ModelUtility.getGltfSemanticUniforms().CESIUM_RTC_MODELVIEW(uniformState, model); + }, + MODELVIEWPROJECTION : function(uniformState, model) { + return ModelUtility.getGltfSemanticUniforms().MODELVIEWPROJECTION(uniformState, model); + } + }; - geometry.material = href; - geometry.material.color = queryColorValue(groundOverlay, 'color', namespaces.kml); - geometry.material.transparent = true; - } else { - geometry.material = queryColorValue(groundOverlay, 'color', namespaces.kml); + function createUniformMap(model, context) { + if (defined(model._uniformMap)) { + return; } - var altitudeMode = queryStringValue(groundOverlay, 'altitudeMode', namespaces.kml); + var techniques = model.gltf.techniques; + var technique = techniques[0]; + var parameters = technique.parameters; + var uniforms = technique.uniforms; - if (defined(altitudeMode)) { - if (altitudeMode === 'absolute') { - //Use height above ellipsoid until we support MSL. - geometry.height = queryNumericValue(groundOverlay, 'altitude', namespaces.kml); - } else if (altitudeMode !== 'clampToGround') { - oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + altitudeMode); - } - // else just use the default of 0 until we support 'clampToGround' - } else { - altitudeMode = queryStringValue(groundOverlay, 'altitudeMode', namespaces.gx); - if (altitudeMode === 'relativeToSeaFloor') { - oneTimeWarning('kml-altitudeMode-relativeToSeaFloor', 'KML - altitudeMode relativeToSeaFloor is currently not supported, treating as absolute.'); - geometry.height = queryNumericValue(groundOverlay, 'altitude', namespaces.kml); - } else if (altitudeMode === 'clampToSeaFloor') { - oneTimeWarning('kml-altitudeMode-clampToSeaFloor', 'KML - altitudeMode clampToSeaFloor is currently not supported, treating as clampToGround.'); - } else if (defined(altitudeMode)) { - oneTimeWarning('kml-altitudeMode-unknown', 'KML - Unknown altitudeMode: ' + altitudeMode); + var uniformMap = {}; + for (var name in uniforms) { + if (uniforms.hasOwnProperty(name) && name !== 'extras') { + var parameterName = uniforms[name]; + var parameter = parameters[parameterName]; + + if (!defined(parameter.semantic) || !defined(gltfSemanticUniforms[parameter.semantic])) { + continue; + } + uniformMap[name] = gltfSemanticUniforms[parameter.semantic](context.uniformState, model); } } - } - function processUnsupportedFeature(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context) { - dataSource._unsupportedNode.raiseEvent(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver); - oneTimeWarning('kml-unsupportedFeature-' + node.nodeName, 'KML - Unsupported feature: ' + node.nodeName); + model._uniformMap = uniformMap; } - var RefreshMode = { - INTERVAL : 0, - EXPIRE : 1, - STOP : 2 - }; + function createUniformsForQuantizedAttributes(model, primitive) { + return ModelUtility.createUniformsForQuantizedAttributes(model.gltf, primitive, model._quantizedUniforms); + } - function cleanupString(s) { - if (!defined(s) || s.length === 0) { - return ''; + function triangleCountFromPrimitiveIndices(primitive, indicesCount) { + switch (primitive.mode) { + case PrimitiveType.TRIANGLES: + return (indicesCount / 3); + case PrimitiveType.TRIANGLE_STRIP: + case PrimitiveType.TRIANGLE_FAN: + return Math.max(indicesCount - 2, 0); + default: + return 0; } + } - var sFirst = s[0]; - if (sFirst === '&') { - s.splice(0, 1); - } + function createPrimitive(model) { + var batchTable = model._batchTable; - if (sFirst !== '?') { - s = '?' + s; - } + var uniformMap = model._uniformMap; + var vertexArray = model._vertexArray; - return s; - } + var gltf = model.gltf; + var accessors = gltf.accessors; + var gltfMeshes = gltf.meshes; + var primitive = gltfMeshes[0].primitives[0]; + var ix = accessors[primitive.indices]; - function makeQueryString(string1, string2) { - var result = ''; - if ((defined(string1) && string1.length > 0) || (defined(string2) && string2.length > 0)) { - result += joinUrls(cleanupString(string1), cleanupString(string2), false); - } + var positionAccessor = primitive.attributes.POSITION; + var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor); + var boundingSphere = BoundingSphere.fromCornerPoints(Cartesian3.fromArray(minMax.min), Cartesian3.fromArray(minMax.max)); - return result; - } + var offset; + var count; + if (defined(ix)) { + count = ix.count; + offset = (ix.byteOffset / IndexDatatype.getSizeInBytes(ix.componentType)); // glTF has offset in bytes. Cesium has offsets in indices + } + else { + var positions = accessors[primitive.attributes.POSITION]; + count = positions.count; + offset = 0; + } - var zeroRectangle = new Rectangle(); - var scratchCartographic = new Cartographic(); - var scratchCartesian2 = new Cartesian2(); - var scratchCartesian3 = new Cartesian3(); + // Update model triangle count using number of indices + model._trianglesLength += triangleCountFromPrimitiveIndices(primitive, count); - function processNetworkLinkQueryString(camera, canvas, queryString, viewBoundScale, bbox) { - function fixLatitude(value) { - if (value < -CesiumMath.PI_OVER_TWO) { - return -CesiumMath.PI_OVER_TWO; - } else if (value > CesiumMath.PI_OVER_TWO) { - return CesiumMath.PI_OVER_TWO; - } - return value; + // Allow callback to modify the uniformMap + if (defined(model._uniformMapLoaded)) { + uniformMap = model._uniformMapLoaded(uniformMap); } - function fixLongitude(value) { - if (value > CesiumMath.PI) { - return value - CesiumMath.TWO_PI; - } else if (value < -CesiumMath.PI) { - return value + CesiumMath.TWO_PI; - } - - return value; + // Add uniforms for decoding quantized attributes if used + if (model.extensionsUsed.WEB3D_quantized_attributes) { + var quantizedUniformMap = createUniformsForQuantizedAttributes(model, primitive); + uniformMap = combine(uniformMap, quantizedUniformMap); } - if (defined(camera) && camera._mode !== SceneMode.MORPHING) { - var wgs84 = Ellipsoid.WGS84; - var centerCartesian; - var centerCartographic; + var attribute = vertexArray.attributes.POSITION; + var componentDatatype = attribute.componentDatatype; + var typedArray = attribute.vertexBuffer; + var byteOffset = typedArray.byteOffset; + var bufferLength = typedArray.byteLength / ComponentDatatype.getSizeInBytes(componentDatatype); + var positionsBuffer = ComponentDatatype.createArrayBufferView(componentDatatype, typedArray.buffer, byteOffset, bufferLength); - bbox = defaultValue(bbox, zeroRectangle); - if (defined(canvas)) { - scratchCartesian2.x = canvas.clientWidth * 0.5; - scratchCartesian2.y = canvas.clientHeight * 0.5; - centerCartesian = camera.pickEllipsoid(scratchCartesian2, wgs84, scratchCartesian3); - } + attribute = vertexArray.attributes._BATCHID; + componentDatatype = attribute.componentDatatype; + typedArray = attribute.vertexBuffer; + byteOffset = typedArray.byteOffset; + bufferLength = typedArray.byteLength / ComponentDatatype.getSizeInBytes(componentDatatype); + var vertexBatchIds = ComponentDatatype.createArrayBufferView(componentDatatype, typedArray.buffer, byteOffset, bufferLength); - if (defined(centerCartesian)) { - centerCartographic = wgs84.cartesianToCartographic(centerCartesian, scratchCartographic); - } else { - centerCartographic = Rectangle.center(bbox, scratchCartographic); - centerCartesian = wgs84.cartographicToCartesian(centerCartographic); - } + var buffer = vertexArray.indexBuffer.typedArray; + var indices; + if (vertexArray.indexBuffer.indexDatatype === IndexDatatype.UNSIGNED_SHORT) { + indices = new Uint16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint16Array.BYTES_PER_ELEMENT); + } else { + indices = new Uint32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint32Array.BYTES_PER_ELEMENT); + } - if (defined(viewBoundScale) && !CesiumMath.equalsEpsilon(viewBoundScale, 1.0, CesiumMath.EPSILON9)) { - var newHalfWidth = bbox.width * viewBoundScale * 0.5; - var newHalfHeight = bbox.height * viewBoundScale * 0.5; - bbox = new Rectangle(fixLongitude(centerCartographic.longitude - newHalfWidth), - fixLatitude(centerCartographic.latitude - newHalfHeight), - fixLongitude(centerCartographic.longitude + newHalfWidth), - fixLatitude(centerCartographic.latitude + newHalfHeight) - ); - } + positionsBuffer = arraySlice(positionsBuffer); + vertexBatchIds = arraySlice(vertexBatchIds); + indices = arraySlice(indices, offset, offset + count); - queryString = queryString.replace('[bboxWest]', CesiumMath.toDegrees(bbox.west).toString()); - queryString = queryString.replace('[bboxSouth]', CesiumMath.toDegrees(bbox.south).toString()); - queryString = queryString.replace('[bboxEast]', CesiumMath.toDegrees(bbox.east).toString()); - queryString = queryString.replace('[bboxNorth]', CesiumMath.toDegrees(bbox.north).toString()); + var batchIds = []; + var indexCounts = []; + var indexOffsets = []; + var batchedIndices = []; - var lon = CesiumMath.toDegrees(centerCartographic.longitude).toString(); - var lat = CesiumMath.toDegrees(centerCartographic.latitude).toString(); - queryString = queryString.replace('[lookatLon]', lon); - queryString = queryString.replace('[lookatLat]', lat); - queryString = queryString.replace('[lookatTilt]', CesiumMath.toDegrees(camera.pitch).toString()); - queryString = queryString.replace('[lookatHeading]', CesiumMath.toDegrees(camera.heading).toString()); - queryString = queryString.replace('[lookatRange]', Cartesian3.distance(camera.positionWC, centerCartesian)); - queryString = queryString.replace('[lookatTerrainLon]', lon); - queryString = queryString.replace('[lookatTerrainLat]', lat); - queryString = queryString.replace('[lookatTerrainAlt]', centerCartographic.height.toString()); + var currentId = vertexBatchIds[indices[0]]; + batchIds.push(currentId); + indexOffsets.push(0); - wgs84.cartesianToCartographic(camera.positionWC, scratchCartographic); - queryString = queryString.replace('[cameraLon]', CesiumMath.toDegrees(scratchCartographic.longitude).toString()); - queryString = queryString.replace('[cameraLat]', CesiumMath.toDegrees(scratchCartographic.latitude).toString()); - queryString = queryString.replace('[cameraAlt]', CesiumMath.toDegrees(scratchCartographic.height).toString()); + var batchId; + var indexOffset; + var indexCount; + var indicesLength = indices.length; + for (var j = 1; j < indicesLength; ++j) { + batchId = vertexBatchIds[indices[j]]; + if (batchId !== currentId) { + indexOffset = indexOffsets[indexOffsets.length - 1]; + indexCount = j - indexOffset; + + batchIds.push(batchId); + indexCounts.push(indexCount); + indexOffsets.push(j); + + batchedIndices.push(new Vector3DTileBatch({ + offset : indexOffset, + count : indexCount, + batchIds : [currentId], + color : Color.WHITE + })); - var frustum = camera.frustum; - var aspectRatio = frustum.aspectRatio; - var horizFov = ''; - var vertFov = ''; - if (defined(aspectRatio)) { - var fov = CesiumMath.toDegrees(frustum.fov); - if (aspectRatio > 1.0) { - horizFov = fov; - vertFov = fov / aspectRatio; - } else { - vertFov = fov; - horizFov = fov * aspectRatio; - } + currentId = batchId; } - queryString = queryString.replace('[horizFov]', horizFov.toString()); - queryString = queryString.replace('[vertFov]', vertFov.toString()); - } else { - queryString = queryString.replace('[bboxWest]', '-180'); - queryString = queryString.replace('[bboxSouth]', '-90'); - queryString = queryString.replace('[bboxEast]', '180'); - queryString = queryString.replace('[bboxNorth]', '90'); - - queryString = queryString.replace('[lookatLon]', ''); - queryString = queryString.replace('[lookatLat]', ''); - queryString = queryString.replace('[lookatRange]', ''); - queryString = queryString.replace('[lookatTilt]', ''); - queryString = queryString.replace('[lookatHeading]', ''); - queryString = queryString.replace('[lookatTerrainLon]', ''); - queryString = queryString.replace('[lookatTerrainLat]', ''); - queryString = queryString.replace('[lookatTerrainAlt]', ''); - - queryString = queryString.replace('[cameraLon]', ''); - queryString = queryString.replace('[cameraLat]', ''); - queryString = queryString.replace('[cameraAlt]', ''); - queryString = queryString.replace('[horizFov]', ''); - queryString = queryString.replace('[vertFov]', ''); } - if (defined(canvas)) { - queryString = queryString.replace('[horizPixels]', canvas.clientWidth); - queryString = queryString.replace('[vertPixels]', canvas.clientHeight); - } else { - queryString = queryString.replace('[horizPixels]', ''); - queryString = queryString.replace('[vertPixels]', ''); - } - - queryString = queryString.replace('[terrainEnabled]', '1'); - queryString = queryString.replace('[clientVersion]', '1'); - queryString = queryString.replace('[kmlVersion]', '2.2'); - queryString = queryString.replace('[clientName]', 'Cesium'); - queryString = queryString.replace('[language]', 'English'); + indexOffset = indexOffsets[indexOffsets.length - 1]; + indexCount = indicesLength - indexOffset; - return queryString; - } + indexCounts.push(indexCount); + batchedIndices.push(new Vector3DTileBatch({ + offset : indexOffset, + count : indexCount, + batchIds : [currentId], + color : Color.WHITE + })); - function processNetworkLink(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var r = processFeature(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - var networkEntity = r.entity; + var shader = model._shaderProgram; + var vertexShaderSource = shader.vertexShaderSource; + var fragmentShaderSource = shader.fragmentShaderSource; + var attributeLocations = shader.attributeLocations; - var link = queryFirstNode(node, 'Link', namespaces.kml); + var pickUniformMap; + var pickShader = model._pickShaderProgram; + var pickVertexShaderSource = pickShader.vertexShaderSource; + var pickFragmentShaderSource = pickShader.fragmentShaderSource; - if (!defined(link)) { - link = queryFirstNode(node, 'Url', namespaces.kml); + if (defined(model._pickUniformMapLoaded)) { + pickUniformMap = model._pickUniformMapLoaded(uniformMap); + } else { + // This is unlikely, but could happen if the override shader does not + // need new uniforms since, for example, its pick ids are coming from + // a vertex attribute or are baked into the shader source. + pickUniformMap = combine(uniformMap); } - if (defined(link)) { - var href = queryStringValue(link, 'href', namespaces.kml); - var viewRefreshMode; - var viewBoundScale; - var queryString; - if (defined(href)) { - var newSourceUri = href; - href = resolveHref(href, undefined, sourceUri, uriResolver, query); - var linkUrl; - // We need to pass in the original path if resolveHref returns a data uri because the network link - // references a document in a KMZ archive - if (/^data:/.test(href)) { - // No need to build a query string for a data uri, just use as is - linkUrl = href; + model._primitive = new Vector3DTilePrimitive({ + classificationType : model._classificationType, + positions : positionsBuffer, + indices : indices, + indexOffsets : indexOffsets, + indexCounts : indexCounts, + batchIds : batchIds, + vertexBatchIds : vertexBatchIds, + batchedIndices : batchedIndices, + batchTable : batchTable, + boundingVolume : new BoundingSphere(), // updated in update() + _vertexShaderSource : vertexShaderSource, + _fragmentShaderSource : fragmentShaderSource, + _attributeLocations : attributeLocations, + _pickVertexShaderSource : pickVertexShaderSource, + _pickFragmentShaderSource : pickFragmentShaderSource, + _uniformMap : uniformMap, + _pickUniformMap : pickUniformMap, + _modelMatrix : new Matrix4(), // updated in update() + _boundingSphere : boundingSphere // used to update boundingVolume + }); + + // Release CPU resources + model._buffers = undefined; + model._vertexArray = undefined; + model._shaderProgram = undefined; + model._pickShaderProgram = undefined; + model._uniformMap = undefined; + } + + function createRuntimeNodes(model) { + var loadResources = model._loadResources; + if (!loadResources.finished()) { + return; + } - // So if sourceUri isn't the kmz file, then its another kml in the archive, so resolve it - if (!/\.kmz/i.test(sourceUri)) { - newSourceUri = getAbsoluteUri(newSourceUri, sourceUri); - } - } else { - newSourceUri = href; // Not a data uri so use the fully qualified uri - viewRefreshMode = queryStringValue(link, 'viewRefreshMode', namespaces.kml); - viewBoundScale = defaultValue(queryStringValue(link, 'viewBoundScale', namespaces.kml), 1.0); - var defaultViewFormat = (viewRefreshMode === 'onStop') ? 'BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]' : ''; - var viewFormat = defaultValue(queryStringValue(link, 'viewFormat', namespaces.kml), defaultViewFormat); - var httpQuery = queryStringValue(link, 'httpQuery', namespaces.kml); - queryString = makeQueryString(viewFormat, httpQuery); + if (defined(model._primitive)) { + return; + } - linkUrl = processNetworkLinkQueryString(dataSource._camera, dataSource._canvas, joinUrls(href, queryString, false), - viewBoundScale, dataSource._lastCameraView.bbox); - } + var gltf = model.gltf; + var nodes = gltf.nodes; + var gltfNode = nodes[0]; + model._nodeMatrix = ModelUtility.getTransform(gltfNode, model._nodeMatrix); - var options = { - sourceUri : newSourceUri, - uriResolver : uriResolver, - context : networkEntity.id - }; - var networkLinkCollection = new EntityCollection(); - var promise = load(dataSource, networkLinkCollection, linkUrl, options).then(function(rootElement) { - var entities = dataSource._entityCollection; - var newEntities = networkLinkCollection.values; - entities.suspendEvents(); - for (var i = 0; i < newEntities.length; i++) { - var newEntity = newEntities[i]; - if (!defined(newEntity.parent)) { - newEntity.parent = networkEntity; - mergeAvailabilityWithParent(newEntity); - } + createPrimitive(model); + } - entities.add(newEntity); - } - entities.resumeEvents(); + function createResources(model, frameState) { + var context = frameState.context; - // Add network links to a list if we need they will need to be updated - var refreshMode = queryStringValue(link, 'refreshMode', namespaces.kml); - var refreshInterval = defaultValue(queryNumericValue(link, 'refreshInterval', namespaces.kml), 0); - if ((refreshMode === 'onInterval' && refreshInterval > 0 ) || (refreshMode === 'onExpire') || (viewRefreshMode === 'onStop')) { - var networkLinkControl = queryFirstNode(rootElement, 'NetworkLinkControl', namespaces.kml); - var hasNetworkLinkControl = defined(networkLinkControl); + ModelUtility.checkSupportedGlExtensions(model.gltf.glExtensionsUsed, context); + createBuffers(model); // using glTF bufferViews + createProgram(model); + createVertexArray(model); // using glTF meshes + createUniformMap(model, context); // using glTF materials/techniques + createRuntimeNodes(model); // using glTF scene + } - var now = JulianDate.now(); - var networkLinkInfo = { - id : createGuid(), - href : href, - cookie : '', - queryString : queryString, - lastUpdated : now, - updating : false, - entity : networkEntity, - viewBoundScale : viewBoundScale, - needsUpdate : false, - cameraUpdateTime : now - }; + /////////////////////////////////////////////////////////////////////////// - var minRefreshPeriod = 0; - if (hasNetworkLinkControl) { - networkLinkInfo.cookie = defaultValue(queryStringValue(networkLinkControl, 'cookie', namespaces.kml), ''); - minRefreshPeriod = defaultValue(queryNumericValue(networkLinkControl, 'minRefreshPeriod', namespaces.kml), 0); - } + var scratchComputedTranslation = new Cartesian4(); + var scratchComputedMatrixIn2D = new Matrix4(); - if (refreshMode === 'onInterval') { - if (hasNetworkLinkControl) { - refreshInterval = Math.max(minRefreshPeriod, refreshInterval); - } - networkLinkInfo.refreshMode = RefreshMode.INTERVAL; - networkLinkInfo.time = refreshInterval; - } else if (refreshMode === 'onExpire') { - var expires; - if (hasNetworkLinkControl) { - expires = queryStringValue(networkLinkControl, 'expires', namespaces.kml); - } - if (defined(expires)) { - try { - var date = JulianDate.fromIso8601(expires); - var diff = JulianDate.secondsDifference(date, now); - if (diff > 0 && diff < minRefreshPeriod) { - JulianDate.addSeconds(now, minRefreshPeriod, date); - } - networkLinkInfo.refreshMode = RefreshMode.EXPIRE; - networkLinkInfo.time = date; - } catch (e) { - oneTimeWarning('kml-refreshMode-onInterval-onExpire', 'KML - NetworkLinkControl expires is not a valid date'); - } - } else { - oneTimeWarning('kml-refreshMode-onExpire', 'KML - refreshMode of onExpire requires the NetworkLinkControl to have an expires element'); - } - } else if (dataSource._camera) { // Only allow onStop refreshes if we have a camera - networkLinkInfo.refreshMode = RefreshMode.STOP; - networkLinkInfo.time = defaultValue(queryNumericValue(link, 'viewRefreshTime', namespaces.kml), 0); - } else { - oneTimeWarning('kml-refrehMode-onStop-noCamera', 'A NetworkLink with viewRefreshMode=onStop requires a camera be passed in when creating the KmlDataSource'); - } + function updateNodeModelMatrix(model, modelTransformChanged, justLoaded, projection) { + var computedModelMatrix = model._computedModelMatrix; - if (defined(networkLinkInfo.refreshMode)) { - dataSource._networkLinks.set(networkLinkInfo.id, networkLinkInfo); - } - } else if (viewRefreshMode === 'onRegion') { - oneTimeWarning('kml-refrehMode-onRegion', 'KML - Unsupported viewRefreshMode: onRegion'); - } - }).otherwise(function(error) { - oneTimeWarning('An error occured during loading ' + linkUrl); - }); + if ((model._mode !== SceneMode.SCENE3D) && !model._ignoreCommands) { + var translation = Matrix4.getColumn(computedModelMatrix, 3, scratchComputedTranslation); + if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) { + computedModelMatrix = Transforms.basisTo2D(projection, computedModelMatrix, scratchComputedMatrixIn2D); + model._rtcCenter = model._rtcCenter3D; + } else { + var center = model.boundingSphere.center; + var to2D = Transforms.wgs84To2DModelMatrix(projection, center, scratchComputedMatrixIn2D); + computedModelMatrix = Matrix4.multiply(to2D, computedModelMatrix, scratchComputedMatrixIn2D); - promises.push(promise); + if (defined(model._rtcCenter)) { + Matrix4.setTranslation(computedModelMatrix, Cartesian4.UNIT_W, computedModelMatrix); + model._rtcCenter = model._rtcCenter2D; + } } } - } - function processFeatureNode(dataSource, node, parent, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query) { - var featureProcessor = featureTypes[node.localName]; - if (defined(featureProcessor)) { - featureProcessor(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - } else { - processUnsupportedFeature(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver, promises, context); + var primitive = model._primitive; + + if (modelTransformChanged || justLoaded) { + Matrix4.multiplyTransformation(computedModelMatrix, model._nodeMatrix, primitive._modelMatrix); + BoundingSphere.transform(primitive._boundingSphere, primitive._modelMatrix, primitive._boundingVolume); + + if (defined(model._rtcCenter)) { + Cartesian3.add(model._rtcCenter, primitive._boundingVolume.center, primitive._boundingVolume.center); + } } } - function loadKml(dataSource, entityCollection, kml, sourceUri, uriResolver, context, query) { - entityCollection.removeAll(); + /////////////////////////////////////////////////////////////////////////// - var promises = []; - var documentElement = kml.documentElement; - var document = documentElement.localName === 'Document' ? documentElement : queryFirstNode(documentElement, 'Document', namespaces.kml); - var name = queryStringValue(document, 'name', namespaces.kml); - if (!defined(name) && defined(sourceUri)) { - name = getFilenameFromUri(sourceUri); - } + ClassificationModel.prototype.updateCommands = function(batchId, color) { + this._primitive.updateCommands(batchId, color); + }; - // Only set the name from the root document - if (!defined(dataSource._name)) { - dataSource._name = name; + ClassificationModel.prototype.update = function(frameState) { + if (frameState.mode === SceneMode.MORPHING) { + return; } - var styleCollection = new EntityCollection(dataSource); - return when.all(processStyles(dataSource, kml, styleCollection, sourceUri, false, uriResolver, query)).then(function() { - var element = kml.documentElement; - if (element.localName === 'kml') { - var childNodes = element.childNodes; - for (var i = 0; i < childNodes.length; i++) { - var tmp = childNodes[i]; - if (defined(featureTypes[tmp.localName])) { - element = tmp; - break; - } - } - } - entityCollection.suspendEvents(); - processFeatureNode(dataSource, element, undefined, entityCollection, styleCollection, sourceUri, uriResolver, promises, context, query); - entityCollection.resumeEvents(); + if ((this._state === ModelState.NEEDS_LOAD) && defined(this.gltf)) { + this._state = ModelState.LOADING; + if (this._state !== ModelState.FAILED) { + var extensions = this.gltf.extensions; + if (defined(extensions) && defined(extensions.CESIUM_RTC)) { + var center = Cartesian3.fromArray(extensions.CESIUM_RTC.center); + if (!Cartesian3.equals(center, Cartesian3.ZERO)) { + this._rtcCenter3D = center; - return when.all(promises).then(function() { - return kml.documentElement; - }); - }); - } + var projection = frameState.mapProjection; + var ellipsoid = projection.ellipsoid; + var cartographic = ellipsoid.cartesianToCartographic(this._rtcCenter3D); + var projectedCart = projection.project(cartographic); + Cartesian3.fromElements(projectedCart.z, projectedCart.x, projectedCart.y, projectedCart); + this._rtcCenter2D = projectedCart; - function loadKmz(dataSource, entityCollection, blob, sourceUri) { - var deferred = when.defer(); - zip.createReader(new zip.BlobReader(blob), function(reader) { - reader.getEntries(function(entries) { - var promises = []; - var uriResolver = {}; - var docEntry; - var docDefer; - for (var i = 0; i < entries.length; i++) { - var entry = entries[i]; - if (!entry.directory) { - var innerDefer = when.defer(); - promises.push(innerDefer.promise); - if (/\.kml$/i.test(entry.filename)) { - // We use the first KML document we come across - // https://developers.google.com/kml/documentation/kmzarchives - // Unless we come across a .kml file at the root of the archive because GE does this - if (!defined(docEntry) || !/\//i.test(entry.filename)) { - if (defined(docEntry)) { - // We found one at the root so load the initial kml as a data uri - loadDataUriFromZip(reader, docEntry, uriResolver, docDefer); - } - docEntry = entry; - docDefer = innerDefer; - } else { - // Wasn't the first kml and wasn't at the root - loadDataUriFromZip(reader, entry, uriResolver, innerDefer); - } - } else { - loadDataUriFromZip(reader, entry, uriResolver, innerDefer); - } + this._rtcCenterEye = new Cartesian3(); + this._rtcCenter = this._rtcCenter3D; } } - // Now load the root KML document - if (defined(docEntry)) { - loadXmlFromZip(reader, docEntry, uriResolver, docDefer); - } - when.all(promises).then(function() { - reader.close(); - if (!defined(uriResolver.kml)) { - deferred.reject(new RuntimeError('KMZ file does not contain a KML document.')); - return; - } - uriResolver.keys = Object.keys(uriResolver); - return loadKml(dataSource, entityCollection, uriResolver.kml, sourceUri, uriResolver); - }).then(deferred.resolve).otherwise(deferred.reject); - }); - }, function(e) { - deferred.reject(e); - }); + this._loadResources = new ModelLoadResources(); + parseBuffers(this); + } + } - return deferred.promise; - } + var loadResources = this._loadResources; + var justLoaded = false; - function load(dataSource, entityCollection, data, options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var sourceUri = options.sourceUri; - var uriResolver = options.uriResolver; - var context = options.context; - var query = defined(options.query) ? objectToQuery(options.query) : undefined; + if (this._state === ModelState.LOADING) { + // Transition from LOADING -> LOADED once resources are downloaded and created. + // Textures may continue to stream in while in the LOADED state. + if (loadResources.pendingBufferLoads === 0) { + ModelUtility.checkSupportedExtensions(this.extensionsRequired); - var promise = data; - if (typeof data === 'string') { - promise = loadBlob(proxyUrl(data, dataSource._proxy, query)); - sourceUri = defaultValue(sourceUri, data); + addBuffersToLoadResources(this); + parseBufferViews(this); + + this._boundingSphere = computeBoundingSphere(this); + this._initialRadius = this._boundingSphere.radius; + createResources(this, frameState); + } + if (loadResources.finished()) { + this._state = ModelState.LOADED; + justLoaded = true; + } } - return when(promise) - .then(function(dataToLoad) { - if (dataToLoad instanceof Blob) { - return isZipFile(dataToLoad).then(function(isZip) { - if (isZip) { - return loadKmz(dataSource, entityCollection, dataToLoad, sourceUri); - } - return readBlobAsText(dataToLoad).then(function(text) { - //There's no official way to validate if a parse was successful. - //The following check detects the error on various browsers. + if (defined(loadResources) && (this._state === ModelState.LOADED)) { + if (!justLoaded) { + createResources(this, frameState); + } - //Insert missing namespaces - text = insertNamespaces(text); + if (loadResources.finished()) { + this._loadResources = undefined; // Clear CPU memory since WebGL resources were created. + } + } - //Remove Duplicate Namespaces - text = removeDuplicateNamespaces(text); + var show = this.show; - //IE raises an exception - var kml; - var error; - try { - kml = parser.parseFromString(text, 'application/xml'); - } catch (e) { - error = e.toString(); - } + if ((show && this._state === ModelState.LOADED) || justLoaded) { + this._dirty = false; + var modelMatrix = this.modelMatrix; - //The parse succeeds on Chrome and Firefox, but the error - //handling is different in each. - if (defined(error) || kml.body || kml.documentElement.tagName === 'parsererror') { - //Firefox has error information as the firstChild nodeValue. - var msg = defined(error) ? error : kml.documentElement.firstChild.nodeValue; + var modeChanged = frameState.mode !== this._mode; + this._mode = frameState.mode; - //Chrome has it in the body text. - if (!msg) { - msg = kml.body.innerText; - } + // ClassificationModel's model matrix needs to be updated + var modelTransformChanged = !Matrix4.equals(this._modelMatrix, modelMatrix) || modeChanged; - //Return the error - throw new RuntimeError(msg); - } - return loadKml(dataSource, entityCollection, kml, sourceUri, uriResolver, context, query); - }); - }); + if (modelTransformChanged || justLoaded) { + Matrix4.clone(modelMatrix, this._modelMatrix); + + var computedModelMatrix = this._computedModelMatrix; + Matrix4.clone(modelMatrix, computedModelMatrix); + if (this._upAxis === Axis.Y) { + Matrix4.multiplyTransformation(computedModelMatrix, Axis.Y_UP_TO_Z_UP, computedModelMatrix); + } else if (this._upAxis === Axis.X) { + Matrix4.multiplyTransformation(computedModelMatrix, Axis.X_UP_TO_Z_UP, computedModelMatrix); } - return loadKml(dataSource, entityCollection, dataToLoad, sourceUri, uriResolver, context, query); - }) - .otherwise(function(error) { - dataSource._error.raiseEvent(dataSource, error); - console.log(error); - return when.reject(error); + } + + // Update modelMatrix throughout the graph as needed + if (modelTransformChanged || justLoaded) { + updateNodeModelMatrix(this, modelTransformChanged, justLoaded, frameState.mapProjection); + this._dirty = true; + } + } + + if (justLoaded) { + // Called after modelMatrix update. + var model = this; + frameState.afterRender.push(function() { + model._ready = true; + model._readyPromise.resolve(model); }); + return; + } + + if (show && !this._ignoreCommands) { + this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; + this._primitive.debugWireframe = this.debugWireframe; + this._primitive.update(frameState); + } + }; + + ClassificationModel.prototype.isDestroyed = function() { + return false; + }; + + ClassificationModel.prototype.destroy = function() { + this._primitive = this._primitive && this._primitive.destroy(); + return destroyObject(this); + }; + + return ClassificationModel; +}); + +define('Scene/Batched3DModel3DTileContent',[ + '../Core/ClippingPlaneCollection', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/FeatureDetection', + '../Core/getBaseUri', + '../Core/getStringFromTypedArray', + '../Core/RequestType', + '../Core/RuntimeError', + '../Renderer/Pass', + './Cesium3DTileBatchTable', + './Cesium3DTileFeature', + './Cesium3DTileFeatureTable', + './ClassificationModel', + './Model', + './ModelUtility' + ], function( + ClippingPlaneCollection, + Color, + defaultValue, + defined, + defineProperties, + deprecationWarning, + destroyObject, + DeveloperError, + FeatureDetection, + getBaseUri, + getStringFromTypedArray, + RequestType, + RuntimeError, + Pass, + Cesium3DTileBatchTable, + Cesium3DTileFeature, + Cesium3DTileFeatureTable, + ClassificationModel, + Model, + ModelUtility) { + 'use strict'; + + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; } /** - * A {@link DataSource} which processes Keyhole Markup Language 2.2 (KML). - * <p> - * KML support in Cesium is incomplete, but a large amount of the standard, - * as well as Google's <code>gx</code> extension namespace, is supported. See Github issue - * {@link https://github.com/AnalyticalGraphicsInc/cesium/issues/873|#873} for a - * detailed list of what is and isn't support. Cesium will also write information to the - * console when it encounters most unsupported features. - * </p> + * Represents the contents of a + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md|Batched 3D Model} + * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. * <p> - * Non visual feature data, such as <code>atom:author</code> and <code>ExtendedData</code> - * is exposed via an instance of {@link KmlFeatureData}, which is added to each {@link Entity} - * under the <code>kml</code> property. + * Implements the {@link Cesium3DTileContent} interface. * </p> * - * @alias KmlDataSource + * @alias Batched3DModel3DTileContent * @constructor * - * @param {Object} options An object with the following properties: - * @param {Camera} options.camera The camera that is used for viewRefreshModes and sending camera properties to network links. - * @param {Canvas} options.canvas The canvas that is used for sending viewer properties to network links. - * @param {DefaultProxy} [options.proxy] A proxy to be used for loading external data. - * - * @see {@link http://www.opengeospatial.org/standards/kml/|Open Geospatial Consortium KML Standard} - * @see {@link https://developers.google.com/kml/|Google KML Documentation} - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=KML.html|Cesium Sandcastle KML Demo} - * - * @example - * var viewer = new Cesium.Viewer('cesiumContainer'); - * viewer.dataSources.add(Cesium.KmlDataSource.load('../../SampleData/facilities.kmz', - * { - * camera: viewer.scene.camera, - * canvas: viewer.scene.canvas - * }) - * ); + * @private */ - function KmlDataSource(options) { - options = defaultValue(options, {}); - var camera = options.camera; - var canvas = options.canvas; - - if (!defined(camera)) { - throw new DeveloperError('options.camera is required.'); - } - if (!defined(canvas)) { - throw new DeveloperError('options.canvas is required.'); - } - - this._changed = new Event(); - this._error = new Event(); - this._loading = new Event(); - this._refresh = new Event(); - this._unsupportedNode = new Event(); + function Batched3DModel3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { + this._tileset = tileset; + this._tile = tile; + this._resource = resource; + this._model = undefined; + this._batchTable = undefined; + this._features = undefined; - this._clock = undefined; - this._entityCollection = new EntityCollection(this); - this._name = undefined; - this._isLoading = false; - this._proxy = options.proxy; - this._pinBuilder = new PinBuilder(); - this._networkLinks = new AssociativeArray(); - this._entityCluster = new EntityCluster(); + /** + * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + */ + this.featurePropertiesDirty = false; - this._canvas = canvas; - this._camera = camera; - this._lastCameraView = { - position : defined(camera) ? Cartesian3.clone(camera.positionWC) : undefined, - direction : defined(camera) ? Cartesian3.clone(camera.directionWC) : undefined, - up : defined(camera) ? Cartesian3.clone(camera.upWC) : undefined, - bbox : defined(camera) ? camera.computeViewRectangle() : Rectangle.clone(Rectangle.MAX_VALUE) - }; + initialize(this, arrayBuffer, byteOffset); } - /** - * Creates a Promise to a new instance loaded with the provided KML data. - * - * @param {String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. - * @param {Object} options An object with the following properties: - * @param {Camera} options.camera The camera that is used for viewRefreshModes and sending camera properties to network links. - * @param {Canvas} options.canvas The canvas that is used for sending viewer properties to network links. - * @param {DefaultProxy} [options.proxy] A proxy to be used for loading external data. - * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links and other KML network features. - * @param {Boolean} [options.clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. If true, lines will use corridors so use Entity.corridor instead of Entity.polyline. - * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. - * - * @returns {Promise.<KmlDataSource>} A promise that will resolve to a new KmlDataSource instance once the KML is loaded. - */ - KmlDataSource.load = function(data, options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var dataSource = new KmlDataSource(options); - return dataSource.load(data, options); - }; + // This can be overridden for testing purposes + Batched3DModel3DTileContent._deprecationWarning = deprecationWarning; - defineProperties(KmlDataSource.prototype, { + defineProperties(Batched3DModel3DTileContent.prototype, { /** - * Gets or sets a human-readable name for this instance. - * This will be automatically be set to the KML document name on load. - * @memberof KmlDataSource.prototype - * @type {String} + * @inheritdoc Cesium3DTileContent#featuresLength */ - name : { + featuresLength : { get : function() { - return this._name; - }, - set : function(value) { - if (this._name !== value) { - this._name = value; - this._changed.raiseEvent(this); - } + return this._batchTable.featuresLength; } }, + /** - * Gets the clock settings defined by the loaded KML. This represents the total - * availability interval for all time-dynamic data. If the KML does not contain - * time-dynamic data, this value is undefined. - * @memberof KmlDataSource.prototype - * @type {DataSourceClock} + * @inheritdoc Cesium3DTileContent#pointsLength */ - clock : { + pointsLength : { get : function() { - return this._clock; + return 0; } }, + /** - * Gets the collection of {@link Entity} instances. - * @memberof KmlDataSource.prototype - * @type {EntityCollection} + * @inheritdoc Cesium3DTileContent#trianglesLength */ - entities : { + trianglesLength : { get : function() { - return this._entityCollection; + return this._model.trianglesLength; } }, + /** - * Gets a value indicating if the data source is currently loading data. - * @memberof KmlDataSource.prototype - * @type {Boolean} + * @inheritdoc Cesium3DTileContent#geometryByteLength */ - isLoading : { + geometryByteLength : { get : function() { - return this._isLoading; + return this._model.geometryByteLength; } }, + /** - * Gets an event that will be raised when the underlying data changes. - * @memberof KmlDataSource.prototype - * @type {Event} + * @inheritdoc Cesium3DTileContent#texturesByteLength */ - changedEvent : { + texturesByteLength : { get : function() { - return this._changed; + return this._model.texturesByteLength; } }, + /** - * Gets an event that will be raised if an error is encountered during processing. - * @memberof KmlDataSource.prototype - * @type {Event} + * @inheritdoc Cesium3DTileContent#batchTableByteLength */ - errorEvent : { + batchTableByteLength : { get : function() { - return this._error; + return this._batchTable.memorySizeInBytes; } }, + /** - * Gets an event that will be raised when the data source either starts or stops loading. - * @memberof KmlDataSource.prototype - * @type {Event} + * @inheritdoc Cesium3DTileContent#innerContents */ - loadingEvent : { + innerContents : { get : function() { - return this._loading; + return undefined; } }, + /** - * Gets an event that will be raised when the data source refreshes a network link. - * @memberof KmlDataSource.prototype - * @type {Event} + * @inheritdoc Cesium3DTileContent#readyPromise */ - refreshEvent : { + readyPromise : { get : function() { - return this._refresh; + return this._model.readyPromise; } }, + /** - * Gets an event that will be raised when the data source finds an unsupported node type. - * @memberof KmlDataSource.prototype - * @type {Event} + * @inheritdoc Cesium3DTileContent#tileset */ - unsupportedNodeEvent : { + tileset : { get : function() { - return this._unsupportedNode; + return this._tileset; } }, + /** - * Gets whether or not this data source should be displayed. - * @memberof KmlDataSource.prototype - * @type {Boolean} + * @inheritdoc Cesium3DTileContent#tile */ - show : { + tile : { get : function() { - return this._entityCollection.show; - }, - set : function(value) { - this._entityCollection.show = value; + return this._tile; } }, /** - * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. - * - * @memberof KmlDataSource.prototype - * @type {EntityCluster} + * @inheritdoc Cesium3DTileContent#url */ - clustering : { + url: { + get: function() { + return this._resource.getUrlComponent(true); + } + }, + + /** + * @inheritdoc Cesium3DTileContent#batchTable + */ + batchTable : { get : function() { - return this._entityCluster; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value must be defined.'); - } - this._entityCluster = value; + return this._batchTable; } } }); - /** - * Asynchronously loads the provided KML data, replacing any existing data. - * - * @param {String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.sourceUri] Overrides the url to use for resolving relative links and other KML network features. - * @returns {Promise.<KmlDataSource>} A promise that will resolve to this instances once the KML is loaded. - * @param {Boolean} [options.clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. If true, lines will use corridors so use Entity.corridor instead of Entity.polyline. - * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. - */ - KmlDataSource.prototype.load = function(data, options) { - if (!defined(data)) { - throw new DeveloperError('data is required.'); - } - - options = defaultValue(options, {}); - DataSource.setLoading(this, true); - - var oldName = this._name; - this._name = undefined; - this._clampToGround = defaultValue(options.clampToGround, false); - - var that = this; - return load(this, this._entityCollection, data, options).then(function() { - var clock; - - var availability = that._entityCollection.computeAvailability(); - - var start = availability.start; - var stop = availability.stop; - var isMinStart = JulianDate.equals(start, Iso8601.MINIMUM_VALUE); - var isMaxStop = JulianDate.equals(stop, Iso8601.MAXIMUM_VALUE); - if (!isMinStart || !isMaxStop) { - var date; - - //If start is min time just start at midnight this morning, local time - if (isMinStart) { - date = new Date(); - date.setHours(0, 0, 0, 0); - start = JulianDate.fromDate(date); - } - - //If stop is max value just stop at midnight tonight, local time - if (isMaxStop) { - date = new Date(); - date.setHours(24, 0, 0, 0); - stop = JulianDate.fromDate(date); - } - - clock = new DataSourceClock(); - clock.startTime = start; - clock.stopTime = stop; - clock.currentTime = JulianDate.clone(start); - clock.clockRange = ClockRange.LOOP_STOP; - clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; - clock.multiplier = Math.round(Math.min(Math.max(JulianDate.secondsDifference(stop, start) / 60, 1), 3.15569e7)); - } + var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - var changed = false; - if (clock !== that._clock) { - that._clock = clock; - changed = true; + function getBatchIdAttributeName(gltf) { + var batchIdAttributeName = ModelUtility.getAttributeOrUniformBySemantic(gltf, '_BATCHID'); + if (!defined(batchIdAttributeName)) { + batchIdAttributeName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'BATCHID'); + if (defined(batchIdAttributeName)) { + Batched3DModel3DTileContent._deprecationWarning('b3dm-legacy-batchid', 'The glTF in this b3dm uses the semantic `BATCHID`. Application-specific semantics should be prefixed with an underscore: `_BATCHID`.'); } + } + return batchIdAttributeName; + } - if (oldName !== that._name) { - changed = true; - } + function getVertexShaderCallback(content) { + return function(vs, programId) { + var batchTable = content._batchTable; + var gltf = content._model.gltf; + var handleTranslucent = !defined(content._tileset.classificationType); + var batchIdAttributeName = getBatchIdAttributeName(gltf); + var diffuseAttributeOrUniformName = ModelUtility.getDiffuseAttributeOrUniform(gltf, programId); + var callback = batchTable.getVertexShaderCallback(handleTranslucent, batchIdAttributeName, diffuseAttributeOrUniformName); + return defined(callback) ? callback(vs) : vs; + }; + } - if (changed) { - that._changed.raiseEvent(that); - } + function getPickVertexShaderCallback(content) { + return function(vs) { + var batchTable = content._batchTable; + var gltf = content._model.gltf; + var batchIdAttributeName = getBatchIdAttributeName(gltf); + var callback = batchTable.getPickVertexShaderCallback(batchIdAttributeName); + return defined(callback) ? callback(vs) : vs; + }; + } - DataSource.setLoading(that, false); + function getFragmentShaderCallback(content) { + return function(fs, programId) { + var batchTable = content._batchTable; + var gltf = content._model.gltf; + var handleTranslucent = !defined(content._tileset.classificationType); + var diffuseAttributeOrUniformName = ModelUtility.getDiffuseAttributeOrUniform(gltf, programId); + var callback = batchTable.getFragmentShaderCallback(handleTranslucent, diffuseAttributeOrUniformName); + return defined(callback) ? callback(fs) : fs; + }; + } - return that; - }).otherwise(function(error) { - DataSource.setLoading(that, false); - that._error.raiseEvent(that, error); - console.log(error); - return when.reject(error); - }); - }; + function getClassificationFragmentShaderCallback(content) { + return function(fs) { + var batchTable = content._batchTable; + var callback = batchTable.getClassificationFragmentShaderCallback(); + return defined(callback) ? callback(fs) : fs; + }; + } - function mergeAvailabilityWithParent(child) { - var parent = child.parent; - if (defined(parent)) { - var parentAvailability = parent.availability; - if (defined(parentAvailability)) { - var childAvailability = child.availability; - if (defined(childAvailability)) { - childAvailability.intersect(parentAvailability); - } else { - child.availability = parentAvailability; - } - } - } + function createColorChangedCallback(content) { + return function(batchId, color) { + content._model.updateCommands(batchId, color); + }; } - function getNetworkLinkUpdateCallback(dataSource, networkLink, newEntityCollection, networkLinks, processedHref) { - return function(rootElement) { - if (!networkLinks.contains(networkLink.id)) { - // Got into the odd case where a parent network link was updated while a child - // network link update was in flight, so just throw it away. - return; - } - var remove = false; - var networkLinkControl = queryFirstNode(rootElement, 'NetworkLinkControl', namespaces.kml); - var hasNetworkLinkControl = defined(networkLinkControl); + function initialize(content, arrayBuffer, byteOffset) { + var tileset = content._tileset; + var tile = content._tile; + var resource = content._resource; - var minRefreshPeriod = 0; - if (hasNetworkLinkControl) { - if (defined(queryFirstNode(networkLinkControl, 'Update', namespaces.kml))) { - oneTimeWarning('kml-networkLinkControl-update', 'KML - NetworkLinkControl updates aren\'t supported.'); - networkLink.updating = false; - networkLinks.remove(networkLink.id); - return; - } - networkLink.cookie = defaultValue(queryStringValue(networkLinkControl, 'cookie', namespaces.kml), ''); - minRefreshPeriod = defaultValue(queryNumericValue(networkLinkControl, 'minRefreshPeriod', namespaces.kml), 0); - } + var byteStart = defaultValue(byteOffset, 0); + byteOffset = byteStart; - var now = JulianDate.now(); - var refreshMode = networkLink.refreshMode; - if (refreshMode === RefreshMode.INTERVAL) { - if (defined(networkLinkControl)) { - networkLink.time = Math.max(minRefreshPeriod, networkLink.time); - } - } else if (refreshMode === RefreshMode.EXPIRE) { - var expires; - if (defined(networkLinkControl)) { - expires = queryStringValue(networkLinkControl, 'expires', namespaces.kml); - } - if (defined(expires)) { - try { - var date = JulianDate.fromIso8601(expires); - var diff = JulianDate.secondsDifference(date, now); - if (diff > 0 && diff < minRefreshPeriod) { - JulianDate.addSeconds(now, minRefreshPeriod, date); - } - networkLink.time = date; - } catch (e) { - oneTimeWarning('kml-networkLinkControl-expires', 'KML - NetworkLinkControl expires is not a valid date'); - remove = true; - } - } else { - oneTimeWarning('kml-refreshMode-onExpire', 'KML - refreshMode of onExpire requires the NetworkLinkControl to have an expires element'); - remove = true; - } - } + var uint8Array = new Uint8Array(arrayBuffer); + var view = new DataView(arrayBuffer); + byteOffset += sizeOfUint32; // Skip magic - var networkLinkEntity = networkLink.entity; - var entityCollection = dataSource._entityCollection; - var newEntities = newEntityCollection.values; + var version = view.getUint32(byteOffset, true); + if (version !== 1) { + throw new RuntimeError('Only Batched 3D Model version 1 is supported. Version ' + version + ' is not.'); + } + byteOffset += sizeOfUint32; - function removeChildren(entity) { - entityCollection.remove(entity); - var children = entity._children; - var count = children.length; - for (var i = 0; i < count; ++i) { - removeChildren(children[i]); - } - } + var byteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - // Remove old entities - entityCollection.suspendEvents(); - var entitiesCopy = entityCollection.values.slice(); - var i; - for (i = 0; i < entitiesCopy.length; ++i) { - var entityToRemove = entitiesCopy[i]; - if (entityToRemove.parent === networkLinkEntity) { - entityToRemove.parent = undefined; - removeChildren(entityToRemove); - } - } - entityCollection.resumeEvents(); + var featureTableJsonByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - // Add new entities - entityCollection.suspendEvents(); - for (i = 0; i < newEntities.length; i++) { - var newEntity = newEntities[i]; - if (!defined(newEntity.parent)) { - newEntity.parent = networkLinkEntity; - mergeAvailabilityWithParent(newEntity); - } - entityCollection.add(newEntity); - } - entityCollection.resumeEvents(); + var featureTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - // No refresh information remove it, otherwise update lastUpdate time - if (remove) { - networkLinks.remove(networkLink.id); - } else { - networkLink.lastUpdated = now; - } + var batchTableJsonByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - var availability = entityCollection.computeAvailability(); + var batchTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - var start = availability.start; - var stop = availability.stop; - var isMinStart = JulianDate.equals(start, Iso8601.MINIMUM_VALUE); - var isMaxStop = JulianDate.equals(stop, Iso8601.MAXIMUM_VALUE); - if (!isMinStart || !isMaxStop) { - var clock = dataSource._clock; + var batchLength; - if (clock.startTime !== start || clock.stopTime !== stop) { - clock.startTime = start; - clock.stopTime = stop; - dataSource._changed.raiseEvent(dataSource); - } - } + // Legacy header #1: [batchLength] [batchTableByteLength] + // Legacy header #2: [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength] + // Current header: [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] + // If the header is in the first legacy format 'batchTableJsonByteLength' will be the start of the JSON string (a quotation mark) or the glTF magic. + // Accordingly its first byte will be either 0x22 or 0x67, and so the minimum uint32 expected is 0x22000000 = 570425344 = 570MB. It is unlikely that the feature table JSON will exceed this length. + // The check for the second legacy format is similar, except it checks 'batchTableBinaryByteLength' instead + if (batchTableJsonByteLength >= 570425344) { + // First legacy check + byteOffset -= sizeOfUint32 * 2; + batchLength = featureTableJsonByteLength; + batchTableJsonByteLength = featureTableBinaryByteLength; + batchTableBinaryByteLength = 0; + featureTableJsonByteLength = 0; + featureTableBinaryByteLength = 0; + Batched3DModel3DTileContent._deprecationWarning('b3dm-legacy-header', 'This b3dm header is using the legacy format [batchLength] [batchTableByteLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.'); + } else if (batchTableBinaryByteLength >= 570425344) { + // Second legacy check + byteOffset -= sizeOfUint32; + batchLength = batchTableJsonByteLength; + batchTableJsonByteLength = featureTableJsonByteLength; + batchTableBinaryByteLength = featureTableBinaryByteLength; + featureTableJsonByteLength = 0; + featureTableBinaryByteLength = 0; + Batched3DModel3DTileContent._deprecationWarning('b3dm-legacy-header', 'This b3dm header is using the legacy format [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.'); + } - networkLink.updating = false; - networkLink.needsUpdate = false; - dataSource._refresh.raiseEvent(dataSource, processedHref); - }; - } + var featureTableJson; + if (featureTableJsonByteLength === 0) { + featureTableJson = { + BATCH_LENGTH : defaultValue(batchLength, 0) + }; + } else { + var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength); + featureTableJson = JSON.parse(featureTableString); + byteOffset += featureTableJsonByteLength; + } - var entitiesToIgnore = new AssociativeArray(); + var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); + byteOffset += featureTableBinaryByteLength; - /** - * Updates any NetworkLink that require updating - * @function - * - * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. - */ - KmlDataSource.prototype.update = function(time) { - var networkLinks = this._networkLinks; - if (networkLinks.length === 0) { - return true; - } + var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); - var now = JulianDate.now(); - var that = this; + batchLength = featureTable.getGlobalProperty('BATCH_LENGTH'); + featureTable.featuresLength = batchLength; - entitiesToIgnore.removeAll(); + var batchTableJson; + var batchTableBinary; + if (batchTableJsonByteLength > 0) { + // PERFORMANCE_IDEA: is it possible to allocate this on-demand? Perhaps keep the + // arraybuffer/string compressed in memory and then decompress it when it is first accessed. + // + // We could also make another request for it, but that would make the property set/get + // API async, and would double the number of numbers in some cases. + var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength); + batchTableJson = JSON.parse(batchTableString); + byteOffset += batchTableJsonByteLength; - function recurseIgnoreEntities(entity) { - var children = entity._children; - var count = children.length; - for (var i = 0; i < count; ++i) { - var child = children[i]; - entitiesToIgnore.set(child.id, child); - recurseIgnoreEntities(child); + if (batchTableBinaryByteLength > 0) { + // Has a batch table binary + batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); + // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed + batchTableBinary = new Uint8Array(batchTableBinary); + byteOffset += batchTableBinaryByteLength; } } - var cameraViewUpdate = false; - var lastCameraView = this._lastCameraView; - var camera = this._camera; - if (defined(camera) && - !(camera.positionWC.equalsEpsilon(lastCameraView.position, CesiumMath.EPSILON7) && - camera.directionWC.equalsEpsilon(lastCameraView.direction, CesiumMath.EPSILON7) && - camera.upWC.equalsEpsilon(lastCameraView.up, CesiumMath.EPSILON7))) { - - // Camera has changed so update the last view - lastCameraView.position = Cartesian3.clone(camera.positionWC); - lastCameraView.direction = Cartesian3.clone(camera.directionWC); - lastCameraView.up = Cartesian3.clone(camera.upWC); - lastCameraView.bbox = camera.computeViewRectangle(); - cameraViewUpdate = true; + var colorChangedCallback; + if (defined(tileset.classificationType)) { + colorChangedCallback = createColorChangedCallback(content); } - var newNetworkLinks = new AssociativeArray(); - var changed = false; - networkLinks.values.forEach(function(networkLink) { - var entity = networkLink.entity; - if (entitiesToIgnore.contains(entity.id)) { - return; - } + var batchTable = new Cesium3DTileBatchTable(content, batchLength, batchTableJson, batchTableBinary, colorChangedCallback); + content._batchTable = batchTable; - if (!networkLink.updating) { - var doUpdate = false; - if (networkLink.refreshMode === RefreshMode.INTERVAL) { - if (JulianDate.secondsDifference(now, networkLink.lastUpdated) > networkLink.time) { - doUpdate = true; - } - } - else if (networkLink.refreshMode === RefreshMode.EXPIRE) { - if (JulianDate.greaterThan(now, networkLink.time)) { - doUpdate = true; - } + var gltfByteLength = byteStart + byteLength - byteOffset; + if (gltfByteLength === 0) { + throw new RuntimeError('glTF byte length must be greater than 0.'); + } - } else if (networkLink.refreshMode === RefreshMode.STOP) { - if (cameraViewUpdate) { - networkLink.needsUpdate = true; - networkLink.cameraUpdateTime = now; - } + var gltfView; + if (byteOffset % 4 === 0) { + gltfView = new Uint8Array(arrayBuffer, byteOffset, gltfByteLength); + } else { + // Create a copy of the glb so that it is 4-byte aligned + Batched3DModel3DTileContent._deprecationWarning('b3dm-glb-unaligned', 'The embedded glb is not aligned to a 4-byte boundary.'); + gltfView = new Uint8Array(uint8Array.subarray(byteOffset, byteOffset + gltfByteLength)); + } - if (networkLink.needsUpdate && JulianDate.secondsDifference(now, networkLink.cameraUpdateTime) >= networkLink.time) { - doUpdate = true; - } - } + var pickObject = { + content : content, + primitive : tileset + }; - if (doUpdate) { - recurseIgnoreEntities(entity); - networkLink.updating = true; - var newEntityCollection = new EntityCollection(); - var href = joinUrls(networkLink.href, makeQueryString(networkLink.cookie, networkLink.queryString), false); - href = processNetworkLinkQueryString(that._camera, that._canvas, href, networkLink.viewBoundScale, lastCameraView.bbox); - load(that, newEntityCollection, href, {context : entity.id}) - .then(getNetworkLinkUpdateCallback(that, networkLink, newEntityCollection, newNetworkLinks, href)) - .otherwise(function(error) { - var msg = 'NetworkLink ' + networkLink.href + ' refresh failed: ' + error; - console.log(msg); - that._error.raiseEvent(that, msg); - }); - changed = true; - } + if (!defined(tileset.classificationType)) { + var clippingPlanes; + if (defined(tileset.clippingPlanes)) { + clippingPlanes = tileset.clippingPlanes.clone(); + } else { + clippingPlanes = new ClippingPlaneCollection({ + enabled : false + }); } - newNetworkLinks.set(networkLink.id, networkLink); - }); - if (changed) { - this._networkLinks = newNetworkLinks; - this._changed.raiseEvent(this); + // PERFORMANCE_IDEA: patch the shader on demand, e.g., the first time show/color changes. + // The pick shader still needs to be patched. + content._model = new Model({ + gltf : gltfView, + cull : false, // The model is already culled by 3D Tiles + releaseGltfJson : true, // Models are unique and will not benefit from caching so save memory + opaquePass : Pass.CESIUM_3D_TILE, // Draw opaque portions of the model during the 3D Tiles pass + basePath : resource, + requestType : RequestType.TILES3D, + modelMatrix : tile.computedTransform, + upAxis : tileset._gltfUpAxis, + shadows: tileset.shadows, + debugWireframe: tileset.debugWireframe, + incrementallyLoadTextures : false, + vertexShaderLoaded : getVertexShaderCallback(content), + fragmentShaderLoaded : getFragmentShaderCallback(content), + uniformMapLoaded : batchTable.getUniformMapCallback(), + pickVertexShaderLoaded : getPickVertexShaderCallback(content), + pickFragmentShaderLoaded : batchTable.getPickFragmentShaderCallback(), + pickUniformMapLoaded : batchTable.getPickUniformMapCallback(), + addBatchIdToGeneratedShaders : (batchLength > 0), // If the batch table has values in it, generated shaders will need a batchId attribute + pickObject : pickObject, + clippingPlanes : clippingPlanes + }); + } else { + // This transcodes glTF to an internal representation for geometry so we can take advantage of the re-batching of vector data. + // For a list of limitations on the input glTF, see the documentation for classificationType of Cesium3DTileset. + content._model = new ClassificationModel({ + gltf : gltfView, + cull : false, // The model is already culled by 3D Tiles + basePath : resource, + requestType : RequestType.TILES3D, + modelMatrix : tile.computedTransform, + upAxis : tileset._gltfUpAxis, + debugWireframe : tileset.debugWireframe, + vertexShaderLoaded : getVertexShaderCallback(content), + classificationShaderLoaded : getClassificationFragmentShaderCallback(content), + uniformMapLoaded : batchTable.getUniformMapCallback(), + pickVertexShaderLoaded : getPickVertexShaderCallback(content), + pickFragmentShaderLoaded : batchTable.getPickFragmentShaderCallback(), + pickUniformMapLoaded : batchTable.getPickUniformMapCallback(), + classificationType : tileset._classificationType, + batchTable : batchTable + }); } + } - return true; - }; - - /** - * Contains KML Feature data loaded into the <code>Entity.kml</code> property by {@link KmlDataSource}. - * @alias KmlFeatureData - * @constructor - */ - function KmlFeatureData() { - /** - * Gets the atom syndication format author field. - * @type Object - */ - this.author = { - /** - * Gets the name. - * @type String - * @alias author.name - * @memberof! KmlFeatureData# - * @property author.name - */ - name : undefined, - /** - * Gets the URI. - * @type String - * @alias author.uri - * @memberof! KmlFeatureData# - * @property author.uri - */ - uri : undefined, - /** - * Gets the email. - * @type String - * @alias author.email - * @memberof! KmlFeatureData# - * @property author.email - */ - email : undefined - }; - - /** - * Gets the link. - * @type Object - */ - this.link = { - /** - * Gets the href. - * @type String - * @alias link.href - * @memberof! KmlFeatureData# - * @property link.href - */ - href : undefined, - /** - * Gets the language of the linked resource. - * @type String - * @alias link.hreflang - * @memberof! KmlFeatureData# - * @property link.hreflang - */ - hreflang : undefined, - /** - * Gets the link relation. - * @type String - * @alias link.rel - * @memberof! KmlFeatureData# - * @property link.rel - */ - rel : undefined, - /** - * Gets the link type. - * @type String - * @alias link.type - * @memberof! KmlFeatureData# - * @property link.type - */ - type : undefined, - /** - * Gets the link title. - * @type String - * @alias link.title - * @memberof! KmlFeatureData# - * @property link.title - */ - title : undefined, - /** - * Gets the link length. - * @type String - * @alias link.length - * @memberof! KmlFeatureData# - * @property link.length - */ - length : undefined - }; - - /** - * Gets the unstructured address field. - * @type String - */ - this.address = undefined; - /** - * Gets the phone number. - * @type String - */ - this.phoneNumber = undefined; - /** - * Gets the snippet. - * @type String - */ - this.snippet = undefined; - /** - * Gets the extended data, parsed into a JSON object. - * Currently only the <code>Data</code> property is supported. - * <code>SchemaData</code> and custom data are ignored. - * @type String - */ - this.extendedData = undefined; + function createFeatures(content) { + var featuresLength = content.featuresLength; + if (!defined(content._features) && (featuresLength > 0)) { + var features = new Array(featuresLength); + for (var i = 0; i < featuresLength; ++i) { + features[i] = new Cesium3DTileFeature(content, i); + } + content._features = features; + } } - return KmlDataSource; -}); + /** + * @inheritdoc Cesium3DTileContent#hasProperty + */ + Batched3DModel3DTileContent.prototype.hasProperty = function(batchId, name) { + return this._batchTable.hasProperty(batchId, name); + }; -define('DataSources/Visualizer',[ - '../Core/DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + /** + * @inheritdoc Cesium3DTileContent#getFeature + */ + Batched3DModel3DTileContent.prototype.getFeature = function(batchId) { + var featuresLength = this.featuresLength; + if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); + } + + createFeatures(this); + return this._features[batchId]; + }; /** - * Defines the interface for visualizers. Visualizers are plug-ins to - * {@link DataSourceDisplay} that render data associated with - * {@link DataSource} instances. - * This object is an interface for documentation purposes and is not intended - * to be instantiated directly. - * @alias Visualizer - * @constructor - * - * @see BillboardVisualizer - * @see LabelVisualizer - * @see ModelVisualizer - * @see PathVisualizer - * @see PointVisualizer - * @see GeometryVisualizer + * @inheritdoc Cesium3DTileContent#applyDebugSettings */ - function Visualizer() { - DeveloperError.throwInstantiationError(); - } + Batched3DModel3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + color = enabled ? color : Color.WHITE; + if (this.featuresLength === 0) { + this._model.color = color; + } else { + this._batchTable.setAllColor(color); + } + }; /** - * Updates the visualization to the provided time. - * @function - * - * @param {JulianDate} time The time. - * - * @returns {Boolean} True if the display was updated to the provided time, - * false if the visualizer is waiting for an asynchronous operation to - * complete before data can be updated. + * @inheritdoc Cesium3DTileContent#applyStyle */ - Visualizer.prototype.update = DeveloperError.throwInstantiationError; + Batched3DModel3DTileContent.prototype.applyStyle = function(frameState, style) { + this._batchTable.applyStyle(frameState, style); + }; /** - * Computes a bounding sphere which encloses the visualization produced for the specified entity. - * The bounding sphere is in the fixed frame of the scene's globe. - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, - * BoundingSphereState.PENDING if the result is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private + * @inheritdoc Cesium3DTileContent#update */ - Visualizer.prototype.getBoundingSphere = DeveloperError.throwInstantiationError; + Batched3DModel3DTileContent.prototype.update = function(tileset, frameState) { + var commandStart = frameState.commandList.length; + + // In the PROCESSING state we may be calling update() to move forward + // the content's resource loading. In the READY state, it will + // actually generate commands. + this._batchTable.update(tileset, frameState); + this._model.modelMatrix = this._tile.computedTransform; + this._model.shadows = this._tileset.shadows; + this._model.debugWireframe = this._tileset.debugWireframe; + + // Update clipping planes + var tilesetClippingPlanes = this._tileset.clippingPlanes; + var modelClippingPlanes = this._model.clippingPlanes; + if (defined(tilesetClippingPlanes)) { + tilesetClippingPlanes.clone(modelClippingPlanes); + modelClippingPlanes.enabled = tilesetClippingPlanes.enabled && this._tile._isClipped; + } else if (defined(modelClippingPlanes) && modelClippingPlanes.enabled) { + modelClippingPlanes.enabled = false; + } + + this._model.update(frameState); + + // If any commands were pushed, add derived commands + var commandEnd = frameState.commandList.length; + if ((commandStart < commandEnd) && frameState.passes.render && !defined(tileset.classificationType)) { + var finalResolution = this._tile._finalResolution; + this._batchTable.addDerivedCommands(frameState, commandStart, finalResolution); + } + }; /** - * Returns true if this object was destroyed; otherwise, false. - * @function - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @inheritdoc Cesium3DTileContent#isDestroyed */ - Visualizer.prototype.isDestroyed = DeveloperError.throwInstantiationError; + Batched3DModel3DTileContent.prototype.isDestroyed = function() { + return false; + }; /** - * Removes all visualization and cleans up any resources associated with this instance. - * @function + * @inheritdoc Cesium3DTileContent#destroy */ - Visualizer.prototype.destroy = DeveloperError.throwInstantiationError; + Batched3DModel3DTileContent.prototype.destroy = function() { + this._model = this._model && this._model.destroy(); + this._batchTable = this._batchTable && this._batchTable.destroy(); + return destroyObject(this); + }; - return Visualizer; + return Batched3DModel3DTileContent; }); -define('Renderer/ClearCommand',[ - '../Core/Color', - '../Core/defaultValue', +define('Scene/BingMapsStyle',[ '../Core/freezeObject' ], function( - Color, - defaultValue, freezeObject) { 'use strict'; /** - * Represents a command to the renderer for clearing a framebuffer. + * The types of imagery provided by Bing Maps. * - * @private + * @exports BingMapsStyle + * + * @see BingMapsImageryProvider */ - function ClearCommand(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - + var BingMapsStyle = { /** - * The value to clear the color buffer to. When <code>undefined</code>, the color buffer is not cleared. - * - * @type {Color} + * Aerial imagery. * - * @default undefined + * @type {String} + * @constant */ - this.color = options.color; + AERIAL : 'Aerial', /** - * The value to clear the depth buffer to. When <code>undefined</code>, the depth buffer is not cleared. - * - * @type {Number} + * Aerial imagery with a road overlay. * - * @default undefined + * @type {String} + * @constant */ - this.depth = options.depth; + AERIAL_WITH_LABELS : 'AerialWithLabels', /** - * The value to clear the stencil buffer to. When <code>undefined</code>, the stencil buffer is not cleared. - * - * @type {Number} + * Roads without additional imagery. * - * @default undefined + * @type {String} + * @constant */ - this.stencil = options.stencil; + ROAD : 'Road', /** - * The render state to apply when executing the clear command. The following states affect clearing: - * scissor test, color mask, depth mask, and stencil mask. When the render state is - * <code>undefined</code>, the default render state is used. - * - * @type {RenderState} + * A dark version of the road maps. * - * @default undefined + * @type {String} + * @constant */ - this.renderState = options.renderState; + CANVAS_DARK : 'CanvasDark', /** - * The framebuffer to clear. - * - * @type {Framebuffer} + * A lighter version of the road maps. * - * @default undefined + * @type {String} + * @constant */ - this.framebuffer = options.framebuffer; + CANVAS_LIGHT : 'CanvasLight', /** - * The object who created this command. This is useful for debugging command - * execution; it allows you to see who created a command when you only have a - * reference to the command, and can be used to selectively execute commands - * with {@link Scene#debugCommandFilter}. - * - * @type {Object} - * - * @default undefined + * A grayscale version of the road maps. * - * @see Scene#debugCommandFilter + * @type {String} + * @constant */ - this.owner = options.owner; + CANVAS_GRAY : 'CanvasGray', /** - * The pass in which to run this command. - * - * @type {Pass} + * Ordnance Survey imagery. This imagery is visible only for the London, UK area. * - * @default undefined + * @type {String} + * @constant */ - this.pass = options.pass; - } - - /** - * Clears color to (0.0, 0.0, 0.0, 0.0); depth to 1.0; and stencil to 0. - * - * @type {ClearCommand} - * - * @constant - */ - ClearCommand.ALL = freezeObject(new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 0.0), - depth : 1.0, - stencil : 0.0 - })); + ORDNANCE_SURVEY : 'OrdnanceSurvey', - ClearCommand.prototype.execute = function(context, passState) { - context.clear(this, passState); + /** + * Collins Bart imagery. + * + * @type {String} + * @constant + */ + COLLINS_BART : 'CollinsBart' }; - return ClearCommand; + return freezeObject(BingMapsStyle); }); -define('Renderer/ComputeCommand',[ +define('Scene/BingMapsImageryProvider',[ + '../Core/BingMapsApi', + '../Core/Cartesian2', + '../Core/Credit', '../Core/defaultValue', - './Pass' + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/Event', + '../Core/Math', + '../Core/Rectangle', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/TileProviderError', + '../Core/WebMercatorTilingScheme', + '../ThirdParty/when', + './BingMapsStyle', + './DiscardMissingTileImagePolicy', + './ImageryProvider' ], function( + BingMapsApi, + Cartesian2, + Credit, defaultValue, - Pass) { + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Event, + CesiumMath, + Rectangle, + Resource, + RuntimeError, + TileProviderError, + WebMercatorTilingScheme, + when, + BingMapsStyle, + DiscardMissingTileImagePolicy, + ImageryProvider) { 'use strict'; /** - * Represents a command to the renderer for GPU Compute (using old-school GPGPU). + * Provides tiled imagery using the Bing Maps Imagery REST API. * - * @private + * @alias BingMapsImageryProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url of the Bing Maps server hosting the imagery. + * @param {String} [options.key] The Bing Maps key for your application, which can be + * created at {@link https://www.bingmapsportal.com/}. + * If this parameter is not provided, {@link BingMapsApi.defaultKey} is used. + * If {@link BingMapsApi.defaultKey} is undefined as well, a message is + * written to the console reminding you that you must create and supply a Bing Maps + * key as soon as possible. Please do not deploy an application that uses + * Bing Maps imagery without creating a separate key for your application. + * @param {String} [options.tileProtocol] The protocol to use when loading tiles, e.g. 'http:' or 'https:'. + * By default, tiles are loaded using the same protocol as the page. + * @param {BingMapsStyle} [options.mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps imagery to load. + * @param {String} [options.culture=''] The culture to use when requesting Bing Maps imagery. Not + * all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx} + * for information on the supported cultures. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile + * is invalid and should be discarded. If this value is not specified, a default + * {@link DiscardMissingTileImagePolicy} is used which requests + * tile 0,0 at the maximum tile level and checks pixels (0,0), (120,140), (130,160), + * (200,50), and (200,200). If all of these pixels are transparent, the discard check is + * disabled and no tiles are discarded. If any of them have a non-transparent color, any + * tile that has the same values in these pixel locations is discarded. The end result of + * these defaults should be correct tile discarding for a standard Bing Maps server. To ensure + * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this + * parameter. + * + * @see ArcGisMapServerImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + * + * + * @example + * var bing = new Cesium.BingMapsImageryProvider({ + * url : 'https://dev.virtualearth.net', + * key : 'get-yours-at-https://www.bingmapsportal.com/', + * mapStyle : Cesium.BingMapsStyle.AERIAL + * }); + * + * @see {@link http://msdn.microsoft.com/en-us/library/ff701713.aspx|Bing Maps REST Services} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ - function ComputeCommand(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * The vertex array. If none is provided, a viewport quad will be used. - * - * @type {VertexArray} - * @default undefined - */ - this.vertexArray = options.vertexArray; - - /** - * The fragment shader source. The default vertex shader is ViewportQuadVS. - * - * @type {ShaderSource} - * @default undefined - */ - this.fragmentShaderSource = options.fragmentShaderSource; - - /** - * The shader program to apply. - * - * @type {ShaderProgram} - * @default undefined - */ - this.shaderProgram = options.shaderProgram; + function BingMapsImageryProvider(options) { + options = defaultValue(options, {}); - /** - * An object with functions whose names match the uniforms in the shader program - * and return values to set those uniforms. - * - * @type {Object} - * @default undefined - */ - this.uniformMap = options.uniformMap; + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('BingMapsImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); + } - /** - * Texture to use for offscreen rendering. - * - * @type {Texture} - * @default undefined - */ - this.outputTexture = options.outputTexture; + this._key = BingMapsApi.getKey(options.key); + this._keyErrorCredit = BingMapsApi.getErrorCredit(options.key); - /** - * Function that is called immediately before the ComputeCommand is executed. Used to - * update any renderer resources. Takes the ComputeCommand as its single argument. - * - * @type {Function} - * @default undefined - */ - this.preExecute = options.preExecute; + var urlResource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); - /** - * Function that is called after the ComputeCommand is executed. Takes the output - * texture as its single argument. - * - * @type {Function} - * @default undefined - */ - this.postExecute = options.postExecute; + urlResource.addQueryParameters({ + key: this._key + }); - /** - * Whether the renderer resources will persist beyond this call. If not, they - * will be destroyed after completion. - * - * @type {Boolean} - * @default false - */ - this.persists = defaultValue(options.persists, false); + this._resource = urlResource; - /** - * The pass when to render. Always compute pass. - * - * @type {Pass} - * @default Pass.COMPUTE; - */ - this.pass = Pass.COMPUTE; + this._tileProtocol = options.tileProtocol; + this._mapStyle = defaultValue(options.mapStyle, BingMapsStyle.AERIAL); + this._culture = defaultValue(options.culture, ''); + this._tileDiscardPolicy = options.tileDiscardPolicy; + this._proxy = options.proxy; + this._credit = new Credit({ + text: 'Bing Imagery', + imageUrl: BingMapsImageryProvider._logoData, + link: 'http://www.bing.com' + }); /** - * The object who created this command. This is useful for debugging command - * execution; it allows us to see who created a command when we only have a - * reference to the command, and can be used to selectively execute commands - * with {@link Scene#debugCommandFilter}. - * - * @type {Object} - * @default undefined + * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider. + * Changing this value after creating an {@link ImageryLayer} for this provider will have + * no effect. Instead, set the layer's {@link ImageryLayer#gamma} property. * - * @see Scene#debugCommandFilter + * @type {Number} + * @default 1.0 */ - this.owner = options.owner; - } - - /** - * Executes the compute command. - * - * @param {Context} computeEngine The context that processes the compute command. - */ - ComputeCommand.prototype.execute = function(computeEngine) { - computeEngine.execute(this); - }; - - return ComputeCommand; -}); + this.defaultGamma = 1.0; -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/ViewportQuadVS',[],function() { - 'use strict'; - return "attribute vec4 position;\n\ -attribute vec2 textureCoordinates;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -gl_Position = position;\n\ -v_textureCoordinates = textureCoordinates;\n\ -}\n\ -"; -}); -define('Renderer/ComputeEngine',[ - '../Core/BoundingRectangle', - '../Core/Check', - '../Core/Color', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/PrimitiveType', - '../Shaders/ViewportQuadVS', - './ClearCommand', - './DrawCommand', - './Framebuffer', - './RenderState', - './ShaderProgram' - ], function( - BoundingRectangle, - Check, - Color, - defined, - destroyObject, - DeveloperError, - PrimitiveType, - ViewportQuadVS, - ClearCommand, - DrawCommand, - Framebuffer, - RenderState, - ShaderProgram) { - 'use strict'; + this._tilingScheme = new WebMercatorTilingScheme({ + numberOfLevelZeroTilesX : 2, + numberOfLevelZeroTilesY : 2, + ellipsoid : options.ellipsoid + }); - /** - * @private - */ - function ComputeEngine(context) { - this._context = context; - } + this._tileWidth = undefined; + this._tileHeight = undefined; + this._maximumLevel = undefined; + this._imageUrlTemplate = undefined; + this._imageUrlSubdomains = undefined; - var renderStateScratch; - var drawCommandScratch = new DrawCommand({ - primitiveType : PrimitiveType.TRIANGLES - }); - var clearCommandScratch = new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 0.0) - }); + this._errorEvent = new Event(); - function createFramebuffer(context, outputTexture) { - return new Framebuffer({ - context : context, - colorTextures : [outputTexture], - destroyAttachments : false - }); - } + this._ready = false; + this._readyPromise = when.defer(); - function createViewportQuadShader(context, fragmentShaderSource) { - return ShaderProgram.fromCache({ - context : context, - vertexShaderSource : ViewportQuadVS, - fragmentShaderSource : fragmentShaderSource, - attributeLocations : { - position : 0, - textureCoordinates : 1 + var metadataResource = urlResource.getDerivedResource({ + url:'/REST/v1/Imagery/Metadata/' + this._mapStyle, + queryParameters: { + incl: 'ImageryProviders' } }); - } + var that = this; + var metadataError; - function createRenderState(width, height) { - if ((!defined(renderStateScratch)) || - (renderStateScratch.viewport.width !== width) || - (renderStateScratch.viewport.height !== height)) { + function metadataSuccess(data) { + if (data.resourceSets.length !== 1) { + metadataFailure(); + return; + } + var resource = data.resourceSets[0].resources[0]; - renderStateScratch = RenderState.fromCache({ - viewport : new BoundingRectangle(0, 0, width, height) - }); - } - return renderStateScratch; - } + that._tileWidth = resource.imageWidth; + that._tileHeight = resource.imageHeight; + that._maximumLevel = resource.zoomMax - 1; + that._imageUrlSubdomains = resource.imageUrlSubdomains; + that._imageUrlTemplate = resource.imageUrl; - ComputeEngine.prototype.execute = function(computeCommand) { - Check.defined('computeCommand', computeCommand); - - // This may modify the command's resources, so do error checking afterwards - if (defined(computeCommand.preExecute)) { - computeCommand.preExecute(computeCommand); - } + var tileProtocol = that._tileProtocol; + if (!defined(tileProtocol)) { + // use the document's protocol, unless it's not http or https + var documentProtocol = document.location.protocol; + tileProtocol = /^http/.test(documentProtocol) ? documentProtocol : 'http:'; + } - if (!defined(computeCommand.fragmentShaderSource) && !defined(computeCommand.shaderProgram)) { - throw new DeveloperError('computeCommand.fragmentShaderSource or computeCommand.shaderProgram is required.'); - } + that._imageUrlTemplate = that._imageUrlTemplate.replace(/^http:/, tileProtocol); - Check.defined('computeCommand.outputTexture', computeCommand.outputTexture); - - var outputTexture = computeCommand.outputTexture; - var width = outputTexture.width; - var height = outputTexture.height; + // Install the default tile discard policy if none has been supplied. + if (!defined(that._tileDiscardPolicy)) { + that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ + missingImageUrl : buildImageResource(that, 0, 0, that._maximumLevel).url, + pixelsToCheck : [new Cartesian2(0, 0), new Cartesian2(120, 140), new Cartesian2(130, 160), new Cartesian2(200, 50), new Cartesian2(200, 200)], + disableCheckIfAllPixelsAreTransparent : true + }); + } - var context = this._context; - var vertexArray = defined(computeCommand.vertexArray) ? computeCommand.vertexArray : context.getViewportQuadVertexArray(); - var shaderProgram = defined(computeCommand.shaderProgram) ? computeCommand.shaderProgram : createViewportQuadShader(context, computeCommand.fragmentShaderSource); - var framebuffer = createFramebuffer(context, outputTexture); - var renderState = createRenderState(width, height); - var uniformMap = computeCommand.uniformMap; + var attributionList = that._attributionList = resource.imageryProviders; + if (!attributionList) { + attributionList = that._attributionList = []; + } - var clearCommand = clearCommandScratch; - clearCommand.framebuffer = framebuffer; - clearCommand.renderState = renderState; - clearCommand.execute(context); + for (var attributionIndex = 0, attributionLength = attributionList.length; attributionIndex < attributionLength; ++attributionIndex) { + var attribution = attributionList[attributionIndex]; - var drawCommand = drawCommandScratch; - drawCommand.vertexArray = vertexArray; - drawCommand.renderState = renderState; - drawCommand.shaderProgram = shaderProgram; - drawCommand.uniformMap = uniformMap; - drawCommand.framebuffer = framebuffer; - drawCommand.execute(context); + attribution.credit = new Credit({ + text: attribution.attribution + }); - framebuffer.destroy(); + var coverageAreas = attribution.coverageAreas; - if (!computeCommand.persists) { - shaderProgram.destroy(); - if (defined(computeCommand.vertexArray)) { - vertexArray.destroy(); + for (var areaIndex = 0, areaLength = attribution.coverageAreas.length; areaIndex < areaLength; ++areaIndex) { + var area = coverageAreas[areaIndex]; + var bbox = area.bbox; + area.bbox = new Rectangle( + CesiumMath.toRadians(bbox[1]), + CesiumMath.toRadians(bbox[0]), + CesiumMath.toRadians(bbox[3]), + CesiumMath.toRadians(bbox[2])); + } } - } - if (defined(computeCommand.postExecute)) { - computeCommand.postExecute(outputTexture); + that._ready = true; + that._readyPromise.resolve(true); + TileProviderError.handleSuccess(metadataError); } - }; - - ComputeEngine.prototype.isDestroyed = function() { - return false; - }; - ComputeEngine.prototype.destroy = function() { - return destroyObject(this); - }; + function metadataFailure(e) { + var message = 'An error occurred while accessing ' + metadataResource.url + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + that._readyPromise.reject(new RuntimeError(message)); + } - return ComputeEngine; -}); + function requestMetadata() { + var metadata = metadataResource.fetchJsonp('jsonp'); + when(metadata, metadataSuccess, metadataFailure); + } -define('Renderer/PassState',[], function() { - 'use strict'; + requestMetadata(); + } - /** - * The state for a particular rendering pass. This is used to supplement the state - * in a command being executed. - * - * @private - */ - function PassState(context) { + defineProperties(BingMapsImageryProvider.prototype, { /** - * The context used to execute commands for this pass. - * - * @type {Context} + * Gets the name of the BingMaps server url hosting the imagery. + * @memberof BingMapsImageryProvider.prototype + * @type {String} + * @readonly */ - this.context = context; + url : { + get : function() { + return this._resource.url; + } + }, /** - * The framebuffer to render to. This framebuffer is used unless a {@link DrawCommand} - * or {@link ClearCommand} explicitly define a framebuffer, which is used for off-screen - * rendering. - * - * @type {Framebuffer} - * @default undefined + * Gets the proxy used by this provider. + * @memberof BingMapsImageryProvider.prototype + * @type {Proxy} + * @readonly */ - this.framebuffer = undefined; + proxy : { + get : function() { + return this._resource.proxy; + } + }, + /** - * When defined, this overrides the blending property of a {@link DrawCommand}'s render state. - * This is used to, for example, to allow the renderer to turn off blending during the picking pass. - * <p> - * When this is <code>undefined</code>, the {@link DrawCommand}'s property is used. - * </p> - * - * @type {Boolean} - * @default undefined + * Gets the Bing Maps key. + * @memberof BingMapsImageryProvider.prototype + * @type {String} + * @readonly */ - this.blendingEnabled = undefined; + key : { + get : function() { + return this._key; + } + }, /** - * When defined, this overrides the scissor test property of a {@link DrawCommand}'s render state. - * This is used to, for example, to allow the renderer to scissor out the pick region during the picking pass. - * <p> - * When this is <code>undefined</code>, the {@link DrawCommand}'s property is used. - * </p> - * - * @type {Object} - * @default undefined + * Gets the type of Bing Maps imagery to load. + * @memberof BingMapsImageryProvider.prototype + * @type {BingMapsStyle} + * @readonly */ - this.scissorTest = undefined; + mapStyle : { + get : function() { + return this._mapStyle; + } + }, /** - * The viewport used when one is not defined by a {@link DrawCommand}'s render state. - * @type {BoundingRectangle} - * @default undefined + * The culture to use when requesting Bing Maps imagery. Not + * all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx} + * for information on the supported cultures. + * @memberof BingMapsImageryProvider.prototype + * @type {String} + * @readonly */ - this.viewport = undefined; - } - - return PassState; -}); - -define('Renderer/RenderbufferFormat',[ - '../Core/freezeObject', - '../Core/WebGLConstants' - ], function( - freezeObject, - WebGLConstants) { - 'use strict'; - - /** - * @private - */ - var RenderbufferFormat = { - RGBA4 : WebGLConstants.RGBA4, - RGB5_A1 : WebGLConstants.RGB5_A1, - RGB565 : WebGLConstants.RGB565, - DEPTH_COMPONENT16 : WebGLConstants.DEPTH_COMPONENT16, - STENCIL_INDEX8 : WebGLConstants.STENCIL_INDEX8, - DEPTH_STENCIL : WebGLConstants.DEPTH_STENCIL, - - validate : function(renderbufferFormat) { - return ((renderbufferFormat === RenderbufferFormat.RGBA4) || - (renderbufferFormat === RenderbufferFormat.RGB5_A1) || - (renderbufferFormat === RenderbufferFormat.RGB565) || - (renderbufferFormat === RenderbufferFormat.DEPTH_COMPONENT16) || - (renderbufferFormat === RenderbufferFormat.STENCIL_INDEX8) || - (renderbufferFormat === RenderbufferFormat.DEPTH_STENCIL)); - } - }; - - return freezeObject(RenderbufferFormat); -}); + culture : { + get : function() { + return this._culture; + } + }, -define('Renderer/Renderbuffer',[ - '../Core/Check', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - './ContextLimits', - './RenderbufferFormat' - ], function( - Check, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - ContextLimits, - RenderbufferFormat) { - 'use strict'; + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileWidth : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); + } + + return this._tileWidth; + } + }, - /** - * @private - */ - function Renderbuffer(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + /** + * Gets the height of each tile, in pixels. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileHeight: { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + } + + return this._tileHeight; + } + }, - Check.defined('options.context', options.context); - - var context = options.context; - var gl = context._gl; - var maximumRenderbufferSize = ContextLimits.maximumRenderbufferSize; - var format = defaultValue(options.format, RenderbufferFormat.RGBA4); - var width = defined(options.width) ? options.width : gl.drawingBufferWidth; - var height = defined(options.height) ? options.height : gl.drawingBufferHeight; + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : function() { + if (!this._ready) { + throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); + } + + return this._maximumLevel; + } + }, - if (!RenderbufferFormat.validate(format)) { - throw new DeveloperError('Invalid format.'); - } + /** + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {Number} + * @readonly + */ + minimumLevel : { + get : function() { + if (!this._ready) { + throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); + } + + return 0; + } + }, - Check.typeOf.number.greaterThan('width', width, 0); + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {TilingScheme} + * @readonly + */ + tilingScheme : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme; + } + }, - if (width > maximumRenderbufferSize) { - throw new DeveloperError('Width must be less than or equal to the maximum renderbuffer size (' + maximumRenderbufferSize + '). Check maximumRenderbufferSize.'); - } + /** + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle : { + get : function() { + if (!this._ready) { + throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme.rectangle; + } + }, - Check.typeOf.number.greaterThan('height', height, 0); + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + */ + tileDiscardPolicy : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); + } + + return this._tileDiscardPolicy; + } + }, - if (height > maximumRenderbufferSize) { - throw new DeveloperError('Height must be less than or equal to the maximum renderbuffer size (' + maximumRenderbufferSize + '). Check maximumRenderbufferSize.'); - } - - this._gl = gl; - this._format = format; - this._width = width; - this._height = height; - this._renderbuffer = this._gl.createRenderbuffer(); + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof BingMapsImageryProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, - gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderbuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height); - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - } + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof BingMapsImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; + } + }, - defineProperties(Renderbuffer.prototype, { - format: { + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof BingMapsImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { get : function() { - return this._format; + return this._readyPromise.promise; } }, - width: { + + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link BingMapsImageryProvider#ready} returns true. + * @memberof BingMapsImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { get : function() { - return this._width; + return this._credit; } }, - height: { + + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage + * and texture upload time. + * @memberof BingMapsImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { get : function() { - return this._height; + return false; } } - }); + }); + + var rectangleScratch = new Rectangle(); + + /** + * Gets the credits to be displayed when a given tile is displayed. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + */ + BingMapsImageryProvider.prototype.getTileCredits = function(x, y, level) { + if (!this._ready) { + throw new DeveloperError('getTileCredits must not be called before the imagery provider is ready.'); + } + + var rectangle = this._tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); + var result = getRectangleAttribution(this._attributionList, level, rectangle); + + if (defined(this._keyErrorCredit)) { + result.push(this._keyErrorCredit); + } - Renderbuffer.prototype._getRenderbuffer = function() { - return this._renderbuffer; + return result; }; - Renderbuffer.prototype.isDestroyed = function() { - return false; + /** + * Requests the image for a given tile. This function should + * not be called before {@link BingMapsImageryProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + */ + BingMapsImageryProvider.prototype.requestImage = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); + } + + return ImageryProvider.loadImage(this, buildImageResource(this, x, y, level, request)); }; - Renderbuffer.prototype.destroy = function() { - this._gl.deleteRenderbuffer(this._renderbuffer); - return destroyObject(this); + /** + * Picking features is not currently supported by this imagery provider, so this function simply returns + * undefined. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. + */ + BingMapsImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return undefined; }; - return Renderbuffer; -}); - -define('Renderer/PickFramebuffer',[ - '../Core/BoundingRectangle', - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/destroyObject', - './Framebuffer', - './PassState', - './Renderbuffer', - './RenderbufferFormat', - './Texture' - ], function( - BoundingRectangle, - Color, - defaultValue, - defined, - destroyObject, - Framebuffer, - PassState, - Renderbuffer, - RenderbufferFormat, - Texture) { - 'use strict'; + BingMapsImageryProvider._logoData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAAaCAYAAAAEy1RnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3gIDEgcPTMnXOQAAClZJREFUWMPdWGtsFNcV/u689uH1+sXaONhlWQzBENtxiUFBpBSLd60IpXHSNig4URtSYQUkRJNSi0igViVVVBJBaBsiAgKRQJSG8AgEHCCWU4iBCprY2MSgXfOI16y9D3s9Mzsztz9yB12WNU2i9Ecy0tHOzN4793zn3POdcy7BnRfJ8I7iB3SRDPeEExswLz8Y0DZIAYDIRGAgLQAm+7Xle31J3L3Anp1MZPY+BUBjorN332vgYhpgV1FRUd6TTz45ubq6OtDV1SXpuu5g//Oept9wNwlMyAi8IXDjyF245TsDTdivDMATCATGNDU1/WbhwoWPTZs2bWx1dXWhx+Oxrl+/PqTrus5t9W8KWEzjinTAYhro/xuBStwiIgBnJBLxKIoy1u/3V/r9/krDMMz3339/Z3t7e38ikUgCMDLEt8W+Q0cAI3McYTDDmZxh7DESG5Ni43jg9Gsa+X+OsxWxPSJTSj3JZFK5ZRVJErOzs8e6XC4fgGwALhbzDgAKU1hK28KEA6PMmTMn56233qpevnz5PQDcbJ7EzVUAuMrLy3MBeABkcWOEDELSyFe4y7iMoHkriZZlKYZh8ASHZDKpJJPJHAC5APIA5APIAeBlCjo5TwlpXnbOmTPHP3fu3KZVq1atZKBcDJQ9x7V48WJfc3Pzhp6enj+tXLnyR8w4MjdG4gyVDk7KICMClzKlLUrpbQMNw5AkScppbGz8cWdn57WjR4/2caw+DEBlYjO8wX1foZQWuN3uKZIklQD4G+fhlG0Yl8uVm5WVVW6app6dne0D0G8vnxbjJntHubCUOK/badZICyWanrJuAaeUknTQpmlKkUhEWbx48U8LCwtHhUKha+fPn+85fPhwV0tLyzUACSZx9jvMFhIByNFoVDEMw/qKB5HPvJfkUqBr9+7deklJyZ/j8bi5ffv2OAslieMLsG+m2DybT2QuzEQOsF5SUqJfvXo1yc2l6Xn6rgSRSCSEc+fOhVeuXLmwoqJixvTp0wcWLFgQ7unpudHR0dF97ty5z/fu3XseQJh5adjeerquy5ZlCalUivh8Pt8HH3ywzOPxyD09PZ81NjZ+2NnZaQEQx40b54vFYqaqquEVK1b4a2tr/WvWrDn18ssv144fP36SqqoD69ev371nz57rDLwAwHHkyJGfjRs3rtowDOv06dOnu7q6rs6bN2/s7Nmz9zIjDKenWoFZKg/AlMLCwl82Nzf/m3LX22+/fXb06NF/ALC8u7u7m6ZdkUhksL29/UpLS0vzunXrVgAoBzAaQBGAiY2NjUui0ei1RCLRFwwG/9PX19cVi8WCqqoOdHd3HysrK6sDMCccDl8IBoOtiqIsOnbs2D+i0eiV3t7ez8Ph8GeRSKRT07TB/v7+i1OnTp0HYBqABzs7O/+paVo0Fot1RyKRi/F4/Gp/f39XIpHoZnoUMn6wU+ZtRDaymwmxZFk2AWjvvvvuJ/F4PMn/n5+fn1VeXu6fOXNmbU1NzUOM4Bz8QqIoyg6HwxuLxfq3bdu2a+vWrW/09/dfKy0tffDVV199BEC20+n0ud3uQgBup9Pp83g8JYqieE+ePPnxxo0bt33xxRen8/Ly7n3hhRcWASh47bXX5pWVldWFw+GuXbt27XjzzTd3BoPBDq/XG1AUZRRHmAKPVfqaoKkgCCkA+oYNG84Eg0FHTU1N5ezZs8eWlJQ4CSF8/LvZYhJPQoQQpFKpwcrKyo1su9HBwUF99erVv588eXINgOOmacIwDEopdaZSKUIpxYkTJz6sr68/BMBav379RcMwZk2aNOl+AP+qq6t7xDTNVEVFxR+j0WgSAJk4ceKlTz/9tNzpdHpZvIvpjVW6pykhhBJCbkvwgiAQQogEQL558ybdtGlTsLm5OWJZdxZmlmWll5OUEEJN0zSGhob6GcOrALSzZ8/2apqWcLlc2axGACNRkRAimqaph0Kh68xIwwB0y7IMSZKcABz5+fkl8Xj8y2g0apOb5na7rYGBgS/JV54Q0qpAAoBKaS0jBWClg1ZVFeFw2AlgVF1dXeDpp5+eWVFRUVpcXOzgvQwAbrcbDJhdudlGpKZpGtx6JCcnRxIEQbQsS2PjbjM+AMvlchnMSBaXkr7ymCCIhmEYfMoVRVESBEHI0CaTTNubssUsQRBuubCtra33pZdeCk6YMCGwZs2aipqaGn9paWmuJEl3JP0bN258eeTIkRMABrm0YomiaImiKGVlZeWxLecAgBkzZvgdDkfWjRs3ggA0bpfpoiiahBCqKEqKAy2yULMA6MlkMp6Xl3cP1x2SWCwmFhQU+CmlFhfHNFOevpX4LcvSJUkyAeDQoUOh119//fpTTz01Zf78+UWBQCBHUZQ7yE/TNGPfvn0n33vvvSP79+//BECMeZsCMGRZNgRBgNPpHHXx4sVVDQ0Nf1+wYMGYJ554YikAevDgwUMA4oIgQJZlSggZdDqdBiGEZGdn6ww0tQlJURTT4/EMHz9+/MCjjz7622AwuHbZsmVbiouLvWvXrm1wOp3ZqVRqaKQTIInf1gAMl8ulU0q1CxcuBGOxmL5u3bryQCDgycrKEjORXGtra8eOHTsOHz169OyVK1cuA+hlRYrGlNRkWR7UNO2mYRiaz+cb3dLS8gYhhOi6Hj116tSOVatWHQNALcsaME0zLghClBDSZ9+zQsZ2SoJS2udwOKLPPffcvsrKyrJAIPDQ/v37txiGofX19V3r7e29UlBQMHqEVpjwnrYA6PF4PK6q6s2qqqqpZWVlitvtljOB7enpiWzbtu3wgQMHTre1tV0E0MeKkkGuIhMAqHv37u30er3Px+NxlyiKygMPPOAnhFiXLl0Kbd68uYPNsXbu3Lk6mUwaqqr2btmyZUdtbe3hd955pwvAEFNcO3jw4K/b2tqiqqpGIpGI4/HHH/9rQ0PDCa/XOyoSidDLly8PNTU1PcZ4QuNK1ju6NYHFRAGASXPnzv1Fa2vrxzTDpapqateuXR/Nnz+/SVGUhwFMBzCBFSLZLF75DsrJGpXRAH4EIABgPIBxAEoBFAPwARjFif1sNzZ25+VlOhaxufcCqAFQC+BhAPVLliz5XSqVUkOhUAuAKWnFyR3dlsw+fg+A+8eMGfPzTZs2bY9GozEb8JkzZ9qXLl36l+Li4l8B+AmAyQDGsGrOzfXNPGPawG2l85jksmcPm+vihH+2W1iF3bvZPN+sWbPuGx4eDrW3t+85fvz41o6OjmZN04Y0TYvV19cvYIbN5QqUjG2mwj5YAqDK4XDMe+aZZ55vbW09+sorr2yuqqpqYFatAuBn3uB7XzJCY297XeaUd2RoGzOJmHb6IjFj5D777LP3DQwMfDw8PBxSVbUvkUj0hEKhj1588cXH2O7zMSPdplumoxveMx5Zlj3jx4/39vb26gMDA4MsvgYZo+p8Pr7LqQX5Ds/U7d0jFxUVZS1atKg4Nzc317Isp67rZldXV6y5ufkmI78hFtcmrx8ZweMit6XsUs4+6kmlgbW+peLf9gyMZNCR374G0y/FxEzX8b/8+bkXEBxKFwAAAABJRU5ErkJggg=='; /** - * @private + * Converts a tiles (x, y, level) position into a quadkey used to request an image + * from a Bing Maps server. + * + * @param {Number} x The tile's x coordinate. + * @param {Number} y The tile's y coordinate. + * @param {Number} level The tile's zoom level. + * + * @see {@link http://msdn.microsoft.com/en-us/library/bb259689.aspx|Bing Maps Tile System} + * @see BingMapsImageryProvider#quadKeyToTileXY */ - function PickFramebuffer(context) { - // Override per-command states - var passState = new PassState(context); - passState.blendingEnabled = false; - passState.scissorTest = { - enabled : true, - rectangle : new BoundingRectangle() - }; - passState.viewport = new BoundingRectangle(); - - this._context = context; - this._fb = undefined; - this._passState = passState; - this._width = 0; - this._height = 0; - } - PickFramebuffer.prototype.begin = function(screenSpaceRectangle) { - var context = this._context; - var width = context.drawingBufferWidth; - var height = context.drawingBufferHeight; + BingMapsImageryProvider.tileXYToQuadKey = function(x, y, level) { + var quadkey = ''; + for ( var i = level; i >= 0; --i) { + var bitmask = 1 << i; + var digit = 0; - BoundingRectangle.clone(screenSpaceRectangle, this._passState.scissorTest.rectangle); + if ((x & bitmask) !== 0) { + digit |= 1; + } - // Initially create or recreate renderbuffers and framebuffer used for picking - if ((!defined(this._fb)) || (this._width !== width) || (this._height !== height)) { - this._width = width; - this._height = height; + if ((y & bitmask) !== 0) { + digit |= 2; + } - this._fb = this._fb && this._fb.destroy(); - this._fb = new Framebuffer({ - context : context, - colorTextures : [new Texture({ - context : context, - width : width, - height : height - })], - depthStencilRenderbuffer : new Renderbuffer({ - context : context, - format : RenderbufferFormat.DEPTH_STENCIL - }) - }); - this._passState.framebuffer = this._fb; + quadkey += digit; } + return quadkey; + }; - this._passState.viewport.width = width; - this._passState.viewport.height = height; + /** + * Converts a tile's quadkey used to request an image from a Bing Maps server into the + * (x, y, level) position. + * + * @param {String} quadkey The tile's quad key + * + * @see {@link http://msdn.microsoft.com/en-us/library/bb259689.aspx|Bing Maps Tile System} + * @see BingMapsImageryProvider#tileXYToQuadKey + */ + BingMapsImageryProvider.quadKeyToTileXY = function(quadkey) { + var x = 0; + var y = 0; + var level = quadkey.length - 1; + for ( var i = level; i >= 0; --i) { + var bitmask = 1 << i; + var digit = +quadkey[level - i]; - return this._passState; + if ((digit & 1) !== 0) { + x |= bitmask; + } + + if ((digit & 2) !== 0) { + y |= bitmask; + } + } + return { + x : x, + y : y, + level : level + }; }; - var colorScratch = new Color(); + function buildImageResource(imageryProvider, x, y, level, request) { + var imageUrl = imageryProvider._imageUrlTemplate; - PickFramebuffer.prototype.end = function(screenSpaceRectangle) { - var width = defaultValue(screenSpaceRectangle.width, 1.0); - var height = defaultValue(screenSpaceRectangle.height, 1.0); + var subdomains = imageryProvider._imageUrlSubdomains; + var subdomainIndex = (x + y + level) % subdomains.length; - var context = this._context; - var pixels = context.readPixels({ - x : screenSpaceRectangle.x, - y : screenSpaceRectangle.y, - width : width, - height : height, - framebuffer : this._fb + return imageryProvider._resource.getDerivedResource({ + url: imageUrl, + request: request, + templateValues: { + quadkey: BingMapsImageryProvider.tileXYToQuadKey(x, y, level), + subdomain: subdomains[subdomainIndex], + culture: imageryProvider._culture + } }); + } - var max = Math.max(width, height); - var length = max * max; - var halfWidth = Math.floor(width * 0.5); - var halfHeight = Math.floor(height * 0.5); + var intersectionScratch = new Rectangle(); - var x = 0; - var y = 0; - var dx = 0; - var dy = -1; + function getRectangleAttribution(attributionList, level, rectangle) { + // Bing levels start at 1, while ours start at 0. + ++level; - // Spiral around the center pixel, this is a workaround until - // we can access the depth buffer on all browsers. + var result = []; - // The region does not have to square and the dimensions do not have to be odd, but - // loop iterations would be wasted. Prefer square regions where the size is odd. - for (var i = 0; i < length; ++i) { - if (-halfWidth <= x && x <= halfWidth && -halfHeight <= y && y <= halfHeight) { - var index = 4 * ((halfHeight - y) * width + x + halfWidth); + for (var attributionIndex = 0, attributionLength = attributionList.length; attributionIndex < attributionLength; ++attributionIndex) { + var attribution = attributionList[attributionIndex]; + var coverageAreas = attribution.coverageAreas; - colorScratch.red = Color.byteToFloat(pixels[index]); - colorScratch.green = Color.byteToFloat(pixels[index + 1]); - colorScratch.blue = Color.byteToFloat(pixels[index + 2]); - colorScratch.alpha = Color.byteToFloat(pixels[index + 3]); + var included = false; - var object = context.getObjectByPickColor(colorScratch); - if (defined(object)) { - return object; + for (var areaIndex = 0, areaLength = attribution.coverageAreas.length; !included && areaIndex < areaLength; ++areaIndex) { + var area = coverageAreas[areaIndex]; + if (level >= area.zoomMin && level <= area.zoomMax) { + var intersection = Rectangle.intersection(rectangle, area.bbox, intersectionScratch); + if (defined(intersection)) { + included = true; + } } } - // if (top right || bottom left corners) || (top left corner) || (bottom right corner + (1, 0)) - // change spiral direction - if (x === y || (x < 0 && -x === y) || (x > 0 && x === 1 - y)) { - var temp = dx; - dx = -dy; - dy = temp; + if (included) { + result.push(attribution.credit); } - - x += dx; - y += dy; } - return undefined; - }; - - PickFramebuffer.prototype.isDestroyed = function() { - return false; - }; - - PickFramebuffer.prototype.destroy = function() { - this._fb = this._fb && this._fb.destroy(); - return destroyObject(this); - }; + return result; + } - return PickFramebuffer; + return BingMapsImageryProvider; }); -define('Renderer/ShaderCache',[ - '../Core/defined', +define('Scene/BoxEmitter',[ + '../Core/Cartesian3', + '../Core/Check', + '../Core/defaultValue', '../Core/defineProperties', - '../Core/destroyObject', - './ShaderProgram', - './ShaderSource' + '../Core/Math' ], function( - defined, + Cartesian3, + Check, + defaultValue, defineProperties, - destroyObject, - ShaderProgram, - ShaderSource) { + CesiumMath) { 'use strict'; + var defaultDimensions = new Cartesian3(1.0, 1.0, 1.0); + /** - * @private + * A ParticleEmitter that emits particles within a box. + * Particles will be positioned randomly within the box and have initial velocities emanating from the center of the box. + * + * @alias BoxEmitter + * @constructor + * + * @param {Cartesian3} dimensions The width, height and depth dimensions of the box. */ - function ShaderCache(context) { - this._context = context; - this._shaders = {}; - this._numberOfShaders = 0; - this._shadersToRelease = {}; + function BoxEmitter(dimensions) { + dimensions = defaultValue(dimensions, defaultDimensions); + + Check.defined('dimensions', dimensions); + Check.typeOf.number.greaterThanOrEquals('dimensions.x', dimensions.x, 0.0); + Check.typeOf.number.greaterThanOrEquals('dimensions.y', dimensions.y, 0.0); + Check.typeOf.number.greaterThanOrEquals('dimensions.z', dimensions.z, 0.0); + + this._dimensions = Cartesian3.clone(dimensions); } - defineProperties(ShaderCache.prototype, { - numberOfShaders : { + defineProperties(BoxEmitter.prototype, { + /** + * The width, height and depth dimensions of the box in meters. + * @memberof BoxEmitter.prototype + * @type {Cartesian3} + * @default new Cartesian3(1.0, 1.0, 1.0) + */ + dimensions : { get : function() { - return this._numberOfShaders; + return this._dimensions; + }, + set : function(value) { + Check.defined('value', value); + Check.typeOf.number.greaterThanOrEquals('value.x', value.x, 0.0); + Check.typeOf.number.greaterThanOrEquals('value.y', value.y, 0.0); + Check.typeOf.number.greaterThanOrEquals('value.z', value.z, 0.0); + Cartesian3.clone(value, this._dimensions); } } - }); - - /** - * Returns a shader program from the cache, or creates and caches a new shader program, - * given the GLSL vertex and fragment shader source and attribute locations. - * <p> - * The difference between this and {@link ShaderCache#getShaderProgram}, is this is used to - * replace an existing reference to a shader program, which is passed as the first argument. - * </p> - * - * @param {Object} options Object with the following properties: - * @param {ShaderProgram} [options.shaderProgram] The shader program that is being reassigned. - * @param {String|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. - * @param {String|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. - * @param {Object} options.attributeLocations Indices for the attribute inputs to the vertex shader. - * @returns {ShaderProgram} The cached or newly created shader program. - * - * - * @example - * this._shaderProgram = context.shaderCache.replaceShaderProgram({ - * shaderProgram : this._shaderProgram, - * vertexShaderSource : vs, - * fragmentShaderSource : fs, - * attributeLocations : attributeLocations - * }); - * - * @see ShaderCache#getShaderProgram - */ - ShaderCache.prototype.replaceShaderProgram = function(options) { - if (defined(options.shaderProgram)) { - options.shaderProgram.destroy(); - } + }); - return this.getShaderProgram(options); - }; + var scratchHalfDim = new Cartesian3(); /** - * Returns a shader program from the cache, or creates and caches a new shader program, - * given the GLSL vertex and fragment shader source and attribute locations. - * - * @param {Object} options Object with the following properties: - * @param {String|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. - * @param {String|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. - * @param {Object} options.attributeLocations Indices for the attribute inputs to the vertex shader. + * Initializes the given {Particle} by setting it's position and velocity. * - * @returns {ShaderProgram} The cached or newly created shader program. + * @private + * @param {Particle} particle The particle to initialize. */ - ShaderCache.prototype.getShaderProgram = function(options) { - // convert shaders which are provided as strings into ShaderSource objects - // because ShaderSource handles all the automatic including of built-in functions, etc. - - var vertexShaderSource = options.vertexShaderSource; - var fragmentShaderSource = options.fragmentShaderSource; - var attributeLocations = options.attributeLocations; - - if (typeof vertexShaderSource === 'string') { - vertexShaderSource = new ShaderSource({ - sources : [vertexShaderSource] - }); - } - - if (typeof fragmentShaderSource === 'string') { - fragmentShaderSource = new ShaderSource({ - sources : [fragmentShaderSource] - }); - } - - var vertexShaderText = vertexShaderSource.createCombinedVertexShader(this._context); - var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(this._context); - - var keyword = vertexShaderText + fragmentShaderText + JSON.stringify(attributeLocations); - var cachedShader; - - if (defined(this._shaders[keyword])) { - cachedShader = this._shaders[keyword]; - - // No longer want to release this if it was previously released. - delete this._shadersToRelease[keyword]; - } else { - var context = this._context; - var shaderProgram = new ShaderProgram({ - gl : context._gl, - logShaderCompilation : context.logShaderCompilation, - debugShaders : context.debugShaders, - vertexShaderSource : vertexShaderSource, - vertexShaderText : vertexShaderText, - fragmentShaderSource : fragmentShaderSource, - fragmentShaderText : fragmentShaderText, - attributeLocations : attributeLocations - }); - - cachedShader = { - cache : this, - shaderProgram : shaderProgram, - keyword : keyword, - derivedKeywords : [], - count : 0 - }; + BoxEmitter.prototype.emit = function(particle) { + var dim = this._dimensions; + var halfDim = Cartesian3.multiplyByScalar(dim, 0.5, scratchHalfDim); - // A shader can't be in more than one cache. - shaderProgram._cachedShader = cachedShader; - this._shaders[keyword] = cachedShader; - ++this._numberOfShaders; - } + var x = CesiumMath.randomBetween(-halfDim.x, halfDim.x); + var y = CesiumMath.randomBetween(-halfDim.y, halfDim.y); + var z = CesiumMath.randomBetween(-halfDim.z, halfDim.z); - ++cachedShader.count; - return cachedShader.shaderProgram; + particle.position = Cartesian3.fromElements(x, y, z, particle.position); + particle.velocity = Cartesian3.normalize(particle.position, particle.velocity); }; - ShaderCache.prototype.getDerivedShaderProgram = function(shaderProgram, keyword) { - var cachedShader = shaderProgram._cachedShader; - var derivedKeyword = keyword + cachedShader.keyword; - var cachedDerivedShader = this._shaders[derivedKeyword]; - if (!defined(cachedDerivedShader)) { - return undefined; - } - - return cachedDerivedShader.shaderProgram; - }; + return BoxEmitter; +}); - ShaderCache.prototype.createDerivedShaderProgram = function(shaderProgram, keyword, options) { - var cachedShader = shaderProgram._cachedShader; - var derivedKeyword = keyword + cachedShader.keyword; +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/BrdfLutGeneratorFS',[],function() { + 'use strict'; + return "varying vec2 v_textureCoordinates;\n\ +const float M_PI = 3.141592653589793;\n\ +float vdcRadicalInverse(int i)\n\ +{\n\ +float r;\n\ +float base = 2.0;\n\ +float value = 0.0;\n\ +float invBase = 1.0 / base;\n\ +float invBi = invBase;\n\ +for (int x = 0; x < 100; x++)\n\ +{\n\ +if (i <= 0)\n\ +{\n\ +break;\n\ +}\n\ +r = mod(float(i), base);\n\ +value += r * invBi;\n\ +invBi *= invBase;\n\ +i = int(float(i) * invBase);\n\ +}\n\ +return value;\n\ +}\n\ +vec2 hammersley2D(int i, int N)\n\ +{\n\ +return vec2(float(i) / float(N), vdcRadicalInverse(i));\n\ +}\n\ +vec3 importanceSampleGGX(vec2 xi, float roughness, vec3 N)\n\ +{\n\ +float a = roughness * roughness;\n\ +float phi = 2.0 * M_PI * xi.x;\n\ +float cosTheta = sqrt((1.0 - xi.y) / (1.0 + (a * a - 1.0) * xi.y));\n\ +float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n\ +vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);\n\ +vec3 upVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n\ +vec3 tangentX = normalize(cross(upVector, N));\n\ +vec3 tangentY = cross(N, tangentX);\n\ +return tangentX * H.x + tangentY * H.y + N * H.z;\n\ +}\n\ +float G1_Smith(float NdotV, float k)\n\ +{\n\ +return NdotV / (NdotV * (1.0 - k) + k);\n\ +}\n\ +float G_Smith(float roughness, float NdotV, float NdotL)\n\ +{\n\ +float k = roughness * roughness / 2.0;\n\ +return G1_Smith(NdotV, k) * G1_Smith(NdotL, k);\n\ +}\n\ +vec2 integrateBrdf(float roughness, float NdotV)\n\ +{\n\ +vec3 V = vec3(sqrt(1.0 - NdotV * NdotV), 0.0, NdotV);\n\ +float A = 0.0;\n\ +float B = 0.0;\n\ +const int NumSamples = 1024;\n\ +for (int i = 0; i < NumSamples; i++)\n\ +{\n\ +vec2 xi = hammersley2D(i, NumSamples);\n\ +vec3 H = importanceSampleGGX(xi, roughness, vec3(0.0, 0.0, 1.0));\n\ +vec3 L = 2.0 * dot(V, H) * H - V;\n\ +float NdotL = clamp(L.z, 0.0, 1.0);\n\ +float NdotH = clamp(H.z, 0.0, 1.0);\n\ +float VdotH = clamp(dot(V, H), 0.0, 1.0);\n\ +if (NdotL > 0.0)\n\ +{\n\ +float G = G_Smith(roughness, NdotV, NdotL);\n\ +float G_Vis = G * VdotH / (NdotH * NdotV);\n\ +float Fc = pow(1.0 - VdotH, 5.0);\n\ +A += (1.0 - Fc) * G_Vis;\n\ +B += Fc * G_Vis;\n\ +}\n\ +}\n\ +return vec2(A, B) / float(NumSamples);\n\ +}\n\ +void main()\n\ +{\n\ +gl_FragColor = vec4(integrateBrdf(1.0 - v_textureCoordinates.y, v_textureCoordinates.x), 0.0, 1.0);\n\ +}\n\ +"; +}); +define('Scene/BrdfLutGenerator',[ + '../Core/BoundingRectangle', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/PixelFormat', + '../Renderer/Framebuffer', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/Sampler', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', + '../Shaders/BrdfLutGeneratorFS' + ], function( + BoundingRectangle, + defined, + defineProperties, + destroyObject, + PixelFormat, + Framebuffer, + PixelDatatype, + RenderState, + Sampler, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap, + BrdfLutGeneratorFS) { + 'use strict'; - var vertexShaderSource = options.vertexShaderSource; - var fragmentShaderSource = options.fragmentShaderSource; - var attributeLocations = options.attributeLocations; + /** + * @private + */ + function BrdfLutGenerator() { + this._framebuffer = undefined; + this._colorTexture = undefined; + this._drawCommand = undefined; + } - if (typeof vertexShaderSource === 'string') { - vertexShaderSource = new ShaderSource({ - sources : [vertexShaderSource] - }); + defineProperties(BrdfLutGenerator.prototype, { + colorTexture : { + get : function() { + return this._colorTexture; + } } + }); - if (typeof fragmentShaderSource === 'string') { - fragmentShaderSource = new ShaderSource({ - sources : [fragmentShaderSource] - }); - } + function createCommand(generator, context) { + var framebuffer = generator._framebuffer; - var context = this._context; + var drawCommand = context.createViewportQuadCommand(BrdfLutGeneratorFS, { + framebuffer : framebuffer, + renderState : RenderState.fromCache({ + viewport : new BoundingRectangle(0.0, 0.0, 256.0, 256.0) + }) + }); - var vertexShaderText = vertexShaderSource.createCombinedVertexShader(context); - var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(context); + generator._drawCommand = drawCommand; + } - var derivedShaderProgram = new ShaderProgram({ - gl : context._gl, - logShaderCompilation : context.logShaderCompilation, - debugShaders : context.debugShaders, - vertexShaderSource : vertexShaderSource, - vertexShaderText : vertexShaderText, - fragmentShaderSource : fragmentShaderSource, - fragmentShaderText : fragmentShaderText, - attributeLocations : attributeLocations + function createFramebuffer(generator, context) { + var colorTexture = new Texture({ + context : context, + width : 256, + height: 256, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }) }); - var derivedCachedShader = { - cache : this, - shaderProgram : derivedShaderProgram, - keyword : derivedKeyword, - derivedKeywords : [], - count : 0 - }; - - cachedShader.derivedKeywords.push(keyword); - derivedShaderProgram._cachedShader = derivedCachedShader; - this._shaders[derivedKeyword] = derivedCachedShader; - return derivedShaderProgram; - }; + generator._colorTexture = colorTexture; - function destroyShader(cache, cachedShader) { - var derivedKeywords = cachedShader.derivedKeywords; - var length = derivedKeywords.length; - for (var i = 0; i < length; ++i) { - var keyword = derivedKeywords[i] + cachedShader.keyword; - var derivedCachedShader = cache._shaders[keyword]; - destroyShader(cache, derivedCachedShader); - } + var framebuffer = new Framebuffer({ + context : context, + colorTextures : [colorTexture], + destroyAttachments : false + }); - delete cache._shaders[cachedShader.keyword]; - cachedShader.shaderProgram.finalDestroy(); + generator._framebuffer = framebuffer; } - ShaderCache.prototype.destroyReleasedShaderPrograms = function() { - var shadersToRelease = this._shadersToRelease; - - for ( var keyword in shadersToRelease) { - if (shadersToRelease.hasOwnProperty(keyword)) { - var cachedShader = shadersToRelease[keyword]; - destroyShader(this, cachedShader); - --this._numberOfShaders; - } - } - - this._shadersToRelease = {}; - }; + BrdfLutGenerator.prototype.update = function(frameState) { + if (!defined(this._colorTexture)) { + var context = frameState.context; - ShaderCache.prototype.releaseShaderProgram = function(shaderProgram) { - if (defined(shaderProgram)) { - var cachedShader = shaderProgram._cachedShader; - if (cachedShader && (--cachedShader.count === 0)) { - this._shadersToRelease[cachedShader.keyword] = cachedShader; - } + createFramebuffer(this, context); + createCommand(this, context); + this._drawCommand.execute(context); + this._framebuffer = this._framebuffer && this._framebuffer.destroy(); + this._drawCommand.shaderProgram = this._drawCommand.shaderProgram && this._drawCommand.shaderProgram.destroy(); } }; - ShaderCache.prototype.isDestroyed = function() { + BrdfLutGenerator.prototype.isDestroyed = function() { return false; }; - ShaderCache.prototype.destroy = function() { - var shaders = this._shaders; - for (var keyword in shaders) { - if (shaders.hasOwnProperty(keyword)) { - shaders[keyword].shaderProgram.finalDestroy(); - } - } + BrdfLutGenerator.prototype.destroy = function() { + this._colorTexture = this._colorTexture && this._colorTexture.destroy(); return destroyObject(this); }; - return ShaderCache; + return BrdfLutGenerator; }); -define('Renderer/UniformState',[ - './Sampler', - '../Core/BoundingRectangle', +define('Scene/CameraFlightPath',[ '../Core/Cartesian2', '../Core/Cartesian3', - '../Core/Cartesian4', '../Core/Cartographic', - '../Core/Color', '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', - '../Core/EncodedCartesian3', + '../Core/DeveloperError', + '../Core/EasingFunction', '../Core/Math', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/OrthographicFrustum', - '../Core/Simon1994PlanetaryPositions', - '../Core/Transforms', - '../Scene/SceneMode' + '../Core/PerspectiveFrustum', + '../Core/PerspectiveOffCenterFrustum', + './SceneMode' ], function( - Sampler, - BoundingRectangle, Cartesian2, Cartesian3, - Cartesian4, Cartographic, - Color, defaultValue, defined, - defineProperties, - EncodedCartesian3, + DeveloperError, + EasingFunction, CesiumMath, - Matrix3, - Matrix4, - OrthographicFrustum, - Simon1994PlanetaryPositions, - Transforms, + PerspectiveFrustum, + PerspectiveOffCenterFrustum, SceneMode) { 'use strict'; /** + * Creates tweens for camera flights. + * <br /><br /> + * Mouse interaction is disabled during flights. + * * @private */ - function UniformState() { - /** - * @type {Texture} - */ - this.globeDepthTexture = undefined; + var CameraFlightPath = { + }; - this._viewport = new BoundingRectangle(); - this._viewportCartesian4 = new Cartesian4(); - this._viewportDirty = false; - this._viewportOrthographicMatrix = Matrix4.clone(Matrix4.IDENTITY); - this._viewportTransformation = Matrix4.clone(Matrix4.IDENTITY); + function getAltitude(frustum, dx, dy) { + var near; + var top; + var right; + if (frustum instanceof PerspectiveFrustum) { + var tanTheta = Math.tan(0.5 * frustum.fovy); + near = frustum.near; + top = frustum.near * tanTheta; + right = frustum.aspectRatio * top; + return Math.max(dx * near / right, dy * near / top); + } else if (frustum instanceof PerspectiveOffCenterFrustum) { + near = frustum.near; + top = frustum.top; + right = frustum.right; + return Math.max(dx * near / right, dy * near / top); + } - this._model = Matrix4.clone(Matrix4.IDENTITY); - this._view = Matrix4.clone(Matrix4.IDENTITY); - this._inverseView = Matrix4.clone(Matrix4.IDENTITY); - this._projection = Matrix4.clone(Matrix4.IDENTITY); - this._infiniteProjection = Matrix4.clone(Matrix4.IDENTITY); - this._entireFrustum = new Cartesian2(); - this._currentFrustum = new Cartesian2(); - this._frustumPlanes = new Cartesian4(); + return Math.max(dx, dy); + } - this._frameState = undefined; - this._temeToPseudoFixed = Matrix3.clone(Matrix4.IDENTITY); + var scratchCart = new Cartesian3(); + var scratchCart2 = new Cartesian3(); - // Derived members - this._view3DDirty = true; - this._view3D = new Matrix4(); + function createPitchFunction(startPitch, endPitch, heightFunction, pitchAdjustHeight) { + if (defined(pitchAdjustHeight) && heightFunction(0.5) > pitchAdjustHeight) { + var startHeight = heightFunction(0.0); + var endHeight = heightFunction(1.0); + var middleHeight = heightFunction(0.5); - this._inverseView3DDirty = true; - this._inverseView3D = new Matrix4(); + var d1 = middleHeight - startHeight; + var d2 = middleHeight - endHeight; - this._inverseModelDirty = true; - this._inverseModel = new Matrix4(); + return function(time) { + var altitude = heightFunction(time); + if (time <= 0.5) { + var t1 = (altitude - startHeight) / d1; + return CesiumMath.lerp(startPitch, -CesiumMath.PI_OVER_TWO, t1); + } - this._inverseTransposeModelDirty = true; - this._inverseTransposeModel = new Matrix3(); + var t2 = (altitude - endHeight) / d2; + return CesiumMath.lerp(-CesiumMath.PI_OVER_TWO, endPitch, 1 - t2); + }; + } + return function(time) { + return CesiumMath.lerp(startPitch, endPitch, time); + }; + } - this._viewRotation = new Matrix3(); - this._inverseViewRotation = new Matrix3(); + function createHeightFunction(camera, destination, startHeight, endHeight, optionAltitude) { + var altitude = optionAltitude; + var maxHeight = Math.max(startHeight, endHeight); - this._viewRotation3D = new Matrix3(); - this._inverseViewRotation3D = new Matrix3(); + if (!defined(altitude)) { + var start = camera.position; + var end = destination; + var up = camera.up; + var right = camera.right; + var frustum = camera.frustum; - this._inverseProjectionDirty = true; - this._inverseProjection = new Matrix4(); + var diff = Cartesian3.subtract(start, end, scratchCart); + var verticalDistance = Cartesian3.magnitude(Cartesian3.multiplyByScalar(up, Cartesian3.dot(diff, up), scratchCart2)); + var horizontalDistance = Cartesian3.magnitude(Cartesian3.multiplyByScalar(right, Cartesian3.dot(diff, right), scratchCart2)); - this._modelViewDirty = true; - this._modelView = new Matrix4(); + altitude = Math.min(getAltitude(frustum, verticalDistance, horizontalDistance) * 0.20, 1000000000.0); + } - this._modelView3DDirty = true; - this._modelView3D = new Matrix4(); + if (maxHeight < altitude) { + var power = 8.0; + var factor = 1000000.0; - this._modelViewRelativeToEyeDirty = true; - this._modelViewRelativeToEye = new Matrix4(); + var s = -Math.pow((altitude - startHeight) * factor, 1.0 / power); + var e = Math.pow((altitude - endHeight) * factor, 1.0 / power); - this._inverseModelViewDirty = true; - this._inverseModelView = new Matrix4(); + return function(t) { + var x = t * (e - s) + s; + return -Math.pow(x, power) / factor + altitude; + }; + } - this._inverseModelView3DDirty = true; - this._inverseModelView3D = new Matrix4(); + return function(t) { + return CesiumMath.lerp(startHeight, endHeight, t); + }; + } - this._viewProjectionDirty = true; - this._viewProjection = new Matrix4(); + function adjustAngleForLERP(startAngle, endAngle) { + if (CesiumMath.equalsEpsilon(startAngle, CesiumMath.TWO_PI, CesiumMath.EPSILON11)) { + startAngle = 0.0; + } - this._inverseViewProjectionDirty = true; - this._inverseViewProjection = new Matrix4(); + if (endAngle > startAngle + Math.PI) { + startAngle += CesiumMath.TWO_PI; + } else if (endAngle < startAngle - Math.PI) { + startAngle -= CesiumMath.TWO_PI; + } - this._modelViewProjectionDirty = true; - this._modelViewProjection = new Matrix4(); + return startAngle; + } - this._inverseModelViewProjectionDirty = true; - this._inverseModelViewProjection = new Matrix4(); + var scratchStart = new Cartesian3(); - this._modelViewProjectionRelativeToEyeDirty = true; - this._modelViewProjectionRelativeToEye = new Matrix4(); + function createUpdateCV(scene, duration, destination, heading, pitch, roll, optionAltitude) { + var camera = scene.camera; - this._modelViewInfiniteProjectionDirty = true; - this._modelViewInfiniteProjection = new Matrix4(); + var start = Cartesian3.clone(camera.position, scratchStart); + var startPitch = camera.pitch; + var startHeading = adjustAngleForLERP(camera.heading, heading); + var startRoll = adjustAngleForLERP(camera.roll, roll); - this._normalDirty = true; - this._normal = new Matrix3(); + var heightFunction = createHeightFunction(camera, destination, start.z, destination.z, optionAltitude); - this._normal3DDirty = true; - this._normal3D = new Matrix3(); + function update(value) { + var time = value.time / duration; - this._inverseNormalDirty = true; - this._inverseNormal = new Matrix3(); + camera.setView({ + orientation: { + heading : CesiumMath.lerp(startHeading, heading, time), + pitch : CesiumMath.lerp(startPitch, pitch, time), + roll : CesiumMath.lerp(startRoll, roll, time) + } + }); - this._inverseNormal3DDirty = true; - this._inverseNormal3D = new Matrix3(); + Cartesian2.lerp(start, destination, time, camera.position); + camera.position.z = heightFunction(time); + } + return update; + } - this._encodedCameraPositionMCDirty = true; - this._encodedCameraPositionMC = new EncodedCartesian3(); - this._cameraPosition = new Cartesian3(); + function useLongestFlight(startCart, destCart) { + if (startCart.longitude < destCart.longitude) { + startCart.longitude += CesiumMath.TWO_PI; + } else { + destCart.longitude += CesiumMath.TWO_PI; + } + } - this._sunPositionWC = new Cartesian3(); - this._sunPositionColumbusView = new Cartesian3(); - this._sunDirectionWC = new Cartesian3(); - this._sunDirectionEC = new Cartesian3(); - this._moonDirectionEC = new Cartesian3(); + function useShortestFlight(startCart, destCart) { + var diff = startCart.longitude - destCart.longitude; + if (diff < -CesiumMath.PI) { + startCart.longitude += CesiumMath.TWO_PI; + } else if (diff > CesiumMath.PI) { + destCart.longitude += CesiumMath.TWO_PI; + } + } - this._pass = undefined; - this._mode = undefined; - this._mapProjection = undefined; - this._cameraDirection = new Cartesian3(); - this._cameraRight = new Cartesian3(); - this._cameraUp = new Cartesian3(); - this._frustum2DWidth = 0.0; - this._eyeHeight2D = new Cartesian2(); - this._resolutionScale = 1.0; - this._orthographicIn3D = false; - this._backgroundColor = new Color(); + var scratchStartCart = new Cartographic(); + var scratchEndCart = new Cartographic(); - this._brdfLut = new Sampler(); - this._environmentMap = new Sampler(); + function createUpdate3D(scene, duration, destination, heading, pitch, roll, optionAltitude, optionFlyOverLongitude, optionFlyOverLongitudeWeight, optionPitchAdjustHeight) { + var camera = scene.camera; + var projection = scene.mapProjection; + var ellipsoid = projection.ellipsoid; - this._fogDensity = undefined; + var startCart = Cartographic.clone(camera.positionCartographic, scratchStartCart); + var startPitch = camera.pitch; + var startHeading = adjustAngleForLERP(camera.heading, heading); + var startRoll = adjustAngleForLERP(camera.roll, roll); - this._invertClassificationColor = undefined; + var destCart = ellipsoid.cartesianToCartographic(destination, scratchEndCart); + startCart.longitude = CesiumMath.zeroToTwoPi(startCart.longitude); + destCart.longitude = CesiumMath.zeroToTwoPi(destCart.longitude); - this._imagerySplitPosition = 0.0; - this._pixelSizePerMeter = undefined; - this._geometricToleranceOverMeter = undefined; + var useLongFlight = false; - this._minimumDisableDepthTestDistance = undefined; - } + if (defined(optionFlyOverLongitude)) { + var hitLon = CesiumMath.zeroToTwoPi(optionFlyOverLongitude); - defineProperties(UniformState.prototype, { - /** - * @memberof UniformState.prototype - * @type {FrameState} - * @readonly - */ - frameState : { - get : function() { - return this._frameState; - } - }, - /** - * @memberof UniformState.prototype - * @type {BoundingRectangle} - */ - viewport : { - get : function() { - return this._viewport; - }, - set : function(viewport) { - if (!BoundingRectangle.equals(viewport, this._viewport)) { - BoundingRectangle.clone(viewport, this._viewport); + var lonMin = Math.min(startCart.longitude, destCart.longitude); + var lonMax = Math.max(startCart.longitude, destCart.longitude); - var v = this._viewport; - var vc = this._viewportCartesian4; - vc.x = v.x; - vc.y = v.y; - vc.z = v.width; - vc.w = v.height; + var hitInside = (hitLon >= lonMin && hitLon <= lonMax); - this._viewportDirty = true; + if (defined(optionFlyOverLongitudeWeight)) { + // Distance inside (0...2Pi) + var din = Math.abs(startCart.longitude - destCart.longitude); + // Distance outside (0...2Pi) + var dot = CesiumMath.TWO_PI - din; + + var hitDistance = hitInside ? din : dot; + var offDistance = hitInside ? dot : din; + + if (hitDistance < offDistance * optionFlyOverLongitudeWeight && !hitInside) { + useLongFlight = true; } + } else if (!hitInside) { + useLongFlight = true; } - }, + } - /** - * @memberof UniformState.prototype - * @private - */ - viewportCartesian4 : { - get : function() { - return this._viewportCartesian4; - } - }, + if (useLongFlight) { + useLongestFlight(startCart, destCart); + } else { + useShortestFlight(startCart, destCart); + } - viewportOrthographic : { - get : function() { - cleanViewport(this); - return this._viewportOrthographicMatrix; - } - }, + var heightFunction = createHeightFunction(camera, destination, startCart.height, destCart.height, optionAltitude); + var pitchFunction = createPitchFunction(startPitch, pitch, heightFunction, optionPitchAdjustHeight); + + // Isolate scope for update function. + // to have local copies of vars used in lerp + // Othervise, if you call nex + // createUpdate3D (createAnimationTween) + // before you played animation, variables will be overwriten. + function isolateUpdateFunction() { + var startLongitude = startCart.longitude; + var destLongitude = destCart.longitude; + var startLatitude = startCart.latitude; + var destLatitude = destCart.latitude; - viewportTransformation : { - get : function() { - cleanViewport(this); - return this._viewportTransformation; - } - }, + return function update(value) { + var time = value.time / duration; - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - model : { - get : function() { - return this._model; - }, - set : function(matrix) { - Matrix4.clone(matrix, this._model); + var position = Cartesian3.fromRadians( + CesiumMath.lerp(startLongitude, destLongitude, time), + CesiumMath.lerp(startLatitude, destLatitude, time), + heightFunction(time) + ); - this._modelView3DDirty = true; - this._inverseModelView3DDirty = true; - this._inverseModelDirty = true; - this._inverseTransposeModelDirty = true; - this._modelViewDirty = true; - this._inverseModelViewDirty = true; - this._modelViewRelativeToEyeDirty = true; - this._inverseModelViewDirty = true; - this._modelViewProjectionDirty = true; - this._inverseModelViewProjectionDirty = true; - this._modelViewProjectionRelativeToEyeDirty = true; - this._modelViewInfiniteProjectionDirty = true; - this._normalDirty = true; - this._inverseNormalDirty = true; - this._normal3DDirty = true; - this._inverseNormal3DDirty = true; - this._encodedCameraPositionMCDirty = true; - } - }, + camera.setView({ + destination : position, + orientation: { + heading : CesiumMath.lerp(startHeading, heading, time), + pitch : pitchFunction(time), + roll : CesiumMath.lerp(startRoll, roll, time) + } + }); + }; + } + return isolateUpdateFunction(); + } - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseModel : { - get : function() { - if (this._inverseModelDirty) { - this._inverseModelDirty = false; + function createUpdate2D(scene, duration, destination, heading, pitch, roll, optionAltitude) { + var camera = scene.camera; - Matrix4.inverse(this._model, this._inverseModel); - } + var start = Cartesian3.clone(camera.position, scratchStart); + var startHeading = adjustAngleForLERP(camera.heading, heading); - return this._inverseModel; - } - }, + var startHeight = camera.frustum.right - camera.frustum.left; + var heightFunction = createHeightFunction(camera, destination, startHeight, destination.z, optionAltitude); - /** - * @memberof UniformState.prototype - * @private - */ - inverseTransposeModel : { - get : function() { - var m = this._inverseTransposeModel; - if (this._inverseTransposeModelDirty) { - this._inverseTransposeModelDirty = false; + function update(value) { + var time = value.time / duration; - Matrix4.getRotation(this.inverseModel, m); - Matrix3.transpose(m, m); + camera.setView({ + orientation: { + heading : CesiumMath.lerp(startHeading, heading, time) } + }); - return m; - } - }, + Cartesian2.lerp(start, destination, time, camera.position); - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - view : { - get : function() { - return this._view; - } - }, + var zoom = heightFunction(time); - /** - * The 3D view matrix. In 3D mode, this is identical to {@link UniformState#view}, - * but in 2D and Columbus View it is a synthetic matrix based on the equivalent position - * of the camera in the 3D world. - * @memberof UniformState.prototype - * @type {Matrix4} - */ - view3D : { - get : function() { - updateView3D(this); - return this._view3D; - } - }, + var frustum = camera.frustum; + var ratio = frustum.top / frustum.right; - /** - * The 3x3 rotation matrix of the current view matrix ({@link UniformState#view}). - * @memberof UniformState.prototype - * @type {Matrix3} - */ - viewRotation : { - get : function() { - updateView3D(this); - return this._viewRotation; - } - }, + var incrementAmount = (zoom - (frustum.right - frustum.left)) * 0.5; + frustum.right += incrementAmount; + frustum.left -= incrementAmount; + frustum.top = ratio * frustum.right; + frustum.bottom = -frustum.top; + } + return update; + } - /** - * @memberof UniformState.prototype - * @type {Matrix3} - */ - viewRotation3D : { - get : function() { - updateView3D(this); - return this._viewRotation3D; - } - }, + var scratchCartographic = new Cartographic(); + var scratchDestination = new Cartesian3(); - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseView : { - get : function() { - return this._inverseView; - } - }, + function emptyFlight(complete, cancel) { + return { + startObject : {}, + stopObject : {}, + duration : 0.0, + complete : complete, + cancel : cancel + }; + } - /** - * the 4x4 inverse-view matrix that transforms from eye to 3D world coordinates. In 3D mode, this is - * identical to {@link UniformState#inverseView}, but in 2D and Columbus View it is a synthetic matrix - * based on the equivalent position of the camera in the 3D world. - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseView3D : { - get : function() { - updateInverseView3D(this); - return this._inverseView3D; + function wrapCallback(controller, cb) { + function wrapped() { + if (typeof cb === 'function') { + cb(); } - }, - /** - * @memberof UniformState.prototype - * @type {Matrix3} - */ - inverseViewRotation : { - get : function() { - return this._inverseViewRotation; - } - }, + controller.enableInputs = true; + } + return wrapped; + } - /** - * The 3x3 rotation matrix of the current 3D inverse-view matrix ({@link UniformState#inverseView3D}). - * @memberof UniformState.prototype - * @type {Matrix3} - */ - inverseViewRotation3D : { - get : function() { - updateInverseView3D(this); - return this._inverseViewRotation3D; - } - }, + CameraFlightPath.createTween = function(scene, options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var destination = options.destination; - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - projection : { - get : function() { - return this._projection; - } - }, + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + if (!defined(destination)) { + throw new DeveloperError('destination is required.'); + } + var mode = scene.mode; - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseProjection : { - get : function() { - cleanInverseProjection(this); - return this._inverseProjection; - } - }, + if (mode === SceneMode.MORPHING) { + return emptyFlight(); + } - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - infiniteProjection : { - get : function() { - return this._infiniteProjection; - } - }, + var convert = defaultValue(options.convert, true); + var projection = scene.mapProjection; + var ellipsoid = projection.ellipsoid; + var maximumHeight = options.maximumHeight; + var flyOverLongitude = options.flyOverLongitude; + var flyOverLongitudeWeight = options.flyOverLongitudeWeight; + var pitchAdjustHeight = options.pitchAdjustHeight; + var easingFunction = options.easingFunction; - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - modelView : { - get : function() { - cleanModelView(this); - return this._modelView; - } - }, + if (convert && mode !== SceneMode.SCENE3D) { + ellipsoid.cartesianToCartographic(destination, scratchCartographic); + destination = projection.project(scratchCartographic, scratchDestination); + } - /** - * The 3D model-view matrix. In 3D mode, this is equivalent to {@link UniformState#modelView}. In 2D and - * Columbus View, however, it is a synthetic matrix based on the equivalent position of the camera in the 3D world. - * @memberof UniformState.prototype - * @type {Matrix4} - */ - modelView3D : { - get : function() { - cleanModelView3D(this); - return this._modelView3D; - } - }, + var camera = scene.camera; + var transform = options.endTransform; + if (defined(transform)) { + camera._setTransform(transform); + } - /** - * Model-view relative to eye matrix. - * - * @memberof UniformState.prototype - * @type {Matrix4} - */ - modelViewRelativeToEye : { - get : function() { - cleanModelViewRelativeToEye(this); - return this._modelViewRelativeToEye; - } - }, + var duration = options.duration; + if (!defined(duration)) { + duration = Math.ceil(Cartesian3.distance(camera.position, destination) / 1000000.0) + 2.0; + duration = Math.min(duration, 3.0); + } - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseModelView : { - get : function() { - cleanInverseModelView(this); - return this._inverseModelView; - } - }, + var heading = defaultValue(options.heading, 0.0); + var pitch = defaultValue(options.pitch, -CesiumMath.PI_OVER_TWO); + var roll = defaultValue(options.roll, 0.0); - /** - * The inverse of the 3D model-view matrix. In 3D mode, this is equivalent to {@link UniformState#inverseModelView}. - * In 2D and Columbus View, however, it is a synthetic matrix based on the equivalent position of the camera in the 3D world. - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseModelView3D : { - get : function() { - cleanInverseModelView3D(this); - return this._inverseModelView3D; + var controller = scene.screenSpaceCameraController; + controller.enableInputs = false; - } - }, + var complete = wrapCallback(controller, options.complete); + var cancel = wrapCallback(controller, options.cancel); - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - viewProjection : { - get : function() { - cleanViewProjection(this); - return this._viewProjection; - } - }, + var frustum = camera.frustum; - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseViewProjection : { - get : function() { - cleanInverseViewProjection(this); - return this._inverseViewProjection; - } - }, + var empty = scene.mode === SceneMode.SCENE2D; + empty = empty && Cartesian2.equalsEpsilon(camera.position, destination, CesiumMath.EPSILON6); + empty = empty && CesiumMath.equalsEpsilon(Math.max(frustum.right - frustum.left, frustum.top - frustum.bottom), destination.z, CesiumMath.EPSILON6); - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - modelViewProjection : { - get : function() { - cleanModelViewProjection(this); - return this._modelViewProjection; + empty = empty || (scene.mode !== SceneMode.SCENE2D && + Cartesian3.equalsEpsilon(destination, camera.position, CesiumMath.EPSILON10)); - } - }, + empty = empty && + CesiumMath.equalsEpsilon(CesiumMath.negativePiToPi(heading), CesiumMath.negativePiToPi(camera.heading), CesiumMath.EPSILON10) && + CesiumMath.equalsEpsilon(CesiumMath.negativePiToPi(pitch), CesiumMath.negativePiToPi(camera.pitch), CesiumMath.EPSILON10) && + CesiumMath.equalsEpsilon(CesiumMath.negativePiToPi(roll), CesiumMath.negativePiToPi(camera.roll), CesiumMath.EPSILON10); - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - inverseModelViewProjection : { - get : function() { - cleanInverseModelViewProjection(this); - return this._inverseModelViewProjection; + if (empty) { + return emptyFlight(complete, cancel); + } - } - }, + var updateFunctions = new Array(4); + updateFunctions[SceneMode.SCENE2D] = createUpdate2D; + updateFunctions[SceneMode.SCENE3D] = createUpdate3D; + updateFunctions[SceneMode.COLUMBUS_VIEW] = createUpdateCV; - /** - * Model-view-projection relative to eye matrix. - * - * @memberof UniformState.prototype - * @type {Matrix4} - */ - modelViewProjectionRelativeToEye : { - get : function() { - cleanModelViewProjectionRelativeToEye(this); - return this._modelViewProjectionRelativeToEye; - } - }, + if (duration <= 0.0) { + var newOnComplete = function() { + var update = updateFunctions[mode](scene, 1.0, destination, heading, pitch, roll, maximumHeight, flyOverLongitude, flyOverLongitudeWeight, pitchAdjustHeight); + update({ time: 1.0 }); - /** - * @memberof UniformState.prototype - * @type {Matrix4} - */ - modelViewInfiniteProjection : { - get : function() { - cleanModelViewInfiniteProjection(this); - return this._modelViewInfiniteProjection; - } - }, + if (typeof complete === 'function') { + complete(); + } + }; + return emptyFlight(newOnComplete, cancel); + } - /** - * A 3x3 normal transformation matrix that transforms normal vectors in model coordinates to - * eye coordinates. - * @memberof UniformState.prototype - * @type {Matrix3} - */ - normal : { - get : function() { - cleanNormal(this); - return this._normal; - } - }, + var update = updateFunctions[mode](scene, duration, destination, heading, pitch, roll, maximumHeight, flyOverLongitude, flyOverLongitudeWeight, pitchAdjustHeight); - /** - * A 3x3 normal transformation matrix that transforms normal vectors in 3D model - * coordinates to eye coordinates. In 3D mode, this is identical to - * {@link UniformState#normal}, but in 2D and Columbus View it represents the normal transformation - * matrix as if the camera were at an equivalent location in 3D mode. - * @memberof UniformState.prototype - * @type {Matrix3} - */ - normal3D : { - get : function() { - cleanNormal3D(this); - return this._normal3D; + if (!defined(easingFunction)) { + var startHeight = camera.positionCartographic.height; + var endHeight = mode === SceneMode.SCENE3D ? ellipsoid.cartesianToCartographic(destination).height : destination.z; + if (startHeight > endHeight && startHeight > 11500.0) { + easingFunction = EasingFunction.CUBIC_OUT; + } else { + easingFunction = EasingFunction.QUINTIC_IN_OUT; } - }, + } - /** - * An inverse 3x3 normal transformation matrix that transforms normal vectors in model coordinates - * to eye coordinates. - * @memberof UniformState.prototype - * @type {Matrix3} - */ - inverseNormal : { - get : function() { - cleanInverseNormal(this); - return this._inverseNormal; - } - }, + return { + duration : duration, + easingFunction : easingFunction, + startObject : { + time : 0.0 + }, + stopObject : { + time : duration + }, + update : update, + complete : complete, + cancel: cancel + }; + }; - /** - * An inverse 3x3 normal transformation matrix that transforms normal vectors in eye coordinates - * to 3D model coordinates. In 3D mode, this is identical to - * {@link UniformState#inverseNormal}, but in 2D and Columbus View it represents the normal transformation - * matrix as if the camera were at an equivalent location in 3D mode. - * @memberof UniformState.prototype - * @type {Matrix3} - */ - inverseNormal3D : { - get : function() { - cleanInverseNormal3D(this); - return this._inverseNormal3D; - } - }, + return CameraFlightPath; +}); - /** - * The near distance (<code>x</code>) and the far distance (<code>y</code>) of the frustum defined by the camera. - * This is the largest possible frustum, not an individual frustum used for multi-frustum rendering. - * @memberof UniformState.prototype - * @type {Cartesian2} - */ - entireFrustum : { - get : function() { - return this._entireFrustum; - } - }, +define('Scene/MapMode2D',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** + * Describes how the map will operate in 2D. + * + * @exports MapMode2D + */ + var MapMode2D = { /** - * The near distance (<code>x</code>) and the far distance (<code>y</code>) of the frustum defined by the camera. - * This is the individual frustum used for multi-frustum rendering. - * @memberof UniformState.prototype - * @type {Cartesian2} + * The 2D map can be rotated about the z axis. + * + * @type {Number} + * @constant */ - currentFrustum : { - get : function() { - return this._currentFrustum; - } - }, + ROTATE : 0, /** - * The distances to the frustum planes. The top, bottom, left and right distances are - * the x, y, z, and w components, respectively. - * @memberof UniformState.prototype - * @type {Cartesian4} + * The 2D map can be scrolled infinitely in the horizontal direction. + * + * @type {Number} + * @constant */ - frustumPlanes : { - get : function() { - return this._frustumPlanes; - } - }, + INFINITE_SCROLL : 1 + }; - /** - * The the height (<code>x</code>) and the height squared (<code>y</code>) - * in meters of the camera above the 2D world plane. This uniform is only valid - * when the {@link SceneMode} equal to <code>SCENE2D</code>. - * @memberof UniformState.prototype - * @type {Cartesian2} - */ - eyeHeight2D : { - get : function() { - return this._eyeHeight2D; - } - }, + return freezeObject(MapMode2D); +}); - /** - * The sun position in 3D world coordinates at the current scene time. - * @memberof UniformState.prototype - * @type {Cartesian3} - */ - sunPositionWC : { - get : function() { - return this._sunPositionWC; - } - }, +define('Scene/Camera',[ + '../Core/BoundingSphere', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/EasingFunction', + '../Core/Ellipsoid', + '../Core/EllipsoidGeodesic', + '../Core/Event', + '../Core/HeadingPitchRange', + '../Core/HeadingPitchRoll', + '../Core/Intersect', + '../Core/IntersectionTests', + '../Core/Math', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/OrthographicFrustum', + '../Core/OrthographicOffCenterFrustum', + '../Core/PerspectiveFrustum', + '../Core/Quaternion', + '../Core/Ray', + '../Core/Rectangle', + '../Core/Transforms', + './CameraFlightPath', + './MapMode2D', + './SceneMode' + ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + defaultValue, + defined, + defineProperties, + DeveloperError, + EasingFunction, + Ellipsoid, + EllipsoidGeodesic, + Event, + HeadingPitchRange, + HeadingPitchRoll, + Intersect, + IntersectionTests, + CesiumMath, + Matrix3, + Matrix4, + OrthographicFrustum, + OrthographicOffCenterFrustum, + PerspectiveFrustum, + Quaternion, + Ray, + Rectangle, + Transforms, + CameraFlightPath, + MapMode2D, + SceneMode) { + 'use strict'; - /** - * The sun position in 2D world coordinates at the current scene time. - * @memberof UniformState.prototype - * @type {Cartesian3} - */ - sunPositionColumbusView : { - get : function(){ - return this._sunPositionColumbusView; - } - }, + /** + * The camera is defined by a position, orientation, and view frustum. + * <br /><br /> + * The orientation forms an orthonormal basis with a view, up and right = view x up unit vectors. + * <br /><br /> + * The viewing frustum is defined by 6 planes. + * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components + * define the unit vector normal to the plane, and the w component is the distance of the + * plane from the origin/camera position. + * + * @alias Camera + * + * @constructor + * + * @param {Scene} scene The scene. + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Camera.html|Cesium Sandcastle Camera Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Camera%20Tutorial.html">Sandcastle Example</a> from the <a href="https://cesiumjs.org/2013/02/13/Cesium-Camera-Tutorial/|Camera Tutorial} + * + * @example + * // Create a camera looking down the negative z-axis, positioned at the origin, + * // with a field of view of 60 degrees, and 1:1 aspect ratio. + * var camera = new Cesium.Camera(scene); + * camera.position = new Cesium.Cartesian3(); + * camera.direction = Cesium.Cartesian3.negate(Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3()); + * camera.up = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_Y); + * camera.frustum.fov = Cesium.Math.PI_OVER_THREE; + * camera.frustum.near = 1.0; + * camera.frustum.far = 2.0; + */ + function Camera(scene) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); + } + this._scene = scene; - /** - * A normalized vector to the sun in 3D world coordinates at the current scene time. Even in 2D or - * Columbus View mode, this returns the position of the sun in the 3D scene. - * @memberof UniformState.prototype - * @type {Cartesian3} - */ - sunDirectionWC : { - get : function() { - return this._sunDirectionWC; - } - }, + this._transform = Matrix4.clone(Matrix4.IDENTITY); + this._invTransform = Matrix4.clone(Matrix4.IDENTITY); + this._actualTransform = Matrix4.clone(Matrix4.IDENTITY); + this._actualInvTransform = Matrix4.clone(Matrix4.IDENTITY); + this._transformChanged = false; /** - * A normalized vector to the sun in eye coordinates at the current scene time. In 3D mode, this - * returns the actual vector from the camera position to the sun position. In 2D and Columbus View, it returns - * the vector from the equivalent 3D camera position to the position of the sun in the 3D scene. - * @memberof UniformState.prototype + * The position of the camera. + * * @type {Cartesian3} */ - sunDirectionEC : { - get : function() { - return this._sunDirectionEC; - } - }, + this.position = new Cartesian3(); + this._position = new Cartesian3(); + this._positionWC = new Cartesian3(); + this._positionCartographic = new Cartographic(); /** - * A normalized vector to the moon in eye coordinates at the current scene time. In 3D mode, this - * returns the actual vector from the camera position to the moon position. In 2D and Columbus View, it returns - * the vector from the equivalent 3D camera position to the position of the moon in the 3D scene. - * @memberof UniformState.prototype + * The view direction of the camera. + * * @type {Cartesian3} */ - moonDirectionEC : { - get : function() { - return this._moonDirectionEC; - } - }, + this.direction = new Cartesian3(); + this._direction = new Cartesian3(); + this._directionWC = new Cartesian3(); /** - * The high bits of the camera position. - * @memberof UniformState.prototype + * The up direction of the camera. + * * @type {Cartesian3} */ - encodedCameraPositionMCHigh : { - get : function() { - cleanEncodedCameraPositionMC(this); - return this._encodedCameraPositionMC.high; - } - }, + this.up = new Cartesian3(); + this._up = new Cartesian3(); + this._upWC = new Cartesian3(); /** - * The low bits of the camera position. - * @memberof UniformState.prototype + * The right direction of the camera. + * * @type {Cartesian3} */ - encodedCameraPositionMCLow : { - get : function() { - cleanEncodedCameraPositionMC(this); - return this._encodedCameraPositionMC.low; - } - }, - - /** - * A 3x3 matrix that transforms from True Equator Mean Equinox (TEME) axes to the - * pseudo-fixed axes at the Scene's current time. - * @memberof UniformState.prototype - * @type {Matrix3} - */ - temeToPseudoFixedMatrix : { - get : function() { - return this._temeToPseudoFixed; - } - }, + this.right = new Cartesian3(); + this._right = new Cartesian3(); + this._rightWC = new Cartesian3(); /** - * Gets the scaling factor for transforming from the canvas - * pixel space to canvas coordinate space. - * @memberof UniformState.prototype - * @type {Number} + * The region of space in view. + * + * @type {Frustum} + * @default PerspectiveFrustum() + * + * @see PerspectiveFrustum + * @see PerspectiveOffCenterFrustum + * @see OrthographicFrustum */ - resolutionScale : { - get : function() { - return this._resolutionScale; - } - }, + this.frustum = new PerspectiveFrustum(); + this.frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + this.frustum.fov = CesiumMath.toRadians(60.0); /** - * A scalar used to mix a color with the fog color based on the distance to the camera. - * @memberof UniformState.prototype + * The default amount to move the camera when an argument is not + * provided to the move methods. * @type {Number} + * @default 100000.0; */ - fogDensity : { - get : function() { - return this._fogDensity; - } - }, - + this.defaultMoveAmount = 100000.0; /** - * A scalar that represents the geometric tolerance per meter - * @memberof UniformStat.prototype + * The default amount to rotate the camera when an argument is not + * provided to the look methods. * @type {Number} + * @default Math.PI / 60.0 */ - geometricToleranceOverMeter: { - get: function() { - return this._geometricToleranceOverMeter; - } - }, - - /** - * @memberof UniformState.prototype - * @type {Pass} - */ - pass : { - get : function() { - return this._pass; - } - }, - - /** - * The current background color - * @memberof UniformState.prototype - * @type {Color} - */ - backgroundColor : { - get : function() { - return this._backgroundColor; - } - }, - - /** - * The look up texture used to find the BRDF for a material - * @memberof UniformState.prototype - * @type {Sampler} - */ - brdfLut : { - get : function() { - return this._brdfLut; - } - }, - - /** - * The environment map of the scene - * @memberof UniformState.prototype - * @type {Sampler} - */ - environmentMap : { - get : function() { - return this._environmentMap; - } - }, - + this.defaultLookAmount = Math.PI / 60.0; /** - * @memberof UniformState.prototype + * The default amount to rotate the camera when an argument is not + * provided to the rotate methods. * @type {Number} + * @default Math.PI / 3600.0 */ - imagerySplitPosition : { - get : function() { - return this._imagerySplitPosition; - } - }, - + this.defaultRotateAmount = Math.PI / 3600.0; /** - * The distance from the camera at which to disable the depth test of billboards, labels and points - * to, for example, prevent clipping against terrain. When set to zero, the depth test should always - * be applied. When less than zero, the depth test should never be applied. - * - * @memberof UniformState.prototype + * The default amount to move the camera when an argument is not + * provided to the zoom methods. * @type {Number} + * @default 100000.0; */ - minimumDisableDepthTestDistance : { - get : function() { - return this._minimumDisableDepthTestDistance; - } - }, - + this.defaultZoomAmount = 100000.0; /** - * The highlight color of unclassified 3D Tiles. - * - * @memberof UniformState.prototype - * @type {Color} - */ - invertClassificationColor : { - get : function() { - return this._invertClassificationColor; - } - } - }); - - function setView(uniformState, matrix) { - Matrix4.clone(matrix, uniformState._view); - Matrix4.getRotation(matrix, uniformState._viewRotation); - - uniformState._view3DDirty = true; - uniformState._inverseView3DDirty = true; - uniformState._modelViewDirty = true; - uniformState._modelView3DDirty = true; - uniformState._modelViewRelativeToEyeDirty = true; - uniformState._inverseModelViewDirty = true; - uniformState._inverseModelView3DDirty = true; - uniformState._viewProjectionDirty = true; - uniformState._inverseViewProjectionDirty = true; - uniformState._modelViewProjectionDirty = true; - uniformState._modelViewProjectionRelativeToEyeDirty = true; - uniformState._modelViewInfiniteProjectionDirty = true; - uniformState._normalDirty = true; - uniformState._inverseNormalDirty = true; - uniformState._normal3DDirty = true; - uniformState._inverseNormal3DDirty = true; - } - - function setInverseView(uniformState, matrix) { - Matrix4.clone(matrix, uniformState._inverseView); - Matrix4.getRotation(matrix, uniformState._inverseViewRotation); - } - - function setProjection(uniformState, matrix) { - Matrix4.clone(matrix, uniformState._projection); - - uniformState._inverseProjectionDirty = true; - uniformState._viewProjectionDirty = true; - uniformState._inverseViewProjectionDirty = true; - uniformState._modelViewProjectionDirty = true; - uniformState._modelViewProjectionRelativeToEyeDirty = true; - } - - function setInfiniteProjection(uniformState, matrix) { - Matrix4.clone(matrix, uniformState._infiniteProjection); - - uniformState._modelViewInfiniteProjectionDirty = true; - } - - function setCamera(uniformState, camera) { - Cartesian3.clone(camera.positionWC, uniformState._cameraPosition); - Cartesian3.clone(camera.directionWC, uniformState._cameraDirection); - Cartesian3.clone(camera.rightWC, uniformState._cameraRight); - Cartesian3.clone(camera.upWC, uniformState._cameraUp); - uniformState._encodedCameraPositionMCDirty = true; - } - - var transformMatrix = new Matrix3(); - var sunCartographicScratch = new Cartographic(); - function setSunAndMoonDirections(uniformState, frameState) { - if (!defined(Transforms.computeIcrfToFixedMatrix(frameState.time, transformMatrix))) { - transformMatrix = Transforms.computeTemeToPseudoFixedMatrix(frameState.time, transformMatrix); - } - - var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(frameState.time, uniformState._sunPositionWC); - Matrix3.multiplyByVector(transformMatrix, position, position); - - Cartesian3.normalize(position, uniformState._sunDirectionWC); - - position = Matrix3.multiplyByVector(uniformState.viewRotation3D, position, uniformState._sunDirectionEC); - Cartesian3.normalize(position, position); - - position = Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(frameState.time, uniformState._moonDirectionEC); - Matrix3.multiplyByVector(transformMatrix, position, position); - Matrix3.multiplyByVector(uniformState.viewRotation3D, position, position); - Cartesian3.normalize(position, position); - - var projection = frameState.mapProjection; - var ellipsoid = projection.ellipsoid; - var sunCartographic = ellipsoid.cartesianToCartographic(uniformState._sunPositionWC, sunCartographicScratch); - projection.project(sunCartographic, uniformState._sunPositionColumbusView); - } - - /** - * Synchronizes the frustum's state with the camera state. This is called - * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms - * are set to the right value. - * - * @param {Object} camera The camera to synchronize with. - */ - UniformState.prototype.updateCamera = function(camera) { - setView(this, camera.viewMatrix); - setInverseView(this, camera.inverseViewMatrix); - setCamera(this, camera); - - this._entireFrustum.x = camera.frustum.near; - this._entireFrustum.y = camera.frustum.far; - this.updateFrustum(camera.frustum); - - this._orthographicIn3D = this._mode !== SceneMode.SCENE2D && camera.frustum instanceof OrthographicFrustum; - }; - - /** - * Synchronizes the frustum's state with the uniform state. This is called - * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms - * are set to the right value. - * - * @param {Object} frustum The frustum to synchronize with. - */ - UniformState.prototype.updateFrustum = function(frustum) { - setProjection(this, frustum.projectionMatrix); - if (defined(frustum.infiniteProjectionMatrix)) { - setInfiniteProjection(this, frustum.infiniteProjectionMatrix); - } - this._currentFrustum.x = frustum.near; - this._currentFrustum.y = frustum.far; - - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; - } - - this._frustumPlanes.x = frustum.top; - this._frustumPlanes.y = frustum.bottom; - this._frustumPlanes.z = frustum.left; - this._frustumPlanes.w = frustum.right; - }; - - UniformState.prototype.updatePass = function(pass) { - this._pass = pass; - }; - - /** - * Synchronizes frame state with the uniform state. This is called - * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms - * are set to the right value. - * - * @param {FrameState} frameState The frameState to synchronize with. - */ - UniformState.prototype.update = function(frameState) { - this._mode = frameState.mode; - this._mapProjection = frameState.mapProjection; + * If set, the camera will not be able to rotate past this axis in either direction. + * @type {Cartesian3} + * @default undefined + */ + this.constrainedAxis = undefined; + /** + * The factor multiplied by the the map size used to determine where to clamp the camera position + * when zooming out from the surface. The default is 1.5. Only valid for 2D and the map is rotatable. + * @type {Number} + * @default 1.5 + */ + this.maximumZoomFactor = 1.5; - var canvas = frameState.context._canvas; - this._resolutionScale = canvas.width / canvas.clientWidth; + this._moveStart = new Event(); + this._moveEnd = new Event(); - var camera = frameState.camera; - this.updateCamera(camera); + this._changed = new Event(); + this._changedPosition = undefined; + this._changedDirection = undefined; + this._changedFrustum = undefined; - if (frameState.mode === SceneMode.SCENE2D) { - this._frustum2DWidth = camera.frustum.right - camera.frustum.left; - this._eyeHeight2D.x = this._frustum2DWidth * 0.5; - this._eyeHeight2D.y = this._eyeHeight2D.x * this._eyeHeight2D.x; - } else { - this._frustum2DWidth = 0.0; - this._eyeHeight2D.x = 0.0; - this._eyeHeight2D.y = 0.0; - } + /** + * The amount the camera has to change before the <code>changed</code> event is raised. The value is a percentage in the [0, 1] range. + * @type {number} + * @default 0.5 + */ + this.percentageChanged = 0.5; - setSunAndMoonDirections(this, frameState); + this._viewMatrix = new Matrix4(); + this._invViewMatrix = new Matrix4(); + updateViewMatrix(this); - var brdfLutGenerator = frameState.brdfLutGenerator; - var brdfLut = defined(brdfLutGenerator) ? brdfLutGenerator.colorTexture : undefined; - this._brdfLut = brdfLut; + this._mode = SceneMode.SCENE3D; + this._modeChanged = true; + var projection = scene.mapProjection; + this._projection = projection; + this._maxCoord = projection.project(new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO)); + this._max2Dfrustum = undefined; + this._suspendTerrainAdjustment = false; - this._environmentMap = defaultValue(frameState.environmentMap, frameState.context.defaultCubeMap); + // set default view + rectangleCameraPosition3D(this, Camera.DEFAULT_VIEW_RECTANGLE, this.position, true); - this._fogDensity = frameState.fog.density; + var mag = Cartesian3.magnitude(this.position); + mag += mag * Camera.DEFAULT_VIEW_FACTOR; + Cartesian3.normalize(this.position, this.position); + Cartesian3.multiplyByScalar(this.position, mag, this.position); + } - this._invertClassificationColor = frameState.invertClassificationColor; + /** + * @private + */ + Camera.TRANSFORM_2D = new Matrix4( + 0.0, 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0); - this._frameState = frameState; - this._temeToPseudoFixed = Transforms.computeTemeToPseudoFixedMatrix(frameState.time, this._temeToPseudoFixed); + /** + * @private + */ + Camera.TRANSFORM_2D_INVERSE = Matrix4.inverseTransformation(Camera.TRANSFORM_2D, new Matrix4()); - // Convert the relative imagerySplitPosition to absolute pixel coordinates - this._imagerySplitPosition = frameState.imagerySplitPosition * frameState.context.drawingBufferWidth; - var fov = camera.frustum.fov; - var viewport = this._viewport; - var pixelSizePerMeter; - if (viewport.height > viewport.width) { - pixelSizePerMeter = Math.tan(0.5 * fov) * 2.0 / viewport.height; - } else { - pixelSizePerMeter = Math.tan(0.5 * fov) * 2.0 / viewport.width; - } + /** + * The default rectangle the camera will view on creation. + * @type Rectangle + */ + Camera.DEFAULT_VIEW_RECTANGLE = Rectangle.fromDegrees(-95.0, -20.0, -70.0, 90.0); - this._geometricToleranceOverMeter = pixelSizePerMeter * frameState.maximumScreenSpaceError; - Color.clone(frameState.backgroundColor, this._backgroundColor); + /** + * A scalar to multiply to the camera position and add it back after setting the camera to view the rectangle. + * A value of zero means the camera will view the entire {@link Camera#DEFAULT_VIEW_RECTANGLE}, a value greater than zero + * will move it further away from the extent, and a value less than zero will move it close to the extent. + * @type Number + */ + Camera.DEFAULT_VIEW_FACTOR = 0.5; - this._minimumDisableDepthTestDistance = frameState.minimumDisableDepthTestDistance; - this._minimumDisableDepthTestDistance *= this._minimumDisableDepthTestDistance; - if (this._minimumDisableDepthTestDistance === Number.POSITIVE_INFINITY) { - this._minimumDisableDepthTestDistance = -1.0; - } - }; + /** + * The default heading/pitch/range that is used when the camera flies to a location that contains a bounding sphere. + * @type HeadingPitchRange + */ + Camera.DEFAULT_OFFSET = new HeadingPitchRange(0.0, -CesiumMath.PI_OVER_FOUR, 0.0); - function cleanViewport(uniformState) { - if (uniformState._viewportDirty) { - var v = uniformState._viewport; - Matrix4.computeOrthographicOffCenter(v.x, v.x + v.width, v.y, v.y + v.height, 0.0, 1.0, uniformState._viewportOrthographicMatrix); - Matrix4.computeViewportTransformation(v, 0.0, 1.0, uniformState._viewportTransformation); - uniformState._viewportDirty = false; - } + function updateViewMatrix(camera) { + Matrix4.computeView(camera._position, camera._direction, camera._up, camera._right, camera._viewMatrix); + Matrix4.multiply(camera._viewMatrix, camera._actualInvTransform, camera._viewMatrix); + Matrix4.inverseTransformation(camera._viewMatrix, camera._invViewMatrix); } - function cleanInverseProjection(uniformState) { - if (uniformState._inverseProjectionDirty) { - uniformState._inverseProjectionDirty = false; + Camera.prototype._updateCameraChanged = function() { + var camera = this; - if (uniformState._mode !== SceneMode.SCENE2D && uniformState._mode !== SceneMode.MORPHING && !uniformState._orthographicIn3D) { - Matrix4.inverse(uniformState._projection, uniformState._inverseProjection); - } else { - Matrix4.clone(Matrix4.ZERO, uniformState._inverseProjection); - } + if (camera._changed.numberOfListeners === 0) { + return; } - } - - // Derived - function cleanModelView(uniformState) { - if (uniformState._modelViewDirty) { - uniformState._modelViewDirty = false; - Matrix4.multiplyTransformation(uniformState._view, uniformState._model, uniformState._modelView); - } - } + var percentageChanged = camera.percentageChanged; - function cleanModelView3D(uniformState) { - if (uniformState._modelView3DDirty) { - uniformState._modelView3DDirty = false; + if (camera._mode === SceneMode.SCENE2D) { + if (!defined(camera._changedFrustum)) { + camera._changedPosition = Cartesian3.clone(camera.position, camera._changedPosition); + camera._changedFrustum = camera.frustum.clone(); + return; + } - Matrix4.multiplyTransformation(uniformState.view3D, uniformState._model, uniformState._modelView3D); - } - } + var position = camera.position; + var lastPosition = camera._changedPosition; - function cleanInverseModelView(uniformState) { - if (uniformState._inverseModelViewDirty) { - uniformState._inverseModelViewDirty = false; + var frustum = camera.frustum; + var lastFrustum = camera._changedFrustum; - Matrix4.inverse(uniformState.modelView, uniformState._inverseModelView); - } - } + var x0 = position.x + frustum.left; + var x1 = position.x + frustum.right; + var x2 = lastPosition.x + lastFrustum.left; + var x3 = lastPosition.x + lastFrustum.right; - function cleanInverseModelView3D(uniformState) { - if (uniformState._inverseModelView3DDirty) { - uniformState._inverseModelView3DDirty = false; + var y0 = position.y + frustum.bottom; + var y1 = position.y + frustum.top; + var y2 = lastPosition.y + lastFrustum.bottom; + var y3 = lastPosition.y + lastFrustum.top; - Matrix4.inverse(uniformState.modelView3D, uniformState._inverseModelView3D); - } - } + var leftX = Math.max(x0, x2); + var rightX = Math.min(x1, x3); + var bottomY = Math.max(y0, y2); + var topY = Math.min(y1, y3); - function cleanViewProjection(uniformState) { - if (uniformState._viewProjectionDirty) { - uniformState._viewProjectionDirty = false; + var areaPercentage; + if (leftX >= rightX || bottomY >= y1) { + areaPercentage = 1.0; + } else { + var areaRef = lastFrustum; + if (x0 < x2 && x1 > x3 && y0 < y2 && y1 > y3) { + areaRef = frustum; + } + areaPercentage = 1.0 - ((rightX - leftX) * (topY - bottomY)) / ((areaRef.right - areaRef.left) * (areaRef.top - areaRef.bottom)); + } - Matrix4.multiply(uniformState._projection, uniformState._view, uniformState._viewProjection); + if (areaPercentage > percentageChanged) { + camera._changed.raiseEvent(areaPercentage); + camera._changedPosition = Cartesian3.clone(camera.position, camera._changedPosition); + camera._changedFrustum = camera.frustum.clone(camera._changedFrustum); + } + return; } - } - - function cleanInverseViewProjection(uniformState) { - if (uniformState._inverseViewProjectionDirty) { - uniformState._inverseViewProjectionDirty = false; - Matrix4.inverse(uniformState.viewProjection, uniformState._inverseViewProjection); + if (!defined(camera._changedDirection)) { + camera._changedPosition = Cartesian3.clone(camera.positionWC, camera._changedPosition); + camera._changedDirection = Cartesian3.clone(camera.directionWC, camera._changedDirection); + return; } - } - function cleanModelViewProjection(uniformState) { - if (uniformState._modelViewProjectionDirty) { - uniformState._modelViewProjectionDirty = false; + var dirAngle = CesiumMath.acosClamped(Cartesian3.dot(camera.directionWC, camera._changedDirection)); - Matrix4.multiply(uniformState._projection, uniformState.modelView, uniformState._modelViewProjection); + var dirPercentage; + if (defined(camera.frustum.fovy)) { + dirPercentage = dirAngle / (camera.frustum.fovy * 0.5); + } else { + dirPercentage = dirAngle; } - } - function cleanModelViewRelativeToEye(uniformState) { - if (uniformState._modelViewRelativeToEyeDirty) { - uniformState._modelViewRelativeToEyeDirty = false; + var distance = Cartesian3.distance(camera.positionWC, camera._changedPosition); + var heightPercentage = distance / camera.positionCartographic.height; - var mv = uniformState.modelView; - var mvRte = uniformState._modelViewRelativeToEye; - mvRte[0] = mv[0]; - mvRte[1] = mv[1]; - mvRte[2] = mv[2]; - mvRte[3] = mv[3]; - mvRte[4] = mv[4]; - mvRte[5] = mv[5]; - mvRte[6] = mv[6]; - mvRte[7] = mv[7]; - mvRte[8] = mv[8]; - mvRte[9] = mv[9]; - mvRte[10] = mv[10]; - mvRte[11] = mv[11]; - mvRte[12] = 0.0; - mvRte[13] = 0.0; - mvRte[14] = 0.0; - mvRte[15] = mv[15]; + if (dirPercentage > percentageChanged || heightPercentage > percentageChanged) { + camera._changed.raiseEvent(Math.max(dirPercentage, heightPercentage)); + camera._changedPosition = Cartesian3.clone(camera.positionWC, camera._changedPosition); + camera._changedDirection = Cartesian3.clone(camera.directionWC, camera._changedDirection); } - } + }; - function cleanInverseModelViewProjection(uniformState) { - if (uniformState._inverseModelViewProjectionDirty) { - uniformState._inverseModelViewProjectionDirty = false; + var scratchAdjustHeightTransform = new Matrix4(); + var scratchAdjustHeightCartographic = new Cartographic(); - Matrix4.inverse(uniformState.modelViewProjection, uniformState._inverseModelViewProjection); - } - } + Camera.prototype._adjustHeightForTerrain = function() { + var scene = this._scene; - function cleanModelViewProjectionRelativeToEye(uniformState) { - if (uniformState._modelViewProjectionRelativeToEyeDirty) { - uniformState._modelViewProjectionRelativeToEyeDirty = false; + var screenSpaceCameraController = scene.screenSpaceCameraController; + var enableCollisionDetection = screenSpaceCameraController.enableCollisionDetection; + var minimumCollisionTerrainHeight = screenSpaceCameraController.minimumCollisionTerrainHeight; + var minimumZoomDistance = screenSpaceCameraController.minimumZoomDistance; - Matrix4.multiply(uniformState._projection, uniformState.modelViewRelativeToEye, uniformState._modelViewProjectionRelativeToEye); + if (this._suspendTerrainAdjustment || !enableCollisionDetection) { + return; } - } - function cleanModelViewInfiniteProjection(uniformState) { - if (uniformState._modelViewInfiniteProjectionDirty) { - uniformState._modelViewInfiniteProjectionDirty = false; + var mode = this._mode; + var globe = scene.globe; - Matrix4.multiply(uniformState._infiniteProjection, uniformState.modelView, uniformState._modelViewInfiniteProjection); + if (!defined(globe) || mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { + return; } - } - function cleanNormal(uniformState) { - if (uniformState._normalDirty) { - uniformState._normalDirty = false; + var ellipsoid = globe.ellipsoid; + var projection = scene.mapProjection; - var m = uniformState._normal; - Matrix4.getRotation(uniformState.inverseModelView, m); - Matrix3.transpose(m, m); + var transform; + var mag; + if (!Matrix4.equals(this.transform, Matrix4.IDENTITY)) { + transform = Matrix4.clone(this.transform, scratchAdjustHeightTransform); + mag = Cartesian3.magnitude(this.position); + this._setTransform(Matrix4.IDENTITY); } - } - - function cleanNormal3D(uniformState) { - if (uniformState._normal3DDirty) { - uniformState._normal3DDirty = false; - var m = uniformState._normal3D; - Matrix4.getRotation(uniformState.inverseModelView3D, m); - Matrix3.transpose(m, m); + var cartographic = scratchAdjustHeightCartographic; + if (mode === SceneMode.SCENE3D) { + ellipsoid.cartesianToCartographic(this.position, cartographic); + } else { + projection.unproject(this.position, cartographic); } - } - function cleanInverseNormal(uniformState) { - if (uniformState._inverseNormalDirty) { - uniformState._inverseNormalDirty = false; - - Matrix4.getRotation(uniformState.inverseModelView, uniformState._inverseNormal); + var heightUpdated = false; + if (cartographic.height < minimumCollisionTerrainHeight) { + var height = globe.getHeight(cartographic); + if (defined(height)) { + height += minimumZoomDistance; + if (cartographic.height < height) { + cartographic.height = height; + if (mode === SceneMode.SCENE3D) { + ellipsoid.cartographicToCartesian(cartographic, this.position); + } else { + projection.project(cartographic, this.position); + } + heightUpdated = true; + } + } } - } - - function cleanInverseNormal3D(uniformState) { - if (uniformState._inverseNormal3DDirty) { - uniformState._inverseNormal3DDirty = false; - Matrix4.getRotation(uniformState.inverseModelView3D, uniformState._inverseNormal3D); + if (defined(transform)) { + this._setTransform(transform); + if (heightUpdated) { + Cartesian3.normalize(this.position, this.position); + Cartesian3.negate(this.position, this.direction); + Cartesian3.multiplyByScalar(this.position, Math.max(mag, minimumZoomDistance), this.position); + Cartesian3.normalize(this.direction, this.direction); + Cartesian3.cross(this.direction, this.up, this.right); + Cartesian3.cross(this.right, this.direction, this.up); + } } - } - - var cameraPositionMC = new Cartesian3(); - - function cleanEncodedCameraPositionMC(uniformState) { - if (uniformState._encodedCameraPositionMCDirty) { - uniformState._encodedCameraPositionMCDirty = false; + }; - Matrix4.multiplyByPoint(uniformState.inverseModel, uniformState._cameraPosition, cameraPositionMC); - EncodedCartesian3.fromCartesian(cameraPositionMC, uniformState._encodedCameraPositionMC); - } + function convertTransformForColumbusView(camera) { + Transforms.basisTo2D(camera._projection, camera._transform, camera._actualTransform); } - var view2Dto3DPScratch = new Cartesian3(); - var view2Dto3DRScratch = new Cartesian3(); - var view2Dto3DUScratch = new Cartesian3(); - var view2Dto3DDScratch = new Cartesian3(); - var view2Dto3DCartographicScratch = new Cartographic(); - var view2Dto3DCartesian3Scratch = new Cartesian3(); - var view2Dto3DMatrix4Scratch = new Matrix4(); - - function view2Dto3D(position2D, direction2D, right2D, up2D, frustum2DWidth, mode, projection, result) { - // The camera position and directions are expressed in the 2D coordinate system where the Y axis is to the East, - // the Z axis is to the North, and the X axis is out of the map. Express them instead in the ENU axes where - // X is to the East, Y is to the North, and Z is out of the local horizontal plane. - var p = view2Dto3DPScratch; - p.x = position2D.y; - p.y = position2D.z; - p.z = position2D.x; + var scratchCartographic = new Cartographic(); + var scratchCartesian3Projection = new Cartesian3(); + var scratchCartesian3 = new Cartesian3(); + var scratchCartesian4Origin = new Cartesian4(); + var scratchCartesian4NewOrigin = new Cartesian4(); + var scratchCartesian4NewXAxis = new Cartesian4(); + var scratchCartesian4NewYAxis = new Cartesian4(); + var scratchCartesian4NewZAxis = new Cartesian4(); - var r = view2Dto3DRScratch; - r.x = right2D.y; - r.y = right2D.z; - r.z = right2D.x; + function convertTransformFor2D(camera) { + var projection = camera._projection; + var ellipsoid = projection.ellipsoid; - var u = view2Dto3DUScratch; - u.x = up2D.y; - u.y = up2D.z; - u.z = up2D.x; + var origin = Matrix4.getColumn(camera._transform, 3, scratchCartesian4Origin); + var cartographic = ellipsoid.cartesianToCartographic(origin, scratchCartographic); - var d = view2Dto3DDScratch; - d.x = direction2D.y; - d.y = direction2D.z; - d.z = direction2D.x; + var projectedPosition = projection.project(cartographic, scratchCartesian3Projection); + var newOrigin = scratchCartesian4NewOrigin; + newOrigin.x = projectedPosition.z; + newOrigin.y = projectedPosition.x; + newOrigin.z = projectedPosition.y; + newOrigin.w = 1.0; - // In 2D, the camera height is always 12.7 million meters. - // The apparent height is equal to half the frustum width. - if (mode === SceneMode.SCENE2D) { - p.z = frustum2DWidth * 0.5; - } + var newZAxis = Cartesian4.clone(Cartesian4.UNIT_X, scratchCartesian4NewZAxis); - // Compute the equivalent camera position in the real (3D) world. - // In 2D and Columbus View, the camera can travel outside the projection, and when it does so - // there's not really any corresponding location in the real world. So clamp the unprojected - // longitude and latitude to their valid ranges. - var cartographic = projection.unproject(p, view2Dto3DCartographicScratch); - cartographic.longitude = CesiumMath.clamp(cartographic.longitude, -Math.PI, Math.PI); - cartographic.latitude = CesiumMath.clamp(cartographic.latitude, -CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO); - var ellipsoid = projection.ellipsoid; - var position3D = ellipsoid.cartographicToCartesian(cartographic, view2Dto3DCartesian3Scratch); + var xAxis = Cartesian4.add(Matrix4.getColumn(camera._transform, 0, scratchCartesian3), origin, scratchCartesian3); + ellipsoid.cartesianToCartographic(xAxis, cartographic); - // Compute the rotation from the local ENU at the real world camera position to the fixed axes. - var enuToFixed = Transforms.eastNorthUpToFixedFrame(position3D, ellipsoid, view2Dto3DMatrix4Scratch); + projection.project(cartographic, projectedPosition); + var newXAxis = scratchCartesian4NewXAxis; + newXAxis.x = projectedPosition.z; + newXAxis.y = projectedPosition.x; + newXAxis.z = projectedPosition.y; + newXAxis.w = 0.0; - // Transform each camera direction to the fixed axes. - Matrix4.multiplyByPointAsVector(enuToFixed, r, r); - Matrix4.multiplyByPointAsVector(enuToFixed, u, u); - Matrix4.multiplyByPointAsVector(enuToFixed, d, d); + Cartesian3.subtract(newXAxis, newOrigin, newXAxis); + newXAxis.x = 0.0; - // Compute the view matrix based on the new fixed-frame camera position and directions. - if (!defined(result)) { - result = new Matrix4(); - } + var newYAxis = scratchCartesian4NewYAxis; + if (Cartesian3.magnitudeSquared(newXAxis) > CesiumMath.EPSILON10) { + Cartesian3.cross(newZAxis, newXAxis, newYAxis); + } else { + var yAxis = Cartesian4.add(Matrix4.getColumn(camera._transform, 1, scratchCartesian3), origin, scratchCartesian3); + ellipsoid.cartesianToCartographic(yAxis, cartographic); - result[0] = r.x; - result[1] = u.x; - result[2] = -d.x; - result[3] = 0.0; - result[4] = r.y; - result[5] = u.y; - result[6] = -d.y; - result[7] = 0.0; - result[8] = r.z; - result[9] = u.z; - result[10] = -d.z; - result[11] = 0.0; - result[12] = -Cartesian3.dot(r, position3D); - result[13] = -Cartesian3.dot(u, position3D); - result[14] = Cartesian3.dot(d, position3D); - result[15] = 1.0; + projection.project(cartographic, projectedPosition); + newYAxis.x = projectedPosition.z; + newYAxis.y = projectedPosition.x; + newYAxis.z = projectedPosition.y; + newYAxis.w = 0.0; - return result; - } + Cartesian3.subtract(newYAxis, newOrigin, newYAxis); + newYAxis.x = 0.0; - function updateView3D(that) { - if (that._view3DDirty) { - if (that._mode === SceneMode.SCENE3D) { - Matrix4.clone(that._view, that._view3D); - } else { - view2Dto3D(that._cameraPosition, that._cameraDirection, that._cameraRight, that._cameraUp, that._frustum2DWidth, that._mode, that._mapProjection, that._view3D); + if (Cartesian3.magnitudeSquared(newYAxis) < CesiumMath.EPSILON10) { + Cartesian4.clone(Cartesian4.UNIT_Y, newXAxis); + Cartesian4.clone(Cartesian4.UNIT_Z, newYAxis); } - Matrix4.getRotation(that._view3D, that._viewRotation3D); - that._view3DDirty = false; } - } - function updateInverseView3D(that){ - if (that._inverseView3DDirty) { - Matrix4.inverseTransformation(that.view3D, that._inverseView3D); - Matrix4.getRotation(that._inverseView3D, that._inverseViewRotation3D); - that._inverseView3DDirty = false; - } - } + Cartesian3.cross(newYAxis, newZAxis, newXAxis); + Cartesian3.normalize(newXAxis, newXAxis); + Cartesian3.cross(newZAxis, newXAxis, newYAxis); + Cartesian3.normalize(newYAxis, newYAxis); - return UniformState; -}); + Matrix4.setColumn(camera._actualTransform, 0, newXAxis, camera._actualTransform); + Matrix4.setColumn(camera._actualTransform, 1, newYAxis, camera._actualTransform); + Matrix4.setColumn(camera._actualTransform, 2, newZAxis, camera._actualTransform); + Matrix4.setColumn(camera._actualTransform, 3, newOrigin, camera._actualTransform); + } -define('Renderer/Context',[ - '../Core/Check', - '../Core/clone', - '../Core/Color', - '../Core/ComponentDatatype', - '../Core/createGuid', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Geometry', - '../Core/GeometryAttribute', - '../Core/Matrix4', - '../Core/PrimitiveType', - '../Core/RuntimeError', - '../Core/WebGLConstants', - '../Shaders/ViewportQuadVS', - './BufferUsage', - './ClearCommand', - './ContextLimits', - './CubeMap', - './DrawCommand', - './PassState', - './PickFramebuffer', - './RenderState', - './ShaderCache', - './ShaderProgram', - './Texture', - './UniformState', - './VertexArray' -], function( - Check, - clone, - Color, - ComponentDatatype, - createGuid, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - Geometry, - GeometryAttribute, - Matrix4, - PrimitiveType, - RuntimeError, - WebGLConstants, - ViewportQuadVS, - BufferUsage, - ClearCommand, - ContextLimits, - CubeMap, - DrawCommand, - PassState, - PickFramebuffer, - RenderState, - ShaderCache, - ShaderProgram, - Texture, - UniformState, - VertexArray) { - 'use strict'; - /*global WebGLRenderingContext*/ + var scratchCartesian = new Cartesian3(); - /*global WebGL2RenderingContext*/ + function updateMembers(camera) { + var mode = camera._mode; - function errorToString(gl, error) { - var message = 'WebGL Error: '; - switch (error) { - case gl.INVALID_ENUM: - message += 'INVALID_ENUM'; - break; - case gl.INVALID_VALUE: - message += 'INVALID_VALUE'; - break; - case gl.INVALID_OPERATION: - message += 'INVALID_OPERATION'; - break; - case gl.OUT_OF_MEMORY: - message += 'OUT_OF_MEMORY'; - break; - case gl.CONTEXT_LOST_WEBGL: - message += 'CONTEXT_LOST_WEBGL lost'; - break; - default: - message += 'Unknown (' + error + ')'; + var heightChanged = false; + var height = 0.0; + if (mode === SceneMode.SCENE2D) { + height = camera.frustum.right - camera.frustum.left; + heightChanged = height !== camera._positionCartographic.height; } - return message; - } - - function createErrorMessage(gl, glFunc, glFuncArguments, error) { - var message = errorToString(gl, error) + ': ' + glFunc.name + '('; - - for (var i = 0; i < glFuncArguments.length; ++i) { - if (i !== 0) { - message += ', '; - } - message += glFuncArguments[i]; + var position = camera._position; + var positionChanged = !Cartesian3.equals(position, camera.position) || heightChanged; + if (positionChanged) { + position = Cartesian3.clone(camera.position, camera._position); } - message += ');'; - - return message; - } - function throwOnError(gl, glFunc, glFuncArguments) { - var error = gl.getError(); - if (error !== gl.NO_ERROR) { - throw new RuntimeError(createErrorMessage(gl, glFunc, glFuncArguments, error)); + var direction = camera._direction; + var directionChanged = !Cartesian3.equals(direction, camera.direction); + if (directionChanged) { + Cartesian3.normalize(camera.direction, camera.direction); + direction = Cartesian3.clone(camera.direction, camera._direction); } - } - - function makeGetterSetter(gl, propertyName, logFunction) { - return { - get : function() { - var value = gl[propertyName]; - logFunction(gl, 'get: ' + propertyName, value); - return gl[propertyName]; - }, - set : function(value) { - gl[propertyName] = value; - logFunction(gl, 'set: ' + propertyName, value); - } - }; - } - function wrapGL(gl, logFunction) { - if (!defined(logFunction)) { - return gl; + var up = camera._up; + var upChanged = !Cartesian3.equals(up, camera.up); + if (upChanged) { + Cartesian3.normalize(camera.up, camera.up); + up = Cartesian3.clone(camera.up, camera._up); } - function wrapFunction(property) { - return function() { - var result = property.apply(gl, arguments); - logFunction(gl, property, arguments); - return result; - }; + var right = camera._right; + var rightChanged = !Cartesian3.equals(right, camera.right); + if (rightChanged) { + Cartesian3.normalize(camera.right, camera.right); + right = Cartesian3.clone(camera.right, camera._right); } - var glWrapper = {}; + var transformChanged = camera._transformChanged || camera._modeChanged; + camera._transformChanged = false; - // JavaScript linters normally demand that a for..in loop must directly contain an if, - // but in our loop below, we actually intend to iterate all properties, including - // those in the prototype. - /*eslint-disable guard-for-in*/ - for (var propertyName in gl) { - var property = gl[propertyName]; + if (transformChanged) { + Matrix4.inverseTransformation(camera._transform, camera._invTransform); - // wrap any functions we encounter, otherwise just copy the property to the wrapper. - if (property instanceof Function) { - glWrapper[propertyName] = wrapFunction(property); + if (camera._mode === SceneMode.COLUMBUS_VIEW || camera._mode === SceneMode.SCENE2D) { + if (Matrix4.equals(Matrix4.IDENTITY, camera._transform)) { + Matrix4.clone(Camera.TRANSFORM_2D, camera._actualTransform); + } else if (camera._mode === SceneMode.COLUMBUS_VIEW) { + convertTransformForColumbusView(camera); + } else { + convertTransformFor2D(camera); + } } else { - Object.defineProperty(glWrapper, propertyName, makeGetterSetter(gl, propertyName, logFunction)); - } - } - /*eslint-enable guard-for-in*/ - - return glWrapper; - } - - function getExtension(gl, names) { - var length = names.length; - for (var i = 0; i < length; ++i) { - var extension = gl.getExtension(names[i]); - if (extension) { - return extension; + Matrix4.clone(camera._transform, camera._actualTransform); } - } - return undefined; - } + Matrix4.inverseTransformation(camera._actualTransform, camera._actualInvTransform); - /** - * @private - */ - function Context(canvas, options) { - // this check must use typeof, not defined, because defined doesn't work with undeclared variables. - if (typeof WebGLRenderingContext === 'undefined') { - throw new RuntimeError('The browser does not support WebGL. Visit http://get.webgl.org.'); + camera._modeChanged = false; } - Check.defined('canvas', canvas); - - this._canvas = canvas; - - options = clone(options, true); - options = defaultValue(options, {}); - options.allowTextureFilterAnisotropic = defaultValue(options.allowTextureFilterAnisotropic, true); - var webglOptions = defaultValue(options.webgl, {}); - - // Override select WebGL defaults - webglOptions.alpha = defaultValue(webglOptions.alpha, false); // WebGL default is true - webglOptions.stencil = defaultValue(webglOptions.stencil, true); // WebGL default is false + var transform = camera._actualTransform; - var requestWebgl2 = defaultValue(options.requestWebgl2, false) && (typeof WebGL2RenderingContext !== 'undefined'); - var webgl2 = false; + if (positionChanged || transformChanged) { + camera._positionWC = Matrix4.multiplyByPoint(transform, position, camera._positionWC); - var glContext; - var getWebGLStub = options.getWebGLStub; + // Compute the Cartographic position of the camera. + if (mode === SceneMode.SCENE3D || mode === SceneMode.MORPHING) { + camera._positionCartographic = camera._projection.ellipsoid.cartesianToCartographic(camera._positionWC, camera._positionCartographic); + } else { + // The camera position is expressed in the 2D coordinate system where the Y axis is to the East, + // the Z axis is to the North, and the X axis is out of the map. Express them instead in the ENU axes where + // X is to the East, Y is to the North, and Z is out of the local horizontal plane. + var positionENU = scratchCartesian; + positionENU.x = camera._positionWC.y; + positionENU.y = camera._positionWC.z; + positionENU.z = camera._positionWC.x; - if (!defined(getWebGLStub)) { - if (requestWebgl2) { - glContext = canvas.getContext('webgl2', webglOptions) || canvas.getContext('experimental-webgl2', webglOptions) || undefined; - if (defined(glContext)) { - webgl2 = true; + // In 2D, the camera height is always 12.7 million meters. + // The apparent height is equal to half the frustum width. + if (mode === SceneMode.SCENE2D) { + positionENU.z = height; } - } - if (!defined(glContext)) { - glContext = canvas.getContext('webgl', webglOptions) || canvas.getContext('experimental-webgl', webglOptions) || undefined; - } - if (!defined(glContext)) { - throw new RuntimeError('The browser supports WebGL, but initialization failed.'); - } - } else { - // Use WebGL stub when requested for unit tests - glContext = getWebGLStub(canvas, webglOptions); - } - - this._originalGLContext = glContext; - this._gl = glContext; - this._webgl2 = webgl2; - this._id = createGuid(); - - // Validation and logging disabled by default for speed. - this.validateFramebuffer = false; - this.validateShaderProgram = false; - this.logShaderCompilation = false; - this._throwOnWebGLError = false; - - this._shaderCache = new ShaderCache(this); - - var gl = glContext; - - this._stencilBits = gl.getParameter(gl.STENCIL_BITS); - - ContextLimits._maximumCombinedTextureImageUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); // min: 8 - ContextLimits._maximumCubeMapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); // min: 16 - ContextLimits._maximumFragmentUniformVectors = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); // min: 16 - ContextLimits._maximumTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); // min: 8 - ContextLimits._maximumRenderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE); // min: 1 - ContextLimits._maximumTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); // min: 64 - ContextLimits._maximumVaryingVectors = gl.getParameter(gl.MAX_VARYING_VECTORS); // min: 8 - ContextLimits._maximumVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); // min: 8 - ContextLimits._maximumVertexTextureImageUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); // min: 0 - ContextLimits._maximumVertexUniformVectors = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); // min: 128 - - var aliasedLineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE); // must include 1 - ContextLimits._minimumAliasedLineWidth = aliasedLineWidthRange[0]; - ContextLimits._maximumAliasedLineWidth = aliasedLineWidthRange[1]; - - var aliasedPointSizeRange = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE); // must include 1 - ContextLimits._minimumAliasedPointSize = aliasedPointSizeRange[0]; - ContextLimits._maximumAliasedPointSize = aliasedPointSizeRange[1]; - - var maximumViewportDimensions = gl.getParameter(gl.MAX_VIEWPORT_DIMS); - ContextLimits._maximumViewportWidth = maximumViewportDimensions[0]; - ContextLimits._maximumViewportHeight = maximumViewportDimensions[1]; - - var highpFloat = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); - ContextLimits._highpFloatSupported = highpFloat.precision !== 0; - var highpInt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT); - ContextLimits._highpIntSupported = highpInt.rangeMax !== 0; - - this._antialias = gl.getContextAttributes().antialias; - - // Query and initialize extensions - this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']); - this._blendMinmax = !!getExtension(gl, ['EXT_blend_minmax']); - this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']); - this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']); - this._textureFloat = !!getExtension(gl, ['OES_texture_float']); - this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']); - this._debugShaders = getExtension(gl, ['WEBGL_debug_shaders']); - - this._colorBufferFloat = this._webgl2 && !!getExtension(gl, ['EXT_color_buffer_float']); - - this._s3tc = !!getExtension(gl, ['WEBGL_compressed_texture_s3tc', 'MOZ_WEBGL_compressed_texture_s3tc', 'WEBKIT_WEBGL_compressed_texture_s3tc']); - this._pvrtc = !!getExtension(gl, ['WEBGL_compressed_texture_pvrtc', 'WEBKIT_WEBGL_compressed_texture_pvrtc']); - this._etc1 = !!getExtension(gl, ['WEBGL_compressed_texture_etc1']); - - var textureFilterAnisotropic = options.allowTextureFilterAnisotropic ? getExtension(gl, ['EXT_texture_filter_anisotropic', 'WEBKIT_EXT_texture_filter_anisotropic']) : undefined; - this._textureFilterAnisotropic = textureFilterAnisotropic; - ContextLimits._maximumTextureFilterAnisotropy = defined(textureFilterAnisotropic) ? gl.getParameter(textureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 1.0; - - var glCreateVertexArray; - var glBindVertexArray; - var glDeleteVertexArray; - - var glDrawElementsInstanced; - var glDrawArraysInstanced; - var glVertexAttribDivisor; - - var glDrawBuffers; - - var vertexArrayObject; - var instancedArrays; - var drawBuffers; - - if (webgl2) { - var that = this; - - glCreateVertexArray = function() { - return that._gl.createVertexArray(); - }; - glBindVertexArray = function(vao) { - that._gl.bindVertexArray(vao); - }; - glDeleteVertexArray = function(vao) { - that._gl.deleteVertexArray(vao); - }; - - glDrawElementsInstanced = function(mode, count, type, offset, instanceCount) { - gl.drawElementsInstanced(mode, count, type, offset, instanceCount); - }; - glDrawArraysInstanced = function(mode, first, count, instanceCount) { - gl.drawArraysInstanced(mode, first, count, instanceCount); - }; - glVertexAttribDivisor = function(index, divisor) { - gl.vertexAttribDivisor(index, divisor); - }; - - glDrawBuffers = function(buffers) { - gl.drawBuffers(buffers); - }; - } else { - vertexArrayObject = getExtension(gl, ['OES_vertex_array_object']); - if (defined(vertexArrayObject)) { - glCreateVertexArray = function() { - return vertexArrayObject.createVertexArrayOES(); - }; - glBindVertexArray = function(vertexArray) { - vertexArrayObject.bindVertexArrayOES(vertexArray); - }; - glDeleteVertexArray = function(vertexArray) { - vertexArrayObject.deleteVertexArrayOES(vertexArray); - }; + camera._projection.unproject(positionENU, camera._positionCartographic); } + } - instancedArrays = getExtension(gl, ['ANGLE_instanced_arrays']); - if (defined(instancedArrays)) { - glDrawElementsInstanced = function(mode, count, type, offset, instanceCount) { - instancedArrays.drawElementsInstancedANGLE(mode, count, type, offset, instanceCount); - }; - glDrawArraysInstanced = function(mode, first, count, instanceCount) { - instancedArrays.drawArraysInstancedANGLE(mode, first, count, instanceCount); - }; - glVertexAttribDivisor = function(index, divisor) { - instancedArrays.vertexAttribDivisorANGLE(index, divisor); - }; - } + if (directionChanged || upChanged || rightChanged) { + var det = Cartesian3.dot(direction, Cartesian3.cross(up, right, scratchCartesian)); + if (Math.abs(1.0 - det) > CesiumMath.EPSILON2) { + //orthonormalize axes + var invUpMag = 1.0 / Cartesian3.magnitudeSquared(up); + var scalar = Cartesian3.dot(up, direction) * invUpMag; + var w0 = Cartesian3.multiplyByScalar(direction, scalar, scratchCartesian); + up = Cartesian3.normalize(Cartesian3.subtract(up, w0, camera._up), camera._up); + Cartesian3.clone(up, camera.up); - drawBuffers = getExtension(gl, ['WEBGL_draw_buffers']); - if (defined(drawBuffers)) { - glDrawBuffers = function(buffers) { - drawBuffers.drawBuffersWEBGL(buffers); - }; + right = Cartesian3.cross(direction, up, camera._right); + Cartesian3.clone(right, camera.right); } } - this.glCreateVertexArray = glCreateVertexArray; - this.glBindVertexArray = glBindVertexArray; - this.glDeleteVertexArray = glDeleteVertexArray; - - this.glDrawElementsInstanced = glDrawElementsInstanced; - this.glDrawArraysInstanced = glDrawArraysInstanced; - this.glVertexAttribDivisor = glVertexAttribDivisor; - - this.glDrawBuffers = glDrawBuffers; - - this._vertexArrayObject = !!vertexArrayObject; - this._instancedArrays = !!instancedArrays; - this._drawBuffers = !!drawBuffers; - - ContextLimits._maximumDrawBuffers = this.drawBuffers ? gl.getParameter(WebGLConstants.MAX_DRAW_BUFFERS) : 1; - ContextLimits._maximumColorAttachments = this.drawBuffers ? gl.getParameter(WebGLConstants.MAX_COLOR_ATTACHMENTS) : 1; - - this._clearColor = new Color(0.0, 0.0, 0.0, 0.0); - this._clearDepth = 1.0; - this._clearStencil = 0; - - var us = new UniformState(); - var ps = new PassState(this); - var rs = RenderState.fromCache(); - - this._defaultPassState = ps; - this._defaultRenderState = rs; - this._defaultTexture = undefined; - this._defaultCubeMap = undefined; - - this._us = us; - this._currentRenderState = rs; - this._currentPassState = ps; - this._currentFramebuffer = undefined; - this._maxFrameTextureUnitIndex = 0; - - // Vertex attribute divisor state cache. Workaround for ANGLE (also look at VertexArray.setVertexAttribDivisor) - this._vertexAttribDivisors = []; - this._previousDrawInstanced = false; - for (var i = 0; i < ContextLimits._maximumVertexAttributes; i++) { - this._vertexAttribDivisors.push(0); + if (directionChanged || transformChanged) { + camera._directionWC = Matrix4.multiplyByPointAsVector(transform, direction, camera._directionWC); + Cartesian3.normalize(camera._directionWC, camera._directionWC); } - this._pickObjects = {}; - this._nextPickColor = new Uint32Array(1); - - /** - * @example - * { - * webgl : { - * alpha : false, - * depth : true, - * stencil : false, - * antialias : true, - * premultipliedAlpha : true, - * preserveDrawingBuffer : false, - * failIfMajorPerformanceCaveat : true - * }, - * allowTextureFilterAnisotropic : true - * } - */ - this.options = options; + if (upChanged || transformChanged) { + camera._upWC = Matrix4.multiplyByPointAsVector(transform, up, camera._upWC); + Cartesian3.normalize(camera._upWC, camera._upWC); + } - /** - * A cache of objects tied to this context. Just before the Context is destroyed, - * <code>destroy</code> will be invoked on each object in this object literal that has - * such a method. This is useful for caching any objects that might otherwise - * be stored globally, except they're tied to a particular context, and to manage - * their lifetime. - * - * @type {Object} - */ - this.cache = {}; + if (rightChanged || transformChanged) { + camera._rightWC = Matrix4.multiplyByPointAsVector(transform, right, camera._rightWC); + Cartesian3.normalize(camera._rightWC, camera._rightWC); + } - RenderState.apply(gl, rs, ps); + if (positionChanged || directionChanged || upChanged || rightChanged || transformChanged) { + updateViewMatrix(camera); + } } - var defaultFramebufferMarker = {}; - - defineProperties(Context.prototype, { - id : { - get : function() { - return this._id; - } - }, - webgl2 : { - get : function() { - return this._webgl2; - } - }, - canvas : { - get : function() { - return this._canvas; - } - }, - shaderCache : { - get : function() { - return this._shaderCache; - } - }, - uniformState : { - get : function() { - return this._us; - } - }, + function getHeading(direction, up) { + var heading; + if (!CesiumMath.equalsEpsilon(Math.abs(direction.z), 1.0, CesiumMath.EPSILON3)) { + heading = Math.atan2(direction.y, direction.x) - CesiumMath.PI_OVER_TWO; + } else { + heading = Math.atan2(up.y, up.x) - CesiumMath.PI_OVER_TWO; + } - /** - * The number of stencil bits per pixel in the default bound framebuffer. The minimum is eight bits. - * @memberof Context.prototype - * @type {Number} - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>STENCIL_BITS</code>. - */ - stencilBits : { - get : function() { - return this._stencilBits; - } - }, + return CesiumMath.TWO_PI - CesiumMath.zeroToTwoPi(heading); + } - /** - * <code>true</code> if the WebGL context supports stencil buffers. - * Stencil buffers are not supported by all systems. - * @memberof Context.prototype - * @type {Boolean} - */ - stencilBuffer : { - get : function() { - return this._stencilBits >= 8; - } - }, + function getPitch(direction) { + return CesiumMath.PI_OVER_TWO - CesiumMath.acosClamped(direction.z); + } - /** - * <code>true</code> if the WebGL context supports antialiasing. By default - * antialiasing is requested, but it is not supported by all systems. - * @memberof Context.prototype - * @type {Boolean} - */ - antialias : { - get : function() { - return this._antialias; - } - }, + function getRoll(direction, up, right) { + var roll = 0.0; + if (!CesiumMath.equalsEpsilon(Math.abs(direction.z), 1.0, CesiumMath.EPSILON3)) { + roll = Math.atan2(-right.z, up.z); + roll = CesiumMath.zeroToTwoPi(roll + CesiumMath.TWO_PI); + } - /** - * <code>true</code> if the OES_standard_derivatives extension is supported. This - * extension provides access to <code>dFdx</code>, <code>dFdy</code>, and <code>fwidth</code> - * functions from GLSL. A shader using these functions still needs to explicitly enable the - * extension with <code>#extension GL_OES_standard_derivatives : enable</code>. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/gles/extensions/OES/OES_standard_derivatives.txt|OES_standard_derivatives} - */ - standardDerivatives : { - get : function() { - return this._standardDerivatives || this._webgl2; - } - }, + return roll; + } - /** - * <code>true</code> if the EXT_blend_minmax extension is supported. This - * extension extends blending capabilities by adding two new blend equations: - * the minimum or maximum color components of the source and destination colors. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/} - */ - blendMinmax : { - get : function() { - return this._blendMinmax || this._webgl2; - } - }, + var scratchHPRMatrix1 = new Matrix4(); + var scratchHPRMatrix2 = new Matrix4(); + defineProperties(Camera.prototype, { /** - * <code>true</code> if the OES_element_index_uint extension is supported. This - * extension allows the use of unsigned int indices, which can improve performance by - * eliminating batch breaking caused by unsigned short indices. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/|OES_element_index_uint} + * Gets the camera's reference frame. The inverse of this transformation is appended to the view matrix. + * @memberof Camera.prototype + * + * @type {Matrix4} + * @readonly + * + * @default {@link Matrix4.IDENTITY} */ - elementIndexUint : { + transform : { get : function() { - return this._elementIndexUint || this._webgl2; + return this._transform; } }, /** - * <code>true</code> if WEBGL_depth_texture is supported. This extension provides - * access to depth textures that, for example, can be attached to framebuffers for shadow mapping. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} + * Gets the inverse camera transform. + * @memberof Camera.prototype + * + * @type {Matrix4} + * @readonly + * + * @default {@link Matrix4.IDENTITY} */ - depthTexture : { + inverseTransform : { get : function() { - return this._depthTexture || this._webgl2; + updateMembers(this); + return this._invTransform; } }, /** - * <code>true</code> if OES_texture_float is supported. This extension provides - * access to floating point textures that, for example, can be attached to framebuffers for high dynamic range. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/gles/extensions/OES/OES_texture_float.txt|OES_texture_float} + * Gets the view matrix. + * @memberof Camera.prototype + * + * @type {Matrix4} + * @readonly + * + * @see Camera#inverseViewMatrix */ - floatingPointTexture : { - get : function() { - return this._textureFloat || this._colorBufferFloat; - } - }, - - textureFilterAnisotropic : { + viewMatrix : { get : function() { - return !!this._textureFilterAnisotropic; + updateMembers(this); + return this._viewMatrix; } }, /** - * <code>true</code> if WEBGL_texture_compression_s3tc is supported. This extension provides - * access to DXT compressed textures. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/} + * Gets the inverse view matrix. + * @memberof Camera.prototype + * + * @type {Matrix4} + * @readonly + * + * @see Camera#viewMatrix */ - s3tc : { + inverseViewMatrix : { get : function() { - return this._s3tc; + updateMembers(this); + return this._invViewMatrix; } }, /** - * <code>true</code> if WEBGL_texture_compression_pvrtc is supported. This extension provides - * access to PVR compressed textures. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/} + * Gets the {@link Cartographic} position of the camera, with longitude and latitude + * expressed in radians and height in meters. In 2D and Columbus View, it is possible + * for the returned longitude and latitude to be outside the range of valid longitudes + * and latitudes when the camera is outside the map. + * @memberof Camera.prototype + * + * @type {Cartographic} + * @readonly */ - pvrtc : { + positionCartographic : { get : function() { - return this._pvrtc; + updateMembers(this); + return this._positionCartographic; } }, /** - * <code>true</code> if WEBGL_texture_compression_etc1 is supported. This extension provides - * access to ETC1 compressed textures. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/} + * Gets the position of the camera in world coordinates. + * @memberof Camera.prototype + * + * @type {Cartesian3} + * @readonly */ - etc1 : { + positionWC : { get : function() { - return this._etc1; + updateMembers(this); + return this._positionWC; } }, /** - * <code>true</code> if the OES_vertex_array_object extension is supported. This - * extension can improve performance by reducing the overhead of switching vertex arrays. - * When enabled, this extension is automatically used by {@link VertexArray}. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/|OES_vertex_array_object} + * Gets the view direction of the camera in world coordinates. + * @memberof Camera.prototype + * + * @type {Cartesian3} + * @readonly */ - vertexArrayObject : { + directionWC : { get : function() { - return this._vertexArrayObject || this._webgl2; + updateMembers(this); + return this._directionWC; } }, /** - * <code>true</code> if the EXT_frag_depth extension is supported. This - * extension provides access to the <code>gl_FragDepthEXT</code> built-in output variable - * from GLSL fragment shaders. A shader using these functions still needs to explicitly enable the - * extension with <code>#extension GL_EXT_frag_depth : enable</code>. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/|EXT_frag_depth} + * Gets the up direction of the camera in world coordinates. + * @memberof Camera.prototype + * + * @type {Cartesian3} + * @readonly */ - fragmentDepth : { + upWC : { get : function() { - return this._fragDepth || this._webgl2; + updateMembers(this); + return this._upWC; } }, /** - * <code>true</code> if the ANGLE_instanced_arrays extension is supported. This - * extension provides access to instanced rendering. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays} + * Gets the right direction of the camera in world coordinates. + * @memberof Camera.prototype + * + * @type {Cartesian3} + * @readonly */ - instancedArrays : { + rightWC : { get : function() { - return this._instancedArrays || this._webgl2; + updateMembers(this); + return this._rightWC; } }, /** - * <code>true</code> if the EXT_color_buffer_float extension is supported. This - * extension makes the formats gl.R16F, gl.RG16F, gl.RGBA16F, gl.R32F, gl.RG32F, - * gl.RGBA32F, gl.R11F_G11F_B10F color renderable. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/} + * Gets the camera heading in radians. + * @memberof Camera.prototype + * + * @type {Number} + * @readonly */ - colorBufferFloat : { + heading : { get : function() { - return this._colorBufferFloat; - } - }, + if (this._mode !== SceneMode.MORPHING) { + var ellipsoid = this._projection.ellipsoid; - /** - * <code>true</code> if the WEBGL_draw_buffers extension is supported. This - * extensions provides support for multiple render targets. The framebuffer object can have mutiple - * color attachments and the GLSL fragment shader can write to the built-in output array <code>gl_FragData</code>. - * A shader using this feature needs to explicitly enable the extension with - * <code>#extension GL_EXT_draw_buffers : enable</code>. - * @memberof Context.prototype - * @type {Boolean} - * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_draw_buffers/|WEBGL_draw_buffers} - */ - drawBuffers : { - get : function() { - return this._drawBuffers || this._webgl2; - } - }, + var oldTransform = Matrix4.clone(this._transform, scratchHPRMatrix1); + var transform = Transforms.eastNorthUpToFixedFrame(this.positionWC, ellipsoid, scratchHPRMatrix2); + this._setTransform(transform); - debugShaders : { - get : function() { - return this._debugShaders; - } - }, + var heading = getHeading(this.direction, this.up); - throwOnWebGLError : { - get : function() { - return this._throwOnWebGLError; - }, - set : function(value) { - this._throwOnWebGLError = value; - this._gl = wrapGL(this._originalGLContext, value ? throwOnError : undefined); + this._setTransform(oldTransform); + + return heading; + } + + return undefined; } }, /** - * A 1x1 RGBA texture initialized to [255, 255, 255, 255]. This can - * be used as a placeholder texture while other textures are downloaded. - * @memberof Context.prototype - * @type {Texture} + * Gets the camera pitch in radians. + * @memberof Camera.prototype + * + * @type {Number} + * @readonly */ - defaultTexture : { + pitch : { get : function() { - if (this._defaultTexture === undefined) { - this._defaultTexture = new Texture({ - context : this, - source : { - width : 1, - height : 1, - arrayBufferView : new Uint8Array([255, 255, 255, 255]) - } - }); + if (this._mode !== SceneMode.MORPHING) { + var ellipsoid = this._projection.ellipsoid; + + var oldTransform = Matrix4.clone(this._transform, scratchHPRMatrix1); + var transform = Transforms.eastNorthUpToFixedFrame(this.positionWC, ellipsoid, scratchHPRMatrix2); + this._setTransform(transform); + + var pitch = getPitch(this.direction); + + this._setTransform(oldTransform); + + return pitch; } - return this._defaultTexture; + return undefined; } }, /** - * A cube map, where each face is a 1x1 RGBA texture initialized to - * [255, 255, 255, 255]. This can be used as a placeholder cube map while - * other cube maps are downloaded. - * @memberof Context.prototype - * @type {CubeMap} + * Gets the camera roll in radians. + * @memberof Camera.prototype + * + * @type {Number} + * @readonly */ - defaultCubeMap : { + roll : { get : function() { - if (this._defaultCubeMap === undefined) { - var face = { - width : 1, - height : 1, - arrayBufferView : new Uint8Array([255, 255, 255, 255]) - }; + if (this._mode !== SceneMode.MORPHING) { + var ellipsoid = this._projection.ellipsoid; - this._defaultCubeMap = new CubeMap({ - context : this, - source : { - positiveX : face, - negativeX : face, - positiveY : face, - negativeY : face, - positiveZ : face, - negativeZ : face - } - }); - } + var oldTransform = Matrix4.clone(this._transform, scratchHPRMatrix1); + var transform = Transforms.eastNorthUpToFixedFrame(this.positionWC, ellipsoid, scratchHPRMatrix2); + this._setTransform(transform); - return this._defaultCubeMap; + var roll = getRoll(this.direction, this.up, this.right); + this._setTransform(oldTransform); + + return roll; + } + + return undefined; } }, /** - * The drawingBufferHeight of the underlying GL context. - * @memberof Context.prototype - * @type {Number} - * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} + * Gets the event that will be raised at when the camera starts to move. + * @memberof Camera.prototype + * @type {Event} + * @readonly */ - drawingBufferHeight : { + moveStart : { get : function() { - return this._gl.drawingBufferHeight; + return this._moveStart; } }, /** - * The drawingBufferWidth of the underlying GL context. - * @memberof Context.prototype - * @type {Number} - * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferWidth|drawingBufferWidth} + * Gets the event that will be raised when the camera has stopped moving. + * @memberof Camera.prototype + * @type {Event} + * @readonly */ - drawingBufferWidth : { + moveEnd : { get : function() { - return this._gl.drawingBufferWidth; + return this._moveEnd; } }, /** - * Gets an object representing the currently bound framebuffer. While this instance is not an actual - * {@link Framebuffer}, it is used to represent the default framebuffer in calls to - * {@link Texture.FromFramebuffer}. - * @memberof Context.prototype - * @type {Object} + * Gets the event that will be raised when the camera has changed by <code>percentageChanged</code>. + * @memberof Camera.prototype + * @type {Event} + * @readonly */ - defaultFramebuffer : { + changed : { get : function() { - return defaultFramebufferMarker; + return this._changed; } } }); /** - * Validates a framebuffer. - * Available in debug builds only. * @private */ - function validateFramebuffer(context) { - if (context.validateFramebuffer) { - var gl = context._gl; - var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); - - if (status !== gl.FRAMEBUFFER_COMPLETE) { - var message; - - switch (status) { - case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - message = 'Framebuffer is not complete. Incomplete attachment: at least one attachment point with a renderbuffer or texture attached has its attached object no longer in existence or has an attached image with a width or height of zero, or the color attachment point has a non-color-renderable image attached, or the depth attachment point has a non-depth-renderable image attached, or the stencil attachment point has a non-stencil-renderable image attached. Color-renderable formats include GL_RGBA4, GL_RGB5_A1, and GL_RGB565. GL_DEPTH_COMPONENT16 is the only depth-renderable format. GL_STENCIL_INDEX8 is the only stencil-renderable format.'; - break; - case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - message = 'Framebuffer is not complete. Incomplete dimensions: not all attached images have the same width and height.'; - break; - case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - message = 'Framebuffer is not complete. Missing attachment: no images are attached to the framebuffer.'; - break; - case gl.FRAMEBUFFER_UNSUPPORTED: - message = 'Framebuffer is not complete. Unsupported: the combination of internal formats of the attached images violates an implementation-dependent set of restrictions.'; - break; - } - - throw new DeveloperError(message); - } + Camera.prototype.update = function(mode) { + if (!defined(mode)) { + throw new DeveloperError('mode is required.'); } - } - - function applyRenderState(context, renderState, passState, clear) { - var previousRenderState = context._currentRenderState; - var previousPassState = context._currentPassState; - context._currentRenderState = renderState; - context._currentPassState = passState; - RenderState.partialApply(context._gl, previousRenderState, renderState, previousPassState, passState, clear); - } - - var scratchBackBufferArray; - // this check must use typeof, not defined, because defined doesn't work with undeclared variables. - if (typeof WebGLRenderingContext !== 'undefined') { - scratchBackBufferArray = [WebGLConstants.BACK]; - } - - function bindFramebuffer(context, framebuffer) { - if (framebuffer !== context._currentFramebuffer) { - context._currentFramebuffer = framebuffer; - var buffers = scratchBackBufferArray; - - if (defined(framebuffer)) { - framebuffer._bind(); - validateFramebuffer(context); - - // TODO: Need a way for a command to give what draw buffers are active. - buffers = framebuffer._getActiveColorAttachments(); - } else { - var gl = context._gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - } - - if (context.drawBuffers) { - context.glDrawBuffers(buffers); - } + if (mode === SceneMode.SCENE2D && !(this.frustum instanceof OrthographicOffCenterFrustum)) { + throw new DeveloperError('An OrthographicOffCenterFrustum is required in 2D.'); + } + if ((mode === SceneMode.SCENE3D || mode === SceneMode.COLUMBUS_VIEW) && + (!(this.frustum instanceof PerspectiveFrustum) && !(this.frustum instanceof OrthographicFrustum))) { + throw new DeveloperError('A PerspectiveFrustum or OrthographicFrustum is required in 3D and Columbus view'); + } + + var updateFrustum = false; + if (mode !== this._mode) { + this._mode = mode; + this._modeChanged = mode !== SceneMode.MORPHING; + updateFrustum = this._mode === SceneMode.SCENE2D; } - } - - var defaultClearCommand = new ClearCommand(); - - Context.prototype.clear = function(clearCommand, passState) { - clearCommand = defaultValue(clearCommand, defaultClearCommand); - passState = defaultValue(passState, this._defaultPassState); - - var gl = this._gl; - var bitmask = 0; - var c = clearCommand.color; - var d = clearCommand.depth; - var s = clearCommand.stencil; + if (updateFrustum) { + var frustum = this._max2Dfrustum = this.frustum.clone(); - if (defined(c)) { - if (!Color.equals(this._clearColor, c)) { - Color.clone(c, this._clearColor); - gl.clearColor(c.red, c.green, c.blue, c.alpha); + if (!(frustum instanceof OrthographicOffCenterFrustum)) { + throw new DeveloperError('The camera frustum is expected to be orthographic for 2D camera control.'); } - bitmask |= gl.COLOR_BUFFER_BIT; + + var maxZoomOut = 2.0; + var ratio = frustum.top / frustum.right; + frustum.right = this._maxCoord.x * maxZoomOut; + frustum.left = -frustum.right; + frustum.top = ratio * frustum.right; + frustum.bottom = -frustum.top; } - if (defined(d)) { - if (d !== this._clearDepth) { - this._clearDepth = d; - gl.clearDepth(d); - } - bitmask |= gl.DEPTH_BUFFER_BIT; + if (this._mode === SceneMode.SCENE2D) { + clampMove2D(this, this.position); } - if (defined(s)) { - if (s !== this._clearStencil) { - this._clearStencil = s; - gl.clearStencil(s); - } - bitmask |= gl.STENCIL_BUFFER_BIT; + var globe = this._scene.globe; + var globeFinishedUpdating = !defined(globe) || (globe._surface.tileProvider.ready && globe._surface._tileLoadQueueHigh.length === 0 && globe._surface._tileLoadQueueMedium.length === 0 && globe._surface._tileLoadQueueLow.length === 0 && globe._surface._debug.tilesWaitingForChildren === 0); + if (this._suspendTerrainAdjustment) { + this._suspendTerrainAdjustment = !globeFinishedUpdating; } - - var rs = defaultValue(clearCommand.renderState, this._defaultRenderState); - applyRenderState(this, rs, passState, true); - - // The command's framebuffer takes presidence over the pass' framebuffer, e.g., for off-screen rendering. - var framebuffer = defaultValue(clearCommand.framebuffer, passState.framebuffer); - bindFramebuffer(this, framebuffer); - - gl.clear(bitmask); + this._adjustHeightForTerrain(); }; - function beginDraw(context, framebuffer, drawCommand, passState) { - var rs = defaultValue(drawCommand._renderState, context._defaultRenderState); + var setTransformPosition = new Cartesian3(); + var setTransformUp = new Cartesian3(); + var setTransformDirection = new Cartesian3(); - if (defined(framebuffer) && rs.depthTest) { - if (rs.depthTest.enabled && !framebuffer.hasDepthAttachment) { - throw new DeveloperError('The depth test can not be enabled (drawCommand.renderState.depthTest.enabled) because the framebuffer (drawCommand.framebuffer) does not have a depth or depth-stencil renderbuffer.'); - } - } - - bindFramebuffer(context, framebuffer); + Camera.prototype._setTransform = function(transform) { + var position = Cartesian3.clone(this.positionWC, setTransformPosition); + var up = Cartesian3.clone(this.upWC, setTransformUp); + var direction = Cartesian3.clone(this.directionWC, setTransformDirection); - applyRenderState(context, rs, passState, false); + Matrix4.clone(transform, this._transform); + this._transformChanged = true; + updateMembers(this); + var inverse = this._actualInvTransform; - var sp = drawCommand._shaderProgram; - sp._bind(); - context._maxFrameTextureUnitIndex = Math.max(context._maxFrameTextureUnitIndex, sp.maximumTextureUnitIndex); - } + Matrix4.multiplyByPoint(inverse, position, this.position); + Matrix4.multiplyByPointAsVector(inverse, direction, this.direction); + Matrix4.multiplyByPointAsVector(inverse, up, this.up); + Cartesian3.cross(this.direction, this.up, this.right); - function continueDraw(context, drawCommand) { - var primitiveType = drawCommand._primitiveType; - var va = drawCommand._vertexArray; - var offset = drawCommand._offset; - var count = drawCommand._count; - var instanceCount = drawCommand.instanceCount; + updateMembers(this); + }; - if (!PrimitiveType.validate(primitiveType)) { - throw new DeveloperError('drawCommand.primitiveType is required and must be valid.'); - } + var scratchAdjustOrtghographicFrustumMousePosition = new Cartesian2(); + var pickGlobeScratchRay = new Ray(); + var scratchRayIntersection = new Cartesian3(); + var scratchDepthIntersection = new Cartesian3(); - Check.defined('drawCommand.vertexArray', va); - Check.typeOf.number.greaterThanOrEquals('drawCommand.offset', offset, 0); - if (defined(count)) { - Check.typeOf.number.greaterThanOrEquals('drawCommand.count', count, 0); - } - Check.typeOf.number.greaterThanOrEquals('drawCommand.instanceCount', instanceCount, 0); - if (instanceCount > 0 && !context.instancedArrays) { - throw new DeveloperError('Instanced arrays extension is not supported'); + Camera.prototype._adjustOrthographicFrustum = function(zooming) { + if (!(this.frustum instanceof OrthographicFrustum)) { + return; } - - context._us.model = defaultValue(drawCommand._modelMatrix, Matrix4.IDENTITY); - drawCommand._shaderProgram._setUniforms(drawCommand._uniformMap, context._us, context.validateShaderProgram); - va._bind(); - var indexBuffer = va.indexBuffer; - - if (defined(indexBuffer)) { - offset = offset * indexBuffer.bytesPerIndex; // offset in vertices to offset in bytes - count = defaultValue(count, indexBuffer.numberOfIndices); - if (instanceCount === 0) { - context._gl.drawElements(primitiveType, count, indexBuffer.indexDatatype, offset); - } else { - context.glDrawElementsInstanced(primitiveType, count, indexBuffer.indexDatatype, offset, instanceCount); - } - } else { - count = defaultValue(count, va.numberOfVertices); - if (instanceCount === 0) { - context._gl.drawArrays(primitiveType, offset, count); - } else { - context.glDrawArraysInstanced(primitiveType, offset, count, instanceCount); - } + if (!zooming && this._positionCartographic.height < 150000.0) { + return; } - va._unBind(); - } + if (!Matrix4.equals(Matrix4.IDENTITY, this.transform)) { + this.frustum.width = Cartesian3.magnitude(this.position); + return; + } - Context.prototype.draw = function(drawCommand, passState) { - Check.defined('drawCommand', drawCommand); - Check.defined('drawCommand.shaderProgram', drawCommand._shaderProgram); - - passState = defaultValue(passState, this._defaultPassState); - // The command's framebuffer takes presidence over the pass' framebuffer, e.g., for off-screen rendering. - var framebuffer = defaultValue(drawCommand._framebuffer, passState.framebuffer); + var scene = this._scene; + var globe = scene._globe; + var rayIntersection; + var depthIntersection; - beginDraw(this, framebuffer, drawCommand, passState); - continueDraw(this, drawCommand); - }; + if (defined(globe)) { + var mousePosition = scratchAdjustOrtghographicFrustumMousePosition; + mousePosition.x = scene.drawingBufferWidth / 2.0; + mousePosition.y = scene.drawingBufferHeight / 2.0; - Context.prototype.endFrame = function() { - var gl = this._gl; - gl.useProgram(null); + var ray = this.getPickRay(mousePosition, pickGlobeScratchRay); + rayIntersection = globe.pick(ray, scene, scratchRayIntersection); - this._currentFramebuffer = undefined; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); + if (scene.pickPositionSupported) { + depthIntersection = scene.pickPositionWorldCoordinates(mousePosition, scratchDepthIntersection); + } - var buffers = scratchBackBufferArray; - if (this.drawBuffers) { - this.glDrawBuffers(buffers); + if (defined(rayIntersection) && defined(depthIntersection)) { + var depthDistance = defined(depthIntersection) ? Cartesian3.distance(depthIntersection, this.positionWC) : Number.POSITIVE_INFINITY; + var rayDistance = defined(rayIntersection) ? Cartesian3.distance(rayIntersection, this.positionWC) : Number.POSITIVE_INFINITY; + this.frustum.width = Math.min(depthDistance, rayDistance); + } else if (defined(depthIntersection)) { + this.frustum.width = Cartesian3.distance(depthIntersection, this.positionWC); + } else if (defined(rayIntersection)) { + this.frustum.width = Cartesian3.distance(rayIntersection, this.positionWC); + } } - var length = this._maxFrameTextureUnitIndex; - this._maxFrameTextureUnitIndex = 0; - - for (var i = 0; i < length; ++i) { - gl.activeTexture(gl.TEXTURE0 + i); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.bindTexture(gl.TEXTURE_CUBE_MAP, null); + if (!defined(globe) || (!defined(rayIntersection) && !defined(depthIntersection))) { + var distance = Math.max(this.positionCartographic.height, 0.0); + this.frustum.width = distance; } }; - Context.prototype.readPixels = function(readState) { - var gl = this._gl; - - readState = readState || {}; - var x = Math.max(readState.x || 0, 0); - var y = Math.max(readState.y || 0, 0); - var width = readState.width || gl.drawingBufferWidth; - var height = readState.height || gl.drawingBufferHeight; - var framebuffer = readState.framebuffer; - - Check.typeOf.number.greaterThan('readState.width', width, 0); - Check.typeOf.number.greaterThan('readState.height', height, 0); - - var pixels = new Uint8Array(4 * width * height); - - bindFramebuffer(this, framebuffer); + var scratchSetViewCartesian = new Cartesian3(); + var scratchSetViewTransform1 = new Matrix4(); + var scratchSetViewTransform2 = new Matrix4(); + var scratchSetViewQuaternion = new Quaternion(); + var scratchSetViewMatrix3 = new Matrix3(); + var scratchSetViewCartographic = new Cartographic(); - gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + function setView3D(camera, position, hpr) { + var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); + var localTransform = Transforms.eastNorthUpToFixedFrame(position, camera._projection.ellipsoid, scratchSetViewTransform2); + camera._setTransform(localTransform); - return pixels; - }; + Cartesian3.clone(Cartesian3.ZERO, camera.position); + hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - var viewportQuadAttributeLocations = { - position : 0, - textureCoordinates : 1 - }; + var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); + var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); - Context.prototype.getViewportQuadVertexArray = function() { - // Per-context cache for viewport quads - var vertexArray = this.cache.viewportQuad_vertexArray; + Matrix3.getColumn(rotMat, 0, camera.direction); + Matrix3.getColumn(rotMat, 2, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); - if (!defined(vertexArray)) { - var geometry = new Geometry({ - attributes : { - position : new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : [ - -1.0, -1.0, - 1.0, -1.0, - 1.0, 1.0, - -1.0, 1.0 - ] - }), + camera._setTransform(currentTransform); - textureCoordinates : new GeometryAttribute({ - componentDatatype : ComponentDatatype.FLOAT, - componentsPerAttribute : 2, - values : [ - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0 - ] - }) - }, - // Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN - indices : new Uint16Array([0, 1, 2, 0, 2, 3]), - primitiveType : PrimitiveType.TRIANGLES - }); + camera._adjustOrthographicFrustum(true); + } - vertexArray = VertexArray.fromGeometry({ - context : this, - geometry : geometry, - attributeLocations : viewportQuadAttributeLocations, - bufferUsage : BufferUsage.STATIC_DRAW, - interleave : true - }); + function setViewCV(camera, position,hpr, convert) { + var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); + camera._setTransform(Matrix4.IDENTITY); - this.cache.viewportQuad_vertexArray = vertexArray; + if (!Cartesian3.equals(position, camera.positionWC)) { + if (convert) { + var projection = camera._projection; + var cartographic = projection.ellipsoid.cartesianToCartographic(position, scratchSetViewCartographic); + position = projection.project(cartographic, scratchSetViewCartesian); + } + Cartesian3.clone(position, camera.position); } + hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - return vertexArray; - }; - - Context.prototype.createViewportQuadCommand = function(fragmentShaderSource, overrides) { - overrides = defaultValue(overrides, defaultValue.EMPTY_OBJECT); - - return new DrawCommand({ - vertexArray : this.getViewportQuadVertexArray(), - primitiveType : PrimitiveType.TRIANGLES, - renderState : overrides.renderState, - shaderProgram : ShaderProgram.fromCache({ - context : this, - vertexShaderSource : ViewportQuadVS, - fragmentShaderSource : fragmentShaderSource, - attributeLocations : viewportQuadAttributeLocations - }), - uniformMap : overrides.uniformMap, - owner : overrides.owner, - framebuffer : overrides.framebuffer, - pass : overrides.pass - }); - }; + var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); + var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); - Context.prototype.createPickFramebuffer = function() { - return new PickFramebuffer(this); - }; + Matrix3.getColumn(rotMat, 0, camera.direction); + Matrix3.getColumn(rotMat, 2, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); - /** - * Gets the object associated with a pick color. - * - * @param {Color} pickColor The pick color. - * @returns {Object} The object associated with the pick color, or undefined if no object is associated with that color. - * - * @example - * var object = context.getObjectByPickColor(pickColor); - * - * @see Context#createPickId - */ - Context.prototype.getObjectByPickColor = function(pickColor) { - Check.defined('pickColor', pickColor); - - return this._pickObjects[pickColor.toRgba()]; - }; + camera._setTransform(currentTransform); - function PickId(pickObjects, key, color) { - this._pickObjects = pickObjects; - this.key = key; - this.color = color; + camera._adjustOrthographicFrustum(true); } - defineProperties(PickId.prototype, { - object : { - get : function() { - return this._pickObjects[this.key]; - }, - set : function(value) { - this._pickObjects[this.key] = value; - } - } - }); - - PickId.prototype.destroy = function() { - delete this._pickObjects[this.key]; - return undefined; - }; + function setView2D(camera, position, hpr, convert) { + var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); + camera._setTransform(Matrix4.IDENTITY); - /** - * Creates a unique ID associated with the input object for use with color-buffer picking. - * The ID has an RGBA color value unique to this context. You must call destroy() - * on the pick ID when destroying the input object. - * - * @param {Object} object The object to associate with the pick ID. - * @returns {Object} A PickId object with a <code>color</code> property. - * - * @exception {RuntimeError} Out of unique Pick IDs. - * - * - * @example - * this._pickId = context.createPickId({ - * primitive : this, - * id : this.id - * }); - * - * @see Context#getObjectByPickColor - */ - Context.prototype.createPickId = function(object) { - Check.defined('object', object); - - // the increment and assignment have to be separate statements to - // actually detect overflow in the Uint32 value - ++this._nextPickColor[0]; - var key = this._nextPickColor[0]; - if (key === 0) { - // In case of overflow - throw new RuntimeError('Out of unique Pick IDs.'); - } + if (!Cartesian3.equals(position, camera.positionWC)) { + if (convert) { + var projection = camera._projection; + var cartographic = projection.ellipsoid.cartesianToCartographic(position, scratchSetViewCartographic); + position = projection.project(cartographic, scratchSetViewCartesian); + } - this._pickObjects[key] = object; - return new PickId(this._pickObjects, key, Color.fromRgba(key)); - }; + Cartesian2.clone(position, camera.position); - Context.prototype.isDestroyed = function() { - return false; - }; + var newLeft = -position.z * 0.5; + var newRight = -newLeft; - Context.prototype.destroy = function() { - // Destroy all objects in the cache that have a destroy method. - var cache = this.cache; - for (var property in cache) { - if (cache.hasOwnProperty(property)) { - var propertyValue = cache[property]; - if (defined(propertyValue.destroy)) { - propertyValue.destroy(); - } + var frustum = camera.frustum; + if (newRight > newLeft) { + var ratio = frustum.top / frustum.right; + frustum.right = newRight; + frustum.left = newLeft; + frustum.top = frustum.right * ratio; + frustum.bottom = -frustum.top; } } - this._shaderCache = this._shaderCache.destroy(); - this._defaultTexture = this._defaultTexture && this._defaultTexture.destroy(); - this._defaultCubeMap = this._defaultCubeMap && this._defaultCubeMap.destroy(); - - return destroyObject(this); - }; + if (camera._scene.mapMode2D === MapMode2D.ROTATE) { + hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; + hpr.pitch = -CesiumMath.PI_OVER_TWO; + hpr.roll = 0.0; + var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); + var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); - return Context; -}); + Matrix3.getColumn(rotMat, 2, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + } -define('Renderer/loadCubeMap',[ - '../Core/Check', - '../Core/defined', - '../Core/DeveloperError', - '../Core/loadImage', - '../ThirdParty/when', - './CubeMap' - ], function( - Check, - defined, - DeveloperError, - loadImage, - when, - CubeMap) { - 'use strict'; + camera._setTransform(currentTransform); + } - /** - * Asynchronously loads six images and creates a cube map. Returns a promise that - * will resolve to a {@link CubeMap} once loaded, or reject if any image fails to load. - * - * @exports loadCubeMap - * - * @param {Context} context The context to use to create the cube map. - * @param {Object} urls The source URL of each image. See the example below. - * @param {Boolean} [allowCrossOrigin=true] Whether to request the image using Cross-Origin - * Resource Sharing (CORS). CORS is only actually used if the image URL is actually cross-origin. - * Data URIs are never requested using CORS. - * @returns {Promise.<CubeMap>} a promise that will resolve to the requested {@link CubeMap} when loaded. - * - * @exception {DeveloperError} context is required. - * @exception {DeveloperError} urls is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. - * - * - * @example - * Cesium.loadCubeMap(context, { - * positiveX : 'skybox_px.png', - * negativeX : 'skybox_nx.png', - * positiveY : 'skybox_py.png', - * negativeY : 'skybox_ny.png', - * positiveZ : 'skybox_pz.png', - * negativeZ : 'skybox_nz.png' - * }).then(function(cubeMap) { - * // use the cubemap - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - * - * @private - */ - function loadCubeMap(context, urls, allowCrossOrigin) { - Check.defined('context', context); - if ((!defined(urls)) || - (!defined(urls.positiveX)) || - (!defined(urls.negativeX)) || - (!defined(urls.positiveY)) || - (!defined(urls.negativeY)) || - (!defined(urls.positiveZ)) || - (!defined(urls.negativeZ))) { - throw new DeveloperError('urls is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.'); - } - - // PERFORMANCE_IDEA: Given the size of some cube maps, we should consider tiling them, which - // would prevent hiccups when uploading, for example, six 4096x4096 textures to the GPU. - // - // Also, it is perhaps acceptable to use the context here in the callbacks, but - // ideally, we would do it in the primitive's update function. + var scratchToHPRDirection = new Cartesian3(); + var scratchToHPRUp = new Cartesian3(); + var scratchToHPRRight = new Cartesian3(); - var facePromises = [ - loadImage(urls.positiveX, allowCrossOrigin), - loadImage(urls.negativeX, allowCrossOrigin), - loadImage(urls.positiveY, allowCrossOrigin), - loadImage(urls.negativeY, allowCrossOrigin), - loadImage(urls.positiveZ, allowCrossOrigin), - loadImage(urls.negativeZ, allowCrossOrigin) - ]; + function directionUpToHeadingPitchRoll(camera, position, orientation, result) { + var direction = Cartesian3.clone(orientation.direction, scratchToHPRDirection); + var up = Cartesian3.clone(orientation.up, scratchToHPRUp); - return when.all(facePromises, function(images) { - return new CubeMap({ - context : context, - source : { - positiveX : images[0], - negativeX : images[1], - positiveY : images[2], - negativeY : images[3], - positiveZ : images[4], - negativeZ : images[5] - } - }); - }); - } + if (camera._scene.mode === SceneMode.SCENE3D) { + var ellipsoid = camera._projection.ellipsoid; + var transform = Transforms.eastNorthUpToFixedFrame(position, ellipsoid, scratchHPRMatrix1); + var invTransform = Matrix4.inverseTransformation(transform, scratchHPRMatrix2); - return loadCubeMap; -}); + Matrix4.multiplyByPointAsVector(invTransform, direction, direction); + Matrix4.multiplyByPointAsVector(invTransform, up, up); + } -define('Scene/DiscardMissingTileImagePolicy',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/DeveloperError', - '../Core/getImagePixels', - '../Core/loadImageViaBlob', - '../ThirdParty/when' - ], function( - defaultValue, - defined, - DeveloperError, - getImagePixels, - loadImageViaBlob, - when) { - 'use strict'; + var right = Cartesian3.cross(direction, up, scratchToHPRRight); + + result.heading = getHeading(direction, up); + result.pitch = getPitch(direction); + result.roll = getRoll(direction, up, right); + + return result; + } + + var scratchSetViewOptions = { + destination : undefined, + orientation : { + direction : undefined, + up : undefined, + heading : undefined, + pitch : undefined, + roll : undefined + }, + convert : undefined, + endTransform : undefined + }; + var scratchHpr = new HeadingPitchRoll(); /** - * A policy for discarding tile images that match a known image containing a - * "missing" image. - * - * @alias DiscardMissingTileImagePolicy - * @constructor + * Sets the camera position, orientation and transform. * * @param {Object} options Object with the following properties: - * @param {String} options.missingImageUrl The URL of the known missing image. - * @param {Cartesian2[]} options.pixelsToCheck An array of {@link Cartesian2} pixel positions to - * compare against the missing image. - * @param {Boolean} [options.disableCheckIfAllPixelsAreTransparent=false] If true, the discard check will be disabled - * if all of the pixelsToCheck in the missingImageUrl have an alpha value of 0. If false, the - * discard check will proceed no matter the values of the pixelsToCheck. + * @param {Cartesian3|Rectangle} [options.destination] The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. + * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pitch and roll properties. By default, the direction will point + * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive + * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. + * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame of the camera. + * + * @example + * // 1. Set position with a top-down view + * viewer.camera.setView({ + * destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0) + * }); + * + * // 2 Set view with heading, pitch and roll + * viewer.camera.setView({ + * destination : cartesianPosition, + * orientation: { + * heading : Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north) + * pitch : Cesium.Math.toRadians(-90), // default value (looking down) + * roll : 0.0 // default value + * } + * }); + * + * // 3. Change heading, pitch and roll with the camera position remaining the same. + * viewer.camera.setView({ + * orientation: { + * heading : Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north) + * pitch : Cesium.Math.toRadians(-90), // default value (looking down) + * roll : 0.0 // default value + * } + * }); + * + * + * // 4. View rectangle with a top-down view + * viewer.camera.setView({ + * destination : Cesium.Rectangle.fromDegrees(west, south, east, north) + * }); + * + * // 5. Set position with an orientation using unit vectors. + * viewer.camera.setView({ + * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), + * orientation : { + * direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734), + * up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339) + * } + * }); */ - function DiscardMissingTileImagePolicy(options) { + Camera.prototype.setView = function(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var orientation = defaultValue(options.orientation, defaultValue.EMPTY_OBJECT); - if (!defined(options.missingImageUrl)) { - throw new DeveloperError('options.missingImageUrl is required.'); + var mode = this._mode; + if (mode === SceneMode.MORPHING) { + return; } - if (!defined(options.pixelsToCheck)) { - throw new DeveloperError('options.pixelsToCheck is required.'); + if (defined(options.endTransform)) { + this._setTransform(options.endTransform); } - - this._pixelsToCheck = options.pixelsToCheck; - this._missingImagePixels = undefined; - this._missingImageByteLength = undefined; - this._isReady = false; - - var that = this; - function success(image) { - if (defined(image.blob)) { - that._missingImageByteLength = image.blob.size; - } + var convert = defaultValue(options.convert, true); + var destination = defaultValue(options.destination, Cartesian3.clone(this.positionWC, scratchSetViewCartesian)); + if (defined(destination) && defined(destination.west)) { + destination = this.getRectangleCameraCoordinates(destination, scratchSetViewCartesian); + convert = false; + } - var pixels = getImagePixels(image); + if (defined(orientation.direction)) { + orientation = directionUpToHeadingPitchRoll(this, destination, orientation, scratchSetViewOptions.orientation); + } - if (options.disableCheckIfAllPixelsAreTransparent) { - var allAreTransparent = true; - var width = image.width; + scratchHpr.heading = defaultValue(orientation.heading, 0.0); + scratchHpr.pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO); + scratchHpr.roll = defaultValue(orientation.roll, 0.0); - var pixelsToCheck = options.pixelsToCheck; - for (var i = 0, len = pixelsToCheck.length; allAreTransparent && i < len; ++i) { - var pos = pixelsToCheck[i]; - var index = pos.x * 4 + pos.y * width; - var alpha = pixels[index + 3]; + this._suspendTerrainAdjustment = true; - if (alpha > 0) { - allAreTransparent = false; - } - } + if (mode === SceneMode.SCENE3D) { + setView3D(this, destination, scratchHpr); + } else if (mode === SceneMode.SCENE2D) { + setView2D(this, destination, scratchHpr, convert); + } else { + setViewCV(this, destination, scratchHpr, convert); + } + }; - if (allAreTransparent) { - pixels = undefined; - } - } + var pitchScratch = new Cartesian3(); + /** + * Fly the camera to the home view. Use {@link Camera#.DEFAULT_VIEW_RECTANGLE} to set + * the default view for the 3D scene. The home view for 2D and columbus view shows the + * entire map. + * + * @param {Number} [duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. See {@link Camera#flyTo} + */ + Camera.prototype.flyHome = function(duration) { + var mode = this._mode; - that._missingImagePixels = pixels; - that._isReady = true; + if (mode === SceneMode.MORPHING) { + this._scene.completeMorph(); } - function failure() { - // Failed to download "missing" image, so assume that any truly missing tiles - // will also fail to download and disable the discard check. - that._missingImagePixels = undefined; - that._isReady = true; - } + if (mode === SceneMode.SCENE2D) { + this.flyTo({ + destination : Camera.DEFAULT_VIEW_RECTANGLE, + duration : duration, + endTransform : Matrix4.IDENTITY + }); + } else if (mode === SceneMode.SCENE3D) { + var destination = this.getRectangleCameraCoordinates(Camera.DEFAULT_VIEW_RECTANGLE); - when(loadImageViaBlob(options.missingImageUrl), success, failure); - } + var mag = Cartesian3.magnitude(destination); + mag += mag * Camera.DEFAULT_VIEW_FACTOR; + Cartesian3.normalize(destination, destination); + Cartesian3.multiplyByScalar(destination, mag, destination); + + this.flyTo({ + destination : destination, + duration : duration, + endTransform : Matrix4.IDENTITY + }); + } else if (mode === SceneMode.COLUMBUS_VIEW) { + var maxRadii = this._projection.ellipsoid.maximumRadius; + var position = new Cartesian3(0.0, -1.0, 1.0); + position = Cartesian3.multiplyByScalar(Cartesian3.normalize(position, position), 5.0 * maxRadii, position); + this.flyTo({ + destination : position, + duration : duration, + orientation : { + heading : 0.0, + pitch : -Math.acos(Cartesian3.normalize(position, pitchScratch).z), + roll : 0.0 + }, + endTransform : Matrix4.IDENTITY, + convert : false + }); + } + }; /** - * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * Transform a vector or point from world coordinates to the camera's reference frame. + * + * @param {Cartesian4} cartesian The vector or point to transform. + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The transformed vector or point. */ - DiscardMissingTileImagePolicy.prototype.isReady = function() { - return this._isReady; + Camera.prototype.worldToCameraCoordinates = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + + if (!defined(result)) { + result = new Cartesian4(); + } + updateMembers(this); + return Matrix4.multiplyByVector(this._actualInvTransform, cartesian, result); }; /** - * Given a tile image, decide whether to discard that image. - * - * @param {Image} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * Transform a point from world coordinates to the camera's reference frame. * - * @exception {DeveloperError} <code>shouldDiscardImage</code> must not be called before the discard policy is ready. + * @param {Cartesian3} cartesian The point to transform. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The transformed point. */ - DiscardMissingTileImagePolicy.prototype.shouldDiscardImage = function(image) { - if (!this._isReady) { - throw new DeveloperError('shouldDiscardImage must not be called before the discard policy is ready.'); + Camera.prototype.worldToCameraCoordinatesPoint = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); } - var pixelsToCheck = this._pixelsToCheck; - var missingImagePixels = this._missingImagePixels; - - // If missingImagePixels is undefined, it indicates that the discard check has been disabled. - if (!defined(missingImagePixels)) { - return false; + if (!defined(result)) { + result = new Cartesian3(); } + updateMembers(this); + return Matrix4.multiplyByPoint(this._actualInvTransform, cartesian, result); + }; - if (defined(image.blob) && image.blob.size !== this._missingImageByteLength) { - return false; + /** + * Transform a vector from world coordinates to the camera's reference frame. + * + * @param {Cartesian3} cartesian The vector to transform. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The transformed vector. + */ + Camera.prototype.worldToCameraCoordinatesVector = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); } - - var pixels = getImagePixels(image); - var width = image.width; - - for (var i = 0, len = pixelsToCheck.length; i < len; ++i) { - var pos = pixelsToCheck[i]; - var index = pos.x * 4 + pos.y * width; - for (var offset = 0; offset < 4; ++offset) { - var pixel = index + offset; - if (pixels[pixel] !== missingImagePixels[pixel]) { - return false; - } - } + + if (!defined(result)) { + result = new Cartesian3(); } - return true; + updateMembers(this); + return Matrix4.multiplyByPointAsVector(this._actualInvTransform, cartesian, result); }; - return DiscardMissingTileImagePolicy; -}); + /** + * Transform a vector or point from the camera's reference frame to world coordinates. + * + * @param {Cartesian4} cartesian The vector or point to transform. + * @param {Cartesian4} [result] The object onto which to store the result. + * @returns {Cartesian4} The transformed vector or point. + */ + Camera.prototype.cameraToWorldCoordinates = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + + if (!defined(result)) { + result = new Cartesian4(); + } + updateMembers(this); + return Matrix4.multiplyByVector(this._actualTransform, cartesian, result); + }; -define('Scene/ImageryLayerFeatureInfo',[ - '../Core/defined' - ], function( - defined) { - 'use strict'; + /** + * Transform a point from the camera's reference frame to world coordinates. + * + * @param {Cartesian3} cartesian The point to transform. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The transformed point. + */ + Camera.prototype.cameraToWorldCoordinatesPoint = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + + if (!defined(result)) { + result = new Cartesian3(); + } + updateMembers(this); + return Matrix4.multiplyByPoint(this._actualTransform, cartesian, result); + }; /** - * Describes a rasterized feature, such as a point, polygon, polyline, etc., in an imagery layer. + * Transform a vector from the camera's reference frame to world coordinates. * - * @alias ImageryLayerFeatureInfo - * @constructor + * @param {Cartesian3} cartesian The vector to transform. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The transformed vector. */ - function ImageryLayerFeatureInfo() { - /** - * Gets or sets the name of the feature. - * @type {String} - */ - this.name = undefined; + Camera.prototype.cameraToWorldCoordinatesVector = function(cartesian, result) { + if (!defined(cartesian)) { + throw new DeveloperError('cartesian is required.'); + } + + if (!defined(result)) { + result = new Cartesian3(); + } + updateMembers(this); + return Matrix4.multiplyByPointAsVector(this._actualTransform, cartesian, result); + }; - /** - * Gets or sets an HTML description of the feature. The HTML is not trusted and should - * be sanitized before display to the user. - * @type {String} - */ - this.description = undefined; + function clampMove2D(camera, position) { + var rotatable2D = camera._scene.mapMode2D === MapMode2D.ROTATE; + var maxProjectedX = camera._maxCoord.x; + var maxProjectedY = camera._maxCoord.y; - /** - * Gets or sets the position of the feature, or undefined if the position is not known. - * - * @type {Cartographic} - */ - this.position = undefined; + var minX; + var maxX; + if (rotatable2D) { + maxX = maxProjectedX; + minX = -maxX; + } else { + maxX = position.x - maxProjectedX * 2.0; + minX = position.x + maxProjectedX * 2.0; + } - /** - * Gets or sets the raw data describing the feature. The raw data may be in any - * number of formats, such as GeoJSON, KML, etc. - * @type {Object} - */ - this.data = undefined; + if (position.x > maxProjectedX) { + position.x = maxX; + } + if (position.x < -maxProjectedX) { + position.x = minX; + } - /** - * Gets or sets the image layer of the feature. - * @type {Object} - */ - this.imageryLayer = undefined; + if (position.y > maxProjectedY) { + position.y = maxProjectedY; + } + if (position.y < -maxProjectedY) { + position.y = -maxProjectedY; + } } + var moveScratch = new Cartesian3(); /** - * Configures the name of this feature by selecting an appropriate property. The name will be obtained from - * one of the following sources, in this order: 1) the property with the name 'name', 2) the property with the name 'title', - * 3) the first property containing the word 'name', 4) the first property containing the word 'title'. If - * the name cannot be obtained from any of these sources, the existing name will be left unchanged. + * Translates the camera's position by <code>amount</code> along <code>direction</code>. * - * @param {Object} properties An object literal containing the properties of the feature. + * @param {Cartesian3} direction The direction to move. + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * + * @see Camera#moveBackward + * @see Camera#moveForward + * @see Camera#moveLeft + * @see Camera#moveRight + * @see Camera#moveUp + * @see Camera#moveDown */ - ImageryLayerFeatureInfo.prototype.configureNameFromProperties = function(properties) { - var namePropertyPrecedence = 10; - var nameProperty; - - for (var key in properties) { - if (properties.hasOwnProperty(key) && properties[key]) { - var lowerKey = key.toLowerCase(); - - if (namePropertyPrecedence > 1 && lowerKey === 'name') { - namePropertyPrecedence = 1; - nameProperty = key; - } else if (namePropertyPrecedence > 2 && lowerKey === 'title') { - namePropertyPrecedence = 2; - nameProperty = key; - } else if (namePropertyPrecedence > 3 && /name/i.test(key)) { - namePropertyPrecedence = 3; - nameProperty = key; - } else if (namePropertyPrecedence > 4 && /title/i.test(key)) { - namePropertyPrecedence = 4; - nameProperty = key; - } - } + Camera.prototype.move = function(direction, amount) { + if (!defined(direction)) { + throw new DeveloperError('direction is required.'); } + + var cameraPosition = this.position; + Cartesian3.multiplyByScalar(direction, amount, moveScratch); + Cartesian3.add(cameraPosition, moveScratch, cameraPosition); - if (defined(nameProperty)) { - this.name = properties[nameProperty]; + if (this._mode === SceneMode.SCENE2D) { + clampMove2D(this, cameraPosition); } + this._adjustOrthographicFrustum(true); }; /** - * Configures the description of this feature by creating an HTML table of properties and their values. + * Translates the camera's position by <code>amount</code> along the camera's view vector. + * When in 2D mode, this will zoom in the camera instead of translating the camera's position. * - * @param {Object} properties An object literal containing the properties of the feature. + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * + * @see Camera#moveBackward */ - ImageryLayerFeatureInfo.prototype.configureDescriptionFromProperties = function(properties) { - function describe(properties) { - var html = '<table class="cesium-infoBox-defaultTable">'; - for (var key in properties) { - if (properties.hasOwnProperty(key)) { - var value = properties[key]; - if (defined(value)) { - if (typeof value === 'object') { - html += '<tr><td>' + key + '</td><td>' + describe(value) + '</td></tr>'; - } else { - html += '<tr><td>' + key + '</td><td>' + value + '</td></tr>'; - } - } - } - } - html += '</table>'; + Camera.prototype.moveForward = function(amount) { + amount = defaultValue(amount, this.defaultMoveAmount); - return html; + if (this._mode === SceneMode.SCENE2D) { + // 2D mode + zoom2D(this, amount); + } else { + // 3D or Columbus view mode + this.move(this.direction, amount); } - - this.description = describe(properties); }; - return ImageryLayerFeatureInfo; -}); - -define('Scene/ImageryProvider',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/loadCRN', - '../Core/loadImage', - '../Core/loadImageViaBlob', - '../Core/loadKTX' - ], function( - defined, - defineProperties, - DeveloperError, - loadCRN, - loadImage, - loadImageViaBlob, - loadKTX) { - 'use strict'; - /** - * Provides imagery to be displayed on the surface of an ellipsoid. This type describes an - * interface and is not intended to be instantiated directly. - * - * @alias ImageryProvider - * @constructor + * Translates the camera's position by <code>amount</code> along the opposite direction + * of the camera's view vector. + * When in 2D mode, this will zoom out the camera instead of translating the camera's position. * - * @see ArcGisMapServerImageryProvider - * @see BingMapsImageryProvider - * @see createOpenStreetMapImageryProvider - * @see createTileMapServiceImageryProvider - * @see GoogleEarthEnterpriseImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see GridImageryProvider - * @see MapboxImageryProvider - * @see SingleTileImageryProvider - * @see TileCoordinatesImageryProvider - * @see UrlTemplateImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Layers.html|Cesium Sandcastle Imagery Layers Demo} - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Layers%20Manipulation.html|Cesium Sandcastle Imagery Manipulation Demo} + * @see Camera#moveForward */ - function ImageryProvider() { - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; - - DeveloperError.throwInstantiationError(); - } - - defineProperties(ImageryProvider.prototype, { - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof ImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof ImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the rectangle, in radians, of the imagery provided by the instance. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle: { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link ImageryProvider#ready} returns true. Generally, - * a minimum level should only be used when the rectangle of the imagery is small - * enough that the number of tiles at the minimum level is small. An imagery - * provider with more than a few tiles at the minimum level will lead to - * rendering problems. - * @memberof ImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error.. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof ImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof ImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : DeveloperError.throwInstantiationError - }, - - /** - * Gets the proxy used by this provider. - * @memberof ImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : DeveloperError.throwInstantiationError - }, + Camera.prototype.moveBackward = function(amount) { + amount = defaultValue(amount, this.defaultMoveAmount); - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof ImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - hasAlphaChannel : { - get : DeveloperError.throwInstantiationError + if (this._mode === SceneMode.SCENE2D) { + // 2D mode + zoom2D(this, -amount); + } else { + // 3D or Columbus view mode + this.move(this.direction, -amount); } - }); + }; /** - * Gets the credits to be displayed when a given tile is displayed. - * @function + * Translates the camera's position by <code>amount</code> along the camera's up vector. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + * @see Camera#moveDown */ - ImageryProvider.prototype.getTileCredits = DeveloperError.throwInstantiationError; + Camera.prototype.moveUp = function(amount) { + amount = defaultValue(amount, this.defaultMoveAmount); + this.move(this.up, amount); + }; /** - * Requests the image for a given tile. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @function + * Translates the camera's position by <code>amount</code> along the opposite direction + * of the camera's up vector. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + * @see Camera#moveUp */ - ImageryProvider.prototype.requestImage = DeveloperError.throwInstantiationError; + Camera.prototype.moveDown = function(amount) { + amount = defaultValue(amount, this.defaultMoveAmount); + this.move(this.up, -amount); + }; /** - * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. - * This function is optional, so it may not exist on all ImageryProviders. - * - * @function + * Translates the camera's position by <code>amount</code> along the camera's right vector. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * - * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + * @see Camera#moveLeft */ - ImageryProvider.prototype.pickFeatures = DeveloperError.throwInstantiationError; - - var ktxRegex = /\.ktx$/i; - var crnRegex = /\.crn$/i; + Camera.prototype.moveRight = function(amount) { + amount = defaultValue(amount, this.defaultMoveAmount); + this.move(this.right, amount); + }; /** - * Loads an image from a given URL. If the server referenced by the URL already has - * too many requests pending, this function will instead return undefined, indicating - * that the request should be retried later. + * Translates the camera's position by <code>amount</code> along the opposite direction + * of the camera's right vector. * - * @param {ImageryProvider} imageryProvider The imagery provider for the URL. - * @param {String} url The URL of the image. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. + * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * + * @see Camera#moveRight */ - ImageryProvider.loadImage = function(imageryProvider, url, request) { - if (ktxRegex.test(url)) { - return loadKTX(url, undefined, request); - } else if (crnRegex.test(url)) { - return loadCRN(url, undefined, request); - } else if (defined(imageryProvider.tileDiscardPolicy)) { - return loadImageViaBlob(url, request); - } - - return loadImage(url, undefined, request); + Camera.prototype.moveLeft = function(amount) { + amount = defaultValue(amount, this.defaultMoveAmount); + this.move(this.right, -amount); }; - return ImageryProvider; -}); - -define('Scene/ArcGisMapServerImageryProvider',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/Credit', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/GeographicTilingScheme', - '../Core/loadJson', - '../Core/loadJsonp', - '../Core/Math', - '../Core/Rectangle', - '../Core/RuntimeError', - '../Core/TileProviderError', - '../Core/WebMercatorProjection', - '../Core/WebMercatorTilingScheme', - '../ThirdParty/when', - './DiscardMissingTileImagePolicy', - './ImageryLayerFeatureInfo', - './ImageryProvider' - ], function( - Cartesian2, - Cartesian3, - Cartographic, - Credit, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - GeographicTilingScheme, - loadJson, - loadJsonp, - CesiumMath, - Rectangle, - RuntimeError, - TileProviderError, - WebMercatorProjection, - WebMercatorTilingScheme, - when, - DiscardMissingTileImagePolicy, - ImageryLayerFeatureInfo, - ImageryProvider) { - 'use strict'; - /** - * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are - * used, if available. - * - * @alias ArcGisMapServerImageryProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the ArcGIS MapServer service. - * @param {String} [options.token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. - * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile - * is invalid and should be discarded. If this value is not specified, a default - * {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a - * {@link NeverTileDiscardPolicy} is used for non-tiled map servers. In the former case, - * we request tile 0,0 at the maximum tile level and check pixels (0,0), (200,20), (20,200), - * (80,110), and (160, 130). If all of these pixels are transparent, the discard check is - * disabled and no tiles are discarded. If any of them have a non-transparent color, any - * tile that has the same values in these pixel locations is discarded. The end result of - * these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure - * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this - * parameter. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * @param {Boolean} [options.usePreCachedTilesIfAvailable=true] If true, the server's pre-cached - * tiles are used if they are available. If false, any pre-cached tiles are ignored and the - * 'export' service is used. - * @param {String} [options.layers] A comma-separated list of the layers to show, or undefined if all layers should be shown. - * @param {Boolean} [options.enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke - * the Identify service on the MapServer and return the features included in the response. If false, - * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) - * without communicating with the server. Set this property to false if you don't want this provider's features to - * be pickable. Can be overridden by setting the {@link ArcGisMapServerImageryProvider#enablePickFeatures} property on the object. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing - * a tiled layer. - * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles. - * This parameter is ignored when accessing a tiled server. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified and used, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. - * @param {Number} [options.tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server. - * @param {Number} [options.tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server. - * @param {Number} [options.maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing - * a tiled server. - * - * @see BingMapsImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider - * + * Rotates the camera around its up vector by amount, in radians, in the opposite direction + * of its right vector if not in 2D mode. * - * @example - * var esri = new Cesium.ArcGisMapServerImageryProvider({ - * url : 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - * }); + * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * - * @see {@link http://resources.esri.com/help/9.3/arcgisserver/apis/rest/|ArcGIS Server REST API} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see Camera#lookRight */ - function ArcGisMapServerImageryProvider(options) { - options = defaultValue(options, {}); + Camera.prototype.lookLeft = function(amount) { + amount = defaultValue(amount, this.defaultLookAmount); - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); + // only want view of map to change in 3D mode, 2D visual is incorrect when look changes + if (this._mode !== SceneMode.SCENE2D) { + this.look(this.up, -amount); } - - this._url = options.url; - this._token = options.token; - this._tileDiscardPolicy = options.tileDiscardPolicy; - this._proxy = options.proxy; - - this._tileWidth = defaultValue(options.tileWidth, 256); - this._tileHeight = defaultValue(options.tileHeight, 256); - this._maximumLevel = options.maximumLevel; - this._tilingScheme = defaultValue(options.tilingScheme, new GeographicTilingScheme({ ellipsoid : options.ellipsoid })); - this._credit = undefined; - this._useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true); - this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle); - this._layers = options.layers; - - /** - * Gets or sets a value indicating whether feature picking is enabled. If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will - * invoke the "identify" operation on the ArcGIS server and return the features included in the response. If false, - * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) - * without communicating with the server. - * @type {Boolean} - * @default true - */ - this.enablePickFeatures = defaultValue(options.enablePickFeatures, true); - - this._errorEvent = new Event(); - - this._ready = false; - this._readyPromise = when.defer(); - - // Grab the details of this MapServer. - var that = this; - var metadataError; - - function metadataSuccess(data) { - var tileInfo = data.tileInfo; - if (!defined(tileInfo)) { - that._useTiles = false; - } else { - that._tileWidth = tileInfo.rows; - that._tileHeight = tileInfo.cols; - - if (tileInfo.spatialReference.wkid === 102100 || - tileInfo.spatialReference.wkid === 102113) { - that._tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); - } else if (data.tileInfo.spatialReference.wkid === 4326) { - that._tilingScheme = new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); - } else { - var message = 'Tile spatial reference WKID ' + data.tileInfo.spatialReference.wkid + ' is not supported.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - return; - } - that._maximumLevel = data.tileInfo.lods.length - 1; - - if (defined(data.fullExtent)) { - if (defined(data.fullExtent.spatialReference) && defined(data.fullExtent.spatialReference.wkid)) { - if (data.fullExtent.spatialReference.wkid === 102100 || - data.fullExtent.spatialReference.wkid === 102113) { - - var projection = new WebMercatorProjection(); - var extent = data.fullExtent; - var sw = projection.unproject(new Cartesian3(Math.max(extent.xmin, -that._tilingScheme.ellipsoid.maximumRadius * Math.PI), Math.max(extent.ymin, -that._tilingScheme.ellipsoid.maximumRadius * Math.PI), 0.0)); - var ne = projection.unproject(new Cartesian3(Math.min(extent.xmax, that._tilingScheme.ellipsoid.maximumRadius * Math.PI), Math.min(extent.ymax, that._tilingScheme.ellipsoid.maximumRadius * Math.PI), 0.0)); - that._rectangle = new Rectangle(sw.longitude, sw.latitude, ne.longitude, ne.latitude); - } else if (data.fullExtent.spatialReference.wkid === 4326) { - that._rectangle = Rectangle.fromDegrees(data.fullExtent.xmin, data.fullExtent.ymin, data.fullExtent.xmax, data.fullExtent.ymax); - } else { - var extentMessage = 'fullExtent.spatialReference WKID ' + data.fullExtent.spatialReference.wkid + ' is not supported.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, extentMessage, undefined, undefined, undefined, requestMetadata); - return; - } - } - } else { - that._rectangle = that._tilingScheme.rectangle; - } - - // Install the default tile discard policy if none has been supplied. - if (!defined(that._tileDiscardPolicy)) { - that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ - missingImageUrl : buildImageUrl(that, 0, 0, that._maximumLevel), - pixelsToCheck : [new Cartesian2(0, 0), new Cartesian2(200, 20), new Cartesian2(20, 200), new Cartesian2(80, 110), new Cartesian2(160, 130)], - disableCheckIfAllPixelsAreTransparent : true - }); - } - - that._useTiles = true; - } + }; - if (defined(data.copyrightText) && data.copyrightText.length > 0) { - that._credit = new Credit({text: data.copyrightText}); - } + /** + * Rotates the camera around its up vector by amount, in radians, in the direction + * of its right vector if not in 2D mode. + * + * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * + * @see Camera#lookLeft + */ + Camera.prototype.lookRight = function(amount) { + amount = defaultValue(amount, this.defaultLookAmount); - that._ready = true; - that._readyPromise.resolve(true); - TileProviderError.handleSuccess(metadataError); + // only want view of map to change in 3D mode, 2D visual is incorrect when look changes + if (this._mode !== SceneMode.SCENE2D) { + this.look(this.up, amount); } + }; - function metadataFailure(e) { - var message = 'An error occurred while accessing ' + that._url + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - that._readyPromise.reject(new RuntimeError(message)); - } + /** + * Rotates the camera around its right vector by amount, in radians, in the direction + * of its up vector if not in 2D mode. + * + * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * + * @see Camera#lookDown + */ + Camera.prototype.lookUp = function(amount) { + amount = defaultValue(amount, this.defaultLookAmount); - function requestMetadata() { - var parameters = { - f: 'json' - }; + // only want view of map to change in 3D mode, 2D visual is incorrect when look changes + if (this._mode !== SceneMode.SCENE2D) { + this.look(this.right, -amount); + } + }; - if (defined(that._token)) { - parameters.token = that._token; - } + /** + * Rotates the camera around its right vector by amount, in radians, in the opposite direction + * of its up vector if not in 2D mode. + * + * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * + * @see Camera#lookUp + */ + Camera.prototype.lookDown = function(amount) { + amount = defaultValue(amount, this.defaultLookAmount); - var metadata = loadJsonp(that._url, { - parameters : parameters, - proxy : that._proxy - }); - when(metadata, metadataSuccess, metadataFailure); + // only want view of map to change in 3D mode, 2D visual is incorrect when look changes + if (this._mode !== SceneMode.SCENE2D) { + this.look(this.right, amount); } + }; - if (this._useTiles) { - requestMetadata(); - } else { - this._ready = true; - this._readyPromise.resolve(true); + var lookScratchQuaternion = new Quaternion(); + var lookScratchMatrix = new Matrix3(); + /** + * Rotate each of the camera's orientation vectors around <code>axis</code> by <code>angle</code> + * + * @param {Cartesian3} axis The axis to rotate around. + * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * + * @see Camera#lookUp + * @see Camera#lookDown + * @see Camera#lookLeft + * @see Camera#lookRight + */ + Camera.prototype.look = function(axis, angle) { + if (!defined(axis)) { + throw new DeveloperError('axis is required.'); } - } + + var turnAngle = defaultValue(angle, this.defaultLookAmount); + var quaternion = Quaternion.fromAxisAngle(axis, -turnAngle, lookScratchQuaternion); + var rotation = Matrix3.fromQuaternion(quaternion, lookScratchMatrix); - function buildImageUrl(imageryProvider, x, y, level) { - var url; - if (imageryProvider._useTiles) { - url = imageryProvider._url + '/tile/' + level + '/' + y + '/' + x; - } else { - var nativeRectangle = imageryProvider._tilingScheme.tileXYToNativeRectangle(x, y, level); - var bbox = nativeRectangle.west + '%2C' + nativeRectangle.south + '%2C' + nativeRectangle.east + '%2C' + nativeRectangle.north; + var direction = this.direction; + var up = this.up; + var right = this.right; - url = imageryProvider._url + '/export?'; - url += 'bbox=' + bbox; - if (imageryProvider._tilingScheme instanceof GeographicTilingScheme) { - url += '&bboxSR=4326&imageSR=4326'; - } else { - url += '&bboxSR=3857&imageSR=3857'; - } - url += '&size=' + imageryProvider._tileWidth + '%2C' + imageryProvider._tileHeight; - url += '&format=png&transparent=true&f=image'; + Matrix3.multiplyByVector(rotation, direction, direction); + Matrix3.multiplyByVector(rotation, up, up); + Matrix3.multiplyByVector(rotation, right, right); + }; - if (imageryProvider.layers) { - url += '&layers=show:' + imageryProvider.layers; - } - } + /** + * Rotate the camera counter-clockwise around its direction vector by amount, in radians. + * + * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * + * @see Camera#twistRight + */ + Camera.prototype.twistLeft = function(amount) { + amount = defaultValue(amount, this.defaultLookAmount); + this.look(this.direction, amount); + }; - var token = imageryProvider._token; - if (defined(token)) { - if (url.indexOf('?') === -1) { - url += '?'; - } - if (url[url.length - 1] !== '?'){ - url += '&'; - } - url += 'token=' + token; - } + /** + * Rotate the camera clockwise around its direction vector by amount, in radians. + * + * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * + * @see Camera#twistLeft + */ + Camera.prototype.twistRight = function(amount) { + amount = defaultValue(amount, this.defaultLookAmount); + this.look(this.direction, -amount); + }; - var proxy = imageryProvider._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); + var rotateScratchQuaternion = new Quaternion(); + var rotateScratchMatrix = new Matrix3(); + /** + * Rotates the camera around <code>axis</code> by <code>angle</code>. The distance + * of the camera's position to the center of the camera's reference frame remains the same. + * + * @param {Cartesian3} axis The axis to rotate around given in world coordinates. + * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * + * @see Camera#rotateUp + * @see Camera#rotateDown + * @see Camera#rotateLeft + * @see Camera#rotateRight + */ + Camera.prototype.rotate = function(axis, angle) { + if (!defined(axis)) { + throw new DeveloperError('axis is required.'); } + + var turnAngle = defaultValue(angle, this.defaultRotateAmount); + var quaternion = Quaternion.fromAxisAngle(axis, -turnAngle, rotateScratchQuaternion); + var rotation = Matrix3.fromQuaternion(quaternion, rotateScratchMatrix); + Matrix3.multiplyByVector(rotation, this.position, this.position); + Matrix3.multiplyByVector(rotation, this.direction, this.direction); + Matrix3.multiplyByVector(rotation, this.up, this.up); + Cartesian3.cross(this.direction, this.up, this.right); + Cartesian3.cross(this.right, this.direction, this.up); - return url; - } + this._adjustOrthographicFrustum(false); + }; - defineProperties(ArcGisMapServerImageryProvider.prototype, { - /** - * Gets the URL of the ArcGIS MapServer. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; - } - }, + /** + * Rotates the camera around the center of the camera's reference frame by angle downwards. + * + * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * + * @see Camera#rotateUp + * @see Camera#rotate + */ + Camera.prototype.rotateDown = function(angle) { + angle = defaultValue(angle, this.defaultRotateAmount); + rotateVertical(this, angle); + }; - /** - * Gets the ArcGIS token used to authenticate with the ArcGis MapServer service. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {String} - * @readonly - */ - token : { - get : function() { - return this._token; - } - }, + /** + * Rotates the camera around the center of the camera's reference frame by angle upwards. + * + * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * + * @see Camera#rotateDown + * @see Camera#rotate + */ + Camera.prototype.rotateUp = function(angle) { + angle = defaultValue(angle, this.defaultRotateAmount); + rotateVertical(this, -angle); + }; - /** - * Gets the proxy used by this provider. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._proxy; - } - }, + var rotateVertScratchP = new Cartesian3(); + var rotateVertScratchA = new Cartesian3(); + var rotateVertScratchTan = new Cartesian3(); + var rotateVertScratchNegate = new Cartesian3(); + function rotateVertical(camera, angle) { + var position = camera.position; + var p = Cartesian3.normalize(position, rotateVertScratchP); + if (defined(camera.constrainedAxis)) { + var northParallel = Cartesian3.equalsEpsilon(p, camera.constrainedAxis, CesiumMath.EPSILON2); + var southParallel = Cartesian3.equalsEpsilon(p, Cartesian3.negate(camera.constrainedAxis, rotateVertScratchNegate), CesiumMath.EPSILON2); + if ((!northParallel && !southParallel)) { + var constrainedAxis = Cartesian3.normalize(camera.constrainedAxis, rotateVertScratchA); - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); + var dot = Cartesian3.dot(p, constrainedAxis); + var angleToAxis = CesiumMath.acosClamped(dot); + if (angle > 0 && angle > angleToAxis) { + angle = angleToAxis - CesiumMath.EPSILON4; } - - return this._tileWidth; - } - }, - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight: { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + dot = Cartesian3.dot(p, Cartesian3.negate(constrainedAxis, rotateVertScratchNegate)); + angleToAxis = CesiumMath.acosClamped(dot); + if (angle < 0 && -angle > angleToAxis) { + angle = -angleToAxis + CesiumMath.EPSILON4; } - - return this._tileHeight; - } - }, - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); - } - - return this._maximumLevel; + var tangent = Cartesian3.cross(constrainedAxis, p, rotateVertScratchTan); + camera.rotate(tangent, angle); + } else if ((northParallel && angle < 0) || (southParallel && angle > 0)) { + camera.rotate(camera.right, angle); } - }, + } else { + camera.rotate(camera.right, angle); + } + } - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); - } - - return 0; - } - }, + /** + * Rotates the camera around the center of the camera's reference frame by angle to the right. + * + * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * + * @see Camera#rotateLeft + * @see Camera#rotate + */ + Camera.prototype.rotateRight = function(angle) { + angle = defaultValue(angle, this.defaultRotateAmount); + rotateHorizontal(this, -angle); + }; - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme; - } - }, + /** + * Rotates the camera around the center of the camera's reference frame by angle to the left. + * + * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * + * @see Camera#rotateRight + * @see Camera#rotate + */ + Camera.prototype.rotateLeft = function(angle) { + angle = defaultValue(angle, this.defaultRotateAmount); + rotateHorizontal(this, angle); + }; - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - if (!this._ready) { - throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); - } - - return this._rectangle; - } - }, + function rotateHorizontal(camera, angle) { + if (defined(camera.constrainedAxis)) { + camera.rotate(camera.constrainedAxis, angle); + } else { + camera.rotate(camera.up, angle); + } + } - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); - } - - return this._tileDiscardPolicy; - } - }, + function zoom2D(camera, amount) { + var frustum = camera.frustum; - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._errorEvent; - } - }, + if (!(frustum instanceof OrthographicOffCenterFrustum) || !defined(frustum.left) || !defined(frustum.right) || + !defined(frustum.bottom) || !defined(frustum.top)) { + throw new DeveloperError('The camera frustum is expected to be orthographic for 2D camera control.'); + } + + var ratio; + amount = amount * 0.5; - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; + if((Math.abs(frustum.top) + Math.abs(frustum.bottom)) > (Math.abs(frustum.left) + Math.abs(frustum.right))) { + var newTop = frustum.top - amount; + var newBottom = frustum.bottom + amount; + + var maxBottom = camera._maxCoord.y; + if (camera._scene.mapMode2D === MapMode2D.ROTATE) { + maxBottom *= camera.maximumZoomFactor; } - }, - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; + if (newBottom > maxBottom) { + newBottom = maxBottom; + newTop = -maxBottom; } - }, - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. - * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return this._credit; + if (newTop <= newBottom) { + newTop = 1.0; + newBottom = -1.0; } - }, - /** - * Gets a value indicating whether this imagery provider is using pre-cached tiles from the - * ArcGIS MapServer. If the imagery provider is not yet ready ({@link ArcGisMapServerImageryProvider#ready}), this function - * will return the value of `options.usePreCachedTilesIfAvailable`, even if the MapServer does - * not have pre-cached tiles. - * @memberof ArcGisMapServerImageryProvider.prototype - * - * @type {Boolean} - * @readonly - * @default true - */ - usingPrecachedTiles : { - get : function() { - return this._useTiles; + ratio = frustum.right / frustum.top; + frustum.top = newTop; + frustum.bottom = newBottom; + frustum.right = frustum.top * ratio; + frustum.left = -frustum.right; + } else { + var newRight = frustum.right - amount; + var newLeft = frustum.left + amount; + + var maxRight = camera._maxCoord.x; + if (camera._scene.mapMode2D === MapMode2D.ROTATE) { + maxRight *= camera.maximumZoomFactor; } - }, - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof ArcGisMapServerImageryProvider.prototype - * - * @type {Boolean} - * @readonly - * @default true - */ - hasAlphaChannel : { - get : function() { - return true; + if (newRight > maxRight) { + newRight = maxRight; + newLeft = -maxRight; } - }, - /** - * Gets the comma-separated list of layer IDs to show. - * @memberof ArcGisMapServerImageryProvider.prototype - * - * @type {String} - */ - layers : { - get : function() { - return this._layers; + if (newRight <= newLeft) { + newRight = 1.0; + newLeft = -1.0; } + ratio = frustum.top / frustum.right; + frustum.right = newRight; + frustum.left = newLeft; + frustum.top = frustum.right * ratio; + frustum.bottom = -frustum.top; } - }); + } + function zoom3D(camera, amount) { + camera.move(camera.direction, amount); + } /** - * Gets the credits to be displayed when a given tile is displayed. + * Zooms <code>amount</code> along the camera's view vector. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * @param {Number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + * @see Camera#zoomOut */ - ArcGisMapServerImageryProvider.prototype.getTileCredits = function(x, y, level) { - return undefined; + Camera.prototype.zoomIn = function(amount) { + amount = defaultValue(amount, this.defaultZoomAmount); + if (this._mode === SceneMode.SCENE2D) { + zoom2D(this, amount); + } else { + zoom3D(this, amount); + } }; /** - * Requests the image for a given tile. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Zooms <code>amount</code> along the opposite direction of + * the camera's view vector. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. + * @param {Number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + * @see Camera#zoomIn */ - ArcGisMapServerImageryProvider.prototype.requestImage = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); + Camera.prototype.zoomOut = function(amount) { + amount = defaultValue(amount, this.defaultZoomAmount); + if (this._mode === SceneMode.SCENE2D) { + zoom2D(this, -amount); + } else { + zoom3D(this, -amount); } - - var url = buildImageUrl(this, x, y, level); - return ImageryProvider.loadImage(this, url, request); }; /** + * Gets the magnitude of the camera position. In 3D, this is the vector magnitude. In 2D and + * Columbus view, this is the distance to the map. + * + * @returns {Number} The magnitude of the position. + */ + Camera.prototype.getMagnitude = function() { + if (this._mode === SceneMode.SCENE3D) { + return Cartesian3.magnitude(this.position); + } else if (this._mode === SceneMode.COLUMBUS_VIEW) { + return Math.abs(this.position.z); + } else if (this._mode === SceneMode.SCENE2D) { + return Math.max(this.frustum.right - this.frustum.left, this.frustum.top - this.frustum.bottom); + } + }; + + var scratchLookAtMatrix4 = new Matrix4(); + /** - * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * Sets the camera position and orientation using a target and offset. The target must be given in + * world coordinates. The offset can be either a cartesian or heading/pitch/range in the local east-north-up reference frame centered at the target. + * If the offset is a cartesian, then it is an offset from the center of the reference frame defined by the transformation matrix. If the offset + * is heading/pitch/range, then the heading and the pitch angles are defined in the reference frame defined by the transformation matrix. + * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch + * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. + * In 2D, there must be a top down view. The camera will be placed above the target looking down. The height above the + * target will be the magnitude of the offset. The heading will be determined from the offset. If the heading cannot be + * determined from the offset, the heading will be north. * - * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + * @param {Cartesian3} target The target position in world coordinates. + * @param {Cartesian3|HeadingPitchRange} offset The offset from the target in the local east-north-up reference frame centered at the target. + * + * @exception {DeveloperError} lookAt is not supported while morphing. + * + * @example + * // 1. Using a cartesian offset + * var center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0); + * viewer.camera.lookAt(center, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)); + * + * // 2. Using a HeadingPitchRange offset + * var center = Cesium.Cartesian3.fromDegrees(-72.0, 40.0); + * var heading = Cesium.Math.toRadians(50.0); + * var pitch = Cesium.Math.toRadians(-20.0); + * var range = 5000.0; + * viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range)); */ - ArcGisMapServerImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - if (!this._ready) { - throw new DeveloperError('pickFeatures must not be called before the imagery provider is ready.'); + Camera.prototype.lookAt = function(target, offset) { + if (!defined(target)) { + throw new DeveloperError('target is required'); } - - if (!this.enablePickFeatures) { - return undefined; + if (!defined(offset)) { + throw new DeveloperError('offset is required'); } + if (this._mode === SceneMode.MORPHING) { + throw new DeveloperError('lookAt is not supported while morphing.'); + } + + var transform = Transforms.eastNorthUpToFixedFrame(target, Ellipsoid.WGS84, scratchLookAtMatrix4); + this.lookAtTransform(transform, offset); + }; - var rectangle = this._tilingScheme.tileXYToNativeRectangle(x, y, level); + var scratchLookAtHeadingPitchRangeOffset = new Cartesian3(); + var scratchLookAtHeadingPitchRangeQuaternion1 = new Quaternion(); + var scratchLookAtHeadingPitchRangeQuaternion2 = new Quaternion(); + var scratchHeadingPitchRangeMatrix3 = new Matrix3(); - var horizontal; - var vertical; - var sr; - if (this._tilingScheme instanceof GeographicTilingScheme) { - horizontal = CesiumMath.toDegrees(longitude); - vertical = CesiumMath.toDegrees(latitude); - sr = '4326'; - } else { - var projected = this._tilingScheme.projection.project(new Cartographic(longitude, latitude, 0.0)); - horizontal = projected.x; - vertical = projected.y; - sr = '3857'; - } + function offsetFromHeadingPitchRange(heading, pitch, range) { + pitch = CesiumMath.clamp(pitch, -CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO); + heading = CesiumMath.zeroToTwoPi(heading) - CesiumMath.PI_OVER_TWO; - var url = this._url + '/identify?f=json&tolerance=2&geometryType=esriGeometryPoint'; - url += '&geometry=' + horizontal + ',' + vertical; - url += '&mapExtent=' + rectangle.west + ',' + rectangle.south + ',' + rectangle.east + ',' + rectangle.north; - url += '&imageDisplay=' + this._tileWidth + ',' + this._tileHeight + ',96'; - url += '&sr=' + sr; + var pitchQuat = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -pitch, scratchLookAtHeadingPitchRangeQuaternion1); + var headingQuat = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -heading, scratchLookAtHeadingPitchRangeQuaternion2); + var rotQuat = Quaternion.multiply(headingQuat, pitchQuat, headingQuat); + var rotMatrix = Matrix3.fromQuaternion(rotQuat, scratchHeadingPitchRangeMatrix3); - url += '&layers=visible'; - if (defined(this._layers)) { - url += ':' + this._layers; - } + var offset = Cartesian3.clone(Cartesian3.UNIT_X, scratchLookAtHeadingPitchRangeOffset); + Matrix3.multiplyByVector(rotMatrix, offset, offset); + Cartesian3.negate(offset, offset); + Cartesian3.multiplyByScalar(offset, range, offset); + return offset; + } - if (defined(this._token)) { - url += '&token=' + this._token; + /** + * Sets the camera position and orientation using a target and transformation matrix. The offset can be either a cartesian or heading/pitch/range. + * If the offset is a cartesian, then it is an offset from the center of the reference frame defined by the transformation matrix. If the offset + * is heading/pitch/range, then the heading and the pitch angles are defined in the reference frame defined by the transformation matrix. + * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch + * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. + * + * In 2D, there must be a top down view. The camera will be placed above the center of the reference frame. The height above the + * target will be the magnitude of the offset. The heading will be determined from the offset. If the heading cannot be + * determined from the offset, the heading will be north. + * + * @param {Matrix4} transform The transformation matrix defining the reference frame. + * @param {Cartesian3|HeadingPitchRange} [offset] The offset from the target in a reference frame centered at the target. + * + * @exception {DeveloperError} lookAtTransform is not supported while morphing. + * + * @example + * // 1. Using a cartesian offset + * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-98.0, 40.0)); + * viewer.camera.lookAtTransform(transform, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)); + * + * // 2. Using a HeadingPitchRange offset + * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-72.0, 40.0)); + * var heading = Cesium.Math.toRadians(50.0); + * var pitch = Cesium.Math.toRadians(-20.0); + * var range = 5000.0; + * viewer.camera.lookAtTransform(transform, new Cesium.HeadingPitchRange(heading, pitch, range)); + */ + Camera.prototype.lookAtTransform = function(transform, offset) { + if (!defined(transform)) { + throw new DeveloperError('transform is required'); + } + if (this._mode === SceneMode.MORPHING) { + throw new DeveloperError('lookAtTransform is not supported while morphing.'); + } + + this._setTransform(transform); + if (!defined(offset)) { + return; } - if (defined(this._proxy)) { - url = this._proxy.getURL(url); + var cartesianOffset; + if (defined(offset.heading)) { + cartesianOffset = offsetFromHeadingPitchRange(offset.heading, offset.pitch, offset.range); + } else { + cartesianOffset = offset; } - return loadJson(url).then(function(json) { - var result = []; + if (this._mode === SceneMode.SCENE2D) { + Cartesian2.clone(Cartesian2.ZERO, this.position); - var features = json.results; - if (!defined(features)) { - return result; + Cartesian3.negate(cartesianOffset, this.up); + this.up.z = 0.0; + + if (Cartesian3.magnitudeSquared(this.up) < CesiumMath.EPSILON10) { + Cartesian3.clone(Cartesian3.UNIT_Y, this.up); } - for (var i = 0; i < features.length; ++i) { - var feature = features[i]; + Cartesian3.normalize(this.up, this.up); - var featureInfo = new ImageryLayerFeatureInfo(); - featureInfo.data = feature; - featureInfo.name = feature.value; - featureInfo.properties = feature.attributes; - featureInfo.configureDescriptionFromProperties(feature.attributes); + this._setTransform(Matrix4.IDENTITY); - // If this is a point feature, use the coordinates of the point. - if (feature.geometryType === 'esriGeometryPoint' && feature.geometry) { - var wkid = feature.geometry.spatialReference && feature.geometry.spatialReference.wkid ? feature.geometry.spatialReference.wkid : 4326; - if (wkid === 4326 || wkid === 4283) { - featureInfo.position = Cartographic.fromDegrees(feature.geometry.x, feature.geometry.y, feature.geometry.z); - } else if (wkid === 102100 || wkid === 900913 || wkid === 3857) { - var projection = new WebMercatorProjection(); - featureInfo.position = projection.unproject(new Cartesian3(feature.geometry.x, feature.geometry.y, feature.geometry.z)); - } - } + Cartesian3.negate(Cartesian3.UNIT_Z, this.direction); + Cartesian3.cross(this.direction, this.up, this.right); + Cartesian3.normalize(this.right, this.right); - result.push(featureInfo); - } + var frustum = this.frustum; + var ratio = frustum.top / frustum.right; + frustum.right = Cartesian3.magnitude(cartesianOffset) * 0.5; + frustum.left = -frustum.right; + frustum.top = ratio * frustum.right; + frustum.bottom = -frustum.top; - return result; - }); - }; + this._setTransform(transform); - return ArcGisMapServerImageryProvider; -}); + return; + } -define('Scene/Cesium3DTileColorBlendMode',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + Cartesian3.clone(cartesianOffset, this.position); + Cartesian3.negate(this.position, this.direction); + Cartesian3.normalize(this.direction, this.direction); + Cartesian3.cross(this.direction, Cartesian3.UNIT_Z, this.right); - /** - * Defines how per-feature colors set from the Cesium API or declarative styling blend with the source colors from - * the original feature, e.g. glTF material or per-point color in the tile. - * <p> - * When <code>REPLACE</code> or <code>MIX</code> are used and the source color is a glTF material, the technique must assign the - * <code>_3DTILESDIFFUSE</code> semantic to the diffuse color parameter. Otherwise only <code>HIGHLIGHT</code> is supported. - * </p> - * <pre><code> - * "techniques": { - * "technique0": { - * "parameters": { - * "diffuse": { - * "semantic": "_3DTILESDIFFUSE", - * "type": 35666 - * } - * } - * } - * } - * </code></pre> - * - * @exports Cesium3DTileColorBlendMode - */ - var Cesium3DTileColorBlendMode = { - /** - * Multiplies the source color by the feature color. - * - * @type {Number} - * @constant - */ - HIGHLIGHT : 0, + if (Cartesian3.magnitudeSquared(this.right) < CesiumMath.EPSILON10) { + Cartesian3.clone(Cartesian3.UNIT_X, this.right); + } - /** - * Replaces the source color with the feature color. - * - * @type {Number} - * @constant - */ - REPLACE : 1, + Cartesian3.normalize(this.right, this.right); + Cartesian3.cross(this.right, this.direction, this.up); + Cartesian3.normalize(this.up, this.up); - /** - * Blends the source color and feature color together. - * - * @type {Number} - * @constant - */ - MIX : 2 + this._adjustOrthographicFrustum(true); }; - return freezeObject(Cesium3DTileColorBlendMode); -}); + var viewRectangle3DCartographic1 = new Cartographic(); + var viewRectangle3DCartographic2 = new Cartographic(); + var viewRectangle3DNorthEast = new Cartesian3(); + var viewRectangle3DSouthWest = new Cartesian3(); + var viewRectangle3DNorthWest = new Cartesian3(); + var viewRectangle3DSouthEast = new Cartesian3(); + var viewRectangle3DNorthCenter = new Cartesian3(); + var viewRectangle3DSouthCenter = new Cartesian3(); + var viewRectangle3DCenter = new Cartesian3(); + var viewRectangle3DEquator = new Cartesian3(); + var defaultRF = { + direction : new Cartesian3(), + right : new Cartesian3(), + up : new Cartesian3() + }; + var viewRectangle3DEllipsoidGeodesic; -define('Scene/getBinaryAccessor',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/ComponentDatatype', - '../Core/Matrix2', - '../Core/Matrix3', - '../Core/Matrix4' - ], function( - Cartesian2, - Cartesian3, - Cartesian4, - ComponentDatatype, - Matrix2, - Matrix3, - Matrix4) { - 'use strict'; + function computeD(direction, upOrRight, corner, tanThetaOrPhi) { + var opposite = Math.abs(Cartesian3.dot(upOrRight, corner)); + return opposite / tanThetaOrPhi - Cartesian3.dot(direction, corner); + } - var ComponentsPerAttribute = { - SCALAR : 1, - VEC2 : 2, - VEC3 : 3, - VEC4 : 4, - MAT2 : 4, - MAT3 : 9, - MAT4 : 16 - }; + function rectangleCameraPosition3D(camera, rectangle, result, updateCamera) { + var ellipsoid = camera._projection.ellipsoid; + var cameraRF = updateCamera ? camera : defaultRF; - var ClassPerType = { - SCALAR : undefined, - VEC2 : Cartesian2, - VEC3 : Cartesian3, - VEC4 : Cartesian4, - MAT2 : Matrix2, - MAT3 : Matrix3, - MAT4 : Matrix4 - }; + var north = rectangle.north; + var south = rectangle.south; + var east = rectangle.east; + var west = rectangle.west; - /** - * @private - */ - function getBinaryAccessor(accessor) { - var componentType = accessor.componentType; - var componentDatatype; - if (typeof componentType === 'string') { - componentDatatype = ComponentDatatype.fromName(componentType); - } else { - componentDatatype = componentType; + // If we go across the International Date Line + if (west > east) { + east += CesiumMath.TWO_PI; } - var componentsPerAttribute = ComponentsPerAttribute[accessor.type]; - var classType = ClassPerType[accessor.type]; - return { - componentsPerAttribute : componentsPerAttribute, - classType : classType, - createArrayBufferView : function(buffer, byteOffset, length) { - return ComponentDatatype.createArrayBufferView(componentDatatype, buffer, byteOffset, componentsPerAttribute * length); + // Find the midpoint latitude. + // + // EllipsoidGeodesic will fail if the north and south edges are very close to being on opposite sides of the ellipsoid. + // Ideally we'd just call EllipsoidGeodesic.setEndPoints and let it throw when it detects this case, but sadly it doesn't + // even look for this case in optimized builds, so we have to test for it here instead. + // + // Fortunately, this case can only happen (here) when north is very close to the north pole and south is very close to the south pole, + // so handle it just by using 0 latitude as the center. It's certainliy possible to use a smaller tolerance + // than one degree here, but one degree is safe and putting the center at 0 latitude should be good enough for any + // rectangle that spans 178+ of the 180 degrees of latitude. + var longitude = (west + east) * 0.5; + var latitude; + if (south < -CesiumMath.PI_OVER_TWO + CesiumMath.RADIANS_PER_DEGREE && north > CesiumMath.PI_OVER_TWO - CesiumMath.RADIANS_PER_DEGREE) { + latitude = 0.0; + } else { + var northCartographic = viewRectangle3DCartographic1; + northCartographic.longitude = longitude; + northCartographic.latitude = north; + northCartographic.height = 0.0; + + var southCartographic = viewRectangle3DCartographic2; + southCartographic.longitude = longitude; + southCartographic.latitude = south; + southCartographic.height = 0.0; + + var ellipsoidGeodesic = viewRectangle3DEllipsoidGeodesic; + if (!defined(ellipsoidGeodesic) || ellipsoidGeodesic.ellipsoid !== ellipsoid) { + viewRectangle3DEllipsoidGeodesic = ellipsoidGeodesic = new EllipsoidGeodesic(undefined, undefined, ellipsoid); } - }; - } - return getBinaryAccessor; -}); + ellipsoidGeodesic.setEndPoints(northCartographic, southCartographic); + latitude = ellipsoidGeodesic.interpolateUsingFraction(0.5, viewRectangle3DCartographic1).latitude; + } -define('Scene/Cesium3DTileBatchTable',[ - '../Core/arrayFill', - '../Core/Cartesian2', - '../Core/Cartesian4', - '../Core/Check', - '../Core/clone', - '../Core/Color', - '../Core/combine', - '../Core/ComponentDatatype', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Math', - '../Core/PixelFormat', - '../Core/RuntimeError', - '../Renderer/ContextLimits', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/PixelDatatype', - '../Renderer/RenderState', - '../Renderer/Sampler', - '../Renderer/ShaderSource', - '../Renderer/Texture', - '../Renderer/TextureMagnificationFilter', - '../Renderer/TextureMinificationFilter', - './AttributeType', - './BlendingState', - './Cesium3DTileColorBlendMode', - './CullFace', - './getBinaryAccessor', - './StencilFunction', - './StencilOperation' - ], function( - arrayFill, - Cartesian2, - Cartesian4, - Check, - clone, - Color, - combine, - ComponentDatatype, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - CesiumMath, - PixelFormat, - RuntimeError, - ContextLimits, - DrawCommand, - Pass, - PixelDatatype, - RenderState, - Sampler, - ShaderSource, - Texture, - TextureMagnificationFilter, - TextureMinificationFilter, - AttributeType, - BlendingState, - Cesium3DTileColorBlendMode, - CullFace, - getBinaryAccessor, - StencilFunction, - StencilOperation) { - 'use strict'; + var centerCartographic = viewRectangle3DCartographic1; + centerCartographic.longitude = longitude; + centerCartographic.latitude = latitude; + centerCartographic.height = 0.0; - var DEFAULT_COLOR_VALUE = Color.WHITE; - var DEFAULT_SHOW_VALUE = true; + var center = ellipsoid.cartographicToCartesian(centerCartographic, viewRectangle3DCenter); - /** - * @private - */ - function Cesium3DTileBatchTable(content, featuresLength, batchTableJson, batchTableBinary) { - /** - * @readonly - */ - this.featuresLength = featuresLength; + var cart = viewRectangle3DCartographic1; + cart.longitude = east; + cart.latitude = north; + var northEast = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthEast); + cart.longitude = west; + var northWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthWest); + cart.longitude = longitude; + var northCenter = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthCenter); + cart.latitude = south; + var southCenter = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthCenter); + cart.longitude = east; + var southEast = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthEast); + cart.longitude = west; + var southWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthWest); + + Cartesian3.subtract(northWest, center, northWest); + Cartesian3.subtract(southEast, center, southEast); + Cartesian3.subtract(northEast, center, northEast); + Cartesian3.subtract(southWest, center, southWest); + Cartesian3.subtract(northCenter, center, northCenter); + Cartesian3.subtract(southCenter, center, southCenter); + + var direction = ellipsoid.geodeticSurfaceNormal(center, cameraRF.direction); + Cartesian3.negate(direction, direction); + var right = Cartesian3.cross(direction, Cartesian3.UNIT_Z, cameraRF.right); + Cartesian3.normalize(right, right); + var up = Cartesian3.cross(right, direction, cameraRF.up); + + var d; + if (camera.frustum instanceof OrthographicFrustum) { + var width = Math.max(Cartesian3.distance(northEast, northWest), Cartesian3.distance(southEast, southWest)); + var height = Math.max(Cartesian3.distance(northEast, southEast), Cartesian3.distance(northWest, southWest)); - this._translucentFeaturesLength = 0; // Number of features in the tile that are translucent + var rightScalar; + var topScalar; + var ratio = camera.frustum._offCenterFrustum.right / camera.frustum._offCenterFrustum.top; + var heightRatio = height * ratio; + if (width > heightRatio) { + rightScalar = width; + topScalar = rightScalar / ratio; + } else { + topScalar = height; + rightScalar = heightRatio; + } - /** - * @private - */ - this.batchTableJson = batchTableJson; + d = Math.max(rightScalar, topScalar); + } else { + var tanPhi = Math.tan(camera.frustum.fovy * 0.5); + var tanTheta = camera.frustum.aspectRatio * tanPhi; - /** - * @private - */ - this.batchTableBinary = batchTableBinary; + d = Math.max( + computeD(direction, up, northWest, tanPhi), + computeD(direction, up, southEast, tanPhi), + computeD(direction, up, northEast, tanPhi), + computeD(direction, up, southWest, tanPhi), + computeD(direction, up, northCenter, tanPhi), + computeD(direction, up, southCenter, tanPhi), + computeD(direction, right, northWest, tanTheta), + computeD(direction, right, southEast, tanTheta), + computeD(direction, right, northEast, tanTheta), + computeD(direction, right, southWest, tanTheta), + computeD(direction, right, northCenter, tanTheta), + computeD(direction, right, southCenter, tanTheta)); - var batchTableHierarchy; - var batchTableBinaryProperties; - if (defined(batchTableJson)) { - // Extract the hierarchy and remove it from the batch table json - batchTableHierarchy = batchTableJson.HIERARCHY; - if (defined(batchTableHierarchy)) { - delete batchTableJson.HIERARCHY; - batchTableHierarchy = initializeHierarchy(batchTableHierarchy, batchTableBinary); + // If the rectangle crosses the equator, compute D at the equator, too, because that's the + // widest part of the rectangle when projected onto the globe. + if (south < 0 && north > 0) { + var equatorCartographic = viewRectangle3DCartographic1; + equatorCartographic.longitude = west; + equatorCartographic.latitude = 0.0; + equatorCartographic.height = 0.0; + var equatorPosition = ellipsoid.cartographicToCartesian(equatorCartographic, viewRectangle3DEquator); + Cartesian3.subtract(equatorPosition, center, equatorPosition); + d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); + + equatorCartographic.longitude = east; + equatorPosition = ellipsoid.cartographicToCartesian(equatorCartographic, viewRectangle3DEquator); + Cartesian3.subtract(equatorPosition, center, equatorPosition); + d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); } - // Get the binary properties - batchTableBinaryProperties = Cesium3DTileBatchTable.getBinaryProperties(featuresLength, batchTableJson, batchTableBinary); } - this._batchTableHierarchy = batchTableHierarchy; - this._batchTableBinaryProperties = batchTableBinaryProperties; - - // PERFORMANCE_IDEA: These parallel arrays probably generate cache misses in get/set color/show - // and use A LOT of memory. How can we use less memory? - this._showAlphaProperties = undefined; // [Show (0 or 255), Alpha (0 to 255)] property for each feature - this._batchValues = undefined; // Per-feature RGBA (A is based on the color's alpha and feature's show property) - - this._batchValuesDirty = false; - this._batchTexture = undefined; - this._defaultTexture = undefined; + return Cartesian3.add(center, Cartesian3.multiplyByScalar(direction, -d, viewRectangle3DEquator), result); + } - this._pickTexture = undefined; - this._pickIds = []; + var viewRectangleCVCartographic = new Cartographic(); + var viewRectangleCVNorthEast = new Cartesian3(); + var viewRectangleCVSouthWest = new Cartesian3(); + function rectangleCameraPositionColumbusView(camera, rectangle, result) { + var projection = camera._projection; + if (rectangle.west > rectangle.east) { + rectangle = Rectangle.MAX_VALUE; + } + var transform = camera._actualTransform; + var invTransform = camera._actualInvTransform; - this._content = content; + var cart = viewRectangleCVCartographic; + cart.longitude = rectangle.east; + cart.latitude = rectangle.north; + var northEast = projection.project(cart, viewRectangleCVNorthEast); + Matrix4.multiplyByPoint(transform, northEast, northEast); + Matrix4.multiplyByPoint(invTransform, northEast, northEast); - // Dimensions for batch and pick textures - var textureDimensions; - var textureStep; + cart.longitude = rectangle.west; + cart.latitude = rectangle.south; + var southWest = projection.project(cart, viewRectangleCVSouthWest); + Matrix4.multiplyByPoint(transform, southWest, southWest); + Matrix4.multiplyByPoint(invTransform, southWest, southWest); - if (featuresLength > 0) { - // PERFORMANCE_IDEA: this can waste memory in the last row in the uncommon case - // when more than one row is needed (e.g., > 16K features in one tile) - var width = Math.min(featuresLength, ContextLimits.maximumTextureSize); - var height = Math.ceil(featuresLength / ContextLimits.maximumTextureSize); - var stepX = 1.0 / width; - var centerX = stepX * 0.5; - var stepY = 1.0 / height; - var centerY = stepY * 0.5; + result.x = (northEast.x - southWest.x) * 0.5 + southWest.x; + result.y = (northEast.y - southWest.y) * 0.5 + southWest.y; - textureDimensions = new Cartesian2(width, height); - textureStep = new Cartesian4(stepX, centerX, stepY, centerY); + if (defined(camera.frustum.fovy)) { + var tanPhi = Math.tan(camera.frustum.fovy * 0.5); + var tanTheta = camera.frustum.aspectRatio * tanPhi; + result.z = Math.max((northEast.x - southWest.x) / tanTheta, (northEast.y - southWest.y) / tanPhi) * 0.5; + } else { + var width = northEast.x - southWest.x; + var height = northEast.y - southWest.y; + result.z = Math.max(width, height); } - this._textureDimensions = textureDimensions; - this._textureStep = textureStep; + return result; } - defineProperties(Cesium3DTileBatchTable.prototype, { - memorySizeInBytes : { - get : function() { - var memory = 0; - if (defined(this._pickTexture)) { - memory += this._pickTexture.sizeInBytes; - } - if (defined(this._batchTexture)) { - memory += this._batchTexture.sizeInBytes; - } - return memory; - } + var viewRectangle2DCartographic = new Cartographic(); + var viewRectangle2DNorthEast = new Cartesian3(); + var viewRectangle2DSouthWest = new Cartesian3(); + function rectangleCameraPosition2D(camera, rectangle, result) { + var projection = camera._projection; + if (rectangle.west > rectangle.east) { + rectangle = Rectangle.MAX_VALUE; } - }); - function initializeHierarchy(json, binary) { - var i; - var classId; - var binaryAccessor; + var cart = viewRectangle2DCartographic; + cart.longitude = rectangle.east; + cart.latitude = rectangle.north; + var northEast = projection.project(cart, viewRectangle2DNorthEast); + cart.longitude = rectangle.west; + cart.latitude = rectangle.south; + var southWest = projection.project(cart, viewRectangle2DSouthWest); - var instancesLength = json.instancesLength; - var classes = json.classes; - var classIds = json.classIds; - var parentCounts = json.parentCounts; - var parentIds = json.parentIds; - var parentIdsLength = instancesLength; + var width = Math.abs(northEast.x - southWest.x) * 0.5; + var height = Math.abs(northEast.y - southWest.y) * 0.5; - if (defined(classIds.byteOffset)) { - classIds.componentType = defaultValue(classIds.componentType, ComponentDatatype.UNSIGNED_SHORT); - classIds.type = AttributeType.SCALAR; - binaryAccessor = getBinaryAccessor(classIds); - classIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + classIds.byteOffset, instancesLength); + var right, top; + var ratio = camera.frustum.right / camera.frustum.top; + var heightRatio = height * ratio; + if (width > heightRatio) { + right = width; + top = right / ratio; + } else { + top = height; + right = heightRatio; } - var parentIndexes; - if (defined(parentCounts)) { - if (defined(parentCounts.byteOffset)) { - parentCounts.componentType = defaultValue(parentCounts.componentType, ComponentDatatype.UNSIGNED_SHORT); - parentCounts.type = AttributeType.SCALAR; - binaryAccessor = getBinaryAccessor(parentCounts); - parentCounts = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentCounts.byteOffset, instancesLength); - } - parentIndexes = new Uint16Array(instancesLength); - parentIdsLength = 0; - for (i = 0; i < instancesLength; ++i) { - parentIndexes[i] = parentIdsLength; - parentIdsLength += parentCounts[i]; - } - } + height = Math.max(2.0 * right, 2.0 * top); - if (defined(parentIds) && defined(parentIds.byteOffset)) { - parentIds.componentType = defaultValue(parentIds.componentType, ComponentDatatype.UNSIGNED_SHORT); - parentIds.type = AttributeType.SCALAR; - binaryAccessor = getBinaryAccessor(parentIds); - parentIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentIds.byteOffset, parentIdsLength); + result.x = (northEast.x - southWest.x) * 0.5 + southWest.x; + result.y = (northEast.y - southWest.y) * 0.5 + southWest.y; + + cart = projection.unproject(result, cart); + cart.height = height; + result = projection.project(cart, result); + + return result; + } + + /** + * Get the camera position needed to view a rectangle on an ellipsoid or map + * + * @param {Rectangle} rectangle The rectangle to view. + * @param {Cartesian3} [result] The camera position needed to view the rectangle + * @returns {Cartesian3} The camera position needed to view the rectangle + */ + Camera.prototype.getRectangleCameraCoordinates = function(rectangle, result) { + if (!defined(rectangle)) { + throw new DeveloperError('rectangle is required'); } + var mode = this._mode; - var classesLength = classes.length; - for (i = 0; i < classesLength; ++i) { - var classInstancesLength = classes[i].length; - var properties = classes[i].instances; - var binaryProperties = Cesium3DTileBatchTable.getBinaryProperties(classInstancesLength, properties, binary); - classes[i].instances = combine(binaryProperties, properties); + if (!defined(result)) { + result = new Cartesian3(); } - var classCounts = arrayFill(new Array(classesLength), 0); - var classIndexes = new Uint16Array(instancesLength); - for (i = 0; i < instancesLength; ++i) { - classId = classIds[i]; - classIndexes[i] = classCounts[classId]; - ++classCounts[classId]; + if (mode === SceneMode.SCENE3D) { + return rectangleCameraPosition3D(this, rectangle, result); + } else if (mode === SceneMode.COLUMBUS_VIEW) { + return rectangleCameraPositionColumbusView(this, rectangle, result); + } else if (mode === SceneMode.SCENE2D) { + return rectangleCameraPosition2D(this, rectangle, result); } - var hierarchy = { - classes : classes, - classIds : classIds, - classIndexes : classIndexes, - parentCounts : parentCounts, - parentIndexes : parentIndexes, - parentIds : parentIds - }; + return undefined; + }; - validateHierarchy(hierarchy); - - return hierarchy; - } + var pickEllipsoid3DRay = new Ray(); + function pickEllipsoid3D(camera, windowPosition, ellipsoid, result) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + var ray = camera.getPickRay(windowPosition, pickEllipsoid3DRay); + var intersection = IntersectionTests.rayEllipsoid(ray, ellipsoid); + if (!intersection) { + return undefined; + } - var scratchValidateStack = []; - function validateHierarchy(hierarchy) { - var stack = scratchValidateStack; - stack.length = 0; + var t = intersection.start > 0.0 ? intersection.start : intersection.stop; + return Ray.getPoint(ray, t, result); + } - var classIds = hierarchy.classIds; - var instancesLength = classIds.length; + var pickEllipsoid2DRay = new Ray(); + function pickMap2D(camera, windowPosition, projection, result) { + var ray = camera.getPickRay(windowPosition, pickEllipsoid2DRay); + var position = ray.origin; + position.z = 0.0; + var cart = projection.unproject(position); - for (var i = 0; i < instancesLength; ++i) { - validateInstance(hierarchy, i, stack); + if (cart.latitude < -CesiumMath.PI_OVER_TWO || cart.latitude > CesiumMath.PI_OVER_TWO) { + return undefined; } + + return projection.ellipsoid.cartographicToCartesian(cart, result); } - function validateInstance(hierarchy, instanceIndex, stack) { - var parentCounts = hierarchy.parentCounts; - var parentIds = hierarchy.parentIds; - var parentIndexes = hierarchy.parentIndexes; - var classIds = hierarchy.classIds; - var instancesLength = classIds.length; + var pickEllipsoidCVRay = new Ray(); + function pickMapColumbusView(camera, windowPosition, projection, result) { + var ray = camera.getPickRay(windowPosition, pickEllipsoidCVRay); + var scalar = -ray.origin.x / ray.direction.x; + Ray.getPoint(ray, scalar, result); - if (!defined(parentIds)) { - // No need to validate if there are no parents - return; + var cart = projection.unproject(new Cartesian3(result.y, result.z, 0.0)); + + if (cart.latitude < -CesiumMath.PI_OVER_TWO || cart.latitude > CesiumMath.PI_OVER_TWO || + cart.longitude < -Math.PI || cart.longitude > Math.PI) { + return undefined; } - if (instanceIndex >= instancesLength) { - throw new DeveloperError('Parent index ' + instanceIndex + ' exceeds the total number of instances: ' + instancesLength); + return projection.ellipsoid.cartographicToCartesian(cart, result); + } + + /** + * Pick an ellipsoid or map. + * + * @param {Cartesian2} windowPosition The x and y coordinates of a pixel. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to pick. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} If the ellipsoid or map was picked, returns the point on the surface of the ellipsoid or map + * in world coordinates. If the ellipsoid or map was not picked, returns undefined. + */ + Camera.prototype.pickEllipsoid = function(windowPosition, ellipsoid, result) { + if (!defined(windowPosition)) { + throw new DeveloperError('windowPosition is required.'); } - if (stack.indexOf(instanceIndex) > -1) { - throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); + + var canvas = this._scene.canvas; + if (canvas.clientWidth === 0 || canvas.clientHeight === 0) { + return undefined; } - stack.push(instanceIndex); - var parentCount = defined(parentCounts) ? parentCounts[instanceIndex] : 1; - var parentIndex = defined(parentCounts) ? parentIndexes[instanceIndex] : instanceIndex; - for (var i = 0; i < parentCount; ++i) { - var parentId = parentIds[parentIndex + i]; - // Stop the traversal when the instance has no parent (its parentId equals itself), else continue the traversal. - if (parentId !== instanceIndex) { - validateInstance(hierarchy, parentId, stack); - } + if (!defined(result)) { + result = new Cartesian3(); } - stack.pop(instanceIndex); - } - - Cesium3DTileBatchTable.getBinaryProperties = function(featuresLength, json, binary) { - var binaryProperties; - for (var name in json) { - if (json.hasOwnProperty(name)) { - var property = json[name]; - var byteOffset = property.byteOffset; - if (defined(byteOffset)) { - // This is a binary property - var componentType = property.componentType; - var type = property.type; - if (!defined(componentType)) { - throw new RuntimeError('componentType is required.'); - } - if (!defined(type)) { - throw new RuntimeError('type is required.'); - } - if (!defined(binary)) { - throw new RuntimeError('Property ' + name + ' requires a batch table binary.'); - } - - var binaryAccessor = getBinaryAccessor(property); - var componentCount = binaryAccessor.componentsPerAttribute; - var classType = binaryAccessor.classType; - var typedArray = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + byteOffset, featuresLength); - if (!defined(binaryProperties)) { - binaryProperties = {}; - } + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - // Store any information needed to access the binary data, including the typed array, - // componentCount (e.g. a VEC4 would be 4), and the type used to pack and unpack (e.g. Cartesian4). - binaryProperties[name] = { - typedArray : typedArray, - componentCount : componentCount, - type : classType - }; - } - } + if (this._mode === SceneMode.SCENE3D) { + result = pickEllipsoid3D(this, windowPosition, ellipsoid, result); + } else if (this._mode === SceneMode.SCENE2D) { + result = pickMap2D(this, windowPosition, this._projection, result); + } else if (this._mode === SceneMode.COLUMBUS_VIEW) { + result = pickMapColumbusView(this, windowPosition, this._projection, result); + } else { + return undefined; } - return binaryProperties; + + return result; }; - function getByteLength(batchTable) { - var dimensions = batchTable._textureDimensions; - return (dimensions.x * dimensions.y) * 4; - } + var pickPerspCenter = new Cartesian3(); + var pickPerspXDir = new Cartesian3(); + var pickPerspYDir = new Cartesian3(); + function getPickRayPerspective(camera, windowPosition, result) { + var canvas = camera._scene.canvas; + var width = canvas.clientWidth; + var height = canvas.clientHeight; - function getBatchValues(batchTable) { - if (!defined(batchTable._batchValues)) { - // Default batch texture to RGBA = 255: white highlight (RGB) and show/alpha = true/255 (A). - var byteLength = getByteLength(batchTable); - var bytes = new Uint8Array(byteLength); - arrayFill(bytes, 255); - batchTable._batchValues = bytes; - } + var tanPhi = Math.tan(camera.frustum.fovy * 0.5); + var tanTheta = camera.frustum.aspectRatio * tanPhi; + var near = camera.frustum.near; - return batchTable._batchValues; + var x = (2.0 / width) * windowPosition.x - 1.0; + var y = (2.0 / height) * (height - windowPosition.y) - 1.0; + + var position = camera.positionWC; + Cartesian3.clone(position, result.origin); + + var nearCenter = Cartesian3.multiplyByScalar(camera.directionWC, near, pickPerspCenter); + Cartesian3.add(position, nearCenter, nearCenter); + var xDir = Cartesian3.multiplyByScalar(camera.rightWC, x * near * tanTheta, pickPerspXDir); + var yDir = Cartesian3.multiplyByScalar(camera.upWC, y * near * tanPhi, pickPerspYDir); + var direction = Cartesian3.add(nearCenter, xDir, result.direction); + Cartesian3.add(direction, yDir, direction); + Cartesian3.subtract(direction, position, direction); + Cartesian3.normalize(direction, direction); + + return result; } - function getShowAlphaProperties(batchTable) { - if (!defined(batchTable._showAlphaProperties)) { - var byteLength = 2 * batchTable.featuresLength; - var bytes = new Uint8Array(byteLength); - // [Show = true, Alpha = 255] - arrayFill(bytes, 255); - batchTable._showAlphaProperties = bytes; + var scratchDirection = new Cartesian3(); + + function getPickRayOrthographic(camera, windowPosition, result) { + var canvas = camera._scene.canvas; + var width = canvas.clientWidth; + var height = canvas.clientHeight; + + var frustum = camera.frustum; + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; } - return batchTable._showAlphaProperties; - } + var x = (2.0 / width) * windowPosition.x - 1.0; + x *= (frustum.right - frustum.left) * 0.5; + var y = (2.0 / height) * (height - windowPosition.y) - 1.0; + y *= (frustum.top - frustum.bottom) * 0.5; - function checkBatchId(batchId, featuresLength) { - if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { - throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); + var origin = result.origin; + Cartesian3.clone(camera.position, origin); + + Cartesian3.multiplyByScalar(camera.right, x, scratchDirection); + Cartesian3.add(scratchDirection, origin, origin); + Cartesian3.multiplyByScalar(camera.up, y, scratchDirection); + Cartesian3.add(scratchDirection, origin, origin); + + Cartesian3.clone(camera.directionWC, result.direction); + + if (camera._mode === SceneMode.COLUMBUS_VIEW) { + Cartesian3.fromElements(result.origin.z, result.origin.x, result.origin.y, result.origin); } + + return result; } - Cesium3DTileBatchTable.prototype.setShow = function(batchId, show) { - checkBatchId(batchId, this.featuresLength); - Check.typeOf.bool('show', show); + /** + * Create a ray from the camera position through the pixel at <code>windowPosition</code> + * in world coordinates. + * + * @param {Cartesian2} windowPosition The x and y coordinates of a pixel. + * @param {Ray} [result] The object onto which to store the result. + * @returns {Ray} Returns the {@link Cartesian3} position and direction of the ray. + */ + Camera.prototype.getPickRay = function(windowPosition, result) { + if (!defined(windowPosition)) { + throw new DeveloperError('windowPosition is required.'); + } - if (show && !defined(this._showAlphaProperties)) { - // Avoid allocating since the default is show = true - return; + if (!defined(result)) { + result = new Ray(); } - var showAlphaProperties = getShowAlphaProperties(this); - var propertyOffset = batchId * 2; - - var newShow = show ? 255 : 0; - if (showAlphaProperties[propertyOffset] !== newShow) { - showAlphaProperties[propertyOffset] = newShow; + var frustum = this.frustum; + if (defined(frustum.aspectRatio) && defined(frustum.fov) && defined(frustum.near)) { + return getPickRayPerspective(this, windowPosition, result); + } - var batchValues = getBatchValues(this); + return getPickRayOrthographic(this, windowPosition, result); + }; - // Compute alpha used in the shader based on show and color.alpha properties - var offset = (batchId * 4) + 3; - batchValues[offset] = show ? showAlphaProperties[propertyOffset + 1] : 0; + var scratchToCenter = new Cartesian3(); + var scratchProj = new Cartesian3(); - this._batchValuesDirty = true; + /** + * Return the distance from the camera to the front of the bounding sphere. + * + * @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. + * @returns {Number} The distance to the bounding sphere. + */ + Camera.prototype.distanceToBoundingSphere = function(boundingSphere) { + if (!defined(boundingSphere)) { + throw new DeveloperError('boundingSphere is required.'); } + + var toCenter = Cartesian3.subtract(this.positionWC, boundingSphere.center, scratchToCenter); + var proj = Cartesian3.multiplyByScalar(this.directionWC, Cartesian3.dot(toCenter, this.directionWC), scratchProj); + return Math.max(0.0, Cartesian3.magnitude(proj) - boundingSphere.radius); }; - Cesium3DTileBatchTable.prototype.setAllShow = function(show) { - Check.typeOf.bool('show', show); - - var featuresLength = this.featuresLength; - for (var i = 0; i < featuresLength; ++i) { - this.setShow(i, show); + var scratchPixelSize = new Cartesian2(); + + /** + * Return the pixel size in meters. + * + * @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. + * @param {Number} drawingBufferWidth The drawing buffer width. + * @param {Number} drawingBufferHeight The drawing buffer height. + * @returns {Number} The pixel size in meters. + */ + Camera.prototype.getPixelSize = function(boundingSphere, drawingBufferWidth, drawingBufferHeight) { + if (!defined(boundingSphere)) { + throw new DeveloperError('boundingSphere is required.'); + } + if (!defined(drawingBufferWidth)) { + throw new DeveloperError('drawingBufferWidth is required.'); } + if (!defined(drawingBufferHeight)) { + throw new DeveloperError('drawingBufferHeight is required.'); + } + + var distance = this.distanceToBoundingSphere(boundingSphere); + var pixelSize = this.frustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, scratchPixelSize); + return Math.max(pixelSize.x, pixelSize.y); }; - Cesium3DTileBatchTable.prototype.getShow = function(batchId) { - checkBatchId(batchId, this.featuresLength); - - if (!defined(this._showAlphaProperties)) { - // Avoid allocating since the default is show = true - return true; - } + function createAnimationTemplateCV(camera, position, center, maxX, maxY, duration) { + var newPosition = Cartesian3.clone(position); - var offset = batchId * 2; - return (this._showAlphaProperties[offset] === 255); - }; + if (center.y > maxX) { + newPosition.y -= center.y - maxX; + } else if (center.y < -maxX) { + newPosition.y += -maxX - center.y; + } - var scratchColorBytes = new Array(4); + if (center.z > maxY) { + newPosition.z -= center.z - maxY; + } else if (center.z < -maxY) { + newPosition.z += -maxY - center.z; + } - Cesium3DTileBatchTable.prototype.setColor = function(batchId, color) { - checkBatchId(batchId, this.featuresLength); - Check.typeOf.object('color', color); - - if (Color.equals(color, DEFAULT_COLOR_VALUE) && !defined(this._batchValues)) { - // Avoid allocating since the default is white - return; + function updateCV(value) { + var interp = Cartesian3.lerp(position, newPosition, value.time, new Cartesian3()); + camera.worldToCameraCoordinatesPoint(interp, camera.position); } + return { + easingFunction : EasingFunction.EXPONENTIAL_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + duration : duration, + update : updateCV + }; + } - var newColor = color.toBytes(scratchColorBytes); - var newAlpha = newColor[3]; + var normalScratch = new Cartesian3(); + var centerScratch = new Cartesian3(); + var posScratch = new Cartesian3(); + var scratchCartesian3Subtract = new Cartesian3(); - var batchValues = getBatchValues(this); - var offset = batchId * 4; + function createAnimationCV(camera, duration) { + var position = camera.position; + var direction = camera.direction; - var showAlphaProperties = getShowAlphaProperties(this); - var propertyOffset = batchId * 2; + var normal = camera.worldToCameraCoordinatesVector(Cartesian3.UNIT_X, normalScratch); + var scalar = -Cartesian3.dot(normal, position) / Cartesian3.dot(normal, direction); + var center = Cartesian3.add(position, Cartesian3.multiplyByScalar(direction, scalar, centerScratch), centerScratch); + camera.cameraToWorldCoordinatesPoint(center, center); - if ((batchValues[offset] !== newColor[0]) || - (batchValues[offset + 1] !== newColor[1]) || - (batchValues[offset + 2] !== newColor[2]) || - (showAlphaProperties[propertyOffset + 1] !== newAlpha)) { + position = camera.cameraToWorldCoordinatesPoint(camera.position, posScratch); - batchValues[offset] = newColor[0]; - batchValues[offset + 1] = newColor[1]; - batchValues[offset + 2] = newColor[2]; + var tanPhi = Math.tan(camera.frustum.fovy * 0.5); + var tanTheta = camera.frustum.aspectRatio * tanPhi; + var distToC = Cartesian3.magnitude(Cartesian3.subtract(position, center, scratchCartesian3Subtract)); + var dWidth = tanTheta * distToC; + var dHeight = tanPhi * distToC; - var wasTranslucent = (showAlphaProperties[propertyOffset + 1] !== 255); + var mapWidth = camera._maxCoord.x; + var mapHeight = camera._maxCoord.y; - // Compute alpha used in the shader based on show and color.alpha properties - var show = showAlphaProperties[propertyOffset] !== 0; - batchValues[offset + 3] = show ? newAlpha : 0; - showAlphaProperties[propertyOffset + 1] = newAlpha; + var maxX = Math.max(dWidth - mapWidth, mapWidth); + var maxY = Math.max(dHeight - mapHeight, mapHeight); - // Track number of translucent features so we know if this tile needs - // opaque commands, translucent commands, or both for rendering. - var isTranslucent = (newAlpha !== 255); - if (isTranslucent && !wasTranslucent) { - ++this._translucentFeaturesLength; - } else if (!isTranslucent && wasTranslucent) { - --this._translucentFeaturesLength; + if (position.z < -maxX || position.z > maxX || position.y < -maxY || position.y > maxY) { + var translateX = center.y < -maxX || center.y > maxX; + var translateY = center.z < -maxY || center.z > maxY; + if (translateX || translateY) { + return createAnimationTemplateCV(camera, position, center, maxX, maxY, duration); } + } - this._batchValuesDirty = true; + return undefined; + } + + /** + * Create an animation to move the map into view. This method is only valid for 2D and Columbus modes. + * + * @param {Number} duration The duration, in seconds, of the animation. + * @returns {Object} The animation or undefined if the scene mode is 3D or the map is already ion view. + * + * @private + */ + Camera.prototype.createCorrectPositionTween = function(duration) { + if (!defined(duration)) { + throw new DeveloperError('duration is required.'); + } + + if (this._mode === SceneMode.COLUMBUS_VIEW) { + return createAnimationCV(this, duration); } + + return undefined; }; - Cesium3DTileBatchTable.prototype.setAllColor = function(color) { - Check.typeOf.object('color', color); - - var featuresLength = this.featuresLength; - for (var i = 0; i < featuresLength; ++i) { - this.setColor(i, color); + var scratchFlyToDestination = new Cartesian3(); + var newOptions = { + destination : undefined, + heading : undefined, + pitch : undefined, + roll : undefined, + duration : undefined, + complete : undefined, + cancel : undefined, + endTransform : undefined, + maximumHeight : undefined, + easingFunction : undefined + }; + + /** + * Cancels the current camera flight if one is in progress. + * The camera is left at it's current location. + */ + Camera.prototype.cancelFlight = function () { + if (defined(this._currentFlight)) { + this._currentFlight.cancelTween(); + this._currentFlight = undefined; } }; - Cesium3DTileBatchTable.prototype.getColor = function(batchId, result) { - checkBatchId(batchId, this.featuresLength); - Check.typeOf.object('result', result); + /** + * Flies the camera from its current position to a new position. + * + * @param {Object} options Object with the following properties: + * @param {Cartesian3|Rectangle} options.destination The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. + * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pith and roll properties. By default, the direction will point + * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive + * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. + * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. + * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. + * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. + * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed. + * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. + * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. + * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. + * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. + * @param {EasingFunction|EasingFunction~Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight. + * + * @exception {DeveloperError} If either direction or up is given, then both are required. + * + * @example + * // 1. Fly to a position with a top-down view + * viewer.camera.flyTo({ + * destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0) + * }); + * + * // 2. Fly to a Rectangle with a top-down view + * viewer.camera.flyTo({ + * destination : Cesium.Rectangle.fromDegrees(west, south, east, north) + * }); + * + * // 3. Fly to a position with an orientation using unit vectors. + * viewer.camera.flyTo({ + * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), + * orientation : { + * direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734), + * up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339) + * } + * }); + * + * // 4. Fly to a position with an orientation using heading, pitch and roll. + * viewer.camera.flyTo({ + * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), + * orientation : { + * heading : Cesium.Math.toRadians(175.0), + * pitch : Cesium.Math.toRadians(-35.0), + * roll : 0.0 + * } + * }); + */ + Camera.prototype.flyTo = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var destination = options.destination; + if (!defined(destination)) { + throw new DeveloperError('destination is required.'); + } - if (!defined(this._batchValues)) { - return Color.clone(DEFAULT_COLOR_VALUE, result); + var mode = this._mode; + if (mode === SceneMode.MORPHING) { + return; } - var batchValues = this._batchValues; - var offset = batchId * 4; - - var showAlphaProperties = this._showAlphaProperties; - var propertyOffset = batchId * 2; - - return Color.fromBytes(batchValues[offset], - batchValues[offset + 1], - batchValues[offset + 2], - showAlphaProperties[propertyOffset + 1], - result); - }; + this.cancelFlight(); - var scratchColor = new Color(); + var orientation = defaultValue(options.orientation, defaultValue.EMPTY_OBJECT); + if (defined(orientation.direction)) { + orientation = directionUpToHeadingPitchRoll(this, destination, orientation, scratchSetViewOptions.orientation); + } - Cesium3DTileBatchTable.prototype.applyStyle = function(frameState, style) { - if (!defined(style)) { - this.setAllColor(DEFAULT_COLOR_VALUE); - this.setAllShow(true); + if (defined(options.duration) && options.duration <= 0.0) { + var setViewOptions = scratchSetViewOptions; + setViewOptions.destination = options.destination; + setViewOptions.orientation.heading = orientation.heading; + setViewOptions.orientation.pitch = orientation.pitch; + setViewOptions.orientation.roll = orientation.roll; + setViewOptions.convert = options.convert; + setViewOptions.endTransform = options.endTransform; + this.setView(setViewOptions); + if (typeof options.complete === 'function') { + options.complete(); + } return; } - var content = this._content; - var length = this.featuresLength; - for (var i = 0; i < length; ++i) { - var feature = content.getFeature(i); - var color = defined(style.color) ? style.color.evaluateColor(frameState, feature, scratchColor) : DEFAULT_COLOR_VALUE; - var show = defined(style.show) ? style.show.evaluate(frameState, feature) : DEFAULT_SHOW_VALUE; - this.setColor(i, color); - this.setShow(i, show); + var isRectangle = defined(destination.west); + if (isRectangle) { + destination = this.getRectangleCameraCoordinates(destination, scratchFlyToDestination); } + + var that = this; + var flightTween; + + newOptions.destination = destination; + newOptions.heading = orientation.heading; + newOptions.pitch = orientation.pitch; + newOptions.roll = orientation.roll; + newOptions.duration = options.duration; + newOptions.complete = function () { + if(flightTween === that._currentFlight){ + that._currentFlight = undefined; + } + if (defined(options.complete)) { + options.complete(); + } + }; + newOptions.cancel = options.cancel; + newOptions.endTransform = options.endTransform; + newOptions.convert = isRectangle ? false : options.convert; + newOptions.maximumHeight = options.maximumHeight; + newOptions.pitchAdjustHeight = options.pitchAdjustHeight; + newOptions.flyOverLongitude = options.flyOverLongitude; + newOptions.flyOverLongitudeWeight = options.flyOverLongitudeWeight; + newOptions.easingFunction = options.easingFunction; + + var scene = this._scene; + flightTween = scene.tweens.add(CameraFlightPath.createTween(scene, newOptions)); + this._currentFlight = flightTween; }; - function getBinaryProperty(binaryProperty, index) { - var typedArray = binaryProperty.typedArray; - var componentCount = binaryProperty.componentCount; - if (componentCount === 1) { - return typedArray[index]; - } - return binaryProperty.type.unpack(typedArray, index * componentCount); + function distanceToBoundingSphere3D(camera, radius) { + var frustum = camera.frustum; + var tanPhi = Math.tan(frustum.fovy * 0.5); + var tanTheta = frustum.aspectRatio * tanPhi; + return Math.max(radius / tanTheta, radius / tanPhi); } - function setBinaryProperty(binaryProperty, index, value) { - var typedArray = binaryProperty.typedArray; - var componentCount = binaryProperty.componentCount; - if (componentCount === 1) { - typedArray[index] = value; + function distanceToBoundingSphere2D(camera, radius) { + var frustum = camera.frustum; + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } + + var right, top; + var ratio = frustum.right / frustum.top; + var heightRatio = radius * ratio; + if (radius > heightRatio) { + right = radius; + top = right / ratio; } else { - binaryProperty.type.pack(value, typedArray, index * componentCount); + top = radius; + right = heightRatio; } - } - // The size of this array equals the maximum instance count among all loaded tiles, which has the potential to be large. - var scratchVisited = []; - var scratchStack = []; - var marker = 0; - function traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback) { - var classIds = hierarchy.classIds; - var parentCounts = hierarchy.parentCounts; - var parentIds = hierarchy.parentIds; - var parentIndexes = hierarchy.parentIndexes; - var instancesLength = classIds.length; + return Math.max(right, top) * 1.50; + } - // Ignore instances that have already been visited. This occurs in diamond inheritance situations. - // Use a marker value to indicate that an instance has been visited, which increments with each run. - // This is more efficient than clearing the visited array every time. - var visited = scratchVisited; - visited.length = Math.max(visited.length, instancesLength); - var visitedMarker = ++marker; + var MINIMUM_ZOOM = 100.0; - var stack = scratchStack; - stack.length = 0; - stack.push(instanceIndex); + function adjustBoundingSphereOffset(camera, boundingSphere, offset) { + if (!defined(offset)) { + offset = HeadingPitchRange.clone(Camera.DEFAULT_OFFSET); + } - while (stack.length > 0) { - instanceIndex = stack.pop(); - if (visited[instanceIndex] === visitedMarker) { - // This instance has already been visited, stop traversal - continue; - } - visited[instanceIndex] = visitedMarker; - var result = endConditionCallback(hierarchy, instanceIndex); - if (defined(result)) { - // The end condition was met, stop the traversal and return the result - return result; - } - var parentCount = parentCounts[instanceIndex]; - var parentIndex = parentIndexes[instanceIndex]; - for (var i = 0; i < parentCount; ++i) { - var parentId = parentIds[parentIndex + i]; - // Stop the traversal when the instance has no parent (its parentId equals itself) - // else add the parent to the stack to continue the traversal. - if (parentId !== instanceIndex) { - stack.push(parentId); - } + var minimumZoom = camera._scene.screenSpaceCameraController.minimumZoomDistance; + var maximumZoom = camera._scene.screenSpaceCameraController.maximumZoomDistance; + var range = offset.range; + if (!defined(range) || range === 0.0) { + var radius = boundingSphere.radius; + if (radius === 0.0) { + offset.range = MINIMUM_ZOOM; + } else if (camera.frustum instanceof OrthographicFrustum || camera._mode === SceneMode.SCENE2D) { + offset.range = distanceToBoundingSphere2D(camera, radius); + } else { + offset.range = distanceToBoundingSphere3D(camera, radius); } + offset.range = CesiumMath.clamp(offset.range, minimumZoom, maximumZoom); } + + return offset; } - function traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback) { - var hasParent = true; - while (hasParent) { - var result = endConditionCallback(hierarchy, instanceIndex); - if (defined(result)) { - // The end condition was met, stop the traversal and return the result - return result; - } - var parentId = hierarchy.parentIds[instanceIndex]; - hasParent = parentId !== instanceIndex; - instanceIndex = parentId; + /** + * Sets the camera so that the current view contains the provided bounding sphere. + * + * <p>The offset is heading/pitch/range in the local east-north-up reference frame centered at the center of the bounding sphere. + * The heading and the pitch angles are defined in the local east-north-up reference frame. + * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch + * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. If the range is + * zero, a range will be computed such that the whole bounding sphere is visible.</p> + * + * <p>In 2D, there must be a top down view. The camera will be placed above the target looking down. The height above the + * target will be the range. The heading will be determined from the offset. If the heading cannot be + * determined from the offset, the heading will be north.</p> + * + * @param {BoundingSphere} boundingSphere The bounding sphere to view, in world coordinates. + * @param {HeadingPitchRange} [offset] The offset from the target in the local east-north-up reference frame centered at the target. + * + * @exception {DeveloperError} viewBoundingSphere is not supported while morphing. + */ + Camera.prototype.viewBoundingSphere = function(boundingSphere, offset) { + if (!defined(boundingSphere)) { + throw new DeveloperError('boundingSphere is required.'); } - } - function traverseHierarchy(hierarchy, instanceIndex, endConditionCallback) { - // Traverse over the hierarchy and process each instance with the endConditionCallback. - // When the endConditionCallback returns a value, the traversal stops and that value is returned. - var parentCounts = hierarchy.parentCounts; - var parentIds = hierarchy.parentIds; - if (!defined(parentIds)) { - return endConditionCallback(hierarchy, instanceIndex); - } else if (defined(parentCounts)) { - return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); + if (this._mode === SceneMode.MORPHING) { + throw new DeveloperError('viewBoundingSphere is not supported while morphing.'); + } + + offset = adjustBoundingSphereOffset(this, boundingSphere, offset); + this.lookAt(boundingSphere.center, offset); + }; + + var scratchflyToBoundingSphereTransform = new Matrix4(); + var scratchflyToBoundingSphereDestination = new Cartesian3(); + var scratchflyToBoundingSphereDirection = new Cartesian3(); + var scratchflyToBoundingSphereUp = new Cartesian3(); + var scratchflyToBoundingSphereRight = new Cartesian3(); + var scratchFlyToBoundingSphereCart4 = new Cartesian4(); + var scratchFlyToBoundingSphereQuaternion = new Quaternion(); + var scratchFlyToBoundingSphereMatrix3 = new Matrix3(); + + /** + * Flies the camera to a location where the current view contains the provided bounding sphere. + * + * <p> The offset is heading/pitch/range in the local east-north-up reference frame centered at the center of the bounding sphere. + * The heading and the pitch angles are defined in the local east-north-up reference frame. + * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch + * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. If the range is + * zero, a range will be computed such that the whole bounding sphere is visible.</p> + * + * <p>In 2D and Columbus View, there must be a top down view. The camera will be placed above the target looking down. The height above the + * target will be the range. The heading will be aligned to local north.</p> + * + * @param {BoundingSphere} boundingSphere The bounding sphere to view, in world coordinates. + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. + * @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target. + * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. + * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. + * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed. + * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. + * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. + * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. + * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. + * @param {EasingFunction|EasingFunction~Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight. + */ + Camera.prototype.flyToBoundingSphere = function(boundingSphere, options) { + if (!defined(boundingSphere)) { + throw new DeveloperError('boundingSphere is required.'); + } + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var scene2D = this._mode === SceneMode.SCENE2D || this._mode === SceneMode.COLUMBUS_VIEW; + this._setTransform(Matrix4.IDENTITY); + var offset = adjustBoundingSphereOffset(this, boundingSphere, options.offset); + + var position; + if (scene2D) { + position = Cartesian3.multiplyByScalar(Cartesian3.UNIT_Z, offset.range, scratchflyToBoundingSphereDestination); + } else { + position = offsetFromHeadingPitchRange(offset.heading, offset.pitch, offset.range); } - return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); - } - function hasPropertyInHierarchy(batchTable, batchId, name) { - var hierarchy = batchTable._batchTableHierarchy; - var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { - var classId = hierarchy.classIds[instanceIndex]; - var instances = hierarchy.classes[classId].instances; - if (defined(instances[name])) { - return true; - } - }); - return defined(result); - } + var transform = Transforms.eastNorthUpToFixedFrame(boundingSphere.center, Ellipsoid.WGS84, scratchflyToBoundingSphereTransform); + Matrix4.multiplyByPoint(transform, position, position); - function getPropertyNamesInHierarchy(batchTable, batchId, results) { - var hierarchy = batchTable._batchTableHierarchy; - traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { - var classId = hierarchy.classIds[instanceIndex]; - var instances = hierarchy.classes[classId].instances; - for (var name in instances) { - if (instances.hasOwnProperty(name)) { - if (results.indexOf(name) === -1) { - results.push(name); - } - } - } - }); - } + var direction; + var up; - function getHierarchyProperty(batchTable, batchId, name) { - var hierarchy = batchTable._batchTableHierarchy; - return traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { - var classId = hierarchy.classIds[instanceIndex]; - var instanceClass = hierarchy.classes[classId]; - var indexInClass = hierarchy.classIndexes[instanceIndex]; - var propertyValues = instanceClass.instances[name]; - if (defined(propertyValues)) { - if (defined(propertyValues.typedArray)) { - return getBinaryProperty(propertyValues, indexInClass); - } - return clone(propertyValues[indexInClass], true); - } - }); - } + if (!scene2D) { + direction = Cartesian3.subtract(boundingSphere.center, position, scratchflyToBoundingSphereDirection); + Cartesian3.normalize(direction, direction); - function setHierarchyProperty(batchTable, batchId, name, value) { - var hierarchy = batchTable._batchTableHierarchy; - var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { - var classId = hierarchy.classIds[instanceIndex]; - var instanceClass = hierarchy.classes[classId]; - var indexInClass = hierarchy.classIndexes[instanceIndex]; - var propertyValues = instanceClass.instances[name]; - if (defined(propertyValues)) { - if (instanceIndex !== batchId) { - throw new DeveloperError('Inherited property "' + name + '" is read-only.'); - } - if (defined(propertyValues.typedArray)) { - setBinaryProperty(propertyValues, indexInClass, value); - } else { - propertyValues[indexInClass] = clone(value, true); - } - return true; + up = Matrix4.multiplyByPointAsVector(transform, Cartesian3.UNIT_Z, scratchflyToBoundingSphereUp); + if (1.0 - Math.abs(Cartesian3.dot(direction, up)) < CesiumMath.EPSILON6) { + var rotateQuat = Quaternion.fromAxisAngle(direction, offset.heading, scratchFlyToBoundingSphereQuaternion); + var rotation = Matrix3.fromQuaternion(rotateQuat, scratchFlyToBoundingSphereMatrix3); + + Cartesian3.fromCartesian4(Matrix4.getColumn(transform, 1, scratchFlyToBoundingSphereCart4), up); + Matrix3.multiplyByVector(rotation, up, up); } - }); - return defined(result); - } - Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { - checkBatchId(batchId, this.featuresLength); - Check.typeOf.string('className', className); - - // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if this area becomes a hotspot - var hierarchy = this._batchTableHierarchy; - if (!defined(hierarchy)) { - return false; + var right = Cartesian3.cross(direction, up, scratchflyToBoundingSphereRight); + Cartesian3.cross(right, direction, up); + Cartesian3.normalize(up, up); } - // PERFORMANCE_IDEA : treat class names as integers for faster comparisons - var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { - var classId = hierarchy.classIds[instanceIndex]; - var instanceClass = hierarchy.classes[classId]; - if (instanceClass.name === className) { - return true; - } + this.flyTo({ + destination : position, + orientation : { + direction : direction, + up : up + }, + duration : options.duration, + complete : options.complete, + cancel : options.cancel, + endTransform : options.endTransform, + maximumHeight : options.maximumHeight, + easingFunction : options.easingFunction, + flyOverLongitude : options.flyOverLongitude, + flyOverLongitudeWeight : options.flyOverLongitudeWeight, + pitchAdjustHeight : options.pitchAdjustHeight }); - return defined(result); }; - Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { - Check.typeOf.string('className', className); - - return (this.getExactClassName(batchId) === className); - }; + var scratchCartesian3_1 = new Cartesian3(); + var scratchCartesian3_2 = new Cartesian3(); + var scratchCartesian3_3 = new Cartesian3(); + var scratchCartesian3_4 = new Cartesian3(); + var horizonPoints = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; - Cesium3DTileBatchTable.prototype.getExactClassName = function(batchId) { - checkBatchId(batchId, this.featuresLength); - - var hierarchy = this._batchTableHierarchy; - if (!defined(hierarchy)) { - return undefined; - } - var classId = hierarchy.classIds[batchId]; - var instanceClass = hierarchy.classes[classId]; - return instanceClass.name; - }; + function computeHorizonQuad(camera, ellipsoid) { + var radii = ellipsoid.radii; + var p = camera.positionWC; - Cesium3DTileBatchTable.prototype.hasProperty = function(batchId, name) { - checkBatchId(batchId, this.featuresLength); - Check.typeOf.string('name', name); - - var json = this.batchTableJson; - return (defined(json) && defined(json[name])) || (defined(this._batchTableHierarchy) && hasPropertyInHierarchy(this, batchId, name)); - }; + // Find the corresponding position in the scaled space of the ellipsoid. + var q = Cartesian3.multiplyComponents(ellipsoid.oneOverRadii, p, scratchCartesian3_1); - Cesium3DTileBatchTable.prototype.getPropertyNames = function(batchId, results) { - checkBatchId(batchId, this.featuresLength); - - results = defined(results) ? results : []; - results.length = 0; + var qMagnitude = Cartesian3.magnitude(q); + var qUnit = Cartesian3.normalize(q, scratchCartesian3_2); - var json = this.batchTableJson; - for (var name in json) { - if (json.hasOwnProperty(name)) { - results.push(name); - } + // Determine the east and north directions at q. + var eUnit; + var nUnit; + if (Cartesian3.equalsEpsilon(qUnit, Cartesian3.UNIT_Z, CesiumMath.EPSILON10)) { + eUnit = new Cartesian3(0, 1, 0); + nUnit = new Cartesian3(0, 0, 1); + } else { + eUnit = Cartesian3.normalize(Cartesian3.cross(Cartesian3.UNIT_Z, qUnit, scratchCartesian3_3), scratchCartesian3_3); + nUnit = Cartesian3.normalize(Cartesian3.cross(qUnit, eUnit, scratchCartesian3_4), scratchCartesian3_4); } - if (defined(this._batchTableHierarchy)) { - getPropertyNamesInHierarchy(this, batchId, results); - } + // Determine the radius of the 'limb' of the ellipsoid. + var wMagnitude = Math.sqrt(Cartesian3.magnitudeSquared(q) - 1.0); - return results; - }; + // Compute the center and offsets. + var center = Cartesian3.multiplyByScalar(qUnit, 1.0 / qMagnitude, scratchCartesian3_1); + var scalar = wMagnitude / qMagnitude; + var eastOffset = Cartesian3.multiplyByScalar(eUnit, scalar, scratchCartesian3_2); + var northOffset = Cartesian3.multiplyByScalar(nUnit, scalar, scratchCartesian3_3); - Cesium3DTileBatchTable.prototype.getProperty = function(batchId, name) { - checkBatchId(batchId, this.featuresLength); - Check.typeOf.string('name', name); - - if (!defined(this.batchTableJson)) { + // A conservative measure for the longitudes would be to use the min/max longitudes of the bounding frustum. + var upperLeft = Cartesian3.add(center, northOffset, horizonPoints[0]); + Cartesian3.subtract(upperLeft, eastOffset, upperLeft); + Cartesian3.multiplyComponents(radii, upperLeft, upperLeft); + + var lowerLeft = Cartesian3.subtract(center, northOffset, horizonPoints[1]); + Cartesian3.subtract(lowerLeft, eastOffset, lowerLeft); + Cartesian3.multiplyComponents(radii, lowerLeft, lowerLeft); + + var lowerRight = Cartesian3.subtract(center, northOffset, horizonPoints[2]); + Cartesian3.add(lowerRight, eastOffset, lowerRight); + Cartesian3.multiplyComponents(radii, lowerRight, lowerRight); + + var upperRight = Cartesian3.add(center, northOffset, horizonPoints[3]); + Cartesian3.add(upperRight, eastOffset, upperRight); + Cartesian3.multiplyComponents(radii, upperRight, upperRight); + + return horizonPoints; + } + + var scratchPickCartesian2 = new Cartesian2(); + var scratchRectCartesian = new Cartesian3(); + var cartoArray = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; + function addToResult(x, y, index, camera, ellipsoid, computedHorizonQuad) { + scratchPickCartesian2.x = x; + scratchPickCartesian2.y = y; + var r = camera.pickEllipsoid(scratchPickCartesian2, ellipsoid, scratchRectCartesian); + if (defined(r)) { + cartoArray[index] = ellipsoid.cartesianToCartographic(r, cartoArray[index]); + return 1; + } + cartoArray[index] = ellipsoid.cartesianToCartographic(computedHorizonQuad[index], cartoArray[index]); + return 0; + } + /** + * Computes the approximate visible rectangle on the ellipsoid. + * + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that you want to know the visible region. + * @param {Rectangle} [result] The rectangle in which to store the result + * + * @returns {Rectangle|undefined} The visible rectangle or undefined if the ellipsoid isn't visible at all. + */ + Camera.prototype.computeViewRectangle = function(ellipsoid, result) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + var cullingVolume = this.frustum.computeCullingVolume(this.positionWC, this.directionWC, this.upWC); + var boundingSphere = new BoundingSphere(Cartesian3.ZERO, ellipsoid.maximumRadius); + var visibility = cullingVolume.computeVisibility(boundingSphere); + if (visibility === Intersect.OUTSIDE) { return undefined; } - if (defined(this._batchTableBinaryProperties)) { - var binaryProperty = this._batchTableBinaryProperties[name]; - if (defined(binaryProperty)) { - return getBinaryProperty(binaryProperty, batchId); - } - } + var canvas = this._scene.canvas; + var width = canvas.clientWidth; + var height = canvas.clientHeight; - var propertyValues = this.batchTableJson[name]; - if (defined(propertyValues)) { - return clone(propertyValues[batchId], true); - } + var successfulPickCount = 0; - if (defined(this._batchTableHierarchy)) { - var hierarchyProperty = getHierarchyProperty(this, batchId, name); - if (defined(hierarchyProperty)) { - return hierarchyProperty; - } - } + var computedHorizonQuad = computeHorizonQuad(this, ellipsoid); - return undefined; - }; + successfulPickCount += addToResult(0, 0, 0, this, ellipsoid, computedHorizonQuad); + successfulPickCount += addToResult(0, height, 1, this, ellipsoid, computedHorizonQuad); + successfulPickCount += addToResult(width, height, 2, this, ellipsoid, computedHorizonQuad); + successfulPickCount += addToResult(width, 0, 3, this, ellipsoid, computedHorizonQuad); - Cesium3DTileBatchTable.prototype.setProperty = function(batchId, name, value) { - var featuresLength = this.featuresLength; - checkBatchId(batchId, featuresLength); - Check.typeOf.string('name', name); - - if (defined(this._batchTableBinaryProperties)) { - var binaryProperty = this._batchTableBinaryProperties[name]; - if (defined(binaryProperty)) { - setBinaryProperty(binaryProperty, batchId, value); - return; - } + if (successfulPickCount < 2) { + // If we have space non-globe in 3 or 4 corners then return the whole globe + return Rectangle.MAX_VALUE; } - if (defined(this._batchTableHierarchy)) { - if (setHierarchyProperty(this, batchId, name, value)) { - return; + result = Rectangle.fromCartographicArray(cartoArray, result); + + // Detect if we go over the poles + var distance = 0; + var lastLon = cartoArray[3].longitude; + for (var i = 0; i < 4; ++i) { + var lon = cartoArray[i].longitude; + var diff = Math.abs(lon - lastLon); + if (diff > CesiumMath.PI) { + // Crossed the dateline + distance += CesiumMath.TWO_PI - diff; + } else { + distance += diff; } + + lastLon = lon; } - if (!defined(this.batchTableJson)) { - // Tile payload did not have a batch table. Create one for new user-defined properties. - this.batchTableJson = {}; + // We are over one of the poles so adjust the rectangle accordingly + if (CesiumMath.equalsEpsilon(Math.abs(distance), CesiumMath.TWO_PI, CesiumMath.EPSILON9)) { + result.west = -CesiumMath.PI; + result.east = CesiumMath.PI; + if (cartoArray[0].latitude >= 0.0) { + result.north = CesiumMath.PI_OVER_TWO; + } else { + result.south = -CesiumMath.PI_OVER_TWO; + } } - var propertyValues = this.batchTableJson[name]; + return result; + }; - if (!defined(propertyValues)) { - // Property does not exist. Create it. - this.batchTableJson[name] = new Array(featuresLength); - propertyValues = this.batchTableJson[name]; + /** + * Switches the frustum/projection to perspective. + * + * This function is a no-op in 2D which must always be orthographic. + */ + Camera.prototype.switchToPerspectiveFrustum = function() { + if (this._mode === SceneMode.SCENE2D || this.frustum instanceof PerspectiveFrustum) { + return; } - propertyValues[batchId] = clone(value, true); + var scene = this._scene; + this.frustum = new PerspectiveFrustum(); + this.frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + this.frustum.fov = CesiumMath.toRadians(60.0); }; - function getGlslComputeSt(batchTable) { - // GLSL batchId is zero-based: [0, featuresLength - 1] - if (batchTable._textureDimensions.y === 1) { - return 'uniform vec4 tile_textureStep; \n' + - 'vec2 computeSt(float batchId) \n' + - '{ \n' + - ' float stepX = tile_textureStep.x; \n' + - ' float centerX = tile_textureStep.y; \n' + - ' return vec2(centerX + (batchId * stepX), 0.5); \n' + - '} \n'; + /** + * Switches the frustum/projection to orthographic. + * + * This function is a no-op in 2D which will always be orthographic. + */ + Camera.prototype.switchToOrthographicFrustum = function() { + if (this._mode === SceneMode.SCENE2D || this.frustum instanceof OrthographicFrustum) { + return; } - return 'uniform vec4 tile_textureStep; \n' + - 'uniform vec2 tile_textureDimensions; \n' + - 'vec2 computeSt(float batchId) \n' + - '{ \n' + - ' float stepX = tile_textureStep.x; \n' + - ' float centerX = tile_textureStep.y; \n' + - ' float stepY = tile_textureStep.z; \n' + - ' float centerY = tile_textureStep.w; \n' + - ' float xId = mod(batchId, tile_textureDimensions.x); \n' + - ' float yId = floor(batchId / tile_textureDimensions.x); \n' + - ' return vec2(centerX + (xId * stepX), 1.0 - (centerY + (yId * stepY))); \n' + - '} \n'; - } + var scene = this._scene; + this.frustum = new OrthographicFrustum(); + this.frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - Cesium3DTileBatchTable.prototype.getVertexShaderCallback = function(handleTranslucent, batchIdAttributeName) { - if (this.featuresLength === 0) { - return; + // It doesn't matter what we set this to. The adjust below will correct the width based on the camera position. + this.frustum.width = Cartesian3.magnitude(this.position); + + // Check the projection matrix. It will always be defined, but we need to force an off-center update. + var projectionMatrix = this.frustum.projectionMatrix; + if (defined(projectionMatrix)) { + this._adjustOrthographicFrustum(true); } + }; - var that = this; - return function(source) { - var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); - var newMain; + /** + * @private + */ + Camera.clone = function(camera, result) { + if (!defined(result)) { + result = new Camera(camera._scene); + } - if (ContextLimits.maximumVertexTextureImageUnits > 0) { - // When VTF is supported, perform per-feature show/hide in the vertex shader - newMain = ''; - if (handleTranslucent) { - newMain += 'uniform bool tile_translucentCommand; \n'; - } - newMain += - 'uniform sampler2D tile_batchTexture; \n' + - 'varying vec4 tile_featureColor; \n' + - 'void main() \n' + - '{ \n' + - ' tile_main(); \n' + - ' vec2 st = computeSt(' + batchIdAttributeName + '); \n' + - ' vec4 featureProperties = texture2D(tile_batchTexture, st); \n' + - ' float show = ceil(featureProperties.a); \n' + // 0 - false, non-zeo - true - ' gl_Position *= show; \n'; // Per-feature show/hide - if (handleTranslucent) { - newMain += - ' bool isStyleTranslucent = (featureProperties.a != 1.0); \n' + - ' if (czm_pass == czm_passTranslucent) \n' + - ' { \n' + - ' if (!isStyleTranslucent && !tile_translucentCommand) \n' + // Do not render opaque features in the translucent pass - ' { \n' + - ' gl_Position *= 0.0; \n' + - ' } \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' if (isStyleTranslucent) \n' + // Do not render translucent features in the opaque pass - ' { \n' + - ' gl_Position *= 0.0; \n' + - ' } \n' + - ' } \n'; - } - newMain += - ' tile_featureColor = featureProperties; \n' + - '}'; - } else { - newMain = - 'varying vec2 tile_featureSt; \n' + - 'void main() \n' + - '{ \n' + - ' tile_main(); \n' + - ' tile_featureSt = computeSt(' + batchIdAttributeName + '); \n' + - '}'; - } + Cartesian3.clone(camera.position, result.position); + Cartesian3.clone(camera.direction, result.direction); + Cartesian3.clone(camera.up, result.up); + Cartesian3.clone(camera.right, result.right); + Matrix4.clone(camera._transform, result.transform); + result._transformChanged = true; - return renamedSource + '\n' + getGlslComputeSt(that) + newMain; - }; + return result; }; - function getHighlightOnlyShader(source) { - source = ShaderSource.replaceMain(source, 'tile_main'); - return source + - 'void tile_color(vec4 tile_featureColor) \n' + - '{ \n' + - ' tile_main(); \n' + - ' gl_FragColor *= tile_featureColor; \n' + - '} \n'; - } + /** + * A function that will execute when a flight completes. + * @callback Camera~FlightCompleteCallback + */ - function modifyDiffuse(source, diffuseUniformName) { - // If the glTF does not specify the _3DTILESDIFFUSE semantic, return a basic highlight shader. - // Otherwise if _3DTILESDIFFUSE is defined prefer the shader below that can switch the color mode at runtime. - if (!defined(diffuseUniformName)) { - return getHighlightOnlyShader(source); - } + /** + * A function that will execute when a flight is cancelled. + * @callback Camera~FlightCancelledCallback + */ - // Find the diffuse uniform. Examples matches: - // uniform vec3 u_diffuseColor; - // uniform sampler2D diffuseTexture; - var regex = new RegExp('uniform\\s+(vec[34]|sampler2D)\\s+' + diffuseUniformName + ';'); - var uniformMatch = source.match(regex); + return Camera; +}); - if (!defined(uniformMatch)) { - // Could not find uniform declaration of type vec3, vec4, or sampler2D - return getHighlightOnlyShader(source); - } +define('Scene/CameraEventType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - var declaration = uniformMatch[0]; - var type = uniformMatch[1]; + /** + * Enumerates the available input for interacting with the camera. + * + * @exports CameraEventType + */ + var CameraEventType = { + /** + * A left mouse button press followed by moving the mouse and releasing the button. + * + * @type {Number} + * @constant + */ + LEFT_DRAG : 0, - source = ShaderSource.replaceMain(source, 'tile_main'); - source = source.replace(declaration, ''); // Remove uniform declaration for now so the replace below doesn't affect it + /** + * A right mouse button press followed by moving the mouse and releasing the button. + * + * @type {Number} + * @constant + */ + RIGHT_DRAG : 1, - // If the tile color is white, use the source color. This implies the feature has not been styled. - // Highlight: tile_colorBlend is 0.0 and the source color is used - // Replace: tile_colorBlend is 1.0 and the tile color is used - // Mix: tile_colorBlend is between 0.0 and 1.0, causing the source color and tile color to mix - var finalDiffuseFunction = - 'vec4 tile_diffuse_final(vec4 sourceDiffuse, vec4 tileDiffuse) \n' + - '{ \n' + - ' vec4 blendDiffuse = mix(sourceDiffuse, tileDiffuse, tile_colorBlend); \n' + - ' vec4 diffuse = (tileDiffuse.rgb == vec3(1.0)) ? sourceDiffuse : blendDiffuse; \n' + - ' return vec4(diffuse.rgb, sourceDiffuse.a); \n' + - '} \n'; + /** + * A middle mouse button press followed by moving the mouse and releasing the button. + * + * @type {Number} + * @constant + */ + MIDDLE_DRAG : 2, - // The color blend mode is intended for the RGB channels so alpha is always just multiplied. - // gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) - var applyHighlight = - ' gl_FragColor.a *= tile_featureColor.a; \n' + - ' float highlight = ceil(tile_colorBlend); \n' + - ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n'; + /** + * Scrolling the middle mouse button. + * + * @type {Number} + * @constant + */ + WHEEL : 3, - var setColor; - if (type === 'vec3' || type === 'vec4') { - var sourceDiffuse = (type === 'vec3') ? ('vec4(' + diffuseUniformName + ', 1.0)') : diffuseUniformName; - var replaceDiffuse = (type === 'vec3') ? 'tile_diffuse.xyz' : 'tile_diffuse'; - regex = new RegExp(diffuseUniformName, 'g'); - source = source.replace(regex, replaceDiffuse); - setColor = - ' vec4 source = ' + sourceDiffuse + '; \n' + - ' tile_diffuse = tile_diffuse_final(source, tile_featureColor); \n' + - ' tile_main(); \n'; - } else if (type === 'sampler2D') { - regex = new RegExp('texture2D\\(' + diffuseUniformName + '.*?\\)', 'g'); - source = source.replace(regex, 'tile_diffuse_final($&, tile_diffuse)'); - setColor = - ' tile_diffuse = tile_featureColor; \n' + - ' tile_main(); \n'; - } + /** + * A two-finger touch on a touch surface. + * + * @type {Number} + * @constant + */ + PINCH : 4 + }; - source = - 'uniform float tile_colorBlend; \n' + - 'vec4 tile_diffuse = vec4(1.0); \n' + - finalDiffuseFunction + - declaration + '\n' + - source + '\n' + - 'void tile_color(vec4 tile_featureColor) \n' + - '{ \n' + - setColor + - applyHighlight + - '} \n'; + return freezeObject(CameraEventType); +}); - return source; - } +define('Scene/CameraEventAggregator',[ + '../Core/Cartesian2', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/KeyboardEventModifier', + '../Core/Math', + '../Core/ScreenSpaceEventHandler', + '../Core/ScreenSpaceEventType', + './CameraEventType' + ], function( + Cartesian2, + defined, + defineProperties, + destroyObject, + DeveloperError, + KeyboardEventModifier, + CesiumMath, + ScreenSpaceEventHandler, + ScreenSpaceEventType, + CameraEventType) { + 'use strict'; - Cesium3DTileBatchTable.prototype.getFragmentShaderCallback = function(handleTranslucent, diffuseUniformName) { - if (this.featuresLength === 0) { - return; + function getKey(type, modifier) { + var key = type; + if (defined(modifier)) { + key += '+' + modifier; } - return function(source) { - source = modifyDiffuse(source, diffuseUniformName); - if (ContextLimits.maximumVertexTextureImageUnits > 0) { - // When VTF is supported, per-feature show/hide already happened in the fragment shader - source += - 'varying vec4 tile_featureColor; \n' + - 'void main() \n' + - '{ \n' + - ' tile_color(tile_featureColor); \n' + - '}'; - } else { - if (handleTranslucent) { - source += 'uniform bool tile_translucentCommand; \n'; - } - source += - 'uniform sampler2D tile_batchTexture; \n' + - 'varying vec2 tile_featureSt; \n' + - 'void main() \n' + - '{ \n' + - ' vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n' + - ' if (featureProperties.a == 0.0) { \n' + // show: alpha == 0 - false, non-zeo - true - ' discard; \n' + - ' } \n'; + return key; + } - if (handleTranslucent) { - source += - ' bool isStyleTranslucent = (featureProperties.a != 1.0); \n' + - ' if (czm_pass == czm_passTranslucent) \n' + - ' { \n' + - ' if (!isStyleTranslucent && !tile_translucentCommand) \n' + // Do not render opaque features in the translucent pass - ' { \n' + - ' discard; \n' + - ' } \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' if (isStyleTranslucent) \n' + // Do not render translucent features in the opaque pass - ' { \n' + - ' discard; \n' + - ' } \n' + - ' } \n'; - } + function clonePinchMovement(pinchMovement, result) { + Cartesian2.clone(pinchMovement.distance.startPosition, result.distance.startPosition); + Cartesian2.clone(pinchMovement.distance.endPosition, result.distance.endPosition); - source += - ' tile_color(featureProperties); \n' + - '} \n'; - } - return source; - }; - }; + Cartesian2.clone(pinchMovement.angleAndHeight.startPosition, result.angleAndHeight.startPosition); + Cartesian2.clone(pinchMovement.angleAndHeight.endPosition, result.angleAndHeight.endPosition); + } - function getColorBlend(batchTable) { - var tileset = batchTable._content._tileset; - var colorBlendMode = tileset.colorBlendMode; - var colorBlendAmount = tileset.colorBlendAmount; - if (colorBlendMode === Cesium3DTileColorBlendMode.HIGHLIGHT) { - return 0.0; - } - if (colorBlendMode === Cesium3DTileColorBlendMode.REPLACE) { - return 1.0; - } - if (colorBlendMode === Cesium3DTileColorBlendMode.MIX) { - // The value 0.0 is reserved for highlight, so clamp to just above 0.0. - return CesiumMath.clamp(colorBlendAmount, CesiumMath.EPSILON4, 1.0); - } - throw new DeveloperError('Invalid color blend mode "' + colorBlendMode + '".'); - } + function listenToPinch(aggregator, modifier, canvas) { + var key = getKey(CameraEventType.PINCH, modifier); - Cesium3DTileBatchTable.prototype.getUniformMapCallback = function() { - if (this.featuresLength === 0) { - return; - } + var update = aggregator._update; + var isDown = aggregator._isDown; + var eventStartPosition = aggregator._eventStartPosition; + var pressTime = aggregator._pressTime; + var releaseTime = aggregator._releaseTime; - var that = this; - return function(uniformMap) { - var batchUniformMap = { - tile_batchTexture : function() { - // PERFORMANCE_IDEA: we could also use a custom shader that avoids the texture read. - return defaultValue(that._batchTexture, that._defaultTexture); - }, - tile_textureDimensions : function() { - return that._textureDimensions; - }, - tile_textureStep : function() { - return that._textureStep; - }, - tile_colorBlend : function() { - return getColorBlend(that); - } - }; + update[key] = true; + isDown[key] = false; + eventStartPosition[key] = new Cartesian2(); - return combine(uniformMap, batchUniformMap); + var movement = aggregator._movement[key]; + if (!defined(movement)) { + movement = aggregator._movement[key] = {}; + } + + movement.distance = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() }; - }; + movement.angleAndHeight = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() + }; + movement.prevAngle = 0.0; - Cesium3DTileBatchTable.prototype.getPickVertexShaderCallback = function(batchIdAttributeName) { - if (this.featuresLength === 0) { - return; - } + aggregator._eventHandler.setInputAction(function(event) { + aggregator._buttonsDown++; + isDown[key] = true; + pressTime[key] = new Date(); + // Compute center position and store as start point. + Cartesian2.lerp(event.position1, event.position2, 0.5, eventStartPosition[key]); + }, ScreenSpaceEventType.PINCH_START, modifier); - var that = this; - return function(source) { - var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); - var newMain; + aggregator._eventHandler.setInputAction(function() { + aggregator._buttonsDown = Math.max(aggregator._buttonsDown - 1, 0); + isDown[key] = false; + releaseTime[key] = new Date(); + }, ScreenSpaceEventType.PINCH_END, modifier); - if (ContextLimits.maximumVertexTextureImageUnits > 0) { - // When VTF is supported, perform per-feature show/hide in the vertex shader - newMain = - 'uniform sampler2D tile_batchTexture; \n' + - 'varying vec2 tile_featureSt; \n' + - 'void main() \n' + - '{ \n' + - ' tile_main(); \n' + - ' vec2 st = computeSt(' + batchIdAttributeName + '); \n' + - ' vec4 featureProperties = texture2D(tile_batchTexture, st); \n' + - ' float show = ceil(featureProperties.a); \n' + // 0 - false, non-zero - true - ' gl_Position *= show; \n' + // Per-feature show/hide - ' tile_featureSt = st; \n' + - '}'; - } else { - newMain = - 'varying vec2 tile_featureSt; \n' + - 'void main() \n' + - '{ \n' + - ' tile_main(); \n' + - ' tile_featureSt = computeSt(' + batchIdAttributeName + '); \n' + - '}'; + aggregator._eventHandler.setInputAction(function(mouseMovement) { + if (isDown[key]) { + // Aggregate several input events into a single animation frame. + if (!update[key]) { + Cartesian2.clone(mouseMovement.distance.endPosition, movement.distance.endPosition); + Cartesian2.clone(mouseMovement.angleAndHeight.endPosition, movement.angleAndHeight.endPosition); + } else { + clonePinchMovement(mouseMovement, movement); + update[key] = false; + movement.prevAngle = movement.angleAndHeight.startPosition.x; + } + // Make sure our aggregation of angles does not "flip" over 360 degrees. + var angle = movement.angleAndHeight.endPosition.x; + var prevAngle = movement.prevAngle; + var TwoPI = Math.PI * 2; + while (angle >= (prevAngle + Math.PI)) { + angle -= TwoPI; + } + while (angle < (prevAngle - Math.PI)) { + angle += TwoPI; + } + movement.angleAndHeight.endPosition.x = -angle * canvas.clientWidth / 12; + movement.angleAndHeight.startPosition.x = -prevAngle * canvas.clientWidth / 12; } + }, ScreenSpaceEventType.PINCH_MOVE, modifier); + } - return renamedSource + '\n' + getGlslComputeSt(that) + newMain; - }; - }; + function listenToWheel(aggregator, modifier) { + var key = getKey(CameraEventType.WHEEL, modifier); - Cesium3DTileBatchTable.prototype.getPickFragmentShaderCallback = function() { - if (this.featuresLength === 0) { - return; + var update = aggregator._update; + update[key] = true; + + var movement = aggregator._movement[key]; + if (!defined(movement)) { + movement = aggregator._movement[key] = {}; } - return function(source) { - var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); - var newMain; + movement.startPosition = new Cartesian2(); + movement.endPosition = new Cartesian2(); - // Pick shaders do not need to take into account per-feature color/alpha. - // (except when alpha is zero, which is treated as if show is false, so - // it does not write depth in the color or pick pass). - if (ContextLimits.maximumVertexTextureImageUnits > 0) { - // When VTF is supported, per-feature show/hide already happened in the fragment shader - newMain = - 'uniform sampler2D tile_pickTexture; \n' + - 'varying vec2 tile_featureSt; \n' + - 'void main() \n' + - '{ \n' + - ' tile_main(); \n' + - ' if (gl_FragColor.a == 0.0) { \n' + // per-feature show: alpha == 0 - false, non-zeo - true - ' discard; \n' + - ' } \n' + - ' gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n' + - '}'; + aggregator._eventHandler.setInputAction(function(delta) { + // TODO: magic numbers + var arcLength = 15.0 * CesiumMath.toRadians(delta); + if (!update[key]) { + movement.endPosition.y = movement.endPosition.y + arcLength; } else { - newMain = - 'uniform sampler2D tile_pickTexture; \n' + - 'uniform sampler2D tile_batchTexture; \n' + - 'varying vec2 tile_featureSt; \n' + - 'void main() \n' + - '{ \n' + - ' vec4 featureProperties = texture2D(tile_batchTexture, tile_featureSt); \n' + - ' if (featureProperties.a == 0.0) { \n' + // per-feature show: alpha == 0 - false, non-zeo - true - ' discard; \n' + - ' } \n' + - ' tile_main(); \n' + - ' if (gl_FragColor.a == 0.0) { \n' + - ' discard; \n' + - ' } \n' + - ' gl_FragColor = texture2D(tile_pickTexture, tile_featureSt); \n' + - '}'; + Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); + movement.endPosition.x = 0.0; + movement.endPosition.y = arcLength; + update[key] = false; } + }, ScreenSpaceEventType.WHEEL, modifier); + } - return renamedSource + '\n' + newMain; - }; - }; + function listenMouseButtonDownUp(aggregator, modifier, type) { + var key = getKey(type, modifier); - Cesium3DTileBatchTable.prototype.getPickUniformMapCallback = function() { - if (this.featuresLength === 0) { - return; - } + var isDown = aggregator._isDown; + var eventStartPosition = aggregator._eventStartPosition; + var pressTime = aggregator._pressTime; + var releaseTime = aggregator._releaseTime; - var that = this; - return function(uniformMap) { - var batchUniformMap = { - tile_batchTexture : function() { - return defaultValue(that._batchTexture, that._defaultTexture); - }, - tile_textureDimensions : function() { - return that._textureDimensions; - }, - tile_textureStep : function() { - return that._textureStep; - }, - tile_pickTexture : function() { - return that._pickTexture; - } + isDown[key] = false; + eventStartPosition[key] = new Cartesian2(); + + var lastMovement = aggregator._lastMovement[key]; + if (!defined(lastMovement)) { + lastMovement = aggregator._lastMovement[key] = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2(), + valid : false }; + } - return combine(batchUniformMap, uniformMap); - }; - }; + var down; + var up; + if (type === CameraEventType.LEFT_DRAG) { + down = ScreenSpaceEventType.LEFT_DOWN; + up = ScreenSpaceEventType.LEFT_UP; + } else if (type === CameraEventType.RIGHT_DRAG) { + down = ScreenSpaceEventType.RIGHT_DOWN; + up = ScreenSpaceEventType.RIGHT_UP; + } else if (type === CameraEventType.MIDDLE_DRAG) { + down = ScreenSpaceEventType.MIDDLE_DOWN; + up = ScreenSpaceEventType.MIDDLE_UP; + } - /////////////////////////////////////////////////////////////////////////// + aggregator._eventHandler.setInputAction(function(event) { + aggregator._buttonsDown++; + lastMovement.valid = false; + isDown[key] = true; + pressTime[key] = new Date(); + Cartesian2.clone(event.position, eventStartPosition[key]); + }, down, modifier); - var StyleCommandsNeeded = { - ALL_OPAQUE : 0, - ALL_TRANSLUCENT : 1, - OPAQUE_AND_TRANSLUCENT : 2 - }; + aggregator._eventHandler.setInputAction(function() { + aggregator._buttonsDown = Math.max(aggregator._buttonsDown - 1, 0); + isDown[key] = false; + releaseTime[key] = new Date(); + }, up, modifier); + } - Cesium3DTileBatchTable.prototype.addDerivedCommands = function(frameState, commandStart, finalResolution) { - var commandList = frameState.commandList; - var commandEnd = commandList.length; - var tile = this._content._tile; - var tileset = tile._tileset; - var bivariateVisibilityTest = tileset.skipLevelOfDetail && tileset._hasMixedContent && frameState.context.stencilBuffer; - var styleCommandsNeeded = getStyleCommandsNeeded(this); + function cloneMouseMovement(mouseMovement, result) { + Cartesian2.clone(mouseMovement.startPosition, result.startPosition); + Cartesian2.clone(mouseMovement.endPosition, result.endPosition); + } - for (var i = commandStart; i < commandEnd; ++i) { - var command = commandList[i]; - var derivedCommands = command.derivedCommands.tileset; - if (!defined(derivedCommands)) { - derivedCommands = {}; - command.derivedCommands.tileset = derivedCommands; - derivedCommands.originalCommand = deriveCommand(command); - } + function listenMouseMove(aggregator, modifier) { + var update = aggregator._update; + var movement = aggregator._movement; + var lastMovement = aggregator._lastMovement; + var isDown = aggregator._isDown; - updateDerivedCommand(derivedCommands.originalCommand, command); + for ( var typeName in CameraEventType) { + if (CameraEventType.hasOwnProperty(typeName)) { + var type = CameraEventType[typeName]; + if (defined(type)) { + var key = getKey(type, modifier); + update[key] = true; - if (styleCommandsNeeded !== StyleCommandsNeeded.ALL_OPAQUE) { - if (!defined(derivedCommands.translucent)) { - derivedCommands.translucent = deriveTranslucentCommand(derivedCommands.originalCommand); - } - updateDerivedCommand(derivedCommands.translucent, command); - } + if (!defined(aggregator._lastMovement[key])) { + aggregator._lastMovement[key] = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2(), + valid : false + }; + } - if (bivariateVisibilityTest) { - if (command.pass !== Pass.TRANSLUCENT && !finalResolution) { - if (!defined(derivedCommands.zback)) { - derivedCommands.zback = deriveZBackfaceCommand(derivedCommands.originalCommand); + if (!defined(aggregator._movement[key])) { + aggregator._movement[key] = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2() + }; } - tileset._backfaceCommands.push(derivedCommands.zback); - } - if (!defined(derivedCommands.stencil) || tile._selectionDepth !== tile._lastSelectionDepth) { - derivedCommands.stencil = deriveStencilCommand(derivedCommands.originalCommand, tile._selectionDepth); - tile._lastSelectionDepth = tile._selectionDepth; } - updateDerivedCommand(derivedCommands.stencil, command); } + } - var opaqueCommand = bivariateVisibilityTest ? derivedCommands.stencil : derivedCommands.originalCommand; - var translucentCommand = derivedCommands.translucent; - - // If the command was originally opaque: - // * If the styling applied to the tile is all opaque, use the original command - // (with one additional uniform needed for the shader). - // * If the styling is all translucent, use new (cached) derived commands (front - // and back faces) with a translucent render state. - // * If the styling causes both opaque and translucent features in this tile, - // then use both sets of commands. - if (command.pass !== Pass.TRANSLUCENT) { - if (styleCommandsNeeded === StyleCommandsNeeded.ALL_OPAQUE) { - commandList[i] = opaqueCommand; - } - if (styleCommandsNeeded === StyleCommandsNeeded.ALL_TRANSLUCENT) { - commandList[i] = translucentCommand; - } - if (styleCommandsNeeded === StyleCommandsNeeded.OPAQUE_AND_TRANSLUCENT) { - // PERFORMANCE_IDEA: if the tile has multiple commands, we do not know what features are in what - // commands so this case may be overkill. - commandList[i] = opaqueCommand; - commandList.push(translucentCommand); + aggregator._eventHandler.setInputAction(function(mouseMovement) { + for ( var typeName in CameraEventType) { + if (CameraEventType.hasOwnProperty(typeName)) { + var type = CameraEventType[typeName]; + if (defined(type)) { + var key = getKey(type, modifier); + if (isDown[key]) { + if (!update[key]) { + Cartesian2.clone(mouseMovement.endPosition, movement[key].endPosition); + } else { + cloneMouseMovement(movement[key], lastMovement[key]); + lastMovement[key].valid = true; + cloneMouseMovement(mouseMovement, movement[key]); + update[key] = false; + } + } + } } - } else { - // Command was originally translucent so no need to derive new commands; - // as of now, a style can't change an originally translucent feature to - // opaque since the style's alpha is modulated, not a replacement. When - // this changes, we need to derive new opaque commands here. - commandList[i] = opaqueCommand; } - } - }; - - function updateDerivedCommand(derivedCommand, command) { - derivedCommand.castShadows = command.castShadows; - derivedCommand.receiveShadows = command.receiveShadows; - derivedCommand.primitiveType = command.primitiveType; - } - - function getStyleCommandsNeeded(batchTable) { - var translucentFeaturesLength = batchTable._translucentFeaturesLength; - - if (translucentFeaturesLength === 0) { - return StyleCommandsNeeded.ALL_OPAQUE; - } else if (translucentFeaturesLength === batchTable.featuresLength) { - return StyleCommandsNeeded.ALL_TRANSLUCENT; - } - return StyleCommandsNeeded.OPAQUE_AND_TRANSLUCENT; + Cartesian2.clone(mouseMovement.endPosition, aggregator._currentMousePosition); + }, ScreenSpaceEventType.MOUSE_MOVE, modifier); } - function deriveCommand(command) { - var derivedCommand = DrawCommand.shallowClone(command); - - // Add a uniform to indicate if the original command was translucent so - // the shader knows not to cull vertices that were originally transparent - // even though their style is opaque. - var translucentCommand = (derivedCommand.pass === Pass.TRANSLUCENT); + /** + * Aggregates input events. For example, suppose the following inputs are received between frames: + * left mouse button down, mouse move, mouse move, left mouse button up. These events will be aggregated into + * one event with a start and end position of the mouse. + * + * @alias CameraEventAggregator + * @constructor + * + * @param {Canvas} [canvas=document] The element to handle events for. + * + * @see ScreenSpaceEventHandler + */ + function CameraEventAggregator(canvas) { + if (!defined(canvas)) { + throw new DeveloperError('canvas is required.'); + } + + this._eventHandler = new ScreenSpaceEventHandler(canvas, true); - derivedCommand.uniformMap = defined(derivedCommand.uniformMap) ? derivedCommand.uniformMap : {}; - derivedCommand.uniformMap.tile_translucentCommand = function() { - return translucentCommand; - }; + this._update = {}; + this._movement = {}; + this._lastMovement = {}; + this._isDown = {}; + this._eventStartPosition = {}; + this._pressTime = {}; + this._releaseTime = {}; - return derivedCommand; - } + this._buttonsDown = 0; - function deriveTranslucentCommand(command) { - var derivedCommand = DrawCommand.shallowClone(command); - derivedCommand.pass = Pass.TRANSLUCENT; - derivedCommand.renderState = getTranslucentRenderState(command.renderState); - return derivedCommand; - } + this._currentMousePosition = new Cartesian2(); - function deriveZBackfaceCommand(command) { - // Write just backface depth of unresolved tiles so resolved stenciled tiles do not appear in front - var derivedCommand = DrawCommand.shallowClone(command); - var rs = clone(derivedCommand.renderState, true); - rs.cull.enabled = true; - rs.cull.face = CullFace.FRONT; - // Back faces do not need to write color. - rs.colorMask = { - red : false, - green : false, - blue : false, - alpha : false - }; - // Push back face depth away from the camera so it is less likely that back faces and front faces of the same tile - // intersect and overlap. This helps avoid flickering for very thin double-sided walls. - rs.polygonOffset = { - enabled : true, - factor : 5.0, - units : 5.0 - }; - derivedCommand.renderState = RenderState.fromCache(rs); - derivedCommand.castShadows = false; - derivedCommand.receiveShadows = false; - return derivedCommand; - } + listenToWheel(this, undefined); + listenToPinch(this, undefined, canvas); + listenMouseButtonDownUp(this, undefined, CameraEventType.LEFT_DRAG); + listenMouseButtonDownUp(this, undefined, CameraEventType.RIGHT_DRAG); + listenMouseButtonDownUp(this, undefined, CameraEventType.MIDDLE_DRAG); + listenMouseMove(this, undefined); - function deriveStencilCommand(command, reference) { - var derivedCommand = command; - if (command.renderState.depthMask) { // ignore if tile does not write depth (ex. translucent) - // Tiles only draw if their selection depth is >= the tile drawn already. They write their - // selection depth to the stencil buffer to prevent ancestor tiles from drawing on top - derivedCommand = DrawCommand.shallowClone(command); - var rs = clone(derivedCommand.renderState, true); - // Stencil test is masked to the most significant 4 bits so the reference is shifted. - // This is to prevent clearing the stencil before classification which needs the least significant - // bits for increment/decrement operations. - rs.stencilTest.enabled = true; - rs.stencilTest.mask = 0xF0; - rs.stencilTest.reference = reference << 4; - rs.stencilTest.frontFunction = StencilFunction.GREATER_OR_EQUAL; - rs.stencilTest.frontOperation.zPass = StencilOperation.REPLACE; - derivedCommand.renderState = RenderState.fromCache(rs); + for ( var modifierName in KeyboardEventModifier) { + if (KeyboardEventModifier.hasOwnProperty(modifierName)) { + var modifier = KeyboardEventModifier[modifierName]; + if (defined(modifier)) { + listenToWheel(this, modifier); + listenToPinch(this, modifier, canvas); + listenMouseButtonDownUp(this, modifier, CameraEventType.LEFT_DRAG); + listenMouseButtonDownUp(this, modifier, CameraEventType.RIGHT_DRAG); + listenMouseButtonDownUp(this, modifier, CameraEventType.MIDDLE_DRAG); + listenMouseMove(this, modifier); + } + } } - return derivedCommand; } - function getTranslucentRenderState(renderState) { - var rs = clone(renderState, true); - rs.cull.enabled = false; - rs.depthTest.enabled = true; - rs.depthMask = false; - rs.blending = BlendingState.ALPHA_BLEND; - - return RenderState.fromCache(rs); - } + defineProperties(CameraEventAggregator.prototype, { + /** + * Gets the current mouse position. + * @memberof CameraEventAggregator.prototype + * @type {Cartesian2} + */ + currentMousePosition : { + get : function() { + return this._currentMousePosition; + } + }, - /////////////////////////////////////////////////////////////////////////// + /** + * Gets whether any mouse button is down, a touch has started, or the wheel has been moved. + * @memberof CameraEventAggregator.prototype + * @type {Boolean} + */ + anyButtonDown : { + get : function() { + var wheelMoved = !this._update[getKey(CameraEventType.WHEEL)] || + !this._update[getKey(CameraEventType.WHEEL, KeyboardEventModifier.SHIFT)] || + !this._update[getKey(CameraEventType.WHEEL, KeyboardEventModifier.CTRL)] || + !this._update[getKey(CameraEventType.WHEEL, KeyboardEventModifier.ALT)]; + return this._buttonsDown > 0 || wheelMoved; + } + } + }); - function createTexture(batchTable, context, bytes) { - var dimensions = batchTable._textureDimensions; - return new Texture({ - context : context, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, - source : { - width : dimensions.x, - height : dimensions.y, - arrayBufferView : bytes - }, - sampler : new Sampler({ - minificationFilter : TextureMinificationFilter.NEAREST, - magnificationFilter : TextureMagnificationFilter.NEAREST - }) - }); - } + /** + * Gets if a mouse button down or touch has started and has been moved. + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Boolean} Returns <code>true</code> if a mouse button down or touch has started and has been moved; otherwise, <code>false</code> + */ + CameraEventAggregator.prototype.isMoving = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + var key = getKey(type, modifier); + return !this._update[key]; + }; - function createPickTexture(batchTable, context) { - var featuresLength = batchTable.featuresLength; - if (!defined(batchTable._pickTexture) && (featuresLength > 0)) { - var pickIds = batchTable._pickIds; - var byteLength = getByteLength(batchTable); - var bytes = new Uint8Array(byteLength); - var content = batchTable._content; + /** + * Gets the aggregated start and end position of the current event. + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Object} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code>. + */ + CameraEventAggregator.prototype.getMovement = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + var key = getKey(type, modifier); + var movement = this._movement[key]; + return movement; + }; - // PERFORMANCE_IDEA: we could skip the pick texture completely by allocating - // a continuous range of pickIds and then converting the base pickId + batchId - // to RGBA in the shader. The only consider is precision issues, which might - // not be an issue in WebGL 2. - for (var i = 0; i < featuresLength; ++i) { - var pickId = context.createPickId(content.getFeature(i)); - pickIds.push(pickId); + /** + * Gets the start and end position of the last move event (not the aggregated event). + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Object|undefined} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code> or <code>undefined</code>. + */ + CameraEventAggregator.prototype.getLastMovement = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + var key = getKey(type, modifier); + var lastMovement = this._lastMovement[key]; + if (lastMovement.valid) { + return lastMovement; + } - var pickColor = pickId.color; - var offset = i * 4; - bytes[offset] = Color.floatToByte(pickColor.red); - bytes[offset + 1] = Color.floatToByte(pickColor.green); - bytes[offset + 2] = Color.floatToByte(pickColor.blue); - bytes[offset + 3] = Color.floatToByte(pickColor.alpha); - } + return undefined; + }; - batchTable._pickTexture = createTexture(batchTable, context, bytes); - content._tileset._statistics.batchTableByteLength += batchTable._pickTexture.sizeInBytes; + /** + * Gets whether the mouse button is down or a touch has started. + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Boolean} Whether the mouse button is down or a touch has started. + */ + CameraEventAggregator.prototype.isButtonDown = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); } - } + + var key = getKey(type, modifier); + return this._isDown[key]; + }; - function updateBatchTexture(batchTable) { - var dimensions = batchTable._textureDimensions; - // PERFORMANCE_IDEA: Instead of rewriting the entire texture, use fine-grained - // texture updates when less than, for example, 10%, of the values changed. Or - // even just optimize the common case when one feature show/color changed. - batchTable._batchTexture.copyFrom({ - width : dimensions.x, - height : dimensions.y, - arrayBufferView : batchTable._batchValues - }); - } + /** + * Gets the mouse position that started the aggregation. + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Cartesian2} The mouse position. + */ + CameraEventAggregator.prototype.getStartMousePosition = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + if (type === CameraEventType.WHEEL) { + return this._currentMousePosition; + } - Cesium3DTileBatchTable.prototype.update = function(tileset, frameState) { - var context = frameState.context; - this._defaultTexture = context.defaultTexture; + var key = getKey(type, modifier); + return this._eventStartPosition[key]; + }; - if (frameState.passes.pick) { - // Create pick texture on-demand - createPickTexture(this, context); + /** + * Gets the time the button was pressed or the touch was started. + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Date} The time the button was pressed or the touch was started. + */ + CameraEventAggregator.prototype.getButtonPressTime = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); } + + var key = getKey(type, modifier); + return this._pressTime[key]; + }; - if (this._batchValuesDirty) { - this._batchValuesDirty = false; + /** + * Gets the time the button was released or the touch was ended. + * + * @param {CameraEventType} type The camera event type. + * @param {KeyboardEventModifier} [modifier] The keyboard modifier. + * @returns {Date} The time the button was released or the touch was ended. + */ + CameraEventAggregator.prototype.getButtonReleaseTime = function(type, modifier) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); + } + + var key = getKey(type, modifier); + return this._releaseTime[key]; + }; - // Create batch texture on-demand - if (!defined(this._batchTexture)) { - this._batchTexture = createTexture(this, context, this._batchValues); - tileset._statistics.batchTableByteLength += this._batchTexture.sizeInBytes; + /** + * Signals that all of the events have been handled and the aggregator should be reset to handle new events. + */ + CameraEventAggregator.prototype.reset = function() { + for ( var name in this._update) { + if (this._update.hasOwnProperty(name)) { + this._update[name] = true; } - - updateBatchTexture(this); // Apply per-feature show/color updates } }; - Cesium3DTileBatchTable.prototype.isDestroyed = function() { + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see CameraEventAggregator#destroy + */ + CameraEventAggregator.prototype.isDestroyed = function() { return false; }; - Cesium3DTileBatchTable.prototype.destroy = function() { - this._batchTexture = this._batchTexture && this._batchTexture.destroy(); - this._pickTexture = this._pickTexture && this._pickTexture.destroy(); + /** + * Removes mouse listeners held by this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * handler = handler && handler.destroy(); + * + * @see CameraEventAggregator#isDestroyed + */ + CameraEventAggregator.prototype.destroy = function() { + this._eventHandler = this._eventHandler && this._eventHandler.destroy(); + return destroyObject(this); + }; - var pickIds = this._pickIds; - var length = pickIds.length; - for (var i = 0; i < length; ++i) { - pickIds[i].destroy(); - } + return CameraEventAggregator; +}); - return destroyObject(this); +define('Scene/Cesium3DTileChildrenVisibility',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * @private + */ + var Cesium3DTileChildrenVisibility = { + NONE : 0, // No children visible + VISIBLE : 1, // At least one child visible + IN_REQUEST_VOLUME : 2, // At least one child in viewer request volume + VISIBLE_IN_REQUEST_VOLUME : 4, // At least one child both visible and in viewer request volume + VISIBLE_NOT_IN_REQUEST_VOLUME : 8 // At least one child visible but not in viewer request volume }; - return Cesium3DTileBatchTable; + return freezeObject(Cesium3DTileChildrenVisibility); }); -define('Scene/Cesium3DTileFeature',[ - '../Core/Color', +define('Scene/Composite3DTileContent',[ + '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties' + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/FeatureDetection', + '../Core/getMagic', + '../Core/RuntimeError', + '../ThirdParty/when' ], function( - Color, + defaultValue, defined, - defineProperties) { + defineProperties, + destroyObject, + FeatureDetection, + getMagic, + RuntimeError, + when) { 'use strict'; + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; + } + /** - * A feature of a {@link Cesium3DTileset}. - * <p> - * Provides access to a feature's properties stored in the tile's batch table, as well - * as the ability to show/hide a feature and change its highlight color via - * {@link Cesium3DTileFeature#show} and {@link Cesium3DTileFeature#color}, respectively. - * </p> - * <p> - * Modifications to a <code>Cesium3DTileFeature</code> object have the lifetime of the tile's - * content. If the tile's content is unloaded, e.g., due to it going out of view and needing - * to free space in the cache for visible tiles, listen to the {@link Cesium3DTileset#tileUnload} event to save any - * modifications. Also listen to the {@link Cesium3DTileset#tileVisible} event to reapply any modifications. - * </p> + * Represents the contents of a + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Composite/README.md|Composite} + * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. * <p> - * Do not construct this directly. Access it through {@link Cesium3DTileContent#getFeature} - * or picking using {@link Scene#pick} and {@link Scene#pickPosition}. + * Implements the {@link Cesium3DTileContent} interface. * </p> * - * @alias Cesium3DTileFeature + * @alias Composite3DTileContent * @constructor * - * @example - * // On mouse over, display all the properties for a feature in the console log. - * handler.setInputAction(function(movement) { - * var feature = scene.pick(movement.endPosition); - * if (feature instanceof Cesium.Cesium3DTileFeature) { - * var propertyNames = feature.getPropertyNames(); - * var length = propertyNames.length; - * for (var i = 0; i < length; ++i) { - * var propertyName = propertyNames[i]; - * console.log(propertyName + ': ' + feature.getProperty(propertyName)); - * } - * } - * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + * @private */ - function Cesium3DTileFeature(tileset, content, batchId) { - this._content = content; - this._batchId = batchId; - this._color = undefined; // for calling getColor + function Composite3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset, factory) { + this._tileset = tileset; + this._tile = tile; + this._resource = resource; + this._contents = []; + this._readyPromise = when.defer(); + + initialize(this, arrayBuffer, byteOffset, factory); } - defineProperties(Cesium3DTileFeature.prototype, { + defineProperties(Composite3DTileContent.prototype, { /** - * Gets or sets if the feature will be shown. This is set for all features - * when a style's show is evaluated. - * - * @memberof Cesium3DTileFeature.prototype - * - * @type {Boolean} - * - * @default true + * @inheritdoc Cesium3DTileContent#featurePropertiesDirty */ - show : { + featurePropertiesDirty : { get : function() { - return this._content.batchTable.getShow(this._batchId); + var contents = this._contents; + var length = contents.length; + for (var i = 0; i < length; ++i) { + if (contents[i].featurePropertiesDirty) { + return true; + } + } + + return false; }, set : function(value) { - this._content.batchTable.setShow(this._batchId, value); + var contents = this._contents; + var length = contents.length; + for (var i = 0; i < length; ++i) { + contents[i].featurePropertiesDirty = value; + } } }, /** - * Gets or sets the highlight color multiplied with the feature's color. When - * this is white, the feature's color is not changed. This is set for all features - * when a style's color is evaluated. - * - * @memberof Cesium3DTileFeature.prototype - * - * @type {Color} - * - * @default {@link Color.WHITE} + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>0</code>. Instead call <code>featuresLength</code> for a tile in the composite. */ - color : { + featuresLength : { get : function() { - if (!defined(this._color)) { - this._color = new Color(); - } - return this._content.batchTable.getColor(this._batchId, this._color); - }, - set : function(value) { - this._content.batchTable.setColor(this._batchId, value); + return 0; } }, /** - * Gets the content of the tile containing the feature. - * - * @memberof Cesium3DTileFeature.prototype - * - * @type {Cesium3DTileContent} - * - * @readonly - * @private + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>0</code>. Instead call <code>pointsLength</code> for a tile in the composite. */ - content : { + pointsLength : { get : function() { - return this._content; + return 0; } }, /** - * Gets the tileset containing the feature. - * - * @memberof Cesium3DTileFeature.prototype - * - * @type {Cesium3DTileset} - * - * @readonly + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>0</code>. Instead call <code>trianglesLength</code> for a tile in the composite. + */ + trianglesLength : { + get : function() { + return 0; + } + }, + + /** + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>0</code>. Instead call <code>geometryByteLength</code> for a tile in the composite. + */ + geometryByteLength : { + get : function() { + return 0; + } + }, + + /** + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>0</code>. Instead call <code>texturesByteLength</code> for a tile in the composite. + */ + texturesByteLength : { + get : function() { + return 0; + } + }, + + /** + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>0</code>. Instead call <code>batchTableByteLength</code> for a tile in the composite. + */ + batchTableByteLength : { + get : function() { + return 0; + } + }, + + /** + * @inheritdoc Cesium3DTileContent#innerContents + */ + innerContents : { + get : function() { + return this._contents; + } + }, + + /** + * @inheritdoc Cesium3DTileContent#readyPromise + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + }, + + /** + * @inheritdoc Cesium3DTileContent#tileset */ tileset : { get : function() { - return this._content.tileset; + return this._tileset; } }, /** - * All objects returned by {@link Scene#pick} have a <code>primitive</code> property. This returns - * the tileset containing the feature. - * - * @memberof Cesium3DTileFeature.prototype - * - * @type {Cesium3DTileset} - * - * @readonly + * @inheritdoc Cesium3DTileContent#tile */ - primitive : { + tile : { get : function() { - return this._content.tileset; + return this._tile; + } + }, + + /** + * @inheritdoc Cesium3DTileContent#url + */ + url : { + get : function() { + return this._resource.getUrlComponent(true); + } + }, + + /** + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>undefined</code>. Instead call <code>batchTable</code> for a tile in the composite. + */ + batchTable : { + get : function() { + return undefined; } } }); + var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; + + function initialize(content, arrayBuffer, byteOffset, factory) { + byteOffset = defaultValue(byteOffset, 0); + + var uint8Array = new Uint8Array(arrayBuffer); + var view = new DataView(arrayBuffer); + byteOffset += sizeOfUint32; // Skip magic + + var version = view.getUint32(byteOffset, true); + if (version !== 1) { + throw new RuntimeError('Only Composite Tile version 1 is supported. Version ' + version + ' is not.'); + } + byteOffset += sizeOfUint32; + + // Skip byteLength + byteOffset += sizeOfUint32; + + var tilesLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + + var contentPromises = []; + + for (var i = 0; i < tilesLength; ++i) { + var tileType = getMagic(uint8Array, byteOffset); + + // Tile byte length is stored after magic and version + var tileByteLength = view.getUint32(byteOffset + sizeOfUint32 * 2, true); + + var contentFactory = factory[tileType]; + + if (defined(contentFactory)) { + var innerContent = contentFactory(content._tileset, content._tile, content._resource, arrayBuffer, byteOffset); + content._contents.push(innerContent); + contentPromises.push(innerContent.readyPromise); + } else { + throw new RuntimeError('Unknown tile content type, ' + tileType + ', inside Composite tile'); + } + + byteOffset += tileByteLength; + } + + when.all(contentPromises).then(function() { + content._readyPromise.resolve(content); + }).otherwise(function(error) { + content._readyPromise.reject(error); + }); + } + /** - * Returns whether the feature contains this property. This includes properties from this feature's - * class and inherited classes when using a batch table hierarchy. - * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} - * - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} Whether the feature contains this property. + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>false</code>. Instead call <code>hasProperty</code> for a tile in the composite. */ - Cesium3DTileFeature.prototype.hasProperty = function(name) { - return this._content.batchTable.hasProperty(this._batchId, name); + Composite3DTileContent.prototype.hasProperty = function(batchId, name) { + return false; }; /** - * Returns an array of property names for the feature. This includes properties from this feature's - * class and inherited classes when using a batch table hierarchy. - * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} - * - * @param {String[]} results An array into which to store the results. - * @returns {String[]} The names of the feature's properties. + * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> + * always returns <code>undefined</code>. Instead call <code>getFeature</code> for a tile in the composite. */ - Cesium3DTileFeature.prototype.getPropertyNames = function(results) { - return this._content.batchTable.getPropertyNames(this._batchId, results); + Composite3DTileContent.prototype.getFeature = function(batchId) { + return undefined; }; /** - * Returns a copy of the value of the feature's property with the given name. This includes properties from this feature's - * class and inherited classes when using a batch table hierarchy. - * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} - * - * @param {String} name The case-sensitive name of the property. - * @returns {*} The value of the property or <code>undefined</code> if the property does not exist. - * - * @example - * // Display all the properties for a feature in the console log. - * var propertyNames = feature.getPropertyNames(); - * var length = propertyNames.length; - * for (var i = 0; i < length; ++i) { - * var propertyName = propertyNames[i]; - * console.log(propertyName + ': ' + feature.getProperty(propertyName)); - * } + * @inheritdoc Cesium3DTileContent#applyDebugSettings */ - Cesium3DTileFeature.prototype.getProperty = function(name) { - return this._content.batchTable.getProperty(this._batchId, name); + Composite3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + var contents = this._contents; + var length = contents.length; + for (var i = 0; i < length; ++i) { + contents[i].applyDebugSettings(enabled, color); + } }; /** - * Sets the value of the feature's property with the given name. - * <p> - * If a property with the given name doesn't exist, it is created. - * </p> - * - * @param {String} name The case-sensitive name of the property. - * @param {*} value The value of the property that will be copied. - * - * @exception {DeveloperError} Inherited batch table hierarchy property is read only. - * - * @example - * var height = feature.getProperty('Height'); // e.g., the height of a building - * - * @example - * var name = 'clicked'; - * if (feature.getProperty(name)) { - * console.log('already clicked'); - * } else { - * feature.setProperty(name, true); - * console.log('first click'); - * } + * @inheritdoc Cesium3DTileContent#applyStyle */ - Cesium3DTileFeature.prototype.setProperty = function(name, value) { - this._content.batchTable.setProperty(this._batchId, name, value); - - // PERFORMANCE_IDEA: Probably overkill, but maybe only mark the tile dirty if the - // property is in one of the style's expressions or - if it can be done quickly - - // if the new property value changed the result of an expression. - this._content.featurePropertiesDirty = true; + Composite3DTileContent.prototype.applyStyle = function(frameState, style) { + var contents = this._contents; + var length = contents.length; + for (var i = 0; i < length; ++i) { + contents[i].applyStyle(frameState, style); + } }; /** - * Returns whether the feature's class name equals <code>className</code>. Unlike {@link Cesium3DTileFeature#isClass} - * this function only checks the feature's exact class and not inherited classes. - * <p> - * This function returns <code>false</code> if no batch table hierarchy is present. - * </p> - * - * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class name equals <code>className</code> - * - * @private + * @inheritdoc Cesium3DTileContent#update */ - Cesium3DTileFeature.prototype.isExactClass = function(className) { - return this._content.batchTable.isExactClass(this._batchId, className); + Composite3DTileContent.prototype.update = function(tileset, frameState) { + var contents = this._contents; + var length = contents.length; + for (var i = 0; i < length; ++i) { + contents[i].update(tileset, frameState); + } }; /** - * Returns whether the feature's class or any inherited classes are named <code>className</code>. - * <p> - * This function returns <code>false</code> if no batch table hierarchy is present. - * </p> - * - * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class or inherited classes are named <code>className</code> - * - * @private + * @inheritdoc Cesium3DTileContent#isDestroyed */ - Cesium3DTileFeature.prototype.isClass = function(className) { - return this._content.batchTable.isClass(this._batchId, className); + Composite3DTileContent.prototype.isDestroyed = function() { + return false; }; /** - * Returns the feature's class name. - * <p> - * This function returns <code>undefined</code> if no batch table hierarchy is present. - * </p> - * - * @returns {String} The feature's class name. - * - * @private + * @inheritdoc Cesium3DTileContent#destroy */ - Cesium3DTileFeature.prototype.getExactClassName = function() { - return this._content.batchTable.getExactClassName(this._batchId); + Composite3DTileContent.prototype.destroy = function() { + var contents = this._contents; + var length = contents.length; + for (var i = 0; i < length; ++i) { + contents[i].destroy(); + } + return destroyObject(this); }; - return Cesium3DTileFeature; + return Composite3DTileContent; }); -define('Scene/Cesium3DTileFeatureTable',[ - '../Core/ComponentDatatype', +define('Scene/Vector3DTileGeometry',[ + '../Core/arraySlice', + '../Core/BoundingSphere', + '../Core/Cartesian3', + '../Core/Color', '../Core/defaultValue', - '../Core/defined' + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/Matrix4', + '../Core/TaskProcessor', + '../ThirdParty/when', + './ClassificationType', + './Vector3DTileBatch', + './Vector3DTilePrimitive' ], function( - ComponentDatatype, + arraySlice, + BoundingSphere, + Cartesian3, + Color, defaultValue, - defined) { + defined, + defineProperties, + destroyObject, + Matrix4, + TaskProcessor, + when, + ClassificationType, + Vector3DTileBatch, + Vector3DTilePrimitive) { 'use strict'; /** + * Creates a batch of box, cylinder, ellipsoid and/or sphere geometries intersecting terrain or 3D Tiles. + * + * @alias Vector3DTileGeometry + * @constructor + * + * @param {Object} options An object with following properties: + * @param {Float32Array} [options.boxes] The boxes in the tile. + * @param {Uint16Array} [options.boxBatchIds] The batch ids for each box. + * @param {Float32Array} [options.cylinders] The cylinders in the tile. + * @param {Uint16Array} [options.cylinderBatchIds] The batch ids for each cylinder. + * @param {Float32Array} [options.ellipsoids] The ellipsoids in the tile. + * @param {Uint16Array} [options.ellipsoidBatchIds] The batch ids for each ellipsoid. + * @param {Float32Array} [options.spheres] The spheres in the tile. + * @param {Uint16Array} [options.sphereBatchIds] The batch ids for each sphere. + * @param {Cartesian3} options.center The RTC center of all geometries. + * @param {Matrix4} options.modelMatrix The model matrix of all geometries. Applied after the individual geometry model matrices. + * @param {Cesium3DTileBatchTable} options.batchTable The batch table. + * @param {BoundingSphere} options.boundingVolume The bounding volume containing all of the geometry in the tile. + * * @private */ - function Cesium3DTileFeatureTable(featureTableJson, featureTableBinary) { - this.json = featureTableJson; - this.buffer = featureTableBinary; - this._cachedTypedArrays = {}; - this.featuresLength = 0; - } + function Vector3DTileGeometry(options) { + // these will all be released after the primitive is created + this._boxes = options.boxes; + this._boxBatchIds = options.boxBatchIds; + this._cylinders = options.cylinders; + this._cylinderBatchIds = options.cylinderBatchIds; + this._ellipsoids = options.ellipsoids; + this._ellipsoidBatchIds = options.ellipsoidBatchIds; + this._spheres = options.spheres; + this._sphereBatchIds = options.sphereBatchIds; + this._modelMatrix = options.modelMatrix; + this._batchTable = options.batchTable; + this._boundingVolume = options.boundingVolume; - function getTypedArrayFromBinary(featureTable, semantic, componentType, componentLength, count, byteOffset) { - var cachedTypedArrays = featureTable._cachedTypedArrays; - var typedArray = cachedTypedArrays[semantic]; - if (!defined(typedArray)) { - typedArray = ComponentDatatype.createArrayBufferView(componentType, featureTable.buffer.buffer, featureTable.buffer.byteOffset + byteOffset, count * componentLength); - cachedTypedArrays[semantic] = typedArray; + this._center = options.center; + if (!defined(this._center)) { + if (defined(this._boundingVolume)) { + this._center = Cartesian3.clone(this._boundingVolume.center); + } else { + this._center = Cartesian3.clone(Cartesian3.ZERO); + } } - return typedArray; + + this._boundingVolumes = undefined; + this._batchedIndices = undefined; + + this._indices = undefined; + this._indexOffsets = undefined; + this._indexCounts = undefined; + + this._positions = undefined; + this._vertexBatchIds = undefined; + + this._batchIds = undefined; + + this._batchTableColors = undefined; + this._packedBuffer = undefined; + + this._ready = false; + this._readyPromise = when.defer(); + + this._verticesPromise = undefined; + + this._primitive = undefined; + + /** + * Draws the wireframe of the classification geometries. + * @type {Boolean} + * @default false + */ + this.debugWireframe = false; + + /** + * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only. + * @type {Boolean} + * @default false + */ + this.forceRebatch = false; + + /** + * What this tile will classify. + * @type {ClassificationType} + * @default ClassificationType.CESIUM_3D_TILE + */ + this.classificationType = ClassificationType.CESIUM_3D_TILE; } - function getTypedArrayFromArray(featureTable, semantic, componentType, array) { - var cachedTypedArrays = featureTable._cachedTypedArrays; - var typedArray = cachedTypedArrays[semantic]; - if (!defined(typedArray)) { - typedArray = ComponentDatatype.createTypedArray(componentType, array); - cachedTypedArrays[semantic] = typedArray; + defineProperties(Vector3DTileGeometry.prototype, { + /** + * Gets the number of triangles. + * + * @memberof Vector3DTileGeometry.prototype + * + * @type {Number} + * @readonly + */ + trianglesLength : { + get : function() { + if (defined(this._primitive)) { + return this._primitive.trianglesLength; + } + return 0; + } + }, + + /** + * Gets the geometry memory in bytes. + * + * @memberof Vector3DTileGeometry.prototype + * + * @type {Number} + * @readonly + */ + geometryByteLength : { + get : function() { + if (defined(this._primitive)) { + return this._primitive.geometryByteLength; + } + return 0; + } + }, + + /** + * Gets a promise that resolves when the primitive is ready to render. + * @memberof Vector3DTileGeometry.prototype + * @type {Promise} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } } - return typedArray; + }); + + Vector3DTileGeometry.packedBoxLength = Matrix4.packedLength + Cartesian3.packedLength; + Vector3DTileGeometry.packedCylinderLength = Matrix4.packedLength + 2; + Vector3DTileGeometry.packedEllipsoidLength = Matrix4.packedLength + Cartesian3.packedLength; + Vector3DTileGeometry.packedSphereLength = Cartesian3.packedLength + 1; + + function packBuffer(geometries) { + var packedBuffer = new Float64Array(Matrix4.packedLength + Cartesian3.packedLength); + + var offset = 0; + Cartesian3.pack(geometries._center, packedBuffer, offset); + offset += Cartesian3.packedLength; + Matrix4.pack(geometries._modelMatrix, packedBuffer, offset); + + return packedBuffer; } - Cesium3DTileFeatureTable.prototype.getGlobalProperty = function(semantic, componentType, componentLength) { - var jsonValue = this.json[semantic]; - if (!defined(jsonValue)) { - return undefined; + function unpackBuffer(geometries, packedBuffer) { + var offset = 0; + + var indicesBytesPerElement = packedBuffer[offset++]; + var numBVS = packedBuffer[offset++]; + var bvs = geometries._boundingVolumes = new Array(numBVS); + + for (var i = 0; i < numBVS; ++i) { + bvs[i] = BoundingSphere.unpack(packedBuffer, offset); + offset += BoundingSphere.packedLength; } - if (defined(jsonValue.byteOffset)) { - componentType = defaultValue(componentType, ComponentDatatype.UNSIGNED_INT); - componentLength = defaultValue(componentLength, 1); - return getTypedArrayFromBinary(this, semantic, componentType, componentLength, 1, jsonValue.byteOffset); + var numBatchedIndices = packedBuffer[offset++]; + var bis = geometries._batchedIndices = new Array(numBatchedIndices); + + for (var j = 0; j < numBatchedIndices; ++j) { + var color = Color.unpack(packedBuffer, offset); + offset += Color.packedLength; + + var indexOffset = packedBuffer[offset++]; + var count = packedBuffer[offset++]; + + var length = packedBuffer[offset++]; + var batchIds = new Array(length); + + for (var k = 0; k < length; ++k) { + batchIds[k] = packedBuffer[offset++]; + } + + bis[j] = new Vector3DTileBatch({ + color : color, + offset : indexOffset, + count : count, + batchIds : batchIds + }); } - return jsonValue; - }; + return indicesBytesPerElement; + } - Cesium3DTileFeatureTable.prototype.getPropertyArray = function(semantic, componentType, componentLength) { - var jsonValue = this.json[semantic]; - if (!defined(jsonValue)) { - return undefined; + var createVerticesTaskProcessor = new TaskProcessor('createVectorTileGeometries'); + var scratchColor = new Color(); + + function createPrimitive(geometries) { + if (defined(geometries._primitive)) { + return; } - if (defined(jsonValue.byteOffset)) { - if (defined(jsonValue.componentType)) { - componentType = ComponentDatatype.fromName(jsonValue.componentType); + if (!defined(geometries._verticesPromise)) { + var boxes = geometries._boxes; + var boxBatchIds = geometries._boxBatchIds; + var cylinders = geometries._cylinders; + var cylinderBatchIds = geometries._cylinderBatchIds; + var ellipsoids = geometries._ellipsoids; + var ellipsoidBatchIds = geometries._ellipsoidBatchIds; + var spheres = geometries._spheres; + var sphereBatchIds = geometries._sphereBatchIds; + + var batchTableColors = geometries._batchTableColors; + var packedBuffer = geometries._packedBuffer; + + if (!defined(batchTableColors)) { + // Copy because they may be the views on the same buffer. + var length = 0; + if (defined(geometries._boxes)) { + boxes = geometries._boxes = arraySlice(boxes); + boxBatchIds = geometries._boxBatchIds = arraySlice(boxBatchIds); + length += boxBatchIds.length; + } + if (defined(geometries._cylinders)) { + cylinders = geometries._cylinders = arraySlice(cylinders); + cylinderBatchIds = geometries._cylinderBatchIds = arraySlice(cylinderBatchIds); + length += cylinderBatchIds.length; + } + if (defined(geometries._ellipsoids)) { + ellipsoids = geometries._ellipsoids = arraySlice(ellipsoids); + ellipsoidBatchIds = geometries._ellipsoidBatchIds = arraySlice(ellipsoidBatchIds); + length += ellipsoidBatchIds.length; + } + if (defined(geometries._spheres)) { + spheres = geometries._sphere = arraySlice(spheres); + sphereBatchIds = geometries._sphereBatchIds = arraySlice(sphereBatchIds); + length += sphereBatchIds.length; + } + + batchTableColors = geometries._batchTableColors = new Uint32Array(length); + var batchTable = geometries._batchTable; + + for (var i = 0; i < length; ++i) { + var color = batchTable.getColor(i, scratchColor); + batchTableColors[i] = color.toRgba(); + } + + packedBuffer = geometries._packedBuffer = packBuffer(geometries); } - return getTypedArrayFromBinary(this, semantic, componentType, componentLength, this.featuresLength, jsonValue.byteOffset); + + var transferrableObjects = []; + if (defined(boxes)) { + transferrableObjects.push(boxes.buffer, boxBatchIds.buffer); + } + if (defined(cylinders)) { + transferrableObjects.push(cylinders.buffer, cylinderBatchIds.buffer); + } + if (defined(ellipsoids)) { + transferrableObjects.push(ellipsoids.buffer, ellipsoidBatchIds.buffer); + } + if (defined(spheres)) { + transferrableObjects.push(spheres.buffer, sphereBatchIds.buffer); + } + transferrableObjects.push(batchTableColors.buffer, packedBuffer.buffer); + + var parameters = { + boxes : defined(boxes) ? boxes.buffer : undefined, + boxBatchIds : defined(boxes) ? boxBatchIds.buffer : undefined, + cylinders : defined(cylinders) ? cylinders.buffer : undefined, + cylinderBatchIds : defined(cylinders) ? cylinderBatchIds.buffer : undefined, + ellipsoids : defined(ellipsoids) ? ellipsoids.buffer : undefined, + ellipsoidBatchIds : defined(ellipsoids) ? ellipsoidBatchIds.buffer : undefined, + spheres : defined(spheres) ? spheres.buffer : undefined, + sphereBatchIds : defined(spheres) ? sphereBatchIds.buffer : undefined, + batchTableColors : batchTableColors.buffer, + packedBuffer : packedBuffer.buffer + }; + + var verticesPromise = geometries._verticesPromise = createVerticesTaskProcessor.scheduleTask(parameters, transferrableObjects); + if (!defined(verticesPromise)) { + // Postponed + return; + } + + verticesPromise.then(function(result) { + var packedBuffer = new Float64Array(result.packedBuffer); + var indicesBytesPerElement = unpackBuffer(geometries, packedBuffer); + + if (indicesBytesPerElement === 2) { + geometries._indices = new Uint16Array(result.indices); + } else { + geometries._indices = new Uint32Array(result.indices); + } + + geometries._indexOffsets = new Uint32Array(result.indexOffsets); + geometries._indexCounts = new Uint32Array(result.indexCounts); + + geometries._positions = new Float32Array(result.positions); + geometries._vertexBatchIds = new Uint16Array(result.vertexBatchIds); + + geometries._batchIds = new Uint16Array(result.batchIds); + + geometries._ready = true; + }); } - return getTypedArrayFromArray(this, semantic, componentType, jsonValue); - }; + if (geometries._ready && !defined(geometries._primitive)) { + geometries._primitive = new Vector3DTilePrimitive({ + batchTable : geometries._batchTable, + positions : geometries._positions, + batchIds : geometries._batchIds, + vertexBatchIds : geometries._vertexBatchIds, + indices : geometries._indices, + indexOffsets : geometries._indexOffsets, + indexCounts : geometries._indexCounts, + batchedIndices : geometries._batchedIndices, + boundingVolume : geometries._boundingVolume, + boundingVolumes : geometries._boundingVolumes, + center : geometries._center, + pickObject : defaultValue(geometries._pickObject, geometries) + }); - Cesium3DTileFeatureTable.prototype.getProperty = function(semantic, componentType, componentLength, featureId, result) { - var jsonValue = this.json[semantic]; - if (!defined(jsonValue)) { - return undefined; + geometries._boxes = undefined; + geometries._boxBatchIds = undefined; + geometries._cylinders = undefined; + geometries._cylinderBatchIds = undefined; + geometries._ellipsoids = undefined; + geometries._ellipsoidBatchIds = undefined; + geometries._spheres = undefined; + geometries._sphereBatchIds = undefined; + geometries._center = undefined; + geometries._modelMatrix = undefined; + geometries._batchTable = undefined; + geometries._boundingVolume = undefined; + + geometries._boundingVolumes = undefined; + geometries._batchedIndices = undefined; + + geometries._indices = undefined; + geometries._indexOffsets = undefined; + geometries._indexCounts = undefined; + + geometries._positions = undefined; + geometries._vertexBatchIds = undefined; + + geometries._batchIds = undefined; + + geometries._batchTableColors = undefined; + geometries._packedBuffer = undefined; + + geometries._verticesPromise = undefined; + + geometries._readyPromise.resolve(); } + } + + /** + * Creates features for each geometry and places it at the batch id index of features. + * + * @param {Vector3DTileContent} content The vector tile content. + * @param {Cesium3DTileFeature[]} features An array of features where the polygon features will be placed. + */ + Vector3DTileGeometry.prototype.createFeatures = function(content, features) { + this._primitive.createFeatures(content, features); + }; + + /** + * Colors the entire tile when enabled is true. The resulting color will be (geometry batch table color * color). + * + * @param {Boolean} enabled Whether to enable debug coloring. + * @param {Color} color The debug color. + */ + Vector3DTileGeometry.prototype.applyDebugSettings = function(enabled, color) { + this._primitive.applyDebugSettings(enabled, color); + }; + + /** + * Apply a style to the content. + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileStyle} style The style. + * @param {Cesium3DTileFeature[]} features The array of features. + */ + Vector3DTileGeometry.prototype.applyStyle = function(frameState, style, features) { + this._primitive.applyStyle(frameState, style, features); + }; + + /** + * Call when updating the color of a geometry with batchId changes color. The geometries will need to be re-batched + * on the next update. + * + * @param {Number} batchId The batch id of the geometries whose color has changed. + * @param {Color} color The new polygon color. + */ + Vector3DTileGeometry.prototype.updateCommands = function(batchId, color) { + this._primitive.updateCommands(batchId, color); + }; - var typedArray = this.getPropertyArray(semantic, componentType, componentLength); + /** + * Updates the batches and queues the commands for rendering. + * + * @param {FrameState} frameState The current frame state. + */ + Vector3DTileGeometry.prototype.update = function(frameState) { + createPrimitive(this); - if (componentLength === 1) { - return typedArray[featureId]; + if (!this._ready) { + return; } - for (var i = 0; i < componentLength; ++i) { - result[i] = typedArray[componentLength * featureId + i]; - } + this._primitive.debugWireframe = this.debugWireframe; + this._primitive.forceRebatch = this.forceRebatch; + this._primitive.classificationType = this.classificationType; + this._primitive.update(frameState); + }; - return result; + /** + * Returns true if this object was destroyed; otherwise, false. + * <p> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + */ + Vector3DTileGeometry.prototype.isDestroyed = function() { + return false; }; - return Cesium3DTileFeatureTable; + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + Vector3DTileGeometry.prototype.destroy = function() { + this._primitive = this._primitive && this._primitive.destroy(); + return destroyObject(this); + }; + + return Vector3DTileGeometry; }); -define('Scene/Batched3DModel3DTileContent',[ - '../Core/ClippingPlaneCollection', - '../Core/Color', +define('Scene/Geometry3DTileContent',[ + '../Core/Cartesian3', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/deprecationWarning', '../Core/destroyObject', '../Core/DeveloperError', + '../Core/Ellipsoid', '../Core/FeatureDetection', - '../Core/getAbsoluteUri', - '../Core/getBaseUri', + '../Core/getMagic', '../Core/getStringFromTypedArray', - '../Core/RequestType', + '../Core/Math', + '../Core/Matrix4', + '../Core/Rectangle', '../Core/RuntimeError', - '../Renderer/Pass', + '../ThirdParty/when', './Cesium3DTileBatchTable', - './Cesium3DTileFeature', - './Cesium3DTileFeatureTable', - './getAttributeOrUniformBySemantic', - './Model' + './Vector3DTileGeometry' ], function( - ClippingPlaneCollection, - Color, + Cartesian3, defaultValue, defined, defineProperties, - deprecationWarning, destroyObject, DeveloperError, + Ellipsoid, FeatureDetection, - getAbsoluteUri, - getBaseUri, + getMagic, getStringFromTypedArray, - RequestType, + CesiumMath, + Matrix4, + Rectangle, RuntimeError, - Pass, + when, Cesium3DTileBatchTable, - Cesium3DTileFeature, - Cesium3DTileFeatureTable, - getAttributeOrUniformBySemantic, - Model) { + Vector3DTileGeometry) { 'use strict'; // Bail out if the browser doesn't support typed arrays, to prevent the setup function @@ -166902,44 +180388,42 @@ define('Scene/Batched3DModel3DTileContent',[ } /** - * Represents the contents of a - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md|Batched 3D Model} - * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> * - * @alias Batched3DModel3DTileContent + * @alias Geometry3DTileContent * @constructor * * @private */ - function Batched3DModel3DTileContent(tileset, tile, url, arrayBuffer, byteOffset) { + function Geometry3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { this._tileset = tileset; this._tile = tile; - this._url = url; - this._model = undefined; + this._resource = resource; + this._geometries = undefined; + + this._contentReadyPromise = undefined; + this._readyPromise = when.defer(); + this._batchTable = undefined; this._features = undefined; /** - * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + * Part of the {@link Cesium3DTileContent} interface. */ this.featurePropertiesDirty = false; initialize(this, arrayBuffer, byteOffset); } - // This can be overridden for testing purposes - Batched3DModel3DTileContent._deprecationWarning = deprecationWarning; - - defineProperties(Batched3DModel3DTileContent.prototype, { + defineProperties(Geometry3DTileContent.prototype, { /** * @inheritdoc Cesium3DTileContent#featuresLength */ featuresLength : { get : function() { - return this._batchTable.featuresLength; + return defined(this._batchTable) ? this._batchTable.featuresLength : 0; } }, @@ -166957,7 +180441,10 @@ define('Scene/Batched3DModel3DTileContent',[ */ trianglesLength : { get : function() { - return this._model.trianglesLength; + if (defined(this._geometries)) { + return this._geometries.trianglesLength; + } + return 0; } }, @@ -166966,7 +180453,10 @@ define('Scene/Batched3DModel3DTileContent',[ */ geometryByteLength : { get : function() { - return this._model.geometryByteLength; + if (defined(this._geometries)) { + return this._geometries.geometryByteLength; + } + return 0; } }, @@ -166975,7 +180465,7 @@ define('Scene/Batched3DModel3DTileContent',[ */ texturesByteLength : { get : function() { - return this._model.texturesByteLength; + return 0; } }, @@ -166984,7 +180474,7 @@ define('Scene/Batched3DModel3DTileContent',[ */ batchTableByteLength : { get : function() { - return this._batchTable.memorySizeInBytes; + return defined(this._batchTable) ? this._batchTable.memorySizeInBytes : 0; } }, @@ -167002,7 +180492,7 @@ define('Scene/Batched3DModel3DTileContent',[ */ readyPromise : { get : function() { - return this._model.readyPromise; + return this._readyPromise.promise; } }, @@ -167027,9 +180517,9 @@ define('Scene/Batched3DModel3DTileContent',[ /** * @inheritdoc Cesium3DTileContent#url */ - url: { - get: function() { - return this._url; + url : { + get : function() { + return this._resource.getUrlComponent(true); } }, @@ -167043,211 +180533,230 @@ define('Scene/Batched3DModel3DTileContent',[ } }); - var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - - function getBatchIdAttributeName(gltf) { - var batchIdAttributeName = getAttributeOrUniformBySemantic(gltf, '_BATCHID'); - if (!defined(batchIdAttributeName)) { - batchIdAttributeName = getAttributeOrUniformBySemantic(gltf, 'BATCHID'); - if (defined(batchIdAttributeName)) { - Batched3DModel3DTileContent._deprecationWarning('b3dm-legacy-batchid', 'The glTF in this b3dm uses the semantic `BATCHID`. Application-specific semantics should be prefixed with an underscore: `_BATCHID`.'); + function createColorChangedCallback(content) { + return function(batchId, color) { + if (defined(content._geometries)) { + content._geometries.updateCommands(batchId, color); } - } - return batchIdAttributeName; - } - - function getVertexShaderCallback(content) { - return function(vs) { - var batchTable = content._batchTable; - var gltf = content._model.gltf; - var batchIdAttributeName = getBatchIdAttributeName(gltf); - var callback = batchTable.getVertexShaderCallback(true, batchIdAttributeName); - return defined(callback) ? callback(vs) : vs; }; } - function getPickVertexShaderCallback(content) { - return function(vs) { - var batchTable = content._batchTable; - var gltf = content._model.gltf; - var batchIdAttributeName = getBatchIdAttributeName(gltf); - var callback = batchTable.getPickVertexShaderCallback(batchIdAttributeName); - return defined(callback) ? callback(vs) : vs; - }; - } + function getBatchIds(featureTableJson, featureTableBinary) { + var boxBatchIds; + var cylinderBatchIds; + var ellipsoidBatchIds; + var sphereBatchIds; + var i; - function getFragmentShaderCallback(content) { - return function(fs) { - var batchTable = content._batchTable; - var gltf = content._model.gltf; - var diffuseUniformName = getAttributeOrUniformBySemantic(gltf, '_3DTILESDIFFUSE'); - var callback = batchTable.getFragmentShaderCallback(true, diffuseUniformName); - return defined(callback) ? callback(fs) : fs; + var numberOfBoxes = defaultValue(featureTableJson.BOXES_LENGTH, 0); + var numberOfCylinders = defaultValue(featureTableJson.CYLINDERS_LENGTH, 0); + var numberOfEllipsoids = defaultValue(featureTableJson.ELLIPSOIDS_LENGTH, 0); + var numberOfSpheres = defaultValue(featureTableJson.SPHERES_LENGTH, 0); + + if (numberOfBoxes > 0 && defined(featureTableJson.BOX_BATCH_IDS)) { + var boxBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.BOX_BATCH_IDS.byteOffset; + boxBatchIds = new Uint16Array(featureTableBinary.buffer, boxBatchIdsByteOffset, numberOfBoxes); + } + + if (numberOfCylinders > 0 && defined(featureTableJson.CYLINDER_BATCH_IDS)) { + var cylinderBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.CYLINDER_BATCH_IDS.byteOffset; + cylinderBatchIds = new Uint16Array(featureTableBinary.buffer, cylinderBatchIdsByteOffset, numberOfCylinders); + } + + if (numberOfEllipsoids > 0 && defined(featureTableJson.ELLIPSOID_BATCH_IDS)) { + var ellipsoidBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.ELLIPSOID_BATCH_IDS.byteOffset; + ellipsoidBatchIds = new Uint16Array(featureTableBinary.buffer, ellipsoidBatchIdsByteOffset, numberOfEllipsoids); + } + + if (numberOfSpheres > 0 && defined(featureTableJson.SPHERE_BATCH_IDS)) { + var sphereBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.SPHERE_BATCH_IDS.byteOffset; + sphereBatchIds = new Uint16Array(featureTableBinary.buffer, sphereBatchIdsByteOffset, numberOfSpheres); + } + + var atLeastOneDefined = defined(boxBatchIds) || defined(cylinderBatchIds) || defined(ellipsoidBatchIds) || defined(sphereBatchIds); + var atLeastOneUndefined = (numberOfBoxes > 0 && !defined(boxBatchIds)) || + (numberOfCylinders > 0 && !defined(cylinderBatchIds)) || + (numberOfEllipsoids > 0 && !defined(ellipsoidBatchIds)) || + (numberOfSpheres > 0 && !defined(sphereBatchIds)); + + if (atLeastOneDefined && atLeastOneUndefined) { + throw new RuntimeError('If one group of batch ids is defined, then all batch ids must be defined.'); + } + + var allUndefinedBatchIds = !defined(boxBatchIds) && !defined(cylinderBatchIds) && !defined(ellipsoidBatchIds) && !defined(sphereBatchIds); + if (allUndefinedBatchIds) { + var id = 0; + if (!defined(boxBatchIds) && numberOfBoxes > 0) { + boxBatchIds = new Uint16Array(numberOfBoxes); + for (i = 0; i < numberOfBoxes; ++i) { + boxBatchIds[i] = id++; + } + } + if (!defined(cylinderBatchIds) && numberOfCylinders > 0) { + cylinderBatchIds = new Uint16Array(numberOfCylinders); + for (i = 0; i < numberOfCylinders; ++i) { + cylinderBatchIds[i] = id++; + } + } + if (!defined(ellipsoidBatchIds) && numberOfEllipsoids > 0) { + ellipsoidBatchIds = new Uint16Array(numberOfEllipsoids); + for (i = 0; i < numberOfEllipsoids; ++i) { + ellipsoidBatchIds[i] = id++; + } + } + if (!defined(sphereBatchIds) && numberOfSpheres > 0) { + sphereBatchIds = new Uint16Array(numberOfSpheres); + for (i = 0; i < numberOfSpheres; ++i) { + sphereBatchIds[i] = id++; + } + } + } + + return { + boxes : boxBatchIds, + cylinders : cylinderBatchIds, + ellipsoids : ellipsoidBatchIds, + spheres : sphereBatchIds }; } - function initialize(content, arrayBuffer, byteOffset) { - var tileset = content._tileset; - var tile = content._tile; - var basePath = getAbsoluteUri(getBaseUri(content._url, true)); + var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - var byteStart = defaultValue(byteOffset, 0); - byteOffset = byteStart; + function initialize(content, arrayBuffer, byteOffset) { + byteOffset = defaultValue(byteOffset, 0); var uint8Array = new Uint8Array(arrayBuffer); var view = new DataView(arrayBuffer); - byteOffset += sizeOfUint32; // Skip magic + byteOffset += sizeOfUint32; // Skip magic number var version = view.getUint32(byteOffset, true); if (version !== 1) { - throw new RuntimeError('Only Batched 3D Model version 1 is supported. Version ' + version + ' is not.'); + throw new RuntimeError('Only Geometry tile version 1 is supported. Version ' + version + ' is not.'); } byteOffset += sizeOfUint32; var byteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - var featureTableJsonByteLength = view.getUint32(byteOffset, true); + if (byteLength === 0) { + content._readyPromise.resolve(content); + return; + } + + var featureTableJSONByteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; + if (featureTableJSONByteLength === 0) { + throw new RuntimeError('Feature table must have a byte length greater than zero'); + } + var featureTableBinaryByteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - - var batchTableJsonByteLength = view.getUint32(byteOffset, true); + var batchTableJSONByteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - var batchTableBinaryByteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - var batchLength; - - // Legacy header #1: [batchLength] [batchTableByteLength] - // Legacy header #2: [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength] - // Current header: [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] - // If the header is in the first legacy format 'batchTableJsonByteLength' will be the start of the JSON string (a quotation mark) or the glTF magic. - // Accordingly its first byte will be either 0x22 or 0x67, and so the minimum uint32 expected is 0x22000000 = 570425344 = 570MB. It is unlikely that the feature table JSON will exceed this length. - // The check for the second legacy format is similar, except it checks 'batchTableBinaryByteLength' instead - if (batchTableJsonByteLength >= 570425344) { - // First legacy check - byteOffset -= sizeOfUint32 * 2; - batchLength = featureTableJsonByteLength; - batchTableJsonByteLength = featureTableBinaryByteLength; - batchTableBinaryByteLength = 0; - featureTableJsonByteLength = 0; - featureTableBinaryByteLength = 0; - Batched3DModel3DTileContent._deprecationWarning('b3dm-legacy-header', 'This b3dm header is using the legacy format [batchLength] [batchTableByteLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.'); - } else if (batchTableBinaryByteLength >= 570425344) { - // Second legacy check - byteOffset -= sizeOfUint32; - batchLength = batchTableJsonByteLength; - batchTableJsonByteLength = featureTableJsonByteLength; - batchTableBinaryByteLength = featureTableBinaryByteLength; - featureTableJsonByteLength = 0; - featureTableBinaryByteLength = 0; - Batched3DModel3DTileContent._deprecationWarning('b3dm-legacy-header', 'This b3dm header is using the legacy format [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.'); - } - - var featureTableJson; - if (featureTableJsonByteLength === 0) { - featureTableJson = { - BATCH_LENGTH : defaultValue(batchLength, 0) - }; - } else { - var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength); - featureTableJson = JSON.parse(featureTableString); - byteOffset += featureTableJsonByteLength; - } + var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJSONByteLength); + var featureTableJson = JSON.parse(featureTableString); + byteOffset += featureTableJSONByteLength; var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); byteOffset += featureTableBinaryByteLength; - var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); - - batchLength = featureTable.getGlobalProperty('BATCH_LENGTH'); - featureTable.featuresLength = batchLength; - var batchTableJson; var batchTableBinary; - if (batchTableJsonByteLength > 0) { + if (batchTableJSONByteLength > 0) { // PERFORMANCE_IDEA: is it possible to allocate this on-demand? Perhaps keep the // arraybuffer/string compressed in memory and then decompress it when it is first accessed. // // We could also make another request for it, but that would make the property set/get // API async, and would double the number of numbers in some cases. - var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength); + var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJSONByteLength); batchTableJson = JSON.parse(batchTableString); - byteOffset += batchTableJsonByteLength; + byteOffset += batchTableJSONByteLength; if (batchTableBinaryByteLength > 0) { // Has a batch table binary batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed batchTableBinary = new Uint8Array(batchTableBinary); - byteOffset += batchTableBinaryByteLength; } } - var batchTable = new Cesium3DTileBatchTable(content, batchLength, batchTableJson, batchTableBinary); + var numberOfBoxes = defaultValue(featureTableJson.BOXES_LENGTH, 0); + var numberOfCylinders = defaultValue(featureTableJson.CYLINDERS_LENGTH, 0); + var numberOfEllipsoids = defaultValue(featureTableJson.ELLIPSOIDS_LENGTH, 0); + var numberOfSpheres = defaultValue(featureTableJson.SPHERES_LENGTH, 0); + + var totalPrimitives = numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres; + + var batchTable = new Cesium3DTileBatchTable(content, totalPrimitives, batchTableJson, batchTableBinary, createColorChangedCallback(content)); content._batchTable = batchTable; - var gltfByteLength = byteStart + byteLength - byteOffset; - if (gltfByteLength === 0) { - throw new RuntimeError('glTF byte length must be greater than 0.'); + if (totalPrimitives === 0) { + return; } - var gltfView; - if (byteOffset % 4 === 0) { - gltfView = new Uint8Array(arrayBuffer, byteOffset, gltfByteLength); - } else { - // Create a copy of the glb so that it is 4-byte aligned - Batched3DModel3DTileContent._deprecationWarning('b3dm-glb-unaligned', 'The embedded glb is not aligned to a 4-byte boundary.'); - gltfView = new Uint8Array(uint8Array.subarray(byteOffset, byteOffset + gltfByteLength)); + var modelMatrix = content._tile.computedTransform; + + var center; + if (defined(featureTableJson.RTC_CENTER)) { + center = Cartesian3.unpack(featureTableJson.RTC_CENTER); + Matrix4.multiplyByPoint(modelMatrix, center, center); } - var pickObject = { - content : content, - primitive : tileset - }; + var batchIds = getBatchIds(featureTableJson, featureTableBinary); - // PERFORMANCE_IDEA: patch the shader on demand, e.g., the first time show/color changes. - // The pick shader still needs to be patched. - content._model = new Model({ - gltf : gltfView, - cull : false, // The model is already culled by 3D Tiles - releaseGltfJson : true, // Models are unique and will not benefit from caching so save memory - opaquePass : Pass.CESIUM_3D_TILE, // Draw opaque portions of the model during the 3D Tiles pass - basePath : basePath, - requestType : RequestType.TILES3D, - modelMatrix : tile.computedTransform, - upAxis : tileset._gltfUpAxis, - shadows: tileset.shadows, - debugWireframe: tileset.debugWireframe, - incrementallyLoadTextures : false, - vertexShaderLoaded : getVertexShaderCallback(content), - fragmentShaderLoaded : getFragmentShaderCallback(content), - uniformMapLoaded : batchTable.getUniformMapCallback(), - pickVertexShaderLoaded : getPickVertexShaderCallback(content), - pickFragmentShaderLoaded : batchTable.getPickFragmentShaderCallback(), - pickUniformMapLoaded : batchTable.getPickUniformMapCallback(), - addBatchIdToGeneratedShaders : (batchLength > 0), // If the batch table has values in it, generated shaders will need a batchId attribute - pickObject : pickObject, - clippingPlanes : new ClippingPlaneCollection({ - enabled : false - }) - }); + if (numberOfBoxes > 0 || numberOfCylinders > 0 || numberOfEllipsoids > 0 || numberOfSpheres > 0) { + var boxes; + var cylinders; + var ellipsoids; + var spheres; + + if (numberOfBoxes > 0) { + var boxesByteOffset = featureTableBinary.byteOffset + featureTableJson.BOXES.byteOffset; + boxes = new Float32Array(featureTableBinary.buffer, boxesByteOffset, Vector3DTileGeometry.packedBoxLength * numberOfBoxes); + } + + if (numberOfCylinders > 0) { + var cylindersByteOffset = featureTableBinary.byteOffset + featureTableJson.CYLINDERS.byteOffset; + cylinders = new Float32Array(featureTableBinary.buffer, cylindersByteOffset, Vector3DTileGeometry.packedCylinderLength * numberOfCylinders); + } + + if (numberOfEllipsoids > 0) { + var ellipsoidsByteOffset = featureTableBinary.byteOffset + featureTableJson.ELLIPSOIDS.byteOffset; + ellipsoids = new Float32Array(featureTableBinary.buffer, ellipsoidsByteOffset, Vector3DTileGeometry.packedEllipsoidLength * numberOfEllipsoids); + } - if (defined(tileset.clippingPlanes)) { - content._model.clippingPlanes = tileset.clippingPlanes.clone(); + if (numberOfSpheres > 0) { + var spheresByteOffset = featureTableBinary.byteOffset + featureTableJson.SPHERES.byteOffset; + spheres = new Float32Array(featureTableBinary.buffer, spheresByteOffset, Vector3DTileGeometry.packedSphereLength * numberOfSpheres); + } + + content._geometries = new Vector3DTileGeometry({ + boxes : boxes, + boxBatchIds : batchIds.boxes, + cylinders : cylinders, + cylinderBatchIds : batchIds.cylinders, + ellipsoids : ellipsoids, + ellipsoidBatchIds : batchIds.ellipsoids, + spheres : spheres, + sphereBatchIds : batchIds.spheres, + center : center, + modelMatrix : modelMatrix, + batchTable : batchTable, + boundingVolume : content._tile._boundingVolume.boundingVolume + }); } } function createFeatures(content) { - var tileset = content._tileset; var featuresLength = content.featuresLength; if (!defined(content._features) && (featuresLength > 0)) { var features = new Array(featuresLength); - for (var i = 0; i < featuresLength; ++i) { - features[i] = new Cesium3DTileFeature(tileset, content, i); + if (defined(content._geometries)) { + content._geometries.createFeatures(content, features); } content._features = features; } @@ -167256,14 +180765,14 @@ define('Scene/Batched3DModel3DTileContent',[ /** * @inheritdoc Cesium3DTileContent#hasProperty */ - Batched3DModel3DTileContent.prototype.hasProperty = function(batchId, name) { + Geometry3DTileContent.prototype.hasProperty = function(batchId, name) { return this._batchTable.hasProperty(batchId, name); }; /** * @inheritdoc Cesium3DTileContent#getFeature */ - Batched3DModel3DTileContent.prototype.getFeature = function(batchId) { + Geometry3DTileContent.prototype.getFeature = function(batchId) { var featuresLength = this.featuresLength; if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); @@ -167276,5328 +180785,5757 @@ define('Scene/Batched3DModel3DTileContent',[ /** * @inheritdoc Cesium3DTileContent#applyDebugSettings */ - Batched3DModel3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - color = enabled ? color : Color.WHITE; - if (this.featuresLength === 0) { - this._model.color = color; - } else { - this._batchTable.setAllColor(color); + Geometry3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + if (defined(this._geometries)) { + this._geometries.applyDebugSettings(enabled, color); } }; /** * @inheritdoc Cesium3DTileContent#applyStyle */ - Batched3DModel3DTileContent.prototype.applyStyle = function(frameState, style) { - this._batchTable.applyStyle(frameState, style); + Geometry3DTileContent.prototype.applyStyle = function(frameState, style) { + createFeatures(this); + if (defined(this._geometries)) { + this._geometries.applyStyle(frameState, style, this._features); + } }; /** * @inheritdoc Cesium3DTileContent#update */ - Batched3DModel3DTileContent.prototype.update = function(tileset, frameState) { - var commandStart = frameState.commandList.length; - - // In the PROCESSING state we may be calling update() to move forward - // the content's resource loading. In the READY state, it will - // actually generate commands. - this._batchTable.update(tileset, frameState); - this._model.modelMatrix = this._tile.computedTransform; - this._model.shadows = this._tileset.shadows; - this._model.debugWireframe = this._tileset.debugWireframe; - - // Update clipping planes - var tilesetClippingPlanes = this._tileset.clippingPlanes; - var modelClippingPlanes = this._model.clippingPlanes; - if (defined(tilesetClippingPlanes)) { - tilesetClippingPlanes.clone(modelClippingPlanes); - modelClippingPlanes.enabled = tilesetClippingPlanes.enabled && this._tile._isClipped; - } else if (defined(modelClippingPlanes) && modelClippingPlanes.enabled) { - modelClippingPlanes.enabled = false; + Geometry3DTileContent.prototype.update = function(tileset, frameState) { + if (defined(this._batchTable)) { + this._batchTable.update(tileset, frameState); + } + if (defined(this._geometries)) { + this._geometries.classificationType = this._tileset.classificationType; + this._geometries.debugWireframe = this._tileset.debugWireframe; + this._geometries.update(frameState); } - this._model.update(frameState); - - // If any commands were pushed, add derived commands - var commandEnd = frameState.commandList.length; - if ((commandStart < commandEnd) && frameState.passes.render) { - var finalResolution = this._tile._finalResolution; - this._batchTable.addDerivedCommands(frameState, commandStart, finalResolution); + if (!defined(this._contentReadyPromise)) { + var that = this; + this._contentReadyPromise = this._geometries.readyPromise.then(function() { + that._readyPromise.resolve(that); + }); } - }; + }; /** * @inheritdoc Cesium3DTileContent#isDestroyed */ - Batched3DModel3DTileContent.prototype.isDestroyed = function() { + Geometry3DTileContent.prototype.isDestroyed = function() { return false; }; /** * @inheritdoc Cesium3DTileContent#destroy */ - Batched3DModel3DTileContent.prototype.destroy = function() { - this._model = this._model && this._model.destroy(); + Geometry3DTileContent.prototype.destroy = function() { + this._geometries = this._geometries && this._geometries.destroy(); this._batchTable = this._batchTable && this._batchTable.destroy(); return destroyObject(this); }; - return Batched3DModel3DTileContent; + return Geometry3DTileContent; }); -define('Scene/BingMapsStyle',[ - '../Core/freezeObject' +define('Scene/ModelInstance',[ + '../Core/defineProperties', + '../Core/Matrix4' ], function( - freezeObject) { + defineProperties, + Matrix4) { 'use strict'; /** - * The types of imagery provided by Bing Maps. - * - * @exports BingMapsStyle - * - * @see BingMapsImageryProvider + * @private */ - var BingMapsStyle = { - /** - * Aerial imagery. - * - * @type {String} - * @constant - */ - AERIAL : 'Aerial', - - /** - * Aerial imagery with a road overlay. - * - * @type {String} - * @constant - */ - AERIAL_WITH_LABELS : 'AerialWithLabels', - - /** - * Roads without additional imagery. - * - * @type {String} - * @constant - */ - ROAD : 'Road', - - /** - * A dark version of the road maps. - * - * @type {String} - * @constant - */ - CANVAS_DARK : 'CanvasDark', - - /** - * A lighter version of the road maps. - * - * @type {String} - * @constant - */ - CANVAS_LIGHT : 'CanvasLight', - - /** - * A grayscale version of the road maps. - * - * @type {String} - * @constant - */ - CANVAS_GRAY : 'CanvasGray', - - /** - * Ordnance Survey imagery. This imagery is visible only for the London, UK area. - * - * @type {String} - * @constant - */ - ORDNANCE_SURVEY : 'OrdnanceSurvey', + function ModelInstance(collection, modelMatrix, instanceId) { + this.primitive = collection; + this._modelMatrix = Matrix4.clone(modelMatrix); + this._instanceId = instanceId; + } - /** - * Collins Bart imagery. - * - * @type {String} - * @constant - */ - COLLINS_BART : 'CollinsBart' - }; + defineProperties(ModelInstance.prototype, { + instanceId : { + get : function() { + return this._instanceId; + } + }, + model : { + get : function() { + return this.primitive._model; + } + }, + modelMatrix : { + get : function() { + return Matrix4.clone(this._modelMatrix); + }, + set : function(value) { + Matrix4.clone(value, this._modelMatrix); + this.primitive.expandBoundingSphere(this._modelMatrix); + this.primitive._dirty = true; + } + } + }); - return freezeObject(BingMapsStyle); + return ModelInstance; }); -define('Scene/BingMapsImageryProvider',[ - '../Core/BingMapsApi', - '../Core/Cartesian2', - '../Core/Credit', +define('Scene/ModelInstanceCollection',[ + '../Core/BoundingSphere', + '../Core/Cartesian3', + '../Core/clone', + '../Core/Color', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Event', - '../Core/loadJsonp', - '../Core/Math', - '../Core/Rectangle', + '../Core/Matrix4', + '../Core/PrimitiveType', + '../Core/Resource', '../Core/RuntimeError', - '../Core/TileProviderError', - '../Core/WebMercatorTilingScheme', + '../Core/Transforms', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/ShaderSource', '../ThirdParty/when', - './BingMapsStyle', - './DiscardMissingTileImagePolicy', - './ImageryProvider' + './Model', + './ModelInstance', + './ModelUtility', + './SceneMode', + './ShadowMode' ], function( - BingMapsApi, - Cartesian2, - Credit, + BoundingSphere, + Cartesian3, + clone, + Color, + ComponentDatatype, defaultValue, defined, defineProperties, + deprecationWarning, + destroyObject, DeveloperError, - Event, - loadJsonp, - CesiumMath, - Rectangle, + Matrix4, + PrimitiveType, + Resource, RuntimeError, - TileProviderError, - WebMercatorTilingScheme, + Transforms, + Buffer, + BufferUsage, + DrawCommand, + Pass, + ShaderSource, when, - BingMapsStyle, - DiscardMissingTileImagePolicy, - ImageryProvider) { + Model, + ModelInstance, + ModelUtility, + SceneMode, + ShadowMode) { 'use strict'; - /** - * Provides tiled imagery using the Bing Maps Imagery REST API. - * - * @alias BingMapsImageryProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url of the Bing Maps server hosting the imagery. - * @param {String} [options.key] The Bing Maps key for your application, which can be - * created at {@link https://www.bingmapsportal.com/}. - * If this parameter is not provided, {@link BingMapsApi.defaultKey} is used. - * If {@link BingMapsApi.defaultKey} is undefined as well, a message is - * written to the console reminding you that you must create and supply a Bing Maps - * key as soon as possible. Please do not deploy an application that uses - * Bing Maps imagery without creating a separate key for your application. - * @param {String} [options.tileProtocol] The protocol to use when loading tiles, e.g. 'http:' or 'https:'. - * By default, tiles are loaded using the same protocol as the page. - * @param {String} [options.mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps - * imagery to load. - * @param {String} [options.culture=''] The culture to use when requesting Bing Maps imagery. Not - * all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx} - * for information on the supported cultures. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile - * is invalid and should be discarded. If this value is not specified, a default - * {@link DiscardMissingTileImagePolicy} is used which requests - * tile 0,0 at the maximum tile level and checks pixels (0,0), (120,140), (130,160), - * (200,50), and (200,200). If all of these pixels are transparent, the discard check is - * disabled and no tiles are discarded. If any of them have a non-transparent color, any - * tile that has the same values in these pixel locations is discarded. The end result of - * these defaults should be correct tile discarding for a standard Bing Maps server. To ensure - * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this - * parameter. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * - * @see ArcGisMapServerImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider - * - * - * @example - * var bing = new Cesium.BingMapsImageryProvider({ - * url : 'https://dev.virtualearth.net', - * key : 'get-yours-at-https://www.bingmapsportal.com/', - * mapStyle : Cesium.BingMapsStyle.AERIAL - * }); - * - * @see {@link http://msdn.microsoft.com/en-us/library/ff701713.aspx|Bing Maps REST Services} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - */ - function BingMapsImageryProvider(options) { - options = defaultValue(options, {}); - - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); - } - - this._key = BingMapsApi.getKey(options.key); - this._keyErrorCredit = BingMapsApi.getErrorCredit(options.key); - - this._url = options.url; - this._tileProtocol = options.tileProtocol; - this._mapStyle = defaultValue(options.mapStyle, BingMapsStyle.AERIAL); - this._culture = defaultValue(options.culture, ''); - this._tileDiscardPolicy = options.tileDiscardPolicy; - this._proxy = options.proxy; - this._credit = new Credit({ - text: 'Bing Imagery', - imageUrl: BingMapsImageryProvider._logoData, - link: 'http://www.bing.com' - }); - - /** - * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider. - * Changing this value after creating an {@link ImageryLayer} for this provider will have - * no effect. Instead, set the layer's {@link ImageryLayer#gamma} property. - * - * @type {Number} - * @default 1.0 - */ - this.defaultGamma = 1.0; - - this._tilingScheme = new WebMercatorTilingScheme({ - numberOfLevelZeroTilesX : 2, - numberOfLevelZeroTilesY : 2, - ellipsoid : options.ellipsoid - }); - - this._tileWidth = undefined; - this._tileHeight = undefined; - this._maximumLevel = undefined; - this._imageUrlTemplate = undefined; - this._imageUrlSubdomains = undefined; - - this._errorEvent = new Event(); - - this._ready = false; - this._readyPromise = when.defer(); - - var metadataUrl = this._url + '/REST/v1/Imagery/Metadata/' + this._mapStyle + '?incl=ImageryProviders&key=' + this._key; - var that = this; - var metadataError; - - function metadataSuccess(data) { - var resource = data.resourceSets[0].resources[0]; - - that._tileWidth = resource.imageWidth; - that._tileHeight = resource.imageHeight; - that._maximumLevel = resource.zoomMax - 1; - that._imageUrlSubdomains = resource.imageUrlSubdomains; - that._imageUrlTemplate = resource.imageUrl.replace('{culture}', that._culture); - - var tileProtocol = that._tileProtocol; - if (!defined(tileProtocol)) { - // use the document's protocol, unless it's not http or https - var documentProtocol = document.location.protocol; - tileProtocol = /^http/.test(documentProtocol) ? documentProtocol : 'http:'; - } - - that._imageUrlTemplate = that._imageUrlTemplate.replace(/^http:/, tileProtocol); - - // Install the default tile discard policy if none has been supplied. - if (!defined(that._tileDiscardPolicy)) { - that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ - missingImageUrl : buildImageUrl(that, 0, 0, that._maximumLevel), - pixelsToCheck : [new Cartesian2(0, 0), new Cartesian2(120, 140), new Cartesian2(130, 160), new Cartesian2(200, 50), new Cartesian2(200, 200)], - disableCheckIfAllPixelsAreTransparent : true - }); - } - - var attributionList = that._attributionList = resource.imageryProviders; - if (!attributionList) { - attributionList = that._attributionList = []; - } - - for (var attributionIndex = 0, attributionLength = attributionList.length; attributionIndex < attributionLength; ++attributionIndex) { - var attribution = attributionList[attributionIndex]; - - attribution.credit = new Credit({ - text: attribution.attribution - }); - - var coverageAreas = attribution.coverageAreas; - - for (var areaIndex = 0, areaLength = attribution.coverageAreas.length; areaIndex < areaLength; ++areaIndex) { - var area = coverageAreas[areaIndex]; - var bbox = area.bbox; - area.bbox = new Rectangle( - CesiumMath.toRadians(bbox[1]), - CesiumMath.toRadians(bbox[0]), - CesiumMath.toRadians(bbox[3]), - CesiumMath.toRadians(bbox[2])); - } - } - - that._ready = true; - that._readyPromise.resolve(true); - TileProviderError.handleSuccess(metadataError); - } - - function metadataFailure(e) { - var message = 'An error occurred while accessing ' + metadataUrl + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - that._readyPromise.reject(new RuntimeError(message)); - } - - function requestMetadata() { - var metadata = loadJsonp(metadataUrl, { - callbackParameterName : 'jsonp', - proxy : that._proxy - }); - when(metadata, metadataSuccess, metadataFailure); - } - - requestMetadata(); - } - - defineProperties(BingMapsImageryProvider.prototype, { - /** - * Gets the name of the BingMaps server url hosting the imagery. - * @memberof BingMapsImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; - } - }, - - /** - * Gets the proxy used by this provider. - * @memberof BingMapsImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._proxy; - } - }, - - - /** - * Gets the Bing Maps key. - * @memberof BingMapsImageryProvider.prototype - * @type {String} - * @readonly - */ - key : { - get : function() { - return this._key; - } - }, - - /** - * Gets the type of Bing Maps imagery to load. - * @memberof BingMapsImageryProvider.prototype - * @type {BingMapsStyle} - * @readonly - */ - mapStyle : { - get : function() { - return this._mapStyle; - } - }, - - /** - * The culture to use when requesting Bing Maps imagery. Not - * all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx} - * for information on the supported cultures. - * @memberof BingMapsImageryProvider.prototype - * @type {String} - * @readonly - */ - culture : { - get : function() { - return this._culture; - } - }, - - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); - } - - return this._tileWidth; - } - }, - - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight: { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); - } - - return this._tileHeight; - } - }, - - - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); - } - - return this._maximumLevel; - } - }, - - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); - } - - return 0; - } - }, - - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme; - } - }, - - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - if (!this._ready) { - throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme.rectangle; - } - }, - - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); - } - - return this._tileDiscardPolicy; - } - }, - - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof BingMapsImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._errorEvent; - } - }, - - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof BingMapsImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, - - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof BingMapsImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; - } - }, - - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link BingMapsImageryProvider#ready} returns true. - * @memberof BingMapsImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return this._credit; - } - }, - - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage - * and texture upload time. - * @memberof BingMapsImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - hasAlphaChannel : { - get : function() { - return false; - } - } - }); - - var rectangleScratch = new Rectangle(); - - /** - * Gets the credits to be displayed when a given tile is displayed. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. - */ - BingMapsImageryProvider.prototype.getTileCredits = function(x, y, level) { - if (!this._ready) { - throw new DeveloperError('getTileCredits must not be called before the imagery provider is ready.'); - } - - var rectangle = this._tilingScheme.tileXYToRectangle(x, y, level, rectangleScratch); - var result = getRectangleAttribution(this._attributionList, level, rectangle); - - if (defined(this._keyErrorCredit)) { - result.push(this._keyErrorCredit); - } - - return result; - }; - - /** - * Requests the image for a given tile. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. - * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. - */ - BingMapsImageryProvider.prototype.requestImage = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); - } - - var url = buildImageUrl(this, x, y, level); - return ImageryProvider.loadImage(this, url, request); + var LoadState = { + NEEDS_LOAD : 0, + LOADING : 1, + LOADED : 2, + FAILED : 3 }; /** - * Picking features is not currently supported by this imagery provider, so this function simply returns - * undefined. + * A 3D model instance collection. All instances reference the same underlying model, but have unique + * per-instance properties like model matrix, pick id, etc. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. - */ - BingMapsImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return undefined; - }; - - BingMapsImageryProvider._logoData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAAaCAYAAAAEy1RnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3gIDEgcPTMnXOQAAClZJREFUWMPdWGtsFNcV/u689uH1+sXaONhlWQzBENtxiUFBpBSLd60IpXHSNig4URtSYQUkRJNSi0igViVVVBJBaBsiAgKRQJSG8AgEHCCWU4iBCprY2MSgXfOI16y9D3s9Mzsztz9yB12WNU2i9Ecy0tHOzN4793zn3POdcy7BnRfJ8I7iB3SRDPeEExswLz8Y0DZIAYDIRGAgLQAm+7Xle31J3L3Anp1MZPY+BUBjorN332vgYhpgV1FRUd6TTz45ubq6OtDV1SXpuu5g//Oept9wNwlMyAi8IXDjyF245TsDTdivDMATCATGNDU1/WbhwoWPTZs2bWx1dXWhx+Oxrl+/PqTrus5t9W8KWEzjinTAYhro/xuBStwiIgBnJBLxKIoy1u/3V/r9/krDMMz3339/Z3t7e38ikUgCMDLEt8W+Q0cAI3McYTDDmZxh7DESG5Ni43jg9Gsa+X+OsxWxPSJTSj3JZFK5ZRVJErOzs8e6XC4fgGwALhbzDgAKU1hK28KEA6PMmTMn56233qpevnz5PQDcbJ7EzVUAuMrLy3MBeABkcWOEDELSyFe4y7iMoHkriZZlKYZh8ASHZDKpJJPJHAC5APIA5APIAeBlCjo5TwlpXnbOmTPHP3fu3KZVq1atZKBcDJQ9x7V48WJfc3Pzhp6enj+tXLnyR8w4MjdG4gyVDk7KICMClzKlLUrpbQMNw5AkScppbGz8cWdn57WjR4/2caw+DEBlYjO8wX1foZQWuN3uKZIklQD4G+fhlG0Yl8uVm5WVVW6app6dne0D0G8vnxbjJntHubCUOK/badZICyWanrJuAaeUknTQpmlKkUhEWbx48U8LCwtHhUKha+fPn+85fPhwV0tLyzUACSZx9jvMFhIByNFoVDEMw/qKB5HPvJfkUqBr9+7deklJyZ/j8bi5ffv2OAslieMLsG+m2DybT2QuzEQOsF5SUqJfvXo1yc2l6Xn6rgSRSCSEc+fOhVeuXLmwoqJixvTp0wcWLFgQ7unpudHR0dF97ty5z/fu3XseQJh5adjeerquy5ZlCalUivh8Pt8HH3ywzOPxyD09PZ81NjZ+2NnZaQEQx40b54vFYqaqquEVK1b4a2tr/WvWrDn18ssv144fP36SqqoD69ev371nz57rDLwAwHHkyJGfjRs3rtowDOv06dOnu7q6rs6bN2/s7Nmz9zIjDKenWoFZKg/AlMLCwl82Nzf/m3LX22+/fXb06NF/ALC8u7u7m6ZdkUhksL29/UpLS0vzunXrVgAoBzAaQBGAiY2NjUui0ei1RCLRFwwG/9PX19cVi8WCqqoOdHd3HysrK6sDMCccDl8IBoOtiqIsOnbs2D+i0eiV3t7ez8Ph8GeRSKRT07TB/v7+i1OnTp0HYBqABzs7O/+paVo0Fot1RyKRi/F4/Gp/f39XIpHoZnoUMn6wU+ZtRDaymwmxZFk2AWjvvvvuJ/F4PMn/n5+fn1VeXu6fOXNmbU1NzUOM4Bz8QqIoyg6HwxuLxfq3bdu2a+vWrW/09/dfKy0tffDVV199BEC20+n0ud3uQgBup9Pp83g8JYqieE+ePPnxxo0bt33xxRen8/Ly7n3hhRcWASh47bXX5pWVldWFw+GuXbt27XjzzTd3BoPBDq/XG1AUZRRHmAKPVfqaoKkgCCkA+oYNG84Eg0FHTU1N5ezZs8eWlJQ4CSF8/LvZYhJPQoQQpFKpwcrKyo1su9HBwUF99erVv588eXINgOOmacIwDEopdaZSKUIpxYkTJz6sr68/BMBav379RcMwZk2aNOl+AP+qq6t7xDTNVEVFxR+j0WgSAJk4ceKlTz/9tNzpdHpZvIvpjVW6pykhhBJCbkvwgiAQQogEQL558ybdtGlTsLm5OWJZdxZmlmWll5OUEEJN0zSGhob6GcOrALSzZ8/2apqWcLlc2axGACNRkRAimqaph0Kh68xIwwB0y7IMSZKcABz5+fkl8Xj8y2g0apOb5na7rYGBgS/JV54Q0qpAAoBKaS0jBWClg1ZVFeFw2AlgVF1dXeDpp5+eWVFRUVpcXOzgvQwAbrcbDJhdudlGpKZpGtx6JCcnRxIEQbQsS2PjbjM+AMvlchnMSBaXkr7ymCCIhmEYfMoVRVESBEHI0CaTTNubssUsQRBuubCtra33pZdeCk6YMCGwZs2aipqaGn9paWmuJEl3JP0bN258eeTIkRMABrm0YomiaImiKGVlZeWxLecAgBkzZvgdDkfWjRs3ggA0bpfpoiiahBCqKEqKAy2yULMA6MlkMp6Xl3cP1x2SWCwmFhQU+CmlFhfHNFOevpX4LcvSJUkyAeDQoUOh119//fpTTz01Zf78+UWBQCBHUZQ7yE/TNGPfvn0n33vvvSP79+//BECMeZsCMGRZNgRBgNPpHHXx4sVVDQ0Nf1+wYMGYJ554YikAevDgwUMA4oIgQJZlSggZdDqdBiGEZGdn6ww0tQlJURTT4/EMHz9+/MCjjz7622AwuHbZsmVbiouLvWvXrm1wOp3ZqVRqaKQTIInf1gAMl8ulU0q1CxcuBGOxmL5u3bryQCDgycrKEjORXGtra8eOHTsOHz169OyVK1cuA+hlRYrGlNRkWR7UNO2mYRiaz+cb3dLS8gYhhOi6Hj116tSOVatWHQNALcsaME0zLghClBDSZ9+zQsZ2SoJS2udwOKLPPffcvsrKyrJAIPDQ/v37txiGofX19V3r7e29UlBQMHqEVpjwnrYA6PF4PK6q6s2qqqqpZWVlitvtljOB7enpiWzbtu3wgQMHTre1tV0E0MeKkkGuIhMAqHv37u30er3Px+NxlyiKygMPPOAnhFiXLl0Kbd68uYPNsXbu3Lk6mUwaqqr2btmyZUdtbe3hd955pwvAEFNcO3jw4K/b2tqiqqpGIpGI4/HHH/9rQ0PDCa/XOyoSidDLly8PNTU1PcZ4QuNK1ju6NYHFRAGASXPnzv1Fa2vrxzTDpapqateuXR/Nnz+/SVGUhwFMBzCBFSLZLF75DsrJGpXRAH4EIABgPIBxAEoBFAPwARjFif1sNzZ25+VlOhaxufcCqAFQC+BhAPVLliz5XSqVUkOhUAuAKWnFyR3dlsw+fg+A+8eMGfPzTZs2bY9GozEb8JkzZ9qXLl36l+Li4l8B+AmAyQDGsGrOzfXNPGPawG2l85jksmcPm+vihH+2W1iF3bvZPN+sWbPuGx4eDrW3t+85fvz41o6OjmZN04Y0TYvV19cvYIbN5QqUjG2mwj5YAqDK4XDMe+aZZ55vbW09+sorr2yuqqpqYFatAuBn3uB7XzJCY297XeaUd2RoGzOJmHb6IjFj5D777LP3DQwMfDw8PBxSVbUvkUj0hEKhj1588cXH2O7zMSPdplumoxveMx5Zlj3jx4/39vb26gMDA4MsvgYZo+p8Pr7LqQX5Ds/U7d0jFxUVZS1atKg4Nzc317Isp67rZldXV6y5ufkmI78hFtcmrx8ZweMit6XsUs4+6kmlgbW+peLf9gyMZNCR374G0y/FxEzX8b/8+bkXEBxKFwAAAABJRU5ErkJggg=='; - - /** - * Converts a tiles (x, y, level) position into a quadkey used to request an image - * from a Bing Maps server. + * Instances are rendered relative-to-center and for best results instances should be positioned close to one another. + * Otherwise there may be precision issues if, for example, instances are placed on opposite sides of the globe. * - * @param {Number} x The tile's x coordinate. - * @param {Number} y The tile's y coordinate. - * @param {Number} level The tile's zoom level. + * @alias ModelInstanceCollection + * @constructor * - * @see {@link http://msdn.microsoft.com/en-us/library/bb259689.aspx|Bing Maps Tile System} - * @see BingMapsImageryProvider#quadKeyToTileXY - */ - BingMapsImageryProvider.tileXYToQuadKey = function(x, y, level) { - var quadkey = ''; - for ( var i = level; i >= 0; --i) { - var bitmask = 1 << i; - var digit = 0; - - if ((x & bitmask) !== 0) { - digit |= 1; - } - - if ((y & bitmask) !== 0) { - digit |= 2; - } - - quadkey += digit; - } - return quadkey; - }; - - /** - * Converts a tile's quadkey used to request an image from a Bing Maps server into the - * (x, y, level) position. + * @param {Object} options Object with the following properties: + * @param {Object[]} [options.instances] An array of instances, where each instance contains a modelMatrix and optional batchId when options.batchTable is defined. + * @param {Cesium3DTileBatchTable} [options.batchTable] The batch table of the instanced 3D Tile. + * @param {Resource|String} [options.url] The url to the .gltf file. + * @param {Object} [options.requestType] The request type, used for request prioritization + * @param {Object|ArrayBuffer|Uint8Array} [options.gltf] The object for the glTF JSON or an arraybuffer of Binary glTF defined by the CESIUM_binary_glTF extension. + * @param {Resource|String} [options.basePath=''] The base path that paths in the glTF JSON are relative to. + * @param {Boolean} [options.dynamic=false] Hint if instance model matrices will be updated frequently. + * @param {Boolean} [options.show=true] Determines if the collection will be shown. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each instance is pickable with {@link Scene#pick}. + * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. + * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the collection casts or receives shadows from each light source. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for the collection. + * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the instances in wireframe. * - * @param {String} quadkey The tile's quad key + * @exception {DeveloperError} Must specify either <options.gltf> or <options.url>, but not both. + * @exception {DeveloperError} Shader program cannot be optimized for instancing. Parameters cannot have any of the following semantics: MODEL, MODELINVERSE, MODELVIEWINVERSE, MODELVIEWPROJECTIONINVERSE, MODELINVERSETRANSPOSE. * - * @see {@link http://msdn.microsoft.com/en-us/library/bb259689.aspx|Bing Maps Tile System} - * @see BingMapsImageryProvider#tileXYToQuadKey + * @private */ - BingMapsImageryProvider.quadKeyToTileXY = function(quadkey) { - var x = 0; - var y = 0; - var level = quadkey.length - 1; - for ( var i = level; i >= 0; --i) { - var bitmask = 1 << i; - var digit = +quadkey[level - i]; - - if ((digit & 1) !== 0) { - x |= bitmask; - } + function ModelInstanceCollection(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if ((digit & 2) !== 0) { - y |= bitmask; - } + if (!defined(options.gltf) && !defined(options.url)) { + throw new DeveloperError('Either options.gltf or options.url is required.'); } - return { - x : x, - y : y, - level : level - }; - }; - - function buildImageUrl(imageryProvider, x, y, level) { - var imageUrl = imageryProvider._imageUrlTemplate; - - var quadkey = BingMapsImageryProvider.tileXYToQuadKey(x, y, level); - imageUrl = imageUrl.replace('{quadkey}', quadkey); - var subdomains = imageryProvider._imageUrlSubdomains; - var subdomainIndex = (x + y + level) % subdomains.length; - imageUrl = imageUrl.replace('{subdomain}', subdomains[subdomainIndex]); - - var proxy = imageryProvider._proxy; - if (defined(proxy)) { - imageUrl = proxy.getURL(imageUrl); + if (defined(options.gltf) && defined(options.url)) { + throw new DeveloperError('Cannot pass in both options.gltf and options.url.'); } + + this.show = defaultValue(options.show, true); - return imageUrl; - } - - var intersectionScratch = new Rectangle(); + this._instancingSupported = false; + this._dynamic = defaultValue(options.dynamic, false); + this._allowPicking = defaultValue(options.allowPicking, true); + this._ready = false; + this._readyPromise = when.defer(); + this._state = LoadState.NEEDS_LOAD; + this._dirty = false; - function getRectangleAttribution(attributionList, level, rectangle) { - // Bing levels start at 1, while ours start at 0. - ++level; + // Undocumented options + this._cull = defaultValue(options.cull, true); + this._opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); - var result = []; + this._instances = createInstances(this, options.instances); - for (var attributionIndex = 0, attributionLength = attributionList.length; attributionIndex < attributionLength; ++attributionIndex) { - var attribution = attributionList[attributionIndex]; - var coverageAreas = attribution.coverageAreas; + // When the model instance collection is backed by an i3dm tile, + // use its batch table resources to modify the shaders, attributes, and uniform maps. + this._batchTable = options.batchTable; - var included = false; + this._model = undefined; + this._vertexBufferTypedArray = undefined; // Hold onto the vertex buffer contents when dynamic is true + this._vertexBuffer = undefined; + this._batchIdBuffer = undefined; + this._instancedUniformsByProgram = undefined; - for (var areaIndex = 0, areaLength = attribution.coverageAreas.length; !included && areaIndex < areaLength; ++areaIndex) { - var area = coverageAreas[areaIndex]; - if (level >= area.zoomMin && level <= area.zoomMax) { - var intersection = Rectangle.intersection(rectangle, area.bbox, intersectionScratch); - if (defined(intersection)) { - included = true; - } - } - } + this._drawCommands = []; + this._pickCommands = []; + this._modelCommands = undefined; - if (included) { - result.push(attribution.credit); - } - } + this._boundingSphere = createBoundingSphere(this); + this._center = Cartesian3.clone(this._boundingSphere.center); + this._rtcTransform = new Matrix4(); + this._rtcModelView = new Matrix4(); // Holds onto uniform - return result; - } + this._mode = undefined; - return BingMapsImageryProvider; -}); + this.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + this._modelMatrix = Matrix4.clone(this.modelMatrix); -define('Scene/BoxEmitter',[ - '../Core/Cartesian3', - '../Core/Check', - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/Math' - ], function( - Cartesian3, - Check, - defaultValue, - defineProperties, - CesiumMath) { - 'use strict'; + // Passed on to Model + this._url = Resource.createIfNeeded(options.url); + this._requestType = options.requestType; + this._gltf = options.gltf; + this._basePath = Resource.createIfNeeded(options.basePath); + this._asynchronous = options.asynchronous; + this._incrementallyLoadTextures = options.incrementallyLoadTextures; + this._upAxis = options.upAxis; // Undocumented option - var defaultDimensions = new Cartesian3(1.0, 1.0, 1.0); + this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); + this._shadows = this.shadows; - /** - * A ParticleEmitter that emits particles within a box. - * Particles will be positioned randomly within the box and have initial velocities emanating from the center of the box. - * - * @alias BoxEmitter - * @constructor - * - * @param {Cartesian3} dimensions The width, height and depth dimensions of the box. - */ - function BoxEmitter(dimensions) { - dimensions = defaultValue(dimensions, defaultDimensions); + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + this._debugShowBoundingVolume = false; - Check.defined('dimensions', dimensions); - Check.typeOf.number.greaterThanOrEquals('dimensions.x', dimensions.x, 0.0); - Check.typeOf.number.greaterThanOrEquals('dimensions.y', dimensions.y, 0.0); - Check.typeOf.number.greaterThanOrEquals('dimensions.z', dimensions.z, 0.0); - - this._dimensions = Cartesian3.clone(dimensions); + this.debugWireframe = defaultValue(options.debugWireframe, false); + this._debugWireframe = false; } - defineProperties(BoxEmitter.prototype, { - /** - * The width, height and depth dimensions of the box in meters. - * @memberof BoxEmitter.prototype - * @type {Cartesian3} - * @default new Cartesian3(1.0, 1.0, 1.0) - */ - dimensions : { + defineProperties(ModelInstanceCollection.prototype, { + allowPicking : { get : function() { - return this._dimensions; - }, - set : function(value) { - Check.defined('value', value); - Check.typeOf.number.greaterThanOrEquals('value.x', value.x, 0.0); - Check.typeOf.number.greaterThanOrEquals('value.y', value.y, 0.0); - Check.typeOf.number.greaterThanOrEquals('value.z', value.z, 0.0); - Cartesian3.clone(value, this._dimensions); + return this._allowPicking; + } + }, + length : { + get : function() { + return this._instances.length; + } + }, + activeAnimations : { + get : function() { + return this._model.activeAnimations; + } + }, + ready : { + get : function() { + return this._ready; + } + }, + readyPromise : { + get : function() { + return this._readyPromise.promise; } } - }); - var scratchHalfDim = new Cartesian3(); + function createInstances(collection, instancesOptions) { + instancesOptions = defaultValue(instancesOptions, []); + var length = instancesOptions.length; + var instances = new Array(length); + for (var i = 0; i < length; ++i) { + var instanceOptions = instancesOptions[i]; + var modelMatrix = instanceOptions.modelMatrix; + var instanceId = defaultValue(instanceOptions.batchId, i); + instances[i] = new ModelInstance(collection, modelMatrix, instanceId); + } + return instances; + } - /** - * Initializes the given {Particle} by setting it's position and velocity. - * - * @private - * @param {Particle} particle The particle to initialize. - */ - BoxEmitter.prototype.emit = function(particle) { - var dim = this._dimensions; - var halfDim = Cartesian3.multiplyByScalar(dim, 0.5, scratchHalfDim); + function createBoundingSphere(collection) { + var instancesLength = collection.length; + var points = new Array(instancesLength); + for (var i = 0; i < instancesLength; ++i) { + points[i] = Matrix4.getTranslation(collection._instances[i]._modelMatrix, new Cartesian3()); + } - var x = CesiumMath.randomBetween(-halfDim.x, halfDim.x); - var y = CesiumMath.randomBetween(-halfDim.y, halfDim.y); - var z = CesiumMath.randomBetween(-halfDim.z, halfDim.z); + return BoundingSphere.fromPoints(points); + } - particle.position = Cartesian3.fromElements(x, y, z, particle.position); - particle.velocity = Cartesian3.normalize(particle.position, particle.velocity); + var scratchCartesian = new Cartesian3(); + var scratchMatrix = new Matrix4(); + + ModelInstanceCollection.prototype.expandBoundingSphere = function(instanceModelMatrix) { + var translation = Matrix4.getTranslation(instanceModelMatrix, scratchCartesian); + BoundingSphere.expand(this._boundingSphere, translation, this._boundingSphere); }; - return BoxEmitter; -}); + function getInstancedUniforms(collection, programId) { + if (defined(collection._instancedUniformsByProgram)) { + return collection._instancedUniformsByProgram[programId]; + } -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/BrdfLutGeneratorFS',[],function() { - 'use strict'; - return "varying vec2 v_textureCoordinates;\n\ -const float M_PI = 3.141592653589793;\n\ -float vdcRadicalInverse(int i)\n\ -{\n\ -float r;\n\ -float base = 2.0;\n\ -float value = 0.0;\n\ -float invBase = 1.0 / base;\n\ -float invBi = invBase;\n\ -for (int x = 0; x < 100; x++)\n\ -{\n\ -if (i <= 0)\n\ -{\n\ -break;\n\ -}\n\ -r = mod(float(i), base);\n\ -value += r * invBi;\n\ -invBi *= invBase;\n\ -i = int(float(i) * invBase);\n\ -}\n\ -return value;\n\ -}\n\ -vec2 hammersley2D(int i, int N)\n\ -{\n\ -return vec2(float(i) / float(N), vdcRadicalInverse(i));\n\ -}\n\ -vec3 importanceSampleGGX(vec2 xi, float roughness, vec3 N)\n\ -{\n\ -float a = roughness * roughness;\n\ -float phi = 2.0 * M_PI * xi.x;\n\ -float cosTheta = sqrt((1.0 - xi.y) / (1.0 + (a * a - 1.0) * xi.y));\n\ -float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n\ -vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);\n\ -vec3 upVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n\ -vec3 tangentX = normalize(cross(upVector, N));\n\ -vec3 tangentY = cross(N, tangentX);\n\ -return tangentX * H.x + tangentY * H.y + N * H.z;\n\ -}\n\ -float G1_Smith(float NdotV, float k)\n\ -{\n\ -return NdotV / (NdotV * (1.0 - k) + k);\n\ -}\n\ -float G_Smith(float roughness, float NdotV, float NdotL)\n\ -{\n\ -float k = roughness * roughness / 2.0;\n\ -return G1_Smith(NdotV, k) * G1_Smith(NdotL, k);\n\ -}\n\ -vec2 integrateBrdf(float roughness, float NdotV)\n\ -{\n\ -vec3 V = vec3(sqrt(1.0 - NdotV * NdotV), 0.0, NdotV);\n\ -float A = 0.0;\n\ -float B = 0.0;\n\ -const int NumSamples = 1024;\n\ -for (int i = 0; i < NumSamples; i++)\n\ -{\n\ -vec2 xi = hammersley2D(i, NumSamples);\n\ -vec3 H = importanceSampleGGX(xi, roughness, vec3(0.0, 0.0, 1.0));\n\ -vec3 L = 2.0 * dot(V, H) * H - V;\n\ -float NdotL = clamp(L.z, 0.0, 1.0);\n\ -float NdotH = clamp(H.z, 0.0, 1.0);\n\ -float VdotH = clamp(dot(V, H), 0.0, 1.0);\n\ -if (NdotL > 0.0)\n\ -{\n\ -float G = G_Smith(roughness, NdotV, NdotL);\n\ -float G_Vis = G * VdotH / (NdotH * NdotV);\n\ -float Fc = pow(1.0 - VdotH, 5.0);\n\ -A += (1.0 - Fc) * G_Vis;\n\ -B += Fc * G_Vis;\n\ -}\n\ -}\n\ -return vec2(A, B) / float(NumSamples);\n\ -}\n\ -void main()\n\ -{\n\ -gl_FragColor = vec4(integrateBrdf(1.0 - v_textureCoordinates.y, v_textureCoordinates.x), 0.0, 1.0);\n\ -}\n\ -"; -}); -define('Scene/BrdfLutGenerator',[ - '../Core/BoundingRectangle', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/PixelFormat', - '../Renderer/Framebuffer', - '../Renderer/PixelDatatype', - '../Renderer/RenderState', - '../Renderer/Sampler', - '../Renderer/Texture', - '../Renderer/TextureMagnificationFilter', - '../Renderer/TextureMinificationFilter', - '../Renderer/TextureWrap', - '../Shaders/BrdfLutGeneratorFS' - ], function( - BoundingRectangle, - defined, - defineProperties, - destroyObject, - PixelFormat, - Framebuffer, - PixelDatatype, - RenderState, - Sampler, - Texture, - TextureMagnificationFilter, - TextureMinificationFilter, - TextureWrap, - BrdfLutGeneratorFS) { - 'use strict'; + var instancedUniformsByProgram = {}; + collection._instancedUniformsByProgram = instancedUniformsByProgram; - /** - * @private - */ - function BrdfLutGenerator() { - this._framebuffer = undefined; - this._colorTexture = undefined; - this._drawCommand = undefined; - } + // When using CESIUM_RTC_MODELVIEW the CESIUM_RTC center is ignored. Instances are always rendered relative-to-center. + var modelSemantics = ['MODEL', 'MODELVIEW', 'CESIUM_RTC_MODELVIEW', 'MODELVIEWPROJECTION', 'MODELINVERSE', 'MODELVIEWINVERSE', 'MODELVIEWPROJECTIONINVERSE', 'MODELINVERSETRANSPOSE', 'MODELVIEWINVERSETRANSPOSE']; + var supportedSemantics = ['MODELVIEW', 'CESIUM_RTC_MODELVIEW', 'MODELVIEWPROJECTION', 'MODELVIEWINVERSETRANSPOSE']; - defineProperties(BrdfLutGenerator.prototype, { - colorTexture : { - get : function() { - return this._colorTexture; + var gltf = collection._model.gltf; + var techniques = gltf.techniques; + for (var techniqueName in techniques) { + if (techniques.hasOwnProperty(techniqueName)) { + var technique = techniques[techniqueName]; + var parameters = technique.parameters; + var uniforms = technique.uniforms; + var program = technique.program; + + // Different techniques may share the same program, skip if already processed. + // This assumes techniques that share a program do not declare different semantics for the same uniforms. + if (!defined(instancedUniformsByProgram[program])) { + var uniformMap = {}; + instancedUniformsByProgram[program] = uniformMap; + for (var uniformName in uniforms) { + if (uniforms.hasOwnProperty(uniformName)) { + var parameterName = uniforms[uniformName]; + var parameter = parameters[parameterName]; + var semantic = parameter.semantic; + if (defined(semantic) && (modelSemantics.indexOf(semantic) > -1)) { + if (supportedSemantics.indexOf(semantic) > -1) { + uniformMap[uniformName] = semantic; + } else { + throw new RuntimeError('Shader program cannot be optimized for instancing. ' + + 'Parameter "' + parameter + '" in program "' + programId + + '" uses unsupported semantic "' + semantic + '"' + ); + } + } + } + } + } } } - }); - function createCommand(generator, context) { - var framebuffer = generator._framebuffer; + return instancedUniformsByProgram[programId]; + } - var drawCommand = context.createViewportQuadCommand(BrdfLutGeneratorFS, { - framebuffer : framebuffer, - renderState : RenderState.fromCache({ - viewport : new BoundingRectangle(0.0, 0.0, 256.0, 256.0) - }) - }); + var vertexShaderCached; - generator._drawCommand = drawCommand; - } + function getVertexShaderCallback(collection) { + return function(vs, programId) { + var instancedUniforms = getInstancedUniforms(collection, programId); + var usesBatchTable = defined(collection._batchTable); - function createFramebuffer(generator, context) { - var colorTexture = new Texture({ - context : context, - width : 256, - height: 256, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, - sampler : new Sampler({ - wrapS : TextureWrap.CLAMP_TO_EDGE, - wrapT : TextureWrap.CLAMP_TO_EDGE, - minificationFilter : TextureMinificationFilter.NEAREST, - magnificationFilter : TextureMagnificationFilter.NEAREST - }) - }); + var renamedSource = ShaderSource.replaceMain(vs, 'czm_instancing_main'); - generator._colorTexture = colorTexture; + var globalVarsHeader = ''; + var globalVarsMain = ''; + for (var uniform in instancedUniforms) { + if (instancedUniforms.hasOwnProperty(uniform)) { + var semantic = instancedUniforms[uniform]; + var varName; + if (semantic === 'MODELVIEW' || semantic === 'CESIUM_RTC_MODELVIEW') { + varName = 'czm_instanced_modelView'; + } else if (semantic === 'MODELVIEWPROJECTION') { + varName = 'czm_instanced_modelViewProjection'; + globalVarsHeader += 'mat4 czm_instanced_modelViewProjection;\n'; + globalVarsMain += 'czm_instanced_modelViewProjection = czm_projection * czm_instanced_modelView;\n'; + } else if (semantic === 'MODELVIEWINVERSETRANSPOSE') { + varName = 'czm_instanced_modelViewInverseTranspose'; + globalVarsHeader += 'mat3 czm_instanced_modelViewInverseTranspose;\n'; + globalVarsMain += 'czm_instanced_modelViewInverseTranspose = mat3(czm_instanced_modelView);\n'; + } - var framebuffer = new Framebuffer({ - context : context, - colorTextures : [colorTexture], - destroyAttachments : false - }); + // Remove the uniform declaration + var regex = new RegExp('uniform.*' + uniform + '.*'); + renamedSource = renamedSource.replace(regex, ''); - generator._framebuffer = framebuffer; - } + // Replace all occurrences of the uniform with the global variable + regex = new RegExp(uniform + '\\b', 'g'); + renamedSource = renamedSource.replace(regex, varName); + } + } - BrdfLutGenerator.prototype.update = function(frameState) { - if (!defined(this._colorTexture)) { - var context = frameState.context; + // czm_instanced_model is the model matrix of the instance relative to center + // czm_instanced_modifiedModelView is the transform from the center to view + // czm_instanced_nodeTransform is the local offset of the node within the model + var uniforms = + 'uniform mat4 czm_instanced_modifiedModelView;\n' + + 'uniform mat4 czm_instanced_nodeTransform;\n'; - createFramebuffer(this, context); - createCommand(this, context); - this._drawCommand.execute(context); - this._framebuffer = this._framebuffer && this._framebuffer.destroy(); - this._drawCommand.shaderProgram = this._drawCommand.shaderProgram && this._drawCommand.shaderProgram.destroy(); - } - }; + var batchIdAttribute = usesBatchTable ? 'attribute float a_batchId;\n' : ''; - BrdfLutGenerator.prototype.isDestroyed = function() { - return false; - }; + var instancedSource = + uniforms + + globalVarsHeader + + 'mat4 czm_instanced_modelView;\n' + + 'attribute vec4 czm_modelMatrixRow0;\n' + + 'attribute vec4 czm_modelMatrixRow1;\n' + + 'attribute vec4 czm_modelMatrixRow2;\n' + + batchIdAttribute + + renamedSource + + 'void main()\n' + + '{\n' + + ' mat4 czm_instanced_model = mat4(czm_modelMatrixRow0.x, czm_modelMatrixRow1.x, czm_modelMatrixRow2.x, 0.0, czm_modelMatrixRow0.y, czm_modelMatrixRow1.y, czm_modelMatrixRow2.y, 0.0, czm_modelMatrixRow0.z, czm_modelMatrixRow1.z, czm_modelMatrixRow2.z, 0.0, czm_modelMatrixRow0.w, czm_modelMatrixRow1.w, czm_modelMatrixRow2.w, 1.0);\n' + + ' czm_instanced_modelView = czm_instanced_modifiedModelView * czm_instanced_model * czm_instanced_nodeTransform;\n' + + globalVarsMain + + ' czm_instancing_main();\n' + + '}'; - BrdfLutGenerator.prototype.destroy = function() { - this._colorTexture = this._colorTexture && this._colorTexture.destroy(); - return destroyObject(this); - }; + vertexShaderCached = instancedSource; - return BrdfLutGenerator; -}); + if (usesBatchTable) { + var gltf = collection._model.gltf; + var diffuseAttributeOrUniformName = ModelUtility.getDiffuseAttributeOrUniform(gltf, programId); + instancedSource = collection._batchTable.getVertexShaderCallback(true, 'a_batchId', diffuseAttributeOrUniformName)(instancedSource); + } -define('Scene/CameraFlightPath',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/defaultValue', - '../Core/defined', - '../Core/DeveloperError', - '../Core/EasingFunction', - '../Core/Math', - '../Core/PerspectiveFrustum', - '../Core/PerspectiveOffCenterFrustum', - './SceneMode' - ], function( - Cartesian2, - Cartesian3, - Cartographic, - defaultValue, - defined, - DeveloperError, - EasingFunction, - CesiumMath, - PerspectiveFrustum, - PerspectiveOffCenterFrustum, - SceneMode) { - 'use strict'; + return instancedSource; + }; + } - /** - * Creates tweens for camera flights. - * <br /><br /> - * Mouse interaction is disabled during flights. - * - * @private - */ - var CameraFlightPath = { - }; + function getFragmentShaderCallback(collection) { + return function(fs, programId) { + var batchTable = collection._batchTable; + if (defined(batchTable)) { + var gltf = collection._model.gltf; + var diffuseAttributeOrUniformName = ModelUtility.getDiffuseAttributeOrUniform(gltf, programId); + fs = batchTable.getFragmentShaderCallback(true, diffuseAttributeOrUniformName)(fs); + } + return fs; + }; + } - function getAltitude(frustum, dx, dy) { - var near; - var top; - var right; - if (frustum instanceof PerspectiveFrustum) { - var tanTheta = Math.tan(0.5 * frustum.fovy); - near = frustum.near; - top = frustum.near * tanTheta; - right = frustum.aspectRatio * top; - return Math.max(dx * near / right, dy * near / top); - } else if (frustum instanceof PerspectiveOffCenterFrustum) { - near = frustum.near; - top = frustum.top; - right = frustum.right; - return Math.max(dx * near / right, dy * near / top); - } + function getPickVertexShaderCallback(collection) { + return function (vs) { + // Use the vertex shader that was generated earlier + vs = vertexShaderCached; + var usesBatchTable = defined(collection._batchTable); + var allowPicking = collection._allowPicking; + if (usesBatchTable) { + vs = collection._batchTable.getPickVertexShaderCallback('a_batchId')(vs); + } else if (allowPicking) { + vs = ShaderSource.createPickVertexShaderSource(vs); + } + return vs; + }; + } - return Math.max(dx, dy); + function getPickFragmentShaderCallback(collection) { + return function(fs) { + var usesBatchTable = defined(collection._batchTable); + var allowPicking = collection._allowPicking; + if (usesBatchTable) { + fs = collection._batchTable.getPickFragmentShaderCallback()(fs); + } else if (allowPicking) { + fs = ShaderSource.createPickFragmentShaderSource(fs, 'varying'); + } + return fs; + }; } - var scratchCart = new Cartesian3(); - var scratchCart2 = new Cartesian3(); + function createModifiedModelView(collection, context) { + return function() { + return Matrix4.multiply(context.uniformState.view, collection._rtcTransform, collection._rtcModelView); + }; + } - function createPitchFunction(startPitch, endPitch, heightFunction, pitchAdjustHeight) { - if (defined(pitchAdjustHeight) && heightFunction(0.5) > pitchAdjustHeight) { - var startHeight = heightFunction(0.0); - var endHeight = heightFunction(1.0); - var middleHeight = heightFunction(0.5); + function createNodeTransformFunction(node) { + return function() { + return node.computedMatrix; + }; + } - var d1 = middleHeight - startHeight; - var d2 = middleHeight - endHeight; + function getUniformMapCallback(collection, context) { + return function(uniformMap, programId, node) { + uniformMap = clone(uniformMap); + uniformMap.czm_instanced_modifiedModelView = createModifiedModelView(collection, context); + uniformMap.czm_instanced_nodeTransform = createNodeTransformFunction(node); - return function(time) { - var altitude = heightFunction(time); - if (time <= 0.5) { - var t1 = (altitude - startHeight) / d1; - return CesiumMath.lerp(startPitch, -CesiumMath.PI_OVER_TWO, t1); + // Remove instanced uniforms from the uniform map + var instancedUniforms = getInstancedUniforms(collection, programId); + for (var uniform in instancedUniforms) { + if (instancedUniforms.hasOwnProperty(uniform)) { + delete uniformMap[uniform]; } + } - var t2 = (altitude - endHeight) / d2; - return CesiumMath.lerp(-CesiumMath.PI_OVER_TWO, endPitch, 1 - t2); - }; - } - return function(time) { - return CesiumMath.lerp(startPitch, endPitch, time); + if (defined(collection._batchTable)) { + uniformMap = collection._batchTable.getUniformMapCallback()(uniformMap); + } + + return uniformMap; }; } - function createHeightFunction(camera, destination, startHeight, endHeight, optionAltitude) { - var altitude = optionAltitude; - var maxHeight = Math.max(startHeight, endHeight); - - if (!defined(altitude)) { - var start = camera.position; - var end = destination; - var up = camera.up; - var right = camera.right; - var frustum = camera.frustum; - - var diff = Cartesian3.subtract(start, end, scratchCart); - var verticalDistance = Cartesian3.magnitude(Cartesian3.multiplyByScalar(up, Cartesian3.dot(diff, up), scratchCart2)); - var horizontalDistance = Cartesian3.magnitude(Cartesian3.multiplyByScalar(right, Cartesian3.dot(diff, right), scratchCart2)); + function getPickUniformMapCallback(collection) { + return function(uniformMap) { + // Uses the uniform map generated from getUniformMapCallback + if (defined(collection._batchTable)) { + uniformMap = collection._batchTable.getPickUniformMapCallback()(uniformMap); + } + return uniformMap; + }; + } - altitude = Math.min(getAltitude(frustum, verticalDistance, horizontalDistance) * 0.20, 1000000000.0); - } + function getVertexShaderNonInstancedCallback(collection) { + return function(vs, programId) { + if (defined(collection._batchTable)) { + var gltf = collection._model.gltf; + var diffuseAttributeOrUniformName = ModelUtility.getDiffuseAttributeOrUniform(gltf, programId); + vs = collection._batchTable.getVertexShaderCallback(true, 'a_batchId', diffuseAttributeOrUniformName)(vs); + // Treat a_batchId as a uniform rather than a vertex attribute + vs = 'uniform float a_batchId\n;' + vs; + } + return vs; + }; + } - if (maxHeight < altitude) { - var power = 8.0; - var factor = 1000000.0; + function getPickVertexShaderNonInstancedCallback(collection) { + return function(vs) { + if (defined(collection._batchTable)) { + vs = collection._batchTable.getPickVertexShaderCallback('a_batchId')(vs); + // Treat a_batchId as a uniform rather than a vertex attribute + vs = 'uniform float a_batchId\n;' + vs; + } + return vs; + }; + } - var s = -Math.pow((altitude - startHeight) * factor, 1.0 / power); - var e = Math.pow((altitude - endHeight) * factor, 1.0 / power); + function getPickFragmentShaderNonInstancedCallback(collection) { + return function(fs) { + var usesBatchTable = defined(collection._batchTable); + var allowPicking = collection._allowPicking; + if (usesBatchTable) { + fs = collection._batchTable.getPickFragmentShaderCallback()(fs); + } else if (allowPicking) { + fs = ShaderSource.createPickFragmentShaderSource(fs, 'uniform'); + } + return fs; + }; + } - return function(t) { - var x = t * (e - s) + s; - return -Math.pow(x, power) / factor + altitude; - }; - } + function getUniformMapNonInstancedCallback(collection) { + return function(uniformMap) { + if (defined(collection._batchTable)) { + uniformMap = collection._batchTable.getUniformMapCallback()(uniformMap); + } - return function(t) { - return CesiumMath.lerp(startHeight, endHeight, t); + return uniformMap; }; } - function adjustAngleForLERP(startAngle, endAngle) { - if (CesiumMath.equalsEpsilon(startAngle, CesiumMath.TWO_PI, CesiumMath.EPSILON11)) { - startAngle = 0.0; - } + function getVertexBufferTypedArray(collection) { + var instances = collection._instances; + var instancesLength = collection.length; + var collectionCenter = collection._center; + var vertexSizeInFloats = 12; - if (endAngle > startAngle + Math.PI) { - startAngle += CesiumMath.TWO_PI; - } else if (endAngle < startAngle - Math.PI) { - startAngle -= CesiumMath.TWO_PI; + var bufferData = collection._vertexBufferTypedArray; + if (!defined(bufferData)) { + bufferData = new Float32Array(instancesLength * vertexSizeInFloats); + } + if (collection._dynamic) { + // Hold onto the buffer data so we don't have to allocate new memory every frame. + collection._vertexBufferTypedArray = bufferData; } - return startAngle; - } + for (var i = 0; i < instancesLength; ++i) { + var modelMatrix = instances[i]._modelMatrix; - var scratchStart = new Cartesian3(); + // Instance matrix is relative to center + var instanceMatrix = Matrix4.clone(modelMatrix, scratchMatrix); + instanceMatrix[12] -= collectionCenter.x; + instanceMatrix[13] -= collectionCenter.y; + instanceMatrix[14] -= collectionCenter.z; - function createUpdateCV(scene, duration, destination, heading, pitch, roll, optionAltitude) { - var camera = scene.camera; + var offset = i * vertexSizeInFloats; - var start = Cartesian3.clone(camera.position, scratchStart); - var startPitch = camera.pitch; - var startHeading = adjustAngleForLERP(camera.heading, heading); - var startRoll = adjustAngleForLERP(camera.roll, roll); + // First three rows of the model matrix + bufferData[offset + 0] = instanceMatrix[0]; + bufferData[offset + 1] = instanceMatrix[4]; + bufferData[offset + 2] = instanceMatrix[8]; + bufferData[offset + 3] = instanceMatrix[12]; + bufferData[offset + 4] = instanceMatrix[1]; + bufferData[offset + 5] = instanceMatrix[5]; + bufferData[offset + 6] = instanceMatrix[9]; + bufferData[offset + 7] = instanceMatrix[13]; + bufferData[offset + 8] = instanceMatrix[2]; + bufferData[offset + 9] = instanceMatrix[6]; + bufferData[offset + 10] = instanceMatrix[10]; + bufferData[offset + 11] = instanceMatrix[14]; + } - var heightFunction = createHeightFunction(camera, destination, start.z, destination.z, optionAltitude); + return bufferData; + } - function update(value) { - var time = value.time / duration; + function createVertexBuffer(collection, context) { + var i; + var instances = collection._instances; + var instancesLength = collection.length; + var dynamic = collection._dynamic; + var usesBatchTable = defined(collection._batchTable); + var allowPicking = collection._allowPicking; - camera.setView({ - orientation: { - heading : CesiumMath.lerp(startHeading, heading, time), - pitch : CesiumMath.lerp(startPitch, pitch, time), - roll : CesiumMath.lerp(startRoll, roll, time) - } + if (usesBatchTable) { + var batchIdBufferData = new Uint16Array(instancesLength); + for (i = 0; i < instancesLength; ++i) { + batchIdBufferData[i] = instances[i]._instanceId; + } + collection._batchIdBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : batchIdBufferData, + usage : BufferUsage.STATIC_DRAW }); + } - Cartesian2.lerp(start, destination, time, camera.position); - camera.position.z = heightFunction(time); + if (allowPicking && !usesBatchTable) { + var pickIdBuffer = new Uint8Array(instancesLength * 4); + for (i = 0; i < instancesLength; ++i) { + var pickId = collection._pickIds[i]; + var pickColor = pickId.color; + var offset = i * 4; + pickIdBuffer[offset] = Color.floatToByte(pickColor.red); + pickIdBuffer[offset + 1] = Color.floatToByte(pickColor.green); + pickIdBuffer[offset + 2] = Color.floatToByte(pickColor.blue); + pickIdBuffer[offset + 3] = Color.floatToByte(pickColor.alpha); + } + collection._pickIdBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : pickIdBuffer, + usage : BufferUsage.STATIC_DRAW + }); } - return update; + + var vertexBufferTypedArray = getVertexBufferTypedArray(collection); + collection._vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : vertexBufferTypedArray, + usage : dynamic ? BufferUsage.STREAM_DRAW : BufferUsage.STATIC_DRAW + }); } - function useLongestFlight(startCart, destCart) { - if (startCart.longitude < destCart.longitude) { - startCart.longitude += CesiumMath.TWO_PI; - } else { - destCart.longitude += CesiumMath.TWO_PI; - } + function updateVertexBuffer(collection) { + var vertexBufferTypedArray = getVertexBufferTypedArray(collection); + collection._vertexBuffer.copyFromArrayView(vertexBufferTypedArray); } - function useShortestFlight(startCart, destCart) { - var diff = startCart.longitude - destCart.longitude; - if (diff < -CesiumMath.PI) { - startCart.longitude += CesiumMath.TWO_PI; - } else if (diff > CesiumMath.PI) { - destCart.longitude += CesiumMath.TWO_PI; + function createPickIds(collection, context) { + // PERFORMANCE_IDEA: we could skip the pick buffer completely by allocating + // a continuous range of pickIds and then converting the base pickId + batchId + // to RGBA in the shader. The only consider is precision issues, which might + // not be an issue in WebGL 2. + var instances = collection._instances; + var instancesLength = instances.length; + var pickIds = new Array(instancesLength); + for (var i = 0; i < instancesLength; ++i) { + pickIds[i] = context.createPickId(instances[i]); } + return pickIds; } - var scratchStartCart = new Cartographic(); - var scratchEndCart = new Cartographic(); - - function createUpdate3D(scene, duration, destination, heading, pitch, roll, optionAltitude, optionFlyOverLongitude, optionFlyOverLongitudeWeight, optionPitchAdjustHeight) { - var camera = scene.camera; - var projection = scene.mapProjection; - var ellipsoid = projection.ellipsoid; + function createModel(collection, context) { + var instancingSupported = collection._instancingSupported; + var usesBatchTable = defined(collection._batchTable); + var allowPicking = collection._allowPicking; - var startCart = Cartographic.clone(camera.positionCartographic, scratchStartCart); - var startPitch = camera.pitch; - var startHeading = adjustAngleForLERP(camera.heading, heading); - var startRoll = adjustAngleForLERP(camera.roll, roll); + var modelOptions = { + url : collection._url, + requestType : collection._requestType, + gltf : collection._gltf, + basePath : collection._basePath, + shadows : collection._shadows, + cacheKey : undefined, + asynchronous : collection._asynchronous, + allowPicking : allowPicking, + incrementallyLoadTextures : collection._incrementallyLoadTextures, + upAxis : collection._upAxis, + precreatedAttributes : undefined, + vertexShaderLoaded : undefined, + fragmentShaderLoaded : undefined, + uniformMapLoaded : undefined, + pickVertexShaderLoaded : undefined, + pickFragmentShaderLoaded : undefined, + pickUniformMapLoaded : undefined, + ignoreCommands : true, + opaquePass : collection._opaquePass + }; - var destCart = ellipsoid.cartesianToCartographic(destination, scratchEndCart); - startCart.longitude = CesiumMath.zeroToTwoPi(startCart.longitude); - destCart.longitude = CesiumMath.zeroToTwoPi(destCart.longitude); + if (allowPicking && !usesBatchTable) { + collection._pickIds = createPickIds(collection, context); + } - var useLongFlight = false; + if (instancingSupported) { + createVertexBuffer(collection, context); - if (defined(optionFlyOverLongitude)) { - var hitLon = CesiumMath.zeroToTwoPi(optionFlyOverLongitude); + var vertexSizeInFloats = 12; + var componentSizeInBytes = ComponentDatatype.getSizeInBytes(ComponentDatatype.FLOAT); - var lonMin = Math.min(startCart.longitude, destCart.longitude); - var lonMax = Math.max(startCart.longitude, destCart.longitude); + var instancedAttributes = { + czm_modelMatrixRow0 : { + index : 0, // updated in Model + vertexBuffer : collection._vertexBuffer, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + normalize : false, + offsetInBytes : 0, + strideInBytes : componentSizeInBytes * vertexSizeInFloats, + instanceDivisor : 1 + }, + czm_modelMatrixRow1 : { + index : 0, // updated in Model + vertexBuffer : collection._vertexBuffer, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + normalize : false, + offsetInBytes : componentSizeInBytes * 4, + strideInBytes : componentSizeInBytes * vertexSizeInFloats, + instanceDivisor : 1 + }, + czm_modelMatrixRow2 : { + index : 0, // updated in Model + vertexBuffer : collection._vertexBuffer, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + normalize : false, + offsetInBytes : componentSizeInBytes * 8, + strideInBytes : componentSizeInBytes * vertexSizeInFloats, + instanceDivisor : 1 + } + }; - var hitInside = (hitLon >= lonMin && hitLon <= lonMax); + // When using a batch table, add a batch id attribute + if (usesBatchTable) { + instancedAttributes.a_batchId = { + index : 0, // updated in Model + vertexBuffer : collection._batchIdBuffer, + componentsPerAttribute : 1, + componentDatatype : ComponentDatatype.UNSIGNED_SHORT, + normalize : false, + offsetInBytes : 0, + strideInBytes : 0, + instanceDivisor : 1 + }; + } - if (defined(optionFlyOverLongitudeWeight)) { - // Distance inside (0...2Pi) - var din = Math.abs(startCart.longitude - destCart.longitude); - // Distance outside (0...2Pi) - var dot = CesiumMath.TWO_PI - din; + if (allowPicking && !usesBatchTable) { + instancedAttributes.pickColor = { + index : 0, // updated in Model + vertexBuffer : collection._pickIdBuffer, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + normalize : true, + offsetInBytes : 0, + strideInBytes : 0, + instanceDivisor : 1 + }; + } - var hitDistance = hitInside ? din : dot; - var offDistance = hitInside ? dot : din; + modelOptions.precreatedAttributes = instancedAttributes; + modelOptions.vertexShaderLoaded = getVertexShaderCallback(collection); + modelOptions.fragmentShaderLoaded = getFragmentShaderCallback(collection); + modelOptions.uniformMapLoaded = getUniformMapCallback(collection, context); + modelOptions.pickVertexShaderLoaded = getPickVertexShaderCallback(collection); + modelOptions.pickFragmentShaderLoaded = getPickFragmentShaderCallback(collection); + modelOptions.pickUniformMapLoaded = getPickUniformMapCallback(collection); - if (hitDistance < offDistance * optionFlyOverLongitudeWeight && !hitInside) { - useLongFlight = true; - } - } else if (!hitInside) { - useLongFlight = true; + if (defined(collection._url)) { + modelOptions.cacheKey = collection._url.getUrlComponent() + '#instanced'; } + } else { + modelOptions.vertexShaderLoaded = getVertexShaderNonInstancedCallback(collection); + modelOptions.fragmentShaderLoaded = getFragmentShaderCallback(collection); + modelOptions.uniformMapLoaded = getUniformMapNonInstancedCallback(collection, context); + modelOptions.pickVertexShaderLoaded = getPickVertexShaderNonInstancedCallback(collection); + modelOptions.pickFragmentShaderLoaded = getPickFragmentShaderNonInstancedCallback(collection); + modelOptions.pickUniformMapLoaded = getPickUniformMapCallback(collection); } - if (useLongFlight) { - useLongestFlight(startCart, destCart); + if (defined(collection._url)) { + collection._model = Model.fromGltf(modelOptions); } else { - useShortestFlight(startCart, destCart); + collection._model = new Model(modelOptions); + } + } + + function updateWireframe(collection) { + if (collection._debugWireframe !== collection.debugWireframe) { + collection._debugWireframe = collection.debugWireframe; + + // This assumes the original primitive was TRIANGLES and that the triangles + // are connected for the wireframe to look perfect. + var primitiveType = collection.debugWireframe ? PrimitiveType.LINES : PrimitiveType.TRIANGLES; + var commands = collection._drawCommands; + var length = commands.length; + for (var i = 0; i < length; ++i) { + commands[i].primitiveType = primitiveType; + } + } + } + function updateShowBoundingVolume(collection) { + if (collection.debugShowBoundingVolume !== collection._debugShowBoundingVolume) { + collection._debugShowBoundingVolume = collection.debugShowBoundingVolume; + + var commands = collection._drawCommands; + var length = commands.length; + for (var i = 0; i < length; ++i) { + commands[i].debugShowBoundingVolume = collection.debugShowBoundingVolume; + } + } + } + + function createCommands(collection, drawCommands, pickCommands) { + var commandsLength = drawCommands.length; + var instancesLength = collection.length; + var allowPicking = collection.allowPicking; + var boundingSphere = collection._boundingSphere; + var cull = collection._cull; + + for (var i = 0; i < commandsLength; ++i) { + var drawCommand = DrawCommand.shallowClone(drawCommands[i]); + drawCommand.instanceCount = instancesLength; + drawCommand.boundingVolume = boundingSphere; + drawCommand.cull = cull; + collection._drawCommands.push(drawCommand); + + if (allowPicking) { + var pickCommand = DrawCommand.shallowClone(pickCommands[i]); + pickCommand.instanceCount = instancesLength; + pickCommand.boundingVolume = boundingSphere; + pickCommand.cull = cull; + collection._pickCommands.push(pickCommand); + } } + } - var heightFunction = createHeightFunction(camera, destination, startCart.height, destCart.height, optionAltitude); - var pitchFunction = createPitchFunction(startPitch, pitch, heightFunction, optionPitchAdjustHeight); + function createBatchIdFunction(batchId) { + return function() { + return batchId; + }; + } - // Isolate scope for update function. - // to have local copies of vars used in lerp - // Othervise, if you call nex - // createUpdate3D (createAnimationTween) - // before you played animation, variables will be overwriten. - function isolateUpdateFunction() { - var startLongitude = startCart.longitude; - var destLongitude = destCart.longitude; - var startLatitude = startCart.latitude; - var destLatitude = destCart.latitude; + function createPickColorFunction(color) { + return function() { + return color; + }; + } - return function update(value) { - var time = value.time / duration; + function createCommandsNonInstanced(collection, drawCommands, pickCommands) { + // When instancing is disabled, create commands for every instance. + var instances = collection._instances; + var commandsLength = drawCommands.length; + var instancesLength = collection.length; + var allowPicking = collection.allowPicking; + var usesBatchTable = defined(collection._batchTable); + var cull = collection._cull; - var position = Cartesian3.fromRadians( - CesiumMath.lerp(startLongitude, destLongitude, time), - CesiumMath.lerp(startLatitude, destLatitude, time), - heightFunction(time) - ); + for (var i = 0; i < commandsLength; ++i) { + for (var j = 0; j < instancesLength; ++j) { + var drawCommand = DrawCommand.shallowClone(drawCommands[i]); + drawCommand.modelMatrix = new Matrix4(); // Updated in updateCommandsNonInstanced + drawCommand.boundingVolume = new BoundingSphere(); // Updated in updateCommandsNonInstanced + drawCommand.cull = cull; + drawCommand.uniformMap = clone(drawCommand.uniformMap); + if (usesBatchTable) { + drawCommand.uniformMap.a_batchId = createBatchIdFunction(instances[j]._instanceId); + } + collection._drawCommands.push(drawCommand); - camera.setView({ - destination : position, - orientation: { - heading : CesiumMath.lerp(startHeading, heading, time), - pitch : pitchFunction(time), - roll : CesiumMath.lerp(startRoll, roll, time) + if (allowPicking) { + var pickCommand = DrawCommand.shallowClone(pickCommands[i]); + pickCommand.modelMatrix = new Matrix4(); // Updated in updateCommandsNonInstanced + pickCommand.boundingVolume = new BoundingSphere(); // Updated in updateCommandsNonInstanced + pickCommand.cull = cull; + pickCommand.uniformMap = clone(pickCommand.uniformMap); + if (usesBatchTable) { + pickCommand.uniformMap.a_batchId = createBatchIdFunction(instances[j]._instanceId); + } else if (allowPicking) { + var pickId = collection._pickIds[j]; + pickCommand.uniformMap.czm_pickColor = createPickColorFunction(pickId.color); } - }); - }; + collection._pickCommands.push(pickCommand); + } + } } - return isolateUpdateFunction(); } - function createUpdate2D(scene, duration, destination, heading, pitch, roll, optionAltitude) { - var camera = scene.camera; - - var start = Cartesian3.clone(camera.position, scratchStart); - var startHeading = adjustAngleForLERP(camera.heading, heading); + function updateCommandsNonInstanced(collection) { + var modelCommands = collection._modelCommands; + var commandsLength = modelCommands.length; + var instancesLength = collection.length; + var allowPicking = collection.allowPicking; + var collectionTransform = collection._rtcTransform; + var collectionCenter = collection._center; - var startHeight = camera.frustum.right - camera.frustum.left; - var heightFunction = createHeightFunction(camera, destination, startHeight, destination.z, optionAltitude); + for (var i = 0; i < commandsLength; ++i) { + var modelCommand = modelCommands[i]; + for (var j = 0; j < instancesLength; ++j) { + var commandIndex = i * instancesLength + j; + var drawCommand = collection._drawCommands[commandIndex]; + var instanceMatrix = Matrix4.clone(collection._instances[j]._modelMatrix, scratchMatrix); + instanceMatrix[12] -= collectionCenter.x; + instanceMatrix[13] -= collectionCenter.y; + instanceMatrix[14] -= collectionCenter.z; + instanceMatrix = Matrix4.multiply(collectionTransform, instanceMatrix, scratchMatrix); + var nodeMatrix = modelCommand.modelMatrix; + var modelMatrix = drawCommand.modelMatrix; + Matrix4.multiply(instanceMatrix, nodeMatrix, modelMatrix); - function update(value) { - var time = value.time / duration; + var nodeBoundingSphere = modelCommand.boundingVolume; + var boundingSphere = drawCommand.boundingVolume; + BoundingSphere.transform(nodeBoundingSphere, instanceMatrix, boundingSphere); - camera.setView({ - orientation: { - heading : CesiumMath.lerp(startHeading, heading, time) + if (allowPicking) { + var pickCommand = collection._pickCommands[commandIndex]; + Matrix4.clone(modelMatrix, pickCommand.modelMatrix); + BoundingSphere.clone(boundingSphere, pickCommand.boundingVolume); } - }); - - Cartesian2.lerp(start, destination, time, camera.position); + } + } + } - var zoom = heightFunction(time); + function getModelCommands(model) { + var nodeCommands = model._nodeCommands; + var length = nodeCommands.length; - var frustum = camera.frustum; - var ratio = frustum.top / frustum.right; + var drawCommands = []; + var pickCommands = []; - var incrementAmount = (zoom - (frustum.right - frustum.left)) * 0.5; - frustum.right += incrementAmount; - frustum.left -= incrementAmount; - frustum.top = ratio * frustum.right; - frustum.bottom = -frustum.top; + for (var i = 0; i < length; ++i) { + var nc = nodeCommands[i]; + if (nc.show) { + drawCommands.push(nc.command); + pickCommands.push(nc.pickCommand); + } } - return update; - } - - var scratchCartographic = new Cartographic(); - var scratchDestination = new Cartesian3(); - function emptyFlight(complete, cancel) { return { - startObject : {}, - stopObject : {}, - duration : 0.0, - complete : complete, - cancel : cancel + draw: drawCommands, + pick: pickCommands }; } - function wrapCallback(controller, cb) { - function wrapped() { - if (typeof cb === 'function') { - cb(); - } + function updateShadows(collection) { + if (collection.shadows !== collection._shadows) { + collection._shadows = collection.shadows; - controller.enableInputs = true; + var castShadows = ShadowMode.castShadows(collection.shadows); + var receiveShadows = ShadowMode.receiveShadows(collection.shadows); + + var drawCommands = collection._drawCommands; + var length = drawCommands.length; + for (var i = 0; i < length; ++i) { + var drawCommand = drawCommands[i]; + drawCommand.castShadows = castShadows; + drawCommand.receiveShadows = receiveShadows; + } } - return wrapped; } - CameraFlightPath.createTween = function(scene, options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var destination = options.destination; - - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - if (!defined(destination)) { - throw new DeveloperError('destination is required.'); + ModelInstanceCollection.prototype.update = function(frameState) { + if (frameState.mode === SceneMode.MORPHING) { + return; } - var mode = scene.mode; - if (mode === SceneMode.MORPHING) { - return emptyFlight(); + if (!this.show) { + return; } - var convert = defaultValue(options.convert, true); - var projection = scene.mapProjection; - var ellipsoid = projection.ellipsoid; - var maximumHeight = options.maximumHeight; - var flyOverLongitude = options.flyOverLongitude; - var flyOverLongitudeWeight = options.flyOverLongitudeWeight; - var pitchAdjustHeight = options.pitchAdjustHeight; - var easingFunction = options.easingFunction; - - if (convert && mode !== SceneMode.SCENE3D) { - ellipsoid.cartesianToCartographic(destination, scratchCartographic); - destination = projection.project(scratchCartographic, scratchDestination); + if (this.length === 0) { + return; } - var camera = scene.camera; - var transform = options.endTransform; - if (defined(transform)) { - camera._setTransform(transform); - } + var context = frameState.context; - var duration = options.duration; - if (!defined(duration)) { - duration = Math.ceil(Cartesian3.distance(camera.position, destination) / 1000000.0) + 2.0; - duration = Math.min(duration, 3.0); + if (this._state === LoadState.NEEDS_LOAD) { + this._state = LoadState.LOADING; + this._instancingSupported = context.instancedArrays; + createModel(this, context); + var that = this; + this._model.readyPromise.otherwise(function(error) { + that._state = LoadState.FAILED; + that._readyPromise.reject(error); + }); } - var heading = defaultValue(options.heading, 0.0); - var pitch = defaultValue(options.pitch, -CesiumMath.PI_OVER_TWO); - var roll = defaultValue(options.roll, 0.0); + var instancingSupported = this._instancingSupported; + var model = this._model; + model.update(frameState); - var controller = scene.screenSpaceCameraController; - controller.enableInputs = false; + if (model.ready && (this._state === LoadState.LOADING)) { + this._state = LoadState.LOADED; + this._ready = true; - var complete = wrapCallback(controller, options.complete); - var cancel = wrapCallback(controller, options.cancel); + // Expand bounding volume to fit the radius of the loaded model including the model's offset from the center + var modelRadius = model.boundingSphere.radius + Cartesian3.magnitude(model.boundingSphere.center); + this._boundingSphere.radius += modelRadius; - var frustum = camera.frustum; + var modelCommands = getModelCommands(model); + this._modelCommands = modelCommands.draw; - var empty = scene.mode === SceneMode.SCENE2D; - empty = empty && Cartesian2.equalsEpsilon(camera.position, destination, CesiumMath.EPSILON6); - empty = empty && CesiumMath.equalsEpsilon(Math.max(frustum.right - frustum.left, frustum.top - frustum.bottom), destination.z, CesiumMath.EPSILON6); + if (instancingSupported) { + createCommands(this, modelCommands.draw, modelCommands.pick); + } else { + createCommandsNonInstanced(this, modelCommands.draw, modelCommands.pick); + updateCommandsNonInstanced(this); + } - empty = empty || (scene.mode !== SceneMode.SCENE2D && - Cartesian3.equalsEpsilon(destination, camera.position, CesiumMath.EPSILON10)); + this._readyPromise.resolve(this); + return; + } - empty = empty && - CesiumMath.equalsEpsilon(CesiumMath.negativePiToPi(heading), CesiumMath.negativePiToPi(camera.heading), CesiumMath.EPSILON10) && - CesiumMath.equalsEpsilon(CesiumMath.negativePiToPi(pitch), CesiumMath.negativePiToPi(camera.pitch), CesiumMath.EPSILON10) && - CesiumMath.equalsEpsilon(CesiumMath.negativePiToPi(roll), CesiumMath.negativePiToPi(camera.roll), CesiumMath.EPSILON10); + if (this._state !== LoadState.LOADED) { + return; + } - if (empty) { - return emptyFlight(complete, cancel); + var modeChanged = (frameState.mode !== this._mode); + var modelMatrix = this.modelMatrix; + var modelMatrixChanged = !Matrix4.equals(this._modelMatrix, modelMatrix); + + if (modeChanged || modelMatrixChanged) { + this._mode = frameState.mode; + Matrix4.clone(modelMatrix, this._modelMatrix); + var rtcTransform = Matrix4.multiplyByTranslation(this._modelMatrix, this._center, this._rtcTransform); + if (this._mode !== SceneMode.SCENE3D) { + rtcTransform = Transforms.basisTo2D(frameState.mapProjection, rtcTransform, rtcTransform); + } + Matrix4.getTranslation(rtcTransform, this._boundingSphere.center); } - var updateFunctions = new Array(4); - updateFunctions[SceneMode.SCENE2D] = createUpdate2D; - updateFunctions[SceneMode.SCENE3D] = createUpdate3D; - updateFunctions[SceneMode.COLUMBUS_VIEW] = createUpdateCV; + if (instancingSupported && this._dirty) { + // If at least one instance has moved assume the collection is now dynamic + this._dynamic = true; + this._dirty = false; - if (duration <= 0.0) { - var newOnComplete = function() { - var update = updateFunctions[mode](scene, 1.0, destination, heading, pitch, roll, maximumHeight, flyOverLongitude, flyOverLongitudeWeight, pitchAdjustHeight); - update({ time: 1.0 }); + // PERFORMANCE_IDEA: only update dirty sub-sections instead of the whole collection + updateVertexBuffer(this); + } - if (typeof complete === 'function') { - complete(); - } - }; - return emptyFlight(newOnComplete, cancel); + // If any node changes due to an animation, update the commands. This could be inefficient if the model is + // composed of many nodes and only one changes, however it is probably fine in the general use case. + // Only applies when instancing is disabled. The instanced shader automatically handles node transformations. + if (!instancingSupported && (model.dirty || this._dirty || modeChanged || modelMatrixChanged)) { + updateCommandsNonInstanced(this); } - var update = updateFunctions[mode](scene, duration, destination, heading, pitch, roll, maximumHeight, flyOverLongitude, flyOverLongitudeWeight, pitchAdjustHeight); + updateShadows(this); + updateWireframe(this); + updateShowBoundingVolume(this); - if (!defined(easingFunction)) { - var startHeight = camera.positionCartographic.height; - var endHeight = mode === SceneMode.SCENE3D ? ellipsoid.cartesianToCartographic(destination).height : destination.z; + var passes = frameState.passes; + var commandList = frameState.commandList; + var commands = passes.render ? this._drawCommands : this._pickCommands; + var commandsLength = commands.length; - if (startHeight > endHeight && startHeight > 11500.0) { - easingFunction = EasingFunction.CUBIC_OUT; - } else { - easingFunction = EasingFunction.QUINTIC_IN_OUT; - } + for (var i = 0; i < commandsLength; ++i) { + commandList.push(commands[i]); } - - return { - duration : duration, - easingFunction : easingFunction, - startObject : { - time : 0.0 - }, - stopObject : { - time : duration - }, - update : update, - complete : complete, - cancel: cancel - }; }; - return CameraFlightPath; -}); + ModelInstanceCollection.prototype.isDestroyed = function() { + return false; + }; -define('Scene/MapMode2D',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + ModelInstanceCollection.prototype.destroy = function() { + this._model = this._model && this._model.destroy(); - /** - * Describes how the map will operate in 2D. - * - * @exports MapMode2D - */ - var MapMode2D = { - /** - * The 2D map can be rotated about the z axis. - * - * @type {Number} - * @constant - */ - ROTATE : 0, + var pickIds = this._pickIds; + if (defined(pickIds)) { + var length = pickIds.length; + for (var i = 0; i < length; ++i) { + pickIds[i].destroy(); + } + } - /** - * The 2D map can be scrolled infinitely in the horizontal direction. - * - * @type {Number} - * @constant - */ - INFINITE_SCROLL : 1 + return destroyObject(this); }; - return freezeObject(MapMode2D); + return ModelInstanceCollection; }); -define('Scene/Camera',[ - '../Core/BoundingSphere', - '../Core/Cartesian2', +define('Scene/Instanced3DModel3DTileContent',[ + '../Core/AttributeCompression', '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', + '../Core/ClippingPlaneCollection', + '../Core/Color', + '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/destroyObject', '../Core/DeveloperError', - '../Core/EasingFunction', '../Core/Ellipsoid', - '../Core/EllipsoidGeodesic', - '../Core/Event', - '../Core/HeadingPitchRange', - '../Core/HeadingPitchRoll', - '../Core/Intersect', - '../Core/IntersectionTests', - '../Core/Math', + '../Core/FeatureDetection', + '../Core/getBaseUri', + '../Core/getStringFromTypedArray', '../Core/Matrix3', '../Core/Matrix4', - '../Core/OrthographicFrustum', - '../Core/OrthographicOffCenterFrustum', - '../Core/PerspectiveFrustum', '../Core/Quaternion', - '../Core/Ray', - '../Core/Rectangle', + '../Core/RequestType', + '../Core/RuntimeError', '../Core/Transforms', - './CameraFlightPath', - './MapMode2D', - './SceneMode' + '../Core/TranslationRotationScale', + '../Renderer/Pass', + './Cesium3DTileBatchTable', + './Cesium3DTileFeature', + './Cesium3DTileFeatureTable', + './ModelInstanceCollection' ], function( - BoundingSphere, - Cartesian2, + AttributeCompression, Cartesian3, - Cartesian4, - Cartographic, + ClippingPlaneCollection, + Color, + ComponentDatatype, defaultValue, defined, defineProperties, + deprecationWarning, + destroyObject, DeveloperError, - EasingFunction, Ellipsoid, - EllipsoidGeodesic, - Event, - HeadingPitchRange, - HeadingPitchRoll, - Intersect, - IntersectionTests, - CesiumMath, + FeatureDetection, + getBaseUri, + getStringFromTypedArray, Matrix3, Matrix4, - OrthographicFrustum, - OrthographicOffCenterFrustum, - PerspectiveFrustum, Quaternion, - Ray, - Rectangle, + RequestType, + RuntimeError, Transforms, - CameraFlightPath, - MapMode2D, - SceneMode) { + TranslationRotationScale, + Pass, + Cesium3DTileBatchTable, + Cesium3DTileFeature, + Cesium3DTileFeatureTable, + ModelInstanceCollection) { 'use strict'; + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; + } + /** - * The camera is defined by a position, orientation, and view frustum. - * <br /><br /> - * The orientation forms an orthonormal basis with a view, up and right = view x up unit vectors. - * <br /><br /> - * The viewing frustum is defined by 6 planes. - * Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components - * define the unit vector normal to the plane, and the w component is the distance of the - * plane from the origin/camera position. - * - * @alias Camera + * Represents the contents of a + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Instanced3DModel/README.md|Instanced 3D Model} + * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. + * <p> + * Implements the {@link Cesium3DTileContent} interface. + * </p> * + * @alias Instanced3DModel3DTileContent * @constructor * - * @param {Scene} scene The scene. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Camera.html|Cesium Sandcastle Camera Demo} - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Camera%20Tutorial.html">Sandcastle Example</a> from the <a href="http://cesiumjs.org/2013/02/13/Cesium-Camera-Tutorial/|Camera Tutorial} - * - * @example - * // Create a camera looking down the negative z-axis, positioned at the origin, - * // with a field of view of 60 degrees, and 1:1 aspect ratio. - * var camera = new Cesium.Camera(scene); - * camera.position = new Cesium.Cartesian3(); - * camera.direction = Cesium.Cartesian3.negate(Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3()); - * camera.up = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_Y); - * camera.frustum.fov = Cesium.Math.PI_OVER_THREE; - * camera.frustum.near = 1.0; - * camera.frustum.far = 2.0; + * @private */ - function Camera(scene) { - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } - this._scene = scene; - - this._transform = Matrix4.clone(Matrix4.IDENTITY); - this._invTransform = Matrix4.clone(Matrix4.IDENTITY); - this._actualTransform = Matrix4.clone(Matrix4.IDENTITY); - this._actualInvTransform = Matrix4.clone(Matrix4.IDENTITY); - this._transformChanged = false; + function Instanced3DModel3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { + this._tileset = tileset; + this._tile = tile; + this._resource = resource; + this._modelInstanceCollection = undefined; + this._batchTable = undefined; + this._features = undefined; /** - * The position of the camera. - * - * @type {Cartesian3} + * @inheritdoc Cesium3DTileContent#featurePropertiesDirty */ - this.position = new Cartesian3(); - this._position = new Cartesian3(); - this._positionWC = new Cartesian3(); - this._positionCartographic = new Cartographic(); + this.featurePropertiesDirty = false; + + initialize(this, arrayBuffer, byteOffset); + } + + // This can be overridden for testing purposes + Instanced3DModel3DTileContent._deprecationWarning = deprecationWarning; + defineProperties(Instanced3DModel3DTileContent.prototype, { /** - * The view direction of the camera. - * - * @type {Cartesian3} + * @inheritdoc Cesium3DTileContent#featuresLength */ - this.direction = new Cartesian3(); - this._direction = new Cartesian3(); - this._directionWC = new Cartesian3(); + featuresLength : { + get : function() { + return this._batchTable.featuresLength; + } + }, /** - * The up direction of the camera. - * - * @type {Cartesian3} + * @inheritdoc Cesium3DTileContent#pointsLength */ - this.up = new Cartesian3(); - this._up = new Cartesian3(); - this._upWC = new Cartesian3(); + pointsLength : { + get : function() { + return 0; + } + }, /** - * The right direction of the camera. - * - * @type {Cartesian3} + * @inheritdoc Cesium3DTileContent#trianglesLength */ - this.right = new Cartesian3(); - this._right = new Cartesian3(); - this._rightWC = new Cartesian3(); + trianglesLength : { + get : function() { + var model = this._modelInstanceCollection._model; + if (defined(model)) { + return model.trianglesLength; + } + return 0; + } + }, /** - * The region of space in view. - * - * @type {Frustum} - * @default PerspectiveFrustum() - * - * @see PerspectiveFrustum - * @see PerspectiveOffCenterFrustum - * @see OrthographicFrustum + * @inheritdoc Cesium3DTileContent#geometryByteLength */ - this.frustum = new PerspectiveFrustum(); - this.frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - this.frustum.fov = CesiumMath.toRadians(60.0); + geometryByteLength : { + get : function() { + var model = this._modelInstanceCollection._model; + if (defined(model)) { + return model.geometryByteLength; + } + return 0; + } + }, /** - * The default amount to move the camera when an argument is not - * provided to the move methods. - * @type {Number} - * @default 100000.0; + * @inheritdoc Cesium3DTileContent#texturesByteLength */ - this.defaultMoveAmount = 100000.0; + texturesByteLength : { + get : function() { + var model = this._modelInstanceCollection._model; + if (defined(model)) { + return model.texturesByteLength; + } + return 0; + } + }, + /** - * The default amount to rotate the camera when an argument is not - * provided to the look methods. - * @type {Number} - * @default Math.PI / 60.0 + * @inheritdoc Cesium3DTileContent#batchTableByteLength */ - this.defaultLookAmount = Math.PI / 60.0; + batchTableByteLength : { + get : function() { + return this._batchTable.memorySizeInBytes; + } + }, + /** - * The default amount to rotate the camera when an argument is not - * provided to the rotate methods. - * @type {Number} - * @default Math.PI / 3600.0 + * @inheritdoc Cesium3DTileContent#innerContents */ - this.defaultRotateAmount = Math.PI / 3600.0; + innerContents : { + get : function() { + return undefined; + } + }, + /** - * The default amount to move the camera when an argument is not - * provided to the zoom methods. - * @type {Number} - * @default 100000.0; + * @inheritdoc Cesium3DTileContent#readyPromise */ - this.defaultZoomAmount = 100000.0; + readyPromise : { + get : function() { + return this._modelInstanceCollection.readyPromise; + } + }, + /** - * If set, the camera will not be able to rotate past this axis in either direction. - * @type {Cartesian3} - * @default undefined + * @inheritdoc Cesium3DTileContent#tileset */ - this.constrainedAxis = undefined; + tileset : { + get : function() { + return this._tileset; + } + }, + /** - * The factor multiplied by the the map size used to determine where to clamp the camera position - * when zooming out from the surface. The default is 1.5. Only valid for 2D and the map is rotatable. - * @type {Number} - * @default 1.5 + * @inheritdoc Cesium3DTileContent#tile */ - this.maximumZoomFactor = 1.5; - - this._moveStart = new Event(); - this._moveEnd = new Event(); - - this._changed = new Event(); - this._changedPosition = undefined; - this._changedDirection = undefined; - this._changedFrustum = undefined; + tile : { + get : function() { + return this._tile; + } + }, /** - * The amount the camera has to change before the <code>changed</code> event is raised. The value is a percentage in the [0, 1] range. - * @type {number} - * @default 0.5 + * @inheritdoc Cesium3DTileContent#url */ - this.percentageChanged = 0.5; - - this._viewMatrix = new Matrix4(); - this._invViewMatrix = new Matrix4(); - updateViewMatrix(this); + url: { + get: function() { + return this._resource.getUrlComponent(true); + } + }, - this._mode = SceneMode.SCENE3D; - this._modeChanged = true; - var projection = scene.mapProjection; - this._projection = projection; - this._maxCoord = projection.project(new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO)); - this._max2Dfrustum = undefined; - this._suspendTerrainAdjustment = false; + /** + * @inheritdoc Cesium3DTileContent#batchTable + */ + batchTable : { + get : function() { + return this._batchTable; + } + } + }); - // set default view - rectangleCameraPosition3D(this, Camera.DEFAULT_VIEW_RECTANGLE, this.position, true); + var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; + var propertyScratch1 = new Array(4); + var propertyScratch2 = new Array(4); - var mag = Cartesian3.magnitude(this.position); - mag += mag * Camera.DEFAULT_VIEW_FACTOR; - Cartesian3.normalize(this.position, this.position); - Cartesian3.multiplyByScalar(this.position, mag, this.position); - } + function initialize(content, arrayBuffer, byteOffset) { + var byteStart = defaultValue(byteOffset, 0); + byteOffset = byteStart; - /** - * @private - */ - Camera.TRANSFORM_2D = new Matrix4( - 0.0, 0.0, 1.0, 0.0, - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0); + var uint8Array = new Uint8Array(arrayBuffer); + var view = new DataView(arrayBuffer); + byteOffset += sizeOfUint32; // Skip magic - /** - * @private - */ - Camera.TRANSFORM_2D_INVERSE = Matrix4.inverseTransformation(Camera.TRANSFORM_2D, new Matrix4()); + var version = view.getUint32(byteOffset, true); + if (version !== 1) { + throw new RuntimeError('Only Instanced 3D Model version 1 is supported. Version ' + version + ' is not.'); + } + byteOffset += sizeOfUint32; - /** - * The default rectangle the camera will view on creation. - * @type Rectangle - */ - Camera.DEFAULT_VIEW_RECTANGLE = Rectangle.fromDegrees(-95.0, -20.0, -70.0, 90.0); + var byteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - /** - * A scalar to multiply to the camera position and add it back after setting the camera to view the rectangle. - * A value of zero means the camera will view the entire {@link Camera#DEFAULT_VIEW_RECTANGLE}, a value greater than zero - * will move it further away from the extent, and a value less than zero will move it close to the extent. - * @type Number - */ - Camera.DEFAULT_VIEW_FACTOR = 0.5; + var featureTableJsonByteLength = view.getUint32(byteOffset, true); + if (featureTableJsonByteLength === 0) { + throw new RuntimeError('featureTableJsonByteLength is zero, the feature table must be defined.'); + } + byteOffset += sizeOfUint32; - /** - * The default heading/pitch/range that is used when the camera flies to a location that contains a bounding sphere. - * @type HeadingPitchRange - */ - Camera.DEFAULT_OFFSET = new HeadingPitchRange(0.0, -CesiumMath.PI_OVER_FOUR, 0.0); + var featureTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - function updateViewMatrix(camera) { - Matrix4.computeView(camera._position, camera._direction, camera._up, camera._right, camera._viewMatrix); - Matrix4.multiply(camera._viewMatrix, camera._actualInvTransform, camera._viewMatrix); - Matrix4.inverseTransformation(camera._viewMatrix, camera._invViewMatrix); - } + var batchTableJsonByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - Camera.prototype._updateCameraChanged = function() { - var camera = this; + var batchTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - if (camera._changed.numberOfListeners === 0) { - return; + var gltfFormat = view.getUint32(byteOffset, true); + if (gltfFormat !== 1 && gltfFormat !== 0) { + throw new RuntimeError('Only glTF format 0 (uri) or 1 (embedded) are supported. Format ' + gltfFormat + ' is not.'); } + byteOffset += sizeOfUint32; - var percentageChanged = camera.percentageChanged; - - if (camera._mode === SceneMode.SCENE2D) { - if (!defined(camera._changedFrustum)) { - camera._changedPosition = Cartesian3.clone(camera.position, camera._changedPosition); - camera._changedFrustum = camera.frustum.clone(); - return; - } - - var position = camera.position; - var lastPosition = camera._changedPosition; - - var frustum = camera.frustum; - var lastFrustum = camera._changedFrustum; + var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength); + var featureTableJson = JSON.parse(featureTableString); + byteOffset += featureTableJsonByteLength; - var x0 = position.x + frustum.left; - var x1 = position.x + frustum.right; - var x2 = lastPosition.x + lastFrustum.left; - var x3 = lastPosition.x + lastFrustum.right; + var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); + byteOffset += featureTableBinaryByteLength; - var y0 = position.y + frustum.bottom; - var y1 = position.y + frustum.top; - var y2 = lastPosition.y + lastFrustum.bottom; - var y3 = lastPosition.y + lastFrustum.top; + var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); + var instancesLength = featureTable.getGlobalProperty('INSTANCES_LENGTH'); + featureTable.featuresLength = instancesLength; - var leftX = Math.max(x0, x2); - var rightX = Math.min(x1, x3); - var bottomY = Math.max(y0, y2); - var topY = Math.min(y1, y3); + if (!defined(instancesLength)) { + throw new RuntimeError('Feature table global property: INSTANCES_LENGTH must be defined'); + } - var areaPercentage; - if (leftX >= rightX || bottomY >= y1) { - areaPercentage = 1.0; - } else { - var areaRef = lastFrustum; - if (x0 < x2 && x1 > x3 && y0 < y2 && y1 > y3) { - areaRef = frustum; - } - areaPercentage = 1.0 - ((rightX - leftX) * (topY - bottomY)) / ((areaRef.right - areaRef.left) * (areaRef.top - areaRef.bottom)); - } + var batchTableJson; + var batchTableBinary; + if (batchTableJsonByteLength > 0) { + var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength); + batchTableJson = JSON.parse(batchTableString); + byteOffset += batchTableJsonByteLength; - if (areaPercentage > percentageChanged) { - camera._changed.raiseEvent(areaPercentage); - camera._changedPosition = Cartesian3.clone(camera.position, camera._changedPosition); - camera._changedFrustum = camera.frustum.clone(camera._changedFrustum); + if (batchTableBinaryByteLength > 0) { + // Has a batch table binary + batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); + // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed + batchTableBinary = new Uint8Array(batchTableBinary); + byteOffset += batchTableBinaryByteLength; } - return; - } - - if (!defined(camera._changedDirection)) { - camera._changedPosition = Cartesian3.clone(camera.positionWC, camera._changedPosition); - camera._changedDirection = Cartesian3.clone(camera.directionWC, camera._changedDirection); - return; } - var dirAngle = CesiumMath.acosClamped(Cartesian3.dot(camera.directionWC, camera._changedDirection)); + content._batchTable = new Cesium3DTileBatchTable(content, instancesLength, batchTableJson, batchTableBinary); - var dirPercentage; - if (defined(camera.frustum.fovy)) { - dirPercentage = dirAngle / (camera.frustum.fovy * 0.5); - } else { - dirPercentage = dirAngle; + var gltfByteLength = byteStart + byteLength - byteOffset; + if (gltfByteLength === 0) { + throw new RuntimeError('glTF byte length is zero, i3dm must have a glTF to instance.'); } - var distance = Cartesian3.distance(camera.positionWC, camera._changedPosition); - var heightPercentage = distance / camera.positionCartographic.height; - - if (dirPercentage > percentageChanged || heightPercentage > percentageChanged) { - camera._changed.raiseEvent(Math.max(dirPercentage, heightPercentage)); - camera._changedPosition = Cartesian3.clone(camera.positionWC, camera._changedPosition); - camera._changedDirection = Cartesian3.clone(camera.directionWC, camera._changedDirection); + var gltfView; + if (byteOffset % 4 === 0) { + gltfView = new Uint8Array(arrayBuffer, byteOffset, gltfByteLength); + } else { + // Create a copy of the glb so that it is 4-byte aligned + Instanced3DModel3DTileContent._deprecationWarning('i3dm-glb-unaligned', 'The embedded glb is not aligned to a 4-byte boundary.'); + gltfView = new Uint8Array(uint8Array.subarray(byteOffset, byteOffset + gltfByteLength)); } - }; - - var scratchAdjustHeightTransform = new Matrix4(); - var scratchAdjustHeightCartographic = new Cartographic(); - - Camera.prototype._adjustHeightForTerrain = function() { - var scene = this._scene; - - var screenSpaceCameraController = scene.screenSpaceCameraController; - var enableCollisionDetection = screenSpaceCameraController.enableCollisionDetection; - var minimumCollisionTerrainHeight = screenSpaceCameraController.minimumCollisionTerrainHeight; - var minimumZoomDistance = screenSpaceCameraController.minimumZoomDistance; - if (this._suspendTerrainAdjustment || !enableCollisionDetection) { - return; - } + // Create model instance collection + var collectionOptions = { + instances : new Array(instancesLength), + batchTable : content._batchTable, + cull : false, // Already culled by 3D Tiles + url : undefined, + requestType : RequestType.TILES3D, + gltf : undefined, + basePath : undefined, + incrementallyLoadTextures : false, + upAxis : content._tileset._gltfUpAxis, + opaquePass : Pass.CESIUM_3D_TILE // Draw opaque portions during the 3D Tiles pass + }; - var mode = this._mode; - var globe = scene.globe; + if (gltfFormat === 0) { + var gltfUrl = getStringFromTypedArray(gltfView); - if (!defined(globe) || mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { - return; + // We need to remove padding from the end of the model URL in case this tile was part of a composite tile. + // This removes all white space and null characters from the end of the string. + gltfUrl = gltfUrl.replace(/[\s\0]+$/, ''); + collectionOptions.url = content._resource.getDerivedResource({ + url: gltfUrl + }); + } else { + collectionOptions.gltf = gltfView; + collectionOptions.basePath = content._resource.clone(); } - var ellipsoid = globe.ellipsoid; - var projection = scene.mapProjection; + var eastNorthUp = featureTable.getGlobalProperty('EAST_NORTH_UP'); - var transform; - var mag; - if (!Matrix4.equals(this.transform, Matrix4.IDENTITY)) { - transform = Matrix4.clone(this.transform, scratchAdjustHeightTransform); - mag = Cartesian3.magnitude(this.position); - this._setTransform(Matrix4.IDENTITY); + var rtcCenter; + var rtcCenterArray = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); + if (defined(rtcCenterArray)) { + rtcCenter = Cartesian3.unpack(rtcCenterArray); } - var cartographic = scratchAdjustHeightCartographic; - if (mode === SceneMode.SCENE3D) { - ellipsoid.cartesianToCartographic(this.position, cartographic); - } else { - projection.unproject(this.position, cartographic); - } + var instances = collectionOptions.instances; + var instancePosition = new Cartesian3(); + var instancePositionArray = new Array(3); + var instanceNormalRight = new Cartesian3(); + var instanceNormalUp = new Cartesian3(); + var instanceNormalForward = new Cartesian3(); + var instanceRotation = new Matrix3(); + var instanceQuaternion = new Quaternion(); + var instanceScale = new Cartesian3(); + var instanceTranslationRotationScale = new TranslationRotationScale(); + var instanceTransform = new Matrix4(); + for (var i = 0; i < instancesLength; i++) { + // Get the instance position + var position = featureTable.getProperty('POSITION', ComponentDatatype.FLOAT, 3, i, propertyScratch1); + if (!defined(position)) { + position = instancePositionArray; + var positionQuantized = featureTable.getProperty('POSITION_QUANTIZED', ComponentDatatype.UNSIGNED_SHORT, 3, i, propertyScratch1); + if (!defined(positionQuantized)) { + throw new RuntimeError('Either POSITION or POSITION_QUANTIZED must be defined for each instance.'); + } + var quantizedVolumeOffset = featureTable.getGlobalProperty('QUANTIZED_VOLUME_OFFSET', ComponentDatatype.FLOAT, 3); + if (!defined(quantizedVolumeOffset)) { + throw new RuntimeError('Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.'); + } + var quantizedVolumeScale = featureTable.getGlobalProperty('QUANTIZED_VOLUME_SCALE', ComponentDatatype.FLOAT, 3); + if (!defined(quantizedVolumeScale)) { + throw new RuntimeError('Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.'); + } + for (var j = 0; j < 3; j++) { + position[j] = (positionQuantized[j] / 65535.0 * quantizedVolumeScale[j]) + quantizedVolumeOffset[j]; + } + } + Cartesian3.unpack(position, 0, instancePosition); + if (defined(rtcCenter)) { + Cartesian3.add(instancePosition, rtcCenter, instancePosition); + } + instanceTranslationRotationScale.translation = instancePosition; - var heightUpdated = false; - if (cartographic.height < minimumCollisionTerrainHeight) { - var height = globe.getHeight(cartographic); - if (defined(height)) { - height += minimumZoomDistance; - if (cartographic.height < height) { - cartographic.height = height; - if (mode === SceneMode.SCENE3D) { - ellipsoid.cartographicToCartesian(cartographic, this.position); - } else { - projection.project(cartographic, this.position); + // Get the instance rotation + var normalUp = featureTable.getProperty('NORMAL_UP', ComponentDatatype.FLOAT, 3, i, propertyScratch1); + var normalRight = featureTable.getProperty('NORMAL_RIGHT', ComponentDatatype.FLOAT, 3, i, propertyScratch2); + var hasCustomOrientation = false; + if (defined(normalUp)) { + if (!defined(normalRight)) { + throw new RuntimeError('To define a custom orientation, both NORMAL_UP and NORMAL_RIGHT must be defined.'); + } + Cartesian3.unpack(normalUp, 0, instanceNormalUp); + Cartesian3.unpack(normalRight, 0, instanceNormalRight); + hasCustomOrientation = true; + } else { + var octNormalUp = featureTable.getProperty('NORMAL_UP_OCT32P', ComponentDatatype.UNSIGNED_SHORT, 2, i, propertyScratch1); + var octNormalRight = featureTable.getProperty('NORMAL_RIGHT_OCT32P', ComponentDatatype.UNSIGNED_SHORT, 2, i, propertyScratch2); + if (defined(octNormalUp)) { + if (!defined(octNormalRight)) { + throw new RuntimeError('To define a custom orientation with oct-encoded vectors, both NORMAL_UP_OCT32P and NORMAL_RIGHT_OCT32P must be defined.'); } - heightUpdated = true; + AttributeCompression.octDecodeInRange(octNormalUp[0], octNormalUp[1], 65535, instanceNormalUp); + AttributeCompression.octDecodeInRange(octNormalRight[0], octNormalRight[1], 65535, instanceNormalRight); + hasCustomOrientation = true; + } else if (eastNorthUp) { + Transforms.eastNorthUpToFixedFrame(instancePosition, Ellipsoid.WGS84, instanceTransform); + Matrix4.getRotation(instanceTransform, instanceRotation); + } else { + Matrix3.clone(Matrix3.IDENTITY, instanceRotation); } } - } + if (hasCustomOrientation) { + Cartesian3.cross(instanceNormalRight, instanceNormalUp, instanceNormalForward); + Cartesian3.normalize(instanceNormalForward, instanceNormalForward); + Matrix3.setColumn(instanceRotation, 0, instanceNormalRight, instanceRotation); + Matrix3.setColumn(instanceRotation, 1, instanceNormalUp, instanceRotation); + Matrix3.setColumn(instanceRotation, 2, instanceNormalForward, instanceRotation); + } + Quaternion.fromRotationMatrix(instanceRotation, instanceQuaternion); + instanceTranslationRotationScale.rotation = instanceQuaternion; + + // Get the instance scale + instanceScale = Cartesian3.fromElements(1.0, 1.0, 1.0, instanceScale); + var scale = featureTable.getProperty('SCALE', ComponentDatatype.FLOAT, 1, i); + if (defined(scale)) { + Cartesian3.multiplyByScalar(instanceScale, scale, instanceScale); + } + var nonUniformScale = featureTable.getProperty('SCALE_NON_UNIFORM', ComponentDatatype.FLOAT, 3, i, propertyScratch1); + if (defined(nonUniformScale)) { + instanceScale.x *= nonUniformScale[0]; + instanceScale.y *= nonUniformScale[1]; + instanceScale.z *= nonUniformScale[2]; + } + instanceTranslationRotationScale.scale = instanceScale; + + // Get the batchId + var batchId = featureTable.getProperty('BATCH_ID', ComponentDatatype.UNSIGNED_SHORT, 1, i); + if (!defined(batchId)) { + // If BATCH_ID semantic is undefined, batchId is just the instance number + batchId = i; + } - if (defined(transform)) { - this._setTransform(transform); - if (heightUpdated) { - Cartesian3.normalize(this.position, this.position); - Cartesian3.negate(this.position, this.direction); - Cartesian3.multiplyByScalar(this.position, Math.max(mag, minimumZoomDistance), this.position); - Cartesian3.normalize(this.direction, this.direction); - Cartesian3.cross(this.direction, this.up, this.right); - Cartesian3.cross(this.right, this.direction, this.up); - } + // Create the model matrix and the instance + Matrix4.fromTranslationRotationScale(instanceTranslationRotationScale, instanceTransform); + var modelMatrix = instanceTransform.clone(); + instances[i] = { + modelMatrix : modelMatrix, + batchId : batchId + }; } - }; - function convertTransformForColumbusView(camera) { - Transforms.basisTo2D(camera._projection, camera._transform, camera._actualTransform); + content._modelInstanceCollection = new ModelInstanceCollection(collectionOptions); } - var scratchCartographic = new Cartographic(); - var scratchCartesian3Projection = new Cartesian3(); - var scratchCartesian3 = new Cartesian3(); - var scratchCartesian4Origin = new Cartesian4(); - var scratchCartesian4NewOrigin = new Cartesian4(); - var scratchCartesian4NewXAxis = new Cartesian4(); - var scratchCartesian4NewYAxis = new Cartesian4(); - var scratchCartesian4NewZAxis = new Cartesian4(); - - function convertTransformFor2D(camera) { - var projection = camera._projection; - var ellipsoid = projection.ellipsoid; - - var origin = Matrix4.getColumn(camera._transform, 3, scratchCartesian4Origin); - var cartographic = ellipsoid.cartesianToCartographic(origin, scratchCartographic); - - var projectedPosition = projection.project(cartographic, scratchCartesian3Projection); - var newOrigin = scratchCartesian4NewOrigin; - newOrigin.x = projectedPosition.z; - newOrigin.y = projectedPosition.x; - newOrigin.z = projectedPosition.y; - newOrigin.w = 1.0; - - var newZAxis = Cartesian4.clone(Cartesian4.UNIT_X, scratchCartesian4NewZAxis); - - var xAxis = Cartesian4.add(Matrix4.getColumn(camera._transform, 0, scratchCartesian3), origin, scratchCartesian3); - ellipsoid.cartesianToCartographic(xAxis, cartographic); - - projection.project(cartographic, projectedPosition); - var newXAxis = scratchCartesian4NewXAxis; - newXAxis.x = projectedPosition.z; - newXAxis.y = projectedPosition.x; - newXAxis.z = projectedPosition.y; - newXAxis.w = 0.0; - - Cartesian3.subtract(newXAxis, newOrigin, newXAxis); - newXAxis.x = 0.0; - - var newYAxis = scratchCartesian4NewYAxis; - if (Cartesian3.magnitudeSquared(newXAxis) > CesiumMath.EPSILON10) { - Cartesian3.cross(newZAxis, newXAxis, newYAxis); - } else { - var yAxis = Cartesian4.add(Matrix4.getColumn(camera._transform, 1, scratchCartesian3), origin, scratchCartesian3); - ellipsoid.cartesianToCartographic(yAxis, cartographic); - - projection.project(cartographic, projectedPosition); - newYAxis.x = projectedPosition.z; - newYAxis.y = projectedPosition.x; - newYAxis.z = projectedPosition.y; - newYAxis.w = 0.0; - - Cartesian3.subtract(newYAxis, newOrigin, newYAxis); - newYAxis.x = 0.0; - - if (Cartesian3.magnitudeSquared(newYAxis) < CesiumMath.EPSILON10) { - Cartesian4.clone(Cartesian4.UNIT_Y, newXAxis); - Cartesian4.clone(Cartesian4.UNIT_Z, newYAxis); + function createFeatures(content) { + var featuresLength = content.featuresLength; + if (!defined(content._features) && (featuresLength > 0)) { + var features = new Array(featuresLength); + for (var i = 0; i < featuresLength; ++i) { + features[i] = new Cesium3DTileFeature(content, i); } + content._features = features; } + } - Cartesian3.cross(newYAxis, newZAxis, newXAxis); - Cartesian3.normalize(newXAxis, newXAxis); - Cartesian3.cross(newZAxis, newXAxis, newYAxis); - Cartesian3.normalize(newYAxis, newYAxis); + /** + * @inheritdoc Cesium3DTileContent#hasProperty + */ + Instanced3DModel3DTileContent.prototype.hasProperty = function(batchId, name) { + return this._batchTable.hasProperty(batchId, name); + }; - Matrix4.setColumn(camera._actualTransform, 0, newXAxis, camera._actualTransform); - Matrix4.setColumn(camera._actualTransform, 1, newYAxis, camera._actualTransform); - Matrix4.setColumn(camera._actualTransform, 2, newZAxis, camera._actualTransform); - Matrix4.setColumn(camera._actualTransform, 3, newOrigin, camera._actualTransform); - } + /** + * @inheritdoc Cesium3DTileContent#getFeature + */ + Instanced3DModel3DTileContent.prototype.getFeature = function(batchId) { + var featuresLength = this.featuresLength; + if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); + } + + createFeatures(this); + return this._features[batchId]; + }; - var scratchCartesian = new Cartesian3(); + /** + * @inheritdoc Cesium3DTileContent#applyDebugSettings + */ + Instanced3DModel3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + color = enabled ? color : Color.WHITE; + this._batchTable.setAllColor(color); + }; - function updateMembers(camera) { - var mode = camera._mode; + /** + * @inheritdoc Cesium3DTileContent#applyStyle + */ + Instanced3DModel3DTileContent.prototype.applyStyle = function(frameState, style) { + this._batchTable.applyStyle(frameState, style); + }; - var heightChanged = false; - var height = 0.0; - if (mode === SceneMode.SCENE2D) { - height = camera.frustum.right - camera.frustum.left; - heightChanged = height !== camera._positionCartographic.height; - } + /** + * @inheritdoc Cesium3DTileContent#update + */ + Instanced3DModel3DTileContent.prototype.update = function(tileset, frameState) { + var commandStart = frameState.commandList.length; - var position = camera._position; - var positionChanged = !Cartesian3.equals(position, camera.position) || heightChanged; - if (positionChanged) { - position = Cartesian3.clone(camera.position, camera._position); - } + // In the PROCESSING state we may be calling update() to move forward + // the content's resource loading. In the READY state, it will + // actually generate commands. + this._batchTable.update(tileset, frameState); + this._modelInstanceCollection.modelMatrix = this._tile.computedTransform; + this._modelInstanceCollection.shadows = this._tileset.shadows; + this._modelInstanceCollection.debugWireframe = this._tileset.debugWireframe; + this._modelInstanceCollection.update(frameState); - var direction = camera._direction; - var directionChanged = !Cartesian3.equals(direction, camera.direction); - if (directionChanged) { - Cartesian3.normalize(camera.direction, camera.direction); - direction = Cartesian3.clone(camera.direction, camera._direction); - } + // Update clipping planes + var tilesetClippingPlanes = this._tileset.clippingPlanes; + var model = this._modelInstanceCollection._model; + var modelClippingPlanes = model.clippingPlanes; + if (defined(tilesetClippingPlanes)) { + if (!defined(modelClippingPlanes)) { + model.clippingPlanes = new ClippingPlaneCollection(); + modelClippingPlanes = model.clippingPlanes; + } - var up = camera._up; - var upChanged = !Cartesian3.equals(up, camera.up); - if (upChanged) { - Cartesian3.normalize(camera.up, camera.up); - up = Cartesian3.clone(camera.up, camera._up); + tilesetClippingPlanes.clone(modelClippingPlanes); + modelClippingPlanes.enabled = tilesetClippingPlanes.enabled && this._tile._isClipped; + } else if (defined(modelClippingPlanes) && modelClippingPlanes.enabled) { + modelClippingPlanes.enabled = false; } - var right = camera._right; - var rightChanged = !Cartesian3.equals(right, camera.right); - if (rightChanged) { - Cartesian3.normalize(camera.right, camera.right); - right = Cartesian3.clone(camera.right, camera._right); + // If any commands were pushed, add derived commands + var commandEnd = frameState.commandList.length; + if ((commandStart < commandEnd) && frameState.passes.render) { + this._batchTable.addDerivedCommands(frameState, commandStart, false); } + }; - var transformChanged = camera._transformChanged || camera._modeChanged; - camera._transformChanged = false; - - if (transformChanged) { - Matrix4.inverseTransformation(camera._transform, camera._invTransform); + /** + * @inheritdoc Cesium3DTileContent#isDestroyed + */ + Instanced3DModel3DTileContent.prototype.isDestroyed = function() { + return false; + }; - if (camera._mode === SceneMode.COLUMBUS_VIEW || camera._mode === SceneMode.SCENE2D) { - if (Matrix4.equals(Matrix4.IDENTITY, camera._transform)) { - Matrix4.clone(Camera.TRANSFORM_2D, camera._actualTransform); - } else if (camera._mode === SceneMode.COLUMBUS_VIEW) { - convertTransformForColumbusView(camera); - } else { - convertTransformFor2D(camera); - } - } else { - Matrix4.clone(camera._transform, camera._actualTransform); - } + /** + * @inheritdoc Cesium3DTileContent#destroy + */ + Instanced3DModel3DTileContent.prototype.destroy = function() { + this._modelInstanceCollection = this._modelInstanceCollection && this._modelInstanceCollection.destroy(); + this._batchTable = this._batchTable && this._batchTable.destroy(); - Matrix4.inverseTransformation(camera._actualTransform, camera._actualInvTransform); + return destroyObject(this); + }; + return Instanced3DModel3DTileContent; +}); - camera._modeChanged = false; - } +define('Scene/PointCloud3DTileContent',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/ClippingPlaneCollection', + '../Core/Color', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/FeatureDetection', + '../Core/getStringFromTypedArray', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/oneTimeWarning', + '../Core/OrthographicFrustum', + '../Core/Plane', + '../Core/PrimitiveType', + '../Core/RuntimeError', + '../Core/Transforms', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArray', + '../ThirdParty/when', + './BlendingState', + './Cesium3DTileBatchTable', + './Cesium3DTileFeature', + './Cesium3DTileFeatureTable', + './SceneMode', + './ShadowMode' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + ClippingPlaneCollection, + Color, + combine, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + FeatureDetection, + getStringFromTypedArray, + Matrix3, + Matrix4, + oneTimeWarning, + OrthographicFrustum, + Plane, + PrimitiveType, + RuntimeError, + Transforms, + Buffer, + BufferUsage, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + VertexArray, + when, + BlendingState, + Cesium3DTileBatchTable, + Cesium3DTileFeature, + Cesium3DTileFeatureTable, + SceneMode, + ShadowMode) { + 'use strict'; - var transform = camera._actualTransform; + // Bail out if the browser doesn't support typed arrays, to prevent the setup function + // from failing, since we won't be able to create a WebGL context anyway. + if (!FeatureDetection.supportsTypedArrays()) { + return {}; + } - if (positionChanged || transformChanged) { - camera._positionWC = Matrix4.multiplyByPoint(transform, position, camera._positionWC); + /** + * Represents the contents of a + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/PointCloud/README.md|Points} + * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. + * <p> + * Implements the {@link Cesium3DTileContent} interface. + * </p> + * + * @alias PointCloud3DTileContent + * @constructor + * + * @private + */ + function PointCloud3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { + this._tileset = tileset; + this._tile = tile; + this._resource = resource; - // Compute the Cartographic position of the camera. - if (mode === SceneMode.SCENE3D || mode === SceneMode.MORPHING) { - camera._positionCartographic = camera._projection.ellipsoid.cartesianToCartographic(camera._positionWC, camera._positionCartographic); - } else { - // The camera position is expressed in the 2D coordinate system where the Y axis is to the East, - // the Z axis is to the North, and the X axis is out of the map. Express them instead in the ENU axes where - // X is to the East, Y is to the North, and Z is out of the local horizontal plane. - var positionENU = scratchCartesian; - positionENU.x = camera._positionWC.y; - positionENU.y = camera._positionWC.z; - positionENU.z = camera._positionWC.x; + // Hold onto the payload until the render resources are created + this._parsedContent = undefined; - // In 2D, the camera height is always 12.7 million meters. - // The apparent height is equal to half the frustum width. - if (mode === SceneMode.SCENE2D) { - positionENU.z = height; - } + this._drawCommand = undefined; + this._pickCommand = undefined; + this._pickId = undefined; // Only defined when batchTable is undefined + this._isTranslucent = false; + this._styleTranslucent = false; + this._constantColor = Color.clone(Color.WHITE); + this._rtcCenter = undefined; + this._batchTable = undefined; // Used when feature table contains BATCH_ID semantic - camera._projection.unproject(positionENU, camera._positionCartographic); - } - } + // These values are used to regenerate the shader when the style changes + this._styleableShaderAttributes = undefined; + this._isQuantized = false; + this._isOctEncoded16P = false; + this._isRGB565 = false; + this._hasColors = false; + this._hasNormals = false; + this._hasBatchIds = false; - if (directionChanged || upChanged || rightChanged) { - var det = Cartesian3.dot(direction, Cartesian3.cross(up, right, scratchCartesian)); - if (Math.abs(1.0 - det) > CesiumMath.EPSILON2) { - //orthonormalize axes - var invUpMag = 1.0 / Cartesian3.magnitudeSquared(up); - var scalar = Cartesian3.dot(up, direction) * invUpMag; - var w0 = Cartesian3.multiplyByScalar(direction, scalar, scratchCartesian); - up = Cartesian3.normalize(Cartesian3.subtract(up, w0, camera._up), camera._up); - Cartesian3.clone(up, camera.up); + // Used to regenerate shader when clipping on this tile changes + this._isClipped = false; + this._unionClippingRegions = false; - right = Cartesian3.cross(direction, up, camera._right); - Cartesian3.clone(right, camera.right); - } - } + // Use per-point normals to hide back-facing points. + this.backFaceCulling = false; + this._backFaceCulling = false; - if (directionChanged || transformChanged) { - camera._directionWC = Matrix4.multiplyByPointAsVector(transform, direction, camera._directionWC); - Cartesian3.normalize(camera._directionWC, camera._directionWC); - } + this._opaqueRenderState = undefined; + this._translucentRenderState = undefined; - if (upChanged || transformChanged) { - camera._upWC = Matrix4.multiplyByPointAsVector(transform, up, camera._upWC); - Cartesian3.normalize(camera._upWC, camera._upWC); - } + this._highlightColor = Color.clone(Color.WHITE); + this._pointSize = 1.0; + this._quantizedVolumeScale = undefined; + this._quantizedVolumeOffset = undefined; - if (rightChanged || transformChanged) { - camera._rightWC = Matrix4.multiplyByPointAsVector(transform, right, camera._rightWC); - Cartesian3.normalize(camera._rightWC, camera._rightWC); - } + this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + this._mode = undefined; - if (positionChanged || directionChanged || upChanged || rightChanged || transformChanged) { - updateViewMatrix(camera); - } - } + this._readyPromise = when.defer(); + this._pointsLength = 0; + this._geometryByteLength = 0; - function getHeading(direction, up) { - var heading; - if (!CesiumMath.equalsEpsilon(Math.abs(direction.z), 1.0, CesiumMath.EPSILON3)) { - heading = Math.atan2(direction.y, direction.x) - CesiumMath.PI_OVER_TWO; - } else { - heading = Math.atan2(up.y, up.x) - CesiumMath.PI_OVER_TWO; - } + this._features = undefined; - return CesiumMath.TWO_PI - CesiumMath.zeroToTwoPi(heading); - } + this._packedClippingPlanes = []; + this._modelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); - function getPitch(direction) { - return CesiumMath.PI_OVER_TWO - CesiumMath.acosClamped(direction.z); - } + /** + * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + */ + this.featurePropertiesDirty = false; - function getRoll(direction, up, right) { - var roll = 0.0; - if (!CesiumMath.equalsEpsilon(Math.abs(direction.z), 1.0, CesiumMath.EPSILON3)) { - roll = Math.atan2(-right.z, up.z); - roll = CesiumMath.zeroToTwoPi(roll + CesiumMath.TWO_PI); - } + // Options for geometric error based attenuation + this._attenuation = false; + this._geometricErrorScale = undefined; + this._maximumAttenuation = undefined; + this._baseResolution = undefined; + this._baseResolutionApproximation = undefined; - return roll; + initialize(this, arrayBuffer, byteOffset); } - var scratchHPRMatrix1 = new Matrix4(); - var scratchHPRMatrix2 = new Matrix4(); + defineProperties(PointCloud3DTileContent.prototype, { + /** + * @inheritdoc Cesium3DTileContent#featuresLength + */ + featuresLength : { + get : function() { + if (defined(this._batchTable)) { + return this._batchTable.featuresLength; + } + return 0; + } + }, - defineProperties(Camera.prototype, { /** - * Gets the camera's reference frame. The inverse of this transformation is appended to the view matrix. - * @memberof Camera.prototype - * - * @type {Matrix4} - * @readonly - * - * @default {@link Matrix4.IDENTITY} + * @inheritdoc Cesium3DTileContent#pointsLength */ - transform : { + pointsLength : { get : function() { - return this._transform; + return this._pointsLength; } }, /** - * Gets the inverse camera transform. - * @memberof Camera.prototype - * - * @type {Matrix4} - * @readonly - * - * @default {@link Matrix4.IDENTITY} + * @inheritdoc Cesium3DTileContent#trianglesLength */ - inverseTransform : { + trianglesLength : { get : function() { - updateMembers(this); - return this._invTransform; + return 0; } }, /** - * Gets the view matrix. - * @memberof Camera.prototype - * - * @type {Matrix4} - * @readonly - * - * @see Camera#inverseViewMatrix + * @inheritdoc Cesium3DTileContent#geometryByteLength */ - viewMatrix : { + geometryByteLength : { get : function() { - updateMembers(this); - return this._viewMatrix; + return this._geometryByteLength; } }, /** - * Gets the inverse view matrix. - * @memberof Camera.prototype - * - * @type {Matrix4} - * @readonly - * - * @see Camera#viewMatrix + * @inheritdoc Cesium3DTileContent#texturesByteLength */ - inverseViewMatrix : { + texturesByteLength : { get : function() { - updateMembers(this); - return this._invViewMatrix; + return 0; } }, /** - * Gets the {@link Cartographic} position of the camera, with longitude and latitude - * expressed in radians and height in meters. In 2D and Columbus View, it is possible - * for the returned longitude and latitude to be outside the range of valid longitudes - * and latitudes when the camera is outside the map. - * @memberof Camera.prototype - * - * @type {Cartographic} - * @readonly + * @inheritdoc Cesium3DTileContent#batchTableByteLength */ - positionCartographic : { + batchTableByteLength : { get : function() { - updateMembers(this); - return this._positionCartographic; + if (defined(this._batchTable)) { + return this._batchTable.memorySizeInBytes; + } + return 0; } }, /** - * Gets the position of the camera in world coordinates. - * @memberof Camera.prototype - * - * @type {Cartesian3} - * @readonly + * @inheritdoc Cesium3DTileContent#innerContents */ - positionWC : { + innerContents : { get : function() { - updateMembers(this); - return this._positionWC; + return undefined; } }, /** - * Gets the view direction of the camera in world coordinates. - * @memberof Camera.prototype - * - * @type {Cartesian3} - * @readonly + * @inheritdoc Cesium3DTileContent#readyPromise */ - directionWC : { + readyPromise : { get : function() { - updateMembers(this); - return this._directionWC; + return this._readyPromise.promise; } }, /** - * Gets the up direction of the camera in world coordinates. - * @memberof Camera.prototype - * - * @type {Cartesian3} - * @readonly + * @inheritdoc Cesium3DTileContent#tileset */ - upWC : { + tileset : { get : function() { - updateMembers(this); - return this._upWC; + return this._tileset; } }, /** - * Gets the right direction of the camera in world coordinates. - * @memberof Camera.prototype - * - * @type {Cartesian3} - * @readonly + * @inheritdoc Cesium3DTileContent#tile */ - rightWC : { + tile : { get : function() { - updateMembers(this); - return this._rightWC; + return this._tile; } }, /** - * Gets the camera heading in radians. - * @memberof Camera.prototype - * - * @type {Number} - * @readonly + * @inheritdoc Cesium3DTileContent#url */ - heading : { + url : { get : function() { - if (this._mode !== SceneMode.MORPHING) { - var ellipsoid = this._projection.ellipsoid; + return this._resource.getUrlComponent(true); + } + }, - var oldTransform = Matrix4.clone(this._transform, scratchHPRMatrix1); - var transform = Transforms.eastNorthUpToFixedFrame(this.positionWC, ellipsoid, scratchHPRMatrix2); - this._setTransform(transform); + /** + * @inheritdoc Cesium3DTileContent#batchTable + */ + batchTable : { + get : function() { + return this._batchTable; + } + } + }); - var heading = getHeading(this.direction, this.up); + var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - this._setTransform(oldTransform); + function initialize(content, arrayBuffer, byteOffset) { + byteOffset = defaultValue(byteOffset, 0); - return heading; + var uint8Array = new Uint8Array(arrayBuffer); + var view = new DataView(arrayBuffer); + byteOffset += sizeOfUint32; // Skip magic + + var version = view.getUint32(byteOffset, true); + if (version !== 1) { + throw new RuntimeError('Only Point Cloud tile version 1 is supported. Version ' + version + ' is not.'); + } + byteOffset += sizeOfUint32; + + // Skip byteLength + byteOffset += sizeOfUint32; + + var featureTableJsonByteLength = view.getUint32(byteOffset, true); + if (featureTableJsonByteLength === 0) { + throw new RuntimeError('Feature table must have a byte length greater than zero'); + } + byteOffset += sizeOfUint32; + + var featureTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + + var batchTableJsonByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var batchTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + + var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength); + var featureTableJson = JSON.parse(featureTableString); + byteOffset += featureTableJsonByteLength; + + var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); + byteOffset += featureTableBinaryByteLength; + + // Get the batch table JSON and binary + var batchTableJson; + var batchTableBinary; + if (batchTableJsonByteLength > 0) { + // Has a batch table JSON + var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength); + batchTableJson = JSON.parse(batchTableString); + byteOffset += batchTableJsonByteLength; + + if (batchTableBinaryByteLength > 0) { + // Has a batch table binary + batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); + byteOffset += batchTableBinaryByteLength; + } + } + + var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); + + var pointsLength = featureTable.getGlobalProperty('POINTS_LENGTH'); + featureTable.featuresLength = pointsLength; + + if (!defined(pointsLength)) { + throw new RuntimeError('Feature table global property: POINTS_LENGTH must be defined'); + } + + // Get the positions + var positions; + var isQuantized = false; + + if (defined(featureTableJson.POSITION)) { + positions = featureTable.getPropertyArray('POSITION', ComponentDatatype.FLOAT, 3); + var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); + if (defined(rtcCenter)) { + content._rtcCenter = Cartesian3.unpack(rtcCenter); + } + } else if (defined(featureTableJson.POSITION_QUANTIZED)) { + positions = featureTable.getPropertyArray('POSITION_QUANTIZED', ComponentDatatype.UNSIGNED_SHORT, 3); + isQuantized = true; + + var quantizedVolumeScale = featureTable.getGlobalProperty('QUANTIZED_VOLUME_SCALE', ComponentDatatype.FLOAT, 3); + if (!defined(quantizedVolumeScale)) { + throw new RuntimeError('Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.'); + } + content._quantizedVolumeScale = Cartesian3.unpack(quantizedVolumeScale); + + var quantizedVolumeOffset = featureTable.getGlobalProperty('QUANTIZED_VOLUME_OFFSET', ComponentDatatype.FLOAT, 3); + if (!defined(quantizedVolumeOffset)) { + throw new RuntimeError('Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.'); + } + content._quantizedVolumeOffset = Cartesian3.unpack(quantizedVolumeOffset); + } + + if (!defined(positions)) { + throw new RuntimeError('Either POSITION or POSITION_QUANTIZED must be defined.'); + } + + // Get the colors + var colors; + var isTranslucent = false; + var isRGB565 = false; + + if (defined(featureTableJson.RGBA)) { + colors = featureTable.getPropertyArray('RGBA', ComponentDatatype.UNSIGNED_BYTE, 4); + isTranslucent = true; + } else if (defined(featureTableJson.RGB)) { + colors = featureTable.getPropertyArray('RGB', ComponentDatatype.UNSIGNED_BYTE, 3); + } else if (defined(featureTableJson.RGB565)) { + colors = featureTable.getPropertyArray('RGB565', ComponentDatatype.UNSIGNED_SHORT, 1); + isRGB565 = true; + } else if (defined(featureTableJson.CONSTANT_RGBA)) { + var constantRGBA = featureTable.getGlobalProperty('CONSTANT_RGBA', ComponentDatatype.UNSIGNED_BYTE, 4); + content._constantColor = Color.fromBytes(constantRGBA[0], constantRGBA[1], constantRGBA[2], constantRGBA[3], content._constantColor); + } else { + // Use a default constant color + content._constantColor = Color.clone(Color.DARKGRAY, content._constantColor); + } + + content._isTranslucent = isTranslucent; + + // Get the normals + var normals; + var isOctEncoded16P = false; + + if (defined(featureTableJson.NORMAL)) { + normals = featureTable.getPropertyArray('NORMAL', ComponentDatatype.FLOAT, 3); + } else if (defined(featureTableJson.NORMAL_OCT16P)) { + normals = featureTable.getPropertyArray('NORMAL_OCT16P', ComponentDatatype.UNSIGNED_BYTE, 2); + isOctEncoded16P = true; + } + + // Get the batchIds and batch table. BATCH_ID does not need to be defined when the point cloud has per-point properties. + var batchIds; + if (defined(featureTableJson.BATCH_ID)) { + batchIds = featureTable.getPropertyArray('BATCH_ID', ComponentDatatype.UNSIGNED_SHORT, 1); + + var batchLength = featureTable.getGlobalProperty('BATCH_LENGTH'); + if (!defined(batchLength)) { + throw new RuntimeError('Global property: BATCH_LENGTH must be defined when BATCH_ID is defined.'); + } + + if (defined(batchTableBinary)) { + // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed + batchTableBinary = new Uint8Array(batchTableBinary); + } + content._batchTable = new Cesium3DTileBatchTable(content, batchLength, batchTableJson, batchTableBinary); + } + + // If points are not batched and there are per-point properties, use these properties for styling purposes + var styleableProperties; + if (!defined(batchIds) && defined(batchTableBinary)) { + styleableProperties = Cesium3DTileBatchTable.getBinaryProperties(pointsLength, batchTableJson, batchTableBinary); + + // WebGL does not support UNSIGNED_INT, INT, or DOUBLE vertex attributes. Convert these to FLOAT. + for (var name in styleableProperties) { + if (styleableProperties.hasOwnProperty(name)) { + var property = styleableProperties[name]; + var typedArray = property.typedArray; + var componentDatatype = ComponentDatatype.fromTypedArray(typedArray); + if (componentDatatype === ComponentDatatype.INT || componentDatatype === ComponentDatatype.UNSIGNED_INT || componentDatatype === ComponentDatatype.DOUBLE) { + oneTimeWarning('Cast pnts property to floats', 'Point cloud property "' + name + '" will be casted to a float array because INT, UNSIGNED_INT, and DOUBLE are not valid WebGL vertex attribute types. Some precision may be lost.'); + property.typedArray = new Float32Array(typedArray); + } } + } + } - return undefined; + content._parsedContent = { + positions : positions, + colors : colors, + normals : normals, + batchIds : batchIds, + styleableProperties : styleableProperties + }; + content._pointsLength = pointsLength; + content._isQuantized = isQuantized; + content._isOctEncoded16P = isOctEncoded16P; + content._isRGB565 = isRGB565; + content._hasColors = defined(colors); + content._hasNormals = defined(normals); + content._hasBatchIds = defined(batchIds); + + // Compute an approximation for base resolution in case it isn't given. + // Assume a uniform distribution of points in cubical cells throughout the + // bounding sphere around the tile. + // Typical use case is leaves, where lower estimates of interpoint distance might + // lead to underattenuation. + var sphereVolume = content._tile.contentBoundingVolume.boundingSphere.volume(); + content._baseResolutionApproximation = Math.cbrt(sphereVolume / pointsLength); + } + + var scratchPointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier = new Cartesian4(); + + var positionLocation = 0; + var colorLocation = 1; + var normalLocation = 2; + var batchIdLocation = 3; + var numberOfAttributes = 4; + + function createResources(content, frameState) { + var context = frameState.context; + var parsedContent = content._parsedContent; + var pointsLength = content._pointsLength; + var positions = parsedContent.positions; + var colors = parsedContent.colors; + var normals = parsedContent.normals; + var batchIds = parsedContent.batchIds; + var styleableProperties = parsedContent.styleableProperties; + var hasStyleableProperties = defined(styleableProperties); + var isQuantized = content._isQuantized; + var isOctEncoded16P = content._isOctEncoded16P; + var isRGB565 = content._isRGB565; + var isTranslucent = content._isTranslucent; + var hasColors = content._hasColors; + var hasNormals = content._hasNormals; + var hasBatchIds = content._hasBatchIds; + + var batchTable = content._batchTable; + var hasBatchTable = defined(batchTable); + + var styleableVertexAttributes = []; + var styleableShaderAttributes = {}; + content._styleableShaderAttributes = styleableShaderAttributes; + + if (hasStyleableProperties) { + var attributeLocation = numberOfAttributes; + + for (var name in styleableProperties) { + if (styleableProperties.hasOwnProperty(name)) { + var property = styleableProperties[name]; + var typedArray = property.typedArray; + var componentCount = property.componentCount; + var componentDatatype = ComponentDatatype.fromTypedArray(typedArray); + + var vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : property.typedArray, + usage : BufferUsage.STATIC_DRAW + }); + + content._geometryByteLength += vertexBuffer.sizeInBytes; + + var vertexAttribute = { + index : attributeLocation, + vertexBuffer : vertexBuffer, + componentsPerAttribute : componentCount, + componentDatatype : componentDatatype, + normalize : false, + offsetInBytes : 0, + strideInBytes : 0 + }; + + styleableVertexAttributes.push(vertexAttribute); + styleableShaderAttributes[name] = { + location : attributeLocation, + componentCount : componentCount + }; + ++attributeLocation; + } } - }, + } - /** - * Gets the camera pitch in radians. - * @memberof Camera.prototype - * - * @type {Number} - * @readonly - */ - pitch : { - get : function() { - if (this._mode !== SceneMode.MORPHING) { - var ellipsoid = this._projection.ellipsoid; + var uniformMap = { + u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier : function() { + var scratch = scratchPointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier; + scratch.x = content._attenuation ? content._maximumAttenuation : content._pointSize; + scratch.y = content._tileset.timeSinceLoad; + + if (content._attenuation) { + var geometricError = content.tile.geometricError; + if (geometricError === 0) { + geometricError = defined(content._baseResolution) ? content._baseResolution : content._baseResolutionApproximation; + } + var frustum = frameState.camera.frustum; + var depthMultiplier; + // Attenuation is maximumAttenuation in 2D/ortho + if (frameState.mode === SceneMode.SCENE2D || frustum instanceof OrthographicFrustum) { + depthMultiplier = Number.POSITIVE_INFINITY; + } else { + depthMultiplier = context.drawingBufferHeight / frameState.camera.frustum.sseDenominator; + } - var oldTransform = Matrix4.clone(this._transform, scratchHPRMatrix1); - var transform = Transforms.eastNorthUpToFixedFrame(this.positionWC, ellipsoid, scratchHPRMatrix2); - this._setTransform(transform); + scratch.z = geometricError * content._geometricErrorScale; + scratch.w = depthMultiplier; + } - var pitch = getPitch(this.direction); + return scratch; + }, + u_highlightColor : function() { + return content._highlightColor; + }, + u_constantColor : function() { + return content._constantColor; + }, + u_clippingPlanesLength : function() { + return content._packedClippingPlanes.length; + }, + u_clippingPlanes : function() { + return content._packedClippingPlanes; + }, + u_clippingPlanesEdgeStyle : function() { + var clippingPlanes = content._tileset.clippingPlanes; - this._setTransform(oldTransform); + if (!defined(clippingPlanes)) { + return Color.WHITE.withAlpha(0.0); + } - return pitch; + var style = Color.clone(clippingPlanes.edgeColor); + style.alpha = clippingPlanes.edgeWidth; + return style; + } + }; + + if (isQuantized) { + uniformMap = combine(uniformMap, { + u_quantizedVolumeScale : function() { + return content._quantizedVolumeScale; } + }); + } - return undefined; + var positionsVertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : positions, + usage : BufferUsage.STATIC_DRAW + }); + content._geometryByteLength += positionsVertexBuffer.sizeInBytes; + + var colorsVertexBuffer; + if (hasColors) { + colorsVertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : colors, + usage : BufferUsage.STATIC_DRAW + }); + content._geometryByteLength += colorsVertexBuffer.sizeInBytes; + } + + var normalsVertexBuffer; + if (hasNormals) { + normalsVertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : normals, + usage : BufferUsage.STATIC_DRAW + }); + content._geometryByteLength += normalsVertexBuffer.sizeInBytes; + } + + var batchIdsVertexBuffer; + if (hasBatchIds) { + batchIdsVertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : batchIds, + usage : BufferUsage.STATIC_DRAW + }); + content._geometryByteLength += batchIdsVertexBuffer.sizeInBytes; + } + + var attributes = []; + if (isQuantized) { + attributes.push({ + index : positionLocation, + vertexBuffer : positionsVertexBuffer, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.UNSIGNED_SHORT, + normalize : true, // Convert position to 0 to 1 before entering the shader + offsetInBytes : 0, + strideInBytes : 0 + }); + } else { + attributes.push({ + index : positionLocation, + vertexBuffer : positionsVertexBuffer, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + normalize : false, + offsetInBytes : 0, + strideInBytes : 0 + }); + } + + if (hasColors) { + if (isRGB565) { + attributes.push({ + index : colorLocation, + vertexBuffer : colorsVertexBuffer, + componentsPerAttribute : 1, + componentDatatype : ComponentDatatype.UNSIGNED_SHORT, + normalize : false, + offsetInBytes : 0, + strideInBytes : 0 + }); + } else { + var colorComponentsPerAttribute = isTranslucent ? 4 : 3; + attributes.push({ + index : colorLocation, + vertexBuffer : colorsVertexBuffer, + componentsPerAttribute : colorComponentsPerAttribute, + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + normalize : true, + offsetInBytes : 0, + strideInBytes : 0 + }); } - }, + } - /** - * Gets the camera roll in radians. - * @memberof Camera.prototype - * - * @type {Number} - * @readonly - */ - roll : { - get : function() { - if (this._mode !== SceneMode.MORPHING) { - var ellipsoid = this._projection.ellipsoid; + if (hasNormals) { + if (isOctEncoded16P) { + attributes.push({ + index : normalLocation, + vertexBuffer : normalsVertexBuffer, + componentsPerAttribute : 2, + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + normalize : false, + offsetInBytes : 0, + strideInBytes : 0 + }); + } else { + attributes.push({ + index : normalLocation, + vertexBuffer : normalsVertexBuffer, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + normalize : false, + offsetInBytes : 0, + strideInBytes : 0 + }); + } + } + + if (hasBatchIds) { + attributes.push({ + index : batchIdLocation, + vertexBuffer : batchIdsVertexBuffer, + componentsPerAttribute : 1, + componentDatatype : ComponentDatatype.fromTypedArray(batchIds), + normalize : false, + offsetInBytes : 0, + strideInBytes : 0 + }); + } + + if (hasStyleableProperties) { + attributes = attributes.concat(styleableVertexAttributes); + } + + var vertexArray = new VertexArray({ + context : context, + attributes : attributes + }); - var oldTransform = Matrix4.clone(this._transform, scratchHPRMatrix1); - var transform = Transforms.eastNorthUpToFixedFrame(this.positionWC, ellipsoid, scratchHPRMatrix2); - this._setTransform(transform); + var drawUniformMap = uniformMap; - var roll = getRoll(this.direction, this.up, this.right); + if (hasBatchTable) { + drawUniformMap = batchTable.getUniformMapCallback()(uniformMap); + } - this._setTransform(oldTransform); + var pickUniformMap; - return roll; + if (hasBatchTable) { + pickUniformMap = batchTable.getPickUniformMapCallback()(uniformMap); + } else { + content._pickId = context.createPickId({ + primitive : content._tileset, + content : content + }); + + pickUniformMap = combine(uniformMap, { + czm_pickColor : function() { + return content._pickId.color; } + }); + } - return undefined; + content._opaqueRenderState = RenderState.fromCache({ + depthTest : { + enabled : true } - }, + }); - /** - * Gets the event that will be raised at when the camera starts to move. - * @memberof Camera.prototype - * @type {Event} - * @readonly - */ - moveStart : { - get : function() { - return this._moveStart; - } - }, + content._translucentRenderState = RenderState.fromCache({ + depthTest : { + enabled : true + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND + }); - /** - * Gets the event that will be raised when the camera has stopped moving. - * @memberof Camera.prototype - * @type {Event} - * @readonly - */ - moveEnd : { - get : function() { - return this._moveEnd; - } - }, + content._drawCommand = new DrawCommand({ + boundingVolume : undefined, // Updated in update + cull : false, // Already culled by 3D Tiles + modelMatrix : new Matrix4(), + primitiveType : PrimitiveType.POINTS, + vertexArray : vertexArray, + count : pointsLength, + shaderProgram : undefined, // Updated in createShaders + uniformMap : drawUniformMap, + renderState : isTranslucent ? content._translucentRenderState : content._opaqueRenderState, + pass : isTranslucent ? Pass.TRANSLUCENT : Pass.CESIUM_3D_TILE, + owner : content, + castShadows : false, + receiveShadows : false + }); - /** - * Gets the event that will be raised when the camera has changed by <code>percentageChanged</code>. - * @memberof Camera.prototype - * @type {Event} - * @readonly - */ - changed : { - get : function() { - return this._changed; + content._pickCommand = new DrawCommand({ + boundingVolume : undefined, // Updated in update + cull : false, // Already culled by 3D Tiles + modelMatrix : new Matrix4(), + primitiveType : PrimitiveType.POINTS, + vertexArray : vertexArray, + count : pointsLength, + shaderProgram : undefined, // Updated in createShaders + uniformMap : pickUniformMap, + renderState : isTranslucent ? content._translucentRenderState : content._opaqueRenderState, + pass : isTranslucent ? Pass.TRANSLUCENT : Pass.CESIUM_3D_TILE, + owner : content + }); + } + + var defaultProperties = ['POSITION', 'COLOR', 'NORMAL', 'POSITION_ABSOLUTE']; + + function getStyleableProperties(source, properties) { + // Get all the properties used by this style + var regex = /czm_tiles3d_style_(\w+)/g; + var matches = regex.exec(source); + while (matches !== null) { + var name = matches[1]; + if (properties.indexOf(name) === -1) { + properties.push(name); } + matches = regex.exec(source); } - }); + } - /** - * @private - */ - Camera.prototype.update = function(mode) { - if (!defined(mode)) { - throw new DeveloperError('mode is required.'); - } - if (mode === SceneMode.SCENE2D && !(this.frustum instanceof OrthographicOffCenterFrustum)) { - throw new DeveloperError('An OrthographicOffCenterFrustum is required in 2D.'); - } - if ((mode === SceneMode.SCENE3D || mode === SceneMode.COLUMBUS_VIEW) && - (!(this.frustum instanceof PerspectiveFrustum) && !(this.frustum instanceof OrthographicFrustum))) { - throw new DeveloperError('A PerspectiveFrustum or OrthographicFrustum is required in 3D and Columbus view'); + function getVertexAttribute(vertexArray, index) { + var numberOfAttributes = vertexArray.numberOfAttributes; + for (var i = 0; i < numberOfAttributes; ++i) { + var attribute = vertexArray.getAttribute(i); + if (attribute.index === index) { + return attribute; + } } - - var updateFrustum = false; - if (mode !== this._mode) { - this._mode = mode; - this._modeChanged = mode !== SceneMode.MORPHING; - updateFrustum = this._mode === SceneMode.SCENE2D; + } + + function modifyStyleFunction(source) { + // Replace occurrences of czm_tiles3d_style_DEFAULTPROPERTY + var length = defaultProperties.length; + for (var i = 0; i < length; ++i) { + var property = defaultProperties[i]; + var styleName = 'czm_tiles3d_style_' + property; + var replaceName = property.toLowerCase(); + source = source.replace(new RegExp(styleName + '(\\W)', 'g'), replaceName + '$1'); } - if (updateFrustum) { - var frustum = this._max2Dfrustum = this.frustum.clone(); + // Edit the function header to accept the point position, color, and normal + return source.replace('()', '(vec3 position, vec3 position_absolute, vec4 color, vec3 normal)'); + } - if (!(frustum instanceof OrthographicOffCenterFrustum)) { - throw new DeveloperError('The camera frustum is expected to be orthographic for 2D camera control.'); - } - - var maxZoomOut = 2.0; - var ratio = frustum.top / frustum.right; - frustum.right = this._maxCoord.x * maxZoomOut; - frustum.left = -frustum.right; - frustum.top = ratio * frustum.right; - frustum.bottom = -frustum.top; - } + function createShaders(content, frameState, style) { + var i; + var name; + var attribute; - if (this._mode === SceneMode.SCENE2D) { - clampMove2D(this, this.position); + var context = frameState.context; + var batchTable = content._batchTable; + var hasBatchTable = defined(batchTable); + var hasStyle = defined(style); + var isQuantized = content._isQuantized; + var isOctEncoded16P = content._isOctEncoded16P; + var isRGB565 = content._isRGB565; + var isTranslucent = content._isTranslucent; + var hasColors = content._hasColors; + var hasNormals = content._hasNormals; + var hasBatchIds = content._hasBatchIds; + var backFaceCulling = content._backFaceCulling; + var vertexArray = content._drawCommand.vertexArray; + var clippingPlanes = content._tileset.clippingPlanes; + var attenuation = content._attenuation; + + var colorStyleFunction; + var showStyleFunction; + var pointSizeStyleFunction; + var styleTranslucent = isTranslucent; + + if (hasBatchTable) { + // Styling is handled in the batch table + hasStyle = false; } - var globe = this._scene.globe; - var globeFinishedUpdating = !defined(globe) || (globe._surface.tileProvider.ready && globe._surface._tileLoadQueueHigh.length === 0 && globe._surface._tileLoadQueueMedium.length === 0 && globe._surface._tileLoadQueueLow.length === 0 && globe._surface._debug.tilesWaitingForChildren === 0); - if (this._suspendTerrainAdjustment) { - this._suspendTerrainAdjustment = !globeFinishedUpdating; + if (hasStyle) { + var shaderState = { + translucent : false + }; + colorStyleFunction = style.getColorShaderFunction('getColorFromStyle', 'czm_tiles3d_style_', shaderState); + showStyleFunction = style.getShowShaderFunction('getShowFromStyle', 'czm_tiles3d_style_', shaderState); + pointSizeStyleFunction = style.getPointSizeShaderFunction('getPointSizeFromStyle', 'czm_tiles3d_style_', shaderState); + if (defined(colorStyleFunction) && shaderState.translucent) { + styleTranslucent = true; + } } - this._adjustHeightForTerrain(); - }; - var setTransformPosition = new Cartesian3(); - var setTransformUp = new Cartesian3(); - var setTransformDirection = new Cartesian3(); + content._styleTranslucent = styleTranslucent; - Camera.prototype._setTransform = function(transform) { - var position = Cartesian3.clone(this.positionWC, setTransformPosition); - var up = Cartesian3.clone(this.upWC, setTransformUp); - var direction = Cartesian3.clone(this.directionWC, setTransformDirection); + var hasColorStyle = defined(colorStyleFunction); + var hasShowStyle = defined(showStyleFunction); + var hasPointSizeStyle = defined(pointSizeStyleFunction); + var hasClippedContent = defined(clippingPlanes) && clippingPlanes.enabled && content._tile._isClipped && ClippingPlaneCollection.isSupported(); - Matrix4.clone(transform, this._transform); - this._transformChanged = true; - updateMembers(this); - var inverse = this._actualInvTransform; + // Get the properties in use by the style + var styleableProperties = []; - Matrix4.multiplyByPoint(inverse, position, this.position); - Matrix4.multiplyByPointAsVector(inverse, direction, this.direction); - Matrix4.multiplyByPointAsVector(inverse, up, this.up); - Cartesian3.cross(this.direction, this.up, this.right); + if (hasColorStyle) { + getStyleableProperties(colorStyleFunction, styleableProperties); + colorStyleFunction = modifyStyleFunction(colorStyleFunction); + } + if (hasShowStyle) { + getStyleableProperties(showStyleFunction, styleableProperties); + showStyleFunction = modifyStyleFunction(showStyleFunction); + } + if (hasPointSizeStyle) { + getStyleableProperties(pointSizeStyleFunction, styleableProperties); + pointSizeStyleFunction = modifyStyleFunction(pointSizeStyleFunction); + } - updateMembers(this); - }; + var usesColorSemantic = styleableProperties.indexOf('COLOR') >= 0; + var usesNormalSemantic = styleableProperties.indexOf('NORMAL') >= 0; - var scratchAdjustOrtghographicFrustumMousePosition = new Cartesian2(); - var pickGlobeScratchRay = new Ray(); - var scratchRayIntersection = new Cartesian3(); - var scratchDepthIntersection = new Cartesian3(); + // Split default properties from user properties + var userProperties = styleableProperties.filter(function(property) { return defaultProperties.indexOf(property) === -1; }); - Camera.prototype._adjustOrthographicFrustum = function(zooming) { - if (!(this.frustum instanceof OrthographicFrustum)) { - return; + if (usesNormalSemantic && !hasNormals) { + throw new RuntimeError('Style references the NORMAL semantic but the point cloud does not have normals'); } - if (!zooming && this._positionCartographic.height < 150000.0) { - return; + // Disable vertex attributes that aren't used in the style, enable attributes that are + var styleableShaderAttributes = content._styleableShaderAttributes; + for (name in styleableShaderAttributes) { + if (styleableShaderAttributes.hasOwnProperty(name)) { + attribute = styleableShaderAttributes[name]; + var enabled = (userProperties.indexOf(name) >= 0); + var vertexAttribute = getVertexAttribute(vertexArray, attribute.location); + vertexAttribute.enabled = enabled; + } } - if (!Matrix4.equals(Matrix4.IDENTITY, this.transform)) { - this.frustum.width = Cartesian3.magnitude(this.position); - return; + var usesColors = hasColors && (!hasColorStyle || usesColorSemantic); + if (hasColors) { + // Disable the color vertex attribute if the color style does not reference the color semantic + var colorVertexAttribute = getVertexAttribute(vertexArray, colorLocation); + colorVertexAttribute.enabled = usesColors; } - var scene = this._scene; - var globe = scene._globe; - var rayIntersection; - var depthIntersection; - - if (defined(globe)) { - var mousePosition = scratchAdjustOrtghographicFrustumMousePosition; - mousePosition.x = scene.drawingBufferWidth / 2.0; - mousePosition.y = scene.drawingBufferHeight / 2.0; + var attributeLocations = { + a_position : positionLocation + }; + if (usesColors) { + attributeLocations.a_color = colorLocation; + } + if (hasNormals) { + attributeLocations.a_normal = normalLocation; + } + if (hasBatchIds) { + attributeLocations.a_batchId = batchIdLocation; + } - var ray = this.getPickRay(mousePosition, pickGlobeScratchRay); - rayIntersection = globe.pick(ray, scene, scratchRayIntersection); + var attributeDeclarations = ''; - if (scene.pickPositionSupported) { - depthIntersection = scene.pickPositionWorldCoordinates(mousePosition, scratchDepthIntersection); + var length = userProperties.length; + for (i = 0; i < length; ++i) { + name = userProperties[i]; + attribute = styleableShaderAttributes[name]; + if (!defined(attribute)) { + throw new RuntimeError('Style references a property "' + name + '" that does not exist or is not styleable.'); } - if (defined(rayIntersection) && defined(depthIntersection)) { - var depthDistance = defined(depthIntersection) ? Cartesian3.distance(depthIntersection, this.positionWC) : Number.POSITIVE_INFINITY; - var rayDistance = defined(rayIntersection) ? Cartesian3.distance(rayIntersection, this.positionWC) : Number.POSITIVE_INFINITY; - this.frustum.width = Math.min(depthDistance, rayDistance); - } else if (defined(depthIntersection)) { - this.frustum.width = Cartesian3.distance(depthIntersection, this.positionWC); - } else if (defined(rayIntersection)) { - this.frustum.width = Cartesian3.distance(rayIntersection, this.positionWC); + var componentCount = attribute.componentCount; + var attributeName = 'czm_tiles3d_style_' + name; + var attributeType; + if (componentCount === 1) { + attributeType = 'float'; + } else { + attributeType = 'vec' + componentCount; } - } - if (!defined(globe) || (!defined(rayIntersection) && !defined(depthIntersection))) { - var distance = Math.max(this.positionCartographic.height, 0.0); - this.frustum.width = distance; + attributeDeclarations += 'attribute ' + attributeType + ' ' + attributeName + '; \n'; + attributeLocations[attributeName] = attribute.location; } - }; - - var scratchSetViewCartesian = new Cartesian3(); - var scratchSetViewTransform1 = new Matrix4(); - var scratchSetViewTransform2 = new Matrix4(); - var scratchSetViewQuaternion = new Quaternion(); - var scratchSetViewMatrix3 = new Matrix3(); - var scratchSetViewCartographic = new Cartographic(); - - function setView3D(camera, position, hpr) { - var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); - var localTransform = Transforms.eastNorthUpToFixedFrame(position, camera._projection.ellipsoid, scratchSetViewTransform2); - camera._setTransform(localTransform); - - Cartesian3.clone(Cartesian3.ZERO, camera.position); - hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); - var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); + var vs = 'attribute vec3 a_position; \n' + + 'varying vec4 v_color; \n' + + 'uniform vec4 u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier; \n' + + 'uniform vec4 u_constantColor; \n' + + 'uniform vec4 u_highlightColor; \n'; + vs += 'float u_pointSize; \n' + + 'float u_tilesetTime; \n'; - Matrix3.getColumn(rotMat, 0, camera.direction); - Matrix3.getColumn(rotMat, 2, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); + if (attenuation) { + vs += 'float u_geometricError; \n' + + 'float u_depthMultiplier; \n'; + } - camera._setTransform(currentTransform); + vs += attributeDeclarations; - camera._adjustOrthographicFrustum(true); - } + if (usesColors) { + if (isTranslucent) { + vs += 'attribute vec4 a_color; \n'; + } else if (isRGB565) { + vs += 'attribute float a_color; \n' + + 'const float SHIFT_RIGHT_11 = 1.0 / 2048.0; \n' + + 'const float SHIFT_RIGHT_5 = 1.0 / 32.0; \n' + + 'const float SHIFT_LEFT_11 = 2048.0; \n' + + 'const float SHIFT_LEFT_5 = 32.0; \n' + + 'const float NORMALIZE_6 = 1.0 / 64.0; \n' + + 'const float NORMALIZE_5 = 1.0 / 32.0; \n'; + } else { + vs += 'attribute vec3 a_color; \n'; + } + } + if (hasNormals) { + if (isOctEncoded16P) { + vs += 'attribute vec2 a_normal; \n'; + } else { + vs += 'attribute vec3 a_normal; \n'; + } + } - function setViewCV(camera, position,hpr, convert) { - var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); - camera._setTransform(Matrix4.IDENTITY); + if (hasBatchIds) { + vs += 'attribute float a_batchId; \n'; + } - if (!Cartesian3.equals(position, camera.positionWC)) { - if (convert) { - var projection = camera._projection; - var cartographic = projection.ellipsoid.cartesianToCartographic(position, scratchSetViewCartographic); - position = projection.project(cartographic, scratchSetViewCartesian); - } - Cartesian3.clone(position, camera.position); + if (isQuantized) { + vs += 'uniform vec3 u_quantizedVolumeScale; \n'; } - hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); - var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); + if (hasColorStyle) { + vs += colorStyleFunction; + } - Matrix3.getColumn(rotMat, 0, camera.direction); - Matrix3.getColumn(rotMat, 2, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); + if (hasShowStyle) { + vs += showStyleFunction; + } - camera._setTransform(currentTransform); + if (hasPointSizeStyle) { + vs += pointSizeStyleFunction; + } - camera._adjustOrthographicFrustum(true); - } + vs += 'void main() \n' + + '{ \n' + + ' u_pointSize = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.x; \n' + + ' u_tilesetTime = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.y; \n'; - function setView2D(camera, position, hpr, convert) { - var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); - camera._setTransform(Matrix4.IDENTITY); + if (attenuation) { + vs += ' u_geometricError = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.z; \n' + + ' u_depthMultiplier = u_pointSizeAndTilesetTimeAndGeometricErrorAndDepthMultiplier.w; \n'; + } - if (!Cartesian3.equals(position, camera.positionWC)) { - if (convert) { - var projection = camera._projection; - var cartographic = projection.ellipsoid.cartesianToCartographic(position, scratchSetViewCartographic); - position = projection.project(cartographic, scratchSetViewCartesian); + if (usesColors) { + if (isTranslucent) { + vs += ' vec4 color = a_color; \n'; + } else if (isRGB565) { + vs += ' float compressed = a_color; \n' + + ' float r = floor(compressed * SHIFT_RIGHT_11); \n' + + ' compressed -= r * SHIFT_LEFT_11; \n' + + ' float g = floor(compressed * SHIFT_RIGHT_5); \n' + + ' compressed -= g * SHIFT_LEFT_5; \n' + + ' float b = compressed; \n' + + ' vec3 rgb = vec3(r * NORMALIZE_5, g * NORMALIZE_6, b * NORMALIZE_5); \n' + + ' vec4 color = vec4(rgb, 1.0); \n'; + } else { + vs += ' vec4 color = vec4(a_color, 1.0); \n'; } + } else { + vs += ' vec4 color = u_constantColor; \n'; + } - Cartesian2.clone(position, camera.position); - - var newLeft = -position.z * 0.5; - var newRight = -newLeft; + if (isQuantized) { + vs += ' vec3 position = a_position * u_quantizedVolumeScale; \n'; + } else { + vs += ' vec3 position = a_position; \n'; + } + vs += ' vec3 position_absolute = vec3(czm_model * vec4(position, 1.0)); \n'; - var frustum = camera.frustum; - if (newRight > newLeft) { - var ratio = frustum.top / frustum.right; - frustum.right = newRight; - frustum.left = newLeft; - frustum.top = frustum.right * ratio; - frustum.bottom = -frustum.top; + if (hasNormals) { + if (isOctEncoded16P) { + vs += ' vec3 normal = czm_octDecode(a_normal); \n'; + } else { + vs += ' vec3 normal = a_normal; \n'; } + } else { + vs += ' vec3 normal = vec3(1.0); \n'; } - if (camera._scene.mapMode2D === MapMode2D.ROTATE) { - hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - hpr.pitch = -CesiumMath.PI_OVER_TWO; - hpr.roll = 0.0; - var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); - var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); + if (hasColorStyle) { + vs += ' color = getColorFromStyle(position, position_absolute, color, normal); \n'; + } - Matrix3.getColumn(rotMat, 2, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); + if (hasShowStyle) { + vs += ' float show = float(getShowFromStyle(position, position_absolute, color, normal)); \n'; } - camera._setTransform(currentTransform); - } + if (hasPointSizeStyle) { + vs += ' gl_PointSize = getPointSizeFromStyle(position, position_absolute, color, normal); \n'; + } else if (attenuation) { + vs += ' vec4 positionEC = czm_modelView * vec4(position, 1.0); \n' + + ' float depth = -positionEC.z; \n' + + // compute SSE for this point + ' gl_PointSize = min((u_geometricError / depth) * u_depthMultiplier, u_pointSize); \n'; + } else { + vs += ' gl_PointSize = u_pointSize; \n'; + } - var scratchToHPRDirection = new Cartesian3(); - var scratchToHPRUp = new Cartesian3(); - var scratchToHPRRight = new Cartesian3(); + vs += ' color = color * u_highlightColor; \n'; - function directionUpToHeadingPitchRoll(camera, position, orientation, result) { - var direction = Cartesian3.clone(orientation.direction, scratchToHPRDirection); - var up = Cartesian3.clone(orientation.up, scratchToHPRUp); + if (hasNormals) { + vs += ' normal = czm_normal * normal; \n' + + ' float diffuseStrength = czm_getLambertDiffuse(czm_sunDirectionEC, normal); \n' + + ' diffuseStrength = max(diffuseStrength, 0.4); \n' + // Apply some ambient lighting + ' color.xyz *= diffuseStrength; \n'; + } - if (camera._scene.mode === SceneMode.SCENE3D) { - var ellipsoid = camera._projection.ellipsoid; - var transform = Transforms.eastNorthUpToFixedFrame(position, ellipsoid, scratchHPRMatrix1); - var invTransform = Matrix4.inverseTransformation(transform, scratchHPRMatrix2); + vs += ' v_color = color; \n' + + ' gl_Position = czm_modelViewProjection * vec4(position, 1.0); \n'; - Matrix4.multiplyByPointAsVector(invTransform, direction, direction); - Matrix4.multiplyByPointAsVector(invTransform, up, up); + if (hasNormals && backFaceCulling) { + vs += ' float visible = step(-normal.z, 0.0); \n' + + ' gl_Position *= visible; \n' + + ' gl_PointSize *= visible; \n'; } - var right = Cartesian3.cross(direction, up, scratchToHPRRight); + if (hasShowStyle) { + vs += ' gl_Position *= show; \n' + + ' gl_PointSize *= show; \n'; + } - result.heading = getHeading(direction, up); - result.pitch = getPitch(direction); - result.roll = getRoll(direction, up, right); + vs += '} \n'; - return result; - } + var fs = 'varying vec4 v_color; \n'; - var scratchSetViewOptions = { - destination : undefined, - orientation : { - direction : undefined, - up : undefined, - heading : undefined, - pitch : undefined, - roll : undefined - }, - convert : undefined, - endTransform : undefined - }; + if (hasClippedContent) { + fs += 'uniform int u_clippingPlanesLength;' + + 'uniform vec4 u_clippingPlanes[czm_maxClippingPlanes]; \n' + + 'uniform vec4 u_clippingPlanesEdgeStyle; \n'; + } - var scratchHpr = new HeadingPitchRoll(); - /** - * Sets the camera position, orientation and transform. - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3|Rectangle} [options.destination] The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. - * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pitch and roll properties. By default, the direction will point - * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive - * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. - * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame of the camera. - * - * @example - * // 1. Set position with a top-down view - * viewer.camera.setView({ - * destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0) - * }); - * - * // 2 Set view with heading, pitch and roll - * viewer.camera.setView({ - * destination : cartesianPosition, - * orientation: { - * heading : Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north) - * pitch : Cesium.Math.toRadians(-90), // default value (looking down) - * roll : 0.0 // default value - * } - * }); - * - * // 3. Change heading, pitch and roll with the camera position remaining the same. - * viewer.camera.setView({ - * orientation: { - * heading : Cesium.Math.toRadians(90.0), // east, default value is 0.0 (north) - * pitch : Cesium.Math.toRadians(-90), // default value (looking down) - * roll : 0.0 // default value - * } - * }); - * - * - * // 4. View rectangle with a top-down view - * viewer.camera.setView({ - * destination : Cesium.Rectangle.fromDegrees(west, south, east, north) - * }); - * - * // 5. Set position with an orientation using unit vectors. - * viewer.camera.setView({ - * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), - * orientation : { - * direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734), - * up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339) - * } - * }); - */ - Camera.prototype.setView = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var orientation = defaultValue(options.orientation, defaultValue.EMPTY_OBJECT); + fs += 'void main() \n' + + '{ \n' + + ' gl_FragColor = v_color; \n'; - var mode = this._mode; - if (mode === SceneMode.MORPHING) { - return; + if (hasClippedContent) { + var clippingFunction = clippingPlanes.unionClippingRegions ? 'czm_discardIfClippedWithUnion' : 'czm_discardIfClippedWithIntersect'; + fs += ' float clipDistance = ' + clippingFunction + '(u_clippingPlanes, u_clippingPlanesLength); \n' + + ' vec4 clippingPlanesEdgeColor = vec4(1.0); \n' + + ' clippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb; \n' + + ' float clippingPlanesEdgeWidth = u_clippingPlanesEdgeStyle.a; \n' + + ' if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n' + + ' { \n' + + ' gl_FragColor = clippingPlanesEdgeColor; \n' + + ' } \n'; } - if (defined(options.endTransform)) { - this._setTransform(options.endTransform); - } + fs += '} \n'; - var convert = defaultValue(options.convert, true); - var destination = defaultValue(options.destination, Cartesian3.clone(this.positionWC, scratchSetViewCartesian)); - if (defined(destination) && defined(destination.west)) { - destination = this.getRectangleCameraCoordinates(destination, scratchSetViewCartesian); - convert = false; - } + var drawVS = vs; + var drawFS = fs; - if (defined(orientation.direction)) { - orientation = directionUpToHeadingPitchRoll(this, destination, orientation, scratchSetViewOptions.orientation); + if (hasBatchTable) { + // Batched points always use the HIGHLIGHT color blend mode + drawVS = batchTable.getVertexShaderCallback(false, 'a_batchId', undefined)(drawVS); + drawFS = batchTable.getFragmentShaderCallback(false, undefined)(drawFS); } - scratchHpr.heading = defaultValue(orientation.heading, 0.0); - scratchHpr.pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO); - scratchHpr.roll = defaultValue(orientation.roll, 0.0); - - this._suspendTerrainAdjustment = true; + var pickVS = vs; + var pickFS = fs; - if (mode === SceneMode.SCENE3D) { - setView3D(this, destination, scratchHpr); - } else if (mode === SceneMode.SCENE2D) { - setView2D(this, destination, scratchHpr, convert); + if (hasBatchTable) { + pickVS = batchTable.getPickVertexShaderCallback('a_batchId')(pickVS); + pickFS = batchTable.getPickFragmentShaderCallback()(pickFS); } else { - setViewCV(this, destination, scratchHpr, convert); + pickFS = ShaderSource.createPickFragmentShaderSource(pickFS, 'uniform'); } - }; - - var pitchScratch = new Cartesian3(); - /** - * Fly the camera to the home view. Use {@link Camera#.DEFAULT_VIEW_RECTANGLE} to set - * the default view for the 3D scene. The home view for 2D and columbus view shows the - * entire map. - * - * @param {Number} [duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. See {@link Camera#flyTo} - */ - Camera.prototype.flyHome = function(duration) { - var mode = this._mode; - if (mode === SceneMode.MORPHING) { - this._scene.completeMorph(); + var drawCommand = content._drawCommand; + if (defined(drawCommand.shaderProgram)) { + // Destroy the old shader + drawCommand.shaderProgram.destroy(); } + drawCommand.shaderProgram = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : drawVS, + fragmentShaderSource : drawFS, + attributeLocations : attributeLocations + }); - if (mode === SceneMode.SCENE2D) { - this.flyTo({ - destination : Camera.DEFAULT_VIEW_RECTANGLE, - duration : duration, - endTransform : Matrix4.IDENTITY - }); - } else if (mode === SceneMode.SCENE3D) { - var destination = this.getRectangleCameraCoordinates(Camera.DEFAULT_VIEW_RECTANGLE); - - var mag = Cartesian3.magnitude(destination); - mag += mag * Camera.DEFAULT_VIEW_FACTOR; - Cartesian3.normalize(destination, destination); - Cartesian3.multiplyByScalar(destination, mag, destination); - - this.flyTo({ - destination : destination, - duration : duration, - endTransform : Matrix4.IDENTITY - }); - } else if (mode === SceneMode.COLUMBUS_VIEW) { - var maxRadii = this._projection.ellipsoid.maximumRadius; - var position = new Cartesian3(0.0, -1.0, 1.0); - position = Cartesian3.multiplyByScalar(Cartesian3.normalize(position, position), 5.0 * maxRadii, position); - this.flyTo({ - destination : position, - duration : duration, - orientation : { - heading : 0.0, - pitch : -Math.acos(Cartesian3.normalize(position, pitchScratch).z), - roll : 0.0 - }, - endTransform : Matrix4.IDENTITY, - convert : false - }); + var pickCommand = content._pickCommand; + if (defined(pickCommand.shaderProgram)) { + // Destroy the old shader + pickCommand.shaderProgram.destroy(); } - }; + pickCommand.shaderProgram = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : pickVS, + fragmentShaderSource : pickFS, + attributeLocations : attributeLocations + }); - /** - * Transform a vector or point from world coordinates to the camera's reference frame. - * - * @param {Cartesian4} cartesian The vector or point to transform. - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The transformed vector or point. - */ - Camera.prototype.worldToCameraCoordinates = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); + try { + // Check if the shader compiles correctly. If not there is likely a syntax error with the style. + drawCommand.shaderProgram._bind(); + } catch (error) { + // Rephrase the error. + throw new RuntimeError('Error generating style shader: this may be caused by a type mismatch, index out-of-bounds, or other syntax error.'); } - - if (!defined(result)) { - result = new Cartesian4(); + } + + function createFeatures(content) { + var featuresLength = content.featuresLength; + if (!defined(content._features) && (featuresLength > 0)) { + var features = new Array(featuresLength); + for (var i = 0; i < featuresLength; ++i) { + features[i] = new Cesium3DTileFeature(content, i); + } + content._features = features; } - updateMembers(this); - return Matrix4.multiplyByVector(this._actualInvTransform, cartesian, result); - }; + } /** - * Transform a point from world coordinates to the camera's reference frame. - * - * @param {Cartesian3} cartesian The point to transform. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The transformed point. + * @inheritdoc Cesium3DTileContent#hasProperty */ - Camera.prototype.worldToCameraCoordinatesPoint = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); - } - - if (!defined(result)) { - result = new Cartesian3(); + PointCloud3DTileContent.prototype.hasProperty = function(batchId, name) { + if (defined(this._batchTable)) { + return this._batchTable.hasProperty(batchId, name); } - updateMembers(this); - return Matrix4.multiplyByPoint(this._actualInvTransform, cartesian, result); + return false; }; /** - * Transform a vector from world coordinates to the camera's reference frame. + * Part of the {@link Cesium3DTileContent} interface. * - * @param {Cartesian3} cartesian The vector to transform. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The transformed vector. + * In this context a feature refers to a group of points that share the same BATCH_ID. + * For example all the points that represent a door in a house point cloud would be a feature. + * + * Features are backed by a batch table and can be colored, shown/hidden, picked, etc like features + * in b3dm and i3dm. + * + * When the BATCH_ID semantic is omitted and the point cloud stores per-point properties, they + * are not accessible by getFeature. They are only used for dynamic styling. */ - Camera.prototype.worldToCameraCoordinatesVector = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); + PointCloud3DTileContent.prototype.getFeature = function(batchId) { + if (!defined(this._batchTable)) { + return undefined; } - - if (!defined(result)) { - result = new Cartesian3(); + var featuresLength = this.featuresLength; + if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); } - updateMembers(this); - return Matrix4.multiplyByPointAsVector(this._actualInvTransform, cartesian, result); + createFeatures(this); + return this._features[batchId]; }; /** - * Transform a vector or point from the camera's reference frame to world coordinates. - * - * @param {Cartesian4} cartesian The vector or point to transform. - * @param {Cartesian4} [result] The object onto which to store the result. - * @returns {Cartesian4} The transformed vector or point. + * @inheritdoc Cesium3DTileContent#applyDebugSettings */ - Camera.prototype.cameraToWorldCoordinates = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); - } - - if (!defined(result)) { - result = new Cartesian4(); - } - updateMembers(this); - return Matrix4.multiplyByVector(this._actualTransform, cartesian, result); + PointCloud3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + this._highlightColor = enabled ? color : Color.WHITE; }; /** - * Transform a point from the camera's reference frame to world coordinates. - * - * @param {Cartesian3} cartesian The point to transform. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The transformed point. + * @inheritdoc Cesium3DTileContent#applyStyle */ - Camera.prototype.cameraToWorldCoordinatesPoint = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); - } - - if (!defined(result)) { - result = new Cartesian3(); + PointCloud3DTileContent.prototype.applyStyle = function(frameState, style) { + if (defined(this._batchTable)) { + this._batchTable.applyStyle(frameState, style); + } else { + createShaders(this, frameState, style); } - updateMembers(this); - return Matrix4.multiplyByPoint(this._actualTransform, cartesian, result); }; + var scratchComputedTranslation = new Cartesian4(); + var scratchComputedMatrixIn2D = new Matrix4(); + /** - * Transform a vector from the camera's reference frame to world coordinates. - * - * @param {Cartesian3} cartesian The vector to transform. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} The transformed vector. + * @inheritdoc Cesium3DTileContent#update */ - Camera.prototype.cameraToWorldCoordinatesVector = function(cartesian, result) { - if (!defined(cartesian)) { - throw new DeveloperError('cartesian is required.'); - } - - if (!defined(result)) { - result = new Cartesian3(); - } - updateMembers(this); - return Matrix4.multiplyByPointAsVector(this._actualTransform, cartesian, result); - }; + PointCloud3DTileContent.prototype.update = function(tileset, frameState) { + var modelMatrix = this._tile.computedTransform; + var modelMatrixChanged = !Matrix4.equals(this._modelMatrix, modelMatrix); + var updateModelMatrix = modelMatrixChanged || this._mode !== frameState.mode; - function clampMove2D(camera, position) { - var rotatable2D = camera._scene.mapMode2D === MapMode2D.ROTATE; - var maxProjectedX = camera._maxCoord.x; - var maxProjectedY = camera._maxCoord.y; + this._mode = frameState.mode; - var minX; - var maxX; - if (rotatable2D) { - maxX = maxProjectedX; - minX = -maxX; - } else { - maxX = position.x - maxProjectedX * 2.0; - minX = position.x + maxProjectedX * 2.0; - } + var context = frameState.context; - if (position.x > maxProjectedX) { - position.x = maxX; - } - if (position.x < -maxProjectedX) { - position.x = minX; - } + // update clipping planes + var clippingPlanes = this._tileset.clippingPlanes; + var clippingEnabled = defined(clippingPlanes) && clippingPlanes.enabled && this._tile._isClipped; - if (position.y > maxProjectedY) { - position.y = maxProjectedY; - } - if (position.y < -maxProjectedY) { - position.y = -maxProjectedY; + var unionClippingRegions = false; + var length = 0; + if (clippingEnabled) { + unionClippingRegions = clippingPlanes.unionClippingRegions; + length = clippingPlanes.length; } - } - var moveScratch = new Cartesian3(); - /** - * Translates the camera's position by <code>amount</code> along <code>direction</code>. - * - * @param {Cartesian3} direction The direction to move. - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveBackward - * @see Camera#moveForward - * @see Camera#moveLeft - * @see Camera#moveRight - * @see Camera#moveUp - * @see Camera#moveDown - */ - Camera.prototype.move = function(direction, amount) { - if (!defined(direction)) { - throw new DeveloperError('direction is required.'); - } - - var cameraPosition = this.position; - Cartesian3.multiplyByScalar(direction, amount, moveScratch); - Cartesian3.add(cameraPosition, moveScratch, cameraPosition); + var packedPlanes = this._packedClippingPlanes; + var packedLength = packedPlanes.length; + if (packedLength !== length) { + packedPlanes.length = length; - if (this._mode === SceneMode.SCENE2D) { - clampMove2D(this, cameraPosition); + for (var i = 0; i < length; ++i) { + packedPlanes[i] = new Cartesian4(); + } } - this._adjustOrthographicFrustum(true); - }; - - /** - * Translates the camera's position by <code>amount</code> along the camera's view vector. - * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveBackward - */ - Camera.prototype.moveForward = function(amount) { - amount = defaultValue(amount, this.defaultMoveAmount); - this.move(this.direction, amount); - }; - /** - * Translates the camera's position by <code>amount</code> along the opposite direction - * of the camera's view vector. - * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveForward - */ - Camera.prototype.moveBackward = function(amount) { - amount = defaultValue(amount, this.defaultMoveAmount); - this.move(this.direction, -amount); - }; + if (!defined(this._drawCommand)) { + createResources(this, frameState); + createShaders(this, frameState, tileset.style); + updateModelMatrix = true; - /** - * Translates the camera's position by <code>amount</code> along the camera's up vector. - * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveDown - */ - Camera.prototype.moveUp = function(amount) { - amount = defaultValue(amount, this.defaultMoveAmount); - this.move(this.up, amount); - }; + this._readyPromise.resolve(this); + this._parsedContent = undefined; // Unload + } - /** - * Translates the camera's position by <code>amount</code> along the opposite direction - * of the camera's up vector. - * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveUp - */ - Camera.prototype.moveDown = function(amount) { - amount = defaultValue(amount, this.defaultMoveAmount); - this.move(this.up, -amount); - }; + if (this._isClipped !== clippingEnabled || this._unionClippingRegions !== unionClippingRegions) { + this._isClipped = clippingEnabled; + this._unionClippingRegions = unionClippingRegions; - /** - * Translates the camera's position by <code>amount</code> along the camera's right vector. - * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveLeft - */ - Camera.prototype.moveRight = function(amount) { - amount = defaultValue(amount, this.defaultMoveAmount); - this.move(this.right, amount); - }; + createShaders(this, frameState, tileset.style); + } - /** - * Translates the camera's position by <code>amount</code> along the opposite direction - * of the camera's right vector. - * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. - * - * @see Camera#moveRight - */ - Camera.prototype.moveLeft = function(amount) { - amount = defaultValue(amount, this.defaultMoveAmount); - this.move(this.right, -amount); - }; + // Update attenuation + var pointCloudShading = this._tileset.pointCloudShading; + if (defined(pointCloudShading)) { + var formerAttenuation = this._attenuation; + this._attenuation = pointCloudShading.attenuation; + this._geometricErrorScale = pointCloudShading.geometricErrorScale; + this._maximumAttenuation = defined(pointCloudShading.maximumAttenuation) ? pointCloudShading.maximumAttenuation : tileset.maximumScreenSpaceError; + this._baseResolution = pointCloudShading.baseResolution; + if (this._attenuation !== formerAttenuation) { + createShaders(this, frameState, tileset.style); + } + } - /** - * Rotates the camera around its up vector by amount, in radians, in the opposite direction - * of its right vector. - * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#lookRight - */ - Camera.prototype.lookLeft = function(amount) { - amount = defaultValue(amount, this.defaultLookAmount); - this.look(this.up, -amount); - }; + if (updateModelMatrix) { + Matrix4.clone(modelMatrix, this._modelMatrix); + if (defined(this._rtcCenter)) { + Matrix4.multiplyByTranslation(modelMatrix, this._rtcCenter, this._drawCommand.modelMatrix); + } else if (defined(this._quantizedVolumeOffset)) { + Matrix4.multiplyByTranslation(modelMatrix, this._quantizedVolumeOffset, this._drawCommand.modelMatrix); + } else { + Matrix4.clone(modelMatrix, this._drawCommand.modelMatrix); + } - /** - * Rotates the camera around its up vector by amount, in radians, in the direction - * of its right vector. - * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#lookLeft - */ - Camera.prototype.lookRight = function(amount) { - amount = defaultValue(amount, this.defaultLookAmount); - this.look(this.up, amount); - }; + if (frameState.mode !== SceneMode.SCENE3D) { + var projection = frameState.mapProjection; + modelMatrix = this._drawCommand.modelMatrix; + var translation = Matrix4.getColumn(modelMatrix, 3, scratchComputedTranslation); + if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) { + Transforms.basisTo2D(projection, modelMatrix, modelMatrix); + } else { + var center = this._tile.boundingSphere.center; + var to2D = Transforms.wgs84To2DModelMatrix(projection, center, scratchComputedMatrixIn2D); + Matrix4.multiply(to2D, modelMatrix, modelMatrix); + } + } - /** - * Rotates the camera around its right vector by amount, in radians, in the direction - * of its up vector. - * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#lookDown - */ - Camera.prototype.lookUp = function(amount) { - amount = defaultValue(amount, this.defaultLookAmount); - this.look(this.right, -amount); - }; + Matrix4.clone(this._drawCommand.modelMatrix, this._pickCommand.modelMatrix); - /** - * Rotates the camera around its right vector by amount, in radians, in the opposite direction - * of its up vector. - * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#lookUp - */ - Camera.prototype.lookDown = function(amount) { - amount = defaultValue(amount, this.defaultLookAmount); - this.look(this.right, amount); - }; + var boundingVolume; + if (defined(this._tile._contentBoundingVolume)) { + boundingVolume = this._mode === SceneMode.SCENE3D ? this._tile._contentBoundingVolume.boundingSphere : this._tile._contentBoundingVolume2D.boundingSphere; + } else { + boundingVolume = this._mode === SceneMode.SCENE3D ? this._tile._boundingVolume.boundingSphere : this._tile._boundingVolume2D.boundingSphere; + } - var lookScratchQuaternion = new Quaternion(); - var lookScratchMatrix = new Matrix3(); - /** - * Rotate each of the camera's orientation vectors around <code>axis</code> by <code>angle</code> - * - * @param {Cartesian3} axis The axis to rotate around. - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#lookUp - * @see Camera#lookDown - * @see Camera#lookLeft - * @see Camera#lookRight - */ - Camera.prototype.look = function(axis, angle) { - if (!defined(axis)) { - throw new DeveloperError('axis is required.'); + this._drawCommand.boundingVolume = boundingVolume; + this._pickCommand.boundingVolume = boundingVolume; } - - var turnAngle = defaultValue(angle, this.defaultLookAmount); - var quaternion = Quaternion.fromAxisAngle(axis, -turnAngle, lookScratchQuaternion); - var rotation = Matrix3.fromQuaternion(quaternion, lookScratchMatrix); - var direction = this.direction; - var up = this.up; - var right = this.right; + if (clippingEnabled) { + Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); + clippingPlanes.transformAndPackPlanes(this._modelViewMatrix, packedPlanes); + } - Matrix3.multiplyByVector(rotation, direction, direction); - Matrix3.multiplyByVector(rotation, up, up); - Matrix3.multiplyByVector(rotation, right, right); - }; + this._drawCommand.castShadows = ShadowMode.castShadows(tileset.shadows); + this._drawCommand.receiveShadows = ShadowMode.receiveShadows(tileset.shadows); - /** - * Rotate the camera counter-clockwise around its direction vector by amount, in radians. - * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#twistRight - */ - Camera.prototype.twistLeft = function(amount) { - amount = defaultValue(amount, this.defaultLookAmount); - this.look(this.direction, amount); - }; + if (this.backFaceCulling !== this._backFaceCulling) { + this._backFaceCulling = this.backFaceCulling; + createShaders(this, frameState, tileset.style); + } - /** - * Rotate the camera clockwise around its direction vector by amount, in radians. - * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. - * - * @see Camera#twistLeft - */ - Camera.prototype.twistRight = function(amount) { - amount = defaultValue(amount, this.defaultLookAmount); - this.look(this.direction, -amount); - }; + // Update the render state + var isTranslucent = (this._highlightColor.alpha < 1.0) || (this._constantColor.alpha < 1.0) || this._styleTranslucent; + this._drawCommand.renderState = isTranslucent ? this._translucentRenderState : this._opaqueRenderState; + this._drawCommand.pass = isTranslucent ? Pass.TRANSLUCENT : Pass.CESIUM_3D_TILE; - var rotateScratchQuaternion = new Quaternion(); - var rotateScratchMatrix = new Matrix3(); - /** - * Rotates the camera around <code>axis</code> by <code>angle</code>. The distance - * of the camera's position to the center of the camera's reference frame remains the same. - * - * @param {Cartesian3} axis The axis to rotate around given in world coordinates. - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. - * - * @see Camera#rotateUp - * @see Camera#rotateDown - * @see Camera#rotateLeft - * @see Camera#rotateRight - */ - Camera.prototype.rotate = function(axis, angle) { - if (!defined(axis)) { - throw new DeveloperError('axis is required.'); + if (defined(this._batchTable)) { + this._batchTable.update(tileset, frameState); } - - var turnAngle = defaultValue(angle, this.defaultRotateAmount); - var quaternion = Quaternion.fromAxisAngle(axis, -turnAngle, rotateScratchQuaternion); - var rotation = Matrix3.fromQuaternion(quaternion, rotateScratchMatrix); - Matrix3.multiplyByVector(rotation, this.position, this.position); - Matrix3.multiplyByVector(rotation, this.direction, this.direction); - Matrix3.multiplyByVector(rotation, this.up, this.up); - Cartesian3.cross(this.direction, this.up, this.right); - Cartesian3.cross(this.right, this.direction, this.up); - this._adjustOrthographicFrustum(false); + var commandList = frameState.commandList; + + var passes = frameState.passes; + if (passes.render) { + commandList.push(this._drawCommand); + } + if (passes.pick) { + commandList.push(this._pickCommand); + } }; /** - * Rotates the camera around the center of the camera's reference frame by angle downwards. - * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. - * - * @see Camera#rotateUp - * @see Camera#rotate + * @inheritdoc Cesium3DTileContent#isDestroyed */ - Camera.prototype.rotateDown = function(angle) { - angle = defaultValue(angle, this.defaultRotateAmount); - rotateVertical(this, angle); + PointCloud3DTileContent.prototype.isDestroyed = function() { + return false; }; /** - * Rotates the camera around the center of the camera's reference frame by angle upwards. - * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. - * - * @see Camera#rotateDown - * @see Camera#rotate + * @inheritdoc Cesium3DTileContent#destroy */ - Camera.prototype.rotateUp = function(angle) { - angle = defaultValue(angle, this.defaultRotateAmount); - rotateVertical(this, -angle); + PointCloud3DTileContent.prototype.destroy = function() { + var command = this._drawCommand; + var pickCommand = this._pickCommand; + if (defined(command)) { + command.vertexArray = command.vertexArray && command.vertexArray.destroy(); + command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); + pickCommand.shaderProgram = pickCommand.shaderProgram && pickCommand.shaderProgram.destroy(); + } + this._batchTable = this._batchTable && this._batchTable.destroy(); + return destroyObject(this); }; - var rotateVertScratchP = new Cartesian3(); - var rotateVertScratchA = new Cartesian3(); - var rotateVertScratchTan = new Cartesian3(); - var rotateVertScratchNegate = new Cartesian3(); - function rotateVertical(camera, angle) { - var position = camera.position; - var p = Cartesian3.normalize(position, rotateVertScratchP); - if (defined(camera.constrainedAxis)) { - var northParallel = Cartesian3.equalsEpsilon(p, camera.constrainedAxis, CesiumMath.EPSILON2); - var southParallel = Cartesian3.equalsEpsilon(p, Cartesian3.negate(camera.constrainedAxis, rotateVertScratchNegate), CesiumMath.EPSILON2); - if ((!northParallel && !southParallel)) { - var constrainedAxis = Cartesian3.normalize(camera.constrainedAxis, rotateVertScratchA); - - var dot = Cartesian3.dot(p, constrainedAxis); - var angleToAxis = CesiumMath.acosClamped(dot); - if (angle > 0 && angle > angleToAxis) { - angle = angleToAxis - CesiumMath.EPSILON4; - } - - dot = Cartesian3.dot(p, Cartesian3.negate(constrainedAxis, rotateVertScratchNegate)); - angleToAxis = CesiumMath.acosClamped(dot); - if (angle < 0 && -angle > angleToAxis) { - angle = -angleToAxis + CesiumMath.EPSILON4; - } + return PointCloud3DTileContent; +}); - var tangent = Cartesian3.cross(constrainedAxis, p, rotateVertScratchTan); - camera.rotate(tangent, angle); - } else if ((northParallel && angle < 0) || (southParallel && angle > 0)) { - camera.rotate(camera.right, angle); - } - } else { - camera.rotate(camera.right, angle); - } - } +define('Scene/Tileset3DTileContent',[ + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/getStringFromTypedArray', + '../Core/RuntimeError', + '../ThirdParty/when' + ], function( + defaultValue, + defineProperties, + destroyObject, + getStringFromTypedArray, + RuntimeError, + when) { + 'use strict'; /** - * Rotates the camera around the center of the camera's reference frame by angle to the right. + * Represents content for a tile in a + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset whose + * content points to another 3D Tiles tileset. + * <p> + * Implements the {@link Cesium3DTileContent} interface. + * </p> * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * @alias Tileset3DTileContent + * @constructor * - * @see Camera#rotateLeft - * @see Camera#rotate + * @private */ - Camera.prototype.rotateRight = function(angle) { - angle = defaultValue(angle, this.defaultRotateAmount); - rotateHorizontal(this, -angle); - }; + function Tileset3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { + this._tileset = tileset; + this._tile = tile; + this._resource = resource; + this._readyPromise = when.defer(); - /** - * Rotates the camera around the center of the camera's reference frame by angle to the left. - * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. - * - * @see Camera#rotateRight - * @see Camera#rotate - */ - Camera.prototype.rotateLeft = function(angle) { - angle = defaultValue(angle, this.defaultRotateAmount); - rotateHorizontal(this, angle); - }; + /** + * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + */ + this.featurePropertiesDirty = false; - function rotateHorizontal(camera, angle) { - if (defined(camera.constrainedAxis)) { - camera.rotate(camera.constrainedAxis, angle); - } else { - camera.rotate(camera.up, angle); - } + initialize(this, arrayBuffer, byteOffset); } - function zoom2D(camera, amount) { - var frustum = camera.frustum; + defineProperties(Tileset3DTileContent.prototype, { + /** + * @inheritdoc Cesium3DTileContent#featuresLength + */ + featuresLength : { + get : function() { + return 0; + } + }, - if (!(frustum instanceof OrthographicOffCenterFrustum) || !defined(frustum.left) || !defined(frustum.right) || - !defined(frustum.bottom) || !defined(frustum.top)) { - throw new DeveloperError('The camera frustum is expected to be orthographic for 2D camera control.'); - } - - var ratio; - amount = amount * 0.5; + /** + * @inheritdoc Cesium3DTileContent#pointsLength + */ + pointsLength : { + get : function() { + return 0; + } + }, - if((Math.abs(frustum.top) + Math.abs(frustum.bottom)) > (Math.abs(frustum.left) + Math.abs(frustum.right))) { - var newTop = frustum.top - amount; - var newBottom = frustum.bottom + amount; + /** + * @inheritdoc Cesium3DTileContent#trianglesLength + */ + trianglesLength : { + get : function() { + return 0; + } + }, - var maxBottom = camera._maxCoord.y; - if (camera._scene.mapMode2D === MapMode2D.ROTATE) { - maxBottom *= camera.maximumZoomFactor; + /** + * @inheritdoc Cesium3DTileContent#geometryByteLength + */ + geometryByteLength : { + get : function() { + return 0; } + }, - if (newBottom > maxBottom) { - newBottom = maxBottom; - newTop = -maxBottom; + /** + * @inheritdoc Cesium3DTileContent#texturesByteLength + */ + texturesByteLength : { + get : function() { + return 0; } + }, - if (newTop <= newBottom) { - newTop = 1.0; - newBottom = -1.0; + /** + * @inheritdoc Cesium3DTileContent#batchTableByteLength + */ + batchTableByteLength : { + get : function() { + return 0; } + }, - ratio = frustum.right / frustum.top; - frustum.top = newTop; - frustum.bottom = newBottom; - frustum.right = frustum.top * ratio; - frustum.left = -frustum.right; - } else { - var newRight = frustum.right - amount; - var newLeft = frustum.left + amount; + /** + * @inheritdoc Cesium3DTileContent#innerContents + */ + innerContents : { + get : function() { + return undefined; + } + }, - var maxRight = camera._maxCoord.x; - if (camera._scene.mapMode2D === MapMode2D.ROTATE) { - maxRight *= camera.maximumZoomFactor; + /** + * @inheritdoc Cesium3DTileContent#readyPromise + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; } + }, - if (newRight > maxRight) { - newRight = maxRight; - newLeft = -maxRight; + /** + * @inheritdoc Cesium3DTileContent#tileset + */ + tileset : { + get : function() { + return this._tileset; } + }, - if (newRight <= newLeft) { - newRight = 1.0; - newLeft = -1.0; + /** + * @inheritdoc Cesium3DTileContent#tile + */ + tile : { + get : function() { + return this._tile; + } + }, + + /** + * @inheritdoc Cesium3DTileContent#url + */ + url : { + get : function() { + return this._resource.getUrlComponent(true); + } + }, + + /** + * @inheritdoc Cesium3DTileContent#batchTable + */ + batchTable : { + get : function() { + return undefined; } - ratio = frustum.top / frustum.right; - frustum.right = newRight; - frustum.left = newLeft; - frustum.top = frustum.right * ratio; - frustum.bottom = -frustum.top; } - } + }); - function zoom3D(camera, amount) { - camera.move(camera.direction, amount); + function initialize(content, arrayBuffer, byteOffset) { + byteOffset = defaultValue(byteOffset, 0); + var uint8Array = new Uint8Array(arrayBuffer); + var jsonString = getStringFromTypedArray(uint8Array, byteOffset); + var tilesetJson; + + try { + tilesetJson = JSON.parse(jsonString); + } catch (error) { + content._readyPromise.reject(new RuntimeError('Invalid tile content.')); + return; + } + + content._tileset.loadTileset(content._resource, tilesetJson, content._tile); + content._readyPromise.resolve(content); } /** - * Zooms <code>amount</code> along the camera's view vector. - * - * @param {Number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. - * - * @see Camera#zoomOut + * Part of the {@link Cesium3DTileContent} interface. <code>Tileset3DTileContent</code> + * always returns <code>false</code> since a tile of this type does not have any features. */ - Camera.prototype.zoomIn = function(amount) { - amount = defaultValue(amount, this.defaultZoomAmount); - if (this._mode === SceneMode.SCENE2D) { - zoom2D(this, amount); - } else { - zoom3D(this, amount); - } + Tileset3DTileContent.prototype.hasProperty = function(batchId, name) { + return false; }; /** - * Zooms <code>amount</code> along the opposite direction of - * the camera's view vector. - * - * @param {Number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. - * - * @see Camera#zoomIn + * Part of the {@link Cesium3DTileContent} interface. <code>Tileset3DTileContent</code> + * always returns <code>undefined</code> since a tile of this type does not have any features. */ - Camera.prototype.zoomOut = function(amount) { - amount = defaultValue(amount, this.defaultZoomAmount); - if (this._mode === SceneMode.SCENE2D) { - zoom2D(this, -amount); - } else { - zoom3D(this, -amount); - } + Tileset3DTileContent.prototype.getFeature = function(batchId) { + return undefined; }; /** - * Gets the magnitude of the camera position. In 3D, this is the vector magnitude. In 2D and - * Columbus view, this is the distance to the map. - * - * @returns {Number} The magnitude of the position. + * @inheritdoc Cesium3DTileContent#applyDebugSettings */ - Camera.prototype.getMagnitude = function() { - if (this._mode === SceneMode.SCENE3D) { - return Cartesian3.magnitude(this.position); - } else if (this._mode === SceneMode.COLUMBUS_VIEW) { - return Math.abs(this.position.z); - } else if (this._mode === SceneMode.SCENE2D) { - return Math.max(this.frustum.right - this.frustum.left, this.frustum.top - this.frustum.bottom); - } + Tileset3DTileContent.prototype.applyDebugSettings = function(enabled, color) { }; - var scratchLookAtMatrix4 = new Matrix4(); + /** + * @inheritdoc Cesium3DTileContent#applyStyle + */ + Tileset3DTileContent.prototype.applyStyle = function(frameState, style) { + }; /** - * Sets the camera position and orientation using a target and offset. The target must be given in - * world coordinates. The offset can be either a cartesian or heading/pitch/range in the local east-north-up reference frame centered at the target. - * If the offset is a cartesian, then it is an offset from the center of the reference frame defined by the transformation matrix. If the offset - * is heading/pitch/range, then the heading and the pitch angles are defined in the reference frame defined by the transformation matrix. - * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch - * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. - * - * In 2D, there must be a top down view. The camera will be placed above the target looking down. The height above the - * target will be the magnitude of the offset. The heading will be determined from the offset. If the heading cannot be - * determined from the offset, the heading will be north. - * - * @param {Cartesian3} target The target position in world coordinates. - * @param {Cartesian3|HeadingPitchRange} offset The offset from the target in the local east-north-up reference frame centered at the target. - * - * @exception {DeveloperError} lookAt is not supported while morphing. - * - * @example - * // 1. Using a cartesian offset - * var center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0); - * viewer.camera.lookAt(center, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)); - * - * // 2. Using a HeadingPitchRange offset - * var center = Cesium.Cartesian3.fromDegrees(-72.0, 40.0); - * var heading = Cesium.Math.toRadians(50.0); - * var pitch = Cesium.Math.toRadians(-20.0); - * var range = 5000.0; - * viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range)); + * @inheritdoc Cesium3DTileContent#update */ - Camera.prototype.lookAt = function(target, offset) { - if (!defined(target)) { - throw new DeveloperError('target is required'); - } - if (!defined(offset)) { - throw new DeveloperError('offset is required'); - } - if (this._mode === SceneMode.MORPHING) { - throw new DeveloperError('lookAt is not supported while morphing.'); - } - - var transform = Transforms.eastNorthUpToFixedFrame(target, Ellipsoid.WGS84, scratchLookAtMatrix4); - this.lookAtTransform(transform, offset); + Tileset3DTileContent.prototype.update = function(tileset, frameState) { }; - var scratchLookAtHeadingPitchRangeOffset = new Cartesian3(); - var scratchLookAtHeadingPitchRangeQuaternion1 = new Quaternion(); - var scratchLookAtHeadingPitchRangeQuaternion2 = new Quaternion(); - var scratchHeadingPitchRangeMatrix3 = new Matrix3(); + /** + * @inheritdoc Cesium3DTileContent#isDestroyed + */ + Tileset3DTileContent.prototype.isDestroyed = function() { + return false; + }; - function offsetFromHeadingPitchRange(heading, pitch, range) { - pitch = CesiumMath.clamp(pitch, -CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO); - heading = CesiumMath.zeroToTwoPi(heading) - CesiumMath.PI_OVER_TWO; + /** + * @inheritdoc Cesium3DTileContent#destroy + */ + Tileset3DTileContent.prototype.destroy = function() { + return destroyObject(this); + }; - var pitchQuat = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -pitch, scratchLookAtHeadingPitchRangeQuaternion1); - var headingQuat = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -heading, scratchLookAtHeadingPitchRangeQuaternion2); - var rotQuat = Quaternion.multiply(headingQuat, pitchQuat, headingQuat); - var rotMatrix = Matrix3.fromQuaternion(rotQuat, scratchHeadingPitchRangeMatrix3); + return Tileset3DTileContent; +}); - var offset = Cartesian3.clone(Cartesian3.UNIT_X, scratchLookAtHeadingPitchRangeOffset); - Matrix3.multiplyByVector(rotMatrix, offset, offset); - Cartesian3.negate(offset, offset); - Cartesian3.multiplyByScalar(offset, range, offset); - return offset; - } +define('Scene/Cesium3DTilePointFeature',[ + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/Ellipsoid', + './createBillboardPointCallback' + ], function( + Cartesian3, + Cartographic, + Color, + defaultValue, + defined, + defineProperties, + Ellipsoid, + createBillboardPointCallback) { + 'use strict'; /** - * Sets the camera position and orientation using a target and transformation matrix. The offset can be either a cartesian or heading/pitch/range. - * If the offset is a cartesian, then it is an offset from the center of the reference frame defined by the transformation matrix. If the offset - * is heading/pitch/range, then the heading and the pitch angles are defined in the reference frame defined by the transformation matrix. - * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch - * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. - * - * In 2D, there must be a top down view. The camera will be placed above the center of the reference frame. The height above the - * target will be the magnitude of the offset. The heading will be determined from the offset. If the heading cannot be - * determined from the offset, the heading will be north. + * A point feature of a {@link Cesium3DTileset}. + * <p> + * Provides access to a feature's properties stored in the tile's batch table, as well + * as the ability to show/hide a feature and change its point properties + * </p> + * <p> + * Modifications to a <code>Cesium3DTilePointFeature</code> object have the lifetime of the tile's + * content. If the tile's content is unloaded, e.g., due to it going out of view and needing + * to free space in the cache for visible tiles, listen to the {@link Cesium3DTileset#tileUnload} event to save any + * modifications. Also listen to the {@link Cesium3DTileset#tileVisible} event to reapply any modifications. + * </p> + * <p> + * Do not construct this directly. Access it through {@link Cesium3DTileContent#getFeature} + * or picking using {@link Scene#pick} and {@link Scene#pickPosition}. + * </p> * - * @param {Matrix4} transform The transformation matrix defining the reference frame. - * @param {Cartesian3|HeadingPitchRange} [offset] The offset from the target in a reference frame centered at the target. + * @alias Cesium3DTilePointFeature + * @constructor * - * @exception {DeveloperError} lookAtTransform is not supported while morphing. + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * * @example - * // 1. Using a cartesian offset - * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-98.0, 40.0)); - * viewer.camera.lookAtTransform(transform, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)); - * - * // 2. Using a HeadingPitchRange offset - * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-72.0, 40.0)); - * var heading = Cesium.Math.toRadians(50.0); - * var pitch = Cesium.Math.toRadians(-20.0); - * var range = 5000.0; - * viewer.camera.lookAtTransform(transform, new Cesium.HeadingPitchRange(heading, pitch, range)); + * // On mouse over, display all the properties for a feature in the console log. + * handler.setInputAction(function(movement) { + * var feature = scene.pick(movement.endPosition); + * if (feature instanceof Cesium.Cesium3DTilePointFeature) { + * var propertyNames = feature.getPropertyNames(); + * var length = propertyNames.length; + * for (var i = 0; i < length; ++i) { + * var propertyName = propertyNames[i]; + * console.log(propertyName + ': ' + feature.getProperty(propertyName)); + * } + * } + * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); */ - Camera.prototype.lookAtTransform = function(transform, offset) { - if (!defined(transform)) { - throw new DeveloperError('transform is required'); - } - if (this._mode === SceneMode.MORPHING) { - throw new DeveloperError('lookAtTransform is not supported while morphing.'); - } - - this._setTransform(transform); - if (!defined(offset)) { - return; - } + function Cesium3DTilePointFeature(content, batchId, billboard, label, polyline) { + this._content = content; + this._billboard = billboard; + this._label = label; + this._polyline = polyline; - var cartesianOffset; - if (defined(offset.heading)) { - cartesianOffset = offsetFromHeadingPitchRange(offset.heading, offset.pitch, offset.range); - } else { - cartesianOffset = offset; - } + this._batchId = batchId; + this._billboardImage = undefined; + this._billboardColor = undefined; + this._billboardOutlineColor = undefined; + this._billboardOutlineWidth = undefined; + this._billboardSize = undefined; + this._pointSize = undefined; + this._color = undefined; + this._pointSize = undefined; + this._pointOutlineColor = undefined; + this._pointOutlineWidth = undefined; + this._heightOffset = undefined; - if (this._mode === SceneMode.SCENE2D) { - Cartesian2.clone(Cartesian2.ZERO, this.position); + setBillboardImage(this); + } - Cartesian3.negate(cartesianOffset, this.up); - this.up.z = 0.0; + var scratchCartographic = new Cartographic(); - if (Cartesian3.magnitudeSquared(this.up) < CesiumMath.EPSILON10) { - Cartesian3.clone(Cartesian3.UNIT_Y, this.up); + defineProperties(Cesium3DTilePointFeature.prototype, { + /** + * Gets or sets if the feature will be shown. This is set for all features + * when a style's show is evaluated. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Boolean} + * + * @default true + */ + show : { + get : function() { + return this._label.show; + }, + set : function(value) { + this._label.show = value; + this._billboard.show = value; + this._polyline.show = value; } + }, - Cartesian3.normalize(this.up, this.up); + /** + * Gets or sets the color of the point of this feature. + * <p> + * Only applied when <code>image</code> is <code>undefined</code>. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Color} + */ + color : { + get : function() { + return this._color; + }, + set : function(value) { + this._color = Color.clone(value, this._color); + setBillboardImage(this); + } + }, - this._setTransform(Matrix4.IDENTITY); + /** + * Gets or sets the point size of this feature. + * <p> + * Only applied when <code>image</code> is <code>undefined</code>. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Number} + */ + pointSize : { + get : function() { + return this._pointSize; + }, + set : function(value) { + this._pointSize = value; + setBillboardImage(this); + } + }, - Cartesian3.negate(Cartesian3.UNIT_Z, this.direction); - Cartesian3.cross(this.direction, this.up, this.right); - Cartesian3.normalize(this.right, this.right); + /** + * Gets or sets the point outline color of this feature. + * <p> + * Only applied when <code>image</code> is <code>undefined</code>. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Color} + */ + pointOutlineColor : { + get : function() { + return this._pointOutlineColor; + }, + set : function(value) { + this._pointOutlineColor = Color.clone(value, this._pointOutlineColor); + setBillboardImage(this); + } + }, - var frustum = this.frustum; - var ratio = frustum.top / frustum.right; - frustum.right = Cartesian3.magnitude(cartesianOffset) * 0.5; - frustum.left = -frustum.right; - frustum.top = ratio * frustum.right; - frustum.bottom = -frustum.top; + /** + * Gets or sets the point outline width in pixels of this feature. + * <p> + * Only applied when <code>image</code> is <code>undefined</code>. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Number} + */ + pointOutlineWidth : { + get : function() { + return this._pointOutlineWidth; + }, + set : function(value) { + this._pointOutlineWidth = value; + setBillboardImage(this); + } + }, - this._setTransform(transform); + /** + * Gets or sets the label color of this feature. + * <p> + * The color will be applied to the label if <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Color} + */ + labelColor : { + get : function() { + return this._label.fillColor; + }, + set : function(value) { + this._label.fillColor = value; + this._polyline.show = this._label.show && value.alpha > 0.0; + } + }, - return; - } + /** + * Gets or sets the label outline color of this feature. + * <p> + * The outline color will be applied to the label if <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Color} + */ + labelOutlineColor : { + get : function() { + return this._label.outlineColor; + }, + set : function(value) { + this._label.outlineColor = value; + } + }, - Cartesian3.clone(cartesianOffset, this.position); - Cartesian3.negate(this.position, this.direction); - Cartesian3.normalize(this.direction, this.direction); - Cartesian3.cross(this.direction, Cartesian3.UNIT_Z, this.right); + /** + * Gets or sets the outline width in pixels of this feature. + * <p> + * The outline width will be applied to the point if <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Number} + */ + labelOutlineWidth : { + get : function() { + return this._label.outlineWidth; + }, + set : function(value) { + this._label.outlineWidth = value; + } + }, - if (Cartesian3.magnitudeSquared(this.right) < CesiumMath.EPSILON10) { - Cartesian3.clone(Cartesian3.UNIT_X, this.right); - } + /** + * Gets or sets the font of this feature. + * <p> + * Only applied when the <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {String} + */ + font : { + get : function() { + return this._label.font; + }, + set : function(value) { + this._label.font = value; + } + }, - Cartesian3.normalize(this.right, this.right); - Cartesian3.cross(this.right, this.direction, this.up); - Cartesian3.normalize(this.up, this.up); + /** + * Gets or sets the fill and outline style of this feature. + * <p> + * Only applied when <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {LabelStyle} + */ + labelStyle : { + get : function() { + return this._label.style; + }, + set : function(value) { + this._label.style = value; + } + }, - this._adjustOrthographicFrustum(true); - }; + /** + * Gets or sets the text for this feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {String} + */ + labelText : { + get : function() { + return this._label.text; + }, + set : function(value) { + if (!defined(value)) { + value = ''; + } + this._label.text = value; + } + }, - var viewRectangle3DCartographic1 = new Cartographic(); - var viewRectangle3DCartographic2 = new Cartographic(); - var viewRectangle3DNorthEast = new Cartesian3(); - var viewRectangle3DSouthWest = new Cartesian3(); - var viewRectangle3DNorthWest = new Cartesian3(); - var viewRectangle3DSouthEast = new Cartesian3(); - var viewRectangle3DNorthCenter = new Cartesian3(); - var viewRectangle3DSouthCenter = new Cartesian3(); - var viewRectangle3DCenter = new Cartesian3(); - var viewRectangle3DEquator = new Cartesian3(); - var defaultRF = { - direction : new Cartesian3(), - right : new Cartesian3(), - up : new Cartesian3() - }; - var viewRectangle3DEllipsoidGeodesic; + /** + * Gets or sets the background color of the text for this feature. + * <p> + * Only applied when <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Color} + */ + backgroundColor : { + get : function() { + return this._label.backgroundColor; + }, + set : function(value) { + this._label.backgroundColor = value; + } + }, - function computeD(direction, upOrRight, corner, tanThetaOrPhi) { - var opposite = Math.abs(Cartesian3.dot(upOrRight, corner)); - return opposite / tanThetaOrPhi - Cartesian3.dot(direction, corner); - } + /** + * Gets or sets the background padding of the text for this feature. + * <p> + * Only applied when <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Cartesian2} + */ + backgroundPadding : { + get : function() { + return this._label.backgroundPadding; + }, + set : function(value) { + this._label.backgroundPadding = value; + } + }, - function rectangleCameraPosition3D(camera, rectangle, result, updateCamera) { - var ellipsoid = camera._projection.ellipsoid; - var cameraRF = updateCamera ? camera : defaultRF; + /** + * Gets or sets whether to display the background of the text for this feature. + * <p> + * Only applied when <code>labelText</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Boolean} + */ + backgroundEnabled : { + get : function() { + return this._label.showBackground; + }, + set : function(value) { + this._label.showBackground = value; + } + }, - var north = rectangle.north; - var south = rectangle.south; - var east = rectangle.east; - var west = rectangle.west; + /** + * Gets or sets the near and far scaling properties for this feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {NearFarScalar} + */ + scaleByDistance : { + get : function() { + return this._label.scaleByDistance; + }, + set : function(value) { + this._label.scaleByDistance = value; + this._billboard.scaleByDistance = value; + } + }, - // If we go across the International Date Line - if (west > east) { - east += CesiumMath.TWO_PI; - } + /** + * Gets or sets the near and far translucency properties for this feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {NearFarScalar} + */ + translucencyByDistance : { + get : function() { + return this._label.translucencyByDistance; + }, + set : function(value) { + this._label.translucencyByDistance = value; + this._billboard.translucencyByDistance = value; + } + }, - // Find the midpoint latitude. - // - // EllipsoidGeodesic will fail if the north and south edges are very close to being on opposite sides of the ellipsoid. - // Ideally we'd just call EllipsoidGeodesic.setEndPoints and let it throw when it detects this case, but sadly it doesn't - // even look for this case in optimized builds, so we have to test for it here instead. - // - // Fortunately, this case can only happen (here) when north is very close to the north pole and south is very close to the south pole, - // so handle it just by using 0 latitude as the center. It's certainliy possible to use a smaller tolerance - // than one degree here, but one degree is safe and putting the center at 0 latitude should be good enough for any - // rectangle that spans 178+ of the 180 degrees of latitude. - var longitude = (west + east) * 0.5; - var latitude; - if (south < -CesiumMath.PI_OVER_TWO + CesiumMath.RADIANS_PER_DEGREE && north > CesiumMath.PI_OVER_TWO - CesiumMath.RADIANS_PER_DEGREE) { - latitude = 0.0; - } else { - var northCartographic = viewRectangle3DCartographic1; - northCartographic.longitude = longitude; - northCartographic.latitude = north; - northCartographic.height = 0.0; + /** + * Gets or sets the condition specifying at what distance from the camera that this feature will be displayed. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {DistanceDisplayCondition} + */ + distanceDisplayCondition : { + get : function() { + return this._label.distanceDisplayCondition; + }, + set : function(value) { + this._label.distanceDisplayCondition = value; + this._polyline.distanceDisplayCondition = value; + this._billboard.distanceDisplayCondition = value; + } + }, - var southCartographic = viewRectangle3DCartographic2; - southCartographic.longitude = longitude; - southCartographic.latitude = south; - southCartographic.height = 0.0; + /** + * Gets or sets the height offset in meters of this feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Number} + */ + heightOffset : { + get : function() { + return this._heightOffset; + }, + set : function(value) { + var offset = defaultValue(this._heightOffset, 0.0); - var ellipsoidGeodesic = viewRectangle3DEllipsoidGeodesic; - if (!defined(ellipsoidGeodesic) || ellipsoidGeodesic.ellipsoid !== ellipsoid) { - viewRectangle3DEllipsoidGeodesic = ellipsoidGeodesic = new EllipsoidGeodesic(undefined, undefined, ellipsoid); - } + var ellipsoid = this._content.tileset.ellipsoid; + var cart = ellipsoid.cartesianToCartographic(this._billboard.position, scratchCartographic); + cart.height = cart.height - offset + value; + var newPosition = ellipsoid.cartographicToCartesian(cart); - ellipsoidGeodesic.setEndPoints(northCartographic, southCartographic); - latitude = ellipsoidGeodesic.interpolateUsingFraction(0.5, viewRectangle3DCartographic1).latitude; - } + this._billboard.position = newPosition; + this._label.position = this._billboard.position; + this._polyline.positions = [this._polyline.positions[0], newPosition]; - var centerCartographic = viewRectangle3DCartographic1; - centerCartographic.longitude = longitude; - centerCartographic.latitude = latitude; - centerCartographic.height = 0.0; + this._heightOffset = value; + } + }, - var center = ellipsoid.cartographicToCartesian(centerCartographic, viewRectangle3DCenter); + /** + * Gets or sets whether the anchor line is displayed. + * <p> + * Only applied when <code>heightOffset</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Boolean} + */ + anchorLineEnabled : { + get : function() { + return this._polyline.show; + }, + set : function(value) { + this._polyline.show = value; + } + }, - var cart = viewRectangle3DCartographic1; - cart.longitude = east; - cart.latitude = north; - var northEast = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthEast); - cart.longitude = west; - var northWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthWest); - cart.longitude = longitude; - var northCenter = ellipsoid.cartographicToCartesian(cart, viewRectangle3DNorthCenter); - cart.latitude = south; - var southCenter = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthCenter); - cart.longitude = east; - var southEast = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthEast); - cart.longitude = west; - var southWest = ellipsoid.cartographicToCartesian(cart, viewRectangle3DSouthWest); + /** + * Gets or sets the color for the anchor line. + * <p> + * Only applied when <code>heightOffset</code> is defined. + * </p> + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Color} + */ + anchorLineColor : { + get : function() { + return this._polyline.material.uniforms.color; + }, + set : function(value) { + this._polyline.material.uniforms.color = value; + } + }, - Cartesian3.subtract(northWest, center, northWest); - Cartesian3.subtract(southEast, center, southEast); - Cartesian3.subtract(northEast, center, northEast); - Cartesian3.subtract(southWest, center, southWest); - Cartesian3.subtract(northCenter, center, northCenter); - Cartesian3.subtract(southCenter, center, southCenter); + /** + * Gets or sets the image of this feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {String} + */ + image : { + get : function() { + return this._billboardImage; + }, + set : function(value) { + var imageChanged = this._billboardImage !== value; + this._billboardImage = value; + if (imageChanged) { + setBillboardImage(this); + } + } + }, + + /** + * Gets or sets the distance where depth testing will be disabled. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Number} + */ + disableDepthTestDistance : { + get : function() { + return this._label.disableDepthTestDistance; + }, + set : function(value) { + this._label.disableDepthTestDistance = value; + this._billboard.disableDepthTestDistance = value; + } + }, - var direction = ellipsoid.geodeticSurfaceNormal(center, cameraRF.direction); - Cartesian3.negate(direction, direction); - var right = Cartesian3.cross(direction, Cartesian3.UNIT_Z, cameraRF.right); - Cartesian3.normalize(right, right); - var up = Cartesian3.cross(right, direction, cameraRF.up); + /** + * Gets or sets the horizontal origin of this point, which determines if the point is + * to the left, center, or right of its anchor position. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {HorizontalOrigin} + */ + horizontalOrigin : { + get : function() { + return this._billboard.horizontalOrigin; + }, + set : function(value) { + this._billboard.horizontalOrigin = value; + } + }, - var d; - if (camera.frustum instanceof OrthographicFrustum) { - var width = Math.max(Cartesian3.distance(northEast, northWest), Cartesian3.distance(southEast, southWest)); - var height = Math.max(Cartesian3.distance(northEast, southEast), Cartesian3.distance(northWest, southWest)); + /** + * Gets or sets the vertical origin of this point, which determines if the point is + * to the bottom, center, or top of its anchor position. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {VerticalOrigin} + */ + verticalOrigin : { + get : function() { + return this._billboard.verticalOrigin; + }, + set : function(value) { + this._billboard.verticalOrigin = value; + } + }, - var rightScalar; - var topScalar; - var ratio = camera.frustum._offCenterFrustum.right / camera.frustum._offCenterFrustum.top; - var heightRatio = height * ratio; - if (width > heightRatio) { - rightScalar = width; - topScalar = rightScalar / ratio; - } else { - topScalar = height; - rightScalar = heightRatio; + /** + * Gets or sets the horizontal origin of this point's text, which determines if the point's text is + * to the left, center, or right of its anchor position. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {HorizontalOrigin} + */ + labelHorizontalOrigin : { + get : function() { + return this._label.horizontalOrigin; + }, + set : function(value) { + this._label.horizontalOrigin = value; } + }, - d = Math.max(rightScalar, topScalar); - } else { - var tanPhi = Math.tan(camera.frustum.fovy * 0.5); - var tanTheta = camera.frustum.aspectRatio * tanPhi; + /** + * Get or sets the vertical origin of this point's text, which determines if the point's text is + * to the bottom, center, top, or baseline of it's anchor point. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {VerticalOrigin} + */ + labelVerticalOrigin : { + get : function() { + return this._label.verticalOrigin; + }, + set : function(value) { + this._label.verticalOrigin = value; + } + }, - d = Math.max( - computeD(direction, up, northWest, tanPhi), - computeD(direction, up, southEast, tanPhi), - computeD(direction, up, northEast, tanPhi), - computeD(direction, up, southWest, tanPhi), - computeD(direction, up, northCenter, tanPhi), - computeD(direction, up, southCenter, tanPhi), - computeD(direction, right, northWest, tanTheta), - computeD(direction, right, southEast, tanTheta), - computeD(direction, right, northEast, tanTheta), - computeD(direction, right, southWest, tanTheta), - computeD(direction, right, northCenter, tanTheta), - computeD(direction, right, southCenter, tanTheta)); + /** + * Gets the content of the tile containing the feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Cesium3DTileContent} + * + * @readonly + * @private + */ + content : { + get : function() { + return this._content; + } + }, - // If the rectangle crosses the equator, compute D at the equator, too, because that's the - // widest part of the rectangle when projected onto the globe. - if (south < 0 && north > 0) { - var equatorCartographic = viewRectangle3DCartographic1; - equatorCartographic.longitude = west; - equatorCartographic.latitude = 0.0; - equatorCartographic.height = 0.0; - var equatorPosition = ellipsoid.cartographicToCartesian(equatorCartographic, viewRectangle3DEquator); - Cartesian3.subtract(equatorPosition, center, equatorPosition); - d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); + /** + * Gets the tileset containing the feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Cesium3DTileset} + * + * @readonly + */ + tileset : { + get : function() { + return this._content.tileset; + } + }, - equatorCartographic.longitude = east; - equatorPosition = ellipsoid.cartographicToCartesian(equatorCartographic, viewRectangle3DEquator); - Cartesian3.subtract(equatorPosition, center, equatorPosition); - d = Math.max(d, computeD(direction, up, equatorPosition, tanPhi), computeD(direction, right, equatorPosition, tanTheta)); + /** + * All objects returned by {@link Scene#pick} have a <code>primitive</code> property. This returns + * the tileset containing the feature. + * + * @memberof Cesium3DTilePointFeature.prototype + * + * @type {Cesium3DTileset} + * + * @readonly + */ + primitive : { + get : function() { + return this._content.tileset; } } + }); - return Cartesian3.add(center, Cartesian3.multiplyByScalar(direction, -d, viewRectangle3DEquator), result); - } + Cesium3DTilePointFeature.defaultColor = Color.WHITE; + Cesium3DTilePointFeature.defaultPointOutlineColor = Color.BLACK; + Cesium3DTilePointFeature.defaultPointOutlineWidth = 0.0; + Cesium3DTilePointFeature.defaultPointSize = 8.0; - var viewRectangleCVCartographic = new Cartographic(); - var viewRectangleCVNorthEast = new Cartesian3(); - var viewRectangleCVSouthWest = new Cartesian3(); - function rectangleCameraPositionColumbusView(camera, rectangle, result) { - var projection = camera._projection; - if (rectangle.west > rectangle.east) { - rectangle = Rectangle.MAX_VALUE; + function setBillboardImage(feature) { + var b = feature._billboard; + if (defined(feature._billboardImage) && feature._billboardImage !== b.image) { + b.image = feature._billboardImage; + return; } - var transform = camera._actualTransform; - var invTransform = camera._actualInvTransform; - var cart = viewRectangleCVCartographic; - cart.longitude = rectangle.east; - cart.latitude = rectangle.north; - var northEast = projection.project(cart, viewRectangleCVNorthEast); - Matrix4.multiplyByPoint(transform, northEast, northEast); - Matrix4.multiplyByPoint(invTransform, northEast, northEast); + if (defined(feature._billboardImage)) { + return; + } - cart.longitude = rectangle.west; - cart.latitude = rectangle.south; - var southWest = projection.project(cart, viewRectangleCVSouthWest); - Matrix4.multiplyByPoint(transform, southWest, southWest); - Matrix4.multiplyByPoint(invTransform, southWest, southWest); + var newColor = defaultValue(feature._color, Cesium3DTilePointFeature.defaultColor); + var newOutlineColor = defaultValue(feature._pointOutlineColor, Cesium3DTilePointFeature.defaultPointOutlineColor); + var newOutlineWidth = defaultValue(feature._pointOutlineWidth, Cesium3DTilePointFeature.defaultPointOutlineWidth); + var newPointSize = defaultValue(feature._pointSize, Cesium3DTilePointFeature.defaultPointSize); - result.x = (northEast.x - southWest.x) * 0.5 + southWest.x; - result.y = (northEast.y - southWest.y) * 0.5 + southWest.y; + var currentColor = feature._billboardColor; + var currentOutlineColor = feature._billboardOutlineColor; + var currentOutlineWidth = feature._billboardOutlineWidth; + var currentPointSize = feature._billboardSize; - if (defined(camera.frustum.fovy)) { - var tanPhi = Math.tan(camera.frustum.fovy * 0.5); - var tanTheta = camera.frustum.aspectRatio * tanPhi; - result.z = Math.max((northEast.x - southWest.x) / tanTheta, (northEast.y - southWest.y) / tanPhi) * 0.5; - } else { - var width = northEast.x - southWest.x; - var height = northEast.y - southWest.y; - result.z = Math.max(width, height); + if (Color.equals(newColor, currentColor) && Color.equals(newOutlineColor, currentOutlineColor) && + newOutlineWidth === currentOutlineWidth && newPointSize === currentPointSize) { + return; } - return result; - } + feature._billboardColor = Color.clone(newColor, feature._billboardColor); + feature._billboardOutlineColor = Color.clone(newOutlineColor, feature._billboardOutlineColor); + feature._billboardOutlineWidth = newOutlineWidth; + feature._billboardSize = newPointSize; - var viewRectangle2DCartographic = new Cartographic(); - var viewRectangle2DNorthEast = new Cartesian3(); - var viewRectangle2DSouthWest = new Cartesian3(); - function rectangleCameraPosition2D(camera, rectangle, result) { - var projection = camera._projection; - if (rectangle.west > rectangle.east) { - rectangle = Rectangle.MAX_VALUE; - } + var centerAlpha = newColor.alpha; + var cssColor = newColor.toCssColorString(); + var cssOutlineColor = newOutlineColor.toCssColorString(); + var textureId = JSON.stringify([cssColor, newPointSize, cssOutlineColor, newOutlineWidth]); - var cart = viewRectangle2DCartographic; - cart.longitude = rectangle.east; - cart.latitude = rectangle.north; - var northEast = projection.project(cart, viewRectangle2DNorthEast); - cart.longitude = rectangle.west; - cart.latitude = rectangle.south; - var southWest = projection.project(cart, viewRectangle2DSouthWest); + b.setImage(textureId, createBillboardPointCallback(centerAlpha, cssColor, cssOutlineColor, newOutlineWidth, newPointSize)); + } - var width = Math.abs(northEast.x - southWest.x) * 0.5; - var height = Math.abs(northEast.y - southWest.y) * 0.5; + /** + * Returns whether the feature contains this property. This includes properties from this feature's + * class and inherited classes when using a batch table hierarchy. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} + * + * @param {String} name The case-sensitive name of the property. + * @returns {Boolean} Whether the feature contains this property. + */ + Cesium3DTilePointFeature.prototype.hasProperty = function(name) { + return this._content.batchTable.hasProperty(this._batchId, name); + }; - var right, top; - var ratio = camera.frustum.right / camera.frustum.top; - var heightRatio = height * ratio; - if (width > heightRatio) { - right = width; - top = right / ratio; - } else { - top = height; - right = heightRatio; - } + /** + * Returns an array of property names for the feature. This includes properties from this feature's + * class and inherited classes when using a batch table hierarchy. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} + * + * @param {String[]} results An array into which to store the results. + * @returns {String[]} The names of the feature's properties. + */ + Cesium3DTilePointFeature.prototype.getPropertyNames = function(results) { + return this._content.batchTable.getPropertyNames(this._batchId, results); + }; - height = Math.max(2.0 * right, 2.0 * top); + /** + * Returns a copy of the value of the feature's property with the given name. This includes properties from this feature's + * class and inherited classes when using a batch table hierarchy. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable#batch-table-hierarchy} + * + * @param {String} name The case-sensitive name of the property. + * @returns {*} The value of the property or <code>undefined</code> if the property does not exist. + * + * @example + * // Display all the properties for a feature in the console log. + * var propertyNames = feature.getPropertyNames(); + * var length = propertyNames.length; + * for (var i = 0; i < length; ++i) { + * var propertyName = propertyNames[i]; + * console.log(propertyName + ': ' + feature.getProperty(propertyName)); + * } + */ + Cesium3DTilePointFeature.prototype.getProperty = function(name) { + return this._content.batchTable.getProperty(this._batchId, name); + }; - result.x = (northEast.x - southWest.x) * 0.5 + southWest.x; - result.y = (northEast.y - southWest.y) * 0.5 + southWest.y; + /** + * Sets the value of the feature's property with the given name. + * <p> + * If a property with the given name doesn't exist, it is created. + * </p> + * + * @param {String} name The case-sensitive name of the property. + * @param {*} value The value of the property that will be copied. + * + * @exception {DeveloperError} Inherited batch table hierarchy property is read only. + * + * @example + * var height = feature.getProperty('Height'); // e.g., the height of a building + * + * @example + * var name = 'clicked'; + * if (feature.getProperty(name)) { + * console.log('already clicked'); + * } else { + * feature.setProperty(name, true); + * console.log('first click'); + * } + */ + Cesium3DTilePointFeature.prototype.setProperty = function(name, value) { + this._content.batchTable.setProperty(this._batchId, name, value); - cart = projection.unproject(result, cart); - cart.height = height; - result = projection.project(cart, result); + // PERFORMANCE_IDEA: Probably overkill, but maybe only mark the tile dirty if the + // property is in one of the style's expressions or - if it can be done quickly - + // if the new property value changed the result of an expression. + this._content.featurePropertiesDirty = true; + }; - return result; - } + /** + * Returns whether the feature's class name equals <code>className</code>. Unlike {@link Cesium3DTileFeature#isClass} + * this function only checks the feature's exact class and not inherited classes. + * <p> + * This function returns <code>false</code> if no batch table hierarchy is present. + * </p> + * + * @param {String} className The name to check against. + * @returns {Boolean} Whether the feature's class name equals <code>className</code> + * + * @private + */ + Cesium3DTilePointFeature.prototype.isExactClass = function(className) { + return this._content.batchTable.isExactClass(this._batchId, className); + }; /** - * Get the camera position needed to view a rectangle on an ellipsoid or map + * Returns whether the feature's class or any inherited classes are named <code>className</code>. + * <p> + * This function returns <code>false</code> if no batch table hierarchy is present. + * </p> * - * @param {Rectangle} rectangle The rectangle to view. - * @param {Cartesian3} [result] The camera position needed to view the rectangle - * @returns {Cartesian3} The camera position needed to view the rectangle + * @param {String} className The name to check against. + * @returns {Boolean} Whether the feature's class or inherited classes are named <code>className</code> + * + * @private */ - Camera.prototype.getRectangleCameraCoordinates = function(rectangle, result) { - if (!defined(rectangle)) { - throw new DeveloperError('rectangle is required'); - } - var mode = this._mode; + Cesium3DTilePointFeature.prototype.isClass = function(className) { + return this._content.batchTable.isClass(this._batchId, className); + }; - if (!defined(result)) { - result = new Cartesian3(); - } + /** + * Returns the feature's class name. + * <p> + * This function returns <code>undefined</code> if no batch table hierarchy is present. + * </p> + * + * @returns {String} The feature's class name. + * + * @private + */ + Cesium3DTilePointFeature.prototype.getExactClassName = function() { + return this._content.batchTable.getExactClassName(this._batchId); + }; - if (mode === SceneMode.SCENE3D) { - return rectangleCameraPosition3D(this, rectangle, result); - } else if (mode === SceneMode.COLUMBUS_VIEW) { - return rectangleCameraPositionColumbusView(this, rectangle, result); - } else if (mode === SceneMode.SCENE2D) { - return rectangleCameraPosition2D(this, rectangle, result); - } + return Cesium3DTilePointFeature; +}); - return undefined; - }; +define('Scene/Vector3DTilePoints',[ + '../Core/arraySlice', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Color', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DistanceDisplayCondition', + '../Core/Ellipsoid', + '../Core/NearFarScalar', + '../Core/Rectangle', + '../Core/TaskProcessor', + '../ThirdParty/when', + './BillboardCollection', + './Cesium3DTilePointFeature', + './HorizontalOrigin', + './LabelCollection', + './LabelStyle', + './PolylineCollection', + './VerticalOrigin' + ], function( + arraySlice, + Cartesian2, + Cartesian3, + Color, + defined, + defineProperties, + destroyObject, + DistanceDisplayCondition, + Ellipsoid, + NearFarScalar, + Rectangle, + TaskProcessor, + when, + BillboardCollection, + Cesium3DTilePointFeature, + HorizontalOrigin, + LabelCollection, + LabelStyle, + PolylineCollection, + VerticalOrigin) { + 'use strict'; - var pickEllipsoid3DRay = new Ray(); - function pickEllipsoid3D(camera, windowPosition, ellipsoid, result) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - var ray = camera.getPickRay(windowPosition, pickEllipsoid3DRay); - var intersection = IntersectionTests.rayEllipsoid(ray, ellipsoid); - if (!intersection) { - return undefined; - } + /** + * Creates a batch of points or billboards and labels. + * + * @alias Vector3DTilePoints + * @constructor + * + * @param {Object} options An object with following properties: + * @param {Uint16Array} options.positions The positions of the polygons. + * @param {Number} options.minimumHeight The minimum height of the terrain covered by the tile. + * @param {Number} options.maximumHeight The maximum height of the terrain covered by the tile. + * @param {Rectangle} options.rectangle The rectangle containing the tile. + * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polygons. + * @param {Uint16Array} options.batchIds The batch ids for each polygon. + * + * @private + */ + function Vector3DTilePoints(options) { + // released after the first update + this._positions = options.positions; - var t = intersection.start > 0.0 ? intersection.start : intersection.stop; - return Ray.getPoint(ray, t, result); - } + this._batchTable = options.batchTable; + this._batchIds = options.batchIds; - var pickEllipsoid2DRay = new Ray(); - function pickMap2D(camera, windowPosition, projection, result) { - var ray = camera.getPickRay(windowPosition, pickEllipsoid2DRay); - var position = ray.origin; - position.z = 0.0; - var cart = projection.unproject(position); + this._rectangle = options.rectangle; + this._minHeight = options.minimumHeight; + this._maxHeight = options.maximumHeight; - if (cart.latitude < -CesiumMath.PI_OVER_TWO || cart.latitude > CesiumMath.PI_OVER_TWO) { - return undefined; - } + this._billboardCollection = undefined; + this._labelCollection = undefined; + this._polylineCollection = undefined; - return projection.ellipsoid.cartographicToCartesian(cart, result); + this._verticesPromise = undefined; + this._packedBuffer = undefined; + + this._ready = false; + this._readyPromise = when.defer(); + this._resolvedPromise = false; } - var pickEllipsoidCVRay = new Ray(); - function pickMapColumbusView(camera, windowPosition, projection, result) { - var ray = camera.getPickRay(windowPosition, pickEllipsoidCVRay); - var scalar = -ray.origin.x / ray.direction.x; - Ray.getPoint(ray, scalar, result); + defineProperties(Vector3DTilePoints.prototype, { + /** + * Gets the number of points. + * + * @memberof Vector3DTilePoints.prototype + * + * @type {Number} + * @readonly + */ + pointsLength : { + get : function() { + return this._billboardCollection.length; + } + }, - var cart = projection.unproject(new Cartesian3(result.y, result.z, 0.0)); + /** + * Gets the texture atlas memory in bytes. + * + * @memberof Vector3DTilePoints.prototype + * + * @type {Number} + * @readonly + */ + texturesByteLength : { + get : function() { + var billboardSize = this._billboardCollection.textureAtlas.texture.sizeInBytes; + var labelSize = this._labelCollection._textureAtlas.texture.sizeInBytes; + return billboardSize + labelSize; + } + }, - if (cart.latitude < -CesiumMath.PI_OVER_TWO || cart.latitude > CesiumMath.PI_OVER_TWO || - cart.longitude < -Math.PI || cart.longitude > Math.PI) { - return undefined; + /** + * Gets a promise that resolves when the primitive is ready to render. + * @memberof Vector3DTilePoints.prototype + * @type {Promise} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } } + }); - return projection.ellipsoid.cartographicToCartesian(cart, result); - } + function packBuffer(points, ellipsoid) { + var rectangle = points._rectangle; + var minimumHeight = points._minHeight; + var maximumHeight = points._maxHeight; - /** - * Pick an ellipsoid or map. - * - * @param {Cartesian2} windowPosition The x and y coordinates of a pixel. - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to pick. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3} If the ellipsoid or map was picked, returns the point on the surface of the ellipsoid or map - * in world coordinates. If the ellipsoid or map was not picked, returns undefined. - */ - Camera.prototype.pickEllipsoid = function(windowPosition, ellipsoid, result) { - if (!defined(windowPosition)) { - throw new DeveloperError('windowPosition is required.'); - } - - var canvas = this._scene.canvas; - if (canvas.clientWidth === 0 || canvas.clientHeight === 0) { - return undefined; - } + var packedLength = 2 + Rectangle.packedLength + Ellipsoid.packedLength; + var packedBuffer = new Float64Array(packedLength); - if (!defined(result)) { - result = new Cartesian3(); - } + var offset = 0; + packedBuffer[offset++] = minimumHeight; + packedBuffer[offset++] = maximumHeight; - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + Rectangle.pack(rectangle, packedBuffer, offset); + offset += Rectangle.packedLength; - if (this._mode === SceneMode.SCENE3D) { - result = pickEllipsoid3D(this, windowPosition, ellipsoid, result); - } else if (this._mode === SceneMode.SCENE2D) { - result = pickMap2D(this, windowPosition, this._projection, result); - } else if (this._mode === SceneMode.COLUMBUS_VIEW) { - result = pickMapColumbusView(this, windowPosition, this._projection, result); - } else { - return undefined; + Ellipsoid.pack(ellipsoid, packedBuffer, offset); + + return packedBuffer; + } + + var createVerticesTaskProcessor = new TaskProcessor('createVectorTilePoints'); + var scratchPosition = new Cartesian3(); + + function createPoints(points, ellipsoid) { + if (defined(points._billboardCollection)) { + return; } - return result; - }; + var positions; + if (!defined(points._verticesPromise)) { + positions = points._positions; + var packedBuffer = points._packedBuffer; - var pickPerspCenter = new Cartesian3(); - var pickPerspXDir = new Cartesian3(); - var pickPerspYDir = new Cartesian3(); - function getPickRayPerspective(camera, windowPosition, result) { - var canvas = camera._scene.canvas; - var width = canvas.clientWidth; - var height = canvas.clientHeight; + if (!defined(packedBuffer)) { + // Copy because they may be the views on the same buffer. + positions = points._positions = arraySlice(positions); + points._batchIds = arraySlice(points._batchIds); - var tanPhi = Math.tan(camera.frustum.fovy * 0.5); - var tanTheta = camera.frustum.aspectRatio * tanPhi; - var near = camera.frustum.near; + packedBuffer = points._packedBuffer = packBuffer(points, ellipsoid); + } - var x = (2.0 / width) * windowPosition.x - 1.0; - var y = (2.0 / height) * (height - windowPosition.y) - 1.0; + var transferrableObjects = [positions.buffer, packedBuffer.buffer]; + var parameters = { + positions : positions.buffer, + packedBuffer : packedBuffer.buffer + }; - var position = camera.positionWC; - Cartesian3.clone(position, result.origin); + var verticesPromise = points._verticesPromise = createVerticesTaskProcessor.scheduleTask(parameters, transferrableObjects); + if (!defined(verticesPromise)) { + // Postponed + return; + } - var nearCenter = Cartesian3.multiplyByScalar(camera.directionWC, near, pickPerspCenter); - Cartesian3.add(position, nearCenter, nearCenter); - var xDir = Cartesian3.multiplyByScalar(camera.rightWC, x * near * tanTheta, pickPerspXDir); - var yDir = Cartesian3.multiplyByScalar(camera.upWC, y * near * tanPhi, pickPerspYDir); - var direction = Cartesian3.add(nearCenter, xDir, result.direction); - Cartesian3.add(direction, yDir, direction); - Cartesian3.subtract(direction, position, direction); - Cartesian3.normalize(direction, direction); + verticesPromise.then(function(result) { + points._positions = new Float64Array(result.positions); + points._ready = true; + }); + } - return result; - } + if (points._ready && !defined(points._billboardCollection)) { + positions = points._positions; + var batchTable = points._batchTable; + var batchIds = points._batchIds; - var scratchDirection = new Cartesian3(); + var billboardCollection = points._billboardCollection = new BillboardCollection({batchTable : batchTable}); + var labelCollection = points._labelCollection = new LabelCollection({batchTable : batchTable}); + var polylineCollection = points._polylineCollection = new PolylineCollection(); + polylineCollection._useHighlightColor = true; - function getPickRayOrthographic(camera, windowPosition, result) { - var canvas = camera._scene.canvas; - var width = canvas.clientWidth; - var height = canvas.clientHeight; + var numberOfPoints = positions.length / 3; + for (var i = 0; i < numberOfPoints; ++i) { + var id = batchIds[i]; - var frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; - } - var x = (2.0 / width) * windowPosition.x - 1.0; - x *= (frustum.right - frustum.left) * 0.5; - var y = (2.0 / height) * (height - windowPosition.y) - 1.0; - y *= (frustum.top - frustum.bottom) * 0.5; + var position = Cartesian3.unpack(positions, i * 3, scratchPosition); - var origin = result.origin; - Cartesian3.clone(camera.position, origin); + var b = billboardCollection.add(); + b.position = position; + b._batchIndex = id; - Cartesian3.multiplyByScalar(camera.right, x, scratchDirection); - Cartesian3.add(scratchDirection, origin, origin); - Cartesian3.multiplyByScalar(camera.up, y, scratchDirection); - Cartesian3.add(scratchDirection, origin, origin); + var l = labelCollection.add(); + l.text = ' '; + l.position = position; + l._batchIndex = id; - Cartesian3.clone(camera.directionWC, result.direction); + var p = polylineCollection.add(); + p.positions = [Cartesian3.clone(position), Cartesian3.clone(position)]; + } - if (camera._mode === SceneMode.COLUMBUS_VIEW) { - Cartesian3.fromElements(result.origin.z, result.origin.x, result.origin.y, result.origin); + points._positions = undefined; + points._packedBuffer = undefined; } - - return result; } /** - * Create a ray from the camera position through the pixel at <code>windowPosition</code> - * in world coordinates. + * Creates features for each point and places it at the batch id index of features. * - * @param {Cartesian2} windowPosition The x and y coordinates of a pixel. - * @param {Ray} [result] The object onto which to store the result. - * @returns {Ray} Returns the {@link Cartesian3} position and direction of the ray. + * @param {Vector3DTileContent} content The vector tile content. + * @param {Cesium3DTileFeature[]} features An array of features where the point features will be placed. */ - Camera.prototype.getPickRay = function(windowPosition, result) { - if (!defined(windowPosition)) { - throw new DeveloperError('windowPosition is required.'); - } - - if (!defined(result)) { - result = new Ray(); - } + Vector3DTilePoints.prototype.createFeatures = function(content, features) { + var billboardCollection = this._billboardCollection; + var labelCollection = this._labelCollection; + var polylineCollection = this._polylineCollection; - var frustum = this.frustum; - if (defined(frustum.aspectRatio) && defined(frustum.fov) && defined(frustum.near)) { - return getPickRayPerspective(this, windowPosition, result); - } + var batchIds = this._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; - return getPickRayOrthographic(this, windowPosition, result); - }; + var billboard = billboardCollection.get(i); + var label = labelCollection.get(i); + var polyline = polylineCollection.get(i); - var scratchToCenter = new Cartesian3(); - var scratchProj = new Cartesian3(); + features[batchId] = new Cesium3DTilePointFeature(content, batchId, billboard, label, polyline); + } + }; /** - * Return the distance from the camera to the front of the bounding sphere. + * Colors the entire tile when enabled is true. The resulting color will be (batch table color * color). * - * @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. - * @returns {Number} The distance to the bounding sphere. + * @param {Boolean} enabled Whether to enable debug coloring. + * @param {Color} color The debug color. */ - Camera.prototype.distanceToBoundingSphere = function(boundingSphere) { - if (!defined(boundingSphere)) { - throw new DeveloperError('boundingSphere is required.'); + Vector3DTilePoints.prototype.applyDebugSettings = function(enabled, color) { + if (enabled) { + Color.clone(color, this._billboardCollection._highlightColor); + Color.clone(color, this._labelCollection._highlightColor); + Color.clone(color, this._polylineCollection._highlightColor); + } else { + Color.clone(Color.WHITE, this._billboardCollection._highlightColor); + Color.clone(Color.WHITE, this._labelCollection._highlightColor); + Color.clone(Color.WHITE, this._polylineCollection._highlightColor); } - - var toCenter = Cartesian3.subtract(this.positionWC, boundingSphere.center, scratchToCenter); - var proj = Cartesian3.multiplyByScalar(this.directionWC, Cartesian3.dot(toCenter, this.directionWC), scratchProj); - return Math.max(0.0, Cartesian3.magnitude(proj) - boundingSphere.radius); }; - var scratchPixelSize = new Cartesian2(); + function clearStyle(polygons, features) { + var batchIds = polygons._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; + var feature = features[batchId]; + + feature.show = true; + feature.pointSize = Cesium3DTilePointFeature.defaultPointSize; + feature.color = Cesium3DTilePointFeature.defaultColor; + feature.pointOutlineColor = Cesium3DTilePointFeature.defaultPointOutlineColor; + feature.pointOutlineWidth = Cesium3DTilePointFeature.defaultPointOutlineWidth; + feature.labelColor = Color.WHITE; + feature.labelOutlineColor = Color.WHITE; + feature.labelOutlineWidth = 1.0; + feature.font = '30px sans-serif'; + feature.labelStyle = LabelStyle.FILL; + feature.labelText = undefined; + feature.backgroundColor = new Color(0.165, 0.165, 0.165, 0.8); + feature.backgroundPadding = new Cartesian2(7, 5); + feature.backgroundEnabled = false; + feature.scaleByDistance = undefined; + feature.translucencyByDistance = undefined; + feature.distanceDisplayCondition = undefined; + feature.heightOffset = 0.0; + feature.anchorLineEnabled = false; + feature.anchorLineColor = Color.WHITE; + feature.image = undefined; + feature.disableDepthTestDistance = 0.0; + feature.horizontalOrigin = HorizontalOrigin.CENTER; + feature.verticalOrigin = VerticalOrigin.CENTER; + feature.labelHorizontalOrigin = HorizontalOrigin.RIGHT; + feature.labelVerticalOrigin = VerticalOrigin.BASELINE; + } + } + + var scratchColor = new Color(); + var scratchColor2 = new Color(); + var scratchColor3 = new Color(); + var scratchColor4 = new Color(); + var scratchColor5 = new Color(); + var scratchColor6 = new Color(); + var scratchScaleByDistance = new NearFarScalar(); + var scratchTranslucencyByDistance = new NearFarScalar(); + var scratchDistanceDisplayCondition = new DistanceDisplayCondition(); /** - * Return the pixel size in meters. + * Apply a style to the content. * - * @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. - * @param {Number} drawingBufferWidth The drawing buffer width. - * @param {Number} drawingBufferHeight The drawing buffer height. - * @returns {Number} The pixel size in meters. + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileStyle} style The style. + * @param {Cesium3DTileFeature[]} features The array of features. */ - Camera.prototype.getPixelSize = function(boundingSphere, drawingBufferWidth, drawingBufferHeight) { - if (!defined(boundingSphere)) { - throw new DeveloperError('boundingSphere is required.'); - } - if (!defined(drawingBufferWidth)) { - throw new DeveloperError('drawingBufferWidth is required.'); - } - if (!defined(drawingBufferHeight)) { - throw new DeveloperError('drawingBufferHeight is required.'); - } - - var distance = this.distanceToBoundingSphere(boundingSphere); - var pixelSize = this.frustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, scratchPixelSize); - return Math.max(pixelSize.x, pixelSize.y); - }; - - function createAnimationTemplateCV(camera, position, center, maxX, maxY, duration) { - var newPosition = Cartesian3.clone(position); - - if (center.y > maxX) { - newPosition.y -= center.y - maxX; - } else if (center.y < -maxX) { - newPosition.y += -maxX - center.y; + Vector3DTilePoints.prototype.applyStyle = function(frameState, style, features) { + if (!defined(style)) { + clearStyle(this, features); + return; } - if (center.z > maxY) { - newPosition.z -= center.z - maxY; - } else if (center.z < -maxY) { - newPosition.z += -maxY - center.z; - } + var batchIds = this._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; + var feature = features[batchId]; - function updateCV(value) { - var interp = Cartesian3.lerp(position, newPosition, value.time, new Cartesian3()); - camera.worldToCameraCoordinatesPoint(interp, camera.position); - } - return { - easingFunction : EasingFunction.EXPONENTIAL_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - duration : duration, - update : updateCV - }; - } + if (defined(style.show)) { + feature.show = style.show.evaluate(frameState, feature); + } - var normalScratch = new Cartesian3(); - var centerScratch = new Cartesian3(); - var posScratch = new Cartesian3(); - var scratchCartesian3Subtract = new Cartesian3(); + if (defined(style.pointSize)) { + feature.pointSize = style.pointSize.evaluate(frameState, feature); + } - function createAnimationCV(camera, duration) { - var position = camera.position; - var direction = camera.direction; + if (defined(style.color)) { + feature.color = style.color.evaluateColor(frameState, feature, scratchColor); + } - var normal = camera.worldToCameraCoordinatesVector(Cartesian3.UNIT_X, normalScratch); - var scalar = -Cartesian3.dot(normal, position) / Cartesian3.dot(normal, direction); - var center = Cartesian3.add(position, Cartesian3.multiplyByScalar(direction, scalar, centerScratch), centerScratch); - camera.cameraToWorldCoordinatesPoint(center, center); + if (defined(style.pointOutlineColor)) { + feature.pointOutlineColor = style.pointOutlineColor.evaluateColor(frameState, feature, scratchColor2); + } - position = camera.cameraToWorldCoordinatesPoint(camera.position, posScratch); + if (defined(style.pointOutlineWidth)) { + feature.pointOutlineWidth = style.pointOutlineWidth.evaluate(frameState, feature); + } - var tanPhi = Math.tan(camera.frustum.fovy * 0.5); - var tanTheta = camera.frustum.aspectRatio * tanPhi; - var distToC = Cartesian3.magnitude(Cartesian3.subtract(position, center, scratchCartesian3Subtract)); - var dWidth = tanTheta * distToC; - var dHeight = tanPhi * distToC; + if (defined(style.labelColor)) { + feature.labelColor = style.labelColor.evaluateColor(frameState, feature, scratchColor3); + } - var mapWidth = camera._maxCoord.x; - var mapHeight = camera._maxCoord.y; + if (defined(style.labelOutlineColor)) { + feature.labelOutlineColor = style.labelOutlineColor.evaluateColor(frameState, feature, scratchColor4); + } - var maxX = Math.max(dWidth - mapWidth, mapWidth); - var maxY = Math.max(dHeight - mapHeight, mapHeight); + if (defined(style.labelOutlineWidth)) { + feature.labelOutlineWidth = style.labelOutlineWidth.evaluate(frameState, feature); + } - if (position.z < -maxX || position.z > maxX || position.y < -maxY || position.y > maxY) { - var translateX = center.y < -maxX || center.y > maxX; - var translateY = center.z < -maxY || center.z > maxY; - if (translateX || translateY) { - return createAnimationTemplateCV(camera, position, center, maxX, maxY, duration); + if (defined(style.font)) { + feature.font = style.font.evaluate(frameState, feature); } - } - return undefined; - } + if (defined(style.labelStyle)) { + feature.labelStyle = style.labelStyle.evaluate(frameState, feature); + } - /** - * Create an animation to move the map into view. This method is only valid for 2D and Columbus modes. - * - * @param {Number} duration The duration, in seconds, of the animation. - * @returns {Object} The animation or undefined if the scene mode is 3D or the map is already ion view. - * - * @private - */ - Camera.prototype.createCorrectPositionTween = function(duration) { - if (!defined(duration)) { - throw new DeveloperError('duration is required.'); - } - - if (this._mode === SceneMode.COLUMBUS_VIEW) { - return createAnimationCV(this, duration); - } + if (defined(style.labelText)) { + feature.labelText = style.labelText.evaluate(frameState, feature); + } else { + feature.labelText = undefined; + } - return undefined; - }; + if (defined(style.backgroundColor)) { + feature.backgroundColor = style.backgroundColor.evaluateColor(frameState, feature, scratchColor5); + } - var scratchFlyToDestination = new Cartesian3(); - var newOptions = { - destination : undefined, - heading : undefined, - pitch : undefined, - roll : undefined, - duration : undefined, - complete : undefined, - cancel : undefined, - endTransform : undefined, - maximumHeight : undefined, - easingFunction : undefined - }; + if (defined(style.backgroundPadding)) { + feature.backgroundPadding = style.backgroundPadding.evaluate(frameState, feature); + } - /** - * Cancels the current camera flight if one is in progress. - * The camera is left at it's current location. - */ - Camera.prototype.cancelFlight = function () { - if (defined(this._currentFlight)) { - this._currentFlight.cancelTween(); - this._currentFlight = undefined; - } - }; + if (defined(style.backgroundEnabled)) { + feature.backgroundEnabled = style.backgroundEnabled.evaluate(frameState, feature); + } - /** - * Flies the camera from its current position to a new position. - * - * @param {Object} options Object with the following properties: - * @param {Cartesian3|Rectangle} options.destination The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. - * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pith and roll properties. By default, the direction will point - * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive - * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. - * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. - * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. - * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. - * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed. - * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. - * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. - * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. - * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. - * @param {EasingFunction|EasingFunction~Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight. - * - * @exception {DeveloperError} If either direction or up is given, then both are required. - * - * @example - * // 1. Fly to a position with a top-down view - * viewer.camera.flyTo({ - * destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0) - * }); - * - * // 2. Fly to a Rectangle with a top-down view - * viewer.camera.flyTo({ - * destination : Cesium.Rectangle.fromDegrees(west, south, east, north) - * }); - * - * // 3. Fly to a position with an orientation using unit vectors. - * viewer.camera.flyTo({ - * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), - * orientation : { - * direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734), - * up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339) - * } - * }); - * - * // 4. Fly to a position with an orientation using heading, pitch and roll. - * viewer.camera.flyTo({ - * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0), - * orientation : { - * heading : Cesium.Math.toRadians(175.0), - * pitch : Cesium.Math.toRadians(-35.0), - * roll : 0.0 - * } - * }); - */ - Camera.prototype.flyTo = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var destination = options.destination; - if (!defined(destination)) { - throw new DeveloperError('destination is required.'); - } - - var mode = this._mode; - if (mode === SceneMode.MORPHING) { - return; - } + if (defined(style.scaleByDistance)) { + var scaleByDistanceCart4 = style.scaleByDistance.evaluate(frameState, feature); + scratchScaleByDistance.near = scaleByDistanceCart4.x; + scratchScaleByDistance.nearValue = scaleByDistanceCart4.y; + scratchScaleByDistance.far = scaleByDistanceCart4.z; + scratchScaleByDistance.farValue = scaleByDistanceCart4.w; + feature.scaleByDistance = scratchScaleByDistance; + } else { + feature.scaleByDistance = undefined; + } - this.cancelFlight(); + if (defined(style.translucencyByDistance)) { + var translucencyByDistanceCart4 = style.translucencyByDistance.evaluate(frameState, feature); + scratchTranslucencyByDistance.near = translucencyByDistanceCart4.x; + scratchTranslucencyByDistance.nearValue = translucencyByDistanceCart4.y; + scratchTranslucencyByDistance.far = translucencyByDistanceCart4.z; + scratchTranslucencyByDistance.farValue = translucencyByDistanceCart4.w; + feature.translucencyByDistance = scratchTranslucencyByDistance; + } else { + feature.translucencyByDistance = undefined; + } - var orientation = defaultValue(options.orientation, defaultValue.EMPTY_OBJECT); - if (defined(orientation.direction)) { - orientation = directionUpToHeadingPitchRoll(this, destination, orientation, scratchSetViewOptions.orientation); - } + if (defined(style.distanceDisplayCondition)) { + var distanceDisplayConditionCart2 = style.distanceDisplayCondition.evaluate(frameState, feature); + scratchDistanceDisplayCondition.near = distanceDisplayConditionCart2.x; + scratchDistanceDisplayCondition.far = distanceDisplayConditionCart2.y; + feature.distanceDisplayCondition = scratchDistanceDisplayCondition; + } else { + feature.distanceDisplayCondition = undefined; + } - if (defined(options.duration) && options.duration <= 0.0) { - var setViewOptions = scratchSetViewOptions; - setViewOptions.destination = options.destination; - setViewOptions.orientation.heading = orientation.heading; - setViewOptions.orientation.pitch = orientation.pitch; - setViewOptions.orientation.roll = orientation.roll; - setViewOptions.convert = options.convert; - setViewOptions.endTransform = options.endTransform; - this.setView(setViewOptions); - if (typeof options.complete === 'function') { - options.complete(); + if (defined(style.heightOffset)) { + feature.heightOffset = style.heightOffset.evaluate(frameState, feature); } - return; - } - var isRectangle = defined(destination.west); - if (isRectangle) { - destination = this.getRectangleCameraCoordinates(destination, scratchFlyToDestination); - } + if (defined(style.anchorLineEnabled)) { + feature.anchorLineEnabled = style.anchorLineEnabled.evaluate(frameState, feature); + } - var that = this; - var flightTween; + if (defined(style.anchorLineColor)) { + feature.anchorLineColor = style.anchorLineColor.evaluateColor(frameState, feature, scratchColor6); + } - newOptions.destination = destination; - newOptions.heading = orientation.heading; - newOptions.pitch = orientation.pitch; - newOptions.roll = orientation.roll; - newOptions.duration = options.duration; - newOptions.complete = function () { - if(flightTween === that._currentFlight){ - that._currentFlight = undefined; + if (defined(style.image)) { + feature.image = style.image.evaluate(frameState, feature); + } else { + feature.image = undefined; } - if (defined(options.complete)) { - options.complete(); + + if (defined(style.disableDepthTestDistance)) { + feature.disableDepthTestDistance = style.disableDepthTestDistance.evaluate(frameState, feature); } - }; - newOptions.cancel = options.cancel; - newOptions.endTransform = options.endTransform; - newOptions.convert = isRectangle ? false : options.convert; - newOptions.maximumHeight = options.maximumHeight; - newOptions.pitchAdjustHeight = options.pitchAdjustHeight; - newOptions.flyOverLongitude = options.flyOverLongitude; - newOptions.flyOverLongitudeWeight = options.flyOverLongitudeWeight; - newOptions.easingFunction = options.easingFunction; - var scene = this._scene; - flightTween = scene.tweens.add(CameraFlightPath.createTween(scene, newOptions)); - this._currentFlight = flightTween; - }; + if (defined(style.horizontalOrigin)) { + feature.horizontalOrigin = style.horizontalOrigin.evaluate(frameState, feature); + } - function distanceToBoundingSphere3D(camera, radius) { - var frustum = camera.frustum; - var tanPhi = Math.tan(frustum.fovy * 0.5); - var tanTheta = frustum.aspectRatio * tanPhi; - return Math.max(radius / tanTheta, radius / tanPhi); - } + if (defined(style.verticalOrigin)) { + feature.verticalOrigin = style.verticalOrigin.evaluate(frameState, feature); + } - function distanceToBoundingSphere2D(camera, radius) { - var frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; - } + if (defined(style.labelHorizontalOrigin)) { + feature.labelHorizontalOrigin = style.labelHorizontalOrigin.evaluate(frameState, feature); + } - var right, top; - var ratio = frustum.right / frustum.top; - var heightRatio = radius * ratio; - if (radius > heightRatio) { - right = radius; - top = right / ratio; - } else { - top = radius; - right = heightRatio; + if (defined(style.labelVerticalOrigin)) { + feature.labelVerticalOrigin = style.labelVerticalOrigin.evaluate(frameState, feature); + } } + }; - return Math.max(right, top) * 1.50; - } - - var MINIMUM_ZOOM = 100.0; + /** + * @private + */ + Vector3DTilePoints.prototype.update = function(frameState) { + createPoints(this, frameState.mapProjection.ellipsoid); - function adjustBoundingSphereOffset(camera, boundingSphere, offset) { - if (!defined(offset)) { - offset = HeadingPitchRange.clone(Camera.DEFAULT_OFFSET); + if (!this._ready) { + return; } - var minimumZoom = camera._scene.screenSpaceCameraController.minimumZoomDistance; - var maximumZoom = camera._scene.screenSpaceCameraController.maximumZoomDistance; - var range = offset.range; - if (!defined(range) || range === 0.0) { - var radius = boundingSphere.radius; - if (radius === 0.0) { - offset.range = MINIMUM_ZOOM; - } else if (camera.frustum instanceof OrthographicFrustum || camera._mode === SceneMode.SCENE2D) { - offset.range = distanceToBoundingSphere2D(camera, radius); - } else { - offset.range = distanceToBoundingSphere3D(camera, radius); - } - offset.range = CesiumMath.clamp(offset.range, minimumZoom, maximumZoom); - } + this._polylineCollection.update(frameState); + this._billboardCollection.update(frameState); + this._labelCollection.update(frameState); - return offset; - } + if (!this._resolvedPromise) { + this._readyPromise.resolve(); + this._resolvedPromise = true; + } + }; /** - * Sets the camera so that the current view contains the provided bounding sphere. - * - * <p>The offset is heading/pitch/range in the local east-north-up reference frame centered at the center of the bounding sphere. - * The heading and the pitch angles are defined in the local east-north-up reference frame. - * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch - * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. If the range is - * zero, a range will be computed such that the whole bounding sphere is visible.</p> + * Returns true if this object was destroyed; otherwise, false. + * <p> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> * - * <p>In 2D, there must be a top down view. The camera will be placed above the target looking down. The height above the - * target will be the range. The heading will be determined from the offset. If the heading cannot be - * determined from the offset, the heading will be north.</p> + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + */ + Vector3DTilePoints.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> * - * @param {BoundingSphere} boundingSphere The bounding sphere to view, in world coordinates. - * @param {HeadingPitchRange} [offset] The offset from the target in the local east-north-up reference frame centered at the target. + * @returns {undefined} * - * @exception {DeveloperError} viewBoundingSphere is not supported while morphing. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ - Camera.prototype.viewBoundingSphere = function(boundingSphere, offset) { - if (!defined(boundingSphere)) { - throw new DeveloperError('boundingSphere is required.'); - } - - if (this._mode === SceneMode.MORPHING) { - throw new DeveloperError('viewBoundingSphere is not supported while morphing.'); - } - - offset = adjustBoundingSphereOffset(this, boundingSphere, offset); - this.lookAt(boundingSphere.center, offset); + Vector3DTilePoints.prototype.destroy = function() { + this._billboardCollection = this._billboardCollection && this._billboardCollection.destroy(); + this._labelCollection = this._labelCollection && this._labelCollection.destroy(); + this._polylineCollection = this._polylineCollection && this._polylineCollection.destroy(); + return destroyObject(this); }; - var scratchflyToBoundingSphereTransform = new Matrix4(); - var scratchflyToBoundingSphereDestination = new Cartesian3(); - var scratchflyToBoundingSphereDirection = new Cartesian3(); - var scratchflyToBoundingSphereUp = new Cartesian3(); - var scratchflyToBoundingSphereRight = new Cartesian3(); - var scratchFlyToBoundingSphereCart4 = new Cartesian4(); - var scratchFlyToBoundingSphereQuaternion = new Quaternion(); - var scratchFlyToBoundingSphereMatrix3 = new Matrix3(); + return Vector3DTilePoints; +}); + +define('Scene/Vector3DTilePolygons',[ + '../Core/arraySlice', + '../Core/Cartesian3', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/Ellipsoid', + '../Core/IndexDatatype', + '../Core/Matrix4', + '../Core/OrientedBoundingBox', + '../Core/Rectangle', + '../Core/TaskProcessor', + '../ThirdParty/when', + './ClassificationType', + './Vector3DTileBatch', + './Vector3DTilePrimitive' + ], function( + arraySlice, + Cartesian3, + Color, + defaultValue, + defined, + defineProperties, + destroyObject, + Ellipsoid, + IndexDatatype, + Matrix4, + OrientedBoundingBox, + Rectangle, + TaskProcessor, + when, + ClassificationType, + Vector3DTileBatch, + Vector3DTilePrimitive) { + 'use strict'; /** - * Flies the camera to a location where the current view contains the provided bounding sphere. - * - * <p> The offset is heading/pitch/range in the local east-north-up reference frame centered at the center of the bounding sphere. - * The heading and the pitch angles are defined in the local east-north-up reference frame. - * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch - * angles are below the plane. Negative pitch angles are above the plane. The range is the distance from the center. If the range is - * zero, a range will be computed such that the whole bounding sphere is visible.</p> + * Creates a batch of pre-triangulated polygons draped on terrain and/or 3D Tiles. * - * <p>In 2D and Columbus View, there must be a top down view. The camera will be placed above the target looking down. The height above the - * target will be the range. The heading will be aligned to local north.</p> + * @alias Vector3DTilePolygons + * @constructor * - * @param {BoundingSphere} boundingSphere The bounding sphere to view, in world coordinates. - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. - * @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target. - * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. - * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. - * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed. - * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. - * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. - * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. - * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. - * @param {EasingFunction|EasingFunction~Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight. - */ - Camera.prototype.flyToBoundingSphere = function(boundingSphere, options) { - if (!defined(boundingSphere)) { - throw new DeveloperError('boundingSphere is required.'); - } - - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var scene2D = this._mode === SceneMode.SCENE2D || this._mode === SceneMode.COLUMBUS_VIEW; - this._setTransform(Matrix4.IDENTITY); - var offset = adjustBoundingSphereOffset(this, boundingSphere, options.offset); + * @param {Object} options An object with following properties: + * @param {Float32Array|Uint16Array} options.positions The positions of the polygons. The positions must be contiguous + * so that the positions for polygon n are in [c, c + counts[n]] where c = sum{counts[0], counts[n - 1]} and they are the outer ring of + * the polygon in counter-clockwise order. + * @param {Uint32Array} options.counts The number of positions in the each polygon. + * @param {Uint32Array} options.indices The indices of the triangulated polygons. The indices must be contiguous so that + * the indices for polygon n are in [i, i + indexCounts[n]] where i = sum{indexCounts[0], indexCounts[n - 1]}. + * @param {Uint32Array} options.indexCounts The number of indices for each polygon. + * @param {Number} options.minimumHeight The minimum height of the terrain covered by the tile. + * @param {Number} options.maximumHeight The maximum height of the terrain covered by the tile. + * @param {Float32Array} [options.polygonMinimumHeights] An array containing the minimum heights for each polygon. + * @param {Float32Array} [options.polygonMaximumHeights] An array containing the maximum heights for each polygon. + * @param {Rectangle} options.rectangle The rectangle containing the tile. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid. + * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center. + * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polygons. + * @param {Uint16Array} options.batchIds The batch ids for each polygon. + * @param {BoundingSphere} options.boundingVolume The bounding volume for the entire batch of polygons. + * + * @private + */ + function Vector3DTilePolygons(options) { + // All of the private properties will be released except _readyPromise + // and _primitive after the Vector3DTilePrimitive is created. + this._batchTable = options.batchTable; - var position; - if (scene2D) { - position = Cartesian3.multiplyByScalar(Cartesian3.UNIT_Z, offset.range, scratchflyToBoundingSphereDestination); - } else { - position = offsetFromHeadingPitchRange(offset.heading, offset.pitch, offset.range); - } + this._batchIds = options.batchIds; + this._positions = options.positions; + this._counts = options.counts; - var transform = Transforms.eastNorthUpToFixedFrame(boundingSphere.center, Ellipsoid.WGS84, scratchflyToBoundingSphereTransform); - Matrix4.multiplyByPoint(transform, position, position); + this._indices = options.indices; + this._indexCounts = options.indexCounts; + this._indexOffsets = undefined; - var direction; - var up; + this._batchTableColors = undefined; + this._packedBuffer = undefined; - if (!scene2D) { - direction = Cartesian3.subtract(boundingSphere.center, position, scratchflyToBoundingSphereDirection); - Cartesian3.normalize(direction, direction); + this._batchedPositions = undefined; + this._transferrableBatchIds = undefined; + this._vertexBatchIds = undefined; - up = Matrix4.multiplyByPointAsVector(transform, Cartesian3.UNIT_Z, scratchflyToBoundingSphereUp); - if (1.0 - Math.abs(Cartesian3.dot(direction, up)) < CesiumMath.EPSILON6) { - var rotateQuat = Quaternion.fromAxisAngle(direction, offset.heading, scratchFlyToBoundingSphereQuaternion); - var rotation = Matrix3.fromQuaternion(rotateQuat, scratchFlyToBoundingSphereMatrix3); + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._minimumHeight = options.minimumHeight; + this._maximumHeight = options.maximumHeight; + this._polygonMinimumHeights = options.polygonMinimumHeights; + this._polygonMaximumHeights = options.polygonMaximumHeights; + this._center = defaultValue(options.center, Cartesian3.ZERO); + this._rectangle = options.rectangle; - Cartesian3.fromCartesian4(Matrix4.getColumn(transform, 1, scratchFlyToBoundingSphereCart4), up); - Matrix3.multiplyByVector(rotation, up, up); - } + this._center = undefined; - var right = Cartesian3.cross(direction, up, scratchflyToBoundingSphereRight); - Cartesian3.cross(right, direction, up); - Cartesian3.normalize(up, up); - } + this._boundingVolume = options.boundingVolume; + this._boundingVolumes = undefined; - this.flyTo({ - destination : position, - orientation : { - direction : direction, - up : up - }, - duration : options.duration, - complete : options.complete, - cancel : options.cancel, - endTransform : options.endTransform, - maximumHeight : options.maximumHeight, - easingFunction : options.easingFunction, - flyOverLongitude : options.flyOverLongitude, - flyOverLongitudeWeight : options.flyOverLongitudeWeight, - pitchAdjustHeight : options.pitchAdjustHeight - }); - }; + this._batchedIndices = undefined; - var scratchCartesian3_1 = new Cartesian3(); - var scratchCartesian3_2 = new Cartesian3(); - var scratchCartesian3_3 = new Cartesian3(); - var scratchCartesian3_4 = new Cartesian3(); - var horizonPoints = [new Cartesian3(), new Cartesian3(), new Cartesian3(), new Cartesian3()]; + this._ready = false; + this._readyPromise = when.defer(); - function computeHorizonQuad(camera, ellipsoid) { - var radii = ellipsoid.radii; - var p = camera.positionWC; + this._verticesPromise = undefined; - // Find the corresponding position in the scaled space of the ellipsoid. - var q = Cartesian3.multiplyComponents(ellipsoid.oneOverRadii, p, scratchCartesian3_1); + this._primitive = undefined; - var qMagnitude = Cartesian3.magnitude(q); - var qUnit = Cartesian3.normalize(q, scratchCartesian3_2); + /** + * Draws the wireframe of the classification meshes. + * @type {Boolean} + * @default false + */ + this.debugWireframe = false; - // Determine the east and north directions at q. - var eUnit; - var nUnit; - if (Cartesian3.equalsEpsilon(qUnit, Cartesian3.UNIT_Z, CesiumMath.EPSILON10)) { - eUnit = new Cartesian3(0, 1, 0); - nUnit = new Cartesian3(0, 0, 1); - } else { - eUnit = Cartesian3.normalize(Cartesian3.cross(Cartesian3.UNIT_Z, qUnit, scratchCartesian3_3), scratchCartesian3_3); - nUnit = Cartesian3.normalize(Cartesian3.cross(qUnit, eUnit, scratchCartesian3_4), scratchCartesian3_4); + /** + * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only. + * @type {Boolean} + * @default false + */ + this.forceRebatch = false; + + /** + * What this tile will classify. + * @type {ClassificationType} + * @default ClassificationType.CESIUM_3D_TILE + */ + this.classificationType = ClassificationType.CESIUM_3D_TILE; + } + + defineProperties(Vector3DTilePolygons.prototype, { + /** + * Gets the number of triangles. + * + * @memberof Vector3DTilePolygons.prototype + * + * @type {Number} + * @readonly + */ + trianglesLength : { + get : function() { + if (defined(this._primitive)) { + return this._primitive.trianglesLength; + } + return 0; + } + }, + + /** + * Gets the geometry memory in bytes. + * + * @memberof Vector3DTilePolygons.prototype + * + * @type {Number} + * @readonly + */ + geometryByteLength : { + get : function() { + if (defined(this._primitive)) { + return this._primitive.geometryByteLength; + } + return 0; + } + }, + + /** + * Gets a promise that resolves when the primitive is ready to render. + * @memberof Vector3DTilePolygons.prototype + * @type {Promise} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } } + }); - // Determine the radius of the 'limb' of the ellipsoid. - var wMagnitude = Math.sqrt(Cartesian3.magnitudeSquared(q) - 1.0); + function packBuffer(polygons) { + var packedBuffer = new Float64Array(3 + Cartesian3.packedLength + Ellipsoid.packedLength + Rectangle.packedLength); - // Compute the center and offsets. - var center = Cartesian3.multiplyByScalar(qUnit, 1.0 / qMagnitude, scratchCartesian3_1); - var scalar = wMagnitude / qMagnitude; - var eastOffset = Cartesian3.multiplyByScalar(eUnit, scalar, scratchCartesian3_2); - var northOffset = Cartesian3.multiplyByScalar(nUnit, scalar, scratchCartesian3_3); + var offset = 0; + packedBuffer[offset++] = polygons._indices.BYTES_PER_ELEMENT; - // A conservative measure for the longitudes would be to use the min/max longitudes of the bounding frustum. - var upperLeft = Cartesian3.add(center, northOffset, horizonPoints[0]); - Cartesian3.subtract(upperLeft, eastOffset, upperLeft); - Cartesian3.multiplyComponents(radii, upperLeft, upperLeft); + packedBuffer[offset++] = polygons._minimumHeight; + packedBuffer[offset++] = polygons._maximumHeight; - var lowerLeft = Cartesian3.subtract(center, northOffset, horizonPoints[1]); - Cartesian3.subtract(lowerLeft, eastOffset, lowerLeft); - Cartesian3.multiplyComponents(radii, lowerLeft, lowerLeft); + Cartesian3.pack(polygons._center, packedBuffer, offset); + offset += Cartesian3.packedLength; - var lowerRight = Cartesian3.subtract(center, northOffset, horizonPoints[2]); - Cartesian3.add(lowerRight, eastOffset, lowerRight); - Cartesian3.multiplyComponents(radii, lowerRight, lowerRight); + Ellipsoid.pack(polygons._ellipsoid, packedBuffer, offset); + offset += Ellipsoid.packedLength; - var upperRight = Cartesian3.add(center, northOffset, horizonPoints[3]); - Cartesian3.add(upperRight, eastOffset, upperRight); - Cartesian3.multiplyComponents(radii, upperRight, upperRight); + Rectangle.pack(polygons._rectangle, packedBuffer, offset); - return horizonPoints; + return packedBuffer; } - var scratchPickCartesian2 = new Cartesian2(); - var scratchRectCartesian = new Cartesian3(); - var cartoArray = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; - function addToResult(x, y, index, camera, ellipsoid, computedHorizonQuad) { - scratchPickCartesian2.x = x; - scratchPickCartesian2.y = y; - var r = camera.pickEllipsoid(scratchPickCartesian2, ellipsoid, scratchRectCartesian); - if (defined(r)) { - cartoArray[index] = ellipsoid.cartesianToCartographic(r, cartoArray[index]); - return 1; + function unpackBuffer(polygons, packedBuffer) { + var offset = 1; + + var numBVS = packedBuffer[offset++]; + var bvs = polygons._boundingVolumes = new Array(numBVS); + + for (var i = 0; i < numBVS; ++i) { + bvs[i] = OrientedBoundingBox.unpack(packedBuffer, offset); + offset += OrientedBoundingBox.packedLength; + } + + var numBatchedIndices = packedBuffer[offset++]; + var bis = polygons._batchedIndices = new Array(numBatchedIndices); + + for (var j = 0; j < numBatchedIndices; ++j) { + var color = Color.unpack(packedBuffer, offset); + offset += Color.packedLength; + + var indexOffset = packedBuffer[offset++]; + var count = packedBuffer[offset++]; + + var length = packedBuffer[offset++]; + var batchIds = new Array(length); + + for (var k = 0; k < length; ++k) { + batchIds[k] = packedBuffer[offset++]; + } + + bis[j] = new Vector3DTileBatch({ + color : color, + offset : indexOffset, + count : count, + batchIds : batchIds + }); } - cartoArray[index] = ellipsoid.cartesianToCartographic(computedHorizonQuad[index], cartoArray[index]); - return 0; } - /** - * Computes the approximate visible rectangle on the ellipsoid. - * - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that you want to know the visible region. - * @param {Rectangle} [result] The rectangle in which to store the result - * - * @returns {Rectangle|undefined} The visible rectangle or undefined if the ellipsoid isn't visible at all. - */ - Camera.prototype.computeViewRectangle = function(ellipsoid, result) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - var cullingVolume = this.frustum.computeCullingVolume(this.positionWC, this.directionWC, this.upWC); - var boundingSphere = new BoundingSphere(Cartesian3.ZERO, ellipsoid.maximumRadius); - var visibility = cullingVolume.computeVisibility(boundingSphere); - if (visibility === Intersect.OUTSIDE) { - return undefined; + + var createVerticesTaskProcessor = new TaskProcessor('createVectorTilePolygons'); + var scratchColor = new Color(); + + function createPrimitive(polygons) { + if (defined(polygons._primitive)) { + return; } - var canvas = this._scene.canvas; - var width = canvas.clientWidth; - var height = canvas.clientHeight; + if (!defined(polygons._verticesPromise)) { + var positions = polygons._positions; + var counts = polygons._counts; + var indexCounts = polygons._indexCounts; + var indices = polygons._indices; - var successfulPickCount = 0; + var batchIds = polygons._transferrableBatchIds; + var batchTableColors = polygons._batchTableColors; - var computedHorizonQuad = computeHorizonQuad(this, ellipsoid); + var packedBuffer = polygons._packedBuffer; - successfulPickCount += addToResult(0, 0, 0, this, ellipsoid, computedHorizonQuad); - successfulPickCount += addToResult(0, height, 1, this, ellipsoid, computedHorizonQuad); - successfulPickCount += addToResult(width, height, 2, this, ellipsoid, computedHorizonQuad); - successfulPickCount += addToResult(width, 0, 3, this, ellipsoid, computedHorizonQuad); + if (!defined(batchTableColors)) { + // Copy because they may be the views on the same buffer. + positions = polygons._positions = arraySlice(polygons._positions); + counts = polygons._counts = arraySlice(polygons._counts); + indexCounts = polygons._indexCounts= arraySlice(polygons._indexCounts); + indices = polygons._indices = arraySlice(polygons._indices); - if (successfulPickCount < 2) { - // If we have space non-globe in 3 or 4 corners then return the whole globe - return Rectangle.MAX_VALUE; - } + polygons._center = polygons._ellipsoid.cartographicToCartesian(Rectangle.center(polygons._rectangle)); - result = Rectangle.fromCartographicArray(cartoArray, result); + batchIds = polygons._transferrableBatchIds = new Uint32Array(polygons._batchIds); + batchTableColors = polygons._batchTableColors = new Uint32Array(batchIds.length); + var batchTable = polygons._batchTable; - // Detect if we go over the poles - var distance = 0; - var lastLon = cartoArray[3].longitude; - for (var i = 0; i < 4; ++i) { - var lon = cartoArray[i].longitude; - var diff = Math.abs(lon - lastLon); - if (diff > CesiumMath.PI) { - // Crossed the dateline - distance += CesiumMath.TWO_PI - diff; - } else { - distance += diff; + var length = batchTableColors.length; + for (var i = 0; i < length; ++i) { + var color = batchTable.getColor(i, scratchColor); + batchTableColors[i] = color.toRgba(); + } + + packedBuffer = polygons._packedBuffer = packBuffer(polygons); } - lastLon = lon; - } + var transferrableObjects = [positions.buffer, counts.buffer, indexCounts.buffer, indices.buffer, batchIds.buffer, batchTableColors.buffer, packedBuffer.buffer]; + var parameters = { + packedBuffer : packedBuffer.buffer, + positions : positions.buffer, + counts : counts.buffer, + indexCounts : indexCounts.buffer, + indices : indices.buffer, + batchIds : batchIds.buffer, + batchTableColors : batchTableColors.buffer + }; - // We are over one of the poles so adjust the rectangle accordingly - if (CesiumMath.equalsEpsilon(Math.abs(distance), CesiumMath.TWO_PI, CesiumMath.EPSILON9)) { - result.west = -CesiumMath.PI; - result.east = CesiumMath.PI; - if (cartoArray[0].latitude >= 0.0) { - result.north = CesiumMath.PI_OVER_TWO; - } else { - result.south = -CesiumMath.PI_OVER_TWO; + var minimumHeights = polygons._polygonMinimumHeights; + var maximumHeights = polygons._polygonMaximumHeights; + if (defined(minimumHeights) && defined(maximumHeights)) { + transferrableObjects.push(minimumHeights.buffer, maximumHeights.buffer); + parameters.minimumHeights = minimumHeights; + parameters.maximumHeights = maximumHeights; } + + var verticesPromise = polygons._verticesPromise = createVerticesTaskProcessor.scheduleTask(parameters, transferrableObjects); + if (!defined(verticesPromise)) { + // Postponed + return; + } + + when(verticesPromise, function(result) { + polygons._positions = undefined; + polygons._counts = undefined; + polygons._polygonMinimumHeights = undefined; + polygons._polygonMaximumHeights = undefined; + + var packedBuffer = new Float64Array(result.packedBuffer); + var indexDatatype = packedBuffer[0]; + unpackBuffer(polygons, packedBuffer); + + polygons._indices = IndexDatatype.getSizeInBytes(indexDatatype) === 2 ? new Uint16Array(result.indices) : new Uint32Array(result.indices); + polygons._indexOffsets = new Uint32Array(result.indexOffsets); + polygons._indexCounts = new Uint32Array(result.indexCounts); + + // will be released + polygons._batchedPositions = new Float32Array(result.positions); + polygons._vertexBatchIds = new Uint16Array(result.batchIds); + + polygons._ready = true; + }); } - return result; - }; + if (polygons._ready && !defined(polygons._primitive)) { + polygons._primitive = new Vector3DTilePrimitive({ + batchTable : polygons._batchTable, + positions : polygons._batchedPositions, + batchIds : polygons._batchIds, + vertexBatchIds : polygons._vertexBatchIds, + indices : polygons._indices, + indexOffsets : polygons._indexOffsets, + indexCounts : polygons._indexCounts, + batchedIndices : polygons._batchedIndices, + boundingVolume : polygons._boundingVolume, + boundingVolumes : polygons._boundingVolumes, + center : polygons._center + }); + + polygons._batchTable = undefined; + polygons._batchIds = undefined; + polygons._positions = undefined; + polygons._counts = undefined; + polygons._indices = undefined; + polygons._indexCounts = undefined; + polygons._indexOffsets = undefined; + polygons._batchTableColors = undefined; + polygons._packedBuffer = undefined; + polygons._batchedPositions = undefined; + polygons._transferrableBatchIds = undefined; + polygons._vertexBatchIds = undefined; + polygons._ellipsoid = undefined; + polygons._minimumHeight = undefined; + polygons._maximumHeight = undefined; + polygons._polygonMinimumHeights = undefined; + polygons._polygonMaximumHeights = undefined; + polygons._center = undefined; + polygons._rectangle = undefined; + polygons._boundingVolume = undefined; + polygons._boundingVolumes = undefined; + polygons._batchedIndices = undefined; + polygons._verticesPromise = undefined; + + polygons._readyPromise.resolve(); + } + } /** - * Switches the frustum/projection to perspective. + * Creates features for each polygon and places it at the batch id index of features. * - * This function is a no-op in 2D which must always be orthographic. + * @param {Vector3DTileContent} content The vector tile content. + * @param {Cesium3DTileFeature[]} features An array of features where the polygon features will be placed. */ - Camera.prototype.switchToPerspectiveFrustum = function() { - if (this._mode === SceneMode.SCENE2D || this.frustum instanceof PerspectiveFrustum) { - return; - } - - var scene = this._scene; - this.frustum = new PerspectiveFrustum(); - this.frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - this.frustum.fov = CesiumMath.toRadians(60.0); + Vector3DTilePolygons.prototype.createFeatures = function(content, features) { + this._primitive.createFeatures(content, features); }; /** - * Switches the frustum/projection to orthographic. + * Colors the entire tile when enabled is true. The resulting color will be (polygon batch table color * color). * - * This function is a no-op in 2D which will always be orthographic. + * @param {Boolean} enabled Whether to enable debug coloring. + * @param {Color} color The debug color. */ - Camera.prototype.switchToOrthographicFrustum = function() { - if (this._mode === SceneMode.SCENE2D || this.frustum instanceof OrthographicFrustum) { - return; - } - - var scene = this._scene; - this.frustum = new OrthographicFrustum(); - this.frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + Vector3DTilePolygons.prototype.applyDebugSettings = function(enabled, color) { + this._primitive.applyDebugSettings(enabled, color); + }; - // It doesn't matter what we set this to. The adjust below will correct the width based on the camera position. - this.frustum.width = Cartesian3.magnitude(this.position); + /** + * Apply a style to the content. + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileStyle} style The style. + * @param {Cesium3DTileFeature[]} features The array of features. + */ + Vector3DTilePolygons.prototype.applyStyle = function(frameState, style, features) { + this._primitive.applyStyle(frameState, style, features); + }; - // Check the projection matrix. It will always be defined, but we need to force an off-center update. - var projectionMatrix = this.frustum.projectionMatrix; - if (defined(projectionMatrix)) { - this._adjustOrthographicFrustum(true); - } + /** + * Call when updating the color of a polygon with batchId changes color. The polygons will need to be re-batched + * on the next update. + * + * @param {Number} batchId The batch id of the polygon whose color has changed. + * @param {Color} color The new polygon color. + */ + Vector3DTilePolygons.prototype.updateCommands = function(batchId, color) { + this._primitive.updateCommands(batchId, color); }; /** - * @private + * Updates the batches and queues the commands for rendering. + * + * @param {FrameState} frameState The current frame state. */ - Camera.clone = function(camera, result) { - if (!defined(result)) { - result = new Camera(camera._scene); - } + Vector3DTilePolygons.prototype.update = function(frameState) { + createPrimitive(this); - Cartesian3.clone(camera.position, result.position); - Cartesian3.clone(camera.direction, result.direction); - Cartesian3.clone(camera.up, result.up); - Cartesian3.clone(camera.right, result.right); - Matrix4.clone(camera._transform, result.transform); - result._transformChanged = true; + if (!this._ready) { + return; + } - return result; + this._primitive.debugWireframe = this.debugWireframe; + this._primitive.forceRebatch = this.forceRebatch; + this._primitive.classificationType = this.classificationType; + this._primitive.update(frameState); }; /** - * A function that will execute when a flight completes. - * @callback Camera~FlightCompleteCallback + * Returns true if this object was destroyed; otherwise, false. + * <p> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ + Vector3DTilePolygons.prototype.isDestroyed = function() { + return false; + }; /** - * A function that will execute when a flight is cancelled. - * @callback Camera~FlightCancelledCallback + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ + Vector3DTilePolygons.prototype.destroy = function() { + this._primitive = this._primitive && this._primitive.destroy(); + return destroyObject(this); + }; - return Camera; + return Vector3DTilePolygons; }); -define('Scene/CameraEventType',[ - '../Core/freezeObject' +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/Vector3DTilePolylinesVS',[],function() { + 'use strict'; + return "attribute vec4 currentPosition;\n\ +attribute vec4 previousPosition;\n\ +attribute vec4 nextPosition;\n\ +attribute vec2 expandAndWidth;\n\ +attribute float a_batchId;\n\ +uniform mat4 u_modifiedModelView;\n\ +void main()\n\ +{\n\ +float expandDir = expandAndWidth.x;\n\ +float width = abs(expandAndWidth.y) + 0.5;\n\ +bool usePrev = expandAndWidth.y < 0.0;\n\ +vec4 p = u_modifiedModelView * currentPosition;\n\ +vec4 prev = u_modifiedModelView * previousPosition;\n\ +vec4 next = u_modifiedModelView * nextPosition;\n\ +float angle;\n\ +vec4 positionWC = getPolylineWindowCoordinatesEC(p, prev, next, expandDir, width, usePrev, angle);\n\ +gl_Position = czm_viewportOrthographic * positionWC;\n\ +}\n\ +"; +}); +define('Scene/Vector3DTilePolylines',[ + '../Core/arraySlice', + '../Core/Cartesian3', + '../Core/Color', + '../Core/ComponentDatatype', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/Ellipsoid', + '../Core/IndexDatatype', + '../Core/Matrix4', + '../Core/Rectangle', + '../Core/TaskProcessor', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArray', + '../Shaders/PolylineCommon', + '../Shaders/Vector3DTilePolylinesVS', + '../ThirdParty/when', + './BlendingState', + './Cesium3DTileFeature' ], function( - freezeObject) { + arraySlice, + Cartesian3, + Color, + ComponentDatatype, + defaultValue, + defined, + defineProperties, + destroyObject, + Ellipsoid, + IndexDatatype, + Matrix4, + Rectangle, + TaskProcessor, + Buffer, + BufferUsage, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + VertexArray, + PolylineCommon, + Vector3DTilePolylinesVS, + when, + BlendingState, + Cesium3DTileFeature) { 'use strict'; /** - * Enumerates the available input for interacting with the camera. + * Creates a batch of polylines that have been subdivided to be draped on terrain. * - * @exports CameraEventType + * @alias Vector3DTilePolylines + * @constructor + * + * @param {Object} options An object with following properties: + * @param {Uint16Array} options.positions The positions of the polylines + * @param {Uint32Array} options.counts The number or positions in the each polyline. + * @param {Uint16Array} options.widths The width of each polyline. + * @param {Number} options.minimumHeight The minimum height of the terrain covered by the tile. + * @param {Number} options.maximumHeight The maximum height of the terrain covered by the tile. + * @param {Rectangle} options.rectangle The rectangle containing the tile. + * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center. + * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polylines. + * @param {Uint16Array} options.batchIds The batch ids for each polyline. + * @param {BoundingSphere} options.boundingVolume The bounding volume for the entire batch of polylines. + * + * @private */ - var CameraEventType = { - /** - * A left mouse button press followed by moving the mouse and releasing the button. - * - * @type {Number} - * @constant - */ - LEFT_DRAG : 0, + function Vector3DTilePolylines(options) { + // these arrays are all released after the first update. + this._positions = options.positions; + this._widths = options.widths; + this._counts = options.counts; + this._batchIds = options.batchIds; - /** - * A right mouse button press followed by moving the mouse and releasing the button. - * - * @type {Number} - * @constant - */ - RIGHT_DRAG : 1, + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._minimumHeight = options.minimumHeight; + this._maximumHeight = options.maximumHeight; + this._center = options.center; + this._rectangle = options.rectangle; + + this._boundingVolume = options.boundingVolume; + this._batchTable = options.batchTable; + + this._va = undefined; + this._sp = undefined; + this._rs = undefined; + this._uniformMap = undefined; + this._command = undefined; + + this._spPick = undefined; + this._rsPick = undefined; + this._pickCommand = undefined; + + this._transferrableBatchIds = undefined; + this._packedBuffer = undefined; + + this._currentPositions = undefined; + this._previousPositions = undefined; + this._nextPositions = undefined; + this._expandAndWidth = undefined; + this._vertexBatchIds = undefined; + this._indices = undefined; + + this._constantColor = Color.clone(Color.WHITE); + this._highlightColor = this._constantColor; + + this._trianglesLength = 0; + this._geometryByteLength = 0; + this._ready = false; + this._readyPromise = when.defer(); + + this._verticesPromise = undefined; + } + + defineProperties(Vector3DTilePolylines.prototype, { /** - * A middle mouse button press followed by moving the mouse and releasing the button. + * Gets the number of triangles. + * + * @memberof Vector3DTilePolylines.prototype * * @type {Number} - * @constant + * @readonly */ - MIDDLE_DRAG : 2, + trianglesLength : { + get : function() { + return this._trianglesLength; + } + }, /** - * Scrolling the middle mouse button. + * Gets the geometry memory in bytes. + * + * @memberof Vector3DTilePolylines.prototype * * @type {Number} - * @constant + * @readonly */ - WHEEL : 3, + geometryByteLength : { + get : function() { + return this._geometryByteLength; + } + }, /** - * A two-finger touch on a touch surface. - * - * @type {Number} - * @constant + * Gets a promise that resolves when the primitive is ready to render. + * @memberof Vector3DTilePolylines.prototype + * @type {Promise} + * @readonly */ - PINCH : 4 - }; + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + } + }); - return freezeObject(CameraEventType); -}); + function packBuffer(polylines) { + var rectangle = polylines._rectangle; + var minimumHeight = polylines._minimumHeight; + var maximumHeight = polylines._maximumHeight; + var ellipsoid = polylines._ellipsoid; + var center = polylines._center; -define('Scene/CameraEventAggregator',[ - '../Core/Cartesian2', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/KeyboardEventModifier', - '../Core/Math', - '../Core/ScreenSpaceEventHandler', - '../Core/ScreenSpaceEventType', - './CameraEventType' - ], function( - Cartesian2, - defined, - defineProperties, - destroyObject, - DeveloperError, - KeyboardEventModifier, - CesiumMath, - ScreenSpaceEventHandler, - ScreenSpaceEventType, - CameraEventType) { - 'use strict'; + var packedLength = 2 + Rectangle.packedLength + Ellipsoid.packedLength + Cartesian3.packedLength; + var packedBuffer = new Float64Array(packedLength); - function getKey(type, modifier) { - var key = type; - if (defined(modifier)) { - key += '+' + modifier; - } - return key; - } + var offset = 0; + packedBuffer[offset++] = minimumHeight; + packedBuffer[offset++] = maximumHeight; - function clonePinchMovement(pinchMovement, result) { - Cartesian2.clone(pinchMovement.distance.startPosition, result.distance.startPosition); - Cartesian2.clone(pinchMovement.distance.endPosition, result.distance.endPosition); + Rectangle.pack(rectangle, packedBuffer, offset); + offset += Rectangle.packedLength; - Cartesian2.clone(pinchMovement.angleAndHeight.startPosition, result.angleAndHeight.startPosition); - Cartesian2.clone(pinchMovement.angleAndHeight.endPosition, result.angleAndHeight.endPosition); - } + Ellipsoid.pack(ellipsoid, packedBuffer, offset); + offset += Ellipsoid.packedLength; - function listenToPinch(aggregator, modifier, canvas) { - var key = getKey(CameraEventType.PINCH, modifier); + Cartesian3.pack(center, packedBuffer, offset); - var update = aggregator._update; - var isDown = aggregator._isDown; - var eventStartPosition = aggregator._eventStartPosition; - var pressTime = aggregator._pressTime; - var releaseTime = aggregator._releaseTime; + return packedBuffer; + } - update[key] = true; - isDown[key] = false; - eventStartPosition[key] = new Cartesian2(); + var createVerticesTaskProcessor = new TaskProcessor('createVectorTilePolylines'); + var attributeLocations = { + previousPosition : 0, + currentPosition : 1, + nextPosition : 2, + expandAndWidth : 3, + a_batchId : 4 + }; - var movement = aggregator._movement[key]; - if (!defined(movement)) { - movement = aggregator._movement[key] = {}; + function createVertexArray(polylines, context) { + if (defined(polylines._va)) { + return; } - movement.distance = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - }; - movement.angleAndHeight = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - }; - movement.prevAngle = 0.0; + if (!defined(polylines._verticesPromise)) { + var positions = polylines._positions; + var widths = polylines._widths; + var counts = polylines._counts; + var batchIds = polylines._transferrableBatchIds; - aggregator._eventHandler.setInputAction(function(event) { - aggregator._buttonsDown++; - isDown[key] = true; - pressTime[key] = new Date(); - // Compute center position and store as start point. - Cartesian2.lerp(event.position1, event.position2, 0.5, eventStartPosition[key]); - }, ScreenSpaceEventType.PINCH_START, modifier); + var packedBuffer = polylines._packedBuffer; - aggregator._eventHandler.setInputAction(function() { - aggregator._buttonsDown = Math.max(aggregator._buttonsDown - 1, 0); - isDown[key] = false; - releaseTime[key] = new Date(); - }, ScreenSpaceEventType.PINCH_END, modifier); + if (!defined(packedBuffer)) { + // Copy because they may be the views on the same buffer. + positions = polylines._positions = arraySlice(positions); + widths = polylines._widths = arraySlice(widths); + counts = polylines._counts = arraySlice(counts); - aggregator._eventHandler.setInputAction(function(mouseMovement) { - if (isDown[key]) { - // Aggregate several input events into a single animation frame. - if (!update[key]) { - Cartesian2.clone(mouseMovement.distance.endPosition, movement.distance.endPosition); - Cartesian2.clone(mouseMovement.angleAndHeight.endPosition, movement.angleAndHeight.endPosition); - } else { - clonePinchMovement(mouseMovement, movement); - update[key] = false; - movement.prevAngle = movement.angleAndHeight.startPosition.x; - } - // Make sure our aggregation of angles does not "flip" over 360 degrees. - var angle = movement.angleAndHeight.endPosition.x; - var prevAngle = movement.prevAngle; - var TwoPI = Math.PI * 2; - while (angle >= (prevAngle + Math.PI)) { - angle -= TwoPI; - } - while (angle < (prevAngle - Math.PI)) { - angle += TwoPI; - } - movement.angleAndHeight.endPosition.x = -angle * canvas.clientWidth / 12; - movement.angleAndHeight.startPosition.x = -prevAngle * canvas.clientWidth / 12; + batchIds = polylines._transferrableBatchIds = arraySlice(polylines._batchIds); + + packedBuffer = polylines._packedBuffer = packBuffer(polylines); } - }, ScreenSpaceEventType.PINCH_MOVE, modifier); - } - function listenToWheel(aggregator, modifier) { - var key = getKey(CameraEventType.WHEEL, modifier); + var transferrableObjects = [positions.buffer, widths.buffer, counts.buffer, batchIds.buffer, packedBuffer.buffer]; + var parameters = { + positions : positions.buffer, + widths : widths.buffer, + counts : counts.buffer, + batchIds : batchIds.buffer, + packedBuffer : packedBuffer.buffer + }; - var update = aggregator._update; - update[key] = true; + var verticesPromise = polylines._verticesPromise = createVerticesTaskProcessor.scheduleTask(parameters, transferrableObjects); + if (!defined(verticesPromise)) { + // Postponed + return; + } - var movement = aggregator._movement[key]; - if (!defined(movement)) { - movement = aggregator._movement[key] = {}; + when(verticesPromise, function(result) { + polylines._currentPositions = new Float32Array(result.currentPositions); + polylines._previousPositions = new Float32Array(result.previousPositions); + polylines._nextPositions = new Float32Array(result.nextPositions); + polylines._expandAndWidth = new Float32Array(result.expandAndWidth); + polylines._vertexBatchIds = new Uint16Array(result.batchIds); + + var indexDatatype = result.indexDatatype; + polylines._indices = indexDatatype === IndexDatatype.UNSIGNED_SHORT ? new Uint16Array(result.indices) : new Uint32Array(result.indices); + + polylines._ready = true; + }); } - movement.startPosition = new Cartesian2(); - movement.endPosition = new Cartesian2(); + if (polylines._ready && !defined(polylines._va)) { + var curPositions = polylines._currentPositions; + var prevPositions = polylines._previousPositions; + var nextPositions = polylines._nextPositions; + var expandAndWidth = polylines._expandAndWidth; + var vertexBatchIds = polylines._vertexBatchIds; + var indices = polylines._indices; - aggregator._eventHandler.setInputAction(function(delta) { - // TODO: magic numbers - var arcLength = 15.0 * CesiumMath.toRadians(delta); - if (!update[key]) { - movement.endPosition.y = movement.endPosition.y + arcLength; - } else { - Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); - movement.endPosition.x = 0.0; - movement.endPosition.y = arcLength; - update[key] = false; - } - }, ScreenSpaceEventType.WHEEL, modifier); - } + var byteLength = prevPositions.byteLength + curPositions.byteLength + nextPositions.byteLength; + byteLength += expandAndWidth.byteLength + vertexBatchIds.byteLength + indices.byteLength; + polylines._trianglesLength = indices.length / 3; + polylines._geometryByteLength = byteLength; - function listenMouseButtonDownUp(aggregator, modifier, type) { - var key = getKey(type, modifier); + var prevPositionBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : prevPositions, + usage : BufferUsage.STATIC_DRAW + }); + var curPositionBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : curPositions, + usage : BufferUsage.STATIC_DRAW + }); + var nextPositionBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : nextPositions, + usage : BufferUsage.STATIC_DRAW + }); + var expandAndWidthBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : expandAndWidth, + usage : BufferUsage.STATIC_DRAW + }); + var idBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : vertexBatchIds, + usage : BufferUsage.STATIC_DRAW + }); - var isDown = aggregator._isDown; - var eventStartPosition = aggregator._eventStartPosition; - var pressTime = aggregator._pressTime; - var releaseTime = aggregator._releaseTime; + var indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : indices, + usage : BufferUsage.STATIC_DRAW, + indexDatatype : (indices.BYTES_PER_ELEMENT === 2) ? IndexDatatype.UNSIGNED_SHORT : IndexDatatype.UNSIGNED_INT + }); - isDown[key] = false; - eventStartPosition[key] = new Cartesian2(); + var vertexAttributes = [{ + index : attributeLocations.previousPosition, + vertexBuffer : prevPositionBuffer, + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + }, { + index : attributeLocations.currentPosition, + vertexBuffer : curPositionBuffer, + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + }, { + index : attributeLocations.nextPosition, + vertexBuffer : nextPositionBuffer, + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3 + }, { + index : attributeLocations.expandAndWidth, + vertexBuffer : expandAndWidthBuffer, + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2 + }, { + index : attributeLocations.a_batchId, + vertexBuffer : idBuffer, + componentDatatype : ComponentDatatype.UNSIGNED_SHORT, + componentsPerAttribute : 1 + }]; - var lastMovement = aggregator._lastMovement[key]; - if (!defined(lastMovement)) { - lastMovement = aggregator._lastMovement[key] = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2(), - valid : false - }; - } + polylines._va = new VertexArray({ + context : context, + attributes : vertexAttributes, + indexBuffer : indexBuffer + }); - var down; - var up; - if (type === CameraEventType.LEFT_DRAG) { - down = ScreenSpaceEventType.LEFT_DOWN; - up = ScreenSpaceEventType.LEFT_UP; - } else if (type === CameraEventType.RIGHT_DRAG) { - down = ScreenSpaceEventType.RIGHT_DOWN; - up = ScreenSpaceEventType.RIGHT_UP; - } else if (type === CameraEventType.MIDDLE_DRAG) { - down = ScreenSpaceEventType.MIDDLE_DOWN; - up = ScreenSpaceEventType.MIDDLE_UP; - } + polylines._positions = undefined; + polylines._widths = undefined; + polylines._counts = undefined; - aggregator._eventHandler.setInputAction(function(event) { - aggregator._buttonsDown++; - lastMovement.valid = false; - isDown[key] = true; - pressTime[key] = new Date(); - Cartesian2.clone(event.position, eventStartPosition[key]); - }, down, modifier); + polylines._ellipsoid = undefined; + polylines._minimumHeight = undefined; + polylines._maximumHeight = undefined; + polylines._rectangle = undefined; - aggregator._eventHandler.setInputAction(function() { - aggregator._buttonsDown = Math.max(aggregator._buttonsDown - 1, 0); - isDown[key] = false; - releaseTime[key] = new Date(); - }, up, modifier); - } + polylines._transferrableBatchIds = undefined; + polylines._packedBuffer = undefined; - function cloneMouseMovement(mouseMovement, result) { - Cartesian2.clone(mouseMovement.startPosition, result.startPosition); - Cartesian2.clone(mouseMovement.endPosition, result.endPosition); - } + polylines._currentPositions = undefined; + polylines._previousPositions = undefined; + polylines._nextPositions = undefined; + polylines._expandAndWidth = undefined; + polylines._vertexBatchIds = undefined; + polylines._indices = undefined; - function listenMouseMove(aggregator, modifier) { - var update = aggregator._update; - var movement = aggregator._movement; - var lastMovement = aggregator._lastMovement; - var isDown = aggregator._isDown; + polylines._readyPromise.resolve(); + } + } - for ( var typeName in CameraEventType) { - if (CameraEventType.hasOwnProperty(typeName)) { - var type = CameraEventType[typeName]; - if (defined(type)) { - var key = getKey(type, modifier); - update[key] = true; + var modifiedModelViewScratch = new Matrix4(); + var rtcScratch = new Cartesian3(); - if (!defined(aggregator._lastMovement[key])) { - aggregator._lastMovement[key] = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2(), - valid : false - }; - } + function createUniformMap(primitive, context) { + if (defined(primitive._uniformMap)) { + return; + } - if (!defined(aggregator._movement[key])) { - aggregator._movement[key] = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2() - }; - } - } + primitive._uniformMap = { + u_modifiedModelView : function() { + var viewMatrix = context.uniformState.view; + Matrix4.clone(viewMatrix, modifiedModelViewScratch); + Matrix4.multiplyByPoint(modifiedModelViewScratch, primitive._center, rtcScratch); + Matrix4.setTranslation(modifiedModelViewScratch, rtcScratch, modifiedModelViewScratch); + return modifiedModelViewScratch; + }, + u_highlightColor : function() { + return primitive._highlightColor; } + }; + } + + function createRenderStates(primitive) { + if (defined(primitive._rs)) { + return; } - aggregator._eventHandler.setInputAction(function(mouseMovement) { - for ( var typeName in CameraEventType) { - if (CameraEventType.hasOwnProperty(typeName)) { - var type = CameraEventType[typeName]; - if (defined(type)) { - var key = getKey(type, modifier); - if (isDown[key]) { - if (!update[key]) { - Cartesian2.clone(mouseMovement.endPosition, movement[key].endPosition); - } else { - cloneMouseMovement(movement[key], lastMovement[key]); - lastMovement[key].valid = true; - cloneMouseMovement(mouseMovement, movement[key]); - update[key] = false; - } - } - } - } - } + var polygonOffset = { + enabled : true, + factor : -5.0, + units : -5.0 + }; - Cartesian2.clone(mouseMovement.endPosition, aggregator._currentMousePosition); - }, ScreenSpaceEventType.MOUSE_MOVE, modifier); + primitive._rs = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND, + depthMask : false, + depthTest : { + enabled : true + }, + polygonOffset : polygonOffset + }); + + primitive._rsPick = RenderState.fromCache({ + depthMask : false, + depthTest : { + enabled : true + }, + polygonOffset : polygonOffset + }); } - /** - * Aggregates input events. For example, suppose the following inputs are received between frames: - * left mouse button down, mouse move, mouse move, left mouse button up. These events will be aggregated into - * one event with a start and end position of the mouse. - * - * @alias CameraEventAggregator - * @constructor - * - * @param {Canvas} [canvas=document] The element to handle events for. - * - * @see ScreenSpaceEventHandler - */ - function CameraEventAggregator(canvas) { - if (!defined(canvas)) { - throw new DeveloperError('canvas is required.'); + var PolylineFS = + 'uniform vec4 u_highlightColor; \n' + + 'void main()\n' + + '{\n' + + ' gl_FragColor = u_highlightColor;\n' + + '}\n'; + + function createShaders(primitive, context) { + if (defined(primitive._sp)) { + return; } - - this._eventHandler = new ScreenSpaceEventHandler(canvas, true); - this._update = {}; - this._movement = {}; - this._lastMovement = {}; - this._isDown = {}; - this._eventStartPosition = {}; - this._pressTime = {}; - this._releaseTime = {}; + var batchTable = primitive._batchTable; - this._buttonsDown = 0; + var vsSource = batchTable.getVertexShaderCallback(false, 'a_batchId', undefined)(Vector3DTilePolylinesVS); + var fsSource = batchTable.getFragmentShaderCallback()(PolylineFS, false, undefined); - this._currentMousePosition = new Cartesian2(); + var vs = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [PolylineCommon, vsSource] + }); + var fs = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [fsSource] + }); - listenToWheel(this, undefined); - listenToPinch(this, undefined, canvas); - listenMouseButtonDownUp(this, undefined, CameraEventType.LEFT_DRAG); - listenMouseButtonDownUp(this, undefined, CameraEventType.RIGHT_DRAG); - listenMouseButtonDownUp(this, undefined, CameraEventType.MIDDLE_DRAG); - listenMouseMove(this, undefined); + primitive._sp = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); - for ( var modifierName in KeyboardEventModifier) { - if (KeyboardEventModifier.hasOwnProperty(modifierName)) { - var modifier = KeyboardEventModifier[modifierName]; - if (defined(modifier)) { - listenToWheel(this, modifier); - listenToPinch(this, modifier, canvas); - listenMouseButtonDownUp(this, modifier, CameraEventType.LEFT_DRAG); - listenMouseButtonDownUp(this, modifier, CameraEventType.RIGHT_DRAG); - listenMouseButtonDownUp(this, modifier, CameraEventType.MIDDLE_DRAG); - listenMouseMove(this, modifier); - } - } - } + vsSource = batchTable.getPickVertexShaderCallback('a_batchId')(Vector3DTilePolylinesVS); + fsSource = batchTable.getPickFragmentShaderCallback()(PolylineFS, false, undefined); + + var pickVS = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [PolylineCommon, vsSource] + }); + var pickFS = new ShaderSource({ + defines : ['VECTOR_TILE'], + sources : [fsSource] + }); + primitive._spPick = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : pickVS, + fragmentShaderSource : pickFS, + attributeLocations : attributeLocations + }); } - defineProperties(CameraEventAggregator.prototype, { - /** - * Gets the current mouse position. - * @memberof CameraEventAggregator.prototype - * @type {Cartesian2} - */ - currentMousePosition : { - get : function() { - return this._currentMousePosition; - } - }, + function queueCommands(primitive, frameState) { + if (!defined(primitive._command)) { + var uniformMap = primitive._batchTable.getUniformMapCallback()(primitive._uniformMap); + primitive._command = new DrawCommand({ + owner : primitive, + vertexArray : primitive._va, + renderState : primitive._rs, + shaderProgram : primitive._sp, + uniformMap : uniformMap, + boundingVolume : primitive._boundingVolume, + pass : Pass.TRANSLUCENT + }); + } - /** - * Gets whether any mouse button is down, a touch has started, or the wheel has been moved. - * @memberof CameraEventAggregator.prototype - * @type {Boolean} - */ - anyButtonDown : { - get : function() { - var wheelMoved = !this._update[getKey(CameraEventType.WHEEL)] || - !this._update[getKey(CameraEventType.WHEEL, KeyboardEventModifier.SHIFT)] || - !this._update[getKey(CameraEventType.WHEEL, KeyboardEventModifier.CTRL)] || - !this._update[getKey(CameraEventType.WHEEL, KeyboardEventModifier.ALT)]; - return this._buttonsDown > 0 || wheelMoved; - } + frameState.commandList.push(primitive._command); + } + + function queuePickCommands(primitive, frameState) { + if (!defined(primitive._pickCommand)) { + var uniformMap = primitive._batchTable.getPickUniformMapCallback()(primitive._uniformMap); + primitive._pickCommand = new DrawCommand({ + owner : primitive, + vertexArray : primitive._va, + renderState : primitive._rsPick, + shaderProgram : primitive._spPick, + uniformMap : uniformMap, + boundingVolume : primitive._boundingVolume, + pass : Pass.TRANSLUCENT + }); } - }); + + frameState.commandList.push(primitive._pickCommand); + } /** - * Gets if a mouse button down or touch has started and has been moved. + * Creates features for each polyline and places it at the batch id index of features. * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Boolean} Returns <code>true</code> if a mouse button down or touch has started and has been moved; otherwise, <code>false</code> + * @param {Vector3DTileContent} content The vector tile content. + * @param {Cesium3DTileFeature[]} features An array of features where the polygon features will be placed. */ - CameraEventAggregator.prototype.isMoving = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); + Vector3DTilePolylines.prototype.createFeatures = function(content, features) { + var batchIds = this._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; + features[batchId] = new Cesium3DTileFeature(content, batchId); } - - var key = getKey(type, modifier); - return !this._update[key]; }; /** - * Gets the aggregated start and end position of the current event. + * Colors the entire tile when enabled is true. The resulting color will be (polyline batch table color * color). * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Object} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code>. + * @param {Boolean} enabled Whether to enable debug coloring. + * @param {Color} color The debug color. */ - CameraEventAggregator.prototype.getMovement = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - var key = getKey(type, modifier); - var movement = this._movement[key]; - return movement; + Vector3DTilePolylines.prototype.applyDebugSettings = function(enabled, color) { + this._highlightColor = enabled ? color : this._constantColor; }; - /** - * Gets the start and end position of the last move event (not the aggregated event). - * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Object|undefined} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code> or <code>undefined</code>. - */ - CameraEventAggregator.prototype.getLastMovement = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - var key = getKey(type, modifier); - var lastMovement = this._lastMovement[key]; - if (lastMovement.valid) { - return lastMovement; + function clearStyle(polygons, features) { + var batchIds = polygons._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; + var feature = features[batchId]; + + feature.show = true; + feature.color = Color.WHITE; } + } - return undefined; - }; + var scratchColor = new Color(); - /** - * Gets whether the mouse button is down or a touch has started. - * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Boolean} Whether the mouse button is down or a touch has started. - */ - CameraEventAggregator.prototype.isButtonDown = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - var key = getKey(type, modifier); - return this._isDown[key]; - }; + var DEFAULT_COLOR_VALUE = Color.WHITE; + var DEFAULT_SHOW_VALUE = true; /** - * Gets the mouse position that started the aggregation. + * Apply a style to the content. * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Cartesian2} The mouse position. + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileStyle} style The style. + * @param {Cesium3DTileFeature[]} features The array of features. */ - CameraEventAggregator.prototype.getStartMousePosition = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - if (type === CameraEventType.WHEEL) { - return this._currentMousePosition; + Vector3DTilePolylines.prototype.applyStyle = function(frameState, style, features) { + if (!defined(style)) { + clearStyle(this, features); + return; } - var key = getKey(type, modifier); - return this._eventStartPosition[key]; - }; + var batchIds = this._batchIds; + var length = batchIds.length; + for (var i = 0; i < length; ++i) { + var batchId = batchIds[i]; + var feature = features[batchId]; - /** - * Gets the time the button was pressed or the touch was started. - * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Date} The time the button was pressed or the touch was started. - */ - CameraEventAggregator.prototype.getButtonPressTime = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); + feature.color = defined(style.color) ? style.color.evaluateColor(frameState, feature, scratchColor) : DEFAULT_COLOR_VALUE; + feature.show = defined(style.show) ? style.show.evaluate(frameState, feature) : DEFAULT_SHOW_VALUE; } - - var key = getKey(type, modifier); - return this._pressTime[key]; }; /** - * Gets the time the button was released or the touch was ended. + * Updates the batches and queues the commands for rendering. * - * @param {CameraEventType} type The camera event type. - * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Date} The time the button was released or the touch was ended. + * @param {FrameState} frameState The current frame state. */ - CameraEventAggregator.prototype.getButtonReleaseTime = function(type, modifier) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); + Vector3DTilePolylines.prototype.update = function(frameState) { + var context = frameState.context; + + createVertexArray(this, context); + createUniformMap(this, context); + createShaders(this, context); + createRenderStates(this); + + if (!this._ready) { + return; } - - var key = getKey(type, modifier); - return this._releaseTime[key]; - }; - /** - * Signals that all of the events have been handled and the aggregator should be reset to handle new events. - */ - CameraEventAggregator.prototype.reset = function() { - for ( var name in this._update) { - if (this._update.hasOwnProperty(name)) { - this._update[name] = true; - } + var passes = frameState.passes; + if (passes.render) { + queueCommands(this, frameState); + } + + if (passes.pick) { + queuePickCommands(this, frameState); } }; /** * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> + * <p> * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * </p> * * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see CameraEventAggregator#destroy */ - CameraEventAggregator.prototype.isDestroyed = function() { + Vector3DTilePolylines.prototype.isDestroyed = function() { return false; }; /** - * Removes mouse listeners held by this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * handler = handler && handler.destroy(); - * - * @see CameraEventAggregator#isDestroyed - */ - CameraEventAggregator.prototype.destroy = function() { - this._eventHandler = this._eventHandler && this._eventHandler.destroy(); - return destroyObject(this); - }; - - return CameraEventAggregator; -}); - -define('Scene/Cesium3DTileChildrenVisibility',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; - - /** - * @private + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <p> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * </p> + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ - var Cesium3DTileChildrenVisibility = { - NONE : 0, // No children visible - VISIBLE : 1, // At least one child visible - IN_REQUEST_VOLUME : 2, // At least one child in viewer request volume - VISIBLE_IN_REQUEST_VOLUME : 4, // At least one child both visible and in viewer request volume - VISIBLE_NOT_IN_REQUEST_VOLUME : 8 // At least one child visible but not in viewer request volume + Vector3DTilePolylines.prototype.destroy = function() { + this._va = this._va && this._va.destroy(); + this._sp = this._sp && this._sp.destroy(); + this._spPick = this._spPick && this._spPick.destroy(); + return destroyObject(this); }; - return freezeObject(Cesium3DTileChildrenVisibility); + return Vector3DTilePolylines; }); -define('Scene/Composite3DTileContent',[ +define('Scene/Vector3DTileContent',[ + '../Core/Cartesian3', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Ellipsoid', '../Core/FeatureDetection', '../Core/getMagic', + '../Core/getStringFromTypedArray', + '../Core/Math', + '../Core/Matrix4', + '../Core/Rectangle', '../Core/RuntimeError', - '../ThirdParty/when' + '../ThirdParty/when', + './Cesium3DTileBatchTable', + './Vector3DTilePoints', + './Vector3DTilePolygons', + './Vector3DTilePolylines' ], function( + Cartesian3, defaultValue, defined, defineProperties, destroyObject, + DeveloperError, + Ellipsoid, FeatureDetection, getMagic, + getStringFromTypedArray, + CesiumMath, + Matrix4, + Rectangle, RuntimeError, - when) { + when, + Cesium3DTileBatchTable, + Vector3DTilePoints, + Vector3DTilePolygons, + Vector3DTilePolylines) { 'use strict'; // Bail out if the browser doesn't support typed arrays, to prevent the setup function @@ -172608,109 +186546,112 @@ define('Scene/Composite3DTileContent',[ /** * Represents the contents of a - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Composite/README.md|Composite} + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/3d-tiles-next/TileFormats/VectorData|Vector} * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> * - * @alias Composite3DTileContent + * @alias Vector3DTileContent * @constructor * * @private */ - function Composite3DTileContent(tileset, tile, url, arrayBuffer, byteOffset, factory) { + function Vector3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { this._tileset = tileset; this._tile = tile; - this._url = url; - this._contents = []; + this._resource = resource; + + this._polygons = undefined; + this._polylines = undefined; + this._points = undefined; + + this._contentReadyPromise = undefined; this._readyPromise = when.defer(); - initialize(this, arrayBuffer, byteOffset, factory); - } + this._batchTable = undefined; + this._features = undefined; - defineProperties(Composite3DTileContent.prototype, { /** - * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + * Part of the {@link Cesium3DTileContent} interface. */ - featurePropertiesDirty : { - get : function() { - var contents = this._contents; - var length = contents.length; - for (var i = 0; i < length; ++i) { - if (contents[i].featurePropertiesDirty) { - return true; - } - } + this.featurePropertiesDirty = false; - return false; - }, - set : function(value) { - var contents = this._contents; - var length = contents.length; - for (var i = 0; i < length; ++i) { - contents[i].featurePropertiesDirty = value; - } - } - }, + initialize(this, arrayBuffer, byteOffset); + } + defineProperties(Vector3DTileContent.prototype, { /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>0</code>. Instead call <code>featuresLength</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#featuresLength */ featuresLength : { get : function() { - return 0; + return defined(this._batchTable) ? this._batchTable.featuresLength : 0; } }, /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>0</code>. Instead call <code>pointsLength</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#pointsLength */ pointsLength : { get : function() { + if (defined(this._points)) { + return this._points.pointsLength; + } return 0; } }, /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>0</code>. Instead call <code>trianglesLength</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#trianglesLength */ trianglesLength : { get : function() { - return 0; + var trianglesLength = 0; + if (defined(this._polygons)) { + trianglesLength += this._polygons.trianglesLength; + } + if (defined(this._polylines)) { + trianglesLength += this._polylines.trianglesLength; + } + return trianglesLength; } }, /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>0</code>. Instead call <code>geometryByteLength</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#geometryByteLength */ geometryByteLength : { get : function() { - return 0; + var geometryByteLength = 0; + if (defined(this._polygons)) { + geometryByteLength += this._polygons.geometryByteLength; + } + if (defined(this._polylines)) { + geometryByteLength += this._polylines.geometryByteLength; + } + return geometryByteLength; } }, /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>0</code>. Instead call <code>texturesByteLength</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#texturesByteLength */ texturesByteLength : { get : function() { + if (defined(this._points)) { + return this._points.texturesByteLength; + } return 0; } }, /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>0</code>. Instead call <code>batchTableByteLength</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#batchTableByteLength */ batchTableByteLength : { get : function() { - return 0; + return defined(this._batchTable) ? this._batchTable.memorySizeInBytes : 0; } }, @@ -172719,7 +186660,7 @@ define('Scene/Composite3DTileContent',[ */ innerContents : { get : function() { - return this._contents; + return undefined; } }, @@ -172755,12126 +186696,11958 @@ define('Scene/Composite3DTileContent',[ */ url : { get : function() { - return this._url; + return this._resource.getUrlComponent(true); } }, /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>undefined</code>. Instead call <code>batchTable</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#batchTable */ batchTable : { get : function() { - return undefined; + return this._batchTable; } } }); + function createColorChangedCallback(content) { + return function(batchId, color) { + if (defined(content._polygons)) { + content._polygons.updateCommands(batchId, color); + } + }; + } + + function getBatchIds(featureTableJson, featureTableBinary) { + var polygonBatchIds; + var polylineBatchIds; + var pointBatchIds; + var i; + + var numberOfPolygons = defaultValue(featureTableJson.POLYGONS_LENGTH, 0); + var numberOfPolylines = defaultValue(featureTableJson.POLYLINES_LENGTH, 0); + var numberOfPoints = defaultValue(featureTableJson.POINTS_LENGTH, 0); + + if (numberOfPolygons > 0 && defined(featureTableJson.POLYGON_BATCH_IDS)) { + var polygonBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYGON_BATCH_IDS.byteOffset; + polygonBatchIds = new Uint16Array(featureTableBinary.buffer, polygonBatchIdsByteOffset, numberOfPolygons); + } + + if (numberOfPolylines > 0 && defined(featureTableJson.POLYLINE_BATCH_IDS)) { + var polylineBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYLINE_BATCH_IDS.byteOffset; + polylineBatchIds = new Uint16Array(featureTableBinary.buffer, polylineBatchIdsByteOffset, numberOfPolylines); + } + + if (numberOfPoints > 0 && defined(featureTableJson.POINT_BATCH_IDS)) { + var pointBatchIdsByteOffset = featureTableBinary.byteOffset + featureTableJson.POINT_BATCH_IDS.byteOffset; + pointBatchIds = new Uint16Array(featureTableBinary.buffer, pointBatchIdsByteOffset, numberOfPoints); + } + + var atLeastOneDefined = defined(polygonBatchIds) || defined(polylineBatchIds) || defined(pointBatchIds); + var atLeastOneUndefined = (numberOfPolygons > 0 && !defined(polygonBatchIds)) || + (numberOfPolylines > 0 && !defined(polylineBatchIds)) || + (numberOfPoints > 0 && !defined(pointBatchIds)); + + if (atLeastOneDefined && atLeastOneUndefined) { + throw new RuntimeError('If one group of batch ids is defined, then all batch ids must be defined.'); + } + + var allUndefinedBatchIds = !defined(polygonBatchIds) && !defined(polylineBatchIds) && !defined(pointBatchIds); + if (allUndefinedBatchIds) { + var id = 0; + if (!defined(polygonBatchIds) && numberOfPolygons > 0) { + polygonBatchIds = new Uint16Array(numberOfPolygons); + for (i = 0; i < numberOfPolygons; ++i) { + polygonBatchIds[i] = id++; + } + } + if (!defined(polylineBatchIds) && numberOfPolylines > 0) { + polylineBatchIds = new Uint16Array(numberOfPolylines); + for (i = 0; i < numberOfPolylines; ++i) { + polylineBatchIds[i] = id++; + } + } + if (!defined(pointBatchIds) && numberOfPoints > 0) { + pointBatchIds = new Uint16Array(numberOfPoints); + for (i = 0; i < numberOfPoints; ++i) { + pointBatchIds[i] = id++; + } + } + } + + return { + polygons : polygonBatchIds, + polylines : polylineBatchIds, + points : pointBatchIds + }; + } + + var sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT; var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - function initialize(content, arrayBuffer, byteOffset, factory) { + function initialize(content, arrayBuffer, byteOffset) { byteOffset = defaultValue(byteOffset, 0); var uint8Array = new Uint8Array(arrayBuffer); var view = new DataView(arrayBuffer); - byteOffset += sizeOfUint32; // Skip magic + byteOffset += sizeOfUint32; // Skip magic number var version = view.getUint32(byteOffset, true); if (version !== 1) { - throw new RuntimeError('Only Composite Tile version 1 is supported. Version ' + version + ' is not.'); + throw new RuntimeError('Only Vector tile version 1 is supported. Version ' + version + ' is not.'); } byteOffset += sizeOfUint32; - // Skip byteLength + var byteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - var tilesLength = view.getUint32(byteOffset, true); + if (byteLength === 0) { + content._readyPromise.resolve(content); + return; + } + + var featureTableJSONByteLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - var contentPromises = []; + if (featureTableJSONByteLength === 0) { + throw new RuntimeError('Feature table must have a byte length greater than zero'); + } - for (var i = 0; i < tilesLength; ++i) { - var tileType = getMagic(uint8Array, byteOffset); + var featureTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var batchTableJSONByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var batchTableBinaryByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var indicesByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var positionByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var polylinePositionByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; + var pointsPositionByteLength = view.getUint32(byteOffset, true); + byteOffset += sizeOfUint32; - // Tile byte length is stored after magic and version - var tileByteLength = view.getUint32(byteOffset + sizeOfUint32 * 2, true); + var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJSONByteLength); + var featureTableJson = JSON.parse(featureTableString); + byteOffset += featureTableJSONByteLength; - var contentFactory = factory[tileType]; + var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); + byteOffset += featureTableBinaryByteLength; - if (defined(contentFactory)) { - var innerContent = contentFactory(content._tileset, content._tile, content._url, arrayBuffer, byteOffset); - content._contents.push(innerContent); - contentPromises.push(innerContent.readyPromise); - } else { - throw new RuntimeError('Unknown tile content type, ' + tileType + ', inside Composite tile'); + var batchTableJson; + var batchTableBinary; + if (batchTableJSONByteLength > 0) { + // PERFORMANCE_IDEA: is it possible to allocate this on-demand? Perhaps keep the + // arraybuffer/string compressed in memory and then decompress it when it is first accessed. + // + // We could also make another request for it, but that would make the property set/get + // API async, and would double the number of numbers in some cases. + var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJSONByteLength); + batchTableJson = JSON.parse(batchTableString); + byteOffset += batchTableJSONByteLength; + + if (batchTableBinaryByteLength > 0) { + // Has a batch table binary + batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); + // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed + batchTableBinary = new Uint8Array(batchTableBinary); + byteOffset += batchTableBinaryByteLength; } + } - byteOffset += tileByteLength; + var numberOfPolygons = defaultValue(featureTableJson.POLYGONS_LENGTH, 0); + var numberOfPolylines = defaultValue(featureTableJson.POLYLINES_LENGTH, 0); + var numberOfPoints = defaultValue(featureTableJson.POINTS_LENGTH, 0); + var totalPrimitives = numberOfPolygons + numberOfPolylines + numberOfPoints; + + var batchTable = new Cesium3DTileBatchTable(content, totalPrimitives, batchTableJson, batchTableBinary, createColorChangedCallback(content)); + content._batchTable = batchTable; + + if (totalPrimitives === 0) { + return; } - when.all(contentPromises).then(function() { - content._readyPromise.resolve(content); - }).otherwise(function(error) { - content._readyPromise.reject(error); - }); + var rectangle; + var minHeight; + var maxHeight; + if (defined(featureTableJson.REGION)) { + var region = featureTableJson.REGION; + rectangle = Rectangle.unpack(region); + minHeight = region[4]; + maxHeight = region[5]; + } else { + throw new RuntimeError('REGION is required in the feature table.'); + } + + var modelMatrix = content._tile.computedTransform; + + var center; + if (defined(featureTableJson.RTC_CENTER)) { + center = Cartesian3.unpack(featureTableJson.RTC_CENTER); + Matrix4.multiplyByPoint(modelMatrix, center, center); + } else { + center = Rectangle.center(rectangle); + center.height = CesiumMath.lerp(minHeight, maxHeight, 0.5); + center = Ellipsoid.WGS84.cartographicToCartesian(center); + } + + var batchIds = getBatchIds(featureTableJson, featureTableBinary); + + byteOffset += byteOffset % 4; + + if (numberOfPolygons > 0) { + var indices = new Uint32Array(arrayBuffer, byteOffset, indicesByteLength / sizeOfUint32); + byteOffset += indicesByteLength; + + var polygonPositions = new Uint16Array(arrayBuffer, byteOffset, positionByteLength / sizeOfUint16); + byteOffset += positionByteLength; + + var polygonCountByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYGON_COUNT.byteOffset; + var counts = new Uint32Array(featureTableBinary.buffer, polygonCountByteOffset, numberOfPolygons); + + var polygonIndexCountByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYGON_INDEX_COUNT.byteOffset; + var indexCounts = new Uint32Array(featureTableBinary.buffer, polygonIndexCountByteOffset, numberOfPolygons); + + var polygonMinimumHeights; + var polygonMaximumHeights; + if (defined(featureTableJson.POLYGON_MINIMUM_HEIGHTS) && defined(featureTableJson.POLYGON_MAXIMUM_HEIGHTS)) { + var polygonMinimumHeightsByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYGON_MINIMUM_HEIGHTS.byteOffset; + polygonMinimumHeights = new Float32Array(featureTableBinary.buffer, polygonMinimumHeightsByteOffset, numberOfPolygons); + + var polygonMaximumHeightsByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYGON_MAXIMUM_HEIGHTS.byteOffset; + polygonMaximumHeights = new Float32Array(featureTableBinary.buffer, polygonMaximumHeightsByteOffset, numberOfPolygons); + } + + content._polygons = new Vector3DTilePolygons({ + positions : polygonPositions, + counts : counts, + indexCounts : indexCounts, + indices : indices, + minimumHeight : minHeight, + maximumHeight : maxHeight, + polygonMinimumHeights : polygonMinimumHeights, + polygonMaximumHeights : polygonMaximumHeights, + center : center, + rectangle : rectangle, + boundingVolume : content._tile._boundingVolume.boundingVolume, + batchTable : batchTable, + batchIds : batchIds.polygons, + modelMatrix : modelMatrix + }); + } + + if (numberOfPolylines > 0) { + var polylinePositions = new Uint16Array(arrayBuffer, byteOffset, polylinePositionByteLength / sizeOfUint16); + byteOffset += polylinePositionByteLength; + + var polylineCountByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYLINE_COUNT.byteOffset; + var polylineCounts = new Uint32Array(featureTableBinary.buffer, polylineCountByteOffset, numberOfPolylines); + + var widths; + if (!defined(featureTableJson.POLYLINE_WIDTHS)) { + widths = new Uint16Array(numberOfPolylines); + for (var i = 0; i < numberOfPolylines; ++i) { + widths[i] = 2.0; + } + } else { + var polylineWidthsByteOffset = featureTableBinary.byteOffset + featureTableJson.POLYLINE_WIDTHS.byteOffset; + widths = new Uint16Array(featureTableBinary.buffer, polylineWidthsByteOffset, numberOfPolylines); + } + + content._polylines = new Vector3DTilePolylines({ + positions : polylinePositions, + widths : widths, + counts : polylineCounts, + batchIds : batchIds.polylines, + minimumHeight : minHeight, + maximumHeight : maxHeight, + center : center, + rectangle : rectangle, + boundingVolume : content._tile._boundingVolume.boundingVolume, + batchTable : batchTable + }); + } + + if (numberOfPoints > 0) { + var pointPositions = new Uint16Array(arrayBuffer, byteOffset, pointsPositionByteLength / sizeOfUint16); + content._points = new Vector3DTilePoints({ + positions : pointPositions, + batchIds : batchIds.points, + minimumHeight : minHeight, + maximumHeight : maxHeight, + rectangle : rectangle, + batchTable : batchTable + }); + } + } + + function createFeatures(content) { + var featuresLength = content.featuresLength; + if (!defined(content._features) && (featuresLength > 0)) { + var features = new Array(featuresLength); + + if (defined(content._polygons)) { + content._polygons.createFeatures(content, features); + } + if (defined(content._polylines)) { + content._polylines.createFeatures(content, features); + } + if (defined(content._points)) { + content._points.createFeatures(content, features); + } + content._features = features; + } } /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>false</code>. Instead call <code>hasProperty</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#hasProperty */ - Composite3DTileContent.prototype.hasProperty = function(batchId, name) { - return false; + Vector3DTileContent.prototype.hasProperty = function(batchId, name) { + return this._batchTable.hasProperty(batchId, name); }; /** - * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> - * always returns <code>undefined</code>. Instead call <code>getFeature</code> for a tile in the composite. + * @inheritdoc Cesium3DTileContent#getFeature */ - Composite3DTileContent.prototype.getFeature = function(batchId) { - return undefined; + Vector3DTileContent.prototype.getFeature = function(batchId) { + var featuresLength = this.featuresLength; + if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); + } + + createFeatures(this); + return this._features[batchId]; }; /** * @inheritdoc Cesium3DTileContent#applyDebugSettings */ - Composite3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - var contents = this._contents; - var length = contents.length; - for (var i = 0; i < length; ++i) { - contents[i].applyDebugSettings(enabled, color); + Vector3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + if (defined(this._polygons)) { + this._polygons.applyDebugSettings(enabled, color); + } + if (defined(this._polylines)) { + this._polylines.applyDebugSettings(enabled, color); + } + if (defined(this._points)) { + this._points.applyDebugSettings(enabled, color); } }; /** * @inheritdoc Cesium3DTileContent#applyStyle */ - Composite3DTileContent.prototype.applyStyle = function(frameState, style) { - var contents = this._contents; - var length = contents.length; - for (var i = 0; i < length; ++i) { - contents[i].applyStyle(frameState, style); + Vector3DTileContent.prototype.applyStyle = function(frameState, style) { + createFeatures(this); + if (defined(this._polygons)) { + this._polygons.applyStyle(frameState, style, this._features); + } + if (defined(this._polylines)) { + this._polylines.applyStyle(frameState, style, this._features); + } + if (defined(this._points)) { + this._points.applyStyle(frameState, style, this._features); } }; /** * @inheritdoc Cesium3DTileContent#update */ - Composite3DTileContent.prototype.update = function(tileset, frameState) { - var contents = this._contents; - var length = contents.length; - for (var i = 0; i < length; ++i) { - contents[i].update(tileset, frameState); + Vector3DTileContent.prototype.update = function(tileset, frameState) { + if (defined(this._batchTable)) { + this._batchTable.update(tileset, frameState); + } + if (defined(this._polygons)) { + this._polygons.classificationType = this._tileset.classificationType; + this._polygons.update(frameState); + } + if (defined(this._polylines)) { + this._polylines.update(frameState); + } + if (defined(this._points)) { + this._points.update(frameState); + } + + if (!defined(this._contentReadyPromise)) { + var pointsPromise = defined(this._points) ? this._points.readyPromise : undefined; + var polygonPromise = defined(this._polygons) ? this._polygons.readyPromise : undefined; + var polylinePromise = defined(this._polylines) ? this._polylines.readyPromise : undefined; + + var that = this; + this._contentReadyPromise = when.all([pointsPromise, polygonPromise, polylinePromise]).then(function() { + that._readyPromise.resolve(that); + }); } }; /** * @inheritdoc Cesium3DTileContent#isDestroyed */ - Composite3DTileContent.prototype.isDestroyed = function() { + Vector3DTileContent.prototype.isDestroyed = function() { return false; }; /** * @inheritdoc Cesium3DTileContent#destroy */ - Composite3DTileContent.prototype.destroy = function() { - var contents = this._contents; - var length = contents.length; - for (var i = 0; i < length; ++i) { - contents[i].destroy(); - } + Vector3DTileContent.prototype.destroy = function() { + this._polygons = this._polygons && this._polygons.destroy(); + this._polylines = this._polylines && this._polylines.destroy(); + this._points = this._points && this._points.destroy(); + this._batchTable = this._batchTable && this._batchTable.destroy(); return destroyObject(this); }; - return Composite3DTileContent; + return Vector3DTileContent; }); -define('Scene/ModelInstance',[ - '../Core/defineProperties', - '../Core/Matrix4' +define('Scene/Cesium3DTileContentFactory',[ + './Batched3DModel3DTileContent', + './Composite3DTileContent', + './Geometry3DTileContent', + './Instanced3DModel3DTileContent', + './PointCloud3DTileContent', + './Tileset3DTileContent', + './Vector3DTileContent' ], function( - defineProperties, - Matrix4) { + Batched3DModel3DTileContent, + Composite3DTileContent, + Geometry3DTileContent, + Instanced3DModel3DTileContent, + PointCloud3DTileContent, + Tileset3DTileContent, + Vector3DTileContent) { 'use strict'; /** + * Maps a tile's magic field in its header to a new content object for the tile's payload. + * * @private */ - function ModelInstance(collection, modelMatrix, instanceId) { - this.primitive = collection; - this._modelMatrix = Matrix4.clone(modelMatrix); - this._instanceId = instanceId; - } - - defineProperties(ModelInstance.prototype, { - instanceId : { - get : function() { - return this._instanceId; - } + var Cesium3DTileContentFactory = { + b3dm : function(tileset, tile, resource, arrayBuffer, byteOffset) { + return new Batched3DModel3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset); }, - model : { - get : function() { - return this.primitive._model; - } + pnts : function(tileset, tile, resource, arrayBuffer, byteOffset) { + return new PointCloud3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset); }, - modelMatrix : { - get : function() { - return Matrix4.clone(this._modelMatrix); - }, - set : function(value) { - Matrix4.clone(value, this._modelMatrix); - this.primitive.expandBoundingSphere(this._modelMatrix); - this.primitive._dirty = true; - } + i3dm : function(tileset, tile, resource, arrayBuffer, byteOffset) { + return new Instanced3DModel3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset); + }, + cmpt : function(tileset, tile, resource, arrayBuffer, byteOffset) { + // Send in the factory in order to avoid a cyclical dependency + return new Composite3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset, Cesium3DTileContentFactory); + }, + json : function(tileset, tile, resource, arrayBuffer, byteOffset) { + return new Tileset3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset); + }, + geom : function(tileset, tile, resource, arrayBuffer, byteOffset) { + return new Geometry3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset); + }, + vctr : function(tileset, tile, resource, arrayBuffer, byteOffset) { + return new Vector3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset); } - }); + }; - return ModelInstance; + return Cesium3DTileContentFactory; }); -define('Scene/ModelInstanceCollection',[ - '../Core/BoundingSphere', - '../Core/Cartesian3', - '../Core/clone', - '../Core/Color', - '../Core/ComponentDatatype', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Matrix4', - '../Core/PrimitiveType', - '../Core/RuntimeError', - '../Core/Transforms', - '../Renderer/Buffer', - '../Renderer/BufferUsage', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/ShaderSource', - '../ThirdParty/when', - './getAttributeOrUniformBySemantic', - './Model', - './ModelInstance', - './SceneMode', - './ShadowMode' +define('Scene/Cesium3DTileContentState',[ + '../Core/freezeObject' ], function( - BoundingSphere, - Cartesian3, - clone, - Color, - ComponentDatatype, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - Matrix4, - PrimitiveType, - RuntimeError, - Transforms, - Buffer, - BufferUsage, - DrawCommand, - Pass, - ShaderSource, - when, - getAttributeOrUniformBySemantic, - Model, - ModelInstance, - SceneMode, - ShadowMode) { + freezeObject) { 'use strict'; - var LoadState = { - NEEDS_LOAD : 0, - LOADING : 1, - LOADED : 2, - FAILED : 3 + /** + * @private + */ + var Cesium3DTileContentState = { + UNLOADED : 0, // Has never been requested + LOADING : 1, // Is waiting on a pending request + PROCESSING : 2, // Request received. Contents are being processed for rendering. Depending on the content, it might make its own requests for external data. + READY : 3, // Ready to render. + EXPIRED : 4, // Is expired and will be unloaded once new content is loaded. + FAILED : 5 // Request failed. }; + return freezeObject(Cesium3DTileContentState); +}); + +define('Scene/Cesium3DTileOptimizationHint',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + /** - * A 3D model instance collection. All instances reference the same underlying model, but have unique - * per-instance properties like model matrix, pick id, etc. - * - * Instances are rendered relative-to-center and for best results instances should be positioned close to one another. - * Otherwise there may be precision issues if, for example, instances are placed on opposite sides of the globe. - * - * @alias ModelInstanceCollection - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Object[]} [options.instances] An array of instances, where each instance contains a modelMatrix and optional batchId when options.batchTable is defined. - * @param {Cesium3DTileBatchTable} [options.batchTable] The batch table of the instanced 3D Tile. - * @param {String} [options.url] The url to the .gltf file. - * @param {Object} [options.headers] HTTP headers to send with the request. - * @param {Object} [options.requestType] The request type, used for request prioritization - * @param {Object|ArrayBuffer|Uint8Array} [options.gltf] The object for the glTF JSON or an arraybuffer of Binary glTF defined by the CESIUM_binary_glTF extension. - * @param {String} [options.basePath=''] The base path that paths in the glTF JSON are relative to. - * @param {Boolean} [options.dynamic=false] Hint if instance model matrices will be updated frequently. - * @param {Boolean} [options.show=true] Determines if the collection will be shown. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each instance is pickable with {@link Scene#pick}. - * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. - * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the collection casts or receives shadows from each light source. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for the collection. - * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the instances in wireframe. + * Hint defining optimization support for a 3D tile * - * @exception {DeveloperError} Must specify either <options.gltf> or <options.url>, but not both. - * @exception {DeveloperError} Shader program cannot be optimized for instancing. Parameters cannot have any of the following semantics: MODEL, MODELINVERSE, MODELVIEWINVERSE, MODELVIEWPROJECTIONINVERSE, MODELINVERSETRANSPOSE. + * @exports Cesium3DTileOptimizationHint * * @private */ - function ModelInstanceCollection(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (!defined(options.gltf) && !defined(options.url)) { - throw new DeveloperError('Either options.gltf or options.url is required.'); - } - - if (defined(options.gltf) && defined(options.url)) { - throw new DeveloperError('Cannot pass in both options.gltf and options.url.'); - } - - this.show = defaultValue(options.show, true); - - this._instancingSupported = false; - this._dynamic = defaultValue(options.dynamic, false); - this._allowPicking = defaultValue(options.allowPicking, true); - this._ready = false; - this._readyPromise = when.defer(); - this._state = LoadState.NEEDS_LOAD; - this._dirty = false; - - // Undocumented options - this._cull = defaultValue(options.cull, true); - this._opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); - - this._instances = createInstances(this, options.instances); - - // When the model instance collection is backed by an i3dm tile, - // use its batch table resources to modify the shaders, attributes, and uniform maps. - this._batchTable = options.batchTable; - - this._model = undefined; - this._vertexBufferTypedArray = undefined; // Hold onto the vertex buffer contents when dynamic is true - this._vertexBuffer = undefined; - this._batchIdBuffer = undefined; - this._instancedUniformsByProgram = undefined; + var Cesium3DTileOptimizationHint = { + NOT_COMPUTED: -1, + USE_OPTIMIZATION: 1, + SKIP_OPTIMIZATION: 0 + }; - this._drawCommands = []; - this._pickCommands = []; - this._modelCommands = undefined; + return freezeObject(Cesium3DTileOptimizationHint); +}); - this._boundingSphere = createBoundingSphere(this); - this._center = Cartesian3.clone(this._boundingSphere.center); - this._rtcTransform = new Matrix4(); - this._rtcModelView = new Matrix4(); // Holds onto uniform +define('Scene/Cesium3DTileRefine',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; - this._mode = undefined; + /** + * The refinement approach for a tile. + * <p> + * See the {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/schema/tile.schema.json|tile schema} + * in the 3D Tiles spec. + * </p> + * + * @exports Cesium3DTileRefine + * + * @private + */ + var Cesium3DTileRefine = { + /** + * Render this tile and, if it doesn't meet the screen space error, also refine to its children. + * + * @type {Number} + * @constant + */ + ADD : 0, - this.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); - this._modelMatrix = Matrix4.clone(this.modelMatrix); + /** + * Render this tile or, if it doesn't meet the screen space error, refine to its descendants instead. + * + * @type {Number} + * @constant + */ + REPLACE : 1 + }; - // Passed on to Model - this._url = options.url; - this._headers = options.headers; - this._requestType = options.requestType; - this._gltf = options.gltf; - this._basePath = options.basePath; - this._asynchronous = options.asynchronous; - this._incrementallyLoadTextures = options.incrementallyLoadTextures; - this._upAxis = options.upAxis; // Undocumented option + return freezeObject(Cesium3DTileRefine); +}); - this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); - this._shadows = this.shadows; +define('Scene/Empty3DTileContent',[ + '../Core/defineProperties', + '../Core/destroyObject' + ], function( + defineProperties, + destroyObject) { + 'use strict'; - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - this._debugShowBoundingVolume = false; + /** + * Represents empty content for tiles in a + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset that + * do not have content, e.g., because they are used to optimize hierarchical culling. + * <p> + * Implements the {@link Cesium3DTileContent} interface. + * </p> + * + * @alias Empty3DTileContent + * @constructor + * + * @private + */ + function Empty3DTileContent(tileset, tile) { + this._tileset = tileset; + this._tile = tile; - this.debugWireframe = defaultValue(options.debugWireframe, false); - this._debugWireframe = false; + /** + * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + */ + this.featurePropertiesDirty = false; } - defineProperties(ModelInstanceCollection.prototype, { - allowPicking : { + defineProperties(Empty3DTileContent.prototype, { + /** + * @inheritdoc Cesium3DTileContent#featuresLength + */ + featuresLength : { get : function() { - return this._allowPicking; + return 0; } }, - length : { + + /** + * @inheritdoc Cesium3DTileContent#pointsLength + */ + pointsLength : { get : function() { - return this._instances.length; + return 0; } }, - activeAnimations : { + + /** + * @inheritdoc Cesium3DTileContent#trianglesLength + */ + trianglesLength : { get : function() { - return this._model.activeAnimations; + return 0; } }, - ready : { + + /** + * @inheritdoc Cesium3DTileContent#geometryByteLength + */ + geometryByteLength : { get : function() { - return this._ready; + return 0; } }, - readyPromise : { - get : function() { - return this._readyPromise.promise; - } - } - }); - - function createInstances(collection, instancesOptions) { - instancesOptions = defaultValue(instancesOptions, []); - var length = instancesOptions.length; - var instances = new Array(length); - for (var i = 0; i < length; ++i) { - var instanceOptions = instancesOptions[i]; - var modelMatrix = instanceOptions.modelMatrix; - var instanceId = defaultValue(instanceOptions.batchId, i); - instances[i] = new ModelInstance(collection, modelMatrix, instanceId); - } - return instances; - } - - function createBoundingSphere(collection) { - var instancesLength = collection.length; - var points = new Array(instancesLength); - for (var i = 0; i < instancesLength; ++i) { - points[i] = Matrix4.getTranslation(collection._instances[i]._modelMatrix, new Cartesian3()); - } - - return BoundingSphere.fromPoints(points); - } - - var scratchCartesian = new Cartesian3(); - var scratchMatrix = new Matrix4(); - - ModelInstanceCollection.prototype.expandBoundingSphere = function(instanceModelMatrix) { - var translation = Matrix4.getTranslation(instanceModelMatrix, scratchCartesian); - BoundingSphere.expand(this._boundingSphere, translation, this._boundingSphere); - }; - - function getInstancedUniforms(collection, programName) { - if (defined(collection._instancedUniformsByProgram)) { - return collection._instancedUniformsByProgram[programName]; - } - - var instancedUniformsByProgram = {}; - collection._instancedUniformsByProgram = instancedUniformsByProgram; - - // When using CESIUM_RTC_MODELVIEW the CESIUM_RTC center is ignored. Instances are always rendered relative-to-center. - var modelSemantics = ['MODEL', 'MODELVIEW', 'CESIUM_RTC_MODELVIEW', 'MODELVIEWPROJECTION', 'MODELINVERSE', 'MODELVIEWINVERSE', 'MODELVIEWPROJECTIONINVERSE', 'MODELINVERSETRANSPOSE', 'MODELVIEWINVERSETRANSPOSE']; - var supportedSemantics = ['MODELVIEW', 'CESIUM_RTC_MODELVIEW', 'MODELVIEWPROJECTION', 'MODELVIEWINVERSETRANSPOSE']; - - var gltf = collection._model.gltf; - var techniques = gltf.techniques; - for (var techniqueName in techniques) { - if (techniques.hasOwnProperty(techniqueName)) { - var technique = techniques[techniqueName]; - var parameters = technique.parameters; - var uniforms = technique.uniforms; - var program = technique.program; - - // Different techniques may share the same program, skip if already processed. - // This assumes techniques that share a program do not declare different semantics for the same uniforms. - if (!defined(instancedUniformsByProgram[program])) { - var uniformMap = {}; - instancedUniformsByProgram[program] = uniformMap; - for (var uniformName in uniforms) { - if (uniforms.hasOwnProperty(uniformName)) { - var parameterName = uniforms[uniformName]; - var parameter = parameters[parameterName]; - var semantic = parameter.semantic; - if (defined(semantic) && (modelSemantics.indexOf(semantic) > -1)) { - if (supportedSemantics.indexOf(semantic) > -1) { - uniformMap[uniformName] = semantic; - } else { - throw new RuntimeError('Shader program cannot be optimized for instancing. ' + - 'Parameter "' + parameter + '" in program "' + programName + - '" uses unsupported semantic "' + semantic + '"' - ); - } - } - } - } - } - } - } - - return instancedUniformsByProgram[programName]; - } - - var vertexShaderCached; - - function getVertexShaderCallback(collection) { - return function(vs, programName) { - var instancedUniforms = getInstancedUniforms(collection, programName); - var usesBatchTable = defined(collection._batchTable); - - var renamedSource = ShaderSource.replaceMain(vs, 'czm_instancing_main'); - - var globalVarsHeader = ''; - var globalVarsMain = ''; - for (var uniform in instancedUniforms) { - if (instancedUniforms.hasOwnProperty(uniform)) { - var semantic = instancedUniforms[uniform]; - var varName; - if (semantic === 'MODELVIEW' || semantic === 'CESIUM_RTC_MODELVIEW') { - varName = 'czm_instanced_modelView'; - } else if (semantic === 'MODELVIEWPROJECTION') { - varName = 'czm_instanced_modelViewProjection'; - globalVarsHeader += 'mat4 czm_instanced_modelViewProjection;\n'; - globalVarsMain += 'czm_instanced_modelViewProjection = czm_projection * czm_instanced_modelView;\n'; - } else if (semantic === 'MODELVIEWINVERSETRANSPOSE') { - varName = 'czm_instanced_modelViewInverseTranspose'; - globalVarsHeader += 'mat3 czm_instanced_modelViewInverseTranspose;\n'; - globalVarsMain += 'czm_instanced_modelViewInverseTranspose = mat3(czm_instanced_modelView);\n'; - } - - // Remove the uniform declaration - var regex = new RegExp('uniform.*' + uniform + '.*'); - renamedSource = renamedSource.replace(regex, ''); - - // Replace all occurrences of the uniform with the global variable - regex = new RegExp(uniform + '\\b', 'g'); - renamedSource = renamedSource.replace(regex, varName); - } - } - - // czm_instanced_model is the model matrix of the instance relative to center - // czm_instanced_modifiedModelView is the transform from the center to view - // czm_instanced_nodeTransform is the local offset of the node within the model - var uniforms = - 'uniform mat4 czm_instanced_modifiedModelView;\n' + - 'uniform mat4 czm_instanced_nodeTransform;\n'; - - var batchIdAttribute = usesBatchTable ? 'attribute float a_batchId;\n' : ''; - - var instancedSource = - uniforms + - globalVarsHeader + - 'mat4 czm_instanced_modelView;\n' + - 'attribute vec4 czm_modelMatrixRow0;\n' + - 'attribute vec4 czm_modelMatrixRow1;\n' + - 'attribute vec4 czm_modelMatrixRow2;\n' + - batchIdAttribute + - renamedSource + - 'void main()\n' + - '{\n' + - ' mat4 czm_instanced_model = mat4(czm_modelMatrixRow0.x, czm_modelMatrixRow1.x, czm_modelMatrixRow2.x, 0.0, czm_modelMatrixRow0.y, czm_modelMatrixRow1.y, czm_modelMatrixRow2.y, 0.0, czm_modelMatrixRow0.z, czm_modelMatrixRow1.z, czm_modelMatrixRow2.z, 0.0, czm_modelMatrixRow0.w, czm_modelMatrixRow1.w, czm_modelMatrixRow2.w, 1.0);\n' + - ' czm_instanced_modelView = czm_instanced_modifiedModelView * czm_instanced_model * czm_instanced_nodeTransform;\n' + - globalVarsMain + - ' czm_instancing_main();\n' + - '}'; - - vertexShaderCached = instancedSource; - - if (usesBatchTable) { - instancedSource = collection._batchTable.getVertexShaderCallback(true, 'a_batchId')(instancedSource); - } - - return instancedSource; - }; - } - - function getFragmentShaderCallback(collection) { - return function(fs) { - var batchTable = collection._batchTable; - if (defined(batchTable)) { - var gltf = collection._model.gltf; - var diffuseUniformName = getAttributeOrUniformBySemantic(gltf, '_3DTILESDIFFUSE'); - fs = batchTable.getFragmentShaderCallback(true, diffuseUniformName)(fs); - } - return fs; - }; - } - - function getPickVertexShaderCallback(collection) { - return function (vs) { - // Use the vertex shader that was generated earlier - vs = vertexShaderCached; - var usesBatchTable = defined(collection._batchTable); - var allowPicking = collection._allowPicking; - if (usesBatchTable) { - vs = collection._batchTable.getPickVertexShaderCallback('a_batchId')(vs); - } else if (allowPicking) { - vs = ShaderSource.createPickVertexShaderSource(vs); - } - return vs; - }; - } - - function getPickFragmentShaderCallback(collection) { - return function(fs) { - var usesBatchTable = defined(collection._batchTable); - var allowPicking = collection._allowPicking; - if (usesBatchTable) { - fs = collection._batchTable.getPickFragmentShaderCallback()(fs); - } else if (allowPicking) { - fs = ShaderSource.createPickFragmentShaderSource(fs, 'varying'); - } - return fs; - }; - } - - function createModifiedModelView(collection, context) { - return function() { - return Matrix4.multiply(context.uniformState.view, collection._rtcTransform, collection._rtcModelView); - }; - } - - function createNodeTransformFunction(node) { - return function() { - return node.computedMatrix; - }; - } - function getUniformMapCallback(collection, context) { - return function(uniformMap, programName, node) { - uniformMap = clone(uniformMap); - uniformMap.czm_instanced_modifiedModelView = createModifiedModelView(collection, context); - uniformMap.czm_instanced_nodeTransform = createNodeTransformFunction(node); - - // Remove instanced uniforms from the uniform map - var instancedUniforms = getInstancedUniforms(collection, programName); - for (var uniform in instancedUniforms) { - if (instancedUniforms.hasOwnProperty(uniform)) { - delete uniformMap[uniform]; - } + /** + * @inheritdoc Cesium3DTileContent#texturesByteLength + */ + texturesByteLength : { + get : function() { + return 0; } + }, - if (defined(collection._batchTable)) { - uniformMap = collection._batchTable.getUniformMapCallback()(uniformMap); + /** + * @inheritdoc Cesium3DTileContent#batchTableByteLength + */ + batchTableByteLength : { + get : function() { + return 0; } + }, - return uniformMap; - }; - } - - function getPickUniformMapCallback(collection) { - return function(uniformMap) { - // Uses the uniform map generated from getUniformMapCallback - if (defined(collection._batchTable)) { - uniformMap = collection._batchTable.getPickUniformMapCallback()(uniformMap); + /** + * @inheritdoc Cesium3DTileContent#innerContents + */ + innerContents : { + get : function() { + return undefined; } - return uniformMap; - }; - } + }, - function getVertexShaderNonInstancedCallback(collection) { - return function(vs) { - if (defined(collection._batchTable)) { - vs = collection._batchTable.getVertexShaderCallback(true, 'a_batchId')(vs); - // Treat a_batchId as a uniform rather than a vertex attribute - vs = 'uniform float a_batchId\n;' + vs; + /** + * @inheritdoc Cesium3DTileContent#readyPromise + */ + readyPromise : { + get : function() { + return undefined; } - return vs; - }; - } + }, - function getPickVertexShaderNonInstancedCallback(collection) { - return function(vs) { - if (defined(collection._batchTable)) { - vs = collection._batchTable.getPickVertexShaderCallback('a_batchId')(vs); - // Treat a_batchId as a uniform rather than a vertex attribute - vs = 'uniform float a_batchId\n;' + vs; + /** + * @inheritdoc Cesium3DTileContent#tileset + */ + tileset : { + get : function() { + return this._tileset; } - return vs; - }; - } + }, - function getPickFragmentShaderNonInstancedCallback(collection) { - return function(fs) { - var usesBatchTable = defined(collection._batchTable); - var allowPicking = collection._allowPicking; - if (usesBatchTable) { - fs = collection._batchTable.getPickFragmentShaderCallback()(fs); - } else if (allowPicking) { - fs = ShaderSource.createPickFragmentShaderSource(fs, 'uniform'); + /** + * @inheritdoc Cesium3DTileContent#tile + */ + tile : { + get : function() { + return this._tile; } - return fs; - }; - } + }, - function getUniformMapNonInstancedCallback(collection) { - return function(uniformMap) { - if (defined(collection._batchTable)) { - uniformMap = collection._batchTable.getUniformMapCallback()(uniformMap); + /** + * @inheritdoc Cesium3DTileContent#url + */ + url: { + get: function() { + return undefined; } + }, - return uniformMap; - }; - } - - function getVertexBufferTypedArray(collection) { - var instances = collection._instances; - var instancesLength = collection.length; - var collectionCenter = collection._center; - var vertexSizeInFloats = 12; - - var bufferData = collection._vertexBufferTypedArray; - if (!defined(bufferData)) { - bufferData = new Float32Array(instancesLength * vertexSizeInFloats); - } - if (collection._dynamic) { - // Hold onto the buffer data so we don't have to allocate new memory every frame. - collection._vertexBufferTypedArray = bufferData; - } - - for (var i = 0; i < instancesLength; ++i) { - var modelMatrix = instances[i]._modelMatrix; - - // Instance matrix is relative to center - var instanceMatrix = Matrix4.clone(modelMatrix, scratchMatrix); - instanceMatrix[12] -= collectionCenter.x; - instanceMatrix[13] -= collectionCenter.y; - instanceMatrix[14] -= collectionCenter.z; - - var offset = i * vertexSizeInFloats; - - // First three rows of the model matrix - bufferData[offset + 0] = instanceMatrix[0]; - bufferData[offset + 1] = instanceMatrix[4]; - bufferData[offset + 2] = instanceMatrix[8]; - bufferData[offset + 3] = instanceMatrix[12]; - bufferData[offset + 4] = instanceMatrix[1]; - bufferData[offset + 5] = instanceMatrix[5]; - bufferData[offset + 6] = instanceMatrix[9]; - bufferData[offset + 7] = instanceMatrix[13]; - bufferData[offset + 8] = instanceMatrix[2]; - bufferData[offset + 9] = instanceMatrix[6]; - bufferData[offset + 10] = instanceMatrix[10]; - bufferData[offset + 11] = instanceMatrix[14]; - } - - return bufferData; - } - - function createVertexBuffer(collection, context) { - var i; - var instances = collection._instances; - var instancesLength = collection.length; - var dynamic = collection._dynamic; - var usesBatchTable = defined(collection._batchTable); - var allowPicking = collection._allowPicking; - - if (usesBatchTable) { - var batchIdBufferData = new Uint16Array(instancesLength); - for (i = 0; i < instancesLength; ++i) { - batchIdBufferData[i] = instances[i]._instanceId; + /** + * @inheritdoc Cesium3DTileContent#batchTable + */ + batchTable : { + get : function() { + return undefined; } - collection._batchIdBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : batchIdBufferData, - usage : BufferUsage.STATIC_DRAW - }); } + }); - if (allowPicking && !usesBatchTable) { - var pickIdBuffer = new Uint8Array(instancesLength * 4); - for (i = 0; i < instancesLength; ++i) { - var pickId = collection._pickIds[i]; - var pickColor = pickId.color; - var offset = i * 4; - pickIdBuffer[offset] = Color.floatToByte(pickColor.red); - pickIdBuffer[offset + 1] = Color.floatToByte(pickColor.green); - pickIdBuffer[offset + 2] = Color.floatToByte(pickColor.blue); - pickIdBuffer[offset + 3] = Color.floatToByte(pickColor.alpha); - } - collection._pickIdBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : pickIdBuffer, - usage : BufferUsage.STATIC_DRAW - }); - } + /** + * Part of the {@link Cesium3DTileContent} interface. <code>Empty3DTileContent</code> + * always returns <code>false</code> since a tile of this type does not have any features. + */ + Empty3DTileContent.prototype.hasProperty = function(batchId, name) { + return false; + }; - var vertexBufferTypedArray = getVertexBufferTypedArray(collection); - collection._vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : vertexBufferTypedArray, - usage : dynamic ? BufferUsage.STREAM_DRAW : BufferUsage.STATIC_DRAW - }); - } + /** + * Part of the {@link Cesium3DTileContent} interface. <code>Empty3DTileContent</code> + * always returns <code>undefined</code> since a tile of this type does not have any features. + */ + Empty3DTileContent.prototype.getFeature = function(batchId) { + return undefined; + }; - function updateVertexBuffer(collection) { - var vertexBufferTypedArray = getVertexBufferTypedArray(collection); - collection._vertexBuffer.copyFromArrayView(vertexBufferTypedArray); - } + /** + * @inheritdoc Cesium3DTileContent#applyDebugSettings + */ + Empty3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + }; - function createPickIds(collection, context) { - // PERFORMANCE_IDEA: we could skip the pick buffer completely by allocating - // a continuous range of pickIds and then converting the base pickId + batchId - // to RGBA in the shader. The only consider is precision issues, which might - // not be an issue in WebGL 2. - var instances = collection._instances; - var instancesLength = instances.length; - var pickIds = new Array(instancesLength); - for (var i = 0; i < instancesLength; ++i) { - pickIds[i] = context.createPickId(instances[i]); - } - return pickIds; - } + /** + * @inheritdoc Cesium3DTileContent#applyStyle + */ + Empty3DTileContent.prototype.applyStyle = function(frameState, style) { + }; - function createModel(collection, context) { - var instancingSupported = collection._instancingSupported; - var usesBatchTable = defined(collection._batchTable); - var allowPicking = collection._allowPicking; + /** + * @inheritdoc Cesium3DTileContent#update + */ + Empty3DTileContent.prototype.update = function(tileset, frameState) { + }; - var modelOptions = { - url : collection._url, - headers : collection._headers, - requestType : collection._requestType, - gltf : collection._gltf, - basePath : collection._basePath, - shadows : collection._shadows, - cacheKey : undefined, - asynchronous : collection._asynchronous, - allowPicking : allowPicking, - incrementallyLoadTextures : collection._incrementallyLoadTextures, - upAxis : collection._upAxis, - precreatedAttributes : undefined, - vertexShaderLoaded : undefined, - fragmentShaderLoaded : undefined, - uniformMapLoaded : undefined, - pickVertexShaderLoaded : undefined, - pickFragmentShaderLoaded : undefined, - pickUniformMapLoaded : undefined, - ignoreCommands : true, - opaquePass : collection._opaquePass - }; + /** + * @inheritdoc Cesium3DTileContent#isDestroyed + */ + Empty3DTileContent.prototype.isDestroyed = function() { + return false; + }; - if (allowPicking && !usesBatchTable) { - collection._pickIds = createPickIds(collection, context); - } + /** + * @inheritdoc Cesium3DTileContent#destroy + */ + Empty3DTileContent.prototype.destroy = function() { + return destroyObject(this); + }; - if (instancingSupported) { - createVertexBuffer(collection, context); + return Empty3DTileContent; +}); - var vertexSizeInFloats = 12; - var componentSizeInBytes = ComponentDatatype.getSizeInBytes(ComponentDatatype.FLOAT); +define('Scene/TileBoundingRegion',[ + '../Core/BoundingSphere', + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/Check', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/Ellipsoid', + '../Core/GeometryInstance', + '../Core/IntersectionTests', + '../Core/Matrix4', + '../Core/OrientedBoundingBox', + '../Core/Plane', + '../Core/Ray', + '../Core/Rectangle', + '../Core/RectangleOutlineGeometry', + './PerInstanceColorAppearance', + './Primitive', + './SceneMode' + ], function( + BoundingSphere, + Cartesian3, + Cartographic, + Check, + ColorGeometryInstanceAttribute, + defaultValue, + defineProperties, + Ellipsoid, + GeometryInstance, + IntersectionTests, + Matrix4, + OrientedBoundingBox, + Plane, + Ray, + Rectangle, + RectangleOutlineGeometry, + PerInstanceColorAppearance, + Primitive, + SceneMode) { + 'use strict'; - var instancedAttributes = { - czm_modelMatrixRow0 : { - index : 0, // updated in Model - vertexBuffer : collection._vertexBuffer, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - normalize : false, - offsetInBytes : 0, - strideInBytes : componentSizeInBytes * vertexSizeInFloats, - instanceDivisor : 1 - }, - czm_modelMatrixRow1 : { - index : 0, // updated in Model - vertexBuffer : collection._vertexBuffer, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - normalize : false, - offsetInBytes : componentSizeInBytes * 4, - strideInBytes : componentSizeInBytes * vertexSizeInFloats, - instanceDivisor : 1 - }, - czm_modelMatrixRow2 : { - index : 0, // updated in Model - vertexBuffer : collection._vertexBuffer, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - normalize : false, - offsetInBytes : componentSizeInBytes * 8, - strideInBytes : componentSizeInBytes * vertexSizeInFloats, - instanceDivisor : 1 - } - }; + /** + * A tile bounding volume specified as a longitude/latitude/height region. + * @alias TileBoundingRegion + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Rectangle} options.rectangle The rectangle specifying the longitude and latitude range of the region. + * @param {Number} [options.minimumHeight=0.0] The minimum height of the region. + * @param {Number} [options.maximumHeight=0.0] The maximum height of the region. + * @param {Ellipsoid} [options.ellipsoid=Cesium.Ellipsoid.WGS84] The ellipsoid. + * + * @private + */ + function TileBoundingRegion(options) { + Check.typeOf.object('options', options); + Check.typeOf.object('options.rectangle', options.rectangle); + + this.rectangle = Rectangle.clone(options.rectangle); + this.minimumHeight = defaultValue(options.minimumHeight, 0.0); + this.maximumHeight = defaultValue(options.maximumHeight, 0.0); - // When using a batch table, add a batch id attribute - if (usesBatchTable) { - instancedAttributes.a_batchId = { - index : 0, // updated in Model - vertexBuffer : collection._batchIdBuffer, - componentsPerAttribute : 1, - componentDatatype : ComponentDatatype.UNSIGNED_SHORT, - normalize : false, - offsetInBytes : 0, - strideInBytes : 0, - instanceDivisor : 1 - }; - } + /** + * The world coordinates of the southwest corner of the tile's rectangle. + * + * @type {Cartesian3} + * @default Cartesian3() + */ + this.southwestCornerCartesian = new Cartesian3(); - if (allowPicking && !usesBatchTable) { - instancedAttributes.pickColor = { - index : 0, // updated in Model - vertexBuffer : collection._pickIdBuffer, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - normalize : true, - offsetInBytes : 0, - strideInBytes : 0, - instanceDivisor : 1 - }; - } + /** + * The world coordinates of the northeast corner of the tile's rectangle. + * + * @type {Cartesian3} + * @default Cartesian3() + */ + this.northeastCornerCartesian = new Cartesian3(); - modelOptions.precreatedAttributes = instancedAttributes; - modelOptions.vertexShaderLoaded = getVertexShaderCallback(collection); - modelOptions.fragmentShaderLoaded = getFragmentShaderCallback(collection); - modelOptions.uniformMapLoaded = getUniformMapCallback(collection, context); - modelOptions.pickVertexShaderLoaded = getPickVertexShaderCallback(collection); - modelOptions.pickFragmentShaderLoaded = getPickFragmentShaderCallback(collection); - modelOptions.pickUniformMapLoaded = getPickUniformMapCallback(collection); + /** + * A normal that, along with southwestCornerCartesian, defines a plane at the western edge of + * the tile. Any position above (in the direction of the normal) this plane is outside the tile. + * + * @type {Cartesian3} + * @default Cartesian3() + */ + this.westNormal = new Cartesian3(); - if (defined(collection._url)) { - modelOptions.cacheKey = collection._url + '#instanced'; - } - } else { - modelOptions.vertexShaderLoaded = getVertexShaderNonInstancedCallback(collection); - modelOptions.fragmentShaderLoaded = getFragmentShaderCallback(collection); - modelOptions.uniformMapLoaded = getUniformMapNonInstancedCallback(collection, context); - modelOptions.pickVertexShaderLoaded = getPickVertexShaderNonInstancedCallback(collection); - modelOptions.pickFragmentShaderLoaded = getPickFragmentShaderNonInstancedCallback(collection); - modelOptions.pickUniformMapLoaded = getPickUniformMapCallback(collection); - } + /** + * A normal that, along with southwestCornerCartesian, defines a plane at the southern edge of + * the tile. Any position above (in the direction of the normal) this plane is outside the tile. + * Because points of constant latitude do not necessary lie in a plane, positions below this + * plane are not necessarily inside the tile, but they are close. + * + * @type {Cartesian3} + * @default Cartesian3() + */ + this.southNormal = new Cartesian3(); - if (defined(collection._url)) { - collection._model = Model.fromGltf(modelOptions); - } else { - collection._model = new Model(modelOptions); - } - } + /** + * A normal that, along with northeastCornerCartesian, defines a plane at the eastern edge of + * the tile. Any position above (in the direction of the normal) this plane is outside the tile. + * + * @type {Cartesian3} + * @default Cartesian3() + */ + this.eastNormal = new Cartesian3(); - function updateWireframe(collection) { - if (collection._debugWireframe !== collection.debugWireframe) { - collection._debugWireframe = collection.debugWireframe; + /** + * A normal that, along with northeastCornerCartesian, defines a plane at the eastern edge of + * the tile. Any position above (in the direction of the normal) this plane is outside the tile. + * Because points of constant latitude do not necessary lie in a plane, positions below this + * plane are not necessarily inside the tile, but they are close. + * + * @type {Cartesian3} + * @default Cartesian3() + */ + this.northNormal = new Cartesian3(); - // This assumes the original primitive was TRIANGLES and that the triangles - // are connected for the wireframe to look perfect. - var primitiveType = collection.debugWireframe ? PrimitiveType.LINES : PrimitiveType.TRIANGLES; - var commands = collection._drawCommands; - var length = commands.length; - for (var i = 0; i < length; ++i) { - commands[i].primitiveType = primitiveType; - } - } + var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + computeBox(this, options.rectangle, ellipsoid); + + // An oriented bounding box that encloses this tile's region. This is used to calculate tile visibility. + this._orientedBoundingBox = OrientedBoundingBox.fromRectangle(this.rectangle, this.minimumHeight, this.maximumHeight, ellipsoid); + + this._boundingSphere = BoundingSphere.fromOrientedBoundingBox(this._orientedBoundingBox); } - function updateShowBoundingVolume(collection) { - if (collection.debugShowBoundingVolume !== collection._debugShowBoundingVolume) { - collection._debugShowBoundingVolume = collection.debugShowBoundingVolume; - var commands = collection._drawCommands; - var length = commands.length; - for (var i = 0; i < length; ++i) { - commands[i].debugShowBoundingVolume = collection.debugShowBoundingVolume; + defineProperties(TileBoundingRegion.prototype, { + /** + * The underlying bounding volume + * + * @memberof TileBoundingRegion.prototype + * + * @type {Object} + * @readonly + */ + boundingVolume : { + get : function() { + return this._orientedBoundingBox; + } + }, + /** + * The underlying bounding sphere + * + * @memberof TileBoundingRegion.prototype + * + * @type {BoundingSphere} + * @readonly + */ + boundingSphere : { + get : function() { + return this._boundingSphere; } } - } + }); - function createCommands(collection, drawCommands, pickCommands) { - var commandsLength = drawCommands.length; - var instancesLength = collection.length; - var allowPicking = collection.allowPicking; - var boundingSphere = collection._boundingSphere; - var cull = collection._cull; + var cartesian3Scratch = new Cartesian3(); + var cartesian3Scratch2 = new Cartesian3(); + var cartesian3Scratch3 = new Cartesian3(); + var eastWestNormalScratch = new Cartesian3(); + var westernMidpointScratch = new Cartesian3(); + var easternMidpointScratch = new Cartesian3(); + var cartographicScratch = new Cartographic(); + var planeScratch = new Plane(Cartesian3.UNIT_X, 0.0); + var rayScratch = new Ray(); - for (var i = 0; i < commandsLength; ++i) { - var drawCommand = DrawCommand.shallowClone(drawCommands[i]); - drawCommand.instanceCount = instancesLength; - drawCommand.boundingVolume = boundingSphere; - drawCommand.cull = cull; - collection._drawCommands.push(drawCommand); + function computeBox(tileBB, rectangle, ellipsoid) { + ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle), tileBB.southwestCornerCartesian); + ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle), tileBB.northeastCornerCartesian); - if (allowPicking) { - var pickCommand = DrawCommand.shallowClone(pickCommands[i]); - pickCommand.instanceCount = instancesLength; - pickCommand.boundingVolume = boundingSphere; - pickCommand.cull = cull; - collection._pickCommands.push(pickCommand); - } - } - } + // The middle latitude on the western edge. + cartographicScratch.longitude = rectangle.west; + cartographicScratch.latitude = (rectangle.south + rectangle.north) * 0.5; + cartographicScratch.height = 0.0; + var westernMidpointCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, westernMidpointScratch); - function createBatchIdFunction(batchId) { - return function() { - return batchId; - }; - } + // Compute the normal of the plane on the western edge of the tile. + var westNormal = Cartesian3.cross(westernMidpointCartesian, Cartesian3.UNIT_Z, cartesian3Scratch); + Cartesian3.normalize(westNormal, tileBB.westNormal); - function createPickColorFunction(color) { - return function() { - return color; - }; - } + // The middle latitude on the eastern edge. + cartographicScratch.longitude = rectangle.east; + var easternMidpointCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, easternMidpointScratch); - function createCommandsNonInstanced(collection, drawCommands, pickCommands) { - // When instancing is disabled, create commands for every instance. - var instances = collection._instances; - var commandsLength = drawCommands.length; - var instancesLength = collection.length; - var allowPicking = collection.allowPicking; - var usesBatchTable = defined(collection._batchTable); - var cull = collection._cull; + // Compute the normal of the plane on the eastern edge of the tile. + var eastNormal = Cartesian3.cross(Cartesian3.UNIT_Z, easternMidpointCartesian, cartesian3Scratch); + Cartesian3.normalize(eastNormal, tileBB.eastNormal); - for (var i = 0; i < commandsLength; ++i) { - for (var j = 0; j < instancesLength; ++j) { - var drawCommand = DrawCommand.shallowClone(drawCommands[i]); - drawCommand.modelMatrix = new Matrix4(); // Updated in updateCommandsNonInstanced - drawCommand.boundingVolume = new BoundingSphere(); // Updated in updateCommandsNonInstanced - drawCommand.cull = cull; - drawCommand.uniformMap = clone(drawCommand.uniformMap); - if (usesBatchTable) { - drawCommand.uniformMap.a_batchId = createBatchIdFunction(instances[j]._instanceId); - } - collection._drawCommands.push(drawCommand); + // Compute the normal of the plane bounding the southern edge of the tile. + var westVector = Cartesian3.subtract(westernMidpointCartesian, easternMidpointCartesian, cartesian3Scratch); + var eastWestNormal = Cartesian3.normalize(westVector, eastWestNormalScratch); - if (allowPicking) { - var pickCommand = DrawCommand.shallowClone(pickCommands[i]); - pickCommand.modelMatrix = new Matrix4(); // Updated in updateCommandsNonInstanced - pickCommand.boundingVolume = new BoundingSphere(); // Updated in updateCommandsNonInstanced - pickCommand.cull = cull; - pickCommand.uniformMap = clone(pickCommand.uniformMap); - if (usesBatchTable) { - pickCommand.uniformMap.a_batchId = createBatchIdFunction(instances[j]._instanceId); - } else if (allowPicking) { - var pickId = collection._pickIds[j]; - pickCommand.uniformMap.czm_pickColor = createPickColorFunction(pickId.color); - } - collection._pickCommands.push(pickCommand); - } - } - } - } + var south = rectangle.south; + var southSurfaceNormal; - function updateCommandsNonInstanced(collection) { - var modelCommands = collection._modelCommands; - var commandsLength = modelCommands.length; - var instancesLength = collection.length; - var allowPicking = collection.allowPicking; - var collectionTransform = collection._rtcTransform; - var collectionCenter = collection._center; + if (south > 0.0) { + // Compute a plane that doesn't cut through the tile. + cartographicScratch.longitude = (rectangle.west + rectangle.east) * 0.5; + cartographicScratch.latitude = south; + var southCenterCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, rayScratch.origin); + Cartesian3.clone(eastWestNormal, rayScratch.direction); + var westPlane = Plane.fromPointNormal(tileBB.southwestCornerCartesian, tileBB.westNormal, planeScratch); + // Find a point that is on the west and the south planes + IntersectionTests.rayPlane(rayScratch, westPlane, tileBB.southwestCornerCartesian); + southSurfaceNormal = ellipsoid.geodeticSurfaceNormal(southCenterCartesian, cartesian3Scratch2); - for (var i = 0; i < commandsLength; ++i) { - var modelCommand = modelCommands[i]; - for (var j = 0; j < instancesLength; ++j) { - var commandIndex = i * instancesLength + j; - var drawCommand = collection._drawCommands[commandIndex]; - var instanceMatrix = Matrix4.clone(collection._instances[j]._modelMatrix, scratchMatrix); - instanceMatrix[12] -= collectionCenter.x; - instanceMatrix[13] -= collectionCenter.y; - instanceMatrix[14] -= collectionCenter.z; - instanceMatrix = Matrix4.multiply(collectionTransform, instanceMatrix, scratchMatrix); - var nodeMatrix = modelCommand.modelMatrix; - var modelMatrix = drawCommand.modelMatrix; - Matrix4.multiply(instanceMatrix, nodeMatrix, modelMatrix); + } else { + southSurfaceNormal = ellipsoid.geodeticSurfaceNormalCartographic(Rectangle.southeast(rectangle), cartesian3Scratch2); + } + var southNormal = Cartesian3.cross(southSurfaceNormal, westVector, cartesian3Scratch3); + Cartesian3.normalize(southNormal, tileBB.southNormal); - var nodeBoundingSphere = modelCommand.boundingVolume; - var boundingSphere = drawCommand.boundingVolume; - BoundingSphere.transform(nodeBoundingSphere, instanceMatrix, boundingSphere); + // Compute the normal of the plane bounding the northern edge of the tile. + var north = rectangle.north; + var northSurfaceNormal; + if (north < 0.0) { + // Compute a plane that doesn't cut through the tile. + cartographicScratch.longitude = (rectangle.west + rectangle.east) * 0.5; + cartographicScratch.latitude = north; + var northCenterCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, rayScratch.origin); + Cartesian3.negate(eastWestNormal, rayScratch.direction); + var eastPlane = Plane.fromPointNormal(tileBB.northeastCornerCartesian, tileBB.eastNormal, planeScratch); + // Find a point that is on the east and the north planes + IntersectionTests.rayPlane(rayScratch, eastPlane, tileBB.northeastCornerCartesian); + northSurfaceNormal = ellipsoid.geodeticSurfaceNormal(northCenterCartesian, cartesian3Scratch2); - if (allowPicking) { - var pickCommand = collection._pickCommands[commandIndex]; - Matrix4.clone(modelMatrix, pickCommand.modelMatrix); - BoundingSphere.clone(boundingSphere, pickCommand.boundingVolume); - } - } + } else { + northSurfaceNormal = ellipsoid.geodeticSurfaceNormalCartographic(Rectangle.northwest(rectangle), cartesian3Scratch2); } + var northNormal = Cartesian3.cross(westVector, northSurfaceNormal, cartesian3Scratch3); + Cartesian3.normalize(northNormal, tileBB.northNormal); } - function getModelCommands(model) { - var nodeCommands = model._nodeCommands; - var length = nodeCommands.length; + var southwestCornerScratch = new Cartesian3(); + var northeastCornerScratch = new Cartesian3(); + var negativeUnitY = new Cartesian3(0.0, -1.0, 0.0); + var negativeUnitZ = new Cartesian3(0.0, 0.0, -1.0); + var vectorScratch = new Cartesian3(); - var drawCommands = []; - var pickCommands = []; + /** + * Gets the distance from the camera to the closest point on the tile. This is used for level of detail selection. + * + * @param {FrameState} frameState The state information of the current rendering frame. + * @returns {Number} The distance from the camera to the closest point on the tile, in meters. + */ + TileBoundingRegion.prototype.distanceToCamera = function(frameState) { + Check.defined('frameState', frameState); + var camera = frameState.camera; + var cameraCartesianPosition = camera.positionWC; + var cameraCartographicPosition = camera.positionCartographic; - for (var i = 0; i < length; ++i) { - var nc = nodeCommands[i]; - if (nc.show) { - drawCommands.push(nc.command); - pickCommands.push(nc.pickCommand); + var result = 0.0; + if (!Rectangle.contains(this.rectangle, cameraCartographicPosition)) { + var southwestCornerCartesian = this.southwestCornerCartesian; + var northeastCornerCartesian = this.northeastCornerCartesian; + var westNormal = this.westNormal; + var southNormal = this.southNormal; + var eastNormal = this.eastNormal; + var northNormal = this.northNormal; + + if (frameState.mode !== SceneMode.SCENE3D) { + southwestCornerCartesian = frameState.mapProjection.project(Rectangle.southwest(this.rectangle), southwestCornerScratch); + southwestCornerCartesian.z = southwestCornerCartesian.y; + southwestCornerCartesian.y = southwestCornerCartesian.x; + southwestCornerCartesian.x = 0.0; + northeastCornerCartesian = frameState.mapProjection.project(Rectangle.northeast(this.rectangle), northeastCornerScratch); + northeastCornerCartesian.z = northeastCornerCartesian.y; + northeastCornerCartesian.y = northeastCornerCartesian.x; + northeastCornerCartesian.x = 0.0; + westNormal = negativeUnitY; + eastNormal = Cartesian3.UNIT_Y; + southNormal = negativeUnitZ; + northNormal = Cartesian3.UNIT_Z; } - } - return { - draw: drawCommands, - pick: pickCommands - }; - } + var vectorFromSouthwestCorner = Cartesian3.subtract(cameraCartesianPosition, southwestCornerCartesian, vectorScratch); + var distanceToWestPlane = Cartesian3.dot(vectorFromSouthwestCorner, westNormal); + var distanceToSouthPlane = Cartesian3.dot(vectorFromSouthwestCorner, southNormal); - function updateShadows(collection) { - if (collection.shadows !== collection._shadows) { - collection._shadows = collection.shadows; + var vectorFromNortheastCorner = Cartesian3.subtract(cameraCartesianPosition, northeastCornerCartesian, vectorScratch); + var distanceToEastPlane = Cartesian3.dot(vectorFromNortheastCorner, eastNormal); + var distanceToNorthPlane = Cartesian3.dot(vectorFromNortheastCorner, northNormal); - var castShadows = ShadowMode.castShadows(collection.shadows); - var receiveShadows = ShadowMode.receiveShadows(collection.shadows); + if (distanceToWestPlane > 0.0) { + result += distanceToWestPlane * distanceToWestPlane; + } else if (distanceToEastPlane > 0.0) { + result += distanceToEastPlane * distanceToEastPlane; + } - var drawCommands = collection._drawCommands; - var length = drawCommands.length; - for (var i = 0; i < length; ++i) { - var drawCommand = drawCommands[i]; - drawCommand.castShadows = castShadows; - drawCommand.receiveShadows = receiveShadows; + if (distanceToSouthPlane > 0.0) { + result += distanceToSouthPlane * distanceToSouthPlane; + } else if (distanceToNorthPlane > 0.0) { + result += distanceToNorthPlane * distanceToNorthPlane; } } - } - ModelInstanceCollection.prototype.update = function(frameState) { - if (frameState.mode === SceneMode.MORPHING) { - return; + var cameraHeight; + if (frameState.mode === SceneMode.SCENE3D) { + cameraHeight = cameraCartographicPosition.height; + } else { + cameraHeight = cameraCartesianPosition.x; } - if (!this.show) { - return; + var maximumHeight = frameState.mode === SceneMode.SCENE3D ? this.maximumHeight : 0.0; + var distanceFromTop = cameraHeight - maximumHeight; + if (distanceFromTop > 0.0) { + result += distanceFromTop * distanceFromTop; } - if (this.length === 0) { - return; - } + return Math.sqrt(result); + }; - var context = frameState.context; + /** + * Determines which side of a plane this box is located. + * + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is + * on the opposite side, and {@link Intersect.INTERSECTING} if the box + * intersects the plane. + */ + TileBoundingRegion.prototype.intersectPlane = function(plane) { + Check.defined('plane', plane); + return this._orientedBoundingBox.intersectPlane(plane); + }; - if (this._state === LoadState.NEEDS_LOAD) { - this._state = LoadState.LOADING; - this._instancingSupported = context.instancedArrays; - createModel(this, context); - var that = this; - this._model.readyPromise.otherwise(function(error) { - that._state = LoadState.FAILED; - that._readyPromise.reject(error); - }); - } + /** + * Creates a debug primitive that shows the outline of the tile bounding region. + * + * @param {Color} color The desired color of the primitive's mesh + * @return {Primitive} + * + * @private + */ + TileBoundingRegion.prototype.createDebugVolume = function(color) { + Check.defined('color', color); + + var modelMatrix = new Matrix4.clone(Matrix4.IDENTITY); + var geometry = new RectangleOutlineGeometry({ + rectangle : this.rectangle, + height : this.minimumHeight, + extrudedHeight: this.maximumHeight + }); + var instance = new GeometryInstance({ + geometry : geometry, + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(color) + } + }); - var instancingSupported = this._instancingSupported; - var model = this._model; - model.update(frameState); + return new Primitive({ + geometryInstances : instance, + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false + }); + }; - if (model.ready && (this._state === LoadState.LOADING)) { - this._state = LoadState.LOADED; - this._ready = true; + return TileBoundingRegion; +}); - // Expand bounding volume to fit the radius of the loaded model including the model's offset from the center - var modelRadius = model.boundingSphere.radius + Cartesian3.magnitude(model.boundingSphere.center); - this._boundingSphere.radius += modelRadius; +define('Scene/TileBoundingSphere',[ + '../Core/BoundingSphere', + '../Core/Cartesian3', + '../Core/Check', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defineProperties', + '../Core/GeometryInstance', + '../Core/Matrix4', + '../Core/SphereOutlineGeometry', + './PerInstanceColorAppearance', + './Primitive' + ], function( + BoundingSphere, + Cartesian3, + Check, + ColorGeometryInstanceAttribute, + defineProperties, + GeometryInstance, + Matrix4, + SphereOutlineGeometry, + PerInstanceColorAppearance, + Primitive) { + 'use strict'; - var modelCommands = getModelCommands(model); - this._modelCommands = modelCommands.draw; + /** + * A tile bounding volume specified as a sphere. + * @alias TileBoundingSphere + * @constructor + * + * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere. + * @param {Number} [radius=0.0] The radius of the bounding sphere. + * + * @private + */ + function TileBoundingSphere(center, radius) { + this._boundingSphere = new BoundingSphere(center, radius); + } - if (instancingSupported) { - createCommands(this, modelCommands.draw, modelCommands.pick); - } else { - createCommandsNonInstanced(this, modelCommands.draw, modelCommands.pick); - updateCommandsNonInstanced(this); + defineProperties(TileBoundingSphere.prototype, { + /** + * The center of the bounding sphere + * + * @memberof TileBoundingSphere.prototype + * + * @type {Cartesian3} + * @readonly + */ + center : { + get : function() { + return this._boundingSphere.center; } + }, - this._readyPromise.resolve(this); - return; - } + /** + * The radius of the bounding sphere + * + * @memberof TileBoundingSphere.prototype + * + * @type {Number} + * @readonly + */ + radius : { + get : function() { + return this._boundingSphere.radius; + } + }, - if (this._state !== LoadState.LOADED) { - return; + /** + * The underlying bounding volume + * + * @memberof TileBoundingSphere.prototype + * + * @type {Object} + * @readonly + */ + boundingVolume : { + get : function() { + return this._boundingSphere; + } + }, + /** + * The underlying bounding sphere + * + * @memberof TileBoundingSphere.prototype + * + * @type {BoundingSphere} + * @readonly + */ + boundingSphere : { + get : function() { + return this._boundingSphere; + } } + }); - var modeChanged = (frameState.mode !== this._mode); - var modelMatrix = this.modelMatrix; - var modelMatrixChanged = !Matrix4.equals(this._modelMatrix, modelMatrix); + /** + * Computes the distance between this bounding sphere and the camera attached to frameState. + * + * @param {FrameState} frameState The frameState to which the camera is attached. + * @returns {Number} The distance between the camera and the bounding sphere in meters. Returns 0 if the camera is inside the bounding volume. + * + */ + TileBoundingSphere.prototype.distanceToCamera = function(frameState) { + Check.defined('frameState', frameState); + var boundingSphere = this._boundingSphere; + return Math.max(0.0, Cartesian3.distance(boundingSphere.center, frameState.camera.positionWC) - boundingSphere.radius); + }; - if (modeChanged || modelMatrixChanged) { - this._mode = frameState.mode; - Matrix4.clone(modelMatrix, this._modelMatrix); - var rtcTransform = Matrix4.multiplyByTranslation(this._modelMatrix, this._center, this._rtcTransform); - if (this._mode !== SceneMode.SCENE3D) { - rtcTransform = Transforms.basisTo2D(frameState.mapProjection, rtcTransform, rtcTransform); - } - Matrix4.getTranslation(rtcTransform, this._boundingSphere.center); - } + /** + * Determines which side of a plane this sphere is located. + * + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is + * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere + * intersects the plane. + */ + TileBoundingSphere.prototype.intersectPlane = function(plane) { + Check.defined('plane', plane); + return BoundingSphere.intersectPlane(this._boundingSphere, plane); + }; - if (instancingSupported && this._dirty) { - // If at least one instance has moved assume the collection is now dynamic - this._dynamic = true; - this._dirty = false; + /** + * Update the bounding sphere after the tile is transformed. + * + * @param {Cartesian3} center The center of the bounding sphere. + * @param {Number} radius The radius of the bounding sphere. + */ + TileBoundingSphere.prototype.update = function(center, radius) { + Cartesian3.clone(center, this._boundingSphere.center); + this._boundingSphere.radius = radius; + }; - // PERFORMANCE_IDEA: only update dirty sub-sections instead of the whole collection - updateVertexBuffer(this); - } + /** + * Creates a debug primitive that shows the outline of the sphere. + * + * @param {Color} color The desired color of the primitive's mesh + * @return {Primitive} + */ + TileBoundingSphere.prototype.createDebugVolume = function(color) { + Check.defined('color', color); + var geometry = new SphereOutlineGeometry({ + radius: this.radius + }); + var modelMatrix = Matrix4.fromTranslation(this.center, new Matrix4.clone(Matrix4.IDENTITY)); + var instance = new GeometryInstance({ + geometry : geometry, + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(color) + } + }); - // If any node changes due to an animation, update the commands. This could be inefficient if the model is - // composed of many nodes and only one changes, however it is probably fine in the general use case. - // Only applies when instancing is disabled. The instanced shader automatically handles node transformations. - if (!instancingSupported && (model.dirty || this._dirty || modeChanged || modelMatrixChanged)) { - updateCommandsNonInstanced(this); - } + return new Primitive({ + geometryInstances : instance, + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false + }); + }; - updateShadows(this); - updateWireframe(this); - updateShowBoundingVolume(this); + return TileBoundingSphere; +}); - var passes = frameState.passes; - var commandList = frameState.commandList; - var commands = passes.render ? this._drawCommands : this._pickCommands; - var commandsLength = commands.length; +define('Scene/TileOrientedBoundingBox',[ + '../Core/BoundingSphere', + '../Core/BoxOutlineGeometry', + '../Core/Cartesian3', + '../Core/Check', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defineProperties', + '../Core/GeometryInstance', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/OrientedBoundingBox', + './PerInstanceColorAppearance', + './Primitive' + ], function( + BoundingSphere, + BoxOutlineGeometry, + Cartesian3, + Check, + ColorGeometryInstanceAttribute, + defineProperties, + GeometryInstance, + Matrix3, + Matrix4, + OrientedBoundingBox, + PerInstanceColorAppearance, + Primitive) { + 'use strict'; - for (var i = 0; i < commandsLength; ++i) { - commandList.push(commands[i]); + /** + * A tile bounding volume specified as an oriented bounding box. + * @alias TileOrientedBoundingBox + * @constructor + * + * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. + * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. + * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 + * cube centered at the origin. + * + * @private + */ + function TileOrientedBoundingBox(center, halfAxes) { + this._orientedBoundingBox = new OrientedBoundingBox(center, halfAxes); + this._boundingSphere = BoundingSphere.fromOrientedBoundingBox(this._orientedBoundingBox); + } + + defineProperties(TileOrientedBoundingBox.prototype, { + /** + * The underlying bounding volume. + * + * @memberof TileOrientedBoundingBox.prototype + * + * @type {Object} + * @readonly + */ + boundingVolume : { + get : function() { + return this._orientedBoundingBox; + } + }, + /** + * The underlying bounding sphere. + * + * @memberof TileOrientedBoundingBox.prototype + * + * @type {BoundingSphere} + * @readonly + */ + boundingSphere : { + get : function() { + return this._boundingSphere; + } } + }); + + /** + * Computes the distance between this bounding box and the camera attached to frameState. + * + * @param {FrameState} frameState The frameState to which the camera is attached. + * @returns {Number} The distance between the camera and the bounding box in meters. Returns 0 if the camera is inside the bounding volume. + */ + TileOrientedBoundingBox.prototype.distanceToCamera = function(frameState) { + Check.defined('frameState', frameState); + return Math.sqrt(this._orientedBoundingBox.distanceSquaredTo(frameState.camera.positionWC)); }; - ModelInstanceCollection.prototype.isDestroyed = function() { - return false; + /** + * Determines which side of a plane this box is located. + * + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is + * on the opposite side, and {@link Intersect.INTERSECTING} if the box + * intersects the plane. + */ + TileOrientedBoundingBox.prototype.intersectPlane = function(plane) { + Check.defined('plane', plane); + return this._orientedBoundingBox.intersectPlane(plane); }; - ModelInstanceCollection.prototype.destroy = function() { - this._model = this._model && this._model.destroy(); + /** + * Update the bounding box after the tile is transformed. + * + * @param {Cartesian3} center The center of the box. + * @param {Matrix3} halfAxes The three orthogonal half-axes of the bounding box. + * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 + * cube centered at the origin. + */ + TileOrientedBoundingBox.prototype.update = function(center, halfAxes) { + Cartesian3.clone(center, this._orientedBoundingBox.center); + Matrix3.clone(halfAxes, this._orientedBoundingBox.halfAxes); + BoundingSphere.fromOrientedBoundingBox(this._orientedBoundingBox, this._boundingSphere); + }; - var pickIds = this._pickIds; - if (defined(pickIds)) { - var length = pickIds.length; - for (var i = 0; i < length; ++i) { - pickIds[i].destroy(); + /** + * Creates a debug primitive that shows the outline of the box. + * + * @param {Color} color The desired color of the primitive's mesh + * @return {Primitive} + */ + TileOrientedBoundingBox.prototype.createDebugVolume = function(color) { + Check.defined('color', color); + + var geometry = new BoxOutlineGeometry({ + // Make a 2x2x2 cube + minimum: new Cartesian3(-1.0, -1.0, -1.0), + maximum: new Cartesian3(1.0, 1.0, 1.0) + }); + var modelMatrix = Matrix4.fromRotationTranslation(this.boundingVolume.halfAxes, this.boundingVolume.center); + var instance = new GeometryInstance({ + geometry : geometry, + modelMatrix : modelMatrix, + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(color) } - } + }); - return destroyObject(this); + return new Primitive({ + geometryInstances : instance, + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false + }); }; - return ModelInstanceCollection; + return TileOrientedBoundingBox; }); -define('Scene/Instanced3DModel3DTileContent',[ - '../Core/AttributeCompression', +define('Scene/Cesium3DTile',[ + '../Core/BoundingSphere', '../Core/Cartesian3', - '../Core/ClippingPlaneCollection', '../Core/Color', - '../Core/ComponentDatatype', + '../Core/CullingVolume', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/deprecationWarning', '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/FeatureDetection', - '../Core/getAbsoluteUri', - '../Core/getBaseUri', - '../Core/getStringFromTypedArray', - '../Core/joinUrls', + '../Core/getMagic', + '../Core/Intersect', + '../Core/JulianDate', '../Core/Matrix3', '../Core/Matrix4', - '../Core/Quaternion', + '../Core/Plane', + '../Core/Rectangle', + '../Core/Request', + '../Core/RequestScheduler', + '../Core/RequestState', '../Core/RequestType', + '../Core/Resource', '../Core/RuntimeError', - '../Core/Transforms', - '../Core/TranslationRotationScale', - '../Renderer/Pass', - './Cesium3DTileBatchTable', - './Cesium3DTileFeature', - './Cesium3DTileFeatureTable', - './ModelInstanceCollection' + '../ThirdParty/when', + './Cesium3DTileChildrenVisibility', + './Cesium3DTileContentFactory', + './Cesium3DTileContentState', + './Cesium3DTileOptimizationHint', + './Cesium3DTileRefine', + './Empty3DTileContent', + './SceneMode', + './TileBoundingRegion', + './TileBoundingSphere', + './TileOrientedBoundingBox' ], function( - AttributeCompression, + BoundingSphere, Cartesian3, - ClippingPlaneCollection, Color, - ComponentDatatype, + CullingVolume, defaultValue, defined, defineProperties, deprecationWarning, destroyObject, - DeveloperError, - Ellipsoid, - FeatureDetection, - getAbsoluteUri, - getBaseUri, - getStringFromTypedArray, - joinUrls, + getMagic, + Intersect, + JulianDate, Matrix3, Matrix4, - Quaternion, + Plane, + Rectangle, + Request, + RequestScheduler, + RequestState, RequestType, + Resource, RuntimeError, - Transforms, - TranslationRotationScale, - Pass, - Cesium3DTileBatchTable, - Cesium3DTileFeature, - Cesium3DTileFeatureTable, - ModelInstanceCollection) { + when, + Cesium3DTileChildrenVisibility, + Cesium3DTileContentFactory, + Cesium3DTileContentState, + Cesium3DTileOptimizationHint, + Cesium3DTileRefine, + Empty3DTileContent, + SceneMode, + TileBoundingRegion, + TileBoundingSphere, + TileOrientedBoundingBox) { 'use strict'; - // Bail out if the browser doesn't support typed arrays, to prevent the setup function - // from failing, since we won't be able to create a WebGL context anyway. - if (!FeatureDetection.supportsTypedArrays()) { - return {}; - } - /** - * Represents the contents of a - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Instanced3DModel/README.md|Instanced 3D Model} - * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. + * A tile in a {@link Cesium3DTileset}. When a tile is first created, its content is not loaded; + * the content is loaded on-demand when needed based on the view. * <p> - * Implements the {@link Cesium3DTileContent} interface. + * Do not construct this directly, instead access tiles through {@link Cesium3DTileset#tileVisible}. * </p> * - * @alias Instanced3DModel3DTileContent + * @alias Cesium3DTile * @constructor - * - * @private */ - function Instanced3DModel3DTileContent(tileset, tile, url, arrayBuffer, byteOffset) { + function Cesium3DTile(tileset, baseResource, header, parent) { this._tileset = tileset; - this._tile = tile; - this._url = url; - this._modelInstanceCollection = undefined; - this._batchTable = undefined; - this._features = undefined; + this._header = header; + var contentHeader = header.content; /** - * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + * The local transform of this tile + * @type {Matrix4} */ - this.featurePropertiesDirty = false; + this.transform = defined(header.transform) ? Matrix4.unpack(header.transform) : Matrix4.clone(Matrix4.IDENTITY); - initialize(this, arrayBuffer, byteOffset); + var parentTransform = defined(parent) ? parent.computedTransform : tileset.modelMatrix; + var computedTransform = Matrix4.multiply(parentTransform, this.transform, new Matrix4()); + + /** + * The final computed transform of this tile + * @type {Matrix4} + * @readonly + */ + this.computedTransform = computedTransform; + + this._boundingVolume = this.createBoundingVolume(header.boundingVolume, computedTransform); + this._boundingVolume2D = undefined; + + var contentBoundingVolume; + + if (defined(contentHeader) && defined(contentHeader.boundingVolume)) { + // Non-leaf tiles may have a content bounding-volume, which is a tight-fit bounding volume + // around only the features in the tile. This box is useful for culling for rendering, + // but not for culling for traversing the tree since it does not guarantee spatial coherence, i.e., + // since it only bounds features in the tile, not the entire tile, children may be + // outside of this box. + contentBoundingVolume = this.createBoundingVolume(contentHeader.boundingVolume, computedTransform); + } + this._contentBoundingVolume = contentBoundingVolume; + this._contentBoundingVolume2D = undefined; + + var viewerRequestVolume; + if (defined(header.viewerRequestVolume)) { + viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, computedTransform); + } + this._viewerRequestVolume = viewerRequestVolume; + + /** + * The error, in meters, introduced if this tile is rendered and its children are not. + * This is used to compute screen space error, i.e., the error measured in pixels. + * + * @type {Number} + * @readonly + */ + this.geometricError = header.geometricError; + + if (!defined(this.geometricError)) { + this.geometricError = defined(parent) ? parent.geometricError : tileset._geometricError; + Cesium3DTile._deprecationWarning('geometricErrorUndefined', 'Required property geometricError is undefined for this tile. Using parent\'s geometric error instead.'); + } + + var refine; + if (defined(header.refine)) { + if (header.refine === 'replace' || header.refine === 'add') { + Cesium3DTile._deprecationWarning('lowercase-refine', 'This tile uses a lowercase refine "' + header.refine + '". Instead use "' + header.refine.toUpperCase() + '".'); + } + refine = (header.refine.toUpperCase() === 'REPLACE') ? Cesium3DTileRefine.REPLACE : Cesium3DTileRefine.ADD; + } else if (defined(parent)) { + // Inherit from parent tile if omitted. + refine = parent.refine; + } else { + refine = Cesium3DTileRefine.REPLACE; + } + + /** + * Specifies the type of refinment that is used when traversing this tile for rendering. + * + * @type {Cesium3DTileRefine} + * @readonly + * @private + */ + this.refine = refine; + + /** + * Gets the tile's children. + * + * @type {Cesium3DTile[]} + * @readonly + */ + this.children = []; + + /** + * This tile's parent or <code>undefined</code> if this tile is the root. + * <p> + * When a tile's content points to an external tileset.json, the external tileset's + * root tile's parent is not <code>undefined</code>; instead, the parent references + * the tile (with its content pointing to an external tileset.json) as if the two tilesets were merged. + * </p> + * + * @type {Cesium3DTile} + * @readonly + */ + this.parent = parent; + + var content; + var hasEmptyContent; + var contentState; + var contentResource; + var serverKey; + + baseResource = Resource.createIfNeeded(baseResource); + + if (defined(contentHeader)) { + var contentHeaderUrl = contentHeader.url; + if (tileset._brokenUrlWorkaround && contentHeaderUrl.length > 0 && (contentHeaderUrl[0] === '/')) { + contentHeaderUrl = contentHeader.url = contentHeaderUrl.substring(1); + } + + hasEmptyContent = false; + contentState = Cesium3DTileContentState.UNLOADED; + contentResource = baseResource.getDerivedResource({ + url : contentHeaderUrl + }); + serverKey = RequestScheduler.getServerKey(contentResource.getUrlComponent()); + } else { + content = new Empty3DTileContent(tileset, this); + hasEmptyContent = true; + contentState = Cesium3DTileContentState.READY; + } + + this._content = content; + this._contentResource = contentResource; + this._contentState = contentState; + this._contentReadyToProcessPromise = undefined; + this._contentReadyPromise = undefined; + this._expiredContent = undefined; + + this._serverKey = serverKey; + + /** + * When <code>true</code>, the tile has no content. + * + * @type {Boolean} + * @readonly + * + * @private + */ + this.hasEmptyContent = hasEmptyContent; + + /** + * When <code>true</code>, the tile's content is renderable. + * <p> + * This is <code>false</code> until the tile's content is loaded. + * </p> + * + * @type {Boolean} + * @readonly + * + * @private + */ + this.hasRenderableContent = false; + + /** + * When <code>true</code>, the tile's content points to an external tileset. + * <p> + * This is <code>false</code> until the tile's content is loaded. + * </p> + * + * @type {Boolean} + * @readonly + * + * @private + */ + this.hasTilesetContent = false; + + /** + * The corresponding node in the cache replacement list. + * + * @type {DoublyLinkedListNode} + * @readonly + * + * @private + */ + this.replacementNode = undefined; + + var expire = header.expire; + var expireDuration; + var expireDate; + if (defined(expire)) { + expireDuration = expire.duration; + if (defined(expire.date)) { + expireDate = JulianDate.fromIso8601(expire.date); + } + } + + /** + * The time in seconds after the tile's content is ready when the content expires and new content is requested. + * + * @type {Number} + */ + this.expireDuration = expireDuration; + + /** + * The date when the content expires and new content is requested. + * + * @type {JulianDate} + */ + this.expireDate = expireDate; + + /** + * Marks if the tile is selected this frame. + * + * @type {Boolean} + * + * @private + */ + this.selected = false; + + /** + * The time when a style was last applied to this tile. + * + * @type {Number} + * + * @private + */ + this.lastStyleTime = 0; + + /** + * Marks whether the tile's children bounds are fully contained within the tile's bounds + * + * @type {Cesium3DTileOptimizationHint} + * + * @private + */ + this._optimChildrenWithinParent = Cesium3DTileOptimizationHint.NOT_COMPUTED; + + // Members that are updated every frame for tree traversal and rendering optimizations: + this._distanceToCamera = 0; + this._visibilityPlaneMask = 0; + this._childrenVisibility = Cesium3DTileChildrenVisibility.VISIBLE; + this._lastSelectedFrameNumber = -1; + this._screenSpaceError = 0; + this._screenSpaceErrorComputedFrame = -1; + this._finalResolution = true; + this._depth = 0; + this._centerZDepth = 0; + this._stackLength = 0; + this._selectedFrame = -1; + this._selectionDepth = 0; + this._lastSelectionDepth = undefined; + this._requestedFrame = undefined; + this._lastVisitedFrame = undefined; + this._ancestorWithContent = undefined; + this._ancestorWithLoadedContent = undefined; + this._isClipped = true; + + this._debugBoundingVolume = undefined; + this._debugContentBoundingVolume = undefined; + this._debugViewerRequestVolume = undefined; + this._debugColor = Color.fromRandom({ alpha : 1.0 }); + this._debugColorizeTiles = false; + + this._commandsLength = 0; + + this._color = undefined; + this._colorDirty = false; } // This can be overridden for testing purposes - Instanced3DModel3DTileContent._deprecationWarning = deprecationWarning; + Cesium3DTile._deprecationWarning = deprecationWarning; - defineProperties(Instanced3DModel3DTileContent.prototype, { + defineProperties(Cesium3DTile.prototype, { /** - * @inheritdoc Cesium3DTileContent#featuresLength + * The tileset containing this tile. + * + * @memberof Cesium3DTile.prototype + * + * @type {Cesium3DTileset} + * @readonly */ - featuresLength : { + tileset : { get : function() { - return this._batchTable.featuresLength; + return this._tileset; } }, /** - * @inheritdoc Cesium3DTileContent#pointsLength + * The tile's content. This represents the actual tile's payload, + * not the content's metadata in tileset.json. + * + * @memberof Cesium3DTile.prototype + * + * @type {Cesium3DTileContent} + * @readonly */ - pointsLength : { + content : { get : function() { - return 0; + return this._content; } }, /** - * @inheritdoc Cesium3DTileContent#trianglesLength + * Get the bounding volume of the tile's contents. This defaults to the + * tile's bounding volume when the content's bounding volume is + * <code>undefined</code>. + * + * @memberof Cesium3DTile.prototype + * + * @type {TileBoundingVolume} + * @readonly + * @private */ - trianglesLength : { + contentBoundingVolume : { get : function() { - var model = this._modelInstanceCollection._model; - if (defined(model)) { - return model.trianglesLength; - } - return 0; + return defaultValue(this._contentBoundingVolume, this._boundingVolume); } }, /** - * @inheritdoc Cesium3DTileContent#geometryByteLength + * Get the bounding sphere derived from the tile's bounding volume. + * + * @memberof Cesium3DTile.prototype + * + * @type {BoundingSphere} + * @readonly */ - geometryByteLength : { + boundingSphere : { get : function() { - var model = this._modelInstanceCollection._model; - if (defined(model)) { - return model.geometryByteLength; - } - return 0; + return this._boundingVolume.boundingSphere; } }, /** - * @inheritdoc Cesium3DTileContent#texturesByteLength + * Gets or sets the tile's highlight color. + * + * @memberof Cesium3DTile.prototype + * + * @type {Color} + * + * @default {@link Color.WHITE} + * + * @private */ - texturesByteLength : { + color : { get : function() { - var model = this._modelInstanceCollection._model; - if (defined(model)) { - return model.texturesByteLength; + if (!defined(this._color)) { + this._color = new Color(); } - return 0; + return Color.clone(this._color); + }, + set : function(value) { + this._color = Color.clone(value, this._color); + this._colorDirty = true; } }, /** - * @inheritdoc Cesium3DTileContent#batchTableByteLength + * Determines if the tile has available content to render. <code>true</code> if the tile's + * content is ready or if it has expired content that renders while new content loads; otherwise, + * <code>false</code>. + * + * @memberof Cesium3DTile.prototype + * + * @type {Boolean} + * @readonly + * + * @private */ - batchTableByteLength : { + contentAvailable : { get : function() { - return this._batchTable.memorySizeInBytes; + return this.contentReady || (defined(this._expiredContent) && this._contentState !== Cesium3DTileContentState.FAILED); } }, /** - * @inheritdoc Cesium3DTileContent#innerContents + * Determines if the tile is ready to render. <code>true</code> if the tile + * is ready to render; otherwise, <code>false</code>. + * + * @memberof Cesium3DTile.prototype + * + * @type {Boolean} + * @readonly + * + * @private */ - innerContents : { + contentReady : { get : function() { - return undefined; + return this._contentState === Cesium3DTileContentState.READY; } }, /** - * @inheritdoc Cesium3DTileContent#readyPromise + * Determines if the tile's content has not be requested. <code>true</code> if tile's + * content has not be requested; otherwise, <code>false</code>. + * + * @memberof Cesium3DTile.prototype + * + * @type {Boolean} + * @readonly + * + * @private */ - readyPromise : { + contentUnloaded : { get : function() { - return this._modelInstanceCollection.readyPromise; + return this._contentState === Cesium3DTileContentState.UNLOADED; } }, /** - * @inheritdoc Cesium3DTileContent#tileset + * Determines if the tile's content is expired. <code>true</code> if tile's + * content is expired; otherwise, <code>false</code>. + * + * @memberof Cesium3DTile.prototype + * + * @type {Boolean} + * @readonly + * + * @private */ - tileset : { + contentExpired : { get : function() { - return this._tileset; + return this._contentState === Cesium3DTileContentState.EXPIRED; } }, /** - * @inheritdoc Cesium3DTileContent#tile + * Gets the promise that will be resolved when the tile's content is ready to process. + * This happens after the content is downloaded but before the content is ready + * to render. + * <p> + * The promise remains <code>undefined</code> until the tile's content is requested. + * </p> + * + * @type {Promise.<Cesium3DTileContent>} + * @readonly + * + * @private */ - tile : { + contentReadyToProcessPromise : { get : function() { - return this._tile; + if (defined(this._contentReadyToProcessPromise)) { + return this._contentReadyToProcessPromise.promise; + } } }, /** - * @inheritdoc Cesium3DTileContent#url + * Gets the promise that will be resolved when the tile's content is ready to render. + * <p> + * The promise remains <code>undefined</code> until the tile's content is requested. + * </p> + * + * @type {Promise.<Cesium3DTileContent>} + * @readonly + * + * @private */ - url: { - get: function() { - return this._url; + contentReadyPromise : { + get : function() { + if (defined(this._contentReadyPromise)) { + return this._contentReadyPromise.promise; + } } }, /** - * @inheritdoc Cesium3DTileContent#batchTable + * Returns the number of draw commands used by this tile. + * + * @readonly + * + * @private */ - batchTable : { + commandsLength : { get : function() { - return this._batchTable; + return this._commandsLength; } } }); - var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - var propertyScratch1 = new Array(4); - var propertyScratch2 = new Array(4); + var scratchJulianDate = new JulianDate(); - function initialize(content, arrayBuffer, byteOffset) { - var byteStart = defaultValue(byteOffset, 0); - byteOffset = byteStart; + /** + * Update whether the tile has expired. + * + * @private + */ + Cesium3DTile.prototype.updateExpiration = function() { + if (defined(this.expireDate) && this.contentReady && !this.hasEmptyContent) { + var now = JulianDate.now(scratchJulianDate); + if (JulianDate.lessThan(this.expireDate, now)) { + this._contentState = Cesium3DTileContentState.EXPIRED; + this._expiredContent = this._content; + } + } + }; - var uint8Array = new Uint8Array(arrayBuffer); - var view = new DataView(arrayBuffer); - byteOffset += sizeOfUint32; // Skip magic + function updateExpireDate(tile) { + if (defined(tile.expireDuration)) { + var expireDurationDate = JulianDate.now(scratchJulianDate); + JulianDate.addSeconds(expireDurationDate, tile.expireDuration, expireDurationDate); - var version = view.getUint32(byteOffset, true); - if (version !== 1) { - throw new RuntimeError('Only Instanced 3D Model version 1 is supported. Version ' + version + ' is not.'); + if (defined(tile.expireDate)) { + if (JulianDate.lessThan(tile.expireDate, expireDurationDate)) { + JulianDate.clone(expireDurationDate, tile.expireDate); + } + } else { + tile.expireDate = JulianDate.clone(expireDurationDate); + } } - byteOffset += sizeOfUint32; + } - var byteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; + function getContentFailedFunction(tile) { + return function(error) { + tile._contentState = Cesium3DTileContentState.FAILED; + tile._contentReadyPromise.reject(error); + tile._contentReadyToProcessPromise.reject(error); + }; + } - var featureTableJsonByteLength = view.getUint32(byteOffset, true); - if (featureTableJsonByteLength === 0) { - throw new RuntimeError('featureTableJsonByteLength is zero, the feature table must be defined.'); + function createPriorityFunction(tile) { + return function() { + return tile._distanceToCamera; + }; + } + + /** + * Requests the tile's content. + * <p> + * The request may not be made if the Cesium Request Scheduler can't prioritize it. + * </p> + * + * @private + */ + Cesium3DTile.prototype.requestContent = function() { + var that = this; + var tileset = this._tileset; + + if (this.hasEmptyContent) { + return false; } - byteOffset += sizeOfUint32; - var featureTableBinaryByteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; + var resource = this._contentResource.clone(); + var expired = this.contentExpired; + if (expired) { + // Append a query parameter of the tile expiration date to prevent caching + resource.addQueryParameters({ + expired: this.expireDate.toString() + }); + } - var batchTableJsonByteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; + var request = new Request({ + throttle : true, + throttleByServer : true, + type : RequestType.TILES3D, + priorityFunction : createPriorityFunction(this), + serverKey : this._serverKey + }); - var batchTableBinaryByteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; + resource.request = request; - var gltfFormat = view.getUint32(byteOffset, true); - if (gltfFormat !== 1 && gltfFormat !== 0) { - throw new RuntimeError('Only glTF format 0 (uri) or 1 (embedded) are supported. Format ' + gltfFormat + ' is not.'); + var promise = resource.fetchArrayBuffer(); + + if (!defined(promise)) { + return false; } - byteOffset += sizeOfUint32; - var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength); - var featureTableJson = JSON.parse(featureTableString); - byteOffset += featureTableJsonByteLength; + var contentState = this._contentState; + this._contentState = Cesium3DTileContentState.LOADING; + this._contentReadyToProcessPromise = when.defer(); + this._contentReadyPromise = when.defer(); - var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); - byteOffset += featureTableBinaryByteLength; + if (expired) { + this.expireDate = undefined; + } - var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); - var instancesLength = featureTable.getGlobalProperty('INSTANCES_LENGTH'); - featureTable.featuresLength = instancesLength; + var contentFailedFunction = getContentFailedFunction(this); - if (!defined(instancesLength)) { - throw new RuntimeError('Feature table global property: INSTANCES_LENGTH must be defined'); + promise.then(function(arrayBuffer) { + if (that.isDestroyed()) { + // Tile is unloaded before the content finishes loading + contentFailedFunction(); + return; + } + var uint8Array = new Uint8Array(arrayBuffer); + var magic = getMagic(uint8Array); + var contentFactory = Cesium3DTileContentFactory[magic]; + var content; + + // Vector and Geometry tile rendering do not support the skip LOD optimization. + tileset._disableSkipLevelOfDetail = tileset._disableSkipLevelOfDetail || magic === 'vctr' || magic === 'geom'; + + if (defined(contentFactory)) { + content = contentFactory(tileset, that, that._contentResource, arrayBuffer, 0); + that.hasRenderableContent = true; + } else { + // The content may be json instead + content = Cesium3DTileContentFactory.json(tileset, that, that._contentResource, arrayBuffer, 0); + that.hasTilesetContent = true; + } + + that._content = content; + that._contentState = Cesium3DTileContentState.PROCESSING; + that._contentReadyToProcessPromise.resolve(content); + + return content.readyPromise.then(function(content) { + if (that.isDestroyed()) { + // Tile is unloaded before the content finishes processing + contentFailedFunction(); + return; + } + updateExpireDate(that); + + // Refresh style for expired content + that.lastStyleTime = 0; + + that._contentState = Cesium3DTileContentState.READY; + that._contentReadyPromise.resolve(content); + }); + }).otherwise(function(error) { + if (request.state === RequestState.CANCELLED) { + // Cancelled due to low priority - try again later. + that._contentState = contentState; + --tileset.statistics.numberOfPendingRequests; + ++tileset.statistics.numberOfAttemptedRequests; + return; + } + contentFailedFunction(error); + }); + + return true; + }; + + /** + * Unloads the tile's content. + * + * @private + */ + Cesium3DTile.prototype.unloadContent = function() { + if (!this.hasRenderableContent) { + return; } - var batchTableJson; - var batchTableBinary; - if (batchTableJsonByteLength > 0) { - var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength); - batchTableJson = JSON.parse(batchTableString); - byteOffset += batchTableJsonByteLength; + this._content = this._content && this._content.destroy(); + this._contentState = Cesium3DTileContentState.UNLOADED; + this._contentReadyToProcessPromise = undefined; + this._contentReadyPromise = undefined; - if (batchTableBinaryByteLength > 0) { - // Has a batch table binary - batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); - // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed - batchTableBinary = new Uint8Array(batchTableBinary); - byteOffset += batchTableBinaryByteLength; + this.replacementNode = undefined; + + this.lastStyleTime = 0; + + this._debugColorizeTiles = false; + + this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); + this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); + this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); + }; + + var scratchProjectedBoundingSphere = new BoundingSphere(); + + function getBoundingVolume(tile, frameState) { + if (frameState.mode !== SceneMode.SCENE3D && !defined(tile._boundingVolume2D)) { + var boundingSphere = tile._boundingVolume.boundingSphere; + var sphere = BoundingSphere.projectTo2D(boundingSphere, frameState.mapProjection, scratchProjectedBoundingSphere); + tile._boundingVolume2D = new TileBoundingSphere(sphere.center, sphere.radius); + } + + return frameState.mode !== SceneMode.SCENE3D ? tile._boundingVolume2D : tile._boundingVolume; + } + + function getContentBoundingVolume(tile, frameState) { + if (frameState.mode !== SceneMode.SCENE3D && !defined(tile._contentBoundingVolume2D)) { + var boundingSphere = tile._contentBoundingVolume.boundingSphere; + var sphere = BoundingSphere.projectTo2D(boundingSphere, frameState.mapProjection, scratchProjectedBoundingSphere); + tile._contentBoundingVolume2D = new TileBoundingSphere(sphere.center, sphere.radius); + } + return frameState.mode !== SceneMode.SCENE3D ? tile._contentBoundingVolume2D : tile._contentBoundingVolume; + } + + /** + * Determines whether the tile's bounding volume intersects the culling volume. + * + * @param {FrameState} frameState The frame state. + * @param {Number} parentVisibilityPlaneMask The parent's plane mask to speed up the visibility check. + * @returns {Number} A plane mask as described above in {@link CullingVolume#computeVisibilityWithPlaneMask}. + * + * @private + */ + Cesium3DTile.prototype.visibility = function(frameState, parentVisibilityPlaneMask) { + var cullingVolume = frameState.cullingVolume; + var boundingVolume = getBoundingVolume(this, frameState); + + var tileset = this._tileset; + var clippingPlanes = tileset.clippingPlanes; + if (defined(clippingPlanes) && clippingPlanes.enabled) { + var tileTransform = tileset._root.computedTransform; + var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); + this._isClipped = intersection !== Intersect.INSIDE; + if (intersection === Intersect.OUTSIDE) { + return CullingVolume.MASK_OUTSIDE; } } - content._batchTable = new Cesium3DTileBatchTable(content, instancesLength, batchTableJson, batchTableBinary); + return cullingVolume.computeVisibilityWithPlaneMask(boundingVolume, parentVisibilityPlaneMask); + }; - var gltfByteLength = byteStart + byteLength - byteOffset; - if (gltfByteLength === 0) { - throw new RuntimeError('glTF byte length is zero, i3dm must have a glTF to instance.'); + /** + * Assuming the tile's bounding volume intersects the culling volume, determines + * whether the tile's content's bounding volume intersects the culling volume. + * + * @param {FrameState} frameState The frame state. + * @returns {Intersect} The result of the intersection: the tile's content is completely outside, completely inside, or intersecting the culling volume. + * + * @private + */ + Cesium3DTile.prototype.contentVisibility = function(frameState) { + // Assumes the tile's bounding volume intersects the culling volume already, so + // just return Intersect.INSIDE if there is no content bounding volume. + if (!defined(this._contentBoundingVolume)) { + return Intersect.INSIDE; } - var gltfView; - if (byteOffset % 4 === 0) { - gltfView = new Uint8Array(arrayBuffer, byteOffset, gltfByteLength); - } else { - // Create a copy of the glb so that it is 4-byte aligned - Instanced3DModel3DTileContent._deprecationWarning('i3dm-glb-unaligned', 'The embedded glb is not aligned to a 4-byte boundary.'); - gltfView = new Uint8Array(uint8Array.subarray(byteOffset, byteOffset + gltfByteLength)); + // PERFORMANCE_IDEA: is it possible to burn less CPU on this test since we know the + // tile's (not the content's) bounding volume intersects the culling volume? + var cullingVolume = frameState.cullingVolume; + var boundingVolume = getContentBoundingVolume(this, frameState); + + var tileset = this._tileset; + var clippingPlanes = tileset.clippingPlanes; + if (defined(clippingPlanes) && clippingPlanes.enabled) { + var tileTransform = tileset._root.computedTransform; + var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); + this._isClipped = intersection !== Intersect.INSIDE; + if (intersection === Intersect.OUTSIDE) { + return Intersect.OUTSIDE; + } } - // Create model instance collection - var collectionOptions = { - instances : new Array(instancesLength), - batchTable : content._batchTable, - cull : false, // Already culled by 3D Tiles - url : undefined, - requestType : RequestType.TILES3D, - gltf : undefined, - basePath : undefined, - incrementallyLoadTextures : false, - upAxis : content._tileset._gltfUpAxis, - opaquePass : Pass.CESIUM_3D_TILE // Draw opaque portions during the 3D Tiles pass - }; + return cullingVolume.computeVisibility(boundingVolume); + }; - if (gltfFormat === 0) { - var gltfUrl = getStringFromTypedArray(gltfView); + /** + * Computes the (potentially approximate) distance from the closest point of the tile's bounding volume to the camera. + * + * @param {FrameState} frameState The frame state. + * @returns {Number} The distance, in meters, or zero if the camera is inside the bounding volume. + * + * @private + */ + Cesium3DTile.prototype.distanceToTile = function(frameState) { + var boundingVolume = getBoundingVolume(this, frameState); + return boundingVolume.distanceToCamera(frameState); + }; - // We need to remove padding from the end of the model URL in case this tile was part of a composite tile. - // This removes all white space and null characters from the end of the string. - gltfUrl = gltfUrl.replace(/[\s\0]+$/, ''); - collectionOptions.url = getAbsoluteUri(joinUrls(getBaseUri(content._url, true), gltfUrl)); - } else { - collectionOptions.gltf = gltfView; - collectionOptions.basePath = getAbsoluteUri(getBaseUri(content._url, true)); + var scratchToTileCenter = new Cartesian3(); + + /** + * Computes the distance from the center of the tile's bounding volume to the camera. + * + * @param {FrameState} frameState The frame state. + * @returns {Number} The distance, in meters, or zero if the camera is inside the bounding volume. + * + * @private + */ + Cesium3DTile.prototype.distanceToTileCenter = function(frameState) { + var tileBoundingVolume = getBoundingVolume(this, frameState); + var boundingVolume = tileBoundingVolume.boundingVolume; // Gets the underlying OrientedBoundingBox or BoundingSphere + var toCenter = Cartesian3.subtract(boundingVolume.center, frameState.camera.positionWC, scratchToTileCenter); + var distance = Cartesian3.magnitude(toCenter); + Cartesian3.divideByScalar(toCenter, distance, toCenter); + var dot = Cartesian3.dot(frameState.camera.directionWC, toCenter); + return distance * dot; + }; + + /** + * Checks if the camera is inside the viewer request volume. + * + * @param {FrameState} frameState The frame state. + * @returns {Boolean} Whether the camera is inside the volume. + * + * @private + */ + Cesium3DTile.prototype.insideViewerRequestVolume = function(frameState) { + var viewerRequestVolume = this._viewerRequestVolume; + return !defined(viewerRequestVolume) || (viewerRequestVolume.distanceToCamera(frameState) === 0.0); + }; + + var scratchMatrix = new Matrix3(); + var scratchScale = new Cartesian3(); + var scratchHalfAxes = new Matrix3(); + var scratchCenter = new Cartesian3(); + var scratchRectangle = new Rectangle(); + + function createBox(box, transform, result) { + var center = Cartesian3.fromElements(box[0], box[1], box[2], scratchCenter); + var halfAxes = Matrix3.fromArray(box, 3, scratchHalfAxes); + + // Find the transformed center and halfAxes + center = Matrix4.multiplyByPoint(transform, center, center); + var rotationScale = Matrix4.getRotation(transform, scratchMatrix); + halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes); + + if (defined(result)) { + result.update(center, halfAxes); + return result; } + return new TileOrientedBoundingBox(center, halfAxes); + } - var eastNorthUp = featureTable.getGlobalProperty('EAST_NORTH_UP'); + function createRegion(region, result) { + var rectangleRegion = Rectangle.unpack(region, 0, scratchRectangle); - var rtcCenter; - var rtcCenterArray = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); - if (defined(rtcCenterArray)) { - rtcCenter = Cartesian3.unpack(rtcCenterArray); + if (defined(result)) { + // Don't update regions when the transform changes + return result; } + return new TileBoundingRegion({ + rectangle : rectangleRegion, + minimumHeight : region[4], + maximumHeight : region[5] + }); + } - var instances = collectionOptions.instances; - var instancePosition = new Cartesian3(); - var instancePositionArray = new Array(3); - var instanceNormalRight = new Cartesian3(); - var instanceNormalUp = new Cartesian3(); - var instanceNormalForward = new Cartesian3(); - var instanceRotation = new Matrix3(); - var instanceQuaternion = new Quaternion(); - var instanceScale = new Cartesian3(); - var instanceTranslationRotationScale = new TranslationRotationScale(); - var instanceTransform = new Matrix4(); - for (var i = 0; i < instancesLength; i++) { - // Get the instance position - var position = featureTable.getProperty('POSITION', ComponentDatatype.FLOAT, 3, i, propertyScratch1); - if (!defined(position)) { - position = instancePositionArray; - var positionQuantized = featureTable.getProperty('POSITION_QUANTIZED', ComponentDatatype.UNSIGNED_SHORT, 3, i, propertyScratch1); - if (!defined(positionQuantized)) { - throw new RuntimeError('Either POSITION or POSITION_QUANTIZED must be defined for each instance.'); - } - var quantizedVolumeOffset = featureTable.getGlobalProperty('QUANTIZED_VOLUME_OFFSET', ComponentDatatype.FLOAT, 3); - if (!defined(quantizedVolumeOffset)) { - throw new RuntimeError('Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.'); - } - var quantizedVolumeScale = featureTable.getGlobalProperty('QUANTIZED_VOLUME_SCALE', ComponentDatatype.FLOAT, 3); - if (!defined(quantizedVolumeScale)) { - throw new RuntimeError('Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.'); - } - for (var j = 0; j < 3; j++) { - position[j] = (positionQuantized[j] / 65535.0 * quantizedVolumeScale[j]) + quantizedVolumeOffset[j]; - } - } - Cartesian3.unpack(position, 0, instancePosition); - if (defined(rtcCenter)) { - Cartesian3.add(instancePosition, rtcCenter, instancePosition); - } - instanceTranslationRotationScale.translation = instancePosition; + function createSphere(sphere, transform, result) { + var center = Cartesian3.fromElements(sphere[0], sphere[1], sphere[2], scratchCenter); + var radius = sphere[3]; + + // Find the transformed center and radius + center = Matrix4.multiplyByPoint(transform, center, center); + var scale = Matrix4.getScale(transform, scratchScale); + var uniformScale = Cartesian3.maximumComponent(scale); + radius *= uniformScale; + + if (defined(result)) { + result.update(center, radius); + return result; + } + return new TileBoundingSphere(center, radius); + } + + /** + * Create a bounding volume from the tile's bounding volume header. + * + * @param {Object} boundingVolumeHeader The tile's bounding volume header. + * @param {Matrix4} transform The transform to apply to the bounding volume. + * @param {TileBoundingVolume} [result] The object onto which to store the result. + * + * @returns {TileBoundingVolume} The modified result parameter or a new TileBoundingVolume instance if none was provided. + * + * @private + */ + Cesium3DTile.prototype.createBoundingVolume = function(boundingVolumeHeader, transform, result) { + if (!defined(boundingVolumeHeader)) { + throw new RuntimeError('boundingVolume must be defined'); + } + if (defined(boundingVolumeHeader.box)) { + return createBox(boundingVolumeHeader.box, transform, result); + } + if (defined(boundingVolumeHeader.region)) { + return createRegion(boundingVolumeHeader.region, result); + } + if (defined(boundingVolumeHeader.sphere)) { + return createSphere(boundingVolumeHeader.sphere, transform, result); + } + throw new RuntimeError('boundingVolume must contain a sphere, region, or box'); + }; + + var scratchTransform = new Matrix4(); + + /** + * Update the tile's transform. The transform is applied to the tile's bounding volumes. + * + * @private + */ + Cesium3DTile.prototype.updateTransform = function(parentTransform) { + parentTransform = defaultValue(parentTransform, Matrix4.IDENTITY); + var computedTransform = Matrix4.multiply(parentTransform, this.transform, scratchTransform); + var transformChanged = !Matrix4.equals(computedTransform, this.computedTransform); + + if (!transformChanged) { + return; + } + + Matrix4.clone(computedTransform, this.computedTransform); + + // Update the bounding volumes + var header = this._header; + var content = this._header.content; + this._boundingVolume = this.createBoundingVolume(header.boundingVolume, computedTransform, this._boundingVolume); + if (defined(this._contentBoundingVolume)) { + this._contentBoundingVolume = this.createBoundingVolume(content.boundingVolume, computedTransform, this._contentBoundingVolume); + } + if (defined(this._viewerRequestVolume)) { + this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, computedTransform, this._viewerRequestVolume); + } + + // Destroy the debug bounding volumes. They will be generated fresh. + this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); + this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); + this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); + }; - // Get the instance rotation - var normalUp = featureTable.getProperty('NORMAL_UP', ComponentDatatype.FLOAT, 3, i, propertyScratch1); - var normalRight = featureTable.getProperty('NORMAL_RIGHT', ComponentDatatype.FLOAT, 3, i, propertyScratch2); - var hasCustomOrientation = false; - if (defined(normalUp)) { - if (!defined(normalRight)) { - throw new RuntimeError('To define a custom orientation, both NORMAL_UP and NORMAL_RIGHT must be defined.'); - } - Cartesian3.unpack(normalUp, 0, instanceNormalUp); - Cartesian3.unpack(normalRight, 0, instanceNormalRight); - hasCustomOrientation = true; - } else { - var octNormalUp = featureTable.getProperty('NORMAL_UP_OCT32P', ComponentDatatype.UNSIGNED_SHORT, 2, i, propertyScratch1); - var octNormalRight = featureTable.getProperty('NORMAL_RIGHT_OCT32P', ComponentDatatype.UNSIGNED_SHORT, 2, i, propertyScratch2); - if (defined(octNormalUp)) { - if (!defined(octNormalRight)) { - throw new RuntimeError('To define a custom orientation with oct-encoded vectors, both NORMAL_UP_OCT32P and NORMAL_RIGHT_OCT32P must be defined.'); - } - AttributeCompression.octDecodeInRange(octNormalUp[0], octNormalUp[1], 65535, instanceNormalUp); - AttributeCompression.octDecodeInRange(octNormalRight[0], octNormalRight[1], 65535, instanceNormalRight); - hasCustomOrientation = true; - } else if (eastNorthUp) { - Transforms.eastNorthUpToFixedFrame(instancePosition, Ellipsoid.WGS84, instanceTransform); - Matrix4.getRotation(instanceTransform, instanceRotation); - } else { - Matrix3.clone(Matrix3.IDENTITY, instanceRotation); - } - } - if (hasCustomOrientation) { - Cartesian3.cross(instanceNormalRight, instanceNormalUp, instanceNormalForward); - Cartesian3.normalize(instanceNormalForward, instanceNormalForward); - Matrix3.setColumn(instanceRotation, 0, instanceNormalRight, instanceRotation); - Matrix3.setColumn(instanceRotation, 1, instanceNormalUp, instanceRotation); - Matrix3.setColumn(instanceRotation, 2, instanceNormalForward, instanceRotation); - } - Quaternion.fromRotationMatrix(instanceRotation, instanceQuaternion); - instanceTranslationRotationScale.rotation = instanceQuaternion; + function applyDebugSettings(tile, tileset, frameState) { + var hasContentBoundingVolume = defined(tile._header.content) && defined(tile._header.content.boundingVolume); - // Get the instance scale - instanceScale = Cartesian3.fromElements(1.0, 1.0, 1.0, instanceScale); - var scale = featureTable.getProperty('SCALE', ComponentDatatype.FLOAT, 1, i); - if (defined(scale)) { - Cartesian3.multiplyByScalar(instanceScale, scale, instanceScale); + var showVolume = tileset.debugShowBoundingVolume || (tileset.debugShowContentBoundingVolume && !hasContentBoundingVolume); + if (showVolume) { + if (!defined(tile._debugBoundingVolume)) { + var color = tile._finalResolution ? (hasContentBoundingVolume ? Color.WHITE : Color.RED) : Color.YELLOW; + tile._debugBoundingVolume = tile._boundingVolume.createDebugVolume(color); } - var nonUniformScale = featureTable.getProperty('SCALE_NON_UNIFORM', ComponentDatatype.FLOAT, 3, i, propertyScratch1); - if (defined(nonUniformScale)) { - instanceScale.x *= nonUniformScale[0]; - instanceScale.y *= nonUniformScale[1]; - instanceScale.z *= nonUniformScale[2]; + tile._debugBoundingVolume.update(frameState); + } else if (!showVolume && defined(tile._debugBoundingVolume)) { + tile._debugBoundingVolume = tile._debugBoundingVolume.destroy(); + } + + if (tileset.debugShowContentBoundingVolume && hasContentBoundingVolume) { + if (!defined(tile._debugContentBoundingVolume)) { + tile._debugContentBoundingVolume = tile._contentBoundingVolume.createDebugVolume(Color.BLUE); } - instanceTranslationRotationScale.scale = instanceScale; + tile._debugContentBoundingVolume.update(frameState); + } else if (!tileset.debugShowContentBoundingVolume && defined(tile._debugContentBoundingVolume)) { + tile._debugContentBoundingVolume = tile._debugContentBoundingVolume.destroy(); + } - // Get the batchId - var batchId = featureTable.getProperty('BATCH_ID', ComponentDatatype.UNSIGNED_SHORT, 1, i); - if (!defined(batchId)) { - // If BATCH_ID semantic is undefined, batchId is just the instance number - batchId = i; + if (tileset.debugShowViewerRequestVolume && defined(tile._viewerRequestVolume)) { + if (!defined(tile._debugViewerRequestVolume)) { + tile._debugViewerRequestVolume = tile._viewerRequestVolume.createDebugVolume(Color.YELLOW); } + tile._debugViewerRequestVolume.update(frameState); + } else if (!tileset.debugShowViewerRequestVolume && defined(tile._debugViewerRequestVolume)) { + tile._debugViewerRequestVolume = tile._debugViewerRequestVolume.destroy(); + } - // Create the model matrix and the instance - Matrix4.fromTranslationRotationScale(instanceTranslationRotationScale, instanceTransform); - var modelMatrix = instanceTransform.clone(); - instances[i] = { - modelMatrix : modelMatrix, - batchId : batchId - }; + var debugColorizeTilesOn = tileset.debugColorizeTiles && !tile._debugColorizeTiles; + var debugColorizeTilesOff = !tileset.debugColorizeTiles && tile._debugColorizeTiles; + + if (debugColorizeTilesOn) { + tile._debugColorizeTiles = true; + tile.color = tile._debugColor; + } else if (debugColorizeTilesOff) { + tile._debugColorizeTiles = false; + tile.color = Color.WHITE; } - content._modelInstanceCollection = new ModelInstanceCollection(collectionOptions); - } + if (tile._colorDirty) { + tile._colorDirty = false; + tile._content.applyDebugSettings(true, tile._color); + } - function createFeatures(content) { - var tileset = content._tileset; - var featuresLength = content.featuresLength; - if (!defined(content._features) && (featuresLength > 0)) { - var features = new Array(featuresLength); - for (var i = 0; i < featuresLength; ++i) { - features[i] = new Cesium3DTileFeature(tileset, content, i); - } - content._features = features; + if (debugColorizeTilesOff) { + tileset.makeStyleDirty(); // Re-apply style now that colorize is switched off } } - /** - * @inheritdoc Cesium3DTileContent#hasProperty - */ - Instanced3DModel3DTileContent.prototype.hasProperty = function(batchId, name) { - return this._batchTable.hasProperty(batchId, name); - }; + function updateContent(tile, tileset, frameState) { + var content = tile._content; + var expiredContent = tile._expiredContent; - /** - * @inheritdoc Cesium3DTileContent#getFeature - */ - Instanced3DModel3DTileContent.prototype.getFeature = function(batchId) { - var featuresLength = this.featuresLength; - if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { - throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); + if (defined(expiredContent)) { + if (!tile.contentReady) { + // Render the expired content while the content loads + expiredContent.update(tileset, frameState); + return; + } + + // New content is ready, destroy expired content + tile._expiredContent.destroy(); + tile._expiredContent = undefined; } - - createFeatures(this); - return this._features[batchId]; - }; - /** - * @inheritdoc Cesium3DTileContent#applyDebugSettings - */ - Instanced3DModel3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - color = enabled ? color : Color.WHITE; - this._batchTable.setAllColor(color); - }; + content.update(tileset, frameState); + } /** - * @inheritdoc Cesium3DTileContent#applyStyle + * Get the draw commands needed to render this tile. + * + * @private */ - Instanced3DModel3DTileContent.prototype.applyStyle = function(frameState, style) { - this._batchTable.applyStyle(frameState, style); + Cesium3DTile.prototype.update = function(tileset, frameState) { + var initCommandLength = frameState.commandList.length; + applyDebugSettings(this, tileset, frameState); + updateContent(this, tileset, frameState); + this._commandsLength = frameState.commandList.length - initCommandLength; }; + var scratchCommandList = []; + /** - * @inheritdoc Cesium3DTileContent#update + * Processes the tile's content, e.g., create WebGL resources, to move from the PROCESSING to READY state. + * + * @param {Cesium3DTileset} tileset The tileset containing this tile. + * @param {FrameState} frameState The frame state. + * + * @private */ - Instanced3DModel3DTileContent.prototype.update = function(tileset, frameState) { - var commandStart = frameState.commandList.length; - - // In the PROCESSING state we may be calling update() to move forward - // the content's resource loading. In the READY state, it will - // actually generate commands. - this._batchTable.update(tileset, frameState); - this._modelInstanceCollection.modelMatrix = this._tile.computedTransform; - this._modelInstanceCollection.shadows = this._tileset.shadows; - this._modelInstanceCollection.debugWireframe = this._tileset.debugWireframe; - this._modelInstanceCollection.update(frameState); - - // Update clipping planes - var tilesetClippingPlanes = this._tileset.clippingPlanes; - var model = this._modelInstanceCollection._model; - var modelClippingPlanes = model.clippingPlanes; - if (defined(tilesetClippingPlanes)) { - if (!defined(modelClippingPlanes)) { - model.clippingPlanes = new ClippingPlaneCollection(); - modelClippingPlanes = model.clippingPlanes; - } + Cesium3DTile.prototype.process = function(tileset, frameState) { + var savedCommandList = frameState.commandList; + frameState.commandList = scratchCommandList; - tilesetClippingPlanes.clone(modelClippingPlanes); - modelClippingPlanes.enabled = tilesetClippingPlanes.enabled && this._tile._isClipped; - } else if (defined(modelClippingPlanes) && modelClippingPlanes.enabled) { - modelClippingPlanes.enabled = false; - } + this._content.update(tileset, frameState); - // If any commands were pushed, add derived commands - var commandEnd = frameState.commandList.length; - if ((commandStart < commandEnd) && frameState.passes.render) { - this._batchTable.addDerivedCommands(frameState, commandStart, false); - } + scratchCommandList.length = 0; + frameState.commandList = savedCommandList; }; /** - * @inheritdoc Cesium3DTileContent#isDestroyed + * @private */ - Instanced3DModel3DTileContent.prototype.isDestroyed = function() { + Cesium3DTile.prototype.isDestroyed = function() { return false; }; /** - * @inheritdoc Cesium3DTileContent#destroy + * @private */ - Instanced3DModel3DTileContent.prototype.destroy = function() { - this._modelInstanceCollection = this._modelInstanceCollection && this._modelInstanceCollection.destroy(); - this._batchTable = this._batchTable && this._batchTable.destroy(); - + Cesium3DTile.prototype.destroy = function() { + // For the interval between new content being requested and downloaded, expiredContent === content, so don't destroy twice + this._content = this._content && this._content.destroy(); + this._expiredContent = this._expiredContent && !this._expiredContent.isDestroyed() && this._expiredContent.destroy(); + this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); + this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); + this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); return destroyObject(this); }; - return Instanced3DModel3DTileContent; + + return Cesium3DTile; }); -define('Scene/PointCloud3DTileContent',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Color', - '../Core/combine', - '../Core/ComponentDatatype', - '../Core/defaultValue', - '../Core/defined', +define('Scene/Cesium3DTileContent',[ '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/FeatureDetection', - '../Core/getStringFromTypedArray', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/oneTimeWarning', - '../Core/Plane', - '../Core/PrimitiveType', - '../Core/RuntimeError', - '../Core/Transforms', - '../Renderer/Buffer', - '../Renderer/BufferUsage', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/VertexArray', - '../ThirdParty/when', - './BlendingState', - './Cesium3DTileBatchTable', - './Cesium3DTileFeature', - './Cesium3DTileFeatureTable', - './SceneMode', - './ShadowMode' + '../Core/DeveloperError' ], function( - Cartesian2, - Cartesian3, - Cartesian4, - Color, - combine, - ComponentDatatype, - defaultValue, - defined, defineProperties, - destroyObject, - DeveloperError, - FeatureDetection, - getStringFromTypedArray, - Matrix3, - Matrix4, - oneTimeWarning, - Plane, - PrimitiveType, - RuntimeError, - Transforms, - Buffer, - BufferUsage, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - VertexArray, - when, - BlendingState, - Cesium3DTileBatchTable, - Cesium3DTileFeature, - Cesium3DTileFeatureTable, - SceneMode, - ShadowMode) { + DeveloperError) { 'use strict'; - // Bail out if the browser doesn't support typed arrays, to prevent the setup function - // from failing, since we won't be able to create a WebGL context anyway. - if (!FeatureDetection.supportsTypedArrays()) { - return {}; - } - /** - * Represents the contents of a - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/PointCloud/README.md|Points} - * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset. + * The content of a tile in a {@link Cesium3DTileset}. * <p> - * Implements the {@link Cesium3DTileContent} interface. + * Derived classes of this interface provide access to individual features in the tile. + * Access derived objects through {@link Cesium3DTile#content}. + * </p> + * <p> + * This type describes an interface and is not intended to be instantiated directly. * </p> * - * @alias PointCloud3DTileContent + * @alias Cesium3DTileContent * @constructor - * - * @private */ - function PointCloud3DTileContent(tileset, tile, url, arrayBuffer, byteOffset) { - this._tileset = tileset; - this._tile = tile; - this._url = url; - - // Hold onto the payload until the render resources are created - this._parsedContent = undefined; - - this._drawCommand = undefined; - this._pickCommand = undefined; - this._pickId = undefined; // Only defined when batchTable is undefined - this._isTranslucent = false; - this._styleTranslucent = false; - this._constantColor = Color.clone(Color.WHITE); - this._rtcCenter = undefined; - this._batchTable = undefined; // Used when feature table contains BATCH_ID semantic - - // These values are used to regenerate the shader when the style changes - this._styleableShaderAttributes = undefined; - this._isQuantized = false; - this._isOctEncoded16P = false; - this._isRGB565 = false; - this._hasColors = false; - this._hasNormals = false; - this._hasBatchIds = false; - - // Used to regenerate shader when clipping on this tile changes - this._isClipped = false; - this._unionClippingRegions = false; - - // Use per-point normals to hide back-facing points. - this.backFaceCulling = false; - this._backFaceCulling = false; - - this._opaqueRenderState = undefined; - this._translucentRenderState = undefined; - - this._highlightColor = Color.clone(Color.WHITE); - this._pointSize = 1.0; - this._quantizedVolumeScale = undefined; - this._quantizedVolumeOffset = undefined; - - this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY); - this._mode = undefined; - - this._readyPromise = when.defer(); - this._pointsLength = 0; - this._geometryByteLength = 0; - - this._features = undefined; - - this._packedClippingPlanes = []; - this._modelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); - + function Cesium3DTileContent(tileset, tile, url, arrayBuffer, byteOffset) { /** - * @inheritdoc Cesium3DTileContent#featurePropertiesDirty + * Gets or sets if any feature's property changed. Used to + * optimized applying a style when a feature's property changed. + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @type {Boolean} + * + * @private */ this.featurePropertiesDirty = false; - - initialize(this, arrayBuffer, byteOffset); } - defineProperties(PointCloud3DTileContent.prototype, { + defineProperties(Cesium3DTileContent.prototype, { /** - * @inheritdoc Cesium3DTileContent#featuresLength + * Gets the number of features in the tile. + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Number} + * @readonly */ featuresLength : { get : function() { - if (defined(this._batchTable)) { - return this._batchTable.featuresLength; - } - return 0; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#pointsLength + * Gets the number of points in the tile. + * <p> + * Only applicable for tiles with Point Cloud content. This is different than {@link Cesium3DTileContent#featuresLength} which + * equals the number of groups of points as distinguished by the <code>BATCH_ID</code> feature table semantic. + * </p> + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/PointCloud/README.md#batched-points} + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Number} + * @readonly */ pointsLength : { get : function() { - return this._pointsLength; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#trianglesLength + * Gets the number of triangles in the tile. + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Number} + * @readonly */ trianglesLength : { get : function() { - return 0; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#geometryByteLength + * Gets the tile's geometry memory in bytes. + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Number} + * @readonly */ geometryByteLength : { get : function() { - return this._geometryByteLength; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#texturesByteLength + * Gets the tile's texture memory in bytes. + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Number} + * @readonly */ texturesByteLength : { get : function() { - return 0; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#batchTableByteLength + * Gets the amount of memory used by the batch table textures, in bytes. + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Number} + * @readonly */ batchTableByteLength : { get : function() { - if (defined(this._batchTable)) { - return this._batchTable.memorySizeInBytes; - } - return 0; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#innerContents + * Gets the array of {@link Cesium3DTileContent} objects that represent the + * content a composite's inner tiles, which can also be composites. + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Composite/README.md} + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Array} + * @readonly */ innerContents : { get : function() { - return undefined; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#readyPromise + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Cesium3DTileContent.prototype + * + * @type {Promise.<Cesium3DTileContent>} + * @readonly */ readyPromise : { get : function() { - return this._readyPromise.promise; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#tileset + * Gets the tileset for this tile. + * + * @type {Cesium3DTileset} + * @readonly */ tileset : { get : function() { - return this._tileset; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#tile + * Gets the tile containing this content. + * + * @type {Cesium3DTile} + * @readonly */ tile : { get : function() { - return this._tile; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#url + * Gets the url of the tile's content. + * @memberof Cesium3DTileContent.prototype + * + * @type {String} + * @readonly */ url : { get : function() { - return this._url; + DeveloperError.throwInstantiationError(); } }, /** - * @inheritdoc Cesium3DTileContent#batchTable + * Gets the batch table for this content. + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @type {Cesium3DTileBatchTable} + * @readonly + * + * @private */ batchTable : { get : function() { - return this._batchTable; + DeveloperError.throwInstantiationError(); } } }); - var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; - - function initialize(content, arrayBuffer, byteOffset) { - byteOffset = defaultValue(byteOffset, 0); - - var uint8Array = new Uint8Array(arrayBuffer); - var view = new DataView(arrayBuffer); - byteOffset += sizeOfUint32; // Skip magic - - var version = view.getUint32(byteOffset, true); - if (version !== 1) { - throw new RuntimeError('Only Point Cloud tile version 1 is supported. Version ' + version + ' is not.'); - } - byteOffset += sizeOfUint32; - - // Skip byteLength - byteOffset += sizeOfUint32; - - var featureTableJsonByteLength = view.getUint32(byteOffset, true); - if (featureTableJsonByteLength === 0) { - throw new RuntimeError('Feature table must have a byte length greater than zero'); - } - byteOffset += sizeOfUint32; - - var featureTableBinaryByteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - - var batchTableJsonByteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var batchTableBinaryByteLength = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - - var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength); - var featureTableJson = JSON.parse(featureTableString); - byteOffset += featureTableJsonByteLength; - - var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); - byteOffset += featureTableBinaryByteLength; - - // Get the batch table JSON and binary - var batchTableJson; - var batchTableBinary; - if (batchTableJsonByteLength > 0) { - // Has a batch table JSON - var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength); - batchTableJson = JSON.parse(batchTableString); - byteOffset += batchTableJsonByteLength; - - if (batchTableBinaryByteLength > 0) { - // Has a batch table binary - batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); - byteOffset += batchTableBinaryByteLength; - } - } - - var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary); - - var pointsLength = featureTable.getGlobalProperty('POINTS_LENGTH'); - featureTable.featuresLength = pointsLength; - - if (!defined(pointsLength)) { - throw new RuntimeError('Feature table global property: POINTS_LENGTH must be defined'); - } - - // Get the positions - var positions; - var isQuantized = false; - - if (defined(featureTableJson.POSITION)) { - positions = featureTable.getPropertyArray('POSITION', ComponentDatatype.FLOAT, 3); - var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); - if (defined(rtcCenter)) { - content._rtcCenter = Cartesian3.unpack(rtcCenter); - } - } else if (defined(featureTableJson.POSITION_QUANTIZED)) { - positions = featureTable.getPropertyArray('POSITION_QUANTIZED', ComponentDatatype.UNSIGNED_SHORT, 3); - isQuantized = true; - - var quantizedVolumeScale = featureTable.getGlobalProperty('QUANTIZED_VOLUME_SCALE', ComponentDatatype.FLOAT, 3); - if (!defined(quantizedVolumeScale)) { - throw new RuntimeError('Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.'); - } - content._quantizedVolumeScale = Cartesian3.unpack(quantizedVolumeScale); - - var quantizedVolumeOffset = featureTable.getGlobalProperty('QUANTIZED_VOLUME_OFFSET', ComponentDatatype.FLOAT, 3); - if (!defined(quantizedVolumeOffset)) { - throw new RuntimeError('Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.'); - } - content._quantizedVolumeOffset = Cartesian3.unpack(quantizedVolumeOffset); - } - - if (!defined(positions)) { - throw new RuntimeError('Either POSITION or POSITION_QUANTIZED must be defined.'); - } - - // Get the colors - var colors; - var isTranslucent = false; - var isRGB565 = false; - - if (defined(featureTableJson.RGBA)) { - colors = featureTable.getPropertyArray('RGBA', ComponentDatatype.UNSIGNED_BYTE, 4); - isTranslucent = true; - } else if (defined(featureTableJson.RGB)) { - colors = featureTable.getPropertyArray('RGB', ComponentDatatype.UNSIGNED_BYTE, 3); - } else if (defined(featureTableJson.RGB565)) { - colors = featureTable.getPropertyArray('RGB565', ComponentDatatype.UNSIGNED_SHORT, 1); - isRGB565 = true; - } else if (defined(featureTableJson.CONSTANT_RGBA)) { - var constantRGBA = featureTable.getGlobalProperty('CONSTANT_RGBA', ComponentDatatype.UNSIGNED_BYTE, 4); - content._constantColor = Color.fromBytes(constantRGBA[0], constantRGBA[1], constantRGBA[2], constantRGBA[3], content._constantColor); - } else { - // Use a default constant color - content._constantColor = Color.clone(Color.DARKGRAY, content._constantColor); - } - - content._isTranslucent = isTranslucent; - - // Get the normals - var normals; - var isOctEncoded16P = false; - - if (defined(featureTableJson.NORMAL)) { - normals = featureTable.getPropertyArray('NORMAL', ComponentDatatype.FLOAT, 3); - } else if (defined(featureTableJson.NORMAL_OCT16P)) { - normals = featureTable.getPropertyArray('NORMAL_OCT16P', ComponentDatatype.UNSIGNED_BYTE, 2); - isOctEncoded16P = true; - } - - // Get the batchIds and batch table. BATCH_ID does not need to be defined when the point cloud has per-point properties. - var batchIds; - if (defined(featureTableJson.BATCH_ID)) { - batchIds = featureTable.getPropertyArray('BATCH_ID', ComponentDatatype.UNSIGNED_SHORT, 1); - - var batchLength = featureTable.getGlobalProperty('BATCH_LENGTH'); - if (!defined(batchLength)) { - throw new RuntimeError('Global property: BATCH_LENGTH must be defined when BATCH_ID is defined.'); - } - - if (defined(batchTableBinary)) { - // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed - batchTableBinary = new Uint8Array(batchTableBinary); - } - content._batchTable = new Cesium3DTileBatchTable(content, batchLength, batchTableJson, batchTableBinary); - } - - // If points are not batched and there are per-point properties, use these properties for styling purposes - var styleableProperties; - if (!defined(batchIds) && defined(batchTableBinary)) { - styleableProperties = Cesium3DTileBatchTable.getBinaryProperties(pointsLength, batchTableJson, batchTableBinary); - - // WebGL does not support UNSIGNED_INT, INT, or DOUBLE vertex attributes. Convert these to FLOAT. - for (var name in styleableProperties) { - if (styleableProperties.hasOwnProperty(name)) { - var property = styleableProperties[name]; - var typedArray = property.typedArray; - var componentDatatype = ComponentDatatype.fromTypedArray(typedArray); - if (componentDatatype === ComponentDatatype.INT || componentDatatype === ComponentDatatype.UNSIGNED_INT || componentDatatype === ComponentDatatype.DOUBLE) { - oneTimeWarning('Cast pnts property to floats', 'Point cloud property "' + name + '" will be casted to a float array because INT, UNSIGNED_INT, and DOUBLE are not valid WebGL vertex attribute types. Some precision may be lost.'); - property.typedArray = new Float32Array(typedArray); - } - } - } - } - - content._parsedContent = { - positions : positions, - colors : colors, - normals : normals, - batchIds : batchIds, - styleableProperties : styleableProperties - }; - content._pointsLength = pointsLength; - content._isQuantized = isQuantized; - content._isOctEncoded16P = isOctEncoded16P; - content._isRGB565 = isRGB565; - content._hasColors = defined(colors); - content._hasNormals = defined(normals); - content._hasBatchIds = defined(batchIds); - } - - var scratchPointSizeAndTilesetTime = new Cartesian2(); - - var positionLocation = 0; - var colorLocation = 1; - var normalLocation = 2; - var batchIdLocation = 3; - var numberOfAttributes = 4; - - function createResources(content, frameState) { - var context = frameState.context; - var parsedContent = content._parsedContent; - var pointsLength = content._pointsLength; - var positions = parsedContent.positions; - var colors = parsedContent.colors; - var normals = parsedContent.normals; - var batchIds = parsedContent.batchIds; - var styleableProperties = parsedContent.styleableProperties; - var hasStyleableProperties = defined(styleableProperties); - var isQuantized = content._isQuantized; - var isOctEncoded16P = content._isOctEncoded16P; - var isRGB565 = content._isRGB565; - var isTranslucent = content._isTranslucent; - var hasColors = content._hasColors; - var hasNormals = content._hasNormals; - var hasBatchIds = content._hasBatchIds; - - var batchTable = content._batchTable; - var hasBatchTable = defined(batchTable); - - var styleableVertexAttributes = []; - var styleableShaderAttributes = {}; - content._styleableShaderAttributes = styleableShaderAttributes; - - if (hasStyleableProperties) { - var attributeLocation = numberOfAttributes; - - for (var name in styleableProperties) { - if (styleableProperties.hasOwnProperty(name)) { - var property = styleableProperties[name]; - var typedArray = property.typedArray; - var componentCount = property.componentCount; - var componentDatatype = ComponentDatatype.fromTypedArray(typedArray); - - var vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : property.typedArray, - usage : BufferUsage.STATIC_DRAW - }); - - content._geometryByteLength += vertexBuffer.sizeInBytes; - - var vertexAttribute = { - index : attributeLocation, - vertexBuffer : vertexBuffer, - componentsPerAttribute : componentCount, - componentDatatype : componentDatatype, - normalize : false, - offsetInBytes : 0, - strideInBytes : 0 - }; - - styleableVertexAttributes.push(vertexAttribute); - styleableShaderAttributes[name] = { - location : attributeLocation, - componentCount : componentCount - }; - ++attributeLocation; - } - } - } - - var uniformMap = { - u_pointSizeAndTilesetTime : function() { - scratchPointSizeAndTilesetTime.x = content._pointSize; - scratchPointSizeAndTilesetTime.y = content._tileset.timeSinceLoad; - return scratchPointSizeAndTilesetTime; - }, - u_highlightColor : function() { - return content._highlightColor; - }, - u_constantColor : function() { - return content._constantColor; - }, - u_clippingPlanesLength : function() { - return content._packedClippingPlanes.length; - }, - u_clippingPlanes : function() { - return content._packedClippingPlanes; - }, - u_clippingPlanesEdgeStyle : function() { - var clippingPlanes = content._tileset.clippingPlanes; - - if (!defined(clippingPlanes)) { - return Color.WHITE.withAlpha(0.0); - } + /** + * Determines if the tile's batch table has a property. If it does, each feature in + * the tile will have the property. + * + * @param {Number} batchId The batchId for the feature. + * @param {String} name The case-sensitive name of the property. + * @returns {Boolean} <code>true</code> if the property exists; otherwise, <code>false</code>. + */ + Cesium3DTileContent.prototype.hasProperty = function(batchId, name) { + DeveloperError.throwInstantiationError(); + }; - var style = Color.clone(clippingPlanes.edgeColor); - style.alpha = clippingPlanes.edgeWidth; - return style; - } - }; + /** + * Returns the {@link Cesium3DTileFeature} object for the feature with the + * given <code>batchId</code>. This object is used to get and modify the + * feature's properties. + * <p> + * Features in a tile are ordered by <code>batchId</code>, an index used to retrieve their metadata from the batch table. + * </p> + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable}. + * + * @param {Number} batchId The batchId for the feature. + * @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object. + * + * @exception {DeveloperError} batchId must be between zero and {@link Cesium3DTileContent#featuresLength} - 1. + */ + Cesium3DTileContent.prototype.getFeature = function(batchId) { + DeveloperError.throwInstantiationError(); + }; - if (isQuantized) { - uniformMap = combine(uniformMap, { - u_quantizedVolumeScale : function() { - return content._quantizedVolumeScale; - } - }); - } + /** + * Called when {@link Cesium3DTileset#debugColorizeTiles} changes. + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @param {Boolean} enabled Whether to enable or disable debug settings. + * @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object. - var positionsVertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : positions, - usage : BufferUsage.STATIC_DRAW - }); - content._geometryByteLength += positionsVertexBuffer.sizeInBytes; + * @private + */ + Cesium3DTileContent.prototype.applyDebugSettings = function(enabled, color) { + DeveloperError.throwInstantiationError(); + }; - var colorsVertexBuffer; - if (hasColors) { - colorsVertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : colors, - usage : BufferUsage.STATIC_DRAW - }); - content._geometryByteLength += colorsVertexBuffer.sizeInBytes; - } + /** + * Apply a style to the content + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @param {FrameSate} frameState The frame state. + * @param {Cesium3DTileStyle} style The style. + * + * @private + */ + Cesium3DTileContent.prototype.applyStyle = function(frameState, style) { + DeveloperError.throwInstantiationError(); + }; - var normalsVertexBuffer; - if (hasNormals) { - normalsVertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : normals, - usage : BufferUsage.STATIC_DRAW - }); - content._geometryByteLength += normalsVertexBuffer.sizeInBytes; - } + /** + * Called by the tile during tileset traversal to get the draw commands needed to render this content. + * When the tile's content is in the PROCESSING state, this creates WebGL resources to ultimately + * move to the READY state. + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @param {Cesium3DTileset} tileset The tileset containing this tile. + * @param {FrameState} frameState The frame state. + * + * @private + */ + Cesium3DTileContent.prototype.update = function(tileset, frameState) { + DeveloperError.throwInstantiationError(); + }; - var batchIdsVertexBuffer; - if (hasBatchIds) { - batchIdsVertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : batchIds, - usage : BufferUsage.STATIC_DRAW - }); - content._geometryByteLength += batchIdsVertexBuffer.sizeInBytes; - } + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see Cesium3DTileContent#destroy + * + * @private + */ + Cesium3DTileContent.prototype.isDestroyed = function() { + DeveloperError.throwInstantiationError(); + }; - var attributes = []; - if (isQuantized) { - attributes.push({ - index : positionLocation, - vertexBuffer : positionsVertexBuffer, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.UNSIGNED_SHORT, - normalize : true, // Convert position to 0 to 1 before entering the shader - offsetInBytes : 0, - strideInBytes : 0 - }); - } else { - attributes.push({ - index : positionLocation, - vertexBuffer : positionsVertexBuffer, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - normalize : false, - offsetInBytes : 0, - strideInBytes : 0 - }); - } + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * <p> + * This is used to implement the <code>Cesium3DTileContent</code> interface, but is + * not part of the public Cesium API. + * </p> + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * content = content && content.destroy(); + * + * @see Cesium3DTileContent#isDestroyed + * + * @private + */ + Cesium3DTileContent.prototype.destroy = function() { + DeveloperError.throwInstantiationError(); + }; - if (hasColors) { - if (isRGB565) { - attributes.push({ - index : colorLocation, - vertexBuffer : colorsVertexBuffer, - componentsPerAttribute : 1, - componentDatatype : ComponentDatatype.UNSIGNED_SHORT, - normalize : false, - offsetInBytes : 0, - strideInBytes : 0 - }); - } else { - var colorComponentsPerAttribute = isTranslucent ? 4 : 3; - attributes.push({ - index : colorLocation, - vertexBuffer : colorsVertexBuffer, - componentsPerAttribute : colorComponentsPerAttribute, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - normalize : true, - offsetInBytes : 0, - strideInBytes : 0 - }); - } - } + return Cesium3DTileContent; +}); - if (hasNormals) { - if (isOctEncoded16P) { - attributes.push({ - index : normalLocation, - vertexBuffer : normalsVertexBuffer, - componentsPerAttribute : 2, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - normalize : false, - offsetInBytes : 0, - strideInBytes : 0 - }); - } else { - attributes.push({ - index : normalLocation, - vertexBuffer : normalsVertexBuffer, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - normalize : false, - offsetInBytes : 0, - strideInBytes : 0 - }); - } - } +define('Scene/Cesium3DTileOptimizations',[ + '../Core/Cartesian3', + '../Core/Check', + './Cesium3DTileOptimizationHint', + './TileBoundingRegion', + './TileOrientedBoundingBox' + ], function( + Cartesian3, + Check, + Cesium3DTileOptimizationHint, + TileBoundingRegion, + TileOrientedBoundingBox) { + 'use strict'; - if (hasBatchIds) { - attributes.push({ - index : batchIdLocation, - vertexBuffer : batchIdsVertexBuffer, - componentsPerAttribute : 1, - componentDatatype : ComponentDatatype.fromTypedArray(batchIds), - normalize : false, - offsetInBytes : 0, - strideInBytes : 0 - }); - } + /** + * Utility functions for computing optimization hints for a {@link Cesium3DTileset}. + * + * @exports Cesium3DTileOptimizations + * + * @private + */ + var Cesium3DTileOptimizations = {}; - if (hasStyleableProperties) { - attributes = attributes.concat(styleableVertexAttributes); - } + var scratchAxis = new Cartesian3(); - var vertexArray = new VertexArray({ - context : context, - attributes : attributes - }); + /** + * Evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if + * children bounds are fully contained within the parent. Currently, support for the optimization only works for + * oriented bounding boxes, so both the child and parent tile must be either a {@link TileOrientedBoundingBox} or + * {@link TileBoundingRegion}. The purpose of this check is to prevent use of a culling optimization when the child + * bounds exceed those of the parent. If the child bounds are greater, it is more likely that the optimization will + * waste CPU cycles. Bounding spheres are not supported for the reason that the child bounds can very often be + * partially outside of the parent bounds. + * + * @param {Cesium3DTile} tile The tile to check. + * @returns {Boolean} Whether the childrenWithinParent optimization is supported. + */ + Cesium3DTileOptimizations.checkChildrenWithinParent = function(tile) { + Check.typeOf.object('tile', tile); + + var children = tile.children; + var length = children.length; - var drawUniformMap = uniformMap; + // Check if the parent has an oriented bounding box. + var boundingVolume = tile._boundingVolume; + if (boundingVolume instanceof TileOrientedBoundingBox || boundingVolume instanceof TileBoundingRegion) { + var orientedBoundingBox = boundingVolume._orientedBoundingBox; + tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.USE_OPTIMIZATION; + for (var i = 0; i < length; ++i) { + var child = children[i]; - if (hasBatchTable) { - drawUniformMap = batchTable.getUniformMapCallback()(uniformMap); - } + // Check if the child has an oriented bounding box. + var childBoundingVolume = child._boundingVolume; + if (!(childBoundingVolume instanceof TileOrientedBoundingBox || childBoundingVolume instanceof TileBoundingRegion)) { + // Do not support if the parent and child both do not have oriented bounding boxes. + tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; + break; + } - var pickUniformMap; + var childOrientedBoundingBox = childBoundingVolume._orientedBoundingBox; - if (hasBatchTable) { - pickUniformMap = batchTable.getPickUniformMapCallback()(uniformMap); - } else { - content._pickId = context.createPickId({ - primitive : content._tileset, - content : content - }); + // Compute the axis from the parent to the child. + var axis = Cartesian3.subtract(childOrientedBoundingBox.center, orientedBoundingBox.center, scratchAxis); + var axisLength = Cartesian3.magnitude(axis); + Cartesian3.divideByScalar(axis, axisLength, axis); - pickUniformMap = combine(uniformMap, { - czm_pickColor : function() { - return content._pickId.color; + // Project the bounding box of the parent onto the axis. Because the axis is a ray from the parent + // to the child, the projection parameterized along the ray will be (+/- proj1). + var proj1 = Math.abs(orientedBoundingBox.halfAxes[0] * axis.x) + + Math.abs(orientedBoundingBox.halfAxes[1] * axis.y) + + Math.abs(orientedBoundingBox.halfAxes[2] * axis.z) + + Math.abs(orientedBoundingBox.halfAxes[3] * axis.x) + + Math.abs(orientedBoundingBox.halfAxes[4] * axis.y) + + Math.abs(orientedBoundingBox.halfAxes[5] * axis.z) + + Math.abs(orientedBoundingBox.halfAxes[6] * axis.x) + + Math.abs(orientedBoundingBox.halfAxes[7] * axis.y) + + Math.abs(orientedBoundingBox.halfAxes[8] * axis.z); + + // Project the bounding box of the child onto the axis. Because the axis is a ray from the parent + // to the child, the projection parameterized along the ray will be (+/- proj2) + axis.length. + var proj2 = Math.abs(childOrientedBoundingBox.halfAxes[0] * axis.x) + + Math.abs(childOrientedBoundingBox.halfAxes[1] * axis.y) + + Math.abs(childOrientedBoundingBox.halfAxes[2] * axis.z) + + Math.abs(childOrientedBoundingBox.halfAxes[3] * axis.x) + + Math.abs(childOrientedBoundingBox.halfAxes[4] * axis.y) + + Math.abs(childOrientedBoundingBox.halfAxes[5] * axis.z) + + Math.abs(childOrientedBoundingBox.halfAxes[6] * axis.x) + + Math.abs(childOrientedBoundingBox.halfAxes[7] * axis.y) + + Math.abs(childOrientedBoundingBox.halfAxes[8] * axis.z); + + // If the child extends the parent's bounds, the optimization is not valid and we skip it. + if (proj1 <= proj2 + axisLength) { + tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; + break; } - }); + } } - content._opaqueRenderState = RenderState.fromCache({ - depthTest : { - enabled : true - } - }); + return tile._optimChildrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION; + }; - content._translucentRenderState = RenderState.fromCache({ - depthTest : { - enabled : true - }, - depthMask : false, - blending : BlendingState.ALPHA_BLEND - }); + return Cesium3DTileOptimizations; +}); - content._drawCommand = new DrawCommand({ - boundingVolume : undefined, // Updated in update - cull : false, // Already culled by 3D Tiles - modelMatrix : new Matrix4(), - primitiveType : PrimitiveType.POINTS, - vertexArray : vertexArray, - count : pointsLength, - shaderProgram : undefined, // Updated in createShaders - uniformMap : drawUniformMap, - renderState : isTranslucent ? content._translucentRenderState : content._opaqueRenderState, - pass : isTranslucent ? Pass.TRANSLUCENT : Pass.CESIUM_3D_TILE, - owner : content, - castShadows : false, - receiveShadows : false - }); +define('Scene/Cesium3DTilesetStatistics',[ + '../Core/defined' + ], function( + defined) { + 'use strict'; - content._pickCommand = new DrawCommand({ - boundingVolume : undefined, // Updated in update - cull : false, // Already culled by 3D Tiles - modelMatrix : new Matrix4(), - primitiveType : PrimitiveType.POINTS, - vertexArray : vertexArray, - count : pointsLength, - shaderProgram : undefined, // Updated in createShaders - uniformMap : pickUniformMap, - renderState : isTranslucent ? content._translucentRenderState : content._opaqueRenderState, - pass : isTranslucent ? Pass.TRANSLUCENT : Pass.CESIUM_3D_TILE, - owner : content - }); + /** + * @private + */ + function Cesium3DTilesetStatistics() { + // Rendering statistics + this.selected = 0; + this.visited = 0; + // Loading statistics + this.numberOfCommands = 0; + this.numberOfAttemptedRequests = 0; + this.numberOfPendingRequests = 0; + this.numberOfTilesProcessing = 0; + this.numberOfTilesWithContentReady = 0; // Number of tiles with content loaded, does not include empty tiles + this.numberOfTilesTotal = 0; // Number of tiles in tileset.json (and other tileset.json files as they are loaded) + // Features statistics + this.numberOfFeaturesSelected = 0; // Number of features rendered + this.numberOfFeaturesLoaded = 0; // Number of features in memory + this.numberOfPointsSelected = 0; + this.numberOfPointsLoaded = 0; + this.numberOfTrianglesSelected = 0; + // Styling statistics + this.numberOfTilesStyled = 0; + this.numberOfFeaturesStyled = 0; + // Optimization statistics + this.numberOfTilesCulledWithChildrenUnion = 0; + // Memory statistics + this.geometryByteLength = 0; + this.texturesByteLength = 0; + this.batchTableByteLength = 0; } - var defaultProperties = ['POSITION', 'COLOR', 'NORMAL', 'POSITION_ABSOLUTE']; + Cesium3DTilesetStatistics.prototype.clear = function() { + this.selected = 0; + this.visited = 0; + this.numberOfCommands = 0; + this.numberOfAttemptedRequests = 0; + this.numberOfFeaturesSelected = 0; + this.numberOfPointsSelected = 0; + this.numberOfTrianglesSelected = 0; + this.numberOfTilesStyled = 0; + this.numberOfFeaturesStyled = 0; + this.numberOfTilesCulledWithChildrenUnion = 0; + }; - function getStyleableProperties(source, properties) { - // Get all the properties used by this style - var regex = /czm_tiles3d_style_(\w+)/g; - var matches = regex.exec(source); - while (matches !== null) { - var name = matches[1]; - if (properties.indexOf(name) === -1) { - properties.push(name); - } - matches = regex.exec(source); + function updatePointAndFeatureCounts(statistics, content, decrement, load) { + var contents = content.innerContents; + var pointsLength = content.pointsLength; + var trianglesLength = content.trianglesLength; + var featuresLength = content.featuresLength; + var geometryByteLength = content.geometryByteLength; + var texturesByteLength = content.texturesByteLength; + var batchTableByteLength = content.batchTableByteLength; + + if (load) { + statistics.numberOfFeaturesLoaded += decrement ? -featuresLength : featuresLength; + statistics.numberOfPointsLoaded += decrement ? -pointsLength : pointsLength; + statistics.geometryByteLength += decrement ? -geometryByteLength : geometryByteLength; + statistics.texturesByteLength += decrement ? -texturesByteLength : texturesByteLength; + statistics.batchTableByteLength += decrement ? -batchTableByteLength : batchTableByteLength; + } else { + statistics.numberOfFeaturesSelected += decrement ? -featuresLength : featuresLength; + statistics.numberOfPointsSelected += decrement ? -pointsLength : pointsLength; + statistics.numberOfTrianglesSelected += decrement ? -trianglesLength : trianglesLength; } - } - function getVertexAttribute(vertexArray, index) { - var numberOfAttributes = vertexArray.numberOfAttributes; - for (var i = 0; i < numberOfAttributes; ++i) { - var attribute = vertexArray.getAttribute(i); - if (attribute.index === index) { - return attribute; + if (defined(contents)) { + var length = contents.length; + for (var i = 0; i < length; ++i) { + updatePointAndFeatureCounts(statistics, contents[i], decrement, load); } } } - function modifyStyleFunction(source) { - // Replace occurrences of czm_tiles3d_style_DEFAULTPROPERTY - var length = defaultProperties.length; - for (var i = 0; i < length; ++i) { - var property = defaultProperties[i]; - var styleName = 'czm_tiles3d_style_' + property; - var replaceName = property.toLowerCase(); - source = source.replace(new RegExp(styleName + '(\\W)', 'g'), replaceName + '$1'); - } + Cesium3DTilesetStatistics.prototype.incrementSelectionCounts = function(content) { + updatePointAndFeatureCounts(this, content, false, false); + }; - // Edit the function header to accept the point position, color, and normal - return source.replace('()', '(vec3 position, vec3 position_absolute, vec4 color, vec3 normal)'); - } + Cesium3DTilesetStatistics.prototype.incrementLoadCounts = function(content) { + updatePointAndFeatureCounts(this, content, false, true); + }; - function createShaders(content, frameState, style) { - var i; - var name; - var attribute; + Cesium3DTilesetStatistics.prototype.decrementLoadCounts = function(content) { + updatePointAndFeatureCounts(this, content, true, true); + }; - var context = frameState.context; - var batchTable = content._batchTable; - var hasBatchTable = defined(batchTable); - var hasStyle = defined(style); - var isQuantized = content._isQuantized; - var isOctEncoded16P = content._isOctEncoded16P; - var isRGB565 = content._isRGB565; - var isTranslucent = content._isTranslucent; - var hasColors = content._hasColors; - var hasNormals = content._hasNormals; - var hasBatchIds = content._hasBatchIds; - var backFaceCulling = content._backFaceCulling; - var vertexArray = content._drawCommand.vertexArray; - var clippingPlanes = content._tileset.clippingPlanes; + Cesium3DTilesetStatistics.clone = function(statistics, result) { + result.selected = statistics.selected; + result.visited = statistics.visited; + result.numberOfCommands = statistics.numberOfCommands; + result.selected = statistics.selected; + result.numberOfAttemptedRequests = statistics.numberOfAttemptedRequests; + result.numberOfPendingRequests = statistics.numberOfPendingRequests; + result.numberOfTilesProcessing = statistics.numberOfTilesProcessing; + result.numberOfTilesWithContentReady = statistics.numberOfTilesWithContentReady; + result.numberOfTilesTotal = statistics.numberOfTilesTotal; + result.numberOfFeaturesSelected = statistics.numberOfFeaturesSelected; + result.numberOfFeaturesLoaded = statistics.numberOfFeaturesLoaded; + result.numberOfPointsSelected = statistics.numberOfPointsSelected; + result.numberOfPointsLoaded = statistics.numberOfPointsLoaded; + result.numberOfTrianglesSelected = statistics.numberOfTrianglesSelected; + result.numberOfTilesStyled = statistics.numberOfTilesStyled; + result.numberOfFeaturesStyled = statistics.numberOfFeaturesStyled; + result.numberOfTilesCulledWithChildrenUnion = statistics.numberOfTilesCulledWithChildrenUnion; + result.geometryByteLength = statistics.geometryByteLength; + result.texturesByteLength = statistics.texturesByteLength; + result.batchTableByteLength = statistics.batchTableByteLength; + }; - var colorStyleFunction; - var showStyleFunction; - var pointSizeStyleFunction; - var styleTranslucent = isTranslucent; + return Cesium3DTilesetStatistics; +}); - if (hasBatchTable) { - // Styling is handled in the batch table - hasStyle = false; - } +define('Scene/Cesium3DTilesetTraversal',[ + '../Core/CullingVolume', + '../Core/defined', + '../Core/freezeObject', + '../Core/Intersect', + '../Core/ManagedArray', + '../Core/Math', + '../Core/OrthographicFrustum', + './Cesium3DTileChildrenVisibility', + './Cesium3DTileRefine', + './SceneMode' + ], function( + CullingVolume, + defined, + freezeObject, + Intersect, + ManagedArray, + CesiumMath, + OrthographicFrustum, + Cesium3DTileChildrenVisibility, + Cesium3DTileRefine, + SceneMode) { + 'use strict'; - if (hasStyle) { - var shaderState = { - translucent : false - }; - colorStyleFunction = style.getColorShaderFunction('getColorFromStyle', 'czm_tiles3d_style_', shaderState); - showStyleFunction = style.getShowShaderFunction('getShowFromStyle', 'czm_tiles3d_style_', shaderState); - pointSizeStyleFunction = style.getPointSizeShaderFunction('getPointSizeFromStyle', 'czm_tiles3d_style_', shaderState); - if (defined(colorStyleFunction) && shaderState.translucent) { - styleTranslucent = true; - } + /** + * @private + */ + var Cesium3DTilesetTraversal = {}; + + function selectTiles(tileset, frameState, outOfCore) { + if (tileset.debugFreezeFrame) { + return; } - content._styleTranslucent = styleTranslucent; + var maximumScreenSpaceError = tileset._maximumScreenSpaceError; - var hasColorStyle = defined(colorStyleFunction); - var hasShowStyle = defined(showStyleFunction); - var hasPointSizeStyle = defined(pointSizeStyleFunction); - var hasClippedContent = defined(clippingPlanes) && clippingPlanes.enabled && content._tile._isClipped && !FeatureDetection.isInternetExplorer(); + tileset._desiredTiles.length = 0; + tileset._selectedTiles.length = 0; + tileset._requestedTiles.length = 0; + tileset._selectedTilesToStyle.length = 0; + tileset._hasMixedContent = false; - // Get the properties in use by the style - var styleableProperties = []; + // Move sentinel node to the tail so, at the start of the frame, all tiles + // may be potentially replaced. Tiles are moved to the right of the sentinel + // when they are selected so they will not be replaced. + var replacementList = tileset._replacementList; + replacementList.splice(replacementList.tail, tileset._replacementSentinel); - if (hasColorStyle) { - getStyleableProperties(colorStyleFunction, styleableProperties); - colorStyleFunction = modifyStyleFunction(colorStyleFunction); - } - if (hasShowStyle) { - getStyleableProperties(showStyleFunction, styleableProperties); - showStyleFunction = modifyStyleFunction(showStyleFunction); - } - if (hasPointSizeStyle) { - getStyleableProperties(pointSizeStyleFunction, styleableProperties); - pointSizeStyleFunction = modifyStyleFunction(pointSizeStyleFunction); + var root = tileset._root; + root.updateTransform(tileset._modelMatrix); + + if (!root.insideViewerRequestVolume(frameState)) { + return; } - var usesColorSemantic = styleableProperties.indexOf('COLOR') >= 0; - var usesNormalSemantic = styleableProperties.indexOf('NORMAL') >= 0; + root._distanceToCamera = root.distanceToTile(frameState); - // Split default properties from user properties - var userProperties = styleableProperties.filter(function(property) { return defaultProperties.indexOf(property) === -1; }); + if (getScreenSpaceError(tileset, tileset._geometricError, root, frameState) <= maximumScreenSpaceError) { + // The SSE of not rendering the tree is small enough that the tree does not need to be rendered + return; + } - if (usesNormalSemantic && !hasNormals) { - throw new RuntimeError('Style references the NORMAL semantic but the point cloud does not have normals'); + root._visibilityPlaneMask = root.visibility(frameState, CullingVolume.MASK_INDETERMINATE); + if (root._visibilityPlaneMask === CullingVolume.MASK_OUTSIDE) { + return; } - // Disable vertex attributes that aren't used in the style, enable attributes that are - var styleableShaderAttributes = content._styleableShaderAttributes; - for (name in styleableShaderAttributes) { - if (styleableShaderAttributes.hasOwnProperty(name)) { - attribute = styleableShaderAttributes[name]; - var enabled = (userProperties.indexOf(name) >= 0); - var vertexAttribute = getVertexAttribute(vertexArray, attribute.location); - vertexAttribute.enabled = enabled; + loadTile(tileset, root, frameState, true); + + if (!tileset._skipLevelOfDetail) { + // just execute base traversal and add tiles to _desiredTiles + tileset._baseTraversal.execute(tileset, root, maximumScreenSpaceError, frameState, outOfCore); + var leaves = tileset._baseTraversal.leaves; + var length = leaves.length; + for (var i = 0; i < length; ++i) { + tileset._desiredTiles.push(leaves.get(i)); } - } + } else if (tileset.immediatelyLoadDesiredLevelOfDetail) { + tileset._skipTraversal.execute(tileset, root, frameState, outOfCore); + } else { + // leaves of the base traversal is where we start the skip traversal + tileset._baseTraversal.leaves = tileset._skipTraversal.queue1; - var usesColors = hasColors && (!hasColorStyle || usesColorSemantic); - if (hasColors) { - // Disable the color vertex attribute if the color style does not reference the color semantic - var colorVertexAttribute = getVertexAttribute(vertexArray, colorLocation); - colorVertexAttribute.enabled = usesColors; - } + // load and select tiles without skipping up to tileset.baseScreenSpaceError + tileset._baseTraversal.execute(tileset, root, tileset.baseScreenSpaceError, frameState, outOfCore); - var attributeLocations = { - a_position : positionLocation - }; - if (usesColors) { - attributeLocations.a_color = colorLocation; - } - if (hasNormals) { - attributeLocations.a_normal = normalLocation; - } - if (hasBatchIds) { - attributeLocations.a_batchId = batchIdLocation; + // skip traversal starts from a prepopulated queue from the base traversal + tileset._skipTraversal.execute(tileset, undefined, frameState, outOfCore); } - var attributeDeclarations = ''; + // mark tiles for selection or their nearest loaded ancestor + markLoadedTilesForSelection(tileset, frameState, outOfCore); - var length = userProperties.length; - for (i = 0; i < length; ++i) { - name = userProperties[i]; - attribute = styleableShaderAttributes[name]; - if (!defined(attribute)) { - throw new RuntimeError('Style references a property "' + name + '" that does not exist or is not styleable.'); + // sort selected tiles by distance to camera and call selectTile on each + // set tile._selectionDepth on all tiles + traverseAndSelect(tileset, root, frameState); + + tileset._desiredTiles.trim(); + } + + var descendantStack = []; + + function markLoadedTilesForSelection(tileset, frameState, outOfCore) { + var tiles = tileset._desiredTiles; + var length = tiles.length; + for (var i = 0; i < length; ++i) { + var original = tiles.get(i); + + if (hasAdditiveContent(original)) { + original.selected = true; + original._selectedFrame = frameState.frameNumber; + continue; } - var componentCount = attribute.componentCount; - var attributeName = 'czm_tiles3d_style_' + name; - var attributeType; - if (componentCount === 1) { - attributeType = 'float'; - } else { - attributeType = 'vec' + componentCount; + var loadedTile = original._ancestorWithLoadedContent; + if (original.hasRenderableContent && original.contentAvailable) { + loadedTile = original; } - attributeDeclarations += 'attribute ' + attributeType + ' ' + attributeName + '; \n'; - attributeLocations[attributeName] = attribute.location; + if (defined(loadedTile)) { + loadedTile.selected = true; + loadedTile._selectedFrame = frameState.frameNumber; + } else { + // if no ancestors are ready, traverse down and select ready tiles to minimize empty regions + descendantStack.push(original); + while (descendantStack.length > 0) { + var tile = descendantStack.pop(); + var children = tile.children; + var childrenLength = children.length; + for (var j = 0; j < childrenLength; ++j) { + var child = children[j]; + touch(tileset, child, outOfCore); + if (child.contentAvailable) { + child.selected = true; + child._finalResolution = true; + child._selectedFrame = frameState.frameNumber; + } + if (child._depth - original._depth < 2) { // prevent traversing too far + if (!child.contentAvailable || child.refine === Cesium3DTileRefine.ADD) { + descendantStack.push(child); + } + } + } + } + } } + } - var vs = 'attribute vec3 a_position; \n' + - 'varying vec4 v_color; \n' + - 'uniform vec2 u_pointSizeAndTilesetTime; \n' + - 'uniform vec4 u_constantColor; \n' + - 'uniform vec4 u_highlightColor; \n' + - 'float u_pointSize; \n' + - 'float u_tilesetTime; \n'; + var scratchStack = []; + var scratchStack2 = []; - vs += attributeDeclarations; + /** + * Traverse the tree while tiles are visible and check if their selected frame is the current frame. + * If so, add it to a selection queue. + * Tiles are sorted near to far so we can take advantage of early Z. + * Furthermore, this is a preorder traversal so children tiles are selected before ancestor tiles. + * + * The reason for the preorder traversal is so that tiles can easily be marked with their + * selection depth. A tile's _selectionDepth is its depth in the tree where all non-selected tiles are removed. + * This property is important for use in the stencil test because we want to render deeper tiles on top of their + * ancestors. If a tileset is very deep, the depth is unlikely to fit into the stencil buffer. + * + * We want to select children before their ancestors because there is no guarantee on the relationship between + * the children's z-depth and the ancestor's z-depth. We cannot rely on Z because we want the child to appear on top + * of ancestor regardless of true depth. The stencil tests used require children to be drawn first. @see {@link updateTiles} + * + * NOTE: this will no longer work when there is a chain of selected tiles that is longer than the size of the + * stencil buffer (usually 8 bits). In other words, the subset of the tree containing only selected tiles must be + * no deeper than 255. It is very, very unlikely this will cause a problem. + * + * NOTE: when the scene has inverted classification enabled, the stencil buffer will be masked to 4 bits. So, the + * selected tiles must be no deeper than 15. This is still very unlikely. + */ + function traverseAndSelect(tileset, root, frameState) { + var stack = scratchStack; + var ancestorStack = scratchStack2; - if (usesColors) { - if (isTranslucent) { - vs += 'attribute vec4 a_color; \n'; - } else if (isRGB565) { - vs += 'attribute float a_color; \n' + - 'const float SHIFT_RIGHT_11 = 1.0 / 2048.0; \n' + - 'const float SHIFT_RIGHT_5 = 1.0 / 32.0; \n' + - 'const float SHIFT_LEFT_11 = 2048.0; \n' + - 'const float SHIFT_LEFT_5 = 32.0; \n' + - 'const float NORMALIZE_6 = 1.0 / 64.0; \n' + - 'const float NORMALIZE_5 = 1.0 / 32.0; \n'; - } else { - vs += 'attribute vec3 a_color; \n'; + var lastAncestor; + stack.push(root); + while (stack.length > 0 || ancestorStack.length > 0) { + if (ancestorStack.length > 0) { + var waitingTile = ancestorStack[ancestorStack.length - 1]; + if (waitingTile._stackLength === stack.length) { + ancestorStack.pop(); + if (waitingTile === lastAncestor) { + waitingTile._finalResolution = true; + } + selectTile(tileset, waitingTile, frameState); + continue; + } } - } - if (hasNormals) { - if (isOctEncoded16P) { - vs += 'attribute vec2 a_normal; \n'; - } else { - vs += 'attribute vec3 a_normal; \n'; + + var tile = stack.pop(); + if (!defined(tile) || !isVisited(tile, frameState)) { + continue; } - } - if (hasBatchIds) { - vs += 'attribute float a_batchId; \n'; - } + var shouldSelect = tile.selected && tile._selectedFrame === frameState.frameNumber && tile.hasRenderableContent; - if (isQuantized) { - vs += 'uniform vec3 u_quantizedVolumeScale; \n'; - } + var children = tile.children; + var childrenLength = children.length; - if (hasColorStyle) { - vs += colorStyleFunction; - } + children.sort(sortChildrenByDistanceToCamera); - if (hasShowStyle) { - vs += showStyleFunction; - } + if (shouldSelect) { + if (tile.refine === Cesium3DTileRefine.ADD) { + tile._finalResolution = true; + selectTile(tileset, tile, frameState); + } else { + tile._selectionDepth = ancestorStack.length; - if (hasPointSizeStyle) { - vs += pointSizeStyleFunction; - } + if (tile._selectionDepth > 0) { + tileset._hasMixedContent = true; + } - vs += 'void main() \n' + - '{ \n' + - ' u_pointSize = u_pointSizeAndTilesetTime.x; \n' + - ' u_tilesetTime = u_pointSizeAndTilesetTime.y; \n'; + lastAncestor = tile; - if (usesColors) { - if (isTranslucent) { - vs += ' vec4 color = a_color; \n'; - } else if (isRGB565) { - vs += ' float compressed = a_color; \n' + - ' float r = floor(compressed * SHIFT_RIGHT_11); \n' + - ' compressed -= r * SHIFT_LEFT_11; \n' + - ' float g = floor(compressed * SHIFT_RIGHT_5); \n' + - ' compressed -= g * SHIFT_LEFT_5; \n' + - ' float b = compressed; \n' + - ' vec3 rgb = vec3(r * NORMALIZE_5, g * NORMALIZE_6, b * NORMALIZE_5); \n' + - ' vec4 color = vec4(rgb, 1.0); \n'; - } else { - vs += ' vec4 color = vec4(a_color, 1.0); \n'; + if (childrenLength === 0) { + tile._finalResolution = true; + selectTile(tileset, tile, frameState); + continue; + } + + ancestorStack.push(tile); + tile._stackLength = stack.length; + } } - } else { - vs += ' vec4 color = u_constantColor; \n'; - } - if (isQuantized) { - vs += ' vec3 position = a_position * u_quantizedVolumeScale; \n'; - } else { - vs += ' vec3 position = a_position; \n'; + for (var i = 0; i < childrenLength; ++i) { + var child = children[i]; + stack.push(child); + } } - vs += ' vec3 position_absolute = vec3(czm_model * vec4(position, 1.0)); \n'; + } - if (hasNormals) { - if (isOctEncoded16P) { - vs += ' vec3 normal = czm_octDecode(a_normal); \n'; - } else { - vs += ' vec3 normal = a_normal; \n'; + function selectTile(tileset, tile, frameState) { + // There may also be a tight box around just the tile's contents, e.g., for a city, we may be + // zoomed into a neighborhood and can cull the skyscrapers in the root tile. + if (tile.contentAvailable && ( + (tile._visibilityPlaneMask === CullingVolume.MASK_INSIDE) || + (tile.contentVisibility(frameState) !== Intersect.OUTSIDE) + )) { + tileset._selectedTiles.push(tile); + + var tileContent = tile.content; + if (tileContent.featurePropertiesDirty) { + // A feature's property in this tile changed, the tile needs to be re-styled. + tileContent.featurePropertiesDirty = false; + tile.lastStyleTime = 0; // Force applying the style to this tile + tileset._selectedTilesToStyle.push(tile); + } else if ((tile._lastSelectedFrameNumber !== frameState.frameNumber - 1) || tile.lastStyleTime === 0) { + // Tile is newly selected; it is selected this frame, but was not selected last frame. + tileset._selectedTilesToStyle.push(tile); } - } else { - vs += ' vec3 normal = vec3(1.0); \n'; + tile._lastSelectedFrameNumber = frameState.frameNumber; } + } - if (hasColorStyle) { - vs += ' color = getColorFromStyle(position, position_absolute, color, normal); \n'; + // PERFORMANCE_IDEA: is it worth exploiting frame-to-frame coherence in the sort, i.e., the + // list of children are probably fully or mostly sorted unless the camera moved significantly? + function sortChildrenByDistanceToCamera(a, b) { + // Sort by farthest child first since this is going on a stack + if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { + return b._centerZDepth - a._centerZDepth; } - if (hasShowStyle) { - vs += ' float show = float(getShowFromStyle(position, position_absolute, color, normal)); \n'; - } + return b._distanceToCamera - a._distanceToCamera; + } - if (hasPointSizeStyle) { - vs += ' gl_PointSize = getPointSizeFromStyle(position, position_absolute, color, normal); \n'; - } else { - vs += ' gl_PointSize = u_pointSize; \n'; - } + var emptyArray = freezeObject([]); - vs += ' color = color * u_highlightColor; \n'; + function BaseTraversal() { + this.tileset = undefined; + this.frameState = undefined; + this.outOfCore = undefined; + this.stack = new ManagedArray(); + this.leaves = new ManagedArray(); + this.baseScreenSpaceError = undefined; + this.internalDFS = new InternalBaseTraversal(); + } - if (hasNormals) { - vs += ' normal = czm_normal * normal; \n' + - ' float diffuseStrength = czm_getLambertDiffuse(czm_sunDirectionEC, normal); \n' + - ' diffuseStrength = max(diffuseStrength, 0.4); \n' + // Apply some ambient lighting - ' color *= diffuseStrength; \n'; + BaseTraversal.prototype.execute = function(tileset, root, baseScreenSpaceError, frameState, outOfCore) { + this.tileset = tileset; + this.frameState = frameState; + this.outOfCore = outOfCore; + this.leaves.length = 0; + this.baseScreenSpaceError = Math.max(baseScreenSpaceError, this.tileset._maximumScreenSpaceError); + this.internalDFS.tileset = this.tileset; + this.internalDFS.frameState = this.frameState; + this.internalDFS.outOfCore = this.outOfCore; + this.internalDFS.baseScreenSpaceError = this.baseScreenSpaceError; + depthFirstSearch(root, this); + }; + + BaseTraversal.prototype.visitStart = function(tile) { + if (!isVisited(tile, this.frameState)) { + visitTile(this.tileset, tile, this.frameState, this.outOfCore); } + }; - vs += ' v_color = color; \n' + - ' gl_Position = czm_modelViewProjection * vec4(position, 1.0); \n'; + BaseTraversal.prototype.visitEnd = function(tile) { + tile._lastVisitedFrame = this.frameState.frameNumber; + }; - if (hasNormals && backFaceCulling) { - vs += ' float visible = step(-normal.z, 0.0); \n' + - ' gl_Position *= visible; \n' + - ' gl_PointSize *= visible; \n'; + BaseTraversal.prototype.getChildren = function(tile) { + var tileset = this.tileset; + var outOfCore = this.outOfCore; + var frameState = this.frameState; + if (!baseUpdateAndCheckChildren(tileset, tile, this.baseScreenSpaceError, frameState)) { + return emptyArray; } - if (hasShowStyle) { - vs += ' gl_Position *= show; \n' + - ' gl_PointSize *= show; \n'; + var children = tile.children; + var childrenLength = children.length; + var allReady = true; + var replacementWithContent = tile.refine === Cesium3DTileRefine.REPLACE && tile.hasRenderableContent; + for (var i = 0; i < childrenLength; ++i) { + var child = children[i]; + loadTile(tileset, child, frameState, true); + touch(tileset, child, outOfCore); + + // content cannot be replaced until all of the nearest descendants with content are all loaded + if (replacementWithContent) { + if (!child.hasEmptyContent) { + allReady = allReady && child.contentAvailable; + } else { + allReady = allReady && this.internalDFS.execute(child); + } + } } - vs += '} \n'; + if (allReady) { + return children; + } - var fs = 'varying vec4 v_color; \n'; + return emptyArray; + }; - if (hasClippedContent) { - fs += 'uniform int u_clippingPlanesLength;' + - 'uniform vec4 u_clippingPlanes[czm_maxClippingPlanes]; \n' + - 'uniform vec4 u_clippingPlanesEdgeStyle; \n'; + function baseUpdateAndCheckChildren(tileset, tile, baseScreenSpaceError, frameState) { + if (hasAdditiveContent(tile)) { + tileset._desiredTiles.push(tile); } - fs += 'void main() \n' + - '{ \n' + - ' gl_FragColor = v_color; \n'; + // Stop traversal on the subtree since it will be destroyed + if (tile.hasTilesetContent && tile.contentExpired) { + return false; + } - if (hasClippedContent) { - var clippingFunction = clippingPlanes.unionClippingRegions ? 'czm_discardIfClippedWithUnion' : 'czm_discardIfClippedWithIntersect'; - fs += ' float clipDistance = ' + clippingFunction + '(u_clippingPlanes, u_clippingPlanesLength); \n' + - ' vec4 clippingPlanesEdgeColor = vec4(1.0); \n' + - ' clippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb; \n' + - ' float clippingPlanesEdgeWidth = u_clippingPlanesEdgeStyle.a; \n' + - ' if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n' + - ' { \n' + - ' gl_FragColor = clippingPlanesEdgeColor; \n' + - ' } \n'; + // stop traversal when we've attained the desired level of error + if (tile._screenSpaceError <= baseScreenSpaceError && !tile.hasTilesetContent) { + // update children so the leaf handler can check if any are visible for the children union bound optimization + updateChildren(tile, frameState); + return false; } - fs += '} \n'; + var childrenVisibility = updateChildren(tile, frameState); + var showAdditive = tile.refine === Cesium3DTileRefine.ADD; + var showReplacement = tile.refine === Cesium3DTileRefine.REPLACE && (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME) !== 0; - var drawVS = vs; - var drawFS = fs; + return showAdditive || showReplacement || tile.hasTilesetContent || !defined(tile._ancestorWithContent); + } - if (hasBatchTable) { - // Batched points always use the HIGHLIGHT color blend mode - drawVS = batchTable.getVertexShaderCallback(false, 'a_batchId')(drawVS); - drawFS = batchTable.getFragmentShaderCallback(false, undefined)(drawFS); + BaseTraversal.prototype.shouldVisit = function(tile) { + return isVisible(tile._visibilityPlaneMask); + }; + + BaseTraversal.prototype.leafHandler = function(tile) { + // if skipLevelOfDetail is off, leaves of the base traversal get pushed to tileset._desiredTiles. additive tiles have already been pushed + if (this.tileset._skipLevelOfDetail || !hasAdditiveContent(tile)) { + if (tile.refine === Cesium3DTileRefine.REPLACE && !childrenAreVisible(tile)) { + ++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion; + return; + } + this.leaves.push(tile); } + }; - var pickVS = vs; - var pickFS = fs; + function InternalBaseTraversal() { + this.tileset = undefined; + this.frameState = undefined; + this.outOfCore = undefined; + this.baseScreenSpaceError = undefined; + this.stack = new ManagedArray(); + this.allLoaded = undefined; + } - if (hasBatchTable) { - pickVS = batchTable.getPickVertexShaderCallback('a_batchId')(pickVS); - pickFS = batchTable.getPickFragmentShaderCallback()(pickFS); - } else { - pickFS = ShaderSource.createPickFragmentShaderSource(pickFS, 'uniform'); - } + InternalBaseTraversal.prototype.execute = function(root) { + this.allLoaded = true; + depthFirstSearch(root, this); + return this.allLoaded; + }; - var drawCommand = content._drawCommand; - if (defined(drawCommand.shaderProgram)) { - // Destroy the old shader - drawCommand.shaderProgram.destroy(); + InternalBaseTraversal.prototype.visitStart = function(tile) { + if (!isVisited(tile, this.frameState)) { + visitTile(this.tileset, tile, this.frameState, this.outOfCore); } - drawCommand.shaderProgram = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : drawVS, - fragmentShaderSource : drawFS, - attributeLocations : attributeLocations - }); + }; - var pickCommand = content._pickCommand; - if (defined(pickCommand.shaderProgram)) { - // Destroy the old shader - pickCommand.shaderProgram.destroy(); - } - pickCommand.shaderProgram = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : pickVS, - fragmentShaderSource : pickFS, - attributeLocations : attributeLocations - }); + InternalBaseTraversal.prototype.visitEnd = BaseTraversal.prototype.visitEnd; - try { - // Check if the shader compiles correctly. If not there is likely a syntax error with the style. - drawCommand.shaderProgram._bind(); - } catch (error) { - // Rephrase the error. - throw new RuntimeError('Error generating style shader: this may be caused by a type mismatch, index out-of-bounds, or other syntax error.'); + // Continue traversing until we have renderable content. We want the first descendants with content of the root to load + InternalBaseTraversal.prototype.shouldVisit = function(tile) { + return !tile.hasRenderableContent && isVisible(tile._visibilityPlaneMask); + }; + + InternalBaseTraversal.prototype.getChildren = function(tile) { + var tileset = this.tileset; + var frameState = this.frameState; + var outOfCore = this.outOfCore; + + if (!baseUpdateAndCheckChildren(tileset, tile, this.baseScreenSpaceError, frameState)) { + return emptyArray; } - } - function createFeatures(content) { - var tileset = content._tileset; - var featuresLength = content.featuresLength; - if (!defined(content._features) && (featuresLength > 0)) { - var features = new Array(featuresLength); - for (var i = 0; i < featuresLength; ++i) { - features[i] = new Cesium3DTileFeature(tileset, content, i); + var children = tile.children; + var childrenLength = children.length; + for (var i = 0; i < childrenLength; ++i) { + var child = children[i]; + loadTile(tileset, child, frameState, true); + touch(tileset, child, outOfCore); + if (!tile.contentAvailable) { + this.allLoaded = false; } - content._features = features; } + return children; + }; + + InternalBaseTraversal.prototype.updateAndCheckChildren = BaseTraversal.prototype.updateAndCheckChildren; + + function SkipTraversal(options) { + this.tileset = undefined; + this.frameState = undefined; + this.outOfCore = undefined; + this.queue1 = new ManagedArray(); + this.queue2 = new ManagedArray(); + this.internalDFS = new InternalSkipTraversal(options.selectionHeuristic); + this.maxChildrenLength = 0; + this.scratchQueue = new ManagedArray(); } - /** - * @inheritdoc Cesium3DTileContent#hasProperty - */ - PointCloud3DTileContent.prototype.hasProperty = function(batchId, name) { - if (defined(this._batchTable)) { - return this._batchTable.hasProperty(batchId, name); - } - return false; + SkipTraversal.prototype.execute = function(tileset, root, frameState, outOfCore) { + this.tileset = tileset; + this.frameState = frameState; + this.outOfCore = outOfCore; + this.internalDFS.frameState = frameState; + this.internalDFS.outOfCore = outOfCore; + + this.maxChildrenLength = 0; + breadthFirstSearch(root, this); + this.queue1.length = 0; + this.queue2.length = 0; + this.scratchQueue.length = 0; + this.scratchQueue.trim(this.maxChildrenLength); }; - /** - * Part of the {@link Cesium3DTileContent} interface. - * - * In this context a feature refers to a group of points that share the same BATCH_ID. - * For example all the points that represent a door in a house point cloud would be a feature. - * - * Features are backed by a batch table and can be colored, shown/hidden, picked, etc like features - * in b3dm and i3dm. - * - * When the BATCH_ID semantic is omitted and the point cloud stores per-point properties, they - * are not accessible by getFeature. They are only used for dynamic styling. - */ - PointCloud3DTileContent.prototype.getFeature = function(batchId) { - if (!defined(this._batchTable)) { - return undefined; - } - var featuresLength = this.featuresLength; - if (!defined(batchId) || (batchId < 0) || (batchId >= featuresLength)) { - throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + (featuresLength - 1) + ').'); + SkipTraversal.prototype.visitStart = function(tile) { + if (!isVisited(tile, this.frameState)) { + visitTile(this.tileset, tile, this.frameState, this.outOfCore); } - createFeatures(this); - return this._features[batchId]; }; - /** - * @inheritdoc Cesium3DTileContent#applyDebugSettings - */ - PointCloud3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - this._highlightColor = enabled ? color : Color.WHITE; + SkipTraversal.prototype.visitEnd = BaseTraversal.prototype.visitEnd; + + SkipTraversal.prototype.getChildren = function(tile) { + this.scratchQueue.length = 0; + this.internalDFS.execute(tile, this.scratchQueue); + this.maxChildrenLength = Math.max(this.maxChildrenLength, this.scratchQueue.length); + return this.scratchQueue; }; - /** - * @inheritdoc Cesium3DTileContent#applyStyle - */ - PointCloud3DTileContent.prototype.applyStyle = function(frameState, style) { - if (defined(this._batchTable)) { - this._batchTable.applyStyle(frameState, style); - } else { - createShaders(this, frameState, style); + SkipTraversal.prototype.leafHandler = function(tile) { + // additive tiles have already been pushed + if (!hasAdditiveContent(tile) && !isVisited(tile, this.frameState)) { + this.tileset._desiredTiles.push(tile); } }; - var scratchComputedTranslation = new Cartesian4(); - var scratchComputedMatrixIn2D = new Matrix4(); + function InternalSkipTraversal(selectionHeuristic) { + this.selectionHeuristic = selectionHeuristic; + this.tileset = undefined; + this.frameState = undefined; + this.outOfCore = undefined; + this.root = undefined; + this.queue = undefined; + this.stack = new ManagedArray(); + } - /** - * @inheritdoc Cesium3DTileContent#update - */ - PointCloud3DTileContent.prototype.update = function(tileset, frameState) { - var modelMatrix = this._tile.computedTransform; - var modelMatrixChanged = !Matrix4.equals(this._modelMatrix, modelMatrix); - var updateModelMatrix = modelMatrixChanged || this._mode !== frameState.mode; + InternalSkipTraversal.prototype.execute = function(root, queue) { + this.tileset = root._tileset; + this.root = root; + this.queue = queue; + depthFirstSearch(root, this); + }; - this._mode = frameState.mode; + InternalSkipTraversal.prototype.visitStart = function(tile) { + if (!isVisited(tile, this.frameState)) { + visitTile(this.tileset, tile, this.frameState, this.outOfCore); + } + }; - var context = frameState.context; + InternalSkipTraversal.prototype.visitEnd = BaseTraversal.prototype.visitEnd; - // update clipping planes - var clippingPlanes = this._tileset.clippingPlanes; - var clippingEnabled = defined(clippingPlanes) && clippingPlanes.enabled && this._tile._isClipped; + InternalSkipTraversal.prototype.getChildren = function(tile) { + var tileset = this.tileset; + var maximumScreenSpaceError = tileset._maximumScreenSpaceError; - var unionClippingRegions = false; - var length = 0; - if (clippingEnabled) { - unionClippingRegions = clippingPlanes.unionClippingRegions; - length = clippingPlanes.length; + // Stop traversal on the subtree since it will be destroyed + if (tile.hasTilesetContent && tile.contentExpired) { + return emptyArray; } - var packedPlanes = this._packedClippingPlanes; - var packedLength = packedPlanes.length; - if (packedLength !== length) { - packedPlanes.length = length; - - for (var i = 0; i < length; ++i) { - packedPlanes[i] = new Cartesian4(); + if (!tile.hasTilesetContent) { + if (tile.refine === Cesium3DTileRefine.ADD) { + // Always load additive tiles + loadTile(tileset, tile, this.frameState, true); + if (hasAdditiveContent(tile)) { + tileset._desiredTiles.push(tile); + } } - } - if (!defined(this._drawCommand)) { - createResources(this, frameState); - createShaders(this, frameState, tileset.style); - updateModelMatrix = true; + // stop traversal when we've attained the desired level of error + if (tile._screenSpaceError <= maximumScreenSpaceError) { + updateChildren(tile, this.frameState); + return emptyArray; + } - this._readyPromise.resolve(this); - this._parsedContent = undefined; // Unload + // if we have reached the skipping threshold without any loaded ancestors, return empty so this tile is loaded + if ( + (!tile.hasEmptyContent && tile.contentUnloaded) && + defined(tile._ancestorWithLoadedContent) && + this.selectionHeuristic(tileset, tile._ancestorWithLoadedContent, tile)) { + updateChildren(tile, this.frameState); + return emptyArray; + } } - if (this._isClipped !== clippingEnabled || this._unionClippingRegions !== unionClippingRegions) { - this._isClipped = clippingEnabled; - this._unionClippingRegions = unionClippingRegions; + var childrenVisibility = updateChildren(tile, this.frameState); + var showAdditive = tile.refine === Cesium3DTileRefine.ADD && tile._screenSpaceError > maximumScreenSpaceError; + var showReplacement = tile.refine === Cesium3DTileRefine.REPLACE && (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME) !== 0; - createShaders(this, frameState, tileset.style); + // at least one child is visible, but is not in request volume. the parent must be selected + if (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_NOT_IN_REQUEST_VOLUME && tile.refine === Cesium3DTileRefine.REPLACE) { + this.tileset._desiredTiles.push(tile); } - if (updateModelMatrix) { - Matrix4.clone(modelMatrix, this._modelMatrix); - if (defined(this._rtcCenter)) { - Matrix4.multiplyByTranslation(modelMatrix, this._rtcCenter, this._drawCommand.modelMatrix); - } else if (defined(this._quantizedVolumeOffset)) { - Matrix4.multiplyByTranslation(modelMatrix, this._quantizedVolumeOffset, this._drawCommand.modelMatrix); - } else { - Matrix4.clone(modelMatrix, this._drawCommand.modelMatrix); + if (showAdditive || showReplacement || tile.hasTilesetContent) { + var children = tile.children; + var childrenLength = children.length; + for (var i = 0; i < childrenLength; ++i) { + touch(tileset, children[i], this.outOfCore); } + return children; + } - if (frameState.mode !== SceneMode.SCENE3D) { - var projection = frameState.mapProjection; - modelMatrix = this._drawCommand.modelMatrix; - var translation = Matrix4.getColumn(modelMatrix, 3, scratchComputedTranslation); - if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) { - Transforms.basisTo2D(projection, modelMatrix, modelMatrix); - } else { - var center = this._tile.boundingSphere.center; - var to2D = Transforms.wgs84To2DModelMatrix(projection, center, scratchComputedMatrixIn2D); - Matrix4.multiply(to2D, modelMatrix, modelMatrix); - } - } + return emptyArray; + }; - Matrix4.clone(this._drawCommand.modelMatrix, this._pickCommand.modelMatrix); + InternalSkipTraversal.prototype.shouldVisit = function(tile) { + return isVisibleAndMeetsSSE(this.tileset, tile, this.frameState); + }; - var boundingVolume; - if (defined(this._tile._contentBoundingVolume)) { - boundingVolume = this._mode === SceneMode.SCENE3D ? this._tile._contentBoundingVolume.boundingSphere : this._tile._contentBoundingVolume2D.boundingSphere; - } else { - boundingVolume = this._mode === SceneMode.SCENE3D ? this._tile._boundingVolume.boundingSphere : this._tile._boundingVolume2D.boundingSphere; + InternalSkipTraversal.prototype.leafHandler = function(tile) { + if (tile !== this.root) { + if (tile.refine === Cesium3DTileRefine.REPLACE && !childrenAreVisible(tile)) { + ++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion; + return; } - - this._drawCommand.boundingVolume = boundingVolume; - this._pickCommand.boundingVolume = boundingVolume; + if (!tile.hasEmptyContent) { + if (this.tileset.loadSiblings) { + var parent = tile.parent; + var tiles = parent.children; + var length = tiles.length; + for (var i = 0; i < length; ++i) { + loadTile(this.tileset, tiles[i], this.frameState, false); + touch(this.tileset, tiles[i], this.outOfCore); + } + } else { + loadTile(this.tileset, tile, this.frameState, true); + touch(this.tileset, tile, this.outOfCore); + } + } + this.queue.push(tile); + } else if (!hasAdditiveContent(tile)) { + // additive tiles have already been pushed + this.tileset._desiredTiles.push(tile); } + }; - if (clippingEnabled) { - Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); - clippingPlanes.transformAndPackPlanes(this._modelViewMatrix, packedPlanes); + function updateChildren(tile, frameState) { + if (isVisited(tile, frameState)) { + return tile._childrenVisibility; } - this._drawCommand.castShadows = ShadowMode.castShadows(tileset.shadows); - this._drawCommand.receiveShadows = ShadowMode.receiveShadows(tileset.shadows); + var children = tile.children; - if (this.backFaceCulling !== this._backFaceCulling) { - this._backFaceCulling = this.backFaceCulling; - createShaders(this, frameState, tileset.style); - } + updateTransforms(children, tile.computedTransform); + computeDistanceToCamera(children, frameState); - // Update the render state - var isTranslucent = (this._highlightColor.alpha < 1.0) || (this._constantColor.alpha < 1.0) || this._styleTranslucent; - this._drawCommand.renderState = isTranslucent ? this._translucentRenderState : this._opaqueRenderState; - this._drawCommand.pass = isTranslucent ? Pass.TRANSLUCENT : Pass.CESIUM_3D_TILE; + return computeChildrenVisibility(tile, frameState); + } - if (defined(this._batchTable)) { - this._batchTable.update(tileset, frameState); - } + function isVisited(tile, frameState) { + // because the leaves of one tree traversal are the root of the subsequent traversal, avoid double visitation + return tile._lastVisitedFrame === frameState.frameNumber; + } - var commandList = frameState.commandList; + function visitTile(tileset, tile, frameState, outOfCore) { + ++tileset._statistics.visited; + tile.selected = false; + tile._finalResolution = false; + computeSSE(tile, frameState); + touch(tileset, tile, outOfCore); + tile.updateExpiration(); + tile._ancestorWithContent = undefined; + tile._ancestorWithLoadedContent = undefined; + var parent = tile.parent; + if (defined(parent)) { + var replace = parent.refine === Cesium3DTileRefine.REPLACE; + tile._ancestorWithContent = (replace && parent.hasRenderableContent) ? parent : parent._ancestorWithContent; + tile._ancestorWithLoadedContent = (replace && parent.hasRenderableContent && parent.contentAvailable) ? parent : parent._ancestorWithLoadedContent; + } + } - var passes = frameState.passes; - if (passes.render) { - commandList.push(this._drawCommand); + function touch(tileset, tile, outOfCore) { + if (!outOfCore) { + return; } - if (passes.pick) { - commandList.push(this._pickCommand); + var node = tile.replacementNode; + if (defined(node)) { + tileset._replacementList.splice(tileset._replacementSentinel, node); } - }; - - /** - * @inheritdoc Cesium3DTileContent#isDestroyed - */ - PointCloud3DTileContent.prototype.isDestroyed = function() { - return false; - }; + } - /** - * @inheritdoc Cesium3DTileContent#destroy - */ - PointCloud3DTileContent.prototype.destroy = function() { - var command = this._drawCommand; - var pickCommand = this._pickCommand; - if (defined(command)) { - command.vertexArray = command.vertexArray && command.vertexArray.destroy(); - command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); - pickCommand.shaderProgram = pickCommand.shaderProgram && pickCommand.shaderProgram.destroy(); + function computeSSE(tile, frameState) { + if (tile._screenSpaceErrorComputedFrame !== frameState.frameNumber) { + tile._screenSpaceErrorComputedFrame = frameState.frameNumber; + tile._screenSpaceError = getScreenSpaceError(tile._tileset, tile.geometricError, tile, frameState); } - this._batchTable = this._batchTable && this._batchTable.destroy(); - return destroyObject(this); - }; - - return PointCloud3DTileContent; -}); + } -define('Scene/Tileset3DTileContent',[ - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/getStringFromTypedArray', - '../Core/RuntimeError', - '../ThirdParty/when' - ], function( - defaultValue, - defineProperties, - destroyObject, - getStringFromTypedArray, - RuntimeError, - when) { - 'use strict'; + function checkAdditiveVisibility(tileset, tile, frameState) { + if (defined(tile.parent) && (tile.parent.refine === Cesium3DTileRefine.ADD)) { + return isVisibleAndMeetsSSE(tileset, tile, frameState); + } + return true; + } - /** - * Represents content for a tile in a - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset whose - * content points to another 3D Tiles tileset. - * <p> - * Implements the {@link Cesium3DTileContent} interface. - * </p> - * - * @alias Tileset3DTileContent - * @constructor - * - * @private - */ - function Tileset3DTileContent(tileset, tile, url, arrayBuffer, byteOffset) { - this._tileset = tileset; - this._tile = tile; - this._url = url; - this._readyPromise = when.defer(); + function loadTile(tileset, tile, frameState, checkVisibility) { + if ((tile.contentUnloaded || tile.contentExpired) && tile._requestedFrame !== frameState.frameNumber) { + if (!checkVisibility || checkAdditiveVisibility(tileset, tile, frameState)) { + tile._requestedFrame = frameState.frameNumber; + tileset._requestedTiles.push(tile); + } + } + } - /** - * @inheritdoc Cesium3DTileContent#featurePropertiesDirty - */ - this.featurePropertiesDirty = false; + function computeChildrenVisibility(tile, frameState) { + var flag = Cesium3DTileChildrenVisibility.NONE; + var children = tile.children; + var childrenLength = children.length; + var visibilityPlaneMask = tile._visibilityPlaneMask; + for (var k = 0; k < childrenLength; ++k) { + var child = children[k]; - initialize(this, arrayBuffer, byteOffset); - } + var visibilityMask = child.visibility(frameState, visibilityPlaneMask); - defineProperties(Tileset3DTileContent.prototype, { - /** - * @inheritdoc Cesium3DTileContent#featuresLength - */ - featuresLength : { - get : function() { - return 0; + if (isVisible(visibilityMask)) { + flag |= Cesium3DTileChildrenVisibility.VISIBLE; } - }, - /** - * @inheritdoc Cesium3DTileContent#pointsLength - */ - pointsLength : { - get : function() { - return 0; + if (!child.insideViewerRequestVolume(frameState)) { + if (isVisible(visibilityMask)) { + flag |= Cesium3DTileChildrenVisibility.VISIBLE_NOT_IN_REQUEST_VOLUME; + } + visibilityMask = CullingVolume.MASK_OUTSIDE; + } else { + flag |= Cesium3DTileChildrenVisibility.IN_REQUEST_VOLUME; + if (isVisible(visibilityMask)) { + flag |= Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME; + } } - }, - /** - * @inheritdoc Cesium3DTileContent#trianglesLength - */ - trianglesLength : { - get : function() { - return 0; - } - }, + child._visibilityPlaneMask = visibilityMask; + } - /** - * @inheritdoc Cesium3DTileContent#geometryByteLength - */ - geometryByteLength : { - get : function() { - return 0; - } - }, + tile._childrenVisibility = flag; - /** - * @inheritdoc Cesium3DTileContent#texturesByteLength - */ - texturesByteLength : { - get : function() { - return 0; - } - }, + return flag; + } - /** - * @inheritdoc Cesium3DTileContent#batchTableByteLength - */ - batchTableByteLength : { - get : function() { - return 0; - } - }, + function getScreenSpaceError(tileset, geometricError, tile, frameState) { + if (geometricError === 0.0) { + // Leaf tiles do not have any error so save the computation + return 0.0; + } - /** - * @inheritdoc Cesium3DTileContent#innerContents - */ - innerContents : { - get : function() { - return undefined; - } - }, + // Avoid divide by zero when viewer is inside the tile + var camera = frameState.camera; + var frustum = camera.frustum; + var context = frameState.context; + var height = context.drawingBufferHeight; - /** - * @inheritdoc Cesium3DTileContent#readyPromise - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; + var error; + if (frameState.mode === SceneMode.SCENE2D || frustum instanceof OrthographicFrustum) { + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; } - }, + var width = context.drawingBufferWidth; + var pixelSize = Math.max(frustum.top - frustum.bottom, frustum.right - frustum.left) / Math.max(width, height); + error = geometricError / pixelSize; + } else { + var distance = Math.max(tile._distanceToCamera, CesiumMath.EPSILON7); + var sseDenominator = camera.frustum.sseDenominator; + error = (geometricError * height) / (distance * sseDenominator); - /** - * @inheritdoc Cesium3DTileContent#tileset - */ - tileset : { - get : function() { - return this._tileset; + if (tileset.dynamicScreenSpaceError) { + var density = tileset._dynamicScreenSpaceErrorComputedDensity; + var factor = tileset.dynamicScreenSpaceErrorFactor; + var dynamicError = CesiumMath.fog(distance, density) * factor; + error -= dynamicError; } - }, + } - /** - * @inheritdoc Cesium3DTileContent#tile - */ - tile : { - get : function() { - return this._tile; - } - }, + return error; + } - /** - * @inheritdoc Cesium3DTileContent#url - */ - url : { - get : function() { - return this._url; - } - }, + function computeDistanceToCamera(children, frameState) { + var length = children.length; + for (var i = 0; i < length; ++i) { + var child = children[i]; + child._distanceToCamera = child.distanceToTile(frameState); + child._centerZDepth = child.distanceToTileCenter(frameState); + } + } - /** - * @inheritdoc Cesium3DTileContent#batchTable - */ - batchTable : { - get : function() { - return undefined; - } + function updateTransforms(children, parentTransform) { + var length = children.length; + for (var i = 0; i < length; ++i) { + var child = children[i]; + child.updateTransform(parentTransform); } - }); + } - function initialize(content, arrayBuffer, byteOffset) { - byteOffset = defaultValue(byteOffset, 0); - var uint8Array = new Uint8Array(arrayBuffer); - var jsonString = getStringFromTypedArray(uint8Array, byteOffset); - var tilesetJson; + function isVisible(visibilityPlaneMask) { + return visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE; + } - try { - tilesetJson = JSON.parse(jsonString); - } catch (error) { - content._readyPromise.reject(new RuntimeError('Invalid tile content.')); - return; + function isVisibleAndMeetsSSE(tileset, tile, frameState) { + var maximumScreenSpaceError = tileset._maximumScreenSpaceError; + var parent = tile.parent; + if (!defined(parent)) { + return isVisible(tile._visibilityPlaneMask); } + var showAdditive = parent.refine === Cesium3DTileRefine.ADD && parent._screenSpaceError > maximumScreenSpaceError; - content._tileset.loadTileset(content._url, tilesetJson, content._tile); - content._readyPromise.resolve(content); + return isVisible(tile._visibilityPlaneMask) && (!showAdditive || getScreenSpaceError(tileset, parent.geometricError, tile, frameState) > maximumScreenSpaceError); } - /** - * Part of the {@link Cesium3DTileContent} interface. <code>Tileset3DTileContent</code> - * always returns <code>false</code> since a tile of this type does not have any features. - */ - Tileset3DTileContent.prototype.hasProperty = function(batchId, name) { - return false; - }; + function childrenAreVisible(tile) { + // optimization does not apply for additive refinement + return tile.refine === Cesium3DTileRefine.ADD || tile.children.length === 0 || tile._childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE !== 0; + } - /** - * Part of the {@link Cesium3DTileContent} interface. <code>Tileset3DTileContent</code> - * always returns <code>undefined</code> since a tile of this type does not have any features. - */ - Tileset3DTileContent.prototype.getFeature = function(batchId) { - return undefined; - }; + function hasAdditiveContent(tile) { + return tile.refine === Cesium3DTileRefine.ADD && tile.hasRenderableContent; + } - /** - * @inheritdoc Cesium3DTileContent#applyDebugSettings - */ - Tileset3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - }; + function depthFirstSearch(root, options) { + var stack = options.stack; - /** - * @inheritdoc Cesium3DTileContent#applyStyle - */ - Tileset3DTileContent.prototype.applyStyle = function(frameState, style) { - }; + if (defined(root) && (!defined(options.shouldVisit) || options.shouldVisit(root))) { + stack.push(root); + } - /** - * @inheritdoc Cesium3DTileContent#update - */ - Tileset3DTileContent.prototype.update = function(tileset, frameState) { - }; + var maxLength = 0; + while (stack.length > 0) { + maxLength = Math.max(maxLength, stack.length); - /** - * @inheritdoc Cesium3DTileContent#isDestroyed - */ - Tileset3DTileContent.prototype.isDestroyed = function() { - return false; - }; + var tile = stack.pop(); + options.visitStart(tile); + var children = options.getChildren(tile); + var isNativeArray = !defined(children.get); + var length = children.length; + for (var i = 0; i < length; ++i) { + var child = isNativeArray ? children[i] : children.get(i); - /** - * @inheritdoc Cesium3DTileContent#destroy - */ - Tileset3DTileContent.prototype.destroy = function() { - return destroyObject(this); - }; + if (!defined(options.shouldVisit) || options.shouldVisit(child)) { + stack.push(child); + } + } - return Tileset3DTileContent; -}); + if (length === 0 && defined(options.leafHandler)) { + options.leafHandler(tile); + } + options.visitEnd(tile); + } -define('Scene/Cesium3DTileContentFactory',[ - './Batched3DModel3DTileContent', - './Composite3DTileContent', - './Instanced3DModel3DTileContent', - './PointCloud3DTileContent', - './Tileset3DTileContent' - ], function( - Batched3DModel3DTileContent, - Composite3DTileContent, - Instanced3DModel3DTileContent, - PointCloud3DTileContent, - Tileset3DTileContent) { - 'use strict'; + stack.trim(maxLength); + } - /** - * Maps a tile's magic field in its header to a new content object for the tile's payload. - * - * @private - */ - var Cesium3DTileContentFactory = { - b3dm : function(tileset, tile, url, arrayBuffer, byteOffset) { - return new Batched3DModel3DTileContent(tileset, tile, url, arrayBuffer, byteOffset); - }, - pnts : function(tileset, tile, url, arrayBuffer, byteOffset) { - return new PointCloud3DTileContent(tileset, tile, url, arrayBuffer, byteOffset); - }, - i3dm : function(tileset, tile, url, arrayBuffer, byteOffset) { - return new Instanced3DModel3DTileContent(tileset, tile, url, arrayBuffer, byteOffset); - }, - cmpt : function(tileset, tile, url, arrayBuffer, byteOffset) { - // Send in the factory in order to avoid a cyclical dependency - return new Composite3DTileContent(tileset, tile, url, arrayBuffer, byteOffset, Cesium3DTileContentFactory); - }, - json : function(tileset, tile, url, arrayBuffer, byteOffset) { - return new Tileset3DTileContent(tileset, tile, url, arrayBuffer, byteOffset); + function breadthFirstSearch(root, options) { + var queue1 = options.queue1; + var queue2 = options.queue2; + + if (defined(root) && (!defined(options.shouldVisit) || options.shouldVisit(root))) { + queue1.push(root); } - }; - return Cesium3DTileContentFactory; -}); + var maxLength = 0; + while (queue1.length > 0) { + var length = queue1.length; + maxLength = Math.max(maxLength, length); -define('Scene/Cesium3DTileContentState',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + for (var i = 0; i < length; ++i) { + var tile = queue1.get(i); + options.visitStart(tile); + var children = options.getChildren(tile); + var isNativeArray = !defined(children.get); + var childrenLength = children.length; + for (var j = 0; j < childrenLength; ++j) { + var child = isNativeArray ? children[j] : children.get(j); - /** - * @private - */ - var Cesium3DTileContentState = { - UNLOADED : 0, // Has never been requested - LOADING : 1, // Is waiting on a pending request - PROCESSING : 2, // Request received. Contents are being processed for rendering. Depending on the content, it might make its own requests for external data. - READY : 3, // Ready to render. - EXPIRED : 4, // Is expired and will be unloaded once new content is loaded. - FAILED : 5 // Request failed. - }; + if (!defined(options.shouldVisit) || options.shouldVisit(child)) { + queue2.push(child); + } + } - return freezeObject(Cesium3DTileContentState); -}); + if (childrenLength === 0 && defined(options.leafHandler)) { + options.leafHandler(tile); + } + options.visitEnd(tile); + } -define('Scene/Cesium3DTileOptimizationHint',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + queue1.length = 0; + var temp = queue1; + queue1 = queue2; + queue2 = temp; + options.queue1 = queue1; + options.queue2 = queue2; + } - /** - * Hint defining optimization support for a 3D tile - * - * @exports Cesium3DTileOptimizationHint - * - * @private - */ - var Cesium3DTileOptimizationHint = { - NOT_COMPUTED: -1, - USE_OPTIMIZATION: 1, - SKIP_OPTIMIZATION: 0 - }; + queue1.length = 0; + queue2.length = 0; - return freezeObject(Cesium3DTileOptimizationHint); -}); + queue1.trim(maxLength); + queue2.trim(maxLength); + } -define('Scene/Cesium3DTileRefine',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + Cesium3DTilesetTraversal.selectTiles = selectTiles; - /** - * The refinement approach for a tile. - * <p> - * See the {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/schema/tile.schema.json|tile schema} - * in the 3D Tiles spec. - * </p> - * - * @exports Cesium3DTileRefine - * - * @private - */ - var Cesium3DTileRefine = { - /** - * Render this tile and, if it doesn't meet the screen space error, also refine to its children. - * - * @type {Number} - * @constant - */ - ADD : 0, + Cesium3DTilesetTraversal.BaseTraversal = BaseTraversal; - /** - * Render this tile or, if it doesn't meet the screen space error, refine to its descendants instead. - * - * @type {Number} - * @constant - */ - REPLACE : 1 - }; + Cesium3DTilesetTraversal.SkipTraversal = SkipTraversal; - return freezeObject(Cesium3DTileRefine); + return Cesium3DTilesetTraversal; }); -define('Scene/Empty3DTileContent',[ - '../Core/defineProperties', - '../Core/destroyObject' +define('Scene/Cesium3DTileStyleEngine',[ + '../Core/defined', + '../Core/defineProperties' ], function( - defineProperties, - destroyObject) { + defined, + defineProperties) { 'use strict'; /** - * Represents empty content for tiles in a - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles} tileset that - * do not have content, e.g., because they are used to optimize hierarchical culling. - * <p> - * Implements the {@link Cesium3DTileContent} interface. - * </p> - * - * @alias Empty3DTileContent - * @constructor - * * @private */ - function Empty3DTileContent(tileset, tile) { - this._tileset = tileset; - this._tile = tile; - - /** - * @inheritdoc Cesium3DTileContent#featurePropertiesDirty - */ - this.featurePropertiesDirty = false; + function Cesium3DTileStyleEngine() { + this._style = undefined; // The style provided by the user + this._styleDirty = false; // true when the style is reassigned + this._lastStyleTime = 0; // The "time" when the last style was assigned } - defineProperties(Empty3DTileContent.prototype, { - /** - * @inheritdoc Cesium3DTileContent#featuresLength - */ - featuresLength : { - get : function() { - return 0; - } - }, - - /** - * @inheritdoc Cesium3DTileContent#pointsLength - */ - pointsLength : { - get : function() { - return 0; - } - }, - - /** - * @inheritdoc Cesium3DTileContent#trianglesLength - */ - trianglesLength : { + defineProperties(Cesium3DTileStyleEngine.prototype, { + style : { get : function() { - return 0; + return this._style; + }, + set : function(value) { + this._style = value; + this._styleDirty = true; } - }, + } + }); - /** - * @inheritdoc Cesium3DTileContent#geometryByteLength - */ - geometryByteLength : { - get : function() { - return 0; - } - }, + Cesium3DTileStyleEngine.prototype.makeDirty = function() { + this._styleDirty = true; + }; - /** - * @inheritdoc Cesium3DTileContent#texturesByteLength - */ - texturesByteLength : { - get : function() { - return 0; - } - }, + Cesium3DTileStyleEngine.prototype.applyStyle = function(tileset, frameState) { + if (!tileset.ready) { + return; + } - /** - * @inheritdoc Cesium3DTileContent#batchTableByteLength - */ - batchTableByteLength : { - get : function() { - return 0; - } - }, + if (defined(this._style) && !this._style.ready) { + return; + } - /** - * @inheritdoc Cesium3DTileContent#innerContents - */ - innerContents : { - get : function() { - return undefined; - } - }, + var styleDirty = this._styleDirty; - /** - * @inheritdoc Cesium3DTileContent#readyPromise - */ - readyPromise : { - get : function() { - return undefined; - } - }, + if (frameState.passes.render) { + // Don't reset until the color pass, e.g., for mouse-over picking + this._styleDirty = false; + } - /** - * @inheritdoc Cesium3DTileContent#tileset - */ - tileset : { - get : function() { - return this._tileset; - } - }, + if (styleDirty) { + // Increase "time", so the style is applied to all visible tiles + ++this._lastStyleTime; + } - /** - * @inheritdoc Cesium3DTileContent#tile - */ - tile : { - get : function() { - return this._tile; - } - }, + var lastStyleTime = this._lastStyleTime; + var statistics = tileset._statistics; - /** - * @inheritdoc Cesium3DTileContent#url - */ - url: { - get: function() { - return undefined; - } - }, + // If a new style was assigned, loop through all the visible tiles; otherwise, loop through + // only the tiles that are newly visible, i.e., they are visible this frame, but were not + // visible last frame. In many cases, the newly selected tiles list will be short or empty. + var tiles = styleDirty ? tileset._selectedTiles : tileset._selectedTilesToStyle; + // PERFORMANCE_IDEA: does mouse-over picking basically trash this? We need to style on + // pick, for example, because a feature's show may be false. - /** - * @inheritdoc Cesium3DTileContent#batchTable - */ - batchTable : { - get : function() { - return undefined; + var length = tiles.length; + for (var i = 0; i < length; ++i) { + var tile = tiles[i]; + if (tile.selected && (tile.lastStyleTime !== lastStyleTime)) { + // Apply the style to this tile if it wasn't already applied because: + // 1) the user assigned a new style to the tileset + // 2) this tile is now visible, but it wasn't visible when the style was first assigned + var content = tile.content; + tile.lastStyleTime = lastStyleTime; + content.applyStyle(frameState, this._style); + statistics.numberOfFeaturesStyled += content.featuresLength; + ++statistics.numberOfTilesStyled; } } - }); - - /** - * Part of the {@link Cesium3DTileContent} interface. <code>Empty3DTileContent</code> - * always returns <code>false</code> since a tile of this type does not have any features. - */ - Empty3DTileContent.prototype.hasProperty = function(batchId, name) { - return false; - }; - - /** - * Part of the {@link Cesium3DTileContent} interface. <code>Empty3DTileContent</code> - * always returns <code>undefined</code> since a tile of this type does not have any features. - */ - Empty3DTileContent.prototype.getFeature = function(batchId) { - return undefined; - }; - - /** - * @inheritdoc Cesium3DTileContent#applyDebugSettings - */ - Empty3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - }; - - /** - * @inheritdoc Cesium3DTileContent#applyStyle - */ - Empty3DTileContent.prototype.applyStyle = function(frameState, style) { - }; - - /** - * @inheritdoc Cesium3DTileContent#update - */ - Empty3DTileContent.prototype.update = function(tileset, frameState) { - }; - - /** - * @inheritdoc Cesium3DTileContent#isDestroyed - */ - Empty3DTileContent.prototype.isDestroyed = function() { - return false; - }; - - /** - * @inheritdoc Cesium3DTileContent#destroy - */ - Empty3DTileContent.prototype.destroy = function() { - return destroyObject(this); }; - return Empty3DTileContent; + return Cesium3DTileStyleEngine; }); -define('Scene/TileBoundingRegion',[ - '../Core/BoundingSphere', +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PostProcessFilters/PointCloudEyeDomeLighting',[],function() { + 'use strict'; + return "#extension GL_EXT_frag_depth : enable\n\ +uniform sampler2D u_pointCloud_colorTexture;\n\ +uniform sampler2D u_pointCloud_ecAndLogDepthTexture;\n\ +uniform vec3 u_distancesAndEdlStrength;\n\ +varying vec2 v_textureCoordinates;\n\ +vec2 neighborContribution(float log2Depth, vec2 padding)\n\ +{\n\ +vec2 depthAndLog2Depth = texture2D(u_pointCloud_ecAndLogDepthTexture, v_textureCoordinates + padding).zw;\n\ +if (depthAndLog2Depth.x == 0.0)\n\ +{\n\ +return vec2(0.0);\n\ +}\n\ +else\n\ +{\n\ +return vec2(max(0.0, log2Depth - depthAndLog2Depth.y), 1.0);\n\ +}\n\ +}\n\ +void main()\n\ +{\n\ +vec4 ecAlphaDepth = texture2D(u_pointCloud_ecAndLogDepthTexture, v_textureCoordinates);\n\ +if (length(ecAlphaDepth.xyz) < czm_epsilon7)\n\ +{\n\ +discard;\n\ +}\n\ +else\n\ +{\n\ +vec4 color = texture2D(u_pointCloud_colorTexture, v_textureCoordinates);\n\ +float distX = u_distancesAndEdlStrength.x;\n\ +float distY = u_distancesAndEdlStrength.y;\n\ +vec2 responseAndCount = vec2(0.0);\n\ +responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(0, distY));\n\ +responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(distX, 0));\n\ +responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(0, -distY));\n\ +responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(-distX, 0));\n\ +float response = responseAndCount.x / responseAndCount.y;\n\ +float shade = exp(-response * 300.0 * u_distancesAndEdlStrength.z);\n\ +color.rgb *= shade;\n\ +gl_FragColor = vec4(color);\n\ +gl_FragDepthEXT = czm_eyeToWindowCoordinates(vec4(ecAlphaDepth.xyz, 1.0)).z;\n\ +}\n\ +}\n\ +"; +}); +define('Scene/PointCloudEyeDomeLighting',[ '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/Check', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/Ellipsoid', - '../Core/GeometryInstance', - '../Core/IntersectionTests', - '../Core/Matrix4', - '../Core/OrientedBoundingBox', - '../Core/Plane', - '../Core/Ray', - '../Core/Rectangle', - '../Core/RectangleOutlineGeometry', - './PerInstanceColorAppearance', - './Primitive', - './SceneMode' + '../Core/clone', + '../Core/Color', + '../Core/combine', + '../Core/ComponentDatatype', + '../Core/defined', + '../Core/destroyObject', + '../Core/FeatureDetection', + '../Core/Geometry', + '../Core/GeometryAttribute', + '../Core/PixelFormat', + '../Core/PrimitiveType', + '../Renderer/BufferUsage', + '../Renderer/ClearCommand', + '../Renderer/DrawCommand', + '../Renderer/Framebuffer', + '../Renderer/Pass', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/Sampler', + '../Renderer/ShaderSource', + '../Renderer/ShaderProgram', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', + '../Renderer/VertexArray', + '../Scene/BlendEquation', + '../Scene/BlendFunction', + '../Scene/BlendingState', + '../Scene/StencilFunction', + '../Scene/StencilOperation', + '../Shaders/PostProcessFilters/PointCloudEyeDomeLighting' ], function( - BoundingSphere, Cartesian3, - Cartographic, - Check, - ColorGeometryInstanceAttribute, - defaultValue, - defineProperties, - Ellipsoid, - GeometryInstance, - IntersectionTests, - Matrix4, - OrientedBoundingBox, - Plane, - Ray, - Rectangle, - RectangleOutlineGeometry, - PerInstanceColorAppearance, - Primitive, - SceneMode) { + clone, + Color, + combine, + ComponentDatatype, + defined, + destroyObject, + FeatureDetection, + Geometry, + GeometryAttribute, + PixelFormat, + PrimitiveType, + BufferUsage, + ClearCommand, + DrawCommand, + Framebuffer, + Pass, + PixelDatatype, + RenderState, + Sampler, + ShaderSource, + ShaderProgram, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap, + VertexArray, + BlendEquation, + BlendFunction, + BlendingState, + StencilFunction, + StencilOperation, + PointCloudEyeDomeLightingShader + ) { 'use strict'; /** - * A tile bounding volume specified as a longitude/latitude/height region. - * @alias TileBoundingRegion - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Rectangle} options.rectangle The rectangle specifying the longitude and latitude range of the region. - * @param {Number} [options.minimumHeight=0.0] The minimum height of the region. - * @param {Number} [options.maximumHeight=0.0] The maximum height of the region. - * @param {Ellipsoid} [options.ellipsoid=Cesium.Ellipsoid.WGS84] The ellipsoid. + * Eye dome lighting. Does not support points with per-point translucency, but does allow translucent styling against the globe. + * Requires support for EXT_frag_depth, OES_texture_float, and WEBGL_draw_buffers extensions in WebGL 1.0. * * @private */ - function TileBoundingRegion(options) { - Check.typeOf.object('options', options); - Check.typeOf.object('options.rectangle', options.rectangle); - - this.rectangle = Rectangle.clone(options.rectangle); - this.minimumHeight = defaultValue(options.minimumHeight, 0.0); - this.maximumHeight = defaultValue(options.maximumHeight, 0.0); + function PointCloudEyeDomeLighting() { + this._framebuffer = undefined; + this._colorTexture = undefined; // color gbuffer + this._ecAndLogDepthTexture = undefined; // depth gbuffer + this._depthTexture = undefined; // needed to write depth so camera based on depth works + this._drawCommand = undefined; + this._clearCommand = undefined; - /** - * The world coordinates of the southwest corner of the tile's rectangle. - * - * @type {Cartesian3} - * @default Cartesian3() - */ - this.southwestCornerCartesian = new Cartesian3(); + this._strength = 1.0; + this._radius = 1.0; + } + + function createSampler() { + return new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }); + } - /** - * The world coordinates of the northeast corner of the tile's rectangle. - * - * @type {Cartesian3} - * @default Cartesian3() - */ - this.northeastCornerCartesian = new Cartesian3(); + function destroyFramebuffer(processor) { + var framebuffer = processor._framebuffer; + if (!defined(framebuffer)) { + return; + } - /** - * A normal that, along with southwestCornerCartesian, defines a plane at the western edge of - * the tile. Any position above (in the direction of the normal) this plane is outside the tile. - * - * @type {Cartesian3} - * @default Cartesian3() - */ - this.westNormal = new Cartesian3(); + processor._colorTexture.destroy(); + processor._ecAndLogDepthTexture.destroy(); + processor._depthTexture.destroy(); + framebuffer.destroy(); - /** - * A normal that, along with southwestCornerCartesian, defines a plane at the southern edge of - * the tile. Any position above (in the direction of the normal) this plane is outside the tile. - * Because points of constant latitude do not necessary lie in a plane, positions below this - * plane are not necessarily inside the tile, but they are close. - * - * @type {Cartesian3} - * @default Cartesian3() - */ - this.southNormal = new Cartesian3(); + processor._framebuffer = undefined; + processor._colorTexture = undefined; + processor._ecAndLogDepthTexture = undefined; + processor._depthTexture = undefined; + processor._drawCommand = undefined; + processor._clearCommand = undefined; + } - /** - * A normal that, along with northeastCornerCartesian, defines a plane at the eastern edge of - * the tile. Any position above (in the direction of the normal) this plane is outside the tile. - * - * @type {Cartesian3} - * @default Cartesian3() - */ - this.eastNormal = new Cartesian3(); + function createFramebuffer(processor, context) { + var screenWidth = context.drawingBufferWidth; + var screenHeight = context.drawingBufferHeight; - /** - * A normal that, along with northeastCornerCartesian, defines a plane at the eastern edge of - * the tile. Any position above (in the direction of the normal) this plane is outside the tile. - * Because points of constant latitude do not necessary lie in a plane, positions below this - * plane are not necessarily inside the tile, but they are close. - * - * @type {Cartesian3} - * @default Cartesian3() - */ - this.northNormal = new Cartesian3(); + var colorTexture = new Texture({ + context : context, + width : screenWidth, + height : screenHeight, + pixelFormat : PixelFormat.RGBA, + // Firefox as of 57.02 throws FRAMEBUFFER_UNSUPPORTED 0x8CDD if this doesn't match what's in ecTexture + pixelDatatype : FeatureDetection.isFirefox() ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE, + sampler : createSampler() + }); - var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); - computeBox(this, options.rectangle, ellipsoid); + var ecTexture = new Texture({ + context : context, + width : screenWidth, + height : screenHeight, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.FLOAT, + sampler : createSampler() + }); - // An oriented bounding box that encloses this tile's region. This is used to calculate tile visibility. - this._orientedBoundingBox = OrientedBoundingBox.fromRectangle(this.rectangle, this.minimumHeight, this.maximumHeight, ellipsoid); + var depthTexture = new Texture({ + context : context, + width : screenWidth, + height : screenHeight, + pixelFormat : PixelFormat.DEPTH_COMPONENT, + pixelDatatype : PixelDatatype.UNSIGNED_INT, + sampler : createSampler() + }); - this._boundingSphere = BoundingSphere.fromOrientedBoundingBox(this._orientedBoundingBox); + processor._framebuffer = new Framebuffer({ + context : context, + colorTextures : [ + colorTexture, + ecTexture + ], + depthTexture : depthTexture, + destroyAttachments : false + }); + processor._colorTexture = colorTexture; + processor._ecAndLogDepthTexture = ecTexture; + processor._depthTexture = depthTexture; } - defineProperties(TileBoundingRegion.prototype, { - /** - * The underlying bounding volume - * - * @memberof TileBoundingRegion.prototype - * - * @type {Object} - * @readonly - */ - boundingVolume : { - get : function() { - return this._orientedBoundingBox; + var distancesAndEdlStrengthScratch = new Cartesian3(); + + function createCommands(processor, context) { + var blendFS = PointCloudEyeDomeLightingShader; + + var blendUniformMap = { + u_pointCloud_colorTexture : function() { + return processor._colorTexture; + }, + u_pointCloud_ecAndLogDepthTexture : function() { + return processor._ecAndLogDepthTexture; + }, + u_distancesAndEdlStrength : function() { + distancesAndEdlStrengthScratch.x = processor._radius / context.drawingBufferWidth; + distancesAndEdlStrengthScratch.y = processor._radius / context.drawingBufferHeight; + distancesAndEdlStrengthScratch.z = processor._strength; + return distancesAndEdlStrengthScratch; } - }, - /** - * The underlying bounding sphere - * - * @memberof TileBoundingRegion.prototype - * - * @type {BoundingSphere} - * @readonly - */ - boundingSphere : { - get : function() { - return this._boundingSphere; + }; + + var blendRenderState = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND, + depthMask : true, + depthTest : { + enabled : true } - } - }); + }); - var cartesian3Scratch = new Cartesian3(); - var cartesian3Scratch2 = new Cartesian3(); - var cartesian3Scratch3 = new Cartesian3(); - var eastWestNormalScratch = new Cartesian3(); - var westernMidpointScratch = new Cartesian3(); - var easternMidpointScratch = new Cartesian3(); - var cartographicScratch = new Cartographic(); - var planeScratch = new Plane(Cartesian3.UNIT_X, 0.0); - var rayScratch = new Ray(); + processor._drawCommand = context.createViewportQuadCommand(blendFS, { + uniformMap : blendUniformMap, + renderState : blendRenderState, + pass : Pass.CESIUM_3D_TILE, + owner : processor + }); - function computeBox(tileBB, rectangle, ellipsoid) { - ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle), tileBB.southwestCornerCartesian); - ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle), tileBB.northeastCornerCartesian); + processor._clearCommand = new ClearCommand({ + framebuffer : processor._framebuffer, + color : new Color(0.0, 0.0, 0.0, 0.0), + depth : 1.0, + renderState : RenderState.fromCache(), + pass : Pass.CESIUM_3D_TILE, + owner : processor + }); + } - // The middle latitude on the western edge. - cartographicScratch.longitude = rectangle.west; - cartographicScratch.latitude = (rectangle.south + rectangle.north) * 0.5; - cartographicScratch.height = 0.0; - var westernMidpointCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, westernMidpointScratch); + function createResources(processor, context) { + var screenWidth = context.drawingBufferWidth; + var screenHeight = context.drawingBufferHeight; + var colorTexture = processor._colorTexture; + var nowDirty = false; + var resized = defined(colorTexture) && + ((colorTexture.width !== screenWidth) || + (colorTexture.height !== screenHeight)); - // Compute the normal of the plane on the western edge of the tile. - var westNormal = Cartesian3.cross(westernMidpointCartesian, Cartesian3.UNIT_Z, cartesian3Scratch); - Cartesian3.normalize(westNormal, tileBB.westNormal); + if (!defined(colorTexture) || resized) { + destroyFramebuffer(processor); + createFramebuffer(processor, context); + createCommands(processor, context); + nowDirty = true; + } + return nowDirty; + } - // The middle latitude on the eastern edge. - cartographicScratch.longitude = rectangle.east; - var easternMidpointCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, easternMidpointScratch); + function isSupported(context) { + return context.floatingPointTexture && context.drawBuffers && context.fragmentDepth; + } - // Compute the normal of the plane on the eastern edge of the tile. - var eastNormal = Cartesian3.cross(Cartesian3.UNIT_Z, easternMidpointCartesian, cartesian3Scratch); - Cartesian3.normalize(eastNormal, tileBB.eastNormal); + PointCloudEyeDomeLighting.isSupported = isSupported; - // Compute the normal of the plane bounding the southern edge of the tile. - var westVector = Cartesian3.subtract(westernMidpointCartesian, easternMidpointCartesian, cartesian3Scratch); - var eastWestNormal = Cartesian3.normalize(westVector, eastWestNormalScratch); + function getECShaderProgram(context, shaderProgram) { + var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'EC'); + if (!defined(shader)) { + var attributeLocations = shaderProgram._attributeLocations; - var south = rectangle.south; - var southSurfaceNormal; + var vs = shaderProgram.vertexShaderSource.clone(); + var fs = shaderProgram.fragmentShaderSource.clone(); - if (south > 0.0) { - // Compute a plane that doesn't cut through the tile. - cartographicScratch.longitude = (rectangle.west + rectangle.east) * 0.5; - cartographicScratch.latitude = south; - var southCenterCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, rayScratch.origin); - Cartesian3.clone(eastWestNormal, rayScratch.direction); - var westPlane = Plane.fromPointNormal(tileBB.southwestCornerCartesian, tileBB.westNormal, planeScratch); - // Find a point that is on the west and the south planes - IntersectionTests.rayPlane(rayScratch, westPlane, tileBB.southwestCornerCartesian); - southSurfaceNormal = ellipsoid.geodeticSurfaceNormal(southCenterCartesian, cartesian3Scratch2); + vs.sources = vs.sources.map(function(source) { + source = ShaderSource.replaceMain(source, 'czm_point_cloud_post_process_main'); + return source; + }); - } else { - southSurfaceNormal = ellipsoid.geodeticSurfaceNormalCartographic(Rectangle.southeast(rectangle), cartesian3Scratch2); - } - var southNormal = Cartesian3.cross(southSurfaceNormal, westVector, cartesian3Scratch3); - Cartesian3.normalize(southNormal, tileBB.southNormal); + fs.sources = fs.sources.map(function(source) { + source = ShaderSource.replaceMain(source, 'czm_point_cloud_post_process_main'); + source = source.replace(/gl_FragColor/g, 'gl_FragData[0]'); + return source; + }); - // Compute the normal of the plane bounding the northern edge of the tile. - var north = rectangle.north; - var northSurfaceNormal; - if (north < 0.0) { - // Compute a plane that doesn't cut through the tile. - cartographicScratch.longitude = (rectangle.west + rectangle.east) * 0.5; - cartographicScratch.latitude = north; - var northCenterCartesian = ellipsoid.cartographicToCartesian(cartographicScratch, rayScratch.origin); - Cartesian3.negate(eastWestNormal, rayScratch.direction); - var eastPlane = Plane.fromPointNormal(tileBB.northeastCornerCartesian, tileBB.eastNormal, planeScratch); - // Find a point that is on the east and the north planes - IntersectionTests.rayPlane(rayScratch, eastPlane, tileBB.northeastCornerCartesian); - northSurfaceNormal = ellipsoid.geodeticSurfaceNormal(northCenterCartesian, cartesian3Scratch2); + vs.sources.push( + 'varying vec3 v_positionEC; \n' + + 'void main() \n' + + '{ \n' + + ' czm_point_cloud_post_process_main(); \n' + + ' v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n' + + '}'); + fs.sources.unshift('#extension GL_EXT_draw_buffers : enable \n'); + fs.sources.push( + 'varying vec3 v_positionEC; \n' + + 'void main() \n' + + '{ \n' + + ' czm_point_cloud_post_process_main(); \n' + + // Write log base 2 depth to alpha for EDL + ' gl_FragData[1] = vec4(v_positionEC, log2(-v_positionEC.z)); \n' + + '}'); - } else { - northSurfaceNormal = ellipsoid.geodeticSurfaceNormalCartographic(Rectangle.northwest(rectangle), cartesian3Scratch2); + shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'EC', { + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); } - var northNormal = Cartesian3.cross(westVector, northSurfaceNormal, cartesian3Scratch3); - Cartesian3.normalize(northNormal, tileBB.northNormal); - } - - var southwestCornerScratch = new Cartesian3(); - var northeastCornerScratch = new Cartesian3(); - var negativeUnitY = new Cartesian3(0.0, -1.0, 0.0); - var negativeUnitZ = new Cartesian3(0.0, 0.0, -1.0); - var vectorScratch = new Cartesian3(); - /** - * Gets the distance from the camera to the closest point on the tile. This is used for level of detail selection. - * - * @param {FrameState} frameState The state information of the current rendering frame. - * @returns {Number} The distance from the camera to the closest point on the tile, in meters. - */ - TileBoundingRegion.prototype.distanceToCamera = function(frameState) { - Check.defined('frameState', frameState); - var camera = frameState.camera; - var cameraCartesianPosition = camera.positionWC; - var cameraCartographicPosition = camera.positionCartographic; + return shader; + } - var result = 0.0; - if (!Rectangle.contains(this.rectangle, cameraCartographicPosition)) { - var southwestCornerCartesian = this.southwestCornerCartesian; - var northeastCornerCartesian = this.northeastCornerCartesian; - var westNormal = this.westNormal; - var southNormal = this.southNormal; - var eastNormal = this.eastNormal; - var northNormal = this.northNormal; + PointCloudEyeDomeLighting.prototype.update = function(frameState, commandStart, tileset) { + var passes = frameState.passes; + var isPick = (passes.pick && !passes.render); + if (!isSupported(frameState.context) || isPick) { + return; + } - if (frameState.mode !== SceneMode.SCENE3D) { - southwestCornerCartesian = frameState.mapProjection.project(Rectangle.southwest(this.rectangle), southwestCornerScratch); - southwestCornerCartesian.z = southwestCornerCartesian.y; - southwestCornerCartesian.y = southwestCornerCartesian.x; - southwestCornerCartesian.x = 0.0; - northeastCornerCartesian = frameState.mapProjection.project(Rectangle.northeast(this.rectangle), northeastCornerScratch); - northeastCornerCartesian.z = northeastCornerCartesian.y; - northeastCornerCartesian.y = northeastCornerCartesian.x; - northeastCornerCartesian.x = 0.0; - westNormal = negativeUnitY; - eastNormal = Cartesian3.UNIT_Y; - southNormal = negativeUnitZ; - northNormal = Cartesian3.UNIT_Z; - } + this._strength = tileset.pointCloudShading.eyeDomeLightingStrength; + this._radius = tileset.pointCloudShading.eyeDomeLightingRadius; - var vectorFromSouthwestCorner = Cartesian3.subtract(cameraCartesianPosition, southwestCornerCartesian, vectorScratch); - var distanceToWestPlane = Cartesian3.dot(vectorFromSouthwestCorner, westNormal); - var distanceToSouthPlane = Cartesian3.dot(vectorFromSouthwestCorner, southNormal); + var dirty = createResources(this, frameState.context); - var vectorFromNortheastCorner = Cartesian3.subtract(cameraCartesianPosition, northeastCornerCartesian, vectorScratch); - var distanceToEastPlane = Cartesian3.dot(vectorFromNortheastCorner, eastNormal); - var distanceToNorthPlane = Cartesian3.dot(vectorFromNortheastCorner, northNormal); + // Hijack existing point commands to render into an offscreen FBO. + var i; + var commandList = frameState.commandList; + var commandEnd = commandList.length; - if (distanceToWestPlane > 0.0) { - result += distanceToWestPlane * distanceToWestPlane; - } else if (distanceToEastPlane > 0.0) { - result += distanceToEastPlane * distanceToEastPlane; + for (i = commandStart; i < commandEnd; ++i) { + var command = commandList[i]; + if (command.primitiveType !== PrimitiveType.POINTS || command.pass === Pass.TRANSLUCENT) { + continue; } + var derivedCommand = command.derivedCommands.pointCloudProcessor; + if (!defined(derivedCommand) || command.dirty || dirty || + (derivedCommand.framebuffer !== this._framebuffer)) { // Prevent crash when tiles out-of-view come in-view during context size change + derivedCommand = DrawCommand.shallowClone(command); + command.derivedCommands.pointCloudProcessor = derivedCommand; - if (distanceToSouthPlane > 0.0) { - result += distanceToSouthPlane * distanceToSouthPlane; - } else if (distanceToNorthPlane > 0.0) { - result += distanceToNorthPlane * distanceToNorthPlane; + derivedCommand.framebuffer = this._framebuffer; + derivedCommand.shaderProgram = getECShaderProgram(frameState.context, command.shaderProgram); + derivedCommand.castShadows = false; + derivedCommand.receiveShadows = false; } - } - var cameraHeight; - if (frameState.mode === SceneMode.SCENE3D) { - cameraHeight = cameraCartographicPosition.height; - } else { - cameraHeight = cameraCartesianPosition.x; + commandList[i] = derivedCommand; } - var maximumHeight = frameState.mode === SceneMode.SCENE3D ? this.maximumHeight : 0.0; - var distanceFromTop = cameraHeight - maximumHeight; - if (distanceFromTop > 0.0) { - result += distanceFromTop * distanceFromTop; - } + var clearCommand = this._clearCommand; + var blendCommand = this._drawCommand; - return Math.sqrt(result); + // Blend EDL into the main FBO + commandList.push(blendCommand); + commandList.push(clearCommand); }; /** - * Determines which side of a plane this box is located. + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is - * on the opposite side, and {@link Intersect.INTERSECTING} if the box - * intersects the plane. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see PointCloudEyeDomeLighting#destroy */ - TileBoundingRegion.prototype.intersectPlane = function(plane) { - Check.defined('plane', plane); - return this._orientedBoundingBox.intersectPlane(plane); + PointCloudEyeDomeLighting.prototype.isDestroyed = function() { + return false; }; /** - * Creates a debug primitive that shows the outline of the tile bounding region. + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. * - * @param {Color} color The desired color of the primitive's mesh - * @return {Primitive} + * @returns {undefined} * - * @private + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * processor = processor && processor.destroy(); + * + * @see PointCloudEyeDomeLighting#isDestroyed */ - TileBoundingRegion.prototype.createDebugVolume = function(color) { - Check.defined('color', color); - - var modelMatrix = new Matrix4.clone(Matrix4.IDENTITY); - var geometry = new RectangleOutlineGeometry({ - rectangle : this.rectangle, - height : this.minimumHeight, - extrudedHeight: this.maximumHeight - }); - var instance = new GeometryInstance({ - geometry : geometry, - modelMatrix : modelMatrix, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(color) - } - }); - - return new Primitive({ - geometryInstances : instance, - appearance : new PerInstanceColorAppearance({ - translucent : false, - flat : true - }), - asynchronous : false - }); + PointCloudEyeDomeLighting.prototype.destroy = function() { + destroyFramebuffer(this); + return destroyObject(this); }; - return TileBoundingRegion; + return PointCloudEyeDomeLighting; }); -define('Scene/TileBoundingSphere',[ - '../Core/BoundingSphere', - '../Core/Cartesian3', - '../Core/Check', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defineProperties', - '../Core/GeometryInstance', - '../Core/Matrix4', - '../Core/SphereOutlineGeometry', - './PerInstanceColorAppearance', - './Primitive' +define('Scene/PointCloudShading',[ + '../Core/defaultValue', + './PointCloudEyeDomeLighting' ], function( - BoundingSphere, - Cartesian3, - Check, - ColorGeometryInstanceAttribute, - defineProperties, - GeometryInstance, - Matrix4, - SphereOutlineGeometry, - PerInstanceColorAppearance, - Primitive) { + defaultValue, + PointCloudEyeDomeLighting) { 'use strict'; /** - * A tile bounding volume specified as a sphere. - * @alias TileBoundingSphere - * @constructor - * - * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere. - * @param {Number} [radius=0.0] The radius of the bounding sphere. + * Options for performing point attenuation based on geometric error when rendering + * point clouds using 3D Tiles. * - * @private + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.attenuation=false] Perform point attenuation based on geometric error. + * @param {Number} [options.geometricErrorScale=1.0] Scale to be applied to each tile's geometric error. + * @param {Number} [options.maximumAttenuation] Maximum attenuation in pixels. Defaults to the Cesium3DTileset's maximumScreenSpaceError. + * @param {Number} [options.baseResolution] Average base resolution for the dataset in meters. Substitute for Geometric Error when not available. + * @param {Boolean} [options.eyeDomeLighting=true] When true, use eye dome lighting when drawing with point attenuation. + * @param {Number} [options.eyeDomeLightingStrength=1.0] Increasing this value increases contrast on slopes and edges. + * @param {Number} [options.eyeDomeLightingRadius=1.0] Increase the thickness of contours from eye dome lighting. + * @constructor */ - function TileBoundingSphere(center, radius) { - this._boundingSphere = new BoundingSphere(center, radius); - } + function PointCloudShading(options) { + var pointCloudShading = defaultValue(options, {}); - defineProperties(TileBoundingSphere.prototype, { /** - * The center of the bounding sphere - * - * @memberof TileBoundingSphere.prototype - * - * @type {Cartesian3} - * @readonly + * Perform point attenuation based on geometric error. + * @type {Boolean} + * @default false */ - center : { - get : function() { - return this._boundingSphere.center; - } - }, + this.attenuation = defaultValue(pointCloudShading.attenuation, false); /** - * The radius of the bounding sphere - * - * @memberof TileBoundingSphere.prototype - * + * Scale to be applied to the geometric error before computing attenuation. * @type {Number} - * @readonly + * @default 1.0 */ - radius : { - get : function() { - return this._boundingSphere.radius; - } - }, + this.geometricErrorScale = defaultValue(pointCloudShading.geometricErrorScale, 1.0); /** - * The underlying bounding volume - * - * @memberof TileBoundingSphere.prototype - * - * @type {Object} - * @readonly + * Maximum point attenuation in pixels. If undefined, the Cesium3DTileset's maximumScreenSpaceError will be used. + * @type {Number} */ - boundingVolume : { - get : function() { - return this._boundingSphere; - } - }, + this.maximumAttenuation = pointCloudShading.maximumAttenuation; + /** - * The underlying bounding sphere - * - * @memberof TileBoundingSphere.prototype - * - * @type {BoundingSphere} - * @readonly + * Average base resolution for the dataset in meters. + * Used in place of geometric error when geometric error is 0. + * If undefined, an approximation will be computed for each tile that has geometric error of 0. + * @type {Number} */ - boundingSphere : { - get : function() { - return this._boundingSphere; - } - } - }); - - /** - * Computes the distance between this bounding sphere and the camera attached to frameState. - * - * @param {FrameState} frameState The frameState to which the camera is attached. - * @returns {Number} The distance between the camera and the bounding sphere in meters. Returns 0 if the camera is inside the bounding volume. - * - */ - TileBoundingSphere.prototype.distanceToCamera = function(frameState) { - Check.defined('frameState', frameState); - var boundingSphere = this._boundingSphere; - return Math.max(0.0, Cartesian3.distance(boundingSphere.center, frameState.camera.positionWC) - boundingSphere.radius); - }; - - /** - * Determines which side of a plane this sphere is located. - * - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire sphere is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire sphere is - * on the opposite side, and {@link Intersect.INTERSECTING} if the sphere - * intersects the plane. - */ - TileBoundingSphere.prototype.intersectPlane = function(plane) { - Check.defined('plane', plane); - return BoundingSphere.intersectPlane(this._boundingSphere, plane); - }; - - /** - * Update the bounding sphere after the tile is transformed. - * - * @param {Cartesian3} center The center of the bounding sphere. - * @param {Number} radius The radius of the bounding sphere. - */ - TileBoundingSphere.prototype.update = function(center, radius) { - Cartesian3.clone(center, this._boundingSphere.center); - this._boundingSphere.radius = radius; - }; - - /** - * Creates a debug primitive that shows the outline of the sphere. - * - * @param {Color} color The desired color of the primitive's mesh - * @return {Primitive} - */ - TileBoundingSphere.prototype.createDebugVolume = function(color) { - Check.defined('color', color); - var geometry = new SphereOutlineGeometry({ - radius: this.radius - }); - var modelMatrix = Matrix4.fromTranslation(this.center, new Matrix4.clone(Matrix4.IDENTITY)); - var instance = new GeometryInstance({ - geometry : geometry, - modelMatrix : modelMatrix, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(color) - } - }); - - return new Primitive({ - geometryInstances : instance, - appearance : new PerInstanceColorAppearance({ - translucent : false, - flat : true - }), - asynchronous : false - }); - }; - - return TileBoundingSphere; -}); - -define('Scene/TileOrientedBoundingBox',[ - '../Core/BoundingSphere', - '../Core/BoxOutlineGeometry', - '../Core/Cartesian3', - '../Core/Check', - '../Core/ColorGeometryInstanceAttribute', - '../Core/defineProperties', - '../Core/GeometryInstance', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/OrientedBoundingBox', - './PerInstanceColorAppearance', - './Primitive' - ], function( - BoundingSphere, - BoxOutlineGeometry, - Cartesian3, - Check, - ColorGeometryInstanceAttribute, - defineProperties, - GeometryInstance, - Matrix3, - Matrix4, - OrientedBoundingBox, - PerInstanceColorAppearance, - Primitive) { - 'use strict'; - - /** - * A tile bounding volume specified as an oriented bounding box. - * @alias TileOrientedBoundingBox - * @constructor - * - * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. - * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 - * cube centered at the origin. - * - * @private - */ - function TileOrientedBoundingBox(center, halfAxes) { - this._orientedBoundingBox = new OrientedBoundingBox(center, halfAxes); - this._boundingSphere = BoundingSphere.fromOrientedBoundingBox(this._orientedBoundingBox); - } + this.baseResolution = pointCloudShading.baseResolution; - defineProperties(TileOrientedBoundingBox.prototype, { /** - * The underlying bounding volume. - * - * @memberof TileOrientedBoundingBox.prototype + * Use eye dome lighting when drawing with point attenuation + * Requires support for EXT_frag_depth, OES_texture_float, and WEBGL_draw_buffers extensions in WebGL 1.0, + * otherwise eye dome lighting is ignored. * - * @type {Object} - * @readonly + * @type {Boolean} + * @default true */ - boundingVolume : { - get : function() { - return this._orientedBoundingBox; - } - }, + this.eyeDomeLighting = defaultValue(pointCloudShading.eyeDomeLighting, true); + /** - * The underlying bounding sphere. - * - * @memberof TileOrientedBoundingBox.prototype - * - * @type {BoundingSphere} - * @readonly + * Eye dome lighting strength (apparent contrast) + * @type {Number} + * @default 1.0 */ - boundingSphere : { - get : function() { - return this._boundingSphere; - } - } - }); - - /** - * Computes the distance between this bounding box and the camera attached to frameState. - * - * @param {FrameState} frameState The frameState to which the camera is attached. - * @returns {Number} The distance between the camera and the bounding box in meters. Returns 0 if the camera is inside the bounding volume. - */ - TileOrientedBoundingBox.prototype.distanceToCamera = function(frameState) { - Check.defined('frameState', frameState); - return Math.sqrt(this._orientedBoundingBox.distanceSquaredTo(frameState.camera.positionWC)); - }; - - /** - * Determines which side of a plane this box is located. - * - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire box is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire box is - * on the opposite side, and {@link Intersect.INTERSECTING} if the box - * intersects the plane. - */ - TileOrientedBoundingBox.prototype.intersectPlane = function(plane) { - Check.defined('plane', plane); - return this._orientedBoundingBox.intersectPlane(plane); - }; + this.eyeDomeLightingStrength = defaultValue(pointCloudShading.eyeDomeLightingStrength, 1.0); - /** - * Update the bounding box after the tile is transformed. - * - * @param {Cartesian3} center The center of the box. - * @param {Matrix3} halfAxes The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 - * cube centered at the origin. - */ - TileOrientedBoundingBox.prototype.update = function(center, halfAxes) { - Cartesian3.clone(center, this._orientedBoundingBox.center); - Matrix3.clone(halfAxes, this._orientedBoundingBox.halfAxes); - BoundingSphere.fromOrientedBoundingBox(this._orientedBoundingBox, this._boundingSphere); - }; + /** + * Thickness of contours from eye dome lighting + * @type {Number} + * @default 1.0 + */ + this.eyeDomeLightingRadius = defaultValue(pointCloudShading.eyeDomeLightingRadius, 1.0); + } /** - * Creates a debug primitive that shows the outline of the box. + * Determines if point cloud shading is supported. * - * @param {Color} color The desired color of the primitive's mesh - * @return {Primitive} + * @param {Scene} scene The scene. + * @returns {Boolean} <code>true</code> if point cloud shading is supported; otherwise, returns <code>false</code> */ - TileOrientedBoundingBox.prototype.createDebugVolume = function(color) { - Check.defined('color', color); - - var geometry = new BoxOutlineGeometry({ - // Make a 2x2x2 cube - minimum: new Cartesian3(-1.0, -1.0, -1.0), - maximum: new Cartesian3(1.0, 1.0, 1.0) - }); - var modelMatrix = Matrix4.fromRotationTranslation(this.boundingVolume.halfAxes, this.boundingVolume.center); - var instance = new GeometryInstance({ - geometry : geometry, - modelMatrix : modelMatrix, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(color) - } - }); - - return new Primitive({ - geometryInstances : instance, - appearance : new PerInstanceColorAppearance({ - translucent : false, - flat : true - }), - asynchronous : false - }); + PointCloudShading.isSupported = function(scene) { + return PointCloudEyeDomeLighting.isSupported(scene.context); }; - return TileOrientedBoundingBox; + return PointCloudShading; }); -define('Scene/Cesium3DTile',[ - '../Core/BoundingSphere', +define('Scene/Cesium3DTileset',[ + '../Core/Cartesian2', '../Core/Cartesian3', - '../Core/Color', - '../Core/CullingVolume', + '../Core/Cartographic', + '../Core/Check', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/deprecationWarning', '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/DoublyLinkedList', + '../Core/Ellipsoid', + '../Core/Event', + '../Core/getBaseUri', + '../Core/getExtensionFromUri', '../Core/getMagic', - '../Core/Intersect', - '../Core/joinUrls', + '../Core/isDataUri', '../Core/JulianDate', - '../Core/loadArrayBuffer', - '../Core/Matrix3', + '../Core/ManagedArray', + '../Core/Math', '../Core/Matrix4', - '../Core/Plane', - '../Core/Rectangle', - '../Core/Request', - '../Core/RequestScheduler', - '../Core/RequestState', - '../Core/RequestType', + '../Core/Resource', '../Core/RuntimeError', + '../Renderer/ClearCommand', + '../Renderer/Pass', '../ThirdParty/when', - './Cesium3DTileChildrenVisibility', - './Cesium3DTileContentFactory', - './Cesium3DTileContentState', - './Cesium3DTileOptimizationHint', - './Cesium3DTileRefine', - './Empty3DTileContent', + './Axis', + './Cesium3DTile', + './Cesium3DTileColorBlendMode', + './Cesium3DTileOptimizations', + './Cesium3DTilesetStatistics', + './Cesium3DTilesetTraversal', + './Cesium3DTileStyleEngine', + './ClassificationType', + './LabelCollection', + './PointCloudShading', + './PointCloudEyeDomeLighting', './SceneMode', + './ShadowMode', './TileBoundingRegion', './TileBoundingSphere', './TileOrientedBoundingBox' ], function( - BoundingSphere, + Cartesian2, Cartesian3, - Color, - CullingVolume, + Cartographic, + Check, defaultValue, defined, defineProperties, deprecationWarning, destroyObject, + DeveloperError, + DoublyLinkedList, + Ellipsoid, + Event, + getBaseUri, + getExtensionFromUri, getMagic, - Intersect, - joinUrls, + isDataUri, JulianDate, - loadArrayBuffer, - Matrix3, + ManagedArray, + CesiumMath, Matrix4, - Plane, - Rectangle, - Request, - RequestScheduler, - RequestState, - RequestType, + Resource, RuntimeError, + ClearCommand, + Pass, when, - Cesium3DTileChildrenVisibility, - Cesium3DTileContentFactory, - Cesium3DTileContentState, - Cesium3DTileOptimizationHint, - Cesium3DTileRefine, - Empty3DTileContent, + Axis, + Cesium3DTile, + Cesium3DTileColorBlendMode, + Cesium3DTileOptimizations, + Cesium3DTilesetStatistics, + Cesium3DTilesetTraversal, + Cesium3DTileStyleEngine, + ClassificationType, + LabelCollection, + PointCloudShading, + PointCloudEyeDomeLighting, SceneMode, + ShadowMode, TileBoundingRegion, TileBoundingSphere, TileOrientedBoundingBox) { 'use strict'; /** - * A tile in a {@link Cesium3DTileset}. When a tile is first created, its content is not loaded; - * the content is loaded on-demand when needed based on the view. - * <p> - * Do not construct this directly, instead access tiles through {@link Cesium3DTileset#tileVisible}. - * </p> + * A {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles tileset}, + * used for streaming massive heterogeneous 3D geospatial datasets. * - * @alias Cesium3DTile + * @alias Cesium3DTileset * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url to a tileset.json file or to a directory containing a tileset.json file. + * @param {Boolean} [options.show=true] Determines if the tileset will be shown. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. + * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from each light source. + * @param {Number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. + * @param {Number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. + * @param {Boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. + * @param {Boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. + * @param {Number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. + * @param {Number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. + * @param {Number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. + * @param {Boolean} [options.skipLevelOfDetail=true] Optimization option. Determines if level of detail skipping should be applied during the traversal. + * @param {Number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. + * @param {Number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. + * @param {Number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. + * @param {Boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. + * @param {Boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. + * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. Clipping planes are not currently supported in Internet Explorer. + * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. + * @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. + * @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. + * @param {Boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. + * @param {Boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. + * @param {Boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. + * @param {Boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. + * @param {Boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. + * @param {Boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. + * @param {Boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. + * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. + * + * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. See {@link https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status} + * + * @example + * var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ + * url : 'http://localhost:8002/tilesets/Seattle' + * })); + * + * @example + * // Common setting for the skipLevelOfDetail optimization + * var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ + * url : 'http://localhost:8002/tilesets/Seattle', + * skipLevelOfDetail : true, + * baseScreenSpaceError : 1024, + * skipScreenSpaceErrorFactor : 16, + * skipLevels : 1, + * immediatelyLoadDesiredLevelOfDetail : false, + * loadSiblings : false, + * cullWithChildrenBounds : true + * })); + * + * @example + * // Common settings for the dynamicScreenSpaceError optimization + * var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ + * url : 'http://localhost:8002/tilesets/Seattle', + * dynamicScreenSpaceError : true, + * dynamicScreenSpaceErrorDensity : 0.00278, + * dynamicScreenSpaceErrorFactor : 4.0, + * dynamicScreenSpaceErrorHeightFalloff : 0.25 + * })); + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles specification} */ - function Cesium3DTile(tileset, basePath, header, parent) { - this._tileset = tileset; - this._header = header; - var contentHeader = header.content; + function Cesium3DTileset(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The local transform of this tile - * @type {Matrix4} - */ - this.transform = defined(header.transform) ? Matrix4.unpack(header.transform) : Matrix4.clone(Matrix4.IDENTITY); + Check.defined('options.url', options.url); + + var resource = Resource.createIfNeeded(options.url); - var parentTransform = defined(parent) ? parent.computedTransform : tileset.modelMatrix; - var computedTransform = Matrix4.multiply(parentTransform, this.transform, new Matrix4()); + var tilesetResource = resource; + var basePath; + + if (resource.extension === 'json') { + basePath = resource.getBaseUri(true); + } else if (resource.isDataUri) { + basePath = ''; + } else { + resource.appendForwardSlash(); + tilesetResource = resource.getDerivedResource({ + url: 'tileset.json' + }); + basePath = resource.url; + } + + this._url = resource.url; + this._tilesetUrl = tilesetResource.url; + this._basePath = basePath; + this._root = undefined; + this._asset = undefined; // Metadata for the entire tileset + this._properties = undefined; // Metadata for per-model/point/etc properties + this._geometricError = undefined; // Geometric error when the tree is not rendered at all + this._gltfUpAxis = undefined; + this._processingQueue = []; + this._selectedTiles = []; + this._requestedTiles = []; + this._desiredTiles = new ManagedArray(); + this._selectedTilesToStyle = []; + this._loadTimestamp = undefined; + this._timeSinceLoad = 0.0; + + var replacementList = new DoublyLinkedList(); + + // [head, sentinel) -> tiles that weren't selected this frame and may be replaced + // (sentinel, tail] -> tiles that were selected this frame + this._replacementList = replacementList; // Tiles with content loaded. For cache management. + this._replacementSentinel = replacementList.add(); + this._trimTiles = false; + + this._cullWithChildrenBounds = defaultValue(options.cullWithChildrenBounds, true); + + this._hasMixedContent = false; + + this._baseTraversal = new Cesium3DTilesetTraversal.BaseTraversal(); + this._skipTraversal = new Cesium3DTilesetTraversal.SkipTraversal({ + selectionHeuristic : selectionHeuristic + }); + + this._backfaceCommands = new ManagedArray(); + + this._maximumScreenSpaceError = defaultValue(options.maximumScreenSpaceError, 16); + this._maximumMemoryUsage = defaultValue(options.maximumMemoryUsage, 512); + + this._styleEngine = new Cesium3DTileStyleEngine(); + + this._modelMatrix = defined(options.modelMatrix) ? Matrix4.clone(options.modelMatrix) : Matrix4.clone(Matrix4.IDENTITY); + + this._statistics = new Cesium3DTilesetStatistics(); + this._statisticsLastColor = new Cesium3DTilesetStatistics(); + this._statisticsLastPick = new Cesium3DTilesetStatistics(); + + this._tilesLoaded = false; + + this._tileDebugLabels = undefined; + + this._readyPromise = when.defer(); + + this._classificationType = options.classificationType; + + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); /** - * The final computed transform of this tile - * @type {Matrix4} - * @readonly + * Optimization option. Whether the tileset should refine based on a dynamic screen space error. Tiles that are further + * away will be rendered with lower detail than closer tiles. This improves performance by rendering fewer + * tiles and making less requests, but may result in a slight drop in visual quality for tiles in the distance. + * The algorithm is biased towards "street views" where the camera is close to the ground plane of the tileset and looking + * at the horizon. In addition results are more accurate for tightly fitting bounding volumes like box and region. + * + * @type {Boolean} + * @default false */ - this.computedTransform = computedTransform; + this.dynamicScreenSpaceError = defaultValue(options.dynamicScreenSpaceError, false); - this._boundingVolume = this.createBoundingVolume(header.boundingVolume, computedTransform); - this._boundingVolume2D = undefined; + /** + * A scalar that determines the density used to adjust the dynamic screen space error, similar to {@link Fog}. Increasing this + * value has the effect of increasing the maximum screen space error for all tiles, but in a non-linear fashion. + * The error starts at 0.0 and increases exponentially until a midpoint is reached, and then approaches 1.0 asymptotically. + * This has the effect of keeping high detail in the closer tiles and lower detail in the further tiles, with all tiles + * beyond a certain distance all roughly having an error of 1.0. + * <p> + * The dynamic error is in the range [0.0, 1.0) and is multiplied by <code>dynamicScreenSpaceErrorFactor</code> to produce the + * final dynamic error. This dynamic error is then subtracted from the tile's actual screen space error. + * </p> + * <p> + * Increasing <code>dynamicScreenSpaceErrorDensity</code> has the effect of moving the error midpoint closer to the camera. + * It is analogous to moving fog closer to the camera. + * </p> + * + * @type {Number} + * @default 0.00278 + */ + this.dynamicScreenSpaceErrorDensity = 0.00278; - var contentBoundingVolume; + /** + * A factor used to increase the screen space error of tiles for dynamic screen space error. As this value increases less tiles + * are requested for rendering and tiles in the distance will have lower detail. If set to zero, the feature will be disabled. + * + * @type {Number} + * @default 4.0 + */ + this.dynamicScreenSpaceErrorFactor = 4.0; - if (defined(contentHeader) && defined(contentHeader.boundingVolume)) { - // Non-leaf tiles may have a content bounding-volume, which is a tight-fit bounding volume - // around only the features in the tile. This box is useful for culling for rendering, - // but not for culling for traversing the tree since it does not guarantee spatial coherence, i.e., - // since it only bounds features in the tile, not the entire tile, children may be - // outside of this box. - contentBoundingVolume = this.createBoundingVolume(contentHeader.boundingVolume, computedTransform); - } - this._contentBoundingVolume = contentBoundingVolume; - this._contentBoundingVolume2D = undefined; + /** + * A ratio of the tileset's height at which the density starts to falloff. If the camera is below this height the + * full computed density is applied, otherwise the density falls off. This has the effect of higher density at + * street level views. + * <p> + * Valid values are between 0.0 and 1.0. + * </p> + * + * @type {Number} + * @default 0.25 + */ + this.dynamicScreenSpaceErrorHeightFalloff = 0.25; - var viewerRequestVolume; - if (defined(header.viewerRequestVolume)) { - viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, computedTransform); - } - this._viewerRequestVolume = viewerRequestVolume; + this._dynamicScreenSpaceErrorComputedDensity = 0.0; // Updated based on the camera position and direction /** - * The error, in meters, introduced if this tile is rendered and its children are not. - * This is used to compute screen space error, i.e., the error measured in pixels. + * Determines whether the tileset casts or receives shadows from each light source. + * <p> + * Enabling shadows has a performance impact. A tileset that casts shadows must be rendered twice, once from the camera and again from the light's point of view. + * </p> + * <p> + * Shadows are rendered only when {@link Viewer#shadows} is <code>true</code>. + * </p> * - * @type {Number} - * @readonly + * @type {ShadowMode} + * @default ShadowMode.ENABLED */ - this.geometricError = header.geometricError; + this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); - if (!defined(this.geometricError)) { - this.geometricError = defined(parent) ? parent.geometricError : tileset._geometricError; - Cesium3DTile._deprecationWarning('geometricErrorUndefined', 'Required property geometricError is undefined for this tile. Using parent\'s geometric error instead.'); - } + /** + * Determines if the tileset will be shown. + * + * @type {Boolean} + * @default true + */ + this.show = defaultValue(options.show, true); - var refine; - if (defined(header.refine)) { - if (header.refine === 'replace' || header.refine === 'add') { - Cesium3DTile._deprecationWarning('lowercase-refine', 'This tile uses a lowercase refine "' + header.refine + '". Instead use "' + header.refine.toUpperCase() + '".'); - } - refine = (header.refine.toUpperCase() === 'REPLACE') ? Cesium3DTileRefine.REPLACE : Cesium3DTileRefine.ADD; - } else if (defined(parent)) { - // Inherit from parent tile if omitted. - refine = parent.refine; - } else { - refine = Cesium3DTileRefine.REPLACE; - } + /** + * Defines how per-feature colors set from the Cesium API or declarative styling blend with the source colors from + * the original feature, e.g. glTF material or per-point color in the tile. + * + * @type {Cesium3DTileColorBlendMode} + * @default Cesium3DTileColorBlendMode.HIGHLIGHT + */ + this.colorBlendMode = Cesium3DTileColorBlendMode.HIGHLIGHT; /** - * Specifies the type of refinment that is used when traversing this tile for rendering. + * Defines the value used to linearly interpolate between the source color and feature color when the {@link Cesium3DTileset#colorBlendMode} is <code>MIX</code>. + * A value of 0.0 results in the source color while a value of 1.0 results in the feature color, with any value in-between + * resulting in a mix of the source color and feature color. * - * @type {Cesium3DTileRefine} - * @readonly - * @private + * @type {Number} + * @default 0.5 */ - this.refine = refine; + this.colorBlendAmount = 0.5; /** - * Gets the tile's children. + * Options for controlling point size based on geometric error and eye dome lighting. + * @type {PointCloudShading} + */ + this.pointCloudShading = new PointCloudShading(options.pointCloudShading); + + this._pointCloudEyeDomeLighting = new PointCloudEyeDomeLighting(); + + /** + * The event fired to indicate progress of loading new tiles. This event is fired when a new tile + * is requested, when a requested tile is finished downloading, and when a downloaded tile has been + * processed and is ready to render. + * <p> + * The number of pending tile requests, <code>numberOfPendingRequests</code>, and number of tiles + * processing, <code>numberOfTilesProcessing</code> are passed to the event listener. + * </p> + * <p> + * This event is fired at the end of the frame after the scene is rendered. + * </p> * - * @type {Cesium3DTile[]} - * @readonly + * @type {Event} + * @default new Event() + * + * @example + * tileset.loadProgress.addEventListener(function(numberOfPendingRequests, numberOfTilesProcessing) { + * if ((numberOfPendingRequests === 0) && (numberOfTilesProcessing === 0)) { + * console.log('Stopped loading'); + * return; + * } + * + * console.log('Loading: requests: ' + numberOfPendingRequests + ', processing: ' + numberOfTilesProcessing); + * }); */ - this.children = []; + this.loadProgress = new Event(); /** - * This tile's parent or <code>undefined</code> if this tile is the root. + * The event fired to indicate that all tiles that meet the screen space error this frame are loaded. The tileset + * is completely loaded for this view. * <p> - * When a tile's content points to an external tileset.json, the external tileset's - * root tile's parent is not <code>undefined</code>; instead, the parent references - * the tile (with its content pointing to an external tileset.json) as if the two tilesets were merged. + * This event is fired at the end of the frame after the scene is rendered. * </p> * - * @type {Cesium3DTile} - * @readonly + * @type {Event} + * @default new Event() + * + * @example + * tileset.allTilesLoaded.addEventListener(function() { + * console.log('All tiles are loaded'); + * }); + * + * @see Cesium3DTileset#tilesLoaded */ - this.parent = parent; - - var content; - var hasEmptyContent; - var contentState; - var contentUrl; - var serverKey; - - if (defined(contentHeader)) { - hasEmptyContent = false; - contentState = Cesium3DTileContentState.UNLOADED; - contentUrl = joinUrls(basePath, contentHeader.url); - serverKey = RequestScheduler.getServerKey(contentUrl); - } else { - content = new Empty3DTileContent(tileset, this); - hasEmptyContent = true; - contentState = Cesium3DTileContentState.READY; - } - - this._content = content; - this._contentUrl = contentUrl; - this._contentState = contentState; - this._contentReadyToProcessPromise = undefined; - this._contentReadyPromise = undefined; - this._expiredContent = undefined; - - this._serverKey = serverKey; + this.allTilesLoaded = new Event(); /** - * When <code>true</code>, the tile has no content. + * The event fired to indicate that a tile's content was loaded. + * <p> + * The loaded {@link Cesium3DTile} is passed to the event listener. + * </p> + * <p> + * This event is fired during the tileset traversal while the frame is being rendered + * so that updates to the tile take effect in the same frame. Do not create or modify + * Cesium entities or primitives during the event listener. + * </p> * - * @type {Boolean} - * @readonly + * @type {Event} + * @default new Event() * - * @private + * @example + * tileset.tileLoad.addEventListener(function(tile) { + * console.log('A tile was loaded.'); + * }); */ - this.hasEmptyContent = hasEmptyContent; + this.tileLoad = new Event(); /** - * When <code>true</code>, the tile's content is renderable. + * The event fired to indicate that a tile's content was unloaded. * <p> - * This is <code>false</code> until the tile's content is loaded. + * The unloaded {@link Cesium3DTile} is passed to the event listener. + * </p> + * <p> + * This event is fired immediately before the tile's content is unloaded while the frame is being + * rendered so that the event listener has access to the tile's content. Do not create + * or modify Cesium entities or primitives during the event listener. * </p> * - * @type {Boolean} - * @readonly + * @type {Event} + * @default new Event() * - * @private + * @example + * tileset.tileUnload.addEventListener(function(tile) { + * console.log('A tile was unloaded from the cache.'); + * }); + * + * @see Cesium3DTileset#maximumMemoryUsage + * @see Cesium3DTileset#trimLoadedTiles */ - this.hasRenderableContent = false; + this.tileUnload = new Event(); /** - * When <code>true</code>, the tile's content points to an external tileset. + * The event fired to indicate that a tile's content failed to load. * <p> - * This is <code>false</code> until the tile's content is loaded. + * If there are no event listeners, error messages will be logged to the console. * </p> * - * @type {Boolean} - * @readonly + * @type {Event} + * @default new Event() * - * @private + * @example + * tileset.tileFailed.addEventListener(function(error) { + * console.log('An error occurred loading tile: ' + error.url); + * console.log('Error: ' + error.message); + * }); */ - this.hasTilesetContent = false; + this.tileFailed = new Event(); /** - * The corresponding node in the cache replacement list. + * This event fires once for each visible tile in a frame. This can be used to manually + * style a tileset. + * <p> + * The visible {@link Cesium3DTile} is passed to the event listener. + * </p> + * <p> + * This event is fired during the tileset traversal while the frame is being rendered + * so that updates to the tile take effect in the same frame. Do not create or modify + * Cesium entities or primitives during the event listener. + * </p> * - * @type {DoublyLinkedListNode} - * @readonly + * @type {Event} + * @default new Event() * - * @private + * @example + * tileset.tileVisible.addEventListener(function(tile) { + * if (tile.content instanceof Cesium.Batched3DModel3DTileContent) { + * console.log('A Batched 3D Model tile is visible.'); + * } + * }); + * + * @example + * // Apply a red style and then manually set random colors for every other feature when the tile becomes visible. + * tileset.style = new Cesium.Cesium3DTileStyle({ + * color : 'color("red")' + * }); + * tileset.tileVisible.addEventListener(function(tile) { + * var content = tile.content; + * var featuresLength = content.featuresLength; + * for (var i = 0; i < featuresLength; i+=2) { + * content.getFeature(i).color = Cesium.Color.fromRandom(); + * } + * }); */ - this.replacementNode = undefined; - - var expire = header.expire; - var expireDuration; - var expireDate; - if (defined(expire)) { - expireDuration = expire.duration; - if (defined(expire.date)) { - expireDate = JulianDate.fromIso8601(expire.date); - } - } + this.tileVisible = new Event(); /** - * The time in seconds after the tile's content is ready when the content expires and new content is requested. + * Optimization option. Determines if level of detail skipping should be applied during the traversal. + * <p> + * The common strategy for replacement-refinement traversal is to store all levels of the tree in memory and require + * all children to be loaded before the parent can refine. With this optimization levels of the tree can be skipped + * entirely and children can be rendered alongside their parents. The tileset requires significantly less memory when + * using this optimization. + * </p> * - * @type {Number} + * @type {Boolean} + * @default true */ - this.expireDuration = expireDuration; + this.skipLevelOfDetail = defaultValue(options.skipLevelOfDetail, true); + this._skipLevelOfDetail = this.skipLevelOfDetail; + this._disableSkipLevelOfDetail = false; /** - * The date when the content expires and new content is requested. + * The screen space error that must be reached before skipping levels of detail. + * <p> + * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * </p> * - * @type {JulianDate} + * @type {Number} + * @default 1024 */ - this.expireDate = expireDate; + this.baseScreenSpaceError = defaultValue(options.baseScreenSpaceError, 1024); /** - * Marks if the tile is selected this frame. - * - * @type {Boolean} + * Multiplier defining the minimum screen space error to skip. + * For example, if a tile has screen space error of 100, no tiles will be loaded unless they + * are leaves or have a screen space error <code><= 100 / skipScreenSpaceErrorFactor</code>. + * <p> + * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * </p> * - * @private + * @type {Number} + * @default 16 */ - this.selected = false; + this.skipScreenSpaceErrorFactor = defaultValue(options.skipScreenSpaceErrorFactor, 16); /** - * The time when a style was last applied to this tile. + * Constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. + * For example, if a tile is level 1, no tiles will be loaded unless they are at level greater than 2. + * <p> + * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * </p> * * @type {Number} - * - * @private + * @default 1 */ - this.lastStyleTime = 0; + this.skipLevels = defaultValue(options.skipLevels, 1); /** - * Marks whether the tile's children bounds are fully contained within the tile's bounds - * - * @type {Cesium3DTileOptimizationHint} + * When true, only tiles that meet the maximum screen space error will ever be downloaded. + * Skipping factors are ignored and just the desired tiles are loaded. + * <p> + * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * </p> * - * @private + * @type {Boolean} + * @default false */ - this._optimChildrenWithinParent = Cesium3DTileOptimizationHint.NOT_COMPUTED; - - // Members that are updated every frame for tree traversal and rendering optimizations: - this._distanceToCamera = 0; - this._visibilityPlaneMask = 0; - this._childrenVisibility = Cesium3DTileChildrenVisibility.VISIBLE; - this._lastSelectedFrameNumber = -1; - this._screenSpaceError = 0; - this._screenSpaceErrorComputedFrame = -1; - this._finalResolution = true; - this._depth = 0; - this._centerZDepth = 0; - this._stackLength = 0; - this._selectedFrame = -1; - this._selectionDepth = 0; - this._lastSelectionDepth = undefined; - this._requestedFrame = undefined; - this._lastVisitedFrame = undefined; - this._ancestorWithContent = undefined; - this._ancestorWithLoadedContent = undefined; - this._isClipped = true; - - this._debugBoundingVolume = undefined; - this._debugContentBoundingVolume = undefined; - this._debugViewerRequestVolume = undefined; - this._debugColor = Color.fromRandom({ alpha : 1.0 }); - this._debugColorizeTiles = false; - - this._commandsLength = 0; - - this._color = undefined; - this._colorDirty = false; - } - - // This can be overridden for testing purposes - Cesium3DTile._deprecationWarning = deprecationWarning; + this.immediatelyLoadDesiredLevelOfDetail = defaultValue(options.immediatelyLoadDesiredLevelOfDetail, false); - defineProperties(Cesium3DTile.prototype, { /** - * The tileset containing this tile. - * - * @memberof Cesium3DTile.prototype + * Determines whether siblings of visible tiles are always downloaded during traversal. + * This may be useful for ensuring that tiles are already available when the viewer turns left/right. + * <p> + * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * </p> * - * @type {Cesium3DTileset} - * @readonly + * @type {Boolean} + * @default false */ - tileset : { - get : function() { - return this._tileset; - } - }, + this.loadSiblings = defaultValue(options.loadSiblings, false); /** - * The tile's content. This represents the actual tile's payload, - * not the content's metadata in tileset.json. - * - * @memberof Cesium3DTile.prototype + * The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. Clipping planes are not currently supported in Internet Explorer. * - * @type {Cesium3DTileContent} - * @readonly + * @type {ClippingPlaneCollection} */ - content : { - get : function() { - return this._content; - } - }, + this.clippingPlanes = options.clippingPlanes; /** - * Get the bounding volume of the tile's contents. This defaults to the - * tile's bounding volume when the content's bounding volume is - * <code>undefined</code>. - * - * @memberof Cesium3DTile.prototype + * This property is for debugging only; it is not optimized for production use. + * <p> + * Determines if only the tiles from last frame should be used for rendering. This + * effectively "freezes" the tileset to the previous frame so it is possible to zoom + * out and see what was rendered. + * </p> * - * @type {TileBoundingVolume} - * @readonly - * @private + * @type {Boolean} + * @default false */ - contentBoundingVolume : { - get : function() { - return defaultValue(this._contentBoundingVolume, this._boundingVolume); - } - }, + this.debugFreezeFrame = defaultValue(options.debugFreezeFrame, false); /** - * Get the bounding sphere derived from the tile's bounding volume. - * - * @memberof Cesium3DTile.prototype + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, assigns a random color to each tile. This is useful for visualizing + * what features belong to what tiles, especially with additive refinement where features + * from parent tiles may be interleaved with features from child tiles. + * </p> * - * @type {BoundingSphere} - * @readonly + * @type {Boolean} + * @default false */ - boundingSphere : { - get : function() { - return this._boundingVolume.boundingSphere; - } - }, + this.debugColorizeTiles = defaultValue(options.debugColorizeTiles, false); /** - * Gets or sets the tile's highlight color. - * - * @memberof Cesium3DTile.prototype - * - * @type {Color} - * - * @default {@link Color.WHITE} + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, renders each tile's content as a wireframe. + * </p> * - * @private + * @type {Boolean} + * @default false */ - color : { - get : function() { - if (!defined(this._color)) { - this._color = new Color(); - } - return Color.clone(this._color); - }, - set : function(value) { - this._color = Color.clone(value, this._color); - this._colorDirty = true; - } - }, + this.debugWireframe = defaultValue(options.debugWireframe, false); /** - * Determines if the tile has available content to render. <code>true</code> if the tile's - * content is ready or if it has expired content that renders while new content loads; otherwise, - * <code>false</code>. - * - * @memberof Cesium3DTile.prototype + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, renders the bounding volume for each visible tile. The bounding volume is + * white if the tile has a content bounding volume; otherwise, it is red. Tiles that don't meet the + * screen space error and are still refining to their descendants are yellow. + * </p> * * @type {Boolean} - * @readonly - * - * @private + * @default false */ - contentAvailable : { - get : function() { - return this.contentReady || (defined(this._expiredContent) && this._contentState !== Cesium3DTileContentState.FAILED); - } - }, + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); /** - * Determines if the tile is ready to render. <code>true</code> if the tile - * is ready to render; otherwise, <code>false</code>. - * - * @memberof Cesium3DTile.prototype + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, renders the bounding volume for each visible tile's content. The bounding volume is + * blue if the tile has a content bounding volume; otherwise it is red. + * </p> * * @type {Boolean} - * @readonly - * - * @private + * @default false */ - contentReady : { - get : function() { - return this._contentState === Cesium3DTileContentState.READY; - } - }, + this.debugShowContentBoundingVolume = defaultValue(options.debugShowContentBoundingVolume, false); /** - * Determines if the tile's content has not be requested. <code>true</code> if tile's - * content has not be requested; otherwise, <code>false</code>. - * - * @memberof Cesium3DTile.prototype + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, renders the viewer request volume for each tile. + * </p> * * @type {Boolean} - * @readonly - * - * @private + * @default false */ - contentUnloaded : { - get : function() { - return this._contentState === Cesium3DTileContentState.UNLOADED; - } - }, + this.debugShowViewerRequestVolume = defaultValue(options.debugShowViewerRequestVolume, false); + + this._tileDebugLabels = undefined; + this.debugPickedTileLabelOnly = false; + this.debugPickedTile = undefined; + this.debugPickPosition = undefined; /** - * Determines if the tile's content is expired. <code>true</code> if tile's - * content is expired; otherwise, <code>false</code>. - * - * @memberof Cesium3DTile.prototype + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, draws labels to indicate the geometric error of each tile. + * </p> * * @type {Boolean} - * @readonly - * - * @private + * @default false */ - contentExpired : { - get : function() { - return this._contentState === Cesium3DTileContentState.EXPIRED; - } - }, + this.debugShowGeometricError = defaultValue(options.debugShowGeometricError, false); /** - * Gets the promise that will be resolved when the tile's content is ready to process. - * This happens after the content is downloaded but before the content is ready - * to render. + * This property is for debugging only; it is not optimized for production use. * <p> - * The promise remains <code>undefined</code> until the tile's content is requested. + * When true, draws labels to indicate the number of commands, points, triangles and features of each tile. * </p> * - * @type {Promise.<Cesium3DTileContent>} - * @readonly - * - * @private + * @type {Boolean} + * @default false */ - contentReadyToProcessPromise : { - get : function() { - if (defined(this._contentReadyToProcessPromise)) { - return this._contentReadyToProcessPromise.promise; - } - } - }, + this.debugShowRenderingStatistics = defaultValue(options.debugShowRenderingStatistics, false); /** - * Gets the promise that will be resolved when the tile's content is ready to render. + * This property is for debugging only; it is not optimized for production use. * <p> - * The promise remains <code>undefined</code> until the tile's content is requested. + * When true, draws labels to indicate the geometry and texture memory usage of each tile. * </p> * - * @type {Promise.<Cesium3DTileContent>} - * @readonly - * - * @private + * @type {Boolean} + * @default false */ - contentReadyPromise : { - get : function() { - if (defined(this._contentReadyPromise)) { - return this._contentReadyPromise.promise; - } - } - }, + this.debugShowMemoryUsage = defaultValue(options.debugShowMemoryUsage, false); /** - * Returns the number of draw commands used by this tile. - * - * @readonly + * This property is for debugging only; it is not optimized for production use. + * <p> + * When true, draws labels to indicate the url of each tile. + * </p> * - * @private + * @type {Boolean} + * @default false */ - commandsLength : { - get : function() { - return this._commandsLength; - } - } - }); - - var scratchJulianDate = new JulianDate(); - - /** - * Update whether the tile has expired. - * - * @private - */ - Cesium3DTile.prototype.updateExpiration = function() { - if (defined(this.expireDate) && this.contentReady && !this.hasEmptyContent) { - var now = JulianDate.now(scratchJulianDate); - if (JulianDate.lessThan(this.expireDate, now)) { - this._contentState = Cesium3DTileContentState.EXPIRED; - this._expiredContent = this._content; - } - } - }; - - function updateExpireDate(tile) { - if (defined(tile.expireDuration)) { - var expireDurationDate = JulianDate.now(scratchJulianDate); - JulianDate.addSeconds(expireDurationDate, tile.expireDuration, expireDurationDate); - - if (defined(tile.expireDate)) { - if (JulianDate.lessThan(tile.expireDate, expireDurationDate)) { - JulianDate.clone(expireDurationDate, tile.expireDate); - } - } else { - tile.expireDate = JulianDate.clone(expireDurationDate); - } - } - } - - function getContentFailedFunction(tile) { - return function(error) { - tile._contentState = Cesium3DTileContentState.FAILED; - tile._contentReadyPromise.reject(error); - tile._contentReadyToProcessPromise.reject(error); - }; - } + this.debugShowUrl = defaultValue(options.debugShowUrl, false); - function createPriorityFunction(tile) { - return function() { - return tile._distanceToCamera; - }; - } + // A bunch of tilesets were generated that have a leading / in front of all URLs in the tileset.json. If the tiles aren't + // at the root of the domain they will not load anymore. If we find a b3dm file with a leading slash, we test load a tile. + // If it succeeds we continue on. If it fails, we set this to true so we know to strip the slash when loading tiles. + this._brokenUrlWorkaround = false; - /** - * Requests the tile's content. - * <p> - * The request may not be made if the Cesium Request Scheduler can't prioritize it. - * </p> - * - * @private - */ - Cesium3DTile.prototype.requestContent = function() { var that = this; - var tileset = this._tileset; - - if (this.hasEmptyContent) { - return false; - } - - var url = this._contentUrl; - var expired = this.contentExpired; - if (expired) { - // Append a query parameter of the tile expiration date to prevent caching - var timestampQuery = '?expired=' + this.expireDate.toString(); - url = joinUrls(url, timestampQuery, false); - } - - var request = new Request({ - throttle : true, - throttleByServer : true, - type : RequestType.TILES3D, - priorityFunction : createPriorityFunction(this), - serverKey : this._serverKey - }); - - var promise = loadArrayBuffer(url, undefined, request); - - if (!defined(promise)) { - return false; - } - - var contentState = this._contentState; - this._contentState = Cesium3DTileContentState.LOADING; - this._contentReadyToProcessPromise = when.defer(); - this._contentReadyPromise = when.defer(); - - if (expired) { - this.expireDate = undefined; - } - - var contentFailedFunction = getContentFailedFunction(this); - - promise.then(function(arrayBuffer) { - if (that.isDestroyed()) { - // Tile is unloaded before the content finishes loading - contentFailedFunction(); - return; - } - var uint8Array = new Uint8Array(arrayBuffer); - var magic = getMagic(uint8Array); - var contentFactory = Cesium3DTileContentFactory[magic]; - var content; - - if (defined(contentFactory)) { - content = contentFactory(tileset, that, that._contentUrl, arrayBuffer, 0); - that.hasRenderableContent = true; - } else { - // The content may be json instead - content = Cesium3DTileContentFactory.json(tileset, that, that._contentUrl, arrayBuffer, 0); - that.hasTilesetContent = true; - } - - that._content = content; - that._contentState = Cesium3DTileContentState.PROCESSING; - that._contentReadyToProcessPromise.resolve(content); - - return content.readyPromise.then(function(content) { - if (that.isDestroyed()) { - // Tile is unloaded before the content finishes processing - contentFailedFunction(); - return; - } - updateExpireDate(that); - // Refresh style for expired content - that.lastStyleTime = 0; - - that._contentState = Cesium3DTileContentState.READY; - that._contentReadyPromise.resolve(content); + // We don't know the distance of the tileset until tileset.json is loaded, so use the default distance for now + Cesium3DTileset.loadJson(tilesetResource) + .then(function(tilesetJson) { + return detectBrokenUrlWorkaround(that, tilesetResource, tilesetJson); + }) + .then(function(tilesetJson) { + if (that._brokenUrlWorkaround) { + deprecationWarning('Cesium3DTileset.leadingSlash', 'Having a leading slash in a tile URL that is actually relative to the tileset.json is deprecated.'); + } + + that._root = that.loadTileset(tilesetResource, tilesetJson); + var gltfUpAxis = defined(tilesetJson.asset.gltfUpAxis) ? Axis.fromName(tilesetJson.asset.gltfUpAxis) : Axis.Y; + that._asset = tilesetJson.asset; + that._properties = tilesetJson.properties; + that._geometricError = tilesetJson.geometricError; + that._gltfUpAxis = gltfUpAxis; + that._readyPromise.resolve(that); + }).otherwise(function(error) { + that._readyPromise.reject(error); }); - }).otherwise(function(error) { - if (request.state === RequestState.CANCELLED) { - // Cancelled due to low priority - try again later. - that._contentState = contentState; - --tileset.statistics.numberOfPendingRequests; - ++tileset.statistics.numberOfAttemptedRequests; - return; - } - contentFailedFunction(error); - }); - - return true; - }; - - /** - * Unloads the tile's content. - * - * @private - */ - Cesium3DTile.prototype.unloadContent = function() { - if (!this.hasRenderableContent) { - return; - } - - this._content = this._content && this._content.destroy(); - this._contentState = Cesium3DTileContentState.UNLOADED; - this._contentReadyToProcessPromise = undefined; - this._contentReadyPromise = undefined; - - this.replacementNode = undefined; - - this.lastStyleTime = 0; - - this._debugColorizeTiles = false; - - this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); - this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); - this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); - }; - - var scratchProjectedBoundingSphere = new BoundingSphere(); - - function getBoundingVolume(tile, frameState) { - if (frameState.mode !== SceneMode.SCENE3D && !defined(tile._boundingVolume2D)) { - var boundingSphere = tile._boundingVolume.boundingSphere; - var sphere = BoundingSphere.projectTo2D(boundingSphere, frameState.mapProjection, scratchProjectedBoundingSphere); - tile._boundingVolume2D = new TileBoundingSphere(sphere.center, sphere.radius); - } - - return frameState.mode !== SceneMode.SCENE3D ? tile._boundingVolume2D : tile._boundingVolume; - } - - function getContentBoundingVolume(tile, frameState) { - if (frameState.mode !== SceneMode.SCENE3D && !defined(tile._contentBoundingVolume2D)) { - var boundingSphere = tile._contentBoundingVolume.boundingSphere; - var sphere = BoundingSphere.projectTo2D(boundingSphere, frameState.mapProjection, scratchProjectedBoundingSphere); - tile._contentBoundingVolume2D = new TileBoundingSphere(sphere.center, sphere.radius); - } - return frameState.mode !== SceneMode.SCENE3D ? tile._contentBoundingVolume2D : tile._contentBoundingVolume; } - /** - * Determines whether the tile's bounding volume intersects the culling volume. - * - * @param {FrameState} frameState The frame state. - * @param {Number} parentVisibilityPlaneMask The parent's plane mask to speed up the visibility check. - * @returns {Number} A plane mask as described above in {@link CullingVolume#computeVisibilityWithPlaneMask}. - * - * @private - */ - Cesium3DTile.prototype.visibility = function(frameState, parentVisibilityPlaneMask) { - var cullingVolume = frameState.cullingVolume; - var boundingVolume = getBoundingVolume(this, frameState); - - var tileset = this._tileset; - var clippingPlanes = tileset.clippingPlanes; - if (defined(clippingPlanes) && clippingPlanes.enabled) { - var tileTransform = tileset._root.computedTransform; - var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); - this._isClipped = intersection !== Intersect.INSIDE; - if (intersection === Intersect.OUTSIDE) { - return CullingVolume.MASK_OUTSIDE; - } - } - - return cullingVolume.computeVisibilityWithPlaneMask(boundingVolume, parentVisibilityPlaneMask); - }; - - /** - * Assuming the tile's bounding volume intersects the culling volume, determines - * whether the tile's content's bounding volume intersects the culling volume. - * - * @param {FrameState} frameState The frame state. - * @returns {Intersect} The result of the intersection: the tile's content is completely outside, completely inside, or intersecting the culling volume. - * - * @private - */ - Cesium3DTile.prototype.contentVisibility = function(frameState) { - // Assumes the tile's bounding volume intersects the culling volume already, so - // just return Intersect.INSIDE if there is no content bounding volume. - if (!defined(this._contentBoundingVolume)) { - return Intersect.INSIDE; - } - - // PERFORMANCE_IDEA: is it possible to burn less CPU on this test since we know the - // tile's (not the content's) bounding volume intersects the culling volume? - var cullingVolume = frameState.cullingVolume; - var boundingVolume = getContentBoundingVolume(this, frameState); - - var tileset = this._tileset; - var clippingPlanes = tileset.clippingPlanes; - if (defined(clippingPlanes) && clippingPlanes.enabled) { - var tileTransform = tileset._root.computedTransform; - var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); - this._isClipped = intersection !== Intersect.INSIDE; - if (intersection === Intersect.OUTSIDE) { - return Intersect.OUTSIDE; - } - } - - return cullingVolume.computeVisibility(boundingVolume); - }; - - /** - * Computes the (potentially approximate) distance from the closest point of the tile's bounding volume to the camera. - * - * @param {FrameState} frameState The frame state. - * @returns {Number} The distance, in meters, or zero if the camera is inside the bounding volume. - * - * @private - */ - Cesium3DTile.prototype.distanceToTile = function(frameState) { - var boundingVolume = getBoundingVolume(this, frameState); - return boundingVolume.distanceToCamera(frameState); - }; - - var scratchToTileCenter = new Cartesian3(); - - /** - * Computes the distance from the center of the tile's bounding volume to the camera. - * - * @param {FrameState} frameState The frame state. - * @returns {Number} The distance, in meters, or zero if the camera is inside the bounding volume. - * - * @private - */ - Cesium3DTile.prototype.distanceToTileCenter = function(frameState) { - var tileBoundingVolume = getBoundingVolume(this, frameState); - var boundingVolume = tileBoundingVolume.boundingVolume; // Gets the underlying OrientedBoundingBox or BoundingSphere - var toCenter = Cartesian3.subtract(boundingVolume.center, frameState.camera.positionWC, scratchToTileCenter); - var distance = Cartesian3.magnitude(toCenter); - Cartesian3.divideByScalar(toCenter, distance, toCenter); - var dot = Cartesian3.dot(frameState.camera.directionWC, toCenter); - return distance * dot; - }; - - /** - * Checks if the camera is inside the viewer request volume. - * - * @param {FrameState} frameState The frame state. - * @returns {Boolean} Whether the camera is inside the volume. - * - * @private - */ - Cesium3DTile.prototype.insideViewerRequestVolume = function(frameState) { - var viewerRequestVolume = this._viewerRequestVolume; - return !defined(viewerRequestVolume) || (viewerRequestVolume.distanceToCamera(frameState) === 0.0); - }; - - var scratchMatrix = new Matrix3(); - var scratchScale = new Cartesian3(); - var scratchHalfAxes = new Matrix3(); - var scratchCenter = new Cartesian3(); - var scratchRectangle = new Rectangle(); - - function createBox(box, transform, result) { - var center = Cartesian3.fromElements(box[0], box[1], box[2], scratchCenter); - var halfAxes = Matrix3.fromArray(box, 3, scratchHalfAxes); - - // Find the transformed center and halfAxes - center = Matrix4.multiplyByPoint(transform, center, center); - var rotationScale = Matrix4.getRotation(transform, scratchMatrix); - halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes); + function detectBrokenUrlWorkaround(tileset, tilesetResource, tilesetJson) { + var testUrl = findBrokenUrl(tilesetJson.root); - if (defined(result)) { - result.update(center, halfAxes); - return result; + // If it's an empty string, we are good to load the tileset. + if (!defined(testUrl) || (testUrl.length === 0)) { + return tilesetJson; } - return new TileOrientedBoundingBox(center, halfAxes); - } - - function createRegion(region, result) { - var rectangleRegion = Rectangle.unpack(region, 0, scratchRectangle); - if (defined(result)) { - // Don't update regions when the transform changes - return result; - } - return new TileBoundingRegion({ - rectangle : rectangleRegion, - minimumHeight : region[4], - maximumHeight : region[5] + var testResource = tilesetResource.getDerivedResource({ + url : testUrl }); - } - function createSphere(sphere, transform, result) { - var center = Cartesian3.fromElements(sphere[0], sphere[1], sphere[2], scratchCenter); - var radius = sphere[3]; + return testResource.fetchArrayBuffer() + .then(function(buffer) { + var uint8Array = new Uint8Array(buffer); + var magic = getMagic(uint8Array); - // Find the transformed center and radius - center = Matrix4.multiplyByPoint(transform, center, center); - var scale = Matrix4.getScale(transform, scratchScale); - var uniformScale = Cartesian3.maximumComponent(scale); - radius *= uniformScale; + // If its not a b3dm file, then use workaround + // This accounts for servers that return an error page with a 200 status code + tileset._brokenUrlWorkaround = (magic !== 'b3dm'); - if (defined(result)) { - result.update(center, radius); - return result; - } - return new TileBoundingSphere(center, radius); + return tilesetJson; + }) + .otherwise(function() { + // Tile failed to load, so use the workaround + tileset._brokenUrlWorkaround = true; + return tilesetJson; + }); } - /** - * Create a bounding volume from the tile's bounding volume header. - * - * @param {Object} boundingVolumeHeader The tile's bounding volume header. - * @param {Matrix4} transform The transform to apply to the bounding volume. - * @param {TileBoundingVolume} [result] The object onto which to store the result. - * - * @returns {TileBoundingVolume} The modified result parameter or a new TileBoundingVolume instance if none was provided. - * - * @private - */ - Cesium3DTile.prototype.createBoundingVolume = function(boundingVolumeHeader, transform, result) { - if (!defined(boundingVolumeHeader)) { - throw new RuntimeError('boundingVolume must be defined'); - } - if (defined(boundingVolumeHeader.box)) { - return createBox(boundingVolumeHeader.box, transform, result); - } - if (defined(boundingVolumeHeader.region)) { - return createRegion(boundingVolumeHeader.region, result); - } - if (defined(boundingVolumeHeader.sphere)) { - return createSphere(boundingVolumeHeader.sphere, transform, result); - } - throw new RuntimeError('boundingVolume must contain a sphere, region, or box'); - }; - - var scratchTransform = new Matrix4(); - - /** - * Update the tile's transform. The transform is applied to the tile's bounding volumes. - * - * @private - */ - Cesium3DTile.prototype.updateTransform = function(parentTransform) { - parentTransform = defaultValue(parentTransform, Matrix4.IDENTITY); - var computedTransform = Matrix4.multiply(parentTransform, this.transform, scratchTransform); - var transformChanged = !Matrix4.equals(computedTransform, this.computedTransform); - - if (!transformChanged) { - return; - } - - Matrix4.clone(computedTransform, this.computedTransform); - - // Update the bounding volumes - var header = this._header; - var content = this._header.content; - this._boundingVolume = this.createBoundingVolume(header.boundingVolume, computedTransform, this._boundingVolume); - if (defined(this._contentBoundingVolume)) { - this._contentBoundingVolume = this.createBoundingVolume(content.boundingVolume, computedTransform, this._contentBoundingVolume); - } - if (defined(this._viewerRequestVolume)) { - this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, computedTransform, this._viewerRequestVolume); - } - - // Destroy the debug bounding volumes. They will be generated fresh. - this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); - this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); - this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); - }; - - function applyDebugSettings(tile, tileset, frameState) { - var hasContentBoundingVolume = defined(tile._header.content) && defined(tile._header.content.boundingVolume); - - var showVolume = tileset.debugShowBoundingVolume || (tileset.debugShowContentBoundingVolume && !hasContentBoundingVolume); - if (showVolume) { - if (!defined(tile._debugBoundingVolume)) { - var color = tile._finalResolution ? (hasContentBoundingVolume ? Color.WHITE : Color.RED) : Color.YELLOW; - tile._debugBoundingVolume = tile._boundingVolume.createDebugVolume(color); - } - tile._debugBoundingVolume.update(frameState); - } else if (!showVolume && defined(tile._debugBoundingVolume)) { - tile._debugBoundingVolume = tile._debugBoundingVolume.destroy(); - } - - if (tileset.debugShowContentBoundingVolume && hasContentBoundingVolume) { - if (!defined(tile._debugContentBoundingVolume)) { - tile._debugContentBoundingVolume = tile._contentBoundingVolume.createDebugVolume(Color.BLUE); - } - tile._debugContentBoundingVolume.update(frameState); - } else if (!tileset.debugShowContentBoundingVolume && defined(tile._debugContentBoundingVolume)) { - tile._debugContentBoundingVolume = tile._debugContentBoundingVolume.destroy(); - } + var brokenUrlRegex = /^\/.+\.b3dm$/; - if (tileset.debugShowViewerRequestVolume && defined(tile._viewerRequestVolume)) { - if (!defined(tile._debugViewerRequestVolume)) { - tile._debugViewerRequestVolume = tile._viewerRequestVolume.createDebugVolume(Color.YELLOW); + function findBrokenUrl(node) { + var content = node.content; + if (defined(content) && defined(content.url)) { + if (brokenUrlRegex.test(content.url)) { + return content.url; } - tile._debugViewerRequestVolume.update(frameState); - } else if (!tileset.debugShowViewerRequestVolume && defined(tile._debugViewerRequestVolume)) { - tile._debugViewerRequestVolume = tile._debugViewerRequestVolume.destroy(); - } - - var debugColorizeTilesOn = tileset.debugColorizeTiles && !tile._debugColorizeTiles; - var debugColorizeTilesOff = !tileset.debugColorizeTiles && tile._debugColorizeTiles; - - if (debugColorizeTilesOn) { - tile._debugColorizeTiles = true; - tile.color = tile._debugColor; - } else if (debugColorizeTilesOff) { - tile._debugColorizeTiles = false; - tile.color = Color.WHITE; - } - - if (tile._colorDirty) { - tile._colorDirty = false; - tile._content.applyDebugSettings(true, tile._color); - } - if (debugColorizeTilesOff) { - tileset.makeStyleDirty(); // Re-apply style now that colorize is switched off + return ''; } - } - - function updateContent(tile, tileset, frameState) { - var content = tile._content; - var expiredContent = tile._expiredContent; - if (defined(expiredContent)) { - if (!tile.contentReady) { - // Render the expired content while the content loads - expiredContent.update(tileset, frameState); - return; + var children = node.children; + if (defined(children)) { + var count = children.length; + for (var i = 0; i < count; ++i) { + var result = findBrokenUrl(children[i]); + if (defined(result)) { + return result; + } } - - // New content is ready, destroy expired content - tile._expiredContent.destroy(); - tile._expiredContent = undefined; } - - content.update(tileset, frameState); } - /** - * Get the draw commands needed to render this tile. - * - * @private - */ - Cesium3DTile.prototype.update = function(tileset, frameState) { - var initCommandLength = frameState.commandList.length; - applyDebugSettings(this, tileset, frameState); - updateContent(this, tileset, frameState); - this._commandsLength = frameState.commandList.length - initCommandLength; - }; - - var scratchCommandList = []; - - /** - * Processes the tile's content, e.g., create WebGL resources, to move from the PROCESSING to READY state. - * - * @param {Cesium3DTileset} tileset The tileset containing this tile. - * @param {FrameState} frameState The frame state. - * - * @private - */ - Cesium3DTile.prototype.process = function(tileset, frameState) { - var savedCommandList = frameState.commandList; - frameState.commandList = scratchCommandList; - - this._content.update(tileset, frameState); - - scratchCommandList.length = 0; - frameState.commandList = savedCommandList; - }; - - /** - * @private - */ - Cesium3DTile.prototype.isDestroyed = function() { - return false; - }; - - /** - * @private - */ - Cesium3DTile.prototype.destroy = function() { - // For the interval between new content being requested and downloaded, expiredContent === content, so don't destroy twice - this._content = this._content && this._content.destroy(); - this._expiredContent = this._expiredContent && !this._expiredContent.isDestroyed() && this._expiredContent.destroy(); - this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); - this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); - this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); - return destroyObject(this); - }; - - return Cesium3DTile; -}); - -define('Scene/Cesium3DTileContent',[ - '../Core/defineProperties', - '../Core/DeveloperError' - ], function( - defineProperties, - DeveloperError) { - 'use strict'; + defineProperties(Cesium3DTileset.prototype, { + /** + * Gets the tileset's asset object property, which contains metadata about the tileset. + * <p> + * See the {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/schema/asset.schema.json|asset schema} + * in the 3D Tiles spec for the full set of properties. + * </p> + * + * @memberof Cesium3DTileset.prototype + * + * @type {Object} + * @readonly + * + * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. + */ + asset : { + get : function() { + if (!this.ready) { + throw new DeveloperError('The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true.'); + } + + return this._asset; + } + }, - /** - * The content of a tile in a {@link Cesium3DTileset}. - * <p> - * Derived classes of this interface provide access to individual features in the tile. - * Access derived objects through {@link Cesium3DTile#content}. - * </p> - * <p> - * This type describes an interface and is not intended to be instantiated directly. - * </p> - * - * @alias Cesium3DTileContent - * @constructor - */ - function Cesium3DTileContent(tileset, tile, url, arrayBuffer, byteOffset) { /** - * Gets or sets if any feature's property changed. Used to - * optimized applying a style when a feature's property changed. + * Gets the tileset's properties dictionary object, which contains metadata about per-feature properties. * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. + * See the {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/schema/properties.schema.json|properties schema} + * in the 3D Tiles spec for the full set of properties. * </p> * - * @type {Boolean} + * @memberof Cesium3DTileset.prototype * - * @private + * @type {Object} + * @readonly + * + * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. + * + * @example + * console.log('Maximum building height: ' + tileset.properties.height.maximum); + * console.log('Minimum building height: ' + tileset.properties.height.minimum); + * + * @see Cesium3DTileFeature#getProperty + * @see Cesium3DTileFeature#setProperty */ - this.featurePropertiesDirty = false; - } + properties : { + get : function() { + if (!this.ready) { + throw new DeveloperError('The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true.'); + } + + return this._properties; + } + }, - defineProperties(Cesium3DTileContent.prototype, { /** - * Gets the number of features in the tile. + * When <code>true</code>, the tileset's root tile is loaded and the tileset is ready to render. + * This is set to <code>true</code> right before {@link Cesium3DTileset#readyPromise} is resolved. * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {Boolean} * @readonly + * + * @default false */ - featuresLength : { + ready : { get : function() { - DeveloperError.throwInstantiationError(); + return defined(this._root); } }, /** - * Gets the number of points in the tile. + * Gets the promise that will be resolved when the tileset's root tile is loaded and the tileset is ready to render. * <p> - * Only applicable for tiles with Point Cloud content. This is different than {@link Cesium3DTileContent#featuresLength} which - * equals the number of groups of points as distinguished by the <code>BATCH_ID</code> feature table semantic. + * This promise is resolved at the end of the frame before the first frame the tileset is rendered in. * </p> * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/PointCloud/README.md#batched-points} - * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {Promise.<Cesium3DTileset>} * @readonly + * + * @example + * tileset.readyPromise.then(function(tileset) { + * // tile.properties is not defined until readyPromise resolves. + * var properties = tileset.properties; + * if (Cesium.defined(properties)) { + * for (var name in properties) { + * console.log(properties[name]); + * } + * } + * }); */ - pointsLength : { + readyPromise : { get : function() { - DeveloperError.throwInstantiationError(); + return this._readyPromise.promise; } }, /** - * Gets the number of triangles in the tile. + * When <code>true</code>, all tiles that meet the screen space error this frame are loaded. The tileset is + * completely loaded for this view. * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {Boolean} * @readonly + * + * @default false + * + * @see Cesium3DTileset#allTilesLoaded */ - trianglesLength : { + tilesLoaded : { get : function() { - DeveloperError.throwInstantiationError(); + return this._tilesLoaded; } }, /** - * Gets the tile's geometry memory in bytes. + * The url to a tileset.json file or to a directory containing a tileset.json file. * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {String} * @readonly */ - geometryByteLength : { + url : { get : function() { - DeveloperError.throwInstantiationError(); + return this._url; } }, /** - * Gets the tile's texture memory in bytes. + * The base path that non-absolute paths in tileset.json are relative to. * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {String} * @readonly + * @deprecated */ - texturesByteLength : { + basePath : { get : function() { - DeveloperError.throwInstantiationError(); + deprecationWarning('Cesium3DTileset.basePath', 'Cesium3DTileset.basePath has been deprecated. All tiles are relative to the url of the tileset.json that contains them. Use the url property instead.'); + return this._basePath; } }, /** - * Gets the amount of memory used by the batch table textures, in bytes. + * The style, defined using the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}, + * applied to each feature in the tileset. + * <p> + * Assign <code>undefined</code> to remove the style, which will restore the visual + * appearance of the tileset to its default when no style was applied. + * </p> + * <p> + * The style is applied to a tile before the {@link Cesium3DTileset#tileVisible} + * event is raised, so code in <code>tileVisible</code> can manually set a feature's + * properties (e.g. color and show) after the style is applied. When + * a new style is assigned any manually set properties are overwritten. + * </p> * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype + * + * @type {Cesium3DTileStyle} + * + * @default undefined + * + * @example + * tileset.style = new Cesium.Cesium3DTileStyle({ + * color : { + * conditions : [ + * ['${Height} >= 100', 'color("purple", 0.5)'], + * ['${Height} >= 50', 'color("red")'], + * ['true', 'color("blue")'] + * ] + * }, + * show : '${Height} > 0', + * meta : { + * description : '"Building id ${id} has height ${Height}."' + * } + * }); + * + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} + */ + style : { + get : function() { + return this._styleEngine.style; + }, + set : function(value) { + this._styleEngine.style = value; + } + }, + + /** + * The maximum screen space error used to drive level of detail refinement. This value helps determine when a tile + * refines to its descendants, and therefore plays a major role in balancing performance with visual quality. + * <p> + * A tile's screen space error is roughly equivalent to the number of pixels wide that would be drawn if a sphere with a + * radius equal to the tile's <b>geometric error</b> were rendered at the tile's position. If this value exceeds + * <code>maximumScreenSpaceError</code> the tile refines to its descendants. + * </p> + * <p> + * Depending on the tileset, <code>maximumScreenSpaceError</code> may need to be tweaked to achieve the right balance. + * Higher values provide better performance but lower visual quality. + * </p> + * + * @memberof Cesium3DTileset.prototype * * @type {Number} - * @readonly + * @default 16 + * + * @exception {DeveloperError} <code>maximumScreenSpaceError</code> must be greater than or equal to zero. */ - batchTableByteLength : { + maximumScreenSpaceError : { get : function() { - DeveloperError.throwInstantiationError(); + return this._maximumScreenSpaceError; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('maximumScreenSpaceError', value, 0); + + this._maximumScreenSpaceError = value; } }, /** - * Gets the array of {@link Cesium3DTileContent} objects that represent the - * content a composite's inner tiles, which can also be composites. + * The maximum amount of GPU memory (in MB) that may be used to cache tiles. This value is estimated from + * geometry, textures, and batch table textures of loaded tiles. For point clouds, this value also + * includes per-point metadata. + * <p> + * Tiles not in view are unloaded to enforce this. + * </p> + * <p> + * If decreasing this value results in unloading tiles, the tiles are unloaded the next frame. + * </p> + * <p> + * If tiles sized more than <code>maximumMemoryUsage</code> are needed + * to meet the desired screen space error, determined by {@link Cesium3DTileset#maximumScreenSpaceError}, + * for the current view, then the memory usage of the tiles loaded will exceed + * <code>maximumMemoryUsage</code>. For example, if the maximum is 256 MB, but + * 300 MB of tiles are needed to meet the screen space error, then 300 MB of tiles may be loaded. When + * these tiles go out of view, they will be unloaded. + * </p> * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Composite/README.md} + * @memberof Cesium3DTileset.prototype * - * @memberof Cesium3DTileContent.prototype + * @type {Number} + * @default 512 * - * @type {Array} - * @readonly + * @exception {DeveloperError} <code>maximumMemoryUsage</code> must be greater than or equal to zero. + * @see Cesium3DTileset#totalMemoryUsageInBytes */ - innerContents : { + maximumMemoryUsage : { get : function() { - DeveloperError.throwInstantiationError(); + return this._maximumMemoryUsage; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0); + + this._maximumMemoryUsage = value; } }, /** - * Gets the promise that will be resolved when the tile's content is ready to render. + * The tileset's bounding sphere. * - * @memberof Cesium3DTileContent.prototype + * @memberof Cesium3DTileset.prototype * - * @type {Promise.<Cesium3DTileContent>} + * @type {BoundingSphere} * @readonly + * + * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. + * + * @example + * var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ + * url : 'http://localhost:8002/tilesets/Seattle' + * })); + * + * tileset.readyPromise.then(function(tileset) { + * // Set the camera to view the newly added tileset + * viewer.camera.viewBoundingSphere(tileset.boundingSphere, new Cesium.HeadingPitchRange(0, -0.5, 0)); + * }); */ - readyPromise : { + boundingSphere : { get : function() { - DeveloperError.throwInstantiationError(); + if (!this.ready) { + throw new DeveloperError('The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true.'); + } + + return this._root.boundingSphere; } }, /** - * Gets the tileset for this tile. + * A 4x4 transformation matrix that transforms the entire tileset. * - * @type {Cesium3DTileset} - * @readonly + * @memberof Cesium3DTileset.prototype + * + * @type {Matrix4} + * @default Matrix4.IDENTITY + * + * @example + * // Adjust a tileset's height from the globe's surface. + * var heightOffset = 20.0; + * var boundingSphere = tileset.boundingSphere; + * var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center); + * var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0); + * var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset); + * var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); + * tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); */ - tileset : { + modelMatrix : { get : function() { - DeveloperError.throwInstantiationError(); + return this._modelMatrix; + }, + set : function(value) { + this._modelMatrix = Matrix4.clone(value, this._modelMatrix); + if (defined(this._root)) { + // Update the root transform right away instead of waiting for the next update loop. + // Useful, for example, when setting the modelMatrix and then having the camera view the tileset. + this._root.updateTransform(this._modelMatrix); + } } }, /** - * Gets the tile containing this content. + * Returns the time, in milliseconds, since the tileset was loaded and first updated. * - * @type {Cesium3DTile} + * @memberof Cesium3DTileset.prototype + * + * @type {Number} * @readonly */ - tile : { + timeSinceLoad : { get : function() { - DeveloperError.throwInstantiationError(); + return this._timeSinceLoad; } }, /** - * Gets the url of the tile's content. - * @memberof Cesium3DTileContent.prototype + * The total amount of GPU memory in bytes used by the tileset. This value is estimated from + * geometry, texture, and batch table textures of loaded tiles. For point clouds, this value also + * includes per-point metadata. * - * @type {String} + * @memberof Cesium3DTileset.prototype + * + * @type {Number} * @readonly + * + * @see Cesium3DTileset#maximumMemoryUsage */ - url : { + totalMemoryUsageInBytes : { get : function() { - DeveloperError.throwInstantiationError(); + var statistics = this._statistics; + return statistics.texturesByteLength + statistics.geometryByteLength + statistics.batchTableByteLength; } }, /** - * Gets the batch table for this content. + * @private + */ + styleEngine : { + get : function() { + return this._styleEngine; + } + }, + + /** + * @private + */ + statistics : { + get : function() { + return this._statistics; + } + }, + + /** + * Determines whether terrain, 3D Tiles or both will be classified by this tileset. * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. + * This option is only applied to tilesets containing batched 3D models, geometry data, or vector data. Even when undefined, vector data and geometry data + * must render as classifications and will default to rendering on both terrain and other 3D Tiles tilesets. + * </p> + * <p> + * When enabled for batched 3D model tilesets, there are a few requirements/limitations on the glTF: + * <ul> + * <li>POSITION and _BATCHID semantics are required.</li> + * <li>All indices with the same batch id must occupy contiguous sections of the index buffer.</li> + * <li>All shaders and techniques are ignored. The generated shader simply multiplies the position by the model-view-projection matrix.</li> + * <li>The only supported extensions are CESIUM_RTC and WEB3D_quantized_attributes.</li> + * <li>Only one node is supported.</li> + * <li>Only one mesh per node is supported.</li> + * <li>Only one primitive per mesh is supported.</li> + * </ul> * </p> * - * @type {Cesium3DTileBatchTable} + * @memberof Cesium3DTileset.prototype + * + * @type {ClassificationType} + * @default undefined + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * @readonly + */ + classificationType : { + get : function() { + return this._classificationType; + } + }, + + /** + * Gets an ellipsoid describing the shape of the globe. * - * @private + * @memberof Cesium3DTileset.prototype + * + * @type {Ellipsoid} + * @readonly */ - batchTable : { + ellipsoid : { get : function() { - DeveloperError.throwInstantiationError(); + return this._ellipsoid; } } }); /** - * Determines if the tile's batch table has a property. If it does, each feature in - * the tile will have the property. - * - * @param {Number} batchId The batchId for the feature. - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} <code>true</code> if the property exists; otherwise, <code>false</code>. - */ - Cesium3DTileContent.prototype.hasProperty = function(batchId, name) { - DeveloperError.throwInstantiationError(); - }; - - /** - * Returns the {@link Cesium3DTileFeature} object for the feature with the - * given <code>batchId</code>. This object is used to get and modify the - * feature's properties. - * <p> - * Features in a tile are ordered by <code>batchId</code>, an index used to retrieve their metadata from the batch table. - * </p> - * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/TileFormats/BatchTable}. - * - * @param {Number} batchId The batchId for the feature. - * @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object. - * - * @exception {DeveloperError} batchId must be between zero and {@link Cesium3DTileContent#featuresLength} - 1. - */ - Cesium3DTileContent.prototype.getFeature = function(batchId) { - DeveloperError.throwInstantiationError(); - }; - - /** - * Called when {@link Cesium3DTileset#debugColorizeTiles} changes. - * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. - * </p> - * - * @param {Boolean} enabled Whether to enable or disable debug settings. - * @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object. - - * @private - */ - Cesium3DTileContent.prototype.applyDebugSettings = function(enabled, color) { - DeveloperError.throwInstantiationError(); - }; - - /** - * Apply a style to the content - * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. - * </p> - * - * @param {FrameSate} frameState The frame state. - * @param {Cesium3DTileStyle} style The style. - * - * @private - */ - Cesium3DTileContent.prototype.applyStyle = function(frameState, style) { - DeveloperError.throwInstantiationError(); - }; - - /** - * Called by the tile during tileset traversal to get the draw commands needed to render this content. - * When the tile's content is in the PROCESSING state, this creates WebGL resources to ultimately - * move to the READY state. - * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. - * </p> - * - * @param {Cesium3DTileset} tileset The tileset containing this tile. - * @param {FrameState} frameState The frame state. - * - * @private - */ - Cesium3DTileContent.prototype.update = function(tileset, frameState) { - DeveloperError.throwInstantiationError(); - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. - * </p> - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see Cesium3DTileContent#destroy - * - * @private + * Provides a hook to override the method used to request the tileset json + * useful when fetching tilesets from remote servers + * @param {Resource|String} tilesetUrl The url of the json file to be fetched + * @returns {Promise.<Object>} A promise that resolves with the fetched json data */ - Cesium3DTileContent.prototype.isDestroyed = function() { - DeveloperError.throwInstantiationError(); + Cesium3DTileset.loadJson = function(tilesetUrl) { + var resource = Resource.createIfNeeded(tilesetUrl); + return resource.fetchJson(); }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * <p> - * This is used to implement the <code>Cesium3DTileContent</code> interface, but is - * not part of the public Cesium API. - * </p> - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @example - * content = content && content.destroy(); - * - * @see Cesium3DTileContent#isDestroyed - * - * @private + * Marks the tileset's {@link Cesium3DTileset#style} as dirty, which forces all + * features to re-evaluate the style in the next frame each is visible. */ - Cesium3DTileContent.prototype.destroy = function() { - DeveloperError.throwInstantiationError(); + Cesium3DTileset.prototype.makeStyleDirty = function() { + this._styleEngine.makeDirty(); }; - return Cesium3DTileContent; -}); - -define('Scene/Cesium3DTileOptimizations',[ - '../Core/Cartesian3', - '../Core/Check', - './Cesium3DTileOptimizationHint', - './TileBoundingRegion', - './TileOrientedBoundingBox' - ], function( - Cartesian3, - Check, - Cesium3DTileOptimizationHint, - TileBoundingRegion, - TileOrientedBoundingBox) { - 'use strict'; - /** - * Utility functions for computing optimization hints for a {@link Cesium3DTileset}. - * - * @exports Cesium3DTileOptimizations + * Loads the main tileset.json or a tileset.json referenced from a tile. * * @private */ - var Cesium3DTileOptimizations = {}; - - var scratchAxis = new Cartesian3(); - - /** - * Evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if - * children bounds are fully contained within the parent. Currently, support for the optimization only works for - * oriented bounding boxes, so both the child and parent tile must be either a {@link TileOrientedBoundingBox} or - * {@link TileBoundingRegion}. The purpose of this check is to prevent use of a culling optimization when the child - * bounds exceed those of the parent. If the child bounds are greater, it is more likely that the optimization will - * waste CPU cycles. Bounding spheres are not supported for the reason that the child bounds can very often be - * partially outside of the parent bounds. - * - * @param {Cesium3DTile} tile The tile to check. - * @returns {Boolean} Whether the childrenWithinParent optimization is supported. - */ - Cesium3DTileOptimizations.checkChildrenWithinParent = function(tile) { - Check.typeOf.object('tile', tile); - - var children = tile.children; - var length = children.length; + Cesium3DTileset.prototype.loadTileset = function(tilesetResource, tilesetJson, parentTile) { + var asset = tilesetJson.asset; + if (!defined(asset)) { + throw new RuntimeError('Tileset must have an asset property.'); + } + if (asset.version !== '0.0' && asset.version !== '1.0') { + throw new RuntimeError('The tileset must be 3D Tiles version 0.0 or 1.0. See https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status'); + } - // Check if the parent has an oriented bounding box. - var boundingVolume = tile._boundingVolume; - if (boundingVolume instanceof TileOrientedBoundingBox || boundingVolume instanceof TileBoundingRegion) { - var orientedBoundingBox = boundingVolume._orientedBoundingBox; - tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.USE_OPTIMIZATION; - for (var i = 0; i < length; ++i) { - var child = children[i]; + var statistics = this._statistics; - // Check if the child has an oriented bounding box. - var childBoundingVolume = child._boundingVolume; - if (!(childBoundingVolume instanceof TileOrientedBoundingBox || childBoundingVolume instanceof TileBoundingRegion)) { - // Do not support if the parent and child both do not have oriented bounding boxes. - tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; - break; - } + // Append the tileset version to the tilesetResource + if (!defined(tilesetResource.queryParameters.v)) { + var versionQuery = { + v: defaultValue(asset.tilesetVersion, '0.0') + }; + this._basePath += '?v=' + versionQuery.v; + tilesetResource.addQueryParameters(versionQuery); + } - var childOrientedBoundingBox = childBoundingVolume._orientedBoundingBox; + // A tileset.json referenced from a tile may exist in a different directory than the root tileset. + // Get the basePath relative to the external tileset. + var rootTile = new Cesium3DTile(this, tilesetResource, tilesetJson.root, parentTile); - // Compute the axis from the parent to the child. - var axis = Cartesian3.subtract(childOrientedBoundingBox.center, orientedBoundingBox.center, scratchAxis); - var axisLength = Cartesian3.magnitude(axis); - Cartesian3.divideByScalar(axis, axisLength, axis); + // If there is a parentTile, add the root of the currently loading tileset + // to parentTile's children, and update its _depth. + if (defined(parentTile)) { + parentTile.children.push(rootTile); + rootTile._depth = parentTile._depth + 1; + } - // Project the bounding box of the parent onto the axis. Because the axis is a ray from the parent - // to the child, the projection parameterized along the ray will be (+/- proj1). - var proj1 = Math.abs(orientedBoundingBox.halfAxes[0] * axis.x) + - Math.abs(orientedBoundingBox.halfAxes[1] * axis.y) + - Math.abs(orientedBoundingBox.halfAxes[2] * axis.z) + - Math.abs(orientedBoundingBox.halfAxes[3] * axis.x) + - Math.abs(orientedBoundingBox.halfAxes[4] * axis.y) + - Math.abs(orientedBoundingBox.halfAxes[5] * axis.z) + - Math.abs(orientedBoundingBox.halfAxes[6] * axis.x) + - Math.abs(orientedBoundingBox.halfAxes[7] * axis.y) + - Math.abs(orientedBoundingBox.halfAxes[8] * axis.z); + ++statistics.numberOfTilesTotal; - // Project the bounding box of the child onto the axis. Because the axis is a ray from the parent - // to the child, the projection parameterized along the ray will be (+/- proj2) + axis.length. - var proj2 = Math.abs(childOrientedBoundingBox.halfAxes[0] * axis.x) + - Math.abs(childOrientedBoundingBox.halfAxes[1] * axis.y) + - Math.abs(childOrientedBoundingBox.halfAxes[2] * axis.z) + - Math.abs(childOrientedBoundingBox.halfAxes[3] * axis.x) + - Math.abs(childOrientedBoundingBox.halfAxes[4] * axis.y) + - Math.abs(childOrientedBoundingBox.halfAxes[5] * axis.z) + - Math.abs(childOrientedBoundingBox.halfAxes[6] * axis.x) + - Math.abs(childOrientedBoundingBox.halfAxes[7] * axis.y) + - Math.abs(childOrientedBoundingBox.halfAxes[8] * axis.z); + var stack = []; + stack.push({ + header : tilesetJson.root, + tile3D : rootTile + }); - // If the child extends the parent's bounds, the optimization is not valid and we skip it. - if (proj1 <= proj2 + axisLength) { - tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; - break; + while (stack.length > 0) { + var tile = stack.pop(); + var tile3D = tile.tile3D; + var children = tile.header.children; + if (defined(children)) { + var length = children.length; + for (var i = 0; i < length; ++i) { + var childHeader = children[i]; + var childTile = new Cesium3DTile(this, tilesetResource, childHeader, tile3D); + tile3D.children.push(childTile); + childTile._depth = tile3D._depth + 1; + ++statistics.numberOfTilesTotal; + stack.push({ + header : childHeader, + tile3D : childTile + }); } } - } - - return tile._optimChildrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION; - }; - - return Cesium3DTileOptimizations; -}); - -define('Scene/Cesium3DTilesetStatistics',[ - '../Core/defined' - ], function( - defined) { - 'use strict'; - - /** - * @private - */ - function Cesium3DTilesetStatistics() { - // Rendering statistics - this.selected = 0; - this.visited = 0; - // Loading statistics - this.numberOfCommands = 0; - this.numberOfAttemptedRequests = 0; - this.numberOfPendingRequests = 0; - this.numberOfTilesProcessing = 0; - this.numberOfTilesWithContentReady = 0; // Number of tiles with content loaded, does not include empty tiles - this.numberOfTilesTotal = 0; // Number of tiles in tileset.json (and other tileset.json files as they are loaded) - // Features statistics - this.numberOfFeaturesSelected = 0; // Number of features rendered - this.numberOfFeaturesLoaded = 0; // Number of features in memory - this.numberOfPointsSelected = 0; - this.numberOfPointsLoaded = 0; - this.numberOfTrianglesSelected = 0; - // Styling statistics - this.numberOfTilesStyled = 0; - this.numberOfFeaturesStyled = 0; - // Optimization statistics - this.numberOfTilesCulledWithChildrenUnion = 0; - // Memory statistics - this.geometryByteLength = 0; - this.texturesByteLength = 0; - this.batchTableByteLength = 0; - } - - Cesium3DTilesetStatistics.prototype.clear = function() { - this.selected = 0; - this.visited = 0; - this.numberOfCommands = 0; - this.numberOfAttemptedRequests = 0; - this.numberOfFeaturesSelected = 0; - this.numberOfPointsSelected = 0; - this.numberOfTrianglesSelected = 0; - this.numberOfTilesStyled = 0; - this.numberOfFeaturesStyled = 0; - this.numberOfTilesCulledWithChildrenUnion = 0; - }; - - function updatePointAndFeatureCounts(statistics, content, decrement, load) { - var contents = content.innerContents; - var pointsLength = content.pointsLength; - var trianglesLength = content.trianglesLength; - var featuresLength = content.featuresLength; - var geometryByteLength = content.geometryByteLength; - var texturesByteLength = content.texturesByteLength; - var batchTableByteLength = content.batchTableByteLength; - if (load) { - statistics.numberOfFeaturesLoaded += decrement ? -featuresLength : featuresLength; - statistics.numberOfPointsLoaded += decrement ? -pointsLength : pointsLength; - statistics.geometryByteLength += decrement ? -geometryByteLength : geometryByteLength; - statistics.texturesByteLength += decrement ? -texturesByteLength : texturesByteLength; - statistics.batchTableByteLength += decrement ? -batchTableByteLength : batchTableByteLength; - } else { - statistics.numberOfFeaturesSelected += decrement ? -featuresLength : featuresLength; - statistics.numberOfPointsSelected += decrement ? -pointsLength : pointsLength; - statistics.numberOfTrianglesSelected += decrement ? -trianglesLength : trianglesLength; - } - - if (defined(contents)) { - var length = contents.length; - for (var i = 0; i < length; ++i) { - updatePointAndFeatureCounts(statistics, contents[i], decrement, load); + if (this._cullWithChildrenBounds) { + Cesium3DTileOptimizations.checkChildrenWithinParent(tile3D); } } - } - - Cesium3DTilesetStatistics.prototype.incrementSelectionCounts = function(content) { - updatePointAndFeatureCounts(this, content, false, false); - }; - - Cesium3DTilesetStatistics.prototype.incrementLoadCounts = function(content) { - updatePointAndFeatureCounts(this, content, false, true); - }; - - Cesium3DTilesetStatistics.prototype.decrementLoadCounts = function(content) { - updatePointAndFeatureCounts(this, content, true, true); - }; - Cesium3DTilesetStatistics.clone = function(statistics, result) { - result.selected = statistics.selected; - result.visited = statistics.visited; - result.numberOfCommands = statistics.numberOfCommands; - result.selected = statistics.selected; - result.numberOfAttemptedRequests = statistics.numberOfAttemptedRequests; - result.numberOfPendingRequests = statistics.numberOfPendingRequests; - result.numberOfTilesProcessing = statistics.numberOfTilesProcessing; - result.numberOfTilesWithContentReady = statistics.numberOfTilesWithContentReady; - result.numberOfTilesTotal = statistics.numberOfTilesTotal; - result.numberOfFeaturesSelected = statistics.numberOfFeaturesSelected; - result.numberOfFeaturesLoaded = statistics.numberOfFeaturesLoaded; - result.numberOfPointsSelected = statistics.numberOfPointsSelected; - result.numberOfPointsLoaded = statistics.numberOfPointsLoaded; - result.numberOfTrianglesSelected = statistics.numberOfTrianglesSelected; - result.numberOfTilesStyled = statistics.numberOfTilesStyled; - result.numberOfFeaturesStyled = statistics.numberOfFeaturesStyled; - result.numberOfTilesCulledWithChildrenUnion = statistics.numberOfTilesCulledWithChildrenUnion; - result.geometryByteLength = statistics.geometryByteLength; - result.texturesByteLength = statistics.texturesByteLength; - result.batchTableByteLength = statistics.batchTableByteLength; + return rootTile; }; - return Cesium3DTilesetStatistics; -}); - -define('Scene/Cesium3DTilesetTraversal',[ - '../Core/CullingVolume', - '../Core/defined', - '../Core/freezeObject', - '../Core/Intersect', - '../Core/ManagedArray', - '../Core/Math', - '../Core/OrthographicFrustum', - './Cesium3DTileChildrenVisibility', - './Cesium3DTileRefine', - './SceneMode' - ], function( - CullingVolume, - defined, - freezeObject, - Intersect, - ManagedArray, - CesiumMath, - OrthographicFrustum, - Cesium3DTileChildrenVisibility, - Cesium3DTileRefine, - SceneMode) { - 'use strict'; - - /** - * @private - */ - var Cesium3DTilesetTraversal = {}; - - function selectTiles(tileset, frameState, outOfCore) { - if (tileset.debugFreezeFrame) { - return; - } - - var maximumScreenSpaceError = tileset._maximumScreenSpaceError; - - tileset._desiredTiles.length = 0; - tileset._selectedTiles.length = 0; - tileset._requestedTiles.length = 0; - tileset._selectedTilesToStyle.length = 0; - tileset._hasMixedContent = false; + var scratchPositionNormal = new Cartesian3(); + var scratchCartographic = new Cartographic(); + var scratchMatrix = new Matrix4(); + var scratchCenter = new Cartesian3(); + var scratchPosition = new Cartesian3(); + var scratchDirection = new Cartesian3(); - // Move sentinel node to the tail so, at the start of the frame, all tiles - // may be potentially replaced. Tiles are moved to the right of the sentinel - // when they are selected so they will not be replaced. - var replacementList = tileset._replacementList; - replacementList.splice(replacementList.tail, tileset._replacementSentinel); + function updateDynamicScreenSpaceError(tileset, frameState) { + var up; + var direction; + var height; + var minimumHeight; + var maximumHeight; + var camera = frameState.camera; var root = tileset._root; - root.updateTransform(tileset._modelMatrix); - - if (!root.insideViewerRequestVolume(frameState)) { - return; - } - - root._distanceToCamera = root.distanceToTile(frameState); - - if (getScreenSpaceError(tileset, tileset._geometricError, root, frameState) <= maximumScreenSpaceError) { - // The SSE of not rendering the tree is small enough that the tree does not need to be rendered - return; - } - - root._visibilityPlaneMask = root.visibility(frameState, CullingVolume.MASK_INDETERMINATE); - if (root._visibilityPlaneMask === CullingVolume.MASK_OUTSIDE) { - return; - } - - loadTile(tileset, root, frameState, true); + var tileBoundingVolume = root.contentBoundingVolume; - if (!tileset.skipLevelOfDetail) { - // just execute base traversal and add tiles to _desiredTiles - tileset._baseTraversal.execute(tileset, root, maximumScreenSpaceError, frameState, outOfCore); - var leaves = tileset._baseTraversal.leaves; - var length = leaves.length; - for (var i = 0; i < length; ++i) { - tileset._desiredTiles.push(leaves.get(i)); - } - } else if (tileset.immediatelyLoadDesiredLevelOfDetail) { - tileset._skipTraversal.execute(tileset, root, frameState, outOfCore); + if (tileBoundingVolume instanceof TileBoundingRegion) { + up = Cartesian3.normalize(camera.positionWC, scratchPositionNormal); + direction = camera.directionWC; + height = camera.positionCartographic.height; + minimumHeight = tileBoundingVolume.minimumHeight; + maximumHeight = tileBoundingVolume.maximumHeight; } else { - // leaves of the base traversal is where we start the skip traversal - tileset._baseTraversal.leaves = tileset._skipTraversal.queue1; - - // load and select tiles without skipping up to tileset.baseScreenSpaceError - tileset._baseTraversal.execute(tileset, root, tileset.baseScreenSpaceError, frameState, outOfCore); - - // skip traversal starts from a prepopulated queue from the base traversal - tileset._skipTraversal.execute(tileset, undefined, frameState, outOfCore); - } - - // mark tiles for selection or their nearest loaded ancestor - markLoadedTilesForSelection(tileset, frameState, outOfCore); - - // sort selected tiles by distance to camera and call selectTile on each - // set tile._selectionDepth on all tiles - traverseAndSelect(tileset, root, frameState); - - tileset._desiredTiles.trim(); - } - - var descendantStack = []; - - function markLoadedTilesForSelection(tileset, frameState, outOfCore) { - var tiles = tileset._desiredTiles; - var length = tiles.length; - for (var i = 0; i < length; ++i) { - var original = tiles.get(i); - - if (hasAdditiveContent(original)) { - original.selected = true; - original._selectedFrame = frameState.frameNumber; - continue; - } - - var loadedTile = original._ancestorWithLoadedContent; - if (original.hasRenderableContent && original.contentAvailable) { - loadedTile = original; - } - - if (defined(loadedTile)) { - loadedTile.selected = true; - loadedTile._selectedFrame = frameState.frameNumber; + // Transform camera position and direction into the local coordinate system of the tileset + var transformLocal = Matrix4.inverseTransformation(root.computedTransform, scratchMatrix); + var ellipsoid = frameState.mapProjection.ellipsoid; + var boundingVolume = tileBoundingVolume.boundingVolume; + var centerLocal = Matrix4.multiplyByPoint(transformLocal, boundingVolume.center, scratchCenter); + if (Cartesian3.magnitude(centerLocal) > ellipsoid.minimumRadius) { + // The tileset is defined in WGS84. Approximate the minimum and maximum height. + var centerCartographic = Cartographic.fromCartesian(centerLocal, ellipsoid, scratchCartographic); + up = Cartesian3.normalize(camera.positionWC, scratchPositionNormal); + direction = camera.directionWC; + height = camera.positionCartographic.height; + minimumHeight = 0.0; + maximumHeight = centerCartographic.height * 2.0; } else { - // if no ancestors are ready, traverse down and select ready tiles to minimize empty regions - descendantStack.push(original); - while (descendantStack.length > 0) { - var tile = descendantStack.pop(); - var children = tile.children; - var childrenLength = children.length; - for (var j = 0; j < childrenLength; ++j) { - var child = children[j]; - touch(tileset, child, outOfCore); - if (child.contentAvailable) { - child.selected = true; - child._finalResolution = true; - child._selectedFrame = frameState.frameNumber; - } - if (child._depth - original._depth < 2) { // prevent traversing too far - if (!child.contentAvailable || child.refine === Cesium3DTileRefine.ADD) { - descendantStack.push(child); - } - } - } - } - } - } - } - - var scratchStack = []; - var scratchStack2 = []; - - /** - * Traverse the tree while tiles are visible and check if their selected frame is the current frame. - * If so, add it to a selection queue. - * Tiles are sorted near to far so we can take advantage of early Z. - * Furthermore, this is a preorder traversal so children tiles are selected before ancestor tiles. - * - * The reason for the preorder traversal is so that tiles can easily be marked with their - * selection depth. A tile's _selectionDepth is its depth in the tree where all non-selected tiles are removed. - * This property is important for use in the stencil test because we want to render deeper tiles on top of their - * ancestors. If a tileset is very deep, the depth is unlikely to fit into the stencil buffer. - * - * We want to select children before their ancestors because there is no guarantee on the relationship between - * the children's z-depth and the ancestor's z-depth. We cannot rely on Z because we want the child to appear on top - * of ancestor regardless of true depth. The stencil tests used require children to be drawn first. @see {@link updateTiles} - * - * NOTE: this will no longer work when there is a chain of selected tiles that is longer than the size of the - * stencil buffer (usually 8 bits). In other words, the subset of the tree containing only selected tiles must be - * no deeper than 255. It is very, very unlikely this will cause a problem. - * - * NOTE: when the scene has inverted classification enabled, the stencil buffer will be masked to 4 bits. So, the - * selected tiles must be no deeper than 15. This is still very unlikely. - */ - function traverseAndSelect(tileset, root, frameState) { - var stack = scratchStack; - var ancestorStack = scratchStack2; - - var lastAncestor; - stack.push(root); - while (stack.length > 0 || ancestorStack.length > 0) { - if (ancestorStack.length > 0) { - var waitingTile = ancestorStack[ancestorStack.length - 1]; - if (waitingTile._stackLength === stack.length) { - ancestorStack.pop(); - if (waitingTile === lastAncestor) { - waitingTile._finalResolution = true; - } - selectTile(tileset, waitingTile, frameState); - continue; - } - } - - var tile = stack.pop(); - if (!defined(tile) || !isVisited(tile, frameState)) { - continue; - } - - var shouldSelect = tile.selected && tile._selectedFrame === frameState.frameNumber && tile.hasRenderableContent; - - var children = tile.children; - var childrenLength = children.length; - - children.sort(sortChildrenByDistanceToCamera); - - if (shouldSelect) { - if (tile.refine === Cesium3DTileRefine.ADD) { - tile._finalResolution = true; - selectTile(tileset, tile, frameState); - } else { - tile._selectionDepth = ancestorStack.length; - - if (tile._selectionDepth > 0) { - tileset._hasMixedContent = true; - } - - lastAncestor = tile; - - if (childrenLength === 0) { - tile._finalResolution = true; - selectTile(tileset, tile, frameState); - continue; - } - - ancestorStack.push(tile); - tile._stackLength = stack.length; - } - } - - for (var i = 0; i < childrenLength; ++i) { - var child = children[i]; - stack.push(child); - } - } - } - - function selectTile(tileset, tile, frameState) { - // There may also be a tight box around just the tile's contents, e.g., for a city, we may be - // zoomed into a neighborhood and can cull the skyscrapers in the root tile. - if (tile.contentAvailable && ( - (tile._visibilityPlaneMask === CullingVolume.MASK_INSIDE) || - (tile.contentVisibility(frameState) !== Intersect.OUTSIDE) - )) { - tileset._selectedTiles.push(tile); - - var tileContent = tile.content; - if (tileContent.featurePropertiesDirty) { - // A feature's property in this tile changed, the tile needs to be re-styled. - tileContent.featurePropertiesDirty = false; - tile.lastStyleTime = 0; // Force applying the style to this tile - tileset._selectedTilesToStyle.push(tile); - } else if ((tile._lastSelectedFrameNumber !== frameState.frameNumber - 1) || tile.lastStyleTime === 0) { - // Tile is newly selected; it is selected this frame, but was not selected last frame. - tileset._selectedTilesToStyle.push(tile); + // The tileset is defined in local coordinates (z-up) + var positionLocal = Matrix4.multiplyByPoint(transformLocal, camera.positionWC, scratchPosition); + up = Cartesian3.UNIT_Z; + direction = Matrix4.multiplyByPointAsVector(transformLocal, camera.directionWC, scratchDirection); + direction = Cartesian3.normalize(direction, direction); + height = positionLocal.z; + if (tileBoundingVolume instanceof TileOrientedBoundingBox) { + // Assuming z-up, the last component stores the half-height of the box + var boxHeight = root._header.boundingVolume.box[11]; + minimumHeight = centerLocal.z - boxHeight; + maximumHeight = centerLocal.z + boxHeight; + } else if (tileBoundingVolume instanceof TileBoundingSphere) { + var radius = boundingVolume.radius; + minimumHeight = centerLocal.z - radius; + maximumHeight = centerLocal.z + radius; + } } - tile._lastSelectedFrameNumber = frameState.frameNumber; } - } - // PERFORMANCE_IDEA: is it worth exploiting frame-to-frame coherence in the sort, i.e., the - // list of children are probably fully or mostly sorted unless the camera moved significantly? - function sortChildrenByDistanceToCamera(a, b) { - // Sort by farthest child first since this is going on a stack - if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { - return b._centerZDepth - a._centerZDepth; - } + // The range where the density starts to lessen. Start at the quarter height of the tileset. + var heightFalloff = tileset.dynamicScreenSpaceErrorHeightFalloff; + var heightClose = minimumHeight + (maximumHeight - minimumHeight) * heightFalloff; + var heightFar = maximumHeight; - return b._distanceToCamera - a._distanceToCamera; - } + var t = CesiumMath.clamp((height - heightClose) / (heightFar - heightClose), 0.0, 1.0); - var emptyArray = freezeObject([]); + // Increase density as the camera tilts towards the horizon + var dot = Math.abs(Cartesian3.dot(direction, up)); + var horizonFactor = 1.0 - dot; - function BaseTraversal() { - this.tileset = undefined; - this.frameState = undefined; - this.outOfCore = undefined; - this.stack = new ManagedArray(); - this.leaves = new ManagedArray(); - this.baseScreenSpaceError = undefined; - this.internalDFS = new InternalBaseTraversal(); + // Weaken the horizon factor as the camera height increases, implying the camera is further away from the tileset. + // The goal is to increase density for the "street view", not when viewing the tileset from a distance. + horizonFactor = horizonFactor * (1.0 - t); + + var density = tileset.dynamicScreenSpaceErrorDensity; + density *= horizonFactor; + + tileset._dynamicScreenSpaceErrorComputedDensity = density; } - BaseTraversal.prototype.execute = function(tileset, root, baseScreenSpaceError, frameState, outOfCore) { - this.tileset = tileset; - this.frameState = frameState; - this.outOfCore = outOfCore; - this.leaves.length = 0; - this.baseScreenSpaceError = Math.max(baseScreenSpaceError, this.tileset._maximumScreenSpaceError); - this.internalDFS.tileset = this.tileset; - this.internalDFS.frameState = this.frameState; - this.internalDFS.outOfCore = this.outOfCore; - this.internalDFS.baseScreenSpaceError = this.baseScreenSpaceError; - depthFirstSearch(root, this); - }; + function selectionHeuristic(tileset, ancestor, tile) { + var skipLevels = tileset._skipLevelOfDetail ? tileset.skipLevels : 0; + var skipScreenSpaceErrorFactor = tileset._skipLevelOfDetail ? tileset.skipScreenSpaceErrorFactor : 1.0; - BaseTraversal.prototype.visitStart = function(tile) { - if (!isVisited(tile, this.frameState)) { - visitTile(this.tileset, tile, this.frameState, this.outOfCore); - } - }; + return (ancestor !== tile && !tile.hasEmptyContent && !tileset.immediatelyLoadDesiredLevelOfDetail) && + (tile._screenSpaceError < ancestor._screenSpaceError / skipScreenSpaceErrorFactor) && + (tile._depth > ancestor._depth + skipLevels); + } - BaseTraversal.prototype.visitEnd = function(tile) { - tile._lastVisitedFrame = this.frameState.frameNumber; - }; + /////////////////////////////////////////////////////////////////////////// - BaseTraversal.prototype.getChildren = function(tile) { - var tileset = this.tileset; - var outOfCore = this.outOfCore; - var frameState = this.frameState; - if (!baseUpdateAndCheckChildren(tileset, tile, this.baseScreenSpaceError, frameState)) { - return emptyArray; + function requestContent(tileset, tile) { + if (tile.hasEmptyContent) { + return; } - var children = tile.children; - var childrenLength = children.length; - var allReady = true; - var replacementWithContent = tile.refine === Cesium3DTileRefine.REPLACE && tile.hasRenderableContent; - for (var i = 0; i < childrenLength; ++i) { - var child = children[i]; - loadTile(tileset, child, frameState, true); - touch(tileset, child, outOfCore); + var statistics = tileset._statistics; + var expired = tile.contentExpired; + var requested = tile.requestContent(); - // content cannot be replaced until all of the nearest descendants with content are all loaded - if (replacementWithContent) { - if (!child.hasEmptyContent) { - allReady = allReady && child.contentAvailable; - } else { - allReady = allReady && this.internalDFS.execute(child); - } - } + if (!requested) { + ++statistics.numberOfAttemptedRequests; + return; } - if (allReady) { - return children; + if (expired) { + if (tile.hasRenderableContent) { + statistics.decrementLoadCounts(tile.content); + --tileset._statistics.numberOfTilesWithContentReady; + } else if (tile.hasTilesetContent) { + destroySubtree(tileset, tile); + } } - return emptyArray; - }; + ++statistics.numberOfPendingRequests; - function baseUpdateAndCheckChildren(tileset, tile, baseScreenSpaceError, frameState) { - if (hasAdditiveContent(tile)) { - tileset._desiredTiles.push(tile); - } + var removeFunction = removeFromProcessingQueue(tileset, tile); + tile.contentReadyToProcessPromise.then(addToProcessingQueue(tileset, tile)); + tile.contentReadyPromise.then(function() { + removeFunction(); + tileset.tileLoad.raiseEvent(tile); + }).otherwise(function(error) { + removeFunction(); + var url = tile._contentResource.url; + var message = defined(error.message) ? error.message : error.toString(); + if (tileset.tileFailed.numberOfListeners > 0) { + tileset.tileFailed.raiseEvent({ + url : url, + message : message + }); + } else { + console.log('A 3D tile failed to load: ' + url); + console.log('Error: ' + message); + } + }); + } - // Stop traversal on the subtree since it will be destroyed - if (tile.hasTilesetContent && tile.contentExpired) { - return false; + function requestTiles(tileset, outOfCore) { + if (!outOfCore) { + return; } - - // stop traversal when we've attained the desired level of error - if (tile._screenSpaceError <= baseScreenSpaceError && !tile.hasTilesetContent) { - // update children so the leaf handler can check if any are visible for the children union bound optimization - updateChildren(tile, frameState); - return false; + var requestedTiles = tileset._requestedTiles; + var length = requestedTiles.length; + for (var i = 0; i < length; ++i) { + requestContent(tileset, requestedTiles[i]); } + } - var childrenVisibility = updateChildren(tile, frameState); - var showAdditive = tile.refine === Cesium3DTileRefine.ADD; - var showReplacement = tile.refine === Cesium3DTileRefine.REPLACE && (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME) !== 0; + function addToProcessingQueue(tileset, tile) { + return function() { + tileset._processingQueue.push(tile); - return showAdditive || showReplacement || tile.hasTilesetContent || !defined(tile._ancestorWithContent); + --tileset._statistics.numberOfPendingRequests; + ++tileset._statistics.numberOfTilesProcessing; + }; } - BaseTraversal.prototype.shouldVisit = function(tile) { - return isVisible(tile._visibilityPlaneMask); - }; - - BaseTraversal.prototype.leafHandler = function(tile) { - // if skipLevelOfDetail is off, leaves of the base traversal get pushed to tileset._desiredTiles. additive tiles have already been pushed - if (this.tileset.skipLevelOfDetail || !hasAdditiveContent(tile)) { - if (tile.refine === Cesium3DTileRefine.REPLACE && !childrenAreVisible(tile)) { - ++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion; + function removeFromProcessingQueue(tileset, tile) { + return function() { + var index = tileset._processingQueue.indexOf(tile); + if (index === -1) { + // Not in processing queue + // For example, when a url request fails and the ready promise is rejected + --tileset._statistics.numberOfPendingRequests; return; } - this.leaves.push(tile); - } - }; - - function InternalBaseTraversal() { - this.tileset = undefined; - this.frameState = undefined; - this.outOfCore = undefined; - this.baseScreenSpaceError = undefined; - this.stack = new ManagedArray(); - this.allLoaded = undefined; - } - - InternalBaseTraversal.prototype.execute = function(root) { - this.allLoaded = true; - depthFirstSearch(root, this); - return this.allLoaded; - }; - - InternalBaseTraversal.prototype.visitStart = function(tile) { - if (!isVisited(tile, this.frameState)) { - visitTile(this.tileset, tile, this.frameState, this.outOfCore); - } - }; - - InternalBaseTraversal.prototype.visitEnd = BaseTraversal.prototype.visitEnd; - - // Continue traversing until we have renderable content. We want the first descendants with content of the root to load - InternalBaseTraversal.prototype.shouldVisit = function(tile) { - return !tile.hasRenderableContent && isVisible(tile._visibilityPlaneMask); - }; - InternalBaseTraversal.prototype.getChildren = function(tile) { - var tileset = this.tileset; - var frameState = this.frameState; - var outOfCore = this.outOfCore; + // Remove from processing queue + tileset._processingQueue.splice(index, 1); + --tileset._statistics.numberOfTilesProcessing; - if (!baseUpdateAndCheckChildren(tileset, tile, this.baseScreenSpaceError, frameState)) { - return emptyArray; - } + if (tile.hasRenderableContent) { + // RESEARCH_IDEA: ability to unload tiles (without content) for an + // external tileset when all the tiles are unloaded. + tileset._statistics.incrementLoadCounts(tile.content); + ++tileset._statistics.numberOfTilesWithContentReady; - var children = tile.children; - var childrenLength = children.length; - for (var i = 0; i < childrenLength; ++i) { - var child = children[i]; - loadTile(tileset, child, frameState, true); - touch(tileset, child, outOfCore); - if (!tile.contentAvailable) { - this.allLoaded = false; + // Add to the tile cache. Previously expired tiles are already in the cache. + if (!defined(tile.replacementNode)) { + tile.replacementNode = tileset._replacementList.add(tile); + } } - } - return children; - }; - - InternalBaseTraversal.prototype.updateAndCheckChildren = BaseTraversal.prototype.updateAndCheckChildren; - - function SkipTraversal(options) { - this.tileset = undefined; - this.frameState = undefined; - this.outOfCore = undefined; - this.queue1 = new ManagedArray(); - this.queue2 = new ManagedArray(); - this.internalDFS = new InternalSkipTraversal(options.selectionHeuristic); - this.maxChildrenLength = 0; - this.scratchQueue = new ManagedArray(); + }; } - SkipTraversal.prototype.execute = function(tileset, root, frameState, outOfCore) { - this.tileset = tileset; - this.frameState = frameState; - this.outOfCore = outOfCore; - this.internalDFS.frameState = frameState; - this.internalDFS.outOfCore = outOfCore; - - this.maxChildrenLength = 0; - breadthFirstSearch(root, this); - this.queue1.length = 0; - this.queue2.length = 0; - this.scratchQueue.length = 0; - this.scratchQueue.trim(this.maxChildrenLength); - }; + function processTiles(tileset, frameState) { + var tiles = tileset._processingQueue; + var length = tiles.length; - SkipTraversal.prototype.visitStart = function(tile) { - if (!isVisited(tile, this.frameState)) { - visitTile(this.tileset, tile, this.frameState, this.outOfCore); + // Process tiles in the PROCESSING state so they will eventually move to the READY state. + // Traverse backwards in case a tile is removed as a result of calling process() + for (var i = length - 1; i >= 0; --i) { + tiles[i].process(tileset, frameState); } - }; + } - SkipTraversal.prototype.visitEnd = BaseTraversal.prototype.visitEnd; + /////////////////////////////////////////////////////////////////////////// - SkipTraversal.prototype.getChildren = function(tile) { - this.scratchQueue.length = 0; - this.internalDFS.execute(tile, this.scratchQueue); - this.maxChildrenLength = Math.max(this.maxChildrenLength, this.scratchQueue.length); - return this.scratchQueue; - }; + var scratchCartesian = new Cartesian3(); - SkipTraversal.prototype.leafHandler = function(tile) { - // additive tiles have already been pushed - if (!hasAdditiveContent(tile) && !isVisited(tile, this.frameState)) { - this.tileset._desiredTiles.push(tile); - } + var stringOptions = { + maximumFractionDigits : 3 }; - function InternalSkipTraversal(selectionHeuristic) { - this.selectionHeuristic = selectionHeuristic; - this.tileset = undefined; - this.frameState = undefined; - this.outOfCore = undefined; - this.root = undefined; - this.queue = undefined; - this.stack = new ManagedArray(); + function formatMemoryString(memorySizeInBytes) { + var memoryInMegabytes = memorySizeInBytes / 1048576; + if (memoryInMegabytes < 1.0) { + return memoryInMegabytes.toLocaleString(undefined, stringOptions); + } + return Math.round(memoryInMegabytes).toLocaleString(); } - InternalSkipTraversal.prototype.execute = function(root, queue) { - this.tileset = root._tileset; - this.root = root; - this.queue = queue; - depthFirstSearch(root, this); - }; + function computeTileLabelPosition(tile) { + var boundingVolume = tile._boundingVolume.boundingVolume; + var halfAxes = boundingVolume.halfAxes; + var radius = boundingVolume.radius; - InternalSkipTraversal.prototype.visitStart = function(tile) { - if (!isVisited(tile, this.frameState)) { - visitTile(this.tileset, tile, this.frameState, this.outOfCore); + var position = Cartesian3.clone(boundingVolume.center, scratchCartesian); + if (defined(halfAxes)) { + position.x += 0.75 * (halfAxes[0] + halfAxes[3] + halfAxes[6]); + position.y += 0.75 * (halfAxes[1] + halfAxes[4] + halfAxes[7]); + position.z += 0.75 * (halfAxes[2] + halfAxes[5] + halfAxes[8]); + } else if (defined(radius)) { + var normal = Cartesian3.normalize(boundingVolume.center, scratchCartesian); + normal = Cartesian3.multiplyByScalar(normal, 0.75 * radius, scratchCartesian); + position = Cartesian3.add(normal, boundingVolume.center, scratchCartesian); } - }; - - InternalSkipTraversal.prototype.visitEnd = BaseTraversal.prototype.visitEnd; + return position; + } - InternalSkipTraversal.prototype.getChildren = function(tile) { - var tileset = this.tileset; - var maximumScreenSpaceError = tileset._maximumScreenSpaceError; + function addTileDebugLabel(tile, tileset, position) { + var labelString = ''; + var attributes = 0; - // Stop traversal on the subtree since it will be destroyed - if (tile.hasTilesetContent && tile.contentExpired) { - return emptyArray; + if (tileset.debugShowGeometricError) { + labelString += '\nGeometric error: ' + tile.geometricError; + attributes++; } - if (!tile.hasTilesetContent) { - if (tile.refine === Cesium3DTileRefine.ADD) { - // Always load additive tiles - loadTile(tileset, tile, this.frameState, true); - if (hasAdditiveContent(tile)) { - tileset._desiredTiles.push(tile); - } - } + if (tileset.debugShowRenderingStatistics) { + labelString += '\nCommands: ' + tile.commandsLength; + attributes++; - // stop traversal when we've attained the desired level of error - if (tile._screenSpaceError <= maximumScreenSpaceError) { - updateChildren(tile, this.frameState); - return emptyArray; + // Don't display number of points or triangles if 0. + var numberOfPoints = tile.content.pointsLength; + if (numberOfPoints > 0) { + labelString += '\nPoints: ' + tile.content.pointsLength; + attributes++; } - // if we have reached the skipping threshold without any loaded ancestors, return empty so this tile is loaded - if ( - (!tile.hasEmptyContent && tile.contentUnloaded) && - defined(tile._ancestorWithLoadedContent) && - this.selectionHeuristic(tileset, tile._ancestorWithLoadedContent, tile)) { - updateChildren(tile, this.frameState); - return emptyArray; + var numberOfTriangles = tile.content.trianglesLength; + if (numberOfTriangles > 0) { + labelString += '\nTriangles: ' + tile.content.trianglesLength; + attributes++; } - } - var childrenVisibility = updateChildren(tile, this.frameState); - var showAdditive = tile.refine === Cesium3DTileRefine.ADD && tile._screenSpaceError > maximumScreenSpaceError; - var showReplacement = tile.refine === Cesium3DTileRefine.REPLACE && (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME) !== 0; + labelString += '\nFeatures: ' + tile.content.featuresLength; + attributes ++; + } - // at least one child is visible, but is not in request volume. the parent must be selected - if (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_NOT_IN_REQUEST_VOLUME && tile.refine === Cesium3DTileRefine.REPLACE) { - this.tileset._desiredTiles.push(tile); + if (tileset.debugShowMemoryUsage) { + labelString += '\nTexture Memory: ' + formatMemoryString(tile.content.texturesByteLength); + labelString += '\nGeometry Memory: ' + formatMemoryString(tile.content.geometryByteLength); + attributes += 2; } - if (showAdditive || showReplacement || tile.hasTilesetContent) { - var children = tile.children; - var childrenLength = children.length; - for (var i = 0; i < childrenLength; ++i) { - touch(tileset, children[i], this.outOfCore); - } - return children; + if (tileset.debugShowUrl) { + labelString += '\nUrl: ' + tile._header.content.url; + attributes++; } - return emptyArray; - }; + var newLabel = { + text : labelString.substring(1), + position : position, + font : (19-attributes) + 'px sans-serif', + showBackground : true, + disableDepthTestDistance : Number.POSITIVE_INFINITY + }; - InternalSkipTraversal.prototype.shouldVisit = function(tile) { - return isVisibleAndMeetsSSE(this.tileset, tile, this.frameState); - }; + return tileset._tileDebugLabels.add(newLabel); + } - InternalSkipTraversal.prototype.leafHandler = function(tile) { - if (tile !== this.root) { - if (tile.refine === Cesium3DTileRefine.REPLACE && !childrenAreVisible(tile)) { - ++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion; - return; + function updateTileDebugLabels(tileset, frameState) { + var selectedTiles = tileset._selectedTiles; + var length = selectedTiles.length; + tileset._tileDebugLabels.removeAll(); + + if (tileset.debugPickedTileLabelOnly) { + if (defined(tileset.debugPickedTile)) { + var position = (defined(tileset.debugPickPosition)) ? tileset.debugPickPosition : computeTileLabelPosition(tileset.debugPickedTile); + var label = addTileDebugLabel(tileset.debugPickedTile, tileset, position); + label.pixelOffset = new Cartesian2(15, -15); // Offset to avoid picking the label. } - if (!tile.hasEmptyContent) { - if (this.tileset.loadSiblings) { - var parent = tile.parent; - var tiles = parent.children; - var length = tiles.length; - for (var i = 0; i < length; ++i) { - loadTile(this.tileset, tiles[i], this.frameState, false); - touch(this.tileset, tiles[i], this.outOfCore); - } - } else { - loadTile(this.tileset, tile, this.frameState, true); - touch(this.tileset, tile, this.outOfCore); - } + } else { + for (var i = 0; i < length; ++i) { + var tile = selectedTiles[i]; + addTileDebugLabel(tile, tileset, computeTileLabelPosition(tile)); } - this.queue.push(tile); - } else if (!hasAdditiveContent(tile)) { - // additive tiles have already been pushed - this.tileset._desiredTiles.push(tile); - } - }; - - function updateChildren(tile, frameState) { - if (isVisited(tile, frameState)) { - return tile._childrenVisibility; } + tileset._tileDebugLabels.update(frameState); + } - var children = tile.children; + var stencilClearCommand = new ClearCommand({ + stencil : 0, + pass : Pass.CESIUM_3D_TILE + }); - updateTransforms(children, tile.computedTransform); - computeDistanceToCamera(children, frameState); + function updateTiles(tileset, frameState) { + tileset._styleEngine.applyStyle(tileset, frameState); - return computeChildrenVisibility(tile, frameState); - } + var statistics = tileset._statistics; + var commandList = frameState.commandList; + var numberOfInitialCommands = commandList.length; + var selectedTiles = tileset._selectedTiles; + var length = selectedTiles.length; + var tileVisible = tileset.tileVisible; + var i; - function isVisited(tile, frameState) { - // because the leaves of one tree traversal are the root of the subsequent traversal, avoid double visitation - return tile._lastVisitedFrame === frameState.frameNumber; - } + var bivariateVisibilityTest = tileset._skipLevelOfDetail && tileset._hasMixedContent && frameState.context.stencilBuffer && length > 0; - function visitTile(tileset, tile, frameState, outOfCore) { - ++tileset._statistics.visited; - tile.selected = false; - tile._finalResolution = false; - computeSSE(tile, frameState); - touch(tileset, tile, outOfCore); - tile.updateExpiration(); - tile._ancestorWithContent = undefined; - tile._ancestorWithLoadedContent = undefined; - var parent = tile.parent; - if (defined(parent)) { - var replace = parent.refine === Cesium3DTileRefine.REPLACE; - tile._ancestorWithContent = (replace && parent.hasRenderableContent) ? parent : parent._ancestorWithContent; - tile._ancestorWithLoadedContent = (replace && parent.hasRenderableContent && parent.contentAvailable) ? parent : parent._ancestorWithLoadedContent; - } - } + tileset._backfaceCommands.length = 0; - function touch(tileset, tile, outOfCore) { - if (!outOfCore) { - return; - } - var node = tile.replacementNode; - if (defined(node)) { - tileset._replacementList.splice(tileset._replacementSentinel, node); + if (bivariateVisibilityTest) { + commandList.push(stencilClearCommand); } - } - function computeSSE(tile, frameState) { - if (tile._screenSpaceErrorComputedFrame !== frameState.frameNumber) { - tile._screenSpaceErrorComputedFrame = frameState.frameNumber; - tile._screenSpaceError = getScreenSpaceError(tile._tileset, tile.geometricError, tile, frameState); + var lengthBeforeUpdate = commandList.length; + for (i = 0; i < length; ++i) { + var tile = selectedTiles[i]; + // tiles may get unloaded and destroyed between selection and update + if (tile.selected) { + // Raise the tileVisible event before update in case the tileVisible event + // handler makes changes that update needs to apply to WebGL resources + tileVisible.raiseEvent(tile); + tile.update(tileset, frameState); + statistics.incrementSelectionCounts(tile.content); + ++statistics.selected; + } } - } + var lengthAfterUpdate = commandList.length; + var addedCommandsLength = lengthAfterUpdate - lengthBeforeUpdate; - function checkAdditiveVisibility(tileset, tile, frameState) { - if (defined(tile.parent) && (tile.parent.refine === Cesium3DTileRefine.ADD)) { - return isVisibleAndMeetsSSE(tileset, tile, frameState); - } - return true; - } + tileset._backfaceCommands.trim(); - function loadTile(tileset, tile, frameState, checkVisibility) { - if ((tile.contentUnloaded || tile.contentExpired) && tile._requestedFrame !== frameState.frameNumber) { - if (!checkVisibility || checkAdditiveVisibility(tileset, tile, frameState)) { - tile._requestedFrame = frameState.frameNumber; - tileset._requestedTiles.push(tile); - } - } - } + if (bivariateVisibilityTest) { + /** + * Consider 'effective leaf' tiles as selected tiles that have no selected descendants. They may have children, + * but they are currently our effective leaves because they do not have selected descendants. These tiles + * are those where with tile._finalResolution === true. + * Let 'unresolved' tiles be those with tile._finalResolution === false. + * + * 1. Render just the backfaces of unresolved tiles in order to lay down z + * 2. Render all frontfaces wherever tile._selectionDepth > stencilBuffer. + * Replace stencilBuffer with tile._selectionDepth, when passing the z test. + * Because children are always drawn before ancestors {@link Cesium3DTilesetTraversal#traverseAndSelect}, + * this effectively draws children first and does not draw ancestors if a descendant has already + * been drawn at that pixel. + * Step 1 prevents child tiles from appearing on top when they are truly behind ancestor content. + * If they are behind the backfaces of the ancestor, then they will not be drawn. + * + * NOTE: Step 2 sometimes causes visual artifacts when backfacing child content has some faces that + * partially face the camera and are inside of the ancestor content. Because they are inside, they will + * not be culled by the depth writes in Step 1, and because they partially face the camera, the stencil tests + * will draw them on top of the ancestor content. + * + * NOTE: Because we always render backfaces of unresolved tiles, if the camera is looking at the backfaces + * of an object, they will always be drawn while loading, even if backface culling is enabled. + */ - function computeChildrenVisibility(tile, frameState) { - var flag = Cesium3DTileChildrenVisibility.NONE; - var children = tile.children; - var childrenLength = children.length; - var visibilityPlaneMask = tile._visibilityPlaneMask; - for (var k = 0; k < childrenLength; ++k) { - var child = children[k]; + var backfaceCommands = tileset._backfaceCommands.values; + var backfaceCommandsLength = backfaceCommands.length; - var visibilityMask = child.visibility(frameState, visibilityPlaneMask); + commandList.length += backfaceCommandsLength; - if (isVisible(visibilityMask)) { - flag |= Cesium3DTileChildrenVisibility.VISIBLE; + // copy commands to the back of the commandList + for (i = addedCommandsLength - 1; i >= 0; --i) { + commandList[lengthBeforeUpdate + backfaceCommandsLength + i] = commandList[lengthBeforeUpdate + i]; } - if (!child.insideViewerRequestVolume(frameState)) { - if (isVisible(visibilityMask)) { - flag |= Cesium3DTileChildrenVisibility.VISIBLE_NOT_IN_REQUEST_VOLUME; - } - visibilityMask = CullingVolume.MASK_OUTSIDE; - } else { - flag |= Cesium3DTileChildrenVisibility.IN_REQUEST_VOLUME; - if (isVisible(visibilityMask)) { - flag |= Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME; - } + // move backface commands to the front of the commandList + for (i = 0; i < backfaceCommandsLength; ++i) { + commandList[lengthBeforeUpdate + i] = backfaceCommands[i]; } - - child._visibilityPlaneMask = visibilityMask; } - tile._childrenVisibility = flag; - - return flag; - } + // Number of commands added by each update above + statistics.numberOfCommands = (commandList.length - numberOfInitialCommands); - function getScreenSpaceError(tileset, geometricError, tile, frameState) { - if (geometricError === 0.0) { - // Leaf tiles do not have any error so save the computation - return 0.0; + // Only run EDL if simple attenuation is on + if (tileset.pointCloudShading.attenuation && + tileset.pointCloudShading.eyeDomeLighting && + (addedCommandsLength > 0)) { + tileset._pointCloudEyeDomeLighting.update(frameState, numberOfInitialCommands, tileset); } - // Avoid divide by zero when viewer is inside the tile - var camera = frameState.camera; - var frustum = camera.frustum; - var context = frameState.context; - var height = context.drawingBufferHeight; - - var error; - if (frameState.mode === SceneMode.SCENE2D || frustum instanceof OrthographicFrustum) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + if (tileset.debugShowGeometricError || tileset.debugShowRenderingStatistics || tileset.debugShowMemoryUsage || tileset.debugShowUrl) { + if (!defined(tileset._tileDebugLabels)) { + tileset._tileDebugLabels = new LabelCollection(); } - var width = context.drawingBufferWidth; - var pixelSize = Math.max(frustum.top - frustum.bottom, frustum.right - frustum.left) / Math.max(width, height); - error = geometricError / pixelSize; + updateTileDebugLabels(tileset, frameState); } else { - var distance = Math.max(tile._distanceToCamera, CesiumMath.EPSILON7); - var sseDenominator = camera.frustum.sseDenominator; - error = (geometricError * height) / (distance * sseDenominator); + tileset._tileDebugLabels = tileset._tileDebugLabels && tileset._tileDebugLabels.destroy(); + } + } - if (tileset.dynamicScreenSpaceError) { - var density = tileset._dynamicScreenSpaceErrorComputedDensity; - var factor = tileset.dynamicScreenSpaceErrorFactor; - var dynamicError = CesiumMath.fog(distance, density) * factor; - error -= dynamicError; + var scratchStack = []; + + function destroySubtree(tileset, tile) { + var root = tile; + var statistics = tileset._statistics; + var stack = scratchStack; + stack.push(tile); + while (stack.length > 0) { + tile = stack.pop(); + var children = tile.children; + var length = children.length; + for (var i = 0; i < length; ++i) { + stack.push(children[i]); + } + if (tile !== root) { + unloadTileFromCache(tileset, tile); + tile.destroy(); + --statistics.numberOfTilesTotal; } } - - return error; + root.children = []; } - function computeDistanceToCamera(children, frameState) { - var length = children.length; - for (var i = 0; i < length; ++i) { - var child = children[i]; - child._distanceToCamera = child.distanceToTile(frameState); - child._centerZDepth = child.distanceToTileCenter(frameState); + function unloadTileFromCache(tileset, tile) { + var node = tile.replacementNode; + if (!defined(node)) { + return; } + + var statistics = tileset._statistics; + var replacementList = tileset._replacementList; + var tileUnload = tileset.tileUnload; + + tileUnload.raiseEvent(tile); + replacementList.remove(node); + statistics.decrementLoadCounts(tile.content); + --statistics.numberOfTilesWithContentReady; } - function updateTransforms(children, parentTransform) { - var length = children.length; - for (var i = 0; i < length; ++i) { - var child = children[i]; - child.updateTransform(parentTransform); + function unloadTiles(tileset) { + var trimTiles = tileset._trimTiles; + tileset._trimTiles = false; + + var replacementList = tileset._replacementList; + + var totalMemoryUsageInBytes = tileset.totalMemoryUsageInBytes; + var maximumMemoryUsageInBytes = tileset._maximumMemoryUsage * 1024 * 1024; + + // Traverse the list only to the sentinel since tiles/nodes to the + // right of the sentinel were used this frame. + // + // The sub-list to the left of the sentinel is ordered from LRU to MRU. + var sentinel = tileset._replacementSentinel; + var node = replacementList.head; + while ((node !== sentinel) && ((totalMemoryUsageInBytes > maximumMemoryUsageInBytes) || trimTiles)) { + var tile = node.item; + node = node.next; + unloadTileFromCache(tileset, tile); + tile.unloadContent(); + totalMemoryUsageInBytes = tileset.totalMemoryUsageInBytes; } } - function isVisible(visibilityPlaneMask) { - return visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE; - } + /** + * Unloads all tiles that weren't selected the previous frame. This can be used to + * explicitly manage the tile cache and reduce the total number of tiles loaded below + * {@link Cesium3DTileset#maximumMemoryUsage}. + * <p> + * Tile unloads occur at the next frame to keep all the WebGL delete calls + * within the render loop. + * </p> + */ + Cesium3DTileset.prototype.trimLoadedTiles = function() { + // Defer to next frame so WebGL delete calls happen inside the render loop + this._trimTiles = true; + }; - function isVisibleAndMeetsSSE(tileset, tile, frameState) { - var maximumScreenSpaceError = tileset._maximumScreenSpaceError; - var parent = tile.parent; - if (!defined(parent)) { - return isVisible(tile._visibilityPlaneMask); + /////////////////////////////////////////////////////////////////////////// + + function raiseLoadProgressEvent(tileset, frameState) { + var statistics = tileset._statistics; + var statisticsLast = tileset._statisticsLastColor; + var numberOfPendingRequests = statistics.numberOfPendingRequests; + var numberOfTilesProcessing = statistics.numberOfTilesProcessing; + var lastNumberOfPendingRequest = statisticsLast.numberOfPendingRequests; + var lastNumberOfTilesProcessing = statisticsLast.numberOfTilesProcessing; + + var progressChanged = (numberOfPendingRequests !== lastNumberOfPendingRequest) || (numberOfTilesProcessing !== lastNumberOfTilesProcessing); + + if (progressChanged) { + frameState.afterRender.push(function() { + tileset.loadProgress.raiseEvent(numberOfPendingRequests, numberOfTilesProcessing); + }); } - var showAdditive = parent.refine === Cesium3DTileRefine.ADD && parent._screenSpaceError > maximumScreenSpaceError; - return isVisible(tile._visibilityPlaneMask) && (!showAdditive || getScreenSpaceError(tileset, parent.geometricError, tile, frameState) > maximumScreenSpaceError); - } + tileset._tilesLoaded = (statistics.numberOfPendingRequests === 0) && (statistics.numberOfTilesProcessing === 0) && (statistics.numberOfAttemptedRequests === 0); - function childrenAreVisible(tile) { - // optimization does not apply for additive refinement - return tile.refine === Cesium3DTileRefine.ADD || tile.children.length === 0 || tile._childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE !== 0; + if (progressChanged && tileset._tilesLoaded) { + frameState.afterRender.push(function() { + tileset.allTilesLoaded.raiseEvent(); + }); + } } - function hasAdditiveContent(tile) { - return tile.refine === Cesium3DTileRefine.ADD && tile.hasRenderableContent; - } + /////////////////////////////////////////////////////////////////////////// - function depthFirstSearch(root, options) { - var stack = options.stack; + /** + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> + */ + Cesium3DTileset.prototype.update = function(frameState) { + if (frameState.mode === SceneMode.MORPHING) { + return; + } - if (defined(root) && (!defined(options.shouldVisit) || options.shouldVisit(root))) { - stack.push(root); + if (!this.show || !this.ready) { + return; } - var maxLength = 0; - while (stack.length > 0) { - maxLength = Math.max(maxLength, stack.length); + if (!defined(this._loadTimestamp)) { + this._loadTimestamp = JulianDate.clone(frameState.time); + } - var tile = stack.pop(); - options.visitStart(tile); - var children = options.getChildren(tile); - var isNativeArray = !defined(children.get); - var length = children.length; - for (var i = 0; i < length; ++i) { - var child = isNativeArray ? children[i] : children.get(i); + this._timeSinceLoad = Math.max(JulianDate.secondsDifference(frameState.time, this._loadTimestamp) * 1000, 0.0); - if (!defined(options.shouldVisit) || options.shouldVisit(child)) { - stack.push(child); - } - } + this._skipLevelOfDetail = this.skipLevelOfDetail && !defined(this._classificationType) && !this._disableSkipLevelOfDetail; - if (length === 0 && defined(options.leafHandler)) { - options.leafHandler(tile); - } - options.visitEnd(tile); - } + // Do not do out-of-core operations (new content requests, cache removal, + // process new tiles) during the pick pass. + var passes = frameState.passes; + var isPick = (passes.pick && !passes.render); + var outOfCore = !isPick; - stack.trim(maxLength); - } + var statistics = this._statistics; + statistics.clear(); - function breadthFirstSearch(root, options) { - var queue1 = options.queue1; - var queue2 = options.queue2; + if (outOfCore) { + processTiles(this, frameState); + } - if (defined(root) && (!defined(options.shouldVisit) || options.shouldVisit(root))) { - queue1.push(root); + if (this.dynamicScreenSpaceError) { + updateDynamicScreenSpaceError(this, frameState); } - var maxLength = 0; - while (queue1.length > 0) { - var length = queue1.length; - maxLength = Math.max(maxLength, length); + Cesium3DTilesetTraversal.selectTiles(this, frameState, outOfCore); + requestTiles(this, outOfCore); + updateTiles(this, frameState); - for (var i = 0; i < length; ++i) { - var tile = queue1.get(i); - options.visitStart(tile); - var children = options.getChildren(tile); - var isNativeArray = !defined(children.get); - var childrenLength = children.length; - for (var j = 0; j < childrenLength; ++j) { - var child = isNativeArray ? children[j] : children.get(j); + if (outOfCore) { + unloadTiles(this); + } - if (!defined(options.shouldVisit) || options.shouldVisit(child)) { - queue2.push(child); - } - } + // Events are raised (added to the afterRender queue) here since promises + // may resolve outside of the update loop that then raise events, e.g., + // model's readyPromise. + raiseLoadProgressEvent(this, frameState); - if (childrenLength === 0 && defined(options.leafHandler)) { - options.leafHandler(tile); - } - options.visitEnd(tile); - } + // Update last statistics + var statisticsLast = isPick ? this._statisticsLastPick : this._statisticsLastColor; + Cesium3DTilesetStatistics.clone(statistics, statisticsLast); + }; - queue1.length = 0; - var temp = queue1; - queue1 = queue2; - queue2 = temp; - options.queue1 = queue1; - options.queue2 = queue2; - } + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see Cesium3DTileset#destroy + */ + Cesium3DTileset.prototype.isDestroyed = function() { + return false; + }; - queue1.length = 0; - queue2.length = 0; + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * tileset = tileset && tileset.destroy(); + * + * @see Cesium3DTileset#isDestroyed + */ + Cesium3DTileset.prototype.destroy = function() { + // Destroy debug labels + this._tileDebugLabels = this._tileDebugLabels && this._tileDebugLabels.destroy(); - queue1.trim(maxLength); - queue2.trim(maxLength); - } + // Traverse the tree and destroy all tiles + if (defined(this._root)) { + var stack = scratchStack; + stack.push(this._root); - Cesium3DTilesetTraversal.selectTiles = selectTiles; + while (stack.length > 0) { + var tile = stack.pop(); + tile.destroy(); - Cesium3DTilesetTraversal.BaseTraversal = BaseTraversal; + var children = tile.children; + var length = children.length; + for (var i = 0; i < length; ++i) { + stack.push(children[i]); + } + } + } - Cesium3DTilesetTraversal.SkipTraversal = SkipTraversal; + this._root = undefined; + return destroyObject(this); + }; - return Cesium3DTilesetTraversal; + return Cesium3DTileset; }); -define('Scene/Cesium3DTileStyleEngine',[ +define('Scene/ConditionsExpression',[ + '../Core/clone', '../Core/defined', - '../Core/defineProperties' + '../Core/defineProperties', + './Expression' ], function( + clone, defined, - defineProperties) { + defineProperties, + Expression) { 'use strict'; /** - * @private + * An expression for a style applied to a {@link Cesium3DTileset}. + * <p> + * Evaluates a conditions expression defined using the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. + * </p> + * <p> + * Implements the {@link StyleExpression} interface. + * </p> + * + * @alias ConditionsExpression + * @constructor + * + * @param {Object} [conditionsExpression] The conditions expression defined using the 3D Tiles Styling language. + * @param {Object} [defines] Defines in the style. + * + * @example + * var expression = new Cesium.ConditionsExpression({ + * conditions : [ + * ['${Area} > 10, 'color("#FF0000")'], + * ['${id} !== "1"', 'color("#00FF00")'], + * ['true', 'color("#FFFFFF")'] + * ] + * }); + * expression.evaluateColor(frameState, feature, result); // returns a Cesium.Color object */ - function Cesium3DTileStyleEngine() { - this._style = undefined; // The style provided by the user - this._styleDirty = false; // true when the style is reassigned - this._lastStyleTime = 0; // The "time" when the last style was assigned + function ConditionsExpression(conditionsExpression, defines) { + this._conditionsExpression = clone(conditionsExpression, true); + this._conditions = conditionsExpression.conditions; + this._runtimeConditions = undefined; + + setRuntime(this, defines); } - defineProperties(Cesium3DTileStyleEngine.prototype, { - style : { + defineProperties(ConditionsExpression.prototype, { + /** + * Gets the conditions expression defined in the 3D Tiles Styling language. + * + * @memberof ConditionsExpression.prototype + * + * @type {Object} + * @readonly + * + * @default undefined + */ + conditionsExpression : { get : function() { - return this._style; - }, - set : function(value) { - this._style = value; - this._styleDirty = true; + return this._conditionsExpression; + } + } + }); + + function Statement(condition, expression) { + this.condition = condition; + this.expression = expression; + } + + function setRuntime(expression, defines) { + var runtimeConditions = []; + var conditions = expression._conditions; + if (!defined(conditions)) { + return; + } + var length = conditions.length; + for (var i = 0; i < length; ++i) { + var statement = conditions[i]; + var cond = String(statement[0]); + var condExpression = String(statement[1]); + runtimeConditions.push(new Statement( + new Expression(cond, defines), + new Expression(condExpression, defines) + )); + } + expression._runtimeConditions = runtimeConditions; + } + + /** + * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of + * the expression in the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} + * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript + * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code> + * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>, + * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is + * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. + * @param {Object} [result] The object onto which to store the result. + * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. + */ + ConditionsExpression.prototype.evaluate = function(frameState, feature, result) { + var conditions = this._runtimeConditions; + if (!defined(conditions)) { + return undefined; + } + var length = conditions.length; + for (var i = 0; i < length; ++i) { + var statement = conditions[i]; + if (statement.condition.evaluate(frameState, feature)) { + return statement.expression.evaluate(frameState, feature, result); } } - }); - - Cesium3DTileStyleEngine.prototype.makeDirty = function() { - this._styleDirty = true; }; - Cesium3DTileStyleEngine.prototype.applyStyle = function(tileset, frameState) { - if (!tileset.ready) { - return; + /** + * Evaluates the result of a Color expression, using the values defined by a feature. + * <p> + * This is equivalent to {@link ConditionsExpression#evaluate} but always returns a {@link Color} object. + * </p> + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. + * @param {Color} [result] The object in which to store the result + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + */ + ConditionsExpression.prototype.evaluateColor = function(frameState, feature, result) { + var conditions = this._runtimeConditions; + if (!defined(conditions)) { + return undefined; + } + var length = conditions.length; + for (var i = 0; i < length; ++i) { + var statement = conditions[i]; + if (statement.condition.evaluate(frameState, feature)) { + return statement.expression.evaluateColor(frameState, feature, result); + } } + }; - if (defined(this._style) && !this._style.ready) { - return; + /** + * Gets the shader function for this expression. + * Returns undefined if the shader function can't be generated from this expression. + * + * @param {String} functionName Name to give to the generated function. + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {String} returnType The return type of the generated function. + * + * @returns {String} The shader function. + * + * @private + */ + ConditionsExpression.prototype.getShaderFunction = function(functionName, attributePrefix, shaderState, returnType) { + var conditions = this._runtimeConditions; + if (!defined(conditions) || conditions.length === 0) { + return undefined; } - var styleDirty = this._styleDirty; + var shaderFunction = ''; + var length = conditions.length; + for (var i = 0; i < length; ++i) { + var statement = conditions[i]; - if (frameState.passes.render) { - // Don't reset until the color pass, e.g., for mouse-over picking - this._styleDirty = false; - } + var condition = statement.condition.getShaderExpression(attributePrefix, shaderState); + var expression = statement.expression.getShaderExpression(attributePrefix, shaderState); - if (styleDirty) { - // Increase "time", so the style is applied to all visible tiles - ++this._lastStyleTime; + // Build the if/else chain from the list of conditions + shaderFunction += + ' ' + ((i === 0) ? 'if' : 'else if') + ' (' + condition + ') \n' + + ' { \n' + + ' return ' + expression + '; \n' + + ' } \n'; } - var lastStyleTime = this._lastStyleTime; - var statistics = tileset._statistics; - - // If a new style was assigned, loop through all the visible tiles; otherwise, loop through - // only the tiles that are newly visible, i.e., they are visible this frame, but were not - // visible last frame. In many cases, the newly selected tiles list will be short or empty. - var tiles = styleDirty ? tileset._selectedTiles : tileset._selectedTilesToStyle; - // PERFORMANCE_IDEA: does mouse-over picking basically trash this? We need to style on - // pick, for example, because a feature's show may be false. + shaderFunction = returnType + ' ' + functionName + '() \n' + + '{ \n' + + shaderFunction + + ' return ' + returnType + '(1.0); \n' + // Return a default value if no conditions are met + '} \n'; - var length = tiles.length; - for (var i = 0; i < length; ++i) { - var tile = tiles[i]; - if (tile.selected && (tile.lastStyleTime !== lastStyleTime)) { - // Apply the style to this tile if it wasn't already applied because: - // 1) the user assigned a new style to the tileset - // 2) this tile is now visible, but it wasn't visible when the style was first assigned - var content = tile.content; - tile.lastStyleTime = lastStyleTime; - content.applyStyle(frameState, this._style); - statistics.numberOfFeaturesStyled += content.featuresLength; - ++statistics.numberOfTilesStyled; - } - } + return shaderFunction; }; - return Cesium3DTileStyleEngine; + return ConditionsExpression; }); -define('Scene/Cesium3DTileset',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/Check', +define('Scene/Cesium3DTileStyle',[ + '../Core/clone', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/DoublyLinkedList', - '../Core/Event', - '../Core/getBaseUri', - '../Core/getExtensionFromUri', - '../Core/isDataUri', - '../Core/joinUrls', - '../Core/JulianDate', - '../Core/loadJson', - '../Core/ManagedArray', - '../Core/Math', - '../Core/Matrix4', - '../Core/RuntimeError', - '../Renderer/ClearCommand', - '../Renderer/Pass', + '../Core/Resource', '../ThirdParty/when', - './Axis', - './Cesium3DTile', - './Cesium3DTileColorBlendMode', - './Cesium3DTileOptimizations', - './Cesium3DTilesetStatistics', - './Cesium3DTilesetTraversal', - './Cesium3DTileStyleEngine', - './LabelCollection', - './SceneMode', - './ShadowMode', - './TileBoundingRegion', - './TileBoundingSphere', - './TileOrientedBoundingBox' + './ConditionsExpression', + './Expression' ], function( - Cartesian2, - Cartesian3, - Cartographic, - Check, + clone, defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - DoublyLinkedList, - Event, - getBaseUri, - getExtensionFromUri, - isDataUri, - joinUrls, - JulianDate, - loadJson, - ManagedArray, - CesiumMath, - Matrix4, - RuntimeError, - ClearCommand, - Pass, + Resource, when, - Axis, - Cesium3DTile, - Cesium3DTileColorBlendMode, - Cesium3DTileOptimizations, - Cesium3DTilesetStatistics, - Cesium3DTilesetTraversal, - Cesium3DTileStyleEngine, - LabelCollection, - SceneMode, - ShadowMode, - TileBoundingRegion, - TileBoundingSphere, - TileOrientedBoundingBox) { + ConditionsExpression, + Expression) { 'use strict'; /** - * A {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles tileset}, - * used for streaming massive heterogeneous 3D geospatial datasets. + * A style that is applied to a {@link Cesium3DTileset}. + * <p> + * Evaluates an expression defined using the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. + * </p> * - * @alias Cesium3DTileset + * @alias Cesium3DTileStyle * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url to a tileset.json file or to a directory containing a tileset.json file. - * @param {Boolean} [options.show=true] Determines if the tileset will be shown. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. - * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from each light source. - * @param {Number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. - * @param {Number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. - * @param {Boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. - * @param {Boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. - * @param {Number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. - * @param {Number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. - * @param {Number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. - * @param {Boolean} [options.skipLevelOfDetail=true] Optimization option. Determines if level of detail skipping should be applied during the traversal. - * @param {Number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. - * @param {Number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. - * @param {Number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. - * @param {Boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. - * @param {Boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. - * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. Clipping planes are not currently supported in Internet Explorer. - * @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. - * @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. - * @param {Boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. - * @param {Boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. - * @param {Boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. - * @param {Boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. - * @param {Boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. - * @param {Boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. - * @param {Boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. - * - * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. See {@link https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status} - * - * @example - * var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle' - * })); + * @param {Resource|String|Object} [style] The url of a style or an object defining a style. * * @example - * // Common setting for the skipLevelOfDetail optimization - * var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle', - * skipLevelOfDetail : true, - * baseScreenSpaceError : 1024, - * skipScreenSpaceErrorFactor : 16, - * skipLevels : 1, - * immediatelyLoadDesiredLevelOfDetail : false, - * loadSiblings : false, - * cullWithChildrenBounds : true - * })); + * tileset.style = new Cesium.Cesium3DTileStyle({ + * color : { + * conditions : [ + * ['${Height} >= 100', 'color("purple", 0.5)'], + * ['${Height} >= 50', 'color("red")'], + * ['true', 'color("blue")'] + * ] + * }, + * show : '${Height} > 0', + * meta : { + * description : '"Building id ${id} has height ${Height}."' + * } + * }); * * @example - * // Common settings for the dynamicScreenSpaceError optimization - * var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle', - * dynamicScreenSpaceError : true, - * dynamicScreenSpaceErrorDensity : 0.00278, - * dynamicScreenSpaceErrorFactor : 4.0, - * dynamicScreenSpaceErrorHeightFalloff : 0.25 - * })); + * tileset.style = new Cesium.Cesium3DTileStyle({ + * color : 'vec4(${Temperature})', + * pointSize : '${Temperature} * 2.0' + * }); * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/README.md|3D Tiles specification} + * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} */ - function Cesium3DTileset(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function Cesium3DTileStyle(style) { + this._style = undefined; + this._ready = false; - var url = options.url; + this._show = undefined; + this._color = undefined; + this._pointSize = undefined; + this._pointOutlineColor = undefined; + this._pointOutlineWidth = undefined; + this._labelColor = undefined; + this._labelOutlineColor = undefined; + this._labelOutlineWidth = undefined; + this._font = undefined; + this._labelStyle = undefined; + this._labelText = undefined; + this._backgroundColor = undefined; + this._backgroundPadding = undefined; + this._backgroundEnabled = undefined; + this._scaleByDistance = undefined; + this._translucencyByDistance = undefined; + this._distanceDisplayCondition = undefined; + this._heightOffset = undefined; + this._anchorLineEnabled = undefined; + this._anchorLineColor = undefined; + this._image = undefined; + this._disableDepthTestDistance = undefined; + this._horizontalOrigin = undefined; + this._verticalOrigin = undefined; + this._labelHorizontalOrigin = undefined; + this._labelVerticalOrigin = undefined; + this._meta = undefined; - Check.typeOf.string('options.url', url); - - var tilesetUrl; - var basePath; + this._colorShaderFunction = undefined; + this._showShaderFunction = undefined; + this._pointSizeShaderFunction = undefined; + this._colorShaderFunctionReady = false; + this._showShaderFunctionReady = false; + this._pointSizeShaderFunctionReady = false; - if (getExtensionFromUri(url) === 'json') { - tilesetUrl = url; - basePath = getBaseUri(url, true); - } else if (isDataUri(url)) { - tilesetUrl = url; - basePath = ''; + this._colorShaderTranslucent = false; + + var promise; + if (typeof style === 'string' || style instanceof Resource) { + var resource = Resource.createIfNeeded(style); + promise = resource.fetchJson(style); } else { - basePath = url; - tilesetUrl = joinUrls(basePath, 'tileset.json'); + promise = when.resolve(style); } - this._url = url; - this._basePath = basePath; - this._tilesetUrl = tilesetUrl; - this._root = undefined; - this._asset = undefined; // Metadata for the entire tileset - this._properties = undefined; // Metadata for per-model/point/etc properties - this._geometricError = undefined; // Geometric error when the tree is not rendered at all - this._gltfUpAxis = undefined; - this._processingQueue = []; - this._selectedTiles = []; - this._requestedTiles = []; - this._desiredTiles = new ManagedArray(); - this._selectedTilesToStyle = []; - this._loadTimestamp = undefined; - this._timeSinceLoad = 0.0; - - var replacementList = new DoublyLinkedList(); - - // [head, sentinel) -> tiles that weren't selected this frame and may be replaced - // (sentinel, tail] -> tiles that were selected this frame - this._replacementList = replacementList; // Tiles with content loaded. For cache management. - this._replacementSentinel = replacementList.add(); - this._trimTiles = false; - - this._cullWithChildrenBounds = defaultValue(options.cullWithChildrenBounds, true); - - this._hasMixedContent = false; - - this._baseTraversal = new Cesium3DTilesetTraversal.BaseTraversal(); - this._skipTraversal = new Cesium3DTilesetTraversal.SkipTraversal({ - selectionHeuristic : selectionHeuristic + var that = this; + this._readyPromise = promise.then(function(styleJson) { + setup(that, styleJson); + return that; }); + } - this._backfaceCommands = new ManagedArray(); - - this._maximumScreenSpaceError = defaultValue(options.maximumScreenSpaceError, 16); - this._maximumMemoryUsage = defaultValue(options.maximumMemoryUsage, 512); + function setup(that, styleJson) { + that._style = clone(styleJson, true); - this._styleEngine = new Cesium3DTileStyleEngine(); + styleJson = defaultValue(styleJson, defaultValue.EMPTY_OBJECT); - this._modelMatrix = defined(options.modelMatrix) ? Matrix4.clone(options.modelMatrix) : Matrix4.clone(Matrix4.IDENTITY); + that.show = styleJson.show; + that.color = styleJson.color; + that.pointSize = styleJson.pointSize; + that.pointOutlineColor = styleJson.pointOutlineColor; + that.pointOutlineWidth = styleJson.pointOutlineWidth; + that.labelColor = styleJson.labelColor; + that.labelOutlineColor = styleJson.labelOutlineColor; + that.labelOutlineWidth = styleJson.labelOutlineWidth; + that.labelStyle = styleJson.labelStyle; + that.font = styleJson.font; + that.labelText = styleJson.labelText; + that.backgroundColor = styleJson.backgroundColor; + that.backgroundPadding = styleJson.backgroundPadding; + that.backgroundEnabled = styleJson.backgroundEnabled; + that.scaleByDistance = styleJson.scaleByDistance; + that.translucencyByDistance = styleJson.translucencyByDistance; + that.distanceDisplayCondition = styleJson.distanceDisplayCondition; + that.heightOffset = styleJson.heightOffset; + that.anchorLineEnabled = styleJson.anchorLineEnabled; + that.anchorLineColor = styleJson.anchorLineColor; + that.image = styleJson.image; + that.disableDepthTestDistance = styleJson.disableDepthTestDistance; + that.horizontalOrigin = styleJson.horizontalOrigin; + that.verticalOrigin = styleJson.verticalOrigin; + that.labelHorizontalOrigin = styleJson.labelHorizontalOrigin; + that.labelVerticalOrigin = styleJson.labelVerticalOrigin; - this._statistics = new Cesium3DTilesetStatistics(); - this._statisticsLastColor = new Cesium3DTilesetStatistics(); - this._statisticsLastPick = new Cesium3DTilesetStatistics(); + var meta = {}; + if (defined(styleJson.meta)) { + var defines = styleJson.defines; + var metaJson = defaultValue(styleJson.meta, defaultValue.EMPTY_OBJECT); + for (var property in metaJson) { + if (metaJson.hasOwnProperty(property)) { + meta[property] = new Expression(metaJson[property], defines); + } + } + } - this._tilesLoaded = false; + that._meta = meta; - this._tileDebugLabels = undefined; + that._ready = true; + } - this._readyPromise = when.defer(); + function getExpression(tileStyle, value) { + var defines = defaultValue(tileStyle._style, defaultValue.EMPTY_OBJECT).defines; + if (!defined(value)) { + return undefined; + } else if (typeof value === 'boolean' || typeof value === 'number') { + return new Expression(String(value)); + } else if (typeof value === 'string') { + return new Expression(value, defines); + } else if (defined(value.conditions)) { + return new ConditionsExpression(value, defines); + } + return value; + } + defineProperties(Cesium3DTileStyle.prototype, { /** - * Optimization option. Whether the tileset should refine based on a dynamic screen space error. Tiles that are further - * away will be rendered with lower detail than closer tiles. This improves performance by rendering fewer - * tiles and making less requests, but may result in a slight drop in visual quality for tiles in the distance. - * The algorithm is biased towards "street views" where the camera is close to the ground plane of the tileset and looking - * at the horizon. In addition results are more accurate for tightly fitting bounding volumes like box and region. + * Gets the object defining the style using the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. * - * @type {Boolean} - * @default false - */ - this.dynamicScreenSpaceError = defaultValue(options.dynamicScreenSpaceError, false); - - /** - * A scalar that determines the density used to adjust the dynamic screen space error, similar to {@link Fog}. Increasing this - * value has the effect of increasing the maximum screen space error for all tiles, but in a non-linear fashion. - * The error starts at 0.0 and increases exponentially until a midpoint is reached, and then approaches 1.0 asymptotically. - * This has the effect of keeping high detail in the closer tiles and lower detail in the further tiles, with all tiles - * beyond a certain distance all roughly having an error of 1.0. - * <p> - * The dynamic error is in the range [0.0, 1.0) and is multiplied by <code>dynamicScreenSpaceErrorFactor</code> to produce the - * final dynamic error. This dynamic error is then subtracted from the tile's actual screen space error. - * </p> - * <p> - * Increasing <code>dynamicScreenSpaceErrorDensity</code> has the effect of moving the error midpoint closer to the camera. - * It is analogous to moving fog closer to the camera. - * </p> + * @memberof Cesium3DTileStyle.prototype * - * @type {Number} - * @default 0.00278 - */ - this.dynamicScreenSpaceErrorDensity = 0.00278; - - /** - * A factor used to increase the screen space error of tiles for dynamic screen space error. As this value increases less tiles - * are requested for rendering and tiles in the distance will have lower detail. If set to zero, the feature will be disabled. + * @type {Object} + * @readonly * - * @type {Number} - * @default 4.0 - */ - this.dynamicScreenSpaceErrorFactor = 4.0; - - /** - * A ratio of the tileset's height at which the density starts to falloff. If the camera is below this height the - * full computed density is applied, otherwise the density falls off. This has the effect of higher density at - * street level views. - * <p> - * Valid values are between 0.0 and 1.0. - * </p> + * @default undefined * - * @type {Number} - * @default 0.25 + * @exception {DeveloperError} The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true. */ - this.dynamicScreenSpaceErrorHeightFalloff = 0.25; - - this._dynamicScreenSpaceErrorComputedDensity = 0.0; // Updated based on the camera position and direction + style : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._style; + } + }, /** - * Determines whether the tileset casts or receives shadows from each light source. - * <p> - * Enabling shadows has a performance impact. A tileset that casts shadows must be rendered twice, once from the camera and again from the light's point of view. - * </p> - * <p> - * Shadows are rendered only when {@link Viewer#shadows} is <code>true</code>. - * </p> + * When <code>true</code>, the style is ready and its expressions can be evaluated. When + * a style is constructed with an object, as opposed to a url, this is <code>true</code> immediately. * - * @type {ShadowMode} - * @default ShadowMode.ENABLED - */ - this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); - - /** - * Determines if the tileset will be shown. + * @memberof Cesium3DTileStyle.prototype * * @type {Boolean} - * @default true - */ - this.show = defaultValue(options.show, true); - - /** - * Defines how per-feature colors set from the Cesium API or declarative styling blend with the source colors from - * the original feature, e.g. glTF material or per-point color in the tile. + * @readonly * - * @type {Cesium3DTileColorBlendMode} - * @default Cesium3DTileColorBlendMode.HIGHLIGHT + * @default false */ - this.colorBlendMode = Cesium3DTileColorBlendMode.HIGHLIGHT; + ready : { + get : function() { + return this._ready; + } + }, /** - * Defines the value used to linearly interpolate between the source color and feature color when the {@link Cesium3DTileset#colorBlendMode} is <code>MIX</code>. - * A value of 0.0 results in the source color while a value of 1.0 results in the feature color, with any value in-between - * resulting in a mix of the source color and feature color. + * Gets the promise that will be resolved when the the style is ready and its expressions can be evaluated. * - * @type {Number} - * @default 0.5 + * @memberof Cesium3DTileStyle.prototype + * + * @type {Promise.<Cesium3DTileStyle>} + * @readonly */ - this.colorBlendAmount = 0.5; + readyPromise : { + get : function() { + return this._readyPromise; + } + }, /** - * The event fired to indicate progress of loading new tiles. This event is fired when a new tile - * is requested, when a requested tile is finished downloading, and when a downloaded tile has been - * processed and is ready to render. - * <p> - * The number of pending tile requests, <code>numberOfPendingRequests</code>, and number of tiles - * processing, <code>numberOfTilesProcessing</code> are passed to the event listener. - * </p> + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>show</code> property. Alternatively a boolean, string, or object defining a show style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * This event is fired at the end of the frame after the scene is rendered. + * The expression must return or convert to a <code>Boolean</code>. * </p> * - * @type {Event} - * @default new Event() + * @memberof Cesium3DTileStyle.prototype * - * @example - * tileset.loadProgress.addEventListener(function(numberOfPendingRequests, numberOfTilesProcessing) { - * if ((numberOfPendingRequests === 0) && (numberOfTilesProcessing === 0)) { - * console.log('Stopped loading'); - * return; - * } + * @type {StyleExpression} * - * console.log('Loading: requests: ' + numberOfPendingRequests + ', processing: ' + numberOfTilesProcessing); + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @example + * var style = new Cesium3DTileStyle({ + * show : '(regExp("^Chest").test(${County})) && (${YearBuilt} >= 1970)' * }); - */ - this.loadProgress = new Event(); - - /** - * The event fired to indicate that all tiles that meet the screen space error this frame are loaded. The tileset - * is completely loaded for this view. - * <p> - * This event is fired at the end of the frame after the scene is rendered. - * </p> + * style.show.evaluate(frameState, feature); // returns true or false depending on the feature's properties * - * @type {Event} - * @default new Event() + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a custom function + * style.show = { + * evaluate : function(frameState, feature) { + * return true; + * } + * }; * * @example - * tileset.allTilesLoaded.addEventListener(function() { - * console.log('All tiles are loaded'); - * }); + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a boolean + * style.show = true; + * }; * - * @see Cesium3DTileset#tilesLoaded + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a string + * style.show = '${Height} > 0'; + * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a condition + * style.show = { + * conditions: [ + * ['${height} > 2', 'false'], + * ['true', 'true'] + * ]; + * }; */ - this.allTilesLoaded = new Event(); + show : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._show; + }, + set : function(value) { + this._show = getExpression(this, value); + this._showShaderFunctionReady = false; + } + }, /** - * The event fired to indicate that a tile's content was loaded. - * <p> - * The loaded {@link Cesium3DTile} is passed to the event listener. - * </p> + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>color</code> property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * This event is fired during the tileset traversal while the frame is being rendered - * so that updates to the tile take effect in the same frame. Do not create or modify - * Cesium entities or primitives during the event listener. + * The expression must return a <code>Color</code>. * </p> * - * @type {Event} - * @default new Event() + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. * * @example - * tileset.tileLoad.addEventListener(function(tile) { - * console.log('A tile was loaded.'); + * var style = new Cesium3DTileStyle({ + * color : '(${Temperature} > 90) ? color("red") : color("white")' * }); - */ - this.tileLoad = new Event(); - - /** - * The event fired to indicate that a tile's content was unloaded. - * <p> - * The unloaded {@link Cesium3DTile} is passed to the event listener. - * </p> - * <p> - * This event is fired immediately before the tile's content is unloaded while the frame is being - * rendered so that the event listener has access to the tile's content. Do not create - * or modify Cesium entities or primitives during the event listener. - * </p> + * style.color.evaluateColor(frameState, feature, result); // returns a Cesium.Color object * - * @type {Event} - * @default new Event() + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a custom function + * style.color = { + * evaluateColor : function(frameState, feature, result) { + * return Cesium.Color.clone(Cesium.Color.WHITE, result); + * } + * }; * * @example - * tileset.tileUnload.addEventListener(function(tile) { - * console.log('A tile was unloaded from the cache.'); - * }); + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a string + * style.color = 'color("blue")'; * - * @see Cesium3DTileset#maximumMemoryUsage - * @see Cesium3DTileset#trimLoadedTiles + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a condition + * style.color = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ - this.tileUnload = new Event(); + color : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._color; + }, + set : function(value) { + this._color = getExpression(this, value); + this._colorShaderFunctionReady = false; + } + }, /** - * This event fires once for each visible tile in a frame. This can be used to manually - * style a tileset. - * <p> - * The visible {@link Cesium3DTile} is passed to the event listener. - * </p> + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>pointSize</code> property. Alternatively a string or object defining a point size style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * This event is fired during the tileset traversal while the frame is being rendered - * so that updates to the tile take effect in the same frame. Do not create or modify - * Cesium entities or primitives during the event listener. + * The expression must return a <code>Number</code>. * </p> * - * @type {Event} - * @default new Event() + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. * * @example - * tileset.tileVisible.addEventListener(function(tile) { - * if (tile.content instanceof Cesium.Batched3DModel3DTileContent) { - * console.log('A Batched 3D Model tile is visible.'); - * } + * var style = new Cesium3DTileStyle({ + * pointSize : '(${Temperature} > 90) ? 2.0 : 1.0' * }); + * style.pointSize.evaluate(frameState, feature); // returns a Number * * @example - * // Apply a red style and then manually set random colors for every other feature when the tile becomes visible. - * tileset.style = new Cesium.Cesium3DTileStyle({ - * color : 'color("red")' - * }); - * tileset.tileVisible.addEventListener(function(tile) { - * var content = tile.content; - * var featuresLength = content.featuresLength; - * for (var i = 0; i < featuresLength; i+=2) { - * content.getFeature(i).color = Cesium.Color.fromRandom(); + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a custom function + * style.pointSize = { + * evaluate : function(frameState, feature) { + * return 1.0; * } - * }); - */ - this.tileVisible = new Event(); - - /** - * Optimization option. Determines if level of detail skipping should be applied during the traversal. - * <p> - * The common strategy for replacement-refinement traversal is to store all levels of the tree in memory and require - * all children to be loaded before the parent can refine. With this optimization levels of the tree can be skipped - * entirely and children can be rendered alongside their parents. The tileset requires significantly less memory when - * using this optimization. - * </p> + * }; * - * @type {Boolean} - * @default true - */ - this.skipLevelOfDetail = defaultValue(options.skipLevelOfDetail, true); - - /** - * The screen space error that must be reached before skipping levels of detail. - * <p> - * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. - * </p> + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a number + * style.pointSize = 1.0; * - * @type {Number} - * @default 1024 - */ - this.baseScreenSpaceError = defaultValue(options.baseScreenSpaceError, 1024); - - /** - * Multiplier defining the minimum screen space error to skip. - * For example, if a tile has screen space error of 100, no tiles will be loaded unless they - * are leaves or have a screen space error <code><= 100 / skipScreenSpaceErrorFactor</code>. - * <p> - * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. - * </p> + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a string + * style.pointSize = '${height} / 10'; * - * @type {Number} - * @default 16 + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a condition + * style.pointSize = { + * conditions : [ + * ['${height} > 2', '1.0'], + * ['true', '2.0'] + * ] + * }; */ - this.skipScreenSpaceErrorFactor = defaultValue(options.skipScreenSpaceErrorFactor, 16); + pointSize : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._pointSize; + }, + set : function(value) { + this._pointSize = getExpression(this, value); + this._pointSizeShaderFunctionReady = false; + } + }, /** - * Constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. - * For example, if a tile is level 1, no tiles will be loaded unless they are at level greater than 2. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>pointOutlineColor</code> property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * The expression must return a <code>Color</code>. * </p> * - * @type {Number} - * @default 1 - */ - this.skipLevels = defaultValue(options.skipLevels, 1); - - /** - * When true, only tiles that meet the maximum screen space error will ever be downloaded. - * Skipping factors are ignored and just the desired tiles are loaded. - * <p> - * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. - * </p> + * @memberof Cesium3DTileStyle.prototype * - * @type {Boolean} - * @default false + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointOutlineColor expression with a string + * style.pointOutlineColor = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointOutlineColor expression with a condition + * style.pointOutlineColor = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ - this.immediatelyLoadDesiredLevelOfDetail = defaultValue(options.immediatelyLoadDesiredLevelOfDetail, false); + pointOutlineColor : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._pointOutlineColor; + }, + set : function(value) { + this._pointOutlineColor = getExpression(this, value); + } + }, /** - * Determines whether siblings of visible tiles are always downloaded during traversal. - * This may be useful for ensuring that tiles are already available when the viewer turns left/right. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>pointOutlineWidth</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. + * The expression must return a <code>Number</code>. * </p> * - * @type {Boolean} - * @default false - */ - this.loadSiblings = defaultValue(options.loadSiblings, false); - - /** - * The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. Clipping planes are not currently supported in Internet Explorer. + * @memberof Cesium3DTileStyle.prototype * - * @type {ClippingPlaneCollection} + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointOutlineWidth expression with a string + * style.pointOutlineWidth = '5'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointOutlineWidth expression with a condition + * style.pointOutlineWidth = { + * conditions : [ + * ['${height} > 2', '5'], + * ['true', '0'] + * ] + * }; */ - this.clippingPlanes = options.clippingPlanes; + pointOutlineWidth : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._pointOutlineWidth; + }, + set : function(value) { + this._pointOutlineWidth = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>labelColor</code> property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * Determines if only the tiles from last frame should be used for rendering. This - * effectively "freezes" the tileset to the previous frame so it is possible to zoom - * out and see what was rendered. + * The expression must return a <code>Color</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelColor expression with a string + * style.labelColor = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelColor expression with a condition + * style.labelColor = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ - this.debugFreezeFrame = defaultValue(options.debugFreezeFrame, false); + labelColor : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._labelColor; + }, + set : function(value) { + this._labelColor = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>labelOutlineColor</code> property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, assigns a random color to each tile. This is useful for visualizing - * what features belong to what tiles, especially with additive refinement where features - * from parent tiles may be interleaved with features from child tiles. + * The expression must return a <code>Color</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelOutlineColor expression with a string + * style.labelOutlineColor = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelOutlineColor expression with a condition + * style.labelOutlineColor = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ - this.debugColorizeTiles = defaultValue(options.debugColorizeTiles, false); + labelOutlineColor : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._labelOutlineColor; + }, + set : function(value) { + this._labelOutlineColor = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>labelOutlineWidth</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, renders each tile's content as a wireframe. + * The expression must return a <code>Number</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelOutlineWidth expression with a string + * style.labelOutlineWidth = '5'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelOutlineWidth expression with a condition + * style.labelOutlineWidth = { + * conditions : [ + * ['${height} > 2', '5'], + * ['true', '0'] + * ] + * }; */ - this.debugWireframe = defaultValue(options.debugWireframe, false); + labelOutlineWidth : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._labelOutlineWidth; + }, + set : function(value) { + this._labelOutlineWidth = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>font</code> property. Alternatively a string or object defining a string style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, renders the bounding volume for each visible tile. The bounding volume is - * white if the tile has a content bounding volume; otherwise, it is red. Tiles that don't meet the - * screen space error and are still refining to their descendants are yellow. + * The expression must return a <code>String</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium3DTileStyle({ + * font : '(${Temperature} > 90) ? "30px Helvetica" : "24px Helvetica"' + * }); + * style.font.evaluate(frameState, feature); // returns a String + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override font expression with a custom function + * style.font = { + * evaluate : function(frameState, feature) { + * return '24px Helvetica'; + * } + * }; */ - this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + font : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._font; + }, + set : function(value) { + this._font = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>label style</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, renders the bounding volume for each visible tile's content. The bounding volume is - * blue if the tile has a content bounding volume; otherwise it is red. + * The expression must return a <code>LabelStyle</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium3DTileStyle({ + * labelStyle : '(${Temperature} > 90) ? ' + LabelStyle.FILL_AND_OUTLINE + ' : ' + LabelStyle.FILL + * }); + * style.labelStyle.evaluate(frameState, feature); // returns a LabelStyle + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelStyle expression with a custom function + * style.labelStyle = { + * evaluate : function(frameState, feature) { + * return LabelStyle.FILL; + * } + * }; */ - this.debugShowContentBoundingVolume = defaultValue(options.debugShowContentBoundingVolume, false); + labelStyle : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._labelStyle; + }, + set : function(value) { + this._labelStyle = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>labelText</code> property. Alternatively a string or object defining a string style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, renders the viewer request volume for each tile. + * The expression must return a <code>String</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium3DTileStyle({ + * labelText : '(${Temperature} > 90) ? ">90" : "<=90"' + * }); + * style.labelText.evaluate(frameState, feature); // returns a String + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelText expression with a custom function + * style.labelText = { + * evaluate : function(frameState, feature) { + * return 'Example label text'; + * } + * }; */ - this.debugShowViewerRequestVolume = defaultValue(options.debugShowViewerRequestVolume, false); - - this._tileDebugLabels = undefined; - this.debugPickedTileLabelOnly = false; - this.debugPickedTile = undefined; - this.debugPickPosition = undefined; + labelText : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._labelText; + }, + set : function(value) { + this._labelText = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>backgroundColor</code> property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, draws labels to indicate the geometric error of each tile. + * The expression must return a <code>Color</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override backgroundColor expression with a string + * style.backgroundColor = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override backgroundColor expression with a condition + * style.backgroundColor = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ - this.debugShowGeometricError = defaultValue(options.debugShowGeometricError, false); + backgroundColor : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._backgroundColor; + }, + set : function(value) { + this._backgroundColor = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>backgroundPadding</code> property. Alternatively a string or object defining a vec2 style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, draws labels to indicate the number of commands, points, triangles and features of each tile. + * The expression must return a <code>Cartesian2</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override backgroundPadding expression with a string + * style.backgroundPadding = 'vec2(5.0, 7.0)'; + * style.backgroundPadding.evaluate(frameState, feature); // returns a Cartesian2 */ - this.debugShowRenderingStatistics = defaultValue(options.debugShowRenderingStatistics, false); + backgroundPadding : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._backgroundPadding; + }, + set : function(value) { + this._backgroundPadding = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>backgroundEnabled</code> property. Alternatively a string or object defining a boolean style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, draws labels to indicate the geometry and texture memory usage of each tile. + * The expression must return a <code>Boolean</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override backgroundEnabled expression with a string + * style.backgroundEnabled = 'true'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override backgroundEnabled expression with a condition + * style.backgroundEnabled = { + * conditions : [ + * ['${height} > 2', 'true'], + * ['true', 'false'] + * ] + * }; */ - this.debugShowMemoryUsage = defaultValue(options.debugShowMemoryUsage, false); + backgroundEnabled : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._backgroundEnabled; + }, + set : function(value) { + this._backgroundEnabled = getExpression(this, value); + } + }, /** - * This property is for debugging only; it is not optimized for production use. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>scaleByDistance</code> property. Alternatively a string or object defining a vec4 style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * When true, draws labels to indicate the url of each tile. + * The expression must return a <code>Cartesian4</code>. * </p> * - * @type {Boolean} - * @default false + * @memberof Cesium3DTileStyle.prototype + * + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override scaleByDistance expression with a string + * style.scaleByDistance = 'vec4(1.5e2, 2.0, 1.5e7, 0.5)'; + * style.scaleByDistance.evaluate(frameState, feature); // returns a Cartesian4 */ - this.debugShowUrl = defaultValue(options.debugShowUrl, false); - - var that = this; - - // We don't know the distance of the tileset until tileset.json is loaded, so use the default distance for now - Cesium3DTileset.loadJson(tilesetUrl).then(function(tilesetJson) { - that._root = that.loadTileset(tilesetUrl, tilesetJson); - var gltfUpAxis = defined(tilesetJson.asset.gltfUpAxis) ? Axis.fromName(tilesetJson.asset.gltfUpAxis) : Axis.Y; - that._asset = tilesetJson.asset; - that._properties = tilesetJson.properties; - that._geometricError = tilesetJson.geometricError; - that._gltfUpAxis = gltfUpAxis; - that._readyPromise.resolve(that); - }).otherwise(function(error) { - that._readyPromise.reject(error); - }); - } + scaleByDistance : { + get : function() { + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._scaleByDistance; + }, + set : function(value) { + this._scaleByDistance = getExpression(this, value); + } + }, - defineProperties(Cesium3DTileset.prototype, { /** - * Gets the tileset's asset object property, which contains metadata about the tileset. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>translucencyByDistance</code> property. Alternatively a string or object defining a vec4 style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * See the {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/schema/asset.schema.json|asset schema} - * in the 3D Tiles spec for the full set of properties. + * The expression must return a <code>Cartesian4</code>. * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Object} - * @readonly + * @type {StyleExpression} * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override translucencyByDistance expression with a string + * style.translucencyByDistance = 'vec4(1.5e2, 1.0, 1.5e7, 0.2)'; + * style.translucencyByDistance.evaluate(frameState, feature); // returns a Cartesian4 */ - asset : { + translucencyByDistance : { get : function() { - if (!this.ready) { - throw new DeveloperError('The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true.'); + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); } - return this._asset; + return this._translucencyByDistance; + }, + set : function(value) { + this._translucencyByDistance = getExpression(this, value); } }, /** - * Gets the tileset's properties dictionary object, which contains metadata about per-feature properties. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>distanceDisplayCondition</code> property. Alternatively a string or object defining a vec2 style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * See the {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/schema/properties.schema.json|properties schema} - * in the 3D Tiles spec for the full set of properties. + * The expression must return a <code>Cartesian2</code>. * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Object} - * @readonly + * @type {StyleExpression} * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. * - * @example - * console.log('Maximum building height: ' + tileset.properties.height.maximum); - * console.log('Minimum building height: ' + tileset.properties.height.minimum); + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * - * @see Cesium3DTileFeature#getProperty - * @see Cesium3DTileFeature#setProperty + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override distanceDisplayCondition expression with a string + * style.distanceDisplayCondition = 'vec2(0.0, 5.5e6)'; + * style.distanceDisplayCondition.evaluate(frameState, feature); // returns a Cartesian2 */ - properties : { + distanceDisplayCondition : { get : function() { - if (!this.ready) { - throw new DeveloperError('The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true.'); + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); } - return this._properties; + return this._distanceDisplayCondition; + }, + set : function(value) { + this._distanceDisplayCondition = getExpression(this, value); } }, /** - * When <code>true</code>, the tileset's root tile is loaded and the tileset is ready to render. - * This is set to <code>true</code> right before {@link Cesium3DTileset#readyPromise} is resolved. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>heightOffset</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. + * <p> + * The expression must return a <code>Number</code>. + * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Boolean} - * @readonly + * @type {StyleExpression} * - * @default false + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override heightOffset expression with a string + * style.heightOffset = '2.0'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override heightOffset expression with a condition + * style.heightOffset = { + * conditions : [ + * ['${height} > 2', '4.0'], + * ['true', '2.0'] + * ] + * }; */ - ready : { + heightOffset : { get : function() { - return defined(this._root); + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._heightOffset; + }, + set : function(value) { + this._heightOffset = getExpression(this, value); } }, /** - * Gets the promise that will be resolved when the tileset's root tile is loaded and the tileset is ready to render. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>anchorLineEnabled</code> property. Alternatively a string or object defining a boolean style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * This promise is resolved at the end of the frame before the first frame the tileset is rendered in. + * The expression must return a <code>Boolean</code>. * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Promise.<Cesium3DTileset>} - * @readonly + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * * @example - * tileset.readyPromise.then(function(tileset) { - * // tile.properties is not defined until readyPromise resolves. - * var properties = tileset.properties; - * if (Cesium.defined(properties)) { - * for (var name in properties) { - * console.log(properties[name]); - * } - * } - * }); + * var style = new Cesium.Cesium3DTileStyle(); + * // Override anchorLineEnabled expression with a string + * style.anchorLineEnabled = 'true'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override anchorLineEnabled expression with a condition + * style.anchorLineEnabled = { + * conditions : [ + * ['${height} > 2', 'true'], + * ['true', 'false'] + * ] + * }; */ - readyPromise : { + anchorLineEnabled : { get : function() { - return this._readyPromise.promise; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._anchorLineEnabled; + }, + set : function(value) { + this._anchorLineEnabled = getExpression(this, value); } }, /** - * When <code>true</code>, all tiles that meet the screen space error this frame are loaded. The tileset is - * completely loaded for this view. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>anchorLineColor</code> property. Alternatively a string or object defining a color style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. + * <p> + * The expression must return a <code>Color</code>. + * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Boolean} - * @readonly + * @type {StyleExpression} * - * @default false + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. * - * @see Cesium3DTileset#allTilesLoaded + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override anchorLineColor expression with a string + * style.anchorLineColor = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override anchorLineColor expression with a condition + * style.anchorLineColor = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ - tilesLoaded : { + anchorLineColor : { get : function() { - return this._tilesLoaded; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._anchorLineColor; + }, + set : function(value) { + this._anchorLineColor = getExpression(this, value); } }, /** - * The url to a tileset.json file or to a directory containing a tileset.json file. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>image</code> property. Alternatively a string or object defining a string style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. + * <p> + * The expression must return a <code>String</code>. + * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {String} - * @readonly + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium3DTileStyle({ + * image : '(${Temperature} > 90) ? "/url/to/image1" : "/url/to/image2"' + * }); + * style.image.evaluate(frameState, feature); // returns a String + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override image expression with a custom function + * style.image = { + * evaluate : function(frameState, feature) { + * return '/url/to/image'; + * } + * }; */ - url : { + image : { get : function() { - return this._url; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._image; + }, + set : function(value) { + this._image = getExpression(this, value); } }, /** - * The base path that non-absolute paths in tileset.json are relative to. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>disableDepthTestDistance</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. + * <p> + * The expression must return a <code>Number</code>. + * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {String} - * @readonly + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override disableDepthTestDistance expression with a string + * style.disableDepthTestDistance = '1000.0'; + * style.disableDepthTestDistance.evaluate(frameState, feature); // returns a Number */ - basePath : { + disableDepthTestDistance : { get : function() { - return this._basePath; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._disableDepthTestDistance; + }, + set : function(value) { + this._disableDepthTestDistance = getExpression(this, value); } }, /** - * The style, defined using the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}, - * applied to each feature in the tileset. - * <p> - * Assign <code>undefined</code> to remove the style, which will restore the visual - * appearance of the tileset to its default when no style was applied. - * </p> + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>horizontalOrigin</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * The style is applied to a tile before the {@link Cesium3DTileset#tileVisible} - * event is raised, so code in <code>tileVisible</code> can manually set a feature's - * properties (e.g. color and show) after the style is applied. When - * a new style is assigned any manually set properties are overwritten. + * The expression must return a <code>HorizontalOrigin</code>. * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Cesium3DTileStyle} + * @type {StyleExpression} * - * @default undefined + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * * @example - * tileset.style = new Cesium.Cesium3DTileStyle({ - * color : { - * conditions : [ - * ['${Height} >= 100', 'color("purple", 0.5)'], - * ['${Height} >= 50', 'color("red")'], - * ['true', 'color("blue")'] - * ] - * }, - * show : '${Height} > 0', - * meta : { - * description : '"Building id ${id} has height ${Height}."' - * } + * var style = new Cesium3DTileStyle({ + * horizontalOrigin : HorizontalOrigin.LEFT * }); + * style.horizontalOrigin.evaluate(frameState, feature); // returns a HorizontalOrigin * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override horizontalOrigin expression with a custom function + * style.horizontalOrigin = { + * evaluate : function(frameState, feature) { + * return HorizontalOrigin.CENTER; + * } + * }; */ - style : { + horizontalOrigin : { get : function() { - return this._styleEngine.style; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._horizontalOrigin; }, set : function(value) { - this._styleEngine.style = value; + this._horizontalOrigin = getExpression(this, value); } }, /** - * The maximum screen space error used to drive level of detail refinement. This value helps determine when a tile - * refines to its descendants, and therefore plays a major role in balancing performance with visual quality. - * <p> - * A tile's screen space error is roughly equivalent to the number of pixels wide that would be drawn if a sphere with a - * radius equal to the tile's <b>geometric error</b> were rendered at the tile's position. If this value exceeds - * <code>maximumScreenSpaceError</code> the tile refines to its descendants. - * </p> + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>verticalOrigin</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * Depending on the tileset, <code>maximumScreenSpaceError</code> may need to be tweaked to achieve the right balance. - * Higher values provide better performance but lower visual quality. + * The expression must return a <code>VerticalOrigin</code>. * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Number} - * @default 16 + * @type {StyleExpression} * - * @exception {DeveloperError} <code>maximumScreenSpaceError</code> must be greater than or equal to zero. + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium3DTileStyle({ + * verticalOrigin : VerticalOrigin.TOP + * }); + * style.verticalOrigin.evaluate(frameState, feature); // returns a VerticalOrigin + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override verticalOrigin expression with a custom function + * style.verticalOrigin = { + * evaluate : function(frameState, feature) { + * return VerticalOrigin.CENTER; + * } + * }; */ - maximumScreenSpaceError : { + verticalOrigin : { get : function() { - return this._maximumScreenSpaceError; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._verticalOrigin; }, set : function(value) { - Check.typeOf.number.greaterThanOrEquals('maximumScreenSpaceError', value, 0); - - this._maximumScreenSpaceError = value; + this._verticalOrigin = getExpression(this, value); } }, /** - * The maximum amount of GPU memory (in MB) that may be used to cache tiles. This value is estimated from - * geometry, textures, and batch table textures of loaded tiles. For point clouds, this value also - * includes per-point metadata. - * <p> - * Tiles not in view are unloaded to enforce this. - * </p> - * <p> - * If decreasing this value results in unloading tiles, the tiles are unloaded the next frame. - * </p> + Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>labelHorizontalOrigin</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. * <p> - * If tiles sized more than <code>maximumMemoryUsage</code> are needed - * to meet the desired screen space error, determined by {@link Cesium3DTileset#maximumScreenSpaceError}, - * for the current view, then the memory usage of the tiles loaded will exceed - * <code>maximumMemoryUsage</code>. For example, if the maximum is 256 MB, but - * 300 MB of tiles are needed to meet the screen space error, then 300 MB of tiles may be loaded. When - * these tiles go out of view, they will be unloaded. + * The expression must return a <code>HorizontalOrigin</code>. * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Number} - * @default 512 + * @type {StyleExpression} * - * @exception {DeveloperError} <code>maximumMemoryUsage</code> must be greater than or equal to zero. - * @see Cesium3DTileset#totalMemoryUsageInBytes + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. + * + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + * + * @example + * var style = new Cesium3DTileStyle({ + * labelHorizontalOrigin : HorizontalOrigin.LEFT + * }); + * style.labelHorizontalOrigin.evaluate(frameState, feature); // returns a HorizontalOrigin + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelHorizontalOrigin expression with a custom function + * style.labelHorizontalOrigin = { + * evaluate : function(frameState, feature) { + * return HorizontalOrigin.CENTER; + * } + * }; */ - maximumMemoryUsage : { + labelHorizontalOrigin : { get : function() { - return this._maximumMemoryUsage; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._labelHorizontalOrigin; }, set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0); - - this._maximumMemoryUsage = value; + this._labelHorizontalOrigin = getExpression(this, value); } }, /** - * The tileset's bounding sphere. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>labelVerticalOrigin</code> property. Alternatively a string or object defining a number style can be used. + * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. + * <p> + * The expression must return a <code>VerticalOrigin</code>. + * </p> * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {BoundingSphere} - * @readonly + * @type {StyleExpression} * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. * - * @example - * var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle' - * })); + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * - * tileset.readyPromise.then(function(tileset) { - * // Set the camera to view the newly added tileset - * viewer.camera.viewBoundingSphere(tileset.boundingSphere, new Cesium.HeadingPitchRange(0, -0.5, 0)); + * @example + * var style = new Cesium3DTileStyle({ + * labelVerticalOrigin : VerticalOrigin.TOP * }); + * style.labelVerticalOrigin.evaluate(frameState, feature); // returns a VerticalOrigin + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override labelVerticalOrigin expression with a custom function + * style.labelVerticalOrigin = { + * evaluate : function(frameState, feature) { + * return VerticalOrigin.CENTER; + * } + * }; */ - boundingSphere : { + labelVerticalOrigin : { get : function() { - if (!this.ready) { - throw new DeveloperError('The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true.'); + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); } - return this._root.boundingSphere; + return this._labelVerticalOrigin; + }, + set : function(value) { + this._labelVerticalOrigin = getExpression(this, value); } }, /** - * A 4x4 transformation matrix that transforms the entire tileset. + * Gets or sets the object containing application-specific expression that can be explicitly + * evaluated, e.g., for display in a UI. * - * @memberof Cesium3DTileset.prototype + * @memberof Cesium3DTileStyle.prototype * - * @type {Matrix4} - * @default Matrix4.IDENTITY + * @type {StyleExpression} + * + * @exception {DeveloperError} The style is not loaded. Use {@link Cesium3DTileStyle#readyPromise} or wait for {@link Cesium3DTileStyle#ready} to be true. * * @example - * // Adjust a tileset's height from the globe's surface. - * var heightOffset = 20.0; - * var boundingSphere = tileset.boundingSphere; - * var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center); - * var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0); - * var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset); - * var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); - * tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + * var style = new Cesium3DTileStyle({ + * meta : { + * description : '"Building id ${id} has height ${Height}."' + * } + * }); + * style.meta.description.evaluate(frameState, feature); // returns a String with the substituted variables */ - modelMatrix : { + meta : { get : function() { - return this._modelMatrix; + if (!this._ready) { + throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); + } + + return this._meta; }, set : function(value) { - this._modelMatrix = Matrix4.clone(value, this._modelMatrix); - if (defined(this._root)) { - // Update the root transform right away instead of waiting for the next update loop. - // Useful, for example, when setting the modelMatrix and then having the camera view the tileset. - this._root.updateTransform(this._modelMatrix); + this._meta = value; + } + } + }); + + /** + * Gets the color shader function for this style. + * + * @param {String} functionName Name to give to the generated function. + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * + * @returns {String} The shader function. + * + * @private + */ + Cesium3DTileStyle.prototype.getColorShaderFunction = function(functionName, attributePrefix, shaderState) { + if (this._colorShaderFunctionReady) { + shaderState.translucent = this._colorShaderTranslucent; + // Return the cached result, may be undefined + return this._colorShaderFunction; + } + + this._colorShaderFunctionReady = true; + this._colorShaderFunction = defined(this.color) ? this.color.getShaderFunction(functionName, attributePrefix, shaderState, 'vec4') : undefined; + this._colorShaderTranslucent = shaderState.translucent; + return this._colorShaderFunction; + }; + + /** + * Gets the show shader function for this style. + * + * @param {String} functionName Name to give to the generated function. + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * + * @returns {String} The shader function. + * + * @private + */ + Cesium3DTileStyle.prototype.getShowShaderFunction = function(functionName, attributePrefix, shaderState) { + if (this._showShaderFunctionReady) { + // Return the cached result, may be undefined + return this._showShaderFunction; + } + + this._showShaderFunctionReady = true; + this._showShaderFunction = defined(this.show) ? this.show.getShaderFunction(functionName, attributePrefix, shaderState, 'bool') : undefined; + return this._showShaderFunction; + }; + + /** + * Gets the pointSize shader function for this style. + * + * @param {String} functionName Name to give to the generated function. + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * + * @returns {String} The shader function. + * + * @private + */ + Cesium3DTileStyle.prototype.getPointSizeShaderFunction = function(functionName, attributePrefix, shaderState) { + if (this._pointSizeShaderFunctionReady) { + // Return the cached result, may be undefined + return this._pointSizeShaderFunction; + } + + this._pointSizeShaderFunctionReady = true; + this._pointSizeShaderFunction = defined(this.pointSize) ? this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float') : undefined; + return this._pointSizeShaderFunction; + }; + + return Cesium3DTileStyle; +}); + +define('Scene/UrlTemplateImageryProvider',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/clone', + '../Core/combine', + '../Core/Credit', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/Event', + '../Core/GeographicTilingScheme', + '../Core/isArray', + '../Core/Math', + '../Core/Rectangle', + '../Core/Resource', + '../Core/WebMercatorTilingScheme', + '../ThirdParty/when', + './ImageryProvider' + ], function( + Cartesian2, + Cartesian3, + Cartographic, + clone, + combine, + Credit, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Event, + GeographicTilingScheme, + isArray, + CesiumMath, + Rectangle, + Resource, + WebMercatorTilingScheme, + when, + ImageryProvider) { + 'use strict'; + + var templateRegex = /{[^}]+}/g; + + var tags = { + 'x': xTag, + 'y': yTag, + 'z': zTag, + 's': sTag, + 'reverseX': reverseXTag, + 'reverseY': reverseYTag, + 'reverseZ': reverseZTag, + 'westDegrees': westDegreesTag, + 'southDegrees': southDegreesTag, + 'eastDegrees': eastDegreesTag, + 'northDegrees': northDegreesTag, + 'westProjected': westProjectedTag, + 'southProjected': southProjectedTag, + 'eastProjected': eastProjectedTag, + 'northProjected': northProjectedTag, + 'width': widthTag, + 'height': heightTag + }; + + var pickFeaturesTags = combine(tags, { + 'i' : iTag, + 'j' : jTag, + 'reverseI' : reverseITag, + 'reverseJ' : reverseJTag, + 'longitudeDegrees' : longitudeDegreesTag, + 'latitudeDegrees' : latitudeDegreesTag, + 'longitudeProjected' : longitudeProjectedTag, + 'latitudeProjected' : latitudeProjectedTag, + 'format' : formatTag + }); + + /** + * Provides imagery by requesting tiles using a specified URL template. + * + * @alias UrlTemplateImageryProvider + * @constructor + * + * @param {Promise.<Object>|Object} [options] Object with the following properties: + * @param {Resource|String} options.url The URL template to use to request tiles. It has the following keywords: + * <ul> + * <li><code>{z}</code>: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.</li> + * <li><code>{x}</code>: The tile X coordinate in the tiling scheme, where 0 is the Westernmost tile.</li> + * <li><code>{y}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Northernmost tile.</li> + * <li><code>{s}</code>: One of the available subdomains, used to overcome browser limits on the number of simultaneous requests per host.</li> + * <li><code>{reverseX}</code>: The tile X coordinate in the tiling scheme, where 0 is the Easternmost tile.</li> + * <li><code>{reverseY}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Southernmost tile.</li> + * <li><code>{reverseZ}</code>: The level of the tile in the tiling scheme, where level zero is the maximum level of the quadtree pyramid. In order to use reverseZ, maximumLevel must be defined.</li> + * <li><code>{westDegrees}</code>: The Western edge of the tile in geodetic degrees.</li> + * <li><code>{southDegrees}</code>: The Southern edge of the tile in geodetic degrees.</li> + * <li><code>{eastDegrees}</code>: The Eastern edge of the tile in geodetic degrees.</li> + * <li><code>{northDegrees}</code>: The Northern edge of the tile in geodetic degrees.</li> + * <li><code>{westProjected}</code>: The Western edge of the tile in projected coordinates of the tiling scheme.</li> + * <li><code>{southProjected}</code>: The Southern edge of the tile in projected coordinates of the tiling scheme.</li> + * <li><code>{eastProjected}</code>: The Eastern edge of the tile in projected coordinates of the tiling scheme.</li> + * <li><code>{northProjected}</code>: The Northern edge of the tile in projected coordinates of the tiling scheme.</li> + * <li><code>{width}</code>: The width of each tile in pixels.</li> + * <li><code>{height}</code>: The height of each tile in pixels.</li> + * </ul> + * @param {Resource|String} [options.pickFeaturesUrl] The URL template to use to pick features. If this property is not specified, + * {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no + * features picked. The URL template supports all of the keywords supported by the <code>url</code> + * parameter, plus the following: + * <ul> + * <li><code>{i}</code>: The pixel column (horizontal coordinate) of the picked position, where the Westernmost pixel is 0.</li> + * <li><code>{j}</code>: The pixel row (vertical coordinate) of the picked position, where the Northernmost pixel is 0.</li> + * <li><code>{reverseI}</code>: The pixel column (horizontal coordinate) of the picked position, where the Easternmost pixel is 0.</li> + * <li><code>{reverseJ}</code>: The pixel row (vertical coordinate) of the picked position, where the Southernmost pixel is 0.</li> + * <li><code>{longitudeDegrees}</code>: The longitude of the picked position in degrees.</li> + * <li><code>{latitudeDegrees}</code>: The latitude of the picked position in degrees.</li> + * <li><code>{longitudeProjected}</code>: The longitude of the picked position in the projected coordinates of the tiling scheme.</li> + * <li><code>{latitudeProjected}</code>: The latitude of the picked position in the projected coordinates of the tiling scheme.</li> + * <li><code>{format}</code>: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.</li> + * </ul> + * @param {Object} [options.urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where + * each coordinate will be padded on the left with zeros to match the width of the passed string of zeros. e.g. Setting: + * urlSchemeZeroPadding : { '{x}' : '0000'} + * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL. + * It the passed object has the following keywords: + * <ul> + * <li> <code>{z}</code>: The zero padding for the level of the tile in the tiling scheme.</li> + * <li> <code>{x}</code>: The zero padding for the tile X coordinate in the tiling scheme.</li> + * <li> <code>{y}</code>: The zero padding for the the tile Y coordinate in the tiling scheme.</li> + * <li> <code>{reverseX}</code>: The zero padding for the tile reverseX coordinate in the tiling scheme.</li> + * <li> <code>{reverseY}</code>: The zero padding for the tile reverseY coordinate in the tiling scheme.</li> + * <li> <code>{reverseZ}</code>: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.</li> + * </ul> + * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. + * If this parameter is a single string, each character in the string is a subdomain. If it is + * an array, each element in the array is a subdomain. + * @param {Credit|String} [options.credit=''] A credit for the data source, which is displayed on the canvas. + * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely + * to result in rendering problems. + * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. + * @param {TilingScheme} [options.tilingScheme=WebMercatorTilingScheme] The tiling scheme specifying how the ellipsoidal + * surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme} + * is used. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * @param {Number} [options.tileWidth=256] Pixel width of image tiles. + * @param {Number} [options.tileHeight=256] Pixel height of image tiles. + * @param {Boolean} [options.hasAlphaChannel=true] true if the images provided by this imagery provider + * include an alpha channel; otherwise, false. If this property is false, an alpha channel, if + * present, will be ignored. If this property is true, any images without an alpha channel will + * be treated as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are potentially reduced. + * @param {GetFeatureInfoFormat[]} [options.getFeatureInfoFormats] The formats in which to get feature information at a + * specific location when {@link UrlTemplateImageryProvider#pickFeatures} is invoked. If this + * parameter is not specified, feature picking is disabled. + * @param {Boolean} [options.enablePickFeatures=true] If true, {@link UrlTemplateImageryProvider#pickFeatures} will + * request the <code>options.pickFeaturesUrl</code> and attempt to interpret the features included in the response. If false, + * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable + * features) without communicating with the server. Set this property to false if you know your data + * source does not support picking features or if you don't want this provider's features to be pickable. Note + * that this can be dynamically overridden by modifying the {@link UriTemplateImageryProvider#enablePickFeatures} + * property. + * @param {Object} [options.customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values. + * + * + * @example + * // Access Natural Earth II imagery, which uses a TMS tiling scheme and Geographic (EPSG:4326) project + * var tms = new Cesium.UrlTemplateImageryProvider({ + * url : 'https://cesiumjs.org/tilesets/imagery/naturalearthii/{z}/{x}/{reverseY}.jpg', + * credit : '© Analytical Graphics, Inc.', + * tilingScheme : new Cesium.GeographicTilingScheme(), + * maximumLevel : 5 + * }); + * // Access the CartoDB Positron basemap, which uses an OpenStreetMap-like tiling scheme. + * var positron = new Cesium.UrlTemplateImageryProvider({ + * url : 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', + * credit : 'Map tiles by CartoDB, under CC BY 3.0. Data by OpenStreetMap, under ODbL.' + * }); + * // Access a Web Map Service (WMS) server. + * var wms = new Cesium.UrlTemplateImageryProvider({ + * url : 'https://programs.communications.gov.au/geoserver/ows?tiled=true&' + + * 'transparent=true&format=image%2Fpng&exceptions=application%2Fvnd.ogc.se_xml&' + + * 'styles=&service=WMS&version=1.1.1&request=GetMap&' + + * 'layers=public%3AMyBroadband_Availability&srs=EPSG%3A3857&' + + * 'bbox={westProjected}%2C{southProjected}%2C{eastProjected}%2C{northProjected}&' + + * 'width=256&height=256', + * rectangle : Cesium.Rectangle.fromDegrees(96.799393, -43.598214999057824, 153.63925700000001, -9.2159219997013) + * }); + * // Using custom tags in your template url. + * var custom = new Cesium.UrlTemplateImageryProvider({ + * url : 'https://yoururl/{Time}/{z}/{y}/{x}.png', + * customTags : { + * Time: function(imageryProvider, x, y, level) { + * return '20171231' + * } + * } + * }); + * + * @see ArcGisMapServerImageryProvider + * @see BingMapsImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + */ + function UrlTemplateImageryProvider(options) { + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + if (!when.isPromise(options) && !defined(options.url)) { + throw new DeveloperError('options is required.'); + } + + this._errorEvent = new Event(); + + this._resource = undefined; + this._urlSchemeZeroPadding = undefined; + this._pickFeaturesResource = undefined; + this._tileWidth = undefined; + this._tileHeight = undefined; + this._maximumLevel = undefined; + this._minimumLevel = undefined; + this._tilingScheme = undefined; + this._rectangle = undefined; + this._tileDiscardPolicy = undefined; + this._credit = undefined; + this._hasAlphaChannel = undefined; + this._readyPromise = undefined; + this._tags = undefined; + this._pickFeaturesTags = undefined; + + /** + * Gets or sets a value indicating whether feature picking is enabled. If true, {@link UrlTemplateImageryProvider#pickFeatures} will + * request the <code>options.pickFeaturesUrl</code> and attempt to interpret the features included in the response. If false, + * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable + * features) without communicating with the server. Set this property to false if you know your data + * source does not support picking features or if you don't want this provider's features to be pickable. + * @type {Boolean} + * @default true + */ + this.enablePickFeatures = true; + + this.reinitialize(options); + } + + defineProperties(UrlTemplateImageryProvider.prototype, { + /** + * Gets the URL template to use to request tiles. It has the following keywords: + * <ul> + * <li> <code>{z}</code>: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.</li> + * <li> <code>{x}</code>: The tile X coordinate in the tiling scheme, where 0 is the Westernmost tile.</li> + * <li> <code>{y}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Northernmost tile.</li> + * <li> <code>{s}</code>: One of the available subdomains, used to overcome browser limits on the number of simultaneous requests per host.</li> + * <li> <code>{reverseX}</code>: The tile X coordinate in the tiling scheme, where 0 is the Easternmost tile.</li> + * <li> <code>{reverseY}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Southernmost tile.</li> + * <li> <code>{reverseZ}</code>: The level of the tile in the tiling scheme, where level zero is the maximum level of the quadtree pyramid. In order to use reverseZ, maximumLevel must be defined.</li> + * <li> <code>{westDegrees}</code>: The Western edge of the tile in geodetic degrees.</li> + * <li> <code>{southDegrees}</code>: The Southern edge of the tile in geodetic degrees.</li> + * <li> <code>{eastDegrees}</code>: The Eastern edge of the tile in geodetic degrees.</li> + * <li> <code>{northDegrees}</code>: The Northern edge of the tile in geodetic degrees.</li> + * <li> <code>{westProjected}</code>: The Western edge of the tile in projected coordinates of the tiling scheme.</li> + * <li> <code>{southProjected}</code>: The Southern edge of the tile in projected coordinates of the tiling scheme.</li> + * <li> <code>{eastProjected}</code>: The Eastern edge of the tile in projected coordinates of the tiling scheme.</li> + * <li> <code>{northProjected}</code>: The Northern edge of the tile in projected coordinates of the tiling scheme.</li> + * <li> <code>{width}</code>: The width of each tile in pixels.</li> + * <li> <code>{height}</code>: The height of each tile in pixels.</li> + * </ul> + * @memberof UrlTemplateImageryProvider.prototype + * @type {String} + * @readonly + */ + url : { + get : function() { + return this._resource.url; + } + }, + + /** + * Gets the URL scheme zero padding for each tile coordinate. The format is '000' where each coordinate will be padded on + * the left with zeros to match the width of the passed string of zeros. e.g. Setting: + * urlSchemeZeroPadding : { '{x}' : '0000'} + * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL. + * It has the following keywords: + * <ul> + * <li> <code>{z}</code>: The zero padding for the level of the tile in the tiling scheme.</li> + * <li> <code>{x}</code>: The zero padding for the tile X coordinate in the tiling scheme.</li> + * <li> <code>{y}</code>: The zero padding for the the tile Y coordinate in the tiling scheme.</li> + * <li> <code>{reverseX}</code>: The zero padding for the tile reverseX coordinate in the tiling scheme.</li> + * <li> <code>{reverseY}</code>: The zero padding for the tile reverseY coordinate in the tiling scheme.</li> + * <li> <code>{reverseZ}</code>: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.</li> + * </ul> + * @memberof UrlTemplateImageryProvider.prototype + * @type {Object} + * @readonly + */ + urlSchemeZeroPadding : { + get : function() { + return this._urlSchemeZeroPadding; + } + }, + + /** + * Gets the URL template to use to use to pick features. If this property is not specified, + * {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no + * features picked. The URL template supports all of the keywords supported by the + * {@link UrlTemplateImageryProvider#url} property, plus the following: + * <ul> + * <li><code>{i}</code>: The pixel column (horizontal coordinate) of the picked position, where the Westernmost pixel is 0.</li> + * <li><code>{j}</code>: The pixel row (vertical coordinate) of the picked position, where the Northernmost pixel is 0.</li> + * <li><code>{reverseI}</code>: The pixel column (horizontal coordinate) of the picked position, where the Easternmost pixel is 0.</li> + * <li><code>{reverseJ}</code>: The pixel row (vertical coordinate) of the picked position, where the Southernmost pixel is 0.</li> + * <li><code>{longitudeDegrees}</code>: The longitude of the picked position in degrees.</li> + * <li><code>{latitudeDegrees}</code>: The latitude of the picked position in degrees.</li> + * <li><code>{longitudeProjected}</code>: The longitude of the picked position in the projected coordinates of the tiling scheme.</li> + * <li><code>{latitudeProjected}</code>: The latitude of the picked position in the projected coordinates of the tiling scheme.</li> + * <li><code>{format}</code>: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.</li> + * </ul> + * @memberof UrlTemplateImageryProvider.prototype + * @type {String} + * @readonly + */ + pickFeaturesUrl : { + get : function() { + return this._pickFeaturesResource.url; + } + }, + + /** + * Gets the proxy used by this provider. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Proxy} + * @readonly + * @default undefined + */ + proxy : { + get : function() { + return this._resource.proxy; + } + }, + + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number} + * @readonly + * @default 256 + */ + tileWidth : { + get : function() { + if (!this.ready) { + throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); } + return this._tileWidth; } }, /** - * Returns the time, in milliseconds, since the tileset was loaded and first updated. - * - * @memberof Cesium3DTileset.prototype - * + * Gets the height of each tile, in pixels. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number} + * @readonly + * @default 256 + */ + tileHeight: { + get : function() { + if (!this.ready) { + throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + } + return this._tileHeight; + } + }, + + /** + * Gets the maximum level-of-detail that can be requested, or undefined if there is no limit. + * This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number} + * @readonly + * @default undefined + */ + maximumLevel : { + get : function() { + if (!this.ready) { + throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); + } + return this._maximumLevel; + } + }, + + /** + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype * @type {Number} * @readonly + * @default 0 + */ + minimumLevel : { + get : function() { + if (!this.ready) { + throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); + } + return this._minimumLevel; + } + }, + + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {TilingScheme} + * @readonly + * @default new WebMercatorTilingScheme() + */ + tilingScheme : { + get : function() { + if (!this.ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + } + return this._tilingScheme; + } + }, + + /** + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Rectangle} + * @readonly + * @default tilingScheme.rectangle + */ + rectangle : { + get : function() { + if (!this.ready) { + throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); + } + return this._rectangle; + } + }, + + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + * @default undefined + */ + tileDiscardPolicy : { + get : function() { + if (!this.ready) { + throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); + } + return this._tileDiscardPolicy; + } + }, + + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, + + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Boolean} + * @readonly */ - timeSinceLoad : { + ready : { get : function() { - return this._timeSinceLoad; + return defined(this._resource); } }, /** - * The total amount of GPU memory in bytes used by the tileset. This value is estimated from - * geometry, texture, and batch table textures of loaded tiles. For point clouds, this value also - * includes per-point metadata. - * - * @memberof Cesium3DTileset.prototype - * - * @type {Number} + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Promise.<Boolean>} * @readonly - * - * @see Cesium3DTileset#maximumMemoryUsage */ - totalMemoryUsageInBytes : { + readyPromise : { get : function() { - var statistics = this._statistics; - return statistics.texturesByteLength + statistics.geometryByteLength + statistics.batchTableByteLength; + return this._readyPromise; } }, /** - * @private + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Credit} + * @readonly + * @default undefined */ - styleEngine : { + credit : { get : function() { - return this._styleEngine; + if (!this.ready) { + throw new DeveloperError('credit must not be called before the imagery provider is ready.'); + } + return this._credit; } }, /** - * @private + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. This function should + * not be called before {@link ImageryProvider#ready} returns true. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Boolean} + * @readonly + * @default true */ - statistics : { + hasAlphaChannel : { get : function() { - return this._statistics; + if (!this.ready) { + throw new DeveloperError('hasAlphaChannel must not be called before the imagery provider is ready.'); + } + return this._hasAlphaChannel; } } }); /** - * Provides a hook to override the method used to request the tileset json - * useful when fetching tilesets from remote servers - * @param {String} tilesetUrl The url of the json file to be fetched - * @returns {Promise.<Object>} A promise that resolves with the fetched json data - */ - Cesium3DTileset.loadJson = function(tilesetUrl) { - return loadJson(tilesetUrl); - }; - - /** - * Marks the tileset's {@link Cesium3DTileset#style} as dirty, which forces all - * features to re-evaluate the style in the next frame each is visible. - */ - Cesium3DTileset.prototype.makeStyleDirty = function() { - this._styleEngine.makeDirty(); - }; - - /** - * Loads the main tileset.json or a tileset.json referenced from a tile. + * Reinitializes this instance. Reinitializing an instance already in use is supported, but it is not + * recommended because existing tiles provided by the imagery provider will not be updated. * - * @private + * @param {Promise.<Object>|Object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. */ - Cesium3DTileset.prototype.loadTileset = function(tilesetUrl, tilesetJson, parentTile) { - var asset = tilesetJson.asset; - if (!defined(asset)) { - throw new RuntimeError('Tileset must have an asset property.'); - } - if (asset.version !== '0.0' && asset.version !== '1.0') { - throw new RuntimeError('The tileset must be 3D Tiles version 0.0 or 1.0. See https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status'); - } - - var statistics = this._statistics; - - // Append the tileset version to the basePath - var hasVersionQuery = /[?&]v=/.test(tilesetUrl); - if (!hasVersionQuery) { - var versionQuery = '?v=' + defaultValue(asset.tilesetVersion, '0.0'); - this._basePath = joinUrls(this._basePath, versionQuery); - tilesetUrl = joinUrls(tilesetUrl, versionQuery, false); - } - - // A tileset.json referenced from a tile may exist in a different directory than the root tileset. - // Get the basePath relative to the external tileset. - var basePath = getBaseUri(tilesetUrl, true); - var rootTile = new Cesium3DTile(this, basePath, tilesetJson.root, parentTile); - - // If there is a parentTile, add the root of the currently loading tileset - // to parentTile's children, and update its _depth. - if (defined(parentTile)) { - parentTile.children.push(rootTile); - rootTile._depth = parentTile._depth + 1; - } - - ++statistics.numberOfTilesTotal; - - var stack = []; - stack.push({ - header : tilesetJson.root, - tile3D : rootTile - }); - - while (stack.length > 0) { - var tile = stack.pop(); - var tile3D = tile.tile3D; - var children = tile.header.children; - if (defined(children)) { - var length = children.length; - for (var i = 0; i < length; ++i) { - var childHeader = children[i]; - var childTile = new Cesium3DTile(this, basePath, childHeader, tile3D); - tile3D.children.push(childTile); - childTile._depth = tile3D._depth + 1; - ++statistics.numberOfTilesTotal; - stack.push({ - header : childHeader, - tile3D : childTile - }); - } + UrlTemplateImageryProvider.prototype.reinitialize = function(options) { + var that = this; + that._readyPromise = when(options).then(function(properties) { + if (!defined(properties)) { + throw new DeveloperError('options is required.'); + } + if (!defined(properties.url)) { + throw new DeveloperError('options.url is required.'); } - - if (this._cullWithChildrenBounds) { - Cesium3DTileOptimizations.checkChildrenWithinParent(tile3D); + + if (defined(options.proxy)) { + deprecationWarning('UrlTemplateImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - } - return rootTile; - }; + var customTags = properties.customTags; + var allTags = combine(tags, customTags); + var allPickFeaturesTags = combine(pickFeaturesTags, customTags); - var scratchPositionNormal = new Cartesian3(); - var scratchCartographic = new Cartographic(); - var scratchMatrix = new Matrix4(); - var scratchCenter = new Cartesian3(); - var scratchPosition = new Cartesian3(); - var scratchDirection = new Cartesian3(); + var resource = Resource.createIfNeeded(properties.url, { + proxy: properties.proxy + }); - function updateDynamicScreenSpaceError(tileset, frameState) { - var up; - var direction; - var height; - var minimumHeight; - var maximumHeight; + var pickFeaturesResource = Resource.createIfNeeded(properties.pickFeaturesUrl, { + proxy: properties.proxy + }); - var camera = frameState.camera; - var root = tileset._root; - var tileBoundingVolume = root.contentBoundingVolume; + that.enablePickFeatures = defaultValue(properties.enablePickFeatures, that.enablePickFeatures); + that._urlSchemeZeroPadding = defaultValue(properties.urlSchemeZeroPadding, that.urlSchemeZeroPadding); + that._tileDiscardPolicy = properties.tileDiscardPolicy; + that._getFeatureInfoFormats = properties.getFeatureInfoFormats; - if (tileBoundingVolume instanceof TileBoundingRegion) { - up = Cartesian3.normalize(camera.positionWC, scratchPositionNormal); - direction = camera.directionWC; - height = camera.positionCartographic.height; - minimumHeight = tileBoundingVolume.minimumHeight; - maximumHeight = tileBoundingVolume.maximumHeight; - } else { - // Transform camera position and direction into the local coordinate system of the tileset - var transformLocal = Matrix4.inverseTransformation(root.computedTransform, scratchMatrix); - var ellipsoid = frameState.mapProjection.ellipsoid; - var boundingVolume = tileBoundingVolume.boundingVolume; - var centerLocal = Matrix4.multiplyByPoint(transformLocal, boundingVolume.center, scratchCenter); - if (Cartesian3.magnitude(centerLocal) > ellipsoid.minimumRadius) { - // The tileset is defined in WGS84. Approximate the minimum and maximum height. - var centerCartographic = Cartographic.fromCartesian(centerLocal, ellipsoid, scratchCartographic); - up = Cartesian3.normalize(camera.positionWC, scratchPositionNormal); - direction = camera.directionWC; - height = camera.positionCartographic.height; - minimumHeight = 0.0; - maximumHeight = centerCartographic.height * 2.0; + that._subdomains = properties.subdomains; + if (isArray(that._subdomains)) { + that._subdomains = that._subdomains.slice(); + } else if (defined(that._subdomains) && that._subdomains.length > 0) { + that._subdomains = that._subdomains.split(''); } else { - // The tileset is defined in local coordinates (z-up) - var positionLocal = Matrix4.multiplyByPoint(transformLocal, camera.positionWC, scratchPosition); - up = Cartesian3.UNIT_Z; - direction = Matrix4.multiplyByPointAsVector(transformLocal, camera.directionWC, scratchDirection); - direction = Cartesian3.normalize(direction, direction); - height = positionLocal.z; - if (tileBoundingVolume instanceof TileOrientedBoundingBox) { - // Assuming z-up, the last component stores the half-height of the box - var boxHeight = root._header.boundingVolume.box[11]; - minimumHeight = centerLocal.z - boxHeight; - maximumHeight = centerLocal.z + boxHeight; - } else if (tileBoundingVolume instanceof TileBoundingSphere) { - var radius = boundingVolume.radius; - minimumHeight = centerLocal.z - radius; - maximumHeight = centerLocal.z + radius; - } - } - } - - // The range where the density starts to lessen. Start at the quarter height of the tileset. - var heightFalloff = tileset.dynamicScreenSpaceErrorHeightFalloff; - var heightClose = minimumHeight + (maximumHeight - minimumHeight) * heightFalloff; - var heightFar = maximumHeight; - - var t = CesiumMath.clamp((height - heightClose) / (heightFar - heightClose), 0.0, 1.0); - - // Increase density as the camera tilts towards the horizon - var dot = Math.abs(Cartesian3.dot(direction, up)); - var horizonFactor = 1.0 - dot; - - // Weaken the horizon factor as the camera height increases, implying the camera is further away from the tileset. - // The goal is to increase density for the "street view", not when viewing the tileset from a distance. - horizonFactor = horizonFactor * (1.0 - t); - - var density = tileset.dynamicScreenSpaceErrorDensity; - density *= horizonFactor; - - tileset._dynamicScreenSpaceErrorComputedDensity = density; - } - - function selectionHeuristic(tileset, ancestor, tile) { - var skipLevels = tileset.skipLevelOfDetail ? tileset.skipLevels : 0; - var skipScreenSpaceErrorFactor = tileset.skipLevelOfDetail ? tileset.skipScreenSpaceErrorFactor : 1.0; - - return (ancestor !== tile && !tile.hasEmptyContent && !tileset.immediatelyLoadDesiredLevelOfDetail) && - (tile._screenSpaceError < ancestor._screenSpaceError / skipScreenSpaceErrorFactor) && - (tile._depth > ancestor._depth + skipLevels); - } - - /////////////////////////////////////////////////////////////////////////// - - function requestContent(tileset, tile) { - if (tile.hasEmptyContent) { - return; - } - - var statistics = tileset._statistics; - var expired = tile.contentExpired; - var requested = tile.requestContent(); - - if (!requested) { - ++statistics.numberOfAttemptedRequests; - return; - } - - if (expired) { - if (tile.hasRenderableContent) { - statistics.decrementLoadCounts(tile.content); - --tileset._statistics.numberOfTilesWithContentReady; - } else if (tile.hasTilesetContent) { - destroySubtree(tileset, tile); - } - } - - ++statistics.numberOfPendingRequests; - - var removeFunction = removeFromProcessingQueue(tileset, tile); - tile.contentReadyToProcessPromise.then(addToProcessingQueue(tileset, tile)); - tile.contentReadyPromise.then(function() { - removeFunction(); - tileset.tileLoad.raiseEvent(tile); - }).otherwise(removeFunction); - } - - function requestTiles(tileset, outOfCore) { - if (!outOfCore) { - return; - } - var requestedTiles = tileset._requestedTiles; - var length = requestedTiles.length; - for (var i = 0; i < length; ++i) { - requestContent(tileset, requestedTiles[i]); - } - } - - function addToProcessingQueue(tileset, tile) { - return function() { - tileset._processingQueue.push(tile); - - --tileset._statistics.numberOfPendingRequests; - ++tileset._statistics.numberOfTilesProcessing; - }; - } - - function removeFromProcessingQueue(tileset, tile) { - return function() { - var index = tileset._processingQueue.indexOf(tile); - if (index === -1) { - // Not in processing queue - // For example, when a url request fails and the ready promise is rejected - --tileset._statistics.numberOfPendingRequests; - return; - } - - // Remove from processing queue - tileset._processingQueue.splice(index, 1); - --tileset._statistics.numberOfTilesProcessing; - - if (tile.hasRenderableContent) { - // RESEARCH_IDEA: ability to unload tiles (without content) for an - // external tileset when all the tiles are unloaded. - tileset._statistics.incrementLoadCounts(tile.content); - ++tileset._statistics.numberOfTilesWithContentReady; - - // Add to the tile cache. Previously expired tiles are already in the cache. - if (!defined(tile.replacementNode)) { - tile.replacementNode = tileset._replacementList.add(tile); - } - } - }; - } - - function processTiles(tileset, frameState) { - var tiles = tileset._processingQueue; - var length = tiles.length; - - // Process tiles in the PROCESSING state so they will eventually move to the READY state. - // Traverse backwards in case a tile is removed as a result of calling process() - for (var i = length - 1; i >= 0; --i) { - tiles[i].process(tileset, frameState); - } - } - - /////////////////////////////////////////////////////////////////////////// - - var scratchCartesian = new Cartesian3(); - - var stringOptions = { - maximumFractionDigits : 3 - }; - - function formatMemoryString(memorySizeInBytes) { - var memoryInMegabytes = memorySizeInBytes / 1048576; - if (memoryInMegabytes < 1.0) { - return memoryInMegabytes.toLocaleString(undefined, stringOptions); - } - return Math.round(memoryInMegabytes).toLocaleString(); - } - - function computeTileLabelPosition(tile) { - var boundingVolume = tile._boundingVolume.boundingVolume; - var halfAxes = boundingVolume.halfAxes; - var radius = boundingVolume.radius; - - var position = Cartesian3.clone(boundingVolume.center, scratchCartesian); - if (defined(halfAxes)) { - position.x += 0.75 * (halfAxes[0] + halfAxes[3] + halfAxes[6]); - position.y += 0.75 * (halfAxes[1] + halfAxes[4] + halfAxes[7]); - position.z += 0.75 * (halfAxes[2] + halfAxes[5] + halfAxes[8]); - } else if (defined(radius)) { - var normal = Cartesian3.normalize(boundingVolume.center, scratchCartesian); - normal = Cartesian3.multiplyByScalar(normal, 0.75 * radius, scratchCartesian); - position = Cartesian3.add(normal, boundingVolume.center, scratchCartesian); - } - return position; - } - - function addTileDebugLabel(tile, tileset, position) { - var labelString = ''; - var attributes = 0; - - if (tileset.debugShowGeometricError) { - labelString += '\nGeometric error: ' + tile.geometricError; - attributes++; - } - - if (tileset.debugShowRenderingStatistics) { - labelString += '\nCommands: ' + tile.commandsLength; - attributes++; - - // Don't display number of points or triangles if 0. - var numberOfPoints = tile.content.pointsLength; - if (numberOfPoints > 0) { - labelString += '\nPoints: ' + tile.content.pointsLength; - attributes++; - } - - var numberOfTriangles = tile.content.trianglesLength; - if (numberOfTriangles > 0) { - labelString += '\nTriangles: ' + tile.content.trianglesLength; - attributes++; - } - - labelString += '\nFeatures: ' + tile.content.featuresLength; - attributes ++; - } - - if (tileset.debugShowMemoryUsage) { - labelString += '\nTexture Memory: ' + formatMemoryString(tile.content.texturesByteLength); - labelString += '\nGeometry Memory: ' + formatMemoryString(tile.content.geometryByteLength); - attributes += 2; - } - - if (tileset.debugShowUrl) { - labelString += '\nUrl: ' + tile._header.content.url; - attributes++; - } - - var newLabel = { - text : labelString.substring(1), - position : position, - font : (19-attributes) + 'px sans-serif', - showBackground : true, - disableDepthTestDistance : Number.POSITIVE_INFINITY - }; - - return tileset._tileDebugLabels.add(newLabel); - } - - function updateTileDebugLabels(tileset, frameState) { - var selectedTiles = tileset._selectedTiles; - var length = selectedTiles.length; - tileset._tileDebugLabels.removeAll(); - - if (tileset.debugPickedTileLabelOnly) { - if (defined(tileset.debugPickedTile)) { - var position = (defined(tileset.debugPickPosition)) ? tileset.debugPickPosition : computeTileLabelPosition(tileset.debugPickedTile); - var label = addTileDebugLabel(tileset.debugPickedTile, tileset, position); - label.pixelOffset = new Cartesian2(15, -15); // Offset to avoid picking the label. - } - } else { - for (var i = 0; i < length; ++i) { - var tile = selectedTiles[i]; - addTileDebugLabel(tile, tileset, computeTileLabelPosition(tile)); - } - } - tileset._tileDebugLabels.update(frameState); - } - - var stencilClearCommand = new ClearCommand({ - stencil : 0, - pass : Pass.CESIUM_3D_TILE - }); - - function updateTiles(tileset, frameState) { - tileset._styleEngine.applyStyle(tileset, frameState); - - var statistics = tileset._statistics; - var commandList = frameState.commandList; - var numberOfInitialCommands = commandList.length; - var selectedTiles = tileset._selectedTiles; - var length = selectedTiles.length; - var tileVisible = tileset.tileVisible; - var i; - - var bivariateVisibilityTest = tileset.skipLevelOfDetail && tileset._hasMixedContent && frameState.context.stencilBuffer && length > 0; - - tileset._backfaceCommands.length = 0; - - if (bivariateVisibilityTest) { - commandList.push(stencilClearCommand); - } - - var lengthBeforeUpdate = commandList.length; - for (i = 0; i < length; ++i) { - var tile = selectedTiles[i]; - // tiles may get unloaded and destroyed between selection and update - if (tile.selected) { - // Raise the tileVisible event before update in case the tileVisible event - // handler makes changes that update needs to apply to WebGL resources - tileVisible.raiseEvent(tile); - tile.update(tileset, frameState); - statistics.incrementSelectionCounts(tile.content); - ++statistics.selected; - } - } - var lengthAfterUpdate = commandList.length; - - tileset._backfaceCommands.trim(); - - if (bivariateVisibilityTest) { - /** - * Consider 'effective leaf' tiles as selected tiles that have no selected descendants. They may have children, - * but they are currently our effective leaves because they do not have selected descendants. These tiles - * are those where with tile._finalResolution === true. - * Let 'unresolved' tiles be those with tile._finalResolution === false. - * - * 1. Render just the backfaces of unresolved tiles in order to lay down z - * 2. Render all frontfaces wherever tile._selectionDepth > stencilBuffer. - * Replace stencilBuffer with tile._selectionDepth, when passing the z test. - * Because children are always drawn before ancestors {@link Cesium3DTilesetTraversal#traverseAndSelect}, - * this effectively draws children first and does not draw ancestors if a descendant has already - * been drawn at that pixel. - * Step 1 prevents child tiles from appearing on top when they are truly behind ancestor content. - * If they are behind the backfaces of the ancestor, then they will not be drawn. - * - * NOTE: Step 2 sometimes causes visual artifacts when backfacing child content has some faces that - * partially face the camera and are inside of the ancestor content. Because they are inside, they will - * not be culled by the depth writes in Step 1, and because they partially face the camera, the stencil tests - * will draw them on top of the ancestor content. - * - * NOTE: Because we always render backfaces of unresolved tiles, if the camera is looking at the backfaces - * of an object, they will always be drawn while loading, even if backface culling is enabled. - */ - - var backfaceCommands = tileset._backfaceCommands.values; - var addedCommandsLength = (lengthAfterUpdate - lengthBeforeUpdate); - var backfaceCommandsLength = backfaceCommands.length; - - commandList.length += backfaceCommandsLength; - - // copy commands to the back of the commandList - for (i = addedCommandsLength - 1; i >= 0; --i) { - commandList[lengthBeforeUpdate + backfaceCommandsLength + i] = commandList[lengthBeforeUpdate + i]; - } - - // move backface commands to the front of the commandList - for (i = 0; i < backfaceCommandsLength; ++i) { - commandList[lengthBeforeUpdate + i] = backfaceCommands[i]; - } - } - - // Number of commands added by each update above - statistics.numberOfCommands = (commandList.length - numberOfInitialCommands); - - if (tileset.debugShowGeometricError || tileset.debugShowRenderingStatistics || tileset.debugShowMemoryUsage || tileset.debugShowUrl) { - if (!defined(tileset._tileDebugLabels)) { - tileset._tileDebugLabels = new LabelCollection(); + that._subdomains = ['a', 'b', 'c']; } - updateTileDebugLabels(tileset, frameState); - } else { - tileset._tileDebugLabels = tileset._tileDebugLabels && tileset._tileDebugLabels.destroy(); - } - } - var scratchStack = []; + that._tileWidth = defaultValue(properties.tileWidth, 256); + that._tileHeight = defaultValue(properties.tileHeight, 256); + that._minimumLevel = defaultValue(properties.minimumLevel, 0); + that._maximumLevel = properties.maximumLevel; + that._tilingScheme = defaultValue(properties.tilingScheme, new WebMercatorTilingScheme({ ellipsoid : properties.ellipsoid })); + that._rectangle = defaultValue(properties.rectangle, that._tilingScheme.rectangle); + that._rectangle = Rectangle.intersection(that._rectangle, that._tilingScheme.rectangle); + that._hasAlphaChannel = defaultValue(properties.hasAlphaChannel, true); - function destroySubtree(tileset, tile) { - var root = tile; - var statistics = tileset._statistics; - var stack = scratchStack; - stack.push(tile); - while (stack.length > 0) { - tile = stack.pop(); - var children = tile.children; - var length = children.length; - for (var i = 0; i < length; ++i) { - stack.push(children[i]); - } - if (tile !== root) { - unloadTileFromCache(tileset, tile); - tile.destroy(); - --statistics.numberOfTilesTotal; + var credit = properties.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); } - } - root.children = []; - } - - function unloadTileFromCache(tileset, tile) { - var node = tile.replacementNode; - if (!defined(node)) { - return; - } - - var statistics = tileset._statistics; - var replacementList = tileset._replacementList; - var tileUnload = tileset.tileUnload; - - tileUnload.raiseEvent(tile); - replacementList.remove(node); - statistics.decrementLoadCounts(tile.content); - --statistics.numberOfTilesWithContentReady; - } - - function unloadTiles(tileset) { - var trimTiles = tileset._trimTiles; - tileset._trimTiles = false; - - var replacementList = tileset._replacementList; - - var totalMemoryUsageInBytes = tileset.totalMemoryUsageInBytes; - var maximumMemoryUsageInBytes = tileset._maximumMemoryUsage * 1024 * 1024; + that._credit = credit; - // Traverse the list only to the sentinel since tiles/nodes to the - // right of the sentinel were used this frame. - // - // The sub-list to the left of the sentinel is ordered from LRU to MRU. - var sentinel = tileset._replacementSentinel; - var node = replacementList.head; - while ((node !== sentinel) && ((totalMemoryUsageInBytes > maximumMemoryUsageInBytes) || trimTiles)) { - var tile = node.item; - node = node.next; - unloadTileFromCache(tileset, tile); - tile.unloadContent(); - totalMemoryUsageInBytes = tileset.totalMemoryUsageInBytes; - } - } + that._resource = resource; + that._tags = allTags; + that._pickFeaturesResource = pickFeaturesResource; + that._pickFeaturesTags = allPickFeaturesTags; - /** - * Unloads all tiles that weren't selected the previous frame. This can be used to - * explicitly manage the tile cache and reduce the total number of tiles loaded below - * {@link Cesium3DTileset#maximumMemoryUsage}. - * <p> - * Tile unloads occur at the next frame to keep all the WebGL delete calls - * within the render loop. - * </p> - */ - Cesium3DTileset.prototype.trimLoadedTiles = function() { - // Defer to next frame so WebGL delete calls happen inside the render loop - this._trimTiles = true; + return true; + }); }; - /////////////////////////////////////////////////////////////////////////// - - function raiseLoadProgressEvent(tileset, frameState) { - var statistics = tileset._statistics; - var statisticsLast = tileset._statisticsLastColor; - var numberOfPendingRequests = statistics.numberOfPendingRequests; - var numberOfTilesProcessing = statistics.numberOfTilesProcessing; - var lastNumberOfPendingRequest = statisticsLast.numberOfPendingRequests; - var lastNumberOfTilesProcessing = statisticsLast.numberOfTilesProcessing; - - var progressChanged = (numberOfPendingRequests !== lastNumberOfPendingRequest) || (numberOfTilesProcessing !== lastNumberOfTilesProcessing); - - if (progressChanged) { - frameState.afterRender.push(function() { - tileset.loadProgress.raiseEvent(numberOfPendingRequests, numberOfTilesProcessing); - }); - } - - tileset._tilesLoaded = (statistics.numberOfPendingRequests === 0) && (statistics.numberOfTilesProcessing === 0) && (statistics.numberOfAttemptedRequests === 0); - - if (progressChanged && tileset._tilesLoaded) { - frameState.afterRender.push(function() { - tileset.allTilesLoaded.raiseEvent(); - }); - } - } - - /////////////////////////////////////////////////////////////////////////// - /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> + * Gets the credits to be displayed when a given tile is displayed. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - Cesium3DTileset.prototype.update = function(frameState) { - if (frameState.mode === SceneMode.MORPHING) { - return; - } - - if (!this.show || !this.ready) { - return; - } - - if (!defined(this._loadTimestamp)) { - this._loadTimestamp = JulianDate.clone(frameState.time); - } - - this._timeSinceLoad = Math.max(JulianDate.secondsDifference(frameState.time, this._loadTimestamp) * 1000, 0.0); - - // Do not do out-of-core operations (new content requests, cache removal, - // process new tiles) during the pick pass. - var passes = frameState.passes; - var isPick = (passes.pick && !passes.render); - var outOfCore = !isPick; - - var statistics = this._statistics; - statistics.clear(); - - if (outOfCore) { - processTiles(this, frameState); - } - - if (this.dynamicScreenSpaceError) { - updateDynamicScreenSpaceError(this, frameState); - } - - Cesium3DTilesetTraversal.selectTiles(this, frameState, outOfCore); - requestTiles(this, outOfCore); - updateTiles(this, frameState); - - if (outOfCore) { - unloadTiles(this); + UrlTemplateImageryProvider.prototype.getTileCredits = function(x, y, level) { + if (!this.ready) { + throw new DeveloperError('getTileCredits must not be called before the imagery provider is ready.'); } - - // Events are raised (added to the afterRender queue) here since promises - // may resolve outside of the update loop that then raise events, e.g., - // model's readyPromise. - raiseLoadProgressEvent(this, frameState); - - // Update last statistics - var statisticsLast = isPick ? this._statisticsLastPick : this._statisticsLastColor; - Cesium3DTilesetStatistics.clone(statistics, statisticsLast); + return undefined; }; /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * Requests the image for a given tile. This function should + * not be called before {@link UrlTemplateImageryProvider#ready} returns true. * - * @see Cesium3DTileset#destroy + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. */ - Cesium3DTileset.prototype.isDestroyed = function() { - return false; + UrlTemplateImageryProvider.prototype.requestImage = function(x, y, level, request) { + if (!this.ready) { + throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); + } + return ImageryProvider.loadImage(this, buildImageResource(this, x, y, level, request)); }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @example - * tileset = tileset && tileset.destroy(); + * Asynchronously determines what features, if any, are located at a given longitude and latitude within + * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. * - * @see Cesium3DTileset#isDestroyed + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. */ - Cesium3DTileset.prototype.destroy = function() { - // Destroy debug labels - this._tileDebugLabels = this._tileDebugLabels && this._tileDebugLabels.destroy(); - - // Traverse the tree and destroy all tiles - if (defined(this._root)) { - var stack = scratchStack; - stack.push(this._root); - - while (stack.length > 0) { - var tile = stack.pop(); - tile.destroy(); - - var children = tile.children; - var length = children.length; - for (var i = 0; i < length; ++i) { - stack.push(children[i]); - } - } + UrlTemplateImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + if (!this.ready) { + throw new DeveloperError('pickFeatures must not be called before the imagery provider is ready.'); + } + + if (!this.enablePickFeatures || !defined(this._pickFeaturesResource) || this._getFeatureInfoFormats.length === 0) { + return undefined; } - this._root = undefined; - return destroyObject(this); - }; - - return Cesium3DTileset; -}); - -// JavaScript Expression Parser (JSEP) 0.3.1 -// JSEP may be freely distributed under the MIT License -// http://jsep.from.so/ - -define('ThirdParty/jsep',[],function() { - -/*global module: true, exports: true, console: true */ -(function (root) { - 'use strict'; - // Node Types - // ---------- - - // This is the full set of types that any JSEP node can be. - // Store them here to save space when minified - var COMPOUND = 'Compound', - IDENTIFIER = 'Identifier', - MEMBER_EXP = 'MemberExpression', - LITERAL = 'Literal', - THIS_EXP = 'ThisExpression', - CALL_EXP = 'CallExpression', - UNARY_EXP = 'UnaryExpression', - BINARY_EXP = 'BinaryExpression', - LOGICAL_EXP = 'LogicalExpression', - CONDITIONAL_EXP = 'ConditionalExpression', - ARRAY_EXP = 'ArrayExpression', - - PERIOD_CODE = 46, // '.' - COMMA_CODE = 44, // ',' - SQUOTE_CODE = 39, // single quote - DQUOTE_CODE = 34, // double quotes - OPAREN_CODE = 40, // ( - CPAREN_CODE = 41, // ) - OBRACK_CODE = 91, // [ - CBRACK_CODE = 93, // ] - QUMARK_CODE = 63, // ? - SEMCOL_CODE = 59, // ; - COLON_CODE = 58, // : - - throwError = function(message, index) { - var error = new Error(message + ' at character ' + index); - error.index = index; - error.description = message; - throw error; - }, - - // Operations - // ---------- - - // Set `t` to `true` to save space (when minified, not gzipped) - t = true, - // Use a quickly-accessible map to store all of the unary operators - // Values are set to `true` (it really doesn't matter) - unary_ops = {'-': t, '!': t, '~': t, '+': t}, - // Also use a map for the binary operations but set their values to their - // binary precedence for quick reference: - // see [Order of operations](http://en.wikipedia.org/wiki/Order_of_operations#Programming_language) - binary_ops = { - '||': 1, '&&': 2, '|': 3, '^': 4, '&': 5, - '==': 6, '!=': 6, '===': 6, '!==': 6, - '<': 7, '>': 7, '<=': 7, '>=': 7, - '<<':8, '>>': 8, '>>>': 8, - '+': 9, '-': 9, - '*': 10, '/': 10, '%': 10 - }, - // Get return the longest key length of any object - getMaxKeyLen = function(obj) { - var max_len = 0, len; - for(var key in obj) { - if((len = key.length) > max_len && obj.hasOwnProperty(key)) { - max_len = len; - } - } - return max_len; - }, - max_unop_len = getMaxKeyLen(unary_ops), - max_binop_len = getMaxKeyLen(binary_ops), - // Literals - // ---------- - // Store the values to return for the various literals we may encounter - literals = { - 'true': true, - 'false': false, - 'null': null - }, - // Except for `this`, which is special. This could be changed to something like `'self'` as well - this_str = 'this', - // Returns the precedence of a binary operator or `0` if it isn't a binary operator - binaryPrecedence = function(op_val) { - return binary_ops[op_val] || 0; - }, - // Utility function (gets called from multiple places) - // Also note that `a && b` and `a || b` are *logical* expressions, not binary expressions - createBinaryExpression = function (operator, left, right) { - var type = (operator === '||' || operator === '&&') ? LOGICAL_EXP : BINARY_EXP; - return { - type: type, - operator: operator, - left: left, - right: right - }; - }, - // `ch` is a character code in the next three functions - isDecimalDigit = function(ch) { - return (ch >= 48 && ch <= 57); // 0...9 - }, - isIdentifierStart = function(ch) { - return (ch === 36) || (ch === 95) || // `$` and `_` - (ch >= 65 && ch <= 90) || // A...Z - (ch >= 97 && ch <= 122) || // a...z - (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator - }, - isIdentifierPart = function(ch) { - return (ch === 36) || (ch === 95) || // `$` and `_` - (ch >= 65 && ch <= 90) || // A...Z - (ch >= 97 && ch <= 122) || // a...z - (ch >= 48 && ch <= 57) || // 0...9 - (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator - }, - - // Parsing - // ------- - // `expr` is a string with the passed in expression - jsep = function(expr) { - // `index` stores the character number we are currently at while `length` is a constant - // All of the gobbles below will modify `index` as we move along - var index = 0, - charAtFunc = expr.charAt, - charCodeAtFunc = expr.charCodeAt, - exprI = function(i) { return charAtFunc.call(expr, i); }, - exprICode = function(i) { return charCodeAtFunc.call(expr, i); }, - length = expr.length, - - // Push `index` up to the next non-space character - gobbleSpaces = function() { - var ch = exprICode(index); - // space or tab - while(ch === 32 || ch === 9) { - ch = exprICode(++index); - } - }, - - // The main parsing function. Much of this code is dedicated to ternary expressions - gobbleExpression = function() { - var test = gobbleBinaryExpression(), - consequent, alternate; - gobbleSpaces(); - if(exprICode(index) === QUMARK_CODE) { - // Ternary expression: test ? consequent : alternate - index++; - consequent = gobbleExpression(); - if(!consequent) { - throwError('Expected expression', index); - } - gobbleSpaces(); - if(exprICode(index) === COLON_CODE) { - index++; - alternate = gobbleExpression(); - if(!alternate) { - throwError('Expected expression', index); - } - return { - type: CONDITIONAL_EXP, - test: test, - consequent: consequent, - alternate: alternate - }; - } else { - throwError('Expected :', index); - } - } else { - return test; - } - }, - - // Search for the operation portion of the string (e.g. `+`, `===`) - // Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`) - // and move down from 3 to 2 to 1 character until a matching binary operation is found - // then, return that binary operation - gobbleBinaryOp = function() { - gobbleSpaces(); - var biop, to_check = expr.substr(index, max_binop_len), tc_len = to_check.length; - while(tc_len > 0) { - if(binary_ops.hasOwnProperty(to_check)) { - index += tc_len; - return to_check; - } - to_check = to_check.substr(0, --tc_len); - } - return false; - }, - - // This function is responsible for gobbling an individual expression, - // e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)` - gobbleBinaryExpression = function() { - var ch_i, node, biop, prec, stack, biop_info, left, right, i; + var formatIndex = 0; - // First, try to get the leftmost thing - // Then, check to see if there's a binary operator operating on that leftmost thing - left = gobbleToken(); - biop = gobbleBinaryOp(); + var that = this; - // If there wasn't a binary operator, just return the leftmost node - if(!biop) { - return left; - } + function handleResponse(format, data) { + return format.callback(data); + } - // Otherwise, we need to start a stack to properly place the binary operations in their - // precedence structure - biop_info = { value: biop, prec: binaryPrecedence(biop)}; + function doRequest() { + if (formatIndex >= that._getFeatureInfoFormats.length) { + // No valid formats, so no features picked. + return when([]); + } - right = gobbleToken(); - if(!right) { - throwError("Expected expression after " + biop, index); - } - stack = [left, biop_info, right]; + var format = that._getFeatureInfoFormats[formatIndex]; + var resource = buildPickFeaturesResource(that, x, y, level, longitude, latitude, format.format); - // Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm) - while((biop = gobbleBinaryOp())) { - prec = binaryPrecedence(biop); + ++formatIndex; - if(prec === 0) { - break; - } - biop_info = { value: biop, prec: prec }; + if (format.type === 'json') { + return resource.fetchJson().then(format.callback).otherwise(doRequest); + } else if (format.type === 'xml') { + return resource.fetchXML().then(format.callback).otherwise(doRequest); + } else if (format.type === 'text' || format.type === 'html') { + return resource.fetchText().then(format.callback).otherwise(doRequest); + } + return resource.fetch({ + responseType: format.format + }).then(handleResponse.bind(undefined, format)).otherwise(doRequest); + } - // Reduce: make a binary expression from the three topmost entries. - while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { - right = stack.pop(); - biop = stack.pop().value; - left = stack.pop(); - node = createBinaryExpression(biop, left, right); - stack.push(node); - } + return doRequest(); + }; - node = gobbleToken(); - if(!node) { - throwError("Expected expression after " + biop, index); - } - stack.push(biop_info, node); - } + var degreesScratchComputed = false; + var degreesScratch = new Rectangle(); + var projectedScratchComputed = false; + var projectedScratch = new Rectangle(); - i = stack.length - 1; - node = stack[i]; - while(i > 1) { - node = createBinaryExpression(stack[i - 1].value, stack[i - 2], node); - i -= 2; - } - return node; - }, + function buildImageResource(imageryProvider, x, y, level, request) { + degreesScratchComputed = false; + projectedScratchComputed = false; - // An individual part of a binary expression: - // e.g. `foo.bar(baz)`, `1`, `"abc"`, `(a % 2)` (because it's in parenthesis) - gobbleToken = function() { - var ch, to_check, tc_len; + var resource = imageryProvider._resource; + var url = resource.getUrlComponent(true); + var allTags = imageryProvider._tags; + var templateValues = {}; - gobbleSpaces(); - ch = exprICode(index); + var match = url.match(templateRegex); + if (defined(match)) { + match.forEach(function(tag) { + var key = tag.substring(1, tag.length - 1); //strip {} + if (defined(allTags[key])) { + templateValues[key] = allTags[key](imageryProvider, x, y, level); + } + }); + } - if(isDecimalDigit(ch) || ch === PERIOD_CODE) { - // Char code 46 is a dot `.` which can start off a numeric literal - return gobbleNumericLiteral(); - } else if(ch === SQUOTE_CODE || ch === DQUOTE_CODE) { - // Single or double quotes - return gobbleStringLiteral(); - } else if(isIdentifierStart(ch) || ch === OPAREN_CODE) { // open parenthesis - // `foo`, `bar.baz` - return gobbleVariable(); - } else if (ch === OBRACK_CODE) { - return gobbleArray(); - } else { - to_check = expr.substr(index, max_unop_len); - tc_len = to_check.length; - while(tc_len > 0) { - if(unary_ops.hasOwnProperty(to_check)) { - index += tc_len; - return { - type: UNARY_EXP, - operator: to_check, - argument: gobbleToken(), - prefix: true - }; - } - to_check = to_check.substr(0, --tc_len); - } + return resource.getDerivedResource({ + request: request, + templateValues: templateValues + }); + } - return false; - } - }, - // Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to - // keep track of everything in the numeric literal and then calling `parseFloat` on that string - gobbleNumericLiteral = function() { - var number = '', ch, chCode; - while(isDecimalDigit(exprICode(index))) { - number += exprI(index++); - } + var ijScratchComputed = false; + var ijScratch = new Cartesian2(); + var longitudeLatitudeProjectedScratchComputed = false; - if(exprICode(index) === PERIOD_CODE) { // can start with a decimal marker - number += exprI(index++); + function buildPickFeaturesResource(imageryProvider, x, y, level, longitude, latitude, format) { + degreesScratchComputed = false; + projectedScratchComputed = false; + ijScratchComputed = false; + longitudeLatitudeProjectedScratchComputed = false; - while(isDecimalDigit(exprICode(index))) { - number += exprI(index++); - } - } + var resource = imageryProvider._pickFeaturesResource; + var url = resource.getUrlComponent(true); + var allTags = imageryProvider._pickFeaturesTags; + var templateValues = {}; + var match = url.match(templateRegex); + if (defined(match)) { + match.forEach(function(tag) { + var key = tag.substring(1, tag.length - 1); //strip {} + if (defined(allTags[key])) { + templateValues[key] = allTags[key](imageryProvider, x, y, level, longitude, latitude, format); + } + }); + } - ch = exprI(index); - if(ch === 'e' || ch === 'E') { // exponent marker - number += exprI(index++); - ch = exprI(index); - if(ch === '+' || ch === '-') { // exponent sign - number += exprI(index++); - } - while(isDecimalDigit(exprICode(index))) { //exponent itself - number += exprI(index++); - } - if(!isDecimalDigit(exprICode(index-1)) ) { - throwError('Expected exponent (' + number + exprI(index) + ')', index); - } - } + return resource.getDerivedResource({ + templateValues: templateValues + }); + } + function padWithZerosIfNecessary(imageryProvider, key, value) { + if (imageryProvider && + imageryProvider.urlSchemeZeroPadding && + imageryProvider.urlSchemeZeroPadding.hasOwnProperty(key) ) + { + var paddingTemplate = imageryProvider.urlSchemeZeroPadding[key]; + if (typeof paddingTemplate === 'string') { + var paddingTemplateWidth = paddingTemplate.length; + if (paddingTemplateWidth > 1) { + value = (value.length >= paddingTemplateWidth) ? value : new Array(paddingTemplateWidth - value.toString().length + 1).join('0') + value; + } + } + } + return value; + } - chCode = exprICode(index); - // Check to make sure this isn't a variable name that start with a number (123abc) - if(isIdentifierStart(chCode)) { - throwError('Variable names cannot start with a number (' + - number + exprI(index) + ')', index); - } else if(chCode === PERIOD_CODE) { - throwError('Unexpected period', index); - } + function xTag(imageryProvider, x, y, level) { + return padWithZerosIfNecessary(imageryProvider, '{x}', x); + } - return { - type: LITERAL, - value: parseFloat(number), - raw: number - }; - }, + function reverseXTag(imageryProvider, x, y, level) { + var reverseX = imageryProvider.tilingScheme.getNumberOfXTilesAtLevel(level) - x - 1; + return padWithZerosIfNecessary(imageryProvider, '{reverseX}', reverseX); + } - // Parses a string literal, staring with single or double quotes with basic support for escape codes - // e.g. `"hello world"`, `'this is\nJSEP'` - gobbleStringLiteral = function() { - var str = '', quote = exprI(index++), closed = false, ch; + function yTag(imageryProvider, x, y, level) { + return padWithZerosIfNecessary(imageryProvider, '{y}', y); + } - while(index < length) { - ch = exprI(index++); - if(ch === quote) { - closed = true; - break; - } else if(ch === '\\') { - // Check for all of the common escape codes - ch = exprI(index++); - switch(ch) { - case 'n': str += '\n'; break; - case 'r': str += '\r'; break; - case 't': str += '\t'; break; - case 'b': str += '\b'; break; - case 'f': str += '\f'; break; - case 'v': str += '\x0B'; break; - default : str += '\\' + ch; - } - } else { - str += ch; - } - } + function reverseYTag(imageryProvider, x, y, level) { + var reverseY = imageryProvider.tilingScheme.getNumberOfYTilesAtLevel(level) - y - 1; + return padWithZerosIfNecessary(imageryProvider, '{reverseY}', reverseY); + } - if(!closed) { - throwError('Unclosed quote after "'+str+'"', index); - } + function reverseZTag(imageryProvider, x, y, level) { + var maximumLevel = imageryProvider.maximumLevel; + var reverseZ = defined(maximumLevel) && level < maximumLevel ? maximumLevel - level - 1 : level; + return padWithZerosIfNecessary(imageryProvider, '{reverseZ}', reverseZ); + } - return { - type: LITERAL, - value: str, - raw: quote + str + quote - }; - }, + function zTag(imageryProvider, x, y, level) { + return padWithZerosIfNecessary(imageryProvider, '{z}', level); + } - // Gobbles only identifiers - // e.g.: `foo`, `_value`, `$x1` - // Also, this function checks if that identifier is a literal: - // (e.g. `true`, `false`, `null`) or `this` - gobbleIdentifier = function() { - var ch = exprICode(index), start = index, identifier; + function sTag(imageryProvider, x, y, level) { + var index = (x + y + level) % imageryProvider._subdomains.length; + return imageryProvider._subdomains[index]; + } - if(isIdentifierStart(ch)) { - index++; - } else { - throwError('Unexpected ' + exprI(index), index); - } + function computeDegrees(imageryProvider, x, y, level) { + if (degreesScratchComputed) { + return; + } - while(index < length) { - ch = exprICode(index); - if(isIdentifierPart(ch)) { - index++; - } else { - break; - } - } - identifier = expr.slice(start, index); + imageryProvider.tilingScheme.tileXYToRectangle(x, y, level, degreesScratch); + degreesScratch.west = CesiumMath.toDegrees(degreesScratch.west); + degreesScratch.south = CesiumMath.toDegrees(degreesScratch.south); + degreesScratch.east = CesiumMath.toDegrees(degreesScratch.east); + degreesScratch.north = CesiumMath.toDegrees(degreesScratch.north); - if(literals.hasOwnProperty(identifier)) { - return { - type: LITERAL, - value: literals[identifier], - raw: identifier - }; - } else if(identifier === this_str) { - return { type: THIS_EXP }; - } else { - return { - type: IDENTIFIER, - name: identifier - }; - } - }, + degreesScratchComputed = true; + } - // Gobbles a list of arguments within the context of a function call - // or array literal. This function also assumes that the opening character - // `(` or `[` has already been gobbled, and gobbles expressions and commas - // until the terminator character `)` or `]` is encountered. - // e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]` - gobbleArguments = function(termination) { - var ch_i, args = [], node, closed = false; - while(index < length) { - gobbleSpaces(); - ch_i = exprICode(index); - if(ch_i === termination) { // done parsing - closed = true; - index++; - break; - } else if (ch_i === COMMA_CODE) { // between expressions - index++; - } else { - node = gobbleExpression(); - if(!node || node.type === COMPOUND) { - throwError('Expected comma', index); - } - args.push(node); - } - } - if (!closed) { - throwError('Expected ' + String.fromCharCode(termination), index); - } - return args; - }, + function westDegreesTag(imageryProvider, x, y, level) { + computeDegrees(imageryProvider, x, y, level); + return degreesScratch.west; + } - // Gobble a non-literal variable name. This variable name may include properties - // e.g. `foo`, `bar.baz`, `foo['bar'].baz` - // It also gobbles function calls: - // e.g. `Math.acos(obj.angle)` - gobbleVariable = function() { - var ch_i, node; - ch_i = exprICode(index); + function southDegreesTag(imageryProvider, x, y, level) { + computeDegrees(imageryProvider, x, y, level); + return degreesScratch.south; + } - if(ch_i === OPAREN_CODE) { - node = gobbleGroup(); - } else { - node = gobbleIdentifier(); - } - gobbleSpaces(); - ch_i = exprICode(index); - while(ch_i === PERIOD_CODE || ch_i === OBRACK_CODE || ch_i === OPAREN_CODE) { - index++; - if(ch_i === PERIOD_CODE) { - gobbleSpaces(); - node = { - type: MEMBER_EXP, - computed: false, - object: node, - property: gobbleIdentifier() - }; - } else if(ch_i === OBRACK_CODE) { - node = { - type: MEMBER_EXP, - computed: true, - object: node, - property: gobbleExpression() - }; - gobbleSpaces(); - ch_i = exprICode(index); - if(ch_i !== CBRACK_CODE) { - throwError('Unclosed [', index); - } - index++; - } else if(ch_i === OPAREN_CODE) { - // A function call is being made; gobble all the arguments - node = { - type: CALL_EXP, - 'arguments': gobbleArguments(CPAREN_CODE), - callee: node - }; - } - gobbleSpaces(); - ch_i = exprICode(index); - } - return node; - }, + function eastDegreesTag(imageryProvider, x, y, level) { + computeDegrees(imageryProvider, x, y, level); + return degreesScratch.east; + } - // Responsible for parsing a group of things within parentheses `()` - // This function assumes that it needs to gobble the opening parenthesis - // and then tries to gobble everything within that parenthesis, assuming - // that the next thing it should see is the close parenthesis. If not, - // then the expression probably doesn't have a `)` - gobbleGroup = function() { - index++; - var node = gobbleExpression(); - gobbleSpaces(); - if(exprICode(index) === CPAREN_CODE) { - index++; - return node; - } else { - throwError('Unclosed (', index); - } - }, + function northDegreesTag(imageryProvider, x, y, level) { + computeDegrees(imageryProvider, x, y, level); + return degreesScratch.north; + } - // Responsible for parsing Array literals `[1, 2, 3]` - // This function assumes that it needs to gobble the opening bracket - // and then tries to gobble the expressions as arguments. - gobbleArray = function() { - index++; - return { - type: ARRAY_EXP, - elements: gobbleArguments(CBRACK_CODE) - }; - }, + function computeProjected(imageryProvider, x, y, level) { + if (projectedScratchComputed) { + return; + } - nodes = [], ch_i, node; + imageryProvider.tilingScheme.tileXYToNativeRectangle(x, y, level, projectedScratch); - while(index < length) { - ch_i = exprICode(index); + projectedScratchComputed = true; + } - // Expressions can be separated by semicolons, commas, or just inferred without any - // separators - if(ch_i === SEMCOL_CODE || ch_i === COMMA_CODE) { - index++; // ignore separators - } else { - // Try to gobble each expression individually - if((node = gobbleExpression())) { - nodes.push(node); - // If we weren't able to find a binary expression and are out of room, then - // the expression passed in probably has too much - } else if(index < length) { - throwError('Unexpected "' + exprI(index) + '"', index); - } - } - } + function westProjectedTag(imageryProvider, x, y, level) { + computeProjected(imageryProvider, x, y, level); + return projectedScratch.west; + } - // If there's only one expression just try returning the expression - if(nodes.length === 1) { - return nodes[0]; - } else { - return { - type: COMPOUND, - body: nodes - }; - } - }; + function southProjectedTag(imageryProvider, x, y, level) { + computeProjected(imageryProvider, x, y, level); + return projectedScratch.south; + } - // To be filled in by the template - jsep.version = '0.3.1'; - jsep.toString = function() { return 'JavaScript Expression Parser (JSEP) v' + jsep.version; }; + function eastProjectedTag(imageryProvider, x, y, level) { + computeProjected(imageryProvider, x, y, level); + return projectedScratch.east; + } - /** - * @method jsep.addUnaryOp - * @param {string} op_name The name of the unary op to add - * @return jsep - */ - jsep.addUnaryOp = function(op_name) { - max_unop_len = Math.max(op_name.length, max_unop_len); - unary_ops[op_name] = t; return this; - }; + function northProjectedTag(imageryProvider, x, y, level) { + computeProjected(imageryProvider, x, y, level); + return projectedScratch.north; + } - /** - * @method jsep.addBinaryOp - * @param {string} op_name The name of the binary op to add - * @param {number} precedence The precedence of the binary op (can be a float) - * @return jsep - */ - jsep.addBinaryOp = function(op_name, precedence) { - max_binop_len = Math.max(op_name.length, max_binop_len); - binary_ops[op_name] = precedence; - return this; - }; + function widthTag(imageryProvider, x, y, level) { + return imageryProvider.tileWidth; + } - /** - * @method jsep.addLiteral - * @param {string} literal_name The name of the literal to add - * @param {*} literal_value The value of the literal - * @return jsep - */ - jsep.addLiteral = function(literal_name, literal_value) { - literals[literal_name] = literal_value; - return this; - }; + function heightTag(imageryProvider, x, y, level) { + return imageryProvider.tileHeight; + } - /** - * @method jsep.removeUnaryOp - * @param {string} op_name The name of the unary op to remove - * @return jsep - */ - jsep.removeUnaryOp = function(op_name) { - delete unary_ops[op_name]; - if(op_name.length === max_unop_len) { - max_unop_len = getMaxKeyLen(unary_ops); - } - return this; - }; + function iTag(imageryProvider, x, y, level, longitude, latitude, format) { + computeIJ(imageryProvider, x, y, level, longitude, latitude); + return ijScratch.x; + } - /** - * @method jsep.removeAllUnaryOps - * @return jsep - */ - jsep.removeAllUnaryOps = function() { - unary_ops = {}; - max_unop_len = 0; + function jTag(imageryProvider, x, y, level, longitude, latitude, format) { + computeIJ(imageryProvider, x, y, level, longitude, latitude); + return ijScratch.y; + } - return this; - }; + function reverseITag(imageryProvider, x, y, level, longitude, latitude, format) { + computeIJ(imageryProvider, x, y, level, longitude, latitude); + return imageryProvider.tileWidth - ijScratch.x - 1; + } - /** - * @method jsep.removeBinaryOp - * @param {string} op_name The name of the binary op to remove - * @return jsep - */ - jsep.removeBinaryOp = function(op_name) { - delete binary_ops[op_name]; - if(op_name.length === max_binop_len) { - max_binop_len = getMaxKeyLen(binary_ops); - } - return this; - }; + function reverseJTag(imageryProvider, x, y, level, longitude, latitude, format) { + computeIJ(imageryProvider, x, y, level, longitude, latitude); + return imageryProvider.tileHeight - ijScratch.y - 1; + } - /** - * @method jsep.removeAllBinaryOps - * @return jsep - */ - jsep.removeAllBinaryOps = function() { - binary_ops = {}; - max_binop_len = 0; + var rectangleScratch = new Rectangle(); + var longitudeLatitudeProjectedScratch = new Cartesian3(); - return this; - }; + function computeIJ(imageryProvider, x, y, level, longitude, latitude, format) { + if (ijScratchComputed) { + return; + } - /** - * @method jsep.removeLiteral - * @param {string} literal_name The name of the literal to remove - * @return jsep - */ - jsep.removeLiteral = function(literal_name) { - delete literals[literal_name]; - return this; - }; + computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude); + var projected = longitudeLatitudeProjectedScratch; - /** - * @method jsep.removeAllLiterals - * @return jsep - */ - jsep.removeAllLiterals = function() { - literals = {}; + var rectangle = imageryProvider.tilingScheme.tileXYToNativeRectangle(x, y, level, rectangleScratch); + ijScratch.x = (imageryProvider.tileWidth * (projected.x - rectangle.west) / rectangle.width) | 0; + ijScratch.y = (imageryProvider.tileHeight * (rectangle.north - projected.y) / rectangle.height) | 0; + ijScratchComputed = true; + } - return this; - }; + function longitudeDegreesTag(imageryProvider, x, y, level, longitude, latitude, format) { + return CesiumMath.toDegrees(longitude); + } - // In desktop environments, have a way to restore the old value for `jsep` - if (typeof exports === 'undefined') { - var old_jsep = root.jsep; - // The star of the show! It's a function! - root.jsep = jsep; - // And a courteous function willing to move out of the way for other similarly-named objects! - jsep.noConflict = function() { - if(root.jsep === jsep) { - root.jsep = old_jsep; - } - return jsep; - }; - } else { - // In Node.JS environments - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = jsep; - } else { - exports.parse = jsep; - } - } -}(this)); + function latitudeDegreesTag(imageryProvider, x, y, level, longitude, latitude, format) { + return CesiumMath.toDegrees(latitude); + } - // `jsep` only exists when running in the browser - if (typeof jsep !== 'undefined') { - return jsep.noConflict(); + function longitudeProjectedTag(imageryProvider, x, y, level, longitude, latitude, format) { + computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude); + return longitudeLatitudeProjectedScratch.x; } -}); -define('Scene/ExpressionNodeType',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + function latitudeProjectedTag(imageryProvider, x, y, level, longitude, latitude, format) { + computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude); + return longitudeLatitudeProjectedScratch.y; + } - /** - * @private - */ - var ExpressionNodeType = { - VARIABLE : 0, - UNARY : 1, - BINARY : 2, - TERNARY : 3, - CONDITIONAL : 4, - MEMBER : 5, - FUNCTION_CALL : 6, - ARRAY : 7, - REGEX: 8, - VARIABLE_IN_STRING : 9, - LITERAL_NULL : 10, - LITERAL_BOOLEAN : 11, - LITERAL_NUMBER : 12, - LITERAL_STRING : 13, - LITERAL_COLOR : 14, - LITERAL_VECTOR : 15, - LITERAL_REGEX : 16, - LITERAL_UNDEFINED : 17, - BUILTIN_VARIABLE : 18 - }; + var cartographicScratch = new Cartographic(); - return freezeObject(ExpressionNodeType); + function computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude, format) { + if (longitudeLatitudeProjectedScratchComputed) { + return; + } + + if (imageryProvider.tilingScheme instanceof GeographicTilingScheme) { + longitudeLatitudeProjectedScratch.x = CesiumMath.toDegrees(longitude); + longitudeLatitudeProjectedScratch.y = CesiumMath.toDegrees(latitude); + } else { + var cartographic = cartographicScratch; + cartographic.longitude = longitude; + cartographic.latitude = latitude; + imageryProvider.tilingScheme.projection.project(cartographic, longitudeLatitudeProjectedScratch); + } + + longitudeLatitudeProjectedScratchComputed = true; + } + + function formatTag(imageryProvider, x, y, level, longitude, latitude, format) { + return format; + } + + return UrlTemplateImageryProvider; }); -define('Scene/Expression',[ +define('Scene/createTileMapServiceImageryProvider',[ '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Check', - '../Core/Color', + '../Core/Cartographic', + '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/DeveloperError', - '../Core/isArray', - '../Core/Math', + '../Core/GeographicTilingScheme', + '../Core/Rectangle', + '../Core/Resource', '../Core/RuntimeError', - '../ThirdParty/jsep', - './ExpressionNodeType' + '../Core/TileProviderError', + '../Core/WebMercatorTilingScheme', + '../ThirdParty/when', + './UrlTemplateImageryProvider' ], function( Cartesian2, - Cartesian3, - Cartesian4, - Check, - Color, + Cartographic, + defaultValue, defined, - defineProperties, + deprecationWarning, DeveloperError, - isArray, - CesiumMath, + GeographicTilingScheme, + Rectangle, + Resource, RuntimeError, - jsep, - ExpressionNodeType) { + TileProviderError, + WebMercatorTilingScheme, + when, + UrlTemplateImageryProvider) { 'use strict'; /** - * An expression for a style applied to a {@link Cesium3DTileset}. - * <p> - * Evaluates an expression defined using the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. - * </p> - * <p> - * Implements the {@link StyleExpression} interface. - * </p> + * Creates a {@link UrlTemplateImageryProvider} instance that provides tiled imagery as generated by + * {@link http://www.maptiler.org/'>MapTiler</a> / <a href='http://www.klokan.cz/projects/gdal2tiles/|GDDAL2Tiles} etc. * - * @alias Expression - * @constructor + * @exports createTileMapServiceImageryProvider * - * @param {String} [expression] The expression defined using the 3D Tiles Styling language. - * @param {Object} [defines] Defines in the style. + * @param {Object} [options] Object with the following properties: + * @param {Resource|String} [options.url='.'] Path to image tiles on server. + * @param {String} [options.fileExtension='png'] The file extension for images on the server. + * @param {Credit|String} [options.credit=''] A credit for the data source, which is displayed on the canvas. + * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely + * to result in rendering problems. + * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. + * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal + * surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme} + * is used. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * @param {Number} [options.tileWidth=256] Pixel width of image tiles. + * @param {Number} [options.tileHeight=256] Pixel height of image tiles. + * @param {Boolean} [options.flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml. + * Specifying this option will do the same, allowing for loading of these incorrect tilesets. + * @returns {UrlTemplateImageryProvider} The imagery provider. * - * @example - * var expression = new Cesium.Expression('(regExp("^Chest").test(${County})) && (${YearBuilt} >= 1970)'); - * expression.evaluate(frameState, feature); // returns true or false depending on the feature's properties + * @see ArcGisMapServerImageryProvider + * @see BingMapsImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + * + * @see {@link http://www.maptiler.org/|MapTiler} + * @see {@link http://www.klokan.cz/projects/gdal2tiles/|GDDAL2Tiles} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * * @example - * var expression = new Cesium.Expression('(${Temperature} > 90) ? color("red") : color("white")'); - * expression.evaluateColor(frameState, feature, result); // returns a Cesium.Color object + * var tms = Cesium.createTileMapServiceImageryProvider({ + * url : '../images/cesium_maptiler/Cesium_Logo_Color', + * fileExtension: 'png', + * maximumLevel: 4, + * rectangle: new Cesium.Rectangle( + * Cesium.Math.toRadians(-120.0), + * Cesium.Math.toRadians(20.0), + * Cesium.Math.toRadians(-60.0), + * Cesium.Math.toRadians(40.0)) + * }); */ - function Expression(expression, defines) { - Check.typeOf.string('expression', expression); - - this._expression = expression; - expression = replaceDefines(expression, defines); - expression = replaceVariables(removeBackslashes(expression)); - - // customize jsep operators - jsep.addBinaryOp('=~', 0); - jsep.addBinaryOp('!~', 0); - - var ast; - try { - ast = jsep(expression); - } catch (e) { - throw new RuntimeError(e); - } - - this._runtimeAst = createRuntimeAst(this, ast); - } - - defineProperties(Expression.prototype, { - /** - * Gets the expression defined in the 3D Tiles Styling language. - * - * @memberof Expression.prototype - * - * @type {String} - * @readonly - * - * @default undefined - */ - expression : { - get : function() { - return this._expression; - } - } - }); - - // Scratch storage manager while evaluating deep expressions. - // For example, an expression like dot(vec4(${red}), vec4(${green}) * vec4(${blue}) requires 3 scratch Cartesian4's - var scratchStorage = { - arrayIndex : 0, - arrayArray : [[]], - cartesian2Index : 0, - cartesian3Index : 0, - cartesian4Index : 0, - cartesian2Array : [new Cartesian2()], - cartesian3Array : [new Cartesian3()], - cartesian4Array : [new Cartesian4()], - reset : function() { - this.arrayIndex = 0; - this.cartesian2Index = 0; - this.cartesian3Index = 0; - this.cartesian4Index = 0; - }, - getArray : function() { - if (this.arrayIndex >= this.arrayArray.length) { - this.arrayArray.push([]); - } - var array = this.arrayArray[this.arrayIndex++]; - array.length = 0; - return array; - }, - getCartesian2 : function() { - if (this.cartesian2Index >= this.cartesian2Array.length) { - this.cartesian2Array.push(new Cartesian2()); - } - return this.cartesian2Array[this.cartesian2Index++]; - }, - getCartesian3 : function() { - if (this.cartesian3Index >= this.cartesian3Array.length) { - this.cartesian3Array.push(new Cartesian3()); - } - return this.cartesian3Array[this.cartesian3Index++]; - }, - getCartesian4 : function() { - if (this.cartesian4Index >= this.cartesian4Array.length) { - this.cartesian4Array.push(new Cartesian4()); - } - return this.cartesian4Array[this.cartesian4Index++]; - } - }; + function createTileMapServiceImageryProvider(options) { + options = defaultValue(options, {}); - /** - * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of - * the expression in the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} - * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript - * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code> - * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>, - * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is - * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. - * - * @param {FrameState} frameState The frame state. - * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Object} [result] The object onto which to store the result. - * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. - */ - Expression.prototype.evaluate = function(frameState, feature, result) { - scratchStorage.reset(); - var value = this._runtimeAst.evaluate(frameState, feature); - if ((result instanceof Color) && (value instanceof Cartesian4)) { - return Color.fromCartesian4(value, result); + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); } - if ((value instanceof Cartesian2) || (value instanceof Cartesian3) || (value instanceof Cartesian4)) { - return value.clone(result); + + if (defined(options.proxy)) { + deprecationWarning('createTileMapServiceImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - return value; - }; - - /** - * Evaluates the result of a Color expression, optionally using the provided feature's properties. - * <p> - * This is equivalent to {@link Expression#evaluate} but always returns a {@link Color} object. - * </p> - * - * @param {FrameState} frameState The frame state. - * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Color} [result] The object in which to store the result - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. - */ - Expression.prototype.evaluateColor = function(frameState, feature, result) { - scratchStorage.reset(); - var color = this._runtimeAst.evaluate(frameState, feature); - return Color.fromCartesian4(color, result); - }; - - /** - * Gets the shader function for this expression. - * Returns undefined if the shader function can't be generated from this expression. - * - * @param {String} functionName Name to give to the generated function. - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * @param {String} returnType The return type of the generated function. - * - * @returns {String} The shader function. - * - * @private - */ - Expression.prototype.getShaderFunction = function(functionName, attributePrefix, shaderState, returnType) { - var shaderExpression = this.getShaderExpression(attributePrefix, shaderState); - - shaderExpression = returnType + ' ' + functionName + '() \n' + - '{ \n' + - ' return ' + shaderExpression + '; \n' + - '} \n'; - - return shaderExpression; - }; - - /** - * Gets the shader expression for this expression. - * Returns undefined if the shader expression can't be generated from this expression. - * - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * - * @returns {String} The shader expression. - * - * @private - */ - Expression.prototype.getShaderExpression = function(attributePrefix, shaderState) { - return this._runtimeAst.getShaderExpression(attributePrefix, shaderState); - }; - - var unaryOperators = ['!', '-', '+']; - var binaryOperators = ['+', '-', '*', '/', '%', '===', '!==', '>', '>=', '<', '<=', '&&', '||', '!~', '=~']; - var variableRegex = /\${(.*?)}/g; // Matches ${variable_name} - var backslashRegex = /\\/g; - var backslashReplacement = '@#%'; - var replacementRegex = /@#%/g; - - var scratchColor = new Color(); + var resource = Resource.createIfNeeded(options.url, { + proxy : options.proxy + }); + resource.appendForwardSlash(); - var unaryFunctions = { - abs : getEvaluateUnaryComponentwise(Math.abs), - sqrt : getEvaluateUnaryComponentwise(Math.sqrt), - cos : getEvaluateUnaryComponentwise(Math.cos), - sin : getEvaluateUnaryComponentwise(Math.sin), - tan : getEvaluateUnaryComponentwise(Math.tan), - acos : getEvaluateUnaryComponentwise(Math.acos), - asin : getEvaluateUnaryComponentwise(Math.asin), - atan : getEvaluateUnaryComponentwise(Math.atan), - radians : getEvaluateUnaryComponentwise(CesiumMath.toRadians), - degrees : getEvaluateUnaryComponentwise(CesiumMath.toDegrees), - sign : getEvaluateUnaryComponentwise(CesiumMath.sign), - floor : getEvaluateUnaryComponentwise(Math.floor), - ceil : getEvaluateUnaryComponentwise(Math.ceil), - round : getEvaluateUnaryComponentwise(Math.round), - exp : getEvaluateUnaryComponentwise(Math.exp), - exp2 : getEvaluateUnaryComponentwise(exp2), - log : getEvaluateUnaryComponentwise(Math.log), - log2 : getEvaluateUnaryComponentwise(log2), - fract : getEvaluateUnaryComponentwise(fract), - length : length, - normalize: normalize - }; + var xmlResource = resource.getDerivedResource({ + url: 'tilemapresource.xml' + }); - var binaryFunctions = { - atan2 : getEvaluateBinaryCommponentwise(Math.atan2, false), - pow : getEvaluateBinaryCommponentwise(Math.pow, false), - min : getEvaluateBinaryCommponentwise(Math.min, true), - max : getEvaluateBinaryCommponentwise(Math.max, true), - distance : distance, - dot : dot, - cross : cross - }; + var deferred = when.defer(); + var imageryProvider = new UrlTemplateImageryProvider(deferred.promise); - var ternaryFunctions = { - clamp : getEvaluateTernaryCommponentwise(CesiumMath.clamp, true), - mix : getEvaluateTernaryCommponentwise(CesiumMath.lerp, true) - }; + var metadataError; - function fract(number) { - return number - Math.floor(number); - } + function metadataSuccess(xml) { + var tileFormatRegex = /tileformat/i; + var tileSetRegex = /tileset/i; + var tileSetsRegex = /tilesets/i; + var bboxRegex = /boundingbox/i; + var format, bbox, tilesets; + var tilesetsList = []; //list of TileSets - function exp2(exponent) { - return Math.pow(2.0,exponent); - } + // Allowing options properties (already copied to that) to override XML values - function log2(number) { - return CesiumMath.logBase(number, 2.0); - } + // Iterate XML Document nodes for properties + var nodeList = xml.childNodes[0].childNodes; + for (var i = 0; i < nodeList.length; i++){ + if (tileFormatRegex.test(nodeList.item(i).nodeName)) { + format = nodeList.item(i); + } else if (tileSetsRegex.test(nodeList.item(i).nodeName)) { + tilesets = nodeList.item(i); // Node list of TileSets + var tileSetNodes = nodeList.item(i).childNodes; + // Iterate the nodes to find all TileSets + for(var j = 0; j < tileSetNodes.length; j++) { + if (tileSetRegex.test(tileSetNodes.item(j).nodeName)) { + // Add them to tilesets list + tilesetsList.push(tileSetNodes.item(j)); + } + } + } else if (bboxRegex.test(nodeList.item(i).nodeName)) { + bbox = nodeList.item(i); + } + } - function getEvaluateUnaryComponentwise(operation) { - return function(call, left) { - if (typeof left === 'number') { - return operation(left); - } else if (left instanceof Cartesian2) { - return Cartesian2.fromElements(operation(left.x), operation(left.y), scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3) { - return Cartesian3.fromElements(operation(left.x), operation(left.y), operation(left.z), scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4) { - return Cartesian4.fromElements(operation(left.x), operation(left.y), operation(left.z), operation(left.w), scratchStorage.getCartesian4()); + var message; + if (!defined(tilesets) || !defined(bbox)) { + message = 'Unable to find expected tilesets or bbox attributes in ' + xmlResource.url + '.'; + metadataError = TileProviderError.handleError(metadataError, imageryProvider, imageryProvider.errorEvent, message, undefined, undefined, undefined, requestMetadata); + if(!metadataError.retry) { + deferred.reject(new RuntimeError(message)); + } + return; } - throw new RuntimeError('Function "' + call + '" requires a vector or number argument. Argument is ' + left + '.'); - }; - } - function getEvaluateBinaryCommponentwise(operation, allowScalar) { - return function(call, left, right) { - if (allowScalar && typeof right === 'number') { - if (typeof left === 'number') { - return operation(left, right); - } else if (left instanceof Cartesian2) { - return Cartesian2.fromElements(operation(left.x, right), operation(left.y, right), scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3) { - return Cartesian3.fromElements(operation(left.x, right), operation(left.y, right), operation(left.z, right), scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4) { - return Cartesian4.fromElements(operation(left.x, right), operation(left.y, right), operation(left.z, right), operation(left.w, right), scratchStorage.getCartesian4()); + var fileExtension = defaultValue(options.fileExtension, format.getAttribute('extension')); + var tileWidth = defaultValue(options.tileWidth, parseInt(format.getAttribute('width'), 10)); + var tileHeight = defaultValue(options.tileHeight, parseInt(format.getAttribute('height'), 10)); + var minimumLevel = defaultValue(options.minimumLevel, parseInt(tilesetsList[0].getAttribute('order'), 10)); + var maximumLevel = defaultValue(options.maximumLevel, parseInt(tilesetsList[tilesetsList.length - 1].getAttribute('order'), 10)); + var tilingSchemeName = tilesets.getAttribute('profile'); + var tilingScheme = options.tilingScheme; + + if (!defined(tilingScheme)) { + if (tilingSchemeName === 'geodetic' || tilingSchemeName === 'global-geodetic') { + tilingScheme = new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); + } else if (tilingSchemeName === 'mercator' || tilingSchemeName === 'global-mercator') { + tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); + } else { + message = xmlResource.url + 'specifies an unsupported profile attribute, ' + tilingSchemeName + '.'; + metadataError = TileProviderError.handleError(metadataError, imageryProvider, imageryProvider.errorEvent, message, undefined, undefined, undefined, requestMetadata); + if(!metadataError.retry) { + deferred.reject(new RuntimeError(message)); + } + return; } } - if (typeof left === 'number' && typeof right === 'number') { - return operation(left, right); - } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { - return Cartesian2.fromElements(operation(left.x, right.x), operation(left.y, right.y), scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { - return Cartesian3.fromElements(operation(left.x, right.x), operation(left.y, right.y), operation(left.z, right.z), scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { - return Cartesian4.fromElements(operation(left.x, right.x), operation(left.y, right.y), operation(left.z, right.z), operation(left.w, right.w), scratchStorage.getCartesian4()); - } + // rectangle handling + var rectangle = Rectangle.clone(options.rectangle); - throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); - }; - } + if (!defined(rectangle)) { + var sw; + var ne; + var swXY; + var neXY; - function getEvaluateTernaryCommponentwise(operation, allowScalar) { - return function(call, left, right, test) { - if (allowScalar && typeof test === 'number') { - if (typeof left === 'number' && typeof right === 'number') { - return operation(left, right, test); - } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { - return Cartesian2.fromElements(operation(left.x, right.x, test), operation(left.y, right.y, test), scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { - return Cartesian3.fromElements(operation(left.x, right.x, test), operation(left.y, right.y, test), operation(left.z, right.z, test), scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { - return Cartesian4.fromElements(operation(left.x, right.x, test), operation(left.y, right.y, test), operation(left.z, right.z, test), operation(left.w, right.w, test), scratchStorage.getCartesian4()); + // In older versions of gdal x and y values were flipped, which is why we check for an option to flip + // the values here as well. Unfortunately there is no way to autodetect whether flipping is needed. + var flipXY = defaultValue(options.flipXY, false); + if (flipXY) { + swXY = new Cartesian2(parseFloat(bbox.getAttribute('miny')), parseFloat(bbox.getAttribute('minx'))); + neXY = new Cartesian2(parseFloat(bbox.getAttribute('maxy')), parseFloat(bbox.getAttribute('maxx'))); + } else { + swXY = new Cartesian2(parseFloat(bbox.getAttribute('minx')), parseFloat(bbox.getAttribute('miny'))); + neXY = new Cartesian2(parseFloat(bbox.getAttribute('maxx')), parseFloat(bbox.getAttribute('maxy'))); } - } - if (typeof left === 'number' && typeof right === 'number' && typeof test === 'number') { - return operation(left, right, test); - } else if (left instanceof Cartesian2 && right instanceof Cartesian2 && test instanceof Cartesian2) { - return Cartesian2.fromElements(operation(left.x, right.x, test.x), operation(left.y, right.y, test.y), scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3 && right instanceof Cartesian3 && test instanceof Cartesian3) { - return Cartesian3.fromElements(operation(left.x, right.x, test.x), operation(left.y, right.y, test.y), operation(left.z, right.z, test.z), scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4 && right instanceof Cartesian4 && test instanceof Cartesian4) { - return Cartesian4.fromElements(operation(left.x, right.x, test.x), operation(left.y, right.y, test.y), operation(left.z, right.z, test.z), operation(left.w, right.w, test.w), scratchStorage.getCartesian4()); + // Determine based on the profile attribute if this tileset was generated by gdal2tiles.py, which + // uses 'mercator' and 'geodetic' profiles, or by a tool compliant with the TMS standard, which is + // 'global-mercator' and 'global-geodetic' profiles. In the gdal2Tiles case, X and Y are always in + // geodetic degrees. + var isGdal2tiles = tilingSchemeName === 'geodetic' || tilingSchemeName === 'mercator'; + if (tilingScheme instanceof GeographicTilingScheme || isGdal2tiles) { + sw = Cartographic.fromDegrees(swXY.x, swXY.y); + ne = Cartographic.fromDegrees(neXY.x, neXY.y); + } else { + var projection = tilingScheme.projection; + sw = projection.unproject(swXY); + ne = projection.unproject(neXY); + } + + rectangle = new Rectangle(sw.longitude, sw.latitude, ne.longitude, ne.latitude); } - throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ', ' + right + ', and ' + test + '.'); - }; - } + // The rectangle must not be outside the bounds allowed by the tiling scheme. + if (rectangle.west < tilingScheme.rectangle.west) { + rectangle.west = tilingScheme.rectangle.west; + } + if (rectangle.east > tilingScheme.rectangle.east) { + rectangle.east = tilingScheme.rectangle.east; + } + if (rectangle.south < tilingScheme.rectangle.south) { + rectangle.south = tilingScheme.rectangle.south; + } + if (rectangle.north > tilingScheme.rectangle.north) { + rectangle.north = tilingScheme.rectangle.north; + } - function length(call, left) { - if (typeof left === 'number') { - return Math.abs(left); - } else if (left instanceof Cartesian2) { - return Cartesian2.magnitude(left); - } else if (left instanceof Cartesian3) { - return Cartesian3.magnitude(left); - } else if (left instanceof Cartesian4) { - return Cartesian4.magnitude(left); - } + // Check the number of tiles at the minimum level. If it's more than four, + // try requesting the lower levels anyway, because starting at the higher minimum + // level will cause too many tiles to be downloaded and rendered. + var swTile = tilingScheme.positionToTileXY(Rectangle.southwest(rectangle), minimumLevel); + var neTile = tilingScheme.positionToTileXY(Rectangle.northeast(rectangle), minimumLevel); + var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1); + if (tileCount > 4) { + minimumLevel = 0; + } - throw new RuntimeError('Function "' + call + '" requires a vector or number argument. Argument is ' + left + '.'); - } + var templateResource = resource.getDerivedResource({ + url: '{z}/{x}/{reverseY}.' + fileExtension + }); - function normalize(call, left) { - if (typeof left === 'number') { - return 1.0; - } else if (left instanceof Cartesian2) { - return Cartesian2.normalize(left, scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3) { - return Cartesian3.normalize(left, scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4) { - return Cartesian4.normalize(left, scratchStorage.getCartesian4()); + deferred.resolve({ + url : templateResource, + tilingScheme : tilingScheme, + rectangle : rectangle, + tileWidth : tileWidth, + tileHeight : tileHeight, + minimumLevel : minimumLevel, + maximumLevel : maximumLevel, + tileDiscardPolicy : options.tileDiscardPolicy, + credit: options.credit + }); } - throw new RuntimeError('Function "' + call + '" requires a vector or number argument. Argument is ' + left + '.'); - } - - function distance(call, left, right) { - if (typeof left === 'number' && typeof right === 'number') { - return Math.abs(left - right); - } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { - return Cartesian2.distance(left, right); - } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { - return Cartesian3.distance(left, right); - } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { - return Cartesian4.distance(left, right); - } + function metadataFailure(error) { + // Can't load XML, still allow options and defaults + var fileExtension = defaultValue(options.fileExtension, 'png'); + var tileWidth = defaultValue(options.tileWidth, 256); + var tileHeight = defaultValue(options.tileHeight, 256); + var minimumLevel = defaultValue(options.minimumLevel, 0); + var maximumLevel = options.maximumLevel; + var tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); + var rectangle = defaultValue(options.rectangle, tilingScheme.rectangle); - throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); - } + var templateResource = resource.getDerivedResource({ + url: '{z}/{x}/{reverseY}.' + fileExtension + }); - function dot(call, left, right) { - if (typeof left === 'number' && typeof right === 'number') { - return left * right; - } else if (left instanceof Cartesian2 && right instanceof Cartesian2) { - return Cartesian2.dot(left, right); - } else if (left instanceof Cartesian3 && right instanceof Cartesian3) { - return Cartesian3.dot(left, right); - } else if (left instanceof Cartesian4 && right instanceof Cartesian4) { - return Cartesian4.dot(left, right); + deferred.resolve({ + url : templateResource, + tilingScheme : tilingScheme, + rectangle : rectangle, + tileWidth : tileWidth, + tileHeight : tileHeight, + minimumLevel : minimumLevel, + maximumLevel : maximumLevel, + tileDiscardPolicy : options.tileDiscardPolicy, + credit: options.credit + }); } - throw new RuntimeError('Function "' + call + '" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); - } - - function cross(call, left, right) { - if (left instanceof Cartesian3 && right instanceof Cartesian3) { - return Cartesian3.cross(left, right, scratchStorage.getCartesian3()); + function requestMetadata() { + // Try to load remaining parameters from XML + xmlResource.fetchXML().then(metadataSuccess).otherwise(metadataFailure); } - throw new RuntimeError('Function "' + call + '" requires vec3 arguments. Arguments are ' + left + ' and ' + right + '.'); + requestMetadata(); + return imageryProvider; } - function Node(type, value, left, right, test) { - this._type = type; - this._value = value; - this._left = left; - this._right = right; - this._test = test; - this.evaluate = undefined; + return createTileMapServiceImageryProvider; +}); - setEvaluateFunction(this); - } +define('Scene/GoogleEarthEnterpriseMapsProvider',[ + '../Core/Credit', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/Event', + '../Core/GeographicTilingScheme', + '../Core/Rectangle', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/TileProviderError', + '../Core/WebMercatorTilingScheme', + '../ThirdParty/when', + './ImageryProvider' + ], function( + Credit, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Event, + GeographicTilingScheme, + Rectangle, + Resource, + RuntimeError, + TileProviderError, + WebMercatorTilingScheme, + when, + ImageryProvider) { + 'use strict'; - function replaceDefines(expression, defines) { - if (!defined(defines)) { - return expression; + /** + * Provides tiled imagery using the Google Earth Imagery API. + * + * Notes: This imagery provider does not work with the public Google Earth servers. It works with the + * Google Earth Enterprise Server. + * + * By default the Google Earth Enterprise server does not set the + * {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} headers. You can either + * use a proxy server which adds these headers, or in the /opt/google/gehttpd/conf/gehttpd.conf + * and add the 'Header set Access-Control-Allow-Origin "*"' option to the '<Directory />' and + * '<Directory "/opt/google/gehttpd/htdocs">' directives. + * + * This provider is for use with 2D Maps API as part of Google Earth Enterprise. For 3D Earth API uses, it + * is necessary to use {@link GoogleEarthEnterpriseImageryProvider} + * + * @alias GoogleEarthEnterpriseMapsProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url of the Google Earth server hosting the imagery. + * @param {Number} options.channel The channel (id) to be used when requesting data from the server. + * The channel number can be found by looking at the json file located at: + * earth.localdomain/default_map/query?request=Json&vars=geeServerDefs The /default_map path may + * differ depending on your Google Earth Enterprise server configuration. Look for the "id" that + * is associated with a "ImageryMaps" requestType. There may be more than one id available. + * Example: + * { + * layers: [ + * { + * id: 1002, + * requestType: "ImageryMaps" + * }, + * { + * id: 1007, + * requestType: "VectorMapsRaster" + * } + * ] + * } + * @param {String} [options.path="/default_map"] The path of the Google Earth server hosting the imagery. + * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the Google Earth + * Enterprise server, or undefined if there is no limit. + * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile + * is invalid and should be discarded. To ensure that no tiles are discarded, construct and pass + * a {@link NeverTileDiscardPolicy} for this parameter. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * + * @exception {RuntimeError} Could not find layer with channel (id) of <code>options.channel</code>. + * @exception {RuntimeError} Could not find a version in channel (id) <code>options.channel</code>. + * @exception {RuntimeError} Unsupported projection <code>data.projection</code>. + * + * @see ArcGisMapServerImageryProvider + * @see BingMapsImageryProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + * + * + * @example + * var google = new Cesium.GoogleEarthEnterpriseMapsProvider({ + * url : 'https://earth.localdomain', + * channel : 1008 + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + function GoogleEarthEnterpriseMapsProvider(options) { + options = defaultValue(options, {}); + + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); } - for (var key in defines) { - if (defines.hasOwnProperty(key)) { - var definePlaceholder = new RegExp('\\$\\{' + key + '\\}', 'g'); - var defineReplace = '(' + defines[key] + ')'; - if (defined(defineReplace)) { - expression = expression.replace(definePlaceholder, defineReplace); - } - } + if (!defined(options.channel)) { + throw new DeveloperError('options.channel is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('GoogleEarthEnterpriseMapsProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - return expression; - } - function removeBackslashes(expression) { - return expression.replace(backslashRegex, backslashReplacement); - } + var url = options.url; + var path = defaultValue(options.path, '/default_map'); + var resource = Resource.createIfNeeded(url + path, { + proxy: options.proxy + }); + resource.appendForwardSlash(); - function replaceBackslashes(expression) { - return expression.replace(replacementRegex, '\\'); - } + this._resource = resource; + this._url = url; + this._path = path; + this._tileDiscardPolicy = options.tileDiscardPolicy; + this._channel = options.channel; + this._requestType = 'ImageryMaps'; + this._credit = new Credit({ + text: 'Google Imagery', + imageUrl: GoogleEarthEnterpriseMapsProvider._logoData, + link: 'http://www.google.com/enterprise/mapsearth/products/earthenterprise.html' + }); - function replaceVariables(expression) { - var exp = expression; - var result = ''; - var i = exp.indexOf('${'); - while (i >= 0) { - // Check if string is inside quotes - var openSingleQuote = exp.indexOf('\''); - var openDoubleQuote = exp.indexOf('"'); - var closeQuote; - if (openSingleQuote >= 0 && openSingleQuote < i) { - closeQuote = exp.indexOf('\'', openSingleQuote + 1); - result += exp.substr(0, closeQuote + 1); - exp = exp.substr(closeQuote + 1); - i = exp.indexOf('${'); - } else if (openDoubleQuote >= 0 && openDoubleQuote < i) { - closeQuote = exp.indexOf('"', openDoubleQuote + 1); - result += exp.substr(0, closeQuote + 1); - exp = exp.substr(closeQuote + 1); - i = exp.indexOf('${'); - } else { - result += exp.substr(0, i); - var j = exp.indexOf('}'); - if (j < 0) { - throw new RuntimeError('Unmatched {.'); - } - result += 'czm_' + exp.substr(i + 2, j - (i + 2)); - exp = exp.substr(j + 1); - i = exp.indexOf('${'); - } - } - result += exp; - return result; - } + /** + * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider. + * By default, this is set to 1.9. Changing this value after creating an {@link ImageryLayer} for this provider will have + * no effect. Instead, set the layer's {@link ImageryLayer#gamma} property. + * + * @type {Number} + * @default 1.9 + */ + this.defaultGamma = 1.9; - function parseLiteral(ast) { - var type = typeof ast.value; - if (ast.value === null) { - return new Node(ExpressionNodeType.LITERAL_NULL, null); - } else if (type === 'boolean') { - return new Node(ExpressionNodeType.LITERAL_BOOLEAN, ast.value); - } else if (type === 'number') { - return new Node(ExpressionNodeType.LITERAL_NUMBER, ast.value); - } else if (type === 'string') { - if (ast.value.indexOf('${') >= 0) { - return new Node(ExpressionNodeType.VARIABLE_IN_STRING, ast.value); - } - return new Node(ExpressionNodeType.LITERAL_STRING, replaceBackslashes(ast.value)); - } - } + this._tilingScheme = undefined; - function parseCall(expression, ast) { - var args = ast.arguments; - var argsLength = args.length; - var call; - var val, left, right; + this._version = undefined; - // Member function calls - if (ast.callee.type === 'MemberExpression') { - call = ast.callee.property.name; - var object = ast.callee.object; - if (call === 'test' || call === 'exec') { - // Make sure this is called on a valid type - if (object.callee.name !== 'regExp') { - throw new RuntimeError(call + ' is not a function.'); - } - if (argsLength === 0) { - if (call === 'test') { - return new Node(ExpressionNodeType.LITERAL_BOOLEAN, false); - } - return new Node(ExpressionNodeType.LITERAL_NULL, null); - } - left = createRuntimeAst(expression, object); - right = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.FUNCTION_CALL, call, left, right); - } else if (call === 'toString') { - val = createRuntimeAst(expression, object); - return new Node(ExpressionNodeType.FUNCTION_CALL, call, val); - } + this._tileWidth = 256; + this._tileHeight = 256; + this._maximumLevel = options.maximumLevel; - throw new RuntimeError('Unexpected function call "' + call + '".'); - } + this._errorEvent = new Event(); - // Non-member function calls - call = ast.callee.name; - if (call === 'color') { - if (argsLength === 0) { - return new Node(ExpressionNodeType.LITERAL_COLOR, call); - } - val = createRuntimeAst(expression, args[0]); - if (defined(args[1])) { - var alpha = createRuntimeAst(expression, args[1]); - return new Node(ExpressionNodeType.LITERAL_COLOR, call, [val, alpha]); - } - return new Node(ExpressionNodeType.LITERAL_COLOR, call, [val]); - } else if (call === 'rgb' || call === 'hsl') { - if (argsLength < 3) { - throw new RuntimeError(call + ' requires three arguments.'); - } - val = [ - createRuntimeAst(expression, args[0]), - createRuntimeAst(expression, args[1]), - createRuntimeAst(expression, args[2]) - ]; - return new Node(ExpressionNodeType.LITERAL_COLOR, call, val); - } else if (call === 'rgba' || call === 'hsla') { - if (argsLength < 4) { - throw new RuntimeError(call + ' requires four arguments.'); - } - val = [ - createRuntimeAst(expression, args[0]), - createRuntimeAst(expression, args[1]), - createRuntimeAst(expression, args[2]), - createRuntimeAst(expression, args[3]) - ]; - return new Node(ExpressionNodeType.LITERAL_COLOR, call, val); - } else if (call === 'vec2' || call === 'vec3' || call === 'vec4') { - // Check for invalid constructors at evaluation time - val = new Array(argsLength); - for (var i = 0; i < argsLength; ++i) { - val[i] = createRuntimeAst(expression, args[i]); - } - return new Node(ExpressionNodeType.LITERAL_VECTOR, call, val); - } else if (call === 'isNaN' || call === 'isFinite') { - if (argsLength === 0) { - if (call === 'isNaN') { - return new Node(ExpressionNodeType.LITERAL_BOOLEAN, true); - } - return new Node(ExpressionNodeType.LITERAL_BOOLEAN, false); - } - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'isExactClass' || call === 'isClass') { - if (argsLength < 1 || argsLength > 1) { - throw new RuntimeError(call + ' requires exactly one argument.'); - } - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'getExactClassName') { - if (argsLength > 0) { - throw new RuntimeError(call + ' does not take any argument.'); - } - return new Node(ExpressionNodeType.UNARY, call); - } else if (defined(unaryFunctions[call])) { - if (argsLength !== 1) { - throw new RuntimeError(call + ' requires exactly one argument.'); - } - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); - } else if (defined(binaryFunctions[call])) { - if (argsLength !== 2) { - throw new RuntimeError(call + ' requires exactly two arguments.'); - } - left = createRuntimeAst(expression, args[0]); - right = createRuntimeAst(expression, args[1]); - return new Node(ExpressionNodeType.BINARY, call, left, right); - } else if (defined(ternaryFunctions[call])) { - if (argsLength !== 3) { - throw new RuntimeError(call + ' requires exactly three arguments.'); - } - left = createRuntimeAst(expression, args[0]); - right = createRuntimeAst(expression, args[1]); - var test = createRuntimeAst(expression, args[2]); - return new Node(ExpressionNodeType.TERNARY, call, left, right, test); - } else if (call === 'Boolean') { - if (argsLength === 0) { - return new Node(ExpressionNodeType.LITERAL_BOOLEAN, false); - } - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'Number') { - if (argsLength === 0) { - return new Node(ExpressionNodeType.LITERAL_NUMBER, 0); - } - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'String') { - if (argsLength === 0) { - return new Node(ExpressionNodeType.LITERAL_STRING, ''); - } - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'regExp') { - return parseRegex(expression, ast); - } + this._ready = false; + this._readyPromise = when.defer(); - throw new RuntimeError('Unexpected function call "' + call + '".'); - } + var metadataResource = resource.getDerivedResource({ + url: 'query', + queryParameters: { + request: 'Json', + vars: 'geeServerDefs', + is2d: 't' + } + }); + var that = this; + var metadataError; - function parseRegex(expression, ast) { - var args = ast.arguments; - // no arguments, return default regex - if (args.length === 0) { - return new Node(ExpressionNodeType.LITERAL_REGEX, new RegExp()); - } + function metadataSuccess(text) { + var data; - var pattern = createRuntimeAst(expression, args[0]); - var exp; + // The Google Earth server sends malformed JSON data currently... + try { + // First, try parsing it like normal in case a future version sends correctly formatted JSON + data = JSON.parse(text); + } catch (e) { + // Quote object strings manually, then try parsing again + data = JSON.parse(text.replace(/([\[\{,])[\n\r ]*([A-Za-z0-9]+)[\n\r ]*:/g, '$1"$2":')); + } - // optional flag argument supplied - if (args.length > 1) { - var flags = createRuntimeAst(expression, args[1]); - if (isLiteralType(pattern) && isLiteralType(flags)) { - try { - exp = new RegExp(replaceBackslashes(String(pattern._value)), flags._value); - } catch (e) { - throw new RuntimeError(e); + var layer; + for (var i = 0; i < data.layers.length; i++) { + if (data.layers[i].id === that._channel) { + layer = data.layers[i]; + break; } - return new Node(ExpressionNodeType.LITERAL_REGEX, exp); } - return new Node(ExpressionNodeType.REGEX, pattern, flags); - } - // only pattern argument supplied - if (isLiteralType(pattern)) { - try { - exp = new RegExp(replaceBackslashes(String(pattern._value))); - } catch (e) { - throw new RuntimeError(e); + var message; + + if (!defined(layer)) { + message = 'Could not find layer with channel (id) of ' + that._channel + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + throw new RuntimeError(message); } - return new Node(ExpressionNodeType.LITERAL_REGEX, exp); - } - return new Node(ExpressionNodeType.REGEX, pattern); - } - function parseKeywordsAndVariables(ast) { - if (isVariable(ast.name)) { - var name = getPropertyName(ast.name); - if (name.substr(0, 8) === 'tiles3d_') { - return new Node(ExpressionNodeType.BUILTIN_VARIABLE, name); + if (!defined(layer.version)) { + message = 'Could not find a version in channel (id) ' + that._channel + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + throw new RuntimeError(message); } - return new Node(ExpressionNodeType.VARIABLE, name); - } else if (ast.name === 'NaN') { - return new Node(ExpressionNodeType.LITERAL_NUMBER, NaN); - } else if (ast.name === 'Infinity') { - return new Node(ExpressionNodeType.LITERAL_NUMBER, Infinity); - } else if (ast.name === 'undefined') { - return new Node(ExpressionNodeType.LITERAL_UNDEFINED, undefined); - } + that._version = layer.version; - throw new RuntimeError(ast.name + ' is not defined.'); - } + if (defined(data.projection) && data.projection === 'flat') { + that._tilingScheme = new GeographicTilingScheme({ + numberOfLevelZeroTilesX : 2, + numberOfLevelZeroTilesY : 2, + rectangle : new Rectangle(-Math.PI, -Math.PI, Math.PI, Math.PI), + ellipsoid : options.ellipsoid + }); + // Default to mercator projection when projection is undefined + } else if (!defined(data.projection) || data.projection === 'mercator') { + that._tilingScheme = new WebMercatorTilingScheme({ + numberOfLevelZeroTilesX : 2, + numberOfLevelZeroTilesY : 2, + ellipsoid : options.ellipsoid + }); + } else { + message = 'Unsupported projection ' + data.projection + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + throw new RuntimeError(message); + } - function parseMathConstant(ast) { - var name = ast.property.name; - if (name === 'PI') { - return new Node(ExpressionNodeType.LITERAL_NUMBER, Math.PI); - } else if (name === 'E') { - return new Node(ExpressionNodeType.LITERAL_NUMBER, Math.E); + that._ready = true; + that._readyPromise.resolve(true); + TileProviderError.handleSuccess(metadataError); } - } - function parseMemberExpression(expression, ast) { - if (ast.object.name === 'Math') { - return parseMathConstant(ast); + function metadataFailure(e) { + var message = 'An error occurred while accessing ' + metadataResource.url + '.'; + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); + that._readyPromise.reject(new RuntimeError(message)); } - var val; - var obj = createRuntimeAst(expression, ast.object); - if (ast.computed) { - val = createRuntimeAst(expression, ast.property); - return new Node(ExpressionNodeType.MEMBER, 'brackets', obj, val); + function requestMetadata() { + var metadata = metadataResource.fetchText(); + when(metadata, metadataSuccess, metadataFailure); } - val = new Node(ExpressionNodeType.LITERAL_STRING, ast.property.name); - return new Node(ExpressionNodeType.MEMBER, 'dot', obj, val); + requestMetadata(); } - function isLiteralType(node) { - return (node._type >= ExpressionNodeType.LITERAL_NULL); - } + defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { + /** + * Gets the URL of the Google Earth MapServer. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {String} + * @readonly + */ + url : { + get : function() { + return this._url; + } + }, - function isVariable(name) { - return (name.substr(0, 4) === 'czm_'); - } + /** + * Gets the url path of the data on the Google Earth server. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {String} + * @readonly + */ + path : { + get : function() { + return this._path; + } + }, - function getPropertyName(variable) { - return variable.substr(4); - } + /** + * Gets the proxy used by this provider. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Proxy} + * @readonly + */ + proxy : { + get : function() { + return this._resource.proxy; + } + }, - function createRuntimeAst(expression, ast) { - var node; - var op; - var left; - var right; + /** + * Gets the imagery channel (id) currently being used. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number} + * @readonly + */ + channel : { + get : function() { + return this._channel; + } + }, - if (ast.type === 'Literal') { - node = parseLiteral(ast); - } else if (ast.type === 'CallExpression') { - node = parseCall(expression, ast); - } else if (ast.type === 'Identifier') { - node = parseKeywordsAndVariables(ast); - } else if (ast.type === 'UnaryExpression') { - op = ast.operator; - var child = createRuntimeAst(expression, ast.argument); - if (unaryOperators.indexOf(op) > -1) { - node = new Node(ExpressionNodeType.UNARY, op, child); - } else { - throw new RuntimeError('Unexpected operator "' + op + '".'); + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number} + * @readonly + */ + tileWidth : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); + } + + return this._tileWidth; } - } else if (ast.type === 'BinaryExpression') { - op = ast.operator; - left = createRuntimeAst(expression, ast.left); - right = createRuntimeAst(expression, ast.right); - if (binaryOperators.indexOf(op) > -1) { - node = new Node(ExpressionNodeType.BINARY, op, left, right); - } else { - throw new RuntimeError('Unexpected operator "' + op + '".'); + }, + + /** + * Gets the height of each tile, in pixels. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number} + * @readonly + */ + tileHeight : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + } + + return this._tileHeight; } - } else if (ast.type === 'LogicalExpression') { - op = ast.operator; - left = createRuntimeAst(expression, ast.left); - right = createRuntimeAst(expression, ast.right); - if (binaryOperators.indexOf(op) > -1) { - node = new Node(ExpressionNodeType.BINARY, op, left, right); + }, + + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : function() { + if (!this._ready) { + throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); + } + + return this._maximumLevel; } - } else if (ast.type === 'ConditionalExpression') { - var test = createRuntimeAst(expression, ast.test); - left = createRuntimeAst(expression, ast.consequent); - right = createRuntimeAst(expression, ast.alternate); - node = new Node(ExpressionNodeType.CONDITIONAL, '?', left, right, test); - } else if (ast.type === 'MemberExpression') { - node = parseMemberExpression(expression, ast); - } else if (ast.type === 'ArrayExpression') { - var val = []; - for (var i = 0; i < ast.elements.length; i++) { - val[i] = createRuntimeAst(expression, ast.elements[i]); + }, + + /** + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number} + * @readonly + */ + minimumLevel : { + get : function() { + if (!this._ready) { + throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); + } + + return 0; } - node = new Node(ExpressionNodeType.ARRAY, val); - } else if (ast.type === 'Compound') { - // empty expression or multiple expressions - throw new RuntimeError('Provide exactly one expression.'); - } else { - throw new RuntimeError('Cannot parse expression.'); - } + }, - return node; - } + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {TilingScheme} + * @readonly + */ + tilingScheme : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme; + } + }, - function setEvaluateFunction(node) { - if (node._type === ExpressionNodeType.CONDITIONAL) { - node.evaluate = node._evaluateConditional; - } else if (node._type === ExpressionNodeType.FUNCTION_CALL) { - if (node._value === 'test') { - node.evaluate = node._evaluateRegExpTest; - } else if (node._value === 'exec') { - node.evaluate = node._evaluateRegExpExec; - } else if (node._value === 'toString') { - node.evaluate = node._evaluateToString; + /** + * Gets the version of the data used by this provider. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number} + * @readonly + */ + version : { + get : function() { + if (!this._ready) { + throw new DeveloperError('version must not be called before the imagery provider is ready.'); + } + + return this._version; } - } else if (node._type === ExpressionNodeType.UNARY) { - if (node._value === '!') { - node.evaluate = node._evaluateNot; - } else if (node._value === '-') { - node.evaluate = node._evaluateNegative; - } else if (node._value === '+') { - node.evaluate = node._evaluatePositive; - } else if (node._value === 'isNaN') { - node.evaluate = node._evaluateNaN; - } else if (node._value === 'isFinite') { - node.evaluate = node._evaluateIsFinite; - } else if (node._value === 'isExactClass') { - node.evaluate = node._evaluateIsExactClass; - } else if (node._value === 'isClass') { - node.evaluate = node._evaluateIsClass; - } else if (node._value === 'getExactClassName') { - node.evaluate = node._evaluategetExactClassName; - } else if (node._value === 'Boolean') { - node.evaluate = node._evaluateBooleanConversion; - } else if (node._value === 'Number') { - node.evaluate = node._evaluateNumberConversion; - } else if (node._value === 'String') { - node.evaluate = node._evaluateStringConversion; - } else if (defined(unaryFunctions[node._value])) { - node.evaluate = getEvaluateUnaryFunction(node._value); + }, + + /** + * Gets the type of data that is being requested from the provider. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {String} + * @readonly + */ + requestType : { + get : function() { + if (!this._ready) { + throw new DeveloperError('requestType must not be called before the imagery provider is ready.'); + } + + return this._requestType; } - } else if (node._type === ExpressionNodeType.BINARY) { - if (node._value === '+') { - node.evaluate = node._evaluatePlus; - } else if (node._value === '-') { - node.evaluate = node._evaluateMinus; - } else if (node._value === '*') { - node.evaluate = node._evaluateTimes; - } else if (node._value === '/') { - node.evaluate = node._evaluateDivide; - } else if (node._value === '%') { - node.evaluate = node._evaluateMod; - } else if (node._value === '===') { - node.evaluate = node._evaluateEqualsStrict; - } else if (node._value === '!==') { - node.evaluate = node._evaluateNotEqualsStrict; - } else if (node._value === '<') { - node.evaluate = node._evaluateLessThan; - } else if (node._value === '<=') { - node.evaluate = node._evaluateLessThanOrEquals; - } else if (node._value === '>') { - node.evaluate = node._evaluateGreaterThan; - } else if (node._value === '>=') { - node.evaluate = node._evaluateGreaterThanOrEquals; - } else if (node._value === '&&') { - node.evaluate = node._evaluateAnd; - } else if (node._value === '||') { - node.evaluate = node._evaluateOr; - } else if (node._value === '=~') { - node.evaluate = node._evaluateRegExpMatch; - } else if (node._value === '!~') { - node.evaluate = node._evaluateRegExpNotMatch; - } else if (defined(binaryFunctions[node._value])) { - node.evaluate = getEvaluateBinaryFunction(node._value); + }, + /** + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle : { + get : function() { + if (!this._ready) { + throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme.rectangle; } - } else if (node._type === ExpressionNodeType.TERNARY) { - node.evaluate = getEvaluateTernaryFunction(node._value); - } else if (node._type === ExpressionNodeType.MEMBER) { - if (node._value === 'brackets') { - node.evaluate = node._evaluateMemberBrackets; - } else { - node.evaluate = node._evaluateMemberDot; + }, + + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + */ + tileDiscardPolicy : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); + } + + return this._tileDiscardPolicy; } - } else if (node._type === ExpressionNodeType.ARRAY) { - node.evaluate = node._evaluateArray; - } else if (node._type === ExpressionNodeType.VARIABLE) { - node.evaluate = node._evaluateVariable; - } else if (node._type === ExpressionNodeType.VARIABLE_IN_STRING) { - node.evaluate = node._evaluateVariableString; - } else if (node._type === ExpressionNodeType.LITERAL_COLOR) { - node.evaluate = node._evaluateLiteralColor; - } else if (node._type === ExpressionNodeType.LITERAL_VECTOR) { - node.evaluate = node._evaluateLiteralVector; - } else if (node._type === ExpressionNodeType.LITERAL_STRING) { - node.evaluate = node._evaluateLiteralString; - } else if (node._type === ExpressionNodeType.REGEX) { - node.evaluate = node._evaluateRegExp; - } else if (node._type === ExpressionNodeType.BUILTIN_VARIABLE) { - if (node._value === 'tiles3d_tileset_time') { - node.evaluate = evaluateTilesetTime; + }, + + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._errorEvent; } - } else { - node.evaluate = node._evaluateLiteral; - } - } + }, + + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; + } + }, + + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + }, - function evaluateTilesetTime(frameState, feature) { - return feature.content.tileset.timeSinceLoad; - } + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return this._credit; + } + }, - function getEvaluateUnaryFunction(call) { - var evaluate = unaryFunctions[call]; - return function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - return evaluate(call, left); - }; - } + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { + get : function() { + return true; + } + } + }); - function getEvaluateBinaryFunction(call) { - var evaluate = binaryFunctions[call]; - return function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - return evaluate(call, left, right); - }; - } + /** + * Gets the credits to be displayed when a given tile is displayed. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + */ + GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function(x, y, level) { + return undefined; + }; - function getEvaluateTernaryFunction(call) { - var evaluate = ternaryFunctions[call]; - return function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - var test = this._test.evaluate(frameState, feature); - return evaluate(call, left, right, test); - }; - } + /** + * Requests the image for a given tile. This function should + * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + */ + GoogleEarthEnterpriseMapsProvider.prototype.requestImage = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); + } + + var resource = this._resource.getDerivedResource({ + url: 'query', + request: request, + queryParameters: { + request: this._requestType, + channel: this._channel, + version: this._version, + x: x, + y: y, + z: level + 1 // Google Earth starts with a zoom level of 1, not 0 + } + }); - Node.prototype._evaluateLiteral = function(frameState, feature) { - return this._value; + return ImageryProvider.loadImage(this, resource); }; - Node.prototype._evaluateLiteralColor = function(frameState, feature) { - var color = scratchColor; - var args = this._left; - if (this._value === 'color') { - if (!defined(args)) { - Color.fromBytes(255, 255, 255, 255, color); - } else if (args.length > 1) { - Color.fromCssColorString(args[0].evaluate(frameState, feature), color); - color.alpha = args[1].evaluate(frameState, feature); - } else { - Color.fromCssColorString(args[0].evaluate(frameState, feature), color); - } - } else if (this._value === 'rgb') { - Color.fromBytes( - args[0].evaluate(frameState, feature), - args[1].evaluate(frameState, feature), - args[2].evaluate(frameState, feature), - 255, color); - } else if (this._value === 'rgba') { - // convert between css alpha (0 to 1) and cesium alpha (0 to 255) - var a = args[3].evaluate(frameState, feature) * 255; - Color.fromBytes( - args[0].evaluate(frameState, feature), - args[1].evaluate(frameState, feature), - args[2].evaluate(frameState, feature), - a, color); - } else if (this._value === 'hsl') { - Color.fromHsl( - args[0].evaluate(frameState, feature), - args[1].evaluate(frameState, feature), - args[2].evaluate(frameState, feature), - 1.0, color); - } else if (this._value === 'hsla') { - Color.fromHsl( - args[0].evaluate(frameState, feature), - args[1].evaluate(frameState, feature), - args[2].evaluate(frameState, feature), - args[3].evaluate(frameState, feature), - color); - } - return Cartesian4.fromColor(color, scratchStorage.getCartesian4()); + /** + * Picking features is not currently supported by this imagery provider, so this function simply returns + * undefined. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. + */ + GoogleEarthEnterpriseMapsProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return undefined; }; - Node.prototype._evaluateLiteralVector = function(frameState, feature) { - // Gather the components that make up the vector, which includes components from interior vectors. - // For example vec3(1, 2, 3) or vec3(vec2(1, 2), 3) are both valid. - // - // If the number of components does not equal the vector's size, then a RuntimeError is thrown - with two exceptions: - // 1. A vector may be constructed from a larger vector and drop the extra components. - // 2. A vector may be constructed from a single component - vec3(1) will become vec3(1, 1, 1). - // - // Examples of invalid constructors include: - // vec4(1, 2) // not enough components - // vec3(vec2(1, 2)) // not enough components - // vec3(1, 2, 3, 4) // too many components - // vec2(vec4(1), 1) // too many components + GoogleEarthEnterpriseMapsProvider._logoData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAAnCAYAAACmP2LfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAHdElNRQfcDB4TJDr1mp5kAAAAGnRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAB1zSURBVHhe7ZwHeFTFFsf/u+l9N70npOxuSAKEFFIhCSH0qhEQUHkgKCgWUFGBB6IoCAoo0ntooaRvEkIIBBBpoYSa3nvvfd+5u4sQUigPfMX8v2/Y3Tkzs3fv/d0z58zcgF69Ql1SY+MM1wQJem44ZeiJk8beEOqPwG6uC7ZqyElb9eo/JZEIkH2nRQkBIlNMauuPCS3uGN/kjkmNDghoskBAgzrZ2NLmf1+JwIKQpYsoxdmIV9+N07onCegzBPM9bOdmYKnazF6g/1N6UySPqSJzvCaaiLHtP8G/Phq+FRfgU5ogKWUXMLT6Mvzqr2BE40mMadqO8c3zMabBC6PqDDC8SlY60t9HByCLVTKu+ERmHr5TWI9wjVxEaOZivWo1pil8D1tZeWnLXv1l8iZ3PF2kjymiWRgvCoJv5U243IyAXcQq8A9Mg9W+4bDe6wv+kVGwCZkL+4Sf4ZR+BZ5VGQR3EkbWn8Hopm3wq54Lz2JD6ah/P21XGopQ9Qoc16jGSqVyTJWbQbUsibFXf42mihTwZpsvAtp3k0dOhFOSEH1+ngaDefrgjFCgFkxY8fCisCBvKgODzxRh9qslBFGfYmDGLbiV5mBwRRo8KtPhVBgPu8teMP7u73chD6kMRYRGBY5xqrFKqQwz5SdTbS/Qf5mmUYw8rf01CjHC4VP7AHZxO6E3qy9ZZCQNnio2rE/4o9/tkxiQUYp+KRXgx8XC5FsXcLz/hkCrDUU4pxLHuDVYpdwL9F+qqSJZKlPwenskfOoI5tN7YPCJGVme7wKYr5EBXzgYfW+mwTI0Gjrznaj2WW+I/y8dVPdDGLcKRzXrsEqlHO8oTKHaXqAZWe9hQXCi63NhHWYI3ilfWIW/YLjqL2JRiOFBJRz+LffhcPs09D+0J8vzn3zXdBnYnp8Mi6NboTWzH9X8fVc+DhDQodxqAroe36lU9AJNWr4cEAjNwI8OAC9cT1rbUfzwGeCfKiL7dGnNc+q1NiO80b4BY1oT4V6WDcsdc6j2xbyq4wMWrA9rQmeWFn36ey/jBaoPQ4hmLYI0G/AtAf22fC/QDols8ITrIYi/Bl6knbS2o3gRbxHQxQQ0k0S/gCa2v4OJovPwacqAQ1ICjL40klr+UrWoQbFBETo18jCpZsOoFODkvuCNJYoHW3QKXFEM7ETRcKfiQe8d6NVIFImXvg4skhY40mxnQYVRIIeA1qrHEc1GrFSpxFtP99AiFbDbNKDZpAzzGkVYVcvBuBJQEo/9/6C+dyjPitwLwak74D8V6Bfw0P5VShjXFoTR7TfhUZkL29M/wfATJan1lauWC3aDOgyaVDCuTgbf1bFkfmtkye1ogsK2asivLYfCglIoD8qCknI2NHuG4QSVGMgQyMbt0fioRYh9VYcRU7QX55uDcaHtFOJEsThMtmWtQgxsDodsWaC0c3ea3MzGBJEqxrfbYmzr6xjfPAeTmt5HQPO7eK1xDibUz8eY+k8xtHYJPCtXwvHOu7AXMrMTsF/TH8HajTis1YwVqpWY0TXQDKy1OpBr5EJA52Fukxx+bmKxtjWx2DuaWawNlZD5qhzyo9KhpHAbKpJO/6t65UCPbPHA2PYrGNacgkElabCJJDev/MpDhUKKnuq44LRoYEK1IiswkS1zYCfk5y+F0qjvoTwqBOof34dGeAnUL1ZCLboEnJ9zoe0QD/Nuj00UBVXRabzVLETM3S0ICfwA8yc7Y6C3ANYbZsA7aQ1W1xzEfZEQ6dT2BkG9pP4ouo7jGE1u42JS20QMrzkCr4xwuN4+AM+cYII3EaNar2J86zmMrP8DHulCON4NhU3YWuhOYy6SZENpH9cfx7WacFC7BSvUqjBDsRPQIiugURvazeqYVaqAw6dYrJ9WQy7gayj4nYDy3HtQOVQGpYRqKEWXQf2HdGha/AFdae9Xr4czz0ubISRA75ECbSut7agegO75OLxpahze8j5GtifBpzEDLiV30Dd2mNT6StWiCbVmLt5rUkBQCEt2zWzIMSA8HgrIBkLD+Sp0jhHISYXQ/KMYukfvQ3fQxq68XCTBHId/tMTg7LV1CFs4BszJ6hBarBgHlcRv8H7tbuSKQpFPYGe0BmND+nZ0npECaPKf0r4UIxsuoF/IMpitsAVnrA4s15uh3x8fwLXkLobUZGJIXTqcUzbDaJE5FAVq0t4S7dEcjqMEc6B2K5arVWN6Z6AbdOmm5mJelQKOHWSxF44Cy4CqxW0s6RwchCovFRohdGNfLgX3WiZ0N4aD++y7jfwYJUrAPCle/ZjKV+BFTSegrGAZIm3QjXhBytTWB3zhByzryMUU986jz16wD+96ijCNUIAgmkc3tS6G7GERjCbgR82B4OTbEESqIiCIcqsIYzoGGyrBEMSmgh8xBoIIAR2fAHZhj8Z9DOhl9FHeKkSDvn809fuc+iyCddRYaiOZBTvIt1YJfs0b4N+WDO+GHPLQN2Ab7S61vjJV60C9SRPvNSqzTpxlyQfS1dGUmjppK7gW16B/LhN6abnQu5cDwzO3YNhhqqK4WJY887sEdGzWFpxfOxmDpKZOOvgWFB8sx9L6nShvP4FyUQjKGg5gScpGKEqbUE7RxiGYv6QQ4zIG/r4D2m88sjEy/EIW/a6+TQ4gHe5VhXCvy4JL7gLYnesI2i6t4Tii04r92u1YKt767gB0ozrkGzmY26zEOh7Hkt+kAKhLTX9qOVVdg9aoNOjcToR+wUVKLYKgN0Zq7l7884wn9CKgr4AfWw/B6SwqKQRKOdXVghe9CpbherASSjtIpGpxRIHFjwygNreoXy0lb+lU7lHJBP9kPcGXQnBNghUB/Lh44fbUp5JA+5Hs71LbPPLCVRDEJZDNGIJgeQI6mG6KegKzldq1U7tGKjQmHR8vwl86kgRoAQN0xBw6ztn0nQ/ocxEdQ7L4d/BjG6g+m8aZTL/xsXPuW82Fb8t+DG1Ox5D6XAwqvQ67OA+p9ZWoUQPsei78mjSwNU9GLmEzVGZJTd3qFPTn3YZhXgYMMjNhlHsDxms/hNWfoUdrNPgEc2h7BG5d/Bo7Blt0BuNxXf4MVmXrkdRyEHWiY6hr2oc7mevRX2wc18gioEeI1+N9a+/CNnImVAZ0mhEoNOPAJT8MHjUF8KTiWhqHgbfMpVaJdhLQh3XasU9bJAZ6ekeg6zQwgEKuLSWysmd3QGmatLqD8qDNug3dCX/AIPk4jGr2wDB/JXTmkan70IvmZTY/rB9BdZlKLkG0lG0d5klAObKsw1+jzyFiWPnRawiaDrMYwTyMwMwh220WP2IWFVfqN4CKO8E3n0C6R/ZUej9Y2kUiMdDRFTRePH3nA3q/m7xpAEtAXl0QrkTwscnmS/3eptdzNEYevZLnZ5booqk8tuYs9tAny+n1LL1mghezlcULH0VtHamOZhvhIvoNOXQsd2EZIbluYnlWaMO75TCFG9kYXJ8H14o76H/10Z3yClSrCm6jGtbWK7LC7kIlYRfUmY2XHnUa+mbXYRSfCuNCptyE6b1jMBD/EPKwchQPLxGdxOWWI8iKXYBPqLozgI8pfA5YBWvxbfMeNLUfRmPTLjRnr8YKsdGvRQ5j2zZTSSRQ78H+7GhxfScFAINypsG9ukDspZ0LKKE+O0pqlGi71ggcIqD3dga6RhFKjSqYT+VEFkvu/E9Q+HNWKaE2VVDgVkPFqwAaay5CN3En9M59BM2vfKDs7AvljjPGE5LlharQdL+LoCmhOHU0rIUyD+NgVTOa+q2iVQiIcAKpHtbhXuJOjPqeVCRYThNE6VTvKNs3hM3cHGIxntxKyCbP7Erj1lHZJbVIJAG6iiCroZCAPGukvOyASJbvCgoaAoKoAQ1kHcGC7nmZDkmhBR2PfSQLtkcl4zCSAE2eO6qExYuYxrE4KqdvelBiM4+ncYQy1IY8d0wbhUSLJAZGbsUceNYdwJCGPAyuy4NbZToG3JoO1Qk9AvHvqF4ejo0KCKlisyl04Jw+AE1ma71HRUJP+QqM1t2HcVEyTEoSYVYQCuN3HenCt4XDhGA+KorAnYZ9KIj5ELOl3XpU/k/wrt+OmraDaG7cjpacbxFvYAAZDG5Vw/DWCxjRdp+ATsWAS6+D69H1+XDNsoVb1T06b0VwzCmBIOYdqUWibTojcFBH1CXQctBtUcA6Oh/RmVC4sBmKA5j6erC1qqE4sRpqG25A43QIOHuXgvOmP5R4ZH6m5UY2L9SSLjZ5sKjjsI/o8olH8ngjCZoSgmw9DMIl3t42Up0g+pq89/sEjLK47knZhSkSuDepJP4JOyNJyEFAR8VQKMOR1nbWM69yxNJYwh+VLE90ffPyxLE3EwL9Jq0huWQqwL1iA7zq8+FVl0+epgBO6T+gb2TH+OglqgastxtZrNNlkLt8E5oJx6HZdab7mFZBk3UZRjMewCT7HkzLfodZxREYr5sBjiIBPYiAPt8ehvSGPSg5vwjzpd16VNkmmDTswp22QDTXbkJrxhJkzHGDFoUQmvBpvo2hrZl0TnLhlLIYfUO7nt7dSg3hURcP1/JiDEgphuXBqVKLRFsfA3oJAf3mI6Cr2OjTwGYdqWGzzmZD6WoYVCfehdqsZKjuuwS1oB1Q+5piHac3oaxBzZ9vLZ4nHEeesoXg6niDPSYWP9yUgD5PHu48eKE64krHcErchHIEuRysTpAXjObQWIYEHiV4EQYEojp5aEoyY+IIpOQugKYYOnIdJXrdJ63PtWwXMQM6m6SVT4gfZkbHV0XHsVtaQ3K8yoJr0YfwoHDDq5ZiQSqDik/B4Q9taYtn18gyNia1qGJsmTrGlUjK2FJ1jCjRwOASDnkxDvN95ZD/og5yl0qgfCMJ2leDoeksHaFHXYOJVyrMkm/DrPwMzGr2wmjnLGipthyHL0W7t9pDkduwF2U3lmGFtvbTdyirt0OreT+iWwPRUrUBbSkLkT/fCUZwKVYikBMwpDlPXNzLwuAQ2rWX8KzUh2dDDJyLSmB7/S5Mf3WRWiR6CPSezkCXQs6qBnLCKsheyoXqnTCoL9oOFd9/Qtl9KJT6UJMX3/zhCz8iuCjhiviSYtMx3ZTJBN8lCE7eIRgF0p6krRRaRBDskTTGySBKws5SuUjJHYUiMQdpzCUE0Q3y5MnSDhJJQg5JUvjSgO5hHZofaioGmvc40IycMgbRtJktjgOZ5Ma9irzSg46xYHcaVEZevkgBHqUWGFK+FENKQ+BdGAq/wiMYWbwHI6h4FwTDOes0BMKFMHxPNg9qn1dANakYanfuQSs5FJoTpaP1qBswsSGgb9+EeUU0Af0LDH4dBhXlmv3wajuOpPYQFDcEojxtNQ6sn9ZzUsiofjfUWg/iYOt+tJatRtvN95DqZgxNuKTKwLV4Jdyqc8Wz1uCGTLjmDIVDQqewQ8anwpJi6GsYkF4Ey2O/QvsfXKlJIgboAwT07s5AZ0G1TylUIsuhdKMI6vcuQ3PVAqg+9UZ8JvGEywiuNoIwD4IzaV2X+HSa1otgE3+NwJImVkycG0kx8snfyUZJW+QFApeSu+hN9BpIn6n+ZBp9bqDv+C8Fum+8IpzzJNOmR3UhTaGFcC07iAHXmamuZw28C/S/aIt+CcthF7+ToN0EQdhqOFzcBu/Sm/ApvAGX3DzYXIiF9jtWTJf74L6ZC83UfGg8SId2xnloSZKxp+gWjC0J6KSrMK8KhmnlSugtInpkCzaBV78Hl5oPoaLpECrLt+Bi4jfgS7t1q+YDUGsPwj5KDFsLlqD97JuIpmpZmP+TftM1ezjlxsOllM4H3eReDWHwKrOBW84jqMeK5OBTv4Bu6HxxgqU1s/N3MkAHSoH+ioCe+gjoJHB0s8ENLID6/UJo3E+GVlwoNEwY278tXhR50RhmeexzgmM8JXjdF36MHwEoiXn70Csv6gxBm8PiRc6gJFD1HDzFpq1cP0omo5QJZAfqQzH0f6uHZjQgeR4cC/IJZCnUtSkYVPAWBiX2/CdU/S7Ql+9TgtFCTaiP0qAEXA2yRsqwuzECziWZcM4tgv2DSljF7ID+l+JNh9+hY38HuvcYmLOhk5EEnVPfQOmpW+33YGaXhj53E2BWuxvGebOh5cPUX/sWSgXrsa9mB2qaDqCK4C7I2IA3jn8u7tat2g6D034MIbWb0fZgHlr2DscXUhNNuYdkYRPrg/7JiXDMLYBrZS6GNEZgVJM/JjWY4I16G4xr/BCDq2nKjjoAvY+Zpwo7eXBskQK9Swr0lEdAn4a2wk3o/DMNWmn54KYUQIuZsebGQuXFQ42H4kfNk4QckSOkNZ1lGkGAUoInOKkAm2jJsVtH+om9Nj9ytZxNcNdhljXByo+JJXj/i4G2u2xM02YInPJLxFB7VudTPH0ZHkWu0hbPpwHpfnAszoFDVgVsb1fDMmoL9L8S7wTFQE/1AvR33oB+QSp0czKgl34B2iO9uwJCKib5SGaZjbqLPlkhMG1YDr1gQyioSs24vQTDitagsnIL6loCUVu9C2EJK9FjYtsWBNP2Q7hb9A155zdwY5mTeGexo0w32hEcy2F7JQaOqZfgk38KY6rDMKFBiGHNt+iGPgCNYd0/s/sbAb2fgN5JQC9Wq8bkR0AzioOOx3Xo30mGbnY+tNMKoJOQCm03qfnFxRf6E1yUFAqZJcyuZRWuQmB+TWHJcgJfkjPxImcSSIUsXviMx/O9DvqfALrPDjb6nhuBAWkZ5JFKKTYuIqhz4FUdAo9CGwzO7Ra2LjUg0w9OxdlwyKxAXzHQm8lDi4HeAT1WMPSHnYXR7aswKE6Gfl4K9PdfgZ6+uG8XSmMbKyXD/LsEmFduglH2NHA7rA3Hvg+Ve1/gYO4KNFRvQUPLQVRU7MG4yn1dJ4eiULAo3JhW9xsa77+Hml8GY8FQ425uAM5wRRivNoPlTjs4XhoH35oLGFZ/S/wglyDkbWmrrsUAvY+A3kHlSwJ6ihKzCvLnuQyElmIs9LdfhmHxA+jn5kI3jcrRFOjxU6DTbTx9DybsOBh0f034EeYEVyaFD0IYhnQ9y1pTIsiPvU5AnKYkUBL78yKmQhDLgDRPSWtPp/HFkFtHqFCfRBr73wX67qsD+qFsEubCnqKBAZllcCkkT12RjSHVMfApH0bJXfcH+aQGZg6FU1EWeeoK2NwgoMM3Q++zP/fq/Smf2g392ZEwzk2Acfl9GBHURmuSYPyn132oHBizH8B8wjX0SadQI2cWtOZZQbHTdEgRn8XN93EiczFayn5GU3Mg7lJMPab5SEeoCWZZ0TF4Ne/A/ZSPUbXdDz9Qdddrrk/KtcwR7jX34VXDzGCFGFT0GzyLu922x069kdiv145tOu34jlOHBWoz4arUAZQt0LYOhmFcHJ2H6zAsYnZDc2FwKhv60+m9UQrLUJ4hSYQAVhpM1O6jj30EDD33Q6frZyoY8cMVaWZZR560kuB5V9H6iVUas+Py5L1/IHsT2ZldR4nEkMdkUd8Y8tYd43mLIMhYhenDWvgjQSQiGFOkiEv0rEAzK2u8yG10M2WwBWFdb6q9NKDNd6rCOuYD9L2VI/57QMfcEniU5cCnJgG+lR9haAnz4MzT5ZjmA4e8HBqnGtYXamF+nK7bpx0uwHxoqGyE3sKD5HHjYVJ1C6Z5qTD5Ph2G1hnQEV/0LBhxU2E+4yYsbgTCJGsuNBfYQrnjA0CPxDo2CRYJ0xGesgD1ZWvQ3LQbKeSJ54uC0UcUDVVRGExFR/FB2y7cSf4C+Zv9sXSUeQ9P2z2pQdnmBHQsPKqKqFCyWJsM75o1GMw8O/iEhFZs/KK9CD9wRfhCTYTP1dqwnBOHrQYz8IuuH5ZxxI/MLQZH5kfoeu6D4cVQGNecgXHFbRgXZsD4Xg5MjqfDeE0KTBbRDLXsLiwOR8HkxCJoOs+Eavdr08ZBBGdYP7rYzAZILsH3LYUYtgSsAXlYRwLqW0r8Ksl2id4/Onaz47IE+kayUfwddYhsgwkqXRrLgOpHEuyhVF9B7ytoTAL//qNjeFagGfGEi5nvYPEifqOx/ek4p1J/8aKBWC8N6Icy2+oL6zOhECTmw46SuoHZpXBn/pK7/DK8K1bCp3Q0vAv7wqfIBD55OuS9teFVYASPfAFccseThw+E4Ho5LOMqYB6ZCeOdK6H1bleJH2sOOPZradqlC3otDqY5F2GafQmmCZdgFnMBZteEML2yCnprh0CZWVp66gbDuD5Q2uSLUacm43jSB0gq+h55JeuRX7wRqUUbkJL8DS4GTcPqCdZgduZ6XiZjgvcp9fIY3aAH/yY+3KvcMDBjLSXQBXDML4VbaQG8a9PgUxcOzyIneKY/Or6FHDO8q7INY+RiMFJaJijE4i2VeEylej/FDs99TAPH8Dvofv8bDK/vhVHxMRhX0W+vOgXTijiY5UXANGkNnYeRUGN2VrsPNx6XVaQNgRNM03sBgUjeOKJJ/Cr+LNzFsg61YB5/elyKtic0qM031CaZAG0gqJnVEuYBIoI49gy9D6DXrQR3GoU2j3YE+WE2FI9TGBG1FLywnhNbPt1Y/OhY+o5iGqsGNmdLaVxfqZUB+g0Iztwi2AOkNZ3FCzOm30bHeHK9tKYHKfPZMFhlAtM9c2EpjALv93zY3qlE/8xyOOUVUTiSBrfy83CvDIdbRZC4uJSGwzHzd0qgkmEVfRnGW/dC79vPobtkFLRmm0HDpVt43MnrzoOm/dfQeeOf0P3wB+guJogXrIDuhHfAsdOFbKdQ5GkaYQbNNYNht2c8/AOnYNKB6Ri//Q14zRwIuohdPC76pCbWKGFCkx9GNC7B0NZD8CiJh8Odi7A59zud7EuwvU4hVUYZBhUXwqsqA56V0RiUM1Dam36UoiyFuprQhc6fRZuKKhV5+rcLKD2hrPQ+NPsvgNb0j6C9eCG0v/kU2l9/BK0ZM8EdRJQ833noG8Qib6lDkA0lYD6i8GIJlffZ/IhhbJtQjW4TP164EiWWztTnH9T+a4L/MxpjAn02hWWYDAQnefSZzm7Io7zDOpiSzGh3grwPwd3zDccPZdH4phBEkXcWBrD4wlE07qObw5pmBUGsK43T/YPfgmAFWEe5U2EeCXhGcV5nQ3u2KrTf6w+jdTNhtud7mB/ZC4vg43QAwbAMDYLF0e3os+8HGP80D7oLx0F9dD+oj9AGZ4Y85K0Yj/Vs3kQiFgeybFPIySiDzdwAz9O3JzHjPNtYk8gjv948FOOatlGodR0Dk07Bau9n0F8wFBp+luBO1CXeuDD51Q3830PRP7UIzgUlcC0vhHPRSdic6eI53ecT3W0sKyjI2EFRxhzyz3sOO8voBkEUTclYhAyshCwr642PR79diwlbBOEs8vLMFjgbbuelhpeoz5rEDxsNNl/+9ON5RWJOLsXCysQdh5IhWWbzhUmoel6v/l/RxGpZTKgbh3EtEZQMp5AX2ASd2f3AVu7695ky/7nOuc2U/BZSCFIGp+I82F/rfprsVa/+Mk0sZ2F0tTvGNZ+gRO8B7C/HQ92beWine+/IDWDBbJUmbBN/hUNOGRyyStH34vfQeP3ZV4R61atXIu9Kefg1rIB/XRJciwso9nymLXmxbP+wxcCsVAxIKwfv1AZoDH96jN6rXr1SuVeowKsuFINrs+BSXATbc59JLU/XwCwdDMw7B/vUEpgHfQYZ7v9HCNar/2E55ynDpSwYrhXF4uKUeQiY0/Oy3kM555nCITcJgmvp0F30Yo8L9KpXL1X9E2XhkPoVBuYWwbmolKDOhmv+WHiXyGNkgbTRE1pOublXkRycCz+AfUoRzPdsgKJN1w/19KpXf7n6xlnCPikE/SkWdswrozDkNoZUfIWhFTYYWaPy4a6NkgSR2XAZXSOLIWUWcCv7FP1T7sH8wFZwp7ycxz971auXIm4AG+b77MFLEKLv7ULJMy0FefCsPAOv0t0YUrIMg0s+gVfxYrgVbIJLUSzsrl2F2ZZl4L7J/Pdp/956ca969UrEna0O41/HwSJ4F3in42Fz5Trsbt5Bv3u30e9uImyvnoV15GGY/LIA6kOZP1966pZ8r3r1n5eqhwZ0F/aB4ToHGK9zh/FPHjD60RE6H1tDaaA2cdy7mvFfI+BffksPNrEksu0AAAAASUVORK5CYII='; - var components = scratchStorage.getArray(); - var call = this._value; - var args = this._left; - var argsLength = args.length; - for (var i = 0; i < argsLength; ++i) { - var value = args[i].evaluate(frameState, feature); - if (typeof value === 'number') { - components.push(value); - } else if (value instanceof Cartesian2) { - components.push(value.x, value.y); - } else if (value instanceof Cartesian3) { - components.push(value.x, value.y, value.z); - } else if (value instanceof Cartesian4) { - components.push(value.x, value.y, value.z, value.w); - } else { - throw new RuntimeError(call + ' argument must be a vector or number. Argument is ' + value + '.'); - } - } + return GoogleEarthEnterpriseMapsProvider; +}); - var componentsLength = components.length; - var vectorLength = parseInt(call.charAt(3)); - if (componentsLength === 0) { - throw new RuntimeError('Invalid ' + call + ' constructor. No valid arguments.'); - } else if ((componentsLength < vectorLength) && (componentsLength > 1)) { - throw new RuntimeError('Invalid ' + call + ' constructor. Not enough arguments.'); - } else if ((componentsLength > vectorLength) && (argsLength > 1)) { - throw new RuntimeError('Invalid ' + call + ' constructor. Too many arguments.'); +define('Scene/MapboxImageryProvider',[ + '../Core/Credit', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/MapboxApi', + '../Core/Resource', + './UrlTemplateImageryProvider' + ], function( + Credit, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + MapboxApi, + Resource, + UrlTemplateImageryProvider) { + 'use strict'; + + var trailingSlashRegex = /\/$/; + var defaultCredit1 = new Credit({ + text:'© Mapbox © OpenStreetMap', + link: 'https://www.mapbox.com/about/maps/' + }); + var defaultCredit2 = [new Credit({ + text: 'Improve this map', + link: 'https://www.mapbox.com/map-feedback/' + })]; + + /** + * Provides tiled imagery hosted by Mapbox. + * + * @alias MapboxImageryProvider + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {String} [options.url='https://api.mapbox.com/v4/'] The Mapbox server url. + * @param {String} options.mapId The Mapbox Map ID. + * @param {String} [options.accessToken] The public access token for the imagery. + * @param {String} [options.format='png'] The format of the image request. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely + * to result in rendering problems. + * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * + * + * @example + * // Mapbox tile provider + * var mapbox = new Cesium.MapboxImageryProvider({ + * mapId: 'mapbox.streets', + * accessToken: 'thisIsMyAccessToken' + * }); + * + * @see {@link https://www.mapbox.com/developers/api/maps/#tiles} + * @see {@link https://www.mapbox.com/developers/api/#access-tokens} + */ + function MapboxImageryProvider(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var mapId = options.mapId; + if (!defined(mapId)) { + throw new DeveloperError('options.mapId is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('MapboxImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - if (componentsLength === 1) { - // Add the same component 3 more times - var component = components[0]; - components.push(component, component, component); + var url = options.url; + if (!defined(url)) { + url = 'https://api.mapbox.com/v4/'; } + this._url = url; - if (call === 'vec2') { - return Cartesian2.fromArray(components, 0, scratchStorage.getCartesian2()); - } else if (call === 'vec3') { - return Cartesian3.fromArray(components, 0, scratchStorage.getCartesian3()); - } else if (call === 'vec4') { - return Cartesian4.fromArray(components, 0, scratchStorage.getCartesian4()); + var resource = Resource.createIfNeeded(url, { + proxy: options.proxy + }); + + var accessToken = MapboxApi.getAccessToken(options.accessToken); + this._mapId = mapId; + this._accessToken = accessToken; + this._accessTokenErrorCredit = MapboxApi.getErrorCredit(options.accessToken); + var format = defaultValue(options.format, 'png'); + if (!/\./.test(format)) { + format = '.' + format; } - }; + this._format = format; - Node.prototype._evaluateLiteralString = function(frameState, feature) { - return this._value; - }; + var templateUrl = resource.getUrlComponent(); + if (!trailingSlashRegex.test(templateUrl)) { + templateUrl += '/'; + } + templateUrl += mapId + '/{z}/{x}/{y}' + this._format; + resource.url = templateUrl; - Node.prototype._evaluateVariableString = function(frameState, feature) { - var result = this._value; - var match = variableRegex.exec(result); - while (match !== null) { - var placeholder = match[0]; - var variableName = match[1]; - var property = feature.getProperty(variableName); - if (!defined(property)) { - property = ''; + resource.addQueryParameters({ + access_token: accessToken + }); + + if (defined(options.credit)) { + var credit = options.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); } - result = result.replace(placeholder, property); - match = variableRegex.exec(result); + defaultCredit1 = credit; + defaultCredit2.length = 0; } - return result; - }; - - Node.prototype._evaluateVariable = function(frameState, feature) { - // evaluates to undefined if the property name is not defined for that feature - return feature.getProperty(this._value); - }; - function checkFeature (ast) { - return (ast._value === 'feature'); + this._resource = resource; + this._imageryProvider = new UrlTemplateImageryProvider({ + url: resource, + credit: defaultCredit1, + ellipsoid: options.ellipsoid, + minimumLevel: options.minimumLevel, + maximumLevel: options.maximumLevel, + rectangle: options.rectangle + }); } - // PERFORMANCE_IDEA: Determine if parent property needs to be computed before runtime - Node.prototype._evaluateMemberDot = function(frameState, feature) { - if (checkFeature(this._left)) { - return feature.getProperty(this._right.evaluate(frameState, feature)); - } - var property = this._left.evaluate(frameState, feature); - if (!defined(property)) { - return undefined; - } + defineProperties(MapboxImageryProvider.prototype, { + /** + * Gets the URL of the Mapbox server. + * @memberof MapboxImageryProvider.prototype + * @type {String} + * @readonly + */ + url : { + get : function() { + return this._url; + } + }, - var member = this._right.evaluate(frameState, feature); - if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) { - // Vector components may be accessed with .r, .g, .b, .a and implicitly with .x, .y, .z, .w - if (member === 'r') { - return property.x; - } else if (member === 'g') { - return property.y; - } else if (member === 'b') { - return property.z; - } else if (member === 'a') { - return property.w; + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof MapboxImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._imageryProvider.ready; } - } - return property[member]; - }; + }, - Node.prototype._evaluateMemberBrackets = function(frameState, feature) { - if (checkFeature(this._left)) { - return feature.getProperty(this._right.evaluate(frameState, feature)); - } - var property = this._left.evaluate(frameState, feature); - if (!defined(property)) { - return undefined; - } + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof MapboxImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._imageryProvider.readyPromise; + } + }, - var member = this._right.evaluate(frameState, feature); - if ((property instanceof Cartesian2) || (property instanceof Cartesian3) || (property instanceof Cartesian4)) { - // Vector components may be accessed with [0][1][2][3], ['r']['g']['b']['a'] and implicitly with ['x']['y']['z']['w'] - // For Cartesian2 and Cartesian3 out-of-range components will just return undefined - if (member === 0 || member === 'r') { - return property.x; - } else if (member === 1 || member === 'g') { - return property.y; - } else if (member === 2 || member === 'b') { - return property.z; - } else if (member === 3 || member === 'a') { - return property.w; + /** + * Gets the rectangle, in radians, of the imagery provided by the instance. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle: { + get : function() { + return this._imageryProvider.rectangle; } - } - return property[member]; - }; + }, - Node.prototype._evaluateArray = function(frameState, feature) { - var array = []; - for (var i = 0; i < this._value.length; i++) { - array[i] = this._value[i].evaluate(frameState, feature); - } - return array; - }; + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileWidth : { + get : function() { + return this._imageryProvider.tileWidth; + } + }, - // PERFORMANCE_IDEA: Have "fast path" functions that deal only with specific types - // that we can assign if we know the types before runtime + /** + * Gets the height of each tile, in pixels. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileHeight : { + get : function() { + return this._imageryProvider.tileHeight; + } + }, - Node.prototype._evaluateNot = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - if (typeof left !== 'boolean') { - throw new RuntimeError('Operator "!" requires a boolean argument. Argument is ' + left + '.'); - } - return !left; - }; + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : function() { + return this._imageryProvider.maximumLevel; + } + }, - Node.prototype._evaluateNegative = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - if (left instanceof Cartesian2) { - return Cartesian2.negate(left, scratchStorage.getCartesian2()); - } else if (left instanceof Cartesian3) { - return Cartesian3.negate(left, scratchStorage.getCartesian3()); - } else if (left instanceof Cartesian4) { - return Cartesian4.negate(left, scratchStorage.getCartesian4()); - } else if (typeof left === 'number') { - return -left; - } + /** + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. Generally, + * a minimum level should only be used when the rectangle of the imagery is small + * enough that the number of tiles at the minimum level is small. An imagery + * provider with more than a few tiles at the minimum level will lead to + * rendering problems. + * @memberof MapboxImageryProvider.prototype + * @type {Number} + * @readonly + */ + minimumLevel : { + get : function() { + return this._imageryProvider.minimumLevel; + } + }, - throw new RuntimeError('Operator "-" requires a vector or number argument. Argument is ' + left + '.'); - }; + /** + * Gets the tiling scheme used by the provider. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {TilingScheme} + * @readonly + */ + tilingScheme : { + get : function() { + return this._imageryProvider.tilingScheme; + } + }, - Node.prototype._evaluatePositive = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + */ + tileDiscardPolicy : { + get : function() { + return this._imageryProvider.tileDiscardPolicy; + } + }, - if (!((left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4) || (typeof left === 'number'))) { - throw new RuntimeError('Operator "+" requires a vector or number argument. Argument is ' + left + '.'); - } + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error.. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof MapboxImageryProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._imageryProvider.errorEvent; + } + }, - return left; - }; + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * @memberof MapboxImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return this._imageryProvider.credit; + } + }, - Node.prototype._evaluateLessThan = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + /** + * Gets the proxy used by this provider. + * @memberof MapboxImageryProvider.prototype + * @type {Proxy} + * @readonly + */ + proxy : { + get : function() { + return this._imageryProvider.proxy; + } + }, - if ((typeof left !== 'number') || (typeof right !== 'number')) { - throw new RuntimeError('Operator "<" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof MapboxImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { + get : function() { + return this._imageryProvider.hasAlphaChannel; + } } + }); - return left < right; + /** + * Gets the credits to be displayed when a given tile is displayed. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + */ + MapboxImageryProvider.prototype.getTileCredits = function(x, y, level) { + var credits = defaultCredit2.slice(); + if (defined(this._accessTokenErrorCredit)) { + credits.push(this._accessTokenErrorCredit); + } + return credits; }; - Node.prototype._evaluateLessThanOrEquals = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - - if ((typeof left !== 'number') || (typeof right !== 'number')) { - throw new RuntimeError('Operator "<=" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); - } + /** + * Requests the image for a given tile. This function should + * not be called before {@link MapboxImageryProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + */ + MapboxImageryProvider.prototype.requestImage = function(x, y, level, request) { + return this._imageryProvider.requestImage(x, y, level, request); + }; - return left <= right; + /** + * Asynchronously determines what features, if any, are located at a given longitude and latitude within + * a tile. This function should not be called before {@link MapboxImageryProvider#ready} returns true. + * This function is optional, so it may not exist on all ImageryProviders. + * + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. + * + * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + */ + MapboxImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return this._imageryProvider.pickFeatures(x, y, level, longitude, latitude); }; - Node.prototype._evaluateGreaterThan = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + return MapboxImageryProvider; +}); - if ((typeof left !== 'number') || (typeof right !== 'number')) { - throw new RuntimeError('Operator ">" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); +define('Scene/SingleTileImageryProvider',[ + '../Core/Credit', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/deprecationWarning', + '../Core/DeveloperError', + '../Core/Event', + '../Core/GeographicTilingScheme', + '../Core/Rectangle', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/TileProviderError', + '../ThirdParty/when' + ], function( + Credit, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + Event, + GeographicTilingScheme, + Rectangle, + Resource, + RuntimeError, + TileProviderError, + when) { + 'use strict'; + + /** + * Provides a single, top-level imagery tile. The single image is assumed to use a + * {@link GeographicTilingScheme}. + * + * @alias SingleTileImageryProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url for the tile. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * + * @see ArcGisMapServerImageryProvider + * @see BingMapsImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + */ + function SingleTileImageryProvider(options) { + options = defaultValue(options, {}); + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('SingleTileImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - return left > right; - }; + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); - Node.prototype._evaluateGreaterThanOrEquals = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + var rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE); + var tilingScheme = new GeographicTilingScheme({ + rectangle : rectangle, + numberOfLevelZeroTilesX : 1, + numberOfLevelZeroTilesY : 1, + ellipsoid : options.ellipsoid + }); + this._tilingScheme = tilingScheme; + this._resource = resource; + this._image = undefined; + this._texture = undefined; + this._tileWidth = 0; + this._tileHeight = 0; - if ((typeof left !== 'number') || (typeof right !== 'number')) { - throw new RuntimeError('Operator ">=" requires number arguments. Arguments are ' + left + ' and ' + right + '.'); + this._errorEvent = new Event(); + + this._ready = false; + this._readyPromise = when.defer(); + + var credit = options.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); } + this._credit = credit; - return left >= right; - }; + var that = this; + var error; - Node.prototype._evaluateOr = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - if (typeof left !== 'boolean') { - throw new RuntimeError('Operator "||" requires boolean arguments. First argument is ' + left + '.'); + function success(image) { + that._image = image; + that._tileWidth = image.width; + that._tileHeight = image.height; + that._ready = true; + that._readyPromise.resolve(true); + TileProviderError.handleSuccess(that._errorEvent); } - // short circuit the expression - if (left) { - return true; + function failure(e) { + var message = 'Failed to load image ' + resource.url + '.'; + error = TileProviderError.handleError( + error, + that, + that._errorEvent, + message, + 0, 0, 0, + doRequest, + e); + that._readyPromise.reject(new RuntimeError(message)); } - var right = this._right.evaluate(frameState, feature); - if (typeof right !== 'boolean') { - throw new RuntimeError('Operator "||" requires boolean arguments. Second argument is ' + right + '.'); + function doRequest() { + when(resource.fetchImage(), success, failure); } - return left || right; - }; + doRequest(); + } - Node.prototype._evaluateAnd = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - if (typeof left !== 'boolean') { - throw new RuntimeError('Operator "&&" requires boolean arguments. First argument is ' + left + '.'); - } + defineProperties(SingleTileImageryProvider.prototype, { + /** + * Gets the URL of the single, top-level imagery tile. + * @memberof SingleTileImageryProvider.prototype + * @type {String} + * @readonly + */ + url : { + get : function() { + return this._resource.url; + } + }, - // short circuit the expression - if (!left) { - return false; - } + /** + * Gets the proxy used by this provider. + * @memberof SingleTileImageryProvider.prototype + * @type {Proxy} + * @readonly + */ + proxy : { + get : function() { + return this._resource.proxy; + } + }, - var right = this._right.evaluate(frameState, feature); - if (typeof right !== 'boolean') { - throw new RuntimeError('Operator "&&" requires boolean arguments. Second argument is ' + right + '.'); - } + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileWidth : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); + } + + return this._tileWidth; + } + }, - return left && right; - }; + /** + * Gets the height of each tile, in pixels. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileHeight: { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + } + + return this._tileHeight; + } + }, - Node.prototype._evaluatePlus = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { - return Cartesian2.add(left, right, scratchStorage.getCartesian2()); - } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { - return Cartesian3.add(left, right, scratchStorage.getCartesian3()); - } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return Cartesian4.add(left, right, scratchStorage.getCartesian4()); - } else if ((typeof left === 'string') || (typeof right === 'string')) { - // If only one argument is a string the other argument calls its toString function. - return left + right; - } else if ((typeof left === 'number') && (typeof right === 'number')) { - return left + right; - } + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : function() { + if (!this._ready) { + throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); + } + + return 0; + } + }, - throw new RuntimeError('Operator "+" requires vector or number arguments of matching types, or at least one string argument. Arguments are ' + left + ' and ' + right + '.'); - }; + /** + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {Number} + * @readonly + */ + minimumLevel : { + get : function() { + if (!this._ready) { + throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); + } + + return 0; + } + }, - Node.prototype._evaluateMinus = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { - return Cartesian2.subtract(left, right, scratchStorage.getCartesian2()); - } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { - return Cartesian3.subtract(left, right, scratchStorage.getCartesian3()); - } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return Cartesian4.subtract(left, right, scratchStorage.getCartesian4()); - } else if ((typeof left === 'number') && (typeof right === 'number')) { - return left - right; - } + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {TilingScheme} + * @readonly + */ + tilingScheme : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme; + } + }, - throw new RuntimeError('Operator "-" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); - }; + /** + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle : { + get : function() { + return this._tilingScheme.rectangle; + } + }, - Node.prototype._evaluateTimes = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { - return Cartesian2.multiplyComponents(left, right, scratchStorage.getCartesian2()); - } else if ((right instanceof Cartesian2) && (typeof left === 'number')) { - return Cartesian2.multiplyByScalar(right, left, scratchStorage.getCartesian2()); - } else if ((left instanceof Cartesian2) && (typeof right === 'number')) { - return Cartesian2.multiplyByScalar(left, right, scratchStorage.getCartesian2()); - } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { - return Cartesian3.multiplyComponents(left, right, scratchStorage.getCartesian3()); - } else if ((right instanceof Cartesian3) && (typeof left === 'number')) { - return Cartesian3.multiplyByScalar(right, left, scratchStorage.getCartesian3()); - } else if ((left instanceof Cartesian3) && (typeof right === 'number')) { - return Cartesian3.multiplyByScalar(left, right, scratchStorage.getCartesian3()); - } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return Cartesian4.multiplyComponents(left, right, scratchStorage.getCartesian4()); - } else if ((right instanceof Cartesian4) && (typeof left === 'number')) { - return Cartesian4.multiplyByScalar(right, left, scratchStorage.getCartesian4()); - } else if ((left instanceof Cartesian4) && (typeof right === 'number')) { - return Cartesian4.multiplyByScalar(left, right, scratchStorage.getCartesian4()); - } else if ((typeof left === 'number') && (typeof right === 'number')) { - return left * right; - } + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + */ + tileDiscardPolicy : { + get : function() { + if (!this._ready) { + throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); + } + + return undefined; + } + }, - throw new RuntimeError('Operator "*" requires vector or number arguments. If both arguments are vectors they must be matching types. Arguments are ' + left + ' and ' + right + '.'); - }; + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof SingleTileImageryProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, - Node.prototype._evaluateDivide = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { - return Cartesian2.divideComponents(left, right, scratchStorage.getCartesian2()); - } else if ((left instanceof Cartesian2) && (typeof right === 'number')) { - return Cartesian2.divideByScalar(left, right, scratchStorage.getCartesian2()); - } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { - return Cartesian3.divideComponents(left, right, scratchStorage.getCartesian3()); - } else if ((left instanceof Cartesian3) && (typeof right === 'number')) { - return Cartesian3.divideByScalar(left, right, scratchStorage.getCartesian3()); - } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return Cartesian4.divideComponents(left, right, scratchStorage.getCartesian4()); - } else if ((left instanceof Cartesian4) && (typeof right === 'number')) { - return Cartesian4.divideByScalar(left, right, scratchStorage.getCartesian4()); - } else if ((typeof left === 'number') && (typeof right === 'number')) { - return left / right; - } + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof SingleTileImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; + } + }, + + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof SingleTileImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + }, - throw new RuntimeError('Operator "/" requires vector or number arguments of matching types, or a number as the second argument. Arguments are ' + left + ' and ' + right + '.'); - }; + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link SingleTileImageryProvider#ready} returns true. + * @memberof SingleTileImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return this._credit; + } + }, - Node.prototype._evaluateMod = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2)) { - return Cartesian2.fromElements(left.x % right.x, left.y % right.y, scratchStorage.getCartesian2()); - } else if ((right instanceof Cartesian3) && (left instanceof Cartesian3)) { - return Cartesian3.fromElements(left.x % right.x, left.y % right.y, left.z % right.z, scratchStorage.getCartesian3()); - } else if ((right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return Cartesian4.fromElements(left.x % right.x, left.y % right.y, left.z % right.z, left.w % right.w, scratchStorage.getCartesian4()); - } else if ((typeof left === 'number') && (typeof right === 'number')) { - return left % right; + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof SingleTileImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { + get : function() { + return true; + } } + }); - throw new RuntimeError('Operator "%" requires vector or number arguments of matching types. Arguments are ' + left + ' and ' + right + '.'); + /** + * Gets the credits to be displayed when a given tile is displayed. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + */ + SingleTileImageryProvider.prototype.getTileCredits = function(x, y, level) { + return undefined; }; - Node.prototype._evaluateEqualsStrict = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2) || - (right instanceof Cartesian3) && (left instanceof Cartesian3) || - (right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return left.equals(right); + /** + * Requests the image for a given tile. This function should + * not be called before {@link SingleTileImageryProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + */ + SingleTileImageryProvider.prototype.requestImage = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); } - return left === right; + + return this._image; }; - Node.prototype._evaluateNotEqualsStrict = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); - if ((right instanceof Cartesian2) && (left instanceof Cartesian2) || - (right instanceof Cartesian3) && (left instanceof Cartesian3) || - (right instanceof Cartesian4) && (left instanceof Cartesian4)) { - return !left.equals(right); - } - return left !== right; + /** + * Picking features is not currently supported by this imagery provider, so this function simply returns + * undefined. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. + */ + SingleTileImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return undefined; }; - Node.prototype._evaluateConditional = function(frameState, feature) { - var test = this._test.evaluate(frameState, feature); + return SingleTileImageryProvider; +}); - if (typeof test !== 'boolean') { - throw new RuntimeError('Conditional argument of conditional expression must be a boolean. Argument is ' + test + '.'); - } +define('Scene/GetFeatureInfoFormat',[ + '../Core/Cartographic', + '../Core/defined', + '../Core/DeveloperError', + '../Core/RuntimeError', + './ImageryLayerFeatureInfo' + ], function( + Cartographic, + defined, + DeveloperError, + RuntimeError, + ImageryLayerFeatureInfo) { + 'use strict'; - if (test) { - return this._left.evaluate(frameState, feature); + /** + * Describes the format in which to request GetFeatureInfo from a Web Map Service (WMS) server. + * + * @alias GetFeatureInfoFormat + * @constructor + * + * @param {String} type The type of response to expect from a GetFeatureInfo request. Valid + * values are 'json', 'xml', 'html', or 'text'. + * @param {String} [format] The info format to request from the WMS server. This is usually a + * MIME type such as 'application/json' or text/xml'. If this parameter is not specified, the provider will request 'json' + * using 'application/json', 'xml' using 'text/xml', 'html' using 'text/html', and 'text' using 'text/plain'. + * @param {Function} [callback] A function to invoke with the GetFeatureInfo response from the WMS server + * in order to produce an array of picked {@link ImageryLayerFeatureInfo} instances. If this parameter is not specified, + * a default function for the type of response is used. + */ + function GetFeatureInfoFormat(type, format, callback) { + if (!defined(type)) { + throw new DeveloperError('type is required.'); } - return this._right.evaluate(frameState, feature); - }; - - Node.prototype._evaluateNaN = function(frameState, feature) { - return isNaN(this._left.evaluate(frameState, feature)); - }; + + this.type = type; - Node.prototype._evaluateIsFinite = function(frameState, feature) { - return isFinite(this._left.evaluate(frameState, feature)); - }; + if (!defined(format)) { + if (type === 'json') { + format = 'application/json'; + } else if (type === 'xml') { + format = 'text/xml'; + } else if (type === 'html') { + format = 'text/html'; + } else if (type === 'text') { + format = 'text/plain'; + } + else { + throw new DeveloperError('format is required when type is not "json", "xml", "html", or "text".'); + } + } - Node.prototype._evaluateIsExactClass = function(frameState, feature) { - return feature.isExactClass(this._left.evaluate(frameState, feature)); - }; + this.format = format; - Node.prototype._evaluateIsClass = function(frameState, feature) { - return feature.isClass(this._left.evaluate(frameState, feature)); - }; + if (!defined(callback)) { + if (type === 'json') { + callback = geoJsonToFeatureInfo; + } else if (type === 'xml') { + callback = xmlToFeatureInfo; + } else if (type === 'html') { + callback = textToFeatureInfo; + } else if (type === 'text') { + callback = textToFeatureInfo; + } + else { + throw new DeveloperError('callback is required when type is not "json", "xml", "html", or "text".'); + } + } - Node.prototype._evaluategetExactClassName = function(frameState, feature) { - return feature.getExactClassName(); - }; + this.callback = callback; + } - Node.prototype._evaluateBooleanConversion = function(frameState, feature) { - return Boolean(this._left.evaluate(frameState, feature)); - }; + function geoJsonToFeatureInfo(json) { + var result = []; - Node.prototype._evaluateNumberConversion = function(frameState, feature) { - return Number(this._left.evaluate(frameState, feature)); - }; + var features = json.features; + for (var i = 0; i < features.length; ++i) { + var feature = features[i]; - Node.prototype._evaluateStringConversion = function(frameState, feature) { - return String(this._left.evaluate(frameState, feature)); - }; + var featureInfo = new ImageryLayerFeatureInfo(); + featureInfo.data = feature; + featureInfo.properties = feature.properties; + featureInfo.configureNameFromProperties(feature.properties); + featureInfo.configureDescriptionFromProperties(feature.properties); - Node.prototype._evaluateRegExp = function(frameState, feature) { - var pattern = this._value.evaluate(frameState, feature); - var flags = ''; + // If this is a point feature, use the coordinates of the point. + if (defined(feature.geometry) && feature.geometry.type === 'Point') { + var longitude = feature.geometry.coordinates[0]; + var latitude = feature.geometry.coordinates[1]; + featureInfo.position = Cartographic.fromDegrees(longitude, latitude); + } - if (defined(this._left)) { - flags = this._left.evaluate(frameState, feature); + result.push(featureInfo); } - var exp; - try { - exp = new RegExp(pattern, flags); - } catch (e) { - throw new RuntimeError(e); - } - return exp; - }; + return result; + } - Node.prototype._evaluateRegExpTest = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + var mapInfoMxpNamespace = 'http://www.mapinfo.com/mxp'; + var esriWmsNamespace = 'http://www.esri.com/wms'; + var wfsNamespace = 'http://www.opengis.net/wfs'; + var gmlNamespace = 'http://www.opengis.net/gml'; - if (!((left instanceof RegExp) && (typeof right === 'string'))) { - throw new RuntimeError('RegExp.test requires the first argument to be a RegExp and the second argument to be a string. Arguments are ' + left + ' and ' + right + '.'); + function xmlToFeatureInfo(xml) { + var documentElement = xml.documentElement; + if (documentElement.localName === 'MultiFeatureCollection' && documentElement.namespaceURI === mapInfoMxpNamespace) { + // This looks like a MapInfo MXP response + return mapInfoXmlToFeatureInfo(xml); + } else if (documentElement.localName === 'FeatureInfoResponse' && documentElement.namespaceURI === esriWmsNamespace) { + // This looks like an Esri WMS response + return esriXmlToFeatureInfo(xml); + } else if (documentElement.localName === 'FeatureCollection' && documentElement.namespaceURI === wfsNamespace) { + // This looks like a WFS/GML response. + return gmlToFeatureInfo(xml); + } else if (documentElement.localName === 'ServiceExceptionReport') { + // This looks like a WMS server error, so no features picked. + throw new RuntimeError(new XMLSerializer().serializeToString(documentElement)); + } else if (documentElement.localName === 'msGMLOutput') { + return msGmlToFeatureInfo(xml); + } else { + // Unknown response type, so just dump the XML itself into the description. + return unknownXmlToFeatureInfo(xml); } + } - return left.test(right); - }; + function mapInfoXmlToFeatureInfo(xml) { + var result = []; - Node.prototype._evaluateRegExpMatch = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + var multiFeatureCollection = xml.documentElement; - if ((left instanceof RegExp) && (typeof right === 'string')) { - return left.test(right); - } else if ((right instanceof RegExp) && (typeof left === 'string')) { - return right.test(left); - } + var features = multiFeatureCollection.getElementsByTagNameNS(mapInfoMxpNamespace, 'Feature'); + for (var featureIndex = 0; featureIndex < features.length; ++featureIndex) { + var feature = features[featureIndex]; - throw new RuntimeError('Operator "=~" requires one RegExp argument and one string argument. Arguments are ' + left + ' and ' + right + '.'); - }; + var properties = {}; - Node.prototype._evaluateRegExpNotMatch = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + var propertyElements = feature.getElementsByTagNameNS(mapInfoMxpNamespace, 'Val'); + for (var propertyIndex = 0; propertyIndex < propertyElements.length; ++propertyIndex) { + var propertyElement = propertyElements[propertyIndex]; + if (propertyElement.hasAttribute('ref')) { + var name = propertyElement.getAttribute('ref'); + var value = propertyElement.textContent.trim(); + properties[name] = value; + } + } - if ((left instanceof RegExp) && (typeof right === 'string')) { - return !(left.test(right)); - } else if ((right instanceof RegExp) && (typeof left === 'string')) { - return !(right.test(left)); + var featureInfo = new ImageryLayerFeatureInfo(); + featureInfo.data = feature; + featureInfo.properties = properties; + featureInfo.configureNameFromProperties(properties); + featureInfo.configureDescriptionFromProperties(properties); + result.push(featureInfo); } - throw new RuntimeError('Operator "!~" requires one RegExp argument and one string argument. Arguments are ' + left + ' and ' + right + '.'); - }; - - Node.prototype._evaluateRegExpExec = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - var right = this._right.evaluate(frameState, feature); + return result; + } - if (!((left instanceof RegExp) && (typeof right === 'string'))) { - throw new RuntimeError('RegExp.exec requires the first argument to be a RegExp and the second argument to be a string. Arguments are ' + left + ' and ' + right + '.'); - } + function esriXmlToFeatureInfo(xml) { + var featureInfoResponse = xml.documentElement; + var result = []; + var properties; - var exec = left.exec(right); - if (!defined(exec)) { - return null; - } - return exec[1]; - }; + var features = featureInfoResponse.getElementsByTagNameNS('*', 'FIELDS'); + if (features.length > 0) { + // Standard esri format + for (var featureIndex = 0; featureIndex < features.length; ++featureIndex) { + var feature = features[featureIndex]; - Node.prototype._evaluateToString = function(frameState, feature) { - var left = this._left.evaluate(frameState, feature); - if ((left instanceof RegExp) || (left instanceof Cartesian2) || (left instanceof Cartesian3) || (left instanceof Cartesian4)) { - return String(left); - } + properties = {}; - throw new RuntimeError('Unexpected function call "' + this._value + '".'); - }; + var propertyAttributes = feature.attributes; + for (var attributeIndex = 0; attributeIndex < propertyAttributes.length; ++attributeIndex) { + var attribute = propertyAttributes[attributeIndex]; + properties[attribute.name] = attribute.value; + } - function convertHSLToRGB(ast) { - // Check if the color contains any nested expressions to see if the color can be converted here. - // E.g. "hsl(0.9, 0.6, 0.7)" is able to convert directly to rgb, "hsl(0.9, 0.6, ${Height})" is not. - var channels = ast._left; - var length = channels.length; - for (var i = 0; i < length; ++i) { - if (channels[i]._type !== ExpressionNodeType.LITERAL_NUMBER) { - return undefined; + result.push(imageryLayerFeatureInfoFromDataAndProperties(feature, properties)); } - } - var h = channels[0]._value; - var s = channels[1]._value; - var l = channels[2]._value; - var a = (length === 4) ? channels[3]._value : 1.0; - return Color.fromHsl(h, s, l, a, scratchColor); - } + } else { + // Thredds format -- looks like esri, but instead of containing FIELDS, contains FeatureInfo element + var featureInfoElements = featureInfoResponse.getElementsByTagNameNS('*', 'FeatureInfo'); + for (var featureInfoElementIndex = 0; featureInfoElementIndex < featureInfoElements.length; ++featureInfoElementIndex) { + var featureInfoElement = featureInfoElements[featureInfoElementIndex]; - function convertRGBToColor(ast) { - // Check if the color contains any nested expressions to see if the color can be converted here. - // E.g. "rgb(255, 255, 255)" is able to convert directly to Color, "rgb(255, 255, ${Height})" is not. - var channels = ast._left; - var length = channels.length; - for (var i = 0; i < length; ++i) { - if (channels[i]._type !== ExpressionNodeType.LITERAL_NUMBER) { - return undefined; - } - } - var color = scratchColor; - color.red = channels[0]._value / 255.0; - color.green = channels[1]._value / 255.0; - color.blue = channels[2]._value / 255.0; - color.alpha = (length === 4) ? channels[3]._value : 1.0; - return color; - } + properties = {}; - function numberToString(number) { - if (number % 1 === 0) { - // Add a .0 to whole numbers - return number.toFixed(1); + // node.children is not supported in IE9-11, so use childNodes and check that child.nodeType is an element + var featureInfoChildren = featureInfoElement.childNodes; + for (var childIndex = 0; childIndex < featureInfoChildren.length; ++childIndex) { + var child = featureInfoChildren[childIndex]; + if (child.nodeType === Node.ELEMENT_NODE) { + properties[child.localName] = child.textContent; + } + } + + result.push(imageryLayerFeatureInfoFromDataAndProperties(featureInfoElement, properties)); + } } - return number.toString(); + return result; } - function colorToVec3(color) { - var r = numberToString(color.red); - var g = numberToString(color.green); - var b = numberToString(color.blue); - return 'vec3(' + r + ', ' + g + ', ' + b + ')'; - } + function gmlToFeatureInfo(xml) { + var result = []; - function colorToVec4(color) { - var r = numberToString(color.red); - var g = numberToString(color.green); - var b = numberToString(color.blue); - var a = numberToString(color.alpha); - return 'vec4(' + r + ', ' + g + ', ' + b + ', ' + a + ')'; - } + var featureCollection = xml.documentElement; - function getExpressionArray(array, attributePrefix, shaderState, parent) { - var length = array.length; - var expressions = new Array(length); - for (var i = 0; i < length; ++i) { - expressions[i] = array[i].getShaderExpression(attributePrefix, shaderState, parent); + var featureMembers = featureCollection.getElementsByTagNameNS(gmlNamespace, 'featureMember'); + for (var featureIndex = 0; featureIndex < featureMembers.length; ++featureIndex) { + var featureMember = featureMembers[featureIndex]; + + var properties = {}; + getGmlPropertiesRecursively(featureMember, properties); + result.push(imageryLayerFeatureInfoFromDataAndProperties(featureMember, properties)); } - return expressions; + + return result; } - Node.prototype.getShaderExpression = function(attributePrefix, shaderState, parent) { - var color; - var left; - var right; - var test; + // msGmlToFeatureInfo is similar to gmlToFeatureInfo, but assumes different XML structure + // eg. <msGMLOutput> <ABC_layer> <ABC_feature> <foo>bar</foo> ... </ABC_feature> </ABC_layer> </msGMLOutput> - var type = this._type; - var value = this._value; + function msGmlToFeatureInfo(xml) { + var result = []; - if (defined(this._left)) { - if (isArray(this._left)) { - // Left can be an array if the type is LITERAL_COLOR or LITERAL_VECTOR - left = getExpressionArray(this._left, attributePrefix, shaderState, this); - } else { - left = this._left.getShaderExpression(attributePrefix, shaderState, this); + // Find the first child. Except for IE, this would work: + // var layer = xml.documentElement.children[0]; + var layer; + var children = xml.documentElement.childNodes; + for (var i = 0; i < children.length; i++) { + if (children[i].nodeType === Node.ELEMENT_NODE) { + layer = children[i]; + break; } } - - if (defined(this._right)) { - right = this._right.getShaderExpression(attributePrefix, shaderState, this); - } - - if (defined(this._test)) { - test = this._test.getShaderExpression(attributePrefix, shaderState, this); + if (!defined(layer)) { + throw new RuntimeError('Unable to find first child of the feature info xml document'); } - - if (isArray(this._value)) { - // For ARRAY type - value = getExpressionArray(this._value, attributePrefix, shaderState, this); + var featureMembers = layer.childNodes; + for (var featureIndex = 0; featureIndex < featureMembers.length; ++featureIndex) { + var featureMember = featureMembers[featureIndex]; + if (featureMember.nodeType === Node.ELEMENT_NODE) { + var properties = {}; + getGmlPropertiesRecursively(featureMember, properties); + result.push(imageryLayerFeatureInfoFromDataAndProperties(featureMember, properties)); + } } - switch (type) { - case ExpressionNodeType.VARIABLE: - return attributePrefix + value; - case ExpressionNodeType.UNARY: - // Supported types: +, -, !, Boolean, Number - if (value === 'Boolean') { - return 'bool(' + left + ')'; - } else if (value === 'Number') { - return 'float(' + left + ')'; - } else if (value === 'round') { - return 'floor(' + left + ' + 0.5)'; - } else if (defined(unaryFunctions[value])) { - return value + '(' + left + ')'; - } else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass') || (value === 'getExactClassName')) { - throw new RuntimeError('Error generating style shader: "' + value + '" is not supported.'); - } else if (defined(unaryFunctions[value])) { - return value + '(' + left + ')'; - } - return value + left; - case ExpressionNodeType.BINARY: - // Supported types: ||, &&, ===, !==, <, >, <=, >=, +, -, *, /, % - if (value === '%') { - return 'mod(' + left + ', ' + right + ')'; - } else if (value === '===') { - return '(' + left + ' == ' + right + ')'; - } else if (value === '!==') { - return '(' + left + ' != ' + right + ')'; - } else if (value === 'atan2') { - return 'atan(' + left + ', ' + right + ')'; - } else if (defined(binaryFunctions[value])) { - return value + '(' + left + ', ' + right + ')'; - } - return '(' + left + ' ' + value + ' ' + right + ')'; - case ExpressionNodeType.TERNARY: - if (defined(ternaryFunctions[value])) { - return value + '(' + left + ', ' + right + ', ' + test + ')'; - } - break; - case ExpressionNodeType.CONDITIONAL: - return '(' + test + ' ? ' + left + ' : ' + right + ')'; - case ExpressionNodeType.MEMBER: - // This is intended for accessing the components of vector properties. String members aren't supported. - // Check for 0.0 rather than 0 because all numbers are previously converted to decimals. - if (right === 'r' || right === 'x' || right === '0.0') { - return left + '[0]'; - } else if (right === 'g' || right === 'y' || right === '1.0') { - return left + '[1]'; - } else if (right === 'b' || right === 'z' || right === '2.0') { - return left + '[2]'; - } else if (right === 'a' || right === 'w' || right === '3.0') { - return left + '[3]'; - } - return left + '[int(' + right + ')]'; - case ExpressionNodeType.FUNCTION_CALL: - throw new RuntimeError('Error generating style shader: "' + value + '" is not supported.'); - case ExpressionNodeType.ARRAY: - if (value.length === 4) { - return 'vec4(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + value[3] + ')'; - } else if (value.length === 3) { - return 'vec3(' + value[0] + ', ' + value[1] + ', ' + value[2] + ')'; - } else if (value.length === 2) { - return 'vec2(' + value[0] + ', ' + value[1] + ')'; - } - throw new RuntimeError('Error generating style shader: Invalid array length. Array length should be 2, 3, or 4.'); - case ExpressionNodeType.REGEX: - throw new RuntimeError('Error generating style shader: Regular expressions are not supported.'); - case ExpressionNodeType.VARIABLE_IN_STRING: - throw new RuntimeError('Error generating style shader: Converting a variable to a string is not supported.'); - case ExpressionNodeType.LITERAL_NULL: - throw new RuntimeError('Error generating style shader: null is not supported.'); - case ExpressionNodeType.LITERAL_BOOLEAN: - return value ? 'true' : 'false'; - case ExpressionNodeType.LITERAL_NUMBER: - return numberToString(value); - case ExpressionNodeType.LITERAL_STRING: - if (defined(parent) && (parent._type === ExpressionNodeType.MEMBER)) { - if (value === 'r' || value === 'g' || value === 'b' || value === 'a' || - value === 'x' || value === 'y' || value === 'z' || value === 'w') { - return value; - } - } - // Check for css color strings - color = Color.fromCssColorString(value, scratchColor); - if (defined(color)) { - return colorToVec3(color); - } - throw new RuntimeError('Error generating style shader: String literals are not supported.'); - case ExpressionNodeType.LITERAL_COLOR: - var args = left; - if (value === 'color') { - if (!defined(args)) { - return 'vec4(1.0)'; - } else if (args.length > 1) { - var rgb = args[0]; - var alpha = args[1]; - if (alpha !== '1.0') { - shaderState.translucent = true; - } - return 'vec4(' + rgb + ', ' + alpha + ')'; - } - return 'vec4(' + args[0] + ', 1.0)'; - } else if (value === 'rgb') { - color = convertRGBToColor(this); - if (defined(color)) { - return colorToVec4(color); - } - return 'vec4(' + args[0] + ' / 255.0, ' + args[1] + ' / 255.0, ' + args[2] + ' / 255.0, 1.0)'; - } else if (value === 'rgba') { - if (args[3] !== '1.0') { - shaderState.translucent = true; - } - color = convertRGBToColor(this); - if (defined(color)) { - return colorToVec4(color); - } - return 'vec4(' + args[0] + ' / 255.0, ' + args[1] + ' / 255.0, ' + args[2] + ' / 255.0, ' + args[3] + ')'; - } else if (value === 'hsl') { - color = convertHSLToRGB(this); - if (defined(color)) { - return colorToVec4(color); - } - return 'vec4(czm_HSLToRGB(vec3(' + args[0] + ', ' + args[1] + ', ' + args[2] + ')), 1.0)'; - } else if (value === 'hsla') { - color = convertHSLToRGB(this); - if (defined(color)) { - if (color.alpha !== 1.0) { - shaderState.translucent = true; - } - return colorToVec4(color); - } - if (args[3] !== '1.0') { - shaderState.translucent = true; - } - return 'vec4(czm_HSLToRGB(vec3(' + args[0] + ', ' + args[1] + ', ' + args[2] + ')), ' + args[3] + ')'; - } - break; - case ExpressionNodeType.LITERAL_VECTOR: - if (!defined(left)) { - throw new DeveloperError('left should always be defined for type ExpressionNodeType.LITERAL_VECTOR'); - } - var length = left.length; - var vectorExpression = value + '('; - for (var i = 0; i < length; ++i) { - vectorExpression += left[i]; - if (i < (length - 1)) { - vectorExpression += ', '; - } - } - vectorExpression += ')'; - return vectorExpression; - case ExpressionNodeType.LITERAL_REGEX: - throw new RuntimeError('Error generating style shader: Regular expressions are not supported.'); - case ExpressionNodeType.LITERAL_UNDEFINED: - throw new RuntimeError('Error generating style shader: undefined is not supported.'); - case ExpressionNodeType.BUILTIN_VARIABLE: - if (value === 'tiles3d_tileset_time') { - return 'u_tilesetTime'; - } - } - }; + return result; + } - return Expression; -}); + function getGmlPropertiesRecursively(gmlNode, properties) { + var isSingleValue = true; -define('Scene/ConditionsExpression',[ - '../Core/clone', - '../Core/defined', - '../Core/defineProperties', - './Expression' - ], function( - clone, - defined, - defineProperties, - Expression) { - 'use strict'; + for (var i = 0; i < gmlNode.childNodes.length; ++i) { + var child = gmlNode.childNodes[i]; - /** - * An expression for a style applied to a {@link Cesium3DTileset}. - * <p> - * Evaluates a conditions expression defined using the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. - * </p> - * <p> - * Implements the {@link StyleExpression} interface. - * </p> - * - * @alias ConditionsExpression - * @constructor - * - * @param {Object} [conditionsExpression] The conditions expression defined using the 3D Tiles Styling language. - * @param {Object} [defines] Defines in the style. - * - * @example - * var expression = new Cesium.ConditionsExpression({ - * conditions : [ - * ['${Area} > 10, 'color("#FF0000")'], - * ['${id} !== "1"', 'color("#00FF00")'], - * ['true', 'color("#FFFFFF")'] - * ] - * }); - * expression.evaluateColor(frameState, feature, result); // returns a Cesium.Color object - */ - function ConditionsExpression(conditionsExpression, defines) { - this._conditionsExpression = clone(conditionsExpression, true); - this._conditions = conditionsExpression.conditions; - this._runtimeConditions = undefined; + if (child.nodeType === Node.ELEMENT_NODE) { + isSingleValue = false; + } - setRuntime(this, defines); - } + if (child.localName === 'Point' || child.localName === 'LineString' || child.localName === 'Polygon' || child.localName === 'boundedBy') { + continue; + } - defineProperties(ConditionsExpression.prototype, { - /** - * Gets the conditions expression defined in the 3D Tiles Styling language. - * - * @memberof ConditionsExpression.prototype - * - * @type {Object} - * @readonly - * - * @default undefined - */ - conditionsExpression : { - get : function() { - return this._conditionsExpression; + if (child.hasChildNodes() && getGmlPropertiesRecursively(child, properties)) { + properties[child.localName] = child.textContent; } } - }); - function Statement(condition, expression) { - this.condition = condition; - this.expression = expression; + return isSingleValue; } - function setRuntime(expression, defines) { - var runtimeConditions = []; - var conditions = expression._conditions; - if (!defined(conditions)) { - return; - } - var length = conditions.length; - for (var i = 0; i < length; ++i) { - var statement = conditions[i]; - var cond = String(statement[0]); - var condExpression = String(statement[1]); - runtimeConditions.push(new Statement( - new Expression(cond, defines), - new Expression(condExpression, defines) - )); - } - expression._runtimeConditions = runtimeConditions; + function imageryLayerFeatureInfoFromDataAndProperties(data, properties) { + var featureInfo = new ImageryLayerFeatureInfo(); + featureInfo.data = data; + featureInfo.properties = properties; + featureInfo.configureNameFromProperties(properties); + featureInfo.configureDescriptionFromProperties(properties); + return featureInfo; } - /** - * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of - * the expression in the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} - * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript - * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code> - * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>, - * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is - * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. - * - * @param {FrameState} frameState The frame state. - * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Object} [result] The object onto which to store the result. - * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. - */ - ConditionsExpression.prototype.evaluate = function(frameState, feature, result) { - var conditions = this._runtimeConditions; - if (!defined(conditions)) { - return undefined; - } - var length = conditions.length; - for (var i = 0; i < length; ++i) { - var statement = conditions[i]; - if (statement.condition.evaluate(frameState, feature)) { - return statement.expression.evaluate(frameState, feature, result); - } - } - }; + function unknownXmlToFeatureInfo(xml) { + var xmlText = new XMLSerializer().serializeToString(xml); - /** - * Evaluates the result of a Color expression, using the values defined by a feature. - * <p> - * This is equivalent to {@link ConditionsExpression#evaluate} but always returns a {@link Color} object. - * </p> - * @param {FrameState} frameState The frame state. - * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Color} [result] The object in which to store the result - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. - */ - ConditionsExpression.prototype.evaluateColor = function(frameState, feature, result) { - var conditions = this._runtimeConditions; - if (!defined(conditions)) { + var element = document.createElement('div'); + var pre = document.createElement('pre'); + pre.textContent = xmlText; + element.appendChild(pre); + + var featureInfo = new ImageryLayerFeatureInfo(); + featureInfo.data = xml; + featureInfo.description = element.innerHTML; + return [featureInfo]; + } + + var emptyBodyRegex= /<body>\s*<\/body>/im; + var wmsServiceExceptionReportRegex = /<ServiceExceptionReport([\s\S]*)<\/ServiceExceptionReport>/im; + var titleRegex = /<title>([\s\S]*)<\/title>/im; + + function textToFeatureInfo(text) { + // If the text is HTML and it has an empty body tag, assume it means no features were found. + if (emptyBodyRegex.test(text)) { return undefined; } - var length = conditions.length; - for (var i = 0; i < length; ++i) { - var statement = conditions[i]; - if (statement.condition.evaluate(frameState, feature)) { - return statement.expression.evaluateColor(frameState, feature, result); - } - } - }; - /** - * Gets the shader function for this expression. - * Returns undefined if the shader function can't be generated from this expression. - * - * @param {String} functionName Name to give to the generated function. - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * @param {String} returnType The return type of the generated function. - * - * @returns {String} The shader function. - * - * @private - */ - ConditionsExpression.prototype.getShaderFunction = function(functionName, attributePrefix, shaderState, returnType) { - var conditions = this._runtimeConditions; - if (!defined(conditions) || conditions.length === 0) { + // If this is a WMS exception report, treat it as "no features found" rather than showing + // bogus feature info. + if (wmsServiceExceptionReportRegex.test(text)) { return undefined; } - var shaderFunction = ''; - var length = conditions.length; - for (var i = 0; i < length; ++i) { - var statement = conditions[i]; - - var condition = statement.condition.getShaderExpression(attributePrefix, shaderState); - var expression = statement.expression.getShaderExpression(attributePrefix, shaderState); - - // Build the if/else chain from the list of conditions - shaderFunction += - ' ' + ((i === 0) ? 'if' : 'else if') + ' (' + condition + ') \n' + - ' { \n' + - ' return ' + expression + '; \n' + - ' } \n'; + // If the text has a <title> element, use it as the name. + var name; + var title = titleRegex.exec(text); + if (title && title.length > 1) { + name = title[1]; } - shaderFunction = returnType + ' ' + functionName + '() \n' + - '{ \n' + - shaderFunction + - ' return ' + returnType + '(1.0); \n' + // Return a default value if no conditions are met - '} \n'; - - return shaderFunction; - }; + var featureInfo = new ImageryLayerFeatureInfo(); + featureInfo.name = name; + featureInfo.description = text; + featureInfo.data = text; + return [featureInfo]; + } - return ConditionsExpression; + return GetFeatureInfoFormat; }); -define('Scene/Cesium3DTileStyle',[ - '../Core/clone', +define('Scene/WebMapServiceImageryProvider',[ + '../Core/combine', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/DeveloperError', - '../Core/loadJson', - '../ThirdParty/when', - './ConditionsExpression', - './Expression' + '../Core/freezeObject', + '../Core/GeographicTilingScheme', + '../Core/objectToQuery', + '../Core/queryToObject', + '../Core/Resource', + '../Core/WebMercatorTilingScheme', + '../ThirdParty/Uri', + './GetFeatureInfoFormat', + './UrlTemplateImageryProvider' ], function( - clone, + combine, defaultValue, defined, defineProperties, + deprecationWarning, DeveloperError, - loadJson, - when, - ConditionsExpression, - Expression) { + freezeObject, + GeographicTilingScheme, + objectToQuery, + queryToObject, + Resource, + WebMercatorTilingScheme, + Uri, + GetFeatureInfoFormat, + UrlTemplateImageryProvider) { 'use strict'; /** - * A style that is applied to a {@link Cesium3DTileset}. - * <p> - * Evaluates an expression defined using the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. - * </p> + * Provides tiled imagery hosted by a Web Map Service (WMS) server. * - * @alias Cesium3DTileStyle + * @alias WebMapServiceImageryProvider * @constructor * - * @param {String|Object} [style] The url of a style or an object defining a style. + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The URL of the WMS service. The URL supports the same keywords as the {@link UrlTemplateImageryProvider}. + * @param {String} options.layers The layers to include, separated by commas. + * @param {Object} [options.parameters=WebMapServiceImageryProvider.DefaultParameters] Additional parameters to pass to the WMS server in the GetMap URL. + * @param {Object} [options.getFeatureInfoParameters=WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters] Additional parameters to pass to the WMS server in the GetFeatureInfo URL. + * @param {Boolean} [options.enablePickFeatures=true] If true, {@link WebMapServiceImageryProvider#pickFeatures} will invoke + * the GetFeatureInfo operation on the WMS server and return the features included in the response. If false, + * {@link WebMapServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) + * without communicating with the server. Set this property to false if you know your WMS server does not support + * GetFeatureInfo or if you don't want this provider's features to be pickable. Note that this can be dynamically + * overridden by modifying the WebMapServiceImageryProvider#enablePickFeatures property. + * @param {GetFeatureInfoFormat[]} [options.getFeatureInfoFormats=WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats] The formats + * in which to try WMS GetFeatureInfo requests. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. + * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * @param {Number} [options.tileWidth=256] The width of each tile in pixels. + * @param {Number} [options.tileHeight=256] The height of each tile in pixels. + * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when + * specifying this that the number of tiles at the minimum level is small, such as four or less. A larger number is + * likely to result in rendering problems. + * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * If not specified, there is no limit. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. + * If this parameter is a single string, each character in the string is a subdomain. If it is + * an array, each element in the array is a subdomain. * - * @example - * tileset.style = new Cesium.Cesium3DTileStyle({ - * color : { - * conditions : [ - * ['${Height} >= 100', 'color("purple", 0.5)'], - * ['${Height} >= 50', 'color("red")'], - * ['true', 'color("blue")'] - * ] - * }, - * show : '${Height} > 0', - * meta : { - * description : '"Building id ${id} has height ${Height}."' - * } - * }); + * @see ArcGisMapServerImageryProvider + * @see BingMapsImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + * + * @see {@link http://resources.esri.com/help/9.3/arcgisserver/apis/rest/|ArcGIS Server REST API} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * * @example - * tileset.style = new Cesium.Cesium3DTileStyle({ - * color : 'vec4(${Temperature})', - * pointSize : '${Temperature} * 2.0' + * var provider = new Cesium.WebMapServiceImageryProvider({ + * url : 'https://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer', + * layers : '0', + * proxy: new Cesium.DefaultProxy('/proxy/') * }); * - * @see {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} + * viewer.imageryLayers.addImageryProvider(provider); */ - function Cesium3DTileStyle(style) { - this._style = undefined; - this._ready = false; - this._color = undefined; - this._show = undefined; - this._pointSize = undefined; - this._meta = undefined; + function WebMapServiceImageryProvider(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._colorShaderFunction = undefined; - this._showShaderFunction = undefined; - this._pointSizeShaderFunction = undefined; - this._colorShaderFunctionReady = false; - this._showShaderFunctionReady = false; - this._pointSizeShaderFunctionReady = false; + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); + } + if (!defined(options.layers)) { + throw new DeveloperError('options.layers is required.'); + } + + if (defined(options.proxy)) { + deprecationWarning('WebMapServiceImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); + } - var promise; - if (typeof style === 'string') { - promise = loadJson(style); + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); + + var pickFeatureResource = resource.clone(); + + resource.addQueryParameters(WebMapServiceImageryProvider.DefaultParameters, true); + pickFeatureResource.addQueryParameters(WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters, true); + + if (defined(options.parameters)) { + resource.addQueryParameters(objectToLowercase(options.parameters)); + } + + if (defined(options.getFeatureInfoParameters)) { + pickFeatureResource.addQueryParameters(objectToLowercase(options.getFeatureInfoParameters)); + } + + var parameters = {}; + parameters.layers = options.layers; + parameters.bbox = '{westProjected},{southProjected},{eastProjected},{northProjected}'; + parameters.width = '{width}'; + parameters.height = '{height}'; + + // Use SRS or CRS based on the WMS version. + if (parseFloat(resource.queryParameters.version) >= 1.3) { + // Use CRS with 1.3.0 and going forward. + // For GeographicTilingScheme, use CRS:84 vice EPSG:4326 to specify lon, lat (x, y) ordering for + // bbox requests. + parameters.crs = options.tilingScheme instanceof WebMercatorTilingScheme ? 'EPSG:3857' : 'CRS:84'; } else { - promise = when.resolve(style); + // SRS for WMS 1.1.0 or 1.1.1. + parameters.srs = options.tilingScheme instanceof WebMercatorTilingScheme ? 'EPSG:3857' : 'EPSG:4326'; } - var that = this; - this._readyPromise = promise.then(function(styleJson) { - setup(that, styleJson); - return that; + resource.addQueryParameters(parameters, true); + pickFeatureResource.addQueryParameters(parameters, true); + + var pickFeatureParams = { + query_layers: options.layers, + x: '{i}', + y: '{j}', + info_format: '{format}' + }; + pickFeatureResource.addQueryParameters(pickFeatureParams, true); + + this._resource = resource; + this._pickFeaturesResource = pickFeatureResource; + this._layers = options.layers; + + // Let UrlTemplateImageryProvider do the actual URL building. + this._tileProvider = new UrlTemplateImageryProvider({ + url : resource, + pickFeaturesUrl : pickFeatureResource, + tilingScheme : defaultValue(options.tilingScheme, new GeographicTilingScheme({ ellipsoid : options.ellipsoid})), + rectangle : options.rectangle, + tileWidth : options.tileWidth, + tileHeight : options.tileHeight, + minimumLevel : options.minimumLevel, + maximumLevel : options.maximumLevel, + subdomains: options.subdomains, + tileDiscardPolicy : options.tileDiscardPolicy, + credit : options.credit, + getFeatureInfoFormats : defaultValue(options.getFeatureInfoFormats, WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats), + enablePickFeatures: options.enablePickFeatures }); } - function setup(that, styleJson) { - that._style = clone(styleJson, true); + defineProperties(WebMapServiceImageryProvider.prototype, { + /** + * Gets the URL of the WMS server. + * @memberof WebMapServiceImageryProvider.prototype + * @type {String} + * @readonly + */ + url : { + get : function() { + return this._resource._url; + } + }, - styleJson = defaultValue(styleJson, defaultValue.EMPTY_OBJECT); + /** + * Gets the proxy used by this provider. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Proxy} + * @readonly + */ + proxy : { + get : function() { + return this._resource.proxy; + } + }, - that.color = styleJson.color; - that.show = styleJson.show; - that.pointSize = styleJson.pointSize; + /** + * Gets the names of the WMS layers, separated by commas. + * @memberof WebMapServiceImageryProvider.prototype + * @type {String} + * @readonly + */ + layers : { + get : function() { + return this._layers; + } + }, - var meta = {}; - if (defined(styleJson.meta)) { - var defines = styleJson.defines; - var metaJson = defaultValue(styleJson.meta, defaultValue.EMPTY_OBJECT); - for (var property in metaJson) { - if (metaJson.hasOwnProperty(property)) { - meta[property] = new Expression(metaJson[property], defines); - } + /** + * Gets the width of each tile, in pixels. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileWidth : { + get : function() { + return this._tileProvider.tileWidth; } - } + }, - that._meta = meta; + /** + * Gets the height of each tile, in pixels. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number} + * @readonly + */ + tileHeight : { + get : function() { + return this._tileProvider.tileHeight; + } + }, - that._ready = true; - } + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : function() { + return this._tileProvider.maximumLevel; + } + }, - defineProperties(Cesium3DTileStyle.prototype, { /** - * Gets the object defining the style using the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {Object} + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number} * @readonly - * - * @default undefined - * - * @exception {DeveloperError} The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true. */ - style : { + minimumLevel : { get : function() { - if (!this._ready) { - throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); - } - - return this._style; + return this._tileProvider.minimumLevel; } }, /** - * When <code>true</code>, the style is ready and its expressions can be evaluated. When - * a style is constructed with an object, as opposed to a url, this is <code>true</code> immediately. - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {Boolean} + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {TilingScheme} * @readonly - * - * @default false */ - ready : { + tilingScheme : { get : function() { - return this._ready; + return this._tileProvider.tilingScheme; } }, /** - * Gets the promise that will be resolved when the the style is ready and its expressions can be evaluated. - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {Promise.<Cesium3DTileStyle>} + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Rectangle} * @readonly */ - readyPromise : { + rectangle : { get : function() { - return this._readyPromise; + return this._tileProvider.rectangle; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>show</code> property. Alternatively a boolean, string, or object defining a show style can be used. - * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. - * <p> - * The expression must return or convert to a <code>Boolean</code>. - * </p> - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {StyleExpression} - * - * @exception {DeveloperError} The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true. - * - * @example - * var style = new Cesium3DTileStyle({ - * show : '(regExp("^Chest").test(${County})) && (${YearBuilt} >= 1970)' - * }); - * style.show.evaluate(frameState, feature); // returns true or false depending on the feature's properties - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override show expression with a custom function - * style.show = { - * evaluate : function(frameState, feature) { - * return true; - * } - * }; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override show expression with a boolean - * style.show = true; - * }; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override show expression with a string - * style.show = '${Height} > 0'; - * }; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override show expression with a condition - * style.show = { - * conditions: [ - * ['${height} > 2', 'false'], - * ['true', 'true'] - * ]; - * }; + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly */ - show : { + tileDiscardPolicy : { get : function() { - if (!this._ready) { - throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); - } - - return this._show; - }, - set : function(value) { - var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (!defined(value)) { - this._show = undefined; - } else if (typeof value === 'boolean') { - this._show = new Expression(String(value)); - } else if (typeof value === 'string') { - this._show = new Expression(value, defines); - } else if (defined(value.conditions)) { - this._show = new ConditionsExpression(value, defines); - } else { - this._show = value; - } - this._showShaderFunctionReady = false; + return this._tileProvider.tileDiscardPolicy; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>color</code> property. Alternatively a string or object defining a color style can be used. - * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. - * <p> - * The expression must return a <code>Color</code>. - * </p> - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {StyleExpression} - * - * @exception {DeveloperError} The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true. - * - * @example - * var style = new Cesium3DTileStyle({ - * color : '(${Temperature} > 90) ? color("red") : color("white")' - * }); - * style.color.evaluateColor(frameState, feature, result); // returns a Cesium.Color object - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override color expression with a custom function - * style.color = { - * evaluateColor : function(frameState, feature, result) { - * return Cesium.Color.clone(Cesium.Color.WHITE, result); - * } - * }; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override color expression with a string - * style.color = 'color("blue")'; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override color expression with a condition - * style.color = { - * conditions : [ - * ['${height} > 2', 'color("cyan")'], - * ['true', 'color("blue")'] - * ] - * }; + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Event} + * @readonly */ - color : { + errorEvent : { get : function() { - if (!this._ready) { - throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); - } - - return this._color; - }, - set : function(value) { - var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (!defined(value)) { - this._color = undefined; - } else if (typeof value === 'string') { - this._color = new Expression(value, defines); - } else if (defined(value.conditions)) { - this._color = new ConditionsExpression(value, defines); - } else { - this._color = value; - } - this._colorShaderFunctionReady = false; + return this._tileProvider.errorEvent; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's <code>pointSize</code> property. Alternatively a number, string, or object defining a pointSize style can be used. - * The getter will return the internal {@link Expression} or {@link ConditionsExpression}, which may differ from the value provided to the setter. - * <p> - * The expression must return or convert to a <code>Number</code>. - * </p> - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {StyleExpression} - * - * @exception {DeveloperError} The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true. - * - * @example - * var style = new Cesium3DTileStyle({ - * pointSize : '(${Temperature} > 90) ? 2.0 : 1.0' - * }); - * style.pointSize.evaluate(frameState, feature); // returns a Number - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override pointSize expression with a custom function - * style.pointSize = { - * evaluate : function(frameState, feature) { - * return 1.0; - * } - * }; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override pointSize expression with a number - * style.pointSize = 1.0; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override pointSize expression with a string - * style.pointSize = '${height} / 10'; - * - * @example - * var style = new Cesium.Cesium3DTileStyle(); - * // Override pointSize expression with a condition - * style.pointSize = { - * conditions : [ - * ['${height} > 2', '1.0'], - * ['true', '2.0'] - * ] - * }; + * Gets a value indicating whether or not the provider is ready for use. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Boolean} + * @readonly */ - pointSize : { + ready : { get : function() { - if (!this._ready) { - throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); - } - - return this._pointSize; - }, - set : function(value) { - var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (!defined(value)) { - this._pointSize = undefined; - } else if (typeof value === 'number') { - this._pointSize = new Expression(String(value)); - } else if (typeof value === 'string') { - this._pointSize = new Expression(value, defines); - } else if (defined(value.conditions)) { - this._pointSize = new ConditionsExpression(value, defines); - } else { - this._pointSize = value; - } - this._pointSizeShaderFunctionReady = false; + return this._tileProvider.ready; } }, /** - * Gets or sets the object containing application-specific expression that can be explicitly - * evaluated, e.g., for display in a UI. - * - * @memberof Cesium3DTileStyle.prototype - * - * @type {StyleExpression} - * - * @exception {DeveloperError} The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true. - * - * @example - * var style = new Cesium3DTileStyle({ - * meta : { - * description : '"Building id ${id} has height ${Height}."' - * } - * }); - * style.meta.description.evaluate(frameState, feature); // returns a String with the substituted variables + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly */ - meta : { + readyPromise : { get : function() { - if (!this._ready) { - throw new DeveloperError('The style is not loaded. Use Cesium3DTileStyle.readyPromise or wait for Cesium3DTileStyle.ready to be true.'); - } - - return this._meta; + return this._tileProvider.readyPromise; + } + }, + + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return this._tileProvider.credit; + } + }, + + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { + get : function() { + return this._tileProvider.hasAlphaChannel; + } + }, + + /** + * Gets or sets a value indicating whether feature picking is enabled. If true, {@link WebMapServiceImageryProvider#pickFeatures} will + * invoke the <code>GetFeatureInfo</code> service on the WMS server and attempt to interpret the features included in the response. If false, + * {@link WebMapServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable + * features) without communicating with the server. Set this property to false if you know your data + * source does not support picking features or if you don't want this provider's features to be pickable. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Boolean} + * @default true + */ + enablePickFeatures : { + get : function() { + return this._tileProvider.enablePickFeatures; }, - set : function(value) { - this._meta = value; + set : function(enablePickFeatures) { + this._tileProvider.enablePickFeatures = enablePickFeatures; } } }); /** - * Gets the color shader function for this style. - * - * @param {String} functionName Name to give to the generated function. - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * Gets the credits to be displayed when a given tile is displayed. * - * @returns {String} The shader function. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. * - * @private + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - Cesium3DTileStyle.prototype.getColorShaderFunction = function(functionName, attributePrefix, shaderState) { - if (this._colorShaderFunctionReady) { - // Return the cached result, may be undefined - return this._colorShaderFunction; - } - - this._colorShaderFunctionReady = true; - this._colorShaderFunction = defined(this.color) ? this.color.getShaderFunction(functionName, attributePrefix, shaderState, 'vec4') : undefined; - return this._colorShaderFunction; + WebMapServiceImageryProvider.prototype.getTileCredits = function(x, y, level) { + return this._tileProvider.getTileCredits(x, y, level); }; /** - * Gets the show shader function for this style. - * - * @param {String} functionName Name to give to the generated function. - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * Requests the image for a given tile. This function should + * not be called before {@link WebMapServiceImageryProvider#ready} returns true. * - * @returns {String} The shader function. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. * - * @private + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */ - Cesium3DTileStyle.prototype.getShowShaderFunction = function(functionName, attributePrefix, shaderState) { - if (this._showShaderFunctionReady) { - // Return the cached result, may be undefined - return this._showShaderFunction; - } - - this._showShaderFunctionReady = true; - this._showShaderFunction = defined(this.show) ? this.show.getShaderFunction(functionName, attributePrefix, shaderState, 'bool') : undefined; - return this._showShaderFunction; + WebMapServiceImageryProvider.prototype.requestImage = function(x, y, level, request) { + return this._tileProvider.requestImage(x, y, level, request); }; /** - * Gets the pointSize shader function for this style. + * Asynchronously determines what features, if any, are located at a given longitude and latitude within + * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. * - * @param {String} functionName Name to give to the generated function. - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. * - * @returns {String} The shader function. + * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + */ + WebMapServiceImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return this._tileProvider.pickFeatures(x, y, level, longitude, latitude); + }; + + /** + * The default parameters to include in the WMS URL to obtain images. The values are as follows: + * service=WMS + * version=1.1.1 + * request=GetMap + * styles= + * format=image/jpeg * - * @private + * @constant */ - Cesium3DTileStyle.prototype.getPointSizeShaderFunction = function(functionName, attributePrefix, shaderState) { - if (this._pointSizeShaderFunctionReady) { - // Return the cached result, may be undefined - return this._pointSizeShaderFunction; - } + WebMapServiceImageryProvider.DefaultParameters = freezeObject({ + service : 'WMS', + version : '1.1.1', + request : 'GetMap', + styles : '', + format : 'image/jpeg' + }); - this._pointSizeShaderFunctionReady = true; - this._pointSizeShaderFunction = defined(this.pointSize) ? this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float') : undefined; - return this._pointSizeShaderFunction; - }; + /** + * The default parameters to include in the WMS URL to get feature information. The values are as follows: + * service=WMS + * version=1.1.1 + * request=GetFeatureInfo + * + * @constant + */ + WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters = freezeObject({ + service : 'WMS', + version : '1.1.1', + request : 'GetFeatureInfo' + }); - return Cesium3DTileStyle; + WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats = freezeObject([ + freezeObject(new GetFeatureInfoFormat('json', 'application/json')), + freezeObject(new GetFeatureInfoFormat('xml', 'text/xml')), + freezeObject(new GetFeatureInfoFormat('text', 'text/html')) + ]); + + function objectToLowercase(obj) { + var result = {}; + for ( var key in obj) { + if (obj.hasOwnProperty(key)) { + result[key.toLowerCase()] = obj[key]; + } + } + return result; + } + + return WebMapServiceImageryProvider; }); -define('Scene/CircleEmitter',[ - '../Core/Cartesian3', +define('Scene/TimeDynamicImagery',[ '../Core/Check', '../Core/defaultValue', + '../Core/defined', '../Core/defineProperties', - '../Core/Math' + '../Core/DeveloperError', + '../Core/JulianDate', + '../Core/Request', + '../Core/RequestType' ], function( - Cartesian3, Check, defaultValue, + defined, defineProperties, - CesiumMath) { + DeveloperError, + JulianDate, + Request, + RequestType) { 'use strict'; /** - * A ParticleEmitter that emits particles from a circle. - * Particles will be positioned within a circle and have initial velocities going along the z vector. + * Provides functionality for ImageryProviders that have time dynamic imagery * - * @alias CircleEmitter + * @alias TimeDynamicImagery * @constructor * - * @param {Number} [radius=1.0] The radius of the circle in meters. + * @param {Object} options Object with the following properties: + * @param {Clock} options.clock A Clock instance that is used when determining the value for the time dimension. Required when options.times is specified. + * @param {TimeIntervalCollection} options.times TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values. + * @param {Function} options.requestImageFunction A function that will request imagery tiles. + * @param {Function} options.reloadFunction A function that will be called when all imagery tiles need to be reloaded. */ - function CircleEmitter(radius) { - radius = defaultValue(radius, 1.0); + function TimeDynamicImagery(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - Check.typeOf.number.greaterThan('radius', radius, 0.0); + Check.typeOf.object('options.clock', options.clock); + Check.typeOf.object('options.times', options.times); + Check.typeOf.func('options.requestImageFunction', options.requestImageFunction); + Check.typeOf.func('options.reloadFunction', options.reloadFunction); - this._radius = defaultValue(radius, 1.0); + this._tileCache = {}; + this._tilesRequestedForInterval = []; + + var clock = this._clock = options.clock; + this._times = options.times; + this._requestImageFunction = options.requestImageFunction; + this._reloadFunction = options.reloadFunction; + this._currentIntervalIndex = -1; + + clock.onTick.addEventListener(this._clockOnTick, this); + this._clockOnTick(clock); } - defineProperties(CircleEmitter.prototype, { + defineProperties(TimeDynamicImagery.prototype, { /** - * The radius of the circle in meters. - * @memberof CircleEmitter.prototype - * @type {Number} - * @default 1.0 + * Gets or sets a clock that is used to get keep the time used for time dynamic parameters. + * @memberof TimeDynamicImagery.prototype + * @type {Clock} */ - radius : { + clock : { get : function() { - return this._radius; + return this._clock; }, set : function(value) { - Check.typeOf.number.greaterThan('value', value, 0.0); - this._radius = value; + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._clock !== value) { + this._clock = value; + this._clockOnTick(value); + this._reloadFunction(); + } + } + }, + /** + * Gets or sets a time interval collection. + * @memberof TimeDynamicImagery.prototype + * @type {TimeIntervalCollection} + */ + times : { + get : function() { + return this._times; + }, + set : function(value) { + if (!defined(value)) { + throw new DeveloperError('value is required.'); + } + + if (this._times !== value) { + this._times = value; + this._clockOnTick(this._clock); + this._reloadFunction(); + } + } + }, + /** + * Gets the current interval. + * @memberof TimeDynamicImagery.prototype + * @type {TimeInterval} + */ + currentInterval : { + get : function() { + return this._times.get(this._currentIntervalIndex); } } }); /** - * Initializes the given {@link Particle} by setting it's position and velocity. + * Gets the tile from the cache if its available. * - * @private - * @param {Particle} particle The particle to initialize. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * + * @returns {Promise.<Image>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if the tile is not in the cache. */ - CircleEmitter.prototype.emit = function(particle) { - var theta = CesiumMath.randomBetween(0.0, CesiumMath.TWO_PI); - var rad = CesiumMath.randomBetween(0.0, this._radius); + TimeDynamicImagery.prototype.getFromCache = function(x, y, level, request) { + var key = getKey(x, y, level); + var result; + var cache = this._tileCache[this._currentIntervalIndex]; + if (defined(cache) && defined(cache[key])) { + var item = cache[key]; + result = item.promise + .otherwise(function(e) { + // Set the correct state in case it was cancelled + request.state = item.request.state; + throw e; + }); + delete cache[key]; + } - var x = rad * Math.cos(theta); - var y = rad * Math.sin(theta); - var z = 0.0; + return result; + }; - particle.position = Cartesian3.fromElements(x, y, z, particle.position); - particle.velocity = Cartesian3.clone(Cartesian3.UNIT_Z, particle.velocity); + /** + * Checks if the next interval is approaching and will start preload the tile if necessary. Otherwise it will + * just add the tile to a list to preload when we approach the next interval. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + */ + TimeDynamicImagery.prototype.checkApproachingInterval = function(x, y, level, request) { + var key = getKey(x, y, level); + var tilesRequestedForInterval = this._tilesRequestedForInterval; + + // If we are approaching an interval, preload this tile in the next interval + var approachingInterval = getApproachingInterval(this); + var tile = { + key : key, + // Determines priority based on camera distance to the tile. + // Since the imagery regardless of time will be attached to the same tile we can just steal it. + priorityFunction : request.priorityFunction + }; + if (!defined(approachingInterval) || !addToCache(this, tile, approachingInterval)) { + // Add to recent request list if we aren't approaching and interval or the request was throttled + tilesRequestedForInterval.push(tile); + } + + // Don't let the tile list get out of hand + if (tilesRequestedForInterval.length >= 512) { + tilesRequestedForInterval.splice(0, 256); + } }; - return CircleEmitter; -}); + TimeDynamicImagery.prototype._clockOnTick = function(clock) { + var time = clock.currentTime; + var times = this._times; + var index = times.indexOf(time); + var currentIntervalIndex = this._currentIntervalIndex; -define('Scene/ConeEmitter',[ - '../Core/Cartesian3', - '../Core/Check', - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/Math' - ], function( - Cartesian3, - Check, - defaultValue, - defineProperties, - CesiumMath) { - 'use strict'; + if (index !== currentIntervalIndex) { + // Cancel all outstanding requests and clear out caches not from current time interval + var currentCache = this._tileCache[currentIntervalIndex]; + for (var t in currentCache) { + if (currentCache.hasOwnProperty(t)) { + currentCache[t].request.cancel(); + } + } + delete this._tileCache[currentIntervalIndex]; + this._tilesRequestedForInterval = []; - var defaultAngle = CesiumMath.toRadians(30.0); + this._currentIntervalIndex = index; + this._reloadFunction(); - /** - * A ParticleEmitter that emits particles within a cone. - * Particles will be positioned at the tip of the cone and have initial velocities going towards the base. - * - * @alias ConeEmitter - * @constructor - * - * @param {Number} [angle=Cesium.Math.toRadians(30.0)] The angle of the cone in radians. - */ - function ConeEmitter(angle) { - this._angle = defaultValue(angle, defaultAngle); - } + return; + } - defineProperties(ConeEmitter.prototype, { - /** - * The angle of the cone in radians. - * @memberof CircleEmitter.prototype - * @type {Number} - * @default Cesium.Math.toRadians(30.0) - */ - angle : { - get : function() { - return this._angle; - }, - set : function(value) { - Check.typeOf.number('value', value); - this._angle = value; + var approachingInterval = getApproachingInterval(this); + if (defined(approachingInterval)) { + // Start loading recent tiles from end of this._tilesRequestedForInterval + // We keep preloading until we hit a throttling limit. + var tilesRequested = this._tilesRequestedForInterval; + var success = true; + while (success) { + if (tilesRequested.length === 0) { + break; + } + + var tile = tilesRequested.pop(); + success = addToCache(this, tile, approachingInterval); + if (!success) { + tilesRequested.push(tile); + } } } - }); + }; - /** - * Initializes the given {Particle} by setting it's position and velocity. - * - * @private - * @param {Particle} particle The particle to initialize - */ - ConeEmitter.prototype.emit = function(particle) { - var radius = Math.tan(this._angle); + function getKey(x, y, level) { + return x + '-' + y + '-' + level; + } - // Compute a random point on the cone's base - var theta = CesiumMath.randomBetween(0.0, CesiumMath.TWO_PI); - var rad = CesiumMath.randomBetween(0.0, radius); + function getKeyElements(key) { + var s = key.split('-'); + if (s.length !== 3) { + return undefined; + } - var x = rad * Math.cos(theta); - var y = rad * Math.sin(theta); - var z = 1.0; + return { + x : Number(s[0]), + y : Number(s[1]), + level : Number(s[2]) + }; + } - particle.velocity = Cartesian3.fromElements(x, y, z, particle.velocity); - Cartesian3.normalize(particle.velocity, particle.velocity); - particle.position = Cartesian3.clone(Cartesian3.ZERO, particle.position); - }; + function getApproachingInterval(that) { + var times = that._times; + if (!defined(times)) { + return undefined; + } + var clock = that._clock; + var time = clock.currentTime; + var isAnimating = clock.canAnimate && clock.shouldAnimate; + var multiplier = clock.multiplier; - return ConeEmitter; + if (!isAnimating && multiplier !== 0) { + return undefined; + } + + var seconds; + var index = times.indexOf(time); + if (index === -1) { + return undefined; + } + + var interval = times.get(index); + if (multiplier > 0) { // animating forward + seconds = JulianDate.secondsDifference(interval.stop, time); + ++index; + } else { //backwards + seconds = JulianDate.secondsDifference(interval.start, time); // Will be negative + --index; + } + seconds /= multiplier; // Will always be positive + + // Less than 5 wall time seconds + return (index >= 0 && seconds <= 5.0) ? times.get(index) : undefined; + } + + function addToCache(that, tile, interval) { + var index = that._times.indexOf(interval.start); + var tileCache = that._tileCache; + var intervalTileCache = tileCache[index]; + if (!defined(intervalTileCache)) { + intervalTileCache = tileCache[index] = {}; + } + + var key = tile.key; + if (defined(intervalTileCache[key])) { + return true; // Already in the cache + } + + var keyElements = getKeyElements(key); + var request = new Request({ + throttle : true, + throttleByServer : true, + type : RequestType.IMAGERY, + priorityFunction : tile.priorityFunction + }); + var promise = that._requestImageFunction(keyElements.x, keyElements.y, keyElements.level, request, interval); + if (!defined(promise)) { + return false; + } + + intervalTileCache[key] = { + promise : promise, + request : request + }; + + return true; + } + + return TimeDynamicImagery; }); -define('Scene/UrlTemplateImageryProvider',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartographic', +define('Scene/WebMapTileServiceImageryProvider',[ '../Core/combine', '../Core/Credit', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/DeveloperError', '../Core/Event', - '../Core/GeographicTilingScheme', + '../Core/freezeObject', '../Core/isArray', - '../Core/loadJson', - '../Core/loadText', - '../Core/loadWithXhr', - '../Core/loadXML', - '../Core/Math', + '../Core/objectToQuery', + '../Core/queryToObject', '../Core/Rectangle', + '../Core/Resource', '../Core/WebMercatorTilingScheme', + '../ThirdParty/Uri', '../ThirdParty/when', - './ImageryProvider' + './ImageryProvider', + './TimeDynamicImagery' ], function( - Cartesian2, - Cartesian3, - Cartographic, combine, Credit, defaultValue, defined, defineProperties, + deprecationWarning, DeveloperError, Event, - GeographicTilingScheme, + freezeObject, isArray, - loadJson, - loadText, - loadWithXhr, - loadXML, - CesiumMath, + objectToQuery, + queryToObject, Rectangle, + Resource, WebMercatorTilingScheme, + Uri, when, - ImageryProvider) { + ImageryProvider, + TimeDynamicImagery) { 'use strict'; - var tags = { - '{x}': xTag, - '{y}': yTag, - '{z}': zTag, - '{s}': sTag, - '{reverseX}': reverseXTag, - '{reverseY}': reverseYTag, - '{reverseZ}': reverseZTag, - '{westDegrees}': westDegreesTag, - '{southDegrees}': southDegreesTag, - '{eastDegrees}': eastDegreesTag, - '{northDegrees}': northDegreesTag, - '{westProjected}': westProjectedTag, - '{southProjected}': southProjectedTag, - '{eastProjected}': eastProjectedTag, - '{northProjected}': northProjectedTag, - '{width}': widthTag, - '{height}': heightTag - }; - - var pickFeaturesTags = combine(tags, { - '{i}' : iTag, - '{j}' : jTag, - '{reverseI}' : reverseITag, - '{reverseJ}' : reverseJTag, - '{longitudeDegrees}' : longitudeDegreesTag, - '{latitudeDegrees}' : latitudeDegreesTag, - '{longitudeProjected}' : longitudeProjectedTag, - '{latitudeProjected}' : latitudeProjectedTag, - '{format}' : formatTag + var defaultParameters = freezeObject({ + service : 'WMTS', + version : '1.0.0', + request : 'GetTile' }); /** - * Provides imagery by requesting tiles using a specified URL template. + * Provides tiled imagery served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers. + * This provider supports HTTP KVP-encoded and RESTful GetTile requests, but does not yet support the SOAP encoding. * - * @alias UrlTemplateImageryProvider + * @alias WebMapTileServiceImageryProvider * @constructor * - * @param {Promise.<Object>|Object} [options] Object with the following properties: - * @param {String} options.url The URL template to use to request tiles. It has the following keywords: - * <ul> - * <li><code>{z}</code>: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.</li> - * <li><code>{x}</code>: The tile X coordinate in the tiling scheme, where 0 is the Westernmost tile.</li> - * <li><code>{y}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Northernmost tile.</li> - * <li><code>{s}</code>: One of the available subdomains, used to overcome browser limits on the number of simultaneous requests per host.</li> - * <li><code>{reverseX}</code>: The tile X coordinate in the tiling scheme, where 0 is the Easternmost tile.</li> - * <li><code>{reverseY}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Southernmost tile.</li> - * <li><code>{reverseZ}</code>: The level of the tile in the tiling scheme, where level zero is the maximum level of the quadtree pyramid. In order to use reverseZ, maximumLevel must be defined.</li> - * <li><code>{westDegrees}</code>: The Western edge of the tile in geodetic degrees.</li> - * <li><code>{southDegrees}</code>: The Southern edge of the tile in geodetic degrees.</li> - * <li><code>{eastDegrees}</code>: The Eastern edge of the tile in geodetic degrees.</li> - * <li><code>{northDegrees}</code>: The Northern edge of the tile in geodetic degrees.</li> - * <li><code>{westProjected}</code>: The Western edge of the tile in projected coordinates of the tiling scheme.</li> - * <li><code>{southProjected}</code>: The Southern edge of the tile in projected coordinates of the tiling scheme.</li> - * <li><code>{eastProjected}</code>: The Eastern edge of the tile in projected coordinates of the tiling scheme.</li> - * <li><code>{northProjected}</code>: The Northern edge of the tile in projected coordinates of the tiling scheme.</li> - * <li><code>{width}</code>: The width of each tile in pixels.</li> - * <li><code>{height}</code>: The height of each tile in pixels.</li> - * </ul> - * @param {String} [options.pickFeaturesUrl] The URL template to use to pick features. If this property is not specified, - * {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no - * features picked. The URL template supports all of the keywords supported by the <code>url</code> - * parameter, plus the following: - * <ul> - * <li><code>{i}</code>: The pixel column (horizontal coordinate) of the picked position, where the Westernmost pixel is 0.</li> - * <li><code>{j}</code>: The pixel row (vertical coordinate) of the picked position, where the Northernmost pixel is 0.</li> - * <li><code>{reverseI}</code>: The pixel column (horizontal coordinate) of the picked position, where the Easternmost pixel is 0.</li> - * <li><code>{reverseJ}</code>: The pixel row (vertical coordinate) of the picked position, where the Southernmost pixel is 0.</li> - * <li><code>{longitudeDegrees}</code>: The longitude of the picked position in degrees.</li> - * <li><code>{latitudeDegrees}</code>: The latitude of the picked position in degrees.</li> - * <li><code>{longitudeProjected}</code>: The longitude of the picked position in the projected coordinates of the tiling scheme.</li> - * <li><code>{latitudeProjected}</code>: The latitude of the picked position in the projected coordinates of the tiling scheme.</li> - * <li><code>{format}</code>: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.</li> - * </ul> - * @param {Object} [options.urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where - * each coordinate will be padded on the left with zeros to match the width of the passed string of zeros. e.g. Setting: - * urlSchemeZeroPadding : { '{x}' : '0000'} - * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL. - * It the passed object has the following keywords: - * <ul> - * <li> <code>{z}</code>: The zero padding for the level of the tile in the tiling scheme.</li> - * <li> <code>{x}</code>: The zero padding for the tile X coordinate in the tiling scheme.</li> - * <li> <code>{y}</code>: The zero padding for the the tile Y coordinate in the tiling scheme.</li> - * <li> <code>{reverseX}</code>: The zero padding for the tile reverseX coordinate in the tiling scheme.</li> - * <li> <code>{reverseY}</code>: The zero padding for the tile reverseY coordinate in the tiling scheme.</li> - * <li> <code>{reverseZ}</code>: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.</li> - * </ul> - * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. - * If this parameter is a single string, each character in the string is a subdomain. If it is - * an array, each element in the array is a subdomain. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL. - * @param {Credit|String} [options.credit=''] A credit for the data source, which is displayed on the canvas. - * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying - * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely - * to result in rendering problems. - * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. - * @param {TilingScheme} [options.tilingScheme=WebMercatorTilingScheme] The tiling scheme specifying how the ellipsoidal - * surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme} - * is used. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. - * @param {Number} [options.tileWidth=256] Pixel width of image tiles. - * @param {Number} [options.tileHeight=256] Pixel height of image tiles. - * @param {Boolean} [options.hasAlphaChannel=true] true if the images provided by this imagery provider - * include an alpha channel; otherwise, false. If this property is false, an alpha channel, if - * present, will be ignored. If this property is true, any images without an alpha channel will - * be treated as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are potentially reduced. - * @param {GetFeatureInfoFormat[]} [options.getFeatureInfoFormats] The formats in which to get feature information at a - * specific location when {@link UrlTemplateImageryProvider#pickFeatures} is invoked. If this - * parameter is not specified, feature picking is disabled. - * @param {Boolean} [options.enablePickFeatures=true] If true, {@link UrlTemplateImageryProvider#pickFeatures} will - * request the <code>options.pickFeaturesUrl</code> and attempt to interpret the features included in the response. If false, - * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable - * features) without communicating with the server. Set this property to false if you know your data - * source does not support picking features or if you don't want this provider's features to be pickable. Note - * that this can be dynamically overridden by modifying the {@link UriTemplateImageryProvider#enablePickFeatures} - * property. - * @param {Object} [options.customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values. + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains. + * @param {String} [options.format='image/jpeg'] The MIME type for images to retrieve from the server. + * @param {String} options.layer The layer name for WMTS requests. + * @param {String} options.style The style name for WMTS requests. + * @param {String} options.tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests. + * @param {Array} [options.tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level. + * @param {Clock} [options.clock] A Clock instance that is used when determining the value for the time dimension. Required when options.times is specified. + * @param {TimeIntervalCollection} [options.times] TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values. + * @param {Object} [options.dimensions] A object containing static dimensions and their values. + * @param {Number} [options.tileWidth=256] The tile width in pixels. + * @param {Number} [options.tileHeight=256] The tile height in pixels. + * @param {TilingScheme} [options.tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet. + * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer. + * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. + * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. + * If this parameter is a single string, each character in the string is a subdomain. If it is + * an array, each element in the array is a subdomain. * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Web%20Map%20Tile%20Service%20with%20Time.html|Cesium Sandcastle Web Map Tile Service with Time Demo} * * @example - * // Access Natural Earth II imagery, which uses a TMS tiling scheme and Geographic (EPSG:4326) project - * var tms = new Cesium.UrlTemplateImageryProvider({ - * url : 'https://cesiumjs.org/tilesets/imagery/naturalearthii/{z}/{x}/{reverseY}.jpg', - * credit : '© Analytical Graphics, Inc.', - * tilingScheme : new Cesium.GeographicTilingScheme(), - * maximumLevel : 5 + * // Example 1. USGS shaded relief tiles (KVP) + * var shadedRelief1 = new Cesium.WebMapTileServiceImageryProvider({ + * url : 'http://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS', + * layer : 'USGSShadedReliefOnly', + * style : 'default', + * format : 'image/jpeg', + * tileMatrixSetID : 'default028mm', + * // tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...], + * maximumLevel: 19, + * credit : new Cesium.Credit({ text : 'U. S. Geological Survey' }) * }); - * // Access the CartoDB Positron basemap, which uses an OpenStreetMap-like tiling scheme. - * var positron = new Cesium.UrlTemplateImageryProvider({ - * url : 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', - * credit : 'Map tiles by CartoDB, under CC BY 3.0. Data by OpenStreetMap, under ODbL.' + * viewer.imageryLayers.addImageryProvider(shadedRelief1); + * + * @example + * // Example 2. USGS shaded relief tiles (RESTful) + * var shadedRelief2 = new Cesium.WebMapTileServiceImageryProvider({ + * url : 'http://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS/tile/1.0.0/USGSShadedReliefOnly/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg', + * layer : 'USGSShadedReliefOnly', + * style : 'default', + * format : 'image/jpeg', + * tileMatrixSetID : 'default028mm', + * maximumLevel: 19, + * credit : new Cesium.Credit({ text : 'U. S. Geological Survey' }) * }); - * // Access a Web Map Service (WMS) server. - * var wms = new Cesium.UrlTemplateImageryProvider({ - * url : 'https://programs.communications.gov.au/geoserver/ows?tiled=true&' + - * 'transparent=true&format=image%2Fpng&exceptions=application%2Fvnd.ogc.se_xml&' + - * 'styles=&service=WMS&version=1.1.1&request=GetMap&' + - * 'layers=public%3AMyBroadband_Availability&srs=EPSG%3A3857&' + - * 'bbox={westProjected}%2C{southProjected}%2C{eastProjected}%2C{northProjected}&' + - * 'width=256&height=256', - * rectangle : Cesium.Rectangle.fromDegrees(96.799393, -43.598214999057824, 153.63925700000001, -9.2159219997013) + * viewer.imageryLayers.addImageryProvider(shadedRelief2); + * + * @example + * // Example 3. NASA time dynamic weather data (RESTful) + * var times = Cesium.TimeIntervalCollection.fromIso8601({ + * iso8601: '2015-07-30/2017-06-16/P1D', + * dataCallback: function dataCallback(interval, index) { + * return { + * Time: Cesium.JulianDate.toIso8601(interval.start) + * }; + * } * }); - * // Using custom tags in your template url. - * var custom = new Cesium.UrlTemplateImageryProvider({ - * url : 'https://yoururl/{Time}/{z}/{y}/{x}.png', - * customTags : { - * Time: function(imageryProvider, x, y , level) { - * return '20171231' - * } - * } + * var weather = new Cesium.WebMapTileServiceImageryProvider({ + * url : 'https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/AMSR2_Snow_Water_Equivalent/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png', + * layer : 'AMSR2_Snow_Water_Equivalent', + * style : 'default', + * tileMatrixSetID : '2km', + * maximumLevel : 5, + * format : 'image/png', + * clock: clock, + * times: times, + * credit : new Cesium.Credit({ text : 'NASA Global Imagery Browse Services for EOSDIS' }) * }); + * viewer.imageryLayers.addImageryProvider(weather); * * @see ArcGisMapServerImageryProvider * @see BingMapsImageryProvider @@ -184883,241 +198656,269 @@ define('Scene/UrlTemplateImageryProvider',[ * @see SingleTileImageryProvider * @see createTileMapServiceImageryProvider * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider */ - function UrlTemplateImageryProvider(options) { - if (!defined(options)) { - throw new DeveloperError('options is required.'); + function WebMapTileServiceImageryProvider(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + if (!defined(options.url)) { + throw new DeveloperError('options.url is required.'); } - if (!when.isPromise(options) && !defined(options.url)) { - throw new DeveloperError('options is required.'); + if (!defined(options.layer)) { + throw new DeveloperError('options.layer is required.'); + } + if (!defined(options.style)) { + throw new DeveloperError('options.style is required.'); + } + if (!defined(options.tileMatrixSetID)) { + throw new DeveloperError('options.tileMatrixSetID is required.'); + } + if (defined(options.times) && !defined(options.clock)) { + throw new DeveloperError('options.times was specified, so options.clock is required.'); } - this._errorEvent = new Event(); + if (defined(options.proxy)) { + deprecationWarning('WebMapTileServiceImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); + } - this._url = undefined; - this._urlSchemeZeroPadding = undefined; - this._pickFeaturesUrl = undefined; - this._proxy = undefined; - this._tileWidth = undefined; - this._tileHeight = undefined; - this._maximumLevel = undefined; - this._minimumLevel = undefined; - this._tilingScheme = undefined; - this._rectangle = undefined; - this._tileDiscardPolicy = undefined; - this._credit = undefined; - this._hasAlphaChannel = undefined; - this._readyPromise = undefined; + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); - /** - * Gets or sets a value indicating whether feature picking is enabled. If true, {@link UrlTemplateImageryProvider#pickFeatures} will - * request the <code>options.pickFeaturesUrl</code> and attempt to interpret the features included in the response. If false, - * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable - * features) without communicating with the server. Set this property to false if you know your data - * source does not support picking features or if you don't want this provider's features to be pickable. - * @type {Boolean} - * @default true - */ - this.enablePickFeatures = true; + var style = options.style; + var tileMatrixSetID = options.tileMatrixSetID; + var url = resource.url; + if (url.indexOf('{') >= 0) { + var templateValues = { + style : style, + Style : style, + TileMatrixSet : tileMatrixSetID + }; - this.reinitialize(options); + resource.addTemplateValues(templateValues); + this._useKvp = false; + } else { + resource.addQueryParameters(defaultParameters); + this._useKvp = true; + } + + this._resource = resource; + this._layer = options.layer; + this._style = style; + this._tileMatrixSetID = tileMatrixSetID; + this._tileMatrixLabels = options.tileMatrixLabels; + this._format = defaultValue(options.format, 'image/jpeg'); + this._tileDiscardPolicy = options.tileDiscardPolicy; + + this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme({ellipsoid : options.ellipsoid}); + this._tileWidth = defaultValue(options.tileWidth, 256); + this._tileHeight = defaultValue(options.tileHeight, 256); + + this._minimumLevel = defaultValue(options.minimumLevel, 0); + this._maximumLevel = options.maximumLevel; + + this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle); + this._dimensions = options.dimensions; + + var that = this; + this._reload = undefined; + if (defined(options.times)) { + this._timeDynamicImagery = new TimeDynamicImagery({ + clock : options.clock, + times : options.times, + requestImageFunction : function(x, y, level, request, interval) { + return requestImage(that, x, y, level, request, interval); + }, + reloadFunction : function() { + if (defined(that._reload)) { + that._reload(); + } + } + }); + } + + this._readyPromise = when.resolve(true); + + // Check the number of tiles at the minimum level. If it's more than four, + // throw an exception, because starting at the higher minimum + // level will cause too many tiles to be downloaded and rendered. + var swTile = this._tilingScheme.positionToTileXY(Rectangle.southwest(this._rectangle), this._minimumLevel); + var neTile = this._tilingScheme.positionToTileXY(Rectangle.northeast(this._rectangle), this._minimumLevel); + var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1); + if (tileCount > 4) { + throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.'); + } + + this._errorEvent = new Event(); + + var credit = options.credit; + this._credit = typeof credit === 'string' ? new Credit({text: credit}) : credit; + + this._subdomains = options.subdomains; + if (isArray(this._subdomains)) { + this._subdomains = this._subdomains.slice(); + } else if (defined(this._subdomains) && this._subdomains.length > 0) { + this._subdomains = this._subdomains.split(''); + } else { + this._subdomains = ['a', 'b', 'c']; + } } - defineProperties(UrlTemplateImageryProvider.prototype, { - /** - * Gets the URL template to use to request tiles. It has the following keywords: - * <ul> - * <li> <code>{z}</code>: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.</li> - * <li> <code>{x}</code>: The tile X coordinate in the tiling scheme, where 0 is the Westernmost tile.</li> - * <li> <code>{y}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Northernmost tile.</li> - * <li> <code>{s}</code>: One of the available subdomains, used to overcome browser limits on the number of simultaneous requests per host.</li> - * <li> <code>{reverseX}</code>: The tile X coordinate in the tiling scheme, where 0 is the Easternmost tile.</li> - * <li> <code>{reverseY}</code>: The tile Y coordinate in the tiling scheme, where 0 is the Southernmost tile.</li> - * <li> <code>{reverseZ}</code>: The level of the tile in the tiling scheme, where level zero is the maximum level of the quadtree pyramid. In order to use reverseZ, maximumLevel must be defined.</li> - * <li> <code>{westDegrees}</code>: The Western edge of the tile in geodetic degrees.</li> - * <li> <code>{southDegrees}</code>: The Southern edge of the tile in geodetic degrees.</li> - * <li> <code>{eastDegrees}</code>: The Eastern edge of the tile in geodetic degrees.</li> - * <li> <code>{northDegrees}</code>: The Northern edge of the tile in geodetic degrees.</li> - * <li> <code>{westProjected}</code>: The Western edge of the tile in projected coordinates of the tiling scheme.</li> - * <li> <code>{southProjected}</code>: The Southern edge of the tile in projected coordinates of the tiling scheme.</li> - * <li> <code>{eastProjected}</code>: The Eastern edge of the tile in projected coordinates of the tiling scheme.</li> - * <li> <code>{northProjected}</code>: The Northern edge of the tile in projected coordinates of the tiling scheme.</li> - * <li> <code>{width}</code>: The width of each tile in pixels.</li> - * <li> <code>{height}</code>: The height of each tile in pixels.</li> - * </ul> - * @memberof UrlTemplateImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; + function requestImage(imageryProvider, col, row, level, request, interval) { + var labels = imageryProvider._tileMatrixLabels; + var tileMatrix = defined(labels) ? labels[level] : level.toString(); + var subdomains = imageryProvider._subdomains; + var staticDimensions = imageryProvider._dimensions; + var dynamicIntervalData = defined(interval) ? interval.data : undefined; + + var resource; + if (!imageryProvider._useKvp) { + var templateValues = { + TileMatrix: tileMatrix, + TileRow: row.toString(), + TileCol: col.toString(), + s: subdomains[(col + row + level) % subdomains.length] + }; + + resource = imageryProvider._resource.getDerivedResource({ + request: request + }); + resource.addTemplateValues(templateValues); + + if (defined(staticDimensions)) { + resource.addTemplateValues(staticDimensions); } - }, - /** - * Gets the URL scheme zero padding for each tile coordinate. The format is '000' where each coordinate will be padded on - * the left with zeros to match the width of the passed string of zeros. e.g. Setting: - * urlSchemeZeroPadding : { '{x}' : '0000'} - * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL. - * It has the following keywords: - * <ul> - * <li> <code>{z}</code>: The zero padding for the level of the tile in the tiling scheme.</li> - * <li> <code>{x}</code>: The zero padding for the tile X coordinate in the tiling scheme.</li> - * <li> <code>{y}</code>: The zero padding for the the tile Y coordinate in the tiling scheme.</li> - * <li> <code>{reverseX}</code>: The zero padding for the tile reverseX coordinate in the tiling scheme.</li> - * <li> <code>{reverseY}</code>: The zero padding for the tile reverseY coordinate in the tiling scheme.</li> - * <li> <code>{reverseZ}</code>: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.</li> - * </ul> - * @memberof UrlTemplateImageryProvider.prototype - * @type {Object} - * @readonly - */ - urlSchemeZeroPadding : { - get : function() { - return this._urlSchemeZeroPadding; + if (defined(dynamicIntervalData)) { + resource.addTemplateValues(dynamicIntervalData); } - }, + } else { + // build KVP request + var query = {}; + query.tilematrix = tileMatrix; + query.layer = imageryProvider._layer; + query.style = imageryProvider._style; + query.tilerow = row; + query.tilecol = col; + query.tilematrixset = imageryProvider._tileMatrixSetID; + query.format = imageryProvider._format; + + if (defined(staticDimensions)) { + query = combine(query, staticDimensions); + } + + if (defined(dynamicIntervalData)) { + query = combine(query, dynamicIntervalData); + } + resource = imageryProvider._resource.getDerivedResource({ + queryParameters: query, + request: request + }); + } + + return ImageryProvider.loadImage(imageryProvider, resource); + } + defineProperties(WebMapTileServiceImageryProvider.prototype, { /** - * Gets the URL template to use to use to pick features. If this property is not specified, - * {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no - * features picked. The URL template supports all of the keywords supported by the - * {@link UrlTemplateImageryProvider#url} property, plus the following: - * <ul> - * <li><code>{i}</code>: The pixel column (horizontal coordinate) of the picked position, where the Westernmost pixel is 0.</li> - * <li><code>{j}</code>: The pixel row (vertical coordinate) of the picked position, where the Northernmost pixel is 0.</li> - * <li><code>{reverseI}</code>: The pixel column (horizontal coordinate) of the picked position, where the Easternmost pixel is 0.</li> - * <li><code>{reverseJ}</code>: The pixel row (vertical coordinate) of the picked position, where the Southernmost pixel is 0.</li> - * <li><code>{longitudeDegrees}</code>: The longitude of the picked position in degrees.</li> - * <li><code>{latitudeDegrees}</code>: The latitude of the picked position in degrees.</li> - * <li><code>{longitudeProjected}</code>: The longitude of the picked position in the projected coordinates of the tiling scheme.</li> - * <li><code>{latitudeProjected}</code>: The latitude of the picked position in the projected coordinates of the tiling scheme.</li> - * <li><code>{format}</code>: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.</li> - * </ul> - * @memberof UrlTemplateImageryProvider.prototype + * Gets the URL of the service hosting the imagery. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {String} * @readonly */ - pickFeaturesUrl : { + url : { get : function() { - return this._pickFeaturesUrl; + return this._resource.url; } }, /** * Gets the proxy used by this provider. - * @memberof UrlTemplateImageryProvider.prototype + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Proxy} * @readonly - * @default undefined */ proxy : { get : function() { - return this._proxy; + return this._resource.proxy; } }, /** * Gets the width of each tile, in pixels. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly - * @default 256 */ tileWidth : { get : function() { - if (!this.ready) { - throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); - } - return this._tileWidth; + return this._tileWidth; } }, /** * Gets the height of each tile, in pixels. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly - * @default 256 */ - tileHeight: { + tileHeight : { get : function() { - if (!this.ready) { - throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); - } - return this._tileHeight; + return this._tileHeight; } }, /** - * Gets the maximum level-of-detail that can be requested, or undefined if there is no limit. - * This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly - * @default undefined */ maximumLevel : { get : function() { - if (!this.ready) { - throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); - } - return this._maximumLevel; + return this._maximumLevel; } }, /** * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly - * @default 0 */ minimumLevel : { get : function() { - if (!this.ready) { - throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); - } - return this._minimumLevel; + return this._minimumLevel; } }, /** * Gets the tiling scheme used by this provider. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {TilingScheme} * @readonly - * @default new WebMercatorTilingScheme() */ tilingScheme : { get : function() { - if (!this.ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); - } - return this._tilingScheme; + return this._tilingScheme; } }, /** * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Rectangle} * @readonly - * @default tilingScheme.rectangle */ rectangle : { get : function() { - if (!this.ready) { - throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); - } - return this._rectangle; + return this._rectangle; } }, @@ -185125,18 +198926,14 @@ define('Scene/UrlTemplateImageryProvider',[ * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function * returns undefined, no tiles are filtered. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly - * @default undefined */ tileDiscardPolicy : { get : function() { - if (!this.ready) { - throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); - } - return this._tileDiscardPolicy; + return this._tileDiscardPolicy; } }, @@ -185144,7 +198941,7 @@ define('Scene/UrlTemplateImageryProvider',[ * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners * are passed an instance of {@link TileProviderError}. - * @memberof UrlTemplateImageryProvider.prototype + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Event} * @readonly */ @@ -185154,21 +198951,31 @@ define('Scene/UrlTemplateImageryProvider',[ } }, + /** + * Gets the mime type of images returned by this imagery provider. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {String} + * @readonly + */ + format : { + get : function() { + return this._format; + } + }, + /** * Gets a value indicating whether or not the provider is ready for use. - * @memberof UrlTemplateImageryProvider.prototype + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Boolean} * @readonly */ ready : { - get : function() { - return defined(this._urlParts); - } + value : true }, /** * Gets a promise that resolves to true when the provider is ready for use. - * @memberof UrlTemplateImageryProvider.prototype + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Promise.<Boolean>} * @readonly */ @@ -185180,18 +198987,14 @@ define('Scene/UrlTemplateImageryProvider',[ /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * the source of the imagery. This function should not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Credit} * @readonly - * @default undefined */ credit : { get : function() { - if (!this.ready) { - throw new DeveloperError('credit must not be called before the imagery provider is ready.'); - } - return this._credit; + return this._credit; } }, @@ -185200,100 +199003,63 @@ define('Scene/UrlTemplateImageryProvider',[ * include an alpha channel. If this property is false, an alpha channel, if present, will * be ignored. If this property is true, any images without an alpha channel will be treated * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. This function should - * not be called before {@link ImageryProvider#ready} returns true. - * @memberof UrlTemplateImageryProvider.prototype + * and texture upload time are reduced. + * @memberof WebMapTileServiceImageryProvider.prototype * @type {Boolean} * @readonly - * @default true */ hasAlphaChannel : { get : function() { - if (!this.ready) { - throw new DeveloperError('hasAlphaChannel must not be called before the imagery provider is ready.'); - } - return this._hasAlphaChannel; - } - } - }); - - /** - * Reinitializes this instance. Reinitializing an instance already in use is supported, but it is not - * recommended because existing tiles provided by the imagery provider will not be updated. - * - * @param {Promise.<Object>|Object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. - */ - UrlTemplateImageryProvider.prototype.reinitialize = function(options) { - var that = this; - that._readyPromise = when(options).then(function(properties) { - if (!defined(properties)) { - throw new DeveloperError('options is required.'); - } - if (!defined(properties.url)) { - throw new DeveloperError('options.url is required.'); - } - that.enablePickFeatures = defaultValue(properties.enablePickFeatures, that.enablePickFeatures); - that._url = properties.url; - that._urlSchemeZeroPadding = defaultValue(properties.urlSchemeZeroPadding, that.urlSchemeZeroPadding); - that._pickFeaturesUrl = properties.pickFeaturesUrl; - that._proxy = properties.proxy; - that._tileDiscardPolicy = properties.tileDiscardPolicy; - that._getFeatureInfoFormats = properties.getFeatureInfoFormats; - - that._subdomains = properties.subdomains; - if (isArray(that._subdomains)) { - that._subdomains = that._subdomains.slice(); - } else if (defined(that._subdomains) && that._subdomains.length > 0) { - that._subdomains = that._subdomains.split(''); - } else { - that._subdomains = ['a', 'b', 'c']; - } - - that._tileWidth = defaultValue(properties.tileWidth, 256); - that._tileHeight = defaultValue(properties.tileHeight, 256); - that._minimumLevel = defaultValue(properties.minimumLevel, 0); - that._maximumLevel = properties.maximumLevel; - that._tilingScheme = defaultValue(properties.tilingScheme, new WebMercatorTilingScheme({ ellipsoid : properties.ellipsoid })); - that._rectangle = defaultValue(properties.rectangle, that._tilingScheme.rectangle); - that._rectangle = Rectangle.intersection(that._rectangle, that._tilingScheme.rectangle); - that._hasAlphaChannel = defaultValue(properties.hasAlphaChannel, true); - - var credit = properties.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); + return true; } - that._credit = credit; - - var tag; - var allTags = {}; - var allPickFeaturesTags = {}; - for (tag in tags) { - if (tags.hasOwnProperty(tag)) { - allTags[tag] = tags[tag]; - } + }, + /** + * Gets or sets a clock that is used to get keep the time used for time dynamic parameters. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Clock} + */ + clock : { + get : function() { + return this._timeDynamicImagery.clock; + }, + set : function(value) { + this._timeDynamicImagery.clock = value; } - for (tag in pickFeaturesTags) { - if (pickFeaturesTags.hasOwnProperty(tag)) { - allPickFeaturesTags[tag] = pickFeaturesTags[tag]; - } + }, + /** + * Gets or sets a time interval collection that is used to get time dynamic parameters. The data of each + * TimeInterval is an object containing the keys and values of the properties that are used during + * tile requests. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {TimeIntervalCollection} + */ + times : { + get : function() { + return this._timeDynamicImagery.times; + }, + set : function(value) { + this._timeDynamicImagery.times = value; } - - var customTags = properties.customTags; - if (defined(customTags)) { - for (tag in customTags) { - if (customTags.hasOwnProperty(tag)) { - var targetTag = '{' + tag + '}'; - allTags[targetTag] = customTags[tag]; - allPickFeaturesTags[targetTag] = customTags[tag]; + }, + /** + * Gets or sets an object that contains static dimensions and their values. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Object} + */ + dimensions : { + get : function() { + return this._dimensions; + }, + set : function(value) { + if (this._dimensions !== value) { + this._dimensions = value; + if (defined(this._reload)) { + this._reload(); } } } - - that._urlParts = urlTemplateToParts(that._url, allTags); - that._pickFeaturesUrlParts = urlTemplateToParts(that._pickFeaturesUrl, allPickFeaturesTags); - return true; - }); - }; + } + }); /** * Gets the credits to be displayed when a given tile is displayed. @@ -185305,16 +199071,13 @@ define('Scene/UrlTemplateImageryProvider',[ * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - UrlTemplateImageryProvider.prototype.getTileCredits = function(x, y, level) { - if (!this.ready) { - throw new DeveloperError('getTileCredits must not be called before the imagery provider is ready.'); - } - return undefined; + WebMapTileServiceImageryProvider.prototype.getTileCredits = function(x, y, level) { + return undefined; }; /** * Requests the image for a given tile. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -185324,18 +199087,36 @@ define('Scene/UrlTemplateImageryProvider',[ * undefined if there are too many active requests to the server, and the request * should be retried later. The resolved image may be either an * Image or a Canvas DOM object. + * + * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */ - UrlTemplateImageryProvider.prototype.requestImage = function(x, y, level, request) { - if (!this.ready) { - throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); + WebMapTileServiceImageryProvider.prototype.requestImage = function(x, y, level, request) { + var result; + var timeDynamicImagery = this._timeDynamicImagery; + var currentInterval; + + // Try and load from cache + if (defined(timeDynamicImagery)) { + currentInterval = timeDynamicImagery.currentInterval; + result = timeDynamicImagery.getFromCache(x, y, level, request); } - var url = buildImageUrl(this, x, y, level); - return ImageryProvider.loadImage(this, url, request); + + // Couldn't load from cache + if (!defined(result)) { + result = requestImage(this, x, y, level, request, currentInterval); + } + + // If we are approaching an interval, preload this tile in the next interval + if (defined(result) && defined(timeDynamicImagery)) { + timeDynamicImagery.checkApproachingInterval(x, y, level, request); + } + + return result; }; /** - * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * Picking features is not currently supported by this imagery provider, so this function simply returns + * undefined. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -185347,357 +199128,599 @@ define('Scene/UrlTemplateImageryProvider',[ * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. */ - UrlTemplateImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - if (!this.ready) { - throw new DeveloperError('pickFeatures must not be called before the imagery provider is ready.'); - } - - if (!this.enablePickFeatures || !defined(this._pickFeaturesUrl) || this._getFeatureInfoFormats.length === 0) { - return undefined; - } + WebMapTileServiceImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return undefined; + }; - var formatIndex = 0; + return WebMapTileServiceImageryProvider; +}); - var that = this; +define('Scene/CesiumIonResource',[ + '../Core/Check', + '../Core/defaultValue', + '../Core/defined', + '../Core/loadJson', + '../Core/Resource', + '../Core/RuntimeError', + '../ThirdParty/when', + './ArcGisMapServerImageryProvider', + './BingMapsImageryProvider', + './createTileMapServiceImageryProvider', + './GoogleEarthEnterpriseMapsProvider', + './MapboxImageryProvider', + './SingleTileImageryProvider', + './UrlTemplateImageryProvider', + './WebMapServiceImageryProvider', + './WebMapTileServiceImageryProvider' + ], function( + Check, + defaultValue, + defined, + loadJson, + Resource, + RuntimeError, + when, + ArcGisMapServerImageryProvider, + BingMapsImageryProvider, + createTileMapServiceImageryProvider, + GoogleEarthEnterpriseMapsProvider, + MapboxImageryProvider, + SingleTileImageryProvider, + UrlTemplateImageryProvider, + WebMapServiceImageryProvider, + WebMapTileServiceImageryProvider) { +'use strict'; - function handleResponse(format, data) { - return format.callback(data); - } + /** + * A {@link Resource} instance that encapsulates Cesium ion asset + * creation and automatic refresh token handling. This object + * should not be created directly, use CesiumIonResource.create. + * + * @private + */ + function CesiumIonResource(options, endpoint, endpointResource) { + Resource.call(this, options); - function doRequest() { - if (formatIndex >= that._getFeatureInfoFormats.length) { - // No valid formats, so no features picked. - return when([]); - } + // The asset endpoint data returned from ion. + this.ionEndpoint = endpoint; - var format = that._getFeatureInfoFormats[formatIndex]; - var url = buildPickFeaturesUrl(that, x, y, level, longitude, latitude, format.format); + // The endpoint resource to fetch when a new token is needed + this.ionEndpointResource = endpointResource; - ++formatIndex; + // The primary CesiumIonResource from which an instance is derived + this.ionRoot = undefined; + } - if (format.type === 'json') { - return loadJson(url).then(format.callback).otherwise(doRequest); - } else if (format.type === 'xml') { - return loadXML(url).then(format.callback).otherwise(doRequest); - } else if (format.type === 'text' || format.type === 'html') { - return loadText(url).then(format.callback).otherwise(doRequest); - } - return loadWithXhr({ - url : url, - responseType : format.format - }).then(handleResponse.bind(undefined, format)).otherwise(doRequest); - } + CesiumIonResource.create = function (endpoint, endpointResource) { + var options = { + url: endpoint.url, + retryAttempts: 1, + queryParameters: { access_token: endpoint.accessToken }, + retryCallback: createRetryCallback(endpoint, endpointResource) + }; - return doRequest(); + return new CesiumIonResource(options, endpoint, endpointResource); }; - var degreesScratchComputed = false; - var degreesScratch = new Rectangle(); - var projectedScratchComputed = false; - var projectedScratch = new Rectangle(); + if (defined(Object.create)) { + CesiumIonResource.prototype = Object.create(Resource.prototype); + CesiumIonResource.prototype.constructor = CesiumIonResource; + } - function buildImageUrl(imageryProvider, x, y, level) { - degreesScratchComputed = false; - projectedScratchComputed = false; + CesiumIonResource.prototype.clone = function(result) { + // We always want to use the root's information because it's the most up-to-date + var ionRoot = defaultValue(this.ionRoot, this); - return buildUrl(imageryProvider, imageryProvider._urlParts, function(partFunction) { - return partFunction(imageryProvider, x, y, level); - }); - } + if (!defined(result)) { + result = new CesiumIonResource({ url: this._url }, ionRoot.ionEndpoint, ionRoot.ionEndpointResource); + } - var ijScratchComputed = false; - var ijScratch = new Cartesian2(); - var longitudeLatitudeProjectedScratchComputed = false; + result = Resource.prototype.clone.call(this, result); + result.ionRoot = ionRoot; + result.queryParameters.access_token = ionRoot.queryParameters.access_token; + return result; + }; - function buildPickFeaturesUrl(imageryProvider, x, y, level, longitude, latitude, format) { - degreesScratchComputed = false; - projectedScratchComputed = false; - ijScratchComputed = false; - longitudeLatitudeProjectedScratchComputed = false; + function createRetryCallback(endpoint, endpointResource) { + // We use a shared pending promise for all derived assets, since they share + // a common access_token. If we're already requesting a new token for this + // asset, we wait on the same promise. + var pendingPromise; - return buildUrl(imageryProvider, imageryProvider._pickFeaturesUrlParts, function(partFunction) { - return partFunction(imageryProvider, x, y, level, longitude, latitude, format); - }); - } + var retryCallback = function(that, error) { + // We only want to retry in the case of invalid credentials (401) or image + // requests(since Image failures can not provide a status code) + if (!defined(error) || (error.statusCode !== 401 && !(error.target instanceof Image))) { + return when.resolve(false); + } - function buildUrl(imageryProvider, parts, partFunctionInvoker) { - var url = ''; + if (!defined(pendingPromise)) { + pendingPromise = CesiumIonResource._loadJson(endpointResource) + .then(function(newEndpoint) { + //Set the token for root resource so derived resources automatically pick it up + var ionRoot = that.ionRoot; + if (defined(ionRoot)) { + ionRoot.ionEndpoint = newEndpoint; + ionRoot.queryParameters.access_token = newEndpoint.accessToken; + } + return newEndpoint; + }) + .always(function(newEndpoint) { + // Pass or fail, we're done with this promise, the next failure should use a new one. + pendingPromise = undefined; - for (var i = 0; i < parts.length; ++i) { - var part = parts[i]; - if (typeof part === 'string') { - url += part; - } else { - url += encodeURIComponent(partFunctionInvoker(part)); + // We need this return because our old busted version of when + // doesn't conform to spec of returning the result of the above `then`. + return newEndpoint; + }); } - } - var proxy = imageryProvider._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } + return pendingPromise.then(function(newEndpoint) { + // Set the new token and endpoint for this resource + that.ionEndpoint = newEndpoint; + that.queryParameters.access_token = newEndpoint.accessToken; + return true; + }); + }; - return url; + //Exposed for testing + retryCallback._pendingPromise = pendingPromise; + + return retryCallback; } - function urlTemplateToParts(url, tags) { - if (!defined(url)) { - return undefined; - } + CesiumIonResource._CesiumIonResource = CesiumIonResource; + CesiumIonResource._createRetryCallback = createRetryCallback; + CesiumIonResource._loadJson = loadJson; - var parts = []; - var nextIndex = 0; - var minIndex; - var minTag; - var tagList = Object.keys(tags); + return CesiumIonResource; +}); - while (nextIndex < url.length) { - minIndex = Number.MAX_VALUE; - minTag = undefined; +define('Scene/CesiumIon',[ + '../Core/Check', + '../Core/clone', + '../Core/defaultValue', + '../Core/defined', + '../Core/loadJson', + '../Core/Resource', + '../Core/RuntimeError', + '../ThirdParty/when', + './ArcGisMapServerImageryProvider', + './BingMapsImageryProvider', + './Cesium3DTileset', + './CesiumIonResource', + './createTileMapServiceImageryProvider', + './GoogleEarthEnterpriseMapsProvider', + './MapboxImageryProvider', + './SingleTileImageryProvider', + './UrlTemplateImageryProvider', + './WebMapServiceImageryProvider', + './WebMapTileServiceImageryProvider' + ], function( + Check, + clone, + defaultValue, + defined, + loadJson, + Resource, + RuntimeError, + when, + ArcGisMapServerImageryProvider, + BingMapsImageryProvider, + Cesium3DTileset, + CesiumIonResource, + createTileMapServiceImageryProvider, + GoogleEarthEnterpriseMapsProvider, + MapboxImageryProvider, + SingleTileImageryProvider, + UrlTemplateImageryProvider, + WebMapServiceImageryProvider, + WebMapTileServiceImageryProvider) { + 'use strict'; - for (var i = 0; i < tagList.length; ++i) { - var thisIndex = url.indexOf(tagList[i], nextIndex); - if (thisIndex >= 0 && thisIndex < minIndex) { - minIndex = thisIndex; - minTag = tagList[i]; - } - } + /** + * Utility object for working with the Cesium ion API. + * + * @see https://cesium.com + * + * @exports CesiumIon + * + * @experimental This class is part of Cesium ion beta functionality and may change without our normal deprecation policy. + */ + var CesiumIon = {}; - if (!defined(minTag)) { - parts.push(url.substring(nextIndex)); - nextIndex = url.length; - } else { - if (nextIndex < minIndex) { - parts.push(url.substring(nextIndex, minIndex)); - } - parts.push(tags[minTag]); - nextIndex = minIndex + minTag.length; - } - } + /** + * The default Cesium ion access token to use. + * + * @type {String} + */ + CesiumIon.defaultAccessToken = undefined; - return parts; - } + /** + * The default Cesium ion server to use. + * + * @type {String} + * @default https://api.cesium.com + */ + CesiumIon.defaultServerUrl = 'https://api.cesium.com'; - function padWithZerosIfNecessary(imageryProvider, key, value) { - if (imageryProvider && - imageryProvider.urlSchemeZeroPadding && - imageryProvider.urlSchemeZeroPadding.hasOwnProperty(key) ) - { - var paddingTemplate = imageryProvider.urlSchemeZeroPadding[key]; - if (typeof paddingTemplate === 'string') { - var paddingTemplateWidth = paddingTemplate.length; - if (paddingTemplateWidth > 1) { - value = (value.length >= paddingTemplateWidth) ? value : new Array(paddingTemplateWidth - value.toString().length + 1).join('0') + value; + /** + * Asynchronously creates a {@link Resource} representing a Cesium ion asset. + * + * @param {Number} assetId The Cesium ion asset id. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.accessToken=CesiumIon.defaultAccessToken] The access token to use. + * @param {String} [options.serverUrl=CesiumIon.defaultServerUrl] The url to the Cesium ion API server. + * @returns {Promise.<Resource>} A Promise to a Resource representing the Cesium ion Asset. + * + * @example + * //Load a Cesium3DTileset with asset ID of 124624234 + * Cesium.CesiumIon.createResource(124624234) + * .then(function (resource) { + * viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url: resource })); + * }); + * + * @example + * //Load a CZML file with asset ID of 10890 + * Cesium.CesiumIon.createResource(10890) + * .then(function (resource) { + * viewer.dataSources.add(Cesium.CzmlDataSource.load(resource)); + * }); + * + * @example + * //Load an ImageryProvider with asset ID of 2347923 + * Cesium.CesiumIon.createResource(2347923) + * .then(function (resource) { + * viewer.imageryLayers.addProvider(Cesium.createTileMapServiceImageryProvider({url : resource })); + * }); + */ + CesiumIon.createResource = function(assetId, options) { + var endpointResource = CesiumIon._createEndpointResource(assetId, options); + + return CesiumIon._loadJson(endpointResource) + .then(function (endpoint) { + + var externalType = endpoint.externalType; + if (!defined(externalType)) { + return CesiumIonResource.create(endpoint, endpointResource); } - } - } - return value; - } - function xTag(imageryProvider, x, y, level) { - return padWithZerosIfNecessary(imageryProvider, '{x}', x); - } + // 3D Tiles and STK Terrain Server external assets can still be represented as a resource + // object, just not the CesiumIonResource object. + if (externalType === '3DTILES' || externalType === 'STK_TERRAIN_SERVER') { + return new Resource({ url: endpoint.options.url }); + } - function reverseXTag(imageryProvider, x, y, level) { - var reverseX = imageryProvider.tilingScheme.getNumberOfXTilesAtLevel(level) - x - 1; - return padWithZerosIfNecessary(imageryProvider, '{reverseX}', reverseX); - } + //External imagery assets have additional configuration that can't be represented as a Resource + throw new RuntimeError('CesiumIon.createResource does not support external imagery assets; use CesiumIon.createImageryProvider instead.'); + }); + }; - function yTag(imageryProvider, x, y, level) { - return padWithZerosIfNecessary(imageryProvider, '{y}', y); - } + /** + * @private + */ + CesiumIon._createEndpointResource = function (assetId, options) { + Check.defined('assetId', assetId); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var serverUrl = defaultValue(options.serverUrl, CesiumIon.defaultServerUrl); + var accessToken = defaultValue(options.accessToken, CesiumIon.defaultAccessToken); - function reverseYTag(imageryProvider, x, y, level) { - var reverseY = imageryProvider.tilingScheme.getNumberOfYTilesAtLevel(level) - y - 1; - return padWithZerosIfNecessary(imageryProvider, '{reverseY}', reverseY); - } + var resourceOptions = { + url: serverUrl + '/v1/assets/' + assetId + '/endpoint' + }; - function reverseZTag(imageryProvider, x, y, level) { - var maximumLevel = imageryProvider.maximumLevel; - var reverseZ = defined(maximumLevel) && level < maximumLevel ? maximumLevel - level - 1 : level; - return padWithZerosIfNecessary(imageryProvider, '{reverseZ}', reverseZ); - } + if (defined(accessToken)) { + resourceOptions.queryParameters = { access_token: accessToken }; + } - function zTag(imageryProvider, x, y, level) { - return padWithZerosIfNecessary(imageryProvider, '{z}', level); - } + return new Resource(resourceOptions); + }; - function sTag(imageryProvider, x, y, level) { - var index = (x + y + level) % imageryProvider._subdomains.length; - return imageryProvider._subdomains[index]; + function createFactory(Type) { + return function(options) { + return new Type(options); + }; } - function computeDegrees(imageryProvider, x, y, level) { - if (degreesScratchComputed) { - return; - } + // These values are the unofficial list of supported external imagery + // assets in the Cesium ion beta. They are subject to change. + var ImageryProviderMapping = { + ARCGIS_MAPSERVER: createFactory(ArcGisMapServerImageryProvider), + BING: createFactory(BingMapsImageryProvider), + GOOGLE_EARTH: createFactory(GoogleEarthEnterpriseMapsProvider), + MAPBOX: createFactory(MapboxImageryProvider), + SINGLE_TILE: createFactory(SingleTileImageryProvider), + TMS: createTileMapServiceImageryProvider, + URL_TEMPLATE: createFactory(UrlTemplateImageryProvider), + WMS: createFactory(WebMapServiceImageryProvider), + WMTS: createFactory(WebMapTileServiceImageryProvider) + }; - imageryProvider.tilingScheme.tileXYToRectangle(x, y, level, degreesScratch); - degreesScratch.west = CesiumMath.toDegrees(degreesScratch.west); - degreesScratch.south = CesiumMath.toDegrees(degreesScratch.south); - degreesScratch.east = CesiumMath.toDegrees(degreesScratch.east); - degreesScratch.north = CesiumMath.toDegrees(degreesScratch.north); + /** + * Asynchronously creates an {@link ImageryProvider} representing a Cesium ion imagery asset and + * waits for it to become ready. Unlike {@link CesiumIon.createResource}, this function supports + * external asset functionality. + * + * @param {Number} assetId The Cesium ion asset id. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.accessToken=CesiumIon.defaultAccessToken] The access token to use. + * @param {String} [options.serverUrl=CesiumIon.defaultServerUrl] The url to the Cesium ion API server. + * @returns {Promise<ImageryProvider>} A promise to a ready imagery provider representing the requested Cesium ion Asset. + * + * @example + * //Load an ImageryProvider with asset ID of 2347923 + * Cesium.CesiumIon.createImageryProvider(2347923) + * .then(function (imageryProvider) { + * viewer.imageryLayers.addProvider(imageryProvider); + * }); + */ + CesiumIon.createImageryProvider = function(assetId, options) { + var endpointResource = CesiumIon._createEndpointResource(assetId, options); - degreesScratchComputed = true; - } + return CesiumIon._loadJson(endpointResource) + .then(function(endpoint) { - function westDegreesTag(imageryProvider, x, y, level) { - computeDegrees(imageryProvider, x, y, level); - return degreesScratch.west; - } + if (endpoint.type !== 'IMAGERY') { + throw new RuntimeError('Cesium ion asset ' + assetId + ' is not an imagery asset.'); + } - function southDegreesTag(imageryProvider, x, y, level) { - computeDegrees(imageryProvider, x, y, level); - return degreesScratch.south; - } + var externalType = endpoint.externalType; + if (!defined(externalType)) { + return createTileMapServiceImageryProvider({ + url: CesiumIonResource.create(endpoint, endpointResource) + }); + } - function eastDegreesTag(imageryProvider, x, y, level) { - computeDegrees(imageryProvider, x, y, level); - return degreesScratch.east; - } + var factory = ImageryProviderMapping[externalType]; - function northDegreesTag(imageryProvider, x, y, level) { - computeDegrees(imageryProvider, x, y, level); - return degreesScratch.north; - } + if (!defined(factory)) { + throw new RuntimeError('Unrecognized Cesium ion imagery type: ' + externalType); + } - function computeProjected(imageryProvider, x, y, level) { - if (projectedScratchComputed) { - return; - } + return factory(endpoint.options); + }) + .then(function(imageryProvider) { + return imageryProvider.readyPromise + .then(function() { return imageryProvider; }); + }); + }; - imageryProvider.tilingScheme.tileXYToNativeRectangle(x, y, level, projectedScratch); + /** + * Asynchronously creates a {@link Cesium3DTileset} representing a Cesium ion 3D Tiles asset and + * waits for it to become ready. + * + * @param {Number} assetId The Cesium ion asset id. + * @param {Object} [options] An object with the following properties: + * @param {String} [options.accessToken=CesiumIon.defaultAccessToken] The access token to use. + * @param {String} [options.serverUrl=CesiumIon.defaultServerUrl] The url to the Cesium ion API server. + * @param {String} [options.tilesetOptions] Additional options to be passed to the {@link Cesium3DTileset} constructor. + * @returns {Promise<Cesium3DTileset>} A promise to the ready tileset representing the requested Cesium ion Asset. + * + * @example + * //Load a tileset with asset ID of 2347923 + * Cesium.CesiumIon.create3DTileset(2347923) + * .then(function (tileset) { + * viewer.scene.primitives.add(tileset); + * }); + * + * //Load a tileset with asset ID of 2347923 for 3D Tile classification + * Cesium.CesiumIon.create3DTileset(2347923, { tilesetOptions: { classificationType: Cesium.ClassificationType.CESIUM_3D_TILE } }) + * .then(function (tileset) { + * viewer.scene.primitives.add(tileset); + * }); + */ + CesiumIon.create3DTileset = function(assetId, options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var endpointResource = CesiumIon._createEndpointResource(assetId, options); - projectedScratchComputed = true; - } + return CesiumIon._loadJson(endpointResource) + .then(function(endpoint) { - function westProjectedTag(imageryProvider, x, y, level) { - computeProjected(imageryProvider, x, y, level); - return projectedScratch.west; - } + if (endpoint.type !== '3DTILES') { + throw new RuntimeError('Cesium ion asset ' + assetId + ' is not a 3D Tiles asset.'); + } - function southProjectedTag(imageryProvider, x, y, level) { - computeProjected(imageryProvider, x, y, level); - return projectedScratch.south; - } + var externalType = endpoint.externalType; - function eastProjectedTag(imageryProvider, x, y, level) { - computeProjected(imageryProvider, x, y, level); - return projectedScratch.east; - } + var resource; + if (!defined(externalType)) { + resource = CesiumIonResource.create(endpoint, endpointResource); + } else if (externalType === '3DTILES') { + resource = new Resource({ url: endpoint.options.url }); + } else { + throw new RuntimeError('Unrecognized Cesium ion external 3DTILES type: ' + externalType); + } - function northProjectedTag(imageryProvider, x, y, level) { - computeProjected(imageryProvider, x, y, level); - return projectedScratch.north; - } + var tilesetOptions = options.tilesetOptions; + if (defined(tilesetOptions)) { + tilesetOptions = clone(tilesetOptions); + tilesetOptions.url = resource; + } else { + tilesetOptions = { + url: resource + }; + } - function widthTag(imageryProvider, x, y, level) { - return imageryProvider.tileWidth; - } + var tileset = new Cesium3DTileset(tilesetOptions); + return tileset.readyPromise; + }); + }; - function heightTag(imageryProvider, x, y, level) { - return imageryProvider.tileHeight; - } + //Exposed for testing + CesiumIon._loadJson = function(resource) { + return resource.fetchJson(); + }; - function iTag(imageryProvider, x, y, level, longitude, latitude, format) { - computeIJ(imageryProvider, x, y, level, longitude, latitude); - return ijScratch.x; - } + return CesiumIon; +}); - function jTag(imageryProvider, x, y, level, longitude, latitude, format) { - computeIJ(imageryProvider, x, y, level, longitude, latitude); - return ijScratch.y; - } +define('Scene/CircleEmitter',[ + '../Core/Cartesian3', + '../Core/Check', + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/Math' + ], function( + Cartesian3, + Check, + defaultValue, + defineProperties, + CesiumMath) { + 'use strict'; - function reverseITag(imageryProvider, x, y, level, longitude, latitude, format) { - computeIJ(imageryProvider, x, y, level, longitude, latitude); - return imageryProvider.tileWidth - ijScratch.x - 1; - } + /** + * A ParticleEmitter that emits particles from a circle. + * Particles will be positioned within a circle and have initial velocities going along the z vector. + * + * @alias CircleEmitter + * @constructor + * + * @param {Number} [radius=1.0] The radius of the circle in meters. + */ + function CircleEmitter(radius) { + radius = defaultValue(radius, 1.0); - function reverseJTag(imageryProvider, x, y, level, longitude, latitude, format) { - computeIJ(imageryProvider, x, y, level, longitude, latitude); - return imageryProvider.tileHeight - ijScratch.y - 1; + Check.typeOf.number.greaterThan('radius', radius, 0.0); + + this._radius = defaultValue(radius, 1.0); } - var rectangleScratch = new Rectangle(); - var longitudeLatitudeProjectedScratch = new Cartesian3(); - - function computeIJ(imageryProvider, x, y, level, longitude, latitude, format) { - if (ijScratchComputed) { - return; + defineProperties(CircleEmitter.prototype, { + /** + * The radius of the circle in meters. + * @memberof CircleEmitter.prototype + * @type {Number} + * @default 1.0 + */ + radius : { + get : function() { + return this._radius; + }, + set : function(value) { + Check.typeOf.number.greaterThan('value', value, 0.0); + this._radius = value; + } } + }); - computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude); - var projected = longitudeLatitudeProjectedScratch; + /** + * Initializes the given {@link Particle} by setting it's position and velocity. + * + * @private + * @param {Particle} particle The particle to initialize. + */ + CircleEmitter.prototype.emit = function(particle) { + var theta = CesiumMath.randomBetween(0.0, CesiumMath.TWO_PI); + var rad = CesiumMath.randomBetween(0.0, this._radius); - var rectangle = imageryProvider.tilingScheme.tileXYToNativeRectangle(x, y, level, rectangleScratch); - ijScratch.x = (imageryProvider.tileWidth * (projected.x - rectangle.west) / rectangle.width) | 0; - ijScratch.y = (imageryProvider.tileHeight * (rectangle.north - projected.y) / rectangle.height) | 0; - ijScratchComputed = true; - } + var x = rad * Math.cos(theta); + var y = rad * Math.sin(theta); + var z = 0.0; - function longitudeDegreesTag(imageryProvider, x, y, level, longitude, latitude, format) { - return CesiumMath.toDegrees(longitude); - } + particle.position = Cartesian3.fromElements(x, y, z, particle.position); + particle.velocity = Cartesian3.clone(Cartesian3.UNIT_Z, particle.velocity); + }; - function latitudeDegreesTag(imageryProvider, x, y, level, longitude, latitude, format) { - return CesiumMath.toDegrees(latitude); - } + return CircleEmitter; +}); - function longitudeProjectedTag(imageryProvider, x, y, level, longitude, latitude, format) { - computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude); - return longitudeLatitudeProjectedScratch.x; - } +define('Scene/ConeEmitter',[ + '../Core/Cartesian3', + '../Core/Check', + '../Core/defaultValue', + '../Core/defineProperties', + '../Core/Math' + ], function( + Cartesian3, + Check, + defaultValue, + defineProperties, + CesiumMath) { + 'use strict'; - function latitudeProjectedTag(imageryProvider, x, y, level, longitude, latitude, format) { - computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude); - return longitudeLatitudeProjectedScratch.y; - } + var defaultAngle = CesiumMath.toRadians(30.0); - var cartographicScratch = new Cartographic(); + /** + * A ParticleEmitter that emits particles within a cone. + * Particles will be positioned at the tip of the cone and have initial velocities going towards the base. + * + * @alias ConeEmitter + * @constructor + * + * @param {Number} [angle=Cesium.Math.toRadians(30.0)] The angle of the cone in radians. + */ + function ConeEmitter(angle) { + this._angle = defaultValue(angle, defaultAngle); + } - function computeLongitudeLatitudeProjected(imageryProvider, x, y, level, longitude, latitude, format) { - if (longitudeLatitudeProjectedScratchComputed) { - return; + defineProperties(ConeEmitter.prototype, { + /** + * The angle of the cone in radians. + * @memberof CircleEmitter.prototype + * @type {Number} + * @default Cesium.Math.toRadians(30.0) + */ + angle : { + get : function() { + return this._angle; + }, + set : function(value) { + Check.typeOf.number('value', value); + this._angle = value; + } } + }); - if (imageryProvider.tilingScheme instanceof GeographicTilingScheme) { - longitudeLatitudeProjectedScratch.x = CesiumMath.toDegrees(longitude); - longitudeLatitudeProjectedScratch.y = CesiumMath.toDegrees(latitude); - } else { - var cartographic = cartographicScratch; - cartographic.longitude = longitude; - cartographic.latitude = latitude; - imageryProvider.tilingScheme.projection.project(cartographic, longitudeLatitudeProjectedScratch); - } + /** + * Initializes the given {Particle} by setting it's position and velocity. + * + * @private + * @param {Particle} particle The particle to initialize + */ + ConeEmitter.prototype.emit = function(particle) { + var radius = Math.tan(this._angle); - longitudeLatitudeProjectedScratchComputed = true; - } + // Compute a random point on the cone's base + var theta = CesiumMath.randomBetween(0.0, CesiumMath.TWO_PI); + var rad = CesiumMath.randomBetween(0.0, radius); - function formatTag(imageryProvider, x, y, level, longitude, latitude, format) { - return format; - } + var x = rad * Math.cos(theta); + var y = rad * Math.sin(theta); + var z = 1.0; - return UrlTemplateImageryProvider; + particle.velocity = Cartesian3.fromElements(x, y, z, particle.velocity); + Cartesian3.normalize(particle.velocity, particle.velocity); + particle.position = Cartesian3.clone(Cartesian3.ZERO, particle.position); + }; + + return ConeEmitter; }); define('Scene/createOpenStreetMapImageryProvider',[ + '../Core/appendForwardSlash', '../Core/Credit', '../Core/defaultValue', + '../Core/defined', + '../Core/deprecationWarning', '../Core/DeveloperError', '../Core/Rectangle', + '../Core/Resource', '../Core/WebMercatorTilingScheme', './UrlTemplateImageryProvider' ], function( + appendForwardSlash, Credit, defaultValue, + defined, + deprecationWarning, DeveloperError, Rectangle, + Resource, WebMercatorTilingScheme, UrlTemplateImageryProvider) { 'use strict'; - var trailingSlashRegex = /\/$/; var defaultCredit = new Credit({text: 'MapQuest, Open Street Map and contributors, CC-BY-SA'}); /** @@ -185711,7 +199734,6 @@ define('Scene/createOpenStreetMapImageryProvider',[ * @param {Object} [options] Object with the following properties: * @param {String} [options.url='https://a.tile.openstreetmap.org'] The OpenStreetMap server url. * @param {String} [options.fileExtension='png'] The file extension for images on the server. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL. * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. @@ -185743,12 +199765,16 @@ define('Scene/createOpenStreetMapImageryProvider',[ options = defaultValue(options, {}); var url = defaultValue(options.url, 'https://a.tile.openstreetmap.org/'); + url = appendForwardSlash(url); + url += '{z}/{x}/{y}.' + defaultValue(options.fileExtension, 'png'); - if (!trailingSlashRegex.test(url)) { - url = url + '/'; + if (defined(options.proxy)) { + deprecationWarning('createOpenStreetMapImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - var fileExtension = defaultValue(options.fileExtension, 'png'); + var resource = Resource.createIfNeeded(url, { + proxy: options.proxy + }); var tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); @@ -185775,11 +199801,8 @@ define('Scene/createOpenStreetMapImageryProvider',[ credit = new Credit({text: credit}); } - var templateUrl = url + '{z}/{x}/{y}.' + fileExtension; - return new UrlTemplateImageryProvider({ - url: templateUrl, - proxy: options.proxy, + url: resource, credit: credit, tilingScheme: tilingScheme, tileWidth: tileWidth, @@ -185902,288 +199925,6 @@ define('Scene/createTangentSpaceDebugPrimitive',[ return createTangentSpaceDebugPrimitive; }); -define('Scene/createTileMapServiceImageryProvider',[ - '../Core/Cartesian2', - '../Core/Cartographic', - '../Core/defaultValue', - '../Core/defined', - '../Core/DeveloperError', - '../Core/GeographicTilingScheme', - '../Core/joinUrls', - '../Core/loadXML', - '../Core/Rectangle', - '../Core/RuntimeError', - '../Core/TileProviderError', - '../Core/WebMercatorTilingScheme', - '../ThirdParty/when', - './UrlTemplateImageryProvider' - ], function( - Cartesian2, - Cartographic, - defaultValue, - defined, - DeveloperError, - GeographicTilingScheme, - joinUrls, - loadXML, - Rectangle, - RuntimeError, - TileProviderError, - WebMercatorTilingScheme, - when, - UrlTemplateImageryProvider) { - 'use strict'; - - /** - * Creates a {@link UrlTemplateImageryProvider} instance that provides tiled imagery as generated by - * {@link http://www.maptiler.org/'>MapTiler</a> / <a href='http://www.klokan.cz/projects/gdal2tiles/|GDDAL2Tiles} etc. - * - * @exports createTileMapServiceImageryProvider - * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.url='.'] Path to image tiles on server. - * @param {String} [options.fileExtension='png'] The file extension for images on the server. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL. - * @param {Credit|String} [options.credit=''] A credit for the data source, which is displayed on the canvas. - * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying - * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely - * to result in rendering problems. - * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. - * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal - * surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme} - * is used. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. - * @param {Number} [options.tileWidth=256] Pixel width of image tiles. - * @param {Number} [options.tileHeight=256] Pixel height of image tiles. - * @param {Boolean} [options.flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml. - * Specifying this option will do the same, allowing for loading of these incorrect tilesets. - * @returns {UrlTemplateImageryProvider} The imagery provider. - * - * @see ArcGisMapServerImageryProvider - * @see BingMapsImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider - * - * @see {@link http://www.maptiler.org/|MapTiler} - * @see {@link http://www.klokan.cz/projects/gdal2tiles/|GDDAL2Tiles} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * - * @example - * var tms = Cesium.createTileMapServiceImageryProvider({ - * url : '../images/cesium_maptiler/Cesium_Logo_Color', - * fileExtension: 'png', - * maximumLevel: 4, - * rectangle: new Cesium.Rectangle( - * Cesium.Math.toRadians(-120.0), - * Cesium.Math.toRadians(20.0), - * Cesium.Math.toRadians(-60.0), - * Cesium.Math.toRadians(40.0)) - * }); - */ - function createTileMapServiceImageryProvider(options) { - options = defaultValue(options, {}); - - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); - } - - var url = options.url; - - var deferred = when.defer(); - var imageryProvider = new UrlTemplateImageryProvider(deferred.promise); - - var metadataError; - - function metadataSuccess(xml) { - var tileFormatRegex = /tileformat/i; - var tileSetRegex = /tileset/i; - var tileSetsRegex = /tilesets/i; - var bboxRegex = /boundingbox/i; - var format, bbox, tilesets; - var tilesetsList = []; //list of TileSets - - // Allowing options properties (already copied to that) to override XML values - - // Iterate XML Document nodes for properties - var nodeList = xml.childNodes[0].childNodes; - for (var i = 0; i < nodeList.length; i++){ - if (tileFormatRegex.test(nodeList.item(i).nodeName)) { - format = nodeList.item(i); - } else if (tileSetsRegex.test(nodeList.item(i).nodeName)) { - tilesets = nodeList.item(i); // Node list of TileSets - var tileSetNodes = nodeList.item(i).childNodes; - // Iterate the nodes to find all TileSets - for(var j = 0; j < tileSetNodes.length; j++) { - if (tileSetRegex.test(tileSetNodes.item(j).nodeName)) { - // Add them to tilesets list - tilesetsList.push(tileSetNodes.item(j)); - } - } - } else if (bboxRegex.test(nodeList.item(i).nodeName)) { - bbox = nodeList.item(i); - } - } - - var message; - if (!defined(tilesets) || !defined(bbox)) { - message = 'Unable to find expected tilesets or bbox attributes in ' + joinUrls(url, 'tilemapresource.xml') + '.'; - metadataError = TileProviderError.handleError(metadataError, imageryProvider, imageryProvider.errorEvent, message, undefined, undefined, undefined, requestMetadata); - if(!metadataError.retry) { - deferred.reject(new RuntimeError(message)); - } - return; - } - - var fileExtension = defaultValue(options.fileExtension, format.getAttribute('extension')); - var tileWidth = defaultValue(options.tileWidth, parseInt(format.getAttribute('width'), 10)); - var tileHeight = defaultValue(options.tileHeight, parseInt(format.getAttribute('height'), 10)); - var minimumLevel = defaultValue(options.minimumLevel, parseInt(tilesetsList[0].getAttribute('order'), 10)); - var maximumLevel = defaultValue(options.maximumLevel, parseInt(tilesetsList[tilesetsList.length - 1].getAttribute('order'), 10)); - var tilingSchemeName = tilesets.getAttribute('profile'); - var tilingScheme = options.tilingScheme; - - if (!defined(tilingScheme)) { - if (tilingSchemeName === 'geodetic' || tilingSchemeName === 'global-geodetic') { - tilingScheme = new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); - } else if (tilingSchemeName === 'mercator' || tilingSchemeName === 'global-mercator') { - tilingScheme = new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); - } else { - message = joinUrls(url, 'tilemapresource.xml') + 'specifies an unsupported profile attribute, ' + tilingSchemeName + '.'; - metadataError = TileProviderError.handleError(metadataError, imageryProvider, imageryProvider.errorEvent, message, undefined, undefined, undefined, requestMetadata); - if(!metadataError.retry) { - deferred.reject(new RuntimeError(message)); - } - return; - } - } - - // rectangle handling - var rectangle = Rectangle.clone(options.rectangle); - - if (!defined(rectangle)) { - var sw; - var ne; - var swXY; - var neXY; - - // In older versions of gdal x and y values were flipped, which is why we check for an option to flip - // the values here as well. Unfortunately there is no way to autodetect whether flipping is needed. - var flipXY = defaultValue(options.flipXY, false); - if (flipXY) { - swXY = new Cartesian2(parseFloat(bbox.getAttribute('miny')), parseFloat(bbox.getAttribute('minx'))); - neXY = new Cartesian2(parseFloat(bbox.getAttribute('maxy')), parseFloat(bbox.getAttribute('maxx'))); - } else { - swXY = new Cartesian2(parseFloat(bbox.getAttribute('minx')), parseFloat(bbox.getAttribute('miny'))); - neXY = new Cartesian2(parseFloat(bbox.getAttribute('maxx')), parseFloat(bbox.getAttribute('maxy'))); - } - - // Determine based on the profile attribute if this tileset was generated by gdal2tiles.py, which - // uses 'mercator' and 'geodetic' profiles, or by a tool compliant with the TMS standard, which is - // 'global-mercator' and 'global-geodetic' profiles. In the gdal2Tiles case, X and Y are always in - // geodetic degrees. - var isGdal2tiles = tilingSchemeName === 'geodetic' || tilingSchemeName === 'mercator'; - if (tilingScheme instanceof GeographicTilingScheme || isGdal2tiles) { - sw = Cartographic.fromDegrees(swXY.x, swXY.y); - ne = Cartographic.fromDegrees(neXY.x, neXY.y); - } else { - var projection = tilingScheme.projection; - sw = projection.unproject(swXY); - ne = projection.unproject(neXY); - } - - rectangle = new Rectangle(sw.longitude, sw.latitude, ne.longitude, ne.latitude); - } - - // The rectangle must not be outside the bounds allowed by the tiling scheme. - if (rectangle.west < tilingScheme.rectangle.west) { - rectangle.west = tilingScheme.rectangle.west; - } - if (rectangle.east > tilingScheme.rectangle.east) { - rectangle.east = tilingScheme.rectangle.east; - } - if (rectangle.south < tilingScheme.rectangle.south) { - rectangle.south = tilingScheme.rectangle.south; - } - if (rectangle.north > tilingScheme.rectangle.north) { - rectangle.north = tilingScheme.rectangle.north; - } - - // Check the number of tiles at the minimum level. If it's more than four, - // try requesting the lower levels anyway, because starting at the higher minimum - // level will cause too many tiles to be downloaded and rendered. - var swTile = tilingScheme.positionToTileXY(Rectangle.southwest(rectangle), minimumLevel); - var neTile = tilingScheme.positionToTileXY(Rectangle.northeast(rectangle), minimumLevel); - var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1); - if (tileCount > 4) { - minimumLevel = 0; - } - - var templateUrl = joinUrls(url, '{z}/{x}/{reverseY}.' + fileExtension); - - deferred.resolve({ - url : templateUrl, - tilingScheme : tilingScheme, - rectangle : rectangle, - tileWidth : tileWidth, - tileHeight : tileHeight, - minimumLevel : minimumLevel, - maximumLevel : maximumLevel, - proxy : options.proxy, - tileDiscardPolicy : options.tileDiscardPolicy, - credit: options.credit - }); - } - - function metadataFailure(error) { - // Can't load XML, still allow options and defaults - var fileExtension = defaultValue(options.fileExtension, 'png'); - var tileWidth = defaultValue(options.tileWidth, 256); - var tileHeight = defaultValue(options.tileHeight, 256); - var minimumLevel = defaultValue(options.minimumLevel, 0); - var maximumLevel = options.maximumLevel; - var tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme({ ellipsoid : options.ellipsoid }); - var rectangle = defaultValue(options.rectangle, tilingScheme.rectangle); - - var templateUrl = joinUrls(url, '{z}/{x}/{reverseY}.' + fileExtension); - - deferred.resolve({ - url : templateUrl, - tilingScheme : tilingScheme, - rectangle : rectangle, - tileWidth : tileWidth, - tileHeight : tileHeight, - minimumLevel : minimumLevel, - maximumLevel : maximumLevel, - proxy : options.proxy, - tileDiscardPolicy : options.tileDiscardPolicy, - credit: options.credit - }); - } - - function requestMetadata() { - var resourceUrl = joinUrls(url, 'tilemapresource.xml'); - var proxy = options.proxy; - if (defined(proxy)) { - resourceUrl = proxy.getURL(resourceUrl); - } - // Try to load remaining parameters from XML - loadXML(resourceUrl).then(metadataSuccess).otherwise(metadataFailure); - } - - requestMetadata(); - return imageryProvider; - } - - return createTileMapServiceImageryProvider; -}); - define('Scene/CreditDisplay',[ '../Core/Check', '../Core/Credit', @@ -186368,6 +200109,11 @@ define('Scene/CreditDisplay',[ removeCreditDomElement(credit); } } + } + + function removeUnusedLightboxCredits(creditDisplay) { + var i; + var credit; var displayedLightboxCredits = creditDisplay._displayedCredits.lightboxCredits; for (i = 0; i < displayedLightboxCredits.length; i++) { credit = displayedLightboxCredits[i]; @@ -186663,6 +200409,23 @@ define('Scene/CreditDisplay',[ this._expanded = false; }; + /** + * Updates the credit display before a new frame is rendered. + */ + CreditDisplay.prototype.update = function() { + var displayedLightboxCredits = []; + + if (this._expanded && defined(this._creditsToUpdate)) { + styleLightboxContainer(this); + displayLightboxCredits(this, this._creditsToUpdate); + displayedLightboxCredits = this._creditsToUpdate.slice(); + } + + removeUnusedLightboxCredits(this); + + this._displayedCredits.lightboxCredits = displayedLightboxCredits; + }; + /** * Resets the credit display to a beginning of frame state, clearing out current credits. */ @@ -186673,7 +200436,7 @@ define('Scene/CreditDisplay',[ }; /** - * Sets the credit display to the end of frame state, displaying current credits in the credit container + * Sets the credit display to the end of frame state, displaying credits from the last frame in the credit container. */ CreditDisplay.prototype.endFrame = function() { displayImageCredits(this, this._defaultImageCredits); @@ -186684,22 +200447,16 @@ define('Scene/CreditDisplay',[ var displayedTextCredits = this._defaultTextCredits.concat(this._currentFrameCredits.textCredits); var displayedImageCredits = this._defaultImageCredits.concat(this._currentFrameCredits.imageCredits); - var displayedLightboxCredits = []; var showLightboxLink = this._currentFrameCredits.lightboxCredits.length > 0; this._expandLink.style.display = showLightboxLink ? 'inline' : 'none'; - if (this._expanded) { - styleLightboxContainer(this); - displayLightboxCredits(this, this._currentFrameCredits.lightboxCredits); - - displayedLightboxCredits = this._currentFrameCredits.lightboxCredits.slice(); - } removeUnusedCredits(this); this._displayedCredits.textCredits = displayedTextCredits; this._displayedCredits.imageCredits = displayedImageCredits; - this._displayedCredits.lightboxCredits = displayedLightboxCredits; + + this._creditsToUpdate = this._currentFrameCredits.lightboxCredits.slice(); }; /** @@ -189012,7 +202769,7 @@ define('Scene/FrameRateMonitor',[ this._pauseCount = 0; var that = this; - this._preRenderRemoveListener = this._scene.preRender.addEventListener(function(scene, time) { + this._preUpdateRemoveListener = this._scene.preUpdate.addEventListener(function(scene, time) { update(that, time); }); @@ -189186,7 +202943,7 @@ define('Scene/FrameRateMonitor',[ * @see FrameRateMonitor#isDestroyed */ FrameRateMonitor.prototype.destroy = function() { - this._preRenderRemoveListener(); + this._preUpdateRemoveListener(); if (defined(this._visibilityChangeRemoveListener)) { this._visibilityChangeRemoveListener(); @@ -190361,334 +204118,6 @@ define('Scene/FXAA',[ return FXAA; }); -define('Scene/GetFeatureInfoFormat',[ - '../Core/Cartographic', - '../Core/defined', - '../Core/DeveloperError', - '../Core/RuntimeError', - './ImageryLayerFeatureInfo' - ], function( - Cartographic, - defined, - DeveloperError, - RuntimeError, - ImageryLayerFeatureInfo) { - 'use strict'; - - /** - * Describes the format in which to request GetFeatureInfo from a Web Map Service (WMS) server. - * - * @alias GetFeatureInfoFormat - * @constructor - * - * @param {String} type The type of response to expect from a GetFeatureInfo request. Valid - * values are 'json', 'xml', 'html', or 'text'. - * @param {String} [format] The info format to request from the WMS server. This is usually a - * MIME type such as 'application/json' or text/xml'. If this parameter is not specified, the provider will request 'json' - * using 'application/json', 'xml' using 'text/xml', 'html' using 'text/html', and 'text' using 'text/plain'. - * @param {Function} [callback] A function to invoke with the GetFeatureInfo response from the WMS server - * in order to produce an array of picked {@link ImageryLayerFeatureInfo} instances. If this parameter is not specified, - * a default function for the type of response is used. - */ - function GetFeatureInfoFormat(type, format, callback) { - if (!defined(type)) { - throw new DeveloperError('type is required.'); - } - - this.type = type; - - if (!defined(format)) { - if (type === 'json') { - format = 'application/json'; - } else if (type === 'xml') { - format = 'text/xml'; - } else if (type === 'html') { - format = 'text/html'; - } else if (type === 'text') { - format = 'text/plain'; - } - else { - throw new DeveloperError('format is required when type is not "json", "xml", "html", or "text".'); - } - } - - this.format = format; - - if (!defined(callback)) { - if (type === 'json') { - callback = geoJsonToFeatureInfo; - } else if (type === 'xml') { - callback = xmlToFeatureInfo; - } else if (type === 'html') { - callback = textToFeatureInfo; - } else if (type === 'text') { - callback = textToFeatureInfo; - } - else { - throw new DeveloperError('callback is required when type is not "json", "xml", "html", or "text".'); - } - } - - this.callback = callback; - } - - function geoJsonToFeatureInfo(json) { - var result = []; - - var features = json.features; - for (var i = 0; i < features.length; ++i) { - var feature = features[i]; - - var featureInfo = new ImageryLayerFeatureInfo(); - featureInfo.data = feature; - featureInfo.properties = feature.properties; - featureInfo.configureNameFromProperties(feature.properties); - featureInfo.configureDescriptionFromProperties(feature.properties); - - // If this is a point feature, use the coordinates of the point. - if (defined(feature.geometry) && feature.geometry.type === 'Point') { - var longitude = feature.geometry.coordinates[0]; - var latitude = feature.geometry.coordinates[1]; - featureInfo.position = Cartographic.fromDegrees(longitude, latitude); - } - - result.push(featureInfo); - } - - return result; - } - - var mapInfoMxpNamespace = 'http://www.mapinfo.com/mxp'; - var esriWmsNamespace = 'http://www.esri.com/wms'; - var wfsNamespace = 'http://www.opengis.net/wfs'; - var gmlNamespace = 'http://www.opengis.net/gml'; - - function xmlToFeatureInfo(xml) { - var documentElement = xml.documentElement; - if (documentElement.localName === 'MultiFeatureCollection' && documentElement.namespaceURI === mapInfoMxpNamespace) { - // This looks like a MapInfo MXP response - return mapInfoXmlToFeatureInfo(xml); - } else if (documentElement.localName === 'FeatureInfoResponse' && documentElement.namespaceURI === esriWmsNamespace) { - // This looks like an Esri WMS response - return esriXmlToFeatureInfo(xml); - } else if (documentElement.localName === 'FeatureCollection' && documentElement.namespaceURI === wfsNamespace) { - // This looks like a WFS/GML response. - return gmlToFeatureInfo(xml); - } else if (documentElement.localName === 'ServiceExceptionReport') { - // This looks like a WMS server error, so no features picked. - throw new RuntimeError(new XMLSerializer().serializeToString(documentElement)); - } else if (documentElement.localName === 'msGMLOutput') { - return msGmlToFeatureInfo(xml); - } else { - // Unknown response type, so just dump the XML itself into the description. - return unknownXmlToFeatureInfo(xml); - } - } - - function mapInfoXmlToFeatureInfo(xml) { - var result = []; - - var multiFeatureCollection = xml.documentElement; - - var features = multiFeatureCollection.getElementsByTagNameNS(mapInfoMxpNamespace, 'Feature'); - for (var featureIndex = 0; featureIndex < features.length; ++featureIndex) { - var feature = features[featureIndex]; - - var properties = {}; - - var propertyElements = feature.getElementsByTagNameNS(mapInfoMxpNamespace, 'Val'); - for (var propertyIndex = 0; propertyIndex < propertyElements.length; ++propertyIndex) { - var propertyElement = propertyElements[propertyIndex]; - if (propertyElement.hasAttribute('ref')) { - var name = propertyElement.getAttribute('ref'); - var value = propertyElement.textContent.trim(); - properties[name] = value; - } - } - - var featureInfo = new ImageryLayerFeatureInfo(); - featureInfo.data = feature; - featureInfo.properties = properties; - featureInfo.configureNameFromProperties(properties); - featureInfo.configureDescriptionFromProperties(properties); - result.push(featureInfo); - } - - return result; - } - - function esriXmlToFeatureInfo(xml) { - var featureInfoResponse = xml.documentElement; - var result = []; - var properties; - - var features = featureInfoResponse.getElementsByTagNameNS('*', 'FIELDS'); - if (features.length > 0) { - // Standard esri format - for (var featureIndex = 0; featureIndex < features.length; ++featureIndex) { - var feature = features[featureIndex]; - - properties = {}; - - var propertyAttributes = feature.attributes; - for (var attributeIndex = 0; attributeIndex < propertyAttributes.length; ++attributeIndex) { - var attribute = propertyAttributes[attributeIndex]; - properties[attribute.name] = attribute.value; - } - - result.push(imageryLayerFeatureInfoFromDataAndProperties(feature, properties)); - } - } else { - // Thredds format -- looks like esri, but instead of containing FIELDS, contains FeatureInfo element - var featureInfoElements = featureInfoResponse.getElementsByTagNameNS('*', 'FeatureInfo'); - for (var featureInfoElementIndex = 0; featureInfoElementIndex < featureInfoElements.length; ++featureInfoElementIndex) { - var featureInfoElement = featureInfoElements[featureInfoElementIndex]; - - properties = {}; - - // node.children is not supported in IE9-11, so use childNodes and check that child.nodeType is an element - var featureInfoChildren = featureInfoElement.childNodes; - for (var childIndex = 0; childIndex < featureInfoChildren.length; ++childIndex) { - var child = featureInfoChildren[childIndex]; - if (child.nodeType === Node.ELEMENT_NODE) { - properties[child.localName] = child.textContent; - } - } - - result.push(imageryLayerFeatureInfoFromDataAndProperties(featureInfoElement, properties)); - } - } - - return result; - } - - function gmlToFeatureInfo(xml) { - var result = []; - - var featureCollection = xml.documentElement; - - var featureMembers = featureCollection.getElementsByTagNameNS(gmlNamespace, 'featureMember'); - for (var featureIndex = 0; featureIndex < featureMembers.length; ++featureIndex) { - var featureMember = featureMembers[featureIndex]; - - var properties = {}; - getGmlPropertiesRecursively(featureMember, properties); - result.push(imageryLayerFeatureInfoFromDataAndProperties(featureMember, properties)); - } - - return result; - } - - // msGmlToFeatureInfo is similar to gmlToFeatureInfo, but assumes different XML structure - // eg. <msGMLOutput> <ABC_layer> <ABC_feature> <foo>bar</foo> ... </ABC_feature> </ABC_layer> </msGMLOutput> - - function msGmlToFeatureInfo(xml) { - var result = []; - - // Find the first child. Except for IE, this would work: - // var layer = xml.documentElement.children[0]; - var layer; - var children = xml.documentElement.childNodes; - for (var i = 0; i < children.length; i++) { - if (children[i].nodeType === Node.ELEMENT_NODE) { - layer = children[i]; - break; - } - } - if (!defined(layer)) { - throw new RuntimeError('Unable to find first child of the feature info xml document'); - } - var featureMembers = layer.childNodes; - for (var featureIndex = 0; featureIndex < featureMembers.length; ++featureIndex) { - var featureMember = featureMembers[featureIndex]; - if (featureMember.nodeType === Node.ELEMENT_NODE) { - var properties = {}; - getGmlPropertiesRecursively(featureMember, properties); - result.push(imageryLayerFeatureInfoFromDataAndProperties(featureMember, properties)); - } - } - - return result; - } - - function getGmlPropertiesRecursively(gmlNode, properties) { - var isSingleValue = true; - - for (var i = 0; i < gmlNode.childNodes.length; ++i) { - var child = gmlNode.childNodes[i]; - - if (child.nodeType === Node.ELEMENT_NODE) { - isSingleValue = false; - } - - if (child.localName === 'Point' || child.localName === 'LineString' || child.localName === 'Polygon' || child.localName === 'boundedBy') { - continue; - } - - if (child.hasChildNodes() && getGmlPropertiesRecursively(child, properties)) { - properties[child.localName] = child.textContent; - } - } - - return isSingleValue; - } - - function imageryLayerFeatureInfoFromDataAndProperties(data, properties) { - var featureInfo = new ImageryLayerFeatureInfo(); - featureInfo.data = data; - featureInfo.properties = properties; - featureInfo.configureNameFromProperties(properties); - featureInfo.configureDescriptionFromProperties(properties); - return featureInfo; - } - - function unknownXmlToFeatureInfo(xml) { - var xmlText = new XMLSerializer().serializeToString(xml); - - var element = document.createElement('div'); - var pre = document.createElement('pre'); - pre.textContent = xmlText; - element.appendChild(pre); - - var featureInfo = new ImageryLayerFeatureInfo(); - featureInfo.data = xml; - featureInfo.description = element.innerHTML; - return [featureInfo]; - } - - var emptyBodyRegex= /<body>\s*<\/body>/im; - var wmsServiceExceptionReportRegex = /<ServiceExceptionReport([\s\S]*)<\/ServiceExceptionReport>/im; - var titleRegex = /<title>([\s\S]*)<\/title>/im; - - function textToFeatureInfo(text) { - // If the text is HTML and it has an empty body tag, assume it means no features were found. - if (emptyBodyRegex.test(text)) { - return undefined; - } - - // If this is a WMS exception report, treat it as "no features found" rather than showing - // bogus feature info. - if (wmsServiceExceptionReportRegex.test(text)) { - return undefined; - } - - // If the text has a <title> element, use it as the name. - var name; - var title = titleRegex.exec(text); - if (title && title.length > 1) { - name = title[1]; - } - - var featureInfo = new ImageryLayerFeatureInfo(); - featureInfo.name = name; - featureInfo.description = text; - featureInfo.data = text; - return [featureInfo]; - } - - return GetFeatureInfoFormat; -}); - //This file is automatically rebuilt by the Cesium build process. define('Shaders/GlobeFS',[],function() { 'use strict'; @@ -192162,12 +205591,15 @@ define('Scene/GlobeSurfaceTile',[ } if (isDoneLoading) { - var newCallbacks = []; - tile._loadedCallbacks.forEach(function(cb) { - if (!cb(tile)) { - newCallbacks.push(cb); + var callbacks = tile._loadedCallbacks; + var newCallbacks = {}; + for(var layerId in callbacks) { + if (callbacks.hasOwnProperty(layerId)) { + if(!callbacks[layerId](tile)) { + newCallbacks[layerId] = callbacks[layerId]; + } } - }); + } tile._loadedCallbacks = newCallbacks; tile.state = QuadtreeTileLoadState.DONE; @@ -194053,6 +207485,7 @@ define('Scene/GlobeSurfaceTileProvider',[ '../Core/Cartesian2', '../Core/Cartesian3', '../Core/Cartesian4', + '../Core/ClippingPlaneCollection', '../Core/Color', '../Core/ColorGeometryInstanceAttribute', '../Core/combine', @@ -194062,7 +207495,6 @@ define('Scene/GlobeSurfaceTileProvider',[ '../Core/destroyObject', '../Core/DeveloperError', '../Core/Event', - '../Core/FeatureDetection', '../Core/GeometryInstance', '../Core/GeometryPipeline', '../Core/IndexDatatype', @@ -194100,6 +207532,7 @@ define('Scene/GlobeSurfaceTileProvider',[ Cartesian2, Cartesian3, Cartesian4, + ClippingPlaneCollection, Color, ColorGeometryInstanceAttribute, combine, @@ -194109,7 +207542,6 @@ define('Scene/GlobeSurfaceTileProvider',[ destroyObject, DeveloperError, Event, - FeatureDetection, GeometryInstance, GeometryPipeline, IndexDatatype, @@ -194191,6 +207623,8 @@ define('Scene/GlobeSurfaceTileProvider',[ this._imageryLayers.layerRemoved.addEventListener(GlobeSurfaceTileProvider.prototype._onLayerRemoved, this); this._imageryLayers.layerMoved.addEventListener(GlobeSurfaceTileProvider.prototype._onLayerMoved, this); this._imageryLayers.layerShownOrHidden.addEventListener(GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden, this); + this._tileLoadedEvent = new Event(); + this._imageryLayersUpdatedEvent = new Event(); this._layerOrderChanged = false; @@ -194295,6 +207729,28 @@ define('Scene/GlobeSurfaceTileProvider',[ } }, + /** + * Gets an event that is raised when an globe surface tile is loaded and ready to be rendered. + * @memberof GlobeSurfaceTileProvider.prototype + * @type {Event} + */ + tileLoadedEvent : { + get : function() { + return this._tileLoadedEvent; + } + }, + + /** + * Gets an event that is raised when an imagery layer is added, shown, hidden, moved, or removed. + * @memberof GlobeSurfaceTileProvider.prototype + * @type {Event} + */ + imageryLayersUpdatedEvent : { + get : function() { + return this._imageryLayersUpdatedEvent; + } + }, + /** * Gets or sets the terrain provider that describes the surface geometry. * @memberof GlobeSurfaceTileProvider.prototype @@ -194336,6 +207792,14 @@ define('Scene/GlobeSurfaceTileProvider',[ return aImagery.imageryLayer._layerIndex - bImagery.imageryLayer._layerIndex; } + /** + * Make updates to the tile provider that are not involved in rendering. Called before the render update cycle. + */ + GlobeSurfaceTileProvider.prototype.update = function(frameState) { + // update collection: imagery indices, base layers, raise layer show/hide event + this._imageryLayers._update(); + }; + function freeVertexArray(vertexArray) { var indexBuffer = vertexArray.indexBuffer; vertexArray.destroy(); @@ -194348,17 +207812,28 @@ define('Scene/GlobeSurfaceTileProvider',[ } } + function updateCredits(surface, frameState) { + var creditDisplay = frameState.creditDisplay; + if (surface._terrainProvider.ready && defined(surface._terrainProvider.credit)) { + creditDisplay.addCredit(surface._terrainProvider.credit); + } + + var imageryLayers = surface._imageryLayers; + for (var i = 0, len = imageryLayers.length; i < len; ++i) { + var imageryProvider = imageryLayers.get(i).imageryProvider; + if (imageryProvider.ready && defined(imageryProvider.credit)) { + creditDisplay.addCredit(imageryProvider.credit); + } + } + } + /** * Called at the beginning of each render frame, before {@link QuadtreeTileProvider#showTileThisFrame} * @param {FrameState} frameState The frame state. */ GlobeSurfaceTileProvider.prototype.initialize = function(frameState) { - var imageryLayers = this._imageryLayers; - - // update collection: imagery indices, base layers, raise layer show/hide event - imageryLayers._update(); // update each layer for texture reprojection. - imageryLayers.queueReprojectionCommands(frameState); + this._imageryLayers.queueReprojectionCommands(frameState); if (this._layerOrderChanged) { this._layerOrderChanged = false; @@ -194370,18 +207845,7 @@ define('Scene/GlobeSurfaceTileProvider',[ } // Add credits for terrain and imagery providers. - var creditDisplay = frameState.creditDisplay; - - if (this._terrainProvider.ready && defined(this._terrainProvider.credit)) { - creditDisplay.addCredit(this._terrainProvider.credit); - } - - for (var i = 0, len = imageryLayers.length; i < len; ++i) { - var imageryProvider = imageryLayers.get(i).imageryProvider; - if (imageryProvider.ready && defined(imageryProvider.credit)) { - creditDisplay.addCredit(imageryProvider.credit); - } - } + updateCredits(this, frameState); var vertexArraysToDestroy = this._vertexArraysToDestroy; var length = vertexArraysToDestroy.length; @@ -194512,6 +207976,11 @@ define('Scene/GlobeSurfaceTileProvider',[ */ GlobeSurfaceTileProvider.prototype.loadTile = function(frameState, tile) { GlobeSurfaceTile.processStateMachine(tile, frameState, this._terrainProvider, this._imageryLayers, this._vertexArraysToDestroy); + var tileLoadedEvent = this._tileLoadedEvent; + tile._loadedCallbacks['tileLoadedEvent'] = function (tile) { + tileLoadedEvent.raiseEvent(); + return true; + }; }; var boundingSphereScratch = new BoundingSphere(); @@ -194717,12 +208186,14 @@ define('Scene/GlobeSurfaceTileProvider',[ var that = this; var imageryProvider = layer.imageryProvider; + var tileImageryUpdatedEvent = this._imageryLayersUpdatedEvent; imageryProvider._reload = function() { // Clear the layer's cache layer._imageryCache = {}; that._quadtree.forEachLoadedTile(function(tile) { - if (tile.state !== QuadtreeTileLoadState.DONE) { + // If this layer is still waiting to for the loaded callback, just return + if (defined(tile._loadedCallbacks[layer._layerIndex])) { return; } @@ -194758,7 +208229,7 @@ define('Scene/GlobeSurfaceTileProvider',[ // Create new TileImageries for all loaded tiles if (layer._createTileImagerySkeletons(tile, terrainProvider, insertionPoint)) { // Add callback to remove old TileImageries when the new TileImageries are ready - tile._loadedCallbacks.push(getTileReadyCallback(tileImageriesToFree, layer, terrainProvider)); + tile._loadedCallbacks[layer._layerIndex] = getTileReadyCallback(tileImageriesToFree, layer, terrainProvider); tile.state = QuadtreeTileLoadState.LOADING; } @@ -194773,6 +208244,7 @@ define('Scene/GlobeSurfaceTileProvider',[ }); this._layerOrderChanged = true; + tileImageryUpdatedEvent.raiseEvent(); } }; @@ -194810,10 +208282,13 @@ define('Scene/GlobeSurfaceTileProvider',[ if (defined(layer.imageryProvider)) { layer.imageryProvider._reload = undefined; } + + this._imageryLayersUpdatedEvent.raiseEvent(); }; GlobeSurfaceTileProvider.prototype._onLayerMoved = function(layer, newIndex, oldIndex) { this._layerOrderChanged = true; + this._imageryLayersUpdatedEvent.raiseEvent(); }; GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden = function(layer, index, show) { @@ -194947,3121 +208422,2019 @@ define('Scene/GlobeSurfaceTileProvider',[ dayTextureAlpha : [], dayTextureBrightness : [], dayTextureContrast : [], - dayTextureHue : [], - dayTextureSaturation : [], - dayTextureOneOverGamma : [], - dayTextureSplit : [], - dayIntensity : 0.0, - - southAndNorthLatitude : new Cartesian2(), - southMercatorYAndOneOverHeight : new Cartesian2(), - - waterMask : undefined, - waterMaskTranslationAndScale : new Cartesian4(), - - minMaxHeight : new Cartesian2(), - scaleAndBias : new Matrix4(), - clippingPlanes : [], - clippingPlanesEdgeColor : Color.clone(Color.WHITE), - clippingPlanesEdgeWidth : 0.0 - } - }; - - return uniformMap; - } - - function createWireframeVertexArrayIfNecessary(context, provider, tile) { - var surfaceTile = tile.data; - - if (defined(surfaceTile.wireframeVertexArray)) { - return; - } - - if (!defined(surfaceTile.terrainData) || !defined(surfaceTile.terrainData._mesh)) { - return; - } - - surfaceTile.wireframeVertexArray = createWireframeVertexArray(context, surfaceTile.vertexArray, surfaceTile.terrainData._mesh); - } - - /** - * Creates a vertex array for wireframe rendering of a terrain tile. - * - * @private - * - * @param {Context} context The context in which to create the vertex array. - * @param {VertexArray} vertexArray The existing, non-wireframe vertex array. The new vertex array - * will share vertex buffers with this existing one. - * @param {TerrainMesh} terrainMesh The terrain mesh containing non-wireframe indices. - * @returns {VertexArray} The vertex array for wireframe rendering. - */ - function createWireframeVertexArray(context, vertexArray, terrainMesh) { - var geometry = { - indices : terrainMesh.indices, - primitiveType : PrimitiveType.TRIANGLES - }; - - GeometryPipeline.toWireframe(geometry); - - var wireframeIndices = geometry.indices; - var wireframeIndexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : wireframeIndices, - usage : BufferUsage.STATIC_DRAW, - indexDatatype : IndexDatatype.UNSIGNED_SHORT - }); - return new VertexArray({ - context : context, - attributes : vertexArray._attributes, - indexBuffer : wireframeIndexBuffer - }); - } - - var getDebugOrientedBoundingBox; - var getDebugBoundingSphere; - var debugDestroyPrimitive; - - (function() { - var instanceOBB = new GeometryInstance({ - geometry : BoxOutlineGeometry.fromDimensions({dimensions : new Cartesian3(2.0, 2.0, 2.0)}) - }); - var instanceSphere = new GeometryInstance({ - geometry : new SphereOutlineGeometry({radius : 1.0}) - }); - var modelMatrix = new Matrix4(); - var previousVolume; - var primitive; - - function createDebugPrimitive(instance) { - return new Primitive({ - geometryInstances : instance, - appearance : new PerInstanceColorAppearance({ - translucent : false, - flat : true - }), - asynchronous : false - }); - } - - getDebugOrientedBoundingBox = function(obb, color) { - if (obb === previousVolume) { - return primitive; - } - debugDestroyPrimitive(); - - previousVolume = obb; - modelMatrix = Matrix4.fromRotationTranslation(obb.halfAxes, obb.center, modelMatrix); - - instanceOBB.modelMatrix = modelMatrix; - instanceOBB.attributes.color = ColorGeometryInstanceAttribute.fromColor(color); - - primitive = createDebugPrimitive(instanceOBB); - return primitive; - }; - - getDebugBoundingSphere = function(sphere, color) { - if (sphere === previousVolume) { - return primitive; - } - debugDestroyPrimitive(); - - previousVolume = sphere; - modelMatrix = Matrix4.fromTranslation(sphere.center, modelMatrix); - modelMatrix = Matrix4.multiplyByUniformScale(modelMatrix, sphere.radius, modelMatrix); - - instanceSphere.modelMatrix = modelMatrix; - instanceSphere.attributes.color = ColorGeometryInstanceAttribute.fromColor(color); - - primitive = createDebugPrimitive(instanceSphere); - return primitive; - }; - - debugDestroyPrimitive = function() { - if (defined(primitive)) { - primitive.destroy(); - primitive = undefined; - previousVolume = undefined; - } - }; - })(); - - var otherPassesInitialColor = new Cartesian4(0.0, 0.0, 0.0, 0.0); - - function addDrawCommandsForTile(tileProvider, tile, frameState) { - var surfaceTile = tile.data; - var creditDisplay = frameState.creditDisplay; - - var terrainData = surfaceTile.terrainData; - if (defined(terrainData) && defined(terrainData.credits)) { - var tileCredits = terrainData.credits; - for (var tileCreditIndex = 0, - tileCreditLength = tileCredits.length; tileCreditIndex < tileCreditLength; ++tileCreditIndex) { - creditDisplay.addCredit(tileCredits[tileCreditIndex]); - } - } - - var maxTextures = ContextLimits.maximumTextureImageUnits; - - var waterMaskTexture = surfaceTile.waterMaskTexture; - var showReflectiveOcean = tileProvider.hasWaterMask && defined(waterMaskTexture); - var oceanNormalMap = tileProvider.oceanNormalMap; - var showOceanWaves = showReflectiveOcean && defined(oceanNormalMap); - var hasVertexNormals = tileProvider.terrainProvider.ready && tileProvider.terrainProvider.hasVertexNormals; - var enableFog = frameState.fog.enabled; - var castShadows = ShadowMode.castShadows(tileProvider.shadows); - var receiveShadows = ShadowMode.receiveShadows(tileProvider.shadows); - - if (showReflectiveOcean) { - --maxTextures; - } - if (showOceanWaves) { - --maxTextures; - } - - var rtc = surfaceTile.center; - var encoding = surfaceTile.pickTerrain.mesh.encoding; - - // Not used in 3D. - var tileRectangle = tileRectangleScratch; - - // Only used for Mercator projections. - var southLatitude = 0.0; - var northLatitude = 0.0; - var southMercatorY = 0.0; - var oneOverMercatorHeight = 0.0; - - var useWebMercatorProjection = false; - - if (frameState.mode !== SceneMode.SCENE3D) { - var projection = frameState.mapProjection; - var southwest = projection.project(Rectangle.southwest(tile.rectangle), southwestScratch); - var northeast = projection.project(Rectangle.northeast(tile.rectangle), northeastScratch); - - tileRectangle.x = southwest.x; - tileRectangle.y = southwest.y; - tileRectangle.z = northeast.x; - tileRectangle.w = northeast.y; - - // In 2D and Columbus View, use the center of the tile for RTC rendering. - if (frameState.mode !== SceneMode.MORPHING) { - rtc = rtcScratch; - rtc.x = 0.0; - rtc.y = (tileRectangle.z + tileRectangle.x) * 0.5; - rtc.z = (tileRectangle.w + tileRectangle.y) * 0.5; - tileRectangle.x -= rtc.y; - tileRectangle.y -= rtc.z; - tileRectangle.z -= rtc.y; - tileRectangle.w -= rtc.z; - } - - if (frameState.mode === SceneMode.SCENE2D && encoding.quantization === TerrainQuantization.BITS12) { - // In 2D, the texture coordinates of the tile are interpolated over the rectangle to get the position in the vertex shader. - // When the texture coordinates are quantized, error is introduced. This can be seen through the 1px wide cracking - // between the quantized tiles in 2D. To compensate for the error, move the expand the rectangle in each direction by - // half the error amount. - var epsilon = (1.0 / (Math.pow(2.0, 12.0) - 1.0)) * 0.5; - var widthEpsilon = (tileRectangle.z - tileRectangle.x) * epsilon; - var heightEpsilon = (tileRectangle.w - tileRectangle.y) * epsilon; - tileRectangle.x -= widthEpsilon; - tileRectangle.y -= heightEpsilon; - tileRectangle.z += widthEpsilon; - tileRectangle.w += heightEpsilon; - } - - if (projection instanceof WebMercatorProjection) { - southLatitude = tile.rectangle.south; - northLatitude = tile.rectangle.north; - - southMercatorY = WebMercatorProjection.geodeticLatitudeToMercatorAngle(southLatitude); - - oneOverMercatorHeight = 1.0 / (WebMercatorProjection.geodeticLatitudeToMercatorAngle(northLatitude) - southMercatorY); - - useWebMercatorProjection = true; - } - } - - var tileImageryCollection = surfaceTile.imagery; - var imageryIndex = 0; - var imageryLen = tileImageryCollection.length; - - var firstPassRenderState = tileProvider._renderState; - var otherPassesRenderState = tileProvider._blendRenderState; - var renderState = firstPassRenderState; - - var initialColor = tileProvider._firstPassInitialColor; - - var context = frameState.context; - - if (!defined(tileProvider._debug.boundingSphereTile)) { - debugDestroyPrimitive(); - } - - do { - var numberOfDayTextures = 0; - - var command; - var uniformMap; - - if (tileProvider._drawCommands.length <= tileProvider._usedDrawCommands) { - command = new DrawCommand(); - command.owner = tile; - command.cull = false; - command.boundingVolume = new BoundingSphere(); - command.orientedBoundingBox = undefined; - - uniformMap = createTileUniformMap(frameState); - - tileProvider._drawCommands.push(command); - tileProvider._uniformMaps.push(uniformMap); - } else { - command = tileProvider._drawCommands[tileProvider._usedDrawCommands]; - uniformMap = tileProvider._uniformMaps[tileProvider._usedDrawCommands]; - } - - command.owner = tile; - - ++tileProvider._usedDrawCommands; - - if (tile === tileProvider._debug.boundingSphereTile) { - // If a debug primitive already exists for this tile, it will not be - // re-created, to avoid allocation every frame. If it were possible - // to have more than one selected tile, this would have to change. - if (defined(surfaceTile.orientedBoundingBox)) { - getDebugOrientedBoundingBox(surfaceTile.orientedBoundingBox, Color.RED).update(frameState); - } else if (defined(surfaceTile.boundingSphere3D)) { - getDebugBoundingSphere(surfaceTile.boundingSphere3D, Color.RED).update(frameState); - } - } - - var uniformMapProperties = uniformMap.properties; - Cartesian4.clone(initialColor, uniformMapProperties.initialColor); - uniformMapProperties.oceanNormalMap = oceanNormalMap; - uniformMapProperties.lightingFadeDistance.x = tileProvider.lightingFadeOutDistance; - uniformMapProperties.lightingFadeDistance.y = tileProvider.lightingFadeInDistance; - uniformMapProperties.zoomedOutOceanSpecularIntensity = tileProvider.zoomedOutOceanSpecularIntensity; - - uniformMapProperties.center3D = surfaceTile.center; - Cartesian3.clone(rtc, uniformMapProperties.rtc); - - Cartesian4.clone(tileRectangle, uniformMapProperties.tileRectangle); - uniformMapProperties.southAndNorthLatitude.x = southLatitude; - uniformMapProperties.southAndNorthLatitude.y = northLatitude; - uniformMapProperties.southMercatorYAndOneOverHeight.x = southMercatorY; - uniformMapProperties.southMercatorYAndOneOverHeight.y = oneOverMercatorHeight; - - // For performance, use fog in the shader only when the tile is in fog. - var applyFog = enableFog && CesiumMath.fog(tile._distance, frameState.fog.density) > CesiumMath.EPSILON3; - - var applyBrightness = false; - var applyContrast = false; - var applyHue = false; - var applySaturation = false; - var applyGamma = false; - var applyAlpha = false; - var applySplit = false; - - while (numberOfDayTextures < maxTextures && imageryIndex < imageryLen) { - var tileImagery = tileImageryCollection[imageryIndex]; - var imagery = tileImagery.readyImagery; - ++imageryIndex; - - if (!defined(imagery) || imagery.imageryLayer.alpha === 0.0) { - continue; - } - - var texture = tileImagery.useWebMercatorT ? imagery.textureWebMercator : imagery.texture; - - if (!defined(texture)) { - // Our "ready" texture isn't actually ready. This should never happen. - // - // Side note: It IS possible for it to not be in the READY ImageryState, though. - // This can happen when a single imagery tile is shared by two terrain tiles (common) - // and one of them (A) needs a geographic version of the tile because it is near the poles, - // and the other (B) does not. B can and will transition the imagery tile to the READY state - // without reprojecting to geographic. Then, later, A will deem that same tile not-ready-yet - // because it only has the Web Mercator texture, and flip it back to the TRANSITIONING state. - // The imagery tile won't be in the READY state anymore, but it's still READY enough for B's - // purposes. - throw new DeveloperError('readyImagery is not actually ready!'); - } - - var imageryLayer = imagery.imageryLayer; - - if (!defined(tileImagery.textureTranslationAndScale)) { - tileImagery.textureTranslationAndScale = imageryLayer._calculateTextureTranslationAndScale(tile, tileImagery); - } - - uniformMapProperties.dayTextures[numberOfDayTextures] = texture; - uniformMapProperties.dayTextureTranslationAndScale[numberOfDayTextures] = tileImagery.textureTranslationAndScale; - uniformMapProperties.dayTextureTexCoordsRectangle[numberOfDayTextures] = tileImagery.textureCoordinateRectangle; - uniformMapProperties.dayTextureUseWebMercatorT[numberOfDayTextures] = tileImagery.useWebMercatorT; - - uniformMapProperties.dayTextureAlpha[numberOfDayTextures] = imageryLayer.alpha; - applyAlpha = applyAlpha || uniformMapProperties.dayTextureAlpha[numberOfDayTextures] !== 1.0; - - uniformMapProperties.dayTextureBrightness[numberOfDayTextures] = imageryLayer.brightness; - applyBrightness = applyBrightness || uniformMapProperties.dayTextureBrightness[numberOfDayTextures] !== ImageryLayer.DEFAULT_BRIGHTNESS; - - uniformMapProperties.dayTextureContrast[numberOfDayTextures] = imageryLayer.contrast; - applyContrast = applyContrast || uniformMapProperties.dayTextureContrast[numberOfDayTextures] !== ImageryLayer.DEFAULT_CONTRAST; - - uniformMapProperties.dayTextureHue[numberOfDayTextures] = imageryLayer.hue; - applyHue = applyHue || uniformMapProperties.dayTextureHue[numberOfDayTextures] !== ImageryLayer.DEFAULT_HUE; - - uniformMapProperties.dayTextureSaturation[numberOfDayTextures] = imageryLayer.saturation; - applySaturation = applySaturation || uniformMapProperties.dayTextureSaturation[numberOfDayTextures] !== ImageryLayer.DEFAULT_SATURATION; - - uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] = 1.0 / imageryLayer.gamma; - applyGamma = applyGamma || uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] !== 1.0 / ImageryLayer.DEFAULT_GAMMA; - - uniformMapProperties.dayTextureSplit[numberOfDayTextures] = imageryLayer.splitDirection; - applySplit = applySplit || uniformMapProperties.dayTextureSplit[numberOfDayTextures] !== 0.0; - - if (defined(imagery.credits)) { - var credits = imagery.credits; - for (var creditIndex = 0, creditLength = credits.length; creditIndex < creditLength; ++creditIndex) { - creditDisplay.addCredit(credits[creditIndex]); - } - } - - ++numberOfDayTextures; - } - - // trim texture array to the used length so we don't end up using old textures - // which might get destroyed eventually - uniformMapProperties.dayTextures.length = numberOfDayTextures; - uniformMapProperties.waterMask = waterMaskTexture; - Cartesian4.clone(surfaceTile.waterMaskTranslationAndScale, uniformMapProperties.waterMaskTranslationAndScale); - - uniformMapProperties.minMaxHeight.x = encoding.minimumHeight; - uniformMapProperties.minMaxHeight.y = encoding.maximumHeight; - Matrix4.clone(encoding.matrix, uniformMapProperties.scaleAndBias); - - // update clipping planes - var clippingPlanes = tileProvider.clippingPlanes; - var length = 0; - - if (defined(clippingPlanes) && tile.isClipped) { - length = clippingPlanes.length; - } - - var packedPlanes = uniformMapProperties.clippingPlanes; - var packedLength = packedPlanes.length; - if (packedLength !== length) { - packedPlanes.length = length; - - for (var i = packedLength; i < length; ++i) { - packedPlanes[i] = new Cartesian4(); - } - } - - if (defined(clippingPlanes) && clippingPlanes.enabled && tile.isClipped) { - clippingPlanes.transformAndPackPlanes(context.uniformState.view, packedPlanes); - uniformMapProperties.clippingPlanesEdgeColor = Color.clone(clippingPlanes.edgeColor, uniformMapProperties.clippingPlanesEdgeColor); - uniformMapProperties.clippingPlanesEdgeWidth = clippingPlanes.edgeWidth; - } - - var clippingPlanesEnabled = defined(clippingPlanes) && clippingPlanes.enabled && (uniformMapProperties.clippingPlanes.length > 0) && !FeatureDetection.isInternetExplorer(); - var unionClippingRegions = clippingPlanesEnabled ? clippingPlanes.unionClippingRegions : false; - - if (defined(tileProvider.uniformMap)) { - uniformMap = combine(uniformMap, tileProvider.uniformMap); - } - - command.shaderProgram = tileProvider._surfaceShaderSet.getShaderProgram(frameState, surfaceTile, numberOfDayTextures, applyBrightness, applyContrast, applyHue, applySaturation, applyGamma, applyAlpha, applySplit, showReflectiveOcean, showOceanWaves, tileProvider.enableLighting, hasVertexNormals, useWebMercatorProjection, applyFog, clippingPlanesEnabled, unionClippingRegions); - command.castShadows = castShadows; - command.receiveShadows = receiveShadows; - command.renderState = renderState; - command.primitiveType = PrimitiveType.TRIANGLES; - command.vertexArray = surfaceTile.vertexArray; - command.uniformMap = uniformMap; - command.pass = Pass.GLOBE; - - if (tileProvider._debug.wireframe) { - createWireframeVertexArrayIfNecessary(context, tileProvider, tile); - if (defined(surfaceTile.wireframeVertexArray)) { - command.vertexArray = surfaceTile.wireframeVertexArray; - command.primitiveType = PrimitiveType.LINES; - } - } - - var boundingVolume = command.boundingVolume; - var orientedBoundingBox = command.orientedBoundingBox; - - if (frameState.mode !== SceneMode.SCENE3D) { - BoundingSphere.fromRectangleWithHeights2D(tile.rectangle, frameState.mapProjection, surfaceTile.minimumHeight, surfaceTile.maximumHeight, boundingVolume); - Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); - - if (frameState.mode === SceneMode.MORPHING) { - boundingVolume = BoundingSphere.union(surfaceTile.boundingSphere3D, boundingVolume, boundingVolume); - } - } else { - command.boundingVolume = BoundingSphere.clone(surfaceTile.boundingSphere3D, boundingVolume); - command.orientedBoundingBox = OrientedBoundingBox.clone(surfaceTile.orientedBoundingBox, orientedBoundingBox); - } - - frameState.commandList.push(command); - - renderState = otherPassesRenderState; - initialColor = otherPassesInitialColor; - } while (imageryIndex < imageryLen); - } - - function addPickCommandsForTile(tileProvider, drawCommand, frameState) { - var pickCommand; - if (tileProvider._pickCommands.length <= tileProvider._usedPickCommands) { - pickCommand = new DrawCommand(); - pickCommand.cull = false; - - tileProvider._pickCommands.push(pickCommand); - } else { - pickCommand = tileProvider._pickCommands[tileProvider._usedPickCommands]; - } - - ++tileProvider._usedPickCommands; - - var surfaceTile = drawCommand.owner.data; - var useWebMercatorProjection = frameState.projection instanceof WebMercatorProjection; - - pickCommand.shaderProgram = tileProvider._surfaceShaderSet.getPickShaderProgram(frameState, surfaceTile, useWebMercatorProjection); - pickCommand.renderState = tileProvider._pickRenderState; - - pickCommand.owner = drawCommand.owner; - pickCommand.primitiveType = drawCommand.primitiveType; - pickCommand.vertexArray = drawCommand.vertexArray; - pickCommand.uniformMap = drawCommand.uniformMap; - pickCommand.boundingVolume = drawCommand.boundingVolume; - pickCommand.orientedBoundingBox = drawCommand.orientedBoundingBox; - pickCommand.pass = drawCommand.pass; - - frameState.commandList.push(pickCommand); - } - - return GlobeSurfaceTileProvider; -}); - -define('Scene/ImageryLayerCollection',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Event', - '../Core/Math', - '../Core/Rectangle', - '../ThirdParty/when', - './ImageryLayer' - ], function( - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - Event, - CesiumMath, - Rectangle, - when, - ImageryLayer) { - 'use strict'; - - /** - * An ordered collection of imagery layers. - * - * @alias ImageryLayerCollection - * @constructor - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Adjustment.html|Cesium Sandcastle Imagery Adjustment Demo} - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Layers%20Manipulation.html|Cesium Sandcastle Imagery Manipulation Demo} - */ - function ImageryLayerCollection() { - this._layers = []; - - /** - * An event that is raised when a layer is added to the collection. Event handlers are passed the layer that - * was added and the index at which it was added. - * @type {Event} - * @default Event() - */ - this.layerAdded = new Event(); - - /** - * An event that is raised when a layer is removed from the collection. Event handlers are passed the layer that - * was removed and the index from which it was removed. - * @type {Event} - * @default Event() - */ - this.layerRemoved = new Event(); - - /** - * An event that is raised when a layer changes position in the collection. Event handlers are passed the layer that - * was moved, its new index after the move, and its old index prior to the move. - * @type {Event} - * @default Event() - */ - this.layerMoved = new Event(); - - /** - * An event that is raised when a layer is shown or hidden by setting the - * {@link ImageryLayer#show} property. Event handlers are passed a reference to this layer, - * the index of the layer in the collection, and a flag that is true if the layer is now - * shown or false if it is now hidden. - * - * @type {Event} - * @default Event() - */ - this.layerShownOrHidden = new Event(); - } - - defineProperties(ImageryLayerCollection.prototype, { - /** - * Gets the number of layers in this collection. - * @memberof ImageryLayerCollection.prototype - * @type {Number} - */ - length : { - get : function() { - return this._layers.length; - } - } - }); - - /** - * Adds a layer to the collection. - * - * @param {ImageryLayer} layer the layer to add. - * @param {Number} [index] the index to add the layer at. If omitted, the layer will - * added on top of all existing layers. - * - * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of the layers. - */ - ImageryLayerCollection.prototype.add = function(layer, index) { - var hasIndex = defined(index); - - if (!defined(layer)) { - throw new DeveloperError('layer is required.'); - } - if (hasIndex) { - if (index < 0) { - throw new DeveloperError('index must be greater than or equal to zero.'); - } else if (index > this._layers.length) { - throw new DeveloperError('index must be less than or equal to the number of layers.'); - } - } - - if (!hasIndex) { - index = this._layers.length; - this._layers.push(layer); - } else { - this._layers.splice(index, 0, layer); - } - - this._update(); - this.layerAdded.raiseEvent(layer, index); - }; - - /** - * Creates a new layer using the given ImageryProvider and adds it to the collection. - * - * @param {ImageryProvider} imageryProvider the imagery provider to create a new layer for. - * @param {Number} [index] the index to add the layer at. If omitted, the layer will - * added on top of all existing layers. - * @returns {ImageryLayer} The newly created layer. - */ - ImageryLayerCollection.prototype.addImageryProvider = function(imageryProvider, index) { - if (!defined(imageryProvider)) { - throw new DeveloperError('imageryProvider is required.'); - } - - var layer = new ImageryLayer(imageryProvider); - this.add(layer, index); - return layer; - }; - - /** - * Removes a layer from this collection, if present. - * - * @param {ImageryLayer} layer The layer to remove. - * @param {Boolean} [destroy=true] whether to destroy the layers in addition to removing them. - * @returns {Boolean} true if the layer was in the collection and was removed, - * false if the layer was not in the collection. - */ - ImageryLayerCollection.prototype.remove = function(layer, destroy) { - destroy = defaultValue(destroy, true); - - var index = this._layers.indexOf(layer); - if (index !== -1) { - this._layers.splice(index, 1); - - this._update(); - - this.layerRemoved.raiseEvent(layer, index); - - if (destroy) { - layer.destroy(); - } - - return true; - } - - return false; - }; - - /** - * Removes all layers from this collection. - * - * @param {Boolean} [destroy=true] whether to destroy the layers in addition to removing them. - */ - ImageryLayerCollection.prototype.removeAll = function(destroy) { - destroy = defaultValue(destroy, true); - - var layers = this._layers; - for (var i = 0, len = layers.length; i < len; i++) { - var layer = layers[i]; - this.layerRemoved.raiseEvent(layer, i); - - if (destroy) { - layer.destroy(); - } - } - - this._layers = []; - }; - - /** - * Checks to see if the collection contains a given layer. - * - * @param {ImageryLayer} layer the layer to check for. - * - * @returns {Boolean} true if the collection contains the layer, false otherwise. - */ - ImageryLayerCollection.prototype.contains = function(layer) { - return this.indexOf(layer) !== -1; - }; - - /** - * Determines the index of a given layer in the collection. - * - * @param {ImageryLayer} layer The layer to find the index of. - * - * @returns {Number} The index of the layer in the collection, or -1 if the layer does not exist in the collection. - */ - ImageryLayerCollection.prototype.indexOf = function(layer) { - return this._layers.indexOf(layer); - }; - - /** - * Gets a layer by index from the collection. - * - * @param {Number} index the index to retrieve. - * - * @returns {ImageryLayer} The imagery layer at the given index. - */ - ImageryLayerCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.', 'index'); - } - - return this._layers[index]; - }; - - function getLayerIndex(layers, layer) { - if (!defined(layer)) { - throw new DeveloperError('layer is required.'); - } - - var index = layers.indexOf(layer); - - if (index === -1) { - throw new DeveloperError('layer is not in this collection.'); - } - - return index; - } - - function swapLayers(collection, i, j) { - var arr = collection._layers; - i = CesiumMath.clamp(i, 0, arr.length - 1); - j = CesiumMath.clamp(j, 0, arr.length - 1); - - if (i === j) { - return; - } - - var temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - - collection._update(); - - collection.layerMoved.raiseEvent(temp, j, i); - } - - /** - * Raises a layer up one position in the collection. - * - * @param {ImageryLayer} layer the layer to move. - * - * @exception {DeveloperError} layer is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - ImageryLayerCollection.prototype.raise = function(layer) { - var index = getLayerIndex(this._layers, layer); - swapLayers(this, index, index + 1); - }; - - /** - * Lowers a layer down one position in the collection. - * - * @param {ImageryLayer} layer the layer to move. - * - * @exception {DeveloperError} layer is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - ImageryLayerCollection.prototype.lower = function(layer) { - var index = getLayerIndex(this._layers, layer); - swapLayers(this, index, index - 1); - }; - - /** - * Raises a layer to the top of the collection. - * - * @param {ImageryLayer} layer the layer to move. - * - * @exception {DeveloperError} layer is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - ImageryLayerCollection.prototype.raiseToTop = function(layer) { - var index = getLayerIndex(this._layers, layer); - if (index === this._layers.length - 1) { - return; - } - this._layers.splice(index, 1); - this._layers.push(layer); - - this._update(); - - this.layerMoved.raiseEvent(layer, this._layers.length - 1, index); - }; - - /** - * Lowers a layer to the bottom of the collection. - * - * @param {ImageryLayer} layer the layer to move. - * - * @exception {DeveloperError} layer is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - */ - ImageryLayerCollection.prototype.lowerToBottom = function(layer) { - var index = getLayerIndex(this._layers, layer); - if (index === 0) { - return; - } - this._layers.splice(index, 1); - this._layers.splice(0, 0, layer); - - this._update(); - - this.layerMoved.raiseEvent(layer, 0, index); - }; - - var applicableRectangleScratch = new Rectangle(); - - /** - * Asynchronously determines the imagery layer features that are intersected by a pick ray. The intersected imagery - * layer features are found by invoking {@link ImageryProvider#pickFeatures} for each imagery layer tile intersected - * by the pick ray. To compute a pick ray from a location on the screen, use {@link Camera.getPickRay}. - * - * @param {Ray} ray The ray to test for intersection. - * @param {Scene} scene The scene. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise that resolves to an array of features intersected by the pick ray. - * If it can be quickly determined that no features are intersected (for example, - * because no active imagery providers support {@link ImageryProvider#pickFeatures} - * or because the pick ray does not intersect the surface), this function will - * return undefined. - * - * @example - * var pickRay = viewer.camera.getPickRay(windowPosition); - * var featuresPromise = viewer.imageryLayers.pickImageryLayerFeatures(pickRay, viewer.scene); - * if (!Cesium.defined(featuresPromise)) { - * console.log('No features picked.'); - * } else { - * Cesium.when(featuresPromise, function(features) { - * // This function is called asynchronously when the list if picked features is available. - * console.log('Number of features: ' + features.length); - * if (features.length > 0) { - * console.log('First feature name: ' + features[0].name); - * } - * }); - * } - */ - ImageryLayerCollection.prototype.pickImageryLayerFeatures = function(ray, scene) { - // Find the picked location on the globe. - var pickedPosition = scene.globe.pick(ray, scene); - if (!defined(pickedPosition)) { - return undefined; - } - - var pickedLocation = scene.globe.ellipsoid.cartesianToCartographic(pickedPosition); - - // Find the terrain tile containing the picked location. - var tilesToRender = scene.globe._surface._tilesToRender; - var pickedTile; - - for (var textureIndex = 0; !defined(pickedTile) && textureIndex < tilesToRender.length; ++textureIndex) { - var tile = tilesToRender[textureIndex]; - if (Rectangle.contains(tile.rectangle, pickedLocation)) { - pickedTile = tile; - } - } - - if (!defined(pickedTile)) { - return undefined; - } - - // Pick against all attached imagery tiles containing the pickedLocation. - var imageryTiles = pickedTile.data.imagery; - - var promises = []; - var imageryLayers = []; - for (var i = imageryTiles.length - 1; i >= 0; --i) { - var terrainImagery = imageryTiles[i]; - var imagery = terrainImagery.readyImagery; - if (!defined(imagery)) { - continue; - } - var provider = imagery.imageryLayer.imageryProvider; - if (!defined(provider.pickFeatures)) { - continue; - } - - if (!Rectangle.contains(imagery.rectangle, pickedLocation)) { - continue; - } - - // If this imagery came from a parent, it may not be applicable to its entire rectangle. - // Check the textureCoordinateRectangle. - var applicableRectangle = applicableRectangleScratch; - - var epsilon = 1 / 1024; // 1/4 of a pixel in a typical 256x256 tile. - applicableRectangle.west = CesiumMath.lerp(pickedTile.rectangle.west, pickedTile.rectangle.east, terrainImagery.textureCoordinateRectangle.x - epsilon); - applicableRectangle.east = CesiumMath.lerp(pickedTile.rectangle.west, pickedTile.rectangle.east, terrainImagery.textureCoordinateRectangle.z + epsilon); - applicableRectangle.south = CesiumMath.lerp(pickedTile.rectangle.south, pickedTile.rectangle.north, terrainImagery.textureCoordinateRectangle.y - epsilon); - applicableRectangle.north = CesiumMath.lerp(pickedTile.rectangle.south, pickedTile.rectangle.north, terrainImagery.textureCoordinateRectangle.w + epsilon); - if (!Rectangle.contains(applicableRectangle, pickedLocation)) { - continue; - } - - var promise = provider.pickFeatures(imagery.x, imagery.y, imagery.level, pickedLocation.longitude, pickedLocation.latitude); - if (!defined(promise)) { - continue; - } - - promises.push(promise); - imageryLayers.push(imagery.imageryLayer); - } - - if (promises.length === 0) { - return undefined; - } - - return when.all(promises, function(results) { - var features = []; - - for (var resultIndex = 0; resultIndex < results.length; ++resultIndex) { - var result = results[resultIndex]; - var image = imageryLayers[resultIndex]; - - if (defined(result) && result.length > 0) { - for (var featureIndex = 0; featureIndex < result.length; ++featureIndex) { - var feature = result[featureIndex]; - feature.imageryLayer = image; - - // For features without a position, use the picked location. - if (!defined(feature.position)) { - feature.position = pickedLocation; - } - - features.push(feature); - } - } - } - - return features; - }); - }; - - /** - * Updates frame state to execute any queued texture re-projections. - * - * @private - * - * @param {FrameState} frameState The frameState. - */ - ImageryLayerCollection.prototype.queueReprojectionCommands = function(frameState) { - var layers = this._layers; - for (var i = 0, len = layers.length; i < len; ++i) { - layers[i].queueReprojectionCommands(frameState); - } - }; - - /** - * Cancels re-projection commands queued for the next frame. - * - * @private - */ - ImageryLayerCollection.prototype.cancelReprojections = function() { - var layers = this._layers; - for (var i = 0, len = layers.length; i < len; ++i) { - layers[i].cancelReprojections(); - } - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} true if this object was destroyed; otherwise, false. - * - * @see ImageryLayerCollection#destroy - */ - ImageryLayerCollection.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys the WebGL resources held by all layers in this collection. Explicitly destroying this - * object allows for deterministic release of WebGL resources, instead of relying on the garbage - * collector. - * <br /><br /> - * Once this object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * layerCollection = layerCollection && layerCollection.destroy(); - * - * @see ImageryLayerCollection#isDestroyed - */ - ImageryLayerCollection.prototype.destroy = function() { - this.removeAll(true); - return destroyObject(this); - }; + dayTextureHue : [], + dayTextureSaturation : [], + dayTextureOneOverGamma : [], + dayTextureSplit : [], + dayIntensity : 0.0, - ImageryLayerCollection.prototype._update = function() { - var isBaseLayer = true; - var layers = this._layers; - var layersShownOrHidden; - var layer; - var i, len; - for (i = 0, len = layers.length; i < len; ++i) { - layer = layers[i]; + southAndNorthLatitude : new Cartesian2(), + southMercatorYAndOneOverHeight : new Cartesian2(), - layer._layerIndex = i; + waterMask : undefined, + waterMaskTranslationAndScale : new Cartesian4(), - if (layer.show) { - layer._isBaseLayer = isBaseLayer; - isBaseLayer = false; - } else { - layer._isBaseLayer = false; + minMaxHeight : new Cartesian2(), + scaleAndBias : new Matrix4(), + clippingPlanes : [], + clippingPlanesEdgeColor : Color.clone(Color.WHITE), + clippingPlanesEdgeWidth : 0.0 } + }; - if (layer.show !== layer._show) { - if (defined(layer._show)) { - if (!defined(layersShownOrHidden)) { - layersShownOrHidden = []; - } - layersShownOrHidden.push(layer); - } - layer._show = layer.show; - } - } + return uniformMap; + } - if (defined(layersShownOrHidden)) { - for (i = 0, len = layersShownOrHidden.length; i < len; ++i) { - layer = layersShownOrHidden[i]; - this.layerShownOrHidden.raiseEvent(layer, layer._layerIndex, layer.show); - } + function createWireframeVertexArrayIfNecessary(context, provider, tile) { + var surfaceTile = tile.data; + + if (defined(surfaceTile.wireframeVertexArray)) { + return; } - }; - return ImageryLayerCollection; -}); + if (!defined(surfaceTile.terrainData) || !defined(surfaceTile.terrainData._mesh)) { + return; + } -define('Scene/QuadtreeOccluders',[ - '../Core/Cartesian3', - '../Core/defineProperties', - '../Core/EllipsoidalOccluder' - ], function( - Cartesian3, - defineProperties, - EllipsoidalOccluder) { - 'use strict'; + surfaceTile.wireframeVertexArray = createWireframeVertexArray(context, surfaceTile.vertexArray, surfaceTile.terrainData._mesh); + } /** - * A set of occluders that can be used to test quadtree tiles for occlusion. + * Creates a vertex array for wireframe rendering of a terrain tile. * - * @alias QuadtreeOccluders - * @constructor * @private * - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid that potentially occludes tiles. + * @param {Context} context The context in which to create the vertex array. + * @param {VertexArray} vertexArray The existing, non-wireframe vertex array. The new vertex array + * will share vertex buffers with this existing one. + * @param {TerrainMesh} terrainMesh The terrain mesh containing non-wireframe indices. + * @returns {VertexArray} The vertex array for wireframe rendering. */ - function QuadtreeOccluders(options) { - this._ellipsoid = new EllipsoidalOccluder(options.ellipsoid, Cartesian3.ZERO); + function createWireframeVertexArray(context, vertexArray, terrainMesh) { + var geometry = { + indices : terrainMesh.indices, + primitiveType : PrimitiveType.TRIANGLES + }; + + GeometryPipeline.toWireframe(geometry); + + var wireframeIndices = geometry.indices; + var wireframeIndexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : wireframeIndices, + usage : BufferUsage.STATIC_DRAW, + indexDatatype : IndexDatatype.UNSIGNED_SHORT + }); + return new VertexArray({ + context : context, + attributes : vertexArray._attributes, + indexBuffer : wireframeIndexBuffer + }); } - defineProperties(QuadtreeOccluders.prototype, { - /** - * Gets the {@link EllipsoidalOccluder} that can be used to determine if a point is - * occluded by an {@link Ellipsoid}. - * @type {EllipsoidalOccluder} - * @memberof QuadtreeOccluders.prototype - */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } + var getDebugOrientedBoundingBox; + var getDebugBoundingSphere; + var debugDestroyPrimitive; + + (function() { + var instanceOBB = new GeometryInstance({ + geometry : BoxOutlineGeometry.fromDimensions({dimensions : new Cartesian3(2.0, 2.0, 2.0)}) + }); + var instanceSphere = new GeometryInstance({ + geometry : new SphereOutlineGeometry({radius : 1.0}) + }); + var modelMatrix = new Matrix4(); + var previousVolume; + var primitive; + + function createDebugPrimitive(instance) { + return new Primitive({ + geometryInstances : instance, + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false + }); } - }); - return QuadtreeOccluders; -}); + getDebugOrientedBoundingBox = function(obb, color) { + if (obb === previousVolume) { + return primitive; + } + debugDestroyPrimitive(); -define('Scene/QuadtreeTile',[ - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Rectangle', - './QuadtreeTileLoadState' - ], function( - defined, - defineProperties, - DeveloperError, - Rectangle, - QuadtreeTileLoadState) { - 'use strict'; + previousVolume = obb; + modelMatrix = Matrix4.fromRotationTranslation(obb.halfAxes, obb.center, modelMatrix); - /** - * A single tile in a {@link QuadtreePrimitive}. - * - * @alias QuadtreeTile - * @constructor - * @private - * - * @param {Number} options.level The level of the tile in the quadtree. - * @param {Number} options.x The X coordinate of the tile in the quadtree. 0 is the westernmost tile. - * @param {Number} options.y The Y coordinate of the tile in the quadtree. 0 is the northernmost tile. - * @param {TilingScheme} options.tilingScheme The tiling scheme in which this tile exists. - * @param {QuadtreeTile} [options.parent] This tile's parent, or undefined if this is a root tile. - */ - function QuadtreeTile(options) { - if (!defined(options)) { - throw new DeveloperError('options is required.'); - } - if (!defined(options.x)) { - throw new DeveloperError('options.x is required.'); - } else if (!defined(options.y)) { - throw new DeveloperError('options.y is required.'); - } else if (options.x < 0 || options.y < 0) { - throw new DeveloperError('options.x and options.y must be greater than or equal to zero.'); - } - if (!defined(options.level)) { - throw new DeveloperError('options.level is required and must be greater than or equal to zero.'); - } - if (!defined(options.tilingScheme)) { - throw new DeveloperError('options.tilingScheme is required.'); - } - - this._tilingScheme = options.tilingScheme; - this._x = options.x; - this._y = options.y; - this._level = options.level; - this._parent = options.parent; - this._rectangle = this._tilingScheme.tileXYToRectangle(this._x, this._y, this._level); + instanceOBB.modelMatrix = modelMatrix; + instanceOBB.attributes.color = ColorGeometryInstanceAttribute.fromColor(color); - this._southwestChild = undefined; - this._southeastChild = undefined; - this._northwestChild = undefined; - this._northeastChild = undefined; + primitive = createDebugPrimitive(instanceOBB); + return primitive; + }; - // QuadtreeTileReplacementQueue gets/sets these private properties. - this._replacementPrevious = undefined; - this._replacementNext = undefined; + getDebugBoundingSphere = function(sphere, color) { + if (sphere === previousVolume) { + return primitive; + } + debugDestroyPrimitive(); - // The distance from the camera to this tile, updated when the tile is selected - // for rendering. We can get rid of this if we have a better way to sort by - // distance - for example, by using the natural ordering of a quadtree. - // QuadtreePrimitive gets/sets this private property. - this._distance = 0.0; - this._priorityFunction = undefined; + previousVolume = sphere; + modelMatrix = Matrix4.fromTranslation(sphere.center, modelMatrix); + modelMatrix = Matrix4.multiplyByUniformScale(modelMatrix, sphere.radius, modelMatrix); - this._customData = []; - this._frameUpdated = undefined; - this._frameRendered = undefined; - this._loadedCallbacks = []; + instanceSphere.modelMatrix = modelMatrix; + instanceSphere.attributes.color = ColorGeometryInstanceAttribute.fromColor(color); - /** - * Gets or sets the current state of the tile in the tile load pipeline. - * @type {QuadtreeTileLoadState} - * @default {@link QuadtreeTileLoadState.START} - */ - this.state = QuadtreeTileLoadState.START; + primitive = createDebugPrimitive(instanceSphere); + return primitive; + }; - /** - * Gets or sets a value indicating whether or not the tile is currently renderable. - * @type {Boolean} - * @default false - */ - this.renderable = false; + debugDestroyPrimitive = function() { + if (defined(primitive)) { + primitive.destroy(); + primitive = undefined; + previousVolume = undefined; + } + }; + })(); - /** - * Gets or set a value indicating whether or not the tile was entire upsampled from its - * parent tile. If all four children of a parent tile were upsampled from the parent, - * we will render the parent instead of the children even if the LOD indicates that - * the children would be preferable. - * @type {Boolean} - * @default false - */ - this.upsampledFromParent = false; + var otherPassesInitialColor = new Cartesian4(0.0, 0.0, 0.0, 0.0); - /** - * Gets or sets the additional data associated with this tile. The exact content is specific to the - * {@link QuadtreeTileProvider}. - * @type {Object} - * @default undefined - */ - this.data = undefined; - } + function addDrawCommandsForTile(tileProvider, tile, frameState) { + var surfaceTile = tile.data; + var creditDisplay = frameState.creditDisplay; - /** - * Creates a rectangular set of tiles for level of detail zero, the coarsest, least detailed level. - * - * @memberof QuadtreeTile - * - * @param {TilingScheme} tilingScheme The tiling scheme for which the tiles are to be created. - * @returns {QuadtreeTile[]} An array containing the tiles at level of detail zero, starting with the - * tile in the northwest corner and followed by the tile (if any) to its east. - */ - QuadtreeTile.createLevelZeroTiles = function(tilingScheme) { - if (!defined(tilingScheme)) { - throw new DeveloperError('tilingScheme is required.'); + var terrainData = surfaceTile.terrainData; + if (defined(terrainData) && defined(terrainData.credits)) { + var tileCredits = terrainData.credits; + for (var tileCreditIndex = 0, + tileCreditLength = tileCredits.length; tileCreditIndex < tileCreditLength; ++tileCreditIndex) { + creditDisplay.addCredit(tileCredits[tileCreditIndex]); + } } - - var numberOfLevelZeroTilesX = tilingScheme.getNumberOfXTilesAtLevel(0); - var numberOfLevelZeroTilesY = tilingScheme.getNumberOfYTilesAtLevel(0); - var result = new Array(numberOfLevelZeroTilesX * numberOfLevelZeroTilesY); + var maxTextures = ContextLimits.maximumTextureImageUnits; - var index = 0; - for (var y = 0; y < numberOfLevelZeroTilesY; ++y) { - for (var x = 0; x < numberOfLevelZeroTilesX; ++x) { - result[index++] = new QuadtreeTile({ - tilingScheme : tilingScheme, - x : x, - y : y, - level : 0 - }); - } + var waterMaskTexture = surfaceTile.waterMaskTexture; + var showReflectiveOcean = tileProvider.hasWaterMask && defined(waterMaskTexture); + var oceanNormalMap = tileProvider.oceanNormalMap; + var showOceanWaves = showReflectiveOcean && defined(oceanNormalMap); + var hasVertexNormals = tileProvider.terrainProvider.ready && tileProvider.terrainProvider.hasVertexNormals; + var enableFog = frameState.fog.enabled; + var castShadows = ShadowMode.castShadows(tileProvider.shadows); + var receiveShadows = ShadowMode.receiveShadows(tileProvider.shadows); + + if (showReflectiveOcean) { + --maxTextures; + } + if (showOceanWaves) { + --maxTextures; } - return result; - }; + var rtc = surfaceTile.center; + var encoding = surfaceTile.pickTerrain.mesh.encoding; - QuadtreeTile.prototype._updateCustomData = function(frameNumber, added, removed) { - var customData = this.customData; + // Not used in 3D. + var tileRectangle = tileRectangleScratch; - var i; - var data; - var rectangle; + // Only used for Mercator projections. + var southLatitude = 0.0; + var northLatitude = 0.0; + var southMercatorY = 0.0; + var oneOverMercatorHeight = 0.0; - if (defined(added) && defined(removed)) { - customData = customData.filter(function(value) { - return removed.indexOf(value) === -1; - }); - this._customData = customData; + var useWebMercatorProjection = false; - rectangle = this._rectangle; - for (i = 0; i < added.length; ++i) { - data = added[i]; - if (Rectangle.contains(rectangle, data.positionCartographic)) { - customData.push(data); - } + if (frameState.mode !== SceneMode.SCENE3D) { + var projection = frameState.mapProjection; + var southwest = projection.project(Rectangle.southwest(tile.rectangle), southwestScratch); + var northeast = projection.project(Rectangle.northeast(tile.rectangle), northeastScratch); + + tileRectangle.x = southwest.x; + tileRectangle.y = southwest.y; + tileRectangle.z = northeast.x; + tileRectangle.w = northeast.y; + + // In 2D and Columbus View, use the center of the tile for RTC rendering. + if (frameState.mode !== SceneMode.MORPHING) { + rtc = rtcScratch; + rtc.x = 0.0; + rtc.y = (tileRectangle.z + tileRectangle.x) * 0.5; + rtc.z = (tileRectangle.w + tileRectangle.y) * 0.5; + tileRectangle.x -= rtc.y; + tileRectangle.y -= rtc.z; + tileRectangle.z -= rtc.y; + tileRectangle.w -= rtc.z; } - this._frameUpdated = frameNumber; - } else { - // interior or leaf tile, update from parent - var parent = this._parent; - if (defined(parent) && this._frameUpdated !== parent._frameUpdated) { - customData.length = 0; + if (frameState.mode === SceneMode.SCENE2D && encoding.quantization === TerrainQuantization.BITS12) { + // In 2D, the texture coordinates of the tile are interpolated over the rectangle to get the position in the vertex shader. + // When the texture coordinates are quantized, error is introduced. This can be seen through the 1px wide cracking + // between the quantized tiles in 2D. To compensate for the error, move the expand the rectangle in each direction by + // half the error amount. + var epsilon = (1.0 / (Math.pow(2.0, 12.0) - 1.0)) * 0.5; + var widthEpsilon = (tileRectangle.z - tileRectangle.x) * epsilon; + var heightEpsilon = (tileRectangle.w - tileRectangle.y) * epsilon; + tileRectangle.x -= widthEpsilon; + tileRectangle.y -= heightEpsilon; + tileRectangle.z += widthEpsilon; + tileRectangle.w += heightEpsilon; + } - rectangle = this._rectangle; - var parentCustomData = parent.customData; - for (i = 0; i < parentCustomData.length; ++i) { - data = parentCustomData[i]; - if (Rectangle.contains(rectangle, data.positionCartographic)) { - customData.push(data); - } - } + if (projection instanceof WebMercatorProjection) { + southLatitude = tile.rectangle.south; + northLatitude = tile.rectangle.north; - this._frameUpdated = parent._frameUpdated; + southMercatorY = WebMercatorProjection.geodeticLatitudeToMercatorAngle(southLatitude); + + oneOverMercatorHeight = 1.0 / (WebMercatorProjection.geodeticLatitudeToMercatorAngle(northLatitude) - southMercatorY); + + useWebMercatorProjection = true; } } - }; - defineProperties(QuadtreeTile.prototype, { - /** - * Gets the tiling scheme used to tile the surface. - * @memberof QuadtreeTile.prototype - * @type {TilingScheme} - */ - tilingScheme : { - get : function() { - return this._tilingScheme; - } - }, + var tileImageryCollection = surfaceTile.imagery; + var imageryIndex = 0; + var imageryLen = tileImageryCollection.length; - /** - * Gets the tile X coordinate. - * @memberof QuadtreeTile.prototype - * @type {Number} - */ - x : { - get : function() { - return this._x; - } - }, + var firstPassRenderState = tileProvider._renderState; + var otherPassesRenderState = tileProvider._blendRenderState; + var renderState = firstPassRenderState; - /** - * Gets the tile Y coordinate. - * @memberof QuadtreeTile.prototype - * @type {Number} - */ - y : { - get : function() { - return this._y; - } - }, + var initialColor = tileProvider._firstPassInitialColor; - /** - * Gets the level-of-detail, where zero is the coarsest, least-detailed. - * @memberof QuadtreeTile.prototype - * @type {Number} - */ - level : { - get : function() { - return this._level; - } - }, + var context = frameState.context; - /** - * Gets the parent tile of this tile. - * @memberof QuadtreeTile.prototype - * @type {QuadtreeTile} - */ - parent : { - get : function() { - return this._parent; - } - }, + if (!defined(tileProvider._debug.boundingSphereTile)) { + debugDestroyPrimitive(); + } - /** - * Gets the cartographic rectangle of the tile, with north, south, east and - * west properties in radians. - * @memberof QuadtreeTile.prototype - * @type {Rectangle} - */ - rectangle : { - get : function() { - return this._rectangle; - } - }, + do { + var numberOfDayTextures = 0; - /** - * An array of tiles that is at the next level of the tile tree. - * @memberof QuadtreeTile.prototype - * @type {QuadtreeTile[]} - */ - children : { - get : function() { - return [this.northwestChild, this.northeastChild, this.southwestChild, this.southeastChild]; + var command; + var uniformMap; + + if (tileProvider._drawCommands.length <= tileProvider._usedDrawCommands) { + command = new DrawCommand(); + command.owner = tile; + command.cull = false; + command.boundingVolume = new BoundingSphere(); + command.orientedBoundingBox = undefined; + + uniformMap = createTileUniformMap(frameState); + + tileProvider._drawCommands.push(command); + tileProvider._uniformMaps.push(uniformMap); + } else { + command = tileProvider._drawCommands[tileProvider._usedDrawCommands]; + uniformMap = tileProvider._uniformMaps[tileProvider._usedDrawCommands]; } - }, - /** - * Gets the southwest child tile. - * @memberof QuadtreeTile.prototype - * @type {QuadtreeTile} - */ - southwestChild : { - get : function() { - if (!defined(this._southwestChild)) { - this._southwestChild = new QuadtreeTile({ - tilingScheme : this.tilingScheme, - x : this.x * 2, - y : this.y * 2 + 1, - level : this.level + 1, - parent : this - }); + command.owner = tile; + + ++tileProvider._usedDrawCommands; + + if (tile === tileProvider._debug.boundingSphereTile) { + // If a debug primitive already exists for this tile, it will not be + // re-created, to avoid allocation every frame. If it were possible + // to have more than one selected tile, this would have to change. + if (defined(surfaceTile.orientedBoundingBox)) { + getDebugOrientedBoundingBox(surfaceTile.orientedBoundingBox, Color.RED).update(frameState); + } else if (defined(surfaceTile.boundingSphere3D)) { + getDebugBoundingSphere(surfaceTile.boundingSphere3D, Color.RED).update(frameState); } - return this._southwestChild; } - }, - /** - * Gets the southeast child tile. - * @memberof QuadtreeTile.prototype - * @type {QuadtreeTile} - */ - southeastChild : { - get : function() { - if (!defined(this._southeastChild)) { - this._southeastChild = new QuadtreeTile({ - tilingScheme : this.tilingScheme, - x : this.x * 2 + 1, - y : this.y * 2 + 1, - level : this.level + 1, - parent : this - }); + var uniformMapProperties = uniformMap.properties; + Cartesian4.clone(initialColor, uniformMapProperties.initialColor); + uniformMapProperties.oceanNormalMap = oceanNormalMap; + uniformMapProperties.lightingFadeDistance.x = tileProvider.lightingFadeOutDistance; + uniformMapProperties.lightingFadeDistance.y = tileProvider.lightingFadeInDistance; + uniformMapProperties.zoomedOutOceanSpecularIntensity = tileProvider.zoomedOutOceanSpecularIntensity; + + uniformMapProperties.center3D = surfaceTile.center; + Cartesian3.clone(rtc, uniformMapProperties.rtc); + + Cartesian4.clone(tileRectangle, uniformMapProperties.tileRectangle); + uniformMapProperties.southAndNorthLatitude.x = southLatitude; + uniformMapProperties.southAndNorthLatitude.y = northLatitude; + uniformMapProperties.southMercatorYAndOneOverHeight.x = southMercatorY; + uniformMapProperties.southMercatorYAndOneOverHeight.y = oneOverMercatorHeight; + + // For performance, use fog in the shader only when the tile is in fog. + var applyFog = enableFog && CesiumMath.fog(tile._distance, frameState.fog.density) > CesiumMath.EPSILON3; + + var applyBrightness = false; + var applyContrast = false; + var applyHue = false; + var applySaturation = false; + var applyGamma = false; + var applyAlpha = false; + var applySplit = false; + + while (numberOfDayTextures < maxTextures && imageryIndex < imageryLen) { + var tileImagery = tileImageryCollection[imageryIndex]; + var imagery = tileImagery.readyImagery; + ++imageryIndex; + + if (!defined(imagery) || imagery.imageryLayer.alpha === 0.0) { + continue; } - return this._southeastChild; - } - }, - /** - * Gets the northwest child tile. - * @memberof QuadtreeTile.prototype - * @type {QuadtreeTile} - */ - northwestChild : { - get : function() { - if (!defined(this._northwestChild)) { - this._northwestChild = new QuadtreeTile({ - tilingScheme : this.tilingScheme, - x : this.x * 2, - y : this.y * 2, - level : this.level + 1, - parent : this - }); + var texture = tileImagery.useWebMercatorT ? imagery.textureWebMercator : imagery.texture; + + if (!defined(texture)) { + // Our "ready" texture isn't actually ready. This should never happen. + // + // Side note: It IS possible for it to not be in the READY ImageryState, though. + // This can happen when a single imagery tile is shared by two terrain tiles (common) + // and one of them (A) needs a geographic version of the tile because it is near the poles, + // and the other (B) does not. B can and will transition the imagery tile to the READY state + // without reprojecting to geographic. Then, later, A will deem that same tile not-ready-yet + // because it only has the Web Mercator texture, and flip it back to the TRANSITIONING state. + // The imagery tile won't be in the READY state anymore, but it's still READY enough for B's + // purposes. + throw new DeveloperError('readyImagery is not actually ready!'); } - return this._northwestChild; - } - }, + + var imageryLayer = imagery.imageryLayer; - /** - * Gets the northeast child tile. - * @memberof QuadtreeTile.prototype - * @type {QuadtreeTile} - */ - northeastChild : { - get : function() { - if (!defined(this._northeastChild)) { - this._northeastChild = new QuadtreeTile({ - tilingScheme : this.tilingScheme, - x : this.x * 2 + 1, - y : this.y * 2, - level : this.level + 1, - parent : this - }); + if (!defined(tileImagery.textureTranslationAndScale)) { + tileImagery.textureTranslationAndScale = imageryLayer._calculateTextureTranslationAndScale(tile, tileImagery); } - return this._northeastChild; - } - }, - /** - * An array of objects associated with this tile. - * @memberof QuadtreeTile.prototype - * @type {Array} - */ - customData : { - get : function() { - return this._customData; - } - }, + uniformMapProperties.dayTextures[numberOfDayTextures] = texture; + uniformMapProperties.dayTextureTranslationAndScale[numberOfDayTextures] = tileImagery.textureTranslationAndScale; + uniformMapProperties.dayTextureTexCoordsRectangle[numberOfDayTextures] = tileImagery.textureCoordinateRectangle; + uniformMapProperties.dayTextureUseWebMercatorT[numberOfDayTextures] = tileImagery.useWebMercatorT; - /** - * Gets a value indicating whether or not this tile needs further loading. - * This property will return true if the {@link QuadtreeTile#state} is - * <code>START</code> or <code>LOADING</code>. - * @memberof QuadtreeTile.prototype - * @type {Boolean} - */ - needsLoading : { - get : function() { - return this.state < QuadtreeTileLoadState.DONE; - } - }, + uniformMapProperties.dayTextureAlpha[numberOfDayTextures] = imageryLayer.alpha; + applyAlpha = applyAlpha || uniformMapProperties.dayTextureAlpha[numberOfDayTextures] !== 1.0; - /** - * Gets a value indicating whether or not this tile is eligible to be unloaded. - * Typically, a tile is ineligible to be unloaded while an asynchronous operation, - * such as a request for data, is in progress on it. A tile will never be - * unloaded while it is needed for rendering, regardless of the value of this - * property. If {@link QuadtreeTile#data} is defined and has an - * <code>eligibleForUnloading</code> property, the value of that property is returned. - * Otherwise, this property returns true. - * @memberof QuadtreeTile.prototype - * @type {Boolean} - */ - eligibleForUnloading : { - get : function() { - var result = true; + uniformMapProperties.dayTextureBrightness[numberOfDayTextures] = imageryLayer.brightness; + applyBrightness = applyBrightness || uniformMapProperties.dayTextureBrightness[numberOfDayTextures] !== ImageryLayer.DEFAULT_BRIGHTNESS; - if (defined(this.data)) { - result = this.data.eligibleForUnloading; - if (!defined(result)) { - result = true; + uniformMapProperties.dayTextureContrast[numberOfDayTextures] = imageryLayer.contrast; + applyContrast = applyContrast || uniformMapProperties.dayTextureContrast[numberOfDayTextures] !== ImageryLayer.DEFAULT_CONTRAST; + + uniformMapProperties.dayTextureHue[numberOfDayTextures] = imageryLayer.hue; + applyHue = applyHue || uniformMapProperties.dayTextureHue[numberOfDayTextures] !== ImageryLayer.DEFAULT_HUE; + + uniformMapProperties.dayTextureSaturation[numberOfDayTextures] = imageryLayer.saturation; + applySaturation = applySaturation || uniformMapProperties.dayTextureSaturation[numberOfDayTextures] !== ImageryLayer.DEFAULT_SATURATION; + + uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] = 1.0 / imageryLayer.gamma; + applyGamma = applyGamma || uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] !== 1.0 / ImageryLayer.DEFAULT_GAMMA; + + uniformMapProperties.dayTextureSplit[numberOfDayTextures] = imageryLayer.splitDirection; + applySplit = applySplit || uniformMapProperties.dayTextureSplit[numberOfDayTextures] !== 0.0; + + if (defined(imagery.credits)) { + var credits = imagery.credits; + for (var creditIndex = 0, creditLength = credits.length; creditIndex < creditLength; ++creditIndex) { + creditDisplay.addCredit(credits[creditIndex]); } } - return result; + ++numberOfDayTextures; } - } - }); - - /** - * Frees the resources associated with this tile and returns it to the <code>START</code> - * {@link QuadtreeTileLoadState}. If the {@link QuadtreeTile#data} property is defined and it - * has a <code>freeResources</code> method, the method will be invoked. - * - * @memberof QuadtreeTile - */ - QuadtreeTile.prototype.freeResources = function() { - this.state = QuadtreeTileLoadState.START; - this.renderable = false; - this.upsampledFromParent = false; - - if (defined(this.data) && defined(this.data.freeResources)) { - this.data.freeResources(); - } - freeTile(this._southwestChild); - this._southwestChild = undefined; - freeTile(this._southeastChild); - this._southeastChild = undefined; - freeTile(this._northwestChild); - this._northwestChild = undefined; - freeTile(this._northeastChild); - this._northeastChild = undefined; - }; + // trim texture array to the used length so we don't end up using old textures + // which might get destroyed eventually + uniformMapProperties.dayTextures.length = numberOfDayTextures; + uniformMapProperties.waterMask = waterMaskTexture; + Cartesian4.clone(surfaceTile.waterMaskTranslationAndScale, uniformMapProperties.waterMaskTranslationAndScale); - function freeTile(tile) { - if (defined(tile)) { - tile.freeResources(); - } - } + uniformMapProperties.minMaxHeight.x = encoding.minimumHeight; + uniformMapProperties.minMaxHeight.y = encoding.maximumHeight; + Matrix4.clone(encoding.matrix, uniformMapProperties.scaleAndBias); - return QuadtreeTile; -}); + // update clipping planes + var clippingPlanes = tileProvider.clippingPlanes; + var length = 0; -define('Scene/TileReplacementQueue',[ - '../Core/defined' - ], function( - defined) { - 'use strict'; + if (defined(clippingPlanes) && tile.isClipped) { + length = clippingPlanes.length; + } - /** - * A priority queue of tiles to be replaced, if necessary, to make room for new tiles. The queue - * is implemented as a linked list. - * - * @alias TileReplacementQueue - * @private - */ - function TileReplacementQueue() { - this.head = undefined; - this.tail = undefined; - this.count = 0; - this._lastBeforeStartOfFrame = undefined; - } + var packedPlanes = uniformMapProperties.clippingPlanes; + var packedLength = packedPlanes.length; + if (packedLength !== length) { + packedPlanes.length = length; - /** - * Marks the start of the render frame. Tiles before (closer to the head) this tile in the - * list were used last frame and must not be unloaded. - */ - TileReplacementQueue.prototype.markStartOfRenderFrame = function() { - this._lastBeforeStartOfFrame = this.head; - }; + for (var i = packedLength; i < length; ++i) { + packedPlanes[i] = new Cartesian4(); + } + } - /** - * Reduces the size of the queue to a specified size by unloading the least-recently used - * tiles. Tiles that were used last frame will not be unloaded, even if that puts the number - * of tiles above the specified maximum. - * - * @param {Number} maximumTiles The maximum number of tiles in the queue. - */ - TileReplacementQueue.prototype.trimTiles = function(maximumTiles) { - var tileToTrim = this.tail; - var keepTrimming = true; - while (keepTrimming && - defined(this._lastBeforeStartOfFrame) && - this.count > maximumTiles && - defined(tileToTrim)) { - // Stop trimming after we process the last tile not used in the - // current frame. - keepTrimming = tileToTrim !== this._lastBeforeStartOfFrame; + if (defined(clippingPlanes) && clippingPlanes.enabled && tile.isClipped) { + clippingPlanes.transformAndPackPlanes(context.uniformState.view, packedPlanes); + uniformMapProperties.clippingPlanesEdgeColor = Color.clone(clippingPlanes.edgeColor, uniformMapProperties.clippingPlanesEdgeColor); + uniformMapProperties.clippingPlanesEdgeWidth = clippingPlanes.edgeWidth; + } - var previous = tileToTrim.replacementPrevious; + var clippingPlanesEnabled = defined(clippingPlanes) && clippingPlanes.enabled && (uniformMapProperties.clippingPlanes.length > 0) && ClippingPlaneCollection.isSupported(); + var unionClippingRegions = clippingPlanesEnabled ? clippingPlanes.unionClippingRegions : false; - if (tileToTrim.eligibleForUnloading) { - tileToTrim.freeResources(); - remove(this, tileToTrim); + if (defined(tileProvider.uniformMap)) { + uniformMap = combine(uniformMap, tileProvider.uniformMap); } - tileToTrim = previous; - } - }; + command.shaderProgram = tileProvider._surfaceShaderSet.getShaderProgram(frameState, surfaceTile, numberOfDayTextures, applyBrightness, applyContrast, applyHue, applySaturation, applyGamma, applyAlpha, applySplit, showReflectiveOcean, showOceanWaves, tileProvider.enableLighting, hasVertexNormals, useWebMercatorProjection, applyFog, clippingPlanesEnabled, unionClippingRegions); + command.castShadows = castShadows; + command.receiveShadows = receiveShadows; + command.renderState = renderState; + command.primitiveType = PrimitiveType.TRIANGLES; + command.vertexArray = surfaceTile.vertexArray; + command.uniformMap = uniformMap; + command.pass = Pass.GLOBE; - function remove(tileReplacementQueue, item) { - var previous = item.replacementPrevious; - var next = item.replacementNext; + if (tileProvider._debug.wireframe) { + createWireframeVertexArrayIfNecessary(context, tileProvider, tile); + if (defined(surfaceTile.wireframeVertexArray)) { + command.vertexArray = surfaceTile.wireframeVertexArray; + command.primitiveType = PrimitiveType.LINES; + } + } - if (item === tileReplacementQueue._lastBeforeStartOfFrame) { - tileReplacementQueue._lastBeforeStartOfFrame = next; - } + var boundingVolume = command.boundingVolume; + var orientedBoundingBox = command.orientedBoundingBox; - if (item === tileReplacementQueue.head) { - tileReplacementQueue.head = next; - } else { - previous.replacementNext = next; - } + if (frameState.mode !== SceneMode.SCENE3D) { + BoundingSphere.fromRectangleWithHeights2D(tile.rectangle, frameState.mapProjection, surfaceTile.minimumHeight, surfaceTile.maximumHeight, boundingVolume); + Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); - if (item === tileReplacementQueue.tail) { - tileReplacementQueue.tail = previous; - } else { - next.replacementPrevious = previous; - } + if (frameState.mode === SceneMode.MORPHING) { + boundingVolume = BoundingSphere.union(surfaceTile.boundingSphere3D, boundingVolume, boundingVolume); + } + } else { + command.boundingVolume = BoundingSphere.clone(surfaceTile.boundingSphere3D, boundingVolume); + command.orientedBoundingBox = OrientedBoundingBox.clone(surfaceTile.orientedBoundingBox, orientedBoundingBox); + } - item.replacementPrevious = undefined; - item.replacementNext = undefined; + frameState.commandList.push(command); - --tileReplacementQueue.count; + renderState = otherPassesRenderState; + initialColor = otherPassesInitialColor; + } while (imageryIndex < imageryLen); } - /** - * Marks a tile as rendered this frame and moves it before the first tile that was not rendered - * this frame. - * - * @param {TileReplacementQueue} item The tile that was rendered. - */ - TileReplacementQueue.prototype.markTileRendered = function(item) { - var head = this.head; - if (head === item) { - if (item === this._lastBeforeStartOfFrame) { - this._lastBeforeStartOfFrame = item.replacementNext; - } - return; + function addPickCommandsForTile(tileProvider, drawCommand, frameState) { + var pickCommand; + if (tileProvider._pickCommands.length <= tileProvider._usedPickCommands) { + pickCommand = new DrawCommand(); + pickCommand.cull = false; + + tileProvider._pickCommands.push(pickCommand); + } else { + pickCommand = tileProvider._pickCommands[tileProvider._usedPickCommands]; } - ++this.count; + ++tileProvider._usedPickCommands; - if (!defined(head)) { - // no other tiles in the list - item.replacementPrevious = undefined; - item.replacementNext = undefined; - this.head = item; - this.tail = item; - return; - } + var surfaceTile = drawCommand.owner.data; + var useWebMercatorProjection = frameState.projection instanceof WebMercatorProjection; - if (defined(item.replacementPrevious) || defined(item.replacementNext)) { - // tile already in the list, remove from its current location - remove(this, item); - } + pickCommand.shaderProgram = tileProvider._surfaceShaderSet.getPickShaderProgram(frameState, surfaceTile, useWebMercatorProjection); + pickCommand.renderState = tileProvider._pickRenderState; - item.replacementPrevious = undefined; - item.replacementNext = head; - head.replacementPrevious = item; + pickCommand.owner = drawCommand.owner; + pickCommand.primitiveType = drawCommand.primitiveType; + pickCommand.vertexArray = drawCommand.vertexArray; + pickCommand.uniformMap = drawCommand.uniformMap; + pickCommand.boundingVolume = drawCommand.boundingVolume; + pickCommand.orientedBoundingBox = drawCommand.orientedBoundingBox; + pickCommand.pass = drawCommand.pass; - this.head = item; - }; + frameState.commandList.push(pickCommand); + } - return TileReplacementQueue; + return GlobeSurfaceTileProvider; }); -define('Scene/QuadtreePrimitive',[ - '../Core/Cartesian3', - '../Core/Cartographic', +define('Scene/ImageryLayerCollection',[ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', '../Core/Event', - '../Core/getTimestamp', '../Core/Math', - '../Core/OrthographicFrustum', - '../Core/Ray', '../Core/Rectangle', - '../Core/Visibility', - './QuadtreeOccluders', - './QuadtreeTile', - './QuadtreeTileLoadState', - './SceneMode', - './TileReplacementQueue' + '../ThirdParty/when', + './ImageryLayer' ], function( - Cartesian3, - Cartographic, defaultValue, defined, defineProperties, - DeveloperError, - Event, - getTimestamp, - CesiumMath, - OrthographicFrustum, - Ray, - Rectangle, - Visibility, - QuadtreeOccluders, - QuadtreeTile, - QuadtreeTileLoadState, - SceneMode, - TileReplacementQueue) { - 'use strict'; - - /** - * Renders massive sets of data by utilizing level-of-detail and culling. The globe surface is divided into - * a quadtree of tiles with large, low-detail tiles at the root and small, high-detail tiles at the leaves. - * The set of tiles to render is selected by projecting an estimate of the geometric error in a tile onto - * the screen to estimate screen-space error, in pixels, which must be below a user-specified threshold. - * The actual content of the tiles is arbitrary and is specified using a {@link QuadtreeTileProvider}. - * - * @alias QuadtreePrimitive - * @constructor - * @private - * - * @param {QuadtreeTileProvider} options.tileProvider The tile provider that loads, renders, and estimates - * the distance to individual tiles. - * @param {Number} [options.maximumScreenSpaceError=2] The maximum screen-space error, in pixels, that is allowed. - * A higher maximum error will render fewer tiles and improve performance, while a lower - * value will improve visual quality. - * @param {Number} [options.tileCacheSize=100] The maximum number of tiles that will be retained in the tile cache. - * Note that tiles will never be unloaded if they were used for rendering the last - * frame, so the actual number of resident tiles may be higher. The value of - * this property will not affect visual quality. - */ - function QuadtreePrimitive(options) { - if (!defined(options) || !defined(options.tileProvider)) { - throw new DeveloperError('options.tileProvider is required.'); - } - if (defined(options.tileProvider.quadtree)) { - throw new DeveloperError('A QuadtreeTileProvider can only be used with a single QuadtreePrimitive'); - } - - this._tileProvider = options.tileProvider; - this._tileProvider.quadtree = this; - - this._debug = { - enableDebugOutput : false, - - maxDepth : 0, - tilesVisited : 0, - tilesCulled : 0, - tilesRendered : 0, - tilesWaitingForChildren : 0, - - lastMaxDepth : -1, - lastTilesVisited : -1, - lastTilesCulled : -1, - lastTilesRendered : -1, - lastTilesWaitingForChildren : -1, - - suspendLodUpdate : false - }; - - var tilingScheme = this._tileProvider.tilingScheme; - var ellipsoid = tilingScheme.ellipsoid; - - this._tilesToRender = []; - this._tileLoadQueueHigh = []; // high priority tiles are preventing refinement - this._tileLoadQueueMedium = []; // medium priority tiles are being rendered - this._tileLoadQueueLow = []; // low priority tiles were refined past or are non-visible parts of quads. - this._tileReplacementQueue = new TileReplacementQueue(); - this._levelZeroTiles = undefined; - this._loadQueueTimeSlice = 5.0; - - this._addHeightCallbacks = []; - this._removeHeightCallbacks = []; + destroyObject, + DeveloperError, + Event, + CesiumMath, + Rectangle, + when, + ImageryLayer) { + 'use strict'; - this._tileToUpdateHeights = []; - this._lastTileIndex = 0; - this._updateHeightsTimeSlice = 2.0; + /** + * An ordered collection of imagery layers. + * + * @alias ImageryLayerCollection + * @constructor + * + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Adjustment.html|Cesium Sandcastle Imagery Adjustment Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Imagery%20Layers%20Manipulation.html|Cesium Sandcastle Imagery Manipulation Demo} + */ + function ImageryLayerCollection() { + this._layers = []; /** - * Gets or sets the maximum screen-space error, in pixels, that is allowed. - * A higher maximum error will render fewer tiles and improve performance, while a lower - * value will improve visual quality. - * @type {Number} - * @default 2 + * An event that is raised when a layer is added to the collection. Event handlers are passed the layer that + * was added and the index at which it was added. + * @type {Event} + * @default Event() */ - this.maximumScreenSpaceError = defaultValue(options.maximumScreenSpaceError, 2); + this.layerAdded = new Event(); /** - * Gets or sets the maximum number of tiles that will be retained in the tile cache. - * Note that tiles will never be unloaded if they were used for rendering the last - * frame, so the actual number of resident tiles may be higher. The value of - * this property will not affect visual quality. - * @type {Number} - * @default 100 + * An event that is raised when a layer is removed from the collection. Event handlers are passed the layer that + * was removed and the index from which it was removed. + * @type {Event} + * @default Event() */ - this.tileCacheSize = defaultValue(options.tileCacheSize, 100); - - this._occluders = new QuadtreeOccluders({ - ellipsoid : ellipsoid - }); - - this._tileLoadProgressEvent = new Event(); - this._lastTileLoadQueueLength = 0; - } + this.layerRemoved = new Event(); - defineProperties(QuadtreePrimitive.prototype, { /** - * Gets the provider of {@link QuadtreeTile} instances for this quadtree. - * @type {QuadtreeTile} - * @memberof QuadtreePrimitive.prototype + * An event that is raised when a layer changes position in the collection. Event handlers are passed the layer that + * was moved, its new index after the move, and its old index prior to the move. + * @type {Event} + * @default Event() */ - tileProvider : { - get : function() { - return this._tileProvider; - } - }, + this.layerMoved = new Event(); + /** - * Gets an event that's raised when the length of the tile load queue has changed since the last render frame. When the load queue is empty, - * all terrain and imagery for the current view have been loaded. The event passes the new length of the tile load queue. + * An event that is raised when a layer is shown or hidden by setting the + * {@link ImageryLayer#show} property. Event handlers are passed a reference to this layer, + * the index of the layer in the collection, and a flag that is true if the layer is now + * shown or false if it is now hidden. * - * @memberof QuadtreePrimitive.prototype * @type {Event} + * @default Event() */ - tileLoadProgressEvent : { + this.layerShownOrHidden = new Event(); + } + + defineProperties(ImageryLayerCollection.prototype, { + /** + * Gets the number of layers in this collection. + * @memberof ImageryLayerCollection.prototype + * @type {Number} + */ + length : { get : function() { - return this._tileLoadProgressEvent; + return this._layers.length; } } }); /** - * Invalidates and frees all the tiles in the quadtree. The tiles must be reloaded - * before they can be displayed. + * Adds a layer to the collection. * - * @memberof QuadtreePrimitive + * @param {ImageryLayer} layer the layer to add. + * @param {Number} [index] the index to add the layer at. If omitted, the layer will + * added on top of all existing layers. + * + * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of the layers. */ - QuadtreePrimitive.prototype.invalidateAllTiles = function() { - // Clear the replacement queue - var replacementQueue = this._tileReplacementQueue; - replacementQueue.head = undefined; - replacementQueue.tail = undefined; - replacementQueue.count = 0; - - // Free and recreate the level zero tiles. - var levelZeroTiles = this._levelZeroTiles; - if (defined(levelZeroTiles)) { - for (var i = 0; i < levelZeroTiles.length; ++i) { - var tile = levelZeroTiles[i]; - var customData = tile.customData; - var customDataLength = customData.length; - - for (var j = 0; j < customDataLength; ++j) { - var data = customData[j]; - data.level = 0; - this._addHeightCallbacks.push(data); - } + ImageryLayerCollection.prototype.add = function(layer, index) { + var hasIndex = defined(index); - levelZeroTiles[i].freeResources(); + if (!defined(layer)) { + throw new DeveloperError('layer is required.'); + } + if (hasIndex) { + if (index < 0) { + throw new DeveloperError('index must be greater than or equal to zero.'); + } else if (index > this._layers.length) { + throw new DeveloperError('index must be less than or equal to the number of layers.'); } } + + if (!hasIndex) { + index = this._layers.length; + this._layers.push(layer); + } else { + this._layers.splice(index, 0, layer); + } - this._levelZeroTiles = undefined; - - this._tileProvider.cancelReprojections(); + this._update(); + this.layerAdded.raiseEvent(layer, index); }; /** - * Invokes a specified function for each {@link QuadtreeTile} that is partially - * or completely loaded. + * Creates a new layer using the given ImageryProvider and adds it to the collection. * - * @param {Function} tileFunction The function to invoke for each loaded tile. The - * function is passed a reference to the tile as its only parameter. + * @param {ImageryProvider} imageryProvider the imagery provider to create a new layer for. + * @param {Number} [index] the index to add the layer at. If omitted, the layer will + * added on top of all existing layers. + * @returns {ImageryLayer} The newly created layer. */ - QuadtreePrimitive.prototype.forEachLoadedTile = function(tileFunction) { - var tile = this._tileReplacementQueue.head; - while (defined(tile)) { - if (tile.state !== QuadtreeTileLoadState.START) { - tileFunction(tile); - } - tile = tile.replacementNext; + ImageryLayerCollection.prototype.addImageryProvider = function(imageryProvider, index) { + if (!defined(imageryProvider)) { + throw new DeveloperError('imageryProvider is required.'); } + + var layer = new ImageryLayer(imageryProvider); + this.add(layer, index); + return layer; }; /** - * Invokes a specified function for each {@link QuadtreeTile} that was rendered - * in the most recent frame. + * Removes a layer from this collection, if present. * - * @param {Function} tileFunction The function to invoke for each rendered tile. The - * function is passed a reference to the tile as its only parameter. + * @param {ImageryLayer} layer The layer to remove. + * @param {Boolean} [destroy=true] whether to destroy the layers in addition to removing them. + * @returns {Boolean} true if the layer was in the collection and was removed, + * false if the layer was not in the collection. */ - QuadtreePrimitive.prototype.forEachRenderedTile = function(tileFunction) { - var tilesRendered = this._tilesToRender; - for (var i = 0, len = tilesRendered.length; i < len; ++i) { - tileFunction(tilesRendered[i]); - } - }; + ImageryLayerCollection.prototype.remove = function(layer, destroy) { + destroy = defaultValue(destroy, true); - /** - * Calls the callback when a new tile is rendered that contains the given cartographic. The only parameter - * is the cartesian position on the tile. - * - * @param {Cartographic} cartographic The cartographic position. - * @param {Function} callback The function to be called when a new tile is loaded containing cartographic. - * @returns {Function} The function to remove this callback from the quadtree. - */ - QuadtreePrimitive.prototype.updateHeight = function(cartographic, callback) { - var primitive = this; - var object = { - positionOnEllipsoidSurface : undefined, - positionCartographic : cartographic, - level : -1, - callback : callback - }; + var index = this._layers.indexOf(layer); + if (index !== -1) { + this._layers.splice(index, 1); - object.removeFunc = function() { - var addedCallbacks = primitive._addHeightCallbacks; - var length = addedCallbacks.length; - for (var i = 0; i < length; ++i) { - if (addedCallbacks[i] === object) { - addedCallbacks.splice(i, 1); - break; - } + this._update(); + + this.layerRemoved.raiseEvent(layer, index); + + if (destroy) { + layer.destroy(); } - primitive._removeHeightCallbacks.push(object); - }; - primitive._addHeightCallbacks.push(object); - return object.removeFunc; + return true; + } + + return false; }; /** - * @private + * Removes all layers from this collection. + * + * @param {Boolean} [destroy=true] whether to destroy the layers in addition to removing them. */ - QuadtreePrimitive.prototype.beginFrame = function(frameState) { - var passes = frameState.passes; - if (!passes.render) { - return; - } + ImageryLayerCollection.prototype.removeAll = function(destroy) { + destroy = defaultValue(destroy, true); - // Gets commands for any texture re-projections and updates the credit display - this._tileProvider.initialize(frameState); + var layers = this._layers; + for (var i = 0, len = layers.length; i < len; i++) { + var layer = layers[i]; + this.layerRemoved.raiseEvent(layer, i); - var debug = this._debug; - if (debug.suspendLodUpdate) { - return; + if (destroy) { + layer.destroy(); + } } - debug.maxDepth = 0; - debug.tilesVisited = 0; - debug.tilesCulled = 0; - debug.tilesRendered = 0; - debug.tilesWaitingForChildren = 0; - - this._tileLoadQueueHigh.length = 0; - this._tileLoadQueueMedium.length = 0; - this._tileLoadQueueLow.length = 0; - this._tileReplacementQueue.markStartOfRenderFrame(); + this._layers = []; }; /** - * @private + * Checks to see if the collection contains a given layer. + * + * @param {ImageryLayer} layer the layer to check for. + * + * @returns {Boolean} true if the collection contains the layer, false otherwise. */ - QuadtreePrimitive.prototype.update = function(frameState) { - var passes = frameState.passes; - - if (passes.render) { - this._tileProvider.beginUpdate(frameState); + ImageryLayerCollection.prototype.contains = function(layer) { + return this.indexOf(layer) !== -1; + }; - selectTilesForRendering(this, frameState); - createRenderCommandsForSelectedTiles(this, frameState); + /** + * Determines the index of a given layer in the collection. + * + * @param {ImageryLayer} layer The layer to find the index of. + * + * @returns {Number} The index of the layer in the collection, or -1 if the layer does not exist in the collection. + */ + ImageryLayerCollection.prototype.indexOf = function(layer) { + return this._layers.indexOf(layer); + }; - this._tileProvider.endUpdate(frameState); + /** + * Gets a layer by index from the collection. + * + * @param {Number} index the index to retrieve. + * + * @returns {ImageryLayer} The imagery layer at the given index. + */ + ImageryLayerCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.', 'index'); } + + return this._layers[index]; + }; - if (passes.pick && this._tilesToRender.length > 0) { - this._tileProvider.updateForPick(frameState); + function getLayerIndex(layers, layer) { + if (!defined(layer)) { + throw new DeveloperError('layer is required.'); } - }; + + var index = layers.indexOf(layer); - /** - * @private - */ - QuadtreePrimitive.prototype.endFrame = function(frameState) { - var passes = frameState.passes; - if (!passes.render || frameState.mode === SceneMode.MORPHING) { - // Only process the load queue for a single pass. - // Don't process the load queue or update heights during the morph flights. - return; + if (index === -1) { + throw new DeveloperError('layer is not in this collection.'); } + + return index; + } - // Load/create resources for terrain and imagery. Prepare texture re-projections for the next frame. - processTileLoadQueue(this, frameState); - updateHeights(this, frameState); + function swapLayers(collection, i, j) { + var arr = collection._layers; + i = CesiumMath.clamp(i, 0, arr.length - 1); + j = CesiumMath.clamp(j, 0, arr.length - 1); - var debug = this._debug; - if (debug.suspendLodUpdate) { + if (i === j) { return; } - if (debug.enableDebugOutput) { - if (debug.tilesVisited !== debug.lastTilesVisited || - debug.tilesRendered !== debug.lastTilesRendered || - debug.tilesCulled !== debug.lastTilesCulled || - debug.maxDepth !== debug.lastMaxDepth || - debug.tilesWaitingForChildren !== debug.lastTilesWaitingForChildren) { + var temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; - console.log('Visited ' + debug.tilesVisited + ', Rendered: ' + debug.tilesRendered + ', Culled: ' + debug.tilesCulled + ', Max Depth: ' + debug.maxDepth + ', Waiting for children: ' + debug.tilesWaitingForChildren); + collection._update(); - debug.lastTilesVisited = debug.tilesVisited; - debug.lastTilesRendered = debug.tilesRendered; - debug.lastTilesCulled = debug.tilesCulled; - debug.lastMaxDepth = debug.maxDepth; - debug.lastTilesWaitingForChildren = debug.tilesWaitingForChildren; - } - } - }; + collection.layerMoved.raiseEvent(temp, j, i); + } /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @memberof QuadtreePrimitive + * Raises a layer up one position in the collection. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @param {ImageryLayer} layer the layer to move. * - * @see QuadtreePrimitive#destroy + * @exception {DeveloperError} layer is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. */ - QuadtreePrimitive.prototype.isDestroyed = function() { - return false; + ImageryLayerCollection.prototype.raise = function(layer) { + var index = getLayerIndex(this._layers, layer); + swapLayers(this, index, index + 1); }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @memberof QuadtreePrimitive + * Lowers a layer down one position in the collection. * - * @returns {undefined} + * @param {ImageryLayer} layer the layer to move. * + * @exception {DeveloperError} layer is not in this collection. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * primitive = primitive && primitive.destroy(); - * - * @see QuadtreePrimitive#isDestroyed */ - QuadtreePrimitive.prototype.destroy = function() { - this._tileProvider = this._tileProvider && this._tileProvider.destroy(); + ImageryLayerCollection.prototype.lower = function(layer) { + var index = getLayerIndex(this._layers, layer); + swapLayers(this, index, index - 1); }; - var comparisonPoint; - var centerScratch = new Cartographic(); - function compareDistanceToPoint(a, b) { - var center = Rectangle.center(a.rectangle, centerScratch); - var alon = center.longitude - comparisonPoint.longitude; - var alat = center.latitude - comparisonPoint.latitude; - - center = Rectangle.center(b.rectangle, centerScratch); - var blon = center.longitude - comparisonPoint.longitude; - var blat = center.latitude - comparisonPoint.latitude; - - return (alon * alon + alat * alat) - (blon * blon + blat * blat); - } - - function selectTilesForRendering(primitive, frameState) { - var debug = primitive._debug; - if (debug.suspendLodUpdate) { + /** + * Raises a layer to the top of the collection. + * + * @param {ImageryLayer} layer the layer to move. + * + * @exception {DeveloperError} layer is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + ImageryLayerCollection.prototype.raiseToTop = function(layer) { + var index = getLayerIndex(this._layers, layer); + if (index === this._layers.length - 1) { return; } + this._layers.splice(index, 1); + this._layers.push(layer); - var i; - var len; + this._update(); - // Clear the render list. - var tilesToRender = primitive._tilesToRender; - tilesToRender.length = 0; + this.layerMoved.raiseEvent(layer, this._layers.length - 1, index); + }; - // We can't render anything before the level zero tiles exist. - if (!defined(primitive._levelZeroTiles)) { - if (primitive._tileProvider.ready) { - var tilingScheme = primitive._tileProvider.tilingScheme; - primitive._levelZeroTiles = QuadtreeTile.createLevelZeroTiles(tilingScheme); - } else { - // Nothing to do until the provider is ready. - return; - } + /** + * Lowers a layer to the bottom of the collection. + * + * @param {ImageryLayer} layer the layer to move. + * + * @exception {DeveloperError} layer is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + */ + ImageryLayerCollection.prototype.lowerToBottom = function(layer) { + var index = getLayerIndex(this._layers, layer); + if (index === 0) { + return; } + this._layers.splice(index, 1); + this._layers.splice(0, 0, layer); - primitive._occluders.ellipsoid.cameraPosition = frameState.camera.positionWC; - - var tile; - var levelZeroTiles = primitive._levelZeroTiles; - - var tileProvider = primitive._tileProvider; - var occluders = levelZeroTiles.length > 1 ? primitive._occluders : undefined; - - // Sort the level zero tiles by the distance from the center to the camera. - // The level zero tiles aren't necessarily a nice neat quad, so we can use the - // quadtree ordering we use elsewhere in the tree - comparisonPoint = frameState.camera.positionCartographic; - levelZeroTiles.sort(compareDistanceToPoint); - - var customDataAdded = primitive._addHeightCallbacks; - var customDataRemoved = primitive._removeHeightCallbacks; - var frameNumber = frameState.frameNumber; - - if (customDataAdded.length > 0 || customDataRemoved.length > 0) { - for (i = 0, len = levelZeroTiles.length; i < len; ++i) { - tile = levelZeroTiles[i]; - tile._updateCustomData(frameNumber, customDataAdded, customDataRemoved); - } + this._update(); - customDataAdded.length = 0; - customDataRemoved.length = 0; - } + this.layerMoved.raiseEvent(layer, 0, index); + }; - // Our goal with load ordering is to first load all of the tiles we need to - // render the current scene at full detail. Loading any other tiles is just - // a form of prefetching, and we need not do it at all (other concerns aside). This - // simple and obvious statement gets more complicated when we realize that, because - // we don't have bounding volumes for the entire terrain tile pyramid, we don't - // precisely know which tiles we need to render the scene at full detail, until we do - // some loading. - // - // So our load priority is (from high to low): - // 1. Tiles that we _would_ render, except that they're not sufficiently loaded yet. - // Ideally this would only include tiles that we've already determined to be visible, - // but since we don't have reliable visibility information until a tile is loaded, - // and because we (currently) must have all children in a quad renderable before we - // can refine, this pretty much means tiles we'd like to refine to, regardless of - // visibility. (high) - // 2. Tiles that we're rendering. (medium) - // 3. All other tiles. (low) - // - // Within each priority group, tiles should be loaded in approximate near-to-far order, - // but currently they're just loaded in our traversal order which makes no guarantees - // about depth ordering. + var applicableRectangleScratch = new Rectangle(); - // Traverse in depth-first, near-to-far order. - for (i = 0, len = levelZeroTiles.length; i < len; ++i) { - tile = levelZeroTiles[i]; - primitive._tileReplacementQueue.markTileRendered(tile); - if (!tile.renderable) { - if (tile.needsLoading) { - primitive._tileLoadQueueHigh.push(tile); - } - ++debug.tilesWaitingForChildren; - } else if (tileProvider.computeTileVisibility(tile, frameState, occluders) !== Visibility.NONE) { - visitTile(primitive, frameState, tile); - } else { - if (tile.needsLoading) { - primitive._tileLoadQueueLow.push(tile); - } - ++debug.tilesCulled; - } + /** + * Asynchronously determines the imagery layer features that are intersected by a pick ray. The intersected imagery + * layer features are found by invoking {@link ImageryProvider#pickFeatures} for each imagery layer tile intersected + * by the pick ray. To compute a pick ray from a location on the screen, use {@link Camera.getPickRay}. + * + * @param {Ray} ray The ray to test for intersection. + * @param {Scene} scene The scene. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise that resolves to an array of features intersected by the pick ray. + * If it can be quickly determined that no features are intersected (for example, + * because no active imagery providers support {@link ImageryProvider#pickFeatures} + * or because the pick ray does not intersect the surface), this function will + * return undefined. + * + * @example + * var pickRay = viewer.camera.getPickRay(windowPosition); + * var featuresPromise = viewer.imageryLayers.pickImageryLayerFeatures(pickRay, viewer.scene); + * if (!Cesium.defined(featuresPromise)) { + * console.log('No features picked.'); + * } else { + * Cesium.when(featuresPromise, function(features) { + * // This function is called asynchronously when the list if picked features is available. + * console.log('Number of features: ' + features.length); + * if (features.length > 0) { + * console.log('First feature name: ' + features[0].name); + * } + * }); + * } + */ + ImageryLayerCollection.prototype.pickImageryLayerFeatures = function(ray, scene) { + // Find the picked location on the globe. + var pickedPosition = scene.globe.pick(ray, scene); + if (!defined(pickedPosition)) { + return undefined; } - frameState.afterRender.push(createTileProgressFunction(primitive)); - } - - function createTileProgressFunction(primitive) { - return function() { - raiseTileLoadProgressEvent(primitive); - }; - } - - function visitTile(primitive, frameState, tile) { - var debug = primitive._debug; - - ++debug.tilesVisited; - - primitive._tileReplacementQueue.markTileRendered(tile); - tile._updateCustomData(frameState.frameNumber); + var pickedLocation = scene.globe.ellipsoid.cartesianToCartographic(pickedPosition); - if (tile.level > debug.maxDepth) { - debug.maxDepth = tile.level; - } + // Find the terrain tile containing the picked location. + var tilesToRender = scene.globe._surface._tilesToRender; + var pickedTile; - if (screenSpaceError(primitive, frameState, tile) < primitive.maximumScreenSpaceError) { - // This tile meets SSE requirements, so render it. - if (tile.needsLoading) { - // Rendered tile meeting SSE loads with medium priority. - primitive._tileLoadQueueMedium.push(tile); + for (var textureIndex = 0; !defined(pickedTile) && textureIndex < tilesToRender.length; ++textureIndex) { + var tile = tilesToRender[textureIndex]; + if (Rectangle.contains(tile.rectangle, pickedLocation)) { + pickedTile = tile; } - addTileToRenderList(primitive, tile); - return; } - var southwestChild = tile.southwestChild; - var southeastChild = tile.southeastChild; - var northwestChild = tile.northwestChild; - var northeastChild = tile.northeastChild; - var allAreRenderable = southwestChild.renderable && southeastChild.renderable && - northwestChild.renderable && northeastChild.renderable; - var allAreUpsampled = southwestChild.upsampledFromParent && southeastChild.upsampledFromParent && - northwestChild.upsampledFromParent && northeastChild.upsampledFromParent; - - if (allAreRenderable) { - if (allAreUpsampled) { - // No point in rendering the children because they're all upsampled. Render this tile instead. - addTileToRenderList(primitive, tile); - - // Load the children even though we're (currently) not going to render them. - // A tile that is "upsampled only" right now might change its tune once it does more loading. - // A tile that is upsampled now and forever should also be done loading, so no harm done. - queueChildLoadNearToFar(primitive, frameState.camera.positionCartographic, southwestChild, southeastChild, northwestChild, northeastChild); - - if (tile.needsLoading) { - // Rendered tile that's not waiting on children loads with medium priority. - primitive._tileLoadQueueMedium.push(tile); - } - } else { - // SSE is not good enough and children are loaded, so refine. - // No need to add the children to the load queue because they'll be added (if necessary) when they're visited. - visitVisibleChildrenNearToFar(primitive, southwestChild, southeastChild, northwestChild, northeastChild, frameState); + if (!defined(pickedTile)) { + return undefined; + } - if (tile.needsLoading) { - // Tile is not rendered, so load it with low priority. - primitive._tileLoadQueueLow.push(tile); - } - } - } else { - // We'd like to refine but can't because not all of our children are renderable. Load the refinement blockers with high priority and - // render this tile in the meantime. - queueChildLoadNearToFar(primitive, frameState.camera.positionCartographic, southwestChild, southeastChild, northwestChild, northeastChild); - addTileToRenderList(primitive, tile); + // Pick against all attached imagery tiles containing the pickedLocation. + var imageryTiles = pickedTile.data.imagery; - if (tile.needsLoading) { - // We will refine this tile when it's possible, so load this tile only with low priority. - primitive._tileLoadQueueLow.push(tile); + var promises = []; + var imageryLayers = []; + for (var i = imageryTiles.length - 1; i >= 0; --i) { + var terrainImagery = imageryTiles[i]; + var imagery = terrainImagery.readyImagery; + if (!defined(imagery)) { + continue; } - } - } - - function queueChildLoadNearToFar(primitive, cameraPosition, southwest, southeast, northwest, northeast) { - if (cameraPosition.longitude < southwest.east) { - if (cameraPosition.latitude < southwest.north) { - // Camera in southwest quadrant - queueChildTileLoad(primitive, southwest); - queueChildTileLoad(primitive, southeast); - queueChildTileLoad(primitive, northwest); - queueChildTileLoad(primitive, northeast); - } else { - // Camera in northwest quadrant - queueChildTileLoad(primitive, northwest); - queueChildTileLoad(primitive, southwest); - queueChildTileLoad(primitive, northeast); - queueChildTileLoad(primitive, southeast); + var provider = imagery.imageryLayer.imageryProvider; + if (!defined(provider.pickFeatures)) { + continue; } - } else if (cameraPosition.latitude < southwest.north) { - // Camera southeast quadrant - queueChildTileLoad(primitive, southeast); - queueChildTileLoad(primitive, southwest); - queueChildTileLoad(primitive, northeast); - queueChildTileLoad(primitive, northwest); - } else { - // Camera in northeast quadrant - queueChildTileLoad(primitive, northeast); - queueChildTileLoad(primitive, northwest); - queueChildTileLoad(primitive, southeast); - queueChildTileLoad(primitive, southwest); - } - } - function queueChildTileLoad(primitive, childTile) { - primitive._tileReplacementQueue.markTileRendered(childTile); - if (childTile.needsLoading) { - if (childTile.renderable) { - primitive._tileLoadQueueLow.push(childTile); - } else { - // A tile blocking refine loads with high priority - primitive._tileLoadQueueHigh.push(childTile); + if (!Rectangle.contains(imagery.rectangle, pickedLocation)) { + continue; } - } - } - function visitVisibleChildrenNearToFar(primitive, southwest, southeast, northwest, northeast, frameState) { - var cameraPosition = frameState.camera.positionCartographic; - var tileProvider = primitive._tileProvider; - var occluders = primitive._occluders; + // If this imagery came from a parent, it may not be applicable to its entire rectangle. + // Check the textureCoordinateRectangle. + var applicableRectangle = applicableRectangleScratch; - if (cameraPosition.longitude < southwest.rectangle.east) { - if (cameraPosition.latitude < southwest.rectangle.north) { - // Camera in southwest quadrant - visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); - visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); - visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); - visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); - } else { - // Camera in northwest quadrant - visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); - visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); - visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); - visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); + var epsilon = 1 / 1024; // 1/4 of a pixel in a typical 256x256 tile. + applicableRectangle.west = CesiumMath.lerp(pickedTile.rectangle.west, pickedTile.rectangle.east, terrainImagery.textureCoordinateRectangle.x - epsilon); + applicableRectangle.east = CesiumMath.lerp(pickedTile.rectangle.west, pickedTile.rectangle.east, terrainImagery.textureCoordinateRectangle.z + epsilon); + applicableRectangle.south = CesiumMath.lerp(pickedTile.rectangle.south, pickedTile.rectangle.north, terrainImagery.textureCoordinateRectangle.y - epsilon); + applicableRectangle.north = CesiumMath.lerp(pickedTile.rectangle.south, pickedTile.rectangle.north, terrainImagery.textureCoordinateRectangle.w + epsilon); + if (!Rectangle.contains(applicableRectangle, pickedLocation)) { + continue; } - } else if (cameraPosition.latitude < southwest.rectangle.north) { - // Camera southeast quadrant - visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); - visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); - visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); - visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); - } else { - // Camera in northeast quadrant - visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); - visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); - visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); - visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); - } - } - - function visitIfVisible(primitive, tile, tileProvider, frameState, occluders) { - if (tileProvider.computeTileVisibility(tile, frameState, occluders) !== Visibility.NONE) { - visitTile(primitive, frameState, tile); - } else { - ++primitive._debug.tilesCulled; - primitive._tileReplacementQueue.markTileRendered(tile); - } - } - /** - * Checks if the load queue length has changed since the last time we raised a queue change event - if so, raises - * a new one. - */ - function raiseTileLoadProgressEvent(primitive) { - var currentLoadQueueLength = primitive._tileLoadQueueHigh.length + primitive._tileLoadQueueMedium.length + primitive._tileLoadQueueLow.length; - - if (currentLoadQueueLength !== primitive._lastTileLoadQueueLength) { - primitive._tileLoadProgressEvent.raiseEvent(currentLoadQueueLength); - primitive._lastTileLoadQueueLength = currentLoadQueueLength; - } - } - - function screenSpaceError(primitive, frameState, tile) { - if (frameState.mode === SceneMode.SCENE2D || frameState.camera.frustum instanceof OrthographicFrustum) { - return screenSpaceError2D(primitive, frameState, tile); - } - - var maxGeometricError = primitive._tileProvider.getLevelMaximumGeometricError(tile.level); - - var distance = tile._distance; - var height = frameState.context.drawingBufferHeight; - var sseDenominator = frameState.camera.frustum.sseDenominator; - var error = (maxGeometricError * height) / (distance * sseDenominator); + var promise = provider.pickFeatures(imagery.x, imagery.y, imagery.level, pickedLocation.longitude, pickedLocation.latitude); + if (!defined(promise)) { + continue; + } - if (frameState.fog.enabled) { - error = error - CesiumMath.fog(distance, frameState.fog.density) * frameState.fog.sse; + promises.push(promise); + imageryLayers.push(imagery.imageryLayer); } - return error; - } - - function screenSpaceError2D(primitive, frameState, tile) { - var camera = frameState.camera; - var frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + if (promises.length === 0) { + return undefined; } - var context = frameState.context; - var width = context.drawingBufferWidth; - var height = context.drawingBufferHeight; + return when.all(promises, function(results) { + var features = []; - var maxGeometricError = primitive._tileProvider.getLevelMaximumGeometricError(tile.level); - var pixelSize = Math.max(frustum.top - frustum.bottom, frustum.right - frustum.left) / Math.max(width, height); - var error = maxGeometricError / pixelSize; + for (var resultIndex = 0; resultIndex < results.length; ++resultIndex) { + var result = results[resultIndex]; + var image = imageryLayers[resultIndex]; - if (frameState.fog.enabled && frameState.mode !== SceneMode.SCENE2D) { - error = error - CesiumMath.fog(tile._distance, frameState.fog.density) * frameState.fog.sse; - } + if (defined(result) && result.length > 0) { + for (var featureIndex = 0; featureIndex < result.length; ++featureIndex) { + var feature = result[featureIndex]; + feature.imageryLayer = image; - return error; - } + // For features without a position, use the picked location. + if (!defined(feature.position)) { + feature.position = pickedLocation; + } - function addTileToRenderList(primitive, tile) { - primitive._tilesToRender.push(tile); - ++primitive._debug.tilesRendered; - } + features.push(feature); + } + } + } - function processTileLoadQueue(primitive, frameState) { - var tileLoadQueueHigh = primitive._tileLoadQueueHigh; - var tileLoadQueueMedium = primitive._tileLoadQueueMedium; - var tileLoadQueueLow = primitive._tileLoadQueueLow; - var tileProvider = primitive._tileProvider; + return features; + }); + }; - if (tileLoadQueueHigh.length === 0 && tileLoadQueueMedium.length === 0 && tileLoadQueueLow.length === 0) { - return; + /** + * Updates frame state to execute any queued texture re-projections. + * + * @private + * + * @param {FrameState} frameState The frameState. + */ + ImageryLayerCollection.prototype.queueReprojectionCommands = function(frameState) { + var layers = this._layers; + for (var i = 0, len = layers.length; i < len; ++i) { + layers[i].queueReprojectionCommands(frameState); } + }; - // Remove any tiles that were not used this frame beyond the number - // we're allowed to keep. - primitive._tileReplacementQueue.trimTiles(primitive.tileCacheSize); - - var endTime = getTimestamp() + primitive._loadQueueTimeSlice; - - processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, tileLoadQueueHigh); - processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, tileLoadQueueMedium); - processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, tileLoadQueueLow); - } - - function processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, loadQueue) { - for (var i = 0, len = loadQueue.length; i < len && getTimestamp() < endTime; ++i) { - var tile = loadQueue[i]; - primitive._tileReplacementQueue.markTileRendered(tile); - tileProvider.loadTile(frameState, tile); + /** + * Cancels re-projection commands queued for the next frame. + * + * @private + */ + ImageryLayerCollection.prototype.cancelReprojections = function() { + var layers = this._layers; + for (var i = 0, len = layers.length; i < len; ++i) { + layers[i].cancelReprojections(); } - } - - var scratchRay = new Ray(); - var scratchCartographic = new Cartographic(); - var scratchPosition = new Cartesian3(); - - function updateHeights(primitive, frameState) { - var tilesToUpdateHeights = primitive._tileToUpdateHeights; - var terrainProvider = primitive._tileProvider.terrainProvider; - - var startTime = getTimestamp(); - var timeSlice = primitive._updateHeightsTimeSlice; - var endTime = startTime + timeSlice; - - var mode = frameState.mode; - var projection = frameState.mapProjection; - var ellipsoid = projection.ellipsoid; - - while (tilesToUpdateHeights.length > 0) { - var tile = tilesToUpdateHeights[0]; - var customData = tile.customData; - var customDataLength = customData.length; - - var timeSliceMax = false; - var i; - for (i = primitive._lastTileIndex; i < customDataLength; ++i) { - var data = customData[i]; - - if (tile.level > data.level) { - if (!defined(data.positionOnEllipsoidSurface)) { - // cartesian has to be on the ellipsoid surface for `ellipsoid.geodeticSurfaceNormal` - data.positionOnEllipsoidSurface = Cartesian3.fromRadians(data.positionCartographic.longitude, data.positionCartographic.latitude, 0.0, ellipsoid); - } - - if (mode === SceneMode.SCENE3D) { - var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.positionOnEllipsoidSurface, scratchRay.direction); - - // compute origin point - - // Try to find the intersection point between the surface normal and z-axis. - // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider - var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(data.positionOnEllipsoidSurface, 11500.0, scratchRay.origin); - - // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid - if (!defined(rayOrigin)) { - // intersection point is outside the ellipsoid, try other value - // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider - var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); + }; - // multiply by the *positive* value of the magnitude - var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); - Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); - } - } else { - Cartographic.clone(data.positionCartographic, scratchCartographic); + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see ImageryLayerCollection#destroy + */ + ImageryLayerCollection.prototype.isDestroyed = function() { + return false; + }; - // minimum height for the terrain set, need to get this information from the terrain provider - scratchCartographic.height = -11500.0; - projection.project(scratchCartographic, scratchPosition); - Cartesian3.fromElements(scratchPosition.z, scratchPosition.x, scratchPosition.y, scratchPosition); - Cartesian3.clone(scratchPosition, scratchRay.origin); - Cartesian3.clone(Cartesian3.UNIT_X, scratchRay.direction); - } + /** + * Destroys the WebGL resources held by all layers in this collection. Explicitly destroying this + * object allows for deterministic release of WebGL resources, instead of relying on the garbage + * collector. + * <br /><br /> + * Once this object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * layerCollection = layerCollection && layerCollection.destroy(); + * + * @see ImageryLayerCollection#isDestroyed + */ + ImageryLayerCollection.prototype.destroy = function() { + this.removeAll(true); + return destroyObject(this); + }; - var position = tile.data.pick(scratchRay, mode, projection, false, scratchPosition); - if (defined(position)) { - data.callback(position); - } + ImageryLayerCollection.prototype._update = function() { + var isBaseLayer = true; + var layers = this._layers; + var layersShownOrHidden; + var layer; + var i, len; + for (i = 0, len = layers.length; i < len; ++i) { + layer = layers[i]; - data.level = tile.level; - } else if (tile.level === data.level) { - var children = tile.children; - var childrenLength = children.length; + layer._layerIndex = i; - var child; - for (var j = 0; j < childrenLength; ++j) { - child = children[j]; - if (Rectangle.contains(child.rectangle, data.positionCartographic)) { - break; - } - } + if (layer.show) { + layer._isBaseLayer = isBaseLayer; + isBaseLayer = false; + } else { + layer._isBaseLayer = false; + } - var tileDataAvailable = terrainProvider.getTileDataAvailable(child.x, child.y, child.level); - var parentTile = tile.parent; - if ((defined(tileDataAvailable) && !tileDataAvailable) || - (defined(parentTile) && defined(parentTile.data) && defined(parentTile.data.terrainData) && - !parentTile.data.terrainData.isChildAvailable(parentTile.x, parentTile.y, child.x, child.y))) { - data.removeFunc(); + if (layer.show !== layer._show) { + if (defined(layer._show)) { + if (!defined(layersShownOrHidden)) { + layersShownOrHidden = []; } + layersShownOrHidden.push(layer); } - - if (getTimestamp() >= endTime) { - timeSliceMax = true; - break; - } + layer._show = layer.show; } + } - if (timeSliceMax) { - primitive._lastTileIndex = i; - break; - } else { - primitive._lastTileIndex = 0; - tilesToUpdateHeights.shift(); + if (defined(layersShownOrHidden)) { + for (i = 0, len = layersShownOrHidden.length; i < len; ++i) { + layer = layersShownOrHidden[i]; + this.layerShownOrHidden.raiseEvent(layer, layer._layerIndex, layer.show); } } - } + }; - function createRenderCommandsForSelectedTiles(primitive, frameState) { - var tileProvider = primitive._tileProvider; - var tilesToRender = primitive._tilesToRender; - var tilesToUpdateHeights = primitive._tileToUpdateHeights; + return ImageryLayerCollection; +}); - for (var i = 0, len = tilesToRender.length; i < len; ++i) { - var tile = tilesToRender[i]; - tileProvider.showTileThisFrame(tile, frameState); +define('Scene/QuadtreeOccluders',[ + '../Core/Cartesian3', + '../Core/defineProperties', + '../Core/EllipsoidalOccluder' + ], function( + Cartesian3, + defineProperties, + EllipsoidalOccluder) { + 'use strict'; - if (tile._frameRendered !== frameState.frameNumber - 1) { - tilesToUpdateHeights.push(tile); + /** + * A set of occluders that can be used to test quadtree tiles for occlusion. + * + * @alias QuadtreeOccluders + * @constructor + * @private + * + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid that potentially occludes tiles. + */ + function QuadtreeOccluders(options) { + this._ellipsoid = new EllipsoidalOccluder(options.ellipsoid, Cartesian3.ZERO); + } + + defineProperties(QuadtreeOccluders.prototype, { + /** + * Gets the {@link EllipsoidalOccluder} that can be used to determine if a point is + * occluded by an {@link Ellipsoid}. + * @type {EllipsoidalOccluder} + * @memberof QuadtreeOccluders.prototype + */ + ellipsoid : { + get : function() { + return this._ellipsoid; } - tile._frameRendered = frameState.frameNumber; } - } + }); - return QuadtreePrimitive; + return QuadtreeOccluders; }); -define('Scene/Globe',[ - '../Core/BoundingSphere', - '../Core/buildModuleUrl', - '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/defaultValue', +define('Scene/QuadtreeTile',[ '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/EllipsoidTerrainProvider', - '../Core/Event', - '../Core/IntersectionTests', - '../Core/loadImage', - '../Core/Ray', '../Core/Rectangle', - '../Renderer/ShaderSource', - '../Renderer/Texture', - '../Shaders/GlobeFS', - '../Shaders/GlobeVS', - '../Shaders/GroundAtmosphere', - '../ThirdParty/when', - './GlobeSurfaceShaderSet', - './GlobeSurfaceTileProvider', - './ImageryLayerCollection', - './Material', - './QuadtreePrimitive', - './SceneMode', - './ShadowMode' + './QuadtreeTileLoadState' ], function( - BoundingSphere, - buildModuleUrl, - Cartesian3, - Cartographic, - defaultValue, defined, defineProperties, - destroyObject, DeveloperError, - Ellipsoid, - EllipsoidTerrainProvider, - Event, - IntersectionTests, - loadImage, - Ray, Rectangle, - ShaderSource, - Texture, - GlobeFS, - GlobeVS, - GroundAtmosphere, - when, - GlobeSurfaceShaderSet, - GlobeSurfaceTileProvider, - ImageryLayerCollection, - Material, - QuadtreePrimitive, - SceneMode, - ShadowMode) { + QuadtreeTileLoadState) { 'use strict'; /** - * The globe rendered in the scene, including its terrain ({@link Globe#terrainProvider}) - * and imagery layers ({@link Globe#imageryLayers}). Access the globe using {@link Scene#globe}. + * A single tile in a {@link QuadtreePrimitive}. * - * @alias Globe + * @alias QuadtreeTile * @constructor + * @private * - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] Determines the size and shape of the - * globe. + * @param {Number} options.level The level of the tile in the quadtree. + * @param {Number} options.x The X coordinate of the tile in the quadtree. 0 is the westernmost tile. + * @param {Number} options.y The Y coordinate of the tile in the quadtree. 0 is the northernmost tile. + * @param {TilingScheme} options.tilingScheme The tiling scheme in which this tile exists. + * @param {QuadtreeTile} [options.parent] This tile's parent, or undefined if this is a root tile. */ - function Globe(ellipsoid) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - var terrainProvider = new EllipsoidTerrainProvider({ - ellipsoid : ellipsoid - }); - var imageryLayerCollection = new ImageryLayerCollection(); - - this._ellipsoid = ellipsoid; - this._imageryLayerCollection = imageryLayerCollection; + function QuadtreeTile(options) { + if (!defined(options)) { + throw new DeveloperError('options is required.'); + } + if (!defined(options.x)) { + throw new DeveloperError('options.x is required.'); + } else if (!defined(options.y)) { + throw new DeveloperError('options.y is required.'); + } else if (options.x < 0 || options.y < 0) { + throw new DeveloperError('options.x and options.y must be greater than or equal to zero.'); + } + if (!defined(options.level)) { + throw new DeveloperError('options.level is required and must be greater than or equal to zero.'); + } + if (!defined(options.tilingScheme)) { + throw new DeveloperError('options.tilingScheme is required.'); + } + + this._tilingScheme = options.tilingScheme; + this._x = options.x; + this._y = options.y; + this._level = options.level; + this._parent = options.parent; + this._rectangle = this._tilingScheme.tileXYToRectangle(this._x, this._y, this._level); - this._surfaceShaderSet = new GlobeSurfaceShaderSet(); - this._material = undefined; + this._southwestChild = undefined; + this._southeastChild = undefined; + this._northwestChild = undefined; + this._northeastChild = undefined; - this._surface = new QuadtreePrimitive({ - tileProvider : new GlobeSurfaceTileProvider({ - terrainProvider : terrainProvider, - imageryLayers : imageryLayerCollection, - surfaceShaderSet : this._surfaceShaderSet - }) - }); + // QuadtreeTileReplacementQueue gets/sets these private properties. + this._replacementPrevious = undefined; + this._replacementNext = undefined; - this._terrainProvider = terrainProvider; - this._terrainProviderChanged = new Event(); + // The distance from the camera to this tile, updated when the tile is selected + // for rendering. We can get rid of this if we have a better way to sort by + // distance - for example, by using the natural ordering of a quadtree. + // QuadtreePrimitive gets/sets this private property. + this._distance = 0.0; + this._priorityFunction = undefined; - makeShadersDirty(this); + this._customData = []; + this._frameUpdated = undefined; + this._frameRendered = undefined; + this._loadedCallbacks = {}; /** - * Determines if the globe will be shown. - * - * @type {Boolean} - * @default true + * Gets or sets the current state of the tile in the tile load pipeline. + * @type {QuadtreeTileLoadState} + * @default {@link QuadtreeTileLoadState.START} */ - this.show = true; + this.state = QuadtreeTileLoadState.START; /** - * The normal map to use for rendering waves in the ocean. Setting this property will - * only have an effect if the configured terrain provider includes a water mask. - * - * @type {String} - * @default buildModuleUrl('Assets/Textures/waterNormalsSmall.jpg') + * Gets or sets a value indicating whether or not the tile is currently renderable. + * @type {Boolean} + * @default false */ - this.oceanNormalMapUrl = buildModuleUrl('Assets/Textures/waterNormalsSmall.jpg'); - this._oceanNormalMapUrl = undefined; + this.renderable = false; /** - * The maximum screen-space error used to drive level-of-detail refinement. Higher - * values will provide better performance but lower visual quality. - * - * @type {Number} - * @default 2 + * Gets or set a value indicating whether or not the tile was entire upsampled from its + * parent tile. If all four children of a parent tile were upsampled from the parent, + * we will render the parent instead of the children even if the LOD indicates that + * the children would be preferable. + * @type {Boolean} + * @default false */ - this.maximumScreenSpaceError = 2; + this.upsampledFromParent = false; /** - * The size of the terrain tile cache, expressed as a number of tiles. Any additional - * tiles beyond this number will be freed, as long as they aren't needed for rendering - * this frame. A larger number will consume more memory but will show detail faster - * when, for example, zooming out and then back in. - * - * @type {Number} - * @default 100 + * Gets or sets the additional data associated with this tile. The exact content is specific to the + * {@link QuadtreeTileProvider}. + * @type {Object} + * @default undefined */ - this.tileCacheSize = 100; + this.data = undefined; + } + + /** + * Creates a rectangular set of tiles for level of detail zero, the coarsest, least detailed level. + * + * @memberof QuadtreeTile + * + * @param {TilingScheme} tilingScheme The tiling scheme for which the tiles are to be created. + * @returns {QuadtreeTile[]} An array containing the tiles at level of detail zero, starting with the + * tile in the northwest corner and followed by the tile (if any) to its east. + */ + QuadtreeTile.createLevelZeroTiles = function(tilingScheme) { + if (!defined(tilingScheme)) { + throw new DeveloperError('tilingScheme is required.'); + } + + var numberOfLevelZeroTilesX = tilingScheme.getNumberOfXTilesAtLevel(0); + var numberOfLevelZeroTilesY = tilingScheme.getNumberOfYTilesAtLevel(0); + + var result = new Array(numberOfLevelZeroTilesX * numberOfLevelZeroTilesY); + + var index = 0; + for (var y = 0; y < numberOfLevelZeroTilesY; ++y) { + for (var x = 0; x < numberOfLevelZeroTilesX; ++x) { + result[index++] = new QuadtreeTile({ + tilingScheme : tilingScheme, + x : x, + y : y, + level : 0 + }); + } + } + + return result; + }; + + QuadtreeTile.prototype._updateCustomData = function(frameNumber, added, removed) { + var customData = this.customData; + + var i; + var data; + var rectangle; + + if (defined(added) && defined(removed)) { + customData = customData.filter(function(value) { + return removed.indexOf(value) === -1; + }); + this._customData = customData; + + rectangle = this._rectangle; + for (i = 0; i < added.length; ++i) { + data = added[i]; + if (Rectangle.contains(rectangle, data.positionCartographic)) { + customData.push(data); + } + } + + this._frameUpdated = frameNumber; + } else { + // interior or leaf tile, update from parent + var parent = this._parent; + if (defined(parent) && this._frameUpdated !== parent._frameUpdated) { + customData.length = 0; + + rectangle = this._rectangle; + var parentCustomData = parent.customData; + for (i = 0; i < parentCustomData.length; ++i) { + data = parentCustomData[i]; + if (Rectangle.contains(rectangle, data.positionCartographic)) { + customData.push(data); + } + } + + this._frameUpdated = parent._frameUpdated; + } + } + }; + defineProperties(QuadtreeTile.prototype, { /** - * Enable lighting the globe with the sun as a light source. - * - * @type {Boolean} - * @default false + * Gets the tiling scheme used to tile the surface. + * @memberof QuadtreeTile.prototype + * @type {TilingScheme} */ - this.enableLighting = false; + tilingScheme : { + get : function() { + return this._tilingScheme; + } + }, /** - * The distance where everything becomes lit. This only takes effect - * when <code>enableLighting</code> is <code>true</code>. - * + * Gets the tile X coordinate. + * @memberof QuadtreeTile.prototype * @type {Number} - * @default 6500000.0 */ - this.lightingFadeOutDistance = 6500000.0; + x : { + get : function() { + return this._x; + } + }, /** - * The distance where lighting resumes. This only takes effect - * when <code>enableLighting</code> is <code>true</code>. - * + * Gets the tile Y coordinate. + * @memberof QuadtreeTile.prototype * @type {Number} - * @default 9000000.0 */ - this.lightingFadeInDistance = 9000000.0; + y : { + get : function() { + return this._y; + } + }, /** - * True if an animated wave effect should be shown in areas of the globe - * covered by water; otherwise, false. This property is ignored if the - * <code>terrainProvider</code> does not provide a water mask. - * - * @type {Boolean} - * @default true + * Gets the level-of-detail, where zero is the coarsest, least-detailed. + * @memberof QuadtreeTile.prototype + * @type {Number} */ - this.showWaterEffect = true; + level : { + get : function() { + return this._level; + } + }, /** - * True if primitives such as billboards, polylines, labels, etc. should be depth-tested - * against the terrain surface, or false if such primitives should always be drawn on top - * of terrain unless they're on the opposite side of the globe. The disadvantage of depth - * testing primitives against terrain is that slight numerical noise or terrain level-of-detail - * switched can sometimes make a primitive that should be on the surface disappear underneath it. - * - * @type {Boolean} - * @default false - * + * Gets the parent tile of this tile. + * @memberof QuadtreeTile.prototype + * @type {QuadtreeTile} */ - this.depthTestAgainstTerrain = false; + parent : { + get : function() { + return this._parent; + } + }, /** - * Determines whether the globe casts or receives shadows from each light source. Setting the globe - * to cast shadows may impact performance since the terrain is rendered again from the light's perspective. - * Currently only terrain that is in view casts shadows. By default the globe does not cast shadows. - * - * @type {ShadowMode} - * @default ShadowMode.RECEIVE_ONLY + * Gets the cartographic rectangle of the tile, with north, south, east and + * west properties in radians. + * @memberof QuadtreeTile.prototype + * @type {Rectangle} */ - this.shadows = ShadowMode.RECEIVE_ONLY; - - this._oceanNormalMap = undefined; - this._zoomedOutOceanSpecularIntensity = 0.5; - } + rectangle : { + get : function() { + return this._rectangle; + } + }, - defineProperties(Globe.prototype, { /** - * Gets an ellipsoid describing the shape of this globe. - * @memberof Globe.prototype - * @type {Ellipsoid} + * An array of tiles that is at the next level of the tile tree. + * @memberof QuadtreeTile.prototype + * @type {QuadtreeTile[]} */ - ellipsoid : { + children : { get : function() { - return this._ellipsoid; + return [this.northwestChild, this.northeastChild, this.southwestChild, this.southeastChild]; } }, + /** - * Gets the collection of image layers that will be rendered on this globe. - * @memberof Globe.prototype - * @type {ImageryLayerCollection} + * Gets the southwest child tile. + * @memberof QuadtreeTile.prototype + * @type {QuadtreeTile} */ - imageryLayers : { + southwestChild : { get : function() { - return this._imageryLayerCollection; + if (!defined(this._southwestChild)) { + this._southwestChild = new QuadtreeTile({ + tilingScheme : this.tilingScheme, + x : this.x * 2, + y : this.y * 2 + 1, + level : this.level + 1, + parent : this + }); + } + return this._southwestChild; } }, + /** - * Gets or sets the color of the globe when no imagery is available. - * @memberof Globe.prototype - * @type {Color} + * Gets the southeast child tile. + * @memberof QuadtreeTile.prototype + * @type {QuadtreeTile} */ - baseColor : { + southeastChild : { get : function() { - return this._surface.tileProvider.baseColor; - }, - set : function(value) { - this._surface.tileProvider.baseColor = value; + if (!defined(this._southeastChild)) { + this._southeastChild = new QuadtreeTile({ + tilingScheme : this.tilingScheme, + x : this.x * 2 + 1, + y : this.y * 2 + 1, + level : this.level + 1, + parent : this + }); + } + return this._southeastChild; } }, + /** - * A property specifying a {@link ClippingPlaneCollection} used to selectively disable rendering on the outside of each plane. Clipping planes are not currently supported in Internet Explorer. - * - * @memberof Globe.prototype - * @type {ClippingPlaneCollection} + * Gets the northwest child tile. + * @memberof QuadtreeTile.prototype + * @type {QuadtreeTile} */ - clippingPlanes : { + northwestChild : { get : function() { - return this._surface.tileProvider.clippingPlanes; - }, - set : function(value) { - this._surface.tileProvider.clippingPlanes = value; + if (!defined(this._northwestChild)) { + this._northwestChild = new QuadtreeTile({ + tilingScheme : this.tilingScheme, + x : this.x * 2, + y : this.y * 2, + level : this.level + 1, + parent : this + }); + } + return this._northwestChild; } }, + /** - * The terrain provider providing surface geometry for this globe. - * @type {TerrainProvider} - * - * @memberof Globe.prototype - * @type {TerrainProvider} - * + * Gets the northeast child tile. + * @memberof QuadtreeTile.prototype + * @type {QuadtreeTile} */ - terrainProvider : { + northeastChild : { get : function() { - return this._terrainProvider; - }, - set : function(value) { - if (value !== this._terrainProvider) { - this._terrainProvider = value; - this._terrainProviderChanged.raiseEvent(value); - if (defined(this._material)) { - makeShadersDirty(this); - } + if (!defined(this._northeastChild)) { + this._northeastChild = new QuadtreeTile({ + tilingScheme : this.tilingScheme, + x : this.x * 2 + 1, + y : this.y * 2, + level : this.level + 1, + parent : this + }); } + return this._northeastChild; } }, + /** - * Gets an event that's raised when the terrain provider is changed - * - * @memberof Globe.prototype - * @type {Event} - * @readonly + * An array of objects associated with this tile. + * @memberof QuadtreeTile.prototype + * @type {Array} */ - terrainProviderChanged : { - get: function() { - return this._terrainProviderChanged; + customData : { + get : function() { + return this._customData; } }, + /** - * Gets an event that's raised when the length of the tile load queue has changed since the last render frame. When the load queue is empty, - * all terrain and imagery for the current view have been loaded. The event passes the new length of the tile load queue. - * - * @memberof Globe.prototype - * @type {Event} + * Gets a value indicating whether or not this tile needs further loading. + * This property will return true if the {@link QuadtreeTile#state} is + * <code>START</code> or <code>LOADING</code>. + * @memberof QuadtreeTile.prototype + * @type {Boolean} */ - tileLoadProgressEvent : { - get: function() { - return this._surface.tileLoadProgressEvent; + needsLoading : { + get : function() { + return this.state < QuadtreeTileLoadState.DONE; } }, /** - * Gets or sets the material appearance of the Globe. This can be one of several built-in {@link Material} objects or a custom material, scripted with - * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}. - * @memberof Globe.prototype - * @type {Material} + * Gets a value indicating whether or not this tile is eligible to be unloaded. + * Typically, a tile is ineligible to be unloaded while an asynchronous operation, + * such as a request for data, is in progress on it. A tile will never be + * unloaded while it is needed for rendering, regardless of the value of this + * property. If {@link QuadtreeTile#data} is defined and has an + * <code>eligibleForUnloading</code> property, the value of that property is returned. + * Otherwise, this property returns true. + * @memberof QuadtreeTile.prototype + * @type {Boolean} */ - material: { - get: function() { - return this._material; - }, - set: function(material) { - if (this._material !== material) { - this._material = material; - makeShadersDirty(this); + eligibleForUnloading : { + get : function() { + var result = true; + + if (defined(this.data)) { + result = this.data.eligibleForUnloading; + if (!defined(result)) { + result = true; + } } + + return result; } } }); - function makeShadersDirty(globe) { - var defines = []; - - var requireNormals = defined(globe._material) && (globe._material.shaderSource.match(/slope/) || globe._material.shaderSource.match('normalEC')); + /** + * Frees the resources associated with this tile and returns it to the <code>START</code> + * {@link QuadtreeTileLoadState}. If the {@link QuadtreeTile#data} property is defined and it + * has a <code>freeResources</code> method, the method will be invoked. + * + * @memberof QuadtreeTile + */ + QuadtreeTile.prototype.freeResources = function() { + this.state = QuadtreeTileLoadState.START; + this.renderable = false; + this.upsampledFromParent = false; - var fragmentSources = []; - if (defined(globe._material) && (!requireNormals || globe._terrainProvider.requestVertexNormals)) { - fragmentSources.push(globe._material.shaderSource); - defines.push('APPLY_MATERIAL'); - globe._surface._tileProvider.uniformMap = globe._material._uniforms; - } else { - globe._surface._tileProvider.uniformMap = undefined; + if (defined(this.data) && defined(this.data.freeResources)) { + this.data.freeResources(); } - fragmentSources.push(GlobeFS); - globe._surfaceShaderSet.baseVertexShaderSource = new ShaderSource({ - sources : [GroundAtmosphere, GlobeVS], - defines : defines - }); + freeTile(this._southwestChild); + this._southwestChild = undefined; + freeTile(this._southeastChild); + this._southeastChild = undefined; + freeTile(this._northwestChild); + this._northwestChild = undefined; + freeTile(this._northeastChild); + this._northeastChild = undefined; + }; - globe._surfaceShaderSet.baseFragmentShaderSource = new ShaderSource({ - sources : fragmentSources, - defines : defines - }); - globe._surfaceShaderSet.material = globe._material; + function freeTile(tile) { + if (defined(tile)) { + tile.freeResources(); + } } - function createComparePickTileFunction(rayOrigin) { - return function(a, b) { - var aDist = BoundingSphere.distanceSquaredTo(a.pickBoundingSphere, rayOrigin); - var bDist = BoundingSphere.distanceSquaredTo(b.pickBoundingSphere, rayOrigin); + return QuadtreeTile; +}); - return aDist - bDist; - }; +define('Scene/TileReplacementQueue',[ + '../Core/defined' + ], function( + defined) { + 'use strict'; + + /** + * A priority queue of tiles to be replaced, if necessary, to make room for new tiles. The queue + * is implemented as a linked list. + * + * @alias TileReplacementQueue + * @private + */ + function TileReplacementQueue() { + this.head = undefined; + this.tail = undefined; + this.count = 0; + this._lastBeforeStartOfFrame = undefined; } - var scratchArray = []; - var scratchSphereIntersectionResult = { - start : 0.0, - stop : 0.0 + /** + * Marks the start of the render frame. Tiles before (closer to the head) this tile in the + * list were used last frame and must not be unloaded. + */ + TileReplacementQueue.prototype.markStartOfRenderFrame = function() { + this._lastBeforeStartOfFrame = this.head; }; /** - * Find an intersection between a ray and the globe surface that was rendered. The ray must be given in world coordinates. - * - * @param {Ray} ray The ray to test for intersection. - * @param {Scene} scene The scene. - * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3|undefined} The intersection or <code>undefined</code> if none was found. + * Reduces the size of the queue to a specified size by unloading the least-recently used + * tiles. Tiles that were used last frame will not be unloaded, even if that puts the number + * of tiles above the specified maximum. * - * @example - * // find intersection of ray through a pixel and the globe - * var ray = viewer.camera.getPickRay(windowCoordinates); - * var intersection = globe.pick(ray, scene); + * @param {Number} maximumTiles The maximum number of tiles in the queue. */ - Globe.prototype.pick = function(ray, scene, result) { - if (!defined(ray)) { - throw new DeveloperError('ray is required'); - } - if (!defined(scene)) { - throw new DeveloperError('scene is required'); + TileReplacementQueue.prototype.trimTiles = function(maximumTiles) { + var tileToTrim = this.tail; + var keepTrimming = true; + while (keepTrimming && + defined(this._lastBeforeStartOfFrame) && + this.count > maximumTiles && + defined(tileToTrim)) { + // Stop trimming after we process the last tile not used in the + // current frame. + keepTrimming = tileToTrim !== this._lastBeforeStartOfFrame; + + var previous = tileToTrim.replacementPrevious; + + if (tileToTrim.eligibleForUnloading) { + tileToTrim.freeResources(); + remove(this, tileToTrim); + } + + tileToTrim = previous; } - - var mode = scene.mode; - var projection = scene.mapProjection; + }; - var sphereIntersections = scratchArray; - sphereIntersections.length = 0; + function remove(tileReplacementQueue, item) { + var previous = item.replacementPrevious; + var next = item.replacementNext; - var tilesToRender = this._surface._tilesToRender; - var length = tilesToRender.length; + if (item === tileReplacementQueue._lastBeforeStartOfFrame) { + tileReplacementQueue._lastBeforeStartOfFrame = next; + } - var tile; - var i; + if (item === tileReplacementQueue.head) { + tileReplacementQueue.head = next; + } else { + previous.replacementNext = next; + } - for (i = 0; i < length; ++i) { - tile = tilesToRender[i]; - var tileData = tile.data; + if (item === tileReplacementQueue.tail) { + tileReplacementQueue.tail = previous; + } else { + next.replacementPrevious = previous; + } - if (!defined(tileData)) { - continue; - } + item.replacementPrevious = undefined; + item.replacementNext = undefined; - var boundingVolume = tileData.pickBoundingSphere; - if (mode !== SceneMode.SCENE3D) { - BoundingSphere.fromRectangleWithHeights2D(tile.rectangle, projection, tileData.minimumHeight, tileData.maximumHeight, boundingVolume); - Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); - } else { - BoundingSphere.clone(tileData.boundingSphere3D, boundingVolume); - } + --tileReplacementQueue.count; + } - var boundingSphereIntersection = IntersectionTests.raySphere(ray, boundingVolume, scratchSphereIntersectionResult); - if (defined(boundingSphereIntersection)) { - sphereIntersections.push(tileData); + /** + * Marks a tile as rendered this frame and moves it before the first tile that was not rendered + * this frame. + * + * @param {TileReplacementQueue} item The tile that was rendered. + */ + TileReplacementQueue.prototype.markTileRendered = function(item) { + var head = this.head; + if (head === item) { + if (item === this._lastBeforeStartOfFrame) { + this._lastBeforeStartOfFrame = item.replacementNext; } + return; } - sphereIntersections.sort(createComparePickTileFunction(ray.origin)); + ++this.count; - var intersection; - length = sphereIntersections.length; - for (i = 0; i < length; ++i) { - intersection = sphereIntersections[i].pick(ray, scene.mode, scene.mapProjection, true, result); - if (defined(intersection)) { - break; - } + if (!defined(head)) { + // no other tiles in the list + item.replacementPrevious = undefined; + item.replacementNext = undefined; + this.head = item; + this.tail = item; + return; } - return intersection; + if (defined(item.replacementPrevious) || defined(item.replacementNext)) { + // tile already in the list, remove from its current location + remove(this, item); + } + + item.replacementPrevious = undefined; + item.replacementNext = head; + head.replacementPrevious = item; + + this.head = item; }; - var scratchGetHeightCartesian = new Cartesian3(); - var scratchGetHeightIntersection = new Cartesian3(); - var scratchGetHeightCartographic = new Cartographic(); - var scratchGetHeightRay = new Ray(); + return TileReplacementQueue; +}); - function tileIfContainsCartographic(tile, cartographic) { - return Rectangle.contains(tile.rectangle, cartographic) ? tile : undefined; - } +define('Scene/QuadtreePrimitive',[ + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/Event', + '../Core/getTimestamp', + '../Core/Math', + '../Core/OrthographicFrustum', + '../Core/Ray', + '../Core/Rectangle', + '../Core/Visibility', + './QuadtreeOccluders', + './QuadtreeTile', + './QuadtreeTileLoadState', + './SceneMode', + './TileReplacementQueue' + ], function( + Cartesian3, + Cartographic, + defaultValue, + defined, + defineProperties, + DeveloperError, + Event, + getTimestamp, + CesiumMath, + OrthographicFrustum, + Ray, + Rectangle, + Visibility, + QuadtreeOccluders, + QuadtreeTile, + QuadtreeTileLoadState, + SceneMode, + TileReplacementQueue) { + 'use strict'; /** - * Get the height of the surface at a given cartographic. + * Renders massive sets of data by utilizing level-of-detail and culling. The globe surface is divided into + * a quadtree of tiles with large, low-detail tiles at the root and small, high-detail tiles at the leaves. + * The set of tiles to render is selected by projecting an estimate of the geometric error in a tile onto + * the screen to estimate screen-space error, in pixels, which must be below a user-specified threshold. + * The actual content of the tiles is arbitrary and is specified using a {@link QuadtreeTileProvider}. * - * @param {Cartographic} cartographic The cartographic for which to find the height. - * @returns {Number|undefined} The height of the cartographic or undefined if it could not be found. + * @alias QuadtreePrimitive + * @constructor + * @private + * + * @param {QuadtreeTileProvider} options.tileProvider The tile provider that loads, renders, and estimates + * the distance to individual tiles. + * @param {Number} [options.maximumScreenSpaceError=2] The maximum screen-space error, in pixels, that is allowed. + * A higher maximum error will render fewer tiles and improve performance, while a lower + * value will improve visual quality. + * @param {Number} [options.tileCacheSize=100] The maximum number of tiles that will be retained in the tile cache. + * Note that tiles will never be unloaded if they were used for rendering the last + * frame, so the actual number of resident tiles may be higher. The value of + * this property will not affect visual quality. */ - Globe.prototype.getHeight = function(cartographic) { - if (!defined(cartographic)) { - throw new DeveloperError('cartographic is required'); + function QuadtreePrimitive(options) { + if (!defined(options) || !defined(options.tileProvider)) { + throw new DeveloperError('options.tileProvider is required.'); } - - var levelZeroTiles = this._surface._levelZeroTiles; - if (!defined(levelZeroTiles)) { - return; + if (defined(options.tileProvider.quadtree)) { + throw new DeveloperError('A QuadtreeTileProvider can only be used with a single QuadtreePrimitive'); } + + this._tileProvider = options.tileProvider; + this._tileProvider.quadtree = this; - var tile; - var i; + this._debug = { + enableDebugOutput : false, - var length = levelZeroTiles.length; - for (i = 0; i < length; ++i) { - tile = levelZeroTiles[i]; - if (Rectangle.contains(tile.rectangle, cartographic)) { - break; + maxDepth : 0, + tilesVisited : 0, + tilesCulled : 0, + tilesRendered : 0, + tilesWaitingForChildren : 0, + + lastMaxDepth : -1, + lastTilesVisited : -1, + lastTilesCulled : -1, + lastTilesRendered : -1, + lastTilesWaitingForChildren : -1, + + suspendLodUpdate : false + }; + + var tilingScheme = this._tileProvider.tilingScheme; + var ellipsoid = tilingScheme.ellipsoid; + + this._tilesToRender = []; + this._tileLoadQueueHigh = []; // high priority tiles are preventing refinement + this._tileLoadQueueMedium = []; // medium priority tiles are being rendered + this._tileLoadQueueLow = []; // low priority tiles were refined past or are non-visible parts of quads. + this._tileReplacementQueue = new TileReplacementQueue(); + this._levelZeroTiles = undefined; + this._loadQueueTimeSlice = 5.0; + + this._addHeightCallbacks = []; + this._removeHeightCallbacks = []; + + this._tileToUpdateHeights = []; + this._lastTileIndex = 0; + this._updateHeightsTimeSlice = 2.0; + + /** + * Gets or sets the maximum screen-space error, in pixels, that is allowed. + * A higher maximum error will render fewer tiles and improve performance, while a lower + * value will improve visual quality. + * @type {Number} + * @default 2 + */ + this.maximumScreenSpaceError = defaultValue(options.maximumScreenSpaceError, 2); + + /** + * Gets or sets the maximum number of tiles that will be retained in the tile cache. + * Note that tiles will never be unloaded if they were used for rendering the last + * frame, so the actual number of resident tiles may be higher. The value of + * this property will not affect visual quality. + * @type {Number} + * @default 100 + */ + this.tileCacheSize = defaultValue(options.tileCacheSize, 100); + + this._occluders = new QuadtreeOccluders({ + ellipsoid : ellipsoid + }); + + this._tileLoadProgressEvent = new Event(); + this._lastTileLoadQueueLength = 0; + } + + defineProperties(QuadtreePrimitive.prototype, { + /** + * Gets the provider of {@link QuadtreeTile} instances for this quadtree. + * @type {QuadtreeTile} + * @memberof QuadtreePrimitive.prototype + */ + tileProvider : { + get : function() { + return this._tileProvider; + } + }, + /** + * Gets an event that's raised when the length of the tile load queue has changed since the last render frame. When the load queue is empty, + * all terrain and imagery for the current view have been loaded. The event passes the new length of the tile load queue. + * + * @memberof QuadtreePrimitive.prototype + * @type {Event} + */ + tileLoadProgressEvent : { + get : function() { + return this._tileLoadProgressEvent; } } + }); - if (!defined(tile) || !Rectangle.contains(tile.rectangle, cartographic)) { - return undefined; - } + /** + * Invalidates and frees all the tiles in the quadtree. The tiles must be reloaded + * before they can be displayed. + * + * @memberof QuadtreePrimitive + */ + QuadtreePrimitive.prototype.invalidateAllTiles = function() { + // Clear the replacement queue + var replacementQueue = this._tileReplacementQueue; + replacementQueue.head = undefined; + replacementQueue.tail = undefined; + replacementQueue.count = 0; - while (tile.renderable) { - tile = tileIfContainsCartographic(tile.southwestChild, cartographic) || - tileIfContainsCartographic(tile.southeastChild, cartographic) || - tileIfContainsCartographic(tile.northwestChild, cartographic) || - tile.northeastChild; - } + clearTileLoadQueue(this); - while (defined(tile) && (!defined(tile.data) || !defined(tile.data.pickTerrain))) { - tile = tile.parent; - } + // Free and recreate the level zero tiles. + var levelZeroTiles = this._levelZeroTiles; + if (defined(levelZeroTiles)) { + for (var i = 0; i < levelZeroTiles.length; ++i) { + var tile = levelZeroTiles[i]; + var customData = tile.customData; + var customDataLength = customData.length; - if (!defined(tile)) { - return undefined; + for (var j = 0; j < customDataLength; ++j) { + var data = customData[j]; + data.level = 0; + this._addHeightCallbacks.push(data); + } + + levelZeroTiles[i].freeResources(); + } } - var ellipsoid = this._surface._tileProvider.tilingScheme.ellipsoid; + this._levelZeroTiles = undefined; - //cartesian has to be on the ellipsoid surface for `ellipsoid.geodeticSurfaceNormal` - var cartesian = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0, ellipsoid, scratchGetHeightCartesian); + this._tileProvider.cancelReprojections(); + }; - var ray = scratchGetHeightRay; - var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesian, ray.direction); + /** + * Invokes a specified function for each {@link QuadtreeTile} that is partially + * or completely loaded. + * + * @param {Function} tileFunction The function to invoke for each loaded tile. The + * function is passed a reference to the tile as its only parameter. + */ + QuadtreePrimitive.prototype.forEachLoadedTile = function(tileFunction) { + var tile = this._tileReplacementQueue.head; + while (defined(tile)) { + if (tile.state !== QuadtreeTileLoadState.START) { + tileFunction(tile); + } + tile = tile.replacementNext; + } + }; - // Try to find the intersection point between the surface normal and z-axis. - // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider - var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian, 11500.0, ray.origin); + /** + * Invokes a specified function for each {@link QuadtreeTile} that was rendered + * in the most recent frame. + * + * @param {Function} tileFunction The function to invoke for each rendered tile. The + * function is passed a reference to the tile as its only parameter. + */ + QuadtreePrimitive.prototype.forEachRenderedTile = function(tileFunction) { + var tilesRendered = this._tilesToRender; + for (var i = 0, len = tilesRendered.length; i < len; ++i) { + tileFunction(tilesRendered[i]); + } + }; - // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid - if (!defined(rayOrigin)) { - // intersection point is outside the ellipsoid, try other value - // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider - var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); + /** + * Calls the callback when a new tile is rendered that contains the given cartographic. The only parameter + * is the cartesian position on the tile. + * + * @param {Cartographic} cartographic The cartographic position. + * @param {Function} callback The function to be called when a new tile is loaded containing cartographic. + * @returns {Function} The function to remove this callback from the quadtree. + */ + QuadtreePrimitive.prototype.updateHeight = function(cartographic, callback) { + var primitive = this; + var object = { + positionOnEllipsoidSurface : undefined, + positionCartographic : cartographic, + level : -1, + callback : callback + }; + + object.removeFunc = function() { + var addedCallbacks = primitive._addHeightCallbacks; + var length = addedCallbacks.length; + for (var i = 0; i < length; ++i) { + if (addedCallbacks[i] === object) { + addedCallbacks.splice(i, 1); + break; + } + } + primitive._removeHeightCallbacks.push(object); + }; + + primitive._addHeightCallbacks.push(object); + return object.removeFunc; + }; - // multiply by the *positive* value of the magnitude - var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchGetHeightIntersection); - Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); + /** + * Updates the tile provider imagery and continues to process the tile load queue. + * @private + */ + QuadtreePrimitive.prototype.update = function(frameState) { + if (defined(this._tileProvider.update)) { + this._tileProvider.update(frameState); } + }; - var intersection = tile.data.pick(ray, undefined, undefined, false, scratchGetHeightIntersection); - if (!defined(intersection)) { - return undefined; - } + function clearTileLoadQueue(primitive) { + var debug = primitive._debug; + debug.maxDepth = 0; + debug.tilesVisited = 0; + debug.tilesCulled = 0; + debug.tilesRendered = 0; + debug.tilesWaitingForChildren = 0; - return ellipsoid.cartesianToCartographic(intersection, scratchGetHeightCartographic).height; - }; + primitive._tileLoadQueueHigh.length = 0; + primitive._tileLoadQueueMedium.length = 0; + primitive._tileLoadQueueLow.length = 0; + } /** + * Initializes values for a new render frame and prepare the tile load queue. * @private */ - Globe.prototype.beginFrame = function(frameState) { - if (!this.show) { + QuadtreePrimitive.prototype.beginFrame = function(frameState) { + var passes = frameState.passes; + if (!passes.render) { return; } - var surface = this._surface; - var tileProvider = surface.tileProvider; - var terrainProvider = this.terrainProvider; - var hasWaterMask = this.showWaterEffect && terrainProvider.ready && terrainProvider.hasWaterMask; - - if (hasWaterMask && this.oceanNormalMapUrl !== this._oceanNormalMapUrl) { - // url changed, load new normal map asynchronously - var oceanNormalMapUrl = this.oceanNormalMapUrl; - this._oceanNormalMapUrl = oceanNormalMapUrl; - - if (defined(oceanNormalMapUrl)) { - var that = this; - when(loadImage(oceanNormalMapUrl), function(image) { - if (oceanNormalMapUrl !== that.oceanNormalMapUrl) { - // url changed while we were loading - return; - } + // Gets commands for any texture re-projections + this._tileProvider.initialize(frameState); - that._oceanNormalMap = that._oceanNormalMap && that._oceanNormalMap.destroy(); - that._oceanNormalMap = new Texture({ - context : frameState.context, - source : image - }); - }); - } else { - this._oceanNormalMap = this._oceanNormalMap && this._oceanNormalMap.destroy(); - } + if (this._debug.suspendLodUpdate) { + return; } - var mode = frameState.mode; - var pass = frameState.passes; + clearTileLoadQueue(this); + this._tileReplacementQueue.markStartOfRenderFrame(); + }; - if (pass.render) { - // Don't show the ocean specular highlights when zoomed out in 2D and Columbus View. - if (mode === SceneMode.SCENE3D) { - this._zoomedOutOceanSpecularIntensity = 0.5; - } else { - this._zoomedOutOceanSpecularIntensity = 0.0; - } + /** + * Selects new tiles to load based on the frame state and creates render commands. + * @private + */ + QuadtreePrimitive.prototype.render = function(frameState) { + var passes = frameState.passes; + var tileProvider = this._tileProvider; - surface.maximumScreenSpaceError = this.maximumScreenSpaceError; - surface.tileCacheSize = this.tileCacheSize; + if (passes.render) { + tileProvider.beginUpdate(frameState); - tileProvider.terrainProvider = this.terrainProvider; - tileProvider.lightingFadeOutDistance = this.lightingFadeOutDistance; - tileProvider.lightingFadeInDistance = this.lightingFadeInDistance; - tileProvider.zoomedOutOceanSpecularIntensity = this._zoomedOutOceanSpecularIntensity; - tileProvider.hasWaterMask = hasWaterMask; - tileProvider.oceanNormalMap = this._oceanNormalMap; - tileProvider.enableLighting = this.enableLighting; - tileProvider.shadows = this.shadows; + selectTilesForRendering(this, frameState); + createRenderCommandsForSelectedTiles(this, frameState); - surface.beginFrame(frameState); + tileProvider.endUpdate(frameState); + } + + if (passes.pick && this._tilesToRender.length > 0) { + tileProvider.updateForPick(frameState); } }; /** - * @private + * Checks if the load queue length has changed since the last time we raised a queue change event - if so, raises + * a new change event at the end of the render cycle. */ - Globe.prototype.update = function(frameState) { - if (!this.show) { - return; - } + function updateTileLoadProgress(primitive, frameState) { + var currentLoadQueueLength = primitive._tileLoadQueueHigh.length + primitive._tileLoadQueueMedium.length + primitive._tileLoadQueueLow.length; - if (defined(this._material)) { - this._material.update(frameState.context); + if (currentLoadQueueLength !== primitive._lastTileLoadQueueLength) { + frameState.afterRender.push(Event.prototype.raiseEvent.bind(primitive._tileLoadProgressEvent, currentLoadQueueLength)); + primitive._lastTileLoadQueueLength = currentLoadQueueLength; } - var surface = this._surface; - var pass = frameState.passes; + var debug = primitive._debug; + if (debug.enableDebugOutput && !debug.suspendLodUpdate) { + if (debug.tilesVisited !== debug.lastTilesVisited || + debug.tilesRendered !== debug.lastTilesRendered || + debug.tilesCulled !== debug.lastTilesCulled || + debug.maxDepth !== debug.lastMaxDepth || + debug.tilesWaitingForChildren !== debug.lastTilesWaitingForChildren) { - if (pass.render) { - surface.update(frameState); - } + console.log('Visited ' + debug.tilesVisited + ', Rendered: ' + debug.tilesRendered + ', Culled: ' + debug.tilesCulled + ', Max Depth: ' + debug.maxDepth + ', Waiting for children: ' + debug.tilesWaitingForChildren); - if (pass.pick) { - surface.update(frameState); + debug.lastTilesVisited = debug.tilesVisited; + debug.lastTilesRendered = debug.tilesRendered; + debug.lastTilesCulled = debug.tilesCulled; + debug.lastMaxDepth = debug.maxDepth; + debug.lastTilesWaitingForChildren = debug.tilesWaitingForChildren; + } } - }; + } /** + * Updates terrain heights. * @private */ - Globe.prototype.endFrame = function(frameState) { - if (!this.show) { + QuadtreePrimitive.prototype.endFrame = function(frameState) { + var passes = frameState.passes; + if (!passes.render || frameState.mode === SceneMode.MORPHING) { + // Only process the load queue for a single pass. + // Don't process the load queue or update heights during the morph flights. return; } - if (frameState.passes.render) { - this._surface.endFrame(frameState); - } + // Load/create resources for terrain and imagery. Prepare texture re-projections for the next frame. + processTileLoadQueue(this, frameState); + updateHeights(this, frameState); + updateTileLoadProgress(this, frameState); }; /** @@ -198070,11 +210443,13 @@ define('Scene/Globe',[ * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * + * @memberof QuadtreePrimitive + * * @returns {Boolean} True if this object was destroyed; otherwise, false. * - * @see Globe#destroy + * @see QuadtreePrimitive#destroy */ - Globe.prototype.isDestroyed = function() { + QuadtreePrimitive.prototype.isDestroyed = function() { return false; }; @@ -198086,2627 +210461,1759 @@ define('Scene/Globe',[ * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, * assign the return value (<code>undefined</code>) to the object as done in the example. * + * @memberof QuadtreePrimitive + * * @returns {undefined} * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * * * @example - * globe = globe && globe.destroy(); + * primitive = primitive && primitive.destroy(); * - * @see Globe#isDestroyed + * @see QuadtreePrimitive#isDestroyed */ - Globe.prototype.destroy = function() { - this._surfaceShaderSet = this._surfaceShaderSet && this._surfaceShaderSet.destroy(); - this._surface = this._surface && this._surface.destroy(); - this._oceanNormalMap = this._oceanNormalMap && this._oceanNormalMap.destroy(); - return destroyObject(this); + QuadtreePrimitive.prototype.destroy = function() { + this._tileProvider = this._tileProvider && this._tileProvider.destroy(); }; - return Globe; -}); - -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PostProcessFilters/PassThrough',[],function() { - 'use strict'; - return "uniform sampler2D u_texture;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -gl_FragColor = texture2D(u_texture, v_textureCoordinates);\n\ -}\n\ -"; -}); -define('Scene/GlobeDepth',[ - '../Core/BoundingRectangle', - '../Core/Color', - '../Core/defined', - '../Core/destroyObject', - '../Core/PixelFormat', - '../Renderer/ClearCommand', - '../Renderer/Framebuffer', - '../Renderer/PixelDatatype', - '../Renderer/RenderState', - '../Renderer/Texture', - '../Shaders/PostProcessFilters/PassThrough' - ], function( - BoundingRectangle, - Color, - defined, - destroyObject, - PixelFormat, - ClearCommand, - Framebuffer, - PixelDatatype, - RenderState, - Texture, - PassThrough) { - 'use strict'; - - /** - * @private - */ - function GlobeDepth() { - this._colorTexture = undefined; - this._depthStencilTexture = undefined; - this._globeDepthTexture = undefined; - - this.framebuffer = undefined; - this._copyDepthFramebuffer = undefined; - - this._clearColorCommand = undefined; - this._copyColorCommand = undefined; - this._copyDepthCommand = undefined; - - this._viewport = new BoundingRectangle(); - this._rs = undefined; - - this._useScissorTest = false; - this._scissorRectangle = undefined; - - this._debugGlobeDepthViewportCommand = undefined; - } - - function executeDebugGlobeDepth(globeDepth, context, passState) { - if (!defined(globeDepth._debugGlobeDepthViewportCommand)) { - var fs = - 'uniform sampler2D u_texture;\n' + - 'varying vec2 v_textureCoordinates;\n' + - 'void main()\n' + - '{\n' + - ' float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n' + - ' float n_range = czm_depthRange.near;\n' + - ' float f_range = czm_depthRange.far;\n' + - ' float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n' + - ' float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n' + - ' gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n' + - '}\n'; - - globeDepth._debugGlobeDepthViewportCommand = context.createViewportQuadCommand(fs, { - uniformMap : { - u_texture : function() { - return globeDepth._globeDepthTexture; - } - }, - owner : globeDepth - }); - } - - globeDepth._debugGlobeDepthViewportCommand.execute(context, passState); - } - - function destroyTextures(globeDepth) { - globeDepth._colorTexture = globeDepth._colorTexture && !globeDepth._colorTexture.isDestroyed() && globeDepth._colorTexture.destroy(); - globeDepth._depthStencilTexture = globeDepth._depthStencilTexture && !globeDepth._depthStencilTexture.isDestroyed() && globeDepth._depthStencilTexture.destroy(); - globeDepth._globeDepthTexture = globeDepth._globeDepthTexture && !globeDepth._globeDepthTexture.isDestroyed() && globeDepth._globeDepthTexture.destroy(); - } - - function destroyFramebuffers(globeDepth) { - globeDepth.framebuffer = globeDepth.framebuffer && !globeDepth.framebuffer.isDestroyed() && globeDepth.framebuffer.destroy(); - globeDepth._copyDepthFramebuffer = globeDepth._copyDepthFramebuffer && !globeDepth._copyDepthFramebuffer.isDestroyed() && globeDepth._copyDepthFramebuffer.destroy(); - } - - function createTextures(globeDepth, context, width, height) { - globeDepth._colorTexture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE - }); - - globeDepth._depthStencilTexture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.DEPTH_STENCIL, - pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 - }); - - globeDepth._globeDepthTexture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE - }); - } - - function createFramebuffers(globeDepth, context) { - globeDepth.framebuffer = new Framebuffer({ - context : context, - colorTextures : [globeDepth._colorTexture], - depthStencilTexture : globeDepth._depthStencilTexture, - destroyAttachments : false - }); + var comparisonPoint; + var centerScratch = new Cartographic(); + function compareDistanceToPoint(a, b) { + var center = Rectangle.center(a.rectangle, centerScratch); + var alon = center.longitude - comparisonPoint.longitude; + var alat = center.latitude - comparisonPoint.latitude; - globeDepth._copyDepthFramebuffer = new Framebuffer({ - context : context, - colorTextures : [globeDepth._globeDepthTexture], - destroyAttachments : false - }); - } + center = Rectangle.center(b.rectangle, centerScratch); + var blon = center.longitude - comparisonPoint.longitude; + var blat = center.latitude - comparisonPoint.latitude; - function updateFramebuffers(globeDepth, context, width, height) { - var colorTexture = globeDepth._colorTexture; - var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height; - if (!defined(globeDepth.framebuffer) || textureChanged) { - destroyTextures(globeDepth); - destroyFramebuffers(globeDepth); - createTextures(globeDepth, context, width, height); - createFramebuffers(globeDepth, context); - } + return (alon * alon + alat * alat) - (blon * blon + blat * blat); } - function updateCopyCommands(globeDepth, context, width, height, passState) { - globeDepth._viewport.width = width; - globeDepth._viewport.height = height; - - var useScissorTest = !BoundingRectangle.equals(globeDepth._viewport, passState.viewport); - var updateScissor = useScissorTest !== globeDepth._useScissorTest; - globeDepth._useScissorTest = useScissorTest; - - if (!BoundingRectangle.equals(globeDepth._scissorRectangle, passState.viewport)) { - globeDepth._scissorRectangle = BoundingRectangle.clone(passState.viewport, globeDepth._scissorRectangle); - updateScissor = true; - } - - if (!defined(globeDepth._rs) || !BoundingRectangle.equals(globeDepth._viewport, globeDepth._rs.viewport) || updateScissor) { - globeDepth._rs = RenderState.fromCache({ - viewport : globeDepth._viewport, - scissorTest : { - enabled : globeDepth._useScissorTest, - rectangle : globeDepth._scissorRectangle - } - }); - } - - if (!defined(globeDepth._copyDepthCommand)) { - var fs = - 'uniform sampler2D u_texture;\n' + - 'varying vec2 v_textureCoordinates;\n' + - 'void main()\n' + - '{\n' + - ' gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n' + - '}\n'; - globeDepth._copyDepthCommand = context.createViewportQuadCommand(fs, { - uniformMap : { - u_texture : function() { - return globeDepth._depthStencilTexture; - } - }, - owner : globeDepth - }); - } - - globeDepth._copyDepthCommand.framebuffer = globeDepth._copyDepthFramebuffer; - - if (!defined(globeDepth._copyColorCommand)) { - globeDepth._copyColorCommand = context.createViewportQuadCommand(PassThrough, { - uniformMap : { - u_texture : function() { - return globeDepth._colorTexture; - } - }, - owner : globeDepth - }); + function selectTilesForRendering(primitive, frameState) { + var debug = primitive._debug; + if (debug.suspendLodUpdate) { + return; } - globeDepth._copyDepthCommand.renderState = globeDepth._rs; - globeDepth._copyColorCommand.renderState = globeDepth._rs; + // Clear the render list. + var tilesToRender = primitive._tilesToRender; + tilesToRender.length = 0; - if (!defined(globeDepth._clearColorCommand)) { - globeDepth._clearColorCommand = new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 0.0), - stencil : 0.0, - owner : globeDepth - }); + // We can't render anything before the level zero tiles exist. + var tileProvider = primitive._tileProvider; + if (!defined(primitive._levelZeroTiles)) { + if (tileProvider.ready) { + var tilingScheme = tileProvider.tilingScheme; + primitive._levelZeroTiles = QuadtreeTile.createLevelZeroTiles(tilingScheme); + } else { + // Nothing to do until the provider is ready. + return; + } } - globeDepth._clearColorCommand.framebuffer = globeDepth.framebuffer; - } - - GlobeDepth.prototype.executeDebugGlobeDepth = function(context, passState) { - executeDebugGlobeDepth(this, context, passState); - }; - - GlobeDepth.prototype.update = function(context, passState) { - var width = context.drawingBufferWidth; - var height = context.drawingBufferHeight; - - updateFramebuffers(this, context, width, height); - updateCopyCommands(this, context, width, height, passState); - context.uniformState.globeDepthTexture = undefined; - }; - - GlobeDepth.prototype.executeCopyDepth = function(context, passState) { - if (defined(this._copyDepthCommand)) { - this._copyDepthCommand.execute(context, passState); - context.uniformState.globeDepthTexture = this._globeDepthTexture; - } - }; + primitive._occluders.ellipsoid.cameraPosition = frameState.camera.positionWC; - GlobeDepth.prototype.executeCopyColor = function(context, passState) { - if (defined(this._copyColorCommand)) { - this._copyColorCommand.execute(context, passState); - } - }; + var tile; + var levelZeroTiles = primitive._levelZeroTiles; + var occluders = levelZeroTiles.length > 1 ? primitive._occluders : undefined; - GlobeDepth.prototype.clear = function(context, passState, clearColor) { - var clear = this._clearColorCommand; - if (defined(clear)) { - Color.clone(clearColor, clear.color); - clear.execute(context, passState); - } - }; + // Sort the level zero tiles by the distance from the center to the camera. + // The level zero tiles aren't necessarily a nice neat quad, so we can't use the + // quadtree ordering we use elsewhere in the tree + comparisonPoint = frameState.camera.positionCartographic; + levelZeroTiles.sort(compareDistanceToPoint); - GlobeDepth.prototype.isDestroyed = function() { - return false; - }; + var customDataAdded = primitive._addHeightCallbacks; + var customDataRemoved = primitive._removeHeightCallbacks; + var frameNumber = frameState.frameNumber; - GlobeDepth.prototype.destroy = function() { - destroyTextures(this); - destroyFramebuffers(this); + var i; + var len; + if (customDataAdded.length > 0 || customDataRemoved.length > 0) { + for (i = 0, len = levelZeroTiles.length; i < len; ++i) { + tile = levelZeroTiles[i]; + tile._updateCustomData(frameNumber, customDataAdded, customDataRemoved); + } - if (defined(this._copyColorCommand)) { - this._copyColorCommand.shaderProgram = this._copyColorCommand.shaderProgram.destroy(); + customDataAdded.length = 0; + customDataRemoved.length = 0; } - if (defined(this._copyDepthCommand)) { - this._copyDepthCommand.shaderProgram = this._copyDepthCommand.shaderProgram.destroy(); - } + // Our goal with load ordering is to first load all of the tiles we need to + // render the current scene at full detail. Loading any other tiles is just + // a form of prefetching, and we need not do it at all (other concerns aside). This + // simple and obvious statement gets more complicated when we realize that, because + // we don't have bounding volumes for the entire terrain tile pyramid, we don't + // precisely know which tiles we need to render the scene at full detail, until we do + // some loading. + // + // So our load priority is (from high to low): + // 1. Tiles that we _would_ render, except that they're not sufficiently loaded yet. + // Ideally this would only include tiles that we've already determined to be visible, + // but since we don't have reliable visibility information until a tile is loaded, + // and because we (currently) must have all children in a quad renderable before we + // can refine, this pretty much means tiles we'd like to refine to, regardless of + // visibility. (high) + // 2. Tiles that we're rendering. (medium) + // 3. All other tiles. (low) + // + // Within each priority group, tiles should be loaded in approximate near-to-far order, + // but currently they're just loaded in our traversal order which makes no guarantees + // about depth ordering. - var command = this._debugGlobeDepthViewportCommand; - if (defined(command)) { - command.shaderProgram = command.shaderProgram.destroy(); + // Traverse in depth-first, near-to-far order. + for (i = 0, len = levelZeroTiles.length; i < len; ++i) { + tile = levelZeroTiles[i]; + primitive._tileReplacementQueue.markTileRendered(tile); + if (!tile.renderable) { + if (tile.needsLoading) { + primitive._tileLoadQueueHigh.push(tile); + } + ++debug.tilesWaitingForChildren; + } else if (tileProvider.computeTileVisibility(tile, frameState, occluders) !== Visibility.NONE) { + visitTile(primitive, frameState, tile); + } else { + if (tile.needsLoading) { + primitive._tileLoadQueueLow.push(tile); + } + ++debug.tilesCulled; + } } - - return destroyObject(this); - }; - - return GlobeDepth; -}); - -define('Scene/GoogleEarthEnterpriseImageryProvider',[ - '../Core/Credit', - '../Core/decodeGoogleEarthEnterpriseData', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/GeographicTilingScheme', - '../Core/GoogleEarthEnterpriseMetadata', - '../Core/loadArrayBuffer', - '../Core/loadImageFromTypedArray', - '../Core/Math', - '../Core/Rectangle', - '../Core/Request', - '../Core/RuntimeError', - '../Core/TileProviderError', - '../ThirdParty/protobuf-minimal', - '../ThirdParty/when' - ], function( - Credit, - decodeGoogleEarthEnterpriseData, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - GeographicTilingScheme, - GoogleEarthEnterpriseMetadata, - loadArrayBuffer, - loadImageFromTypedArray, - CesiumMath, - Rectangle, - Request, - RuntimeError, - TileProviderError, - protobuf, - when) { - 'use strict'; - - function GoogleEarthEnterpriseDiscardPolicy() { - this._image = new Image(); } - /** - * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. - */ - GoogleEarthEnterpriseDiscardPolicy.prototype.isReady = function() { - return true; - }; - - /** - * Given a tile image, decide whether to discard that image. - * - * @param {Image} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. - */ - GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function(image) { - return (image === this._image); - }; - - /** - * Provides tiled imagery using the Google Earth Enterprise REST API. - * - * Notes: This provider is for use with the 3D Earth API of Google Earth Enterprise, - * {@link GoogleEarthEnterpriseMapsProvider} should be used with 2D Maps API. - * - * @alias GoogleEarthEnterpriseImageryProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url of the Google Earth Enterprise server hosting the imagery. - * @param {GoogleEarthEnterpriseMetadata} options.metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile - * is invalid and should be discarded. If this value is not specified, a default - * is to discard tiles that fail to download. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * - * @see GoogleEarthEnterpriseTerrainProvider - * @see ArcGisMapServerImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider - * - * - * @example - * var geeMetadata = new GoogleEarthEnterpriseMetadata('http://www.earthenterprise.org/3d'); - * var gee = new Cesium.GoogleEarthEnterpriseImageryProvider({ - * metadata : geeMetadata - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - */ - function GoogleEarthEnterpriseImageryProvider(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (!(defined(options.url) || defined(options.metadata))) { - throw new DeveloperError('options.url or options.metadata is required.'); - } - - var metadata; - if (defined(options.metadata)) { - metadata = this._metadata = options.metadata; - } else { - metadata = this._metadata = new GoogleEarthEnterpriseMetadata({ - url : options.url, - proxy : options.proxy - }); - } - this._tileDiscardPolicy = options.tileDiscardPolicy; - this._proxy = defaultValue(options.proxy, this._metadata.proxy); - - this._tilingScheme = new GeographicTilingScheme({ - numberOfLevelZeroTilesX : 2, - numberOfLevelZeroTilesY : 2, - rectangle : new Rectangle(-CesiumMath.PI, -CesiumMath.PI, CesiumMath.PI, CesiumMath.PI), - ellipsoid : options.ellipsoid - }); + function visitTile(primitive, frameState, tile) { + var debug = primitive._debug; - var credit = options.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); - } - this._credit = credit; + ++debug.tilesVisited; - this._tileWidth = 256; - this._tileHeight = 256; - this._maximumLevel = 23; + primitive._tileReplacementQueue.markTileRendered(tile); + tile._updateCustomData(frameState.frameNumber); - // Install the default tile discard policy if none has been supplied. - if (!defined(this._tileDiscardPolicy)) { - this._tileDiscardPolicy = new GoogleEarthEnterpriseDiscardPolicy(); + if (tile.level > debug.maxDepth) { + debug.maxDepth = tile.level; } - this._errorEvent = new Event(); - - this._ready = false; - var that = this; - var metadataError; - this._readyPromise = metadata.readyPromise - .then(function(result) { - if (!metadata.imageryPresent) { - var e = new RuntimeError('The server ' + metadata.url + ' doesn\'t have imagery'); - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); - return when.reject(e); - } - - TileProviderError.handleSuccess(metadataError); - that._ready = result; - return result; - }) - .otherwise(function(e) { - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); - return when.reject(e); - }); - } - - defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { - /** - * Gets the name of the Google Earth Enterprise server url hosting the imagery. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._metadata.url; - } - }, - - /** - * Gets the proxy used by this provider. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._proxy; - } - }, - - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); - } - - return this._tileWidth; - } - }, - - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); - } - - return this._tileHeight; + if (screenSpaceError(primitive, frameState, tile) < primitive.maximumScreenSpaceError) { + // This tile meets SSE requirements, so render it. + if (tile.needsLoading) { + // Rendered tile meeting SSE loads with medium priority. + primitive._tileLoadQueueMedium.push(tile); } - }, + addTileToRenderList(primitive, tile); + return; + } - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); - } - - return this._maximumLevel; - } - }, + var southwestChild = tile.southwestChild; + var southeastChild = tile.southeastChild; + var northwestChild = tile.northwestChild; + var northeastChild = tile.northeastChild; + var allAreRenderable = southwestChild.renderable && southeastChild.renderable && + northwestChild.renderable && northeastChild.renderable; + var allAreUpsampled = southwestChild.upsampledFromParent && southeastChild.upsampledFromParent && + northwestChild.upsampledFromParent && northeastChild.upsampledFromParent; - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); - } - - return 0; - } - }, + if (allAreRenderable) { + if (allAreUpsampled) { + // No point in rendering the children because they're all upsampled. Render this tile instead. + addTileToRenderList(primitive, tile); - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme; - } - }, + // Load the children even though we're (currently) not going to render them. + // A tile that is "upsampled only" right now might change its tune once it does more loading. + // A tile that is upsampled now and forever should also be done loading, so no harm done. + queueChildLoadNearToFar(primitive, frameState.camera.positionCartographic, southwestChild, southeastChild, northwestChild, northeastChild); - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - if (!this._ready) { - throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); + if (tile.needsLoading) { + // Rendered tile that's not waiting on children loads with medium priority. + primitive._tileLoadQueueMedium.push(tile); } - - return this._tilingScheme.rectangle; - } - }, + } else { + // SSE is not good enough and children are loaded, so refine. + // No need to add the children to the load queue because they'll be added (if necessary) when they're visited. + visitVisibleChildrenNearToFar(primitive, southwestChild, southeastChild, northwestChild, northeastChild, frameState); - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); + if (tile.needsLoading) { + // Tile is not rendered, so load it with low priority. + primitive._tileLoadQueueLow.push(tile); } - - return this._tileDiscardPolicy; - } - }, - - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._errorEvent; } - }, - - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, + } else { + // We'd like to refine but can't because not all of our children are renderable. Load the refinement blockers with high priority and + // render this tile in the meantime. + queueChildLoadNearToFar(primitive, frameState.camera.positionCartographic, southwestChild, southeastChild, northwestChild, northeastChild); + addTileToRenderList(primitive, tile); - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise; + if (tile.needsLoading) { + // We will refine this tile when it's possible, so load this tile only with low priority. + primitive._tileLoadQueueLow.push(tile); } - }, + } + } - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return this._credit; + function queueChildLoadNearToFar(primitive, cameraPosition, southwest, southeast, northwest, northeast) { + if (cameraPosition.longitude < southwest.east) { + if (cameraPosition.latitude < southwest.north) { + // Camera in southwest quadrant + queueChildTileLoad(primitive, southwest); + queueChildTileLoad(primitive, southeast); + queueChildTileLoad(primitive, northwest); + queueChildTileLoad(primitive, northeast); + } else { + // Camera in northwest quadrant + queueChildTileLoad(primitive, northwest); + queueChildTileLoad(primitive, southwest); + queueChildTileLoad(primitive, northeast); + queueChildTileLoad(primitive, southeast); } - }, + } else if (cameraPosition.latitude < southwest.north) { + // Camera southeast quadrant + queueChildTileLoad(primitive, southeast); + queueChildTileLoad(primitive, southwest); + queueChildTileLoad(primitive, northeast); + queueChildTileLoad(primitive, northwest); + } else { + // Camera in northeast quadrant + queueChildTileLoad(primitive, northeast); + queueChildTileLoad(primitive, northwest); + queueChildTileLoad(primitive, southeast); + queueChildTileLoad(primitive, southwest); + } + } - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage - * and texture upload time. - * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - hasAlphaChannel : { - get : function() { - return false; + function queueChildTileLoad(primitive, childTile) { + primitive._tileReplacementQueue.markTileRendered(childTile); + if (childTile.needsLoading) { + if (childTile.renderable) { + primitive._tileLoadQueueLow.push(childTile); + } else { + // A tile blocking refine loads with high priority + primitive._tileLoadQueueHigh.push(childTile); } } - }); + } - /** - * Gets the credits to be displayed when a given tile is displayed. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. - */ - GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function(x, y, level) { - if (!this._ready) { - throw new DeveloperError('getTileCredits must not be called before the imagery provider is ready.'); - } - - var metadata = this._metadata; - var info = metadata.getTileInformation(x, y, level); - if (defined(info)) { - var credit = metadata.providers[info.imageryProvider]; - if (defined(credit)) { - return [credit]; + function visitVisibleChildrenNearToFar(primitive, southwest, southeast, northwest, northeast, frameState) { + var cameraPosition = frameState.camera.positionCartographic; + var tileProvider = primitive._tileProvider; + var occluders = primitive._occluders; + + if (cameraPosition.longitude < southwest.rectangle.east) { + if (cameraPosition.latitude < southwest.rectangle.north) { + // Camera in southwest quadrant + visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); + visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); + visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); + visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); + } else { + // Camera in northwest quadrant + visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); + visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); + visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); + visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); } + } else if (cameraPosition.latitude < southwest.rectangle.north) { + // Camera southeast quadrant + visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); + visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); + visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); + visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); + } else { + // Camera in northeast quadrant + visitIfVisible(primitive, northeast, tileProvider, frameState, occluders); + visitIfVisible(primitive, northwest, tileProvider, frameState, occluders); + visitIfVisible(primitive, southeast, tileProvider, frameState, occluders); + visitIfVisible(primitive, southwest, tileProvider, frameState, occluders); } + } - return undefined; - }; + function visitIfVisible(primitive, tile, tileProvider, frameState, occluders) { + if (tileProvider.computeTileVisibility(tile, frameState, occluders) !== Visibility.NONE) { + visitTile(primitive, frameState, tile); + } else { + ++primitive._debug.tilesCulled; + primitive._tileReplacementQueue.markTileRendered(tile); - /** - * Requests the image for a given tile. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. - * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. - */ - GoogleEarthEnterpriseImageryProvider.prototype.requestImage = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); - } - - var invalidImage = this._tileDiscardPolicy._image; // Empty image or undefined depending on discard policy - var metadata = this._metadata; - var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - var info = metadata.getTileInformation(x, y, level); - if (!defined(info)) { - if (metadata.isValid(quadKey)) { - var metadataRequest = new Request({ - throttle : request.throttle, - throttleByServer : request.throttleByServer, - type : request.type, - priorityFunction : request.priorityFunction - }); - metadata.populateSubtree(x, y, level, metadataRequest); - return undefined; // No metadata so return undefined so we can be loaded later + // We've decided this tile is not visible, but if it's not fully loaded yet, we've made + // this determination based on possibly-incorrect information. We need to load this + // culled tile with low priority just in case it turns out to be visible after all. + if (tile.needsLoading) { + primitive._tileLoadQueueLow.push(tile); } - return invalidImage; // Image doesn't exist } + } - if (!info.hasImagery()) { - // Already have info and there isn't any imagery here - return invalidImage; - } - // Load the - var url = buildImageUrl(this, info, x, y, level); - var promise = loadArrayBuffer(url, undefined, request); - if (!defined(promise)) { - return undefined; // Throttled + function screenSpaceError(primitive, frameState, tile) { + if (frameState.mode === SceneMode.SCENE2D || frameState.camera.frustum instanceof OrthographicFrustum) { + return screenSpaceError2D(primitive, frameState, tile); } - return promise - .then(function(image) { - decodeGoogleEarthEnterpriseData(metadata.key, image); - var a = new Uint8Array(image); - var type; + var maxGeometricError = primitive._tileProvider.getLevelMaximumGeometricError(tile.level); - var protoImagery = metadata.protoImagery; - if (!defined(protoImagery) || !protoImagery) { - type = getImageType(a); - } + var distance = tile._distance; + var height = frameState.context.drawingBufferHeight; + var sseDenominator = frameState.camera.frustum.sseDenominator; - if (!defined(type) && (!defined(protoImagery) || protoImagery)) { - var message = decodeEarthImageryPacket(a); - type = message.imageType; - a = message.imageData; - } + var error = (maxGeometricError * height) / (distance * sseDenominator); - if (!defined(type) || !defined(a)) { - return invalidImage; - } + if (frameState.fog.enabled) { + error = error - CesiumMath.fog(distance, frameState.fog.density) * frameState.fog.sse; + } - return loadImageFromTypedArray(a, type); - }); - }; + return error; + } - /** - * Picking features is not currently supported by this imagery provider, so this function simply returns - * undefined. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. - */ - GoogleEarthEnterpriseImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return undefined; - }; + function screenSpaceError2D(primitive, frameState, tile) { + var camera = frameState.camera; + var frustum = camera.frustum; + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } - // - // Functions to handle imagery packets - // - function buildImageUrl(imageryProvider, info, x, y, level) { - var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); - var version = info.imageryVersion; - version = (defined(version) && version > 0) ? version : 1; - var imageUrl = imageryProvider.url + 'flatfile?f1-0' + quadKey + '-i.' + version.toString(); + var context = frameState.context; + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; - var proxy = imageryProvider._proxy; - if (defined(proxy)) { - imageUrl = proxy.getURL(imageUrl); + var maxGeometricError = primitive._tileProvider.getLevelMaximumGeometricError(tile.level); + var pixelSize = Math.max(frustum.top - frustum.bottom, frustum.right - frustum.left) / Math.max(width, height); + var error = maxGeometricError / pixelSize; + + if (frameState.fog.enabled && frameState.mode !== SceneMode.SCENE2D) { + error = error - CesiumMath.fog(tile._distance, frameState.fog.density) * frameState.fog.sse; } - return imageUrl; + return error; } - // Detects if a Uint8Array is a JPEG or PNG - function getImageType(image) { - var jpeg = 'JFIF'; - if (image[6] === jpeg.charCodeAt(0) && image[7] === jpeg.charCodeAt(1) && - image[8] === jpeg.charCodeAt(2) && image[9] === jpeg.charCodeAt(3)) { - return 'image/jpeg'; - } + function addTileToRenderList(primitive, tile) { + primitive._tilesToRender.push(tile); + ++primitive._debug.tilesRendered; + } - var png = 'PNG'; - if (image[1] === png.charCodeAt(0) && image[2] === png.charCodeAt(1) && image[3] === png.charCodeAt(2)) { - return 'image/png'; + function processTileLoadQueue(primitive, frameState) { + var tileLoadQueueHigh = primitive._tileLoadQueueHigh; + var tileLoadQueueMedium = primitive._tileLoadQueueMedium; + var tileLoadQueueLow = primitive._tileLoadQueueLow; + + if (tileLoadQueueHigh.length === 0 && tileLoadQueueMedium.length === 0 && tileLoadQueueLow.length === 0) { + return; } - return undefined; + // Remove any tiles that were not used this frame beyond the number + // we're allowed to keep. + primitive._tileReplacementQueue.trimTiles(primitive.tileCacheSize); + + var endTime = getTimestamp() + primitive._loadQueueTimeSlice; + var tileProvider = primitive._tileProvider; + + processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, tileLoadQueueHigh); + processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, tileLoadQueueMedium); + processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, tileLoadQueueLow); } - // Decodes an Imagery protobuf into the message - // Partially generated with the help of protobuf.js static generator - function decodeEarthImageryPacket(data) { - var reader = protobuf.Reader.create(data); - var end = reader.len; - var message = {}; - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.imageType = reader.uint32(); - break; - case 2: - message.imageData = reader.bytes(); - break; - case 3: - message.alphaType = reader.uint32(); - break; - case 4: - message.imageAlpha = reader.bytes(); - break; - case 5: - var copyrightIds = message.copyrightIds; - if (!defined(copyrightIds)) { - copyrightIds = message.copyrightIds = []; + function processSinglePriorityLoadQueue(primitive, frameState, tileProvider, endTime, loadQueue) { + for (var i = 0, len = loadQueue.length; i < len && getTimestamp() < endTime; ++i) { + var tile = loadQueue[i]; + primitive._tileReplacementQueue.markTileRendered(tile); + tileProvider.loadTile(frameState, tile); + } + } + + var scratchRay = new Ray(); + var scratchCartographic = new Cartographic(); + var scratchPosition = new Cartesian3(); + + function updateHeights(primitive, frameState) { + var tilesToUpdateHeights = primitive._tileToUpdateHeights; + var terrainProvider = primitive._tileProvider.terrainProvider; + + var startTime = getTimestamp(); + var timeSlice = primitive._updateHeightsTimeSlice; + var endTime = startTime + timeSlice; + + var mode = frameState.mode; + var projection = frameState.mapProjection; + var ellipsoid = projection.ellipsoid; + + while (tilesToUpdateHeights.length > 0) { + var tile = tilesToUpdateHeights[0]; + var customData = tile.customData; + var customDataLength = customData.length; + + var timeSliceMax = false; + var i; + for (i = primitive._lastTileIndex; i < customDataLength; ++i) { + var data = customData[i]; + + if (tile.level > data.level) { + if (!defined(data.positionOnEllipsoidSurface)) { + // cartesian has to be on the ellipsoid surface for `ellipsoid.geodeticSurfaceNormal` + data.positionOnEllipsoidSurface = Cartesian3.fromRadians(data.positionCartographic.longitude, data.positionCartographic.latitude, 0.0, ellipsoid); } - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) { - copyrightIds.push(reader.uint32()); + + if (mode === SceneMode.SCENE3D) { + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(data.positionOnEllipsoidSurface, scratchRay.direction); + + // compute origin point + + // Try to find the intersection point between the surface normal and z-axis. + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(data.positionOnEllipsoidSurface, 11500.0, scratchRay.origin); + + // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid + if (!defined(rayOrigin)) { + // intersection point is outside the ellipsoid, try other value + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); + + // multiply by the *positive* value of the magnitude + var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchPosition); + Cartesian3.subtract(data.positionOnEllipsoidSurface, vectorToMinimumPoint, scratchRay.origin); } } else { - copyrightIds.push(reader.uint32()); + Cartographic.clone(data.positionCartographic, scratchCartographic); + + // minimum height for the terrain set, need to get this information from the terrain provider + scratchCartographic.height = -11500.0; + projection.project(scratchCartographic, scratchPosition); + Cartesian3.fromElements(scratchPosition.z, scratchPosition.x, scratchPosition.y, scratchPosition); + Cartesian3.clone(scratchPosition, scratchRay.origin); + Cartesian3.clone(Cartesian3.UNIT_X, scratchRay.direction); } + + var position = tile.data.pick(scratchRay, mode, projection, false, scratchPosition); + if (defined(position)) { + data.callback(position); + } + + data.level = tile.level; + } else if (tile.level === data.level) { + var children = tile.children; + var childrenLength = children.length; + + var child; + for (var j = 0; j < childrenLength; ++j) { + child = children[j]; + if (Rectangle.contains(child.rectangle, data.positionCartographic)) { + break; + } + } + + var tileDataAvailable = terrainProvider.getTileDataAvailable(child.x, child.y, child.level); + var parentTile = tile.parent; + if ((defined(tileDataAvailable) && !tileDataAvailable) || + (defined(parentTile) && defined(parentTile.data) && defined(parentTile.data.terrainData) && + !parentTile.data.terrainData.isChildAvailable(parentTile.x, parentTile.y, child.x, child.y))) { + data.removeFunc(); + } + } + + if (getTimestamp() >= endTime) { + timeSliceMax = true; break; - default: - reader.skipType(tag & 7); - break; + } } - } - var imageType = message.imageType; - if (defined(imageType)) { - switch (imageType) { - case 0: - message.imageType = 'image/jpeg'; - break; - case 4: - message.imageType = 'image/png'; - break; - default: - throw new RuntimeError('GoogleEarthEnterpriseImageryProvider: Unsupported image type.'); + if (timeSliceMax) { + primitive._lastTileIndex = i; + break; + } else { + primitive._lastTileIndex = 0; + tilesToUpdateHeights.shift(); } } + } - var alphaType = message.alphaType; - if (defined(alphaType) && alphaType !== 0) { - console.log('GoogleEarthEnterpriseImageryProvider: External alpha not supported.'); - delete message.alphaType; - delete message.imageAlpha; - } + function createRenderCommandsForSelectedTiles(primitive, frameState) { + var tileProvider = primitive._tileProvider; + var tilesToRender = primitive._tilesToRender; + var tilesToUpdateHeights = primitive._tileToUpdateHeights; - return message; + for (var i = 0, len = tilesToRender.length; i < len; ++i) { + var tile = tilesToRender[i]; + tileProvider.showTileThisFrame(tile, frameState); + + if (tile._frameRendered !== frameState.frameNumber - 1) { + tilesToUpdateHeights.push(tile); + } + tile._frameRendered = frameState.frameNumber; + } } - return GoogleEarthEnterpriseImageryProvider; + return QuadtreePrimitive; }); -define('Scene/GoogleEarthEnterpriseMapsProvider',[ - '../Core/Credit', +define('Scene/Globe',[ + '../Core/BoundingSphere', + '../Core/buildModuleUrl', + '../Core/Cartesian3', + '../Core/Cartographic', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/destroyObject', '../Core/DeveloperError', + '../Core/Ellipsoid', + '../Core/EllipsoidTerrainProvider', '../Core/Event', - '../Core/GeographicTilingScheme', - '../Core/loadText', + '../Core/IntersectionTests', + '../Core/Ray', '../Core/Rectangle', - '../Core/RuntimeError', - '../Core/TileProviderError', - '../Core/WebMercatorTilingScheme', + '../Core/Resource', + '../Renderer/ShaderSource', + '../Renderer/Texture', + '../Shaders/GlobeFS', + '../Shaders/GlobeVS', + '../Shaders/GroundAtmosphere', '../ThirdParty/when', - './ImageryProvider' + './GlobeSurfaceShaderSet', + './GlobeSurfaceTileProvider', + './ImageryLayerCollection', + './Material', + './QuadtreePrimitive', + './SceneMode', + './ShadowMode' ], function( - Credit, + BoundingSphere, + buildModuleUrl, + Cartesian3, + Cartographic, defaultValue, defined, defineProperties, + destroyObject, DeveloperError, + Ellipsoid, + EllipsoidTerrainProvider, Event, - GeographicTilingScheme, - loadText, + IntersectionTests, + Ray, Rectangle, - RuntimeError, - TileProviderError, - WebMercatorTilingScheme, + Resource, + ShaderSource, + Texture, + GlobeFS, + GlobeVS, + GroundAtmosphere, when, - ImageryProvider) { + GlobeSurfaceShaderSet, + GlobeSurfaceTileProvider, + ImageryLayerCollection, + Material, + QuadtreePrimitive, + SceneMode, + ShadowMode) { 'use strict'; /** - * Provides tiled imagery using the Google Earth Imagery API. - * - * Notes: This imagery provider does not work with the public Google Earth servers. It works with the - * Google Earth Enterprise Server. - * - * By default the Google Earth Enterprise server does not set the - * {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} headers. You can either - * use a proxy server which adds these headers, or in the /opt/google/gehttpd/conf/gehttpd.conf - * and add the 'Header set Access-Control-Allow-Origin "*"' option to the '<Directory />' and - * '<Directory "/opt/google/gehttpd/htdocs">' directives. - * - * This provider is for use with 2D Maps API as part of Google Earth Enterprise. For 3D Earth API uses, it - * is necessary to use {@link GoogleEarthEnterpriseImageryProvider} + * The globe rendered in the scene, including its terrain ({@link Globe#terrainProvider}) + * and imagery layers ({@link Globe#imageryLayers}). Access the globe using {@link Scene#globe}. * - * @alias GoogleEarthEnterpriseMapsProvider + * @alias Globe * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url of the Google Earth server hosting the imagery. - * @param {Number} options.channel The channel (id) to be used when requesting data from the server. - * The channel number can be found by looking at the json file located at: - * earth.localdomain/default_map/query?request=Json&vars=geeServerDefs The /default_map path may - * differ depending on your Google Earth Enterprise server configuration. Look for the "id" that - * is associated with a "ImageryMaps" requestType. There may be more than one id available. - * Example: - * { - * layers: [ - * { - * id: 1002, - * requestType: "ImageryMaps" - * }, - * { - * id: 1007, - * requestType: "VectorMapsRaster" - * } - * ] - * } - * @param {String} [options.path="/default_map"] The path of the Google Earth server hosting the imagery. - * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the Google Earth - * Enterprise server, or undefined if there is no limit. - * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile - * is invalid and should be discarded. To ensure that no tiles are discarded, construct and pass - * a {@link NeverTileDiscardPolicy} for this parameter. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Proxy} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * - * @exception {RuntimeError} Could not find layer with channel (id) of <code>options.channel</code>. - * @exception {RuntimeError} Could not find a version in channel (id) <code>options.channel</code>. - * @exception {RuntimeError} Unsupported projection <code>data.projection</code>. - * - * @see ArcGisMapServerImageryProvider - * @see BingMapsImageryProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider - * - * - * @example - * var google = new Cesium.GoogleEarthEnterpriseMapsProvider({ - * url : 'https://earth.localdomain', - * channel : 1008 - * }); - * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] Determines the size and shape of the + * globe. */ - function GoogleEarthEnterpriseMapsProvider(options) { - options = defaultValue(options, {}); - - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); - } - if (!defined(options.channel)) { - throw new DeveloperError('options.channel is required.'); - } - - this._url = options.url; - this._path = defaultValue(options.path, '/default_map'); - this._tileDiscardPolicy = options.tileDiscardPolicy; - this._proxy = options.proxy; - this._channel = options.channel; - this._requestType = 'ImageryMaps'; - this._credit = new Credit({ - text: 'Google Imagery', - imageUrl: GoogleEarthEnterpriseMapsProvider._logoData, - link: 'http://www.google.com/enterprise/mapsearth/products/earthenterprise.html' + function Globe(ellipsoid) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + var terrainProvider = new EllipsoidTerrainProvider({ + ellipsoid : ellipsoid }); + var imageryLayerCollection = new ImageryLayerCollection(); - /** - * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider. - * By default, this is set to 1.9. Changing this value after creating an {@link ImageryLayer} for this provider will have - * no effect. Instead, set the layer's {@link ImageryLayer#gamma} property. - * - * @type {Number} - * @default 1.9 - */ - this.defaultGamma = 1.9; - - this._tilingScheme = undefined; - - this._version = undefined; - - this._tileWidth = 256; - this._tileHeight = 256; - this._maximumLevel = options.maximumLevel; - this._imageUrlTemplate = this._url + this._path + '/query?request={request}&channel={channel}&version={version}&x={x}&y={y}&z={zoom}'; - - this._errorEvent = new Event(); - - this._ready = false; - this._readyPromise = when.defer(); - - var metadataUrl = this._url + this._path + '/query?request=Json&vars=geeServerDefs&is2d=t'; - var that = this; - var metadataError; - - function metadataSuccess(text) { - var data; - - // The Google Earth server sends malformed JSON data currently... - try { - // First, try parsing it like normal in case a future version sends correctly formatted JSON - data = JSON.parse(text); - } catch (e) { - // Quote object strings manually, then try parsing again - data = JSON.parse(text.replace(/([\[\{,])[\n\r ]*([A-Za-z0-9]+)[\n\r ]*:/g, '$1"$2":')); - } - - var layer; - for (var i = 0; i < data.layers.length; i++) { - if (data.layers[i].id === that._channel) { - layer = data.layers[i]; - break; - } - } - - var message; - - if (!defined(layer)) { - message = 'Could not find layer with channel (id) of ' + that._channel + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - throw new RuntimeError(message); - } - - if (!defined(layer.version)) { - message = 'Could not find a version in channel (id) ' + that._channel + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - throw new RuntimeError(message); - } - that._version = layer.version; - - if (defined(data.projection) && data.projection === 'flat') { - that._tilingScheme = new GeographicTilingScheme({ - numberOfLevelZeroTilesX : 2, - numberOfLevelZeroTilesY : 2, - rectangle : new Rectangle(-Math.PI, -Math.PI, Math.PI, Math.PI), - ellipsoid : options.ellipsoid - }); - // Default to mercator projection when projection is undefined - } else if (!defined(data.projection) || data.projection === 'mercator') { - that._tilingScheme = new WebMercatorTilingScheme({ - numberOfLevelZeroTilesX : 2, - numberOfLevelZeroTilesY : 2, - ellipsoid : options.ellipsoid - }); - } else { - message = 'Unsupported projection ' + data.projection + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - throw new RuntimeError(message); - } - - that._imageUrlTemplate = that._imageUrlTemplate.replace('{request}', that._requestType) - .replace('{channel}', that._channel).replace('{version}', that._version); - - that._ready = true; - that._readyPromise.resolve(true); - TileProviderError.handleSuccess(metadataError); - } - - function metadataFailure(e) { - var message = 'An error occurred while accessing ' + metadataUrl + '.'; - metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, message, undefined, undefined, undefined, requestMetadata); - that._readyPromise.reject(new RuntimeError(message)); - } - - function requestMetadata() { - var url = (!defined(that._proxy)) ? metadataUrl : that._proxy.getURL(metadataUrl); + this._ellipsoid = ellipsoid; + this._imageryLayerCollection = imageryLayerCollection; - var metadata = loadText(url); - when(metadata, metadataSuccess, metadataFailure); - } + this._surfaceShaderSet = new GlobeSurfaceShaderSet(); + this._material = undefined; - requestMetadata(); - } + this._surface = new QuadtreePrimitive({ + tileProvider : new GlobeSurfaceTileProvider({ + terrainProvider : terrainProvider, + imageryLayers : imageryLayerCollection, + surfaceShaderSet : this._surfaceShaderSet + }) + }); - defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { - /** - * Gets the URL of the Google Earth MapServer. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; - } - }, + this._terrainProvider = terrainProvider; + this._terrainProviderChanged = new Event(); - /** - * Gets the url path of the data on the Google Earth server. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {String} - * @readonly - */ - path : { - get : function() { - return this._path; - } - }, + makeShadersDirty(this); /** - * Gets the proxy used by this provider. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Proxy} - * @readonly + * Determines if the globe will be shown. + * + * @type {Boolean} + * @default true */ - proxy : { - get : function() { - return this._proxy; - } - }, + this.show = true; - /** - * Gets the imagery channel (id) currently being used. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} - * @readonly - */ - channel : { - get : function() { - return this._channel; - } - }, + this._oceanNormalMapResourceDirty = true; + this._oceanNormalMapResource = new Resource({ + url: buildModuleUrl('Assets/Textures/waterNormalsSmall.jpg') + }); /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * The maximum screen-space error used to drive level-of-detail refinement. Higher + * values will provide better performance but lower visual quality. + * * @type {Number} - * @readonly + * @default 2 */ - tileWidth : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); - } - - return this._tileWidth; - } - }, + this.maximumScreenSpaceError = 2; /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * The size of the terrain tile cache, expressed as a number of tiles. Any additional + * tiles beyond this number will be freed, as long as they aren't needed for rendering + * this frame. A larger number will consume more memory but will show detail faster + * when, for example, zooming out and then back in. + * * @type {Number} - * @readonly + * @default 100 */ - tileHeight : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); - } - - return this._tileHeight; - } - }, + this.tileCacheSize = 100; /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} - * @readonly + * Enable lighting the globe with the sun as a light source. + * + * @type {Boolean} + * @default false */ - maximumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); - } - - return this._maximumLevel; - } - }, + this.enableLighting = false; /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * The distance where everything becomes lit. This only takes effect + * when <code>enableLighting</code> is <code>true</code>. + * * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); - } - - return 0; - } - }, - - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {TilingScheme} - * @readonly + * @default 6500000.0 */ - tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme; - } - }, + this.lightingFadeOutDistance = 6500000.0; /** - * Gets the version of the data used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * The distance where lighting resumes. This only takes effect + * when <code>enableLighting</code> is <code>true</code>. + * * @type {Number} - * @readonly - */ - version : { - get : function() { - if (!this._ready) { - throw new DeveloperError('version must not be called before the imagery provider is ready.'); - } - - return this._version; - } - }, - - /** - * Gets the type of data that is being requested from the provider. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {String} - * @readonly - */ - requestType : { - get : function() { - if (!this._ready) { - throw new DeveloperError('requestType must not be called before the imagery provider is ready.'); - } - - return this._requestType; - } - }, - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - if (!this._ready) { - throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme.rectangle; - } - }, - - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); - } - - return this._tileDiscardPolicy; - } - }, - - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Event} - * @readonly + * @default 9000000.0 */ - errorEvent : { - get : function() { - return this._errorEvent; - } - }, + this.lightingFadeInDistance = 9000000.0; /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * True if an animated wave effect should be shown in areas of the globe + * covered by water; otherwise, false. This property is ignored if the + * <code>terrainProvider</code> does not provide a water mask. + * * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, - - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; - } - }, - - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Credit} - * @readonly + * @default true */ - credit : { - get : function() { - return this._credit; - } - }, + this.showWaterEffect = true; /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * True if primitives such as billboards, polylines, labels, etc. should be depth-tested + * against the terrain surface, or false if such primitives should always be drawn on top + * of terrain unless they're on the opposite side of the globe. The disadvantage of depth + * testing primitives against terrain is that slight numerical noise or terrain level-of-detail + * switched can sometimes make a primitive that should be on the surface disappear underneath it. + * * @type {Boolean} - * @readonly + * @default false + * */ - hasAlphaChannel : { - get : function() { - return true; - } - } - }); - - /** - * Gets the credits to be displayed when a given tile is displayed. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. - */ - GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function(x, y, level) { - return undefined; - }; - - /** - * Requests the image for a given tile. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. - * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. - */ - GoogleEarthEnterpriseMapsProvider.prototype.requestImage = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); - } - - var url = buildImageUrl(this, x, y, level); - return ImageryProvider.loadImage(this, url, request); - }; - - /** - * Picking features is not currently supported by this imagery provider, so this function simply returns - * undefined. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. - */ - GoogleEarthEnterpriseMapsProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return undefined; - }; - - GoogleEarthEnterpriseMapsProvider._logoData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAAnCAYAAACmP2LfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAHdElNRQfcDB4TJDr1mp5kAAAAGnRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAB1zSURBVHhe7ZwHeFTFFsf/u+l9N70npOxuSAKEFFIhCSH0qhEQUHkgKCgWUFGBB6IoCAoo0ntooaRvEkIIBBBpoYSa3nvvfd+5u4sQUigPfMX8v2/Y3Tkzs3fv/d0z58zcgF69Ql1SY+MM1wQJem44ZeiJk8beEOqPwG6uC7ZqyElb9eo/JZEIkH2nRQkBIlNMauuPCS3uGN/kjkmNDghoskBAgzrZ2NLmf1+JwIKQpYsoxdmIV9+N07onCegzBPM9bOdmYKnazF6g/1N6UySPqSJzvCaaiLHtP8G/Phq+FRfgU5ogKWUXMLT6Mvzqr2BE40mMadqO8c3zMabBC6PqDDC8SlY60t9HByCLVTKu+ERmHr5TWI9wjVxEaOZivWo1pil8D1tZeWnLXv1l8iZ3PF2kjymiWRgvCoJv5U243IyAXcQq8A9Mg9W+4bDe6wv+kVGwCZkL+4Sf4ZR+BZ5VGQR3EkbWn8Hopm3wq54Lz2JD6ah/P21XGopQ9Qoc16jGSqVyTJWbQbUsibFXf42mihTwZpsvAtp3k0dOhFOSEH1+ngaDefrgjFCgFkxY8fCisCBvKgODzxRh9qslBFGfYmDGLbiV5mBwRRo8KtPhVBgPu8teMP7u73chD6kMRYRGBY5xqrFKqQwz5SdTbS/Qf5mmUYw8rf01CjHC4VP7AHZxO6E3qy9ZZCQNnio2rE/4o9/tkxiQUYp+KRXgx8XC5FsXcLz/hkCrDUU4pxLHuDVYpdwL9F+qqSJZKlPwenskfOoI5tN7YPCJGVme7wKYr5EBXzgYfW+mwTI0Gjrznaj2WW+I/y8dVPdDGLcKRzXrsEqlHO8oTKHaXqAZWe9hQXCi63NhHWYI3ilfWIW/YLjqL2JRiOFBJRz+LffhcPs09D+0J8vzn3zXdBnYnp8Mi6NboTWzH9X8fVc+DhDQodxqAroe36lU9AJNWr4cEAjNwI8OAC9cT1rbUfzwGeCfKiL7dGnNc+q1NiO80b4BY1oT4V6WDcsdc6j2xbyq4wMWrA9rQmeWFn36ey/jBaoPQ4hmLYI0G/AtAf22fC/QDols8ITrIYi/Bl6knbS2o3gRbxHQxQQ0k0S/gCa2v4OJovPwacqAQ1ICjL40klr+UrWoQbFBETo18jCpZsOoFODkvuCNJYoHW3QKXFEM7ETRcKfiQe8d6NVIFImXvg4skhY40mxnQYVRIIeA1qrHEc1GrFSpxFtP99AiFbDbNKDZpAzzGkVYVcvBuBJQEo/9/6C+dyjPitwLwak74D8V6Bfw0P5VShjXFoTR7TfhUZkL29M/wfATJan1lauWC3aDOgyaVDCuTgbf1bFkfmtkye1ogsK2asivLYfCglIoD8qCknI2NHuG4QSVGMgQyMbt0fioRYh9VYcRU7QX55uDcaHtFOJEsThMtmWtQgxsDodsWaC0c3ea3MzGBJEqxrfbYmzr6xjfPAeTmt5HQPO7eK1xDibUz8eY+k8xtHYJPCtXwvHOu7AXMrMTsF/TH8HajTis1YwVqpWY0TXQDKy1OpBr5EJA52Fukxx+bmKxtjWx2DuaWawNlZD5qhzyo9KhpHAbKpJO/6t65UCPbPHA2PYrGNacgkElabCJJDev/MpDhUKKnuq44LRoYEK1IiswkS1zYCfk5y+F0qjvoTwqBOof34dGeAnUL1ZCLboEnJ9zoe0QD/Nuj00UBVXRabzVLETM3S0ICfwA8yc7Y6C3ANYbZsA7aQ1W1xzEfZEQ6dT2BkG9pP4ouo7jGE1u42JS20QMrzkCr4xwuN4+AM+cYII3EaNar2J86zmMrP8DHulCON4NhU3YWuhOYy6SZENpH9cfx7WacFC7BSvUqjBDsRPQIiugURvazeqYVaqAw6dYrJ9WQy7gayj4nYDy3HtQOVQGpYRqKEWXQf2HdGha/AFdae9Xr4czz0ubISRA75ECbSut7agegO75OLxpahze8j5GtifBpzEDLiV30Dd2mNT6StWiCbVmLt5rUkBQCEt2zWzIMSA8HgrIBkLD+Sp0jhHISYXQ/KMYukfvQ3fQxq68XCTBHId/tMTg7LV1CFs4BszJ6hBarBgHlcRv8H7tbuSKQpFPYGe0BmND+nZ0npECaPKf0r4UIxsuoF/IMpitsAVnrA4s15uh3x8fwLXkLobUZGJIXTqcUzbDaJE5FAVq0t4S7dEcjqMEc6B2K5arVWN6Z6AbdOmm5mJelQKOHWSxF44Cy4CqxW0s6RwchCovFRohdGNfLgX3WiZ0N4aD++y7jfwYJUrAPCle/ZjKV+BFTSegrGAZIm3QjXhBytTWB3zhByzryMUU986jz16wD+96ijCNUIAgmkc3tS6G7GERjCbgR82B4OTbEESqIiCIcqsIYzoGGyrBEMSmgh8xBoIIAR2fAHZhj8Z9DOhl9FHeKkSDvn809fuc+iyCddRYaiOZBTvIt1YJfs0b4N+WDO+GHPLQN2Ab7S61vjJV60C9SRPvNSqzTpxlyQfS1dGUmjppK7gW16B/LhN6abnQu5cDwzO3YNhhqqK4WJY887sEdGzWFpxfOxmDpKZOOvgWFB8sx9L6nShvP4FyUQjKGg5gScpGKEqbUE7RxiGYv6QQ4zIG/r4D2m88sjEy/EIW/a6+TQ4gHe5VhXCvy4JL7gLYnesI2i6t4Tii04r92u1YKt767gB0ozrkGzmY26zEOh7Hkt+kAKhLTX9qOVVdg9aoNOjcToR+wUVKLYKgN0Zq7l7884wn9CKgr4AfWw/B6SwqKQRKOdXVghe9CpbherASSjtIpGpxRIHFjwygNreoXy0lb+lU7lHJBP9kPcGXQnBNghUB/Lh44fbUp5JA+5Hs71LbPPLCVRDEJZDNGIJgeQI6mG6KegKzldq1U7tGKjQmHR8vwl86kgRoAQN0xBw6ztn0nQ/ocxEdQ7L4d/BjG6g+m8aZTL/xsXPuW82Fb8t+DG1Ox5D6XAwqvQ67OA+p9ZWoUQPsei78mjSwNU9GLmEzVGZJTd3qFPTn3YZhXgYMMjNhlHsDxms/hNWfoUdrNPgEc2h7BG5d/Bo7Blt0BuNxXf4MVmXrkdRyEHWiY6hr2oc7mevRX2wc18gioEeI1+N9a+/CNnImVAZ0mhEoNOPAJT8MHjUF8KTiWhqHgbfMpVaJdhLQh3XasU9bJAZ6ekeg6zQwgEKuLSWysmd3QGmatLqD8qDNug3dCX/AIPk4jGr2wDB/JXTmkan70IvmZTY/rB9BdZlKLkG0lG0d5klAObKsw1+jzyFiWPnRawiaDrMYwTyMwMwh220WP2IWFVfqN4CKO8E3n0C6R/ZUej9Y2kUiMdDRFTRePH3nA3q/m7xpAEtAXl0QrkTwscnmS/3eptdzNEYevZLnZ5booqk8tuYs9tAny+n1LL1mghezlcULH0VtHamOZhvhIvoNOXQsd2EZIbluYnlWaMO75TCFG9kYXJ8H14o76H/10Z3yClSrCm6jGtbWK7LC7kIlYRfUmY2XHnUa+mbXYRSfCuNCptyE6b1jMBD/EPKwchQPLxGdxOWWI8iKXYBPqLozgI8pfA5YBWvxbfMeNLUfRmPTLjRnr8YKsdGvRQ5j2zZTSSRQ78H+7GhxfScFAINypsG9ukDspZ0LKKE+O0pqlGi71ggcIqD3dga6RhFKjSqYT+VEFkvu/E9Q+HNWKaE2VVDgVkPFqwAaay5CN3En9M59BM2vfKDs7AvljjPGE5LlharQdL+LoCmhOHU0rIUyD+NgVTOa+q2iVQiIcAKpHtbhXuJOjPqeVCRYThNE6VTvKNs3hM3cHGIxntxKyCbP7Erj1lHZJbVIJAG6iiCroZCAPGukvOyASJbvCgoaAoKoAQ1kHcGC7nmZDkmhBR2PfSQLtkcl4zCSAE2eO6qExYuYxrE4KqdvelBiM4+ncYQy1IY8d0wbhUSLJAZGbsUceNYdwJCGPAyuy4NbZToG3JoO1Qk9AvHvqF4ejo0KCKlisyl04Jw+AE1ma71HRUJP+QqM1t2HcVEyTEoSYVYQCuN3HenCt4XDhGA+KorAnYZ9KIj5ELOl3XpU/k/wrt+OmraDaG7cjpacbxFvYAAZDG5Vw/DWCxjRdp+ATsWAS6+D69H1+XDNsoVb1T06b0VwzCmBIOYdqUWibTojcFBH1CXQctBtUcA6Oh/RmVC4sBmKA5j6erC1qqE4sRpqG25A43QIOHuXgvOmP5R4ZH6m5UY2L9SSLjZ5sKjjsI/o8olH8ngjCZoSgmw9DMIl3t42Up0g+pq89/sEjLK47knZhSkSuDepJP4JOyNJyEFAR8VQKMOR1nbWM69yxNJYwh+VLE90ffPyxLE3EwL9Jq0huWQqwL1iA7zq8+FVl0+epgBO6T+gb2TH+OglqgastxtZrNNlkLt8E5oJx6HZdab7mFZBk3UZRjMewCT7HkzLfodZxREYr5sBjiIBPYiAPt8ehvSGPSg5vwjzpd16VNkmmDTswp22QDTXbkJrxhJkzHGDFoUQmvBpvo2hrZl0TnLhlLIYfUO7nt7dSg3hURcP1/JiDEgphuXBqVKLRFsfA3oJAf3mI6Cr2OjTwGYdqWGzzmZD6WoYVCfehdqsZKjuuwS1oB1Q+5piHac3oaxBzZ9vLZ4nHEeesoXg6niDPSYWP9yUgD5PHu48eKE64krHcErchHIEuRysTpAXjObQWIYEHiV4EQYEojp5aEoyY+IIpOQugKYYOnIdJXrdJ63PtWwXMQM6m6SVT4gfZkbHV0XHsVtaQ3K8yoJr0YfwoHDDq5ZiQSqDik/B4Q9taYtn18gyNia1qGJsmTrGlUjK2FJ1jCjRwOASDnkxDvN95ZD/og5yl0qgfCMJ2leDoeksHaFHXYOJVyrMkm/DrPwMzGr2wmjnLGipthyHL0W7t9pDkduwF2U3lmGFtvbTdyirt0OreT+iWwPRUrUBbSkLkT/fCUZwKVYikBMwpDlPXNzLwuAQ2rWX8KzUh2dDDJyLSmB7/S5Mf3WRWiR6CPSezkCXQs6qBnLCKsheyoXqnTCoL9oOFd9/Qtl9KJT6UJMX3/zhCz8iuCjhiviSYtMx3ZTJBN8lCE7eIRgF0p6krRRaRBDskTTGySBKws5SuUjJHYUiMQdpzCUE0Q3y5MnSDhJJQg5JUvjSgO5hHZofaioGmvc40IycMgbRtJktjgOZ5Ma9irzSg46xYHcaVEZevkgBHqUWGFK+FENKQ+BdGAq/wiMYWbwHI6h4FwTDOes0BMKFMHxPNg9qn1dANakYanfuQSs5FJoTpaP1qBswsSGgb9+EeUU0Af0LDH4dBhXlmv3wajuOpPYQFDcEojxtNQ6sn9ZzUsiofjfUWg/iYOt+tJatRtvN95DqZgxNuKTKwLV4Jdyqc8Wz1uCGTLjmDIVDQqewQ8anwpJi6GsYkF4Ey2O/QvsfXKlJIgboAwT07s5AZ0G1TylUIsuhdKMI6vcuQ3PVAqg+9UZ8JvGEywiuNoIwD4IzaV2X+HSa1otgE3+NwJImVkycG0kx8snfyUZJW+QFApeSu+hN9BpIn6n+ZBp9bqDv+C8Fum+8IpzzJNOmR3UhTaGFcC07iAHXmamuZw28C/S/aIt+CcthF7+ToN0EQdhqOFzcBu/Sm/ApvAGX3DzYXIiF9jtWTJf74L6ZC83UfGg8SId2xnloSZKxp+gWjC0J6KSrMK8KhmnlSugtInpkCzaBV78Hl5oPoaLpECrLt+Bi4jfgS7t1q+YDUGsPwj5KDFsLlqD97JuIpmpZmP+TftM1ezjlxsOllM4H3eReDWHwKrOBW84jqMeK5OBTv4Bu6HxxgqU1s/N3MkAHSoH+ioCe+gjoJHB0s8ENLID6/UJo3E+GVlwoNEwY278tXhR50RhmeexzgmM8JXjdF36MHwEoiXn70Csv6gxBm8PiRc6gJFD1HDzFpq1cP0omo5QJZAfqQzH0f6uHZjQgeR4cC/IJZCnUtSkYVPAWBiX2/CdU/S7Ql+9TgtFCTaiP0qAEXA2yRsqwuzECziWZcM4tgv2DSljF7ID+l+JNh9+hY38HuvcYmLOhk5EEnVPfQOmpW+33YGaXhj53E2BWuxvGebOh5cPUX/sWSgXrsa9mB2qaDqCK4C7I2IA3jn8u7tat2g6D034MIbWb0fZgHlr2DscXUhNNuYdkYRPrg/7JiXDMLYBrZS6GNEZgVJM/JjWY4I16G4xr/BCDq2nKjjoAvY+Zpwo7eXBskQK9Swr0lEdAn4a2wk3o/DMNWmn54KYUQIuZsebGQuXFQ42H4kfNk4QckSOkNZ1lGkGAUoInOKkAm2jJsVtH+om9Nj9ytZxNcNdhljXByo+JJXj/i4G2u2xM02YInPJLxFB7VudTPH0ZHkWu0hbPpwHpfnAszoFDVgVsb1fDMmoL9L8S7wTFQE/1AvR33oB+QSp0czKgl34B2iO9uwJCKib5SGaZjbqLPlkhMG1YDr1gQyioSs24vQTDitagsnIL6loCUVu9C2EJK9FjYtsWBNP2Q7hb9A155zdwY5mTeGexo0w32hEcy2F7JQaOqZfgk38KY6rDMKFBiGHNt+iGPgCNYd0/s/sbAb2fgN5JQC9Wq8bkR0AzioOOx3Xo30mGbnY+tNMKoJOQCm03qfnFxRf6E1yUFAqZJcyuZRWuQmB+TWHJcgJfkjPxImcSSIUsXviMx/O9DvqfALrPDjb6nhuBAWkZ5JFKKTYuIqhz4FUdAo9CGwzO7Ra2LjUg0w9OxdlwyKxAXzHQm8lDi4HeAT1WMPSHnYXR7aswKE6Gfl4K9PdfgZ6+uG8XSmMbKyXD/LsEmFduglH2NHA7rA3Hvg+Ve1/gYO4KNFRvQUPLQVRU7MG4yn1dJ4eiULAo3JhW9xsa77+Hml8GY8FQ425uAM5wRRivNoPlTjs4XhoH35oLGFZ/S/wglyDkbWmrrsUAvY+A3kHlSwJ6ihKzCvLnuQyElmIs9LdfhmHxA+jn5kI3jcrRFOjxU6DTbTx9DybsOBh0f034EeYEVyaFD0IYhnQ9y1pTIsiPvU5AnKYkUBL78yKmQhDLgDRPSWtPp/HFkFtHqFCfRBr73wX67qsD+qFsEubCnqKBAZllcCkkT12RjSHVMfApH0bJXfcH+aQGZg6FU1EWeeoK2NwgoMM3Q++zP/fq/Smf2g392ZEwzk2Acfl9GBHURmuSYPyn132oHBizH8B8wjX0SadQI2cWtOZZQbHTdEgRn8XN93EiczFayn5GU3Mg7lJMPab5SEeoCWZZ0TF4Ne/A/ZSPUbXdDz9Qdddrrk/KtcwR7jX34VXDzGCFGFT0GzyLu922x069kdiv145tOu34jlOHBWoz4arUAZQt0LYOhmFcHJ2H6zAsYnZDc2FwKhv60+m9UQrLUJ4hSYQAVhpM1O6jj30EDD33Q6frZyoY8cMVaWZZR560kuB5V9H6iVUas+Py5L1/IHsT2ZldR4nEkMdkUd8Y8tYd43mLIMhYhenDWvgjQSQiGFOkiEv0rEAzK2u8yG10M2WwBWFdb6q9NKDNd6rCOuYD9L2VI/57QMfcEniU5cCnJgG+lR9haAnz4MzT5ZjmA4e8HBqnGtYXamF+nK7bpx0uwHxoqGyE3sKD5HHjYVJ1C6Z5qTD5Ph2G1hnQEV/0LBhxU2E+4yYsbgTCJGsuNBfYQrnjA0CPxDo2CRYJ0xGesgD1ZWvQ3LQbKeSJ54uC0UcUDVVRGExFR/FB2y7cSf4C+Zv9sXSUeQ9P2z2pQdnmBHQsPKqKqFCyWJsM75o1GMw8O/iEhFZs/KK9CD9wRfhCTYTP1dqwnBOHrQYz8IuuH5ZxxI/MLQZH5kfoeu6D4cVQGNecgXHFbRgXZsD4Xg5MjqfDeE0KTBbRDLXsLiwOR8HkxCJoOs+Eavdr08ZBBGdYP7rYzAZILsH3LYUYtgSsAXlYRwLqW0r8Ksl2id4/Onaz47IE+kayUfwddYhsgwkqXRrLgOpHEuyhVF9B7ytoTAL//qNjeFagGfGEi5nvYPEifqOx/ek4p1J/8aKBWC8N6Icy2+oL6zOhECTmw46SuoHZpXBn/pK7/DK8K1bCp3Q0vAv7wqfIBD55OuS9teFVYASPfAFccseThw+E4Ho5LOMqYB6ZCeOdK6H1bleJH2sOOPZradqlC3otDqY5F2GafQmmCZdgFnMBZteEML2yCnprh0CZWVp66gbDuD5Q2uSLUacm43jSB0gq+h55JeuRX7wRqUUbkJL8DS4GTcPqCdZgduZ6XiZjgvcp9fIY3aAH/yY+3KvcMDBjLSXQBXDML4VbaQG8a9PgUxcOzyIneKY/Or6FHDO8q7INY+RiMFJaJijE4i2VeEylej/FDs99TAPH8Dvofv8bDK/vhVHxMRhX0W+vOgXTijiY5UXANGkNnYeRUGN2VrsPNx6XVaQNgRNM03sBgUjeOKJJ/Cr+LNzFsg61YB5/elyKtic0qM031CaZAG0gqJnVEuYBIoI49gy9D6DXrQR3GoU2j3YE+WE2FI9TGBG1FLywnhNbPt1Y/OhY+o5iGqsGNmdLaVxfqZUB+g0Iztwi2AOkNZ3FCzOm30bHeHK9tKYHKfPZMFhlAtM9c2EpjALv93zY3qlE/8xyOOUVUTiSBrfy83CvDIdbRZC4uJSGwzHzd0qgkmEVfRnGW/dC79vPobtkFLRmm0HDpVt43MnrzoOm/dfQeeOf0P3wB+guJogXrIDuhHfAsdOFbKdQ5GkaYQbNNYNht2c8/AOnYNKB6Ri//Q14zRwIuohdPC76pCbWKGFCkx9GNC7B0NZD8CiJh8Odi7A59zud7EuwvU4hVUYZBhUXwqsqA56V0RiUM1Dam36UoiyFuprQhc6fRZuKKhV5+rcLKD2hrPQ+NPsvgNb0j6C9eCG0v/kU2l9/BK0ZM8EdRJQ833noG8Qib6lDkA0lYD6i8GIJlffZ/IhhbJtQjW4TP164EiWWztTnH9T+a4L/MxpjAn02hWWYDAQnefSZzm7Io7zDOpiSzGh3grwPwd3zDccPZdH4phBEkXcWBrD4wlE07qObw5pmBUGsK43T/YPfgmAFWEe5U2EeCXhGcV5nQ3u2KrTf6w+jdTNhtud7mB/ZC4vg43QAwbAMDYLF0e3os+8HGP80D7oLx0F9dD+oj9AGZ4Y85K0Yj/Vs3kQiFgeybFPIySiDzdwAz9O3JzHjPNtYk8gjv948FOOatlGodR0Dk07Bau9n0F8wFBp+luBO1CXeuDD51Q3830PRP7UIzgUlcC0vhHPRSdic6eI53ecT3W0sKyjI2EFRxhzyz3sOO8voBkEUTclYhAyshCwr642PR79diwlbBOEs8vLMFjgbbuelhpeoz5rEDxsNNl/+9ON5RWJOLsXCysQdh5IhWWbzhUmoel6v/l/RxGpZTKgbh3EtEZQMp5AX2ASd2f3AVu7695ky/7nOuc2U/BZSCFIGp+I82F/rfprsVa/+Mk0sZ2F0tTvGNZ+gRO8B7C/HQ92beWine+/IDWDBbJUmbBN/hUNOGRyyStH34vfQeP3ZV4R61atXIu9Kefg1rIB/XRJciwso9nymLXmxbP+wxcCsVAxIKwfv1AZoDH96jN6rXr1SuVeowKsuFINrs+BSXATbc59JLU/XwCwdDMw7B/vUEpgHfQYZ7v9HCNar/2E55ynDpSwYrhXF4uKUeQiY0/Oy3kM555nCITcJgmvp0F30Yo8L9KpXL1X9E2XhkPoVBuYWwbmolKDOhmv+WHiXyGNkgbTRE1pOublXkRycCz+AfUoRzPdsgKJN1w/19KpXf7n6xlnCPikE/SkWdswrozDkNoZUfIWhFTYYWaPy4a6NkgSR2XAZXSOLIWUWcCv7FP1T7sH8wFZwp7ycxz971auXIm4AG+b77MFLEKLv7ULJMy0FefCsPAOv0t0YUrIMg0s+gVfxYrgVbIJLUSzsrl2F2ZZl4L7J/Pdp/956ca969UrEna0O41/HwSJ4F3in42Fz5Trsbt5Bv3u30e9uImyvnoV15GGY/LIA6kOZP1966pZ8r3r1n5eqhwZ0F/aB4ToHGK9zh/FPHjD60RE6H1tDaaA2cdy7mvFfI+BffksPNrEksu0AAAAASUVORK5CYII='; - - function buildImageUrl(imageryProvider, x, y, level) { - var imageUrl = imageryProvider._imageUrlTemplate; - - imageUrl = imageUrl.replace('{x}', x); - imageUrl = imageUrl.replace('{y}', y); - // Google Earth starts with a zoom level of 1, not 0 - imageUrl = imageUrl.replace('{zoom}', (level + 1)); - - var proxy = imageryProvider._proxy; - if (defined(proxy)) { - imageUrl = proxy.getURL(imageUrl); - } - - return imageUrl; - } - - return GoogleEarthEnterpriseMapsProvider; -}); - - -define('Scene/GridImageryProvider',[ - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - '../Core/GeographicTilingScheme', - '../ThirdParty/when' - ], function( - Color, - defaultValue, - defined, - defineProperties, - Event, - GeographicTilingScheme, - when) { - 'use strict'; - - var defaultColor = new Color(1.0, 1.0, 1.0, 0.4); - var defaultGlowColor = new Color(0.0, 1.0, 0.0, 0.05); - var defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2); - - /** - * An {@link ImageryProvider} that draws a wireframe grid on every tile with controllable background and glow. - * May be useful for custom rendering effects or debugging terrain. - * - * @alias GridImageryProvider - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. - * @param {Number} [options.cells=8] The number of grids cells. - * @param {Color} [options.color=Color(1.0, 1.0, 1.0, 0.4)] The color to draw grid lines. - * @param {Color} [options.glowColor=Color(0.0, 1.0, 0.0, 0.05)] The color to draw glow for grid lines. - * @param {Number} [options.glowWidth=6] The width of lines used for rendering the line glow effect. - * @param {Color} [options.backgroundColor=Color(0.0, 0.5, 0.0, 0.2)] Background fill color. - * @param {Number} [options.tileWidth=256] The width of the tile for level-of-detail selection purposes. - * @param {Number} [options.tileHeight=256] The height of the tile for level-of-detail selection purposes. - * @param {Number} [options.canvasSize=256] The size of the canvas used for rendering. - */ - function GridImageryProvider(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); - this._cells = defaultValue(options.cells, 8); - this._color = defaultValue(options.color, defaultColor); - this._glowColor = defaultValue(options.glowColor, defaultGlowColor); - this._glowWidth = defaultValue(options.glowWidth, 6); - this._backgroundColor = defaultValue(options.backgroundColor, defaultBackgroundColor); - this._errorEvent = new Event(); - - this._tileWidth = defaultValue(options.tileWidth, 256); - this._tileHeight = defaultValue(options.tileHeight, 256); - - // A little larger than tile size so lines are sharper - // Note: can't be too much difference otherwise texture blowout - this._canvasSize = defaultValue(options.canvasSize, 256); - - // We only need a single canvas since all tiles will be the same - this._canvas = this._createGridCanvas(); - - this._readyPromise = when.resolve(true); - } + this.depthTestAgainstTerrain = false; - defineProperties(GridImageryProvider.prototype, { /** - * Gets the proxy used by this provider. - * @memberof GridImageryProvider.prototype - * @type {Proxy} - * @readonly + * Determines whether the globe casts or receives shadows from each light source. Setting the globe + * to cast shadows may impact performance since the terrain is rendered again from the light's perspective. + * Currently only terrain that is in view casts shadows. By default the globe does not cast shadows. + * + * @type {ShadowMode} + * @default ShadowMode.RECEIVE_ONLY */ - proxy : { - get : function() { - return undefined; - } - }, + this.shadows = ShadowMode.RECEIVE_ONLY; - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - return this._tileWidth; - } - }, + this._oceanNormalMap = undefined; + this._zoomedOutOceanSpecularIntensity = 0.5; + } + defineProperties(Globe.prototype, { /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {Number} - * @readonly + * Gets an ellipsoid describing the shape of this globe. + * @memberof Globe.prototype + * @type {Ellipsoid} */ - tileHeight : { + ellipsoid : { get : function() { - return this._tileHeight; + return this._ellipsoid; } }, - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {Number} - * @readonly + * Gets the collection of image layers that will be rendered on this globe. + * @memberof Globe.prototype + * @type {ImageryLayerCollection} */ - maximumLevel : { + imageryLayers : { get : function() { - return undefined; + return this._imageryLayerCollection; } }, - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {Number} + * Gets an event that's raised when an imagery layer is added, shown, hidden, moved, or removed. + * + * @memberof Globe.prototype + * @type {Event} * @readonly */ - minimumLevel : { + imageryLayersUpdatedEvent : { get : function() { - return undefined; + return this._surface.tileProvider.imageryLayersUpdatedEvent; } }, - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {TilingScheme} + * Gets an event that's raised when a surface tile is loaded and ready to be rendered. + * + * @memberof Globe.prototype + * @type {Event} * @readonly */ - tilingScheme : { + tileLoadedEvent : { get : function() { - return this._tilingScheme; + return this._surface.tileProvider.tileLoadedEvent; } }, - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {Rectangle} - * @readonly + * Gets or sets the color of the globe when no imagery is available. + * @memberof Globe.prototype + * @type {Color} */ - rectangle : { + baseColor : { get : function() { - return this._tilingScheme.rectangle; + return this._surface.tileProvider.baseColor; + }, + set : function(value) { + this._surface.tileProvider.baseColor = value; } }, - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly + * A property specifying a {@link ClippingPlaneCollection} used to selectively disable rendering on the outside of each plane. Clipping planes are not currently supported in Internet Explorer. + * + * @memberof Globe.prototype + * @type {ClippingPlaneCollection} */ - tileDiscardPolicy : { + clippingPlanes : { get : function() { - return undefined; + return this._surface.tileProvider.clippingPlanes; + }, + set : function(value) { + this._surface.tileProvider.clippingPlanes = value; } }, - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof GridImageryProvider.prototype - * @type {Event} - * @readonly + * The normal map to use for rendering waves in the ocean. Setting this property will + * only have an effect if the configured terrain provider includes a water mask. + * @memberof Globe.prototype + * @type {String} + * @default buildModuleUrl('Assets/Textures/waterNormalsSmall.jpg') */ - errorEvent : { - get : function() { - return this._errorEvent; + oceanNormalMapUrl: { + get: function() { + return this._oceanNormalMapResource.url; + }, + set: function(value) { + this._oceanNormalMapResource.url = value; + this._oceanNormalMapResourceDirty = true; } }, - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof GridImageryProvider.prototype - * @type {Boolean} - * @readonly + * The terrain provider providing surface geometry for this globe. + * @type {TerrainProvider} + * + * @memberof Globe.prototype + * @type {TerrainProvider} + * */ - ready : { + terrainProvider : { get : function() { - return true; + return this._terrainProvider; + }, + set : function(value) { + if (value !== this._terrainProvider) { + this._terrainProvider = value; + this._terrainProviderChanged.raiseEvent(value); + if (defined(this._material)) { + makeShadersDirty(this); + } + } } }, - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof GridImageryProvider.prototype - * @type {Promise.<Boolean>} + * Gets an event that's raised when the terrain provider is changed + * + * @memberof Globe.prototype + * @type {Event} * @readonly */ - readyPromise : { - get : function() { - return this._readyPromise; + terrainProviderChanged : { + get: function() { + return this._terrainProviderChanged; } }, - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link GridImageryProvider#ready} returns true. - * @memberof GridImageryProvider.prototype - * @type {Credit} - * @readonly + * Gets an event that's raised when the length of the tile load queue has changed since the last render frame. When the load queue is empty, + * all terrain and imagery for the current view have been loaded. The event passes the new length of the tile load queue. + * + * @memberof Globe.prototype + * @type {Event} */ - credit : { - get : function() { - return undefined; + tileLoadProgressEvent : { + get: function() { + return this._surface.tileLoadProgressEvent; } }, /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof GridImageryProvider.prototype - * @type {Boolean} - * @readonly + * Gets or sets the material appearance of the Globe. This can be one of several built-in {@link Material} objects or a custom material, scripted with + * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}. + * @memberof Globe.prototype + * @type {Material} */ - hasAlphaChannel : { - get : function() { - return true; + material: { + get: function() { + return this._material; + }, + set: function(material) { + if (this._material !== material) { + this._material = material; + makeShadersDirty(this); + } } } }); - /** - * Draws a grid of lines into a canvas. - */ - GridImageryProvider.prototype._drawGrid = function(context) { - var minPixel = 0; - var maxPixel = this._canvasSize; - for (var x = 0; x <= this._cells; ++x) { - var nx = x / this._cells; - var val = 1 + nx * (maxPixel - 1); + function makeShadersDirty(globe) { + var defines = []; - context.moveTo(val, minPixel); - context.lineTo(val, maxPixel); - context.moveTo(minPixel, val); - context.lineTo(maxPixel, val); - } - context.stroke(); - }; + var requireNormals = defined(globe._material) && (globe._material.shaderSource.match(/slope/) || globe._material.shaderSource.match('normalEC')); - /** - * Render a grid into a canvas with background and glow - */ - GridImageryProvider.prototype._createGridCanvas = function() { - var canvas = document.createElement('canvas'); - canvas.width = this._canvasSize; - canvas.height = this._canvasSize; - var minPixel = 0; - var maxPixel = this._canvasSize; + var fragmentSources = []; + if (defined(globe._material) && (!requireNormals || globe._terrainProvider.requestVertexNormals)) { + fragmentSources.push(globe._material.shaderSource); + defines.push('APPLY_MATERIAL'); + globe._surface._tileProvider.uniformMap = globe._material._uniforms; + } else { + globe._surface._tileProvider.uniformMap = undefined; + } + fragmentSources.push(GlobeFS); - var context = canvas.getContext('2d'); + globe._surfaceShaderSet.baseVertexShaderSource = new ShaderSource({ + sources : [GroundAtmosphere, GlobeVS], + defines : defines + }); - // Fill the background - var cssBackgroundColor = this._backgroundColor.toCssColorString(); - context.fillStyle = cssBackgroundColor; - context.fillRect(minPixel, minPixel, maxPixel, maxPixel); + globe._surfaceShaderSet.baseFragmentShaderSource = new ShaderSource({ + sources : fragmentSources, + defines : defines + }); + globe._surfaceShaderSet.material = globe._material; + } - // Glow for grid lines - var cssGlowColor = this._glowColor.toCssColorString(); - context.strokeStyle = cssGlowColor; - // Wide - context.lineWidth = this._glowWidth; - context.strokeRect(minPixel, minPixel, maxPixel, maxPixel); - this._drawGrid(context); - // Narrow - context.lineWidth = this._glowWidth * 0.5; - context.strokeRect(minPixel, minPixel, maxPixel, maxPixel); - this._drawGrid(context); + function createComparePickTileFunction(rayOrigin) { + return function(a, b) { + var aDist = BoundingSphere.distanceSquaredTo(a.pickBoundingSphere, rayOrigin); + var bDist = BoundingSphere.distanceSquaredTo(b.pickBoundingSphere, rayOrigin); - // Grid lines - var cssColor = this._color.toCssColorString(); - // Border - context.strokeStyle = cssColor; - context.lineWidth = 2; - context.strokeRect(minPixel, minPixel, maxPixel, maxPixel); - // Inner - context.lineWidth = 1; - this._drawGrid(context); + return aDist - bDist; + }; + } - return canvas; + var scratchArray = []; + var scratchSphereIntersectionResult = { + start : 0.0, + stop : 0.0 }; /** - * Gets the credits to be displayed when a given tile is displayed. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * Find an intersection between a ray and the globe surface that was rendered. The ray must be given in world coordinates. * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. - */ - GridImageryProvider.prototype.getTileCredits = function(x, y, level) { - return undefined; - }; - - /** - * Requests the image for a given tile. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * @param {Ray} ray The ray to test for intersection. + * @param {Scene} scene The scene. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3|undefined} The intersection or <code>undefined</code> if none was found. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. + * @example + * // find intersection of ray through a pixel and the globe + * var ray = viewer.camera.getPickRay(windowCoordinates); + * var intersection = globe.pick(ray, scene); */ - GridImageryProvider.prototype.requestImage = function(x, y, level, request) { - return this._canvas; - }; + Globe.prototype.pick = function(ray, scene, result) { + if (!defined(ray)) { + throw new DeveloperError('ray is required'); + } + if (!defined(scene)) { + throw new DeveloperError('scene is required'); + } + + var mode = scene.mode; + var projection = scene.mapProjection; - /** - * Picking features is not currently supported by this imagery provider, so this function simply returns - * undefined. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. - */ - GridImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return undefined; - }; + var sphereIntersections = scratchArray; + sphereIntersections.length = 0; - return GridImageryProvider; -}); + var tilesToRender = this._surface._tilesToRender; + var length = tilesToRender.length; -define('Scene/InvertClassification',[ - '../Core/Color', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/PixelFormat', - '../Renderer/ClearCommand', - '../Renderer/Framebuffer', - '../Renderer/PixelDatatype', - '../Renderer/RenderState', - '../Renderer/Sampler', - '../Renderer/ShaderSource', - '../Renderer/Texture', - '../Renderer/TextureMagnificationFilter', - '../Renderer/TextureMinificationFilter', - '../Renderer/TextureWrap', - '../Shaders/PostProcessFilters/PassThrough', - './BlendingState', - './StencilFunction', - './StencilOperation' - ], function( - Color, - defined, - defineProperties, - destroyObject, - PixelFormat, - ClearCommand, - Framebuffer, - PixelDatatype, - RenderState, - Sampler, - ShaderSource, - Texture, - TextureMagnificationFilter, - TextureMinificationFilter, - TextureWrap, - PassThrough, - BlendingState, - StencilFunction, - StencilOperation) { - 'use strict'; + var tile; + var i; - /** - * @private - */ - function InvertClassification() { - this.previousFramebuffer = undefined; - this._previousFramebuffer = undefined; + for (i = 0; i < length; ++i) { + tile = tilesToRender[i]; + var tileData = tile.data; - this._texture = undefined; - this._classifiedTexture = undefined; - this._depthStencilTexture = undefined; - this._fbo = undefined; - this._fboClassified = undefined; + if (!defined(tileData)) { + continue; + } - this._rsUnclassified = undefined; - this._rsClassified = undefined; + var boundingVolume = tileData.pickBoundingSphere; + if (mode !== SceneMode.SCENE3D) { + BoundingSphere.fromRectangleWithHeights2D(tile.rectangle, projection, tileData.minimumHeight, tileData.maximumHeight, boundingVolume); + Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); + } else { + BoundingSphere.clone(tileData.boundingSphere3D, boundingVolume); + } - this._unclassifiedCommand = undefined; - this._classifiedCommand = undefined; - this._translucentCommand = undefined; + var boundingSphereIntersection = IntersectionTests.raySphere(ray, boundingVolume, scratchSphereIntersectionResult); + if (defined(boundingSphereIntersection)) { + sphereIntersections.push(tileData); + } + } - this._clearColorCommand = new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 0.0), - owner : this - }); - this._clearCommand = new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 0.0), - depth : 1.0, - stencil : 0 - }); + sphereIntersections.sort(createComparePickTileFunction(ray.origin)); - var that = this; - this._uniformMap = { - u_texture : function() { - return that._texture; - }, - u_depth : function() { - return that._depthStencilTexture; - }, - u_classified : function() { - return that._classifiedTexture; + var intersection; + length = sphereIntersections.length; + for (i = 0; i < length; ++i) { + intersection = sphereIntersections[i].pick(ray, scene.mode, scene.mapProjection, true, result); + if (defined(intersection)) { + break; } - }; + } + + return intersection; + }; + + var scratchGetHeightCartesian = new Cartesian3(); + var scratchGetHeightIntersection = new Cartesian3(); + var scratchGetHeightCartographic = new Cartographic(); + var scratchGetHeightRay = new Ray(); + + function tileIfContainsCartographic(tile, cartographic) { + return Rectangle.contains(tile.rectangle, cartographic) ? tile : undefined; } - defineProperties(InvertClassification.prototype, { - unclassifiedCommand : { - get : function() { - return this._unclassifiedCommand; + /** + * Get the height of the surface at a given cartographic. + * + * @param {Cartographic} cartographic The cartographic for which to find the height. + * @returns {Number|undefined} The height of the cartographic or undefined if it could not be found. + */ + Globe.prototype.getHeight = function(cartographic) { + if (!defined(cartographic)) { + throw new DeveloperError('cartographic is required'); + } + + var levelZeroTiles = this._surface._levelZeroTiles; + if (!defined(levelZeroTiles)) { + return; + } + + var tile; + var i; + + var length = levelZeroTiles.length; + for (i = 0; i < length; ++i) { + tile = levelZeroTiles[i]; + if (Rectangle.contains(tile.rectangle, cartographic)) { + break; } } - }); - InvertClassification.isTranslucencySupported = function(context) { - return context.depthTexture && context.fragmentDepth; - }; + if (!defined(tile) || !Rectangle.contains(tile.rectangle, cartographic)) { + return undefined; + } - // The stencil mask only uses the least significant 4 bits. - // This is so 3D Tiles with the skip LOD optimization, which uses the most significant 4 bits, - // can be classified. - var stencilMask = 0x0F; - var stencilReference = 0; + while (tile.renderable) { + tile = tileIfContainsCartographic(tile.southwestChild, cartographic) || + tileIfContainsCartographic(tile.southeastChild, cartographic) || + tileIfContainsCartographic(tile.northwestChild, cartographic) || + tile.northeastChild; + } - var rsUnclassified = { - depthMask : false, - stencilTest : { - enabled : true, - frontFunction : StencilFunction.EQUAL, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.KEEP - }, - backFunction : StencilFunction.NEVER, - reference : stencilReference, - mask : stencilMask - }, - blending : BlendingState.ALPHA_BLEND - }; + while (defined(tile) && (!defined(tile.data) || !defined(tile.data.pickTerrain))) { + tile = tile.parent; + } - var rsClassified = { - depthMask : false, - stencilTest : { - enabled : true, - frontFunction : StencilFunction.NOT_EQUAL, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.KEEP - }, - backFunction : StencilFunction.NEVER, - reference : stencilReference, - mask : stencilMask - }, - blending : BlendingState.ALPHA_BLEND - }; + if (!defined(tile)) { + return undefined; + } - var rsDefault = { - depthMask : true, - depthTest : { - enabled : true - }, - blending : BlendingState.ALPHA_BLEND - }; + var ellipsoid = this._surface._tileProvider.tilingScheme.ellipsoid; - var translucentFS = - '#extension GL_EXT_frag_depth : enable\n'+ - 'uniform sampler2D u_texture;\n' + - 'uniform sampler2D u_depth;\n' + - 'uniform sampler2D u_classified;\n' + - 'varying vec2 v_textureCoordinates;\n' + - 'void main()\n' + - '{\n' + - ' vec4 color = texture2D(u_texture, v_textureCoordinates);\n' + - ' if (color.a == 0.0)\n' + - ' {\n' + - ' discard;\n' + - ' }\n' + - ' bool isClassified = all(equal(texture2D(u_classified, v_textureCoordinates), vec4(0.0)));\n' + - '#ifdef UNCLASSIFIED\n' + - ' vec4 highlightColor = czm_invertClassificationColor;\n' + - ' if (isClassified)\n' + - ' {\n' + - ' discard;\n' + - ' }\n' + - '#else\n' + - ' vec4 highlightColor = vec4(1.0);\n' + - ' if (!isClassified)\n' + - ' {\n' + - ' discard;\n' + - ' }\n' + - '#endif\n' + - ' gl_FragColor = color * highlightColor;\n' + - ' gl_FragDepthEXT = texture2D(u_depth, v_textureCoordinates).r;\n' + - '}\n'; + //cartesian has to be on the ellipsoid surface for `ellipsoid.geodeticSurfaceNormal` + var cartesian = Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0, ellipsoid, scratchGetHeightCartesian); - var opaqueFS = - 'uniform sampler2D u_texture;\n' + - 'varying vec2 v_textureCoordinates;\n' + - 'void main()\n' + - '{\n' + - ' vec4 color = texture2D(u_texture, v_textureCoordinates);\n' + - ' if (color.a == 0.0)\n' + - ' {\n' + - ' discard;\n' + - ' }\n' + - '#ifdef UNCLASSIFIED\n' + - ' gl_FragColor = color * czm_invertClassificationColor;\n' + - '#else\n' + - ' gl_FragColor = color;\n' + - '#endif\n' + - '}\n'; + var ray = scratchGetHeightRay; + var surfaceNormal = ellipsoid.geodeticSurfaceNormal(cartesian, ray.direction); - InvertClassification.prototype.update = function(context) { - var texture = this._texture; - var previousFramebufferChanged = !defined(texture) || this.previousFramebuffer !== this._previousFramebuffer; - this._previousFramebuffer = this.previousFramebuffer; + // Try to find the intersection point between the surface normal and z-axis. + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(cartesian, 11500.0, ray.origin); - var width = context.drawingBufferWidth; - var height = context.drawingBufferHeight; + // Theoretically, not with Earth datums, the intersection point can be outside the ellipsoid + if (!defined(rayOrigin)) { + // intersection point is outside the ellipsoid, try other value + // minimum height (-11500.0) for the terrain set, need to get this information from the terrain provider + var magnitude = Math.min(defaultValue(tile.data.minimumHeight, 0.0),-11500.0); - var textureChanged = !defined(texture) || texture.width !== width || texture.height !== height; - if (textureChanged || previousFramebufferChanged) { - this._texture = this._texture && this._texture.destroy(); - this._classifiedTexture = this._classifiedTexture && this._classifiedTexture.destroy(); - this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); + // multiply by the *positive* value of the magnitude + var vectorToMinimumPoint = Cartesian3.multiplyByScalar(surfaceNormal, Math.abs(magnitude) + 1, scratchGetHeightIntersection); + Cartesian3.subtract(cartesian, vectorToMinimumPoint, ray.origin); + } - this._texture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, - sampler : new Sampler({ - wrapS : TextureWrap.CLAMP_TO_EDGE, - wrapT : TextureWrap.CLAMP_TO_EDGE, - minificationFilter : TextureMinificationFilter.LINEAR, - magnificationFilter : TextureMagnificationFilter.LINEAR - }) - }); + var intersection = tile.data.pick(ray, undefined, undefined, false, scratchGetHeightIntersection); + if (!defined(intersection)) { + return undefined; + } - if (!defined(this._previousFramebuffer)) { - this._classifiedTexture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, - sampler : new Sampler({ - wrapS : TextureWrap.CLAMP_TO_EDGE, - wrapT : TextureWrap.CLAMP_TO_EDGE, - minificationFilter : TextureMinificationFilter.LINEAR, - magnificationFilter : TextureMagnificationFilter.LINEAR - }) - }); - this._depthStencilTexture = new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.DEPTH_STENCIL, - pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 - }); - } + return ellipsoid.cartesianToCartographic(intersection, scratchGetHeightCartographic).height; + }; + + /** + * @private + */ + Globe.prototype.update = function(frameState) { + if (!this.show) { + return; } - if (!defined(this._fbo) || textureChanged || previousFramebufferChanged) { - this._fbo = this._fbo && this._fbo.destroy(); - this._fboClassified = this._fboClassified && this._fboClassified.destroy(); + if (frameState.passes.render) { + this._surface.update(frameState); + } + }; - var depthStencilTexture; - var depthStencilRenderbuffer; - if (defined(this._previousFramebuffer)) { - depthStencilTexture = this._previousFramebuffer.depthStencilTexture; - depthStencilRenderbuffer = this._previousFramebuffer.depthStencilRenderbuffer; - } else { - depthStencilTexture = this._depthStencilTexture; - } + /** + * @private + */ + Globe.prototype.beginFrame = function(frameState) { + var surface = this._surface; + var tileProvider = surface.tileProvider; + var terrainProvider = this.terrainProvider; + var hasWaterMask = this.showWaterEffect && terrainProvider.ready && terrainProvider.hasWaterMask; - this._fbo = new Framebuffer({ - context : context, - colorTextures : [this._texture], - depthStencilTexture : depthStencilTexture, - depthStencilRenderbuffer : depthStencilRenderbuffer, - destroyAttachments : false - }); + if (hasWaterMask && this._oceanNormalMapResourceDirty) { + // url changed, load new normal map asynchronously + this._oceanNormalMapResourceDirty = false; + var oceanNormalMapResource = this._oceanNormalMapResource; + var oceanNormalMapUrl = oceanNormalMapResource.url; + if (defined(oceanNormalMapUrl)) { + var that = this; + when(oceanNormalMapResource.fetchImage(), function(image) { + if (oceanNormalMapUrl !== that._oceanNormalMapResource.url) { + // url changed while we were loading + return; + } - if (!defined(this._previousFramebuffer)) { - this._fboClassified = new Framebuffer({ - context : context, - colorTextures : [this._classifiedTexture], - depthStencilTexture : depthStencilTexture, - destroyAttachments : false + that._oceanNormalMap = that._oceanNormalMap && that._oceanNormalMap.destroy(); + that._oceanNormalMap = new Texture({ + context : frameState.context, + source : image + }); }); + } else { + this._oceanNormalMap = this._oceanNormalMap && this._oceanNormalMap.destroy(); } } - if (!defined(this._rsUnclassified)) { - this._rsUnclassified = RenderState.fromCache(rsUnclassified); - this._rsClassified = RenderState.fromCache(rsClassified); - this._rsDefault = RenderState.fromCache(rsDefault); - } + var pass = frameState.passes; + var mode = frameState.mode; - if (!defined(this._unclassifiedCommand) || previousFramebufferChanged) { - if (defined(this._unclassifiedCommand)) { - this._unclassifiedCommand.shaderProgram = this._unclassifiedCommand.shaderProgram && this._unclassifiedCommand.shaderProgram.destroy(); - this._classifiedCommand.shaderProgram = this._classifiedCommand.shaderProgram && this._classifiedCommand.shaderProgram.destroy(); + if (pass.render) { + // Don't show the ocean specular highlights when zoomed out in 2D and Columbus View. + if (mode === SceneMode.SCENE3D) { + this._zoomedOutOceanSpecularIntensity = 0.5; + } else { + this._zoomedOutOceanSpecularIntensity = 0.0; } - var fs = defined(this._previousFramebuffer) ? opaqueFS : translucentFS; - var unclassifiedFSSource = new ShaderSource({ - defines : ['UNCLASSIFIED'], - sources : [fs] - }); - var classifiedFSSource = new ShaderSource({ - sources : [fs] - }); - this._unclassifiedCommand = context.createViewportQuadCommand(unclassifiedFSSource, { - renderState : defined(this._previousFramebuffer) ? this._rsUnclassified : this._rsDefault, - uniformMap : this._uniformMap, - owner : this - }); - this._classifiedCommand = context.createViewportQuadCommand(classifiedFSSource, { - renderState : defined(this._previousFramebuffer) ? this._rsClassified : this._rsDefault, - uniformMap : this._uniformMap, - owner : this - }); + surface.maximumScreenSpaceError = this.maximumScreenSpaceError; + surface.tileCacheSize = this.tileCacheSize; - if (defined(this._translucentCommand)) { - this._translucentCommand.shaderProgram = this._translucentCommand.shaderProgram && this._translucentCommand.shaderProgram.destroy(); - } - if (!defined(this._previousFramebuffer)) { - this._translucentCommand = context.createViewportQuadCommand(PassThrough, { - renderState : this._rsUnclassified, - uniformMap : this._uniformMap, - owner : this - }); - } + tileProvider.terrainProvider = this.terrainProvider; + tileProvider.lightingFadeOutDistance = this.lightingFadeOutDistance; + tileProvider.lightingFadeInDistance = this.lightingFadeInDistance; + tileProvider.zoomedOutOceanSpecularIntensity = this._zoomedOutOceanSpecularIntensity; + tileProvider.hasWaterMask = hasWaterMask; + tileProvider.oceanNormalMap = this._oceanNormalMap; + tileProvider.enableLighting = this.enableLighting; + tileProvider.shadows = this.shadows; + + surface.beginFrame(frameState); } }; - InvertClassification.prototype.clear = function(context, passState) { - var framebuffer = passState.framebuffer; - - if (defined(this._previousFramebuffer)) { - passState.framebuffer = this._fbo; - this._clearColorCommand.execute(context, passState); - } else { - passState.framebuffer = this._fbo; - this._clearCommand.execute(context, passState); - passState.framebuffer = this._fboClassified; - this._clearCommand.execute(context, passState); + /** + * @private + */ + Globe.prototype.render = function(frameState) { + if (!this.show) { + return; } - passState.framebuffer = framebuffer; - }; + if (defined(this._material)) { + this._material.update(frameState.context); + } - InvertClassification.prototype.executeClassified = function(context, passState) { - if (!defined(this._previousFramebuffer)) { - var framebuffer = passState.framebuffer; + var surface = this._surface; + var pass = frameState.passes; - passState.framebuffer = this._fboClassified; - this._translucentCommand.execute(context, passState); + if (pass.render) { + surface.render(frameState); + } - passState.framebuffer = framebuffer; + if (pass.pick) { + surface.render(frameState); } - this._classifiedCommand.execute(context, passState); }; - InvertClassification.prototype.executeUnclassified = function(context, passState) { - this._unclassifiedCommand.execute(context, passState); + /** + * @private + */ + Globe.prototype.endFrame = function(frameState) { + if (!this.show) { + return; + } + + if (frameState.passes.render) { + this._surface.endFrame(frameState); + } }; - InvertClassification.prototype.isDestroyed = function() { + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see Globe#destroy + */ + Globe.prototype.isDestroyed = function() { return false; }; - InvertClassification.prototype.destroy = function() { - this._fbo = this._fbo && this._fbo.destroy(); - this._texture = this._texture && this._texture.destroy(); - this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); - - if (defined(this._unclassifiedCommand)) { - this._unclassifiedCommand.shaderProgram = this._unclassifiedCommand.shaderProgram && this._unclassifiedCommand.shaderProgram.destroy(); - this._classifiedCommand.shaderProgram = this._classifiedCommand.shaderProgram && this._classifiedCommand.shaderProgram.destroy(); - } - + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * globe = globe && globe.destroy(); + * + * @see Globe#isDestroyed + */ + Globe.prototype.destroy = function() { + this._surfaceShaderSet = this._surfaceShaderSet && this._surfaceShaderSet.destroy(); + this._surface = this._surface && this._surface.destroy(); + this._oceanNormalMap = this._oceanNormalMap && this._oceanNormalMap.destroy(); return destroyObject(this); }; - return InvertClassification; + return Globe; }); -define('Scene/JobScheduler',[ +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PostProcessFilters/PassThrough',[],function() { + 'use strict'; + return "uniform sampler2D u_texture;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +gl_FragColor = texture2D(u_texture, v_textureCoordinates);\n\ +}\n\ +"; +}); +define('Scene/GlobeDepth',[ + '../Core/BoundingRectangle', + '../Core/Color', '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/getTimestamp', - './JobType' + '../Core/destroyObject', + '../Core/PixelFormat', + '../Renderer/ClearCommand', + '../Renderer/Framebuffer', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/Texture', + '../Shaders/PostProcessFilters/PassThrough' ], function( + BoundingRectangle, + Color, defined, - defineProperties, - DeveloperError, - getTimestamp, - JobType) { + destroyObject, + PixelFormat, + ClearCommand, + Framebuffer, + PixelDatatype, + RenderState, + Texture, + PassThrough) { 'use strict'; - function JobTypeBudget(total) { - /** - * Total budget, in milliseconds, allowed for one frame - */ - this._total = total; + /** + * @private + */ + function GlobeDepth() { + this._colorTexture = undefined; + this._depthStencilTexture = undefined; + this._globeDepthTexture = undefined; - /** - * Time, in milliseconds, used so far during this frame - */ - this.usedThisFrame = 0.0; + this.framebuffer = undefined; + this._copyDepthFramebuffer = undefined; - /** - * Time, in milliseconds, that other job types stole this frame - */ - this.stolenFromMeThisFrame = 0.0; + this._clearColorCommand = undefined; + this._copyColorCommand = undefined; + this._copyDepthCommand = undefined; - /** - * Indicates if this job type was starved this frame, i.e., a job - * tried to run but didn't have budget - */ - this.starvedThisFrame = false; + this._viewport = new BoundingRectangle(); + this._rs = undefined; - /** - * Indicates if this job was starved last frame. This prevents it - * from being stolen from this frame. - */ - this.starvedLastFrame = false; + this._useScissorTest = false; + this._scissorRectangle = undefined; + + this._debugGlobeDepthViewportCommand = undefined; } - defineProperties(JobTypeBudget.prototype, { - total : { - get : function() { - return this._total; - } + function executeDebugGlobeDepth(globeDepth, context, passState) { + if (!defined(globeDepth._debugGlobeDepthViewportCommand)) { + var fs = + 'uniform sampler2D u_texture;\n' + + 'varying vec2 v_textureCoordinates;\n' + + 'void main()\n' + + '{\n' + + ' float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n' + + ' float n_range = czm_depthRange.near;\n' + + ' float f_range = czm_depthRange.far;\n' + + ' float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n' + + ' float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n' + + ' gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n' + + '}\n'; + + globeDepth._debugGlobeDepthViewportCommand = context.createViewportQuadCommand(fs, { + uniformMap : { + u_texture : function() { + return globeDepth._globeDepthTexture; + } + }, + owner : globeDepth + }); } - }); - /** - * Engine for time slicing jobs during a frame to amortize work over multiple frames. This supports: - * <ul> - * <li> - * Separate budgets for different job types, e.g., texture, shader program, and buffer creation. This - * allows all job types to make progress each frame. - * </li> - * <li> - * Stealing from other jobs type budgets if they were not exhausted in the previous frame. This allows - * using the entire budget for all job types each frame even if, for example, all the jobs are the same type. - * </li> - * <li> - * Guaranteed progress on all job types each frame, even if it means exceeding the total budget for the frame. - * This prevents, for example, several expensive texture uploads over many frames from prevent a shader compile. - * </li> - * </ul> - * - * @private - */ - function JobScheduler(budgets) { - if (defined(budgets) && (budgets.length !== JobType.NUMBER_OF_JOB_TYPES)) { - throw new DeveloperError('A budget must be specified for each job type; budgets.length should equal JobType.NUMBER_OF_JOB_TYPES.'); + globeDepth._debugGlobeDepthViewportCommand.execute(context, passState); + } + + function destroyTextures(globeDepth) { + globeDepth._colorTexture = globeDepth._colorTexture && !globeDepth._colorTexture.isDestroyed() && globeDepth._colorTexture.destroy(); + globeDepth._depthStencilTexture = globeDepth._depthStencilTexture && !globeDepth._depthStencilTexture.isDestroyed() && globeDepth._depthStencilTexture.destroy(); + globeDepth._globeDepthTexture = globeDepth._globeDepthTexture && !globeDepth._globeDepthTexture.isDestroyed() && globeDepth._globeDepthTexture.destroy(); + } + + function destroyFramebuffers(globeDepth) { + globeDepth.framebuffer = globeDepth.framebuffer && !globeDepth.framebuffer.isDestroyed() && globeDepth.framebuffer.destroy(); + globeDepth._copyDepthFramebuffer = globeDepth._copyDepthFramebuffer && !globeDepth._copyDepthFramebuffer.isDestroyed() && globeDepth._copyDepthFramebuffer.destroy(); + } + + function createTextures(globeDepth, context, width, height) { + globeDepth._colorTexture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE + }); + + globeDepth._depthStencilTexture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.DEPTH_STENCIL, + pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 + }); + + globeDepth._globeDepthTexture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE + }); + } + + function createFramebuffers(globeDepth, context) { + globeDepth.framebuffer = new Framebuffer({ + context : context, + colorTextures : [globeDepth._colorTexture], + depthStencilTexture : globeDepth._depthStencilTexture, + destroyAttachments : false + }); + + globeDepth._copyDepthFramebuffer = new Framebuffer({ + context : context, + colorTextures : [globeDepth._globeDepthTexture], + destroyAttachments : false + }); + } + + function updateFramebuffers(globeDepth, context, width, height) { + var colorTexture = globeDepth._colorTexture; + var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height; + if (!defined(globeDepth.framebuffer) || textureChanged) { + destroyTextures(globeDepth); + destroyFramebuffers(globeDepth); + createTextures(globeDepth, context, width, height); + createFramebuffers(globeDepth, context); } - - // Total for defaults is half of of one frame at 10 fps - var jobBudgets = new Array(JobType.NUMBER_OF_JOB_TYPES); - jobBudgets[JobType.TEXTURE] = new JobTypeBudget(defined(budgets) ? budgets[JobType.TEXTURE] : 10.0); - // On cache miss, this most likely only allows one shader compile per frame - jobBudgets[JobType.PROGRAM] = new JobTypeBudget(defined(budgets) ? budgets[JobType.PROGRAM] : 10.0); - jobBudgets[JobType.BUFFER] = new JobTypeBudget(defined(budgets) ? budgets[JobType.BUFFER] : 30.0); + } - var length = jobBudgets.length; - var i; + function updateCopyCommands(globeDepth, context, width, height, passState) { + globeDepth._viewport.width = width; + globeDepth._viewport.height = height; - var totalBudget = 0.0; - for (i = 0; i < length; ++i) { - totalBudget += jobBudgets[i].total; + var useScissorTest = !BoundingRectangle.equals(globeDepth._viewport, passState.viewport); + var updateScissor = useScissorTest !== globeDepth._useScissorTest; + globeDepth._useScissorTest = useScissorTest; + + if (!BoundingRectangle.equals(globeDepth._scissorRectangle, passState.viewport)) { + globeDepth._scissorRectangle = BoundingRectangle.clone(passState.viewport, globeDepth._scissorRectangle); + updateScissor = true; } - var executedThisFrame = new Array(length); - for (i = 0; i < length; ++i) { - executedThisFrame[i] = false; + if (!defined(globeDepth._rs) || !BoundingRectangle.equals(globeDepth._viewport, globeDepth._rs.viewport) || updateScissor) { + globeDepth._rs = RenderState.fromCache({ + viewport : globeDepth._viewport, + scissorTest : { + enabled : globeDepth._useScissorTest, + rectangle : globeDepth._scissorRectangle + } + }); } - this._totalBudget = totalBudget; - this._totalUsedThisFrame = 0.0; - this._budgets = jobBudgets; - this._executedThisFrame = executedThisFrame; - } + if (!defined(globeDepth._copyDepthCommand)) { + var fs = + 'uniform sampler2D u_texture;\n' + + 'varying vec2 v_textureCoordinates;\n' + + 'void main()\n' + + '{\n' + + ' gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n' + + '}\n'; + globeDepth._copyDepthCommand = context.createViewportQuadCommand(fs, { + uniformMap : { + u_texture : function() { + return globeDepth._depthStencilTexture; + } + }, + owner : globeDepth + }); + } - // For unit testing - JobScheduler.getTimestamp = getTimestamp; + globeDepth._copyDepthCommand.framebuffer = globeDepth._copyDepthFramebuffer; - defineProperties(JobScheduler.prototype, { - totalBudget : { - get : function() { - return this._totalBudget; - } + if (!defined(globeDepth._copyColorCommand)) { + globeDepth._copyColorCommand = context.createViewportQuadCommand(PassThrough, { + uniformMap : { + u_texture : function() { + return globeDepth._colorTexture; + } + }, + owner : globeDepth + }); } - }); - JobScheduler.prototype.disableThisFrame = function() { - // Prevent jobs from running this frame - this._totalUsedThisFrame = this._totalBudget; - }; + globeDepth._copyDepthCommand.renderState = globeDepth._rs; + globeDepth._copyColorCommand.renderState = globeDepth._rs; - JobScheduler.prototype.resetBudgets = function() { - var budgets = this._budgets; - var length = budgets.length; - for (var i = 0; i < length; ++i) { - var budget = budgets[i]; - budget.starvedLastFrame = budget.starvedThisFrame; - budget.starvedThisFrame = false; - budget.usedThisFrame = 0.0; - budget.stolenFromMeThisFrame = 0.0; + if (!defined(globeDepth._clearColorCommand)) { + globeDepth._clearColorCommand = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0), + stencil : 0.0, + owner : globeDepth + }); } - this._totalUsedThisFrame = 0.0; + + globeDepth._clearColorCommand.framebuffer = globeDepth.framebuffer; + } + + GlobeDepth.prototype.executeDebugGlobeDepth = function(context, passState) { + executeDebugGlobeDepth(this, context, passState); }; - JobScheduler.prototype.execute = function(job, jobType) { - var budgets = this._budgets; - var budget = budgets[jobType]; + GlobeDepth.prototype.update = function(context, passState) { + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; - // This ensures each job type makes progress each frame by executing at least once - var progressThisFrame = this._executedThisFrame[jobType]; + updateFramebuffers(this, context, width, height); + updateCopyCommands(this, context, width, height, passState); + context.uniformState.globeDepthTexture = undefined; + }; - if ((this._totalUsedThisFrame >= this._totalBudget) && progressThisFrame) { - // No budget left this frame for jobs of any type - budget.starvedThisFrame = true; - return false; + GlobeDepth.prototype.executeCopyDepth = function(context, passState) { + if (defined(this._copyDepthCommand)) { + this._copyDepthCommand.execute(context, passState); + context.uniformState.globeDepthTexture = this._globeDepthTexture; } + }; - var stolenBudget; + GlobeDepth.prototype.executeCopyColor = function(context, passState) { + if (defined(this._copyColorCommand)) { + this._copyColorCommand.execute(context, passState); + } + }; - if ((budget.usedThisFrame + budget.stolenFromMeThisFrame >= budget.total)) { - // No budget remaining for jobs of this type. Try to steal from other job types. - var length = budgets.length; - var i; - for (i = 0; i < length; ++i) { - stolenBudget = budgets[i]; + GlobeDepth.prototype.clear = function(context, passState, clearColor) { + var clear = this._clearColorCommand; + if (defined(clear)) { + Color.clone(clearColor, clear.color); + clear.execute(context, passState); + } + }; - // Steal from this budget if it has time left and it wasn't starved last fame - if ((stolenBudget.usedThisFrame + stolenBudget.stolenFromMeThisFrame < stolenBudget.total) && - (!stolenBudget.starvedLastFrame)) { - break; - } - } + GlobeDepth.prototype.isDestroyed = function() { + return false; + }; - if (i === length && progressThisFrame) { - // No other job types can give up their budget this frame, and - // this job type already progressed this frame - return false; - } + GlobeDepth.prototype.destroy = function() { + destroyTextures(this); + destroyFramebuffers(this); - if (progressThisFrame) { - // It is considered "starved" even if it executes using stolen time so that - // next frame, no other job types can steal time from it. - budget.starvedThisFrame = true; - } + if (defined(this._copyColorCommand)) { + this._copyColorCommand.shaderProgram = this._copyColorCommand.shaderProgram.destroy(); } - var startTime = JobScheduler.getTimestamp(); - job.execute(); - var duration = JobScheduler.getTimestamp() - startTime; - - // Track both time remaining for this job type and all jobs - // so budget stealing does send us way over the total budget. - this._totalUsedThisFrame += duration; + if (defined(this._copyDepthCommand)) { + this._copyDepthCommand.shaderProgram = this._copyDepthCommand.shaderProgram.destroy(); + } - if (stolenBudget) { - stolenBudget.stolenFromMeThisFrame += duration; - } else { - budget.usedThisFrame += duration; + var command = this._debugGlobeDepthViewportCommand; + if (defined(command)) { + command.shaderProgram = command.shaderProgram.destroy(); } - this._executedThisFrame[jobType] = true; - return true; + return destroyObject(this); }; - return JobScheduler; + return GlobeDepth; }); -define('Scene/MapboxImageryProvider',[ +define('Scene/GoogleEarthEnterpriseImageryProvider',[ '../Core/Credit', + '../Core/decodeGoogleEarthEnterpriseData', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', + '../Core/deprecationWarning', '../Core/DeveloperError', - '../Core/MapboxApi', - './UrlTemplateImageryProvider' + '../Core/Event', + '../Core/GeographicTilingScheme', + '../Core/GoogleEarthEnterpriseMetadata', + '../Core/loadImageFromTypedArray', + '../Core/Math', + '../Core/Rectangle', + '../Core/Request', + '../Core/Resource', + '../Core/RuntimeError', + '../Core/TileProviderError', + '../ThirdParty/protobuf-minimal', + '../ThirdParty/when' ], function( Credit, + decodeGoogleEarthEnterpriseData, defaultValue, defined, defineProperties, + deprecationWarning, DeveloperError, - MapboxApi, - UrlTemplateImageryProvider) { + Event, + GeographicTilingScheme, + GoogleEarthEnterpriseMetadata, + loadImageFromTypedArray, + CesiumMath, + Rectangle, + Request, + Resource, + RuntimeError, + TileProviderError, + protobuf, + when) { 'use strict'; - var trailingSlashRegex = /\/$/; - var defaultCredit1 = new Credit({ - text:'© Mapbox © OpenStreetMap', - link: 'https://www.mapbox.com/about/maps/' - }); - var defaultCredit2 = [new Credit({ - text: 'Improve this map', - link: 'https://www.mapbox.com/map-feedback/' - })]; + function GoogleEarthEnterpriseDiscardPolicy() { + this._image = new Image(); + } /** - * Provides tiled imagery hosted by Mapbox. + * Determines if the discard policy is ready to process images. + * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + */ + GoogleEarthEnterpriseDiscardPolicy.prototype.isReady = function() { + return true; + }; + + /** + * Given a tile image, decide whether to discard that image. * - * @alias MapboxImageryProvider + * @param {Image} image An image to test. + * @returns {Boolean} True if the image should be discarded; otherwise, false. + */ + GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function(image) { + return (image === this._image); + }; + + /** + * Provides tiled imagery using the Google Earth Enterprise REST API. + * + * Notes: This provider is for use with the 3D Earth API of Google Earth Enterprise, + * {@link GoogleEarthEnterpriseMapsProvider} should be used with 2D Maps API. + * + * @alias GoogleEarthEnterpriseImageryProvider * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.url='https://api.mapbox.com/v4/'] The Mapbox server url. - * @param {String} options.mapId The Mapbox Map ID. - * @param {String} [options.accessToken] The public access token for the imagery. - * @param {String} [options.format='png'] The format of the image request. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL. + * @param {Object} options Object with the following properties: + * @param {Resource|String} options.url The url of the Google Earth Enterprise server hosting the imagery. + * @param {GoogleEarthEnterpriseMetadata} options.metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider. * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying - * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely - * to result in rendering problems. - * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. + * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile + * is invalid and should be discarded. If this value is not specified, a default + * is to discard tiles that fail to download. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * + * @see GoogleEarthEnterpriseTerrainProvider + * @see ArcGisMapServerImageryProvider + * @see GoogleEarthEnterpriseMapsProvider + * @see createOpenStreetMapImageryProvider + * @see SingleTileImageryProvider + * @see createTileMapServiceImageryProvider + * @see WebMapServiceImageryProvider + * @see WebMapTileServiceImageryProvider + * @see UrlTemplateImageryProvider + * * * @example - * // Mapbox tile provider - * var mapbox = new Cesium.MapboxImageryProvider({ - * mapId: 'mapbox.streets', - * accessToken: 'thisIsMyAccessToken' + * var geeMetadata = new GoogleEarthEnterpriseMetadata('http://www.earthenterprise.org/3d'); + * var gee = new Cesium.GoogleEarthEnterpriseImageryProvider({ + * metadata : geeMetadata * }); * - * @see {@link https://www.mapbox.com/developers/api/maps/#tiles} - * @see {@link https://www.mapbox.com/developers/api/#access-tokens} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ - function MapboxImageryProvider(options) { + function GoogleEarthEnterpriseImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var mapId = options.mapId; - if (!defined(mapId)) { - throw new DeveloperError('options.mapId is required.'); + + if (!(defined(options.url) || defined(options.metadata))) { + throw new DeveloperError('options.url or options.metadata is required.'); } - var url = defaultValue(options.url, 'https://api.mapbox.com/v4/'); - this._url = url; - this._mapId = mapId; - this._accessToken = MapboxApi.getAccessToken(options.accessToken); - this._accessTokenErrorCredit = MapboxApi.getErrorCredit(options.accessToken); - var format = defaultValue(options.format, 'png'); - if (!/\./.test(format)) { - format = '.' + format; + if (defined(options.proxy)) { + deprecationWarning('GoogleEarthEnterpriseImageryProvider.proxy', 'The options.proxy parameter has been deprecated. Specify options.url as a Resource instance and set the proxy property there.'); } - this._format = format; - var templateUrl = url; - if (!trailingSlashRegex.test(url)) { - templateUrl += '/'; + var metadata; + if (defined(options.metadata)) { + metadata = options.metadata; + } else { + var resource = Resource.createIfNeeded(options.url, { + proxy: options.proxy + }); + metadata = new GoogleEarthEnterpriseMetadata(resource); } - templateUrl += mapId + '/{z}/{x}/{y}' + this._format; - if (defined(this._accessToken)) { - templateUrl += '?access_token=' + this._accessToken; + this._metadata = metadata; + this._tileDiscardPolicy = options.tileDiscardPolicy; + + this._tilingScheme = new GeographicTilingScheme({ + numberOfLevelZeroTilesX : 2, + numberOfLevelZeroTilesY : 2, + rectangle : new Rectangle(-CesiumMath.PI, -CesiumMath.PI, CesiumMath.PI, CesiumMath.PI), + ellipsoid : options.ellipsoid + }); + + var credit = options.credit; + if (typeof credit === 'string') { + credit = new Credit({text: credit}); } + this._credit = credit; - if (defined(options.credit)) { - var credit = options.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); - } - defaultCredit1 = credit; - defaultCredit2.length = 0; + this._tileWidth = 256; + this._tileHeight = 256; + this._maximumLevel = 23; + + // Install the default tile discard policy if none has been supplied. + if (!defined(this._tileDiscardPolicy)) { + this._tileDiscardPolicy = new GoogleEarthEnterpriseDiscardPolicy(); } - this._imageryProvider = new UrlTemplateImageryProvider({ - url: templateUrl, - proxy: options.proxy, - credit: defaultCredit1, - ellipsoid: options.ellipsoid, - minimumLevel: options.minimumLevel, - maximumLevel: options.maximumLevel, - rectangle: options.rectangle - }); + this._errorEvent = new Event(); + + this._ready = false; + var that = this; + var metadataError; + this._readyPromise = metadata.readyPromise + .then(function(result) { + if (!metadata.imageryPresent) { + var e = new RuntimeError('The server ' + metadata.url + ' doesn\'t have imagery'); + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); + return when.reject(e); + } + + TileProviderError.handleSuccess(metadataError); + that._ready = result; + return result; + }) + .otherwise(function(e) { + metadataError = TileProviderError.handleError(metadataError, that, that._errorEvent, e.message, undefined, undefined, undefined, e); + return when.reject(e); + }); } - defineProperties(MapboxImageryProvider.prototype, { + defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { /** - * Gets the URL of the Mapbox server. - * @memberof MapboxImageryProvider.prototype + * Gets the name of the Google Earth Enterprise server url hosting the imagery. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {String} * @readonly */ url : { get : function() { - return this._url; - } - }, - - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof MapboxImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._imageryProvider.ready; - } - }, - - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof MapboxImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._imageryProvider.readyPromise; + return this._metadata.url; } }, /** - * Gets the rectangle, in radians, of the imagery provided by the instance. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype - * @type {Rectangle} + * Gets the proxy used by this provider. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Proxy} * @readonly */ - rectangle: { + proxy : { get : function() { - return this._imageryProvider.rectangle; + return this._metadata.proxy; } }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype + * Gets the width of each tile, in pixels. This function should + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ tileWidth : { get : function() { - return this._imageryProvider.tileWidth; + if (!this._ready) { + throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); + } + + return this._tileWidth; } }, /** * Gets the height of each tile, in pixels. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ tileHeight : { get : function() { - return this._imageryProvider.tileHeight; + if (!this._ready) { + throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + } + + return this._tileHeight; } }, /** * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ maximumLevel : { get : function() { - return this._imageryProvider.maximumLevel; + if (!this._ready) { + throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); + } + + return this._maximumLevel; } }, /** * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. Generally, - * a minimum level should only be used when the rectangle of the imagery is small - * enough that the number of tiles at the minimum level is small. An imagery - * provider with more than a few tiles at the minimum level will lead to - * rendering problems. - * @memberof MapboxImageryProvider.prototype + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ minimumLevel : { get : function() { - return this._imageryProvider.minimumLevel; + if (!this._ready) { + throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); + } + + return 0; } }, /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme : { get : function() { - return this._imageryProvider.tilingScheme; + if (!this._ready) { + throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme; + } + }, + + /** + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle : { + get : function() { + if (!this._ready) { + throw new DeveloperError('rectangle must not be called before the imagery provider is ready.'); + } + + return this._tilingScheme.rectangle; } }, @@ -200714,54 +212221,69 @@ define('Scene/MapboxImageryProvider',[ * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function * returns undefined, no tiles are filtered. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy : { get : function() { - return this._imageryProvider.tileDiscardPolicy; + if (!this._ready) { + throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); + } + + return this._tileDiscardPolicy; } }, /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error.. By subscribing + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners * are passed an instance of {@link TileProviderError}. - * @memberof MapboxImageryProvider.prototype + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Event} * @readonly */ errorEvent : { get : function() { - return this._imageryProvider.errorEvent; + return this._errorEvent; } }, /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. - * @memberof MapboxImageryProvider.prototype - * @type {Credit} + * Gets a value indicating whether or not the provider is ready for use. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Boolean} * @readonly */ - credit : { + ready : { get : function() { - return this._imageryProvider.credit; + return this._ready; } }, /** - * Gets the proxy used by this provider. - * @memberof MapboxImageryProvider.prototype - * @type {Proxy} + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Promise.<Boolean>} * @readonly */ - proxy : { + readyPromise : { get : function() { - return this._imageryProvider.proxy; + return this._readyPromise; + } + }, + + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return this._credit; } }, @@ -200769,15 +212291,15 @@ define('Scene/MapboxImageryProvider',[ * Gets a value indicating whether or not the images provided by this imagery provider * include an alpha channel. If this property is false, an alpha channel, if present, will * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof MapboxImageryProvider.prototype + * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage + * and texture upload time. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Boolean} * @readonly */ hasAlphaChannel : { get : function() { - return this._imageryProvider.hasAlphaChannel; + return false; } } }); @@ -200792,17 +212314,26 @@ define('Scene/MapboxImageryProvider',[ * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - MapboxImageryProvider.prototype.getTileCredits = function(x, y, level) { - var credits = defaultCredit2.slice(); - if (defined(this._accessTokenErrorCredit)) { - credits.push(this._accessTokenErrorCredit); + GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function(x, y, level) { + if (!this._ready) { + throw new DeveloperError('getTileCredits must not be called before the imagery provider is ready.'); } - return credits; + + var metadata = this._metadata; + var info = metadata.getTileInformation(x, y, level); + if (defined(info)) { + var credit = metadata.providers[info.imageryProvider]; + if (defined(credit)) { + return [credit]; + } + } + + return undefined; }; /** * Requests the image for a given tile. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -200815,15 +212346,66 @@ define('Scene/MapboxImageryProvider',[ * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */ - MapboxImageryProvider.prototype.requestImage = function(x, y, level, request) { - return this._imageryProvider.requestImage(x, y, level, request); + GoogleEarthEnterpriseImageryProvider.prototype.requestImage = function(x, y, level, request) { + if (!this._ready) { + throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); + } + + var invalidImage = this._tileDiscardPolicy._image; // Empty image or undefined depending on discard policy + var metadata = this._metadata; + var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); + var info = metadata.getTileInformation(x, y, level); + if (!defined(info)) { + if (metadata.isValid(quadKey)) { + var metadataRequest = new Request({ + throttle : request.throttle, + throttleByServer : request.throttleByServer, + type : request.type, + priorityFunction : request.priorityFunction + }); + metadata.populateSubtree(x, y, level, metadataRequest); + return undefined; // No metadata so return undefined so we can be loaded later + } + return invalidImage; // Image doesn't exist + } + + if (!info.hasImagery()) { + // Already have info and there isn't any imagery here + return invalidImage; + } + var promise = buildImageResource(this, info, x, y, level, request).fetchArrayBuffer(); + if (!defined(promise)) { + return undefined; // Throttled + } + + return promise + .then(function(image) { + decodeGoogleEarthEnterpriseData(metadata.key, image); + var a = new Uint8Array(image); + var type; + + var protoImagery = metadata.protoImagery; + if (!defined(protoImagery) || !protoImagery) { + type = getImageType(a); + } + + if (!defined(type) && (!defined(protoImagery) || protoImagery)) { + var message = decodeEarthImageryPacket(a); + type = message.imageType; + a = message.imageData; + } + + if (!defined(type) || !defined(a)) { + return invalidImage; + } + + return loadImageFromTypedArray(a, type); + }); }; /** - * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link MapboxImageryProvider#ready} returns true. - * This function is optional, so it may not exist on all ImageryProviders. - * + * Picking features is not currently supported by this imagery provider, so this function simply returns + * undefined. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -200834,1979 +212416,1175 @@ define('Scene/MapboxImageryProvider',[ * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. - * - * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. */ - MapboxImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return this._imageryProvider.pickFeatures(x, y, level, longitude, latitude); + GoogleEarthEnterpriseImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return undefined; }; - return MapboxImageryProvider; + // + // Functions to handle imagery packets + // + function buildImageResource(imageryProvider, info, x, y, level, request) { + var quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); + var version = info.imageryVersion; + version = (defined(version) && version > 0) ? version : 1; + + return imageryProvider._metadata.resource.getDerivedResource({ + url: 'flatfile?f1-0' + quadKey + '-i.' + version.toString(), + request: request + }); + } + + // Detects if a Uint8Array is a JPEG or PNG + function getImageType(image) { + var jpeg = 'JFIF'; + if (image[6] === jpeg.charCodeAt(0) && image[7] === jpeg.charCodeAt(1) && + image[8] === jpeg.charCodeAt(2) && image[9] === jpeg.charCodeAt(3)) { + return 'image/jpeg'; + } + + var png = 'PNG'; + if (image[1] === png.charCodeAt(0) && image[2] === png.charCodeAt(1) && image[3] === png.charCodeAt(2)) { + return 'image/png'; + } + + return undefined; + } + + // Decodes an Imagery protobuf into the message + // Partially generated with the help of protobuf.js static generator + function decodeEarthImageryPacket(data) { + var reader = protobuf.Reader.create(data); + var end = reader.len; + var message = {}; + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.imageType = reader.uint32(); + break; + case 2: + message.imageData = reader.bytes(); + break; + case 3: + message.alphaType = reader.uint32(); + break; + case 4: + message.imageAlpha = reader.bytes(); + break; + case 5: + var copyrightIds = message.copyrightIds; + if (!defined(copyrightIds)) { + copyrightIds = message.copyrightIds = []; + } + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + copyrightIds.push(reader.uint32()); + } + } else { + copyrightIds.push(reader.uint32()); + } + break; + default: + reader.skipType(tag & 7); + break; + } + } + + var imageType = message.imageType; + if (defined(imageType)) { + switch (imageType) { + case 0: + message.imageType = 'image/jpeg'; + break; + case 4: + message.imageType = 'image/png'; + break; + default: + throw new RuntimeError('GoogleEarthEnterpriseImageryProvider: Unsupported image type.'); + } + } + + var alphaType = message.alphaType; + if (defined(alphaType) && alphaType !== 0) { + console.log('GoogleEarthEnterpriseImageryProvider: External alpha not supported.'); + delete message.alphaType; + delete message.imageAlpha; + } + + return message; + } + + return GoogleEarthEnterpriseImageryProvider; }); -define('Scene/Moon',[ - '../Core/buildModuleUrl', - '../Core/Cartesian3', +define('Scene/GridImageryProvider',[ + '../Core/Color', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/destroyObject', - '../Core/Ellipsoid', - '../Core/IauOrientationAxes', - '../Core/Matrix3', - '../Core/Matrix4', - '../Core/Simon1994PlanetaryPositions', - '../Core/Transforms', - './EllipsoidPrimitive', - './Material' + '../Core/Event', + '../Core/GeographicTilingScheme', + '../ThirdParty/when' ], function( - buildModuleUrl, - Cartesian3, + Color, defaultValue, defined, defineProperties, - destroyObject, - Ellipsoid, - IauOrientationAxes, - Matrix3, - Matrix4, - Simon1994PlanetaryPositions, - Transforms, - EllipsoidPrimitive, - Material) { + Event, + GeographicTilingScheme, + when) { 'use strict'; + var defaultColor = new Color(1.0, 1.0, 1.0, 0.4); + var defaultGlowColor = new Color(0.0, 1.0, 0.0, 0.05); + var defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2); + /** - * Draws the Moon in 3D. - * @alias Moon + * An {@link ImageryProvider} that draws a wireframe grid on every tile with controllable background and glow. + * May be useful for custom rendering effects or debugging terrain. + * + * @alias GridImageryProvider * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Determines whether the moon will be rendered. - * @param {String} [options.textureUrl=buildModuleUrl('Assets/Textures/moonSmall.jpg')] The moon texture. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.MOON] The moon ellipsoid. - * @param {Boolean} [options.onlySunLighting=true] Use the sun as the only light source. - * - * - * @example - * scene.moon = new Cesium.Moon(); - * - * @see Scene#moon + * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * @param {Number} [options.cells=8] The number of grids cells. + * @param {Color} [options.color=Color(1.0, 1.0, 1.0, 0.4)] The color to draw grid lines. + * @param {Color} [options.glowColor=Color(0.0, 1.0, 0.0, 0.05)] The color to draw glow for grid lines. + * @param {Number} [options.glowWidth=6] The width of lines used for rendering the line glow effect. + * @param {Color} [options.backgroundColor=Color(0.0, 0.5, 0.0, 0.2)] Background fill color. + * @param {Number} [options.tileWidth=256] The width of the tile for level-of-detail selection purposes. + * @param {Number} [options.tileHeight=256] The height of the tile for level-of-detail selection purposes. + * @param {Number} [options.canvasSize=256] The size of the canvas used for rendering. */ - function Moon(options) { + function GridImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var url = options.textureUrl; - if (!defined(url)) { - url = buildModuleUrl('Assets/Textures/moonSmall.jpg'); - } + this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); + this._cells = defaultValue(options.cells, 8); + this._color = defaultValue(options.color, defaultColor); + this._glowColor = defaultValue(options.glowColor, defaultGlowColor); + this._glowWidth = defaultValue(options.glowWidth, 6); + this._backgroundColor = defaultValue(options.backgroundColor, defaultBackgroundColor); + this._errorEvent = new Event(); + + this._tileWidth = defaultValue(options.tileWidth, 256); + this._tileHeight = defaultValue(options.tileHeight, 256); + + // A little larger than tile size so lines are sharper + // Note: can't be too much difference otherwise texture blowout + this._canvasSize = defaultValue(options.canvasSize, 256); + + // We only need a single canvas since all tiles will be the same + this._canvas = this._createGridCanvas(); + + this._readyPromise = when.resolve(true); + } + defineProperties(GridImageryProvider.prototype, { /** - * Determines if the moon will be shown. - * - * @type {Boolean} - * @default true + * Gets the proxy used by this provider. + * @memberof GridImageryProvider.prototype + * @type {Proxy} + * @readonly */ - this.show = defaultValue(options.show, true); + proxy : { + get : function() { + return undefined; + } + }, /** - * The moon texture. - * @type {String} - * @default buildModuleUrl('Assets/Textures/moonSmall.jpg') + * Gets the width of each tile, in pixels. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {Number} + * @readonly */ - this.textureUrl = url; - - this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.MOON); + tileWidth : { + get : function() { + return this._tileWidth; + } + }, /** - * Use the sun as the only light source. - * @type {Boolean} - * @default true + * Gets the height of each tile, in pixels. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {Number} + * @readonly */ - this.onlySunLighting = defaultValue(options.onlySunLighting, true); - - this._ellipsoidPrimitive = new EllipsoidPrimitive({ - radii : this.ellipsoid.radii, - material : Material.fromType(Material.ImageType), - depthTestEnabled : false, - _owner : this - }); - this._ellipsoidPrimitive.material.translucent = false; + tileHeight : { + get : function() { + return this._tileHeight; + } + }, - this._axes = new IauOrientationAxes(); - } + /** + * Gets the maximum level-of-detail that can be requested. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {Number} + * @readonly + */ + maximumLevel : { + get : function() { + return undefined; + } + }, - defineProperties(Moon.prototype, { /** - * Get the ellipsoid that defines the shape of the moon. - * - * @memberof Moon.prototype - * - * @type {Ellipsoid} + * Gets the minimum level-of-detail that can be requested. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {Number} * @readonly - * - * @default {@link Ellipsoid.MOON} */ - ellipsoid : { + minimumLevel : { get : function() { - return this._ellipsoid; + return undefined; } - } - }); + }, - var icrfToFixed = new Matrix3(); - var rotationScratch = new Matrix3(); - var translationScratch = new Cartesian3(); - var scratchCommandList = []; + /** + * Gets the tiling scheme used by this provider. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {TilingScheme} + * @readonly + */ + tilingScheme : { + get : function() { + return this._tilingScheme; + } + }, - /** - * @private - */ - Moon.prototype.update = function(frameState) { - if (!this.show) { - return; - } + /** + * Gets the rectangle, in radians, of the imagery provided by this instance. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {Rectangle} + * @readonly + */ + rectangle : { + get : function() { + return this._tilingScheme.rectangle; + } + }, - var ellipsoidPrimitive = this._ellipsoidPrimitive; - ellipsoidPrimitive.material.uniforms.image = this.textureUrl; - ellipsoidPrimitive.onlySunLighting = this.onlySunLighting; + /** + * Gets the tile discard policy. If not undefined, the discard policy is responsible + * for filtering out "missing" tiles via its shouldDiscardImage function. If this function + * returns undefined, no tiles are filtered. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {TileDiscardPolicy} + * @readonly + */ + tileDiscardPolicy : { + get : function() { + return undefined; + } + }, - var date = frameState.time; - if (!defined(Transforms.computeIcrfToFixedMatrix(date, icrfToFixed))) { - Transforms.computeTemeToPseudoFixedMatrix(date, icrfToFixed); - } + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof GridImageryProvider.prototype + * @type {Event} + * @readonly + */ + errorEvent : { + get : function() { + return this._errorEvent; + } + }, - var rotation = this._axes.evaluate(date, rotationScratch); - Matrix3.transpose(rotation, rotation); - Matrix3.multiply(icrfToFixed, rotation, rotation); + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof GridImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return true; + } + }, - var translation = Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(date, translationScratch); - Matrix3.multiplyByVector(icrfToFixed, translation, translation); + /** + * Gets a promise that resolves to true when the provider is ready for use. + * @memberof GridImageryProvider.prototype + * @type {Promise.<Boolean>} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise; + } + }, - Matrix4.fromRotationTranslation(rotation, translation, ellipsoidPrimitive.modelMatrix); + /** + * Gets the credit to display when this imagery provider is active. Typically this is used to credit + * the source of the imagery. This function should not be called before {@link GridImageryProvider#ready} returns true. + * @memberof GridImageryProvider.prototype + * @type {Credit} + * @readonly + */ + credit : { + get : function() { + return undefined; + } + }, - var savedCommandList = frameState.commandList; - frameState.commandList = scratchCommandList; - scratchCommandList.length = 0; - ellipsoidPrimitive.update(frameState); - frameState.commandList = savedCommandList; - return (scratchCommandList.length === 1) ? scratchCommandList[0] : undefined; - }; + /** + * Gets a value indicating whether or not the images provided by this imagery provider + * include an alpha channel. If this property is false, an alpha channel, if present, will + * be ignored. If this property is true, any images without an alpha channel will be treated + * as if their alpha is 1.0 everywhere. When this property is false, memory usage + * and texture upload time are reduced. + * @memberof GridImageryProvider.prototype + * @type {Boolean} + * @readonly + */ + hasAlphaChannel : { + get : function() { + return true; + } + } + }); /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see Moon#destroy + * Draws a grid of lines into a canvas. */ - Moon.prototype.isDestroyed = function() { - return false; + GridImageryProvider.prototype._drawGrid = function(context) { + var minPixel = 0; + var maxPixel = this._canvasSize; + for (var x = 0; x <= this._cells; ++x) { + var nx = x / this._cells; + var val = 1 + nx * (maxPixel - 1); + + context.moveTo(val, minPixel); + context.lineTo(val, maxPixel); + context.moveTo(minPixel, val); + context.lineTo(maxPixel, val); + } + context.stroke(); }; /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * moon = moon && moon.destroy(); - * - * @see Moon#isDestroyed + * Render a grid into a canvas with background and glow */ - Moon.prototype.destroy = function() { - this._ellipsoidPrimitive = this._ellipsoidPrimitive && this._ellipsoidPrimitive.destroy(); - return destroyObject(this); - }; + GridImageryProvider.prototype._createGridCanvas = function() { + var canvas = document.createElement('canvas'); + canvas.width = this._canvasSize; + canvas.height = this._canvasSize; + var minPixel = 0; + var maxPixel = this._canvasSize; - return Moon; -}); + var context = canvas.getContext('2d'); -define('Scene/NeverTileDiscardPolicy',[], function() { - 'use strict'; + // Fill the background + var cssBackgroundColor = this._backgroundColor.toCssColorString(); + context.fillStyle = cssBackgroundColor; + context.fillRect(minPixel, minPixel, maxPixel, maxPixel); + + // Glow for grid lines + var cssGlowColor = this._glowColor.toCssColorString(); + context.strokeStyle = cssGlowColor; + // Wide + context.lineWidth = this._glowWidth; + context.strokeRect(minPixel, minPixel, maxPixel, maxPixel); + this._drawGrid(context); + // Narrow + context.lineWidth = this._glowWidth * 0.5; + context.strokeRect(minPixel, minPixel, maxPixel, maxPixel); + this._drawGrid(context); + + // Grid lines + var cssColor = this._color.toCssColorString(); + // Border + context.strokeStyle = cssColor; + context.lineWidth = 2; + context.strokeRect(minPixel, minPixel, maxPixel, maxPixel); + // Inner + context.lineWidth = 1; + this._drawGrid(context); + + return canvas; + }; /** - * A {@link TileDiscardPolicy} specifying that tile images should never be discard. + * Gets the credits to be displayed when a given tile is displayed. * - * @alias NeverTileDiscardPolicy - * @constructor + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level; + * @returns {Credit[]} The credits to be displayed when the tile is displayed. * - * @see DiscardMissingTileImagePolicy + * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - function NeverTileDiscardPolicy(options) { - } + GridImageryProvider.prototype.getTileCredits = function(x, y, level) { + return undefined; + }; /** - * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * Requests the image for a given tile. This function should + * not be called before {@link GridImageryProvider#ready} returns true. + * + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Request} [request] The request object. Intended for internal use only. + * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or + * undefined if there are too many active requests to the server, and the request + * should be retried later. The resolved image may be either an + * Image or a Canvas DOM object. */ - NeverTileDiscardPolicy.prototype.isReady = function() { - return true; + GridImageryProvider.prototype.requestImage = function(x, y, level, request) { + return this._canvas; }; /** - * Given a tile image, decide whether to discard that image. + * Picking features is not currently supported by this imagery provider, so this function simply returns + * undefined. * - * @param {Image} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @param {Number} x The tile X coordinate. + * @param {Number} y The tile Y coordinate. + * @param {Number} level The tile level. + * @param {Number} longitude The longitude at which to pick features. + * @param {Number} latitude The latitude at which to pick features. + * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} + * instances. The array may be empty if no features are found at the given location. + * It may also be undefined if picking is not supported. */ - NeverTileDiscardPolicy.prototype.shouldDiscardImage = function(image) { - return false; + GridImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + return undefined; }; - return NeverTileDiscardPolicy; + return GridImageryProvider; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/AdjustTranslucentFS',[],function() { - 'use strict'; - return "#ifdef MRT\n\ -#extension GL_EXT_draw_buffers : enable\n\ -#endif\n\ -uniform vec4 u_bgColor;\n\ -uniform sampler2D u_depthTexture;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -if (texture2D(u_depthTexture, v_textureCoordinates).r < 1.0)\n\ -{\n\ -#ifdef MRT\n\ -gl_FragData[0] = u_bgColor;\n\ -gl_FragData[1] = vec4(u_bgColor.a);\n\ -#else\n\ -gl_FragColor = u_bgColor;\n\ -#endif\n\ -return;\n\ -}\n\ -discard;\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/CompositeOITFS',[],function() { - 'use strict'; - return "uniform sampler2D u_opaque;\n\ -uniform sampler2D u_accumulation;\n\ -uniform sampler2D u_revealage;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -vec4 opaque = texture2D(u_opaque, v_textureCoordinates);\n\ -vec4 accum = texture2D(u_accumulation, v_textureCoordinates);\n\ -float r = texture2D(u_revealage, v_textureCoordinates).r;\n\ -#ifdef MRT\n\ -vec4 transparent = vec4(accum.rgb / clamp(r, 1e-4, 5e4), accum.a);\n\ -#else\n\ -vec4 transparent = vec4(accum.rgb / clamp(accum.a, 1e-4, 5e4), r);\n\ -#endif\n\ -gl_FragColor = (1.0 - transparent.a) * transparent + transparent.a * opaque;\n\ -if (opaque != czm_backgroundColor)\n\ -{\n\ -gl_FragColor.a = 1.0;\n\ -}\n\ -}\n\ -"; -}); -define('Scene/OIT',[ - '../Core/BoundingRectangle', +define('Scene/InvertClassification',[ '../Core/Color', '../Core/defined', + '../Core/defineProperties', '../Core/destroyObject', '../Core/PixelFormat', - '../Core/WebGLConstants', '../Renderer/ClearCommand', - '../Renderer/DrawCommand', '../Renderer/Framebuffer', '../Renderer/PixelDatatype', '../Renderer/RenderState', + '../Renderer/Sampler', '../Renderer/ShaderSource', '../Renderer/Texture', - '../Shaders/AdjustTranslucentFS', - '../Shaders/CompositeOITFS', - './BlendEquation', - './BlendFunction' + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', + '../Shaders/PostProcessFilters/PassThrough', + './BlendingState', + './StencilFunction', + './StencilOperation' ], function( - BoundingRectangle, Color, defined, + defineProperties, destroyObject, PixelFormat, - WebGLConstants, ClearCommand, - DrawCommand, Framebuffer, PixelDatatype, RenderState, + Sampler, ShaderSource, Texture, - AdjustTranslucentFS, - CompositeOITFS, - BlendEquation, - BlendFunction) { + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap, + PassThrough, + BlendingState, + StencilFunction, + StencilOperation) { 'use strict'; /** * @private */ - function OIT(context) { - // We support multipass for the Chrome D3D9 backend and ES 2.0 on mobile. - this._translucentMultipassSupport = false; - this._translucentMRTSupport = false; - - var extensionsSupported = context.floatingPointTexture && context.depthTexture; - this._translucentMRTSupport = context.drawBuffers && extensionsSupported; - this._translucentMultipassSupport = !this._translucentMRTSupport && extensionsSupported; + function InvertClassification() { + this.previousFramebuffer = undefined; + this._previousFramebuffer = undefined; - this._opaqueFBO = undefined; - this._opaqueTexture = undefined; + this._texture = undefined; + this._classifiedTexture = undefined; this._depthStencilTexture = undefined; + this._fbo = undefined; + this._fboClassified = undefined; - this._accumulationTexture = undefined; - - this._translucentFBO = undefined; - this._alphaFBO = undefined; + this._rsUnclassified = undefined; + this._rsClassified = undefined; - this._adjustTranslucentFBO = undefined; - this._adjustAlphaFBO = undefined; + this._unclassifiedCommand = undefined; + this._classifiedCommand = undefined; + this._translucentCommand = undefined; - this._opaqueClearCommand = new ClearCommand({ + this._clearColorCommand = new ClearCommand({ color : new Color(0.0, 0.0, 0.0, 0.0), owner : this }); - this._translucentMRTClearCommand = new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 1.0), - owner : this - }); - this._translucentMultipassClearCommand = new ClearCommand({ + this._clearCommand = new ClearCommand({ color : new Color(0.0, 0.0, 0.0, 0.0), - owner : this - }); - this._alphaClearCommand = new ClearCommand({ - color : new Color(1.0, 1.0, 1.0, 1.0), - owner : this + depth : 1.0, + stencil : 0 }); - this._translucentRenderStateCache = {}; - this._alphaRenderStateCache = {}; - - this._compositeCommand = undefined; - this._adjustTranslucentCommand = undefined; - this._adjustAlphaCommand = undefined; - - this._viewport = new BoundingRectangle(); - this._rs = undefined; - - this._useScissorTest = false; - this._scissorRectangle = undefined; - } - - function destroyTextures(oit) { - oit._accumulationTexture = oit._accumulationTexture && !oit._accumulationTexture.isDestroyed() && oit._accumulationTexture.destroy(); - oit._revealageTexture = oit._revealageTexture && !oit._revealageTexture.isDestroyed() && oit._revealageTexture.destroy(); - } - - function destroyFramebuffers(oit) { - oit._translucentFBO = oit._translucentFBO && !oit._translucentFBO.isDestroyed() && oit._translucentFBO.destroy(); - oit._alphaFBO = oit._alphaFBO && !oit._alphaFBO.isDestroyed() && oit._alphaFBO.destroy(); - oit._adjustTranslucentFBO = oit._adjustTranslucentFBO && !oit._adjustTranslucentFBO.isDestroyed() && oit._adjustTranslucentFBO.destroy(); - oit._adjustAlphaFBO = oit._adjustAlphaFBO && !oit._adjustAlphaFBO.isDestroyed() && oit._adjustAlphaFBO.destroy(); - } - - function destroyResources(oit) { - destroyTextures(oit); - destroyFramebuffers(oit); - } - - function updateTextures(oit, context, width, height) { - destroyTextures(oit); - - // Use zeroed arraybuffer instead of null to initialize texture - // to workaround Firefox 50. https://github.com/AnalyticalGraphicsInc/cesium/pull/4762 - var source = new Float32Array(width * height * 4); - - oit._accumulationTexture = new Texture({ - context : context, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.FLOAT, - source : { - arrayBufferView : source, - width : width, - height : height - } - }); - oit._revealageTexture = new Texture({ - context : context, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.FLOAT, - source : { - arrayBufferView : source, - width : width, - height : height + var that = this; + this._uniformMap = { + u_texture : function() { + return that._texture; + }, + u_depth : function() { + return that._depthStencilTexture; + }, + u_classified : function() { + return that._classifiedTexture; } - }); + }; } - function updateFramebuffers(oit, context) { - destroyFramebuffers(oit); - - var completeFBO = WebGLConstants.FRAMEBUFFER_COMPLETE; - var supported = true; - - // if MRT is supported, attempt to make an FBO with multiple color attachments - if (oit._translucentMRTSupport) { - oit._translucentFBO = new Framebuffer({ - context : context, - colorTextures : [oit._accumulationTexture, oit._revealageTexture], - depthStencilTexture : oit._depthStencilTexture, - destroyAttachments : false - }); - oit._adjustTranslucentFBO = new Framebuffer({ - context : context, - colorTextures : [oit._accumulationTexture, oit._revealageTexture], - destroyAttachments : false - }); - - if (oit._translucentFBO.status !== completeFBO || oit._adjustTranslucentFBO.status !== completeFBO) { - destroyFramebuffers(oit); - oit._translucentMRTSupport = false; + defineProperties(InvertClassification.prototype, { + unclassifiedCommand : { + get : function() { + return this._unclassifiedCommand; } } + }); - // either MRT isn't supported or FBO creation failed, attempt multipass - if (!oit._translucentMRTSupport) { - oit._translucentFBO = new Framebuffer({ - context : context, - colorTextures : [oit._accumulationTexture], - depthStencilTexture : oit._depthStencilTexture, - destroyAttachments : false - }); - oit._alphaFBO = new Framebuffer({ - context : context, - colorTextures : [oit._revealageTexture], - depthStencilTexture : oit._depthStencilTexture, - destroyAttachments : false - }); - oit._adjustTranslucentFBO = new Framebuffer({ - context : context, - colorTextures : [oit._accumulationTexture], - destroyAttachments : false - }); - oit._adjustAlphaFBO = new Framebuffer({ - context : context, - colorTextures : [oit._revealageTexture], - destroyAttachments : false - }); + InvertClassification.isTranslucencySupported = function(context) { + return context.depthTexture && context.fragmentDepth; + }; - var translucentComplete = oit._translucentFBO.status === completeFBO; - var alphaComplete = oit._alphaFBO.status === completeFBO; - var adjustTranslucentComplete = oit._adjustTranslucentFBO.status === completeFBO; - var adjustAlphaComplete = oit._adjustAlphaFBO.status === completeFBO; - if (!translucentComplete || !alphaComplete || !adjustTranslucentComplete || !adjustAlphaComplete) { - destroyResources(oit); - oit._translucentMultipassSupport = false; - supported = false; - } - } + // The stencil mask only uses the least significant 4 bits. + // This is so 3D Tiles with the skip LOD optimization, which uses the most significant 4 bits, + // can be classified. + var stencilMask = 0x0F; + var stencilReference = 0; - return supported; - } + var rsUnclassified = { + depthMask : false, + stencilTest : { + enabled : true, + frontFunction : StencilFunction.EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.KEEP + }, + backFunction : StencilFunction.NEVER, + reference : stencilReference, + mask : stencilMask + }, + blending : BlendingState.ALPHA_BLEND + }; - OIT.prototype.update = function(context, passState, framebuffer) { - if (!this.isSupported()) { - return; - } + var rsClassified = { + depthMask : false, + stencilTest : { + enabled : true, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.KEEP + }, + backFunction : StencilFunction.NEVER, + reference : stencilReference, + mask : stencilMask + }, + blending : BlendingState.ALPHA_BLEND + }; - this._opaqueFBO = framebuffer; - this._opaqueTexture = framebuffer.getColorTexture(0); - this._depthStencilTexture = framebuffer.depthStencilTexture; + var rsDefault = { + depthMask : true, + depthTest : { + enabled : true + }, + blending : BlendingState.ALPHA_BLEND + }; - var width = this._opaqueTexture.width; - var height = this._opaqueTexture.height; + var translucentFS = + '#extension GL_EXT_frag_depth : enable\n'+ + 'uniform sampler2D u_texture;\n' + + 'uniform sampler2D u_depth;\n' + + 'uniform sampler2D u_classified;\n' + + 'varying vec2 v_textureCoordinates;\n' + + 'void main()\n' + + '{\n' + + ' vec4 color = texture2D(u_texture, v_textureCoordinates);\n' + + ' if (color.a == 0.0)\n' + + ' {\n' + + ' discard;\n' + + ' }\n' + + ' bool isClassified = all(equal(texture2D(u_classified, v_textureCoordinates), vec4(0.0)));\n' + + '#ifdef UNCLASSIFIED\n' + + ' vec4 highlightColor = czm_invertClassificationColor;\n' + + ' if (isClassified)\n' + + ' {\n' + + ' discard;\n' + + ' }\n' + + '#else\n' + + ' vec4 highlightColor = vec4(1.0);\n' + + ' if (!isClassified)\n' + + ' {\n' + + ' discard;\n' + + ' }\n' + + '#endif\n' + + ' gl_FragColor = color * highlightColor;\n' + + ' gl_FragDepthEXT = texture2D(u_depth, v_textureCoordinates).r;\n' + + '}\n'; - var accumulationTexture = this._accumulationTexture; - var textureChanged = !defined(accumulationTexture) || accumulationTexture.width !== width || accumulationTexture.height !== height; - if (textureChanged) { - updateTextures(this, context, width, height); - } + var opaqueFS = + 'uniform sampler2D u_texture;\n' + + 'varying vec2 v_textureCoordinates;\n' + + 'void main()\n' + + '{\n' + + ' vec4 color = texture2D(u_texture, v_textureCoordinates);\n' + + ' if (color.a == 0.0)\n' + + ' {\n' + + ' discard;\n' + + ' }\n' + + '#ifdef UNCLASSIFIED\n' + + ' gl_FragColor = color * czm_invertClassificationColor;\n' + + '#else\n' + + ' gl_FragColor = color;\n' + + '#endif\n' + + '}\n'; - if (!defined(this._translucentFBO) || textureChanged) { - if (!updateFramebuffers(this, context)) { - // framebuffer creation failed - return; - } - } + InvertClassification.prototype.update = function(context) { + var texture = this._texture; + var previousFramebufferChanged = !defined(texture) || this.previousFramebuffer !== this._previousFramebuffer; + this._previousFramebuffer = this.previousFramebuffer; - var that = this; - var fs; - var uniformMap; + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; - if (!defined(this._compositeCommand)) { - fs = new ShaderSource({ - sources : [CompositeOITFS] - }); - if (this._translucentMRTSupport) { - fs.defines.push('MRT'); - } + var textureChanged = !defined(texture) || texture.width !== width || texture.height !== height; + if (textureChanged || previousFramebufferChanged) { + this._texture = this._texture && this._texture.destroy(); + this._classifiedTexture = this._classifiedTexture && this._classifiedTexture.destroy(); + this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); - uniformMap = { - u_opaque : function() { - return that._opaqueTexture; - }, - u_accumulation : function() { - return that._accumulationTexture; - }, - u_revealage : function() { - return that._revealageTexture; - } - }; - this._compositeCommand = context.createViewportQuadCommand(fs, { - uniformMap : uniformMap, - owner : this + this._texture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.LINEAR, + magnificationFilter : TextureMagnificationFilter.LINEAR + }) }); - } - - if (!defined(this._adjustTranslucentCommand)) { - if (this._translucentMRTSupport) { - fs = new ShaderSource({ - defines : ['MRT'], - sources : [AdjustTranslucentFS] - }); - - uniformMap = { - u_bgColor : function() { - return that._translucentMRTClearCommand.color; - }, - u_depthTexture : function() { - return that._depthStencilTexture; - } - }; - this._adjustTranslucentCommand = context.createViewportQuadCommand(fs, { - uniformMap : uniformMap, - owner : this - }); - } else if (this._translucentMultipassSupport) { - fs = new ShaderSource({ - sources : [AdjustTranslucentFS] - }); - - uniformMap = { - u_bgColor : function() { - return that._translucentMultipassClearCommand.color; - }, - u_depthTexture : function() { - return that._depthStencilTexture; - } - }; - - this._adjustTranslucentCommand = context.createViewportQuadCommand(fs, { - uniformMap : uniformMap, - owner : this + if (!defined(this._previousFramebuffer)) { + this._classifiedTexture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.LINEAR, + magnificationFilter : TextureMagnificationFilter.LINEAR + }) }); - - uniformMap = { - u_bgColor : function() { - return that._alphaClearCommand.color; - }, - u_depthTexture : function() { - return that._depthStencilTexture; - } - }; - - this._adjustAlphaCommand = context.createViewportQuadCommand(fs, { - uniformMap : uniformMap, - owner : this + this._depthStencilTexture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.DEPTH_STENCIL, + pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 }); } } - this._viewport.width = width; - this._viewport.height = height; - - var useScissorTest = !BoundingRectangle.equals(this._viewport, passState.viewport); - var updateScissor = useScissorTest !== this._useScissorTest; - this._useScissorTest = useScissorTest; + if (!defined(this._fbo) || textureChanged || previousFramebufferChanged) { + this._fbo = this._fbo && this._fbo.destroy(); + this._fboClassified = this._fboClassified && this._fboClassified.destroy(); - if (!BoundingRectangle.equals(this._scissorRectangle, passState.viewport)) { - this._scissorRectangle = BoundingRectangle.clone(passState.viewport, this._scissorRectangle); - updateScissor = true; - } + var depthStencilTexture; + var depthStencilRenderbuffer; + if (defined(this._previousFramebuffer)) { + depthStencilTexture = this._previousFramebuffer.depthStencilTexture; + depthStencilRenderbuffer = this._previousFramebuffer.depthStencilRenderbuffer; + } else { + depthStencilTexture = this._depthStencilTexture; + } - if (!defined(this._rs) || !BoundingRectangle.equals(this._viewport, this._rs.viewport) || updateScissor) { - this._rs = RenderState.fromCache({ - viewport : this._viewport, - scissorTest : { - enabled : this._useScissorTest, - rectangle : this._scissorRectangle - } + this._fbo = new Framebuffer({ + context : context, + colorTextures : [this._texture], + depthStencilTexture : depthStencilTexture, + depthStencilRenderbuffer : depthStencilRenderbuffer, + destroyAttachments : false }); - } - - if (defined(this._compositeCommand)) { - this._compositeCommand.renderState = this._rs; - } - - if (this._adjustTranslucentCommand) { - this._adjustTranslucentCommand.renderState = this._rs; - } - if (defined(this._adjustAlphaCommand)) { - this._adjustAlphaCommand.renderState = this._rs; + if (!defined(this._previousFramebuffer)) { + this._fboClassified = new Framebuffer({ + context : context, + colorTextures : [this._classifiedTexture], + depthStencilTexture : depthStencilTexture, + destroyAttachments : false + }); + } } - }; - - var translucentMRTBlend = { - enabled : true, - color : new Color(0.0, 0.0, 0.0, 0.0), - equationRgb : BlendEquation.ADD, - equationAlpha : BlendEquation.ADD, - functionSourceRgb : BlendFunction.ONE, - functionDestinationRgb : BlendFunction.ONE, - functionSourceAlpha : BlendFunction.ZERO, - functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA - }; - - var translucentColorBlend = { - enabled : true, - color : new Color(0.0, 0.0, 0.0, 0.0), - equationRgb : BlendEquation.ADD, - equationAlpha : BlendEquation.ADD, - functionSourceRgb : BlendFunction.ONE, - functionDestinationRgb : BlendFunction.ONE, - functionSourceAlpha : BlendFunction.ONE, - functionDestinationAlpha : BlendFunction.ONE - }; - - var translucentAlphaBlend = { - enabled : true, - color : new Color(0.0, 0.0, 0.0, 0.0), - equationRgb : BlendEquation.ADD, - equationAlpha : BlendEquation.ADD, - functionSourceRgb : BlendFunction.ZERO, - functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA, - functionSourceAlpha : BlendFunction.ZERO, - functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA - }; - - function getTranslucentRenderState(context, translucentBlending, cache, renderState) { - var translucentState = cache[renderState.id]; - if (!defined(translucentState)) { - var rs = RenderState.getState(renderState); - rs.depthMask = false; - rs.blending = translucentBlending; - translucentState = RenderState.fromCache(rs); - cache[renderState.id] = translucentState; + if (!defined(this._rsUnclassified)) { + this._rsUnclassified = RenderState.fromCache(rsUnclassified); + this._rsClassified = RenderState.fromCache(rsClassified); + this._rsDefault = RenderState.fromCache(rsDefault); } - return translucentState; - } - - function getTranslucentMRTRenderState(oit, context, renderState) { - return getTranslucentRenderState(context, translucentMRTBlend, oit._translucentRenderStateCache, renderState); - } - - function getTranslucentColorRenderState(oit, context, renderState) { - return getTranslucentRenderState(context, translucentColorBlend, oit._translucentRenderStateCache, renderState); - } - - function getTranslucentAlphaRenderState(oit, context, renderState) { - return getTranslucentRenderState(context, translucentAlphaBlend, oit._alphaRenderStateCache, renderState); - } - - var mrtShaderSource = - ' vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n' + - ' float ai = czm_gl_FragColor.a;\n' + - ' float wzi = czm_alphaWeight(ai);\n' + - ' gl_FragData[0] = vec4(Ci * wzi, ai);\n' + - ' gl_FragData[1] = vec4(ai * wzi);\n'; - - var colorShaderSource = - ' vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n' + - ' float ai = czm_gl_FragColor.a;\n' + - ' float wzi = czm_alphaWeight(ai);\n' + - ' gl_FragColor = vec4(Ci, ai) * wzi;\n'; - - var alphaShaderSource = - ' float ai = czm_gl_FragColor.a;\n' + - ' gl_FragColor = vec4(ai);\n'; - - function getTranslucentShaderProgram(context, shaderProgram, keyword, source) { - var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword); - if (!defined(shader)) { - var attributeLocations = shaderProgram._attributeLocations; - - var fs = shaderProgram.fragmentShaderSource.clone(); + if (!defined(this._unclassifiedCommand) || previousFramebufferChanged) { + if (defined(this._unclassifiedCommand)) { + this._unclassifiedCommand.shaderProgram = this._unclassifiedCommand.shaderProgram && this._unclassifiedCommand.shaderProgram.destroy(); + this._classifiedCommand.shaderProgram = this._classifiedCommand.shaderProgram && this._classifiedCommand.shaderProgram.destroy(); + } - fs.sources = fs.sources.map(function(source) { - source = ShaderSource.replaceMain(source, 'czm_translucent_main'); - source = source.replace(/gl_FragColor/g, 'czm_gl_FragColor'); - source = source.replace(/\bdiscard\b/g, 'czm_discard = true'); - source = source.replace(/czm_phong/g, 'czm_translucentPhong'); - return source; + var fs = defined(this._previousFramebuffer) ? opaqueFS : translucentFS; + var unclassifiedFSSource = new ShaderSource({ + defines : ['UNCLASSIFIED'], + sources : [fs] }); - - // Discarding the fragment in main is a workaround for ANGLE D3D9 - // shader compilation errors. - - fs.sources.splice(0, 0, - (source.indexOf('gl_FragData') !== -1 ? '#extension GL_EXT_draw_buffers : enable \n' : '') + - 'vec4 czm_gl_FragColor;\n' + - 'bool czm_discard = false;\n'); - - fs.sources.push( - 'void main()\n' + - '{\n' + - ' czm_translucent_main();\n' + - ' if (czm_discard)\n' + - ' {\n' + - ' discard;\n' + - ' }\n' + - source + - '}\n'); - - shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, { - vertexShaderSource : shaderProgram.vertexShaderSource, - fragmentShaderSource : fs, - attributeLocations : attributeLocations + var classifiedFSSource = new ShaderSource({ + sources : [fs] + }); + this._unclassifiedCommand = context.createViewportQuadCommand(unclassifiedFSSource, { + renderState : defined(this._previousFramebuffer) ? this._rsUnclassified : this._rsDefault, + uniformMap : this._uniformMap, + owner : this + }); + this._classifiedCommand = context.createViewportQuadCommand(classifiedFSSource, { + renderState : defined(this._previousFramebuffer) ? this._rsClassified : this._rsDefault, + uniformMap : this._uniformMap, + owner : this }); - } - - return shader; - } - - function getTranslucentMRTShaderProgram(context, shaderProgram) { - return getTranslucentShaderProgram(context, shaderProgram, 'translucentMRT', mrtShaderSource); - } - - function getTranslucentColorShaderProgram(context, shaderProgram) { - return getTranslucentShaderProgram(context, shaderProgram, 'translucentMultipass', colorShaderSource); - } - - function getTranslucentAlphaShaderProgram(context, shaderProgram) { - return getTranslucentShaderProgram(context, shaderProgram, 'alphaMultipass', alphaShaderSource); - } - - OIT.prototype.createDerivedCommands = function(command, context, result) { - if (!defined(result)) { - result = {}; - } - - if (this._translucentMRTSupport) { - var translucentShader; - var translucentRenderState; - if (defined(result.translucentCommand)) { - translucentShader = result.translucentCommand.shaderProgram; - translucentRenderState = result.translucentCommand.renderState; - } - - result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand); - if (!defined(translucentShader) || result.shaderProgramId !== command.shaderProgram.id) { - result.translucentCommand.shaderProgram = getTranslucentMRTShaderProgram(context, command.shaderProgram); - result.translucentCommand.renderState = getTranslucentMRTRenderState(this, context, command.renderState); - result.shaderProgramId = command.shaderProgram.id; - } else { - result.translucentCommand.shaderProgram = translucentShader; - result.translucentCommand.renderState = translucentRenderState; - } - } else { - var colorShader; - var colorRenderState; - var alphaShader; - var alphaRenderState; - if (defined(result.translucentCommand)) { - colorShader = result.translucentCommand.shaderProgram; - colorRenderState = result.translucentCommand.renderState; - alphaShader = result.alphaCommand.shaderProgram; - alphaRenderState = result.alphaCommand.renderState; + if (defined(this._translucentCommand)) { + this._translucentCommand.shaderProgram = this._translucentCommand.shaderProgram && this._translucentCommand.shaderProgram.destroy(); } - - result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand); - result.alphaCommand = DrawCommand.shallowClone(command, result.alphaCommand); - - if (!defined(colorShader) || result.shaderProgramId !== command.shaderProgram.id) { - result.translucentCommand.shaderProgram = getTranslucentColorShaderProgram(context, command.shaderProgram); - result.translucentCommand.renderState = getTranslucentColorRenderState(this, context, command.renderState); - result.alphaCommand.shaderProgram = getTranslucentAlphaShaderProgram(context, command.shaderProgram); - result.alphaCommand.renderState = getTranslucentAlphaRenderState(this, context, command.renderState); - result.shaderProgramId = command.shaderProgram.id; - } else { - result.translucentCommand.shaderProgram = colorShader; - result.translucentCommand.renderState = colorRenderState; - result.alphaCommand.shaderProgram = alphaShader; - result.alphaCommand.renderState = alphaRenderState; + if (!defined(this._previousFramebuffer)) { + this._translucentCommand = context.createViewportQuadCommand(PassThrough, { + renderState : this._rsUnclassified, + uniformMap : this._uniformMap, + owner : this + }); } } - - return result; }; - function executeTranslucentCommandsSortedMultipass(oit, scene, executeFunction, passState, commands, invertClassification) { - var command; - var derivedCommand; - var j; - - var context = scene.context; - var framebuffer = passState.framebuffer; - var length = commands.length; - - var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; - - passState.framebuffer = oit._adjustTranslucentFBO; - oit._adjustTranslucentCommand.execute(context, passState); - passState.framebuffer = oit._adjustAlphaFBO; - oit._adjustAlphaCommand.execute(context, passState); - - var debugFramebuffer = oit._opaqueFBO; - passState.framebuffer = oit._translucentFBO; - - for (j = 0; j < length; ++j) { - command = commands[j]; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; - executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); - } - - if (defined(invertClassification)) { - command = invertClassification.unclassifiedCommand; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; - executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); - } - - passState.framebuffer = oit._alphaFBO; - - for (j = 0; j < length; ++j) { - command = commands[j]; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; - executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); - } - - if (defined(invertClassification)) { - command = invertClassification.unclassifiedCommand; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; - executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); - } - - passState.framebuffer = framebuffer; - } - - function executeTranslucentCommandsSortedMRT(oit, scene, executeFunction, passState, commands, invertClassification) { - var context = scene.context; + InvertClassification.prototype.clear = function(context, passState) { var framebuffer = passState.framebuffer; - var length = commands.length; - - var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; - - passState.framebuffer = oit._adjustTranslucentFBO; - oit._adjustTranslucentCommand.execute(context, passState); - - var debugFramebuffer = oit._opaqueFBO; - passState.framebuffer = oit._translucentFBO; - - var command; - var derivedCommand; - - for (var j = 0; j < length; ++j) { - command = commands[j]; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; - executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); - } - if (defined(invertClassification)) { - command = invertClassification.unclassifiedCommand; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; - executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + if (defined(this._previousFramebuffer)) { + passState.framebuffer = this._fbo; + this._clearColorCommand.execute(context, passState); + } else { + passState.framebuffer = this._fbo; + this._clearCommand.execute(context, passState); + passState.framebuffer = this._fboClassified; + this._clearCommand.execute(context, passState); } passState.framebuffer = framebuffer; - } - - OIT.prototype.executeCommands = function(scene, executeFunction, passState, commands, invertClassification) { - if (this._translucentMRTSupport) { - executeTranslucentCommandsSortedMRT(this, scene, executeFunction, passState, commands, invertClassification); - return; - } - - executeTranslucentCommandsSortedMultipass(this, scene, executeFunction, passState, commands, invertClassification); - }; - - OIT.prototype.execute = function(context, passState) { - this._compositeCommand.execute(context, passState); }; - OIT.prototype.clear = function(context, passState, clearColor) { - var framebuffer = passState.framebuffer; - - passState.framebuffer = this._opaqueFBO; - Color.clone(clearColor, this._opaqueClearCommand.color); - this._opaqueClearCommand.execute(context, passState); + InvertClassification.prototype.executeClassified = function(context, passState) { + if (!defined(this._previousFramebuffer)) { + var framebuffer = passState.framebuffer; - passState.framebuffer = this._translucentFBO; - var translucentClearCommand = this._translucentMRTSupport ? this._translucentMRTClearCommand : this._translucentMultipassClearCommand; - translucentClearCommand.execute(context, passState); + passState.framebuffer = this._fboClassified; + this._translucentCommand.execute(context, passState); - if (this._translucentMultipassSupport) { - passState.framebuffer = this._alphaFBO; - this._alphaClearCommand.execute(context, passState); + passState.framebuffer = framebuffer; } - - passState.framebuffer = framebuffer; + this._classifiedCommand.execute(context, passState); }; - OIT.prototype.isSupported = function() { - return this._translucentMRTSupport || this._translucentMultipassSupport; + InvertClassification.prototype.executeUnclassified = function(context, passState) { + this._unclassifiedCommand.execute(context, passState); }; - OIT.prototype.isDestroyed = function() { + InvertClassification.prototype.isDestroyed = function() { return false; }; - OIT.prototype.destroy = function() { - destroyResources(this); - - if (defined(this._compositeCommand)) { - this._compositeCommand.shaderProgram = this._compositeCommand.shaderProgram && this._compositeCommand.shaderProgram.destroy(); - } - - if (defined(this._adjustTranslucentCommand)) { - this._adjustTranslucentCommand.shaderProgram = this._adjustTranslucentCommand.shaderProgram && this._adjustTranslucentCommand.shaderProgram.destroy(); - } + InvertClassification.prototype.destroy = function() { + this._fbo = this._fbo && this._fbo.destroy(); + this._texture = this._texture && this._texture.destroy(); + this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); - if (defined(this._adjustAlphaCommand)) { - this._adjustAlphaCommand.shaderProgram = this._adjustAlphaCommand.shaderProgram && this._adjustAlphaCommand.shaderProgram.destroy(); + if (defined(this._unclassifiedCommand)) { + this._unclassifiedCommand.shaderProgram = this._unclassifiedCommand.shaderProgram && this._unclassifiedCommand.shaderProgram.destroy(); + this._classifiedCommand.shaderProgram = this._classifiedCommand.shaderProgram && this._classifiedCommand.shaderProgram.destroy(); } return destroyObject(this); }; - return OIT; + return InvertClassification; }); -define('Scene/Particle',[ - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Color', - '../Core/defaultValue', +define('Scene/JobScheduler',[ '../Core/defined', - '../Core/defineProperties' + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/getTimestamp', + './JobType' ], function( - Cartesian2, - Cartesian3, - Color, - defaultValue, defined, - defineProperties) { + defineProperties, + DeveloperError, + getTimestamp, + JobType) { 'use strict'; - var defaultSize = new Cartesian2(1.0, 1.0); - - /** - * A particle emitted by a {@link ParticleSystem}. - * - * @alias Particle - * @constructor - * - * @param {Object} options An object with the following properties: - * @param {Number} [options.mass=1.0] The mass of particles in kilograms. - * @param {Cartesian3} [options.position=Cartesian3.ZERO] The initial position of the particle in world coordinates. - * @param {Cartesian3} [options.velocity=Cartesian3.ZERO] The velocity vector of the particle in world coordinates. - * @param {Number} [options.life=Number.MAX_VALUE] The life of particles in seconds. - * @param {Object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. - * @param {Color} [options.startColor=Color.WHITE] The color of a particle when it is born. - * @param {Color} [options.endColor=Color.WHITE] The color of a particle when it dies. - * @param {Number} [options.startScale=1.0] The scale of the particle when it is born. - * @param {Number} [options.endScale=1.0] The scale of the particle when it dies. - * @param {Cartesian2} [options.size=new Cartesian2(1.0, 1.0)] The dimensions of particles in pixels. - */ - function Particle(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * The mass of the particle in kilograms. - * @type {Number} - * @default 1.0 - */ - this.mass = defaultValue(options.mass, 1.0); - /** - * The positon of the particle in world coordinates. - * @type {Cartesian3} - * @default Cartesian3.ZERO - */ - this.position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); - /** - * The velocity of the particle in world coordinates. - * @type {Cartesian3} - * @default Cartesian3.ZERO - */ - this.velocity = Cartesian3.clone(defaultValue(options.velocity, Cartesian3.ZERO)); - /** - * The life of the particle in seconds. - * @type {Number} - * @default Number.MAX_VALUE - */ - this.life = defaultValue(options.life, Number.MAX_VALUE); - /** - * The image to use for the particle. - * @type {Object} - * @default undefined - */ - this.image = options.image; + function JobTypeBudget(total) { /** - * The color of the particle when it is born. - * @type {Color} - * @default Color.WHITE + * Total budget, in milliseconds, allowed for one frame */ - this.startColor = Color.clone(defaultValue(options.startColor, Color.WHITE)); + this._total = total; + /** - * The color of the particle when it dies. - * @type {Color} - * @default Color.WHITE + * Time, in milliseconds, used so far during this frame */ - this.endColor = Color.clone(defaultValue(options.endColor, Color.WHITE)); + this.usedThisFrame = 0.0; + /** - * the scale of the particle when it is born. - * @type {Number} - * @default 1.0 + * Time, in milliseconds, that other job types stole this frame */ - this.startScale = defaultValue(options.startScale, 1.0); + this.stolenFromMeThisFrame = 0.0; + /** - * The scale of the particle when it dies. - * @type {Number} - * @default 1.0 + * Indicates if this job type was starved this frame, i.e., a job + * tried to run but didn't have budget */ - this.endScale = defaultValue(options.endScale, 1.0); + this.starvedThisFrame = false; + /** - * The dimensions of the particle in pixels. - * @type {Cartesian2} - * @default new Cartesian(1.0, 1.0) + * Indicates if this job was starved last frame. This prevents it + * from being stolen from this frame. */ - this.size = Cartesian2.clone(defaultValue(options.size, defaultSize)); - - this._age = 0.0; - this._normalizedAge = 0.0; - - // used by ParticleSystem - this._billboard = undefined; + this.starvedLastFrame = false; } - defineProperties(Particle.prototype, { - /** - * Gets the age of the particle in seconds. - * @memberof Particle.prototype - * @type {Number} - */ - age : { - get : function() { - return this._age; - } - }, - /** - * Gets the age normalized to a value in the range [0.0, 1.0]. - * @memberof Particle.prototype - * @type {Number} - */ - normalizedAge : { + defineProperties(JobTypeBudget.prototype, { + total : { get : function() { - return this._normalizedAge; + return this._total; } } }); - var deltaScratch = new Cartesian3(); - /** + * Engine for time slicing jobs during a frame to amortize work over multiple frames. This supports: + * <ul> + * <li> + * Separate budgets for different job types, e.g., texture, shader program, and buffer creation. This + * allows all job types to make progress each frame. + * </li> + * <li> + * Stealing from other jobs type budgets if they were not exhausted in the previous frame. This allows + * using the entire budget for all job types each frame even if, for example, all the jobs are the same type. + * </li> + * <li> + * Guaranteed progress on all job types each frame, even if it means exceeding the total budget for the frame. + * This prevents, for example, several expensive texture uploads over many frames from prevent a shader compile. + * </li> + * </ul> + * * @private */ - Particle.prototype.update = function(dt, forces) { - // Apply the velocity - Cartesian3.multiplyByScalar(this.velocity, dt, deltaScratch); - Cartesian3.add(this.position, deltaScratch, this.position); + function JobScheduler(budgets) { + if (defined(budgets) && (budgets.length !== JobType.NUMBER_OF_JOB_TYPES)) { + throw new DeveloperError('A budget must be specified for each job type; budgets.length should equal JobType.NUMBER_OF_JOB_TYPES.'); + } + + // Total for defaults is half of of one frame at 10 fps + var jobBudgets = new Array(JobType.NUMBER_OF_JOB_TYPES); + jobBudgets[JobType.TEXTURE] = new JobTypeBudget(defined(budgets) ? budgets[JobType.TEXTURE] : 10.0); + // On cache miss, this most likely only allows one shader compile per frame + jobBudgets[JobType.PROGRAM] = new JobTypeBudget(defined(budgets) ? budgets[JobType.PROGRAM] : 10.0); + jobBudgets[JobType.BUFFER] = new JobTypeBudget(defined(budgets) ? budgets[JobType.BUFFER] : 30.0); - // Update any forces. - if (defined(forces)) { - var length = forces.length; - for (var i = 0; i < length; ++i) { - var force = forces[i]; - if (typeof force === 'function') { - // Force is just a simple callback function. - force(this, dt); - } - } + var length = jobBudgets.length; + var i; + + var totalBudget = 0.0; + for (i = 0; i < length; ++i) { + totalBudget += jobBudgets[i].total; } - // Age the particle - this._age += dt; + var executedThisFrame = new Array(length); + for (i = 0; i < length; ++i) { + executedThisFrame[i] = false; + } - // Compute the normalized age. - if (this.life === Number.MAX_VALUE) { - this._normalizedAge = 0.0; - } else { - this._normalizedAge = this._age / this.life; + this._totalBudget = totalBudget; + this._totalUsedThisFrame = 0.0; + this._budgets = jobBudgets; + this._executedThisFrame = executedThisFrame; + } + + // For unit testing + JobScheduler.getTimestamp = getTimestamp; + + defineProperties(JobScheduler.prototype, { + totalBudget : { + get : function() { + return this._totalBudget; + } } + }); - // If this particle is older than it's lifespan then die. - return this._age <= this.life; + JobScheduler.prototype.disableThisFrame = function() { + // Prevent jobs from running this frame + this._totalUsedThisFrame = this._totalBudget; }; - return Particle; -}); + JobScheduler.prototype.resetBudgets = function() { + var budgets = this._budgets; + var length = budgets.length; + for (var i = 0; i < length; ++i) { + var budget = budgets[i]; + budget.starvedLastFrame = budget.starvedThisFrame; + budget.starvedThisFrame = false; + budget.usedThisFrame = 0.0; + budget.stolenFromMeThisFrame = 0.0; + } + this._totalUsedThisFrame = 0.0; + }; -define('Scene/ParticleBurst',[ - '../Core/defaultValue', - '../Core/defineProperties' - ], function( - defaultValue, - defineProperties) { - 'use strict'; + JobScheduler.prototype.execute = function(job, jobType) { + var budgets = this._budgets; + var budget = budgets[jobType]; - /** - * Represents a burst of {@link Particle}s from a {@link ParticleSystem} at a given time in the systems lifetime. - * - * @alias ParticleBurst - * @constructor - * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.time=0.0] The time in seconds after the beginning of the particle system's lifetime that the burst will occur. - * @param {Number} [options.minimum=0.0] The minimum number of particles emmitted in the burst. - * @param {Number} [options.maximum=50.0] The maximum number of particles emitted in the burst. - */ - function ParticleBurst(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + // This ensures each job type makes progress each frame by executing at least once + var progressThisFrame = this._executedThisFrame[jobType]; - /** - * The time in seconds after the eginning of the particle system's lifetime that the burst will occur. - * @type {Number} - * @default 0.0 - */ - this.time = defaultValue(options.time, 0.0); - /** - * The minimum number of particles emitted. - * @type {Number} - * @default 0.0 - */ - this.minimum = defaultValue(options.minimum, 0.0); - /** - * The maximum number of particles emitted. - * @type {Number} - * @default 50.0 - */ - this.maximum = defaultValue(options.maximum, 50.0); + if ((this._totalUsedThisFrame >= this._totalBudget) && progressThisFrame) { + // No budget left this frame for jobs of any type + budget.starvedThisFrame = true; + return false; + } - this._complete = false; - } + var stolenBudget; - defineProperties(ParticleBurst.prototype, { - /** - * <code>true</code> if the burst has been completed; <code>false</code> otherwise. - * @memberof ParticleBurst.prototype - * @type {Boolean} - */ - complete : { - get : function() { - return this._complete; + if ((budget.usedThisFrame + budget.stolenFromMeThisFrame >= budget.total)) { + // No budget remaining for jobs of this type. Try to steal from other job types. + var length = budgets.length; + var i; + for (i = 0; i < length; ++i) { + stolenBudget = budgets[i]; + + // Steal from this budget if it has time left and it wasn't starved last fame + if ((stolenBudget.usedThisFrame + stolenBudget.stolenFromMeThisFrame < stolenBudget.total) && + (!stolenBudget.starvedLastFrame)) { + break; + } + } + + if (i === length && progressThisFrame) { + // No other job types can give up their budget this frame, and + // this job type already progressed this frame + return false; + } + + if (progressThisFrame) { + // It is considered "starved" even if it executes using stolen time so that + // next frame, no other job types can steal time from it. + budget.starvedThisFrame = true; } } - }); - return ParticleBurst; -}); + var startTime = JobScheduler.getTimestamp(); + job.execute(); + var duration = JobScheduler.getTimestamp() - startTime; -define('Scene/ParticleEmitter',[ - '../Core/DeveloperError' -], function(DeveloperError) { - 'use strict'; + // Track both time remaining for this job type and all jobs + // so budget stealing does send us way over the total budget. + this._totalUsedThisFrame += duration; - /** - * <p> - * An object that initializes a {@link Particle} from a {@link ParticleSystem}. - * </p> - * <p> - * This type describes an interface and is not intended to be instantiated directly. - * </p> - * - * @alias ParticleEmitter - * @constructor - * - * @see BoxEmitter - * @see CircleEmitter - * @see ConeEmitter - * @see SphereEmitter - */ - function ParticleEmitter(options) { - throw new DeveloperError('This type should not be instantiated directly. Instead, use BoxEmitter, CircleEmitter, ConeEmitter or SphereEmitter.'); - } + if (stolenBudget) { + stolenBudget.stolenFromMeThisFrame += duration; + } else { + budget.usedThisFrame += duration; + } + this._executedThisFrame[jobType] = true; - /** - * Initializes the given {Particle} by setting it's position and velocity. - * - * @private - * @param {Particle} The particle to initialize - */ - ParticleEmitter.prototype.emit = function(particle) { - DeveloperError.throwInstantiationError(); + return true; }; - return ParticleEmitter; + return JobScheduler; }); -define('Scene/ParticleSystem',[ - '../Core/Cartesian2', +define('Scene/Moon',[ + '../Core/buildModuleUrl', '../Core/Cartesian3', - '../Core/Check', - '../Core/Color', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', - '../Core/Event', - '../Core/JulianDate', - '../Core/Math', + '../Core/Ellipsoid', + '../Core/IauOrientationAxes', + '../Core/Matrix3', '../Core/Matrix4', - './BillboardCollection', - './CircleEmitter', - './Particle' + '../Core/Simon1994PlanetaryPositions', + '../Core/Transforms', + './EllipsoidPrimitive', + './Material' ], function( - Cartesian2, + buildModuleUrl, Cartesian3, - Check, - Color, defaultValue, defined, defineProperties, destroyObject, - Event, - JulianDate, - CesiumMath, + Ellipsoid, + IauOrientationAxes, + Matrix3, Matrix4, - BillboardCollection, - CircleEmitter, - Particle) { + Simon1994PlanetaryPositions, + Transforms, + EllipsoidPrimitive, + Material) { 'use strict'; /** - * A ParticleSystem manages the updating and display of a collection of particles. - * - * @alias ParticleSystem + * Draws the Moon in 3D. + * @alias Moon * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Whether to display the particle system. - * @param {ParticleSystem~applyForce[]} [options.forces] An array of force callbacks. - * @param {ParticleEmitter} [options.emitter=new CircleEmitter(0.5)] The particle emitter for this system. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system from model to world coordinates. - * @param {Matrix4} [options.emitterModelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system emitter within the particle systems local coordinate system. - * @param {Color} [options.startColor=Color.WHITE] The color of a particle when it is born. - * @param {Color} [options.endColor=Color.WHITE] The color of a particle when it dies. - * @param {Number} [options.startScale=1.0] The scale of the particle when it is born. - * @param {Number} [options.endScale=1.0] The scale of the particle when it dies. - * @param {Number} [options.rate=5] The number of particles to emit per second. - * @param {ParticleBurst[]} [options.bursts] An array of {@link ParticleBurst}, emitting bursts of particles at periodic times. - * @param {Boolean} [options.loop=true] Whether the particle system should loop it's bursts when it is complete. - * @param {Number} [options.speed] Sets the minimum and maximum speed in meters per second - * @param {Number} [options.minimumSpeed=1.0] Sets the minimum speed in meters per second. - * @param {Number} [options.maximumSpeed=1.0] Sets the maximum speed in meters per second. - * @param {Number} [options.life] Sets the minimum and maximum life of particles in seconds. - * @param {Number} [options.minimumLife=5.0] Sets the minimum life of particles in seconds. - * @param {Number} [options.maximumLife=5.0] Sets the maximum life of particles in seconds. - * @param {Number} [options.mass] Sets the minimum and maximum mass of particles in kilograms. - * @param {Number} [options.minimumMass=1.0] Sets the minimum mass of particles in kilograms. - * @param {Number} [options.maximumMass=1.0] Sets the maximum mass of particles in kilograms. - * @param {Object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. - * @param {Number} [options.width] Sets the minimum and maximum width of particles in pixels. - * @param {Number} [options.minimumWidth=1.0] Sets the minimum width of particles in pixels. - * @param {Number} [options.maximumWidth=1.0] Sets the maximum width of particles in pixels. - * @param {Number} [options.height] Sets the minimum and maximum height of particles in pixels. - * @param {Number} [options.minimumHeight=1.0] Sets the minimum height of particles in pixels. - * @param {Number} [options.maximumHeight=1.0] Sets the maximum height of particles in pixels. - * @param {Number} [options.lifeTime=Number.MAX_VALUE] How long the particle system will emit particles, in seconds. + * @param {Boolean} [options.show=true] Determines whether the moon will be rendered. + * @param {String} [options.textureUrl=buildModuleUrl('Assets/Textures/moonSmall.jpg')] The moon texture. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.MOON] The moon ellipsoid. + * @param {Boolean} [options.onlySunLighting=true] Use the sun as the only light source. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=ParticleSystem.html|Particle Systems Demo} + * + * @example + * scene.moon = new Cesium.Moon(); + * + * @see Scene#moon */ - function ParticleSystem(options) { + function Moon(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var url = options.textureUrl; + if (!defined(url)) { + url = buildModuleUrl('Assets/Textures/moonSmall.jpg'); + } + /** - * Whether to display the particle system. + * Determines if the moon will be shown. + * * @type {Boolean} * @default true */ this.show = defaultValue(options.show, true); /** - * An array of force callbacks. The callback is passed a {@link Particle} and the difference from the last time - * @type {ParticleSystem~applyForce[]} - * @default undefined + * The moon texture. + * @type {String} + * @default buildModuleUrl('Assets/Textures/moonSmall.jpg') */ - this.forces = options.forces; + this.textureUrl = url; + + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.MOON); /** - * Whether the particle system should loop it's bursts when it is complete. + * Use the sun as the only light source. * @type {Boolean} * @default true */ - this.loop = defaultValue(options.loop, true); - - /** - * The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. - * @type {Object} - * @default undefined - */ - this.image = defaultValue(options.image, undefined); - - var emitter = options.emitter; - if (!defined(emitter)) { - emitter = new CircleEmitter(0.5); - } - this._emitter = emitter; - - this._bursts = options.bursts; - - this._modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); - this._emitterModelMatrix = Matrix4.clone(defaultValue(options.emitterModelMatrix, Matrix4.IDENTITY)); - this._matrixDirty = true; - this._combinedMatrix = new Matrix4(); - - this._startColor = Color.clone(defaultValue(options.startColor, Color.WHITE)); - this._endColor = Color.clone(defaultValue(options.endColor, Color.WHITE)); - - this._startScale = defaultValue(options.startScale, 1.0); - this._endScale = defaultValue(options.endScale, 1.0); - - this._rate = defaultValue(options.rate, 5); - - this._minimumSpeed = defaultValue(options.speed, defaultValue(options.minimumSpeed, 1.0)); - this._maximumSpeed = defaultValue(options.speed, defaultValue(options.maximumSpeed, 1.0)); - - this._minimumLife = defaultValue(options.life, defaultValue(options.minimumLife, 5.0)); - this._maximumLife = defaultValue(options.life, defaultValue(options.maximumLife, 5.0)); - - this._minimumMass = defaultValue(options.mass, defaultValue(options.minimumMass, 1.0)); - this._maximumMass = defaultValue(options.mass, defaultValue(options.maximumMass, 1.0)); - - this._minimumWidth = defaultValue(options.width, defaultValue(options.minimumWidth, 1.0)); - this._maximumWidth = defaultValue(options.width, defaultValue(options.maximumWidth, 1.0)); - - this._minimumHeight = defaultValue(options.height, defaultValue(options.minimumHeight, 1.0)); - this._maximumHeight = defaultValue(options.height, defaultValue(options.maximumHeight, 1.0)); - - this._lifeTime = defaultValue(options.lifeTime, Number.MAX_VALUE); - - this._billboardCollection = undefined; - this._particles = []; - - // An array of available particles that we can reuse instead of allocating new. - this._particlePool = []; - - this._previousTime = undefined; - this._currentTime = 0.0; - this._carryOver = 0.0; + this.onlySunLighting = defaultValue(options.onlySunLighting, true); - this._complete = new Event(); - this._isComplete = false; + this._ellipsoidPrimitive = new EllipsoidPrimitive({ + radii : this.ellipsoid.radii, + material : Material.fromType(Material.ImageType), + depthTestEnabled : false, + _owner : this + }); + this._ellipsoidPrimitive.material.translucent = false; - this._updateParticlePool = true; - this._particleEstimate = 0; + this._axes = new IauOrientationAxes(); } - defineProperties(ParticleSystem.prototype, { - /** - * The particle emitter for this - * @memberof ParticleSystem.prototype - * @type {ParticleEmitter} - * @default CricleEmitter - */ - emitter : { - get : function() { - return this._emitter; - }, - set : function(value) { - Check.defined('value', value); - this._emitter = value; - } - }, - /** - * An array of {@link ParticleBurst}, emitting bursts of particles at periodic times. - * @type {ParticleBurst[]} - * @default undefined - */ - bursts : { - get : function() { - return this._bursts; - }, - set : function(value) { - this._bursts = value; - this._updateParticlePool = true; - } - }, - /** - * The 4x4 transformation matrix that transforms the particle system from model to world coordinates. - * @memberof ParticleSystem.prototype - * @type {Matrix4} - * @default Matrix4.IDENTITY - */ - modelMatrix : { - get : function() { - return this._modelMatrix; - }, - set : function(value) { - Check.defined('value', value); - this._matrixDirty = this._matrixDirty || !Matrix4.equals(this._modelMatrix, value); - Matrix4.clone(value, this._modelMatrix); - } - }, - /** - * The 4x4 transformation matrix that transforms the particle system emitter within the particle systems local coordinate system. - * @memberof ParticleSystem.prototype - * @type {Matrix4} - * @default Matrix4.IDENTITY - */ - emitterModelMatrix : { - get : function() { - return this._emitterModelMatrix; - }, - set : function(value) { - Check.defined('value', value); - this._matrixDirty = this._matrixDirty || !Matrix4.equals(this._emitterModelMatrix, value); - Matrix4.clone(value, this._emitterModelMatrix); - } - }, - /** - * The color of a particle when it is born. - * @memberof ParticleSystem.prototype - * @type {Color} - * @default Color.WHITE - */ - startColor : { - get : function() { - return this._startColor; - }, - set : function(value) { - Check.defined('value', value); - Color.clone(value, this._startColor); - } - }, - /** - * The color of a particle when it dies. - * @memberof ParticleSystem.prototype - * @type {Color} - * @default Color.WHITE - */ - endColor : { - get : function() { - return this._endColor; - }, - set : function(value) { - Check.defined('value', value); - Color.clone(value, this._endColor); - } - }, - /** - * The scale of the particle when it is born. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - startScale : { - get : function() { - return this._startScale; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._startScale = value; - } - }, - /** - * The scale of the particle when it dies. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - endScale : { - get : function() { - return this._endScale; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._endScale = value; - } - }, - /** - * The number of particles to emit per second. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 5 - */ - rate : { - get : function() { - return this._rate; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._rate = value; - this._updateParticlePool = true; - } - }, - /** - * Sets the minimum speed in meters per second. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - minimumSpeed : { - get : function() { - return this._minimumSpeed; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._minimumSpeed = value; - } - }, - /** - * Sets the maximum speed in meters per second. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - maximumSpeed : { - get : function() { - return this._maximumSpeed; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._maximumSpeed = value; - } - }, - /** - * Sets the minimum life of particles in seconds. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 5.0 - */ - minimumLife : { - get : function() { - return this._minimumLife; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._minimumLife = value; - } - }, - /** - * Sets the maximum life of particles in seconds. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 5.0 - */ - maximumLife : { - get : function() { - return this._maximumLife; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._maximumLife = value; - this._updateParticlePool = true; - } - }, - /** - * Sets the minimum mass of particles in kilograms. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - minimumMass : { - get : function() { - return this._minimumMass; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._minimumMass = value; - } - }, - /** - * Sets the maximum mass of particles in kilograms. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - maximumMass : { - get : function() { - return this._maximumMass; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._maximumMass = value; - } - }, - /** - * Sets the minimum width of particles in pixels. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - minimumWidth : { - get : function() { - return this._minimumWidth; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._minimumWidth = value; - } - }, - /** - * Sets the maximum width of particles in pixels. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - maximumWidth : { - get : function() { - return this._maximumWidth; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._maximumWidth = value; - } - }, - /** - * Sets the minimum height of particles in pixels. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - minimumHeight : { - get : function() { - return this._minimumHeight; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._minimumHeight = value; - } - }, - /** - * Sets the maximum height of particles in pixels. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default 1.0 - */ - maximumHeight : { - get : function() { - return this._maximumHeight; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._maximumHeight = value; - } - }, - /** - * How long the particle system will emit particles, in seconds. - * @memberof ParticleSystem.prototype - * @type {Number} - * @default Number.MAX_VALUE - */ - lifeTime : { - get : function() { - return this._lifeTime; - }, - set : function(value) { - Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); - this._lifeTime = value; - } - }, - /** - * Fires an event when the particle system has reached the end of its lifetime. - * @memberof ParticleSystem.prototype - * @type {Event} - */ - complete : { - get : function() { - return this._complete; - } - }, + defineProperties(Moon.prototype, { /** - * When <code>true</code>, the particle system has reached the end of its lifetime; <code>false</code> otherwise. - * @memberof ParticleSystem.prototype - * @type {Boolean} + * Get the ellipsoid that defines the shape of the moon. + * + * @memberof Moon.prototype + * + * @type {Ellipsoid} + * @readonly + * + * @default {@link Ellipsoid.MOON} */ - isComplete : { + ellipsoid : { get : function() { - return this._isComplete; + return this._ellipsoid; } } }); - function updateParticlePool(system) { - var rate = system._rate; - var life = system._maximumLife; - - var burstAmount = 0; - var bursts = system._bursts; - if (defined(bursts)) { - var length = bursts.length; - for (var i = 0; i < length; ++i) { - burstAmount += bursts[i].maximum; - } - } - - var billboardCollection = system._billboardCollection; - var image = system.image; - - var particleEstimate = Math.ceil(rate * life + burstAmount); - var particles = system._particles; - var particlePool = system._particlePool; - var numToAdd = Math.max(particleEstimate - particles.length - particlePool.length, 0); - - for (var j = 0; j < numToAdd; ++j) { - var particle = new Particle(); - particle._billboard = billboardCollection.add({ - image : image - }); - particlePool.push(particle); - } - - system._particleEstimate = particleEstimate; - } - - function getOrCreateParticle(system) { - // Try to reuse an existing particle from the pool. - var particle = system._particlePool.pop(); - if (!defined(particle)) { - // Create a new one - particle = new Particle(); - } - return particle; - } - - function addParticleToPool(system, particle) { - system._particlePool.push(particle); - } - - function freeParticlePool(system) { - var particles = system._particles; - var particlePool = system._particlePool; - var billboardCollection = system._billboardCollection; - - var numParticles = particles.length; - var numInPool = particlePool.length; - var estimate = system._particleEstimate; - - var start = numInPool - Math.max(estimate - numParticles - numInPool, 0); - for (var i = start; i < numInPool; ++i) { - var p = particlePool[i]; - billboardCollection.remove(p._billboard); - } - particlePool.length = start; - } - - function removeBillboard(particle) { - if (defined(particle._billboard)) { - particle._billboard.show = false; - } - } - - function updateBillboard(system, particle) { - var billboard = particle._billboard; - if (!defined(billboard)) { - billboard = particle._billboard = system._billboardCollection.add({ - image : particle.image - }); - } - billboard.width = particle.size.x; - billboard.height = particle.size.y; - billboard.position = particle.position; - billboard.show = true; - - // Update the color - var r = CesiumMath.lerp(particle.startColor.red, particle.endColor.red, particle.normalizedAge); - var g = CesiumMath.lerp(particle.startColor.green, particle.endColor.green, particle.normalizedAge); - var b = CesiumMath.lerp(particle.startColor.blue, particle.endColor.blue, particle.normalizedAge); - var a = CesiumMath.lerp(particle.startColor.alpha, particle.endColor.alpha, particle.normalizedAge); - billboard.color = new Color(r,g,b,a); - - // Update the scale - var scale = CesiumMath.lerp(particle.startScale, particle.endScale, particle.normalizedAge); - billboard.scale = scale; - } - - function addParticle(system, particle) { - particle.startColor = Color.clone(system._startColor, particle.startColor); - particle.endColor = Color.clone(system._endColor, particle.endColor); - particle.startScale = system._startScale; - particle.endScale = system._endScale; - particle.image = system.image; - particle.life = CesiumMath.randomBetween(system._minimumLife, system._maximumLife); - particle.mass = CesiumMath.randomBetween(system._minimumMass, system._maximumMass); - - var width = CesiumMath.randomBetween(system._minimumWidth, system._maximumWidth); - var height = CesiumMath.randomBetween(system._minimumHeight, system._maximumHeight); - particle.size = Cartesian2.fromElements(width, height, particle.size); - - // Reset the normalizedAge and age in case the particle was reused. - particle._normalizedAge = 0.0; - particle._age = 0.0; - - var speed = CesiumMath.randomBetween(system._minimumSpeed, system._maximumSpeed); - Cartesian3.multiplyByScalar(particle.velocity, speed, particle.velocity); - - system._particles.push(particle); - } - - function calculateNumberToEmit(system, dt) { - // This emitter is finished if it exceeds it's lifetime. - if (system._isComplete) { - return 0; - } - - dt = CesiumMath.mod(dt, system._lifeTime); - - // Compute the number of particles to emit based on the rate. - var v = dt * system._rate; - var numToEmit = Math.floor(v); - system._carryOver += (v - numToEmit); - if (system._carryOver > 1.0) - { - numToEmit++; - system._carryOver -= 1.0; - } - - // Apply any bursts - if (defined(system.bursts)) { - var length = system.bursts.length; - for (var i = 0; i < length; i++) { - var burst = system.bursts[i]; - var currentTime = system._currentTime; - if (defined(burst) && !burst._complete && currentTime > burst.time) { - numToEmit += CesiumMath.randomBetween(burst.minimum, burst.maximum); - burst._complete = true; - } - } - } - - return numToEmit; - } - - var rotatedVelocityScratch = new Cartesian3(); + var icrfToFixed = new Matrix3(); + var rotationScratch = new Matrix3(); + var translationScratch = new Cartesian3(); + var scratchCommandList = []; /** * @private */ - ParticleSystem.prototype.update = function(frameState) { + Moon.prototype.update = function(frameState) { if (!this.show) { return; } - if (!defined(this._billboardCollection)) { - this._billboardCollection = new BillboardCollection(); - } - - if (this._updateParticlePool) { - updateParticlePool(this); - this._updateParticlePool = false; - } - - // Compute the frame time - var dt = 0.0; - if (this._previousTime) { - dt = JulianDate.secondsDifference(frameState.time, this._previousTime); - } - - if (dt < 0.0) { - dt = 0.0; - } - - var particles = this._particles; - var emitter = this._emitter; - var forces = this.forces; - - var i; - var particle; + var ellipsoidPrimitive = this._ellipsoidPrimitive; + ellipsoidPrimitive.material.uniforms.image = this.textureUrl; + ellipsoidPrimitive.onlySunLighting = this.onlySunLighting; - // update particles and remove dead particles - var length = particles.length; - for (i = 0; i < length; ++i) { - particle = particles[i]; - if (!particle.update(dt, forces)) { - removeBillboard(particle); - // Add the particle back to the pool so it can be reused. - addParticleToPool(this, particle); - particles[i] = particles[length - 1]; - --i; - --length; - } else { - updateBillboard(this, particle); - } + var date = frameState.time; + if (!defined(Transforms.computeIcrfToFixedMatrix(date, icrfToFixed))) { + Transforms.computeTemeToPseudoFixedMatrix(date, icrfToFixed); } - particles.length = length; - - var numToEmit = calculateNumberToEmit(this, dt); - - if (numToEmit > 0 && defined(emitter)) { - // Compute the final model matrix by combining the particle systems model matrix and the emitter matrix. - if (this._matrixDirty) { - this._combinedMatrix = Matrix4.multiply(this.modelMatrix, this.emitterModelMatrix, this._combinedMatrix); - this._matrixDirty = false; - } - - var combinedMatrix = this._combinedMatrix; - for (i = 0; i < numToEmit; i++) { - // Create a new particle. - particle = getOrCreateParticle(this); - - // Let the emitter initialize the particle. - this._emitter.emit(particle); - - //For the velocity we need to add it to the original position and then multiply by point. - Cartesian3.add(particle.position, particle.velocity, rotatedVelocityScratch); - Matrix4.multiplyByPoint(combinedMatrix, rotatedVelocityScratch, rotatedVelocityScratch); - - // Change the position to be in world coordinates - particle.position = Matrix4.multiplyByPoint(combinedMatrix, particle.position, particle.position); - - // Orient the velocity in world space as well. - Cartesian3.subtract(rotatedVelocityScratch, particle.position, particle.velocity); - Cartesian3.normalize(particle.velocity, particle.velocity); - - // Add the particle to the system. - addParticle(this, particle); - updateBillboard(this, particle); - } - } + var rotation = this._axes.evaluate(date, rotationScratch); + Matrix3.transpose(rotation, rotation); + Matrix3.multiply(icrfToFixed, rotation, rotation); - this._billboardCollection.update(frameState); - this._previousTime = JulianDate.clone(frameState.time, this._previousTime); - this._currentTime += dt; + var translation = Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(date, translationScratch); + Matrix3.multiplyByVector(icrfToFixed, translation, translation); - if (this._lifeTime !== Number.MAX_VALUE && this._currentTime > this._lifeTime) { - if (this.loop) { - this._currentTime = CesiumMath.mod(this._currentTime, this._lifeTime); - if (this.bursts) { - var burstLength = this.bursts.length; - // Reset any bursts - for (i = 0; i < burstLength; i++) { - this.bursts[i]._complete = false; - } - } - } else { - this._isComplete = true; - this._complete.raiseEvent(this); - } - } + Matrix4.fromRotationTranslation(rotation, translation, ellipsoidPrimitive.modelMatrix); - // free particles in the pool and release billboard GPU memory - if (frameState.frameNumber % 120 === 0) { - freeParticlePool(this); - } + var savedCommandList = frameState.commandList; + frameState.commandList = scratchCommandList; + scratchCommandList.length = 0; + ellipsoidPrimitive.update(frameState); + frameState.commandList = savedCommandList; + return (scratchCommandList.length === 1) ? scratchCommandList[0] : undefined; }; /** @@ -202817,9 +213595,9 @@ define('Scene/ParticleSystem',[ * * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * - * @see ParticleSystem#destroy + * @see Moon#destroy */ - ParticleSystem.prototype.isDestroyed = function() { + Moon.prototype.isDestroyed = function() { return false; }; @@ -202835,1168 +213613,1793 @@ define('Scene/ParticleSystem',[ * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * - * @see ParticleSystem#isDestroyed - */ - ParticleSystem.prototype.destroy = function() { - this._billboardCollection = this._billboardCollection && this._billboardCollection.destroy(); - return destroyObject(this); - }; - - /** - * A function used to apply a force to the particle on each time step. - * @callback ParticleSystem~applyForce - * - * @param {Particle} particle The particle to apply the force to. - * @param {Number} dt The time since the last update. * * @example - * function applyGravity(particle, dt) { - * var position = particle.position; - * var gravityVector = Cesium.Cartesian3.normalize(position, new Cesium.Cartesian3()); - * Cesium.Cartesian3.multiplyByScalar(gravityVector, GRAVITATIONAL_CONSTANT * dt, gravityVector); - * particle.velocity = Cesium.Cartesian3.add(particle.velocity, gravityVector, particle.velocity); - * } + * moon = moon && moon.destroy(); + * + * @see Moon#isDestroyed */ + Moon.prototype.destroy = function() { + this._ellipsoidPrimitive = this._ellipsoidPrimitive && this._ellipsoidPrimitive.destroy(); + return destroyObject(this); + }; - return ParticleSystem; + return Moon; }); -define('Widgets/getElement',[ - '../Core/DeveloperError' - ], function( - DeveloperError) { +define('Scene/NeverTileDiscardPolicy',[], function() { 'use strict'; /** - * If element is a string, look up the element in the DOM by ID. Otherwise return element. + * A {@link TileDiscardPolicy} specifying that tile images should never be discard. * - * @private + * @alias NeverTileDiscardPolicy + * @constructor * - * @exception {DeveloperError} Element with id "id" does not exist in the document. - */ - function getElement(element) { - if (typeof element === 'string') { - var foundElement = document.getElementById(element); - - if (foundElement === null) { - throw new DeveloperError('Element with id "' + element + '" does not exist in the document.'); - } - - element = foundElement; - } - return element; - } - - return getElement; -}); - -define('Scene/PerformanceDisplay',[ - '../Core/defaultValue', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/getTimestamp', - '../Widgets/getElement' - ], function( - defaultValue, - defined, - destroyObject, - DeveloperError, - getTimestamp, - getElement) { - 'use strict'; - - /** - * @private + * @see DiscardMissingTileImagePolicy */ - function PerformanceDisplay(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var container = getElement(options.container); - if (!defined(container)) { - throw new DeveloperError('container is required'); - } - - this._container = container; - - var display = document.createElement('div'); - display.className = 'cesium-performanceDisplay'; - var fpsElement = document.createElement('div'); - fpsElement.className = 'cesium-performanceDisplay-fps'; - this._fpsText = document.createTextNode(''); - fpsElement.appendChild(this._fpsText); - var msElement = document.createElement('div'); - msElement.className = 'cesium-performanceDisplay-ms'; - this._msText = document.createTextNode(''); - msElement.appendChild(this._msText); - display.appendChild(msElement); - display.appendChild(fpsElement); - this._container.appendChild(display); - - this._lastFpsSampleTime = getTimestamp(); - this._lastMsSampleTime = getTimestamp(); - this._fpsFrameCount = 0; - this._msFrameCount = 0; + function NeverTileDiscardPolicy(options) { } /** - * Update the display. This function should only be called once per frame, because - * each call records a frame in the internal buffer and redraws the display. + * Determines if the discard policy is ready to process images. + * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. */ - PerformanceDisplay.prototype.update = function() { - var time = getTimestamp(); - - this._fpsFrameCount++; - var fpsElapsedTime = time - this._lastFpsSampleTime; - if (fpsElapsedTime > 1000) { - var fps = this._fpsFrameCount * 1000 / fpsElapsedTime | 0; - this._fpsText.nodeValue = fps + ' FPS'; - this._lastFpsSampleTime = time; - this._fpsFrameCount = 0; - } - - this._msFrameCount++; - var msElapsedTime = time - this._lastMsSampleTime; - if (msElapsedTime > 200) { - this._msText.nodeValue = (msElapsedTime / this._msFrameCount).toFixed(2) + ' MS'; - this._lastMsSampleTime = time; - this._msFrameCount = 0; - } + NeverTileDiscardPolicy.prototype.isReady = function() { + return true; }; /** - * Destroys the WebGL resources held by this object. + * Given a tile image, decide whether to discard that image. + * + * @param {Image} image An image to test. + * @returns {Boolean} True if the image should be discarded; otherwise, false. */ - PerformanceDisplay.prototype.destroy = function() { - return destroyObject(this); + NeverTileDiscardPolicy.prototype.shouldDiscardImage = function(image) { + return false; }; - return PerformanceDisplay; + return NeverTileDiscardPolicy; }); -define('Scene/PickDepth',[ +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/AdjustTranslucentFS',[],function() { + 'use strict'; + return "#ifdef MRT\n\ +#extension GL_EXT_draw_buffers : enable\n\ +#endif\n\ +uniform vec4 u_bgColor;\n\ +uniform sampler2D u_depthTexture;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +if (texture2D(u_depthTexture, v_textureCoordinates).r < 1.0)\n\ +{\n\ +#ifdef MRT\n\ +gl_FragData[0] = u_bgColor;\n\ +gl_FragData[1] = vec4(u_bgColor.a);\n\ +#else\n\ +gl_FragColor = u_bgColor;\n\ +#endif\n\ +return;\n\ +}\n\ +discard;\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/CompositeOITFS',[],function() { + 'use strict'; + return "uniform sampler2D u_opaque;\n\ +uniform sampler2D u_accumulation;\n\ +uniform sampler2D u_revealage;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +vec4 opaque = texture2D(u_opaque, v_textureCoordinates);\n\ +vec4 accum = texture2D(u_accumulation, v_textureCoordinates);\n\ +float r = texture2D(u_revealage, v_textureCoordinates).r;\n\ +#ifdef MRT\n\ +vec4 transparent = vec4(accum.rgb / clamp(r, 1e-4, 5e4), accum.a);\n\ +#else\n\ +vec4 transparent = vec4(accum.rgb / clamp(accum.a, 1e-4, 5e4), r);\n\ +#endif\n\ +gl_FragColor = (1.0 - transparent.a) * transparent + transparent.a * opaque;\n\ +if (opaque != czm_backgroundColor)\n\ +{\n\ +gl_FragColor.a = 1.0;\n\ +}\n\ +}\n\ +"; +}); +define('Scene/OIT',[ + '../Core/BoundingRectangle', + '../Core/Color', '../Core/defined', '../Core/destroyObject', '../Core/PixelFormat', + '../Core/WebGLConstants', + '../Renderer/ClearCommand', + '../Renderer/DrawCommand', '../Renderer/Framebuffer', '../Renderer/PixelDatatype', '../Renderer/RenderState', - '../Renderer/Texture' + '../Renderer/ShaderSource', + '../Renderer/Texture', + '../Shaders/AdjustTranslucentFS', + '../Shaders/CompositeOITFS', + './BlendEquation', + './BlendFunction' ], function( + BoundingRectangle, + Color, defined, destroyObject, PixelFormat, + WebGLConstants, + ClearCommand, + DrawCommand, Framebuffer, PixelDatatype, RenderState, - Texture) { + ShaderSource, + Texture, + AdjustTranslucentFS, + CompositeOITFS, + BlendEquation, + BlendFunction) { 'use strict'; /** * @private */ - function PickDepth() { - this.framebuffer = undefined; + function OIT(context) { + // We support multipass for the Chrome D3D9 backend and ES 2.0 on mobile. + this._translucentMultipassSupport = false; + this._translucentMRTSupport = false; - this._depthTexture = undefined; - this._textureToCopy = undefined; - this._copyDepthCommand = undefined; + var extensionsSupported = context.floatingPointTexture && context.depthTexture; + this._translucentMRTSupport = context.drawBuffers && extensionsSupported; + this._translucentMultipassSupport = !this._translucentMRTSupport && extensionsSupported; - this._debugPickDepthViewportCommand = undefined; - } + this._opaqueFBO = undefined; + this._opaqueTexture = undefined; + this._depthStencilTexture = undefined; - function executeDebugPickDepth(pickDepth, context, passState) { - if (!defined(pickDepth._debugPickDepthViewportCommand)) { - var fs = - 'uniform sampler2D u_texture;\n' + - 'varying vec2 v_textureCoordinates;\n' + - 'void main()\n' + - '{\n' + - ' float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n' + - ' float n_range = czm_depthRange.near;\n' + - ' float f_range = czm_depthRange.far;\n' + - ' float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n' + - ' float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n' + - ' gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n' + - '}\n'; + this._accumulationTexture = undefined; - pickDepth._debugPickDepthViewportCommand = context.createViewportQuadCommand(fs, { - uniformMap : { - u_texture : function() { - return pickDepth._depthTexture; - } - }, - owner : pickDepth - }); - } + this._translucentFBO = undefined; + this._alphaFBO = undefined; - pickDepth._debugPickDepthViewportCommand.execute(context, passState); + this._adjustTranslucentFBO = undefined; + this._adjustAlphaFBO = undefined; + + this._opaqueClearCommand = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0), + owner : this + }); + this._translucentMRTClearCommand = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 1.0), + owner : this + }); + this._translucentMultipassClearCommand = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0), + owner : this + }); + this._alphaClearCommand = new ClearCommand({ + color : new Color(1.0, 1.0, 1.0, 1.0), + owner : this + }); + + this._translucentRenderStateCache = {}; + this._alphaRenderStateCache = {}; + + this._compositeCommand = undefined; + this._adjustTranslucentCommand = undefined; + this._adjustAlphaCommand = undefined; + + this._viewport = new BoundingRectangle(); + this._rs = undefined; + + this._useScissorTest = false; + this._scissorRectangle = undefined; } - function destroyTextures(pickDepth) { - pickDepth._depthTexture = pickDepth._depthTexture && !pickDepth._depthTexture.isDestroyed() && pickDepth._depthTexture.destroy(); + function destroyTextures(oit) { + oit._accumulationTexture = oit._accumulationTexture && !oit._accumulationTexture.isDestroyed() && oit._accumulationTexture.destroy(); + oit._revealageTexture = oit._revealageTexture && !oit._revealageTexture.isDestroyed() && oit._revealageTexture.destroy(); } - function destroyFramebuffers(pickDepth) { - pickDepth.framebuffer = pickDepth.framebuffer && !pickDepth.framebuffer.isDestroyed() && pickDepth.framebuffer.destroy(); + function destroyFramebuffers(oit) { + oit._translucentFBO = oit._translucentFBO && !oit._translucentFBO.isDestroyed() && oit._translucentFBO.destroy(); + oit._alphaFBO = oit._alphaFBO && !oit._alphaFBO.isDestroyed() && oit._alphaFBO.destroy(); + oit._adjustTranslucentFBO = oit._adjustTranslucentFBO && !oit._adjustTranslucentFBO.isDestroyed() && oit._adjustTranslucentFBO.destroy(); + oit._adjustAlphaFBO = oit._adjustAlphaFBO && !oit._adjustAlphaFBO.isDestroyed() && oit._adjustAlphaFBO.destroy(); } - function createTextures(pickDepth, context, width, height) { - pickDepth._depthTexture = new Texture({ + function destroyResources(oit) { + destroyTextures(oit); + destroyFramebuffers(oit); + } + + function updateTextures(oit, context, width, height) { + destroyTextures(oit); + + // Use zeroed arraybuffer instead of null to initialize texture + // to workaround Firefox 50. https://github.com/AnalyticalGraphicsInc/cesium/pull/4762 + var source = new Float32Array(width * height * 4); + + oit._accumulationTexture = new Texture({ context : context, - width : width, - height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE + pixelDatatype : PixelDatatype.FLOAT, + source : { + arrayBufferView : source, + width : width, + height : height + } + }); + oit._revealageTexture = new Texture({ + context : context, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.FLOAT, + source : { + arrayBufferView : source, + width : width, + height : height + } }); } - function createFramebuffers(pickDepth, context, width, height) { - destroyTextures(pickDepth); - destroyFramebuffers(pickDepth); + function updateFramebuffers(oit, context) { + destroyFramebuffers(oit); - createTextures(pickDepth, context, width, height); + var completeFBO = WebGLConstants.FRAMEBUFFER_COMPLETE; + var supported = true; - pickDepth.framebuffer = new Framebuffer({ - context : context, - colorTextures : [pickDepth._depthTexture], - destroyAttachments : false - }); + // if MRT is supported, attempt to make an FBO with multiple color attachments + if (oit._translucentMRTSupport) { + oit._translucentFBO = new Framebuffer({ + context : context, + colorTextures : [oit._accumulationTexture, oit._revealageTexture], + depthStencilTexture : oit._depthStencilTexture, + destroyAttachments : false + }); + oit._adjustTranslucentFBO = new Framebuffer({ + context : context, + colorTextures : [oit._accumulationTexture, oit._revealageTexture], + destroyAttachments : false + }); + + if (oit._translucentFBO.status !== completeFBO || oit._adjustTranslucentFBO.status !== completeFBO) { + destroyFramebuffers(oit); + oit._translucentMRTSupport = false; + } + } + + // either MRT isn't supported or FBO creation failed, attempt multipass + if (!oit._translucentMRTSupport) { + oit._translucentFBO = new Framebuffer({ + context : context, + colorTextures : [oit._accumulationTexture], + depthStencilTexture : oit._depthStencilTexture, + destroyAttachments : false + }); + oit._alphaFBO = new Framebuffer({ + context : context, + colorTextures : [oit._revealageTexture], + depthStencilTexture : oit._depthStencilTexture, + destroyAttachments : false + }); + oit._adjustTranslucentFBO = new Framebuffer({ + context : context, + colorTextures : [oit._accumulationTexture], + destroyAttachments : false + }); + oit._adjustAlphaFBO = new Framebuffer({ + context : context, + colorTextures : [oit._revealageTexture], + destroyAttachments : false + }); + + var translucentComplete = oit._translucentFBO.status === completeFBO; + var alphaComplete = oit._alphaFBO.status === completeFBO; + var adjustTranslucentComplete = oit._adjustTranslucentFBO.status === completeFBO; + var adjustAlphaComplete = oit._adjustAlphaFBO.status === completeFBO; + if (!translucentComplete || !alphaComplete || !adjustTranslucentComplete || !adjustAlphaComplete) { + destroyResources(oit); + oit._translucentMultipassSupport = false; + supported = false; + } + } + + return supported; } - function updateFramebuffers(pickDepth, context, depthTexture) { - var width = depthTexture.width; - var height = depthTexture.height; + OIT.prototype.update = function(context, passState, framebuffer) { + if (!this.isSupported()) { + return; + } - var texture = pickDepth._depthTexture; - var textureChanged = !defined(texture) || texture.width !== width || texture.height !== height; - if (!defined(pickDepth.framebuffer) || textureChanged) { - createFramebuffers(pickDepth, context, width, height); + this._opaqueFBO = framebuffer; + this._opaqueTexture = framebuffer.getColorTexture(0); + this._depthStencilTexture = framebuffer.depthStencilTexture; + + var width = this._opaqueTexture.width; + var height = this._opaqueTexture.height; + + var accumulationTexture = this._accumulationTexture; + var textureChanged = !defined(accumulationTexture) || accumulationTexture.width !== width || accumulationTexture.height !== height; + if (textureChanged) { + updateTextures(this, context, width, height); + } + + if (!defined(this._translucentFBO) || textureChanged) { + if (!updateFramebuffers(this, context)) { + // framebuffer creation failed + return; + } + } + + var that = this; + var fs; + var uniformMap; + + if (!defined(this._compositeCommand)) { + fs = new ShaderSource({ + sources : [CompositeOITFS] + }); + if (this._translucentMRTSupport) { + fs.defines.push('MRT'); + } + + uniformMap = { + u_opaque : function() { + return that._opaqueTexture; + }, + u_accumulation : function() { + return that._accumulationTexture; + }, + u_revealage : function() { + return that._revealageTexture; + } + }; + this._compositeCommand = context.createViewportQuadCommand(fs, { + uniformMap : uniformMap, + owner : this + }); + } + + if (!defined(this._adjustTranslucentCommand)) { + if (this._translucentMRTSupport) { + fs = new ShaderSource({ + defines : ['MRT'], + sources : [AdjustTranslucentFS] + }); + + uniformMap = { + u_bgColor : function() { + return that._translucentMRTClearCommand.color; + }, + u_depthTexture : function() { + return that._depthStencilTexture; + } + }; + + this._adjustTranslucentCommand = context.createViewportQuadCommand(fs, { + uniformMap : uniformMap, + owner : this + }); + } else if (this._translucentMultipassSupport) { + fs = new ShaderSource({ + sources : [AdjustTranslucentFS] + }); + + uniformMap = { + u_bgColor : function() { + return that._translucentMultipassClearCommand.color; + }, + u_depthTexture : function() { + return that._depthStencilTexture; + } + }; + + this._adjustTranslucentCommand = context.createViewportQuadCommand(fs, { + uniformMap : uniformMap, + owner : this + }); + + uniformMap = { + u_bgColor : function() { + return that._alphaClearCommand.color; + }, + u_depthTexture : function() { + return that._depthStencilTexture; + } + }; + + this._adjustAlphaCommand = context.createViewportQuadCommand(fs, { + uniformMap : uniformMap, + owner : this + }); + } + } + + this._viewport.width = width; + this._viewport.height = height; + + var useScissorTest = !BoundingRectangle.equals(this._viewport, passState.viewport); + var updateScissor = useScissorTest !== this._useScissorTest; + this._useScissorTest = useScissorTest; + + if (!BoundingRectangle.equals(this._scissorRectangle, passState.viewport)) { + this._scissorRectangle = BoundingRectangle.clone(passState.viewport, this._scissorRectangle); + updateScissor = true; + } + + if (!defined(this._rs) || !BoundingRectangle.equals(this._viewport, this._rs.viewport) || updateScissor) { + this._rs = RenderState.fromCache({ + viewport : this._viewport, + scissorTest : { + enabled : this._useScissorTest, + rectangle : this._scissorRectangle + } + }); + } + + if (defined(this._compositeCommand)) { + this._compositeCommand.renderState = this._rs; + } + + if (this._adjustTranslucentCommand) { + this._adjustTranslucentCommand.renderState = this._rs; + } + + if (defined(this._adjustAlphaCommand)) { + this._adjustAlphaCommand.renderState = this._rs; + } + }; + + var translucentMRTBlend = { + enabled : true, + color : new Color(0.0, 0.0, 0.0, 0.0), + equationRgb : BlendEquation.ADD, + equationAlpha : BlendEquation.ADD, + functionSourceRgb : BlendFunction.ONE, + functionDestinationRgb : BlendFunction.ONE, + functionSourceAlpha : BlendFunction.ZERO, + functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA + }; + + var translucentColorBlend = { + enabled : true, + color : new Color(0.0, 0.0, 0.0, 0.0), + equationRgb : BlendEquation.ADD, + equationAlpha : BlendEquation.ADD, + functionSourceRgb : BlendFunction.ONE, + functionDestinationRgb : BlendFunction.ONE, + functionSourceAlpha : BlendFunction.ONE, + functionDestinationAlpha : BlendFunction.ONE + }; + + var translucentAlphaBlend = { + enabled : true, + color : new Color(0.0, 0.0, 0.0, 0.0), + equationRgb : BlendEquation.ADD, + equationAlpha : BlendEquation.ADD, + functionSourceRgb : BlendFunction.ZERO, + functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA, + functionSourceAlpha : BlendFunction.ZERO, + functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA + }; + + function getTranslucentRenderState(context, translucentBlending, cache, renderState) { + var translucentState = cache[renderState.id]; + if (!defined(translucentState)) { + var rs = RenderState.getState(renderState); + rs.depthMask = false; + rs.blending = translucentBlending; + + translucentState = RenderState.fromCache(rs); + cache[renderState.id] = translucentState; } + + return translucentState; } - function updateCopyCommands(pickDepth, context, depthTexture) { - if (!defined(pickDepth._copyDepthCommand)) { - var fs = - 'uniform sampler2D u_texture;\n' + - 'varying vec2 v_textureCoordinates;\n' + + function getTranslucentMRTRenderState(oit, context, renderState) { + return getTranslucentRenderState(context, translucentMRTBlend, oit._translucentRenderStateCache, renderState); + } + + function getTranslucentColorRenderState(oit, context, renderState) { + return getTranslucentRenderState(context, translucentColorBlend, oit._translucentRenderStateCache, renderState); + } + + function getTranslucentAlphaRenderState(oit, context, renderState) { + return getTranslucentRenderState(context, translucentAlphaBlend, oit._alphaRenderStateCache, renderState); + } + + var mrtShaderSource = + ' vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n' + + ' float ai = czm_gl_FragColor.a;\n' + + ' float wzi = czm_alphaWeight(ai);\n' + + ' gl_FragData[0] = vec4(Ci * wzi, ai);\n' + + ' gl_FragData[1] = vec4(ai * wzi);\n'; + + var colorShaderSource = + ' vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n' + + ' float ai = czm_gl_FragColor.a;\n' + + ' float wzi = czm_alphaWeight(ai);\n' + + ' gl_FragColor = vec4(Ci, ai) * wzi;\n'; + + var alphaShaderSource = + ' float ai = czm_gl_FragColor.a;\n' + + ' gl_FragColor = vec4(ai);\n'; + + function getTranslucentShaderProgram(context, shaderProgram, keyword, source) { + var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword); + if (!defined(shader)) { + var attributeLocations = shaderProgram._attributeLocations; + + var fs = shaderProgram.fragmentShaderSource.clone(); + + fs.sources = fs.sources.map(function(source) { + source = ShaderSource.replaceMain(source, 'czm_translucent_main'); + source = source.replace(/gl_FragColor/g, 'czm_gl_FragColor'); + source = source.replace(/\bdiscard\b/g, 'czm_discard = true'); + source = source.replace(/czm_phong/g, 'czm_translucentPhong'); + return source; + }); + + // Discarding the fragment in main is a workaround for ANGLE D3D9 + // shader compilation errors. + + fs.sources.splice(0, 0, + (source.indexOf('gl_FragData') !== -1 ? '#extension GL_EXT_draw_buffers : enable \n' : '') + + 'vec4 czm_gl_FragColor;\n' + + 'bool czm_discard = false;\n'); + + fs.sources.push( 'void main()\n' + '{\n' + - ' gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n' + - '}\n'; - pickDepth._copyDepthCommand = context.createViewportQuadCommand(fs, { - renderState : RenderState.fromCache(), - uniformMap : { - u_texture : function() { - return pickDepth._textureToCopy; - } - }, - owner : pickDepth + ' czm_translucent_main();\n' + + ' if (czm_discard)\n' + + ' {\n' + + ' discard;\n' + + ' }\n' + + source + + '}\n'); + + shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, { + vertexShaderSource : shaderProgram.vertexShaderSource, + fragmentShaderSource : fs, + attributeLocations : attributeLocations }); } - pickDepth._textureToCopy = depthTexture; - pickDepth._copyDepthCommand.framebuffer = pickDepth.framebuffer; + return shader; } - PickDepth.prototype.executeDebugPickDepth = function(context, passState) { - executeDebugPickDepth(this, context, passState); + function getTranslucentMRTShaderProgram(context, shaderProgram) { + return getTranslucentShaderProgram(context, shaderProgram, 'translucentMRT', mrtShaderSource); + } + + function getTranslucentColorShaderProgram(context, shaderProgram) { + return getTranslucentShaderProgram(context, shaderProgram, 'translucentMultipass', colorShaderSource); + } + + function getTranslucentAlphaShaderProgram(context, shaderProgram) { + return getTranslucentShaderProgram(context, shaderProgram, 'alphaMultipass', alphaShaderSource); + } + + OIT.prototype.createDerivedCommands = function(command, context, result) { + if (!defined(result)) { + result = {}; + } + + if (this._translucentMRTSupport) { + var translucentShader; + var translucentRenderState; + if (defined(result.translucentCommand)) { + translucentShader = result.translucentCommand.shaderProgram; + translucentRenderState = result.translucentCommand.renderState; + } + + result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand); + + if (!defined(translucentShader) || result.shaderProgramId !== command.shaderProgram.id) { + result.translucentCommand.shaderProgram = getTranslucentMRTShaderProgram(context, command.shaderProgram); + result.translucentCommand.renderState = getTranslucentMRTRenderState(this, context, command.renderState); + result.shaderProgramId = command.shaderProgram.id; + } else { + result.translucentCommand.shaderProgram = translucentShader; + result.translucentCommand.renderState = translucentRenderState; + } + } else { + var colorShader; + var colorRenderState; + var alphaShader; + var alphaRenderState; + if (defined(result.translucentCommand)) { + colorShader = result.translucentCommand.shaderProgram; + colorRenderState = result.translucentCommand.renderState; + alphaShader = result.alphaCommand.shaderProgram; + alphaRenderState = result.alphaCommand.renderState; + } + + result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand); + result.alphaCommand = DrawCommand.shallowClone(command, result.alphaCommand); + + if (!defined(colorShader) || result.shaderProgramId !== command.shaderProgram.id) { + result.translucentCommand.shaderProgram = getTranslucentColorShaderProgram(context, command.shaderProgram); + result.translucentCommand.renderState = getTranslucentColorRenderState(this, context, command.renderState); + result.alphaCommand.shaderProgram = getTranslucentAlphaShaderProgram(context, command.shaderProgram); + result.alphaCommand.renderState = getTranslucentAlphaRenderState(this, context, command.renderState); + result.shaderProgramId = command.shaderProgram.id; + } else { + result.translucentCommand.shaderProgram = colorShader; + result.translucentCommand.renderState = colorRenderState; + result.alphaCommand.shaderProgram = alphaShader; + result.alphaCommand.renderState = alphaRenderState; + } + } + + return result; }; - PickDepth.prototype.update = function(context, depthTexture) { - updateFramebuffers(this, context, depthTexture); - updateCopyCommands(this, context, depthTexture); + function executeTranslucentCommandsSortedMultipass(oit, scene, executeFunction, passState, commands, invertClassification) { + var command; + var derivedCommand; + var j; + + var context = scene.context; + var framebuffer = passState.framebuffer; + var length = commands.length; + + var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; + + passState.framebuffer = oit._adjustTranslucentFBO; + oit._adjustTranslucentCommand.execute(context, passState); + passState.framebuffer = oit._adjustAlphaFBO; + oit._adjustAlphaCommand.execute(context, passState); + + var debugFramebuffer = oit._opaqueFBO; + passState.framebuffer = oit._translucentFBO; + + for (j = 0; j < length; ++j) { + command = commands[j]; + derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + } + + if (defined(invertClassification)) { + command = invertClassification.unclassifiedCommand; + derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + } + + passState.framebuffer = oit._alphaFBO; + + for (j = 0; j < length; ++j) { + command = commands[j]; + derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; + executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + } + + if (defined(invertClassification)) { + command = invertClassification.unclassifiedCommand; + derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; + executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + } + + passState.framebuffer = framebuffer; + } + + function executeTranslucentCommandsSortedMRT(oit, scene, executeFunction, passState, commands, invertClassification) { + var context = scene.context; + var framebuffer = passState.framebuffer; + var length = commands.length; + + var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; + + passState.framebuffer = oit._adjustTranslucentFBO; + oit._adjustTranslucentCommand.execute(context, passState); + + var debugFramebuffer = oit._opaqueFBO; + passState.framebuffer = oit._translucentFBO; + + var command; + var derivedCommand; + + for (var j = 0; j < length; ++j) { + command = commands[j]; + derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + } + + if (defined(invertClassification)) { + command = invertClassification.unclassifiedCommand; + derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); + } + + passState.framebuffer = framebuffer; + } + + OIT.prototype.executeCommands = function(scene, executeFunction, passState, commands, invertClassification) { + if (this._translucentMRTSupport) { + executeTranslucentCommandsSortedMRT(this, scene, executeFunction, passState, commands, invertClassification); + return; + } + + executeTranslucentCommandsSortedMultipass(this, scene, executeFunction, passState, commands, invertClassification); }; - PickDepth.prototype.executeCopyDepth = function(context, passState) { - this._copyDepthCommand.execute(context, passState); + OIT.prototype.execute = function(context, passState) { + this._compositeCommand.execute(context, passState); }; - PickDepth.prototype.isDestroyed = function() { + OIT.prototype.clear = function(context, passState, clearColor) { + var framebuffer = passState.framebuffer; + + passState.framebuffer = this._opaqueFBO; + Color.clone(clearColor, this._opaqueClearCommand.color); + this._opaqueClearCommand.execute(context, passState); + + passState.framebuffer = this._translucentFBO; + var translucentClearCommand = this._translucentMRTSupport ? this._translucentMRTClearCommand : this._translucentMultipassClearCommand; + translucentClearCommand.execute(context, passState); + + if (this._translucentMultipassSupport) { + passState.framebuffer = this._alphaFBO; + this._alphaClearCommand.execute(context, passState); + } + + passState.framebuffer = framebuffer; + }; + + OIT.prototype.isSupported = function() { + return this._translucentMRTSupport || this._translucentMultipassSupport; + }; + + OIT.prototype.isDestroyed = function() { return false; }; - PickDepth.prototype.destroy = function() { - destroyTextures(this); - destroyFramebuffers(this); + OIT.prototype.destroy = function() { + destroyResources(this); - this._copyDepthCommand.shaderProgram = defined(this._copyDepthCommand.shaderProgram) && this._copyDepthCommand.shaderProgram.destroy(); + if (defined(this._compositeCommand)) { + this._compositeCommand.shaderProgram = this._compositeCommand.shaderProgram && this._compositeCommand.shaderProgram.destroy(); + } + + if (defined(this._adjustTranslucentCommand)) { + this._adjustTranslucentCommand.shaderProgram = this._adjustTranslucentCommand.shaderProgram && this._adjustTranslucentCommand.shaderProgram.destroy(); + } + + if (defined(this._adjustAlphaCommand)) { + this._adjustAlphaCommand.shaderProgram = this._adjustAlphaCommand.shaderProgram && this._adjustAlphaCommand.shaderProgram.destroy(); + } return destroyObject(this); }; - return PickDepth; + return OIT; }); -define('Scene/PrimitiveCollection',[ - '../Core/createGuid', +define('Scene/Particle',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Color', '../Core/defaultValue', '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError' + '../Core/defineProperties' ], function( - createGuid, + Cartesian2, + Cartesian3, + Color, defaultValue, defined, - defineProperties, - destroyObject, - DeveloperError) { + defineProperties) { 'use strict'; + var defaultSize = new Cartesian2(1.0, 1.0); + /** - * A collection of primitives. This is most often used with {@link Scene#primitives}, - * but <code>PrimitiveCollection</code> is also a primitive itself so collections can - * be added to collections forming a hierarchy. + * A particle emitted by a {@link ParticleSystem}. * - * @alias PrimitiveCollection + * @alias Particle * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Determines if the primitives in the collection will be shown. - * @param {Boolean} [options.destroyPrimitives=true] Determines if primitives in the collection are destroyed when they are removed. - * - * @example - * var billboards = new Cesium.BillboardCollection(); - * var labels = new Cesium.LabelCollection(); - * - * var collection = new Cesium.PrimitiveCollection(); - * collection.add(billboards); - * - * scene.primitives.add(collection); // Add collection - * scene.primitives.add(labels); // Add regular primitive + * @param {Object} options An object with the following properties: + * @param {Number} [options.mass=1.0] The mass of particles in kilograms. + * @param {Cartesian3} [options.position=Cartesian3.ZERO] The initial position of the particle in world coordinates. + * @param {Cartesian3} [options.velocity=Cartesian3.ZERO] The velocity vector of the particle in world coordinates. + * @param {Number} [options.life=Number.MAX_VALUE] The life of particles in seconds. + * @param {Object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. + * @param {Color} [options.startColor=Color.WHITE] The color of a particle when it is born. + * @param {Color} [options.endColor=Color.WHITE] The color of a particle when it dies. + * @param {Number} [options.startScale=1.0] The scale of the particle when it is born. + * @param {Number} [options.endScale=1.0] The scale of the particle when it dies. + * @param {Cartesian2} [options.size=new Cartesian2(1.0, 1.0)] The dimensions of particles in pixels. */ - function PrimitiveCollection(options) { + function Particle(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._primitives = []; - this._guid = createGuid(); - /** - * Determines if primitives in this collection will be shown. - * - * @type {Boolean} - * @default true + * The mass of the particle in kilograms. + * @type {Number} + * @default 1.0 */ - this.show = defaultValue(options.show, true); - + this.mass = defaultValue(options.mass, 1.0); /** - * Determines if primitives in the collection are destroyed when they are removed by - * {@link PrimitiveCollection#destroy} or {@link PrimitiveCollection#remove} or implicitly - * by {@link PrimitiveCollection#removeAll}. - * - * @type {Boolean} - * @default true - * - * @example - * // Example 1. Primitives are destroyed by default. - * var primitives = new Cesium.PrimitiveCollection(); - * var labels = primitives.add(new Cesium.LabelCollection()); - * primitives = primitives.destroy(); - * var b = labels.isDestroyed(); // true - * - * @example - * // Example 2. Do not destroy primitives in a collection. - * var primitives = new Cesium.PrimitiveCollection(); - * primitives.destroyPrimitives = false; - * var labels = primitives.add(new Cesium.LabelCollection()); - * primitives = primitives.destroy(); - * var b = labels.isDestroyed(); // false - * labels = labels.destroy(); // explicitly destroy + * The positon of the particle in world coordinates. + * @type {Cartesian3} + * @default Cartesian3.ZERO */ - this.destroyPrimitives = defaultValue(options.destroyPrimitives, true); + this.position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); + /** + * The velocity of the particle in world coordinates. + * @type {Cartesian3} + * @default Cartesian3.ZERO + */ + this.velocity = Cartesian3.clone(defaultValue(options.velocity, Cartesian3.ZERO)); + /** + * The life of the particle in seconds. + * @type {Number} + * @default Number.MAX_VALUE + */ + this.life = defaultValue(options.life, Number.MAX_VALUE); + /** + * The image to use for the particle. + * @type {Object} + * @default undefined + */ + this.image = options.image; + /** + * The color of the particle when it is born. + * @type {Color} + * @default Color.WHITE + */ + this.startColor = Color.clone(defaultValue(options.startColor, Color.WHITE)); + /** + * The color of the particle when it dies. + * @type {Color} + * @default Color.WHITE + */ + this.endColor = Color.clone(defaultValue(options.endColor, Color.WHITE)); + /** + * the scale of the particle when it is born. + * @type {Number} + * @default 1.0 + */ + this.startScale = defaultValue(options.startScale, 1.0); + /** + * The scale of the particle when it dies. + * @type {Number} + * @default 1.0 + */ + this.endScale = defaultValue(options.endScale, 1.0); + /** + * The dimensions of the particle in pixels. + * @type {Cartesian2} + * @default new Cartesian(1.0, 1.0) + */ + this.size = Cartesian2.clone(defaultValue(options.size, defaultSize)); + + this._age = 0.0; + this._normalizedAge = 0.0; + + // used by ParticleSystem + this._billboard = undefined; } - defineProperties(PrimitiveCollection.prototype, { + defineProperties(Particle.prototype, { /** - * Gets the number of primitives in the collection. - * - * @memberof PrimitiveCollection.prototype - * + * Gets the age of the particle in seconds. + * @memberof Particle.prototype * @type {Number} - * @readonly */ - length : { + age : { get : function() { - return this._primitives.length; + return this._age; + } + }, + /** + * Gets the age normalized to a value in the range [0.0, 1.0]. + * @memberof Particle.prototype + * @type {Number} + */ + normalizedAge : { + get : function() { + return this._normalizedAge; } } }); - /** - * Adds a primitive to the collection. - * - * @param {Object} primitive The primitive to add. - * @returns {Object} The primitive added to the collection. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @example - * var billboards = scene.primitives.add(new Cesium.BillboardCollection()); - */ - PrimitiveCollection.prototype.add = function(primitive) { - if (!defined(primitive)) { - throw new DeveloperError('primitive is required.'); - } - - var external = (primitive._external = primitive._external || {}); - var composites = (external._composites = external._composites || {}); - composites[this._guid] = { - collection : this - }; - - this._primitives.push(primitive); - - return primitive; - }; + var deltaScratch = new Cartesian3(); /** - * Removes a primitive from the collection. - * - * @param {Object} [primitive] The primitive to remove. - * @returns {Boolean} <code>true</code> if the primitive was removed; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * var billboards = scene.primitives.add(new Cesium.BillboardCollection()); - * scene.primitives.remove(p); // Returns true - * - * @see PrimitiveCollection#destroyPrimitives + * @private */ - PrimitiveCollection.prototype.remove = function(primitive) { - // PERFORMANCE_IDEA: We can obviously make this a lot faster. - if (this.contains(primitive)) { - var index = this._primitives.indexOf(primitive); - if (index !== -1) { - this._primitives.splice(index, 1); - - delete primitive._external._composites[this._guid]; + Particle.prototype.update = function(dt, forces) { + // Apply the velocity + Cartesian3.multiplyByScalar(this.velocity, dt, deltaScratch); + Cartesian3.add(this.position, deltaScratch, this.position); - if (this.destroyPrimitives) { - primitive.destroy(); + // Update any forces. + if (defined(forces)) { + var length = forces.length; + for (var i = 0; i < length; ++i) { + var force = forces[i]; + if (typeof force === 'function') { + // Force is just a simple callback function. + force(this, dt); } - - return true; } - // else ... this is not possible, I swear. } - return false; - }; + // Age the particle + this._age += dt; - /** - * Removes and destroys a primitive, regardless of destroyPrimitives setting. - * @private - */ - PrimitiveCollection.prototype.removeAndDestroy = function(primitive) { - var removed = this.remove(primitive); - if (removed && !this.destroyPrimitives) { - primitive.destroy(); + // Compute the normalized age. + if (this.life === Number.MAX_VALUE) { + this._normalizedAge = 0.0; + } else { + this._normalizedAge = this._age / this.life; } - return removed; - }; - /** - * Removes all primitives in the collection. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see PrimitiveCollection#destroyPrimitives - */ - PrimitiveCollection.prototype.removeAll = function() { - if (this.destroyPrimitives) { - var primitives = this._primitives; - var length = primitives.length; - for ( var i = 0; i < length; ++i) { - primitives[i].destroy(); - } - } - this._primitives = []; + // If this particle is older than it's lifespan then die. + return this._age <= this.life; }; - /** - * Determines if this collection contains a primitive. - * - * @param {Object} [primitive] The primitive to check for. - * @returns {Boolean} <code>true</code> if the primitive is in the collection; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see PrimitiveCollection#get - */ - PrimitiveCollection.prototype.contains = function(primitive) { - return !!(defined(primitive) && - primitive._external && - primitive._external._composites && - primitive._external._composites[this._guid]); - }; + return Particle; +}); - function getPrimitiveIndex(compositePrimitive, primitive) { - if (!compositePrimitive.contains(primitive)) { - throw new DeveloperError('primitive is not in this collection.'); - } - - return compositePrimitive._primitives.indexOf(primitive); - } +define('Scene/ParticleBurst',[ + '../Core/defaultValue', + '../Core/defineProperties' + ], function( + defaultValue, + defineProperties) { + 'use strict'; /** - * Raises a primitive "up one" in the collection. If all primitives in the collection are drawn - * on the globe surface, this visually moves the primitive up one. - * - * @param {Object} [primitive] The primitive to raise. + * Represents a burst of {@link Particle}s from a {@link ParticleSystem} at a given time in the systems lifetime. * - * @exception {DeveloperError} primitive is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * @alias ParticleBurst + * @constructor * - * @see PrimitiveCollection#raiseToTop - * @see PrimitiveCollection#lower - * @see PrimitiveCollection#lowerToBottom + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.time=0.0] The time in seconds after the beginning of the particle system's lifetime that the burst will occur. + * @param {Number} [options.minimum=0.0] The minimum number of particles emmitted in the burst. + * @param {Number} [options.maximum=50.0] The maximum number of particles emitted in the burst. */ - PrimitiveCollection.prototype.raise = function(primitive) { - if (defined(primitive)) { - var index = getPrimitiveIndex(this, primitive); - var primitives = this._primitives; + function ParticleBurst(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (index !== primitives.length - 1) { - var p = primitives[index]; - primitives[index] = primitives[index + 1]; - primitives[index + 1] = p; - } - } - }; + /** + * The time in seconds after the eginning of the particle system's lifetime that the burst will occur. + * @type {Number} + * @default 0.0 + */ + this.time = defaultValue(options.time, 0.0); + /** + * The minimum number of particles emitted. + * @type {Number} + * @default 0.0 + */ + this.minimum = defaultValue(options.minimum, 0.0); + /** + * The maximum number of particles emitted. + * @type {Number} + * @default 50.0 + */ + this.maximum = defaultValue(options.maximum, 50.0); - /** - * Raises a primitive to the "top" of the collection. If all primitives in the collection are drawn - * on the globe surface, this visually moves the primitive to the top. - * - * @param {Object} [primitive] The primitive to raise the top. - * - * @exception {DeveloperError} primitive is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see PrimitiveCollection#raise - * @see PrimitiveCollection#lower - * @see PrimitiveCollection#lowerToBottom - */ - PrimitiveCollection.prototype.raiseToTop = function(primitive) { - if (defined(primitive)) { - var index = getPrimitiveIndex(this, primitive); - var primitives = this._primitives; + this._complete = false; + } - if (index !== primitives.length - 1) { - // PERFORMANCE_IDEA: Could be faster - primitives.splice(index, 1); - primitives.push(primitive); + defineProperties(ParticleBurst.prototype, { + /** + * <code>true</code> if the burst has been completed; <code>false</code> otherwise. + * @memberof ParticleBurst.prototype + * @type {Boolean} + */ + complete : { + get : function() { + return this._complete; } } - }; + }); - /** - * Lowers a primitive "down one" in the collection. If all primitives in the collection are drawn - * on the globe surface, this visually moves the primitive down one. - * - * @param {Object} [primitive] The primitive to lower. - * - * @exception {DeveloperError} primitive is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see PrimitiveCollection#lowerToBottom - * @see PrimitiveCollection#raise - * @see PrimitiveCollection#raiseToTop - */ - PrimitiveCollection.prototype.lower = function(primitive) { - if (defined(primitive)) { - var index = getPrimitiveIndex(this, primitive); - var primitives = this._primitives; + return ParticleBurst; +}); - if (index !== 0) { - var p = primitives[index]; - primitives[index] = primitives[index - 1]; - primitives[index - 1] = p; - } - } - }; +define('Scene/ParticleEmitter',[ + '../Core/DeveloperError' +], function(DeveloperError) { + 'use strict'; /** - * Lowers a primitive to the "bottom" of the collection. If all primitives in the collection are drawn - * on the globe surface, this visually moves the primitive to the bottom. - * - * @param {Object} [primitive] The primitive to lower to the bottom. + * <p> + * An object that initializes a {@link Particle} from a {@link ParticleSystem}. + * </p> + * <p> + * This type describes an interface and is not intended to be instantiated directly. + * </p> * - * @exception {DeveloperError} primitive is not in this collection. - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * @alias ParticleEmitter + * @constructor * - * @see PrimitiveCollection#lower - * @see PrimitiveCollection#raise - * @see PrimitiveCollection#raiseToTop + * @see BoxEmitter + * @see CircleEmitter + * @see ConeEmitter + * @see SphereEmitter */ - PrimitiveCollection.prototype.lowerToBottom = function(primitive) { - if (defined(primitive)) { - var index = getPrimitiveIndex(this, primitive); - var primitives = this._primitives; - - if (index !== 0) { - // PERFORMANCE_IDEA: Could be faster - primitives.splice(index, 1); - primitives.unshift(primitive); + function ParticleEmitter(options) { + throw new DeveloperError('This type should not be instantiated directly. Instead, use BoxEmitter, CircleEmitter, ConeEmitter or SphereEmitter.'); } - } - }; /** - * Returns the primitive in the collection at the specified index. - * - * @param {Number} index The zero-based index of the primitive to return. - * @returns {Object} The primitive at the <code>index</code>. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * // Toggle the show property of every primitive in the collection. - * var primitives = scene.primitives; - * var length = primitives.length; - * for (var i = 0; i < length; ++i) { - * var p = primitives.get(i); - * p.show = !p.show; - * } + * Initializes the given {Particle} by setting it's position and velocity. * - * @see PrimitiveCollection#length - */ - PrimitiveCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - return this._primitives[index]; - }; - - /** * @private + * @param {Particle} The particle to initialize */ - PrimitiveCollection.prototype.update = function(frameState) { - if (!this.show) { - return; - } - - var primitives = this._primitives; - // Using primitives.length in the loop is a temporary workaround - // to allow quadtree updates to add and remove primitives in - // update(). This will be changed to manage added and removed lists. - for (var i = 0; i < primitives.length; ++i) { - primitives[i].update(frameState); - } - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see PrimitiveCollection#destroy - */ - PrimitiveCollection.prototype.isDestroyed = function() { - return false; - }; - - /** - * Destroys the WebGL resources held by each primitive in this collection. Explicitly destroying this - * collection allows for deterministic release of WebGL resources, instead of relying on the garbage - * collector to destroy this collection. - * <br /><br /> - * Since destroying a collection destroys all the contained primitives, only destroy a collection - * when you are sure no other code is still using any of the contained primitives. - * <br /><br /> - * Once this collection is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * primitives = primitives && primitives.destroy(); - * - * @see PrimitiveCollection#isDestroyed - */ - PrimitiveCollection.prototype.destroy = function() { - this.removeAll(); - return destroyObject(this); + ParticleEmitter.prototype.emit = function(particle) { + DeveloperError.throwInstantiationError(); }; - return PrimitiveCollection; + return ParticleEmitter; }); -define('Scene/QuadtreeTileProvider',[ +define('Scene/ParticleSystem',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Check', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', '../Core/defineProperties', - '../Core/DeveloperError' + '../Core/destroyObject', + '../Core/Event', + '../Core/JulianDate', + '../Core/Math', + '../Core/Matrix4', + './BillboardCollection', + './CircleEmitter', + './Particle' ], function( + Cartesian2, + Cartesian3, + Check, + Color, + defaultValue, + defined, defineProperties, - DeveloperError) { + destroyObject, + Event, + JulianDate, + CesiumMath, + Matrix4, + BillboardCollection, + CircleEmitter, + Particle) { 'use strict'; /** - * Provides general quadtree tiles to be displayed on or near the surface of an ellipsoid. It is intended to be - * used with the {@link QuadtreePrimitive}. This type describes an interface and is not intended to be - * instantiated directly. + * A ParticleSystem manages the updating and display of a collection of particles. * - * @alias QuadtreeTileProvider + * @alias ParticleSystem * @constructor - * @private - */ - function QuadtreeTileProvider() { - DeveloperError.throwInstantiationError(); - } - - /** - * Computes the default geometric error for level zero of the quadtree. * - * @memberof QuadtreeTileProvider + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.show=true] Whether to display the particle system. + * @param {ParticleSystem~applyForce[]} [options.forces] An array of force callbacks. + * @param {ParticleEmitter} [options.emitter=new CircleEmitter(0.5)] The particle emitter for this system. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system from model to world coordinates. + * @param {Matrix4} [options.emitterModelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system emitter within the particle systems local coordinate system. + * @param {Color} [options.startColor=Color.WHITE] The color of a particle when it is born. + * @param {Color} [options.endColor=Color.WHITE] The color of a particle when it dies. + * @param {Number} [options.startScale=1.0] The scale of the particle when it is born. + * @param {Number} [options.endScale=1.0] The scale of the particle when it dies. + * @param {Number} [options.rate=5] The number of particles to emit per second. + * @param {ParticleBurst[]} [options.bursts] An array of {@link ParticleBurst}, emitting bursts of particles at periodic times. + * @param {Boolean} [options.loop=true] Whether the particle system should loop it's bursts when it is complete. + * @param {Number} [options.speed] Sets the minimum and maximum speed in meters per second + * @param {Number} [options.minimumSpeed=1.0] Sets the minimum speed in meters per second. + * @param {Number} [options.maximumSpeed=1.0] Sets the maximum speed in meters per second. + * @param {Number} [options.life] Sets the minimum and maximum life of particles in seconds. + * @param {Number} [options.minimumLife=5.0] Sets the minimum life of particles in seconds. + * @param {Number} [options.maximumLife=5.0] Sets the maximum life of particles in seconds. + * @param {Number} [options.mass] Sets the minimum and maximum mass of particles in kilograms. + * @param {Number} [options.minimumMass=1.0] Sets the minimum mass of particles in kilograms. + * @param {Number} [options.maximumMass=1.0] Sets the maximum mass of particles in kilograms. + * @param {Object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. + * @param {Number} [options.width] Sets the minimum and maximum width of particles in pixels. + * @param {Number} [options.minimumWidth=1.0] Sets the minimum width of particles in pixels. + * @param {Number} [options.maximumWidth=1.0] Sets the maximum width of particles in pixels. + * @param {Number} [options.height] Sets the minimum and maximum height of particles in pixels. + * @param {Number} [options.minimumHeight=1.0] Sets the minimum height of particles in pixels. + * @param {Number} [options.maximumHeight=1.0] Sets the maximum height of particles in pixels. + * @param {Number} [options.lifeTime=Number.MAX_VALUE] How long the particle system will emit particles, in seconds. * - * @param {TilingScheme} tilingScheme The tiling scheme for which to compute the geometric error. - * @returns {Number} The maximum geometric error at level zero, in meters. + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=ParticleSystem.html|Particle Systems Demo} */ - QuadtreeTileProvider.computeDefaultLevelZeroMaximumGeometricError = function(tilingScheme) { - return tilingScheme.ellipsoid.maximumRadius * 2 * Math.PI * 0.25 / (65 * tilingScheme.getNumberOfXTilesAtLevel(0)); - }; + function ParticleSystem(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - defineProperties(QuadtreeTileProvider.prototype, { /** - * Gets or sets the {@link QuadtreePrimitive} for which this provider is - * providing tiles. - * @memberof QuadtreeTileProvider.prototype - * @type {QuadtreePrimitive} + * Whether to display the particle system. + * @type {Boolean} + * @default true */ - quadtree : { - get : DeveloperError.throwInstantiationError, - set : DeveloperError.throwInstantiationError - }, + this.show = defaultValue(options.show, true); /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof QuadtreeTileProvider.prototype + * An array of force callbacks. The callback is passed a {@link Particle} and the difference from the last time + * @type {ParticleSystem~applyForce[]} + * @default undefined + */ + this.forces = options.forces; + + /** + * Whether the particle system should loop it's bursts when it is complete. * @type {Boolean} + * @default true */ - ready : { - get : DeveloperError.throwInstantiationError - }, + this.loop = defaultValue(options.loop, true); /** - * Gets the tiling scheme used by the provider. This property should - * not be accessed before {@link QuadtreeTileProvider#ready} returns true. - * @memberof QuadtreeTileProvider.prototype - * @type {TilingScheme} + * The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. + * @type {Object} + * @default undefined */ - tilingScheme : { - get : DeveloperError.throwInstantiationError - }, + this.image = defaultValue(options.image, undefined); + + var emitter = options.emitter; + if (!defined(emitter)) { + emitter = new CircleEmitter(0.5); + } + this._emitter = emitter; + + this._bursts = options.bursts; + + this._modelMatrix = Matrix4.clone(defaultValue(options.modelMatrix, Matrix4.IDENTITY)); + this._emitterModelMatrix = Matrix4.clone(defaultValue(options.emitterModelMatrix, Matrix4.IDENTITY)); + this._matrixDirty = true; + this._combinedMatrix = new Matrix4(); + + this._startColor = Color.clone(defaultValue(options.startColor, Color.WHITE)); + this._endColor = Color.clone(defaultValue(options.endColor, Color.WHITE)); + + this._startScale = defaultValue(options.startScale, 1.0); + this._endScale = defaultValue(options.endScale, 1.0); + + this._rate = defaultValue(options.rate, 5); + + this._minimumSpeed = defaultValue(options.speed, defaultValue(options.minimumSpeed, 1.0)); + this._maximumSpeed = defaultValue(options.speed, defaultValue(options.maximumSpeed, 1.0)); + + this._minimumLife = defaultValue(options.life, defaultValue(options.minimumLife, 5.0)); + this._maximumLife = defaultValue(options.life, defaultValue(options.maximumLife, 5.0)); + this._minimumMass = defaultValue(options.mass, defaultValue(options.minimumMass, 1.0)); + this._maximumMass = defaultValue(options.mass, defaultValue(options.maximumMass, 1.0)); + + this._minimumWidth = defaultValue(options.width, defaultValue(options.minimumWidth, 1.0)); + this._maximumWidth = defaultValue(options.width, defaultValue(options.maximumWidth, 1.0)); + + this._minimumHeight = defaultValue(options.height, defaultValue(options.minimumHeight, 1.0)); + this._maximumHeight = defaultValue(options.height, defaultValue(options.maximumHeight, 1.0)); + + this._lifeTime = defaultValue(options.lifeTime, Number.MAX_VALUE); + + this._billboardCollection = undefined; + this._particles = []; + + // An array of available particles that we can reuse instead of allocating new. + this._particlePool = []; + + this._previousTime = undefined; + this._currentTime = 0.0; + this._carryOver = 0.0; + + this._complete = new Event(); + this._isComplete = false; + + this._updateParticlePool = true; + this._particleEstimate = 0; + } + + defineProperties(ParticleSystem.prototype, { /** - * Gets an event that is raised when the geometry provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof QuadtreeTileProvider.prototype + * The particle emitter for this + * @memberof ParticleSystem.prototype + * @type {ParticleEmitter} + * @default CricleEmitter + */ + emitter : { + get : function() { + return this._emitter; + }, + set : function(value) { + Check.defined('value', value); + this._emitter = value; + } + }, + /** + * An array of {@link ParticleBurst}, emitting bursts of particles at periodic times. + * @type {ParticleBurst[]} + * @default undefined + */ + bursts : { + get : function() { + return this._bursts; + }, + set : function(value) { + this._bursts = value; + this._updateParticlePool = true; + } + }, + /** + * The 4x4 transformation matrix that transforms the particle system from model to world coordinates. + * @memberof ParticleSystem.prototype + * @type {Matrix4} + * @default Matrix4.IDENTITY + */ + modelMatrix : { + get : function() { + return this._modelMatrix; + }, + set : function(value) { + Check.defined('value', value); + this._matrixDirty = this._matrixDirty || !Matrix4.equals(this._modelMatrix, value); + Matrix4.clone(value, this._modelMatrix); + } + }, + /** + * The 4x4 transformation matrix that transforms the particle system emitter within the particle systems local coordinate system. + * @memberof ParticleSystem.prototype + * @type {Matrix4} + * @default Matrix4.IDENTITY + */ + emitterModelMatrix : { + get : function() { + return this._emitterModelMatrix; + }, + set : function(value) { + Check.defined('value', value); + this._matrixDirty = this._matrixDirty || !Matrix4.equals(this._emitterModelMatrix, value); + Matrix4.clone(value, this._emitterModelMatrix); + } + }, + /** + * The color of a particle when it is born. + * @memberof ParticleSystem.prototype + * @type {Color} + * @default Color.WHITE + */ + startColor : { + get : function() { + return this._startColor; + }, + set : function(value) { + Check.defined('value', value); + Color.clone(value, this._startColor); + } + }, + /** + * The color of a particle when it dies. + * @memberof ParticleSystem.prototype + * @type {Color} + * @default Color.WHITE + */ + endColor : { + get : function() { + return this._endColor; + }, + set : function(value) { + Check.defined('value', value); + Color.clone(value, this._endColor); + } + }, + /** + * The scale of the particle when it is born. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + startScale : { + get : function() { + return this._startScale; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._startScale = value; + } + }, + /** + * The scale of the particle when it dies. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + endScale : { + get : function() { + return this._endScale; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._endScale = value; + } + }, + /** + * The number of particles to emit per second. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 5 + */ + rate : { + get : function() { + return this._rate; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._rate = value; + this._updateParticlePool = true; + } + }, + /** + * Sets the minimum speed in meters per second. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + minimumSpeed : { + get : function() { + return this._minimumSpeed; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._minimumSpeed = value; + } + }, + /** + * Sets the maximum speed in meters per second. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + maximumSpeed : { + get : function() { + return this._maximumSpeed; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._maximumSpeed = value; + } + }, + /** + * Sets the minimum life of particles in seconds. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 5.0 + */ + minimumLife : { + get : function() { + return this._minimumLife; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._minimumLife = value; + } + }, + /** + * Sets the maximum life of particles in seconds. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 5.0 + */ + maximumLife : { + get : function() { + return this._maximumLife; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._maximumLife = value; + this._updateParticlePool = true; + } + }, + /** + * Sets the minimum mass of particles in kilograms. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + minimumMass : { + get : function() { + return this._minimumMass; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._minimumMass = value; + } + }, + /** + * Sets the maximum mass of particles in kilograms. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + maximumMass : { + get : function() { + return this._maximumMass; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._maximumMass = value; + } + }, + /** + * Sets the minimum width of particles in pixels. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + minimumWidth : { + get : function() { + return this._minimumWidth; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._minimumWidth = value; + } + }, + /** + * Sets the maximum width of particles in pixels. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + maximumWidth : { + get : function() { + return this._maximumWidth; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._maximumWidth = value; + } + }, + /** + * Sets the minimum height of particles in pixels. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + minimumHeight : { + get : function() { + return this._minimumHeight; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._minimumHeight = value; + } + }, + /** + * Sets the maximum height of particles in pixels. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default 1.0 + */ + maximumHeight : { + get : function() { + return this._maximumHeight; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._maximumHeight = value; + } + }, + /** + * How long the particle system will emit particles, in seconds. + * @memberof ParticleSystem.prototype + * @type {Number} + * @default Number.MAX_VALUE + */ + lifeTime : { + get : function() { + return this._lifeTime; + }, + set : function(value) { + Check.typeOf.number.greaterThanOrEquals('value', value, 0.0); + this._lifeTime = value; + } + }, + /** + * Fires an event when the particle system has reached the end of its lifetime. + * @memberof ParticleSystem.prototype * @type {Event} */ - errorEvent : { - get : DeveloperError.throwInstantiationError + complete : { + get : function() { + return this._complete; + } + }, + /** + * When <code>true</code>, the particle system has reached the end of its lifetime; <code>false</code> otherwise. + * @memberof ParticleSystem.prototype + * @type {Boolean} + */ + isComplete : { + get : function() { + return this._isComplete; + } } }); - /** - * Called at the beginning of the update cycle for each render frame, before {@link QuadtreeTileProvider#showTileThisFrame} - * or any other functions. - * @memberof QuadtreeTileProvider - * @function - * - * @param {Context} context The rendering context. - * @param {FrameState} frameState The frame state. - * @param {DrawCommand[]} commandList An array of rendering commands. This method may push - * commands into this array. - */ - QuadtreeTileProvider.prototype.beginUpdate = DeveloperError.throwInstantiationError; - - /** - * Called at the end of the update cycle for each render frame, after {@link QuadtreeTileProvider#showTileThisFrame} - * and any other functions. - * @memberof QuadtreeTileProvider - * @function - * - * @param {Context} context The rendering context. - * @param {FrameState} frameState The frame state. - * @param {DrawCommand[]} commandList An array of rendering commands. This method may push - * commands into this array. - */ - QuadtreeTileProvider.prototype.endUpdate = DeveloperError.throwInstantiationError; + function updateParticlePool(system) { + var rate = system._rate; + var life = system._maximumLife; - /** - * Gets the maximum geometric error allowed in a tile at a given level, in meters. This function should not be - * called before {@link QuadtreeTileProvider#ready} returns true. - * - * @see QuadtreeTileProvider#computeDefaultLevelZeroMaximumGeometricError - * - * @memberof QuadtreeTileProvider - * @function - * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error in meters. - */ - QuadtreeTileProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; + var burstAmount = 0; + var bursts = system._bursts; + if (defined(bursts)) { + var length = bursts.length; + for (var i = 0; i < length; ++i) { + burstAmount += bursts[i].maximum; + } + } - /** - * Loads, or continues loading, a given tile. This function will continue to be called - * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}. This function should - * not be called before {@link QuadtreeTileProvider#ready} returns true. - * - * @memberof QuadtreeTileProvider - * @function - * - * @param {Context} context The rendering context. - * @param {FrameState} frameState The frame state. - * @param {QuadtreeTile} tile The tile to load. - * - * @exception {DeveloperError} <code>loadTile</code> must not be called before the tile provider is ready. - */ - QuadtreeTileProvider.prototype.loadTile = DeveloperError.throwInstantiationError; + var billboardCollection = system._billboardCollection; + var image = system.image; - /** - * Determines the visibility of a given tile. The tile may be fully visible, partially visible, or not - * visible at all. Tiles that are renderable and are at least partially visible will be shown by a call - * to {@link QuadtreeTileProvider#showTileThisFrame}. - * - * @memberof QuadtreeTileProvider - * - * @param {QuadtreeTile} tile The tile instance. - * @param {FrameState} frameState The state information about the current frame. - * @param {QuadtreeOccluders} occluders The objects that may occlude this tile. - * - * @returns {Visibility} The visibility of the tile. - */ - QuadtreeTileProvider.prototype.computeTileVisibility = DeveloperError.throwInstantiationError; + var particleEstimate = Math.ceil(rate * life + burstAmount); + var particles = system._particles; + var particlePool = system._particlePool; + var numToAdd = Math.max(particleEstimate - particles.length - particlePool.length, 0); - /** - * Shows a specified tile in this frame. The provider can cause the tile to be shown by adding - * render commands to the commandList, or use any other method as appropriate. The tile is not - * expected to be visible next frame as well, unless this method is call next frame, too. - * - * @memberof QuadtreeTileProvider - * @function - * - * @param {QuadtreeTile} tile The tile instance. - * @param {Context} context The rendering context. - * @param {FrameState} frameState The state information of the current rendering frame. - * @param {DrawCommand[]} commandList The list of rendering commands. This method may add additional commands to this list. - */ - QuadtreeTileProvider.prototype.showTileThisFrame = DeveloperError.throwInstantiationError; + for (var j = 0; j < numToAdd; ++j) { + var particle = new Particle(); + particle._billboard = billboardCollection.add({ + image : image + }); + particlePool.push(particle); + } - /** - * Gets the distance from the camera to the closest point on the tile. This is used for level-of-detail selection. - * - * @memberof QuadtreeTileProvider - * @function - * - * @param {QuadtreeTile} tile The tile instance. - * @param {FrameState} frameState The state information of the current rendering frame. - * - * @returns {Number} The distance from the camera to the closest point on the tile, in meters. - */ - QuadtreeTileProvider.prototype.computeDistanceToTile = DeveloperError.throwInstantiationError; + system._particleEstimate = particleEstimate; + } - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @memberof QuadtreeTileProvider - * - * @returns {Boolean} True if this object was destroyed; otherwise, false. - * - * @see QuadtreeTileProvider#destroy - */ - QuadtreeTileProvider.prototype.isDestroyed = DeveloperError.throwInstantiationError; + function getOrCreateParticle(system) { + // Try to reuse an existing particle from the pool. + var particle = system._particlePool.pop(); + if (!defined(particle)) { + // Create a new one + particle = new Particle(); + } + return particle; + } - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @memberof QuadtreeTileProvider - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * provider = provider && provider(); - * - * @see QuadtreeTileProvider#isDestroyed - */ - QuadtreeTileProvider.prototype.destroy = DeveloperError.throwInstantiationError; + function addParticleToPool(system, particle) { + system._particlePool.push(particle); + } - return QuadtreeTileProvider; -}); + function freeParticlePool(system) { + var particles = system._particles; + var particlePool = system._particlePool; + var billboardCollection = system._billboardCollection; -define('Scene/SceneTransitioner',[ - '../Core/Cartesian3', - '../Core/Cartographic', - '../Core/Check', - '../Core/defined', - '../Core/destroyObject', - '../Core/EasingFunction', - '../Core/Math', - '../Core/Matrix4', - '../Core/OrthographicFrustum', - '../Core/OrthographicOffCenterFrustum', - '../Core/PerspectiveFrustum', - '../Core/Ray', - '../Core/ScreenSpaceEventHandler', - '../Core/ScreenSpaceEventType', - '../Core/Transforms', - './Camera', - './SceneMode' - ], function( - Cartesian3, - Cartographic, - Check, - defined, - destroyObject, - EasingFunction, - CesiumMath, - Matrix4, - OrthographicFrustum, - OrthographicOffCenterFrustum, - PerspectiveFrustum, - Ray, - ScreenSpaceEventHandler, - ScreenSpaceEventType, - Transforms, - Camera, - SceneMode) { - 'use strict'; + var numParticles = particles.length; + var numInPool = particlePool.length; + var estimate = system._particleEstimate; - /** - * @private - */ - function SceneTransitioner(scene) { - Check.typeOf.object('scene', scene); - - this._scene = scene; - this._currentTweens = []; - this._morphHandler = undefined; - this._morphCancelled = false; - this._completeMorph = undefined; - this._morphToOrthographic = false; + var start = numInPool - Math.max(estimate - numParticles - numInPool, 0); + for (var i = start; i < numInPool; ++i) { + var p = particlePool[i]; + billboardCollection.remove(p._billboard); + } + particlePool.length = start; } - SceneTransitioner.prototype.completeMorph = function() { - if (defined(this._completeMorph)) { - this._completeMorph(); + function removeBillboard(particle) { + if (defined(particle._billboard)) { + particle._billboard.show = false; } - }; + } - SceneTransitioner.prototype.morphTo2D = function(duration, ellipsoid) { - if (defined(this._completeMorph)) { - this._completeMorph(); + function updateBillboard(system, particle) { + var billboard = particle._billboard; + if (!defined(billboard)) { + billboard = particle._billboard = system._billboardCollection.add({ + image : particle.image + }); } + billboard.width = particle.size.x; + billboard.height = particle.size.y; + billboard.position = particle.position; + billboard.show = true; - var scene = this._scene; - this._previousMode = scene.mode; - this._morphToOrthographic = scene.camera.frustum instanceof OrthographicFrustum; + // Update the color + var r = CesiumMath.lerp(particle.startColor.red, particle.endColor.red, particle.normalizedAge); + var g = CesiumMath.lerp(particle.startColor.green, particle.endColor.green, particle.normalizedAge); + var b = CesiumMath.lerp(particle.startColor.blue, particle.endColor.blue, particle.normalizedAge); + var a = CesiumMath.lerp(particle.startColor.alpha, particle.endColor.alpha, particle.normalizedAge); + billboard.color = new Color(r,g,b,a); - if (this._previousMode === SceneMode.SCENE2D || this._previousMode === SceneMode.MORPHING) { - return; - } - this._scene.morphStart.raiseEvent(this, this._previousMode, SceneMode.SCENE2D, true); + // Update the scale + var scale = CesiumMath.lerp(particle.startScale, particle.endScale, particle.normalizedAge); + billboard.scale = scale; + } - scene._mode = SceneMode.MORPHING; - scene.camera._setTransform(Matrix4.IDENTITY); + function addParticle(system, particle) { + particle.startColor = Color.clone(system._startColor, particle.startColor); + particle.endColor = Color.clone(system._endColor, particle.endColor); + particle.startScale = system._startScale; + particle.endScale = system._endScale; + particle.image = system.image; + particle.life = CesiumMath.randomBetween(system._minimumLife, system._maximumLife); + particle.mass = CesiumMath.randomBetween(system._minimumMass, system._maximumMass); - if (this._previousMode === SceneMode.COLUMBUS_VIEW) { - morphFromColumbusViewTo2D(this, duration); - } else { - morphFrom3DTo2D(this, duration, ellipsoid); - } + var width = CesiumMath.randomBetween(system._minimumWidth, system._maximumWidth); + var height = CesiumMath.randomBetween(system._minimumHeight, system._maximumHeight); + particle.size = Cartesian2.fromElements(width, height, particle.size); - if (duration === 0.0 && defined(this._completeMorph)) { - this._completeMorph(); - } - }; + // Reset the normalizedAge and age in case the particle was reused. + particle._normalizedAge = 0.0; + particle._age = 0.0; - var scratchToCVPosition = new Cartesian3(); - var scratchToCVDirection = new Cartesian3(); - var scratchToCVUp = new Cartesian3(); - var scratchToCVPosition2D = new Cartesian3(); - var scratchToCVDirection2D = new Cartesian3(); - var scratchToCVUp2D = new Cartesian3(); - var scratchToCVSurfacePosition = new Cartesian3(); - var scratchToCVCartographic = new Cartographic(); - var scratchToCVToENU = new Matrix4(); - var scratchToCVFrustumPerspective = new PerspectiveFrustum(); - var scratchToCVFrustumOrthographic = new OrthographicFrustum(); - var scratchToCVCamera = { - position : undefined, - direction : undefined, - up : undefined, - position2D : undefined, - direction2D : undefined, - up2D : undefined, - frustum : undefined - }; + var speed = CesiumMath.randomBetween(system._minimumSpeed, system._maximumSpeed); + Cartesian3.multiplyByScalar(particle.velocity, speed, particle.velocity); - SceneTransitioner.prototype.morphToColumbusView = function(duration, ellipsoid) { - if (defined(this._completeMorph)) { - this._completeMorph(); + system._particles.push(particle); + } + + function calculateNumberToEmit(system, dt) { + // This emitter is finished if it exceeds it's lifetime. + if (system._isComplete) { + return 0; } - var scene = this._scene; - this._previousMode = scene.mode; + dt = CesiumMath.mod(dt, system._lifeTime); - if (this._previousMode === SceneMode.COLUMBUS_VIEW || this._previousMode === SceneMode.MORPHING) { - return; + // Compute the number of particles to emit based on the rate. + var v = dt * system._rate; + var numToEmit = Math.floor(v); + system._carryOver += (v - numToEmit); + if (system._carryOver > 1.0) + { + numToEmit++; + system._carryOver -= 1.0; } - this._scene.morphStart.raiseEvent(this, this._previousMode, SceneMode.COLUMBUS_VIEW, true); - scene.camera._setTransform(Matrix4.IDENTITY); + // Apply any bursts + if (defined(system.bursts)) { + var length = system.bursts.length; + for (var i = 0; i < length; i++) { + var burst = system.bursts[i]; + var currentTime = system._currentTime; + if (defined(burst) && !burst._complete && currentTime > burst.time) { + numToEmit += CesiumMath.randomBetween(burst.minimum, burst.maximum); + burst._complete = true; + } + } + } - var position = scratchToCVPosition; - var direction = scratchToCVDirection; - var up = scratchToCVUp; + return numToEmit; + } - if (duration > 0.0) { - position.x = 0.0; - position.y = -1.0; - position.z = 1.0; - position = Cartesian3.multiplyByScalar(Cartesian3.normalize(position, position), 5.0 * ellipsoid.maximumRadius, position); + var rotatedVelocityScratch = new Cartesian3(); - Cartesian3.negate(Cartesian3.normalize(position, direction), direction); - Cartesian3.cross(Cartesian3.UNIT_X, direction, up); - } else { - var camera = scene.camera; - if (this._previousMode === SceneMode.SCENE2D) { - Cartesian3.clone(camera.position, position); - position.z = camera.frustum.right - camera.frustum.left; - Cartesian3.negate(Cartesian3.UNIT_Z, direction); - Cartesian3.clone(Cartesian3.UNIT_Y, up); - } else { - Cartesian3.clone(camera.positionWC, position); - Cartesian3.clone(camera.directionWC, direction); - Cartesian3.clone(camera.upWC, up); + /** + * @private + */ + ParticleSystem.prototype.update = function(frameState) { + if (!this.show) { + return; + } - var surfacePoint = ellipsoid.scaleToGeodeticSurface(position, scratchToCVSurfacePosition); - var toENU = Transforms.eastNorthUpToFixedFrame(surfacePoint, ellipsoid, scratchToCVToENU); - Matrix4.inverseTransformation(toENU, toENU); + if (!defined(this._billboardCollection)) { + this._billboardCollection = new BillboardCollection(); + } - scene.mapProjection.project(ellipsoid.cartesianToCartographic(position, scratchToCVCartographic), position); - Matrix4.multiplyByPointAsVector(toENU, direction, direction); - Matrix4.multiplyByPointAsVector(toENU, up, up); - } + if (this._updateParticlePool) { + updateParticlePool(this); + this._updateParticlePool = false; } - var frustum; - if (this._morphToOrthographic) { - frustum = scratchToCVFrustumOrthographic; - frustum.width = scene.camera.frustum.right - scene.camera.frustum.left; - frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - } else { - frustum = scratchToCVFrustumPerspective; - frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - frustum.fov = CesiumMath.toRadians(60.0); + // Compute the frame time + var dt = 0.0; + if (this._previousTime) { + dt = JulianDate.secondsDifference(frameState.time, this._previousTime); } - var cameraCV = scratchToCVCamera; - cameraCV.position = position; - cameraCV.direction = direction; - cameraCV.up = up; - cameraCV.frustum = frustum; + if (dt < 0.0) { + dt = 0.0; + } - var complete = completeColumbusViewCallback(cameraCV); - createMorphHandler(this, complete); + var particles = this._particles; + var emitter = this._emitter; + var forces = this.forces; - if (this._previousMode === SceneMode.SCENE2D) { - morphFrom2DToColumbusView(this, duration, cameraCV, complete); - } else { - cameraCV.position2D = Matrix4.multiplyByPoint(Camera.TRANSFORM_2D, position, scratchToCVPosition2D); - cameraCV.direction2D = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, direction, scratchToCVDirection2D); - cameraCV.up2D = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, up, scratchToCVUp2D); + var i; + var particle; - scene._mode = SceneMode.MORPHING; - morphFrom3DToColumbusView(this, duration, cameraCV, complete); + // update particles and remove dead particles + var length = particles.length; + for (i = 0; i < length; ++i) { + particle = particles[i]; + if (!particle.update(dt, forces)) { + removeBillboard(particle); + // Add the particle back to the pool so it can be reused. + addParticleToPool(this, particle); + particles[i] = particles[length - 1]; + --i; + --length; + } else { + updateBillboard(this, particle); + } } + particles.length = length; - if (duration === 0.0 && defined(this._completeMorph)) { - this._completeMorph(); - } - }; + var numToEmit = calculateNumberToEmit(this, dt); - var scratchCVTo3DCamera = { - position : new Cartesian3(), - direction : new Cartesian3(), - up : new Cartesian3(), - frustum : undefined - }; - var scratch2DTo3DFrustumPersp = new PerspectiveFrustum(); + if (numToEmit > 0 && defined(emitter)) { + // Compute the final model matrix by combining the particle systems model matrix and the emitter matrix. + if (this._matrixDirty) { + this._combinedMatrix = Matrix4.multiply(this.modelMatrix, this.emitterModelMatrix, this._combinedMatrix); + this._matrixDirty = false; + } - SceneTransitioner.prototype.morphTo3D = function(duration, ellipsoid) { - if (defined(this._completeMorph)) { - this._completeMorph(); - } + var combinedMatrix = this._combinedMatrix; - var scene = this._scene; - this._previousMode = scene.mode; + for (i = 0; i < numToEmit; i++) { + // Create a new particle. + particle = getOrCreateParticle(this); - if (this._previousMode === SceneMode.SCENE3D || this._previousMode === SceneMode.MORPHING) { - return; - } - this._scene.morphStart.raiseEvent(this, this._previousMode, SceneMode.SCENE3D, true); + // Let the emitter initialize the particle. + this._emitter.emit(particle); - scene._mode = SceneMode.MORPHING; - scene.camera._setTransform(Matrix4.IDENTITY); + //For the velocity we need to add it to the original position and then multiply by point. + Cartesian3.add(particle.position, particle.velocity, rotatedVelocityScratch); + Matrix4.multiplyByPoint(combinedMatrix, rotatedVelocityScratch, rotatedVelocityScratch); - if (this._previousMode === SceneMode.SCENE2D) { - morphFrom2DTo3D(this, duration, ellipsoid); - } else { - var camera3D; - if (duration > 0.0) { - camera3D = scratchCVTo3DCamera; - Cartesian3.fromDegrees(0.0, 0.0, 5.0 * ellipsoid.maximumRadius, ellipsoid, camera3D.position); - Cartesian3.negate(camera3D.position, camera3D.direction); - Cartesian3.normalize(camera3D.direction, camera3D.direction); - Cartesian3.clone(Cartesian3.UNIT_Z, camera3D.up); - } else { - camera3D = getColumbusViewTo3DCamera(this, ellipsoid); - } + // Change the position to be in world coordinates + particle.position = Matrix4.multiplyByPoint(combinedMatrix, particle.position, particle.position); - var frustum; - var camera = scene.camera; - if (camera.frustum instanceof OrthographicFrustum) { - frustum = camera.frustum.clone(); - } else { - frustum = scratch2DTo3DFrustumPersp; - frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - frustum.fov = CesiumMath.toRadians(60.0); + // Orient the velocity in world space as well. + Cartesian3.subtract(rotatedVelocityScratch, particle.position, particle.velocity); + Cartesian3.normalize(particle.velocity, particle.velocity); + + // Add the particle to the system. + addParticle(this, particle); + updateBillboard(this, particle); } - camera3D.frustum = frustum; + } - var complete = complete3DCallback(camera3D); - createMorphHandler(this, complete); + this._billboardCollection.update(frameState); + this._previousTime = JulianDate.clone(frameState.time, this._previousTime); + this._currentTime += dt; - morphFromColumbusViewTo3D(this, duration, camera3D, complete); + if (this._lifeTime !== Number.MAX_VALUE && this._currentTime > this._lifeTime) { + if (this.loop) { + this._currentTime = CesiumMath.mod(this._currentTime, this._lifeTime); + if (this.bursts) { + var burstLength = this.bursts.length; + // Reset any bursts + for (i = 0; i < burstLength; i++) { + this.bursts[i]._complete = false; + } + } + } else { + this._isComplete = true; + this._complete.raiseEvent(this); + } } - if (duration === 0.0 && defined(this._completeMorph)) { - this._completeMorph(); + // free particles in the pool and release billboard GPU memory + if (frameState.frameNumber % 120 === 0) { + freeParticlePool(this); } }; @@ -204007,8939 +215410,8946 @@ define('Scene/SceneTransitioner',[ * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see ParticleSystem#destroy */ - SceneTransitioner.prototype.isDestroyed = function() { + ParticleSystem.prototype.isDestroyed = function() { return false; }; /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> * Once an object is destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, * assign the return value (<code>undefined</code>) to the object as done in the example. * + * @returns {undefined} + * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * - * @example - * transitioner = transitioner && transitioner.destroy(); + * @see ParticleSystem#isDestroyed */ - SceneTransitioner.prototype.destroy = function() { - destroyMorphHandler(this); + ParticleSystem.prototype.destroy = function() { + this._billboardCollection = this._billboardCollection && this._billboardCollection.destroy(); return destroyObject(this); }; - function createMorphHandler(transitioner, completeMorphFunction) { - if (transitioner._scene.completeMorphOnUserInput) { - transitioner._morphHandler = new ScreenSpaceEventHandler(transitioner._scene.canvas, false); - - var completeMorph = function() { - transitioner._morphCancelled = true; - completeMorphFunction(transitioner); - }; - transitioner._completeMorph = completeMorph; - transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.LEFT_DOWN); - transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.MIDDLE_DOWN); - transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.RIGHT_DOWN); - transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.WHEEL); - } - } - - function destroyMorphHandler(transitioner) { - var tweens = transitioner._currentTweens; - for ( var i = 0; i < tweens.length; ++i) { - tweens[i].cancelTween(); - } - transitioner._currentTweens.length = 0; - transitioner._morphHandler = transitioner._morphHandler && transitioner._morphHandler.destroy(); - } - - var scratchCVTo3DCartographic = new Cartographic(); - var scratchCVTo3DSurfacePoint = new Cartesian3(); - var scratchCVTo3DFromENU = new Matrix4(); - - function getColumbusViewTo3DCamera(transitioner, ellipsoid) { - var scene = transitioner._scene; - var camera = scene.camera; - - var camera3D = scratchCVTo3DCamera; - var position = camera3D.position; - var direction = camera3D.direction; - var up = camera3D.up; - - var positionCarto = scene.mapProjection.unproject(camera.position, scratchCVTo3DCartographic); - ellipsoid.cartographicToCartesian(positionCarto, position); - var surfacePoint = ellipsoid.scaleToGeodeticSurface(position, scratchCVTo3DSurfacePoint); - - var fromENU = Transforms.eastNorthUpToFixedFrame(surfacePoint, ellipsoid, scratchCVTo3DFromENU); - - Matrix4.multiplyByPointAsVector(fromENU, camera.direction, direction); - Matrix4.multiplyByPointAsVector(fromENU, camera.up, up); - - return camera3D; - } - - var scratchCVTo3DStartPos = new Cartesian3(); - var scratchCVTo3DStartDir = new Cartesian3(); - var scratchCVTo3DStartUp = new Cartesian3(); - var scratchCVTo3DEndPos = new Cartesian3(); - var scratchCVTo3DEndDir = new Cartesian3(); - var scratchCVTo3DEndUp = new Cartesian3(); - - function morphFromColumbusViewTo3D(transitioner, duration, endCamera, complete) { - duration *= 0.5; - - var scene = transitioner._scene; - var camera = scene.camera; - - var startPos = Cartesian3.clone(camera.position, scratchCVTo3DStartPos); - var startDir = Cartesian3.clone(camera.direction, scratchCVTo3DStartDir); - var startUp = Cartesian3.clone(camera.up, scratchCVTo3DStartUp); - - var endPos = Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, endCamera.position, scratchCVTo3DEndPos); - var endDir = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D_INVERSE, endCamera.direction, scratchCVTo3DEndDir); - var endUp = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D_INVERSE, endCamera.up, scratchCVTo3DEndUp); - - function update(value) { - columbusViewMorph(startPos, endPos, value.time, camera.position); - columbusViewMorph(startDir, endDir, value.time, camera.direction); - columbusViewMorph(startUp, endUp, value.time, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - } - - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - update : update, - complete : function() { - addMorphTimeAnimations(transitioner, scene, 0.0, 1.0, duration, complete); - } - }); - transitioner._currentTweens.push(tween); - } - - var scratch2DTo3DFrustumOrtho = new OrthographicFrustum(); - var scratch3DToCVStartPos = new Cartesian3(); - var scratch3DToCVStartDir = new Cartesian3(); - var scratch3DToCVStartUp = new Cartesian3(); - var scratch3DToCVEndPos = new Cartesian3(); - var scratch3DToCVEndDir = new Cartesian3(); - var scratch3DToCVEndUp = new Cartesian3(); - - function morphFrom2DTo3D(transitioner, duration, ellipsoid) { - duration /= 3.0; - - var scene = transitioner._scene; - var camera = scene.camera; - - var camera3D; - if (duration > 0.0) { - camera3D = scratchCVTo3DCamera; - Cartesian3.fromDegrees(0.0, 0.0, 5.0 * ellipsoid.maximumRadius, ellipsoid, camera3D.position); - Cartesian3.negate(camera3D.position, camera3D.direction); - Cartesian3.normalize(camera3D.direction, camera3D.direction); - Cartesian3.clone(Cartesian3.UNIT_Z, camera3D.up); - } else { - camera.position.z = camera.frustum.right - camera.frustum.left; - - camera3D = getColumbusViewTo3DCamera(transitioner, ellipsoid); - } - - var frustum; - if (transitioner._morphToOrthographic) { - frustum = scratch2DTo3DFrustumOrtho; - frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - frustum.width = camera.frustum.right - camera.frustum.left; - } else { - frustum = scratch2DTo3DFrustumPersp; - frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; - frustum.fov = CesiumMath.toRadians(60.0); - } - - camera3D.frustum = frustum; - - var complete = complete3DCallback(camera3D); - createMorphHandler(transitioner, complete); - - var startPos = Cartesian3.clone(camera.position, scratch3DToCVStartPos); - var startDir = Cartesian3.clone(camera.direction, scratch3DToCVStartDir); - var startUp = Cartesian3.clone(camera.up, scratch3DToCVStartUp); - - var endPos = Cartesian3.fromElements(0.0, 0.0, 5.0 * ellipsoid.maximumRadius, scratch3DToCVEndPos); - var endDir = Cartesian3.negate(Cartesian3.UNIT_Z, scratch3DToCVEndDir); - var endUp = Cartesian3.clone(Cartesian3.UNIT_Y, scratch3DToCVEndUp); - - var startRight = camera.frustum.right; - var endRight = endPos.z * 0.5; - - function update(value) { - columbusViewMorph(startPos, endPos, value.time, camera.position); - columbusViewMorph(startDir, endDir, value.time, camera.direction); - columbusViewMorph(startUp, endUp, value.time, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - - var frustum = camera.frustum; - frustum.right = CesiumMath.lerp(startRight, endRight, value.time); - frustum.left = -frustum.right; - frustum.top = frustum.right * (scene.drawingBufferHeight / scene.drawingBufferWidth); - frustum.bottom = -frustum.top; - - camera.position.z = 2.0 * scene.mapProjection.ellipsoid.maximumRadius; - } - - var morph; - if (transitioner._morphToOrthographic) { - morph = function() { - morphFromColumbusViewTo3D(transitioner, duration, camera3D, complete); - }; - } else { - morph = function() { - morphOrthographicToPerspective(transitioner, duration, camera3D, function() { - morphFromColumbusViewTo3D(transitioner, duration, camera3D, complete); - }); - }; - } - - if (duration > 0.0) { - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - update : update, - complete : function() { - scene._mode = SceneMode.MORPHING; - morph(); - } - }); - transitioner._currentTweens.push(tween); - } else { - morph(); - } - } - - function columbusViewMorph(startPosition, endPosition, time, result) { - // Just linear for now. - return Cartesian3.lerp(startPosition, endPosition, time, result); - } - - function morphPerspectiveToOrthographic(transitioner, duration, endCamera, updateHeight, complete) { - var scene = transitioner._scene; - var camera = scene.camera; - - if (camera.frustum instanceof OrthographicFrustum) { - return; - } - - var startFOV = camera.frustum.fov; - var endFOV = CesiumMath.RADIANS_PER_DEGREE * 0.5; - var d = endCamera.position.z * Math.tan(startFOV * 0.5); - camera.frustum.far = d / Math.tan(endFOV * 0.5) + 10000000.0; - - function update(value) { - camera.frustum.fov = CesiumMath.lerp(startFOV, endFOV, value.time); - var height = d / Math.tan(camera.frustum.fov * 0.5); - updateHeight(camera, height); - } - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - update : update, - complete : function() { - camera.frustum = endCamera.frustum.clone(); - complete(transitioner); - } - }); - transitioner._currentTweens.push(tween); - } - - var scratchCVTo2DStartPos = new Cartesian3(); - var scratchCVTo2DStartDir = new Cartesian3(); - var scratchCVTo2DStartUp = new Cartesian3(); - var scratchCVTo2DEndPos = new Cartesian3(); - var scratchCVTo2DEndDir = new Cartesian3(); - var scratchCVTo2DEndUp = new Cartesian3(); - var scratchCVTo2DFrustum = new OrthographicOffCenterFrustum(); - var scratchCVTo2DRay = new Ray(); - var scratchCVTo2DPickPos = new Cartesian3(); - var scratchCVTo2DCamera = { - position : undefined, - direction : undefined, - up : undefined, - frustum : undefined - }; - - function morphFromColumbusViewTo2D(transitioner, duration) { - duration *= 0.5; - - var scene = transitioner._scene; - var camera = scene.camera; - - var startPos = Cartesian3.clone(camera.position, scratchCVTo2DStartPos); - var startDir = Cartesian3.clone(camera.direction, scratchCVTo2DStartDir); - var startUp = Cartesian3.clone(camera.up, scratchCVTo2DStartUp); - - var endDir = Cartesian3.negate(Cartesian3.UNIT_Z, scratchCVTo2DEndDir); - var endUp = Cartesian3.clone(Cartesian3.UNIT_Y, scratchCVTo2DEndUp); + /** + * A function used to apply a force to the particle on each time step. + * @callback ParticleSystem~applyForce + * + * @param {Particle} particle The particle to apply the force to. + * @param {Number} dt The time since the last update. + * + * @example + * function applyGravity(particle, dt) { + * var position = particle.position; + * var gravityVector = Cesium.Cartesian3.normalize(position, new Cesium.Cartesian3()); + * Cesium.Cartesian3.multiplyByScalar(gravityVector, GRAVITATIONAL_CONSTANT * dt, gravityVector); + * particle.velocity = Cesium.Cartesian3.add(particle.velocity, gravityVector, particle.velocity); + * } + */ - var endPos = scratchCVTo2DEndPos; + return ParticleSystem; +}); - if (duration > 0.0) { - Cartesian3.clone(Cartesian3.ZERO, scratchCVTo2DEndPos); - endPos.z = 5.0 * scene.mapProjection.ellipsoid.maximumRadius; - } else { - Cartesian3.clone(startPos, scratchCVTo2DEndPos); +define('Widgets/getElement',[ + '../Core/DeveloperError' + ], function( + DeveloperError) { + 'use strict'; - var ray = scratchCVTo2DRay; - Matrix4.multiplyByPoint(Camera.TRANSFORM_2D, startPos, ray.origin); - Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, startDir, ray.direction); + /** + * If element is a string, look up the element in the DOM by ID. Otherwise return element. + * + * @private + * + * @exception {DeveloperError} Element with id "id" does not exist in the document. + */ + function getElement(element) { + if (typeof element === 'string') { + var foundElement = document.getElementById(element); - var globe = scene.globe; - if (defined(globe)) { - var pickPos = globe.pick(ray, scene, scratchCVTo2DPickPos); - if (defined(pickPos)) { - Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, pickPos, endPos); - endPos.z += Cartesian3.distance(startPos, endPos); - } + if (foundElement === null) { + throw new DeveloperError('Element with id "' + element + '" does not exist in the document.'); } + + element = foundElement; } - - var frustum = scratchCVTo2DFrustum; - frustum.right = endPos.z * 0.5; - frustum.left = -frustum.right; - frustum.top = frustum.right * (scene.drawingBufferHeight / scene.drawingBufferWidth); - frustum.bottom = -frustum.top; - - var camera2D = scratchCVTo2DCamera; - camera2D.position = endPos; - camera2D.direction = endDir; - camera2D.up = endUp; - camera2D.frustum = frustum; - - var complete = complete2DCallback(camera2D); - createMorphHandler(transitioner, complete); - - function updateCV(value) { - columbusViewMorph(startPos, endPos, value.time, camera.position); - columbusViewMorph(startDir, endDir, value.time, camera.direction); - columbusViewMorph(startUp, endUp, value.time, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - camera._adjustOrthographicFrustum(true); - } - - function updateHeight(camera, height) { - camera.position.z = height; - } - - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - update : updateCV, - complete : function() { - morphPerspectiveToOrthographic(transitioner, duration, camera2D, updateHeight, complete); - } - }); - transitioner._currentTweens.push(tween); + return element; } - var scratch3DTo2DCartographic = new Cartographic(); - var scratch3DTo2DCamera = { - position : new Cartesian3(), - direction : new Cartesian3(), - up : new Cartesian3(), - position2D : new Cartesian3(), - direction2D : new Cartesian3(), - up2D : new Cartesian3(), - frustum : new OrthographicOffCenterFrustum() - }; - var scratch3DTo2DEndCamera = { - position : new Cartesian3(), - direction : new Cartesian3(), - up : new Cartesian3(), - frustum : undefined - }; - var scratch3DTo2DPickPosition = new Cartesian3(); - var scratch3DTo2DRay = new Ray(); - var scratch3DTo2DToENU = new Matrix4(); - var scratch3DTo2DSurfacePoint = new Cartesian3(); - - function morphFrom3DTo2D(transitioner, duration, ellipsoid) { - duration *= 0.5; - - var scene = transitioner._scene; - var camera = scene.camera; - var camera2D = scratch3DTo2DCamera; - - if (duration > 0.0) { - Cartesian3.clone(Cartesian3.ZERO, camera2D.position); - camera2D.position.z = 5.0 * ellipsoid.maximumRadius; - Cartesian3.negate(Cartesian3.UNIT_Z, camera2D.direction); - Cartesian3.clone(Cartesian3.UNIT_Y, camera2D.up); - } else { - ellipsoid.cartesianToCartographic(camera.positionWC, scratch3DTo2DCartographic); - scene.mapProjection.project(scratch3DTo2DCartographic, camera2D.position); + return getElement; +}); - Cartesian3.negate(Cartesian3.UNIT_Z, camera2D.direction); - Cartesian3.clone(Cartesian3.UNIT_Y, camera2D.up); +define('Scene/PerformanceDisplay',[ + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/getTimestamp', + '../Widgets/getElement' + ], function( + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + getTimestamp, + getElement) { + 'use strict'; - var ray = scratch3DTo2DRay; - Cartesian3.clone(camera2D.position2D, ray.origin); - var rayDirection = Cartesian3.clone(camera.directionWC, ray.direction); - var surfacePoint = ellipsoid.scaleToGeodeticSurface(camera.positionWC, scratch3DTo2DSurfacePoint); - var toENU = Transforms.eastNorthUpToFixedFrame(surfacePoint, ellipsoid, scratch3DTo2DToENU); - Matrix4.inverseTransformation(toENU, toENU); - Matrix4.multiplyByPointAsVector(toENU, rayDirection, rayDirection); - Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, rayDirection, rayDirection); + /** + * @private + */ + function PerformanceDisplay(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var globe = scene.globe; - if (defined(globe)) { - var pickedPos = globe.pick(ray, scene, scratch3DTo2DPickPosition); - if (defined(pickedPos)) { - var height = Cartesian3.distance(camera2D.position2D, pickedPos); - pickedPos.x += height; - Cartesian3.clone(pickedPos, camera2D.position2D); - } - } + var container = getElement(options.container); + if (!defined(container)) { + throw new DeveloperError('container is required'); } + + this._container = container; - function updateHeight(camera, height) { - camera.position.x = height; - } + var display = document.createElement('div'); + display.className = 'cesium-performanceDisplay'; + var fpsElement = document.createElement('div'); + fpsElement.className = 'cesium-performanceDisplay-fps'; + this._fpsText = document.createTextNode(''); + fpsElement.appendChild(this._fpsText); + var msElement = document.createElement('div'); + msElement.className = 'cesium-performanceDisplay-ms'; + this._msText = document.createTextNode(''); + msElement.appendChild(this._msText); + display.appendChild(msElement); + display.appendChild(fpsElement); + this._container.appendChild(display); - Matrix4.multiplyByPoint(Camera.TRANSFORM_2D, camera2D.position, camera2D.position2D); - Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, camera2D.direction, camera2D.direction2D); - Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, camera2D.up, camera2D.up2D); + this._lastFpsSampleTime = getTimestamp(); + this._lastMsSampleTime = getTimestamp(); + this._fpsFrameCount = 0; + this._msFrameCount = 0; - var frustum = camera2D.frustum; - frustum.right = camera2D.position.z * 0.5; - frustum.left = -frustum.right; - frustum.top = frustum.right * (scene.drawingBufferHeight / scene.drawingBufferWidth); - frustum.bottom = -frustum.top; + this._throttled = false; + var throttledElement = document.createElement('div'); + throttledElement.className = 'cesium-performanceDisplay-throttled'; + this._throttledText = document.createTextNode(''); + throttledElement.appendChild(this._throttledText); + display.appendChild(throttledElement); + } - var endCamera = scratch3DTo2DEndCamera; - Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, camera2D.position2D, endCamera.position); - Cartesian3.clone(camera2D.direction, endCamera.direction); - Cartesian3.clone(camera2D.up, endCamera.up); - endCamera.frustum = frustum; + defineProperties(PerformanceDisplay.prototype, { + /** + * The display should indicate the FPS is being throttled. + * @memberof PerformanceDisplay.prototype + * + * @type {Boolean} + */ + throttled : { + get : function() { + return this._throttled; + }, + set : function(value) { + if (this._throttled === value) { + return; + } - var complete = complete2DCallback(endCamera); - createMorphHandler(transitioner, complete); + if (value) { + this._throttledText.nodeValue = '(throttled)'; + } else { + this._throttledText.nodeValue = ''; + } - function completeCallback() { - morphPerspectiveToOrthographic(transitioner, duration, camera2D, updateHeight, complete); + this._throttled = value; + } } - morphFrom3DToColumbusView(transitioner, duration, camera2D, completeCallback); - } - - function morphOrthographicToPerspective(transitioner, duration, cameraCV, complete) { - var scene = transitioner._scene; - var camera = scene.camera; + }); - var height = camera.frustum.right - camera.frustum.left; - camera.frustum = cameraCV.frustum.clone(); + /** + * Update the display. This function should only be called once per frame, because + * each call records a frame in the internal buffer and redraws the display. + * + * @param {Boolean} [renderedThisFrame=true] If provided, the FPS count will only update and display if true. + */ + PerformanceDisplay.prototype.update = function(renderedThisFrame) { + var time = getTimestamp(); + var updateDisplay = defaultValue(renderedThisFrame, true); - var endFOV = camera.frustum.fov; - var startFOV = CesiumMath.RADIANS_PER_DEGREE * 0.5; - var d = height * Math.tan(endFOV * 0.5); - camera.frustum.far = d / Math.tan(startFOV * 0.5) + 10000000.0; - camera.frustum.fov = startFOV; + this._fpsFrameCount++; + var fpsElapsedTime = time - this._lastFpsSampleTime; + if (fpsElapsedTime > 1000) { + var fps = 'N/A'; + if (updateDisplay) { + fps = this._fpsFrameCount * 1000 / fpsElapsedTime | 0; + } - function update(value) { - camera.frustum.fov = CesiumMath.lerp(startFOV, endFOV, value.time); - camera.position.z = d / Math.tan(camera.frustum.fov * 0.5); + this._fpsText.nodeValue = fps + ' FPS'; + this._lastFpsSampleTime = time; + this._fpsFrameCount = 0; } - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - update : update, - complete : function() { - complete(transitioner); + + this._msFrameCount++; + var msElapsedTime = time - this._lastMsSampleTime; + if (msElapsedTime > 200) { + var ms = 'N/A'; + if (updateDisplay) { + ms = (msElapsedTime / this._msFrameCount).toFixed(2); } - }); - transitioner._currentTweens.push(tween); - } - function morphFrom2DToColumbusView(transitioner, duration, cameraCV, complete) { - duration *= 0.5; + this._msText.nodeValue = ms + ' MS'; + this._lastMsSampleTime = time; + this._msFrameCount = 0; + } + }; - var scene = transitioner._scene; - var camera = scene.camera; + /** + * Destroys the WebGL resources held by this object. + */ + PerformanceDisplay.prototype.destroy = function() { + return destroyObject(this); + }; - var endPos = Cartesian3.clone(cameraCV.position, scratch3DToCVEndPos); - var endDir = Cartesian3.clone(cameraCV.direction, scratch3DToCVEndDir); - var endUp = Cartesian3.clone(cameraCV.up, scratch3DToCVEndUp); + return PerformanceDisplay; +}); - scene._mode = SceneMode.MORPHING; +define('Scene/PickDepth',[ + '../Core/defined', + '../Core/destroyObject', + '../Core/PixelFormat', + '../Renderer/Framebuffer', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/Texture' + ], function( + defined, + destroyObject, + PixelFormat, + Framebuffer, + PixelDatatype, + RenderState, + Texture) { + 'use strict'; - function morph() { - camera.frustum = cameraCV.frustum.clone(); + /** + * @private + */ + function PickDepth() { + this.framebuffer = undefined; - var startPos = Cartesian3.clone(camera.position, scratch3DToCVStartPos); - var startDir = Cartesian3.clone(camera.direction, scratch3DToCVStartDir); - var startUp = Cartesian3.clone(camera.up, scratch3DToCVStartUp); - startPos.z = endPos.z; + this._depthTexture = undefined; + this._textureToCopy = undefined; + this._copyDepthCommand = undefined; - function update(value) { - columbusViewMorph(startPos, endPos, value.time, camera.position); - columbusViewMorph(startDir, endDir, value.time, camera.direction); - columbusViewMorph(startUp, endUp, value.time, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - } - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 + this._debugPickDepthViewportCommand = undefined; + } + + function executeDebugPickDepth(pickDepth, context, passState) { + if (!defined(pickDepth._debugPickDepthViewportCommand)) { + var fs = + 'uniform sampler2D u_texture;\n' + + 'varying vec2 v_textureCoordinates;\n' + + 'void main()\n' + + '{\n' + + ' float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n' + + ' float n_range = czm_depthRange.near;\n' + + ' float f_range = czm_depthRange.far;\n' + + ' float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n' + + ' float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n' + + ' gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n' + + '}\n'; + + pickDepth._debugPickDepthViewportCommand = context.createViewportQuadCommand(fs, { + uniformMap : { + u_texture : function() { + return pickDepth._depthTexture; + } }, - update : update, - complete : function() { - complete(transitioner); - } + owner : pickDepth }); - transitioner._currentTweens.push(tween); } - if (transitioner._morphToOrthographic) { - morph(); - } else { - morphOrthographicToPerspective(transitioner, 0.0, cameraCV, morph); - } + pickDepth._debugPickDepthViewportCommand.execute(context, passState); } - function morphFrom3DToColumbusView(transitioner, duration, endCamera, complete) { - var scene = transitioner._scene; - var camera = scene.camera; - - var startPos = Cartesian3.clone(camera.position, scratch3DToCVStartPos); - var startDir = Cartesian3.clone(camera.direction, scratch3DToCVStartDir); - var startUp = Cartesian3.clone(camera.up, scratch3DToCVStartUp); + function destroyTextures(pickDepth) { + pickDepth._depthTexture = pickDepth._depthTexture && !pickDepth._depthTexture.isDestroyed() && pickDepth._depthTexture.destroy(); + } - var endPos = Cartesian3.clone(endCamera.position2D, scratch3DToCVEndPos); - var endDir = Cartesian3.clone(endCamera.direction2D, scratch3DToCVEndDir); - var endUp = Cartesian3.clone(endCamera.up2D, scratch3DToCVEndUp); + function destroyFramebuffers(pickDepth) { + pickDepth.framebuffer = pickDepth.framebuffer && !pickDepth.framebuffer.isDestroyed() && pickDepth.framebuffer.destroy(); + } - function update(value) { - columbusViewMorph(startPos, endPos, value.time, camera.position); - columbusViewMorph(startDir, endDir, value.time, camera.direction); - columbusViewMorph(startUp, endUp, value.time, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - camera._adjustOrthographicFrustum(true); - } - var tween = scene.tweens.add({ - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT, - startObject : { - time : 0.0 - }, - stopObject : { - time : 1.0 - }, - update : update, - complete : function() { - addMorphTimeAnimations(transitioner, scene, 1.0, 0.0, duration, complete); - } + function createTextures(pickDepth, context, width, height) { + pickDepth._depthTexture = new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE }); - transitioner._currentTweens.push(tween); } - function addMorphTimeAnimations(transitioner, scene, start, stop, duration, complete) { - // Later, this will be linear and each object will adjust, if desired, in its vertex shader. - var options = { - object : scene, - property : 'morphTime', - startValue : start, - stopValue : stop, - duration : duration, - easingFunction : EasingFunction.QUARTIC_OUT - }; + function createFramebuffers(pickDepth, context, width, height) { + destroyTextures(pickDepth); + destroyFramebuffers(pickDepth); - if (defined(complete)) { - options.complete = function() { - complete(transitioner); - }; - } + createTextures(pickDepth, context, width, height); - var tween = scene.tweens.addProperty(options); - transitioner._currentTweens.push(tween); + pickDepth.framebuffer = new Framebuffer({ + context : context, + colorTextures : [pickDepth._depthTexture], + destroyAttachments : false + }); } - function complete3DCallback(camera3D) { - return function(transitioner) { - var scene = transitioner._scene; - scene._mode = SceneMode.SCENE3D; - scene.morphTime = SceneMode.getMorphTime(SceneMode.SCENE3D); - - destroyMorphHandler(transitioner); - - if (transitioner._previousMode !== SceneMode.MORPHING || transitioner._morphCancelled) { - transitioner._morphCancelled = false; - - var camera = scene.camera; - Cartesian3.clone(camera3D.position, camera.position); - Cartesian3.clone(camera3D.direction, camera.direction); - Cartesian3.clone(camera3D.up, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - - camera.frustum = camera3D.frustum.clone(); - } + function updateFramebuffers(pickDepth, context, depthTexture) { + var width = depthTexture.width; + var height = depthTexture.height; - var wasMorphing = defined(transitioner._completeMorph); - transitioner._completeMorph = undefined; - scene.camera.update(scene.mode); - transitioner._scene.morphComplete.raiseEvent(transitioner, transitioner._previousMode, SceneMode.SCENE3D, wasMorphing); - }; + var texture = pickDepth._depthTexture; + var textureChanged = !defined(texture) || texture.width !== width || texture.height !== height; + if (!defined(pickDepth.framebuffer) || textureChanged) { + createFramebuffers(pickDepth, context, width, height); + } } - function complete2DCallback(camera2D) { - return function(transitioner) { - var scene = transitioner._scene; - - scene._mode = SceneMode.SCENE2D; - scene.morphTime = SceneMode.getMorphTime(SceneMode.SCENE2D); + function updateCopyCommands(pickDepth, context, depthTexture) { + if (!defined(pickDepth._copyDepthCommand)) { + var fs = + 'uniform sampler2D u_texture;\n' + + 'varying vec2 v_textureCoordinates;\n' + + 'void main()\n' + + '{\n' + + ' gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n' + + '}\n'; + pickDepth._copyDepthCommand = context.createViewportQuadCommand(fs, { + renderState : RenderState.fromCache(), + uniformMap : { + u_texture : function() { + return pickDepth._textureToCopy; + } + }, + owner : pickDepth + }); + } - destroyMorphHandler(transitioner); + pickDepth._textureToCopy = depthTexture; + pickDepth._copyDepthCommand.framebuffer = pickDepth.framebuffer; + } - var camera = scene.camera; - Cartesian3.clone(camera2D.position, camera.position); - camera.position.z = scene.mapProjection.ellipsoid.maximumRadius * 2.0; - Cartesian3.clone(camera2D.direction, camera.direction); - Cartesian3.clone(camera2D.up, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - camera.frustum = camera2D.frustum.clone(); + PickDepth.prototype.executeDebugPickDepth = function(context, passState) { + executeDebugPickDepth(this, context, passState); + }; - var wasMorphing = defined(transitioner._completeMorph); - transitioner._completeMorph = undefined; - scene.camera.update(scene.mode); - transitioner._scene.morphComplete.raiseEvent(transitioner, transitioner._previousMode, SceneMode.SCENE2D, wasMorphing); - }; - } + PickDepth.prototype.update = function(context, depthTexture) { + updateFramebuffers(this, context, depthTexture); + updateCopyCommands(this, context, depthTexture); + }; - function completeColumbusViewCallback(cameraCV) { - return function(transitioner) { - var scene = transitioner._scene; - scene._mode = SceneMode.COLUMBUS_VIEW; - scene.morphTime = SceneMode.getMorphTime(SceneMode.COLUMBUS_VIEW); + PickDepth.prototype.executeCopyDepth = function(context, passState) { + this._copyDepthCommand.execute(context, passState); + }; - destroyMorphHandler(transitioner); + PickDepth.prototype.isDestroyed = function() { + return false; + }; - if (transitioner._previousModeMode !== SceneMode.MORPHING || transitioner._morphCancelled) { - transitioner._morphCancelled = false; + PickDepth.prototype.destroy = function() { + destroyTextures(this); + destroyFramebuffers(this); - var camera = scene.camera; - Cartesian3.clone(cameraCV.position, camera.position); - Cartesian3.clone(cameraCV.direction, camera.direction); - Cartesian3.clone(cameraCV.up, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.normalize(camera.right, camera.right); - } + this._copyDepthCommand.shaderProgram = defined(this._copyDepthCommand.shaderProgram) && this._copyDepthCommand.shaderProgram.destroy(); - var wasMorphing = defined(transitioner._completeMorph); - transitioner._completeMorph = undefined; - scene.camera.update(scene.mode); - transitioner._scene.morphComplete.raiseEvent(transitioner, transitioner._previousMode, SceneMode.COLUMBUS_VIEW, wasMorphing); - }; - } + return destroyObject(this); + }; - return SceneTransitioner; + return PickDepth; }); -define('Scene/TweenCollection',[ - '../Core/clone', +define('Scene/PrimitiveCollection',[ + '../Core/createGuid', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/EasingFunction', - '../Core/getTimestamp', - '../Core/TimeConstants', - '../ThirdParty/Tween' + '../Core/destroyObject', + '../Core/DeveloperError' ], function( - clone, + createGuid, defaultValue, defined, defineProperties, - DeveloperError, - EasingFunction, - getTimestamp, - TimeConstants, - TweenJS) { + destroyObject, + DeveloperError) { 'use strict'; /** - * A tween is an animation that interpolates the properties of two objects using an {@link EasingFunction}. Create - * one using {@link Scene#tweens} and {@link TweenCollection#add} and related add functions. + * A collection of primitives. This is most often used with {@link Scene#primitives}, + * but <code>PrimitiveCollection</code> is also a primitive itself so collections can + * be added to collections forming a hierarchy. * - * @alias Tween + * @alias PrimitiveCollection * @constructor * - * @private + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.show=true] Determines if the primitives in the collection will be shown. + * @param {Boolean} [options.destroyPrimitives=true] Determines if primitives in the collection are destroyed when they are removed. + * + * @example + * var billboards = new Cesium.BillboardCollection(); + * var labels = new Cesium.LabelCollection(); + * + * var collection = new Cesium.PrimitiveCollection(); + * collection.add(billboards); + * + * scene.primitives.add(collection); // Add collection + * scene.primitives.add(labels); // Add regular primitive */ - function Tween(tweens, tweenjs, startObject, stopObject, duration, delay, easingFunction, update, complete, cancel) { - this._tweens = tweens; - this._tweenjs = tweenjs; - - this._startObject = clone(startObject); - this._stopObject = clone(stopObject); - - this._duration = duration; - this._delay = delay; - this._easingFunction = easingFunction; + function PrimitiveCollection(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._update = update; - this._complete = complete; + this._primitives = []; + this._guid = createGuid(); /** - * The callback to call if the tween is canceled either because {@link Tween#cancelTween} - * was called or because the tween was removed from the collection. + * Determines if primitives in this collection will be shown. * - * @type {TweenCollection~TweenCancelledCallback} - */ - this.cancel = cancel; - - /** - * @private + * @type {Boolean} + * @default true */ - this.needsStart = true; - } + this.show = defaultValue(options.show, true); - defineProperties(Tween.prototype, { /** - * An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. - * @memberof Tween.prototype + * Determines if primitives in the collection are destroyed when they are removed by + * {@link PrimitiveCollection#destroy} or {@link PrimitiveCollection#remove} or implicitly + * by {@link PrimitiveCollection#removeAll}. * - * @type {Object} - * @readonly - */ - startObject : { - get : function() { - return this._startObject; - } - }, - - /** - * An object with properties for the final values of the tween. - * @memberof Tween.prototype + * @type {Boolean} + * @default true * - * @type {Object} - * @readonly - */ - stopObject : { - get : function() { - return this._stopObject; - } - }, - - /** - * The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @memberof Tween.prototype + * @example + * // Example 1. Primitives are destroyed by default. + * var primitives = new Cesium.PrimitiveCollection(); + * var labels = primitives.add(new Cesium.LabelCollection()); + * primitives = primitives.destroy(); + * var b = labels.isDestroyed(); // true * - * @type {Number} - * @readonly + * @example + * // Example 2. Do not destroy primitives in a collection. + * var primitives = new Cesium.PrimitiveCollection(); + * primitives.destroyPrimitives = false; + * var labels = primitives.add(new Cesium.LabelCollection()); + * primitives = primitives.destroy(); + * var b = labels.isDestroyed(); // false + * labels = labels.destroy(); // explicitly destroy */ - duration : { - get : function() { - return this._duration; - } - }, + this.destroyPrimitives = defaultValue(options.destroyPrimitives, true); + } + defineProperties(PrimitiveCollection.prototype, { /** - * The delay, in seconds, before the tween starts animating. - * @memberof Tween.prototype + * Gets the number of primitives in the collection. + * + * @memberof PrimitiveCollection.prototype * * @type {Number} * @readonly */ - delay : { + length : { get : function() { - return this._delay; + return this._primitives.length; } - }, + } + }); - /** - * Determines the curve for animtion. - * @memberof Tween.prototype - * - * @type {EasingFunction} - * @readonly - */ - easingFunction : { - get : function() { - return this._easingFunction; - } - }, + /** + * Adds a primitive to the collection. + * + * @param {Object} primitive The primitive to add. + * @returns {Object} The primitive added to the collection. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * var billboards = scene.primitives.add(new Cesium.BillboardCollection()); + */ + PrimitiveCollection.prototype.add = function(primitive) { + if (!defined(primitive)) { + throw new DeveloperError('primitive is required.'); + } + + var external = (primitive._external = primitive._external || {}); + var composites = (external._composites = external._composites || {}); + composites[this._guid] = { + collection : this + }; - /** - * The callback to call at each animation update (usually tied to the a rendered frame). - * @memberof Tween.prototype - * - * @type {TweenCollection~TweenUpdateCallback} - * @readonly - */ - update : { - get : function() { - return this._update; - } - }, + this._primitives.push(primitive); - /** - * The callback to call when the tween finishes animating. - * @memberof Tween.prototype - * - * @type {TweenCollection~TweenCompleteCallback} - * @readonly - */ - complete : { - get : function() { - return this._complete; - } - }, + return primitive; + }; - /** - * @memberof Tween.prototype - * - * @private - */ - tweenjs : { - get : function() { - return this._tweenjs; + /** + * Removes a primitive from the collection. + * + * @param {Object} [primitive] The primitive to remove. + * @returns {Boolean} <code>true</code> if the primitive was removed; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * var billboards = scene.primitives.add(new Cesium.BillboardCollection()); + * scene.primitives.remove(p); // Returns true + * + * @see PrimitiveCollection#destroyPrimitives + */ + PrimitiveCollection.prototype.remove = function(primitive) { + // PERFORMANCE_IDEA: We can obviously make this a lot faster. + if (this.contains(primitive)) { + var index = this._primitives.indexOf(primitive); + if (index !== -1) { + this._primitives.splice(index, 1); + + delete primitive._external._composites[this._guid]; + + if (this.destroyPrimitives) { + primitive.destroy(); + } + + return true; } + // else ... this is not possible, I swear. } - }); + + return false; + }; /** - * Cancels the tween calling the {@link Tween#cancel} callback if one exists. This - * has no effect if the tween finished or was already canceled. + * Removes and destroys a primitive, regardless of destroyPrimitives setting. + * @private */ - Tween.prototype.cancelTween = function() { - this._tweens.remove(this); + PrimitiveCollection.prototype.removeAndDestroy = function(primitive) { + var removed = this.remove(primitive); + if (removed && !this.destroyPrimitives) { + primitive.destroy(); + } + return removed; }; /** - * A collection of tweens for animating properties. Commonly accessed using {@link Scene#tweens}. + * Removes all primitives in the collection. * - * @alias TweenCollection - * @constructor + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * - * @private + * @see PrimitiveCollection#destroyPrimitives */ - function TweenCollection() { - this._tweens = []; - } - - defineProperties(TweenCollection.prototype, { - /** - * The number of tweens in the collection. - * @memberof TweenCollection.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._tweens.length; + PrimitiveCollection.prototype.removeAll = function() { + if (this.destroyPrimitives) { + var primitives = this._primitives; + var length = primitives.length; + for ( var i = 0; i < length; ++i) { + primitives[i].destroy(); } } - }); + this._primitives = []; + }; /** - * Creates a tween for animating between two sets of properties. The tween starts animating at the next call to {@link TweenCollection#update}, which - * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * Determines if this collection contains a primitive. * - * @param {Object} [options] Object with the following properties: - * @param {Object} options.startObject An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. - * @param {Object} options.stopObject An object with properties for the final values of the tween. - * @param {Number} options.duration The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. - * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. - * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). - * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. - * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. - * @returns {Tween} The tween. + * @param {Object} [primitive] The primitive to check for. + * @returns {Boolean} <code>true</code> if the primitive is in the collection; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. * - * @exception {DeveloperError} options.duration must be positive. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see PrimitiveCollection#get */ - TweenCollection.prototype.add = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - if (!defined(options.startObject) || !defined(options.stopObject)) { - throw new DeveloperError('options.startObject and options.stopObject are required.'); - } + PrimitiveCollection.prototype.contains = function(primitive) { + return !!(defined(primitive) && + primitive._external && + primitive._external._composites && + primitive._external._composites[this._guid]); + }; - if (!defined(options.duration) || options.duration < 0.0) { - throw new DeveloperError('options.duration is required and must be positive.'); + function getPrimitiveIndex(compositePrimitive, primitive) { + if (!compositePrimitive.contains(primitive)) { + throw new DeveloperError('primitive is not in this collection.'); } - if (options.duration === 0.0) { - if (defined(options.complete)) { - options.complete(); + return compositePrimitive._primitives.indexOf(primitive); + } + + /** + * Raises a primitive "up one" in the collection. If all primitives in the collection are drawn + * on the globe surface, this visually moves the primitive up one. + * + * @param {Object} [primitive] The primitive to raise. + * + * @exception {DeveloperError} primitive is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see PrimitiveCollection#raiseToTop + * @see PrimitiveCollection#lower + * @see PrimitiveCollection#lowerToBottom + */ + PrimitiveCollection.prototype.raise = function(primitive) { + if (defined(primitive)) { + var index = getPrimitiveIndex(this, primitive); + var primitives = this._primitives; + + if (index !== primitives.length - 1) { + var p = primitives[index]; + primitives[index] = primitives[index + 1]; + primitives[index + 1] = p; } - return new Tween(this); } + }; - var duration = options.duration / TimeConstants.SECONDS_PER_MILLISECOND; - var delayInSeconds = defaultValue(options.delay, 0.0); - var delay = delayInSeconds / TimeConstants.SECONDS_PER_MILLISECOND; - var easingFunction = defaultValue(options.easingFunction, EasingFunction.LINEAR_NONE); + /** + * Raises a primitive to the "top" of the collection. If all primitives in the collection are drawn + * on the globe surface, this visually moves the primitive to the top. + * + * @param {Object} [primitive] The primitive to raise the top. + * + * @exception {DeveloperError} primitive is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see PrimitiveCollection#raise + * @see PrimitiveCollection#lower + * @see PrimitiveCollection#lowerToBottom + */ + PrimitiveCollection.prototype.raiseToTop = function(primitive) { + if (defined(primitive)) { + var index = getPrimitiveIndex(this, primitive); + var primitives = this._primitives; - var value = options.startObject; - var tweenjs = new TweenJS.Tween(value); - tweenjs.to(clone(options.stopObject), duration); - tweenjs.delay(delay); - tweenjs.easing(easingFunction); - if (defined(options.update)) { - tweenjs.onUpdate(function() { - options.update(value); - }); + if (index !== primitives.length - 1) { + // PERFORMANCE_IDEA: Could be faster + primitives.splice(index, 1); + primitives.push(primitive); + } } - tweenjs.onComplete(defaultValue(options.complete, null)); - tweenjs.repeat(defaultValue(options._repeat, 0.0)); - - var tween = new Tween(this, tweenjs, options.startObject, options.stopObject, options.duration, delayInSeconds, easingFunction, options.update, options.complete, options.cancel); - this._tweens.push(tween); - return tween; }; /** - * Creates a tween for animating a scalar property on the given object. The tween starts animating at the next call to {@link TweenCollection#update}, which - * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * Lowers a primitive "down one" in the collection. If all primitives in the collection are drawn + * on the globe surface, this visually moves the primitive down one. * - * @param {Object} [options] Object with the following properties: - * @param {Object} options.object The object containing the property to animate. - * @param {String} options.property The name of the property to animate. - * @param {Number} options.startValue The initial value. - * @param {Number} options.stopValue The final value. - * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. - * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. - * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). - * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. - * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. - * @returns {Tween} The tween. + * @param {Object} [primitive] The primitive to lower. * - * @exception {DeveloperError} options.object must have the specified property. - * @exception {DeveloperError} options.duration must be positive. + * @exception {DeveloperError} primitive is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see PrimitiveCollection#lowerToBottom + * @see PrimitiveCollection#raise + * @see PrimitiveCollection#raiseToTop */ - TweenCollection.prototype.addProperty = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var object = options.object; - var property = options.property; - var startValue = options.startValue; - var stopValue = options.stopValue; + PrimitiveCollection.prototype.lower = function(primitive) { + if (defined(primitive)) { + var index = getPrimitiveIndex(this, primitive); + var primitives = this._primitives; - if (!defined(object) || !defined(options.property)) { - throw new DeveloperError('options.object and options.property are required.'); - } - if (!defined(object[property])) { - throw new DeveloperError('options.object must have the specified property.'); - } - if (!defined(startValue) || !defined(stopValue)) { - throw new DeveloperError('options.startValue and options.stopValue are required.'); - } - - function update(value) { - object[property] = value.value; + if (index !== 0) { + var p = primitives[index]; + primitives[index] = primitives[index - 1]; + primitives[index - 1] = p; + } } - - return this.add({ - startObject : { - value : startValue - }, - stopObject : { - value : stopValue - }, - duration : defaultValue(options.duration, 3.0), - delay : options.delay, - easingFunction : options.easingFunction, - update : update, - complete : options.complete, - cancel : options.cancel, - _repeat : options._repeat - }); }; /** - * Creates a tween for animating the alpha of all color uniforms on a {@link Material}. The tween starts animating at the next call to {@link TweenCollection#update}, which - * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * Lowers a primitive to the "bottom" of the collection. If all primitives in the collection are drawn + * on the globe surface, this visually moves the primitive to the bottom. * - * @param {Object} [options] Object with the following properties: - * @param {Material} options.material The material to animate. - * @param {Number} [options.startValue=0.0] The initial alpha value. - * @param {Number} [options.stopValue=1.0] The final alpha value. - * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. - * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. - * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). - * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. - * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. - * @returns {Tween} The tween. + * @param {Object} [primitive] The primitive to lower to the bottom. * - * @exception {DeveloperError} material has no properties with alpha components. - * @exception {DeveloperError} options.duration must be positive. + * @exception {DeveloperError} primitive is not in this collection. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see PrimitiveCollection#lower + * @see PrimitiveCollection#raise + * @see PrimitiveCollection#raiseToTop */ - TweenCollection.prototype.addAlpha = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + PrimitiveCollection.prototype.lowerToBottom = function(primitive) { + if (defined(primitive)) { + var index = getPrimitiveIndex(this, primitive); + var primitives = this._primitives; - var material = options.material; + if (index !== 0) { + // PERFORMANCE_IDEA: Could be faster + primitives.splice(index, 1); + primitives.unshift(primitive); + } + } + }; - if (!defined(material)) { - throw new DeveloperError('options.material is required.'); + /** + * Returns the primitive in the collection at the specified index. + * + * @param {Number} index The zero-based index of the primitive to return. + * @returns {Object} The primitive at the <code>index</code>. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * // Toggle the show property of every primitive in the collection. + * var primitives = scene.primitives; + * var length = primitives.length; + * for (var i = 0; i < length; ++i) { + * var p = primitives.get(i); + * p.show = !p.show; + * } + * + * @see PrimitiveCollection#length + */ + PrimitiveCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); } - var properties = []; + return this._primitives[index]; + }; - for (var property in material.uniforms) { - if (material.uniforms.hasOwnProperty(property) && - defined(material.uniforms[property]) && - defined(material.uniforms[property].alpha)) { - properties.push(property); - } + /** + * @private + */ + PrimitiveCollection.prototype.update = function(frameState) { + if (!this.show) { + return; } - if (properties.length === 0) { - throw new DeveloperError('material has no properties with alpha components.'); - } - - function update(value) { - var length = properties.length; - for (var i = 0; i < length; ++i) { - material.uniforms[properties[i]].alpha = value.alpha; - } + var primitives = this._primitives; + // Using primitives.length in the loop is a temporary workaround + // to allow quadtree updates to add and remove primitives in + // update(). This will be changed to manage added and removed lists. + for (var i = 0; i < primitives.length; ++i) { + primitives[i].update(frameState); } + }; - return this.add({ - startObject : { - alpha : defaultValue(options.startValue, 0.0) // Default to fade in - }, - stopObject : { - alpha : defaultValue(options.stopValue, 1.0) - }, - duration : defaultValue(options.duration, 3.0), - delay : options.delay, - easingFunction : options.easingFunction, - update : update, - complete : options.complete, - cancel : options.cancel - }); + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see PrimitiveCollection#destroy + */ + PrimitiveCollection.prototype.isDestroyed = function() { + return false; }; /** - * Creates a tween for animating the offset uniform of a {@link Material}. The tween starts animating at the next call to {@link TweenCollection#update}, which - * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * Destroys the WebGL resources held by each primitive in this collection. Explicitly destroying this + * collection allows for deterministic release of WebGL resources, instead of relying on the garbage + * collector to destroy this collection. + * <br /><br /> + * Since destroying a collection destroys all the contained primitives, only destroy a collection + * when you are sure no other code is still using any of the contained primitives. + * <br /><br /> + * Once this collection is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. * - * @param {Object} [options] Object with the following properties: - * @param {Material} options.material The material to animate. - * @param {Number} options.startValue The initial alpha value. - * @param {Number} options.stopValue The final alpha value. - * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. - * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. - * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). - * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. - * @returns {Tween} The tween. + * @returns {undefined} * - * @exception {DeveloperError} material.uniforms must have an offset property. - * @exception {DeveloperError} options.duration must be positive. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * primitives = primitives && primitives.destroy(); + * + * @see PrimitiveCollection#isDestroyed + */ + PrimitiveCollection.prototype.destroy = function() { + this.removeAll(); + return destroyObject(this); + }; + + return PrimitiveCollection; +}); + +define('Scene/QuadtreeTileProvider',[ + '../Core/defineProperties', + '../Core/DeveloperError' + ], function( + defineProperties, + DeveloperError) { + 'use strict'; + + /** + * Provides general quadtree tiles to be displayed on or near the surface of an ellipsoid. It is intended to be + * used with the {@link QuadtreePrimitive}. This type describes an interface and is not intended to be + * instantiated directly. + * + * @alias QuadtreeTileProvider + * @constructor + * @private + */ + function QuadtreeTileProvider() { + DeveloperError.throwInstantiationError(); + } + + /** + * Computes the default geometric error for level zero of the quadtree. + * + * @memberof QuadtreeTileProvider + * + * @param {TilingScheme} tilingScheme The tiling scheme for which to compute the geometric error. + * @returns {Number} The maximum geometric error at level zero, in meters. */ - TweenCollection.prototype.addOffsetIncrement = function(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + QuadtreeTileProvider.computeDefaultLevelZeroMaximumGeometricError = function(tilingScheme) { + return tilingScheme.ellipsoid.maximumRadius * 2 * Math.PI * 0.25 / (65 * tilingScheme.getNumberOfXTilesAtLevel(0)); + }; - var material = options.material; + defineProperties(QuadtreeTileProvider.prototype, { + /** + * Gets or sets the {@link QuadtreePrimitive} for which this provider is + * providing tiles. + * @memberof QuadtreeTileProvider.prototype + * @type {QuadtreePrimitive} + */ + quadtree : { + get : DeveloperError.throwInstantiationError, + set : DeveloperError.throwInstantiationError + }, - if (!defined(material)) { - throw new DeveloperError('material is required.'); - } - if (!defined(material.uniforms.offset)) { - throw new DeveloperError('material.uniforms must have an offset property.'); + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof QuadtreeTileProvider.prototype + * @type {Boolean} + */ + ready : { + get : DeveloperError.throwInstantiationError + }, + + /** + * Gets the tiling scheme used by the provider. This property should + * not be accessed before {@link QuadtreeTileProvider#ready} returns true. + * @memberof QuadtreeTileProvider.prototype + * @type {TilingScheme} + */ + tilingScheme : { + get : DeveloperError.throwInstantiationError + }, + + /** + * Gets an event that is raised when the geometry provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof QuadtreeTileProvider.prototype + * @type {Event} + */ + errorEvent : { + get : DeveloperError.throwInstantiationError } - - var uniforms = material.uniforms; - return this.addProperty({ - object : uniforms, - property : 'offset', - startValue : uniforms.offset, - stopValue : uniforms.offset + 1, - duration : options.duration, - delay : options.delay, - easingFunction : options.easingFunction, - update : options.update, - cancel : options.cancel, - _repeat : Infinity - }); - }; + }); /** - * Removes a tween from the collection. - * <p> - * This calls the {@link Tween#cancel} callback if the tween has one. - * </p> + * Called at the beginning of the update cycle, regardless of id a new frame is being rendered, before {@link QuadtreeTileProvider#beginUpdate} + * @memberof QuadtreeTileProvider + * @function * - * @param {Tween} tween The tween to remove. - * @returns {Boolean} <code>true</code> if the tween was removed; <code>false</code> if the tween was not found in the collection. + * @param {Context} context The rendering context. + * @param {FrameState} frameState The frame state. */ - TweenCollection.prototype.remove = function(tween) { - if (!defined(tween)) { - return false; - } - - var index = this._tweens.indexOf(tween); - if (index !== -1) { - tween.tweenjs.stop(); - if (defined(tween.cancel)) { - tween.cancel(); - } - this._tweens.splice(index, 1); - return true; - } - - return false; - }; + QuadtreeTileProvider.prototype.update = DeveloperError.throwInstantiationError; /** - * Removes all tweens from the collection. - * <p> - * This calls the {@link Tween#cancel} callback for each tween that has one. - * </p> + * Called at the beginning of the update cycle for each render frame, before {@link QuadtreeTileProvider#showTileThisFrame} + * or any other functions. + * @memberof QuadtreeTileProvider + * @function + * + * @param {Context} context The rendering context. + * @param {FrameState} frameState The frame state. + * @param {DrawCommand[]} commandList An array of rendering commands. This method may push + * commands into this array. */ - TweenCollection.prototype.removeAll = function() { - var tweens = this._tweens; - - for (var i = 0; i < tweens.length; ++i) { - var tween = tweens[i]; - tween.tweenjs.stop(); - if (defined(tween.cancel)) { - tween.cancel(); - } - } - tweens.length = 0; - }; + QuadtreeTileProvider.prototype.beginUpdate = DeveloperError.throwInstantiationError; /** - * Determines whether this collection contains a given tween. + * Called at the end of the update cycle for each render frame, after {@link QuadtreeTileProvider#showTileThisFrame} + * and any other functions. + * @memberof QuadtreeTileProvider + * @function * - * @param {Tween} tween The tween to check for. - * @returns {Boolean} <code>true</code> if this collection contains the tween, <code>false</code> otherwise. + * @param {Context} context The rendering context. + * @param {FrameState} frameState The frame state. + * @param {DrawCommand[]} commandList An array of rendering commands. This method may push + * commands into this array. */ - TweenCollection.prototype.contains = function(tween) { - return defined(tween) && (this._tweens.indexOf(tween) !== -1); - }; + QuadtreeTileProvider.prototype.endUpdate = DeveloperError.throwInstantiationError; /** - * Returns the tween in the collection at the specified index. Indices are zero-based - * and increase as tweens are added. Removing a tween shifts all tweens after - * it to the left, changing their indices. This function is commonly used to iterate over - * all the tween in the collection. + * Gets the maximum geometric error allowed in a tile at a given level, in meters. This function should not be + * called before {@link QuadtreeTileProvider#ready} returns true. * - * @param {Number} index The zero-based index of the tween. - * @returns {Tween} The tween at the specified index. + * @see QuadtreeTileProvider#computeDefaultLevelZeroMaximumGeometricError * - * @example - * // Output the duration of all the tweens in the collection. - * var tweens = scene.tweens; - * var length = tweens.length; - * for (var i = 0; i < length; ++i) { - * console.log(tweens.get(i).duration); - * } + * @memberof QuadtreeTileProvider + * @function + * + * @param {Number} level The tile level for which to get the maximum geometric error. + * @returns {Number} The maximum geometric error in meters. */ - TweenCollection.prototype.get = function(index) { - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - - return this._tweens[index]; - }; + QuadtreeTileProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; /** - * Updates the tweens in the collection to be at the provide time. When a tween finishes, it is removed - * from the collection. + * Loads, or continues loading, a given tile. This function will continue to be called + * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}. This function should + * not be called before {@link QuadtreeTileProvider#ready} returns true. * - * @param {Number} [time=getTimestamp()] The time in seconds. By default tweens are synced to the system clock. + * @memberof QuadtreeTileProvider + * @function + * + * @param {Context} context The rendering context. + * @param {FrameState} frameState The frame state. + * @param {QuadtreeTile} tile The tile to load. + * + * @exception {DeveloperError} <code>loadTile</code> must not be called before the tile provider is ready. */ - TweenCollection.prototype.update = function(time) { - var tweens = this._tweens; + QuadtreeTileProvider.prototype.loadTile = DeveloperError.throwInstantiationError; - var i = 0; - time = defined(time) ? time / TimeConstants.SECONDS_PER_MILLISECOND : getTimestamp(); - while (i < tweens.length) { - var tween = tweens[i]; - var tweenjs = tween.tweenjs; + /** + * Determines the visibility of a given tile. The tile may be fully visible, partially visible, or not + * visible at all. Tiles that are renderable and are at least partially visible will be shown by a call + * to {@link QuadtreeTileProvider#showTileThisFrame}. + * + * @memberof QuadtreeTileProvider + * + * @param {QuadtreeTile} tile The tile instance. + * @param {FrameState} frameState The state information about the current frame. + * @param {QuadtreeOccluders} occluders The objects that may occlude this tile. + * + * @returns {Visibility} The visibility of the tile. + */ + QuadtreeTileProvider.prototype.computeTileVisibility = DeveloperError.throwInstantiationError; - if (tween.needsStart) { - tween.needsStart = false; - tweenjs.start(time); - } else if (tweenjs.update(time)) { - i++; - } else { - tweenjs.stop(); - tweens.splice(i, 1); - } - } - }; + /** + * Shows a specified tile in this frame. The provider can cause the tile to be shown by adding + * render commands to the commandList, or use any other method as appropriate. The tile is not + * expected to be visible next frame as well, unless this method is call next frame, too. + * + * @memberof QuadtreeTileProvider + * @function + * + * @param {QuadtreeTile} tile The tile instance. + * @param {Context} context The rendering context. + * @param {FrameState} frameState The state information of the current rendering frame. + * @param {DrawCommand[]} commandList The list of rendering commands. This method may add additional commands to this list. + */ + QuadtreeTileProvider.prototype.showTileThisFrame = DeveloperError.throwInstantiationError; /** - * A function that will execute when a tween completes. - * @callback TweenCollection~TweenCompleteCallback + * Gets the distance from the camera to the closest point on the tile. This is used for level-of-detail selection. + * + * @memberof QuadtreeTileProvider + * @function + * + * @param {QuadtreeTile} tile The tile instance. + * @param {FrameState} frameState The state information of the current rendering frame. + * + * @returns {Number} The distance from the camera to the closest point on the tile, in meters. */ + QuadtreeTileProvider.prototype.computeDistanceToTile = DeveloperError.throwInstantiationError; /** - * A function that will execute when a tween updates. - * @callback TweenCollection~TweenUpdateCallback + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @memberof QuadtreeTileProvider + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see QuadtreeTileProvider#destroy */ + QuadtreeTileProvider.prototype.isDestroyed = DeveloperError.throwInstantiationError; /** - * A function that will execute when a tween is cancelled. - * @callback TweenCollection~TweenCancelledCallback + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @memberof QuadtreeTileProvider + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * provider = provider && provider(); + * + * @see QuadtreeTileProvider#isDestroyed */ + QuadtreeTileProvider.prototype.destroy = DeveloperError.throwInstantiationError; - return TweenCollection; + return QuadtreeTileProvider; }); -define('Scene/ScreenSpaceCameraController',[ - '../Core/Cartesian2', +define('Scene/SceneTransitioner',[ '../Core/Cartesian3', - '../Core/Cartesian4', '../Core/Cartographic', - '../Core/defaultValue', + '../Core/Check', '../Core/defined', '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Ellipsoid', - '../Core/HeadingPitchRoll', - '../Core/IntersectionTests', - '../Core/isArray', - '../Core/KeyboardEventModifier', + '../Core/EasingFunction', '../Core/Math', - '../Core/Matrix3', '../Core/Matrix4', '../Core/OrthographicFrustum', - '../Core/Plane', - '../Core/Quaternion', + '../Core/OrthographicOffCenterFrustum', + '../Core/PerspectiveFrustum', '../Core/Ray', + '../Core/ScreenSpaceEventHandler', + '../Core/ScreenSpaceEventType', '../Core/Transforms', - './CameraEventAggregator', - './CameraEventType', - './MapMode2D', - './SceneMode', - './SceneTransforms', - './TweenCollection' + './Camera', + './SceneMode' ], function( - Cartesian2, Cartesian3, - Cartesian4, Cartographic, - defaultValue, + Check, defined, destroyObject, - DeveloperError, - Ellipsoid, - HeadingPitchRoll, - IntersectionTests, - isArray, - KeyboardEventModifier, + EasingFunction, CesiumMath, - Matrix3, Matrix4, OrthographicFrustum, - Plane, - Quaternion, + OrthographicOffCenterFrustum, + PerspectiveFrustum, Ray, + ScreenSpaceEventHandler, + ScreenSpaceEventType, Transforms, - CameraEventAggregator, - CameraEventType, - MapMode2D, - SceneMode, - SceneTransforms, - TweenCollection) { + Camera, + SceneMode) { 'use strict'; /** - * Modifies the camera position and orientation based on mouse input to a canvas. - * @alias ScreenSpaceCameraController - * @constructor - * - * @param {Scene} scene The scene. + * @private */ - function ScreenSpaceCameraController(scene) { - if (!defined(scene)) { - throw new DeveloperError('scene is required.'); - } + function SceneTransitioner(scene) { + Check.typeOf.object('scene', scene); - /** - * If true, inputs are allowed conditionally with the flags enableTranslate, enableZoom, - * enableRotate, enableTilt, and enableLook. If false, all inputs are disabled. - * - * NOTE: This setting is for temporary use cases, such as camera flights and - * drag-selection of regions (see Picking demo). It is typically set to false at the - * start of such events, and set true on completion. To keep inputs disabled - * past the end of camera flights, you must use the other booleans (enableTranslate, - * enableZoom, enableRotate, enableTilt, and enableLook). - * @type {Boolean} - * @default true - */ - this.enableInputs = true; - /** - * If true, allows the user to pan around the map. If false, the camera stays locked at the current position. - * This flag only applies in 2D and Columbus view modes. - * @type {Boolean} - * @default true - */ - this.enableTranslate = true; - /** - * If true, allows the user to zoom in and out. If false, the camera is locked to the current distance from the ellipsoid. - * @type {Boolean} - * @default true - */ - this.enableZoom = true; - /** - * If true, allows the user to rotate the camera. If false, the camera is locked to the current heading. - * This flag only applies in 2D and 3D. - * @type {Boolean} - * @default true - */ - this.enableRotate = true; - /** - * If true, allows the user to tilt the camera. If false, the camera is locked to the current heading. - * This flag only applies in 3D and Columbus view. - * @type {Boolean} - * @default true - */ - this.enableTilt = true; - /** - * If true, allows the user to use free-look. If false, the camera view direction can only be changed through translating - * or rotating. This flag only applies in 3D and Columbus view modes. - * @type {Boolean} - * @default true - */ - this.enableLook = true; - /** - * A parameter in the range <code>[0, 1)</code> used to determine how long - * the camera will continue to spin because of inertia. - * With value of zero, the camera will have no inertia. - * @type {Number} - * @default 0.9 - */ - this.inertiaSpin = 0.9; - /** - * A parameter in the range <code>[0, 1)</code> used to determine how long - * the camera will continue to translate because of inertia. - * With value of zero, the camera will have no inertia. - * @type {Number} - * @default 0.9 - */ - this.inertiaTranslate = 0.9; - /** - * A parameter in the range <code>[0, 1)</code> used to determine how long - * the camera will continue to zoom because of inertia. - * With value of zero, the camera will have no inertia. - * @type {Number} - * @default 0.8 - */ - this.inertiaZoom = 0.8; - /** - * A parameter in the range <code>[0, 1)</code> used to limit the range - * of various user inputs to a percentage of the window width/height per animation frame. - * This helps keep the camera under control in low-frame-rate situations. - * @type {Number} - * @default 0.1 - */ - this.maximumMovementRatio = 0.1; - /** - * Sets the duration, in seconds, of the bounce back animations in 2D and Columbus view. - * @type {Number} - * @default 3.0 - */ - this.bounceAnimationTime = 3.0; - /** - * The minimum magnitude, in meters, of the camera position when zooming. Defaults to 1.0. - * @type {Number} - * @default 1.0 - */ - this.minimumZoomDistance = 1.0; - /** - * The maximum magnitude, in meters, of the camera position when zooming. Defaults to positive infinity. - * @type {Number} - * @default {@link Number.POSITIVE_INFINITY} - */ - this.maximumZoomDistance = Number.POSITIVE_INFINITY; - /** - * The input that allows the user to pan around the map. This only applies in 2D and Columbus view modes. - * <p> - * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> - * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, - * or an array of any of the preceding. - * </p> - * @type {CameraEventType|Array|undefined} - * @default {@link CameraEventType.LEFT_DRAG} - */ - this.translateEventTypes = CameraEventType.LEFT_DRAG; - /** - * The input that allows the user to zoom in/out. - * <p> - * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> - * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, - * or an array of any of the preceding. - * </p> - * @type {CameraEventType|Array|undefined} - * @default [{@link CameraEventType.RIGHT_DRAG}, {@link CameraEventType.WHEEL}, {@link CameraEventType.PINCH}] - */ - this.zoomEventTypes = [CameraEventType.RIGHT_DRAG, CameraEventType.WHEEL, CameraEventType.PINCH]; - /** - * The input that allows the user to rotate around the globe or another object. This only applies in 3D and Columbus view modes. - * <p> - * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> - * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, - * or an array of any of the preceding. - * </p> - * @type {CameraEventType|Array|undefined} - * @default {@link CameraEventType.LEFT_DRAG} - */ - this.rotateEventTypes = CameraEventType.LEFT_DRAG; - /** - * The input that allows the user to tilt in 3D and Columbus view or twist in 2D. - * <p> - * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> - * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, - * or an array of any of the preceding. - * </p> - * @type {CameraEventType|Array|undefined} - * @default [{@link CameraEventType.MIDDLE_DRAG}, {@link CameraEventType.PINCH}, { - * eventType : {@link CameraEventType.LEFT_DRAG}, - * modifier : {@link KeyboardEventModifier.CTRL} - * }, { - * eventType : {@link CameraEventType.RIGHT_DRAG}, - * modifier : {@link KeyboardEventModifier.CTRL} - * }] - */ - this.tiltEventTypes = [CameraEventType.MIDDLE_DRAG, CameraEventType.PINCH, { - eventType : CameraEventType.LEFT_DRAG, - modifier : KeyboardEventModifier.CTRL - }, { - eventType : CameraEventType.RIGHT_DRAG, - modifier : KeyboardEventModifier.CTRL - }]; - /** - * The input that allows the user to change the direction the camera is viewing. This only applies in 3D and Columbus view modes. - * <p> - * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> - * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, - * or an array of any of the preceding. - * </p> - * @type {CameraEventType|Array|undefined} - * @default { eventType : {@link CameraEventType.LEFT_DRAG}, modifier : {@link KeyboardEventModifier.SHIFT} } - */ - this.lookEventTypes = { - eventType : CameraEventType.LEFT_DRAG, - modifier : KeyboardEventModifier.SHIFT - }; - /** - * The minimum height the camera must be before picking the terrain instead of the ellipsoid. - * @type {Number} - * @default 150000.0 - */ - this.minimumPickingTerrainHeight = 150000.0; - this._minimumPickingTerrainHeight = this.minimumPickingTerrainHeight; - /** - * The minimum height the camera must be before testing for collision with terrain. - * @type {Number} - * @default 10000.0 - */ - this.minimumCollisionTerrainHeight = 15000.0; - this._minimumCollisionTerrainHeight = this.minimumCollisionTerrainHeight; - /** - * The minimum height the camera must be before switching from rotating a track ball to - * free look when clicks originate on the sky on in space. - * @type {Number} - * @default 7500000.0 - */ - this.minimumTrackBallHeight = 7500000.0; - this._minimumTrackBallHeight = this.minimumTrackBallHeight; - /** - * Enables or disables camera collision detection with terrain. - * @type {Boolean} - * @default true - */ - this.enableCollisionDetection = true; - this._scene = scene; - this._globe = undefined; - this._ellipsoid = undefined; - - this._aggregator = new CameraEventAggregator(scene.canvas); - - this._lastInertiaSpinMovement = undefined; - this._lastInertiaZoomMovement = undefined; - this._lastInertiaTranslateMovement = undefined; - this._lastInertiaTiltMovement = undefined; - - this._tweens = new TweenCollection(); - this._tween = undefined; - - this._horizontalRotationAxis = undefined; - - this._tiltCenterMousePosition = new Cartesian2(-1.0, -1.0); - this._tiltCenter = new Cartesian3(); - this._rotateMousePosition = new Cartesian2(-1.0, -1.0); - this._rotateStartPosition = new Cartesian3(); - this._strafeStartPosition = new Cartesian3(); - this._zoomMouseStart = new Cartesian2(-1.0, -1.0); - this._zoomWorldPosition = new Cartesian3(); - this._useZoomWorldPosition = false; - this._tiltCVOffMap = false; - this._looking = false; - this._rotating = false; - this._strafing = false; - this._zoomingOnVector = false; - this._rotatingZoom = false; - - var projection = scene.mapProjection; - this._maxCoord = projection.project(new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO)); - - // Constants, Make any of these public? - this._zoomFactor = 5.0; - this._rotateFactor = undefined; - this._rotateRateRangeAdjustment = undefined; - this._maximumRotateRate = 1.77; - this._minimumRotateRate = 1.0 / 5000.0; - this._minimumZoomRate = 20.0; - this._maximumZoomRate = 5906376272000.0; // distance from the Sun to Pluto in meters. - } - - function decay(time, coefficient) { - if (time < 0) { - return 0.0; - } - - var tau = (1.0 - coefficient) * 25.0; - return Math.exp(-tau * time); - } - - function sameMousePosition(movement) { - return Cartesian2.equalsEpsilon(movement.startPosition, movement.endPosition, CesiumMath.EPSILON14); + this._currentTweens = []; + this._morphHandler = undefined; + this._morphCancelled = false; + this._completeMorph = undefined; + this._morphToOrthographic = false; } - // If the time between mouse down and mouse up is not between - // these thresholds, the camera will not move with inertia. - // This value is probably dependent on the browser and/or the - // hardware. Should be investigated further. - var inertiaMaxClickTimeThreshold = 0.4; - - function maintainInertia(aggregator, type, modifier, decayCoef, action, object, lastMovementName) { - var movementState = object[lastMovementName]; - if (!defined(movementState)) { - movementState = object[lastMovementName] = { - startPosition : new Cartesian2(), - endPosition : new Cartesian2(), - motion : new Cartesian2(), - active : false - }; + SceneTransitioner.prototype.completeMorph = function() { + if (defined(this._completeMorph)) { + this._completeMorph(); } + }; - var ts = aggregator.getButtonPressTime(type, modifier); - var tr = aggregator.getButtonReleaseTime(type, modifier); - - var threshold = ts && tr && ((tr.getTime() - ts.getTime()) / 1000.0); - var now = new Date(); - var fromNow = tr && ((now.getTime() - tr.getTime()) / 1000.0); - - if (ts && tr && threshold < inertiaMaxClickTimeThreshold) { - var d = decay(fromNow, decayCoef); - - if (!movementState.active) { - var lastMovement = aggregator.getLastMovement(type, modifier); - if (!defined(lastMovement) || sameMousePosition(lastMovement)) { - return; - } - - movementState.motion.x = (lastMovement.endPosition.x - lastMovement.startPosition.x) * 0.5; - movementState.motion.y = (lastMovement.endPosition.y - lastMovement.startPosition.y) * 0.5; - - movementState.startPosition = Cartesian2.clone(lastMovement.startPosition, movementState.startPosition); - - movementState.endPosition = Cartesian2.multiplyByScalar(movementState.motion, d, movementState.endPosition); - movementState.endPosition = Cartesian2.add(movementState.startPosition, movementState.endPosition, movementState.endPosition); - - movementState.active = true; - } else { - movementState.startPosition = Cartesian2.clone(movementState.endPosition, movementState.startPosition); - - movementState.endPosition = Cartesian2.multiplyByScalar(movementState.motion, d, movementState.endPosition); - movementState.endPosition = Cartesian2.add(movementState.startPosition, movementState.endPosition, movementState.endPosition); - - movementState.motion = Cartesian2.clone(Cartesian2.ZERO, movementState.motion); - } - - // If value from the decreasing exponential function is close to zero, - // the end coordinates may be NaN. - if (isNaN(movementState.endPosition.x) || isNaN(movementState.endPosition.y) || Cartesian2.distance(movementState.startPosition, movementState.endPosition) < 0.5) { - movementState.active = false; - return; - } - - if (!aggregator.isButtonDown(type, modifier)) { - var startPosition = aggregator.getStartMousePosition(type, modifier); - action(object, startPosition, movementState); - } - } else { - movementState.active = false; + SceneTransitioner.prototype.morphTo2D = function(duration, ellipsoid) { + if (defined(this._completeMorph)) { + this._completeMorph(); } - } - var scratchEventTypeArray = []; + var scene = this._scene; + this._previousMode = scene.mode; + this._morphToOrthographic = scene.camera.frustum instanceof OrthographicFrustum; - function reactToInput(controller, enabled, eventTypes, action, inertiaConstant, inertiaStateName) { - if (!defined(eventTypes)) { + if (this._previousMode === SceneMode.SCENE2D || this._previousMode === SceneMode.MORPHING) { return; } + this._scene.morphStart.raiseEvent(this, this._previousMode, SceneMode.SCENE2D, true); - var aggregator = controller._aggregator; + scene._mode = SceneMode.MORPHING; + scene.camera._setTransform(Matrix4.IDENTITY); - if (!isArray(eventTypes)) { - scratchEventTypeArray[0] = eventTypes; - eventTypes = scratchEventTypeArray; + if (this._previousMode === SceneMode.COLUMBUS_VIEW) { + morphFromColumbusViewTo2D(this, duration); + } else { + morphFrom3DTo2D(this, duration, ellipsoid); } - var length = eventTypes.length; - for (var i = 0; i < length; ++i) { - var eventType = eventTypes[i]; - var type = defined(eventType.eventType) ? eventType.eventType : eventType; - var modifier = eventType.modifier; - - var movement = aggregator.isMoving(type, modifier) && aggregator.getMovement(type, modifier); - var startPosition = aggregator.getStartMousePosition(type, modifier); - - if (controller.enableInputs && enabled) { - if (movement) { - action(controller, startPosition, movement); - } else if (inertiaConstant < 1.0) { - maintainInertia(aggregator, type, modifier, inertiaConstant, action, controller, inertiaStateName); - } - } + if (duration === 0.0 && defined(this._completeMorph)) { + this._completeMorph(); } - } - - var scratchZoomPickRay = new Ray(); - var scratchPickCartesian = new Cartesian3(); - var scratchZoomOffset = new Cartesian2(); - var scratchZoomDirection = new Cartesian3(); - var scratchCenterPixel = new Cartesian2(); - var scratchCenterPosition = new Cartesian3(); - var scratchPositionNormal = new Cartesian3(); - var scratchPickNormal = new Cartesian3(); - var scratchZoomAxis = new Cartesian3(); - var scratchCameraPositionNormal = new Cartesian3(); + }; - // Scratch variables used in zooming algorithm - var scratchTargetNormal = new Cartesian3(); - var scratchCameraPosition = new Cartesian3(); - var scratchCameraUpNormal = new Cartesian3(); - var scratchCameraRightNormal = new Cartesian3(); - var scratchForwardNormal = new Cartesian3(); - var scratchPositionToTarget = new Cartesian3(); - var scratchPositionToTargetNormal = new Cartesian3(); - var scratchPan = new Cartesian3(); - var scratchCenterMovement = new Cartesian3(); - var scratchCenter = new Cartesian3(); - var scratchCartesian = new Cartesian3(); - var scratchCartesianTwo = new Cartesian3(); - var scratchCartesianThree = new Cartesian3(); - var scratchZoomViewOptions = { - orientation: new HeadingPitchRoll() + var scratchToCVPosition = new Cartesian3(); + var scratchToCVDirection = new Cartesian3(); + var scratchToCVUp = new Cartesian3(); + var scratchToCVPosition2D = new Cartesian3(); + var scratchToCVDirection2D = new Cartesian3(); + var scratchToCVUp2D = new Cartesian3(); + var scratchToCVSurfacePosition = new Cartesian3(); + var scratchToCVCartographic = new Cartographic(); + var scratchToCVToENU = new Matrix4(); + var scratchToCVFrustumPerspective = new PerspectiveFrustum(); + var scratchToCVFrustumOrthographic = new OrthographicFrustum(); + var scratchToCVCamera = { + position : undefined, + direction : undefined, + up : undefined, + position2D : undefined, + direction2D : undefined, + up2D : undefined, + frustum : undefined }; - function handleZoom(object, startPosition, movement, zoomFactor, distanceMeasure, unitPositionDotDirection) { - var percentage = 1.0; - if (defined(unitPositionDotDirection)) { - percentage = CesiumMath.clamp(Math.abs(unitPositionDotDirection), 0.25, 1.0); + SceneTransitioner.prototype.morphToColumbusView = function(duration, ellipsoid) { + if (defined(this._completeMorph)) { + this._completeMorph(); } - // distanceMeasure should be the height above the ellipsoid. - // The zoomRate slows as it approaches the surface and stops minimumZoomDistance above it. - var minHeight = object.minimumZoomDistance * percentage; - var maxHeight = object.maximumZoomDistance; - - var minDistance = distanceMeasure - minHeight; - var zoomRate = zoomFactor * minDistance; - zoomRate = CesiumMath.clamp(zoomRate, object._minimumZoomRate, object._maximumZoomRate); - - var diff = movement.endPosition.y - movement.startPosition.y; - var rangeWindowRatio = diff / object._scene.canvas.clientHeight; - rangeWindowRatio = Math.min(rangeWindowRatio, object.maximumMovementRatio); - var distance = zoomRate * rangeWindowRatio; - - if (distance > 0.0 && Math.abs(distanceMeasure - minHeight) < 1.0) { - return; - } + var scene = this._scene; + this._previousMode = scene.mode; - if (distance < 0.0 && Math.abs(distanceMeasure - maxHeight) < 1.0) { + if (this._previousMode === SceneMode.COLUMBUS_VIEW || this._previousMode === SceneMode.MORPHING) { return; } + this._scene.morphStart.raiseEvent(this, this._previousMode, SceneMode.COLUMBUS_VIEW, true); - if (distanceMeasure - distance < minHeight) { - distance = distanceMeasure - minHeight - 1.0; - } else if (distanceMeasure - distance > maxHeight) { - distance = distanceMeasure - maxHeight; - } - - var scene = object._scene; - var camera = scene.camera; - var mode = scene.mode; - - var orientation = scratchZoomViewOptions.orientation; - orientation.heading = camera.heading; - orientation.pitch = camera.pitch; - orientation.roll = camera.roll; - - if (camera.frustum instanceof OrthographicFrustum) { - if (Math.abs(distance) > 0.0) { - camera.zoomIn(distance); - camera._adjustOrthographicFrustum(); - } - return; - } + scene.camera._setTransform(Matrix4.IDENTITY); - var sameStartPosition = Cartesian2.equals(startPosition, object._zoomMouseStart); - var zoomingOnVector = object._zoomingOnVector; - var rotatingZoom = object._rotatingZoom; - var pickedPosition; + var position = scratchToCVPosition; + var direction = scratchToCVDirection; + var up = scratchToCVUp; - if (!sameStartPosition) { - object._zoomMouseStart = Cartesian2.clone(startPosition, object._zoomMouseStart); + if (duration > 0.0) { + position.x = 0.0; + position.y = -1.0; + position.z = 1.0; + position = Cartesian3.multiplyByScalar(Cartesian3.normalize(position, position), 5.0 * ellipsoid.maximumRadius, position); - if (defined(object._globe)) { - pickedPosition = mode !== SceneMode.SCENE2D ? pickGlobe(object, startPosition, scratchPickCartesian) : camera.getPickRay(startPosition, scratchZoomPickRay).origin; - } - if (defined(pickedPosition)) { - object._useZoomWorldPosition = true; - object._zoomWorldPosition = Cartesian3.clone(pickedPosition, object._zoomWorldPosition); + Cartesian3.negate(Cartesian3.normalize(position, direction), direction); + Cartesian3.cross(Cartesian3.UNIT_X, direction, up); + } else { + var camera = scene.camera; + if (this._previousMode === SceneMode.SCENE2D) { + Cartesian3.clone(camera.position, position); + position.z = camera.frustum.right - camera.frustum.left; + Cartesian3.negate(Cartesian3.UNIT_Z, direction); + Cartesian3.clone(Cartesian3.UNIT_Y, up); } else { - object._useZoomWorldPosition = false; - } + Cartesian3.clone(camera.positionWC, position); + Cartesian3.clone(camera.directionWC, direction); + Cartesian3.clone(camera.upWC, up); - zoomingOnVector = object._zoomingOnVector = false; - rotatingZoom = object._rotatingZoom = false; - } + var surfacePoint = ellipsoid.scaleToGeodeticSurface(position, scratchToCVSurfacePosition); + var toENU = Transforms.eastNorthUpToFixedFrame(surfacePoint, ellipsoid, scratchToCVToENU); + Matrix4.inverseTransformation(toENU, toENU); - if (!object._useZoomWorldPosition) { - camera.zoomIn(distance); - return; + scene.mapProjection.project(ellipsoid.cartesianToCartographic(position, scratchToCVCartographic), position); + Matrix4.multiplyByPointAsVector(toENU, direction, direction); + Matrix4.multiplyByPointAsVector(toENU, up, up); + } } - var zoomOnVector = mode === SceneMode.COLUMBUS_VIEW; - - if (camera.positionCartographic.height < 2000000) { - rotatingZoom = true; + var frustum; + if (this._morphToOrthographic) { + frustum = scratchToCVFrustumOrthographic; + frustum.width = scene.camera.frustum.right - scene.camera.frustum.left; + frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + } else { + frustum = scratchToCVFrustumPerspective; + frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + frustum.fov = CesiumMath.toRadians(60.0); } - if (!sameStartPosition || rotatingZoom) { - if (mode === SceneMode.SCENE2D) { - var worldPosition = object._zoomWorldPosition; - var endPosition = camera.position; - - if (!Cartesian3.equals(worldPosition, endPosition) && camera.positionCartographic.height < object._maxCoord.x * 2.0) { - var savedX = camera.position.x; - - var direction = Cartesian3.subtract(worldPosition, endPosition, scratchZoomDirection); - Cartesian3.normalize(direction, direction); - - var d = Cartesian3.distance(worldPosition, endPosition) * distance / (camera.getMagnitude() * 0.5); - camera.move(direction, d * 0.5); - - if ((camera.position.x < 0.0 && savedX > 0.0) || (camera.position.x > 0.0 && savedX < 0.0)) { - pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay).origin; - object._zoomWorldPosition = Cartesian3.clone(pickedPosition, object._zoomWorldPosition); - } - } - } else if (mode === SceneMode.SCENE3D) { - var cameraPositionNormal = Cartesian3.normalize(camera.position, scratchCameraPositionNormal); - if (camera.positionCartographic.height < 3000.0 && Math.abs(Cartesian3.dot(camera.direction, cameraPositionNormal)) < 0.6) { - zoomOnVector = true; - } else { - var canvas = scene.canvas; - - var centerPixel = scratchCenterPixel; - centerPixel.x = canvas.clientWidth / 2; - centerPixel.y = canvas.clientHeight / 2; - var centerPosition = pickGlobe(object, centerPixel, scratchCenterPosition); - // If centerPosition is not defined, it means the globe does not cover the center position of screen - - if (defined(centerPosition) && camera.positionCartographic.height < 1000000) { - - var cameraPosition = scratchCameraPosition; - Cartesian3.clone(camera.position, cameraPosition); - var target = object._zoomWorldPosition; - - var targetNormal = scratchTargetNormal; - - targetNormal = Cartesian3.normalize(target, targetNormal); - - if (Cartesian3.dot(targetNormal, cameraPositionNormal) < 0.0) { - return; - } - - var center = scratchCenter; - var forward = scratchForwardNormal; - Cartesian3.clone(camera.direction, forward); - Cartesian3.add(cameraPosition, Cartesian3.multiplyByScalar(forward, 1000, scratchCartesian), center); - - var positionToTarget = scratchPositionToTarget; - var positionToTargetNormal = scratchPositionToTargetNormal; - Cartesian3.subtract(target, cameraPosition, positionToTarget); - - Cartesian3.normalize(positionToTarget, positionToTargetNormal); - - var alphaDot = Cartesian3.dot(cameraPositionNormal, positionToTargetNormal); - if (alphaDot >= 0.0) { - // We zoomed past the target, and this zoom is not valid anymore. - // This line causes the next zoom movement to pick a new starting point. - object._zoomMouseStart.x = -1; - return; - } - var alpha = Math.acos(-alphaDot); - var cameraDistance = Cartesian3.magnitude( cameraPosition ); - var targetDistance = Cartesian3.magnitude( target ); - var remainingDistance = cameraDistance - distance; - var positionToTargetDistance = Cartesian3.magnitude(positionToTarget); - - var gamma = Math.asin( CesiumMath.clamp( positionToTargetDistance / targetDistance * Math.sin(alpha), -1.0, 1.0 ) ); - var delta = Math.asin( CesiumMath.clamp( remainingDistance / targetDistance * Math.sin(alpha), -1.0, 1.0 ) ); - var beta = gamma - delta + alpha; - - var up = scratchCameraUpNormal; - Cartesian3.normalize(cameraPosition, up); - var right = scratchCameraRightNormal; - right = Cartesian3.cross(positionToTargetNormal, up, right); - right = Cartesian3.normalize(right, right ); - - Cartesian3.normalize( Cartesian3.cross(up, right, scratchCartesian), forward ); - - // Calculate new position to move to - Cartesian3.multiplyByScalar(Cartesian3.normalize(center, scratchCartesian), (Cartesian3.magnitude(center) - distance), center); - Cartesian3.normalize(cameraPosition, cameraPosition); - Cartesian3.multiplyByScalar(cameraPosition, remainingDistance, cameraPosition); - - // Pan - var pMid = scratchPan; - Cartesian3.multiplyByScalar(Cartesian3.add( - Cartesian3.multiplyByScalar(up, Math.cos(beta) - 1, scratchCartesianTwo), - Cartesian3.multiplyByScalar(forward, Math.sin(beta), scratchCartesianThree), - scratchCartesian - ), remainingDistance, pMid); - Cartesian3.add(cameraPosition, pMid, cameraPosition); - - Cartesian3.normalize(center, up); - Cartesian3.normalize( Cartesian3.cross(up, right, scratchCartesian), forward ); - - var cMid = scratchCenterMovement; - Cartesian3.multiplyByScalar(Cartesian3.add( - Cartesian3.multiplyByScalar(up, Math.cos(beta) - 1, scratchCartesianTwo), - Cartesian3.multiplyByScalar(forward, Math.sin(beta), scratchCartesianThree), - scratchCartesian - ), Cartesian3.magnitude(center), cMid); - Cartesian3.add(center, cMid, center); - - // Update camera - - // Set new position - Cartesian3.clone(cameraPosition, camera.position); + var cameraCV = scratchToCVCamera; + cameraCV.position = position; + cameraCV.direction = direction; + cameraCV.up = up; + cameraCV.frustum = frustum; - // Set new direction - Cartesian3.normalize(Cartesian3.subtract(center, cameraPosition, scratchCartesian), camera.direction); - Cartesian3.clone(camera.direction, camera.direction); + var complete = completeColumbusViewCallback(cameraCV); + createMorphHandler(this, complete); - // Set new right & up vectors - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.cross(camera.right, camera.direction, camera.up); + if (this._previousMode === SceneMode.SCENE2D) { + morphFrom2DToColumbusView(this, duration, cameraCV, complete); + } else { + cameraCV.position2D = Matrix4.multiplyByPoint(Camera.TRANSFORM_2D, position, scratchToCVPosition2D); + cameraCV.direction2D = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, direction, scratchToCVDirection2D); + cameraCV.up2D = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, up, scratchToCVUp2D); - camera.setView(scratchZoomViewOptions); - return; - } + scene._mode = SceneMode.MORPHING; + morphFrom3DToColumbusView(this, duration, cameraCV, complete); + } - if (defined(centerPosition)) { - var positionNormal = Cartesian3.normalize(centerPosition, scratchPositionNormal); - var pickedNormal = Cartesian3.normalize(object._zoomWorldPosition, scratchPickNormal); - var dotProduct = Cartesian3.dot(pickedNormal, positionNormal); + if (duration === 0.0 && defined(this._completeMorph)) { + this._completeMorph(); + } + }; - if (dotProduct > 0.0 && dotProduct < 1.0) { - var angle = CesiumMath.acosClamped(dotProduct); - var axis = Cartesian3.cross(pickedNormal, positionNormal, scratchZoomAxis); + var scratchCVTo3DCamera = { + position : new Cartesian3(), + direction : new Cartesian3(), + up : new Cartesian3(), + frustum : undefined + }; + var scratch2DTo3DFrustumPersp = new PerspectiveFrustum(); - var denom = Math.abs(angle) > CesiumMath.toRadians(20.0) ? camera.positionCartographic.height * 0.75 : camera.positionCartographic.height - distance; - var scalar = distance / denom; - camera.rotate(axis, angle * scalar); - } - } else { - zoomOnVector = true; - } - } - } + SceneTransitioner.prototype.morphTo3D = function(duration, ellipsoid) { + if (defined(this._completeMorph)) { + this._completeMorph(); + } - object._rotatingZoom = !zoomOnVector; + var scene = this._scene; + this._previousMode = scene.mode; + + if (this._previousMode === SceneMode.SCENE3D || this._previousMode === SceneMode.MORPHING) { + return; } + this._scene.morphStart.raiseEvent(this, this._previousMode, SceneMode.SCENE3D, true); - if ((!sameStartPosition && zoomOnVector) || zoomingOnVector) { - var ray; - var zoomMouseStart = SceneTransforms.wgs84ToWindowCoordinates(scene, object._zoomWorldPosition, scratchZoomOffset); - if (mode !== SceneMode.COLUMBUS_VIEW && Cartesian2.equals(startPosition, object._zoomMouseStart) && defined(zoomMouseStart)) { - ray = camera.getPickRay(zoomMouseStart, scratchZoomPickRay); + scene._mode = SceneMode.MORPHING; + scene.camera._setTransform(Matrix4.IDENTITY); + + if (this._previousMode === SceneMode.SCENE2D) { + morphFrom2DTo3D(this, duration, ellipsoid); + } else { + var camera3D; + if (duration > 0.0) { + camera3D = scratchCVTo3DCamera; + Cartesian3.fromDegrees(0.0, 0.0, 5.0 * ellipsoid.maximumRadius, ellipsoid, camera3D.position); + Cartesian3.negate(camera3D.position, camera3D.direction); + Cartesian3.normalize(camera3D.direction, camera3D.direction); + Cartesian3.clone(Cartesian3.UNIT_Z, camera3D.up); } else { - ray = camera.getPickRay(startPosition, scratchZoomPickRay); + camera3D = getColumbusViewTo3DCamera(this, ellipsoid); } - var rayDirection = ray.direction; - if (mode === SceneMode.COLUMBUS_VIEW) { - Cartesian3.fromElements(rayDirection.y, rayDirection.z, rayDirection.x, rayDirection); + var frustum; + var camera = scene.camera; + if (camera.frustum instanceof OrthographicFrustum) { + frustum = camera.frustum.clone(); + } else { + frustum = scratch2DTo3DFrustumPersp; + frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + frustum.fov = CesiumMath.toRadians(60.0); } + camera3D.frustum = frustum; - camera.move(rayDirection, distance); + var complete = complete3DCallback(camera3D); + createMorphHandler(this, complete); - object._zoomingOnVector = true; - } else { - camera.zoomIn(distance); + morphFromColumbusViewTo3D(this, duration, camera3D, complete); } - camera.setView(scratchZoomViewOptions); - } + if (duration === 0.0 && defined(this._completeMorph)) { + this._completeMorph(); + } + }; - var translate2DStart = new Ray(); - var translate2DEnd = new Ray(); - var scratchTranslateP0 = new Cartesian3(); + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + */ + SceneTransitioner.prototype.isDestroyed = function() { + return false; + }; - function translate2D(controller, startPosition, movement) { - var scene = controller._scene; - var camera = scene.camera; - var start = camera.getPickRay(movement.startPosition, translate2DStart).origin; - var end = camera.getPickRay(movement.endPosition, translate2DEnd).origin; + /** + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * transitioner = transitioner && transitioner.destroy(); + */ + SceneTransitioner.prototype.destroy = function() { + destroyMorphHandler(this); + return destroyObject(this); + }; - var direction = Cartesian3.subtract(start, end, scratchTranslateP0); - var distance = Cartesian3.magnitude(direction); + function createMorphHandler(transitioner, completeMorphFunction) { + if (transitioner._scene.completeMorphOnUserInput) { + transitioner._morphHandler = new ScreenSpaceEventHandler(transitioner._scene.canvas, false); - if (distance > 0.0) { - Cartesian3.normalize(direction, direction); - camera.move(direction, distance); + var completeMorph = function() { + transitioner._morphCancelled = true; + completeMorphFunction(transitioner); + }; + transitioner._completeMorph = completeMorph; + transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.LEFT_DOWN); + transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.MIDDLE_DOWN); + transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.RIGHT_DOWN); + transitioner._morphHandler.setInputAction(completeMorph, ScreenSpaceEventType.WHEEL); } } - function zoom2D(controller, startPosition, movement) { - if (defined(movement.distance)) { - movement = movement.distance; + function destroyMorphHandler(transitioner) { + var tweens = transitioner._currentTweens; + for ( var i = 0; i < tweens.length; ++i) { + tweens[i].cancelTween(); } - - var scene = controller._scene; - var camera = scene.camera; - - handleZoom(controller, startPosition, movement, controller._zoomFactor, camera.getMagnitude()); + transitioner._currentTweens.length = 0; + transitioner._morphHandler = transitioner._morphHandler && transitioner._morphHandler.destroy(); } - var twist2DStart = new Cartesian2(); - var twist2DEnd = new Cartesian2(); - - function twist2D(controller, startPosition, movement) { - if (defined(movement.angleAndHeight)) { - singleAxisTwist2D(controller, startPosition, movement.angleAndHeight); - return; - } + var scratchCVTo3DCartographic = new Cartographic(); + var scratchCVTo3DSurfacePoint = new Cartesian3(); + var scratchCVTo3DFromENU = new Matrix4(); - var scene = controller._scene; + function getColumbusViewTo3DCamera(transitioner, ellipsoid) { + var scene = transitioner._scene; var camera = scene.camera; - var canvas = scene.canvas; - var width = canvas.clientWidth; - var height = canvas.clientHeight; - var start = twist2DStart; - start.x = (2.0 / width) * movement.startPosition.x - 1.0; - start.y = (2.0 / height) * (height - movement.startPosition.y) - 1.0; - start = Cartesian2.normalize(start, start); + var camera3D = scratchCVTo3DCamera; + var position = camera3D.position; + var direction = camera3D.direction; + var up = camera3D.up; - var end = twist2DEnd; - end.x = (2.0 / width) * movement.endPosition.x - 1.0; - end.y = (2.0 / height) * (height - movement.endPosition.y) - 1.0; - end = Cartesian2.normalize(end, end); + var positionCarto = scene.mapProjection.unproject(camera.position, scratchCVTo3DCartographic); + ellipsoid.cartographicToCartesian(positionCarto, position); + var surfacePoint = ellipsoid.scaleToGeodeticSurface(position, scratchCVTo3DSurfacePoint); - var startTheta = CesiumMath.acosClamped(start.x); - if (start.y < 0) { - startTheta = CesiumMath.TWO_PI - startTheta; - } - var endTheta = CesiumMath.acosClamped(end.x); - if (end.y < 0) { - endTheta = CesiumMath.TWO_PI - endTheta; - } - var theta = endTheta - startTheta; + var fromENU = Transforms.eastNorthUpToFixedFrame(surfacePoint, ellipsoid, scratchCVTo3DFromENU); - camera.twistRight(theta); - } + Matrix4.multiplyByPointAsVector(fromENU, camera.direction, direction); + Matrix4.multiplyByPointAsVector(fromENU, camera.up, up); - function singleAxisTwist2D(controller, startPosition, movement) { - var rotateRate = controller._rotateFactor * controller._rotateRateRangeAdjustment; + return camera3D; + } - if (rotateRate > controller._maximumRotateRate) { - rotateRate = controller._maximumRotateRate; - } + var scratchCVTo3DStartPos = new Cartesian3(); + var scratchCVTo3DStartDir = new Cartesian3(); + var scratchCVTo3DStartUp = new Cartesian3(); + var scratchCVTo3DEndPos = new Cartesian3(); + var scratchCVTo3DEndDir = new Cartesian3(); + var scratchCVTo3DEndUp = new Cartesian3(); - if (rotateRate < controller._minimumRotateRate) { - rotateRate = controller._minimumRotateRate; - } + function morphFromColumbusViewTo3D(transitioner, duration, endCamera, complete) { + duration *= 0.5; - var scene = controller._scene; + var scene = transitioner._scene; var camera = scene.camera; - var canvas = scene.canvas; - var phiWindowRatio = (movement.endPosition.x - movement.startPosition.x) / canvas.clientWidth; - phiWindowRatio = Math.min(phiWindowRatio, controller.maximumMovementRatio); + var startPos = Cartesian3.clone(camera.position, scratchCVTo3DStartPos); + var startDir = Cartesian3.clone(camera.direction, scratchCVTo3DStartDir); + var startUp = Cartesian3.clone(camera.up, scratchCVTo3DStartUp); - var deltaPhi = rotateRate * phiWindowRatio * Math.PI * 4.0; + var endPos = Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, endCamera.position, scratchCVTo3DEndPos); + var endDir = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D_INVERSE, endCamera.direction, scratchCVTo3DEndDir); + var endUp = Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D_INVERSE, endCamera.up, scratchCVTo3DEndUp); - camera.twistRight(deltaPhi); - } + function update(value) { + columbusViewMorph(startPos, endPos, value.time, camera.position); + columbusViewMorph(startDir, endDir, value.time, camera.direction); + columbusViewMorph(startUp, endUp, value.time, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.normalize(camera.right, camera.right); + } - function update2D(controller) { - var rotatable2D = controller._scene.mapMode2D === MapMode2D.ROTATE; - if (!Matrix4.equals(Matrix4.IDENTITY, controller._scene.camera.transform)) { - reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom2D, controller.inertiaZoom, '_lastInertiaZoomMovement'); - if (rotatable2D) { - reactToInput(controller, controller.enableRotate, controller.translateEventTypes, twist2D, controller.inertiaSpin, '_lastInertiaSpinMovement'); - } - } else { - reactToInput(controller, controller.enableTranslate, controller.translateEventTypes, translate2D, controller.inertiaTranslate, '_lastInertiaTranslateMovement'); - reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom2D, controller.inertiaZoom, '_lastInertiaZoomMovement'); - if (rotatable2D) { - reactToInput(controller, controller.enableRotate, controller.tiltEventTypes, twist2D, controller.inertiaSpin, '_lastInertiaTiltMovement'); + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : update, + complete : function() { + addMorphTimeAnimations(transitioner, scene, 0.0, 1.0, duration, complete); } - } + }); + transitioner._currentTweens.push(tween); } - var pickGlobeScratchRay = new Ray(); - var scratchDepthIntersection = new Cartesian3(); - var scratchRayIntersection = new Cartesian3(); + var scratch2DTo3DFrustumOrtho = new OrthographicFrustum(); + var scratch3DToCVStartPos = new Cartesian3(); + var scratch3DToCVStartDir = new Cartesian3(); + var scratch3DToCVStartUp = new Cartesian3(); + var scratch3DToCVEndPos = new Cartesian3(); + var scratch3DToCVEndDir = new Cartesian3(); + var scratch3DToCVEndUp = new Cartesian3(); - function pickGlobe(controller, mousePosition, result) { - var scene = controller._scene; - var globe = controller._globe; + function morphFrom2DTo3D(transitioner, duration, ellipsoid) { + duration /= 3.0; + + var scene = transitioner._scene; var camera = scene.camera; - if (!defined(globe)) { - return undefined; - } + var camera3D; + if (duration > 0.0) { + camera3D = scratchCVTo3DCamera; + Cartesian3.fromDegrees(0.0, 0.0, 5.0 * ellipsoid.maximumRadius, ellipsoid, camera3D.position); + Cartesian3.negate(camera3D.position, camera3D.direction); + Cartesian3.normalize(camera3D.direction, camera3D.direction); + Cartesian3.clone(Cartesian3.UNIT_Z, camera3D.up); + } else { + camera.position.z = camera.frustum.right - camera.frustum.left; - var depthIntersection; - if (scene.pickPositionSupported) { - depthIntersection = scene.pickPositionWorldCoordinates(mousePosition, scratchDepthIntersection); + camera3D = getColumbusViewTo3DCamera(transitioner, ellipsoid); } - var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); - var rayIntersection = globe.pick(ray, scene, scratchRayIntersection); - - var pickDistance = defined(depthIntersection) ? Cartesian3.distance(depthIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; - var rayDistance = defined(rayIntersection) ? Cartesian3.distance(rayIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; - - if (pickDistance < rayDistance) { - return Cartesian3.clone(depthIntersection, result); + var frustum; + if (transitioner._morphToOrthographic) { + frustum = scratch2DTo3DFrustumOrtho; + frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + frustum.width = camera.frustum.right - camera.frustum.left; + } else { + frustum = scratch2DTo3DFrustumPersp; + frustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight; + frustum.fov = CesiumMath.toRadians(60.0); } - return Cartesian3.clone(rayIntersection, result); - } - - var translateCVStartRay = new Ray(); - var translateCVEndRay = new Ray(); - var translateCVStartPos = new Cartesian3(); - var translateCVEndPos = new Cartesian3(); - var translatCVDifference = new Cartesian3(); - var translateCVOrigin = new Cartesian3(); - var translateCVPlane = new Plane(Cartesian3.UNIT_X, 0.0); - var translateCVStartMouse = new Cartesian2(); - var translateCVEndMouse = new Cartesian2(); - - function translateCV(controller, startPosition, movement) { - if (!Cartesian3.equals(startPosition, controller._translateMousePosition)) { - controller._looking = false; - } + camera3D.frustum = frustum; - if (!Cartesian3.equals(startPosition, controller._strafeMousePosition)) { - controller._strafing = false; - } + var complete = complete3DCallback(camera3D); + createMorphHandler(transitioner, complete); - if (controller._looking) { - look3D(controller, startPosition, movement); - return; - } + var startPos = Cartesian3.clone(camera.position, scratch3DToCVStartPos); + var startDir = Cartesian3.clone(camera.direction, scratch3DToCVStartDir); + var startUp = Cartesian3.clone(camera.up, scratch3DToCVStartUp); - if (controller._strafing) { - strafe(controller, startPosition, movement); - return; - } + var endPos = Cartesian3.fromElements(0.0, 0.0, 5.0 * ellipsoid.maximumRadius, scratch3DToCVEndPos); + var endDir = Cartesian3.negate(Cartesian3.UNIT_Z, scratch3DToCVEndDir); + var endUp = Cartesian3.clone(Cartesian3.UNIT_Y, scratch3DToCVEndUp); - var scene = controller._scene; - var camera = scene.camera; - var startMouse = Cartesian2.clone(movement.startPosition, translateCVStartMouse); - var endMouse = Cartesian2.clone(movement.endPosition, translateCVEndMouse); - var startRay = camera.getPickRay(startMouse, translateCVStartRay); + var startRight = camera.frustum.right; + var endRight = endPos.z * 0.5; - var origin = Cartesian3.clone(Cartesian3.ZERO, translateCVOrigin); - var normal = Cartesian3.UNIT_X; + function update(value) { + columbusViewMorph(startPos, endPos, value.time, camera.position); + columbusViewMorph(startDir, endDir, value.time, camera.direction); + columbusViewMorph(startUp, endUp, value.time, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.normalize(camera.right, camera.right); - var globePos; - if (camera.position.z < controller._minimumPickingTerrainHeight) { - globePos = pickGlobe(controller, startMouse, translateCVStartPos); - if (defined(globePos)) { - origin.x = globePos.x; - } - } + var frustum = camera.frustum; + frustum.right = CesiumMath.lerp(startRight, endRight, value.time); + frustum.left = -frustum.right; + frustum.top = frustum.right * (scene.drawingBufferHeight / scene.drawingBufferWidth); + frustum.bottom = -frustum.top; - if (origin.x > camera.position.z && defined(globePos)) { - Cartesian3.clone(globePos, controller._strafeStartPosition); - controller._strafing = true; - strafe(controller, startPosition, movement); - controller._strafeMousePosition = Cartesian2.clone(startPosition, controller._strafeMousePosition); - return; + camera.position.z = 2.0 * scene.mapProjection.ellipsoid.maximumRadius; } - var plane = Plane.fromPointNormal(origin, normal, translateCVPlane); - - startRay = camera.getPickRay(startMouse, translateCVStartRay); - var startPlanePos = IntersectionTests.rayPlane(startRay, plane, translateCVStartPos); - - var endRay = camera.getPickRay(endMouse, translateCVEndRay); - var endPlanePos = IntersectionTests.rayPlane(endRay, plane, translateCVEndPos); - - if (!defined(startPlanePos) || !defined(endPlanePos)) { - controller._looking = true; - look3D(controller, startPosition, movement); - Cartesian2.clone(startPosition, controller._translateMousePosition); - return; + var morph; + if (transitioner._morphToOrthographic) { + morph = function() { + morphFromColumbusViewTo3D(transitioner, duration, camera3D, complete); + }; + } else { + morph = function() { + morphOrthographicToPerspective(transitioner, duration, camera3D, function() { + morphFromColumbusViewTo3D(transitioner, duration, camera3D, complete); + }); + }; } - var diff = Cartesian3.subtract(startPlanePos, endPlanePos, translatCVDifference); - var temp = diff.x; - diff.x = diff.y; - diff.y = diff.z; - diff.z = temp; - var mag = Cartesian3.magnitude(diff); - if (mag > CesiumMath.EPSILON6) { - Cartesian3.normalize(diff, diff); - camera.move(diff, mag); + if (duration > 0.0) { + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : update, + complete : function() { + scene._mode = SceneMode.MORPHING; + morph(); + } + }); + transitioner._currentTweens.push(tween); + } else { + morph(); } } - var rotateCVWindowPos = new Cartesian2(); - var rotateCVWindowRay = new Ray(); - var rotateCVCenter = new Cartesian3(); - var rotateCVVerticalCenter = new Cartesian3(); - var rotateCVTransform = new Matrix4(); - var rotateCVVerticalTransform = new Matrix4(); - var rotateCVOrigin = new Cartesian3(); - var rotateCVPlane = new Plane(Cartesian3.UNIT_X, 0.0); - var rotateCVCartesian3 = new Cartesian3(); - var rotateCVCart = new Cartographic(); - var rotateCVOldTransform = new Matrix4(); - var rotateCVQuaternion = new Quaternion(); - var rotateCVMatrix = new Matrix3(); - var tilt3DCartesian3 = new Cartesian3(); - - function rotateCV(controller, startPosition, movement) { - if (defined(movement.angleAndHeight)) { - movement = movement.angleAndHeight; - } + function columbusViewMorph(startPosition, endPosition, time, result) { + // Just linear for now. + return Cartesian3.lerp(startPosition, endPosition, time, result); + } - if (!Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { - controller._tiltCVOffMap = false; - controller._looking = false; - } + function morphPerspectiveToOrthographic(transitioner, duration, endCamera, updateHeight, complete) { + var scene = transitioner._scene; + var camera = scene.camera; - if (controller._looking) { - look3D(controller, startPosition, movement); + if (camera.frustum instanceof OrthographicFrustum) { return; } - var scene = controller._scene; - var camera = scene.camera; - var maxCoord = controller._maxCoord; - var onMap = Math.abs(camera.position.x) - maxCoord.x < 0 && Math.abs(camera.position.y) - maxCoord.y < 0; + var startFOV = camera.frustum.fov; + var endFOV = CesiumMath.RADIANS_PER_DEGREE * 0.5; + var d = endCamera.position.z * Math.tan(startFOV * 0.5); + camera.frustum.far = d / Math.tan(endFOV * 0.5) + 10000000.0; - if (controller._tiltCVOffMap || !onMap || camera.position.z > controller._minimumPickingTerrainHeight) { - controller._tiltCVOffMap = true; - rotateCVOnPlane(controller, startPosition, movement); - } else { - rotateCVOnTerrain(controller, startPosition, movement); + function update(value) { + camera.frustum.fov = CesiumMath.lerp(startFOV, endFOV, value.time); + var height = d / Math.tan(camera.frustum.fov * 0.5); + updateHeight(camera, height); } + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : update, + complete : function() { + camera.frustum = endCamera.frustum.clone(); + complete(transitioner); + } + }); + transitioner._currentTweens.push(tween); } - function rotateCVOnPlane(controller, startPosition, movement) { - var scene = controller._scene; + var scratchCVTo2DStartPos = new Cartesian3(); + var scratchCVTo2DStartDir = new Cartesian3(); + var scratchCVTo2DStartUp = new Cartesian3(); + var scratchCVTo2DEndPos = new Cartesian3(); + var scratchCVTo2DEndDir = new Cartesian3(); + var scratchCVTo2DEndUp = new Cartesian3(); + var scratchCVTo2DFrustum = new OrthographicOffCenterFrustum(); + var scratchCVTo2DRay = new Ray(); + var scratchCVTo2DPickPos = new Cartesian3(); + var scratchCVTo2DCamera = { + position : undefined, + direction : undefined, + up : undefined, + frustum : undefined + }; + + function morphFromColumbusViewTo2D(transitioner, duration) { + duration *= 0.5; + + var scene = transitioner._scene; var camera = scene.camera; - var canvas = scene.canvas; - var windowPosition = rotateCVWindowPos; - windowPosition.x = canvas.clientWidth / 2; - windowPosition.y = canvas.clientHeight / 2; - var ray = camera.getPickRay(windowPosition, rotateCVWindowRay); - var normal = Cartesian3.UNIT_X; + var startPos = Cartesian3.clone(camera.position, scratchCVTo2DStartPos); + var startDir = Cartesian3.clone(camera.direction, scratchCVTo2DStartDir); + var startUp = Cartesian3.clone(camera.up, scratchCVTo2DStartUp); - var position = ray.origin; - var direction = ray.direction; - var scalar; - var normalDotDirection = Cartesian3.dot(normal, direction); - if (Math.abs(normalDotDirection) > CesiumMath.EPSILON6) { - scalar = -Cartesian3.dot(normal, position) / normalDotDirection; - } + var endDir = Cartesian3.negate(Cartesian3.UNIT_Z, scratchCVTo2DEndDir); + var endUp = Cartesian3.clone(Cartesian3.UNIT_Y, scratchCVTo2DEndUp); - if (!defined(scalar) || scalar <= 0.0) { - controller._looking = true; - look3D(controller, startPosition, movement); - Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); - return; - } + var endPos = scratchCVTo2DEndPos; - var center = Cartesian3.multiplyByScalar(direction, scalar, rotateCVCenter); - Cartesian3.add(position, center, center); + if (duration > 0.0) { + Cartesian3.clone(Cartesian3.ZERO, scratchCVTo2DEndPos); + endPos.z = 5.0 * scene.mapProjection.ellipsoid.maximumRadius; + } else { + Cartesian3.clone(startPos, scratchCVTo2DEndPos); - var projection = scene.mapProjection; - var ellipsoid = projection.ellipsoid; + var ray = scratchCVTo2DRay; + Matrix4.multiplyByPoint(Camera.TRANSFORM_2D, startPos, ray.origin); + Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, startDir, ray.direction); - Cartesian3.fromElements(center.y, center.z, center.x, center); - var cart = projection.unproject(center, rotateCVCart); - ellipsoid.cartographicToCartesian(cart, center); + var globe = scene.globe; + if (defined(globe)) { + var pickPos = globe.pick(ray, scene, scratchCVTo2DPickPos); + if (defined(pickPos)) { + Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, pickPos, endPos); + endPos.z += Cartesian3.distance(startPos, endPos); + } + } + } - var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, rotateCVTransform); + var frustum = scratchCVTo2DFrustum; + frustum.right = endPos.z * 0.5; + frustum.left = -frustum.right; + frustum.top = frustum.right * (scene.drawingBufferHeight / scene.drawingBufferWidth); + frustum.bottom = -frustum.top; - var oldGlobe = controller._globe; - var oldEllipsoid = controller._ellipsoid; - controller._globe = undefined; - controller._ellipsoid = Ellipsoid.UNIT_SPHERE; - controller._rotateFactor = 1.0; - controller._rotateRateRangeAdjustment = 1.0; + var camera2D = scratchCVTo2DCamera; + camera2D.position = endPos; + camera2D.direction = endDir; + camera2D.up = endUp; + camera2D.frustum = frustum; - var oldTransform = Matrix4.clone(camera.transform, rotateCVOldTransform); - camera._setTransform(transform); + var complete = complete2DCallback(camera2D); + createMorphHandler(transitioner, complete); - rotate3D(controller, startPosition, movement, Cartesian3.UNIT_Z); + function updateCV(value) { + columbusViewMorph(startPos, endPos, value.time, camera.position); + columbusViewMorph(startDir, endDir, value.time, camera.direction); + columbusViewMorph(startUp, endUp, value.time, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.normalize(camera.right, camera.right); + camera._adjustOrthographicFrustum(true); + } - camera._setTransform(oldTransform); - controller._globe = oldGlobe; - controller._ellipsoid = oldEllipsoid; + function updateHeight(camera, height) { + camera.position.z = height; + } - var radius = oldEllipsoid.maximumRadius; - controller._rotateFactor = 1.0 / radius; - controller._rotateRateRangeAdjustment = radius; + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : updateCV, + complete : function() { + morphPerspectiveToOrthographic(transitioner, duration, camera2D, updateHeight, complete); + } + }); + transitioner._currentTweens.push(tween); } - function rotateCVOnTerrain(controller, startPosition, movement) { - var scene = controller._scene; - var camera = scene.camera; + var scratch3DTo2DCartographic = new Cartographic(); + var scratch3DTo2DCamera = { + position : new Cartesian3(), + direction : new Cartesian3(), + up : new Cartesian3(), + position2D : new Cartesian3(), + direction2D : new Cartesian3(), + up2D : new Cartesian3(), + frustum : new OrthographicOffCenterFrustum() + }; + var scratch3DTo2DEndCamera = { + position : new Cartesian3(), + direction : new Cartesian3(), + up : new Cartesian3(), + frustum : undefined + }; + var scratch3DTo2DPickPosition = new Cartesian3(); + var scratch3DTo2DRay = new Ray(); + var scratch3DTo2DToENU = new Matrix4(); + var scratch3DTo2DSurfacePoint = new Cartesian3(); - var center; - var ray; - var normal = Cartesian3.UNIT_X; + function morphFrom3DTo2D(transitioner, duration, ellipsoid) { + duration *= 0.5; - if (Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { - center = Cartesian3.clone(controller._tiltCenter, rotateCVCenter); + var scene = transitioner._scene; + var camera = scene.camera; + var camera2D = scratch3DTo2DCamera; + + if (duration > 0.0) { + Cartesian3.clone(Cartesian3.ZERO, camera2D.position); + camera2D.position.z = 5.0 * ellipsoid.maximumRadius; + Cartesian3.negate(Cartesian3.UNIT_Z, camera2D.direction); + Cartesian3.clone(Cartesian3.UNIT_Y, camera2D.up); } else { - if (camera.position.z < controller._minimumPickingTerrainHeight) { - center = pickGlobe(controller, startPosition, rotateCVCenter); - } + ellipsoid.cartesianToCartographic(camera.positionWC, scratch3DTo2DCartographic); + scene.mapProjection.project(scratch3DTo2DCartographic, camera2D.position); - if (!defined(center)) { - ray = camera.getPickRay(startPosition, rotateCVWindowRay); - var position = ray.origin; - var direction = ray.direction; + Cartesian3.negate(Cartesian3.UNIT_Z, camera2D.direction); + Cartesian3.clone(Cartesian3.UNIT_Y, camera2D.up); - var scalar; - var normalDotDirection = Cartesian3.dot(normal, direction); - if (Math.abs(normalDotDirection) > CesiumMath.EPSILON6) { - scalar = -Cartesian3.dot(normal, position) / normalDotDirection; - } + var ray = scratch3DTo2DRay; + Cartesian3.clone(camera2D.position2D, ray.origin); + var rayDirection = Cartesian3.clone(camera.directionWC, ray.direction); + var surfacePoint = ellipsoid.scaleToGeodeticSurface(camera.positionWC, scratch3DTo2DSurfacePoint); + var toENU = Transforms.eastNorthUpToFixedFrame(surfacePoint, ellipsoid, scratch3DTo2DToENU); + Matrix4.inverseTransformation(toENU, toENU); + Matrix4.multiplyByPointAsVector(toENU, rayDirection, rayDirection); + Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, rayDirection, rayDirection); - if (!defined(scalar) || scalar <= 0.0) { - controller._looking = true; - look3D(controller, startPosition, movement); - Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); - return; + var globe = scene.globe; + if (defined(globe)) { + var pickedPos = globe.pick(ray, scene, scratch3DTo2DPickPosition); + if (defined(pickedPos)) { + var height = Cartesian3.distance(camera2D.position2D, pickedPos); + pickedPos.x += height; + Cartesian3.clone(pickedPos, camera2D.position2D); } - - center = Cartesian3.multiplyByScalar(direction, scalar, rotateCVCenter); - Cartesian3.add(position, center, center); } - - Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); - Cartesian3.clone(center, controller._tiltCenter); } - var canvas = scene.canvas; - - var windowPosition = rotateCVWindowPos; - windowPosition.x = canvas.clientWidth / 2; - windowPosition.y = controller._tiltCenterMousePosition.y; - ray = camera.getPickRay(windowPosition, rotateCVWindowRay); - - var origin = Cartesian3.clone(Cartesian3.ZERO, rotateCVOrigin); - origin.x = center.x; - - var plane = Plane.fromPointNormal(origin, normal, rotateCVPlane); - var verticalCenter = IntersectionTests.rayPlane(ray, plane, rotateCVVerticalCenter); + function updateHeight(camera, height) { + camera.position.x = height; + } - var projection = camera._projection; - var ellipsoid = projection.ellipsoid; + Matrix4.multiplyByPoint(Camera.TRANSFORM_2D, camera2D.position, camera2D.position2D); + Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, camera2D.direction, camera2D.direction2D); + Matrix4.multiplyByPointAsVector(Camera.TRANSFORM_2D, camera2D.up, camera2D.up2D); - Cartesian3.fromElements(center.y, center.z, center.x, center); - var cart = projection.unproject(center, rotateCVCart); - ellipsoid.cartographicToCartesian(cart, center); + var frustum = camera2D.frustum; + frustum.right = camera2D.position.z * 0.5; + frustum.left = -frustum.right; + frustum.top = frustum.right * (scene.drawingBufferHeight / scene.drawingBufferWidth); + frustum.bottom = -frustum.top; - var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, rotateCVTransform); + var endCamera = scratch3DTo2DEndCamera; + Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, camera2D.position2D, endCamera.position); + Cartesian3.clone(camera2D.direction, endCamera.direction); + Cartesian3.clone(camera2D.up, endCamera.up); + endCamera.frustum = frustum; - var verticalTransform; - if (defined(verticalCenter)) { - Cartesian3.fromElements(verticalCenter.y, verticalCenter.z, verticalCenter.x, verticalCenter); - cart = projection.unproject(verticalCenter, rotateCVCart); - ellipsoid.cartographicToCartesian(cart, verticalCenter); + var complete = complete2DCallback(endCamera); + createMorphHandler(transitioner, complete); - verticalTransform = Transforms.eastNorthUpToFixedFrame(verticalCenter, ellipsoid, rotateCVVerticalTransform); - } else { - verticalTransform = transform; + function completeCallback() { + morphPerspectiveToOrthographic(transitioner, duration, camera2D, updateHeight, complete); } + morphFrom3DToColumbusView(transitioner, duration, camera2D, completeCallback); + } - var oldGlobe = controller._globe; - var oldEllipsoid = controller._ellipsoid; - controller._globe = undefined; - controller._ellipsoid = Ellipsoid.UNIT_SPHERE; - controller._rotateFactor = 1.0; - controller._rotateRateRangeAdjustment = 1.0; + function morphOrthographicToPerspective(transitioner, duration, cameraCV, complete) { + var scene = transitioner._scene; + var camera = scene.camera; - var constrainedAxis = Cartesian3.UNIT_Z; + var height = camera.frustum.right - camera.frustum.left; + camera.frustum = cameraCV.frustum.clone(); - var oldTransform = Matrix4.clone(camera.transform, rotateCVOldTransform); - camera._setTransform(transform); + var endFOV = camera.frustum.fov; + var startFOV = CesiumMath.RADIANS_PER_DEGREE * 0.5; + var d = height * Math.tan(endFOV * 0.5); + camera.frustum.far = d / Math.tan(startFOV * 0.5) + 10000000.0; + camera.frustum.fov = startFOV; - var tangent = Cartesian3.cross(Cartesian3.UNIT_Z, Cartesian3.normalize(camera.position, rotateCVCartesian3), rotateCVCartesian3); - var dot = Cartesian3.dot(camera.right, tangent); + function update(value) { + camera.frustum.fov = CesiumMath.lerp(startFOV, endFOV, value.time); + camera.position.z = d / Math.tan(camera.frustum.fov * 0.5); + } + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : update, + complete : function() { + complete(transitioner); + } + }); + transitioner._currentTweens.push(tween); + } - rotate3D(controller, startPosition, movement, constrainedAxis, false, true); + function morphFrom2DToColumbusView(transitioner, duration, cameraCV, complete) { + duration *= 0.5; - camera._setTransform(verticalTransform); - if (dot < 0.0) { - if (movement.startPosition.y > movement.endPosition.y) { - constrainedAxis = undefined; - } + var scene = transitioner._scene; + var camera = scene.camera; - var oldConstrainedAxis = camera.constrainedAxis; - camera.constrainedAxis = undefined; + var endPos = Cartesian3.clone(cameraCV.position, scratch3DToCVEndPos); + var endDir = Cartesian3.clone(cameraCV.direction, scratch3DToCVEndDir); + var endUp = Cartesian3.clone(cameraCV.up, scratch3DToCVEndUp); - rotate3D(controller, startPosition, movement, constrainedAxis, true, false); + scene._mode = SceneMode.MORPHING; - camera.constrainedAxis = oldConstrainedAxis; - } else { - rotate3D(controller, startPosition, movement, constrainedAxis, true, false); - } + function morph() { + camera.frustum = cameraCV.frustum.clone(); - if (defined(camera.constrainedAxis)) { - var right = Cartesian3.cross(camera.direction, camera.constrainedAxis, tilt3DCartesian3); - if (!Cartesian3.equalsEpsilon(right, Cartesian3.ZERO, CesiumMath.EPSILON6)) { - if (Cartesian3.dot(right, camera.right) < 0.0) { - Cartesian3.negate(right, right); - } + var startPos = Cartesian3.clone(camera.position, scratch3DToCVStartPos); + var startDir = Cartesian3.clone(camera.direction, scratch3DToCVStartDir); + var startUp = Cartesian3.clone(camera.up, scratch3DToCVStartUp); + startPos.z = endPos.z; - Cartesian3.cross(right, camera.direction, camera.up); + function update(value) { + columbusViewMorph(startPos, endPos, value.time, camera.position); + columbusViewMorph(startDir, endDir, value.time, camera.direction); + columbusViewMorph(startUp, endUp, value.time, camera.up); Cartesian3.cross(camera.direction, camera.up, camera.right); - - Cartesian3.normalize(camera.up, camera.up); Cartesian3.normalize(camera.right, camera.right); } + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : update, + complete : function() { + complete(transitioner); + } + }); + transitioner._currentTweens.push(tween); } - camera._setTransform(oldTransform); - controller._globe = oldGlobe; - controller._ellipsoid = oldEllipsoid; - - var radius = oldEllipsoid.maximumRadius; - controller._rotateFactor = 1.0 / radius; - controller._rotateRateRangeAdjustment = radius; - - var originalPosition = Cartesian3.clone(camera.positionWC, rotateCVCartesian3); - camera._adjustHeightForTerrain(); + if (transitioner._morphToOrthographic) { + morph(); + } else { + morphOrthographicToPerspective(transitioner, 0.0, cameraCV, morph); + } + } - if (!Cartesian3.equals(camera.positionWC, originalPosition)) { - camera._setTransform(verticalTransform); - camera.worldToCameraCoordinatesPoint(originalPosition, originalPosition); + function morphFrom3DToColumbusView(transitioner, duration, endCamera, complete) { + var scene = transitioner._scene; + var camera = scene.camera; - var magSqrd = Cartesian3.magnitudeSquared(originalPosition); - if (Cartesian3.magnitudeSquared(camera.position) > magSqrd) { - Cartesian3.normalize(camera.position, camera.position); - Cartesian3.multiplyByScalar(camera.position, Math.sqrt(magSqrd), camera.position); - } + var startPos = Cartesian3.clone(camera.position, scratch3DToCVStartPos); + var startDir = Cartesian3.clone(camera.direction, scratch3DToCVStartDir); + var startUp = Cartesian3.clone(camera.up, scratch3DToCVStartUp); - var angle = Cartesian3.angleBetween(originalPosition, camera.position); - var axis = Cartesian3.cross(originalPosition, camera.position, originalPosition); - Cartesian3.normalize(axis, axis); + var endPos = Cartesian3.clone(endCamera.position2D, scratch3DToCVEndPos); + var endDir = Cartesian3.clone(endCamera.direction2D, scratch3DToCVEndDir); + var endUp = Cartesian3.clone(endCamera.up2D, scratch3DToCVEndUp); - var quaternion = Quaternion.fromAxisAngle(axis, angle, rotateCVQuaternion); - var rotation = Matrix3.fromQuaternion(quaternion, rotateCVMatrix); - Matrix3.multiplyByVector(rotation, camera.direction, camera.direction); - Matrix3.multiplyByVector(rotation, camera.up, camera.up); + function update(value) { + columbusViewMorph(startPos, endPos, value.time, camera.position); + columbusViewMorph(startDir, endDir, value.time, camera.direction); + columbusViewMorph(startUp, endUp, value.time, camera.up); Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.cross(camera.right, camera.direction, camera.up); - - camera._setTransform(oldTransform); + Cartesian3.normalize(camera.right, camera.right); + camera._adjustOrthographicFrustum(true); } + var tween = scene.tweens.add({ + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT, + startObject : { + time : 0.0 + }, + stopObject : { + time : 1.0 + }, + update : update, + complete : function() { + addMorphTimeAnimations(transitioner, scene, 1.0, 0.0, duration, complete); + } + }); + transitioner._currentTweens.push(tween); } - var zoomCVWindowPos = new Cartesian2(); - var zoomCVWindowRay = new Ray(); - var zoomCVIntersection = new Cartesian3(); - - function zoomCV(controller, startPosition, movement) { - if (defined(movement.distance)) { - movement = movement.distance; - } - - var scene = controller._scene; - var camera = scene.camera; - var canvas = scene.canvas; - - var windowPosition = zoomCVWindowPos; - windowPosition.x = canvas.clientWidth / 2; - windowPosition.y = canvas.clientHeight / 2; - var ray = camera.getPickRay(windowPosition, zoomCVWindowRay); - - var intersection; - if (camera.position.z < controller._minimumPickingTerrainHeight) { - intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); - } + function addMorphTimeAnimations(transitioner, scene, start, stop, duration, complete) { + // Later, this will be linear and each object will adjust, if desired, in its vertex shader. + var options = { + object : scene, + property : 'morphTime', + startValue : start, + stopValue : stop, + duration : duration, + easingFunction : EasingFunction.QUARTIC_OUT + }; - var distance; - if (defined(intersection)) { - distance = Cartesian3.distance(ray.origin, intersection); - } else { - var normal = Cartesian3.UNIT_X; - var position = ray.origin; - var direction = ray.direction; - distance = -Cartesian3.dot(normal, position) / Cartesian3.dot(normal, direction); + if (defined(complete)) { + options.complete = function() { + complete(transitioner); + }; } - handleZoom(controller, startPosition, movement, controller._zoomFactor, distance); + var tween = scene.tweens.addProperty(options); + transitioner._currentTweens.push(tween); } - function updateCV(controller) { - var scene = controller._scene; - var camera = scene.camera; + function complete3DCallback(camera3D) { + return function(transitioner) { + var scene = transitioner._scene; + scene._mode = SceneMode.SCENE3D; + scene.morphTime = SceneMode.getMorphTime(SceneMode.SCENE3D); - if (!Matrix4.equals(Matrix4.IDENTITY, camera.transform)) { - reactToInput(controller, controller.enableRotate, controller.rotateEventTypes, rotate3D, controller.inertiaSpin, '_lastInertiaSpinMovement'); - reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom3D, controller.inertiaZoom, '_lastInertiaZoomMovement'); - } else { - var tweens = controller._tweens; + destroyMorphHandler(transitioner); - if (controller._aggregator.anyButtonDown) { - tweens.removeAll(); - } + if (transitioner._previousMode !== SceneMode.MORPHING || transitioner._morphCancelled) { + transitioner._morphCancelled = false; - reactToInput(controller, controller.enableTilt, controller.tiltEventTypes, rotateCV, controller.inertiaSpin, '_lastInertiaTiltMovement'); - reactToInput(controller, controller.enableTranslate, controller.translateEventTypes, translateCV, controller.inertiaTranslate, '_lastInertiaTranslateMovement'); - reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoomCV, controller.inertiaZoom, '_lastInertiaZoomMovement'); - reactToInput(controller, controller.enableLook, controller.lookEventTypes, look3D); + var camera = scene.camera; + Cartesian3.clone(camera3D.position, camera.position); + Cartesian3.clone(camera3D.direction, camera.direction); + Cartesian3.clone(camera3D.up, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.normalize(camera.right, camera.right); - if (!controller._aggregator.anyButtonDown && - (!defined(controller._lastInertiaZoomMovement) || !controller._lastInertiaZoomMovement.active) && - (!defined(controller._lastInertiaTranslateMovement) || !controller._lastInertiaTranslateMovement.active) && - !tweens.contains(controller._tween)) { - var tween = camera.createCorrectPositionTween(controller.bounceAnimationTime); - if (defined(tween)) { - controller._tween = tweens.add(tween); - } + camera.frustum = camera3D.frustum.clone(); } - tweens.update(); - } + var wasMorphing = defined(transitioner._completeMorph); + transitioner._completeMorph = undefined; + scene.camera.update(scene.mode); + transitioner._scene.morphComplete.raiseEvent(transitioner, transitioner._previousMode, SceneMode.SCENE3D, wasMorphing); + }; } - var scratchStrafeRay = new Ray(); - var scratchStrafePlane = new Plane(Cartesian3.UNIT_X, 0.0); - var scratchStrafeIntersection = new Cartesian3(); - var scratchStrafeDirection = new Cartesian3(); - var scratchMousePos = new Cartesian3(); + function complete2DCallback(camera2D) { + return function(transitioner) { + var scene = transitioner._scene; - function strafe(controller, startPosition, movement) { - var scene = controller._scene; - var camera = scene.camera; + scene._mode = SceneMode.SCENE2D; + scene.morphTime = SceneMode.getMorphTime(SceneMode.SCENE2D); - var mouseStartPosition = pickGlobe(controller, movement.startPosition, scratchMousePos); - if (!defined(mouseStartPosition)) { - return; - } + destroyMorphHandler(transitioner); - var mousePosition = movement.endPosition; - var ray = camera.getPickRay(mousePosition, scratchStrafeRay); + var camera = scene.camera; + Cartesian3.clone(camera2D.position, camera.position); + camera.position.z = scene.mapProjection.ellipsoid.maximumRadius * 2.0; + Cartesian3.clone(camera2D.direction, camera.direction); + Cartesian3.clone(camera2D.up, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.normalize(camera.right, camera.right); + camera.frustum = camera2D.frustum.clone(); - var direction = Cartesian3.clone(camera.direction, scratchStrafeDirection); - if (scene.mode === SceneMode.COLUMBUS_VIEW) { - Cartesian3.fromElements(direction.z, direction.x, direction.y, direction); - } + var wasMorphing = defined(transitioner._completeMorph); + transitioner._completeMorph = undefined; + scene.camera.update(scene.mode); + transitioner._scene.morphComplete.raiseEvent(transitioner, transitioner._previousMode, SceneMode.SCENE2D, wasMorphing); + }; + } - var plane = Plane.fromPointNormal(mouseStartPosition, direction, scratchStrafePlane); - var intersection = IntersectionTests.rayPlane(ray, plane, scratchStrafeIntersection); - if (!defined(intersection)) { - return; - } + function completeColumbusViewCallback(cameraCV) { + return function(transitioner) { + var scene = transitioner._scene; + scene._mode = SceneMode.COLUMBUS_VIEW; + scene.morphTime = SceneMode.getMorphTime(SceneMode.COLUMBUS_VIEW); - direction = Cartesian3.subtract(mouseStartPosition, intersection, direction); - if (scene.mode === SceneMode.COLUMBUS_VIEW) { - Cartesian3.fromElements(direction.y, direction.z, direction.x, direction); - } + destroyMorphHandler(transitioner); - Cartesian3.add(camera.position, direction, camera.position); + if (transitioner._previousModeMode !== SceneMode.MORPHING || transitioner._morphCancelled) { + transitioner._morphCancelled = false; + + var camera = scene.camera; + Cartesian3.clone(cameraCV.position, camera.position); + Cartesian3.clone(cameraCV.direction, camera.direction); + Cartesian3.clone(cameraCV.up, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.normalize(camera.right, camera.right); + } + + var wasMorphing = defined(transitioner._completeMorph); + transitioner._completeMorph = undefined; + scene.camera.update(scene.mode); + transitioner._scene.morphComplete.raiseEvent(transitioner, transitioner._previousMode, SceneMode.COLUMBUS_VIEW, wasMorphing); + }; } - var spin3DPick = new Cartesian3(); - var scratchCartographic = new Cartographic(); - var scratchRadii = new Cartesian3(); - var scratchEllipsoid = new Ellipsoid(); - var scratchLookUp = new Cartesian3(); + return SceneTransitioner; +}); - function spin3D(controller, startPosition, movement) { - var scene = controller._scene; - var camera = scene.camera; +define('Scene/TweenCollection',[ + '../Core/clone', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/DeveloperError', + '../Core/EasingFunction', + '../Core/getTimestamp', + '../Core/TimeConstants', + '../ThirdParty/Tween' + ], function( + clone, + defaultValue, + defined, + defineProperties, + DeveloperError, + EasingFunction, + getTimestamp, + TimeConstants, + TweenJS) { + 'use strict'; - if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) { - rotate3D(controller, startPosition, movement); - return; - } + /** + * A tween is an animation that interpolates the properties of two objects using an {@link EasingFunction}. Create + * one using {@link Scene#tweens} and {@link TweenCollection#add} and related add functions. + * + * @alias Tween + * @constructor + * + * @private + */ + function Tween(tweens, tweenjs, startObject, stopObject, duration, delay, easingFunction, update, complete, cancel) { + this._tweens = tweens; + this._tweenjs = tweenjs; - var magnitude; - var radii; - var ellipsoid; + this._startObject = clone(startObject); + this._stopObject = clone(stopObject); - var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, scratchLookUp); + this._duration = duration; + this._delay = delay; + this._easingFunction = easingFunction; - var height = controller._ellipsoid.cartesianToCartographic(camera.positionWC, scratchCartographic).height; - var globe = controller._globe; + this._update = update; + this._complete = complete; - var mousePos; - var tangentPick = false; - if (defined(globe) && height < controller._minimumPickingTerrainHeight) { - mousePos = pickGlobe(controller, movement.startPosition, scratchMousePos); - if (defined(mousePos)) { - var ray = camera.getPickRay(movement.startPosition, pickGlobeScratchRay); - var normal = controller._ellipsoid.geodeticSurfaceNormal(mousePos); - tangentPick = Math.abs(Cartesian3.dot(ray.direction, normal)) < 0.05; + /** + * The callback to call if the tween is canceled either because {@link Tween#cancelTween} + * was called or because the tween was removed from the collection. + * + * @type {TweenCollection~TweenCancelledCallback} + */ + this.cancel = cancel; - if (tangentPick && !controller._looking) { - controller._rotating = false; - controller._strafing = true; - } - } - } + /** + * @private + */ + this.needsStart = true; + } - if (Cartesian2.equals(startPosition, controller._rotateMousePosition)) { - if (controller._looking) { - look3D(controller, startPosition, movement, up); - } else if (controller._rotating) { - rotate3D(controller, startPosition, movement); - } else if (controller._strafing) { - Cartesian3.clone(mousePos, controller._strafeStartPosition); - strafe(controller, startPosition, movement); - } else { - magnitude = Cartesian3.magnitude(controller._rotateStartPosition); - radii = scratchRadii; - radii.x = radii.y = radii.z = magnitude; - ellipsoid = Ellipsoid.fromCartesian3(radii, scratchEllipsoid); - pan3D(controller, startPosition, movement, ellipsoid); + defineProperties(Tween.prototype, { + /** + * An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. + * @memberof Tween.prototype + * + * @type {Object} + * @readonly + */ + startObject : { + get : function() { + return this._startObject; } - return; - } - controller._looking = false; - controller._rotating = false; - controller._strafing = false; + }, - if (defined(globe) && height < controller._minimumPickingTerrainHeight) { - if (defined(mousePos)) { - if (Cartesian3.magnitude(camera.position) < Cartesian3.magnitude(mousePos)) { - Cartesian3.clone(mousePos, controller._strafeStartPosition); + /** + * An object with properties for the final values of the tween. + * @memberof Tween.prototype + * + * @type {Object} + * @readonly + */ + stopObject : { + get : function() { + return this._stopObject; + } + }, - controller._strafing = true; - strafe(controller, startPosition, movement); - } else { - magnitude = Cartesian3.magnitude(mousePos); - radii = scratchRadii; - radii.x = radii.y = radii.z = magnitude; - ellipsoid = Ellipsoid.fromCartesian3(radii, scratchEllipsoid); - pan3D(controller, startPosition, movement, ellipsoid); + /** + * The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @memberof Tween.prototype + * + * @type {Number} + * @readonly + */ + duration : { + get : function() { + return this._duration; + } + }, - Cartesian3.clone(mousePos, controller._rotateStartPosition); - } - } else { - controller._looking = true; - look3D(controller, startPosition, movement, up); + /** + * The delay, in seconds, before the tween starts animating. + * @memberof Tween.prototype + * + * @type {Number} + * @readonly + */ + delay : { + get : function() { + return this._delay; } - } else if (defined(camera.pickEllipsoid(movement.startPosition, controller._ellipsoid, spin3DPick))) { - pan3D(controller, startPosition, movement, controller._ellipsoid); - Cartesian3.clone(spin3DPick, controller._rotateStartPosition); - } else if (height > controller._minimumTrackBallHeight) { - controller._rotating = true; - rotate3D(controller, startPosition, movement); - } else { - controller._looking = true; - look3D(controller, startPosition, movement, up); - } + }, - Cartesian2.clone(startPosition, controller._rotateMousePosition); - } + /** + * Determines the curve for animtion. + * @memberof Tween.prototype + * + * @type {EasingFunction} + * @readonly + */ + easingFunction : { + get : function() { + return this._easingFunction; + } + }, - function rotate3D(controller, startPosition, movement, constrainedAxis, rotateOnlyVertical, rotateOnlyHorizontal) { - rotateOnlyVertical = defaultValue(rotateOnlyVertical, false); - rotateOnlyHorizontal = defaultValue(rotateOnlyHorizontal, false); + /** + * The callback to call at each animation update (usually tied to the a rendered frame). + * @memberof Tween.prototype + * + * @type {TweenCollection~TweenUpdateCallback} + * @readonly + */ + update : { + get : function() { + return this._update; + } + }, - var scene = controller._scene; - var camera = scene.camera; - var canvas = scene.canvas; + /** + * The callback to call when the tween finishes animating. + * @memberof Tween.prototype + * + * @type {TweenCollection~TweenCompleteCallback} + * @readonly + */ + complete : { + get : function() { + return this._complete; + } + }, - var oldAxis = camera.constrainedAxis; - if (defined(constrainedAxis)) { - camera.constrainedAxis = constrainedAxis; + /** + * @memberof Tween.prototype + * + * @private + */ + tweenjs : { + get : function() { + return this._tweenjs; + } } + }); - var rho = Cartesian3.magnitude(camera.position); - var rotateRate = controller._rotateFactor * (rho - controller._rotateRateRangeAdjustment); + /** + * Cancels the tween calling the {@link Tween#cancel} callback if one exists. This + * has no effect if the tween finished or was already canceled. + */ + Tween.prototype.cancelTween = function() { + this._tweens.remove(this); + }; - if (rotateRate > controller._maximumRotateRate) { - rotateRate = controller._maximumRotateRate; - } + /** + * A collection of tweens for animating properties. Commonly accessed using {@link Scene#tweens}. + * + * @alias TweenCollection + * @constructor + * + * @private + */ + function TweenCollection() { + this._tweens = []; + } - if (rotateRate < controller._minimumRotateRate) { - rotateRate = controller._minimumRotateRate; + defineProperties(TweenCollection.prototype, { + /** + * The number of tweens in the collection. + * @memberof TweenCollection.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._tweens.length; + } } + }); - var phiWindowRatio = (movement.startPosition.x - movement.endPosition.x) / canvas.clientWidth; - var thetaWindowRatio = (movement.startPosition.y - movement.endPosition.y) / canvas.clientHeight; - phiWindowRatio = Math.min(phiWindowRatio, controller.maximumMovementRatio); - thetaWindowRatio = Math.min(thetaWindowRatio, controller.maximumMovementRatio); - - var deltaPhi = rotateRate * phiWindowRatio * Math.PI * 2.0; - var deltaTheta = rotateRate * thetaWindowRatio * Math.PI; + /** + * Creates a tween for animating between two sets of properties. The tween starts animating at the next call to {@link TweenCollection#update}, which + * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * + * @param {Object} [options] Object with the following properties: + * @param {Object} options.startObject An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. + * @param {Object} options.stopObject An object with properties for the final values of the tween. + * @param {Number} options.duration The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. + * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). + * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. + * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. + * @returns {Tween} The tween. + * + * @exception {DeveloperError} options.duration must be positive. + */ + TweenCollection.prototype.add = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (!rotateOnlyVertical) { - camera.rotateRight(deltaPhi); + if (!defined(options.startObject) || !defined(options.stopObject)) { + throw new DeveloperError('options.startObject and options.stopObject are required.'); } - if (!rotateOnlyHorizontal) { - camera.rotateUp(deltaTheta); + if (!defined(options.duration) || options.duration < 0.0) { + throw new DeveloperError('options.duration is required and must be positive.'); + } + + if (options.duration === 0.0) { + if (defined(options.complete)) { + options.complete(); + } + return new Tween(this); } - camera.constrainedAxis = oldAxis; - } + var duration = options.duration / TimeConstants.SECONDS_PER_MILLISECOND; + var delayInSeconds = defaultValue(options.delay, 0.0); + var delay = delayInSeconds / TimeConstants.SECONDS_PER_MILLISECOND; + var easingFunction = defaultValue(options.easingFunction, EasingFunction.LINEAR_NONE); - var pan3DP0 = Cartesian4.clone(Cartesian4.UNIT_W); - var pan3DP1 = Cartesian4.clone(Cartesian4.UNIT_W); - var pan3DTemp0 = new Cartesian3(); - var pan3DTemp1 = new Cartesian3(); - var pan3DTemp2 = new Cartesian3(); - var pan3DTemp3 = new Cartesian3(); - var pan3DStartMousePosition = new Cartesian2(); - var pan3DEndMousePosition = new Cartesian2(); + var value = options.startObject; + var tweenjs = new TweenJS.Tween(value); + tweenjs.to(clone(options.stopObject), duration); + tweenjs.delay(delay); + tweenjs.easing(easingFunction); + if (defined(options.update)) { + tweenjs.onUpdate(function() { + options.update(value); + }); + } + tweenjs.onComplete(defaultValue(options.complete, null)); + tweenjs.repeat(defaultValue(options._repeat, 0.0)); - function pan3D(controller, startPosition, movement, ellipsoid) { - var scene = controller._scene; - var camera = scene.camera; + var tween = new Tween(this, tweenjs, options.startObject, options.stopObject, options.duration, delayInSeconds, easingFunction, options.update, options.complete, options.cancel); + this._tweens.push(tween); + return tween; + }; - var startMousePosition = Cartesian2.clone(movement.startPosition, pan3DStartMousePosition); - var endMousePosition = Cartesian2.clone(movement.endPosition, pan3DEndMousePosition); + /** + * Creates a tween for animating a scalar property on the given object. The tween starts animating at the next call to {@link TweenCollection#update}, which + * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * + * @param {Object} [options] Object with the following properties: + * @param {Object} options.object The object containing the property to animate. + * @param {String} options.property The name of the property to animate. + * @param {Number} options.startValue The initial value. + * @param {Number} options.stopValue The final value. + * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. + * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). + * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. + * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. + * @returns {Tween} The tween. + * + * @exception {DeveloperError} options.object must have the specified property. + * @exception {DeveloperError} options.duration must be positive. + */ + TweenCollection.prototype.addProperty = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var p0 = camera.pickEllipsoid(startMousePosition, ellipsoid, pan3DP0); - var p1 = camera.pickEllipsoid(endMousePosition, ellipsoid, pan3DP1); + var object = options.object; + var property = options.property; + var startValue = options.startValue; + var stopValue = options.stopValue; - if (!defined(p0) || !defined(p1)) { - controller._rotating = true; - rotate3D(controller, startPosition, movement); - return; + if (!defined(object) || !defined(options.property)) { + throw new DeveloperError('options.object and options.property are required.'); + } + if (!defined(object[property])) { + throw new DeveloperError('options.object must have the specified property.'); + } + if (!defined(startValue) || !defined(stopValue)) { + throw new DeveloperError('options.startValue and options.stopValue are required.'); + } + + function update(value) { + object[property] = value.value; } - p0 = camera.worldToCameraCoordinates(p0, p0); - p1 = camera.worldToCameraCoordinates(p1, p1); - - if (!defined(camera.constrainedAxis)) { - Cartesian3.normalize(p0, p0); - Cartesian3.normalize(p1, p1); - var dot = Cartesian3.dot(p0, p1); - var axis = Cartesian3.cross(p0, p1, pan3DTemp0); + return this.add({ + startObject : { + value : startValue + }, + stopObject : { + value : stopValue + }, + duration : defaultValue(options.duration, 3.0), + delay : options.delay, + easingFunction : options.easingFunction, + update : update, + complete : options.complete, + cancel : options.cancel, + _repeat : options._repeat + }); + }; - if (dot < 1.0 && !Cartesian3.equalsEpsilon(axis, Cartesian3.ZERO, CesiumMath.EPSILON14)) { // dot is in [0, 1] - var angle = Math.acos(dot); - camera.rotate(axis, angle); - } - } else { - var basis0 = camera.constrainedAxis; - var basis1 = Cartesian3.mostOrthogonalAxis(basis0, pan3DTemp0); - Cartesian3.cross(basis1, basis0, basis1); - Cartesian3.normalize(basis1, basis1); - var basis2 = Cartesian3.cross(basis0, basis1, pan3DTemp1); + /** + * Creates a tween for animating the alpha of all color uniforms on a {@link Material}. The tween starts animating at the next call to {@link TweenCollection#update}, which + * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * + * @param {Object} [options] Object with the following properties: + * @param {Material} options.material The material to animate. + * @param {Number} [options.startValue=0.0] The initial alpha value. + * @param {Number} [options.stopValue=1.0] The final alpha value. + * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. + * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). + * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. + * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. + * @returns {Tween} The tween. + * + * @exception {DeveloperError} material has no properties with alpha components. + * @exception {DeveloperError} options.duration must be positive. + */ + TweenCollection.prototype.addAlpha = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var startRho = Cartesian3.magnitude(p0); - var startDot = Cartesian3.dot(basis0, p0); - var startTheta = Math.acos(startDot / startRho); - var startRej = Cartesian3.multiplyByScalar(basis0, startDot, pan3DTemp2); - Cartesian3.subtract(p0, startRej, startRej); - Cartesian3.normalize(startRej, startRej); + var material = options.material; - var endRho = Cartesian3.magnitude(p1); - var endDot = Cartesian3.dot(basis0, p1); - var endTheta = Math.acos(endDot / endRho); - var endRej = Cartesian3.multiplyByScalar(basis0, endDot, pan3DTemp3); - Cartesian3.subtract(p1, endRej, endRej); - Cartesian3.normalize(endRej, endRej); + if (!defined(material)) { + throw new DeveloperError('options.material is required.'); + } + + var properties = []; - var startPhi = Math.acos(Cartesian3.dot(startRej, basis1)); - if (Cartesian3.dot(startRej, basis2) < 0) { - startPhi = CesiumMath.TWO_PI - startPhi; + for (var property in material.uniforms) { + if (material.uniforms.hasOwnProperty(property) && + defined(material.uniforms[property]) && + defined(material.uniforms[property].alpha)) { + properties.push(property); } + } - var endPhi = Math.acos(Cartesian3.dot(endRej, basis1)); - if (Cartesian3.dot(endRej, basis2) < 0) { - endPhi = CesiumMath.TWO_PI - endPhi; + if (properties.length === 0) { + throw new DeveloperError('material has no properties with alpha components.'); + } + + function update(value) { + var length = properties.length; + for (var i = 0; i < length; ++i) { + material.uniforms[properties[i]].alpha = value.alpha; } + } - var deltaPhi = startPhi - endPhi; - - var east; - if (Cartesian3.equalsEpsilon(basis0, camera.position, CesiumMath.EPSILON2)) { - east = camera.right; - } else { - east = Cartesian3.cross(basis0, camera.position, pan3DTemp0); - } + return this.add({ + startObject : { + alpha : defaultValue(options.startValue, 0.0) // Default to fade in + }, + stopObject : { + alpha : defaultValue(options.stopValue, 1.0) + }, + duration : defaultValue(options.duration, 3.0), + delay : options.delay, + easingFunction : options.easingFunction, + update : update, + complete : options.complete, + cancel : options.cancel + }); + }; - var planeNormal = Cartesian3.cross(basis0, east, pan3DTemp0); - var side0 = Cartesian3.dot(planeNormal, Cartesian3.subtract(p0, basis0, pan3DTemp1)); - var side1 = Cartesian3.dot(planeNormal, Cartesian3.subtract(p1, basis0, pan3DTemp1)); + /** + * Creates a tween for animating the offset uniform of a {@link Material}. The tween starts animating at the next call to {@link TweenCollection#update}, which + * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. + * + * @param {Object} [options] Object with the following properties: + * @param {Material} options.material The material to animate. + * @param {Number} options.startValue The initial alpha value. + * @param {Number} options.stopValue The final alpha value. + * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. + * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). + * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. + * @returns {Tween} The tween. + * + * @exception {DeveloperError} material.uniforms must have an offset property. + * @exception {DeveloperError} options.duration must be positive. + */ + TweenCollection.prototype.addOffsetIncrement = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var deltaTheta; - if (side0 > 0 && side1 > 0) { - deltaTheta = endTheta - startTheta; - } else if (side0 > 0 && side1 <= 0) { - if (Cartesian3.dot(camera.position, basis0) > 0) { - deltaTheta = -startTheta - endTheta; - } else { - deltaTheta = startTheta + endTheta; - } - } else { - deltaTheta = startTheta - endTheta; - } + var material = options.material; - camera.rotateRight(deltaPhi); - camera.rotateUp(deltaTheta); + if (!defined(material)) { + throw new DeveloperError('material is required.'); } - } - - var zoom3DUnitPosition = new Cartesian3(); - var zoom3DCartographic = new Cartographic(); + if (!defined(material.uniforms.offset)) { + throw new DeveloperError('material.uniforms must have an offset property.'); + } + + var uniforms = material.uniforms; + return this.addProperty({ + object : uniforms, + property : 'offset', + startValue : uniforms.offset, + stopValue : uniforms.offset + 1, + duration : options.duration, + delay : options.delay, + easingFunction : options.easingFunction, + update : options.update, + cancel : options.cancel, + _repeat : Infinity + }); + }; - function zoom3D(controller, startPosition, movement) { - if (defined(movement.distance)) { - movement = movement.distance; + /** + * Removes a tween from the collection. + * <p> + * This calls the {@link Tween#cancel} callback if the tween has one. + * </p> + * + * @param {Tween} tween The tween to remove. + * @returns {Boolean} <code>true</code> if the tween was removed; <code>false</code> if the tween was not found in the collection. + */ + TweenCollection.prototype.remove = function(tween) { + if (!defined(tween)) { + return false; } - var ellipsoid = controller._ellipsoid; - var scene = controller._scene; - var camera = scene.camera; - var canvas = scene.canvas; + var index = this._tweens.indexOf(tween); + if (index !== -1) { + tween.tweenjs.stop(); + if (defined(tween.cancel)) { + tween.cancel(); + } + this._tweens.splice(index, 1); + return true; + } - var windowPosition = zoomCVWindowPos; - windowPosition.x = canvas.clientWidth / 2; - windowPosition.y = canvas.clientHeight / 2; - var ray = camera.getPickRay(windowPosition, zoomCVWindowRay); + return false; + }; - var intersection; - var height = ellipsoid.cartesianToCartographic(camera.position, zoom3DCartographic).height; - if (height < controller._minimumPickingTerrainHeight) { - intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); - } + /** + * Removes all tweens from the collection. + * <p> + * This calls the {@link Tween#cancel} callback for each tween that has one. + * </p> + */ + TweenCollection.prototype.removeAll = function() { + var tweens = this._tweens; - var distance; - if (defined(intersection)) { - distance = Cartesian3.distance(ray.origin, intersection); - } else { - distance = height; + for (var i = 0; i < tweens.length; ++i) { + var tween = tweens[i]; + tween.tweenjs.stop(); + if (defined(tween.cancel)) { + tween.cancel(); + } } + tweens.length = 0; + }; - var unitPosition = Cartesian3.normalize(camera.position, zoom3DUnitPosition); - handleZoom(controller, startPosition, movement, controller._zoomFactor, distance, Cartesian3.dot(unitPosition, camera.direction)); - } + /** + * Determines whether this collection contains a given tween. + * + * @param {Tween} tween The tween to check for. + * @returns {Boolean} <code>true</code> if this collection contains the tween, <code>false</code> otherwise. + */ + TweenCollection.prototype.contains = function(tween) { + return defined(tween) && (this._tweens.indexOf(tween) !== -1); + }; - var tilt3DWindowPos = new Cartesian2(); - var tilt3DRay = new Ray(); - var tilt3DCenter = new Cartesian3(); - var tilt3DVerticalCenter = new Cartesian3(); - var tilt3DTransform = new Matrix4(); - var tilt3DVerticalTransform = new Matrix4(); - var tilt3DOldTransform = new Matrix4(); - var tilt3DQuaternion = new Quaternion(); - var tilt3DMatrix = new Matrix3(); - var tilt3DCart = new Cartographic(); - var tilt3DLookUp = new Cartesian3(); + /** + * Returns the tween in the collection at the specified index. Indices are zero-based + * and increase as tweens are added. Removing a tween shifts all tweens after + * it to the left, changing their indices. This function is commonly used to iterate over + * all the tween in the collection. + * + * @param {Number} index The zero-based index of the tween. + * @returns {Tween} The tween at the specified index. + * + * @example + * // Output the duration of all the tweens in the collection. + * var tweens = scene.tweens; + * var length = tweens.length; + * for (var i = 0; i < length; ++i) { + * console.log(tweens.get(i).duration); + * } + */ + TweenCollection.prototype.get = function(index) { + if (!defined(index)) { + throw new DeveloperError('index is required.'); + } + + return this._tweens[index]; + }; - function tilt3D(controller, startPosition, movement) { - var scene = controller._scene; - var camera = scene.camera; + /** + * Updates the tweens in the collection to be at the provide time. When a tween finishes, it is removed + * from the collection. + * + * @param {Number} [time=getTimestamp()] The time in seconds. By default tweens are synced to the system clock. + */ + TweenCollection.prototype.update = function(time) { + var tweens = this._tweens; - if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) { - return; - } + var i = 0; + time = defined(time) ? time / TimeConstants.SECONDS_PER_MILLISECOND : getTimestamp(); + while (i < tweens.length) { + var tween = tweens[i]; + var tweenjs = tween.tweenjs; - if (defined(movement.angleAndHeight)) { - movement = movement.angleAndHeight; + if (tween.needsStart) { + tween.needsStart = false; + tweenjs.start(time); + } else if (tweenjs.update(time)) { + i++; + } else { + tweenjs.stop(); + tweens.splice(i, 1); + } } + }; - if (!Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { - controller._tiltOnEllipsoid = false; - controller._looking = false; - } + /** + * A function that will execute when a tween completes. + * @callback TweenCollection~TweenCompleteCallback + */ - if (controller._looking) { - var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, tilt3DLookUp); - look3D(controller, startPosition, movement, up); - return; - } + /** + * A function that will execute when a tween updates. + * @callback TweenCollection~TweenUpdateCallback + */ - var ellipsoid = controller._ellipsoid; - var cartographic = ellipsoid.cartesianToCartographic(camera.position, tilt3DCart); + /** + * A function that will execute when a tween is cancelled. + * @callback TweenCollection~TweenCancelledCallback + */ - if (controller._tiltOnEllipsoid || cartographic.height > controller._minimumCollisionTerrainHeight) { - controller._tiltOnEllipsoid = true; - tilt3DOnEllipsoid(controller, startPosition, movement); - } else { - tilt3DOnTerrain(controller, startPosition, movement); - } - } + return TweenCollection; +}); - var tilt3DOnEllipsoidCartographic = new Cartographic(); +define('Scene/ScreenSpaceCameraController',[ + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/defaultValue', + '../Core/defined', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Ellipsoid', + '../Core/HeadingPitchRoll', + '../Core/IntersectionTests', + '../Core/isArray', + '../Core/KeyboardEventModifier', + '../Core/Math', + '../Core/Matrix3', + '../Core/Matrix4', + '../Core/OrthographicFrustum', + '../Core/Plane', + '../Core/Quaternion', + '../Core/Ray', + '../Core/Transforms', + './CameraEventAggregator', + './CameraEventType', + './MapMode2D', + './SceneMode', + './SceneTransforms', + './TweenCollection' + ], function( + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + defaultValue, + defined, + destroyObject, + DeveloperError, + Ellipsoid, + HeadingPitchRoll, + IntersectionTests, + isArray, + KeyboardEventModifier, + CesiumMath, + Matrix3, + Matrix4, + OrthographicFrustum, + Plane, + Quaternion, + Ray, + Transforms, + CameraEventAggregator, + CameraEventType, + MapMode2D, + SceneMode, + SceneTransforms, + TweenCollection) { + 'use strict'; - function tilt3DOnEllipsoid(controller, startPosition, movement) { - var ellipsoid = controller._ellipsoid; - var scene = controller._scene; - var camera = scene.camera; - var minHeight = controller.minimumZoomDistance * 0.25; - var height = ellipsoid.cartesianToCartographic(camera.positionWC, tilt3DOnEllipsoidCartographic).height; - if (height - minHeight - 1.0 < CesiumMath.EPSILON3 && - movement.endPosition.y - movement.startPosition.y < 0) { - return; + /** + * Modifies the camera position and orientation based on mouse input to a canvas. + * @alias ScreenSpaceCameraController + * @constructor + * + * @param {Scene} scene The scene. + */ + function ScreenSpaceCameraController(scene) { + if (!defined(scene)) { + throw new DeveloperError('scene is required.'); } + + /** + * If true, inputs are allowed conditionally with the flags enableTranslate, enableZoom, + * enableRotate, enableTilt, and enableLook. If false, all inputs are disabled. + * + * NOTE: This setting is for temporary use cases, such as camera flights and + * drag-selection of regions (see Picking demo). It is typically set to false at the + * start of such events, and set true on completion. To keep inputs disabled + * past the end of camera flights, you must use the other booleans (enableTranslate, + * enableZoom, enableRotate, enableTilt, and enableLook). + * @type {Boolean} + * @default true + */ + this.enableInputs = true; + /** + * If true, allows the user to pan around the map. If false, the camera stays locked at the current position. + * This flag only applies in 2D and Columbus view modes. + * @type {Boolean} + * @default true + */ + this.enableTranslate = true; + /** + * If true, allows the user to zoom in and out. If false, the camera is locked to the current distance from the ellipsoid. + * @type {Boolean} + * @default true + */ + this.enableZoom = true; + /** + * If true, allows the user to rotate the camera. If false, the camera is locked to the current heading. + * This flag only applies in 2D and 3D. + * @type {Boolean} + * @default true + */ + this.enableRotate = true; + /** + * If true, allows the user to tilt the camera. If false, the camera is locked to the current heading. + * This flag only applies in 3D and Columbus view. + * @type {Boolean} + * @default true + */ + this.enableTilt = true; + /** + * If true, allows the user to use free-look. If false, the camera view direction can only be changed through translating + * or rotating. This flag only applies in 3D and Columbus view modes. + * @type {Boolean} + * @default true + */ + this.enableLook = true; + /** + * A parameter in the range <code>[0, 1)</code> used to determine how long + * the camera will continue to spin because of inertia. + * With value of zero, the camera will have no inertia. + * @type {Number} + * @default 0.9 + */ + this.inertiaSpin = 0.9; + /** + * A parameter in the range <code>[0, 1)</code> used to determine how long + * the camera will continue to translate because of inertia. + * With value of zero, the camera will have no inertia. + * @type {Number} + * @default 0.9 + */ + this.inertiaTranslate = 0.9; + /** + * A parameter in the range <code>[0, 1)</code> used to determine how long + * the camera will continue to zoom because of inertia. + * With value of zero, the camera will have no inertia. + * @type {Number} + * @default 0.8 + */ + this.inertiaZoom = 0.8; + /** + * A parameter in the range <code>[0, 1)</code> used to limit the range + * of various user inputs to a percentage of the window width/height per animation frame. + * This helps keep the camera under control in low-frame-rate situations. + * @type {Number} + * @default 0.1 + */ + this.maximumMovementRatio = 0.1; + /** + * Sets the duration, in seconds, of the bounce back animations in 2D and Columbus view. + * @type {Number} + * @default 3.0 + */ + this.bounceAnimationTime = 3.0; + /** + * The minimum magnitude, in meters, of the camera position when zooming. Defaults to 1.0. + * @type {Number} + * @default 1.0 + */ + this.minimumZoomDistance = 1.0; + /** + * The maximum magnitude, in meters, of the camera position when zooming. Defaults to positive infinity. + * @type {Number} + * @default {@link Number.POSITIVE_INFINITY} + */ + this.maximumZoomDistance = Number.POSITIVE_INFINITY; + /** + * The input that allows the user to pan around the map. This only applies in 2D and Columbus view modes. + * <p> + * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> + * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, + * or an array of any of the preceding. + * </p> + * @type {CameraEventType|Array|undefined} + * @default {@link CameraEventType.LEFT_DRAG} + */ + this.translateEventTypes = CameraEventType.LEFT_DRAG; + /** + * The input that allows the user to zoom in/out. + * <p> + * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> + * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, + * or an array of any of the preceding. + * </p> + * @type {CameraEventType|Array|undefined} + * @default [{@link CameraEventType.RIGHT_DRAG}, {@link CameraEventType.WHEEL}, {@link CameraEventType.PINCH}] + */ + this.zoomEventTypes = [CameraEventType.RIGHT_DRAG, CameraEventType.WHEEL, CameraEventType.PINCH]; + /** + * The input that allows the user to rotate around the globe or another object. This only applies in 3D and Columbus view modes. + * <p> + * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> + * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, + * or an array of any of the preceding. + * </p> + * @type {CameraEventType|Array|undefined} + * @default {@link CameraEventType.LEFT_DRAG} + */ + this.rotateEventTypes = CameraEventType.LEFT_DRAG; + /** + * The input that allows the user to tilt in 3D and Columbus view or twist in 2D. + * <p> + * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> + * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, + * or an array of any of the preceding. + * </p> + * @type {CameraEventType|Array|undefined} + * @default [{@link CameraEventType.MIDDLE_DRAG}, {@link CameraEventType.PINCH}, { + * eventType : {@link CameraEventType.LEFT_DRAG}, + * modifier : {@link KeyboardEventModifier.CTRL} + * }, { + * eventType : {@link CameraEventType.RIGHT_DRAG}, + * modifier : {@link KeyboardEventModifier.CTRL} + * }] + */ + this.tiltEventTypes = [CameraEventType.MIDDLE_DRAG, CameraEventType.PINCH, { + eventType : CameraEventType.LEFT_DRAG, + modifier : KeyboardEventModifier.CTRL + }, { + eventType : CameraEventType.RIGHT_DRAG, + modifier : KeyboardEventModifier.CTRL + }]; + /** + * The input that allows the user to change the direction the camera is viewing. This only applies in 3D and Columbus view modes. + * <p> + * The type came be a {@link CameraEventType}, <code>undefined</code>, an object with <code>eventType</code> + * and <code>modifier</code> properties with types <code>CameraEventType</code> and {@link KeyboardEventModifier}, + * or an array of any of the preceding. + * </p> + * @type {CameraEventType|Array|undefined} + * @default { eventType : {@link CameraEventType.LEFT_DRAG}, modifier : {@link KeyboardEventModifier.SHIFT} } + */ + this.lookEventTypes = { + eventType : CameraEventType.LEFT_DRAG, + modifier : KeyboardEventModifier.SHIFT + }; + /** + * The minimum height the camera must be before picking the terrain instead of the ellipsoid. + * @type {Number} + * @default 150000.0 + */ + this.minimumPickingTerrainHeight = 150000.0; + this._minimumPickingTerrainHeight = this.minimumPickingTerrainHeight; + /** + * The minimum height the camera must be before testing for collision with terrain. + * @type {Number} + * @default 10000.0 + */ + this.minimumCollisionTerrainHeight = 15000.0; + this._minimumCollisionTerrainHeight = this.minimumCollisionTerrainHeight; + /** + * The minimum height the camera must be before switching from rotating a track ball to + * free look when clicks originate on the sky on in space. + * @type {Number} + * @default 7500000.0 + */ + this.minimumTrackBallHeight = 7500000.0; + this._minimumTrackBallHeight = this.minimumTrackBallHeight; + /** + * Enables or disables camera collision detection with terrain. + * @type {Boolean} + * @default true + */ + this.enableCollisionDetection = true; - var canvas = scene.canvas; - - var windowPosition = tilt3DWindowPos; - windowPosition.x = canvas.clientWidth / 2; - windowPosition.y = canvas.clientHeight / 2; - var ray = camera.getPickRay(windowPosition, tilt3DRay); + this._scene = scene; + this._globe = undefined; + this._ellipsoid = undefined; - var center; - var intersection = IntersectionTests.rayEllipsoid(ray, ellipsoid); - if (defined(intersection)) { - center = Ray.getPoint(ray, intersection.start, tilt3DCenter); - } else if (height > controller._minimumTrackBallHeight) { - var grazingAltitudeLocation = IntersectionTests.grazingAltitudeLocation(ray, ellipsoid); - if (!defined(grazingAltitudeLocation)) { - return; - } - var grazingAltitudeCart = ellipsoid.cartesianToCartographic(grazingAltitudeLocation, tilt3DCart); - grazingAltitudeCart.height = 0.0; - center = ellipsoid.cartographicToCartesian(grazingAltitudeCart, tilt3DCenter); - } else { - controller._looking = true; - var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, tilt3DLookUp); - look3D(controller, startPosition, movement, up); - Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); - return; - } + this._aggregator = new CameraEventAggregator(scene.canvas); - var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, tilt3DTransform); + this._lastInertiaSpinMovement = undefined; + this._lastInertiaZoomMovement = undefined; + this._lastInertiaTranslateMovement = undefined; + this._lastInertiaTiltMovement = undefined; - var oldGlobe = controller._globe; - var oldEllipsoid = controller._ellipsoid; - controller._globe = undefined; - controller._ellipsoid = Ellipsoid.UNIT_SPHERE; - controller._rotateFactor = 1.0; - controller._rotateRateRangeAdjustment = 1.0; + this._tweens = new TweenCollection(); + this._tween = undefined; - var oldTransform = Matrix4.clone(camera.transform, tilt3DOldTransform); - camera._setTransform(transform); + this._horizontalRotationAxis = undefined; - rotate3D(controller, startPosition, movement, Cartesian3.UNIT_Z); + this._tiltCenterMousePosition = new Cartesian2(-1.0, -1.0); + this._tiltCenter = new Cartesian3(); + this._rotateMousePosition = new Cartesian2(-1.0, -1.0); + this._rotateStartPosition = new Cartesian3(); + this._strafeStartPosition = new Cartesian3(); + this._zoomMouseStart = new Cartesian2(-1.0, -1.0); + this._zoomWorldPosition = new Cartesian3(); + this._useZoomWorldPosition = false; + this._tiltCVOffMap = false; + this._looking = false; + this._rotating = false; + this._strafing = false; + this._zoomingOnVector = false; + this._rotatingZoom = false; - camera._setTransform(oldTransform); - controller._globe = oldGlobe; - controller._ellipsoid = oldEllipsoid; + var projection = scene.mapProjection; + this._maxCoord = projection.project(new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO)); - var radius = oldEllipsoid.maximumRadius; - controller._rotateFactor = 1.0 / radius; - controller._rotateRateRangeAdjustment = radius; + // Constants, Make any of these public? + this._zoomFactor = 5.0; + this._rotateFactor = undefined; + this._rotateRateRangeAdjustment = undefined; + this._maximumRotateRate = 1.77; + this._minimumRotateRate = 1.0 / 5000.0; + this._minimumZoomRate = 20.0; + this._maximumZoomRate = 5906376272000.0; // distance from the Sun to Pluto in meters. } - function tilt3DOnTerrain(controller, startPosition, movement) { - var ellipsoid = controller._ellipsoid; - var scene = controller._scene; - var camera = scene.camera; - - var center; - var ray; - var intersection; - - if (Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { - center = Cartesian3.clone(controller._tiltCenter, tilt3DCenter); - } else { - center = pickGlobe(controller, startPosition, tilt3DCenter); - - if (!defined(center)) { - ray = camera.getPickRay(startPosition, tilt3DRay); - intersection = IntersectionTests.rayEllipsoid(ray, ellipsoid); - if (!defined(intersection)) { - var cartographic = ellipsoid.cartesianToCartographic(camera.position, tilt3DCart); - if (cartographic.height <= controller._minimumTrackBallHeight) { - controller._looking = true; - var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, tilt3DLookUp); - look3D(controller, startPosition, movement, up); - Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); - } - return; - } - center = Ray.getPoint(ray, intersection.start, tilt3DCenter); - } - - Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); - Cartesian3.clone(center, controller._tiltCenter); + function decay(time, coefficient) { + if (time < 0) { + return 0.0; } - var canvas = scene.canvas; + var tau = (1.0 - coefficient) * 25.0; + return Math.exp(-tau * time); + } - var windowPosition = tilt3DWindowPos; - windowPosition.x = canvas.clientWidth / 2; - windowPosition.y = controller._tiltCenterMousePosition.y; - ray = camera.getPickRay(windowPosition, tilt3DRay); + function sameMousePosition(movement) { + return Cartesian2.equalsEpsilon(movement.startPosition, movement.endPosition, CesiumMath.EPSILON14); + } - var mag = Cartesian3.magnitude(center); - var radii = Cartesian3.fromElements(mag, mag, mag, scratchRadii); - var newEllipsoid = Ellipsoid.fromCartesian3(radii, scratchEllipsoid); + // If the time between mouse down and mouse up is not between + // these thresholds, the camera will not move with inertia. + // This value is probably dependent on the browser and/or the + // hardware. Should be investigated further. + var inertiaMaxClickTimeThreshold = 0.4; - intersection = IntersectionTests.rayEllipsoid(ray, newEllipsoid); - if (!defined(intersection)) { - return; + function maintainInertia(aggregator, type, modifier, decayCoef, action, object, lastMovementName) { + var movementState = object[lastMovementName]; + if (!defined(movementState)) { + movementState = object[lastMovementName] = { + startPosition : new Cartesian2(), + endPosition : new Cartesian2(), + motion : new Cartesian2(), + active : false + }; } - var t = Cartesian3.magnitude(ray.origin) > mag ? intersection.start : intersection.stop; - var verticalCenter = Ray.getPoint(ray, t, tilt3DVerticalCenter); + var ts = aggregator.getButtonPressTime(type, modifier); + var tr = aggregator.getButtonReleaseTime(type, modifier); - var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, tilt3DTransform); - var verticalTransform = Transforms.eastNorthUpToFixedFrame(verticalCenter, newEllipsoid, tilt3DVerticalTransform); + var threshold = ts && tr && ((tr.getTime() - ts.getTime()) / 1000.0); + var now = new Date(); + var fromNow = tr && ((now.getTime() - tr.getTime()) / 1000.0); - var oldGlobe = controller._globe; - var oldEllipsoid = controller._ellipsoid; - controller._globe = undefined; - controller._ellipsoid = Ellipsoid.UNIT_SPHERE; - controller._rotateFactor = 1.0; - controller._rotateRateRangeAdjustment = 1.0; + if (ts && tr && threshold < inertiaMaxClickTimeThreshold) { + var d = decay(fromNow, decayCoef); - var constrainedAxis = Cartesian3.UNIT_Z; + if (!movementState.active) { + var lastMovement = aggregator.getLastMovement(type, modifier); + if (!defined(lastMovement) || sameMousePosition(lastMovement)) { + return; + } - var oldTransform = Matrix4.clone(camera.transform, tilt3DOldTransform); - camera._setTransform(transform); + movementState.motion.x = (lastMovement.endPosition.x - lastMovement.startPosition.x) * 0.5; + movementState.motion.y = (lastMovement.endPosition.y - lastMovement.startPosition.y) * 0.5; - var tangent = Cartesian3.cross(verticalCenter, camera.positionWC, tilt3DCartesian3); - var dot = Cartesian3.dot(camera.rightWC, tangent); + movementState.startPosition = Cartesian2.clone(lastMovement.startPosition, movementState.startPosition); - rotate3D(controller, startPosition, movement, constrainedAxis, false, true); + movementState.endPosition = Cartesian2.multiplyByScalar(movementState.motion, d, movementState.endPosition); + movementState.endPosition = Cartesian2.add(movementState.startPosition, movementState.endPosition, movementState.endPosition); - camera._setTransform(verticalTransform); + movementState.active = true; + } else { + movementState.startPosition = Cartesian2.clone(movementState.endPosition, movementState.startPosition); - if (dot < 0.0) { - if (movement.startPosition.y > movement.endPosition.y) { - constrainedAxis = undefined; - } + movementState.endPosition = Cartesian2.multiplyByScalar(movementState.motion, d, movementState.endPosition); + movementState.endPosition = Cartesian2.add(movementState.startPosition, movementState.endPosition, movementState.endPosition); - var oldConstrainedAxis = camera.constrainedAxis; - camera.constrainedAxis = undefined; + movementState.motion = Cartesian2.clone(Cartesian2.ZERO, movementState.motion); + } - rotate3D(controller, startPosition, movement, constrainedAxis, true, false); + // If value from the decreasing exponential function is close to zero, + // the end coordinates may be NaN. + if (isNaN(movementState.endPosition.x) || isNaN(movementState.endPosition.y) || Cartesian2.distance(movementState.startPosition, movementState.endPosition) < 0.5) { + movementState.active = false; + return; + } - camera.constrainedAxis = oldConstrainedAxis; + if (!aggregator.isButtonDown(type, modifier)) { + var startPosition = aggregator.getStartMousePosition(type, modifier); + action(object, startPosition, movementState); + } } else { - rotate3D(controller, startPosition, movement, constrainedAxis, true, false); + movementState.active = false; } + } - if (defined(camera.constrainedAxis)) { - var right = Cartesian3.cross(camera.direction, camera.constrainedAxis, tilt3DCartesian3); - if (!Cartesian3.equalsEpsilon(right, Cartesian3.ZERO, CesiumMath.EPSILON6)) { - if (Cartesian3.dot(right, camera.right) < 0.0) { - Cartesian3.negate(right, right); - } - - Cartesian3.cross(right, camera.direction, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); + var scratchEventTypeArray = []; - Cartesian3.normalize(camera.up, camera.up); - Cartesian3.normalize(camera.right, camera.right); - } + function reactToInput(controller, enabled, eventTypes, action, inertiaConstant, inertiaStateName) { + if (!defined(eventTypes)) { + return; } - camera._setTransform(oldTransform); - controller._globe = oldGlobe; - controller._ellipsoid = oldEllipsoid; + var aggregator = controller._aggregator; - var radius = oldEllipsoid.maximumRadius; - controller._rotateFactor = 1.0 / radius; - controller._rotateRateRangeAdjustment = radius; + if (!isArray(eventTypes)) { + scratchEventTypeArray[0] = eventTypes; + eventTypes = scratchEventTypeArray; + } - var originalPosition = Cartesian3.clone(camera.positionWC, tilt3DCartesian3); - camera._adjustHeightForTerrain(); + var length = eventTypes.length; + for (var i = 0; i < length; ++i) { + var eventType = eventTypes[i]; + var type = defined(eventType.eventType) ? eventType.eventType : eventType; + var modifier = eventType.modifier; - if (!Cartesian3.equals(camera.positionWC, originalPosition)) { - camera._setTransform(verticalTransform); - camera.worldToCameraCoordinatesPoint(originalPosition, originalPosition); + var movement = aggregator.isMoving(type, modifier) && aggregator.getMovement(type, modifier); + var startPosition = aggregator.getStartMousePosition(type, modifier); - var magSqrd = Cartesian3.magnitudeSquared(originalPosition); - if (Cartesian3.magnitudeSquared(camera.position) > magSqrd) { - Cartesian3.normalize(camera.position, camera.position); - Cartesian3.multiplyByScalar(camera.position, Math.sqrt(magSqrd), camera.position); + if (controller.enableInputs && enabled) { + if (movement) { + action(controller, startPosition, movement); + } else if (inertiaConstant < 1.0) { + maintainInertia(aggregator, type, modifier, inertiaConstant, action, controller, inertiaStateName); + } } - - var angle = Cartesian3.angleBetween(originalPosition, camera.position); - var axis = Cartesian3.cross(originalPosition, camera.position, originalPosition); - Cartesian3.normalize(axis, axis); - - var quaternion = Quaternion.fromAxisAngle(axis, angle, tilt3DQuaternion); - var rotation = Matrix3.fromQuaternion(quaternion, tilt3DMatrix); - Matrix3.multiplyByVector(rotation, camera.direction, camera.direction); - Matrix3.multiplyByVector(rotation, camera.up, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.cross(camera.right, camera.direction, camera.up); - - camera._setTransform(oldTransform); } } - var look3DStartPos = new Cartesian2(); - var look3DEndPos = new Cartesian2(); - var look3DStartRay = new Ray(); - var look3DEndRay = new Ray(); - var look3DNegativeRot = new Cartesian3(); - var look3DTan = new Cartesian3(); - - function look3D(controller, startPosition, movement, rotationAxis) { - var scene = controller._scene; - var camera = scene.camera; + var scratchZoomPickRay = new Ray(); + var scratchPickCartesian = new Cartesian3(); + var scratchZoomOffset = new Cartesian2(); + var scratchZoomDirection = new Cartesian3(); + var scratchCenterPixel = new Cartesian2(); + var scratchCenterPosition = new Cartesian3(); + var scratchPositionNormal = new Cartesian3(); + var scratchPickNormal = new Cartesian3(); + var scratchZoomAxis = new Cartesian3(); + var scratchCameraPositionNormal = new Cartesian3(); - var startPos = look3DStartPos; - startPos.x = movement.startPosition.x; - startPos.y = 0.0; - var endPos = look3DEndPos; - endPos.x = movement.endPosition.x; - endPos.y = 0.0; + // Scratch variables used in zooming algorithm + var scratchTargetNormal = new Cartesian3(); + var scratchCameraPosition = new Cartesian3(); + var scratchCameraUpNormal = new Cartesian3(); + var scratchCameraRightNormal = new Cartesian3(); + var scratchForwardNormal = new Cartesian3(); + var scratchPositionToTarget = new Cartesian3(); + var scratchPositionToTargetNormal = new Cartesian3(); + var scratchPan = new Cartesian3(); + var scratchCenterMovement = new Cartesian3(); + var scratchCenter = new Cartesian3(); + var scratchCartesian = new Cartesian3(); + var scratchCartesianTwo = new Cartesian3(); + var scratchCartesianThree = new Cartesian3(); + var scratchZoomViewOptions = { + orientation: new HeadingPitchRoll() + }; - var startRay = camera.getPickRay(startPos, look3DStartRay); - var endRay = camera.getPickRay(endPos, look3DEndRay); - var angle = 0.0; - var start; - var end; + function handleZoom(object, startPosition, movement, zoomFactor, distanceMeasure, unitPositionDotDirection) { + var percentage = 1.0; + if (defined(unitPositionDotDirection)) { + percentage = CesiumMath.clamp(Math.abs(unitPositionDotDirection), 0.25, 1.0); + } - if (camera.frustum instanceof OrthographicFrustum) { - start = startRay.origin; - end = endRay.origin; + // distanceMeasure should be the height above the ellipsoid. + // The zoomRate slows as it approaches the surface and stops minimumZoomDistance above it. + var minHeight = object.minimumZoomDistance * percentage; + var maxHeight = object.maximumZoomDistance; - Cartesian3.add(camera.direction, start, start); - Cartesian3.add(camera.direction, end, end); + var minDistance = distanceMeasure - minHeight; + var zoomRate = zoomFactor * minDistance; + zoomRate = CesiumMath.clamp(zoomRate, object._minimumZoomRate, object._maximumZoomRate); - Cartesian3.subtract(start, camera.position, start); - Cartesian3.subtract(end, camera.position, end); + var diff = movement.endPosition.y - movement.startPosition.y; + var rangeWindowRatio = diff / object._scene.canvas.clientHeight; + rangeWindowRatio = Math.min(rangeWindowRatio, object.maximumMovementRatio); + var distance = zoomRate * rangeWindowRatio; - Cartesian3.normalize(start, start); - Cartesian3.normalize(end, end); - } else { - start = startRay.direction; - end = endRay.direction; + if (distance > 0.0 && Math.abs(distanceMeasure - minHeight) < 1.0) { + return; } - var dot = Cartesian3.dot(start, end); - if (dot < 1.0) { // dot is in [0, 1] - angle = Math.acos(dot); + if (distance < 0.0 && Math.abs(distanceMeasure - maxHeight) < 1.0) { + return; } - angle = (movement.startPosition.x > movement.endPosition.x) ? -angle : angle; - - var horizontalRotationAxis = controller._horizontalRotationAxis; - if (defined(rotationAxis)) { - camera.look(rotationAxis, -angle); - } else if (defined(horizontalRotationAxis)) { - camera.look(horizontalRotationAxis, -angle); - } else { - camera.lookLeft(angle); + if (distanceMeasure - distance < minHeight) { + distance = distanceMeasure - minHeight - 1.0; + } else if (distanceMeasure - distance > maxHeight) { + distance = distanceMeasure - maxHeight; } - startPos.x = 0.0; - startPos.y = movement.startPosition.y; - endPos.x = 0.0; - endPos.y = movement.endPosition.y; + var scene = object._scene; + var camera = scene.camera; + var mode = scene.mode; - startRay = camera.getPickRay(startPos, look3DStartRay); - endRay = camera.getPickRay(endPos, look3DEndRay); - angle = 0.0; + var orientation = scratchZoomViewOptions.orientation; + orientation.heading = camera.heading; + orientation.pitch = camera.pitch; + orientation.roll = camera.roll; if (camera.frustum instanceof OrthographicFrustum) { - start = startRay.origin; - end = endRay.origin; - - Cartesian3.add(camera.direction, start, start); - Cartesian3.add(camera.direction, end, end); - - Cartesian3.subtract(start, camera.position, start); - Cartesian3.subtract(end, camera.position, end); - - Cartesian3.normalize(start, start); - Cartesian3.normalize(end, end); - } else { - start = startRay.direction; - end = endRay.direction; - } - - dot = Cartesian3.dot(start, end); - if (dot < 1.0) { // dot is in [0, 1] - angle = Math.acos(dot); + if (Math.abs(distance) > 0.0) { + camera.zoomIn(distance); + camera._adjustOrthographicFrustum(); + } + return; } - angle = (movement.startPosition.y > movement.endPosition.y) ? -angle : angle; - rotationAxis = defaultValue(rotationAxis, horizontalRotationAxis); - if (defined(rotationAxis)) { - var direction = camera.direction; - var negativeRotationAxis = Cartesian3.negate(rotationAxis, look3DNegativeRot); - var northParallel = Cartesian3.equalsEpsilon(direction, rotationAxis, CesiumMath.EPSILON2); - var southParallel = Cartesian3.equalsEpsilon(direction, negativeRotationAxis, CesiumMath.EPSILON2); - if ((!northParallel && !southParallel)) { - dot = Cartesian3.dot(direction, rotationAxis); - var angleToAxis = CesiumMath.acosClamped(dot); - if (angle > 0 && angle > angleToAxis) { - angle = angleToAxis - CesiumMath.EPSILON4; - } + var sameStartPosition = Cartesian2.equals(startPosition, object._zoomMouseStart); + var zoomingOnVector = object._zoomingOnVector; + var rotatingZoom = object._rotatingZoom; + var pickedPosition; - dot = Cartesian3.dot(direction, negativeRotationAxis); - angleToAxis = CesiumMath.acosClamped(dot); - if (angle < 0 && -angle > angleToAxis) { - angle = -angleToAxis + CesiumMath.EPSILON4; - } + if (!sameStartPosition) { + object._zoomMouseStart = Cartesian2.clone(startPosition, object._zoomMouseStart); - var tangent = Cartesian3.cross(rotationAxis, direction, look3DTan); - camera.look(tangent, angle); - } else if ((northParallel && angle < 0) || (southParallel && angle > 0)) { - camera.look(camera.right, -angle); + if (defined(object._globe)) { + pickedPosition = mode !== SceneMode.SCENE2D ? pickGlobe(object, startPosition, scratchPickCartesian) : camera.getPickRay(startPosition, scratchZoomPickRay).origin; + } + if (defined(pickedPosition)) { + object._useZoomWorldPosition = true; + object._zoomWorldPosition = Cartesian3.clone(pickedPosition, object._zoomWorldPosition); + } else { + object._useZoomWorldPosition = false; } - } else { - camera.lookUp(angle); - } - } - - function update3D(controller) { - reactToInput(controller, controller.enableRotate, controller.rotateEventTypes, spin3D, controller.inertiaSpin, '_lastInertiaSpinMovement'); - reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom3D, controller.inertiaZoom, '_lastInertiaZoomMovement'); - reactToInput(controller, controller.enableTilt, controller.tiltEventTypes, tilt3D, controller.inertiaSpin, '_lastInertiaTiltMovement'); - reactToInput(controller, controller.enableLook, controller.lookEventTypes, look3D); - } - /** - * @private - */ - ScreenSpaceCameraController.prototype.update = function() { - if (!Matrix4.equals(this._scene.camera.transform, Matrix4.IDENTITY)) { - this._globe = undefined; - this._ellipsoid = Ellipsoid.UNIT_SPHERE; - } else { - this._globe = this._scene.globe; - this._ellipsoid = defined(this._globe) ? this._globe.ellipsoid : this._scene.mapProjection.ellipsoid; + zoomingOnVector = object._zoomingOnVector = false; + rotatingZoom = object._rotatingZoom = false; } - this._minimumCollisionTerrainHeight = this.minimumCollisionTerrainHeight * this._scene.terrainExaggeration; - this._minimumPickingTerrainHeight = this.minimumPickingTerrainHeight * this._scene.terrainExaggeration; - this._minimumTrackBallHeight = this.minimumTrackBallHeight * this._scene.terrainExaggeration; - - var radius = this._ellipsoid.maximumRadius; - this._rotateFactor = 1.0 / radius; - this._rotateRateRangeAdjustment = radius; - - var scene = this._scene; - var mode = scene.mode; - if (mode === SceneMode.SCENE2D) { - update2D(this); - } else if (mode === SceneMode.COLUMBUS_VIEW) { - this._horizontalRotationAxis = Cartesian3.UNIT_Z; - updateCV(this); - } else if (mode === SceneMode.SCENE3D) { - this._horizontalRotationAxis = undefined; - update3D(this); + if (!object._useZoomWorldPosition) { + camera.zoomIn(distance); + return; } - this._aggregator.reset(); - }; - - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see ScreenSpaceCameraController#destroy - */ - ScreenSpaceCameraController.prototype.isDestroyed = function() { - return false; - }; - - /** - * Removes mouse listeners held by this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * controller = controller && controller.destroy(); - * - * @see ScreenSpaceCameraController#isDestroyed - */ - ScreenSpaceCameraController.prototype.destroy = function() { - this._tweens.removeAll(); - this._aggregator = this._aggregator && this._aggregator.destroy(); - return destroyObject(this); - }; + var zoomOnVector = mode === SceneMode.COLUMBUS_VIEW; - return ScreenSpaceCameraController; -}); + if (camera.positionCartographic.height < 2000000) { + rotatingZoom = true; + } -define('Scene/ShadowMapShader',[ - '../Core/defined', - '../Renderer/ShaderSource' - ], function( - defined, - ShaderSource) { - 'use strict'; + if (!sameStartPosition || rotatingZoom) { + if (mode === SceneMode.SCENE2D) { + var worldPosition = object._zoomWorldPosition; + var endPosition = camera.position; - /** - * @private - */ - function ShadowMapShader() { - } + if (!Cartesian3.equals(worldPosition, endPosition) && camera.positionCartographic.height < object._maxCoord.x * 2.0) { + var savedX = camera.position.x; - ShadowMapShader.getShadowCastShaderKeyword = function(isPointLight, isTerrain, usesDepthTexture, isOpaque) { - return 'castShadow ' + isPointLight + ' ' + isTerrain + ' ' + usesDepthTexture + ' ' + isOpaque; - }; + var direction = Cartesian3.subtract(worldPosition, endPosition, scratchZoomDirection); + Cartesian3.normalize(direction, direction); - ShadowMapShader.createShadowCastVertexShader = function(vs, isPointLight, isTerrain) { - var defines = vs.defines.slice(0); - var sources = vs.sources.slice(0); + var d = Cartesian3.distance(worldPosition, endPosition) * distance / (camera.getMagnitude() * 0.5); + camera.move(direction, d * 0.5); - if (isTerrain) { - defines.push('GENERATE_POSITION'); - } + if ((camera.position.x < 0.0 && savedX > 0.0) || (camera.position.x > 0.0 && savedX < 0.0)) { + pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay).origin; + object._zoomWorldPosition = Cartesian3.clone(pickedPosition, object._zoomWorldPosition); + } + } + } else if (mode === SceneMode.SCENE3D) { + var cameraPositionNormal = Cartesian3.normalize(camera.position, scratchCameraPositionNormal); + if (camera.positionCartographic.height < 3000.0 && Math.abs(Cartesian3.dot(camera.direction, cameraPositionNormal)) < 0.6) { + zoomOnVector = true; + } else { + var canvas = scene.canvas; - var positionVaryingName = ShaderSource.findPositionVarying(vs); - var hasPositionVarying = defined(positionVaryingName); + var centerPixel = scratchCenterPixel; + centerPixel.x = canvas.clientWidth / 2; + centerPixel.y = canvas.clientHeight / 2; + var centerPosition = pickGlobe(object, centerPixel, scratchCenterPosition); + // If centerPosition is not defined, it means the globe does not cover the center position of screen - if (isPointLight && !hasPositionVarying) { - var length = sources.length; - for (var j = 0; j < length; ++j) { - sources[j] = ShaderSource.replaceMain(sources[j], 'czm_shadow_cast_main'); - } + if (defined(centerPosition) && camera.positionCartographic.height < 1000000) { - var shadowVS = - 'varying vec3 v_positionEC; \n' + - 'void main() \n' + - '{ \n' + - ' czm_shadow_cast_main(); \n' + - ' v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n' + - '}'; - sources.push(shadowVS); - } + var cameraPosition = scratchCameraPosition; + Cartesian3.clone(camera.position, cameraPosition); + var target = object._zoomWorldPosition; - return new ShaderSource({ - defines : defines, - sources : sources - }); - }; + var targetNormal = scratchTargetNormal; - ShadowMapShader.createShadowCastFragmentShader = function(fs, isPointLight, usesDepthTexture, opaque) { - var defines = fs.defines.slice(0); - var sources = fs.sources.slice(0); + targetNormal = Cartesian3.normalize(target, targetNormal); - var positionVaryingName = ShaderSource.findPositionVarying(fs); - var hasPositionVarying = defined(positionVaryingName); - if (!hasPositionVarying) { - positionVaryingName = 'v_positionEC'; - } + if (Cartesian3.dot(targetNormal, cameraPositionNormal) < 0.0) { + return; + } - var length = sources.length; - for (var i = 0; i < length; ++i) { - sources[i] = ShaderSource.replaceMain(sources[i], 'czm_shadow_cast_main'); - } + var center = scratchCenter; + var forward = scratchForwardNormal; + Cartesian3.clone(camera.direction, forward); + Cartesian3.add(cameraPosition, Cartesian3.multiplyByScalar(forward, 1000, scratchCartesian), center); - var fsSource = ''; + var positionToTarget = scratchPositionToTarget; + var positionToTargetNormal = scratchPositionToTargetNormal; + Cartesian3.subtract(target, cameraPosition, positionToTarget); - if (isPointLight) { - if (!hasPositionVarying) { - fsSource += 'varying vec3 v_positionEC; \n'; - } - fsSource += 'uniform vec4 shadowMap_lightPositionEC; \n'; - } + Cartesian3.normalize(positionToTarget, positionToTargetNormal); - if (opaque) { - fsSource += - 'void main() \n' + - '{ \n'; - } else { - fsSource += - 'void main() \n' + - '{ \n' + - ' czm_shadow_cast_main(); \n' + - ' if (gl_FragColor.a == 0.0) \n' + - ' { \n' + - ' discard; \n' + - ' } \n'; - } + var alphaDot = Cartesian3.dot(cameraPositionNormal, positionToTargetNormal); + if (alphaDot >= 0.0) { + // We zoomed past the target, and this zoom is not valid anymore. + // This line causes the next zoom movement to pick a new starting point. + object._zoomMouseStart.x = -1; + return; + } + var alpha = Math.acos(-alphaDot); + var cameraDistance = Cartesian3.magnitude( cameraPosition ); + var targetDistance = Cartesian3.magnitude( target ); + var remainingDistance = cameraDistance - distance; + var positionToTargetDistance = Cartesian3.magnitude(positionToTarget); - if (isPointLight) { - fsSource += - 'float distance = length(' + positionVaryingName + '); \n' + - 'distance /= shadowMap_lightPositionEC.w; // radius \n' + - 'gl_FragColor = czm_packDepth(distance); \n'; - } else if (usesDepthTexture) { - fsSource += 'gl_FragColor = vec4(1.0); \n'; - } else { - fsSource += 'gl_FragColor = czm_packDepth(gl_FragCoord.z); \n'; - } + var gamma = Math.asin( CesiumMath.clamp( positionToTargetDistance / targetDistance * Math.sin(alpha), -1.0, 1.0 ) ); + var delta = Math.asin( CesiumMath.clamp( remainingDistance / targetDistance * Math.sin(alpha), -1.0, 1.0 ) ); + var beta = gamma - delta + alpha; - fsSource += '} \n'; + var up = scratchCameraUpNormal; + Cartesian3.normalize(cameraPosition, up); + var right = scratchCameraRightNormal; + right = Cartesian3.cross(positionToTargetNormal, up, right); + right = Cartesian3.normalize(right, right ); - sources.push(fsSource); + Cartesian3.normalize( Cartesian3.cross(up, right, scratchCartesian), forward ); - return new ShaderSource({ - defines : defines, - sources : sources - }); - }; + // Calculate new position to move to + Cartesian3.multiplyByScalar(Cartesian3.normalize(center, scratchCartesian), (Cartesian3.magnitude(center) - distance), center); + Cartesian3.normalize(cameraPosition, cameraPosition); + Cartesian3.multiplyByScalar(cameraPosition, remainingDistance, cameraPosition); - ShadowMapShader.getShadowReceiveShaderKeyword = function(shadowMap, castShadows, isTerrain, hasTerrainNormal) { - var usesDepthTexture = shadowMap._usesDepthTexture; - var polygonOffsetSupported = shadowMap._polygonOffsetSupported; - var isPointLight = shadowMap._isPointLight; - var isSpotLight = shadowMap._isSpotLight; - var hasCascades = shadowMap._numberOfCascades > 1; - var debugCascadeColors = shadowMap.debugCascadeColors; - var softShadows = shadowMap.softShadows; + // Pan + var pMid = scratchPan; + Cartesian3.multiplyByScalar(Cartesian3.add( + Cartesian3.multiplyByScalar(up, Math.cos(beta) - 1, scratchCartesianTwo), + Cartesian3.multiplyByScalar(forward, Math.sin(beta), scratchCartesianThree), + scratchCartesian + ), remainingDistance, pMid); + Cartesian3.add(cameraPosition, pMid, cameraPosition); - return 'receiveShadow ' + usesDepthTexture + polygonOffsetSupported + isPointLight + isSpotLight + - hasCascades + debugCascadeColors + softShadows + castShadows + isTerrain + hasTerrainNormal; - }; + Cartesian3.normalize(center, up); + Cartesian3.normalize( Cartesian3.cross(up, right, scratchCartesian), forward ); - ShadowMapShader.createShadowReceiveVertexShader = function(vs, isTerrain, hasTerrainNormal) { - var defines = vs.defines.slice(0); - var sources = vs.sources.slice(0); + var cMid = scratchCenterMovement; + Cartesian3.multiplyByScalar(Cartesian3.add( + Cartesian3.multiplyByScalar(up, Math.cos(beta) - 1, scratchCartesianTwo), + Cartesian3.multiplyByScalar(forward, Math.sin(beta), scratchCartesianThree), + scratchCartesian + ), Cartesian3.magnitude(center), cMid); + Cartesian3.add(center, cMid, center); - if (isTerrain) { - if (hasTerrainNormal) { - defines.push('GENERATE_POSITION_AND_NORMAL'); - } else { - defines.push('GENERATE_POSITION'); - } - } + // Update camera - return new ShaderSource({ - defines : defines, - sources : sources - }); - }; + // Set new position + Cartesian3.clone(cameraPosition, camera.position); - ShadowMapShader.createShadowReceiveFragmentShader = function(fs, shadowMap, castShadows, isTerrain, hasTerrainNormal) { - var normalVaryingName = ShaderSource.findNormalVarying(fs); - var hasNormalVarying = (!isTerrain && defined(normalVaryingName)) || (isTerrain && hasTerrainNormal); + // Set new direction + Cartesian3.normalize(Cartesian3.subtract(center, cameraPosition, scratchCartesian), camera.direction); + Cartesian3.clone(camera.direction, camera.direction); - var positionVaryingName = ShaderSource.findPositionVarying(fs); - var hasPositionVarying = defined(positionVaryingName); + // Set new right & up vectors + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.cross(camera.right, camera.direction, camera.up); - var usesDepthTexture = shadowMap._usesDepthTexture; - var polygonOffsetSupported = shadowMap._polygonOffsetSupported; - var isPointLight = shadowMap._isPointLight; - var isSpotLight = shadowMap._isSpotLight; - var hasCascades = shadowMap._numberOfCascades > 1; - var debugCascadeColors = shadowMap.debugCascadeColors; - var softShadows = shadowMap.softShadows; - var bias = isPointLight ? shadowMap._pointBias : (isTerrain ? shadowMap._terrainBias : shadowMap._primitiveBias); + camera.setView(scratchZoomViewOptions); + return; + } - var defines = fs.defines.slice(0); - var sources = fs.sources.slice(0); + if (defined(centerPosition)) { + var positionNormal = Cartesian3.normalize(centerPosition, scratchPositionNormal); + var pickedNormal = Cartesian3.normalize(object._zoomWorldPosition, scratchPickNormal); + var dotProduct = Cartesian3.dot(pickedNormal, positionNormal); - var length = sources.length; - for (var i = 0; i < length; ++i) { - sources[i] = ShaderSource.replaceMain(sources[i], 'czm_shadow_receive_main'); - } + if (dotProduct > 0.0 && dotProduct < 1.0) { + var angle = CesiumMath.acosClamped(dotProduct); + var axis = Cartesian3.cross(pickedNormal, positionNormal, scratchZoomAxis); - if (isPointLight) { - defines.push('USE_CUBE_MAP_SHADOW'); - } else if (usesDepthTexture) { - defines.push('USE_SHADOW_DEPTH_TEXTURE'); - } + var denom = Math.abs(angle) > CesiumMath.toRadians(20.0) ? camera.positionCartographic.height * 0.75 : camera.positionCartographic.height - distance; + var scalar = distance / denom; + camera.rotate(axis, angle * scalar); + } + } else { + zoomOnVector = true; + } + } + } - if (softShadows && !isPointLight) { - defines.push('USE_SOFT_SHADOWS'); + object._rotatingZoom = !zoomOnVector; } - // Enable day-night shading so that the globe is dark when the light is below the horizon - if (hasCascades && castShadows && isTerrain) { - if (hasNormalVarying) { - defines.push('ENABLE_VERTEX_LIGHTING'); + if ((!sameStartPosition && zoomOnVector) || zoomingOnVector) { + var ray; + var zoomMouseStart = SceneTransforms.wgs84ToWindowCoordinates(scene, object._zoomWorldPosition, scratchZoomOffset); + if (mode !== SceneMode.COLUMBUS_VIEW && Cartesian2.equals(startPosition, object._zoomMouseStart) && defined(zoomMouseStart)) { + ray = camera.getPickRay(zoomMouseStart, scratchZoomPickRay); } else { - defines.push('ENABLE_DAYNIGHT_SHADING'); + ray = camera.getPickRay(startPosition, scratchZoomPickRay); } - } - if (castShadows && bias.normalShading && hasNormalVarying) { - defines.push('USE_NORMAL_SHADING'); - if (bias.normalShadingSmooth > 0.0) { - defines.push('USE_NORMAL_SHADING_SMOOTH'); + var rayDirection = ray.direction; + if (mode === SceneMode.COLUMBUS_VIEW) { + Cartesian3.fromElements(rayDirection.y, rayDirection.z, rayDirection.x, rayDirection); } - } - var fsSource = ''; + camera.move(rayDirection, distance); - if (isPointLight) { - fsSource += 'uniform samplerCube shadowMap_textureCube; \n'; + object._zoomingOnVector = true; } else { - fsSource += 'uniform sampler2D shadowMap_texture; \n'; + camera.zoomIn(distance); } - fsSource += - 'uniform mat4 shadowMap_matrix; \n' + - 'uniform vec3 shadowMap_lightDirectionEC; \n' + - 'uniform vec4 shadowMap_lightPositionEC; \n' + - 'uniform vec4 shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness; \n' + - 'uniform vec4 shadowMap_texelSizeDepthBiasAndNormalShadingSmooth; \n' + - 'vec4 getPositionEC() \n' + - '{ \n' + - (hasPositionVarying ? - ' return vec4(' + positionVaryingName + ', 1.0); \n' : - ' return czm_windowToEyeCoordinates(gl_FragCoord); \n') + - '} \n' + - 'vec3 getNormalEC() \n' + - '{ \n' + - (hasNormalVarying ? - ' return normalize(' + normalVaryingName + '); \n' : - ' return vec3(1.0); \n') + - '} \n' + + camera.setView(scratchZoomViewOptions); + } - // Offset the shadow position in the direction of the normal for perpendicular and back faces - 'void applyNormalOffset(inout vec4 positionEC, vec3 normalEC, float nDotL) \n' + - '{ \n' + - (bias.normalOffset && hasNormalVarying ? - ' float normalOffset = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.x; \n' + - ' float normalOffsetScale = 1.0 - nDotL; \n' + - ' vec3 offset = normalOffset * normalOffsetScale * normalEC; \n' + - ' positionEC.xyz += offset; \n' : '') + - '} \n'; + var translate2DStart = new Ray(); + var translate2DEnd = new Ray(); + var scratchTranslateP0 = new Cartesian3(); - fsSource += - 'void main() \n' + - '{ \n' + - ' czm_shadow_receive_main(); \n' + - ' vec4 positionEC = getPositionEC(); \n' + - ' vec3 normalEC = getNormalEC(); \n' + - ' float depth = -positionEC.z; \n'; + function translate2D(controller, startPosition, movement) { + var scene = controller._scene; + var camera = scene.camera; + var start = camera.getPickRay(movement.startPosition, translate2DStart).origin; + var end = camera.getPickRay(movement.endPosition, translate2DEnd).origin; - fsSource += - ' czm_shadowParameters shadowParameters; \n' + - ' shadowParameters.texelStepSize = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.xy; \n' + - ' shadowParameters.depthBias = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.z; \n' + - ' shadowParameters.normalShadingSmooth = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.w; \n' + - ' shadowParameters.darkness = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.w; \n'; + var direction = Cartesian3.subtract(start, end, scratchTranslateP0); + var distance = Cartesian3.magnitude(direction); - if (isTerrain) { - // Scale depth bias based on view distance to reduce z-fighting in distant terrain - fsSource += ' shadowParameters.depthBias *= max(depth * 0.01, 1.0); \n'; - } else if (!polygonOffsetSupported) { - // If polygon offset isn't supported push the depth back based on view, however this - // causes light leaking at further away views - fsSource += ' shadowParameters.depthBias *= mix(1.0, 100.0, depth * 0.0015); \n'; + if (distance > 0.0) { + Cartesian3.normalize(direction, direction); + camera.move(direction, distance); } + } - if (isPointLight) { - fsSource += - ' vec3 directionEC = positionEC.xyz - shadowMap_lightPositionEC.xyz; \n' + - ' float distance = length(directionEC); \n' + - ' directionEC = normalize(directionEC); \n' + - ' float radius = shadowMap_lightPositionEC.w; \n' + - ' // Stop early if the fragment is beyond the point light radius \n' + - ' if (distance > radius) \n' + - ' { \n' + - ' return; \n' + - ' } \n' + - ' vec3 directionWC = czm_inverseViewRotation * directionEC; \n' + + function zoom2D(controller, startPosition, movement) { + if (defined(movement.distance)) { + movement = movement.distance; + } - ' shadowParameters.depth = distance / radius; \n' + - ' shadowParameters.nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n' + + var scene = controller._scene; + var camera = scene.camera; - ' shadowParameters.texCoords = directionWC; \n' + - ' float visibility = czm_shadowVisibility(shadowMap_textureCube, shadowParameters); \n'; - } else if (isSpotLight) { - fsSource += - ' vec3 directionEC = normalize(positionEC.xyz - shadowMap_lightPositionEC.xyz); \n' + - ' float nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n' + - ' applyNormalOffset(positionEC, normalEC, nDotL); \n' + + handleZoom(controller, startPosition, movement, controller._zoomFactor, camera.getMagnitude()); + } - ' vec4 shadowPosition = shadowMap_matrix * positionEC; \n' + - ' // Spot light uses a perspective projection, so perform the perspective divide \n' + - ' shadowPosition /= shadowPosition.w; \n' + + var twist2DStart = new Cartesian2(); + var twist2DEnd = new Cartesian2(); - ' // Stop early if the fragment is not in the shadow bounds \n' + - ' if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n' + - ' { \n' + - ' return; \n' + - ' } \n' + + function twist2D(controller, startPosition, movement) { + if (defined(movement.angleAndHeight)) { + singleAxisTwist2D(controller, startPosition, movement.angleAndHeight); + return; + } - ' shadowParameters.texCoords = shadowPosition.xy; \n' + - ' shadowParameters.depth = shadowPosition.z; \n' + - ' shadowParameters.nDotL = nDotL; \n' + + var scene = controller._scene; + var camera = scene.camera; + var canvas = scene.canvas; + var width = canvas.clientWidth; + var height = canvas.clientHeight; - ' float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n'; - } else if (hasCascades) { - fsSource += - ' float maxDepth = shadowMap_cascadeSplits[1].w; \n' + + var start = twist2DStart; + start.x = (2.0 / width) * movement.startPosition.x - 1.0; + start.y = (2.0 / height) * (height - movement.startPosition.y) - 1.0; + start = Cartesian2.normalize(start, start); - ' // Stop early if the eye depth exceeds the last cascade \n' + - ' if (depth > maxDepth) \n' + - ' { \n' + - ' return; \n' + - ' } \n' + + var end = twist2DEnd; + end.x = (2.0 / width) * movement.endPosition.x - 1.0; + end.y = (2.0 / height) * (height - movement.endPosition.y) - 1.0; + end = Cartesian2.normalize(end, end); - ' // Get the cascade based on the eye-space depth \n' + - ' vec4 weights = czm_cascadeWeights(depth); \n' + + var startTheta = CesiumMath.acosClamped(start.x); + if (start.y < 0) { + startTheta = CesiumMath.TWO_PI - startTheta; + } + var endTheta = CesiumMath.acosClamped(end.x); + if (end.y < 0) { + endTheta = CesiumMath.TWO_PI - endTheta; + } + var theta = endTheta - startTheta; - ' // Apply normal offset \n' + - ' float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n' + - ' applyNormalOffset(positionEC, normalEC, nDotL); \n' + + camera.twistRight(theta); + } - ' // Transform position into the cascade \n' + - ' vec4 shadowPosition = czm_cascadeMatrix(weights) * positionEC; \n' + + function singleAxisTwist2D(controller, startPosition, movement) { + var rotateRate = controller._rotateFactor * controller._rotateRateRangeAdjustment; - ' // Get visibility \n' + - ' shadowParameters.texCoords = shadowPosition.xy; \n' + - ' shadowParameters.depth = shadowPosition.z; \n' + - ' shadowParameters.nDotL = nDotL; \n' + - ' float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n' + + if (rotateRate > controller._maximumRotateRate) { + rotateRate = controller._maximumRotateRate; + } - ' // Fade out shadows that are far away \n' + - ' float shadowMapMaximumDistance = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.z; \n' + - ' float fade = max((depth - shadowMapMaximumDistance * 0.8) / (shadowMapMaximumDistance * 0.2), 0.0); \n' + - ' visibility = mix(visibility, 1.0, fade); \n' + + if (rotateRate < controller._minimumRotateRate) { + rotateRate = controller._minimumRotateRate; + } - (debugCascadeColors ? - ' // Draw cascade colors for debugging \n' + - ' gl_FragColor *= czm_cascadeColor(weights); \n' : ''); + var scene = controller._scene; + var camera = scene.camera; + var canvas = scene.canvas; + + var phiWindowRatio = (movement.endPosition.x - movement.startPosition.x) / canvas.clientWidth; + phiWindowRatio = Math.min(phiWindowRatio, controller.maximumMovementRatio); + + var deltaPhi = rotateRate * phiWindowRatio * Math.PI * 4.0; + + camera.twistRight(deltaPhi); + } + + function update2D(controller) { + var rotatable2D = controller._scene.mapMode2D === MapMode2D.ROTATE; + if (!Matrix4.equals(Matrix4.IDENTITY, controller._scene.camera.transform)) { + reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom2D, controller.inertiaZoom, '_lastInertiaZoomMovement'); + if (rotatable2D) { + reactToInput(controller, controller.enableRotate, controller.translateEventTypes, twist2D, controller.inertiaSpin, '_lastInertiaSpinMovement'); + } } else { - fsSource += - ' float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n' + - ' applyNormalOffset(positionEC, normalEC, nDotL); \n' + - ' vec4 shadowPosition = shadowMap_matrix * positionEC; \n' + + reactToInput(controller, controller.enableTranslate, controller.translateEventTypes, translate2D, controller.inertiaTranslate, '_lastInertiaTranslateMovement'); + reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom2D, controller.inertiaZoom, '_lastInertiaZoomMovement'); + if (rotatable2D) { + reactToInput(controller, controller.enableRotate, controller.tiltEventTypes, twist2D, controller.inertiaSpin, '_lastInertiaTiltMovement'); + } + } + } + + var pickGlobeScratchRay = new Ray(); + var scratchDepthIntersection = new Cartesian3(); + var scratchRayIntersection = new Cartesian3(); - ' // Stop early if the fragment is not in the shadow bounds \n' + - ' if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n' + - ' { \n' + - ' return; \n' + - ' } \n' + + function pickGlobe(controller, mousePosition, result) { + var scene = controller._scene; + var globe = controller._globe; + var camera = scene.camera; - ' shadowParameters.texCoords = shadowPosition.xy; \n' + - ' shadowParameters.depth = shadowPosition.z; \n' + - ' shadowParameters.nDotL = nDotL; \n' + - ' float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n'; + if (!defined(globe)) { + return undefined; } - fsSource += - ' gl_FragColor.rgb *= visibility; \n' + - '} \n'; + var depthIntersection; + if (scene.pickPositionSupported) { + depthIntersection = scene.pickPositionWorldCoordinates(mousePosition, scratchDepthIntersection); + } - sources.push(fsSource); + var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); + var rayIntersection = globe.pick(ray, scene, scratchRayIntersection); - return new ShaderSource({ - defines : defines, - sources : sources - }); - }; + var pickDistance = defined(depthIntersection) ? Cartesian3.distance(depthIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; + var rayDistance = defined(rayIntersection) ? Cartesian3.distance(rayIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; - return ShadowMapShader; -}); + if (pickDistance < rayDistance) { + return Cartesian3.clone(depthIntersection, result); + } -define('Scene/ShadowMap',[ - '../Core/BoundingRectangle', - '../Core/BoundingSphere', - '../Core/BoxOutlineGeometry', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/Cartographic', - '../Core/clone', - '../Core/Color', - '../Core/ColorGeometryInstanceAttribute', - '../Core/combine', - '../Core/CullingVolume', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/FeatureDetection', - '../Core/GeometryInstance', - '../Core/Intersect', - '../Core/Math', - '../Core/Matrix4', - '../Core/OrthographicOffCenterFrustum', - '../Core/PerspectiveFrustum', - '../Core/PixelFormat', - '../Core/Quaternion', - '../Core/SphereOutlineGeometry', - '../Core/WebGLConstants', - '../Renderer/ClearCommand', - '../Renderer/ContextLimits', - '../Renderer/CubeMap', - '../Renderer/DrawCommand', - '../Renderer/Framebuffer', - '../Renderer/Pass', - '../Renderer/PassState', - '../Renderer/PixelDatatype', - '../Renderer/Renderbuffer', - '../Renderer/RenderbufferFormat', - '../Renderer/RenderState', - '../Renderer/Sampler', - '../Renderer/Texture', - '../Renderer/TextureMagnificationFilter', - '../Renderer/TextureMinificationFilter', - '../Renderer/TextureWrap', - './Camera', - './CullFace', - './DebugCameraPrimitive', - './PerInstanceColorAppearance', - './Primitive', - './ShadowMapShader' - ], function( - BoundingRectangle, - BoundingSphere, - BoxOutlineGeometry, - Cartesian2, - Cartesian3, - Cartesian4, - Cartographic, - clone, - Color, - ColorGeometryInstanceAttribute, - combine, - CullingVolume, - defaultValue, - defined, - defineProperties, - destroyObject, - DeveloperError, - FeatureDetection, - GeometryInstance, - Intersect, - CesiumMath, - Matrix4, - OrthographicOffCenterFrustum, - PerspectiveFrustum, - PixelFormat, - Quaternion, - SphereOutlineGeometry, - WebGLConstants, - ClearCommand, - ContextLimits, - CubeMap, - DrawCommand, - Framebuffer, - Pass, - PassState, - PixelDatatype, - Renderbuffer, - RenderbufferFormat, - RenderState, - Sampler, - Texture, - TextureMagnificationFilter, - TextureMinificationFilter, - TextureWrap, - Camera, - CullFace, - DebugCameraPrimitive, - PerInstanceColorAppearance, - Primitive, - ShadowMapShader) { - 'use strict'; + return Cartesian3.clone(rayIntersection, result); + } - /** - * Use {@link Viewer#shadowMap} to get the scene's shadow map originating from the sun. Do not construct this directly. - * - * <p> - * The normalOffset bias pushes the shadows forward slightly, and may be disabled - * for applications that require ultra precise shadows. - * </p> - * - * @alias ShadowMap - * @internalConstructor - * - * @param {Object} options An object containing the following properties: - * @param {Camera} options.lightCamera A camera representing the light source. - * @param {Boolean} [options.enabled=true] Whether the shadow map is enabled. - * @param {Boolean} [options.isPointLight=false] Whether the light source is a point light. Point light shadows do not use cascades. - * @param {Boolean} [options.pointLightRadius=100.0] Radius of the point light. - * @param {Boolean} [options.cascadesEnabled=true] Use multiple shadow maps to cover different partitions of the view frustum. - * @param {Number} [options.numberOfCascades=4] The number of cascades to use for the shadow map. Supported values are one and four. - * @param {Number} [options.maximumDistance=5000.0] The maximum distance used for generating cascaded shadows. Lower values improve shadow quality. - * @param {Number} [options.size=2048] The width and height, in pixels, of each shadow map. - * @param {Boolean} [options.softShadows=false] Whether percentage-closer-filtering is enabled for producing softer shadows. - * @param {Number} [options.darkness=0.3] The shadow darkness. - * @param {Boolean} [options.normalOffset=true] Whether a normal bias is applied to shadows. - * - * @exception {DeveloperError} Only one or four cascades are supported. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Shadows.html|Cesium Sandcastle Shadows Demo} - */ - function ShadowMap(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - // options.context is an undocumented option - var context = options.context; + var translateCVStartRay = new Ray(); + var translateCVEndRay = new Ray(); + var translateCVStartPos = new Cartesian3(); + var translateCVEndPos = new Cartesian3(); + var translatCVDifference = new Cartesian3(); + var translateCVOrigin = new Cartesian3(); + var translateCVPlane = new Plane(Cartesian3.UNIT_X, 0.0); + var translateCVStartMouse = new Cartesian2(); + var translateCVEndMouse = new Cartesian2(); - if (!defined(context)) { - throw new DeveloperError('context is required.'); - } - if (!defined(options.lightCamera)) { - throw new DeveloperError('lightCamera is required.'); + function translateCV(controller, startPosition, movement) { + if (!Cartesian3.equals(startPosition, controller._translateMousePosition)) { + controller._looking = false; } - if (defined(options.numberOfCascades) && ((options.numberOfCascades !== 1) && (options.numberOfCascades !== 4))) { - throw new DeveloperError('Only one or four cascades are supported.'); + + if (!Cartesian3.equals(startPosition, controller._strafeMousePosition)) { + controller._strafing = false; } - - this._enabled = defaultValue(options.enabled, true); - this._softShadows = defaultValue(options.softShadows, false); - this._normalOffset = defaultValue(options.normalOffset, true); - this.dirty = true; - /** - * Specifies whether the shadow map originates from a light source. Shadow maps that are used for analytical - * purposes should set this to false so as not to affect scene rendering. - * - * @private - */ - this.fromLightSource = defaultValue(options.fromLightSource, true); + if (controller._looking) { + look3D(controller, startPosition, movement); + return; + } - /** - * Determines the darkness of the shadows. - * - * @type {Number} - * @default 0.3 - */ - this.darkness = defaultValue(options.darkness, 0.3); - this._darkness = this.darkness; + if (controller._strafing) { + strafe(controller, startPosition, movement); + return; + } - /** - * Determines the maximum distance of the shadow map. Only applicable for cascaded shadows. Larger distances may result in lower quality shadows. - * - * @type {Number} - * @default 5000.0 - */ - this.maximumDistance = defaultValue(options.maximumDistance, 5000.0); + var scene = controller._scene; + var camera = scene.camera; + var startMouse = Cartesian2.clone(movement.startPosition, translateCVStartMouse); + var endMouse = Cartesian2.clone(movement.endPosition, translateCVEndMouse); + var startRay = camera.getPickRay(startMouse, translateCVStartRay); - this._outOfView = false; - this._outOfViewPrevious = false; - this._needsUpdate = true; + var origin = Cartesian3.clone(Cartesian3.ZERO, translateCVOrigin); + var normal = Cartesian3.UNIT_X; - // In IE11 and Edge polygon offset is not functional. - // TODO : Also disabled for instances of Firefox and Chrome running ANGLE that do not support depth textures. - // Re-enable once https://github.com/AnalyticalGraphicsInc/cesium/issues/4560 is resolved. - var polygonOffsetSupported = true; - if (FeatureDetection.isInternetExplorer() || FeatureDetection.isEdge() || ((FeatureDetection.isChrome() || FeatureDetection.isFirefox()) && FeatureDetection.isWindows() && !context.depthTexture)) { - polygonOffsetSupported = false; + var globePos; + if (camera.position.z < controller._minimumPickingTerrainHeight) { + globePos = pickGlobe(controller, startMouse, translateCVStartPos); + if (defined(globePos)) { + origin.x = globePos.x; + } } - this._polygonOffsetSupported = polygonOffsetSupported; - this._terrainBias = { - polygonOffset : polygonOffsetSupported, - polygonOffsetFactor : 1.1, - polygonOffsetUnits : 4.0, - normalOffset : this._normalOffset, - normalOffsetScale : 0.5, - normalShading : true, - normalShadingSmooth : 0.3, - depthBias : 0.0001 - }; + if (origin.x > camera.position.z && defined(globePos)) { + Cartesian3.clone(globePos, controller._strafeStartPosition); + controller._strafing = true; + strafe(controller, startPosition, movement); + controller._strafeMousePosition = Cartesian2.clone(startPosition, controller._strafeMousePosition); + return; + } - this._primitiveBias = { - polygonOffset : polygonOffsetSupported, - polygonOffsetFactor : 1.1, - polygonOffsetUnits : 4.0, - normalOffset : this._normalOffset, - normalOffsetScale : 0.1, - normalShading : true, - normalShadingSmooth : 0.05, - depthBias : 0.00002 - }; + var plane = Plane.fromPointNormal(origin, normal, translateCVPlane); - this._pointBias = { - polygonOffset : false, - polygonOffsetFactor : 1.1, - polygonOffsetUnits : 4.0, - normalOffset : this._normalOffset, - normalOffsetScale : 0.0, - normalShading : true, - normalShadingSmooth : 0.1, - depthBias : 0.0005 - }; + startRay = camera.getPickRay(startMouse, translateCVStartRay); + var startPlanePos = IntersectionTests.rayPlane(startRay, plane, translateCVStartPos); - // Framebuffer resources - this._depthAttachment = undefined; - this._colorAttachment = undefined; + var endRay = camera.getPickRay(endMouse, translateCVEndRay); + var endPlanePos = IntersectionTests.rayPlane(endRay, plane, translateCVEndPos); - // Uniforms - this._shadowMapMatrix = new Matrix4(); - this._shadowMapTexture = undefined; - this._lightDirectionEC = new Cartesian3(); - this._lightPositionEC = new Cartesian4(); - this._distance = 0.0; + if (!defined(startPlanePos) || !defined(endPlanePos)) { + controller._looking = true; + look3D(controller, startPosition, movement); + Cartesian2.clone(startPosition, controller._translateMousePosition); + return; + } - this._lightCamera = options.lightCamera; - this._shadowMapCamera = new ShadowMapCamera(); - this._shadowMapCullingVolume = undefined; - this._sceneCamera = undefined; - this._boundingSphere = new BoundingSphere(); + var diff = Cartesian3.subtract(startPlanePos, endPlanePos, translatCVDifference); + var temp = diff.x; + diff.x = diff.y; + diff.y = diff.z; + diff.z = temp; + var mag = Cartesian3.magnitude(diff); + if (mag > CesiumMath.EPSILON6) { + Cartesian3.normalize(diff, diff); + camera.move(diff, mag); + } + } - this._isPointLight = defaultValue(options.isPointLight, false); - this._pointLightRadius = defaultValue(options.pointLightRadius, 100.0); + var rotateCVWindowPos = new Cartesian2(); + var rotateCVWindowRay = new Ray(); + var rotateCVCenter = new Cartesian3(); + var rotateCVVerticalCenter = new Cartesian3(); + var rotateCVTransform = new Matrix4(); + var rotateCVVerticalTransform = new Matrix4(); + var rotateCVOrigin = new Cartesian3(); + var rotateCVPlane = new Plane(Cartesian3.UNIT_X, 0.0); + var rotateCVCartesian3 = new Cartesian3(); + var rotateCVCart = new Cartographic(); + var rotateCVOldTransform = new Matrix4(); + var rotateCVQuaternion = new Quaternion(); + var rotateCVMatrix = new Matrix3(); + var tilt3DCartesian3 = new Cartesian3(); - this._cascadesEnabled = this._isPointLight ? false : defaultValue(options.cascadesEnabled, true); - this._numberOfCascades = !this._cascadesEnabled ? 0 : defaultValue(options.numberOfCascades, 4); - this._fitNearFar = true; - this._maximumCascadeDistances = [25.0, 150.0, 700.0, Number.MAX_VALUE]; + function rotateCV(controller, startPosition, movement) { + if (defined(movement.angleAndHeight)) { + movement = movement.angleAndHeight; + } - this._textureSize = new Cartesian2(); + if (!Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { + controller._tiltCVOffMap = false; + controller._looking = false; + } - this._isSpotLight = false; - if (this._cascadesEnabled) { - // Cascaded shadows are always orthographic. The frustum dimensions are calculated on the fly. - this._shadowMapCamera.frustum = new OrthographicOffCenterFrustum(); - } else if (defined(this._lightCamera.frustum.fov)) { - // If the light camera uses a perspective frustum, then the light source is a spot light - this._isSpotLight = true; + if (controller._looking) { + look3D(controller, startPosition, movement); + return; } - // Uniforms - this._cascadeSplits = [new Cartesian4(), new Cartesian4()]; - this._cascadeMatrices = [new Matrix4(), new Matrix4(), new Matrix4(), new Matrix4()]; - this._cascadeDistances = new Cartesian4(); + var scene = controller._scene; + var camera = scene.camera; + var maxCoord = controller._maxCoord; + var onMap = Math.abs(camera.position.x) - maxCoord.x < 0 && Math.abs(camera.position.y) - maxCoord.y < 0; - var numberOfPasses; - if (this._isPointLight) { - numberOfPasses = 6; // One shadow map for each direction - } else if (!this._cascadesEnabled) { - numberOfPasses = 1; + if (controller._tiltCVOffMap || !onMap || camera.position.z > controller._minimumPickingTerrainHeight) { + controller._tiltCVOffMap = true; + rotateCVOnPlane(controller, startPosition, movement); } else { - numberOfPasses = this._numberOfCascades; + rotateCVOnTerrain(controller, startPosition, movement); } + } - this._passes = new Array(numberOfPasses); - for (var i = 0; i < numberOfPasses; ++i) { - this._passes[i] = new ShadowPass(context); - } + function rotateCVOnPlane(controller, startPosition, movement) { + var scene = controller._scene; + var camera = scene.camera; + var canvas = scene.canvas; - this.debugShow = false; - this.debugFreezeFrame = false; - this._debugFreezeFrame = false; - this._debugCascadeColors = false; - this._debugLightFrustum = undefined; - this._debugCameraFrustum = undefined; - this._debugCascadeFrustums = new Array(this._numberOfCascades); - this._debugShadowViewCommand = undefined; + var windowPosition = rotateCVWindowPos; + windowPosition.x = canvas.clientWidth / 2; + windowPosition.y = canvas.clientHeight / 2; + var ray = camera.getPickRay(windowPosition, rotateCVWindowRay); + var normal = Cartesian3.UNIT_X; - this._usesDepthTexture = context.depthTexture; + var position = ray.origin; + var direction = ray.direction; + var scalar; + var normalDotDirection = Cartesian3.dot(normal, direction); + if (Math.abs(normalDotDirection) > CesiumMath.EPSILON6) { + scalar = -Cartesian3.dot(normal, position) / normalDotDirection; + } - if (this._isPointLight) { - this._usesDepthTexture = false; + if (!defined(scalar) || scalar <= 0.0) { + controller._looking = true; + look3D(controller, startPosition, movement); + Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); + return; } - // Create render states for shadow casters - this._primitiveRenderState = undefined; - this._terrainRenderState = undefined; - this._pointRenderState = undefined; - createRenderStates(this); + var center = Cartesian3.multiplyByScalar(direction, scalar, rotateCVCenter); + Cartesian3.add(position, center, center); - // For clearing the shadow map texture every frame - this._clearCommand = new ClearCommand({ - depth : 1.0, - color : new Color() - }); + var projection = scene.mapProjection; + var ellipsoid = projection.ellipsoid; - this._clearPassState = new PassState(context); + Cartesian3.fromElements(center.y, center.z, center.x, center); + var cart = projection.unproject(center, rotateCVCart); + ellipsoid.cartographicToCartesian(cart, center); - this._size = defaultValue(options.size, 2048); - this.size = this._size; - } + var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, rotateCVTransform); - /** - * Global maximum shadow distance used to prevent far off receivers from extending - * the shadow far plane. This helps set a tighter near/far when viewing objects from space. - * - * @private - */ - ShadowMap.MAXIMUM_DISTANCE = 20000.0; + var oldGlobe = controller._globe; + var oldEllipsoid = controller._ellipsoid; + controller._globe = undefined; + controller._ellipsoid = Ellipsoid.UNIT_SPHERE; + controller._rotateFactor = 1.0; + controller._rotateRateRangeAdjustment = 1.0; - function ShadowPass(context) { - this.camera = new ShadowMapCamera(); - this.passState = new PassState(context); - this.framebuffer = undefined; - this.textureOffsets = undefined; - this.commandList = []; - this.cullingVolume = undefined; - } + var oldTransform = Matrix4.clone(camera.transform, rotateCVOldTransform); + camera._setTransform(transform); - function createRenderState(colorMask, bias) { - return RenderState.fromCache({ - cull : { - enabled : true, - face : CullFace.BACK - }, - depthTest : { - enabled : true - }, - colorMask : { - red : colorMask, - green : colorMask, - blue : colorMask, - alpha : colorMask - }, - depthMask : true, - polygonOffset : { - enabled : bias.polygonOffset, - factor : bias.polygonOffsetFactor, - units : bias.polygonOffsetUnits - } - }); - } + rotate3D(controller, startPosition, movement, Cartesian3.UNIT_Z); - function createRenderStates(shadowMap) { - // Enable the color mask if the shadow map is backed by a color texture, e.g. when depth textures aren't supported - var colorMask = !shadowMap._usesDepthTexture; - shadowMap._primitiveRenderState = createRenderState(colorMask, shadowMap._primitiveBias); - shadowMap._terrainRenderState = createRenderState(colorMask, shadowMap._terrainBias); - shadowMap._pointRenderState = createRenderState(colorMask, shadowMap._pointBias); + camera._setTransform(oldTransform); + controller._globe = oldGlobe; + controller._ellipsoid = oldEllipsoid; + + var radius = oldEllipsoid.maximumRadius; + controller._rotateFactor = 1.0 / radius; + controller._rotateRateRangeAdjustment = radius; } - /** - * @private - */ - ShadowMap.prototype.debugCreateRenderStates = function() { - createRenderStates(this); - }; + function rotateCVOnTerrain(controller, startPosition, movement) { + var scene = controller._scene; + var camera = scene.camera; - defineProperties(ShadowMap.prototype, { - /** - * Determines if the shadow map will be shown. - * - * @memberof ShadowMap.prototype - * @type {Boolean} - * @default true - */ - enabled : { - get : function() { - return this._enabled; - }, - set : function(value) { - this.dirty = this._enabled !== value; - this._enabled = value; - } - }, + var center; + var ray; + var normal = Cartesian3.UNIT_X; - /** - * Determines if a normal bias will be applied to shadows. - * - * @memberof ShadowMap.prototype - * @type {Boolean} - * @default true - */ - normalOffset : { - get : function() { - return this._normalOffset; - }, - set : function(value) { - this.dirty = this._normalOffset !== value; - this._normalOffset = value; - this._terrainBias.normalOffset = value; - this._primitiveBias.normalOffset = value; - this._pointBias.normalOffset = value; + if (Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { + center = Cartesian3.clone(controller._tiltCenter, rotateCVCenter); + } else { + if (camera.position.z < controller._minimumPickingTerrainHeight) { + center = pickGlobe(controller, startPosition, rotateCVCenter); } - }, - /** - * Determines if soft shadows are enabled. Uses pcf filtering which requires more texture reads and may hurt performance. - * - * @memberof ShadowMap.prototype - * @type {Boolean} - * @default false - */ - softShadows : { - get : function() { - return this._softShadows; - }, - set : function(value) { - this.dirty = this._softShadows !== value; - this._softShadows = value; - } - }, + if (!defined(center)) { + ray = camera.getPickRay(startPosition, rotateCVWindowRay); + var position = ray.origin; + var direction = ray.direction; - /** - * The width and height, in pixels, of each shadow map. - * - * @memberof ShadowMap.prototype - * @type {Number} - * @default 2048 - */ - size : { - get : function() { - return this._size; - }, - set : function(value) { - resize(this, value); - } - }, + var scalar; + var normalDotDirection = Cartesian3.dot(normal, direction); + if (Math.abs(normalDotDirection) > CesiumMath.EPSILON6) { + scalar = -Cartesian3.dot(normal, position) / normalDotDirection; + } - /** - * Whether the shadow map is out of view of the scene camera. - * - * @memberof ShadowMap.prototype - * @type {Boolean} - * @readonly - * @private - */ - outOfView : { - get : function() { - return this._outOfView; - } - }, + if (!defined(scalar) || scalar <= 0.0) { + controller._looking = true; + look3D(controller, startPosition, movement); + Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); + return; + } - /** - * The culling volume of the shadow frustum. - * - * @memberof ShadowMap.prototype - * @type {CullingVolume} - * @readonly - * @private - */ - shadowMapCullingVolume : { - get : function() { - return this._shadowMapCullingVolume; + center = Cartesian3.multiplyByScalar(direction, scalar, rotateCVCenter); + Cartesian3.add(position, center, center); } - }, - /** - * The passes used for rendering shadows. Each face of a point light or each cascade for a cascaded shadow map is a separate pass. - * - * @memberof ShadowMap.prototype - * @type {ShadowPass[]} - * @readonly - * @private - */ - passes : { - get : function() { - return this._passes; - } - }, + Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); + Cartesian3.clone(center, controller._tiltCenter); + } - /** - * Whether the light source is a point light. - * - * @memberof ShadowMap.prototype - * @type {Boolean} - * @readonly - * @private - */ - isPointLight : { - get : function() { - return this._isPointLight; - } - }, + var canvas = scene.canvas; - /** - * Debug option for visualizing the cascades by color. - * - * @memberof ShadowMap.prototype - * @type {Boolean} - * @default false - * @private - */ - debugCascadeColors : { - get : function() { - return this._debugCascadeColors; - }, - set : function(value) { - this.dirty = this._debugCascadeColors !== value; - this._debugCascadeColors = value; - } - } - }); + var windowPosition = rotateCVWindowPos; + windowPosition.x = canvas.clientWidth / 2; + windowPosition.y = controller._tiltCenterMousePosition.y; + ray = camera.getPickRay(windowPosition, rotateCVWindowRay); - function destroyFramebuffer(shadowMap) { - var length = shadowMap._passes.length; - for (var i = 0; i < length; ++i) { - var pass = shadowMap._passes[i]; - var framebuffer = pass.framebuffer; - if (defined(framebuffer) && !framebuffer.isDestroyed()) { - framebuffer.destroy(); - } - pass.framebuffer = undefined; - } + var origin = Cartesian3.clone(Cartesian3.ZERO, rotateCVOrigin); + origin.x = center.x; - // Destroy the framebuffer attachments - shadowMap._depthAttachment = shadowMap._depthAttachment && shadowMap._depthAttachment.destroy(); - shadowMap._colorAttachment = shadowMap._colorAttachment && shadowMap._colorAttachment.destroy(); - } + var plane = Plane.fromPointNormal(origin, normal, rotateCVPlane); + var verticalCenter = IntersectionTests.rayPlane(ray, plane, rotateCVVerticalCenter); - function createSampler() { - return new Sampler({ - wrapS : TextureWrap.CLAMP_TO_EDGE, - wrapT : TextureWrap.CLAMP_TO_EDGE, - minificationFilter : TextureMinificationFilter.NEAREST, - magnificationFilter : TextureMagnificationFilter.NEAREST - }); - } + var projection = camera._projection; + var ellipsoid = projection.ellipsoid; - function createFramebufferColor(shadowMap, context) { - var depthRenderbuffer = new Renderbuffer({ - context : context, - width : shadowMap._textureSize.x, - height : shadowMap._textureSize.y, - format : RenderbufferFormat.DEPTH_COMPONENT16 - }); + Cartesian3.fromElements(center.y, center.z, center.x, center); + var cart = projection.unproject(center, rotateCVCart); + ellipsoid.cartographicToCartesian(cart, center); - var colorTexture = new Texture({ - context : context, - width : shadowMap._textureSize.x, - height : shadowMap._textureSize.y, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, - sampler : createSampler() - }); + var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, rotateCVTransform); - var framebuffer = new Framebuffer({ - context : context, - depthRenderbuffer : depthRenderbuffer, - colorTextures : [colorTexture], - destroyAttachments : false - }); + var verticalTransform; + if (defined(verticalCenter)) { + Cartesian3.fromElements(verticalCenter.y, verticalCenter.z, verticalCenter.x, verticalCenter); + cart = projection.unproject(verticalCenter, rotateCVCart); + ellipsoid.cartographicToCartesian(cart, verticalCenter); - var length = shadowMap._passes.length; - for (var i = 0; i < length; ++i) { - var pass = shadowMap._passes[i]; - pass.framebuffer = framebuffer; - pass.passState.framebuffer = framebuffer; + verticalTransform = Transforms.eastNorthUpToFixedFrame(verticalCenter, ellipsoid, rotateCVVerticalTransform); + } else { + verticalTransform = transform; } - shadowMap._shadowMapTexture = colorTexture; - shadowMap._depthAttachment = depthRenderbuffer; - shadowMap._colorAttachment = colorTexture; - } + var oldGlobe = controller._globe; + var oldEllipsoid = controller._ellipsoid; + controller._globe = undefined; + controller._ellipsoid = Ellipsoid.UNIT_SPHERE; + controller._rotateFactor = 1.0; + controller._rotateRateRangeAdjustment = 1.0; - function createFramebufferDepth(shadowMap, context) { - var depthStencilTexture = new Texture({ - context : context, - width : shadowMap._textureSize.x, - height : shadowMap._textureSize.y, - pixelFormat : PixelFormat.DEPTH_STENCIL, - pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8, - sampler : createSampler() - }); + var constrainedAxis = Cartesian3.UNIT_Z; - var framebuffer = new Framebuffer({ - context : context, - depthStencilTexture : depthStencilTexture, - destroyAttachments : false - }); + var oldTransform = Matrix4.clone(camera.transform, rotateCVOldTransform); + camera._setTransform(transform); - var length = shadowMap._passes.length; - for (var i = 0; i < length; ++i) { - var pass = shadowMap._passes[i]; - pass.framebuffer = framebuffer; - pass.passState.framebuffer = framebuffer; - } + var tangent = Cartesian3.cross(Cartesian3.UNIT_Z, Cartesian3.normalize(camera.position, rotateCVCartesian3), rotateCVCartesian3); + var dot = Cartesian3.dot(camera.right, tangent); - shadowMap._shadowMapTexture = depthStencilTexture; - shadowMap._depthAttachment = depthStencilTexture; - } + rotate3D(controller, startPosition, movement, constrainedAxis, false, true); - function createFramebufferCube(shadowMap, context) { - var depthRenderbuffer = new Renderbuffer({ - context : context, - width : shadowMap._textureSize.x, - height : shadowMap._textureSize.y, - format : RenderbufferFormat.DEPTH_COMPONENT16 - }); + camera._setTransform(verticalTransform); + if (dot < 0.0) { + if (movement.startPosition.y > movement.endPosition.y) { + constrainedAxis = undefined; + } - var cubeMap = new CubeMap({ - context : context, - width : shadowMap._textureSize.x, - height : shadowMap._textureSize.y, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, - sampler : createSampler() - }); + var oldConstrainedAxis = camera.constrainedAxis; + camera.constrainedAxis = undefined; - var faces = [cubeMap.negativeX, cubeMap.negativeY, cubeMap.negativeZ, cubeMap.positiveX, cubeMap.positiveY, cubeMap.positiveZ]; + rotate3D(controller, startPosition, movement, constrainedAxis, true, false); - for (var i = 0; i < 6; ++i) { - var framebuffer = new Framebuffer({ - context : context, - depthRenderbuffer : depthRenderbuffer, - colorTextures : [faces[i]], - destroyAttachments : false - }); - var pass = shadowMap._passes[i]; - pass.framebuffer = framebuffer; - pass.passState.framebuffer = framebuffer; + camera.constrainedAxis = oldConstrainedAxis; + } else { + rotate3D(controller, startPosition, movement, constrainedAxis, true, false); } - shadowMap._shadowMapTexture = cubeMap; - shadowMap._depthAttachment = depthRenderbuffer; - shadowMap._colorAttachment = cubeMap; - } + if (defined(camera.constrainedAxis)) { + var right = Cartesian3.cross(camera.direction, camera.constrainedAxis, tilt3DCartesian3); + if (!Cartesian3.equalsEpsilon(right, Cartesian3.ZERO, CesiumMath.EPSILON6)) { + if (Cartesian3.dot(right, camera.right) < 0.0) { + Cartesian3.negate(right, right); + } - function createFramebuffer(shadowMap, context) { - if (shadowMap._isPointLight) { - createFramebufferCube(shadowMap, context); - } else if (shadowMap._usesDepthTexture) { - createFramebufferDepth(shadowMap, context); - } else { - createFramebufferColor(shadowMap, context); - } - } + Cartesian3.cross(right, camera.direction, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); - function checkFramebuffer(shadowMap, context) { - // Attempt to make an FBO with only a depth texture. If it fails, fallback to a color texture. - if (shadowMap._usesDepthTexture && (shadowMap._passes[0].framebuffer.status !== WebGLConstants.FRAMEBUFFER_COMPLETE)) { - shadowMap._usesDepthTexture = false; - createRenderStates(shadowMap); - destroyFramebuffer(shadowMap); - createFramebuffer(shadowMap, context); + Cartesian3.normalize(camera.up, camera.up); + Cartesian3.normalize(camera.right, camera.right); + } } - } - function updateFramebuffer(shadowMap, context) { - if (!defined(shadowMap._passes[0].framebuffer) || (shadowMap._shadowMapTexture.width !== shadowMap._textureSize.x)) { - destroyFramebuffer(shadowMap); - createFramebuffer(shadowMap, context); - checkFramebuffer(shadowMap, context); - clearFramebuffer(shadowMap, context); - } - } + camera._setTransform(oldTransform); + controller._globe = oldGlobe; + controller._ellipsoid = oldEllipsoid; - function clearFramebuffer(shadowMap, context, shadowPass) { - shadowPass = defaultValue(shadowPass, 0); - if (shadowMap._isPointLight || (shadowPass === 0)) { - shadowMap._clearCommand.framebuffer = shadowMap._passes[shadowPass].framebuffer; - shadowMap._clearCommand.execute(context, shadowMap._clearPassState); + var radius = oldEllipsoid.maximumRadius; + controller._rotateFactor = 1.0 / radius; + controller._rotateRateRangeAdjustment = radius; + + var originalPosition = Cartesian3.clone(camera.positionWC, rotateCVCartesian3); + camera._adjustHeightForTerrain(); + + if (!Cartesian3.equals(camera.positionWC, originalPosition)) { + camera._setTransform(verticalTransform); + camera.worldToCameraCoordinatesPoint(originalPosition, originalPosition); + + var magSqrd = Cartesian3.magnitudeSquared(originalPosition); + if (Cartesian3.magnitudeSquared(camera.position) > magSqrd) { + Cartesian3.normalize(camera.position, camera.position); + Cartesian3.multiplyByScalar(camera.position, Math.sqrt(magSqrd), camera.position); + } + + var angle = Cartesian3.angleBetween(originalPosition, camera.position); + var axis = Cartesian3.cross(originalPosition, camera.position, originalPosition); + Cartesian3.normalize(axis, axis); + + var quaternion = Quaternion.fromAxisAngle(axis, angle, rotateCVQuaternion); + var rotation = Matrix3.fromQuaternion(quaternion, rotateCVMatrix); + Matrix3.multiplyByVector(rotation, camera.direction, camera.direction); + Matrix3.multiplyByVector(rotation, camera.up, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.cross(camera.right, camera.direction, camera.up); + + camera._setTransform(oldTransform); } } - function resize(shadowMap, size) { - shadowMap._size = size; - var passes = shadowMap._passes; - var numberOfPasses = passes.length; - var textureSize = shadowMap._textureSize; + var zoomCVWindowPos = new Cartesian2(); + var zoomCVWindowRay = new Ray(); + var zoomCVIntersection = new Cartesian3(); - if (shadowMap._isPointLight) { - size = (ContextLimits.maximumCubeMapSize >= size) ? size : ContextLimits.maximumCubeMapSize; - textureSize.x = size; - textureSize.y = size; - var faceViewport = new BoundingRectangle(0, 0, size, size); - passes[0].passState.viewport = faceViewport; - passes[1].passState.viewport = faceViewport; - passes[2].passState.viewport = faceViewport; - passes[3].passState.viewport = faceViewport; - passes[4].passState.viewport = faceViewport; - passes[5].passState.viewport = faceViewport; - } else if (numberOfPasses === 1) { - // +----+ - // | 1 | - // +----+ - size = (ContextLimits.maximumTextureSize >= size) ? size : ContextLimits.maximumTextureSize; - textureSize.x = size; - textureSize.y = size; - passes[0].passState.viewport = new BoundingRectangle(0, 0, size, size); - } else if (numberOfPasses === 4) { - // +----+----+ - // | 3 | 4 | - // +----+----+ - // | 1 | 2 | - // +----+----+ - size = (ContextLimits.maximumTextureSize >= size * 2) ? size : ContextLimits.maximumTextureSize / 2; - textureSize.x = size * 2; - textureSize.y = size * 2; - passes[0].passState.viewport = new BoundingRectangle(0, 0, size, size); - passes[1].passState.viewport = new BoundingRectangle(size, 0, size, size); - passes[2].passState.viewport = new BoundingRectangle(0, size, size, size); - passes[3].passState.viewport = new BoundingRectangle(size, size, size, size); + function zoomCV(controller, startPosition, movement) { + if (defined(movement.distance)) { + movement = movement.distance; } - // Update clear pass state - shadowMap._clearPassState.viewport = new BoundingRectangle(0, 0, textureSize.x, textureSize.y); + var scene = controller._scene; + var camera = scene.camera; + var canvas = scene.canvas; - // Transforms shadow coordinates [0, 1] into the pass's region of the texture - for (var i = 0; i < numberOfPasses; ++i) { - var pass = passes[i]; - var viewport = pass.passState.viewport; - var biasX = viewport.x / textureSize.x; - var biasY = viewport.y / textureSize.y; - var scaleX = viewport.width / textureSize.x; - var scaleY = viewport.height / textureSize.y; - pass.textureOffsets = new Matrix4(scaleX, 0.0, 0.0, biasX, 0.0, scaleY, 0.0, biasY, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); - } - } + var windowPosition = zoomCVWindowPos; + windowPosition.x = canvas.clientWidth / 2; + windowPosition.y = canvas.clientHeight / 2; + var ray = camera.getPickRay(windowPosition, zoomCVWindowRay); - var scratchViewport = new BoundingRectangle(); + var intersection; + if (camera.position.z < controller._minimumPickingTerrainHeight) { + intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); + } - function createDebugShadowViewCommand(shadowMap, context) { - var fs; - if (shadowMap._isPointLight) { - fs = 'uniform samplerCube shadowMap_textureCube; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'void main() \n' + - '{ \n' + - ' vec2 uv = v_textureCoordinates; \n' + - ' vec3 dir; \n' + - ' \n' + - ' if (uv.y < 0.5) \n' + - ' { \n' + - ' if (uv.x < 0.333) \n' + - ' { \n' + - ' dir.x = -1.0; \n' + - ' dir.y = uv.x * 6.0 - 1.0; \n' + - ' dir.z = uv.y * 4.0 - 1.0; \n' + - ' } \n' + - ' else if (uv.x < 0.666) \n' + - ' { \n' + - ' dir.y = -1.0; \n' + - ' dir.x = uv.x * 6.0 - 3.0; \n' + - ' dir.z = uv.y * 4.0 - 1.0; \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' dir.z = -1.0; \n' + - ' dir.x = uv.x * 6.0 - 5.0; \n' + - ' dir.y = uv.y * 4.0 - 1.0; \n' + - ' } \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' if (uv.x < 0.333) \n' + - ' { \n' + - ' dir.x = 1.0; \n' + - ' dir.y = uv.x * 6.0 - 1.0; \n' + - ' dir.z = uv.y * 4.0 - 3.0; \n' + - ' } \n' + - ' else if (uv.x < 0.666) \n' + - ' { \n' + - ' dir.y = 1.0; \n' + - ' dir.x = uv.x * 6.0 - 3.0; \n' + - ' dir.z = uv.y * 4.0 - 3.0; \n' + - ' } \n' + - ' else \n' + - ' { \n' + - ' dir.z = 1.0; \n' + - ' dir.x = uv.x * 6.0 - 5.0; \n' + - ' dir.y = uv.y * 4.0 - 3.0; \n' + - ' } \n' + - ' } \n' + - ' \n' + - ' float shadow = czm_unpackDepth(textureCube(shadowMap_textureCube, dir)); \n' + - ' gl_FragColor = vec4(vec3(shadow), 1.0); \n' + - '} \n'; + var distance; + if (defined(intersection)) { + distance = Cartesian3.distance(ray.origin, intersection); } else { - fs = 'uniform sampler2D shadowMap_texture; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'void main() \n' + - '{ \n' + + var normal = Cartesian3.UNIT_X; + var position = ray.origin; + var direction = ray.direction; + distance = -Cartesian3.dot(normal, position) / Cartesian3.dot(normal, direction); + } - (shadowMap._usesDepthTexture ? - ' float shadow = texture2D(shadowMap_texture, v_textureCoordinates).r; \n' : - ' float shadow = czm_unpackDepth(texture2D(shadowMap_texture, v_textureCoordinates)); \n') + + handleZoom(controller, startPosition, movement, controller._zoomFactor, distance); + } - ' gl_FragColor = vec4(vec3(shadow), 1.0); \n' + - '} \n'; - } + function updateCV(controller) { + var scene = controller._scene; + var camera = scene.camera; - var drawCommand = context.createViewportQuadCommand(fs, { - uniformMap : { - shadowMap_texture : function() { - return shadowMap._shadowMapTexture; - }, - shadowMap_textureCube : function() { - return shadowMap._shadowMapTexture; + if (!Matrix4.equals(Matrix4.IDENTITY, camera.transform)) { + reactToInput(controller, controller.enableRotate, controller.rotateEventTypes, rotate3D, controller.inertiaSpin, '_lastInertiaSpinMovement'); + reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom3D, controller.inertiaZoom, '_lastInertiaZoomMovement'); + } else { + var tweens = controller._tweens; + + if (controller._aggregator.anyButtonDown) { + tweens.removeAll(); + } + + reactToInput(controller, controller.enableTilt, controller.tiltEventTypes, rotateCV, controller.inertiaSpin, '_lastInertiaTiltMovement'); + reactToInput(controller, controller.enableTranslate, controller.translateEventTypes, translateCV, controller.inertiaTranslate, '_lastInertiaTranslateMovement'); + reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoomCV, controller.inertiaZoom, '_lastInertiaZoomMovement'); + reactToInput(controller, controller.enableLook, controller.lookEventTypes, look3D); + + if (!controller._aggregator.anyButtonDown && + (!defined(controller._lastInertiaZoomMovement) || !controller._lastInertiaZoomMovement.active) && + (!defined(controller._lastInertiaTranslateMovement) || !controller._lastInertiaTranslateMovement.active) && + !tweens.contains(controller._tween)) { + var tween = camera.createCorrectPositionTween(controller.bounceAnimationTime); + if (defined(tween)) { + controller._tween = tweens.add(tween); } } - }); - drawCommand.pass = Pass.OVERLAY; - return drawCommand; + + tweens.update(); + } } - function updateDebugShadowViewCommand(shadowMap, frameState) { - // Draws the shadow map on the bottom-right corner of the screen - var context = frameState.context; - var screenWidth = frameState.context.drawingBufferWidth; - var screenHeight = frameState.context.drawingBufferHeight; - var size = Math.min(screenWidth, screenHeight) * 0.3; + var scratchStrafeRay = new Ray(); + var scratchStrafePlane = new Plane(Cartesian3.UNIT_X, 0.0); + var scratchStrafeIntersection = new Cartesian3(); + var scratchStrafeDirection = new Cartesian3(); + var scratchMousePos = new Cartesian3(); - var viewport = scratchViewport; - viewport.x = screenWidth - size; - viewport.y = 0; - viewport.width = size; - viewport.height = size; + function strafe(controller, startPosition, movement) { + var scene = controller._scene; + var camera = scene.camera; - var debugCommand = shadowMap._debugShadowViewCommand; - if (!defined(debugCommand)) { - debugCommand = createDebugShadowViewCommand(shadowMap, context); - shadowMap._debugShadowViewCommand = debugCommand; + var mouseStartPosition = pickGlobe(controller, movement.startPosition, scratchMousePos); + if (!defined(mouseStartPosition)) { + return; } - // Get a new RenderState for the updated viewport size - if (!defined(debugCommand.renderState) || !BoundingRectangle.equals(debugCommand.renderState.viewport, viewport)) { - debugCommand.renderState = RenderState.fromCache({ - viewport : BoundingRectangle.clone(viewport) - }); + var mousePosition = movement.endPosition; + var ray = camera.getPickRay(mousePosition, scratchStrafeRay); + + var direction = Cartesian3.clone(camera.direction, scratchStrafeDirection); + if (scene.mode === SceneMode.COLUMBUS_VIEW) { + Cartesian3.fromElements(direction.z, direction.x, direction.y, direction); } - frameState.commandList.push(shadowMap._debugShadowViewCommand); - } + var plane = Plane.fromPointNormal(mouseStartPosition, direction, scratchStrafePlane); + var intersection = IntersectionTests.rayPlane(ray, plane, scratchStrafeIntersection); + if (!defined(intersection)) { + return; + } - var frustumCornersNDC = new Array(8); - frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, -1.0, 1.0); - frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, -1.0, 1.0); - frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, -1.0, 1.0); - frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, -1.0, 1.0); - frustumCornersNDC[4] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[5] = new Cartesian4(1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[6] = new Cartesian4(1.0, 1.0, 1.0, 1.0); - frustumCornersNDC[7] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); + direction = Cartesian3.subtract(mouseStartPosition, intersection, direction); + if (scene.mode === SceneMode.COLUMBUS_VIEW) { + Cartesian3.fromElements(direction.y, direction.z, direction.x, direction); + } - var scratchMatrix = new Matrix4(); - var scratchFrustumCorners = new Array(8); - for (var i = 0; i < 8; ++i) { - scratchFrustumCorners[i] = new Cartesian4(); + Cartesian3.add(camera.position, direction, camera.position); } - function createDebugPointLight(modelMatrix, color) { - var box = new GeometryInstance({ - geometry : new BoxOutlineGeometry({ - minimum : new Cartesian3(-0.5, -0.5, -0.5), - maximum : new Cartesian3(0.5, 0.5, 0.5) - }), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(color) - } - }); + var spin3DPick = new Cartesian3(); + var scratchCartographic = new Cartographic(); + var scratchRadii = new Cartesian3(); + var scratchEllipsoid = new Ellipsoid(); + var scratchLookUp = new Cartesian3(); - var sphere = new GeometryInstance({ - geometry : new SphereOutlineGeometry({ - radius : 0.5 - }), - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(color) - } - }); + function spin3D(controller, startPosition, movement) { + var scene = controller._scene; + var camera = scene.camera; - return new Primitive({ - geometryInstances : [box, sphere], - appearance : new PerInstanceColorAppearance({ - translucent : false, - flat : true - }), - asynchronous : false, - modelMatrix : modelMatrix - }); - } + if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) { + rotate3D(controller, startPosition, movement); + return; + } - var debugOutlineColors = [Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA]; - var scratchScale = new Cartesian3(); + var magnitude; + var radii; + var ellipsoid; - function applyDebugSettings(shadowMap, frameState) { - updateDebugShadowViewCommand(shadowMap, frameState); + var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, scratchLookUp); - var enterFreezeFrame = shadowMap.debugFreezeFrame && !shadowMap._debugFreezeFrame; - shadowMap._debugFreezeFrame = shadowMap.debugFreezeFrame; + var height = controller._ellipsoid.cartesianToCartographic(camera.positionWC, scratchCartographic).height; + var globe = controller._globe; - // Draw scene camera in freeze frame mode - if (shadowMap.debugFreezeFrame) { - if (enterFreezeFrame) { - // Recreate debug camera when entering freeze frame mode - shadowMap._debugCameraFrustum = shadowMap._debugCameraFrustum && shadowMap._debugCameraFrustum.destroy(); - shadowMap._debugCameraFrustum = new DebugCameraPrimitive({ - camera : shadowMap._sceneCamera, - color : Color.CYAN, - updateOnChange : false - }); - } - shadowMap._debugCameraFrustum.update(frameState); - } + var mousePos; + var tangentPick = false; + if (defined(globe) && height < controller._minimumPickingTerrainHeight) { + mousePos = pickGlobe(controller, movement.startPosition, scratchMousePos); + if (defined(mousePos)) { + var ray = camera.getPickRay(movement.startPosition, pickGlobeScratchRay); + var normal = controller._ellipsoid.geodeticSurfaceNormal(mousePos); + tangentPick = Math.abs(Cartesian3.dot(ray.direction, normal)) < 0.05; - if (shadowMap._cascadesEnabled) { - // Draw cascades only in freeze frame mode - if (shadowMap.debugFreezeFrame) { - if (enterFreezeFrame) { - // Recreate debug frustum when entering freeze frame mode - shadowMap._debugLightFrustum = shadowMap._debugLightFrustum && shadowMap._debugLightFrustum.destroy(); - shadowMap._debugLightFrustum = new DebugCameraPrimitive({ - camera : shadowMap._shadowMapCamera, - color : Color.YELLOW, - updateOnChange : false - }); + if (tangentPick && !controller._looking) { + controller._rotating = false; + controller._strafing = true; } - shadowMap._debugLightFrustum.update(frameState); + } + } - for (var i = 0; i < shadowMap._numberOfCascades; ++i) { - if (enterFreezeFrame) { - // Recreate debug frustum when entering freeze frame mode - shadowMap._debugCascadeFrustums[i] = shadowMap._debugCascadeFrustums[i] && shadowMap._debugCascadeFrustums[i].destroy(); - shadowMap._debugCascadeFrustums[i] = new DebugCameraPrimitive({ - camera : shadowMap._passes[i].camera, - color : debugOutlineColors[i], - updateOnChange : false - }); - } - shadowMap._debugCascadeFrustums[i].update(frameState); - } + if (Cartesian2.equals(startPosition, controller._rotateMousePosition)) { + if (controller._looking) { + look3D(controller, startPosition, movement, up); + } else if (controller._rotating) { + rotate3D(controller, startPosition, movement); + } else if (controller._strafing) { + Cartesian3.clone(mousePos, controller._strafeStartPosition); + strafe(controller, startPosition, movement); + } else { + magnitude = Cartesian3.magnitude(controller._rotateStartPosition); + radii = scratchRadii; + radii.x = radii.y = radii.z = magnitude; + ellipsoid = Ellipsoid.fromCartesian3(radii, scratchEllipsoid); + pan3D(controller, startPosition, movement, ellipsoid); } - } else if (shadowMap._isPointLight) { - if (!defined(shadowMap._debugLightFrustum) || shadowMap._needsUpdate) { - var translation = shadowMap._shadowMapCamera.positionWC; - var rotation = Quaternion.IDENTITY; - var uniformScale = shadowMap._pointLightRadius * 2.0; - var scale = Cartesian3.fromElements(uniformScale, uniformScale, uniformScale, scratchScale); - var modelMatrix = Matrix4.fromTranslationQuaternionRotationScale(translation, rotation, scale, scratchMatrix); + return; + } + controller._looking = false; + controller._rotating = false; + controller._strafing = false; - shadowMap._debugLightFrustum = shadowMap._debugLightFrustum && shadowMap._debugLightFrustum.destroy(); - shadowMap._debugLightFrustum = createDebugPointLight(modelMatrix, Color.YELLOW); + if (defined(globe) && height < controller._minimumPickingTerrainHeight) { + if (defined(mousePos)) { + if (Cartesian3.magnitude(camera.position) < Cartesian3.magnitude(mousePos)) { + Cartesian3.clone(mousePos, controller._strafeStartPosition); + + controller._strafing = true; + strafe(controller, startPosition, movement); + } else { + magnitude = Cartesian3.magnitude(mousePos); + radii = scratchRadii; + radii.x = radii.y = radii.z = magnitude; + ellipsoid = Ellipsoid.fromCartesian3(radii, scratchEllipsoid); + pan3D(controller, startPosition, movement, ellipsoid); + + Cartesian3.clone(mousePos, controller._rotateStartPosition); + } + } else { + controller._looking = true; + look3D(controller, startPosition, movement, up); } - shadowMap._debugLightFrustum.update(frameState); + } else if (defined(camera.pickEllipsoid(movement.startPosition, controller._ellipsoid, spin3DPick))) { + pan3D(controller, startPosition, movement, controller._ellipsoid); + Cartesian3.clone(spin3DPick, controller._rotateStartPosition); + } else if (height > controller._minimumTrackBallHeight) { + controller._rotating = true; + rotate3D(controller, startPosition, movement); } else { - if (!defined(shadowMap._debugLightFrustum) || shadowMap._needsUpdate) { - shadowMap._debugLightFrustum = new DebugCameraPrimitive({ - camera : shadowMap._shadowMapCamera, - color : Color.YELLOW, - updateOnChange : false - }); - } - shadowMap._debugLightFrustum.update(frameState); + controller._looking = true; + look3D(controller, startPosition, movement, up); } - } - function ShadowMapCamera() { - this.viewMatrix = new Matrix4(); - this.inverseViewMatrix = new Matrix4(); - this.frustum = undefined; - this.positionCartographic = new Cartographic(); - this.positionWC = new Cartesian3(); - this.directionWC = Cartesian3.clone(Cartesian3.UNIT_Z); - this.upWC = Cartesian3.clone(Cartesian3.UNIT_Y); - this.rightWC = Cartesian3.clone(Cartesian3.UNIT_X); - this.viewProjectionMatrix = new Matrix4(); + Cartesian2.clone(startPosition, controller._rotateMousePosition); } - ShadowMapCamera.prototype.clone = function(camera) { - Matrix4.clone(camera.viewMatrix, this.viewMatrix); - Matrix4.clone(camera.inverseViewMatrix, this.inverseViewMatrix); - this.frustum = camera.frustum.clone(this.frustum); - Cartographic.clone(camera.positionCartographic, this.positionCartographic); - Cartesian3.clone(camera.positionWC, this.positionWC); - Cartesian3.clone(camera.directionWC, this.directionWC); - Cartesian3.clone(camera.upWC, this.upWC); - Cartesian3.clone(camera.rightWC, this.rightWC); - }; + function rotate3D(controller, startPosition, movement, constrainedAxis, rotateOnlyVertical, rotateOnlyHorizontal) { + rotateOnlyVertical = defaultValue(rotateOnlyVertical, false); + rotateOnlyHorizontal = defaultValue(rotateOnlyHorizontal, false); - // Converts from NDC space to texture space - var scaleBiasMatrix = new Matrix4(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); + var scene = controller._scene; + var camera = scene.camera; + var canvas = scene.canvas; - ShadowMapCamera.prototype.getViewProjection = function() { - var view = this.viewMatrix; - var projection = this.frustum.projectionMatrix; - Matrix4.multiply(projection, view, this.viewProjectionMatrix); - Matrix4.multiply(scaleBiasMatrix, this.viewProjectionMatrix, this.viewProjectionMatrix); - return this.viewProjectionMatrix; - }; + var oldAxis = camera.constrainedAxis; + if (defined(constrainedAxis)) { + camera.constrainedAxis = constrainedAxis; + } - var scratchSplits = new Array(5); - var scratchFrustum = new PerspectiveFrustum(); - var scratchCascadeDistances = new Array(4); - var scratchMin = new Cartesian3(); - var scratchMax = new Cartesian3(); + var rho = Cartesian3.magnitude(camera.position); + var rotateRate = controller._rotateFactor * (rho - controller._rotateRateRangeAdjustment); - function computeCascades(shadowMap, frameState) { - var shadowMapCamera = shadowMap._shadowMapCamera; - var sceneCamera = shadowMap._sceneCamera; - var cameraNear = sceneCamera.frustum.near; - var cameraFar = sceneCamera.frustum.far; - var numberOfCascades = shadowMap._numberOfCascades; + if (rotateRate > controller._maximumRotateRate) { + rotateRate = controller._maximumRotateRate; + } - // Split cascades. Use a mix of linear and log splits. - var i; - var range = cameraFar - cameraNear; - var ratio = cameraFar / cameraNear; + if (rotateRate < controller._minimumRotateRate) { + rotateRate = controller._minimumRotateRate; + } - var lambda = 0.9; - var clampCascadeDistances = false; + var phiWindowRatio = (movement.startPosition.x - movement.endPosition.x) / canvas.clientWidth; + var thetaWindowRatio = (movement.startPosition.y - movement.endPosition.y) / canvas.clientHeight; + phiWindowRatio = Math.min(phiWindowRatio, controller.maximumMovementRatio); + thetaWindowRatio = Math.min(thetaWindowRatio, controller.maximumMovementRatio); - // When the camera is close to a relatively small model, provide more detail in the closer cascades. - // If the camera is near or inside a large model, such as the root tile of a city, then use the default values. - // To get the most accurate cascade splits we would need to find the min and max values from the depth texture. - if (frameState.shadowHints.closestObjectSize < 200.0) { - clampCascadeDistances = true; - lambda = 0.9; - } + var deltaPhi = rotateRate * phiWindowRatio * Math.PI * 2.0; + var deltaTheta = rotateRate * thetaWindowRatio * Math.PI; - var cascadeDistances = scratchCascadeDistances; - var splits = scratchSplits; - splits[0] = cameraNear; - splits[numberOfCascades] = cameraFar; + if (!rotateOnlyVertical) { + camera.rotateRight(deltaPhi); + } - // Find initial splits - for (i = 0; i < numberOfCascades; ++i) { - var p = (i + 1) / numberOfCascades; - var logScale = cameraNear * Math.pow(ratio, p); - var uniformScale = cameraNear + range * p; - var split = CesiumMath.lerp(uniformScale, logScale, lambda); - splits[i + 1] = split; - cascadeDistances[i] = split - splits[i]; + if (!rotateOnlyHorizontal) { + camera.rotateUp(deltaTheta); } - if (clampCascadeDistances) { - // Clamp each cascade to its maximum distance - for (i = 0; i < numberOfCascades; ++i) { - cascadeDistances[i] = Math.min(cascadeDistances[i], shadowMap._maximumCascadeDistances[i]); - } + camera.constrainedAxis = oldAxis; + } - // Recompute splits - var distance = splits[0]; - for (i = 0; i < numberOfCascades - 1; ++i) { - distance += cascadeDistances[i]; - splits[i + 1] = distance; - } - } + var pan3DP0 = Cartesian4.clone(Cartesian4.UNIT_W); + var pan3DP1 = Cartesian4.clone(Cartesian4.UNIT_W); + var pan3DTemp0 = new Cartesian3(); + var pan3DTemp1 = new Cartesian3(); + var pan3DTemp2 = new Cartesian3(); + var pan3DTemp3 = new Cartesian3(); + var pan3DStartMousePosition = new Cartesian2(); + var pan3DEndMousePosition = new Cartesian2(); - Cartesian4.unpack(splits, 0, shadowMap._cascadeSplits[0]); - Cartesian4.unpack(splits, 1, shadowMap._cascadeSplits[1]); - Cartesian4.unpack(cascadeDistances, 0, shadowMap._cascadeDistances); + function pan3D(controller, startPosition, movement, ellipsoid) { + var scene = controller._scene; + var camera = scene.camera; - var shadowFrustum = shadowMapCamera.frustum; - var left = shadowFrustum.left; - var right = shadowFrustum.right; - var bottom = shadowFrustum.bottom; - var top = shadowFrustum.top; - var near = shadowFrustum.near; - var far = shadowFrustum.far; + var startMousePosition = Cartesian2.clone(movement.startPosition, pan3DStartMousePosition); + var endMousePosition = Cartesian2.clone(movement.endPosition, pan3DEndMousePosition); - var position = shadowMapCamera.positionWC; - var direction = shadowMapCamera.directionWC; - var up = shadowMapCamera.upWC; + var p0 = camera.pickEllipsoid(startMousePosition, ellipsoid, pan3DP0); + var p1 = camera.pickEllipsoid(endMousePosition, ellipsoid, pan3DP1); - var cascadeSubFrustum = sceneCamera.frustum.clone(scratchFrustum); - var shadowViewProjection = shadowMapCamera.getViewProjection(); + if (!defined(p0) || !defined(p1)) { + controller._rotating = true; + rotate3D(controller, startPosition, movement); + return; + } - for (i = 0; i < numberOfCascades; ++i) { - // Find the bounding box of the camera sub-frustum in shadow map texture space - cascadeSubFrustum.near = splits[i]; - cascadeSubFrustum.far = splits[i + 1]; - var viewProjection = Matrix4.multiply(cascadeSubFrustum.projectionMatrix, sceneCamera.viewMatrix, scratchMatrix); - var inverseViewProjection = Matrix4.inverse(viewProjection, scratchMatrix); - var shadowMapMatrix = Matrix4.multiply(shadowViewProjection, inverseViewProjection, scratchMatrix); + p0 = camera.worldToCameraCoordinates(p0, p0); + p1 = camera.worldToCameraCoordinates(p1, p1); - // Project each corner from camera NDC space to shadow map texture space. Min and max will be from 0 to 1. - var min = Cartesian3.fromElements(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, scratchMin); - var max = Cartesian3.fromElements(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, scratchMax); + if (!defined(camera.constrainedAxis)) { + Cartesian3.normalize(p0, p0); + Cartesian3.normalize(p1, p1); + var dot = Cartesian3.dot(p0, p1); + var axis = Cartesian3.cross(p0, p1, pan3DTemp0); - for (var k = 0; k < 8; ++k) { - var corner = Cartesian4.clone(frustumCornersNDC[k], scratchFrustumCorners[k]); - Matrix4.multiplyByVector(shadowMapMatrix, corner, corner); - Cartesian3.divideByScalar(corner, corner.w, corner); // Handle the perspective divide - Cartesian3.minimumByComponent(corner, min, min); - Cartesian3.maximumByComponent(corner, max, max); + if (dot < 1.0 && !Cartesian3.equalsEpsilon(axis, Cartesian3.ZERO, CesiumMath.EPSILON14)) { // dot is in [0, 1] + var angle = Math.acos(dot); + camera.rotate(axis, angle); } + } else { + var basis0 = camera.constrainedAxis; + var basis1 = Cartesian3.mostOrthogonalAxis(basis0, pan3DTemp0); + Cartesian3.cross(basis1, basis0, basis1); + Cartesian3.normalize(basis1, basis1); + var basis2 = Cartesian3.cross(basis0, basis1, pan3DTemp1); - // Limit light-space coordinates to the [0, 1] range - min.x = Math.max(min.x, 0.0); - min.y = Math.max(min.y, 0.0); - min.z = 0.0; // Always start cascade frustum at the top of the light frustum to capture objects in the light's path - max.x = Math.min(max.x, 1.0); - max.y = Math.min(max.y, 1.0); - max.z = Math.min(max.z, 1.0); - - var pass = shadowMap._passes[i]; - var cascadeCamera = pass.camera; - cascadeCamera.clone(shadowMapCamera); // PERFORMANCE_IDEA : could do a shallow clone for all properties except the frustum + var startRho = Cartesian3.magnitude(p0); + var startDot = Cartesian3.dot(basis0, p0); + var startTheta = Math.acos(startDot / startRho); + var startRej = Cartesian3.multiplyByScalar(basis0, startDot, pan3DTemp2); + Cartesian3.subtract(p0, startRej, startRej); + Cartesian3.normalize(startRej, startRej); - var frustum = cascadeCamera.frustum; - frustum.left = left + min.x * (right - left); - frustum.right = left + max.x * (right - left); - frustum.bottom = bottom + min.y * (top - bottom); - frustum.top = bottom + max.y * (top - bottom); - frustum.near = near + min.z * (far - near); - frustum.far = near + max.z * (far - near); + var endRho = Cartesian3.magnitude(p1); + var endDot = Cartesian3.dot(basis0, p1); + var endTheta = Math.acos(endDot / endRho); + var endRej = Cartesian3.multiplyByScalar(basis0, endDot, pan3DTemp3); + Cartesian3.subtract(p1, endRej, endRej); + Cartesian3.normalize(endRej, endRej); - pass.cullingVolume = cascadeCamera.frustum.computeCullingVolume(position, direction, up); + var startPhi = Math.acos(Cartesian3.dot(startRej, basis1)); + if (Cartesian3.dot(startRej, basis2) < 0) { + startPhi = CesiumMath.TWO_PI - startPhi; + } - // Transforms from eye space to the cascade's texture space - var cascadeMatrix = shadowMap._cascadeMatrices[i]; - Matrix4.multiply(cascadeCamera.getViewProjection(), sceneCamera.inverseViewMatrix, cascadeMatrix); - Matrix4.multiply(pass.textureOffsets, cascadeMatrix, cascadeMatrix); - } - } + var endPhi = Math.acos(Cartesian3.dot(endRej, basis1)); + if (Cartesian3.dot(endRej, basis2) < 0) { + endPhi = CesiumMath.TWO_PI - endPhi; + } - var scratchLightView = new Matrix4(); - var scratchRight = new Cartesian3(); - var scratchUp = new Cartesian3(); - var scratchTranslation = new Cartesian3(); + var deltaPhi = startPhi - endPhi; - function fitShadowMapToScene(shadowMap, frameState) { - var shadowMapCamera = shadowMap._shadowMapCamera; - var sceneCamera = shadowMap._sceneCamera; + var east; + if (Cartesian3.equalsEpsilon(basis0, camera.position, CesiumMath.EPSILON2)) { + east = camera.right; + } else { + east = Cartesian3.cross(basis0, camera.position, pan3DTemp0); + } - // 1. First find a tight bounding box in light space that contains the entire camera frustum. - var viewProjection = Matrix4.multiply(sceneCamera.frustum.projectionMatrix, sceneCamera.viewMatrix, scratchMatrix); - var inverseViewProjection = Matrix4.inverse(viewProjection, scratchMatrix); + var planeNormal = Cartesian3.cross(basis0, east, pan3DTemp0); + var side0 = Cartesian3.dot(planeNormal, Cartesian3.subtract(p0, basis0, pan3DTemp1)); + var side1 = Cartesian3.dot(planeNormal, Cartesian3.subtract(p1, basis0, pan3DTemp1)); - // Start to construct the light view matrix. Set translation later once the bounding box is found. - var lightDir = shadowMapCamera.directionWC; - var lightUp = sceneCamera.directionWC; // Align shadows to the camera view. - var lightRight = Cartesian3.cross(lightDir, lightUp, scratchRight); - lightUp = Cartesian3.cross(lightRight, lightDir, scratchUp); // Recalculate up now that right is derived - Cartesian3.normalize(lightUp, lightUp); - Cartesian3.normalize(lightRight, lightRight); - var lightPosition = Cartesian3.fromElements(0.0, 0.0, 0.0, scratchTranslation); + var deltaTheta; + if (side0 > 0 && side1 > 0) { + deltaTheta = endTheta - startTheta; + } else if (side0 > 0 && side1 <= 0) { + if (Cartesian3.dot(camera.position, basis0) > 0) { + deltaTheta = -startTheta - endTheta; + } else { + deltaTheta = startTheta + endTheta; + } + } else { + deltaTheta = startTheta - endTheta; + } - var lightView = Matrix4.computeView(lightPosition, lightDir, lightUp, lightRight, scratchLightView); - var cameraToLight = Matrix4.multiply(lightView, inverseViewProjection, scratchMatrix); + camera.rotateRight(deltaPhi); + camera.rotateUp(deltaTheta); + } + } - // Project each corner from NDC space to light view space, and calculate a min and max in light view space - var min = Cartesian3.fromElements(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, scratchMin); - var max = Cartesian3.fromElements(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, scratchMax); + var zoom3DUnitPosition = new Cartesian3(); + var zoom3DCartographic = new Cartographic(); - for (var i = 0; i < 8; ++i) { - var corner = Cartesian4.clone(frustumCornersNDC[i], scratchFrustumCorners[i]); - Matrix4.multiplyByVector(cameraToLight, corner, corner); - Cartesian3.divideByScalar(corner, corner.w, corner); // Handle the perspective divide - Cartesian3.minimumByComponent(corner, min, min); - Cartesian3.maximumByComponent(corner, max, max); + function zoom3D(controller, startPosition, movement) { + if (defined(movement.distance)) { + movement = movement.distance; } - // 2. Set bounding box back to include objects in the light's view - max.z += 1000.0; // Note: in light space, a positive number is behind the camera - min.z -= 10.0; // Extend the shadow volume forward slightly to avoid problems right at the edge - - // 3. Adjust light view matrix so that it is centered on the bounding volume - var translation = scratchTranslation; - translation.x = -(0.5 * (min.x + max.x)); - translation.y = -(0.5 * (min.y + max.y)); - translation.z = -max.z; + var ellipsoid = controller._ellipsoid; + var scene = controller._scene; + var camera = scene.camera; + var canvas = scene.canvas; - var translationMatrix = Matrix4.fromTranslation(translation, scratchMatrix); - lightView = Matrix4.multiply(translationMatrix, lightView, lightView); + var windowPosition = zoomCVWindowPos; + windowPosition.x = canvas.clientWidth / 2; + windowPosition.y = canvas.clientHeight / 2; + var ray = camera.getPickRay(windowPosition, zoomCVWindowRay); - // 4. Create an orthographic frustum that covers the bounding box extents - var halfWidth = 0.5 * (max.x - min.x); - var halfHeight = 0.5 * (max.y - min.y); - var depth = max.z - min.z; + var intersection; + var height = ellipsoid.cartesianToCartographic(camera.position, zoom3DCartographic).height; + if (height < controller._minimumPickingTerrainHeight) { + intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); + } - var frustum = shadowMapCamera.frustum; - frustum.left = -halfWidth; - frustum.right = halfWidth; - frustum.bottom = -halfHeight; - frustum.top = halfHeight; - frustum.near = 0.01; - frustum.far = depth; + var distance; + if (defined(intersection)) { + distance = Cartesian3.distance(ray.origin, intersection); + } else { + distance = height; + } - // 5. Update the shadow map camera - Matrix4.clone(lightView, shadowMapCamera.viewMatrix); - Matrix4.inverse(lightView, shadowMapCamera.inverseViewMatrix); - Matrix4.getTranslation(shadowMapCamera.inverseViewMatrix, shadowMapCamera.positionWC); - frameState.mapProjection.ellipsoid.cartesianToCartographic(shadowMapCamera.positionWC, shadowMapCamera.positionCartographic); - Cartesian3.clone(lightDir, shadowMapCamera.directionWC); - Cartesian3.clone(lightUp, shadowMapCamera.upWC); - Cartesian3.clone(lightRight, shadowMapCamera.rightWC); + var unitPosition = Cartesian3.normalize(camera.position, zoom3DUnitPosition); + handleZoom(controller, startPosition, movement, controller._zoomFactor, distance, Cartesian3.dot(unitPosition, camera.direction)); } - var directions = [ - new Cartesian3(-1.0, 0.0, 0.0), - new Cartesian3(0.0, -1.0, 0.0), - new Cartesian3(0.0, 0.0, -1.0), - new Cartesian3(1.0, 0.0, 0.0), - new Cartesian3(0.0, 1.0, 0.0), - new Cartesian3(0.0, 0.0, 1.0) - ]; + var tilt3DWindowPos = new Cartesian2(); + var tilt3DRay = new Ray(); + var tilt3DCenter = new Cartesian3(); + var tilt3DVerticalCenter = new Cartesian3(); + var tilt3DTransform = new Matrix4(); + var tilt3DVerticalTransform = new Matrix4(); + var tilt3DOldTransform = new Matrix4(); + var tilt3DQuaternion = new Quaternion(); + var tilt3DMatrix = new Matrix3(); + var tilt3DCart = new Cartographic(); + var tilt3DLookUp = new Cartesian3(); - var ups = [ - new Cartesian3(0.0, -1.0, 0.0), - new Cartesian3(0.0, 0.0, -1.0), - new Cartesian3(0.0, -1.0, 0.0), - new Cartesian3(0.0, -1.0, 0.0), - new Cartesian3(0.0, 0.0, 1.0), - new Cartesian3(0.0, -1.0, 0.0) - ]; + function tilt3D(controller, startPosition, movement) { + var scene = controller._scene; + var camera = scene.camera; - var rights = [ - new Cartesian3(0.0, 0.0, 1.0), - new Cartesian3(1.0, 0.0, 0.0), - new Cartesian3(-1.0, 0.0, 0.0), - new Cartesian3(0.0, 0.0, -1.0), - new Cartesian3(1.0, 0.0, 0.0), - new Cartesian3(1.0, 0.0, 0.0) - ]; + if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) { + return; + } - function computeOmnidirectional(shadowMap, frameState) { - // All sides share the same frustum - var frustum = new PerspectiveFrustum(); - frustum.fov = CesiumMath.PI_OVER_TWO; - frustum.near = 1.0; - frustum.far = shadowMap._pointLightRadius; - frustum.aspectRatio = 1.0; + if (defined(movement.angleAndHeight)) { + movement = movement.angleAndHeight; + } - for (var i = 0; i < 6; ++i) { - var camera = shadowMap._passes[i].camera; - camera.positionWC = shadowMap._shadowMapCamera.positionWC; - camera.positionCartographic = frameState.mapProjection.ellipsoid.cartesianToCartographic(camera.positionWC, camera.positionCartographic); - camera.directionWC = directions[i]; - camera.upWC = ups[i]; - camera.rightWC = rights[i]; + if (!Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { + controller._tiltOnEllipsoid = false; + controller._looking = false; + } - Matrix4.computeView(camera.positionWC, camera.directionWC, camera.upWC, camera.rightWC, camera.viewMatrix); - Matrix4.inverse(camera.viewMatrix, camera.inverseViewMatrix); + if (controller._looking) { + var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, tilt3DLookUp); + look3D(controller, startPosition, movement, up); + return; + } - camera.frustum = frustum; + var ellipsoid = controller._ellipsoid; + var cartographic = ellipsoid.cartesianToCartographic(camera.position, tilt3DCart); + + if (controller._tiltOnEllipsoid || cartographic.height > controller._minimumCollisionTerrainHeight) { + controller._tiltOnEllipsoid = true; + tilt3DOnEllipsoid(controller, startPosition, movement); + } else { + tilt3DOnTerrain(controller, startPosition, movement); } } - var scratchCartesian1 = new Cartesian3(); - var scratchCartesian2 = new Cartesian3(); - var scratchBoundingSphere = new BoundingSphere(); - var scratchCenter = scratchBoundingSphere.center; + var tilt3DOnEllipsoidCartographic = new Cartographic(); - function checkVisibility(shadowMap, frameState) { - var sceneCamera = shadowMap._sceneCamera; - var shadowMapCamera = shadowMap._shadowMapCamera; + function tilt3DOnEllipsoid(controller, startPosition, movement) { + var ellipsoid = controller._ellipsoid; + var scene = controller._scene; + var camera = scene.camera; + var minHeight = controller.minimumZoomDistance * 0.25; + var height = ellipsoid.cartesianToCartographic(camera.positionWC, tilt3DOnEllipsoidCartographic).height; + if (height - minHeight - 1.0 < CesiumMath.EPSILON3 && + movement.endPosition.y - movement.startPosition.y < 0) { + return; + } - var boundingSphere = scratchBoundingSphere; + var canvas = scene.canvas; - // Check whether the shadow map is in view and needs to be updated - if (shadowMap._cascadesEnabled) { - // If the nearest shadow receiver is further than the shadow map's maximum distance then the shadow map is out of view. - if (sceneCamera.frustum.near >= shadowMap.maximumDistance) { - shadowMap._outOfView = true; - shadowMap._needsUpdate = false; + var windowPosition = tilt3DWindowPos; + windowPosition.x = canvas.clientWidth / 2; + windowPosition.y = canvas.clientHeight / 2; + var ray = camera.getPickRay(windowPosition, tilt3DRay); + + var center; + var intersection = IntersectionTests.rayEllipsoid(ray, ellipsoid); + if (defined(intersection)) { + center = Ray.getPoint(ray, intersection.start, tilt3DCenter); + } else if (height > controller._minimumTrackBallHeight) { + var grazingAltitudeLocation = IntersectionTests.grazingAltitudeLocation(ray, ellipsoid); + if (!defined(grazingAltitudeLocation)) { return; } + var grazingAltitudeCart = ellipsoid.cartesianToCartographic(grazingAltitudeLocation, tilt3DCart); + grazingAltitudeCart.height = 0.0; + center = ellipsoid.cartographicToCartesian(grazingAltitudeCart, tilt3DCenter); + } else { + controller._looking = true; + var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, tilt3DLookUp); + look3D(controller, startPosition, movement, up); + Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); + return; + } - // If the light source is below the horizon then the shadow map is out of view - var surfaceNormal = frameState.mapProjection.ellipsoid.geodeticSurfaceNormal(sceneCamera.positionWC, scratchCartesian1); - var lightDirection = Cartesian3.negate(shadowMapCamera.directionWC, scratchCartesian2); - var dot = Cartesian3.dot(surfaceNormal, lightDirection); + var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, tilt3DTransform); - // Shadows start to fade out once the light gets closer to the horizon. - // At this point the globe uses vertex lighting alone to darken the surface. - var darknessAmount = CesiumMath.clamp(dot / 0.1, 0.0, 1.0); - shadowMap._darkness = CesiumMath.lerp(1.0, shadowMap.darkness, darknessAmount); + var oldGlobe = controller._globe; + var oldEllipsoid = controller._ellipsoid; + controller._globe = undefined; + controller._ellipsoid = Ellipsoid.UNIT_SPHERE; + controller._rotateFactor = 1.0; + controller._rotateRateRangeAdjustment = 1.0; - if (dot < 0.0) { - shadowMap._outOfView = true; - shadowMap._needsUpdate = false; - return; - } + var oldTransform = Matrix4.clone(camera.transform, tilt3DOldTransform); + camera._setTransform(transform); - // By default cascaded shadows need to update and are always in view - shadowMap._needsUpdate = true; - shadowMap._outOfView = false; - } else if (shadowMap._isPointLight) { - // Sphere-frustum intersection test - boundingSphere.center = shadowMapCamera.positionWC; - boundingSphere.radius = shadowMap._pointLightRadius; - shadowMap._outOfView = frameState.cullingVolume.computeVisibility(boundingSphere) === Intersect.OUTSIDE; - shadowMap._needsUpdate = !shadowMap._outOfView && !shadowMap._boundingSphere.equals(boundingSphere); - BoundingSphere.clone(boundingSphere, shadowMap._boundingSphere); - } else { - // Simplify frustum-frustum intersection test as a sphere-frustum test - var frustumRadius = shadowMapCamera.frustum.far / 2.0; - var frustumCenter = Cartesian3.add(shadowMapCamera.positionWC, Cartesian3.multiplyByScalar(shadowMapCamera.directionWC, frustumRadius, scratchCenter), scratchCenter); - boundingSphere.center = frustumCenter; - boundingSphere.radius = frustumRadius; - shadowMap._outOfView = frameState.cullingVolume.computeVisibility(boundingSphere) === Intersect.OUTSIDE; - shadowMap._needsUpdate = !shadowMap._outOfView && !shadowMap._boundingSphere.equals(boundingSphere); - BoundingSphere.clone(boundingSphere, shadowMap._boundingSphere); - } + rotate3D(controller, startPosition, movement, Cartesian3.UNIT_Z); + + camera._setTransform(oldTransform); + controller._globe = oldGlobe; + controller._ellipsoid = oldEllipsoid; + + var radius = oldEllipsoid.maximumRadius; + controller._rotateFactor = 1.0 / radius; + controller._rotateRateRangeAdjustment = radius; } - function updateCameras(shadowMap, frameState) { - var camera = frameState.camera; // The actual camera in the scene - var lightCamera = shadowMap._lightCamera; // The external camera representing the light source - var sceneCamera = shadowMap._sceneCamera; // Clone of camera, with clamped near and far planes - var shadowMapCamera = shadowMap._shadowMapCamera; // Camera representing the shadow volume, initially cloned from lightCamera + function tilt3DOnTerrain(controller, startPosition, movement) { + var ellipsoid = controller._ellipsoid; + var scene = controller._scene; + var camera = scene.camera; - // Clone light camera into the shadow map camera - if (shadowMap._cascadesEnabled) { - Cartesian3.clone(lightCamera.directionWC, shadowMapCamera.directionWC); - } else if (shadowMap._isPointLight) { - Cartesian3.clone(lightCamera.positionWC, shadowMapCamera.positionWC); + var center; + var ray; + var intersection; + + if (Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { + center = Cartesian3.clone(controller._tiltCenter, tilt3DCenter); } else { - shadowMapCamera.clone(lightCamera); + center = pickGlobe(controller, startPosition, tilt3DCenter); + + if (!defined(center)) { + ray = camera.getPickRay(startPosition, tilt3DRay); + intersection = IntersectionTests.rayEllipsoid(ray, ellipsoid); + if (!defined(intersection)) { + var cartographic = ellipsoid.cartesianToCartographic(camera.position, tilt3DCart); + if (cartographic.height <= controller._minimumTrackBallHeight) { + controller._looking = true; + var up = controller._ellipsoid.geodeticSurfaceNormal(camera.position, tilt3DLookUp); + look3D(controller, startPosition, movement, up); + Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); + } + return; + } + center = Ray.getPoint(ray, intersection.start, tilt3DCenter); + } + + Cartesian2.clone(startPosition, controller._tiltCenterMousePosition); + Cartesian3.clone(center, controller._tiltCenter); } - // Get the light direction in eye coordinates - var lightDirection = shadowMap._lightDirectionEC; - Matrix4.multiplyByPointAsVector(camera.viewMatrix, shadowMapCamera.directionWC, lightDirection); - Cartesian3.normalize(lightDirection, lightDirection); - Cartesian3.negate(lightDirection, lightDirection); + var canvas = scene.canvas; - // Get the light position in eye coordinates - Matrix4.multiplyByPoint(camera.viewMatrix, shadowMapCamera.positionWC, shadowMap._lightPositionEC); - shadowMap._lightPositionEC.w = shadowMap._pointLightRadius; + var windowPosition = tilt3DWindowPos; + windowPosition.x = canvas.clientWidth / 2; + windowPosition.y = controller._tiltCenterMousePosition.y; + ray = camera.getPickRay(windowPosition, tilt3DRay); - // Get the near and far of the scene camera - var near; - var far; - if (shadowMap._fitNearFar) { - // shadowFar can be very large, so limit to shadowMap.maximumDistance - // Push the far plane slightly further than the near plane to avoid degenerate frustum - near = Math.min(frameState.shadowHints.nearPlane, shadowMap.maximumDistance); - far = Math.min(frameState.shadowHints.farPlane, shadowMap.maximumDistance + 1.0); - } else { - near = camera.frustum.near; - far = shadowMap.maximumDistance; + var mag = Cartesian3.magnitude(center); + var radii = Cartesian3.fromElements(mag, mag, mag, scratchRadii); + var newEllipsoid = Ellipsoid.fromCartesian3(radii, scratchEllipsoid); + + intersection = IntersectionTests.rayEllipsoid(ray, newEllipsoid); + if (!defined(intersection)) { + return; } - shadowMap._sceneCamera = Camera.clone(camera, sceneCamera); - camera.frustum.clone(shadowMap._sceneCamera.frustum); - shadowMap._sceneCamera.frustum.near = near; - shadowMap._sceneCamera.frustum.far = far; - shadowMap._distance = far - near; + var t = Cartesian3.magnitude(ray.origin) > mag ? intersection.start : intersection.stop; + var verticalCenter = Ray.getPoint(ray, t, tilt3DVerticalCenter); - checkVisibility(shadowMap, frameState); + var transform = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, tilt3DTransform); + var verticalTransform = Transforms.eastNorthUpToFixedFrame(verticalCenter, newEllipsoid, tilt3DVerticalTransform); - if (!shadowMap._outOfViewPrevious && shadowMap._outOfView) { - shadowMap._needsUpdate = true; - } - shadowMap._outOfViewPrevious = shadowMap._outOfView; - } + var oldGlobe = controller._globe; + var oldEllipsoid = controller._ellipsoid; + controller._globe = undefined; + controller._ellipsoid = Ellipsoid.UNIT_SPHERE; + controller._rotateFactor = 1.0; + controller._rotateRateRangeAdjustment = 1.0; - /** - * @private - */ - ShadowMap.prototype.update = function(frameState) { - updateCameras(this, frameState); + var constrainedAxis = Cartesian3.UNIT_Z; - if (this._needsUpdate) { - updateFramebuffer(this, frameState.context); + var oldTransform = Matrix4.clone(camera.transform, tilt3DOldTransform); + camera._setTransform(transform); - if (this._isPointLight) { - computeOmnidirectional(this, frameState); - } + var tangent = Cartesian3.cross(verticalCenter, camera.positionWC, tilt3DCartesian3); + var dot = Cartesian3.dot(camera.rightWC, tangent); - if (this._cascadesEnabled) { - fitShadowMapToScene(this, frameState); + rotate3D(controller, startPosition, movement, constrainedAxis, false, true); - if (this._numberOfCascades > 1) { - computeCascades(this, frameState); - } + camera._setTransform(verticalTransform); + + if (dot < 0.0) { + if (movement.startPosition.y > movement.endPosition.y) { + constrainedAxis = undefined; } - if (!this._isPointLight) { - // Compute the culling volume - var shadowMapCamera = this._shadowMapCamera; - var position = shadowMapCamera.positionWC; - var direction = shadowMapCamera.directionWC; - var up = shadowMapCamera.upWC; - this._shadowMapCullingVolume = shadowMapCamera.frustum.computeCullingVolume(position, direction, up); + var oldConstrainedAxis = camera.constrainedAxis; + camera.constrainedAxis = undefined; - if (this._passes.length === 1) { - // Since there is only one pass, use the shadow map camera as the pass camera. - this._passes[0].camera.clone(shadowMapCamera); - } - } else { - this._shadowMapCullingVolume = CullingVolume.fromBoundingSphere(this._boundingSphere); - } - } + rotate3D(controller, startPosition, movement, constrainedAxis, true, false); - if (this._passes.length === 1) { - // Transforms from eye space to shadow texture space. - // Always requires an update since the scene camera constantly changes. - var inverseView = this._sceneCamera.inverseViewMatrix; - Matrix4.multiply(this._shadowMapCamera.getViewProjection(), inverseView, this._shadowMapMatrix); + camera.constrainedAxis = oldConstrainedAxis; + } else { + rotate3D(controller, startPosition, movement, constrainedAxis, true, false); } - if (this.debugShow) { - applyDebugSettings(this, frameState); + if (defined(camera.constrainedAxis)) { + var right = Cartesian3.cross(camera.direction, camera.constrainedAxis, tilt3DCartesian3); + if (!Cartesian3.equalsEpsilon(right, Cartesian3.ZERO, CesiumMath.EPSILON6)) { + if (Cartesian3.dot(right, camera.right) < 0.0) { + Cartesian3.negate(right, right); + } + + Cartesian3.cross(right, camera.direction, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + + Cartesian3.normalize(camera.up, camera.up); + Cartesian3.normalize(camera.right, camera.right); + } } - }; - /** - * @private - */ - ShadowMap.prototype.updatePass = function(context, shadowPass) { - clearFramebuffer(this, context, shadowPass); - }; + camera._setTransform(oldTransform); + controller._globe = oldGlobe; + controller._ellipsoid = oldEllipsoid; - var scratchTexelStepSize = new Cartesian2(); + var radius = oldEllipsoid.maximumRadius; + controller._rotateFactor = 1.0 / radius; + controller._rotateRateRangeAdjustment = radius; - function combineUniforms(shadowMap, uniforms, isTerrain) { - var bias = shadowMap._isPointLight ? shadowMap._pointBias : (isTerrain ? shadowMap._terrainBias : shadowMap._primitiveBias); + var originalPosition = Cartesian3.clone(camera.positionWC, tilt3DCartesian3); + camera._adjustHeightForTerrain(); - var mapUniforms = { - shadowMap_texture :function() { - return shadowMap._shadowMapTexture; - }, - shadowMap_textureCube : function() { - return shadowMap._shadowMapTexture; - }, - shadowMap_matrix : function() { - return shadowMap._shadowMapMatrix; - }, - shadowMap_cascadeSplits : function() { - return shadowMap._cascadeSplits; - }, - shadowMap_cascadeMatrices : function() { - return shadowMap._cascadeMatrices; - }, - shadowMap_lightDirectionEC : function() { - return shadowMap._lightDirectionEC; - }, - shadowMap_lightPositionEC : function() { - return shadowMap._lightPositionEC; - }, - shadowMap_cascadeDistances : function() { - return shadowMap._cascadeDistances; - }, - shadowMap_texelSizeDepthBiasAndNormalShadingSmooth : function() { - var texelStepSize = scratchTexelStepSize; - texelStepSize.x = 1.0 / shadowMap._textureSize.x; - texelStepSize.y = 1.0 / shadowMap._textureSize.y; + if (!Cartesian3.equals(camera.positionWC, originalPosition)) { + camera._setTransform(verticalTransform); + camera.worldToCameraCoordinatesPoint(originalPosition, originalPosition); - return Cartesian4.fromElements(texelStepSize.x, texelStepSize.y, bias.depthBias, bias.normalShadingSmooth, this.combinedUniforms1); - }, - shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness : function() { - return Cartesian4.fromElements(bias.normalOffsetScale, shadowMap._distance, shadowMap.maximumDistance, shadowMap._darkness, this.combinedUniforms2); - }, + var magSqrd = Cartesian3.magnitudeSquared(originalPosition); + if (Cartesian3.magnitudeSquared(camera.position) > magSqrd) { + Cartesian3.normalize(camera.position, camera.position); + Cartesian3.multiplyByScalar(camera.position, Math.sqrt(magSqrd), camera.position); + } - combinedUniforms1 : new Cartesian4(), - combinedUniforms2 : new Cartesian4() - }; + var angle = Cartesian3.angleBetween(originalPosition, camera.position); + var axis = Cartesian3.cross(originalPosition, camera.position, originalPosition); + Cartesian3.normalize(axis, axis); - return combine(uniforms, mapUniforms, false); - } + var quaternion = Quaternion.fromAxisAngle(axis, angle, tilt3DQuaternion); + var rotation = Matrix3.fromQuaternion(quaternion, tilt3DMatrix); + Matrix3.multiplyByVector(rotation, camera.direction, camera.direction); + Matrix3.multiplyByVector(rotation, camera.up, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.cross(camera.right, camera.direction, camera.up); - function createCastDerivedCommand(shadowMap, shadowsDirty, command, context, oldShaderId, result) { - var castShader; - var castRenderState; - var castUniformMap; - if (defined(result)) { - castShader = result.shaderProgram; - castRenderState = result.renderState; - castUniformMap = result.uniformMap; + camera._setTransform(oldTransform); } + } - result = DrawCommand.shallowClone(command, result); - result.castShadows = true; - result.receiveShadows = false; - - if (!defined(castShader) || oldShaderId !== command.shaderProgram.id || shadowsDirty) { - var shaderProgram = command.shaderProgram; + var look3DStartPos = new Cartesian2(); + var look3DEndPos = new Cartesian2(); + var look3DStartRay = new Ray(); + var look3DEndRay = new Ray(); + var look3DNegativeRot = new Cartesian3(); + var look3DTan = new Cartesian3(); - var isTerrain = command.pass === Pass.GLOBE; - var isOpaque = command.pass !== Pass.TRANSLUCENT; - var isPointLight = shadowMap._isPointLight; - var usesDepthTexture= shadowMap._usesDepthTexture; + function look3D(controller, startPosition, movement, rotationAxis) { + var scene = controller._scene; + var camera = scene.camera; - var keyword = ShadowMapShader.getShadowCastShaderKeyword(isPointLight, isTerrain, usesDepthTexture, isOpaque); - castShader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword); - if (!defined(castShader)) { - var vertexShaderSource = shaderProgram.vertexShaderSource; - var fragmentShaderSource = shaderProgram.fragmentShaderSource; + var startPos = look3DStartPos; + startPos.x = movement.startPosition.x; + startPos.y = 0.0; + var endPos = look3DEndPos; + endPos.x = movement.endPosition.x; + endPos.y = 0.0; - var castVS = ShadowMapShader.createShadowCastVertexShader(vertexShaderSource, isPointLight, isTerrain); - var castFS = ShadowMapShader.createShadowCastFragmentShader(fragmentShaderSource, isPointLight, usesDepthTexture, isOpaque); + var startRay = camera.getPickRay(startPos, look3DStartRay); + var endRay = camera.getPickRay(endPos, look3DEndRay); + var angle = 0.0; + var start; + var end; - castShader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, { - vertexShaderSource : castVS, - fragmentShaderSource : castFS, - attributeLocations : shaderProgram._attributeLocations - }); - } + if (camera.frustum instanceof OrthographicFrustum) { + start = startRay.origin; + end = endRay.origin; - castRenderState = shadowMap._primitiveRenderState; - if (isPointLight) { - castRenderState = shadowMap._pointRenderState; - } else if (isTerrain) { - castRenderState = shadowMap._terrainRenderState; - } + Cartesian3.add(camera.direction, start, start); + Cartesian3.add(camera.direction, end, end); - // Modify the render state for commands that do not use back-face culling, e.g. flat textured walls - var cullEnabled = command.renderState.cull.enabled; - if (!cullEnabled) { - castRenderState = clone(castRenderState, false); - castRenderState.cull = clone(castRenderState.cull, false); - castRenderState.cull.enabled = false; - castRenderState = RenderState.fromCache(castRenderState); - } + Cartesian3.subtract(start, camera.position, start); + Cartesian3.subtract(end, camera.position, end); - castUniformMap = combineUniforms(shadowMap, command.uniformMap, isTerrain); + Cartesian3.normalize(start, start); + Cartesian3.normalize(end, end); + } else { + start = startRay.direction; + end = endRay.direction; } - result.shaderProgram = castShader; - result.renderState = castRenderState; - result.uniformMap = castUniformMap; + var dot = Cartesian3.dot(start, end); + if (dot < 1.0) { // dot is in [0, 1] + angle = Math.acos(dot); + } - return result; - } + angle = (movement.startPosition.x > movement.endPosition.x) ? -angle : angle; - ShadowMap.createDerivedCommands = function(shadowMaps, lightShadowMaps, command, shadowsDirty, context, result) { - if (!defined(result)) { - result = {}; + var horizontalRotationAxis = controller._horizontalRotationAxis; + if (defined(rotationAxis)) { + camera.look(rotationAxis, -angle); + } else if (defined(horizontalRotationAxis)) { + camera.look(horizontalRotationAxis, -angle); + } else { + camera.lookLeft(angle); } - var lightShadowMapsEnabled = (lightShadowMaps.length > 0); - var shaderProgram = command.shaderProgram; - var vertexShaderSource = shaderProgram.vertexShaderSource; - var fragmentShaderSource = shaderProgram.fragmentShaderSource; - var isTerrain = command.pass === Pass.GLOBE; + startPos.x = 0.0; + startPos.y = movement.startPosition.y; + endPos.x = 0.0; + endPos.y = movement.endPosition.y; - var hasTerrainNormal = false; - if (isTerrain) { - hasTerrainNormal = command.owner.data.pickTerrain.mesh.encoding.hasVertexNormals; - } + startRay = camera.getPickRay(startPos, look3DStartRay); + endRay = camera.getPickRay(endPos, look3DEndRay); + angle = 0.0; - if (command.castShadows) { - var castCommands = result.castCommands; - if (!defined(castCommands)) { - castCommands = result.castCommands = []; - } + if (camera.frustum instanceof OrthographicFrustum) { + start = startRay.origin; + end = endRay.origin; - var oldShaderId = result.castShaderProgramId; + Cartesian3.add(camera.direction, start, start); + Cartesian3.add(camera.direction, end, end); - var shadowMapLength = shadowMaps.length; - castCommands.length = shadowMapLength; + Cartesian3.subtract(start, camera.position, start); + Cartesian3.subtract(end, camera.position, end); - for (var i = 0; i < shadowMapLength; ++i) { - castCommands[i] = createCastDerivedCommand(shadowMaps[i], shadowsDirty, command, context, oldShaderId, castCommands[i]); - } + Cartesian3.normalize(start, start); + Cartesian3.normalize(end, end); + } else { + start = startRay.direction; + end = endRay.direction; + } - result.castShaderProgramId = command.shaderProgram.id; + dot = Cartesian3.dot(start, end); + if (dot < 1.0) { // dot is in [0, 1] + angle = Math.acos(dot); } + angle = (movement.startPosition.y > movement.endPosition.y) ? -angle : angle; - if (command.receiveShadows && lightShadowMapsEnabled) { - // Only generate a receiveCommand if there is a shadow map originating from a light source. - var receiveShader; - var receiveUniformMap; - if (defined(result.receiveCommand)) { - receiveShader = result.receiveCommand.shaderProgram; - receiveUniformMap = result.receiveCommand.uniformMap; - } + rotationAxis = defaultValue(rotationAxis, horizontalRotationAxis); + if (defined(rotationAxis)) { + var direction = camera.direction; + var negativeRotationAxis = Cartesian3.negate(rotationAxis, look3DNegativeRot); + var northParallel = Cartesian3.equalsEpsilon(direction, rotationAxis, CesiumMath.EPSILON2); + var southParallel = Cartesian3.equalsEpsilon(direction, negativeRotationAxis, CesiumMath.EPSILON2); + if ((!northParallel && !southParallel)) { + dot = Cartesian3.dot(direction, rotationAxis); + var angleToAxis = CesiumMath.acosClamped(dot); + if (angle > 0 && angle > angleToAxis) { + angle = angleToAxis - CesiumMath.EPSILON4; + } - result.receiveCommand = DrawCommand.shallowClone(command, result.receiveCommand); - result.castShadows = false; - result.receiveShadows = true; + dot = Cartesian3.dot(direction, negativeRotationAxis); + angleToAxis = CesiumMath.acosClamped(dot); + if (angle < 0 && -angle > angleToAxis) { + angle = -angleToAxis + CesiumMath.EPSILON4; + } - // If castShadows changed, recompile the receive shadows shader. The normal shading technique simulates - // self-shadowing so it should be turned off if castShadows is false. - var castShadowsDirty = result.receiveShaderCastShadows !== command.castShadows; - var shaderDirty = result.receiveShaderProgramId !== command.shaderProgram.id; + var tangent = Cartesian3.cross(rotationAxis, direction, look3DTan); + camera.look(tangent, angle); + } else if ((northParallel && angle < 0) || (southParallel && angle > 0)) { + camera.look(camera.right, -angle); + } + } else { + camera.lookUp(angle); + } + } - if (!defined(receiveShader) || shaderDirty || shadowsDirty || castShadowsDirty) { - var keyword = ShadowMapShader.getShadowReceiveShaderKeyword(lightShadowMaps[0], command.castShadows, isTerrain, hasTerrainNormal); - receiveShader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword); - if (!defined(receiveShader)) { - var receiveVS = ShadowMapShader.createShadowReceiveVertexShader(vertexShaderSource, isTerrain, hasTerrainNormal); - var receiveFS = ShadowMapShader.createShadowReceiveFragmentShader(fragmentShaderSource, lightShadowMaps[0], command.castShadows, isTerrain, hasTerrainNormal); + function update3D(controller) { + reactToInput(controller, controller.enableRotate, controller.rotateEventTypes, spin3D, controller.inertiaSpin, '_lastInertiaSpinMovement'); + reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom3D, controller.inertiaZoom, '_lastInertiaZoomMovement'); + reactToInput(controller, controller.enableTilt, controller.tiltEventTypes, tilt3D, controller.inertiaSpin, '_lastInertiaTiltMovement'); + reactToInput(controller, controller.enableLook, controller.lookEventTypes, look3D); + } - receiveShader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, { - vertexShaderSource : receiveVS, - fragmentShaderSource : receiveFS, - attributeLocations : shaderProgram._attributeLocations - }); - } + /** + * @private + */ + ScreenSpaceCameraController.prototype.update = function() { + if (!Matrix4.equals(this._scene.camera.transform, Matrix4.IDENTITY)) { + this._globe = undefined; + this._ellipsoid = Ellipsoid.UNIT_SPHERE; + } else { + this._globe = this._scene.globe; + this._ellipsoid = defined(this._globe) ? this._globe.ellipsoid : this._scene.mapProjection.ellipsoid; + } - receiveUniformMap = combineUniforms(lightShadowMaps[0], command.uniformMap, isTerrain); - } + this._minimumCollisionTerrainHeight = this.minimumCollisionTerrainHeight * this._scene.terrainExaggeration; + this._minimumPickingTerrainHeight = this.minimumPickingTerrainHeight * this._scene.terrainExaggeration; + this._minimumTrackBallHeight = this.minimumTrackBallHeight * this._scene.terrainExaggeration; - result.receiveCommand.shaderProgram = receiveShader; - result.receiveCommand.uniformMap = receiveUniformMap; - result.receiveShaderProgramId = command.shaderProgram.id; - result.receiveShaderCastShadows = command.castShadows; + var radius = this._ellipsoid.maximumRadius; + this._rotateFactor = 1.0 / radius; + this._rotateRateRangeAdjustment = radius; + + var scene = this._scene; + var mode = scene.mode; + if (mode === SceneMode.SCENE2D) { + update2D(this); + } else if (mode === SceneMode.COLUMBUS_VIEW) { + this._horizontalRotationAxis = Cartesian3.UNIT_Z; + updateCV(this); + } else if (mode === SceneMode.SCENE3D) { + this._horizontalRotationAxis = undefined; + update3D(this); } - return result; + this._aggregator.reset(); }; /** - * @private + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see ScreenSpaceCameraController#destroy */ - ShadowMap.prototype.isDestroyed = function() { + ScreenSpaceCameraController.prototype.isDestroyed = function() { return false; }; /** - * @private + * Removes mouse listeners held by this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * controller = controller && controller.destroy(); + * + * @see ScreenSpaceCameraController#isDestroyed */ - ShadowMap.prototype.destroy = function() { - destroyFramebuffer(this); - - this._debugLightFrustum = this._debugLightFrustum && this._debugLightFrustum.destroy(); - this._debugCameraFrustum = this._debugCameraFrustum && this._debugCameraFrustum.destroy(); - this._debugShadowViewCommand = this._debugShadowViewCommand && this._debugShadowViewCommand.shaderProgram && this._debugShadowViewCommand.shaderProgram.destroy(); - - for (var i = 0; i < this._numberOfCascades; ++i) { - this._debugCascadeFrustums[i] = this._debugCascadeFrustums[i] && this._debugCascadeFrustums[i].destroy(); - } - + ScreenSpaceCameraController.prototype.destroy = function() { + this._tweens.removeAll(); + this._aggregator = this._aggregator && this._aggregator.destroy(); return destroyObject(this); }; - return ShadowMap; + return ScreenSpaceCameraController; }); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PostProcessFilters/AdditiveBlend',[],function() { - 'use strict'; - return "uniform sampler2D u_texture0;\n\ -uniform sampler2D u_texture1;\n\ -uniform vec2 u_center;\n\ -uniform float u_radius;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -vec4 color0 = texture2D(u_texture0, v_textureCoordinates);\n\ -vec4 color1 = texture2D(u_texture1, v_textureCoordinates);\n\ -float x = length(gl_FragCoord.xy - u_center) / u_radius;\n\ -float t = smoothstep(0.5, 0.8, x);\n\ -gl_FragColor = mix(color0 + color1, color0, t);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PostProcessFilters/BrightPass',[],function() { - 'use strict'; - return "uniform sampler2D u_texture;\n\ -uniform float u_avgLuminance;\n\ -uniform float u_threshold;\n\ -uniform float u_offset;\n\ -varying vec2 v_textureCoordinates;\n\ -float key(float avg)\n\ -{\n\ -float guess = 1.5 - (1.5 / (avg * 0.1 + 1.0));\n\ -return max(0.0, guess) + 0.1;\n\ -}\n\ -void main()\n\ -{\n\ -vec4 color = texture2D(u_texture, v_textureCoordinates);\n\ -vec3 xyz = czm_RGBToXYZ(color.rgb);\n\ -float luminance = xyz.r;\n\ -float scaledLum = key(u_avgLuminance) * luminance / u_avgLuminance;\n\ -float brightLum = max(scaledLum - u_threshold, 0.0);\n\ -float brightness = brightLum / (u_offset + brightLum);\n\ -xyz.r = brightness;\n\ -gl_FragColor = vec4(czm_XYZToRGB(xyz), 1.0);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/PostProcessFilters/GaussianBlur1D',[],function() { - 'use strict'; - return "#define SAMPLES 8\n\ -uniform float delta;\n\ -uniform float sigma;\n\ -uniform float direction;\n\ -uniform sampler2D u_texture;\n\ -uniform vec2 u_step;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -vec2 st = v_textureCoordinates;\n\ -vec2 dir = vec2(1.0 - direction, direction);\n\ -vec3 g;\n\ -g.x = 1.0 / (sqrt(czm_twoPi) * sigma);\n\ -g.y = exp((-0.5 * delta * delta) / (sigma * sigma));\n\ -g.z = g.y * g.y;\n\ -vec4 result = texture2D(u_texture, st) * g.x;\n\ -for (int i = 1; i < SAMPLES; ++i)\n\ -{\n\ -g.xy *= g.yz;\n\ -vec2 offset = float(i) * dir * u_step;\n\ -result += texture2D(u_texture, st - offset) * g.x;\n\ -result += texture2D(u_texture, st + offset) * g.x;\n\ -}\n\ -gl_FragColor = result;\n\ -}\n\ -"; -}); -define('Scene/SunPostProcess',[ - '../Core/BoundingRectangle', - '../Core/Cartesian2', - '../Core/Cartesian4', - '../Core/Color', - '../Core/defaultValue', +define('Scene/ShadowMapShader',[ '../Core/defined', - '../Core/destroyObject', - '../Core/Math', - '../Core/Matrix4', - '../Core/PixelFormat', - '../Core/Transforms', - '../Renderer/ClearCommand', - '../Renderer/Framebuffer', - '../Renderer/PassState', - '../Renderer/PixelDatatype', - '../Renderer/Renderbuffer', - '../Renderer/RenderbufferFormat', - '../Renderer/RenderState', - '../Renderer/Texture', - '../Shaders/PostProcessFilters/AdditiveBlend', - '../Shaders/PostProcessFilters/BrightPass', - '../Shaders/PostProcessFilters/GaussianBlur1D', - '../Shaders/PostProcessFilters/PassThrough' + '../Renderer/ShaderSource' ], function( - BoundingRectangle, - Cartesian2, - Cartesian4, - Color, - defaultValue, defined, - destroyObject, - CesiumMath, - Matrix4, - PixelFormat, - Transforms, - ClearCommand, - Framebuffer, - PassState, - PixelDatatype, - Renderbuffer, - RenderbufferFormat, - RenderState, - Texture, - AdditiveBlend, - BrightPass, - GaussianBlur1D, - PassThrough) { + ShaderSource) { 'use strict'; - function SunPostProcess() { - this._fbo = undefined; - - this._downSampleFBO1 = undefined; - this._downSampleFBO2 = undefined; - - this._clearFBO1Command = undefined; - this._clearFBO2Command = undefined; + /** + * @private + */ + function ShadowMapShader() { + } - this._downSampleCommand = undefined; - this._brightPassCommand = undefined; - this._blurXCommand = undefined; - this._blurYCommand = undefined; - this._blendCommand = undefined; - this._fullScreenCommand = undefined; + ShadowMapShader.getShadowCastShaderKeyword = function(isPointLight, isTerrain, usesDepthTexture, isOpaque) { + return 'castShadow ' + isPointLight + ' ' + isTerrain + ' ' + usesDepthTexture + ' ' + isOpaque; + }; - this._downSamplePassState = new PassState(); - this._downSamplePassState.scissorTest = { - enable : true, - rectangle : new BoundingRectangle() - }; + ShadowMapShader.createShadowCastVertexShader = function(vs, isPointLight, isTerrain) { + var defines = vs.defines.slice(0); + var sources = vs.sources.slice(0); - this._upSamplePassState = new PassState(); - this._upSamplePassState.scissorTest = { - enabled : true, - rectangle : new BoundingRectangle() - }; + if (isTerrain) { + defines.push('GENERATE_POSITION'); + } - this._uCenter = new Cartesian2(); - this._uRadius = undefined; + var positionVaryingName = ShaderSource.findPositionVarying(vs); + var hasPositionVarying = defined(positionVaryingName); - this._blurStep = new Cartesian2(); - } + if (isPointLight && !hasPositionVarying) { + var length = sources.length; + for (var j = 0; j < length; ++j) { + sources[j] = ShaderSource.replaceMain(sources[j], 'czm_shadow_cast_main'); + } - SunPostProcess.prototype.clear = function(context, color) { - var clear = this._clearFBO1Command; - Color.clone(defaultValue(color, Color.BLACK), clear.color); - clear.execute(context); + var shadowVS = + 'varying vec3 v_positionEC; \n' + + 'void main() \n' + + '{ \n' + + ' czm_shadow_cast_main(); \n' + + ' v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n' + + '}'; + sources.push(shadowVS); + } - clear = this._clearFBO2Command; - Color.clone(defaultValue(color, Color.BLACK), clear.color); - clear.execute(context); + return new ShaderSource({ + defines : defines, + sources : sources + }); }; - SunPostProcess.prototype.execute = function(context, framebuffer) { - this._downSampleCommand.execute(context, this._downSamplePassState); - this._brightPassCommand.execute(context, this._downSamplePassState); - this._blurXCommand.execute(context, this._downSamplePassState); - this._blurYCommand.execute(context, this._downSamplePassState); + ShadowMapShader.createShadowCastFragmentShader = function(fs, isPointLight, usesDepthTexture, opaque) { + var defines = fs.defines.slice(0); + var sources = fs.sources.slice(0); - this._fullScreenCommand.framebuffer = framebuffer; - this._blendCommand.framebuffer = framebuffer; + var positionVaryingName = ShaderSource.findPositionVarying(fs); + var hasPositionVarying = defined(positionVaryingName); + if (!hasPositionVarying) { + positionVaryingName = 'v_positionEC'; + } - this._fullScreenCommand.execute(context); - this._blendCommand.execute(context, this._upSamplePassState); - }; + var length = sources.length; + for (var i = 0; i < length; ++i) { + sources[i] = ShaderSource.replaceMain(sources[i], 'czm_shadow_cast_main'); + } - var viewportBoundingRectangle = new BoundingRectangle(); - var downSampleViewportBoundingRectangle = new BoundingRectangle(); - var sunPositionECScratch = new Cartesian4(); - var sunPositionWCScratch = new Cartesian2(); - var sizeScratch = new Cartesian2(); - var postProcessMatrix4Scratch= new Matrix4(); + var fsSource = ''; - SunPostProcess.prototype.update = function(passState) { - var context = passState.context; - var viewport = passState.viewport; - var width = context.drawingBufferWidth; - var height = context.drawingBufferHeight; + if (isPointLight) { + if (!hasPositionVarying) { + fsSource += 'varying vec3 v_positionEC; \n'; + } + fsSource += 'uniform vec4 shadowMap_lightPositionEC; \n'; + } - var that = this; + if (opaque) { + fsSource += + 'void main() \n' + + '{ \n'; + } else { + fsSource += + 'void main() \n' + + '{ \n' + + ' czm_shadow_cast_main(); \n' + + ' if (gl_FragColor.a == 0.0) \n' + + ' { \n' + + ' discard; \n' + + ' } \n'; + } - if (!defined(this._downSampleCommand)) { - this._clearFBO1Command = new ClearCommand({ - color : new Color() - }); - this._clearFBO2Command = new ClearCommand({ - color : new Color() - }); + if (isPointLight) { + fsSource += + ' float distance = length(' + positionVaryingName + '); \n' + + ' if (distance >= shadowMap_lightPositionEC.w) \n' + + ' { \n' + + ' discard; \n' + + ' } \n' + + ' distance /= shadowMap_lightPositionEC.w; // radius \n' + + ' gl_FragColor = czm_packDepth(distance); \n'; + } else if (usesDepthTexture) { + fsSource += ' gl_FragColor = vec4(1.0); \n'; + } else { + fsSource += ' gl_FragColor = czm_packDepth(gl_FragCoord.z); \n'; + } - var uniformMap = {}; + fsSource += '} \n'; - this._downSampleCommand = context.createViewportQuadCommand(PassThrough, { - uniformMap : uniformMap, - owner : this - }); + sources.push(fsSource); - uniformMap = { - u_avgLuminance : function() { - // A guess at the average luminance across the entire scene - return 0.5; - }, - u_threshold : function() { - return 0.25; - }, - u_offset : function() { - return 0.1; - } - }; + return new ShaderSource({ + defines : defines, + sources : sources + }); + }; - this._brightPassCommand = context.createViewportQuadCommand(BrightPass, { - uniformMap : uniformMap, - owner : this - }); + ShadowMapShader.getShadowReceiveShaderKeyword = function(shadowMap, castShadows, isTerrain, hasTerrainNormal) { + var usesDepthTexture = shadowMap._usesDepthTexture; + var polygonOffsetSupported = shadowMap._polygonOffsetSupported; + var isPointLight = shadowMap._isPointLight; + var isSpotLight = shadowMap._isSpotLight; + var hasCascades = shadowMap._numberOfCascades > 1; + var debugCascadeColors = shadowMap.debugCascadeColors; + var softShadows = shadowMap.softShadows; - var delta = 1.0; - var sigma = 2.0; + return 'receiveShadow ' + usesDepthTexture + polygonOffsetSupported + isPointLight + isSpotLight + + hasCascades + debugCascadeColors + softShadows + castShadows + isTerrain + hasTerrainNormal; + }; - uniformMap = { - delta : function() { - return delta; - }, - sigma : function() { - return sigma; - }, - direction : function() { - return 0.0; - } - }; + ShadowMapShader.createShadowReceiveVertexShader = function(vs, isTerrain, hasTerrainNormal) { + var defines = vs.defines.slice(0); + var sources = vs.sources.slice(0); - this._blurXCommand = context.createViewportQuadCommand(GaussianBlur1D, { - uniformMap : uniformMap, - owner : this - }); + if (isTerrain) { + if (hasTerrainNormal) { + defines.push('GENERATE_POSITION_AND_NORMAL'); + } else { + defines.push('GENERATE_POSITION'); + } + } - uniformMap = { - delta : function() { - return delta; - }, - sigma : function() { - return sigma; - }, - direction : function() { - return 1.0; - } - }; + return new ShaderSource({ + defines : defines, + sources : sources + }); + }; - this._blurYCommand = context.createViewportQuadCommand(GaussianBlur1D, { - uniformMap : uniformMap, - owner : this - }); + ShadowMapShader.createShadowReceiveFragmentShader = function(fs, shadowMap, castShadows, isTerrain, hasTerrainNormal) { + var normalVaryingName = ShaderSource.findNormalVarying(fs); + var hasNormalVarying = (!isTerrain && defined(normalVaryingName)) || (isTerrain && hasTerrainNormal); - uniformMap = { - u_center : function() { - return that._uCenter; - }, - u_radius : function() { - return that._uRadius; - } - }; + var positionVaryingName = ShaderSource.findPositionVarying(fs); + var hasPositionVarying = defined(positionVaryingName); - this._blendCommand = context.createViewportQuadCommand(AdditiveBlend, { - uniformMap : uniformMap, - owner : this - }); + var usesDepthTexture = shadowMap._usesDepthTexture; + var polygonOffsetSupported = shadowMap._polygonOffsetSupported; + var isPointLight = shadowMap._isPointLight; + var isSpotLight = shadowMap._isSpotLight; + var hasCascades = shadowMap._numberOfCascades > 1; + var debugCascadeColors = shadowMap.debugCascadeColors; + var softShadows = shadowMap.softShadows; + var bias = isPointLight ? shadowMap._pointBias : (isTerrain ? shadowMap._terrainBias : shadowMap._primitiveBias); - uniformMap = {}; + var defines = fs.defines.slice(0); + var sources = fs.sources.slice(0); - this._fullScreenCommand = context.createViewportQuadCommand(PassThrough, { - uniformMap : uniformMap, - owner : this - }); + var length = sources.length; + for (var i = 0; i < length; ++i) { + sources[i] = ShaderSource.replaceMain(sources[i], 'czm_shadow_receive_main'); } - var downSampleWidth = Math.pow(2.0, Math.ceil(Math.log(width) / Math.log(2)) - 2.0); - var downSampleHeight = Math.pow(2.0, Math.ceil(Math.log(height) / Math.log(2)) - 2.0); - - // The size computed above can be less than 1.0 if size < 4.0. This will probably - // never happen in practice, but does in the tests. Clamp to 1.0 to prevent WebGL - // errors in the tests. - var downSampleSize = Math.max(1.0, downSampleWidth, downSampleHeight); + if (isPointLight) { + defines.push('USE_CUBE_MAP_SHADOW'); + } else if (usesDepthTexture) { + defines.push('USE_SHADOW_DEPTH_TEXTURE'); + } - var downSampleViewport = downSampleViewportBoundingRectangle; - downSampleViewport.width = downSampleSize; - downSampleViewport.height = downSampleSize; + if (softShadows && !isPointLight) { + defines.push('USE_SOFT_SHADOWS'); + } - var fbo = this._fbo; - var colorTexture = (defined(fbo) && fbo.getColorTexture(0)) || undefined; - if (!defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height) { - fbo = fbo && fbo.destroy(); - this._downSampleFBO1 = this._downSampleFBO1 && this._downSampleFBO1.destroy(); - this._downSampleFBO2 = this._downSampleFBO2 && this._downSampleFBO2.destroy(); + // Enable day-night shading so that the globe is dark when the light is below the horizon + if (hasCascades && castShadows && isTerrain) { + if (hasNormalVarying) { + defines.push('ENABLE_VERTEX_LIGHTING'); + } else { + defines.push('ENABLE_DAYNIGHT_SHADING'); + } + } - this._blurStep.x = this._blurStep.y = 1.0 / downSampleSize; + if (castShadows && bias.normalShading && hasNormalVarying) { + defines.push('USE_NORMAL_SHADING'); + if (bias.normalShadingSmooth > 0.0) { + defines.push('USE_NORMAL_SHADING_SMOOTH'); + } + } - var colorTextures = [new Texture({ - context : context, - width : width, - height : height - })]; + var fsSource = ''; - if (context.depthTexture) { - fbo = this._fbo = new Framebuffer({ - context : context, - colorTextures :colorTextures, - depthTexture : new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.DEPTH_COMPONENT, - pixelDatatype : PixelDatatype.UNSIGNED_SHORT - }) - }); - } else { - fbo = this._fbo = new Framebuffer({ - context : context, - colorTextures : colorTextures, - depthRenderbuffer : new Renderbuffer({ - context : context, - format : RenderbufferFormat.DEPTH_COMPONENT16 - }) - }); - } + if (isPointLight) { + fsSource += 'uniform samplerCube shadowMap_textureCube; \n'; + } else { + fsSource += 'uniform sampler2D shadowMap_texture; \n'; + } - this._downSampleFBO1 = new Framebuffer({ - context : context, - colorTextures : [new Texture({ - context : context, - width : downSampleSize, - height : downSampleSize - })] - }); - this._downSampleFBO2 = new Framebuffer({ - context : context, - colorTextures : [new Texture({ - context : context, - width : downSampleSize, - height : downSampleSize - })] - }); + fsSource += + 'uniform mat4 shadowMap_matrix; \n' + + 'uniform vec3 shadowMap_lightDirectionEC; \n' + + 'uniform vec4 shadowMap_lightPositionEC; \n' + + 'uniform vec4 shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness; \n' + + 'uniform vec4 shadowMap_texelSizeDepthBiasAndNormalShadingSmooth; \n' + + 'vec4 getPositionEC() \n' + + '{ \n' + + (hasPositionVarying ? + ' return vec4(' + positionVaryingName + ', 1.0); \n' : + ' return czm_windowToEyeCoordinates(gl_FragCoord); \n') + + '} \n' + + 'vec3 getNormalEC() \n' + + '{ \n' + + (hasNormalVarying ? + ' return normalize(' + normalVaryingName + '); \n' : + ' return vec3(1.0); \n') + + '} \n' + - this._clearFBO1Command.framebuffer = this._downSampleFBO1; - this._clearFBO2Command.framebuffer = this._downSampleFBO2; - this._downSampleCommand.framebuffer = this._downSampleFBO1; - this._brightPassCommand.framebuffer = this._downSampleFBO2; - this._blurXCommand.framebuffer = this._downSampleFBO1; - this._blurYCommand.framebuffer = this._downSampleFBO2; + // Offset the shadow position in the direction of the normal for perpendicular and back faces + 'void applyNormalOffset(inout vec4 positionEC, vec3 normalEC, float nDotL) \n' + + '{ \n' + + (bias.normalOffset && hasNormalVarying ? + ' float normalOffset = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.x; \n' + + ' float normalOffsetScale = 1.0 - nDotL; \n' + + ' vec3 offset = normalOffset * normalOffsetScale * normalEC; \n' + + ' positionEC.xyz += offset; \n' : '') + + '} \n'; - var downSampleRenderState = RenderState.fromCache({ - viewport : downSampleViewport - }); + fsSource += + 'void main() \n' + + '{ \n' + + ' czm_shadow_receive_main(); \n' + + ' vec4 positionEC = getPositionEC(); \n' + + ' vec3 normalEC = getNormalEC(); \n' + + ' float depth = -positionEC.z; \n'; - this._downSampleCommand.uniformMap.u_texture = function() { - return fbo.getColorTexture(0); - }; - this._downSampleCommand.renderState = downSampleRenderState; + fsSource += + ' czm_shadowParameters shadowParameters; \n' + + ' shadowParameters.texelStepSize = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.xy; \n' + + ' shadowParameters.depthBias = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.z; \n' + + ' shadowParameters.normalShadingSmooth = shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.w; \n' + + ' shadowParameters.darkness = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.w; \n'; - this._brightPassCommand.uniformMap.u_texture = function() { - return that._downSampleFBO1.getColorTexture(0); - }; - this._brightPassCommand.renderState = downSampleRenderState; + if (isTerrain) { + // Scale depth bias based on view distance to reduce z-fighting in distant terrain + fsSource += ' shadowParameters.depthBias *= max(depth * 0.01, 1.0); \n'; + } else if (!polygonOffsetSupported) { + // If polygon offset isn't supported push the depth back based on view, however this + // causes light leaking at further away views + fsSource += ' shadowParameters.depthBias *= mix(1.0, 100.0, depth * 0.0015); \n'; + } - this._blurXCommand.uniformMap.u_texture = function() { - return that._downSampleFBO2.getColorTexture(0); - }; - this._blurXCommand.uniformMap.u_step = function() { - return that._blurStep; - }; - this._blurXCommand.renderState = downSampleRenderState; + if (isPointLight) { + fsSource += + ' vec3 directionEC = positionEC.xyz - shadowMap_lightPositionEC.xyz; \n' + + ' float distance = length(directionEC); \n' + + ' directionEC = normalize(directionEC); \n' + + ' float radius = shadowMap_lightPositionEC.w; \n' + + ' // Stop early if the fragment is beyond the point light radius \n' + + ' if (distance > radius) \n' + + ' { \n' + + ' return; \n' + + ' } \n' + + ' vec3 directionWC = czm_inverseViewRotation * directionEC; \n' + - this._blurYCommand.uniformMap.u_texture = function() { - return that._downSampleFBO1.getColorTexture(0); - }; - this._blurYCommand.uniformMap.u_step = function() { - return that._blurStep; - }; - this._blurYCommand.renderState = downSampleRenderState; + ' shadowParameters.depth = distance / radius; \n' + + ' shadowParameters.nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n' + - var upSampledViewport = viewportBoundingRectangle; - upSampledViewport.width = width; - upSampledViewport.height = height; + ' shadowParameters.texCoords = directionWC; \n' + + ' float visibility = czm_shadowVisibility(shadowMap_textureCube, shadowParameters); \n'; + } else if (isSpotLight) { + fsSource += + ' vec3 directionEC = normalize(positionEC.xyz - shadowMap_lightPositionEC.xyz); \n' + + ' float nDotL = clamp(dot(normalEC, -directionEC), 0.0, 1.0); \n' + + ' applyNormalOffset(positionEC, normalEC, nDotL); \n' + - var upSampleRenderState = RenderState.fromCache({ viewport : upSampledViewport }); + ' vec4 shadowPosition = shadowMap_matrix * positionEC; \n' + + ' // Spot light uses a perspective projection, so perform the perspective divide \n' + + ' shadowPosition /= shadowPosition.w; \n' + - this._blendCommand.uniformMap.u_texture0 = function() { - return fbo.getColorTexture(0); - }; - this._blendCommand.uniformMap.u_texture1 = function() { - return that._downSampleFBO2.getColorTexture(0); - }; - this._blendCommand.renderState = upSampleRenderState; + ' // Stop early if the fragment is not in the shadow bounds \n' + + ' if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n' + + ' { \n' + + ' return; \n' + + ' } \n' + - this._fullScreenCommand.uniformMap.u_texture = function() { - return fbo.getColorTexture(0); - }; - this._fullScreenCommand.renderState = upSampleRenderState; - } + ' shadowParameters.texCoords = shadowPosition.xy; \n' + + ' shadowParameters.depth = shadowPosition.z; \n' + + ' shadowParameters.nDotL = nDotL; \n' + - var us = context.uniformState; - var sunPosition = us.sunPositionWC; - var viewMatrix = us.view; - var viewProjectionMatrix = us.viewProjection; - var projectionMatrix = us.projection; + ' float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n'; + } else if (hasCascades) { + fsSource += + ' float maxDepth = shadowMap_cascadeSplits[1].w; \n' + - // create up sampled render state - var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, postProcessMatrix4Scratch); - var sunPositionEC = Matrix4.multiplyByPoint(viewMatrix, sunPosition, sunPositionECScratch); - var sunPositionWC = Transforms.pointToGLWindowCoordinates(viewProjectionMatrix, viewportTransformation, sunPosition, sunPositionWCScratch); + ' // Stop early if the eye depth exceeds the last cascade \n' + + ' if (depth > maxDepth) \n' + + ' { \n' + + ' return; \n' + + ' } \n' + - sunPositionEC.x += CesiumMath.SOLAR_RADIUS; - var limbWC = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, sunPositionEC, sunPositionEC); - var sunSize = Cartesian2.magnitude(Cartesian2.subtract(limbWC, sunPositionWC, limbWC)) * 30.0 * 2.0; + ' // Get the cascade based on the eye-space depth \n' + + ' vec4 weights = czm_cascadeWeights(depth); \n' + - var size = sizeScratch; - size.x = sunSize; - size.y = sunSize; + ' // Apply normal offset \n' + + ' float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n' + + ' applyNormalOffset(positionEC, normalEC, nDotL); \n' + - var scissorRectangle = this._upSamplePassState.scissorTest.rectangle; - scissorRectangle.x = Math.max(sunPositionWC.x - size.x * 0.5, 0.0); - scissorRectangle.y = Math.max(sunPositionWC.y - size.y * 0.5, 0.0); - scissorRectangle.width = Math.min(size.x, width); - scissorRectangle.height = Math.min(size.y, height); + ' // Transform position into the cascade \n' + + ' vec4 shadowPosition = czm_cascadeMatrix(weights) * positionEC; \n' + - this._uCenter = Cartesian2.clone(sunPositionWC, this._uCenter); - this._uRadius = Math.max(size.x, size.y) * 0.15; + ' // Get visibility \n' + + ' shadowParameters.texCoords = shadowPosition.xy; \n' + + ' shadowParameters.depth = shadowPosition.z; \n' + + ' shadowParameters.nDotL = nDotL; \n' + + ' float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n' + - // create down sampled render state - viewportTransformation = Matrix4.computeViewportTransformation(downSampleViewport, 0.0, 1.0, postProcessMatrix4Scratch); - sunPositionWC = Transforms.pointToGLWindowCoordinates(viewProjectionMatrix, viewportTransformation, sunPosition, sunPositionWCScratch); + ' // Fade out shadows that are far away \n' + + ' float shadowMapMaximumDistance = shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.z; \n' + + ' float fade = max((depth - shadowMapMaximumDistance * 0.8) / (shadowMapMaximumDistance * 0.2), 0.0); \n' + + ' visibility = mix(visibility, 1.0, fade); \n' + - size.x *= downSampleWidth / width; - size.y *= downSampleHeight / height; + (debugCascadeColors ? + ' // Draw cascade colors for debugging \n' + + ' gl_FragColor *= czm_cascadeColor(weights); \n' : ''); + } else { + fsSource += + ' float nDotL = clamp(dot(normalEC, shadowMap_lightDirectionEC), 0.0, 1.0); \n' + + ' applyNormalOffset(positionEC, normalEC, nDotL); \n' + + ' vec4 shadowPosition = shadowMap_matrix * positionEC; \n' + - scissorRectangle = this._downSamplePassState.scissorTest.rectangle; - scissorRectangle.x = Math.max(sunPositionWC.x - size.x * 0.5, 0.0); - scissorRectangle.y = Math.max(sunPositionWC.y - size.y * 0.5, 0.0); - scissorRectangle.width = Math.min(size.x, width); - scissorRectangle.height = Math.min(size.y, height); + ' // Stop early if the fragment is not in the shadow bounds \n' + + ' if (any(lessThan(shadowPosition.xyz, vec3(0.0))) || any(greaterThan(shadowPosition.xyz, vec3(1.0)))) \n' + + ' { \n' + + ' return; \n' + + ' } \n' + - this._downSamplePassState.context = context; - this._upSamplePassState.context = context; + ' shadowParameters.texCoords = shadowPosition.xy; \n' + + ' shadowParameters.depth = shadowPosition.z; \n' + + ' shadowParameters.nDotL = nDotL; \n' + + ' float visibility = czm_shadowVisibility(shadowMap_texture, shadowParameters); \n'; + } - return this._fbo; - }; + fsSource += + ' gl_FragColor.rgb *= visibility; \n' + + '} \n'; - SunPostProcess.prototype.isDestroyed = function() { - return false; - }; + sources.push(fsSource); - SunPostProcess.prototype.destroy = function() { - this._fbo = this._fbo && this._fbo.destroy(); - this._downSampleFBO1 = this._downSampleFBO1 && this._downSampleFBO1.destroy(); - this._downSampleFBO2 = this._downSampleFBO2 && this._downSampleFBO2.destroy(); - this._downSampleCommand = this._downSampleCommand && this._downSampleCommand.shaderProgram && this._downSampleCommand.shaderProgram.destroy(); - this._brightPassCommand = this._brightPassCommand && this._brightPassCommand.shaderProgram && this._brightPassCommand.shaderProgram.destroy(); - this._blurXCommand = this._blurXCommand && this._blurXCommand.shaderProgram && this._blurXCommand.shaderProgram.destroy(); - this._blurYCommand = this._blurYCommand && this._blurYCommand.shaderProgram && this._blurYCommand.shaderProgram.destroy(); - this._blendCommand = this._blendCommand && this._blendCommand.shaderProgram && this._blendCommand.shaderProgram.destroy(); - this._fullScreenCommand = this._fullScreenCommand && this._fullScreenCommand.shaderProgram && this._fullScreenCommand.shaderProgram.destroy(); - return destroyObject(this); + return new ShaderSource({ + defines : defines, + sources : sources + }); }; - return SunPostProcess; + return ShadowMapShader; }); -define('Scene/Scene',[ +define('Scene/ShadowMap',[ '../Core/BoundingRectangle', '../Core/BoundingSphere', - '../Core/BoxGeometry', + '../Core/BoxOutlineGeometry', '../Core/Cartesian2', '../Core/Cartesian3', '../Core/Cartesian4', '../Core/Cartographic', + '../Core/clone', '../Core/Color', '../Core/ColorGeometryInstanceAttribute', - '../Core/createGuid', + '../Core/combine', '../Core/CullingVolume', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/EllipsoidGeometry', - '../Core/Event', - '../Core/GeographicProjection', + '../Core/FeatureDetection', '../Core/GeometryInstance', - '../Core/GeometryPipeline', - '../Core/getTimestamp', '../Core/Intersect', - '../Core/Interval', - '../Core/JulianDate', '../Core/Math', '../Core/Matrix4', - '../Core/mergeSort', - '../Core/Occluder', - '../Core/OrthographicFrustum', '../Core/OrthographicOffCenterFrustum', '../Core/PerspectiveFrustum', - '../Core/PerspectiveOffCenterFrustum', '../Core/PixelFormat', - '../Core/RequestScheduler', - '../Core/ShowGeometryInstanceAttribute', - '../Core/Transforms', + '../Core/Quaternion', + '../Core/SphereOutlineGeometry', + '../Core/WebGLConstants', '../Renderer/ClearCommand', - '../Renderer/ComputeEngine', - '../Renderer/Context', '../Renderer/ContextLimits', + '../Renderer/CubeMap', '../Renderer/DrawCommand', '../Renderer/Framebuffer', '../Renderer/Pass', '../Renderer/PassState', '../Renderer/PixelDatatype', + '../Renderer/Renderbuffer', + '../Renderer/RenderbufferFormat', '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', + '../Renderer/Sampler', '../Renderer/Texture', - './BrdfLutGenerator', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', './Camera', - './CreditDisplay', + './CullFace', './DebugCameraPrimitive', - './DepthPlane', - './DeviceOrientationCameraController', - './Fog', - './FrameState', - './FrustumCommands', - './FXAA', - './GlobeDepth', - './InvertClassification', - './JobScheduler', - './MapMode2D', - './OIT', - './PerformanceDisplay', './PerInstanceColorAppearance', - './PickDepth', './Primitive', - './PrimitiveCollection', - './SceneMode', - './SceneTransforms', - './SceneTransitioner', - './ScreenSpaceCameraController', - './ShadowMap', - './SunPostProcess', - './TweenCollection' + './ShadowMapShader' ], function( BoundingRectangle, BoundingSphere, - BoxGeometry, + BoxOutlineGeometry, Cartesian2, Cartesian3, Cartesian4, Cartographic, + clone, Color, ColorGeometryInstanceAttribute, - createGuid, + combine, CullingVolume, defaultValue, defined, defineProperties, destroyObject, DeveloperError, - EllipsoidGeometry, - Event, - GeographicProjection, + FeatureDetection, GeometryInstance, - GeometryPipeline, - getTimestamp, Intersect, - Interval, - JulianDate, CesiumMath, Matrix4, - mergeSort, - Occluder, - OrthographicFrustum, OrthographicOffCenterFrustum, PerspectiveFrustum, - PerspectiveOffCenterFrustum, PixelFormat, - RequestScheduler, - ShowGeometryInstanceAttribute, - Transforms, + Quaternion, + SphereOutlineGeometry, + WebGLConstants, ClearCommand, - ComputeEngine, - Context, ContextLimits, + CubeMap, DrawCommand, Framebuffer, Pass, PassState, PixelDatatype, + Renderbuffer, + RenderbufferFormat, RenderState, - ShaderProgram, - ShaderSource, + Sampler, Texture, - BrdfLutGenerator, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap, Camera, - CreditDisplay, + CullFace, DebugCameraPrimitive, - DepthPlane, - DeviceOrientationCameraController, - Fog, - FrameState, - FrustumCommands, - FXAA, - GlobeDepth, - InvertClassification, - JobScheduler, - MapMode2D, - OIT, - PerformanceDisplay, PerInstanceColorAppearance, - PickDepth, Primitive, - PrimitiveCollection, - SceneMode, - SceneTransforms, - SceneTransitioner, - ScreenSpaceCameraController, - ShadowMap, - SunPostProcess, - TweenCollection) { + ShadowMapShader) { 'use strict'; /** - * The container for all 3D graphical objects and state in a Cesium virtual scene. Generally, - * a scene is not created directly; instead, it is implicitly created by {@link CesiumWidget}. - * <p> - * <em><code>contextOptions</code> parameter details:</em> - * </p> - * <p> - * The default values are: - * <code> - * { - * webgl : { - * alpha : false, - * depth : true, - * stencil : false, - * antialias : true, - * premultipliedAlpha : true, - * preserveDrawingBuffer : false, - * failIfMajorPerformanceCaveat : false - * }, - * allowTextureFilterAnisotropic : true - * } - * </code> - * </p> - * <p> - * The <code>webgl</code> property corresponds to the {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} - * object used to create the WebGL context. - * </p> - * <p> - * <code>webgl.alpha</code> defaults to false, which can improve performance compared to the standard WebGL default - * of true. If an application needs to composite Cesium above other HTML elements using alpha-blending, set - * <code>webgl.alpha</code> to true. - * </p> - * <p> - * The other <code>webgl</code> properties match the WebGL defaults for {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes}. - * </p> + * Use {@link Viewer#shadowMap} to get the scene's shadow map originating from the sun. Do not construct this directly. + * * <p> - * <code>allowTextureFilterAnisotropic</code> defaults to true, which enables anisotropic texture filtering when the - * WebGL extension is supported. Setting this to false will improve performance, but hurt visual quality, especially for horizon views. + * The normalOffset bias pushes the shadows forward slightly, and may be disabled + * for applications that require ultra precise shadows. * </p> * - * @alias Scene - * @constructor - * - * @param {Object} [options] Object with the following properties: - * @param {Canvas} options.canvas The HTML canvas element to create the scene for. - * @param {Object} [options.contextOptions] Context and WebGL creation properties. See details above. - * @param {Element} [options.creditContainer] The HTML element in which the credits will be displayed. - * @param {Element} [options.creditViewport] The HTML element in which to display the credit popup. If not specified, the viewport will be a added as a sibling of the canvas. - * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes. - * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. - * @param {Boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View. - * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. - * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. - * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @alias ShadowMap + * @internalConstructor * - * @see CesiumWidget - * @see {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} + * @param {Object} options An object containing the following properties: + * @param {Camera} options.lightCamera A camera representing the light source. + * @param {Boolean} [options.enabled=true] Whether the shadow map is enabled. + * @param {Boolean} [options.isPointLight=false] Whether the light source is a point light. Point light shadows do not use cascades. + * @param {Boolean} [options.pointLightRadius=100.0] Radius of the point light. + * @param {Boolean} [options.cascadesEnabled=true] Use multiple shadow maps to cover different partitions of the view frustum. + * @param {Number} [options.numberOfCascades=4] The number of cascades to use for the shadow map. Supported values are one and four. + * @param {Number} [options.maximumDistance=5000.0] The maximum distance used for generating cascaded shadows. Lower values improve shadow quality. + * @param {Number} [options.size=2048] The width and height, in pixels, of each shadow map. + * @param {Boolean} [options.softShadows=false] Whether percentage-closer-filtering is enabled for producing softer shadows. + * @param {Number} [options.darkness=0.3] The shadow darkness. + * @param {Boolean} [options.normalOffset=true] Whether a normal bias is applied to shadows. * - * @exception {DeveloperError} options and options.canvas are required. + * @exception {DeveloperError} Only one or four cascades are supported. * - * @example - * // Create scene without anisotropic texture filtering - * var scene = new Cesium.Scene({ - * canvas : canvas, - * contextOptions : { - * allowTextureFilterAnisotropic : false - * } - * }); + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Shadows.html|Cesium Sandcastle Shadows Demo} */ - function Scene(options) { + function ShadowMap(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var canvas = options.canvas; - var contextOptions = options.contextOptions; - var creditContainer = options.creditContainer; - var creditViewport = options.creditViewport; + // options.context is an undocumented option + var context = options.context; - if (!defined(canvas)) { - throw new DeveloperError('options and options.canvas are required.'); + if (!defined(context)) { + throw new DeveloperError('context is required.'); } - var hasCreditContainer = defined(creditContainer); - var context = new Context(canvas, contextOptions); - if (!hasCreditContainer) { - creditContainer = document.createElement('div'); - creditContainer.style.position = 'absolute'; - creditContainer.style.bottom = '0'; - creditContainer.style['text-shadow'] = '0 0 2px #000000'; - creditContainer.style.color = '#ffffff'; - creditContainer.style['font-size'] = '10px'; - creditContainer.style['padding-right'] = '5px'; - canvas.parentNode.appendChild(creditContainer); + if (!defined(options.lightCamera)) { + throw new DeveloperError('lightCamera is required.'); } - if (!defined(creditViewport)) { - creditViewport = canvas.parentNode; + if (defined(options.numberOfCascades) && ((options.numberOfCascades !== 1) && (options.numberOfCascades !== 4))) { + throw new DeveloperError('Only one or four cascades are supported.'); } + + this._enabled = defaultValue(options.enabled, true); + this._softShadows = defaultValue(options.softShadows, false); + this._normalOffset = defaultValue(options.normalOffset, true); + this.dirty = true; - this._id = createGuid(); - this._jobScheduler = new JobScheduler(); - this._frameState = new FrameState(context, new CreditDisplay(creditContainer, ' • ', creditViewport), this._jobScheduler); - this._frameState.scene3DOnly = defaultValue(options.scene3DOnly, false); - this._removeCreditContainer = !hasCreditContainer; - this._creditContainer = creditContainer; + /** + * Specifies whether the shadow map originates from a light source. Shadow maps that are used for analytical + * purposes should set this to false so as not to affect scene rendering. + * + * @private + */ + this.fromLightSource = defaultValue(options.fromLightSource, true); - var ps = new PassState(context); - ps.viewport = new BoundingRectangle(); - ps.viewport.x = 0; - ps.viewport.y = 0; - ps.viewport.width = context.drawingBufferWidth; - ps.viewport.height = context.drawingBufferHeight; - this._passState = ps; + /** + * Determines the darkness of the shadows. + * + * @type {Number} + * @default 0.3 + */ + this.darkness = defaultValue(options.darkness, 0.3); + this._darkness = this.darkness; - this._canvas = canvas; - this._context = context; - this._computeEngine = new ComputeEngine(context); - this._globe = undefined; - this._primitives = new PrimitiveCollection(); - this._groundPrimitives = new PrimitiveCollection(); + /** + * Determines the maximum distance of the shadow map. Only applicable for cascaded shadows. Larger distances may result in lower quality shadows. + * + * @type {Number} + * @default 5000.0 + */ + this.maximumDistance = defaultValue(options.maximumDistance, 5000.0); - this._tweens = new TweenCollection(); + this._outOfView = false; + this._outOfViewPrevious = false; + this._needsUpdate = true; - this._shaderFrameCount = 0; + // In IE11 and Edge polygon offset is not functional. + // TODO : Also disabled for instances of Firefox and Chrome running ANGLE that do not support depth textures. + // Re-enable once https://github.com/AnalyticalGraphicsInc/cesium/issues/4560 is resolved. + var polygonOffsetSupported = true; + if (FeatureDetection.isInternetExplorer() || FeatureDetection.isEdge() || ((FeatureDetection.isChrome() || FeatureDetection.isFirefox()) && FeatureDetection.isWindows() && !context.depthTexture)) { + polygonOffsetSupported = false; + } + this._polygonOffsetSupported = polygonOffsetSupported; - this._sunPostProcess = undefined; + this._terrainBias = { + polygonOffset : polygonOffsetSupported, + polygonOffsetFactor : 1.1, + polygonOffsetUnits : 4.0, + normalOffset : this._normalOffset, + normalOffsetScale : 0.5, + normalShading : true, + normalShadingSmooth : 0.3, + depthBias : 0.0001 + }; - this._computeCommandList = []; - this._frustumCommandsList = []; - this._overlayCommandList = []; + this._primitiveBias = { + polygonOffset : polygonOffsetSupported, + polygonOffsetFactor : 1.1, + polygonOffsetUnits : 4.0, + normalOffset : this._normalOffset, + normalOffsetScale : 0.1, + normalShading : true, + normalShadingSmooth : 0.05, + depthBias : 0.00002 + }; - this._pickFramebuffer = undefined; + this._pointBias = { + polygonOffset : false, + polygonOffsetFactor : 1.1, + polygonOffsetUnits : 4.0, + normalOffset : this._normalOffset, + normalOffsetScale : 0.0, + normalShading : true, + normalShadingSmooth : 0.1, + depthBias : 0.0005 + }; - this._useOIT = defaultValue(options.orderIndependentTranslucency, true); - this._executeOITFunction = undefined; + // Framebuffer resources + this._depthAttachment = undefined; + this._colorAttachment = undefined; - var globeDepth; - if (context.depthTexture) { - globeDepth = new GlobeDepth(); + // Uniforms + this._shadowMapMatrix = new Matrix4(); + this._shadowMapTexture = undefined; + this._lightDirectionEC = new Cartesian3(); + this._lightPositionEC = new Cartesian4(); + this._distance = 0.0; + + this._lightCamera = options.lightCamera; + this._shadowMapCamera = new ShadowMapCamera(); + this._shadowMapCullingVolume = undefined; + this._sceneCamera = undefined; + this._boundingSphere = new BoundingSphere(); + + this._isPointLight = defaultValue(options.isPointLight, false); + this._pointLightRadius = defaultValue(options.pointLightRadius, 100.0); + + this._cascadesEnabled = this._isPointLight ? false : defaultValue(options.cascadesEnabled, true); + this._numberOfCascades = !this._cascadesEnabled ? 0 : defaultValue(options.numberOfCascades, 4); + this._fitNearFar = true; + this._maximumCascadeDistances = [25.0, 150.0, 700.0, Number.MAX_VALUE]; + + this._textureSize = new Cartesian2(); + + this._isSpotLight = false; + if (this._cascadesEnabled) { + // Cascaded shadows are always orthographic. The frustum dimensions are calculated on the fly. + this._shadowMapCamera.frustum = new OrthographicOffCenterFrustum(); + } else if (defined(this._lightCamera.frustum.fov)) { + // If the light camera uses a perspective frustum, then the light source is a spot light + this._isSpotLight = true; } - var oit; - if (this._useOIT && defined(globeDepth)) { - oit = new OIT(context); + // Uniforms + this._cascadeSplits = [new Cartesian4(), new Cartesian4()]; + this._cascadeMatrices = [new Matrix4(), new Matrix4(), new Matrix4(), new Matrix4()]; + this._cascadeDistances = new Cartesian4(); + + var numberOfPasses; + if (this._isPointLight) { + numberOfPasses = 6; // One shadow map for each direction + } else if (!this._cascadesEnabled) { + numberOfPasses = 1; + } else { + numberOfPasses = this._numberOfCascades; } - this._globeDepth = globeDepth; - this._depthPlane = new DepthPlane(); - this._oit = oit; - this._fxaa = new FXAA(); + this._passes = new Array(numberOfPasses); + for (var i = 0; i < numberOfPasses; ++i) { + this._passes[i] = new ShadowPass(context); + } - this._clearColorCommand = new ClearCommand({ - color : new Color(), - stencil : 0, - owner : this - }); - this._depthClearCommand = new ClearCommand({ + this.debugShow = false; + this.debugFreezeFrame = false; + this._debugFreezeFrame = false; + this._debugCascadeColors = false; + this._debugLightFrustum = undefined; + this._debugCameraFrustum = undefined; + this._debugCascadeFrustums = new Array(this._numberOfCascades); + this._debugShadowViewCommand = undefined; + + this._usesDepthTexture = context.depthTexture; + + if (this._isPointLight) { + this._usesDepthTexture = false; + } + + // Create render states for shadow casters + this._primitiveRenderState = undefined; + this._terrainRenderState = undefined; + this._pointRenderState = undefined; + createRenderStates(this); + + // For clearing the shadow map texture every frame + this._clearCommand = new ClearCommand({ depth : 1.0, - owner : this - }); - this._stencilClearCommand = new ClearCommand({ - stencil : 0 + color : new Color() }); - this._pickDepths = []; - this._debugGlobeDepths = []; + this._clearPassState = new PassState(context); - this._pickDepthPassState = undefined; - this._pickDepthFramebuffer = undefined; - this._pickDepthFramebufferWidth = undefined; - this._pickDepthFramebufferHeight = undefined; - this._depthOnlyRenderStateCache = {}; + this._size = defaultValue(options.size, 2048); + this.size = this._size; + } - this._transitioner = new SceneTransitioner(this); + /** + * Global maximum shadow distance used to prevent far off receivers from extending + * the shadow far plane. This helps set a tighter near/far when viewing objects from space. + * + * @private + */ + ShadowMap.MAXIMUM_DISTANCE = 20000.0; - this._renderError = new Event(); - this._preRender = new Event(); - this._postRender = new Event(); + function ShadowPass(context) { + this.camera = new ShadowMapCamera(); + this.passState = new PassState(context); + this.framebuffer = undefined; + this.textureOffsets = undefined; + this.commandList = []; + this.cullingVolume = undefined; + } - this._cameraStartFired = false; - this._cameraMovedTime = undefined; + function createRenderState(colorMask, bias) { + return RenderState.fromCache({ + cull : { + enabled : true, + face : CullFace.BACK + }, + depthTest : { + enabled : true + }, + colorMask : { + red : colorMask, + green : colorMask, + blue : colorMask, + alpha : colorMask + }, + depthMask : true, + polygonOffset : { + enabled : bias.polygonOffset, + factor : bias.polygonOffsetFactor, + units : bias.polygonOffsetUnits + } + }); + } - this._pickPositionCache = {}; - this._pickPositionCacheDirty = false; + function createRenderStates(shadowMap) { + // Enable the color mask if the shadow map is backed by a color texture, e.g. when depth textures aren't supported + var colorMask = !shadowMap._usesDepthTexture; + shadowMap._primitiveRenderState = createRenderState(colorMask, shadowMap._primitiveBias); + shadowMap._terrainRenderState = createRenderState(colorMask, shadowMap._terrainBias); + shadowMap._pointRenderState = createRenderState(colorMask, shadowMap._pointBias); + } - this._minimumDisableDepthTestDistance = 0.0; + /** + * @private + */ + ShadowMap.prototype.debugCreateRenderStates = function() { + createRenderStates(this); + }; + defineProperties(ShadowMap.prototype, { /** - * Exceptions occurring in <code>render</code> are always caught in order to raise the - * <code>renderError</code> event. If this property is true, the error is rethrown - * after the event is raised. If this property is false, the <code>render</code> function - * returns normally after raising the event. + * Determines if the shadow map will be shown. * + * @memberof ShadowMap.prototype * @type {Boolean} - * @default false + * @default true */ - this.rethrowRenderErrors = false; + enabled : { + get : function() { + return this._enabled; + }, + set : function(value) { + this.dirty = this._enabled !== value; + this._enabled = value; + } + }, /** - * Determines whether or not to instantly complete the - * scene transition animation on user input. + * Determines if a normal bias will be applied to shadows. * + * @memberof ShadowMap.prototype * @type {Boolean} * @default true */ - this.completeMorphOnUserInput = true; + normalOffset : { + get : function() { + return this._normalOffset; + }, + set : function(value) { + this.dirty = this._normalOffset !== value; + this._normalOffset = value; + this._terrainBias.normalOffset = value; + this._primitiveBias.normalOffset = value; + this._pointBias.normalOffset = value; + } + }, /** - * The event fired at the beginning of a scene transition. - * @type {Event} - * @default Event() + * Determines if soft shadows are enabled. Uses pcf filtering which requires more texture reads and may hurt performance. + * + * @memberof ShadowMap.prototype + * @type {Boolean} + * @default false */ - this.morphStart = new Event(); + softShadows : { + get : function() { + return this._softShadows; + }, + set : function(value) { + this.dirty = this._softShadows !== value; + this._softShadows = value; + } + }, /** - * The event fired at the completion of a scene transition. - * @type {Event} - * @default Event() + * The width and height, in pixels, of each shadow map. + * + * @memberof ShadowMap.prototype + * @type {Number} + * @default 2048 */ - this.morphComplete = new Event(); + size : { + get : function() { + return this._size; + }, + set : function(value) { + resize(this, value); + } + }, /** - * The {@link SkyBox} used to draw the stars. - * - * @type {SkyBox} - * @default undefined + * Whether the shadow map is out of view of the scene camera. * - * @see Scene#backgroundColor + * @memberof ShadowMap.prototype + * @type {Boolean} + * @readonly + * @private */ - this.skyBox = undefined; + outOfView : { + get : function() { + return this._outOfView; + } + }, /** - * The sky atmosphere drawn around the globe. + * The culling volume of the shadow frustum. * - * @type {SkyAtmosphere} - * @default undefined + * @memberof ShadowMap.prototype + * @type {CullingVolume} + * @readonly + * @private */ - this.skyAtmosphere = undefined; + shadowMapCullingVolume : { + get : function() { + return this._shadowMapCullingVolume; + } + }, /** - * The {@link Sun}. + * The passes used for rendering shadows. Each face of a point light or each cascade for a cascaded shadow map is a separate pass. * - * @type {Sun} - * @default undefined + * @memberof ShadowMap.prototype + * @type {ShadowPass[]} + * @readonly + * @private */ - this.sun = undefined; + passes : { + get : function() { + return this._passes; + } + }, /** - * Uses a bloom filter on the sun when enabled. + * Whether the light source is a point light. * + * @memberof ShadowMap.prototype * @type {Boolean} - * @default true + * @readonly + * @private */ - this.sunBloom = true; - this._sunBloom = undefined; + isPointLight : { + get : function() { + return this._isPointLight; + } + }, /** - * The {@link Moon} + * Debug option for visualizing the cascades by color. * - * @type Moon - * @default undefined + * @memberof ShadowMap.prototype + * @type {Boolean} + * @default false + * @private */ - this.moon = undefined; + debugCascadeColors : { + get : function() { + return this._debugCascadeColors; + }, + set : function(value) { + this.dirty = this._debugCascadeColors !== value; + this._debugCascadeColors = value; + } + } + }); - /** - * The background color, which is only visible if there is no sky box, i.e., {@link Scene#skyBox} is undefined. - * - * @type {Color} - * @default {@link Color.BLACK} - * - * @see Scene#skyBox - */ - this.backgroundColor = Color.clone(Color.BLACK); + function destroyFramebuffer(shadowMap) { + var length = shadowMap._passes.length; + for (var i = 0; i < length; ++i) { + var pass = shadowMap._passes[i]; + var framebuffer = pass.framebuffer; + if (defined(framebuffer) && !framebuffer.isDestroyed()) { + framebuffer.destroy(); + } + pass.framebuffer = undefined; + } - this._mode = SceneMode.SCENE3D; + // Destroy the framebuffer attachments + shadowMap._depthAttachment = shadowMap._depthAttachment && shadowMap._depthAttachment.destroy(); + shadowMap._colorAttachment = shadowMap._colorAttachment && shadowMap._colorAttachment.destroy(); + } - this._mapProjection = defined(options.mapProjection) ? options.mapProjection : new GeographicProjection(); + function createSampler() { + return new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }); + } - /** - * The current morph transition time between 2D/Columbus View and 3D, - * with 0.0 being 2D or Columbus View and 1.0 being 3D. - * - * @type {Number} - * @default 1.0 - */ - this.morphTime = 1.0; - /** - * The far-to-near ratio of the multi-frustum. The default is 1,000.0. - * - * @type {Number} - * @default 1000.0 - */ - this.farToNearRatio = 1000.0; + function createFramebufferColor(shadowMap, context) { + var depthRenderbuffer = new Renderbuffer({ + context : context, + width : shadowMap._textureSize.x, + height : shadowMap._textureSize.y, + format : RenderbufferFormat.DEPTH_COMPONENT16 + }); - /** - * Determines the uniform depth size in meters of each frustum of the multifrustum in 2D. If a primitive or model close - * to the surface shows z-fighting, decreasing this will eliminate the artifact, but decrease performance. On the - * other hand, increasing this will increase performance but may cause z-fighting among primitives close to thesurface. - * @type {Number} - * @default 1.75e6 - */ - this.nearToFarDistance2D = 1.75e6; + var colorTexture = new Texture({ + context : context, + width : shadowMap._textureSize.x, + height : shadowMap._textureSize.y, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : createSampler() + }); - /** - * This property is for debugging only; it is not for production use. - * <p> - * A function that determines what commands are executed. As shown in the examples below, - * the function receives the command's <code>owner</code> as an argument, and returns a boolean indicating if the - * command should be executed. - * </p> - * <p> - * The default is <code>undefined</code>, indicating that all commands are executed. - * </p> - * - * @type Function - * - * @default undefined - * - * @example - * // Do not execute any commands. - * scene.debugCommandFilter = function(command) { - * return false; - * }; - * - * // Execute only the billboard's commands. That is, only draw the billboard. - * var billboards = new Cesium.BillboardCollection(); - * scene.debugCommandFilter = function(command) { - * return command.owner === billboards; - * }; - */ - this.debugCommandFilter = undefined; + var framebuffer = new Framebuffer({ + context : context, + depthRenderbuffer : depthRenderbuffer, + colorTextures : [colorTexture], + destroyAttachments : false + }); + + var length = shadowMap._passes.length; + for (var i = 0; i < length; ++i) { + var pass = shadowMap._passes[i]; + pass.framebuffer = framebuffer; + pass.passState.framebuffer = framebuffer; + } + + shadowMap._shadowMapTexture = colorTexture; + shadowMap._depthAttachment = depthRenderbuffer; + shadowMap._colorAttachment = colorTexture; + } + + function createFramebufferDepth(shadowMap, context) { + var depthStencilTexture = new Texture({ + context : context, + width : shadowMap._textureSize.x, + height : shadowMap._textureSize.y, + pixelFormat : PixelFormat.DEPTH_STENCIL, + pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8, + sampler : createSampler() + }); + + var framebuffer = new Framebuffer({ + context : context, + depthStencilTexture : depthStencilTexture, + destroyAttachments : false + }); + + var length = shadowMap._passes.length; + for (var i = 0; i < length; ++i) { + var pass = shadowMap._passes[i]; + pass.framebuffer = framebuffer; + pass.passState.framebuffer = framebuffer; + } + + shadowMap._shadowMapTexture = depthStencilTexture; + shadowMap._depthAttachment = depthStencilTexture; + } + + function createFramebufferCube(shadowMap, context) { + var depthRenderbuffer = new Renderbuffer({ + context : context, + width : shadowMap._textureSize.x, + height : shadowMap._textureSize.y, + format : RenderbufferFormat.DEPTH_COMPONENT16 + }); + + var cubeMap = new CubeMap({ + context : context, + width : shadowMap._textureSize.x, + height : shadowMap._textureSize.y, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : createSampler() + }); + + var faces = [cubeMap.negativeX, cubeMap.negativeY, cubeMap.negativeZ, cubeMap.positiveX, cubeMap.positiveY, cubeMap.positiveZ]; + + for (var i = 0; i < 6; ++i) { + var framebuffer = new Framebuffer({ + context : context, + depthRenderbuffer : depthRenderbuffer, + colorTextures : [faces[i]], + destroyAttachments : false + }); + var pass = shadowMap._passes[i]; + pass.framebuffer = framebuffer; + pass.passState.framebuffer = framebuffer; + } + + shadowMap._shadowMapTexture = cubeMap; + shadowMap._depthAttachment = depthRenderbuffer; + shadowMap._colorAttachment = cubeMap; + } + + function createFramebuffer(shadowMap, context) { + if (shadowMap._isPointLight) { + createFramebufferCube(shadowMap, context); + } else if (shadowMap._usesDepthTexture) { + createFramebufferDepth(shadowMap, context); + } else { + createFramebufferColor(shadowMap, context); + } + } + + function checkFramebuffer(shadowMap, context) { + // Attempt to make an FBO with only a depth texture. If it fails, fallback to a color texture. + if (shadowMap._usesDepthTexture && (shadowMap._passes[0].framebuffer.status !== WebGLConstants.FRAMEBUFFER_COMPLETE)) { + shadowMap._usesDepthTexture = false; + createRenderStates(shadowMap); + destroyFramebuffer(shadowMap); + createFramebuffer(shadowMap, context); + } + } + + function updateFramebuffer(shadowMap, context) { + if (!defined(shadowMap._passes[0].framebuffer) || (shadowMap._shadowMapTexture.width !== shadowMap._textureSize.x)) { + destroyFramebuffer(shadowMap); + createFramebuffer(shadowMap, context); + checkFramebuffer(shadowMap, context); + clearFramebuffer(shadowMap, context); + } + } + + function clearFramebuffer(shadowMap, context, shadowPass) { + shadowPass = defaultValue(shadowPass, 0); + if (shadowMap._isPointLight || (shadowPass === 0)) { + shadowMap._clearCommand.framebuffer = shadowMap._passes[shadowPass].framebuffer; + shadowMap._clearCommand.execute(context, shadowMap._clearPassState); + } + } + + function resize(shadowMap, size) { + shadowMap._size = size; + var passes = shadowMap._passes; + var numberOfPasses = passes.length; + var textureSize = shadowMap._textureSize; + + if (shadowMap._isPointLight) { + size = (ContextLimits.maximumCubeMapSize >= size) ? size : ContextLimits.maximumCubeMapSize; + textureSize.x = size; + textureSize.y = size; + var faceViewport = new BoundingRectangle(0, 0, size, size); + passes[0].passState.viewport = faceViewport; + passes[1].passState.viewport = faceViewport; + passes[2].passState.viewport = faceViewport; + passes[3].passState.viewport = faceViewport; + passes[4].passState.viewport = faceViewport; + passes[5].passState.viewport = faceViewport; + } else if (numberOfPasses === 1) { + // +----+ + // | 1 | + // +----+ + size = (ContextLimits.maximumTextureSize >= size) ? size : ContextLimits.maximumTextureSize; + textureSize.x = size; + textureSize.y = size; + passes[0].passState.viewport = new BoundingRectangle(0, 0, size, size); + } else if (numberOfPasses === 4) { + // +----+----+ + // | 3 | 4 | + // +----+----+ + // | 1 | 2 | + // +----+----+ + size = (ContextLimits.maximumTextureSize >= size * 2) ? size : ContextLimits.maximumTextureSize / 2; + textureSize.x = size * 2; + textureSize.y = size * 2; + passes[0].passState.viewport = new BoundingRectangle(0, 0, size, size); + passes[1].passState.viewport = new BoundingRectangle(size, 0, size, size); + passes[2].passState.viewport = new BoundingRectangle(0, size, size, size); + passes[3].passState.viewport = new BoundingRectangle(size, size, size, size); + } + + // Update clear pass state + shadowMap._clearPassState.viewport = new BoundingRectangle(0, 0, textureSize.x, textureSize.y); + + // Transforms shadow coordinates [0, 1] into the pass's region of the texture + for (var i = 0; i < numberOfPasses; ++i) { + var pass = passes[i]; + var viewport = pass.passState.viewport; + var biasX = viewport.x / textureSize.x; + var biasY = viewport.y / textureSize.y; + var scaleX = viewport.width / textureSize.x; + var scaleY = viewport.height / textureSize.y; + pass.textureOffsets = new Matrix4(scaleX, 0.0, 0.0, biasX, 0.0, scaleY, 0.0, biasY, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); + } + } + + var scratchViewport = new BoundingRectangle(); + + function createDebugShadowViewCommand(shadowMap, context) { + var fs; + if (shadowMap._isPointLight) { + fs = 'uniform samplerCube shadowMap_textureCube; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() \n' + + '{ \n' + + ' vec2 uv = v_textureCoordinates; \n' + + ' vec3 dir; \n' + + ' \n' + + ' if (uv.y < 0.5) \n' + + ' { \n' + + ' if (uv.x < 0.333) \n' + + ' { \n' + + ' dir.x = -1.0; \n' + + ' dir.y = uv.x * 6.0 - 1.0; \n' + + ' dir.z = uv.y * 4.0 - 1.0; \n' + + ' } \n' + + ' else if (uv.x < 0.666) \n' + + ' { \n' + + ' dir.y = -1.0; \n' + + ' dir.x = uv.x * 6.0 - 3.0; \n' + + ' dir.z = uv.y * 4.0 - 1.0; \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' dir.z = -1.0; \n' + + ' dir.x = uv.x * 6.0 - 5.0; \n' + + ' dir.y = uv.y * 4.0 - 1.0; \n' + + ' } \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' if (uv.x < 0.333) \n' + + ' { \n' + + ' dir.x = 1.0; \n' + + ' dir.y = uv.x * 6.0 - 1.0; \n' + + ' dir.z = uv.y * 4.0 - 3.0; \n' + + ' } \n' + + ' else if (uv.x < 0.666) \n' + + ' { \n' + + ' dir.y = 1.0; \n' + + ' dir.x = uv.x * 6.0 - 3.0; \n' + + ' dir.z = uv.y * 4.0 - 3.0; \n' + + ' } \n' + + ' else \n' + + ' { \n' + + ' dir.z = 1.0; \n' + + ' dir.x = uv.x * 6.0 - 5.0; \n' + + ' dir.y = uv.y * 4.0 - 3.0; \n' + + ' } \n' + + ' } \n' + + ' \n' + + ' float shadow = czm_unpackDepth(textureCube(shadowMap_textureCube, dir)); \n' + + ' gl_FragColor = vec4(vec3(shadow), 1.0); \n' + + '} \n'; + } else { + fs = 'uniform sampler2D shadowMap_texture; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() \n' + + '{ \n' + + + (shadowMap._usesDepthTexture ? + ' float shadow = texture2D(shadowMap_texture, v_textureCoordinates).r; \n' : + ' float shadow = czm_unpackDepth(texture2D(shadowMap_texture, v_textureCoordinates)); \n') + + + ' gl_FragColor = vec4(vec3(shadow), 1.0); \n' + + '} \n'; + } + + var drawCommand = context.createViewportQuadCommand(fs, { + uniformMap : { + shadowMap_texture : function() { + return shadowMap._shadowMapTexture; + }, + shadowMap_textureCube : function() { + return shadowMap._shadowMapTexture; + } + } + }); + drawCommand.pass = Pass.OVERLAY; + return drawCommand; + } + + function updateDebugShadowViewCommand(shadowMap, frameState) { + // Draws the shadow map on the bottom-right corner of the screen + var context = frameState.context; + var screenWidth = frameState.context.drawingBufferWidth; + var screenHeight = frameState.context.drawingBufferHeight; + var size = Math.min(screenWidth, screenHeight) * 0.3; + + var viewport = scratchViewport; + viewport.x = screenWidth - size; + viewport.y = 0; + viewport.width = size; + viewport.height = size; + + var debugCommand = shadowMap._debugShadowViewCommand; + if (!defined(debugCommand)) { + debugCommand = createDebugShadowViewCommand(shadowMap, context); + shadowMap._debugShadowViewCommand = debugCommand; + } + + // Get a new RenderState for the updated viewport size + if (!defined(debugCommand.renderState) || !BoundingRectangle.equals(debugCommand.renderState.viewport, viewport)) { + debugCommand.renderState = RenderState.fromCache({ + viewport : BoundingRectangle.clone(viewport) + }); + } + + frameState.commandList.push(shadowMap._debugShadowViewCommand); + } + + var frustumCornersNDC = new Array(8); + frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, -1.0, 1.0); + frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, -1.0, 1.0); + frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, -1.0, 1.0); + frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, -1.0, 1.0); + frustumCornersNDC[4] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[5] = new Cartesian4(1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[6] = new Cartesian4(1.0, 1.0, 1.0, 1.0); + frustumCornersNDC[7] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); + + var scratchMatrix = new Matrix4(); + var scratchFrustumCorners = new Array(8); + for (var i = 0; i < 8; ++i) { + scratchFrustumCorners[i] = new Cartesian4(); + } + + function createDebugPointLight(modelMatrix, color) { + var box = new GeometryInstance({ + geometry : new BoxOutlineGeometry({ + minimum : new Cartesian3(-0.5, -0.5, -0.5), + maximum : new Cartesian3(0.5, 0.5, 0.5) + }), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(color) + } + }); + + var sphere = new GeometryInstance({ + geometry : new SphereOutlineGeometry({ + radius : 0.5 + }), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(color) + } + }); + + return new Primitive({ + geometryInstances : [box, sphere], + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false, + modelMatrix : modelMatrix + }); + } - /** - * This property is for debugging only; it is not for production use. - * <p> - * When <code>true</code>, commands are randomly shaded. This is useful - * for performance analysis to see what parts of a scene or model are - * command-dense and could benefit from batching. - * </p> - * - * @type Boolean - * - * @default false - */ - this.debugShowCommands = false; + var debugOutlineColors = [Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA]; + var scratchScale = new Cartesian3(); - /** - * This property is for debugging only; it is not for production use. - * <p> - * When <code>true</code>, commands are shaded based on the frustums they - * overlap. Commands in the closest frustum are tinted red, commands in - * the next closest are green, and commands in the farthest frustum are - * blue. If a command overlaps more than one frustum, the color components - * are combined, e.g., a command overlapping the first two frustums is tinted - * yellow. - * </p> - * - * @type Boolean - * - * @default false - */ - this.debugShowFrustums = false; + function applyDebugSettings(shadowMap, frameState) { + updateDebugShadowViewCommand(shadowMap, frameState); - this._debugFrustumStatistics = undefined; + var enterFreezeFrame = shadowMap.debugFreezeFrame && !shadowMap._debugFreezeFrame; + shadowMap._debugFreezeFrame = shadowMap.debugFreezeFrame; - /** - * This property is for debugging only; it is not for production use. - * <p> - * Displays frames per second and time between frames. - * </p> - * - * @type Boolean - * - * @default false - */ - this.debugShowFramesPerSecond = false; + // Draw scene camera in freeze frame mode + if (shadowMap.debugFreezeFrame) { + if (enterFreezeFrame) { + // Recreate debug camera when entering freeze frame mode + shadowMap._debugCameraFrustum = shadowMap._debugCameraFrustum && shadowMap._debugCameraFrustum.destroy(); + shadowMap._debugCameraFrustum = new DebugCameraPrimitive({ + camera : shadowMap._sceneCamera, + color : Color.CYAN, + updateOnChange : false + }); + } + shadowMap._debugCameraFrustum.update(frameState); + } - /** - * This property is for debugging only; it is not for production use. - * <p> - * Displays depth information for the indicated frustum. - * </p> - * - * @type Boolean - * - * @default false - */ - this.debugShowGlobeDepth = false; + if (shadowMap._cascadesEnabled) { + // Draw cascades only in freeze frame mode + if (shadowMap.debugFreezeFrame) { + if (enterFreezeFrame) { + // Recreate debug frustum when entering freeze frame mode + shadowMap._debugLightFrustum = shadowMap._debugLightFrustum && shadowMap._debugLightFrustum.destroy(); + shadowMap._debugLightFrustum = new DebugCameraPrimitive({ + camera : shadowMap._shadowMapCamera, + color : Color.YELLOW, + updateOnChange : false + }); + } + shadowMap._debugLightFrustum.update(frameState); - /** - * This property is for debugging only; it is not for production use. - * <p> - * Indicates which frustum will have depth information displayed. - * </p> - * - * @type Number - * - * @default 1 - */ - this.debugShowDepthFrustum = 1; + for (var i = 0; i < shadowMap._numberOfCascades; ++i) { + if (enterFreezeFrame) { + // Recreate debug frustum when entering freeze frame mode + shadowMap._debugCascadeFrustums[i] = shadowMap._debugCascadeFrustums[i] && shadowMap._debugCascadeFrustums[i].destroy(); + shadowMap._debugCascadeFrustums[i] = new DebugCameraPrimitive({ + camera : shadowMap._passes[i].camera, + color : debugOutlineColors[i], + updateOnChange : false + }); + } + shadowMap._debugCascadeFrustums[i].update(frameState); + } + } + } else if (shadowMap._isPointLight) { + if (!defined(shadowMap._debugLightFrustum) || shadowMap._needsUpdate) { + var translation = shadowMap._shadowMapCamera.positionWC; + var rotation = Quaternion.IDENTITY; + var uniformScale = shadowMap._pointLightRadius * 2.0; + var scale = Cartesian3.fromElements(uniformScale, uniformScale, uniformScale, scratchScale); + var modelMatrix = Matrix4.fromTranslationQuaternionRotationScale(translation, rotation, scale, scratchMatrix); - /** - * This property is for debugging only; it is not for production use. - * <p> - * When <code>true</code>, draws outlines to show the boundaries of the camera frustums - * </p> - * - * @type Boolean - * - * @default false - */ - this.debugShowFrustumPlanes = false; - this._debugShowFrustumPlanes = false; - this._debugFrustumPlanes = undefined; + shadowMap._debugLightFrustum = shadowMap._debugLightFrustum && shadowMap._debugLightFrustum.destroy(); + shadowMap._debugLightFrustum = createDebugPointLight(modelMatrix, Color.YELLOW); + } + shadowMap._debugLightFrustum.update(frameState); + } else { + if (!defined(shadowMap._debugLightFrustum) || shadowMap._needsUpdate) { + shadowMap._debugLightFrustum = new DebugCameraPrimitive({ + camera : shadowMap._shadowMapCamera, + color : Color.YELLOW, + updateOnChange : false + }); + } + shadowMap._debugLightFrustum.update(frameState); + } + } - /** - * When <code>true</code>, enables Fast Approximate Anti-aliasing even when order independent translucency - * is unsupported. - * - * @type Boolean - * @default true - */ - this.fxaa = true; + function ShadowMapCamera() { + this.viewMatrix = new Matrix4(); + this.inverseViewMatrix = new Matrix4(); + this.frustum = undefined; + this.positionCartographic = new Cartographic(); + this.positionWC = new Cartesian3(); + this.directionWC = Cartesian3.clone(Cartesian3.UNIT_Z); + this.upWC = Cartesian3.clone(Cartesian3.UNIT_Y); + this.rightWC = Cartesian3.clone(Cartesian3.UNIT_X); + this.viewProjectionMatrix = new Matrix4(); + } - /** - * When <code>true</code>, enables picking using the depth buffer. - * - * @type Boolean - * @default true - */ - this.useDepthPicking = true; + ShadowMapCamera.prototype.clone = function(camera) { + Matrix4.clone(camera.viewMatrix, this.viewMatrix); + Matrix4.clone(camera.inverseViewMatrix, this.inverseViewMatrix); + this.frustum = camera.frustum.clone(this.frustum); + Cartographic.clone(camera.positionCartographic, this.positionCartographic); + Cartesian3.clone(camera.positionWC, this.positionWC); + Cartesian3.clone(camera.directionWC, this.directionWC); + Cartesian3.clone(camera.upWC, this.upWC); + Cartesian3.clone(camera.rightWC, this.rightWC); + }; - /** - * When <code>true</code>, enables picking translucent geometry using the depth buffer. - * {@link Scene#useDepthPicking} must also be true to enable picking the depth buffer. - * <p> - * There is a decrease in performance when enabled. There are extra draw calls to write depth for - * translucent geometry. - * </p> - * @type {Boolean} - * @default false - */ - this.pickTranslucentDepth = false; + // Converts from NDC space to texture space + var scaleBiasMatrix = new Matrix4(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); - /** - * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. - * @type {Number} - * @default 500.0 - * @private - */ - this.cameraEventWaitTime = 500.0; + ShadowMapCamera.prototype.getViewProjection = function() { + var view = this.viewMatrix; + var projection = this.frustum.projectionMatrix; + Matrix4.multiply(projection, view, this.viewProjectionMatrix); + Matrix4.multiply(scaleBiasMatrix, this.viewProjectionMatrix, this.viewProjectionMatrix); + return this.viewProjectionMatrix; + }; - /** - * Set to true to copy the depth texture after rendering the globe. Makes czm_globeDepthTexture valid. - * @type {Boolean} - * @default false - * @private - */ - this.copyGlobeDepth = false; + var scratchSplits = new Array(5); + var scratchFrustum = new PerspectiveFrustum(); + var scratchCascadeDistances = new Array(4); + var scratchMin = new Cartesian3(); + var scratchMax = new Cartesian3(); - /** - * Blends the atmosphere to geometry far from the camera for horizon views. Allows for additional - * performance improvements by rendering less geometry and dispatching less terrain requests. - * @type {Fog} - */ - this.fog = new Fog(); + function computeCascades(shadowMap, frameState) { + var shadowMapCamera = shadowMap._shadowMapCamera; + var sceneCamera = shadowMap._sceneCamera; + var cameraNear = sceneCamera.frustum.near; + var cameraFar = sceneCamera.frustum.far; + var numberOfCascades = shadowMap._numberOfCascades; - this._sunCamera = new Camera(this); + // Split cascades. Use a mix of linear and log splits. + var i; + var range = cameraFar - cameraNear; + var ratio = cameraFar / cameraNear; - /** - * The shadow map in the scene. When enabled, models, primitives, and the globe may cast and receive shadows. - * By default the light source of the shadow map is the sun. - * @type {ShadowMap} - */ - this.shadowMap = new ShadowMap({ - context : context, - lightCamera : this._sunCamera, - enabled : defaultValue(options.shadows, false) - }); + var lambda = 0.9; + var clampCascadeDistances = false; - /** - * When <code>false</code>, 3D Tiles will render normally. When <code>true</code>, classified 3D Tile geometry will render normally and - * unclassified 3D Tile geometry will render with the color multiplied by {@link Scene#invertClassificationColor}. - * @type {Boolean} - * @default false - */ - this.invertClassification = false; + // When the camera is close to a relatively small model, provide more detail in the closer cascades. + // If the camera is near or inside a large model, such as the root tile of a city, then use the default values. + // To get the most accurate cascade splits we would need to find the min and max values from the depth texture. + if (frameState.shadowHints.closestObjectSize < 200.0) { + clampCascadeDistances = true; + lambda = 0.9; + } - /** - * The highlight color of unclassified 3D Tile geometry when {@link Scene#invertClassification} is <code>true</code>. - * <p>When the color's alpha is less than 1.0, the unclassified portions of the 3D Tiles will not blend correctly with the classified positions of the 3D Tiles.</p> - * <p>Also, when the color's alpha is less than 1.0, the WEBGL_depth_texture and EXT_frag_depth WebGL extensions must be supported.</p> - * @type {Color} - * @default Color.WHITE - */ - this.invertClassificationColor = Color.clone(Color.WHITE); + var cascadeDistances = scratchCascadeDistances; + var splits = scratchSplits; + splits[0] = cameraNear; + splits[numberOfCascades] = cameraFar; - this._actualInvertClassificationColor = Color.clone(this._invertClassificationColor); - this._invertClassification = new InvertClassification(); + // Find initial splits + for (i = 0; i < numberOfCascades; ++i) { + var p = (i + 1) / numberOfCascades; + var logScale = cameraNear * Math.pow(ratio, p); + var uniformScale = cameraNear + range * p; + var split = CesiumMath.lerp(uniformScale, logScale, lambda); + splits[i + 1] = split; + cascadeDistances[i] = split - splits[i]; + } - /** - * The focal length for use when with cardboard or WebVR. - * @type {Number} - */ - this.focalLength = undefined; + if (clampCascadeDistances) { + // Clamp each cascade to its maximum distance + for (i = 0; i < numberOfCascades; ++i) { + cascadeDistances[i] = Math.min(cascadeDistances[i], shadowMap._maximumCascadeDistances[i]); + } - /** - * The eye separation distance in meters for use with cardboard or WebVR. - * @type {Number} - */ - this.eyeSeparation = undefined; + // Recompute splits + var distance = splits[0]; + for (i = 0; i < numberOfCascades - 1; ++i) { + distance += cascadeDistances[i]; + splits[i + 1] = distance; + } + } - this._brdfLutGenerator = new BrdfLutGenerator(); + Cartesian4.unpack(splits, 0, shadowMap._cascadeSplits[0]); + Cartesian4.unpack(splits, 1, shadowMap._cascadeSplits[1]); + Cartesian4.unpack(cascadeDistances, 0, shadowMap._cascadeDistances); - this._terrainExaggeration = defaultValue(options.terrainExaggeration, 1.0); + var shadowFrustum = shadowMapCamera.frustum; + var left = shadowFrustum.left; + var right = shadowFrustum.right; + var bottom = shadowFrustum.bottom; + var top = shadowFrustum.top; + var near = shadowFrustum.near; + var far = shadowFrustum.far; - this._performanceDisplay = undefined; - this._debugVolume = undefined; + var position = shadowMapCamera.positionWC; + var direction = shadowMapCamera.directionWC; + var up = shadowMapCamera.upWC; - var camera = new Camera(this); - this._camera = camera; - this._cameraClone = Camera.clone(camera); - this._screenSpaceCameraController = new ScreenSpaceCameraController(this); - this._mapMode2D = defaultValue(options.mapMode2D, MapMode2D.INFINITE_SCROLL); + var cascadeSubFrustum = sceneCamera.frustum.clone(scratchFrustum); + var shadowViewProjection = shadowMapCamera.getViewProjection(); - // Keeps track of the state of a frame. FrameState is the state across - // the primitives of the scene. This state is for internally keeping track - // of celestial and environment effects that need to be updated/rendered in - // a certain order as well as updating/tracking framebuffer usage. - this._environmentState = { - skyBoxCommand : undefined, - skyAtmosphereCommand : undefined, - sunDrawCommand : undefined, - sunComputeCommand : undefined, - moonCommand : undefined, + for (i = 0; i < numberOfCascades; ++i) { + // Find the bounding box of the camera sub-frustum in shadow map texture space + cascadeSubFrustum.near = splits[i]; + cascadeSubFrustum.far = splits[i + 1]; + var viewProjection = Matrix4.multiply(cascadeSubFrustum.projectionMatrix, sceneCamera.viewMatrix, scratchMatrix); + var inverseViewProjection = Matrix4.inverse(viewProjection, scratchMatrix); + var shadowMapMatrix = Matrix4.multiply(shadowViewProjection, inverseViewProjection, scratchMatrix); - isSunVisible : false, - isMoonVisible : false, - isReadyForAtmosphere : false, - isSkyAtmosphereVisible : false, + // Project each corner from camera NDC space to shadow map texture space. Min and max will be from 0 to 1. + var min = Cartesian3.fromElements(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, scratchMin); + var max = Cartesian3.fromElements(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, scratchMax); - clearGlobeDepth : false, - useDepthPlane : false, + for (var k = 0; k < 8; ++k) { + var corner = Cartesian4.clone(frustumCornersNDC[k], scratchFrustumCorners[k]); + Matrix4.multiplyByVector(shadowMapMatrix, corner, corner); + Cartesian3.divideByScalar(corner, corner.w, corner); // Handle the perspective divide + Cartesian3.minimumByComponent(corner, min, min); + Cartesian3.maximumByComponent(corner, max, max); + } - originalFramebuffer : undefined, - useGlobeDepthFramebuffer : false, - useOIT : false, - useFXAA : false, - useInvertClassification : false - }; + // Limit light-space coordinates to the [0, 1] range + min.x = Math.max(min.x, 0.0); + min.y = Math.max(min.y, 0.0); + min.z = 0.0; // Always start cascade frustum at the top of the light frustum to capture objects in the light's path + max.x = Math.min(max.x, 1.0); + max.y = Math.min(max.y, 1.0); + max.z = Math.min(max.z, 1.0); - this._useWebVR = false; - this._cameraVR = undefined; - this._aspectRatioVR = undefined; + var pass = shadowMap._passes[i]; + var cascadeCamera = pass.camera; + cascadeCamera.clone(shadowMapCamera); // PERFORMANCE_IDEA : could do a shallow clone for all properties except the frustum - // initial guess at frustums. - var near = camera.frustum.near; - var far = camera.frustum.far; - var numFrustums = Math.ceil(Math.log(far / near) / Math.log(this.farToNearRatio)); - updateFrustums(near, far, this.farToNearRatio, numFrustums, this._frustumCommandsList, false, undefined); + var frustum = cascadeCamera.frustum; + frustum.left = left + min.x * (right - left); + frustum.right = left + max.x * (right - left); + frustum.bottom = bottom + min.y * (top - bottom); + frustum.top = bottom + max.y * (top - bottom); + frustum.near = near + min.z * (far - near); + frustum.far = near + max.z * (far - near); - // give frameState, camera, and screen space camera controller initial state before rendering - updateFrameState(this, 0.0, JulianDate.now()); - this.initializeFrame(); + pass.cullingVolume = cascadeCamera.frustum.computeCullingVolume(position, direction, up); + + // Transforms from eye space to the cascade's texture space + var cascadeMatrix = shadowMap._cascadeMatrices[i]; + Matrix4.multiply(cascadeCamera.getViewProjection(), sceneCamera.inverseViewMatrix, cascadeMatrix); + Matrix4.multiply(pass.textureOffsets, cascadeMatrix, cascadeMatrix); + } } - var OPAQUE_FRUSTUM_NEAR_OFFSET = 0.9999; + var scratchLightView = new Matrix4(); + var scratchRight = new Cartesian3(); + var scratchUp = new Cartesian3(); + var scratchTranslation = new Cartesian3(); - defineProperties(Scene.prototype, { - /** - * Gets the canvas element to which this scene is bound. - * @memberof Scene.prototype - * - * @type {Canvas} - * @readonly - */ - canvas : { - get : function() { - return this._canvas; - } - }, + function fitShadowMapToScene(shadowMap, frameState) { + var shadowMapCamera = shadowMap._shadowMapCamera; + var sceneCamera = shadowMap._sceneCamera; - /** - * The drawingBufferWidth of the underlying GL context. - * @memberof Scene.prototype - * - * @type {Number} - * @readonly - * - * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferWidth|drawingBufferWidth} - */ - drawingBufferHeight : { - get : function() { - return this._context.drawingBufferHeight; - } - }, + // 1. First find a tight bounding box in light space that contains the entire camera frustum. + var viewProjection = Matrix4.multiply(sceneCamera.frustum.projectionMatrix, sceneCamera.viewMatrix, scratchMatrix); + var inverseViewProjection = Matrix4.inverse(viewProjection, scratchMatrix); - /** - * The drawingBufferHeight of the underlying GL context. - * @memberof Scene.prototype - * - * @type {Number} - * @readonly - * - * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} - */ - drawingBufferWidth : { - get : function() { - return this._context.drawingBufferWidth; - } - }, + // Start to construct the light view matrix. Set translation later once the bounding box is found. + var lightDir = shadowMapCamera.directionWC; + var lightUp = sceneCamera.directionWC; // Align shadows to the camera view. + var lightRight = Cartesian3.cross(lightDir, lightUp, scratchRight); + lightUp = Cartesian3.cross(lightRight, lightDir, scratchUp); // Recalculate up now that right is derived + Cartesian3.normalize(lightUp, lightUp); + Cartesian3.normalize(lightRight, lightRight); + var lightPosition = Cartesian3.fromElements(0.0, 0.0, 0.0, scratchTranslation); - /** - * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. - * @memberof Scene.prototype - * - * @type {Number} - * @readonly - * - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. - */ - maximumAliasedLineWidth : { - get : function() { - return ContextLimits.maximumAliasedLineWidth; - } - }, + var lightView = Matrix4.computeView(lightPosition, lightDir, lightUp, lightRight, scratchLightView); + var cameraToLight = Matrix4.multiply(lightView, inverseViewProjection, scratchMatrix); - /** - * The maximum length in pixels of one edge of a cube map, supported by this WebGL implementation. It will be at least 16. - * @memberof Scene.prototype - * - * @type {Number} - * @readonly - * - * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>GL_MAX_CUBE_MAP_TEXTURE_SIZE</code>. - */ - maximumCubeMapSize : { - get : function() { - return ContextLimits.maximumCubeMapSize; - } - }, + // Project each corner from NDC space to light view space, and calculate a min and max in light view space + var min = Cartesian3.fromElements(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, scratchMin); + var max = Cartesian3.fromElements(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, scratchMax); - /** - * Returns true if the pickPosition function is supported. - * @memberof Scene.prototype - * - * @type {Boolean} - * @readonly - */ - pickPositionSupported : { - get : function() { - return this._context.depthTexture; - } - }, + for (var i = 0; i < 8; ++i) { + var corner = Cartesian4.clone(frustumCornersNDC[i], scratchFrustumCorners[i]); + Matrix4.multiplyByVector(cameraToLight, corner, corner); + Cartesian3.divideByScalar(corner, corner.w, corner); // Handle the perspective divide + Cartesian3.minimumByComponent(corner, min, min); + Cartesian3.maximumByComponent(corner, max, max); + } - /** - * Gets or sets the depth-test ellipsoid. - * @memberof Scene.prototype - * - * @type {Globe} - */ - globe : { - get: function() { - return this._globe; - }, + // 2. Set bounding box back to include objects in the light's view + max.z += 1000.0; // Note: in light space, a positive number is behind the camera + min.z -= 10.0; // Extend the shadow volume forward slightly to avoid problems right at the edge - set: function(globe) { - this._globe = this._globe && this._globe.destroy(); - this._globe = globe; - } - }, + // 3. Adjust light view matrix so that it is centered on the bounding volume + var translation = scratchTranslation; + translation.x = -(0.5 * (min.x + max.x)); + translation.y = -(0.5 * (min.y + max.y)); + translation.z = -max.z; - /** - * Gets the collection of primitives. - * @memberof Scene.prototype - * - * @type {PrimitiveCollection} - * @readonly - */ - primitives : { - get : function() { - return this._primitives; - } - }, + var translationMatrix = Matrix4.fromTranslation(translation, scratchMatrix); + lightView = Matrix4.multiply(translationMatrix, lightView, lightView); - /** - * Gets the collection of ground primitives. - * @memberof Scene.prototype - * - * @type {PrimitiveCollection} - * @readonly - */ - groundPrimitives : { - get : function() { - return this._groundPrimitives; - } - }, + // 4. Create an orthographic frustum that covers the bounding box extents + var halfWidth = 0.5 * (max.x - min.x); + var halfHeight = 0.5 * (max.y - min.y); + var depth = max.z - min.z; - /** - * Gets the camera. - * @memberof Scene.prototype - * - * @type {Camera} - * @readonly - */ - camera : { - get : function() { - return this._camera; - } - }, - // TODO: setCamera + var frustum = shadowMapCamera.frustum; + frustum.left = -halfWidth; + frustum.right = halfWidth; + frustum.bottom = -halfHeight; + frustum.top = halfHeight; + frustum.near = 0.01; + frustum.far = depth; - /** - * Gets the controller for camera input handling. - * @memberof Scene.prototype - * - * @type {ScreenSpaceCameraController} - * @readonly - */ - screenSpaceCameraController : { - get : function() { - return this._screenSpaceCameraController; - } - }, + // 5. Update the shadow map camera + Matrix4.clone(lightView, shadowMapCamera.viewMatrix); + Matrix4.inverse(lightView, shadowMapCamera.inverseViewMatrix); + Matrix4.getTranslation(shadowMapCamera.inverseViewMatrix, shadowMapCamera.positionWC); + frameState.mapProjection.ellipsoid.cartesianToCartographic(shadowMapCamera.positionWC, shadowMapCamera.positionCartographic); + Cartesian3.clone(lightDir, shadowMapCamera.directionWC); + Cartesian3.clone(lightUp, shadowMapCamera.upWC); + Cartesian3.clone(lightRight, shadowMapCamera.rightWC); + } - /** - * Get the map projection to use in 2D and Columbus View modes. - * @memberof Scene.prototype - * - * @type {MapProjection} - * @readonly - * - * @default new GeographicProjection() - */ - mapProjection : { - get: function() { - return this._mapProjection; - } - }, + var directions = [ + new Cartesian3(-1.0, 0.0, 0.0), + new Cartesian3(0.0, -1.0, 0.0), + new Cartesian3(0.0, 0.0, -1.0), + new Cartesian3(1.0, 0.0, 0.0), + new Cartesian3(0.0, 1.0, 0.0), + new Cartesian3(0.0, 0.0, 1.0) + ]; - /** - * Gets state information about the current scene. If called outside of a primitive's <code>update</code> - * function, the previous frame's state is returned. - * @memberof Scene.prototype - * - * @type {FrameState} - * @readonly - * - * @private - */ - frameState : { - get: function() { - return this._frameState; - } - }, + var ups = [ + new Cartesian3(0.0, -1.0, 0.0), + new Cartesian3(0.0, 0.0, -1.0), + new Cartesian3(0.0, -1.0, 0.0), + new Cartesian3(0.0, -1.0, 0.0), + new Cartesian3(0.0, 0.0, 1.0), + new Cartesian3(0.0, -1.0, 0.0) + ]; - /** - * Gets the collection of tweens taking place in the scene. - * @memberof Scene.prototype - * - * @type {TweenCollection} - * @readonly - * - * @private - */ - tweens : { - get : function() { - return this._tweens; - } - }, + var rights = [ + new Cartesian3(0.0, 0.0, 1.0), + new Cartesian3(1.0, 0.0, 0.0), + new Cartesian3(-1.0, 0.0, 0.0), + new Cartesian3(0.0, 0.0, -1.0), + new Cartesian3(1.0, 0.0, 0.0), + new Cartesian3(1.0, 0.0, 0.0) + ]; - /** - * Gets the collection of image layers that will be rendered on the globe. - * @memberof Scene.prototype - * - * @type {ImageryLayerCollection} - * @readonly - */ - imageryLayers : { - get : function() { - if (!defined(this.globe)) { - return undefined; - } + function computeOmnidirectional(shadowMap, frameState) { + // All sides share the same frustum + var frustum = new PerspectiveFrustum(); + frustum.fov = CesiumMath.PI_OVER_TWO; + frustum.near = 1.0; + frustum.far = shadowMap._pointLightRadius; + frustum.aspectRatio = 1.0; - return this.globe.imageryLayers; - } - }, + for (var i = 0; i < 6; ++i) { + var camera = shadowMap._passes[i].camera; + camera.positionWC = shadowMap._shadowMapCamera.positionWC; + camera.positionCartographic = frameState.mapProjection.ellipsoid.cartesianToCartographic(camera.positionWC, camera.positionCartographic); + camera.directionWC = directions[i]; + camera.upWC = ups[i]; + camera.rightWC = rights[i]; - /** - * The terrain provider providing surface geometry for the globe. - * @memberof Scene.prototype - * - * @type {TerrainProvider} - */ - terrainProvider : { - get : function() { - if (!defined(this.globe)) { - return undefined; - } + Matrix4.computeView(camera.positionWC, camera.directionWC, camera.upWC, camera.rightWC, camera.viewMatrix); + Matrix4.inverse(camera.viewMatrix, camera.inverseViewMatrix); - return this.globe.terrainProvider; - }, - set : function(terrainProvider) { - if (defined(this.globe)) { - this.globe.terrainProvider = terrainProvider; - } - } - }, + camera.frustum = frustum; + } + } - /** - * Gets an event that's raised when the terrain provider is changed - * @memberof Scene.prototype - * - * @type {Event} - * @readonly - */ - terrainProviderChanged : { - get : function() { - if (!defined(this.globe)) { - return undefined; - } + var scratchCartesian1 = new Cartesian3(); + var scratchCartesian2 = new Cartesian3(); + var scratchBoundingSphere = new BoundingSphere(); + var scratchCenter = scratchBoundingSphere.center; - return this.globe.terrainProviderChanged; - } - }, + function checkVisibility(shadowMap, frameState) { + var sceneCamera = shadowMap._sceneCamera; + var shadowMapCamera = shadowMap._shadowMapCamera; - /** - * Gets the event that will be raised when an error is thrown inside the <code>render</code> function. - * The Scene instance and the thrown error are the only two parameters passed to the event handler. - * By default, errors are not rethrown after this event is raised, but that can be changed by setting - * the <code>rethrowRenderErrors</code> property. - * @memberof Scene.prototype - * - * @type {Event} - * @readonly - */ - renderError : { - get : function() { - return this._renderError; - } - }, + var boundingSphere = scratchBoundingSphere; - /** - * Gets the event that will be raised at the start of each call to <code>render</code>. Subscribers to the event - * receive the Scene instance as the first parameter and the current time as the second parameter. - * @memberof Scene.prototype - * - * @type {Event} - * @readonly - */ - preRender : { - get : function() { - return this._preRender; + // Check whether the shadow map is in view and needs to be updated + if (shadowMap._cascadesEnabled) { + // If the nearest shadow receiver is further than the shadow map's maximum distance then the shadow map is out of view. + if (sceneCamera.frustum.near >= shadowMap.maximumDistance) { + shadowMap._outOfView = true; + shadowMap._needsUpdate = false; + return; } - }, - /** - * Gets the event that will be raised at the end of each call to <code>render</code>. Subscribers to the event - * receive the Scene instance as the first parameter and the current time as the second parameter. - * @memberof Scene.prototype - * - * @type {Event} - * @readonly - */ - postRender : { - get : function() { - return this._postRender; - } - }, + // If the light source is below the horizon then the shadow map is out of view + var surfaceNormal = frameState.mapProjection.ellipsoid.geodeticSurfaceNormal(sceneCamera.positionWC, scratchCartesian1); + var lightDirection = Cartesian3.negate(shadowMapCamera.directionWC, scratchCartesian2); + var dot = Cartesian3.dot(surfaceNormal, lightDirection); - /** - * @memberof Scene.prototype - * @private - * @readonly - */ - context : { - get : function() { - return this._context; - } - }, + // Shadows start to fade out once the light gets closer to the horizon. + // At this point the globe uses vertex lighting alone to darken the surface. + var darknessAmount = CesiumMath.clamp(dot / 0.1, 0.0, 1.0); + shadowMap._darkness = CesiumMath.lerp(1.0, shadowMap.darkness, darknessAmount); - /** - * This property is for debugging only; it is not for production use. - * <p> - * When {@link Scene.debugShowFrustums} is <code>true</code>, this contains - * properties with statistics about the number of command execute per frustum. - * <code>totalCommands</code> is the total number of commands executed, ignoring - * overlap. <code>commandsInFrustums</code> is an array with the number of times - * commands are executed redundantly, e.g., how many commands overlap two or - * three frustums. - * </p> - * - * @memberof Scene.prototype - * - * @type {Object} - * @readonly - * - * @default undefined - */ - debugFrustumStatistics : { - get : function() { - return this._debugFrustumStatistics; + if (dot < 0.0) { + shadowMap._outOfView = true; + shadowMap._needsUpdate = false; + return; } - }, - /** - * Gets whether or not the scene is optimized for 3D only viewing. - * @memberof Scene.prototype - * @type {Boolean} - * @readonly - */ - scene3DOnly : { - get : function() { - return this._frameState.scene3DOnly; - } - }, + // By default cascaded shadows need to update and are always in view + shadowMap._needsUpdate = true; + shadowMap._outOfView = false; + } else if (shadowMap._isPointLight) { + // Sphere-frustum intersection test + boundingSphere.center = shadowMapCamera.positionWC; + boundingSphere.radius = shadowMap._pointLightRadius; + shadowMap._outOfView = frameState.cullingVolume.computeVisibility(boundingSphere) === Intersect.OUTSIDE; + shadowMap._needsUpdate = !shadowMap._outOfView && !shadowMap._boundingSphere.equals(boundingSphere); + BoundingSphere.clone(boundingSphere, shadowMap._boundingSphere); + } else { + // Simplify frustum-frustum intersection test as a sphere-frustum test + var frustumRadius = shadowMapCamera.frustum.far / 2.0; + var frustumCenter = Cartesian3.add(shadowMapCamera.positionWC, Cartesian3.multiplyByScalar(shadowMapCamera.directionWC, frustumRadius, scratchCenter), scratchCenter); + boundingSphere.center = frustumCenter; + boundingSphere.radius = frustumRadius; + shadowMap._outOfView = frameState.cullingVolume.computeVisibility(boundingSphere) === Intersect.OUTSIDE; + shadowMap._needsUpdate = !shadowMap._outOfView && !shadowMap._boundingSphere.equals(boundingSphere); + BoundingSphere.clone(boundingSphere, shadowMap._boundingSphere); + } + } - /** - * Gets whether or not the scene has order independent translucency enabled. - * Note that this only reflects the original construction option, and there are - * other factors that could prevent OIT from functioning on a given system configuration. - * @memberof Scene.prototype - * @type {Boolean} - * @readonly - */ - orderIndependentTranslucency : { - get : function() { - return defined(this._oit); - } - }, + function updateCameras(shadowMap, frameState) { + var camera = frameState.camera; // The actual camera in the scene + var lightCamera = shadowMap._lightCamera; // The external camera representing the light source + var sceneCamera = shadowMap._sceneCamera; // Clone of camera, with clamped near and far planes + var shadowMapCamera = shadowMap._shadowMapCamera; // Camera representing the shadow volume, initially cloned from lightCamera - /** - * Gets the unique identifier for this scene. - * @memberof Scene.prototype - * @type {String} - * @readonly - */ - id : { - get : function() { - return this._id; - } - }, + // Clone light camera into the shadow map camera + if (shadowMap._cascadesEnabled) { + Cartesian3.clone(lightCamera.directionWC, shadowMapCamera.directionWC); + } else if (shadowMap._isPointLight) { + Cartesian3.clone(lightCamera.positionWC, shadowMapCamera.positionWC); + } else { + shadowMapCamera.clone(lightCamera); + } - /** - * Gets or sets the current mode of the scene. - * @memberof Scene.prototype - * @type {SceneMode} - * @default {@link SceneMode.SCENE3D} - */ - mode : { - get : function() { - return this._mode; - }, - set : function(value) { - if (this.scene3DOnly && value !== SceneMode.SCENE3D) { - throw new DeveloperError('Only SceneMode.SCENE3D is valid when scene3DOnly is true.'); - } - if (value === SceneMode.SCENE2D) { - this.morphTo2D(0); - } else if (value === SceneMode.SCENE3D) { - this.morphTo3D(0); - } else if (value === SceneMode.COLUMBUS_VIEW) { - this.morphToColumbusView(0); - } else { - throw new DeveloperError('value must be a valid SceneMode enumeration.'); - } - this._mode = value; - } - }, + // Get the light direction in eye coordinates + var lightDirection = shadowMap._lightDirectionEC; + Matrix4.multiplyByPointAsVector(camera.viewMatrix, shadowMapCamera.directionWC, lightDirection); + Cartesian3.normalize(lightDirection, lightDirection); + Cartesian3.negate(lightDirection, lightDirection); - /** - * Gets the number of frustums used in the last frame. - * @memberof Scene.prototype - * @type {Number} - * - * @private - */ - numberOfFrustums : { - get : function() { - return this._frustumCommandsList.length; - } - }, + // Get the light position in eye coordinates + Matrix4.multiplyByPoint(camera.viewMatrix, shadowMapCamera.positionWC, shadowMap._lightPositionEC); + shadowMap._lightPositionEC.w = shadowMap._pointLightRadius; - /** - * Gets the scalar used to exaggerate the terrain. - * @memberof Scene.prototype - * @type {Number} - */ - terrainExaggeration : { - get : function() { - return this._terrainExaggeration; - } - }, + // Get the near and far of the scene camera + var near; + var far; + if (shadowMap._fitNearFar) { + // shadowFar can be very large, so limit to shadowMap.maximumDistance + // Push the far plane slightly further than the near plane to avoid degenerate frustum + near = Math.min(frameState.shadowHints.nearPlane, shadowMap.maximumDistance); + far = Math.min(frameState.shadowHints.farPlane, shadowMap.maximumDistance + 1.0); + } else { + near = camera.frustum.near; + far = shadowMap.maximumDistance; + } - /** - * When <code>true</code>, splits the scene into two viewports with steroscopic views for the left and right eyes. - * Used for cardboard and WebVR. - * @memberof Scene.prototype - * @type {Boolean} - * @default false - */ - useWebVR : { - get : function() { - return this._useWebVR; - }, - set : function(value) { - if (this.camera.frustum instanceof OrthographicFrustum) { - throw new DeveloperError('VR is unsupported with an orthographic projection.'); - } - this._useWebVR = value; - if (this._useWebVR) { - this._frameState.creditDisplay.container.style.visibility = 'hidden'; - this._cameraVR = new Camera(this); - if (!defined(this._deviceOrientationCameraController)) { - this._deviceOrientationCameraController = new DeviceOrientationCameraController(this); - } + shadowMap._sceneCamera = Camera.clone(camera, sceneCamera); + camera.frustum.clone(shadowMap._sceneCamera.frustum); + shadowMap._sceneCamera.frustum.near = near; + shadowMap._sceneCamera.frustum.far = far; + shadowMap._distance = far - near; + + checkVisibility(shadowMap, frameState); + + if (!shadowMap._outOfViewPrevious && shadowMap._outOfView) { + shadowMap._needsUpdate = true; + } + shadowMap._outOfViewPrevious = shadowMap._outOfView; + } + + /** + * @private + */ + ShadowMap.prototype.update = function(frameState) { + updateCameras(this, frameState); - this._aspectRatioVR = this._camera.frustum.aspectRatio; - } else { - this._frameState.creditDisplay.container.style.visibility = 'visible'; - this._cameraVR = undefined; - this._deviceOrientationCameraController = this._deviceOrientationCameraController && !this._deviceOrientationCameraController.isDestroyed() && this._deviceOrientationCameraController.destroy(); + if (this._needsUpdate) { + updateFramebuffer(this, frameState.context); - this._camera.frustum.aspectRatio = this._aspectRatioVR; - this._camera.frustum.xOffset = 0.0; - } + if (this._isPointLight) { + computeOmnidirectional(this, frameState); } - }, - /** - * Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. - * @memberof Scene.prototype - * @type {Boolean} - */ - mapMode2D : { - get : function() { - return this._mapMode2D; - } - }, + if (this._cascadesEnabled) { + fitShadowMapToScene(this, frameState); - /** - * Gets or sets the position of the Imagery splitter within the viewport. Valid values are between 0.0 and 1.0. - * @memberof Scene.prototype - * - * @type {Number} - */ - imagerySplitPosition : { - get: function() { - return this._frameState.imagerySplitPosition; - }, - set: function(value) { - this._frameState.imagerySplitPosition = value; + if (this._numberOfCascades > 1) { + computeCascades(this, frameState); + } } - }, - /** - * The distance from the camera at which to disable the depth test of billboards, labels and points - * to, for example, prevent clipping against terrain. When set to zero, the depth test should always - * be applied. When less than zero, the depth test should never be applied. Setting the disableDepthTestDistance - * property of a billboard, label or point will override this value. - * @memberof Scene.prototype - * @type {Number} - * @default 0.0 - */ - minimumDisableDepthTestDistance : { - get : function() { - return this._minimumDisableDepthTestDistance; - }, - set : function(value) { - if (!defined(value) || value < 0.0) { - throw new DeveloperError('minimumDisableDepthTestDistance must be greater than or equal to 0.0.'); + if (!this._isPointLight) { + // Compute the culling volume + var shadowMapCamera = this._shadowMapCamera; + var position = shadowMapCamera.positionWC; + var direction = shadowMapCamera.directionWC; + var up = shadowMapCamera.upWC; + this._shadowMapCullingVolume = shadowMapCamera.frustum.computeCullingVolume(position, direction, up); + + if (this._passes.length === 1) { + // Since there is only one pass, use the shadow map camera as the pass camera. + this._passes[0].camera.clone(shadowMapCamera); } - this._minimumDisableDepthTestDistance = value; + } else { + this._shadowMapCullingVolume = CullingVolume.fromBoundingSphere(this._boundingSphere); } } - }); + + if (this._passes.length === 1) { + // Transforms from eye space to shadow texture space. + // Always requires an update since the scene camera constantly changes. + var inverseView = this._sceneCamera.inverseViewMatrix; + Matrix4.multiply(this._shadowMapCamera.getViewProjection(), inverseView, this._shadowMapMatrix); + } + + if (this.debugShow) { + applyDebugSettings(this, frameState); + } + }; /** - * Determines if a compressed texture format is supported. - * @param {String} format The texture format. May be the name of the format or the WebGL extension name, e.g. s3tc or WEBGL_compressed_texture_s3tc. - * @return {boolean} Whether or not the format is supported. + * @private */ - Scene.prototype.getCompressedTextureFormatSupported = function(format) { - var context = this.context; - return ((format === 'WEBGL_compressed_texture_s3tc' || format === 's3tc') && context.s3tc) || - ((format === 'WEBGL_compressed_texture_pvrtc' || format === 'pvrtc') && context.pvrtc) || - ((format === 'WEBGL_compressed_texture_etc1' || format === 'etc1') && context.etc1); + ShadowMap.prototype.updatePass = function(context, shadowPass) { + clearFramebuffer(this, context, shadowPass); }; - var scratchPosition0 = new Cartesian3(); - var scratchPosition1 = new Cartesian3(); - function maxComponent(a, b) { - var x = Math.max(Math.abs(a.x), Math.abs(b.x)); - var y = Math.max(Math.abs(a.y), Math.abs(b.y)); - var z = Math.max(Math.abs(a.z), Math.abs(b.z)); - return Math.max(Math.max(x, y), z); - } - - function cameraEqual(camera0, camera1, epsilon) { - var scalar = 1 / Math.max(1, maxComponent(camera0.position, camera1.position)); - Cartesian3.multiplyByScalar(camera0.position, scalar, scratchPosition0); - Cartesian3.multiplyByScalar(camera1.position, scalar, scratchPosition1); - return Cartesian3.equalsEpsilon(scratchPosition0, scratchPosition1, epsilon) && - Cartesian3.equalsEpsilon(camera0.direction, camera1.direction, epsilon) && - Cartesian3.equalsEpsilon(camera0.up, camera1.up, epsilon) && - Cartesian3.equalsEpsilon(camera0.right, camera1.right, epsilon) && - Matrix4.equalsEpsilon(camera0.transform, camera1.transform, epsilon); - } - - function updateDerivedCommands(scene, command) { - var frameState = scene.frameState; - var context = scene._context; - var shadowsEnabled = frameState.shadowHints.shadowsEnabled; - var shadowMaps = frameState.shadowHints.shadowMaps; - var lightShadowMaps = frameState.shadowHints.lightShadowMaps; - var lightShadowsEnabled = shadowsEnabled && (lightShadowMaps.length > 0); + var scratchTexelStepSize = new Cartesian2(); - // Update derived commands when any shadow maps become dirty - var shadowsDirty = false; - var lastDirtyTime = frameState.shadowHints.lastDirtyTime; - if (command.lastDirtyTime !== lastDirtyTime) { - command.lastDirtyTime = lastDirtyTime; - command.dirty = true; - shadowsDirty = true; - } + function combineUniforms(shadowMap, uniforms, isTerrain) { + var bias = shadowMap._isPointLight ? shadowMap._pointBias : (isTerrain ? shadowMap._terrainBias : shadowMap._primitiveBias); - var derivedCommands = command.derivedCommands; - if (command.dirty && defined(derivedCommands)) { - command.dirty = false; + var mapUniforms = { + shadowMap_texture :function() { + return shadowMap._shadowMapTexture; + }, + shadowMap_textureCube : function() { + return shadowMap._shadowMapTexture; + }, + shadowMap_matrix : function() { + return shadowMap._shadowMapMatrix; + }, + shadowMap_cascadeSplits : function() { + return shadowMap._cascadeSplits; + }, + shadowMap_cascadeMatrices : function() { + return shadowMap._cascadeMatrices; + }, + shadowMap_lightDirectionEC : function() { + return shadowMap._lightDirectionEC; + }, + shadowMap_lightPositionEC : function() { + return shadowMap._lightPositionEC; + }, + shadowMap_cascadeDistances : function() { + return shadowMap._cascadeDistances; + }, + shadowMap_texelSizeDepthBiasAndNormalShadingSmooth : function() { + var texelStepSize = scratchTexelStepSize; + texelStepSize.x = 1.0 / shadowMap._textureSize.x; + texelStepSize.y = 1.0 / shadowMap._textureSize.y; - if (shadowsEnabled && (command.receiveShadows || command.castShadows)) { - derivedCommands.shadows = ShadowMap.createDerivedCommands(shadowMaps, lightShadowMaps, command, shadowsDirty, context, derivedCommands.shadows); - } + return Cartesian4.fromElements(texelStepSize.x, texelStepSize.y, bias.depthBias, bias.normalShadingSmooth, this.combinedUniforms1); + }, + shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness : function() { + return Cartesian4.fromElements(bias.normalOffsetScale, shadowMap._distance, shadowMap.maximumDistance, shadowMap._darkness, this.combinedUniforms2); + }, - var oit = scene._oit; - if (command.pass === Pass.TRANSLUCENT && defined(oit) && oit.isSupported()) { - if (lightShadowsEnabled && command.receiveShadows) { - derivedCommands.oit = defined(derivedCommands.oit) ? derivedCommands.oit : {}; - derivedCommands.oit.shadows = oit.createDerivedCommands(command.derivedCommands.shadows.receiveCommand, context, derivedCommands.oit.shadows); - } else { - derivedCommands.oit = oit.createDerivedCommands(command, context, derivedCommands.oit); - } - } + combinedUniforms1 : new Cartesian4(), + combinedUniforms2 : new Cartesian4() + }; - derivedCommands.depth = createDepthOnlyDerivedCommand(scene, command, context, derivedCommands.depth); - } + return combine(uniforms, mapUniforms, false); } - var scratchOccluderBoundingSphere = new BoundingSphere(); - var scratchOccluder; - - function getOccluder(scene) { - // TODO: The occluder is the top-level globe. When we add - // support for multiple central bodies, this should be the closest one. - var globe = scene.globe; - if (scene._mode === SceneMode.SCENE3D && defined(globe)) { - var ellipsoid = globe.ellipsoid; - scratchOccluderBoundingSphere.radius = ellipsoid.minimumRadius; - scratchOccluder = Occluder.fromBoundingSphere(scratchOccluderBoundingSphere, scene._camera.positionWC, scratchOccluder); - return scratchOccluder; + function createCastDerivedCommand(shadowMap, shadowsDirty, command, context, oldShaderId, result) { + var castShader; + var castRenderState; + var castUniformMap; + if (defined(result)) { + castShader = result.shaderProgram; + castRenderState = result.renderState; + castUniformMap = result.uniformMap; } - return undefined; - } - - function clearPasses(passes) { - passes.render = false; - passes.pick = false; - passes.depth = false; - } - - function updateFrameState(scene, frameNumber, time) { - var camera = scene._camera; - - var frameState = scene._frameState; - frameState.commandList.length = 0; - frameState.shadowMaps.length = 0; - frameState.brdfLutGenerator = scene._brdfLutGenerator; - frameState.environmentMap = scene.skyBox && scene.skyBox._cubeMap; - frameState.mode = scene._mode; - frameState.morphTime = scene.morphTime; - frameState.mapProjection = scene.mapProjection; - frameState.frameNumber = frameNumber; - frameState.time = JulianDate.clone(time, frameState.time); - frameState.camera = camera; - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - frameState.occluder = getOccluder(scene); - frameState.terrainExaggeration = scene._terrainExaggeration; - frameState.minimumDisableDepthTestDistance = scene._minimumDisableDepthTestDistance; - frameState.invertClassification = scene.invertClassification; + result = DrawCommand.shallowClone(command, result); + result.castShadows = true; + result.receiveShadows = false; - scene._actualInvertClassificationColor = Color.clone(scene.invertClassificationColor, scene._actualInvertClassificationColor); - if (!InvertClassification.isTranslucencySupported(scene._context)) { - scene._actualInvertClassificationColor.alpha = 1.0; - } + if (!defined(castShader) || oldShaderId !== command.shaderProgram.id || shadowsDirty) { + var shaderProgram = command.shaderProgram; - frameState.invertClassificationColor = scene._actualInvertClassificationColor; + var isTerrain = command.pass === Pass.GLOBE; + var isOpaque = command.pass !== Pass.TRANSLUCENT; + var isPointLight = shadowMap._isPointLight; + var usesDepthTexture= shadowMap._usesDepthTexture; - if (defined(scene.globe)) { - frameState.maximumScreenSpaceError = scene.globe.maximumScreenSpaceError; - } else { - frameState.maximumScreenSpaceError = 2; - } + var keyword = ShadowMapShader.getShadowCastShaderKeyword(isPointLight, isTerrain, usesDepthTexture, isOpaque); + castShader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword); + if (!defined(castShader)) { + var vertexShaderSource = shaderProgram.vertexShaderSource; + var fragmentShaderSource = shaderProgram.fragmentShaderSource; - clearPasses(frameState.passes); - } + var castVS = ShadowMapShader.createShadowCastVertexShader(vertexShaderSource, isPointLight, isTerrain); + var castFS = ShadowMapShader.createShadowCastFragmentShader(fragmentShaderSource, isPointLight, usesDepthTexture, isOpaque); - function updateFrustums(near, far, farToNearRatio, numFrustums, frustumCommandsList, is2D, nearToFarDistance2D) { - frustumCommandsList.length = numFrustums; - for (var m = 0; m < numFrustums; ++m) { - var curNear; - var curFar; + castShader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, { + vertexShaderSource : castVS, + fragmentShaderSource : castFS, + attributeLocations : shaderProgram._attributeLocations + }); + } - if (!is2D) { - curNear = Math.max(near, Math.pow(farToNearRatio, m) * near); - curFar = Math.min(far, farToNearRatio * curNear); - } else { - curNear = Math.min(far - nearToFarDistance2D, near + m * nearToFarDistance2D); - curFar = Math.min(far, curNear + nearToFarDistance2D); + castRenderState = shadowMap._primitiveRenderState; + if (isPointLight) { + castRenderState = shadowMap._pointRenderState; + } else if (isTerrain) { + castRenderState = shadowMap._terrainRenderState; } - var frustumCommands = frustumCommandsList[m]; - if (!defined(frustumCommands)) { - frustumCommands = frustumCommandsList[m] = new FrustumCommands(curNear, curFar); - } else { - frustumCommands.near = curNear; - frustumCommands.far = curFar; + // Modify the render state for commands that do not use back-face culling, e.g. flat textured walls + var cullEnabled = command.renderState.cull.enabled; + if (!cullEnabled) { + castRenderState = clone(castRenderState, false); + castRenderState.cull = clone(castRenderState.cull, false); + castRenderState.cull.enabled = false; + castRenderState = RenderState.fromCache(castRenderState); } + + castUniformMap = combineUniforms(shadowMap, command.uniformMap, isTerrain); } + + result.shaderProgram = castShader; + result.renderState = castRenderState; + result.uniformMap = castUniformMap; + + return result; } - function insertIntoBin(scene, command, distance) { - if (scene.debugShowFrustums) { - command.debugOverlappingFrustums = 0; + ShadowMap.createDerivedCommands = function(shadowMaps, lightShadowMaps, command, shadowsDirty, context, result) { + if (!defined(result)) { + result = {}; } - if (!scene.frameState.passes.pick) { - updateDerivedCommands(scene, command); + var lightShadowMapsEnabled = (lightShadowMaps.length > 0); + var shaderProgram = command.shaderProgram; + var vertexShaderSource = shaderProgram.vertexShaderSource; + var fragmentShaderSource = shaderProgram.fragmentShaderSource; + var isTerrain = command.pass === Pass.GLOBE; + + var hasTerrainNormal = false; + if (isTerrain) { + hasTerrainNormal = command.owner.data.pickTerrain.mesh.encoding.hasVertexNormals; } - var frustumCommandsList = scene._frustumCommandsList; - var length = frustumCommandsList.length; + if (command.castShadows) { + var castCommands = result.castCommands; + if (!defined(castCommands)) { + castCommands = result.castCommands = []; + } - for (var i = 0; i < length; ++i) { - var frustumCommands = frustumCommandsList[i]; - var curNear = frustumCommands.near; - var curFar = frustumCommands.far; + var oldShaderId = result.castShaderProgramId; - if (distance.start > curFar) { - continue; - } + var shadowMapLength = shadowMaps.length; + castCommands.length = shadowMapLength; - if (distance.stop < curNear) { - break; + for (var i = 0; i < shadowMapLength; ++i) { + castCommands[i] = createCastDerivedCommand(shadowMaps[i], shadowsDirty, command, context, oldShaderId, castCommands[i]); } - var pass = command.pass; - var index = frustumCommands.indices[pass]++; - frustumCommands.commands[pass][index] = command; + result.castShaderProgramId = command.shaderProgram.id; + } - if (scene.debugShowFrustums) { - command.debugOverlappingFrustums |= (1 << i); + if (command.receiveShadows && lightShadowMapsEnabled) { + // Only generate a receiveCommand if there is a shadow map originating from a light source. + var receiveShader; + var receiveUniformMap; + if (defined(result.receiveCommand)) { + receiveShader = result.receiveCommand.shaderProgram; + receiveUniformMap = result.receiveCommand.uniformMap; } - if (command.executeInClosestFrustum) { - break; + result.receiveCommand = DrawCommand.shallowClone(command, result.receiveCommand); + result.castShadows = false; + result.receiveShadows = true; + + // If castShadows changed, recompile the receive shadows shader. The normal shading technique simulates + // self-shadowing so it should be turned off if castShadows is false. + var castShadowsDirty = result.receiveShaderCastShadows !== command.castShadows; + var shaderDirty = result.receiveShaderProgramId !== command.shaderProgram.id; + + if (!defined(receiveShader) || shaderDirty || shadowsDirty || castShadowsDirty) { + var keyword = ShadowMapShader.getShadowReceiveShaderKeyword(lightShadowMaps[0], command.castShadows, isTerrain, hasTerrainNormal); + receiveShader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword); + if (!defined(receiveShader)) { + var receiveVS = ShadowMapShader.createShadowReceiveVertexShader(vertexShaderSource, isTerrain, hasTerrainNormal); + var receiveFS = ShadowMapShader.createShadowReceiveFragmentShader(fragmentShaderSource, lightShadowMaps[0], command.castShadows, isTerrain, hasTerrainNormal); + + receiveShader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, { + vertexShaderSource : receiveVS, + fragmentShaderSource : receiveFS, + attributeLocations : shaderProgram._attributeLocations + }); + } + + receiveUniformMap = combineUniforms(lightShadowMaps[0], command.uniformMap, isTerrain); } - } - if (scene.debugShowFrustums) { - var cf = scene._debugFrustumStatistics.commandsInFrustums; - cf[command.debugOverlappingFrustums] = defined(cf[command.debugOverlappingFrustums]) ? cf[command.debugOverlappingFrustums] + 1 : 1; - ++scene._debugFrustumStatistics.totalCommands; + result.receiveCommand.shaderProgram = receiveShader; + result.receiveCommand.uniformMap = receiveUniformMap; + result.receiveShaderProgramId = command.shaderProgram.id; + result.receiveShaderCastShadows = command.castShadows; } - } - var scratchCullingVolume = new CullingVolume(); - var distances = new Interval(); + return result; + }; - function isVisible(command, cullingVolume, occluder) { - return ((defined(command)) && - ((!defined(command.boundingVolume)) || - !command.cull || - ((cullingVolume.computeVisibility(command.boundingVolume) !== Intersect.OUTSIDE) && - (!defined(occluder) || !command.boundingVolume.isOccluded(occluder))))); - } + /** + * @private + */ + ShadowMap.prototype.isDestroyed = function() { + return false; + }; - function createPotentiallyVisibleSet(scene) { - var frameState = scene._frameState; - var camera = frameState.camera; - var direction = camera.directionWC; - var position = camera.positionWC; + /** + * @private + */ + ShadowMap.prototype.destroy = function() { + destroyFramebuffer(this); - var computeList = scene._computeCommandList; - var overlayList = scene._overlayCommandList; - var commandList = frameState.commandList; + this._debugLightFrustum = this._debugLightFrustum && this._debugLightFrustum.destroy(); + this._debugCameraFrustum = this._debugCameraFrustum && this._debugCameraFrustum.destroy(); + this._debugShadowViewCommand = this._debugShadowViewCommand && this._debugShadowViewCommand.shaderProgram && this._debugShadowViewCommand.shaderProgram.destroy(); - if (scene.debugShowFrustums) { - scene._debugFrustumStatistics = { - totalCommands : 0, - commandsInFrustums : {} - }; + for (var i = 0; i < this._numberOfCascades; ++i) { + this._debugCascadeFrustums[i] = this._debugCascadeFrustums[i] && this._debugCascadeFrustums[i].destroy(); } - var frustumCommandsList = scene._frustumCommandsList; - var numberOfFrustums = frustumCommandsList.length; - var numberOfPasses = Pass.NUMBER_OF_PASSES; - for (var n = 0; n < numberOfFrustums; ++n) { - for (var p = 0; p < numberOfPasses; ++p) { - frustumCommandsList[n].indices[p] = 0; - } - } + return destroyObject(this); + }; - computeList.length = 0; - overlayList.length = 0; + return ShadowMap; +}); - var near = Number.MAX_VALUE; - var far = -Number.MAX_VALUE; - var undefBV = false; +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PostProcessFilters/AdditiveBlend',[],function() { + 'use strict'; + return "uniform sampler2D u_texture0;\n\ +uniform sampler2D u_texture1;\n\ +uniform vec2 u_center;\n\ +uniform float u_radius;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +vec4 color0 = texture2D(u_texture0, v_textureCoordinates);\n\ +vec4 color1 = texture2D(u_texture1, v_textureCoordinates);\n\ +float x = length(gl_FragCoord.xy - u_center) / u_radius;\n\ +float t = smoothstep(0.5, 0.8, x);\n\ +gl_FragColor = mix(color0 + color1, color0, t);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PostProcessFilters/BrightPass',[],function() { + 'use strict'; + return "uniform sampler2D u_texture;\n\ +uniform float u_avgLuminance;\n\ +uniform float u_threshold;\n\ +uniform float u_offset;\n\ +varying vec2 v_textureCoordinates;\n\ +float key(float avg)\n\ +{\n\ +float guess = 1.5 - (1.5 / (avg * 0.1 + 1.0));\n\ +return max(0.0, guess) + 0.1;\n\ +}\n\ +void main()\n\ +{\n\ +vec4 color = texture2D(u_texture, v_textureCoordinates);\n\ +vec3 xyz = czm_RGBToXYZ(color.rgb);\n\ +float luminance = xyz.r;\n\ +float scaledLum = key(u_avgLuminance) * luminance / u_avgLuminance;\n\ +float brightLum = max(scaledLum - u_threshold, 0.0);\n\ +float brightness = brightLum / (u_offset + brightLum);\n\ +xyz.r = brightness;\n\ +gl_FragColor = vec4(czm_XYZToRGB(xyz), 1.0);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/PostProcessFilters/GaussianBlur1D',[],function() { + 'use strict'; + return "#define SAMPLES 8\n\ +uniform float delta;\n\ +uniform float sigma;\n\ +uniform float direction;\n\ +uniform sampler2D u_texture;\n\ +uniform vec2 u_step;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +vec2 st = v_textureCoordinates;\n\ +vec2 dir = vec2(1.0 - direction, direction);\n\ +vec3 g;\n\ +g.x = 1.0 / (sqrt(czm_twoPi) * sigma);\n\ +g.y = exp((-0.5 * delta * delta) / (sigma * sigma));\n\ +g.z = g.y * g.y;\n\ +vec4 result = texture2D(u_texture, st) * g.x;\n\ +for (int i = 1; i < SAMPLES; ++i)\n\ +{\n\ +g.xy *= g.yz;\n\ +vec2 offset = float(i) * dir * u_step;\n\ +result += texture2D(u_texture, st - offset) * g.x;\n\ +result += texture2D(u_texture, st + offset) * g.x;\n\ +}\n\ +gl_FragColor = result;\n\ +}\n\ +"; +}); +define('Scene/SunPostProcess',[ + '../Core/BoundingRectangle', + '../Core/Cartesian2', + '../Core/Cartesian4', + '../Core/Color', + '../Core/defaultValue', + '../Core/defined', + '../Core/destroyObject', + '../Core/Math', + '../Core/Matrix4', + '../Core/PixelFormat', + '../Core/Transforms', + '../Renderer/ClearCommand', + '../Renderer/Framebuffer', + '../Renderer/PassState', + '../Renderer/PixelDatatype', + '../Renderer/Renderbuffer', + '../Renderer/RenderbufferFormat', + '../Renderer/RenderState', + '../Renderer/Texture', + '../Shaders/PostProcessFilters/AdditiveBlend', + '../Shaders/PostProcessFilters/BrightPass', + '../Shaders/PostProcessFilters/GaussianBlur1D', + '../Shaders/PostProcessFilters/PassThrough' + ], function( + BoundingRectangle, + Cartesian2, + Cartesian4, + Color, + defaultValue, + defined, + destroyObject, + CesiumMath, + Matrix4, + PixelFormat, + Transforms, + ClearCommand, + Framebuffer, + PassState, + PixelDatatype, + Renderbuffer, + RenderbufferFormat, + RenderState, + Texture, + AdditiveBlend, + BrightPass, + GaussianBlur1D, + PassThrough) { + 'use strict'; - var shadowsEnabled = frameState.shadowHints.shadowsEnabled; - var shadowNear = Number.MAX_VALUE; - var shadowFar = -Number.MAX_VALUE; - var shadowClosestObjectSize = Number.MAX_VALUE; + function SunPostProcess() { + this._fbo = undefined; - var occluder = (frameState.mode === SceneMode.SCENE3D) ? frameState.occluder: undefined; - var cullingVolume = frameState.cullingVolume; + this._downSampleFBO1 = undefined; + this._downSampleFBO2 = undefined; - // get user culling volume minus the far plane. - var planes = scratchCullingVolume.planes; - for (var k = 0; k < 5; ++k) { - planes[k] = cullingVolume.planes[k]; - } - cullingVolume = scratchCullingVolume; + this._clearFBO1Command = undefined; + this._clearFBO2Command = undefined; - var length = commandList.length; - for (var i = 0; i < length; ++i) { - var command = commandList[i]; - var pass = command.pass; + this._downSampleCommand = undefined; + this._brightPassCommand = undefined; + this._blurXCommand = undefined; + this._blurYCommand = undefined; + this._blendCommand = undefined; + this._fullScreenCommand = undefined; - if (pass === Pass.COMPUTE) { - computeList.push(command); - } else if (pass === Pass.OVERLAY) { - overlayList.push(command); - } else { - var boundingVolume = command.boundingVolume; - if (defined(boundingVolume)) { - if (!isVisible(command, cullingVolume, occluder)) { - continue; - } + this._downSamplePassState = new PassState(); + this._downSamplePassState.scissorTest = { + enable : true, + rectangle : new BoundingRectangle() + }; - distances = boundingVolume.computePlaneDistances(position, direction, distances); - near = Math.min(near, distances.start); - far = Math.max(far, distances.stop); + this._upSamplePassState = new PassState(); + this._upSamplePassState.scissorTest = { + enabled : true, + rectangle : new BoundingRectangle() + }; - // Compute a tight near and far plane for commands that receive shadows. This helps compute - // good splits for cascaded shadow maps. Ignore commands that exceed the maximum distance. - // When moving the camera low LOD globe tiles begin to load, whose bounding volumes - // throw off the near/far fitting for the shadow map. Only update for globe tiles that the - // camera isn't inside. - if (shadowsEnabled && command.receiveShadows && (distances.start < ShadowMap.MAXIMUM_DISTANCE) && - !((pass === Pass.GLOBE) && (distances.start < -100.0) && (distances.stop > 100.0))) { + this._uCenter = new Cartesian2(); + this._uRadius = undefined; - // Get the smallest bounding volume the camera is near. This is used to place more shadow detail near the object. - var size = distances.stop - distances.start; - if ((pass !== Pass.GLOBE) && (distances.start < 100.0)) { - shadowClosestObjectSize = Math.min(shadowClosestObjectSize, size); - } - shadowNear = Math.min(shadowNear, distances.start); - shadowFar = Math.max(shadowFar, distances.stop); - } - } else { - // Clear commands don't need a bounding volume - just add the clear to all frustums. - // If another command has no bounding volume, though, we need to use the camera's - // worst-case near and far planes to avoid clipping something important. - distances.start = camera.frustum.near; - distances.stop = camera.frustum.far; - undefBV = !(command instanceof ClearCommand); - } + this._blurStep = new Cartesian2(); + } - insertIntoBin(scene, command, distances); - } - } + SunPostProcess.prototype.clear = function(context, color) { + var clear = this._clearFBO1Command; + Color.clone(defaultValue(color, Color.BLACK), clear.color); + clear.execute(context); - if (undefBV) { - near = camera.frustum.near; - far = camera.frustum.far; - } else { - // The computed near plane must be between the user defined near and far planes. - // The computed far plane must between the user defined far and computed near. - // This will handle the case where the computed near plane is further than the user defined far plane. - near = Math.min(Math.max(near, camera.frustum.near), camera.frustum.far); - far = Math.max(Math.min(far, camera.frustum.far), near); + clear = this._clearFBO2Command; + Color.clone(defaultValue(color, Color.BLACK), clear.color); + clear.execute(context); + }; - if (shadowsEnabled) { - shadowNear = Math.min(Math.max(shadowNear, camera.frustum.near), camera.frustum.far); - shadowFar = Math.max(Math.min(shadowFar, camera.frustum.far), shadowNear); - } - } + SunPostProcess.prototype.execute = function(context, framebuffer) { + this._downSampleCommand.execute(context, this._downSamplePassState); + this._brightPassCommand.execute(context, this._downSamplePassState); + this._blurXCommand.execute(context, this._downSamplePassState); + this._blurYCommand.execute(context, this._downSamplePassState); - // Use the computed near and far for shadows - if (shadowsEnabled) { - frameState.shadowHints.nearPlane = shadowNear; - frameState.shadowHints.farPlane = shadowFar; - frameState.shadowHints.closestObjectSize = shadowClosestObjectSize; - } + this._fullScreenCommand.framebuffer = framebuffer; + this._blendCommand.framebuffer = framebuffer; - // Exploit temporal coherence. If the frustums haven't changed much, use the frustums computed - // last frame, else compute the new frustums and sort them by frustum again. - var is2D = scene.mode === SceneMode.SCENE2D; - var farToNearRatio = scene.farToNearRatio; + this._fullScreenCommand.execute(context); + this._blendCommand.execute(context, this._upSamplePassState); + }; - var numFrustums; - if (!is2D) { - // The multifrustum for 3D/CV is non-uniformly distributed. - numFrustums = Math.ceil(Math.log(far / near) / Math.log(farToNearRatio)); - } else { - // The multifrustum for 2D is uniformly distributed. To avoid z-fighting in 2D, - // the camera i smoved to just before the frustum and the frustum depth is scaled - // to be in [1.0, nearToFarDistance2D]. - far = Math.min(far, camera.position.z + scene.nearToFarDistance2D); - near = Math.min(near, far); - numFrustums = Math.ceil(Math.max(1.0, far - near) / scene.nearToFarDistance2D); - } + var viewportBoundingRectangle = new BoundingRectangle(); + var downSampleViewportBoundingRectangle = new BoundingRectangle(); + var sunPositionECScratch = new Cartesian4(); + var sunPositionWCScratch = new Cartesian2(); + var sizeScratch = new Cartesian2(); + var postProcessMatrix4Scratch= new Matrix4(); - if (near !== Number.MAX_VALUE && (numFrustums !== numberOfFrustums || (frustumCommandsList.length !== 0 && - (near < frustumCommandsList[0].near || (far > frustumCommandsList[numberOfFrustums - 1].far && !CesiumMath.equalsEpsilon(far, frustumCommandsList[numberOfFrustums - 1].far, CesiumMath.EPSILON8)))))) { - updateFrustums(near, far, farToNearRatio, numFrustums, frustumCommandsList, is2D, scene.nearToFarDistance2D); - createPotentiallyVisibleSet(scene); - } + SunPostProcess.prototype.update = function(passState) { + var context = passState.context; + var viewport = passState.viewport; + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; - var frustumSplits = frameState.frustumSplits; - frustumSplits.length = numFrustums + 1; - for (var j = 0; j < numFrustums; ++j) { - frustumSplits[j] = frustumCommandsList[j].near; - if (j === numFrustums - 1) { - frustumSplits[j + 1] = frustumCommandsList[j].far; - } - } - } + var that = this; - function getAttributeLocations(shaderProgram) { - var attributeLocations = {}; - var attributes = shaderProgram.vertexAttributes; - for (var a in attributes) { - if (attributes.hasOwnProperty(a)) { - attributeLocations[a] = attributes[a].index; - } - } + if (!defined(this._downSampleCommand)) { + this._clearFBO1Command = new ClearCommand({ + color : new Color() + }); + this._clearFBO2Command = new ClearCommand({ + color : new Color() + }); - return attributeLocations; - } + var uniformMap = {}; - function createDebugFragmentShaderProgram(command, scene, shaderProgram) { - var context = scene.context; - var sp = defaultValue(shaderProgram, command.shaderProgram); - var fs = sp.fragmentShaderSource.clone(); + this._downSampleCommand = context.createViewportQuadCommand(PassThrough, { + uniformMap : uniformMap, + owner : this + }); - var targets = []; - fs.sources = fs.sources.map(function(source) { - source = ShaderSource.replaceMain(source, 'czm_Debug_main'); - var re = /gl_FragData\[(\d+)\]/g; - var match; - while ((match = re.exec(source)) !== null) { - if (targets.indexOf(match[1]) === -1) { - targets.push(match[1]); + uniformMap = { + u_avgLuminance : function() { + // A guess at the average luminance across the entire scene + return 0.5; + }, + u_threshold : function() { + return 0.25; + }, + u_offset : function() { + return 0.1; } - } - return source; - }); - var length = targets.length; + }; - var newMain = - 'void main() \n' + - '{ \n' + - ' czm_Debug_main(); \n'; + this._brightPassCommand = context.createViewportQuadCommand(BrightPass, { + uniformMap : uniformMap, + owner : this + }); - var i; - if (scene.debugShowCommands) { - if (!defined(command._debugColor)) { - command._debugColor = Color.fromRandom(); - } - var c = command._debugColor; - if (length > 0) { - for (i = 0; i < length; ++i) { - newMain += ' gl_FragData[' + targets[i] + '].rgb *= vec3(' + c.red + ', ' + c.green + ', ' + c.blue + '); \n'; - } - } else { - newMain += ' ' + 'gl_FragColor' + '.rgb *= vec3(' + c.red + ', ' + c.green + ', ' + c.blue + '); \n'; - } - } + var delta = 1.0; + var sigma = 2.0; - if (scene.debugShowFrustums) { - // Support up to three frustums. If a command overlaps all - // three, it's code is not changed. - var r = (command.debugOverlappingFrustums & (1 << 0)) ? '1.0' : '0.0'; - var g = (command.debugOverlappingFrustums & (1 << 1)) ? '1.0' : '0.0'; - var b = (command.debugOverlappingFrustums & (1 << 2)) ? '1.0' : '0.0'; - if (length > 0) { - for (i = 0; i < length; ++i) { - newMain += ' gl_FragData[' + targets[i] + '].rgb *= vec3(' + r + ', ' + g + ', ' + b + '); \n'; + uniformMap = { + delta : function() { + return delta; + }, + sigma : function() { + return sigma; + }, + direction : function() { + return 0.0; } - } else { - newMain += ' ' + 'gl_FragColor' + '.rgb *= vec3(' + r + ', ' + g + ', ' + b + '); \n'; - } - } + }; - newMain += '}'; + this._blurXCommand = context.createViewportQuadCommand(GaussianBlur1D, { + uniformMap : uniformMap, + owner : this + }); - fs.sources.push(newMain); + uniformMap = { + delta : function() { + return delta; + }, + sigma : function() { + return sigma; + }, + direction : function() { + return 1.0; + } + }; - var attributeLocations = getAttributeLocations(sp); + this._blurYCommand = context.createViewportQuadCommand(GaussianBlur1D, { + uniformMap : uniformMap, + owner : this + }); - return ShaderProgram.fromCache({ - context : context, - vertexShaderSource : sp.vertexShaderSource, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } + uniformMap = { + u_center : function() { + return that._uCenter; + }, + u_radius : function() { + return that._uRadius; + } + }; - function executeDebugCommand(command, scene, passState) { - var debugCommand = DrawCommand.shallowClone(command); - debugCommand.shaderProgram = createDebugFragmentShaderProgram(command, scene); - debugCommand.execute(scene.context, passState); - debugCommand.shaderProgram.destroy(); - } + this._blendCommand = context.createViewportQuadCommand(AdditiveBlend, { + uniformMap : uniformMap, + owner : this + }); - var transformFrom2D = new Matrix4(0.0, 0.0, 1.0, 0.0, - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0); - transformFrom2D = Matrix4.inverseTransformation(transformFrom2D, transformFrom2D); + uniformMap = {}; - function executeCommand(command, scene, context, passState, debugFramebuffer) { - if ((defined(scene.debugCommandFilter)) && !scene.debugCommandFilter(command)) { - return; + this._fullScreenCommand = context.createViewportQuadCommand(PassThrough, { + uniformMap : uniformMap, + owner : this + }); } - if (command instanceof ClearCommand) { - command.execute(context, passState); - return; - } + var downSampleWidth = Math.pow(2.0, Math.ceil(Math.log(width) / Math.log(2)) - 2.0); + var downSampleHeight = Math.pow(2.0, Math.ceil(Math.log(height) / Math.log(2)) - 2.0); - var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; - var lightShadowsEnabled = shadowsEnabled && (scene.frameState.shadowHints.lightShadowMaps.length > 0); + // The size computed above can be less than 1.0 if size < 4.0. This will probably + // never happen in practice, but does in the tests. Clamp to 1.0 to prevent WebGL + // errors in the tests. + var downSampleSize = Math.max(1.0, downSampleWidth, downSampleHeight); - if (scene.debugShowCommands || scene.debugShowFrustums) { - executeDebugCommand(command, scene, passState); - } else if (lightShadowsEnabled && command.receiveShadows && defined(command.derivedCommands.shadows)) { - // If the command receives shadows, execute the derived shadows command. - // Some commands, such as OIT derived commands, do not have derived shadow commands themselves - // and instead shadowing is built-in. In this case execute the command regularly below. - command.derivedCommands.shadows.receiveCommand.execute(context, passState); - } else if (scene.frameState.passes.depth && defined(command.derivedCommands.depth)) { - command.derivedCommands.depth.depthOnlyCommand.execute(context, passState); - } else { - command.execute(context, passState); - } + var downSampleViewport = downSampleViewportBoundingRectangle; + downSampleViewport.width = downSampleSize; + downSampleViewport.height = downSampleSize; - if (command.debugShowBoundingVolume && (defined(command.boundingVolume))) { - // Debug code to draw bounding volume for command. Not optimized! - // Assumes bounding volume is a bounding sphere or box - var frameState = scene._frameState; - var boundingVolume = command.boundingVolume; + var fbo = this._fbo; + var colorTexture = (defined(fbo) && fbo.getColorTexture(0)) || undefined; + if (!defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height) { + fbo = fbo && fbo.destroy(); + this._downSampleFBO1 = this._downSampleFBO1 && this._downSampleFBO1.destroy(); + this._downSampleFBO2 = this._downSampleFBO2 && this._downSampleFBO2.destroy(); - if (defined(scene._debugVolume)) { - scene._debugVolume.destroy(); - } + this._blurStep.x = this._blurStep.y = 1.0 / downSampleSize; - var geometry; + var colorTextures = [new Texture({ + context : context, + width : width, + height : height + })]; - var center = Cartesian3.clone(boundingVolume.center); - if (frameState.mode !== SceneMode.SCENE3D) { - center = Matrix4.multiplyByPoint(transformFrom2D, center, center); - var projection = frameState.mapProjection; - var centerCartographic = projection.unproject(center); - center = projection.ellipsoid.cartographicToCartesian(centerCartographic); + if (context.depthTexture) { + fbo = this._fbo = new Framebuffer({ + context : context, + colorTextures :colorTextures, + depthTexture : new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.DEPTH_COMPONENT, + pixelDatatype : PixelDatatype.UNSIGNED_SHORT + }) + }); + } else { + fbo = this._fbo = new Framebuffer({ + context : context, + colorTextures : colorTextures, + depthRenderbuffer : new Renderbuffer({ + context : context, + format : RenderbufferFormat.DEPTH_COMPONENT16 + }) + }); } - if (defined(boundingVolume.radius)) { - var radius = boundingVolume.radius; + this._downSampleFBO1 = new Framebuffer({ + context : context, + colorTextures : [new Texture({ + context : context, + width : downSampleSize, + height : downSampleSize + })] + }); + this._downSampleFBO2 = new Framebuffer({ + context : context, + colorTextures : [new Texture({ + context : context, + width : downSampleSize, + height : downSampleSize + })] + }); - geometry = GeometryPipeline.toWireframe(EllipsoidGeometry.createGeometry(new EllipsoidGeometry({ - radii : new Cartesian3(radius, radius, radius), - vertexFormat : PerInstanceColorAppearance.FLAT_VERTEX_FORMAT - }))); + this._clearFBO1Command.framebuffer = this._downSampleFBO1; + this._clearFBO2Command.framebuffer = this._downSampleFBO2; + this._downSampleCommand.framebuffer = this._downSampleFBO1; + this._brightPassCommand.framebuffer = this._downSampleFBO2; + this._blurXCommand.framebuffer = this._downSampleFBO1; + this._blurYCommand.framebuffer = this._downSampleFBO2; - scene._debugVolume = new Primitive({ - geometryInstances : new GeometryInstance({ - geometry : geometry, - modelMatrix : Matrix4.fromTranslation(center), - attributes : { - color : new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0) - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : false - }), - asynchronous : false - }); - } else { - var halfAxes = boundingVolume.halfAxes; + var downSampleRenderState = RenderState.fromCache({ + viewport : downSampleViewport + }); - geometry = GeometryPipeline.toWireframe(BoxGeometry.createGeometry(BoxGeometry.fromDimensions({ - dimensions : new Cartesian3(2.0, 2.0, 2.0), - vertexFormat : PerInstanceColorAppearance.FLAT_VERTEX_FORMAT - }))); + this._downSampleCommand.uniformMap.u_texture = function() { + return fbo.getColorTexture(0); + }; + this._downSampleCommand.renderState = downSampleRenderState; - scene._debugVolume = new Primitive({ - geometryInstances : new GeometryInstance({ - geometry : geometry, - modelMatrix : Matrix4.fromRotationTranslation(halfAxes, center, new Matrix4()), - attributes : { - color : new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0) - } - }), - appearance : new PerInstanceColorAppearance({ - flat : true, - translucent : false - }), - asynchronous : false - }); - } + this._brightPassCommand.uniformMap.u_texture = function() { + return that._downSampleFBO1.getColorTexture(0); + }; + this._brightPassCommand.renderState = downSampleRenderState; - var savedCommandList = frameState.commandList; - var commandList = frameState.commandList = []; - scene._debugVolume.update(frameState); + this._blurXCommand.uniformMap.u_texture = function() { + return that._downSampleFBO2.getColorTexture(0); + }; + this._blurXCommand.uniformMap.u_step = function() { + return that._blurStep; + }; + this._blurXCommand.renderState = downSampleRenderState; - var framebuffer; - if (defined(debugFramebuffer)) { - framebuffer = passState.framebuffer; - passState.framebuffer = debugFramebuffer; - } + this._blurYCommand.uniformMap.u_texture = function() { + return that._downSampleFBO1.getColorTexture(0); + }; + this._blurYCommand.uniformMap.u_step = function() { + return that._blurStep; + }; + this._blurYCommand.renderState = downSampleRenderState; - commandList[0].execute(context, passState); + var upSampledViewport = viewportBoundingRectangle; + upSampledViewport.width = width; + upSampledViewport.height = height; - if (defined(framebuffer)) { - passState.framebuffer = framebuffer; - } + var upSampleRenderState = RenderState.fromCache({ viewport : upSampledViewport }); - frameState.commandList = savedCommandList; + this._blendCommand.uniformMap.u_texture0 = function() { + return fbo.getColorTexture(0); + }; + this._blendCommand.uniformMap.u_texture1 = function() { + return that._downSampleFBO2.getColorTexture(0); + }; + this._blendCommand.renderState = upSampleRenderState; + + this._fullScreenCommand.uniformMap.u_texture = function() { + return fbo.getColorTexture(0); + }; + this._fullScreenCommand.renderState = upSampleRenderState; } - } - function translucentCompare(a, b, position) { - return b.boundingVolume.distanceSquaredTo(position) - a.boundingVolume.distanceSquaredTo(position); - } + var us = context.uniformState; + var sunPosition = us.sunPositionWC; + var viewMatrix = us.view; + var viewProjectionMatrix = us.viewProjection; + var projectionMatrix = us.projection; - function executeTranslucentCommandsSorted(scene, executeFunction, passState, commands, invertClassification) { - var context = scene.context; + // create up sampled render state + var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, postProcessMatrix4Scratch); + var sunPositionEC = Matrix4.multiplyByPoint(viewMatrix, sunPosition, sunPositionECScratch); + var sunPositionWC = Transforms.pointToGLWindowCoordinates(viewProjectionMatrix, viewportTransformation, sunPosition, sunPositionWCScratch); - mergeSort(commands, translucentCompare, scene._camera.positionWC); + sunPositionEC.x += CesiumMath.SOLAR_RADIUS; + var limbWC = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, sunPositionEC, sunPositionEC); + var sunSize = Cartesian2.magnitude(Cartesian2.subtract(limbWC, sunPositionWC, limbWC)) * 30.0 * 2.0; - if (defined(invertClassification)) { - executeFunction(invertClassification.unclassifiedCommand, scene, context, passState); - } + var size = sizeScratch; + size.x = sunSize; + size.y = sunSize; - var length = commands.length; - for (var j = 0; j < length; ++j) { - executeFunction(commands[j], scene, context, passState); - } - } + var scissorRectangle = this._upSamplePassState.scissorTest.rectangle; + scissorRectangle.x = Math.max(sunPositionWC.x - size.x * 0.5, 0.0); + scissorRectangle.y = Math.max(sunPositionWC.y - size.y * 0.5, 0.0); + scissorRectangle.width = Math.min(size.x, width); + scissorRectangle.height = Math.min(size.y, height); - function getDebugGlobeDepth(scene, index) { - var globeDepth = scene._debugGlobeDepths[index]; - if (!defined(globeDepth) && scene.context.depthTexture) { - globeDepth = new GlobeDepth(); - scene._debugGlobeDepths[index] = globeDepth; - } - return globeDepth; - } + this._uCenter = Cartesian2.clone(sunPositionWC, this._uCenter); + this._uRadius = Math.max(size.x, size.y) * 0.15; - function getPickDepth(scene, index) { - var pickDepth = scene._pickDepths[index]; - if (!defined(pickDepth)) { - pickDepth = new PickDepth(); - scene._pickDepths[index] = pickDepth; - } - return pickDepth; - } + // create down sampled render state + viewportTransformation = Matrix4.computeViewportTransformation(downSampleViewport, 0.0, 1.0, postProcessMatrix4Scratch); + sunPositionWC = Transforms.pointToGLWindowCoordinates(viewProjectionMatrix, viewportTransformation, sunPosition, sunPositionWCScratch); - var scratchPerspectiveFrustum = new PerspectiveFrustum(); - var scratchPerspectiveOffCenterFrustum = new PerspectiveOffCenterFrustum(); - var scratchOrthographicFrustum = new OrthographicFrustum(); - var scratchOrthographicOffCenterFrustum = new OrthographicOffCenterFrustum(); + size.x *= downSampleWidth / width; + size.y *= downSampleHeight / height; - function executeCommands(scene, passState) { - var camera = scene._camera; - var context = scene.context; - var us = context.uniformState; + scissorRectangle = this._downSamplePassState.scissorTest.rectangle; + scissorRectangle.x = Math.max(sunPositionWC.x - size.x * 0.5, 0.0); + scissorRectangle.y = Math.max(sunPositionWC.y - size.y * 0.5, 0.0); + scissorRectangle.width = Math.min(size.x, width); + scissorRectangle.height = Math.min(size.y, height); - us.updateCamera(camera); + this._downSamplePassState.context = context; + this._upSamplePassState.context = context; - // Create a working frustum from the original camera frustum. - var frustum; - if (defined(camera.frustum.fov)) { - frustum = camera.frustum.clone(scratchPerspectiveFrustum); - } else if (defined(camera.frustum.infiniteProjectionMatrix)){ - frustum = camera.frustum.clone(scratchPerspectiveOffCenterFrustum); - } else if (defined(camera.frustum.width)) { - frustum = camera.frustum.clone(scratchOrthographicFrustum); - } else { - frustum = camera.frustum.clone(scratchOrthographicOffCenterFrustum); - } + return this._fbo; + }; - // Ideally, we would render the sky box and atmosphere last for - // early-z, but we would have to draw it in each frustum - frustum.near = camera.frustum.near; - frustum.far = camera.frustum.far; - us.updateFrustum(frustum); - us.updatePass(Pass.ENVIRONMENT); + SunPostProcess.prototype.isDestroyed = function() { + return false; + }; - var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; - var passes = scene._frameState.passes; - var picking = passes.pick; - var depthOnly = passes.depth; - var environmentState = scene._environmentState; + SunPostProcess.prototype.destroy = function() { + this._fbo = this._fbo && this._fbo.destroy(); + this._downSampleFBO1 = this._downSampleFBO1 && this._downSampleFBO1.destroy(); + this._downSampleFBO2 = this._downSampleFBO2 && this._downSampleFBO2.destroy(); + this._downSampleCommand = this._downSampleCommand && this._downSampleCommand.shaderProgram && this._downSampleCommand.shaderProgram.destroy(); + this._brightPassCommand = this._brightPassCommand && this._brightPassCommand.shaderProgram && this._brightPassCommand.shaderProgram.destroy(); + this._blurXCommand = this._blurXCommand && this._blurXCommand.shaderProgram && this._blurXCommand.shaderProgram.destroy(); + this._blurYCommand = this._blurYCommand && this._blurYCommand.shaderProgram && this._blurYCommand.shaderProgram.destroy(); + this._blendCommand = this._blendCommand && this._blendCommand.shaderProgram && this._blendCommand.shaderProgram.destroy(); + this._fullScreenCommand = this._fullScreenCommand && this._fullScreenCommand.shaderProgram && this._fullScreenCommand.shaderProgram.destroy(); + return destroyObject(this); + }; - // Do not render environment primitives during a pick pass since they do not generate picking commands. - if (!picking) { - var skyBoxCommand = environmentState.skyBoxCommand; - if (defined(skyBoxCommand)) { - executeCommand(skyBoxCommand, scene, context, passState); - } + return SunPostProcess; +}); - if (environmentState.isSkyAtmosphereVisible) { - executeCommand(environmentState.skyAtmosphereCommand, scene, context, passState); - } +define('Scene/Scene',[ + '../Core/BoundingRectangle', + '../Core/BoundingSphere', + '../Core/BoxGeometry', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Cartographic', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', + '../Core/createGuid', + '../Core/CullingVolume', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/EllipsoidGeometry', + '../Core/Event', + '../Core/GeographicProjection', + '../Core/GeometryInstance', + '../Core/GeometryPipeline', + '../Core/getTimestamp', + '../Core/Intersect', + '../Core/Interval', + '../Core/JulianDate', + '../Core/Math', + '../Core/Matrix4', + '../Core/mergeSort', + '../Core/Occluder', + '../Core/OrthographicFrustum', + '../Core/OrthographicOffCenterFrustum', + '../Core/PerspectiveFrustum', + '../Core/PerspectiveOffCenterFrustum', + '../Core/PixelFormat', + '../Core/RequestScheduler', + '../Core/ShowGeometryInstanceAttribute', + '../Core/TaskProcessor', + '../Core/Transforms', + '../Renderer/ClearCommand', + '../Renderer/ComputeEngine', + '../Renderer/Context', + '../Renderer/ContextLimits', + '../Renderer/DrawCommand', + '../Renderer/Framebuffer', + '../Renderer/Pass', + '../Renderer/PassState', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/Texture', + './BrdfLutGenerator', + './Camera', + './CreditDisplay', + './DebugCameraPrimitive', + './DepthPlane', + './DeviceOrientationCameraController', + './Fog', + './FrameState', + './FrustumCommands', + './FXAA', + './GlobeDepth', + './InvertClassification', + './JobScheduler', + './MapMode2D', + './OIT', + './PerformanceDisplay', + './PerInstanceColorAppearance', + './PickDepth', + './Primitive', + './PrimitiveCollection', + './SceneMode', + './SceneTransforms', + './SceneTransitioner', + './ScreenSpaceCameraController', + './ShadowMap', + './SunPostProcess', + './TweenCollection' + ], function( + BoundingRectangle, + BoundingSphere, + BoxGeometry, + Cartesian2, + Cartesian3, + Cartesian4, + Cartographic, + Color, + ColorGeometryInstanceAttribute, + createGuid, + CullingVolume, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + EllipsoidGeometry, + Event, + GeographicProjection, + GeometryInstance, + GeometryPipeline, + getTimestamp, + Intersect, + Interval, + JulianDate, + CesiumMath, + Matrix4, + mergeSort, + Occluder, + OrthographicFrustum, + OrthographicOffCenterFrustum, + PerspectiveFrustum, + PerspectiveOffCenterFrustum, + PixelFormat, + RequestScheduler, + ShowGeometryInstanceAttribute, + TaskProcessor, + Transforms, + ClearCommand, + ComputeEngine, + Context, + ContextLimits, + DrawCommand, + Framebuffer, + Pass, + PassState, + PixelDatatype, + RenderState, + ShaderProgram, + ShaderSource, + Texture, + BrdfLutGenerator, + Camera, + CreditDisplay, + DebugCameraPrimitive, + DepthPlane, + DeviceOrientationCameraController, + Fog, + FrameState, + FrustumCommands, + FXAA, + GlobeDepth, + InvertClassification, + JobScheduler, + MapMode2D, + OIT, + PerformanceDisplay, + PerInstanceColorAppearance, + PickDepth, + Primitive, + PrimitiveCollection, + SceneMode, + SceneTransforms, + SceneTransitioner, + ScreenSpaceCameraController, + ShadowMap, + SunPostProcess, + TweenCollection) { + 'use strict'; - if (environmentState.isSunVisible) { - environmentState.sunDrawCommand.execute(context, passState); - if (scene.sunBloom && !useWebVR) { - var framebuffer; - if (environmentState.useGlobeDepthFramebuffer) { - framebuffer = scene._globeDepth.framebuffer; - } else if (environmentState.useFXAA) { - framebuffer = scene._fxaa.getColorFramebuffer(); - } else { - framebuffer = environmentState.originalFramebuffer; - } - scene._sunPostProcess.execute(context, framebuffer); - passState.framebuffer = framebuffer; - } - } + var requestRenderAfterFrame = function (scene) { + return function () { + scene.frameState.afterRender.push(function() { + scene.requestRender(); + }); + }; + }; - // Moon can be seen through the atmosphere, since the sun is rendered after the atmosphere. - if (environmentState.isMoonVisible) { - environmentState.moonCommand.execute(context, passState); - } - } + /** + * The container for all 3D graphical objects and state in a Cesium virtual scene. Generally, + * a scene is not created directly; instead, it is implicitly created by {@link CesiumWidget}. + * <p> + * <em><code>contextOptions</code> parameter details:</em> + * </p> + * <p> + * The default values are: + * <code> + * { + * webgl : { + * alpha : false, + * depth : true, + * stencil : false, + * antialias : true, + * premultipliedAlpha : true, + * preserveDrawingBuffer : false, + * failIfMajorPerformanceCaveat : false + * }, + * allowTextureFilterAnisotropic : true + * } + * </code> + * </p> + * <p> + * The <code>webgl</code> property corresponds to the {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} + * object used to create the WebGL context. + * </p> + * <p> + * <code>webgl.alpha</code> defaults to false, which can improve performance compared to the standard WebGL default + * of true. If an application needs to composite Cesium above other HTML elements using alpha-blending, set + * <code>webgl.alpha</code> to true. + * </p> + * <p> + * The other <code>webgl</code> properties match the WebGL defaults for {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes}. + * </p> + * <p> + * <code>allowTextureFilterAnisotropic</code> defaults to true, which enables anisotropic texture filtering when the + * WebGL extension is supported. Setting this to false will improve performance, but hurt visual quality, especially for horizon views. + * </p> + * + * @alias Scene + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Canvas} options.canvas The HTML canvas element to create the scene for. + * @param {Object} [options.contextOptions] Context and WebGL creation properties. See details above. + * @param {Element} [options.creditContainer] The HTML element in which the credits will be displayed. + * @param {Element} [options.creditViewport] The HTML element in which to display the credit popup. If not specified, the viewport will be a added as a sibling of the canvas. + * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes. + * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. + * @param {Boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View. + * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. + * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. + * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * + * @see CesiumWidget + * @see {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} + * + * @exception {DeveloperError} options and options.canvas are required. + * + * @example + * // Create scene without anisotropic texture filtering + * var scene = new Cesium.Scene({ + * canvas : canvas, + * contextOptions : { + * allowTextureFilterAnisotropic : false + * } + * }); + */ + function Scene(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var canvas = options.canvas; + var contextOptions = options.contextOptions; + var creditContainer = options.creditContainer; + var creditViewport = options.creditViewport; - // Determine how translucent surfaces will be handled. - var executeTranslucentCommands; - if (environmentState.useOIT) { - if (!defined(scene._executeOITFunction)) { - scene._executeOITFunction = function(scene, executeFunction, passState, commands, invertClassification) { - scene._oit.executeCommands(scene, executeFunction, passState, commands, invertClassification); - }; - } - executeTranslucentCommands = scene._executeOITFunction; - } else { - executeTranslucentCommands = executeTranslucentCommandsSorted; + if (!defined(canvas)) { + throw new DeveloperError('options and options.canvas are required.'); + } + var hasCreditContainer = defined(creditContainer); + var context = new Context(canvas, contextOptions); + if (!hasCreditContainer) { + creditContainer = document.createElement('div'); + creditContainer.style.position = 'absolute'; + creditContainer.style.bottom = '0'; + creditContainer.style['text-shadow'] = '0 0 2px #000000'; + creditContainer.style.color = '#ffffff'; + creditContainer.style['font-size'] = '10px'; + creditContainer.style['padding-right'] = '5px'; + canvas.parentNode.appendChild(creditContainer); + } + if (!defined(creditViewport)) { + creditViewport = canvas.parentNode; } - var clearGlobeDepth = environmentState.clearGlobeDepth; - var useDepthPlane = environmentState.useDepthPlane; - var clearDepth = scene._depthClearCommand; - var depthPlane = scene._depthPlane; - - var height2D = camera.position.z; + this._id = createGuid(); + this._jobScheduler = new JobScheduler(); + this._frameState = new FrameState(context, new CreditDisplay(creditContainer, ' • ', creditViewport), this._jobScheduler); + this._frameState.scene3DOnly = defaultValue(options.scene3DOnly, false); + this._removeCreditContainer = !hasCreditContainer; + this._creditContainer = creditContainer; - // Execute commands in each frustum in back to front order - var j; - var frustumCommandsList = scene._frustumCommandsList; - var numFrustums = frustumCommandsList.length; + var ps = new PassState(context); + ps.viewport = new BoundingRectangle(); + ps.viewport.x = 0; + ps.viewport.y = 0; + ps.viewport.width = context.drawingBufferWidth; + ps.viewport.height = context.drawingBufferHeight; + this._passState = ps; - for (var i = 0; i < numFrustums; ++i) { - var index = numFrustums - i - 1; - var frustumCommands = frustumCommandsList[index]; + this._canvas = canvas; + this._context = context; + this._computeEngine = new ComputeEngine(context); + this._globe = undefined; + this._primitives = new PrimitiveCollection(); + this._groundPrimitives = new PrimitiveCollection(); - if (scene.mode === SceneMode.SCENE2D) { - // To avoid z-fighting in 2D, move the camera to just before the frustum - // and scale the frustum depth to be in [1.0, nearToFarDistance2D]. - camera.position.z = height2D - frustumCommands.near + 1.0; - frustum.far = Math.max(1.0, frustumCommands.far - frustumCommands.near); - frustum.near = 1.0; - us.update(scene.frameState); - us.updateFrustum(frustum); - } else { - // Avoid tearing artifacts between adjacent frustums in the opaque passes - frustum.near = index !== 0 ? frustumCommands.near * OPAQUE_FRUSTUM_NEAR_OFFSET : frustumCommands.near; - frustum.far = frustumCommands.far; - us.updateFrustum(frustum); - } + this._tweens = new TweenCollection(); - var globeDepth = scene.debugShowGlobeDepth ? getDebugGlobeDepth(scene, index) : scene._globeDepth; + this._shaderFrameCount = 0; - var fb; - if (scene.debugShowGlobeDepth && defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) { - fb = passState.framebuffer; - passState.framebuffer = globeDepth.framebuffer; - } + this._sunPostProcess = undefined; - clearDepth.execute(context, passState); - scene._stencilClearCommand.execute(context, passState); + this._computeCommandList = []; + this._frustumCommandsList = []; + this._overlayCommandList = []; - us.updatePass(Pass.GLOBE); - var commands = frustumCommands.commands[Pass.GLOBE]; - var length = frustumCommands.indices[Pass.GLOBE]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } + this._pickFramebuffer = undefined; - if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer && (scene.copyGlobeDepth || scene.debugShowGlobeDepth)) { - globeDepth.update(context, passState); - globeDepth.executeCopyDepth(context, passState); - } + this._useOIT = defaultValue(options.orderIndependentTranslucency, true); + this._executeOITFunction = undefined; - if (scene.debugShowGlobeDepth && defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) { - passState.framebuffer = fb; - } + var globeDepth; + if (context.depthTexture) { + globeDepth = new GlobeDepth(); + } - us.updatePass(Pass.TERRAIN_CLASSIFICATION); - commands = frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION]; - length = frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } + var oit; + if (this._useOIT && defined(globeDepth)) { + oit = new OIT(context); + } - if (clearGlobeDepth) { - clearDepth.execute(context, passState); - } + this._globeDepth = globeDepth; + this._depthPlane = new DepthPlane(); + this._oit = oit; + this._fxaa = new FXAA(); - if (!environmentState.useInvertClassification || picking) { - // Common/fastest path. Draw 3D Tiles and classification normally. + this._clearColorCommand = new ClearCommand({ + color : new Color(), + stencil : 0, + owner : this + }); + this._depthClearCommand = new ClearCommand({ + depth : 1.0, + owner : this + }); + this._stencilClearCommand = new ClearCommand({ + stencil : 0 + }); - // Draw 3D Tiles - us.updatePass(Pass.CESIUM_3D_TILE); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } + this._pickDepths = []; + this._debugGlobeDepths = []; - // Draw classifications. Modifies 3D Tiles color. - us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } - } else { - // When the invert classification color is opaque: - // Main FBO (FBO1): Main_Color + Main_DepthStencil - // Invert classification FBO (FBO2) : Invert_Color + Main_DepthStencil - // - // 1. Clear FBO2 color to vec4(0.0) for each frustum - // 2. Draw 3D Tiles to FBO2 - // 3. Draw classification to FBO2 - // 4. Fullscreen pass to FBO1, draw Invert_Color when: - // * Main_DepthStencil has the stencil bit set > 0 (classified) - // 5. Fullscreen pass to FBO1, draw Invert_Color * czm_invertClassificationColor when: - // * Main_DepthStencil has stencil bit set to 0 (unclassified) and - // * Invert_Color !== vec4(0.0) - // - // When the invert classification color is translucent: - // Main FBO (FBO1): Main_Color + Main_DepthStencil - // Invert classification FBO (FBO2): Invert_Color + Invert_DepthStencil - // IsClassified FBO (FBO3): IsClassified_Color + Invert_DepthStencil - // - // 1. Clear FBO2 and FBO3 color to vec4(0.0), stencil to 0, and depth to 1.0 - // 2. Draw 3D Tiles to FBO2 - // 3. Draw classification to FBO2 - // 4. Fullscreen pass to FBO3, draw any color when - // * Invert_DepthStencil has the stencil bit set > 0 (classified) - // 5. Fullscreen pass to FBO1, draw Invert_Color when: - // * Invert_Color !== vec4(0.0) and - // * IsClassified_Color !== vec4(0.0) - // 6. Fullscreen pass to FBO1, draw Invert_Color * czm_invertClassificationColor when: - // * Invert_Color !== vec4(0.0) and - // * IsClassified_Color === vec4(0.0) - // - // NOTE: Step six when translucent invert color occurs after the TRANSLUCENT pass - // - scene._invertClassification.clear(context, passState); + this._pickDepthPassState = undefined; + this._pickDepthFramebuffer = undefined; + this._pickDepthFramebufferWidth = undefined; + this._pickDepthFramebufferHeight = undefined; + this._depthOnlyRenderStateCache = {}; - var opaqueClassificationFramebuffer = passState.framebuffer; - passState.framebuffer = scene._invertClassification._fbo; + this._transitioner = new SceneTransitioner(this); - // Draw normally - us.updatePass(Pass.CESIUM_3D_TILE); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } + this._preUpdate = new Event(); + this._postUpdate = new Event(); - // Set stencil - us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } + this._renderError = new Event(); + this._preRender = new Event(); + this._postRender = new Event(); - passState.framebuffer = opaqueClassificationFramebuffer; + this._cameraStartFired = false; + this._cameraMovedTime = undefined; - // Fullscreen pass to copy classified fragments - scene._invertClassification.executeClassified(context, passState); - if (scene.frameState.invertClassificationColor.alpha === 1.0) { - // Fullscreen pass to copy unclassified fragments when alpha == 1.0 - scene._invertClassification.executeUnclassified(context, passState); - } + this._pickPositionCache = {}; + this._pickPositionCacheDirty = false; - // Clear stencil set by the classification for the next classification pass - if (length > 0 && context.stencilBuffer) { - scene._stencilClearCommand.execute(context, passState); - } + this._minimumDisableDepthTestDistance = 0.0; - // Draw style over classification. - us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } - } + /** + * Exceptions occurring in <code>render</code> are always caught in order to raise the + * <code>renderError</code> event. If this property is true, the error is rethrown + * after the event is raised. If this property is false, the <code>render</code> function + * returns normally after raising the event. + * + * @type {Boolean} + * @default false + */ + this.rethrowRenderErrors = false; - if (length > 0 && context.stencilBuffer) { - scene._stencilClearCommand.execute(context, passState); - } + /** + * Determines whether or not to instantly complete the + * scene transition animation on user input. + * + * @type {Boolean} + * @default true + */ + this.completeMorphOnUserInput = true; - if (clearGlobeDepth && useDepthPlane) { - depthPlane.execute(context, passState); - } + /** + * The event fired at the beginning of a scene transition. + * @type {Event} + * @default Event() + */ + this.morphStart = new Event(); - // Execute commands in order by pass up to the translucent pass. - // Translucent geometry needs special handling (sorting/OIT). - var startPass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW + 1; - var endPass = Pass.TRANSLUCENT; - for (var pass = startPass; pass < endPass; ++pass) { - us.updatePass(pass); - commands = frustumCommands.commands[pass]; - length = frustumCommands.indices[pass]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } - } + /** + * The event fired at the completion of a scene transition. + * @type {Event} + * @default Event() + */ + this.morphComplete = new Event(); - if (index !== 0 && scene.mode !== SceneMode.SCENE2D) { - // Do not overlap frustums in the translucent pass to avoid blending artifacts - frustum.near = frustumCommands.near; - us.updateFrustum(frustum); - } + /** + * The {@link SkyBox} used to draw the stars. + * + * @type {SkyBox} + * @default undefined + * + * @see Scene#backgroundColor + */ + this.skyBox = undefined; - var invertClassification; - if (!picking && environmentState.useInvertClassification && scene.frameState.invertClassificationColor.alpha < 1.0) { - // Fullscreen pass to copy unclassified fragments when alpha < 1.0. - // Not executed when undefined. - invertClassification = scene._invertClassification; - } + /** + * The sky atmosphere drawn around the globe. + * + * @type {SkyAtmosphere} + * @default undefined + */ + this.skyAtmosphere = undefined; - us.updatePass(Pass.TRANSLUCENT); - commands = frustumCommands.commands[Pass.TRANSLUCENT]; - commands.length = frustumCommands.indices[Pass.TRANSLUCENT]; - executeTranslucentCommands(scene, executeCommand, passState, commands, invertClassification); + /** + * The {@link Sun}. + * + * @type {Sun} + * @default undefined + */ + this.sun = undefined; - if (defined(globeDepth) && (environmentState.useGlobeDepthFramebuffer || depthOnly) && scene.useDepthPicking) { - // PERFORMANCE_IDEA: Use MRT to avoid the extra copy. - var depthStencilTexture = depthOnly ? passState.framebuffer.depthStencilTexture : globeDepth.framebuffer.depthStencilTexture; - var pickDepth = getPickDepth(scene, index); - pickDepth.update(context, depthStencilTexture); - pickDepth.executeCopyDepth(context, passState); - } - } - } + /** + * Uses a bloom filter on the sun when enabled. + * + * @type {Boolean} + * @default true + */ + this.sunBloom = true; + this._sunBloom = undefined; - function executeComputeCommands(scene) { - var us = scene.context.uniformState; - us.updatePass(Pass.COMPUTE); + /** + * The {@link Moon} + * + * @type Moon + * @default undefined + */ + this.moon = undefined; - var sunComputeCommand = scene._environmentState.sunComputeCommand; - if (defined(sunComputeCommand)) { - sunComputeCommand.execute(scene._computeEngine); - } + /** + * The background color, which is only visible if there is no sky box, i.e., {@link Scene#skyBox} is undefined. + * + * @type {Color} + * @default {@link Color.BLACK} + * + * @see Scene#skyBox + */ + this.backgroundColor = Color.clone(Color.BLACK); - var commandList = scene._computeCommandList; - var length = commandList.length; - for (var i = 0; i < length; ++i) { - commandList[i].execute(scene._computeEngine); - } - } + this._mode = SceneMode.SCENE3D; - function executeOverlayCommands(scene, passState) { - var us = scene.context.uniformState; - us.updatePass(Pass.OVERLAY); + this._mapProjection = defined(options.mapProjection) ? options.mapProjection : new GeographicProjection(); - var context = scene.context; - var commandList = scene._overlayCommandList; - var length = commandList.length; - for (var i = 0; i < length; ++i) { - commandList[i].execute(context, passState); - } - } + /** + * The current morph transition time between 2D/Columbus View and 3D, + * with 0.0 being 2D or Columbus View and 1.0 being 3D. + * + * @type {Number} + * @default 1.0 + */ + this.morphTime = 1.0; + /** + * The far-to-near ratio of the multi-frustum. The default is 1,000.0. + * + * @type {Number} + * @default 1000.0 + */ + this.farToNearRatio = 1000.0; - function insertShadowCastCommands(scene, commandList, shadowMap) { - var shadowVolume = shadowMap.shadowMapCullingVolume; - var isPointLight = shadowMap.isPointLight; - var passes = shadowMap.passes; - var numberOfPasses = passes.length; + /** + * Determines the uniform depth size in meters of each frustum of the multifrustum in 2D. If a primitive or model close + * to the surface shows z-fighting, decreasing this will eliminate the artifact, but decrease performance. On the + * other hand, increasing this will increase performance but may cause z-fighting among primitives close to thesurface. + * @type {Number} + * @default 1.75e6 + */ + this.nearToFarDistance2D = 1.75e6; - var length = commandList.length; - for (var i = 0; i < length; ++i) { - var command = commandList[i]; - updateDerivedCommands(scene, command); + /** + * This property is for debugging only; it is not for production use. + * <p> + * A function that determines what commands are executed. As shown in the examples below, + * the function receives the command's <code>owner</code> as an argument, and returns a boolean indicating if the + * command should be executed. + * </p> + * <p> + * The default is <code>undefined</code>, indicating that all commands are executed. + * </p> + * + * @type Function + * + * @default undefined + * + * @example + * // Do not execute any commands. + * scene.debugCommandFilter = function(command) { + * return false; + * }; + * + * // Execute only the billboard's commands. That is, only draw the billboard. + * var billboards = new Cesium.BillboardCollection(); + * scene.debugCommandFilter = function(command) { + * return command.owner === billboards; + * }; + */ + this.debugCommandFilter = undefined; - if (command.castShadows && (command.pass === Pass.GLOBE || command.pass === Pass.CESIUM_3D_TILE || command.pass === Pass.OPAQUE || command.pass === Pass.TRANSLUCENT)) { - if (isVisible(command, shadowVolume)) { - if (isPointLight) { - for (var k = 0; k < numberOfPasses; ++k) { - passes[k].commandList.push(command); - } - } else if (numberOfPasses === 1) { - passes[0].commandList.push(command); - } else { - var wasVisible = false; - // Loop over cascades from largest to smallest - for (var j = numberOfPasses - 1; j >= 0; --j) { - var cascadeVolume = passes[j].cullingVolume; - if (isVisible(command, cascadeVolume)) { - passes[j].commandList.push(command); - wasVisible = true; - } else if (wasVisible) { - // If it was visible in the previous cascade but now isn't - // then there is no need to check any more cascades - break; - } - } - } - } - } - } - } + /** + * This property is for debugging only; it is not for production use. + * <p> + * When <code>true</code>, commands are randomly shaded. This is useful + * for performance analysis to see what parts of a scene or model are + * command-dense and could benefit from batching. + * </p> + * + * @type Boolean + * + * @default false + */ + this.debugShowCommands = false; - function executeShadowMapCastCommands(scene) { - var frameState = scene.frameState; - var shadowMaps = frameState.shadowHints.shadowMaps; - var shadowMapLength = shadowMaps.length; + /** + * This property is for debugging only; it is not for production use. + * <p> + * When <code>true</code>, commands are shaded based on the frustums they + * overlap. Commands in the closest frustum are tinted red, commands in + * the next closest are green, and commands in the farthest frustum are + * blue. If a command overlaps more than one frustum, the color components + * are combined, e.g., a command overlapping the first two frustums is tinted + * yellow. + * </p> + * + * @type Boolean + * + * @default false + */ + this.debugShowFrustums = false; - if (!frameState.shadowHints.shadowsEnabled) { - return; - } + this._debugFrustumStatistics = undefined; - var context = scene.context; - var uniformState = context.uniformState; + /** + * This property is for debugging only; it is not for production use. + * <p> + * Displays frames per second and time between frames. + * </p> + * + * @type Boolean + * + * @default false + */ + this.debugShowFramesPerSecond = false; - for (var i = 0; i < shadowMapLength; ++i) { - var shadowMap = shadowMaps[i]; - if (shadowMap.outOfView) { - continue; - } + /** + * This property is for debugging only; it is not for production use. + * <p> + * Displays depth information for the indicated frustum. + * </p> + * + * @type Boolean + * + * @default false + */ + this.debugShowGlobeDepth = false; - // Reset the command lists - var j; - var passes = shadowMap.passes; - var numberOfPasses = passes.length; - for (j = 0; j < numberOfPasses; ++j) { - passes[j].commandList.length = 0; - } + /** + * This property is for debugging only; it is not for production use. + * <p> + * Indicates which frustum will have depth information displayed. + * </p> + * + * @type Number + * + * @default 1 + */ + this.debugShowDepthFrustum = 1; - // Insert the primitive/model commands into the command lists - var sceneCommands = scene.frameState.commandList; - insertShadowCastCommands(scene, sceneCommands, shadowMap); + /** + * This property is for debugging only; it is not for production use. + * <p> + * When <code>true</code>, draws outlines to show the boundaries of the camera frustums + * </p> + * + * @type Boolean + * + * @default false + */ + this.debugShowFrustumPlanes = false; + this._debugShowFrustumPlanes = false; + this._debugFrustumPlanes = undefined; - for (j = 0; j < numberOfPasses; ++j) { - var pass = shadowMap.passes[j]; - uniformState.updateCamera(pass.camera); - shadowMap.updatePass(context, j); - var numberOfCommands = pass.commandList.length; - for (var k = 0; k < numberOfCommands; ++k) { - var command = pass.commandList[k]; - // Set the correct pass before rendering into the shadow map because some shaders - // conditionally render based on whether the pass is translucent or opaque. - uniformState.updatePass(command.pass); - executeCommand(command.derivedCommands.shadows.castCommands[i], scene, context, pass.passState); - } - } - } - } + /** + * When <code>true</code>, enables Fast Approximate Anti-aliasing even when order independent translucency + * is unsupported. + * + * @type Boolean + * @default true + */ + this.fxaa = true; - var scratchEyeTranslation = new Cartesian3(); + /** + * When <code>true</code>, enables picking using the depth buffer. + * + * @type Boolean + * @default true + */ + this.useDepthPicking = true; - function updateAndExecuteCommands(scene, passState, backgroundColor) { - var context = scene._context; + /** + * When <code>true</code>, enables picking translucent geometry using the depth buffer. + * {@link Scene#useDepthPicking} must also be true to enable picking the depth buffer. + * <p> + * There is a decrease in performance when enabled. There are extra draw calls to write depth for + * translucent geometry. + * </p> + * @type {Boolean} + * @default false + */ + this.pickTranslucentDepth = false; - var viewport = passState.viewport; - viewport.x = 0; - viewport.y = 0; - viewport.width = context.drawingBufferWidth; - viewport.height = context.drawingBufferHeight; + /** + * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. + * @type {Number} + * @default 500.0 + * @private + */ + this.cameraEventWaitTime = 500.0; - var frameState = scene._frameState; - var camera = frameState.camera; - var mode = frameState.mode; - var depthOnly = frameState.passes.depth; + /** + * Set to true to copy the depth texture after rendering the globe. Makes czm_globeDepthTexture valid. + * @type {Boolean} + * @default false + * @private + */ + this.copyGlobeDepth = false; - if (scene._useWebVR && mode !== SceneMode.SCENE2D) { - updateAndClearFramebuffers(scene, passState, backgroundColor); + /** + * Blends the atmosphere to geometry far from the camera for horizon views. Allows for additional + * performance improvements by rendering less geometry and dispatching less terrain requests. + * @type {Fog} + */ + this.fog = new Fog(); - if (!depthOnly) { - updatePrimitives(scene); - } + this._sunCamera = new Camera(this); - createPotentiallyVisibleSet(scene); + /** + * The shadow map in the scene. When enabled, models, primitives, and the globe may cast and receive shadows. + * By default the light source of the shadow map is the sun. + * @type {ShadowMap} + */ + this.shadowMap = new ShadowMap({ + context : context, + lightCamera : this._sunCamera, + enabled : defaultValue(options.shadows, false) + }); - if (!depthOnly) { - executeComputeCommands(scene); - executeShadowMapCastCommands(scene); - } + /** + * When <code>false</code>, 3D Tiles will render normally. When <code>true</code>, classified 3D Tile geometry will render normally and + * unclassified 3D Tile geometry will render with the color multiplied by {@link Scene#invertClassificationColor}. + * @type {Boolean} + * @default false + */ + this.invertClassification = false; - // Based on Calculating Stereo pairs by Paul Bourke - // http://paulbourke.net/stereographics/stereorender/ + /** + * The highlight color of unclassified 3D Tile geometry when {@link Scene#invertClassification} is <code>true</code>. + * <p>When the color's alpha is less than 1.0, the unclassified portions of the 3D Tiles will not blend correctly with the classified positions of the 3D Tiles.</p> + * <p>Also, when the color's alpha is less than 1.0, the WEBGL_depth_texture and EXT_frag_depth WebGL extensions must be supported.</p> + * @type {Color} + * @default Color.WHITE + */ + this.invertClassificationColor = Color.clone(Color.WHITE); - viewport.x = 0; - viewport.y = 0; - viewport.width = context.drawingBufferWidth * 0.5; - viewport.height = context.drawingBufferHeight; + this._actualInvertClassificationColor = Color.clone(this._invertClassificationColor); + this._invertClassification = new InvertClassification(); - var savedCamera = Camera.clone(camera, scene._cameraVR); + /** + * The focal length for use when with cardboard or WebVR. + * @type {Number} + */ + this.focalLength = undefined; - var near = camera.frustum.near; - var fo = near * defaultValue(scene.focalLength, 5.0); - var eyeSeparation = defaultValue(scene.eyeSeparation, fo / 30.0); - var eyeTranslation = Cartesian3.multiplyByScalar(savedCamera.right, eyeSeparation * 0.5, scratchEyeTranslation); + /** + * The eye separation distance in meters for use with cardboard or WebVR. + * @type {Number} + */ + this.eyeSeparation = undefined; - camera.frustum.aspectRatio = viewport.width / viewport.height; + this._brdfLutGenerator = new BrdfLutGenerator(); - var offset = 0.5 * eyeSeparation * near / fo; + this._terrainExaggeration = defaultValue(options.terrainExaggeration, 1.0); - Cartesian3.add(savedCamera.position, eyeTranslation, camera.position); - camera.frustum.xOffset = offset; + this._performanceDisplay = undefined; + this._debugVolume = undefined; - executeCommands(scene, passState); + var camera = new Camera(this); + this._camera = camera; + this._cameraClone = Camera.clone(camera); + this._screenSpaceCameraController = new ScreenSpaceCameraController(this); + this._mapMode2D = defaultValue(options.mapMode2D, MapMode2D.INFINITE_SCROLL); - viewport.x = passState.viewport.width; + // Keeps track of the state of a frame. FrameState is the state across + // the primitives of the scene. This state is for internally keeping track + // of celestial and environment effects that need to be updated/rendered in + // a certain order as well as updating/tracking framebuffer usage. + this._environmentState = { + skyBoxCommand : undefined, + skyAtmosphereCommand : undefined, + sunDrawCommand : undefined, + sunComputeCommand : undefined, + moonCommand : undefined, - Cartesian3.subtract(savedCamera.position, eyeTranslation, camera.position); - camera.frustum.xOffset = -offset; + isSunVisible : false, + isMoonVisible : false, + isReadyForAtmosphere : false, + isSkyAtmosphereVisible : false, - executeCommands(scene, passState); + clearGlobeDepth : false, + useDepthPlane : false, - Camera.clone(savedCamera, camera); - } else if (mode !== SceneMode.SCENE2D || scene._mapMode2D === MapMode2D.ROTATE) { - executeCommandsInViewport(true, scene, passState, backgroundColor); - } else { - updateAndClearFramebuffers(scene, passState, backgroundColor); - execute2DViewportCommands(scene, passState); - } - } + originalFramebuffer : undefined, + useGlobeDepthFramebuffer : false, + useOIT : false, + useFXAA : false, + useInvertClassification : false + }; - var scratch2DViewportCartographic = new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO); - var scratch2DViewportMaxCoord = new Cartesian3(); - var scratch2DViewportSavedPosition = new Cartesian3(); - var scratch2DViewportTransform = new Matrix4(); - var scratch2DViewportCameraTransform = new Matrix4(); - var scratch2DViewportEyePoint = new Cartesian3(); - var scratch2DViewportWindowCoords = new Cartesian3(); - var scratch2DViewport = new BoundingRectangle(); + this._useWebVR = false; + this._cameraVR = undefined; + this._aspectRatioVR = undefined; - function execute2DViewportCommands(scene, passState) { - var context = scene.context; - var frameState = scene.frameState; - var camera = scene.camera; + /** + * When <code>true</code>, rendering a frame will only occur when needed as determined by changes within the scene. + * Enabling improves performance of the application, but requires using {@link Scene#requestRender} + * to render a new frame explicitly in this mode. This will be necessary in many cases after making changes + * to the scene in other parts of the API. + * + * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} + * @see Scene#maximumRenderTimeChange + * @see Scene#requestRender + * + * @type {Boolean} + * @default false + */ + this.requestRenderMode = defaultValue(options.requestRenderMode, false); + this._renderRequested = true; - var originalViewport = passState.viewport; - var viewport = BoundingRectangle.clone(originalViewport, scratch2DViewport); - passState.viewport = viewport; + /** + * If {@link Scene#requestRenderMode} is <code>true</code>, this value defines the maximum change in + * simulation time allowed before a render is requested. Lower values increase the number of frames rendered + * and higher values decrease the number of frames rendered. If <code>undefined</code>, changes to + * the simulation time will never request a render. + * This value impacts the rate of rendering for changes in the scene like lighting, entity property updates, + * and animations. + * + * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} + * @see Scene#requestRenderMode + * + * @type {Number} + * @default 0.5 + */ + this.maximumRenderTimeChange = defaultValue(options.maximumRenderTimeChange, 0.0); + this._lastRenderTime = undefined; - var maxCartographic = scratch2DViewportCartographic; - var maxCoord = scratch2DViewportMaxCoord; + this._removeRequestListenerCallback = RequestScheduler.requestCompletedEvent.addEventListener(requestRenderAfterFrame(this)); + this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(requestRenderAfterFrame(this)); + this._removeGlobeCallbacks = []; - var projection = scene.mapProjection; - projection.project(maxCartographic, maxCoord); + // initial guess at frustums. + var near = camera.frustum.near; + var far = camera.frustum.far; + var numFrustums = Math.ceil(Math.log(far / near) / Math.log(this.farToNearRatio)); + updateFrustums(near, far, this.farToNearRatio, numFrustums, this._frustumCommandsList, false, undefined); - var position = Cartesian3.clone(camera.position, scratch2DViewportSavedPosition); - var transform = Matrix4.clone(camera.transform, scratch2DViewportCameraTransform); - var frustum = camera.frustum.clone(); + // give frameState, camera, and screen space camera controller initial state before rendering + updateFrameState(this, 0.0, JulianDate.now()); + this.initializeFrame(); + } - camera._setTransform(Matrix4.IDENTITY); + var OPAQUE_FRUSTUM_NEAR_OFFSET = 0.9999; - var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, scratch2DViewportTransform); - var projectionMatrix = camera.frustum.projectionMatrix; + function updateGlobeListeners(scene, globe) { + for (var i = 0; i < scene._removeGlobeCallbacks.length; ++i) { + scene._removeGlobeCallbacks[i](); + } + scene._removeGlobeCallbacks.length = 0; - var x = camera.positionWC.y; - var eyePoint = Cartesian3.fromElements(CesiumMath.sign(x) * maxCoord.x - x, 0.0, -camera.positionWC.x, scratch2DViewportEyePoint); - var windowCoordinates = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, eyePoint, scratch2DViewportWindowCoords); + var removeGlobeCallbacks = []; + if (defined(globe)) { + removeGlobeCallbacks.push(globe.tileLoadedEvent.addEventListener(requestRenderAfterFrame(scene))); + removeGlobeCallbacks.push(globe.imageryLayersUpdatedEvent.addEventListener(requestRenderAfterFrame(scene))); + } + scene._removeGlobeCallbacks = removeGlobeCallbacks; + } - windowCoordinates.x = Math.floor(windowCoordinates.x); + defineProperties(Scene.prototype, { + /** + * Gets the canvas element to which this scene is bound. + * @memberof Scene.prototype + * + * @type {Canvas} + * @readonly + */ + canvas : { + get : function() { + return this._canvas; + } + }, - var viewportX = viewport.x; - var viewportWidth = viewport.width; + /** + * The drawingBufferWidth of the underlying GL context. + * @memberof Scene.prototype + * + * @type {Number} + * @readonly + * + * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferWidth|drawingBufferWidth} + */ + drawingBufferHeight : { + get : function() { + return this._context.drawingBufferHeight; + } + }, - if (x === 0.0 || windowCoordinates.x <= viewportX || windowCoordinates.x >= viewportX + viewportWidth) { - executeCommandsInViewport(true, scene, passState); - } else if (Math.abs(viewportX + viewportWidth * 0.5 - windowCoordinates.x) < 1.0) { - viewport.width = windowCoordinates.x - viewport.x; + /** + * The drawingBufferHeight of the underlying GL context. + * @memberof Scene.prototype + * + * @type {Number} + * @readonly + * + * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} + */ + drawingBufferWidth : { + get : function() { + return this._context.drawingBufferWidth; + } + }, - camera.position.x *= CesiumMath.sign(camera.position.x); + /** + * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. + * @memberof Scene.prototype + * + * @type {Number} + * @readonly + * + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. + */ + maximumAliasedLineWidth : { + get : function() { + return ContextLimits.maximumAliasedLineWidth; + } + }, - camera.frustum.right = 0.0; + /** + * The maximum length in pixels of one edge of a cube map, supported by this WebGL implementation. It will be at least 16. + * @memberof Scene.prototype + * + * @type {Number} + * @readonly + * + * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>GL_MAX_CUBE_MAP_TEXTURE_SIZE</code>. + */ + maximumCubeMapSize : { + get : function() { + return ContextLimits.maximumCubeMapSize; + } + }, - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - context.uniformState.update(frameState); + /** + * Returns true if the pickPosition function is supported. + * @memberof Scene.prototype + * + * @type {Boolean} + * @readonly + */ + pickPositionSupported : { + get : function() { + return this._context.depthTexture; + } + }, - executeCommandsInViewport(true, scene, passState); + /** + * Gets or sets the depth-test ellipsoid. + * @memberof Scene.prototype + * + * @type {Globe} + */ + globe : { + get: function() { + return this._globe; + }, - viewport.x = windowCoordinates.x; + set: function(globe) { + this._globe = this._globe && this._globe.destroy(); + this._globe = globe; - camera.position.x = -camera.position.x; + updateGlobeListeners(this, globe); + } + }, - camera.frustum.right = -camera.frustum.left; - camera.frustum.left = 0.0; + /** + * Gets the collection of primitives. + * @memberof Scene.prototype + * + * @type {PrimitiveCollection} + * @readonly + */ + primitives : { + get : function() { + return this._primitives; + } + }, - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - context.uniformState.update(frameState); + /** + * Gets the collection of ground primitives. + * @memberof Scene.prototype + * + * @type {PrimitiveCollection} + * @readonly + */ + groundPrimitives : { + get : function() { + return this._groundPrimitives; + } + }, - executeCommandsInViewport(false, scene, passState); - } else if (windowCoordinates.x > viewportX + viewportWidth * 0.5) { - viewport.width = windowCoordinates.x - viewportX; + /** + * Gets the camera. + * @memberof Scene.prototype + * + * @type {Camera} + * @readonly + */ + camera : { + get : function() { + return this._camera; + } + }, + // TODO: setCamera - var right = camera.frustum.right; - camera.frustum.right = maxCoord.x - x; + /** + * Gets the controller for camera input handling. + * @memberof Scene.prototype + * + * @type {ScreenSpaceCameraController} + * @readonly + */ + screenSpaceCameraController : { + get : function() { + return this._screenSpaceCameraController; + } + }, - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - context.uniformState.update(frameState); + /** + * Get the map projection to use in 2D and Columbus View modes. + * @memberof Scene.prototype + * + * @type {MapProjection} + * @readonly + * + * @default new GeographicProjection() + */ + mapProjection : { + get: function() { + return this._mapProjection; + } + }, - executeCommandsInViewport(true, scene, passState); + /** + * Gets state information about the current scene. If called outside of a primitive's <code>update</code> + * function, the previous frame's state is returned. + * @memberof Scene.prototype + * + * @type {FrameState} + * @readonly + * + * @private + */ + frameState : { + get: function() { + return this._frameState; + } + }, - viewport.x = windowCoordinates.x; - viewport.width = viewportX + viewportWidth - windowCoordinates.x; + /** + * Gets the collection of tweens taking place in the scene. + * @memberof Scene.prototype + * + * @type {TweenCollection} + * @readonly + * + * @private + */ + tweens : { + get : function() { + return this._tweens; + } + }, - camera.position.x = -camera.position.x; + /** + * Gets the collection of image layers that will be rendered on the globe. + * @memberof Scene.prototype + * + * @type {ImageryLayerCollection} + * @readonly + */ + imageryLayers : { + get : function() { + if (!defined(this.globe)) { + return undefined; + } - camera.frustum.left = -camera.frustum.right; - camera.frustum.right = right - camera.frustum.right * 2.0; + return this.globe.imageryLayers; + } + }, - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - context.uniformState.update(frameState); + /** + * The terrain provider providing surface geometry for the globe. + * @memberof Scene.prototype + * + * @type {TerrainProvider} + */ + terrainProvider : { + get : function() { + if (!defined(this.globe)) { + return undefined; + } - executeCommandsInViewport(false, scene, passState); - } else { - viewport.x = windowCoordinates.x; - viewport.width = viewportX + viewportWidth - windowCoordinates.x; + return this.globe.terrainProvider; + }, + set : function(terrainProvider) { + if (defined(this.globe)) { + this.globe.terrainProvider = terrainProvider; + } + } + }, - var left = camera.frustum.left; - camera.frustum.left = -maxCoord.x - x; + /** + * Gets an event that's raised when the terrain provider is changed + * @memberof Scene.prototype + * + * @type {Event} + * @readonly + */ + terrainProviderChanged : { + get : function() { + if (!defined(this.globe)) { + return undefined; + } - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - context.uniformState.update(frameState); + return this.globe.terrainProviderChanged; + } + }, - executeCommandsInViewport(true, scene, passState); + /** + * Gets the event that will be raised before the scene is updated or rendered. Subscribers to the event + * receive the Scene instance as the first parameter and the current time as the second parameter. + * @memberof Scene.prototype + * + * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} + * @see Scene#postUpdate + * @see Scene#preRender + * @see Scene#postRender + * + * @type {Event} + * @readonly + */ + preUpdate : { + get : function() { + return this._preUpdate; + } + }, - viewport.x = viewportX; - viewport.width = windowCoordinates.x - viewportX; + /** + * Gets the event that will be raised immediately after the scene is updated and before the scene is rendered. + * Subscribers to the event receive the Scene instance as the first parameter and the current time as the second + * parameter. + * @memberof Scene.prototype + * + * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} + * @see Scene#preUpdate + * @see Scene#preRender + * @see Scene#postRender + * + * @type {Event} + * @readonly + */ + postUpdate : { + get : function() { + return this._postUpdate; + } + }, - camera.position.x = -camera.position.x; + /** + * Gets the event that will be raised when an error is thrown inside the <code>render</code> function. + * The Scene instance and the thrown error are the only two parameters passed to the event handler. + * By default, errors are not rethrown after this event is raised, but that can be changed by setting + * the <code>rethrowRenderErrors</code> property. + * @memberof Scene.prototype + * + * @type {Event} + * @readonly + */ + renderError : { + get : function() { + return this._renderError; + } + }, - camera.frustum.right = -camera.frustum.left; - camera.frustum.left = left - camera.frustum.left * 2.0; + /** + * Gets the event that will be raised after the scene is updated and immediately before the scene is rendered. + * Subscribers to the event receive the Scene instance as the first parameter and the current time as the second + * parameter. + * @memberof Scene.prototype + * + * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} + * @see Scene#preUpdate + * @see Scene#postUpdate + * @see Scene#postRender + * + * @type {Event} + * @readonly + */ + preRender : { + get : function() { + return this._preRender; + } + }, - frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - context.uniformState.update(frameState); + /** + * Gets the event that will be raised immediately after the scene is rendered. Subscribers to the event + * receive the Scene instance as the first parameter and the current time as the second parameter. + * @memberof Scene.prototype + * + * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} + * @see Scene#preUpdate + * @see Scene#postUpdate + * @see Scene#postRender + * + * @type {Event} + * @readonly + */ + postRender : { + get : function() { + return this._postRender; + } + }, - executeCommandsInViewport(false, scene, passState); - } + /** + * Gets the simulation time when the scene was last rendered. Returns undefined if the scene has not yet been + * rendered. + * @memberof Scene.prototype + * + * @type {JulianDate} + * @readonly + */ + lastRenderTime : { + get : function() { + return this._lastRenderTime; + } + }, - camera._setTransform(transform); - Cartesian3.clone(position, camera.position); - camera.frustum = frustum.clone(); - passState.viewport = originalViewport; - } + /** + * @memberof Scene.prototype + * @private + * @readonly + */ + context : { + get : function() { + return this._context; + } + }, - function executeCommandsInViewport(firstViewport, scene, passState, backgroundColor) { - var depthOnly = scene.frameState.passes.depth; + /** + * This property is for debugging only; it is not for production use. + * <p> + * When {@link Scene.debugShowFrustums} is <code>true</code>, this contains + * properties with statistics about the number of command execute per frustum. + * <code>totalCommands</code> is the total number of commands executed, ignoring + * overlap. <code>commandsInFrustums</code> is an array with the number of times + * commands are executed redundantly, e.g., how many commands overlap two or + * three frustums. + * </p> + * + * @memberof Scene.prototype + * + * @type {Object} + * @readonly + * + * @default undefined + */ + debugFrustumStatistics : { + get : function() { + return this._debugFrustumStatistics; + } + }, - if (!firstViewport && !depthOnly) { - scene.frameState.commandList.length = 0; - } + /** + * Gets whether or not the scene is optimized for 3D only viewing. + * @memberof Scene.prototype + * @type {Boolean} + * @readonly + */ + scene3DOnly : { + get : function() { + return this._frameState.scene3DOnly; + } + }, - if (!depthOnly) { - updatePrimitives(scene); - } + /** + * Gets whether or not the scene has order independent translucency enabled. + * Note that this only reflects the original construction option, and there are + * other factors that could prevent OIT from functioning on a given system configuration. + * @memberof Scene.prototype + * @type {Boolean} + * @readonly + */ + orderIndependentTranslucency : { + get : function() { + return defined(this._oit); + } + }, - createPotentiallyVisibleSet(scene); + /** + * Gets the unique identifier for this scene. + * @memberof Scene.prototype + * @type {String} + * @readonly + */ + id : { + get : function() { + return this._id; + } + }, - if (firstViewport) { - if (defined(backgroundColor)) { - updateAndClearFramebuffers(scene, passState, backgroundColor); + /** + * Gets or sets the current mode of the scene. + * @memberof Scene.prototype + * @type {SceneMode} + * @default {@link SceneMode.SCENE3D} + */ + mode : { + get : function() { + return this._mode; + }, + set : function(value) { + if (this.scene3DOnly && value !== SceneMode.SCENE3D) { + throw new DeveloperError('Only SceneMode.SCENE3D is valid when scene3DOnly is true.'); + } + if (value === SceneMode.SCENE2D) { + this.morphTo2D(0); + } else if (value === SceneMode.SCENE3D) { + this.morphTo3D(0); + } else if (value === SceneMode.COLUMBUS_VIEW) { + this.morphToColumbusView(0); + } else { + throw new DeveloperError('value must be a valid SceneMode enumeration.'); + } + this._mode = value; } - if (!depthOnly) { - executeComputeCommands(scene); - executeShadowMapCastCommands(scene); + }, + + /** + * Gets the number of frustums used in the last frame. + * @memberof Scene.prototype + * @type {Number} + * + * @private + */ + numberOfFrustums : { + get : function() { + return this._frustumCommandsList.length; } - } + }, - executeCommands(scene, passState); - } + /** + * Gets the scalar used to exaggerate the terrain. + * @memberof Scene.prototype + * @type {Number} + */ + terrainExaggeration : { + get : function() { + return this._terrainExaggeration; + } + }, - function updateEnvironment(scene, passState) { - var frameState = scene._frameState; + /** + * When <code>true</code>, splits the scene into two viewports with steroscopic views for the left and right eyes. + * Used for cardboard and WebVR. + * @memberof Scene.prototype + * @type {Boolean} + * @default false + */ + useWebVR : { + get : function() { + return this._useWebVR; + }, + set : function(value) { + if (this.camera.frustum instanceof OrthographicFrustum) { + throw new DeveloperError('VR is unsupported with an orthographic projection.'); + } + this._useWebVR = value; + if (this._useWebVR) { + this._frameState.creditDisplay.container.style.visibility = 'hidden'; + this._cameraVR = new Camera(this); + if (!defined(this._deviceOrientationCameraController)) { + this._deviceOrientationCameraController = new DeviceOrientationCameraController(this); + } - // Update celestial and terrestrial environment effects. - var environmentState = scene._environmentState; - var renderPass = frameState.passes.render; - var skyAtmosphere = scene.skyAtmosphere; - var globe = scene.globe; + this._aspectRatioVR = this._camera.frustum.aspectRatio; + } else { + this._frameState.creditDisplay.container.style.visibility = 'visible'; + this._cameraVR = undefined; + this._deviceOrientationCameraController = this._deviceOrientationCameraController && !this._deviceOrientationCameraController.isDestroyed() && this._deviceOrientationCameraController.destroy(); - if (!renderPass || (scene._mode !== SceneMode.SCENE2D && frameState.camera.frustum instanceof OrthographicFrustum)) { - environmentState.skyAtmosphereCommand = undefined; - environmentState.skyBoxCommand = undefined; - environmentState.sunDrawCommand = undefined; - environmentState.sunComputeCommand = undefined; - environmentState.moonCommand = undefined; - } else { - if (defined(skyAtmosphere) && defined(globe)) { - skyAtmosphere.setDynamicAtmosphereColor(globe.enableLighting); - environmentState.isReadyForAtmosphere = environmentState.isReadyForAtmosphere || globe._surface._tilesToRender.length > 0; + this._camera.frustum.aspectRatio = this._aspectRatioVR; + this._camera.frustum.xOffset = 0.0; + } } - environmentState.skyAtmosphereCommand = defined(skyAtmosphere) ? skyAtmosphere.update(frameState) : undefined; - environmentState.skyBoxCommand = defined(scene.skyBox) ? scene.skyBox.update(frameState) : undefined; - var sunCommands = defined(scene.sun) ? scene.sun.update(frameState, passState) : undefined; - environmentState.sunDrawCommand = defined(sunCommands) ? sunCommands.drawCommand : undefined; - environmentState.sunComputeCommand = defined(sunCommands) ? sunCommands.computeCommand : undefined; - environmentState.moonCommand = defined(scene.moon) ? scene.moon.update(frameState) : undefined; - } + }, - var clearGlobeDepth = environmentState.clearGlobeDepth = defined(globe) && (!globe.depthTestAgainstTerrain || scene.mode === SceneMode.SCENE2D); - var useDepthPlane = environmentState.useDepthPlane = clearGlobeDepth && scene.mode === SceneMode.SCENE3D; - if (useDepthPlane) { - // Update the depth plane that is rendered in 3D when the primitives are - // not depth tested against terrain so primitives on the backface - // of the globe are not picked. - scene._depthPlane.update(frameState); - } + /** + * Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @memberof Scene.prototype + * @type {Boolean} + */ + mapMode2D : { + get : function() { + return this._mapMode2D; + } + }, - var occluder = (frameState.mode === SceneMode.SCENE3D) ? frameState.occluder: undefined; - var cullingVolume = frameState.cullingVolume; + /** + * Gets or sets the position of the Imagery splitter within the viewport. Valid values are between 0.0 and 1.0. + * @memberof Scene.prototype + * + * @type {Number} + */ + imagerySplitPosition : { + get: function() { + return this._frameState.imagerySplitPosition; + }, + set: function(value) { + this._frameState.imagerySplitPosition = value; + } + }, - // get user culling volume minus the far plane. - var planes = scratchCullingVolume.planes; - for (var k = 0; k < 5; ++k) { - planes[k] = cullingVolume.planes[k]; + /** + * The distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always + * be applied. When less than zero, the depth test should never be applied. Setting the disableDepthTestDistance + * property of a billboard, label or point will override this value. + * @memberof Scene.prototype + * @type {Number} + * @default 0.0 + */ + minimumDisableDepthTestDistance : { + get : function() { + return this._minimumDisableDepthTestDistance; + }, + set : function(value) { + if (!defined(value) || value < 0.0) { + throw new DeveloperError('minimumDisableDepthTestDistance must be greater than or equal to 0.0.'); + } + this._minimumDisableDepthTestDistance = value; + } } - cullingVolume = scratchCullingVolume; + }); - // Determine visibility of celestial and terrestrial environment effects. - environmentState.isSkyAtmosphereVisible = defined(environmentState.skyAtmosphereCommand) && environmentState.isReadyForAtmosphere; - environmentState.isSunVisible = isVisible(environmentState.sunDrawCommand, cullingVolume, occluder); - environmentState.isMoonVisible = isVisible(environmentState.moonCommand, cullingVolume, occluder); - } + /** + * Determines if a compressed texture format is supported. + * @param {String} format The texture format. May be the name of the format or the WebGL extension name, e.g. s3tc or WEBGL_compressed_texture_s3tc. + * @return {boolean} Whether or not the format is supported. + */ + Scene.prototype.getCompressedTextureFormatSupported = function(format) { + var context = this.context; + return ((format === 'WEBGL_compressed_texture_s3tc' || format === 's3tc') && context.s3tc) || + ((format === 'WEBGL_compressed_texture_pvrtc' || format === 'pvrtc') && context.pvrtc) || + ((format === 'WEBGL_compressed_texture_etc1' || format === 'etc1') && context.etc1); + }; - function updateDebugFrustumPlanes(scene) { - var frameState = scene._frameState; - if (scene.debugShowFrustumPlanes !== scene._debugShowFrustumPlanes) { - if (scene.debugShowFrustumPlanes) { - scene._debugFrustumPlanes = new DebugCameraPrimitive({ - camera: scene.camera, - updateOnChange: false - }); - } else { - scene._debugFrustumPlanes = scene._debugFrustumPlanes && scene._debugFrustumPlanes.destroy(); - } - scene._debugShowFrustumPlanes = scene.debugShowFrustumPlanes; - } + var scratchPosition0 = new Cartesian3(); + var scratchPosition1 = new Cartesian3(); + function maxComponent(a, b) { + var x = Math.max(Math.abs(a.x), Math.abs(b.x)); + var y = Math.max(Math.abs(a.y), Math.abs(b.y)); + var z = Math.max(Math.abs(a.z), Math.abs(b.z)); + return Math.max(Math.max(x, y), z); + } - if (defined(scene._debugFrustumPlanes)) { - scene._debugFrustumPlanes.update(frameState); - } + function cameraEqual(camera0, camera1, epsilon) { + var scalar = 1 / Math.max(1, maxComponent(camera0.position, camera1.position)); + Cartesian3.multiplyByScalar(camera0.position, scalar, scratchPosition0); + Cartesian3.multiplyByScalar(camera1.position, scalar, scratchPosition1); + return Cartesian3.equalsEpsilon(scratchPosition0, scratchPosition1, epsilon) && + Cartesian3.equalsEpsilon(camera0.direction, camera1.direction, epsilon) && + Cartesian3.equalsEpsilon(camera0.up, camera1.up, epsilon) && + Cartesian3.equalsEpsilon(camera0.right, camera1.right, epsilon) && + Matrix4.equalsEpsilon(camera0.transform, camera1.transform, epsilon); } - function updateShadowMaps(scene) { - var frameState = scene._frameState; - var shadowMaps = frameState.shadowMaps; - var length = shadowMaps.length; + function updateDerivedCommands(scene, command) { + var frameState = scene.frameState; + var context = scene._context; + var shadowsEnabled = frameState.shadowHints.shadowsEnabled; + var shadowMaps = frameState.shadowHints.shadowMaps; + var lightShadowMaps = frameState.shadowHints.lightShadowMaps; + var lightShadowsEnabled = shadowsEnabled && (lightShadowMaps.length > 0); - var shadowsEnabled = (length > 0) && !frameState.passes.pick && (scene.mode === SceneMode.SCENE3D); - if (shadowsEnabled !== frameState.shadowHints.shadowsEnabled) { - // Update derived commands when shadowsEnabled changes - ++frameState.shadowHints.lastDirtyTime; - frameState.shadowHints.shadowsEnabled = shadowsEnabled; + // Update derived commands when any shadow maps become dirty + var shadowsDirty = false; + var lastDirtyTime = frameState.shadowHints.lastDirtyTime; + if (command.lastDirtyTime !== lastDirtyTime) { + command.lastDirtyTime = lastDirtyTime; + command.dirty = true; + shadowsDirty = true; } - if (!shadowsEnabled) { - return; - } + var derivedCommands = command.derivedCommands; + if (command.dirty && defined(derivedCommands)) { + command.dirty = false; - // Check if the shadow maps are different than the shadow maps last frame. - // If so, the derived commands need to be updated. - for (var j = 0; j < length; ++j) { - if (shadowMaps[j] !== frameState.shadowHints.shadowMaps[j]) { - ++frameState.shadowHints.lastDirtyTime; - break; + if (shadowsEnabled && (command.receiveShadows || command.castShadows)) { + derivedCommands.shadows = ShadowMap.createDerivedCommands(shadowMaps, lightShadowMaps, command, shadowsDirty, context, derivedCommands.shadows); } - } - - frameState.shadowHints.shadowMaps.length = 0; - frameState.shadowHints.lightShadowMaps.length = 0; - - for (var i = 0; i < length; ++i) { - var shadowMap = shadowMaps[i]; - shadowMap.update(frameState); - - frameState.shadowHints.shadowMaps.push(shadowMap); - if (shadowMap.fromLightSource) { - frameState.shadowHints.lightShadowMaps.push(shadowMap); + var oit = scene._oit; + if (command.pass === Pass.TRANSLUCENT && defined(oit) && oit.isSupported()) { + if (lightShadowsEnabled && command.receiveShadows) { + derivedCommands.oit = defined(derivedCommands.oit) ? derivedCommands.oit : {}; + derivedCommands.oit.shadows = oit.createDerivedCommands(command.derivedCommands.shadows.receiveCommand, context, derivedCommands.oit.shadows); + } else { + derivedCommands.oit = oit.createDerivedCommands(command, context, derivedCommands.oit); + } } - if (shadowMap.dirty) { - ++frameState.shadowHints.lastDirtyTime; - shadowMap.dirty = false; - } + derivedCommands.depth = createDepthOnlyDerivedCommand(scene, command, context, derivedCommands.depth); } } - function updatePrimitives(scene) { - var frameState = scene._frameState; - - scene._groundPrimitives.update(frameState); - scene._primitives.update(frameState); - - updateDebugFrustumPlanes(scene); - updateShadowMaps(scene); + var scratchOccluderBoundingSphere = new BoundingSphere(); + var scratchOccluder; - if (scene._globe) { - scene._globe.update(frameState); + function getOccluder(scene) { + // TODO: The occluder is the top-level globe. When we add + // support for multiple central bodies, this should be the closest one. + var globe = scene.globe; + if (scene._mode === SceneMode.SCENE3D && defined(globe)) { + var ellipsoid = globe.ellipsoid; + scratchOccluderBoundingSphere.radius = ellipsoid.minimumRadius; + scratchOccluder = Occluder.fromBoundingSphere(scratchOccluderBoundingSphere, scene._camera.positionWC, scratchOccluder); + return scratchOccluder; } - } - - function updateAndClearFramebuffers(scene, passState, clearColor) { - var context = scene._context; - var environmentState = scene._environmentState; - - var passes = scene._frameState.passes; - var picking = passes.pick; - var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; - - // Preserve the reference to the original framebuffer. - environmentState.originalFramebuffer = passState.framebuffer; - // Manage sun bloom post-processing effect. - if (defined(scene.sun) && scene.sunBloom !== scene._sunBloom) { - if (scene.sunBloom && !useWebVR) { - scene._sunPostProcess = new SunPostProcess(); - } else if(defined(scene._sunPostProcess)){ - scene._sunPostProcess = scene._sunPostProcess.destroy(); - } + return undefined; + } - scene._sunBloom = scene.sunBloom; - } else if (!defined(scene.sun) && defined(scene._sunPostProcess)) { - scene._sunPostProcess = scene._sunPostProcess.destroy(); - scene._sunBloom = false; - } + function clearPasses(passes) { + passes.render = false; + passes.pick = false; + passes.depth = false; + } - // Clear the pass state framebuffer. - var clear = scene._clearColorCommand; - Color.clone(clearColor, clear.color); - clear.execute(context, passState); + function updateFrameState(scene, frameNumber, time) { + var camera = scene._camera; - // Update globe depth rendering based on the current context and clear the globe depth framebuffer. - var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = !picking && defined(scene._globeDepth); - if (useGlobeDepthFramebuffer) { - scene._globeDepth.update(context, passState); - scene._globeDepth.clear(context, passState, clearColor); - } + var frameState = scene._frameState; + frameState.commandList.length = 0; + frameState.shadowMaps.length = 0; + frameState.brdfLutGenerator = scene._brdfLutGenerator; + frameState.environmentMap = scene.skyBox && scene.skyBox._cubeMap; + frameState.mode = scene._mode; + frameState.morphTime = scene.morphTime; + frameState.mapProjection = scene.mapProjection; + frameState.frameNumber = frameNumber; + frameState.time = JulianDate.clone(time, frameState.time); + frameState.camera = camera; + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + frameState.occluder = getOccluder(scene); + frameState.terrainExaggeration = scene._terrainExaggeration; + frameState.minimumDisableDepthTestDistance = scene._minimumDisableDepthTestDistance; + frameState.invertClassification = scene.invertClassification; - // If supported, configure OIT to use the globe depth framebuffer and clear the OIT framebuffer. - var useOIT = environmentState.useOIT = !picking && defined(scene._oit) && scene._oit.isSupported(); - if (useOIT) { - scene._oit.update(context, passState, scene._globeDepth.framebuffer); - scene._oit.clear(context, passState, clearColor); - environmentState.useOIT = scene._oit.isSupported(); + scene._actualInvertClassificationColor = Color.clone(scene.invertClassificationColor, scene._actualInvertClassificationColor); + if (!InvertClassification.isTranslucencySupported(scene._context)) { + scene._actualInvertClassificationColor.alpha = 1.0; } - // If supported, configure FXAA to use the globe depth color texture and clear the FXAA framebuffer. - var useFXAA = environmentState.useFXAA = !picking && scene.fxaa; - if (useFXAA) { - scene._fxaa.update(context, passState); - scene._fxaa.clear(context, passState, clearColor); - } + frameState.invertClassificationColor = scene._actualInvertClassificationColor; - if (environmentState.isSunVisible && scene.sunBloom && !useWebVR) { - passState.framebuffer = scene._sunPostProcess.update(passState); - } else if (useGlobeDepthFramebuffer) { - passState.framebuffer = scene._globeDepth.framebuffer; - } else if (useFXAA) { - passState.framebuffer = scene._fxaa.getColorFramebuffer(); + if (defined(scene.globe)) { + frameState.maximumScreenSpaceError = scene.globe.maximumScreenSpaceError; + } else { + frameState.maximumScreenSpaceError = 2; } - if (defined(passState.framebuffer)) { - clear.execute(context, passState); - } + clearPasses(frameState.passes); + } - var useInvertClassification = environmentState.useInvertClassification = !picking && defined(passState.framebuffer) && scene.invertClassification; - if (useInvertClassification) { - var depthFramebuffer; - if (scene.frameState.invertClassificationColor.alpha === 1.0) { - if (environmentState.useGlobeDepthFramebuffer) { - depthFramebuffer = scene._globeDepth.framebuffer; - } else if (environmentState.useFXAA) { - depthFramebuffer = scene._fxaa.getColorFramebuffer(); - } - } + function updateFrustums(near, far, farToNearRatio, numFrustums, frustumCommandsList, is2D, nearToFarDistance2D) { + frustumCommandsList.length = numFrustums; + for (var m = 0; m < numFrustums; ++m) { + var curNear; + var curFar; - scene._invertClassification.previousFramebuffer = depthFramebuffer; - scene._invertClassification.update(context); - scene._invertClassification.clear(context, passState); + if (!is2D) { + curNear = Math.max(near, Math.pow(farToNearRatio, m) * near); + curFar = Math.min(far, farToNearRatio * curNear); + } else { + curNear = Math.min(far - nearToFarDistance2D, near + m * nearToFarDistance2D); + curFar = Math.min(far, curNear + nearToFarDistance2D); + } - if (scene.frameState.invertClassificationColor.alpha < 1.0 && useOIT) { - var command = scene._invertClassification.unclassifiedCommand; - var derivedCommands = command.derivedCommands; - derivedCommands.oit = scene._oit.createDerivedCommands(command, context, derivedCommands.oit); + var frustumCommands = frustumCommandsList[m]; + if (!defined(frustumCommands)) { + frustumCommands = frustumCommandsList[m] = new FrustumCommands(curNear, curFar); + } else { + frustumCommands.near = curNear; + frustumCommands.far = curFar; } } } - function resolveFramebuffers(scene, passState) { - var context = scene._context; - var environmentState = scene._environmentState; - - var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer; - if (scene.debugShowGlobeDepth && useGlobeDepthFramebuffer) { - var gd = getDebugGlobeDepth(scene, scene.debugShowDepthFrustum - 1); - gd.executeDebugGlobeDepth(context, passState); + function insertIntoBin(scene, command, distance) { + if (scene.debugShowFrustums) { + command.debugOverlappingFrustums = 0; } - if (scene.debugShowPickDepth && useGlobeDepthFramebuffer) { - var pd = getPickDepth(scene, scene.debugShowDepthFrustum - 1); - pd.executeDebugPickDepth(context, passState); + if (!scene.frameState.passes.pick) { + updateDerivedCommands(scene, command); } - var useOIT = environmentState.useOIT; - var useFXAA = environmentState.useFXAA; + var frustumCommandsList = scene._frustumCommandsList; + var length = frustumCommandsList.length; - if (useOIT) { - passState.framebuffer = useFXAA ? scene._fxaa.getColorFramebuffer() : undefined; - scene._oit.execute(context, passState); - } + for (var i = 0; i < length; ++i) { + var frustumCommands = frustumCommandsList[i]; + var curNear = frustumCommands.near; + var curFar = frustumCommands.far; - if (useFXAA) { - if (!useOIT && useGlobeDepthFramebuffer) { - passState.framebuffer = scene._fxaa.getColorFramebuffer(); - scene._globeDepth.executeCopyColor(context, passState); + if (distance.start > curFar) { + continue; } - passState.framebuffer = environmentState.originalFramebuffer; - scene._fxaa.execute(context, passState); - } + if (distance.stop < curNear) { + break; + } - if (!useOIT && !useFXAA && useGlobeDepthFramebuffer) { - passState.framebuffer = environmentState.originalFramebuffer; - scene._globeDepth.executeCopyColor(context, passState); - } - } + var pass = command.pass; + var index = frustumCommands.indices[pass]++; + frustumCommands.commands[pass][index] = command; - function callAfterRenderFunctions(frameState) { - // Functions are queued up during primitive update and executed here in case - // the function modifies scene state that should remain constant over the frame. - var functions = frameState.afterRender; - for (var i = 0, length = functions.length; i < length; ++i) { - functions[i](); + if (scene.debugShowFrustums) { + command.debugOverlappingFrustums |= (1 << i); + } + + if (command.executeInClosestFrustum) { + break; + } } - functions.length = 0; - } - /** - * @private - */ - Scene.prototype.initializeFrame = function() { - // Destroy released shaders once every 120 frames to avoid thrashing the cache - if (this._shaderFrameCount++ === 120) { - this._shaderFrameCount = 0; - this._context.shaderCache.destroyReleasedShaderPrograms(); + if (scene.debugShowFrustums) { + var cf = scene._debugFrustumStatistics.commandsInFrustums; + cf[command.debugOverlappingFrustums] = defined(cf[command.debugOverlappingFrustums]) ? cf[command.debugOverlappingFrustums] + 1 : 1; + ++scene._debugFrustumStatistics.totalCommands; } + } - this._tweens.update(); + var scratchCullingVolume = new CullingVolume(); + var distances = new Interval(); - this._screenSpaceCameraController.update(); - if (defined(this._deviceOrientationCameraController)) { - this._deviceOrientationCameraController.update(); - } + function isVisible(command, cullingVolume, occluder) { + return ((defined(command)) && + ((!defined(command.boundingVolume)) || + !command.cull || + ((cullingVolume.computeVisibility(command.boundingVolume) !== Intersect.OUTSIDE) && + (!defined(occluder) || !command.boundingVolume.isOccluded(occluder))))); + } - this._camera.update(this._mode); - this._camera._updateCameraChanged(); - }; + function createPotentiallyVisibleSet(scene) { + var frameState = scene._frameState; + var camera = frameState.camera; + var direction = camera.directionWC; + var position = camera.positionWC; - function render(scene, time) { - scene._pickPositionCacheDirty = true; + var computeList = scene._computeCommandList; + var overlayList = scene._overlayCommandList; + var commandList = frameState.commandList; - if (!defined(time)) { - time = JulianDate.now(); + if (scene.debugShowFrustums) { + scene._debugFrustumStatistics = { + totalCommands : 0, + commandsInFrustums : {} + }; } - var camera = scene._camera; - if (!cameraEqual(camera, scene._cameraClone, CesiumMath.EPSILON6)) { - if (!scene._cameraStartFired) { - camera.moveStart.raiseEvent(); - scene._cameraStartFired = true; + var frustumCommandsList = scene._frustumCommandsList; + var numberOfFrustums = frustumCommandsList.length; + var numberOfPasses = Pass.NUMBER_OF_PASSES; + for (var n = 0; n < numberOfFrustums; ++n) { + for (var p = 0; p < numberOfPasses; ++p) { + frustumCommandsList[n].indices[p] = 0; } - scene._cameraMovedTime = getTimestamp(); - Camera.clone(camera, scene._cameraClone); - } else if (scene._cameraStartFired && getTimestamp() - scene._cameraMovedTime > scene.cameraEventWaitTime) { - camera.moveEnd.raiseEvent(); - scene._cameraStartFired = false; } - scene._preRender.raiseEvent(scene, time); - scene._jobScheduler.resetBudgets(); - - var context = scene.context; - var us = context.uniformState; - var frameState = scene._frameState; - - var frameNumber = CesiumMath.incrementWrap(frameState.frameNumber, 15000000.0, 1.0); - updateFrameState(scene, frameNumber, time); - frameState.passes.render = true; - - var backgroundColor = defaultValue(scene.backgroundColor, Color.BLACK); - frameState.backgroundColor = backgroundColor; + computeList.length = 0; + overlayList.length = 0; - frameState.creditDisplay.beginFrame(); + var near = Number.MAX_VALUE; + var far = -Number.MAX_VALUE; + var undefBV = false; - scene.fog.update(frameState); + var shadowsEnabled = frameState.shadowHints.shadowsEnabled; + var shadowNear = Number.MAX_VALUE; + var shadowFar = -Number.MAX_VALUE; + var shadowClosestObjectSize = Number.MAX_VALUE; - us.update(frameState); + var occluder = (frameState.mode === SceneMode.SCENE3D) ? frameState.occluder: undefined; + var cullingVolume = frameState.cullingVolume; - var shadowMap = scene.shadowMap; - if (defined(shadowMap) && shadowMap.enabled) { - // Update the sun's direction - Cartesian3.negate(us.sunDirectionWC, scene._sunCamera.direction); - frameState.shadowMaps.push(shadowMap); + // get user culling volume minus the far plane. + var planes = scratchCullingVolume.planes; + for (var k = 0; k < 5; ++k) { + planes[k] = cullingVolume.planes[k]; } + cullingVolume = scratchCullingVolume; - scene._computeCommandList.length = 0; - scene._overlayCommandList.length = 0; - - var passState = scene._passState; - passState.framebuffer = undefined; - passState.blendingEnabled = undefined; - passState.scissorTest = undefined; + var length = commandList.length; + for (var i = 0; i < length; ++i) { + var command = commandList[i]; + var pass = command.pass; - if (defined(scene.globe)) { - scene.globe.beginFrame(frameState); - } + if (pass === Pass.COMPUTE) { + computeList.push(command); + } else if (pass === Pass.OVERLAY) { + overlayList.push(command); + } else { + var boundingVolume = command.boundingVolume; + if (defined(boundingVolume)) { + if (!isVisible(command, cullingVolume, occluder)) { + continue; + } - updateEnvironment(scene, passState); - updateAndExecuteCommands(scene, passState, backgroundColor); - resolveFramebuffers(scene, passState); - executeOverlayCommands(scene, passState); + distances = boundingVolume.computePlaneDistances(position, direction, distances); + near = Math.min(near, distances.start); + far = Math.max(far, distances.stop); - if (defined(scene.globe)) { - scene.globe.endFrame(frameState); - } + // Compute a tight near and far plane for commands that receive shadows. This helps compute + // good splits for cascaded shadow maps. Ignore commands that exceed the maximum distance. + // When moving the camera low LOD globe tiles begin to load, whose bounding volumes + // throw off the near/far fitting for the shadow map. Only update for globe tiles that the + // camera isn't inside. + if (shadowsEnabled && command.receiveShadows && (distances.start < ShadowMap.MAXIMUM_DISTANCE) && + !((pass === Pass.GLOBE) && (distances.start < -100.0) && (distances.stop > 100.0))) { - frameState.creditDisplay.endFrame(); + // Get the smallest bounding volume the camera is near. This is used to place more shadow detail near the object. + var size = distances.stop - distances.start; + if ((pass !== Pass.GLOBE) && (distances.start < 100.0)) { + shadowClosestObjectSize = Math.min(shadowClosestObjectSize, size); + } + shadowNear = Math.min(shadowNear, distances.start); + shadowFar = Math.max(shadowFar, distances.stop); + } + } else { + // Clear commands don't need a bounding volume - just add the clear to all frustums. + // If another command has no bounding volume, though, we need to use the camera's + // worst-case near and far planes to avoid clipping something important. + distances.start = camera.frustum.near; + distances.stop = camera.frustum.far; + undefBV = !(command instanceof ClearCommand); + } - if (scene.debugShowFramesPerSecond) { - if (!defined(scene._performanceDisplay)) { - var performanceContainer = document.createElement('div'); - performanceContainer.className = 'cesium-performanceDisplay-defaultContainer'; - var container = scene._canvas.parentNode; - container.appendChild(performanceContainer); - var performanceDisplay = new PerformanceDisplay({container: performanceContainer}); - scene._performanceDisplay = performanceDisplay; - scene._performanceContainer = performanceContainer; + insertIntoBin(scene, command, distances); } - - scene._performanceDisplay.update(); - } else if (defined(scene._performanceDisplay)) { - scene._performanceDisplay = scene._performanceDisplay && scene._performanceDisplay.destroy(); - scene._performanceContainer.parentNode.removeChild(scene._performanceContainer); } - context.endFrame(); - RequestScheduler.update(); - callAfterRenderFunctions(frameState); - - scene._postRender.raiseEvent(scene, time); - } - - /** - * @private - */ - Scene.prototype.render = function(time) { - try { - render(this, time); - } catch (error) { - this._renderError.raiseEvent(this, error); + if (undefBV) { + near = camera.frustum.near; + far = camera.frustum.far; + } else { + // The computed near plane must be between the user defined near and far planes. + // The computed far plane must between the user defined far and computed near. + // This will handle the case where the computed near plane is further than the user defined far plane. + near = Math.min(Math.max(near, camera.frustum.near), camera.frustum.far); + far = Math.max(Math.min(far, camera.frustum.far), near); - if (this.rethrowRenderErrors) { - throw error; + if (shadowsEnabled) { + shadowNear = Math.min(Math.max(shadowNear, camera.frustum.near), camera.frustum.far); + shadowFar = Math.max(Math.min(shadowFar, camera.frustum.far), shadowNear); } } - }; - - /** - * @private - */ - Scene.prototype.clampLineWidth = function(width) { - return Math.max(ContextLimits.minimumAliasedLineWidth, Math.min(width, ContextLimits.maximumAliasedLineWidth)); - }; - - var orthoPickingFrustum = new OrthographicOffCenterFrustum(); - var scratchOrigin = new Cartesian3(); - var scratchDirection = new Cartesian3(); - var scratchPixelSize = new Cartesian2(); - var scratchPickVolumeMatrix4 = new Matrix4(); - function getPickOrthographicCullingVolume(scene, drawingBufferPosition, width, height) { - var camera = scene._camera; - var frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + // Use the computed near and far for shadows + if (shadowsEnabled) { + frameState.shadowHints.nearPlane = shadowNear; + frameState.shadowHints.farPlane = shadowFar; + frameState.shadowHints.closestObjectSize = shadowClosestObjectSize; } - var viewport = scene._passState.viewport; - var x = 2.0 * (drawingBufferPosition.x - viewport.x) / viewport.width - 1.0; - x *= (frustum.right - frustum.left) * 0.5; - var y = 2.0 * (viewport.height - drawingBufferPosition.y - viewport.y) / viewport.height - 1.0; - y *= (frustum.top - frustum.bottom) * 0.5; - - var transform = Matrix4.clone(camera.transform, scratchPickVolumeMatrix4); - camera._setTransform(Matrix4.IDENTITY); - - var origin = Cartesian3.clone(camera.position, scratchOrigin); - Cartesian3.multiplyByScalar(camera.right, x, scratchDirection); - Cartesian3.add(scratchDirection, origin, origin); - Cartesian3.multiplyByScalar(camera.up, y, scratchDirection); - Cartesian3.add(scratchDirection, origin, origin); + // Exploit temporal coherence. If the frustums haven't changed much, use the frustums computed + // last frame, else compute the new frustums and sort them by frustum again. + var is2D = scene.mode === SceneMode.SCENE2D; + var farToNearRatio = scene.farToNearRatio; - camera._setTransform(transform); + var numFrustums; + if (!is2D) { + // The multifrustum for 3D/CV is non-uniformly distributed. + numFrustums = Math.ceil(Math.log(far / near) / Math.log(farToNearRatio)); + } else { + // The multifrustum for 2D is uniformly distributed. To avoid z-fighting in 2D, + // the camera i smoved to just before the frustum and the frustum depth is scaled + // to be in [1.0, nearToFarDistance2D]. + far = Math.min(far, camera.position.z + scene.nearToFarDistance2D); + near = Math.min(near, far); + numFrustums = Math.ceil(Math.max(1.0, far - near) / scene.nearToFarDistance2D); + } - if (scene.mode === SceneMode.SCENE2D) { - Cartesian3.fromElements(origin.z, origin.x, origin.y, origin); + if (near !== Number.MAX_VALUE && (numFrustums !== numberOfFrustums || (frustumCommandsList.length !== 0 && + (near < frustumCommandsList[0].near || (far > frustumCommandsList[numberOfFrustums - 1].far && !CesiumMath.equalsEpsilon(far, frustumCommandsList[numberOfFrustums - 1].far, CesiumMath.EPSILON8)))))) { + updateFrustums(near, far, farToNearRatio, numFrustums, frustumCommandsList, is2D, scene.nearToFarDistance2D); + createPotentiallyVisibleSet(scene); } - var pixelSize = frustum.getPixelDimensions(viewport.width, viewport.height, 1.0, scratchPixelSize); + var frustumSplits = frameState.frustumSplits; + frustumSplits.length = numFrustums + 1; + for (var j = 0; j < numFrustums; ++j) { + frustumSplits[j] = frustumCommandsList[j].near; + if (j === numFrustums - 1) { + frustumSplits[j + 1] = frustumCommandsList[j].far; + } + } + } - var ortho = orthoPickingFrustum; - ortho.right = pixelSize.x * 0.5; - ortho.left = -ortho.right; - ortho.top = pixelSize.y * 0.5; - ortho.bottom = -ortho.top; - ortho.near = frustum.near; - ortho.far = frustum.far; + function getAttributeLocations(shaderProgram) { + var attributeLocations = {}; + var attributes = shaderProgram.vertexAttributes; + for (var a in attributes) { + if (attributes.hasOwnProperty(a)) { + attributeLocations[a] = attributes[a].index; + } + } - return ortho.computeCullingVolume(origin, camera.directionWC, camera.upWC); + return attributeLocations; } - var perspPickingFrustum = new PerspectiveOffCenterFrustum(); + function createDebugFragmentShaderProgram(command, scene, shaderProgram) { + var context = scene.context; + var sp = defaultValue(shaderProgram, command.shaderProgram); + var fs = sp.fragmentShaderSource.clone(); - function getPickPerspectiveCullingVolume(scene, drawingBufferPosition, width, height) { - var camera = scene._camera; - var frustum = camera.frustum; - var near = frustum.near; + var targets = []; + fs.sources = fs.sources.map(function(source) { + source = ShaderSource.replaceMain(source, 'czm_Debug_main'); + var re = /gl_FragData\[(\d+)\]/g; + var match; + while ((match = re.exec(source)) !== null) { + if (targets.indexOf(match[1]) === -1) { + targets.push(match[1]); + } + } + return source; + }); + var length = targets.length; - var tanPhi = Math.tan(frustum.fovy * 0.5); - var tanTheta = frustum.aspectRatio * tanPhi; + var newMain = + 'void main() \n' + + '{ \n' + + ' czm_Debug_main(); \n'; - var viewport = scene._passState.viewport; - var x = 2.0 * (drawingBufferPosition.x - viewport.x) / viewport.width - 1.0; - var y = 2.0 * (viewport.height - drawingBufferPosition.y - viewport.y) / viewport.height - 1.0; + var i; + if (scene.debugShowCommands) { + if (!defined(command._debugColor)) { + command._debugColor = Color.fromRandom(); + } + var c = command._debugColor; + if (length > 0) { + for (i = 0; i < length; ++i) { + newMain += ' gl_FragData[' + targets[i] + '].rgb *= vec3(' + c.red + ', ' + c.green + ', ' + c.blue + '); \n'; + } + } else { + newMain += ' ' + 'gl_FragColor' + '.rgb *= vec3(' + c.red + ', ' + c.green + ', ' + c.blue + '); \n'; + } + } - var xDir = x * near * tanTheta; - var yDir = y * near * tanPhi; + if (scene.debugShowFrustums) { + // Support up to three frustums. If a command overlaps all + // three, it's code is not changed. + var r = (command.debugOverlappingFrustums & (1 << 0)) ? '1.0' : '0.0'; + var g = (command.debugOverlappingFrustums & (1 << 1)) ? '1.0' : '0.0'; + var b = (command.debugOverlappingFrustums & (1 << 2)) ? '1.0' : '0.0'; + if (length > 0) { + for (i = 0; i < length; ++i) { + newMain += ' gl_FragData[' + targets[i] + '].rgb *= vec3(' + r + ', ' + g + ', ' + b + '); \n'; + } + } else { + newMain += ' ' + 'gl_FragColor' + '.rgb *= vec3(' + r + ', ' + g + ', ' + b + '); \n'; + } + } - var pixelSize = frustum.getPixelDimensions(viewport.width, viewport.height, 1.0, scratchPixelSize); - var pickWidth = pixelSize.x * width * 0.5; - var pickHeight = pixelSize.y * height * 0.5; + newMain += '}'; - var offCenter = perspPickingFrustum; - offCenter.top = yDir + pickHeight; - offCenter.bottom = yDir - pickHeight; - offCenter.right = xDir + pickWidth; - offCenter.left = xDir - pickWidth; - offCenter.near = near; - offCenter.far = frustum.far; + fs.sources.push(newMain); - return offCenter.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); - } + var attributeLocations = getAttributeLocations(sp); - function getPickCullingVolume(scene, drawingBufferPosition, width, height) { - var frustum = scene.camera.frustum; - if (frustum instanceof OrthographicFrustum || frustum instanceof OrthographicOffCenterFrustum) { - return getPickOrthographicCullingVolume(scene, drawingBufferPosition, width, height); - } + return ShaderProgram.fromCache({ + context : context, + vertexShaderSource : sp.vertexShaderSource, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } - return getPickPerspectiveCullingVolume(scene, drawingBufferPosition, width, height); + function executeDebugCommand(command, scene, passState) { + var debugCommand = DrawCommand.shallowClone(command); + debugCommand.shaderProgram = createDebugFragmentShaderProgram(command, scene); + debugCommand.execute(scene.context, passState); + debugCommand.shaderProgram.destroy(); } - // pick rectangle width and height, assumed odd - var rectangleWidth = 3.0; - var rectangleHeight = 3.0; - var scratchRectangle = new BoundingRectangle(0.0, 0.0, rectangleWidth, rectangleHeight); - var scratchColorZero = new Color(0.0, 0.0, 0.0, 0.0); - var scratchPosition = new Cartesian2(); + var transformFrom2D = new Matrix4(0.0, 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0); + transformFrom2D = Matrix4.inverseTransformation(transformFrom2D, transformFrom2D); - /** - * Returns an object with a `primitive` property that contains the first (top) primitive in the scene - * at a particular window coordinate or undefined if nothing is at the location. Other properties may - * potentially be set depending on the type of primitive. - * <p> - * When a feature of a 3D Tiles tileset is picked, <code>pick</code> returns a {@link Cesium3DTileFeature} object. - * </p> - * - * @example - * // On mouse over, color the feature yellow. - * handler.setInputAction(function(movement) { - * var feature = scene.pick(movement.endPosition); - * if (feature instanceof Cesium.Cesium3DTileFeature) { - * feature.color = Cesium.Color.YELLOW; - * } - * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - * - * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Number} [width=3] Width of the pick rectangle. - * @param {Number} [height=3] Height of the pick rectangle. - * @returns {Object} Object containing the picked primitive. - * - * @exception {DeveloperError} windowPosition is undefined. - */ - Scene.prototype.pick = function(windowPosition, width, height) { - if(!defined(windowPosition)) { - throw new DeveloperError('windowPosition is undefined.'); + function executeCommand(command, scene, context, passState, debugFramebuffer) { + if ((defined(scene.debugCommandFilter)) && !scene.debugCommandFilter(command)) { + return; } - - rectangleWidth = defaultValue(width, 3.0); - rectangleHeight = defaultValue(height, rectangleWidth); - var context = this._context; - var us = context.uniformState; - var frameState = this._frameState; + if (command instanceof ClearCommand) { + command.execute(context, passState); + return; + } - var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); + var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; + var lightShadowsEnabled = shadowsEnabled && (scene.frameState.shadowHints.lightShadowMaps.length > 0); - if (!defined(this._pickFramebuffer)) { - this._pickFramebuffer = context.createPickFramebuffer(); + if (scene.debugShowCommands || scene.debugShowFrustums) { + executeDebugCommand(command, scene, passState); + } else if (lightShadowsEnabled && command.receiveShadows && defined(command.derivedCommands.shadows)) { + // If the command receives shadows, execute the derived shadows command. + // Some commands, such as OIT derived commands, do not have derived shadow commands themselves + // and instead shadowing is built-in. In this case execute the command regularly below. + command.derivedCommands.shadows.receiveCommand.execute(context, passState); + } else if (scene.frameState.passes.depth && defined(command.derivedCommands.depth)) { + command.derivedCommands.depth.depthOnlyCommand.execute(context, passState); + } else { + command.execute(context, passState); } - this._jobScheduler.disableThisFrame(); - - // Update with previous frame's number and time, assuming that render is called before picking. - updateFrameState(this, frameState.frameNumber, frameState.time); - frameState.cullingVolume = getPickCullingVolume(this, drawingBufferPosition, rectangleWidth, rectangleHeight); - frameState.invertClassification = false; - frameState.passes.pick = true; + if (command.debugShowBoundingVolume && (defined(command.boundingVolume))) { + // Debug code to draw bounding volume for command. Not optimized! + // Assumes bounding volume is a bounding sphere or box + var frameState = scene._frameState; + var boundingVolume = command.boundingVolume; - us.update(frameState); + if (defined(scene._debugVolume)) { + scene._debugVolume.destroy(); + } - scratchRectangle.x = drawingBufferPosition.x - ((rectangleWidth - 1.0) * 0.5); - scratchRectangle.y = (this.drawingBufferHeight - drawingBufferPosition.y) - ((rectangleHeight - 1.0) * 0.5); - scratchRectangle.width = rectangleWidth; - scratchRectangle.height = rectangleHeight; - var passState = this._pickFramebuffer.begin(scratchRectangle); + var geometry; - updateEnvironment(this, passState); - updateAndExecuteCommands(this, passState, scratchColorZero); - resolveFramebuffers(this, passState); + var center = Cartesian3.clone(boundingVolume.center); + if (frameState.mode !== SceneMode.SCENE3D) { + center = Matrix4.multiplyByPoint(transformFrom2D, center, center); + var projection = frameState.mapProjection; + var centerCartographic = projection.unproject(center); + center = projection.ellipsoid.cartographicToCartesian(centerCartographic); + } - var object = this._pickFramebuffer.end(scratchRectangle); - context.endFrame(); - callAfterRenderFunctions(frameState); - return object; - }; + if (defined(boundingVolume.radius)) { + var radius = boundingVolume.radius; - var fragDepthRegex = /\bgl_FragDepthEXT\b/; - var discardRegex = /\bdiscard\b/; + geometry = GeometryPipeline.toWireframe(EllipsoidGeometry.createGeometry(new EllipsoidGeometry({ + radii : new Cartesian3(radius, radius, radius), + vertexFormat : PerInstanceColorAppearance.FLAT_VERTEX_FORMAT + }))); - function getDepthOnlyShaderProgram(context, shaderProgram) { - var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'depthOnly'); - if (!defined(shader)) { - var attributeLocations = shaderProgram._attributeLocations; - var fs = shaderProgram.fragmentShaderSource; + scene._debugVolume = new Primitive({ + geometryInstances : new GeometryInstance({ + geometry : geometry, + modelMatrix : Matrix4.fromTranslation(center), + attributes : { + color : new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : false + }), + asynchronous : false + }); + } else { + var halfAxes = boundingVolume.halfAxes; - var writesDepthOrDiscards = false; - var sources = fs.sources; - var length = sources.length; - for (var i = 0; i < length; ++i) { - if (fragDepthRegex.test(sources[i]) || discardRegex.test(sources[i])) { - writesDepthOrDiscards = true; - break; - } - } + geometry = GeometryPipeline.toWireframe(BoxGeometry.createGeometry(BoxGeometry.fromDimensions({ + dimensions : new Cartesian3(2.0, 2.0, 2.0), + vertexFormat : PerInstanceColorAppearance.FLAT_VERTEX_FORMAT + }))); - if (!writesDepthOrDiscards) { - fs = new ShaderSource({ - sources : ['void main() { gl_FragColor = vec4(1.0); }'] + scene._debugVolume = new Primitive({ + geometryInstances : new GeometryInstance({ + geometry : geometry, + modelMatrix : Matrix4.fromRotationTranslation(halfAxes, center, new Matrix4()), + attributes : { + color : new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0) + } + }), + appearance : new PerInstanceColorAppearance({ + flat : true, + translucent : false + }), + asynchronous : false }); } - shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'depthOnly', { - vertexShaderSource : shaderProgram.vertexShaderSource, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } - - return shader; - } - - function getDepthOnlyRenderState(scene, renderState) { - var cache = scene._depthOnlyRenderStateCache; - var depthOnlyState = cache[renderState.id]; - if (!defined(depthOnlyState)) { - var rs = RenderState.getState(renderState); - rs.depthMask = true; - rs.colorMask = { - red : false, - green : false, - blue : false, - alpha : false - }; - - depthOnlyState = RenderState.fromCache(rs); - cache[renderState.id] = depthOnlyState; - } - - return depthOnlyState; - } - - function createDepthOnlyDerivedCommand(scene, command, context, result) { - // For a depth only pass, we bind a framebuffer with only a depth attachment (no color attachments), - // do not write color, and write depth. If the fragment shader doesn't modify the fragment depth - // or discard, the driver can replace the fragment shader with a pass-through shader. We're unsure if this - // actually happens so we modify the shader to use a pass-through fragment shader. + var savedCommandList = frameState.commandList; + var commandList = frameState.commandList = []; + scene._debugVolume.update(frameState); - if (!defined(result)) { - result = {}; - } + var framebuffer; + if (defined(debugFramebuffer)) { + framebuffer = passState.framebuffer; + passState.framebuffer = debugFramebuffer; + } - var shader; - var renderState; - if (defined(result.depthOnlyCommand)) { - shader = result.depthOnlyCommand.shaderProgram; - renderState = result.depthOnlyCommand.renderState; - } + commandList[0].execute(context, passState); - result.depthOnlyCommand = DrawCommand.shallowClone(command, result.depthOnlyCommand); + if (defined(framebuffer)) { + passState.framebuffer = framebuffer; + } - if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { - result.depthOnlyCommand.shaderProgram = getDepthOnlyShaderProgram(context, command.shaderProgram); - result.depthOnlyCommand.renderState = getDepthOnlyRenderState(scene, command.renderState); - result.shaderProgramId = command.shaderProgram.id; - } else { - result.depthOnlyCommand.shaderProgram = shader; - result.depthOnlyCommand.renderState = renderState; + frameState.commandList = savedCommandList; } + } - return result; + function translucentCompare(a, b, position) { + return b.boundingVolume.distanceSquaredTo(position) - a.boundingVolume.distanceSquaredTo(position); } - function renderTranslucentDepthForPick(scene, drawingBufferPosition) { - // PERFORMANCE_IDEA: render translucent only and merge with the previous frame - var context = scene._context; - var frameState = scene._frameState; + function executeTranslucentCommandsSorted(scene, executeFunction, passState, commands, invertClassification) { + var context = scene.context; - clearPasses(frameState.passes); - frameState.passes.pick = true; - frameState.passes.depth = true; - frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); + mergeSort(commands, translucentCompare, scene._camera.positionWC); - var passState = scene._pickDepthPassState; - if (!defined(passState)) { - passState = scene._pickDepthPassState = new PassState(context); - passState.scissorTest = { - enabled : true, - rectangle : new BoundingRectangle() - }; - passState.viewport = new BoundingRectangle(); + if (defined(invertClassification)) { + executeFunction(invertClassification.unclassifiedCommand, scene, context, passState); } - var width = context.drawingBufferWidth; - var height = context.drawingBufferHeight; - - var framebuffer = scene._pickDepthFramebuffer; - var pickDepthFBWidth = scene._pickDepthFramebufferWidth; - var pickDepthFBHeight = scene._pickDepthFramebufferHeight; - if (!defined(framebuffer) || pickDepthFBWidth !== width || pickDepthFBHeight !== height) { - scene._pickDepthFramebuffer = scene._pickDepthFramebuffer && scene._pickDepthFramebuffer.destroy(); - framebuffer = scene._pickDepthFramebuffer = new Framebuffer({ - context : context, - depthStencilTexture : new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.DEPTH_STENCIL, - pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 - }) - }); - - scene._pickDepthFramebufferWidth = width; - scene._pickDepthFramebufferHeight = height; + var length = commands.length; + for (var j = 0; j < length; ++j) { + executeFunction(commands[j], scene, context, passState); } - - passState.framebuffer = framebuffer; - passState.viewport.width = width; - passState.viewport.height = height; - passState.scissorTest.rectangle.x = drawingBufferPosition.x; - passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; - passState.scissorTest.rectangle.width = 1; - passState.scissorTest.rectangle.height = 1; - - updateEnvironment(scene, passState); - updateAndExecuteCommands(scene, passState, scratchColorZero); - resolveFramebuffers(scene, passState); - - context.endFrame(); } - var scratchPackedDepth = new Cartesian4(); - var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); - - /** - * Returns the cartesian position reconstructed from the depth buffer and window position. - * The returned position is in world coordinates. Used internally by camera functions to - * prevent conversion to projected 2D coordinates and then back. - * <p> - * Set {@link Scene#pickTranslucentDepth} to <code>true</code> to include the depth of - * translucent primitives; otherwise, this essentially picks through translucent primitives. - * </p> - * - * @private - * - * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Cartesian3} [result] The object on which to restore the result. - * @returns {Cartesian3} The cartesian position in world coordinates. - * - * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. - */ - Scene.prototype.pickPositionWorldCoordinates = function(windowPosition, result) { - if (!this.useDepthPicking) { - return undefined; - } - - if(!defined(windowPosition)) { - throw new DeveloperError('windowPosition is undefined.'); - } - if (!defined(this._globeDepth)) { - throw new DeveloperError('Picking from the depth buffer is not supported. Check pickPositionSupported.'); + function getDebugGlobeDepth(scene, index) { + var globeDepth = scene._debugGlobeDepths[index]; + if (!defined(globeDepth) && scene.context.depthTexture) { + globeDepth = new GlobeDepth(); + scene._debugGlobeDepths[index] = globeDepth; } - - var cacheKey = windowPosition.toString(); + return globeDepth; + } - if (this._pickPositionCacheDirty){ - this._pickPositionCache = {}; - this._pickPositionCacheDirty = false; - } else if (this._pickPositionCache.hasOwnProperty(cacheKey)){ - return Cartesian3.clone(this._pickPositionCache[cacheKey], result); + function getPickDepth(scene, index) { + var pickDepth = scene._pickDepths[index]; + if (!defined(pickDepth)) { + pickDepth = new PickDepth(); + scene._pickDepths[index] = pickDepth; } + return pickDepth; + } - var context = this._context; - var uniformState = context.uniformState; + var scratchPerspectiveFrustum = new PerspectiveFrustum(); + var scratchPerspectiveOffCenterFrustum = new PerspectiveOffCenterFrustum(); + var scratchOrthographicFrustum = new OrthographicFrustum(); + var scratchOrthographicOffCenterFrustum = new OrthographicOffCenterFrustum(); - var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); - if (this.pickTranslucentDepth) { - renderTranslucentDepthForPick(this, drawingBufferPosition); - } - drawingBufferPosition.y = this.drawingBufferHeight - drawingBufferPosition.y; + function executeCommands(scene, passState) { + var camera = scene._camera; + var context = scene.context; + var us = context.uniformState; - var camera = this._camera; + us.updateCamera(camera); // Create a working frustum from the original camera frustum. var frustum; @@ -212953,2902 +224363,2420 @@ define('Scene/Scene',[ frustum = camera.frustum.clone(scratchOrthographicOffCenterFrustum); } - var numFrustums = this.numberOfFrustums; - for (var i = 0; i < numFrustums; ++i) { - var pickDepth = getPickDepth(this, i); - var pixels = context.readPixels({ - x : drawingBufferPosition.x, - y : drawingBufferPosition.y, - width : 1, - height : 1, - framebuffer : pickDepth.framebuffer - }); + // Ideally, we would render the sky box and atmosphere last for + // early-z, but we would have to draw it in each frustum + frustum.near = camera.frustum.near; + frustum.far = camera.frustum.far; + us.updateFrustum(frustum); + us.updatePass(Pass.ENVIRONMENT); - var packedDepth = Cartesian4.unpack(pixels, 0, scratchPackedDepth); - Cartesian4.divideByScalar(packedDepth, 255.0, packedDepth); - var depth = Cartesian4.dot(packedDepth, packedDepthScale); + var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; + var passes = scene._frameState.passes; + var picking = passes.pick; + var depthOnly = passes.depth; + var environmentState = scene._environmentState; - if (depth > 0.0 && depth < 1.0) { - var renderedFrustum = this._frustumCommandsList[i]; - var height2D; - if (this.mode === SceneMode.SCENE2D) { - height2D = camera.position.z; - camera.position.z = height2D - renderedFrustum.near + 1.0; - frustum.far = Math.max(1.0, renderedFrustum.far - renderedFrustum.near); - frustum.near = 1.0; - uniformState.update(this.frameState); - uniformState.updateFrustum(frustum); - } else { - frustum.near = renderedFrustum.near * (i !== 0 ? OPAQUE_FRUSTUM_NEAR_OFFSET : 1.0); - frustum.far = renderedFrustum.far; - uniformState.updateFrustum(frustum); - } + // Do not render environment primitives during a pick pass since they do not generate picking commands. + if (!picking) { + var skyBoxCommand = environmentState.skyBoxCommand; + if (defined(skyBoxCommand)) { + executeCommand(skyBoxCommand, scene, context, passState); + } - result = SceneTransforms.drawingBufferToWgs84Coordinates(this, drawingBufferPosition, depth, result); + if (environmentState.isSkyAtmosphereVisible) { + executeCommand(environmentState.skyAtmosphereCommand, scene, context, passState); + } - if (this.mode === SceneMode.SCENE2D) { - camera.position.z = height2D; - uniformState.update(this.frameState); + if (environmentState.isSunVisible) { + environmentState.sunDrawCommand.execute(context, passState); + if (scene.sunBloom && !useWebVR) { + var framebuffer; + if (environmentState.useGlobeDepthFramebuffer) { + framebuffer = scene._globeDepth.framebuffer; + } else if (environmentState.useFXAA) { + framebuffer = scene._fxaa.getColorFramebuffer(); + } else { + framebuffer = environmentState.originalFramebuffer; + } + scene._sunPostProcess.execute(context, framebuffer); + passState.framebuffer = framebuffer; } + } - this._pickPositionCache[cacheKey] = Cartesian3.clone(result); - return result; + // Moon can be seen through the atmosphere, since the sun is rendered after the atmosphere. + if (environmentState.isMoonVisible) { + environmentState.moonCommand.execute(context, passState); } } - this._pickPositionCache[cacheKey] = undefined; - return undefined; - }; - - var scratchPickPositionCartographic = new Cartographic(); + // Determine how translucent surfaces will be handled. + var executeTranslucentCommands; + if (environmentState.useOIT) { + if (!defined(scene._executeOITFunction)) { + scene._executeOITFunction = function(scene, executeFunction, passState, commands, invertClassification) { + scene._oit.executeCommands(scene, executeFunction, passState, commands, invertClassification); + }; + } + executeTranslucentCommands = scene._executeOITFunction; + } else { + executeTranslucentCommands = executeTranslucentCommandsSorted; + } - /** - * Returns the cartesian position reconstructed from the depth buffer and window position. - * <p> - * The position reconstructed from the depth buffer in 2D may be slightly different from those - * reconstructed in 3D and Columbus view. This is caused by the difference in the distribution - * of depth values of perspective and orthographic projection. - * </p> - * <p> - * Set {@link Scene#pickTranslucentDepth} to <code>true</code> to include the depth of - * translucent primitives; otherwise, this essentially picks through translucent primitives. - * </p> - * - * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Cartesian3} [result] The object on which to restore the result. - * @returns {Cartesian3} The cartesian position. - * - * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. - */ - Scene.prototype.pickPosition = function(windowPosition, result) { - result = this.pickPositionWorldCoordinates(windowPosition, result); - if (defined(result) && this.mode !== SceneMode.SCENE3D) { - Cartesian3.fromElements(result.y, result.z, result.x, result); + var clearGlobeDepth = environmentState.clearGlobeDepth; + var useDepthPlane = environmentState.useDepthPlane; + var clearDepth = scene._depthClearCommand; + var depthPlane = scene._depthPlane; - var projection = this.mapProjection; - var ellipsoid = projection.ellipsoid; + var height2D = camera.position.z; - var cart = projection.unproject(result, scratchPickPositionCartographic); - ellipsoid.cartographicToCartesian(cart, result); - } + // Execute commands in each frustum in back to front order + var j; + var frustumCommandsList = scene._frustumCommandsList; + var numFrustums = frustumCommandsList.length; - return result; - }; + for (var i = 0; i < numFrustums; ++i) { + var index = numFrustums - i - 1; + var frustumCommands = frustumCommandsList[index]; - /** - * Returns a list of objects, each containing a `primitive` property, for all primitives at - * a particular window coordinate position. Other properties may also be set depending on the - * type of primitive. The primitives in the list are ordered by their visual order in the - * scene (front to back). - * - * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Number} [limit] If supplied, stop drilling after collecting this many picks. - * @returns {Object[]} Array of objects, each containing 1 picked primitives. - * - * @exception {DeveloperError} windowPosition is undefined. - * - * @example - * var pickedObjects = scene.drillPick(new Cesium.Cartesian2(100.0, 200.0)); - */ - Scene.prototype.drillPick = function(windowPosition, limit) { - // PERFORMANCE_IDEA: This function calls each primitive's update for each pass. Instead - // we could update the primitive once, and then just execute their commands for each pass, - // and cull commands for picked primitives. e.g., base on the command's owner. + if (scene.mode === SceneMode.SCENE2D) { + // To avoid z-fighting in 2D, move the camera to just before the frustum + // and scale the frustum depth to be in [1.0, nearToFarDistance2D]. + camera.position.z = height2D - frustumCommands.near + 1.0; + frustum.far = Math.max(1.0, frustumCommands.far - frustumCommands.near); + frustum.near = 1.0; + us.update(scene.frameState); + us.updateFrustum(frustum); + } else { + // Avoid tearing artifacts between adjacent frustums in the opaque passes + frustum.near = index !== 0 ? frustumCommands.near * OPAQUE_FRUSTUM_NEAR_OFFSET : frustumCommands.near; + frustum.far = frustumCommands.far; + us.updateFrustum(frustum); + } - if (!defined(windowPosition)) { - throw new DeveloperError('windowPosition is undefined.'); - } - - var i; - var attributes; - var result = []; - var pickedPrimitives = []; - var pickedAttributes = []; - if (!defined(limit)) { - limit = Number.MAX_VALUE; - } + var globeDepth = scene.debugShowGlobeDepth ? getDebugGlobeDepth(scene, index) : scene._globeDepth; - var pickedResult = this.pick(windowPosition); - while (defined(pickedResult) && defined(pickedResult.primitive)) { - result.push(pickedResult); - if (0 >= --limit) { - break; + var fb; + if (scene.debugShowGlobeDepth && defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) { + fb = passState.framebuffer; + passState.framebuffer = globeDepth.framebuffer; } - var primitive = pickedResult.primitive; - var hasShowAttribute = false; + clearDepth.execute(context, passState); + scene._stencilClearCommand.execute(context, passState); - //If the picked object has a show attribute, use it. - if (typeof primitive.getGeometryInstanceAttributes === 'function') { - if (defined(pickedResult.id)) { - attributes = primitive.getGeometryInstanceAttributes(pickedResult.id); - if (defined(attributes) && defined(attributes.show)) { - hasShowAttribute = true; - attributes.show = ShowGeometryInstanceAttribute.toValue(false, attributes.show); - pickedAttributes.push(attributes); - } - } + us.updatePass(Pass.GLOBE); + var commands = frustumCommands.commands[Pass.GLOBE]; + var length = frustumCommands.indices[Pass.GLOBE]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); } - //Otherwise, hide the entire primitive - if (!hasShowAttribute) { - primitive.show = false; - pickedPrimitives.push(primitive); + if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer && (scene.copyGlobeDepth || scene.debugShowGlobeDepth)) { + globeDepth.update(context, passState); + globeDepth.executeCopyDepth(context, passState); } - pickedResult = this.pick(windowPosition); - } + if (scene.debugShowGlobeDepth && defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) { + passState.framebuffer = fb; + } - // unhide everything we hid while drill picking - for (i = 0; i < pickedPrimitives.length; ++i) { - pickedPrimitives[i].show = true; - } + // Draw terrain classification + us.updatePass(Pass.TERRAIN_CLASSIFICATION); + commands = frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION]; + length = frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - for (i = 0; i < pickedAttributes.length; ++i) { - attributes = pickedAttributes[i]; - attributes.show = ShowGeometryInstanceAttribute.toValue(true, attributes.show); - } + // Draw classification marked for both terrain and 3D Tiles classification + us.updatePass(Pass.CLASSIFICATION); + commands = frustumCommands.commands[Pass.CLASSIFICATION]; + length = frustumCommands.indices[Pass.CLASSIFICATION]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - return result; - }; + if (clearGlobeDepth) { + clearDepth.execute(context, passState); + } - /** - * Instantly completes an active transition. - */ - Scene.prototype.completeMorph = function(){ - this._transitioner.completeMorph(); - }; + if (!environmentState.useInvertClassification || picking) { + // Common/fastest path. Draw 3D Tiles and classification normally. - /** - * Asynchronously transitions the scene to 2D. - * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. - */ - Scene.prototype.morphTo2D = function(duration) { - var ellipsoid; - var globe = this.globe; - if (defined(globe)) { - ellipsoid = globe.ellipsoid; - } else { - ellipsoid = this.mapProjection.ellipsoid; - } - duration = defaultValue(duration, 2.0); - this._transitioner.morphTo2D(duration, ellipsoid); - }; + // Draw 3D Tiles + us.updatePass(Pass.CESIUM_3D_TILE); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - /** - * Asynchronously transitions the scene to Columbus View. - * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. - */ - Scene.prototype.morphToColumbusView = function(duration) { - var ellipsoid; - var globe = this.globe; - if (defined(globe)) { - ellipsoid = globe.ellipsoid; - } else { - ellipsoid = this.mapProjection.ellipsoid; - } - duration = defaultValue(duration, 2.0); - this._transitioner.morphToColumbusView(duration, ellipsoid); - }; + // Draw classifications. Modifies 3D Tiles color. + us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - /** - * Asynchronously transitions the scene to 3D. - * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. - */ - Scene.prototype.morphTo3D = function(duration) { - var ellipsoid; - var globe = this.globe; - if (defined(globe)) { - ellipsoid = globe.ellipsoid; - } else { - ellipsoid = this.mapProjection.ellipsoid; - } - duration = defaultValue(duration, 2.0); - this._transitioner.morphTo3D(duration, ellipsoid); - }; + // Draw classification marked for both terrain and 3D Tiles classification + us.updatePass(Pass.CLASSIFICATION); + commands = frustumCommands.commands[Pass.CLASSIFICATION]; + length = frustumCommands.indices[Pass.CLASSIFICATION]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } + } else { + // When the invert classification color is opaque: + // Main FBO (FBO1): Main_Color + Main_DepthStencil + // Invert classification FBO (FBO2) : Invert_Color + Main_DepthStencil + // + // 1. Clear FBO2 color to vec4(0.0) for each frustum + // 2. Draw 3D Tiles to FBO2 + // 3. Draw classification to FBO2 + // 4. Fullscreen pass to FBO1, draw Invert_Color when: + // * Main_DepthStencil has the stencil bit set > 0 (classified) + // 5. Fullscreen pass to FBO1, draw Invert_Color * czm_invertClassificationColor when: + // * Main_DepthStencil has stencil bit set to 0 (unclassified) and + // * Invert_Color !== vec4(0.0) + // + // When the invert classification color is translucent: + // Main FBO (FBO1): Main_Color + Main_DepthStencil + // Invert classification FBO (FBO2): Invert_Color + Invert_DepthStencil + // IsClassified FBO (FBO3): IsClassified_Color + Invert_DepthStencil + // + // 1. Clear FBO2 and FBO3 color to vec4(0.0), stencil to 0, and depth to 1.0 + // 2. Draw 3D Tiles to FBO2 + // 3. Draw classification to FBO2 + // 4. Fullscreen pass to FBO3, draw any color when + // * Invert_DepthStencil has the stencil bit set > 0 (classified) + // 5. Fullscreen pass to FBO1, draw Invert_Color when: + // * Invert_Color !== vec4(0.0) and + // * IsClassified_Color !== vec4(0.0) + // 6. Fullscreen pass to FBO1, draw Invert_Color * czm_invertClassificationColor when: + // * Invert_Color !== vec4(0.0) and + // * IsClassified_Color === vec4(0.0) + // + // NOTE: Step six when translucent invert color occurs after the TRANSLUCENT pass + // + scene._invertClassification.clear(context, passState); - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see Scene#destroy - */ - Scene.prototype.isDestroyed = function() { - return false; - }; + var opaqueClassificationFramebuffer = passState.framebuffer; + passState.framebuffer = scene._invertClassification._fbo; - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * scene = scene && scene.destroy(); - * - * @see Scene#isDestroyed - */ - Scene.prototype.destroy = function() { - this._tweens.removeAll(); - this._computeEngine = this._computeEngine && this._computeEngine.destroy(); - this._screenSpaceCameraController = this._screenSpaceCameraController && this._screenSpaceCameraController.destroy(); - this._deviceOrientationCameraController = this._deviceOrientationCameraController && !this._deviceOrientationCameraController.isDestroyed() && this._deviceOrientationCameraController.destroy(); - this._pickFramebuffer = this._pickFramebuffer && this._pickFramebuffer.destroy(); - this._pickDepthFramebuffer = this._pickDepthFramebuffer && this._pickDepthFramebuffer.destroy(); - this._primitives = this._primitives && this._primitives.destroy(); - this._groundPrimitives = this._groundPrimitives && this._groundPrimitives.destroy(); - this._globe = this._globe && this._globe.destroy(); - this.skyBox = this.skyBox && this.skyBox.destroy(); - this.skyAtmosphere = this.skyAtmosphere && this.skyAtmosphere.destroy(); - this._debugSphere = this._debugSphere && this._debugSphere.destroy(); - this.sun = this.sun && this.sun.destroy(); - this._sunPostProcess = this._sunPostProcess && this._sunPostProcess.destroy(); - this._depthPlane = this._depthPlane && this._depthPlane.destroy(); - this._transitioner.destroy(); - this._debugFrustumPlanes = this._debugFrustumPlanes && this._debugFrustumPlanes.destroy(); - this._brdfLutGenerator = this._brdfLutGenerator && this._brdfLutGenerator.destroy(); + // Draw normally + us.updatePass(Pass.CESIUM_3D_TILE); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - if (defined(this._globeDepth)) { - this._globeDepth.destroy(); - } - if (this._removeCreditContainer) { - this._canvas.parentNode.removeChild(this._creditContainer); - } + // Set stencil + us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - if (defined(this._oit)) { - this._oit.destroy(); - } - this._fxaa.destroy(); + passState.framebuffer = opaqueClassificationFramebuffer; - this._context = this._context && this._context.destroy(); - this._frameState.creditDisplay.destroy(); - if (defined(this._performanceDisplay)){ - this._performanceDisplay = this._performanceDisplay && this._performanceDisplay.destroy(); - this._performanceContainer.parentNode.removeChild(this._performanceContainer); - } + // Fullscreen pass to copy classified fragments + scene._invertClassification.executeClassified(context, passState); + if (scene.frameState.invertClassificationColor.alpha === 1.0) { + // Fullscreen pass to copy unclassified fragments when alpha == 1.0 + scene._invertClassification.executeUnclassified(context, passState); + } - return destroyObject(this); - }; + // Clear stencil set by the classification for the next classification pass + if (length > 0 && context.stencilBuffer) { + scene._stencilClearCommand.execute(context, passState); + } - /** - * Transforms a position in cartesian coordinates to canvas coordinates. This is commonly used to place an - * HTML element at the same screen position as an object in the scene. - * - * @param {Cartesian3} position The position in cartesian coordinates. - * @param {Cartesian2} [result] An optional object to return the input position transformed to canvas coordinates. - * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid. - * - * @example - * // Output the canvas position of longitude/latitude (0, 0) every time the mouse moves. - * var scene = widget.scene; - * var ellipsoid = scene.globe.ellipsoid; - * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0); - * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - * handler.setInputAction(function(movement) { - * console.log(scene.cartesianToCanvasCoordinates(position)); - * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - */ - Scene.prototype.cartesianToCanvasCoordinates = function(position, result) { - return SceneTransforms.wgs84ToWindowCoordinates(this, position, result); - }; + // Draw style over classification. + us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - return Scene; -}); + // Draw style over classification marked for both terrain and 3D Tiles classification + us.updatePass(Pass.CLASSIFICATION); + commands = frustumCommands.commands[Pass.CLASSIFICATION]; + length = frustumCommands.indices[Pass.CLASSIFICATION]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } + } -define('Scene/SingleTileImageryProvider',[ - '../Core/Credit', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/Event', - '../Core/GeographicTilingScheme', - '../Core/loadImage', - '../Core/Rectangle', - '../Core/RuntimeError', - '../Core/TileProviderError', - '../ThirdParty/when' - ], function( - Credit, - defaultValue, - defined, - defineProperties, - DeveloperError, - Event, - GeographicTilingScheme, - loadImage, - Rectangle, - RuntimeError, - TileProviderError, - when) { - 'use strict'; + if (length > 0 && context.stencilBuffer) { + scene._stencilClearCommand.execute(context, passState); + } - /** - * Provides a single, top-level imagery tile. The single image is assumed to use a - * {@link GeographicTilingScheme}. - * - * @alias SingleTileImageryProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The url for the tile. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed. - * - * @see ArcGisMapServerImageryProvider - * @see BingMapsImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider - */ - function SingleTileImageryProvider(options) { - options = defaultValue(options, {}); - var url = options.url; + if (clearGlobeDepth && useDepthPlane) { + depthPlane.execute(context, passState); + } - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - this._url = url; + us.updatePass(Pass.OPAQUE); + commands = frustumCommands.commands[Pass.OPAQUE]; + length = frustumCommands.indices[Pass.OPAQUE]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } - var proxy = options.proxy; - this._proxy = proxy; + if (index !== 0 && scene.mode !== SceneMode.SCENE2D) { + // Do not overlap frustums in the translucent pass to avoid blending artifacts + frustum.near = frustumCommands.near; + us.updateFrustum(frustum); + } - var rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE); - var tilingScheme = new GeographicTilingScheme({ - rectangle : rectangle, - numberOfLevelZeroTilesX : 1, - numberOfLevelZeroTilesY : 1, - ellipsoid : options.ellipsoid - }); - this._tilingScheme = tilingScheme; + var invertClassification; + if (!picking && environmentState.useInvertClassification && scene.frameState.invertClassificationColor.alpha < 1.0) { + // Fullscreen pass to copy unclassified fragments when alpha < 1.0. + // Not executed when undefined. + invertClassification = scene._invertClassification; + } - this._image = undefined; - this._texture = undefined; - this._tileWidth = 0; - this._tileHeight = 0; + us.updatePass(Pass.TRANSLUCENT); + commands = frustumCommands.commands[Pass.TRANSLUCENT]; + commands.length = frustumCommands.indices[Pass.TRANSLUCENT]; + executeTranslucentCommands(scene, executeCommand, passState, commands, invertClassification); - this._errorEvent = new Event(); + if (defined(globeDepth) && (environmentState.useGlobeDepthFramebuffer || depthOnly) && scene.useDepthPicking) { + // PERFORMANCE_IDEA: Use MRT to avoid the extra copy. + var depthStencilTexture = depthOnly ? passState.framebuffer.depthStencilTexture : globeDepth.framebuffer.depthStencilTexture; + var pickDepth = getPickDepth(scene, index); + pickDepth.update(context, depthStencilTexture); + pickDepth.executeCopyDepth(context, passState); + } + } + } - this._ready = false; - this._readyPromise = when.defer(); + function executeComputeCommands(scene) { + var us = scene.context.uniformState; + us.updatePass(Pass.COMPUTE); - var imageUrl = url; - if (defined(proxy)) { - imageUrl = proxy.getURL(imageUrl); + var sunComputeCommand = scene._environmentState.sunComputeCommand; + if (defined(sunComputeCommand)) { + sunComputeCommand.execute(scene._computeEngine); } - var credit = options.credit; - if (typeof credit === 'string') { - credit = new Credit({text: credit}); + var commandList = scene._computeCommandList; + var length = commandList.length; + for (var i = 0; i < length; ++i) { + commandList[i].execute(scene._computeEngine); } - this._credit = credit; + } - var that = this; - var error; + function executeOverlayCommands(scene, passState) { + var us = scene.context.uniformState; + us.updatePass(Pass.OVERLAY); - function success(image) { - that._image = image; - that._tileWidth = image.width; - that._tileHeight = image.height; - that._ready = true; - that._readyPromise.resolve(true); - TileProviderError.handleSuccess(that._errorEvent); + var context = scene.context; + var commandList = scene._overlayCommandList; + var length = commandList.length; + for (var i = 0; i < length; ++i) { + commandList[i].execute(context, passState); } + } - function failure(e) { - var message = 'Failed to load image ' + imageUrl + '.'; - error = TileProviderError.handleError( - error, - that, - that._errorEvent, - message, - 0, 0, 0, - doRequest, - e); - that._readyPromise.reject(new RuntimeError(message)); + function insertShadowCastCommands(scene, commandList, shadowMap) { + var shadowVolume = shadowMap.shadowMapCullingVolume; + var isPointLight = shadowMap.isPointLight; + var passes = shadowMap.passes; + var numberOfPasses = passes.length; + + var length = commandList.length; + for (var i = 0; i < length; ++i) { + var command = commandList[i]; + updateDerivedCommands(scene, command); + + if (command.castShadows && (command.pass === Pass.GLOBE || command.pass === Pass.CESIUM_3D_TILE || command.pass === Pass.OPAQUE || command.pass === Pass.TRANSLUCENT)) { + if (isVisible(command, shadowVolume)) { + if (isPointLight) { + for (var k = 0; k < numberOfPasses; ++k) { + passes[k].commandList.push(command); + } + } else if (numberOfPasses === 1) { + passes[0].commandList.push(command); + } else { + var wasVisible = false; + // Loop over cascades from largest to smallest + for (var j = numberOfPasses - 1; j >= 0; --j) { + var cascadeVolume = passes[j].cullingVolume; + if (isVisible(command, cascadeVolume)) { + passes[j].commandList.push(command); + wasVisible = true; + } else if (wasVisible) { + // If it was visible in the previous cascade but now isn't + // then there is no need to check any more cascades + break; + } + } + } + } + } } + } - function doRequest() { - when(loadImage(imageUrl), success, failure); + function executeShadowMapCastCommands(scene) { + var frameState = scene.frameState; + var shadowMaps = frameState.shadowHints.shadowMaps; + var shadowMapLength = shadowMaps.length; + + if (!frameState.shadowHints.shadowsEnabled) { + return; } - doRequest(); - } + var context = scene.context; + var uniformState = context.uniformState; - defineProperties(SingleTileImageryProvider.prototype, { - /** - * Gets the URL of the single, top-level imagery tile. - * @memberof SingleTileImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; + for (var i = 0; i < shadowMapLength; ++i) { + var shadowMap = shadowMaps[i]; + if (shadowMap.outOfView) { + continue; } - }, - /** - * Gets the proxy used by this provider. - * @memberof SingleTileImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._proxy; + // Reset the command lists + var j; + var passes = shadowMap.passes; + var numberOfPasses = passes.length; + for (j = 0; j < numberOfPasses; ++j) { + passes[j].commandList.length = 0; } - }, - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileWidth must not be called before the imagery provider is ready.'); - } - - return this._tileWidth; - } - }, + // Insert the primitive/model commands into the command lists + var sceneCommands = scene.frameState.commandList; + insertShadowCastCommands(scene, sceneCommands, shadowMap); - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight: { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileHeight must not be called before the imagery provider is ready.'); + for (j = 0; j < numberOfPasses; ++j) { + var pass = shadowMap.passes[j]; + uniformState.updateCamera(pass.camera); + shadowMap.updatePass(context, j); + var numberOfCommands = pass.commandList.length; + for (var k = 0; k < numberOfCommands; ++k) { + var command = pass.commandList[k]; + // Set the correct pass before rendering into the shadow map because some shaders + // conditionally render based on whether the pass is translucent or opaque. + uniformState.updatePass(command.pass); + executeCommand(command.derivedCommands.shadows.castCommands[i], scene, context, pass.passState); } - - return this._tileHeight; } - }, + } + } - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('maximumLevel must not be called before the imagery provider is ready.'); - } - - return 0; - } - }, + var scratchEyeTranslation = new Cartesian3(); - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - if (!this._ready) { - throw new DeveloperError('minimumLevel must not be called before the imagery provider is ready.'); - } - - return 0; - } - }, + function updateAndExecuteCommands(scene, passState, backgroundColor) { + var context = scene._context; - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tilingScheme must not be called before the imagery provider is ready.'); - } - - return this._tilingScheme; - } - }, + var viewport = passState.viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = context.drawingBufferWidth; + viewport.height = context.drawingBufferHeight; - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - return this._tilingScheme.rectangle; - } - }, + var frameState = scene._frameState; + var camera = frameState.camera; + var mode = frameState.mode; + var depthOnly = frameState.passes.depth; - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - if (!this._ready) { - throw new DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.'); - } - - return undefined; - } - }, + if (scene._useWebVR && mode !== SceneMode.SCENE2D) { + updateAndClearFramebuffers(scene, passState, backgroundColor); - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof SingleTileImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._errorEvent; + if (!depthOnly) { + updateAndRenderPrimitives(scene); } - }, - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof SingleTileImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._ready; - } - }, + createPotentiallyVisibleSet(scene); - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof SingleTileImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise.promise; + if (!depthOnly) { + executeComputeCommands(scene); + executeShadowMapCastCommands(scene); } - }, - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link SingleTileImageryProvider#ready} returns true. - * @memberof SingleTileImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return this._credit; - } - }, + // Based on Calculating Stereo pairs by Paul Bourke + // http://paulbourke.net/stereographics/stereorender/ - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof SingleTileImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - hasAlphaChannel : { - get : function() { - return true; - } - } - }); + viewport.x = 0; + viewport.y = 0; + viewport.width = context.drawingBufferWidth * 0.5; + viewport.height = context.drawingBufferHeight; - /** - * Gets the credits to be displayed when a given tile is displayed. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. - */ - SingleTileImageryProvider.prototype.getTileCredits = function(x, y, level) { - return undefined; - }; + var savedCamera = Camera.clone(camera, scene._cameraVR); - /** - * Requests the image for a given tile. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. - * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. - */ - SingleTileImageryProvider.prototype.requestImage = function(x, y, level, request) { - if (!this._ready) { - throw new DeveloperError('requestImage must not be called before the imagery provider is ready.'); - } - - return this._image; - }; + var near = camera.frustum.near; + var fo = near * defaultValue(scene.focalLength, 5.0); + var eyeSeparation = defaultValue(scene.eyeSeparation, fo / 30.0); + var eyeTranslation = Cartesian3.multiplyByScalar(savedCamera.right, eyeSeparation * 0.5, scratchEyeTranslation); - /** - * Picking features is not currently supported by this imagery provider, so this function simply returns - * undefined. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. - */ - SingleTileImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return undefined; - }; + camera.frustum.aspectRatio = viewport.width / viewport.height; - return SingleTileImageryProvider; -}); + var offset = 0.5 * eyeSeparation * near / fo; -/** - * @license - * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the project nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Modifications made by Analytical Graphics, Inc. - */ -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SkyAtmosphereFS',[],function() { - 'use strict'; - return "#ifdef COLOR_CORRECT\n\ -uniform vec3 u_hsbShift;\n\ -#endif\n\ -uniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\n\ -const float g = -0.95;\n\ -const float g2 = g * g;\n\ -varying vec3 v_rayleighColor;\n\ -varying vec3 v_mieColor;\n\ -varying vec3 v_toCamera;\n\ -varying vec3 v_positionEC;\n\ -void main (void)\n\ -{\n\ -float cosAngle = dot(czm_sunDirectionWC, normalize(v_toCamera)) / length(v_toCamera);\n\ -float rayleighPhase = 0.75 * (1.0 + cosAngle * cosAngle);\n\ -float miePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cosAngle * cosAngle) / pow(1.0 + g2 - 2.0 * g * cosAngle, 1.5);\n\ -const float exposure = 2.0;\n\ -vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor;\n\ -rgb = vec3(1.0) - exp(-exposure * rgb);\n\ -float l = czm_luminance(rgb);\n\ -#ifdef COLOR_CORRECT\n\ -vec3 hsb = czm_RGBToHSB(rgb);\n\ -hsb.x += u_hsbShift.x;\n\ -hsb.y = clamp(hsb.y + u_hsbShift.y, 0.0, 1.0);\n\ -hsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0;\n\ -rgb = czm_HSBToRGB(hsb);\n\ -l = min(l, czm_luminance(rgb));\n\ -#endif\n\ -float atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0);\n\ -float nightAlpha = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), 0.0, 1.0) : 1.0;\n\ -atmosphereAlpha *= pow(nightAlpha, 0.5);\n\ -gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime));\n\ -}\n\ -"; -}); -/** - * @license - * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the project nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Modifications made by Analytical Graphics, Inc. - */ -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SkyAtmosphereVS',[],function() { - 'use strict'; - return "attribute vec4 position;\n\ -uniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\n\ -const float Kr = 0.0025;\n\ -const float Kr4PI = Kr * 4.0 * czm_pi;\n\ -const float Km = 0.0015;\n\ -const float Km4PI = Km * 4.0 * czm_pi;\n\ -const float ESun = 15.0;\n\ -const float KmESun = Km * ESun;\n\ -const float KrESun = Kr * ESun;\n\ -const vec3 InvWavelength = vec3(\n\ -5.60204474633241,\n\ -9.473284437923038,\n\ -19.643802610477206);\n\ -const float rayleighScaleDepth = 0.25;\n\ -const int nSamples = 2;\n\ -const float fSamples = 2.0;\n\ -varying vec3 v_rayleighColor;\n\ -varying vec3 v_mieColor;\n\ -varying vec3 v_toCamera;\n\ -float scale(float cosAngle)\n\ -{\n\ -float x = 1.0 - cosAngle;\n\ -return rayleighScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\n\ -}\n\ -void main(void)\n\ -{\n\ -float cameraHeight = u_cameraAndRadiiAndDynamicAtmosphereColor.x;\n\ -float outerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.y;\n\ -float innerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.z;\n\ -vec3 positionV3 = position.xyz;\n\ -vec3 ray = positionV3 - czm_viewerPositionWC;\n\ -float far = length(ray);\n\ -ray /= far;\n\ -float atmosphereScale = 1.0 / (outerRadius - innerRadius);\n\ -#ifdef SKY_FROM_SPACE\n\ -float B = 2.0 * dot(czm_viewerPositionWC, ray);\n\ -float C = cameraHeight * cameraHeight - outerRadius * outerRadius;\n\ -float det = max(0.0, B*B - 4.0 * C);\n\ -float near = 0.5 * (-B - sqrt(det));\n\ -vec3 start = czm_viewerPositionWC + ray * near;\n\ -far -= near;\n\ -float startAngle = dot(ray, start) / outerRadius;\n\ -float startDepth = exp(-1.0 / rayleighScaleDepth );\n\ -float startOffset = startDepth*scale(startAngle);\n\ -#else // SKY_FROM_ATMOSPHERE\n\ -vec3 start = czm_viewerPositionWC;\n\ -float height = length(start);\n\ -float depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - cameraHeight));\n\ -float startAngle = dot(ray, start) / height;\n\ -float startOffset = depth*scale(startAngle);\n\ -#endif\n\ -float sampleLength = far / fSamples;\n\ -float scaledLength = sampleLength * atmosphereScale;\n\ -vec3 sampleRay = ray * sampleLength;\n\ -vec3 samplePoint = start + sampleRay * 0.5;\n\ -vec3 frontColor = vec3(0.0, 0.0, 0.0);\n\ -vec3 lightDir = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? czm_sunPositionWC - czm_viewerPositionWC : czm_viewerPositionWC;\n\ -lightDir = normalize(lightDir);\n\ -for(int i=0; i<nSamples; i++)\n\ -{\n\ -float height = length(samplePoint);\n\ -float depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - height));\n\ -float fLightAngle = dot(lightDir, samplePoint) / height;\n\ -float fCameraAngle = dot(ray, samplePoint) / height;\n\ -float fScatter = (startOffset + depth*(scale(fLightAngle) - scale(fCameraAngle)));\n\ -vec3 attenuate = exp(-fScatter * (InvWavelength * Kr4PI + Km4PI));\n\ -frontColor += attenuate * (depth * scaledLength);\n\ -samplePoint += sampleRay;\n\ -}\n\ -v_mieColor = frontColor * KmESun;\n\ -v_rayleighColor = frontColor * (InvWavelength * KrESun);\n\ -v_toCamera = czm_viewerPositionWC - positionV3;\n\ -gl_Position = czm_modelViewProjection * position;\n\ -}\n\ -"; -}); -define('Scene/SkyAtmosphere',[ - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/Ellipsoid', - '../Core/EllipsoidGeometry', - '../Core/GeometryPipeline', - '../Core/Math', - '../Core/VertexFormat', - '../Renderer/BufferUsage', - '../Renderer/DrawCommand', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Renderer/VertexArray', - '../Shaders/SkyAtmosphereFS', - '../Shaders/SkyAtmosphereVS', - './BlendingState', - './CullFace', - './SceneMode' - ], function( - Cartesian3, - Cartesian4, - defaultValue, - defined, - defineProperties, - destroyObject, - Ellipsoid, - EllipsoidGeometry, - GeometryPipeline, - CesiumMath, - VertexFormat, - BufferUsage, - DrawCommand, - RenderState, - ShaderProgram, - ShaderSource, - VertexArray, - SkyAtmosphereFS, - SkyAtmosphereVS, - BlendingState, - CullFace, - SceneMode) { - 'use strict'; + Cartesian3.add(savedCamera.position, eyeTranslation, camera.position); + camera.frustum.xOffset = offset; + + executeCommands(scene, passState); + + viewport.x = passState.viewport.width; + + Cartesian3.subtract(savedCamera.position, eyeTranslation, camera.position); + camera.frustum.xOffset = -offset; - /** - * An atmosphere drawn around the limb of the provided ellipsoid. Based on - * {@link http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering} - * in GPU Gems 2. - * <p> - * This is only supported in 3D. atmosphere is faded out when morphing to 2D or Columbus view. - * </p> - * - * @alias SkyAtmosphere - * @constructor - * - * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around. - * - * @example - * scene.skyAtmosphere = new Cesium.SkyAtmosphere(); - * - * @see Scene.skyAtmosphere - */ - function SkyAtmosphere(ellipsoid) { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + executeCommands(scene, passState); - /** - * Determines if the atmosphere is shown. - * - * @type {Boolean} - * @default true - */ - this.show = true; + Camera.clone(savedCamera, camera); + } else if (mode !== SceneMode.SCENE2D || scene._mapMode2D === MapMode2D.ROTATE) { + executeCommandsInViewport(true, scene, passState, backgroundColor); + } else { + updateAndClearFramebuffers(scene, passState, backgroundColor); + execute2DViewportCommands(scene, passState); + } + } - this._ellipsoid = ellipsoid; - this._command = new DrawCommand({ - owner : this - }); - this._spSkyFromSpace = undefined; - this._spSkyFromAtmosphere = undefined; + var scratch2DViewportCartographic = new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO); + var scratch2DViewportMaxCoord = new Cartesian3(); + var scratch2DViewportSavedPosition = new Cartesian3(); + var scratch2DViewportTransform = new Matrix4(); + var scratch2DViewportCameraTransform = new Matrix4(); + var scratch2DViewportEyePoint = new Cartesian3(); + var scratch2DViewportWindowCoords = new Cartesian3(); + var scratch2DViewport = new BoundingRectangle(); - this._spSkyFromSpaceColorCorrect = undefined; - this._spSkyFromAtmosphereColorCorrect = undefined; + function execute2DViewportCommands(scene, passState) { + var context = scene.context; + var frameState = scene.frameState; + var camera = scene.camera; - /** - * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift). - * A hue shift of 1.0 indicates a complete rotation of the hues available. - * @type {Number} - * @default 0.0 - */ - this.hueShift = 0.0; + var originalViewport = passState.viewport; + var viewport = BoundingRectangle.clone(originalViewport, scratch2DViewport); + passState.viewport = viewport; - /** - * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift). - * A saturation shift of -1.0 is monochrome. - * @type {Number} - * @default 0.0 - */ - this.saturationShift = 0.0; + var maxCartographic = scratch2DViewportCartographic; + var maxCoord = scratch2DViewportMaxCoord; - /** - * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift). - * A brightness shift of -1.0 is complete darkness, which will let space show through. - * @type {Number} - * @default 0.0 - */ - this.brightnessShift = 0.0; + var projection = scene.mapProjection; + projection.project(maxCartographic, maxCoord); - this._hueSaturationBrightness = new Cartesian3(); + var position = Cartesian3.clone(camera.position, scratch2DViewportSavedPosition); + var transform = Matrix4.clone(camera.transform, scratch2DViewportCameraTransform); + var frustum = camera.frustum.clone(); - // camera height, outer radius, inner radius, dynamic atmosphere color flag - var cameraAndRadiiAndDynamicAtmosphereColor = new Cartesian4(); + camera._setTransform(Matrix4.IDENTITY); - // Toggles whether the sun position is used. 0 treats the sun as always directly overhead. - cameraAndRadiiAndDynamicAtmosphereColor.w = 0; - cameraAndRadiiAndDynamicAtmosphereColor.y = Cartesian3.maximumComponent(Cartesian3.multiplyByScalar(ellipsoid.radii, 1.025, new Cartesian3())); - cameraAndRadiiAndDynamicAtmosphereColor.z = ellipsoid.maximumRadius; + var viewportTransformation = Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, scratch2DViewportTransform); + var projectionMatrix = camera.frustum.projectionMatrix; - this._cameraAndRadiiAndDynamicAtmosphereColor = cameraAndRadiiAndDynamicAtmosphereColor; + var x = camera.positionWC.y; + var eyePoint = Cartesian3.fromElements(CesiumMath.sign(x) * maxCoord.x - x, 0.0, -camera.positionWC.x, scratch2DViewportEyePoint); + var windowCoordinates = Transforms.pointToGLWindowCoordinates(projectionMatrix, viewportTransformation, eyePoint, scratch2DViewportWindowCoords); - var that = this; + windowCoordinates.x = Math.floor(windowCoordinates.x); - this._command.uniformMap = { - u_cameraAndRadiiAndDynamicAtmosphereColor : function() { - return that._cameraAndRadiiAndDynamicAtmosphereColor; - }, - u_hsbShift : function() { - that._hueSaturationBrightness.x = that.hueShift; - that._hueSaturationBrightness.y = that.saturationShift; - that._hueSaturationBrightness.z = that.brightnessShift; - return that._hueSaturationBrightness; - } - }; - } + var viewportX = viewport.x; + var viewportWidth = viewport.width; - defineProperties(SkyAtmosphere.prototype, { - /** - * Gets the ellipsoid the atmosphere is drawn around. - * @memberof SkyAtmosphere.prototype - * - * @type {Ellipsoid} - * @readonly - */ - ellipsoid : { - get : function() { - return this._ellipsoid; - } + if (x === 0.0 || windowCoordinates.x <= viewportX || windowCoordinates.x >= viewportX + viewportWidth) { + executeCommandsInViewport(true, scene, passState); + } else if (Math.abs(viewportX + viewportWidth * 0.5 - windowCoordinates.x) < 1.0) { + viewport.width = windowCoordinates.x - viewport.x; + + camera.position.x *= CesiumMath.sign(camera.position.x); + + camera.frustum.right = 0.0; + + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + context.uniformState.update(frameState); + + executeCommandsInViewport(true, scene, passState); + + viewport.x = windowCoordinates.x; + + camera.position.x = -camera.position.x; + + camera.frustum.right = -camera.frustum.left; + camera.frustum.left = 0.0; + + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + context.uniformState.update(frameState); + + executeCommandsInViewport(false, scene, passState); + } else if (windowCoordinates.x > viewportX + viewportWidth * 0.5) { + viewport.width = windowCoordinates.x - viewportX; + + var right = camera.frustum.right; + camera.frustum.right = maxCoord.x - x; + + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + context.uniformState.update(frameState); + + executeCommandsInViewport(true, scene, passState); + + viewport.x = windowCoordinates.x; + viewport.width = viewportX + viewportWidth - windowCoordinates.x; + + camera.position.x = -camera.position.x; + + camera.frustum.left = -camera.frustum.right; + camera.frustum.right = right - camera.frustum.right * 2.0; + + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + context.uniformState.update(frameState); + + executeCommandsInViewport(false, scene, passState); + } else { + viewport.x = windowCoordinates.x; + viewport.width = viewportX + viewportWidth - windowCoordinates.x; + + var left = camera.frustum.left; + camera.frustum.left = -maxCoord.x - x; + + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + context.uniformState.update(frameState); + + executeCommandsInViewport(true, scene, passState); + + viewport.x = viewportX; + viewport.width = windowCoordinates.x - viewportX; + + camera.position.x = -camera.position.x; + + camera.frustum.right = -camera.frustum.left; + camera.frustum.left = left - camera.frustum.left * 2.0; + + frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + context.uniformState.update(frameState); + + executeCommandsInViewport(false, scene, passState); } - }); - /** - * @private - */ - SkyAtmosphere.prototype.setDynamicAtmosphereColor = function(enableLighting) { - this._cameraAndRadiiAndDynamicAtmosphereColor.w = enableLighting ? 1 : 0; - }; + camera._setTransform(transform); + Cartesian3.clone(position, camera.position); + camera.frustum = frustum.clone(); + passState.viewport = originalViewport; + } - /** - * @private - */ - SkyAtmosphere.prototype.update = function(frameState) { - if (!this.show) { - return undefined; + function executeCommandsInViewport(firstViewport, scene, passState, backgroundColor) { + var depthOnly = scene.frameState.passes.depth; + + if (!firstViewport && !depthOnly) { + scene.frameState.commandList.length = 0; } - var mode = frameState.mode; - if ((mode !== SceneMode.SCENE3D) && - (mode !== SceneMode.MORPHING)) { - return undefined; + if (!depthOnly) { + updateAndRenderPrimitives(scene); } - // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc. - if (!frameState.passes.render) { - return undefined; + createPotentiallyVisibleSet(scene); + + if (firstViewport) { + if (defined(backgroundColor)) { + updateAndClearFramebuffers(scene, passState, backgroundColor); + } + if (!depthOnly) { + executeComputeCommands(scene); + executeShadowMapCastCommands(scene); + } } - var command = this._command; + executeCommands(scene, passState); + } - if (!defined(command.vertexArray)) { - var context = frameState.context; + function updateEnvironment(scene, passState) { + var frameState = scene._frameState; - var geometry = EllipsoidGeometry.createGeometry(new EllipsoidGeometry({ - radii : Cartesian3.multiplyByScalar(this._ellipsoid.radii, 1.025, new Cartesian3()), - slicePartitions : 256, - stackPartitions : 256, - vertexFormat : VertexFormat.POSITION_ONLY - })); - command.vertexArray = VertexArray.fromGeometry({ - context : context, - geometry : geometry, - attributeLocations : GeometryPipeline.createAttributeLocations(geometry), - bufferUsage : BufferUsage.STATIC_DRAW - }); - command.renderState = RenderState.fromCache({ - cull : { - enabled : true, - face : CullFace.FRONT - }, - blending : BlendingState.ALPHA_BLEND - }); + // Update celestial and terrestrial environment effects. + var environmentState = scene._environmentState; + var renderPass = frameState.passes.render; + var skyAtmosphere = scene.skyAtmosphere; + var globe = scene.globe; - var vs = new ShaderSource({ - defines : ['SKY_FROM_SPACE'], - sources : [SkyAtmosphereVS] - }); + if (!renderPass || (scene._mode !== SceneMode.SCENE2D && frameState.camera.frustum instanceof OrthographicFrustum)) { + environmentState.skyAtmosphereCommand = undefined; + environmentState.skyBoxCommand = undefined; + environmentState.sunDrawCommand = undefined; + environmentState.sunComputeCommand = undefined; + environmentState.moonCommand = undefined; + } else { + if (defined(skyAtmosphere) && defined(globe)) { + skyAtmosphere.setDynamicAtmosphereColor(globe.enableLighting); + environmentState.isReadyForAtmosphere = environmentState.isReadyForAtmosphere || globe._surface._tilesToRender.length > 0; + } + environmentState.skyAtmosphereCommand = defined(skyAtmosphere) ? skyAtmosphere.update(frameState) : undefined; + environmentState.skyBoxCommand = defined(scene.skyBox) ? scene.skyBox.update(frameState) : undefined; + var sunCommands = defined(scene.sun) ? scene.sun.update(frameState, passState) : undefined; + environmentState.sunDrawCommand = defined(sunCommands) ? sunCommands.drawCommand : undefined; + environmentState.sunComputeCommand = defined(sunCommands) ? sunCommands.computeCommand : undefined; + environmentState.moonCommand = defined(scene.moon) ? scene.moon.update(frameState) : undefined; + } - this._spSkyFromSpace = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : vs, - fragmentShaderSource : SkyAtmosphereFS - }); + var clearGlobeDepth = environmentState.clearGlobeDepth = defined(globe) && (!globe.depthTestAgainstTerrain || scene.mode === SceneMode.SCENE2D); + var useDepthPlane = environmentState.useDepthPlane = clearGlobeDepth && scene.mode === SceneMode.SCENE3D; + if (useDepthPlane) { + // Update the depth plane that is rendered in 3D when the primitives are + // not depth tested against terrain so primitives on the backface + // of the globe are not picked. + scene._depthPlane.update(frameState); + } - vs = new ShaderSource({ - defines : ['SKY_FROM_ATMOSPHERE'], - sources : [SkyAtmosphereVS] - }); - this._spSkyFromAtmosphere = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : vs, - fragmentShaderSource : SkyAtmosphereFS - }); + var occluder = (frameState.mode === SceneMode.SCENE3D) ? frameState.occluder: undefined; + var cullingVolume = frameState.cullingVolume; + + // get user culling volume minus the far plane. + var planes = scratchCullingVolume.planes; + for (var k = 0; k < 5; ++k) { + planes[k] = cullingVolume.planes[k]; } + cullingVolume = scratchCullingVolume; - // Compile the color correcting versions of the shader on demand - var useColorCorrect = colorCorrect(this); - if (useColorCorrect && (!defined(this._spSkyFromSpaceColorCorrect) || !defined(this._spSkyFromAtmosphereColorCorrect))) { - var contextColorCorrect = frameState.context; + // Determine visibility of celestial and terrestrial environment effects. + environmentState.isSkyAtmosphereVisible = defined(environmentState.skyAtmosphereCommand) && environmentState.isReadyForAtmosphere; + environmentState.isSunVisible = isVisible(environmentState.sunDrawCommand, cullingVolume, occluder); + environmentState.isMoonVisible = isVisible(environmentState.moonCommand, cullingVolume, occluder); + } - var vsColorCorrect = new ShaderSource({ - defines : ['SKY_FROM_SPACE'], - sources : [SkyAtmosphereVS] - }); - var fsColorCorrect = new ShaderSource({ - defines : ['COLOR_CORRECT'], - sources : [SkyAtmosphereFS] - }); + function updateDebugFrustumPlanes(scene) { + var frameState = scene._frameState; + if (scene.debugShowFrustumPlanes !== scene._debugShowFrustumPlanes) { + if (scene.debugShowFrustumPlanes) { + scene._debugFrustumPlanes = new DebugCameraPrimitive({ + camera: scene.camera, + updateOnChange: false + }); + } else { + scene._debugFrustumPlanes = scene._debugFrustumPlanes && scene._debugFrustumPlanes.destroy(); + } + scene._debugShowFrustumPlanes = scene.debugShowFrustumPlanes; + } - this._spSkyFromSpaceColorCorrect = ShaderProgram.fromCache({ - context : contextColorCorrect, - vertexShaderSource : vsColorCorrect, - fragmentShaderSource : fsColorCorrect - }); - vsColorCorrect = new ShaderSource({ - defines : ['SKY_FROM_ATMOSPHERE'], - sources : [SkyAtmosphereVS] - }); - this._spSkyFromAtmosphereColorCorrect = ShaderProgram.fromCache({ - context : contextColorCorrect, - vertexShaderSource : vsColorCorrect, - fragmentShaderSource : fsColorCorrect - }); + if (defined(scene._debugFrustumPlanes)) { + scene._debugFrustumPlanes.update(frameState); } + } - var cameraPosition = frameState.camera.positionWC; + function updateShadowMaps(scene) { + var frameState = scene._frameState; + var shadowMaps = frameState.shadowMaps; + var length = shadowMaps.length; - var cameraHeight = Cartesian3.magnitude(cameraPosition); - this._cameraAndRadiiAndDynamicAtmosphereColor.x = cameraHeight; + var shadowsEnabled = (length > 0) && !frameState.passes.pick && (scene.mode === SceneMode.SCENE3D); + if (shadowsEnabled !== frameState.shadowHints.shadowsEnabled) { + // Update derived commands when shadowsEnabled changes + ++frameState.shadowHints.lastDirtyTime; + frameState.shadowHints.shadowsEnabled = shadowsEnabled; + } - if (cameraHeight > this._cameraAndRadiiAndDynamicAtmosphereColor.y) { - // Camera in space - command.shaderProgram = useColorCorrect ? this._spSkyFromSpaceColorCorrect : this._spSkyFromSpace; - } else { - // Camera in atmosphere - command.shaderProgram = useColorCorrect ? this._spSkyFromAtmosphereColorCorrect : this._spSkyFromAtmosphere; + if (!shadowsEnabled) { + return; } - return command; - }; + // Check if the shadow maps are different than the shadow maps last frame. + // If so, the derived commands need to be updated. + for (var j = 0; j < length; ++j) { + if (shadowMaps[j] !== frameState.shadowHints.shadowMaps[j]) { + ++frameState.shadowHints.lastDirtyTime; + break; + } + } - function colorCorrect(skyAtmosphere) { - return !(CesiumMath.equalsEpsilon(skyAtmosphere.hueShift, 0.0, CesiumMath.EPSILON7) && - CesiumMath.equalsEpsilon(skyAtmosphere.saturationShift, 0.0, CesiumMath.EPSILON7) && - CesiumMath.equalsEpsilon(skyAtmosphere.brightnessShift, 0.0, CesiumMath.EPSILON7)); - } + frameState.shadowHints.shadowMaps.length = 0; + frameState.shadowHints.lightShadowMaps.length = 0; - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see SkyAtmosphere#destroy - */ - SkyAtmosphere.prototype.isDestroyed = function() { - return false; - }; + for (var i = 0; i < length; ++i) { + var shadowMap = shadowMaps[i]; + shadowMap.update(frameState); - /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy(); - * - * @see SkyAtmosphere#isDestroyed - */ - SkyAtmosphere.prototype.destroy = function() { - var command = this._command; - command.vertexArray = command.vertexArray && command.vertexArray.destroy(); - this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy(); - this._spSkyFromAtmosphere = this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy(); - this._spSkyFromSpaceColorCorrect = this._spSkyFromSpaceColorCorrect && this._spSkyFromSpaceColorCorrect.destroy(); - this._spSkyFromAtmosphereColorCorrect = this._spSkyFromAtmosphereColorCorrect && this._spSkyFromAtmosphereColorCorrect.destroy(); - return destroyObject(this); - }; + frameState.shadowHints.shadowMaps.push(shadowMap); - return SkyAtmosphere; -}); + if (shadowMap.fromLightSource) { + frameState.shadowHints.lightShadowMaps.push(shadowMap); + } -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SkyBoxFS',[],function() { - 'use strict'; - return "uniform samplerCube u_cubeMap;\n\ -varying vec3 v_texCoord;\n\ -void main()\n\ -{\n\ -vec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb;\n\ -gl_FragColor = vec4(rgb, czm_morphTime);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SkyBoxVS',[],function() { - 'use strict'; - return "attribute vec3 position;\n\ -varying vec3 v_texCoord;\n\ -void main()\n\ -{\n\ -vec3 p = czm_viewRotation * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\n\ -gl_Position = czm_projection * vec4(p, 1.0);\n\ -v_texCoord = position.xyz;\n\ -}\n\ -"; -}); -define('Scene/SkyBox',[ - '../Core/BoxGeometry', - '../Core/Cartesian3', - '../Core/defaultValue', - '../Core/defined', - '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/GeometryPipeline', - '../Core/Matrix4', - '../Core/VertexFormat', - '../Renderer/BufferUsage', - '../Renderer/CubeMap', - '../Renderer/DrawCommand', - '../Renderer/loadCubeMap', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/VertexArray', - '../Shaders/SkyBoxFS', - '../Shaders/SkyBoxVS', - './BlendingState', - './SceneMode' - ], function( - BoxGeometry, - Cartesian3, - defaultValue, - defined, - destroyObject, - DeveloperError, - GeometryPipeline, - Matrix4, - VertexFormat, - BufferUsage, - CubeMap, - DrawCommand, - loadCubeMap, - RenderState, - ShaderProgram, - VertexArray, - SkyBoxFS, - SkyBoxVS, - BlendingState, - SceneMode) { - 'use strict'; + if (shadowMap.dirty) { + ++frameState.shadowHints.lastDirtyTime; + shadowMap.dirty = false; + } + } + } - /** - * A sky box around the scene to draw stars. The sky box is defined using the True Equator Mean Equinox (TEME) axes. - * <p> - * This is only supported in 3D. The sky box is faded out when morphing to 2D or Columbus view. The size of - * the sky box must not exceed {@link Scene#maximumCubeMapSize}. - * </p> - * - * @alias SkyBox - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {Object} [options.sources] The source URL or <code>Image</code> object for each of the six cube map faces. See the example below. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * - * - * @example - * scene.skyBox = new Cesium.SkyBox({ - * sources : { - * positiveX : 'skybox_px.png', - * negativeX : 'skybox_nx.png', - * positiveY : 'skybox_py.png', - * negativeY : 'skybox_ny.png', - * positiveZ : 'skybox_pz.png', - * negativeZ : 'skybox_nz.png' - * } - * }); - * - * @see Scene#skyBox - * @see Transforms.computeTemeToPseudoFixedMatrix - */ - function SkyBox(options) { - /** - * The sources used to create the cube map faces: an object - * with <code>positiveX</code>, <code>negativeX</code>, <code>positiveY</code>, - * <code>negativeY</code>, <code>positiveZ</code>, and <code>negativeZ</code> properties. - * These can be either URLs or <code>Image</code> objects. - * - * @type Object - * @default undefined - */ - this.sources = options.sources; - this._sources = undefined; + function updateAndRenderPrimitives(scene) { + var frameState = scene._frameState; - /** - * Determines if the sky box will be shown. - * - * @type {Boolean} - * @default true - */ - this.show = defaultValue(options.show, true); + scene._groundPrimitives.update(frameState); + scene._primitives.update(frameState); - this._command = new DrawCommand({ - modelMatrix : Matrix4.clone(Matrix4.IDENTITY), - owner : this - }); - this._cubeMap = undefined; + updateDebugFrustumPlanes(scene); + updateShadowMaps(scene); + + if (scene._globe) { + scene._globe.render(frameState); + } } - /** - * Called when {@link Viewer} or {@link CesiumWidget} render the scene to - * get the draw commands needed to render this primitive. - * <p> - * Do not call this function directly. This is documented just to - * list the exceptions that may be propagated when the scene is rendered: - * </p> - * - * @exception {DeveloperError} this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. - * @exception {DeveloperError} this.sources properties must all be the same type. - */ - SkyBox.prototype.update = function(frameState) { - var that = this; + function updateAndClearFramebuffers(scene, passState, clearColor) { + var context = scene._context; + var environmentState = scene._environmentState; - if (!this.show) { - return undefined; + var passes = scene._frameState.passes; + var picking = passes.pick; + var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; + + // Preserve the reference to the original framebuffer. + environmentState.originalFramebuffer = passState.framebuffer; + + // Manage sun bloom post-processing effect. + if (defined(scene.sun) && scene.sunBloom !== scene._sunBloom) { + if (scene.sunBloom && !useWebVR) { + scene._sunPostProcess = new SunPostProcess(); + } else if(defined(scene._sunPostProcess)){ + scene._sunPostProcess = scene._sunPostProcess.destroy(); + } + + scene._sunBloom = scene.sunBloom; + } else if (!defined(scene.sun) && defined(scene._sunPostProcess)) { + scene._sunPostProcess = scene._sunPostProcess.destroy(); + scene._sunBloom = false; } - if ((frameState.mode !== SceneMode.SCENE3D) && - (frameState.mode !== SceneMode.MORPHING)) { - return undefined; + // Clear the pass state framebuffer. + var clear = scene._clearColorCommand; + Color.clone(clearColor, clear.color); + clear.execute(context, passState); + + // Update globe depth rendering based on the current context and clear the globe depth framebuffer. + var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = !picking && defined(scene._globeDepth); + if (useGlobeDepthFramebuffer) { + scene._globeDepth.update(context, passState); + scene._globeDepth.clear(context, passState, clearColor); } - // The sky box is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc. - if (!frameState.passes.render) { - return undefined; + // If supported, configure OIT to use the globe depth framebuffer and clear the OIT framebuffer. + var useOIT = environmentState.useOIT = !picking && defined(scene._oit) && scene._oit.isSupported(); + if (useOIT) { + scene._oit.update(context, passState, scene._globeDepth.framebuffer); + scene._oit.clear(context, passState, clearColor); + environmentState.useOIT = scene._oit.isSupported(); } - var context = frameState.context; + // If supported, configure FXAA to use the globe depth color texture and clear the FXAA framebuffer. + var useFXAA = environmentState.useFXAA = !picking && scene.fxaa; + if (useFXAA) { + scene._fxaa.update(context, passState); + scene._fxaa.clear(context, passState, clearColor); + } - if (this._sources !== this.sources) { - this._sources = this.sources; - var sources = this.sources; + if (environmentState.isSunVisible && scene.sunBloom && !useWebVR) { + passState.framebuffer = scene._sunPostProcess.update(passState); + } else if (useGlobeDepthFramebuffer) { + passState.framebuffer = scene._globeDepth.framebuffer; + } else if (useFXAA) { + passState.framebuffer = scene._fxaa.getColorFramebuffer(); + } - if ((!defined(sources.positiveX)) || - (!defined(sources.negativeX)) || - (!defined(sources.positiveY)) || - (!defined(sources.negativeY)) || - (!defined(sources.positiveZ)) || - (!defined(sources.negativeZ))) { - throw new DeveloperError('this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.'); - } + if (defined(passState.framebuffer)) { + clear.execute(context, passState); + } - if ((typeof sources.positiveX !== typeof sources.negativeX) || - (typeof sources.positiveX !== typeof sources.positiveY) || - (typeof sources.positiveX !== typeof sources.negativeY) || - (typeof sources.positiveX !== typeof sources.positiveZ) || - (typeof sources.positiveX !== typeof sources.negativeZ)) { - throw new DeveloperError('this.sources properties must all be the same type.'); + var useInvertClassification = environmentState.useInvertClassification = !picking && defined(passState.framebuffer) && scene.invertClassification; + if (useInvertClassification) { + var depthFramebuffer; + if (scene.frameState.invertClassificationColor.alpha === 1.0) { + if (environmentState.useGlobeDepthFramebuffer) { + depthFramebuffer = scene._globeDepth.framebuffer; + } else if (environmentState.useFXAA) { + depthFramebuffer = scene._fxaa.getColorFramebuffer(); + } } - - if (typeof sources.positiveX === 'string') { - // Given urls for cube-map images. Load them. - loadCubeMap(context, this._sources).then(function(cubeMap) { - that._cubeMap = that._cubeMap && that._cubeMap.destroy(); - that._cubeMap = cubeMap; - }); - } else { - this._cubeMap = this._cubeMap && this._cubeMap.destroy(); - this._cubeMap = new CubeMap({ - context : context, - source : sources - }); + + scene._invertClassification.previousFramebuffer = depthFramebuffer; + scene._invertClassification.update(context); + scene._invertClassification.clear(context, passState); + + if (scene.frameState.invertClassificationColor.alpha < 1.0 && useOIT) { + var command = scene._invertClassification.unclassifiedCommand; + var derivedCommands = command.derivedCommands; + derivedCommands.oit = scene._oit.createDerivedCommands(command, context, derivedCommands.oit); } } + } - var command = this._command; + function resolveFramebuffers(scene, passState) { + var context = scene._context; + var environmentState = scene._environmentState; - if (!defined(command.vertexArray)) { - command.uniformMap = { - u_cubeMap: function() { - return that._cubeMap; - } - }; + var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer; + if (scene.debugShowGlobeDepth && useGlobeDepthFramebuffer) { + var gd = getDebugGlobeDepth(scene, scene.debugShowDepthFrustum - 1); + gd.executeDebugGlobeDepth(context, passState); + } - var geometry = BoxGeometry.createGeometry(BoxGeometry.fromDimensions({ - dimensions : new Cartesian3(2.0, 2.0, 2.0), - vertexFormat : VertexFormat.POSITION_ONLY - })); - var attributeLocations = GeometryPipeline.createAttributeLocations(geometry); + if (scene.debugShowPickDepth && useGlobeDepthFramebuffer) { + var pd = getPickDepth(scene, scene.debugShowDepthFrustum - 1); + pd.executeDebugPickDepth(context, passState); + } - command.vertexArray = VertexArray.fromGeometry({ - context : context, - geometry : geometry, - attributeLocations : attributeLocations, - bufferUsage : BufferUsage.STATIC_DRAW - }); + var useOIT = environmentState.useOIT; + var useFXAA = environmentState.useFXAA; - command.shaderProgram = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : SkyBoxVS, - fragmentShaderSource : SkyBoxFS, - attributeLocations : attributeLocations - }); + if (useOIT) { + passState.framebuffer = useFXAA ? scene._fxaa.getColorFramebuffer() : undefined; + scene._oit.execute(context, passState); + } - command.renderState = RenderState.fromCache({ - blending : BlendingState.ALPHA_BLEND - }); + if (useFXAA) { + if (!useOIT && useGlobeDepthFramebuffer) { + passState.framebuffer = scene._fxaa.getColorFramebuffer(); + scene._globeDepth.executeCopyColor(context, passState); + } + + passState.framebuffer = environmentState.originalFramebuffer; + scene._fxaa.execute(context, passState); } - if (!defined(this._cubeMap)) { - return undefined; + if (!useOIT && !useFXAA && useGlobeDepthFramebuffer) { + passState.framebuffer = environmentState.originalFramebuffer; + scene._globeDepth.executeCopyColor(context, passState); } + } - return command; - }; + function callAfterRenderFunctions(scene) { + // Functions are queued up during primitive update and executed here in case + // the function modifies scene state that should remain constant over the frame. + var functions = scene._frameState.afterRender; + for (var i = 0, length = functions.length; i < length; ++i) { + functions[i](); + scene.requestRender(); + } - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see SkyBox#destroy - */ - SkyBox.prototype.isDestroyed = function() { - return false; - }; + functions.length = 0; + } /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * - * @example - * skyBox = skyBox && skyBox.destroy(); - * - * @see SkyBox#isDestroyed + * @private */ - SkyBox.prototype.destroy = function() { - var command = this._command; - command.vertexArray = command.vertexArray && command.vertexArray.destroy(); - command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); - this._cubeMap = this._cubeMap && this._cubeMap.destroy(); - return destroyObject(this); + Scene.prototype.initializeFrame = function() { + // Destroy released shaders once every 120 frames to avoid thrashing the cache + if (this._shaderFrameCount++ === 120) { + this._shaderFrameCount = 0; + this._context.shaderCache.destroyReleasedShaderPrograms(); + } + + this._tweens.update(); + + this._screenSpaceCameraController.update(); + if (defined(this._deviceOrientationCameraController)) { + this._deviceOrientationCameraController.update(); + } + + this._camera.update(this._mode); + this._camera._updateCameraChanged(); }; - return SkyBox; -}); + function checkForCameraUpdates(scene) { + var camera = scene._camera; + if (!cameraEqual(camera, scene._cameraClone, CesiumMath.EPSILON15)) { + if (!scene._cameraStartFired) { + camera.moveStart.raiseEvent(); + scene._cameraStartFired = true; + } + scene._cameraMovedTime = getTimestamp(); + Camera.clone(camera, scene._cameraClone); -define('Scene/SphereEmitter',[ - '../Core/Cartesian3', - '../Core/Check', - '../Core/defaultValue', - '../Core/defineProperties', - '../Core/Math' - ], function( - Cartesian3, - Check, - defaultValue, - defineProperties, - CesiumMath) { - 'use strict'; + return true; + } - /** - * A ParticleEmitter that emits particles within a sphere. - * Particles will be positioned randomly within the sphere and have initial velocities emanating from the center of the sphere. - * - * @alias SphereEmitter - * @constructor - * - * @param {Number} [radius=1.0] The radius of the sphere in meters. - */ - function SphereEmitter(radius) { - radius = defaultValue(radius, 1.0); + if (scene._cameraStartFired && getTimestamp() - scene._cameraMovedTime > scene.cameraEventWaitTime) { + camera.moveEnd.raiseEvent(); + scene._cameraStartFired = false; + } - Check.typeOf.number.greaterThan('radius', radius, 0.0); - - this._radius = defaultValue(radius, 1.0); + return false; } - defineProperties(SphereEmitter.prototype, { - /** - * The radius of the sphere in meters. - * @memberof SphereEmitter.prototype - * @type {Number} - * @default 1.0 - */ - radius : { - get : function() { - return this._radius; - }, - set : function(value) { - Check.typeOf.number.greaterThan('value', value, 0.0); - this._radius = value; + function updateDebugShowFramesPerSecond(scene, renderedThisFrame) { + if (scene.debugShowFramesPerSecond) { + if (!defined(scene._performanceDisplay)) { + var performanceContainer = document.createElement('div'); + performanceContainer.className = 'cesium-performanceDisplay-defaultContainer'; + var container = scene._canvas.parentNode; + container.appendChild(performanceContainer); + var performanceDisplay = new PerformanceDisplay({container: performanceContainer}); + scene._performanceDisplay = performanceDisplay; + scene._performanceContainer = performanceContainer; } + + scene._performanceDisplay.throttled = scene.requestRenderMode; + scene._performanceDisplay.update(renderedThisFrame); + } else if (defined(scene._performanceDisplay)) { + scene._performanceDisplay = scene._performanceDisplay && scene._performanceDisplay.destroy(); + scene._performanceContainer.parentNode.removeChild(scene._performanceContainer); } - }); + } + + function update(scene) { + var frameState = scene._frameState; + + if (defined(scene.globe)) { + scene.globe.update(frameState); + } + + frameState.creditDisplay.update(); + } + + function render(scene, time) { + scene._pickPositionCacheDirty = true; + + var context = scene.context; + var us = context.uniformState; + var frameState = scene._frameState; + + var frameNumber = CesiumMath.incrementWrap(frameState.frameNumber, 15000000.0, 1.0); + updateFrameState(scene, frameNumber, time); + frameState.passes.render = true; + + var backgroundColor = defaultValue(scene.backgroundColor, Color.BLACK); + frameState.backgroundColor = backgroundColor; + + frameState.creditDisplay.beginFrame(); + + scene.fog.update(frameState); + + us.update(frameState); + + var shadowMap = scene.shadowMap; + if (defined(shadowMap) && shadowMap.enabled) { + // Update the sun's direction + Cartesian3.negate(us.sunDirectionWC, scene._sunCamera.direction); + frameState.shadowMaps.push(shadowMap); + } + + scene._computeCommandList.length = 0; + scene._overlayCommandList.length = 0; + + var passState = scene._passState; + passState.framebuffer = undefined; + passState.blendingEnabled = undefined; + passState.scissorTest = undefined; + + if (defined(scene.globe)) { + scene.globe.beginFrame(frameState); + } + + updateEnvironment(scene, passState); + updateAndExecuteCommands(scene, passState, backgroundColor); + resolveFramebuffers(scene, passState); + executeOverlayCommands(scene, passState); + + if (defined(scene.globe)) { + scene.globe.endFrame(frameState); + } + + frameState.creditDisplay.endFrame(); + context.endFrame(); + } + + function tryAndCatchError(scene, time, functionToExecute) { + try { + functionToExecute(scene, time); + } catch (error) { + scene._renderError.raiseEvent(scene, error); + + if (scene.rethrowRenderErrors) { + throw error; + } + } + } /** - * Initializes the given {Particle} by setting it's position and velocity. + * Update and render the scene. + * @param {JulianDate} [time] The simulation time at which to render. * * @private - * @param {Particle} particle The particle to initialize */ - SphereEmitter.prototype.emit = function(particle) { - var theta = CesiumMath.randomBetween(0.0, CesiumMath.TWO_PI); - var phi = CesiumMath.randomBetween(0.0, CesiumMath.PI); - var rad = CesiumMath.randomBetween(0.0, this._radius); + Scene.prototype.render = function(time) { + if (!defined(time)) { + time = JulianDate.now(); + } - var x = rad * Math.cos(theta) * Math.sin(phi); - var y = rad * Math.sin(theta) * Math.sin(phi); - var z = rad * Math.cos(phi); + this._jobScheduler.resetBudgets(); - particle.position = Cartesian3.fromElements(x, y, z, particle.position); - particle.velocity = Cartesian3.normalize(particle.position, particle.velocity); - }; + // Update + this._preUpdate.raiseEvent(this, time); + tryAndCatchError(this, time, update); + this._postUpdate.raiseEvent(this, time); - return SphereEmitter; -}); + var cameraChanged = checkForCameraUpdates(this); + var shouldRender = !this.requestRenderMode || this._renderRequested || cameraChanged || (this.mode === SceneMode.MORPHING); + if (!shouldRender && defined(this.maximumRenderTimeChange) && defined(this._lastRenderTime)) { + var difference = Math.abs(JulianDate.secondsDifference(this._lastRenderTime, time)); + shouldRender = shouldRender || difference > this.maximumRenderTimeChange; + } -define('Scene/StyleExpression',[ - '../Core/DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + if (shouldRender) { + this._lastRenderTime = JulianDate.clone(time, this._lastRenderTime); + this._renderRequested = false; - /** - * An expression for a style applied to a {@link Cesium3DTileset}. - * <p> - * Derived classes of this interface evaluate expressions in the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. - * </p> - * <p> - * This type describes an interface and is not intended to be instantiated directly. - * </p> - * - * @alias StyleExpression - * @constructor - * - * @see Expression - * @see ConditionsExpression - */ - function StyleExpression() { - } + // Render + this._preRender.raiseEvent(this, time); + tryAndCatchError(this, time, render); + this._postRender.raiseEvent(this, time); + + RequestScheduler.update(); + } + + updateDebugShowFramesPerSecond(this, shouldRender); + callAfterRenderFunctions(this); + }; /** - * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of - * the expression in the - * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} - * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript - * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code> - * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>, - * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is - * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. + * Update and render the scene. Always forces a new render frame regardless of whether a render was + * previously requested. + * @param {JulianDate} [time] The simulation time at which to render. * - * @param {FrameState} frameState The frame state. - * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Object} [result] The object onto which to store the result. - * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. + * @private */ - StyleExpression.prototype.evaluate = function(frameState, feature, result) { - DeveloperError.throwInstantiationError(); + Scene.prototype.forceRender = function(time) { + this._renderRequested = true; + this.render(time); }; /** - * Evaluates the result of a Color expression, optionally using the provided feature's properties. - * <p> - * This is equivalent to {@link StyleExpression#evaluate} but always returns a {@link Color} object. - * </p> + * Requests a new rendered frame when {@link Scene#requestRenderMode} is set to <code>true</code>. + * The render rate will not exceed the {@link CesiumWidget#targetFrameRate}. * - * @param {FrameState} frameState The frame state. - * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Color} [result] The object in which to store the result. - * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + * @see Scene#requestRenderMode */ - StyleExpression.prototype.evaluateColor = function(frameState, feature, result) { - DeveloperError.throwInstantiationError(); + Scene.prototype.requestRender = function() { + this._renderRequested = true; }; /** - * Gets the shader function for this expression. - * Returns undefined if the shader function can't be generated from this expression. - * - * @param {String} functionName Name to give to the generated function. - * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * @param {String} returnType The return type of the generated function. - * - * @returns {String} The shader function. - * * @private */ - StyleExpression.prototype.getShaderFunction = function(functionName, attributePrefix, shaderState, returnType) { - DeveloperError.throwInstantiationError(); + Scene.prototype.clampLineWidth = function(width) { + return Math.max(ContextLimits.minimumAliasedLineWidth, Math.min(width, ContextLimits.maximumAliasedLineWidth)); }; - return StyleExpression; -}); + var orthoPickingFrustum = new OrthographicOffCenterFrustum(); + var scratchOrigin = new Cartesian3(); + var scratchDirection = new Cartesian3(); + var scratchPixelSize = new Cartesian2(); + var scratchPickVolumeMatrix4 = new Matrix4(); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SunFS',[],function() { - 'use strict'; - return "uniform sampler2D u_texture;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -gl_FragColor = texture2D(u_texture, v_textureCoordinates);\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SunTextureFS',[],function() { - 'use strict'; - return "uniform float u_glowLengthTS;\n\ -uniform float u_radiusTS;\n\ -varying vec2 v_textureCoordinates;\n\ -vec2 rotate(vec2 p, vec2 direction)\n\ -{\n\ -return vec2(p.x * direction.x - p.y * direction.y, p.x * direction.y + p.y * direction.x);\n\ -}\n\ -vec4 addBurst(vec2 position, vec2 direction)\n\ -{\n\ -vec2 rotatedPosition = rotate(position, direction) * vec2(25.0, 0.75);\n\ -float radius = length(rotatedPosition);\n\ -float burst = 1.0 - smoothstep(0.0, 0.55, radius);\n\ -return vec4(burst);\n\ -}\n\ -void main()\n\ -{\n\ -vec2 position = v_textureCoordinates - vec2(0.5);\n\ -float radius = length(position);\n\ -float surface = step(radius, u_radiusTS);\n\ -vec4 color = vec4(1.0, 1.0, surface + 0.2, surface);\n\ -float glow = 1.0 - smoothstep(0.0, 0.55, radius);\n\ -color.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75;\n\ -vec4 burst = vec4(0.0);\n\ -burst += 0.4 * addBurst(position, vec2(0.38942, 0.92106));\n\ -burst += 0.4 * addBurst(position, vec2(0.99235, 0.12348));\n\ -burst += 0.4 * addBurst(position, vec2(0.60327, -0.79754));\n\ -burst += 0.3 * addBurst(position, vec2(0.31457, 0.94924));\n\ -burst += 0.3 * addBurst(position, vec2(0.97931, 0.20239));\n\ -burst += 0.3 * addBurst(position, vec2(0.66507, -0.74678));\n\ -color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15;\n\ -gl_FragColor = clamp(color, vec4(0.0), vec4(1.0));\n\ -}\n\ -"; -}); -//This file is automatically rebuilt by the Cesium build process. -define('Shaders/SunVS',[],function() { - 'use strict'; - return "attribute vec2 direction;\n\ -uniform float u_size;\n\ -varying vec2 v_textureCoordinates;\n\ -void main()\n\ -{\n\ -vec4 position;\n\ -if (czm_morphTime == 1.0)\n\ -{\n\ -position = vec4(czm_sunPositionWC, 1.0);\n\ -}\n\ -else\n\ -{\n\ -position = vec4(czm_sunPositionColumbusView.zxy, 1.0);\n\ -}\n\ -vec4 positionEC = czm_view * position;\n\ -vec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\n\ -vec2 halfSize = vec2(u_size * 0.5);\n\ -halfSize *= ((direction * 2.0) - 1.0);\n\ -gl_Position = czm_viewportOrthographic * vec4(positionWC.xy + halfSize, -positionWC.z, 1.0);\n\ -v_textureCoordinates = direction;\n\ -}\n\ -"; -}); -define('Scene/Sun',[ - '../Core/BoundingSphere', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartesian4', - '../Core/ComponentDatatype', - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/IndexDatatype', - '../Core/Math', - '../Core/Matrix4', - '../Core/PixelFormat', - '../Core/PrimitiveType', - '../Renderer/Buffer', - '../Renderer/BufferUsage', - '../Renderer/ComputeCommand', - '../Renderer/DrawCommand', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/Texture', - '../Renderer/VertexArray', - '../Shaders/SunFS', - '../Shaders/SunTextureFS', - '../Shaders/SunVS', - './BlendingState', - './SceneMode', - './SceneTransforms' - ], function( - BoundingSphere, - Cartesian2, - Cartesian3, - Cartesian4, - ComponentDatatype, - defined, - defineProperties, - destroyObject, - IndexDatatype, - CesiumMath, - Matrix4, - PixelFormat, - PrimitiveType, - Buffer, - BufferUsage, - ComputeCommand, - DrawCommand, - RenderState, - ShaderProgram, - Texture, - VertexArray, - SunFS, - SunTextureFS, - SunVS, - BlendingState, - SceneMode, - SceneTransforms) { - 'use strict'; + function getPickOrthographicCullingVolume(scene, drawingBufferPosition, width, height) { + var camera = scene._camera; + var frustum = camera.frustum; + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } - /** - * Draws a sun billboard. - * <p>This is only supported in 3D and Columbus view.</p> - * - * @alias Sun - * @constructor - * - * - * @example - * scene.sun = new Cesium.Sun(); - * - * @see Scene#sun - */ - function Sun() { - /** - * Determines if the sun will be shown. - * - * @type {Boolean} - * @default true - */ - this.show = true; + var viewport = scene._passState.viewport; + var x = 2.0 * (drawingBufferPosition.x - viewport.x) / viewport.width - 1.0; + x *= (frustum.right - frustum.left) * 0.5; + var y = 2.0 * (viewport.height - drawingBufferPosition.y - viewport.y) / viewport.height - 1.0; + y *= (frustum.top - frustum.bottom) * 0.5; - this._drawCommand = new DrawCommand({ - primitiveType : PrimitiveType.TRIANGLES, - boundingVolume : new BoundingSphere(), - owner : this - }); - this._commands = { - drawCommand : this._drawCommand, - computeCommand : undefined - }; - this._boundingVolume = new BoundingSphere(); - this._boundingVolume2D = new BoundingSphere(); + var transform = Matrix4.clone(camera.transform, scratchPickVolumeMatrix4); + camera._setTransform(Matrix4.IDENTITY); - this._texture = undefined; - this._drawingBufferWidth = undefined; - this._drawingBufferHeight = undefined; - this._radiusTS = undefined; - this._size = undefined; + var origin = Cartesian3.clone(camera.position, scratchOrigin); + Cartesian3.multiplyByScalar(camera.right, x, scratchDirection); + Cartesian3.add(scratchDirection, origin, origin); + Cartesian3.multiplyByScalar(camera.up, y, scratchDirection); + Cartesian3.add(scratchDirection, origin, origin); - this.glowFactor = 1.0; - this._glowFactorDirty = false; + camera._setTransform(transform); - var that = this; - this._uniformMap = { - u_texture : function() { - return that._texture; - }, - u_size : function() { - return that._size; - } - }; + if (scene.mode === SceneMode.SCENE2D) { + Cartesian3.fromElements(origin.z, origin.x, origin.y, origin); + } + + var pixelSize = frustum.getPixelDimensions(viewport.width, viewport.height, 1.0, scratchPixelSize); + + var ortho = orthoPickingFrustum; + ortho.right = pixelSize.x * 0.5; + ortho.left = -ortho.right; + ortho.top = pixelSize.y * 0.5; + ortho.bottom = -ortho.top; + ortho.near = frustum.near; + ortho.far = frustum.far; + + return ortho.computeCullingVolume(origin, camera.directionWC, camera.upWC); } - defineProperties(Sun.prototype, { - /** - * Gets or sets a number that controls how "bright" the Sun's lens flare appears - * to be. Zero shows just the Sun's disc without any flare. - * Use larger values for a more pronounced flare around the Sun. - * - * @memberof Sun.prototype - * @type {Number} - * @default 1.0 - */ - glowFactor : { - get : function () { return this._glowFactor; }, - set : function (glowFactor) { - glowFactor = Math.max(glowFactor, 0.0); - this._glowFactor = glowFactor; - this._glowFactorDirty = true; - } + var perspPickingFrustum = new PerspectiveOffCenterFrustum(); + + function getPickPerspectiveCullingVolume(scene, drawingBufferPosition, width, height) { + var camera = scene._camera; + var frustum = camera.frustum; + var near = frustum.near; + + var tanPhi = Math.tan(frustum.fovy * 0.5); + var tanTheta = frustum.aspectRatio * tanPhi; + + var viewport = scene._passState.viewport; + var x = 2.0 * (drawingBufferPosition.x - viewport.x) / viewport.width - 1.0; + var y = 2.0 * (viewport.height - drawingBufferPosition.y - viewport.y) / viewport.height - 1.0; + + var xDir = x * near * tanTheta; + var yDir = y * near * tanPhi; + + var pixelSize = frustum.getPixelDimensions(viewport.width, viewport.height, 1.0, scratchPixelSize); + var pickWidth = pixelSize.x * width * 0.5; + var pickHeight = pixelSize.y * height * 0.5; + + var offCenter = perspPickingFrustum; + offCenter.top = yDir + pickHeight; + offCenter.bottom = yDir - pickHeight; + offCenter.right = xDir + pickWidth; + offCenter.left = xDir - pickWidth; + offCenter.near = near; + offCenter.far = frustum.far; + + return offCenter.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); + } + + function getPickCullingVolume(scene, drawingBufferPosition, width, height) { + var frustum = scene.camera.frustum; + if (frustum instanceof OrthographicFrustum || frustum instanceof OrthographicOffCenterFrustum) { + return getPickOrthographicCullingVolume(scene, drawingBufferPosition, width, height); } - }); - var scratchPositionWC = new Cartesian2(); - var scratchLimbWC = new Cartesian2(); - var scratchPositionEC = new Cartesian4(); - var scratchCartesian4 = new Cartesian4(); + return getPickPerspectiveCullingVolume(scene, drawingBufferPosition, width, height); + } + + // pick rectangle width and height, assumed odd + var rectangleWidth = 3.0; + var rectangleHeight = 3.0; + var scratchRectangle = new BoundingRectangle(0.0, 0.0, rectangleWidth, rectangleHeight); + var scratchColorZero = new Color(0.0, 0.0, 0.0, 0.0); + var scratchPosition = new Cartesian2(); /** - * @private + * Returns an object with a `primitive` property that contains the first (top) primitive in the scene + * at a particular window coordinate or undefined if nothing is at the location. Other properties may + * potentially be set depending on the type of primitive. + * <p> + * When a feature of a 3D Tiles tileset is picked, <code>pick</code> returns a {@link Cesium3DTileFeature} object. + * </p> + * + * @example + * // On mouse over, color the feature yellow. + * handler.setInputAction(function(movement) { + * var feature = scene.pick(movement.endPosition); + * if (feature instanceof Cesium.Cesium3DTileFeature) { + * feature.color = Cesium.Color.YELLOW; + * } + * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + * + * @param {Cartesian2} windowPosition Window coordinates to perform picking on. + * @param {Number} [width=3] Width of the pick rectangle. + * @param {Number} [height=3] Height of the pick rectangle. + * @returns {Object} Object containing the picked primitive. + * + * @exception {DeveloperError} windowPosition is undefined. */ - Sun.prototype.update = function(frameState, passState) { - if (!this.show) { - return undefined; + Scene.prototype.pick = function(windowPosition, width, height) { + if(!defined(windowPosition)) { + throw new DeveloperError('windowPosition is undefined.'); } + + rectangleWidth = defaultValue(width, 3.0); + rectangleHeight = defaultValue(height, rectangleWidth); - var mode = frameState.mode; - if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { - return undefined; - } + var context = this._context; + var us = context.uniformState; + var frameState = this._frameState; - if (!frameState.passes.render) { - return undefined; + var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); + + if (!defined(this._pickFramebuffer)) { + this._pickFramebuffer = context.createPickFramebuffer(); } - var context = frameState.context; - var drawingBufferWidth = passState.viewport.width; - var drawingBufferHeight = passState.viewport.height; + this._jobScheduler.disableThisFrame(); - if (!defined(this._texture) || - drawingBufferWidth !== this._drawingBufferWidth || - drawingBufferHeight !== this._drawingBufferHeight || - this._glowFactorDirty) { - this._texture = this._texture && this._texture.destroy(); - this._drawingBufferWidth = drawingBufferWidth; - this._drawingBufferHeight = drawingBufferHeight; - this._glowFactorDirty = false; + // Update with previous frame's number and time, assuming that render is called before picking. + updateFrameState(this, frameState.frameNumber, frameState.time); + frameState.cullingVolume = getPickCullingVolume(this, drawingBufferPosition, rectangleWidth, rectangleHeight); + frameState.invertClassification = false; + frameState.passes.pick = true; - var size = Math.max(drawingBufferWidth, drawingBufferHeight); - size = Math.pow(2.0, Math.ceil(Math.log(size) / Math.log(2.0)) - 2.0); + us.update(frameState); - // The size computed above can be less than 1.0 if size < 4.0. This will probably - // never happen in practice, but does in the tests. Clamp to 1.0 to prevent WebGL - // errors in the tests. - size = Math.max(1.0, size); + scratchRectangle.x = drawingBufferPosition.x - ((rectangleWidth - 1.0) * 0.5); + scratchRectangle.y = (this.drawingBufferHeight - drawingBufferPosition.y) - ((rectangleHeight - 1.0) * 0.5); + scratchRectangle.width = rectangleWidth; + scratchRectangle.height = rectangleHeight; + var passState = this._pickFramebuffer.begin(scratchRectangle); - this._texture = new Texture({ - context : context, - width : size, - height : size, - pixelFormat : PixelFormat.RGBA - }); + updateEnvironment(this, passState); + updateAndExecuteCommands(this, passState, scratchColorZero); + resolveFramebuffers(this, passState); - this._glowLengthTS = this._glowFactor * 5.0; - this._radiusTS = (1.0 / (1.0 + 2.0 * this._glowLengthTS)) * 0.5; + var object = this._pickFramebuffer.end(scratchRectangle); + context.endFrame(); + callAfterRenderFunctions(this); + return object; + }; - var that = this; - var uniformMap = { - u_glowLengthTS : function() { - return that._glowLengthTS; - }, - u_radiusTS : function() { - return that._radiusTS; - } - }; + var fragDepthRegex = /\bgl_FragDepthEXT\b/; + var discardRegex = /\bdiscard\b/; - this._commands.computeCommand = new ComputeCommand({ - fragmentShaderSource : SunTextureFS, - outputTexture : this._texture, - uniformMap : uniformMap, - persists : false, - owner : this, - postExecute : function() { - that._commands.computeCommand = undefined; + function getDepthOnlyShaderProgram(context, shaderProgram) { + var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'depthOnly'); + if (!defined(shader)) { + var attributeLocations = shaderProgram._attributeLocations; + var fs = shaderProgram.fragmentShaderSource; + + var writesDepthOrDiscards = false; + var sources = fs.sources; + var length = sources.length; + for (var i = 0; i < length; ++i) { + if (fragDepthRegex.test(sources[i]) || discardRegex.test(sources[i])) { + writesDepthOrDiscards = true; + break; } + } + + if (!writesDepthOrDiscards) { + fs = new ShaderSource({ + sources : ['void main() { gl_FragColor = vec4(1.0); }'] + }); + } + + shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'depthOnly', { + vertexShaderSource : shaderProgram.vertexShaderSource, + fragmentShaderSource : fs, + attributeLocations : attributeLocations }); } - var drawCommand = this._drawCommand; + return shader; + } - if (!defined(drawCommand.vertexArray)) { - var attributeLocations = { - direction : 0 + function getDepthOnlyRenderState(scene, renderState) { + var cache = scene._depthOnlyRenderStateCache; + var depthOnlyState = cache[renderState.id]; + if (!defined(depthOnlyState)) { + var rs = RenderState.getState(renderState); + rs.depthMask = true; + rs.colorMask = { + red : false, + green : false, + blue : false, + alpha : false }; - var directions = new Uint8Array(4 * 2); - directions[0] = 0; - directions[1] = 0; + depthOnlyState = RenderState.fromCache(rs); + cache[renderState.id] = depthOnlyState; + } - directions[2] = 255; - directions[3] = 0.0; + return depthOnlyState; + } - directions[4] = 255; - directions[5] = 255; + function createDepthOnlyDerivedCommand(scene, command, context, result) { + // For a depth only pass, we bind a framebuffer with only a depth attachment (no color attachments), + // do not write color, and write depth. If the fragment shader doesn't modify the fragment depth + // or discard, the driver can replace the fragment shader with a pass-through shader. We're unsure if this + // actually happens so we modify the shader to use a pass-through fragment shader. - directions[6] = 0.0; - directions[7] = 255; + if (!defined(result)) { + result = {}; + } - var vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : directions, - usage : BufferUsage.STATIC_DRAW - }); - var attributes = [{ - index : attributeLocations.direction, - vertexBuffer : vertexBuffer, - componentsPerAttribute : 2, - normalize : true, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE - }]; - // Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN - var indexBuffer = Buffer.createIndexBuffer({ - context : context, - typedArray : new Uint16Array([0, 1, 2, 0, 2, 3]), - usage : BufferUsage.STATIC_DRAW, - indexDatatype : IndexDatatype.UNSIGNED_SHORT - }); - drawCommand.vertexArray = new VertexArray({ - context : context, - attributes : attributes, - indexBuffer : indexBuffer - }); + var shader; + var renderState; + if (defined(result.depthOnlyCommand)) { + shader = result.depthOnlyCommand.shaderProgram; + renderState = result.depthOnlyCommand.renderState; + } - drawCommand.shaderProgram = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : SunVS, - fragmentShaderSource : SunFS, - attributeLocations : attributeLocations - }); + result.depthOnlyCommand = DrawCommand.shallowClone(command, result.depthOnlyCommand); - drawCommand.renderState = RenderState.fromCache({ - blending : BlendingState.ALPHA_BLEND - }); - drawCommand.uniformMap = this._uniformMap; + if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { + result.depthOnlyCommand.shaderProgram = getDepthOnlyShaderProgram(context, command.shaderProgram); + result.depthOnlyCommand.renderState = getDepthOnlyRenderState(scene, command.renderState); + result.shaderProgramId = command.shaderProgram.id; + } else { + result.depthOnlyCommand.shaderProgram = shader; + result.depthOnlyCommand.renderState = renderState; } - var sunPosition = context.uniformState.sunPositionWC; - var sunPositionCV = context.uniformState.sunPositionColumbusView; - - var boundingVolume = this._boundingVolume; - var boundingVolume2D = this._boundingVolume2D; + return result; + } - Cartesian3.clone(sunPosition, boundingVolume.center); - boundingVolume2D.center.x = sunPositionCV.z; - boundingVolume2D.center.y = sunPositionCV.x; - boundingVolume2D.center.z = sunPositionCV.y; + function renderTranslucentDepthForPick(scene, drawingBufferPosition) { + // PERFORMANCE_IDEA: render translucent only and merge with the previous frame + var context = scene._context; + var frameState = scene._frameState; - boundingVolume.radius = CesiumMath.SOLAR_RADIUS + CesiumMath.SOLAR_RADIUS * this._glowLengthTS; - boundingVolume2D.radius = boundingVolume.radius; + clearPasses(frameState.passes); + frameState.passes.pick = true; + frameState.passes.depth = true; + frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); - if (mode === SceneMode.SCENE3D) { - BoundingSphere.clone(boundingVolume, drawCommand.boundingVolume); - } else if (mode === SceneMode.COLUMBUS_VIEW) { - BoundingSphere.clone(boundingVolume2D, drawCommand.boundingVolume); + var passState = scene._pickDepthPassState; + if (!defined(passState)) { + passState = scene._pickDepthPassState = new PassState(context); + passState.scissorTest = { + enabled : true, + rectangle : new BoundingRectangle() + }; + passState.viewport = new BoundingRectangle(); } - var position = SceneTransforms.computeActualWgs84Position(frameState, sunPosition, scratchCartesian4); - - var dist = Cartesian3.magnitude(Cartesian3.subtract(position, frameState.camera.position, scratchCartesian4)); - var projMatrix = context.uniformState.projection; + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; - var positionEC = scratchPositionEC; - positionEC.x = 0; - positionEC.y = 0; - positionEC.z = -dist; - positionEC.w = 1; + var framebuffer = scene._pickDepthFramebuffer; + var pickDepthFBWidth = scene._pickDepthFramebufferWidth; + var pickDepthFBHeight = scene._pickDepthFramebufferHeight; + if (!defined(framebuffer) || pickDepthFBWidth !== width || pickDepthFBHeight !== height) { + scene._pickDepthFramebuffer = scene._pickDepthFramebuffer && scene._pickDepthFramebuffer.destroy(); + framebuffer = scene._pickDepthFramebuffer = new Framebuffer({ + context : context, + depthStencilTexture : new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.DEPTH_STENCIL, + pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 + }) + }); - var positionCC = Matrix4.multiplyByVector(projMatrix, positionEC, scratchCartesian4); - var positionWC = SceneTransforms.clipToGLWindowCoordinates(passState.viewport, positionCC, scratchPositionWC); + scene._pickDepthFramebufferWidth = width; + scene._pickDepthFramebufferHeight = height; + } - positionEC.x = CesiumMath.SOLAR_RADIUS; - var limbCC = Matrix4.multiplyByVector(projMatrix, positionEC, scratchCartesian4); - var limbWC = SceneTransforms.clipToGLWindowCoordinates(passState.viewport, limbCC, scratchLimbWC); + passState.framebuffer = framebuffer; + passState.viewport.width = width; + passState.viewport.height = height; + passState.scissorTest.rectangle.x = drawingBufferPosition.x; + passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; + passState.scissorTest.rectangle.width = 1; + passState.scissorTest.rectangle.height = 1; - this._size = Math.ceil(Cartesian2.magnitude(Cartesian2.subtract(limbWC, positionWC, scratchCartesian4))); - this._size = 2.0 * this._size * (1.0 + 2.0 * this._glowLengthTS); + updateEnvironment(scene, passState); + updateAndExecuteCommands(scene, passState, scratchColorZero); + resolveFramebuffers(scene, passState); - return this._commands; - }; + context.endFrame(); + } - /** - * Returns true if this object was destroyed; otherwise, false. - * <br /><br /> - * If this object was destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. - * - * @see Sun#destroy - */ - Sun.prototype.isDestroyed = function() { - return false; - }; + var scratchPackedDepth = new Cartesian4(); + var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); /** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - * <br /><br /> - * Once an object is destroyed, it should not be used; calling any function other than - * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (<code>undefined</code>) to the object as done in the example. - * - * @returns {undefined} - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * Returns the cartesian position reconstructed from the depth buffer and window position. + * The returned position is in world coordinates. Used internally by camera functions to + * prevent conversion to projected 2D coordinates and then back. + * <p> + * Set {@link Scene#pickTranslucentDepth} to <code>true</code> to include the depth of + * translucent primitives; otherwise, this essentially picks through translucent primitives. + * </p> * + * @private * - * @example - * sun = sun && sun.destroy(); + * @param {Cartesian2} windowPosition Window coordinates to perform picking on. + * @param {Cartesian3} [result] The object on which to restore the result. + * @returns {Cartesian3} The cartesian position in world coordinates. * - * @see Sun#isDestroyed + * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. */ - Sun.prototype.destroy = function() { - var command = this._drawCommand; - command.vertexArray = command.vertexArray && command.vertexArray.destroy(); - command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); + Scene.prototype.pickPositionWorldCoordinates = function(windowPosition, result) { + if (!this.useDepthPicking) { + return undefined; + } - this._texture = this._texture && this._texture.destroy(); + if(!defined(windowPosition)) { + throw new DeveloperError('windowPosition is undefined.'); + } + if (!defined(this._globeDepth)) { + throw new DeveloperError('Picking from the depth buffer is not supported. Check pickPositionSupported.'); + } + + var cacheKey = windowPosition.toString(); - return destroyObject(this); - }; + if (this._pickPositionCacheDirty){ + this._pickPositionCache = {}; + this._pickPositionCacheDirty = false; + } else if (this._pickPositionCache.hasOwnProperty(cacheKey)){ + return Cartesian3.clone(this._pickPositionCache[cacheKey], result); + } - return Sun; -}); + var context = this._context; + var uniformState = context.uniformState; -define('Scene/TileBoundingVolume',[ - '../Core/DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); + if (this.pickTranslucentDepth) { + renderTranslucentDepthForPick(this, drawingBufferPosition); + } + drawingBufferPosition.y = this.drawingBufferHeight - drawingBufferPosition.y; - /** - * Defines a bounding volume for a tile. This type describes an interface - * and is not intended to be instantiated directly. - * - * @see TileBoundingRegion - * @see TileBoundingSphere - * @see TileOrientedBoundingBox - * - * @private - */ - function TileBoundingVolume() { - } + var camera = this._camera; - /** - * The underlying bounding volume. - * - * @memberof TileBoundingVolume.prototype - * - * @type {Object} - * @readonly - */ - TileBoundingVolume.prototype.boundingVolume = undefined; + // Create a working frustum from the original camera frustum. + var frustum; + if (defined(camera.frustum.fov)) { + frustum = camera.frustum.clone(scratchPerspectiveFrustum); + } else if (defined(camera.frustum.infiniteProjectionMatrix)){ + frustum = camera.frustum.clone(scratchPerspectiveOffCenterFrustum); + } else if (defined(camera.frustum.width)) { + frustum = camera.frustum.clone(scratchOrthographicFrustum); + } else { + frustum = camera.frustum.clone(scratchOrthographicOffCenterFrustum); + } - /** - * The underlying bounding sphere. - * - * @memberof TileBoundingVolume.prototype - * - * @type {BoundingSphere} - * @readonly - */ - TileBoundingVolume.prototype.boundingSphere = undefined; + var numFrustums = this.numberOfFrustums; + for (var i = 0; i < numFrustums; ++i) { + var pickDepth = getPickDepth(this, i); + var pixels = context.readPixels({ + x : drawingBufferPosition.x, + y : drawingBufferPosition.y, + width : 1, + height : 1, + framebuffer : pickDepth.framebuffer + }); - /** - * Calculates the distance between the tile and the camera. - * - * @param {FrameState} frameState The frame state. - * @return {Number} The distance between the tile and the camera, in meters. - * Returns 0.0 if the camera is inside the tile. - */ - TileBoundingVolume.prototype.distanceToCamera = function(frameState) { - DeveloperError.throwInstantiationError(); - }; + var packedDepth = Cartesian4.unpack(pixels, 0, scratchPackedDepth); + Cartesian4.divideByScalar(packedDepth, 255.0, packedDepth); + var depth = Cartesian4.dot(packedDepth, packedDepthScale); - /** - * Determines which side of a plane this volume is located. - * - * @param {Plane} plane The plane to test against. - * @returns {Intersect} {@link Intersect.INSIDE} if the entire volume is on the side of the plane - * the normal is pointing, {@link Intersect.OUTSIDE} if the entire volume is - * on the opposite side, and {@link Intersect.INTERSECTING} if the volume - * intersects the plane. - */ - TileBoundingVolume.prototype.intersectPlane = function(plane) { - DeveloperError.throwInstantiationError(); - }; + if (depth > 0.0 && depth < 1.0) { + var renderedFrustum = this._frustumCommandsList[i]; + var height2D; + if (this.mode === SceneMode.SCENE2D) { + height2D = camera.position.z; + camera.position.z = height2D - renderedFrustum.near + 1.0; + frustum.far = Math.max(1.0, renderedFrustum.far - renderedFrustum.near); + frustum.near = 1.0; + uniformState.update(this.frameState); + uniformState.updateFrustum(frustum); + } else { + frustum.near = renderedFrustum.near * (i !== 0 ? OPAQUE_FRUSTUM_NEAR_OFFSET : 1.0); + frustum.far = renderedFrustum.far; + uniformState.updateFrustum(frustum); + } - /** - * Creates a debug primitive that shows the outline of the tile bounding - * volume. - * - * @param {Color} color The desired color of the primitive's mesh - * @return {Primitive} - */ - TileBoundingVolume.prototype.createDebugVolume = function(color) { - DeveloperError.throwInstantiationError(); - }; + result = SceneTransforms.drawingBufferToWgs84Coordinates(this, drawingBufferPosition, depth, result); - return TileBoundingVolume; -}); + if (this.mode === SceneMode.SCENE2D) { + camera.position.z = height2D; + uniformState.update(this.frameState); + } -define('Scene/TileCoordinatesImageryProvider',[ - '../Core/Color', - '../Core/defaultValue', - '../Core/defined', - '../Core/defineProperties', - '../Core/Event', - '../Core/GeographicTilingScheme', - '../ThirdParty/when' - ], function( - Color, - defaultValue, - defined, - defineProperties, - Event, - GeographicTilingScheme, - when) { - 'use strict'; + this._pickPositionCache[cacheKey] = Cartesian3.clone(result); + return result; + } + } + + this._pickPositionCache[cacheKey] = undefined; + return undefined; + }; + + var scratchPickPositionCartographic = new Cartographic(); /** - * An {@link ImageryProvider} that draws a box around every rendered tile in the tiling scheme, and draws - * a label inside it indicating the X, Y, Level coordinates of the tile. This is mostly useful for - * debugging terrain and imagery rendering problems. + * Returns the cartesian position reconstructed from the depth buffer and window position. + * <p> + * The position reconstructed from the depth buffer in 2D may be slightly different from those + * reconstructed in 3D and Columbus view. This is caused by the difference in the distribution + * of depth values of perspective and orthographic projection. + * </p> + * <p> + * Set {@link Scene#pickTranslucentDepth} to <code>true</code> to include the depth of + * translucent primitives; otherwise, this essentially picks through translucent primitives. + * </p> * - * @alias TileCoordinatesImageryProvider - * @constructor + * @param {Cartesian2} windowPosition Window coordinates to perform picking on. + * @param {Cartesian3} [result] The object on which to restore the result. + * @returns {Cartesian3} The cartesian position. * - * @param {Object} [options] Object with the following properties: - * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. - * @param {Color} [options.color=Color.YELLOW] The color to draw the tile box and label. - * @param {Number} [options.tileWidth=256] The width of the tile for level-of-detail selection purposes. - * @param {Number} [options.tileHeight=256] The height of the tile for level-of-detail selection purposes. + * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. */ - function TileCoordinatesImageryProvider(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); - this._color = defaultValue(options.color, Color.YELLOW); - this._errorEvent = new Event(); - this._tileWidth = defaultValue(options.tileWidth, 256); - this._tileHeight = defaultValue(options.tileHeight, 256); - this._readyPromise = when.resolve(true); - } - - defineProperties(TileCoordinatesImageryProvider.prototype, { - /** - * Gets the proxy used by this provider. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return undefined; - } - }, - - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - return this._tileWidth; - } - }, - - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight: { - get : function() { - return this._tileHeight; - } - }, + Scene.prototype.pickPosition = function(windowPosition, result) { + result = this.pickPositionWorldCoordinates(windowPosition, result); + if (defined(result) && this.mode !== SceneMode.SCENE3D) { + Cartesian3.fromElements(result.y, result.z, result.x, result); - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : function() { - return undefined; - } - }, + var projection = this.mapProjection; + var ellipsoid = projection.ellipsoid; - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - return undefined; - } - }, + var cart = projection.unproject(result, scratchPickPositionCartographic); + ellipsoid.cartographicToCartesian(cart, result); + } - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - return this._tilingScheme; - } - }, + return result; + }; - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - return this._tilingScheme.rectangle; - } - }, + /** + * Returns a list of objects, each containing a `primitive` property, for all primitives at + * a particular window coordinate position. Other properties may also be set depending on the + * type of primitive. The primitives in the list are ordered by their visual order in the + * scene (front to back). + * + * @param {Cartesian2} windowPosition Window coordinates to perform picking on. + * @param {Number} [limit] If supplied, stop drilling after collecting this many picks. + * @returns {Object[]} Array of objects, each containing 1 picked primitives. + * + * @exception {DeveloperError} windowPosition is undefined. + * + * @example + * var pickedObjects = scene.drillPick(new Cesium.Cartesian2(100.0, 200.0)); + */ + Scene.prototype.drillPick = function(windowPosition, limit) { + // PERFORMANCE_IDEA: This function calls each primitive's update for each pass. Instead + // we could update the primitive once, and then just execute their commands for each pass, + // and cull commands for picked primitives. e.g., base on the command's owner. - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - return undefined; - } - }, + if (!defined(windowPosition)) { + throw new DeveloperError('windowPosition is undefined.'); + } + + var i; + var attributes; + var result = []; + var pickedPrimitives = []; + var pickedAttributes = []; + if (!defined(limit)) { + limit = Number.MAX_VALUE; + } - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._errorEvent; + var pickedResult = this.pick(windowPosition); + while (defined(pickedResult) && defined(pickedResult.primitive)) { + result.push(pickedResult); + if (0 >= --limit) { + break; } - }, - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return true; - } - }, + var primitive = pickedResult.primitive; + var hasShowAttribute = false; - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._readyPromise; + //If the picked object has a show attribute, use it. + if (typeof primitive.getGeometryInstanceAttributes === 'function') { + if (defined(pickedResult.id)) { + attributes = primitive.getGeometryInstanceAttributes(pickedResult.id); + if (defined(attributes) && defined(attributes.show)) { + hasShowAttribute = true; + attributes.show = ShowGeometryInstanceAttribute.toValue(false, attributes.show); + pickedAttributes.push(attributes); + } + } } - }, - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return undefined; + //Otherwise, hide the entire primitive + if (!hasShowAttribute) { + primitive.show = false; + pickedPrimitives.push(primitive); } - }, - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage - * and texture upload time. - * @memberof TileCoordinatesImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - hasAlphaChannel : { - get : function() { - return true; - } + pickedResult = this.pick(windowPosition); } - }); + + // unhide everything we hid while drill picking + for (i = 0; i < pickedPrimitives.length; ++i) { + pickedPrimitives[i].show = true; + } + + for (i = 0; i < pickedAttributes.length; ++i) { + attributes = pickedAttributes[i]; + attributes.show = ShowGeometryInstanceAttribute.toValue(true, attributes.show); + } + + return result; + }; /** - * Gets the credits to be displayed when a given tile is displayed. + * Transforms a position in cartesian coordinates to canvas coordinates. This is commonly used to place an + * HTML element at the same screen position as an object in the scene. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * @param {Cartesian3} position The position in cartesian coordinates. + * @param {Cartesian2} [result] An optional object to return the input position transformed to canvas coordinates. + * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid. * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + * @example + * // Output the canvas position of longitude/latitude (0, 0) every time the mouse moves. + * var scene = widget.scene; + * var ellipsoid = scene.globe.ellipsoid; + * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0); + * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + * handler.setInputAction(function(movement) { + * console.log(scene.cartesianToCanvasCoordinates(position)); + * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); */ - TileCoordinatesImageryProvider.prototype.getTileCredits = function(x, y, level) { - return undefined; + Scene.prototype.cartesianToCanvasCoordinates = function(position, result) { + return SceneTransforms.wgs84ToWindowCoordinates(this, position, result); }; /** - * Requests the image for a given tile. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. + * Instantly completes an active transition. */ - TileCoordinatesImageryProvider.prototype.requestImage = function(x, y, level, request) { - var canvas = document.createElement('canvas'); - canvas.width = 256; - canvas.height = 256; - var context = canvas.getContext('2d'); - - var cssColor = this._color.toCssColorString(); - - context.strokeStyle = cssColor; - context.lineWidth = 2; - context.strokeRect(1, 1, 255, 255); - - var label = 'L' + level + 'X' + x + 'Y' + y; - context.font = 'bold 25px Arial'; - context.textAlign = 'center'; - context.fillStyle = 'black'; - context.fillText(label, 127, 127); - context.fillStyle = cssColor; - context.fillText(label, 124, 124); - - return canvas; + Scene.prototype.completeMorph = function(){ + this._transitioner.completeMorph(); }; /** - * Picking features is not currently supported by this imagery provider, so this function simply returns - * undefined. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. - * It may also be undefined if picking is not supported. + * Asynchronously transitions the scene to 2D. + * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. */ - TileCoordinatesImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return undefined; + Scene.prototype.morphTo2D = function(duration) { + var ellipsoid; + var globe = this.globe; + if (defined(globe)) { + ellipsoid = globe.ellipsoid; + } else { + ellipsoid = this.mapProjection.ellipsoid; + } + duration = defaultValue(duration, 2.0); + this._transitioner.morphTo2D(duration, ellipsoid); }; - return TileCoordinatesImageryProvider; -}); - -define('Scene/TileDiscardPolicy',[ - '../Core/DeveloperError' - ], function( - DeveloperError) { - 'use strict'; + /** + * Asynchronously transitions the scene to Columbus View. + * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. + */ + Scene.prototype.morphToColumbusView = function(duration) { + var ellipsoid; + var globe = this.globe; + if (defined(globe)) { + ellipsoid = globe.ellipsoid; + } else { + ellipsoid = this.mapProjection.ellipsoid; + } + duration = defaultValue(duration, 2.0); + this._transitioner.morphToColumbusView(duration, ellipsoid); + }; /** - * A policy for discarding tile images according to some criteria. This type describes an - * interface and is not intended to be instantiated directly. - * - * @alias TileDiscardPolicy - * @constructor - * - * @see DiscardMissingTileImagePolicy - * @see NeverTileDiscardPolicy + * Asynchronously transitions the scene to 3D. + * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. */ - function TileDiscardPolicy(options) { - DeveloperError.throwInstantiationError(); - } + Scene.prototype.morphTo3D = function(duration) { + var ellipsoid; + var globe = this.globe; + if (defined(globe)) { + ellipsoid = globe.ellipsoid; + } else { + ellipsoid = this.mapProjection.ellipsoid; + } + duration = defaultValue(duration, 2.0); + this._transitioner.morphTo3D(duration, ellipsoid); + }; /** - * Determines if the discard policy is ready to process images. - * @function + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see Scene#destroy */ - TileDiscardPolicy.prototype.isReady = DeveloperError.throwInstantiationError; + Scene.prototype.isDestroyed = function() { + return false; + }; /** - * Given a tile image, decide whether to discard that image. - * @function + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. * - * @param {Image} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * scene = scene && scene.destroy(); + * + * @see Scene#isDestroyed */ - TileDiscardPolicy.prototype.shouldDiscardImage = DeveloperError.throwInstantiationError; + Scene.prototype.destroy = function() { + this._tweens.removeAll(); + this._computeEngine = this._computeEngine && this._computeEngine.destroy(); + this._screenSpaceCameraController = this._screenSpaceCameraController && this._screenSpaceCameraController.destroy(); + this._deviceOrientationCameraController = this._deviceOrientationCameraController && !this._deviceOrientationCameraController.isDestroyed() && this._deviceOrientationCameraController.destroy(); + this._pickFramebuffer = this._pickFramebuffer && this._pickFramebuffer.destroy(); + this._pickDepthFramebuffer = this._pickDepthFramebuffer && this._pickDepthFramebuffer.destroy(); + this._primitives = this._primitives && this._primitives.destroy(); + this._groundPrimitives = this._groundPrimitives && this._groundPrimitives.destroy(); + this._globe = this._globe && this._globe.destroy(); + this.skyBox = this.skyBox && this.skyBox.destroy(); + this.skyAtmosphere = this.skyAtmosphere && this.skyAtmosphere.destroy(); + this._debugSphere = this._debugSphere && this._debugSphere.destroy(); + this.sun = this.sun && this.sun.destroy(); + this._sunPostProcess = this._sunPostProcess && this._sunPostProcess.destroy(); + this._depthPlane = this._depthPlane && this._depthPlane.destroy(); + this._transitioner.destroy(); + this._debugFrustumPlanes = this._debugFrustumPlanes && this._debugFrustumPlanes.destroy(); + this._brdfLutGenerator = this._brdfLutGenerator && this._brdfLutGenerator.destroy(); - return TileDiscardPolicy; -}); + if (defined(this._globeDepth)) { + this._globeDepth.destroy(); + } + if (this._removeCreditContainer) { + this._canvas.parentNode.removeChild(this._creditContainer); + } -define('Scene/TileState',[ - '../Core/freezeObject' - ], function( - freezeObject) { - 'use strict'; + if (defined(this._oit)) { + this._oit.destroy(); + } + this._fxaa.destroy(); - /** - * @private - */ - var TileState = { - START : 0, - LOADING : 1, - READY : 2, - UPSAMPLED_ONLY : 3 + this._context = this._context && this._context.destroy(); + this._frameState.creditDisplay.destroy(); + if (defined(this._performanceDisplay)){ + this._performanceDisplay = this._performanceDisplay && this._performanceDisplay.destroy(); + this._performanceContainer.parentNode.removeChild(this._performanceContainer); + } + + this._removeRequestListenerCallback(); + this._removeTaskProcessorListenerCallback(); + for (var i = 0; i < this._removeGlobeCallbacks.length; ++i) { + this._removeGlobeCallbacks[i](); + } + this._removeGlobeCallbacks.length = 0; + + return destroyObject(this); }; - return freezeObject(TileState); + return Scene; }); -define('Scene/TimeDynamicImagery',[ - '../Core/Check', +/** + * @license + * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the project nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Modifications made by Analytical Graphics, Inc. + */ +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/SkyAtmosphereFS',[],function() { + 'use strict'; + return "#ifdef COLOR_CORRECT\n\ +uniform vec3 u_hsbShift;\n\ +#endif\n\ +uniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\n\ +const float g = -0.95;\n\ +const float g2 = g * g;\n\ +varying vec3 v_rayleighColor;\n\ +varying vec3 v_mieColor;\n\ +varying vec3 v_toCamera;\n\ +varying vec3 v_positionEC;\n\ +void main (void)\n\ +{\n\ +float cosAngle = dot(czm_sunDirectionWC, normalize(v_toCamera)) / length(v_toCamera);\n\ +float rayleighPhase = 0.75 * (1.0 + cosAngle * cosAngle);\n\ +float miePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cosAngle * cosAngle) / pow(1.0 + g2 - 2.0 * g * cosAngle, 1.5);\n\ +const float exposure = 2.0;\n\ +vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor;\n\ +rgb = vec3(1.0) - exp(-exposure * rgb);\n\ +float l = czm_luminance(rgb);\n\ +#ifdef COLOR_CORRECT\n\ +vec3 hsb = czm_RGBToHSB(rgb);\n\ +hsb.x += u_hsbShift.x;\n\ +hsb.y = clamp(hsb.y + u_hsbShift.y, 0.0, 1.0);\n\ +hsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0;\n\ +rgb = czm_HSBToRGB(hsb);\n\ +l = min(l, czm_luminance(rgb));\n\ +#endif\n\ +float atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0);\n\ +float nightAlpha = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), 0.0, 1.0) : 1.0;\n\ +atmosphereAlpha *= pow(nightAlpha, 0.5);\n\ +gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime));\n\ +}\n\ +"; +}); +/** + * @license + * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the project nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Modifications made by Analytical Graphics, Inc. + */ +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/SkyAtmosphereVS',[],function() { + 'use strict'; + return "attribute vec4 position;\n\ +uniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor;\n\ +const float Kr = 0.0025;\n\ +const float Kr4PI = Kr * 4.0 * czm_pi;\n\ +const float Km = 0.0015;\n\ +const float Km4PI = Km * 4.0 * czm_pi;\n\ +const float ESun = 15.0;\n\ +const float KmESun = Km * ESun;\n\ +const float KrESun = Kr * ESun;\n\ +const vec3 InvWavelength = vec3(\n\ +5.60204474633241,\n\ +9.473284437923038,\n\ +19.643802610477206);\n\ +const float rayleighScaleDepth = 0.25;\n\ +const int nSamples = 2;\n\ +const float fSamples = 2.0;\n\ +varying vec3 v_rayleighColor;\n\ +varying vec3 v_mieColor;\n\ +varying vec3 v_toCamera;\n\ +float scale(float cosAngle)\n\ +{\n\ +float x = 1.0 - cosAngle;\n\ +return rayleighScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\n\ +}\n\ +void main(void)\n\ +{\n\ +float cameraHeight = u_cameraAndRadiiAndDynamicAtmosphereColor.x;\n\ +float outerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.y;\n\ +float innerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.z;\n\ +vec3 positionV3 = position.xyz;\n\ +vec3 ray = positionV3 - czm_viewerPositionWC;\n\ +float far = length(ray);\n\ +ray /= far;\n\ +float atmosphereScale = 1.0 / (outerRadius - innerRadius);\n\ +#ifdef SKY_FROM_SPACE\n\ +float B = 2.0 * dot(czm_viewerPositionWC, ray);\n\ +float C = cameraHeight * cameraHeight - outerRadius * outerRadius;\n\ +float det = max(0.0, B*B - 4.0 * C);\n\ +float near = 0.5 * (-B - sqrt(det));\n\ +vec3 start = czm_viewerPositionWC + ray * near;\n\ +far -= near;\n\ +float startAngle = dot(ray, start) / outerRadius;\n\ +float startDepth = exp(-1.0 / rayleighScaleDepth );\n\ +float startOffset = startDepth*scale(startAngle);\n\ +#else // SKY_FROM_ATMOSPHERE\n\ +vec3 start = czm_viewerPositionWC;\n\ +float height = length(start);\n\ +float depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - cameraHeight));\n\ +float startAngle = dot(ray, start) / height;\n\ +float startOffset = depth*scale(startAngle);\n\ +#endif\n\ +float sampleLength = far / fSamples;\n\ +float scaledLength = sampleLength * atmosphereScale;\n\ +vec3 sampleRay = ray * sampleLength;\n\ +vec3 samplePoint = start + sampleRay * 0.5;\n\ +vec3 frontColor = vec3(0.0, 0.0, 0.0);\n\ +vec3 lightDir = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? czm_sunPositionWC - czm_viewerPositionWC : czm_viewerPositionWC;\n\ +lightDir = normalize(lightDir);\n\ +for(int i=0; i<nSamples; i++)\n\ +{\n\ +float height = length(samplePoint);\n\ +float depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - height));\n\ +float fLightAngle = dot(lightDir, samplePoint) / height;\n\ +float fCameraAngle = dot(ray, samplePoint) / height;\n\ +float fScatter = (startOffset + depth*(scale(fLightAngle) - scale(fCameraAngle)));\n\ +vec3 attenuate = exp(-fScatter * (InvWavelength * Kr4PI + Km4PI));\n\ +frontColor += attenuate * (depth * scaledLength);\n\ +samplePoint += sampleRay;\n\ +}\n\ +v_mieColor = frontColor * KmESun;\n\ +v_rayleighColor = frontColor * (InvWavelength * KrESun);\n\ +v_toCamera = czm_viewerPositionWC - positionV3;\n\ +gl_Position = czm_modelViewProjection * position;\n\ +}\n\ +"; +}); +define('Scene/SkyAtmosphere',[ + '../Core/Cartesian3', + '../Core/Cartesian4', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/JulianDate', - '../Core/Request', - '../Core/RequestType' + '../Core/destroyObject', + '../Core/Ellipsoid', + '../Core/EllipsoidGeometry', + '../Core/GeometryPipeline', + '../Core/Math', + '../Core/VertexFormat', + '../Renderer/BufferUsage', + '../Renderer/DrawCommand', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Renderer/VertexArray', + '../Shaders/SkyAtmosphereFS', + '../Shaders/SkyAtmosphereVS', + './BlendingState', + './CullFace', + './SceneMode' ], function( - Check, + Cartesian3, + Cartesian4, defaultValue, defined, defineProperties, - DeveloperError, - JulianDate, - Request, - RequestType) { + destroyObject, + Ellipsoid, + EllipsoidGeometry, + GeometryPipeline, + CesiumMath, + VertexFormat, + BufferUsage, + DrawCommand, + RenderState, + ShaderProgram, + ShaderSource, + VertexArray, + SkyAtmosphereFS, + SkyAtmosphereVS, + BlendingState, + CullFace, + SceneMode) { 'use strict'; /** - * Provides functionality for ImageryProviders that have time dynamic imagery + * An atmosphere drawn around the limb of the provided ellipsoid. Based on + * {@link http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering} + * in GPU Gems 2. + * <p> + * This is only supported in 3D. atmosphere is faded out when morphing to 2D or Columbus view. + * </p> * - * @alias TimeDynamicImagery + * @alias SkyAtmosphere * @constructor * - * @param {Object} options Object with the following properties: - * @param {Clock} options.clock A Clock instance that is used when determining the value for the time dimension. Required when options.times is specified. - * @param {TimeIntervalCollection} options.times TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values. - * @param {Function} options.requestImageFunction A function that will request imagery tiles. - * @param {Function} options.reloadFunction A function that will be called when all imagery tiles need to be reloaded. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around. + * + * @example + * scene.skyAtmosphere = new Cesium.SkyAtmosphere(); + * + * @see Scene.skyAtmosphere */ - function TimeDynamicImagery(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function SkyAtmosphere(ellipsoid) { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - Check.typeOf.object('options.clock', options.clock); - Check.typeOf.object('options.times', options.times); - Check.typeOf.func('options.requestImageFunction', options.requestImageFunction); - Check.typeOf.func('options.reloadFunction', options.reloadFunction); - - this._tileCache = {}; - this._tilesRequestedForInterval = []; + /** + * Determines if the atmosphere is shown. + * + * @type {Boolean} + * @default true + */ + this.show = true; - var clock = this._clock = options.clock; - this._times = options.times; - this._requestImageFunction = options.requestImageFunction; - this._reloadFunction = options.reloadFunction; - this._currentIntervalIndex = -1; + this._ellipsoid = ellipsoid; + this._command = new DrawCommand({ + owner : this + }); + this._spSkyFromSpace = undefined; + this._spSkyFromAtmosphere = undefined; - clock.onTick.addEventListener(this._clockOnTick, this); - this._clockOnTick(clock); - } + this._spSkyFromSpaceColorCorrect = undefined; + this._spSkyFromAtmosphereColorCorrect = undefined; - defineProperties(TimeDynamicImagery.prototype, { /** - * Gets or sets a clock that is used to get keep the time used for time dynamic parameters. - * @memberof TimeDynamicImagery.prototype - * @type {Clock} + * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift). + * A hue shift of 1.0 indicates a complete rotation of the hues available. + * @type {Number} + * @default 0.0 */ - clock : { - get : function() { - return this._clock; - }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._clock !== value) { - this._clock = value; - this._clockOnTick(value); - this._reloadFunction(); - } - } - }, + this.hueShift = 0.0; + /** - * Gets or sets a time interval collection. - * @memberof TimeDynamicImagery.prototype - * @type {TimeIntervalCollection} + * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift). + * A saturation shift of -1.0 is monochrome. + * @type {Number} + * @default 0.0 */ - times : { - get : function() { - return this._times; + this.saturationShift = 0.0; + + /** + * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift). + * A brightness shift of -1.0 is complete darkness, which will let space show through. + * @type {Number} + * @default 0.0 + */ + this.brightnessShift = 0.0; + + this._hueSaturationBrightness = new Cartesian3(); + + // camera height, outer radius, inner radius, dynamic atmosphere color flag + var cameraAndRadiiAndDynamicAtmosphereColor = new Cartesian4(); + + // Toggles whether the sun position is used. 0 treats the sun as always directly overhead. + cameraAndRadiiAndDynamicAtmosphereColor.w = 0; + cameraAndRadiiAndDynamicAtmosphereColor.y = Cartesian3.maximumComponent(Cartesian3.multiplyByScalar(ellipsoid.radii, 1.025, new Cartesian3())); + cameraAndRadiiAndDynamicAtmosphereColor.z = ellipsoid.maximumRadius; + + this._cameraAndRadiiAndDynamicAtmosphereColor = cameraAndRadiiAndDynamicAtmosphereColor; + + var that = this; + + this._command.uniformMap = { + u_cameraAndRadiiAndDynamicAtmosphereColor : function() { + return that._cameraAndRadiiAndDynamicAtmosphereColor; }, - set : function(value) { - if (!defined(value)) { - throw new DeveloperError('value is required.'); - } - - if (this._times !== value) { - this._times = value; - this._clockOnTick(this._clock); - this._reloadFunction(); - } + u_hsbShift : function() { + that._hueSaturationBrightness.x = that.hueShift; + that._hueSaturationBrightness.y = that.saturationShift; + that._hueSaturationBrightness.z = that.brightnessShift; + return that._hueSaturationBrightness; } - }, + }; + } + + defineProperties(SkyAtmosphere.prototype, { /** - * Gets the current interval. - * @memberof TimeDynamicImagery.prototype - * @type {TimeInterval} + * Gets the ellipsoid the atmosphere is drawn around. + * @memberof SkyAtmosphere.prototype + * + * @type {Ellipsoid} + * @readonly */ - currentInterval : { + ellipsoid : { get : function() { - return this._times.get(this._currentIntervalIndex); + return this._ellipsoid; } } }); /** - * Gets the tile from the cache if its available. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * - * @returns {Promise.<Image>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if the tile is not in the cache. + * @private */ - TimeDynamicImagery.prototype.getFromCache = function(x, y, level, request) { - var key = getKey(x, y, level); - var result; - var cache = this._tileCache[this._currentIntervalIndex]; - if (defined(cache) && defined(cache[key])) { - var item = cache[key]; - result = item.promise - .otherwise(function(e) { - // Set the correct state in case it was cancelled - request.state = item.request.state; - throw e; - }); - delete cache[key]; - } - - return result; + SkyAtmosphere.prototype.setDynamicAtmosphereColor = function(enableLighting) { + this._cameraAndRadiiAndDynamicAtmosphereColor.w = enableLighting ? 1 : 0; }; /** - * Checks if the next interval is approaching and will start preload the tile if necessary. Otherwise it will - * just add the tile to a list to preload when we approach the next interval. - * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. + * @private */ - TimeDynamicImagery.prototype.checkApproachingInterval = function(x, y, level, request) { - var key = getKey(x, y, level); - var tilesRequestedForInterval = this._tilesRequestedForInterval; - - // If we are approaching an interval, preload this tile in the next interval - var approachingInterval = getApproachingInterval(this); - var tile = { - key : key, - // Determines priority based on camera distance to the tile. - // Since the imagery regardless of time will be attached to the same tile we can just steal it. - priorityFunction : request.priorityFunction - }; - if (!defined(approachingInterval) || !addToCache(this, tile, approachingInterval)) { - // Add to recent request list if we aren't approaching and interval or the request was throttled - tilesRequestedForInterval.push(tile); + SkyAtmosphere.prototype.update = function(frameState) { + if (!this.show) { + return undefined; } - // Don't let the tile list get out of hand - if (tilesRequestedForInterval.length >= 512) { - tilesRequestedForInterval.splice(0, 256); + var mode = frameState.mode; + if ((mode !== SceneMode.SCENE3D) && + (mode !== SceneMode.MORPHING)) { + return undefined; } - }; - - TimeDynamicImagery.prototype._clockOnTick = function(clock) { - var time = clock.currentTime; - var times = this._times; - var index = times.indexOf(time); - var currentIntervalIndex = this._currentIntervalIndex; - - if (index !== currentIntervalIndex) { - // Cancel all outstanding requests and clear out caches not from current time interval - var currentCache = this._tileCache[currentIntervalIndex]; - for (var t in currentCache) { - if (currentCache.hasOwnProperty(t)) { - currentCache[t].request.cancel(); - } - } - delete this._tileCache[currentIntervalIndex]; - this._tilesRequestedForInterval = []; - - this._currentIntervalIndex = index; - this._reloadFunction(); - return; + // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc. + if (!frameState.passes.render) { + return undefined; } - var approachingInterval = getApproachingInterval(this); - if (defined(approachingInterval)) { - // Start loading recent tiles from end of this._tilesRequestedForInterval - // We keep preloading until we hit a throttling limit. - var tilesRequested = this._tilesRequestedForInterval; - var success = true; - while (success) { - if (tilesRequested.length === 0) { - break; - } + var command = this._command; - var tile = tilesRequested.pop(); - success = addToCache(this, tile, approachingInterval); - if (!success) { - tilesRequested.push(tile); - } - } - } - }; + if (!defined(command.vertexArray)) { + var context = frameState.context; - function getKey(x, y, level) { - return x + '-' + y + '-' + level; - } + var geometry = EllipsoidGeometry.createGeometry(new EllipsoidGeometry({ + radii : Cartesian3.multiplyByScalar(this._ellipsoid.radii, 1.025, new Cartesian3()), + slicePartitions : 256, + stackPartitions : 256, + vertexFormat : VertexFormat.POSITION_ONLY + })); + command.vertexArray = VertexArray.fromGeometry({ + context : context, + geometry : geometry, + attributeLocations : GeometryPipeline.createAttributeLocations(geometry), + bufferUsage : BufferUsage.STATIC_DRAW + }); + command.renderState = RenderState.fromCache({ + cull : { + enabled : true, + face : CullFace.FRONT + }, + blending : BlendingState.ALPHA_BLEND + }); - function getKeyElements(key) { - var s = key.split('-'); - if (s.length !== 3) { - return undefined; - } + var vs = new ShaderSource({ + defines : ['SKY_FROM_SPACE'], + sources : [SkyAtmosphereVS] + }); - return { - x : Number(s[0]), - y : Number(s[1]), - level : Number(s[2]) - }; - } + this._spSkyFromSpace = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : SkyAtmosphereFS + }); - function getApproachingInterval(that) { - var times = that._times; - if (!defined(times)) { - return undefined; + vs = new ShaderSource({ + defines : ['SKY_FROM_ATMOSPHERE'], + sources : [SkyAtmosphereVS] + }); + this._spSkyFromAtmosphere = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : SkyAtmosphereFS + }); } - var clock = that._clock; - var time = clock.currentTime; - var isAnimating = clock.canAnimate && clock.shouldAnimate; - var multiplier = clock.multiplier; - if (!isAnimating && multiplier !== 0) { - return undefined; - } + // Compile the color correcting versions of the shader on demand + var useColorCorrect = colorCorrect(this); + if (useColorCorrect && (!defined(this._spSkyFromSpaceColorCorrect) || !defined(this._spSkyFromAtmosphereColorCorrect))) { + var contextColorCorrect = frameState.context; - var seconds; - var index = times.indexOf(time); - if (index === -1) { - return undefined; - } + var vsColorCorrect = new ShaderSource({ + defines : ['SKY_FROM_SPACE'], + sources : [SkyAtmosphereVS] + }); + var fsColorCorrect = new ShaderSource({ + defines : ['COLOR_CORRECT'], + sources : [SkyAtmosphereFS] + }); - var interval = times.get(index); - if (multiplier > 0) { // animating forward - seconds = JulianDate.secondsDifference(interval.stop, time); - ++index; - } else { //backwards - seconds = JulianDate.secondsDifference(interval.start, time); // Will be negative - --index; + this._spSkyFromSpaceColorCorrect = ShaderProgram.fromCache({ + context : contextColorCorrect, + vertexShaderSource : vsColorCorrect, + fragmentShaderSource : fsColorCorrect + }); + vsColorCorrect = new ShaderSource({ + defines : ['SKY_FROM_ATMOSPHERE'], + sources : [SkyAtmosphereVS] + }); + this._spSkyFromAtmosphereColorCorrect = ShaderProgram.fromCache({ + context : contextColorCorrect, + vertexShaderSource : vsColorCorrect, + fragmentShaderSource : fsColorCorrect + }); } - seconds /= multiplier; // Will always be positive - - // Less than 5 wall time seconds - return (index >= 0 && seconds <= 5.0) ? times.get(index) : undefined; - } - function addToCache(that, tile, interval) { - var index = that._times.indexOf(interval.start); - var tileCache = that._tileCache; - var intervalTileCache = tileCache[index]; - if (!defined(intervalTileCache)) { - intervalTileCache = tileCache[index] = {}; - } + var cameraPosition = frameState.camera.positionWC; - var key = tile.key; - if (defined(intervalTileCache[key])) { - return true; // Already in the cache - } + var cameraHeight = Cartesian3.magnitude(cameraPosition); + this._cameraAndRadiiAndDynamicAtmosphereColor.x = cameraHeight; - var keyElements = getKeyElements(key); - var request = new Request({ - throttle : true, - throttleByServer : true, - type : RequestType.IMAGERY, - priorityFunction : tile.priorityFunction - }); - var promise = that._requestImageFunction(keyElements.x, keyElements.y, keyElements.level, request, interval); - if (!defined(promise)) { - return false; + if (cameraHeight > this._cameraAndRadiiAndDynamicAtmosphereColor.y) { + // Camera in space + command.shaderProgram = useColorCorrect ? this._spSkyFromSpaceColorCorrect : this._spSkyFromSpace; + } else { + // Camera in atmosphere + command.shaderProgram = useColorCorrect ? this._spSkyFromAtmosphereColorCorrect : this._spSkyFromAtmosphere; } - intervalTileCache[key] = { - promise : promise, - request : request - }; + return command; + }; - return true; + function colorCorrect(skyAtmosphere) { + return !(CesiumMath.equalsEpsilon(skyAtmosphere.hueShift, 0.0, CesiumMath.EPSILON7) && + CesiumMath.equalsEpsilon(skyAtmosphere.saturationShift, 0.0, CesiumMath.EPSILON7) && + CesiumMath.equalsEpsilon(skyAtmosphere.brightnessShift, 0.0, CesiumMath.EPSILON7)); } - return TimeDynamicImagery; + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * + * @see SkyAtmosphere#destroy + */ + SkyAtmosphere.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy(); + * + * @see SkyAtmosphere#isDestroyed + */ + SkyAtmosphere.prototype.destroy = function() { + var command = this._command; + command.vertexArray = command.vertexArray && command.vertexArray.destroy(); + this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy(); + this._spSkyFromAtmosphere = this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy(); + this._spSkyFromSpaceColorCorrect = this._spSkyFromSpaceColorCorrect && this._spSkyFromSpaceColorCorrect.destroy(); + this._spSkyFromAtmosphereColorCorrect = this._spSkyFromAtmosphereColorCorrect && this._spSkyFromAtmosphereColorCorrect.destroy(); + return destroyObject(this); + }; + + return SkyAtmosphere; }); //This file is automatically rebuilt by the Cesium build process. -define('Shaders/ViewportQuadFS',[],function() { +define('Shaders/SkyBoxFS',[],function() { 'use strict'; - return "varying vec2 v_textureCoordinates;\n\ + return "uniform samplerCube u_cubeMap;\n\ +varying vec3 v_texCoord;\n\ void main()\n\ {\n\ -czm_materialInput materialInput;\n\ -materialInput.s = v_textureCoordinates.s;\n\ -materialInput.st = v_textureCoordinates;\n\ -materialInput.str = vec3(v_textureCoordinates, 0.0);\n\ -materialInput.normalEC = vec3(0.0, 0.0, -1.0);\n\ -czm_material material = czm_getMaterial(materialInput);\n\ -gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ +vec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb;\n\ +gl_FragColor = vec4(rgb, czm_morphTime);\n\ }\n\ "; }); -define('Scene/ViewportQuad',[ - '../Core/BoundingRectangle', - '../Core/Color', +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/SkyBoxVS',[],function() { + 'use strict'; + return "attribute vec3 position;\n\ +varying vec3 v_texCoord;\n\ +void main()\n\ +{\n\ +vec3 p = czm_viewRotation * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\n\ +gl_Position = czm_projection * vec4(p, 1.0);\n\ +v_texCoord = position.xyz;\n\ +}\n\ +"; +}); +define('Scene/SkyBox',[ + '../Core/BoxGeometry', + '../Core/Cartesian3', + '../Core/defaultValue', '../Core/defined', '../Core/destroyObject', '../Core/DeveloperError', - '../Renderer/Pass', + '../Core/GeometryPipeline', + '../Core/Matrix4', + '../Core/VertexFormat', + '../Renderer/BufferUsage', + '../Renderer/CubeMap', + '../Renderer/DrawCommand', + '../Renderer/loadCubeMap', '../Renderer/RenderState', - '../Renderer/ShaderSource', - '../Shaders/ViewportQuadFS', + '../Renderer/ShaderProgram', + '../Renderer/VertexArray', + '../Shaders/SkyBoxFS', + '../Shaders/SkyBoxVS', './BlendingState', - './Material' + './SceneMode' ], function( - BoundingRectangle, - Color, + BoxGeometry, + Cartesian3, + defaultValue, defined, destroyObject, DeveloperError, - Pass, + GeometryPipeline, + Matrix4, + VertexFormat, + BufferUsage, + CubeMap, + DrawCommand, + loadCubeMap, RenderState, - ShaderSource, - ViewportQuadFS, + ShaderProgram, + VertexArray, + SkyBoxFS, + SkyBoxVS, BlendingState, - Material) { + SceneMode) { 'use strict'; /** - * A viewport aligned quad. + * A sky box around the scene to draw stars. The sky box is defined using the True Equator Mean Equinox (TEME) axes. + * <p> + * This is only supported in 3D. The sky box is faded out when morphing to 2D or Columbus view. The size of + * the sky box must not exceed {@link Scene#maximumCubeMapSize}. + * </p> * - * @alias ViewportQuad + * @alias SkyBox * @constructor * - * @param {BoundingRectangle} [rectangle] The {@link BoundingRectangle} defining the quad's position within the viewport. - * @param {Material} [material] The {@link Material} defining the surface appearance of the viewport quad. + * @param {Object} options Object with the following properties: + * @param {Object} [options.sources] The source URL or <code>Image</code> object for each of the six cube map faces. See the example below. + * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * * * @example - * var viewportQuad = new Cesium.ViewportQuad(new Cesium.BoundingRectangle(0, 0, 80, 40)); - * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 0.0, 0.0, 1.0); + * scene.skyBox = new Cesium.SkyBox({ + * sources : { + * positiveX : 'skybox_px.png', + * negativeX : 'skybox_nx.png', + * positiveY : 'skybox_py.png', + * negativeY : 'skybox_ny.png', + * positiveZ : 'skybox_pz.png', + * negativeZ : 'skybox_nz.png' + * } + * }); + * + * @see Scene#skyBox + * @see Transforms.computeTemeToPseudoFixedMatrix */ - function ViewportQuad(rectangle, material) { - /** - * Determines if the viewport quad primitive will be shown. - * - * @type {Boolean} - * @default true - */ - this.show = true; - - if (!defined(rectangle)) { - rectangle = new BoundingRectangle(); - } - + function SkyBox(options) { /** - * The BoundingRectangle defining the quad's position within the viewport. - * - * @type {BoundingRectangle} + * The sources used to create the cube map faces: an object + * with <code>positiveX</code>, <code>negativeX</code>, <code>positiveY</code>, + * <code>negativeY</code>, <code>positiveZ</code>, and <code>negativeZ</code> properties. + * These can be either URLs or <code>Image</code> objects. * - * @example - * viewportQuad.rectangle = new Cesium.BoundingRectangle(0, 0, 80, 40); + * @type Object + * @default undefined */ - this.rectangle = BoundingRectangle.clone(rectangle); - - if (!defined(material)) { - material = Material.fromType(Material.ColorType, { - color : new Color(1.0, 1.0, 1.0, 1.0) - }); - } + this.sources = options.sources; + this._sources = undefined; /** - * The surface appearance of the viewport quad. This can be one of several built-in {@link Material} objects or a custom material, scripted with - * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}. - * <p> - * The default material is <code>Material.ColorType</code>. - * </p> - * - * @type Material - * - * @example - * // 1. Change the color of the default material to yellow - * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); - * - * // 2. Change material to horizontal stripes - * viewportQuad.material = Cesium.Material.fromType(Cesium.Material.StripeType); + * Determines if the sky box will be shown. * - * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + * @type {Boolean} + * @default true */ - this.material = material; - this._material = undefined; + this.show = defaultValue(options.show, true); - this._overlayCommand = undefined; - this._rs = undefined; + this._command = new DrawCommand({ + modelMatrix : Matrix4.clone(Matrix4.IDENTITY), + owner : this + }); + this._cubeMap = undefined; } /** @@ -215859,57 +226787,103 @@ define('Scene/ViewportQuad',[ * list the exceptions that may be propagated when the scene is rendered: * </p> * - * @exception {DeveloperError} this.material must be defined. - * @exception {DeveloperError} this.rectangle must be defined. + * @exception {DeveloperError} this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. + * @exception {DeveloperError} this.sources properties must all be the same type. */ - ViewportQuad.prototype.update = function(frameState) { + SkyBox.prototype.update = function(frameState) { + var that = this; + if (!this.show) { - return; + return undefined; } - if (!defined(this.material)) { - throw new DeveloperError('this.material must be defined.'); - } - if (!defined(this.rectangle)) { - throw new DeveloperError('this.rectangle must be defined.'); + if ((frameState.mode !== SceneMode.SCENE3D) && + (frameState.mode !== SceneMode.MORPHING)) { + return undefined; } - - var rs = this._rs; - if ((!defined(rs)) || !BoundingRectangle.equals(rs.viewport, this.rectangle)) { - this._rs = RenderState.fromCache({ - blending : BlendingState.ALPHA_BLEND, - viewport : this.rectangle - }); + + // The sky box is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc. + if (!frameState.passes.render) { + return undefined; } - var pass = frameState.passes; - if (pass.render) { - var context = frameState.context; + var context = frameState.context; - if (this._material !== this.material || !defined(this._overlayCommand)) { - // Recompile shader when material changes - this._material = this.material; + if (this._sources !== this.sources) { + this._sources = this.sources; + var sources = this.sources; - if (defined(this._overlayCommand)) { - this._overlayCommand.shaderProgram.destroy(); - } + if ((!defined(sources.positiveX)) || + (!defined(sources.negativeX)) || + (!defined(sources.positiveY)) || + (!defined(sources.negativeY)) || + (!defined(sources.positiveZ)) || + (!defined(sources.negativeZ))) { + throw new DeveloperError('this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.'); + } - var fs = new ShaderSource({ - sources : [this._material.shaderSource, ViewportQuadFS] + if ((typeof sources.positiveX !== typeof sources.negativeX) || + (typeof sources.positiveX !== typeof sources.positiveY) || + (typeof sources.positiveX !== typeof sources.negativeY) || + (typeof sources.positiveX !== typeof sources.positiveZ) || + (typeof sources.positiveX !== typeof sources.negativeZ)) { + throw new DeveloperError('this.sources properties must all be the same type.'); + } + + if (typeof sources.positiveX === 'string') { + // Given urls for cube-map images. Load them. + loadCubeMap(context, this._sources).then(function(cubeMap) { + that._cubeMap = that._cubeMap && that._cubeMap.destroy(); + that._cubeMap = cubeMap; }); - this._overlayCommand = context.createViewportQuadCommand(fs, { - renderState : this._rs, - uniformMap : this._material._uniforms, - owner : this + } else { + this._cubeMap = this._cubeMap && this._cubeMap.destroy(); + this._cubeMap = new CubeMap({ + context : context, + source : sources }); - this._overlayCommand.pass = Pass.OVERLAY; } + } - this._material.update(context); + var command = this._command; - this._overlayCommand.uniformMap = this._material._uniforms; - frameState.commandList.push(this._overlayCommand); + if (!defined(command.vertexArray)) { + command.uniformMap = { + u_cubeMap: function() { + return that._cubeMap; + } + }; + + var geometry = BoxGeometry.createGeometry(BoxGeometry.fromDimensions({ + dimensions : new Cartesian3(2.0, 2.0, 2.0), + vertexFormat : VertexFormat.POSITION_ONLY + })); + var attributeLocations = GeometryPipeline.createAttributeLocations(geometry); + + command.vertexArray = VertexArray.fromGeometry({ + context : context, + geometry : geometry, + attributeLocations : attributeLocations, + bufferUsage : BufferUsage.STATIC_DRAW + }); + + command.shaderProgram = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : SkyBoxVS, + fragmentShaderSource : SkyBoxFS, + attributeLocations : attributeLocations + }); + + command.renderState = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND + }); } + + if (!defined(this._cubeMap)) { + return undefined; + } + + return command; }; /** @@ -215918,11 +226892,11 @@ define('Scene/ViewportQuad',[ * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * - * @see ViewportQuad#destroy + * @see SkyBox#destroy */ - ViewportQuad.prototype.isDestroyed = function() { + SkyBox.prototype.isDestroyed = function() { return false; }; @@ -215940,860 +226914,739 @@ define('Scene/ViewportQuad',[ * * * @example - * quad = quad && quad.destroy(); + * skyBox = skyBox && skyBox.destroy(); * - * @see ViewportQuad#isDestroyed + * @see SkyBox#isDestroyed */ - ViewportQuad.prototype.destroy = function() { - if (defined(this._overlayCommand)) { - this._overlayCommand.shaderProgram = this._overlayCommand.shaderProgram && this._overlayCommand.shaderProgram.destroy(); - } + SkyBox.prototype.destroy = function() { + var command = this._command; + command.vertexArray = command.vertexArray && command.vertexArray.destroy(); + command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); + this._cubeMap = this._cubeMap && this._cubeMap.destroy(); return destroyObject(this); }; - return ViewportQuad; + return SkyBox; }); -define('Scene/WebMapServiceImageryProvider',[ - '../Core/combine', +define('Scene/SphereEmitter',[ + '../Core/Cartesian3', + '../Core/Check', '../Core/defaultValue', - '../Core/defined', '../Core/defineProperties', - '../Core/DeveloperError', - '../Core/freezeObject', - '../Core/GeographicTilingScheme', - '../Core/objectToQuery', - '../Core/queryToObject', - '../Core/WebMercatorTilingScheme', - '../ThirdParty/Uri', - './GetFeatureInfoFormat', - './UrlTemplateImageryProvider' + '../Core/Math' ], function( - combine, + Cartesian3, + Check, defaultValue, - defined, defineProperties, - DeveloperError, - freezeObject, - GeographicTilingScheme, - objectToQuery, - queryToObject, - WebMercatorTilingScheme, - Uri, - GetFeatureInfoFormat, - UrlTemplateImageryProvider) { + CesiumMath) { 'use strict'; /** - * Provides tiled imagery hosted by a Web Map Service (WMS) server. + * A ParticleEmitter that emits particles within a sphere. + * Particles will be positioned randomly within the sphere and have initial velocities emanating from the center of the sphere. * - * @alias WebMapServiceImageryProvider + * @alias SphereEmitter * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the WMS service. The URL supports the same keywords as the {@link UrlTemplateImageryProvider}. - * @param {String} options.layers The layers to include, separated by commas. - * @param {Object} [options.parameters=WebMapServiceImageryProvider.DefaultParameters] Additional parameters - * to pass to the WMS server in the GetMap URL. - * @param {Object} [options.getFeatureInfoParameters=WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters] Additional - * parameters to pass to the WMS server in the GetFeatureInfo URL. - * @param {Boolean} [options.enablePickFeatures=true] If true, {@link WebMapServiceImageryProvider#pickFeatures} will invoke - * the GetFeatureInfo operation on the WMS server and return the features included in the response. If false, - * {@link WebMapServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) - * without communicating with the server. Set this property to false if you know your WMS server does not support - * GetFeatureInfo or if you don't want this provider's features to be pickable. Note that this can be dynamically - * overridden by modifying the WebMapServiceImageryProvider#enablePickFeatures property. - * @param {GetFeatureInfoFormat[]} [options.getFeatureInfoFormats=WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats] The formats - * in which to try WMS GetFeatureInfo requests. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. - * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, - * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither - * parameter is specified, the WGS84 ellipsoid is used. - * @param {Number} [options.tileWidth=256] The width of each tile in pixels. - * @param {Number} [options.tileHeight=256] The height of each tile in pixels. - * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when - * specifying this that the number of tiles at the minimum level is small, such as four or less. A larger number is - * likely to result in rendering problems. - * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. - * If not specified, there is no limit. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * @param {Object} [options.proxy] A proxy to use for requests. This object is - * expected to have a getURL function which returns the proxied URL, if needed. - * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. - * If this parameter is a single string, each character in the string is a subdomain. If it is - * an array, each element in the array is a subdomain. + * @param {Number} [radius=1.0] The radius of the sphere in meters. + */ + function SphereEmitter(radius) { + radius = defaultValue(radius, 1.0); + + Check.typeOf.number.greaterThan('radius', radius, 0.0); + + this._radius = defaultValue(radius, 1.0); + } + + defineProperties(SphereEmitter.prototype, { + /** + * The radius of the sphere in meters. + * @memberof SphereEmitter.prototype + * @type {Number} + * @default 1.0 + */ + radius : { + get : function() { + return this._radius; + }, + set : function(value) { + Check.typeOf.number.greaterThan('value', value, 0.0); + this._radius = value; + } + } + }); + + /** + * Initializes the given {Particle} by setting it's position and velocity. * - * @see ArcGisMapServerImageryProvider - * @see BingMapsImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider + * @private + * @param {Particle} particle The particle to initialize + */ + SphereEmitter.prototype.emit = function(particle) { + var theta = CesiumMath.randomBetween(0.0, CesiumMath.TWO_PI); + var phi = CesiumMath.randomBetween(0.0, CesiumMath.PI); + var rad = CesiumMath.randomBetween(0.0, this._radius); + + var x = rad * Math.cos(theta) * Math.sin(phi); + var y = rad * Math.sin(theta) * Math.sin(phi); + var z = rad * Math.cos(phi); + + particle.position = Cartesian3.fromElements(x, y, z, particle.position); + particle.velocity = Cartesian3.normalize(particle.position, particle.velocity); + }; + + return SphereEmitter; +}); + +define('Scene/StyleExpression',[ + '../Core/DeveloperError' + ], function( + DeveloperError) { + 'use strict'; + + /** + * An expression for a style applied to a {@link Cesium3DTileset}. + * <p> + * Derived classes of this interface evaluate expressions in the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language}. + * </p> + * <p> + * This type describes an interface and is not intended to be instantiated directly. + * </p> * - * @see {@link http://resources.esri.com/help/9.3/arcgisserver/apis/rest/|ArcGIS Server REST API} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @alias StyleExpression + * @constructor * - * @example - * var provider = new Cesium.WebMapServiceImageryProvider({ - * url : 'https://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer', - * layers : '0', - * proxy: new Cesium.DefaultProxy('/proxy/') - * }); + * @see Expression + * @see ConditionsExpression + */ + function StyleExpression() { + } + + /** + * Evaluates the result of an expression, optionally using the provided feature's properties. If the result of + * the expression in the + * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling|3D Tiles Styling language} + * is of type <code>Boolean</code>, <code>Number</code>, or <code>String</code>, the corresponding JavaScript + * primitive type will be returned. If the result is a <code>RegExp</code>, a Javascript <code>RegExp</code> + * object will be returned. If the result is a <code>Cartesian2</code>, <code>Cartesian3</code>, or <code>Cartesian4</code>, + * a {@link Cartesian2}, {@link Cartesian3}, or {@link Cartesian4} object will be returned. If the <code>result</code> argument is + * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. * - * viewer.imageryLayers.addImageryProvider(provider); + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. + * @param {Object} [result] The object onto which to store the result. + * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. */ - function WebMapServiceImageryProvider(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + StyleExpression.prototype.evaluate = function(frameState, feature, result) { + DeveloperError.throwInstantiationError(); + }; - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); - } - if (!defined(options.layers)) { - throw new DeveloperError('options.layers is required.'); - } - - this._url = options.url; - this._layers = options.layers; + /** + * Evaluates the result of a Color expression, optionally using the provided feature's properties. + * <p> + * This is equivalent to {@link StyleExpression#evaluate} but always returns a {@link Color} object. + * </p> + * + * @param {FrameState} frameState The frame state. + * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. + * @param {Color} [result] The object in which to store the result. + * @returns {Color} The modified result parameter or a new Color instance if one was not provided. + */ + StyleExpression.prototype.evaluateColor = function(frameState, feature, result) { + DeveloperError.throwInstantiationError(); + }; + + /** + * Gets the shader function for this expression. + * Returns undefined if the shader function can't be generated from this expression. + * + * @param {String} functionName Name to give to the generated function. + * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes. + * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {String} returnType The return type of the generated function. + * + * @returns {String} The shader function. + * + * @private + */ + StyleExpression.prototype.getShaderFunction = function(functionName, attributePrefix, shaderState, returnType) { + DeveloperError.throwInstantiationError(); + }; + + return StyleExpression; +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/SunFS',[],function() { + 'use strict'; + return "uniform sampler2D u_texture;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +gl_FragColor = texture2D(u_texture, v_textureCoordinates);\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/SunTextureFS',[],function() { + 'use strict'; + return "uniform float u_glowLengthTS;\n\ +uniform float u_radiusTS;\n\ +varying vec2 v_textureCoordinates;\n\ +vec2 rotate(vec2 p, vec2 direction)\n\ +{\n\ +return vec2(p.x * direction.x - p.y * direction.y, p.x * direction.y + p.y * direction.x);\n\ +}\n\ +vec4 addBurst(vec2 position, vec2 direction)\n\ +{\n\ +vec2 rotatedPosition = rotate(position, direction) * vec2(25.0, 0.75);\n\ +float radius = length(rotatedPosition);\n\ +float burst = 1.0 - smoothstep(0.0, 0.55, radius);\n\ +return vec4(burst);\n\ +}\n\ +void main()\n\ +{\n\ +vec2 position = v_textureCoordinates - vec2(0.5);\n\ +float radius = length(position);\n\ +float surface = step(radius, u_radiusTS);\n\ +vec4 color = vec4(1.0, 1.0, surface + 0.2, surface);\n\ +float glow = 1.0 - smoothstep(0.0, 0.55, radius);\n\ +color.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75;\n\ +vec4 burst = vec4(0.0);\n\ +burst += 0.4 * addBurst(position, vec2(0.38942, 0.92106));\n\ +burst += 0.4 * addBurst(position, vec2(0.99235, 0.12348));\n\ +burst += 0.4 * addBurst(position, vec2(0.60327, -0.79754));\n\ +burst += 0.3 * addBurst(position, vec2(0.31457, 0.94924));\n\ +burst += 0.3 * addBurst(position, vec2(0.97931, 0.20239));\n\ +burst += 0.3 * addBurst(position, vec2(0.66507, -0.74678));\n\ +color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15;\n\ +gl_FragColor = clamp(color, vec4(0.0), vec4(1.0));\n\ +}\n\ +"; +}); +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/SunVS',[],function() { + 'use strict'; + return "attribute vec2 direction;\n\ +uniform float u_size;\n\ +varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +vec4 position;\n\ +if (czm_morphTime == 1.0)\n\ +{\n\ +position = vec4(czm_sunPositionWC, 1.0);\n\ +}\n\ +else\n\ +{\n\ +position = vec4(czm_sunPositionColumbusView.zxy, 1.0);\n\ +}\n\ +vec4 positionEC = czm_view * position;\n\ +vec4 positionWC = czm_eyeToWindowCoordinates(positionEC);\n\ +vec2 halfSize = vec2(u_size * 0.5);\n\ +halfSize *= ((direction * 2.0) - 1.0);\n\ +gl_Position = czm_viewportOrthographic * vec4(positionWC.xy + halfSize, -positionWC.z, 1.0);\n\ +v_textureCoordinates = direction;\n\ +}\n\ +"; +}); +define('Scene/Sun',[ + '../Core/BoundingSphere', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/ComponentDatatype', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/IndexDatatype', + '../Core/Math', + '../Core/Matrix4', + '../Core/PixelFormat', + '../Core/PrimitiveType', + '../Renderer/Buffer', + '../Renderer/BufferUsage', + '../Renderer/ComputeCommand', + '../Renderer/DrawCommand', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/Texture', + '../Renderer/VertexArray', + '../Shaders/SunFS', + '../Shaders/SunTextureFS', + '../Shaders/SunVS', + './BlendingState', + './SceneMode', + './SceneTransforms' + ], function( + BoundingSphere, + Cartesian2, + Cartesian3, + Cartesian4, + ComponentDatatype, + defined, + defineProperties, + destroyObject, + IndexDatatype, + CesiumMath, + Matrix4, + PixelFormat, + PrimitiveType, + Buffer, + BufferUsage, + ComputeCommand, + DrawCommand, + RenderState, + ShaderProgram, + Texture, + VertexArray, + SunFS, + SunTextureFS, + SunVS, + BlendingState, + SceneMode, + SceneTransforms) { + 'use strict'; - var getFeatureInfoFormats = defaultValue(options.getFeatureInfoFormats, WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats); + /** + * Draws a sun billboard. + * <p>This is only supported in 3D and Columbus view.</p> + * + * @alias Sun + * @constructor + * + * + * @example + * scene.sun = new Cesium.Sun(); + * + * @see Scene#sun + */ + function Sun() { + /** + * Determines if the sun will be shown. + * + * @type {Boolean} + * @default true + */ + this.show = true; - // Build the template URLs for tiles and pickFeatures. - var uri = new Uri(options.url); - var queryOptions = queryToObject(defaultValue(uri.query, '')); - var parameters = combine(objectToLowercase(defaultValue(options.parameters, defaultValue.EMPTY_OBJECT)), WebMapServiceImageryProvider.DefaultParameters); - queryOptions = combine(parameters, queryOptions); + this._drawCommand = new DrawCommand({ + primitiveType : PrimitiveType.TRIANGLES, + boundingVolume : new BoundingSphere(), + owner : this + }); + this._commands = { + drawCommand : this._drawCommand, + computeCommand : undefined + }; + this._boundingVolume = new BoundingSphere(); + this._boundingVolume2D = new BoundingSphere(); - var pickFeaturesUri; - var pickFeaturesQueryOptions; + this._texture = undefined; + this._drawingBufferWidth = undefined; + this._drawingBufferHeight = undefined; + this._radiusTS = undefined; + this._size = undefined; - pickFeaturesUri = new Uri(options.url); - pickFeaturesQueryOptions = queryToObject(defaultValue(pickFeaturesUri.query, '')); - var pickFeaturesParameters = combine(objectToLowercase(defaultValue(options.getFeatureInfoParameters, defaultValue.EMPTY_OBJECT)), WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters); - pickFeaturesQueryOptions = combine(pickFeaturesParameters, pickFeaturesQueryOptions); + this.glowFactor = 1.0; + this._glowFactorDirty = false; - function setParameter(name, value) { - if (!defined(queryOptions[name])) { - queryOptions[name] = value; + var that = this; + this._uniformMap = { + u_texture : function() { + return that._texture; + }, + u_size : function() { + return that._size; } + }; + } - if (defined(pickFeaturesQueryOptions) && !defined(pickFeaturesQueryOptions[name])) { - pickFeaturesQueryOptions[name] = value; + defineProperties(Sun.prototype, { + /** + * Gets or sets a number that controls how "bright" the Sun's lens flare appears + * to be. Zero shows just the Sun's disc without any flare. + * Use larger values for a more pronounced flare around the Sun. + * + * @memberof Sun.prototype + * @type {Number} + * @default 1.0 + */ + glowFactor : { + get : function () { return this._glowFactor; }, + set : function (glowFactor) { + glowFactor = Math.max(glowFactor, 0.0); + this._glowFactor = glowFactor; + this._glowFactorDirty = true; } } + }); - setParameter('layers', options.layers); + var scratchPositionWC = new Cartesian2(); + var scratchLimbWC = new Cartesian2(); + var scratchPositionEC = new Cartesian4(); + var scratchCartesian4 = new Cartesian4(); - // Use SRS or CRS based on the WMS version. - if (parseFloat(parameters.version) >= 1.3) { - // Use CRS with 1.3.0 and going forward. - // For GeographicTilingScheme, use CRS:84 vice EPSG:4326 to specify lon, lat (x, y) ordering for - // bbox requests. - setParameter('crs', options.tilingScheme instanceof WebMercatorTilingScheme ? 'EPSG:3857' : 'CRS:84'); + /** + * @private + */ + Sun.prototype.update = function(frameState, passState) { + if (!this.show) { + return undefined; } - else { - // SRS for WMS 1.1.0 or 1.1.1. - setParameter('srs', options.tilingScheme instanceof WebMercatorTilingScheme ? 'EPSG:3857' : 'EPSG:4326'); + + var mode = frameState.mode; + if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) { + return undefined; } - setParameter('bbox', '{westProjected},{southProjected},{eastProjected},{northProjected}'); - setParameter('width', '{width}'); - setParameter('height', '{height}'); + if (!frameState.passes.render) { + return undefined; + } - uri.query = objectToQuery(queryOptions); + var context = frameState.context; + var drawingBufferWidth = passState.viewport.width; + var drawingBufferHeight = passState.viewport.height; - // objectToQuery escapes the placeholders. Undo that. - var templateUrl = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + if (!defined(this._texture) || + drawingBufferWidth !== this._drawingBufferWidth || + drawingBufferHeight !== this._drawingBufferHeight || + this._glowFactorDirty) { + this._texture = this._texture && this._texture.destroy(); + this._drawingBufferWidth = drawingBufferWidth; + this._drawingBufferHeight = drawingBufferHeight; + this._glowFactorDirty = false; - var pickFeaturesTemplateUrl; - if (defined(pickFeaturesQueryOptions)) { - if (!defined(pickFeaturesQueryOptions.query_layers)) { - pickFeaturesQueryOptions.query_layers = options.layers; - } + var size = Math.max(drawingBufferWidth, drawingBufferHeight); + size = Math.pow(2.0, Math.ceil(Math.log(size) / Math.log(2.0)) - 2.0); - if (!defined(pickFeaturesQueryOptions.x)) { - pickFeaturesQueryOptions.x = '{i}'; - } + // The size computed above can be less than 1.0 if size < 4.0. This will probably + // never happen in practice, but does in the tests. Clamp to 1.0 to prevent WebGL + // errors in the tests. + size = Math.max(1.0, size); - if (!defined(pickFeaturesQueryOptions.y)) { - pickFeaturesQueryOptions.y = '{j}'; - } + this._texture = new Texture({ + context : context, + width : size, + height : size, + pixelFormat : PixelFormat.RGBA + }); - if (!defined(pickFeaturesQueryOptions.info_format)) { - pickFeaturesQueryOptions.info_format = '{format}'; - } + this._glowLengthTS = this._glowFactor * 5.0; + this._radiusTS = (1.0 / (1.0 + 2.0 * this._glowLengthTS)) * 0.5; + + var that = this; + var uniformMap = { + u_glowLengthTS : function() { + return that._glowLengthTS; + }, + u_radiusTS : function() { + return that._radiusTS; + } + }; - pickFeaturesUri.query = objectToQuery(pickFeaturesQueryOptions); - pickFeaturesTemplateUrl = pickFeaturesUri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + this._commands.computeCommand = new ComputeCommand({ + fragmentShaderSource : SunTextureFS, + outputTexture : this._texture, + uniformMap : uniformMap, + persists : false, + owner : this, + postExecute : function() { + that._commands.computeCommand = undefined; + } + }); } - // Let UrlTemplateImageryProvider do the actual URL building. - this._tileProvider = new UrlTemplateImageryProvider({ - url : templateUrl, - pickFeaturesUrl : pickFeaturesTemplateUrl, - tilingScheme : defaultValue(options.tilingScheme, new GeographicTilingScheme({ ellipsoid : options.ellipsoid})), - rectangle : options.rectangle, - tileWidth : options.tileWidth, - tileHeight : options.tileHeight, - minimumLevel : options.minimumLevel, - maximumLevel : options.maximumLevel, - proxy : options.proxy, - subdomains: options.subdomains, - tileDiscardPolicy : options.tileDiscardPolicy, - credit : options.credit, - getFeatureInfoFormats : getFeatureInfoFormats, - enablePickFeatures: options.enablePickFeatures - }); - } + var drawCommand = this._drawCommand; - defineProperties(WebMapServiceImageryProvider.prototype, { - /** - * Gets the URL of the WMS server. - * @memberof WebMapServiceImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; - } - }, + if (!defined(drawCommand.vertexArray)) { + var attributeLocations = { + direction : 0 + }; - /** - * Gets the proxy used by this provider. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Proxy} - * @readonly - */ - proxy : { - get : function() { - return this._tileProvider.proxy; - } - }, + var directions = new Uint8Array(4 * 2); + directions[0] = 0; + directions[1] = 0; - /** - * Gets the names of the WMS layers, separated by commas. - * @memberof WebMapServiceImageryProvider.prototype - * @type {String} - * @readonly - */ - layers : { - get : function() { - return this._layers; - } - }, + directions[2] = 255; + directions[3] = 0.0; - /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileWidth : { - get : function() { - return this._tileProvider.tileWidth; - } - }, + directions[4] = 255; + directions[5] = 255; - /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} - * @readonly - */ - tileHeight : { - get : function() { - return this._tileProvider.tileHeight; - } - }, + directions[6] = 0.0; + directions[7] = 255; - /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} - * @readonly - */ - maximumLevel : { - get : function() { - return this._tileProvider.maximumLevel; - } - }, + var vertexBuffer = Buffer.createVertexBuffer({ + context : context, + typedArray : directions, + usage : BufferUsage.STATIC_DRAW + }); + var attributes = [{ + index : attributeLocations.direction, + vertexBuffer : vertexBuffer, + componentsPerAttribute : 2, + normalize : true, + componentDatatype : ComponentDatatype.UNSIGNED_BYTE + }]; + // Workaround Internet Explorer 11.0.8 lack of TRIANGLE_FAN + var indexBuffer = Buffer.createIndexBuffer({ + context : context, + typedArray : new Uint16Array([0, 1, 2, 0, 2, 3]), + usage : BufferUsage.STATIC_DRAW, + indexDatatype : IndexDatatype.UNSIGNED_SHORT + }); + drawCommand.vertexArray = new VertexArray({ + context : context, + attributes : attributes, + indexBuffer : indexBuffer + }); - /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} - * @readonly - */ - minimumLevel : { - get : function() { - return this._tileProvider.minimumLevel; - } - }, + drawCommand.shaderProgram = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : SunVS, + fragmentShaderSource : SunFS, + attributeLocations : attributeLocations + }); - /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {TilingScheme} - * @readonly - */ - tilingScheme : { - get : function() { - return this._tileProvider.tilingScheme; - } - }, + drawCommand.renderState = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND + }); + drawCommand.uniformMap = this._uniformMap; + } - /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Rectangle} - * @readonly - */ - rectangle : { - get : function() { - return this._tileProvider.rectangle; - } - }, + var sunPosition = context.uniformState.sunPositionWC; + var sunPositionCV = context.uniformState.sunPositionColumbusView; - /** - * Gets the tile discard policy. If not undefined, the discard policy is responsible - * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {TileDiscardPolicy} - * @readonly - */ - tileDiscardPolicy : { - get : function() { - return this._tileProvider.tileDiscardPolicy; - } - }, + var boundingVolume = this._boundingVolume; + var boundingVolume2D = this._boundingVolume2D; - /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing - * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Event} - * @readonly - */ - errorEvent : { - get : function() { - return this._tileProvider.errorEvent; - } - }, + Cartesian3.clone(sunPosition, boundingVolume.center); + boundingVolume2D.center.x = sunPositionCV.z; + boundingVolume2D.center.y = sunPositionCV.x; + boundingVolume2D.center.z = sunPositionCV.y; - /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - ready : { - get : function() { - return this._tileProvider.ready; - } - }, + boundingVolume.radius = CesiumMath.SOLAR_RADIUS + CesiumMath.SOLAR_RADIUS * this._glowLengthTS; + boundingVolume2D.radius = boundingVolume.radius; - /** - * Gets a promise that resolves to true when the provider is ready for use. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Promise.<Boolean>} - * @readonly - */ - readyPromise : { - get : function() { - return this._tileProvider.readyPromise; - } - }, + if (mode === SceneMode.SCENE3D) { + BoundingSphere.clone(boundingVolume, drawCommand.boundingVolume); + } else if (mode === SceneMode.COLUMBUS_VIEW) { + BoundingSphere.clone(boundingVolume2D, drawCommand.boundingVolume); + } - /** - * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link WebMapServiceImageryProvider#ready} returns true. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Credit} - * @readonly - */ - credit : { - get : function() { - return this._tileProvider.credit; - } - }, + var position = SceneTransforms.computeActualWgs84Position(frameState, sunPosition, scratchCartesian4); - /** - * Gets a value indicating whether or not the images provided by this imagery provider - * include an alpha channel. If this property is false, an alpha channel, if present, will - * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Boolean} - * @readonly - */ - hasAlphaChannel : { - get : function() { - return this._tileProvider.hasAlphaChannel; - } - }, + var dist = Cartesian3.magnitude(Cartesian3.subtract(position, frameState.camera.position, scratchCartesian4)); + var projMatrix = context.uniformState.projection; - /** - * Gets or sets a value indicating whether feature picking is enabled. If true, {@link WebMapServiceImageryProvider#pickFeatures} will - * invoke the <code>GetFeatureInfo</code> service on the WMS server and attempt to interpret the features included in the response. If false, - * {@link WebMapServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable - * features) without communicating with the server. Set this property to false if you know your data - * source does not support picking features or if you don't want this provider's features to be pickable. - * @memberof WebMapServiceImageryProvider.prototype - * @type {Boolean} - * @default true - */ - enablePickFeatures : { - get : function() { - return this._tileProvider.enablePickFeatures; - }, - set : function(enablePickFeatures) { - this._tileProvider.enablePickFeatures = enablePickFeatures; - } - } - }); + var positionEC = scratchPositionEC; + positionEC.x = 0; + positionEC.y = 0; + positionEC.z = -dist; + positionEC.w = 1; + + var positionCC = Matrix4.multiplyByVector(projMatrix, positionEC, scratchCartesian4); + var positionWC = SceneTransforms.clipToGLWindowCoordinates(passState.viewport, positionCC, scratchPositionWC); + + positionEC.x = CesiumMath.SOLAR_RADIUS; + var limbCC = Matrix4.multiplyByVector(projMatrix, positionEC, scratchCartesian4); + var limbWC = SceneTransforms.clipToGLWindowCoordinates(passState.viewport, limbCC, scratchLimbWC); + + this._size = Math.ceil(Cartesian2.magnitude(Cartesian2.subtract(limbWC, positionWC, scratchCartesian4))); + this._size = 2.0 * this._size * (1.0 + 2.0 * this._glowLengthTS); + + return this._commands; + }; /** - * Gets the credits to be displayed when a given tile is displayed. + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; - * @returns {Credit[]} The credits to be displayed when the tile is displayed. + * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. + * @see Sun#destroy */ - WebMapServiceImageryProvider.prototype.getTileCredits = function(x, y, level) { - return this._tileProvider.getTileCredits(x, y, level); + Sun.prototype.isDestroyed = function() { + return false; }; /** - * Requests the image for a given tile. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Image|Canvas>|undefined} A promise for the image that will resolve when the image is available, or - * undefined if there are too many active requests to the server, and the request - * should be retried later. The resolved image may be either an - * Image or a Canvas DOM object. + * @returns {undefined} * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * sun = sun && sun.destroy(); + * + * @see Sun#isDestroyed */ - WebMapServiceImageryProvider.prototype.requestImage = function(x, y, level, request) { - return this._tileProvider.requestImage(x, y, level, request); + Sun.prototype.destroy = function() { + var command = this._drawCommand; + command.vertexArray = command.vertexArray && command.vertexArray.destroy(); + command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); + + this._texture = this._texture && this._texture.destroy(); + + return destroyObject(this); }; + return Sun; +}); + +define('Scene/TileBoundingVolume',[ + '../Core/DeveloperError' + ], function( + DeveloperError) { + 'use strict'; + /** - * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * Defines a bounding volume for a tile. This type describes an interface + * and is not intended to be instantiated directly. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous - * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} - * instances. The array may be empty if no features are found at the given location. + * @see TileBoundingRegion + * @see TileBoundingSphere + * @see TileOrientedBoundingBox * - * @exception {DeveloperError} <code>pickFeatures</code> must not be called before the imagery provider is ready. + * @private */ - WebMapServiceImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { - return this._tileProvider.pickFeatures(x, y, level, longitude, latitude); - }; + function TileBoundingVolume() { + } /** - * The default parameters to include in the WMS URL to obtain images. The values are as follows: - * service=WMS - * version=1.1.1 - * request=GetMap - * styles= - * format=image/jpeg + * The underlying bounding volume. * - * @constant + * @memberof TileBoundingVolume.prototype + * + * @type {Object} + * @readonly */ - WebMapServiceImageryProvider.DefaultParameters = freezeObject({ - service : 'WMS', - version : '1.1.1', - request : 'GetMap', - styles : '', - format : 'image/jpeg' - }); + TileBoundingVolume.prototype.boundingVolume = undefined; /** - * The default parameters to include in the WMS URL to get feature information. The values are as follows: - * service=WMS - * version=1.1.1 - * request=GetFeatureInfo + * The underlying bounding sphere. * - * @constant + * @memberof TileBoundingVolume.prototype + * + * @type {BoundingSphere} + * @readonly */ - WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters = freezeObject({ - service : 'WMS', - version : '1.1.1', - request : 'GetFeatureInfo' - }); + TileBoundingVolume.prototype.boundingSphere = undefined; - WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats = freezeObject([ - freezeObject(new GetFeatureInfoFormat('json', 'application/json')), - freezeObject(new GetFeatureInfoFormat('xml', 'text/xml')), - freezeObject(new GetFeatureInfoFormat('text', 'text/html')) - ]); + /** + * Calculates the distance between the tile and the camera. + * + * @param {FrameState} frameState The frame state. + * @return {Number} The distance between the tile and the camera, in meters. + * Returns 0.0 if the camera is inside the tile. + */ + TileBoundingVolume.prototype.distanceToCamera = function(frameState) { + DeveloperError.throwInstantiationError(); + }; - function objectToLowercase(obj) { - var result = {}; - for ( var key in obj) { - if (obj.hasOwnProperty(key)) { - result[key.toLowerCase()] = obj[key]; - } - } - return result; - } + /** + * Determines which side of a plane this volume is located. + * + * @param {Plane} plane The plane to test against. + * @returns {Intersect} {@link Intersect.INSIDE} if the entire volume is on the side of the plane + * the normal is pointing, {@link Intersect.OUTSIDE} if the entire volume is + * on the opposite side, and {@link Intersect.INTERSECTING} if the volume + * intersects the plane. + */ + TileBoundingVolume.prototype.intersectPlane = function(plane) { + DeveloperError.throwInstantiationError(); + }; - return WebMapServiceImageryProvider; + /** + * Creates a debug primitive that shows the outline of the tile bounding + * volume. + * + * @param {Color} color The desired color of the primitive's mesh + * @return {Primitive} + */ + TileBoundingVolume.prototype.createDebugVolume = function(color) { + DeveloperError.throwInstantiationError(); + }; + + return TileBoundingVolume; }); -define('Scene/WebMapTileServiceImageryProvider',[ - '../Core/combine', - '../Core/Credit', +define('Scene/TileCoordinatesImageryProvider',[ + '../Core/Color', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/DeveloperError', '../Core/Event', - '../Core/freezeObject', - '../Core/isArray', - '../Core/objectToQuery', - '../Core/queryToObject', - '../Core/Rectangle', - '../Core/WebMercatorTilingScheme', - '../ThirdParty/Uri', - '../ThirdParty/when', - './ImageryProvider', - './TimeDynamicImagery' + '../Core/GeographicTilingScheme', + '../ThirdParty/when' ], function( - combine, - Credit, + Color, defaultValue, defined, defineProperties, - DeveloperError, Event, - freezeObject, - isArray, - objectToQuery, - queryToObject, - Rectangle, - WebMercatorTilingScheme, - Uri, - when, - ImageryProvider, - TimeDynamicImagery) { + GeographicTilingScheme, + when) { 'use strict'; /** - * Provides tiled imagery served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers. - * This provider supports HTTP KVP-encoded and RESTful GetTile requests, but does not yet support the SOAP encoding. + * An {@link ImageryProvider} that draws a box around every rendered tile in the tiling scheme, and draws + * a label inside it indicating the X, Y, Level coordinates of the tile. This is mostly useful for + * debugging terrain and imagery rendering problems. * - * @alias WebMapTileServiceImageryProvider + * @alias TileCoordinatesImageryProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains. - * @param {String} [options.format='image/jpeg'] The MIME type for images to retrieve from the server. - * @param {String} options.layer The layer name for WMTS requests. - * @param {String} options.style The style name for WMTS requests. - * @param {String} options.tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests. - * @param {Array} [options.tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level. - * @param {Clock} [options.clock] A Clock instance that is used when determining the value for the time dimension. Required when options.times is specified. - * @param {TimeIntervalCollection} [options.times] TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values. - * @param {Object} [options.dimensions] A object containing static dimensions and their values. - * @param {Number} [options.tileWidth=256] The tile width in pixels. - * @param {Number} [options.tileHeight=256] The tile height in pixels. - * @param {TilingScheme} [options.tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet. - * @param {Object} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL. - * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer. - * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. - * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. - * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. - * If this parameter is a single string, each character in the string is a subdomain. If it is - * an array, each element in the array is a subdomain. - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Web%20Map%20Tile%20Service%20with%20Time.html|Cesium Sandcastle Web Map Tile Service with Time Demo} - * - * @example - * // Example 1. USGS shaded relief tiles (KVP) - * var shadedRelief1 = new Cesium.WebMapTileServiceImageryProvider({ - * url : 'http://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS', - * layer : 'USGSShadedReliefOnly', - * style : 'default', - * format : 'image/jpeg', - * tileMatrixSetID : 'default028mm', - * // tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...], - * maximumLevel: 19, - * credit : new Cesium.Credit({ text : 'U. S. Geological Survey' }) - * }); - * viewer.imageryLayers.addImageryProvider(shadedRelief1); - * - * @example - * // Example 2. USGS shaded relief tiles (RESTful) - * var shadedRelief2 = new Cesium.WebMapTileServiceImageryProvider({ - * url : 'http://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS/tile/1.0.0/USGSShadedReliefOnly/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg', - * layer : 'USGSShadedReliefOnly', - * style : 'default', - * format : 'image/jpeg', - * tileMatrixSetID : 'default028mm', - * maximumLevel: 19, - * credit : new Cesium.Credit({ text : 'U. S. Geological Survey' }) - * }); - * viewer.imageryLayers.addImageryProvider(shadedRelief2); - * - * @example - * // Example 3. NASA time dynamic weather data (RESTful) - * var times = Cesium.TimeIntervalCollection.fromIso8601({ - * iso8601: '2015-07-30/2017-06-16/P1D', - * dataCallback: function dataCallback(interval, index) { - * return { - * Time: Cesium.JulianDate.toIso8601(interval.start) - * }; - * } - * }); - * var weather = new Cesium.WebMapTileServiceImageryProvider({ - * url : 'https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/AMSR2_Snow_Water_Equivalent/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png', - * layer : 'AMSR2_Snow_Water_Equivalent', - * style : 'default', - * tileMatrixSetID : '2km', - * maximumLevel : 5, - * format : 'image/png', - * clock: clock, - * times: times, - * credit : new Cesium.Credit({ text : 'NASA Global Imagery Browse Services for EOSDIS' }) - * }); - * viewer.imageryLayers.addImageryProvider(weather); - * - * @see ArcGisMapServerImageryProvider - * @see BingMapsImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see createOpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see createTileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see UrlTemplateImageryProvider + * @param {Object} [options] Object with the following properties: + * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles. + * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, + * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither + * parameter is specified, the WGS84 ellipsoid is used. + * @param {Color} [options.color=Color.YELLOW] The color to draw the tile box and label. + * @param {Number} [options.tileWidth=256] The width of the tile for level-of-detail selection purposes. + * @param {Number} [options.tileHeight=256] The height of the tile for level-of-detail selection purposes. */ - function WebMapTileServiceImageryProvider(options) { + function TileCoordinatesImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - if (!defined(options.url)) { - throw new DeveloperError('options.url is required.'); - } - if (!defined(options.layer)) { - throw new DeveloperError('options.layer is required.'); - } - if (!defined(options.style)) { - throw new DeveloperError('options.style is required.'); - } - if (!defined(options.tileMatrixSetID)) { - throw new DeveloperError('options.tileMatrixSetID is required.'); - } - if (defined(options.times) && !defined(options.clock)) { - throw new DeveloperError('options.times was specified, so options.clock is required.'); - } - - this._url = options.url; - this._layer = options.layer; - this._style = options.style; - this._tileMatrixSetID = options.tileMatrixSetID; - this._tileMatrixLabels = options.tileMatrixLabels; - this._format = defaultValue(options.format, 'image/jpeg'); - this._proxy = options.proxy; - this._tileDiscardPolicy = options.tileDiscardPolicy; - - this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new WebMercatorTilingScheme({ellipsoid : options.ellipsoid}); + this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme : new GeographicTilingScheme({ ellipsoid : options.ellipsoid }); + this._color = defaultValue(options.color, Color.YELLOW); + this._errorEvent = new Event(); this._tileWidth = defaultValue(options.tileWidth, 256); this._tileHeight = defaultValue(options.tileHeight, 256); - - this._minimumLevel = defaultValue(options.minimumLevel, 0); - this._maximumLevel = options.maximumLevel; - - this._rectangle = defaultValue(options.rectangle, this._tilingScheme.rectangle); - this._dimensions = options.dimensions; - - var that = this; - this._reload = undefined; - if (defined(options.times)) { - this._timeDynamicImagery = new TimeDynamicImagery({ - clock : options.clock, - times : options.times, - requestImageFunction : function(x, y, level, request, interval) { - return requestImage(that, x, y, level, request, interval); - }, - reloadFunction : function() { - if (defined(that._reload)) { - that._reload(); - } - } - }); - } - this._readyPromise = when.resolve(true); - - // Check the number of tiles at the minimum level. If it's more than four, - // throw an exception, because starting at the higher minimum - // level will cause too many tiles to be downloaded and rendered. - var swTile = this._tilingScheme.positionToTileXY(Rectangle.southwest(this._rectangle), this._minimumLevel); - var neTile = this._tilingScheme.positionToTileXY(Rectangle.northeast(this._rectangle), this._minimumLevel); - var tileCount = (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1); - if (tileCount > 4) { - throw new DeveloperError('The imagery provider\'s rectangle and minimumLevel indicate that there are ' + tileCount + ' tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.'); - } - - this._errorEvent = new Event(); - - var credit = options.credit; - this._credit = typeof credit === 'string' ? new Credit({text: credit}) : credit; - - this._subdomains = options.subdomains; - if (isArray(this._subdomains)) { - this._subdomains = this._subdomains.slice(); - } else if (defined(this._subdomains) && this._subdomains.length > 0) { - this._subdomains = this._subdomains.split(''); - } else { - this._subdomains = ['a', 'b', 'c']; - } - } - - var defaultParameters = freezeObject({ - service : 'WMTS', - version : '1.0.0', - request : 'GetTile' - }); - - function requestImage(imageryProvider, col, row, level, request, interval) { - var labels = imageryProvider._tileMatrixLabels; - var tileMatrix = defined(labels) ? labels[level] : level.toString(); - var subdomains = imageryProvider._subdomains; - var url; - var key; - var staticDimensions = imageryProvider._dimensions; - var dynamicIntervalData = defined(interval) ? interval.data : undefined; - - if (imageryProvider._url.indexOf('{') >= 0) { - // resolve tile-URL template - url = imageryProvider._url - .replace('{style}', imageryProvider._style) - .replace('{Style}', imageryProvider._style) - .replace('{TileMatrixSet}', imageryProvider._tileMatrixSetID) - .replace('{TileMatrix}', tileMatrix) - .replace('{TileRow}', row.toString()) - .replace('{TileCol}', col.toString()) - .replace('{s}', subdomains[(col + row + level) % subdomains.length]); - - if (defined(staticDimensions)) { - for (key in staticDimensions) { - if (staticDimensions.hasOwnProperty(key)) { - url = url.replace('{' + key + '}', staticDimensions[key]); - } - } - } - - if (defined(dynamicIntervalData)) { - for (key in dynamicIntervalData) { - if (dynamicIntervalData.hasOwnProperty(key)) { - url = url.replace('{' + key + '}', dynamicIntervalData[key]); - } - } - } - } - else { - // build KVP request - var uri = new Uri(imageryProvider._url); - var queryOptions = queryToObject(defaultValue(uri.query, '')); - - queryOptions = combine(defaultParameters, queryOptions); - - queryOptions.tilematrix = tileMatrix; - queryOptions.layer = imageryProvider._layer; - queryOptions.style = imageryProvider._style; - queryOptions.tilerow = row; - queryOptions.tilecol = col; - queryOptions.tilematrixset = imageryProvider._tileMatrixSetID; - queryOptions.format = imageryProvider._format; - - if (defined(staticDimensions)) { - for (key in staticDimensions) { - if (staticDimensions.hasOwnProperty(key)) { - queryOptions[key] = staticDimensions[key]; - } - } - } - - if (defined(dynamicIntervalData)) { - for (key in dynamicIntervalData) { - if (dynamicIntervalData.hasOwnProperty(key)) { - queryOptions[key] = dynamicIntervalData[key]; - } - } - } - - uri.query = objectToQuery(queryOptions); - - url = uri.toString(); - } - - var proxy = imageryProvider._proxy; - if (defined(proxy)) { - url = proxy.getURL(url); - } - - return ImageryProvider.loadImage(imageryProvider, url, request); } - defineProperties(WebMapTileServiceImageryProvider.prototype, { - /** - * Gets the URL of the service hosting the imagery. - * @memberof WebMapTileServiceImageryProvider.prototype - * @type {String} - * @readonly - */ - url : { - get : function() { - return this._url; - } - }, - + defineProperties(TileCoordinatesImageryProvider.prototype, { /** * Gets the proxy used by this provider. - * @memberof WebMapTileServiceImageryProvider.prototype + * @memberof TileCoordinatesImageryProvider.prototype * @type {Proxy} * @readonly */ proxy : { get : function() { - return this._proxy; + return undefined; } }, /** * Gets the width of each tile, in pixels. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly */ @@ -216805,12 +227658,12 @@ define('Scene/WebMapTileServiceImageryProvider',[ /** * Gets the height of each tile, in pixels. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly */ - tileHeight : { + tileHeight: { get : function() { return this._tileHeight; } @@ -216818,34 +227671,34 @@ define('Scene/WebMapTileServiceImageryProvider',[ /** * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly */ maximumLevel : { get : function() { - return this._maximumLevel; + return undefined; } }, /** * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly */ minimumLevel : { get : function() { - return this._minimumLevel; + return undefined; } }, /** * Gets the tiling scheme used by this provider. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {TilingScheme} * @readonly */ @@ -216857,14 +227710,14 @@ define('Scene/WebMapTileServiceImageryProvider',[ /** * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Rectangle} * @readonly */ rectangle : { get : function() { - return this._rectangle; + return this._tilingScheme.rectangle; } }, @@ -216872,14 +227725,14 @@ define('Scene/WebMapTileServiceImageryProvider',[ * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function * returns undefined, no tiles are filtered. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy : { get : function() { - return this._tileDiscardPolicy; + return undefined; } }, @@ -216887,7 +227740,7 @@ define('Scene/WebMapTileServiceImageryProvider',[ * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners * are passed an instance of {@link TileProviderError}. - * @memberof WebMapTileServiceImageryProvider.prototype + * @memberof TileCoordinatesImageryProvider.prototype * @type {Event} * @readonly */ @@ -216897,31 +227750,21 @@ define('Scene/WebMapTileServiceImageryProvider',[ } }, - /** - * Gets the mime type of images returned by this imagery provider. - * @memberof WebMapTileServiceImageryProvider.prototype - * @type {String} - * @readonly - */ - format : { - get : function() { - return this._format; - } - }, - /** * Gets a value indicating whether or not the provider is ready for use. - * @memberof WebMapTileServiceImageryProvider.prototype + * @memberof TileCoordinatesImageryProvider.prototype * @type {Boolean} * @readonly */ ready : { - value : true + get : function() { + return true; + } }, /** * Gets a promise that resolves to true when the provider is ready for use. - * @memberof WebMapTileServiceImageryProvider.prototype + * @memberof TileCoordinatesImageryProvider.prototype * @type {Promise.<Boolean>} * @readonly */ @@ -216933,14 +227776,14 @@ define('Scene/WebMapTileServiceImageryProvider',[ /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. - * @memberof WebMapTileServiceImageryProvider.prototype + * the source of the imagery. This function should not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Credit} * @readonly */ credit : { get : function() { - return this._credit; + return undefined; } }, @@ -216948,9 +227791,9 @@ define('Scene/WebMapTileServiceImageryProvider',[ * Gets a value indicating whether or not the images provided by this imagery provider * include an alpha channel. If this property is false, an alpha channel, if present, will * be ignored. If this property is true, any images without an alpha channel will be treated - * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. - * @memberof WebMapTileServiceImageryProvider.prototype + * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage + * and texture upload time. + * @memberof TileCoordinatesImageryProvider.prototype * @type {Boolean} * @readonly */ @@ -216958,52 +227801,6 @@ define('Scene/WebMapTileServiceImageryProvider',[ get : function() { return true; } - }, - /** - * Gets or sets a clock that is used to get keep the time used for time dynamic parameters. - * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Clock} - */ - clock : { - get : function() { - return this._timeDynamicImagery.clock; - }, - set : function(value) { - this._timeDynamicImagery.clock = value; - } - }, - /** - * Gets or sets a time interval collection that is used to get time dynamic parameters. The data of each - * TimeInterval is an object containing the keys and values of the properties that are used during - * tile requests. - * @memberof WebMapTileServiceImageryProvider.prototype - * @type {TimeIntervalCollection} - */ - times : { - get : function() { - return this._timeDynamicImagery.times; - }, - set : function(value) { - this._timeDynamicImagery.times = value; - } - }, - /** - * Gets or sets an object that contains static dimensions and their values. - * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Object} - */ - dimensions : { - get : function() { - return this._dimensions; - }, - set : function(value) { - if (this._dimensions !== value) { - this._dimensions = value; - if (defined(this._reload)) { - this._reload(); - } - } - } } }); @@ -217017,13 +227814,13 @@ define('Scene/WebMapTileServiceImageryProvider',[ * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ - WebMapTileServiceImageryProvider.prototype.getTileCredits = function(x, y, level) { + TileCoordinatesImageryProvider.prototype.getTileCredits = function(x, y, level) { return undefined; }; /** * Requests the image for a given tile. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -217033,31 +227830,28 @@ define('Scene/WebMapTileServiceImageryProvider',[ * undefined if there are too many active requests to the server, and the request * should be retried later. The resolved image may be either an * Image or a Canvas DOM object. - * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */ - WebMapTileServiceImageryProvider.prototype.requestImage = function(x, y, level, request) { - var result; - var timeDynamicImagery = this._timeDynamicImagery; - var currentInterval; + TileCoordinatesImageryProvider.prototype.requestImage = function(x, y, level, request) { + var canvas = document.createElement('canvas'); + canvas.width = 256; + canvas.height = 256; + var context = canvas.getContext('2d'); - // Try and load from cache - if (defined(timeDynamicImagery)) { - currentInterval = timeDynamicImagery.currentInterval; - result = timeDynamicImagery.getFromCache(x, y, level, request); - } + var cssColor = this._color.toCssColorString(); - // Couldn't load from cache - if (!defined(result)) { - result = requestImage(this, x, y, level, request, currentInterval); - } + context.strokeStyle = cssColor; + context.lineWidth = 2; + context.strokeRect(1, 1, 255, 255); - // If we are approaching an interval, preload this tile in the next interval - if (defined(result) && defined(timeDynamicImagery)) { - timeDynamicImagery.checkApproachingInterval(x, y, level, request); - } + var label = 'L' + level + 'X' + x + 'Y' + y; + context.font = 'bold 25px Arial'; + context.textAlign = 'center'; + context.fillStyle = 'black'; + context.fillText(label, 127, 127); + context.fillStyle = cssColor; + context.fillText(label, 124, 124); - return result; + return canvas; }; /** @@ -217074,11 +227868,282 @@ define('Scene/WebMapTileServiceImageryProvider',[ * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. */ - WebMapTileServiceImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { + TileCoordinatesImageryProvider.prototype.pickFeatures = function(x, y, level, longitude, latitude) { return undefined; }; - return WebMapTileServiceImageryProvider; + return TileCoordinatesImageryProvider; +}); + +define('Scene/TileDiscardPolicy',[ + '../Core/DeveloperError' + ], function( + DeveloperError) { + 'use strict'; + + /** + * A policy for discarding tile images according to some criteria. This type describes an + * interface and is not intended to be instantiated directly. + * + * @alias TileDiscardPolicy + * @constructor + * + * @see DiscardMissingTileImagePolicy + * @see NeverTileDiscardPolicy + */ + function TileDiscardPolicy(options) { + DeveloperError.throwInstantiationError(); + } + + /** + * Determines if the discard policy is ready to process images. + * @function + * + * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + */ + TileDiscardPolicy.prototype.isReady = DeveloperError.throwInstantiationError; + + /** + * Given a tile image, decide whether to discard that image. + * @function + * + * @param {Image} image An image to test. + * @returns {Boolean} True if the image should be discarded; otherwise, false. + */ + TileDiscardPolicy.prototype.shouldDiscardImage = DeveloperError.throwInstantiationError; + + return TileDiscardPolicy; +}); + +define('Scene/TileState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * @private + */ + var TileState = { + START : 0, + LOADING : 1, + READY : 2, + UPSAMPLED_ONLY : 3 + }; + + return freezeObject(TileState); +}); + +//This file is automatically rebuilt by the Cesium build process. +define('Shaders/ViewportQuadFS',[],function() { + 'use strict'; + return "varying vec2 v_textureCoordinates;\n\ +void main()\n\ +{\n\ +czm_materialInput materialInput;\n\ +materialInput.s = v_textureCoordinates.s;\n\ +materialInput.st = v_textureCoordinates;\n\ +materialInput.str = vec3(v_textureCoordinates, 0.0);\n\ +materialInput.normalEC = vec3(0.0, 0.0, -1.0);\n\ +czm_material material = czm_getMaterial(materialInput);\n\ +gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\ +}\n\ +"; +}); +define('Scene/ViewportQuad',[ + '../Core/BoundingRectangle', + '../Core/Color', + '../Core/defined', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderSource', + '../Shaders/ViewportQuadFS', + './BlendingState', + './Material' + ], function( + BoundingRectangle, + Color, + defined, + destroyObject, + DeveloperError, + Pass, + RenderState, + ShaderSource, + ViewportQuadFS, + BlendingState, + Material) { + 'use strict'; + + /** + * A viewport aligned quad. + * + * @alias ViewportQuad + * @constructor + * + * @param {BoundingRectangle} [rectangle] The {@link BoundingRectangle} defining the quad's position within the viewport. + * @param {Material} [material] The {@link Material} defining the surface appearance of the viewport quad. + * + * @example + * var viewportQuad = new Cesium.ViewportQuad(new Cesium.BoundingRectangle(0, 0, 80, 40)); + * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 0.0, 0.0, 1.0); + */ + function ViewportQuad(rectangle, material) { + /** + * Determines if the viewport quad primitive will be shown. + * + * @type {Boolean} + * @default true + */ + this.show = true; + + if (!defined(rectangle)) { + rectangle = new BoundingRectangle(); + } + + /** + * The BoundingRectangle defining the quad's position within the viewport. + * + * @type {BoundingRectangle} + * + * @example + * viewportQuad.rectangle = new Cesium.BoundingRectangle(0, 0, 80, 40); + */ + this.rectangle = BoundingRectangle.clone(rectangle); + + if (!defined(material)) { + material = Material.fromType(Material.ColorType, { + color : new Color(1.0, 1.0, 1.0, 1.0) + }); + } + + /** + * The surface appearance of the viewport quad. This can be one of several built-in {@link Material} objects or a custom material, scripted with + * {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}. + * <p> + * The default material is <code>Material.ColorType</code>. + * </p> + * + * @type Material + * + * @example + * // 1. Change the color of the default material to yellow + * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); + * + * // 2. Change material to horizontal stripes + * viewportQuad.material = Cesium.Material.fromType(Cesium.Material.StripeType); + * + * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric} + */ + this.material = material; + this._material = undefined; + + this._overlayCommand = undefined; + this._rs = undefined; + } + + /** + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + * <p> + * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + * </p> + * + * @exception {DeveloperError} this.material must be defined. + * @exception {DeveloperError} this.rectangle must be defined. + */ + ViewportQuad.prototype.update = function(frameState) { + if (!this.show) { + return; + } + + if (!defined(this.material)) { + throw new DeveloperError('this.material must be defined.'); + } + if (!defined(this.rectangle)) { + throw new DeveloperError('this.rectangle must be defined.'); + } + + var rs = this._rs; + if ((!defined(rs)) || !BoundingRectangle.equals(rs.viewport, this.rectangle)) { + this._rs = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND, + viewport : this.rectangle + }); + } + + var pass = frameState.passes; + if (pass.render) { + var context = frameState.context; + + if (this._material !== this.material || !defined(this._overlayCommand)) { + // Recompile shader when material changes + this._material = this.material; + + if (defined(this._overlayCommand)) { + this._overlayCommand.shaderProgram.destroy(); + } + + var fs = new ShaderSource({ + sources : [this._material.shaderSource, ViewportQuadFS] + }); + this._overlayCommand = context.createViewportQuadCommand(fs, { + renderState : this._rs, + uniformMap : this._material._uniforms, + owner : this + }); + this._overlayCommand.pass = Pass.OVERLAY; + } + + this._material.update(context); + + this._overlayCommand.uniformMap = this._material._uniforms; + frameState.commandList.push(this._overlayCommand); + } + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + * <br /><br /> + * If this object was destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} True if this object was destroyed; otherwise, false. + * + * @see ViewportQuad#destroy + */ + ViewportQuad.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + * <br /><br /> + * Once an object is destroyed, it should not be used; calling any function other than + * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (<code>undefined</code>) to the object as done in the example. + * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * + * @example + * quad = quad && quad.destroy(); + * + * @see ViewportQuad#isDestroyed + */ + ViewportQuad.prototype.destroy = function() { + if (defined(this._overlayCommand)) { + this._overlayCommand.shaderProgram = this._overlayCommand.shaderProgram && this._overlayCommand.shaderProgram.destroy(); + } + return destroyObject(this); + }; + + return ViewportQuad; }); /** @@ -224026,6 +235091,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ colorBlendMode(value); if (defined(that._tileset)) { that._tileset.colorBlendMode = value; + that._scene.requestRender(); } } }); @@ -224075,6 +235141,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ } else { that._tileset.debugPickedTile = undefined; } + that._scene.requestRender(); }, ScreenSpaceEventType.MOUSE_MOVE); } else { that.feature = undefined; @@ -224100,6 +235167,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ colorize(value); if (defined(that._tileset)) { that._tileset.debugColorizeTiles = value; + that._scene.requestRender(); } } }); @@ -224120,6 +235188,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ wireframe(value); if (defined(that._tileset)) { that._tileset.debugWireframe = value; + that._scene.requestRender(); } } }); @@ -224140,6 +235209,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showBoundingVolumes(value); if (defined(that._tileset)) { that._tileset.debugShowBoundingVolume = value; + that._scene.requestRender(); } } }); @@ -224160,6 +235230,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showContentBoundingVolumes(value); if (defined(that._tileset)) { that._tileset.debugShowContentBoundingVolume = value; + that._scene.requestRender(); } } }); @@ -224180,6 +235251,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showRequestVolumes(value); if (defined(that._tileset)) { that._tileset.debugShowViewerRequestVolume = value; + that._scene.requestRender(); } } }); @@ -224201,6 +235273,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ if (defined(that._tileset)) { that._tileset.debugFreezeFrame = value; that._scene.debugShowFrustumPlanes = value; + that._scene.requestRender(); } } }); @@ -224221,6 +235294,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showOnlyPickedTileDebugLabel(value); if (defined(that._tileset)) { that._tileset.debugPickedTileLabelOnly = value; + that._scene.requestRender(); } } }); @@ -224241,6 +235315,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showGeometricError(value); if (defined(that._tileset)) { that._tileset.debugShowGeometricError = value; + that._scene.requestRender(); } } }); @@ -224261,6 +235336,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showRenderingStatistics(value); if (defined(that._tileset)) { that._tileset.debugShowRenderingStatistics = value; + that._scene.requestRender(); } } }); @@ -224281,6 +235357,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showMemoryUsage(value); if (defined(that._tileset)) { that._tileset.debugShowMemoryUsage = value; + that._scene.requestRender(); } } }); @@ -224301,6 +235378,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ showUrl(value); if (defined(that._tileset)) { that._tileset.debugShowUrl = value; + that._scene.requestRender(); } } }); @@ -224414,6 +235492,162 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ } } }); + + var pointCloudShading = knockout.observable(); + knockout.defineProperty(this, 'pointCloudShading', { + get : function() { + return pointCloudShading(); + }, + set : function(value) { + pointCloudShading(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.attenuation = value; + } + } + }); + /** + * Gets or sets the flag to enable point cloud shading. This property is observable. + * + * @type {Boolean} + * @default false + */ + this.pointCloudShading = false; + + var geometricErrorScale = knockout.observable(); + knockout.defineProperty(this, 'geometricErrorScale', { + get : function() { + return geometricErrorScale(); + }, + set : function(value) { + value = Number(value); + if (!isNaN(value)) { + geometricErrorScale(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.geometricErrorScale = value; + } + } + } + }); + /** + * Gets or sets the geometric error scale. This property is observable. + * + * @type {Number} + * @default 1.0 + */ + this.geometricErrorScale = 1.0; + + var maximumAttenuation = knockout.observable(); + knockout.defineProperty(this, 'maximumAttenuation', { + get : function() { + return maximumAttenuation(); + }, + set : function(value) { + value = Number(value); + if (!isNaN(value)) { + maximumAttenuation(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.maximumAttenuation = value === 0 ? undefined : value; + } + } + } + }); + /** + * Gets or sets the maximum attenuation. This property is observable. + * + * @type {Number} + * @default 0 + */ + this.maximumAttenuation = 0; + + var baseResolution = knockout.observable(); + knockout.defineProperty(this, 'baseResolution', { + get : function() { + return baseResolution(); + }, + set : function(value) { + value = Number(value); + if (!isNaN(value)) { + baseResolution(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.baseResolution = value === 0 ? undefined : value; + } + } + } + }); + /** + * Gets or sets the base resolution. This property is observable. + * + * @type {Number} + * @default 0 + */ + this.baseResolution = 0; + + var eyeDomeLighting = knockout.observable(); + knockout.defineProperty(this, 'eyeDomeLighting', { + get : function() { + return eyeDomeLighting(); + }, + set : function(value) { + eyeDomeLighting(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.eyeDomeLighting = value; + } + } + }); + /** + * Gets or sets the flag to enable eye dome lighting. This property is observable. + * + * @type {Boolean} + * @default false + */ + this.eyeDomeLighting = false; + + var eyeDomeLightingStrength = knockout.observable(); + knockout.defineProperty(this, 'eyeDomeLightingStrength', { + get : function() { + return eyeDomeLightingStrength(); + }, + set : function(value) { + value = Number(value); + if (!isNaN(value)) { + eyeDomeLightingStrength(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.eyeDomeLightingStrength = value; + } + } + } + }); + /** + * Gets or sets the eye dome lighting strength. This property is observable. + * + * @type {Number} + * @default 1.0 + */ + this.eyeDomeLightingStrength = 1.0; + + var eyeDomeLightingRadius = knockout.observable(); + knockout.defineProperty(this, 'eyeDomeLightingRadius', { + get : function() { + return eyeDomeLightingRadius(); + }, + set : function(value) { + value = Number(value); + if (!isNaN(value)) { + eyeDomeLightingRadius(value); + if (defined(that._tileset)) { + that._tileset.pointCloudShading.eyeDomeLightingRadius = value; + } + } + } + }); + /** + * Gets or sets the eye dome lighting radius. This property is observable. + * + * @type {Number} + * @default 1.0 + */ + this.eyeDomeLightingRadius = 1.0; + /** * Gets or sets the pick state * @@ -224553,7 +235787,8 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ this._definedProperties = ['properties', 'dynamicScreenSpaceError', 'colorBlendMode', 'picking', 'colorize', 'wireframe', 'showBoundingVolumes', 'showContentBoundingVolumes', 'showRequestVolumes', 'freezeFrame', 'maximumScreenSpaceError', 'dynamicScreenSpaceErrorDensity', 'baseScreenSpaceError', 'skipScreenSpaceErrorFactor', 'skipLevelOfDetail', 'skipLevels', 'immediatelyLoadDesiredLevelOfDetail', 'loadSiblings', 'dynamicScreenSpaceErrorDensitySliderValue', - 'dynamicScreenSpaceErrorFactor', 'pickActive', 'showOnlyPickedTileDebugLabel', 'showGeometricError', 'showRenderingStatistics', 'showMemoryUsage', 'showUrl']; + 'dynamicScreenSpaceErrorFactor', 'pickActive', 'showOnlyPickedTileDebugLabel', 'showGeometricError', 'showRenderingStatistics', 'showMemoryUsage', 'showUrl', + 'pointCloudShading', 'geometricErrorScale', 'maximumAttenuation', 'baseResolution', 'eyeDomeLighting', 'eyeDomeLightingStrength', 'eyeDomeLightingRadius']; this._removePostRenderEvent = scene.postRender.addEventListener(function() { that._update(); }); @@ -224688,6 +235923,17 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ this.skipLevels = tileset.skipLevels; this.immediatelyLoadDesiredLevelOfDetail = tileset.immediatelyLoadDesiredLevelOfDetail; this.loadSiblings = tileset.loadSiblings; + + var pointCloudShading = tileset.pointCloudShading; + this.pointCloudShading = pointCloudShading.attenuation; + this.geometricErrorScale = pointCloudShading.geometricErrorScale; + this.maximumAttenuation = pointCloudShading.maximumAttenuation ? pointCloudShading.maximumAttenuation: 0.0; + this.baseResolution = pointCloudShading.baseResolution ? pointCloudShading.baseResolution : 0.0; + this.eyeDomeLighting = pointCloudShading.eyeDomeLighting; + this.eyeDomeLightingStrength = pointCloudShading.eyeDomeLightingStrength; + this.eyeDomeLightingRadius = pointCloudShading.eyeDomeLightingRadius; + + this._scene.requestRender(); } else { this._properties({}); } @@ -224720,11 +235966,13 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ } else { currentFeature.color = oldColor; } + this._scene.requestRender(); } if (defined(feature)) { // Highlight new feature Color.clone(feature.color, oldColor); feature.color = highlightColor; + this._scene.requestRender(); } this._feature = feature; } @@ -224748,12 +235996,14 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ if (defined(currentTile) && !currentTile.isDestroyed() && !hasFeatures(currentTile.content)) { // Restore original color to tile that is no longer selected currentTile.color = oldColor; + this._scene.requestRender(); } if (defined(tile) && !hasFeatures(tile.content)) { // Highlight new tile Color.clone(tile.color, oldColor); tile.color = highlightColor; + this._scene.requestRender(); } this._tile = tile; } @@ -224864,6 +236114,7 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel',[ } this._style = new Cesium3DTileStyle(JSON.parse(this.styleString)); this._shouldStyle = true; + this._scene.requestRender(); } catch (err) { this._editorError = err.toString(); } @@ -225069,6 +236320,21 @@ define('Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector',[ displayPanelContents.appendChild(makeCheckbox('showContentBoundingVolumes', 'Content Volumes')); displayPanelContents.appendChild(makeCheckbox('showRequestVolumes', 'Request Volumes')); + displayPanelContents.appendChild(makeCheckbox('pointCloudShading', 'Point Cloud Shading')); + var pointCloudShadingContainer = document.createElement('div'); + pointCloudShadingContainer.setAttribute('data-bind', 'css: {"cesium-cesiumInspector-show" : pointCloudShading, "cesium-cesiumInspector-hide" : !pointCloudShading}'); + pointCloudShadingContainer.appendChild(makeRangeInput('geometricErrorScale', 0, 2, 0.01, 'Geometric Error Scale')); + pointCloudShadingContainer.appendChild(makeRangeInput('maximumAttenuation', 0, 32, 1, 'Maximum Attenuation')); + pointCloudShadingContainer.appendChild(makeRangeInput('baseResolution', 0, 1, 0.01, 'Base Resolution')); + pointCloudShadingContainer.appendChild(makeCheckbox('eyeDomeLighting', 'Eye Dome Lighting (EDL)')); + displayPanelContents.appendChild(pointCloudShadingContainer); + + var edlContainer = document.createElement('div'); + edlContainer.setAttribute('data-bind', 'css: {"cesium-cesiumInspector-show" : eyeDomeLighting, "cesium-cesiumInspector-hide" : !eyeDomeLighting}'); + edlContainer.appendChild(makeRangeInput('eyeDomeLightingStrength', 0, 2.0, 0.1, 'EDL Strength')); + edlContainer.appendChild(makeRangeInput('eyeDomeLightingRadius', 0, 4.0, 0.1, 'EDL Radius')); + pointCloudShadingContainer.appendChild(edlContainer); + updatePanelContents.appendChild(makeCheckbox('freezeFrame', 'Freeze Frame')); updatePanelContents.appendChild(makeCheckbox('dynamicScreenSpaceError', 'Dynamic Screen Space Error')); var sseContainer = document.createElement('div'); @@ -225626,10 +236892,12 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ this._frustumsSubscription = knockout.getObservable(this, 'frustums').subscribe(function(val) { that._scene.debugShowFrustums = val; + that._scene.requestRender(); }); this._frustumPlanesSubscription = knockout.getObservable(this, 'frustumPlanes').subscribe(function(val) { that._scene.debugShowFrustumPlanes = val; + that._scene.requestRender(); }); this._performanceSubscription = knockout.getObservable(this, 'performance').subscribe(function(val) { @@ -225644,6 +236912,7 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ this._showPrimitiveBoundingSphere = createCommand(function() { that._primitive.debugShowBoundingVolume = that.primitiveBoundingSphere; + that._scene.requestRender(); return true; }); @@ -225662,6 +236931,7 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ that._scene.primitives.remove(that._modelMatrixPrimitive); that._modelMatrixPrimitive = undefined; } + that._scene.requestRender(); return true; }); @@ -225687,33 +236957,40 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ this._filterPrimitiveSubscription = knockout.getObservable(this, 'filterPrimitive').subscribe(function() { that._doFilterPrimitive(); + that._scene.requestRender(); }); this._wireframeSubscription = knockout.getObservable(this, 'wireframe').subscribe(function(val) { globe._surface.tileProvider._debug.wireframe = val; + that._scene.requestRender(); }); this._globeDepthSubscription = knockout.getObservable(this, 'globeDepth').subscribe(function(val) { that._scene.debugShowGlobeDepth = val; + that._scene.requestRender(); }); this._pickDepthSubscription = knockout.getObservable(this, 'pickDepth').subscribe(function(val) { that._scene.debugShowPickDepth = val; + that._scene.requestRender(); }); this._depthFrustumSubscription = knockout.getObservable(this, 'depthFrustum').subscribe(function(val) { - that.scene.debugShowDepthFrustum = val; + that._scene.debugShowDepthFrustum = val; + that._scene.requestRender(); }); this._incrementDepthFrustum = createCommand(function() { var next = that.depthFrustum + 1; that.depthFrustum = boundDepthFrustum(1, that._numberOfFrustums, next); + that._scene.requestRender(); return true; }); this._decrementDepthFrustum = createCommand(function() { var next = that.depthFrustum - 1; that.depthFrustum = boundDepthFrustum(1, that._numberOfFrustums, next); + that._scene.requestRender(); return true; }); @@ -225739,10 +237016,12 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ this._tileCoordinatesSubscription = knockout.getObservable(this, 'tileCoordinates').subscribe(function() { that._showTileCoordinates(); + that._scene.requestRender(); }); this._tileBoundingSphereSubscription = knockout.getObservable(this, 'tileBoundingSphere').subscribe(function() { that._showTileBoundingSphere(); + that._scene.requestRender(); }); this._showTileBoundingSphere = createCommand(function() { @@ -225751,6 +237030,7 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ } else { globe._surface.tileProvider._debug.boundingSphereTile = undefined; } + that._scene.requestRender(); return true; }); @@ -225771,6 +237051,7 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ this._filterTileSubscription = knockout.getObservable(this, 'filterTile').subscribe(function() { that.doFilterTile(); + that._scene.requestRender(); }); function pickPrimitive(e) { @@ -225782,6 +237063,7 @@ define('Widgets/CesiumInspector/CesiumInspectorViewModel',[ that.primitive = defined(newPick.collection) ? newPick.collection : newPick.primitive; } + that._scene.requestRender(); that.pickPrimitiveActive = false; } @@ -226276,7 +237558,7 @@ define('Widgets/CesiumInspector/CesiumInspector',[ * @param {Element|String} container The DOM element or ID that will contain the widget. * @param {Scene} scene The Scene instance to use. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Cesium%20Inspector.html|Cesium Sandcastle Cesium Inspector Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Cesium%20Inspector.html|Cesium Sandcastle Cesium Inspector Demo} */ function CesiumInspector(container, scene) { if (!defined(container)) { @@ -226808,10 +238090,12 @@ define('Widgets/CesiumWidget/CesiumWidget',[ * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. * @param {ShadowMode} [options.terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from the sun. * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Cesium%20Widget.html|Cesium Sandcastle Cesium Widget Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Cesium%20Widget.html|Cesium Sandcastle Cesium Widget Demo} * * @example * // For each example, include a link to CesiumWidget.css stylesheet in HTML head, @@ -226909,7 +238193,9 @@ define('Widgets/CesiumWidget/CesiumWidget',[ scene3DOnly : defaultValue(options.scene3DOnly, false), terrainExaggeration : options.terrainExaggeration, shadows : options.shadows, - mapMode2D : options.mapMode2D + mapMode2D : options.mapMode2D, + requestRenderMode : options.requestRenderMode, + maximumRenderTimeChange : options.maximumRenderTimeChange }); this._scene = scene; @@ -226923,7 +238209,7 @@ define('Widgets/CesiumWidget/CesiumWidget',[ var cesiumCredit = new Credit({ text: 'Cesium', imageUrl: cesiumLogoData, - link: 'http://cesiumjs.org/', + link: 'https://cesiumjs.org/', showOnScreen: true }); creditDisplay.addDefaultCredit(cesiumCredit); @@ -227330,6 +238616,8 @@ define('Widgets/CesiumWidget/CesiumWidget',[ configureCanvasSize(this); configureCameraFrustum(this); + + this._scene.requestRender(); }; /** @@ -232000,6 +243288,7 @@ cesiumSvgPath: { path: isVRMode ? _exitVRPath : _enterVRPath, width: 32, height: define('Widgets/Viewer/Viewer',[ '../../Core/BoundingSphere', '../../Core/Cartesian3', + '../../Core/Check', '../../Core/Clock', '../../Core/defaultValue', '../../Core/defined', @@ -232008,6 +243297,7 @@ define('Widgets/Viewer/Viewer',[ '../../Core/DeveloperError', '../../Core/Event', '../../Core/EventHelper', + '../../Core/HeadingPitchRange', '../../Core/isArray', '../../Core/Matrix4', '../../Core/Rectangle', @@ -232019,6 +243309,7 @@ define('Widgets/Viewer/Viewer',[ '../../DataSources/Entity', '../../DataSources/EntityView', '../../DataSources/Property', + '../../Scene/Cesium3DTileset', '../../Scene/ImageryLayer', '../../Scene/SceneMode', '../../ThirdParty/knockout', @@ -232045,6 +243336,7 @@ define('Widgets/Viewer/Viewer',[ ], function( BoundingSphere, Cartesian3, + Check, Clock, defaultValue, defined, @@ -232053,6 +243345,7 @@ define('Widgets/Viewer/Viewer',[ DeveloperError, Event, EventHelper, + HeadingPitchRange, isArray, Matrix4, Rectangle, @@ -232064,6 +243357,7 @@ define('Widgets/Viewer/Viewer',[ Entity, EntityView, Property, + Cesium3DTileset, ImageryLayer, SceneMode, knockout, @@ -232204,13 +243498,13 @@ define('Widgets/Viewer/Viewer',[ if (defined(homeButton)) { homeButton.container.style.visibility = visibility; } - if(defined(sceneModePicker)) { + if (defined(sceneModePicker)) { sceneModePicker.container.style.visibility = visibility; } if (defined(projectionPicker)) { projectionPicker.container.style.visibility = visibility; } - if(defined(baseLayerPicker)) { + if (defined(baseLayerPicker)) { baseLayerPicker.container.style.visibility = visibility; } if (defined(animation)) { @@ -232259,6 +243553,7 @@ define('Widgets/Viewer/Viewer',[ * @param {Boolean} [options.navigationHelpButton=true] If set to false, the navigation help button will not be created. * @param {Boolean} [options.navigationInstructionsInitiallyVisible=true] True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button. * @param {Boolean} [options.scene3DOnly=false] When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory. + * @param {Boolean} [options.shouldAnimate=false] <code>true</code> if the clock should attempt to advance simulation time by default, <code>false</code> otherwise. This option takes precedence over setting {@link Viewer#clockViewModel}. * @param {ClockViewModel} [options.clockViewModel=new ClockViewModel(options.clock)] The clock view model to use to control current time. * @param {ProviderViewModel} [options.selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available base layer is used. This value is only valid if options.baseLayerPicker is set to true. * @param {ProviderViewModel[]} [options.imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if options.baseLayerPicker is set to true. @@ -232287,6 +243582,8 @@ define('Widgets/Viewer/Viewer',[ * @param {ShadowMode} [options.terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from the sun. * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. * @param {Boolean} [options.projectionPicker=false] If set to true, the ProjectionPicker widget will be created. + * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @exception {DeveloperError} options.imageryProvider is not available when using the BaseLayerPicker widget, specify options.selectedImageryProviderViewModel instead. @@ -232303,7 +243600,7 @@ define('Widgets/Viewer/Viewer',[ * @see Timeline * @see viewerDragDropMixin * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Hello%20World.html|Cesium Sandcastle Hello World Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Hello%20World.html|Cesium Sandcastle Hello World Demo} * * @example * //Initialize the viewer widget with several custom options and mixins. @@ -232353,7 +243650,7 @@ define('Widgets/Viewer/Viewer',[ options = defaultValue(options, defaultValue.EMPTY_OBJECT); var createBaseLayerPicker = (!defined(options.globe) || options.globe !== false) && - (!defined(options.baseLayerPicker) || options.baseLayerPicker !== false); + (!defined(options.baseLayerPicker) || options.baseLayerPicker !== false); // If using BaseLayerPicker, imageryProvider is an invalid option if (createBaseLayerPicker && defined(options.imageryProvider)) { @@ -232410,6 +243707,10 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to destroyClockViewModel = true; } + if (defined(options.shouldAnimate)) { + clock.shouldAnimate = options.shouldAnimate; + } + // Cesium widget var cesiumWidget = new CesiumWidget(cesiumWidgetContainer, { terrainProvider : options.terrainProvider, @@ -232426,12 +243727,14 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to targetFrameRate : options.targetFrameRate, showRenderLoopErrors : options.showRenderLoopErrors, creditContainer : defined(options.creditContainer) ? options.creditContainer : bottomContainer, - creditViewport: options.creditViewport, + creditViewport : options.creditViewport, scene3DOnly : scene3DOnly, terrainExaggeration : options.terrainExaggeration, shadows : options.shadows, terrainShadows : options.terrainShadows, - mapMode2D : options.mapMode2D + mapMode2D : options.mapMode2D, + requestRenderMode : options.requestRenderMode, + maximumRenderTimeChange : options.maximumRenderTimeChange }); var dataSourceCollection = options.dataSources; @@ -232486,7 +243789,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to toolbar.appendChild(geocoderContainer); geocoder = new Geocoder({ container : geocoderContainer, - geocoderServices: defined(options.geocoder) ? (isArray(options.geocoder) ? options.geocoder : [options.geocoder]) : undefined, + geocoderServices : defined(options.geocoder) ? (isArray(options.geocoder) ? options.geocoder : [options.geocoder]) : undefined, scene : cesiumWidget.scene }); // Subscribe to search so that we can clear the trackedEntity when it is clicked. @@ -232694,7 +243997,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to eventHelper.add(dataSourceCollection.dataSourceRemoved, Viewer.prototype._onDataSourceRemoved, this); // Prior to each render, check if anything needs to be resized. - eventHelper.add(cesiumWidget.scene.preRender, Viewer.prototype.resize, this); + eventHelper.add(cesiumWidget.scene.postUpdate, Viewer.prototype.resize, this); eventHelper.add(cesiumWidget.scene.postRender, Viewer.prototype._postRender, this); // We need to subscribe to the data sources and collections so that we can clear the @@ -233224,6 +244527,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to } this._trackedEntityChanged.raiseEvent(value); + this.scene.requestRender(); } } }, @@ -233716,12 +245020,15 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to * target will be the range. The heading will be determined from the offset. If the heading cannot be * determined from the offset, the heading will be north.</p> * - * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer>} target The entity, array of entities, entity collection, data source or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. + * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset>} target The entity, array of entities, entity collection, data source, Cesium#DTileset, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. * @param {HeadingPitchRange} [offset] The offset from the center of the entity in the local east-north-up reference frame. - * @returns {Promise.<Boolean>} A Promise that resolves to true if the zoom was successful or false if the entity is not currently visualized in the scene or the zoom was cancelled. + * @returns {Promise.<Boolean>} A Promise that resolves to true if the zoom was successful or false if the target is not currently visualized in the scene or the zoom was cancelled. */ Viewer.prototype.zoomTo = function(target, offset) { - return zoomToOrFly(this, target, offset, false); + var options = { + offset : offset + }; + return zoomToOrFly(this, target, options, false); }; /** @@ -233739,12 +245046,12 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to * target will be the range. The heading will be determined from the offset. If the heading cannot be * determined from the offset, the heading will be north.</p> * - * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer>} target The entity, array of entities, entity collection, data source or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. + * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. * @param {Object} [options] Object with the following properties: * @param {Number} [options.duration=3.0] The duration of the flight in seconds. * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. * @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target. - * @returns {Promise.<Boolean>} A Promise that resolves to true if the flight was successful or false if the entity is not currently visualized in the scene or the flight was cancelled. + * @returns {Promise.<Boolean>} A Promise that resolves to true if the flight was successful or false if the target is not currently visualized in the scene or the flight was cancelled. //TODO: Cleanup entity mentions */ Viewer.prototype.flyTo = function(target, options) { return zoomToOrFly(this, target, options, true); @@ -233783,6 +245090,12 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to return; } + //If the zoom target is a Cesium3DTileset + if (zoomTarget instanceof Cesium3DTileset) { + that._zoomTarget = zoomTarget; + return; + } + //If the zoom target is a data source, and it's in the middle of loading, wait for it to finish loading. if (zoomTarget.isLoading && defined(zoomTarget.loadingEvent)) { var removeEvent = zoomTarget.loadingEvent.addEventListener(function() { @@ -233810,6 +245123,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to zoomTarget = zoomTarget.entities.values; } + //Zoom target is already an array, just copy it and return. if (isArray(zoomTarget)) { that._zoomTarget = zoomTarget.slice(0); } else { @@ -233818,6 +245132,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to } }); + that.scene.requestRender(); return zoomPromise.promise; } @@ -233844,8 +245159,8 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to }; function updateZoomTarget(viewer) { - var entities = viewer._zoomTarget; - if (!defined(entities) || viewer.scene.mode === SceneMode.MORPHING) { + var target = viewer._zoomTarget; + if (!defined(target) || viewer.scene.mode === SceneMode.MORPHING) { return; } @@ -233853,11 +245168,47 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to var camera = scene.camera; var zoomPromise = viewer._zoomPromise; var zoomOptions = defaultValue(viewer._zoomOptions, {}); + var options; + + // If zoomTarget was Cesium3DTileset + if (target instanceof Cesium3DTileset) { + return target.readyPromise.then(function() { + var boundingSphere = target.boundingSphere; + // if offset was originally undefined then give it base value instead of empty object + if (!defined(zoomOptions.offset)) { + zoomOptions.offset = new HeadingPitchRange(0.0, -0.5, boundingSphere.radius); + } + + options = { + offset : zoomOptions.offset, + duration : zoomOptions.duration, + maximumHeight : zoomOptions.maximumHeight, + complete : function() { + zoomPromise.resolve(true); + }, + cancel : function() { + zoomPromise.resolve(false); + } + }; + + if (viewer._zoomIsFlight) { + camera.flyToBoundingSphere(target.boundingSphere, options); + } else { + camera.viewBoundingSphere(boundingSphere, zoomOptions.offset); + camera.lookAtTransform(Matrix4.IDENTITY); + + // finish the promise + zoomPromise.resolve(true); + } + + clearZoom(viewer); + }); + } //If zoomTarget was an ImageryLayer - if (entities instanceof Rectangle) { - var options = { - destination : entities, + if (target instanceof Rectangle) { + options = { + destination : target, duration : zoomOptions.duration, maximumHeight : zoomOptions.maximumHeight, complete : function() { @@ -233878,6 +245229,8 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to return; } + var entities = target; + var boundingSpheres = []; for (var i = 0, len = entities.length; i < len; i++) { var state = viewer._dataSourceDisplay.getBoundingSphere(entities[i], false, boundingSphereScratch); @@ -233900,7 +245253,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to var boundingSphere = BoundingSphere.fromBoundingSpheres(boundingSpheres); if (!viewer._zoomIsFlight) { - camera.viewBoundingSphere(boundingSphere, viewer._zoomOptions); + camera.viewBoundingSphere(boundingSphere, viewer._zoomOptions.offset); camera.lookAtTransform(Matrix4.IDENTITY); clearZoom(viewer); zoomPromise.resolve(true); @@ -234035,7 +245388,7 @@ define('Widgets/Viewer/viewerCesiumInspectorMixin',[ * * @exception {DeveloperError} viewer is required. * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Cesium%20Inspector.html|Cesium Sandcastle Cesium Inspector Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Cesium%20Inspector.html|Cesium Sandcastle Cesium Inspector Demo} * * @example * var viewer = new Cesium.Viewer('cesiumContainer'); @@ -234545,15 +245898,16 @@ define('Workers/createTaskProcessorWorker',[ return createTaskProcessorWorker; }); -define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayRemoveDuplicates', './Core/AssociativeArray', './Core/AttributeCompression', './Core/AxisAlignedBoundingBox', './Core/barycentricCoordinates', './Core/binarySearch', './Core/BingMapsApi', './Core/BingMapsGeocoderService', './Core/BoundingRectangle', './Core/BoundingSphere', './Core/BoxGeometry', './Core/BoxOutlineGeometry', './Core/buildModuleUrl', './Core/cancelAnimationFrame', './Core/Cartesian2', './Core/Cartesian3', './Core/Cartesian4', './Core/Cartographic', './Core/CartographicGeocoderService', './Core/CatmullRomSpline', './Core/CesiumTerrainProvider', './Core/Check', './Core/CircleGeometry', './Core/CircleOutlineGeometry', './Core/ClippingPlaneCollection', './Core/Clock', './Core/ClockRange', './Core/ClockStep', './Core/clone', './Core/Color', './Core/ColorGeometryInstanceAttribute', './Core/combine', './Core/ComponentDatatype', './Core/CompressedTextureBuffer', './Core/CornerType', './Core/CorridorGeometry', './Core/CorridorGeometryLibrary', './Core/CorridorOutlineGeometry', './Core/createGuid', './Core/Credit', './Core/CubicRealPolynomial', './Core/CullingVolume', './Core/CylinderGeometry', './Core/CylinderGeometryLibrary', './Core/CylinderOutlineGeometry', './Core/decodeGoogleEarthEnterpriseData', './Core/DefaultProxy', './Core/defaultValue', './Core/defined', './Core/defineProperties', './Core/deprecationWarning', './Core/destroyObject', './Core/DeveloperError', './Core/DistanceDisplayCondition', './Core/DistanceDisplayConditionGeometryInstanceAttribute', './Core/DoublyLinkedList', './Core/EarthOrientationParameters', './Core/EarthOrientationParametersSample', './Core/EasingFunction', './Core/EllipseGeometry', './Core/EllipseGeometryLibrary', './Core/EllipseOutlineGeometry', './Core/Ellipsoid', './Core/EllipsoidalOccluder', './Core/EllipsoidGeodesic', './Core/EllipsoidGeometry', './Core/EllipsoidOutlineGeometry', './Core/EllipsoidTangentPlane', './Core/EllipsoidTerrainProvider', './Core/EncodedCartesian3', './Core/Event', './Core/EventHelper', './Core/ExtrapolationType', './Core/FeatureDetection', './Core/formatError', './Core/freezeObject', './Core/FrustumGeometry', './Core/FrustumOutlineGeometry', './Core/Fullscreen', './Core/GeocoderService', './Core/GeographicProjection', './Core/GeographicTilingScheme', './Core/Geometry', './Core/GeometryAttribute', './Core/GeometryAttributes', './Core/GeometryInstance', './Core/GeometryInstanceAttribute', './Core/GeometryPipeline', './Core/GeometryType', './Core/getAbsoluteUri', './Core/getBaseUri', './Core/getExtensionFromUri', './Core/getFilenameFromUri', './Core/getImagePixels', './Core/getMagic', './Core/getStringFromTypedArray', './Core/getTimestamp', './Core/GoogleEarthEnterpriseMetadata', './Core/GoogleEarthEnterpriseTerrainData', './Core/GoogleEarthEnterpriseTerrainProvider', './Core/GoogleEarthEnterpriseTileInformation', './Core/GregorianDate', './Core/HeadingPitchRange', './Core/HeadingPitchRoll', './Core/Heap', './Core/HeightmapTerrainData', './Core/HeightmapTessellator', './Core/HermitePolynomialApproximation', './Core/HermiteSpline', './Core/Iau2000Orientation', './Core/Iau2006XysData', './Core/Iau2006XysSample', './Core/IauOrientationAxes', './Core/IauOrientationParameters', './Core/IndexDatatype', './Core/InterpolationAlgorithm', './Core/Intersect', './Core/Intersections2D', './Core/IntersectionTests', './Core/Interval', './Core/isArray', './Core/isBitSet', './Core/isBlobUri', './Core/isCrossOriginUrl', './Core/isDataUri', './Core/isLeapYear', './Core/Iso8601', './Core/joinUrls', './Core/JulianDate', './Core/KeyboardEventModifier', './Core/LagrangePolynomialApproximation', './Core/LeapSecond', './Core/LinearApproximation', './Core/LinearSpline', './Core/loadArrayBuffer', './Core/loadBlob', './Core/loadCRN', './Core/loadImage', './Core/loadImageFromTypedArray', './Core/loadImageViaBlob', './Core/loadJson', './Core/loadJsonp', './Core/loadKTX', './Core/loadText', './Core/loadWithXhr', './Core/loadXML', './Core/ManagedArray', './Core/MapboxApi', './Core/MapProjection', './Core/Math', './Core/Matrix2', './Core/Matrix3', './Core/Matrix4', './Core/mergeSort', './Core/NearFarScalar', './Core/objectToQuery', './Core/Occluder', './Core/oneTimeWarning', './Core/OrientedBoundingBox', './Core/OrthographicFrustum', './Core/OrthographicOffCenterFrustum', './Core/Packable', './Core/PackableForInterpolation', './Core/parseResponseHeaders', './Core/PerspectiveFrustum', './Core/PerspectiveOffCenterFrustum', './Core/PinBuilder', './Core/PixelFormat', './Core/Plane', './Core/PlaneGeometry', './Core/PlaneOutlineGeometry', './Core/pointInsideTriangle', './Core/PolygonGeometry', './Core/PolygonGeometryLibrary', './Core/PolygonHierarchy', './Core/PolygonOutlineGeometry', './Core/PolygonPipeline', './Core/PolylineGeometry', './Core/PolylinePipeline', './Core/PolylineVolumeGeometry', './Core/PolylineVolumeGeometryLibrary', './Core/PolylineVolumeOutlineGeometry', './Core/PrimitiveType', './Core/QuadraticRealPolynomial', './Core/QuantizedMeshTerrainData', './Core/QuarticRealPolynomial', './Core/Quaternion', './Core/QuaternionSpline', './Core/queryToObject', './Core/Queue', './Core/Ray', './Core/Rectangle', './Core/RectangleGeometry', './Core/RectangleGeometryLibrary', './Core/RectangleOutlineGeometry', './Core/ReferenceFrame', './Core/Request', './Core/requestAnimationFrame', './Core/RequestErrorEvent', './Core/RequestScheduler', './Core/RequestState', './Core/RequestType', './Core/RuntimeError', './Core/sampleTerrain', './Core/sampleTerrainMostDetailed', './Core/scaleToGeodeticSurface', './Core/ScreenSpaceEventHandler', './Core/ScreenSpaceEventType', './Core/ShowGeometryInstanceAttribute', './Core/Simon1994PlanetaryPositions', './Core/SimplePolylineGeometry', './Core/SphereGeometry', './Core/SphereOutlineGeometry', './Core/Spherical', './Core/Spline', './Core/subdivideArray', './Core/TaskProcessor', './Core/TerrainData', './Core/TerrainEncoding', './Core/TerrainMesh', './Core/TerrainProvider', './Core/TerrainQuantization', './Core/TileAvailability', './Core/TileProviderError', './Core/TilingScheme', './Core/TimeConstants', './Core/TimeInterval', './Core/TimeIntervalCollection', './Core/TimeStandard', './Core/Tipsify', './Core/Transforms', './Core/TranslationRotationScale', './Core/TridiagonalSystemSolver', './Core/TrustedServers', './Core/VertexFormat', './Core/VideoSynchronizer', './Core/Visibility', './Core/VRTheWorldTerrainProvider', './Core/WallGeometry', './Core/WallGeometryLibrary', './Core/WallOutlineGeometry', './Core/WebGLConstants', './Core/WebMercatorProjection', './Core/WebMercatorTilingScheme', './Core/WeightSpline', './Core/WindingOrder', './Core/wrapFunction', './Core/writeTextToCanvas', './DataSources/BillboardGraphics', './DataSources/BillboardVisualizer', './DataSources/BoundingSphereState', './DataSources/BoxGeometryUpdater', './DataSources/BoxGraphics', './DataSources/CallbackProperty', './DataSources/CheckerboardMaterialProperty', './DataSources/ColorMaterialProperty', './DataSources/CompositeEntityCollection', './DataSources/CompositeMaterialProperty', './DataSources/CompositePositionProperty', './DataSources/CompositeProperty', './DataSources/ConstantPositionProperty', './DataSources/ConstantProperty', './DataSources/CorridorGeometryUpdater', './DataSources/CorridorGraphics', './DataSources/createMaterialPropertyDescriptor', './DataSources/createPropertyDescriptor', './DataSources/createRawPropertyDescriptor', './DataSources/CustomDataSource', './DataSources/CylinderGeometryUpdater', './DataSources/CylinderGraphics', './DataSources/CzmlDataSource', './DataSources/DataSource', './DataSources/DataSourceClock', './DataSources/DataSourceCollection', './DataSources/DataSourceDisplay', './DataSources/dynamicGeometryGetBoundingSphere', './DataSources/DynamicGeometryUpdater', './DataSources/EllipseGeometryUpdater', './DataSources/EllipseGraphics', './DataSources/EllipsoidGeometryUpdater', './DataSources/EllipsoidGraphics', './DataSources/Entity', './DataSources/EntityCluster', './DataSources/EntityCollection', './DataSources/EntityView', './DataSources/GeoJsonDataSource', './DataSources/GeometryUpdater', './DataSources/GeometryVisualizer', './DataSources/GridMaterialProperty', './DataSources/ImageMaterialProperty', './DataSources/KmlCamera', './DataSources/KmlDataSource', './DataSources/KmlLookAt', './DataSources/KmlTour', './DataSources/KmlTourFlyTo', './DataSources/KmlTourWait', './DataSources/LabelGraphics', './DataSources/LabelVisualizer', './DataSources/MaterialProperty', './DataSources/ModelGraphics', './DataSources/ModelVisualizer', './DataSources/NodeTransformationProperty', './DataSources/PathGraphics', './DataSources/PathVisualizer', './DataSources/PlaneGeometryUpdater', './DataSources/PlaneGraphics', './DataSources/PointGraphics', './DataSources/PointVisualizer', './DataSources/PolygonGeometryUpdater', './DataSources/PolygonGraphics', './DataSources/PolylineArrowMaterialProperty', './DataSources/PolylineDashMaterialProperty', './DataSources/PolylineGeometryUpdater', './DataSources/PolylineGlowMaterialProperty', './DataSources/PolylineGraphics', './DataSources/PolylineOutlineMaterialProperty', './DataSources/PolylineVolumeGeometryUpdater', './DataSources/PolylineVolumeGraphics', './DataSources/PositionProperty', './DataSources/PositionPropertyArray', './DataSources/Property', './DataSources/PropertyArray', './DataSources/PropertyBag', './DataSources/RectangleGeometryUpdater', './DataSources/RectangleGraphics', './DataSources/ReferenceProperty', './DataSources/Rotation', './DataSources/SampledPositionProperty', './DataSources/SampledProperty', './DataSources/ScaledPositionProperty', './DataSources/StaticGeometryColorBatch', './DataSources/StaticGeometryPerMaterialBatch', './DataSources/StaticGroundGeometryColorBatch', './DataSources/StaticOutlineGeometryBatch', './DataSources/StripeMaterialProperty', './DataSources/StripeOrientation', './DataSources/TimeIntervalCollectionPositionProperty', './DataSources/TimeIntervalCollectionProperty', './DataSources/VelocityOrientationProperty', './DataSources/VelocityVectorProperty', './DataSources/Visualizer', './DataSources/WallGeometryUpdater', './DataSources/WallGraphics', './Renderer/AutomaticUniforms', './Renderer/Buffer', './Renderer/BufferUsage', './Renderer/ClearCommand', './Renderer/ComputeCommand', './Renderer/ComputeEngine', './Renderer/Context', './Renderer/ContextLimits', './Renderer/createUniform', './Renderer/createUniformArray', './Renderer/CubeMap', './Renderer/CubeMapFace', './Renderer/DrawCommand', './Renderer/Framebuffer', './Renderer/freezeRenderState', './Renderer/loadCubeMap', './Renderer/MipmapHint', './Renderer/modernizeShader', './Renderer/Pass', './Renderer/PassState', './Renderer/PickFramebuffer', './Renderer/PixelDatatype', './Renderer/Renderbuffer', './Renderer/RenderbufferFormat', './Renderer/RenderState', './Renderer/Sampler', './Renderer/ShaderCache', './Renderer/ShaderProgram', './Renderer/ShaderSource', './Renderer/Texture', './Renderer/TextureMagnificationFilter', './Renderer/TextureMinificationFilter', './Renderer/TextureWrap', './Renderer/UniformState', './Renderer/VertexArray', './Renderer/VertexArrayFacade', './Scene/Appearance', './Scene/ArcGisMapServerImageryProvider', './Scene/AttributeType', './Scene/Axis', './Scene/Batched3DModel3DTileContent', './Scene/BatchTable', './Scene/Billboard', './Scene/BillboardCollection', './Scene/BingMapsImageryProvider', './Scene/BingMapsStyle', './Scene/BlendEquation', './Scene/BlendFunction', './Scene/BlendingState', './Scene/BlendOption', './Scene/BoxEmitter', './Scene/BrdfLutGenerator', './Scene/Camera', './Scene/CameraEventAggregator', './Scene/CameraEventType', './Scene/CameraFlightPath', './Scene/Cesium3DTile', './Scene/Cesium3DTileBatchTable', './Scene/Cesium3DTileChildrenVisibility', './Scene/Cesium3DTileColorBlendMode', './Scene/Cesium3DTileContent', './Scene/Cesium3DTileContentFactory', './Scene/Cesium3DTileContentState', './Scene/Cesium3DTileFeature', './Scene/Cesium3DTileFeatureTable', './Scene/Cesium3DTileOptimizationHint', './Scene/Cesium3DTileOptimizations', './Scene/Cesium3DTileRefine', './Scene/Cesium3DTileset', './Scene/Cesium3DTilesetStatistics', './Scene/Cesium3DTilesetTraversal', './Scene/Cesium3DTileStyle', './Scene/Cesium3DTileStyleEngine', './Scene/CircleEmitter', './Scene/ClassificationPrimitive', './Scene/ClassificationType', './Scene/ColorBlendMode', './Scene/Composite3DTileContent', './Scene/ConditionsExpression', './Scene/ConeEmitter', './Scene/createOpenStreetMapImageryProvider', './Scene/createTangentSpaceDebugPrimitive', './Scene/createTileMapServiceImageryProvider', './Scene/CreditDisplay', './Scene/CullFace', './Scene/DebugAppearance', './Scene/DebugCameraPrimitive', './Scene/DebugModelMatrixPrimitive', './Scene/DepthFunction', './Scene/DepthPlane', './Scene/DeviceOrientationCameraController', './Scene/DiscardMissingTileImagePolicy', './Scene/EllipsoidPrimitive', './Scene/EllipsoidSurfaceAppearance', './Scene/Empty3DTileContent', './Scene/Expression', './Scene/ExpressionNodeType', './Scene/Fog', './Scene/FrameRateMonitor', './Scene/FrameState', './Scene/FrustumCommands', './Scene/FXAA', './Scene/getAttributeOrUniformBySemantic', './Scene/getBinaryAccessor', './Scene/GetFeatureInfoFormat', './Scene/Globe', './Scene/GlobeDepth', './Scene/GlobeSurfaceShaderSet', './Scene/GlobeSurfaceTile', './Scene/GlobeSurfaceTileProvider', './Scene/GoogleEarthEnterpriseImageryProvider', './Scene/GoogleEarthEnterpriseMapsProvider', './Scene/GridImageryProvider', './Scene/GroundPrimitive', './Scene/HeightReference', './Scene/HorizontalOrigin', './Scene/Imagery', './Scene/ImageryLayer', './Scene/ImageryLayerCollection', './Scene/ImageryLayerFeatureInfo', './Scene/ImageryProvider', './Scene/ImagerySplitDirection', './Scene/ImageryState', './Scene/Instanced3DModel3DTileContent', './Scene/InvertClassification', './Scene/JobScheduler', './Scene/JobType', './Scene/Label', './Scene/LabelCollection', './Scene/LabelStyle', './Scene/MapboxImageryProvider', './Scene/MapMode2D', './Scene/Material', './Scene/MaterialAppearance', './Scene/Model', './Scene/ModelAnimation', './Scene/ModelAnimationCache', './Scene/ModelAnimationCollection', './Scene/ModelAnimationLoop', './Scene/ModelAnimationState', './Scene/ModelInstance', './Scene/ModelInstanceCollection', './Scene/ModelMaterial', './Scene/ModelMesh', './Scene/ModelNode', './Scene/Moon', './Scene/NeverTileDiscardPolicy', './Scene/OIT', './Scene/Particle', './Scene/ParticleBurst', './Scene/ParticleEmitter', './Scene/ParticleSystem', './Scene/PerformanceDisplay', './Scene/PerInstanceColorAppearance', './Scene/PickDepth', './Scene/PointCloud3DTileContent', './Scene/PointPrimitive', './Scene/PointPrimitiveCollection', './Scene/Polyline', './Scene/PolylineCollection', './Scene/PolylineColorAppearance', './Scene/PolylineMaterialAppearance', './Scene/Primitive', './Scene/PrimitiveCollection', './Scene/PrimitivePipeline', './Scene/PrimitiveState', './Scene/QuadtreeOccluders', './Scene/QuadtreePrimitive', './Scene/QuadtreeTile', './Scene/QuadtreeTileLoadState', './Scene/QuadtreeTileProvider', './Scene/Scene', './Scene/SceneMode', './Scene/SceneTransforms', './Scene/SceneTransitioner', './Scene/ScreenSpaceCameraController', './Scene/ShadowMap', './Scene/ShadowMapShader', './Scene/ShadowMode', './Scene/SingleTileImageryProvider', './Scene/SkyAtmosphere', './Scene/SkyBox', './Scene/SphereEmitter', './Scene/StencilFunction', './Scene/StencilOperation', './Scene/StyleExpression', './Scene/Sun', './Scene/SunPostProcess', './Scene/TerrainState', './Scene/TextureAtlas', './Scene/TileBoundingRegion', './Scene/TileBoundingSphere', './Scene/TileBoundingVolume', './Scene/TileCoordinatesImageryProvider', './Scene/TileDiscardPolicy', './Scene/TileImagery', './Scene/TileOrientedBoundingBox', './Scene/TileReplacementQueue', './Scene/Tileset3DTileContent', './Scene/TileState', './Scene/TileTerrain', './Scene/TimeDynamicImagery', './Scene/TweenCollection', './Scene/UrlTemplateImageryProvider', './Scene/VerticalOrigin', './Scene/ViewportQuad', './Scene/WebMapServiceImageryProvider', './Scene/WebMapTileServiceImageryProvider', './Shaders/AdjustTranslucentFS', './Shaders/Appearances/AllMaterialAppearanceFS', './Shaders/Appearances/AllMaterialAppearanceVS', './Shaders/Appearances/BasicMaterialAppearanceFS', './Shaders/Appearances/BasicMaterialAppearanceVS', './Shaders/Appearances/EllipsoidSurfaceAppearanceFS', './Shaders/Appearances/EllipsoidSurfaceAppearanceVS', './Shaders/Appearances/PerInstanceColorAppearanceFS', './Shaders/Appearances/PerInstanceColorAppearanceVS', './Shaders/Appearances/PerInstanceFlatColorAppearanceFS', './Shaders/Appearances/PerInstanceFlatColorAppearanceVS', './Shaders/Appearances/PolylineColorAppearanceVS', './Shaders/Appearances/PolylineMaterialAppearanceVS', './Shaders/Appearances/TexturedMaterialAppearanceFS', './Shaders/Appearances/TexturedMaterialAppearanceVS', './Shaders/BillboardCollectionFS', './Shaders/BillboardCollectionVS', './Shaders/BrdfLutGeneratorFS', './Shaders/Builtin/Constants/degreesPerRadian', './Shaders/Builtin/Constants/depthRange', './Shaders/Builtin/Constants/epsilon1', './Shaders/Builtin/Constants/epsilon2', './Shaders/Builtin/Constants/epsilon3', './Shaders/Builtin/Constants/epsilon4', './Shaders/Builtin/Constants/epsilon5', './Shaders/Builtin/Constants/epsilon6', './Shaders/Builtin/Constants/epsilon7', './Shaders/Builtin/Constants/infinity', './Shaders/Builtin/Constants/maxClippingPlanes', './Shaders/Builtin/Constants/oneOverPi', './Shaders/Builtin/Constants/oneOverTwoPi', './Shaders/Builtin/Constants/passCesium3DTile', './Shaders/Builtin/Constants/passCesium3DTileClassification', './Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow', './Shaders/Builtin/Constants/passCompute', './Shaders/Builtin/Constants/passEnvironment', './Shaders/Builtin/Constants/passGlobe', './Shaders/Builtin/Constants/passOpaque', './Shaders/Builtin/Constants/passOverlay', './Shaders/Builtin/Constants/passTerrainClassification', './Shaders/Builtin/Constants/passTranslucent', './Shaders/Builtin/Constants/pi', './Shaders/Builtin/Constants/piOverFour', './Shaders/Builtin/Constants/piOverSix', './Shaders/Builtin/Constants/piOverThree', './Shaders/Builtin/Constants/piOverTwo', './Shaders/Builtin/Constants/radiansPerDegree', './Shaders/Builtin/Constants/sceneMode2D', './Shaders/Builtin/Constants/sceneMode3D', './Shaders/Builtin/Constants/sceneModeColumbusView', './Shaders/Builtin/Constants/sceneModeMorphing', './Shaders/Builtin/Constants/solarRadius', './Shaders/Builtin/Constants/threePiOver2', './Shaders/Builtin/Constants/twoPi', './Shaders/Builtin/Constants/webMercatorMaxLatitude', './Shaders/Builtin/CzmBuiltins', './Shaders/Builtin/Functions/alphaWeight', './Shaders/Builtin/Functions/antialias', './Shaders/Builtin/Functions/cascadeColor', './Shaders/Builtin/Functions/cascadeDistance', './Shaders/Builtin/Functions/cascadeMatrix', './Shaders/Builtin/Functions/cascadeWeights', './Shaders/Builtin/Functions/columbusViewMorph', './Shaders/Builtin/Functions/computePosition', './Shaders/Builtin/Functions/cosineAndSine', './Shaders/Builtin/Functions/decompressTextureCoordinates', './Shaders/Builtin/Functions/discardIfClippedWithIntersect', './Shaders/Builtin/Functions/discardIfClippedWithUnion', './Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates', './Shaders/Builtin/Functions/ellipsoidContainsPoint', './Shaders/Builtin/Functions/ellipsoidNew', './Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates', './Shaders/Builtin/Functions/equalsEpsilon', './Shaders/Builtin/Functions/eyeOffset', './Shaders/Builtin/Functions/eyeToWindowCoordinates', './Shaders/Builtin/Functions/fog', './Shaders/Builtin/Functions/geodeticSurfaceNormal', './Shaders/Builtin/Functions/getDefaultMaterial', './Shaders/Builtin/Functions/getLambertDiffuse', './Shaders/Builtin/Functions/getSpecular', './Shaders/Builtin/Functions/getWaterNoise', './Shaders/Builtin/Functions/getWgs84EllipsoidEC', './Shaders/Builtin/Functions/HSBToRGB', './Shaders/Builtin/Functions/HSLToRGB', './Shaders/Builtin/Functions/hue', './Shaders/Builtin/Functions/isEmpty', './Shaders/Builtin/Functions/isFull', './Shaders/Builtin/Functions/latitudeToWebMercatorFraction', './Shaders/Builtin/Functions/luminance', './Shaders/Builtin/Functions/metersPerPixel', './Shaders/Builtin/Functions/modelToWindowCoordinates', './Shaders/Builtin/Functions/multiplyWithColorBalance', './Shaders/Builtin/Functions/nearFarScalar', './Shaders/Builtin/Functions/octDecode', './Shaders/Builtin/Functions/packDepth', './Shaders/Builtin/Functions/phong', './Shaders/Builtin/Functions/pointAlongRay', './Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval', './Shaders/Builtin/Functions/RGBToHSB', './Shaders/Builtin/Functions/RGBToHSL', './Shaders/Builtin/Functions/RGBToXYZ', './Shaders/Builtin/Functions/saturation', './Shaders/Builtin/Functions/shadowDepthCompare', './Shaders/Builtin/Functions/shadowVisibility', './Shaders/Builtin/Functions/signNotZero', './Shaders/Builtin/Functions/tangentToEyeSpaceMatrix', './Shaders/Builtin/Functions/translateRelativeToEye', './Shaders/Builtin/Functions/translucentPhong', './Shaders/Builtin/Functions/transpose', './Shaders/Builtin/Functions/unpackDepth', './Shaders/Builtin/Functions/windowToEyeCoordinates', './Shaders/Builtin/Functions/XYZToRGB', './Shaders/Builtin/Structs/depthRangeStruct', './Shaders/Builtin/Structs/ellipsoid', './Shaders/Builtin/Structs/material', './Shaders/Builtin/Structs/materialInput', './Shaders/Builtin/Structs/ray', './Shaders/Builtin/Structs/raySegment', './Shaders/Builtin/Structs/shadowParameters', './Shaders/CompositeOITFS', './Shaders/DepthPlaneFS', './Shaders/DepthPlaneVS', './Shaders/EllipsoidFS', './Shaders/EllipsoidVS', './Shaders/GlobeFS', './Shaders/GlobeVS', './Shaders/GroundAtmosphere', './Shaders/Materials/BumpMapMaterial', './Shaders/Materials/CheckerboardMaterial', './Shaders/Materials/DotMaterial', './Shaders/Materials/ElevationContourMaterial', './Shaders/Materials/ElevationRampMaterial', './Shaders/Materials/FadeMaterial', './Shaders/Materials/GridMaterial', './Shaders/Materials/NormalMapMaterial', './Shaders/Materials/PolylineArrowMaterial', './Shaders/Materials/PolylineDashMaterial', './Shaders/Materials/PolylineGlowMaterial', './Shaders/Materials/PolylineOutlineMaterial', './Shaders/Materials/RimLightingMaterial', './Shaders/Materials/SlopeRampMaterial', './Shaders/Materials/StripeMaterial', './Shaders/Materials/Water', './Shaders/PointPrimitiveCollectionFS', './Shaders/PointPrimitiveCollectionVS', './Shaders/PolylineCommon', './Shaders/PolylineFS', './Shaders/PolylineVS', './Shaders/PostProcessFilters/AdditiveBlend', './Shaders/PostProcessFilters/BrightPass', './Shaders/PostProcessFilters/FXAA', './Shaders/PostProcessFilters/GaussianBlur1D', './Shaders/PostProcessFilters/PassThrough', './Shaders/ReprojectWebMercatorFS', './Shaders/ReprojectWebMercatorVS', './Shaders/ShadowVolumeFS', './Shaders/ShadowVolumeVS', './Shaders/SkyAtmosphereFS', './Shaders/SkyAtmosphereVS', './Shaders/SkyBoxFS', './Shaders/SkyBoxVS', './Shaders/SunFS', './Shaders/SunTextureFS', './Shaders/SunVS', './Shaders/ViewportQuadFS', './Shaders/ViewportQuadVS', './ThirdParty/Autolinker', './ThirdParty/crunch', './ThirdParty/earcut-2.1.1', './ThirdParty/GltfPipeline/addDefaults', './ThirdParty/GltfPipeline/addExtensionsRequired', './ThirdParty/GltfPipeline/addExtensionsUsed', './ThirdParty/GltfPipeline/addPipelineExtras', './ThirdParty/GltfPipeline/addToArray', './ThirdParty/GltfPipeline/byteLengthForComponentType', './ThirdParty/GltfPipeline/findAccessorMinMax', './ThirdParty/GltfPipeline/ForEach', './ThirdParty/GltfPipeline/getAccessorByteStride', './ThirdParty/GltfPipeline/getJointCountForMaterials', './ThirdParty/GltfPipeline/glslTypeToWebGLConstant', './ThirdParty/GltfPipeline/numberOfComponentsForType', './ThirdParty/GltfPipeline/parseBinaryGltf', './ThirdParty/GltfPipeline/processModelMaterialsCommon', './ThirdParty/GltfPipeline/processPbrMetallicRoughness', './ThirdParty/GltfPipeline/removeExtensionsRequired', './ThirdParty/GltfPipeline/removeExtensionsUsed', './ThirdParty/GltfPipeline/removePipelineExtras', './ThirdParty/GltfPipeline/techniqueParameterForSemantic', './ThirdParty/GltfPipeline/updateVersion', './ThirdParty/GltfPipeline/webGLConstantToGlslType', './ThirdParty/google-earth-dbroot-parser', './ThirdParty/jsep', './ThirdParty/kdbush', './ThirdParty/knockout-3.4.2', './ThirdParty/knockout-es5', './ThirdParty/knockout', './ThirdParty/measureText', './ThirdParty/mersenne-twister', './ThirdParty/NoSleep', './ThirdParty/pako_inflate', './ThirdParty/protobuf-minimal', './ThirdParty/Shaders/FXAA3_11', './ThirdParty/sprintf', './ThirdParty/topojson', './ThirdParty/Tween', './ThirdParty/Uri', './ThirdParty/when', './ThirdParty/zip', './Widgets/Animation/Animation', './Widgets/Animation/AnimationViewModel', './Widgets/BaseLayerPicker/BaseLayerPicker', './Widgets/BaseLayerPicker/BaseLayerPickerViewModel', './Widgets/BaseLayerPicker/createDefaultImageryProviderViewModels', './Widgets/BaseLayerPicker/createDefaultTerrainProviderViewModels', './Widgets/BaseLayerPicker/ProviderViewModel', './Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector', './Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel', './Widgets/CesiumInspector/CesiumInspector', './Widgets/CesiumInspector/CesiumInspectorViewModel', './Widgets/CesiumWidget/CesiumWidget', './Widgets/ClockViewModel', './Widgets/Command', './Widgets/createCommand', './Widgets/FullscreenButton/FullscreenButton', './Widgets/FullscreenButton/FullscreenButtonViewModel', './Widgets/Geocoder/Geocoder', './Widgets/Geocoder/GeocoderViewModel', './Widgets/getElement', './Widgets/HomeButton/HomeButton', './Widgets/HomeButton/HomeButtonViewModel', './Widgets/InfoBox/InfoBox', './Widgets/InfoBox/InfoBoxViewModel', './Widgets/NavigationHelpButton/NavigationHelpButton', './Widgets/NavigationHelpButton/NavigationHelpButtonViewModel', './Widgets/PerformanceWatchdog/PerformanceWatchdog', './Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel', './Widgets/ProjectionPicker/ProjectionPicker', './Widgets/ProjectionPicker/ProjectionPickerViewModel', './Widgets/SceneModePicker/SceneModePicker', './Widgets/SceneModePicker/SceneModePickerViewModel', './Widgets/SelectionIndicator/SelectionIndicator', './Widgets/SelectionIndicator/SelectionIndicatorViewModel', './Widgets/subscribeAndEvaluate', './Widgets/SvgPathBindingHandler', './Widgets/Timeline/Timeline', './Widgets/Timeline/TimelineHighlightRange', './Widgets/Timeline/TimelineTrack', './Widgets/ToggleButtonViewModel', './Widgets/Viewer/Viewer', './Widgets/Viewer/viewerCesium3DTilesInspectorMixin', './Widgets/Viewer/viewerCesiumInspectorMixin', './Widgets/Viewer/viewerDragDropMixin', './Widgets/Viewer/viewerPerformanceWatchdogMixin', './Widgets/VRButton/VRButton', './Widgets/VRButton/VRButtonViewModel', './Workers/createTaskProcessorWorker'], function(Core_appendForwardSlash, Core_arrayFill, Core_arrayRemoveDuplicates, Core_AssociativeArray, Core_AttributeCompression, Core_AxisAlignedBoundingBox, Core_barycentricCoordinates, Core_binarySearch, Core_BingMapsApi, Core_BingMapsGeocoderService, Core_BoundingRectangle, Core_BoundingSphere, Core_BoxGeometry, Core_BoxOutlineGeometry, Core_buildModuleUrl, Core_cancelAnimationFrame, Core_Cartesian2, Core_Cartesian3, Core_Cartesian4, Core_Cartographic, Core_CartographicGeocoderService, Core_CatmullRomSpline, Core_CesiumTerrainProvider, Core_Check, Core_CircleGeometry, Core_CircleOutlineGeometry, Core_ClippingPlaneCollection, Core_Clock, Core_ClockRange, Core_ClockStep, Core_clone, Core_Color, Core_ColorGeometryInstanceAttribute, Core_combine, Core_ComponentDatatype, Core_CompressedTextureBuffer, Core_CornerType, Core_CorridorGeometry, Core_CorridorGeometryLibrary, Core_CorridorOutlineGeometry, Core_createGuid, Core_Credit, Core_CubicRealPolynomial, Core_CullingVolume, Core_CylinderGeometry, Core_CylinderGeometryLibrary, Core_CylinderOutlineGeometry, Core_decodeGoogleEarthEnterpriseData, Core_DefaultProxy, Core_defaultValue, Core_defined, Core_defineProperties, Core_deprecationWarning, Core_destroyObject, Core_DeveloperError, Core_DistanceDisplayCondition, Core_DistanceDisplayConditionGeometryInstanceAttribute, Core_DoublyLinkedList, Core_EarthOrientationParameters, Core_EarthOrientationParametersSample, Core_EasingFunction, Core_EllipseGeometry, Core_EllipseGeometryLibrary, Core_EllipseOutlineGeometry, Core_Ellipsoid, Core_EllipsoidalOccluder, Core_EllipsoidGeodesic, Core_EllipsoidGeometry, Core_EllipsoidOutlineGeometry, Core_EllipsoidTangentPlane, Core_EllipsoidTerrainProvider, Core_EncodedCartesian3, Core_Event, Core_EventHelper, Core_ExtrapolationType, Core_FeatureDetection, Core_formatError, Core_freezeObject, Core_FrustumGeometry, Core_FrustumOutlineGeometry, Core_Fullscreen, Core_GeocoderService, Core_GeographicProjection, Core_GeographicTilingScheme, Core_Geometry, Core_GeometryAttribute, Core_GeometryAttributes, Core_GeometryInstance, Core_GeometryInstanceAttribute, Core_GeometryPipeline, Core_GeometryType, Core_getAbsoluteUri, Core_getBaseUri, Core_getExtensionFromUri, Core_getFilenameFromUri, Core_getImagePixels, Core_getMagic, Core_getStringFromTypedArray, Core_getTimestamp, Core_GoogleEarthEnterpriseMetadata, Core_GoogleEarthEnterpriseTerrainData, Core_GoogleEarthEnterpriseTerrainProvider, Core_GoogleEarthEnterpriseTileInformation, Core_GregorianDate, Core_HeadingPitchRange, Core_HeadingPitchRoll, Core_Heap, Core_HeightmapTerrainData, Core_HeightmapTessellator, Core_HermitePolynomialApproximation, Core_HermiteSpline, Core_Iau2000Orientation, Core_Iau2006XysData, Core_Iau2006XysSample, Core_IauOrientationAxes, Core_IauOrientationParameters, Core_IndexDatatype, Core_InterpolationAlgorithm, Core_Intersect, Core_Intersections2D, Core_IntersectionTests, Core_Interval, Core_isArray, Core_isBitSet, Core_isBlobUri, Core_isCrossOriginUrl, Core_isDataUri, Core_isLeapYear, Core_Iso8601, Core_joinUrls, Core_JulianDate, Core_KeyboardEventModifier, Core_LagrangePolynomialApproximation, Core_LeapSecond, Core_LinearApproximation, Core_LinearSpline, Core_loadArrayBuffer, Core_loadBlob, Core_loadCRN, Core_loadImage, Core_loadImageFromTypedArray, Core_loadImageViaBlob, Core_loadJson, Core_loadJsonp, Core_loadKTX, Core_loadText, Core_loadWithXhr, Core_loadXML, Core_ManagedArray, Core_MapboxApi, Core_MapProjection, Core_Math, Core_Matrix2, Core_Matrix3, Core_Matrix4, Core_mergeSort, Core_NearFarScalar, Core_objectToQuery, Core_Occluder, Core_oneTimeWarning, Core_OrientedBoundingBox, Core_OrthographicFrustum, Core_OrthographicOffCenterFrustum, Core_Packable, Core_PackableForInterpolation, Core_parseResponseHeaders, Core_PerspectiveFrustum, Core_PerspectiveOffCenterFrustum, Core_PinBuilder, Core_PixelFormat, Core_Plane, Core_PlaneGeometry, Core_PlaneOutlineGeometry, Core_pointInsideTriangle, Core_PolygonGeometry, Core_PolygonGeometryLibrary, Core_PolygonHierarchy, Core_PolygonOutlineGeometry, Core_PolygonPipeline, Core_PolylineGeometry, Core_PolylinePipeline, Core_PolylineVolumeGeometry, Core_PolylineVolumeGeometryLibrary, Core_PolylineVolumeOutlineGeometry, Core_PrimitiveType, Core_QuadraticRealPolynomial, Core_QuantizedMeshTerrainData, Core_QuarticRealPolynomial, Core_Quaternion, Core_QuaternionSpline, Core_queryToObject, Core_Queue, Core_Ray, Core_Rectangle, Core_RectangleGeometry, Core_RectangleGeometryLibrary, Core_RectangleOutlineGeometry, Core_ReferenceFrame, Core_Request, Core_requestAnimationFrame, Core_RequestErrorEvent, Core_RequestScheduler, Core_RequestState, Core_RequestType, Core_RuntimeError, Core_sampleTerrain, Core_sampleTerrainMostDetailed, Core_scaleToGeodeticSurface, Core_ScreenSpaceEventHandler, Core_ScreenSpaceEventType, Core_ShowGeometryInstanceAttribute, Core_Simon1994PlanetaryPositions, Core_SimplePolylineGeometry, Core_SphereGeometry, Core_SphereOutlineGeometry, Core_Spherical, Core_Spline, Core_subdivideArray, Core_TaskProcessor, Core_TerrainData, Core_TerrainEncoding, Core_TerrainMesh, Core_TerrainProvider, Core_TerrainQuantization, Core_TileAvailability, Core_TileProviderError, Core_TilingScheme, Core_TimeConstants, Core_TimeInterval, Core_TimeIntervalCollection, Core_TimeStandard, Core_Tipsify, Core_Transforms, Core_TranslationRotationScale, Core_TridiagonalSystemSolver, Core_TrustedServers, Core_VertexFormat, Core_VideoSynchronizer, Core_Visibility, Core_VRTheWorldTerrainProvider, Core_WallGeometry, Core_WallGeometryLibrary, Core_WallOutlineGeometry, Core_WebGLConstants, Core_WebMercatorProjection, Core_WebMercatorTilingScheme, Core_WeightSpline, Core_WindingOrder, Core_wrapFunction, Core_writeTextToCanvas, DataSources_BillboardGraphics, DataSources_BillboardVisualizer, DataSources_BoundingSphereState, DataSources_BoxGeometryUpdater, DataSources_BoxGraphics, DataSources_CallbackProperty, DataSources_CheckerboardMaterialProperty, DataSources_ColorMaterialProperty, DataSources_CompositeEntityCollection, DataSources_CompositeMaterialProperty, DataSources_CompositePositionProperty, DataSources_CompositeProperty, DataSources_ConstantPositionProperty, DataSources_ConstantProperty, DataSources_CorridorGeometryUpdater, DataSources_CorridorGraphics, DataSources_createMaterialPropertyDescriptor, DataSources_createPropertyDescriptor, DataSources_createRawPropertyDescriptor, DataSources_CustomDataSource, DataSources_CylinderGeometryUpdater, DataSources_CylinderGraphics, DataSources_CzmlDataSource, DataSources_DataSource, DataSources_DataSourceClock, DataSources_DataSourceCollection, DataSources_DataSourceDisplay, DataSources_dynamicGeometryGetBoundingSphere, DataSources_DynamicGeometryUpdater, DataSources_EllipseGeometryUpdater, DataSources_EllipseGraphics, DataSources_EllipsoidGeometryUpdater, DataSources_EllipsoidGraphics, DataSources_Entity, DataSources_EntityCluster, DataSources_EntityCollection, DataSources_EntityView, DataSources_GeoJsonDataSource, DataSources_GeometryUpdater, DataSources_GeometryVisualizer, DataSources_GridMaterialProperty, DataSources_ImageMaterialProperty, DataSources_KmlCamera, DataSources_KmlDataSource, DataSources_KmlLookAt, DataSources_KmlTour, DataSources_KmlTourFlyTo, DataSources_KmlTourWait, DataSources_LabelGraphics, DataSources_LabelVisualizer, DataSources_MaterialProperty, DataSources_ModelGraphics, DataSources_ModelVisualizer, DataSources_NodeTransformationProperty, DataSources_PathGraphics, DataSources_PathVisualizer, DataSources_PlaneGeometryUpdater, DataSources_PlaneGraphics, DataSources_PointGraphics, DataSources_PointVisualizer, DataSources_PolygonGeometryUpdater, DataSources_PolygonGraphics, DataSources_PolylineArrowMaterialProperty, DataSources_PolylineDashMaterialProperty, DataSources_PolylineGeometryUpdater, DataSources_PolylineGlowMaterialProperty, DataSources_PolylineGraphics, DataSources_PolylineOutlineMaterialProperty, DataSources_PolylineVolumeGeometryUpdater, DataSources_PolylineVolumeGraphics, DataSources_PositionProperty, DataSources_PositionPropertyArray, DataSources_Property, DataSources_PropertyArray, DataSources_PropertyBag, DataSources_RectangleGeometryUpdater, DataSources_RectangleGraphics, DataSources_ReferenceProperty, DataSources_Rotation, DataSources_SampledPositionProperty, DataSources_SampledProperty, DataSources_ScaledPositionProperty, DataSources_StaticGeometryColorBatch, DataSources_StaticGeometryPerMaterialBatch, DataSources_StaticGroundGeometryColorBatch, DataSources_StaticOutlineGeometryBatch, DataSources_StripeMaterialProperty, DataSources_StripeOrientation, DataSources_TimeIntervalCollectionPositionProperty, DataSources_TimeIntervalCollectionProperty, DataSources_VelocityOrientationProperty, DataSources_VelocityVectorProperty, DataSources_Visualizer, DataSources_WallGeometryUpdater, DataSources_WallGraphics, Renderer_AutomaticUniforms, Renderer_Buffer, Renderer_BufferUsage, Renderer_ClearCommand, Renderer_ComputeCommand, Renderer_ComputeEngine, Renderer_Context, Renderer_ContextLimits, Renderer_createUniform, Renderer_createUniformArray, Renderer_CubeMap, Renderer_CubeMapFace, Renderer_DrawCommand, Renderer_Framebuffer, Renderer_freezeRenderState, Renderer_loadCubeMap, Renderer_MipmapHint, Renderer_modernizeShader, Renderer_Pass, Renderer_PassState, Renderer_PickFramebuffer, Renderer_PixelDatatype, Renderer_Renderbuffer, Renderer_RenderbufferFormat, Renderer_RenderState, Renderer_Sampler, Renderer_ShaderCache, Renderer_ShaderProgram, Renderer_ShaderSource, Renderer_Texture, Renderer_TextureMagnificationFilter, Renderer_TextureMinificationFilter, Renderer_TextureWrap, Renderer_UniformState, Renderer_VertexArray, Renderer_VertexArrayFacade, Scene_Appearance, Scene_ArcGisMapServerImageryProvider, Scene_AttributeType, Scene_Axis, Scene_Batched3DModel3DTileContent, Scene_BatchTable, Scene_Billboard, Scene_BillboardCollection, Scene_BingMapsImageryProvider, Scene_BingMapsStyle, Scene_BlendEquation, Scene_BlendFunction, Scene_BlendingState, Scene_BlendOption, Scene_BoxEmitter, Scene_BrdfLutGenerator, Scene_Camera, Scene_CameraEventAggregator, Scene_CameraEventType, Scene_CameraFlightPath, Scene_Cesium3DTile, Scene_Cesium3DTileBatchTable, Scene_Cesium3DTileChildrenVisibility, Scene_Cesium3DTileColorBlendMode, Scene_Cesium3DTileContent, Scene_Cesium3DTileContentFactory, Scene_Cesium3DTileContentState, Scene_Cesium3DTileFeature, Scene_Cesium3DTileFeatureTable, Scene_Cesium3DTileOptimizationHint, Scene_Cesium3DTileOptimizations, Scene_Cesium3DTileRefine, Scene_Cesium3DTileset, Scene_Cesium3DTilesetStatistics, Scene_Cesium3DTilesetTraversal, Scene_Cesium3DTileStyle, Scene_Cesium3DTileStyleEngine, Scene_CircleEmitter, Scene_ClassificationPrimitive, Scene_ClassificationType, Scene_ColorBlendMode, Scene_Composite3DTileContent, Scene_ConditionsExpression, Scene_ConeEmitter, Scene_createOpenStreetMapImageryProvider, Scene_createTangentSpaceDebugPrimitive, Scene_createTileMapServiceImageryProvider, Scene_CreditDisplay, Scene_CullFace, Scene_DebugAppearance, Scene_DebugCameraPrimitive, Scene_DebugModelMatrixPrimitive, Scene_DepthFunction, Scene_DepthPlane, Scene_DeviceOrientationCameraController, Scene_DiscardMissingTileImagePolicy, Scene_EllipsoidPrimitive, Scene_EllipsoidSurfaceAppearance, Scene_Empty3DTileContent, Scene_Expression, Scene_ExpressionNodeType, Scene_Fog, Scene_FrameRateMonitor, Scene_FrameState, Scene_FrustumCommands, Scene_FXAA, Scene_getAttributeOrUniformBySemantic, Scene_getBinaryAccessor, Scene_GetFeatureInfoFormat, Scene_Globe, Scene_GlobeDepth, Scene_GlobeSurfaceShaderSet, Scene_GlobeSurfaceTile, Scene_GlobeSurfaceTileProvider, Scene_GoogleEarthEnterpriseImageryProvider, Scene_GoogleEarthEnterpriseMapsProvider, Scene_GridImageryProvider, Scene_GroundPrimitive, Scene_HeightReference, Scene_HorizontalOrigin, Scene_Imagery, Scene_ImageryLayer, Scene_ImageryLayerCollection, Scene_ImageryLayerFeatureInfo, Scene_ImageryProvider, Scene_ImagerySplitDirection, Scene_ImageryState, Scene_Instanced3DModel3DTileContent, Scene_InvertClassification, Scene_JobScheduler, Scene_JobType, Scene_Label, Scene_LabelCollection, Scene_LabelStyle, Scene_MapboxImageryProvider, Scene_MapMode2D, Scene_Material, Scene_MaterialAppearance, Scene_Model, Scene_ModelAnimation, Scene_ModelAnimationCache, Scene_ModelAnimationCollection, Scene_ModelAnimationLoop, Scene_ModelAnimationState, Scene_ModelInstance, Scene_ModelInstanceCollection, Scene_ModelMaterial, Scene_ModelMesh, Scene_ModelNode, Scene_Moon, Scene_NeverTileDiscardPolicy, Scene_OIT, Scene_Particle, Scene_ParticleBurst, Scene_ParticleEmitter, Scene_ParticleSystem, Scene_PerformanceDisplay, Scene_PerInstanceColorAppearance, Scene_PickDepth, Scene_PointCloud3DTileContent, Scene_PointPrimitive, Scene_PointPrimitiveCollection, Scene_Polyline, Scene_PolylineCollection, Scene_PolylineColorAppearance, Scene_PolylineMaterialAppearance, Scene_Primitive, Scene_PrimitiveCollection, Scene_PrimitivePipeline, Scene_PrimitiveState, Scene_QuadtreeOccluders, Scene_QuadtreePrimitive, Scene_QuadtreeTile, Scene_QuadtreeTileLoadState, Scene_QuadtreeTileProvider, Scene_Scene, Scene_SceneMode, Scene_SceneTransforms, Scene_SceneTransitioner, Scene_ScreenSpaceCameraController, Scene_ShadowMap, Scene_ShadowMapShader, Scene_ShadowMode, Scene_SingleTileImageryProvider, Scene_SkyAtmosphere, Scene_SkyBox, Scene_SphereEmitter, Scene_StencilFunction, Scene_StencilOperation, Scene_StyleExpression, Scene_Sun, Scene_SunPostProcess, Scene_TerrainState, Scene_TextureAtlas, Scene_TileBoundingRegion, Scene_TileBoundingSphere, Scene_TileBoundingVolume, Scene_TileCoordinatesImageryProvider, Scene_TileDiscardPolicy, Scene_TileImagery, Scene_TileOrientedBoundingBox, Scene_TileReplacementQueue, Scene_Tileset3DTileContent, Scene_TileState, Scene_TileTerrain, Scene_TimeDynamicImagery, Scene_TweenCollection, Scene_UrlTemplateImageryProvider, Scene_VerticalOrigin, Scene_ViewportQuad, Scene_WebMapServiceImageryProvider, Scene_WebMapTileServiceImageryProvider, Shaders_AdjustTranslucentFS, Shaders_Appearances_AllMaterialAppearanceFS, Shaders_Appearances_AllMaterialAppearanceVS, Shaders_Appearances_BasicMaterialAppearanceFS, Shaders_Appearances_BasicMaterialAppearanceVS, Shaders_Appearances_EllipsoidSurfaceAppearanceFS, Shaders_Appearances_EllipsoidSurfaceAppearanceVS, Shaders_Appearances_PerInstanceColorAppearanceFS, Shaders_Appearances_PerInstanceColorAppearanceVS, Shaders_Appearances_PerInstanceFlatColorAppearanceFS, Shaders_Appearances_PerInstanceFlatColorAppearanceVS, Shaders_Appearances_PolylineColorAppearanceVS, Shaders_Appearances_PolylineMaterialAppearanceVS, Shaders_Appearances_TexturedMaterialAppearanceFS, Shaders_Appearances_TexturedMaterialAppearanceVS, Shaders_BillboardCollectionFS, Shaders_BillboardCollectionVS, Shaders_BrdfLutGeneratorFS, Shaders_Builtin_Constants_degreesPerRadian, Shaders_Builtin_Constants_depthRange, Shaders_Builtin_Constants_epsilon1, Shaders_Builtin_Constants_epsilon2, Shaders_Builtin_Constants_epsilon3, Shaders_Builtin_Constants_epsilon4, Shaders_Builtin_Constants_epsilon5, Shaders_Builtin_Constants_epsilon6, Shaders_Builtin_Constants_epsilon7, Shaders_Builtin_Constants_infinity, Shaders_Builtin_Constants_maxClippingPlanes, Shaders_Builtin_Constants_oneOverPi, Shaders_Builtin_Constants_oneOverTwoPi, Shaders_Builtin_Constants_passCesium3DTile, Shaders_Builtin_Constants_passCesium3DTileClassification, Shaders_Builtin_Constants_passCesium3DTileClassificationIgnoreShow, Shaders_Builtin_Constants_passCompute, Shaders_Builtin_Constants_passEnvironment, Shaders_Builtin_Constants_passGlobe, Shaders_Builtin_Constants_passOpaque, Shaders_Builtin_Constants_passOverlay, Shaders_Builtin_Constants_passTerrainClassification, Shaders_Builtin_Constants_passTranslucent, Shaders_Builtin_Constants_pi, Shaders_Builtin_Constants_piOverFour, Shaders_Builtin_Constants_piOverSix, Shaders_Builtin_Constants_piOverThree, Shaders_Builtin_Constants_piOverTwo, Shaders_Builtin_Constants_radiansPerDegree, Shaders_Builtin_Constants_sceneMode2D, Shaders_Builtin_Constants_sceneMode3D, Shaders_Builtin_Constants_sceneModeColumbusView, Shaders_Builtin_Constants_sceneModeMorphing, Shaders_Builtin_Constants_solarRadius, Shaders_Builtin_Constants_threePiOver2, Shaders_Builtin_Constants_twoPi, Shaders_Builtin_Constants_webMercatorMaxLatitude, Shaders_Builtin_CzmBuiltins, Shaders_Builtin_Functions_alphaWeight, Shaders_Builtin_Functions_antialias, Shaders_Builtin_Functions_cascadeColor, Shaders_Builtin_Functions_cascadeDistance, Shaders_Builtin_Functions_cascadeMatrix, Shaders_Builtin_Functions_cascadeWeights, Shaders_Builtin_Functions_columbusViewMorph, Shaders_Builtin_Functions_computePosition, Shaders_Builtin_Functions_cosineAndSine, Shaders_Builtin_Functions_decompressTextureCoordinates, Shaders_Builtin_Functions_discardIfClippedWithIntersect, Shaders_Builtin_Functions_discardIfClippedWithUnion, Shaders_Builtin_Functions_eastNorthUpToEyeCoordinates, Shaders_Builtin_Functions_ellipsoidContainsPoint, Shaders_Builtin_Functions_ellipsoidNew, Shaders_Builtin_Functions_ellipsoidWgs84TextureCoordinates, Shaders_Builtin_Functions_equalsEpsilon, Shaders_Builtin_Functions_eyeOffset, Shaders_Builtin_Functions_eyeToWindowCoordinates, Shaders_Builtin_Functions_fog, Shaders_Builtin_Functions_geodeticSurfaceNormal, Shaders_Builtin_Functions_getDefaultMaterial, Shaders_Builtin_Functions_getLambertDiffuse, Shaders_Builtin_Functions_getSpecular, Shaders_Builtin_Functions_getWaterNoise, Shaders_Builtin_Functions_getWgs84EllipsoidEC, Shaders_Builtin_Functions_HSBToRGB, Shaders_Builtin_Functions_HSLToRGB, Shaders_Builtin_Functions_hue, Shaders_Builtin_Functions_isEmpty, Shaders_Builtin_Functions_isFull, Shaders_Builtin_Functions_latitudeToWebMercatorFraction, Shaders_Builtin_Functions_luminance, Shaders_Builtin_Functions_metersPerPixel, Shaders_Builtin_Functions_modelToWindowCoordinates, Shaders_Builtin_Functions_multiplyWithColorBalance, Shaders_Builtin_Functions_nearFarScalar, Shaders_Builtin_Functions_octDecode, Shaders_Builtin_Functions_packDepth, Shaders_Builtin_Functions_phong, Shaders_Builtin_Functions_pointAlongRay, Shaders_Builtin_Functions_rayEllipsoidIntersectionInterval, Shaders_Builtin_Functions_RGBToHSB, Shaders_Builtin_Functions_RGBToHSL, Shaders_Builtin_Functions_RGBToXYZ, Shaders_Builtin_Functions_saturation, Shaders_Builtin_Functions_shadowDepthCompare, Shaders_Builtin_Functions_shadowVisibility, Shaders_Builtin_Functions_signNotZero, Shaders_Builtin_Functions_tangentToEyeSpaceMatrix, Shaders_Builtin_Functions_translateRelativeToEye, Shaders_Builtin_Functions_translucentPhong, Shaders_Builtin_Functions_transpose, Shaders_Builtin_Functions_unpackDepth, Shaders_Builtin_Functions_windowToEyeCoordinates, Shaders_Builtin_Functions_XYZToRGB, Shaders_Builtin_Structs_depthRangeStruct, Shaders_Builtin_Structs_ellipsoid, Shaders_Builtin_Structs_material, Shaders_Builtin_Structs_materialInput, Shaders_Builtin_Structs_ray, Shaders_Builtin_Structs_raySegment, Shaders_Builtin_Structs_shadowParameters, Shaders_CompositeOITFS, Shaders_DepthPlaneFS, Shaders_DepthPlaneVS, Shaders_EllipsoidFS, Shaders_EllipsoidVS, Shaders_GlobeFS, Shaders_GlobeVS, Shaders_GroundAtmosphere, Shaders_Materials_BumpMapMaterial, Shaders_Materials_CheckerboardMaterial, Shaders_Materials_DotMaterial, Shaders_Materials_ElevationContourMaterial, Shaders_Materials_ElevationRampMaterial, Shaders_Materials_FadeMaterial, Shaders_Materials_GridMaterial, Shaders_Materials_NormalMapMaterial, Shaders_Materials_PolylineArrowMaterial, Shaders_Materials_PolylineDashMaterial, Shaders_Materials_PolylineGlowMaterial, Shaders_Materials_PolylineOutlineMaterial, Shaders_Materials_RimLightingMaterial, Shaders_Materials_SlopeRampMaterial, Shaders_Materials_StripeMaterial, Shaders_Materials_Water, Shaders_PointPrimitiveCollectionFS, Shaders_PointPrimitiveCollectionVS, Shaders_PolylineCommon, Shaders_PolylineFS, Shaders_PolylineVS, Shaders_PostProcessFilters_AdditiveBlend, Shaders_PostProcessFilters_BrightPass, Shaders_PostProcessFilters_FXAA, Shaders_PostProcessFilters_GaussianBlur1D, Shaders_PostProcessFilters_PassThrough, Shaders_ReprojectWebMercatorFS, Shaders_ReprojectWebMercatorVS, Shaders_ShadowVolumeFS, Shaders_ShadowVolumeVS, Shaders_SkyAtmosphereFS, Shaders_SkyAtmosphereVS, Shaders_SkyBoxFS, Shaders_SkyBoxVS, Shaders_SunFS, Shaders_SunTextureFS, Shaders_SunVS, Shaders_ViewportQuadFS, Shaders_ViewportQuadVS, ThirdParty_Autolinker, ThirdParty_crunch, ThirdParty_earcut_2_1_1, ThirdParty_GltfPipeline_addDefaults, ThirdParty_GltfPipeline_addExtensionsRequired, ThirdParty_GltfPipeline_addExtensionsUsed, ThirdParty_GltfPipeline_addPipelineExtras, ThirdParty_GltfPipeline_addToArray, ThirdParty_GltfPipeline_byteLengthForComponentType, ThirdParty_GltfPipeline_findAccessorMinMax, ThirdParty_GltfPipeline_ForEach, ThirdParty_GltfPipeline_getAccessorByteStride, ThirdParty_GltfPipeline_getJointCountForMaterials, ThirdParty_GltfPipeline_glslTypeToWebGLConstant, ThirdParty_GltfPipeline_numberOfComponentsForType, ThirdParty_GltfPipeline_parseBinaryGltf, ThirdParty_GltfPipeline_processModelMaterialsCommon, ThirdParty_GltfPipeline_processPbrMetallicRoughness, ThirdParty_GltfPipeline_removeExtensionsRequired, ThirdParty_GltfPipeline_removeExtensionsUsed, ThirdParty_GltfPipeline_removePipelineExtras, ThirdParty_GltfPipeline_techniqueParameterForSemantic, ThirdParty_GltfPipeline_updateVersion, ThirdParty_GltfPipeline_webGLConstantToGlslType, ThirdParty_google_earth_dbroot_parser, ThirdParty_jsep, ThirdParty_kdbush, ThirdParty_knockout_3_4_2, ThirdParty_knockout_es5, ThirdParty_knockout, ThirdParty_measureText, ThirdParty_mersenne_twister, ThirdParty_NoSleep, ThirdParty_pako_inflate, ThirdParty_protobuf_minimal, ThirdParty_Shaders_FXAA3_11, ThirdParty_sprintf, ThirdParty_topojson, ThirdParty_Tween, ThirdParty_Uri, ThirdParty_when, ThirdParty_zip, Widgets_Animation_Animation, Widgets_Animation_AnimationViewModel, Widgets_BaseLayerPicker_BaseLayerPicker, Widgets_BaseLayerPicker_BaseLayerPickerViewModel, Widgets_BaseLayerPicker_createDefaultImageryProviderViewModels, Widgets_BaseLayerPicker_createDefaultTerrainProviderViewModels, Widgets_BaseLayerPicker_ProviderViewModel, Widgets_Cesium3DTilesInspector_Cesium3DTilesInspector, Widgets_Cesium3DTilesInspector_Cesium3DTilesInspectorViewModel, Widgets_CesiumInspector_CesiumInspector, Widgets_CesiumInspector_CesiumInspectorViewModel, Widgets_CesiumWidget_CesiumWidget, Widgets_ClockViewModel, Widgets_Command, Widgets_createCommand, Widgets_FullscreenButton_FullscreenButton, Widgets_FullscreenButton_FullscreenButtonViewModel, Widgets_Geocoder_Geocoder, Widgets_Geocoder_GeocoderViewModel, Widgets_getElement, Widgets_HomeButton_HomeButton, Widgets_HomeButton_HomeButtonViewModel, Widgets_InfoBox_InfoBox, Widgets_InfoBox_InfoBoxViewModel, Widgets_NavigationHelpButton_NavigationHelpButton, Widgets_NavigationHelpButton_NavigationHelpButtonViewModel, Widgets_PerformanceWatchdog_PerformanceWatchdog, Widgets_PerformanceWatchdog_PerformanceWatchdogViewModel, Widgets_ProjectionPicker_ProjectionPicker, Widgets_ProjectionPicker_ProjectionPickerViewModel, Widgets_SceneModePicker_SceneModePicker, Widgets_SceneModePicker_SceneModePickerViewModel, Widgets_SelectionIndicator_SelectionIndicator, Widgets_SelectionIndicator_SelectionIndicatorViewModel, Widgets_subscribeAndEvaluate, Widgets_SvgPathBindingHandler, Widgets_Timeline_Timeline, Widgets_Timeline_TimelineHighlightRange, Widgets_Timeline_TimelineTrack, Widgets_ToggleButtonViewModel, Widgets_Viewer_Viewer, Widgets_Viewer_viewerCesium3DTilesInspectorMixin, Widgets_Viewer_viewerCesiumInspectorMixin, Widgets_Viewer_viewerDragDropMixin, Widgets_Viewer_viewerPerformanceWatchdogMixin, Widgets_VRButton_VRButton, Widgets_VRButton_VRButtonViewModel, Workers_createTaskProcessorWorker) { +define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayRemoveDuplicates', './Core/arraySlice', './Core/AssociativeArray', './Core/AttributeCompression', './Core/AxisAlignedBoundingBox', './Core/barycentricCoordinates', './Core/binarySearch', './Core/BingMapsApi', './Core/BingMapsGeocoderService', './Core/BoundingRectangle', './Core/BoundingSphere', './Core/BoxGeometry', './Core/BoxOutlineGeometry', './Core/buildModuleUrl', './Core/cancelAnimationFrame', './Core/Cartesian2', './Core/Cartesian3', './Core/Cartesian4', './Core/Cartographic', './Core/CartographicGeocoderService', './Core/CatmullRomSpline', './Core/CesiumTerrainProvider', './Core/Check', './Core/CircleGeometry', './Core/CircleOutlineGeometry', './Core/ClippingPlaneCollection', './Core/Clock', './Core/ClockRange', './Core/ClockStep', './Core/clone', './Core/Color', './Core/ColorGeometryInstanceAttribute', './Core/combine', './Core/ComponentDatatype', './Core/CompressedTextureBuffer', './Core/CornerType', './Core/CorridorGeometry', './Core/CorridorGeometryLibrary', './Core/CorridorOutlineGeometry', './Core/createGuid', './Core/Credit', './Core/CubicRealPolynomial', './Core/CullingVolume', './Core/CylinderGeometry', './Core/CylinderGeometryLibrary', './Core/CylinderOutlineGeometry', './Core/decodeGoogleEarthEnterpriseData', './Core/DefaultProxy', './Core/defaultValue', './Core/defined', './Core/defineProperties', './Core/deprecationWarning', './Core/destroyObject', './Core/DeveloperError', './Core/DistanceDisplayCondition', './Core/DistanceDisplayConditionGeometryInstanceAttribute', './Core/DoublyLinkedList', './Core/EarthOrientationParameters', './Core/EarthOrientationParametersSample', './Core/EasingFunction', './Core/EllipseGeometry', './Core/EllipseGeometryLibrary', './Core/EllipseOutlineGeometry', './Core/Ellipsoid', './Core/EllipsoidalOccluder', './Core/EllipsoidGeodesic', './Core/EllipsoidGeometry', './Core/EllipsoidOutlineGeometry', './Core/EllipsoidTangentPlane', './Core/EllipsoidTerrainProvider', './Core/EncodedCartesian3', './Core/Event', './Core/EventHelper', './Core/ExtrapolationType', './Core/FeatureDetection', './Core/formatError', './Core/freezeObject', './Core/FrustumGeometry', './Core/FrustumOutlineGeometry', './Core/Fullscreen', './Core/GeocoderService', './Core/GeographicProjection', './Core/GeographicTilingScheme', './Core/Geometry', './Core/GeometryAttribute', './Core/GeometryAttributes', './Core/GeometryInstance', './Core/GeometryInstanceAttribute', './Core/GeometryPipeline', './Core/GeometryType', './Core/getAbsoluteUri', './Core/getBaseUri', './Core/getExtensionFromUri', './Core/getFilenameFromUri', './Core/getImagePixels', './Core/getMagic', './Core/getStringFromTypedArray', './Core/getTimestamp', './Core/GoogleEarthEnterpriseMetadata', './Core/GoogleEarthEnterpriseTerrainData', './Core/GoogleEarthEnterpriseTerrainProvider', './Core/GoogleEarthEnterpriseTileInformation', './Core/GregorianDate', './Core/HeadingPitchRange', './Core/HeadingPitchRoll', './Core/Heap', './Core/HeightmapTerrainData', './Core/HeightmapTessellator', './Core/HermitePolynomialApproximation', './Core/HermiteSpline', './Core/Iau2000Orientation', './Core/Iau2006XysData', './Core/Iau2006XysSample', './Core/IauOrientationAxes', './Core/IauOrientationParameters', './Core/IndexDatatype', './Core/InterpolationAlgorithm', './Core/Intersect', './Core/Intersections2D', './Core/IntersectionTests', './Core/Interval', './Core/isArray', './Core/isBitSet', './Core/isBlobUri', './Core/isCrossOriginUrl', './Core/isDataUri', './Core/isLeapYear', './Core/Iso8601', './Core/JulianDate', './Core/KeyboardEventModifier', './Core/LagrangePolynomialApproximation', './Core/LeapSecond', './Core/LinearApproximation', './Core/LinearSpline', './Core/loadArrayBuffer', './Core/loadBlob', './Core/loadCRN', './Core/loadImage', './Core/loadImageFromTypedArray', './Core/loadImageViaBlob', './Core/loadJson', './Core/loadJsonp', './Core/loadKTX', './Core/loadText', './Core/loadWithXhr', './Core/loadXML', './Core/ManagedArray', './Core/MapboxApi', './Core/MapProjection', './Core/Math', './Core/Matrix2', './Core/Matrix3', './Core/Matrix4', './Core/mergeSort', './Core/NearFarScalar', './Core/objectToQuery', './Core/Occluder', './Core/oneTimeWarning', './Core/OrientedBoundingBox', './Core/OrthographicFrustum', './Core/OrthographicOffCenterFrustum', './Core/Packable', './Core/PackableForInterpolation', './Core/parseResponseHeaders', './Core/PerspectiveFrustum', './Core/PerspectiveOffCenterFrustum', './Core/PinBuilder', './Core/PixelFormat', './Core/Plane', './Core/PlaneGeometry', './Core/PlaneOutlineGeometry', './Core/pointInsideTriangle', './Core/PolygonGeometry', './Core/PolygonGeometryLibrary', './Core/PolygonHierarchy', './Core/PolygonOutlineGeometry', './Core/PolygonPipeline', './Core/PolylineGeometry', './Core/PolylinePipeline', './Core/PolylineVolumeGeometry', './Core/PolylineVolumeGeometryLibrary', './Core/PolylineVolumeOutlineGeometry', './Core/PrimitiveType', './Core/QuadraticRealPolynomial', './Core/QuantizedMeshTerrainData', './Core/QuarticRealPolynomial', './Core/Quaternion', './Core/QuaternionSpline', './Core/queryToObject', './Core/Queue', './Core/Ray', './Core/Rectangle', './Core/RectangleGeometry', './Core/RectangleGeometryLibrary', './Core/RectangleOutlineGeometry', './Core/ReferenceFrame', './Core/Request', './Core/requestAnimationFrame', './Core/RequestErrorEvent', './Core/RequestScheduler', './Core/RequestState', './Core/RequestType', './Core/Resource', './Core/RuntimeError', './Core/sampleTerrain', './Core/sampleTerrainMostDetailed', './Core/scaleToGeodeticSurface', './Core/ScreenSpaceEventHandler', './Core/ScreenSpaceEventType', './Core/ShowGeometryInstanceAttribute', './Core/Simon1994PlanetaryPositions', './Core/SimplePolylineGeometry', './Core/SphereGeometry', './Core/SphereOutlineGeometry', './Core/Spherical', './Core/Spline', './Core/subdivideArray', './Core/TaskProcessor', './Core/TerrainData', './Core/TerrainEncoding', './Core/TerrainMesh', './Core/TerrainProvider', './Core/TerrainQuantization', './Core/TileAvailability', './Core/TileProviderError', './Core/TilingScheme', './Core/TimeConstants', './Core/TimeInterval', './Core/TimeIntervalCollection', './Core/TimeStandard', './Core/Tipsify', './Core/Transforms', './Core/TranslationRotationScale', './Core/TridiagonalSystemSolver', './Core/TrustedServers', './Core/VertexFormat', './Core/VideoSynchronizer', './Core/Visibility', './Core/VRTheWorldTerrainProvider', './Core/WallGeometry', './Core/WallGeometryLibrary', './Core/WallOutlineGeometry', './Core/WebGLConstants', './Core/WebMercatorProjection', './Core/WebMercatorTilingScheme', './Core/WeightSpline', './Core/WindingOrder', './Core/wrapFunction', './Core/writeTextToCanvas', './DataSources/BillboardGraphics', './DataSources/BillboardVisualizer', './DataSources/BoundingSphereState', './DataSources/BoxGeometryUpdater', './DataSources/BoxGraphics', './DataSources/CallbackProperty', './DataSources/CheckerboardMaterialProperty', './DataSources/ColorMaterialProperty', './DataSources/CompositeEntityCollection', './DataSources/CompositeMaterialProperty', './DataSources/CompositePositionProperty', './DataSources/CompositeProperty', './DataSources/ConstantPositionProperty', './DataSources/ConstantProperty', './DataSources/CorridorGeometryUpdater', './DataSources/CorridorGraphics', './DataSources/createMaterialPropertyDescriptor', './DataSources/createPropertyDescriptor', './DataSources/createRawPropertyDescriptor', './DataSources/CustomDataSource', './DataSources/CylinderGeometryUpdater', './DataSources/CylinderGraphics', './DataSources/CzmlDataSource', './DataSources/DataSource', './DataSources/DataSourceClock', './DataSources/DataSourceCollection', './DataSources/DataSourceDisplay', './DataSources/dynamicGeometryGetBoundingSphere', './DataSources/DynamicGeometryUpdater', './DataSources/EllipseGeometryUpdater', './DataSources/EllipseGraphics', './DataSources/EllipsoidGeometryUpdater', './DataSources/EllipsoidGraphics', './DataSources/Entity', './DataSources/EntityCluster', './DataSources/EntityCollection', './DataSources/EntityView', './DataSources/GeoJsonDataSource', './DataSources/GeometryUpdater', './DataSources/GeometryVisualizer', './DataSources/GridMaterialProperty', './DataSources/ImageMaterialProperty', './DataSources/KmlCamera', './DataSources/KmlDataSource', './DataSources/KmlLookAt', './DataSources/KmlTour', './DataSources/KmlTourFlyTo', './DataSources/KmlTourWait', './DataSources/LabelGraphics', './DataSources/LabelVisualizer', './DataSources/MaterialProperty', './DataSources/ModelGraphics', './DataSources/ModelVisualizer', './DataSources/NodeTransformationProperty', './DataSources/PathGraphics', './DataSources/PathVisualizer', './DataSources/PlaneGeometryUpdater', './DataSources/PlaneGraphics', './DataSources/PointGraphics', './DataSources/PointVisualizer', './DataSources/PolygonGeometryUpdater', './DataSources/PolygonGraphics', './DataSources/PolylineArrowMaterialProperty', './DataSources/PolylineDashMaterialProperty', './DataSources/PolylineGeometryUpdater', './DataSources/PolylineGlowMaterialProperty', './DataSources/PolylineGraphics', './DataSources/PolylineOutlineMaterialProperty', './DataSources/PolylineVolumeGeometryUpdater', './DataSources/PolylineVolumeGraphics', './DataSources/PositionProperty', './DataSources/PositionPropertyArray', './DataSources/Property', './DataSources/PropertyArray', './DataSources/PropertyBag', './DataSources/RectangleGeometryUpdater', './DataSources/RectangleGraphics', './DataSources/ReferenceProperty', './DataSources/Rotation', './DataSources/SampledPositionProperty', './DataSources/SampledProperty', './DataSources/ScaledPositionProperty', './DataSources/StaticGeometryColorBatch', './DataSources/StaticGeometryPerMaterialBatch', './DataSources/StaticGroundGeometryColorBatch', './DataSources/StaticOutlineGeometryBatch', './DataSources/StripeMaterialProperty', './DataSources/StripeOrientation', './DataSources/TimeIntervalCollectionPositionProperty', './DataSources/TimeIntervalCollectionProperty', './DataSources/VelocityOrientationProperty', './DataSources/VelocityVectorProperty', './DataSources/Visualizer', './DataSources/WallGeometryUpdater', './DataSources/WallGraphics', './Renderer/AutomaticUniforms', './Renderer/Buffer', './Renderer/BufferUsage', './Renderer/ClearCommand', './Renderer/ComputeCommand', './Renderer/ComputeEngine', './Renderer/Context', './Renderer/ContextLimits', './Renderer/createUniform', './Renderer/createUniformArray', './Renderer/CubeMap', './Renderer/CubeMapFace', './Renderer/DrawCommand', './Renderer/Framebuffer', './Renderer/freezeRenderState', './Renderer/loadCubeMap', './Renderer/MipmapHint', './Renderer/modernizeShader', './Renderer/Pass', './Renderer/PassState', './Renderer/PickFramebuffer', './Renderer/PixelDatatype', './Renderer/Renderbuffer', './Renderer/RenderbufferFormat', './Renderer/RenderState', './Renderer/Sampler', './Renderer/ShaderCache', './Renderer/ShaderProgram', './Renderer/ShaderSource', './Renderer/Texture', './Renderer/TextureMagnificationFilter', './Renderer/TextureMinificationFilter', './Renderer/TextureWrap', './Renderer/UniformState', './Renderer/VertexArray', './Renderer/VertexArrayFacade', './Scene/Appearance', './Scene/ArcGisMapServerImageryProvider', './Scene/AttributeType', './Scene/Axis', './Scene/Batched3DModel3DTileContent', './Scene/BatchTable', './Scene/Billboard', './Scene/BillboardCollection', './Scene/BingMapsImageryProvider', './Scene/BingMapsStyle', './Scene/BlendEquation', './Scene/BlendFunction', './Scene/BlendingState', './Scene/BlendOption', './Scene/BoxEmitter', './Scene/BrdfLutGenerator', './Scene/Camera', './Scene/CameraEventAggregator', './Scene/CameraEventType', './Scene/CameraFlightPath', './Scene/Cesium3DTile', './Scene/Cesium3DTileBatchTable', './Scene/Cesium3DTileChildrenVisibility', './Scene/Cesium3DTileColorBlendMode', './Scene/Cesium3DTileContent', './Scene/Cesium3DTileContentFactory', './Scene/Cesium3DTileContentState', './Scene/Cesium3DTileFeature', './Scene/Cesium3DTileFeatureTable', './Scene/Cesium3DTileOptimizationHint', './Scene/Cesium3DTileOptimizations', './Scene/Cesium3DTilePointFeature', './Scene/Cesium3DTileRefine', './Scene/Cesium3DTileset', './Scene/Cesium3DTilesetStatistics', './Scene/Cesium3DTilesetTraversal', './Scene/Cesium3DTileStyle', './Scene/Cesium3DTileStyleEngine', './Scene/CesiumIon', './Scene/CesiumIonResource', './Scene/CircleEmitter', './Scene/ClassificationModel', './Scene/ClassificationPrimitive', './Scene/ClassificationType', './Scene/ColorBlendMode', './Scene/Composite3DTileContent', './Scene/ConditionsExpression', './Scene/ConeEmitter', './Scene/createBillboardPointCallback', './Scene/createOpenStreetMapImageryProvider', './Scene/createTangentSpaceDebugPrimitive', './Scene/createTileMapServiceImageryProvider', './Scene/CreditDisplay', './Scene/CullFace', './Scene/DebugAppearance', './Scene/DebugCameraPrimitive', './Scene/DebugModelMatrixPrimitive', './Scene/DepthFunction', './Scene/DepthPlane', './Scene/DeviceOrientationCameraController', './Scene/DiscardMissingTileImagePolicy', './Scene/EllipsoidPrimitive', './Scene/EllipsoidSurfaceAppearance', './Scene/Empty3DTileContent', './Scene/Expression', './Scene/ExpressionNodeType', './Scene/Fog', './Scene/FrameRateMonitor', './Scene/FrameState', './Scene/FrustumCommands', './Scene/FXAA', './Scene/Geometry3DTileContent', './Scene/getBinaryAccessor', './Scene/GetFeatureInfoFormat', './Scene/Globe', './Scene/GlobeDepth', './Scene/GlobeSurfaceShaderSet', './Scene/GlobeSurfaceTile', './Scene/GlobeSurfaceTileProvider', './Scene/GoogleEarthEnterpriseImageryProvider', './Scene/GoogleEarthEnterpriseMapsProvider', './Scene/GridImageryProvider', './Scene/GroundPrimitive', './Scene/HeightReference', './Scene/HorizontalOrigin', './Scene/Imagery', './Scene/ImageryLayer', './Scene/ImageryLayerCollection', './Scene/ImageryLayerFeatureInfo', './Scene/ImageryProvider', './Scene/ImagerySplitDirection', './Scene/ImageryState', './Scene/Instanced3DModel3DTileContent', './Scene/InvertClassification', './Scene/JobScheduler', './Scene/JobType', './Scene/Label', './Scene/LabelCollection', './Scene/LabelStyle', './Scene/MapboxImageryProvider', './Scene/MapMode2D', './Scene/Material', './Scene/MaterialAppearance', './Scene/Model', './Scene/ModelAnimation', './Scene/ModelAnimationCache', './Scene/ModelAnimationCollection', './Scene/ModelAnimationLoop', './Scene/ModelAnimationState', './Scene/ModelInstance', './Scene/ModelInstanceCollection', './Scene/ModelLoadResources', './Scene/ModelMaterial', './Scene/ModelMesh', './Scene/ModelNode', './Scene/ModelUtility', './Scene/Moon', './Scene/NeverTileDiscardPolicy', './Scene/OIT', './Scene/Particle', './Scene/ParticleBurst', './Scene/ParticleEmitter', './Scene/ParticleSystem', './Scene/PerformanceDisplay', './Scene/PerInstanceColorAppearance', './Scene/PickDepth', './Scene/PointCloud3DTileContent', './Scene/PointCloudEyeDomeLighting', './Scene/PointCloudShading', './Scene/PointPrimitive', './Scene/PointPrimitiveCollection', './Scene/Polyline', './Scene/PolylineCollection', './Scene/PolylineColorAppearance', './Scene/PolylineMaterialAppearance', './Scene/Primitive', './Scene/PrimitiveCollection', './Scene/PrimitivePipeline', './Scene/PrimitiveState', './Scene/QuadtreeOccluders', './Scene/QuadtreePrimitive', './Scene/QuadtreeTile', './Scene/QuadtreeTileLoadState', './Scene/QuadtreeTileProvider', './Scene/Scene', './Scene/SceneMode', './Scene/SceneTransforms', './Scene/SceneTransitioner', './Scene/ScreenSpaceCameraController', './Scene/ShadowMap', './Scene/ShadowMapShader', './Scene/ShadowMode', './Scene/SingleTileImageryProvider', './Scene/SkyAtmosphere', './Scene/SkyBox', './Scene/SphereEmitter', './Scene/StencilFunction', './Scene/StencilOperation', './Scene/StyleExpression', './Scene/Sun', './Scene/SunPostProcess', './Scene/TerrainState', './Scene/TextureAtlas', './Scene/TileBoundingRegion', './Scene/TileBoundingSphere', './Scene/TileBoundingVolume', './Scene/TileCoordinatesImageryProvider', './Scene/TileDiscardPolicy', './Scene/TileImagery', './Scene/TileOrientedBoundingBox', './Scene/TileReplacementQueue', './Scene/Tileset3DTileContent', './Scene/TileState', './Scene/TileTerrain', './Scene/TimeDynamicImagery', './Scene/TweenCollection', './Scene/UrlTemplateImageryProvider', './Scene/Vector3DTileBatch', './Scene/Vector3DTileContent', './Scene/Vector3DTileGeometry', './Scene/Vector3DTilePoints', './Scene/Vector3DTilePolygons', './Scene/Vector3DTilePolylines', './Scene/Vector3DTilePrimitive', './Scene/VerticalOrigin', './Scene/ViewportQuad', './Scene/WebMapServiceImageryProvider', './Scene/WebMapTileServiceImageryProvider', './Shaders/AdjustTranslucentFS', './Shaders/Appearances/AllMaterialAppearanceFS', './Shaders/Appearances/AllMaterialAppearanceVS', './Shaders/Appearances/BasicMaterialAppearanceFS', './Shaders/Appearances/BasicMaterialAppearanceVS', './Shaders/Appearances/EllipsoidSurfaceAppearanceFS', './Shaders/Appearances/EllipsoidSurfaceAppearanceVS', './Shaders/Appearances/PerInstanceColorAppearanceFS', './Shaders/Appearances/PerInstanceColorAppearanceVS', './Shaders/Appearances/PerInstanceFlatColorAppearanceFS', './Shaders/Appearances/PerInstanceFlatColorAppearanceVS', './Shaders/Appearances/PolylineColorAppearanceVS', './Shaders/Appearances/PolylineMaterialAppearanceVS', './Shaders/Appearances/TexturedMaterialAppearanceFS', './Shaders/Appearances/TexturedMaterialAppearanceVS', './Shaders/BillboardCollectionFS', './Shaders/BillboardCollectionVS', './Shaders/BrdfLutGeneratorFS', './Shaders/Builtin/Constants/degreesPerRadian', './Shaders/Builtin/Constants/depthRange', './Shaders/Builtin/Constants/epsilon1', './Shaders/Builtin/Constants/epsilon2', './Shaders/Builtin/Constants/epsilon3', './Shaders/Builtin/Constants/epsilon4', './Shaders/Builtin/Constants/epsilon5', './Shaders/Builtin/Constants/epsilon6', './Shaders/Builtin/Constants/epsilon7', './Shaders/Builtin/Constants/infinity', './Shaders/Builtin/Constants/maxClippingPlanes', './Shaders/Builtin/Constants/oneOverPi', './Shaders/Builtin/Constants/oneOverTwoPi', './Shaders/Builtin/Constants/passCesium3DTile', './Shaders/Builtin/Constants/passCesium3DTileClassification', './Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow', './Shaders/Builtin/Constants/passClassification', './Shaders/Builtin/Constants/passCompute', './Shaders/Builtin/Constants/passEnvironment', './Shaders/Builtin/Constants/passGlobe', './Shaders/Builtin/Constants/passOpaque', './Shaders/Builtin/Constants/passOverlay', './Shaders/Builtin/Constants/passTerrainClassification', './Shaders/Builtin/Constants/passTranslucent', './Shaders/Builtin/Constants/pi', './Shaders/Builtin/Constants/piOverFour', './Shaders/Builtin/Constants/piOverSix', './Shaders/Builtin/Constants/piOverThree', './Shaders/Builtin/Constants/piOverTwo', './Shaders/Builtin/Constants/radiansPerDegree', './Shaders/Builtin/Constants/sceneMode2D', './Shaders/Builtin/Constants/sceneMode3D', './Shaders/Builtin/Constants/sceneModeColumbusView', './Shaders/Builtin/Constants/sceneModeMorphing', './Shaders/Builtin/Constants/solarRadius', './Shaders/Builtin/Constants/threePiOver2', './Shaders/Builtin/Constants/twoPi', './Shaders/Builtin/Constants/webMercatorMaxLatitude', './Shaders/Builtin/CzmBuiltins', './Shaders/Builtin/Functions/alphaWeight', './Shaders/Builtin/Functions/antialias', './Shaders/Builtin/Functions/cascadeColor', './Shaders/Builtin/Functions/cascadeDistance', './Shaders/Builtin/Functions/cascadeMatrix', './Shaders/Builtin/Functions/cascadeWeights', './Shaders/Builtin/Functions/columbusViewMorph', './Shaders/Builtin/Functions/computePosition', './Shaders/Builtin/Functions/cosineAndSine', './Shaders/Builtin/Functions/decompressTextureCoordinates', './Shaders/Builtin/Functions/depthClampFarPlane', './Shaders/Builtin/Functions/discardIfClippedWithIntersect', './Shaders/Builtin/Functions/discardIfClippedWithUnion', './Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates', './Shaders/Builtin/Functions/ellipsoidContainsPoint', './Shaders/Builtin/Functions/ellipsoidNew', './Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates', './Shaders/Builtin/Functions/equalsEpsilon', './Shaders/Builtin/Functions/eyeOffset', './Shaders/Builtin/Functions/eyeToWindowCoordinates', './Shaders/Builtin/Functions/fog', './Shaders/Builtin/Functions/geodeticSurfaceNormal', './Shaders/Builtin/Functions/getDefaultMaterial', './Shaders/Builtin/Functions/getLambertDiffuse', './Shaders/Builtin/Functions/getSpecular', './Shaders/Builtin/Functions/getWaterNoise', './Shaders/Builtin/Functions/getWgs84EllipsoidEC', './Shaders/Builtin/Functions/HSBToRGB', './Shaders/Builtin/Functions/HSLToRGB', './Shaders/Builtin/Functions/hue', './Shaders/Builtin/Functions/isEmpty', './Shaders/Builtin/Functions/isFull', './Shaders/Builtin/Functions/latitudeToWebMercatorFraction', './Shaders/Builtin/Functions/luminance', './Shaders/Builtin/Functions/metersPerPixel', './Shaders/Builtin/Functions/modelToWindowCoordinates', './Shaders/Builtin/Functions/multiplyWithColorBalance', './Shaders/Builtin/Functions/nearFarScalar', './Shaders/Builtin/Functions/octDecode', './Shaders/Builtin/Functions/packDepth', './Shaders/Builtin/Functions/phong', './Shaders/Builtin/Functions/pointAlongRay', './Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval', './Shaders/Builtin/Functions/RGBToHSB', './Shaders/Builtin/Functions/RGBToHSL', './Shaders/Builtin/Functions/RGBToXYZ', './Shaders/Builtin/Functions/saturation', './Shaders/Builtin/Functions/shadowDepthCompare', './Shaders/Builtin/Functions/shadowVisibility', './Shaders/Builtin/Functions/signNotZero', './Shaders/Builtin/Functions/tangentToEyeSpaceMatrix', './Shaders/Builtin/Functions/translateRelativeToEye', './Shaders/Builtin/Functions/translucentPhong', './Shaders/Builtin/Functions/transpose', './Shaders/Builtin/Functions/unpackDepth', './Shaders/Builtin/Functions/windowToEyeCoordinates', './Shaders/Builtin/Functions/writeDepthClampedToFarPlane', './Shaders/Builtin/Functions/XYZToRGB', './Shaders/Builtin/Structs/depthRangeStruct', './Shaders/Builtin/Structs/ellipsoid', './Shaders/Builtin/Structs/material', './Shaders/Builtin/Structs/materialInput', './Shaders/Builtin/Structs/ray', './Shaders/Builtin/Structs/raySegment', './Shaders/Builtin/Structs/shadowParameters', './Shaders/CompositeOITFS', './Shaders/DepthPlaneFS', './Shaders/DepthPlaneVS', './Shaders/EllipsoidFS', './Shaders/EllipsoidVS', './Shaders/GlobeFS', './Shaders/GlobeVS', './Shaders/GroundAtmosphere', './Shaders/Materials/BumpMapMaterial', './Shaders/Materials/CheckerboardMaterial', './Shaders/Materials/DotMaterial', './Shaders/Materials/ElevationContourMaterial', './Shaders/Materials/ElevationRampMaterial', './Shaders/Materials/FadeMaterial', './Shaders/Materials/GridMaterial', './Shaders/Materials/NormalMapMaterial', './Shaders/Materials/PolylineArrowMaterial', './Shaders/Materials/PolylineDashMaterial', './Shaders/Materials/PolylineGlowMaterial', './Shaders/Materials/PolylineOutlineMaterial', './Shaders/Materials/RimLightingMaterial', './Shaders/Materials/SlopeRampMaterial', './Shaders/Materials/StripeMaterial', './Shaders/Materials/Water', './Shaders/PointPrimitiveCollectionFS', './Shaders/PointPrimitiveCollectionVS', './Shaders/PolylineCommon', './Shaders/PolylineFS', './Shaders/PolylineVS', './Shaders/PostProcessFilters/AdditiveBlend', './Shaders/PostProcessFilters/BrightPass', './Shaders/PostProcessFilters/FXAA', './Shaders/PostProcessFilters/GaussianBlur1D', './Shaders/PostProcessFilters/PassThrough', './Shaders/PostProcessFilters/PointCloudEyeDomeLighting', './Shaders/ReprojectWebMercatorFS', './Shaders/ReprojectWebMercatorVS', './Shaders/ShadowVolumeFS', './Shaders/ShadowVolumeVS', './Shaders/SkyAtmosphereFS', './Shaders/SkyAtmosphereVS', './Shaders/SkyBoxFS', './Shaders/SkyBoxVS', './Shaders/SunFS', './Shaders/SunTextureFS', './Shaders/SunVS', './Shaders/Vector3DTilePolylinesVS', './Shaders/ViewportQuadFS', './Shaders/ViewportQuadVS', './ThirdParty/Autolinker', './ThirdParty/crunch', './ThirdParty/earcut-2.1.1', './ThirdParty/GltfPipeline/addDefaults', './ThirdParty/GltfPipeline/addExtensionsRequired', './ThirdParty/GltfPipeline/addExtensionsUsed', './ThirdParty/GltfPipeline/addPipelineExtras', './ThirdParty/GltfPipeline/addToArray', './ThirdParty/GltfPipeline/byteLengthForComponentType', './ThirdParty/GltfPipeline/findAccessorMinMax', './ThirdParty/GltfPipeline/ForEach', './ThirdParty/GltfPipeline/getAccessorByteStride', './ThirdParty/GltfPipeline/getJointCountForMaterials', './ThirdParty/GltfPipeline/glslTypeToWebGLConstant', './ThirdParty/GltfPipeline/numberOfComponentsForType', './ThirdParty/GltfPipeline/parseBinaryGltf', './ThirdParty/GltfPipeline/processModelMaterialsCommon', './ThirdParty/GltfPipeline/processPbrMetallicRoughness', './ThirdParty/GltfPipeline/removeExtensionsRequired', './ThirdParty/GltfPipeline/removeExtensionsUsed', './ThirdParty/GltfPipeline/removePipelineExtras', './ThirdParty/GltfPipeline/techniqueParameterForSemantic', './ThirdParty/GltfPipeline/updateVersion', './ThirdParty/GltfPipeline/webGLConstantToGlslType', './ThirdParty/google-earth-dbroot-parser', './ThirdParty/jsep', './ThirdParty/kdbush', './ThirdParty/knockout-3.4.2', './ThirdParty/knockout-es5', './ThirdParty/knockout', './ThirdParty/measureText', './ThirdParty/mersenne-twister', './ThirdParty/NoSleep', './ThirdParty/pako_inflate', './ThirdParty/protobuf-minimal', './ThirdParty/Shaders/FXAA3_11', './ThirdParty/sprintf', './ThirdParty/topojson', './ThirdParty/Tween', './ThirdParty/Uri', './ThirdParty/when', './ThirdParty/zip', './Widgets/Animation/Animation', './Widgets/Animation/AnimationViewModel', './Widgets/BaseLayerPicker/BaseLayerPicker', './Widgets/BaseLayerPicker/BaseLayerPickerViewModel', './Widgets/BaseLayerPicker/createDefaultImageryProviderViewModels', './Widgets/BaseLayerPicker/createDefaultTerrainProviderViewModels', './Widgets/BaseLayerPicker/ProviderViewModel', './Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector', './Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel', './Widgets/CesiumInspector/CesiumInspector', './Widgets/CesiumInspector/CesiumInspectorViewModel', './Widgets/CesiumWidget/CesiumWidget', './Widgets/ClockViewModel', './Widgets/Command', './Widgets/createCommand', './Widgets/FullscreenButton/FullscreenButton', './Widgets/FullscreenButton/FullscreenButtonViewModel', './Widgets/Geocoder/Geocoder', './Widgets/Geocoder/GeocoderViewModel', './Widgets/getElement', './Widgets/HomeButton/HomeButton', './Widgets/HomeButton/HomeButtonViewModel', './Widgets/InfoBox/InfoBox', './Widgets/InfoBox/InfoBoxViewModel', './Widgets/NavigationHelpButton/NavigationHelpButton', './Widgets/NavigationHelpButton/NavigationHelpButtonViewModel', './Widgets/PerformanceWatchdog/PerformanceWatchdog', './Widgets/PerformanceWatchdog/PerformanceWatchdogViewModel', './Widgets/ProjectionPicker/ProjectionPicker', './Widgets/ProjectionPicker/ProjectionPickerViewModel', './Widgets/SceneModePicker/SceneModePicker', './Widgets/SceneModePicker/SceneModePickerViewModel', './Widgets/SelectionIndicator/SelectionIndicator', './Widgets/SelectionIndicator/SelectionIndicatorViewModel', './Widgets/subscribeAndEvaluate', './Widgets/SvgPathBindingHandler', './Widgets/Timeline/Timeline', './Widgets/Timeline/TimelineHighlightRange', './Widgets/Timeline/TimelineTrack', './Widgets/ToggleButtonViewModel', './Widgets/Viewer/Viewer', './Widgets/Viewer/viewerCesium3DTilesInspectorMixin', './Widgets/Viewer/viewerCesiumInspectorMixin', './Widgets/Viewer/viewerDragDropMixin', './Widgets/Viewer/viewerPerformanceWatchdogMixin', './Widgets/VRButton/VRButton', './Widgets/VRButton/VRButtonViewModel', './Workers/createTaskProcessorWorker'], function(Core_appendForwardSlash, Core_arrayFill, Core_arrayRemoveDuplicates, Core_arraySlice, Core_AssociativeArray, Core_AttributeCompression, Core_AxisAlignedBoundingBox, Core_barycentricCoordinates, Core_binarySearch, Core_BingMapsApi, Core_BingMapsGeocoderService, Core_BoundingRectangle, Core_BoundingSphere, Core_BoxGeometry, Core_BoxOutlineGeometry, Core_buildModuleUrl, Core_cancelAnimationFrame, Core_Cartesian2, Core_Cartesian3, Core_Cartesian4, Core_Cartographic, Core_CartographicGeocoderService, Core_CatmullRomSpline, Core_CesiumTerrainProvider, Core_Check, Core_CircleGeometry, Core_CircleOutlineGeometry, Core_ClippingPlaneCollection, Core_Clock, Core_ClockRange, Core_ClockStep, Core_clone, Core_Color, Core_ColorGeometryInstanceAttribute, Core_combine, Core_ComponentDatatype, Core_CompressedTextureBuffer, Core_CornerType, Core_CorridorGeometry, Core_CorridorGeometryLibrary, Core_CorridorOutlineGeometry, Core_createGuid, Core_Credit, Core_CubicRealPolynomial, Core_CullingVolume, Core_CylinderGeometry, Core_CylinderGeometryLibrary, Core_CylinderOutlineGeometry, Core_decodeGoogleEarthEnterpriseData, Core_DefaultProxy, Core_defaultValue, Core_defined, Core_defineProperties, Core_deprecationWarning, Core_destroyObject, Core_DeveloperError, Core_DistanceDisplayCondition, Core_DistanceDisplayConditionGeometryInstanceAttribute, Core_DoublyLinkedList, Core_EarthOrientationParameters, Core_EarthOrientationParametersSample, Core_EasingFunction, Core_EllipseGeometry, Core_EllipseGeometryLibrary, Core_EllipseOutlineGeometry, Core_Ellipsoid, Core_EllipsoidalOccluder, Core_EllipsoidGeodesic, Core_EllipsoidGeometry, Core_EllipsoidOutlineGeometry, Core_EllipsoidTangentPlane, Core_EllipsoidTerrainProvider, Core_EncodedCartesian3, Core_Event, Core_EventHelper, Core_ExtrapolationType, Core_FeatureDetection, Core_formatError, Core_freezeObject, Core_FrustumGeometry, Core_FrustumOutlineGeometry, Core_Fullscreen, Core_GeocoderService, Core_GeographicProjection, Core_GeographicTilingScheme, Core_Geometry, Core_GeometryAttribute, Core_GeometryAttributes, Core_GeometryInstance, Core_GeometryInstanceAttribute, Core_GeometryPipeline, Core_GeometryType, Core_getAbsoluteUri, Core_getBaseUri, Core_getExtensionFromUri, Core_getFilenameFromUri, Core_getImagePixels, Core_getMagic, Core_getStringFromTypedArray, Core_getTimestamp, Core_GoogleEarthEnterpriseMetadata, Core_GoogleEarthEnterpriseTerrainData, Core_GoogleEarthEnterpriseTerrainProvider, Core_GoogleEarthEnterpriseTileInformation, Core_GregorianDate, Core_HeadingPitchRange, Core_HeadingPitchRoll, Core_Heap, Core_HeightmapTerrainData, Core_HeightmapTessellator, Core_HermitePolynomialApproximation, Core_HermiteSpline, Core_Iau2000Orientation, Core_Iau2006XysData, Core_Iau2006XysSample, Core_IauOrientationAxes, Core_IauOrientationParameters, Core_IndexDatatype, Core_InterpolationAlgorithm, Core_Intersect, Core_Intersections2D, Core_IntersectionTests, Core_Interval, Core_isArray, Core_isBitSet, Core_isBlobUri, Core_isCrossOriginUrl, Core_isDataUri, Core_isLeapYear, Core_Iso8601, Core_JulianDate, Core_KeyboardEventModifier, Core_LagrangePolynomialApproximation, Core_LeapSecond, Core_LinearApproximation, Core_LinearSpline, Core_loadArrayBuffer, Core_loadBlob, Core_loadCRN, Core_loadImage, Core_loadImageFromTypedArray, Core_loadImageViaBlob, Core_loadJson, Core_loadJsonp, Core_loadKTX, Core_loadText, Core_loadWithXhr, Core_loadXML, Core_ManagedArray, Core_MapboxApi, Core_MapProjection, Core_Math, Core_Matrix2, Core_Matrix3, Core_Matrix4, Core_mergeSort, Core_NearFarScalar, Core_objectToQuery, Core_Occluder, Core_oneTimeWarning, Core_OrientedBoundingBox, Core_OrthographicFrustum, Core_OrthographicOffCenterFrustum, Core_Packable, Core_PackableForInterpolation, Core_parseResponseHeaders, Core_PerspectiveFrustum, Core_PerspectiveOffCenterFrustum, Core_PinBuilder, Core_PixelFormat, Core_Plane, Core_PlaneGeometry, Core_PlaneOutlineGeometry, Core_pointInsideTriangle, Core_PolygonGeometry, Core_PolygonGeometryLibrary, Core_PolygonHierarchy, Core_PolygonOutlineGeometry, Core_PolygonPipeline, Core_PolylineGeometry, Core_PolylinePipeline, Core_PolylineVolumeGeometry, Core_PolylineVolumeGeometryLibrary, Core_PolylineVolumeOutlineGeometry, Core_PrimitiveType, Core_QuadraticRealPolynomial, Core_QuantizedMeshTerrainData, Core_QuarticRealPolynomial, Core_Quaternion, Core_QuaternionSpline, Core_queryToObject, Core_Queue, Core_Ray, Core_Rectangle, Core_RectangleGeometry, Core_RectangleGeometryLibrary, Core_RectangleOutlineGeometry, Core_ReferenceFrame, Core_Request, Core_requestAnimationFrame, Core_RequestErrorEvent, Core_RequestScheduler, Core_RequestState, Core_RequestType, Core_Resource, Core_RuntimeError, Core_sampleTerrain, Core_sampleTerrainMostDetailed, Core_scaleToGeodeticSurface, Core_ScreenSpaceEventHandler, Core_ScreenSpaceEventType, Core_ShowGeometryInstanceAttribute, Core_Simon1994PlanetaryPositions, Core_SimplePolylineGeometry, Core_SphereGeometry, Core_SphereOutlineGeometry, Core_Spherical, Core_Spline, Core_subdivideArray, Core_TaskProcessor, Core_TerrainData, Core_TerrainEncoding, Core_TerrainMesh, Core_TerrainProvider, Core_TerrainQuantization, Core_TileAvailability, Core_TileProviderError, Core_TilingScheme, Core_TimeConstants, Core_TimeInterval, Core_TimeIntervalCollection, Core_TimeStandard, Core_Tipsify, Core_Transforms, Core_TranslationRotationScale, Core_TridiagonalSystemSolver, Core_TrustedServers, Core_VertexFormat, Core_VideoSynchronizer, Core_Visibility, Core_VRTheWorldTerrainProvider, Core_WallGeometry, Core_WallGeometryLibrary, Core_WallOutlineGeometry, Core_WebGLConstants, Core_WebMercatorProjection, Core_WebMercatorTilingScheme, Core_WeightSpline, Core_WindingOrder, Core_wrapFunction, Core_writeTextToCanvas, DataSources_BillboardGraphics, DataSources_BillboardVisualizer, DataSources_BoundingSphereState, DataSources_BoxGeometryUpdater, DataSources_BoxGraphics, DataSources_CallbackProperty, DataSources_CheckerboardMaterialProperty, DataSources_ColorMaterialProperty, DataSources_CompositeEntityCollection, DataSources_CompositeMaterialProperty, DataSources_CompositePositionProperty, DataSources_CompositeProperty, DataSources_ConstantPositionProperty, DataSources_ConstantProperty, DataSources_CorridorGeometryUpdater, DataSources_CorridorGraphics, DataSources_createMaterialPropertyDescriptor, DataSources_createPropertyDescriptor, DataSources_createRawPropertyDescriptor, DataSources_CustomDataSource, DataSources_CylinderGeometryUpdater, DataSources_CylinderGraphics, DataSources_CzmlDataSource, DataSources_DataSource, DataSources_DataSourceClock, DataSources_DataSourceCollection, DataSources_DataSourceDisplay, DataSources_dynamicGeometryGetBoundingSphere, DataSources_DynamicGeometryUpdater, DataSources_EllipseGeometryUpdater, DataSources_EllipseGraphics, DataSources_EllipsoidGeometryUpdater, DataSources_EllipsoidGraphics, DataSources_Entity, DataSources_EntityCluster, DataSources_EntityCollection, DataSources_EntityView, DataSources_GeoJsonDataSource, DataSources_GeometryUpdater, DataSources_GeometryVisualizer, DataSources_GridMaterialProperty, DataSources_ImageMaterialProperty, DataSources_KmlCamera, DataSources_KmlDataSource, DataSources_KmlLookAt, DataSources_KmlTour, DataSources_KmlTourFlyTo, DataSources_KmlTourWait, DataSources_LabelGraphics, DataSources_LabelVisualizer, DataSources_MaterialProperty, DataSources_ModelGraphics, DataSources_ModelVisualizer, DataSources_NodeTransformationProperty, DataSources_PathGraphics, DataSources_PathVisualizer, DataSources_PlaneGeometryUpdater, DataSources_PlaneGraphics, DataSources_PointGraphics, DataSources_PointVisualizer, DataSources_PolygonGeometryUpdater, DataSources_PolygonGraphics, DataSources_PolylineArrowMaterialProperty, DataSources_PolylineDashMaterialProperty, DataSources_PolylineGeometryUpdater, DataSources_PolylineGlowMaterialProperty, DataSources_PolylineGraphics, DataSources_PolylineOutlineMaterialProperty, DataSources_PolylineVolumeGeometryUpdater, DataSources_PolylineVolumeGraphics, DataSources_PositionProperty, DataSources_PositionPropertyArray, DataSources_Property, DataSources_PropertyArray, DataSources_PropertyBag, DataSources_RectangleGeometryUpdater, DataSources_RectangleGraphics, DataSources_ReferenceProperty, DataSources_Rotation, DataSources_SampledPositionProperty, DataSources_SampledProperty, DataSources_ScaledPositionProperty, DataSources_StaticGeometryColorBatch, DataSources_StaticGeometryPerMaterialBatch, DataSources_StaticGroundGeometryColorBatch, DataSources_StaticOutlineGeometryBatch, DataSources_StripeMaterialProperty, DataSources_StripeOrientation, DataSources_TimeIntervalCollectionPositionProperty, DataSources_TimeIntervalCollectionProperty, DataSources_VelocityOrientationProperty, DataSources_VelocityVectorProperty, DataSources_Visualizer, DataSources_WallGeometryUpdater, DataSources_WallGraphics, Renderer_AutomaticUniforms, Renderer_Buffer, Renderer_BufferUsage, Renderer_ClearCommand, Renderer_ComputeCommand, Renderer_ComputeEngine, Renderer_Context, Renderer_ContextLimits, Renderer_createUniform, Renderer_createUniformArray, Renderer_CubeMap, Renderer_CubeMapFace, Renderer_DrawCommand, Renderer_Framebuffer, Renderer_freezeRenderState, Renderer_loadCubeMap, Renderer_MipmapHint, Renderer_modernizeShader, Renderer_Pass, Renderer_PassState, Renderer_PickFramebuffer, Renderer_PixelDatatype, Renderer_Renderbuffer, Renderer_RenderbufferFormat, Renderer_RenderState, Renderer_Sampler, Renderer_ShaderCache, Renderer_ShaderProgram, Renderer_ShaderSource, Renderer_Texture, Renderer_TextureMagnificationFilter, Renderer_TextureMinificationFilter, Renderer_TextureWrap, Renderer_UniformState, Renderer_VertexArray, Renderer_VertexArrayFacade, Scene_Appearance, Scene_ArcGisMapServerImageryProvider, Scene_AttributeType, Scene_Axis, Scene_Batched3DModel3DTileContent, Scene_BatchTable, Scene_Billboard, Scene_BillboardCollection, Scene_BingMapsImageryProvider, Scene_BingMapsStyle, Scene_BlendEquation, Scene_BlendFunction, Scene_BlendingState, Scene_BlendOption, Scene_BoxEmitter, Scene_BrdfLutGenerator, Scene_Camera, Scene_CameraEventAggregator, Scene_CameraEventType, Scene_CameraFlightPath, Scene_Cesium3DTile, Scene_Cesium3DTileBatchTable, Scene_Cesium3DTileChildrenVisibility, Scene_Cesium3DTileColorBlendMode, Scene_Cesium3DTileContent, Scene_Cesium3DTileContentFactory, Scene_Cesium3DTileContentState, Scene_Cesium3DTileFeature, Scene_Cesium3DTileFeatureTable, Scene_Cesium3DTileOptimizationHint, Scene_Cesium3DTileOptimizations, Scene_Cesium3DTilePointFeature, Scene_Cesium3DTileRefine, Scene_Cesium3DTileset, Scene_Cesium3DTilesetStatistics, Scene_Cesium3DTilesetTraversal, Scene_Cesium3DTileStyle, Scene_Cesium3DTileStyleEngine, Scene_CesiumIon, Scene_CesiumIonResource, Scene_CircleEmitter, Scene_ClassificationModel, Scene_ClassificationPrimitive, Scene_ClassificationType, Scene_ColorBlendMode, Scene_Composite3DTileContent, Scene_ConditionsExpression, Scene_ConeEmitter, Scene_createBillboardPointCallback, Scene_createOpenStreetMapImageryProvider, Scene_createTangentSpaceDebugPrimitive, Scene_createTileMapServiceImageryProvider, Scene_CreditDisplay, Scene_CullFace, Scene_DebugAppearance, Scene_DebugCameraPrimitive, Scene_DebugModelMatrixPrimitive, Scene_DepthFunction, Scene_DepthPlane, Scene_DeviceOrientationCameraController, Scene_DiscardMissingTileImagePolicy, Scene_EllipsoidPrimitive, Scene_EllipsoidSurfaceAppearance, Scene_Empty3DTileContent, Scene_Expression, Scene_ExpressionNodeType, Scene_Fog, Scene_FrameRateMonitor, Scene_FrameState, Scene_FrustumCommands, Scene_FXAA, Scene_Geometry3DTileContent, Scene_getBinaryAccessor, Scene_GetFeatureInfoFormat, Scene_Globe, Scene_GlobeDepth, Scene_GlobeSurfaceShaderSet, Scene_GlobeSurfaceTile, Scene_GlobeSurfaceTileProvider, Scene_GoogleEarthEnterpriseImageryProvider, Scene_GoogleEarthEnterpriseMapsProvider, Scene_GridImageryProvider, Scene_GroundPrimitive, Scene_HeightReference, Scene_HorizontalOrigin, Scene_Imagery, Scene_ImageryLayer, Scene_ImageryLayerCollection, Scene_ImageryLayerFeatureInfo, Scene_ImageryProvider, Scene_ImagerySplitDirection, Scene_ImageryState, Scene_Instanced3DModel3DTileContent, Scene_InvertClassification, Scene_JobScheduler, Scene_JobType, Scene_Label, Scene_LabelCollection, Scene_LabelStyle, Scene_MapboxImageryProvider, Scene_MapMode2D, Scene_Material, Scene_MaterialAppearance, Scene_Model, Scene_ModelAnimation, Scene_ModelAnimationCache, Scene_ModelAnimationCollection, Scene_ModelAnimationLoop, Scene_ModelAnimationState, Scene_ModelInstance, Scene_ModelInstanceCollection, Scene_ModelLoadResources, Scene_ModelMaterial, Scene_ModelMesh, Scene_ModelNode, Scene_ModelUtility, Scene_Moon, Scene_NeverTileDiscardPolicy, Scene_OIT, Scene_Particle, Scene_ParticleBurst, Scene_ParticleEmitter, Scene_ParticleSystem, Scene_PerformanceDisplay, Scene_PerInstanceColorAppearance, Scene_PickDepth, Scene_PointCloud3DTileContent, Scene_PointCloudEyeDomeLighting, Scene_PointCloudShading, Scene_PointPrimitive, Scene_PointPrimitiveCollection, Scene_Polyline, Scene_PolylineCollection, Scene_PolylineColorAppearance, Scene_PolylineMaterialAppearance, Scene_Primitive, Scene_PrimitiveCollection, Scene_PrimitivePipeline, Scene_PrimitiveState, Scene_QuadtreeOccluders, Scene_QuadtreePrimitive, Scene_QuadtreeTile, Scene_QuadtreeTileLoadState, Scene_QuadtreeTileProvider, Scene_Scene, Scene_SceneMode, Scene_SceneTransforms, Scene_SceneTransitioner, Scene_ScreenSpaceCameraController, Scene_ShadowMap, Scene_ShadowMapShader, Scene_ShadowMode, Scene_SingleTileImageryProvider, Scene_SkyAtmosphere, Scene_SkyBox, Scene_SphereEmitter, Scene_StencilFunction, Scene_StencilOperation, Scene_StyleExpression, Scene_Sun, Scene_SunPostProcess, Scene_TerrainState, Scene_TextureAtlas, Scene_TileBoundingRegion, Scene_TileBoundingSphere, Scene_TileBoundingVolume, Scene_TileCoordinatesImageryProvider, Scene_TileDiscardPolicy, Scene_TileImagery, Scene_TileOrientedBoundingBox, Scene_TileReplacementQueue, Scene_Tileset3DTileContent, Scene_TileState, Scene_TileTerrain, Scene_TimeDynamicImagery, Scene_TweenCollection, Scene_UrlTemplateImageryProvider, Scene_Vector3DTileBatch, Scene_Vector3DTileContent, Scene_Vector3DTileGeometry, Scene_Vector3DTilePoints, Scene_Vector3DTilePolygons, Scene_Vector3DTilePolylines, Scene_Vector3DTilePrimitive, Scene_VerticalOrigin, Scene_ViewportQuad, Scene_WebMapServiceImageryProvider, Scene_WebMapTileServiceImageryProvider, Shaders_AdjustTranslucentFS, Shaders_Appearances_AllMaterialAppearanceFS, Shaders_Appearances_AllMaterialAppearanceVS, Shaders_Appearances_BasicMaterialAppearanceFS, Shaders_Appearances_BasicMaterialAppearanceVS, Shaders_Appearances_EllipsoidSurfaceAppearanceFS, Shaders_Appearances_EllipsoidSurfaceAppearanceVS, Shaders_Appearances_PerInstanceColorAppearanceFS, Shaders_Appearances_PerInstanceColorAppearanceVS, Shaders_Appearances_PerInstanceFlatColorAppearanceFS, Shaders_Appearances_PerInstanceFlatColorAppearanceVS, Shaders_Appearances_PolylineColorAppearanceVS, Shaders_Appearances_PolylineMaterialAppearanceVS, Shaders_Appearances_TexturedMaterialAppearanceFS, Shaders_Appearances_TexturedMaterialAppearanceVS, Shaders_BillboardCollectionFS, Shaders_BillboardCollectionVS, Shaders_BrdfLutGeneratorFS, Shaders_Builtin_Constants_degreesPerRadian, Shaders_Builtin_Constants_depthRange, Shaders_Builtin_Constants_epsilon1, Shaders_Builtin_Constants_epsilon2, Shaders_Builtin_Constants_epsilon3, Shaders_Builtin_Constants_epsilon4, Shaders_Builtin_Constants_epsilon5, Shaders_Builtin_Constants_epsilon6, Shaders_Builtin_Constants_epsilon7, Shaders_Builtin_Constants_infinity, Shaders_Builtin_Constants_maxClippingPlanes, Shaders_Builtin_Constants_oneOverPi, Shaders_Builtin_Constants_oneOverTwoPi, Shaders_Builtin_Constants_passCesium3DTile, Shaders_Builtin_Constants_passCesium3DTileClassification, Shaders_Builtin_Constants_passCesium3DTileClassificationIgnoreShow, Shaders_Builtin_Constants_passClassification, Shaders_Builtin_Constants_passCompute, Shaders_Builtin_Constants_passEnvironment, Shaders_Builtin_Constants_passGlobe, Shaders_Builtin_Constants_passOpaque, Shaders_Builtin_Constants_passOverlay, Shaders_Builtin_Constants_passTerrainClassification, Shaders_Builtin_Constants_passTranslucent, Shaders_Builtin_Constants_pi, Shaders_Builtin_Constants_piOverFour, Shaders_Builtin_Constants_piOverSix, Shaders_Builtin_Constants_piOverThree, Shaders_Builtin_Constants_piOverTwo, Shaders_Builtin_Constants_radiansPerDegree, Shaders_Builtin_Constants_sceneMode2D, Shaders_Builtin_Constants_sceneMode3D, Shaders_Builtin_Constants_sceneModeColumbusView, Shaders_Builtin_Constants_sceneModeMorphing, Shaders_Builtin_Constants_solarRadius, Shaders_Builtin_Constants_threePiOver2, Shaders_Builtin_Constants_twoPi, Shaders_Builtin_Constants_webMercatorMaxLatitude, Shaders_Builtin_CzmBuiltins, Shaders_Builtin_Functions_alphaWeight, Shaders_Builtin_Functions_antialias, Shaders_Builtin_Functions_cascadeColor, Shaders_Builtin_Functions_cascadeDistance, Shaders_Builtin_Functions_cascadeMatrix, Shaders_Builtin_Functions_cascadeWeights, Shaders_Builtin_Functions_columbusViewMorph, Shaders_Builtin_Functions_computePosition, Shaders_Builtin_Functions_cosineAndSine, Shaders_Builtin_Functions_decompressTextureCoordinates, Shaders_Builtin_Functions_depthClampFarPlane, Shaders_Builtin_Functions_discardIfClippedWithIntersect, Shaders_Builtin_Functions_discardIfClippedWithUnion, Shaders_Builtin_Functions_eastNorthUpToEyeCoordinates, Shaders_Builtin_Functions_ellipsoidContainsPoint, Shaders_Builtin_Functions_ellipsoidNew, Shaders_Builtin_Functions_ellipsoidWgs84TextureCoordinates, Shaders_Builtin_Functions_equalsEpsilon, Shaders_Builtin_Functions_eyeOffset, Shaders_Builtin_Functions_eyeToWindowCoordinates, Shaders_Builtin_Functions_fog, Shaders_Builtin_Functions_geodeticSurfaceNormal, Shaders_Builtin_Functions_getDefaultMaterial, Shaders_Builtin_Functions_getLambertDiffuse, Shaders_Builtin_Functions_getSpecular, Shaders_Builtin_Functions_getWaterNoise, Shaders_Builtin_Functions_getWgs84EllipsoidEC, Shaders_Builtin_Functions_HSBToRGB, Shaders_Builtin_Functions_HSLToRGB, Shaders_Builtin_Functions_hue, Shaders_Builtin_Functions_isEmpty, Shaders_Builtin_Functions_isFull, Shaders_Builtin_Functions_latitudeToWebMercatorFraction, Shaders_Builtin_Functions_luminance, Shaders_Builtin_Functions_metersPerPixel, Shaders_Builtin_Functions_modelToWindowCoordinates, Shaders_Builtin_Functions_multiplyWithColorBalance, Shaders_Builtin_Functions_nearFarScalar, Shaders_Builtin_Functions_octDecode, Shaders_Builtin_Functions_packDepth, Shaders_Builtin_Functions_phong, Shaders_Builtin_Functions_pointAlongRay, Shaders_Builtin_Functions_rayEllipsoidIntersectionInterval, Shaders_Builtin_Functions_RGBToHSB, Shaders_Builtin_Functions_RGBToHSL, Shaders_Builtin_Functions_RGBToXYZ, Shaders_Builtin_Functions_saturation, Shaders_Builtin_Functions_shadowDepthCompare, Shaders_Builtin_Functions_shadowVisibility, Shaders_Builtin_Functions_signNotZero, Shaders_Builtin_Functions_tangentToEyeSpaceMatrix, Shaders_Builtin_Functions_translateRelativeToEye, Shaders_Builtin_Functions_translucentPhong, Shaders_Builtin_Functions_transpose, Shaders_Builtin_Functions_unpackDepth, Shaders_Builtin_Functions_windowToEyeCoordinates, Shaders_Builtin_Functions_writeDepthClampedToFarPlane, Shaders_Builtin_Functions_XYZToRGB, Shaders_Builtin_Structs_depthRangeStruct, Shaders_Builtin_Structs_ellipsoid, Shaders_Builtin_Structs_material, Shaders_Builtin_Structs_materialInput, Shaders_Builtin_Structs_ray, Shaders_Builtin_Structs_raySegment, Shaders_Builtin_Structs_shadowParameters, Shaders_CompositeOITFS, Shaders_DepthPlaneFS, Shaders_DepthPlaneVS, Shaders_EllipsoidFS, Shaders_EllipsoidVS, Shaders_GlobeFS, Shaders_GlobeVS, Shaders_GroundAtmosphere, Shaders_Materials_BumpMapMaterial, Shaders_Materials_CheckerboardMaterial, Shaders_Materials_DotMaterial, Shaders_Materials_ElevationContourMaterial, Shaders_Materials_ElevationRampMaterial, Shaders_Materials_FadeMaterial, Shaders_Materials_GridMaterial, Shaders_Materials_NormalMapMaterial, Shaders_Materials_PolylineArrowMaterial, Shaders_Materials_PolylineDashMaterial, Shaders_Materials_PolylineGlowMaterial, Shaders_Materials_PolylineOutlineMaterial, Shaders_Materials_RimLightingMaterial, Shaders_Materials_SlopeRampMaterial, Shaders_Materials_StripeMaterial, Shaders_Materials_Water, Shaders_PointPrimitiveCollectionFS, Shaders_PointPrimitiveCollectionVS, Shaders_PolylineCommon, Shaders_PolylineFS, Shaders_PolylineVS, Shaders_PostProcessFilters_AdditiveBlend, Shaders_PostProcessFilters_BrightPass, Shaders_PostProcessFilters_FXAA, Shaders_PostProcessFilters_GaussianBlur1D, Shaders_PostProcessFilters_PassThrough, Shaders_PostProcessFilters_PointCloudEyeDomeLighting, Shaders_ReprojectWebMercatorFS, Shaders_ReprojectWebMercatorVS, Shaders_ShadowVolumeFS, Shaders_ShadowVolumeVS, Shaders_SkyAtmosphereFS, Shaders_SkyAtmosphereVS, Shaders_SkyBoxFS, Shaders_SkyBoxVS, Shaders_SunFS, Shaders_SunTextureFS, Shaders_SunVS, Shaders_Vector3DTilePolylinesVS, Shaders_ViewportQuadFS, Shaders_ViewportQuadVS, ThirdParty_Autolinker, ThirdParty_crunch, ThirdParty_earcut_2_1_1, ThirdParty_GltfPipeline_addDefaults, ThirdParty_GltfPipeline_addExtensionsRequired, ThirdParty_GltfPipeline_addExtensionsUsed, ThirdParty_GltfPipeline_addPipelineExtras, ThirdParty_GltfPipeline_addToArray, ThirdParty_GltfPipeline_byteLengthForComponentType, ThirdParty_GltfPipeline_findAccessorMinMax, ThirdParty_GltfPipeline_ForEach, ThirdParty_GltfPipeline_getAccessorByteStride, ThirdParty_GltfPipeline_getJointCountForMaterials, ThirdParty_GltfPipeline_glslTypeToWebGLConstant, ThirdParty_GltfPipeline_numberOfComponentsForType, ThirdParty_GltfPipeline_parseBinaryGltf, ThirdParty_GltfPipeline_processModelMaterialsCommon, ThirdParty_GltfPipeline_processPbrMetallicRoughness, ThirdParty_GltfPipeline_removeExtensionsRequired, ThirdParty_GltfPipeline_removeExtensionsUsed, ThirdParty_GltfPipeline_removePipelineExtras, ThirdParty_GltfPipeline_techniqueParameterForSemantic, ThirdParty_GltfPipeline_updateVersion, ThirdParty_GltfPipeline_webGLConstantToGlslType, ThirdParty_google_earth_dbroot_parser, ThirdParty_jsep, ThirdParty_kdbush, ThirdParty_knockout_3_4_2, ThirdParty_knockout_es5, ThirdParty_knockout, ThirdParty_measureText, ThirdParty_mersenne_twister, ThirdParty_NoSleep, ThirdParty_pako_inflate, ThirdParty_protobuf_minimal, ThirdParty_Shaders_FXAA3_11, ThirdParty_sprintf, ThirdParty_topojson, ThirdParty_Tween, ThirdParty_Uri, ThirdParty_when, ThirdParty_zip, Widgets_Animation_Animation, Widgets_Animation_AnimationViewModel, Widgets_BaseLayerPicker_BaseLayerPicker, Widgets_BaseLayerPicker_BaseLayerPickerViewModel, Widgets_BaseLayerPicker_createDefaultImageryProviderViewModels, Widgets_BaseLayerPicker_createDefaultTerrainProviderViewModels, Widgets_BaseLayerPicker_ProviderViewModel, Widgets_Cesium3DTilesInspector_Cesium3DTilesInspector, Widgets_Cesium3DTilesInspector_Cesium3DTilesInspectorViewModel, Widgets_CesiumInspector_CesiumInspector, Widgets_CesiumInspector_CesiumInspectorViewModel, Widgets_CesiumWidget_CesiumWidget, Widgets_ClockViewModel, Widgets_Command, Widgets_createCommand, Widgets_FullscreenButton_FullscreenButton, Widgets_FullscreenButton_FullscreenButtonViewModel, Widgets_Geocoder_Geocoder, Widgets_Geocoder_GeocoderViewModel, Widgets_getElement, Widgets_HomeButton_HomeButton, Widgets_HomeButton_HomeButtonViewModel, Widgets_InfoBox_InfoBox, Widgets_InfoBox_InfoBoxViewModel, Widgets_NavigationHelpButton_NavigationHelpButton, Widgets_NavigationHelpButton_NavigationHelpButtonViewModel, Widgets_PerformanceWatchdog_PerformanceWatchdog, Widgets_PerformanceWatchdog_PerformanceWatchdogViewModel, Widgets_ProjectionPicker_ProjectionPicker, Widgets_ProjectionPicker_ProjectionPickerViewModel, Widgets_SceneModePicker_SceneModePicker, Widgets_SceneModePicker_SceneModePickerViewModel, Widgets_SelectionIndicator_SelectionIndicator, Widgets_SelectionIndicator_SelectionIndicatorViewModel, Widgets_subscribeAndEvaluate, Widgets_SvgPathBindingHandler, Widgets_Timeline_Timeline, Widgets_Timeline_TimelineHighlightRange, Widgets_Timeline_TimelineTrack, Widgets_ToggleButtonViewModel, Widgets_Viewer_Viewer, Widgets_Viewer_viewerCesium3DTilesInspectorMixin, Widgets_Viewer_viewerCesiumInspectorMixin, Widgets_Viewer_viewerDragDropMixin, Widgets_Viewer_viewerPerformanceWatchdogMixin, Widgets_VRButton_VRButton, Widgets_VRButton_VRButtonViewModel, Workers_createTaskProcessorWorker) { 'use strict'; var Cesium = { - VERSION : '1.41', + VERSION : '1.42', _shaders : {} }; Cesium['appendForwardSlash'] = Core_appendForwardSlash; Cesium['arrayFill'] = Core_arrayFill; Cesium['arrayRemoveDuplicates'] = Core_arrayRemoveDuplicates; + Cesium['arraySlice'] = Core_arraySlice; Cesium['AssociativeArray'] = Core_AssociativeArray; Cesium['AttributeCompression'] = Core_AttributeCompression; Cesium['AxisAlignedBoundingBox'] = Core_AxisAlignedBoundingBox; @@ -234680,7 +246034,6 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['isDataUri'] = Core_isDataUri; Cesium['isLeapYear'] = Core_isLeapYear; Cesium['Iso8601'] = Core_Iso8601; - Cesium['joinUrls'] = Core_joinUrls; Cesium['JulianDate'] = Core_JulianDate; Cesium['KeyboardEventModifier'] = Core_KeyboardEventModifier; Cesium['LagrangePolynomialApproximation'] = Core_LagrangePolynomialApproximation; @@ -234755,6 +246108,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['RequestScheduler'] = Core_RequestScheduler; Cesium['RequestState'] = Core_RequestState; Cesium['RequestType'] = Core_RequestType; + Cesium['Resource'] = Core_Resource; Cesium['RuntimeError'] = Core_RuntimeError; Cesium['sampleTerrain'] = Core_sampleTerrain; Cesium['sampleTerrainMostDetailed'] = Core_sampleTerrainMostDetailed; @@ -234963,19 +246317,24 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['Cesium3DTileFeatureTable'] = Scene_Cesium3DTileFeatureTable; Cesium['Cesium3DTileOptimizationHint'] = Scene_Cesium3DTileOptimizationHint; Cesium['Cesium3DTileOptimizations'] = Scene_Cesium3DTileOptimizations; + Cesium['Cesium3DTilePointFeature'] = Scene_Cesium3DTilePointFeature; Cesium['Cesium3DTileRefine'] = Scene_Cesium3DTileRefine; Cesium['Cesium3DTileset'] = Scene_Cesium3DTileset; Cesium['Cesium3DTilesetStatistics'] = Scene_Cesium3DTilesetStatistics; Cesium['Cesium3DTilesetTraversal'] = Scene_Cesium3DTilesetTraversal; Cesium['Cesium3DTileStyle'] = Scene_Cesium3DTileStyle; Cesium['Cesium3DTileStyleEngine'] = Scene_Cesium3DTileStyleEngine; + Cesium['CesiumIon'] = Scene_CesiumIon; + Cesium['CesiumIonResource'] = Scene_CesiumIonResource; Cesium['CircleEmitter'] = Scene_CircleEmitter; + Cesium['ClassificationModel'] = Scene_ClassificationModel; Cesium['ClassificationPrimitive'] = Scene_ClassificationPrimitive; Cesium['ClassificationType'] = Scene_ClassificationType; Cesium['ColorBlendMode'] = Scene_ColorBlendMode; Cesium['Composite3DTileContent'] = Scene_Composite3DTileContent; Cesium['ConditionsExpression'] = Scene_ConditionsExpression; Cesium['ConeEmitter'] = Scene_ConeEmitter; + Cesium['createBillboardPointCallback'] = Scene_createBillboardPointCallback; Cesium['createOpenStreetMapImageryProvider'] = Scene_createOpenStreetMapImageryProvider; Cesium['createTangentSpaceDebugPrimitive'] = Scene_createTangentSpaceDebugPrimitive; Cesium['createTileMapServiceImageryProvider'] = Scene_createTileMapServiceImageryProvider; @@ -234998,7 +246357,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['FrameState'] = Scene_FrameState; Cesium['FrustumCommands'] = Scene_FrustumCommands; Cesium['FXAA'] = Scene_FXAA; - Cesium['getAttributeOrUniformBySemantic'] = Scene_getAttributeOrUniformBySemantic; + Cesium['Geometry3DTileContent'] = Scene_Geometry3DTileContent; Cesium['getBinaryAccessor'] = Scene_getBinaryAccessor; Cesium['GetFeatureInfoFormat'] = Scene_GetFeatureInfoFormat; Cesium['Globe'] = Scene_Globe; @@ -235038,9 +246397,11 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['ModelAnimationState'] = Scene_ModelAnimationState; Cesium['ModelInstance'] = Scene_ModelInstance; Cesium['ModelInstanceCollection'] = Scene_ModelInstanceCollection; + Cesium['ModelLoadResources'] = Scene_ModelLoadResources; Cesium['ModelMaterial'] = Scene_ModelMaterial; Cesium['ModelMesh'] = Scene_ModelMesh; Cesium['ModelNode'] = Scene_ModelNode; + Cesium['ModelUtility'] = Scene_ModelUtility; Cesium['Moon'] = Scene_Moon; Cesium['NeverTileDiscardPolicy'] = Scene_NeverTileDiscardPolicy; Cesium['OIT'] = Scene_OIT; @@ -235052,6 +246413,8 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['PerInstanceColorAppearance'] = Scene_PerInstanceColorAppearance; Cesium['PickDepth'] = Scene_PickDepth; Cesium['PointCloud3DTileContent'] = Scene_PointCloud3DTileContent; + Cesium['PointCloudEyeDomeLighting'] = Scene_PointCloudEyeDomeLighting; + Cesium['PointCloudShading'] = Scene_PointCloudShading; Cesium['PointPrimitive'] = Scene_PointPrimitive; Cesium['PointPrimitiveCollection'] = Scene_PointPrimitiveCollection; Cesium['Polyline'] = Scene_Polyline; @@ -235100,6 +246463,13 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium['TimeDynamicImagery'] = Scene_TimeDynamicImagery; Cesium['TweenCollection'] = Scene_TweenCollection; Cesium['UrlTemplateImageryProvider'] = Scene_UrlTemplateImageryProvider; + Cesium['Vector3DTileBatch'] = Scene_Vector3DTileBatch; + Cesium['Vector3DTileContent'] = Scene_Vector3DTileContent; + Cesium['Vector3DTileGeometry'] = Scene_Vector3DTileGeometry; + Cesium['Vector3DTilePoints'] = Scene_Vector3DTilePoints; + Cesium['Vector3DTilePolygons'] = Scene_Vector3DTilePolygons; + Cesium['Vector3DTilePolylines'] = Scene_Vector3DTilePolylines; + Cesium['Vector3DTilePrimitive'] = Scene_Vector3DTilePrimitive; Cesium['VerticalOrigin'] = Scene_VerticalOrigin; Cesium['ViewportQuad'] = Scene_ViewportQuad; Cesium['WebMapServiceImageryProvider'] = Scene_WebMapServiceImageryProvider; @@ -235138,6 +246508,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium._shaders['passCesium3DTile'] = Shaders_Builtin_Constants_passCesium3DTile; Cesium._shaders['passCesium3DTileClassification'] = Shaders_Builtin_Constants_passCesium3DTileClassification; Cesium._shaders['passCesium3DTileClassificationIgnoreShow'] = Shaders_Builtin_Constants_passCesium3DTileClassificationIgnoreShow; + Cesium._shaders['passClassification'] = Shaders_Builtin_Constants_passClassification; Cesium._shaders['passCompute'] = Shaders_Builtin_Constants_passCompute; Cesium._shaders['passEnvironment'] = Shaders_Builtin_Constants_passEnvironment; Cesium._shaders['passGlobe'] = Shaders_Builtin_Constants_passGlobe; @@ -235170,6 +246541,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium._shaders['computePosition'] = Shaders_Builtin_Functions_computePosition; Cesium._shaders['cosineAndSine'] = Shaders_Builtin_Functions_cosineAndSine; Cesium._shaders['decompressTextureCoordinates'] = Shaders_Builtin_Functions_decompressTextureCoordinates; + Cesium._shaders['depthClampFarPlane'] = Shaders_Builtin_Functions_depthClampFarPlane; Cesium._shaders['discardIfClippedWithIntersect'] = Shaders_Builtin_Functions_discardIfClippedWithIntersect; Cesium._shaders['discardIfClippedWithUnion'] = Shaders_Builtin_Functions_discardIfClippedWithUnion; Cesium._shaders['eastNorthUpToEyeCoordinates'] = Shaders_Builtin_Functions_eastNorthUpToEyeCoordinates; @@ -235215,6 +246587,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium._shaders['transpose'] = Shaders_Builtin_Functions_transpose; Cesium._shaders['unpackDepth'] = Shaders_Builtin_Functions_unpackDepth; Cesium._shaders['windowToEyeCoordinates'] = Shaders_Builtin_Functions_windowToEyeCoordinates; + Cesium._shaders['writeDepthClampedToFarPlane'] = Shaders_Builtin_Functions_writeDepthClampedToFarPlane; Cesium._shaders['XYZToRGB'] = Shaders_Builtin_Functions_XYZToRGB; Cesium._shaders['depthRangeStruct'] = Shaders_Builtin_Structs_depthRangeStruct; Cesium._shaders['ellipsoid'] = Shaders_Builtin_Structs_ellipsoid; @@ -235257,6 +246630,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium._shaders['FXAA'] = Shaders_PostProcessFilters_FXAA; Cesium._shaders['GaussianBlur1D'] = Shaders_PostProcessFilters_GaussianBlur1D; Cesium._shaders['PassThrough'] = Shaders_PostProcessFilters_PassThrough; + Cesium._shaders['PointCloudEyeDomeLighting'] = Shaders_PostProcessFilters_PointCloudEyeDomeLighting; Cesium._shaders['ReprojectWebMercatorFS'] = Shaders_ReprojectWebMercatorFS; Cesium._shaders['ReprojectWebMercatorVS'] = Shaders_ReprojectWebMercatorVS; Cesium._shaders['ShadowVolumeFS'] = Shaders_ShadowVolumeFS; @@ -235268,6 +246642,7 @@ define('Cesium',['./Core/appendForwardSlash', './Core/arrayFill', './Core/arrayR Cesium._shaders['SunFS'] = Shaders_SunFS; Cesium._shaders['SunTextureFS'] = Shaders_SunTextureFS; Cesium._shaders['SunVS'] = Shaders_SunVS; + Cesium._shaders['Vector3DTilePolylinesVS'] = Shaders_Vector3DTilePolylinesVS; Cesium._shaders['ViewportQuadFS'] = Shaders_ViewportQuadFS; Cesium._shaders['ViewportQuadVS'] = Shaders_ViewportQuadVS; Cesium['Autolinker'] = ThirdParty_Autolinker; diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Mouse.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Mouse.svg index 5b8f7d6c..7fae028c 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Mouse.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Mouse.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseLeft.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseLeft.svg index b07a1e82..0c49c15f 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseLeft.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseLeft.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseMiddle.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseMiddle.svg index b5b038dd..9dd533d5 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseMiddle.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseMiddle.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseRight.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseRight.svg index 80748f65..2662ad18 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseRight.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/MouseRight.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Touch.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Touch.svg index 3cef2c89..e682b301 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Touch.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/Touch.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchDrag.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchDrag.svg index 22e87d69..f0509e85 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchDrag.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchDrag.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchRotate.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchRotate.svg index 24f551e6..fe968ff4 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchRotate.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchRotate.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchTilt.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchTilt.svg index 85023669..e1206c5d 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchTilt.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchTilt.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchZoom.svg b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchZoom.svg index 0b48a3b3..74e55d7c 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchZoom.svg +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/Images/NavigationHelp/TouchZoom.svg @@ -5,6 +5,7 @@ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/shared.css b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/shared.css index 19e2db63..307ab8d5 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/shared.css +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Widgets/shared.css @@ -107,6 +107,10 @@ color: #e52; } +.cesium-performanceDisplay-throttled { + color: #a42; +} + .cesium-performanceDisplay-ms { color: #de3; } diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/combineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/combineGeometry.js index d6b5e9e7..463e52c8 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/combineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/combineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -13225,12 +13268,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -13482,6 +13527,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -15691,6 +15777,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxGeometry.js index 319c1195..6b85f6ea 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -12872,7 +12915,7 @@ define('Core/BoxGeometry',[ * @see BoxGeometry.createGeometry * @see Packable * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo} * * @example * var box = new Cesium.BoxGeometry({ @@ -13647,6 +13690,24 @@ define('Core/BoxGeometry',[ }); }; + var unitBoxGeometry; + + /** + * Returns the geometric representation of a unit box, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private + */ + BoxGeometry.getUnitBox = function() { + if (!defined(unitBoxGeometry)) { + unitBoxGeometry = BoxGeometry.createGeometry(BoxGeometry.fromDimensions({ + dimensions : new Cartesian3(1.0, 1.0, 1.0), + vertexFormat : VertexFormat.POSITION_ONLY + })); + } + return unitBoxGeometry; + }; + return BoxGeometry; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxOutlineGeometry.js index 520affc4..4b334123 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createBoxOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleGeometry.js index b58ddcbe..e35777d7 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2686,6 +2702,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -14090,7 +14133,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -14607,12 +14650,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -14864,6 +14909,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -17073,6 +17159,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -22417,6 +22525,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -22456,396 +22580,195 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); - - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; - - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); - - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; - - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; - - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); - - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; - - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; - - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; - - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } - - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; - - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ - - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ - - return Request; -}); - -define('Core/parseResponseHeaders',[], function() { - 'use strict'; - - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; - - if (!headerString) { - return headers; - } - - var headerPairs = headerString.split('\u000d\u000a'); - - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } - - return headers; - } - - return parseResponseHeaders; -}); - -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; - - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; - - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; - - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; - - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); - } - } - - /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent - * - * @returns {String} A string representing the provided RequestErrorEvent. - */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; - } - return str; - }; - - return RequestErrorEvent; -}); + return deprecationWarning; +}); /** * @license @@ -23123,233 +23046,144 @@ define('ThirdParty/Uri',[],function() { return URI; }); -define('Core/Heap',[ - './Check', +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', './defaultValue', './defined', - './defineProperties' + './DeveloperError' ], function( - Check, + Uri, defaultValue, defined, - defineProperties) { + DeveloperError) { 'use strict'; /** - * Array implementation of a heap. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @alias Heap - * @constructor - * @private + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, - - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, - - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, - - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); } - }); - - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } - - /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. - */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); }; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; - - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; - - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } - - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; - } - } - }; + return getAbsoluteUri; +}); - /** - * Resort the heap. - */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); - } - }; +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Given a URI, returns the base path of the URI. + * @exports getBaseUri * - * @param {*} element The element to insert + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + if (!includeQuery) { + return basePath; } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; } - var removedElement; + return basePath; + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; - } + return getBaseUri; +}); - return removedElement; - }; +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Remove the element specified by index from the heap and return it. + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - Check.typeOf.number.lessThan('index', index, this._length); - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; - }; - - /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - */ + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return Heap; + return getExtensionFromUri; }); define('Core/isBlobUri',[ @@ -23379,6 +23213,41 @@ define('Core/isBlobUri',[ return isBlobUri; }); +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; + + var a; + + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } + + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; + + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; + } + + return isCrossOriginUrl; +}); + define('Core/isDataUri',[ './Check' ], function( @@ -23406,652 +23275,2689 @@ define('Core/isDataUri',[ return isDataUri; }); -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' +define('Core/isArray',[ + './defined' ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; + + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } + + return removedElement; + }; + + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; +}); + +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './Check', + './defined', + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' + ], function( + Uri, + when, + Check, + defined, + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, RequestState) { 'use strict'; - function sortRequests(a, b) { - return a.priority - b.priority; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + + /** + * Tracks the number of active requests and prioritizes incoming requests. + * + * @exports RequestScheduler + * + * @private + */ + function RequestScheduler() { + } + + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); + + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; + } + + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } + } + + /** + * Sort requests by priority and start requests. + */ + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; + + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); + + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } + + startRequest(request); + ++filledSlots; + } + + updateStatistics(); + }; + + /** + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. + */ + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; + } + + return serverKey; + }; + + /** + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. + * + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + */ + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); + + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } + + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } + + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; + + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.requestHeap = requestHeap; + + return RequestScheduler; +}); + +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; + + /** + * Adds a trusted server to the registry + * + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. + * + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry + * + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); + */ + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; + + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); + + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } + + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; } - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * + * @param {String} url The url to be tested against the trusted list + * + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } + */ + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } + + return false; + }; + + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } + + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + return xhrBlobSupported; } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); - } - } + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); - } - return request.deferred.promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); + } } - } + }); /** - * Sort requests by priority and start requests. + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. */ - RequestScheduler.update = function() { - var i; - var request; - - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + var uri = new Uri(this._url); + + if (query) { + stringifyQuery(uri, this); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; + + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - clearStatistics(); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - /** - * For testing only. Clears any requests that may not have completed from previous tests. - * - * @private - */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; + + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -24060,7 +25966,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -24107,11 +26039,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -24189,129 +26236,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * The default implementations * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -24323,7 +26294,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -24336,7 +26307,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -24352,7 +26323,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -24409,12 +26380,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -24697,179 +26670,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -24887,10 +26698,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -24904,9 +26715,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -24915,7 +26728,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -24958,7 +26774,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -25009,7 +26827,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -25018,7 +26836,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -25030,7 +26848,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -25044,7 +26862,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -25242,12 +27060,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -25659,7 +27483,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -25789,7 +27613,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleOutlineGeometry.js index 28185ad4..07824856 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCircleOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -13392,7 +13435,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorGeometry.js index 5984ccca..c769be9e 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorGeometry.js @@ -2115,6 +2115,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2749,6 +2765,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9350,6 +9381,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9363,6 +9395,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9415,6 +9448,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10621,6 +10655,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12090,7 +12133,7 @@ define('Core/CornerType',[ /** * Style options for corners. * - * @demo The {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} + * @demo The {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} * demonstrates the three corner types, as used by {@link CorridorGraphics}. * * @exports CornerType @@ -14352,6 +14395,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -18131,6 +18196,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -18170,1602 +18251,3361 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + return deprecationWarning; +}); - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - return Request; -}); + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - if (!headerString) { - return headers; - } + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - var headerPairs = headerString.split('\u000d\u000a'); + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - return headers; - } +// var cache = {}; - return parseResponseHeaders; + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + return removedElement; + }; -// var cache = {}; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ -return URI; + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); + + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } - }, + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } + + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); } - - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); } - var removedElement; + clearStatistics(); + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + return false; + }; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } + + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + return xhrBlobSupported; } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); - } - } + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); - } - return request.deferred.promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); + } } - } + }); /** - * Sort requests by priority and start requests. + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. */ - RequestScheduler.update = function() { - var i; - var request; - - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + var uri = new Uri(this._url); + + if (query) { + stringifyQuery(uri, this); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; + + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - clearStatistics(); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - /** - * For testing only. Clears any requests that may not have completed from previous tests. - * - * @private - */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -19774,7 +21614,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -19821,11 +21687,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -19903,129 +21884,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * The default implementations * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -20037,7 +21942,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -20050,7 +21955,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -20066,7 +21971,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -20123,12 +22028,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -20411,179 +22318,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -20601,10 +22346,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -20618,9 +22363,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -20629,7 +22376,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -20672,7 +22422,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -20723,7 +22475,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -20732,7 +22484,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -20744,7 +22496,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -20758,7 +22510,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -20956,12 +22708,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -22355,7 +24113,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -22485,7 +24243,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -24027,7 +25785,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -26615,7 +28373,7 @@ define('Core/CorridorGeometry',[ * @see CorridorGeometry.createGeometry * @see Packable * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo} * * @example * var corridor = new Cesium.CorridorGeometry({ diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorOutlineGeometry.js index e068fc5f..c4b9a518 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCorridorOutlineGeometry.js @@ -2115,6 +2115,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2749,6 +2765,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9350,6 +9381,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9363,6 +9395,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9415,6 +9448,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10621,6 +10655,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12090,7 +12133,7 @@ define('Core/CornerType',[ /** * Style options for corners. * - * @demo The {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} + * @demo The {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} * demonstrates the three corner types, as used by {@link CorridorGraphics}. * * @exports CornerType @@ -14352,6 +14395,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -18131,6 +18196,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -18170,1602 +18251,3361 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + return deprecationWarning; +}); - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - return Request; -}); + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - if (!headerString) { - return headers; - } + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - var headerPairs = headerString.split('\u000d\u000a'); + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - return headers; - } +// var cache = {}; - return parseResponseHeaders; + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + return removedElement; + }; -// var cache = {}; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ -return URI; + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); + + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } - }, + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } + + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); } - - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); } - var removedElement; + clearStatistics(); + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + return false; + }; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } + + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + return xhrBlobSupported; } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); - } - } + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); - } - return request.deferred.promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); + } } - } + }); /** - * Sort requests by priority and start requests. + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. */ - RequestScheduler.update = function() { - var i; - var request; - - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + var uri = new Uri(this._url); + + if (query) { + stringifyQuery(uri, this); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; + + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - clearStatistics(); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - /** - * For testing only. Clears any requests that may not have completed from previous tests. - * - * @private - */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; + + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -19774,7 +21614,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -19821,11 +21687,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -19903,129 +21884,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; - - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -20037,7 +21942,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -20050,7 +21955,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -20066,7 +21971,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -20123,12 +22028,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -20411,179 +22318,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -20601,10 +22346,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -20618,9 +22363,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -20629,7 +22376,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -20672,7 +22422,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -20723,7 +22475,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -20732,7 +22484,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -20744,7 +22496,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -20758,7 +22510,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -20956,12 +22708,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -22355,7 +24113,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -22485,7 +24243,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -24027,7 +25785,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderGeometry.js index a22cbf13..3985fcaa 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12895,7 +12938,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -14139,6 +14182,26 @@ define('Core/CylinderGeometry',[ }); }; + var unitCylinderGeometry; + + /** + * Returns the geometric representation of a unit cylinder, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private + */ + CylinderGeometry.getUnitCylinder = function() { + if (!defined(unitCylinderGeometry)) { + unitCylinderGeometry = CylinderGeometry.createGeometry(new CylinderGeometry({ + topRadius : 1.0, + bottomRadius : 1.0, + length : 1.0, + vertexFormat : VertexFormat.POSITION_ONLY + })); + } + return unitCylinderGeometry; + }; + return CylinderGeometry; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderOutlineGeometry.js index 1ea67f65..eb7543a9 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createCylinderOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12895,7 +12938,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseGeometry.js index bf460796..26462579 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -14090,7 +14133,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -14607,12 +14650,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -14864,6 +14909,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -17073,6 +17159,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -22417,6 +22525,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -22456,396 +22580,195 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); - - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; - - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); - - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; - - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; - - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); - - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; - - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; - - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; - - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } - - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; - - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ - - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ - - return Request; -}); - -define('Core/parseResponseHeaders',[], function() { - 'use strict'; - - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; - - if (!headerString) { - return headers; - } - - var headerPairs = headerString.split('\u000d\u000a'); - - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } - - return headers; - } - - return parseResponseHeaders; -}); - -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; - - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; - - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; - - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; - - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); - } - } - - /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent - * - * @returns {String} A string representing the provided RequestErrorEvent. - */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; - } - return str; - }; - - return RequestErrorEvent; -}); + return deprecationWarning; +}); /** * @license @@ -23123,233 +23046,144 @@ define('ThirdParty/Uri',[],function() { return URI; }); -define('Core/Heap',[ - './Check', +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', './defaultValue', './defined', - './defineProperties' + './DeveloperError' ], function( - Check, + Uri, defaultValue, defined, - defineProperties) { + DeveloperError) { 'use strict'; /** - * Array implementation of a heap. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @alias Heap - * @constructor - * @private + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, - - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, - - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, - - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); } - }); - - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } - - /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. - */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); }; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; - - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; - - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } - - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; - } - } - }; + return getAbsoluteUri; +}); - /** - * Resort the heap. - */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); - } - }; +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Given a URI, returns the base path of the URI. + * @exports getBaseUri * - * @param {*} element The element to insert + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + if (!includeQuery) { + return basePath; } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; } - var removedElement; + return basePath; + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; - } + return getBaseUri; +}); - return removedElement; - }; +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Remove the element specified by index from the heap and return it. + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - Check.typeOf.number.lessThan('index', index, this._length); - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; - }; - - /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - */ + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return Heap; + return getExtensionFromUri; }); define('Core/isBlobUri',[ @@ -23379,6 +23213,41 @@ define('Core/isBlobUri',[ return isBlobUri; }); +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; + + var a; + + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } + + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; + + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; + } + + return isCrossOriginUrl; +}); + define('Core/isDataUri',[ './Check' ], function( @@ -23406,652 +23275,2689 @@ define('Core/isDataUri',[ return isDataUri; }); -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' +define('Core/isArray',[ + './defined' ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; + + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } + + return removedElement; + }; + + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; +}); + +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './Check', + './defined', + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' + ], function( + Uri, + when, + Check, + defined, + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, RequestState) { 'use strict'; - function sortRequests(a, b) { - return a.priority - b.priority; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + + /** + * Tracks the number of active requests and prioritizes incoming requests. + * + * @exports RequestScheduler + * + * @private + */ + function RequestScheduler() { + } + + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); + + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; + } + + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } + } + + /** + * Sort requests by priority and start requests. + */ + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; + + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); + + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } + + startRequest(request); + ++filledSlots; + } + + updateStatistics(); + }; + + /** + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. + */ + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; + } + + return serverKey; + }; + + /** + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. + * + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + */ + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); + + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } + + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } + + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; + + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.requestHeap = requestHeap; + + return RequestScheduler; +}); + +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; + + /** + * Adds a trusted server to the registry + * + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. + * + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry + * + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); + */ + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; + + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); + + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } + + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; } - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * + * @param {String} url The url to be tested against the trusted list + * + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } + */ + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } + + return false; + }; + + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } + + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + return xhrBlobSupported; } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); - } - } + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); - } - return request.deferred.promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); + } } - } + }); /** - * Sort requests by priority and start requests. + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. */ - RequestScheduler.update = function() { - var i; - var request; - - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + var uri = new Uri(this._url); + + if (query) { + stringifyQuery(uri, this); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; + + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - clearStatistics(); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - /** - * For testing only. Clears any requests that may not have completed from previous tests. - * - * @private - */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; + + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -24060,7 +25966,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -24107,11 +26039,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -24189,129 +26236,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * The default implementations * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -24323,7 +26294,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -24336,7 +26307,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -24352,7 +26323,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -24409,12 +26380,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -24697,179 +26670,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -24887,10 +26698,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -24904,9 +26715,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -24915,7 +26728,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -24958,7 +26774,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -25009,7 +26827,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -25018,7 +26836,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -25030,7 +26848,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -25044,7 +26862,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -25242,12 +27060,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -25659,7 +27483,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -25789,7 +27613,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseOutlineGeometry.js index 92fd0094..e61a9fe1 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipseOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -13392,7 +13435,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidGeometry.js index d711dfee..1c06d209 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12835,7 +12878,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -14068,6 +14111,24 @@ define('Core/EllipsoidGeometry',[ }); }; + var unitEllipsoidGeometry; + + /** + * Returns the geometric representation of a unit ellipsoid, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private + */ + EllipsoidGeometry.getUnitEllipsoid = function() { + if (!defined(unitEllipsoidGeometry)) { + unitEllipsoidGeometry = EllipsoidGeometry.createGeometry((new EllipsoidGeometry({ + radii : new Cartesian3(1.0, 1.0, 1.0), + vertexFormat : VertexFormat.POSITION_ONLY + }))); + } + return unitEllipsoidGeometry; + }; + return EllipsoidGeometry; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidOutlineGeometry.js index 0c1a2a9c..9a4bd16a 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createEllipsoidOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumGeometry.js index 5c031bc5..302a828b 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -12671,6 +12714,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumOutlineGeometry.js index 2a34f7c0..a1cd5cfc 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createFrustumOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -12671,6 +12714,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createGeometry.js index 4f4c60a1..a604b50f 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -13225,12 +13268,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -13482,6 +13527,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -15691,6 +15777,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneGeometry.js index c9f67fd0..81f99cb2 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneOutlineGeometry.js index a2ffcf8c..b02bb8fa 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPlaneOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonGeometry.js index f3d4bac9..9a804d73 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -10313,6 +10344,7 @@ define('Core/Matrix4',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -10326,6 +10358,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -10378,6 +10411,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -11584,6 +11618,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -15077,6 +15120,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -17612,6 +17677,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -17651,1602 +17732,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + return deprecationWarning; +}); - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; - - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; - return Request; -}); + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - if (!headerString) { - return headers; - } + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - var headerPairs = headerString.split('\u000d\u000a'); + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } +// var cache = {}; - return headers; - } + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; - return parseResponseHeaders; +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var removedElement; -// var cache = {}; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + return removedElement; + }; -return URI; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); } - }, + } + }); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + return false; + }; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); - } + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); } - }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + if (typeof resource !== 'string') { + return resource; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } } - return request.deferred.promise; - } + }); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + parseQuery(uri, this); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - if (defined(request.cancelFunction)) { - request.cancelFunction(); - } - } + this._url = uri.toString(); + } + }, - /** - * Sort requests by priority and start requests. - */ - RequestScheduler.update = function() { - var i; - var request; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } - activeRequests.length -= removeCount; + }); - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + var uri = new Uri(this._url); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + if (query) { + stringifyQuery(uri, this); + } + + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; - clearStatistics(); - } + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @private + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; + } + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * - * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -19255,7 +21118,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -19302,11 +21191,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -19384,129 +21388,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; - - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. + * A resource instance initialized to the current browser location * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -19518,7 +21446,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -19531,7 +21459,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -19547,7 +21475,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -19604,12 +21532,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -19892,179 +21822,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -20082,10 +21850,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -20099,9 +21867,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -20110,7 +21880,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -20153,7 +21926,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -20204,7 +21979,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -20213,7 +21988,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -20225,7 +22000,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -20239,7 +22014,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -20437,12 +22212,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -21836,7 +23617,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -21966,7 +23747,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -22781,7 +24562,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -23203,12 +24984,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -23460,6 +25243,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -29202,7 +31026,7 @@ define('Core/PolygonGeometry',[ * @see PolygonGeometry#createGeometry * @see PolygonGeometry#fromPositions * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo} * * @example * // 1. create a polygon from points diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonOutlineGeometry.js index 07a6ce18..56139363 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolygonOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9350,6 +9381,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9363,6 +9395,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9415,6 +9448,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10621,6 +10655,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -14812,6 +14855,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -17347,6 +17412,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -17386,1602 +17467,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + return deprecationWarning; +}); - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; - - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; - return Request; -}); + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - if (!headerString) { - return headers; - } + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - var headerPairs = headerString.split('\u000d\u000a'); + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } +// var cache = {}; - return headers; - } + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; - return parseResponseHeaders; +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var removedElement; -// var cache = {}; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + return removedElement; + }; -return URI; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); } - }, + } + }); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + return false; + }; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); - } + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); } - }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + if (typeof resource !== 'string') { + return resource; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } } - return request.deferred.promise; - } + }); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + parseQuery(uri, this); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - if (defined(request.cancelFunction)) { - request.cancelFunction(); - } - } + this._url = uri.toString(); + } + }, - /** - * Sort requests by priority and start requests. - */ - RequestScheduler.update = function() { - var i; - var request; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } - activeRequests.length -= removeCount; + }); - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + var uri = new Uri(this._url); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + if (query) { + stringifyQuery(uri, this); + } + + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; - clearStatistics(); - } + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @private + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; + } + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * - * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -18990,7 +20853,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -19037,11 +20926,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -19119,129 +21123,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText + * The default implementations * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -19253,7 +21181,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -19266,7 +21194,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -19282,7 +21210,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -19339,12 +21267,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -19627,179 +21557,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -19817,10 +21585,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -19834,9 +21602,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -19845,7 +21615,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -19888,7 +21661,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -19939,7 +21714,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -19948,7 +21723,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -19960,7 +21735,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -19974,7 +21749,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -20172,12 +21947,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -21571,7 +23352,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -21701,7 +23482,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -22516,7 +24297,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -23033,12 +24814,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -23290,6 +25073,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineGeometry.js index 502889bc..242643d0 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9350,6 +9381,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9363,6 +9395,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9415,6 +9448,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10621,6 +10655,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -14383,7 +14426,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -17139,6 +17182,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -17947,7 +18012,7 @@ define('Core/PolylineGeometry',[ * * @see PolylineGeometry#createGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo} * * @example * // A polyline with two connected line segments diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeGeometry.js index b9c9e60b..db85448c 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -10410,6 +10441,7 @@ define('Core/Matrix4',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -10423,6 +10455,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -10475,6 +10508,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -11681,6 +11715,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -13150,7 +13193,7 @@ define('Core/CornerType',[ /** * Style options for corners. * - * @demo The {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} + * @demo The {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} * demonstrates the three corner types, as used by {@link CorridorGraphics}. * * @exports CornerType @@ -13340,7 +13383,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -13730,12 +13773,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -13987,6 +14032,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -16196,6 +16282,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -22777,6 +22885,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -22816,1602 +22940,3334 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - freezeObject) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports deprecationWarning + * + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, + return deprecationWarning; +}); - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - return freezeObject(RequestType); -}); + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' - ], function( - defaultValue, - RequestState, - RequestType) { - 'use strict'; - - /** - * Stores information for making a request. In general this does not need to be constructed directly. - * - * @alias Request - * @constructor - * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. - */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); - - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; - - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; - - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - return Request; -}); + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } -define('Core/parseResponseHeaders',[], function() { + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; + + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; + + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; + +// var cache = {}; + + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; +}); + +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', + './defined', + './DeveloperError' + ], function( + Uri, + defaultValue, + defined, + DeveloperError) { 'use strict'; /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @private + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function parseResponseHeaders(headerString) { - var headers = {}; - - if (!headerString) { - return headers; - } - - var headerPairs = headerString.split('\u000d\u000a'); + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - return headers; - } - - return parseResponseHeaders; + return getAbsoluteUri; }); -define('Core/RequestErrorEvent',[ +define('Core/getBaseUri',[ + '../ThirdParty/Uri', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a URI, returns the base path of the URI. + * @exports getBaseUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; - - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + if (!includeQuery) { + return basePath; + } - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; + var blobUriRegex = /^blob:/i; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + return isBlobUri; +}); - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; + var a; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return isCrossOriginUrl; +}); - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + var dataUriRegex = /^data:/i; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + return isDataUri; +}); - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var removedElement; -// var cache = {}; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + return removedElement; + }; -return URI; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); } - }, + } + }); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - return isDataUri; + return false; + }; + + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; + }; + + return TrustedServers; }); -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { 'use strict'; - function sortRequests(a, b) { - return a.priority - b.priority; - } - - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 - }; + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + /** + * @private + */ + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.throttleRequests = true; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); + + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); + + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private */ - RequestScheduler.debugShowStatistics = false; + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } - defineProperties(RequestScheduler, { + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { /** - * Returns the statistics used by the request scheduler. + * Returns true if blobs are supported. * - * @memberof RequestScheduler + * @memberof Resource + * @type {Boolean} * - * @type Object * @readonly */ - statistics : { + isBlobSupported : { get : function() { - return statistics; + return xhrBlobSupported; + } + } + }); + + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } }, /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * The key/value pairs used to replace template parameters in the url. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {Object} * - * @type {Number} - * @default 20 + * @readonly */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; + templateValues: { + get: function() { + return this._templateValues; + } + }, + + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + set: function(value) { + var uri = new Uri(value); + + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); + } + }, + + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, + + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var uri = new Uri(this._url); - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + if (query) { + stringifyQuery(uri, this); } - return request.deferred.promise; - } - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); + } + }; + + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } + }; + + /** + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. + * + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. + */ + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + if (defined(options.url)) { + var uri = new Uri(options.url); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - if (defined(request.cancelFunction)) { - request.cancelFunction(); + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); } - } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; + } + + return resource; + }; /** - * Sort requests by priority and start requests. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. + * + * @param {Error} [error] The error that was encountered. + * + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.update = function() { - var i; - var request; - - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; + + return result; + }); + }; + + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - startRequest(request); - ++filledSlots; - } + return result; + }; - updateStatistics(); + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); }; /** - * Get the server key from a given url. + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); + }; + + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url. - * @returns {String} The server key. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); - } + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - return serverKey; + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Creates a Resource and calls fetchBlob() on it. * - * @param {Request} request The request object. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - ++statistics.numberOfAttemptedRequests; + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + checkAndResetRequest(this.request); - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } - return issueRequest(request); - }; + var deferred = when.defer(); - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { return; } - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - clearStatistics(); - } + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - /** - * For testing only. Clears any requests that may not have completed from previous tests. - * - * @private - */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + return fetchImage(resource, allowCrossOrigin); + } - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + + /** + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; + + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -24420,7 +26276,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -24467,11 +26349,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -24549,129 +26546,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; - - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -24683,7 +26604,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -24696,7 +26617,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -24712,7 +26633,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -24769,12 +26690,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -25057,179 +26980,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -25247,10 +27008,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -25264,9 +27025,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -25275,7 +27038,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -25318,7 +27084,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -25369,7 +27137,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -25378,7 +27146,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -25390,7 +27158,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -25404,7 +27172,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -25602,12 +27370,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -27001,7 +28775,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -27131,7 +28905,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -28190,29 +29964,6 @@ define('Core/EllipsoidGeodesic',[ return EllipsoidGeodesic; }); -define('Core/isArray',[ - './defined' - ], function( - defined) { - 'use strict'; - - /** - * Tests an object to see if it is an array. - * @exports isArray - * - * @param {Object} value The value to test. - * @returns {Boolean} true if the value is an array, false otherwise. - */ - var isArray = Array.isArray; - if (!defined(isArray)) { - isArray = function(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }; - } - - return isArray; -}); - define('Core/PolylinePipeline',[ './Cartesian3', './Cartographic', @@ -29453,7 +31204,7 @@ define('Core/PolylineVolumeGeometry',[ * * @see PolylineVolumeGeometry#createGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo} * * @example * function computeCircle(radius) { diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeOutlineGeometry.js index 4dc16418..286f5488 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createPolylineVolumeOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -10410,6 +10441,7 @@ define('Core/Matrix4',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -10423,6 +10455,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -10475,6 +10508,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -11681,6 +11715,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -13150,7 +13193,7 @@ define('Core/CornerType',[ /** * Style options for corners. * - * @demo The {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} + * @demo The {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html&label=Geometries|Corridor Demo} * demonstrates the three corner types, as used by {@link CorridorGraphics}. * * @exports CornerType @@ -13340,7 +13383,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -16863,6 +16906,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -19398,6 +19463,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -19437,1602 +19518,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + return deprecationWarning; +}); - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - return Request; -}); + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - if (!headerString) { - return headers; - } + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - var headerPairs = headerString.split('\u000d\u000a'); + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - return headers; - } +// var cache = {}; - return parseResponseHeaders; + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var removedElement; -// var cache = {}; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + return removedElement; + }; -return URI; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); } - }, + } + }); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - return isDataUri; + return false; + }; + + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; + }; + + return TrustedServers; }); -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { 'use strict'; - function sortRequests(a, b) { - return a.priority - b.priority; - } - - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 - }; + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + /** + * @private + */ + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.throttleRequests = true; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); + + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); + + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private */ - RequestScheduler.debugShowStatistics = false; + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } - defineProperties(RequestScheduler, { + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { /** - * Returns the statistics used by the request scheduler. + * Returns true if blobs are supported. * - * @memberof RequestScheduler + * @memberof Resource + * @type {Boolean} * - * @type Object * @readonly */ - statistics : { + isBlobSupported : { get : function() { - return statistics; + return xhrBlobSupported; + } + } + }); + + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } }, /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * The key/value pairs used to replace template parameters in the url. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {Object} * - * @type {Number} - * @default 20 + * @readonly */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; + templateValues: { + get: function() { + return this._templateValues; + } + }, + + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + set: function(value) { + var uri = new Uri(value); + + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); + } + }, + + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, + + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var uri = new Uri(this._url); - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + if (query) { + stringifyQuery(uri, this); } - return request.deferred.promise; - } - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); + } + }; + + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } + }; + + /** + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. + * + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. + */ + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + if (defined(options.url)) { + var uri = new Uri(options.url); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - if (defined(request.cancelFunction)) { - request.cancelFunction(); + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); } - } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; + } + + return resource; + }; /** - * Sort requests by priority and start requests. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. + * + * @param {Error} [error] The error that was encountered. + * + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.update = function() { - var i; - var request; - - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; + + return result; + }); + }; + + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - startRequest(request); - ++filledSlots; - } + return result; + }; - updateStatistics(); + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); }; /** - * Get the server key from a given url. + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); + }; + + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url. - * @returns {String} The server key. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); - } + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - return serverKey; + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Creates a Resource and calls fetchBlob() on it. * - * @param {Request} request The request object. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - ++statistics.numberOfAttemptedRequests; + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + checkAndResetRequest(this.request); - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } - return issueRequest(request); - }; + var deferred = when.defer(); - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { return; } - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - clearStatistics(); - } + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; - /** - * For testing only. Clears any requests that may not have completed from previous tests. - * - * @private - */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + return fetchImage(resource, allowCrossOrigin); + } - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry + * Creates a Resource and calls fetchText() on it. * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. - * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; + + /** + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; + + return makeRequest(this, options); + }; - Check.defined('options.url', options.url); - - var url = options.url; + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -21041,7 +22904,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -21088,11 +22977,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -21170,129 +23174,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * + * A resource instance initialized to the current browser location * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -21304,7 +23232,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -21317,7 +23245,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -21333,7 +23261,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -21390,12 +23318,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -21678,179 +23608,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -21868,10 +23636,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -21885,9 +23653,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -21896,7 +23666,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -21939,7 +23712,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -21990,7 +23765,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -21999,7 +23774,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -22011,7 +23786,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -22025,7 +23800,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -22223,12 +23998,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -23622,7 +25403,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -23752,7 +25533,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -24811,29 +26592,6 @@ define('Core/EllipsoidGeodesic',[ return EllipsoidGeodesic; }); -define('Core/isArray',[ - './defined' - ], function( - defined) { - 'use strict'; - - /** - * Tests an object to see if it is an array. - * @exports isArray - * - * @param {Object} value The value to test. - * @returns {Boolean} true if the value is an array, false otherwise. - */ - var isArray = Array.isArray; - if (!defined(isArray)) { - isArray = function(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }; - } - - return isArray; -}); - define('Core/PolylinePipeline',[ './Cartesian3', './Cartographic', diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleGeometry.js index b584b8d6..59aad2d6 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Matrix4',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12835,7 +12878,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -13352,12 +13395,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -13609,6 +13654,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -15818,6 +15904,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -22645,7 +22753,7 @@ define('Core/RectangleGeometry',[ * * @see RectangleGeometry#createGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo} * * @example * // 1. create a rectangle diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleOutlineGeometry.js index 431ece92..22cbf845 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createRectangleOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Matrix4',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSimplePolylineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSimplePolylineGeometry.js index ec825531..410cb29e 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSimplePolylineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSimplePolylineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -14286,7 +14329,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -17042,6 +17085,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereGeometry.js index 64606f6e..cc2f8c75 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12835,7 +12878,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -14068,6 +14111,24 @@ define('Core/EllipsoidGeometry',[ }); }; + var unitEllipsoidGeometry; + + /** + * Returns the geometric representation of a unit ellipsoid, including its vertices, indices, and a bounding sphere. + * @returns {Geometry} The computed vertices and indices. + * + * @private + */ + EllipsoidGeometry.getUnitEllipsoid = function() { + if (!defined(unitEllipsoidGeometry)) { + unitEllipsoidGeometry = EllipsoidGeometry.createGeometry((new EllipsoidGeometry({ + radii : new Cartesian3(1.0, 1.0, 1.0), + vertexFormat : VertexFormat.POSITION_ONLY + }))); + } + return unitEllipsoidGeometry; + }; + return EllipsoidGeometry; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereOutlineGeometry.js index 518dd4ee..f1c08655 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createSphereOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js index 8b577f7d..0303810e 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2923,6 +2939,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9481,6 +9512,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9494,6 +9526,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9546,6 +9579,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10752,6 +10786,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -11475,7 +11518,7 @@ define('Core/EllipsoidalOccluder',[ * Determine whether or not other objects are visible or hidden behind the visible horizon defined by * an {@link Ellipsoid} and a camera position. The ellipsoid is assumed to be located at the * origin of the coordinate system. This class uses the algorithm described in the - * {@link http://cesiumjs.org/2013/04/25/Horizon-culling/|Horizon Culling} blog post. + * {@link https://cesium.com/blog/2013/04/25/Horizon-culling/|Horizon Culling} blog post. * * @alias EllipsoidalOccluder * @@ -11529,7 +11572,7 @@ define('Core/EllipsoidalOccluder',[ return this._cameraPosition; }, set : function(cameraPosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ var ellipsoid = this._ellipsoid; var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace); var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0; @@ -11579,7 +11622,7 @@ define('Core/EllipsoidalOccluder',[ * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true */ EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ var cv = this._cameraPositionInScaledSpace; var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared; var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian); @@ -13553,6 +13596,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -16088,6 +16153,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -16127,1602 +16208,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + return deprecationWarning; +}); - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; + + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; + + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; + + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; + + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; + + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; + + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; + + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate + + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; + + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; + + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; + + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } + + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } + + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; + + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; + + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; + +// var cache = {}; + + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; +}); + +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', + './defined', + './DeveloperError' + ], function( + Uri, + defaultValue, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri + * + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. + * + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); + */ + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } + + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; + + return getAbsoluteUri; +}); + +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; + } + + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri + * + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); + */ + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } + + return getExtensionFromUri; +}); + +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; + + var blobUriRegex = /^blob:/i; + + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } + + return isBlobUri; +}); + +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; + + var a; + + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } + + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; + + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; + } + + return isCrossOriginUrl; +}); + +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; + + var dataUriRegex = /^data:/i; + + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } + + return isDataUri; +}); + +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { /** - * The function that is called when the request is cancelled. + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. * - * @type {Request~CancelCallback} + * @memberof Heap.prototype + * + * @type {Number} + * @readonly */ - this.cancelFunction = options.cancelFunction; + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + var removedElement; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + return removedElement; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + return Heap; +}); - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './Check', + './defined', + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' + ], function( + Uri, + when, + Check, + defined, + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { + 'use strict'; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; + function sortRequests(a, b) { + return a.priority - b.priority; } + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Mark the request as cancelled. + * Tracks the number of active requests and prioritizes incoming requests. + * + * @exports RequestScheduler * * @private */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + function RequestScheduler() { + } /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 */ + RequestScheduler.maximumRequests = 50; /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 */ + RequestScheduler.maximumRequestsPerServer = 6; /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true */ + RequestScheduler.throttleRequests = true; - return Request; -}); - -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. * - * @private + * @type {Event} + * @default Event() */ - function parseResponseHeaders(headerString) { - var headers = {}; + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); - if (!headerString) { - return headers; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); } + } - var headerPairs = headerString.split('\u000d\u000a'); + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); } - - return headers; + return request.deferred.promise; } - return parseResponseHeaders; -}); + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; + } - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); + if (defined(request.cancelFunction)) { + request.cancelFunction(); } } /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent - * - * @returns {String} A string representing the provided RequestErrorEvent. + * Sort requests by priority and start requests. */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } } - return str; - }; + activeRequests.length -= removeCount; - return RequestErrorEvent; -}); + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } + + startRequest(request); + ++filledSlots; + } + + updateStatistics(); + }; + + /** + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. + */ + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; + } - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + return serverKey; + }; - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + /** + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. + * + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + */ + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); + + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; + ++statistics.numberOfAttemptedRequests; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return issueRequest(request); + }; - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + clearStatistics(); + } - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; + }; -// var cache = {}; + /** + * For testing only. + * + * @private + */ + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; + }; - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + /** + * For testing only. + * + * @private + */ + RequestScheduler.requestHeap = requestHeap; -return URI; + return RequestScheduler; }); -define('Core/Heap',[ - './Check', - './defaultValue', +define('Core/TrustedServers',[ + '../ThirdParty/Uri', './defined', - './defineProperties' + './DeveloperError' ], function( - Check, - defaultValue, + Uri, defined, - defineProperties) { + DeveloperError) { 'use strict'; /** - * Array implementation of a heap. + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. * - * @alias Heap - * @constructor - * @private + * @exports TrustedServers * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; - } - - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, - - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, - - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, - - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } - } - }); - - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } + var TrustedServers = {}; + var _servers = {}; /** - * Resizes the internal array of the heap. + * Adds a trusted server to the registry * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. + * + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } }; /** - * Update the heap so that index and all descendants satisfy the heap property. + * Removes a trusted server from the registry * - * @param {Number} [index=0] The starting index to heapify from. + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; } else { - inserting = false; + return undefined; } } - }; - /** - * Resort the heap. - */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); - } - }; + return authority; + } /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @param {*} element The element to insert + * @param {String} url The url to be tested against the trusted list * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); - - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; - - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); - } - - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; } - return removedElement; + return false; }; /** - * Remove the element specified by index from the heap and return it. + * Clears the registry * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @example + * // Remove a trusted server + * TrustedServers.clear(); */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + TrustedServers.clear = function() { + _servers = {}; }; - /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - */ - - return Heap; + return TrustedServers; }); -define('Core/isBlobUri',[ - './Check' - ], function( - Check) { +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { 'use strict'; - var blobUriRegex = /^blob:/i; + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Determines if the specified uri is a blob uri. - * - * @exports isBlobUri - * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. - * * @private */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); - - return blobUriRegex.test(uri); - } - - return isBlobUri; -}); + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } - var dataUriRegex = /^data:/i; + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } /** - * Determines if the specified uri is a data uri. - * - * @exports isDataUri - * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. - * * @private */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + var keys = Object.keys(queryObject); - function sortRequests(a, b) { - return a.priority - b.priority; + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } } - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 - }; - - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); - - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; - - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); - /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.maximumRequestsPerServer = 6; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); + + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); + + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private */ - RequestScheduler.throttleRequests = true; + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } - /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false - */ - RequestScheduler.debugShowStatistics = false; + if (typeof resource !== 'string') { + return resource; + } - defineProperties(RequestScheduler, { + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { /** - * Returns the statistics used by the request scheduler. + * Returns true if blobs are supported. * - * @memberof RequestScheduler + * @memberof Resource + * @type {Boolean} * - * @type Object * @readonly */ - statistics : { + isBlobSupported : { get : function() { - return statistics; + return xhrBlobSupported; + } + } + }); + + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } }, /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * The key/value pairs used to replace template parameters in the url. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {Object} * - * @type {Number} - * @default 20 + * @readonly */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; + templateValues: { + get: function() { + return this._templateValues; + } + }, + + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + set: function(value) { + var uri = new Uri(value); + + parseQuery(uri, this); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + this._url = uri.toString(); } - } - }); + }, - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); - } - } + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); - } - return request.deferred.promise; - } + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + } + }); - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; + } - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + var uri = new Uri(this._url); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; + if (query) { + stringifyQuery(uri, this); } - if (defined(request.cancelFunction)) { - request.cancelFunction(); + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); + } } - } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; /** - * Sort requests by priority and start requests. + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. */ - RequestScheduler.update = function() { - var i; - var request; + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); + } + }; - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); } - activeRequests.length -= removeCount; + }; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + /** + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. + * + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. + */ + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; + } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } + return resource; + }; - startRequest(request); - ++filledSlots; + /** + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. + * + * @param {Error} [error] The error that was encountered. + * + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. + */ + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - updateStatistics(); + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; + + return result; + }); }; /** - * Get the server key from a given url. + * Duplicates a Resource instance. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - return serverKey; + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; + + return result; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Returns the base path of the Resource. * - * @param {Request} request The request object. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {String} The base URI of the resource */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); - } + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - ++statistics.numberOfAttemptedRequests; + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); + }; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; + + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; + + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } - return issueRequest(request); + return when.reject(error); + }); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { return; } - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - clearStatistics(); + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); } /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); + }; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; + /** + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); }; /** - * For testing only. + * Creates a Resource and calls fetchText() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * For testing only. + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. * - * @private + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.requestHeap = requestHeap; + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - return RequestScheduler; -}); + if (!defined(promise)) { + return undefined; + } -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. - * - * @exports TrustedServers + * Creates a Resource and calls fetchJson() on it. * - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - var TrustedServers = {}; - var _servers = {}; + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Adds a trusted server to the registry + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. * * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); }; /** - * Removes a trusted server from the registry - * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchXML() on it. * - * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } - - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; - } - - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } - - return authority; - } - /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Requests a resource using JSONP. * - * @param {String} url The url to be tested against the trusted list + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); - return false; + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); + + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } + /** - * Clears the registry + * Creates a Resource from a URL and calls fetchJsonp() on it. * - * @example - * // Remove a trusted server - * TrustedServers.clear(); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.clear = function() { - _servers = {}; + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); }; - return TrustedServers; -}); - -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; - /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -17731,7 +19594,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -17760,29 +19649,144 @@ define('Core/loadWithXhr',[ var isBase64 = !!dataUriRegexResult[2]; var data = dataUriRegexResult[3]; - switch (responseType) { - case '': - case 'text': - return decodeDataUriText(isBase64, data); - case 'arraybuffer': - return decodeDataUriArrayBuffer(isBase64, data); - case 'blob': - var buffer = decodeDataUriArrayBuffer(isBase64, data); - return new Blob([buffer], { - type : mimeType - }); - case 'document': - var parser = new DOMParser(); - return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); - case 'json': - return JSON.parse(decodeDataUriText(isBase64, data)); - default: - throw new DeveloperError('Unhandled responseType: ' + responseType); - } - } + switch (responseType) { + case '': + case 'text': + return decodeDataUriText(isBase64, data); + case 'arraybuffer': + return decodeDataUriArrayBuffer(isBase64, data); + case 'blob': + var buffer = decodeDataUriArrayBuffer(isBase64, data); + return new Blob([buffer], { + type : mimeType + }); + case 'document': + var parser = new DOMParser(); + return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); + case 'json': + return JSON.parse(decodeDataUriText(isBase64, data)); + default: + throw new DeveloperError('Unhandled responseType: ' + responseType); + } + } + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -17860,129 +19864,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } - - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -17994,7 +19922,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -18007,7 +19935,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -18023,7 +19951,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -18080,12 +20008,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -18368,179 +20298,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -18558,10 +20326,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -18575,9 +20343,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -18586,7 +20356,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -18629,7 +20402,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -18680,7 +20455,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -18689,7 +20464,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -18701,7 +20476,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -18715,7 +20490,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -18913,12 +20688,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -20829,7 +22610,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -20959,7 +22740,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -21626,6 +23407,7 @@ define('Core/OrientedBoundingBox',[ './Cartesian2', './Cartesian3', './Cartographic', + './Check', './defaultValue', './defined', './DeveloperError', @@ -21642,6 +23424,7 @@ define('Core/OrientedBoundingBox',[ Cartesian2, Cartesian3, Cartographic, + Check, defaultValue, defined, DeveloperError, @@ -21663,7 +23446,7 @@ define('Core/OrientedBoundingBox',[ * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 + * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 * cube centered at the origin. * * @@ -21687,11 +23470,60 @@ define('Core/OrientedBoundingBox',[ /** * The transformation matrix, to rotate the box to the right position. * @type {Matrix3} - * @default {@link Matrix3.IDENTITY} + * @default {@link Matrix3.ZERO} */ this.halfAxes = Matrix3.clone(defaultValue(halfAxes, Matrix3.ZERO)); } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + OrientedBoundingBox.packedLength = Cartesian3.packedLength + Matrix3.packedLength; + + /** + * Stores the provided instance into the provided array. + * + * @param {OrientedBoundingBox} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + OrientedBoundingBox.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + Cartesian3.pack(value.center, array, startingIndex); + Matrix3.pack(value.halfAxes, array, startingIndex + Cartesian3.packedLength); + + return array; + }; + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrientedBoundingBox} [result] The object into which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + */ + OrientedBoundingBox.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new OrientedBoundingBox(); + } + + Cartesian3.unpack(array, startingIndex, result.center); + Matrix3.unpack(array, startingIndex + Cartesian3.packedLength, result.halfAxes); + return result; + }; + var scratchCartesian1 = new Cartesian3(); var scratchCartesian2 = new Cartesian3(); var scratchCartesian3 = new Cartesian3(); @@ -21709,7 +23541,7 @@ define('Core/OrientedBoundingBox',[ * This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis). * Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf * - * @param {Cartesian3[]} positions List of {@link Cartesian3} points that the bounding box will enclose. + * @param {Cartesian3[]} [positions] List of {@link Cartesian3} points that the bounding box will enclose. * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. * @@ -22355,12 +24187,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -22612,6 +24446,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromHeightmap.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromHeightmap.js index 327642aa..8a635201 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromHeightmap.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromHeightmap.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9481,6 +9512,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9494,6 +9526,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9546,6 +9579,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10752,6 +10786,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -11475,7 +11518,7 @@ define('Core/EllipsoidalOccluder',[ * Determine whether or not other objects are visible or hidden behind the visible horizon defined by * an {@link Ellipsoid} and a camera position. The ellipsoid is assumed to be located at the * origin of the coordinate system. This class uses the algorithm described in the - * {@link http://cesiumjs.org/2013/04/25/Horizon-culling/|Horizon Culling} blog post. + * {@link https://cesium.com/blog/2013/04/25/Horizon-culling/|Horizon Culling} blog post. * * @alias EllipsoidalOccluder * @@ -11529,7 +11572,7 @@ define('Core/EllipsoidalOccluder',[ return this._cameraPosition; }, set : function(cameraPosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ var ellipsoid = this._ellipsoid; var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace); var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0; @@ -11579,7 +11622,7 @@ define('Core/EllipsoidalOccluder',[ * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true */ EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ var cv = this._cameraPositionInScaledSpace; var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared; var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian); @@ -13553,6 +13596,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -16088,6 +16153,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -16127,1602 +16208,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + return deprecationWarning; +}); - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; + + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; + + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; + + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; + + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; + + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; + + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; + + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate + + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; + + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; + + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; + + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } + + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } + + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; + + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; + + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; + +// var cache = {}; + + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; +}); + +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', + './defined', + './DeveloperError' + ], function( + Uri, + defaultValue, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri + * + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. + * + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); + */ + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } + + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; + + return getAbsoluteUri; +}); + +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; + } + + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri + * + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); + */ + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } + + return getExtensionFromUri; +}); + +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; + + var blobUriRegex = /^blob:/i; + + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } + + return isBlobUri; +}); + +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; + + var a; + + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } + + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; + + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; + } + + return isCrossOriginUrl; +}); + +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; + + var dataUriRegex = /^data:/i; + + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } + + return isDataUri; +}); + +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ this.requestFunction = options.requestFunction; /** - * The function that is called when the request is cancelled. + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. * - * @type {Request~CancelCallback} + * @memberof Heap.prototype + * + * @type {Number} + * @readonly */ - this.cancelFunction = options.cancelFunction; + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + var removedElement; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + return removedElement; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + return Heap; +}); - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './Check', + './defined', + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' + ], function( + Uri, + when, + Check, + defined, + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { + 'use strict'; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; + function sortRequests(a, b) { + return a.priority - b.priority; } + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Mark the request as cancelled. + * Tracks the number of active requests and prioritizes incoming requests. + * + * @exports RequestScheduler * * @private */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + function RequestScheduler() { + } /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 */ + RequestScheduler.maximumRequests = 50; /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 */ + RequestScheduler.maximumRequestsPerServer = 6; /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true */ + RequestScheduler.throttleRequests = true; - return Request; -}); - -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. * - * @private + * @type {Event} + * @default Event() */ - function parseResponseHeaders(headerString) { - var headers = {}; + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); - if (!headerString) { - return headers; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); } + } - var headerPairs = headerString.split('\u000d\u000a'); + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); } - - return headers; + return request.deferred.promise; } - return parseResponseHeaders; -}); + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; + } - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); + if (defined(request.cancelFunction)) { + request.cancelFunction(); } } /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent - * - * @returns {String} A string representing the provided RequestErrorEvent. + * Sort requests by priority and start requests. */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } } - return str; - }; + activeRequests.length -= removeCount; - return RequestErrorEvent; -}); + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } + + startRequest(request); + ++filledSlots; + } + + updateStatistics(); + }; + + /** + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. + */ + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; + } - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + return serverKey; + }; - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + /** + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. + * + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + */ + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); + + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; + ++statistics.numberOfAttemptedRequests; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return issueRequest(request); + }; - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + clearStatistics(); + } - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; + }; -// var cache = {}; + /** + * For testing only. + * + * @private + */ + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; + }; - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + /** + * For testing only. + * + * @private + */ + RequestScheduler.requestHeap = requestHeap; -return URI; + return RequestScheduler; }); -define('Core/Heap',[ - './Check', - './defaultValue', +define('Core/TrustedServers',[ + '../ThirdParty/Uri', './defined', - './defineProperties' + './DeveloperError' ], function( - Check, - defaultValue, + Uri, defined, - defineProperties) { + DeveloperError) { 'use strict'; /** - * Array implementation of a heap. + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. * - * @alias Heap - * @constructor - * @private + * @exports TrustedServers * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; - } - - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, - - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, - - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, - - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } - } - }); - - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } + var TrustedServers = {}; + var _servers = {}; /** - * Resizes the internal array of the heap. + * Adds a trusted server to the registry * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. + * + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } }; /** - * Update the heap so that index and all descendants satisfy the heap property. + * Removes a trusted server from the registry * - * @param {Number} [index=0] The starting index to heapify from. + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; } else { - inserting = false; + return undefined; } } - }; + + return authority; + } /** - * Resort the heap. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * + * @param {String} url The url to be tested against the trusted list + * + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; } + + return false; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. - * - * @param {*} element The element to insert + * Clears the registry * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @example + * // Remove a trusted server + * TrustedServers.clear(); */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); - - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + TrustedServers.clear = function() { + _servers = {}; + }; - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); - } + return TrustedServers; +}); - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; + + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; } + })(); - var removedElement; + /** + * @private + */ + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); } - return removedElement; - }; + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } /** - * Remove the element specified by index from the heap and return it. - * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; - }; + } /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } - return Heap; -}); + return defined(obj.clone) ? obj.clone() : clone(obj); + } -define('Core/isBlobUri',[ - './Check' - ], function( - Check) { - 'use strict'; + /** + * @private + */ + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } - var blobUriRegex = /^blob:/i; + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * Determines if the specified uri is a blob uri. + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. * - * @exports isBlobUri + * @alias Resource + * @constructor * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. * - * @private + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); - return blobUriRegex.test(uri); - } + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - return isBlobUri; -}); + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); - var dataUriRegex = /^data:/i; + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } /** - * Determines if the specified uri is a data uri. + * A helper function to create a resource depending on whether we have a String or a Resource * - * @exports isDataUri + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. * * @private */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + if (typeof resource !== 'string') { + return resource; + } - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } + } }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); - - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, - /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * - * @private - */ - function RequestScheduler() { - } + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, - /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 - */ - RequestScheduler.maximumRequests = 50; + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 - */ - RequestScheduler.maximumRequestsPerServer = 6; + parseQuery(uri, this); - /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true - */ - RequestScheduler.throttleRequests = true; + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false - */ - RequestScheduler.debugShowStatistics = false; + this._url = uri.toString(); + } + }, - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * The file extension of the resource. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {String} * - * @type Object * @readonly */ - statistics : { - get : function() { - return statistics; + extension: { + get: function() { + return getExtensionFromUri(this._url); } }, /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * True if the Resource refers to a data URI. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, + + /** + * True if the Resource refers to a blob URI. * - * @type {Number} - * @default 20 + * @memberof Resource.prototype + * @type {Boolean} */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var uri = new Uri(this._url); - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + if (query) { + stringifyQuery(uri, this); } - return request.deferred.promise; - } - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } - - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } - - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); } - } + }; /** - * Sort requests by priority and start requests. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. + * + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.update = function() { - var i; - var request; + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + return resource; + }; + + /** + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. + * + * @param {Error} [error] The error that was encountered. + * + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. + */ + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); + } + + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; + + return result; + }); + }; + + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); + } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - startRequest(request); - ++filledSlots; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - updateStatistics(); + return result; }; /** - * Get the server key from a given url. + * Returns the base path of the Resource. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); - } + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); + }; - return serverKey; + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Creates a Resource and calls fetchArrayBuffer() on it. * - * @param {Request} request The request object. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; + + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); - } + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; - ++statistics.numberOfAttemptedRequests; + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. + * + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); - } + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } - return issueRequest(request); + return when.reject(error); + }); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { return; } - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - clearStatistics(); + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); } /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); + }; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; + /** + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); }; /** - * For testing only. + * Creates a Resource and calls fetchText() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * For testing only. + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. * - * @private + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.requestHeap = requestHeap; + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - return RequestScheduler; -}); + if (!defined(promise)) { + return undefined; + } -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; + + /** + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports TrustedServers + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchXML() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Removes a trusted server from the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; - } + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; - return authority; - } + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; - /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. - * - * @param {String} url The url to be tested against the trusted list - * - * @returns {boolean} Returns true if url is trusted, false otherwise. - * - * @example - * // Add server - * TrustedServers.add('my.server.com', 81); - * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } - */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - return false; - }; + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } /** - * Clears the registry + * Creates a Resource from a URL and calls fetchJsonp() on it. * - * @example - * // Remove a trusted server - * TrustedServers.clear(); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.clear = function() { - _servers = {}; + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); }; - return TrustedServers; -}); - -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; - /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -17731,7 +19594,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -17754,35 +19643,150 @@ define('Core/loadWithXhr',[ return buffer; } - function decodeDataUri(dataUriRegexResult, responseType) { - responseType = defaultValue(responseType, ''); - var mimeType = dataUriRegexResult[1]; - var isBase64 = !!dataUriRegexResult[2]; - var data = dataUriRegexResult[3]; + function decodeDataUri(dataUriRegexResult, responseType) { + responseType = defaultValue(responseType, ''); + var mimeType = dataUriRegexResult[1]; + var isBase64 = !!dataUriRegexResult[2]; + var data = dataUriRegexResult[3]; + + switch (responseType) { + case '': + case 'text': + return decodeDataUriText(isBase64, data); + case 'arraybuffer': + return decodeDataUriArrayBuffer(isBase64, data); + case 'blob': + var buffer = decodeDataUriArrayBuffer(isBase64, data); + return new Blob([buffer], { + type : mimeType + }); + case 'document': + var parser = new DOMParser(); + return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); + case 'json': + return JSON.parse(decodeDataUriText(isBase64, data)); + default: + throw new DeveloperError('Unhandled responseType: ' + responseType); + } + } + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } - switch (responseType) { - case '': - case 'text': - return decodeDataUriText(isBase64, data); - case 'arraybuffer': - return decodeDataUriArrayBuffer(isBase64, data); - case 'blob': - var buffer = decodeDataUriArrayBuffer(isBase64, data); - return new Blob([buffer], { - type : mimeType - }); - case 'document': - var parser = new DOMParser(); - return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); - case 'json': - return JSON.parse(decodeDataUriText(isBase64, data)); - default: - throw new DeveloperError('Unhandled responseType: ' + responseType); - } - } + image.src = url; + }; - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -17860,129 +19864,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; - - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -17994,7 +19922,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -18007,7 +19935,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -18023,7 +19951,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -18080,12 +20008,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -18368,179 +20298,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -18558,10 +20326,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -18575,9 +20343,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -18586,7 +20356,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -18629,7 +20402,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -18680,7 +20455,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -18689,7 +20464,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -18701,7 +20476,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -18715,7 +20490,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -18913,12 +20688,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -20829,7 +22610,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -20959,7 +22740,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -21626,6 +23407,7 @@ define('Core/OrientedBoundingBox',[ './Cartesian2', './Cartesian3', './Cartographic', + './Check', './defaultValue', './defined', './DeveloperError', @@ -21642,6 +23424,7 @@ define('Core/OrientedBoundingBox',[ Cartesian2, Cartesian3, Cartographic, + Check, defaultValue, defined, DeveloperError, @@ -21663,7 +23446,7 @@ define('Core/OrientedBoundingBox',[ * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 + * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 * cube centered at the origin. * * @@ -21687,11 +23470,60 @@ define('Core/OrientedBoundingBox',[ /** * The transformation matrix, to rotate the box to the right position. * @type {Matrix3} - * @default {@link Matrix3.IDENTITY} + * @default {@link Matrix3.ZERO} */ this.halfAxes = Matrix3.clone(defaultValue(halfAxes, Matrix3.ZERO)); } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + OrientedBoundingBox.packedLength = Cartesian3.packedLength + Matrix3.packedLength; + + /** + * Stores the provided instance into the provided array. + * + * @param {OrientedBoundingBox} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + OrientedBoundingBox.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + Cartesian3.pack(value.center, array, startingIndex); + Matrix3.pack(value.halfAxes, array, startingIndex + Cartesian3.packedLength); + + return array; + }; + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrientedBoundingBox} [result] The object into which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + */ + OrientedBoundingBox.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new OrientedBoundingBox(); + } + + Cartesian3.unpack(array, startingIndex, result.center); + Matrix3.unpack(array, startingIndex + Cartesian3.packedLength, result.halfAxes); + return result; + }; + var scratchCartesian1 = new Cartesian3(); var scratchCartesian2 = new Cartesian3(); var scratchCartesian3 = new Cartesian3(); @@ -21709,7 +23541,7 @@ define('Core/OrientedBoundingBox',[ * This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis). * Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf * - * @param {Cartesian3[]} positions List of {@link Cartesian3} points that the bounding box will enclose. + * @param {Cartesian3[]} [positions] List of {@link Cartesian3} points that the bounding box will enclose. * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. * @@ -22355,12 +24187,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -22612,6 +24446,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromQuantizedTerrainMesh.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromQuantizedTerrainMesh.js index ddb89fca..d4a7c119 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromQuantizedTerrainMesh.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createVerticesFromQuantizedTerrainMesh.js @@ -2716,6 +2716,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -3076,12 +3092,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -3333,6 +3351,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -3885,6 +3944,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -10443,6 +10517,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -10456,6 +10531,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -10508,6 +10584,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -11714,6 +11791,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -14281,6 +14367,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -16816,6 +16924,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -16855,396 +16979,195 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); - - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; - - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); - - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; - - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; - - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); - - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; - - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; - - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; - - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } - - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; - - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ - - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ - - return Request; -}); - -define('Core/parseResponseHeaders',[], function() { - 'use strict'; - - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; - - if (!headerString) { - return headers; - } - - var headerPairs = headerString.split('\u000d\u000a'); - - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } - - return headers; - } - - return parseResponseHeaders; -}); - -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; - - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; - - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; - - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; - - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); - } - } - - /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent - * - * @returns {String} A string representing the provided RequestErrorEvent. - */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; - } - return str; - }; - - return RequestErrorEvent; -}); + return deprecationWarning; +}); /** * @license @@ -17522,233 +17445,144 @@ define('ThirdParty/Uri',[],function() { return URI; }); -define('Core/Heap',[ - './Check', +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', './defaultValue', './defined', - './defineProperties' + './DeveloperError' ], function( - Check, + Uri, defaultValue, defined, - defineProperties) { + DeveloperError) { 'use strict'; /** - * Array implementation of a heap. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @alias Heap - * @constructor - * @private + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, - - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, - - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, - - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); } - }); - - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } - - /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. - */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); }; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; - - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; - - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } - - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; - } - } - }; + return getAbsoluteUri; +}); - /** - * Resort the heap. - */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); - } - }; +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Given a URI, returns the base path of the URI. + * @exports getBaseUri * - * @param {*} element The element to insert + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + if (!includeQuery) { + return basePath; } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; } - var removedElement; + return basePath; + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; - } + return getBaseUri; +}); - return removedElement; - }; +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Remove the element specified by index from the heap and return it. + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - Check.typeOf.number.lessThan('index', index, this._length); - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; - }; - - /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - */ + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return Heap; + return getExtensionFromUri; }); define('Core/isBlobUri',[ @@ -17778,6 +17612,41 @@ define('Core/isBlobUri',[ return isBlobUri; }); +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; + + var a; + + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } + + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; + + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; + } + + return isCrossOriginUrl; +}); + define('Core/isDataUri',[ './Check' ], function( @@ -17805,652 +17674,2689 @@ define('Core/isDataUri',[ return isDataUri; }); -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' +define('Core/isArray',[ + './defined' ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { + defined) { 'use strict'; - function sortRequests(a, b) { + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; + + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } + + return removedElement; + }; + + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; +}); + +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './Check', + './defined', + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' + ], function( + Uri, + when, + Check, + defined, + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { + 'use strict'; + + function sortRequests(a, b) { return a.priority - b.priority; } - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + + /** + * Tracks the number of active requests and prioritizes incoming requests. + * + * @exports RequestScheduler + * + * @private + */ + function RequestScheduler() { + } + + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); + + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; + } + + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } + } + + /** + * Sort requests by priority and start requests. + */ + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; + + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); + + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } + + startRequest(request); + ++filledSlots; + } + + updateStatistics(); + }; + + /** + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. + */ + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; + } + + return serverKey; + }; + + /** + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. + * + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + */ + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); + + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } + + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } + + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; + + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.requestHeap = requestHeap; + + return RequestScheduler; +}); + +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; + + /** + * Adds a trusted server to the registry + * + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. + * + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry + * + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); + */ + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Tracks the number of active requests and prioritizes incoming requests. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports RequestScheduler + * @param {String} url The url to be tested against the trusted list * + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } + */ + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } + + return false; + }; + + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; + }; + + return TrustedServers; +}); + +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; + + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); + + /** * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } + + /** + * @private + */ + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } + + /** + * @private + */ + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } + + /** + * @private + */ + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } + + /** + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); + */ + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); + + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); + + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; } - /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 - */ - RequestScheduler.maximumRequests = 50; + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } + + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } + } + }); + + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, + + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, + + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 - */ - RequestScheduler.maximumRequestsPerServer = 6; + parseQuery(uri, this); - /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true - */ - RequestScheduler.throttleRequests = true; + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false - */ - RequestScheduler.debugShowStatistics = false; + this._url = uri.toString(); + } + }, - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * The file extension of the resource. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {String} * - * @type Object * @readonly */ - statistics : { - get : function() { - return statistics; + extension: { + get: function() { + return getExtensionFromUri(this._url); } }, /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * True if the Resource refers to a data URI. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, + + /** + * True if the Resource refers to a blob URI. * - * @type {Number} - * @default 20 + * @memberof Resource.prototype + * @type {Boolean} */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var uri = new Uri(this._url); - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + if (query) { + stringifyQuery(uri, this); } - return request.deferred.promise; - } - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } - - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } - - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); } - } + }; /** - * Sort requests by priority and start requests. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. + * + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.update = function() { - var i; - var request; + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + return resource; + }; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } + /** + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. + * + * @param {Error} [error] The error that was encountered. + * + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. + */ + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); + } - startRequest(request); - ++filledSlots; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; + + return result; + }); + }; + + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - updateStatistics(); + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; + + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; + + return result; + }; + + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; + + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; /** - * Get the server key from a given url. + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url. - * @returns {String} The server key. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); - } + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - return serverKey; + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Creates a Resource and calls fetchBlob() on it. * - * @param {Request} request The request object. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - ++statistics.numberOfAttemptedRequests; + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + checkAndResetRequest(this.request); - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } - return issueRequest(request); - }; + var deferred = when.defer(); - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { return; } - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - clearStatistics(); + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); } /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); + }; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; + /** + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); }; /** - * For testing only. + * Creates a Resource and calls fetchText() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * For testing only. + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. * - * @private + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.requestHeap = requestHeap; + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - return RequestScheduler; -}); + if (!defined(promise)) { + return undefined; + } -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * Creates a Resource and calls fetchJson() on it. * - * @exports TrustedServers + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; + + /** + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchXML() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Removes a trusted server from the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; - } + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; - return authority; - } + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; - /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. - * - * @param {String} url The url to be tested against the trusted list - * - * @returns {boolean} Returns true if url is trusted, false otherwise. - * - * @example - * // Add server - * TrustedServers.add('my.server.com', 81); - * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } - */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - return false; - }; + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } /** - * Clears the registry + * Creates a Resource from a URL and calls fetchJsonp() on it. * - * @example - * // Remove a trusted server - * TrustedServers.clear(); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.clear = function() { - _servers = {}; + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); }; - return TrustedServers; -}); - -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; - /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -18459,58 +20365,199 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); + } + + var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + + function decodeDataUriText(isBase64, data) { + var result = decodeURIComponent(data); + if (isBase64) { + return atob(result); + } + return result; + } + + function decodeDataUriArrayBuffer(isBase64, data) { + var byteString = decodeDataUriText(isBase64, data); + var buffer = new ArrayBuffer(byteString.length); + var view = new Uint8Array(buffer); + for (var i = 0; i < byteString.length; i++) { + view[i] = byteString.charCodeAt(i); + } + return buffer; + } + + function decodeDataUri(dataUriRegexResult, responseType) { + responseType = defaultValue(responseType, ''); + var mimeType = dataUriRegexResult[1]; + var isBase64 = !!dataUriRegexResult[2]; + var data = dataUriRegexResult[3]; + + switch (responseType) { + case '': + case 'text': + return decodeDataUriText(isBase64, data); + case 'arraybuffer': + return decodeDataUriArrayBuffer(isBase64, data); + case 'blob': + var buffer = decodeDataUriArrayBuffer(isBase64, data); + return new Blob([buffer], { + type : mimeType + }); + case 'document': + var parser = new DOMParser(); + return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); + case 'json': + return JSON.parse(decodeDataUriText(isBase64, data)); + default: + throw new DeveloperError('Unhandled responseType: ' + responseType); + } } - var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; - function decodeDataUriText(isBase64, data) { - var result = decodeURIComponent(data); - if (isBase64) { - return atob(result); - } - return result; - } + image.onerror = function(e) { + deferred.reject(e); + }; - function decodeDataUriArrayBuffer(isBase64, data) { - var byteString = decodeDataUriText(isBase64, data); - var buffer = new ArrayBuffer(byteString.length); - var view = new Uint8Array(buffer); - for (var i = 0; i < byteString.length; i++) { - view[i] = byteString.charCodeAt(i); + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } } - return buffer; - } - - function decodeDataUri(dataUriRegexResult, responseType) { - responseType = defaultValue(responseType, ''); - var mimeType = dataUriRegexResult[1]; - var isBase64 = !!dataUriRegexResult[2]; - var data = dataUriRegexResult[3]; - switch (responseType) { - case '': - case 'text': - return decodeDataUriText(isBase64, data); - case 'arraybuffer': - return decodeDataUriArrayBuffer(isBase64, data); - case 'blob': - var buffer = decodeDataUriArrayBuffer(isBase64, data); - return new Blob([buffer], { - type : mimeType - }); - case 'document': - var parser = new DOMParser(); - return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); - case 'json': - return JSON.parse(decodeDataUriText(isBase64, data)); - default: - throw new DeveloperError('Unhandled responseType: ' + responseType); - } - } + image.src = url; + }; - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -18588,129 +20635,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -18722,7 +20693,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -18735,7 +20706,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -18751,7 +20722,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -18808,12 +20779,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -19096,179 +21069,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -19286,10 +21097,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -19303,9 +21114,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -19314,7 +21127,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -19357,7 +21173,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -19408,7 +21226,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -19417,7 +21235,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -19429,7 +21247,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -19443,7 +21261,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -19641,12 +21459,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -21557,7 +23381,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -21687,7 +23511,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -22354,6 +24178,7 @@ define('Core/OrientedBoundingBox',[ './Cartesian2', './Cartesian3', './Cartographic', + './Check', './defaultValue', './defined', './DeveloperError', @@ -22370,6 +24195,7 @@ define('Core/OrientedBoundingBox',[ Cartesian2, Cartesian3, Cartographic, + Check, defaultValue, defined, DeveloperError, @@ -22391,7 +24217,7 @@ define('Core/OrientedBoundingBox',[ * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 + * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 * cube centered at the origin. * * @@ -22415,11 +24241,60 @@ define('Core/OrientedBoundingBox',[ /** * The transformation matrix, to rotate the box to the right position. * @type {Matrix3} - * @default {@link Matrix3.IDENTITY} + * @default {@link Matrix3.ZERO} */ this.halfAxes = Matrix3.clone(defaultValue(halfAxes, Matrix3.ZERO)); } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + OrientedBoundingBox.packedLength = Cartesian3.packedLength + Matrix3.packedLength; + + /** + * Stores the provided instance into the provided array. + * + * @param {OrientedBoundingBox} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + OrientedBoundingBox.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + Cartesian3.pack(value.center, array, startingIndex); + Matrix3.pack(value.halfAxes, array, startingIndex + Cartesian3.packedLength); + + return array; + }; + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrientedBoundingBox} [result] The object into which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + */ + OrientedBoundingBox.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new OrientedBoundingBox(); + } + + Cartesian3.unpack(array, startingIndex, result.center); + Matrix3.unpack(array, startingIndex + Cartesian3.packedLength, result.halfAxes); + return result; + }; + var scratchCartesian1 = new Cartesian3(); var scratchCartesian2 = new Cartesian3(); var scratchCartesian3 = new Cartesian3(); @@ -22437,7 +24312,7 @@ define('Core/OrientedBoundingBox',[ * This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis). * Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf * - * @param {Cartesian3[]} positions List of {@link Cartesian3} points that the bounding box will enclose. + * @param {Cartesian3[]} [positions] List of {@link Cartesian3} points that the bounding box will enclose. * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. * diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallGeometry.js index eeb8209b..9aaa9579 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -15705,6 +15748,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -18240,6 +18305,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -18279,1602 +18360,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + return deprecationWarning; +}); - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - return Request; -}); + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - if (!headerString) { - return headers; - } + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - var headerPairs = headerString.split('\u000d\u000a'); + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - return headers; - } +// var cache = {}; - return parseResponseHeaders; + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var removedElement; -// var cache = {}; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + return removedElement; + }; -return URI; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); } - }, + } + }); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + return false; + }; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); - } + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); } - }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + if (typeof resource !== 'string') { + return resource; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } } - return request.deferred.promise; - } + }); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + parseQuery(uri, this); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - if (defined(request.cancelFunction)) { - request.cancelFunction(); - } - } + this._url = uri.toString(); + } + }, - /** - * Sort requests by priority and start requests. - */ - RequestScheduler.update = function() { - var i; - var request; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } - activeRequests.length -= removeCount; + }); - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + var uri = new Uri(this._url); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + if (query) { + stringifyQuery(uri, this); + } + + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; - clearStatistics(); - } + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @private + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; + } + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; + + /** + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; + + return makeRequest(this, options); + }; - Check.defined('options.url', options.url); - - var url = options.url; + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -19883,7 +21746,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -19930,11 +21819,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -20012,129 +22016,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; - - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -20146,7 +22074,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -20159,7 +22087,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -20175,7 +22103,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -20232,12 +22160,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -20520,179 +22450,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -20710,10 +22478,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -20727,9 +22495,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -20738,7 +22508,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -20781,7 +22554,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -20832,7 +22607,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -20841,7 +22616,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -20853,7 +22628,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -20867,7 +22642,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -21065,12 +22840,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -22464,7 +24245,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -22594,7 +24375,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -24612,29 +26393,6 @@ define('Core/EllipsoidGeodesic',[ return EllipsoidGeodesic; }); -define('Core/isArray',[ - './defined' - ], function( - defined) { - 'use strict'; - - /** - * Tests an object to see if it is an array. - * @exports isArray - * - * @param {Object} value The value to test. - * @returns {Boolean} true if the value is an array, false otherwise. - */ - var isArray = Array.isArray; - if (!defined(isArray)) { - isArray = function(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }; - } - - return isArray; -}); - define('Core/PolylinePipeline',[ './Cartesian3', './Cartographic', @@ -25221,7 +26979,7 @@ define('Core/WallGeometry',[ * @see WallGeometry#createGeometry * @see WallGeometry#fromConstantHeight * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo} * * @example * // create a wall that spans from ground level to 10000 meters diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallOutlineGeometry.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallOutlineGeometry.js index 8646113d..e3d9ebf0 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallOutlineGeometry.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/createWallOutlineGeometry.js @@ -2018,6 +2018,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -2652,6 +2668,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -9253,6 +9284,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -9266,6 +9298,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -9318,6 +9351,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -10524,6 +10558,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -12137,7 +12180,7 @@ define('Core/Geometry',[ * @see BoxGeometry * @see EllipsoidGeometry * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} + * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo} * * @example * // Create geometry with a position attribute and indexed lines. @@ -15399,6 +15442,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -17934,6 +17999,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -17973,1602 +18054,3384 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + return deprecationWarning; +}); - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; +/** + * @license + * + * Grauw URI utilities + * + * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js + * + * @author Laurens Holst (http://www.grauw.nl/) + * + * Copyright 2012 Laurens Holst + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +define('ThirdParty/Uri',[],function() { - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + } + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - return Request; -}); + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; -define('Core/parseResponseHeaders',[], function() { - 'use strict'; + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - if (!headerString) { - return headers; - } + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - var headerPairs = headerString.split('\u000d\u000a'); + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } + // We don't like this function because it builds up a cache that is never cleared. +// /** +// * Resolves a relative URI against an absolute base URI. +// * Convenience method. +// * @param {String} uri the relative URI to resolve +// * @param {String} baseURI the base URI (must be absolute) to resolve against +// */ +// URI.resolve = function(sURI, sBaseURI) { +// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); +// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); +// return uri.resolve(baseURI).toString(); +// }; - return headers; - } +// var cache = {}; - return parseResponseHeaders; + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); -define('Core/RequestErrorEvent',[ +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', + './defaultValue', './defined', - './parseResponseHeaders' + './DeveloperError' ], function( + Uri, + defaultValue, defined, - parseResponseHeaders) { + DeveloperError) { 'use strict'; /** - * An event that is raised when a request encounters an error. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @constructor - * @alias RequestErrorEvent + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); + } - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); + } + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); + }; - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; + return getAbsoluteUri; +}); - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * Given a URI, returns the base path of the URI. + * @exports getBaseUri + * + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. + * + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); + */ + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } + + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } + + if (!includeQuery) { + return basePath; + } + + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; + } + + return basePath; } + return getBaseUri; +}); + +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @returns {String} A string representing the provided RequestErrorEvent. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - return str; - }; + + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return RequestErrorEvent; + return getExtensionFromUri; }); -/** - * @license - * - * Grauw URI utilities - * - * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js - * - * @author Laurens Holst (http://www.grauw.nl/) - * - * Copyright 2012 Laurens Holst - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -define('ThirdParty/Uri',[],function() { - - /** - * Constructs a URI object. - * @constructor - * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. - * @param {string|URI} uri A string or URI object to create the object from. - */ - function URI(uri) { - if (uri instanceof URI) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is URI string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } - // Initial values on the prototype - URI.prototype.scheme = null; - URI.prototype.authority = null; - URI.prototype.path = ''; - URI.prototype.query = null; - URI.prototype.fragment = null; +define('Core/isBlobUri',[ + './Check' + ], function( + Check) { + 'use strict'; - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + var blobUriRegex = /^blob:/i; - /** - * Returns the scheme part of the URI. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - URI.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Determines if the specified uri is a blob uri. + * + * @exports isBlobUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * + * @private + */ + function isBlobUri(uri) { + Check.typeOf.string('uri', uri); + + return blobUriRegex.test(uri); + } - /** - * Returns the authority part of the URI. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - URI.prototype.getAuthority = function() { - return this.authority; - }; + return isBlobUri; +}); - /** - * Returns the path part of the URI. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - URI.prototype.getPath = function() { - return this.path; - }; +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; - /** - * Returns the query part of the URI. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - URI.prototype.getQuery = function() { - return this.query; - }; + var a; - /** - * Returns the fragment part of the URI. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - URI.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } - /** - * Tests whether the URI is an absolute URI. - * See RFC 3986 section 4.3. - */ - URI.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; - ///** - //* Extensive validation of the URI against the ABNF in RFC 3986 - //*/ - //URI.prototype.validate + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; - /** - * Tests whether the URI is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.isSameDocumentAs = function(uri) { - return uri.scheme == this.scheme && - uri.authority == this.authority && - uri.path == this.path && - uri.query == this.query; - }; + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set - /** - * Simple String Comparison of two URIs. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the URI objects. - */ - URI.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; - }; + return protocol !== a.protocol || host !== a.host; + } - /** - * Normalizes the URI using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid URI in the first place. See validate().) - * See RFC 3986 section 6.2.2. - */ - URI.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) - this.scheme = this.scheme.toLowerCase(); - if (this.authority) - this.authority = this.authority.replace(authorityRegex, replaceAuthority). - replace(caseRegex, replaceCase); - if (this.path) - this.path = this.path.replace(caseRegex, replaceCase); - if (this.query) - this.query = this.query.replace(caseRegex, replaceCase); - if (this.fragment) - this.fragment = this.fragment.replace(caseRegex, replaceCase); - }; + return isCrossOriginUrl; +}); - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; +define('Core/isDataUri',[ + './Check' + ], function( + Check) { + 'use strict'; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var dataUriRegex = /^data:/i; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + /** + * Determines if the specified uri is a data uri. + * + * @exports isDataUri + * + * @param {String} uri The uri to test. + * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * + * @private + */ + function isDataUri(uri) { + Check.typeOf.string('uri', uri); + + return dataUriRegex.test(uri); + } - /** - * Resolve a relative URI (this) against a base URI. - * The base URI must be an absolute URI. - * See RFC 3986 section 5.2 - */ - URI.prototype.resolve = function(baseURI) { - var uri = new URI(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseURI.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseURI.authority; - if (this.path == '') { - uri.path = baseURI.path; - uri.query = this.query || baseURI.query; - } else { - if (this.path.charAt(0) == '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseURI.authority && baseURI.path == '') { - uri.path = '/' + this.path; - } else { - uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + return isDataUri; +}); - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - URI.prototype.removeDotSegments = function() { - var input = this.path.split('/'), - output = [], - segment, - absPath = input[0] == ''; - if (absPath) - input.shift(); - var sFirst = input[0] == '' ? input.shift() : null; - while (input.length) { - segment = input.shift(); - if (segment == '..') { - output.pop(); - } else if (segment != '.') { - output.push(segment); - } - } - if (segment == '.' || segment == '..') - output.push(''); - if (absPath) - output.unshift(''); - this.path = output.join('/'); - }; +define('Core/isArray',[ + './defined' + ], function( + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } - // We don't like this function because it builds up a cache that is never cleared. -// /** -// * Resolves a relative URI against an absolute base URI. -// * Convenience method. -// * @param {String} uri the relative URI to resolve -// * @param {String} baseURI the base URI (must be absolute) to resolve against -// */ -// URI.resolve = function(sURI, sBaseURI) { -// var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); -// var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); -// return uri.resolve(baseURI).toString(); -// }; + var removedElement; -// var cache = {}; + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } - /** - * Serialises the URI to a string. - */ - URI.prototype.toString = function() { - var result = ''; - if (this.scheme) - result += this.scheme + ':'; - if (this.authority) - result += '//' + this.authority; - result += this.path; - if (this.query) - result += '?' + this.query; - if (this.fragment) - result += '#' + this.fragment; - return result; - }; + return removedElement; + }; -return URI; + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; }); -define('Core/Heap',[ +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', './Check', - './defaultValue', './defined', - './defineProperties' + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' ], function( + Uri, + when, Check, - defaultValue, defined, - defineProperties) { + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, + RequestState) { 'use strict'; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + /** - * Array implementation of a heap. + * Tracks the number of active requests and prioritizes incoming requests. * - * @alias Heap - * @constructor - * @private + * @exports RequestScheduler * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @private */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function RequestScheduler() { } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { /** - * Gets the internal array. + * Returns the statistics used by the request scheduler. * - * @memberof Heap.prototype + * @memberof RequestScheduler * - * @type {Array} + * @type Object * @readonly */ - internalArray : { + statistics : { get : function() { - return this._array; + return statistics; } }, /** - * Gets and sets the maximum length of the heap. + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. * - * @memberof Heap.prototype + * @memberof RequestScheduler * * @type {Number} + * @default 20 */ - maximumLength : { + priorityHeapLength : { get : function() { - return this._maximumLength; + return priorityHeapLength; }, set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); } - }, + } + }); - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; } - }); - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } } /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * Sort requests by priority and start requests. */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; - }; + RequestScheduler.update = function() { + var i; + var request; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; } - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; } + + startRequest(request); + ++filledSlots; } + + updateStatistics(); }; /** - * Resort the heap. + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; } + + return serverKey; }; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. * - * @param {*} element The element to insert + * @param {Request} request The request object. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); } - - var removedElement; - - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; - return removedElement; + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; }; /** - * Remove the element specified by index from the heap and return it. + * For testing only. * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @private */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; - } - Check.typeOf.number.lessThan('index', index, this._length); - - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; }; /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * For testing only. + * + * @private */ + RequestScheduler.requestHeap = requestHeap; - return Heap; + return RequestScheduler; }); -define('Core/isBlobUri',[ - './Check' +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' ], function( - Check) { + Uri, + defined, + DeveloperError) { 'use strict'; - var blobUriRegex = /^blob:/i; + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; /** - * Determines if the specified uri is a blob uri. + * Adds a trusted server to the registry * - * @exports isBlobUri + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry * - * @private + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); */ - function isBlobUri(uri) { - Check.typeOf.string('uri', uri); + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } - return blobUriRegex.test(uri); - } + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; - return isBlobUri; -}); + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); -define('Core/isDataUri',[ - './Check' - ], function( - Check) { - 'use strict'; + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } - var dataUriRegex = /^data:/i; + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; + } /** - * Determines if the specified uri is a data uri. + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @exports isDataUri + * @param {String} url The url to be tested against the trusted list * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @returns {boolean} Returns true if url is trusted, false otherwise. * - * @private + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } */ - function isDataUri(uri) { - Check.typeOf.string('uri', uri); - - return dataUriRegex.test(uri); - } - - return isDataUri; -}); - -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' - ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, - RequestState) { - 'use strict'; + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } - function sortRequests(a, b) { - return a.priority - b.priority; - } + return false; + }; - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + return TrustedServers; +}); - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. - * - * @exports RequestScheduler - * * @private */ - function RequestScheduler() { + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; } /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 + * @private */ - RequestScheduler.maximumRequests = 50; + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 + * @private */ - RequestScheduler.maximumRequestsPerServer = 6; + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true + * @private */ - RequestScheduler.throttleRequests = true; + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. + * + * @alias Resource + * @constructor + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - RequestScheduler.debugShowStatistics = false; + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * Additional HTTP headers that will be sent with the request. * - * @memberof RequestScheduler + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. * - * @type Object - * @readonly + * @type {Request} */ - statistics : { - get : function() { - return statistics; - } - }, + this.request = defaultValue(options.request, new Request()); /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * A proxy to be used when loading the resource. * - * @memberof RequestScheduler + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. * * @type {Number} - * @default 20 */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); - } + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; + } + + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); } - }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + if (typeof resource !== 'string') { + return resource; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } } - return request.deferred.promise; - } + }); - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + }, - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } + }, - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + parseQuery(uri, this); - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; - } + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - if (defined(request.cancelFunction)) { - request.cancelFunction(); - } - } + this._url = uri.toString(); + } + }, - /** - * Sort requests by priority and start requests. - */ - RequestScheduler.update = function() { - var i; - var request; + /** + * The file extension of the resource. + * + * @memberof Resource.prototype + * @type {String} + * + * @readonly + */ + extension: { + get: function() { + return getExtensionFromUri(this._url); + } + }, - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); + /** + * True if the Resource refers to a data URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; + }, + + /** + * True if the Resource refers to a blob URI. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isBlobUri: { + get: function() { + return isBlobUri(this._url); } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } - activeRequests.length -= removeCount; + }); - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + var uri = new Uri(this._url); - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; + if (query) { + stringifyQuery(uri, this); + } + + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); + + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - startRequest(request); - ++filledSlots; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - updateStatistics(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); + } }; /** - * Get the server key from a given url. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; + + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - return serverKey; + return resource; }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Request} request The request object. + * @param {Error} [error] The error that was encountered. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); } - ++statistics.numberOfAttemptedRequests; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + return result; + }); + }; - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; - } + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return result; + }; - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; - } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; - return issueRequest(request); + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + /** + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { - return; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); + }; - clearStatistics(); - } + /** + * Creates a Resource and calls fetchBlob() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @private + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); + + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); + + checkAndResetRequest(this.request); + + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; - }; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; + } + + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); + + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } + + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; + } + + var deferred = when.defer(); + + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); + + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); + } /** - * For testing only. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); }; /** - * For testing only. + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @private - */ - RequestScheduler.requestHeap = requestHeap; - - return RequestScheduler; -}); - -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; - - /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @exports TrustedServers + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchText() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * Removes a trusted server from the registry + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. + * + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } - }; - - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); - - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; + if (!defined(promise)) { + return undefined; } - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; - return authority; - } + /** + * Creates a Resource and calls fetchJson() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url to be tested against the trusted list + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @returns {boolean} Returns true if url is trusted, false otherwise. * * @example - * // Add server - * TrustedServers.add('my.server.com', 81); + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; - } + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; - return false; + /** + * Creates a Resource and calls fetchXML() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Clears the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * * * @example - * // Remove a trusted server - * TrustedServers.clear(); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.clear = function() { - _servers = {}; + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - return TrustedServers; -}); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); + + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); + + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; + + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Creates a Resource from a URL and calls fetchJsonp() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); + }; + + /** + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; + + return makeRequest(this, options); + }; - Check.defined('options.url', options.url); - - var url = options.url; + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -19577,7 +21440,33 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); } var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; @@ -19624,11 +21513,126 @@ define('Core/loadWithXhr',[ return JSON.parse(decodeDataUriText(isBase64, data)); default: throw new DeveloperError('Unhandled responseType: ' + responseType); - } + } } - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; + + image.onerror = function(e) { + deferred.reject(e); + }; + + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } + } + + image.src = url; + }; + + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -19706,129 +21710,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * + * A resource instance initialized to the current browser location * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -19840,7 +21768,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -19853,7 +21781,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -19869,7 +21797,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -19926,12 +21854,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -20214,179 +22144,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -20404,10 +22172,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -20421,9 +22189,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -20432,7 +22202,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -20475,7 +22248,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -20526,7 +22301,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -20535,7 +22310,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -20547,7 +22322,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -20561,7 +22336,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -20759,12 +22534,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -22158,7 +23939,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -22288,7 +24069,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -24306,29 +26087,6 @@ define('Core/EllipsoidGeodesic',[ return EllipsoidGeodesic; }); -define('Core/isArray',[ - './defined' - ], function( - defined) { - 'use strict'; - - /** - * Tests an object to see if it is an array. - * @exports isArray - * - * @param {Object} value The value to test. - * @returns {Boolean} true if the value is an array, false otherwise. - */ - var isArray = Array.isArray; - if (!defined(isArray)) { - isArray = function(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }; - } - - return isArray; -}); - define('Core/PolylinePipeline',[ './Cartesian3', './Cartographic', diff --git a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/upsampleQuantizedTerrainMesh.js b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/upsampleQuantizedTerrainMesh.js index affcb065..dee78ff1 100644 --- a/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/upsampleQuantizedTerrainMesh.js +++ b/gwt-cs-main/src/main/resources/org/cesiumjs/public/cs/CesiumUnminified/Workers/upsampleQuantizedTerrainMesh.js @@ -2716,6 +2716,22 @@ define('Core/Cartesian3',[ return result; }; + /** + * Projects vector a onto vector b + * @param {Cartesian3} a The vector that needs projecting + * @param {Cartesian3} b The vector to project onto + * @param {Cartesian3} result The result cartesian + * @returns {Cartesian3} The modified result parameter + */ + Cartesian3.projectVector = function(a, b, result) { + Check.defined('a', a); + Check.defined('b', b); + Check.defined('result', result); + + var scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b); + return Cartesian3.multiplyByScalar(b, scalar, result); + }; + /** * Compares the provided Cartesians componentwise and returns * <code>true</code> if they are equal, <code>false</code> otherwise. @@ -3076,12 +3092,14 @@ define('Core/AttributeCompression',[ './Cartesian2', './Cartesian3', './Check', + './defined', './DeveloperError', './Math' ], function( Cartesian2, Cartesian3, Check, + defined, DeveloperError, CesiumMath) { 'use strict'; @@ -3333,6 +3351,47 @@ define('Core/AttributeCompression',[ return result; }; + function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); + } + + /** + * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place. + * + * @param {Uint16Array} uBuffer The buffer view of u values. + * @param {Uint16Array} vBuffer The buffer view of v values. + * @param {Uint16Array} [heightBuffer] The buffer view of height values. + * + * @see {@link https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html|quantized-mesh-1.0 terrain format} + */ + AttributeCompression.zigZagDeltaDecode = function(uBuffer, vBuffer, heightBuffer) { + Check.defined('uBuffer', uBuffer); + Check.defined('vBuffer', vBuffer); + Check.typeOf.number.equals('uBuffer.length', 'vBuffer.length', uBuffer.length, vBuffer.length); + if (defined(heightBuffer)) { + Check.typeOf.number.equals('uBuffer.length', 'heightBuffer.length', uBuffer.length, heightBuffer.length); + } + + var count = uBuffer.length; + + var u = 0; + var v = 0; + var height = 0; + + for (var i = 0; i < count; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + + if (defined(heightBuffer)) { + height += zigZagDecode(heightBuffer[i]); + heightBuffer[i] = height; + } + } + }; + return AttributeCompression; }); @@ -3614,6 +3673,21 @@ define('Core/Cartographic',[ return result; }; + /** + * Creates a new Cartesian3 instance from a Cartographic input. The values in the inputted + * object should be in radians. + * + * @param {Cartographic} cartographic Input to be converted into a Cartesian3 output. + * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3} The position + */ + Cartographic.toCartesian = function(cartographic, ellipsoid, result) { + Check.defined('cartographic', cartographic); + + return Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height, ellipsoid, result); + }; + /** * Duplicates a Cartographic instance. * @@ -10215,6 +10289,7 @@ define('Core/Rectangle',[ define('Core/BoundingSphere',[ './Cartesian3', './Cartographic', + './Math', './Check', './defaultValue', './defined', @@ -10228,6 +10303,7 @@ define('Core/BoundingSphere',[ ], function( Cartesian3, Cartographic, + CesiumMath, Check, defaultValue, defined, @@ -10280,6 +10356,7 @@ define('Core/BoundingSphere',[ var fromPointsMinBoxPt = new Cartesian3(); var fromPointsMaxBoxPt = new Cartesian3(); var fromPointsNaiveCenterScratch = new Cartesian3(); + var volumeConstant = (4.0 / 3.0) * CesiumMath.PI; /** * Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points. @@ -11486,6 +11563,15 @@ define('Core/BoundingSphere',[ return BoundingSphere.clone(this, result); }; + /** + * Computes the radius of the BoundingSphere. + * @returns {Number} The radius of the BoundingSphere. + */ + BoundingSphere.prototype.volume = function() { + var radius = this.radius; + return volumeConstant * radius * radius * radius; + }; + return BoundingSphere; }); @@ -11511,7 +11597,7 @@ define('Core/EllipsoidalOccluder',[ * Determine whether or not other objects are visible or hidden behind the visible horizon defined by * an {@link Ellipsoid} and a camera position. The ellipsoid is assumed to be located at the * origin of the coordinate system. This class uses the algorithm described in the - * {@link http://cesiumjs.org/2013/04/25/Horizon-culling/|Horizon Culling} blog post. + * {@link https://cesium.com/blog/2013/04/25/Horizon-culling/|Horizon Culling} blog post. * * @alias EllipsoidalOccluder * @@ -11565,7 +11651,7 @@ define('Core/EllipsoidalOccluder',[ return this._cameraPosition; }, set : function(cameraPosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ var ellipsoid = this._ellipsoid; var cv = ellipsoid.transformPositionToScaledSpace(cameraPosition, this._cameraPositionInScaledSpace); var vhMagnitudeSquared = Cartesian3.magnitudeSquared(cv) - 1.0; @@ -11615,7 +11701,7 @@ define('Core/EllipsoidalOccluder',[ * occluder.isScaledSpacePointVisible(scaledSpacePoint); //returns true */ EllipsoidalOccluder.prototype.isScaledSpacePointVisible = function(occludeeScaledSpacePosition) { - // See http://cesiumjs.org/2013/04/25/Horizon-culling/ + // See https://cesiumjs.org/2013/04/25/Horizon-culling/ var cv = this._cameraPositionInScaledSpace; var vhMagnitudeSquared = this._distanceToLimbInScaledSpaceSquared; var vt = Cartesian3.subtract(occludeeScaledSpacePosition, cv, scratchCartesian); @@ -14855,6 +14941,28 @@ define('Core/Plane',[ return Cartesian3.dot(plane.normal, point) + plane.distance; }; + var scratchCartesian = new Cartesian3(); + /** + * Projects a point onto the plane. + * @param {Plane} plane The plane to project the point onto + * @param {Cartesian3} point The point to project onto the plane + * @param {Cartesian3} [result] The result point. If undefined, a new Cartesian3 will be created. + */ + Plane.projectPointOntoPlane = function(plane, point, result) { + Check.typeOf.object('plane', plane); + Check.typeOf.object('point', point); + + if (!defined(result)) { + result = new Cartesian3(); + } + + // projectedPoint = point - (normal.point + scale) * normal + var pointDistance = Plane.getPointDistance(plane, point); + var scaledNormal = Cartesian3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + + return Cartesian3.subtract(point, scaledNormal, result); + }; + var scratchPosition = new Cartesian3(); /** * Transforms the plane by the given transformation matrix. @@ -17390,6 +17498,22 @@ define('Core/JulianDate',[ return JulianDate; }); +define('Core/appendForwardSlash',[],function() { + 'use strict'; + + /** + * @private + */ + function appendForwardSlash(url) { + if (url.length === 0 || url[url.length - 1] !== '/') { + url = url + '/'; + } + return url; + } + + return appendForwardSlash; +}); + define('Core/clone',[ './defaultValue' ], function( @@ -17429,396 +17553,195 @@ define('Core/clone',[ return clone; }); -define('Core/RequestState',[ - '../Core/freezeObject' +define('Core/combine',[ + './defaultValue', + './defined' ], function( - freezeObject) { + defaultValue, + defined) { 'use strict'; /** - * State of the request. + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. * - * @exports RequestState + * @example + * var object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * var object2 = { + * propTwo : 2 + * } + * var final = Cesium.combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @exports combine */ - var RequestState = { - /** - * Initial unissued state. - * - * @type Number - * @constant - */ - UNISSUED : 0, - - /** - * Issued but not yet active. Will become active when open slots are available. - * - * @type Number - * @constant - */ - ISSUED : 1, - - /** - * Actual http request has been sent. - * - * @type Number - * @constant - */ - ACTIVE : 2, - - /** - * Request completed successfully. - * - * @type Number - * @constant - */ - RECEIVED : 3, - - /** - * Request was cancelled, either explicitly or automatically because of low priority. - * - * @type Number - * @constant - */ - CANCELLED : 4, + function combine(object1, object2, deep) { + deep = defaultValue(deep, false); - /** - * Request failed. - * - * @type Number - * @constant - */ - FAILED : 5 - }; + var result = {}; + + var object1Defined = defined(object1); + var object2Defined = defined(object2); + var property; + var object1Value; + var object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === 'object' && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === 'object') { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; + } - return freezeObject(RequestState); + return combine; }); -define('Core/RequestType',[ - '../Core/freezeObject' +define('Core/oneTimeWarning',[ + './defaultValue', + './defined', + './DeveloperError' ], function( - freezeObject) { + defaultValue, + defined, + DeveloperError) { 'use strict'; + var warnings = {}; + /** - * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * Logs a one time message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @exports RequestType + * @exports oneTimeWarning + * + * @param {String} identifier The unique identifier for this warning. + * @param {String} [message=identifier] The message to log to the console. + * + * @example + * for(var i=0;i<foo.length;++i) { + * if (!defined(foo[i].bar)) { + * // Something that can be recovered from but may happen a lot + * oneTimeWarning('foo.bar undefined', 'foo.bar is undefined. Setting to 0.'); + * foo[i].bar = 0; + * // ... + * } + * } + * + * @private */ - var RequestType = { - /** - * Terrain request. - * - * @type Number - * @constant - */ - TERRAIN : 0, - - /** - * Imagery request. - * - * @type Number - * @constant - */ - IMAGERY : 1, - - /** - * 3D Tiles request. - * - * @type Number - * @constant - */ - TILES3D : 2, + function oneTimeWarning(identifier, message) { + if (!defined(identifier)) { + throw new DeveloperError('identifier is required.'); + } + + if (!defined(warnings[identifier])) { + warnings[identifier] = true; + console.warn(defaultValue(message, identifier)); + } + } - /** - * Other request. - * - * @type Number - * @constant - */ - OTHER : 3 - }; + oneTimeWarning.geometryOutlines = 'Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0.'; - return freezeObject(RequestType); + return oneTimeWarning; }); -define('Core/Request',[ - './defaultValue', - './RequestState', - './RequestType' +define('Core/deprecationWarning',[ + './defined', + './DeveloperError', + './oneTimeWarning' ], function( - defaultValue, - RequestState, - RequestType) { + defined, + DeveloperError, + oneTimeWarning) { 'use strict'; /** - * Stores information for making a request. In general this does not need to be constructed directly. + * Logs a deprecation message to the console. Use this function instead of + * <code>console.log</code> directly since this does not log duplicate messages + * unless it is called from multiple workers. * - * @alias Request - * @constructor + * @exports deprecationWarning * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.url] The url to request. - * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. - * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. - * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. - * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {String} identifier The unique identifier for this deprecated API. + * @param {String} message The message to log to the console. + * + * @example + * // Deprecated function or class + * function Foo() { + * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); + * // ... + * } + * + * // Deprecated function + * Bar.prototype.func = function() { + * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); + * // ... + * }; + * + * // Deprecated property + * defineProperties(Bar.prototype, { + * prop : { + * get : function() { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * }, + * set : function(value) { + * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); + * // ... + * } + * } + * }); + * + * @private */ - function Request(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - var throttleByServer = defaultValue(options.throttleByServer, false); - var throttle = throttleByServer || defaultValue(options.throttle, false); - - /** - * The URL to request. - * - * @type {String} - */ - this.url = options.url; + function deprecationWarning(identifier, message) { + if (!defined(identifier) || !defined(message)) { + throw new DeveloperError('identifier and message are required.'); + } + + oneTimeWarning(identifier, message); + } - /** - * The function that makes the actual data request. - * - * @type {Request~RequestCallback} - */ - this.requestFunction = options.requestFunction; - - /** - * The function that is called when the request is cancelled. - * - * @type {Request~CancelCallback} - */ - this.cancelFunction = options.cancelFunction; - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * - * @type {Request~PriorityCallback} - */ - this.priorityFunction = options.priorityFunction; - - /** - * Priority is a unit-less value where lower values represent higher priority. - * For world-based objects, this is usually the distance from the camera. - * A request that does not have a priority function defaults to a priority of 0. - * - * If priorityFunction is defined, this value is updated every frame with the result of that call. - * - * @type {Number} - * @default 0.0 - */ - this.priority = defaultValue(options.priority, 0.0); - - /** - * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the - * request will be throttled and sent based on priority. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttle = throttle; - - /** - * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections - * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value - * to <code>true</code> is preferable for requests going through HTTP/1 servers. - * - * @type {Boolean} - * @readonly - * - * @default false - */ - this.throttleByServer = throttleByServer; - - /** - * Type of request. - * - * @type {RequestType} - * @readonly - * - * @default RequestType.OTHER - */ - this.type = defaultValue(options.type, RequestType.OTHER); - - /** - * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. - * - * @type {String} - * - * @private - */ - this.serverKey = undefined; - - /** - * The current state of the request. - * - * @type {RequestState} - * @readonly - */ - this.state = RequestState.UNISSUED; - - /** - * The requests's deferred promise. - * - * @type {Object} - * - * @private - */ - this.deferred = undefined; - - /** - * Whether the request was explicitly cancelled. - * - * @type {Boolean} - * - * @private - */ - this.cancelled = false; - } - - /** - * Mark the request as cancelled. - * - * @private - */ - Request.prototype.cancel = function() { - this.cancelled = true; - }; - - /** - * The function that makes the actual data request. - * @callback Request~RequestCallback - * @returns {Promise} A promise for the requested data. - */ - - /** - * The function that is called when the request is cancelled. - * @callback Request~CancelCallback - */ - - /** - * The function that is called to update the request's priority, which occurs once per frame. - * @callback Request~PriorityCallback - * @returns {Number} The updated priority value. - */ - - return Request; -}); - -define('Core/parseResponseHeaders',[], function() { - 'use strict'; - - /** - * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into - * a dictionary. - * - * @exports parseResponseHeaders - * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is - * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value - * is that header's value. - * - * @private - */ - function parseResponseHeaders(headerString) { - var headers = {}; - - if (!headerString) { - return headers; - } - - var headerPairs = headerString.split('\u000d\u000a'); - - for (var i = 0; i < headerPairs.length; ++i) { - var headerPair = headerPairs[i]; - // Can't use split() here because it does the wrong thing - // if the header value has the string ": " in it. - var index = headerPair.indexOf('\u003a\u0020'); - if (index > 0) { - var key = headerPair.substring(0, index); - var val = headerPair.substring(index + 2); - headers[key] = val; - } - } - - return headers; - } - - return parseResponseHeaders; -}); - -define('Core/RequestErrorEvent',[ - './defined', - './parseResponseHeaders' - ], function( - defined, - parseResponseHeaders) { - 'use strict'; - - /** - * An event that is raised when a request encounters an error. - * - * @constructor - * @alias RequestErrorEvent - * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a - * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. - */ - function RequestErrorEvent(statusCode, response, responseHeaders) { - /** - * The HTTP error status code, such as 404. If the error does not have a particular - * HTTP code, this property will be undefined. - * - * @type {Number} - */ - this.statusCode = statusCode; - - /** - * The response included along with the error. If the error does not include a response, - * this property will be undefined. - * - * @type {Object} - */ - this.response = response; - - /** - * The headers included in the response, represented as an object literal of key/value pairs. - * If the error does not include any headers, this property will be undefined. - * - * @type {Object} - */ - this.responseHeaders = responseHeaders; - - if (typeof this.responseHeaders === 'string') { - this.responseHeaders = parseResponseHeaders(this.responseHeaders); - } - } - - /** - * Creates a string representing this RequestErrorEvent. - * @memberof RequestErrorEvent - * - * @returns {String} A string representing the provided RequestErrorEvent. - */ - RequestErrorEvent.prototype.toString = function() { - var str = 'Request has failed.'; - if (defined(this.statusCode)) { - str += ' Status Code: ' + this.statusCode; - } - return str; - }; - - return RequestErrorEvent; -}); + return deprecationWarning; +}); /** * @license @@ -18096,233 +18019,144 @@ define('ThirdParty/Uri',[],function() { return URI; }); -define('Core/Heap',[ - './Check', +define('Core/getAbsoluteUri',[ + '../ThirdParty/Uri', './defaultValue', './defined', - './defineProperties' + './DeveloperError' ], function( - Check, + Uri, defaultValue, defined, - defineProperties) { + DeveloperError) { 'use strict'; /** - * Array implementation of a heap. + * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. + * @exports getAbsoluteUri * - * @alias Heap - * @constructor - * @private + * @param {String} relative The relative Uri. + * @param {String} [base] The base Uri. + * @returns {String} The absolute Uri of the given relative Uri. * - * @param {Object} options Object with the following properties: - * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @example + * //absolute Uri will be "https://test.com/awesome.png"; + * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); */ - function Heap(options) { - Check.typeOf.object('options', options); - Check.defined('options.comparator', options.comparator); - - this._comparator = options.comparator; - this._array = []; - this._length = 0; - this._maximumLength = undefined; + function getAbsoluteUri(relative, base) { + return getAbsoluteUri._implementation(relative, base, document); } - defineProperties(Heap.prototype, { - /** - * Gets the length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - * @readonly - */ - length : { - get : function() { - return this._length; - } - }, - - /** - * Gets the internal array. - * - * @memberof Heap.prototype - * - * @type {Array} - * @readonly - */ - internalArray : { - get : function() { - return this._array; - } - }, - - /** - * Gets and sets the maximum length of the heap. - * - * @memberof Heap.prototype - * - * @type {Number} - */ - maximumLength : { - get : function() { - return this._maximumLength; - }, - set : function(value) { - this._maximumLength = value; - if (this._length > value && value > 0) { - this._length = value; - this._array.length = value; - } - } - }, - - /** - * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - * - * @memberof Heap.prototype - * - * @type {Heap~ComparatorCallback} - */ - comparator : { - get : function() { - return this._comparator; - } + getAbsoluteUri._implementation = function(relative, base, documentObject) { + if (!defined(relative)) { + throw new DeveloperError('relative uri is required.'); } - }); - - function swap(array, a, b) { - var temp = array[a]; - array[a] = array[b]; - array[b] = temp; - } - - /** - * Resizes the internal array of the heap. - * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. - */ - Heap.prototype.reserve = function(length) { - length = defaultValue(length, this._length); - this._array.length = length; + base = defaultValue(base, defaultValue(documentObject.baseURI, documentObject.location.href)); + var baseUri = new Uri(base); + var relativeUri = new Uri(relative); + return relativeUri.resolve(baseUri).toString(); }; - /** - * Update the heap so that index and all descendants satisfy the heap property. - * - * @param {Number} [index=0] The starting index to heapify from. - */ - Heap.prototype.heapify = function(index) { - index = defaultValue(index, 0); - var length = this._length; - var comparator = this._comparator; - var array = this._array; - var candidate = -1; - var inserting = true; - - while (inserting) { - var right = 2 * (index + 1); - var left = right - 1; - - if (left < length && comparator(array[left], array[index]) < 0) { - candidate = left; - } else { - candidate = index; - } - - if (right < length && comparator(array[right], array[candidate]) < 0) { - candidate = right; - } - if (candidate !== index) { - swap(array, candidate, index); - index = candidate; - } else { - inserting = false; - } - } - }; + return getAbsoluteUri; +}); - /** - * Resort the heap. - */ - Heap.prototype.resort = function() { - var length = this._length; - for (var i = Math.ceil(length / 2); i >= 0; --i) { - this.heapify(i); - } - }; +define('Core/getBaseUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Insert an element into the heap. If the length would grow greater than maximumLength - * of the heap, extra elements are removed. + * Given a URI, returns the base path of the URI. + * @exports getBaseUri * - * @param {*} element The element to insert + * @param {String} uri The Uri. + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {String} The base path of the Uri. * - * @return {*} The element that was removed from the heap if the heap is at full capacity. + * @example + * // basePath will be "/Gallery/"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); + * + * // basePath will be "/Gallery/?value=true&example=false"; + * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); */ - Heap.prototype.insert = function(element) { - Check.defined('element', element); + function getBaseUri(uri, includeQuery) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); + } - var array = this._array; - var comparator = this._comparator; - var maximumLength = this._maximumLength; + var basePath = ''; + var i = uri.lastIndexOf('/'); + if (i !== -1) { + basePath = uri.substring(0, i + 1); + } - var index = this._length++; - if (index < array.length) { - array[index] = element; - } else { - array.push(element); + if (!includeQuery) { + return basePath; } - while (index !== 0) { - var parent = Math.floor((index - 1) / 2); - if (comparator(array[index], array[parent]) < 0) { - swap(array, index, parent); - index = parent; - } else { - break; - } + uri = new Uri(uri); + if (defined(uri.query)) { + basePath += '?' + uri.query; + } + if (defined(uri.fragment)){ + basePath += '#' + uri.fragment; } - var removedElement; + return basePath; + } - if (defined(maximumLength) && (this._length > maximumLength)) { - removedElement = array[maximumLength]; - this._length = maximumLength; - } + return getBaseUri; +}); - return removedElement; - }; +define('Core/getExtensionFromUri',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; /** - * Remove the element specified by index from the heap and return it. + * Given a URI, returns the extension of the URI. + * @exports getExtensionFromUri * - * @param {Number} [index=0] The index to remove. - * @returns {*} The specified element of the heap. + * @param {String} uri The Uri. + * @returns {String} The extension of the Uri. + * + * @example + * //extension will be "czml"; + * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); */ - Heap.prototype.pop = function(index) { - index = defaultValue(index, 0); - if (this._length === 0) { - return undefined; + function getExtensionFromUri(uri) { + if (!defined(uri)) { + throw new DeveloperError('uri is required.'); } - Check.typeOf.number.lessThan('index', index, this._length); - var array = this._array; - var root = array[index]; - swap(array, index, --this._length); - this.heapify(index); - return root; - }; - - /** - * The comparator to use for the heap. - * @callback Heap~ComparatorCallback - * @param {*} a An element in the heap. - * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. - */ + var uriObject = new Uri(uri); + uriObject.normalize(); + var path = uriObject.path; + var index = path.lastIndexOf('/'); + if (index !== -1) { + path = path.substr(index + 1); + } + index = path.lastIndexOf('.'); + if (index === -1) { + path = ''; + } else { + path = path.substr(index + 1); + } + return path; + } - return Heap; + return getExtensionFromUri; }); define('Core/isBlobUri',[ @@ -18352,6 +18186,41 @@ define('Core/isBlobUri',[ return isBlobUri; }); +define('Core/isCrossOriginUrl',[ + './defined' + ], function( + defined) { + 'use strict'; + + var a; + + /** + * Given a URL, determine whether that URL is considered cross-origin to the current page. + * + * @private + */ + function isCrossOriginUrl(url) { + if (!defined(a)) { + a = document.createElement('a'); + } + + // copy window location into the anchor to get consistent results + // when the port is default for the protocol (e.g. 80 for HTTP) + a.href = window.location.href; + + // host includes both hostname and port if the port is not standard + var host = a.host; + var protocol = a.protocol; + + a.href = url; + a.href = a.href; // IE only absolutizes href on get, not set + + return protocol !== a.protocol || host !== a.host; + } + + return isCrossOriginUrl; +}); + define('Core/isDataUri',[ './Check' ], function( @@ -18379,652 +18248,2689 @@ define('Core/isDataUri',[ return isDataUri; }); -define('Core/RequestScheduler',[ - '../ThirdParty/Uri', - '../ThirdParty/when', - './Check', - './defined', - './defineProperties', - './Heap', - './isBlobUri', - './isDataUri', - './RequestState' +define('Core/isArray',[ + './defined' ], function( - Uri, - when, - Check, - defined, - defineProperties, - Heap, - isBlobUri, - isDataUri, + defined) { + 'use strict'; + + /** + * Tests an object to see if it is an array. + * @exports isArray + * + * @param {Object} value The value to test. + * @returns {Boolean} true if the value is an array, false otherwise. + */ + var isArray = Array.isArray; + if (!defined(isArray)) { + isArray = function(value) { + return Object.prototype.toString.call(value) === '[object Array]'; + }; + } + + return isArray; +}); + +define('Core/objectToQuery',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Converts an object representing a set of name/value pairs into a query string, + * with names and values encoded properly for use in a URL. Values that are arrays + * will produce multiple values with the same name. + * @exports objectToQuery + * + * @param {Object} obj The object containing data to encode. + * @returns {String} An encoded query string. + * + * + * @example + * var str = Cesium.objectToQuery({ + * key1 : 'some value', + * key2 : 'a/b', + * key3 : ['x', 'y'] + * }); + * + * @see queryToObject + * // str will be: + * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' + */ + function objectToQuery(obj) { + if (!defined(obj)) { + throw new DeveloperError('obj is required.'); + } + + var result = ''; + for ( var propName in obj) { + if (obj.hasOwnProperty(propName)) { + var value = obj[propName]; + + var part = encodeURIComponent(propName) + '='; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + result += part + encodeURIComponent(value[i]) + '&'; + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + + // trim last & + result = result.slice(0, -1); + + // This function used to replace %20 with + which is more compact and readable. + // However, some servers didn't properly handle + as a space. + // https://github.com/AnalyticalGraphicsInc/cesium/issues/2192 + + return result; + } + + return objectToQuery; +}); + +define('Core/queryToObject',[ + './defined', + './DeveloperError', + './isArray' + ], function( + defined, + DeveloperError, + isArray) { + 'use strict'; + + /** + * Parses a query string into an object, where the keys and values of the object are the + * name/value pairs from the query string, decoded. If a name appears multiple times, + * the value in the object will be an array of values. + * @exports queryToObject + * + * @param {String} queryString The query string. + * @returns {Object} An object containing the parameters parsed from the query string. + * + * + * @example + * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); + * // obj will be: + * // { + * // key1 : 'some value', + * // key2 : 'a/b', + * // key3 : ['x', 'y'] + * // } + * + * @see objectToQuery + */ + function queryToObject(queryString) { + if (!defined(queryString)) { + throw new DeveloperError('queryString is required.'); + } + + var result = {}; + if (queryString === '') { + return result; + } + var parts = queryString.replace(/\+/g, '%20').split(/[&;]/); + for (var i = 0, len = parts.length; i < len; ++i) { + var subparts = parts[i].split('='); + + var name = decodeURIComponent(subparts[0]); + var value = subparts[1]; + if (defined(value)) { + value = decodeURIComponent(value); + } else { + value = ''; + } + + var resultValue = result[name]; + if (typeof resultValue === 'string') { + // expand the single value to an array + result[name] = [resultValue, value]; + } else if (isArray(resultValue)) { + resultValue.push(value); + } else { + result[name] = value; + } + } + return result; + } + + return queryToObject; +}); + +define('Core/RequestState',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * State of the request. + * + * @exports RequestState + */ + var RequestState = { + /** + * Initial unissued state. + * + * @type Number + * @constant + */ + UNISSUED : 0, + + /** + * Issued but not yet active. Will become active when open slots are available. + * + * @type Number + * @constant + */ + ISSUED : 1, + + /** + * Actual http request has been sent. + * + * @type Number + * @constant + */ + ACTIVE : 2, + + /** + * Request completed successfully. + * + * @type Number + * @constant + */ + RECEIVED : 3, + + /** + * Request was cancelled, either explicitly or automatically because of low priority. + * + * @type Number + * @constant + */ + CANCELLED : 4, + + /** + * Request failed. + * + * @type Number + * @constant + */ + FAILED : 5 + }; + + return freezeObject(RequestState); +}); + +define('Core/RequestType',[ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * An enum identifying the type of request. Used for finer grained logging and priority sorting. + * + * @exports RequestType + */ + var RequestType = { + /** + * Terrain request. + * + * @type Number + * @constant + */ + TERRAIN : 0, + + /** + * Imagery request. + * + * @type Number + * @constant + */ + IMAGERY : 1, + + /** + * 3D Tiles request. + * + * @type Number + * @constant + */ + TILES3D : 2, + + /** + * Other request. + * + * @type Number + * @constant + */ + OTHER : 3 + }; + + return freezeObject(RequestType); +}); + +define('Core/Request',[ + './defaultValue', + './defined', + './RequestState', + './RequestType' + ], function( + defaultValue, + defined, + RequestState, + RequestType) { + 'use strict'; + + /** + * Stores information for making a request. In general this does not need to be constructed directly. + * + * @alias Request + * @constructor + * + * @param {Object} [options] An object with the following properties: + * @param {Boolean} [options.url] The url to request. + * @param {Request~RequestCallback} [options.requestFunction] The function that makes the actual data request. + * @param {Request~CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. + * @param {Request~PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. + * @param {Number} [options.priority=0.0] The initial priority of the request. + * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + */ + function Request(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + var throttleByServer = defaultValue(options.throttleByServer, false); + var throttle = throttleByServer || defaultValue(options.throttle, false); + + /** + * The URL to request. + * + * @type {String} + */ + this.url = options.url; + + /** + * The function that makes the actual data request. + * + * @type {Request~RequestCallback} + */ + this.requestFunction = options.requestFunction; + + /** + * The function that is called when the request is cancelled. + * + * @type {Request~CancelCallback} + */ + this.cancelFunction = options.cancelFunction; + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * + * @type {Request~PriorityCallback} + */ + this.priorityFunction = options.priorityFunction; + + /** + * Priority is a unit-less value where lower values represent higher priority. + * For world-based objects, this is usually the distance from the camera. + * A request that does not have a priority function defaults to a priority of 0. + * + * If priorityFunction is defined, this value is updated every frame with the result of that call. + * + * @type {Number} + * @default 0.0 + */ + this.priority = defaultValue(options.priority, 0.0); + + /** + * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the + * request will be throttled and sent based on priority. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttle = throttle; + + /** + * Whether to throttle the request by server. Browsers typically support about 6-8 parallel connections + * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value + * to <code>true</code> is preferable for requests going through HTTP/1 servers. + * + * @type {Boolean} + * @readonly + * + * @default false + */ + this.throttleByServer = throttleByServer; + + /** + * Type of request. + * + * @type {RequestType} + * @readonly + * + * @default RequestType.OTHER + */ + this.type = defaultValue(options.type, RequestType.OTHER); + + /** + * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. + * + * @type {String} + * + * @private + */ + this.serverKey = undefined; + + /** + * The current state of the request. + * + * @type {RequestState} + * @readonly + */ + this.state = RequestState.UNISSUED; + + /** + * The requests's deferred promise. + * + * @type {Object} + * + * @private + */ + this.deferred = undefined; + + /** + * Whether the request was explicitly cancelled. + * + * @type {Boolean} + * + * @private + */ + this.cancelled = false; + } + + /** + * Mark the request as cancelled. + * + * @private + */ + Request.prototype.cancel = function() { + this.cancelled = true; + }; + + + /** + * Duplicates a Request instance. + * + * @param {Request} [result] The object onto which to store the result. + * + * @returns {Request} The modified result parameter or a new Resource instance if one was not provided. + */ + Request.prototype.clone = function(result) { + if (!defined(result)) { + return new Request(this); + } + + result.url = this.url; + result.requestFunction = this.requestFunction; + result.cancelFunction = this.cancelFunction; + result.priorityFunction = this.priorityFunction; + result.priority = this.priority; + result.throttle = this.throttle; + result.throttleByServer = this.throttleByServer; + result.type = this.type; + result.serverKey = this.serverKey; + + // These get defaulted because the cloned request hasn't been issued + result.state = this.RequestState.UNISSUED; + result.deferred = undefined; + result.cancelled = false; + + return result; + }; + + /** + * The function that makes the actual data request. + * @callback Request~RequestCallback + * @returns {Promise} A promise for the requested data. + */ + + /** + * The function that is called when the request is cancelled. + * @callback Request~CancelCallback + */ + + /** + * The function that is called to update the request's priority, which occurs once per frame. + * @callback Request~PriorityCallback + * @returns {Number} The updated priority value. + */ + + return Request; +}); + +define('Core/parseResponseHeaders',[], function() { + 'use strict'; + + /** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ + function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; + } + + return parseResponseHeaders; +}); + +define('Core/RequestErrorEvent',[ + './defined', + './parseResponseHeaders' + ], function( + defined, + parseResponseHeaders) { + 'use strict'; + + /** + * An event that is raised when a request encounters an error. + * + * @constructor + * @alias RequestErrorEvent + * + * @param {Number} [statusCode] The HTTP error status code, such as 404. + * @param {Object} [response] The response included along with the error. + * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. + */ + function RequestErrorEvent(statusCode, response, responseHeaders) { + /** + * The HTTP error status code, such as 404. If the error does not have a particular + * HTTP code, this property will be undefined. + * + * @type {Number} + */ + this.statusCode = statusCode; + + /** + * The response included along with the error. If the error does not include a response, + * this property will be undefined. + * + * @type {Object} + */ + this.response = response; + + /** + * The headers included in the response, represented as an object literal of key/value pairs. + * If the error does not include any headers, this property will be undefined. + * + * @type {Object} + */ + this.responseHeaders = responseHeaders; + + if (typeof this.responseHeaders === 'string') { + this.responseHeaders = parseResponseHeaders(this.responseHeaders); + } + } + + /** + * Creates a string representing this RequestErrorEvent. + * @memberof RequestErrorEvent + * + * @returns {String} A string representing the provided RequestErrorEvent. + */ + RequestErrorEvent.prototype.toString = function() { + var str = 'Request has failed.'; + if (defined(this.statusCode)) { + str += ' Status Code: ' + this.statusCode; + } + return str; + }; + + return RequestErrorEvent; +}); + +define('Core/Event',[ + './Check', + './defined', + './defineProperties' + ], function( + Check, + defined, + defineProperties) { + 'use strict'; + + /** + * A generic utility class for managing subscribers for a particular event. + * This class is usually instantiated inside of a container class and + * exposed as a property for others to subscribe to. + * + * @alias Event + * @constructor + * + * @example + * MyObject.prototype.myListener = function(arg1, arg2) { + * this.myArg1Copy = arg1; + * this.myArg2Copy = arg2; + * } + * + * var myObjectInstance = new MyObject(); + * var evt = new Cesium.Event(); + * evt.addEventListener(MyObject.prototype.myListener, myObjectInstance); + * evt.raiseEvent('1', '2'); + * evt.removeEventListener(MyObject.prototype.myListener); + */ + function Event() { + this._listeners = []; + this._scopes = []; + this._toRemove = []; + this._insideRaiseEvent = false; + } + + defineProperties(Event.prototype, { + /** + * The number of listeners currently subscribed to the event. + * @memberof Event.prototype + * @type {Number} + * @readonly + */ + numberOfListeners : { + get : function() { + return this._listeners.length - this._toRemove.length; + } + } + }); + + /** + * Registers a callback function to be executed whenever the event is raised. + * An optional scope can be provided to serve as the <code>this</code> pointer + * in which the function will execute. + * + * @param {Function} listener The function to be executed when the event is raised. + * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * pointer in which the listener function will execute. + * @returns {Event~RemoveCallback} A function that will remove this event listener when invoked. + * + * @see Event#raiseEvent + * @see Event#removeEventListener + */ + Event.prototype.addEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + this._listeners.push(listener); + this._scopes.push(scope); + + var event = this; + return function() { + event.removeEventListener(listener, scope); + }; + }; + + /** + * Unregisters a previously registered callback. + * + * @param {Function} listener The function to be unregistered. + * @param {Object} [scope] The scope that was originally passed to addEventListener. + * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * + * @see Event#addEventListener + * @see Event#raiseEvent + */ + Event.prototype.removeEventListener = function(listener, scope) { + Check.typeOf.func('listener', listener); + + var listeners = this._listeners; + var scopes = this._scopes; + + var index = -1; + for (var i = 0; i < listeners.length; i++) { + if (listeners[i] === listener && scopes[i] === scope) { + index = i; + break; + } + } + + if (index !== -1) { + if (this._insideRaiseEvent) { + //In order to allow removing an event subscription from within + //a callback, we don't actually remove the items here. Instead + //remember the index they are at and undefined their value. + this._toRemove.push(index); + listeners[index] = undefined; + scopes[index] = undefined; + } else { + listeners.splice(index, 1); + scopes.splice(index, 1); + } + return true; + } + + return false; + }; + + function compareNumber(a,b) { + return b - a; + } + + /** + * Raises the event by calling each registered listener with all supplied arguments. + * + * @param {*} arguments This method takes any number of parameters and passes them through to the listener functions. + * + * @see Event#addEventListener + * @see Event#removeEventListener + */ + Event.prototype.raiseEvent = function() { + this._insideRaiseEvent = true; + + var i; + var listeners = this._listeners; + var scopes = this._scopes; + var length = listeners.length; + + for (i = 0; i < length; i++) { + var listener = listeners[i]; + if (defined(listener)) { + listeners[i].apply(scopes[i], arguments); + } + } + + //Actually remove items removed in removeEventListener. + var toRemove = this._toRemove; + length = toRemove.length; + if (length > 0) { + toRemove.sort(compareNumber); + for (i = 0; i < length; i++) { + var index = toRemove[i]; + listeners.splice(index, 1); + scopes.splice(index, 1); + } + toRemove.length = 0; + } + + this._insideRaiseEvent = false; + }; + + /** + * A function that removes a listener. + * @callback Event~RemoveCallback + */ + + return Event; +}); + +define('Core/Heap',[ + './Check', + './defaultValue', + './defined', + './defineProperties' + ], function( + Check, + defaultValue, + defined, + defineProperties) { + 'use strict'; + + /** + * Array implementation of a heap. + * + * @alias Heap + * @constructor + * @private + * + * @param {Object} options Object with the following properties: + * @param {Heap~ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + function Heap(options) { + Check.typeOf.object('options', options); + Check.defined('options.comparator', options.comparator); + + this._comparator = options.comparator; + this._array = []; + this._length = 0; + this._maximumLength = undefined; + } + + defineProperties(Heap.prototype, { + /** + * Gets the length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + * @readonly + */ + length : { + get : function() { + return this._length; + } + }, + + /** + * Gets the internal array. + * + * @memberof Heap.prototype + * + * @type {Array} + * @readonly + */ + internalArray : { + get : function() { + return this._array; + } + }, + + /** + * Gets and sets the maximum length of the heap. + * + * @memberof Heap.prototype + * + * @type {Number} + */ + maximumLength : { + get : function() { + return this._maximumLength; + }, + set : function(value) { + this._maximumLength = value; + if (this._length > value && value > 0) { + this._length = value; + this._array.length = value; + } + } + }, + + /** + * The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * + * @memberof Heap.prototype + * + * @type {Heap~ComparatorCallback} + */ + comparator : { + get : function() { + return this._comparator; + } + } + }); + + function swap(array, a, b) { + var temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + /** + * Resizes the internal array of the heap. + * + * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + */ + Heap.prototype.reserve = function(length) { + length = defaultValue(length, this._length); + this._array.length = length; + }; + + /** + * Update the heap so that index and all descendants satisfy the heap property. + * + * @param {Number} [index=0] The starting index to heapify from. + */ + Heap.prototype.heapify = function(index) { + index = defaultValue(index, 0); + var length = this._length; + var comparator = this._comparator; + var array = this._array; + var candidate = -1; + var inserting = true; + + while (inserting) { + var right = 2 * (index + 1); + var left = right - 1; + + if (left < length && comparator(array[left], array[index]) < 0) { + candidate = left; + } else { + candidate = index; + } + + if (right < length && comparator(array[right], array[candidate]) < 0) { + candidate = right; + } + if (candidate !== index) { + swap(array, candidate, index); + index = candidate; + } else { + inserting = false; + } + } + }; + + /** + * Resort the heap. + */ + Heap.prototype.resort = function() { + var length = this._length; + for (var i = Math.ceil(length / 2); i >= 0; --i) { + this.heapify(i); + } + }; + + /** + * Insert an element into the heap. If the length would grow greater than maximumLength + * of the heap, extra elements are removed. + * + * @param {*} element The element to insert + * + * @return {*} The element that was removed from the heap if the heap is at full capacity. + */ + Heap.prototype.insert = function(element) { + Check.defined('element', element); + + var array = this._array; + var comparator = this._comparator; + var maximumLength = this._maximumLength; + + var index = this._length++; + if (index < array.length) { + array[index] = element; + } else { + array.push(element); + } + + while (index !== 0) { + var parent = Math.floor((index - 1) / 2); + if (comparator(array[index], array[parent]) < 0) { + swap(array, index, parent); + index = parent; + } else { + break; + } + } + + var removedElement; + + if (defined(maximumLength) && (this._length > maximumLength)) { + removedElement = array[maximumLength]; + this._length = maximumLength; + } + + return removedElement; + }; + + /** + * Remove the element specified by index from the heap and return it. + * + * @param {Number} [index=0] The index to remove. + * @returns {*} The specified element of the heap. + */ + Heap.prototype.pop = function(index) { + index = defaultValue(index, 0); + if (this._length === 0) { + return undefined; + } + Check.typeOf.number.lessThan('index', index, this._length); + + var array = this._array; + var root = array[index]; + swap(array, index, --this._length); + this.heapify(index); + return root; + }; + + /** + * The comparator to use for the heap. + * @callback Heap~ComparatorCallback + * @param {*} a An element in the heap. + * @param {*} b An element in the heap. + * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + */ + + return Heap; +}); + +define('Core/RequestScheduler',[ + '../ThirdParty/Uri', + '../ThirdParty/when', + './Check', + './defined', + './defineProperties', + './Event', + './Heap', + './isBlobUri', + './isDataUri', + './RequestState' + ], function( + Uri, + when, + Check, + defined, + defineProperties, + Event, + Heap, + isBlobUri, + isDataUri, RequestState) { 'use strict'; - function sortRequests(a, b) { - return a.priority - b.priority; + function sortRequests(a, b) { + return a.priority - b.priority; + } + + var statistics = { + numberOfAttemptedRequests : 0, + numberOfActiveRequests : 0, + numberOfCancelledRequests : 0, + numberOfCancelledActiveRequests : 0, + numberOfFailedRequests : 0, + numberOfActiveRequestsEver : 0 + }; + + var priorityHeapLength = 20; + var requestHeap = new Heap({ + comparator : sortRequests + }); + requestHeap.maximumLength = priorityHeapLength; + requestHeap.reserve(priorityHeapLength); + + var activeRequests = []; + var numberOfActiveRequestsByServer = {}; + + var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); + + var requestCompletedEvent = new Event(); + + /** + * Tracks the number of active requests and prioritizes incoming requests. + * + * @exports RequestScheduler + * + * @private + */ + function RequestScheduler() { + } + + /** + * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 50 + */ + RequestScheduler.maximumRequests = 50; + + /** + * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. + * @type {Number} + * @default 6 + */ + RequestScheduler.maximumRequestsPerServer = 6; + + /** + * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. + * @type {Boolean} + * @default true + */ + RequestScheduler.throttleRequests = true; + + /** + * When true, log statistics to the console every frame + * @type {Boolean} + * @default false + */ + RequestScheduler.debugShowStatistics = false; + + /** + * An event that's raised when a request is completed. Event handlers are passed + * the error object if the request fails. + * + * @type {Event} + * @default Event() + */ + RequestScheduler.requestCompletedEvent = requestCompletedEvent; + + defineProperties(RequestScheduler, { + /** + * Returns the statistics used by the request scheduler. + * + * @memberof RequestScheduler + * + * @type Object + * @readonly + */ + statistics : { + get : function() { + return statistics; + } + }, + + /** + * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * + * @memberof RequestScheduler + * + * @type {Number} + * @default 20 + */ + priorityHeapLength : { + get : function() { + return priorityHeapLength; + }, + set : function(value) { + // If the new length shrinks the heap, need to cancel some of the requests. + // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. + if (value < priorityHeapLength) { + while (requestHeap.length > value) { + var request = requestHeap.pop(); + cancelRequest(request); + } + } + priorityHeapLength = value; + requestHeap.maximumLength = value; + requestHeap.reserve(value); + } + } + }); + + function updatePriority(request) { + if (defined(request.priorityFunction)) { + request.priority = request.priorityFunction(); + } + } + + function serverHasOpenSlots(serverKey) { + return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; + } + + function issueRequest(request) { + if (request.state === RequestState.UNISSUED) { + request.state = RequestState.ISSUED; + request.deferred = when.defer(); + } + return request.deferred.promise; + } + + function getRequestReceivedFunction(request) { + return function(results) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + request.deferred.resolve(results); + }; + } + + function getRequestFailedFunction(request) { + return function(error) { + if (request.state === RequestState.CANCELLED) { + // If the data request comes back but the request is cancelled, ignore it. + return; + } + ++statistics.numberOfFailedRequests; + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + requestCompletedEvent.raiseEvent(error); + request.state = RequestState.FAILED; + request.deferred.reject(error); + }; + } + + function startRequest(request) { + var promise = issueRequest(request); + request.state = RequestState.ACTIVE; + activeRequests.push(request); + ++statistics.numberOfActiveRequests; + ++statistics.numberOfActiveRequestsEver; + ++numberOfActiveRequestsByServer[request.serverKey]; + request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); + return promise; + } + + function cancelRequest(request) { + var active = request.state === RequestState.ACTIVE; + request.state = RequestState.CANCELLED; + ++statistics.numberOfCancelledRequests; + request.deferred.reject(); + + if (active) { + --statistics.numberOfActiveRequests; + --numberOfActiveRequestsByServer[request.serverKey]; + ++statistics.numberOfCancelledActiveRequests; + } + + if (defined(request.cancelFunction)) { + request.cancelFunction(); + } + } + + /** + * Sort requests by priority and start requests. + */ + RequestScheduler.update = function() { + var i; + var request; + + // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. + var removeCount = 0; + var activeLength = activeRequests.length; + for (i = 0; i < activeLength; ++i) { + request = activeRequests[i]; + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + } + if (request.state !== RequestState.ACTIVE) { + // Request is no longer active, remove from array + ++removeCount; + continue; + } + if (removeCount > 0) { + // Shift back to fill in vacated slots from completed requests + activeRequests[i - removeCount] = request; + } + } + activeRequests.length -= removeCount; + + // Update priority of issued requests and resort the heap + var issuedRequests = requestHeap.internalArray; + var issuedLength = requestHeap.length; + for (i = 0; i < issuedLength; ++i) { + updatePriority(issuedRequests[i]); + } + requestHeap.resort(); + + // Get the number of open slots and fill with the highest priority requests. + // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests + var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); + var filledSlots = 0; + while (filledSlots < openSlots && requestHeap.length > 0) { + // Loop until all open slots are filled or the heap becomes empty + request = requestHeap.pop(); + if (request.cancelled) { + // Request was explicitly cancelled + cancelRequest(request); + continue; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Open slots are available, but the request is throttled by its server. Cancel and try again later. + cancelRequest(request); + continue; + } + + startRequest(request); + ++filledSlots; + } + + updateStatistics(); + }; + + /** + * Get the server key from a given url. + * + * @param {String} url The url. + * @returns {String} The server key. + */ + RequestScheduler.getServerKey = function(url) { + Check.typeOf.string('url', url); + + var uri = new Uri(url).resolve(pageUri); + uri.normalize(); + var serverKey = uri.authority; + if (!/:/.test(serverKey)) { + // If the authority does not contain a port number, add port 443 for https or port 80 for http + serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); + } + + var length = numberOfActiveRequestsByServer[serverKey]; + if (!defined(length)) { + numberOfActiveRequestsByServer[serverKey] = 0; + } + + return serverKey; + }; + + /** + * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be + * queued and sorted by priority before being sent. + * + * @param {Request} request The request object. + * + * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + */ + RequestScheduler.request = function(request) { + Check.typeOf.object('request', request); + Check.typeOf.string('request.url', request.url); + Check.typeOf.func('request.requestFunction', request.requestFunction); + + if (isDataUri(request.url) || isBlobUri(request.url)) { + requestCompletedEvent.raiseEvent(); + request.state = RequestState.RECEIVED; + return request.requestFunction(); + } + + ++statistics.numberOfAttemptedRequests; + + if (!defined(request.serverKey)) { + request.serverKey = RequestScheduler.getServerKey(request.url); + } + + if (!RequestScheduler.throttleRequests || !request.throttle) { + return startRequest(request); + } + + if (activeRequests.length >= RequestScheduler.maximumRequests) { + // Active requests are saturated. Try again later. + return undefined; + } + + if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { + // Server is saturated. Try again later. + return undefined; + } + + // Insert into the priority heap and see if a request was bumped off. If this request is the lowest + // priority it will be returned. + updatePriority(request); + var removedRequest = requestHeap.insert(request); + + if (defined(removedRequest)) { + if (removedRequest === request) { + // Request does not have high enough priority to be issued + return undefined; + } + // A previously issued request has been bumped off the priority heap, so cancel it + cancelRequest(removedRequest); + } + + return issueRequest(request); + }; + + function clearStatistics() { + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + } + + function updateStatistics() { + if (!RequestScheduler.debugShowStatistics) { + return; + } + + if (statistics.numberOfAttemptedRequests > 0) { + console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); + } + if (statistics.numberOfActiveRequests > 0) { + console.log('Number of active requests: ' + statistics.numberOfActiveRequests); + } + if (statistics.numberOfCancelledRequests > 0) { + console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); + } + if (statistics.numberOfCancelledActiveRequests > 0) { + console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); + } + if (statistics.numberOfFailedRequests > 0) { + console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); + } + + clearStatistics(); + } + + /** + * For testing only. Clears any requests that may not have completed from previous tests. + * + * @private + */ + RequestScheduler.clearForSpecs = function() { + while (requestHeap.length > 0) { + var request = requestHeap.pop(); + cancelRequest(request); + } + var length = activeRequests.length; + for (var i = 0; i < length; ++i) { + cancelRequest(activeRequests[i]); + } + activeRequests.length = 0; + numberOfActiveRequestsByServer = {}; + + // Clear stats + statistics.numberOfAttemptedRequests = 0; + statistics.numberOfActiveRequests = 0; + statistics.numberOfCancelledRequests = 0; + statistics.numberOfCancelledActiveRequests = 0; + statistics.numberOfFailedRequests = 0; + statistics.numberOfActiveRequestsEver = 0; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { + return numberOfActiveRequestsByServer[serverKey]; + }; + + /** + * For testing only. + * + * @private + */ + RequestScheduler.requestHeap = requestHeap; + + return RequestScheduler; +}); + +define('Core/TrustedServers',[ + '../ThirdParty/Uri', + './defined', + './DeveloperError' + ], function( + Uri, + defined, + DeveloperError) { + 'use strict'; + + /** + * A singleton that contains all of the servers that are trusted. Credentials will be sent with + * any requests to these servers. + * + * @exports TrustedServers + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + */ + var TrustedServers = {}; + var _servers = {}; + + /** + * Adds a trusted server to the registry + * + * @param {String} host The host to be added. + * @param {Number} port The port used to access the host. + * + * @example + * // Add a trusted server + * TrustedServers.add('my.server.com', 80); + */ + TrustedServers.add = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (!defined(_servers[authority])) { + _servers[authority] = true; + } + }; + + /** + * Removes a trusted server from the registry + * + * @param {String} host The host to be removed. + * @param {Number} port The port used to access the host. + * + * @example + * // Remove a trusted server + * TrustedServers.remove('my.server.com', 80); + */ + TrustedServers.remove = function(host, port) { + if (!defined(host)) { + throw new DeveloperError('host is required.'); + } + if (!defined(port) || port <= 0) { + throw new DeveloperError('port is required to be greater than 0.'); + } + + var authority = host.toLowerCase() + ':' + port; + if (defined(_servers[authority])) { + delete _servers[authority]; + } + }; + + function getAuthority(url) { + var uri = new Uri(url); + uri.normalize(); + + // Removes username:password@ so we just have host[:port] + var authority = uri.getAuthority(); + if (!defined(authority)) { + return undefined; // Relative URL + } + + if (authority.indexOf('@') !== -1) { + var parts = authority.split('@'); + authority = parts[1]; + } + + // If the port is missing add one based on the scheme + if (authority.indexOf(':') === -1) { + var scheme = uri.getScheme(); + if (!defined(scheme)) { + scheme = window.location.protocol; + scheme = scheme.substring(0, scheme.length-1); + } + if (scheme === 'http') { + authority += ':80'; + } else if (scheme === 'https') { + authority += ':443'; + } else { + return undefined; + } + } + + return authority; } - var statistics = { - numberOfAttemptedRequests : 0, - numberOfActiveRequests : 0, - numberOfCancelledRequests : 0, - numberOfCancelledActiveRequests : 0, - numberOfFailedRequests : 0, - numberOfActiveRequestsEver : 0 + /** + * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. + * + * @param {String} url The url to be tested against the trusted list + * + * @returns {boolean} Returns true if url is trusted, false otherwise. + * + * @example + * // Add server + * TrustedServers.add('my.server.com', 81); + * + * // Check if server is trusted + * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { + * // my.server.com:81 is trusted + * } + * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { + * // my.server.com isn't trusted + * } + */ + TrustedServers.contains = function(url) { + if (!defined(url)) { + throw new DeveloperError('url is required.'); + } + var authority = getAuthority(url); + if (defined(authority) && defined(_servers[authority])) { + return true; + } + + return false; }; - var priorityHeapLength = 20; - var requestHeap = new Heap({ - comparator : sortRequests - }); - requestHeap.maximumLength = priorityHeapLength; - requestHeap.reserve(priorityHeapLength); + /** + * Clears the registry + * + * @example + * // Remove a trusted server + * TrustedServers.clear(); + */ + TrustedServers.clear = function() { + _servers = {}; + }; - var activeRequests = []; - var numberOfActiveRequestsByServer = {}; + return TrustedServers; +}); - var pageUri = typeof document !== 'undefined' ? new Uri(document.location.href) : new Uri(); +define('Core/Resource',[ + './appendForwardSlash', + './Check', + './clone', + './combine', + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + './freezeObject', + './getAbsoluteUri', + './getBaseUri', + './getExtensionFromUri', + './isBlobUri', + './isCrossOriginUrl', + './isDataUri', + './objectToQuery', + './queryToObject', + './Request', + './RequestErrorEvent', + './RequestScheduler', + './RequestState', + './RuntimeError', + './TrustedServers', + '../ThirdParty/Uri', + '../ThirdParty/when' +], function(appendForwardSlash, + Check, + clone, + combine, + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + freezeObject, + getAbsoluteUri, + getBaseUri, + getExtensionFromUri, + isBlobUri, + isCrossOriginUrl, + isDataUri, + objectToQuery, + queryToObject, + Request, + RequestErrorEvent, + RequestScheduler, + RequestState, + RuntimeError, + TrustedServers, + Uri, + when) { + 'use strict'; + + var xhrBlobSupported = (function() { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '#', true); + xhr.responseType = 'blob'; + return xhr.responseType === 'blob'; + } catch (e) { + return false; + } + })(); /** - * Tracks the number of active requests and prioritizes incoming requests. + * @private + */ + function parseQuery(uri, resource) { + var queryString = uri.query; + if (!defined(queryString) || (queryString.length === 0)) { + return {}; + } + + var query; + // Special case we run into where the querystring is just a string, not key/value pairs + if (queryString.indexOf('=') === -1) { + var result = {}; + result[queryString] = undefined; + query = result; + } else { + query = queryToObject(queryString); + } + + resource._queryParameters = combine(resource._queryParameters, query); + uri.query = undefined; + } + + /** + * @private + */ + function stringifyQuery(uri, resource) { + var queryObject = resource._queryParameters; + + var keys = Object.keys(queryObject); + + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + uri.query = keys[0]; + } else { + uri.query = objectToQuery(queryObject); + } + } + + /** + * @private + */ + function defaultClone(obj, defaultVal) { + if (!defined(obj)) { + return defaultVal; + } + + return defined(obj.clone) ? obj.clone() : clone(obj); + } + + /** + * @private + */ + function checkAndResetRequest(request) { + if (request.state === RequestState.ISSUED || request.state === RequestState.ACTIVE) { + throw new RuntimeError('The Resource is already being fetched.'); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; + } + + /** + * A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests. * - * @exports RequestScheduler + * @alias Resource + * @constructor * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @example + * function refreshTokenRetryCallback(resource, error) { + * if (error.statusCode === 403) { + * // 403 status code means a new token should be generated + * return getNewAccessToken() + * .then(function(token) { + * resource.queryParameters.access_token = token; + * return true; + * }) + * .otherwise(function() { + * return false; + * }); + * } + * + * return false; + * } + * + * var resource = new Resource({ + * url: 'http://server.com/path/to/resource.json', + * proxy: new DefaultProxy('/proxy/'), + * headers: { + * 'X-My-Header': 'valueOfHeader' + * }, + * queryParameters: { + * 'access_token': '123-435-456-000' + * }, + * retryCallback: refreshTokenRetryCallback, + * retryAttempts: 1 + * }); */ - function RequestScheduler() { + function Resource(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + if (typeof options === 'string') { + options = { + url: options + }; + } + + Check.typeOf.string('options.url', options.url); + + this._url = undefined; + this._templateValues = defaultClone(options.templateValues, {}); + this._queryParameters = defaultClone(options.queryParameters, {}); + + /** + * Additional HTTP headers that will be sent with the request. + * + * @type {Object} + */ + this.headers = defaultClone(options.headers, {}); + + /** + * A Request object that will be used. Intended for internal use only. + * + * @type {Request} + */ + this.request = defaultValue(options.request, new Request()); + + /** + * A proxy to be used when loading the resource. + * + * @type {DefaultProxy} + */ + this.proxy = options.proxy; + + /** + * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried. + * + * @type {Function} + */ + this.retryCallback = options.retryCallback; + + /** + * The number of times the retryCallback should be called before giving up. + * + * @type {Number} + */ + this.retryAttempts = defaultValue(options.retryAttempts, 0); + this._retryCount = 0; + + this.url = options.url; } - /** - * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 50 - */ - RequestScheduler.maximumRequests = 50; + /** + * A helper function to create a resource depending on whether we have a String or a Resource + * + * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Object} options If resource is a String, these are the options passed to the Resource constructor. It is ignored otherwise. + * + * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. + * + * @private + */ + Resource.createIfNeeded = function(resource, options) { + if (resource instanceof Resource) { + return resource.clone(); + } + + if (typeof resource !== 'string') { + return resource; + } + + var args = defaultClone(options, {}); + args.url = resource; + return new Resource(args); + }; + + defineProperties(Resource, { + /** + * Returns true if blobs are supported. + * + * @memberof Resource + * @type {Boolean} + * + * @readonly + */ + isBlobSupported : { + get : function() { + return xhrBlobSupported; + } + } + }); + + defineProperties(Resource.prototype, { + /** + * Query parameters appended to the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + queryParameters: { + get: function() { + return this._queryParameters; + } + }, + + /** + * The key/value pairs used to replace template parameters in the url. + * + * @memberof Resource.prototype + * @type {Object} + * + * @readonly + */ + templateValues: { + get: function() { + return this._templateValues; + } + }, + + /** + * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. + * + * @memberof Resource.prototype + * @type {String} + */ + url: { + get: function() { + return this.getUrlComponent(true, true); + }, + set: function(value) { + var uri = new Uri(value); - /** - * The maximum number of simultaneous active requests per server. Un-throttled requests do not observe this limit. - * @type {Number} - * @default 6 - */ - RequestScheduler.maximumRequestsPerServer = 6; + parseQuery(uri, this); - /** - * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} - * @default true - */ - RequestScheduler.throttleRequests = true; + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; - /** - * When true, log statistics to the console every frame - * @type {Boolean} - * @default false - */ - RequestScheduler.debugShowStatistics = false; + this._url = uri.toString(); + } + }, - defineProperties(RequestScheduler, { /** - * Returns the statistics used by the request scheduler. + * The file extension of the resource. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {String} * - * @type Object * @readonly */ - statistics : { - get : function() { - return statistics; + extension: { + get: function() { + return getExtensionFromUri(this._url); } }, /** - * The maximum size of the priority heap. This limits the number of requests that are sorted by priority. Only applies to requests that are not yet active. + * True if the Resource refers to a data URI. * - * @memberof RequestScheduler + * @memberof Resource.prototype + * @type {Boolean} + */ + isDataUri: { + get: function() { + return isDataUri(this._url); + } + }, + + /** + * True if the Resource refers to a blob URI. * - * @type {Number} - * @default 20 + * @memberof Resource.prototype + * @type {Boolean} */ - priorityHeapLength : { - get : function() { - return priorityHeapLength; - }, - set : function(value) { - // If the new length shrinks the heap, need to cancel some of the requests. - // Since this value is not intended to be tweaked regularly it is fine to just cancel the high priority requests. - if (value < priorityHeapLength) { - while (requestHeap.length > value) { - var request = requestHeap.pop(); - cancelRequest(request); - } - } - priorityHeapLength = value; - requestHeap.maximumLength = value; - requestHeap.reserve(value); + isBlobUri: { + get: function() { + return isBlobUri(this._url); + } + }, + + /** + * True if the Resource refers to a cross origin URL. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + isCrossOriginUrl: { + get: function() { + return isCrossOriginUrl(this._url); + } + }, + + /** + * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. + * + * @memberof Resource.prototype + * @type {Boolean} + */ + hasHeaders: { + get: function() { + return (Object.keys(this.headers).length > 0); } } }); - function updatePriority(request) { - if (defined(request.priorityFunction)) { - request.priority = request.priorityFunction(); + /** + * Returns the url, optional with the query string and processed by a proxy. + * + * @param {Boolean} [query=false] If true, the query string is included. + * @param {Boolean} [proxy=false] If true, the url is processed the proxy object if defined. + * + * @returns {String} The url with all the requested components. + */ + Resource.prototype.getUrlComponent = function(query, proxy) { + if(this.isDataUri) { + return this._url; } - } - function serverHasOpenSlots(serverKey) { - return numberOfActiveRequestsByServer[serverKey] < RequestScheduler.maximumRequestsPerServer; - } + var uri = new Uri(this._url); - function issueRequest(request) { - if (request.state === RequestState.UNISSUED) { - request.state = RequestState.ISSUED; - request.deferred = when.defer(); + if (query) { + stringifyQuery(uri, this); } - return request.deferred.promise; - } - function getRequestReceivedFunction(request) { - return function(results) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; - } - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.RECEIVED; - request.deferred.resolve(results); - }; - } + // objectToQuery escapes the placeholders. Undo that. + var url = uri.toString().replace(/%7B/g, '{').replace(/%7D/g, '}'); - function getRequestFailedFunction(request) { - return function(error) { - if (request.state === RequestState.CANCELLED) { - // If the data request comes back but the request is cancelled, ignore it. - return; + var template = this._templateValues; + var keys = Object.keys(template); + if (keys.length > 0) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = template[key]; + url = url.replace(new RegExp('{' + key + '}', 'g'), encodeURIComponent(value)); } - ++statistics.numberOfFailedRequests; - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - request.state = RequestState.FAILED; - request.deferred.reject(error); - }; - } - - function startRequest(request) { - var promise = issueRequest(request); - request.state = RequestState.ACTIVE; - activeRequests.push(request); - ++statistics.numberOfActiveRequests; - ++statistics.numberOfActiveRequestsEver; - ++numberOfActiveRequestsByServer[request.serverKey]; - request.requestFunction().then(getRequestReceivedFunction(request)).otherwise(getRequestFailedFunction(request)); - return promise; - } - - function cancelRequest(request) { - var active = request.state === RequestState.ACTIVE; - request.state = RequestState.CANCELLED; - ++statistics.numberOfCancelledRequests; - request.deferred.reject(); + } + if (proxy && defined(this.proxy)) { + url = this.proxy.getURL(url); + } + return url; + }; - if (active) { - --statistics.numberOfActiveRequests; - --numberOfActiveRequestsByServer[request.serverKey]; - ++statistics.numberOfCancelledActiveRequests; + /** + * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, + * as opposed to adding them one at a time to the queryParameters property. + * + * @param {Object} params The query parameters + * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addQueryParameters = function(params, useAsDefault) { + if (useAsDefault) { + this._queryParameters = combine(this._queryParameters, params); + } else { + this._queryParameters = combine(params, this._queryParameters); } + }; - if (defined(request.cancelFunction)) { - request.cancelFunction(); + /** + * Combines the specified object and the existing template values. This allows you to add many values at once, + * as opposed to adding them one at a time to the templateValues property. + * + * @param {Object} params The template values + * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + */ + Resource.prototype.addTemplateValues = function(template, useAsDefault) { + if (useAsDefault) { + this._templateValues = combine(this._templateValues, template); + } else { + this._templateValues = combine(template, this._templateValues); } - } + }; /** - * Sort requests by priority and start requests. + * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. + * + * @param {Object} options An object with the following properties + * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The function to call when loading the resource fails. + * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * + * @returns {Resource} The resource derived from the current one. */ - RequestScheduler.update = function() { - var i; - var request; + Resource.prototype.getDerivedResource = function(options) { + var resource = this.clone(); + resource._retryCount = 0; - // Loop over all active requests. Cancelled, failed, or received requests are removed from the array to make room for new requests. - var removeCount = 0; - var activeLength = activeRequests.length; - for (i = 0; i < activeLength; ++i) { - request = activeRequests[i]; - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - } - if (request.state !== RequestState.ACTIVE) { - // Request is no longer active, remove from array - ++removeCount; - continue; - } - if (removeCount > 0) { - // Shift back to fill in vacated slots from completed requests - activeRequests[i - removeCount] = request; - } + if (defined(options.url)) { + var uri = new Uri(options.url); + + parseQuery(uri, resource); + + // Remove the fragment as it's not sent with a request + uri.fragment = undefined; + + resource._url = uri.resolve(new Uri(getAbsoluteUri(this._url))).toString(); } - activeRequests.length -= removeCount; - // Update priority of issued requests and resort the heap - var issuedRequests = requestHeap.internalArray; - var issuedLength = requestHeap.length; - for (i = 0; i < issuedLength; ++i) { - updatePriority(issuedRequests[i]); + if (defined(options.queryParameters)) { + resource._queryParameters = combine(options.queryParameters, resource._queryParameters); + } + if (defined(options.templateValues)) { + resource._templateValues = combine(options.templateValues, resource.templateValues); + } + if (defined(options.headers)) { + resource.headers = combine(options.headers, resource.headers); + } + if (defined(options.proxy)) { + resource.proxy = options.proxy; + } + if (defined(options.request)) { + resource.request = options.request; + } else { + // Clone the request so we keep all the throttle settings + resource.request = this.request.clone(); + } + if (defined(options.retryCallback)) { + resource.retryCallback = options.retryCallback; + } + if (defined(options.retryAttempts)) { + resource.retryAttempts = options.retryAttempts; } - requestHeap.resort(); - // Get the number of open slots and fill with the highest priority requests. - // Un-throttled requests are automatically added to activeRequests, so activeRequests.length may exceed maximumRequests - var openSlots = Math.max(RequestScheduler.maximumRequests - activeRequests.length, 0); - var filledSlots = 0; - while (filledSlots < openSlots && requestHeap.length > 0) { - // Loop until all open slots are filled or the heap becomes empty - request = requestHeap.pop(); - if (request.cancelled) { - // Request was explicitly cancelled - cancelRequest(request); - continue; - } + return resource; + }; - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Open slots are available, but the request is throttled by its server. Cancel and try again later. - cancelRequest(request); - continue; - } + /** + * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. + * + * @param {Error} [error] The error that was encountered. + * + * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. + */ + Resource.prototype.retryOnError = function(error) { + var retryCallback = this.retryCallback; + if ((typeof retryCallback !== 'function') || (this._retryCount >= this.retryAttempts)) { + return when(false); + } - startRequest(request); - ++filledSlots; + var that = this; + return when(retryCallback(this, error)) + .then(function(result) { + ++that._retryCount; + + return result; + }); + }; + + /** + * Duplicates a Resource instance. + * + * @param {Resource} [result] The object onto which to store the result. + * + * @returns {Resource} The modified result parameter or a new Resource instance if one was not provided. + */ + Resource.prototype.clone = function(result) { + if (!defined(result)) { + result = new Resource({ + url : this._url + }); } - updateStatistics(); + result._url = this._url; + result._queryParameters = clone(this._queryParameters); + result._templateValues = clone(this._templateValues); + result.headers = clone(this.headers); + result.proxy = this.proxy; + result.retryCallback = this.retryCallback; + result.retryAttempts = this.retryAttempts; + result._retryCount = 0; + + // In practice, we don't want this cloned. It usually not set, unless we purposely set it internally and not + // using the request will break the request scheduler. + result.request = this.request; + + return result; + }; + + /** + * Returns the base path of the Resource. + * + * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * + * @returns {String} The base URI of the resource + */ + Resource.prototype.getBaseUri = function(includeQuery) { + return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); + }; + + /** + * Appends a forward slash to the URL. + */ + Resource.prototype.appendForwardSlash = function() { + this._url = appendForwardSlash(this._url); }; /** - * Get the server key from a given url. + * Asynchronously loads the resource as raw binary data. Returns a promise that will resolve to + * an ArrayBuffer once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {String} url The url. - * @returns {String} The server key. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchArrayBuffer().then(function(arrayBuffer) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.getServerKey = function(url) { - Check.typeOf.string('url', url); - - var uri = new Uri(url).resolve(pageUri); - uri.normalize(); - var serverKey = uri.authority; - if (!/:/.test(serverKey)) { - // If the authority does not contain a port number, add port 443 for https or port 80 for http - serverKey = serverKey + ':' + (uri.scheme === 'https' ? '443' : '80'); - } + Resource.prototype.fetchArrayBuffer = function () { + return this.fetch({ + responseType : 'arraybuffer' + }); + }; - var length = numberOfActiveRequestsByServer[serverKey]; - if (!defined(length)) { - numberOfActiveRequestsByServer[serverKey] = 0; - } + /** + * Creates a Resource and calls fetchArrayBuffer() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchArrayBuffer = function (options) { + var resource = new Resource(options); + return resource.fetchArrayBuffer(); + }; - return serverKey; + /** + * Asynchronously loads the given resource as a blob. Returns a promise that will resolve to + * a Blob once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load a single URL asynchronously + * resource.fetchBlob().then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchBlob = function () { + return this.fetch({ + responseType : 'blob' + }); }; /** - * Issue a request. If request.throttle is false, the request is sent immediately. Otherwise the request will be - * queued and sorted by priority before being sent. + * Creates a Resource and calls fetchBlob() on it. * - * @param {Request} request The request object. + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchBlob = function (options) { + var resource = new Resource(options); + return resource.fetchBlob(); + }; + + /** + * Asynchronously loads the given image resource. Returns a promise that will resolve to + * an {@link Image} once loaded, or reject if the image failed to load. * - * @returns {Promise|undefined} A Promise for the requested data, or undefined if this request does not have high enough priority to be issued. + * @param {Boolean} [preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load a single image asynchronously + * resource.fetchImage().then(function(image) { + * // use the loaded image + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * // load several images in parallel + * when.all([resource1.fetchImage(), resource2.fetchImage()]).then(function(images) { + * // images is an array containing all the loaded images + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.request = function(request) { - Check.typeOf.object('request', request); - Check.typeOf.string('request.url', request.url); - Check.typeOf.func('request.requestFunction', request.requestFunction); - - if (isDataUri(request.url) || isBlobUri(request.url)) { - request.state = RequestState.RECEIVED; - return request.requestFunction(); + Resource.prototype.fetchImage = function (preferBlob, allowCrossOrigin) { + if (defined(allowCrossOrigin)) { + deprecationWarning('Resource.fetchImage.allowCrossOrigin', 'The allowCrossOrigin parameter has been deprecated and will be removed in Cesium 1.44. It no longer needs to be specified.'); } - ++statistics.numberOfAttemptedRequests; + preferBlob = defaultValue(preferBlob, false); + allowCrossOrigin = defaultValue(allowCrossOrigin, true); - if (!defined(request.serverKey)) { - request.serverKey = RequestScheduler.getServerKey(request.url); - } + checkAndResetRequest(this.request); - if (!RequestScheduler.throttleRequests || !request.throttle) { - return startRequest(request); + // We try to load the image normally if + // 1. Blobs aren't supported + // 2. It's a data URI + // 3. It's a blob URI + // 4. It doesn't have request headers and we preferBlob is false + if (!xhrBlobSupported || this.isDataUri || this.isBlobUri || (!this.hasHeaders && !preferBlob)) { + return fetchImage(this, allowCrossOrigin); } - if (activeRequests.length >= RequestScheduler.maximumRequests) { - // Active requests are saturated. Try again later. - return undefined; + var blobPromise = this.fetchBlob(); + if (!defined(blobPromise)) { + return; } - if (request.throttleByServer && !serverHasOpenSlots(request.serverKey)) { - // Server is saturated. Try again later. - return undefined; - } + var generatedBlobResource; + var generatedBlob; + return blobPromise + .then(function(blob) { + if (!defined(blob)) { + return; + } + generatedBlob = blob; + var blobUrl = window.URL.createObjectURL(blob); + generatedBlobResource = new Resource({ + url: blobUrl + }); - // Insert into the priority heap and see if a request was bumped off. If this request is the lowest - // priority it will be returned. - updatePriority(request); - var removedRequest = requestHeap.insert(request); + return fetchImage(generatedBlobResource); + }) + .then(function(image) { + if (!defined(image)) { + return; + } + window.URL.revokeObjectURL(generatedBlobResource.url); + + // This is because the blob object is needed for DiscardMissingTileImagePolicy + // See https://github.com/AnalyticalGraphicsInc/cesium/issues/1353 + image.blob = generatedBlob; + return image; + }) + .otherwise(function(error) { + if (defined(generatedBlobResource)) { + window.URL.revokeObjectURL(generatedBlobResource.url); + } - if (defined(removedRequest)) { - if (removedRequest === request) { - // Request does not have high enough priority to be issued - return undefined; + return when.reject(error); + }); + }; + + function fetchImage(resource, allowCrossOrigin) { + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var url = resource.url; + var crossOrigin = false; + + // data URIs can't have allowCrossOrigin set. + if (!resource.isDataUri && !resource.isBlobUri) { + crossOrigin = resource.isCrossOriginUrl; } - // A previously issued request has been bumped off the priority heap, so cancel it - cancelRequest(removedRequest); - } - return issueRequest(request); - }; + var deferred = when.defer(); - function clearStatistics() { - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - } + Resource._Implementations.createImage(url, crossOrigin && allowCrossOrigin, deferred); - function updateStatistics() { - if (!RequestScheduler.debugShowStatistics) { + return deferred.promise; + }; + + var promise = RequestScheduler.request(request); + if (!defined(promise)) { return; } - if (statistics.numberOfAttemptedRequests > 0) { - console.log('Number of attempted requests: ' + statistics.numberOfAttemptedRequests); - } - if (statistics.numberOfActiveRequests > 0) { - console.log('Number of active requests: ' + statistics.numberOfActiveRequests); - } - if (statistics.numberOfCancelledRequests > 0) { - console.log('Number of cancelled requests: ' + statistics.numberOfCancelledRequests); - } - if (statistics.numberOfCancelledActiveRequests > 0) { - console.log('Number of cancelled active requests: ' + statistics.numberOfCancelledActiveRequests); - } - if (statistics.numberOfFailedRequests > 0) { - console.log('Number of failed requests: ' + statistics.numberOfFailedRequests); - } + return promise + .otherwise(function(e) { + // Don't retry cancelled or otherwise aborted requests + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } - clearStatistics(); + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchImage(resource, allowCrossOrigin); + } + + return when.reject(e); + }); + }); } /** - * For testing only. Clears any requests that may not have completed from previous tests. + * Creates a Resource and calls fetchImage() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {Boolean} [options.preferBlob = false] If true, we will load the image via a blob. + * @returns {Promise.<Image>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.clearForSpecs = function() { - while (requestHeap.length > 0) { - var request = requestHeap.pop(); - cancelRequest(request); - } - var length = activeRequests.length; - for (var i = 0; i < length; ++i) { - cancelRequest(activeRequests[i]); - } - activeRequests.length = 0; - numberOfActiveRequestsByServer = {}; + Resource.fetchImage = function (options) { + var resource = new Resource(options); + return resource.fetchImage(options.preferBlob, options.allowCrossOrigin); + }; - // Clear stats - statistics.numberOfAttemptedRequests = 0; - statistics.numberOfActiveRequests = 0; - statistics.numberOfCancelledRequests = 0; - statistics.numberOfCancelledActiveRequests = 0; - statistics.numberOfFailedRequests = 0; - statistics.numberOfActiveRequestsEver = 0; + /** + * Asynchronously loads the given resource as text. Returns a promise that will resolve to + * a String once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * @example + * // load text from a URL, setting a custom header + * var resource = new Resource({ + * url: 'http://someUrl.com/someJson.txt', + * headers: { + * 'X-Custom-Header' : 'some value' + * } + * }); + * resource.fetchText().then(function(text) { + * // Do something with the text + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.fetchText = function() { + return this.fetch({ + responseType : 'text' + }); }; /** - * For testing only. + * Creates a Resource and calls fetchText() on it. * - * @private + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - RequestScheduler.numberOfActiveRequestsByServer = function(serverKey) { - return numberOfActiveRequestsByServer[serverKey]; + Resource.fetchText = function (options) { + var resource = new Resource(options); + return resource.fetchText(); }; + // note: */* below is */* but that ends the comment block early /** - * For testing only. + * Asynchronously loads the given resource as JSON. Returns a promise that will resolve to + * a JSON object once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function + * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not + * already specified. * - * @private + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * resource.fetchJson().then(function(jsonData) { + * // Do something with the JSON object + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - RequestScheduler.requestHeap = requestHeap; + Resource.prototype.fetchJson = function() { + var promise = this.fetch({ + responseType : 'text', + headers: { + Accept : 'application/json,*/*;q=0.01' + } + }); - return RequestScheduler; -}); + if (!defined(promise)) { + return undefined; + } -define('Core/TrustedServers',[ - '../ThirdParty/Uri', - './defined', - './DeveloperError' - ], function( - Uri, - defined, - DeveloperError) { - 'use strict'; + return promise + .then(function(value) { + if (!defined(value)) { + return; + } + return JSON.parse(value); + }); + }; /** - * A singleton that contains all of the servers that are trusted. Credentials will be sent with - * any requests to these servers. + * Creates a Resource and calls fetchJson() on it. * - * @exports TrustedServers + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetchJson = function (options) { + var resource = new Resource(options); + return resource.fetchJson(); + }; + + /** + * Asynchronously loads the given resource as XML. Returns a promise that will resolve to + * an XML Document once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // load XML from a URL, setting a custom header + * Cesium.loadXML('http://someUrl.com/someXML.xml', { + * 'X-Custom-Header' : 'some value' + * }).then(function(document) { + * // Do something with the document + * }).otherwise(function(error) { + * // an error occurred + * }); * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - var TrustedServers = {}; - var _servers = {}; + Resource.prototype.fetchXML = function() { + return this.fetch({ + responseType : 'document', + overrideMimeType : 'text/xml' + }); + }; /** - * Adds a trusted server to the registry - * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * Creates a Resource and calls fetchXML() on it. * - * @example - * // Add a trusted server - * TrustedServers.add('my.server.com', 80); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.add = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (!defined(_servers[authority])) { - _servers[authority] = true; - } + Resource.fetchXML = function (options) { + var resource = new Resource(options); + return resource.fetchXML(); }; /** - * Removes a trusted server from the registry + * Requests a resource using JSONP. + * + * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. * * @example - * // Remove a trusted server - * TrustedServers.remove('my.server.com', 80); + * // load a data asynchronously + * resource.loadJsonp().then(function(data) { + * // use the loaded data + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - TrustedServers.remove = function(host, port) { - if (!defined(host)) { - throw new DeveloperError('host is required.'); - } - if (!defined(port) || port <= 0) { - throw new DeveloperError('port is required to be greater than 0.'); - } - - var authority = host.toLowerCase() + ':' + port; - if (defined(_servers[authority])) { - delete _servers[authority]; - } + Resource.prototype.fetchJsonp = function(callbackParameterName) { + callbackParameterName = defaultValue(callbackParameterName, 'callback'); + + checkAndResetRequest(this.request); + + //generate a unique function name + var functionName; + do { + functionName = 'loadJsonp' + Math.random().toString().substring(2, 8); + } while (defined(window[functionName])); + + return fetchJsonp(this, callbackParameterName, functionName); }; - function getAuthority(url) { - var uri = new Uri(url); - uri.normalize(); + function fetchJsonp(resource, callbackParameterName, functionName) { + var callbackQuery = {}; + callbackQuery[callbackParameterName] = functionName; + resource.addQueryParameters(callbackQuery); - // Removes username:password@ so we just have host[:port] - var authority = uri.getAuthority(); - if (!defined(authority)) { - return undefined; // Relative URL - } + var request = resource.request; + request.url = resource.url; + request.requestFunction = function() { + var deferred = when.defer(); - if (authority.indexOf('@') !== -1) { - var parts = authority.split('@'); - authority = parts[1]; - } + //assign a function with that name in the global scope + window[functionName] = function(data) { + deferred.resolve(data); - // If the port is missing add one based on the scheme - if (authority.indexOf(':') === -1) { - var scheme = uri.getScheme(); - if (!defined(scheme)) { - scheme = window.location.protocol; - scheme = scheme.substring(0, scheme.length-1); - } - if (scheme === 'http') { - authority += ':80'; - } else if (scheme === 'https') { - authority += ':443'; - } else { - return undefined; - } - } + try { + delete window[functionName]; + } catch (e) { + window[functionName] = undefined; + } + }; - return authority; - } + Resource._Implementations.loadAndExecuteScript(resource.url, functionName, deferred); + return deferred.promise; + }; - /** - * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. - * - * @param {String} url The url to be tested against the trusted list - * - * @returns {boolean} Returns true if url is trusted, false otherwise. - * - * @example - * // Add server - * TrustedServers.add('my.server.com', 81); - * - * // Check if server is trusted - * if (TrustedServers.contains('https://my.server.com:81/path/to/file.png')) { - * // my.server.com:81 is trusted - * } - * if (TrustedServers.contains('https://my.server.com/path/to/file.png')) { - * // my.server.com isn't trusted - * } - */ - TrustedServers.contains = function(url) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - var authority = getAuthority(url); - if (defined(authority) && defined(_servers[authority])) { - return true; + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; } - return false; - }; + return promise + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return fetchJsonp(resource, callbackParameterName, functionName); + } + + return when.reject(e); + }); + }); + } /** - * Clears the registry + * Creates a Resource from a URL and calls fetchJsonp() on it. * - * @example - * // Remove a trusted server - * TrustedServers.clear(); + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ - TrustedServers.clear = function() { - _servers = {}; + Resource.fetchJsonp = function (options) { + var resource = new Resource(options); + return resource.fetchJsonp(options.callbackParameterName); }; - return TrustedServers; -}); - -define('Core/loadWithXhr',[ - '../ThirdParty/when', - './Check', - './defaultValue', - './defined', - './DeveloperError', - './Request', - './RequestErrorEvent', - './RequestScheduler', - './RuntimeError', - './TrustedServers' - ], function( - when, - Check, - defaultValue, - defined, - DeveloperError, - Request, - RequestErrorEvent, - RequestScheduler, - RuntimeError, - TrustedServers) { - 'use strict'; - /** - * Asynchronously loads the given URL. Returns a promise that will resolve to - * the result once loaded, or reject if the URL failed to load. The data is loaded + * Asynchronously loads the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @exports loadWithXhr - * - * @param {Object} options Object with the following properties: - * @param {String} options.url The URL of the data. + * @param {Object} [options] Object with the following properties: * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.method='GET'] The HTTP method to use. - * @param {String} [options.data] The data to send with the request, if any. - * @param {Object} [options.headers] HTTP headers to send with the request, if any. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @param {Request} [options.request] The request object. * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example - * // Load a single URL asynchronously. In real code, you should use loadBlob instead. - * Cesium.loadWithXhr({ - * url : 'some/url', - * responseType : 'blob' - * }).then(function(blob) { - * // use the data - * }).otherwise(function(error) { - * // an error occurred - * }); + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.fetch() + * .then(function(blob) { + * // use the data + * }).otherwise(function(error) { + * // an error occurred + * }); * - * @see loadArrayBuffer - * @see loadBlob - * @see loadJson - * @see loadText * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} */ - function loadWithXhr(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + Resource.prototype.fetch = function(options) { + options = defaultClone(options, defaultValue.EMPTY_OBJECT); + options.method = 'GET'; - Check.defined('options.url', options.url); - - var url = options.url; + return makeRequest(this, options); + }; - var responseType = options.responseType; - var method = defaultValue(options.method, 'GET'); - var data = options.data; - var headers = options.headers; - var overrideMimeType = options.overrideMimeType; - url = defaultValue(url, options.url); + function makeRequest(resource, options) { + checkAndResetRequest(resource.request); + + var request = resource.request; + request.url = resource.url; - var request = defined(options.request) ? options.request : new Request(); - request.url = url; request.requestFunction = function() { + var responseType = options.responseType; + var headers = combine(resource.headers, options.headers); + var overrideMimeType = options.overrideMimeType; + var method = options.method; + var data = options.data; var deferred = when.defer(); - var xhr = loadWithXhr.load(url, responseType, method, data, headers, deferred, overrideMimeType); + var xhr = Resource._Implementations.loadWithXhr(resource.url, responseType, method, data, headers, deferred, overrideMimeType); if (defined(xhr) && defined(xhr.abort)) { request.cancelFunction = function() { xhr.abort(); @@ -19033,58 +20939,199 @@ define('Core/loadWithXhr',[ return deferred.promise; }; - return RequestScheduler.request(request); + var promise = RequestScheduler.request(request); + if (!defined(promise)) { + return; + } + + return promise + .then(function(data) { + return data; + }) + .otherwise(function(e) { + if (request.state !== RequestState.FAILED) { + return when.reject(e); + } + + return resource.retryOnError(e) + .then(function(retry) { + if (retry) { + // Reset request so it can try again + request.state = RequestState.UNISSUED; + request.deferred = undefined; + + return resource.fetch(options); + } + + return when.reject(e); + }); + }); + } + + var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + + function decodeDataUriText(isBase64, data) { + var result = decodeURIComponent(data); + if (isBase64) { + return atob(result); + } + return result; + } + + function decodeDataUriArrayBuffer(isBase64, data) { + var byteString = decodeDataUriText(isBase64, data); + var buffer = new ArrayBuffer(byteString.length); + var view = new Uint8Array(buffer); + for (var i = 0; i < byteString.length; i++) { + view[i] = byteString.charCodeAt(i); + } + return buffer; + } + + function decodeDataUri(dataUriRegexResult, responseType) { + responseType = defaultValue(responseType, ''); + var mimeType = dataUriRegexResult[1]; + var isBase64 = !!dataUriRegexResult[2]; + var data = dataUriRegexResult[3]; + + switch (responseType) { + case '': + case 'text': + return decodeDataUriText(isBase64, data); + case 'arraybuffer': + return decodeDataUriArrayBuffer(isBase64, data); + case 'blob': + var buffer = decodeDataUriArrayBuffer(isBase64, data); + return new Blob([buffer], { + type : mimeType + }); + case 'document': + var parser = new DOMParser(); + return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); + case 'json': + return JSON.parse(decodeDataUriText(isBase64, data)); + default: + throw new DeveloperError('Unhandled responseType: ' + responseType); + } } - var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.fetch = function (options) { + var resource = new Resource(options); + return resource.fetch({ + // Make copy of just the needed fields because headers can be passed to both the constructor and to fetch + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Asynchronously posts data the given resource. Returns a promise that will resolve to + * the result once loaded, or reject if the resource failed to load. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. + * + * @param {Object} data Data that is posted with the resource. + * @param {Object} [options] Object with the following properties: + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * + * + * @example + * // Load a single resource asynchronously. In real code, you should use loadBlob instead. + * resource.post(data) + * .then(function(result) { + * // use the result + * }).otherwise(function(error) { + * // an error occurred + * }); + * + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + */ + Resource.prototype.post = function(data, options) { + Check.defined('data', data); + + options = defaultClone(options, {}); + options.method = 'POST'; + options.data = data; + + return makeRequest(this, options); + }; + + /** + * Creates a Resource from a URL and calls fetch() on it. + * + * @param {String|Object} options A url or an object with the following properties + * @param {String} options.url The url of the resource. + * @param {Object} options.data Data that is posted with the resource. + * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {DefaultProxy} [options.proxy] A proxy to be used when loading the resource. + * @param {Resource~RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. + * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. + * @param {String} [options.responseType] The type of response. This controls the type of item returned. + * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + */ + Resource.post = function (options) { + var resource = new Resource(options); + return resource.post(options.data, { + // Make copy of just the needed fields because headers can be passed to both the constructor and to post + responseType: options.responseType, + overrideMimeType: options.overrideMimeType + }); + }; + + /** + * Contains implementations of functions that can be replaced for testing + * + * @private + */ + Resource._Implementations = {}; + + Resource._Implementations.createImage = function(url, crossOrigin, deferred) { + var image = new Image(); + + image.onload = function() { + deferred.resolve(image); + }; - function decodeDataUriText(isBase64, data) { - var result = decodeURIComponent(data); - if (isBase64) { - return atob(result); - } - return result; - } + image.onerror = function(e) { + deferred.reject(e); + }; - function decodeDataUriArrayBuffer(isBase64, data) { - var byteString = decodeDataUriText(isBase64, data); - var buffer = new ArrayBuffer(byteString.length); - var view = new Uint8Array(buffer); - for (var i = 0; i < byteString.length; i++) { - view[i] = byteString.charCodeAt(i); + if (crossOrigin) { + if (TrustedServers.contains(url)) { + image.crossOrigin = 'use-credentials'; + } else { + image.crossOrigin = ''; + } } - return buffer; - } - - function decodeDataUri(dataUriRegexResult, responseType) { - responseType = defaultValue(responseType, ''); - var mimeType = dataUriRegexResult[1]; - var isBase64 = !!dataUriRegexResult[2]; - var data = dataUriRegexResult[3]; - switch (responseType) { - case '': - case 'text': - return decodeDataUriText(isBase64, data); - case 'arraybuffer': - return decodeDataUriArrayBuffer(isBase64, data); - case 'blob': - var buffer = decodeDataUriArrayBuffer(isBase64, data); - return new Blob([buffer], { - type : mimeType - }); - case 'document': - var parser = new DOMParser(); - return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType); - case 'json': - return JSON.parse(decodeDataUriText(isBase64, data)); - default: - throw new DeveloperError('Unhandled responseType: ' + responseType); - } - } + image.src = url; + }; - // This is broken out into a separate function so that it can be mocked for testing purposes. - loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + Resource._Implementations.loadWithXhr = function(url, responseType, method, data, headers, deferred, overrideMimeType) { var dataUriRegexResult = dataUriRegex.exec(url); if (dataUriRegexResult !== null) { deferred.resolve(decodeDataUri(dataUriRegexResult, responseType)); @@ -19162,129 +21209,53 @@ define('Core/loadWithXhr',[ return xhr; }; - loadWithXhr.defaultLoad = loadWithXhr.load; + Resource._Implementations.loadAndExecuteScript = function(url, functionName, deferred) { + var script = document.createElement('script'); + script.async = true; + script.src = url; - return loadWithXhr; -}); + var head = document.getElementsByTagName('head')[0]; + script.onload = function() { + script.onload = undefined; + head.removeChild(script); + }; + script.onerror = function(e) { + deferred.reject(e); + }; -define('Core/loadText',[ - './loadWithXhr' - ], function( - loadWithXhr) { - 'use strict'; + head.appendChild(script); + }; /** - * Asynchronously loads the given URL as text. Returns a promise that will resolve to - * a String once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @exports loadText - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * // load text from a URL, setting a custom header - * Cesium.loadText('http://someUrl.com/someJson.txt', { - * 'X-Custom-Header' : 'some value' - * }).then(function(text) { - * // Do something with the text - * }).otherwise(function(error) { - * // an error occurred - * }); + * The default implementations * - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest|XMLHttpRequest} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private */ - function loadText(url, headers, request) { - return loadWithXhr({ - url : url, - headers : headers, - request : request - }); - } - - return loadText; -}); - -define('Core/loadJson',[ - './clone', - './defined', - './DeveloperError', - './loadText' - ], function( - clone, - defined, - DeveloperError, - loadText) { - 'use strict'; - - var defaultHeaders = { - Accept : 'application/json,*/*;q=0.01' - }; + Resource._DefaultImplementations = {}; + Resource._DefaultImplementations.createImage = Resource._Implementations.createImage; + Resource._DefaultImplementations.loadWithXhr = Resource._Implementations.loadWithXhr; + Resource._DefaultImplementations.loadAndExecuteScript = Resource._Implementations.loadAndExecuteScript; - // note: */* below is */* but that ends the comment block early /** - * Asynchronously loads the given URL as JSON. Returns a promise that will resolve to - * a JSON object once loaded, or reject if the URL failed to load. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. This function - * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not - * already specified. - * - * @exports loadJson - * - * @param {String} url The URL to request. - * @param {Object} [headers] HTTP headers to send with the request. - * 'Accept: application/json,*/*;q=0.01' is added to the request headers automatically - * if not specified. - * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<Object>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. - * - * - * @example - * Cesium.loadJson('http://someUrl.com/someJson.txt').then(function(jsonData) { - * // Do something with the JSON object - * }).otherwise(function(error) { - * // an error occurred - * }); + * A resource instance initialized to the current browser location * - * @see loadText - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @type {Resource} + * @constant */ - function loadJson(url, headers, request) { - if (!defined(url)) { - throw new DeveloperError('url is required.'); - } - - if (!defined(headers)) { - headers = defaultHeaders; - } else if (!defined(headers.Accept)) { - // clone before adding the Accept header - headers = clone(headers); - headers.Accept = defaultHeaders.Accept; - } - - var textPromise = loadText(url, headers, request); - if (!defined(textPromise)) { - return undefined; - } + Resource.DEFAULT = freezeObject(new Resource({ + url: (typeof document === 'undefined') ? '' : document.location.href.split('?')[0] + })); - return textPromise.then(function(value) { - if (!defined(value)) { - return; - } - return JSON.parse(value); - }); - } + /** + * A function that returns the value of the property. + * @callback Resource~RetryCallback + * + * @param {Resource} [resource] The resource that failed to load. + * @param {Error} [error] The error that occurred during the loading of the resource. + * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + */ - return loadJson; + return Resource; }); define('Core/EarthOrientationParameters',[ @@ -19296,7 +21267,7 @@ define('Core/EarthOrientationParameters',[ './freezeObject', './JulianDate', './LeapSecond', - './loadJson', + './Resource', './RuntimeError', './TimeConstants', './TimeStandard' @@ -19309,7 +21280,7 @@ define('Core/EarthOrientationParameters',[ freezeObject, JulianDate, LeapSecond, - loadJson, + Resource, RuntimeError, TimeConstants, TimeStandard) { @@ -19325,7 +21296,7 @@ define('Core/EarthOrientationParameters',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.url] The URL from which to obtain EOP data. If neither this + * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. @@ -19382,12 +21353,14 @@ define('Core/EarthOrientationParameters',[ // Use supplied EOP data. onDataReady(this, options.data); } else if (defined(options.url)) { + var resource = Resource.createIfNeeded(options.url); + // Download EOP data. var that = this; - this._downloadPromise = when(loadJson(options.url), function(eopData) { + this._downloadPromise = when(resource.fetchJson(), function(eopData) { onDataReady(that, eopData); }, function() { - that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + options.url + '.'; + that._dataError = 'An error occurred while retrieving the EOP data from the URL ' + resource.url + '.'; }); } else { // Use all zeros for EOP data. @@ -19670,179 +21643,17 @@ define('Core/EarthOrientationParameters',[ return EarthOrientationParameters; }); -define('Core/getAbsoluteUri',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. - * @exports getAbsoluteUri - * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. - * - * @example - * //absolute Uri will be "https://test.com/awesome.png"; - * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); - */ - function getAbsoluteUri(relative, base) { - if (!defined(relative)) { - throw new DeveloperError('relative uri is required.'); - } - base = defaultValue(base, document.location.href); - var baseUri = new Uri(base); - var relativeUri = new Uri(relative); - return relativeUri.resolve(baseUri).toString(); - } - - return getAbsoluteUri; -}); - -define('Core/joinUrls',[ - '../ThirdParty/Uri', - './defaultValue', - './defined', - './DeveloperError' - ], function( - Uri, - defaultValue, - defined, - DeveloperError) { - 'use strict'; - - /** - * Function for joining URLs in a manner that is aware of query strings and fragments. - * This is useful when the base URL has a query string that needs to be maintained - * (e.g. a presigned base URL). - * @param {String|Uri} first The base URL. - * @param {String|Uri} second The URL path to join to the base URL. If this URL is absolute, it is returned unmodified. - * @param {Boolean} [appendSlash=true] The boolean determining whether there should be a forward slash between first and second. - * - * @return {String} The combined url - * @private - */ - function joinUrls(first, second, appendSlash) { - if (!defined(first)) { - throw new DeveloperError('first is required'); - } - if (!defined(second)) { - throw new DeveloperError('second is required'); - } - - appendSlash = defaultValue(appendSlash, true); - - if (!(first instanceof Uri)) { - first = new Uri(first); - } - - if (!(second instanceof Uri)) { - second = new Uri(second); - } - - // Don't try to join a data uri - if (first.scheme === 'data') { - return first.toString(); - } - - // Don't try to join a data uri - if (second.scheme === 'data') { - return second.toString(); - } - - // Uri.isAbsolute returns false for a URL like '//foo.com'. So if we have an authority but - // not a scheme, add a scheme matching the page's scheme. - if (defined(second.authority) && !defined(second.scheme)) { - if (typeof document !== 'undefined' && defined(document.location) && defined(document.location.href)) { - second.scheme = new Uri(document.location.href).scheme; - } else { - // Not in a browser? Use the first URL's scheme instead. - second.scheme = first.scheme; - } - } - - // If the second URL is absolute, use it for the scheme, authority, and path. - var baseUri = first; - if (second.isAbsolute()) { - baseUri = second; - } - - var url = ''; - if (defined(baseUri.scheme)) { - url += baseUri.scheme + ':'; - } - if (defined(baseUri.authority)) { - url += '//' + baseUri.authority; - - if (baseUri.path !== '' && baseUri.path !== '/') { - // The next line ensures that url (including a non-blank authority) ends with a slash. - url = url.replace(/\/?$/, '/'); - baseUri.path = baseUri.path.replace(/^\/?/g, ''); - - // If authority is empty, add a third slash. This is primarily for the file scheme, - // where a blank authority indicates a file on localhost (as opposed to a network share). - if (baseUri.authority === '') { - url += '/'; - } - } - } - - // Combine the paths (only if second is relative). - if (baseUri === first) { - if (appendSlash) { - url += first.path.replace(/\/?$/, '/') + second.path.replace(/^\/?/g, ''); - } else { - url += first.path + second.path; - } - } else { - url += second.path; - } - - // Combine the queries and fragments. - var hasFirstQuery = defined(first.query); - var hasSecondQuery = defined(second.query); - if (hasFirstQuery && hasSecondQuery) { - url += '?' + first.query + '&' + second.query; - } else if (hasFirstQuery && !hasSecondQuery) { - url += '?' + first.query; - } else if (!hasFirstQuery && hasSecondQuery) { - url += '?' + second.query; - } - - var hasSecondFragment = defined(second.fragment); - if (defined(first.fragment) && !hasSecondFragment) { - url += '#' + first.fragment; - } else if (hasSecondFragment) { - url += '#' + second.fragment; - } - - return url; - } - - return joinUrls; -}); - define('Core/buildModuleUrl',[ '../ThirdParty/Uri', './defined', './DeveloperError', - './getAbsoluteUri', - './joinUrls', + './Resource', 'require' ], function( Uri, defined, DeveloperError, - getAbsoluteUri, - joinUrls, + Resource, require) { 'use strict'; /*global CESIUM_BASE_URL*/ @@ -19860,10 +21671,10 @@ define('Core/buildModuleUrl',[ return undefined; } - var baseUrl; + var baseResource; function getCesiumBaseUrl() { - if (defined(baseUrl)) { - return baseUrl; + if (defined(baseResource)) { + return baseResource; } var baseUrlString; @@ -19877,9 +21688,11 @@ define('Core/buildModuleUrl',[ throw new DeveloperError('Unable to determine Cesium base URL automatically, try defining a global variable called CESIUM_BASE_URL.'); } - baseUrl = new Uri(getAbsoluteUri(baseUrlString)); + baseResource = new Resource({ + url: baseUrlString + }); - return baseUrl; + return baseResource; } function buildModuleUrlFromRequireToUrl(moduleID) { @@ -19888,7 +21701,10 @@ define('Core/buildModuleUrl',[ } function buildModuleUrlFromBaseUrl(moduleID) { - return joinUrls(getCesiumBaseUrl(), moduleID); + var resource = getCesiumBaseUrl().getDerivedResource({ + url: moduleID + }); + return resource.url; } var implementation; @@ -19931,7 +21747,9 @@ define('Core/buildModuleUrl',[ * @param {String} value The new base URL. */ buildModuleUrl.setBaseUrl = function(value) { - baseUrl = new Uri(value).resolve(new Uri(document.location.href)); + baseResource = Resource.DEFAULT.getDerivedResource({ + url: value + }); }; return buildModuleUrl; @@ -19982,7 +21800,7 @@ define('Core/Iau2006XysData',[ './defined', './Iau2006XysSample', './JulianDate', - './loadJson', + './Resource', './TimeStandard' ], function( when, @@ -19991,7 +21809,7 @@ define('Core/Iau2006XysData',[ defined, Iau2006XysSample, JulianDate, - loadJson, + Resource, TimeStandard) { 'use strict'; @@ -20003,7 +21821,7 @@ define('Core/Iau2006XysData',[ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the @@ -20017,7 +21835,7 @@ define('Core/Iau2006XysData',[ function Iau2006XysData(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._xysFileUrlTemplate = options.xysFileUrlTemplate; + this._xysFileUrlTemplate = Resource.createIfNeeded(options.xysFileUrlTemplate); this._interpolationOrder = defaultValue(options.interpolationOrder, 9); this._sampleZeroJulianEphemerisDate = defaultValue(options.sampleZeroJulianEphemerisDate, 2442396.5); this._sampleZeroDateTT = new JulianDate(this._sampleZeroJulianEphemerisDate, 0.0, TimeStandard.TAI); @@ -20215,12 +22033,18 @@ define('Core/Iau2006XysData',[ var chunkUrl; var xysFileUrlTemplate = xysData._xysFileUrlTemplate; if (defined(xysFileUrlTemplate)) { - chunkUrl = xysFileUrlTemplate.replace('{0}', chunkIndex); + chunkUrl = xysFileUrlTemplate.getDerivedResource({ + templateValues: { + '0': chunkIndex + } + }); } else { - chunkUrl = buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json'); + chunkUrl = new Resource({ + url : buildModuleUrl('Assets/IAU2006_XYS/IAU2006_XYS_' + chunkIndex + '.json') + }); } - when(loadJson(chunkUrl), function(chunk) { + when(chunkUrl.fetchJson(), function(chunk) { xysData._chunkDownloadsInProgress[chunkIndex] = false; var samples = xysData._samples; @@ -22131,7 +23955,7 @@ define('Core/Transforms',[ * * @example * //Set the view to in the inertial frame. - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var now = Cesium.JulianDate.now(); * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); * var transform = Cesium.Matrix4.fromRotationTranslation(Cesium.Transforms.computeTemeToPseudoFixedMatrix(now)); @@ -22261,7 +24085,7 @@ define('Core/Transforms',[ * * * @example - * scene.preRender.addEventListener(function(scene, time) { + * scene.postUpdate.addEventListener(function(scene, time) { * var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time); * if (Cesium.defined(icrfToFixed)) { * var offset = Cesium.Matrix4.multiplyByPoint(camera.transform, camera.position, new Cesium.Cartesian3()); @@ -22928,6 +24752,7 @@ define('Core/OrientedBoundingBox',[ './Cartesian2', './Cartesian3', './Cartographic', + './Check', './defaultValue', './defined', './DeveloperError', @@ -22944,6 +24769,7 @@ define('Core/OrientedBoundingBox',[ Cartesian2, Cartesian3, Cartographic, + Check, defaultValue, defined, DeveloperError, @@ -22965,7 +24791,7 @@ define('Core/OrientedBoundingBox',[ * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 + * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 * cube centered at the origin. * * @@ -22989,11 +24815,60 @@ define('Core/OrientedBoundingBox',[ /** * The transformation matrix, to rotate the box to the right position. * @type {Matrix3} - * @default {@link Matrix3.IDENTITY} + * @default {@link Matrix3.ZERO} */ this.halfAxes = Matrix3.clone(defaultValue(halfAxes, Matrix3.ZERO)); } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + OrientedBoundingBox.packedLength = Cartesian3.packedLength + Matrix3.packedLength; + + /** + * Stores the provided instance into the provided array. + * + * @param {OrientedBoundingBox} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + OrientedBoundingBox.pack = function(value, array, startingIndex) { + Check.typeOf.object('value', value); + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + Cartesian3.pack(value.center, array, startingIndex); + Matrix3.pack(value.halfAxes, array, startingIndex + Cartesian3.packedLength); + + return array; + }; + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrientedBoundingBox} [result] The object into which to store the result. + * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. + */ + OrientedBoundingBox.unpack = function(array, startingIndex, result) { + Check.defined('array', array); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new OrientedBoundingBox(); + } + + Cartesian3.unpack(array, startingIndex, result.center); + Matrix3.unpack(array, startingIndex + Cartesian3.packedLength, result.halfAxes); + return result; + }; + var scratchCartesian1 = new Cartesian3(); var scratchCartesian2 = new Cartesian3(); var scratchCartesian3 = new Cartesian3(); @@ -23011,7 +24886,7 @@ define('Core/OrientedBoundingBox',[ * This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis). * Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf * - * @param {Cartesian3[]} positions List of {@link Cartesian3} points that the bounding box will enclose. + * @param {Cartesian3[]} [positions] List of {@link Cartesian3} points that the bounding box will enclose. * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. * -- GitLab